From gtk3 at inbox.ru  Sat Jan  1 05:05:06 2022
From: gtk3 at inbox.ru (Maxim Kutnij)
Date: Sat,  1 Jan 2022 18:05:06 +0500
Subject: [PATCH 1/2] ARM: mediatek: add smp bringup code for MT6582
In-Reply-To: dda186e0-38e0-4061-f60e-e297441d9fed@gmail.com
References: <20211230155152.48715-1-gtk3@inbox.ru>
Message-ID: <20220101130506.13150-1-gtk3@inbox.ru>


On Fri, 31 Dec 2021 16:51:20 +0100, Matthias Brugger wrote:
>What do we need the clock-frequency for? I wasn't able to figure that 
>out right now.
>
>Other then that patches look good.
>
>Regards,
>Matthias

I thought it might be useful in the future. But if not, then I will remove it in the next patch.

Maxim


From yu.tu at amlogic.com  Sat Jan  1 05:30:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Sat, 1 Jan 2022 21:30:12 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
Message-ID: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>

Hi Martin,
     Thank you very much for your reply.

On 2021/12/31 23:32, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> On Fri, Dec 31, 2021 at 12:24 PM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>>>    static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +       struct meson_uart_data *private_data = port->private_data;
>>>> +       int ret;
>>>> +
>>>> +       ret = clk_prepare_enable(private_data->pclk);
>>>> +       if (ret)
>>>> +               return ret;
>>>> +
>>>> +       ret = clk_prepare_enable(private_data->baud_clk);
>>>> +       if (ret) {
>>>> +               clk_disable_unprepare(private_data->pclk);
>>>> +               return ret;
>>>> +       }
>>> This code is from my original suggestion - and I had a doubt there
>>> which I forgot to add as a comment originally:
>>> Can you confirm that accessing the UART controller registers works
>>> even when "pclk" is turned off?
>>> I am asking this because the common clock framework can access the
>>> clocks at any time.
>>> And I have seen SoCs which would hang when trying to access a module's
>>> registers while the module's pclk is turned off.
>> On all meson platforms, the default pclk for all UART is turned on
>> during the u-boot phase. When registering uart pclk in the kernel phase,
>> the CLK_IGNORE_UNUSED flag is added. So the real shutdown is when the
>> standby goes down, the parent clk shuts down.
> Interesting, thanks for sharing that u-boot turns these clocks on.
> Let's say someone wanted to make u-boot save power and turn off all
> UART clocks except the one for uart_AO (where we typically connect the
> serial console).
> In that case the pclk of uart_C (just to choose an example here) is
> turned off. Would there be a problem then accessing the registers of
> uart_C before clk_prepare_enable is called?
The way you describe it, it does hang. This would not be recommended on 
actual projects.

At present, AmLogic chips are older than S4 Soc, and we have no way to 
deal with this problem. We have to tell customers not to use it in this 
way?Customers rarely use it in real projects.On the S4 SOC we will use 
a clock like the UART pclk to control the shutdown using two registers, 
one safe (need to operate in EL3) and one normal (EL1). It will only be 
closed if both registers are closed. This mainly prevents misoperation.

With your experience, I'd like to know how you deal with this kind of 
problem.
> 
> [...]
>>>>           port->fifosize = 64;
>>> commit 27d44e05d7b85d ("tty: serial: meson: retrieve port FIFO size
>>> from DT") [0] from May 2021 has changed this line to:
>>>     port->fifosize = fifosize;
>>> So your patch currently does not apply to linux-next (or even Linus'
>>> mainline tree).
>>>
>> So do I need to wait for [0] patch merged before I can continue to make
>> changes ?
> These changes are already merged.
> 
>> What can I do before?
> You should base your changes on top of the tty.git/tty-next branch [1]
> where Greg (the maintainer of this tree) will pick up the patches once
> they are good (got enough Acked-by/Reviewed-by, etc.).
> I suspect that you based your changes on an older or stable kernel
> version (let's say 5.10). New functionality should always get into the
> -next tree where various auto-build robots will compile-test the
> changes and we even have Kernel CI where changes are tested on real
> hardware (BayLibre even maintains Amlogic boards in their Kernel CI
> labs). Let's say Amlogic updates to Linux 5.17 next year then the
> patches are already included in that kernel version - instead of being
> only available in Linux 5.10.
> 
I'm sorry, I did branch confirm there was a mistake, I have corrected.
> 
> Best regards,
> Martin
> 
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/log/?h=tty-next
> 


From gtk3 at inbox.ru  Sat Jan  1 06:01:36 2022
From: gtk3 at inbox.ru (Maxim Kutnij)
Date: Sat,  1 Jan 2022 19:01:36 +0500
Subject: [PATCH v2 1/2] ARM: mediatek: add smp bringup code for MT6582
In-Reply-To: dda186e0-38e0-4061-f60e-e297441d9fed@gmail.com
Message-ID: <20220101140140.4119-1-gtk3@inbox.ru>

This patch adds SMP support on the MediaTek MT6582 quad-core Cortex-A7 SoC.
And also enable GPT6.

Signed-off-by: Maxim Kutnij <gtk3 at inbox.ru>
---
 arch/arm/mach-mediatek/mediatek.c | 4 +++-
 arch/arm/mach-mediatek/platsmp.c  | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c
index e6e9f93a1..aefeb6614 100644
--- a/arch/arm/mach-mediatek/mediatek.c
+++ b/arch/arm/mach-mediatek/mediatek.c
@@ -20,7 +20,8 @@ static void __init mediatek_timer_init(void)
 {
 	void __iomem *gpt_base;
 
-	if (of_machine_is_compatible("mediatek,mt6589") ||
+	if (of_machine_is_compatible("mediatek,mt6582") ||
+	    of_machine_is_compatible("mediatek,mt6589") ||
 	    of_machine_is_compatible("mediatek,mt7623") ||
 	    of_machine_is_compatible("mediatek,mt8135") ||
 	    of_machine_is_compatible("mediatek,mt8127")) {
@@ -38,6 +39,7 @@ static void __init mediatek_timer_init(void)
 
 static const char * const mediatek_board_dt_compat[] = {
 	"mediatek,mt2701",
+	"mediatek,mt6582",
 	"mediatek,mt6589",
 	"mediatek,mt6592",
 	"mediatek,mt7623",
diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c
index 16a4ee6c9..e1c7ad52f 100644
--- a/arch/arm/mach-mediatek/platsmp.c
+++ b/arch/arm/mach-mediatek/platsmp.c
@@ -49,6 +49,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
 };
 
 static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
+	{ .compatible   = "mediatek,mt6582", .data = &mtk_mt7623_boot },
 	{ .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot },
 	{ .compatible   = "mediatek,mt7623", .data = &mtk_mt7623_boot },
 	{ .compatible   = "mediatek,mt7629", .data = &mtk_mt7623_boot },
-- 
2.33.1



From gtk3 at inbox.ru  Sat Jan  1 06:01:37 2022
From: gtk3 at inbox.ru (Maxim Kutnij)
Date: Sat,  1 Jan 2022 19:01:37 +0500
Subject: [PATCH v2 2/2] ARM: mediatek: dts: activate SMP for mt6582
In-Reply-To: dda186e0-38e0-4061-f60e-e297441d9fed@gmail.com
References: <20220101140140.4119-1-gtk3@inbox.ru>
Message-ID: <20220101140140.4119-2-gtk3@inbox.ru>

This patch adds nodes mt6589-smp, pmu and arm,armv7-timer.

Signed-off-by: Maxim Kutnij <gtk3 at inbox.ru>
---
 arch/arm/boot/dts/mt6582.dtsi | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/mt6582.dtsi b/arch/arm/boot/dts/mt6582.dtsi
index 426337178..2d5cb3bdd 100644
--- a/arch/arm/boot/dts/mt6582.dtsi
+++ b/arch/arm/boot/dts/mt6582.dtsi
@@ -15,29 +15,39 @@ / {
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
+		enable-method = "mediatek,mt6589-smp";
 
-		cpu at 0 {
+		cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
 		};
-		cpu at 1 {
+		cpu1: cpu at 1 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x1>;
 		};
-		cpu at 2 {
+		cpu2: cpu at 2 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x2>;
 		};
-		cpu at 3 {
+		cpu3: cpu at 3 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x3>;
 		};
 	};
 
+	pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 5 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 6 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_SPI 7 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+	};
+
 	system_clk: dummy13m {
 		compatible = "fixed-clock";
 		clock-frequency = <13000000>;
@@ -56,7 +66,18 @@ uart_clk: dummy26m {
 		#clock-cells = <0>;
 	};
 
-	timer: timer at 11008000 {
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <13000000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	timer: timer at 10008000 {
 		compatible = "mediatek,mt6577-timer";
 		reg = <0x10008000 0x80>;
 		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
-- 
2.33.1



From abel.vesa at nxp.com  Sat Jan  1 07:52:43 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 17:52:43 +0200
Subject: [PATCH 1/3] interconnect: imx: Switch from imx_icc_node_adj_desc to
 fsl, icc-id node assignment
Message-ID: <20220101155245.3139667-1-abel.vesa@nxp.com>

In order to be able to have more than one NoCs in the interconnect net
we need to decouple the NoC from the dram. So instead of using the
imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
each NoC (or pl301) to the icc node (based on the id) to it.
Along with all the NoC and pl301 nodes in the dts we will have a
interconnect dedicated node. This node will be the actual device of the
icc provider.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/interconnect/imx/imx.c | 70 +++++++++++++++-------------------
 1 file changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index c770951a909c..34bfc7936387 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -34,8 +34,8 @@ static int imx_icc_node_set(struct icc_node *node)
 	if (!node_data->qos_dev)
 		return 0;
 
-	freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
-	do_div(freq, node_data->desc->adj->bw_div);
+	freq = max(node->avg_bw, node->peak_bw);
+
 	dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq %llukHz\n",
 		node->name, dev_name(node_data->qos_dev),
 		node->avg_bw, node->peak_bw, freq);
@@ -79,41 +79,35 @@ static int imx_icc_node_init_qos(struct icc_provider *provider,
 				 struct icc_node *node)
 {
 	struct imx_icc_node *node_data = node->data;
-	const struct imx_icc_node_adj_desc *adj = node_data->desc->adj;
 	struct device *dev = provider->dev;
-	struct device_node *dn = NULL;
 	struct platform_device *pdev;
+	struct device_node *np = NULL, *dn = NULL;
+	int idx;
 
-	if (adj->main_noc) {
-		node_data->qos_dev = dev;
-		dev_dbg(dev, "icc node %s[%d] is main noc itself\n",
-			node->name, node->id);
-	} else {
-		dn = of_parse_phandle(dev->of_node, adj->phandle_name, 0);
-		if (!dn) {
-			dev_warn(dev, "Failed to parse %s\n",
-				 adj->phandle_name);
-			return -ENODEV;
-		}
-		/* Allow scaling to be disabled on a per-node basis */
-		if (!of_device_is_available(dn)) {
-			dev_warn(dev, "Missing property %s, skip scaling %s\n",
-				 adj->phandle_name, node->name);
-			of_node_put(dn);
-			return 0;
-		}
+	for_each_node_with_property(np, "fsl,icc-id") {
+		of_property_read_u32(np, "fsl,icc-id", &idx);
+		if (idx == node_data->desc->id)
+			dn = np;
+	}
 
-		pdev = of_find_device_by_node(dn);
-		of_node_put(dn);
-		if (!pdev) {
-			dev_warn(dev, "node %s[%d] missing device for %pOF\n",
-				 node->name, node->id, dn);
-			return -EPROBE_DEFER;
-		}
-		node_data->qos_dev = &pdev->dev;
-		dev_dbg(dev, "node %s[%d] has device node %pOF\n",
-			node->name, node->id, dn);
+	if (!dn)
+		return 0;
+
+	if (!of_device_is_available(dn)) {
+		dev_warn(dev, "%pOF is disabled\n", dn);
+		return 0;
+	}
+
+	pdev = of_find_device_by_node(dn);
+	of_node_put(dn);
+	if (!pdev) {
+		dev_warn(dev, "node %s[%d] missing device for %pOF\n",
+			 node->name, node->id, dn);
+		return -EPROBE_DEFER;
 	}
+	node_data->qos_dev = &pdev->dev;
+	dev_dbg(dev, "node %s[%d] has device node %pOF\n", node->name,
+							node->id, dn);
 
 	return dev_pm_qos_add_request(node_data->qos_dev,
 				      &node_data->qos_req,
@@ -151,12 +145,10 @@ static struct icc_node *imx_icc_node_add(struct icc_provider *provider,
 	node_data->desc = node_desc;
 	icc_node_add(node, provider);
 
-	if (node_desc->adj) {
-		ret = imx_icc_node_init_qos(provider, node);
-		if (ret < 0) {
-			imx_icc_node_destroy(node);
-			return ERR_PTR(ret);
-		}
+	ret = imx_icc_node_init_qos(provider, node);
+	if (ret < 0) {
+		imx_icc_node_destroy(node);
+		return ERR_PTR(ret);
 	}
 
 	return node;
@@ -244,7 +236,7 @@ int imx_icc_register(struct platform_device *pdev,
 	provider->aggregate = icc_std_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
-	provider->dev = dev->parent;
+	provider->dev = dev;
 	platform_set_drvdata(pdev, provider);
 
 	ret = icc_provider_add(provider);
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 07:52:44 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 17:52:44 +0200
Subject: [PATCH 2/3] interconnect: imx: Add imx_icc_get_bw and
 imx_icc_aggregate functions
In-Reply-To: <20220101155245.3139667-1-abel.vesa@nxp.com>
References: <20220101155245.3139667-1-abel.vesa@nxp.com>
Message-ID: <20220101155245.3139667-2-abel.vesa@nxp.com>

The aggregate function will return whatever is the highest
rate for that specific node. The imx_icc_get_bw sets the
initial avg and peak to 0 in order to avoid setting them to
INT_MAX by the interconnect core.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/interconnect/imx/imx.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index 34bfc7936387..4d8a2a2d2608 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -25,6 +25,23 @@ struct imx_icc_node {
 	struct dev_pm_qos_request qos_req;
 };
 
+static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+	*avg = 0;
+	*peak = 0;
+
+	return 0;
+}
+
+static int imx_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+		      u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	*agg_avg = max(*agg_avg, avg_bw);
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
 static int imx_icc_node_set(struct icc_node *node)
 {
 	struct device *dev = node->provider->dev;
@@ -233,7 +250,8 @@ int imx_icc_register(struct platform_device *pdev,
 	if (!provider)
 		return -ENOMEM;
 	provider->set = imx_icc_set;
-	provider->aggregate = icc_std_aggregate;
+	provider->get_bw = imx_icc_get_bw;
+	provider->aggregate = imx_icc_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
 	provider->dev = dev;
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 07:52:45 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 17:52:45 +0200
Subject: [PATCH 3/3] interconnect: imx8: Remove the imx_icc_node_adj_desc
In-Reply-To: <20220101155245.3139667-1-abel.vesa@nxp.com>
References: <20220101155245.3139667-1-abel.vesa@nxp.com>
Message-ID: <20220101155245.3139667-3-abel.vesa@nxp.com>

Now that the imx generic interconnect doesn't use the
imx_icc_node_adj_desc, we remove it from all the i.MX8M
platform drivers.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/interconnect/imx/imx.h    | 19 ++++-------------
 drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
 drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
 drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
 4 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
index 75da51076c68..5c9f5138f6aa 100644
--- a/drivers/interconnect/imx/imx.h
+++ b/drivers/interconnect/imx/imx.h
@@ -14,15 +14,6 @@
 
 #define IMX_ICC_MAX_LINKS	4
 
-/*
- * struct imx_icc_node_adj - Describe a dynamic adjustable node
- */
-struct imx_icc_node_adj_desc {
-	unsigned int bw_mul, bw_div;
-	const char *phandle_name;
-	bool main_noc;
-};
-
 /*
  * struct imx_icc_node - Describe an interconnect node
  * @name: name of the node
@@ -35,23 +26,21 @@ struct imx_icc_node_desc {
 	u16 id;
 	u16 links[IMX_ICC_MAX_LINKS];
 	u16 num_links;
-	const struct imx_icc_node_adj_desc *adj;
 };
 
-#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
+#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
 	{								\
 		.id = _id,						\
 		.name = _name,						\
-		.adj = _adj,						\
 		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
 		.links = { __VA_ARGS__ },				\
 	}
 
 #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
+	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
 
-#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
+#define DEFINE_BUS_SLAVE(_name, _id)					\
+	DEFINE_BUS_INTERCONNECT(_name, _id)
 
 int imx_icc_register(struct platform_device *pdev,
 		     struct imx_icc_node_desc *nodes,
diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
index 1083490bb391..0c16110bef9d 100644
--- a/drivers/interconnect/imx/imx8mm.c
+++ b/drivers/interconnect/imx/imx8mm.c
@@ -14,18 +14,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
 			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
 	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
 
 	/* HSIO */
 	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
-	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
 
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
@@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
 			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
index ad97e55fd4e5..8d16bd5cf006 100644
--- a/drivers/interconnect/imx/imx8mn.c
+++ b/drivers/interconnect/imx/imx8mn.c
@@ -11,18 +11,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
 			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
 
 	/* USB goes straight to NOC */
 	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
@@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
@@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN
 			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
index d7768d3c6d8a..b8c36d668946 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -12,18 +12,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
-			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
 
 	/* DISPMIX (only for DCSS) */
 	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
-	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
 
 	/* USBMIX */
 	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
 	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
-	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
 
 	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
 	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
-	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
 
 	/* AUDIO */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
 
 	/* ENET */
 	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
 
 	/* OTHER */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
@@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
 			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
 };
 
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 08:24:03 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat, 1 Jan 2022 18:24:03 +0200
Subject: [PATCH 3/3] interconnect: imx8: Remove the imx_icc_node_adj_desc
In-Reply-To: <20220101155245.3139667-3-abel.vesa@nxp.com>
References: <20220101155245.3139667-1-abel.vesa@nxp.com>
 <20220101155245.3139667-3-abel.vesa@nxp.com>
Message-ID: <YdCAI6pxnS3fk+Jm@abelvesa>

On 22-01-01 17:52:45, Abel Vesa wrote:
> Now that the imx generic interconnect doesn't use the
> imx_icc_node_adj_desc, we remove it from all the i.MX8M
> platform drivers.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>  drivers/interconnect/imx/imx.h    | 19 ++++-------------
>  drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
>  drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
>  drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
>  4 files changed, 33 insertions(+), 81 deletions(-)
> 
> diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
> index 75da51076c68..5c9f5138f6aa 100644
> --- a/drivers/interconnect/imx/imx.h
> +++ b/drivers/interconnect/imx/imx.h
> @@ -14,15 +14,6 @@
>  
>  #define IMX_ICC_MAX_LINKS	4
>  
> -/*
> - * struct imx_icc_node_adj - Describe a dynamic adjustable node
> - */
> -struct imx_icc_node_adj_desc {
> -	unsigned int bw_mul, bw_div;
> -	const char *phandle_name;
> -	bool main_noc;
> -};
> -
>  /*
>   * struct imx_icc_node - Describe an interconnect node
>   * @name: name of the node
> @@ -35,23 +26,21 @@ struct imx_icc_node_desc {
>  	u16 id;
>  	u16 links[IMX_ICC_MAX_LINKS];
>  	u16 num_links;
> -	const struct imx_icc_node_adj_desc *adj;
>  };
>  
> -#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
> +#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
>  	{								\
>  		.id = _id,						\
>  		.name = _name,						\
> -		.adj = _adj,						\
>  		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
>  		.links = { __VA_ARGS__ },				\
>  	}
>  
>  #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
> -	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
> +	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
>  
> -#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
> -	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
> +#define DEFINE_BUS_SLAVE(_name, _id)					\
> +	DEFINE_BUS_INTERCONNECT(_name, _id)
>  
>  int imx_icc_register(struct platform_device *pdev,
>  		     struct imx_icc_node_desc *nodes,
> diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
> index 1083490bb391..0c16110bef9d 100644
> --- a/drivers/interconnect/imx/imx8mm.c
> +++ b/drivers/interconnect/imx/imx8mm.c
> @@ -14,18 +14,6 @@
>  
>  #include "imx.h"
>  
> -static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 16,
> -	.phandle_name = "fsl,ddrc",
> -};
> -
> -static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 16,
> -	.main_noc = true,
> -};
> -
>  /*
>   * Describe bus masters, slaves and connections between them
>   *
> @@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
>   * PL301 nics which are skipped/merged into PL301_MAIN
>   */
>  static struct imx_icc_node_desc nodes[] = {
> -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
> +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
>  			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
>  
> -	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
> -	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
> +	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
> +	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
>  	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
>  
>  	/* VPUMIX */
>  	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
>  	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
>  	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
> -	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
>  
>  	/* GPUMIX */
>  	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
>  	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
> -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
>  
>  	/* DISPLAYMIX */
>  	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
>  	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
> -	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
>  
>  	/* HSIO */
>  	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
>  	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
>  	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
> -	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
>  
>  	/* Audio */
>  	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
>  	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
> -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
>  
>  	/* Ethernet */
>  	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
> -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
>  
>  	/* Other */
>  	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
> @@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
>  	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
>  	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
>  	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
> -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
> +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
>  			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
>  };
>  
> diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
> index ad97e55fd4e5..8d16bd5cf006 100644
> --- a/drivers/interconnect/imx/imx8mn.c
> +++ b/drivers/interconnect/imx/imx8mn.c
> @@ -11,18 +11,6 @@
>  
>  #include "imx.h"
>  
> -static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 4,
> -	.phandle_name = "fsl,ddrc",
> -};
> -
> -static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 4,
> -	.main_noc = true,
> -};
> -
>  /*
>   * Describe bus masters, slaves and connections between them
>   *
> @@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
>   * PL301 nics which are skipped/merged into PL301_MAIN
>   */
>  static struct imx_icc_node_desc nodes[] = {
> -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
> +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
>  			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
>  
> -	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
> -	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
> +	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
> +	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
>  	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
>  
>  	/* GPUMIX */
>  	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
> -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
>  
>  	/* DISPLAYMIX */
>  	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
>  	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
>  	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
>  	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
> -	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
>  
>  	/* USB goes straight to NOC */
>  	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
> @@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
>  	/* Audio */
>  	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
>  	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
> -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
>  
>  	/* Ethernet */
>  	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
> -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
>  
>  	/* Other */
>  	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
> @@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
>  	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
>  	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
>  	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
> -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
> +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN

Please ignore this series. This patch will break the build due to the
period missing at the end of the line. I'll resend V2 right away.

>  			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
>  };
>  
> diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
> index d7768d3c6d8a..b8c36d668946 100644
> --- a/drivers/interconnect/imx/imx8mq.c
> +++ b/drivers/interconnect/imx/imx8mq.c
> @@ -12,18 +12,6 @@
>  
>  #include "imx.h"
>  
> -static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 4,
> -	.phandle_name = "fsl,ddrc",
> -};
> -
> -static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
> -	.bw_mul = 1,
> -	.bw_div = 4,
> -	.main_noc = true,
> -};
> -
>  /*
>   * Describe bus masters, slaves and connections between them
>   *
> @@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
>   * PL301 nics which are skipped/merged into PL301_MAIN
>   */
>  static struct imx_icc_node_desc nodes[] = {
> -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
> -			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
>  
> -	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
> -	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
> +	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
> +	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
>  	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
>  
>  	/* VPUMIX */
>  	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
> -	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
>  
>  	/* GPUMIX */
>  	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
> -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
>  
>  	/* DISPMIX (only for DCSS) */
>  	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
> -	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
>  
>  	/* USBMIX */
>  	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
>  	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
> -	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
> +	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
>  
>  	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
>  	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
>  	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
>  	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
> -	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
>  
>  	/* AUDIO */
>  	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
> -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
> +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
>  
>  	/* ENET */
>  	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
> -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
> +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
>  
>  	/* OTHER */
>  	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
> @@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
>  	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
>  	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
>  	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
> -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
> +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
>  			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
>  };
>  
> -- 
> 2.31.1
>


From abel.vesa at nxp.com  Sat Jan  1 08:39:55 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 18:39:55 +0200
Subject: [PATCH v2 2/3] interconnect: imx: Add imx_icc_get_bw and
 imx_icc_aggregate functions
In-Reply-To: <20220101163956.3344467-1-abel.vesa@nxp.com>
References: <20220101163956.3344467-1-abel.vesa@nxp.com>
Message-ID: <20220101163956.3344467-2-abel.vesa@nxp.com>

The aggregate function will return whatever is the highest
rate for that specific node. The imx_icc_get_bw sets the
initial avg and peak to 0 in order to avoid setting them to
INT_MAX by the interconnect core.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

No changes since v1.

 drivers/interconnect/imx/imx.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index 34bfc7936387..4d8a2a2d2608 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -25,6 +25,23 @@ struct imx_icc_node {
 	struct dev_pm_qos_request qos_req;
 };
 
+static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+	*avg = 0;
+	*peak = 0;
+
+	return 0;
+}
+
+static int imx_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+		      u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	*agg_avg = max(*agg_avg, avg_bw);
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
 static int imx_icc_node_set(struct icc_node *node)
 {
 	struct device *dev = node->provider->dev;
@@ -233,7 +250,8 @@ int imx_icc_register(struct platform_device *pdev,
 	if (!provider)
 		return -ENOMEM;
 	provider->set = imx_icc_set;
-	provider->aggregate = icc_std_aggregate;
+	provider->get_bw = imx_icc_get_bw;
+	provider->aggregate = imx_icc_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
 	provider->dev = dev;
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 08:39:54 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 18:39:54 +0200
Subject: [PATCH v2 1/3] interconnect: imx: Switch from imx_icc_node_adj_desc
 to fsl, icc-id node assignment
Message-ID: <20220101163956.3344467-1-abel.vesa@nxp.com>

In order to be able to have more than one NoCs in the interconnect net
we need to decouple the NoC from the dram. So instead of using the
imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
each NoC (or pl301) to the icc node (based on the id) to it.
Along with all the NoC and pl301 nodes in the dts we will have a
interconnect dedicated node. This node will be the actual device of the
icc provider.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

No changes since v1.

 drivers/interconnect/imx/imx.c | 70 +++++++++++++++-------------------
 1 file changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index c770951a909c..34bfc7936387 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -34,8 +34,8 @@ static int imx_icc_node_set(struct icc_node *node)
 	if (!node_data->qos_dev)
 		return 0;
 
-	freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
-	do_div(freq, node_data->desc->adj->bw_div);
+	freq = max(node->avg_bw, node->peak_bw);
+
 	dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq %llukHz\n",
 		node->name, dev_name(node_data->qos_dev),
 		node->avg_bw, node->peak_bw, freq);
@@ -79,41 +79,35 @@ static int imx_icc_node_init_qos(struct icc_provider *provider,
 				 struct icc_node *node)
 {
 	struct imx_icc_node *node_data = node->data;
-	const struct imx_icc_node_adj_desc *adj = node_data->desc->adj;
 	struct device *dev = provider->dev;
-	struct device_node *dn = NULL;
 	struct platform_device *pdev;
+	struct device_node *np = NULL, *dn = NULL;
+	int idx;
 
-	if (adj->main_noc) {
-		node_data->qos_dev = dev;
-		dev_dbg(dev, "icc node %s[%d] is main noc itself\n",
-			node->name, node->id);
-	} else {
-		dn = of_parse_phandle(dev->of_node, adj->phandle_name, 0);
-		if (!dn) {
-			dev_warn(dev, "Failed to parse %s\n",
-				 adj->phandle_name);
-			return -ENODEV;
-		}
-		/* Allow scaling to be disabled on a per-node basis */
-		if (!of_device_is_available(dn)) {
-			dev_warn(dev, "Missing property %s, skip scaling %s\n",
-				 adj->phandle_name, node->name);
-			of_node_put(dn);
-			return 0;
-		}
+	for_each_node_with_property(np, "fsl,icc-id") {
+		of_property_read_u32(np, "fsl,icc-id", &idx);
+		if (idx == node_data->desc->id)
+			dn = np;
+	}
 
-		pdev = of_find_device_by_node(dn);
-		of_node_put(dn);
-		if (!pdev) {
-			dev_warn(dev, "node %s[%d] missing device for %pOF\n",
-				 node->name, node->id, dn);
-			return -EPROBE_DEFER;
-		}
-		node_data->qos_dev = &pdev->dev;
-		dev_dbg(dev, "node %s[%d] has device node %pOF\n",
-			node->name, node->id, dn);
+	if (!dn)
+		return 0;
+
+	if (!of_device_is_available(dn)) {
+		dev_warn(dev, "%pOF is disabled\n", dn);
+		return 0;
+	}
+
+	pdev = of_find_device_by_node(dn);
+	of_node_put(dn);
+	if (!pdev) {
+		dev_warn(dev, "node %s[%d] missing device for %pOF\n",
+			 node->name, node->id, dn);
+		return -EPROBE_DEFER;
 	}
+	node_data->qos_dev = &pdev->dev;
+	dev_dbg(dev, "node %s[%d] has device node %pOF\n", node->name,
+							node->id, dn);
 
 	return dev_pm_qos_add_request(node_data->qos_dev,
 				      &node_data->qos_req,
@@ -151,12 +145,10 @@ static struct icc_node *imx_icc_node_add(struct icc_provider *provider,
 	node_data->desc = node_desc;
 	icc_node_add(node, provider);
 
-	if (node_desc->adj) {
-		ret = imx_icc_node_init_qos(provider, node);
-		if (ret < 0) {
-			imx_icc_node_destroy(node);
-			return ERR_PTR(ret);
-		}
+	ret = imx_icc_node_init_qos(provider, node);
+	if (ret < 0) {
+		imx_icc_node_destroy(node);
+		return ERR_PTR(ret);
 	}
 
 	return node;
@@ -244,7 +236,7 @@ int imx_icc_register(struct platform_device *pdev,
 	provider->aggregate = icc_std_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
-	provider->dev = dev->parent;
+	provider->dev = dev;
 	platform_set_drvdata(pdev, provider);
 
 	ret = icc_provider_add(provider);
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 08:39:56 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat,  1 Jan 2022 18:39:56 +0200
Subject: [PATCH v2 3/3] interconnect: imx8: Remove the imx_icc_node_adj_desc
In-Reply-To: <20220101163956.3344467-1-abel.vesa@nxp.com>
References: <20220101163956.3344467-1-abel.vesa@nxp.com>
Message-ID: <20220101163956.3344467-3-abel.vesa@nxp.com>

Now that the imx generic interconnect doesn't use the
imx_icc_node_adj_desc, we remove it from all the i.MX8M
platform drivers.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v1:
 * added missing comma for the "PL301_MAIN" node in i.MX8MN which fixes
   the build

 drivers/interconnect/imx/imx.h    | 19 ++++-------------
 drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
 drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
 drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
 4 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
index 75da51076c68..5c9f5138f6aa 100644
--- a/drivers/interconnect/imx/imx.h
+++ b/drivers/interconnect/imx/imx.h
@@ -14,15 +14,6 @@
 
 #define IMX_ICC_MAX_LINKS	4
 
-/*
- * struct imx_icc_node_adj - Describe a dynamic adjustable node
- */
-struct imx_icc_node_adj_desc {
-	unsigned int bw_mul, bw_div;
-	const char *phandle_name;
-	bool main_noc;
-};
-
 /*
  * struct imx_icc_node - Describe an interconnect node
  * @name: name of the node
@@ -35,23 +26,21 @@ struct imx_icc_node_desc {
 	u16 id;
 	u16 links[IMX_ICC_MAX_LINKS];
 	u16 num_links;
-	const struct imx_icc_node_adj_desc *adj;
 };
 
-#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
+#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
 	{								\
 		.id = _id,						\
 		.name = _name,						\
-		.adj = _adj,						\
 		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
 		.links = { __VA_ARGS__ },				\
 	}
 
 #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
+	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
 
-#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
+#define DEFINE_BUS_SLAVE(_name, _id)					\
+	DEFINE_BUS_INTERCONNECT(_name, _id)
 
 int imx_icc_register(struct platform_device *pdev,
 		     struct imx_icc_node_desc *nodes,
diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
index 1083490bb391..0c16110bef9d 100644
--- a/drivers/interconnect/imx/imx8mm.c
+++ b/drivers/interconnect/imx/imx8mm.c
@@ -14,18 +14,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
 			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
 	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
 
 	/* HSIO */
 	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
-	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
 
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
@@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
 			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
index ad97e55fd4e5..f03f8db00917 100644
--- a/drivers/interconnect/imx/imx8mn.c
+++ b/drivers/interconnect/imx/imx8mn.c
@@ -11,18 +11,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
 			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
 
 	/* USB goes straight to NOC */
 	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
@@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
@@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN,
 			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
index d7768d3c6d8a..b8c36d668946 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -12,18 +12,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
-			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
 
 	/* DISPMIX (only for DCSS) */
 	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
-	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
 
 	/* USBMIX */
 	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
 	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
-	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
 
 	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
 	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
-	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
 
 	/* AUDIO */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
 
 	/* ENET */
 	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
 
 	/* OTHER */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
@@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
 			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
 };
 
-- 
2.31.1



From abel.vesa at nxp.com  Sat Jan  1 08:41:10 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Sat, 1 Jan 2022 18:41:10 +0200
Subject: [PATCH 3/3] interconnect: imx8: Remove the imx_icc_node_adj_desc
In-Reply-To: <YdCAI6pxnS3fk+Jm@abelvesa>
References: <20220101155245.3139667-1-abel.vesa@nxp.com>
 <20220101155245.3139667-3-abel.vesa@nxp.com>
 <YdCAI6pxnS3fk+Jm@abelvesa>
Message-ID: <YdCEJr0bijT+eJBj@abelvesa>

On 22-01-01 18:24:03, Abel Vesa wrote:
> On 22-01-01 17:52:45, Abel Vesa wrote:
> > Now that the imx generic interconnect doesn't use the
> > imx_icc_node_adj_desc, we remove it from all the i.MX8M
> > platform drivers.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> > ---
> >  drivers/interconnect/imx/imx.h    | 19 ++++-------------
> >  drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
> >  drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
> >  drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
> >  4 files changed, 33 insertions(+), 81 deletions(-)
> > 
> > diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
> > index 75da51076c68..5c9f5138f6aa 100644
> > --- a/drivers/interconnect/imx/imx.h
> > +++ b/drivers/interconnect/imx/imx.h
> > @@ -14,15 +14,6 @@
> >  
> >  #define IMX_ICC_MAX_LINKS	4
> >  
> > -/*
> > - * struct imx_icc_node_adj - Describe a dynamic adjustable node
> > - */
> > -struct imx_icc_node_adj_desc {
> > -	unsigned int bw_mul, bw_div;
> > -	const char *phandle_name;
> > -	bool main_noc;
> > -};
> > -
> >  /*
> >   * struct imx_icc_node - Describe an interconnect node
> >   * @name: name of the node
> > @@ -35,23 +26,21 @@ struct imx_icc_node_desc {
> >  	u16 id;
> >  	u16 links[IMX_ICC_MAX_LINKS];
> >  	u16 num_links;
> > -	const struct imx_icc_node_adj_desc *adj;
> >  };
> >  
> > -#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
> > +#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
> >  	{								\
> >  		.id = _id,						\
> >  		.name = _name,						\
> > -		.adj = _adj,						\
> >  		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
> >  		.links = { __VA_ARGS__ },				\
> >  	}
> >  
> >  #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
> > -	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
> > +	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
> >  
> > -#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
> > -	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
> > +#define DEFINE_BUS_SLAVE(_name, _id)					\
> > +	DEFINE_BUS_INTERCONNECT(_name, _id)
> >  
> >  int imx_icc_register(struct platform_device *pdev,
> >  		     struct imx_icc_node_desc *nodes,
> > diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
> > index 1083490bb391..0c16110bef9d 100644
> > --- a/drivers/interconnect/imx/imx8mm.c
> > +++ b/drivers/interconnect/imx/imx8mm.c
> > @@ -14,18 +14,6 @@
> >  
> >  #include "imx.h"
> >  
> > -static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 16,
> > -	.phandle_name = "fsl,ddrc",
> > -};
> > -
> > -static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 16,
> > -	.main_noc = true,
> > -};
> > -
> >  /*
> >   * Describe bus masters, slaves and connections between them
> >   *
> > @@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
> >   * PL301 nics which are skipped/merged into PL301_MAIN
> >   */
> >  static struct imx_icc_node_desc nodes[] = {
> > -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
> > +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
> >  			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
> >  
> > -	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
> > -	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
> > +	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
> > +	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
> >  	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
> >  
> >  	/* VPUMIX */
> >  	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
> >  	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
> >  	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
> >  
> >  	/* GPUMIX */
> >  	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
> >  	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
> > -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
> >  
> >  	/* DISPLAYMIX */
> >  	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
> >  	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
> > -	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
> >  
> >  	/* HSIO */
> >  	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
> >  	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
> >  	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
> >  
> >  	/* Audio */
> >  	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
> >  	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
> >  
> >  	/* Ethernet */
> >  	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
> > -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
> >  
> >  	/* Other */
> >  	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
> > @@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
> >  	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
> > -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
> > +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
> >  			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
> >  };
> >  
> > diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
> > index ad97e55fd4e5..8d16bd5cf006 100644
> > --- a/drivers/interconnect/imx/imx8mn.c
> > +++ b/drivers/interconnect/imx/imx8mn.c
> > @@ -11,18 +11,6 @@
> >  
> >  #include "imx.h"
> >  
> > -static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 4,
> > -	.phandle_name = "fsl,ddrc",
> > -};
> > -
> > -static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 4,
> > -	.main_noc = true,
> > -};
> > -
> >  /*
> >   * Describe bus masters, slaves and connections between them
> >   *
> > @@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
> >   * PL301 nics which are skipped/merged into PL301_MAIN
> >   */
> >  static struct imx_icc_node_desc nodes[] = {
> > -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
> > +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
> >  			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
> >  
> > -	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
> > -	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
> > +	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
> > +	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
> >  	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
> >  
> >  	/* GPUMIX */
> >  	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
> > -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
> >  
> >  	/* DISPLAYMIX */
> >  	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
> >  	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
> >  	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
> >  	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
> > -	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
> >  
> >  	/* USB goes straight to NOC */
> >  	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
> > @@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
> >  	/* Audio */
> >  	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
> >  	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
> >  
> >  	/* Ethernet */
> >  	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
> > -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
> >  
> >  	/* Other */
> >  	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
> > @@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
> >  	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
> > -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
> > +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN
> 
> Please ignore this series. This patch will break the build due to the
> period missing at the end of the line. I'll resend V2 right away.

Sorry, I meant comma.

> 
> >  			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
> >  };
> >  
> > diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
> > index d7768d3c6d8a..b8c36d668946 100644
> > --- a/drivers/interconnect/imx/imx8mq.c
> > +++ b/drivers/interconnect/imx/imx8mq.c
> > @@ -12,18 +12,6 @@
> >  
> >  #include "imx.h"
> >  
> > -static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 4,
> > -	.phandle_name = "fsl,ddrc",
> > -};
> > -
> > -static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
> > -	.bw_mul = 1,
> > -	.bw_div = 4,
> > -	.main_noc = true,
> > -};
> > -
> >  /*
> >   * Describe bus masters, slaves and connections between them
> >   *
> > @@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
> >   * PL301 nics which are skipped/merged into PL301_MAIN
> >   */
> >  static struct imx_icc_node_desc nodes[] = {
> > -	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
> > -			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
> >  
> > -	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
> > -	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
> > +	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
> > +	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
> >  	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
> >  
> >  	/* VPUMIX */
> >  	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
> >  
> >  	/* GPUMIX */
> >  	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
> > -	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
> >  
> >  	/* DISPMIX (only for DCSS) */
> >  	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
> > -	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
> >  
> >  	/* USBMIX */
> >  	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
> >  	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
> > -	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
> > +	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
> >  
> >  	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
> >  	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
> >  	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
> >  	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
> > -	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
> >  
> >  	/* AUDIO */
> >  	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
> > -	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
> > +	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
> >  
> >  	/* ENET */
> >  	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
> > -	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
> > +	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
> >  
> >  	/* OTHER */
> >  	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
> > @@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
> >  	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
> >  	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
> > -	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
> > +	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
> >  			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
> >  };
> >  
> > -- 
> > 2.31.1
> >


From andrew at lunn.ch  Sat Jan  1 09:18:54 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 1 Jan 2022 18:18:54 +0100
Subject: [PATCH v9 1/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
In-Reply-To: <Yc9tk6IZ0ldqHx4Y@makrotopia.org>
References: <Ycr5Cna76eg2B0An@shell.armlinux.org.uk>
 <Yc9tk6IZ0ldqHx4Y@makrotopia.org>
Message-ID: <YdCM/mbeT66asmj7@lunn.ch>

On Fri, Dec 31, 2021 at 08:52:35PM +0000, Russell King (Oracle) wrote:
> Add a couple of helpers and definitions to extract the clause 45 regad
> and devad fields from the regnum passed into MDIO drivers.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

This email has me confused. It seems to be coming directly from
Russell, but is part of a patchset? Then there is a second 1/3 later
in the patchset?

	 Andrew


From andrew at lunn.ch  Sat Jan  1 09:20:38 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sat, 1 Jan 2022 18:20:38 +0100
Subject: [PATCH v9 1/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
In-Reply-To: <Yc9uphz7RGb63kzM@makrotopia.org>
References: <Ycr5Cna76eg2B0An@shell.armlinux.org.uk>
 <Yc9uphz7RGb63kzM@makrotopia.org>
Message-ID: <YdCNZh5PsBwbfMtp@lunn.ch>

On Fri, Dec 31, 2021 at 08:57:43PM +0000, Daniel Golle wrote:
> From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
> 
> Add a couple of helpers and definitions to extract the clause 45 regad
> and devad fields from the regnum passed into MDIO drivers.
> 
> Tested-by: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Hi Daniel

Since you are submitted this, your Signed-off-by: needs to be last.

      Andrew


From djakov at kernel.org  Sat Jan  1 09:25:34 2022
From: djakov at kernel.org (Georgi Djakov)
Date: Sat, 1 Jan 2022 19:25:34 +0200
Subject: [PATCH v2 1/3] interconnect: imx: Switch from
 imx_icc_node_adj_desc to fsl,icc-id node assignment
In-Reply-To: <20220101163956.3344467-1-abel.vesa@nxp.com>
References: <20220101163956.3344467-1-abel.vesa@nxp.com>
Message-ID: <aef1ecb9-0757-0bbf-74a5-70d88fd52e08@kernel.org>

Hi Abel,

Thanks for working on this!

On 1.01.22 18:39, Abel Vesa wrote:
> In order to be able to have more than one NoCs in the interconnect net
> we need to decouple the NoC from the dram. So instead of using the
> imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
> each NoC (or pl301) to the icc node (based on the id) to it.

I believe that this DT property should be documented somewhere.
Maybe in Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml?

BR,
Georgi

> Along with all the NoC and pl301 nodes in the dts we will have a
> interconnect dedicated node. This node will be the actual device of the
> icc provider.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
> 
> No changes since v1.
> 
>   drivers/interconnect/imx/imx.c | 70 +++++++++++++++-------------------
>   1 file changed, 31 insertions(+), 39 deletions(-)



From daniel at makrotopia.org  Sat Jan  1 09:41:07 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Sat, 1 Jan 2022 17:41:07 +0000
Subject: [PATCH v9 1/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
In-Reply-To: <YdCM/mbeT66asmj7@lunn.ch>
References: <Ycr5Cna76eg2B0An@shell.armlinux.org.uk>
 <Yc9tk6IZ0ldqHx4Y@makrotopia.org> <YdCM/mbeT66asmj7@lunn.ch>
Message-ID: <YdCSM7DiJ+vvfmji@makrotopia.org>

On Sat, Jan 01, 2022 at 06:18:54PM +0100, Andrew Lunn wrote:
> On Fri, Dec 31, 2021 at 08:52:35PM +0000, Russell King (Oracle) wrote:
> > Add a couple of helpers and definitions to extract the clause 45 regad
> > and devad fields from the regnum passed into MDIO drivers.
> > 
> > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> This email has me confused. It seems to be coming directly from
> Russell, but is part of a patchset? Then there is a second 1/3 later
> in the patchset?

That happened by accident when using git-send-email and hence the
first time it was sent with Russell's From: in the RFC822 headers it
was (rightly) rejected.
I noticed that shortly after and resend the patch with my sender
address set as From: in the RFC822 headers and Russell's From: in the
mail body for only git, and not mailservers, to care about.

Sorry for that additional noise.


From djakov at kernel.org  Sat Jan  1 10:26:05 2022
From: djakov at kernel.org (Georgi Djakov)
Date: Sat, 1 Jan 2022 20:26:05 +0200
Subject: [PATCH v2 2/3] interconnect: imx: Add imx_icc_get_bw and
 imx_icc_aggregate functions
In-Reply-To: <20220101163956.3344467-2-abel.vesa@nxp.com>
References: <20220101163956.3344467-1-abel.vesa@nxp.com>
 <20220101163956.3344467-2-abel.vesa@nxp.com>
Message-ID: <048650ad-e015-3733-bdf2-72b7a0ed61e4@kernel.org>

Hi Abel,

On 1.01.22 18:39, Abel Vesa wrote:
> The aggregate function will return whatever is the highest
> rate for that specific node. The imx_icc_get_bw sets the

Adding some more details about why we switch from
icc_std_aggregate to imx_icc_aggregate would be nice.

> initial avg and peak to 0 in order to avoid setting them to
> INT_MAX by the interconnect core.

Do we need a Fixes tag for this?

I would recommend to split imx_icc_get_bw and imx_icc_aggregate
changes into separate patches. These also seem to be unrelated to
the imx_icc_node_adj_desc patchset.

Thanks,
Georgi

> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
> 
> No changes since v1.
> 
>   drivers/interconnect/imx/imx.c | 20 +++++++++++++++++++-
>   1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
> index 34bfc7936387..4d8a2a2d2608 100644
> --- a/drivers/interconnect/imx/imx.c
> +++ b/drivers/interconnect/imx/imx.c
> @@ -25,6 +25,23 @@ struct imx_icc_node {
>   	struct dev_pm_qos_request qos_req;
>   };
>   
> +static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
> +{
> +	*avg = 0;
> +	*peak = 0;
> +
> +	return 0;
> +}
> +
> +static int imx_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> +		      u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	*agg_avg = max(*agg_avg, avg_bw);
> +	*agg_peak = max(*agg_peak, peak_bw);
> +
> +	return 0;
> +}
> +
>   static int imx_icc_node_set(struct icc_node *node)
>   {
>   	struct device *dev = node->provider->dev;
> @@ -233,7 +250,8 @@ int imx_icc_register(struct platform_device *pdev,
>   	if (!provider)
>   		return -ENOMEM;
>   	provider->set = imx_icc_set;
> -	provider->aggregate = icc_std_aggregate;
> +	provider->get_bw = imx_icc_get_bw;
> +	provider->aggregate = imx_icc_aggregate;
>   	provider->xlate = of_icc_xlate_onecell;
>   	provider->data = data;
>   	provider->dev = dev;



From stefan.wahren at i2se.com  Sat Jan  1 12:26:49 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  1 Jan 2022 21:26:49 +0100
Subject: [PATCH RFC 1/4] brcmfmac: use separate firmware for 43430 revision 4
In-Reply-To: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>

A separate firmware is needed, for Broadcom 43430 revision 4. This
chip can be found on e.g. certain revisions of Raspberry Pi Zero 2 W.
Original firmware file from IC vendor is named 'brcmfmac43436-sdio.bin',
but brcmfmac and also btbcm drivers report chip id 43430, so requested
firmware file name is 'brcmfmac43430c0-sdio.bin' in line with other
43430 revisions.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---

Hi,
i'm not sure about all these mappings. All i can say is that the wifi
interface of the RPi Zero 2 cames up with this patch.

 drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
index 8effeb7..c79bd47 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -618,6 +618,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
 /* Note the names are not postfixed with a1 for backward compatibility */
 BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
 BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
+BRCMF_FW_CLM_DEF(43430C0, "brcmfmac43430c0-sdio");
 BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
 BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
 BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
@@ -649,7 +650,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
 	BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
 	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
 	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
-	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
+	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43430C0),
+	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFF8, 43430B0),
 	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
 	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
 	BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Jan  1 12:26:51 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  1 Jan 2022 21:26:51 +0100
Subject: [PATCH RFC 3/4] ARM: dts: Add Raspberry Pi Zero 2 W
In-Reply-To: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1641068812-5851-4-git-send-email-stefan.wahren@i2se.com>

The Raspberry Pi Zero 2 W mostly bases on the Raspberry Pi Zero W with
the following differences:
* Broadcom BCM2710A1, quad-core 64-bit SoC @ 1 GHz
* Synaptics BCM43436, 2.4GHz IEEE 802.11b/g/n wireless LAN

Contrary to the Raspberry Pi 3 boards there is no GPIO expander.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm/boot/dts/Makefile                 |   1 +
 arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts | 136 +++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e41eca7..3d5785a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -93,6 +93,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
 	bcm2837-rpi-3-b.dtb \
 	bcm2837-rpi-3-b-plus.dtb \
 	bcm2837-rpi-cm3-io3.dtb \
+	bcm2837-rpi-zero-2-w.dtb \
 	bcm2711-rpi-400.dtb \
 	bcm2711-rpi-4-b.dtb \
 	bcm2711-rpi-cm4-io.dtb \
diff --git a/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts b/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts
new file mode 100644
index 0000000..60e6880
--- /dev/null
+++ b/arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 Stefan Wahren <stefan.wahren at i2se.com>
+ */
+
+/dts-v1/;
+#include "bcm2837.dtsi"
+#include "bcm2836-rpi.dtsi"
+#include "bcm283x-rpi-usb-otg.dtsi"
+#include "bcm283x-rpi-wifi-bt.dtsi"
+
+/ {
+	compatible = "raspberrypi,model-zero-2-w", "brcm,bcm2837";
+	model = "Raspberry Pi Zero 2 W";
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0 0x20000000>;
+	};
+
+	chosen {
+		/* 8250 auxiliary UART instead of pl011 */
+		stdout-path = "serial1:115200n8";
+	};
+
+	leds {
+		led-act {
+			gpios = <&gpio 29 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&bt {
+	shutdown-gpios = <&gpio 42 GPIO_ACTIVE_HIGH>;
+};
+
+&gpio {
+	/*
+	 * This is based on the official GPU firmware DT blob.
+	 *
+	 * Legend:
+	 * "NC" = not connected (no rail from the SoC)
+	 * "FOO" = GPIO line named "FOO" on the schematic
+	 * "FOO_N" = GPIO line named "FOO" on schematic, active low
+	 */
+	gpio-line-names = "ID_SDA",
+			  "ID_SCL",
+			  "SDA1",
+			  "SCL1",
+			  "GPIO_GCLK",
+			  "GPIO5",
+			  "GPIO6",
+			  "SPI_CE1_N",
+			  "SPI_CE0_N",
+			  "SPI_MISO",
+			  "SPI_MOSI",
+			  "SPI_SCLK",
+			  "GPIO12",
+			  "GPIO13",
+			  /* Serial port */
+			  "TXD0",
+			  "RXD0",
+			  "GPIO16",
+			  "GPIO17",
+			  "GPIO18",
+			  "GPIO19",
+			  "GPIO20",
+			  "GPIO21",
+			  "GPIO22",
+			  "GPIO23",
+			  "GPIO24",
+			  "GPIO25",
+			  "GPIO26",
+			  "GPIO27",
+			  "HDMI_HPD_N",
+			  "STATUS_LED_N",
+			  "NC", /* GPIO30 */
+			  "NC", /* GPIO31 */
+			  "NC", /* GPIO32 */
+			  "NC", /* GPIO33 */
+			  "NC", /* GPIO34 */
+			  "NC", /* GPIO35 */
+			  "NC", /* GPIO36 */
+			  "NC", /* GPIO37 */
+			  "NC", /* GPIO38 */
+			  "NC", /* GPIO39 */
+			  "CAM_GPIO0", /* GPIO40 */
+			  "WL_ON", /* GPIO41 */
+			  "BT_ON", /* GPIO42 */
+			  "WIFI_CLK", /* GPIO43 */
+			  "SDA0", /* GPIO44 */
+			  "SCL0", /* GPIO45 */
+			  "SMPS_SCL",
+			  "SMPS_SDA",
+			  /* Used by SD Card */
+			  "SD_CLK_R",
+			  "SD_CMD_R",
+			  "SD_DATA0_R",
+			  "SD_DATA1_R",
+			  "SD_DATA2_R",
+			  "SD_DATA3_R";
+
+	pinctrl-0 = <&gpioout &alt0>;
+};
+
+&hdmi {
+	hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+	power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+	status = "okay";
+};
+
+&sdhci {
+	pinctrl-0 = <&emmc_gpio34 &gpclk2_gpio43>;
+};
+
+&sdhost {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdhost_gpio48>;
+	bus-width = <4>;
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
+};
+
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart1_gpio14>;
+	status = "okay";
+};
+
+&wifi_pwrseq {
+	reset-gpios = <&gpio 41 GPIO_ACTIVE_LOW>;
+};
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Jan  1 12:26:48 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  1 Jan 2022 21:26:48 +0100
Subject: [PATCH RFC 0/4] ARM: dts: Add Raspberry Pi Zero 2 W support
Message-ID: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>

This small series tries to add support for the Raspberry Pi Zero 2 W.

Stefan Wahren (4):
  brcmfmac: use separate firmware for 43430 revision 4
  dt-bindings: arm: bcm2835: Add Raspberry Pi Zero 2 W
  ARM: dts: Add Raspberry Pi Zero 2 W
  arm64: dts: broadcom: Add reference to RPi Zero 2 W

 .../devicetree/bindings/arm/bcm/bcm2835.yaml       |   1 +
 arch/arm/boot/dts/Makefile                         |   1 +
 arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts         | 136 +++++++++++++++++++++
 arch/arm64/boot/dts/broadcom/Makefile              |   3 +-
 .../boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts     |   2 +
 .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |   4 +-
 6 files changed, 145 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/bcm2837-rpi-zero-2-w.dts
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts

-- 
2.7.4



From stefan.wahren at i2se.com  Sat Jan  1 12:26:50 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  1 Jan 2022 21:26:50 +0100
Subject: [PATCH RFC 2/4] dt-bindings: arm: bcm2835: Add Raspberry Pi Zero 2 W
In-Reply-To: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1641068812-5851-3-git-send-email-stefan.wahren@i2se.com>

Add the Raspberry Pi Zero 2 W to DT schema.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
index 5dc4824..8051a75 100644
--- a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
+++ b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
@@ -51,6 +51,7 @@ properties:
               - raspberrypi,3-model-b-plus
               - raspberrypi,3-compute-module
               - raspberrypi,3-compute-module-lite
+              - raspberrypi,model-zero-2-w
           - const: brcm,bcm2837
 
 additionalProperties: true
-- 
2.7.4



From stefan.wahren at i2se.com  Sat Jan  1 12:26:52 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat,  1 Jan 2022 21:26:52 +0100
Subject: [PATCH RFC 4/4] arm64: dts: broadcom: Add reference to RPi Zero 2 W
In-Reply-To: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <1641068812-5851-5-git-send-email-stefan.wahren@i2se.com>

This adds a reference to the dts of the Raspberry Pi Zero 2 W,
so we don't need to maintain the content in arm64.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
---
 arch/arm64/boot/dts/broadcom/Makefile                 | 3 ++-
 arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts

diff --git a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile
index c688203..5082fcd 100644
--- a/arch/arm64/boot/dts/broadcom/Makefile
+++ b/arch/arm64/boot/dts/broadcom/Makefile
@@ -5,7 +5,8 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2711-rpi-400.dtb \
 			      bcm2837-rpi-3-a-plus.dtb \
 			      bcm2837-rpi-3-b.dtb \
 			      bcm2837-rpi-3-b-plus.dtb \
-			      bcm2837-rpi-cm3-io3.dtb
+			      bcm2837-rpi-cm3-io3.dtb \
+			      bcm2837-rpi-zero-2-w.dtb
 
 subdir-y	+= bcm4908
 subdir-y	+= northstar2
diff --git a/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts
new file mode 100644
index 0000000..307ae69
--- /dev/null
+++ b/arch/arm64/boot/dts/broadcom/bcm2837-rpi-zero-2-w.dts
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "arm/bcm2837-rpi-zero-2-w.dts"
-- 
2.7.4



From alistair23 at gmail.com  Sat Jan  1 14:02:55 2022
From: alistair23 at gmail.com (Alistair Francis)
Date: Sun, 2 Jan 2022 08:02:55 +1000
Subject: [PATCH v17 0/8] Add support for the silergy,sy7636a
In-Reply-To: <20211216122525.136139-1-alistair@alistair23.me>
References: <20211216122525.136139-1-alistair@alistair23.me>
Message-ID: <CAKmqyKP79x-PdEiBAye3tBtYgj17T6WF6pM84vXVHYwPNXshgg@mail.gmail.com>

On Thu, Dec 16, 2021 at 10:25 PM Alistair Francis
<alistair at alistair23.me> wrote:
>
> v17:
>  - Rebase and fix build issues
> v16:
>  - Improve vdd regulator comments
> v15:
>  - Address comments on the patches
> v14:
>  - Merge the thermal driver and hwmon
> v13:
>  - Address comments on thermal driver
>  - Rebase on master (without other patches)
> v12:
>  - Rebase
> v11:
>  - Address comments on hwmon
>  - Improve "mfd: simple-mfd-i2c: Add a Kconfig name" commit message
> v10:
>  - Use dev_get_regmap() instead of dev_get_drvdata()
> v9:
>  - Convert to use the simple-mfd-i2c instead
>
> Alistair Francis (8):
>   dt-bindings: mfd: Initial commit of silergy,sy7636a.yaml
>   mfd: simple-mfd-i2c: Add a Kconfig name
>   mfd: simple-mfd-i2c: Enable support for the silergy,sy7636a
>   regulator: sy7636a: Remove requirement on sy7636a mfd
>   hwmon: sy7636a: Add temperature driver for sy7636a
>   ARM: imx_v6_v7_defconfig: Enable silergy,sy7636a
>   ARM: dts: imx7d-remarkable2: Enable silergy,sy7636a
>   ARM: dts: imx7d-remarkable2: Enable lcdif

All of the code changes have been reviewed or acked. Could some of
these patches go into 5.17?

Alistair

>
>  .../bindings/mfd/silergy,sy7636a.yaml         |  82 +++++++++++
>  Documentation/hwmon/index.rst                 |   1 +
>  Documentation/hwmon/sy7636a-hwmon.rst         |  26 ++++
>  arch/arm/boot/dts/imx7d-remarkable2.dts       | 136 ++++++++++++++++++
>  arch/arm/configs/imx_v6_v7_defconfig          |   3 +
>  drivers/hwmon/Kconfig                         |   9 ++
>  drivers/hwmon/Makefile                        |   1 +
>  drivers/hwmon/sy7636a-hwmon.c                 | 106 ++++++++++++++
>  drivers/mfd/Kconfig                           |   2 +-
>  drivers/mfd/simple-mfd-i2c.c                  |  11 ++
>  drivers/regulator/Kconfig                     |   1 -
>  drivers/regulator/sy7636a-regulator.c         |   7 +-
>  include/linux/mfd/sy7636a.h                   |  34 +++++
>  13 files changed, 415 insertions(+), 4 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
>  create mode 100644 Documentation/hwmon/sy7636a-hwmon.rst
>  create mode 100644 drivers/hwmon/sy7636a-hwmon.c
>  create mode 100644 include/linux/mfd/sy7636a.h
>
> --
> 2.31.1
>


From marcel.ziswiler at toradex.com  Sat Jan  1 15:55:27 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Sat, 1 Jan 2022 23:55:27 +0000
Subject: [PATCH V2 1/4] pinctrl: imx: prepare for making "group_names" in
 "function_desc" const
In-Reply-To: <YcOJieHGeA7p+NIF@ryzen>
References: <20211216162206.8027-1-zajec5@gmail.com>	 <YcOJieHGeA7p+NIF@ryzen>
Message-ID: <b9fe3fdd615fc0a91c9374a58f09d2f3ed38e0c3.camel@toradex.com>

On Wed, 2021-12-22 at 22:24 +0200, Abel Vesa wrote:
> On 21-12-16 17:22:03, Rafa? Mi?ecki wrote:
> > From: Rafa? Mi?ecki <rafal at milecki.pl>
> > 
> > The plan for "struct function_desc" is to make its "group_names"
> > /double/ const. That will allow drivers to use it with static const
> > data.
> > 
> > This imx change is required to avoid:
> > drivers/pinctrl/freescale/pinctrl-imx.c: In function 'imx_pinctrl_parse_functions':
> > drivers/pinctrl/freescale/pinctrl-imx.c:672:24: error: assignment of read-only location '*(func-
> > >group_names + (sizetype)(i * 4))'
> > ? 672 |?? func->group_names[i] = child->name;
> > ????? |??????????????????????? ^
> > 
> > Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> > ---
> > ?drivers/pinctrl/freescale/pinctrl-imx.c | 11 +++++++----
> > ?1 file changed, 7 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
> > index daf28bc5661d..47b2ab1a14d0 100644
> > --- a/drivers/pinctrl/freescale/pinctrl-imx.c
> > +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
> > @@ -648,6 +648,7 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
> > ????????struct device_node *child;
> > ????????struct function_desc *func;
> > ????????struct group_desc *grp;
> > +???????const char **group_names;
> > ????????u32 i = 0;
> > ?
> > ????????dev_dbg(pctl->dev, "parse function(%d): %pOFn\n", index, np);
> > @@ -663,14 +664,16 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
> > ????????????????dev_err(ipctl->dev, "no groups defined in %pOF\n", np);
> > ????????????????return -EINVAL;
> > ????????}
> > -???????func->group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
> > -??????????????????????????????????????? sizeof(char *), GFP_KERNEL);
> > +
> > +???????group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
> > +????????????????????????????????? sizeof(char *), GFP_KERNEL);
> > ????????if (!func->group_names)
> This line needs to be:
> ????????if (!group_names)
> 
> Otherwise, the driver never probes successufully.

After my i.MX 8M Mini target running latest -next just hang early boot I bisected it to this commit.

I can confirm that this fixes it. Thanks!

> Linus, maybe you can squashed this fix in your tree without a resend.
> 
> > ????????????????return -ENOMEM;
> > +???????for_each_child_of_node(np, child)
> > +???????????????group_names[i] = child->name;
> > +???????func->group_names = group_names;
> > ?
> > ????????for_each_child_of_node(np, child) {
> > -???????????????func->group_names[i] = child->name;
> > -
> > ????????????????grp = devm_kzalloc(ipctl->dev, sizeof(struct group_desc),
> > ?????????????????????????????????? GFP_KERNEL);
> > ????????????????if (!grp) {
> > -- 
> > 2.31.1
-- 
Best regards - Mit freundlichen Gr?ssen - Meilleures salutations

Marcel Ziswiler
Software Team Lead - Embedded Linux BSP

Toradex AG
Ebenaustrasse 10 | 6048 Horw/Luzern | Switzerland | T: +41 41 500 4800

From zajec5 at gmail.com  Sat Jan  1 15:58:06 2022
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Sun, 2 Jan 2022 00:58:06 +0100
Subject: [PATCH V2 1/4] pinctrl: imx: prepare for making "group_names" in
 "function_desc" const
In-Reply-To: <b9fe3fdd615fc0a91c9374a58f09d2f3ed38e0c3.camel@toradex.com>
References: <20211216162206.8027-1-zajec5@gmail.com> <YcOJieHGeA7p+NIF@ryzen>
 <b9fe3fdd615fc0a91c9374a58f09d2f3ed38e0c3.camel@toradex.com>
Message-ID: <0ce1b7cb-ae08-65fc-0e2e-1f58ebac7937@gmail.com>

On 2.01.2022 00:55, Marcel Ziswiler wrote:
> On Wed, 2021-12-22 at 22:24 +0200, Abel Vesa wrote:
>>> @@ -663,14 +664,16 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
>>>  ????????????????dev_err(ipctl->dev, "no groups defined in %pOF\n", np);
>>>  ????????????????return -EINVAL;
>>>  ????????}
>>> -???????func->group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
>>> -??????????????????????????????????????? sizeof(char *), GFP_KERNEL);
>>> +
>>> +???????group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
>>> +????????????????????????????????? sizeof(char *), GFP_KERNEL);
>>>  ????????if (!func->group_names)
>> This line needs to be:
>>  ????????if (!group_names)
>>
>> Otherwise, the driver never probes successufully.
> 
> After my i.MX 8M Mini target running latest -next just hang early boot I bisected it to this commit.
> 
> I can confirm that this fixes it. Thanks!

Please note there is one more pending fix. Please apply both:
[PATCH] pinctrl: imx: fix allocation result check
[PATCH] pinctrl: imx: fix assigning groups names


From marcel.ziswiler at toradex.com  Sat Jan  1 15:59:38 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Sat, 1 Jan 2022 23:59:38 +0000
Subject: [PATCH V2 1/4] pinctrl: imx: prepare for making "group_names" in
 "function_desc" const
In-Reply-To: <0ce1b7cb-ae08-65fc-0e2e-1f58ebac7937@gmail.com>
References: <20211216162206.8027-1-zajec5@gmail.com>	 <YcOJieHGeA7p+NIF@ryzen>
 <b9fe3fdd615fc0a91c9374a58f09d2f3ed38e0c3.camel@toradex.com>
 <0ce1b7cb-ae08-65fc-0e2e-1f58ebac7937@gmail.com>
Message-ID: <b7e316f64b55175bca2f9c986378f93ec3ae9e74.camel@toradex.com>

On Sun, 2022-01-02 at 00:58 +0100, Rafa? Mi?ecki wrote:
> On 2.01.2022 00:55, Marcel Ziswiler wrote:
> > On Wed, 2021-12-22 at 22:24 +0200, Abel Vesa wrote:
> > > > @@ -663,14 +664,16 @@ static int imx_pinctrl_parse_functions(struct device_node *np,
> > > > ?????????????????dev_err(ipctl->dev, "no groups defined in %pOF\n", np);
> > > > ?????????????????return -EINVAL;
> > > > ?????????}
> > > > -???????func->group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
> > > > -??????????????????????????????????????? sizeof(char *), GFP_KERNEL);
> > > > +
> > > > +???????group_names = devm_kcalloc(ipctl->dev, func->num_group_names,
> > > > +????????????????????????????????? sizeof(char *), GFP_KERNEL);
> > > > ?????????if (!func->group_names)
> > > This line needs to be:
> > > ?????????if (!group_names)
> > > 
> > > Otherwise, the driver never probes successufully.
> > 
> > After my i.MX 8M Mini target running latest -next just hang early boot I bisected it to this commit.
> > 
> > I can confirm that this fixes it. Thanks!
> 
> Please note there is one more pending fix. Please apply both:
> [PATCH] pinctrl: imx: fix allocation result check
> [PATCH] pinctrl: imx: fix assigning groups names

Yep, also just noticed that. Thanks!

From marcel.ziswiler at toradex.com  Sat Jan  1 16:25:54 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Sun, 2 Jan 2022 00:25:54 +0000
Subject: [PATCH v7 5/8] phy: freescale: pcie: Initialize the imx8 pcie
 standalone phy driver
In-Reply-To: <AS8PR04MB8676151C053B01293A0C1E938C459@AS8PR04MB8676.eurprd04.prod.outlook.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
 <1638432158-4119-6-git-send-email-hongxing.zhu@nxp.com>
 <7320d3fb-4338-86b8-5a49-b56f06f1cd11@linutronix.de>
 <AS8PR04MB8676151C053B01293A0C1E938C459@AS8PR04MB8676.eurprd04.prod.outlook.com>
Message-ID: <6799287e55542e777e316a6525aab2ecced50edf.camel@toradex.com>

On Thu, 2021-12-30 at 04:58 +0000, Hongxing Zhu wrote:
> > -----Original Message-----
> > From: Philip Molloy <philip at linutronix.de>
> > Sent: Wednesday, December 29, 2021 8:40 PM
> > To: Hongxing Zhu <hongxing.zhu at nxp.com>
> > Cc: l.stach at pengutronix.de; bhelgaas at google.com;
> > lorenzo.pieralisi at arm.com; tharvey at gateworks.com; Marcel Ziswiler
> > <marcel.ziswiler at toradex.com>; kishon at ti.com; vkoul at kernel.org;
> > robh at kernel.org; galak at kernel.crashing.org; shawnguo at kernel.org;
> > linux-phy at lists.infradead.org; devicetree at vger.kernel.org;
> > linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > linux-kernel at vger.kernel.org; kernel at pengutronix.de; dl-linux-imx
> > <linux-imx at nxp.com>
> > Subject: Re: [PATCH v7 5/8] phy: freescale: pcie: Initialize the imx8 pcie
> > standalone phy driver
> > 
> > Hi Richard,
> > 
> > I've run into an issue that appears to indicate a functional difference
> > between the existing integrated pci-imx6.c implementation and this new
> > implementation with the separate phy driver.
> > 
> > I'm working with a SOM and baseboard from Phytec that is based on the
> > IMX8MM. The board does not have an external PCIe clock and has a
> > ethernet controller hanging off the PCIe bus.
> > 
> > When booting from a 5.4 NXP-based kernel from Phytec the ethernet
> > controller is probed and functions as expected.
> > 
> > A co-worker backported a slightly earlier version of this patchset to
> > 5.10.[1] With our kernel both the controller driver and new PHY driver are
> > probed, but a timeout occurs in dw_pcie_wait_for_link() which indicates
> > that the "Phy link never came up".
> > 
> > After reproducing this issue I configured pcie_phy with
> > IMX8_PCIE_REFCLK_PAD_OUTPUT. With that configured, phy register
> > CMN_REG062/0x188 matches the 5.4 NXP/Phytec kernel. I then
> > compared the controller and PHY registers between the two kernels and
> > noticed that CMN_REG063/0x18c is set to AUX_IN/0x0 in the 5.4
> > NXP/Phytec kernel, but the new PHY driver writes
> > I_PLL_REFCLK_FROM_SYSPLL/0xc0 to that register.
> > 
> > If I modify the phy driver to not write I_PLL_REFCLK_FROM_SYSPLL/0xc0
> > then the system behaves as expected.
> [Richard Zhu] 
> Hi Philip:
> The address 0x018C is a register to control the output mode of Refclk IO.
> When internal syspll is used as PHY REF clock.
> Regarding my understand, this register should select the syspll, and route
> it out of SOC from CLK N/P pads.
> Then the remote EP device can use the clock from CLK N/P pads.
> 
> If the bit7-6 is set to 2b'00, there wouldn't clock output from CLK N/P pads.
> What's the hardware design of the CLK N/P pads in your project?
> Can you monitor the situation of the CLK N/P if it is possible?

I can confirm that for me similar hardware which also "does not have an external PCIe clock" works just fine
with the following device tree sniped:

&pcie0 {
	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
			  <&clk IMX8MM_CLK_PCIE1_CTRL>;
	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
				 <&clk IMX8MM_SYS_PLL2_250M>;
	assigned-clock-rates = <10000000>, <250000000>;
	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
		 <&clk IMX8MM_CLK_PCIE1_PHY>;
	clock-names = "pcie", "pcie_aux", "pcie_bus";
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_pcie0>;
	/* PCIE_1_RESET# (SODIMM 244) */
	reset-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
	status = "okay";
};

&pcie_phy {
	clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
	fsl,clkreq-unsupported;
	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
	fsl,tx-deemph-gen1 = <0x2d>;
	fsl,tx-deemph-gen2 = <0xf>;
	status = "okay";
};

During boot that looks as follows:

[    1.858312] imx6q-pcie 33800000.pcie: host bridge /soc at 0/pcie at 33800000 ranges:

[    1.865630] imx6q-pcie 33800000.pcie:       IO 0x001ff80000..0x001ff8ffff -> 0x0000000000
[    1.877833] imx6q-pcie 33800000.pcie:      MEM 0x0018000000..0x001fefffff -> 0x0018000000

[    1.992010] imx6q-pcie 33800000.pcie: iATU unroll: enabled
[    1.997523] imx6q-pcie 33800000.pcie: Detected iATU regions: 4 outbound, 4 inbound

[    2.103140] imx6q-pcie 33800000.pcie: Link up
[    2.107527] imx6q-pcie 33800000.pcie: Link up
[    2.111895] imx6q-pcie 33800000.pcie: Link up, Gen1
[    2.116786] imx6q-pcie 33800000.pcie: Link up
[    2.121298] imx6q-pcie 33800000.pcie: PCI host bridge to bus 0000:00
[    2.127671] pci_bus 0000:00: root bus resource [bus 00-ff]
[    2.133171] pci_bus 0000:00: root bus resource [io  0x0000-0xffff]
[    2.139363] pci_bus 0000:00: root bus resource [mem 0x18000000-0x1fefffff]
[    2.146282] pci 0000:00:00.0: [16c3:abcd] type 01 class 0x060400
[    2.152322] pci 0000:00:00.0: reg 0x10: [mem 0x00000000-0x000fffff]
[    2.158612] pci 0000:00:00.0: reg 0x38: [mem 0x00000000-0x0000ffff pref]
[    2.165373] pci 0000:00:00.0: supports D1
[    2.169395] pci 0000:00:00.0: PME# supported from D0 D1 D3hot D3cold
[    2.178101] pci 0000:01:00.0: [10ec:8168] type 00 class 0x020000
[    2.184196] pci 0000:01:00.0: reg 0x10: [io  0x0000-0x00ff]
[    2.189864] pci 0000:01:00.0: reg 0x18: [mem 0x00000000-0x00000fff 64bit pref]
[    2.197152] pci 0000:01:00.0: reg 0x20: [mem 0x00000000-0x00003fff 64bit pref]
[    2.204777] pci 0000:01:00.0: supports D1 D2
[    2.209059] pci 0000:01:00.0: PME# supported from D0 D1 D2 D3hot D3cold
[    2.229114] pci 0000:00:00.0: BAR 0: assigned [mem 0x18000000-0x180fffff]
[    2.235934] pci 0000:00:00.0: BAR 15: assigned [mem 0x18100000-0x181fffff pref]
[    2.243260] pci 0000:00:00.0: BAR 6: assigned [mem 0x18200000-0x1820ffff pref]
[    2.250501] pci 0000:00:00.0: BAR 13: assigned [io  0x1000-0x1fff]
[    2.256734] pci 0000:01:00.0: BAR 4: assigned [mem 0x18100000-0x18103fff 64bit pref]
[    2.264534] pci 0000:01:00.0: BAR 2: assigned [mem 0x18104000-0x18104fff 64bit pref]
[    2.272338] pci 0000:01:00.0: BAR 0: assigned [io  0x1000-0x10ff]
[    2.278460] pci 0000:00:00.0: PCI bridge to [bus 01-ff]
[    2.283698] pci 0000:00:00.0:   bridge window [io  0x1000-0x1fff]
[    2.289808] pci 0000:00:00.0:   bridge window [mem 0x18100000-0x181fffff pref]
[    2.297444] pcieport 0000:00:00.0: PME: Signaling with IRQ 225

And my mini-PCIe Ethernet card gets detected and is fully functional:

[    4.433899] r8169 0000:01:00.0: enabling device (0000 -> 0003)
[    4.466731] libphy: r8169: probed
[    4.476288] r8169 0000:01:00.0 eth1: RTL8168e/8111e, 00:e0:4c:80:f4:0d, XID 2c2, IRQ 229
[    4.484485] r8169 0000:01:00.0 eth1: jumbo features [frames: 9194 bytes, tx checksumming: ko]

[    5.023616] r8169 0000:01:00.0 enp1s0: renamed from eth1

[    6.713601] r8169 0000:01:00.0: Direct firmware load for rtl_nic/rtl8168e-2.fw failed with error -2
[    6.722786] r8169 0000:01:00.0: Unable to load firmware rtl_nic/rtl8168e-2.fw (-2)
[    6.731391] RTL8211DN Gigabit Ethernet r8169-0-100:00: attached PHY driver (mii_bus:phy_addr=r8169-0-100:00,
irq=MAC)
[    6.808798] r8169 0000:01:00.0 enp1s0: Link is Down

root at verdin-imx8mm-06760554:~# lspci
00:00.0 PCI bridge: Synopsys, Inc. DWC_usb3 / PCIe bridge (rev 01)
01:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet
Controller (rev 06)

Cheers

Marcel

> Best Regards
> Richard Zhu
> 
> > 
> > Best,
> > Philip
> > 
> > [1]: I plan on rebasing our branch with the latest patches that have been
> > applied upstream. Note that I did not see any difference in the following
> > code with what we have applied.
> > 
> > On 12/2/21 09:02, Richard Zhu wrote:
> > > +#define IMX8MM_PCIE_PHY_CMN_REG061?????0x184
> > > +#define? ANA_PLL_CLK_OUT_TO_EXT_IO_EN??BIT(0)
> > > +#define IMX8MM_PCIE_PHY_CMN_REG062?????0x188
> > > +#define? ANA_PLL_CLK_OUT_TO_EXT_IO_SEL?BIT(3)
> > > +#define IMX8MM_PCIE_PHY_CMN_REG063?????0x18C
> > > +#define? AUX_PLL_REFCLK_SEL_SYS_PLL????GENMASK(7, 6)
> > > +#define IMX8MM_PCIE_PHY_CMN_REG064?????0x190
> > > +#define? ANA_AUX_RX_TX_SEL_TX??????????BIT(7)
> > > +#define? ANA_AUX_RX_TERM_GND_EN????????????????BIT(3)
> > > +#define? ANA_AUX_TX_TERM???????????????BIT(2)
> > > +#define IMX8MM_PCIE_PHY_CMN_REG065?????0x194
> > > +#define? ANA_AUX_RX_TERM???????????????(BIT(7) | BIT(4))
> > > +#define? ANA_AUX_TX_LVL????????????????????????GENMASK(3, 0)
> > ...
> > > +???????if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT) {
> > > +???????????????/* Configure the pad as input */
> > > +???????????????val = readl(imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG061);
> > > +???????????????writel(val & ~ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG061);
> > > +???????} else if (pad_mode == IMX8_PCIE_REFCLK_PAD_OUTPUT) {
> > > +???????????????/* Configure the PHY to output the refclock via pad */
> > > +???????????????writel(ANA_PLL_CLK_OUT_TO_EXT_IO_EN,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG061);
> > > +???????????????writel(ANA_PLL_CLK_OUT_TO_EXT_IO_SEL,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG062);
> > > +???????????????writel(AUX_PLL_REFCLK_SEL_SYS_PLL,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG063);
> > 
> > If I comment out this writel() then the register defaults to 0x0/AUX_IN
> > and then the system behaves as expected.
> > 
> > > +???????????????val = ANA_AUX_RX_TX_SEL_TX | ANA_AUX_TX_TERM;
> > > +???????????????writel(val | ANA_AUX_RX_TERM_GND_EN,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG064);
> > > +???????????????writel(ANA_AUX_RX_TERM | ANA_AUX_TX_LVL,
> > > +????????????????????? imx8_phy->base +
> > IMX8MM_PCIE_PHY_CMN_REG065);
> > > +???????}

From andreyknvl at gmail.com  Sat Jan  1 18:26:18 2022
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Sun, 2 Jan 2022 03:26:18 +0100
Subject: [PATCH mm v5 00/39] kasan, vmalloc, arm64: add vmalloc tagging
 support for SW/HW_TAGS
In-Reply-To: <20211230183054.a06a88b459b393957cb2d823@linux-foundation.org>
References: <cover.1640891329.git.andreyknvl@google.com>
 <CA+fCnZd+sBzecOGBD8zR3CxXS1yjV-X3-epAb6N=ZT8rJdCU6A@mail.gmail.com>
 <20211230183054.a06a88b459b393957cb2d823@linux-foundation.org>
Message-ID: <CA+fCnZfgBKMN967XfbtOpGJJmpw-5_M2M_hd4fSM7gSsqvd=bw@mail.gmail.com>

On Fri, Dec 31, 2021 at 3:30 AM Andrew Morton <akpm at linux-foundation.org> wrote:
>
> On Thu, 30 Dec 2021 20:19:01 +0100 Andrey Konovalov <andreyknvl at gmail.com> wrote:
>
> > Could you PTAL and consider taking this into mm?
>
> What's PTAL?

It stands for "Please take a look".

> We're at -rc7 so I'll process this after -rc1.

Sounds good, thank you!


From cyril at debamax.com  Sat Jan  1 20:33:22 2022
From: cyril at debamax.com (Cyril Brulebois)
Date: Sun, 2 Jan 2022 05:33:22 +0100
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <20211231115109.94626-1-uwe@kleine-koenig.org>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
Message-ID: <20220102043322.zv4r255yha5pvsp4@debamax.com>

Uwe Kleine-K?nig <uwe at kleine-koenig.org> (2021-12-31):
> The cm4-io board comes with an PCF85063. Add it to the device tree to make
> it usable. The i2c0 bus can use two different pinmux settings to use
> different pins. To keep the bus appearing on the usual pin pair (gpio0 +
> gpio1) use a pinctrl-muxed setting as the vendor dts does.
> 
> Note that if you modified the dts before to add devices to the i2c bus
> appearing on pins gpio0 + gpio1 (either directly in the dts or using an
> overlay), you have to put these into the i2c at 0 node introduced here now.
> 
> Reviewed-by: Maxime Ripard <maxime at cerno.tech>
> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>

Tested-by: Cyril Brulebois <cyril at debamax.com>


Test hardware:
 - 1 Compute Module 4 IO Board;
 - 1 GPIO Extension Board, plugged onto the 40-pin header (mainly used
   for its labels, to ensure I'm using the correct pins);
 - 1 Pimoroni 5x5 RGB LED matrix, plugged onto SDA0/SCL0 as exposed by
   the GPIO Extension Board (plus 3.3V/GND of course);
 - Debian 11 userspace.

With the updated DTB, and provided the right kernel modules have been
enabled (CONFIG_RTC_DRV_PCF85063, CONFIG_I2C_MUX_PINCTRL), the RTC comes
up automatically; I'm also able to use the relevant library to display a
rotating rainbow on the LED matrix while being able to read from / write
to the RTC:
  https://github.com/pimoroni/rgbmatrix5x5-python

In passing, I'm seeing the RTC exclusively on (userspace) i2c-2 while
I'm seeing the LED matrix on both (userspace) i2c-2 and i2c-3:

    # i2cdetect -y 2
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:                         -- -- -- -- 0c -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 2f 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- -- -- -- --                         
    
    # i2cdetect -y 3
         0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    00:                         -- -- -- -- -- -- -- -- 
    10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
    70: -- -- -- -- 74 -- -- --                         

Tweaking the library to use either of those makes the rotation rainbow
display successfully (via python3-smbus):

    self.i2c = smbus.SMBus(2)
    self.i2c = smbus.SMBus(3)


Cheers,
-- 
Cyril Brulebois -- Debian Consultant @ DEBAMAX -- https://debamax.com/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220102/0ebb5d44/attachment.sig>

From linus.walleij at linaro.org  Sat Jan  1 21:16:53 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 2 Jan 2022 06:16:53 +0100
Subject: [PATCH v7 3/4] dt-bindings: pinctrl: mt8195: add wrapping node of
 pin configurations
In-Reply-To: <20211220121825.6446-4-tinghan.shen@mediatek.com>
References: <20211220121825.6446-1-tinghan.shen@mediatek.com>
 <20211220121825.6446-4-tinghan.shen@mediatek.com>
Message-ID: <CACRpkdaGui4ULm7E7Y7YFLZ1BXKfvKKqv4KC=eTMBDExJThPdA@mail.gmail.com>

On Mon, Dec 20, 2021 at 1:18 PM Tinghan Shen <tinghan.shen at mediatek.com> wrote:

> On mt8195, the pinctrl node has pinctrl groups to group pin
> configurations by users' need. In each pinctrl group, it has
> subnode(s) to list pins needed and pin configurations. By supporting
> multiple subnodes, we can configure different pin characteristics
> (driving/pull-up/pull-down/etc.) in a pinctrl group.
>
> Update pinctrl-mt8195.yaml to add subnode in pinctrl groups and an
> example to illustrate the usage.
>
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>

This patch applied.

Yours,
Linus Walleij


From cyril at debamax.com  Sat Jan  1 22:34:18 2022
From: cyril at debamax.com (Cyril Brulebois)
Date: Sun, 2 Jan 2022 07:34:18 +0100
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <20220102043322.zv4r255yha5pvsp4@debamax.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <20220102043322.zv4r255yha5pvsp4@debamax.com>
Message-ID: <20220102063418.acneigxran2a6cpr@debamax.com>

Cyril Brulebois <cyril at debamax.com> (2022-01-02):
> In passing, I'm seeing the RTC exclusively on (userspace) i2c-2 while
> I'm seeing the LED matrix on both (userspace) i2c-2 and i2c-3: [?]

After a few more tests/reboots, checking the output of `i2cdetect -l`
gives the appropriate information, so that one can pick the right i2c-N
device, by looking at the *-mux entries and their channel IDs:

    ?
    i2c-2	i2c       	bcm2835 (i2c at 7e205000)          	I2C adapter
    ?
    i2c-4	i2c       	i2c-2-mux (chan_id 0)           	I2C adapter
    i2c-5	i2c       	i2c-2-mux (chan_id 1)           	I2C adapter

And indeed, those channel IDs match what's been defined in the DTB, with
#0 set to i2c0_gpio0 (e.g. LED matrix on 40-pin header) and #1 set to
i2c0_gpio44 (e.g. RTC, fan control, etc.), which seem quite consistent
this time:

 - `i2cdetect -y 4` reports only 74 (the LED matrix);
 - `i2cdetect -y 5` reports 0c, 2f, and 51 as UU (the RTC).


Cheers,
-- 
Cyril Brulebois -- Debian Consultant @ DEBAMAX -- https://debamax.com/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220102/8a039378/attachment.sig>

From linus.walleij at linaro.org  Sat Jan  1 22:34:21 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 2 Jan 2022 07:34:21 +0100
Subject: [PATCH] pinctrl: imx: fix assigning groups names
In-Reply-To: <20211227122237.6363-1-zajec5@gmail.com>
References: <20211227122237.6363-1-zajec5@gmail.com>
Message-ID: <CACRpkdbvZ+fZoGsVDY+kNEo4FFTUwJbfAq6ciC+mJN03Mm2jvQ@mail.gmail.com>

On Mon, Dec 27, 2021 at 1:23 PM Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> From: Rafa? Mi?ecki <rafal at milecki.pl>
>
> This fixes regression caused by incorrect array indexing.
>
> Reported-by: Fabio Estevam <festevam at gmail.com>
> Fixes: 02f117134952 ("pinctrl: imx: prepare for making "group_names" in "function_desc" const")
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>

Patch applied!

Yours,
Linus Walleij


From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:53 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:53 +0100
Subject: [PATCH 5/8] dt-bindings: clock: samsung: extend Exynos7 bindings with
 UFS
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-5-krzysztof.kozlowski@canonical.com>

The UFS for Exynos7 SoC clock controller requires additional input
clocks for the FSYS1 clock controller.  Update the bindings to reflect
this, at least in theory.  In practice, these input clocks are ignored,
so it is rather adjusting of bindings to existing DTS, without affecting
any real users.  I understand that is not how it should be done,
though...

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/clock/samsung,exynos7-clock.yaml   | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
index f3fa6c7ef48b..599baf0b7231 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
@@ -209,14 +209,17 @@ allOf:
     then:
       properties:
         clocks:
-          minItems: 4
-          maxItems: 4
+          minItems: 7
+          maxItems: 7
         clock-names:
           items:
             - const: fin_pll
             - const: dout_aclk_fsys1_200
             - const: dout_sclk_mmc0
             - const: dout_sclk_mmc1
+            - const: dout_sclk_ufsunipro20
+            - const: dout_sclk_phy_fsys1
+            - const: dout_sclk_phy_fsys1_26m
       required:
         - clock-names
         - clocks
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:50 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:50 +0100
Subject: [PATCH 2/8] ARM: dts: exynos: add necessary clock controller inputs
 in Exynos5260
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-2-krzysztof.kozlowski@canonical.com>

Exynos5260 bindings require to feed clock controllers with certain clock
inputs.  The IO clocks are expected to be provided by the board.  The
PHY clocks are usually followed by mux which can choose between the PHY
clock and main 24 MHz oscillator, so skip defining them and just use the
latter one.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5260-xyref5260.dts |  21 ++++
 arch/arm/boot/dts/exynos5260.dtsi          | 128 +++++++++++++++++++++
 2 files changed, 149 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts
index 0dc2ec16aa0a..c404fdb0fe19 100644
--- a/arch/arm/boot/dts/exynos5260-xyref5260.dts
+++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts
@@ -29,6 +29,27 @@ fin_pll: xxti {
 		#clock-cells = <0>;
 	};
 
+	ioclk_pcm: clock-pcm-ext {
+		compatible = "fixed-clock";
+		clock-frequency = <2048000>;
+		clock-output-names = "ioclk_pcm_extclk";
+		#clock-cells = <0>;
+	};
+
+	ioclk_i2s: clock-i2s-cd {
+		compatible = "fixed-clock";
+		clock-frequency = <147456000>;
+		clock-output-names = "ioclk_i2s_cdclk";
+		#clock-cells = <0>;
+	};
+
+	ioclk_spdif: clock-spdif-ext {
+		compatible = "fixed-clock";
+		clock-frequency = <49152000>;
+		clock-output-names = "ioclk_spdif_extclk";
+		#clock-cells = <0>;
+	};
+
 	xrtcxti: xrtcxti {
 		compatible = "fixed-clock";
 		clock-frequency = <32768>;
diff --git a/arch/arm/boot/dts/exynos5260.dtsi b/arch/arm/boot/dts/exynos5260.dtsi
index 524d244050e0..56271e7c4587 100644
--- a/arch/arm/boot/dts/exynos5260.dtsi
+++ b/arch/arm/boot/dts/exynos5260.dtsi
@@ -113,78 +113,206 @@ clock_top: clock-controller at 10010000 {
 			compatible = "samsung,exynos5260-clock-top";
 			reg = <0x10010000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_mif MIF_DOUT_MEM_PLL>,
+				 <&clock_mif MIF_DOUT_BUS_PLL>,
+				 <&clock_mif MIF_DOUT_MEDIA_PLL>;
+			clock-names = "fin_pll",
+				      "dout_mem_pll",
+				      "dout_bus_pll",
+				      "dout_media_pll";
 		};
 
 		clock_peri: clock-controller at 10200000 {
 			compatible = "samsung,exynos5260-clock-peri";
 			reg = <0x10200000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&ioclk_pcm>,
+				 <&ioclk_i2s>,
+				 <&ioclk_spdif>,
+				 <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_PERI_66>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_UART0>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_UART1>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_UART2>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_SPI0_B>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_SPI1_B>,
+				 <&clock_top TOP_DOUT_SCLK_PERI_SPI2_B>,
+				 <&clock_top TOP_DOUT_ACLK_PERI_AUD>;
+			clock-names = "fin_pll",
+				      "ioclk_pcm_extclk",
+				      "ioclk_i2s_cdclk",
+				      "ioclk_spdif_extclk",
+				      "phyclk_hdmi_phy_ref_cko",
+				      "dout_aclk_peri_66",
+				      "dout_sclk_peri_uart0",
+				      "dout_sclk_peri_uart1",
+				      "dout_sclk_peri_uart2",
+				      "dout_sclk_peri_spi0_b",
+				      "dout_sclk_peri_spi1_b",
+				      "dout_sclk_peri_spi2_b",
+				      "dout_aclk_peri_aud";
 		};
 
 		clock_egl: clock-controller at 10600000 {
 			compatible = "samsung,exynos5260-clock-egl";
 			reg = <0x10600000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_mif MIF_DOUT_BUS_PLL>;
+			clock-names = "fin_pll",
+				      "dout_bus_pll";
 		};
 
 		clock_kfc: clock-controller at 10700000 {
 			compatible = "samsung,exynos5260-clock-kfc";
 			reg = <0x10700000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_mif MIF_DOUT_MEDIA_PLL>;
+			clock-names = "fin_pll",
+				      "dout_media_pll";
 		};
 
 		clock_g2d: clock-controller at 10a00000 {
 			compatible = "samsung,exynos5260-clock-g2d";
 			reg = <0x10A00000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_G2D_333>;
+			clock-names = "fin_pll",
+				      "dout_aclk_g2d_333";
 		};
 
 		clock_mif: clock-controller at 10ce0000 {
 			compatible = "samsung,exynos5260-clock-mif";
 			reg = <0x10CE0000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
 		};
 
 		clock_mfc: clock-controller at 11090000 {
 			compatible = "samsung,exynos5260-clock-mfc";
 			reg = <0x11090000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_MFC_333>;
+			clock-names = "fin_pll",
+				      "dout_aclk_mfc_333";
 		};
 
 		clock_g3d: clock-controller at 11830000 {
 			compatible = "samsung,exynos5260-clock-g3d";
 			reg = <0x11830000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
 		};
 
 		clock_fsys: clock-controller at 122e0000 {
 			compatible = "samsung,exynos5260-clock-fsys";
 			reg = <0x122E0000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_FSYS_200>;
+			clock-names = "fin_pll",
+				      "phyclk_usbhost20_phy_phyclock",
+				      "phyclk_usbhost20_phy_freeclk",
+				      "phyclk_usbhost20_phy_clk48mohci",
+				      "phyclk_usbdrd30_udrd30_pipe_pclk",
+				      "phyclk_usbdrd30_udrd30_phyclock",
+				      "dout_aclk_fsys_200";
 		};
 
 		clock_aud: clock-controller at 128c0000 {
 			compatible = "samsung,exynos5260-clock-aud";
 			reg = <0x128C0000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_top TOP_FOUT_AUD_PLL>,
+				 <&ioclk_i2s>,
+				 <&ioclk_pcm>;
+			clock-names = "fin_pll",
+				      "fout_aud_pll",
+				      "ioclk_i2s_cdclk",
+				      "ioclk_pcm_extclk";
 		};
 
 		clock_isp: clock-controller at 133c0000 {
 			compatible = "samsung,exynos5260-clock-isp";
 			reg = <0x133C0000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_ISP1_266>,
+				 <&clock_top TOP_DOUT_ACLK_ISP1_400>,
+				 <&clock_top TOP_MOUT_ACLK_ISP1_266>;
+			clock-names = "fin_pll",
+				      "dout_aclk_isp1_266",
+				      "dout_aclk_isp1_400",
+				      "mout_aclk_isp1_266";
 		};
 
 		clock_gscl: clock-controller at 13f00000 {
 			compatible = "samsung,exynos5260-clock-gscl";
 			reg = <0x13F00000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&clock_top TOP_DOUT_ACLK_GSCL_400>,
+				 <&clock_top TOP_DOUT_ACLK_GSCL_333>;
+			clock-names = "fin_pll",
+				      "dout_aclk_gscl_400",
+				      "dout_aclk_gscl_333";
 		};
 
 		clock_disp: clock-controller at 14550000 {
 			compatible = "samsung,exynos5260-clock-disp";
 			reg = <0x14550000 0x10000>;
 			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&fin_pll>,
+				 <&ioclk_spdif>,
+				 <&clock_top TOP_DOUT_ACLK_PERI_AUD>,
+				 <&clock_top TOP_DOUT_ACLK_DISP_222>,
+				 <&clock_top TOP_DOUT_SCLK_DISP_PIXEL>,
+				 <&clock_top TOP_DOUT_ACLK_DISP_333>;
+			clock-names = "fin_pll",
+				      "phyclk_dptx_phy_ch3_txd_clk",
+				      "phyclk_dptx_phy_ch2_txd_clk",
+				      "phyclk_dptx_phy_ch1_txd_clk",
+				      "phyclk_dptx_phy_ch0_txd_clk",
+				      "phyclk_hdmi_phy_tmds_clko",
+				      "phyclk_hdmi_phy_ref_clko",
+				      "phyclk_hdmi_phy_pixel_clko",
+				      "phyclk_hdmi_link_o_tmds_clkhi",
+				      "phyclk_mipi_dphy_4l_m_txbyte_clkhs",
+				      "phyclk_dptx_phy_o_ref_clk_24m",
+				      "phyclk_dptx_phy_clk_div2",
+				      "phyclk_mipi_dphy_4l_m_rxclkesc0",
+				      "phyclk_hdmi_phy_ref_cko",
+				      "ioclk_spdif_extclk",
+				      "dout_aclk_peri_aud",
+				      "dout_aclk_disp_222",
+				      "dout_sclk_disp_pixel",
+				      "dout_aclk_disp_333";
 		};
 
 		gic: interrupt-controller at 10481000 {
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:49 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:49 +0100
Subject: [PATCH 1/8] arm64: dts: exynos: add necessary clock inputs in Exynos7
Message-ID: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>

Exynos7 devicetree bindings require more input clocks for TOP0 and
PERIC1 clock controllers, than already provided.  Existing DTS was not
matching the bindings, so let's update the DTS, even though the error
could be in the bindings.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos7.dtsi | 33 ++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index c3efbc8add38..3e53ff2be455 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -177,10 +177,11 @@ clock_top0: clock-controller at 105d0000 {
 			clocks = <&fin_pll>, <&clock_topc DOUT_SCLK_BUS0_PLL>,
 				 <&clock_topc DOUT_SCLK_BUS1_PLL>,
 				 <&clock_topc DOUT_SCLK_CC_PLL>,
-				 <&clock_topc DOUT_SCLK_MFC_PLL>;
+				 <&clock_topc DOUT_SCLK_MFC_PLL>,
+				 <&clock_topc DOUT_SCLK_AUD_PLL>;
 			clock-names = "fin_pll", "dout_sclk_bus0_pll",
 				      "dout_sclk_bus1_pll", "dout_sclk_cc_pll",
-				      "dout_sclk_mfc_pll";
+				      "dout_sclk_mfc_pll", "dout_sclk_aud_pll";
 		};
 
 		clock_top1: clock-controller at 105e0000 {
@@ -218,12 +219,32 @@ clock_peric1: clock-controller at 14c80000 {
 			compatible = "samsung,exynos7-clock-peric1";
 			reg = <0x14c80000 0xd00>;
 			#clock-cells = <1>;
-			clocks = <&fin_pll>, <&clock_top0 DOUT_ACLK_PERIC1>,
+			clocks = <&fin_pll>,
+				 <&clock_top0 DOUT_ACLK_PERIC1>,
 				 <&clock_top0 CLK_SCLK_UART1>,
 				 <&clock_top0 CLK_SCLK_UART2>,
-				 <&clock_top0 CLK_SCLK_UART3>;
-			clock-names = "fin_pll", "dout_aclk_peric1_66",
-				      "sclk_uart1", "sclk_uart2", "sclk_uart3";
+				 <&clock_top0 CLK_SCLK_UART3>,
+				 <&clock_top0 CLK_SCLK_SPI0>,
+				 <&clock_top0 CLK_SCLK_SPI1>,
+				 <&clock_top0 CLK_SCLK_SPI2>,
+				 <&clock_top0 CLK_SCLK_SPI3>,
+				 <&clock_top0 CLK_SCLK_SPI4>,
+				 <&clock_top0 CLK_SCLK_I2S1>,
+				 <&clock_top0 CLK_SCLK_PCM1>,
+				 <&clock_top0 CLK_SCLK_SPDIF>;
+			clock-names = "fin_pll",
+				      "dout_aclk_peric1_66",
+				      "sclk_uart1",
+				      "sclk_uart2",
+				      "sclk_uart3",
+				      "sclk_spi0",
+				      "sclk_spi1",
+				      "sclk_spi2",
+				      "sclk_spi3",
+				      "sclk_spi4",
+				      "sclk_i2s1",
+				      "sclk_pcm1",
+				      "sclk_spdif";
 		};
 
 		clock_peris: clock-controller at 10040000 {
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:55 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:55 +0100
Subject: [PATCH 7/8] dt-bindings: clock: samsung: convert Exynos5410 to
 dtschema
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-7-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5410 SoC clock controller bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5410-clock.txt       | 50 --------------
 .../clock/samsung,exynos5410-clock.yaml       | 66 +++++++++++++++++++
 MAINTAINERS                                   |  1 -
 3 files changed, 66 insertions(+), 51 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5410-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5410-clock.txt b/Documentation/devicetree/bindings/clock/exynos5410-clock.txt
deleted file mode 100644
index 217beb27c30e..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5410-clock.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-* Samsung Exynos5410 Clock Controller
-
-The Exynos5410 clock controller generates and supplies clock to various
-controllers within the Exynos5410 SoC.
-
-Required Properties:
-
-- compatible: should be "samsung,exynos5410-clock"
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-- clocks: should contain an entry specifying the root clock from external
-  oscillator supplied through XXTI or XusbXTI pin.  This clock should be
-  defined using standard clock bindings with "fin_pll" clock-output-name.
-  That clock is being passed internally to the 9 PLLs.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5410.h header and can be used in device
-tree sources.
-
-Example 1: An example of a clock controller node is listed below.
-
-	fin_pll: xxti {
-		compatible = "fixed-clock";
-		clock-frequency = <24000000>;
-		clock-output-names = "fin_pll";
-		#clock-cells = <0>;
-	};
-
-	clock: clock-controller at 10010000 {
-		compatible = "samsung,exynos5410-clock";
-		reg = <0x10010000 0x30000>;
-		#clock-cells = <1>;
-		clocks = <&fin_pll>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the clock
-	   controller. Refer to the standard clock bindings for information
-	   about 'clocks' and 'clock-names' property.
-
-	serial at 12c20000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C00000 0x100>;
-		interrupts = <0 51 0>;
-		clocks = <&clock CLK_UART0>, <&clock CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
new file mode 100644
index 000000000000..032862e9f55b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos5410-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5410 SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Expected external clocks, defined in DTS as fixed-rate clocks with a matching
+  name::
+    - "fin_pll" - PLL input clock from XXTI
+
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos5410.h header.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,exynos5410-clock
+
+  clocks:
+    description:
+      Should contain an entry specifying the root clock from external
+      oscillator supplied through XXTI or XusbXTI pin.  This clock should be
+      defined using standard clock bindings with "fin_pll" clock-output-name.
+      That clock is being passed internally to the 9 PLLs.
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5410.h>
+
+    fin_pll: osc-clock {
+        compatible = "fixed-clock";
+        clock-frequency = <24000000>;
+        clock-output-names = "fin_pll";
+        #clock-cells = <0>;
+    };
+
+    clock-controller at 10010000 {
+        compatible = "samsung,exynos5410-clock";
+        reg = <0x10010000 0x30000>;
+        #clock-cells = <1>;
+        clocks = <&fin_pll>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..0aa6a2728a7c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17036,7 +17036,6 @@ M:	Chanwoo Choi <cw00.choi at samsung.com>
 L:	linux-samsung-soc at vger.kernel.org
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
-F:	Documentation/devicetree/bindings/clock/exynos*.txt
 F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:	Documentation/devicetree/bindings/clock/samsung,s3c*
 F:	Documentation/devicetree/bindings/clock/samsung,s5p*
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:52 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:52 +0100
Subject: [PATCH 4/8] dt-bindings: clock: samsung: convert Exynos7 to dtschema
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-4-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos7 SoC clock controller bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos7-clock.txt          | 108 -------
 .../bindings/clock/samsung,exynos7-clock.yaml | 269 ++++++++++++++++++
 2 files changed, 269 insertions(+), 108 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos7-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos7-clock.txt b/Documentation/devicetree/bindings/clock/exynos7-clock.txt
deleted file mode 100644
index 6bf1e7493f61..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos7-clock.txt
+++ /dev/null
@@ -1,108 +0,0 @@
-* Samsung Exynos7 Clock Controller
-
-Exynos7 clock controller has various blocks which are instantiated
-independently from the device-tree. These clock controllers
-generate and supply clocks to various hardware blocks within
-the SoC.
-
-Each clock is assigned an identifier and client nodes can use
-this identifier to specify the clock which they consume. All
-available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos7-clk.h header and can be used in
-device tree sources.
-
-External clocks:
-
-There are several clocks that are generated outside the SoC. It
-is expected that they are defined using standard clock bindings
-with following clock-output-names:
-
- - "fin_pll" - PLL input clock from XXTI
-
-Required Properties for Clock Controller:
-
- - compatible: clock controllers will use one of the following
-	compatible strings to indicate the clock controller
-	functionality.
-
-	- "samsung,exynos7-clock-topc"
-	- "samsung,exynos7-clock-top0"
-	- "samsung,exynos7-clock-top1"
-	- "samsung,exynos7-clock-ccore"
-	- "samsung,exynos7-clock-peric0"
-	- "samsung,exynos7-clock-peric1"
-	- "samsung,exynos7-clock-peris"
-	- "samsung,exynos7-clock-fsys0"
-	- "samsung,exynos7-clock-fsys1"
-	- "samsung,exynos7-clock-mscl"
-	- "samsung,exynos7-clock-aud"
-
- - reg: physical base address of the controller and the length of
-	memory mapped region.
-
- - #clock-cells: should be 1.
-
- - clocks: list of clock identifiers which are fed as the input to
-	the given clock controller. Please refer the next section to
-	find the input clocks for a given controller.
-
-- clock-names: list of names of clocks which are fed as the input
-	to the given clock controller.
-
-Input clocks for top0 clock controller:
-	- fin_pll
-	- dout_sclk_bus0_pll
-	- dout_sclk_bus1_pll
-	- dout_sclk_cc_pll
-	- dout_sclk_mfc_pll
-	- dout_sclk_aud_pll
-
-Input clocks for top1 clock controller:
-	- fin_pll
-	- dout_sclk_bus0_pll
-	- dout_sclk_bus1_pll
-	- dout_sclk_cc_pll
-	- dout_sclk_mfc_pll
-
-Input clocks for ccore clock controller:
-	- fin_pll
-	- dout_aclk_ccore_133
-
-Input clocks for peric0 clock controller:
-	- fin_pll
-	- dout_aclk_peric0_66
-	- sclk_uart0
-
-Input clocks for peric1 clock controller:
-	- fin_pll
-	- dout_aclk_peric1_66
-	- sclk_uart1
-	- sclk_uart2
-	- sclk_uart3
-	- sclk_spi0
-	- sclk_spi1
-	- sclk_spi2
-	- sclk_spi3
-	- sclk_spi4
-	- sclk_i2s1
-	- sclk_pcm1
-	- sclk_spdif
-
-Input clocks for peris clock controller:
-	- fin_pll
-	- dout_aclk_peris_66
-
-Input clocks for fsys0 clock controller:
-	- fin_pll
-	- dout_aclk_fsys0_200
-	- dout_sclk_mmc2
-
-Input clocks for fsys1 clock controller:
-	- fin_pll
-	- dout_aclk_fsys1_200
-	- dout_sclk_mmc0
-	- dout_sclk_mmc1
-
-Input clocks for aud clock controller:
-	- fin_pll
-	- fout_aud_pll
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
new file mode 100644
index 000000000000..f3fa6c7ef48b
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
@@ -0,0 +1,269 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos7-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos7 SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Expected external clocks, defined in DTS as fixed-rate clocks with a matching
+  name::
+    - "fin_pll" - PLL input clock from XXTI
+
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos7-clk.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos7-clock-topc
+      - samsung,exynos7-clock-top0
+      - samsung,exynos7-clock-top1
+      - samsung,exynos7-clock-ccore
+      - samsung,exynos7-clock-peric0
+      - samsung,exynos7-clock-peric1
+      - samsung,exynos7-clock-peris
+      - samsung,exynos7-clock-fsys0
+      - samsung,exynos7-clock-fsys1
+      - samsung,exynos7-clock-mscl
+      - samsung,exynos7-clock-aud
+
+  clocks:
+    minItems: 1
+    maxItems: 13
+
+  clock-names:
+    minItems: 1
+    maxItems: 13
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-top0
+    then:
+      properties:
+        clocks:
+          minItems: 6
+          maxItems: 6
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_sclk_bus0_pll
+            - const: dout_sclk_bus1_pll
+            - const: dout_sclk_cc_pll
+            - const: dout_sclk_mfc_pll
+            - const: dout_sclk_aud_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-top1
+    then:
+      properties:
+        clocks:
+          minItems: 5
+          maxItems: 5
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_sclk_bus0_pll
+            - const: dout_sclk_bus1_pll
+            - const: dout_sclk_cc_pll
+            - const: dout_sclk_mfc_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-ccore
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_ccore_133
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-peric0
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_peric0_66
+            - const: sclk_uart0
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-peric1
+    then:
+      properties:
+        clocks:
+          minItems: 13
+          maxItems: 13
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_peric1_66
+            - const: sclk_uart1
+            - const: sclk_uart2
+            - const: sclk_uart3
+            - const: sclk_spi0
+            - const: sclk_spi1
+            - const: sclk_spi2
+            - const: sclk_spi3
+            - const: sclk_spi4
+            - const: sclk_i2s1
+            - const: sclk_pcm1
+            - const: sclk_spdif
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-peris
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_peris_66
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-fsys0
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_fsys0_200
+            - const: dout_sclk_mmc2
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-fsys1
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_fsys1_200
+            - const: dout_sclk_mmc0
+            - const: dout_sclk_mmc1
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-clock-aud
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: fout_aud_pll
+      required:
+        - clock-names
+        - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos7-clk.h>
+
+    fin_pll: clock {
+        compatible = "fixed-clock";
+        clock-output-names = "fin_pll";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+    };
+
+    clock-controller at 105e0000 {
+        compatible = "samsung,exynos7-clock-top1";
+        reg = <0x105e0000 0xb000>;
+        #clock-cells = <1>;
+        clocks = <&fin_pll>,
+                 <&clock_topc DOUT_SCLK_BUS0_PLL>,
+                 <&clock_topc DOUT_SCLK_BUS1_PLL>,
+                 <&clock_topc DOUT_SCLK_CC_PLL>,
+                 <&clock_topc DOUT_SCLK_MFC_PLL>;
+        clock-names = "fin_pll",
+                      "dout_sclk_bus0_pll",
+                      "dout_sclk_bus1_pll",
+                      "dout_sclk_cc_pll",
+                      "dout_sclk_mfc_pll";
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:54 +0100
Subject: [PATCH 6/8] dt-bindings: clock: samsung: convert Exynos5260 to
 dtschema
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-6-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5260 SoC clock controller bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5260-clock.txt       | 190 ---------
 .../clock/samsung,exynos5260-clock.yaml       | 382 ++++++++++++++++++
 2 files changed, 382 insertions(+), 190 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5260-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5260-clock.txt b/Documentation/devicetree/bindings/clock/exynos5260-clock.txt
deleted file mode 100644
index c79d31f7f66e..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5260-clock.txt
+++ /dev/null
@@ -1,190 +0,0 @@
-* Samsung Exynos5260 Clock Controller
-
-Exynos5260 has 13 clock controllers which are instantiated
-independently from the device-tree. These clock controllers
-generate and supply clocks to various hardware blocks within
-the SoC.
-
-Each clock is assigned an identifier and client nodes can use
-this identifier to specify the clock which they consume. All
-available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5260-clk.h header and can be used in
-device tree sources.
-
-External clocks:
-
-There are several clocks that are generated outside the SoC. It
-is expected that they are defined using standard clock bindings
-with following clock-output-names:
-
- - "fin_pll" - PLL input clock from XXTI
- - "xrtcxti" - input clock from XRTCXTI
- - "ioclk_pcm_extclk" - pcm external operation clock
- - "ioclk_spdif_extclk" - spdif external operation clock
- - "ioclk_i2s_cdclk" - i2s0 codec clock
-
-Phy clocks:
-
-There are several clocks which are generated by specific PHYs.
-These clocks are fed into the clock controller and then routed to
-the hardware blocks. These clocks are defined as fixed clocks in the
-driver with following names:
-
- - "phyclk_dptx_phy_ch3_txd_clk" - dp phy clock for channel 3
- - "phyclk_dptx_phy_ch2_txd_clk" - dp phy clock for channel 2
- - "phyclk_dptx_phy_ch1_txd_clk" - dp phy clock for channel 1
- - "phyclk_dptx_phy_ch0_txd_clk" - dp phy clock for channel 0
- - "phyclk_hdmi_phy_tmds_clko" - hdmi phy tmds clock
- - "phyclk_hdmi_phy_pixel_clko" - hdmi phy pixel clock
- - "phyclk_hdmi_link_o_tmds_clkhi" - hdmi phy for hdmi link
- - "phyclk_dptx_phy_o_ref_clk_24m" - dp phy reference clock
- - "phyclk_dptx_phy_clk_div2"
- - "phyclk_mipi_dphy_4l_m_rxclkesc0"
- - "phyclk_usbhost20_phy_phyclock" - usb 2.0 phy clock
- - "phyclk_usbhost20_phy_freeclk"
- - "phyclk_usbhost20_phy_clk48mohci"
- - "phyclk_usbdrd30_udrd30_pipe_pclk"
- - "phyclk_usbdrd30_udrd30_phyclock" - usb 3.0 phy clock
-
-Required Properties for Clock Controller:
-
- - compatible: should be one of the following.
-	1) "samsung,exynos5260-clock-top"
-	2) "samsung,exynos5260-clock-peri"
-	3) "samsung,exynos5260-clock-egl"
-	4) "samsung,exynos5260-clock-kfc"
-	5) "samsung,exynos5260-clock-g2d"
-	6) "samsung,exynos5260-clock-mif"
-	7) "samsung,exynos5260-clock-mfc"
-	8) "samsung,exynos5260-clock-g3d"
-	9) "samsung,exynos5260-clock-fsys"
-	10) "samsung,exynos5260-clock-aud"
-	11) "samsung,exynos5260-clock-isp"
-	12) "samsung,exynos5260-clock-gscl"
-	13) "samsung,exynos5260-clock-disp"
-
- - reg: physical base address of the controller and the length of
-	memory mapped region.
-
- - #clock-cells: should be 1.
-
- - clocks: list of clock identifiers which are fed as the input to
-	the given clock controller. Please refer the next section to find
-	the input clocks for a given controller.
-
- - clock-names: list of names of clocks which are fed as the input
-	to the given clock controller.
-
-Input clocks for top clock controller:
-	- fin_pll
-	- dout_mem_pll
-	- dout_bus_pll
-	- dout_media_pll
-
-Input clocks for peri clock controller:
-	- fin_pll
-	- ioclk_pcm_extclk
-	- ioclk_i2s_cdclk
-	- ioclk_spdif_extclk
-	- phyclk_hdmi_phy_ref_cko
-	- dout_aclk_peri_66
-	- dout_sclk_peri_uart0
-	- dout_sclk_peri_uart1
-	- dout_sclk_peri_uart2
-	- dout_sclk_peri_spi0_b
-	- dout_sclk_peri_spi1_b
-	- dout_sclk_peri_spi2_b
-	- dout_aclk_peri_aud
-	- dout_sclk_peri_spi0_b
-
-Input clocks for egl clock controller:
-	- fin_pll
-	- dout_bus_pll
-
-Input clocks for kfc clock controller:
-	- fin_pll
-	- dout_media_pll
-
-Input clocks for g2d clock controller:
-	- fin_pll
-	- dout_aclk_g2d_333
-
-Input clocks for mif clock controller:
-	- fin_pll
-
-Input clocks for mfc clock controller:
-	- fin_pll
-	- dout_aclk_mfc_333
-
-Input clocks for g3d clock controller:
-	- fin_pll
-
-Input clocks for fsys clock controller:
-	- fin_pll
-	- phyclk_usbhost20_phy_phyclock
-	- phyclk_usbhost20_phy_freeclk
-	- phyclk_usbhost20_phy_clk48mohci
-	- phyclk_usbdrd30_udrd30_pipe_pclk
-	- phyclk_usbdrd30_udrd30_phyclock
-	- dout_aclk_fsys_200
-
-Input clocks for aud clock controller:
-	- fin_pll
-	- fout_aud_pll
-	- ioclk_i2s_cdclk
-	- ioclk_pcm_extclk
-
-Input clocks for isp clock controller:
-	- fin_pll
-	- dout_aclk_isp1_266
-	- dout_aclk_isp1_400
-	- mout_aclk_isp1_266
-
-Input clocks for gscl clock controller:
-	- fin_pll
-	- dout_aclk_gscl_400
-	- dout_aclk_gscl_333
-
-Input clocks for disp clock controller:
-	- fin_pll
-	- phyclk_dptx_phy_ch3_txd_clk
-	- phyclk_dptx_phy_ch2_txd_clk
-	- phyclk_dptx_phy_ch1_txd_clk
-	- phyclk_dptx_phy_ch0_txd_clk
-	- phyclk_hdmi_phy_tmds_clko
-	- phyclk_hdmi_phy_ref_clko
-	- phyclk_hdmi_phy_pixel_clko
-	- phyclk_hdmi_link_o_tmds_clkhi
-	- phyclk_mipi_dphy_4l_m_txbyte_clkhs
-	- phyclk_dptx_phy_o_ref_clk_24m
-	- phyclk_dptx_phy_clk_div2
-	- phyclk_mipi_dphy_4l_m_rxclkesc0
-	- phyclk_hdmi_phy_ref_cko
-	- ioclk_spdif_extclk
-	- dout_aclk_peri_aud
-	- dout_aclk_disp_222
-	- dout_sclk_disp_pixel
-	- dout_aclk_disp_333
-
-Example 1: An example of a clock controller node is listed below.
-
-	clock_mfc: clock-controller at 11090000 {
-		compatible = "samsung,exynos5260-clock-mfc";
-		clock = <&fin_pll>, <&clock_top TOP_DOUT_ACLK_MFC_333>;
-		clock-names = "fin_pll", "dout_aclk_mfc_333";
-		reg = <0x11090000 0x10000>;
-		#clock-cells = <1>;
-	};
-
-Example 2: UART controller node that consumes the clock generated by the
-		peri clock controller. Refer to the standard clock bindings for
-		information about 'clocks' and 'clock-names' property.
-
-	serial at 12c00000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x12C00000 0x100>;
-		interrupts = <0 146 0>;
-		clocks = <&clock_peri PERI_PCLK_UART0>, <&clock_peri PERI_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-	};
-
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
new file mode 100644
index 000000000000..a3fac5c6809d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
@@ -0,0 +1,382 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos5260-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5260 SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Expected external clocks, defined in DTS as fixed-rate clocks with a matching
+  name::
+    - "fin_pll" - PLL input clock from XXTI
+    - "xrtcxti" - input clock from XRTCXTI
+    - "ioclk_pcm_extclk" - pcm external operation clock
+    - "ioclk_spdif_extclk" - spdif external operation clock
+    - "ioclk_i2s_cdclk" - i2s0 codec clock
+
+  Phy clocks::
+  There are several clocks which are generated by specific PHYs.  These clocks
+  are fed into the clock controller and then routed to the hardware blocks.
+  These clocks are defined as fixed clocks in the driver with following names::
+    - "phyclk_dptx_phy_ch3_txd_clk" - dp phy clock for channel 3
+    - "phyclk_dptx_phy_ch2_txd_clk" - dp phy clock for channel 2
+    - "phyclk_dptx_phy_ch1_txd_clk" - dp phy clock for channel 1
+    - "phyclk_dptx_phy_ch0_txd_clk" - dp phy clock for channel 0
+    - "phyclk_hdmi_phy_tmds_clko" - hdmi phy tmds clock
+    - "phyclk_hdmi_phy_pixel_clko" - hdmi phy pixel clock
+    - "phyclk_hdmi_link_o_tmds_clkhi" - hdmi phy for hdmi link
+    - "phyclk_dptx_phy_o_ref_clk_24m" - dp phy reference clock
+    - "phyclk_dptx_phy_clk_div2"
+    - "phyclk_mipi_dphy_4l_m_rxclkesc0"
+    - "phyclk_usbhost20_phy_phyclock" - usb 2.0 phy clock
+    - "phyclk_usbhost20_phy_freeclk"
+    - "phyclk_usbhost20_phy_clk48mohci"
+    - "phyclk_usbdrd30_udrd30_pipe_pclk"
+    - "phyclk_usbdrd30_udrd30_phyclock" - usb 3.0 phy clock
+
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos5260-clk.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5260-clock-top
+      - samsung,exynos5260-clock-peri
+      - samsung,exynos5260-clock-egl
+      - samsung,exynos5260-clock-kfc
+      - samsung,exynos5260-clock-g2d
+      - samsung,exynos5260-clock-mif
+      - samsung,exynos5260-clock-mfc
+      - samsung,exynos5260-clock-g3d
+      - samsung,exynos5260-clock-fsys
+      - samsung,exynos5260-clock-aud
+      - samsung,exynos5260-clock-isp
+      - samsung,exynos5260-clock-gscl
+      - samsung,exynos5260-clock-disp
+
+  clocks:
+    minItems: 1
+    maxItems: 19
+
+  clock-names:
+    minItems: 1
+    maxItems: 19
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-top
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_mem_pll
+            - const: dout_bus_pll
+            - const: dout_media_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-peri
+    then:
+      properties:
+        clocks:
+          minItems: 13
+          maxItems: 13
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: ioclk_pcm_extclk
+            - const: ioclk_i2s_cdclk
+            - const: ioclk_spdif_extclk
+            - const: phyclk_hdmi_phy_ref_cko
+            - const: dout_aclk_peri_66
+            - const: dout_sclk_peri_uart0
+            - const: dout_sclk_peri_uart1
+            - const: dout_sclk_peri_uart2
+            - const: dout_sclk_peri_spi0_b
+            - const: dout_sclk_peri_spi1_b
+            - const: dout_sclk_peri_spi2_b
+            - const: dout_aclk_peri_aud
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-egl
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_bus_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-kfc
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_media_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-g2d
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_g2d_333
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-mif
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: fin_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-mfc
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_mfc_333
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-g3d
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: fin_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-fsys
+    then:
+      properties:
+        clocks:
+          minItems: 7
+          maxItems: 7
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: phyclk_usbhost20_phy_phyclock
+            - const: phyclk_usbhost20_phy_freeclk
+            - const: phyclk_usbhost20_phy_clk48mohci
+            - const: phyclk_usbdrd30_udrd30_pipe_pclk
+            - const: phyclk_usbdrd30_udrd30_phyclock
+            - const: dout_aclk_fsys_200
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-aud
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: fout_aud_pll
+            - const: ioclk_i2s_cdclk
+            - const: ioclk_pcm_extclk
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-isp
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_isp1_266
+            - const: dout_aclk_isp1_400
+            - const: mout_aclk_isp1_266
+
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-gscl
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_aclk_gscl_400
+            - const: dout_aclk_gscl_333
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5260-clock-disp
+    then:
+      properties:
+        clocks:
+          minItems: 19
+          maxItems: 19
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: phyclk_dptx_phy_ch3_txd_clk
+            - const: phyclk_dptx_phy_ch2_txd_clk
+            - const: phyclk_dptx_phy_ch1_txd_clk
+            - const: phyclk_dptx_phy_ch0_txd_clk
+            - const: phyclk_hdmi_phy_tmds_clko
+            - const: phyclk_hdmi_phy_ref_clko
+            - const: phyclk_hdmi_phy_pixel_clko
+            - const: phyclk_hdmi_link_o_tmds_clkhi
+            - const: phyclk_mipi_dphy_4l_m_txbyte_clkhs
+            - const: phyclk_dptx_phy_o_ref_clk_24m
+            - const: phyclk_dptx_phy_clk_div2
+            - const: phyclk_mipi_dphy_4l_m_rxclkesc0
+            - const: phyclk_hdmi_phy_ref_cko
+            - const: ioclk_spdif_extclk
+            - const: dout_aclk_peri_aud
+            - const: dout_aclk_disp_222
+            - const: dout_sclk_disp_pixel
+            - const: dout_aclk_disp_333
+      required:
+        - clock-names
+        - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5260-clk.h>
+
+    fin_pll: clock {
+        compatible = "fixed-clock";
+        clock-output-names = "fin_pll";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+    };
+
+    clock-controller at 10010000 {
+        compatible = "samsung,exynos5260-clock-top";
+        reg = <0x10010000 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&fin_pll>,
+                 <&clock_mif MIF_DOUT_MEM_PLL>,
+                 <&clock_mif MIF_DOUT_BUS_PLL>,
+                 <&clock_mif MIF_DOUT_MEDIA_PLL>;
+        clock-names = "fin_pll",
+                      "dout_mem_pll",
+                      "dout_bus_pll",
+                      "dout_media_pll";
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:56 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:56 +0100
Subject: [PATCH 8/8] dt-bindings: clock: samsung: convert S5Pv210 to dtschema
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-8-krzysztof.kozlowski@canonical.com>

Convert Samsung S5Pv210 SoC clock controller bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/samsung,s5pv210-clock.txt  | 77 ------------------
 .../bindings/clock/samsung,s5pv210-clock.yaml | 79 +++++++++++++++++++
 MAINTAINERS                                   |  1 -
 3 files changed, 79 insertions(+), 78 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt
deleted file mode 100644
index a86c83bf9d4e..000000000000
--- a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt
+++ /dev/null
@@ -1,77 +0,0 @@
-* Samsung S5P6442/S5PC110/S5PV210 Clock Controller
-
-Samsung S5P6442, S5PC110 and S5PV210 SoCs contain integrated clock
-controller, which generates and supplies clock to various controllers
-within the SoC.
-
-Required Properties:
-
-- compatible: should be one of following:
-	- "samsung,s5pv210-clock" : for clock controller of Samsung
-	  S5PC110/S5PV210 SoCs,
-	- "samsung,s5p6442-clock" : for clock controller of Samsung
-	  S5P6442 SoC.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/s5pv210.h header and can be used in device tree sources.
-
-External clocks:
-
-There are several clocks that are generated outside the SoC. It is expected
-that they are defined using standard clock bindings with following
-clock-output-names:
- - "xxti": external crystal oscillator connected to XXTI and XXTO pins of
-the SoC,
- - "xusbxti": external crystal oscillator connected to XUSBXTI and XUSBXTO
-pins of the SoC,
-
-A subset of above clocks available on given board shall be specified in
-board device tree, including the system base clock, as selected by XOM[0]
-pin of the SoC. Refer to generic fixed rate clock bindings
-documentation[1] for more information how to specify these clocks.
-
-[1] Documentation/devicetree/bindings/clock/fixed-clock.yaml
-
-Example: Clock controller node:
-
-	clock: clock-controller at 7e00f000 {
-		compatible = "samsung,s5pv210-clock";
-		reg = <0x7e00f000 0x1000>;
-		#clock-cells = <1>;
-	};
-
-Example: Required external clocks:
-
-	xxti: clock-xxti {
-		compatible = "fixed-clock";
-		clock-output-names = "xxti";
-		clock-frequency = <24000000>;
-		#clock-cells = <0>;
-	};
-
-	xusbxti: clock-xusbxti {
-		compatible = "fixed-clock";
-		clock-output-names = "xusbxti";
-		clock-frequency = <24000000>;
-		#clock-cells = <0>;
-	};
-
-Example: UART controller node that consumes the clock generated by the clock
-  controller (refer to the standard clock bindings for information about
-  "clocks" and "clock-names" properties):
-
-	uart0: serial at e2900000 {
-		compatible = "samsung,s5pv210-uart";
-		reg = <0xe2900000 0x400>;
-		interrupt-parent = <&vic1>;
-		interrupts = <10>;
-		clock-names = "uart", "clk_uart_baud0",
-				"clk_uart_baud1";
-		clocks = <&clocks UART0>, <&clocks UART0>,
-				<&clocks SCLK_UART0>;
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
new file mode 100644
index 000000000000..dcb29a2d1159
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,s5pv210-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5P6442/S5PC110/S5PV210 SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Expected external clocks, defined in DTS as fixed-rate clocks with a matching
+  name::
+    - "xxti" - external crystal oscillator connected to XXTI and XXTO pins of
+      the SoC,
+    - "xusbxti" - external crystal oscillator connected to XUSBXTI and XUSBXTO
+      pins of the SoC,
+
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/s5pv210.h header.
+
+properties:
+  compatible:
+    enum:
+      - samsung,s5pv210-clock
+      - samsung,s5p6442-clock
+
+  clocks:
+    items:
+      - description: xxti clock
+      - description: xusbxti clock
+
+  clock-names:
+    items:
+      - const: xxti
+      - const: xusbxti
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/s5pv210.h>
+
+    xxti: clock-0 {
+        compatible = "fixed-clock";
+        clock-frequency = <0>;
+        clock-output-names = "xxti";
+        #clock-cells = <0>;
+    };
+
+    xusbxti: clock-1 {
+        compatible = "fixed-clock";
+        clock-frequency = <0>;
+        clock-output-names = "xusbxti";
+        #clock-cells = <0>;
+    };
+
+    clock-controller at e0100000 {
+        compatible = "samsung,s5pv210-clock";
+        reg = <0xe0100000 0x10000>;
+        clock-names = "xxti", "xusbxti";
+        clocks = <&xxti>, <&xusbxti>;
+        #clock-cells = <1>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 0aa6a2728a7c..d7db7054455d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17038,7 +17038,6 @@ S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:	Documentation/devicetree/bindings/clock/samsung,*.yaml
 F:	Documentation/devicetree/bindings/clock/samsung,s3c*
-F:	Documentation/devicetree/bindings/clock/samsung,s5p*
 F:	drivers/clk/samsung/
 F:	include/dt-bindings/clock/exynos*.h
 F:	include/dt-bindings/clock/s3c*.h
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 03:53:51 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 12:53:51 +0100
Subject: [PATCH 3/8] dt-bindings: clock: samsung: convert Exynos5433 to
 dtschema
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102115356.75796-3-krzysztof.kozlowski@canonical.com>

Convert Samsung Exynos5433 SoC clock controller bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/clock/exynos5433-clock.txt       | 507 -----------------
 .../clock/samsung,exynos5433-clock.yaml       | 524 ++++++++++++++++++
 2 files changed, 524 insertions(+), 507 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/clock/exynos5433-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt b/Documentation/devicetree/bindings/clock/exynos5433-clock.txt
deleted file mode 100644
index 183c327a7d6b..000000000000
--- a/Documentation/devicetree/bindings/clock/exynos5433-clock.txt
+++ /dev/null
@@ -1,507 +0,0 @@
-* Samsung Exynos5433 CMU (Clock Management Units)
-
-The Exynos5433 clock controller generates and supplies clock to various
-controllers within the Exynos5433 SoC.
-
-Required Properties:
-
-- compatible: should be one of the following.
-  - "samsung,exynos5433-cmu-top"   - clock controller compatible for CMU_TOP
-    which generates clocks for IMEM/FSYS/G3D/GSCL/HEVC/MSCL/G2D/MFC/PERIC/PERIS
-    domains and bus clocks.
-  - "samsung,exynos5433-cmu-cpif"  - clock controller compatible for CMU_CPIF
-    which generates clocks for LLI (Low Latency Interface) IP.
-  - "samsung,exynos5433-cmu-mif"   - clock controller compatible for CMU_MIF
-    which generates clocks for DRAM Memory Controller domain.
-  - "samsung,exynos5433-cmu-peric" - clock controller compatible for CMU_PERIC
-    which generates clocks for UART/I2C/SPI/I2S/PCM/SPDIF/PWM/SLIMBUS IPs.
-  - "samsung,exynos5433-cmu-peris" - clock controller compatible for CMU_PERIS
-    which generates clocks for PMU/TMU/MCT/WDT/RTC/SECKEY/TZPC IPs.
-  - "samsung,exynos5433-cmu-fsys"  - clock controller compatible for CMU_FSYS
-    which generates clocks for USB/UFS/SDMMC/TSI/PDMA IPs.
-  - "samsung,exynos5433-cmu-g2d"   - clock controller compatible for CMU_G2D
-    which generates clocks for G2D/MDMA IPs.
-  - "samsung,exynos5433-cmu-disp"  - clock controller compatible for CMU_DISP
-    which generates clocks for Display (DECON/HDMI/DSIM/MIXER) IPs.
-  - "samsung,exynos5433-cmu-aud"   - clock controller compatible for CMU_AUD
-    which generates clocks for Cortex-A5/BUS/AUDIO clocks.
-  - "samsung,exynos5433-cmu-bus0", "samsung,exynos5433-cmu-bus1"
-    and "samsung,exynos5433-cmu-bus2" - clock controller compatible for CMU_BUS
-    which generates global data buses clock and global peripheral buses clock.
-  - "samsung,exynos5433-cmu-g3d"  - clock controller compatible for CMU_G3D
-    which generates clocks for 3D Graphics Engine IP.
-  - "samsung,exynos5433-cmu-gscl"  - clock controller compatible for CMU_GSCL
-    which generates clocks for GSCALER IPs.
-  - "samsung,exynos5433-cmu-apollo"- clock controller compatible for CMU_APOLLO
-    which generates clocks for Cortex-A53 Quad-core processor.
-  - "samsung,exynos5433-cmu-atlas" - clock controller compatible for CMU_ATLAS
-    which generates clocks for Cortex-A57 Quad-core processor, CoreSight and
-    L2 cache controller.
-  - "samsung,exynos5433-cmu-mscl" - clock controller compatible for CMU_MSCL
-    which generates clocks for M2M (Memory to Memory) scaler and JPEG IPs.
-  - "samsung,exynos5433-cmu-mfc"  - clock controller compatible for CMU_MFC
-    which generates clocks for MFC(Multi-Format Codec) IP.
-  - "samsung,exynos5433-cmu-hevc" - clock controller compatible for CMU_HEVC
-    which generates clocks for HEVC(High Efficiency Video Codec) decoder IP.
-  - "samsung,exynos5433-cmu-isp" - clock controller compatible for CMU_ISP
-    which generates clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs.
-  - "samsung,exynos5433-cmu-cam0" - clock controller compatible for CMU_CAM0
-    which generates clocks for MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1}
-    IPs.
-  - "samsung,exynos5433-cmu-cam1" - clock controller compatible for CMU_CAM1
-    which generates clocks for Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs.
-  - "samsung,exynos5433-cmu-imem"   - clock controller compatible for CMU_IMEM
-    which generates clocks for SSS (Security SubSystem) and SlimSSS IPs.
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- #clock-cells: should be 1.
-
-- clocks: list of the clock controller input clock identifiers,
-	from common clock bindings. Please refer the next section
-	to find the input clocks for a given controller.
-
-- clock-names: list of the clock controller input clock names,
-	as described in clock-bindings.txt.
-
-	Input clocks for top clock controller:
-		- oscclk
-		- sclk_mphy_pll
-		- sclk_mfc_pll
-		- sclk_bus_pll
-
-	Input clocks for cpif clock controller:
-		- oscclk
-
-	Input clocks for mif clock controller:
-		- oscclk
-		- sclk_mphy_pll
-
-	Input clocks for fsys clock controller:
-		- oscclk
-		- sclk_ufs_mphy
-		- aclk_fsys_200
-		- sclk_pcie_100_fsys
-		- sclk_ufsunipro_fsys
-		- sclk_mmc2_fsys
-		- sclk_mmc1_fsys
-		- sclk_mmc0_fsys
-		- sclk_usbhost30_fsys
-		- sclk_usbdrd30_fsys
-
-	Input clocks for g2d clock controller:
-		- oscclk
-		- aclk_g2d_266
-		- aclk_g2d_400
-
-	Input clocks for disp clock controller:
-		- oscclk
-		- sclk_dsim1_disp
-		- sclk_dsim0_disp
-		- sclk_dsd_disp
-		- sclk_decon_tv_eclk_disp
-		- sclk_decon_vclk_disp
-		- sclk_decon_eclk_disp
-		- sclk_decon_tv_vclk_disp
-		- aclk_disp_333
-
-	Input clocks for audio clock controller:
-		- oscclk
-		- fout_aud_pll
-
-	Input clocks for bus0 clock controller:
-		- aclk_bus0_400
-
-	Input clocks for bus1 clock controller:
-		- aclk_bus1_400
-
-	Input clocks for bus2 clock controller:
-		- oscclk
-		- aclk_bus2_400
-
-	Input clocks for g3d clock controller:
-		- oscclk
-		- aclk_g3d_400
-
-	Input clocks for gscl clock controller:
-		- oscclk
-		- aclk_gscl_111
-		- aclk_gscl_333
-
-	Input clocks for apollo clock controller:
-		- oscclk
-		- sclk_bus_pll_apollo
-
-	Input clocks for atlas clock controller:
-		- oscclk
-		- sclk_bus_pll_atlas
-
-	Input clocks for mscl clock controller:
-		- oscclk
-		- sclk_jpeg_mscl
-		- aclk_mscl_400
-
-	Input clocks for mfc clock controller:
-		- oscclk
-		- aclk_mfc_400
-
-	Input clocks for hevc clock controller:
-		- oscclk
-		- aclk_hevc_400
-
-	Input clocks for isp clock controller:
-		- oscclk
-		- aclk_isp_dis_400
-		- aclk_isp_400
-
-	Input clocks for cam0 clock controller:
-		- oscclk
-		- aclk_cam0_333
-		- aclk_cam0_400
-		- aclk_cam0_552
-
-	Input clocks for cam1 clock controller:
-		- oscclk
-		- sclk_isp_uart_cam1
-		- sclk_isp_spi1_cam1
-		- sclk_isp_spi0_cam1
-		- aclk_cam1_333
-		- aclk_cam1_400
-		- aclk_cam1_552
-
-	Input clocks for imem clock controller:
-		- oscclk
-		- aclk_imem_sssx_266
-		- aclk_imem_266
-		- aclk_imem_200
-
-Optional properties:
-  - power-domains: a phandle to respective power domain node as described by
-	generic PM domain bindings (see power/power_domain.txt for more
-	information).
-
-Each clock is assigned an identifier and client nodes can use this identifier
-to specify the clock which they consume.
-
-All available clocks are defined as preprocessor macros in
-dt-bindings/clock/exynos5433.h header and can be used in device
-tree sources.
-
-Example 1: Examples of 'oscclk' source clock node are listed below.
-
-	xxti: xxti {
-		compatible = "fixed-clock";
-		clock-output-names = "oscclk";
-		#clock-cells = <0>;
-	};
-
-Example 2: Examples of clock controller nodes are listed below.
-
-	cmu_top: clock-controller at 10030000 {
-		compatible = "samsung,exynos5433-cmu-top";
-		reg = <0x10030000 0x0c04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_mphy_pll",
-			"sclk_mfc_pll",
-			"sclk_bus_pll";
-		clocks = <&xxti>,
-		       <&cmu_cpif CLK_SCLK_MPHY_PLL>,
-		       <&cmu_mif CLK_SCLK_MFC_PLL>,
-		       <&cmu_mif CLK_SCLK_BUS_PLL>;
-	};
-
-	cmu_cpif: clock-controller at 10fc0000 {
-		compatible = "samsung,exynos5433-cmu-cpif";
-		reg = <0x10fc0000 0x0c04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk";
-		clocks = <&xxti>;
-	};
-
-	cmu_mif: clock-controller at 105b0000 {
-		compatible = "samsung,exynos5433-cmu-mif";
-		reg = <0x105b0000 0x100c>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_mphy_pll";
-		clocks = <&xxti>,
-		       <&cmu_cpif CLK_SCLK_MPHY_PLL>;
-	};
-
-	cmu_peric: clock-controller at 14c80000 {
-		compatible = "samsung,exynos5433-cmu-peric";
-		reg = <0x14c80000 0x0b08>;
-		#clock-cells = <1>;
-	};
-
-	cmu_peris: clock-controller at 10040000 {
-		compatible = "samsung,exynos5433-cmu-peris";
-		reg = <0x10040000 0x0b20>;
-		#clock-cells = <1>;
-	};
-
-	cmu_fsys: clock-controller at 156e0000 {
-		compatible = "samsung,exynos5433-cmu-fsys";
-		reg = <0x156e0000 0x0b04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_ufs_mphy",
-			"aclk_fsys_200",
-			"sclk_pcie_100_fsys",
-			"sclk_ufsunipro_fsys",
-			"sclk_mmc2_fsys",
-			"sclk_mmc1_fsys",
-			"sclk_mmc0_fsys",
-			"sclk_usbhost30_fsys",
-			"sclk_usbdrd30_fsys";
-		clocks = <&xxti>,
-		       <&cmu_cpif CLK_SCLK_UFS_MPHY>,
-		       <&cmu_top CLK_ACLK_FSYS_200>,
-		       <&cmu_top CLK_SCLK_PCIE_100_FSYS>,
-		       <&cmu_top CLK_SCLK_UFSUNIPRO_FSYS>,
-		       <&cmu_top CLK_SCLK_MMC2_FSYS>,
-		       <&cmu_top CLK_SCLK_MMC1_FSYS>,
-		       <&cmu_top CLK_SCLK_MMC0_FSYS>,
-		       <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
-		       <&cmu_top CLK_SCLK_USBDRD30_FSYS>;
-	};
-
-	cmu_g2d: clock-controller at 12460000 {
-		compatible = "samsung,exynos5433-cmu-g2d";
-		reg = <0x12460000 0x0b08>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"aclk_g2d_266",
-			"aclk_g2d_400";
-		clocks = <&xxti>,
-		       <&cmu_top CLK_ACLK_G2D_266>,
-		       <&cmu_top CLK_ACLK_G2D_400>;
-		power-domains = <&pd_g2d>;
-	};
-
-	cmu_disp: clock-controller at 13b90000 {
-		compatible = "samsung,exynos5433-cmu-disp";
-		reg = <0x13b90000 0x0c04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_dsim1_disp",
-			"sclk_dsim0_disp",
-			"sclk_dsd_disp",
-			"sclk_decon_tv_eclk_disp",
-			"sclk_decon_vclk_disp",
-			"sclk_decon_eclk_disp",
-			"sclk_decon_tv_vclk_disp",
-			"aclk_disp_333";
-		clocks = <&xxti>,
-		       <&cmu_mif CLK_SCLK_DSIM1_DISP>,
-		       <&cmu_mif CLK_SCLK_DSIM0_DISP>,
-		       <&cmu_mif CLK_SCLK_DSD_DISP>,
-		       <&cmu_mif CLK_SCLK_DECON_TV_ECLK_DISP>,
-		       <&cmu_mif CLK_SCLK_DECON_VCLK_DISP>,
-		       <&cmu_mif CLK_SCLK_DECON_ECLK_DISP>,
-		       <&cmu_mif CLK_SCLK_DECON_TV_VCLK_DISP>,
-		       <&cmu_mif CLK_ACLK_DISP_333>;
-		power-domains = <&pd_disp>;
-	};
-
-	cmu_aud: clock-controller at 114c0000 {
-		compatible = "samsung,exynos5433-cmu-aud";
-		reg = <0x114c0000 0x0b04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "fout_aud_pll";
-		clocks = <&xxti>, <&cmu_top CLK_FOUT_AUD_PLL>;
-		power-domains = <&pd_aud>;
-	};
-
-	cmu_bus0: clock-controller at 13600000 {
-		compatible = "samsung,exynos5433-cmu-bus0";
-		reg = <0x13600000 0x0b04>;
-		#clock-cells = <1>;
-
-		clock-names = "aclk_bus0_400";
-		clocks = <&cmu_top CLK_ACLK_BUS0_400>;
-	};
-
-	cmu_bus1: clock-controller at 14800000 {
-		compatible = "samsung,exynos5433-cmu-bus1";
-		reg = <0x14800000 0x0b04>;
-		#clock-cells = <1>;
-
-		clock-names = "aclk_bus1_400";
-		clocks = <&cmu_top CLK_ACLK_BUS1_400>;
-	};
-
-	cmu_bus2: clock-controller at 13400000 {
-		compatible = "samsung,exynos5433-cmu-bus2";
-		reg = <0x13400000 0x0b04>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "aclk_bus2_400";
-		clocks = <&xxti>, <&cmu_mif CLK_ACLK_BUS2_400>;
-	};
-
-	cmu_g3d: clock-controller at 14aa0000 {
-		compatible = "samsung,exynos5433-cmu-g3d";
-		reg = <0x14aa0000 0x1000>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "aclk_g3d_400";
-		clocks = <&xxti>, <&cmu_top CLK_ACLK_G3D_400>;
-		power-domains = <&pd_g3d>;
-	};
-
-	cmu_gscl: clock-controller at 13cf0000 {
-		compatible = "samsung,exynos5433-cmu-gscl";
-		reg = <0x13cf0000 0x0b10>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"aclk_gscl_111",
-			"aclk_gscl_333";
-		clocks = <&xxti>,
-			<&cmu_top CLK_ACLK_GSCL_111>,
-			<&cmu_top CLK_ACLK_GSCL_333>;
-		power-domains = <&pd_gscl>;
-	};
-
-	cmu_apollo: clock-controller at 11900000 {
-		compatible = "samsung,exynos5433-cmu-apollo";
-		reg = <0x11900000 0x1088>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "sclk_bus_pll_apollo";
-		clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_APOLLO>;
-	};
-
-	cmu_atlas: clock-controller at 11800000 {
-		compatible = "samsung,exynos5433-cmu-atlas";
-		reg = <0x11800000 0x1088>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "sclk_bus_pll_atlas";
-		clocks = <&xxti>, <&cmu_mif CLK_SCLK_BUS_PLL_ATLAS>;
-	};
-
-	cmu_mscl: clock-controller at 105d0000 {
-		compatible = "samsung,exynos5433-cmu-mscl";
-		reg = <0x105d0000 0x0b10>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_jpeg_mscl",
-			"aclk_mscl_400";
-		clocks = <&xxti>,
-		       <&cmu_top CLK_SCLK_JPEG_MSCL>,
-		       <&cmu_top CLK_ACLK_MSCL_400>;
-		power-domains = <&pd_mscl>;
-	};
-
-	cmu_mfc: clock-controller at 15280000 {
-		compatible = "samsung,exynos5433-cmu-mfc";
-		reg = <0x15280000 0x0b08>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "aclk_mfc_400";
-		clocks = <&xxti>, <&cmu_top CLK_ACLK_MFC_400>;
-		power-domains = <&pd_mfc>;
-	};
-
-	cmu_hevc: clock-controller at 14f80000 {
-		compatible = "samsung,exynos5433-cmu-hevc";
-		reg = <0x14f80000 0x0b08>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk", "aclk_hevc_400";
-		clocks = <&xxti>, <&cmu_top CLK_ACLK_HEVC_400>;
-		power-domains = <&pd_hevc>;
-	};
-
-	cmu_isp: clock-controller at 146d0000 {
-		compatible = "samsung,exynos5433-cmu-isp";
-		reg = <0x146d0000 0x0b0c>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"aclk_isp_dis_400",
-			"aclk_isp_400";
-		clocks = <&xxti>,
-		       <&cmu_top CLK_ACLK_ISP_DIS_400>,
-		       <&cmu_top CLK_ACLK_ISP_400>;
-		power-domains = <&pd_isp>;
-	};
-
-	cmu_cam0: clock-controller at 120d0000 {
-		compatible = "samsung,exynos5433-cmu-cam0";
-		reg = <0x120d0000 0x0b0c>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"aclk_cam0_333",
-			"aclk_cam0_400",
-			"aclk_cam0_552";
-		clocks = <&xxti>,
-		       <&cmu_top CLK_ACLK_CAM0_333>,
-		       <&cmu_top CLK_ACLK_CAM0_400>,
-		       <&cmu_top CLK_ACLK_CAM0_552>;
-		power-domains = <&pd_cam0>;
-	};
-
-	cmu_cam1: clock-controller at 145d0000 {
-		compatible = "samsung,exynos5433-cmu-cam1";
-		reg = <0x145d0000 0x0b08>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"sclk_isp_uart_cam1",
-			"sclk_isp_spi1_cam1",
-			"sclk_isp_spi0_cam1",
-			"aclk_cam1_333",
-			"aclk_cam1_400",
-			"aclk_cam1_552";
-		clocks = <&xxti>,
-		       <&cmu_top CLK_SCLK_ISP_UART_CAM1>,
-		       <&cmu_top CLK_SCLK_ISP_SPI1_CAM1>,
-		       <&cmu_top CLK_SCLK_ISP_SPI0_CAM1>,
-		       <&cmu_top CLK_ACLK_CAM1_333>,
-		       <&cmu_top CLK_ACLK_CAM1_400>,
-		       <&cmu_top CLK_ACLK_CAM1_552>;
-		power-domains = <&pd_cam1>;
-	};
-
-	cmu_imem: clock-controller at 11060000 {
-		compatible = "samsung,exynos5433-cmu-imem";
-		reg = <0x11060000 0x1000>;
-		#clock-cells = <1>;
-
-		clock-names = "oscclk",
-			"aclk_imem_sssx_266",
-			"aclk_imem_266",
-			"aclk_imem_200";
-		clocks = <&xxti>,
-			<&cmu_top CLK_DIV_ACLK_IMEM_SSSX_266>,
-			<&cmu_top CLK_DIV_ACLK_IMEM_266>,
-			<&cmu_top CLK_DIV_ACLK_IMEM_200>;
-	};
-
-Example 3: UART controller node that consumes the clock generated by the clock
-	   controller.
-
-	serial_0: serial at 14c10000 {
-		compatible = "samsung,exynos5433-uart";
-		reg = <0x14C10000 0x100>;
-		interrupts = <0 421 0>;
-		clocks = <&cmu_peric CLK_PCLK_UART0>,
-			 <&cmu_peric CLK_SCLK_UART0>;
-		clock-names = "uart", "clk_uart_baud0";
-		pinctrl-names = "default";
-		pinctrl-0 = <&uart0_bus>;
-	};
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
new file mode 100644
index 000000000000..edd1b4ac4334
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
@@ -0,0 +1,524 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/samsung,exynos5433-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5433 SoC clock controller
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  Expected external clocks, defined in DTS as fixed-rate clocks with a matching
+  name::
+    - "oscclk" - PLL input clock from XXTI
+
+  All available clocks are defined as preprocessor macros in
+  include/dt-bindings/clock/exynos5433.h header.
+
+properties:
+  compatible:
+    enum:
+        # CMU_TOP which generates clocks for
+        # IMEM/FSYS/G3D/GSCL/HEVC/MSCL/G2D/MFC/PERIC/PERIS domains and bus
+        # clocks
+      - samsung,exynos5433-cmu-top
+        # CMU_CPIF which generates clocks for LLI (Low Latency Interface) IP
+      - samsung,exynos5433-cmu-cpif
+        # CMU_MIF which generates clocks for DRAM Memory Controller domain
+      - samsung,exynos5433-cmu-mif
+        # CMU_PERIC which generates clocks for
+        # UART/I2C/SPI/I2S/PCM/SPDIF/PWM/SLIMBUS IPs
+      - samsung,exynos5433-cmu-peric
+        # CMU_PERIS which generates clocks for PMU/TMU/MCT/WDT/RTC/SECKEY/TZPC IPs
+      - samsung,exynos5433-cmu-peris
+        # CMU_FSYS which generates clocks for USB/UFS/SDMMC/TSI/PDMA IPs
+      - samsung,exynos5433-cmu-fsys
+      - samsung,exynos5433-cmu-g2d
+        # CMU_DISP which generates clocks for Display (DECON/HDMI/DSIM/MIXER) IPs
+      - samsung,exynos5433-cmu-disp
+      - samsung,exynos5433-cmu-aud
+      - samsung,exynos5433-cmu-bus0
+      - samsung,exynos5433-cmu-bus1
+      - samsung,exynos5433-cmu-bus2
+      - samsung,exynos5433-cmu-g3d
+      - samsung,exynos5433-cmu-gscl
+      - samsung,exynos5433-cmu-apollo
+        # CMU_ATLAS which generates clocks for Cortex-A57 Quad-core processor,
+        # CoreSight and  L2 cache controller
+      - samsung,exynos5433-cmu-atlas
+        # CMU_MSCL which generates clocks for M2M (Memory to Memory) scaler and
+        # JPEG IPs
+      - samsung,exynos5433-cmu-mscl
+      - samsung,exynos5433-cmu-mfc
+      - samsung,exynos5433-cmu-hevc
+        # CMU_ISP which generates clocks for FIMC-ISP/DRC/SCLC/DIS/3DNR IPs
+      - samsung,exynos5433-cmu-isp
+        # CMU_CAM0 which generates clocks for
+        # MIPI_CSIS{0|1}/FIMC_LITE_{A|B|D}/FIMC_3AA{0|1} IPs
+      - samsung,exynos5433-cmu-cam0
+        # CMU_CAM1 which generates clocks for
+        # Cortex-A5/MIPI_CSIS2/FIMC-LITE_C/FIMC-FD IPs
+      - samsung,exynos5433-cmu-cam1
+        # CMU_IMEM which generates clocks for SSS (Security SubSystem) and
+        # SlimSSS IPs
+      - samsung,exynos5433-cmu-imem
+
+  clocks:
+    minItems: 1
+    maxItems: 10
+
+  clock-names:
+    minItems: 1
+    maxItems: 10
+
+  "#clock-cells":
+    const: 1
+
+  power-domains:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-top
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_mphy_pll
+            - const: sclk_mfc_pll
+            - const: sclk_bus_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-cpif
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: oscclk
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-mif
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_mphy_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-fsys
+    then:
+      properties:
+        clocks:
+          minItems: 10
+          maxItems: 10
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_ufs_mphy
+            - const: aclk_fsys_200
+            - const: sclk_pcie_100_fsys
+            - const: sclk_ufsunipro_fsys
+            - const: sclk_mmc2_fsys
+            - const: sclk_mmc1_fsys
+            - const: sclk_mmc0_fsys
+            - const: sclk_usbhost30_fsys
+            - const: sclk_usbdrd30_fsys
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-g2d
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_g2d_266
+            - const: aclk_g2d_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-disp
+    then:
+      properties:
+        clocks:
+          minItems: 9
+          maxItems: 9
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_dsim1_disp
+            - const: sclk_dsim0_disp
+            - const: sclk_dsd_disp
+            - const: sclk_decon_tv_eclk_disp
+            - const: sclk_decon_vclk_disp
+            - const: sclk_decon_eclk_disp
+            - const: sclk_decon_tv_vclk_disp
+            - const: aclk_disp_333
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-aud
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: fout_aud_pll
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-bus0
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: aclk_bus0_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-bus1
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: aclk_bus1_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-bus2
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_bus2_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-g3d
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_g3d_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-gscl
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_gscl_111
+            - const: aclk_gscl_333
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-apollo
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_bus_pll_apollo
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-atlas
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_bus_pll_atlas
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-mscl
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_jpeg_mscl
+            - const: aclk_mscl_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-mfc
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_mfc_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-hevc
+    then:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_hevc_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-isp
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_isp_dis_400
+            - const: aclk_isp_400
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-cam0
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_cam0_333
+            - const: aclk_cam0_400
+            - const: aclk_cam0_552
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-cam1
+    then:
+      properties:
+        clocks:
+          minItems: 7
+          maxItems: 7
+        clock-names:
+          items:
+            - const: oscclk
+            - const: sclk_isp_uart_cam1
+            - const: sclk_isp_spi1_cam1
+            - const: sclk_isp_spi0_cam1
+            - const: aclk_cam1_333
+            - const: aclk_cam1_400
+            - const: aclk_cam1_552
+      required:
+        - clock-names
+        - clocks
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-cmu-imem
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: oscclk
+            - const: aclk_imem_sssx_266
+            - const: aclk_imem_266
+            - const: aclk_imem_200
+      required:
+        - clock-names
+        - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    xxti: clock {
+        compatible = "fixed-clock";
+        clock-output-names = "oscclk";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+    };
+
+    clock-controller at 10030000 {
+        compatible = "samsung,exynos5433-cmu-top";
+        reg = <0x10030000 0x1000>;
+        #clock-cells = <1>;
+
+        clock-names = "oscclk",
+                      "sclk_mphy_pll",
+                      "sclk_mfc_pll",
+                      "sclk_bus_pll";
+        clocks = <&xxti>,
+                 <&cmu_cpif CLK_SCLK_MPHY_PLL>,
+                 <&cmu_mif CLK_SCLK_MFC_PLL>,
+                 <&cmu_mif CLK_SCLK_BUS_PLL>;
+    };
-- 
2.32.0



From maz at kernel.org  Sun Jan  2 05:08:28 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sun, 02 Jan 2022 13:08:28 +0000
Subject: [PATCH v2 devicetree] Revert "arm64: dts: freescale: Fix
 'interrupt-map' parent address cells"
In-Reply-To: <20211231181350.qwfnrwvdfnfssdjt@skbuf>
References: <20211214135852.2934670-1-vladimir.oltean@nxp.com>
 <20211231181350.qwfnrwvdfnfssdjt@skbuf>
Message-ID: <c5b9cec617100b891b7fceaee8655ba8@kernel.org>

On 2021-12-31 18:13, Vladimir Oltean wrote:
> Hello,
> 
> On Tue, Dec 14, 2021 at 03:58:52PM +0200, Vladimir Oltean wrote:
>> This reverts commit 869f0ec048dc8fd88c0b2003373bd985795179fb. That
>> updated the expected device tree binding format for the ls-extirq
>> driver, without also updating the parsing code (ls_extirq_parse_map)
>> to the new format.
>> 
>> The context is that the ls-extirq driver uses the standard
>> "interrupt-map" OF property in a non-standard way, as suggested by
>> Rob Herring during review:
>> https://lore.kernel.org/lkml/20190927161118.GA19333 at bogus/
>> 
>> This has turned out to be problematic, as Marc Zyngier discovered
>> through commit 041284181226 ("of/irq: Allow matching of an 
>> interrupt-map
>> local to an interrupt controller"), later fixed through commit
>> de4adddcbcc2 ("of/irq: Add a quirk for controllers with their own
>> definition of interrupt-map"). Marc's position, expressed on multiple
>> opportunities, is that:
>> 
>> (a) [ making private use of the reserved "interrupt-map" name in a
>>     driver ] "is wrong, by the very letter of what an interrupt-map
>>     means. If the interrupt map points to an interrupt controller,
>>     that's the target for the interrupt."
>> https://lore.kernel.org/lkml/87k0g8jlmg.wl-maz at kernel.org/
>> 
>> (b) [ updating the driver's bindings to accept a non-reserved name for
>>     this property, as an alternative, is ] "is totally pointless. 
>> These
>>     machines have been in the wild for years, and existing DTs will be
>>     there *forever*."
>> https://lore.kernel.org/lkml/87ilvrk1r0.wl-maz at kernel.org/
>> 
>> Considering the above, the Linux kernel has quirks in place to deal 
>> with
>> the ls-extirq's non-standard use of the "interrupt-map". These quirks
>> may be needed in other operating systems that consume this device 
>> tree,
>> yet this is seen as the only viable solution.
>> 
>> Therefore, the premise of the patch being reverted here is invalid.
>> It doesn't matter whether the driver, in its non-standard use of the
>> property, complies to the standard format or not, since this property
>> isn't expected to be used for interrupt translation by the core.
>> 
>> This change restores LS1088A, LS2088A/LS2085A and LX2160A to their
>> previous bindings, which allows these systems to continue to use
>> external interrupt lines with the correct polarity.
>> 
>> Fixes: 869f0ec048dc ("arm64: dts: freescale: Fix 'interrupt-map' 
>> parent address cells")
>> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
>> ---
>> v1->v2: remove the other 9 patches that rename "interrupt-map" to
>>         "fsl,extirq-map", at Marc's suggestion.
> 
> Could this patch be considered for merging in v5.16? The problem is
> going to be quite a bit more severe and tricky to fix otherwise. 
> Thanks.

FWIW:

Acked-by: Marc Zyngier <maz at kernel.org>

Rob, Shawn, can you please queue this as an urgent fix for 5.16?

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...


From daniel at makrotopia.org  Sun Jan  2 07:47:52 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 2 Jan 2022 15:47:52 +0000
Subject: [PATCH v10 0/3] net: ethernet: mtk_eth_soc: refactoring and Clause 45
In-Reply-To: <YdCNZh5PsBwbfMtp@lunn.ch>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
Message-ID: <YdHJKLfFCJvYBcdB@makrotopia.org>

Rework value and type of mdio read and write functions in mtk_eth_soc
and generally clean up and unify both functions.
Then add support to access Clause 45 phy registers, using newly
introduced helper macros added by a patch Russell King has suggested
in a reply to an earlier version of this series [1].

All three commits are tested on the Bananapi BPi-R64 board having
MediaTek MT7531BE DSA gigE switch using clause 22 MDIO and
Ubiquiti UniFi 6 LR access point having Aquantia AQR112C PHY using
clause 45 MDIO.

[1]: https://lore.kernel.org/netdev/Ycr5Cna76eg2B0An at shell.armlinux.org.uk/

v10: correct order of SoB lines in 2/3, change patch order in series
v9: improved formatting and Cc missing maintainer
v8: add patch from Russel King, switch to bitfield helper macros
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

Daniel Golle (2):
  net: ethernet: mtk_eth_soc: fix return value and refactor MDIO ops
  net: ethernet: mtk_eth_soc: implement Clause 45 MDIO access

Russell King (Oracle) (1):
  net: mdio: add helpers to extract clause 45 regad and devad fields

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 85 +++++++++++++++------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 19 +++--
 include/linux/mdio.h                        | 12 +++
 3 files changed, 89 insertions(+), 27 deletions(-)

-- 
2.34.1



From daniel at makrotopia.org  Sun Jan  2 07:48:18 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 2 Jan 2022 15:48:18 +0000
Subject: [PATCH v10 1/3] net: ethernet: mtk_eth_soc: fix return value and
 refactor MDIO ops
In-Reply-To: <YdCNZh5PsBwbfMtp@lunn.ch>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
Message-ID: <YdHJQhG3vmEJ4ia6@makrotopia.org>

Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
while writing or 0xffff if it happens while reading, return the
appropriate -EBUSY. Also fix return type to int instead of u32.
Refactor functions to use bitfield helpers instead of having various
masking and shifting constants in the code.

Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros
v7: remove unneeded variables
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 39 ++++++++++-----------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 ++++++---
 2 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index bcb91b01e69f5..0806688567d8b 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -94,43 +94,42 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
 	return -1;
 }
 
-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
-			   u32 phy_register, u32 write_data)
+static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
+			   u32 write_data)
 {
 	if (mtk_mdio_busy_wait(eth))
-		return -1;
-
-	write_data &= 0xffff;
+		return -EBUSY;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
-		(phy_register << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_WRITE |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr) |
+		     PHY_IAC_DATA(write_data),
 		MTK_PHY_IAC);
 
 	if (mtk_mdio_busy_wait(eth))
-		return -1;
+		return -EBUSY;
 
 	return 0;
 }
 
-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
+static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 {
-	u32 d;
-
 	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
+		return -EBUSY;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
-		(phy_reg << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT),
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_C22_READ |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr),
 		MTK_PHY_IAC);
 
 	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
-
-	d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
+		return -EBUSY;
 
-	return d;
+	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
 }
 
 static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 5ef70dd8b49c6..f2d90639d7ed1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -341,11 +341,17 @@
 /* PHY Indirect Access Control registers */
 #define MTK_PHY_IAC		0x10004
 #define PHY_IAC_ACCESS		BIT(31)
-#define PHY_IAC_READ		BIT(19)
-#define PHY_IAC_WRITE		BIT(18)
-#define PHY_IAC_START		BIT(16)
-#define PHY_IAC_ADDR_SHIFT	20
-#define PHY_IAC_REG_SHIFT	25
+#define PHY_IAC_REG_MASK	GENMASK(29, 25)
+#define PHY_IAC_REG(x)		FIELD_PREP(PHY_IAC_REG_MASK, (x))
+#define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
+#define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
+#define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
+#define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
+#define PHY_IAC_DATA_MASK	GENMASK(15, 0)
+#define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
 #define PHY_IAC_TIMEOUT		HZ
 
 #define MTK_MAC_MISC		0x1000c
-- 
2.34.1



From daniel at makrotopia.org  Sun Jan  2 07:48:50 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 2 Jan 2022 15:48:50 +0000
Subject: [PATCH v10 2/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
In-Reply-To: <YdCNZh5PsBwbfMtp@lunn.ch>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
Message-ID: <YdHJYuO0rYAoWAfD@makrotopia.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

Add a couple of helpers and definitions to extract the clause 45 regad
and devad fields from the regnum passed into MDIO drivers.

Tested-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v10: correct order of SoB lines
v9: unchanged
v8: First inclusing upon comment on mailing list

 include/linux/mdio.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 9f3587a61e145..ecac96d52e010 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -7,6 +7,7 @@
 #define __LINUX_MDIO_H__
 
 #include <uapi/linux/mdio.h>
+#include <linux/bitfield.h>
 #include <linux/mod_devicetable.h>
 
 /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
@@ -14,6 +15,7 @@
  */
 #define MII_ADDR_C45		(1<<30)
 #define MII_DEVADDR_C45_SHIFT	16
+#define MII_DEVADDR_C45_MASK	GENMASK(20, 16)
 #define MII_REGADDR_C45_MASK	GENMASK(15, 0)
 
 struct gpio_desc;
@@ -381,6 +383,16 @@ static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
 	return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
 }
 
+static inline u16 mdiobus_c45_regad(u32 regnum)
+{
+	return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
+}
+
+static inline u16 mdiobus_c45_devad(u32 regnum)
+{
+	return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
+}
+
 static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
 				     u16 regnum)
 {
-- 
2.34.1



From krzysztof.kozlowski at canonical.com  Sun Jan  2 07:58:06 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 16:58:06 +0100
Subject: [PATCH 1/2] ARM: dts: exynos: split dmas into array of phandles in
 Exynos5250
Message-ID: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>

"dmas" property should be rather an array of phandles, as dtschema
points.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..102bb57bf704 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
 			status = "disabled";
 			reg = <0x12d20000 0x100>;
 			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 5
-				&pdma0 4>;
+			dmas = <&pdma0 5>, <&pdma0 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
 			status = "disabled";
 			reg = <0x12d30000 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma1 5
-				&pdma1 4>;
+			dmas = <&pdma1 5>, <&pdma1 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
 			status = "disabled";
 			reg = <0x12d40000 0x100>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 7
-				&pdma0 6>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan  2 07:58:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun,  2 Jan 2022 16:58:07 +0100
Subject: [PATCH 2/2] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/spi/samsung,spi.yaml  | 220 ++++++++++++++++++
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ----------
 MAINTAINERS                                   |   2 +-
 3 files changed, 221 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..195bfafe05fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,220 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+patternProperties:
+  "^.*@[0-9a-f]+$":
+    type: object
+
+    allOf:
+      - $ref: spi-peripheral-props.yaml
+
+    properties:
+      controller-data:
+        type: object
+        additionalProperties: false
+
+        properties:
+          samsung,spi-feedback-delay:
+            description: |
+              The sampling phase shift to be applied on the miso line (to account
+              for any lag in the miso line). Valid values:
+               - 0: No phase shift.
+               - 1: 90 degree phase shift sampling.
+               - 2: 180 degree phase shift sampling.
+               - 3: 270 degree phase shift sampling.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3]
+
+        required:
+          - samsung,spi-feedback-delay
+
+    required:
+      - controller-data
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+        status = "okay";
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index af392bd04874..572eb97f1855 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17058,7 +17058,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From linux at armlinux.org.uk  Sun Jan  2 07:51:16 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Sun, 2 Jan 2022 15:51:16 +0000
Subject: [PATCH v10 0/3] net: ethernet: mtk_eth_soc: refactoring and
 Clause 45
In-Reply-To: <YdHJKLfFCJvYBcdB@makrotopia.org>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
 <YdHJKLfFCJvYBcdB@makrotopia.org>
Message-ID: <YdHJ9Kkl4+zwCV1+@shell.armlinux.org.uk>

On Sun, Jan 02, 2022 at 03:47:52PM +0000, Daniel Golle wrote:
> Rework value and type of mdio read and write functions in mtk_eth_soc
> and generally clean up and unify both functions.
> Then add support to access Clause 45 phy registers, using newly
> introduced helper macros added by a patch Russell King has suggested
> in a reply to an earlier version of this series [1].

Can you please stop threading each re-post to the previous posting of
the series. It's getting rather annoying after ten iterations to have
the subject lines disappearing off the right hand side of the field.
This is not a request to re-post, it is a request for the next posting.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From daniel at makrotopia.org  Sun Jan  2 07:49:16 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Sun, 2 Jan 2022 15:49:16 +0000
Subject: [PATCH v10 3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
 access
In-Reply-To: <YdCNZh5PsBwbfMtp@lunn.ch>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
Message-ID: <YdHJfPVBHUlIs3Yp@makrotopia.org>

Implement read and write access to IEEE 802.3 Clause 45 Ethernet
phy registers while making use of new mdiobus_c45_regad and
mdiobus_c45_devad helpers.
Improve readability by using bitfield helper macros which makes the
register definitions in the header file resemble the exact values
stated in the Reference Manual.

Tested on the Ubiquiti UniFi 6 LR access point featuring
MediaTek MT7622BV WiSoC with Aquantia AQR112C.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros, incl. newly introduced ones
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 68 +++++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +
 2 files changed, 58 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 0806688567d8b..786f3d63ec78c 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -100,13 +100,34 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
 	if (mtk_mdio_busy_wait(eth))
 		return -EBUSY;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_WRITE |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr) |
-		     PHY_IAC_DATA(write_data),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		if (mtk_mdio_busy_wait(eth))
+			return -EBUSY;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	}
 
 	if (mtk_mdio_busy_wait(eth))
 		return -EBUSY;
@@ -119,12 +140,32 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 	if (mtk_mdio_busy_wait(eth))
 		return -EBUSY;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_C22_READ |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		if (mtk_mdio_busy_wait(eth))
+			return -EBUSY;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_READ |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_C22_READ |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	}
 
 	if (mtk_mdio_busy_wait(eth))
 		return -EBUSY;
@@ -496,6 +537,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
 	eth->mii_bus->name = "mdio";
 	eth->mii_bus->read = mtk_mdio_read;
 	eth->mii_bus->write = mtk_mdio_write;
+	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
 	eth->mii_bus->priv = eth;
 	eth->mii_bus->parent = eth->dev;
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f2d90639d7ed1..c9d42be314b5a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -346,9 +346,12 @@
 #define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
 #define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
 #define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_C45_ADDR	FIELD_PREP(PHY_IAC_CMD_MASK, 0)
 #define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
 #define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_CMD_C45_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 3)
 #define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C45	FIELD_PREP(PHY_IAC_START_MASK, 0)
 #define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
 #define PHY_IAC_DATA_MASK	GENMASK(15, 0)
 #define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
-- 
2.34.1



From andrew at lunn.ch  Sun Jan  2 08:43:32 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 2 Jan 2022 17:43:32 +0100
Subject: [PATCH v10 1/3] net: ethernet: mtk_eth_soc: fix return value and
 refactor MDIO ops
In-Reply-To: <YdHJQhG3vmEJ4ia6@makrotopia.org>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
 <YdHJQhG3vmEJ4ia6@makrotopia.org>
Message-ID: <YdHWNIcr9AzFG7oN@lunn.ch>

> +static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
> +			   u32 write_data)
>  {
>  	if (mtk_mdio_busy_wait(eth))
> -		return -1;
> -
> -	write_data &= 0xffff;
> +		return -EBUSY;

-ETIMEDOUT would be more normal.

I would probably also change mtk_mdio_busy_wait() so that it either
returned 0, or -ETIMEDOUT. That is the general pattern in Linux,
return 0 on success, or a negative error code. Returning -1 is an
invitation for trouble.

The code would then become

    ret = mtk_mdio_busy_wait(eth);
    if (ret < 0)
       return ret;

which is a very common pattern in Linux.

      Andrew


From andrew at lunn.ch  Sun Jan  2 08:44:39 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 2 Jan 2022 17:44:39 +0100
Subject: [PATCH v10 2/3] net: mdio: add helpers to extract clause 45
 regad and devad fields
In-Reply-To: <YdHJYuO0rYAoWAfD@makrotopia.org>
References: <YdCNZh5PsBwbfMtp@lunn.ch>
 <YdHJYuO0rYAoWAfD@makrotopia.org>
Message-ID: <YdHWd1kabzYee1Gp@lunn.ch>

On Sun, Jan 02, 2022 at 03:48:50PM +0000, Daniel Golle wrote:
> From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
> 
> Add a couple of helpers and definitions to extract the clause 45 regad
> and devad fields from the regnum passed into MDIO drivers.
> 
> Tested-by: Daniel Golle <daniel at makrotopia.org>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Daniel Golle <daniel at makrotopia.org>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From romain.perier at gmail.com  Sun Jan  2 08:57:21 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:21 +0100
Subject: [PATCH v2 0/9] ARM: mstar: cpupll
Message-ID: <20220102165730.50190-1-romain.perier@gmail.com>

This series adds a basic driver for the PLL that generates
the cpu clock on MStar/SigmaStar ARMv7 SoCs.

Unfortunately there isn't much documentation for this thing
so there are few magic values and guesses.

This needs to come after the MPLL DT changes.

Changes since v2:
- Re-worked the series and ensure that 'make dt_binding_check' passes.
  The required commit is merged now, so it is okay.
- Fixed coding style issues in the driver and makes check_patch.pl happy
- Added one more commit for extending the opp_table for infinity2m.

Daniel Palmer (8):
  dt-bindings: clk: mstar msc313 cpupll binding description
  clk: mstar: msc313 cpupll clk driver
  ARM: mstar: Add cpupll to base dtsi
  ARM: mstar: Link cpupll to cpu
  ARM: mstar: Link cpupll to second core
  ARM: mstar: Add OPP table for infinity
  ARM: mstar: Add OPP table for infinity3
  ARM: mstar: Add OPP table for mercury5

Romain Perier (1):
  ARM: mstar: Extend opp_table for infinity2m

 .../bindings/clock/mstar,msc313-cpupll.yaml   |  45 ++++
 arch/arm/boot/dts/mstar-infinity.dtsi         |  34 +++
 arch/arm/boot/dts/mstar-infinity2m.dtsi       |  17 ++
 arch/arm/boot/dts/mstar-infinity3.dtsi        |  58 +++++
 arch/arm/boot/dts/mstar-mercury5.dtsi         |  36 +++
 arch/arm/boot/dts/mstar-v7.dtsi               |   9 +
 drivers/clk/mstar/Kconfig                     |   7 +
 drivers/clk/mstar/Makefile                    |   1 +
 drivers/clk/mstar/clk-msc313-cpupll.c         | 227 ++++++++++++++++++
 9 files changed, 434 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:22 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:22 +0100
Subject: [PATCH v2 1/9] dt-bindings: clk: mstar msc313 cpupll binding
 description
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-2-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a binding description for the MStar/SigmaStar CPU PLL block.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 .../bindings/clock/mstar,msc313-cpupll.yaml   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml

diff --git a/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
new file mode 100644
index 000000000000..a9ad7ab5230c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mstar,msc313-cpupll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MStar/Sigmastar MSC313 CPU PLL
+
+maintainers:
+  - Daniel Palmer <daniel at thingy.jp>
+
+description: |
+  The MStar/SigmaStar MSC313 and later ARMv7 chips have a scalable
+  PLL that can be used as the clock source for the CPU(s).
+
+properties:
+  compatible:
+    const: mstar,msc313-cpupll
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mstar-msc313-mpll.h>
+    cpupll: cpupll at 206400 {
+        compatible = "mstar,msc313-cpupll";
+        reg = <0x206400 0x200>;
+        #clock-cells = <1>;
+        clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+    };
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:23 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:23 +0100
Subject: [PATCH v2 2/9] clk: mstar: msc313 cpupll clk driver
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a driver for the CPU pll/ARM pll/MIPS pll that is present
in MStar SoCs.

Currently there is no documentation for this block so it's possible
this driver isn't entirely correct.

Only tested on the version of this IP in the MStar/SigmaStar
ARMv7 SoCs.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 drivers/clk/mstar/Kconfig             |   7 +
 drivers/clk/mstar/Makefile            |   1 +
 drivers/clk/mstar/clk-msc313-cpupll.c | 227 ++++++++++++++++++++++++++
 3 files changed, 235 insertions(+)
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

diff --git a/drivers/clk/mstar/Kconfig b/drivers/clk/mstar/Kconfig
index de37e1bce2d2..a44ca2b180ff 100644
--- a/drivers/clk/mstar/Kconfig
+++ b/drivers/clk/mstar/Kconfig
@@ -7,3 +7,10 @@ config MSTAR_MSC313_MPLL
 	help
 	  Support for the MPLL PLL and dividers block present on
 	  MStar/Sigmastar SoCs.
+
+config MSTAR_MSC313_CPUPLL
+	bool "MStar CPUPLL driver"
+	depends on ARCH_MSTARV7 || COMPILE_TEST
+	default ARCH_MSTARV7
+	help
+	  Support for the CPU PLL present on MStar/Sigmastar SoCs.
diff --git a/drivers/clk/mstar/Makefile b/drivers/clk/mstar/Makefile
index f8dcd25ede1d..9f05b73a0619 100644
--- a/drivers/clk/mstar/Makefile
+++ b/drivers/clk/mstar/Makefile
@@ -4,3 +4,4 @@
 #
 
 obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
+obj-$(CONFIG_MSTAR_MSC313_CPUPLL) += clk-msc313-cpupll.o
diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c
new file mode 100644
index 000000000000..2229b16475eb
--- /dev/null
+++ b/drivers/clk/mstar/clk-msc313-cpupll.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Daniel Palmer <daniel at thingy.jp>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+/*
+ * This IP is not documented outside of the messy vendor driver.
+ * Below is what we think the registers look like based on looking at
+ * the vendor code and poking at the hardware:
+ *
+ * 0x140 -- LPF low. Seems to store one half of the clock transition
+ * 0x144 /
+ * 0x148 -- LPF high. Seems to store one half of the clock transition
+ * 0x14c /
+ * 0x150 -- vendor code says "toggle lpf enable"
+ * 0x154 -- mu?
+ * 0x15c -- lpf_update_count?
+ * 0x160 -- vendor code says "switch to LPF". Clock source config? Register bank?
+ * 0x164 -- vendor code says "from low to high" which seems to mean transition from LPF low to
+ * LPF high.
+ * 0x174 -- Seems to be the PLL lock status bit
+ * 0x180 -- Seems to be the current frequency, this might need to be populated by software?
+ * 0x184 /  The vendor driver uses these to set the initial value of LPF low
+ *
+ * Frequency seems to be calculated like this:
+ * (parent clock (432mhz) / register_magic_value) * 16 * 524288
+ * Only the lower 24 bits of the resulting value will be used. In addition, the
+ * PLL doesn't seem to be able to lock on frequencies lower than 220 MHz, as
+ * divisor 0xfb586f (220 MHz) works but 0xfb7fff locks up.
+ *
+ * Vendor values:
+ * frequency - register value
+ *
+ * 400000000  - 0x0067AE14
+ * 600000000  - 0x00451EB8,
+ * 800000000  - 0x0033D70A,
+ * 1000000000 - 0x002978d4,
+ */
+
+#define REG_LPF_LOW_L		0x140
+#define REG_LPF_LOW_H		0x144
+#define REG_LPF_HIGH_BOTTOM	0x148
+#define REG_LPF_HIGH_TOP	0x14c
+#define REG_LPF_TOGGLE		0x150
+#define REG_LPF_MYSTERYTWO	0x154
+#define REG_LPF_UPDATE_COUNT	0x15c
+#define REG_LPF_MYSTERYONE	0x160
+#define REG_LPF_TRANSITIONCTRL	0x164
+#define REG_LPF_LOCK		0x174
+#define REG_CURRENT		0x180
+
+#define MULTIPLIER_1		16
+#define MULTIPLIER_2		524288
+#define MULTIPLIER		(MULTIPLIER_1 * MULTIPLIER_2)
+
+struct msc313_cpupll {
+	void __iomem *base;
+	struct clk_hw clk_hw;
+};
+
+#define to_cpupll(_hw) container_of(_hw, struct msc313_cpupll, clk_hw)
+
+static u32 msc313_cpupll_reg_read32(struct msc313_cpupll *cpupll, unsigned int reg)
+{
+	u32 value;
+
+	value = ioread16(cpupll->base + reg + 4) << 16;
+	value |= ioread16(cpupll->base + reg);
+
+	return value;
+}
+
+static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
+{
+	u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
+
+	iowrite16(l, cpupll->base + reg);
+	iowrite16(h, cpupll->base + reg + 4);
+}
+
+static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
+{
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
+
+	iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
+	iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
+	iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
+	iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+	iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
+
+	while (!(ioread16(cpupll->base + REG_LPF_LOCK)))
+		cpu_relax();
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L, regvalue);
+}
+
+static unsigned long msc313_cpupll_frequencyforreg(u32 reg, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+	unsigned long long scaled;
+
+	if (prescaled == 0 || reg == 0)
+		return 0;
+	scaled = DIV_ROUND_DOWN_ULL(prescaled, reg);
+
+	return scaled;
+}
+
+static u32 msc313_cpupll_regforfrequecy(unsigned long rate, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+	unsigned long long scaled;
+	u32 reg;
+
+	if (prescaled == 0 || rate == 0)
+		return 0;
+
+	scaled = DIV_ROUND_UP_ULL(prescaled, rate);
+	reg = scaled;
+
+	return reg;
+}
+
+static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+
+	return msc313_cpupll_frequencyforreg(msc313_cpupll_reg_read32(cpupll, REG_LPF_LOW_L),
+					     parent_rate);
+}
+
+static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
+	long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	/*
+	 * This is my poor attempt at making sure the resulting
+	 * rate doesn't overshoot the requested rate.
+	 */
+	for (; rounded >= rate && reg > 0; reg--)
+		rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	return rounded;
+}
+
+static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+	u32 reg = msc313_cpupll_regforfrequecy(rate, parent_rate);
+
+	msc313_cpupll_setfreq(cpupll, reg);
+
+	return 0;
+}
+
+static const struct clk_ops msc313_cpupll_ops = {
+	.recalc_rate	= msc313_cpupll_recalc_rate,
+	.round_rate	= msc313_cpupll_round_rate,
+	.set_rate	= msc313_cpupll_set_rate,
+};
+
+static const struct of_device_id msc313_cpupll_of_match[] = {
+	{
+		.compatible = "mstar,msc313-cpupll",
+	},
+	{}
+};
+
+static const struct clk_parent_data cpupll_parent = {
+	.index	= 0,
+};
+
+static int msc313_cpupll_probe(struct platform_device *pdev)
+{
+	struct clk_init_data clk_init = {};
+	struct device *dev = &pdev->dev;
+	struct msc313_cpupll *cpupll;
+	int ret;
+
+	cpupll = devm_kzalloc(&pdev->dev, sizeof(*cpupll), GFP_KERNEL);
+	if (!cpupll)
+		return -ENOMEM;
+
+	cpupll->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(cpupll->base))
+		return PTR_ERR(cpupll->base);
+
+	/* LPF might not contain the current frequency so fix that up */
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L,
+				  msc313_cpupll_reg_read32(cpupll, REG_CURRENT));
+
+	clk_init.name = dev_name(dev);
+	clk_init.ops = &msc313_cpupll_ops;
+	clk_init.flags = CLK_IS_CRITICAL;
+	clk_init.parent_data = &cpupll_parent;
+	clk_init.num_parents = 1;
+	cpupll->clk_hw.init = &clk_init;
+
+	ret = devm_clk_hw_register(dev, &cpupll->clk_hw);
+	if (ret)
+		return ret;
+
+	return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, &cpupll->clk_hw);
+}
+
+static struct platform_driver msc313_cpupll_driver = {
+	.driver = {
+		.name = "mstar-msc313-cpupll",
+		.of_match_table = msc313_cpupll_of_match,
+	},
+	.probe = msc313_cpupll_probe,
+};
+builtin_platform_driver(msc313_cpupll_driver);
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:24 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:24 +0100
Subject: [PATCH v2 3/9] ARM: mstar: Add cpupll to base dtsi
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-4-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

All MStar/SigmaStar ARMv7 SoCs have the CPU PLL at the same
place so add it to the base dtsi.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 89ebfe4f29da..2249faaa3aa7 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -155,6 +155,13 @@ mpll: mpll at 206000 {
 				clocks = <&xtal>;
 			};
 
+			cpupll: cpupll at 206400 {
+				compatible = "mstar,msc313-cpupll";
+				reg = <0x206400 0x200>;
+				#clock-cells = <0>;
+				clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+			};
+
 			gpio: gpio at 207800 {
 				#gpio-cells = <2>;
 				reg = <0x207800 0x200>;
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:25 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:25 +0100
Subject: [PATCH v2 4/9] ARM: mstar: Link cpupll to cpu
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-5-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The CPU clock is sourced from the CPU PLL.
Link cpupll to the cpu so that frequency scaling can happen.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 2249faaa3aa7..c26ba9b7b6dd 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -21,6 +21,8 @@ cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clocks = <&cpupll>;
+			clock-names = "cpuclk";
 		};
 	};
 
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:26 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:26 +0100
Subject: [PATCH v2 5/9] ARM: mstar: Link cpupll to second core
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-6-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The second core also sources it's clock from the CPU PLL.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index 6d4d1d224e96..dc339cd29778 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -11,6 +11,8 @@ cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
 		reg = <0x1>;
+		clocks = <&cpupll>;
+		clock-names = "cpuclk";
 	};
 };
 
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:27 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:27 +0100
Subject: [PATCH v2 6/9] ARM: mstar: Add OPP table for infinity
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-7-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add an OPP table for the inifinity chips so
that cpu frequency scaling can happen.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity.dtsi | 34 +++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi
index 0bee517797f4..441a917b88ba 100644
--- a/arch/arm/boot/dts/mstar-infinity.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity.dtsi
@@ -8,6 +8,40 @@
 
 #include <dt-bindings/gpio/msc313-gpio.h>
 
+/ {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-240000000 {
+			opp-hz = /bits/ 64 <240000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+};
+
+&cpu0 {
+	operating-points-v2 = <&cpu0_opp_table>;
+};
+
 &imi {
 	reg = <0xa0000000 0x16000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:28 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:28 +0100
Subject: [PATCH v2 7/9] ARM: mstar: Add OPP table for infinity3
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-8-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The infinity3 has a slightly higher max frequency
compared to the infinity so extend the OPP table.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity3.dtsi | 58 ++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity3.dtsi b/arch/arm/boot/dts/mstar-infinity3.dtsi
index 9857e2a9934d..a56cf29e5d82 100644
--- a/arch/arm/boot/dts/mstar-infinity3.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity3.dtsi
@@ -6,6 +6,64 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+	opp-1008000000 {
+		opp-hz = /bits/ 64 <1008000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+	};
+
+	// overclock frequencies below, shown to work fine up to 1.3 GHz
+	opp-108000000 {
+		opp-hz = /bits/ 64 <1080000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1188000000 {
+		opp-hz = /bits/ 64 <1188000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1296000000 {
+		opp-hz = /bits/ 64 <1296000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1350000000 {
+		opp-hz = /bits/ 64 <1350000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1404000000 {
+		opp-hz = /bits/ 64 <1404000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1458000000 {
+		opp-hz = /bits/ 64 <1458000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1512000000 {
+		opp-hz = /bits/ 64 <1512000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+};
+
 &imi {
 	reg = <0xa0000000 0x20000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:29 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:29 +0100
Subject: [PATCH v2 8/9] ARM: mstar: Add OPP table for mercury5
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-9-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add an OPP table for mercury5 so that cpu frequency scaling can
happen.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-mercury5.dtsi | 36 +++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-mercury5.dtsi b/arch/arm/boot/dts/mstar-mercury5.dtsi
index a7d0dd9d6132..80a19bd23c9c 100644
--- a/arch/arm/boot/dts/mstar-mercury5.dtsi
+++ b/arch/arm/boot/dts/mstar-mercury5.dtsi
@@ -6,6 +6,42 @@
 
 #include "mstar-v7.dtsi"
 
+/ {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <800000 800000 850000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <850000 850000 880000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <880000 880000 890000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <900000 900000 1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <900000 900000 1000000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+};
+
 &imi {
 	reg = <0xa0000000 0x20000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Sun Jan  2 08:57:30 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Sun,  2 Jan 2022 17:57:30 +0100
Subject: [PATCH v2 9/9] ARM: mstar: Extend opp_table for infinity2m
In-Reply-To: <20220102165730.50190-1-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
Message-ID: <20220102165730.50190-10-romain.perier@gmail.com>

infinity2m are running up to 1.2Ghz, this extends opp_table with the
corresponding frequencies and enable operating-points table for cpu1

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index dc339cd29778..1b485efd7156 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -6,10 +6,25 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+};
+
 &cpus {
 	cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
+		operating-points-v2 = <&cpu0_opp_table>;
 		reg = <0x1>;
 		clocks = <&cpupll>;
 		clock-names = "cpuclk";
-- 
2.34.1



From clabbe.montjoie at gmail.com  Sun Jan  2 09:38:51 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Sun, 2 Jan 2022 18:38:51 +0100
Subject: [PATCH v6] sun4i-emac.c: add dma support
In-Reply-To: <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
References: <20211228164817.1297c1c9@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
 <Yc7e6V9/oioEpx8c@Red>
 <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
Message-ID: <YdHjK+/SzaeI/V2Q@Red>

Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a ?crit :
> On 12/31/21 at 11:43??, Corentin Labbe wrote:
> > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > From: Corentin Labbe <clabbe.montjoie at gmail.com>
> > To: conleylee at foxmail.com
> > Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
> >  wens at csie.org, netdev at vger.kernel.org,
> >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee at foxmail.com a ?crit :
> > > From: Conley Lee <conleylee at foxmail.com>
> > > 
> > > Thanks for your review. Here is the new version for this patch.
> > > 
> > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > is able to move packets from rx fifo to RAM by using dma.
> > > 
> > > Change since v4.
> > >   - rename sbk field to skb
> > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > >     sleeping
> > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > >   - fix some code style issues 
> > > 
> > > Change since v5.
> > >   - fix some code style issue
> > > 
> > 
> > Hello
> > 
> > I just tested this on a sun4i-a10-olinuxino-lime
> > 
> > I got:
> > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > 
> > On which board did you test it and how ?
> > 
> > Regards
> 
> Sorry. I sent the email with text/html format. This email is an clean version.
> 
> In order to enable dma rx channel. `dmas` and `dma-names` properties
> should be added to emac section in dts:
> 
> emac: ethernet at 1c0b000 {
> 	...
> 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> 	dma-names = "rx";
> 	...
> }

Helo

Yes I figured that out. But you should have done a patch serie adding this.
Your patch is now applied but it is a useless change without the dtb change.
You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.

Furthermore, why did you add RX only and not TX dma also ?

Probably it is too late since patch is applied but it is:
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Tested-on: sun4i-a10-olinuxino-lime

Regards


From linux at dominikbrodowski.net  Sun Jan  2 09:35:41 2022
From: linux at dominikbrodowski.net (Dominik Brodowski)
Date: Sun, 2 Jan 2022 18:35:41 +0100
Subject: [PATCH] pcmcia: clean up dead drivers for CompuLab
 CM-X255/CM-X270 boards
In-Reply-To: <20210816150115.12889-1-lukas.bulwahn@gmail.com>
References: <20210816150115.12889-1-lukas.bulwahn@gmail.com>
Message-ID: <YdHibXIuQiBD/TM1@owl.dominikbrodowski.net>

Am Mon, Aug 16, 2021 at 05:01:15PM +0200 schrieb Lukas Bulwahn:
> Commit 9d3239147d6d ("ARM: pxa: remove Compulab pxa2xx boards") removes
> the config MACH_ARMCORE in ./arch/arm/mach-pxa/Kconfig.
> 
> Hence, ./scripts/checkkconfigsymbols.py warns on non-existing configs:
> 
> MACH_ARMCORE
> Referencing files: drivers/pcmcia/Kconfig, drivers/pcmcia/Makefile
> 
> Clean up the dead remains of pcmcia drivers for Compulab pxa2xx boards.
> 
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>

Applied to pcmcia-next.

Thanks,
	Dominik


From martin.blumenstingl at googlemail.com  Sun Jan  2 11:36:48 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sun, 2 Jan 2022 20:36:48 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
Message-ID: <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>

Hi,

On Sat, Jan 1, 2022 at 2:30 PM Yu Tu <yu.tu at amlogic.com> wrote:
[...]
> > Interesting, thanks for sharing that u-boot turns these clocks on.
> > Let's say someone wanted to make u-boot save power and turn off all
> > UART clocks except the one for uart_AO (where we typically connect the
> > serial console).
> > In that case the pclk of uart_C (just to choose an example here) is
> > turned off. Would there be a problem then accessing the registers of
> > uart_C before clk_prepare_enable is called?
> The way you describe it, it does hang. This would not be recommended on
> actual projects.
>
> At present, AmLogic chips are older than S4 Soc, and we have no way to
> deal with this problem. We have to tell customers not to use it in this
> way?Customers rarely use it in real projects.On the S4 SOC we will use
> a clock like the UART pclk to control the shutdown using two registers,
> one safe (need to operate in EL3) and one normal (EL1). It will only be
> closed if both registers are closed. This mainly prevents misoperation.
oh, interesting that there's some updates specifically with the S4 SoCs :-)

> With your experience, I'd like to know how you deal with this kind of
> problem.
Before this patch the driver simply turns on the clock from within
meson_uart_probe() (specifically it does so in
meson_uart_probe_clock()).
I think there's advanced power-saving techniques. Maybe for now we
keep it simple and just enable the clock(s) at probe time and disable
them at driver remove time. What do you think?


Best regards,
Martin


From arinc.unal at arinc9.com  Sun Jan  2 12:26:06 2022
From: arinc.unal at arinc9.com (=?UTF-8?B?QXLEsW7DpyDDnE5BTA==?=)
Date: Sun, 2 Jan 2022 23:26:06 +0300
Subject: [PATCH] ARM: dts: BCM5301X: remove reg property from ports node
 on Asus RT-AC88U
In-Reply-To: <20211223192941.1016-1-arinc.unal@arinc9.com>
References: <20211223192941.1016-1-arinc.unal@arinc9.com>
Message-ID: <8c427486-a456-f070-4325-a5f220507ffe@arinc9.com>

Please ignore this patch since the commit this patch fixes was reverted. 
I'm going to submit another patch to make up for the revert.

On 23/12/2021 22:29, Ar?n? ?NAL wrote:
> The "reg" property on the "ports" node of the Realtek switch is not supposed to
> be there which causes warnings while compiling. Remove it.
> 
> Reported-by: Stephen Rothwell <sfr at canb.auug.org.au>
> Fixes: 3d2d52a0d183 ("ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U")
> Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
> ---
>   arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
> index df8199fd4eb4..82f9629f0abb 100644
> --- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
> +++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
> @@ -106,7 +106,6 @@ switch {
>   		ports {
>   			#address-cells = <1>;
>   			#size-cells = <0>;
> -			reg = <0>;
>   
>   			port at 0 {
>   				reg = <0>;


From arinc.unal at arinc9.com  Sun Jan  2 12:33:04 2022
From: arinc.unal at arinc9.com (=?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?=)
Date: Sun,  2 Jan 2022 23:33:04 +0300
Subject: [PATCH] ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U
Message-ID: <20220102203304.10420-1-arinc.unal@arinc9.com>

Define the Realtek RTL8365MB switch without interrupt support on the device
tree of Asus RT-AC88U.

Signed-off-by: Ar?n? ?NAL <arinc.unal at arinc9.com>
Acked-by: Alvin ?ipraga <alsi at bang-olufsen.dk>
---
 arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts | 76 ++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
index 249476fdad7a..82f9629f0abb 100644
--- a/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
+++ b/arch/arm/boot/dts/bcm47094-asus-rt-ac88u.dts
@@ -93,6 +93,82 @@ led {
 			gpios = <&chipcommon 4 GPIO_ACTIVE_LOW>;
 		};
 	};
+
+	switch {
+		compatible = "realtek,rtl8365mb";
+		/* 7 = MDIO (has input reads), 6 = MDC (clock, output only) */
+		mdc-gpios = <&chipcommon 6 GPIO_ACTIVE_HIGH>;
+		mdio-gpios = <&chipcommon 7 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&chipcommon 10 GPIO_ACTIVE_LOW>;
+		realtek,disable-leds;
+		dsa,member = <1 0>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+				label = "lan5";
+				phy-handle = <&ethphy0>;
+			};
+
+			port at 1 {
+				reg = <1>;
+				label = "lan6";
+				phy-handle = <&ethphy1>;
+			};
+
+			port at 2 {
+				reg = <2>;
+				label = "lan7";
+				phy-handle = <&ethphy2>;
+			};
+
+			port at 3 {
+				reg = <3>;
+				label = "lan8";
+				phy-handle = <&ethphy3>;
+			};
+
+			port at 6 {
+				reg = <6>;
+				label = "cpu";
+				ethernet = <&sw0_p5>;
+				phy-mode = "rgmii";
+				tx-internal-delay-ps = <2000>;
+				rx-internal-delay-ps = <2100>;
+
+				fixed-link {
+					speed = <1000>;
+					full-duplex;
+					pause;
+				};
+			};
+		};
+
+		mdio {
+			compatible = "realtek,smi-mdio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			ethphy0: ethernet-phy at 0 {
+				reg = <0>;
+			};
+
+			ethphy1: ethernet-phy at 1 {
+				reg = <1>;
+			};
+
+			ethphy2: ethernet-phy at 2 {
+				reg = <2>;
+			};
+
+			ethphy3: ethernet-phy at 3 {
+				reg = <3>;
+			};
+		};
+	};
 };
 
 &srab {
-- 
2.25.1



From miles.chen at mediatek.com  Sun Jan  2 15:46:32 2022
From: miles.chen at mediatek.com (miles.chen at mediatek.com)
Date: Mon, 3 Jan 2022 07:46:32 +0800
Subject: [PATCH v3] drm/mediatek: Fix unused-but-set variable warning
In-Reply-To: <fcaccc97-e920-08eb-ec3f-4c4b11ea8925@gmail.com>
References: <fcaccc97-e920-08eb-ec3f-4c4b11ea8925@gmail.com>
Message-ID: <20220102234633.31709-1-miles.chen@mediatek.com>

> I'm still not happy with the commit subject, I think it is misleading. Clang 
> only helped to find the bug, but the we are fixing something else, that's not 
> just a clang warning. But I don't want to nit-pick too much so:
> 
> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

thanks. I think you are right.
I will change the subject to "drm/mediatek: Fix mtk_cec_mask()", remove the 
clang part and submit patch v4.

e.g,
"""
drm/mediatek: Fix mtk_cec_mask()

In current implementation, mtk_cec_mask() writes val into target register
and ignores the mask. After talking to our hdmi experts, mtk_cec_mask()
should read a register, clean only mask bits, and update (val | mask) bits
to the register.

Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
"""


From ck.hu at mediatek.com  Sun Jan  2 17:49:58 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 3 Jan 2022 09:49:58 +0800
Subject: [PATCH v7 7/8] drm/mediatek: Add mt8195 DisplayPort driver
In-Reply-To: <20211217150854.2081-8-granquet@baylibre.com>
References: <20211217150854.2081-1-granquet@baylibre.com>
 <20211217150854.2081-8-granquet@baylibre.com>
Message-ID: <11b7a01889d9e0c5c3598f173be823e1e39ed397.camel@mediatek.com>

Hi, Guillaume:

This is a big patch, so I give you some comment first, and I would
continue to review this patch.

On Fri, 2021-12-17 at 16:08 +0100, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp at baylibre.com>
> 
> This patch adds a DisplayPort driver for the Mediatek mt8195 SoC.
> 
> It supports the mt8195, the external DisplayPort units. It offers
> hot-plug-detection, audio up to 8 channels, and DisplayPort 1.4 with
> up
> to 4 lanes.
> 
> The driver creates a child device for the phy. The child device will
> never exist without the parent being active. As they are sharing a
> register range, the parent passes a regmap pointer to the child so
> that
> both can work with the same register range. The phy driver sets
> device
> data that is read by the parent to get the phy device that can be
> used
> to control the phy properties.
> 
> This driver is based on an initial version by
> Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Reported-by: kernel test robot <lkp at intel.com>
> ---
>  drivers/gpu/drm/mediatek/Kconfig       |    7 +
>  drivers/gpu/drm/mediatek/Makefile      |    2 +
>  drivers/gpu/drm/mediatek/mtk_dp.c      | 3028
> ++++++++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_dp_reg.h  |  568 +++++
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c |    1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h |    1 +
>  6 files changed, 3607 insertions(+)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_dp_reg.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig
> b/drivers/gpu/drm/mediatek/Kconfig
> index 2976d21e9a34a..029b94c716131 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -28,3 +28,10 @@ config DRM_MEDIATEK_HDMI
>  	select PHY_MTK_HDMI
>  	help
>  	  DRM/KMS HDMI driver for Mediatek SoCs
> +
> +config MTK_DPTX_SUPPORT
> +	tristate "DRM DPTX Support for Mediatek SoCs"
> +	depends on DRM_MEDIATEK
> +	select PHY_MTK_DP
> +	help
> +	  DRM/KMS Display Port driver for Mediatek SoCs.
> diff --git a/drivers/gpu/drm/mediatek/Makefile
> b/drivers/gpu/drm/mediatek/Makefile
> index 29098d7c8307c..d86a6406055e6 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -21,3 +21,5 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>  			  mtk_hdmi_ddc.o
>  
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
> +
> +obj-$(CONFIG_MTK_DPTX_SUPPORT) += mtk_dp.o
> 

[snip]

> +
> +enum mtk_dp_train_state {
> +	MTK_DP_TRAIN_STATE_STARTUP = 0,
> +	MTK_DP_TRAIN_STATE_CHECKCAP,
> +	MTK_DP_TRAIN_STATE_CHECKEDID,
> +	MTK_DP_TRAIN_STATE_TRAINING_PRE,
> +	MTK_DP_TRAIN_STATE_TRAINING,
> +	MTK_DP_TRAIN_STATE_CHECKTIMING,
> +	MTK_DP_TRAIN_STATE_NORMAL,
> +	MTK_DP_TRAIN_STATE_POWERSAVE,

Never be this state, so remove it.

> +	MTK_DP_TRAIN_STATE_DPIDLE,
> +};
> +
> +struct mtk_dp_timings {
> +	struct videomode vm;
> +
> +	u16 htotal;
> +	u16 vtotal;
> +	u8 frame_rate;
> +	u32 pix_rate_khz;
> +};
> +
> +struct mtk_dp_train_info {
> +	bool tps3;
> +	bool tps4;
> +	bool sink_ssc;
> +	bool cable_plugged_in;
> +	bool cable_state_change;
> +	bool cr_done;
> +	bool eq_done;
> +
> +	// link_rate is in multiple of 0.27Gbps
> +	int link_rate;
> +	int lane_count;
> +
> +	int irq_status;
> +	int check_cap_count;
> +};
> +
> 

[snip]

> 
> +
> +static u32 mtk_dp_swirq_get_clear(struct mtk_dp *mtk_dp)
> +{
> +	u32 irq_status = mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_35D0) &
> +			 SW_IRQ_FINAL_STATUS_DP_TRANS_P0_MASK;
> +
> +	if (irq_status) {
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8,
> irq_status,
> +				   SW_IRQ_CLR_DP_TRANS_P0_MASK);

SW_IRQ_CLR_DP_TRANS_P0_MASK is already set, so this setting is
redundant, so remove this.


> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_35C8, 0,
> +				   SW_IRQ_CLR_DP_TRANS_P0_MASK);
> +	}
> +
> +	return irq_status;
> +}
> +
> +static u32 mtk_dp_hwirq_get_clear(struct mtk_dp *mtk_dp)
> +{
> +	u8 irq_status = (mtk_dp_read(mtk_dp, MTK_DP_TRANS_P0_3418) &
> +			 IRQ_STATUS_DP_TRANS_P0_MASK) >>
> +			IRQ_STATUS_DP_TRANS_P0_SHIFT;
> +
> +	if (irq_status) {
> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418,
> irq_status,
> +				   IRQ_CLR_DP_TRANS_P0_MASK);

IRQ_CLR_DP_TRANS_P0_MASK is already set, so this setting is redundant,
so remove this.


> +		mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, 0,
> +				   IRQ_CLR_DP_TRANS_P0_MASK);
> +	}
> +
> +	return irq_status;
> +}
> +
> +static void mtk_dp_hwirq_enable(struct mtk_dp *mtk_dp, bool enable)
> +{
> +	u32 val = 0;
> +
> +	if (!enable)
> +		val = IRQ_MASK_DP_TRANS_P0_DISC_IRQ |
> +		      IRQ_MASK_DP_TRANS_P0_CONN_IRQ |
> +		      IRQ_MASK_DP_TRANS_P0_INT_IRQ;
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3418, val,
> +			   IRQ_MASK_DP_TRANS_P0_MASK);
> +}
> +
> +void mtk_dp_initialize_settings(struct mtk_dp *mtk_dp)
> +{
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_342C,
> +			   XTAL_FREQ_DP_TRANS_P0_DEFAULT,
> +			   XTAL_FREQ_DP_TRANS_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3540,
> +			   BIT(FEC_CLOCK_EN_MODE_DP_TRANS_P0_SHIFT),
> +			   FEC_CLOCK_EN_MODE_DP_TRANS_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_31EC,
> +			   BIT(AUDIO_CH_SRC_SEL_DP_ENC0_P0_SHIFT),
> +			   AUDIO_CH_SRC_SEL_DP_ENC0_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_304C, 0,
> +			   SDP_VSYNC_RISING_MASK_DP_ENC0_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TOP_IRQ_MASK,
> IRQ_MASK_AUX_TOP_IRQ,
> +			   IRQ_MASK_AUX_TOP_IRQ);
> +}
> +
> +static void mtk_dp_initialize_hpd_detect_settings(struct mtk_dp
> *mtk_dp)
> +{
> +	// Debounce threshold

/* ... */

> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +			   8 << HPD_DEB_THD_DP_TRANS_P0_SHIFT,
> +			   HPD_DEB_THD_DP_TRANS_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +			   (HPD_INT_THD_DP_TRANS_P0_LOWER_500US |
> +			    HPD_INT_THD_DP_TRANS_P0_UPPER_1100US)
> +				   << HPD_INT_THD_DP_TRANS_P0_SHIFT,
> +			   HPD_INT_THD_DP_TRANS_P0_MASK);
> +
> +	// Connect threshold 1.5ms + 5 x 0.1ms = 2ms
> +	// Disconnect threshold 1.5ms + 5 x 0.1ms = 2ms
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3410,
> +			   (5 << HPD_DISC_THD_DP_TRANS_P0_SHIFT) |
> +				   (5 <<
> HPD_CONN_THD_DP_TRANS_P0_SHIFT),
> +			   HPD_DISC_THD_DP_TRANS_P0_MASK |
> +				   HPD_CONN_THD_DP_TRANS_P0_MASK);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_TRANS_P0_3430,
> +			   HPD_INT_THD_ECO_DP_TRANS_P0_HIGH_BOUND_EXT,
> +			   HPD_INT_THD_ECO_DP_TRANS_P0_MASK);
> +}
> +
> 

[snip]

> +
> +static int mtk_dp_train_handler(struct mtk_dp *mtk_dp)
> +{
> +	int ret = 0;
> +
> +	if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +		return ret;
> +
> +	switch (mtk_dp->train_state) {
> +	case MTK_DP_TRAIN_STATE_STARTUP:
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> +		break;
> +
> +	case MTK_DP_TRAIN_STATE_CHECKCAP:
> +		if (mtk_dp_parse_capabilities(mtk_dp)) {
> +			mtk_dp->train_info.check_cap_count = 0;
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKEDID;
> +		} else {
> +			mtk_dp->train_info.check_cap_count++;
> +
> +			if (mtk_dp->train_info.check_cap_count >
> +			    MTK_DP_CHECK_SINK_CAP_TIMEOUT_COUNT) {
> +				mtk_dp->train_info.check_cap_count = 0;
> +				mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +				ret = -ETIMEDOUT;
> +			}
> +		}
> +		break;
> +
> +	case MTK_DP_TRAIN_STATE_CHECKEDID: {
> +		int caps_found =
> mtk_dp_edid_parse_audio_capabilities(mtk_dp,
> +			&mtk_dp->info.audio_caps);
> +		mtk_dp->audio_enable = caps_found > 0;
> +		if (!mtk_dp->audio_enable)
> +			memset(&mtk_dp->info.audio_caps, 0,
> +			       sizeof(mtk_dp->info.audio_caps));
> +	}
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING_PRE;
> +		break;
> +
> +	case MTK_DP_TRAIN_STATE_TRAINING_PRE:
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_TRAINING;
> +		break;
> +
> +	case MTK_DP_TRAIN_STATE_TRAINING:
> +		ret = mtk_dp_train_start(mtk_dp);
> +		if (!ret) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp_audio_mute(mtk_dp, true);
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_CHECKTIMING;
> +			mtk_dp_fec_enable(mtk_dp, mtk_dp->has_fec);
> +		} else if (ret != -EAGAIN) {
> +			mtk_dp->train_state =
> MTK_DP_TRAIN_STATE_DPIDLE;
> +		}
> +
> +		ret = 0;
> +		break;
> +
> +	case MTK_DP_TRAIN_STATE_CHECKTIMING:
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_NORMAL;

If MTK_DP_TRAIN_STATE_CHECKTIMING does nothing,I think we should drop
state MTK_DP_TRAIN_STATE_CHECKTIMING.

> +		break;
> +	case MTK_DP_TRAIN_STATE_NORMAL:
> +		break;
> +	case MTK_DP_TRAIN_STATE_POWERSAVE:
> +		break;
> +	case MTK_DP_TRAIN_STATE_DPIDLE:
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> 

[snip]

> +
> +static void mtk_dp_video_config(struct mtk_dp *mtk_dp)
> +{
> +	mtk_dp_mn_overwrite_disable(mtk_dp);
> +
> +	mtk_dp_set_msa(mtk_dp);
> +
> +	mtk_dp_set_color_depth(mtk_dp, mtk_dp->info.depth);
> +	mtk_dp_set_color_format(mtk_dp, mtk_dp->info.format);
> +}
> +
> +static int mtk_dp_state_handler(struct mtk_dp *mtk_dp)

Always return 0, so change to void.

> +{
> +	int ret = 0;
> +
> +	switch (mtk_dp->state) {
> +	case MTK_DP_STATE_INITIAL:
> +		mtk_dp_video_mute(mtk_dp, true);
> +		mtk_dp_audio_mute(mtk_dp, true);
> +		mtk_dp->state = MTK_DP_STATE_IDLE;
> +		break;
> +
> +	case MTK_DP_STATE_IDLE:
> +		if (mtk_dp->train_state == MTK_DP_TRAIN_STATE_NORMAL)
> +			mtk_dp->state = MTK_DP_STATE_PREPARE;
> +		break;
> +
> +	case MTK_DP_STATE_PREPARE:
> +		mtk_dp_video_config(mtk_dp);
> +		mtk_dp_video_enable(mtk_dp, true);
> +
> +		if (mtk_dp->audio_enable) {
> +			mtk_dp_audio_setup(mtk_dp, &mtk_dp-
> >info.audio_caps);
> +			mtk_dp_audio_mute(mtk_dp, false);
> +		}
> +
> +		mtk_dp->state = MTK_DP_STATE_NORMAL;
> +		break;
> +
> +	case MTK_DP_STATE_NORMAL:
> +		if (mtk_dp->train_state != MTK_DP_TRAIN_STATE_NORMAL) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp_audio_mute(mtk_dp, true);
> +			mtk_dp_sdp_stop_sending(mtk_dp);
> +			mtk_dp->state = MTK_DP_STATE_IDLE;
> +		}
> +		break;
> +
> +	default:
> +		break;
> +	}
> +
> +	return ret;
> +}
> +
> +static void mtk_dp_init_port(struct mtk_dp *mtk_dp)
> +{
> +	mtk_dp_set_idle_pattern(mtk_dp, true);
> +	mtk_dp_initialize_priv_data(mtk_dp);
> +
> +	mtk_dp_initialize_settings(mtk_dp);
> +	mtk_dp_initialize_aux_settings(mtk_dp);
> +	mtk_dp_initialize_digital_settings(mtk_dp);
> +	mtk_dp_update_bits(mtk_dp, MTK_DP_AUX_P0_3690,
> +			   BIT(RX_REPLY_COMPLETE_MODE_AUX_TX_P0_SHIFT),
> +			   RX_REPLY_COMPLETE_MODE_AUX_TX_P0_MASK);
> +	mtk_dp_initialize_hpd_detect_settings(mtk_dp);
> +
> +	mtk_dp_digital_sw_reset(mtk_dp);
> +}
> +
> +static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	int event;

event is useless, do drop it.

> +	u8 buf[DP_RECEIVER_CAP_SIZE] = {};
> +
> +	event = mtk_dp_plug_state(mtk_dp) ? connector_status_connected
> :
> +						  connector_status_disc
> onnected;
> +
> +	if (event < 0)

Never happen, drop it.

> +		return IRQ_HANDLED;
> +
> +	if (mtk_dp->drm_dev) {
> +		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
> +		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> +	}
> +
> +	if (mtk_dp->train_info.cable_state_change) {
> +		mtk_dp->train_info.cable_state_change = false;
> +
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +
> +		if (!mtk_dp->train_info.cable_plugged_in ||
> +		    !mtk_dp_plug_state(mtk_dp)) {
> +			mtk_dp_video_mute(mtk_dp, true);
> +			mtk_dp_audio_mute(mtk_dp, true);
> +
> +			mtk_dp_initialize_priv_data(mtk_dp);
> +			mtk_dp_set_idle_pattern(mtk_dp, true);
> +			if (mtk_dp->has_fec)
> +				mtk_dp_fec_enable(mtk_dp, false);
> +			mtk_dp_sdp_stop_sending(mtk_dp);
> +
> +			mtk_dp_edid_free(mtk_dp);
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL,
> +					   DP_PWR_STATE_MASK);
> +		} else {
> +			mtk_dp_update_bits(mtk_dp,
> MTK_DP_TOP_PWR_STATE,
> +					   DP_PWR_STATE_BANDGAP_TPLL_LA
> NE,
> +					   DP_PWR_STATE_MASK);
> +			drm_dp_read_dpcd_caps(&mtk_dp->aux, buf);
> +			mtk_dp->train_info.link_rate =
> +				min_t(int, MTK_DP_MAX_LINK_RATE,
> +				      buf[DP_MAX_LINK_RATE]);
> +			mtk_dp->train_info.lane_count =
> +				min_t(int, MTK_DP_MAX_LANES,
> +				      drm_dp_max_lane_count(buf));
> +		}
> +	}
> +
> +	if (mtk_dp->train_info.irq_status & MTK_DP_HPD_INTERRUPT) {
> +		dev_info(mtk_dp->dev, "MTK_DP_HPD_INTERRUPT\n");
> +		mtk_dp->train_info.irq_status &= ~MTK_DP_HPD_INTERRUPT;
> +		mtk_dp_hpd_sink_event(mtk_dp);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
> +{
> +	bool connected;
> +	u16 swirq_status = mtk_dp_swirq_get_clear(mtk_dp);
> +	u8 hwirq_status = mtk_dp_hwirq_get_clear(mtk_dp);

mtk_dp_sw_irq_get_clear() and mtk_dp_hwirq_get_clear() is called once
here, so I would like to merge that two function into this function.

> +	struct mtk_dp_train_info *train_info = &mtk_dp->train_info;
> +
> +	train_info->irq_status |= hwirq_status | swirq_status;
> +
> +	if (!train_info->irq_status)
> +		return IRQ_HANDLED;
> +

Drop below algorithm, and call mtk_dp_plug_state() in
mtk_dp_hpd_event_thread(), and directly compare connected with
train_info->cable_plugged_in.

> +	connected = mtk_dp_plug_state(mtk_dp);
> +	if (connected || !train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +	else if (!connected || train_info->cable_plugged_in)
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +
> +	if (!(train_info->irq_status &
> +	      (MTK_DP_HPD_CONNECT | MTK_DP_HPD_DISCONNECT)))
> +		return IRQ_HANDLED;
> +
> +	if (train_info->irq_status & MTK_DP_HPD_CONNECT) {
> +		train_info->irq_status &= ~MTK_DP_HPD_CONNECT;
> +		train_info->cable_plugged_in = true;
> +	} else {
> +		train_info->irq_status &= ~MTK_DP_HPD_DISCONNECT;
> +		train_info->cable_plugged_in = false;
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
> +	}
> +	train_info->cable_state_change = true;
> +	return IRQ_WAKE_THREAD;
> +}
> +
> +static irqreturn_t mtk_dp_hpd_event(int hpd, void *dev)
> +{
> +	struct mtk_dp *mtk_dp = dev;
> +	u32 irq_status;
> +
> +	irq_status = mtk_dp_read(mtk_dp, MTK_DP_TOP_IRQ_STATUS);
> +
> +	if (!irq_status)
> +		return IRQ_HANDLED;
> +
> +	if (irq_status & RGS_IRQ_STATUS_TRANSMITTER)
> +		return mtk_dp_hpd_isr_handler(mtk_dp);

mtk_dp_hpd_isr_handler() is called once here,
so I would like to merge
mtk_dp_hpd_isr_handler() into this function,
and change mtk_dp_hpd_event() to mtk_dp_hpd_isr_handler().


> +
> +	return IRQ_HANDLED;
> +}
> +
> 

[snip]

> +
> +static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
> +				   struct drm_dp_aux_msg *msg)
> +{
> +	ssize_t err = -EAGAIN;
> +	struct mtk_dp *mtk_dp;
> +	bool is_read;
> +	u8 request;
> +	size_t accessed_bytes = 0;
> +	int retry = 3, ret = 0;
> +
> +	mtk_dp = container_of(mtk_aux, struct mtk_dp, aux);
> +
> +	if (!mtk_dp->train_info.cable_plugged_in ||
> +	    mtk_dp->train_info.irq_status & MTK_DP_HPD_DISCONNECT) {
> +		mtk_dp->train_state = MTK_DP_TRAIN_STATE_CHECKCAP;
> +		err = -EAGAIN;
> +		goto err;
> +	}
> +
> +	switch (msg->request) {

In intel_dp_aux_transfer() [1], it is 

switch (msg->request & ~DP_AUX_I2C_MOT) {

Would that be a better statement?


[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/i915/display/intel_dp_aux.c?h=v5.16-rc6#n413

> +	case DP_AUX_I2C_MOT:
> +	case DP_AUX_I2C_WRITE:
> +	case DP_AUX_NATIVE_WRITE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE:
> +	case DP_AUX_I2C_WRITE_STATUS_UPDATE | DP_AUX_I2C_MOT:
> +		request = msg->request &
> ~DP_AUX_I2C_WRITE_STATUS_UPDATE;
> +		is_read = false;
> +		break;
> +	case DP_AUX_I2C_READ:
> +	case DP_AUX_NATIVE_READ:
> +	case DP_AUX_I2C_READ | DP_AUX_I2C_MOT:
> +		request = msg->request;
> +		is_read = true;
> +		break;
> +	default:
> +		drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n",
> +			msg->request);
> +		err = -EINVAL;
> +		goto err;
> +	}
> +
> +	if (msg->size == 0) {
> +		mtk_dp_aux_do_transfer(mtk_dp, is_read, request,
> +				       msg->address + accessed_bytes,
> +				       msg->buffer + accessed_bytes,
> 0);
> +	} else {
> +		while (accessed_bytes < msg->size) {
> +			size_t to_access =
> +				min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES,
> +				      msg->size - accessed_bytes);
> +			retry = 3;
> +			while (retry--) {
> +				ret = mtk_dp_aux_do_transfer(mtk_dp,
> +							     is_read,
> request,
> +							     msg-
> >address + accessed_bytes,
> +							     msg-
> >buffer + accessed_bytes,
> +							     to_access)
> ;
> +				if (ret == 0)
> +					break;
> +				usleep_range(50, 100);
> +			}
> +			if (!retry && ret) {
> +				drm_info(mtk_dp->drm_dev,
> +					 "Failed to do AUX transfer:
> %d\n",
> +					 ret);
> +				break;
> +			}
> +			accessed_bytes += to_access;
> +		}
> +	}
> +err:
> +	if (ret) {
> +		msg->reply = DP_AUX_NATIVE_REPLY_NACK |
> DP_AUX_I2C_REPLY_NACK;
> +		return err;
> +	}
> +
> +	msg->reply = DP_AUX_NATIVE_REPLY_ACK | DP_AUX_I2C_REPLY_ACK;
> +	return msg->size;
> +}
> +
> 

[snip]

> +
> +static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge,
> +					struct drm_bridge_state
> *old_state)
> +{
> +	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
> +	struct drm_connector_state *conn_state;
> +	struct drm_crtc *crtc;
> +	struct drm_crtc_state *crtc_state;
> +	int ret = 0;
> +	int i;
> +
> +	mtk_dp->conn =
> drm_atomic_get_new_connector_for_encoder(old_state->base.state,
> +								bridge-
> >encoder);
> +	if (!mtk_dp->conn) {
> +		drm_err(mtk_dp->drm_dev,
> +			"Can't enable bridge as connector is
> missing\n");
> +		return;
> +	}
> +
> +	mutex_lock(&mtk_dp->eld_lock);
> +	memcpy(mtk_dp->connector_eld, mtk_dp->conn->eld,
> MAX_ELD_BYTES);
> +	mutex_unlock(&mtk_dp->eld_lock);
> +
> +	conn_state =
> +		drm_atomic_get_new_connector_state(old_state-
> >base.state, mtk_dp->conn);
> +	if (!conn_state) {
> +		drm_err(mtk_dp->drm_dev,
> +			"Can't enable bridge as connector state is
> missing\n");
> +		return;
> +	}
> +
> +	crtc = conn_state->crtc;
> +	if (!crtc) {
> +		drm_err(mtk_dp->drm_dev,
> +			"Can't enable bridge as connector state doesn't
> have a crtc\n");
> +		return;
> +	}
> +
> +	crtc_state = drm_atomic_get_new_crtc_state(old_state-
> >base.state, crtc);
> +	if (!crtc_state) {
> +		drm_err(mtk_dp->drm_dev,
> +			"Can't enable bridge as crtc state is
> missing\n");
> +		return;
> +	}
> +
> +	mtk_dp_parse_drm_mode_timings(mtk_dp, &crtc_state-
> >adjusted_mode);
> +	if (!mtk_dp_parse_capabilities(mtk_dp)) {
> +		drm_err(mtk_dp->drm_dev,
> +			"Can't enable bridge as nothing is plugged
> in\n");
> +		return;
> +	}
> +
> +	/* Training */
> +	for (i = 0; i < 50; i++) {
> +		ret = mtk_dp_train_handler(mtk_dp);

Why do you call mtk_dp_train_handler() many times? Call
mtk_dp_train_handler() once and let all retry inside
mtk_dp_train_handler().

> +		if (ret) {
> +			drm_err(mtk_dp->drm_dev, "Train handler failed
> %d\n",
> +				ret);
> +			return;
> +		}
> +
> +		ret = mtk_dp_state_handler(mtk_dp);
> +		if (ret) {
> +			drm_err(mtk_dp->drm_dev, "State handler failed
> %d\n",
> +				ret);
> +			return;
> +		}
> +	}
> +
> +	mtk_dp->enabled = true;
> +	mtk_dp_update_plugged_status(mtk_dp);
> +}
> +
> 

[snip]

> +
> +static int mtk_dp_probe(struct platform_device *pdev)
> +{
> +	struct mtk_dp *mtk_dp;
> +	struct device *dev = &pdev->dev;
> +	int ret;
> +	int irq_num = 0;
> +
> +	mtk_dp = devm_kzalloc(dev, sizeof(*mtk_dp), GFP_KERNEL);
> +	if (!mtk_dp)
> +		return -ENOMEM;
> +
> +	mtk_dp->dev = dev;
> +
> +	irq_num = platform_get_irq(pdev, 0);
> +	if (irq_num < 0) {
> +		dev_err(dev, "failed to request dp irq resource\n");
> +		return -EPROBE_DEFER;

return irq_num;

> +	}
> +
> +	mtk_dp->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 
> 1, 0);
> +	if (IS_ERR(mtk_dp->next_bridge)) {
> +		ret = PTR_ERR(mtk_dp->next_bridge);
> +		dev_err_probe(dev, ret, "Failed to get bridge\n");
> +		return ret;
> +	}
> +
> +	ret = mtk_dp_dt_parse(mtk_dp, pdev);
> +	if (ret)
> +		return ret;
> +
> +	mtk_dp_aux_init(mtk_dp);
> +
> +	ret = devm_request_threaded_irq(dev, irq_num, mtk_dp_hpd_event,
> +					mtk_dp_hpd_event_thread,
> +					IRQ_TYPE_LEVEL_HIGH,
> dev_name(dev),
> +					mtk_dp);
> +	if (ret) {
> +		dev_err(dev, "failed to request mediatek dptx irq\n");
> +		return -EPROBE_DEFER;

return ret;

> +	}
> +
> +	mutex_init(&mtk_dp->dp_lock);
> +	mutex_init(&mtk_dp->edid_lock);
> +	mutex_init(&mtk_dp->eld_lock);
> +
> +	platform_set_drvdata(pdev, mtk_dp);
> +
> +	mutex_init(&mtk_dp->update_plugged_status_lock);
> +	ret = mtk_dp_register_audio_driver(dev);
> +	if (ret) {
> +		dev_err(dev, "Failed to register audio driver: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
> +	mtk_dp->phy_dev = platform_device_register_data(dev, "mediatek-
> dp-phy",
> +							PLATFORM_DEVID_
> AUTO,
> +							&mtk_dp->regs,
> +							sizeof(struct
> regmap *));
> +	if (IS_ERR(mtk_dp->phy_dev)) {
> +		dev_err(dev, "Failed to create device mediatek-dp-phy:
> %ld\n",
> +			PTR_ERR(mtk_dp->phy_dev));
> +		return PTR_ERR(mtk_dp->phy_dev);
> +	}
> +
> +	mtk_dp_get_calibration_data(mtk_dp);
> +
> +	mtk_dp->phy = devm_phy_get(&mtk_dp->phy_dev->dev, "dp");
> +	if (IS_ERR(mtk_dp->phy)) {
> +		dev_err(dev, "Failed to get phy: %ld\n",
> PTR_ERR(mtk_dp->phy));
> +		platform_device_unregister(mtk_dp->phy_dev);
> +		return PTR_ERR(mtk_dp->phy);
> +	}
> +
> +	mtk_dp->bridge.funcs = &mtk_dp_bridge_funcs;
> +	mtk_dp->bridge.of_node = dev->of_node;
> +	mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
> +
> +	mtk_dp->bridge.ops =
> +		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
> DRM_BRIDGE_OP_HPD;
> +	drm_bridge_add(&mtk_dp->bridge);
> +
> +	pm_runtime_enable(dev);
> +	pm_runtime_get_sync(dev);
> +
> +	return 0;
> +}
> +
> 





From ck.hu at mediatek.com  Sun Jan  2 18:03:16 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 3 Jan 2022 10:03:16 +0800
Subject: [PATCH v10 15/22] drm/mediatek: add display merge async reset
 control
In-Reply-To: <20211208024426.15595-16-nancy.lin@mediatek.com>
References: <20211208024426.15595-1-nancy.lin@mediatek.com>
 <20211208024426.15595-16-nancy.lin@mediatek.com>
Message-ID: <73b6ac2405e72ba1479d84c226d0ede3ecc8dd72.camel@mediatek.com>

Hi, Nancy:

On Wed, 2021-12-08 at 10:44 +0800, Nancy.Lin wrote:
> Add merge async reset control in mtk_merge_stop. Async hw doesn't do
> self
> reset on each sof signal(start of frame), so need to reset the async
> to
> clear the hw status for the next merge start.

Reviewed-by: CK Hu <ck.hu at mediatek.com>

> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_disp_merge.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> index 9dca145cfb71..177473fa8160 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
> @@ -8,6 +8,7 @@
>  #include <linux/of_device.h>
>  #include <linux/of_irq.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset.h>
>  #include <linux/soc/mediatek/mtk-cmdq.h>
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev)
>  	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
>  
>  	mtk_merge_stop_cmdq(dev, NULL);
> +
> +	if (priv->async_clk)
> +		device_reset_optional(dev);
>  }
>  
>  void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt
> *cmdq_pkt)



From Kuan-Ying.Lee at mediatek.com  Sun Jan  2 18:32:55 2022
From: Kuan-Ying.Lee at mediatek.com (Kuan-Ying Lee)
Date: Mon, 3 Jan 2022 10:32:55 +0800
Subject: [PATCH mm v5 29/39] kasan, page_alloc: allow skipping memory
 init for HW_TAGS
In-Reply-To: <88f2964f4063aa6fd935ef8c8302d02d8d67005b.1640891329.git.andreyknvl@google.com>
References: <cover.1640891329.git.andreyknvl@google.com>
 <88f2964f4063aa6fd935ef8c8302d02d8d67005b.1640891329.git.andreyknvl@google.com>
Message-ID: <b968e485f4d7f201fdb4e39f64ca757180e7374a.camel@mediatek.com>

On Fri, 2021-12-31 at 03:14 +0800, andrey.konovalov at linux.dev wrote:
> From: Andrey Konovalov <andreyknvl at google.com>
> 
> Add a new GFP flag __GFP_SKIP_ZERO that allows to skip memory
> initialization. The flag is only effective with HW_TAGS KASAN.
> 
> This flag will be used by vmalloc code for page_alloc allocations
> backing vmalloc() mappings in a following patch. The reason to skip
> memory initialization for these pages in page_alloc is because
> vmalloc
> code will be initializing them instead.
> 
> With the current implementation, when __GFP_SKIP_ZERO is provided,
> __GFP_ZEROTAGS is ignored. This doesn't matter, as these two flags
> are
> never provided at the same time. However, if this is changed in the
> future, this particular implementation detail can be changed as well.
> 
> Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
> 
> ---
> 
> Changes v4->v5:
> - Cosmetic changes to __def_gfpflag_names_kasan and __GFP_BITS_SHIFT.
> 
> Changes v3->v4:
> - Only define __GFP_SKIP_ZERO when CONFIG_KASAN_HW_TAGS is enabled.
> - Add __GFP_SKIP_ZERO to include/trace/events/mmflags.h.
> - Use proper kasan_hw_tags_enabled() check instead of
>   IS_ENABLED(CONFIG_KASAN_HW_TAGS). Also add explicit checks for
>   software modes.
> 
> Changes v2->v3:
> - Update patch description.
> 
> Changes v1->v2:
> - Add this patch.
> ---
>  include/linux/gfp.h            | 18 +++++++++++-------
>  include/trace/events/mmflags.h |  1 +
>  mm/page_alloc.c                | 18 +++++++++++++++++-
>  3 files changed, 29 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> index 487126f089e1..6eef3e447540 100644
> --- a/include/linux/gfp.h
> +++ b/include/linux/gfp.h
> @@ -55,14 +55,16 @@ struct vm_area_struct;
>  #define ___GFP_ACCOUNT		0x400000u
>  #define ___GFP_ZEROTAGS		0x800000u
>  #ifdef CONFIG_KASAN_HW_TAGS
> -#define ___GFP_SKIP_KASAN_UNPOISON	0x1000000u
> -#define ___GFP_SKIP_KASAN_POISON	0x2000000u
> +#define ___GFP_SKIP_ZERO		0x1000000u
> +#define ___GFP_SKIP_KASAN_UNPOISON	0x2000000u
> +#define ___GFP_SKIP_KASAN_POISON	0x4000000u
>  #else
> +#define ___GFP_SKIP_ZERO		0
>  #define ___GFP_SKIP_KASAN_UNPOISON	0
>  #define ___GFP_SKIP_KASAN_POISON	0
>  #endif
>  #ifdef CONFIG_LOCKDEP
> -#define ___GFP_NOLOCKDEP	0x4000000u
> +#define ___GFP_NOLOCKDEP	0x8000000u
>  #else
>  #define ___GFP_NOLOCKDEP	0
>  #endif
> @@ -235,9 +237,10 @@ struct vm_area_struct;
>   * %__GFP_ZERO returns a zeroed page on success.
>   *
>   * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the
> memory itself
> - * is being zeroed (either via __GFP_ZERO or via init_on_alloc).
> This flag is
> - * intended for optimization: setting memory tags at the same time
> as zeroing
> - * memory has minimal additional performace impact.
> + * is being zeroed (either via __GFP_ZERO or via init_on_alloc,
> provided that
> + * __GFP_SKIP_ZERO is not set). This flag is intended for
> optimization: setting
> + * memory tags at the same time as zeroing memory has minimal
> additional
> + * performace impact.
>   *
>   * %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page
> allocation.
>   * Only effective in HW_TAGS mode.
> @@ -249,6 +252,7 @@ struct vm_area_struct;
>  #define __GFP_COMP	((__force gfp_t)___GFP_COMP)
>  #define __GFP_ZERO	((__force gfp_t)___GFP_ZERO)
>  #define __GFP_ZEROTAGS	((__force gfp_t)___GFP_ZEROTAGS)
> +#define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO)
>  #define __GFP_SKIP_KASAN_UNPOISON ((__force
> gfp_t)___GFP_SKIP_KASAN_UNPOISON)
>  #define __GFP_SKIP_KASAN_POISON   ((__force
> gfp_t)___GFP_SKIP_KASAN_POISON)
>  
> @@ -257,7 +261,7 @@ struct vm_area_struct;
>  
>  /* Room for N __GFP_FOO bits */
>  #define __GFP_BITS_SHIFT (24 +					
> 	\
> -			  2 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
> +			  3 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
>  			  IS_ENABLED(CONFIG_LOCKDEP))
>  #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) -
> 1))
>  
> diff --git a/include/trace/events/mmflags.h
> b/include/trace/events/mmflags.h
> index 5ffc7bdce91f..0698c5d0f194 100644
> --- a/include/trace/events/mmflags.h
> +++ b/include/trace/events/mmflags.h
> @@ -52,6 +52,7 @@
>  
>  #ifdef CONFIG_KASAN_HW_TAGS
>  #define __def_gfpflag_names_kasan ,					
>        \
> +	{(unsigned long)__GFP_SKIP_ZERO,	   "__GFP_SKIP_ZERO"},	     
>   \
>  	{(unsigned
> long)__GFP_SKIP_KASAN_POISON,   "__GFP_SKIP_KASAN_POISON"}, \
>  	{(unsigned long)__GFP_SKIP_KASAN_UNPOISON,
> "__GFP_SKIP_KASAN_UNPOISON"}
>  #else
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 102f0cd8815e..30da0e1f94f8 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -2415,10 +2415,26 @@ static inline bool
> should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
>  	return init_tags || (flags & __GFP_SKIP_KASAN_UNPOISON);
>  }
>  
> +static inline bool should_skip_init(gfp_t flags)
> +{
> +	/* Don't skip if a software KASAN mode is enabled. */
> +	if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
> +	    IS_ENABLED(CONFIG_KASAN_SW_TAGS))
> +		return false;

Forget to drop the above check?

I saw v4 mentioned that this check can be dropped. [1]

Do I miss something?

[1] https://lkml.org/lkml/2021/12/30/450

> +
> +	/* Don't skip, if hardware tag-based KASAN is not enabled. */
> +	if (!kasan_hw_tags_enabled())
> +		return false;
> +
> +	/* For hardware tag-based KASAN, skip if requested. */
> +	return (flags & __GFP_SKIP_ZERO);
> +}
> +
>  inline void post_alloc_hook(struct page *page, unsigned int order,
>  				gfp_t gfp_flags)
>  {
> -	bool init = !want_init_on_free() &&
> want_init_on_alloc(gfp_flags);
> +	bool init = !want_init_on_free() &&
> want_init_on_alloc(gfp_flags) &&
> +			!should_skip_init(gfp_flags);
>  	bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
>  
>  	set_page_private(page, 0);
> -- 
> 2.25.1
> 
> 



From yc.hung at mediatek.com  Sun Jan  2 20:32:03 2022
From: yc.hung at mediatek.com (YC Hung)
Date: Mon, 3 Jan 2022 12:32:03 +0800
Subject: [PATCH v3] dt-bindings: dsp: mediatek: add mt8195 dsp document
Message-ID: <20220103043202.6524-1-yc.hung@mediatek.com>

From: "YC Hung" <yc.hung at mediatek.com>

This patch adds mt8195 dsp document. The dsp is used for Sound Open
Firmware driver node. It includes registers,  clocks, memory regions,
and mailbox for dsp.

Signed-off-by: yc.hung <yc.hung at mediatek.com>
---
Changes since v2:
  Remove useless watchdog interrupt.
  Add commit message more detail description.

Changes since v1:
  Rename yaml file name as mediatek,mt8195-dsp.yaml
  Refine descriptions for mailbox, memory-region and drop unused labels
  in examples.
---
---
 .../devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
index bde763191d86..779daa786739 100644
--- a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
+++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
@@ -27,14 +27,6 @@ properties:
       - const: cfg
       - const: sram
 
-  interrupts:
-    items:
-      - description: watchdog interrupt
-
-  interrupt-names:
-    items:
-      - const: wdt
-
   clocks:
     items:
       - description: mux for audio dsp clock
@@ -75,8 +67,6 @@ required:
   - compatible
   - reg
   - reg-names
-  - interrupts
-  - interrupt-names
   - clocks
   - clock-names
   - memory-region
@@ -95,8 +85,6 @@ examples:
        reg = <0x10803000  0x1000>,
              <0x10840000  0x40000>;
        reg-names = "cfg", "sram";
-       interrupts = <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH 0>;
-       interrupt-names = "wdt";
        clocks = <&topckgen 10>, //CLK_TOP_ADSP
                 <&clk26m>,
                 <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS
-- 
2.18.0



From quic_saipraka at quicinc.com  Sun Jan  2 21:41:03 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 3 Jan 2022 11:11:03 +0530
Subject: [PATCHv6 0/5] tracing/rwmmio/arm64: Add support to trace register
 reads/writes
In-Reply-To: <93ef32a5-013a-fdcf-11bb-6f3c9bc34628@quicinc.com>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <93ef32a5-013a-fdcf-11bb-6f3c9bc34628@quicinc.com>
Message-ID: <4009226e-76bf-6e37-65be-8942ef7126df@quicinc.com>

On 12/13/2021 8:58 AM, Sai Prakash Ranjan wrote:
> Hi Arnd,
>
> On 12/7/2021 12:24 PM, Sai Prakash Ranjan wrote:
>> Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
>> are typically used to read/write from/to memory mapped registers
>> and can cause hangs or some undefined behaviour in following cases,
>>
>> * If the access to the register space is unclocked, for example: if
>> ?? there is an access to multimedia(MM) block registers without MM
>> ?? clocks.
>>
>> * If the register space is protected and not set to be accessible from
>> ?? non-secure world, for example: only EL3 (EL: Exception level) access
>> ?? is allowed and any EL2/EL1 access is forbidden.
>>
>> * If xPU(memory/register protection units) is controlling access to
>> ?? certain memory/register space for specific clients.
>>
>> and more...
>>
>> Such cases usually results in instant reboot/SErrors/NOC or interconnect
>> hangs and tracing these register accesses can be very helpful to debug
>> such issues during initial development stages and also in later stages.
>>
>> So use ftrace trace events to log such MMIO register accesses which
>> provides rich feature set such as early enablement of trace events,
>> filtering capability, dumping ftrace logs on console and many more.
>>
>> Sample output:
>>
>> rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 
>> val=0xa0d5d addr=0xfffffbfffdbff700
>> rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 
>> width=32 val=0xa0d5d addr=0xfffffbfffdbff700
>> rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 
>> addr=0xfffffbfffdbff610
>> rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 
>> val=0x0 addr=0xfffffbfffdbff610
>>
>> This series is a follow-up for the series [1] and a recent series [2] 
>> making use
>> of both.
>>
>> [1] 
>> https://lore.kernel.org/lkml/cover.1536430404.git.saiprakash.ranjan at codeaurora.org/
>> [2] 
>> https://lore.kernel.org/lkml/1604631386-178312-1-git-send-email-psodagud at codeaurora.org/
>>
>> Note in previous v4 version, Arnd suggested to benchmark and compare 
>> size with callback
>> based implementation, please see [3] for more details on that with 
>> brief comparison below.
>>
>>
>> **Inline version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
>> $ size vmlinux
>> ??? text?????????? data???????????? bss???? dec hex???????? filename
>> ? 23884219??????? 14284468???????? 532568 38701255 24e88c7??????? 
>> vmlinux
>>
>> **Callback version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
>> $ size vmlinux
>> ???? text????????? data???????????? bss???? dec hex??????? filename
>> ? 24108179??????? 14279596???????? 532568 38920343 251e097?????? vmlinux
>>
>> $ ./scripts/bloat-o-meter inline-vmlinux callback-vmlinux
>> add/remove: 8/3 grow/shrink: 4889/89 up/down: 242244/-11564 (230680)
>> Total: Before=25812612, After=26043292, chg +0.89%
>>
>> [3] 
>> https://lore.kernel.org/lkml/466449a1-36da-aaa9-7e4f-477f36b52c9e at quicinc.com/
>>
>> Changes in v6:
>> ? * Implemented suggestions by Arnd Bergmann:
>> ??? - Use arch independent IO barriers in arm64/asm
>> ??? - Add ARCH_HAVE_TRACE_MMIO_ACCESS
>> ??? - Add post read and post write logging support
>> ??? - Remove tracepoint_active check
>> ? * Fix build error reported by kernel test robot.
>>
>> Changes in v5:
>> ? * Move arm64 to use asm-generic provided high level MMIO accessors 
>> (Arnd).
>> ? * Add inline logging for MMIO relaxed and non-relaxed accessors.
>> ? * Move nVHE KVM comment to makefile (Marc).
>> ? * Fix overflow warning due to switch to inline accessors instead of 
>> macro.
>> ? * Modify trace event field to include caller and parent details for 
>> more detailed logs.
>>
>> Changes in v4:
>> ? * Drop dynamic debug based filter support since that will be 
>> developed later with
>> ??? the help from Steven (Ftrace maintainer).
>> ? * Drop value passed to writel as it is causing hangs when tracing 
>> is enabled.
>> ? * Code cleanup for trace event as suggested by Steven for earlier 
>> version.
>> ? * Fixed some build errors reported by 0-day bot.
>>
>> Changes in v3:
>> ? * Create a generic mmio header for instrumented version (Earlier 
>> suggested in [1]
>> ??? by Will Deacon and recently [2] by Greg to have a generic version 
>> first).
>> ? * Add dynamic debug support to filter out traces which can be very 
>> useful for targeted
>> ??? debugging specific to subsystems or drivers.
>> ? * Few modifications to the rwmmio trace event fields to include the 
>> mmio width and print
>> ??? addresses in hex.
>> ? * Rewrote commit msg to explain some more about usecases.
>>
>> Prasad Sodagudi (1):
>> ?? tracing: Add register read/write tracing support
>>
>> Sai Prakash Ranjan (4):
>> ?? arm64: io: Use asm-generic high level MMIO accessors
>> ?? irqchip/tegra: Fix overflow implicit truncation warnings
>> ?? drm/meson: Fix overflow implicit truncation warnings
>> ?? asm-generic/io: Add logging support for MMIO accessors
>>
>> ? arch/Kconfig????????????????????? |?? 3 +
>> ? arch/arm64/Kconfig??????????????? |?? 1 +
>> ? arch/arm64/include/asm/io.h?????? |? 41 +++--------
>> ? arch/arm64/kvm/hyp/nvhe/Makefile? |?? 7 +-
>> ? drivers/gpu/drm/meson/meson_viu.c |? 22 +++---
>> ? drivers/irqchip/irq-tegra.c?????? |? 10 +--
>> ? include/asm-generic/io.h????????? |? 81 +++++++++++++++++++--
>> ? include/trace/events/rwmmio.h???? | 112 ++++++++++++++++++++++++++++++
>> ? kernel/trace/Kconfig????????????? |?? 7 ++
>> ? kernel/trace/Makefile???????????? |?? 1 +
>> ? kernel/trace/trace_readwrite.c??? |? 47 +++++++++++++
>> ? 11 files changed, 278 insertions(+), 54 deletions(-)
>> ? create mode 100644 include/trace/events/rwmmio.h
>> ? create mode 100644 kernel/trace/trace_readwrite.c
>>
>
> Does this version look good to you? From the other mail thread it 
> seems Catalin
> is ok with your suggested change. Kernel test robot hasn't come with 
> any build error
> reports so far, I have fixed the previous reported one in meson drm 
> driver.
>
> Thanks,
> Sai

Any more comments for this version?

Thanks,
Sai


From miles.chen at mediatek.com  Sun Jan  2 21:47:06 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Mon, 3 Jan 2022 13:47:06 +0800
Subject: [PATCH v4] drm/mediatek: Fix mtk_cec_mask()
Message-ID: <20220103054706.8072-1-miles.chen@mediatek.com>

In current implementation, mtk_cec_mask() writes val into target register
and ignores the mask. After talking to our hdmi experts, mtk_cec_mask()
should read a register, clean only mask bits, and update (val | mask) bits
to the register.

Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")

Cc: Zhiqiang Lin <zhiqiang.lin at mediatek.com>
Cc: CK Hu <ck.hu at mediatek.com>
Cc: Matthias Brugger <matthias.bgg at gmail.com>

Signed-off-by: Miles Chen <miles.chen at mediatek.com>

---

Change since v1:
add Fixes tag

Change since v2:
add explanation of mtk_cec_mask()

Change since v3:
change misleading subject and modify the commit message since this is a bug fix patch

---
 drivers/gpu/drm/mediatek/mtk_cec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
index e9cef5c0c8f7..cdfa648910b2 100644
--- a/drivers/gpu/drm/mediatek/mtk_cec.c
+++ b/drivers/gpu/drm/mediatek/mtk_cec.c
@@ -85,7 +85,7 @@ static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset,
 	u32 tmp = readl(cec->regs + offset) & ~mask;
 
 	tmp |= val & mask;
-	writel(val, cec->regs + offset);
+	writel(tmp, cec->regs + offset);
 }
 
 void mtk_cec_set_hpd_event(struct device *dev,
-- 
2.18.0



From roger.lu at mediatek.com  Sun Jan  2 22:08:15 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 3 Jan 2022 14:08:15 +0800
Subject: [PATCH v16 2/7] arm64: dts: mt8183: add svs device information
In-Reply-To: <20cf2c1e-d55b-5780-8c6e-4d8beaca5a65@gmail.com>
References: <20210428065440.3704-1-roger.lu@mediatek.com>
 <20210428065440.3704-3-roger.lu@mediatek.com>
 <20cf2c1e-d55b-5780-8c6e-4d8beaca5a65@gmail.com>
Message-ID: <63e17e727d8290a5ebd8c4c5cd8f2383fc1164cc.camel@mediatek.com>

Hi Matthias,

On Thu, 2021-12-30 at 13:54 +0100, Matthias Brugger wrote:
> 
> On 28/04/2021 08:54, Roger Lu wrote:
> > add compitable/reg/irq/clock/efuse setting in svs node
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > ---
> >   arch/arm64/boot/dts/mediatek/mt8183.dtsi | 18 ++++++++++++++++++
> >   1 file changed, 18 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > index 80519a145f13..441d617ece43 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > @@ -657,6 +657,18 @@
> >   			status = "disabled";
> >   		};
> >   
> > +		svs: svs at 1100b000 {
> > +			compatible = "mediatek,mt8183-svs";
> > +			reg = <0 0x1100b000 0 0x1000>;
> > +			interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
> > +			clocks = <&infracfg CLK_INFRA_THERM>;
> > +			clock-names = "main";
> > +			nvmem-cells = <&svs_calibration>,
> > +				      <&thermal_calibration>;
> > +			nvmem-cell-names = "svs-calibration-data",
> > +					   "t-calibration-data";
> > +		};
> > +
> >   		pwm0: pwm at 1100e000 {
> >   			compatible = "mediatek,mt8183-disp-pwm";
> >   			reg = <0 0x1100e000 0 0x1000>;
> > @@ -941,9 +953,15 @@
> >   			reg = <0 0x11f10000 0 0x1000>;
> >   			#address-cells = <1>;
> >   			#size-cells = <1>;
> 
> Please add a new line between the different calibartion data, to improve 
> readability.

No problem and thanks for the review.

> Regards,
> Matthias
> 
> > +			thermal_calibration: calib at 180 {
> > +				reg = <0x180 0xc>;
> > +			};
> >   			mipi_tx_calibration: calib at 190 {
> >   				reg = <0x190 0xc>;
> >   			};
> > +			svs_calibration: calib at 580 {
> > +				reg = <0x580 0x64>;
> > +			};
> >   		};
> >   
> >   		u3phy: usb-phy at 11f40000 {
> > 



From anshuman.khandual at arm.com  Sun Jan  2 22:21:56 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon,  3 Jan 2022 11:51:56 +0530
Subject: [PATCH V2] arm64/mm/hotplug: Warn when memory limit has been reduced
Message-ID: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>

If the max memory limit has been reduced with 'mem=' kernel command line
option, there might be UEFI memory map described memory beyond that limit
which could be hot removed. This might be problematic for subsequent kexec
kernel which could just access such removed memory.

Memory offline notifier exists because there is no other way to block the
removal of boot memory, only the offlining (which isn't actually a problem)
But with 'mem=', there is no chance to stop such boot memory being offlined
as it where never in use by the kernel. As 'mem=' is a debug only option on
arm64 platform, just warn for such a situation and move on.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: James Morse <james.morse at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.16-rc8

Changes in V2:

- Moved has_mem_limit_reduced() inside hotplug notifier per Catalin
- Replaced pr_warn() with pr_warn_once() per Catalin

Changes in V1:

https://lore.kernel.org/linux-arm-kernel/1631602270-29215-1-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/include/asm/memory.h |  1 +
 arch/arm64/mm/init.c            |  9 +++++++--
 arch/arm64/mm/mmu.c             | 12 ++++++++++++
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/memory.h b/arch/arm64/include/asm/memory.h
index 1b9a1e242612..dba58cf529e4 100644
--- a/arch/arm64/include/asm/memory.h
+++ b/arch/arm64/include/asm/memory.h
@@ -354,6 +354,7 @@ static inline void *phys_to_virt(phys_addr_t x)
 })
 
 void dump_mem_limit(void);
+bool has_mem_limit_reduced(void);
 #endif /* !ASSEMBLY */
 
 /*
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index a8834434af99..4cd3b2311199 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -174,6 +174,11 @@ EXPORT_SYMBOL(pfn_is_map_memory);
 
 static phys_addr_t memory_limit = PHYS_ADDR_MAX;
 
+bool has_mem_limit_reduced(void)
+{
+	return memory_limit != PHYS_ADDR_MAX;
+}
+
 /*
  * Limit the memory size that was specified via FDT.
  */
@@ -248,7 +253,7 @@ void __init arm64_memblock_init(void)
 	 * high up in memory, add back the kernel region that must be accessible
 	 * via the linear mapping.
 	 */
-	if (memory_limit != PHYS_ADDR_MAX) {
+	if (has_mem_limit_reduced()) {
 		memblock_mem_limit_remove_map(memory_limit);
 		memblock_add(__pa_symbol(_text), (u64)(_end - _text));
 	}
@@ -422,7 +427,7 @@ void free_initmem(void)
 
 void dump_mem_limit(void)
 {
-	if (memory_limit != PHYS_ADDR_MAX) {
+	if (has_mem_limit_reduced()) {
 		pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20);
 	} else {
 		pr_emerg("Memory Limit: none\n");
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index acfae9b41cc8..9288cae136a1 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1537,6 +1537,18 @@ static int prevent_bootmem_remove_notifier(struct notifier_block *nb,
 	if ((action != MEM_GOING_OFFLINE) && (action != MEM_OFFLINE))
 		return NOTIFY_OK;
 
+	if (has_mem_limit_reduced()) {
+		/*
+		 * Physical memory limit has been reduced via the 'mem=' kernel
+		 * command line option. Memory beyond reduced limit could now be
+		 * removed and reassigned (guest ?) transparently to the kernel.
+		 * This might cause subsequent kexec kernel to crash or at least
+		 * corrupt the memory when accessing UEFI memory map enumerated
+		 * boot memory which might have been repurposed.
+		 */
+		pr_warn_once("Memory limit reduced, kexec might be problematic\n");
+	}
+
 	for (; pfn < end_pfn; pfn += PAGES_PER_SECTION) {
 		unsigned long start = PFN_PHYS(pfn);
 		unsigned long end = start + (1UL << PA_SECTION_SHIFT);
-- 
2.20.1



From roger.lu at mediatek.com  Sun Jan  2 23:44:21 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 3 Jan 2022 15:44:21 +0800
Subject: [PATCH v20 0/7] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <fff75b65-51ab-cafd-a55f-137c0b7c2dc6@gmail.com>
References: <20210721070904.15636-1-roger.lu@mediatek.com>
 <fff75b65-51ab-cafd-a55f-137c0b7c2dc6@gmail.com>
Message-ID: <8d0b14c93f98d97ed1c1147b785738baf7dfc117.camel@mediatek.com>

Hi Matthias,

On Thu, 2021-12-30 at 16:13 +0100, Matthias Brugger wrote:
> Hi Roger,
> 
> On 21/07/2021 09:08, Roger Lu wrote:
> > 1. SVS driver uses OPP adjust event in [1] to update OPP table voltage part.
> > 2. SVS driver gets thermal/GPU device by node [2][3] and CPU device by
> > get_cpu_device().
> > After retrieving subsys device, SVS driver calls device_link_add() to make
> > sure probe/suspend callback priority.
> > 3. SVS dts refers to reset controller [4] to help reset SVS HW.
> > 
> > #mt8183 SVS related patches
> > [1] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/patch/11193513/__;!!CTRNKA9wMg0ARbw!1SsvfMF2dN3uBcTxgzllNcmZ0yWfXvvAKdKlWRVgaEm69mvIZUYLBf27o_UqdhsH$
> >  
> > [2] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20201013102358.22588-2-michael.kao at mediatek.com/__;!!CTRNKA9wMg0ARbw!1SsvfMF2dN3uBcTxgzllNcmZ0yWfXvvAKdKlWRVgaEm69mvIZUYLBf27o_10UEyP$
> >  
> > [3] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20200306041345.259332-3-drinkcat at chromium.org/__;!!CTRNKA9wMg0ARbw!1SsvfMF2dN3uBcTxgzllNcmZ0yWfXvvAKdKlWRVgaEm69mvIZUYLBf27ozqhhMBj$
> >  
> > 
> 
> Comments made in v16 actually also hold for v20, so please take them into
> account :)

Sure. Thanks for the reminding :)

> 
> Regards,
> Matthias



From roger.lu at mediatek.com  Sun Jan  2 23:45:17 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 3 Jan 2022 15:45:17 +0800
Subject: [PATCH v20 5/7] dt-bindings: soc: mediatek: add mt8192 svs
 dt-bindings
In-Reply-To: <98efb356-dc0d-fa7e-5579-7984f2bb3e84@gmail.com>
References: <20210721070904.15636-1-roger.lu@mediatek.com>
 <20210721070904.15636-6-roger.lu@mediatek.com>
 <98efb356-dc0d-fa7e-5579-7984f2bb3e84@gmail.com>
Message-ID: <28bc9c8ba962e09e321db3149c1196edefe4e856.camel@mediatek.com>

Hi Matthias,


On Thu, 2021-12-30 at 16:30 +0100, Matthias Brugger wrote:
> Please add a commit message.

Sure, I'll add it in the next version. Thanks.

> 
> Regards,
> Matthias
> 
> On 21/07/2021 09:09, Roger Lu wrote:
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > Reviewed-by: Rob Herring <robh at kernel.org>
> > ---
> >   .../devicetree/bindings/soc/mediatek/mtk-svs.yaml         | 8 ++++++++
> >   1 file changed, 8 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
> > b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
> > index a855ced410f8..59342e627b67 100644
> > --- a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
> > +++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
> > @@ -22,6 +22,7 @@ properties:
> >     compatible:
> >       enum:
> >         - mediatek,mt8183-svs
> > +      - mediatek,mt8192-svs
> >   
> >     reg:
> >       maxItems: 1
> > @@ -51,6 +52,13 @@ properties:
> >         - const: svs-calibration-data
> >         - const: t-calibration-data
> >   
> > +  resets:
> > +    maxItems: 1
> > +
> > +  reset-names:
> > +    items:
> > +      - const: svs_rst
> > +
> >   required:
> >     - compatible
> >     - reg
> > 



From avolmat at me.com  Sun Jan  2 23:47:26 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:26 +0100
Subject: [PATCH RESEND v2 0/5] Introduction of PCIe support on STi platform
Message-ID: <20220103074731.3651-1-avolmat@me.com>

The STi platform SoC embed a designware based PCIe controller.
This serie include the driver for the controller and DT for the
stih407-family and for the stih418-b2264 into which it is used.

Within the DT and the binding, only st,stih407-pcie compatible is
used.
Rob, could you clarify if I need to mention both compatible (st,stih407-pcie
and snps,dw-pcie) or if st,stih407-pcie is enought ?

RESEND since not all patches made their way to the mailing list on
previous attempt.

v2: update of the pcie-st driver to add possibility to build as module
    and remove the __init of the probe

Alain Volmat (5):
  dt-bindings: pci: st-pcie: PCIe controller found on STi platforms
  pci: dwc: pcie-st: Add PCIe driver for STi platforms
  MAINTAINERS: add entry for ST STI PCIE driver
  ARM: dts: sti: add the PCIe controller node within stih407-family
  ARM: dts: sti: enable PCIe on the stih418-b2264 board

 .../devicetree/bindings/pci/snps,dw-pcie.yaml |   2 +-
 .../devicetree/bindings/pci/st,st-pcie.yaml   | 112 +++++
 MAINTAINERS                                   |   6 +
 arch/arm/boot/dts/stih407-family.dtsi         |  40 ++
 arch/arm/boot/dts/stih418-b2264.dts           |   5 +
 drivers/pci/controller/dwc/Kconfig            |  11 +
 drivers/pci/controller/dwc/Makefile           |   1 +
 drivers/pci/controller/dwc/pcie-sti.c         | 386 ++++++++++++++++++
 8 files changed, 562 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/st,st-pcie.yaml
 create mode 100644 drivers/pci/controller/dwc/pcie-sti.c

-- 
2.25.1



From avolmat at me.com  Sun Jan  2 23:47:27 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:27 +0100
Subject: [PATCH RESEND v2 1/5] dt-bindings: pci: st-pcie: PCIe controller
 found on STi platforms
In-Reply-To: <20220103074731.3651-1-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
Message-ID: <20220103074731.3651-2-avolmat@me.com>

Addition of the bindings for the Designware based PCIe controller
that can be found on STi platforms such as STiH407, STiH410 or STiH418.

Signed-off-by: Alain Volmat <avolmat at me.com>
---
 .../devicetree/bindings/pci/snps,dw-pcie.yaml |   2 +-
 .../devicetree/bindings/pci/st,st-pcie.yaml   | 112 ++++++++++++++++++
 2 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/pci/st,st-pcie.yaml

diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
index 9ed0dfba7f89..3a92078128f7 100644
--- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
@@ -35,7 +35,7 @@ properties:
     maxItems: 5
     items:
       enum: [ dbi, dbi2, config, atu, app, elbi, mgmt, ctrl, parf, cfg, link,
-              ulreg, smu, mpu, apb, phy ]
+              ulreg, smu, mpu, apb, phy, mem-window ]
 
   num-lanes:
     description: |
diff --git a/Documentation/devicetree/bindings/pci/st,st-pcie.yaml b/Documentation/devicetree/bindings/pci/st,st-pcie.yaml
new file mode 100644
index 000000000000..2fa686d573c3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pci/st,st-pcie.yaml
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pci/st,st-pcie.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: PCIe RC controller on ST STi platform
+
+maintainers:
+  - Alain Volmat <avolmat at me.com>
+
+allOf:
+  - $ref: /schemas/pci/snps,dw-pcie.yaml#
+
+properties:
+  compatible:
+    const: st,stih407-pcie
+
+  reg:
+    items:
+      - description: Controller control and status registers.
+      - description: PCIe configuration registers.
+      - description: Memory made available to the controller
+
+  reg-names:
+    items:
+      - const: dbi
+      - const: config
+      - const: mem-window
+
+  interrupts:
+    maxItems: 1
+
+  resets:
+    items:
+    - description: Controller reset
+    - description: Powerdown reset (optional)
+    minItems: 1
+
+  reset-names:
+    items:
+      - const: softreset
+      - const: powerdown
+    minItems: 1
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: pcie
+
+  reset-gpios: true
+
+  st,syscfg:
+    $ref: "/schemas/types.yaml#/definitions/phandle-array"
+    description: syscfg node phandle and offsets of the 2 registers
+                 controlling root complex and ltssm.
+
+required:
+  - interrupts
+  - '#interrupt-cells'
+  - interrupt-map
+  - interrupt-map-mask
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/phy/phy.h>
+    #include <dt-bindings/reset/stih407-resets.h>
+    pcie1: pcie at 9b10000 {
+      compatible = "st,stih407-pcie";
+      device_type = "pci";
+      #address-cells = <3>;
+      #size-cells = <2>;
+      reg = <0x09b10000 0x1000>,
+            <0x3fff0000 0x10000>,
+            <0x40000000 0xc0000000>;
+      reg-names = "dbi", "config", "mem-window";
+
+      #interrupt-cells = <1>;
+      interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+      interrupt-names = "msi";
+      interrupt-map-mask = <0 0 0 7>;
+      interrupt-map = <0 0 0 1 &intc GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+                      <0 0 0 2 &intc GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
+                      <0 0 0 3 &intc GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+                      <0 0 0 4 &intc GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+      st,syscfg = <&syscfg_core 0xdc 0xe4>;
+
+      ranges = <0x82000000 0 0x30000000 0x30000000 0 0x05550000>, /* non-prefetchable memory */
+               <0xc2000000 0 0x35550000 0x35550000 0 0x0AAA0000>; /* prefetchable memory */
+      bus-range = <0x00 0xff>;
+
+      resets = <&softreset STIH407_PCIE1_SOFTRESET>,
+               <&powerdown STIH407_PCIE1_POWERDOWN>;
+
+      reset-names = "softreset", "powerdown";
+
+      phys = <&phy_port1 PHY_TYPE_PCIE>;
+      phy-names = "pcie";
+
+      reset-gpios = <&pio34 5 GPIO_ACTIVE_LOW>;
+    };
-- 
2.25.1



From avolmat at me.com  Sun Jan  2 23:47:28 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:28 +0100
Subject: [PATCH RESEND v2 2/5] pci: dwc: pcie-st: Add PCIe driver for STi
 platforms
In-Reply-To: <20220103074731.3651-1-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
Message-ID: <20220103074731.3651-3-avolmat@me.com>

Addition of the PCIe driver (supporting RC) for controllers
found on some STi platforms such as STiH407, STiH410 or
STiH418.
The controller is based on the designware PCIe controller.

Signed-off-by: Alain Volmat <avolmat at me.com>
---
v2: update of the pcie-st driver to add possibility to build as module
    and remove the __init of the probe

 drivers/pci/controller/dwc/Kconfig    |  11 +
 drivers/pci/controller/dwc/Makefile   |   1 +
 drivers/pci/controller/dwc/pcie-sti.c | 386 ++++++++++++++++++++++++++
 3 files changed, 398 insertions(+)
 create mode 100644 drivers/pci/controller/dwc/pcie-sti.c

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index 62ce3abf0f19..232b8ffd54af 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -384,4 +384,15 @@ config PCIE_FU740
 	  Say Y here if you want PCIe controller support for the SiFive
 	  FU740.
 
+config PCIE_STI
+	tristate "STMicroelectronics PCIe Controller for STi SoCs"
+	depends on ARCH_STI || COMPILE_TEST
+	depends on OF && PCI_MSI_IRQ_DOMAIN
+	select PCIE_DW_HOST
+	help
+	  Enable PCIe controller support on STMicroelectronics STi SoCs.
+	  This controller is based on Designware hardware and therefore
+	  the driver re-uses the Designware core functions to implement
+	  the driver.
+
 endmenu
diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
index 8ba7b67f5e50..c98fa18714ce 100644
--- a/drivers/pci/controller/dwc/Makefile
+++ b/drivers/pci/controller/dwc/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PCIE_KEEMBAY) += pcie-keembay.o
 obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
 obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
 obj-$(CONFIG_PCI_MESON) += pci-meson.o
+obj-$(CONFIG_PCIE_STI) += pcie-sti.o
 obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
 obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
 obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
diff --git a/drivers/pci/controller/dwc/pcie-sti.c b/drivers/pci/controller/dwc/pcie-sti.c
new file mode 100644
index 000000000000..61da00a079ac
--- /dev/null
+++ b/drivers/pci/controller/dwc/pcie-sti.c
@@ -0,0 +1,386 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 STMicroelectronics
+ *
+ * STMicroelectronics PCI express Driver for STi SoCs.
+ * ST PCIe IPs are built around a Synopsys IP Core.
+ *
+ * Authors: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
+ *          Alain Volmat <avolmat at me.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+
+#include "pcie-designware.h"
+
+/* RC_ADDRESS_TRANSLATION Registers */
+#define TRANSLATION_CONTROL		0x900
+/* Controls if area is inclusive or exclusive */
+#define RC_PASS_ADDR_RANGE		BIT(1)
+
+/* Base of area reserved for config accesses. Fixed size of 64K. */
+#define CFG_BASE_ADDRESS		0x92c
+#define CFG_REGION_SIZE			65536
+#define CFG_SPACE1_OFFSET		0x1000
+
+/* First 4K of config space has this BDF (bus,device,function) */
+#define FUNC0_BDF_NUM			0x930
+
+/* Mem regions */
+#define IN0_MEM_ADDR_START		0x964
+#define IN0_MEM_ADDR_LIMIT		0x968
+#define IN1_MEM_ADDR_START		0x974
+#define IN1_MEM_ADDR_LIMIT		0x978
+
+/* syscfg1 bits */
+#define PCIE_APP_LTSSM_ENABLE		BIT(2)
+/* syscfg0 bits */
+#define PCIE_TYPE_ROOT_COMPLEX		BIT(0)
+
+/* st,syscfg offsets */
+#define SYSCFG0_REG	1
+#define SYSCFG1_REG	2
+
+#define to_st_pcie(x)	dev_get_drvdata((x)->dev)
+
+/**
+ * struct st_pcie - private data of the controller
+ * @dw: designware pcie
+ * @syscfg0: PCIe conf register setting root complex, regmap offset
+ * @syscfg1: PCIe conf register for PCIE_APP_LTSSM_ENABLE, regmap offset
+ * @phy: associated pcie phy
+ * @lmi: memory made available to the controller
+ * @regmap: Syscfg registers bank in which PCIe port is configured
+ * @pwr: power control
+ * @rst: reset control
+ * @reset_gpio: optional reset gpio
+ * @config_window_start: start address of 64K config space area
+ */
+struct st_pcie {
+	struct dw_pcie *dw;
+	int syscfg0;
+	int syscfg1;
+	struct phy *phy;
+	struct resource	*lmi;
+	struct regmap *regmap;
+	struct reset_control *pwr;
+	struct reset_control *rst;
+	struct gpio_desc *reset_gpio;
+	phys_addr_t config_window_start;
+};
+
+/*
+ * The PCI express core IP expects the following arrangement on it's address
+ * bus (slv_haddr) when driving config cycles.
+ * bus_number		[31:24]
+ * dev_number		[23:19]
+ * func_number		[18:16]
+ * unused		[15:12]
+ * ext_reg_number	[11:8]
+ * reg_number		[7:2]
+ *
+ * Bits [15:12] are unused.
+ *
+ * In the glue logic there is a 64K region of address space that can be
+ * written/read to generate config cycles. The base address of this is
+ * controlled by CFG_BASE_ADDRESS. There are 8 16 bit registers called
+ * FUNC0_BDF_NUM to FUNC8_BDF_NUM. These split the bottom half of the 64K
+ * window into 8 regions at 4K boundaries. These control the bus, device and
+ * function number you are trying to talk to.
+ *
+ * The decision on whether to generate a type 0 or type 1 access is controlled
+ * by bits 15:12 of the address you write to.  If they are zero, then a type 0
+ * is generated, if anything else it will be a type 1. Thus the bottom 4K
+ * region controlled by FUNC0_BDF_NUM can only generate type 0, all the others
+ * can only generate type 1.
+ *
+ * We only use FUNC0_BDF_NUM and FUNC1_BDF_NUM. Which one you use is selected
+ * by bit 12 of the address you write to. The selected register is then used
+ * for the top 16 bits of the slv_haddr to form the bus/dev/func, bit 15:12 are
+ * wired to zero, and bits 11:2 form the address of the register you want to
+ * read in config space.
+ *
+ * We always write FUNC0_BDF_NUM as a 32 bit write. So if we want type 1
+ * accesses we have to shift by 16 so in effect we are writing to FUNC1_BDF_NUM
+ */
+static inline u32 bdf_num(int bus, int devfn, int is_root_bus)
+{
+	return ((bus << 8) | devfn) << (is_root_bus ? 0 : 16);
+}
+
+static void __iomem *st_pcie_other_map_bus(struct pci_bus *bus, unsigned int devfn, int where)
+{
+	struct pcie_port *pp = bus->sysdata;
+	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
+	u32 bdf;
+
+	bdf = bdf_num(bus->number, devfn, pci_is_root_bus(bus));
+
+	/* Set the config packet devfn */
+	dw_pcie_writel_dbi(dw, FUNC0_BDF_NUM, bdf);
+	dw_pcie_readl_dbi(dw, FUNC0_BDF_NUM);
+
+	return pp->va_cfg0_base + where + (pci_is_root_bus(bus->parent) ? 0 : CFG_SPACE1_OFFSET);
+}
+
+static struct pci_ops st_child_pcie_ops = {
+	.map_bus = st_pcie_other_map_bus,
+	.read = pci_generic_config_read,
+	.write = pci_generic_config_write,
+};
+
+static void st_pcie_hw_setup(struct dw_pcie *dw)
+{
+	struct st_pcie *pcie = to_st_pcie(dw);
+
+	/* Set up the config window to the top of the PCI address space */
+	dw_pcie_writel_dbi(dw, CFG_BASE_ADDRESS, pcie->config_window_start);
+
+	/*
+	 * Open up memory to the PCI controller. We could do slightly
+	 * better than this and exclude the kernel text segment and bss etc.
+	 * They are base/limit registers so can be of arbitrary alignment
+	 * presumably
+	 */
+	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_START, pcie->lmi->start);
+	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_LIMIT, pcie->lmi->end);
+
+	/* Disable the 2nd region */
+	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_START, ~0);
+	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_LIMIT, 0);
+
+	dw_pcie_writel_dbi(dw, TRANSLATION_CONTROL, RC_PASS_ADDR_RANGE);
+}
+
+static int st_pcie_init(struct pcie_port *pp)
+{
+	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
+	struct st_pcie *pcie = to_st_pcie(dw);
+	int ret;
+
+	/* Set device type : Root Complex */
+	ret = regmap_write(pcie->regmap, pcie->syscfg0, PCIE_TYPE_ROOT_COMPLEX);
+	if (ret < 0) {
+		dev_err(dw->dev, "unable to set device type\n");
+		return ret;
+	}
+
+	ret = reset_control_deassert(pcie->pwr);
+	if (ret) {
+		dev_err(dw->dev, "unable to bring out of powerdown\n");
+		return ret;
+	}
+
+	ret = reset_control_deassert(pcie->rst);
+	if (ret) {
+		dev_err(dw->dev, "unable to bring out of softreset\n");
+		return ret;
+	}
+
+	/* let the controller initialize in the proper mode (RC) after reset */
+	usleep_range(1000, 2000);
+
+	return ret;
+}
+
+static int st_pcie_control_ltssm(struct dw_pcie *dw, bool enable)
+{
+	struct st_pcie *pcie = to_st_pcie(dw);
+
+	return regmap_update_bits(pcie->regmap, pcie->syscfg1, PCIE_APP_LTSSM_ENABLE,
+				  FIELD_PREP(PCIE_APP_LTSSM_ENABLE, enable));
+}
+
+static int st_pcie_host_init(struct pcie_port *pp)
+{
+	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
+	struct st_pcie *pcie = to_st_pcie(dw);
+	int err;
+
+	pcie->config_window_start = pp->cfg0_base;
+
+	/*
+	 * "Override" default ops provided by designware driver as STI
+	 * PCIe uses its own translation unit rather than iATU
+	 */
+	pp->bridge->child_ops = &st_child_pcie_ops;
+
+	/*
+	 * We have to initialise the PCIe cell on some hardware before we can
+	 * talk to the phy
+	 */
+	err = st_pcie_init(pp);
+	if (err)
+		return err;
+
+	err = st_pcie_control_ltssm(dw, false);
+	if (err) {
+		dev_err(dw->dev, "disable ltssm failed, %d\n", err);
+		return err;
+	}
+
+	/* Init the associated miphy */
+	err = phy_init(pcie->phy);
+	if (err < 0) {
+		dev_err(dw->dev, "Cannot init PHY: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int st_pcie_start_link(struct dw_pcie *dw)
+{
+	struct st_pcie *pcie = to_st_pcie(dw);
+	int err;
+
+	/* Do all the register poking */
+	st_pcie_hw_setup(dw);
+
+	if (pcie->reset_gpio) {
+		/* Assert the PERST# signal */
+		gpiod_set_value(pcie->reset_gpio, 1);
+
+		/* PERST# signal must stay asserted for at least 100us (Tperst-clk) */
+		usleep_range(100, 200);
+
+		/* Release PERST# signal */
+		gpiod_set_value(pcie->reset_gpio, 0);
+	}
+
+	/* Re-enable the link, link training must begin shortly after reset */
+	err = st_pcie_control_ltssm(dw, true);
+	if (err) {
+		dev_err(dw->dev, "enable ltssm failed, %d\n", err);
+		return err;
+	}
+
+	err = dw_pcie_wait_for_link(dw);
+	if (err) {
+		dev_err(dw->dev, "wait for link failed, %d\n", err);
+		return err;
+	}
+
+	/*
+	 * PCIe specification states that you should not issue any config
+	 * requests until 100ms after asserting reset, so we enforce that here
+	 */
+	if  (pcie->reset_gpio)
+		msleep(100);
+
+	return 0;
+}
+
+static struct dw_pcie_host_ops st_pcie_host_ops = {
+	.host_init = st_pcie_host_init,
+};
+
+static const struct dw_pcie_ops dw_pcie_ops = {
+	.start_link = st_pcie_start_link,
+};
+
+static int st_pcie_probe(struct platform_device *pdev)
+{
+	struct st_pcie *pcie;
+	struct dw_pcie *dw;
+	struct device_node *np = pdev->dev.of_node;
+	struct pcie_port *pp;
+	int ret;
+
+	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
+	if (!pcie)
+		return -ENOMEM;
+
+	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
+	if (!dw)
+		return -ENOMEM;
+	pcie->dw = dw;
+	dw->dev = &pdev->dev;
+	dw->ops = &dw_pcie_ops;
+
+	pp = &dw->pp;
+	pp->ops = &st_pcie_host_ops;
+
+	/* mem regions */
+	pcie->lmi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem-window");
+	if (!pcie->lmi)
+		return -ENXIO;
+
+	/* regmap registers for PCIe IP configuration */
+	pcie->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (IS_ERR(pcie->regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->regmap),
+				     "No syscfg phandle specified\n");
+
+	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG0_REG, &pcie->syscfg0);
+	if (ret) {
+		dev_err(&pdev->dev, "can't get syscfg0 offset (%d)\n", ret);
+		return ret;
+	}
+
+	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG1_REG, &pcie->syscfg1);
+	if (ret) {
+		dev_err(&pdev->dev, "can't get syscfg1 offset (%d)\n", ret);
+		return ret;
+	}
+
+	/* powerdown / resets */
+	pcie->pwr = devm_reset_control_get_optional(&pdev->dev, "powerdown");
+	if (IS_ERR(pcie->pwr))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->pwr),
+				     "Error getting powerdown reset control\n");
+
+	pcie->rst = devm_reset_control_get(&pdev->dev, "softreset");
+	if (IS_ERR(pcie->rst))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->rst),
+				     "Error getting softreset control\n");
+
+	/* phy */
+	pcie->phy = devm_phy_get(&pdev->dev, "pcie");
+	if (IS_ERR(pcie->phy))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy), "no PHY configured\n");
+
+	/* Claim the GPIO for PRST# if available, keep it de-asserted */
+	pcie->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(pcie->reset_gpio))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reset_gpio),
+				     "Cannot request reset-gpios\n");
+
+	platform_set_drvdata(pdev, pcie);
+
+	ret = dw_pcie_host_init(pp);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to initialize host\n");
+
+	return 0;
+}
+
+static const struct of_device_id st_pcie_of_match[] = {
+	{ .compatible = "st,stih407-pcie", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, st_pcie_of_match);
+
+static struct platform_driver st_pcie_driver __refdata = {
+	.probe  = st_pcie_probe,
+	.driver = {
+		.name = "st-pcie",
+		.of_match_table = st_pcie_of_match,
+	},
+};
+module_platform_driver(st_pcie_driver);
+
+MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier at foss.st.com>");
+MODULE_AUTHOR("Alain Volmat <avolmat at me.com>");
+MODULE_DESCRIPTION("STi PCIe Controller driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From avolmat at me.com  Sun Jan  2 23:47:29 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:29 +0100
Subject: [PATCH RESEND v2 3/5] MAINTAINERS: add entry for ST STI PCIE driver
In-Reply-To: <20220103074731.3651-1-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
Message-ID: <20220103074731.3651-4-avolmat@me.com>

Add PCIE Driver entry for STI family from ST Microelectronics.

Signed-off-by: Alain Volmat <avolmat at me.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 360e9aa0205d..081ccdfbd89c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14666,6 +14666,12 @@ L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
 F:	drivers/pci/controller/dwc/pci-exynos.c
 
+PCI DRIVER FOR ST STI PLATFORM
+M:	Alain Volmat <avolmat at me.com>
+L:	linux-pci at vger.kernel.org
+S:	Maintained
+F:	drivers/pci/controller/dwc/pcie-sti.c
+
 PCI DRIVER FOR SYNOPSYS DESIGNWARE
 M:	Jingoo Han <jingoohan1 at gmail.com>
 M:	Gustavo Pimentel <gustavo.pimentel at synopsys.com>
-- 
2.25.1



From avolmat at me.com  Sun Jan  2 23:47:30 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:30 +0100
Subject: [PATCH RESEND v2 4/5] ARM: dts: sti: add the PCIe controller node
 within stih407-family
In-Reply-To: <20220103074731.3651-1-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
Message-ID: <20220103074731.3651-5-avolmat@me.com>

Add the pcie1 entry within stih407-family dtsi.

Signed-off-by: Alain Volmat <avolmat at me.com>
---
 arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
index 21f3347a91d6..fe4ea2d5b583 100644
--- a/arch/arm/boot/dts/stih407-family.dtsi
+++ b/arch/arm/boot/dts/stih407-family.dtsi
@@ -631,6 +631,46 @@ spifsm: spifsm at 9022000{
 			status = "disabled";
 		};
 
+		pcie1: pcie at 9b10000 {
+			compatible = "st,stih407-pcie";
+			device_type = "pci";
+			reg = <0x09b10000 0x00001000>,	/* cntrl registers */
+			      <0x3fff0000 0x00010000>,	/* config space */
+			      <0x40000000 0xc0000000>;	/* lmi mem window */
+
+			reg-names = "dbi",
+				    "config",
+				    "mem-window";
+
+			st,syscfg = <&syscfg_core 0xdc 0xe4>;
+
+			#interrupt-cells = <1>;
+			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-map = <0 0 0 1 &intc GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			/* non-prefetchable and prefetchable */
+			ranges = <0x82000000 0 0x30000000 0x30000000 0 0x05550000>,
+				 <0xc2000000 0 0x35550000 0x35550000 0 0x0AAA0000>;
+			bus-range = <0x00 0xff>;
+
+			resets = <&softreset STIH407_PCIE1_SOFTRESET>,
+				 <&powerdown STIH407_PCIE1_POWERDOWN>;
+
+			reset-names = "softreset", "powerdown";
+
+			phys = <&phy_port1 PHY_TYPE_PCIE>;
+			phy-names = "pcie";
+
+			status = "disabled";
+		};
+
 		sata0: sata at 9b20000 {
 			compatible = "st,ahci";
 			reg = <0x9b20000 0x1000>;
-- 
2.25.1



From avolmat at me.com  Sun Jan  2 23:47:31 2022
From: avolmat at me.com (Alain Volmat)
Date: Mon,  3 Jan 2022 08:47:31 +0100
Subject: [PATCH RESEND v2 5/5] ARM: dts: sti: enable PCIe on the stih418-b2264
 board
In-Reply-To: <20220103074731.3651-1-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
Message-ID: <20220103074731.3651-6-avolmat@me.com>

Enable the PCIe controller with proper reset gpio pin for this board.

Signed-off-by: Alain Volmat <avolmat at me.com>
---
 arch/arm/boot/dts/stih418-b2264.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/stih418-b2264.dts b/arch/arm/boot/dts/stih418-b2264.dts
index a99604bebf8c..ed183292a669 100644
--- a/arch/arm/boot/dts/stih418-b2264.dts
+++ b/arch/arm/boot/dts/stih418-b2264.dts
@@ -130,6 +130,11 @@ &ohci1 {
 	status = "okay";
 };
 
+&pcie1 {
+	reset-gpios = <&pio34 5 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
+
 &pwm1 {
 	status = "okay";
 };
-- 
2.25.1



From roger.lu at mediatek.com  Sun Jan  2 23:43:28 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 3 Jan 2022 15:43:28 +0800
Subject: [PATCH v16 0/7] soc: mediatek: SVS: introduce MTK SVS
In-Reply-To: <abd9332b-dace-f75a-33f5-be88fe516784@gmail.com>
References: <20210428065440.3704-1-roger.lu@mediatek.com>
 <abd9332b-dace-f75a-33f5-be88fe516784@gmail.com>
Message-ID: <ca8e8e62d4c7d9b714c64fbf9e59ba0ebe42bea4.camel@mediatek.com>

Hi Matthias,

On Thu, 2021-12-30 at 14:18 +0100, Matthias Brugger wrote:
> 
> On 28/04/2021 08:54, Roger Lu wrote:
> > 1. SVS driver uses OPP adjust event in [1] to update OPP table voltage part.
> > 2. SVS driver gets thermal/GPU device by node [2][3] and CPU device by
> > get_cpu_device().
> > After retrieving subsys device, SVS driver calls device_link_add() to make
> > sure probe/suspend callback priority.
> > 3. SVS dts refers to reset controller [4] to help reset SVS HW.
> > 
> > #mt8183 SVS related patches
> > [1] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/patch/11193513/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MIscKXW-$
> >  
> 
> Already mainline, please either refer to the commit, to make it clear it's 
> maineline or drop it.
> 
> > [2] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20201013102358.22588-2-michael.kao at mediatek.com/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3ML35Ale5$
> >  
> 
> Same here.
> 
> > [3] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20200306041345.259332-3-drinkcat at chromium.org/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MMUMr7Oh$
> >  
> 
> Same here,

Thanks for the review. I'll refer to mainline or the latest reviewing patch. 

> 
> > 
> > #mt8192 SVS related patches
> > [1] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/patch/11193513/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MIscKXW-$
> >  
> 
> Same here, it's actually the same link as [1].
> 
> > [2] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20201223074944.2061-1-michael.kao at mediatek.com/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MEUxFEDM$
> >  
> > [3] 
> > https://urldefense.com/v3/__https://lore.kernel.org/patchwork/patch/1360551/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MNObUeLt$
> >  
> > [4] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20200817030324.5690-5-crystal.guo at mediatek.com/__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MMx-JKoe$
> >  
> 
> There are many dependencies for that. Some patches need resubmit, others seem
> to 
> be stale. I'd advise to concentrate on mt8183 for now and add support for
> mt8192 
> once dependencies have settled.

Sure, let's concentrate on mt8183 patches first. Thanks for sharing the advice.

> 
> Regards,
> Matthias
> 
> > 
> > changes since v15:
> > - Put (*set_freqs_pct) and (*get_vops) in struct svs_bank because they are
> > part of svs bank's operation
> > - Add define "SVSB_INIT02_RM_DVTFIXED" and "SVSB_MON_VOLT_IGNORE" to make
> > control clearly.
> > - Remove unnecessary parenthesis
> > 
> > Roger Lu (7):
> >    [v16,1/7] dt-bindings: soc: mediatek: add mtk svs dt-bindings
> >    [v16,2/7] arm64: dts: mt8183: add svs device information
> >    [v16,3/7] soc: mediatek: SVS: introduce MTK SVS engine
> >    [v16,4/7] soc: mediatek: SVS: add debug commands
> >    [v16,5/7] dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
> >    [v16,6/7] arm64: dts: mt8192: add svs device information
> >    [v16,7/7] soc: mediatek: SVS: add mt8192 SVS GPU driver
> > 
> >   .../bindings/soc/mediatek/mtk-svs.yaml        |   92 +
> >   arch/arm64/boot/dts/mediatek/mt8183.dtsi      |   18 +
> >   arch/arm64/boot/dts/mediatek/mt8192.dtsi      |   34 +
> >   drivers/soc/mediatek/Kconfig                  |   10 +
> >   drivers/soc/mediatek/Makefile                 |    1 +
> >   drivers/soc/mediatek/mtk-svs.c                | 2524 +++++++++++++++++
> >   6 files changed, 2679 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-
> > svs.yaml
> >   create mode 100644 drivers/soc/mediatek/mtk-svs.c
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > 
https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!yy2e7JqE__BQAZF3jwBuR3Fbzbv8LPxwwA3l6SVu7SFAG94dCHyVq9A3MIj4Pohu$
> >  
> > 



From allen-kh.cheng at mediatek.com  Sun Jan  2 23:58:54 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 3 Jan 2022 15:58:54 +0800
Subject: [PATCH 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>
References: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220103075854.10438-2-allen-kh.cheng@mediatek.com>

Add SCP support for mt8186

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
---
 drivers/remoteproc/mtk_scp.c | 39 ++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..38eab6b86fd7 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -365,6 +365,31 @@ static int mt8183_scp_before_load(struct mtk_scp *scp)
 	return 0;
 }
 
+static int mt8186_scp_before_load(struct mtk_scp *scp)
+{
+	int i;
+
+	/* Clear SCP to host interrupt */
+	writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+	/* Reset clocks before loading FW */
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+	/* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
+	for (i = 31; i >= 0; i--)
+		writel(GENMASK(i, 0), scp->reg_base + MT8183_SCP_SRAM_PDN);
+	writel(0, scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+	/* Initialize TCM before loading FW. */
+	writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2);
+
+	return 0;
+}
+
 static void mt8192_power_on_sram(void __iomem *addr)
 {
 	int i;
@@ -887,6 +912,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 	.ipi_buf_offset = 0x7bdb0,
 };
 
+static const struct mtk_scp_of_data mt8186_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
+	.scp_before_load = mt8186_scp_before_load,
+	.scp_irq_handler = mt8183_scp_irq_handler,
+	.scp_reset_assert = mt8183_scp_reset_assert,
+	.scp_reset_deassert = mt8183_scp_reset_deassert,
+	.scp_stop = mt8183_scp_stop,
+	.scp_da_to_va = mt8183_scp_da_to_va,
+	.host_to_scp_reg = MT8183_HOST_TO_SCP,
+	.host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT,
+	.ipi_buf_offset = 0x7bdb0,
+};
+
 static const struct mtk_scp_of_data mt8192_of_data = {
 	.scp_clk_get = mt8192_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
@@ -913,6 +951,7 @@ static const struct mtk_scp_of_data mt8195_of_data = {
 
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
+	{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
 	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Sun Jan  2 23:58:53 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 3 Jan 2022 15:58:53 +0800
Subject: [PATCH 1/2] dt-bindings: remoteproc: mediatek: Add binding for mt8186
 scp
Message-ID: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>

Add mt8186 compatible to binding document.

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index d21a25ee96e6..5b693a2d049c 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-scp
+      - mediatek,mt8186-scp
       - mediatek,mt8192-scp
       - mediatek,mt8195-scp
 
-- 
2.18.0



From michal.simek at xilinx.com  Mon Jan  3 00:39:34 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 3 Jan 2022 09:39:34 +0100
Subject: [PATCH v2 22/23] PCI: xilinx: Rename xilinx_pcie_port to
 xilinx_pcie
In-Reply-To: <20211223011054.1227810-23-helgaas@kernel.org>
References: <20211223011054.1227810-1-helgaas@kernel.org>
 <20211223011054.1227810-23-helgaas@kernel.org>
Message-ID: <51acdf9e-94a8-6cd0-0265-b96af35712a5@xilinx.com>



On 12/23/21 02:10, Bjorn Helgaas wrote:
> From: Fan Fei <ffclaire1224 at gmail.com>
> 
> Rename struct xilinx_pcie_port to xilinx_pcie to match the convention of
> <driver>_pcie. No functional change intended.
> 
> Signed-off-by: Fan Fei <ffclaire1224 at gmail.com>
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Michal Simek <michal.simek at xilinx.com>
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/pci/controller/pcie-xilinx.c | 158 +++++++++++++--------------
>   1 file changed, 79 insertions(+), 79 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c
> index aa9bdcebc838..cb6e9f7b0152 100644
> --- a/drivers/pci/controller/pcie-xilinx.c
> +++ b/drivers/pci/controller/pcie-xilinx.c
> @@ -91,18 +91,18 @@
>   #define XILINX_NUM_MSI_IRQS		128
>   
>   /**
> - * struct xilinx_pcie_port - PCIe port information
> - * @reg_base: IO Mapped Register Base
> + * struct xilinx_pcie - PCIe port information
>    * @dev: Device pointer
> + * @reg_base: IO Mapped Register Base
>    * @msi_map: Bitmap of allocated MSIs
>    * @map_lock: Mutex protecting the MSI allocation
>    * @msi_domain: MSI IRQ domain pointer
>    * @leg_domain: Legacy IRQ domain pointer
>    * @resources: Bus Resources
>    */
> -struct xilinx_pcie_port {
> -	void __iomem *reg_base;
> +struct xilinx_pcie {
>   	struct device *dev;
> +	void __iomem *reg_base;
>   	unsigned long msi_map[BITS_TO_LONGS(XILINX_NUM_MSI_IRQS)];
>   	struct mutex map_lock;
>   	struct irq_domain *msi_domain;
> @@ -110,35 +110,35 @@ struct xilinx_pcie_port {
>   	struct list_head resources;
>   };
>   
> -static inline u32 pcie_read(struct xilinx_pcie_port *port, u32 reg)
> +static inline u32 pcie_read(struct xilinx_pcie *pcie, u32 reg)
>   {
> -	return readl(port->reg_base + reg);
> +	return readl(pcie->reg_base + reg);
>   }
>   
> -static inline void pcie_write(struct xilinx_pcie_port *port, u32 val, u32 reg)
> +static inline void pcie_write(struct xilinx_pcie *pcie, u32 val, u32 reg)
>   {
> -	writel(val, port->reg_base + reg);
> +	writel(val, pcie->reg_base + reg);
>   }
>   
> -static inline bool xilinx_pcie_link_up(struct xilinx_pcie_port *port)
> +static inline bool xilinx_pcie_link_up(struct xilinx_pcie *pcie)
>   {
> -	return (pcie_read(port, XILINX_PCIE_REG_PSCR) &
> +	return (pcie_read(pcie, XILINX_PCIE_REG_PSCR) &
>   		XILINX_PCIE_REG_PSCR_LNKUP) ? 1 : 0;
>   }
>   
>   /**
>    * xilinx_pcie_clear_err_interrupts - Clear Error Interrupts
> - * @port: PCIe port information
> + * @pcie: PCIe port information
>    */
> -static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port)
> +static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie *pcie)
>   {
> -	struct device *dev = port->dev;
> -	unsigned long val = pcie_read(port, XILINX_PCIE_REG_RPEFR);
> +	struct device *dev = pcie->dev;
> +	unsigned long val = pcie_read(pcie, XILINX_PCIE_REG_RPEFR);
>   
>   	if (val & XILINX_PCIE_RPEFR_ERR_VALID) {
>   		dev_dbg(dev, "Requester ID %lu\n",
>   			val & XILINX_PCIE_RPEFR_REQ_ID);
> -		pcie_write(port, XILINX_PCIE_RPEFR_ALL_MASK,
> +		pcie_write(pcie, XILINX_PCIE_RPEFR_ALL_MASK,
>   			   XILINX_PCIE_REG_RPEFR);
>   	}
>   }
> @@ -152,11 +152,11 @@ static void xilinx_pcie_clear_err_interrupts(struct xilinx_pcie_port *port)
>    */
>   static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
>   {
> -	struct xilinx_pcie_port *port = bus->sysdata;
> +	struct xilinx_pcie *pcie = bus->sysdata;
>   
> -	/* Check if link is up when trying to access downstream ports */
> +	/* Check if link is up when trying to access downstream pcie ports */
>   	if (!pci_is_root_bus(bus)) {
> -		if (!xilinx_pcie_link_up(port))
> +		if (!xilinx_pcie_link_up(pcie))
>   			return false;
>   	} else if (devfn > 0) {
>   		/* Only one device down on each root port */
> @@ -177,12 +177,12 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
>   static void __iomem *xilinx_pcie_map_bus(struct pci_bus *bus,
>   					 unsigned int devfn, int where)
>   {
> -	struct xilinx_pcie_port *port = bus->sysdata;
> +	struct xilinx_pcie *pcie = bus->sysdata;
>   
>   	if (!xilinx_pcie_valid_device(bus, devfn))
>   		return NULL;
>   
> -	return port->reg_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
> +	return pcie->reg_base + PCIE_ECAM_OFFSET(bus->number, devfn, where);
>   }
>   
>   /* PCIe operations */
> @@ -215,7 +215,7 @@ static int xilinx_msi_set_affinity(struct irq_data *d, const struct cpumask *mas
>   
>   static void xilinx_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
>   {
> -	struct xilinx_pcie_port *pcie = irq_data_get_irq_chip_data(data);
> +	struct xilinx_pcie *pcie = irq_data_get_irq_chip_data(data);
>   	phys_addr_t pa = ALIGN_DOWN(virt_to_phys(pcie), SZ_4K);
>   
>   	msg->address_lo = lower_32_bits(pa);
> @@ -232,14 +232,14 @@ static struct irq_chip xilinx_msi_bottom_chip = {
>   static int xilinx_msi_domain_alloc(struct irq_domain *domain, unsigned int virq,
>   				  unsigned int nr_irqs, void *args)
>   {
> -	struct xilinx_pcie_port *port = domain->host_data;
> +	struct xilinx_pcie *pcie = domain->host_data;
>   	int hwirq, i;
>   
> -	mutex_lock(&port->map_lock);
> +	mutex_lock(&pcie->map_lock);
>   
> -	hwirq = bitmap_find_free_region(port->msi_map, XILINX_NUM_MSI_IRQS, order_base_2(nr_irqs));
> +	hwirq = bitmap_find_free_region(pcie->msi_map, XILINX_NUM_MSI_IRQS, order_base_2(nr_irqs));
>   
> -	mutex_unlock(&port->map_lock);
> +	mutex_unlock(&pcie->map_lock);
>   
>   	if (hwirq < 0)
>   		return -ENOSPC;
> @@ -256,13 +256,13 @@ static void xilinx_msi_domain_free(struct irq_domain *domain, unsigned int virq,
>   				  unsigned int nr_irqs)
>   {
>   	struct irq_data *d = irq_domain_get_irq_data(domain, virq);
> -	struct xilinx_pcie_port *port = domain->host_data;
> +	struct xilinx_pcie *pcie = domain->host_data;
>   
> -	mutex_lock(&port->map_lock);
> +	mutex_lock(&pcie->map_lock);
>   
> -	bitmap_release_region(port->msi_map, d->hwirq, order_base_2(nr_irqs));
> +	bitmap_release_region(pcie->msi_map, d->hwirq, order_base_2(nr_irqs));
>   
> -	mutex_unlock(&port->map_lock);
> +	mutex_unlock(&pcie->map_lock);
>   }
>   
>   static const struct irq_domain_ops xilinx_msi_domain_ops = {
> @@ -275,7 +275,7 @@ static struct msi_domain_info xilinx_msi_info = {
>   	.chip	= &xilinx_msi_top_chip,
>   };
>   
> -static int xilinx_allocate_msi_domains(struct xilinx_pcie_port *pcie)
> +static int xilinx_allocate_msi_domains(struct xilinx_pcie *pcie)
>   {
>   	struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
>   	struct irq_domain *parent;
> @@ -298,7 +298,7 @@ static int xilinx_allocate_msi_domains(struct xilinx_pcie_port *pcie)
>   	return 0;
>   }
>   
> -static void xilinx_free_msi_domains(struct xilinx_pcie_port *pcie)
> +static void xilinx_free_msi_domains(struct xilinx_pcie *pcie)
>   {
>   	struct irq_domain *parent = pcie->msi_domain->parent;
>   
> @@ -342,13 +342,13 @@ static const struct irq_domain_ops intx_domain_ops = {
>    */
>   static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
>   {
> -	struct xilinx_pcie_port *port = (struct xilinx_pcie_port *)data;
> -	struct device *dev = port->dev;
> +	struct xilinx_pcie *pcie = (struct xilinx_pcie *)data;
> +	struct device *dev = pcie->dev;
>   	u32 val, mask, status;
>   
>   	/* Read interrupt decode and mask registers */
> -	val = pcie_read(port, XILINX_PCIE_REG_IDR);
> -	mask = pcie_read(port, XILINX_PCIE_REG_IMR);
> +	val = pcie_read(pcie, XILINX_PCIE_REG_IDR);
> +	mask = pcie_read(pcie, XILINX_PCIE_REG_IMR);
>   
>   	status = val & mask;
>   	if (!status)
> @@ -371,23 +371,23 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
>   
>   	if (status & XILINX_PCIE_INTR_CORRECTABLE) {
>   		dev_warn(dev, "Correctable error message\n");
> -		xilinx_pcie_clear_err_interrupts(port);
> +		xilinx_pcie_clear_err_interrupts(pcie);
>   	}
>   
>   	if (status & XILINX_PCIE_INTR_NONFATAL) {
>   		dev_warn(dev, "Non fatal error message\n");
> -		xilinx_pcie_clear_err_interrupts(port);
> +		xilinx_pcie_clear_err_interrupts(pcie);
>   	}
>   
>   	if (status & XILINX_PCIE_INTR_FATAL) {
>   		dev_warn(dev, "Fatal error message\n");
> -		xilinx_pcie_clear_err_interrupts(port);
> +		xilinx_pcie_clear_err_interrupts(pcie);
>   	}
>   
>   	if (status & (XILINX_PCIE_INTR_INTX | XILINX_PCIE_INTR_MSI)) {
>   		struct irq_domain *domain;
>   
> -		val = pcie_read(port, XILINX_PCIE_REG_RPIFR1);
> +		val = pcie_read(pcie, XILINX_PCIE_REG_RPIFR1);
>   
>   		/* Check whether interrupt valid */
>   		if (!(val & XILINX_PCIE_RPIFR1_INTR_VALID)) {
> @@ -397,17 +397,17 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
>   
>   		/* Decode the IRQ number */
>   		if (val & XILINX_PCIE_RPIFR1_MSI_INTR) {
> -			val = pcie_read(port, XILINX_PCIE_REG_RPIFR2) &
> +			val = pcie_read(pcie, XILINX_PCIE_REG_RPIFR2) &
>   				XILINX_PCIE_RPIFR2_MSG_DATA;
> -			domain = port->msi_domain->parent;
> +			domain = pcie->msi_domain->parent;
>   		} else {
>   			val = (val & XILINX_PCIE_RPIFR1_INTR_MASK) >>
>   				XILINX_PCIE_RPIFR1_INTR_SHIFT;
> -			domain = port->leg_domain;
> +			domain = pcie->leg_domain;
>   		}
>   
>   		/* Clear interrupt FIFO register 1 */
> -		pcie_write(port, XILINX_PCIE_RPIFR1_ALL_MASK,
> +		pcie_write(pcie, XILINX_PCIE_RPIFR1_ALL_MASK,
>   			   XILINX_PCIE_REG_RPIFR1);
>   
>   		generic_handle_domain_irq(domain, val);
> @@ -442,20 +442,20 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data)
>   
>   error:
>   	/* Clear the Interrupt Decode register */
> -	pcie_write(port, status, XILINX_PCIE_REG_IDR);
> +	pcie_write(pcie, status, XILINX_PCIE_REG_IDR);
>   
>   	return IRQ_HANDLED;
>   }
>   
>   /**
>    * xilinx_pcie_init_irq_domain - Initialize IRQ domain
> - * @port: PCIe port information
> + * @pcie: PCIe port information
>    *
>    * Return: '0' on success and error value on failure
>    */
> -static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
> +static int xilinx_pcie_init_irq_domain(struct xilinx_pcie *pcie)
>   {
> -	struct device *dev = port->dev;
> +	struct device *dev = pcie->dev;
>   	struct device_node *pcie_intc_node;
>   	int ret;
>   
> @@ -466,25 +466,25 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
>   		return -ENODEV;
>   	}
>   
> -	port->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
> +	pcie->leg_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
>   						 &intx_domain_ops,
> -						 port);
> +						 pcie);
>   	of_node_put(pcie_intc_node);
> -	if (!port->leg_domain) {
> +	if (!pcie->leg_domain) {
>   		dev_err(dev, "Failed to get a INTx IRQ domain\n");
>   		return -ENODEV;
>   	}
>   
>   	/* Setup MSI */
>   	if (IS_ENABLED(CONFIG_PCI_MSI)) {
> -		phys_addr_t pa = ALIGN_DOWN(virt_to_phys(port), SZ_4K);
> +		phys_addr_t pa = ALIGN_DOWN(virt_to_phys(pcie), SZ_4K);
>   
> -		ret = xilinx_allocate_msi_domains(port);
> +		ret = xilinx_allocate_msi_domains(pcie);
>   		if (ret)
>   			return ret;
>   
> -		pcie_write(port, upper_32_bits(pa), XILINX_PCIE_REG_MSIBASE1);
> -		pcie_write(port, lower_32_bits(pa), XILINX_PCIE_REG_MSIBASE2);
> +		pcie_write(pcie, upper_32_bits(pa), XILINX_PCIE_REG_MSIBASE1);
> +		pcie_write(pcie, lower_32_bits(pa), XILINX_PCIE_REG_MSIBASE2);
>   	}
>   
>   	return 0;
> @@ -492,44 +492,44 @@ static int xilinx_pcie_init_irq_domain(struct xilinx_pcie_port *port)
>   
>   /**
>    * xilinx_pcie_init_port - Initialize hardware
> - * @port: PCIe port information
> + * @pcie: PCIe port information
>    */
> -static void xilinx_pcie_init_port(struct xilinx_pcie_port *port)
> +static void xilinx_pcie_init_port(struct xilinx_pcie *pcie)
>   {
> -	struct device *dev = port->dev;
> +	struct device *dev = pcie->dev;
>   
> -	if (xilinx_pcie_link_up(port))
> +	if (xilinx_pcie_link_up(pcie))
>   		dev_info(dev, "PCIe Link is UP\n");
>   	else
>   		dev_info(dev, "PCIe Link is DOWN\n");
>   
>   	/* Disable all interrupts */
> -	pcie_write(port, ~XILINX_PCIE_IDR_ALL_MASK,
> +	pcie_write(pcie, ~XILINX_PCIE_IDR_ALL_MASK,
>   		   XILINX_PCIE_REG_IMR);
>   
>   	/* Clear pending interrupts */
> -	pcie_write(port, pcie_read(port, XILINX_PCIE_REG_IDR) &
> +	pcie_write(pcie, pcie_read(pcie, XILINX_PCIE_REG_IDR) &
>   			 XILINX_PCIE_IMR_ALL_MASK,
>   		   XILINX_PCIE_REG_IDR);
>   
>   	/* Enable all interrupts we handle */
> -	pcie_write(port, XILINX_PCIE_IMR_ENABLE_MASK, XILINX_PCIE_REG_IMR);
> +	pcie_write(pcie, XILINX_PCIE_IMR_ENABLE_MASK, XILINX_PCIE_REG_IMR);
>   
>   	/* Enable the Bridge enable bit */
> -	pcie_write(port, pcie_read(port, XILINX_PCIE_REG_RPSC) |
> +	pcie_write(pcie, pcie_read(pcie, XILINX_PCIE_REG_RPSC) |
>   			 XILINX_PCIE_REG_RPSC_BEN,
>   		   XILINX_PCIE_REG_RPSC);
>   }
>   
>   /**
>    * xilinx_pcie_parse_dt - Parse Device tree
> - * @port: PCIe port information
> + * @pcie: PCIe port information
>    *
>    * Return: '0' on success and error value on failure
>    */
> -static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
> +static int xilinx_pcie_parse_dt(struct xilinx_pcie *pcie)
>   {
> -	struct device *dev = port->dev;
> +	struct device *dev = pcie->dev;
>   	struct device_node *node = dev->of_node;
>   	struct resource regs;
>   	unsigned int irq;
> @@ -541,14 +541,14 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
>   		return err;
>   	}
>   
> -	port->reg_base = devm_pci_remap_cfg_resource(dev, &regs);
> -	if (IS_ERR(port->reg_base))
> -		return PTR_ERR(port->reg_base);
> +	pcie->reg_base = devm_pci_remap_cfg_resource(dev, &regs);
> +	if (IS_ERR(pcie->reg_base))
> +		return PTR_ERR(pcie->reg_base);
>   
>   	irq = irq_of_parse_and_map(node, 0);
>   	err = devm_request_irq(dev, irq, xilinx_pcie_intr_handler,
>   			       IRQF_SHARED | IRQF_NO_THREAD,
> -			       "xilinx-pcie", port);
> +			       "xilinx-pcie", pcie);
>   	if (err) {
>   		dev_err(dev, "unable to request irq %d\n", irq);
>   		return err;
> @@ -566,41 +566,41 @@ static int xilinx_pcie_parse_dt(struct xilinx_pcie_port *port)
>   static int xilinx_pcie_probe(struct platform_device *pdev)
>   {
>   	struct device *dev = &pdev->dev;
> -	struct xilinx_pcie_port *port;
> +	struct xilinx_pcie *pcie;
>   	struct pci_host_bridge *bridge;
>   	int err;
>   
>   	if (!dev->of_node)
>   		return -ENODEV;
>   
> -	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port));
> +	bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>   	if (!bridge)
>   		return -ENODEV;
>   
> -	port = pci_host_bridge_priv(bridge);
> -	mutex_init(&port->map_lock);
> -	port->dev = dev;
> +	pcie = pci_host_bridge_priv(bridge);
> +	mutex_init(&pcie->map_lock);
> +	pcie->dev = dev;
>   
> -	err = xilinx_pcie_parse_dt(port);
> +	err = xilinx_pcie_parse_dt(pcie);
>   	if (err) {
>   		dev_err(dev, "Parsing DT failed\n");
>   		return err;
>   	}
>   
> -	xilinx_pcie_init_port(port);
> +	xilinx_pcie_init_port(pcie);
>   
> -	err = xilinx_pcie_init_irq_domain(port);
> +	err = xilinx_pcie_init_irq_domain(pcie);
>   	if (err) {
>   		dev_err(dev, "Failed creating IRQ Domain\n");
>   		return err;
>   	}
>   
> -	bridge->sysdata = port;
> +	bridge->sysdata = pcie;
>   	bridge->ops = &xilinx_pcie_ops;
>   
>   	err = pci_host_probe(bridge);
>   	if (err)
> -		xilinx_free_msi_domains(port);
> +		xilinx_free_msi_domains(pcie);
>   
>   	return err;
>   }

Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From michal.simek at xilinx.com  Mon Jan  3 00:39:41 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 3 Jan 2022 09:39:41 +0100
Subject: [PATCH v2 23/23] PCI: xilinx-cpm: Rename xilinx_cpm_pcie_port to
 xilinx_cpm_pcie
In-Reply-To: <20211223011054.1227810-24-helgaas@kernel.org>
References: <20211223011054.1227810-1-helgaas@kernel.org>
 <20211223011054.1227810-24-helgaas@kernel.org>
Message-ID: <d049cfb1-31e4-b712-cd9a-4566ade8de4c@xilinx.com>



On 12/23/21 02:10, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> Rename struct xilinx_cpm_pcie_port to xilinx_cpm_pcie to match the
> convention of <driver>_pcie. No functional change intended.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Michal Simek <michal.simek at xilinx.com>
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/pci/controller/pcie-xilinx-cpm.c | 44 ++++++++++++------------
>   1 file changed, 22 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-xilinx-cpm.c b/drivers/pci/controller/pcie-xilinx-cpm.c
> index 95426df03200..c7cd44ed4dfc 100644
> --- a/drivers/pci/controller/pcie-xilinx-cpm.c
> +++ b/drivers/pci/controller/pcie-xilinx-cpm.c
> @@ -99,10 +99,10 @@
>   #define XILINX_CPM_PCIE_REG_PSCR_LNKUP		BIT(11)
>   
>   /**
> - * struct xilinx_cpm_pcie_port - PCIe port information
> + * struct xilinx_cpm_pcie - PCIe port information
> + * @dev: Device pointer
>    * @reg_base: Bridge Register Base
>    * @cpm_base: CPM System Level Control and Status Register(SLCR) Base
> - * @dev: Device pointer
>    * @intx_domain: Legacy IRQ domain pointer
>    * @cpm_domain: CPM IRQ domain pointer
>    * @cfg: Holds mappings of config space window
> @@ -110,10 +110,10 @@
>    * @irq: Error interrupt number
>    * @lock: lock protecting shared register access
>    */
> -struct xilinx_cpm_pcie_port {
> +struct xilinx_cpm_pcie {
> +	struct device			*dev;
>   	void __iomem			*reg_base;
>   	void __iomem			*cpm_base;
> -	struct device			*dev;
>   	struct irq_domain		*intx_domain;
>   	struct irq_domain		*cpm_domain;
>   	struct pci_config_window	*cfg;
> @@ -122,24 +122,24 @@ struct xilinx_cpm_pcie_port {
>   	raw_spinlock_t			lock;
>   };
>   
> -static u32 pcie_read(struct xilinx_cpm_pcie_port *port, u32 reg)
> +static u32 pcie_read(struct xilinx_cpm_pcie *port, u32 reg)
>   {
>   	return readl_relaxed(port->reg_base + reg);
>   }
>   
> -static void pcie_write(struct xilinx_cpm_pcie_port *port,
> +static void pcie_write(struct xilinx_cpm_pcie *port,
>   		       u32 val, u32 reg)
>   {
>   	writel_relaxed(val, port->reg_base + reg);
>   }
>   
> -static bool cpm_pcie_link_up(struct xilinx_cpm_pcie_port *port)
> +static bool cpm_pcie_link_up(struct xilinx_cpm_pcie *port)
>   {
>   	return (pcie_read(port, XILINX_CPM_PCIE_REG_PSCR) &
>   		XILINX_CPM_PCIE_REG_PSCR_LNKUP);
>   }
>   
> -static void cpm_pcie_clear_err_interrupts(struct xilinx_cpm_pcie_port *port)
> +static void cpm_pcie_clear_err_interrupts(struct xilinx_cpm_pcie *port)
>   {
>   	unsigned long val = pcie_read(port, XILINX_CPM_PCIE_REG_RPEFR);
>   
> @@ -153,7 +153,7 @@ static void cpm_pcie_clear_err_interrupts(struct xilinx_cpm_pcie_port *port)
>   
>   static void xilinx_cpm_mask_leg_irq(struct irq_data *data)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_data_get_irq_chip_data(data);
> +	struct xilinx_cpm_pcie *port = irq_data_get_irq_chip_data(data);
>   	unsigned long flags;
>   	u32 mask;
>   	u32 val;
> @@ -167,7 +167,7 @@ static void xilinx_cpm_mask_leg_irq(struct irq_data *data)
>   
>   static void xilinx_cpm_unmask_leg_irq(struct irq_data *data)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_data_get_irq_chip_data(data);
> +	struct xilinx_cpm_pcie *port = irq_data_get_irq_chip_data(data);
>   	unsigned long flags;
>   	u32 mask;
>   	u32 val;
> @@ -211,7 +211,7 @@ static const struct irq_domain_ops intx_domain_ops = {
>   
>   static void xilinx_cpm_pcie_intx_flow(struct irq_desc *desc)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_desc_get_handler_data(desc);
> +	struct xilinx_cpm_pcie *port = irq_desc_get_handler_data(desc);
>   	struct irq_chip *chip = irq_desc_get_chip(desc);
>   	unsigned long val;
>   	int i;
> @@ -229,7 +229,7 @@ static void xilinx_cpm_pcie_intx_flow(struct irq_desc *desc)
>   
>   static void xilinx_cpm_mask_event_irq(struct irq_data *d)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_data_get_irq_chip_data(d);
> +	struct xilinx_cpm_pcie *port = irq_data_get_irq_chip_data(d);
>   	u32 val;
>   
>   	raw_spin_lock(&port->lock);
> @@ -241,7 +241,7 @@ static void xilinx_cpm_mask_event_irq(struct irq_data *d)
>   
>   static void xilinx_cpm_unmask_event_irq(struct irq_data *d)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_data_get_irq_chip_data(d);
> +	struct xilinx_cpm_pcie *port = irq_data_get_irq_chip_data(d);
>   	u32 val;
>   
>   	raw_spin_lock(&port->lock);
> @@ -273,7 +273,7 @@ static const struct irq_domain_ops event_domain_ops = {
>   
>   static void xilinx_cpm_pcie_event_flow(struct irq_desc *desc)
>   {
> -	struct xilinx_cpm_pcie_port *port = irq_desc_get_handler_data(desc);
> +	struct xilinx_cpm_pcie *port = irq_desc_get_handler_data(desc);
>   	struct irq_chip *chip = irq_desc_get_chip(desc);
>   	unsigned long val;
>   	int i;
> @@ -327,7 +327,7 @@ static const struct {
>   
>   static irqreturn_t xilinx_cpm_pcie_intr_handler(int irq, void *dev_id)
>   {
> -	struct xilinx_cpm_pcie_port *port = dev_id;
> +	struct xilinx_cpm_pcie *port = dev_id;
>   	struct device *dev = port->dev;
>   	struct irq_data *d;
>   
> @@ -350,7 +350,7 @@ static irqreturn_t xilinx_cpm_pcie_intr_handler(int irq, void *dev_id)
>   	return IRQ_HANDLED;
>   }
>   
> -static void xilinx_cpm_free_irq_domains(struct xilinx_cpm_pcie_port *port)
> +static void xilinx_cpm_free_irq_domains(struct xilinx_cpm_pcie *port)
>   {
>   	if (port->intx_domain) {
>   		irq_domain_remove(port->intx_domain);
> @@ -369,7 +369,7 @@ static void xilinx_cpm_free_irq_domains(struct xilinx_cpm_pcie_port *port)
>    *
>    * Return: '0' on success and error value on failure
>    */
> -static int xilinx_cpm_pcie_init_irq_domain(struct xilinx_cpm_pcie_port *port)
> +static int xilinx_cpm_pcie_init_irq_domain(struct xilinx_cpm_pcie *port)
>   {
>   	struct device *dev = port->dev;
>   	struct device_node *node = dev->of_node;
> @@ -410,7 +410,7 @@ static int xilinx_cpm_pcie_init_irq_domain(struct xilinx_cpm_pcie_port *port)
>   	return -ENOMEM;
>   }
>   
> -static int xilinx_cpm_setup_irq(struct xilinx_cpm_pcie_port *port)
> +static int xilinx_cpm_setup_irq(struct xilinx_cpm_pcie *port)
>   {
>   	struct device *dev = port->dev;
>   	struct platform_device *pdev = to_platform_device(dev);
> @@ -462,7 +462,7 @@ static int xilinx_cpm_setup_irq(struct xilinx_cpm_pcie_port *port)
>    * xilinx_cpm_pcie_init_port - Initialize hardware
>    * @port: PCIe port information
>    */
> -static void xilinx_cpm_pcie_init_port(struct xilinx_cpm_pcie_port *port)
> +static void xilinx_cpm_pcie_init_port(struct xilinx_cpm_pcie *port)
>   {
>   	if (cpm_pcie_link_up(port))
>   		dev_info(port->dev, "PCIe Link is UP\n");
> @@ -497,7 +497,7 @@ static void xilinx_cpm_pcie_init_port(struct xilinx_cpm_pcie_port *port)
>    *
>    * Return: '0' on success and error value on failure
>    */
> -static int xilinx_cpm_pcie_parse_dt(struct xilinx_cpm_pcie_port *port,
> +static int xilinx_cpm_pcie_parse_dt(struct xilinx_cpm_pcie *port,
>   				    struct resource *bus_range)
>   {
>   	struct device *dev = port->dev;
> @@ -523,7 +523,7 @@ static int xilinx_cpm_pcie_parse_dt(struct xilinx_cpm_pcie_port *port,
>   	return 0;
>   }
>   
> -static void xilinx_cpm_free_interrupts(struct xilinx_cpm_pcie_port *port)
> +static void xilinx_cpm_free_interrupts(struct xilinx_cpm_pcie *port)
>   {
>   	irq_set_chained_handler_and_data(port->intx_irq, NULL, NULL);
>   	irq_set_chained_handler_and_data(port->irq, NULL, NULL);
> @@ -537,7 +537,7 @@ static void xilinx_cpm_free_interrupts(struct xilinx_cpm_pcie_port *port)
>    */
>   static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
>   {
> -	struct xilinx_cpm_pcie_port *port;
> +	struct xilinx_cpm_pcie *port;
>   	struct device *dev = &pdev->dev;
>   	struct pci_host_bridge *bridge;
>   	struct resource_entry *bus;



Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From angelogioacchino.delregno at collabora.com  Mon Jan  3 00:59:04 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 3 Jan 2022 09:59:04 +0100
Subject: [PATCH v2 3/5] phy: mediatek: add helpers to update bits of
 registers
In-Reply-To: <75b2773d1d170f42bae0774dbc58d1458cb25502.camel@mediatek.com>
References: <20211218082802.5256-1-chunfeng.yun@mediatek.com>
 <20211218082802.5256-3-chunfeng.yun@mediatek.com>
 <047803b9-d09f-d4f8-a674-317cc19dd055@collabora.com>
 <75b2773d1d170f42bae0774dbc58d1458cb25502.camel@mediatek.com>
Message-ID: <821f9e8b-cf35-2e53-e64f-c19e7bde957b@collabora.com>

Il 30/12/21 03:06, Chunfeng Yun ha scritto:
> On Fri, 2021-12-24 at 11:10 +0100, AngeloGioacchino Del Regno wrote:
>> Il 18/12/21 09:28, Chunfeng Yun ha scritto:
>>> Add three helpers mtk_phy_clear/set/update_bits() for registers
>>> operation
>>>
>>> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
>>> ---
>>> v2: new patch, add register access helpers,
>>>       Add updatel() macro suggested by Vinod, here add more ones
>>> instead.
>>> ---
>>>    drivers/phy/mediatek/phy-mtk-io.h | 38
>>> +++++++++++++++++++++++++++++++
>>>    1 file changed, 38 insertions(+)
>>>    create mode 100644 drivers/phy/mediatek/phy-mtk-io.h
>>>
>>> diff --git a/drivers/phy/mediatek/phy-mtk-io.h
>>> b/drivers/phy/mediatek/phy-mtk-io.h
>>> new file mode 100644
>>> index 000000000000..500fcdab165d
>>> --- /dev/null
>>> +++ b/drivers/phy/mediatek/phy-mtk-io.h
>>> @@ -0,0 +1,38 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/*
>>> + * Copyright (C) 2021 MediaTek Inc.
>>> + *
>>> + * Author: Chunfeng Yun <chunfeng.yun at mediatek.com>
>>> + */
>>> +
>>> +#ifndef __PHY_MTK_H__
>>> +#define __PHY_MTK_H__
>>> +
>>> +#include <linux/io.h>
>>> +
>>> +static inline void mtk_phy_clear_bits(void __iomem *reg, u32 bits)
>>> +{
>>> +	u32 tmp = readl(reg);
>>> +
>>> +	tmp &= ~bits;
>>> +	writel(tmp, reg);
>>> +}
>>> +
>>> +static inline void mtk_phy_set_bits(void __iomem *reg, u32 bits)
>>> +{
>>> +	u32 tmp = readl(reg);
>>> +
>>> +	tmp |= bits;
>>> +	writel(tmp, reg);
>>> +}
>>> +
>>> +static inline void mtk_phy_update_bits(void __iomem *reg, u32
>>> mask, u32 val)
>>> +{
>>> +	u32 tmp = readl(reg);
>>> +
>>> +	tmp &= ~mask;
>>> +	tmp |= val & mask;
>>> +	writel(tmp, reg);
>>> +}
>>> +
>>> +#endif
>>>
>>
>> These helpers are almost exactly duplicating what
>> regmap_update_bits() is doing.
>> I appreciate the effort to stop open-coding the same sequences over
>> and over by
>> adding such helper functions,
> I agree with you.
>> but I think that the proper way of doing what you
>> are proposing is not to add custom functions but rather reuse what
>> the Linux APIs
>> give you.
> I also like to use common APIs ASAP, but not found suitable ones.
> This may be a problem, I found that some similar custom helps already
> added under phy fold.
> 
>>
>> What about doing a conversion to use regmap on this driver?
> No, we don't use regmap here, these registers are monopolized by t-phy,
> it's not syscon.
> 
> 

Hello,

The regmap API allows this kind of usage, registers don't necessarily have
to be part of a syscon.

Regards,
- Angelo


From jianhua.ljh at gmail.com  Mon Jan  3 01:03:33 2022
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Mon, 3 Jan 2022 17:03:33 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
Message-ID: <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>

On Thu, Dec 16, 2021 at 8:26 PM Jianhua Liu <jianhua.ljh at gmail.com> wrote:
>
> On Thu, Dec 16, 2021 at 7:18 PM liuqi (BA) <liuqi115 at huawei.com> wrote:
> >
> >
> >
> > On 2021/12/14 23:55, Jianhua Liu wrote:
> > > On Tue, Dec 14, 2021 at 8:27 AM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> > >>
> > >> On Mon, 13 Dec 2021 18:38:52 +0000
> > >> Will Deacon <will at kernel.org> wrote:
> > >>
> > >>> Hi,
> > >>>
> > >>> [+Janet Liu]
> > >>>
> > >>> On Tue, Dec 07, 2021 at 08:40:02PM +0800, Qi Liu wrote:
> > >>>> This patch introduce optprobe for ARM64. In optprobe, probed
> > >>>> instruction is replaced by a branch instruction to trampoline.
> > >>>>
> > >>>> Performance of optprobe on Hip08 platform is test using kprobe
> > >>>> example module[1] to analyze the latency of a kernel function,
> > >>>> and here is the result:
> > >>>>
> > >>>> common kprobe:
> > >>>> [280709.846380] do_empty returned 0 and took 1530 ns to execute
> > >>>> [280709.852057] do_empty returned 0 and took 550 ns to execute
> > >>>> [280709.857631] do_empty returned 0 and took 440 ns to execute
> > >>>> [280709.863215] do_empty returned 0 and took 380 ns to execute
> > >>>> [280709.868787] do_empty returned 0 and took 360 ns to execute
> > >>>> [280709.874362] do_empty returned 0 and took 340 ns to execute
> > >>>> [280709.879936] do_empty returned 0 and took 320 ns to execute
> > >>>> [280709.885505] do_empty returned 0 and took 300 ns to execute
> > >>>> [280709.891075] do_empty returned 0 and took 280 ns to execute
> > >>>> [280709.896646] do_empty returned 0 and took 290 ns to execute
> > >>>>
> > >>>> optprobe:
> > >>>> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
> > >>>> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
> > >>>> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
> > >>>> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
> > >>>> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
> > >>>> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
> > >>>> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
> > >>>> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
> > >>>> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
> > >>>> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
> > >>>> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
> > >>>>
> > >>>> As the result shows, optprobe can greatly reduce the latency. Big
> > >>>> latency of common kprobe will significantly impact the real result
> > >>>> while doing performance analysis or debugging performance issues
> > >>>> in lab, so optprobe is useful in this scenario.
> > >>>>
> > >>>> Acked-by: Masami Hiramatsu <mhiramat at kernel.org>
> > >>>> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
> > >>>>
> > >>>> Note:
> > >>>> As branch instruction in Arm64 has a 128M range limitation, optprobe
> > >>>> could only used when offset between probe point and trampoline
> > >>>> is less than 128M, otherwise kernel will choose common kprobe
> > >>>> automaticly.
> > >>>>
> > >>>> Limitation caused by branch isn't unique to Arm64, but also to
> > >>>> x86/arm/powerpc.
> > >>>>
> > >>>> In fact, Module PLT has been tried to get rid of limiation, but
> > >>>> destination of PLT must be a fixed value, and we need to modify
> > >>>> the destination (as each optprobe has its own trampoline).
> > >>>>
> > >>>> As discussed with Masami[2], we can start with core-kernel point
> > >>>> (within 128M) as the first step, like other architectures.
> > >>>>
> > >>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
> > >>>> [2] https://lore.kernel.org/lkml/20211201105001.5164f98ba783e7207df1229c at kernel.org/
> > >>>> ---
> > >>>>   arch/arm64/Kconfig                            |   1 +
> > >>>>   arch/arm64/include/asm/kprobes.h              |  21 ++
> > >>>>   arch/arm64/kernel/probes/Makefile             |   2 +
> > >>>>   arch/arm64/kernel/probes/opt_arm64.c          | 199 ++++++++++++++++++
> > >>>>   .../arm64/kernel/probes/optprobe_trampoline.S |  97 +++++++++
> > >>>>   include/linux/kprobes.h                       |   2 +
> > >>>>   kernel/kprobes.c                              |  22 ++
> > >>>>   7 files changed, 344 insertions(+)
> > >>>>   create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
> > >>>>   create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S
> > >>>
> > >>> I've not looked at these changes in detail, but it looks like there is an
> > >>> independent patch from Janet Liu trying to do the same thing:
> > >>>
> > >>> https://lore.kernel.org/r/1635858706-27320-1-git-send-email-jianhua.ljh at gmail.com
> > >>>
> > >>
> > >> Thanks for noticing. I missed it.
> > >>
> > >>> The patch here from Qi Liu looks like it's a bit further along, but it
> > >>> would be good for Janet to at least test it out and confirm that it works
> > >>> for them.
> > >>
> > >> Yeah, it's now v5.
> > >> But it seems Janet's one also has good points. I would like Janet's sharing
> > >> save_all_base_regs macro and the comment about the branch instruction.
> > >>
> > >>>
> > >>> Cheers,
> > >>>
> > >>> Will
> > >>>
> > >>> [Kept diff inline for Janet]
> > >>
> > >> Janet, please feel free to review and test it. It is important that you confirm
> > >> this can work with your envionment too.
> > >> I will review your KPROBE_ON_FTRACE patch.
> > >>
> > > I have tested these patch on UNISOC s9863a platform before sending.
> > >
> > > The test case from:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/
> > >
> > > And I do the following change for kprobe_example.c before testing:
> > > 1. delete function handler_post,
> > >     kprobe_init does "kp.post_handler = handler_post; --->
> > > p.post_handler = NULL;"
> > > 2. handler_pre calls dump_stack.
> > >
> >
> > Hi Jianhua,
> >
> > Could you kindly review this patch and test it on your UNISOC s9863a
> > platform? Let's work together to make arm64 optprobe work : )
> >
> > Thanks,
> > Qi
>
> OK, I will review. I have left UNISOC, I get some help from old
> colleage to do the test.
> Only on weekend, he can do it. So the time will be longer a little.
>
> Thanks
> Jianhua
>
>
Hi Qi,
I have tested your patch on UNISOC s9863a.
Test case "kprobe_example & kretprobe_example" is OK.

Two point:
1. backtrace is not perfect.
   optprobe_common does not saved frame pointer,
   backtrace lacks two calls.
such as for dup_mm: lack copy_process-->dup_mm
dup_mm backtrace from your patch:
[  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
[  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
[  832.387083] Call trace:
[  832.387086]  dump_backtrace+0x0/0x1e0
[  832.387103]  show_stack+0x24/0x30
[  832.387112]  dump_stack_lvl+0x68/0x84
[  832.387123]  dump_stack+0x18/0x34
[  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
[  832.387143]  opt_pre_handler+0x84/0xc0
[  832.387154]  optprobe_optimized_callback+0xec/0x164
[  832.387164]  optprobe_common+0x70/0xc4
[  832.387173]  kernel_clone+0x98/0x440
[  832.387182]  __do_sys_clone+0x54/0x80
[  832.387191]  __arm64_sys_clone+0x2c/0x40
[  832.387199]  invoke_syscall+0x50/0x120
[  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
[  832.387217]  do_el0_svc+0x30/0x9c
[  832.387225]  el0_svc+0x20/0x60
[  832.387235]  el0t_64_sync_handler+0xe8/0xf0
[  832.387242]  el0t_64_sync+0x1a0/0x1a4


dup_mm backtrace from other:
[  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
[  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
[  173.352304] Call trace:
[  173.352307]  dump_backtrace+0x0/0x1d4
[  173.352319]  show_stack+0x18/0x24
[  173.352326]  dump_stack_lvl+0x68/0x84
[  173.352333]  dump_stack+0x18/0x34
[  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
[  173.352347]  opt_pre_handler+0x74/0xb0
[  173.352354]  optimized_callback+0x108/0x130
[  173.352361]  optinsn_slot+0x258/0x1000
[  173.352366]  dup_mm+0x4/0x4b0
[  173.352373]  copy_process+0x1284/0x1360
[  173.352378]  kernel_clone+0x5c/0x3c0
[  173.352384]  __do_sys_clone+0x54/0x80
[  173.352390]  __arm64_sys_clone+0x24/0x30
[  173.352396]  invoke_syscall+0x48/0x114
[  173.352402]  el0_svc_common.constprop.0+0x44/0xec
[  173.352408]  do_el0_svc+0x24/0x90
[  173.352413]  el0_svc+0x20/0x60
[  173.352420]  el0t_64_sync_handler+0xe8/0xf0
[  173.352427]  el0t_64_sync+0x1a0/0x1a4

2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
   kernel/kprobe.c used only one PAGE_SIZE slot memory.

Thanks
Jianhua

> > Thanks for  the review.
> > >
> > >> Thank you,
> > >>
> > >>>
> > >>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > >>>> index c4207cf9bb17..6b68ec498e67 100644
> > >>>> --- a/arch/arm64/Kconfig
> > >>>> +++ b/arch/arm64/Kconfig
> > >>>> @@ -200,6 +200,7 @@ config ARM64
> > >>>>      select HAVE_STACKPROTECTOR
> > >>>>      select HAVE_SYSCALL_TRACEPOINTS
> > >>>>      select HAVE_KPROBES
> > >>>> +   select HAVE_OPTPROBES
> > >>>>      select HAVE_KRETPROBES
> > >>>>      select HAVE_GENERIC_VDSO
> > >>>>      select IOMMU_DMA if IOMMU_SUPPORT
> > >>>> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
> > >>>> index 05cd82eeca13..3838e4317877 100644
> > >>>> --- a/arch/arm64/include/asm/kprobes.h
> > >>>> +++ b/arch/arm64/include/asm/kprobes.h
> > >>>> @@ -39,6 +39,27 @@ void arch_remove_kprobe(struct kprobe *);
> > >>>>   int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
> > >>>>   int kprobe_exceptions_notify(struct notifier_block *self,
> > >>>>                           unsigned long val, void *data);
> > >>>> +
> > >>>> +struct arch_optimized_insn {
> > >>>> +   kprobe_opcode_t orig_insn[1];
> > >>>> +   kprobe_opcode_t *trampoline;
> > >>>> +};
> > >>>> +
> > >>>> +#define MAX_OPTIMIZED_LENGTH       sizeof(kprobe_opcode_t)
> > >>>> +#define MAX_OPTINSN_SIZE                                                       \
> > >>>> +   ((unsigned long)optprobe_template_restore_end - (unsigned long)optprobe_template_entry)
> > >>>> +
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_entry[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_val[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_common[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_end[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
> > >>>> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
> > >>>> +extern __visible kprobe_opcode_t optinsn_slot[];
> > >>>> +
> > >>>> +void optprobe_common(void);
> > >>>> +
> > >>>>   void __kretprobe_trampoline(void);
> > >>>>   void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
> > >>>>
> > >>>> diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> > >>>> index 8e4be92e25b1..07105fd3261d 100644
> > >>>> --- a/arch/arm64/kernel/probes/Makefile
> > >>>> +++ b/arch/arm64/kernel/probes/Makefile
> > >>>> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)               += kprobes.o decode-insn.o      \
> > >>>>                                 simulate-insn.o
> > >>>>   obj-$(CONFIG_UPROBES)              += uprobes.o decode-insn.o      \
> > >>>>                                 simulate-insn.o
> > >>>> +obj-$(CONFIG_OPTPROBES)            += opt_arm64.o                  \
> > >>>> +                              optprobe_trampoline.o
> > >>>> diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
> > >>>> new file mode 100644
> > >>>> index 000000000000..1bad5cddcdf2
> > >>>> --- /dev/null
> > >>>> +++ b/arch/arm64/kernel/probes/opt_arm64.c
> > >>>> @@ -0,0 +1,199 @@
> > >>>> +// SPDX-License-Identifier: GPL-2.0-only
> > >>>> +/*
> > >>>> + * Code for Kernel probes Jump optimization.
> > >>>> + *
> > >>>> + * Copyright (C) 2021 Hisilicon Limited
> > >>>> + */
> > >>>> +
> > >>>> +#include <linux/jump_label.h>
> > >>>> +#include <linux/kprobes.h>
> > >>>> +
> > >>>> +#include <asm/cacheflush.h>
> > >>>> +#include <asm/compiler.h>
> > >>>> +#include <asm/insn.h>
> > >>>> +#include <asm/kprobes.h>
> > >>>> +#include <asm/patching.h>
> > >>>> +
> > >>>> +#define OPTPROBE_BATCH_SIZE 64
> > >>>> +#define GET_LO_VAL(val)            FIELD_GET(GENMASK(31, 0), val)
> > >>>> +#define GET_HI_VAL(val)            FIELD_GET(GENMASK(63, 32), val)
> > >>>> +
> > >>>> +#define TMPL_VAL_IDX \
> > >>>> +   (optprobe_template_val - optprobe_template_entry)
> > >>>> +#define TMPL_CALL_COMMON \
> > >>>> +   (optprobe_template_common - optprobe_template_entry)
> > >>>> +#define TMPL_RESTORE_ORIGN_INSN \
> > >>>> +   (optprobe_template_restore_orig_insn - optprobe_template_entry)
> > >>>> +#define TMPL_RESTORE_END \
> > >>>> +   (optprobe_template_restore_end - optprobe_template_entry)
> > >>>> +#define TMPL_END_IDX \
> > >>>> +   (optprobe_template_end - optprobe_template_entry)
> > >>>> +
> > >>>> +static bool insn_page_in_use;
> > >>>> +
> > >>>> +void *alloc_optinsn_page(void)
> > >>>> +{
> > >>>> +   if (insn_page_in_use)
> > >>>> +           return NULL;
> > >>>> +   insn_page_in_use = true;
> > >>>> +   return &optinsn_slot;
> > >>>> +}
> > >>>> +
> > >>>> +void free_optinsn_page(void *page)
> > >>>> +{
> > >>>> +   insn_page_in_use = false;
> > >>>> +}
> > >>>> +
> > >>>> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
> > >>>> +{
> > >>>> +   return 0;
> > >>>> +}
> > >>>> +
> > >>>> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
> > >>>> +{
> > >>>> +   return optinsn->trampoline != NULL;
> > >>>> +}
> > >>>> +
> > >>>> +int arch_within_optimized_kprobe(struct optimized_kprobe *op, kprobe_opcode_t *addr)
> > >>>> +{
> > >>>> +   return op->kp.addr == addr;
> > >>>> +}
> > >>>> +
> > >>>> +static void optprobe_set_pc_value(struct optimized_kprobe *op, struct pt_regs *regs)
> > >>>> +{
> > >>>> +   regs->pc = (unsigned long)op->kp.addr;
> > >>>> +}
> > >>>> +
> > >>>> +static int optprobe_check_branch_limit(unsigned long pc, unsigned long addr)
> > >>>> +{
> > >>>> +   long offset;
> > >>>> +
> > >>>> +   if ((pc & 0x3) || (addr & 0x3))
> > >>>> +           return -ERANGE;
> > >>>> +
> > >>>> +   offset = (long)addr - (long)pc;
> > >>>> +   if (offset < -SZ_128M || offset >= SZ_128M)
> > >>>> +           return -ERANGE;
> > >>>> +
> > >>>> +   return 0;
> > >>>> +}
> > >>>> +
> > >>>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
> > >>>> +{
> > >>>> +   kprobe_opcode_t *code, *buf;
> > >>>> +   u32 insn;
> > >>>> +   int ret = -ENOMEM;
> > >>>> +   int i;
> > >>>> +
> > >>>> +   buf = kcalloc(MAX_OPTINSN_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
> > >>>> +   if (!buf)
> > >>>> +           return ret;
> > >>>> +
> > >>>> +   code = get_optinsn_slot();
> > >>>> +   if (!code)
> > >>>> +           goto out;
> > >>>> +
> > >>>> +   if (optprobe_check_branch_limit((unsigned long)code, (unsigned long)orig->addr + 8)) {
> > >>>> +           ret = -ERANGE;
> > >>>> +           goto error;
> > >>>> +   }
> > >>>> +
> > >>>> +   op->set_pc = optprobe_set_pc_value;
> > >>>> +   memcpy(buf, optprobe_template_entry, MAX_OPTINSN_SIZE * sizeof(kprobe_opcode_t));
> > >>>> +
> > >>>> +   insn = aarch64_insn_gen_branch_imm((unsigned long)&code[TMPL_CALL_COMMON],
> > >>>> +                                      (unsigned long)&optprobe_common,
> > >>>> +                                      AARCH64_INSN_BRANCH_LINK);
> > >>>> +   buf[TMPL_CALL_COMMON] = insn;
> > >>>> +
> > >>>> +   insn = aarch64_insn_gen_branch_imm((unsigned long)&code[TMPL_RESTORE_END],
> > >>>> +                                      (unsigned long)op->kp.addr + 4,
> > >>>> +                                      AARCH64_INSN_BRANCH_NOLINK);
> > >>>> +   buf[TMPL_RESTORE_END] = insn;
> > >>>> +
> > >>>> +   buf[TMPL_VAL_IDX] = cpu_to_le32(GET_LO_VAL((unsigned long)op));
> > >>>> +   buf[TMPL_VAL_IDX + 1] = cpu_to_le32(GET_HI_VAL((unsigned long)op));
> > >>>> +   buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
> > >>>> +
> > >>>> +   /* Setup template */
> > >>>> +   for (i = 0; i < MAX_OPTINSN_SIZE; i++)
> > >>>> +           aarch64_insn_patch_text_nosync(code + i, buf[i]);
> > >>>> +
> > >>>> +   flush_icache_range((unsigned long)code, (unsigned long)(&code[TMPL_VAL_IDX]));
> > >>>> +   /* Set op->optinsn.trampoline means prepared. */
> > >>>> +   op->optinsn.trampoline = code;
> > >>>> +
> > >>>> +out:
> > >>>> +   kfree(buf);
> > >>>> +   return ret;
> > >>>> +
> > >>>> +error:
> > >>>> +   free_optinsn_slot(code, 0);
> > >>>> +   goto out;
> > >>>> +}
> > >>>> +
> > >>>> +void arch_optimize_kprobes(struct list_head *oplist)
> > >>>> +{
> > >>>> +   struct optimized_kprobe *op, *tmp;
> > >>>> +   kprobe_opcode_t insns[OPTPROBE_BATCH_SIZE];
> > >>>> +   void *addrs[OPTPROBE_BATCH_SIZE];
> > >>>> +   int i = 0;
> > >>>> +
> > >>>> +   list_for_each_entry_safe(op, tmp, oplist, list) {
> > >>>> +           WARN_ON(kprobe_disabled(&op->kp));
> > >>>> +
> > >>>> +           /*
> > >>>> +            * Backup instructions which will be replaced
> > >>>> +            * by jump address
> > >>>> +            */
> > >>>> +           memcpy(op->optinsn.orig_insn, op->kp.addr, AARCH64_INSN_SIZE);
> > >>>> +
> > >>>> +           addrs[i] = (void *)op->kp.addr;
> > >>>> +           insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
> > >>>> +                                                  (unsigned long)op->optinsn.trampoline,
> > >>>> +                                                  AARCH64_INSN_BRANCH_NOLINK);
> > >>>> +
> > >>>> +           list_del_init(&op->list);
> > >>>> +           if (++i == OPTPROBE_BATCH_SIZE)
> > >>>> +                   break;
> > >>>> +   }
> > >>>> +
> > >>>> +   aarch64_insn_patch_text(addrs, insns, i);
> > >>>> +}
> > >>>> +
> > >>>> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> > >>>> +{
> > >>>> +   arch_arm_kprobe(&op->kp);
> > >>>> +}
> > >>>> +
> > >>>> +/*
> > >>>> + * Recover original instructions and breakpoints from relative jumps.
> > >>>> + * Caller must call with locking kprobe_mutex.
> > >>>> + */
> > >>>> +void arch_unoptimize_kprobes(struct list_head *oplist,
> > >>>> +                       struct list_head *done_list)
> > >>>> +{
> > >>>> +   struct optimized_kprobe *op, *tmp;
> > >>>> +   kprobe_opcode_t insns[OPTPROBE_BATCH_SIZE];
> > >>>> +   void *addrs[OPTPROBE_BATCH_SIZE];
> > >>>> +   int i = 0;
> > >>>> +
> > >>>> +   list_for_each_entry_safe(op, tmp, oplist, list) {
> > >>>> +           addrs[i] = (void *)op->kp.addr;
> > >>>> +           insns[i] = BRK64_OPCODE_KPROBES;
> > >>>> +           list_move(&op->list, done_list);
> > >>>> +
> > >>>> +           if (++i == OPTPROBE_BATCH_SIZE)
> > >>>> +                   break;
> > >>>> +   }
> > >>>> +
> > >>>> +   aarch64_insn_patch_text(addrs, insns, i);
> > >>>> +}
> > >>>> +
> > >>>> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
> > >>>> +{
> > >>>> +   if (op->optinsn.trampoline) {
> > >>>> +           free_optinsn_slot(op->optinsn.trampoline, 1);
> > >>>> +           op->optinsn.trampoline = NULL;
> > >>>> +   }
> > >>>> +}
> > >>>> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
> > >>>> new file mode 100644
> > >>>> index 000000000000..1376daeae844
> > >>>> --- /dev/null
> > >>>> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
> > >>>> @@ -0,0 +1,97 @@
> > >>>> +/* SPDX-License-Identifier: GPL-2.0 */
> > >>>> +/*
> > >>>> + * trampoline entry and return code for optprobes.
> > >>>> + */
> > >>>> +
> > >>>> +#include <linux/linkage.h>
> > >>>> +#include <asm/asm-offsets.h>
> > >>>> +#include <asm/assembler.h>
> > >>>> +
> > >>>> +#define        OPT_SLOT_SIZE   65536
> > >>>> +
> > >>>> +   .global optinsn_slot
> > >>>> +optinsn_slot:
> > >>>> +   .space  OPT_SLOT_SIZE
> > >>>> +
> > >>>> +SYM_CODE_START(optprobe_common)
> > >>>> +   stp x2, x3, [sp, #S_X2]
> > >>>> +   stp x4, x5, [sp, #S_X4]
> > >>>> +   stp x6, x7, [sp, #S_X6]
> > >>>> +   stp x8, x9, [sp, #S_X8]
> > >>>> +   stp x10, x11, [sp, #S_X10]
> > >>>> +   stp x12, x13, [sp, #S_X12]
> > >>>> +   stp x14, x15, [sp, #S_X14]
> > >>>> +   stp x16, x17, [sp, #S_X16]
> > >>>> +   stp x18, x19, [sp, #S_X18]
> > >>>> +   stp x20, x21, [sp, #S_X20]
> > >>>> +   stp x22, x23, [sp, #S_X22]
> > >>>> +   stp x24, x25, [sp, #S_X24]
> > >>>> +   stp x26, x27, [sp, #S_X26]
> > >>>> +   stp x28, x29, [sp, #S_X28]
> > >>>> +   add x2, sp, #PT_REGS_SIZE
> > >>>> +   str x2, [sp, #S_SP]
> > >>>> +   /* Construct a useful saved PSTATE */
> > >>>> +   mrs x2, nzcv
> > >>>> +   mrs x3, daif
> > >>>> +   orr x2, x2, x3
> > >>>> +   mrs x3, CurrentEL
> > >>>> +   orr x2, x2, x3
> > >>>> +   mrs x3, SPSel
> > >>>> +   orr x2, x2, x3
> > >>>> +   stp xzr, x2, [sp, #S_PC]
> > >>>> +
> > >>>> +   /* set the pt_regs address to x1 */
> > >>>> +   mov     x1, sp
> > >>>> +   /* store lr of optprobe_common temporary */
> > >>>> +   sub sp, sp, #0x10
> > >>>> +   str lr, [sp, #0x8]
> > >>>> +
> > >>>> +   bl optprobe_optimized_callback
> > >>>> +
> > >>>> +   ldr lr, [sp, #0x8]
> > >>>> +   add sp, sp, #0x10
> > >>>> +   ldr x0, [sp, #S_PSTATE]
> > >>>> +   and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
> > >>>> +   msr nzcv, x0
> > >>>> +   ldp x0, x1, [sp, #S_X0]
> > >>>> +   ldp x2, x3, [sp, #S_X2]
> > >>>> +   ldp x4, x5, [sp, #S_X4]
> > >>>> +   ldp x6, x7, [sp, #S_X6]
> > >>>> +   ldp x8, x9, [sp, #S_X8]
> > >>>> +   ldp x10, x11, [sp, #S_X10]
> > >>>> +   ldp x12, x13, [sp, #S_X12]
> > >>>> +   ldp x14, x15, [sp, #S_X14]
> > >>>> +   ldp x16, x17, [sp, #S_X16]
> > >>>> +   ldp x18, x19, [sp, #S_X18]
> > >>>> +   ldp x20, x21, [sp, #S_X20]
> > >>>> +   ldp x22, x23, [sp, #S_X22]
> > >>>> +   ldp x24, x25, [sp, #S_X24]
> > >>>> +   ldp x26, x27, [sp, #S_X26]
> > >>>> +   ldp x28, x29, [sp, #S_X28]
> > >>>> +   ret
> > >>>> +SYM_CODE_END(optprobe_common)
> > >>>> +
> > >>>> +   .global optprobe_template_entry
> > >>>> +optprobe_template_entry:
> > >>>> +   sub sp, sp, #PT_REGS_SIZE
> > >>>> +   str lr, [sp, #S_LR]
> > >>>> +   stp x0, x1, [sp, #S_X0]
> > >>>> +   /* Get parameters to optimized_callback() */
> > >>>> +   ldr x0, 1f
> > >>>> +   .global optprobe_template_common
> > >>>> +optprobe_template_common:
> > >>>> +   nop
> > >>>> +   ldr lr, [sp, #S_LR]
> > >>>> +       add sp, sp, #PT_REGS_SIZE
> > >>>> +   .global optprobe_template_restore_orig_insn
> > >>>> +optprobe_template_restore_orig_insn:
> > >>>> +   nop
> > >>>> +   .global optprobe_template_restore_end
> > >>>> +optprobe_template_restore_end:
> > >>>> +   nop
> > >>>> +   .global optprobe_template_val
> > >>>> +optprobe_template_val:
> > >>>> +   1:      .long 0
> > >>>> +           .long 0
> > >>>> +   .global optprobe_template_end
> > >>>> +optprobe_template_end:
> > >>>> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
> > >>>> index 8c8f7a4d93af..7be680155df7 100644
> > >>>> --- a/include/linux/kprobes.h
> > >>>> +++ b/include/linux/kprobes.h
> > >>>> @@ -329,6 +329,7 @@ struct optimized_kprobe {
> > >>>>      struct kprobe kp;
> > >>>>      struct list_head list;  /* list for optimizing queue */
> > >>>>      struct arch_optimized_insn optinsn;
> > >>>> +   void (*set_pc)(struct optimized_kprobe *op, struct pt_regs *regs);
> > >>>>   };
> > >>>>
> > >>>>   /* Architecture dependent functions for direct jump optimization */
> > >>>> @@ -345,6 +346,7 @@ extern int arch_within_optimized_kprobe(struct optimized_kprobe *op,
> > >>>>                                      kprobe_opcode_t *addr);
> > >>>>
> > >>>>   extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs);
> > >>>> +extern void optprobe_optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs);
> > >>>>
> > >>>>   DEFINE_INSN_CACHE_OPS(optinsn);
> > >>>>
> > >>>> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > >>>> index 21eccc961bba..d799e562a39a 100644
> > >>>> --- a/kernel/kprobes.c
> > >>>> +++ b/kernel/kprobes.c
> > >>>> @@ -430,6 +430,28 @@ void opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
> > >>>>   }
> > >>>>   NOKPROBE_SYMBOL(opt_pre_handler);
> > >>>>
> > >>>> +void optprobe_optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
> > >>>> +{
> > >>>> +   if (kprobe_disabled(&op->kp))
> > >>>> +           return;
> > >>>> +
> > >>>> +   preempt_disable();
> > >>>> +
> > >>>> +   if (kprobe_running()) {
> > >>>> +           kprobes_inc_nmissed_count(&op->kp);
> > >>>> +   } else {
> > >>>> +           op->set_pc(op, regs);
> > >>>> +           __this_cpu_write(current_kprobe, &op->kp);
> > >>>> +           get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
> > >>>> +           opt_pre_handler(&op->kp, regs);
> > >>>> +           __this_cpu_write(current_kprobe, NULL);
> > >>>> +   }
> > >>>> +
> > >>>> +   preempt_enable();
> > >>>> +}
> > >>>> +NOKPROBE_SYMBOL(optprobe_optimized_callback)
> > >>>> +
> > >>>> +
> > >>>>   /* Free optimized instructions and optimized_kprobe */
> > >>>>   static void free_aggr_kprobe(struct kprobe *p)
> > >>>>   {
> > >>>> --
> > >>>> 2.33.0
> > >>>>
> > >>
> > >>
> > >> --
> > >> Masami Hiramatsu <mhiramat at kernel.org>
> > > .
> > >


From ck.hu at mediatek.com  Mon Jan  3 01:03:57 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 3 Jan 2022 17:03:57 +0800
Subject: [PATCH v10 19/22] drm/mediatek: modify mediatek-drm for mt8195
 multi mmsys support
In-Reply-To: <20211208024426.15595-20-nancy.lin@mediatek.com>
References: <20211208024426.15595-1-nancy.lin@mediatek.com>
 <20211208024426.15595-20-nancy.lin@mediatek.com>
Message-ID: <9ea6439ba4e7cc73c2bba7899eacee37173683bc.camel@mediatek.com>

Hi, Nancy:

On Wed, 2021-12-08 at 10:44 +0800, Nancy.Lin wrote:
> MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support.
> The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers,
> only one drm driver register as the drm device.
> Each drm driver binds its own component. The last bind drm driver
> allocates and registers the drm device to drm core.
> Each crtc path is created with the corresponding drm driver data.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  24 +-
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 300 ++++++++++++++++++--
> ----
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  10 +-
>  4 files changed, 246 insertions(+), 91 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index d661edf7e0fe..fe2871aca859 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -847,21 +847,28 @@ static int mtk_drm_crtc_init_comp_planes(struct
> drm_device *drm_dev,
>  }
>  
>  int mtk_drm_crtc_create(struct drm_device *drm_dev,
> -			const enum mtk_ddp_comp_id *path, unsigned int
> path_len)
> +			const enum mtk_ddp_comp_id *path, unsigned int
> path_len,
> +			int priv_data_index)
>  {
>  	struct mtk_drm_private *priv = drm_dev->dev_private;
>  	struct device *dev = drm_dev->dev;
>  	struct mtk_drm_crtc *mtk_crtc;
>  	unsigned int num_comp_planes = 0;
> -	int pipe = priv->num_pipes;
>  	int ret;
>  	int i;
>  	bool has_ctm = false;
>  	uint gamma_lut_size = 0;
> +	struct drm_crtc *tmp;
> +	int crtc_i = 0;
>  
>  	if (!path)
>  		return 0;
>  
> +	priv = priv->all_drm_private[priv_data_index];
> +
> +	drm_for_each_crtc(tmp, drm_dev)
> +		crtc_i++;
> +
>  	for (i = 0; i < path_len; i++) {
>  		enum mtk_ddp_comp_id comp_id = path[i];
>  		struct device_node *node;
> @@ -873,7 +880,7 @@ int mtk_drm_crtc_create(struct drm_device
> *drm_dev,
>  		if (!node) {
>  			dev_info(dev,
>  				 "Not creating crtc %d because
> component %d is disabled or missing\n",
> -				 pipe, comp_id);
> +				 crtc_i, comp_id);
>  			return 0;
>  		}
>  
> @@ -926,29 +933,28 @@ int mtk_drm_crtc_create(struct drm_device
> *drm_dev,
>  
>  	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
>  		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc,
> i,
> -						    pipe);
> +						    crtc_i);
>  		if (ret)
>  			return ret;
>  	}
>  
> -	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
> +	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
>  	if (ret < 0)
>  		return ret;
>  
>  	if (gamma_lut_size)
>  		drm_mode_crtc_set_gamma_size(&mtk_crtc->base,
> gamma_lut_size);
>  	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm,
> gamma_lut_size);
> -	priv->num_pipes++;
>  	mutex_init(&mtk_crtc->hw_lock);
>  
>  #if IS_REACHABLE(CONFIG_MTK_CMDQ)
> +	i = (priv->data->mbox_index) ? priv->data-
> >mbox_index[drm_crtc_index(&mtk_crtc->base)] : 0;
>  	mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
>  	mtk_crtc->cmdq_client.client.tx_block = false;
>  	mtk_crtc->cmdq_client.client.knows_txdone = true;
>  	mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
>  	mtk_crtc->cmdq_client.chan =
> -			mbox_request_channel(&mtk_crtc-
> >cmdq_client.client,
> -					     drm_crtc_index(&mtk_crtc-
> >base));
> +			mbox_request_channel(&mtk_crtc-
> >cmdq_client.client, i);

I really do not understand how does i work. Could you give an example
of the i value for mt8173 crtc0, mt8173 crtc1, and all mt8195 crtcs.

>  	if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
>  		dev_dbg(dev, "mtk_crtc %d failed to create mailbox
> client, writing register by CPU now\n",
>  			drm_crtc_index(&mtk_crtc->base));
> @@ -958,7 +964,7 @@ int mtk_drm_crtc_create(struct drm_device
> *drm_dev,
>  	if (mtk_crtc->cmdq_client.chan) {
>  		ret = of_property_read_u32_index(priv->mutex_node,
>  						 "mediatek,gce-events",
> -						 drm_crtc_index(&mtk_cr
> tc->base),
> +						 i,
>  						 &mtk_crtc-
> >cmdq_event);
>  		if (ret) {
>  			dev_dbg(dev, "mtk_crtc %d failed to get
> mediatek,gce-events property\n",
> 

[snip]

>  
>  static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data
> = {
>  	.main_path = mt8195_mtk_ddp_main,
>  	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
> +	.mmsys_dev_num = 2,

After this patch, vdosys0 would not work. So set this to 1 in this
patch, and set this to 2 in the mt8195 vdosys1 patch.

Regards,
CK

>  };
>  
> 



From wsa+renesas at sang-engineering.com  Mon Jan  3 01:18:55 2022
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 3 Jan 2022 10:18:55 +0100
Subject: [PATCH v2 1/3] i2c: bcm2835: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20211221175322.7096-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20211221175322.7096-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20211221175322.7096-2-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YdK/fy7AXn2+rYnx@ninjato>

On Tue, Dec 21, 2021 at 05:53:20PM +0000, Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220103/a5547832/attachment.sig>

From wsa+renesas at sang-engineering.com  Mon Jan  3 01:19:04 2022
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 3 Jan 2022 10:19:04 +0100
Subject: [PATCH v2 2/3] i2c: sh_mobile: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <20211221175322.7096-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20211221175322.7096-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20211221175322.7096-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YdK/iC+YHi8HPVrE@ninjato>

On Tue, Dec 21, 2021 at 05:53:21PM +0000, Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq_optional() for DT users only.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220103/df4e73a8/attachment.sig>

From wsa+renesas at sang-engineering.com  Mon Jan  3 01:19:09 2022
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Mon, 3 Jan 2022 10:19:09 +0100
Subject: [PATCH v2 3/3] i2c: riic: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20211221175322.7096-4-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20211221175322.7096-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20211221175322.7096-4-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YdK/jYJTaDQRfOzi@ninjato>

On Tue, Dec 21, 2021 at 05:53:22PM +0000, Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220103/bf609c0c/attachment.sig>

From andi at etezian.org  Mon Jan  3 01:40:54 2022
From: andi at etezian.org (Andi Shyti)
Date: Mon, 3 Jan 2022 11:40:54 +0200
Subject: [PATCH 1/2] ARM: dts: exynos: split dmas into array of phandles
 in Exynos5250
In-Reply-To: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YdLEprsh3i3/oRVb@jack.zhora.eu>

Hi Krzysztof,

On Sun, Jan 02, 2022 at 04:58:06PM +0100, Krzysztof Kozlowski wrote:
> "dmas" property should be rather an array of phandles, as dtschema
> points.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Reviewed-by: Andi Shyti <andi at etezian.org>

Thanks,
Andi


From brgl at bgdev.pl  Mon Jan  3 01:50:38 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Mon, 3 Jan 2022 10:50:38 +0100
Subject: [PATCH v1 1/1] gpio: gpio-aspeed-sgpio: Fix wrong hwirq base in
 irq handler
In-Reply-To: <CAMRc=MdAgK7zKuJ=7cA2T-mSTJD3tWSW2aEB6G=0Tz4X+iHcZQ@mail.gmail.com>
References: <20211214040239.8977-1-steven_lee@aspeedtech.com>
 <20211214040239.8977-2-steven_lee@aspeedtech.com>
 <CAMRc=MdAgK7zKuJ=7cA2T-mSTJD3tWSW2aEB6G=0Tz4X+iHcZQ@mail.gmail.com>
Message-ID: <CAMRc=McjZZTMjR+riwjj6SLEh=fYq0yjBQYNgzGXHok6=OTz_w@mail.gmail.com>

On Wed, Dec 22, 2021 at 10:18 AM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Tue, Dec 14, 2021 at 5:03 AM Steven Lee <steven_lee at aspeedtech.com> wrote:
> >
> > Each aspeed sgpio bank has 64 gpio pins(32 input pins and 32 output pins).
> > The hwirq base for each sgpio bank should be multiples of 64 rather than
> > multiples of 32.
> >
> > Signed-off-by: Steven Lee <steven_lee at aspeedtech.com>
> > ---
> >  drivers/gpio/gpio-aspeed-sgpio.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
> > index 3d6ef37a7702..b3a9b8488f11 100644
> > --- a/drivers/gpio/gpio-aspeed-sgpio.c
> > +++ b/drivers/gpio/gpio-aspeed-sgpio.c
> > @@ -395,7 +395,7 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
> >                 reg = ioread32(bank_reg(data, bank, reg_irq_status));
> >
> >                 for_each_set_bit(p, &reg, 32)
> > -                       generic_handle_domain_irq(gc->irq.domain, i * 32 + p * 2);
> > +                       generic_handle_domain_irq(gc->irq.domain, (i * 32 + p) * 2);
> >         }
> >
> >         chained_irq_exit(ic, desc);
> > --
> > 2.17.1
> >
>
> Joel, Andrew: any comments on this? I'd like to send it upstream tomorrow.
>
> Bart

I don't want to delay it anymore, it looks good so I queued it for fixes.

Bart


From david at redhat.com  Mon Jan  3 01:55:36 2022
From: david at redhat.com (David Hildenbrand)
Date: Mon, 3 Jan 2022 10:55:36 +0100
Subject: [PATCH V2] arm64/mm/hotplug: Warn when memory limit has been
 reduced
In-Reply-To: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>
References: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <bd3f2157-858c-b091-0982-12c425b2029a@redhat.com>

On 03.01.22 07:21, Anshuman Khandual wrote:
> If the max memory limit has been reduced with 'mem=' kernel command line
> option, there might be UEFI memory map described memory beyond that limit
> which could be hot removed. This might be problematic for subsequent kexec
> kernel which could just access such removed memory.
> 
> Memory offline notifier exists because there is no other way to block the
> removal of boot memory, only the offlining (which isn't actually a problem)
> But with 'mem=', there is no chance to stop such boot memory being offlined
> as it where never in use by the kernel. As 'mem=' is a debug only option on
> arm64 platform, just warn for such a situation and move on.
> 

Hi,

but why warn on the offlining path?

IIUC, you'd have a layout like


[ boot memory ][ unused memory ]
               ^memory_limit

Let's assume "unused memory" corresponds to exactly one DIMM that can
get hotunplugged. The complete DIMM isn't added to Linux and not online,
so the offline notifier will never trigger.

Via which mechanism would the unplug of that memory happen? On arm64,
this should only be possible via ACPI, when unplugging a DIMM that was
available since boot.

But won't acpi_memory_enable_device() try adding that memory while
ignoring the memory limit? And adding should work, no?

Can you share some details on how to trigger this on arm64?

-- 
Thanks,

David / dhildenb



From angelogioacchino.delregno at collabora.com  Mon Jan  3 02:18:53 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 11:18:53 +0100
Subject: [PATCH 1/3] pinctrl: mediatek: pinctrl-moore: Simplify with
 dev_err_probe()
Message-ID: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>

Use the dev_err_probe() helper to simplify error handling during probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/pinctrl/mediatek/pinctrl-moore.c | 25 +++++++++---------------
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-moore.c b/drivers/pinctrl/mediatek/pinctrl-moore.c
index ad3b67163973..8531206159b7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-moore.c
+++ b/drivers/pinctrl/mediatek/pinctrl-moore.c
@@ -606,6 +606,7 @@ static int mtk_build_functions(struct mtk_pinctrl *hw)
 int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 			    const struct mtk_pin_soc *soc)
 {
+	struct device *dev = &pdev->dev;
 	struct pinctrl_pin_desc *pins;
 	struct mtk_pinctrl *hw;
 	int err, i;
@@ -617,11 +618,9 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 	hw->soc = soc;
 	hw->dev = &pdev->dev;
 
-	if (!hw->soc->nbase_names) {
-		dev_err(&pdev->dev,
+	if (!hw->soc->nbase_names)
+		return dev_err_probe(dev, -EINVAL,
 			"SoC should be assigned at least one register base\n");
-		return -EINVAL;
-	}
 
 	hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
 				      sizeof(*hw->base), GFP_KERNEL);
@@ -666,17 +665,13 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 
 	/* Setup groups descriptions per SoC types */
 	err = mtk_build_groups(hw);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to build groups\n");
-		return err;
-	}
+	if (err)
+		return dev_err_probe(dev, err, "Failed to build groups\n");
 
 	/* Setup functions descriptions per SoC types */
 	err = mtk_build_functions(hw);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to build functions\n");
-		return err;
-	}
+	if (err)
+		return dev_err_probe(dev, err, "Failed to build functions\n");
 
 	/* For able to make pinctrl_claim_hogs, we must not enable pinctrl
 	 * until all groups and functions are being added one.
@@ -692,10 +687,8 @@ int mtk_moore_pinctrl_probe(struct platform_device *pdev,
 
 	/* Build gpiochip should be after pinctrl_enable is done */
 	err = mtk_build_gpiochip(hw, pdev->dev.of_node);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to add gpio_chip\n");
-		return err;
-	}
+	if (err)
+		return dev_err_probe(dev, err, "Failed to add gpio_chip\n");
 
 	platform_set_drvdata(pdev, hw);
 
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 02:18:54 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 11:18:54 +0100
Subject: [PATCH 2/3] pinctrl: mediatek: pinctrl-paris: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103101855.17350-2-angelogioacchino.delregno@collabora.com>

Use the dev_err_probe() helper to simplify error handling during probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 19 +++++++------------
 1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 4c6f6d967b18..70849d393917 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -956,6 +956,7 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
 int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 			    const struct mtk_pin_soc *soc)
 {
+	struct device *dev = &pdev->dev;
 	struct pinctrl_pin_desc *pins;
 	struct mtk_pinctrl *hw;
 	int err, i;
@@ -968,11 +969,9 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 	hw->soc = soc;
 	hw->dev = &pdev->dev;
 
-	if (!hw->soc->nbase_names) {
-		dev_err(&pdev->dev,
+	if (!hw->soc->nbase_names)
+		return dev_err_probe(dev, -EINVAL,
 			"SoC should be assigned at least one register base\n");
-		return -EINVAL;
-	}
 
 	hw->base = devm_kmalloc_array(&pdev->dev, hw->soc->nbase_names,
 				      sizeof(*hw->base), GFP_KERNEL);
@@ -997,10 +996,8 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 	spin_lock_init(&hw->lock);
 
 	err = mtk_pctrl_build_state(pdev);
-	if (err) {
-		dev_err(&pdev->dev, "build state failed: %d\n", err);
-		return -EINVAL;
-	}
+	if (err)
+		return dev_err_probe(dev, err, "build state failed\n");
 
 	/* Copy from internal struct mtk_pin_desc to register to the core */
 	pins = devm_kmalloc_array(&pdev->dev, hw->soc->npins, sizeof(*pins),
@@ -1038,10 +1035,8 @@ int mtk_paris_pinctrl_probe(struct platform_device *pdev,
 
 	/* Build gpiochip should be after pinctrl_enable is done */
 	err = mtk_build_gpiochip(hw, pdev->dev.of_node);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to add gpio_chip\n");
-		return err;
-	}
+	if (err)
+		return dev_err_probe(dev, err, "Failed to add gpio_chip\n");
 
 	platform_set_drvdata(pdev, hw);
 
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 02:18:55 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 11:18:55 +0100
Subject: [PATCH 3/3] pinctrl: mediatek: pinctrl-mtk-common: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103101855.17350-3-angelogioacchino.delregno@collabora.com>

Use the dev_err_probe() helper to simplify error handling during probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 25 ++++++++-----------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index 5f7c421ab6e7..6f8dfa6ae5a0 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -1013,10 +1013,12 @@ static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
 	return mtk_eint_do_init(pctl->eint);
 }
 
+/* This is used as a common probe function */
 int mtk_pctrl_init(struct platform_device *pdev,
 		const struct mtk_pinctrl_devdata *data,
 		struct regmap *regmap)
 {
+	struct device *dev = &pdev->dev;
 	struct pinctrl_pin_desc *pins;
 	struct mtk_pinctrl *pctl;
 	struct device_node *np = pdev->dev.of_node, *node;
@@ -1030,10 +1032,9 @@ int mtk_pctrl_init(struct platform_device *pdev,
 	platform_set_drvdata(pdev, pctl);
 
 	prop = of_find_property(np, "pins-are-numbered", NULL);
-	if (!prop) {
-		dev_err(&pdev->dev, "only support pins-are-numbered format\n");
-		return -EINVAL;
-	}
+	if (!prop)
+		return dev_err_probe(dev, -EINVAL,
+				     "only support pins-are-numbered format\n");
 
 	node = of_parse_phandle(np, "mediatek,pctl-regmap", 0);
 	if (node) {
@@ -1043,8 +1044,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
 	} else if (regmap) {
 		pctl->regmap1  = regmap;
 	} else {
-		dev_err(&pdev->dev, "Pinctrl node has not register regmap.\n");
-		return -EINVAL;
+		return dev_err_probe(dev, -EINVAL, "Cannot find pinctrl regmap.\n");
 	}
 
 	/* Only 8135 has two base addr, other SoCs have only one. */
@@ -1057,10 +1057,8 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	pctl->devdata = data;
 	ret = mtk_pctrl_build_state(pdev);
-	if (ret) {
-		dev_err(&pdev->dev, "build state failed: %d\n", ret);
-		return -EINVAL;
-	}
+	if (ret)
+		return dev_err_probe(dev, ret, "build state failed\n");
 
 	pins = devm_kcalloc(&pdev->dev, pctl->devdata->npins, sizeof(*pins),
 			    GFP_KERNEL);
@@ -1081,10 +1079,9 @@ int mtk_pctrl_init(struct platform_device *pdev,
 
 	pctl->pctl_dev = devm_pinctrl_register(&pdev->dev, &pctl->pctl_desc,
 					       pctl);
-	if (IS_ERR(pctl->pctl_dev)) {
-		dev_err(&pdev->dev, "couldn't register pinctrl driver\n");
-		return PTR_ERR(pctl->pctl_dev);
-	}
+	if (IS_ERR(pctl->pctl_dev))
+		return dev_err_probe(dev, PTR_ERR(pctl->pctl_dev),
+				     "Couldn't register pinctrl driver\n");
 
 	pctl->chip = devm_kzalloc(&pdev->dev, sizeof(*pctl->chip), GFP_KERNEL);
 	if (!pctl->chip)
-- 
2.33.1



From narmstrong at baylibre.com  Mon Jan  3 03:22:26 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 12:22:26 +0100
Subject: [PATCH 2/2] drm/meson: Fix error handling when afbcd.ops->init
 fails
In-Reply-To: <20211230235515.1627522-3-martin.blumenstingl@googlemail.com>
References: <20211230235515.1627522-1-martin.blumenstingl@googlemail.com>
 <20211230235515.1627522-3-martin.blumenstingl@googlemail.com>
Message-ID: <386f5be4-eca0-6117-82f5-317b82ee66a7@baylibre.com>

On 31/12/2021 00:55, Martin Blumenstingl wrote:
> When afbcd.ops->init fails we need to free the struct drm_device. Also
> all errors which come after afbcd.ops->init was successful need to exit
> the AFBCD, just like meson_drv_unbind() does.
> 
> Fixes: d1b5e41e13a7e9 ("drm/meson: Add AFBCD module driver")
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
>  drivers/gpu/drm/meson/meson_drv.c | 19 +++++++++++--------
>  1 file changed, 11 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index b919271a6e50..26aeaf0ab86e 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -302,42 +302,42 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>  	if (priv->afbcd.ops) {
>  		ret = priv->afbcd.ops->init(priv);
>  		if (ret)
> -			return ret;
> +			goto free_drm;
>  	}
>  
>  	/* Encoder Initialization */
>  
>  	ret = meson_encoder_cvbs_init(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	if (has_components) {
>  		ret = component_bind_all(drm->dev, drm);
>  		if (ret) {
>  			dev_err(drm->dev, "Couldn't bind all components\n");
> -			goto free_drm;
> +			goto exit_afbcd;
>  		}
>  	}
>  
>  	ret = meson_encoder_hdmi_init(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_plane_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_overlay_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = meson_crtc_create(priv);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	ret = request_irq(priv->vsync_irq, meson_irq, 0, drm->driver->name, drm);
>  	if (ret)
> -		goto free_drm;
> +		goto exit_afbcd;
>  
>  	drm_mode_config_reset(drm);
>  
> @@ -355,6 +355,9 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>  
>  uninstall_irq:
>  	free_irq(priv->vsync_irq, drm);
> +exit_afbcd:
> +	if (priv->afbcd.ops)
> +		priv->afbcd.ops->exit(priv);
>  free_drm:
>  	drm_dev_put(drm);
>  
> 

Acked-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,

But this depends on patch 1, so I'll add the same Fixes tag on patch 1 and add to drm-misc-next so it won't pollute -fixes but will still be eventually be backported when landing on linus master.

Neil


From narmstrong at baylibre.com  Mon Jan  3 03:24:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 12:24:01 +0100
Subject: [PATCH 1/2] drm/meson: osd_afbcd: Add an exit callback to struct
 meson_afbcd_ops
In-Reply-To: <20211230235515.1627522-2-martin.blumenstingl@googlemail.com>
References: <20211230235515.1627522-1-martin.blumenstingl@googlemail.com>
 <20211230235515.1627522-2-martin.blumenstingl@googlemail.com>
Message-ID: <4a4b40fd-b9d7-b38d-b4d4-4aaaf03693f2@baylibre.com>

On 31/12/2021 00:55, Martin Blumenstingl wrote:
> Use this to simplify the driver shutdown. It will also come handy when
> fixing the error handling in meson_drv_bind_master().
> 
> Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> ---
>  drivers/gpu/drm/meson/meson_drv.c       |  6 ++--
>  drivers/gpu/drm/meson/meson_osd_afbcd.c | 41 ++++++++++++++++---------
>  drivers/gpu/drm/meson/meson_osd_afbcd.h |  1 +
>  3 files changed, 30 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 80f1d439841a..b919271a6e50 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -385,10 +385,8 @@ static void meson_drv_unbind(struct device *dev)
>  	free_irq(priv->vsync_irq, drm);
>  	drm_dev_put(drm);
>  
> -	if (priv->afbcd.ops) {
> -		priv->afbcd.ops->reset(priv);
> -		meson_rdma_free(priv);
> -	}
> +	if (priv->afbcd.ops)
> +		priv->afbcd.ops->exit(priv);
>  }
>  
>  static const struct component_master_ops meson_drv_master_ops = {
> diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.c b/drivers/gpu/drm/meson/meson_osd_afbcd.c
> index ffc6b584dbf8..0cdbe899402f 100644
> --- a/drivers/gpu/drm/meson/meson_osd_afbcd.c
> +++ b/drivers/gpu/drm/meson/meson_osd_afbcd.c
> @@ -79,11 +79,6 @@ static bool meson_gxm_afbcd_supported_fmt(u64 modifier, uint32_t format)
>  	return meson_gxm_afbcd_pixel_fmt(modifier, format) >= 0;
>  }
>  
> -static int meson_gxm_afbcd_init(struct meson_drm *priv)
> -{
> -	return 0;
> -}
> -
>  static int meson_gxm_afbcd_reset(struct meson_drm *priv)
>  {
>  	writel_relaxed(VIU_SW_RESET_OSD1_AFBCD,
> @@ -93,6 +88,16 @@ static int meson_gxm_afbcd_reset(struct meson_drm *priv)
>  	return 0;
>  }
>  
> +static int meson_gxm_afbcd_init(struct meson_drm *priv)
> +{
> +	return 0;
> +}
> +
> +static void meson_gxm_afbcd_exit(struct meson_drm *priv)
> +{
> +	meson_gxm_afbcd_reset(priv);
> +}
> +
>  static int meson_gxm_afbcd_enable(struct meson_drm *priv)
>  {
>  	writel_relaxed(FIELD_PREP(OSD1_AFBCD_ID_FIFO_THRD, 0x40) |
> @@ -172,6 +177,7 @@ static int meson_gxm_afbcd_setup(struct meson_drm *priv)
>  
>  struct meson_afbcd_ops meson_afbcd_gxm_ops = {
>  	.init = meson_gxm_afbcd_init,
> +	.exit = meson_gxm_afbcd_exit,
>  	.reset = meson_gxm_afbcd_reset,
>  	.enable = meson_gxm_afbcd_enable,
>  	.disable = meson_gxm_afbcd_disable,
> @@ -269,6 +275,18 @@ static bool meson_g12a_afbcd_supported_fmt(u64 modifier, uint32_t format)
>  	return meson_g12a_afbcd_pixel_fmt(modifier, format) >= 0;
>  }
>  
> +static int meson_g12a_afbcd_reset(struct meson_drm *priv)
> +{
> +	meson_rdma_reset(priv);
> +
> +	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
> +			       VIU_SW_RESET_G12A_OSD1_AFBCD,
> +			       VIU_SW_RESET);
> +	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
> +
> +	return 0;
> +}
> +
>  static int meson_g12a_afbcd_init(struct meson_drm *priv)
>  {
>  	int ret;
> @@ -286,16 +304,10 @@ static int meson_g12a_afbcd_init(struct meson_drm *priv)
>  	return 0;
>  }
>  
> -static int meson_g12a_afbcd_reset(struct meson_drm *priv)
> +static void meson_g12a_afbcd_exit(struct meson_drm *priv)
>  {
> -	meson_rdma_reset(priv);
> -
> -	meson_rdma_writel_sync(priv, VIU_SW_RESET_G12A_AFBC_ARB |
> -			       VIU_SW_RESET_G12A_OSD1_AFBCD,
> -			       VIU_SW_RESET);
> -	meson_rdma_writel_sync(priv, 0, VIU_SW_RESET);
> -
> -	return 0;
> +	meson_g12a_afbcd_reset(priv);
> +	meson_rdma_free(priv);
>  }
>  
>  static int meson_g12a_afbcd_enable(struct meson_drm *priv)
> @@ -380,6 +392,7 @@ static int meson_g12a_afbcd_setup(struct meson_drm *priv)
>  
>  struct meson_afbcd_ops meson_afbcd_g12a_ops = {
>  	.init = meson_g12a_afbcd_init,
> +	.exit = meson_g12a_afbcd_exit,
>  	.reset = meson_g12a_afbcd_reset,
>  	.enable = meson_g12a_afbcd_enable,
>  	.disable = meson_g12a_afbcd_disable,
> diff --git a/drivers/gpu/drm/meson/meson_osd_afbcd.h b/drivers/gpu/drm/meson/meson_osd_afbcd.h
> index 5e5523304f42..e77ddeb6416f 100644
> --- a/drivers/gpu/drm/meson/meson_osd_afbcd.h
> +++ b/drivers/gpu/drm/meson/meson_osd_afbcd.h
> @@ -14,6 +14,7 @@
>  
>  struct meson_afbcd_ops {
>  	int (*init)(struct meson_drm *priv);
> +	void (*exit)(struct meson_drm *priv);
>  	int (*reset)(struct meson_drm *priv);
>  	int (*enable)(struct meson_drm *priv);
>  	int (*disable)(struct meson_drm *priv);
> 

Acked-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks for fixing this

Neil



From vkoul at kernel.org  Mon Jan  3 03:30:20 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 3 Jan 2022 17:00:20 +0530
Subject: [PATCH 1/1] dmaengine: stm32-mdma: fix STM32_MDMA_CTBR_TSEL_MASK
In-Reply-To: <20211220165827.1238097-1-amelie.delaunay@foss.st.com>
References: <20211220165827.1238097-1-amelie.delaunay@foss.st.com>
Message-ID: <YdLeTC+H92xZHi77@matsya>

On 20-12-21, 17:58, Amelie Delaunay wrote:
> This patch fixes STM32_MDMA_CTBR_TSEL_MASK, which is [5:0], not [7:0].

Applied, thanks

-- 
~Vinod


From shawnguo at kernel.org  Mon Jan  3 03:30:44 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Mon, 3 Jan 2022 19:30:44 +0800
Subject: [PATCH v2 devicetree] Revert "arm64: dts: freescale: Fix
 'interrupt-map' parent address cells"
In-Reply-To: <c5b9cec617100b891b7fceaee8655ba8@kernel.org>
References: <20211214135852.2934670-1-vladimir.oltean@nxp.com>
 <20211231181350.qwfnrwvdfnfssdjt@skbuf>
 <c5b9cec617100b891b7fceaee8655ba8@kernel.org>
Message-ID: <20220103113043.GA14690@dragon>

On Sun, Jan 02, 2022 at 01:08:28PM +0000, Marc Zyngier wrote:
> On 2021-12-31 18:13, Vladimir Oltean wrote:
> > Hello,
> > 
> > On Tue, Dec 14, 2021 at 03:58:52PM +0200, Vladimir Oltean wrote:
> > > This reverts commit 869f0ec048dc8fd88c0b2003373bd985795179fb. That
> > > updated the expected device tree binding format for the ls-extirq
> > > driver, without also updating the parsing code (ls_extirq_parse_map)
> > > to the new format.
> > > 
> > > The context is that the ls-extirq driver uses the standard
> > > "interrupt-map" OF property in a non-standard way, as suggested by
> > > Rob Herring during review:
> > > https://lore.kernel.org/lkml/20190927161118.GA19333 at bogus/
> > > 
> > > This has turned out to be problematic, as Marc Zyngier discovered
> > > through commit 041284181226 ("of/irq: Allow matching of an
> > > interrupt-map
> > > local to an interrupt controller"), later fixed through commit
> > > de4adddcbcc2 ("of/irq: Add a quirk for controllers with their own
> > > definition of interrupt-map"). Marc's position, expressed on multiple
> > > opportunities, is that:
> > > 
> > > (a) [ making private use of the reserved "interrupt-map" name in a
> > >     driver ] "is wrong, by the very letter of what an interrupt-map
> > >     means. If the interrupt map points to an interrupt controller,
> > >     that's the target for the interrupt."
> > > https://lore.kernel.org/lkml/87k0g8jlmg.wl-maz at kernel.org/
> > > 
> > > (b) [ updating the driver's bindings to accept a non-reserved name for
> > >     this property, as an alternative, is ] "is totally pointless.
> > > These
> > >     machines have been in the wild for years, and existing DTs will be
> > >     there *forever*."
> > > https://lore.kernel.org/lkml/87ilvrk1r0.wl-maz at kernel.org/
> > > 
> > > Considering the above, the Linux kernel has quirks in place to deal
> > > with
> > > the ls-extirq's non-standard use of the "interrupt-map". These quirks
> > > may be needed in other operating systems that consume this device
> > > tree,
> > > yet this is seen as the only viable solution.
> > > 
> > > Therefore, the premise of the patch being reverted here is invalid.
> > > It doesn't matter whether the driver, in its non-standard use of the
> > > property, complies to the standard format or not, since this property
> > > isn't expected to be used for interrupt translation by the core.
> > > 
> > > This change restores LS1088A, LS2088A/LS2085A and LX2160A to their
> > > previous bindings, which allows these systems to continue to use
> > > external interrupt lines with the correct polarity.
> > > 
> > > Fixes: 869f0ec048dc ("arm64: dts: freescale: Fix 'interrupt-map'
> > > parent address cells")
> > > Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> > > ---
> > > v1->v2: remove the other 9 patches that rename "interrupt-map" to
> > >         "fsl,extirq-map", at Marc's suggestion.
> > 
> > Could this patch be considered for merging in v5.16? The problem is
> > going to be quite a bit more severe and tricky to fix otherwise. Thanks.
> 
> FWIW:
> 
> Acked-by: Marc Zyngier <maz at kernel.org>
> 
> Rob, Shawn, can you please queue this as an urgent fix for 5.16?

I would rather leave this to Rob, as I haven't heard anything from him
on this reverting (on his commit).

Shawn


From clabbe.montjoie at gmail.com  Mon Jan  3 03:42:58 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 3 Jan 2022 12:42:58 +0100
Subject: [PATCH v6] sun4i-emac.c: add dma support
In-Reply-To: <tencent_67023336008FE777A58293D2D32DEFA69107@qq.com>
References: <20211228164817.1297c1c9@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
 <Yc7e6V9/oioEpx8c@Red>
 <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
 <YdHjK+/SzaeI/V2Q@Red>
 <tencent_67023336008FE777A58293D2D32DEFA69107@qq.com>
Message-ID: <YdLhQjUTobcLq73j@Red>

Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a ?crit :
> On 01/02/22 at 06:38??, Corentin Labbe wrote:
> > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > From: Corentin Labbe <clabbe.montjoie at gmail.com>
> > To: Conley Lee <conleylee at foxmail.com>
> > Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
> >  wens at csie.org, netdev at vger.kernel.org,
> >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
> >  linux-sunxi at lists.linux.dev, jernej.skrabec at gmail.com
> > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > 
> > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a ?crit :
> > > On 12/31/21 at 11:43??, Corentin Labbe wrote:
> > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > From: Corentin Labbe <clabbe.montjoie at gmail.com>
> > > > To: conleylee at foxmail.com
> > > > Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
> > > >  wens at csie.org, netdev at vger.kernel.org,
> > > >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > 
> > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee at foxmail.com a ?crit :
> > > > > From: Conley Lee <conleylee at foxmail.com>
> > > > > 
> > > > > Thanks for your review. Here is the new version for this patch.
> > > > > 
> > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > 
> > > > > Change since v4.
> > > > >   - rename sbk field to skb
> > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > >     sleeping
> > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > >   - fix some code style issues 
> > > > > 
> > > > > Change since v5.
> > > > >   - fix some code style issue
> > > > > 
> > > > 
> > > > Hello
> > > > 
> > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > 
> > > > I got:
> > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > 
> > > > On which board did you test it and how ?
> > > > 
> > > > Regards
> > > 
> > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > 
> > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > should be added to emac section in dts:
> > > 
> > > emac: ethernet at 1c0b000 {
> > > 	...
> > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > 	dma-names = "rx";
> > > 	...
> > > }
> > 
> > Helo
> > 
> > Yes I figured that out. But you should have done a patch serie adding this.
> > Your patch is now applied but it is a useless change without the dtb change.
> > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > 
> > Furthermore, why did you add RX only and not TX dma also ?
> > 
> > Probably it is too late since patch is applied but it is:
> > Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
> > Tested-on: sun4i-a10-olinuxino-lime
> > 
> > Regards
> 
> Thanks for your suggestion. I will submit a patch to add those changes
> later. 
> 
> And the reason why I didn't add TX support is becasuse there is no any
> public page to describe sun4i emac TX DMA register map. So, I don't known
> how to enable TX DMA at hardware level. If you has any page or datasheet
> about EMAC TX DMA, can you share with me ? Thanks.

Hello

You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)

You should keep all people in CC when you answer to someone.

Regards


From linus.walleij at linaro.org  Mon Jan  3 04:05:59 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Mon, 3 Jan 2022 13:05:59 +0100
Subject: [PATCH] arm: pxa: remove dead and obsolete IrDA initialization
In-Reply-To: <20211229184854.3466-1-lukas.bulwahn@gmail.com>
References: <20211229184854.3466-1-lukas.bulwahn@gmail.com>
Message-ID: <CACRpkdZCnbBvzo6KkAQa3T793OVt680DLGrKx6b1OrmeCvKneg@mail.gmail.com>

On Wed, Dec 29, 2021 at 7:51 PM Lukas Bulwahn <lukas.bulwahn at gmail.com> wrote:

> Commit d64c2a76123f ("staging: irda: remove the irda network stack and
> drivers") removes the Intel PXA2xx Internal FICP driver, and the config
> PXA_FICP and the config IRDA.
>
> Further, this removes any proper effect from the setup functions in the
> file ./include/linux/platform_data/irda-pxaficp.h. So, delete all users
> in arch/arm/mach-pxa/ and this header file.
>
> Clean up radically various left-over of IRDA in the ./arch/arm/mach-pxa.
>
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>

I see there is some noise from the kernel test robot about some missed
lines of code, but with this fixed:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

IIUC the future for IrDA is in BPF for the people who want it, so if someone
wants this they need to go and fix it that way.

Yours,
Linus Walleij


From vkoul at kernel.org  Mon Jan  3 04:19:45 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Mon, 3 Jan 2022 17:49:45 +0530
Subject: [PATCH] dmaengine: uniphier-xdmac: Fix type of address variables
In-Reply-To: <1639456963-10232-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1639456963-10232-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <YdLp4Qz+j9BRPzah@matsya>

On 14-12-21, 13:42, Kunihiko Hayashi wrote:
> The variables src_addr and dst_addr handle DMA addresses, so these should
> be declared as dma_addr_t.

Applied, thanks

-- 
~Vinod


From conleylee at foxmail.com  Mon Jan  3 04:21:25 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Mon, 3 Jan 2022 20:21:25 +0800
Subject: [PATCH v6] sun4i-emac.c: add dma support
In-Reply-To: <YdLhQjUTobcLq73j@Red>
References: <20211228164817.1297c1c9@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
 <Yc7e6V9/oioEpx8c@Red>
 <tencent_57960DDC83F43DA3E0A2F47DEBAD69A4A005@qq.com>
 <YdHjK+/SzaeI/V2Q@Red>
 <tencent_67023336008FE777A58293D2D32DEFA69107@qq.com>
 <YdLhQjUTobcLq73j@Red>
Message-ID: <tencent_E30BB769A8609EADCF03F1FDA7C0AF146205@qq.com>

On 01/03/22 at 12:42??, Corentin Labbe wrote:
> Date: Mon, 3 Jan 2022 12:42:58 +0100
> From: Corentin Labbe <clabbe.montjoie at gmail.com>
> To: Conley Lee <conleylee at foxmail.com>
> Cc: davem at davemloft.net, mripard at kernel.org, wens at csie.org,
>  jernej.skrabec at gmail.com, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-sunxi at lists.linux.dev,
>  linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> 
> Le Mon, Jan 03, 2022 at 10:55:04AM +0800, Conley Lee a ?crit :
> > On 01/02/22 at 06:38??, Corentin Labbe wrote:
> > > Date: Sun, 2 Jan 2022 18:38:51 +0100
> > > From: Corentin Labbe <clabbe.montjoie at gmail.com>
> > > To: Conley Lee <conleylee at foxmail.com>
> > > Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
> > >  wens at csie.org, netdev at vger.kernel.org,
> > >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
> > >  linux-sunxi at lists.linux.dev, jernej.skrabec at gmail.com
> > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > 
> > > Le Sat, Jan 01, 2022 at 03:09:01PM +0800, Conley Lee a ?crit :
> > > > On 12/31/21 at 11:43??, Corentin Labbe wrote:
> > > > > Date: Fri, 31 Dec 2021 11:43:53 +0100
> > > > > From: Corentin Labbe <clabbe.montjoie at gmail.com>
> > > > > To: conleylee at foxmail.com
> > > > > Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
> > > > >  wens at csie.org, netdev at vger.kernel.org,
> > > > >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> > > > > Subject: Re: [PATCH v6] sun4i-emac.c: add dma support
> > > > > 
> > > > > Le Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee at foxmail.com a ?crit :
> > > > > > From: Conley Lee <conleylee at foxmail.com>
> > > > > > 
> > > > > > Thanks for your review. Here is the new version for this patch.
> > > > > > 
> > > > > > This patch adds support for the emac rx dma present on sun4i. The emac
> > > > > > is able to move packets from rx fifo to RAM by using dma.
> > > > > > 
> > > > > > Change since v4.
> > > > > >   - rename sbk field to skb
> > > > > >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> > > > > >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> > > > > >     sleeping
> > > > > >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> > > > > >   - fix some code style issues 
> > > > > > 
> > > > > > Change since v5.
> > > > > >   - fix some code style issue
> > > > > > 
> > > > > 
> > > > > Hello
> > > > > 
> > > > > I just tested this on a sun4i-a10-olinuxino-lime
> > > > > 
> > > > > I got:
> > > > > [    2.922812] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): get io resource from device: 0x1c0b000, size = 4096
> > > > > [    2.934512] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): failed to request dma channel. dma is disabled
> > > > > [    2.945740] sun4i-emac 1c0b000.ethernet (unnamed net_device) (uninitialized): configure dma failed. disable dma.
> > > > > [    2.957887] sun4i-emac 1c0b000.ethernet: eth0: at (ptrval), IRQ 19 MAC: 02:49:09:40:ab:3d
> > > > > 
> > > > > On which board did you test it and how ?
> > > > > 
> > > > > Regards
> > > > 
> > > > Sorry. I sent the email with text/html format. This email is an clean version.
> > > > 
> > > > In order to enable dma rx channel. `dmas` and `dma-names` properties
> > > > should be added to emac section in dts:
> > > > 
> > > > emac: ethernet at 1c0b000 {
> > > > 	...
> > > > 	dmas = <&dma SUN4I_DMA_DEDICATED 7>;
> > > > 	dma-names = "rx";
> > > > 	...
> > > > }
> > > 
> > > Helo
> > > 
> > > Yes I figured that out. But you should have done a patch serie adding this.
> > > Your patch is now applied but it is a useless change without the dtb change.
> > > You should also probably update the driver binding (Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml) since you add new members to DT node.
> > > 
> > > Furthermore, why did you add RX only and not TX dma also ?
> > > 
> > > Probably it is too late since patch is applied but it is:
> > > Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
> > > Tested-on: sun4i-a10-olinuxino-lime
> > > 
> > > Regards
> > 
> > Thanks for your suggestion. I will submit a patch to add those changes
> > later. 
> > 
> > And the reason why I didn't add TX support is becasuse there is no any
> > public page to describe sun4i emac TX DMA register map. So, I don't known
> > how to enable TX DMA at hardware level. If you has any page or datasheet
> > about EMAC TX DMA, can you share with me ? Thanks.
> 
> Hello
> 
> You can find TX DMA info on the R40 Use manual (8.10.5.2 Register Name: EMAC_TX_MODE)
> 
> You should keep all people in CC when you answer to someone.
> 
> Regards

Haha, got it! I have been looking for the docs about emac register map
for a long time. You really help me a lot. I will submit a new patch to
add driver bidding and enable both RX and TX channels. Thanks ~


From anshuman.khandual at arm.com  Mon Jan  3 04:22:29 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 3 Jan 2022 17:52:29 +0530
Subject: [PATCH V2] arm64/mm/hotplug: Warn when memory limit has been
 reduced
In-Reply-To: <bd3f2157-858c-b091-0982-12c425b2029a@redhat.com>
References: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>
 <bd3f2157-858c-b091-0982-12c425b2029a@redhat.com>
Message-ID: <c4104b5d-45b8-732a-45e9-0a1cb4954dde@arm.com>



On 1/3/22 3:25 PM, David Hildenbrand wrote:
> On 03.01.22 07:21, Anshuman Khandual wrote:
>> If the max memory limit has been reduced with 'mem=' kernel command line
>> option, there might be UEFI memory map described memory beyond that limit
>> which could be hot removed. This might be problematic for subsequent kexec
>> kernel which could just access such removed memory.
>>
>> Memory offline notifier exists because there is no other way to block the
>> removal of boot memory, only the offlining (which isn't actually a problem)
>> But with 'mem=', there is no chance to stop such boot memory being offlined
>> as it where never in use by the kernel. As 'mem=' is a debug only option on
>> arm64 platform, just warn for such a situation and move on.
>>
> 
> Hi,
> 
> but why warn on the offlining path?

The proposed change is just a one shot warning which is triggered during
the first memory offlining attempt, explaining potential kexec problems
as the kernel is already running on a trimmed boot memory.

> 
> IIUC, you'd have a layout like
> 
> 
> [ boot memory ][ unused memory ]
>                ^memory_limit

s/unused memory/unused boot memory/ instead as it is present during boot.

> 
> Let's assume "unused memory" corresponds to exactly one DIMM that can
> get hotunplugged. The complete DIMM isn't added to Linux and not online,
> so the offline notifier will never trigger.

Right, it will not trigger the warning. This proposal does not cover such
scenarios, where "unused memory" can just be "hotunplugged" without the
kernel knowing about it. But as the warning is not really dependent on
which exact memory is being offlined, user would still come to know if
there is an offlining attempt for any memory.

We probably might require another patch adding an warning when the boot
memory is trimmed with "mem=" cmdline, irrespective of hotplug support
in the kernel. It would ensure that the user is still warned about any
potential kexec problems, above scenario (i.e "unused memory" getting
"hotunplugged" without kernel knowing about it) might cause.

This patch just adds an warning in case there is an offlining attempt
on a hot-remove enabled kernel.

> 
> Via which mechanism would the unplug of that memory happen? On arm64,
> this should only be possible via ACPI, when unplugging a DIMM that was
> available since boot.
> 
> But won't acpi_memory_enable_device() try adding that memory while
> ignoring the memory limit? And adding should work, no?

Adding that memory via hotplug into the kernel first ? In that case
removal would still go via the kernel and user would know about it.

> 
> Can you share some details on how to trigger this on arm64?

The primary scenario this proposal is targeted towards is when boot
memory is set aside from the host, hot-plugged back into the kernel
and repurposed (via hotplug-hotremove path) for guest kernel usage.
This new warning would reassert that "mem=" cmdline option is debug
only on arm64 platform, and should not be used for production.


From chunkuang.hu at kernel.org  Mon Jan  3 04:39:15 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Mon, 3 Jan 2022 20:39:15 +0800
Subject: [PATCH v2] drm/mediatek: Set default value for Panel Orientation
 connector prop.
In-Reply-To: <20211229184420.793234-1-markyacoub@chromium.org>
References: <20211022172413.195559-1-markyacoub@chromium.org>
 <20211229184420.793234-1-markyacoub@chromium.org>
Message-ID: <CAAOTY_9E71AfKy_poZMA7s++TvzM4=VH0H1o8ZBmDphcz9iXDw@mail.gmail.com>

Hi, Mark:

Mark Yacoub <markyacoub at chromium.org> ? 2021?12?30? ?? ??2:44???
>
> [Why]
> Creating the prop uses UNKNOWN as the initial value, which is not a
> supported value if the prop is to be supported.
>
> [How]
> Set the panel orientation default value to NORMAL right after creating
> the prop if no DSI panel exists.
> Panels have their own orientations, and panel orientation can't be
> overriden once initialized to a value.
>
> v1:
> Set panel orientation only if DSI panel does not exist.
>
> Tested on Jacuzzi(MTK)
> Fixes IGT at kms_properties@get_properties-sanity-{atomic,non-atomic}
>
> Signed-off-by: Mark Yacoub <markyacoub at chromium.org>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 0ad7157660afa..9d33dd93118e0 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -1040,6 +1040,13 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>                 goto err_cleanup_encoder;
>         }
>
> +       /* A drm_panel can have its own orientation. If there is no panel, set the
> +        * orientation to NORMAL. */
> +       if (!dsi->panel) {

Please send patch based on latest kernel version. In latest kernel
version, struct mtk_dsi{} has no member 'panel'.

Regards,
Chun-Kuang.

> +               drm_connector_set_panel_orientation(
> +                       dsi->connector, DRM_MODE_PANEL_ORIENTATION_NORMAL);
> +       }
> +
>         drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>
>         return 0;
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From kavyasree.kotagiri at microchip.com  Mon Jan  3 04:48:57 2022
From: kavyasree.kotagiri at microchip.com (Kavyasree Kotagiri)
Date: Mon, 3 Jan 2022 18:18:57 +0530
Subject: [PATCH] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
Message-ID: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>

This patch adds basic DT for Microchip lan966x SoC and associated board
pcb8291(2-port EVB). Adds peripherals required to allow booting: IRQs,
clocks, timers, memory, flexcoms, GPIOs. Also adds other peripherals like
crypto(AES,SHA), DMA and watchdog.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
---
 arch/arm/boot/dts/Makefile            |   2 +
 arch/arm/boot/dts/lan966x.dtsi        | 235 ++++++++++++++++++++++++++
 arch/arm/boot/dts/lan966x_pcb8291.dts |  55 ++++++
 3 files changed, 292 insertions(+)
 create mode 100644 arch/arm/boot/dts/lan966x.dtsi
 create mode 100644 arch/arm/boot/dts/lan966x_pcb8291.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..dc1bd216ed58 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_LAN966) += \
+	lan966x_pcb8291.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
new file mode 100644
index 000000000000..7e56394b036f
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x.dtsi
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x.dtsi - Device Tree Include file for Microchip LAN966x family SoC
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/microchip,lan966x.h>
+
+/ {
+	model = "Microchip LAN966x family SoC";
+	compatible = "microchip,lan966x";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			clock-frequency = <600000000>;
+			reg = <0x0>;
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;  /* 1GB */
+	};
+
+	clocks {
+		sys_clk: sys_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <162500000>;
+		};
+
+		cpu_clk: cpu_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <600000000>;
+		};
+
+		ddr_clk: ddr_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <300000000>;
+		};
+
+		nic_clk: nic_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+		};
+	};
+
+	clks: clock-controller at e00c00a8 {
+		compatible = "microchip,lan966x-gck";
+		#clock-cells = <1>;
+		clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
+		clock-names = "cpu", "ddr", "sys";
+		reg = <0xe00c00a8 0x38>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <37500000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		flx0: flexcom at e0040000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0040000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0040000 0x800>;
+			status = "disabled";
+		};
+
+		flx1: flexcom at e0044000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0044000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0044000 0x800>;
+			status = "disabled";
+		};
+
+		trng: trng at e0048000 {
+			compatible = "atmel,at91sam9g45-trng";
+			reg = <0xe0048000 0x100>;
+			clocks = <&nic_clk>;
+			status = "disabled";
+		};
+
+		aes: aes at e004c000 {
+			compatible = "atmel,at91sam9g46-aes";
+			reg = <0xe004c000 0x100>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
+			       <&dma0 AT91_XDMAC_DT_PERID(12)>;
+			dma-names = "rx", "tx";
+			clocks = <&nic_clk>;
+			clock-names = "aes_clk";
+		};
+
+		flx2: flexcom at e0060000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0060000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0060000 0x800>;
+			status = "disabled";
+		};
+
+		flx3: flexcom at e0064000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0064000 0x100>,
+			      <0xe2004180 0x8>;
+			clocks = <&clks GCK_ID_FLEXCOM3>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0064000 0x800>;
+			status = "disabled";
+		      };
+
+		dma0: dma-controller at e0068000 {
+			compatible = "microchip,sama7g5-dma";
+			reg = <0xe0068000 0x1000>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&nic_clk>;
+			clock-names = "dma_clk";
+			status = "okay";
+		};
+
+		sha: sha at e006c000 {
+			compatible = "atmel,at91sam9g46-sha";
+			reg = <0xe006c000 0xec>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
+			dma-names = "tx";
+			clocks = <&nic_clk>;
+			clock-names = "sha_clk";
+		};
+
+		flx4: flexcom at e0070000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0070000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM4>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0070000 0x800>;
+			status = "disabled";
+		};
+
+		timer0: timer at e008c000 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0xe008c000 0x400>;
+			clocks = <&nic_clk>;
+			clock-names = "timer";
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		watchdog: watchdog at e0090000 {
+			compatible = "snps,dw-wdt";
+			reg = <0xe0090000 0x1000>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&nic_clk>;
+		};
+
+		can0: can at e081c000 {
+			compatible = "bosch,m_can";
+			reg = <0xe081c000 0xfc>, <0x00100000 0x4000>;
+			reg-names = "m_can", "message_ram";
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "int0", "int1";
+			clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
+			clock-names = "hclk", "cclk";
+			assigned-clocks = <&clks GCK_ID_MCAN0>;
+			assigned-clock-rates = <40000000>;
+			bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+			status = "disabled";
+		};
+
+		gpio: pinctrl at e2004064 {
+			compatible = "microchip,lan966x-pinctrl";
+			reg = <0xe2004064 0xb4>,
+			    <0xe2010024 0x138>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 78>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <2>;
+		};
+
+		gic: interrupt-controller at e8c11000 {
+			compatible = "arm,gic-400", "arm,cortex-a7-gic";
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			reg = <0xe8c11000 0x1000>,
+			      <0xe8c12000 0x2000>,
+			      <0xe8c14000 0x2000>,
+			      <0xe8c16000 0x2000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts b/arch/arm/boot/dts/lan966x_pcb8291.dts
new file mode 100644
index 000000000000..cd0454a795e7
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x_pcb8291.dts - Device Tree file for PCB8291
+ */
+/dts-v1/;
+#include "lan966x.dtsi"
+
+/ {
+	model = "Microchip EVB - LAN9662";
+	compatible = "microchip,lan9662-pcb8291", "microchip,lan9662", "microchip,lan966";
+};
+
+&gpio {
+	fc_shrd7_pins: fc_shrd7-pins {
+		pins = "GPIO_49";
+		function = "fc_shrd7";
+	};
+
+	fc_shrd8_pins: fc_shrd8-pins {
+		pins = "GPIO_54";
+		function = "fc_shrd8";
+	};
+
+	fc3_b_pins: fcb3-spi-pins {
+		/* SCK, RXD, TXD */
+		pins = "GPIO_51", "GPIO_52", "GPIO_53";
+		function = "fc3_b";
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	usart0: serial at 200 {
+		compatible = "atmel,at91sam9260-usart";
+		reg = <0x200 0x200>;
+		interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&nic_clk>;
+		clock-names = "usart";
+		pinctrl-0 = <&fc3_b_pins>, <&fc_shrd7_pins>, <&fc_shrd8_pins>;
+		pinctrl-names = "default";
+		atmel,fifo-size = <32>;
+		status = "okay";
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
-- 
2.17.1



From david at redhat.com  Mon Jan  3 04:57:28 2022
From: david at redhat.com (David Hildenbrand)
Date: Mon, 3 Jan 2022 13:57:28 +0100
Subject: [PATCH V2] arm64/mm/hotplug: Warn when memory limit has been
 reduced
In-Reply-To: <c4104b5d-45b8-732a-45e9-0a1cb4954dde@arm.com>
References: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>
 <bd3f2157-858c-b091-0982-12c425b2029a@redhat.com>
 <c4104b5d-45b8-732a-45e9-0a1cb4954dde@arm.com>
Message-ID: <d8753c88-95f3-75ec-d6b6-27105a9a5968@redhat.com>


>> Via which mechanism would the unplug of that memory happen? On arm64,
>> this should only be possible via ACPI, when unplugging a DIMM that was
>> available since boot.
>>
>> But won't acpi_memory_enable_device() try adding that memory while
>> ignoring the memory limit? And adding should work, no?
> 
> Adding that memory via hotplug into the kernel first ? In that case
> removal would still go via the kernel and user would know about it.

Can we please add details on how to actually trigger it (below) to the
patch description? Otherwise it's really hard to get about which senario
we do care, and about which we don't care.

> 
>>
>> Can you share some details on how to trigger this on arm64?
> 
> The primary scenario this proposal is targeted towards is when boot
> memory is set aside from the host, hot-plugged back into the kernel
> and repurposed (via hotplug-hotremove path) for guest kernel usage.
> This new warning would reassert that "mem=" cmdline option is debug
> only on arm64 platform, and should not be used for production.
Let me get this straight:

1. Restrict physical memory to use via "mem="

-> Some boot memory is !present and, therefore !early

2. Hotplug that memory to the kernel

-> How?

a) dax/kmem? Does not apply I think.
b) DIMM? Does not apply I think.
c) CONFIG_ARCH_MEMORY_PROBE ?

3. Trigger physical hotunplug and actually remove the memory

-> How?

4. kexec; will try using hotunplugged memory


-- 
Thanks,

David / dhildenb



From Tudor.Ambarus at microchip.com  Mon Jan  3 05:42:30 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Mon, 3 Jan 2022 13:42:30 +0000
Subject: [PATCH] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
In-Reply-To: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
References: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
Message-ID: <76804bd6-00e5-02ab-59df-d32586a55422@microchip.com>

Hi,

On 1/3/22 2:48 PM, Kavyasree Kotagiri wrote:
> diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts b/arch/arm/boot/dts/lan966x_pcb8291.dts
> new file mode 100644
> index 000000000000..cd0454a795e7
> --- /dev/null
> +++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
> @@ -0,0 +1,55 @@

> +&flx3 {
> +       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +       status = "okay";
> +
> +       usart0: serial at 200 {
> +               compatible = "atmel,at91sam9260-usart";

The flexcom usart mode should be defined in the dtsi file, so that you
won't duplicate the definition in each dts that includes the dtsi file.

Cheers,
ta

From jbrunet at baylibre.com  Mon Jan  3 04:40:28 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 13:40:28 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <20211230102110.3861-5-yu.tu@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
Message-ID: <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>


On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:

> Using the common Clock code to describe the UART baud rate clock makes
> it easier for the UART driver to be compatible with the baud rate
> requirements of the UART IP on different meson chips
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/Kconfig      |   1 +
>  drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>  2 files changed, 257 insertions(+), 55 deletions(-)
>
> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
> index 780908d43557..32e238173036 100644
> --- a/drivers/tty/serial/Kconfig
> +++ b/drivers/tty/serial/Kconfig
> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>  config SERIAL_MESON
>  	tristate "Meson serial port support"
>  	depends on ARCH_MESON
> +	depends on COMMON_CLK
>  	select SERIAL_CORE
>  	help
>  	  This enables the driver for the on-chip UARTs of the Amlogic
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 99efe62a1507..07eb1f40aaaa 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,21 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	struct clk_divider	baud_div;
> +	struct clk_mux		use_xtal_mux;
> +	struct clk_mux		xtal_clk_sel_mux;
> +	struct clk_mux		xtal2_clk_sel_mux;
> +	struct clk_fixed_factor	xtal_div2;
> +	struct clk_fixed_factor	xtal_div3;
> +	struct clk_fixed_factor	clk81_div4;

Keeping all these internal elements around is not useful since they are
registered using devm_

> +	bool			no_clk81_input;

What is this ?

> +	bool			has_xtal_clk_sel;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>  static int meson_uart_startup(struct uart_port *port)
>  {
>  	u32 val;
> -	int ret = 0;
> +	int ret;
>  
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>  
> +	val = readl(port->membase + AML_UART_CONTROL);
>  	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>  	writel(val, port->membase + AML_UART_CONTROL);
>  
> @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {

This check shows that previous code assumed bit 24 was left untouched
Below you can see that GXBB and newer used the XTAL path while older
used the other

Your change makes this dynamic which is another "unexpected" change.
Please make the bit 24 mux RO to start with so the behavior remains unchanged
for older SoCs.

> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +static int meson_uart_register_clk(struct uart_port *port,
> +				   const char *name_suffix,
> +				   const struct clk_parent_data *parent_data,
> +				   unsigned int num_parents,
> +				   const struct clk_ops *ops,
> +				   struct clk_hw *hw)
>  {
> -	struct clk *clk = NULL;
> +	struct clk_init_data init = { };
> +	char clk_name[32];
>  	int ret;
>  
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 name_suffix);
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> +	init.name = clk_name;
> +	init.ops = ops;
> +	init.flags = CLK_SET_RATE_PARENT;
> +	init.parent_data = parent_data;
> +	init.num_parents = num_parents;
> +
> +	hw->init = &init;
>  
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> +	ret = devm_clk_hw_register(port->dev, hw);
> +	if (ret)
> +		return dev_err_probe(port->dev, ret,
> +				     "Failed to register the '%s' clock\n",
> +				     clk_name);
>  
> -	return clk;
> +	return ret;
>  }
>  
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> +static int meson_uart_probe_clocks(struct uart_port *port,
> +				   bool register_clk81_div4)
> +{
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
> +	struct clk_parent_data baud_div_parent = { };
> +	struct clk *clk_baud, *clk_xtal;
> +	int ret;
>  
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud))
> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
> +				     "Failed to get the 'baud' clock\n");
>  
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	private_data->xtal_div3.mult = 1;
> +	private_data->xtal_div3.div = 3;
> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
> +				      1, &clk_fixed_factor_ops,
> +				      &private_data->xtal_div3.hw);
> +	if (ret)
> +		return ret;
>  
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +	if (register_clk81_div4) {

Clock dividers represent HW elements. The presence of an HW element cannot
dependent on the current of the input clocks. There is no way this is right

> +		private_data->clk81_div4.mult = 1;
> +		private_data->clk81_div4.div = 4;
> +		ret = meson_uart_register_clk(port, "clk81_div4",
> +					      &clk81_div_parent, 1,
> +					      &clk_fixed_factor_ops,
> +					      &private_data->clk81_div4.hw);
> +		if (ret)
> +			return ret;
> +
> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;

This is only going to be used on meson8 and older. Worst case it should depend
on this compatible but I don't think this would be right here.

IMO, this shows that the UART "baud" input was actually fed by a
derivation of "fclk_div4" instead of "clk_81" on these older SoCs.

So instead of registering what I suspect to be a fake element, the
meson8 clock controller driver and DT should be fixed a this should go away.

> +	}
>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	if (private_data->has_xtal_clk_sel) {
> +		private_data->xtal_div2.mult = 1;
> +		private_data->xtal_div2.div = 2;
> +		ret = meson_uart_register_clk(port, "xtal_div2",
> +					      &xtal_div_parent, 1,
> +					      &clk_fixed_factor_ops,
> +					      &private_data->xtal_div2.hw);
> +		if (ret)
> +			return ret;
> +
> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
> +
> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
> +		private_data->xtal_clk_sel_mux.mask = 0x1;
> +		private_data->xtal_clk_sel_mux.shift = 26;
> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
> +					      xtal_clk_sel_mux_parents,
> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
> +					      &clk_mux_ops,
> +					      &private_data->xtal_clk_sel_mux.hw);
> +		if (ret)
> +			return ret;
> +
> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
> +
> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
> +		private_data->xtal2_clk_sel_mux.shift = 27;
> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
> +					      xtal2_clk_sel_mux_parents,
> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
> +					      &clk_mux_ops,
> +					      &private_data->xtal2_clk_sel_mux.hw);
> +		if (ret)
> +			return ret;
> +
> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
> +	} else {
> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;

Well the above is a bit over-complicated. If I summarize: 

GXBB and older used a fixed divider of 3. Bits 26 and 27 read
0 according to the documentation.

Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
selects which of these dividers is used.

So the above could be replaced with a single divider covering bits 26 and 27
with the following divider table { 2, 2, 1, 3 }. The divider should use
RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
variant like this, including the older ones.

The only information you need to carry if whether or not you want to
make this divider modifiable. This means using the dt data to store
clk_div_ops or clk_div_ro_ops pointer.

To avoid changing the behavior of the older platforms in this patch, I would
suggest to make everything use clk_div_ro_ops first, and make another
patch to use clk_div_ops if necessary.


> +	}
> +
> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
> +	private_data->use_xtal_mux.mask = 0x1;
> +	private_data->use_xtal_mux.shift = 24;
> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
> +				      ARRAY_SIZE(use_xtal_mux_parents),
> +				      &clk_mux_ops,

Use RO ops here to start with.
You can make this writable with another patch explicitly describing the change.

> +				      &private_data->use_xtal_mux.hw);
> +	if (ret)
> +		return ret;
> +
> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
> +
> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
> +	private_data->baud_div.shift = 0;
> +	private_data->baud_div.width = 23;
> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
> +	ret = meson_uart_register_clk(port, "baud_div",
> +				      &baud_div_parent, 1,
> +				      &clk_divider_ops,
> +				      &private_data->baud_div.hw);
> +	if (ret)
> +		return ret;
> +
> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
> +						     &private_data->baud_div.hw,
> +						     "baud_rate");

There is a problem with this function in CCF. It will pin the driver to
itself, making it unremovable. It is an ongoing topic. For now, just use
"hw->clk" to get the struct *clk.

> +	if (IS_ERR(private_data->baud_clk))
> +		return dev_err_probe(port->dev,

I don't think anything can defer here, so dev_err_probe() is not
necessary I think

> +				     PTR_ERR(private_data->baud_clk),
> +				     "Failed to request the 'baud_rate' clock\n");
>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem, *res_irq;
> +	struct clk *clk_baud, *clk_xtal;
> +	bool register_clk81_div4;
>  	struct uart_port *port;
>  	int ret = 0;
>  	int id = -1;
> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>  		return -EBUSY;
>  	}
>  
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>  		return -ENOMEM;
>  
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->has_xtal_clk_sel = true;
> +
> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
> +	if (IS_ERR(clk_baud))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
> +				     "Failed to get the 'baud' clock\n");
> +
> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
> +	if (IS_ERR(clk_xtal))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +

This is second time you call devm_clk_get() on these clocks. One
instance has to go away

> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
> +

The above is a ugly way to distinguish the meson8 (32bit) SoC family
from the rest. This definitely not the way to achieve it.

The right is the compatible data but here I think it is not
necessary. The clock input should be fixed.

> +	port = &private_data->port;
> +
>  	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
>  	port->mapsize = resource_size(res_mem);
> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = 64;
> +	port->uartclk = clk_get_rate(clk_baud);
> +	port->private_data = private_data;
> +
> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
> +	if (ret)
> +		return ret;
>  
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-s4-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB and GXL which have different revisions of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From jbrunet at baylibre.com  Mon Jan  3 05:50:06 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 14:50:06 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
Message-ID: <1jbl0s9b1w.fsf@starbuckisacylon.baylibre.com>


On Sat 01 Jan 2022 at 21:30, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Martin,
>     Thank you very much for your reply.
>
> On 2021/12/31 23:32, Martin Blumenstingl wrote:
>> [ EXTERNAL EMAIL ]
>> On Fri, Dec 31, 2021 at 12:24 PM Yu Tu <yu.tu at amlogic.com> wrote:
>> [...]
>>>>>    static int meson_uart_request_port(struct uart_port *port)
>>>>>    {
>>>>> +       struct meson_uart_data *private_data = port->private_data;
>>>>> +       int ret;
>>>>> +
>>>>> +       ret = clk_prepare_enable(private_data->pclk);
>>>>> +       if (ret)
>>>>> +               return ret;
>>>>> +
>>>>> +       ret = clk_prepare_enable(private_data->baud_clk);
>>>>> +       if (ret) {
>>>>> +               clk_disable_unprepare(private_data->pclk);
>>>>> +               return ret;
>>>>> +       }
>>>> This code is from my original suggestion - and I had a doubt there
>>>> which I forgot to add as a comment originally:
>>>> Can you confirm that accessing the UART controller registers works
>>>> even when "pclk" is turned off?
>>>> I am asking this because the common clock framework can access the
>>>> clocks at any time.
>>>> And I have seen SoCs which would hang when trying to access a module's
>>>> registers while the module's pclk is turned off.
>>> On all meson platforms, the default pclk for all UART is turned on
>>> during the u-boot phase. When registering uart pclk in the kernel phase,
>>> the CLK_IGNORE_UNUSED flag is added. So the real shutdown is when the
>>> standby goes down, the parent clk shuts down.
>> Interesting, thanks for sharing that u-boot turns these clocks on.
>> Let's say someone wanted to make u-boot save power and turn off all
>> UART clocks except the one for uart_AO (where we typically connect the
>> serial console).
>> In that case the pclk of uart_C (just to choose an example here) is
>> turned off. Would there be a problem then accessing the registers of
>> uart_C before clk_prepare_enable is called?
> The way you describe it, it does hang. This would not be recommended on
> actual projects.
>
> At present, AmLogic chips are older than S4 Soc, and we have no way to deal
> with this problem. We have to tell customers not to use it in this way?
> Customers rarely use it in real projects.On the S4 SOC we will use a clock
> like the UART pclk to control the shutdown using two registers, one safe
> (need to operate in EL3) and one normal (EL1). It will only be closed if
> both registers are closed. This mainly prevents misoperation.
>
> With your experience, I'd like to know how you deal with this kind of
> problem.

Relying on the CLK_IGNORE_UNUSED and the boot loader is unsafe.
As Martin is suggesting, the driver must ensure pclk is on before
touching any register.

This was done in the probe before in probe before your change which
seems safe but maybe not optimal.

Again, If you wish to optimize that, please do so in another dedicated
change so we can discuss it and make sure it is still safe

>> [...]
>>>>>           port->fifosize = 64;
>>>> commit 27d44e05d7b85d ("tty: serial: meson: retrieve port FIFO size
>>>> from DT") [0] from May 2021 has changed this line to:
>>>>     port->fifosize = fifosize;
>>>> So your patch currently does not apply to linux-next (or even Linus'
>>>> mainline tree).
>>>>
>>> So do I need to wait for [0] patch merged before I can continue to make
>>> changes ?
>> These changes are already merged.
>> 
>>> What can I do before?
>> You should base your changes on top of the tty.git/tty-next branch [1]
>> where Greg (the maintainer of this tree) will pick up the patches once
>> they are good (got enough Acked-by/Reviewed-by, etc.).
>> I suspect that you based your changes on an older or stable kernel
>> version (let's say 5.10). New functionality should always get into the
>> -next tree where various auto-build robots will compile-test the
>> changes and we even have Kernel CI where changes are tested on real
>> hardware (BayLibre even maintains Amlogic boards in their Kernel CI
>> labs). Let's say Amlogic updates to Linux 5.17 next year then the
>> patches are already included in that kernel version - instead of being
>> only available in Linux 5.10.
>> 
> I'm sorry, I did branch confirm there was a mistake, I have corrected.
>> Best regards,
>> Martin
>> 
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/log/?h=tty-next
>> 



From romain.perier at gmail.com  Mon Jan  3 06:13:05 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Mon, 3 Jan 2022 15:13:05 +0100
Subject: [PATCH] rtc: msc313: Select by default on MSTARV7
In-Reply-To: <20211230044027.2739732-1-daniel@0x0f.com>
References: <20211230044027.2739732-1-daniel@0x0f.com>
Message-ID: <CABgxDoKMNcYzPH6mcO0yfJhpK2kRZR5BK=p5H1YvVqJGjbynDg@mail.gmail.com>

Hi,

Le jeu. 30 d?c. 2021 ? 05:40, Daniel Palmer <daniel at 0x0f.com> a ?crit :
>
> All of the ARCH_MSTARV7 chips have this RTC so it's more likey
> ARCH_MSTARV7 wants it than doesn't.
>
> At the same time fix up the indent on the depends on line that looks
> like it got converted from a tab to spaces at some point.
>
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> ---
>  drivers/rtc/Kconfig | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
> index 058e56a10ab8..9acd4ea267df 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1924,7 +1924,8 @@ config RTC_DRV_WILCO_EC
>
>  config RTC_DRV_MSC313
>         tristate "MStar MSC313 RTC"
> -        depends on ARCH_MSTARV7 || COMPILE_TEST
> +       depends on ARCH_MSTARV7 || COMPILE_TEST
> +       default ARCH_MSTARV7

You still depend on ARCH_MSTARV7 so "default y" is enough. It
will only work if the dependencies are satisfied and, when it is the
case, the value can be overridden by the user.

Cheers,
Romain


From angelogioacchino.delregno at collabora.com  Mon Jan  3 06:37:11 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 15:37:11 +0100
Subject: [PATCH 1/2] clk: mediatek: clk-gate: Shrink by adding clockgating bit
 check helper
Message-ID: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>

Add a clockgating bit check helper and use it in functions
mtk_cg_bit_is_cleared(), mtk_cg_bit_is_set() to shrink the
file size.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/clk/mediatek/clk-gate.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index b02d2f74dd0d..957fa1d68f07 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -16,28 +16,24 @@
 #include "clk-mtk.h"
 #include "clk-gate.h"
 
-static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+static u32 mtk_get_clockgating(struct clk_hw *hw)
 {
 	struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
 	u32 val;
 
 	regmap_read(cg->regmap, cg->sta_ofs, &val);
 
-	val &= BIT(cg->bit);
+	return val & BIT(cg->bit);
+}
 
-	return val == 0;
+static int mtk_cg_bit_is_cleared(struct clk_hw *hw)
+{
+	return mtk_get_clockgating(hw) == 0;
 }
 
 static int mtk_cg_bit_is_set(struct clk_hw *hw)
 {
-	struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-	u32 val;
-
-	regmap_read(cg->regmap, cg->sta_ofs, &val);
-
-	val &= BIT(cg->bit);
-
-	return val != 0;
+	return mtk_get_clockgating(hw) != 0;
 }
 
 static void mtk_cg_set_bit(struct clk_hw *hw)
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 06:37:12 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 15:37:12 +0100
Subject: [PATCH 2/2] clk: mediatek: clk-gate: Use regmap_{set/clear}_bits
 helpers
In-Reply-To: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
References: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103143712.46675-2-angelogioacchino.delregno@collabora.com>

Appropriately change calls to regmap_update_bits() with regmap_set_bits()
and regmap_clear_bits() for improved readability.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/clk/mediatek/clk-gate.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 957fa1d68f07..5d88b428565b 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -53,17 +53,15 @@ static void mtk_cg_clr_bit(struct clk_hw *hw)
 static void mtk_cg_set_bit_no_setclr(struct clk_hw *hw)
 {
 	struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-	u32 cgbit = BIT(cg->bit);
 
-	regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, cgbit);
+	regmap_set_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit));
 }
 
 static void mtk_cg_clr_bit_no_setclr(struct clk_hw *hw)
 {
 	struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
-	u32 cgbit = BIT(cg->bit);
 
-	regmap_update_bits(cg->regmap, cg->sta_ofs, cgbit, 0);
+	regmap_clear_bits(cg->regmap, cg->sta_ofs, BIT(cg->bit));
 }
 
 static int mtk_cg_enable(struct clk_hw *hw)
-- 
2.33.1



From semen.protsenko at linaro.org  Mon Jan  3 06:41:37 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 16:41:37 +0200
Subject: [PATCH 2/2] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
 <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4miCOwFR11gdaU1nMQZdk8zVcWOcSK=Wjd3AaCagGLyug@mail.gmail.com>

On Sun, 2 Jan 2022 at 17:58, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> controller bindings to DT schema format
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/spi/samsung,spi.yaml  | 220 ++++++++++++++++++
>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ----------
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 221 insertions(+), 123 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> new file mode 100644
> index 000000000000..195bfafe05fd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -0,0 +1,220 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC SPI controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description:
> +  All the SPI controller nodes should be represented in the aliases node using
> +  the following format 'spi{n}' where n is a unique number for the alias.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - samsung,s3c2443-spi

Maybe add the list of supported platforms for each compatible (in a
comment on the same line), like it was done in .txt binding?

Other than that:

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

> +          - samsung,s3c6410-spi
> +          - samsung,s5pv210-spi
> +          - samsung,exynos5433-spi
> +      - const: samsung,exynos7-spi
> +        deprecated: true
> +
> +  clocks:
> +    minItems: 2
> +    maxItems: 3
> +
> +  clock-names:
> +    minItems: 2
> +    maxItems: 3
> +
> +  cs-gpios: true
> +
> +  dmas:
> +    minItems: 2
> +    maxItems: 2
> +
> +  dma-names:
> +    items:
> +      - const: tx
> +      - const: rx
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  no-cs-readback:
> +    description:
> +      The CS line is disconnected, therefore the device should not operate
> +      based on CS signalling.
> +    type: boolean
> +
> +  num-cs:
> +    minimum: 1
> +    maximum: 4
> +    default: 1
> +
> +  samsung,spi-src-clk:
> +    description:
> +      If the spi controller includes a internal clock mux to select the clock
> +      source for the spi bus clock, this property can be used to indicate the
> +      clock to be used for driving the spi bus clock. If not specified, the
> +      clock number 0 is used as default.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 0
> +
> +  reg:
> +    maxItems: 1
> +
> +patternProperties:
> +  "^.*@[0-9a-f]+$":
> +    type: object
> +
> +    allOf:
> +      - $ref: spi-peripheral-props.yaml
> +
> +    properties:
> +      controller-data:
> +        type: object
> +        additionalProperties: false
> +
> +        properties:
> +          samsung,spi-feedback-delay:
> +            description: |
> +              The sampling phase shift to be applied on the miso line (to account
> +              for any lag in the miso line). Valid values:
> +               - 0: No phase shift.
> +               - 1: 90 degree phase shift sampling.
> +               - 2: 180 degree phase shift sampling.
> +               - 3: 270 degree phase shift sampling.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +        required:
> +          - samsung,spi-feedback-delay
> +
> +    required:
> +      - controller-data
> +
> +    unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - dmas
> +  - dma-names
> +  - interrupts
> +  - reg
> +
> +allOf:
> +  - $ref: spi-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos5433-spi
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +            - const: spi_ioclk
> +    else:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5433.h>
> +    #include <dt-bindings/clock/samsung,s2mps11.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    spi at 14d30000 {
> +        compatible = "samsung,exynos5433-spi";
> +        reg = <0x14d30000 0x100>;
> +        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
> +        dmas = <&pdma0 11>, <&pdma0 10>;
> +        dma-names = "tx", "rx";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        clocks = <&cmu_peric CLK_PCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
> +        clock-names = "spi",
> +                      "spi_busclk0",
> +                      "spi_ioclk";
> +        samsung,spi-src-clk = <0>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&spi1_bus>;
> +        num-cs = <1>;
> +
> +        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
> +        status = "okay";
> +
> +        audio-codec at 0 {
> +            compatible = "wlf,wm5110";
> +            reg = <0x0>;
> +            spi-max-frequency = <20000000>;
> +            interrupt-parent = <&gpa0>;
> +            interrupts = <4 IRQ_TYPE_NONE>;
> +            clocks = <&pmu_system_controller 0>,
> +                     <&s2mps13_osc S2MPS11_CLK_BT>;
> +            clock-names = "mclk1", "mclk2";
> +
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +
> +            wlf,micd-detect-debounce = <300>;
> +            wlf,micd-bias-start-time = <0x1>;
> +            wlf,micd-rate = <0x7>;
> +            wlf,micd-dbtime = <0x2>;
> +            wlf,micd-force-micbias;
> +            wlf,micd-configs = <0x0 1 0>;
> +            wlf,hpdet-channel = <1>;
> +            wlf,gpsw = <0x1>;
> +            wlf,inmode = <2 0 2 0>;
> +
> +            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
> +            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
> +
> +            /* core supplies */
> +            AVDD-supply = <&ldo18_reg>;
> +            DBVDD1-supply = <&ldo18_reg>;
> +            CPVDD-supply = <&ldo18_reg>;
> +            DBVDD2-supply = <&ldo18_reg>;
> +            DBVDD3-supply = <&ldo18_reg>;
> +            SPKVDDL-supply = <&ldo18_reg>;
> +            SPKVDDR-supply = <&ldo18_reg>;
> +
> +            controller-data {
> +                samsung,spi-feedback-delay = <0>;
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> deleted file mode 100644
> index 49028a4f5df1..000000000000
> --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
> +++ /dev/null
> @@ -1,122 +0,0 @@
> -* Samsung SPI Controller
> -
> -The Samsung SPI controller is used to interface with various devices such as flash
> -and display controllers using the SPI communication interface.
> -
> -Required SoC Specific Properties:
> -
> -- compatible: should be one of the following.
> -    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
> -    - samsung,s3c6410-spi: for s3c6410 platforms
> -    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
> -    - samsung,exynos5433-spi: for exynos5433 compatible controllers
> -    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- interrupts: The interrupt number to the cpu. The interrupt specifier format
> -  depends on the interrupt controller.
> -
> -- dmas : Two or more DMA channel specifiers following the convention outlined
> -  in bindings/dma/dma.txt
> -
> -- dma-names: Names for the dma channels. There must be at least one channel
> -  named "tx" for transmit and named "rx" for receive.
> -
> -- clocks: specifies the clock IDs provided to the SPI controller; they are
> -  required for interacting with the controller itself, for synchronizing the bus
> -  and as I/O clock (the latter is required by exynos5433 and exynos7).
> -
> -- clock-names: string names of the clocks in the 'clocks' property; for all the
> -  the devices the names must be "spi", "spi_busclkN" (where N is determined by
> -  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
> -  "spi_ioclk" for the I/O clock.
> -
> -Required Board Specific Properties:
> -
> -- #address-cells: should be 1.
> -- #size-cells: should be 0.
> -
> -Optional Board Specific Properties:
> -
> -- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
> -  select the clock source for the spi bus clock, this property can be used to
> -  indicate the clock to be used for driving the spi bus clock. If not specified,
> -  the clock number 0 is used as default.
> -
> -- num-cs: Specifies the number of chip select lines supported. If
> -  not specified, the default number of chip select lines is set to 1.
> -
> -- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
> -
> -- no-cs-readback: the CS line is disconnected, therefore the device should not
> -  operate based on CS signalling.
> -
> -SPI Controller specific data in SPI slave nodes:
> -
> -- The spi slave nodes should provide the following information which is required
> -  by the spi controller.
> -
> -  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
> -    miso line (to account for any lag in the miso line). The following are the
> -    valid values.
> -
> -      - 0: No phase shift.
> -      - 1: 90 degree phase shift sampling.
> -      - 2: 180 degree phase shift sampling.
> -      - 3: 270 degree phase shift sampling.
> -
> -Aliases:
> -
> -- All the SPI controller nodes should be represented in the aliases node using
> -  the following format 'spi{n}' where n is a unique number for the alias.
> -
> -
> -Example:
> -
> -- SoC Specific Portion:
> -
> -       spi_0: spi at 12d20000 {
> -               compatible = "samsung,exynos4210-spi";
> -               reg = <0x12d20000 0x100>;
> -               interrupts = <0 66 0>;
> -               dmas = <&pdma0 5
> -                       &pdma0 4>;
> -               dma-names = "tx", "rx";
> -               #address-cells = <1>;
> -               #size-cells = <0>;
> -       };
> -
> -- Board Specific Portion:
> -
> -       spi_0: spi at 12d20000 {
> -               #address-cells = <1>;
> -               #size-cells = <0>;
> -               pinctrl-names = "default";
> -               pinctrl-0 = <&spi0_bus>;
> -               cs-gpios = <&gpa2 5 0>;
> -
> -               w25q80bw at 0 {
> -                       #address-cells = <1>;
> -                       #size-cells = <1>;
> -                       compatible = "w25x80";
> -                       reg = <0>;
> -                       spi-max-frequency = <10000>;
> -
> -                       controller-data {
> -                               samsung,spi-feedback-delay = <0>;
> -                       };
> -
> -                       partition at 0 {
> -                               label = "U-Boot";
> -                               reg = <0x0 0x40000>;
> -                               read-only;
> -                       };
> -
> -                       partition at 40000 {
> -                               label = "Kernel";
> -                               reg = <0x40000 0xc0000>;
> -                       };
> -               };
> -       };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index af392bd04874..572eb97f1855 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17058,7 +17058,7 @@ M:      Andi Shyti <andi at etezian.org>
>  L:     linux-spi at vger.kernel.org
>  L:     linux-samsung-soc at vger.kernel.org
>  S:     Maintained
> -F:     Documentation/devicetree/bindings/spi/spi-samsung.txt
> +F:     Documentation/devicetree/bindings/spi/samsung,spi.yaml
>  F:     drivers/spi/spi-s3c*
>  F:     include/linux/platform_data/spi-s3c64xx.h
>  F:     include/linux/spi/s3c24xx-fiq.h
> --
> 2.32.0
>


From narmstrong at baylibre.com  Mon Jan  3 06:43:38 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 15:43:38 +0100
Subject: [PATCH 0/3] ARM: dts: meson: fix UART device-tree schema
 validation
In-Reply-To: <CAFBinCC7iSKjZ=U5PN5FKF9js77tvaQBdWdHMPp_y+u+asaeoA@mail.gmail.com>
References: <20211227180026.4068352-1-martin.blumenstingl@googlemail.com>
 <CAFBinCC7iSKjZ=U5PN5FKF9js77tvaQBdWdHMPp_y+u+asaeoA@mail.gmail.com>
Message-ID: <2c5311fd-187a-d129-4e15-e83e49c14c09@baylibre.com>

Hi,

On 31/12/2021 16:38, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Mon, Dec 27, 2021 at 7:00 PM Martin Blumenstingl
> <martin.blumenstingl at googlemail.com> wrote:
>>
>> Hello,
>>
>> here are three UART device-tree schema related fixes for the 32-bit
>> ARM SoCs.
>> These patches don't fix any functionality which is why linux-stable
>> is not Cc'ed on them.
> The statement above still stands.
> I would like you to apply this series to a 5.17-fixes branch because
> of a change from the tty.git tree which will be going into 5.17 to
> drop the "amlogic,meson-uart" earlycon handling: [0]
> 
> To make it clear: Backporting this series to kernels older than 5.17
> won't break or fix anything.
> Only 5.17 and newer will need this due to a change [0] in the tty.git
> tree. Without the patches from this series the 32-bit SoCs won't have
> earlycon support in 5.17.

OK, I'll submit it as fixes for for 5.17

Neil

> 
> 
> Thank you!
> Martin
> 
> 
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 



From semen.protsenko at linaro.org  Mon Jan  3 06:45:02 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 16:45:02 +0200
Subject: [PATCH 19/24] arm64: dts: exynos: align pinctrl with dtschema in
 Exynos850
In-Reply-To: <20211231162309.257587-2-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162309.257587-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4k5cMUNvLkZNsJCqTfrFWOGiakerYHY3kc+xQAvQ2Ce6w@mail.gmail.com>

On Fri, 31 Dec 2021 at 18:23, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the pin controller related nodes with dtschema.  No functional
> change expected.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 52 +++++++++----------
>  1 file changed, 26 insertions(+), 26 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> index f576b29c9b16..a71acf358d2d 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> @@ -13,7 +13,7 @@
>  #include <dt-bindings/pinctrl/samsung.h>
>
>  &pinctrl_alive {
> -       gpa0: gpa0 {
> +       gpa0: gpa0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -30,7 +30,7 @@ gpa0: gpa0 {
>                              <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa1: gpa1 {
> +       gpa1: gpa1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -47,7 +47,7 @@ gpa1: gpa1 {
>                              <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa2: gpa2 {
> +       gpa2: gpa2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -64,7 +64,7 @@ gpa2: gpa2 {
>                              <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa3: gpa3 {
> +       gpa3: gpa3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -81,7 +81,7 @@ gpa3: gpa3 {
>                              <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa4: gpa4 {
> +       gpa4: gpa4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -94,7 +94,7 @@ gpa4: gpa4 {
>                              <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpq0: gpq0 {
> +       gpq0: gpq0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -134,7 +134,7 @@ uart1_pins: uart1-pins {
>  };
>
>  &pinctrl_cmgp {
> -       gpm0: gpm0 {
> +       gpm0: gpm0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -144,7 +144,7 @@ gpm0: gpm0 {
>                 interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpm1: gpm1 {
> +       gpm1: gpm1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -154,7 +154,7 @@ gpm1: gpm1 {
>                 interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpm2: gpm2 {
> +       gpm2: gpm2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -164,7 +164,7 @@ gpm2: gpm2 {
>                 interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpm3: gpm3 {
> +       gpm3: gpm3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -174,7 +174,7 @@ gpm3: gpm3 {
>                 interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpm4: gpm4 {
> +       gpm4: gpm4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -184,7 +184,7 @@ gpm4: gpm4 {
>                 interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpm5: gpm5 {
> +       gpm5: gpm5-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -256,7 +256,7 @@ spi2_pins: spi2-pins {
>  };
>
>  &pinctrl_aud {
> -       gpb0: gpb0 {
> +       gpb0: gpb0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -264,7 +264,7 @@ gpb0: gpb0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpb1: gpb1 {
> +       gpb1: gpb1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -322,7 +322,7 @@ aud_fm_idle_pins: aud-fm-idle-pins {
>  };
>
>  &pinctrl_hsi {
> -       gpf2: gpf2 {
> +       gpf2: gpf2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -367,7 +367,7 @@ sd2_pdn_pins: sd2-pdn-pins {
>  };
>
>  &pinctrl_core {
> -       gpf0: gpf0 {
> +       gpf0: gpf0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -375,7 +375,7 @@ gpf0: gpf0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf1: gpf1 {
> +       gpf1: gpf1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -434,7 +434,7 @@ sd0_bus8_pins: sd0-bus8-pins {
>  };
>
>  &pinctrl_peri {
> -       gpc0: gpc0 {
> +       gpc0: gpc0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -442,7 +442,7 @@ gpc0: gpc0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpc1: gpc1 {
> +       gpc1: gpc1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -450,7 +450,7 @@ gpc1: gpc1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg0: gpg0 {
> +       gpg0: gpg0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -458,7 +458,7 @@ gpg0: gpg0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg1: gpg1 {
> +       gpg1: gpg1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -466,7 +466,7 @@ gpg1: gpg1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg2: gpg2 {
> +       gpg2: gpg2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -474,7 +474,7 @@ gpg2: gpg2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg3: gpg3 {
> +       gpg3: gpg3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -482,14 +482,14 @@ gpg3: gpg3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp0: gpp0 {
> +       gpp0: gpp0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
>                 interrupt-controller;
>                 #interrupt-cells = <2>;
>         };
> -       gpp1: gpp1 {
> +       gpp1: gpp1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -497,7 +497,7 @@ gpp1: gpp1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp2: gpp2 {
> +       gpp2: gpp2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Mon Jan  3 06:49:08 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 16:49:08 +0200
Subject: [PATCH 01/24] pinctrl: samsung: drop pin banks references on
 error paths
In-Reply-To: <20211231161930.256733-2-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4mosbk2_NPFFP=sUmKjBoZOG3vNcmT+7sMtTunhbVqcxA@mail.gmail.com>

On Fri, 31 Dec 2021 at 18:20, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The driver iterates over its devicetree children with
> for_each_child_of_node() and stores for later found node pointer.  This
> has to be put in error paths to avoid leak during re-probing.
>
> Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device nodes")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  drivers/pinctrl/samsung/pinctrl-samsung.c | 29 +++++++++++++++++------
>  1 file changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index 8941f658e7f1..f2864a7869b3 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1002,6 +1002,15 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
>         return &(of_data->ctrl[id]);
>  }
>
> +static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
> +{
> +       struct samsung_pin_bank *bank;
> +       unsigned int i;
> +
> +       for (i = 0; i < d->nr_banks; ++i, ++bank)
> +               of_node_put(bank->of_node);

But "bank" variable wasn't actually assigned before, only declared?

> +}
> +
>  /* retrieve the soc specific data */
>  static const struct samsung_pin_ctrl *
>  samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
> @@ -1116,19 +1125,19 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
>         if (ctrl->retention_data) {
>                 drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,
>                                                           ctrl->retention_data);
> -               if (IS_ERR(drvdata->retention_ctrl))
> -                       return PTR_ERR(drvdata->retention_ctrl);
> +               if (IS_ERR(drvdata->retention_ctrl)) {
> +                       ret = PTR_ERR(drvdata->retention_ctrl);
> +                       goto err_put_banks;
> +               }
>         }
>
>         ret = samsung_pinctrl_register(pdev, drvdata);
>         if (ret)
> -               return ret;
> +               goto err_put_banks;
>
>         ret = samsung_gpiolib_register(pdev, drvdata);
> -       if (ret) {
> -               samsung_pinctrl_unregister(pdev, drvdata);
> -               return ret;
> -       }
> +       if (ret)
> +               goto err_unregister;
>
>         if (ctrl->eint_gpio_init)
>                 ctrl->eint_gpio_init(drvdata);
> @@ -1138,6 +1147,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
>         platform_set_drvdata(pdev, drvdata);
>
>         return 0;
> +
> +err_unregister:
> +       samsung_pinctrl_unregister(pdev, drvdata);
> +err_put_banks:
> +       samsung_banks_of_node_put(drvdata);
> +       return ret;
>  }
>
>  /*
> --
> 2.32.0
>


From angelogioacchino.delregno at collabora.com  Mon Jan  3 06:53:22 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 15:53:22 +0100
Subject: [PATCH 1/3] phy: mediatek: phy-mtk-mipi-dsi: Switch to regmap for
 mmio access
Message-ID: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>

Switch to using the generic regmap API instead of calls to readl/writel
for MMIO register access, removing custom crafted update/set/clear_bits
functions and also allowing us to reduce code size.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../phy/mediatek/phy-mtk-mipi-dsi-mt8173.c    | 45 ++++++-------
 .../phy/mediatek/phy-mtk-mipi-dsi-mt8183.c    | 63 ++++++++++---------
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c       | 43 +++++--------
 drivers/phy/mediatek/phy-mtk-mipi-dsi.h       |  6 +-
 4 files changed, 72 insertions(+), 85 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
index 7a847954594f..95a0d9a3cca7 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
@@ -4,6 +4,7 @@
  * Author: jitao.shi <jitao.shi at mediatek.com>
  */
 
+#include <linux/regmap.h>
 #include "phy-mtk-mipi-dsi.h"
 
 #define MIPITX_DSI_CON		0x00
@@ -145,7 +146,7 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
 		return -EINVAL;
 	}
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_BG_CON,
 				RG_DSI_VOUT_MSK |
 				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN,
 				(4 << 20) | (4 << 17) | (4 << 14) |
@@ -154,22 +155,22 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
 
 	usleep_range(30, 100);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
 				RG_DSI_LNT_IMP_CAL_CODE | RG_DSI_LNT_HS_BIAS_EN,
 				(8 << 4) | RG_DSI_LNT_HS_BIAS_EN);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON,
+	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_CON,
 			     RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_PWR,
 				RG_DSI_MPPLL_SDM_PWR_ON |
 				RG_DSI_MPPLL_SDM_ISO_EN,
 				RG_DSI_MPPLL_SDM_PWR_ON);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
 			       RG_DSI_MPPLL_PLL_EN);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
 				RG_DSI_MPPLL_TXDIV0 | RG_DSI_MPPLL_TXDIV1 |
 				RG_DSI_MPPLL_PREDIV,
 				(txdiv0 << 3) | (txdiv1 << 5));
@@ -184,19 +185,19 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw *hw)
 	 */
 	pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24,
 		      26000000);
-	writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2);
+	regmap_write(mipi_tx->regmap, MIPITX_DSI_PLL_CON2, pcw);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
+	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON1,
 			     RG_DSI_MPPLL_SDM_FRA_EN);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_PLL_EN);
 
 	usleep_range(20, 100);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON1,
 			       RG_DSI_MPPLL_SDM_SSC_EN);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_TOP,
 				RG_DSI_MPPLL_PRESERVE,
 				mipi_tx->driver_data->mppll_preserve);
 
@@ -209,27 +210,27 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw)
 
 	dev_dbg(mipi_tx->dev, "unprepare\n");
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
 			       RG_DSI_MPPLL_PLL_EN);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_TOP,
 				RG_DSI_MPPLL_PRESERVE, 0);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_PWR,
 				RG_DSI_MPPLL_SDM_ISO_EN |
 				RG_DSI_MPPLL_SDM_PWR_ON,
 				RG_DSI_MPPLL_SDM_ISO_EN);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
 			       RG_DSI_LNT_HS_BIAS_EN);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_CON,
 			       RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_BG_CON,
 			       RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
 			       RG_DSI_MPPLL_DIV_MSK);
 }
 
@@ -254,9 +255,9 @@ static void mtk_mipi_tx_power_on_signal(struct phy *phy)
 
 	for (reg = MIPITX_DSI_CLOCK_LANE;
 	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
-		mtk_mipi_tx_set_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
+		regmap_set_bits(mipi_tx->regmap, reg, RG_DSI_LNTx_LDOOUT_EN);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
 			       RG_DSI_PAD_TIE_LOW_EN);
 }
 
@@ -265,12 +266,12 @@ static void mtk_mipi_tx_power_off_signal(struct phy *phy)
 	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
 	u32 reg;
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
+	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
 			     RG_DSI_PAD_TIE_LOW_EN);
 
 	for (reg = MIPITX_DSI_CLOCK_LANE;
 	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
-		mtk_mipi_tx_clear_bits(mipi_tx, reg, RG_DSI_LNTx_LDOOUT_EN);
+		regmap_clear_bits(mipi_tx->regmap, reg, RG_DSI_LNTx_LDOOUT_EN);
 }
 
 const struct mtk_mipitx_data mt2701_mipitx_data = {
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
index 99108426d57c..01b59527669e 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
@@ -4,6 +4,7 @@
  * Author: jitao.shi <jitao.shi at mediatek.com>
  */
 
+#include <linux/regmap.h>
 #include "phy-mtk-mipi-dsi.h"
 
 #define MIPITX_LANE_CON		0x000c
@@ -70,17 +71,17 @@ static int mtk_mipi_tx_pll_enable(struct clk_hw *hw)
 		return -EINVAL;
 	}
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON4, RG_DSI_PLL_IBIAS);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
 	udelay(1);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
 	pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24, 26000000);
-	writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0);
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV,
+	regmap_write(mipi_tx->regmap, MIPITX_PLL_CON0, pcw);
+	regmap_update_bits(mipi_tx->regmap, MIPITX_PLL_CON1, RG_DSI_PLL_POSDIV,
 				txdiv0 << 8);
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
 
 	return 0;
 }
@@ -89,10 +90,10 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw)
 {
 	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
 
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_ISO_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON);
 }
 
 static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -121,7 +122,7 @@ static void mtk_mipi_tx_config_calibration_data(struct mtk_mipi_tx *mipi_tx)
 			mipi_tx->rt_code[i] |= 0x10 << 5;
 
 		for (j = 0; j < 10; j++)
-			mtk_mipi_tx_update_bits(mipi_tx,
+			regmap_update_bits(mipi_tx->regmap,
 				MIPITX_D2P_RTCODE * (i + 1) + j * 4,
 				1, mipi_tx->rt_code[i] >> j & 1);
 	}
@@ -132,26 +133,26 @@ static void mtk_mipi_tx_power_on_signal(struct phy *phy)
 	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
 
 	/* BG_LPF_EN / BG_CORE_EN */
-	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
-	       mipi_tx->regs + MIPITX_LANE_CON);
+	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
+		    (RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN));
 	usleep_range(30, 100);
-	writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN,
-	       mipi_tx->regs + MIPITX_LANE_CON);
+	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
+		    (RG_DSI_BG_LPF_EN | RG_DSI_BG_CORE_EN));
 
 	/* Switch OFF each Lane */
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_clear_bits(mipi_tx->regmap, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
 
-	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_VOLTAGE_SEL,
+	regmap_update_bits(mipi_tx->regmap, MIPITX_VOLTAGE_SEL,
 				RG_DSI_HSTX_LDO_REF_SEL,
 				(mipi_tx->mipitx_drive - 3000) / 200 << 6);
 
 	mtk_mipi_tx_config_calibration_data(mipi_tx);
 
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_CK_CKMODE_EN, DSI_CK_CKMODE_EN);
 }
 
 static void mtk_mipi_tx_power_off_signal(struct phy *phy)
@@ -159,15 +160,15 @@ static void mtk_mipi_tx_power_off_signal(struct phy *phy)
 	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
 
 	/* Switch ON each Lane */
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
-	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
-
-	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
-	       mipi_tx->regs + MIPITX_LANE_CON);
-	writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_D0_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_D1_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_D2_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_D3_SW_CTL_EN, DSI_SW_CTL_EN);
+	regmap_set_bits(mipi_tx->regmap, MIPITX_CK_SW_CTL_EN, DSI_SW_CTL_EN);
+
+	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
+		    (RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN));
+	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON, RG_DSI_PAD_TIEL_SEL);
 }
 
 const struct mtk_mipitx_data mt8183_mipitx_data = {
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 28ad9403c441..51b1b1d4ad38 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include <linux/regmap.h>
 #include "phy-mtk-mipi-dsi.h"
 
 inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
@@ -10,30 +11,6 @@ inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
 	return container_of(hw, struct mtk_mipi_tx, pll_hw);
 }
 
-void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-			    u32 bits)
-{
-	u32 temp = readl(mipi_tx->regs + offset);
-
-	writel(temp & ~bits, mipi_tx->regs + offset);
-}
-
-void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-			  u32 bits)
-{
-	u32 temp = readl(mipi_tx->regs + offset);
-
-	writel(temp | bits, mipi_tx->regs + offset);
-}
-
-void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
-			     u32 mask, u32 data)
-{
-	u32 temp = readl(mipi_tx->regs + offset);
-
-	writel((temp & ~mask) | (data & mask), mipi_tx->regs + offset);
-}
-
 int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			     unsigned long parent_rate)
 {
@@ -126,6 +103,13 @@ static void mtk_mipi_tx_get_calibration_datal(struct mtk_mipi_tx *mipi_tx)
 	kfree(buf);
 }
 
+static const struct regmap_config mtk_mipi_tx_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.disable_locking = true,
+};
+
 static int mtk_mipi_tx_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -139,6 +123,7 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 	};
 	struct phy *phy;
 	struct phy_provider *phy_provider;
+	void __iomem *regs;
 	int ret;
 
 	mipi_tx = devm_kzalloc(dev, sizeof(*mipi_tx), GFP_KERNEL);
@@ -147,9 +132,13 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
 
-	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(mipi_tx->regs))
-		return PTR_ERR(mipi_tx->regs);
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	mipi_tx->regmap = devm_regmap_init_mmio(dev, regs, &mtk_mipi_tx_regmap_config);
+	if (IS_ERR(mipi_tx->regmap))
+		return PTR_ERR(mipi_tx->regmap);
 
 	ref_clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(ref_clk)) {
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
index c76f07c3fdeb..8d32e9027a15 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
@@ -27,7 +27,7 @@ struct mtk_mipitx_data {
 
 struct mtk_mipi_tx {
 	struct device *dev;
-	void __iomem *regs;
+	struct regmap *regmap;
 	u32 data_rate;
 	u32 mipitx_drive;
 	u32 rt_code[5];
@@ -37,10 +37,6 @@ struct mtk_mipi_tx {
 };
 
 struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw);
-void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits);
-void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 bits);
-void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32 offset, u32 mask,
-			     u32 data);
 int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			     unsigned long parent_rate);
 unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 06:53:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 15:53:23 +0100
Subject: [PATCH 2/3] phy: mediatek: phy-mtk-mipi-dsi: Reorder and stop
 implicit header inclusion
In-Reply-To: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103145324.48008-2-angelogioacchino.delregno@collabora.com>

All the headers for phy-mtk-mipi-{dsi,dsi-mt8173,dsi-mt8183}.c were
included from phy-mtk-mipi-dsi.h, but this isn't optimal: in order to
increase readability and sensibly reduce build times, the inclusions
should be done per-file, also avoiding to include unused headers and
should not be implicit.

For this reason, move the inclusions to each file and remove unused ones.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c |  4 ++++
 drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c |  4 ++++
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c        |  7 +++++++
 drivers/phy/mediatek/phy-mtk-mipi-dsi.h        | 10 ++--------
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
index 95a0d9a3cca7..59f028da9d3e 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
@@ -4,7 +4,11 @@
  * Author: jitao.shi <jitao.shi at mediatek.com>
  */
 
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/regmap.h>
+#include <linux/phy/phy.h>
 #include "phy-mtk-mipi-dsi.h"
 
 #define MIPITX_DSI_CON		0x00
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
index 01b59527669e..6c6b192485ba 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
@@ -4,7 +4,11 @@
  * Author: jitao.shi <jitao.shi at mediatek.com>
  */
 
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/module.h>
 #include <linux/regmap.h>
+#include <linux/phy/phy.h>
 #include "phy-mtk-mipi-dsi.h"
 
 #define MIPITX_LANE_CON		0x000c
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 51b1b1d4ad38..6f7425b0bf5b 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -3,7 +3,14 @@
  * Copyright (c) 2015 MediaTek Inc.
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/phy/phy.h>
 #include "phy-mtk-mipi-dsi.h"
 
 inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
index 8d32e9027a15..4eb5fc91e083 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
@@ -7,16 +7,10 @@
 #ifndef _MTK_MIPI_TX_H
 #define _MTK_MIPI_TX_H
 
-#include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/nvmem-consumer.h>
-#include <linux/of_device.h>
-#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/regmap.h>
 #include <linux/phy/phy.h>
-#include <linux/slab.h>
 
 struct mtk_mipitx_data {
 	const u32 mppll_preserve;
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 06:53:24 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 15:53:24 +0100
Subject: [PATCH 3/3] phy: mediatek: phy-mtk-mipi-dsi: Simplify with
 dev_err_probe()
In-Reply-To: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103145324.48008-3-angelogioacchino.delregno@collabora.com>

Use the dev_err_probe() helper to simplify error handling during probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 29 +++++++++----------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 6f7425b0bf5b..4b77508f5241 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -148,11 +148,9 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return PTR_ERR(mipi_tx->regmap);
 
 	ref_clk = devm_clk_get(dev, NULL);
-	if (IS_ERR(ref_clk)) {
-		ret = PTR_ERR(ref_clk);
-		dev_err(dev, "Failed to get reference clock: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(ref_clk))
+		return dev_err_probe(dev, PTR_ERR(ref_clk),
+				     "Failed to get reference clock\n");
 
 	ret = of_property_read_u32(dev->of_node, "drive-strength-microamp",
 				   &mipi_tx->mipitx_drive);
@@ -172,27 +170,20 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 
 	ret = of_property_read_string(dev->of_node, "clock-output-names",
 				      &clk_init.name);
-	if (ret < 0) {
-		dev_err(dev, "Failed to read clock-output-names: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to read clock-output-names\n");
 
 	clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops;
 
 	mipi_tx->pll_hw.init = &clk_init;
 	mipi_tx->pll = devm_clk_register(dev, &mipi_tx->pll_hw);
-	if (IS_ERR(mipi_tx->pll)) {
-		ret = PTR_ERR(mipi_tx->pll);
-		dev_err(dev, "Failed to register PLL: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(mipi_tx->pll))
+		return dev_err_probe(dev, PTR_ERR(mipi_tx->pll), "Cannot register PLL\n");
 
 	phy = devm_phy_create(dev, NULL, &mtk_mipi_tx_ops);
-	if (IS_ERR(phy)) {
-		ret = PTR_ERR(phy);
-		dev_err(dev, "Failed to create MIPI D-PHY: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Failed to create MIPI D-PHY\n");
+
 	phy_set_drvdata(phy, mipi_tx);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-- 
2.33.1



From s.hauer at pengutronix.de  Mon Jan  3 06:55:03 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 3 Jan 2022 15:55:03 +0100
Subject: [PATCH 22/22] drm: rockchip: Add VOP2 driver
In-Reply-To: <1761858.GBYTvM79DV@archbook>
References: <20211220110630.3521121-1-s.hauer@pengutronix.de>
 <20211220110630.3521121-23-s.hauer@pengutronix.de>
 <1761858.GBYTvM79DV@archbook>
Message-ID: <20220103145503.GH6003@pengutronix.de>

Hi Nicolas,

Thanks for the review. I have changed the points I don't comment on here
according to your suggestions.

> > +#include <linux/regmap.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/delay.h>
> > +#include <linux/swab.h>
> > +#include <linux/bitfield.h>
> > +#include <drm/drm_debugfs.h>
> > +#include <uapi/linux/videodev2.h>
> > +#include <drm/drm_vblank.h>
> > +#include <dt-bindings/soc/rockchip,vop2.h>
> 
> Alphabetically sort these includes? Not sure on what the
> convention is in the DRM subsystem.

Me neither. The first random file I looked at in drivers/gpu/drm/ has
the includes sorted alphabetically, so I'll do the same.

> 
> > +static void vop2_cfg_done(struct vop2_video_port *vp)
> > +{
> > +	struct vop2 *vop2 = vp->vop2;
> > +	uint32_t val;
> > +
> > +	val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
> > +
> > +	val &= 0x7;
> 
> GENMASK(2, 0) instead of 0x7, should that be a constant somewhere?
> 
> > +
> > +	vop2_writel(vop2, RK3568_REG_CFG_DONE,
> > +		    val | BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);

Replaced that with the following which doesn't need a mask:

	regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE,
				BIT(vp->id) | RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);


> > +}
> > +
> > +static void vop2_win_disable(struct vop2_win *win)
> > +{
> > +	vop2_win_write(win, VOP2_WIN_ENABLE, 0);
> > +
> > +	if (vop2_cluster_window(win))
> > +		vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0);
> > +}
> > +
> > +static uint32_t vop2_afbc_transform_offset(struct drm_plane_state *pstate,
> > +					   bool afbc_half_block_en)
> > +{
> > +	struct drm_rect *src = &pstate->src;
> > +	struct drm_framebuffer *fb = pstate->fb;
> > +	uint32_t bpp = fb->format->cpp[0] * 8;
> > +	uint32_t vir_width = (fb->pitches[0] << 3) / bpp;
> > +	uint32_t width = drm_rect_width(src) >> 16;
> > +	uint32_t height = drm_rect_height(src) >> 16;
> > +	uint32_t act_xoffset = src->x1 >> 16;
> > +	uint32_t act_yoffset = src->y1 >> 16;
> > +	uint32_t align16_crop = 0;
> > +	uint32_t align64_crop = 0;
> > +	uint32_t height_tmp = 0;
> > +	uint32_t transform_tmp = 0;
> > +	uint8_t transform_xoffset = 0;
> > +	uint8_t transform_yoffset = 0;
> > +	uint8_t top_crop = 0;
> > +	uint8_t top_crop_line_num = 0;
> > +	uint8_t bottom_crop_line_num = 0;
> > +
> > +	/* 16 pixel align */
> > +	if (height & 0xf)
> > +		align16_crop = 16 - (height & 0xf);
> > +
> > +	height_tmp = height + align16_crop;
> > +
> > +	/* 64 pixel align */
> > +	if (height_tmp & 0x3f)
> > +		align64_crop = 64 - (height_tmp & 0x3f);
> > +
> > +	top_crop_line_num = top_crop << 2;
> > +	if (top_crop == 0)
> > +		bottom_crop_line_num = align16_crop + align64_crop;
> > +	else if (top_crop == 1)
> > +		bottom_crop_line_num = align16_crop + align64_crop + 12;
> > +	else if (top_crop == 2)
> > +		bottom_crop_line_num = align16_crop + align64_crop + 8;
> 
> top_crop == 0 is always taken from what I can gather, rest is
> dead code. Is this intentional? It doesn't seem intentional.

It's the same in the downstream driver. I don't know what top_crop is
good for. I just removed the dead code for now.

> > +		transform_xoffset = transform_tmp & 0xf;
> > +		transform_tmp = vir_width - width - act_xoffset;
> > +		transform_yoffset = transform_tmp & 0xf;
> > +		break;
> > +	case 0:
> > +		transform_tmp = act_xoffset;
> > +		transform_xoffset = transform_tmp & 0xf;
> > +		transform_tmp = top_crop_line_num + act_yoffset;
> > +
> > +		if (afbc_half_block_en)
> > +			transform_yoffset = transform_tmp & 0x7;
> > +		else
> > +			transform_yoffset = transform_tmp & 0xf;
> > +
> > +		break;
> > +	}
> > +
> > +	return (transform_xoffset & 0xf) | ((transform_yoffset & 0xf) << 16);
> > +}
> 
> 0xf, 0x3f, 0x7 might be more clear as GENMASK.
> if (afbc_half_block_en) branches can be moved out of cases and
> assign a transform mask variable instead.

Sure. Other than that the function can be simplified a bit more.

> 
> > +
> > +/*
> > + * A Cluster window has 2048 x 16 line buffer, which can
> > + * works at 2048 x 16(Full) or 4096 x 8 (Half) mode.
> > + * for Cluster_lb_mode register:
> > + * 0: half mode, for plane input width range 2048 ~ 4096
> > + * 1: half mode, for cluster work at 2 * 2048 plane mode
> > + * 2: half mode, for rotate_90/270 mode
> > + *
> > + */
> > +static int vop2_get_cluster_lb_mode(struct vop2_win *win, struct drm_plane_state *pstate)
> > +{
> > +	if ((pstate->rotation & DRM_MODE_ROTATE_270) || (pstate->rotation & DRM_MODE_ROTATE_90))
> > +		return 2;
> > +	else
> > +		return 0;
> > +}
> 
> What about 1?

1 is used in the downstream driver for cluster sub windows. These are
currently not supported, I don't know yet where this is leading to.

> 
> > +
> > +/*
> > + * bli_sd_factor = (src - 1) / (dst - 1) << 12;
> > + * avg_sd_factor:
> > + * bli_su_factor:
> > + * bic_su_factor:
> > + * = (src - 1) / (dst - 1) << 16;
> > + *
> > + * gt2 enable: dst get one line from two line of the src
> > + * gt4 enable: dst get one line from four line of the src.
> > + *
> > + */
> > +static uint16_t vop2_scale_factor(enum scale_mode mode,
> > +				  int32_t filter_mode,
> > +				  uint32_t src, uint32_t dst)
> > +{
> > +	uint32_t fac;
> > +	int i;
> > +
> > +	if (mode == SCALE_NONE)
> > +		return 0;
> > +
> > +	/*
> > +	 * A workaround to avoid zero div.
> > +	 */
> > +	if (dst == 1 || src == 1) {
> > +		dst++;
> > +		src++;
> > +	}
> > +
> > +	if ((mode == SCALE_DOWN) && (filter_mode == VOP2_SCALE_DOWN_BIL)) {
> > +		fac = ((src - 1) << 12) / (dst - 1);
> > +		for (i = 0; i < 100; i++) {
> > +			if (fac * (dst - 1) >> 12 < (src - 1))
> > +				break;
> > +			fac -= 1;
> > +			DRM_DEBUG("down fac cali: src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
> > +		}
> > +	} else {
> > +		fac = ((src - 1) << 16) / (dst - 1);
> > +		for (i = 0; i < 100; i++) {
> > +			if (fac * (dst - 1) >> 16 < (src - 1))
> > +				break;
> > +			fac -= 1;
> > +			DRM_DEBUG("up fac cali:  src:%d, dst:%d, fac:0x%x\n", src, dst, fac);
> > +		}
> > +	}
> > +
> > +	return fac;
> > +}
> 
> src = 0 or dst = 0 causes an uint underflow here.

Right. Looking at it these loops are rather unnecessary and duplicating
the code also. The whole function goes down to:

static uint16_t vop2_scale_factor(uint32_t src, uint32_t dst)
{
	uint32_t fac;
	int shift;

	if (src == dst)
		return 0;

	if (dst < 2)
		return U16_MAX;

	if (src < 2)
		return 0;

	if (src > dst)
		shift = 12;
	else
		shift = 16;

	src--;
	dst--;

	fac = DIV_ROUND_UP(src << shift, dst) - 1;

	if (fac > U16_MAX)
		return U16_MAX;

	return fac;
}


> > +static void vop2_enable(struct vop2 *vop2)
> > +{
> > +	int ret;
> > +	uint32_t v;
> > +
> > +	ret = pm_runtime_get_sync(vop2->dev);
> > +	if (ret < 0) {
> > +		drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
> > +		return;
> > +	}
> > +
> > +	ret = vop2_core_clks_prepare_enable(vop2);
> > +	if (ret) {
> > +		pm_runtime_put_sync(vop2->dev);
> > +		return;
> > +	}
> > +
> > +	if (vop2->data->soc_id == 3566)
> > +		vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
> > +
> > +	vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
> > +
> > +	/*
> > +	 * Disable auto gating, this is a workaround to
> > +	 * avoid display image shift when a window enabled.
> > +	 */
> > +	v = vop2_readl(vop2, RK3568_SYS_AUTO_GATING_CTRL);
> > +	v &= ~RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN;
> > +	vop2_writel(vop2, RK3568_SYS_AUTO_GATING_CTRL, v);
> > +
> > +	vop2_writel(vop2, RK3568_SYS0_INT_CLR,
> > +		    VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
> > +	vop2_writel(vop2, RK3568_SYS0_INT_EN,
> > +		    VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
> > +	vop2_writel(vop2, RK3568_SYS1_INT_CLR,
> > +		    VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
> > +	vop2_writel(vop2, RK3568_SYS1_INT_EN,
> > +		    VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
> > +}
> 
> Does reg writes but doesn't have the spinlock.

I didn't care about it at all when working on this driver, so we can be
sure it's at the wrong places right now.

I think we can just drop the register spinlock. The driver uses regmap
now, so read-modify-write accesses are covered by the regmap internal
locking as long as we use regmap_update_bits(). The remaining accesses
are either orthogonal anyway or are covered by the vop2_lock mutex.

> > +	vop2_lock(vop2);
> > +
> > +	ret = clk_prepare_enable(vp->dclk);
> > +	if (ret < 0) {
> > +		drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n",
> > +			      vp->id, ret);
> > +		return;
> 
> vop2_lock is never unlocked in this branch

I'll move the call to vop2_lock() below the clk_prepare_enable().

> > +	}
> > +
> > +	pm_runtime_put(vop2->dev);
> > +
> > +	return ret;
> > +}
> 
> Does reg writes, does the ISR need the reg spinlock here? I'm not
> sure.
> 
> In general there appear to be a lot of issues with the register
> lock, so either I'm misunderstanding what it's supposed to protect
> or the code is very thread unsafe.

Yeah, the original driver had the spinlock and as said I kept it but
didn't maintain it. Let's remove it for now.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From narmstrong at baylibre.com  Mon Jan  3 06:59:33 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 15:59:33 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
Message-ID: <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>

Hi Greg,

Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
earlycon support on the ARMv7 Amlogic SoCs fore 5.17.

Anyway, I'll push the corresponding DT fixes for 5.17-rc1.

Would it be possible we also receive the notification when those patches are applied ?
Maybe a MAINTAINERS entry is missing so we can receive them ?

It would help me track those TTY and USB patches more easily.

Thanks !

Neil

On 31/12/2021 16:35, Martin Blumenstingl wrote:
> On Fri, Dec 31, 2021 at 11:27 AM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>>> -/* Legacy bindings, should be removed when no more used */
>>>> -OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart",
>>>> -                   meson_serial_early_console_setup);
>>> This part is still needed as long as above series is not merged yet.
>>> If we remove this then earlycon will stop working on the 32-bit SoCs
>>> unless [0] is merged.
>>>
>>> All other code below - except the of_device_id entry - can still be
>>> removed since meson8.dtsi and meson8b.dtsi are using the non-legacy
>>> clocks already.
>>>
>>> Sorry for only noticing this now.
>>>
>> I will add it back in the next patch and delete it after your submission
>> is merged.
> I have just seen that Greg has already added this patch to the tty-next tree [1]
> In this case there's nothing to do on your end - I'll simply ask Neil
> to also queue my 32-bit SoC UART .dts fixes [0] for 5.17
> 
> 
> Best regards,
> Martin
> 
> 
> [0] https://patchwork.kernel.org/project/linux-amlogic/cover/20211227180026.4068352-1-martin.blumenstingl at googlemail.com/
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f
> 



From abel.vesa at nxp.com  Mon Jan  3 07:01:56 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Mon, 3 Jan 2022 17:01:56 +0200
Subject: [PATCH v2 2/3] interconnect: imx: Add imx_icc_get_bw and
 imx_icc_aggregate functions
In-Reply-To: <048650ad-e015-3733-bdf2-72b7a0ed61e4@kernel.org>
References: <20220101163956.3344467-1-abel.vesa@nxp.com>
 <20220101163956.3344467-2-abel.vesa@nxp.com>
 <048650ad-e015-3733-bdf2-72b7a0ed61e4@kernel.org>
Message-ID: <YdMP5P7Lwwkf6uRn@abelvesa>

On 22-01-01 20:26:05, Georgi Djakov wrote:
> Hi Abel,
> 
> On 1.01.22 18:39, Abel Vesa wrote:
> > The aggregate function will return whatever is the highest
> > rate for that specific node. The imx_icc_get_bw sets the
> 
> Adding some more details about why we switch from
> icc_std_aggregate to imx_icc_aggregate would be nice.
> 

On a second look, I think I can drop the imx_icc_aggregate and use the
icc_std_aggregate instead, as long as I use the peak_bw and forget about
the agg_bw.

> > initial avg and peak to 0 in order to avoid setting them to
> > INT_MAX by the interconnect core.
> 
> Do we need a Fixes tag for this?
> 

Neah, the imx interconnect is not used by any platform yet.

> I would recommend to split imx_icc_get_bw and imx_icc_aggregate
> changes into separate patches. These also seem to be unrelated to
> the imx_icc_node_adj_desc patchset.
> 

Since I can use icc_std_aggregate, the imx_icc_aggregate change will be
dropped.

> Thanks,
> Georgi
> 
> > Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> > ---
> > 
> > No changes since v1.
> > 
> >   drivers/interconnect/imx/imx.c | 20 +++++++++++++++++++-
> >   1 file changed, 19 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
> > index 34bfc7936387..4d8a2a2d2608 100644
> > --- a/drivers/interconnect/imx/imx.c
> > +++ b/drivers/interconnect/imx/imx.c
> > @@ -25,6 +25,23 @@ struct imx_icc_node {
> >   	struct dev_pm_qos_request qos_req;
> >   };
> > +static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
> > +{
> > +	*avg = 0;
> > +	*peak = 0;
> > +
> > +	return 0;
> > +}
> > +
> > +static int imx_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
> > +		      u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> > +{
> > +	*agg_avg = max(*agg_avg, avg_bw);
> > +	*agg_peak = max(*agg_peak, peak_bw);
> > +
> > +	return 0;
> > +}
> > +
> >   static int imx_icc_node_set(struct icc_node *node)
> >   {
> >   	struct device *dev = node->provider->dev;
> > @@ -233,7 +250,8 @@ int imx_icc_register(struct platform_device *pdev,
> >   	if (!provider)
> >   		return -ENOMEM;
> >   	provider->set = imx_icc_set;
> > -	provider->aggregate = icc_std_aggregate;
> > +	provider->get_bw = imx_icc_get_bw;
> > +	provider->aggregate = imx_icc_aggregate;
> >   	provider->xlate = of_icc_xlate_onecell;
> >   	provider->data = data;
> >   	provider->dev = dev;
>


From narmstrong at baylibre.com  Mon Jan  3 07:13:44 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:13:44 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc
Message-ID: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>

Hi,

Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
applied by greg in the tty branch for 5.17.

I know it's early for 5.17-rc1, but at least it's in the pipe.

I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
if necessary I can rebase on v5.16-rcX.

Neil

[1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f

The following changes since commit 8b0c59c622dc4dab970ec63264fb5b152944ac80:

  Revert "ARM: dts: BCM5301X: define RTL8365MB switch on Asus RT-AC88U" (2021-12-23 00:18:45 +0100)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-fixes-v5.17-rc

for you to fetch changes up to 7a31a29b35386b6d6aa622d68acd31739a3a8ac5:

  ARM: dts: meson8b: Fix the UART device-tree schema validation (2022-01-03 15:49:56 +0100)

----------------------------------------------------------------
Amlogic fixes for v5.17-rc
- meson6/meson8/meson8b UART compatible fixup to fix earlycon

----------------------------------------------------------------
Martin Blumenstingl (3):
      ARM: dts: meson: Fix the UART compatible strings
      ARM: dts: meson8: Fix the UART device-tree schema validation
      ARM: dts: meson8b: Fix the UART device-tree schema validation

 arch/arm/boot/dts/meson.dtsi   |  8 ++++----
 arch/arm/boot/dts/meson8.dtsi  | 24 ++++++++++++------------
 arch/arm/boot/dts/meson8b.dtsi | 24 ++++++++++++------------
 3 files changed, 28 insertions(+), 28 deletions(-)


From narmstrong at baylibre.com  Mon Jan  3 07:18:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:18:09 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <67d8cefc-d7c7-daba-bfe3-5935ded52beb@baylibre.com>

On 15/12/2021 04:02, Artem Lapkin wrote:
> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
> 
> Signed-off-by: Artem Lapkin <art at khadas.com>
> ---
> 
> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
> same as for VIM3 (meson-g12)
> 
> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
> 
> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
> 
> ALSA spdifin test example
> =========================
> 
> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
> 
> # cat .asoundrc
> pcm.spdifin {
> type iec958
> slave {
> pcm "hw:0,1"
> format IEC958_SUBFRAME_LE
> }
> }
> 
> DT sound card configs for testing
> =================================
> 
> &spdifout {
>     pinctrl-0 = <&spdif_ao_out_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
> 
> &spdifin {
>     pinctrl-0 = <&spdif_in_h_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
> 
> ...
>     spdif_dit: audio-codec-1 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dit";
> 	status = "okay";
> 	sound-name-prefix = "DIT";
>     };
> 
>     spdif_dir: audio-codec-2 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dir";
> 	status = "okay";
> 	sound-name-prefix = "DIR";
>     };
> ...
> 	audio-routing = ...
> 		"TODDR_B IN 3", "SPDIFIN Capture",
> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
> 
> ...
> 	dai-link-10 {
> 	    sound-dai = <&spdifout>;
> 
> 	    codec-0 {
> 		sound-dai = <&spdif_dit>;
> 	    };
> 	};
> 
> 	/* spdif or toslink interface */
> 	dai-link-11 {
> 	    sound-dai = <&spdifin>;
> 
> 	    codec-0 {
> 		sound-dai = <&spdif_dir>;
> 	    };
> 	};
> ...
> 
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> index 3d8b1f4f2001..1e0adf259d61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>  			status = "disabled";
>  		};
>  
> +		spdifin: audio-controller at 400 {
> +			compatible = "amlogic,g12a-spdifin",
> +			"amlogic,axg-spdifin";
> +			reg = <0x0 0x400 0x0 0x30>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFIN";
> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
> +			clock-names = "pclk", "refclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
> +			status = "disabled";
> +		};
> +
> +		spdifout: audio-controller at 480 {
> +			compatible = "amlogic,g12a-spdifout",
> +			"amlogic,axg-spdifout";
> +			reg = <0x0 0x480 0x0 0x50>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFOUT";
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
> +			clock-names = "pclk", "mclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
> +			status = "disabled";
> +		};
> +
>  		tdmout_a: audio-controller at 500 {
>  			compatible = "amlogic,sm1-tdmout";
>  			reg = <0x0 0x500 0x0 0x40>;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,
Neil


From gregkh at linuxfoundation.org  Mon Jan  3 07:19:47 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 3 Jan 2022 16:19:47 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
Message-ID: <YdMUEzStFf99EeQ5@kroah.com>

A: http://en.wikipedia.org/wiki/Top_post
Q: Were do I find info about this thing called top-posting?
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

A: No.
Q: Should I include quotations after my reply?

http://daringfireball.net/2007/07/on_top

On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
> Hi Greg,
> 
> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.

Ok, what should I revert?

> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.

How did we get out of sync here?

> Would it be possible we also receive the notification when those patches are applied ?
> Maybe a MAINTAINERS entry is missing so we can receive them ?

That would be good, so that people can review the patches.  Otherwise I
have to just guess :)

> It would help me track those TTY and USB patches more easily.

I recommend MAINTAINERS entries for drivers that are not listed and that
you care about seeing the changes for.

thanks,

greg k-h


From narmstrong at baylibre.com  Mon Jan  3 07:21:16 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:21:16 +0100
Subject: [RFC PATCH 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20211130060523.19161-7-christianshewitt@gmail.com>
References: <20211130060523.19161-1-christianshewitt@gmail.com>
 <20211130060523.19161-7-christianshewitt@gmail.com>
Message-ID: <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>

Hi,

On 30/11/2021 07:05, Christian Hewitt wrote:
> The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
> designs and ships in multiple configurations:
> 
> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ...
> - HDMI 2.1 video
> - S/PDIF optical output
> - AV output
> - 1x USB 2.0 OTG port
> - 1x USB 3.0 port
> - IR receiver
> - 1x micro SD card slot (internal)
> - 1x Reset/Update button (in AV jack)
> - 7-segment VFD
> - Multicolour case LED 'arc'
> 
> The device-tree with -100 suffix supports models with 10/100 Ethernet
> and with -1000 suffix supports models with Gigabit Ethernet.

I thought about this, and I think we should have:
- meson-sm1-a95xf3-air.dts for 10/100 version
- meson-sm1-a95xf3-air-gbit.dts for gigabit 10/100/1000 version

With this, I'm ok to apply the serie.

Neil

> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |   2 +
>  .../dts/amlogic/meson-sm1-a95xf3-air-100.dts  | 108 +++++++++++++++
>  .../dts/amlogic/meson-sm1-a95xf3-air-1000.dts | 129 ++++++++++++++++++
>  3 files changed, 239 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> 
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index a0c1a7fbae57..e198d17f2ea8 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-100.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-1000.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
> new file mode 100644
> index 000000000000..5158cc40485e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-100.dts
> @@ -0,0 +1,108 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "cyx,a95xf3-air-100", "amlogic,sm1";
> +	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "A95XF3-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +	phy-handle = <&internal_ephy>;
> +	phy-mode = "rmii";
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> new file mode 100644
> index 000000000000..c87d948fa3e6
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-1000.dts
> @@ -0,0 +1,129 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "cyx,a95xf3-air-1000", "amlogic,sm1";
> +	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "A95XF3-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +
> +	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
> +	pinctrl-names = "default";
> +	phy-mode = "rgmii-txid";
> +	phy-handle = <&external_phy>;
> +
> +	rx-internal-delay-ps = <800>;
> +};
> +
> +&ext_mdio {
> +	external_phy: ethernet-phy at 0 {
> +		/* Realtek RTL8211F (0x001cc916) */
> +		reg = <0>;
> +		max-speed = <1000>;
> +
> +		reset-assert-us = <10000>;
> +		reset-deassert-us = <80000>;
> +		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
> +
> +		interrupt-parent = <&gpio_intc>;
> +		/* MAC_INTR on GPIOZ_14 */
> +		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> 



From christianshewitt at gmail.com  Mon Jan  3 07:26:49 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon, 3 Jan 2022 19:26:49 +0400
Subject: [RFC PATCH 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>
References: <20211130060523.19161-1-christianshewitt@gmail.com>
 <20211130060523.19161-7-christianshewitt@gmail.com>
 <6ff128a6-91cb-5b83-737e-e703cab81743@baylibre.com>
Message-ID: <F8463510-1955-4826-BE05-20F3B4079ED4@gmail.com>


> On 3 Jan 2022, at 7:21 pm, Neil Armstrong <narmstrong at baylibre.com> wrote:
> 
> Hi,
> 
> On 30/11/2021 07:05, Christian Hewitt wrote:
>> The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
>> designs and ships in multiple configurations:
>> 
>> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
>> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
>> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
>> ...
>> - HDMI 2.1 video
>> - S/PDIF optical output
>> - AV output
>> - 1x USB 2.0 OTG port
>> - 1x USB 3.0 port
>> - IR receiver
>> - 1x micro SD card slot (internal)
>> - 1x Reset/Update button (in AV jack)
>> - 7-segment VFD
>> - Multicolour case LED 'arc'
>> 
>> The device-tree with -100 suffix supports models with 10/100 Ethernet
>> and with -1000 suffix supports models with Gigabit Ethernet.
> 
> I thought about this, and I think we should have:
> - meson-sm1-a95xf3-air.dts for 10/100 version
> - meson-sm1-a95xf3-air-gbit.dts for gigabit 10/100/1000 version
> 
> With this, I'm ok to apply the serie.
> 
> Neil

That?s fine with me, thanks for the review. I?ll rework the patches and
send a v2 series to the list.

Christian



From narmstrong at baylibre.com  Mon Jan  3 07:29:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 16:29:56 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <YdMUEzStFf99EeQ5@kroah.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
Message-ID: <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>

Hi Greg,
On 03/01/2022 16:19, Greg Kroah-Hartman wrote:
> A: http://en.wikipedia.org/wiki/Top_post
> Q: Were do I find info about this thing called top-posting?
> A: Because it messes up the order in which people normally read text.
> Q: Why is top-posting such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing in e-mail?
> 
> A: No.
> Q: Should I include quotations after my reply?
> 
> http://daringfireball.net/2007/07/on_to>
> On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
>> Hi Greg,
>>
>> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
>> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.
> 
> Ok, what should I revert?

None, we have a fix in the pipe

> 
>> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.
> 
> How did we get out of sync here?

The serie wasn't fully reviewed, and I was out of office when it was applied.

> 
>> Would it be possible we also receive the notification when those patches are applied ?
>> Maybe a MAINTAINERS entry is missing so we can receive them ?
> 
> That would be good, so that people can review the patches.  Otherwise I
> have to just guess :)

exact, I naively thought it would be matched in the:
N:      meson
entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.

> 
>> It would help me track those TTY and USB patches more easily.
> 
> I recommend MAINTAINERS entries for drivers that are not listed and that
> you care about seeing the changes for.

This is why we have a regex to match these.

I can submit a patch to have a proper entry if the regex is not enough/appropriate.

BTW can you point us how are selected the recipients of the notification messages you send ?

Thanks,
Neil

> 
> thanks,
> 
> greg k-h
> 



From angelogioacchino.delregno at collabora.com  Mon Jan  3 07:30:53 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 16:30:53 +0100
Subject: [PATCH 2/4] phy: mediatek: phy-mtk-hdmi: Reorder to remove forward
 declarations
In-Reply-To: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103153055.50473-2-angelogioacchino.delregno@collabora.com>

Forward declarations for mtk_hdmi_power_{on,off} aren't necessary:
move mtk_hdmi_phy_dev_ops down to remove forward declarations.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 707e90691e6e..b4193cb4e4e3 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -6,15 +6,6 @@
 
 #include "phy-mtk-hdmi.h"
 
-static int mtk_hdmi_phy_power_on(struct phy *phy);
-static int mtk_hdmi_phy_power_off(struct phy *phy);
-
-static const struct phy_ops mtk_hdmi_phy_dev_ops = {
-	.power_on = mtk_hdmi_phy_power_on,
-	.power_off = mtk_hdmi_phy_power_off,
-	.owner = THIS_MODULE,
-};
-
 inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
 {
 	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
@@ -43,6 +34,12 @@ static int mtk_hdmi_phy_power_off(struct phy *phy)
 	return 0;
 }
 
+static const struct phy_ops mtk_hdmi_phy_dev_ops = {
+	.power_on = mtk_hdmi_phy_power_on,
+	.power_off = mtk_hdmi_phy_power_off,
+	.owner = THIS_MODULE,
+};
+
 static const struct phy_ops *
 mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
 {
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 07:30:52 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 16:30:52 +0100
Subject: [PATCH 1/4] phy: mediatek: phy-mtk-hdmi: Switch to regmap for mmio
 access
Message-ID: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>

Switch to using the generic regmap API instead of calls to readl/writel
for MMIO register access, removing custom crafted update/set/clear_bits
functions and also allowing us to reduce code size.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 165 ++++++++++-----------
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c | 126 ++++++++--------
 drivers/phy/mediatek/phy-mtk-hdmi.c        |  51 ++-----
 drivers/phy/mediatek/phy-mtk-hdmi.h        |   9 +-
 4 files changed, 158 insertions(+), 193 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
index b74c65a1762c..09e0dd7499d8 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
@@ -69,19 +69,19 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON7, RG_HTPLL_AUTOK_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_RLH_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_MBIAS);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
 	usleep_range(80, 100);
 	return 0;
 }
@@ -90,19 +90,19 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_MBIAS);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_RLH_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON7, RG_HTPLL_AUTOK_EN);
 	usleep_range(80, 100);
 }
 
@@ -125,37 +125,34 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	else
 		pos_div = 1;
 
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
-			  RG_HTPLL_IC_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
-			  RG_HTPLL_IR_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div << RG_HDMITX_TX_POSDIV),
-			  RG_HDMITX_TX_POSDIV_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL),
-			  RG_HTPLL_FBKSEL_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV),
-			  RG_HTPLL_FBKDIV_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN),
-			  RG_HTPLL_DIVEN_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP),
-			  RG_HTPLL_BP_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC),
-			  RG_HTPLL_BC_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR),
-			  RG_HTPLL_BR_MASK);
-
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PRED_IMP);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 << RG_HDMITX_PRED_IBIAS),
-			  RG_HDMITX_PRED_IBIAS_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_IMP_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 << RG_HDMITX_DRV_IMP),
-			  RG_HDMITX_DRV_IMP_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28, RG_HDMITX_RESERVE_MASK);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa << RG_HDMITX_DRV_IBIAS),
-			  RG_HDMITX_DRV_IBIAS_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_PREDIV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_TX_POSDIV);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_IC_MASK, BIT(RG_HTPLL_IC));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_IR_MASK, BIT(RG_HTPLL_IR));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_TX_POSDIV_MASK,
+			   (pos_div << RG_HDMITX_TX_POSDIV));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_FBKSEL_MASK,
+			   (1 << RG_HTPLL_FBKSEL));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_FBKDIV_MASK,
+			   (19 << RG_HTPLL_FBKDIV));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON7, RG_HTPLL_DIVEN_MASK,
+			   (0x2 << RG_HTPLL_DIVEN));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_BP_MASK,
+			   (0xc << RG_HTPLL_BP));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_BC_MASK,
+			   (0x2 << RG_HTPLL_BC));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_BR_MASK, BIT(RG_HTPLL_BR));
+
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PRED_IMP);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PRED_IBIAS_MASK,
+			   (0x3 << RG_HDMITX_PRED_IBIAS));
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_IMP_MASK);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_DRV_IMP_MASK,
+			   (0x28 << RG_HDMITX_DRV_IMP));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON4, RG_HDMITX_RESERVE_MASK, 0x28);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_DRV_IBIAS_MASK,
+			   (0xa << RG_HDMITX_DRV_IBIAS));
 	return 0;
 }
 
@@ -163,10 +160,11 @@ static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
 					      unsigned long parent_rate)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
-	unsigned long out_rate, val;
+	unsigned long out_rate;
+	u32 val;
 
-	val = (readl(hdmi_phy->regs + HDMI_CON6)
-	       & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
+	regmap_read(hdmi_phy->regmap, HDMI_CON6, &val);
+	val = (val & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
 	switch (val) {
 	case 0x00:
 		out_rate = parent_rate;
@@ -179,14 +177,15 @@ static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
 		break;
 	}
 
-	val = (readl(hdmi_phy->regs + HDMI_CON6)
-	       & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
+	regmap_read(hdmi_phy->regmap, HDMI_CON6, &val);
+	val = (val & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
 	out_rate *= (val + 1) * 2;
-	val = (readl(hdmi_phy->regs + HDMI_CON2)
-	       & RG_HDMITX_TX_POSDIV_MASK);
+	regmap_read(hdmi_phy->regmap, HDMI_CON2, &val);
+	val &= RG_HDMITX_TX_POSDIV_MASK;
 	out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
 
-	if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
+	regmap_read(hdmi_phy->regmap, HDMI_CON2, &val);
+	if (val & RG_HDMITX_EN_TX_POSDIV)
 		out_rate /= 5;
 
 	return out_rate;
@@ -202,37 +201,37 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 
 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 {
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON7, RG_HTPLL_AUTOK_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_RLH_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_MBIAS);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
 	usleep_range(80, 100);
 }
 
 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 {
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_DRV_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_PRED_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SER_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_MBIAS_LPF_EN);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_EN_SLDO_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_TX_CKLDO);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
 	usleep_range(80, 100);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2, RG_HDMITX_EN_MBIAS);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_POSDIV_MASK);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_RLH_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON7, RG_HTPLL_AUTOK_EN);
 	usleep_range(80, 100);
 }
 
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
index 6cdfdf5a698a..e317bf4a9db9 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
@@ -111,15 +111,15 @@ static int mtk_hdmi_pll_prepare(struct clk_hw *hw)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3, RG_HDMITX_MHLCK_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3, RG_HDMITX_MHLCK_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
 	usleep_range(100, 150);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_EN);
 	usleep_range(100, 150);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
 
 	return 0;
 }
@@ -128,14 +128,14 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw)
 {
 	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
 
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_TXDIV_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_BIAS_LPF_EN);
 	usleep_range(100, 150);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_EN);
 	usleep_range(100, 150);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_BIAS_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_AUTOK_EN);
 	usleep_range(100, 150);
 }
 
@@ -177,65 +177,59 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 		div = 1;
 	}
 
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
-			  (pre_div << PREDIV_SHIFT), RG_HDMITX_PLL_PREDIV);
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
-			  (0x1 << PLL_IC_SHIFT) | (0x1 << PLL_IR_SHIFT),
-			  RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
-			  (div << PLL_TXDIV_SHIFT), RG_HDMITX_PLL_TXDIV);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
-			  (0x1 << PLL_FBKSEL_SHIFT) | (19 << PLL_FBKDIV_SHIFT),
-			  RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
-			  (0x2 << PLL_DIVEN_SHIFT), RG_HDMITX_PLL_DIVEN);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
-			  (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT) |
-			  (0x1 << PLL_BR_SHIFT),
-			  RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
-			  RG_HDMITX_PLL_BR);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_PREDIV,
+			   (pre_div << PREDIV_SHIFT));
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_POSDIV);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
+			   RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR,
+			   BIT(PLL_IC_SHIFT) | BIT(PLL_IR_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_TXDIV,
+			   (div << PLL_TXDIV_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
+			   RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV,
+			  BIT(PLL_FBKSEL_SHIFT) | (19 << PLL_FBKDIV_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1, RG_HDMITX_PLL_DIVEN,
+			   (0x2 << PLL_DIVEN_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
+			   RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC | RG_HDMITX_PLL_BR,
+			   (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT) |
+			   (0x1 << PLL_BR_SHIFT));
 	if (rate < 165000000) {
-		mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
+		regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3,
 					RG_HDMITX_PRD_IMP_EN);
 		pre_ibias = 0x3;
 		imp_en = 0x0;
 		hdmi_ibias = hdmi_phy->ibias;
 	} else {
-		mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
+		regmap_set_bits(hdmi_phy->regmap, HDMI_CON3,
 				      RG_HDMITX_PRD_IMP_EN);
 		pre_ibias = 0x6;
 		imp_en = 0xf;
 		hdmi_ibias = hdmi_phy->ibias_up;
 	}
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
-			  (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
-			  (pre_ibias << PRD_IBIAS_D2_SHIFT) |
-			  (pre_ibias << PRD_IBIAS_D1_SHIFT) |
-			  (pre_ibias << PRD_IBIAS_D0_SHIFT),
-			  RG_HDMITX_PRD_IBIAS_CLK |
-			  RG_HDMITX_PRD_IBIAS_D2 |
-			  RG_HDMITX_PRD_IBIAS_D1 |
-			  RG_HDMITX_PRD_IBIAS_D0);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
-			  (imp_en << DRV_IMP_EN_SHIFT),
-			  RG_HDMITX_DRV_IMP_EN);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
-			  (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
-			  (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
-			  (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
-			  (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
-			  RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
-			  RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
-	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
-			  (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
-			  (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
-			  (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
-			  (hdmi_ibias << DRV_IBIAS_D0_SHIFT),
-			  RG_HDMITX_DRV_IBIAS_CLK |
-			  RG_HDMITX_DRV_IBIAS_D2 |
-			  RG_HDMITX_DRV_IBIAS_D1 |
-			  RG_HDMITX_DRV_IBIAS_D0);
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON4,
+			   RG_HDMITX_PRD_IBIAS_CLK | RG_HDMITX_PRD_IBIAS_D2 |
+			   RG_HDMITX_PRD_IBIAS_D1 | RG_HDMITX_PRD_IBIAS_D0,
+			   (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
+			   (pre_ibias << PRD_IBIAS_D2_SHIFT) |
+			   (pre_ibias << PRD_IBIAS_D1_SHIFT) |
+			   (pre_ibias << PRD_IBIAS_D0_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON3, RG_HDMITX_DRV_IMP_EN,
+			   (imp_en << DRV_IMP_EN_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
+			   RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2 |
+			   RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0,
+			   (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT) |
+			   (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
+			   (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
+			   (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT));
+	regmap_update_bits(hdmi_phy->regmap, HDMI_CON5,
+			   RG_HDMITX_DRV_IBIAS_CLK | RG_HDMITX_DRV_IBIAS_D2 |
+			   RG_HDMITX_DRV_IBIAS_D1 | RG_HDMITX_DRV_IBIAS_D0,
+			   (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
+			   (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
+			   (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
+			   (hdmi_ibias << DRV_IBIAS_D0_SHIFT));
 	return 0;
 }
 
@@ -257,17 +251,15 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = {
 
 static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 {
-	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
-			      RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
-			      RG_HDMITX_DRV_EN);
+	regmap_set_bits(hdmi_phy->regmap, HDMI_CON3,
+			RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN | RG_HDMITX_DRV_EN);
 	usleep_range(100, 150);
 }
 
 static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
 {
-	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
-				RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
-				RG_HDMITX_SER_EN);
+	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3,
+			  RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN | RG_HDMITX_SER_EN);
 }
 
 struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index 5fb4217fb8e0..707e90691e6e 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -15,39 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops = {
 	.owner = THIS_MODULE,
 };
 
-void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-			     u32 bits)
-{
-	void __iomem *reg = hdmi_phy->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp &= ~bits;
-	writel(tmp, reg);
-}
-
-void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-			   u32 bits)
-{
-	void __iomem *reg = hdmi_phy->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp |= bits;
-	writel(tmp, reg);
-}
-
-void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-		       u32 val, u32 mask)
-{
-	void __iomem *reg = hdmi_phy->regs + offset;
-	u32 tmp;
-
-	tmp = readl(reg);
-	tmp = (tmp & ~mask) | (val & mask);
-	writel(tmp, reg);
-}
-
 inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
 {
 	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
@@ -96,6 +63,13 @@ static void mtk_hdmi_phy_clk_get_data(struct mtk_hdmi_phy *hdmi_phy,
 	clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
 }
 
+static const struct regmap_config mtk_hdmi_phy_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.disable_locking = true,
+};
+
 static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -109,15 +83,20 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 
 	struct phy *phy;
 	struct phy_provider *phy_provider;
+	void __iomem *regs;
 	int ret;
 
 	hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL);
 	if (!hdmi_phy)
 		return -ENOMEM;
 
-	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(hdmi_phy->regs))
-		return PTR_ERR(hdmi_phy->regs);
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	hdmi_phy->regmap = devm_regmap_init_mmio(dev, regs, &mtk_hdmi_phy_regmap_config);
+	if (IS_ERR(hdmi_phy->regmap))
+		return PTR_ERR(hdmi_phy->regmap);
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
 	if (IS_ERR(ref_clk)) {
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h
index dcf9bb13699b..a0571271d730 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -15,6 +15,7 @@
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/types.h>
 
 struct mtk_hdmi_phy;
@@ -28,7 +29,7 @@ struct mtk_hdmi_phy_conf {
 };
 
 struct mtk_hdmi_phy {
-	void __iomem *regs;
+	struct regmap *regmap;
 	struct device *dev;
 	struct mtk_hdmi_phy_conf *conf;
 	struct clk *pll;
@@ -42,12 +43,6 @@ struct mtk_hdmi_phy {
 	unsigned int ibias_up;
 };
 
-void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-			     u32 bits);
-void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-			   u32 bits);
-void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
-		       u32 val, u32 mask);
 struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
 
 extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 07:30:54 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 16:30:54 +0100
Subject: [PATCH 3/4] phy: mediatek: phy-mtk-hdmi: Reorder and stop implicit
 header inclusion
In-Reply-To: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103153055.50473-3-angelogioacchino.delregno@collabora.com>

All the headers for phy-mtk-{hdmi,hdmi-mt2701,hdmi-mt8183}.c were
included from phy-mtk-mipi-dsi.h, but this isn't optimal: in order to
increase readability and sensibly reduce build times, the inclusions
should be done per-file, also avoiding to include unused headers and
should not be implicit.

For this reason, move the inclusions to each file and remove unused ones.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c |  5 +++++
 drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c |  5 +++++
 drivers/phy/mediatek/phy-mtk-hdmi.c        |  8 ++++++++
 drivers/phy/mediatek/phy-mtk-hdmi.h        | 10 +---------
 4 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
index 09e0dd7499d8..270c5f538483 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
@@ -4,6 +4,11 @@
  * Author: Chunhui Dai <chunhui.dai at mediatek.com>
  */
 
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
 #include "phy-mtk-hdmi.h"
 
 #define HDMI_CON0	0x00
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
index e317bf4a9db9..87ba9a3687b7 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
@@ -4,6 +4,11 @@
  * Author: Jie Qiu <jie.qiu at mediatek.com>
  */
 
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
 #include "phy-mtk-hdmi.h"
 
 #define HDMI_CON0		0x00
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index b4193cb4e4e3..e037fa89696c 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -4,6 +4,14 @@
  * Author: Jie Qiu <jie.qiu at mediatek.com>
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/phy/phy.h>
 #include "phy-mtk-hdmi.h"
 
 inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h b/drivers/phy/mediatek/phy-mtk-hdmi.h
index a0571271d730..ef81e44a235d 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
@@ -6,17 +6,9 @@
 
 #ifndef _MTK_HDMI_PHY_H
 #define _MTK_HDMI_PHY_H
-#include <linux/clk.h>
+
 #include <linux/clk-provider.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/mfd/syscon.h>
-#include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/phy/phy.h>
-#include <linux/platform_device.h>
 #include <linux/regmap.h>
-#include <linux/types.h>
 
 struct mtk_hdmi_phy;
 
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 07:30:55 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 16:30:55 +0100
Subject: [PATCH 4/4] phy: mediatek: phy-mtk-hdmi: Simplify with dev_err_probe()
In-Reply-To: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220103153055.50473-4-angelogioacchino.delregno@collabora.com>

Use the dev_err_probe() helper to simplify error handling during probe.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/phy/mediatek/phy-mtk-hdmi.c | 50 +++++++++++------------------
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c b/drivers/phy/mediatek/phy-mtk-hdmi.c
index e037fa89696c..4f40a6eea004 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
@@ -104,20 +104,16 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 		return PTR_ERR(hdmi_phy->regmap);
 
 	ref_clk = devm_clk_get(dev, "pll_ref");
-	if (IS_ERR(ref_clk)) {
-		ret = PTR_ERR(ref_clk);
-		dev_err(&pdev->dev, "Failed to get PLL reference clock: %d\n",
-			ret);
-		return ret;
-	}
+	if (IS_ERR(ref_clk))
+		return dev_err_probe(dev, PTR_ERR(ref_clk),
+				     "Failed to get PLL reference clock\n");
+
 	ref_clk_name = __clk_get_name(ref_clk);
 
 	ret = of_property_read_string(dev->of_node, "clock-output-names",
 				      &clk_init.name);
-	if (ret < 0) {
-		dev_err(dev, "Failed to read clock-output-names: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to read clock-output-names\n");
 
 	hdmi_phy->dev = dev;
 	hdmi_phy->conf =
@@ -125,25 +121,19 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init);
 	hdmi_phy->pll_hw.init = &clk_init;
 	hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
-	if (IS_ERR(hdmi_phy->pll)) {
-		ret = PTR_ERR(hdmi_phy->pll);
-		dev_err(dev, "Failed to register PLL: %d\n", ret);
-		return ret;
-	}
+	if (IS_ERR(hdmi_phy->pll))
+		return dev_err_probe(dev, PTR_ERR(hdmi_phy->pll),
+				    "Failed to register PLL\n");
 
 	ret = of_property_read_u32(dev->of_node, "mediatek,ibias",
 				   &hdmi_phy->ibias);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get ibias\n");
 
 	ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up",
 				   &hdmi_phy->ibias_up);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get ibias up: %d\n", ret);
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to get ibias_up\n");
 
 	dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n");
 	hdmi_phy->drv_imp_clk = 0x30;
@@ -152,17 +142,15 @@ static int mtk_hdmi_phy_probe(struct platform_device *pdev)
 	hdmi_phy->drv_imp_d0 = 0x30;
 
 	phy = devm_phy_create(dev, NULL, mtk_hdmi_phy_dev_get_ops(hdmi_phy));
-	if (IS_ERR(phy)) {
-		dev_err(dev, "Failed to create HDMI PHY\n");
-		return PTR_ERR(phy);
-	}
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy), "Cannot create HDMI PHY\n");
+
 	phy_set_drvdata(phy, hdmi_phy);
 
 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
-	if (IS_ERR(phy_provider)) {
-		dev_err(dev, "Failed to register HDMI PHY\n");
-		return PTR_ERR(phy_provider);
-	}
+	if (IS_ERR(phy_provider))
+		return dev_err_probe(dev, PTR_ERR(phy_provider),
+				     "Failed to register HDMI PHY\n");
 
 	if (hdmi_phy->conf->pll_default_off)
 		hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan  3 07:35:06 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon,  3 Jan 2022 16:35:06 +0100
Subject: [PATCH] pwm: pwm-mtk-disp: Switch to regmap for mmio access
Message-ID: <20220103153506.50896-1-angelogioacchino.delregno@collabora.com>

Switch to using the generic regmap API instead of calls to readl/writel
for MMIO register access, allowing us to reduce code size.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/pwm/pwm-mtk-disp.c | 77 ++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 45 deletions(-)

diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c
index c605013e4114..4a6fab144cee 100644
--- a/drivers/pwm/pwm-mtk-disp.c
+++ b/drivers/pwm/pwm-mtk-disp.c
@@ -14,6 +14,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
 #define DISP_PWM_EN		0x00
@@ -47,7 +48,7 @@ struct mtk_disp_pwm {
 	const struct mtk_pwm_data *data;
 	struct clk *clk_main;
 	struct clk *clk_mm;
-	void __iomem *base;
+	struct regmap *regmap;
 	bool enabled;
 };
 
@@ -56,22 +57,11 @@ static inline struct mtk_disp_pwm *to_mtk_disp_pwm(struct pwm_chip *chip)
 	return container_of(chip, struct mtk_disp_pwm, chip);
 }
 
-static void mtk_disp_pwm_update_bits(struct mtk_disp_pwm *mdp, u32 offset,
-				     u32 mask, u32 data)
-{
-	void __iomem *address = mdp->base + offset;
-	u32 value;
-
-	value = readl(address);
-	value &= ~mask;
-	value |= data;
-	writel(value, address);
-}
-
 static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 			      const struct pwm_state *state)
 {
 	struct mtk_disp_pwm *mdp = to_mtk_disp_pwm(chip);
+	const struct mtk_pwm_data *pdata = mdp->data;
 	u32 clk_div, period, high_width, value;
 	u64 div, rate;
 	int err;
@@ -80,8 +70,7 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 		return -EINVAL;
 
 	if (!state->enabled) {
-		mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
-					 0x0);
+		regmap_clear_bits(mdp->regmap, DISP_PWM_EN, pdata->enable_mask);
 
 		if (mdp->enabled) {
 			clk_disable_unprepare(mdp->clk_mm);
@@ -138,37 +127,25 @@ static int mtk_disp_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 	high_width = mul_u64_u64_div_u64(state->duty_cycle, rate, div);
 	value = period | (high_width << PWM_HIGH_WIDTH_SHIFT);
 
-	mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-				 PWM_CLKDIV_MASK,
-				 clk_div << PWM_CLKDIV_SHIFT);
-	mtk_disp_pwm_update_bits(mdp, mdp->data->con1,
-				 PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK,
-				 value);
+	regmap_update_bits(mdp->regmap, pdata->con0, PWM_CLKDIV_MASK,
+			   clk_div << PWM_CLKDIV_SHIFT);
+	regmap_update_bits(mdp->regmap, pdata->con1,
+			   PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK, value);
 
 	if (mdp->data->has_commit) {
-		mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
-					 mdp->data->commit_mask,
-					 mdp->data->commit_mask);
-		mtk_disp_pwm_update_bits(mdp, mdp->data->commit,
-					 mdp->data->commit_mask,
-					 0x0);
+		regmap_set_bits(mdp->regmap, pdata->commit, pdata->commit_mask);
+		regmap_clear_bits(mdp->regmap, pdata->commit, pdata->commit_mask);
 	} else {
 		/*
 		 * For MT2701, disable double buffer before writing register
 		 * and select manual mode and use PWM_PERIOD/PWM_HIGH_WIDTH.
 		 */
-		mtk_disp_pwm_update_bits(mdp, mdp->data->bls_debug,
-					 mdp->data->bls_debug_mask,
-					 mdp->data->bls_debug_mask);
-		mtk_disp_pwm_update_bits(mdp, mdp->data->con0,
-					 mdp->data->con0_sel,
-					 mdp->data->con0_sel);
+		regmap_set_bits(mdp->regmap, pdata->bls_debug, pdata->bls_debug_mask);
+		regmap_set_bits(mdp->regmap, pdata->con0, pdata->con0_sel);
 	}
 
-	mtk_disp_pwm_update_bits(mdp, DISP_PWM_EN, mdp->data->enable_mask,
-				 mdp->data->enable_mask);
+	regmap_set_bits(mdp->regmap, DISP_PWM_EN, pdata->enable_mask);
 	mdp->enabled = true;
-
 	return 0;
 }
 
@@ -195,8 +172,8 @@ static void mtk_disp_pwm_get_state(struct pwm_chip *chip,
 	}
 
 	rate = clk_get_rate(mdp->clk_main);
-	con0 = readl(mdp->base + mdp->data->con0);
-	con1 = readl(mdp->base + mdp->data->con1);
+	regmap_read(mdp->regmap, mdp->data->con0, &con0);
+	regmap_read(mdp->regmap, mdp->data->con1, &con1);
 	state->enabled = !!(con0 & BIT(0));
 	clk_div = FIELD_GET(PWM_CLKDIV_MASK, con0);
 	period = FIELD_GET(PWM_PERIOD_MASK, con1);
@@ -219,9 +196,17 @@ static const struct pwm_ops mtk_disp_pwm_ops = {
 	.owner = THIS_MODULE,
 };
 
+static const struct regmap_config mtk_disp_pwm_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.disable_locking = true,
+};
+
 static int mtk_disp_pwm_probe(struct platform_device *pdev)
 {
 	struct mtk_disp_pwm *mdp;
+	void __iomem *base;
 	int ret;
 
 	mdp = devm_kzalloc(&pdev->dev, sizeof(*mdp), GFP_KERNEL);
@@ -230,9 +215,13 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 
 	mdp->data = of_device_get_match_data(&pdev->dev);
 
-	mdp->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(mdp->base))
-		return PTR_ERR(mdp->base);
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	mdp->regmap = devm_regmap_init_mmio(&pdev->dev, base, &mtk_disp_pwm_regmap_config);
+	if (IS_ERR(mdp->regmap))
+		return PTR_ERR(mdp->regmap);
 
 	mdp->clk_main = devm_clk_get(&pdev->dev, "main");
 	if (IS_ERR(mdp->clk_main))
@@ -247,10 +236,8 @@ static int mtk_disp_pwm_probe(struct platform_device *pdev)
 	mdp->chip.npwm = 1;
 
 	ret = pwmchip_add(&mdp->chip);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "pwmchip_add() failed: %pe\n", ERR_PTR(ret));
-		return ret;
-	}
+	if (ret < 0)
+		return dev_err_probe(&pdev->dev, ret, "pwmchip_add() failed\n");
 
 	platform_set_drvdata(pdev, mdp);
 
-- 
2.33.1



From jbrunet at baylibre.com  Mon Jan  3 07:35:23 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 03 Jan 2022 16:35:23 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>


On Wed 15 Dec 2021 at 11:02, Artem Lapkin <email2tema at gmail.com> wrote:

> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
             ^ add (same in the title)

>
> Signed-off-by: Artem Lapkin <art at khadas.com>
> ---
>
> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
> same as for VIM3 (meson-g12)
>
> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
>
> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
>
> ALSA spdifin test example
> =========================
>
> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
>
> # cat .asoundrc
> pcm.spdifin {
> type iec958
> slave {
> pcm "hw:0,1"
> format IEC958_SUBFRAME_LE
> }
> }
>
> DT sound card configs for testing
> =================================
>
> &spdifout {
>     pinctrl-0 = <&spdif_ao_out_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
>
> &spdifin {
>     pinctrl-0 = <&spdif_in_h_pins>;
>     pinctrl-names = "default";
>     status = "okay";
> };
>
> ...
>     spdif_dit: audio-codec-1 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dit";
> 	status = "okay";
> 	sound-name-prefix = "DIT";
>     };
>
>     spdif_dir: audio-codec-2 {
> 	#sound-dai-cells = <0>;
> 	compatible = "linux,spdif-dir";
> 	status = "okay";
> 	sound-name-prefix = "DIR";
>     };
> ...
> 	audio-routing = ...
> 		"TODDR_B IN 3", "SPDIFIN Capture",
> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
>
> ...
> 	dai-link-10 {
> 	    sound-dai = <&spdifout>;
>
> 	    codec-0 {
> 		sound-dai = <&spdif_dit>;
> 	    };
> 	};
>
> 	/* spdif or toslink interface */
> 	dai-link-11 {
> 	    sound-dai = <&spdifin>;
>
> 	    codec-0 {
> 		sound-dai = <&spdif_dir>;
> 	    };
> 	};
> ...
>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> index 3d8b1f4f2001..1e0adf259d61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>  			status = "disabled";
>  		};
>  
> +		spdifin: audio-controller at 400 {
> +			compatible = "amlogic,g12a-spdifin",
> +			"amlogic,axg-spdifin";
> +			reg = <0x0 0x400 0x0 0x30>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFIN";
> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
> +			clock-names = "pclk", "refclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
> +			status = "disabled";
> +		};
> +
> +		spdifout: audio-controller at 480 {

Node should still be named spdifout_a, even if the spdifout_b is not added yet

> +			compatible = "amlogic,g12a-spdifout",
> +			"amlogic,axg-spdifout";
> +			reg = <0x0 0x480 0x0 0x50>;
> +			#sound-dai-cells = <0>;
> +			sound-name-prefix = "SPDIFOUT";

Same here

> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
> +			clock-names = "pclk", "mclk";
> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
> +			status = "disabled";
> +		};
> +
>  		tdmout_a: audio-controller at 500 {
>  			compatible = "amlogic,sm1-tdmout";
>  			reg = <0x0 0x500 0x0 0x40>;



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:13 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:13 +0100
Subject: [PATCH 0/3] meson-g12: add pwm and uart pin muxing options
Message-ID: <20220103154616.308376-1-gary.bisson@boundarydevices.com>

Hi,

This series adds a few pin muxing options needed for our HW platform (to
be submitted soon).

1- pwm_f: adding missing both GPIOZ_12 & GPIOA_11 options
  -> tested GPIOA_11 as mipi display backlight
  -> order for this patch is not alphabetical but follows doc order (to
match current order)
2- uart_ao_b: adding both options for ao_b uart + its rts/cts pins
  -> tested on custom hw too

Let me know if you have any questions.

Regards,
Gary

Gary Bisson (3):
  pinctrl: meson-g12a: add more pwm_f options
  arm64: dts: meson-g12-common: add more pwm_f options
  arm64: dts: meson-g12-common: add uart_ao_b pins muxing

 .../boot/dts/amlogic/meson-g12-common.dtsi    | 43 +++++++++++++++++++
 drivers/pinctrl/meson/pinctrl-meson-g12a.c    |  6 ++-
 2 files changed, 48 insertions(+), 1 deletion(-)

-- 
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:14 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:14 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-2-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: linux-gpio at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index cd9656b13836..d182a575981e 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
 static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
 
 /* pwm_f */
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
+static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
 static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
 static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
 
@@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout2_z,		4),
 	GROUP(tdm_c_dout3_z,		4),
 	GROUP(mclk1_z,			4),
+	GROUP(pwm_f_z,			5),
 
 	/* bank GPIOX */
 	GROUP(sdio_d0,			1),
@@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout3_a,		2),
 	GROUP(mclk0_a,			1),
 	GROUP(mclk1_a,			2),
+	GROUP(pwm_f_a,			3),
 };
 
 /* uart_ao_a */
@@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
 };
 
 static const char * const pwm_f_groups[] = {
-	"pwm_f_x", "pwm_f_h",
+	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
 };
 
 static const char * const cec_ao_a_h_groups[] = {
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:15 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:15 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-3-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 00c6f53290d4..af1357c48bee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -894,6 +894,22 @@ mux {
 						};
 					};
 
+					pwm_f_z_pins: pwm-f-z {
+						mux {
+							groups = "pwm_f_z";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
+					pwm_f_a_pins: pwm-f-a {
+						mux {
+							groups = "pwm_f_a";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
 					pwm_f_x_pins: pwm-f-x {
 						mux {
 							groups = "pwm_f_x";
-- 
2.34.1



From gary.bisson at boundarydevices.com  Mon Jan  3 07:46:16 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Mon,  3 Jan 2022 16:46:16 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins muxing
In-Reply-To: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
Message-ID: <20220103154616.308376-4-gary.bisson@boundarydevices.com>

- RX/TX signals can be mapped on 2 different pairs of pins so supporting
  both options
- RTS/CTS signals however only have 1 option available

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index af1357c48bee..3a7773ffbd08 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1952,6 +1952,33 @@ mux {
 						};
 					};
 
+					uart_ao_b_1_pins: uart-ao-b-1 {
+						mux {
+							groups = "uart_ao_b_tx_2",
+								 "uart_ao_b_rx_3";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_2_pins: uart-ao-b-2 {
+						mux {
+							groups = "uart_ao_b_tx_8",
+								 "uart_ao_b_rx_9";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+						mux {
+							groups = "uart_ao_b_cts",
+								 "uart_ao_b_rts";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
 					pwm_a_e_pins: pwm-a-e {
 						mux {
 							groups = "pwm_a_e";
-- 
2.34.1



From miquel.raynal at bootlin.com  Mon Jan  3 08:17:21 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Mon, 3 Jan 2022 17:17:21 +0100
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <20211231102623.izaqlzjvracbbgmp@ti.com>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com>
 <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com>
Message-ID: <20220103171721.46c8e697@xps13>

Hello,

p.yadav at ti.com wrote on Fri, 31 Dec 2021 15:56:25 +0530:

> Hi Patrick,
> 
> On 30/12/21 09:29AM, Patrick Williams wrote:
> > On Wed, Dec 29, 2021 at 11:04:13PM +0530, Pratyush Yadav wrote:  
> > > Hi,
> > > 
> > > On 29/12/21 08:33AM, Patrick Williams wrote:  
> >    
> > > The patch itself looks fine to me but we no longer want to maintain 
> > > drivers under drivers/mtd/spi-nor/controllers/. They should be moved to 
> > > implement the SPI MEM API (under drivers/spi/).  
> > 
> > Is the linux-aspeed community aware of this?  Are you saying you don't want to
> > take fixes for their driver into the MTD tree?  Can it be pulled into the Aspeed
> > tree?  
> 
> I am fine with taking in bug fixes but no longer want to take in any new 
> features. My main intention was to nudge you to convert it to SPI MEM 
> regardless of whether this is a bug fix or a new feature, because 
> eventually we want to get rid of drivers/mtd/spi-nor/controllers/ and 
> the API that comes along with it.

I totally agree with Pratyush here, we no longer want to support the
spi-nor controller API so if, as you say, there are boards failing
in the field, it means there are still users and these users must be
warned that at some point we might discontinue the support of these
drivers if it becomes too painful.

> As for your patch, I certainly don't want it to go via the aspeed tree.

Definitely, no.

> It should go via the MTD tree or not at all. I am not quite sure if this 
> counts as a bug fix or a new feature though.
> 
> >   
> > > Could you please volunteer to do the conversion for this driver?  
> > 
> > I'm not personally going to be able to get to it for at least the next 3 months.
> > 
> > It looks like we don't have a dedicated maintainer for this driver other than
> > Joel by nature of him being listed as the maintainer of "ARM/ASPEED MACHINE
> > SUPPORT".  I'm not sure if Aspeed themselves are planning on doing the necessary
> > refactoring here.
> > 
> > 
> > Joel, are you aware of this driver using a deprecated implementation?  Were
> > there anyone planning to do the reworks that you are aware of?  I'd like to get
> > this fix at least into the OpenBMC kernel tree because I'm seeing this fail in
> > the real world.  
> 

Thanks,
Miqu?l


From gregkh at linuxfoundation.org  Mon Jan  3 08:29:39 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 3 Jan 2022 17:29:39 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
 <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
Message-ID: <YdMkc2YQcYjgR7Qk@kroah.com>

On Mon, Jan 03, 2022 at 04:29:56PM +0100, Neil Armstrong wrote:
> Hi Greg,
> On 03/01/2022 16:19, Greg Kroah-Hartman wrote:
> > A: http://en.wikipedia.org/wiki/Top_post
> > Q: Were do I find info about this thing called top-posting?
> > A: Because it messes up the order in which people normally read text.
> > Q: Why is top-posting such a bad thing?
> > A: Top-posting.
> > Q: What is the most annoying thing in e-mail?
> > 
> > A: No.
> > Q: Should I include quotations after my reply?
> > 
> > http://daringfireball.net/2007/07/on_to>
> > On Mon, Jan 03, 2022 at 03:59:33PM +0100, Neil Armstrong wrote:
> >> Hi Greg,
> >>
> >> Martin just saw this patch was applied, but the serie wasn't reviewed enough and it will break
> >> earlycon support on the ARMv7 Amlogic SoCs fore 5.17.
> > 
> > Ok, what should I revert?
> 
> None, we have a fix in the pipe
> 
> > 
> >> Anyway, I'll push the corresponding DT fixes for 5.17-rc1.
> > 
> > How did we get out of sync here?
> 
> The serie wasn't fully reviewed, and I was out of office when it was applied.
> 
> > 
> >> Would it be possible we also receive the notification when those patches are applied ?
> >> Maybe a MAINTAINERS entry is missing so we can receive them ?
> > 
> > That would be good, so that people can review the patches.  Otherwise I
> > have to just guess :)
> 
> exact, I naively thought it would be matched in the:
> N:      meson
> entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.

Try it, does that work when running get_maintainer.pl on this patch?

> >> It would help me track those TTY and USB patches more easily.
> > 
> > I recommend MAINTAINERS entries for drivers that are not listed and that
> > you care about seeing the changes for.
> 
> This is why we have a regex to match these.

Great, the submitter should have used that.

> I can submit a patch to have a proper entry if the regex is not enough/appropriate.

Whatever makes the tools work is fine with me.

> BTW can you point us how are selected the recipients of the notification messages you send ?

For when I apply a patch, everyone on the ack/signed-off-by/reviewed-by
list gets a response.  I do not hit mailing lists with the notification
as that's just too much noise.

Been doing it this way for well over a decade now, nothing new here :)

thanks,

greg k-h


From narmstrong at baylibre.com  Mon Jan  3 08:35:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:35:01 +0100
Subject: [PATCH V3 1/6] tty: serial: meson: Drop the legacy compatible
 strings and clock code
In-Reply-To: <YdMkc2YQcYjgR7Qk@kroah.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-2-yu.tu@amlogic.com>
 <CAFBinCCwjS36ss_4sU+o9m8gEprFsVZbqcxgpQxczTNohZqFdA@mail.gmail.com>
 <a296e666-368b-4cd5-427e-30fc66a15b49@amlogic.com>
 <CAFBinCA2V=sx95Q=+4nLDXFK1Os11XVWtK8KauxixVwYXLUz1Q@mail.gmail.com>
 <3865f01c-83f7-a69d-6835-c26f662629b7@baylibre.com>
 <YdMUEzStFf99EeQ5@kroah.com>
 <df9e472e-ac17-26ed-d820-e80d5b7b0e80@baylibre.com>
 <YdMkc2YQcYjgR7Qk@kroah.com>
Message-ID: <257d153c-960a-59fc-dfa9-5e160e42b68d@baylibre.com>

On 03/01/2022 17:29, Greg Kroah-Hartman wrote:
> On Mon, Jan 03, 2022 at 04:29:56PM +0100, Neil Armstrong wrote:
>>>> Would it be possible we also receive the notification when those patches are applied ?
>>>> Maybe a MAINTAINERS entry is missing so we can receive them ?
>>>
>>> That would be good, so that people can review the patches.  Otherwise I
>>> have to just guess :)
>>
>> exact, I naively thought it would be matched in the:
>> N:      meson
>> entry but it seems an proper entry for drivers/tty/serial/meson_uart.c is needed.
> 
> Try it, does that work when running get_maintainer.pl on this patch?

Yes it does work, so no problem here

> 
>>>> It would help me track those TTY and USB patches more easily.
>>>
>>> I recommend MAINTAINERS entries for drivers that are not listed and that
>>> you care about seeing the changes for.
>>
>> This is why we have a regex to match these.
> 
> Great, the submitter should have used that.
> 
>> I can submit a patch to have a proper entry if the regex is not enough/appropriate.
> 
> Whatever makes the tools work is fine with me.
> 
>> BTW can you point us how are selected the recipients of the notification messages you send ?
> 
> For when I apply a patch, everyone on the ack/signed-off-by/reviewed-by
> list gets a response.  I do not hit mailing lists with the notification
> as that's just too much noise.
> 
> Been doing it this way for well over a decade now, nothing new here :)

Ok right, no problem, other maintainers (e.g: net, sound) and default b4 behavior is to
send notification to same recipient as original patch.

It it fits everyone for a decade, no need to change ! We have very low patches for tty & usb anyway

Neil

> 
> thanks,
> 
> greg k-h
> 



From christianshewitt at gmail.com  Mon Jan  3 08:39:47 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:47 +0000
Subject: [PATCH v2 0/9] arm64: dts: meson: add support for aac2xx devices
Message-ID: <20220103163956.6581-1-christianshewitt@gmail.com>

This series adds support for several popular Amlogic S905X3 (SM1) Android
Set-Top Box devices. Like most Android box devices, they ship in variants
with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
something we need to consider to get a working boot, but we do need to get
the correct connectivity spec. Broadly speaking we see boxes with Higher
and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
some low-end boxes BT is omitted.

As initial distro setup is frequently performed over SSH or an HDMI GUI
app it is important for users to pick a device-tree with the correct
Ethernet PHY spec else connectivity is impossible. To aid this we append
a -gbit suffix to X96-AIR and A95XF3-AIR models using an external Gigabit
PHY, while 10/00 models with internal PHY have no suffix.

NB: At the current time the Realtek 8822CS and MT7668 WiFi/BT modules we
have seen on 'AIR' devices are not supported in the kernel so these are
deliberately omitted. The H96-Max uses a conventional Broadcom module
so has more complete support. For now the boxes have simple HDMI audio
support; wiring up the Headphone socket will be done at a later date.

Changes since RFC(v1) series:
- Add Robs binding acks on patches 4/7/8 (patches 2/5 still need acks)
- Rename and rework patches around -gbit (as requested by Neil)
- Correct 'manufacturer' typo on patch 8
- Rebase against v5.18/dt64 branch

Christian Hewitt (9):
  arm64: dts: meson: add common SM1 ac2xx dtsi
  dt-bindings: arm: amlogic: add X96-AIR bindings
  arm64: dts: meson: add initial device-trees for X96-AIR
  dt-bindings: vendor-prefixes: add cyx prefix
  dt-bindings: arm: amlogic: add A95XF3-AIR bindings
  arm64: dts: meson: add initial device-trees for A95XF3-AIR
  dt-bindings: vendor-prefixes: add haochuangyi prefix
  dt-bindings: arm: amlogic: add H96-Max bindings
  arm64: dts: meson: add initial device-tree for H96-Max

 .../devicetree/bindings/arm/amlogic.yaml      |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm64/boot/dts/amlogic/Makefile          |   5 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 +++++++++
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++
 9 files changed, 941 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:48 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:48 +0000
Subject: [PATCH v2 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-2-christianshewitt@gmail.com>

Add a common dtsi for Android STB devices based on the Amlogic S905X3
(AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
loosely based on the existing SEI610 device-tree.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 1 file changed, 300 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
new file mode 100644
index 000000000000..46a34731f7e2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ *
+ * AC200/AC202 = S905D3
+ * AC213/AC214 = S905X3
+ *
+ */
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	ao_5v: regulator-ao_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "AO_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	dc_in: regulator-dc_in {
+		compatible = "regulator-fixed";
+		regulator-name = "DC_IN";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	emmc_1v8: regulator-emmc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "EMMC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <690000>;
+		regulator-max-microvolt = <1050000>;
+
+		vin-supply = <&dc_in>;
+
+		pwms = <&pwm_AO_cd 1 1500 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vddio_ao1v8: regulator-vddio_ao1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU1_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU2_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU3_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_ao_a_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr104;
+	max-frequency = <200000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_ao1v8>;
+};
+
+/* SD Card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	/* CRC errors are observed at 50MHz */
+	max-frequency = <35000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "otg";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:49 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:49 +0000
Subject: [PATCH v2 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-3-christianshewitt@gmail.com>

Add board bindings for the Amediatech X96-AIR STB which ships with
model variants distiguished by Ethernet configuration: models using
an external Gigabit PHY have a -gbit suffix, while models using an
internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 31df120d73b0..b5b995941d3b 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -170,6 +170,8 @@ properties:
       - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
         items:
           - enum:
+              - amediatech,x96-air
+              - amediatech,x96-air-gbit
               - bananapi,bpi-m5
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:50 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:50 +0000
Subject: [PATCH v2 3/9] arm64: dts: meson: add initial device-trees for X96-AIR
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-4-christianshewitt@gmail.com>

The Amediatek X96-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 2x USB 2.0 inc. OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..1c0e554f54fc 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
new file mode 100644
index 000000000000..7e1a74046ba5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-x96max";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
new file mode 100644
index 000000000000..cd93d798f2a3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-beelink-gs1";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:51 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:51 +0000
Subject: [PATCH v2 4/9] dt-bindings: vendor-prefixes: add cyx prefix
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-5-christianshewitt@gmail.com>

Shenzhen CYX Industrial Co., Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index eb8ab0d82198..c9202a101d71 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -281,6 +281,8 @@ patternProperties:
     description: CUI Devices
   "^cypress,.*":
     description: Cypress Semiconductor Corporation
+  "^cyx,.*":
+    description: Shenzhen CYX Industrial Co., Ltd
   "^cznic,.*":
     description: CZ.NIC, z.s.p.o.
   "^dallas,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:52 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:52 +0000
Subject: [PATCH v2 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-6-christianshewitt@gmail.com>

Add board bindings for the CYX A95XF3-AIR set-top box which ships
with model variants distiguished by Ethernet configuration: models
using external Gigabit PHY have a -gbit suffix, while models using
an internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index b5b995941d3b..2027ce81a834 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -173,6 +173,8 @@ properties:
               - amediatech,x96-air
               - amediatech,x96-air-gbit
               - bananapi,bpi-m5
+              - cyx,a95xf3-air
+              - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
               - khadas,vim3l
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:53 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:53 +0000
Subject: [PATCH v2 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-7-christianshewitt@gmail.com>

The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD
- Multicolour case LED 'arc'

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 1c0e554f54fc..e87adc6593df 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
new file mode 100644
index 000000000000..d1debccdc1c2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air-gbit", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
new file mode 100644
index 000000000000..c94f2870b78b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:54 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:54 +0000
Subject: [PATCH v2 7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-8-christianshewitt@gmail.com>

Shenzhen Haochuangyi Technology Co.,Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index c9202a101d71..f4160ee3b5df 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -485,6 +485,8 @@ patternProperties:
     deprecated: true
   "^hannstar,.*":
     description: HannStar Display Corporation
+  "^haochuangyi,.*":
+    description: Shenzhen Haochuangyi Technology Co.,Ltd
   "^haoyu,.*":
     description: Haoyu Microelectronic Co. Ltd.
   "^hardkernel,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:55 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:55 +0000
Subject: [PATCH v2 8/9] dt-bindings: arm: amlogic: add H96-Max bindings
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-9-christianshewitt@gmail.com>

Add the board binding for the Haochuangyi H96-Max STB device.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 2027ce81a834..a073a959232c 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -177,6 +177,7 @@ properties:
               - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
+              - haochuangyi,h96-max
               - khadas,vim3l
               - seirobotics,sei610
           - const: amlogic,sm1
-- 
2.17.1



From christianshewitt at gmail.com  Mon Jan  3 08:39:56 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Mon,  3 Jan 2022 16:39:56 +0000
Subject: [PATCH v2 9/9] arm64: dts: meson: add initial device-tree for H96-Max
In-Reply-To: <20220103163956.6581-1-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
Message-ID: <20220103163956.6581-10-christianshewitt@gmail.com>

The Haochuangyi H96-Max is based on the Amlogic S905X3 reference
design with the following specs:

- 4GB DDR4 RAM
- 32/64/128GB eMMC
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 10/100/1000 Base-T Ethernet
- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1)
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

Tested-by: Benoit Masson <yahoo at perenite.com>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 ++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index e87adc6593df..868d74044072 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
new file mode 100644
index 000000000000..0f6660e68e72
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "haochuangyi,h96-max", "amlogic,sm1";
+	model = "Shenzhen Haochuangyi Technology Co., Ltd H96 Max";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "H96-MAX";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
-- 
2.17.1



From narmstrong at baylibre.com  Mon Jan  3 08:49:05 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:49:05 +0100
Subject: [PATCH v2 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220103163956.6581-2-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-2-christianshewitt@gmail.com>
Message-ID: <ca79ab12-eb16-ac6d-a950-de59c6253eba@baylibre.com>

On 03/01/2022 17:39, Christian Hewitt wrote:
> Add a common dtsi for Android STB devices based on the Amlogic S905X3
> (AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
> loosely based on the existing SEI610 device-tree.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
>  1 file changed, 300 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> new file mode 100644
> index 000000000000..46a34731f7e2
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
> @@ -0,0 +1,300 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + *
> + * AC200/AC202 = S905D3
> + * AC213/AC214 = S905X3
> + *
> + */
> +
> +#include "meson-sm1.dtsi"
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/gpio/meson-g12a-gpio.h>
> +#include <dt-bindings/input/input.h>
> +
> +/ {
> +	aliases {
> +		serial0 = &uart_AO;
> +		ethernet0 = &ethmac;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	emmc_pwrseq: emmc-pwrseq {
> +		compatible = "mmc-pwrseq-emmc";
> +		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
> +	};
> +
> +	cvbs-connector {
> +		compatible = "composite-video-connector";
> +
> +		port {
> +			cvbs_connector_in: endpoint {
> +				remote-endpoint = <&cvbs_vdac_out>;
> +			};
> +		};
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_connector_in: endpoint {
> +				remote-endpoint = <&hdmi_tx_tmds_out>;
> +			};
> +		};
> +	};
> +
> +	memory at 0 {
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x40000000>;
> +	};
> +
> +	ao_5v: regulator-ao_5v {
> +		compatible = "regulator-fixed";
> +		regulator-name = "AO_5V";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		vin-supply = <&dc_in>;
> +		regulator-always-on;
> +	};
> +
> +	dc_in: regulator-dc_in {
> +		compatible = "regulator-fixed";
> +		regulator-name = "DC_IN";
> +		regulator-min-microvolt = <5000000>;
> +		regulator-max-microvolt = <5000000>;
> +		regulator-always-on;
> +	};
> +
> +	emmc_1v8: regulator-emmc_1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "EMMC_1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	vddao_3v3: regulator-vddao_3v3 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDAO_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&dc_in>;
> +		regulator-always-on;
> +	};
> +
> +	vddcpu: regulator-vddcpu {
> +		compatible = "pwm-regulator";
> +
> +		regulator-name = "VDDCPU";
> +		regulator-min-microvolt = <690000>;
> +		regulator-max-microvolt = <1050000>;
> +
> +		vin-supply = <&dc_in>;
> +
> +		pwms = <&pwm_AO_cd 1 1500 0>;
> +		pwm-dutycycle-range = <100 0>;
> +
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +
> +	vddio_ao1v8: regulator-vddio_ao1v8 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "VDDIO_AO1V8";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +		vin-supply = <&vddao_3v3>;
> +		regulator-always-on;
> +	};
> +
> +	sdio_pwrseq: sdio-pwrseq {
> +		compatible = "mmc-pwrseq-simple";
> +		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> +		clocks = <&wifi32k>;
> +		clock-names = "ext_clock";
> +	};
> +
> +	wifi32k: wifi32k {
> +		compatible = "pwm-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
> +	};
> +};
> +
> +&cec_AO {
> +	pinctrl-0 = <&cec_ao_a_h_pins>;
> +	pinctrl-names = "default";
> +	status = "disabled";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&cecb_AO {
> +	pinctrl-0 = <&cec_ao_b_h_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +	hdmi-phandle = <&hdmi_tx>;
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu1 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU1_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu2 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU2_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cpu3 {
> +	cpu-supply = <&vddcpu>;
> +	operating-points-v2 = <&cpu_opp_table>;
> +	clocks = <&clkc CLKID_CPU3_CLK>;
> +	clock-latency = <50000>;
> +};
> +
> +&cvbs_vdac_port {
> +	cvbs_vdac_out: endpoint {
> +		remote-endpoint = <&cvbs_connector_in>;
> +	};
> +};
> +
> +&hdmi_tx {
> +	status = "okay";
> +	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&hdmi_tx_tmds_port {
> +	hdmi_tx_tmds_out: endpoint {
> +		remote-endpoint = <&hdmi_connector_in>;
> +	};
> +};
> +
> +&ir {
> +	status = "okay";
> +	pinctrl-0 = <&remote_input_ao_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&pwm_AO_ab {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_ao_a_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin0";
> +};
> +
> +&pwm_AO_cd {
> +	pinctrl-0 = <&pwm_ao_d_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin1";
> +	status = "okay";
> +};
> +
> +&pwm_ef {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&xtal>;
> +	clock-names = "clkin0";
> +};
> +
> +&saradc {
> +	status = "okay";
> +	vref-supply = <&vddio_ao1v8>;
> +};
> +
> +/* SDIO */
> +&sd_emmc_a {
> +	status = "okay";
> +	pinctrl-0 = <&sdio_pins>;
> +	pinctrl-1 = <&sdio_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	sd-uhs-sdr104;
> +	max-frequency = <200000000>;
> +
> +	non-removable;
> +	disable-wp;
> +
> +	/* WiFi firmware requires power to be kept while in suspend */
> +	keep-power-in-suspend;
> +
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddio_ao1v8>;
> +};
> +
> +/* SD Card */
> +&sd_emmc_b {
> +	status = "okay";
> +	pinctrl-0 = <&sdcard_c_pins>;
> +	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	/* CRC errors are observed at 50MHz */
> +	max-frequency = <35000000>;
> +	disable-wp;
> +
> +	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&vddao_3v3>;
> +};
> +
> +/* eMMC */
> +&sd_emmc_c {
> +	status = "okay";
> +	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
> +	pinctrl-1 = <&emmc_clk_gate_pins>;
> +	pinctrl-names = "default", "clk-gate";
> +
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-ddr-1_8v;
> +	mmc-hs200-1_8v;
> +	max-frequency = <200000000>;
> +	non-removable;
> +	disable-wp;
> +
> +	mmc-pwrseq = <&emmc_pwrseq>;
> +	vmmc-supply = <&vddao_3v3>;
> +	vqmmc-supply = <&emmc_1v8>;
> +};
> +
> +&uart_AO {
> +	status = "okay";
> +	pinctrl-0 = <&uart_ao_a_pins>;
> +	pinctrl-names = "default";
> +};
> +
> +&usb {
> +	status = "okay";
> +	dr_mode = "otg";
> +};
> 


Missing:
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit/s PHY


From narmstrong at baylibre.com  Mon Jan  3 08:49:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 3 Jan 2022 17:49:34 +0100
Subject: [PATCH v2 3/9] arm64: dts: meson: add initial device-trees for
 X96-AIR
In-Reply-To: <20220103163956.6581-4-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-4-christianshewitt@gmail.com>
Message-ID: <3a1c359b-7884-7072-4e08-55687b9f94cf@baylibre.com>

On 03/01/2022 17:39, Christian Hewitt wrote:
> The Amediatek X96-AIR is based on Amlogic S905X3 reference board
> designs and ships in multiple configurations:
> 
> ? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
> ? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
> ...
> - HDMI 2.1 video
> - S/PDIF optical output
> - AV output
> - 2x USB 2.0 inc. OTG port
> - 1x USB 3.0 port
> - IR receiver
> - 1x micro SD card slot (internal)
> - 1x Reset/Update button (in AV jack)
> - 7-segment VFD
> 
> The device-tree with -gbit suffix supports models with Gigabit
> Ethernet, and the device-tree with no suffix supports models
> with 10/100 Ethernet.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |   2 +
>  .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
>  .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
>  3 files changed, 247 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> 
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index 5148cd9e5146..1c0e554f54fc 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
> new file mode 100644
> index 000000000000..7e1a74046ba5
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
> @@ -0,0 +1,133 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
> +	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "X96-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +
> +	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
> +	pinctrl-names = "default";
> +	phy-mode = "rgmii-txid";
> +	phy-handle = <&external_phy>;
> +
> +	rx-internal-delay-ps = <800>;
> +};
> +
> +&ext_mdio {
> +	external_phy: ethernet-phy at 0 {
> +		/* Realtek RTL8211F (0x001cc916) */
> +		reg = <0>;
> +		max-speed = <1000>;
> +
> +		reset-assert-us = <10000>;
> +		reset-deassert-us = <80000>;
> +		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
> +
> +		interrupt-parent = <&gpio_intc>;
> +		/* MAC_INTR on GPIOZ_14 */
> +		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&ir {
> +	linux,rc-map-name = "rc-x96max";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> new file mode 100644
> index 000000000000..cd93d798f2a3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 BayLibre SAS. All rights reserved.
> + * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-sm1-ac2xx.dtsi"
> +#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
> +
> +/ {
> +	compatible = "amediatech,x96-air", "amlogic,sm1";
> +	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
> +
> +	sound {
> +		compatible = "amlogic,axg-sound-card";
> +		model = "X96-AIR";
> +		audio-aux-devs = <&tdmout_b>;
> +		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
> +				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
> +				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> +				"TDM_B Playback", "TDMOUT_B OUT";
> +
> +		assigned-clocks = <&clkc CLKID_MPLL2>,
> +				  <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&frddr_a>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&frddr_b>;
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&frddr_c>;
> +		};
> +
> +		/* 8ch hdmi interface */
> +		dai-link-3 {
> +			sound-dai = <&tdmif_b>;
> +			dai-format = "i2s";
> +			dai-tdm-slot-tx-mask-0 = <1 1>;
> +			dai-tdm-slot-tx-mask-1 = <1 1>;
> +			dai-tdm-slot-tx-mask-2 = <1 1>;
> +			dai-tdm-slot-tx-mask-3 = <1 1>;
> +			mclk-fs = <256>;
> +
> +			codec {
> +				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
> +			};
> +		};
> +
> +		/* hdmi glue */
> +		dai-link-4 {
> +			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
> +
> +			codec {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&arb {
> +	status = "okay";
> +};
> +
> +&clkc_audio {
> +	status = "okay";
> +};
> +
> +&ethmac {
> +	status = "okay";
> +	phy-handle = <&internal_ephy>;
> +	phy-mode = "rmii";
> +};
> +
> +&frddr_a {
> +	status = "okay";
> +};
> +
> +&frddr_b {
> +	status = "okay";
> +};
> +
> +&frddr_c {
> +	status = "okay";
> +};
> +
> +&ir {
> +	linux,rc-map-name = "rc-beelink-gs1";
> +};
> +
> +&tdmif_b {
> +	status = "okay";
> +};
> +
> +&tdmout_b {
> +	status = "okay";
> +};
> +
> +&tohdmitx {
> +	status = "okay";
> +};
> 

Missing:
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit/s PHY
Tested-by: Piotr Oniszczuk <piotr.oniszczuk at gmail.com> # X96-Air with 10/100 Eth


From madvenka at linux.microsoft.com  Mon Jan  3 08:52:03 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:03 -0600
Subject: [PATCH v12 01/10] arm64: Remove NULL task check from unwind_frame()
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-2-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Currently, there is a check for a NULL task in unwind_frame(). It is not
needed since all current consumers pass a non-NULL task.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 0fb58fed54cb..5f5bb35b7b41 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -69,9 +69,6 @@ static int notrace unwind_frame(struct task_struct *tsk,
 	unsigned long fp = frame->fp;
 	struct stack_info info;
 
-	if (!tsk)
-		tsk = current;
-
 	/* Final frame; nothing to unwind */
 	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
 		return -ENOENT;
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:04 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:04 -0600
Subject: [PATCH v12 02/10] arm64: Rename unwinder functions
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-3-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Rename unwinder functions for consistency and better naming.

	- Rename start_backtrace() to unwind_init().
	- Rename unwind_frame() to unwind_next().
	- Rename walk_stackframe() to unwind().

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/arm64/kernel/stacktrace.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 5f5bb35b7b41..b980d96dccfc 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,8 @@
  */
 
 
-static void start_backtrace(struct stackframe *frame, unsigned long fp,
-			    unsigned long pc)
+static void unwind_init(struct stackframe *frame, unsigned long fp,
+			unsigned long pc)
 {
 	frame->fp = fp;
 	frame->pc = pc;
@@ -45,7 +45,7 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
 	/*
 	 * Prime the first unwind.
 	 *
-	 * In unwind_frame() we'll check that the FP points to a valid stack,
+	 * In unwind_next() we'll check that the FP points to a valid stack,
 	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
 	 * treated as a transition to whichever stack that happens to be. The
 	 * prev_fp value won't be used, but we set it to 0 such that it is
@@ -63,8 +63,8 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_frame(struct task_struct *tsk,
-				struct stackframe *frame)
+static int notrace unwind_next(struct task_struct *tsk,
+			       struct stackframe *frame)
 {
 	unsigned long fp = frame->fp;
 	struct stack_info info;
@@ -104,7 +104,7 @@ static int notrace unwind_frame(struct task_struct *tsk,
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
-	 * prev_type are only meaningful to the next unwind_frame() invocation.
+	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
@@ -137,23 +137,23 @@ static int notrace unwind_frame(struct task_struct *tsk,
 
 	return 0;
 }
-NOKPROBE_SYMBOL(unwind_frame);
+NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace walk_stackframe(struct task_struct *tsk,
-				    struct stackframe *frame,
-				    bool (*fn)(void *, unsigned long), void *data)
+static void notrace unwind(struct task_struct *tsk,
+			   struct stackframe *frame,
+			   bool (*fn)(void *, unsigned long), void *data)
 {
 	while (1) {
 		int ret;
 
 		if (!fn(data, frame->pc))
 			break;
-		ret = unwind_frame(tsk, frame);
+		ret = unwind_next(tsk, frame);
 		if (ret < 0)
 			break;
 	}
 }
-NOKPROBE_SYMBOL(walk_stackframe);
+NOKPROBE_SYMBOL(unwind);
 
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
@@ -195,14 +195,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 	struct stackframe frame;
 
 	if (regs)
-		start_backtrace(&frame, regs->regs[29], regs->pc);
+		unwind_init(&frame, regs->regs[29], regs->pc);
 	else if (task == current)
-		start_backtrace(&frame,
+		unwind_init(&frame,
 				(unsigned long)__builtin_frame_address(1),
 				(unsigned long)__builtin_return_address(0));
 	else
-		start_backtrace(&frame, thread_saved_fp(task),
+		unwind_init(&frame, thread_saved_fp(task),
 				thread_saved_pc(task));
 
-	walk_stackframe(task, &frame, consume_entry, cookie);
+	unwind(task, &frame, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:05 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:05 -0600
Subject: [PATCH v12 03/10] arm64: Rename stackframe to unwind_state
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-4-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Rename "struct stackframe" to "struct unwind_state" for consistency and
better naming. Accordingly, rename variable/argument "frame" to "state".

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  2 +-
 arch/arm64/kernel/stacktrace.c      | 66 ++++++++++++++---------------
 2 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 3a15d376ab36..fc828c3c5dfd 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -52,7 +52,7 @@ struct stack_info {
  *               associated with the most recently encountered replacement lr
  *               value.
  */
-struct stackframe {
+struct unwind_state {
 	unsigned long fp;
 	unsigned long pc;
 	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b980d96dccfc..a1a7ff93b84f 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,13 +33,13 @@
  */
 
 
-static void unwind_init(struct stackframe *frame, unsigned long fp,
+static void unwind_init(struct unwind_state *state, unsigned long fp,
 			unsigned long pc)
 {
-	frame->fp = fp;
-	frame->pc = pc;
+	state->fp = fp;
+	state->pc = pc;
 #ifdef CONFIG_KRETPROBES
-	frame->kr_cur = NULL;
+	state->kr_cur = NULL;
 #endif
 
 	/*
@@ -51,9 +51,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
 	 * prev_fp value won't be used, but we set it to 0 such that it is
 	 * definitely not an accessible stack address.
 	 */
-	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
-	frame->prev_fp = 0;
-	frame->prev_type = STACK_TYPE_UNKNOWN;
+	bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
+	state->prev_fp = 0;
+	state->prev_type = STACK_TYPE_UNKNOWN;
 }
 
 /*
@@ -64,9 +64,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
  * and the location (but not the fp value) of B.
  */
 static int notrace unwind_next(struct task_struct *tsk,
-			       struct stackframe *frame)
+			       struct unwind_state *state)
 {
-	unsigned long fp = frame->fp;
+	unsigned long fp = state->fp;
 	struct stack_info info;
 
 	/* Final frame; nothing to unwind */
@@ -79,7 +79,7 @@ static int notrace unwind_next(struct task_struct *tsk,
 	if (!on_accessible_stack(tsk, fp, 16, &info))
 		return -EINVAL;
 
-	if (test_bit(info.type, frame->stacks_done))
+	if (test_bit(info.type, state->stacks_done))
 		return -EINVAL;
 
 	/*
@@ -95,27 +95,27 @@ static int notrace unwind_next(struct task_struct *tsk,
 	 * stack to another, it's never valid to unwind back to that first
 	 * stack.
 	 */
-	if (info.type == frame->prev_type) {
-		if (fp <= frame->prev_fp)
+	if (info.type == state->prev_type) {
+		if (fp <= state->prev_fp)
 			return -EINVAL;
 	} else {
-		set_bit(frame->prev_type, frame->stacks_done);
+		set_bit(state->prev_type, state->stacks_done);
 	}
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
 	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
-	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
-	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
-	frame->prev_fp = fp;
-	frame->prev_type = info.type;
+	state->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
+	state->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
+	state->prev_fp = fp;
+	state->prev_type = info.type;
 
-	frame->pc = ptrauth_strip_insn_pac(frame->pc);
+	state->pc = ptrauth_strip_insn_pac(state->pc);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	if (tsk->ret_stack &&
-		(frame->pc == (unsigned long)return_to_handler)) {
+		(state->pc == (unsigned long)return_to_handler)) {
 		unsigned long orig_pc;
 		/*
 		 * This is a case where function graph tracer has
@@ -123,16 +123,16 @@ static int notrace unwind_next(struct task_struct *tsk,
 		 * to hook a function return.
 		 * So replace it to an original value.
 		 */
-		orig_pc = ftrace_graph_ret_addr(tsk, NULL, frame->pc,
-						(void *)frame->fp);
-		if (WARN_ON_ONCE(frame->pc == orig_pc))
+		orig_pc = ftrace_graph_ret_addr(tsk, NULL, state->pc,
+						(void *)state->fp);
+		if (WARN_ON_ONCE(state->pc == orig_pc))
 			return -EINVAL;
-		frame->pc = orig_pc;
+		state->pc = orig_pc;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #ifdef CONFIG_KRETPROBES
-	if (is_kretprobe_trampoline(frame->pc))
-		frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur);
+	if (is_kretprobe_trampoline(state->pc))
+		state->pc = kretprobe_find_ret_addr(tsk, (void *)state->fp, &state->kr_cur);
 #endif
 
 	return 0;
@@ -140,15 +140,15 @@ static int notrace unwind_next(struct task_struct *tsk,
 NOKPROBE_SYMBOL(unwind_next);
 
 static void notrace unwind(struct task_struct *tsk,
-			   struct stackframe *frame,
+			   struct unwind_state *state,
 			   bool (*fn)(void *, unsigned long), void *data)
 {
 	while (1) {
 		int ret;
 
-		if (!fn(data, frame->pc))
+		if (!fn(data, state->pc))
 			break;
-		ret = unwind_next(tsk, frame);
+		ret = unwind_next(tsk, state);
 		if (ret < 0)
 			break;
 	}
@@ -192,17 +192,17 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	struct stackframe frame;
+	struct unwind_state state;
 
 	if (regs)
-		unwind_init(&frame, regs->regs[29], regs->pc);
+		unwind_init(&state, regs->regs[29], regs->pc);
 	else if (task == current)
-		unwind_init(&frame,
+		unwind_init(&state,
 				(unsigned long)__builtin_frame_address(1),
 				(unsigned long)__builtin_return_address(0));
 	else
-		unwind_init(&frame, thread_saved_fp(task),
+		unwind_init(&state, thread_saved_fp(task),
 				thread_saved_pc(task));
 
-	unwind(task, &frame, consume_entry, cookie);
+	unwind(task, &state, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:02 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:02 -0600
Subject: [PATCH v12 00/10] arm64: Reorganize the unwinder and implement stack
 trace reliability checks
In-Reply-To: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
Message-ID: <20220103165212.9303-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

I have rebased this patch series on top of Mark Rutland's series on his
fork of Linux.

Remove NULL task check
======================

Currently, there is a check for a NULL task in unwind_frame(). It is not
needed since all current consumers pass a non-NULL task.

Rename unwinder functions
=========================

Rename unwinder functions to unwind*() similar to other architectures
for naming consistency.

	start_backtrace() ==> unwind_init()
	unwind_frame()    ==> unwind_next()
	walk_stackframe() ==> unwind()

Split unwind_init()
===================

Unwind initialization consists of two pieces:

	1. Specialized initialization for 3 different cases - from regs,
	   from current task and from a blocked task. Define separate
	   inline init functions for these:

	   	- unwind_init_regs()
		- unwind_init_current()
		- unwind_init_task()

	   This makes it easier to add more code to each case in the
	   future.

	2. Common initialization for all the cases:

		- unwind_init_common()

Rename struct stackframe
========================

Rename "struct stackframe" to "struct unwind_state" for better naming
and consistency.

Copy arguments to unwind_state
==============================

The arguments of arch_stack_walk() are currently passed separately
to unwind functions. Instead, copy them to struct unwind_state so
that the only argument passed to unwind functions is unwind_state.

Redefine the unwinder loop
==========================

Redefine the unwinder loop and make it simple and somewhat similar to other
architectures. Define the following:

	while (unwind_continue(&state))
		unwind_next(&state);

unwind_continue()
	This new function implements checks to determine whether the
	unwind should continue or terminate.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_check_reliability() that will detect
these cases and set a boolean "reliable" in the stackframe. Call
unwind_check_reliability() for every frame.

Introduce the first reliability check in unwind_check_reliability() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future.

Make unwind() return a boolean to indicate reliability of the stack trace.

SYM_CODE check
==============

This is the second reliability check implemented.

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_check_reliability(), check the return PC against these ranges. If
a match is found, then mark the stack trace unreliable.

Last stack frame
================

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

	- EL0 exception stack traces end in the top level EL0 exception
	  handlers.

	- All kernel thread stack traces end in ret_from_fork().

arch_stack_walk_reliable()
==========================

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except that it returns an error if the stack trace is
found to be unreliable.

Until all of the reliability checks are in place in
unwind_check_reliability(), arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

HAVE_RELIABLE_STACKTRACE
========================

Select this config for arm64. However, make it conditional on
STACK_VALIDATION. When objtool is enhanced to implement stack
validation for arm64, STACK_VALIDATION will be defined.

---
Changelog:
v12:
	From Mark Brown:

	- Reviewed-by for the following:

	[PATCH v11 1/5] arm64: Call stack_backtrace() only from within
	                walk_stackframe()
	[PATCH v11 2/5] arm64: Rename unwinder functions
	[PATCH v11 3/5] arm64: Make the unwind loop in unwind() similar to
	                other architectures
	[PATCH v11 5/5] arm64: Create a list of SYM_CODE functions, check
	                return PC against list

	- Add an extra patch at the end to select HAVE_RELIABLE_STACKTRACE
	  just as a place holder for the review. I have added it and made
	  it conditional on STACK_VALIDATION which has not yet been
	  implemented.

	- Mark had a concern about the code for the check for the final
	  frame being repeated in two places. I have now added a new
	  field called "final_fp" in struct stackframe which I compute
	  once in stacktrace initialization. I have added an explicit
	  comment that the stacktrace must terminate at the final_fp.

	- Place the implementation of arch_stack_walk_reliable() in a
	  separate patch after all the reliability checks have been
	  implemented.

	From Mark Rutland:

	- Place the removal of the NULL task check in unwind_frame() in
	  a separate patch.

	- Add a task field to struct stackframe so the task pointer can be
	  passed around via the frame instead of as a separate argument. I have
	  taken this a step further by copying all of the arguments to
	  arch_stack_walk() into struct stackframe so that only that
	  struct needs to be passed to unwind functions.

	- Rename start_backtrace() to unwind_init() instead of unwind_start().

	- Acked-by for the following:

	[PATCH v11 2/5] arm64: Rename unwinder functions

	- Rename "struct stackframe" to "struct unwind_state".

	- Define separate inline functions for initializing the starting
	  FP and PC from regs, or caller, or blocked task. Don't merge
	  unwind_init() into unwind().

v11:
	From Mark Rutland:

	- Peter Zijlstra has submitted patches that make ARCH_STACKWALK
	  independent of STACKTRACE. Mark Rutland extracted some of the
	  patches from my v10 series and added his own patches and comments,
	  rebased it on top of Peter's changes and submitted the series.
	  
	  So, I have rebased the rest of the patches from v10 on top of
	  Mark Rutland's changes.

	- Split the renaming of the unwinder functions and annotating them
	  with notrace and NOKPROBE_SYMBOL(). Also, there is currently no
	  need to annotate unwind_start() as its caller is already annotated
	  properly. So, I am removing the annotation patch from the series.
	  This can be done separately later if deemed necessary. Similarly,
	  I have removed the annotations from unwind_check_reliability() and
	  unwind_continue().

	From Nobuta Keiya:

	- unwind_start() should check for final frame and not mark the
	  final frame unreliable.

v9, v10:
	- v9 had a threading problem. So, I resent it as v10.

	From me:

	- Removed the word "RFC" from the subject line as I believe this
	  is mature enough to be a regular patch.

	From Mark Brown, Mark Rutland:

	- Split the patches into smaller, self-contained ones.

	- Always enable STACKTRACE so that arch_stack_walk() is always
	  defined.

	From Mark Rutland:

	- Update callchain_trace() take the return value of
	  perf_callchain_store() into acount.

	- Restore get_wchan() behavior to the original code.

	- Simplify an if statement in dump_backtrace().

	From Mark Brown:

	- Do not abort the stack trace on the first unreliable frame.

	
v8:
	- Synced to v5.14-rc5.

	From Mark Rutland:

	- Make the unwinder loop similar to other architectures.

	- Keep details to within the unwinder functions and return a simple
	  boolean to the caller.

	- Convert some of the current code that contains unwinder logic to
	  simply use arch_stack_walk(). I have converted all of them.

	- Do not copy sym_code_functions[]. Just place it in rodata for now.

	- Have the main loop check for termination conditions rather than
	  having unwind_frame() check for them. In other words, let
	  unwind_frame() assume that the fp is valid.

	- Replace the big comment for SYM_CODE functions with a shorter
	  comment.

		/*
		 * As SYM_CODE functions don't follow the usual calling
		 * conventions, we assume by default that any SYM_CODE function
		 * cannot be unwound reliably.
		 *
		 * Note that this includes:
		 *
		 * - Exception handlers and entry assembly
		 * - Trampoline assembly (e.g., ftrace, kprobes)
		 * - Hypervisor-related assembly
		 * - Hibernation-related assembly
		 * - CPU start-stop, suspend-resume assembly
		 * - Kernel relocation assembly
		 */

v7:
	The Mailer screwed up the threading on this. So, I have resent this
	same series as version 8 with proper threading to avoid confusion.
v6:
	From Mark Rutland:

	- The per-frame reliability concept and flag are acceptable. But more
	  work is needed to make the per-frame checks more accurate and more
	  complete. E.g., some code reorg is being worked on that will help.

	  I have now removed the frame->reliable flag and deleted the whole
	  concept of per-frame status. This is orthogonal to this patch series.
	  Instead, I have improved the unwinder to return proper return codes
	  so a caller can take appropriate action without needing per-frame
	  status.

	- Remove the mention of PLTs and update the comment.

	  I have replaced the comment above the call to __kernel_text_address()
	  with the comment suggested by Mark Rutland.

	Other comments:

	- Other comments on the per-frame stuff are not relevant because
	  that approach is not there anymore.

v5:
	From Keiya Nobuta:
	
	- The term blacklist(ed) is not to be used anymore. I have changed it
	  to unreliable. So, the function unwinder_blacklisted() has been
	  changed to unwinder_is_unreliable().

	From Mark Brown:

	- Add a comment for the "reliable" flag in struct stackframe. The
	  reliability attribute is not complete until all the checks are
	  in place. Added a comment above struct stackframe.

	- Include some of the comments in the cover letter in the actual
	  code so that we can compare it with the reliable stack trace
	  requirements document for completeness. I have added a comment:

	  	- above unwinder_is_unreliable() that lists the requirements
		  that are addressed by the function.

		- above the __kernel_text_address() call about all the cases
		  the call covers.

v4:
	From Mark Brown:

	- I was checking the return PC with __kernel_text_address() before
	  the Function Graph trace handling. Mark Brown felt that all the
	  reliability checks should be performed on the original return PC
	  once that is obtained. So, I have moved all the reliability checks
	  to after the Function Graph Trace handling code in the unwinder.
	  Basically, the unwinder should perform PC translations first (for
	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
	  Then, the reliability checks should be applied to the resulting
	  PC.

	- Mark said to improve the naming of the new functions so they don't
	  collide with existing ones. I have used a prefix "unwinder_" for
	  all the new functions.

	From Josh Poimboeuf:

	- In the error scenarios in the unwinder, the reliable flag in the
	  stack frame should be set. Implemented this.

	- Some of the other comments are not relevant to the new code as
	  I have taken a different approach in the new code. That is why
	  I have not made those changes. E.g., Ard wanted me to add the
	  "const" keyword to the global section array. That array does not
	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
	  the same array in a for loop.

	Other changes:

	- Add a new definition for SYM_CODE_END() that adds the address
	  range of the function to a special section called
	  "sym_code_functions".

	- Include the new section under initdata in vmlinux.lds.S.

	- Define an early_initcall() to copy the contents of the
	  "sym_code_functions" section to an array by the same name.

	- Define a function unwinder_blacklisted() that compares a return
	  PC against sym_code_sections[]. If there is a match, mark the
	  stack trace unreliable. Call this from unwind_frame().

v3:
	- Implemented a sym_code_ranges[] array to contains sections bounds
	  for text sections that contain SYM_CODE_*() functions. The unwinder
	  checks each return PC against the sections. If it falls in any of
	  the sections, the stack trace is marked unreliable.

	- Moved SYM_CODE functions from .text and .init.text into a new
	  text section called ".code.text". Added this section to
	  vmlinux.lds.S and sym_code_ranges[].

	- Fixed the logic in the unwinder that handles Function Graph
	  Tracer return trampoline.

	- Removed all the previous code that handles:
		- ftrace entry code for traced function
		- special_functions[] array that lists individual functions
		- kretprobe_trampoline() special case

v2
	- Removed the terminating entry { 0, 0 } in special_functions[]
	  and replaced it with the idiom { /* sentinel */ }.

	- Change the ftrace trampoline entry ftrace_graph_call in
	  special_functions[] to ftrace_call + 4 and added explanatory
	  comments.

	- Unnested #ifdefs in special_functions[] for FTRACE.

v1
	- Define a bool field in struct stackframe. This will indicate if
	  a stack trace is reliable.

	- Implement a special_functions[] array that will be populated
	  with special functions in which the stack trace is considered
	  unreliable.
	
	- Using kallsyms_lookup(), get the address ranges for the special
	  functions and record them.

	- Implement an is_reliable_function(pc). This function will check
	  if a given return PC falls in any of the special functions. If
	  it does, the stack trace is unreliable.

	- Implement check_reliability() function that will check if a
	  stack frame is reliable. Call is_reliable_function() from
	  check_reliability().

	- Before a return PC is checked against special_funtions[], it
	  must be validates as a proper kernel text address. Call
	  __kernel_text_address() from check_reliability().

	- Finally, call check_reliability() from unwind_frame() for
	  each stack frame.

	- Add EL1 exception handlers to special_functions[].

		el1_sync();
		el1_irq();
		el1_error();
		el1_sync_invalid();
		el1_irq_invalid();
		el1_fiq_invalid();
		el1_error_invalid();

	- The above functions are currently defined as LOCAL symbols.
	  Make them global so that they can be referenced from the
	  unwinder code.

	- Add FTRACE trampolines to special_functions[]:

		ftrace_graph_call()
		ftrace_graph_caller()
		return_to_handler()

	- Add the kretprobe trampoline to special functions[]:

		kretprobe_trampoline()

Previous versions and discussion
================================

v11: https://lore.kernel.org/linux-arm-kernel/20211123193723.12112-1-madvenka at linux.microsoft.com/T/#t
v10: https://lore.kernel.org/linux-arm-kernel/4b3d5552-590c-e6a0-866b-9bc51da7bebf at linux.microsoft.com/T/#t
v9: Mailer screwed up the threading. Sent the same as v10 with proper threading.
v8: https://lore.kernel.org/linux-arm-kernel/20210812190603.25326-1-madvenka at linux.microsoft.com/
v7: Mailer screwed up the threading. Sent the same as v8 with proper threading.
v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/

Madhavan T. Venkataraman (10):
  arm64: Remove NULL task check from unwind_frame()
  arm64: Rename unwinder functions
  arm64: Rename stackframe to unwind_state
  arm64: Split unwind_init()
  arm64: Copy unwind arguments to unwind_state
  arm64: Make the unwind loop in unwind() similar to other architectures
  arm64: Introduce stack trace reliability checks in the unwinder
  arm64: Create a list of SYM_CODE functions, check return PC against
    list
  arm64: Introduce arch_stack_walk_reliable()
  arm64: Select HAVE_RELIABLE_STACKTRACE

 arch/arm64/Kconfig                  |   1 +
 arch/arm64/include/asm/linkage.h    |  12 ++
 arch/arm64/include/asm/sections.h   |   1 +
 arch/arm64/include/asm/stacktrace.h |  23 ++-
 arch/arm64/kernel/stacktrace.c      | 286 +++++++++++++++++++++-------
 arch/arm64/kernel/vmlinux.lds.S     |  10 +
 6 files changed, 266 insertions(+), 67 deletions(-)


base-commit: ec6f65fa3de02e060d9a1c7f9247a4a8ad719b58
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:06 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:06 -0600
Subject: [PATCH v12 04/10] arm64: Split unwind_init()
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-5-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

unwind_init() is currently a single function that initializes all of the
unwind state. Split it into the following functions and call them
appropriately:

	- unwind_init_regs() - initialize from regs passed by caller.

	- unwind_init_current() - initialize for the current task from the
	  caller of arch_stack_walk().

	- unwind_init_from_task() - initialize from the saved state of a
	  task other than the current task. In this case, the other
	  task must not be running.

	- unwind_init_common() - initialize fields that are common across
	  the above 3 cases.

This is done so that specialized initialization can be added to each case
in the future.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/kernel/stacktrace.c | 50 +++++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index a1a7ff93b84f..bd797e3f7789 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,11 +33,8 @@
  */
 
 
-static void unwind_init(struct unwind_state *state, unsigned long fp,
-			unsigned long pc)
+static void unwind_init_common(struct unwind_state *state)
 {
-	state->fp = fp;
-	state->pc = pc;
 #ifdef CONFIG_KRETPROBES
 	state->kr_cur = NULL;
 #endif
@@ -56,6 +53,40 @@ static void unwind_init(struct unwind_state *state, unsigned long fp,
 	state->prev_type = STACK_TYPE_UNKNOWN;
 }
 
+/*
+ * TODO: document requirements here.
+ */
+static inline void unwind_init_regs(struct unwind_state *state,
+				    struct pt_regs *regs)
+{
+	state->fp = regs->regs[29];
+	state->pc = regs->pc;
+}
+
+/*
+ * TODO: document requirements here.
+ *
+ * Note: this is always inlined, and we expect our caller to be a noinline
+ * function, such that this starts from our caller's caller.
+ */
+static __always_inline void unwind_init_current(struct unwind_state *state)
+{
+	state->fp = (unsigned long)__builtin_frame_address(1);
+	state->pc = (unsigned long)__builtin_return_address(0);
+}
+
+/*
+ * TODO: document requirements here.
+ *
+ * The caller guarantees that the task is not running.
+ */
+static inline void unwind_init_task(struct unwind_state *state,
+				    struct task_struct *task)
+{
+	state->fp = thread_saved_fp(task);
+	state->pc = thread_saved_pc(task);
+}
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -194,15 +225,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 {
 	struct unwind_state state;
 
+	unwind_init_common(&state);
+
 	if (regs)
-		unwind_init(&state, regs->regs[29], regs->pc);
+		unwind_init_regs(&state, regs);
 	else if (task == current)
-		unwind_init(&state,
-				(unsigned long)__builtin_frame_address(1),
-				(unsigned long)__builtin_return_address(0));
+		unwind_init_current(&state);
 	else
-		unwind_init(&state, thread_saved_fp(task),
-				thread_saved_pc(task));
+		unwind_init_task(&state, task);
 
 	unwind(task, &state, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:07 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:07 -0600
Subject: [PATCH v12 05/10] arm64: Copy unwind arguments to unwind_state
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-6-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Copy the following arguments passed to arch_stack_walk() to unwind_state
so that they can be passed to unwind functions via unwind_state rather
than as separate arguments:

	- task
	- regs
	- consume_entry
	- cookie

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h | 12 ++++++++
 arch/arm64/kernel/stacktrace.c      | 45 ++++++++++++++++-------------
 2 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index fc828c3c5dfd..322817d40a75 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -51,6 +51,14 @@ struct stack_info {
  * @kr_cur:      When KRETPOLINES is selected, holds the kretprobe instance
  *               associated with the most recently encountered replacement lr
  *               value.
+ *
+ * @task:        Pointer to the task structure.
+ *
+ * @regs:        Registers, if any.
+ *
+ * @consume_pc   Consume PC function pointer.
+ *
+ * @cookie       Argument to consume_pc().
  */
 struct unwind_state {
 	unsigned long fp;
@@ -61,6 +69,10 @@ struct unwind_state {
 #ifdef CONFIG_KRETPROBES
 	struct llist_node *kr_cur;
 #endif
+	struct task_struct *task;
+	struct pt_regs *regs;
+	stack_trace_consume_fn consume_pc;
+	void *cookie;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index bd797e3f7789..3ecb8242caa5 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,17 @@
  */
 
 
-static void unwind_init_common(struct unwind_state *state)
+static void unwind_init_common(struct unwind_state *state,
+			       struct task_struct *task,
+			       struct pt_regs *regs,
+			       stack_trace_consume_fn consume_pc,
+			       void *cookie)
 {
+	state->task = task;
+	state->regs = regs;
+	state->consume_pc = consume_pc;
+	state->cookie = cookie;
+
 #ifdef CONFIG_KRETPROBES
 	state->kr_cur = NULL;
 #endif
@@ -56,11 +65,10 @@ static void unwind_init_common(struct unwind_state *state)
 /*
  * TODO: document requirements here.
  */
-static inline void unwind_init_regs(struct unwind_state *state,
-				    struct pt_regs *regs)
+static inline void unwind_init_regs(struct unwind_state *state)
 {
-	state->fp = regs->regs[29];
-	state->pc = regs->pc;
+	state->fp = state->regs->regs[29];
+	state->pc = state->regs->pc;
 }
 
 /*
@@ -80,11 +88,10 @@ static __always_inline void unwind_init_current(struct unwind_state *state)
  *
  * The caller guarantees that the task is not running.
  */
-static inline void unwind_init_task(struct unwind_state *state,
-				    struct task_struct *task)
+static inline void unwind_init_task(struct unwind_state *state)
 {
-	state->fp = thread_saved_fp(task);
-	state->pc = thread_saved_pc(task);
+	state->fp = thread_saved_fp(state->task);
+	state->pc = thread_saved_pc(state->task);
 }
 
 /*
@@ -94,9 +101,9 @@ static inline void unwind_init_task(struct unwind_state *state,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_next(struct task_struct *tsk,
-			       struct unwind_state *state)
+static int notrace unwind_next(struct unwind_state *state)
 {
+	struct task_struct *tsk = state->task;
 	unsigned long fp = state->fp;
 	struct stack_info info;
 
@@ -170,16 +177,14 @@ static int notrace unwind_next(struct task_struct *tsk,
 }
 NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace unwind(struct task_struct *tsk,
-			   struct unwind_state *state,
-			   bool (*fn)(void *, unsigned long), void *data)
+static void notrace unwind(struct unwind_state *state)
 {
 	while (1) {
 		int ret;
 
-		if (!fn(data, state->pc))
+		if (!state->consume_pc(state->cookie, state->pc))
 			break;
-		ret = unwind_next(tsk, state);
+		ret = unwind_next(state);
 		if (ret < 0)
 			break;
 	}
@@ -225,14 +230,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 {
 	struct unwind_state state;
 
-	unwind_init_common(&state);
+	unwind_init_common(&state, task, regs, consume_entry, cookie);
 
 	if (regs)
-		unwind_init_regs(&state, regs);
+		unwind_init_regs(&state);
 	else if (task == current)
 		unwind_init_current(&state);
 	else
-		unwind_init_task(&state, task);
+		unwind_init_task(&state);
 
-	unwind(task, &state, consume_entry, cookie);
+	unwind(&state);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:08 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:08 -0600
Subject: [PATCH v12 06/10] arm64: Make the unwind loop in unwind() similar to
 other architectures
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-7-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Change the loop in unwind()
===========================

Change the unwind loop in unwind() to:

	while (unwind_continue(state))
		unwind_next(state);

This is easy to understand and maintain.

New function unwind_continue()
==============================

Define a new function unwind_continue() that is used in the unwind loop
to check for conditions that terminate a stack trace.

The conditions checked are:

	- If the bottom of the stack (final frame) has been reached,
	  terminate.

	- If the consume_entry() function returns false, the caller of
	  unwind has asked to terminate the stack trace. So, terminate.

	- If unwind_next() failed for some reason (like stack corruption),
	  terminate.

Do not return an error value from unwind_next()
===============================================

We want to check for terminating conditions only in unwind_continue() from
the unwinder loop. So, do not return an error value from unwind_next().
Simply set a flag in unwind_state and check the flag in unwind_continue().

Final FP
========

Introduce a new field "final_fp" in "struct unwind_state". Initialize this
to the final frame of the stack trace:

	task_pt_regs(task)->stackframe

This is where the stacktrace must terminate if it is successful. Add an
explicit comment to that effect.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/stacktrace.h |  6 +++
 arch/arm64/kernel/stacktrace.c      | 70 ++++++++++++++++++-----------
 2 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 322817d40a75..9d1fddc26586 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -59,6 +59,10 @@ struct stack_info {
  * @consume_pc   Consume PC function pointer.
  *
  * @cookie       Argument to consume_pc().
+ *
+ * @final_fp	 Pointer to the final frame.
+ *
+ * @failed:      Unwind failed.
  */
 struct unwind_state {
 	unsigned long fp;
@@ -73,6 +77,8 @@ struct unwind_state {
 	struct pt_regs *regs;
 	stack_trace_consume_fn consume_pc;
 	void *cookie;
+	unsigned long final_fp;
+	bool failed;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 3ecb8242caa5..af0949f028c9 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -60,6 +60,10 @@ static void unwind_init_common(struct unwind_state *state,
 	bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
 	state->prev_fp = 0;
 	state->prev_type = STACK_TYPE_UNKNOWN;
+	state->failed = false;
+
+	/* Stack trace terminates here. */
+	state->final_fp = (unsigned long)task_pt_regs(task)->stackframe;
 }
 
 /*
@@ -94,6 +98,23 @@ static inline void unwind_init_task(struct unwind_state *state)
 	state->pc = thread_saved_pc(state->task);
 }
 
+static bool notrace unwind_continue(struct unwind_state *state)
+{
+	if (state->failed) {
+		/* PC is suspect. Cannot consume it. */
+		return false;
+	}
+
+	if (!state->consume_pc(state->cookie, state->pc)) {
+		/* Caller terminated the unwind. */
+		state->failed = true;
+		return false;
+	}
+
+	return state->fp != state->final_fp;
+}
+NOKPROBE_SYMBOL(unwind_continue);
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -101,24 +122,26 @@ static inline void unwind_init_task(struct unwind_state *state)
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_next(struct unwind_state *state)
+static void notrace unwind_next(struct unwind_state *state)
 {
 	struct task_struct *tsk = state->task;
 	unsigned long fp = state->fp;
 	struct stack_info info;
 
-	/* Final frame; nothing to unwind */
-	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
-		return -ENOENT;
-
-	if (fp & 0x7)
-		return -EINVAL;
+	if (fp & 0x7) {
+		state->failed = true;
+		return;
+	}
 
-	if (!on_accessible_stack(tsk, fp, 16, &info))
-		return -EINVAL;
+	if (!on_accessible_stack(tsk, fp, 16, &info)) {
+		state->failed = true;
+		return;
+	}
 
-	if (test_bit(info.type, state->stacks_done))
-		return -EINVAL;
+	if (test_bit(info.type, state->stacks_done)) {
+		state->failed = true;
+		return;
+	}
 
 	/*
 	 * As stacks grow downward, any valid record on the same stack must be
@@ -134,8 +157,10 @@ static int notrace unwind_next(struct unwind_state *state)
 	 * stack.
 	 */
 	if (info.type == state->prev_type) {
-		if (fp <= state->prev_fp)
-			return -EINVAL;
+		if (fp <= state->prev_fp) {
+			state->failed = true;
+			return;
+		}
 	} else {
 		set_bit(state->prev_type, state->stacks_done);
 	}
@@ -163,8 +188,10 @@ static int notrace unwind_next(struct unwind_state *state)
 		 */
 		orig_pc = ftrace_graph_ret_addr(tsk, NULL, state->pc,
 						(void *)state->fp);
-		if (WARN_ON_ONCE(state->pc == orig_pc))
-			return -EINVAL;
+		if (WARN_ON_ONCE(state->pc == orig_pc)) {
+			state->failed = true;
+			return;
+		}
 		state->pc = orig_pc;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
@@ -172,22 +199,13 @@ static int notrace unwind_next(struct unwind_state *state)
 	if (is_kretprobe_trampoline(state->pc))
 		state->pc = kretprobe_find_ret_addr(tsk, (void *)state->fp, &state->kr_cur);
 #endif
-
-	return 0;
 }
 NOKPROBE_SYMBOL(unwind_next);
 
 static void notrace unwind(struct unwind_state *state)
 {
-	while (1) {
-		int ret;
-
-		if (!state->consume_pc(state->cookie, state->pc))
-			break;
-		ret = unwind_next(state);
-		if (ret < 0)
-			break;
-	}
+	while (unwind_continue(state))
+		unwind_next(state);
 }
 NOKPROBE_SYMBOL(unwind);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:09 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:09 -0600
Subject: [PATCH v12 07/10] arm64: Introduce stack trace reliability checks in
 the unwinder
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-8-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_check_reliability() that will
detect these cases and set a flag in the stack frame. Call
unwind_check_reliability() for every frame in unwind().

Introduce the first reliability check in unwind_check_reliability() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code. Other reliability checks
will be added in the future.

Let unwind() return a boolean to indicate if the stack trace is
reliable.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  3 +++
 arch/arm64/kernel/stacktrace.c      | 29 +++++++++++++++++++++++++++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 9d1fddc26586..47d4be69799a 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -63,6 +63,8 @@ struct stack_info {
  * @final_fp	 Pointer to the final frame.
  *
  * @failed:      Unwind failed.
+ *
+ * @reliable:    Stack trace is reliable.
  */
 struct unwind_state {
 	unsigned long fp;
@@ -79,6 +81,7 @@ struct unwind_state {
 	void *cookie;
 	unsigned long final_fp;
 	bool failed;
+	bool reliable;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index af0949f028c9..54c3396a65c3 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,25 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+/*
+ * Check the stack frame for conditions that make further unwinding unreliable.
+ */
+static void unwind_check_reliability(struct unwind_state *state)
+{
+	if (state->fp == state->final_fp) {
+		/* Final frame; no more unwind, no need to check reliability */
+		return;
+	}
+
+	/*
+	 * If the PC is not a known kernel text address, then we cannot
+	 * be sure that a subsequent unwind will be reliable, as we
+	 * don't know that the code follows our unwind requirements.
+	 */
+	if (!__kernel_text_address(state->pc))
+		state->reliable = false;
+}
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -64,6 +83,8 @@ static void unwind_init_common(struct unwind_state *state,
 
 	/* Stack trace terminates here. */
 	state->final_fp = (unsigned long)task_pt_regs(task)->stackframe;
+
+	state->reliable = true;
 }
 
 /*
@@ -202,10 +223,14 @@ static void notrace unwind_next(struct unwind_state *state)
 }
 NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace unwind(struct unwind_state *state)
+static bool notrace unwind(struct unwind_state *state)
 {
-	while (unwind_continue(state))
+	unwind_check_reliability(state);
+	while (unwind_continue(state)) {
 		unwind_next(state);
+		unwind_check_reliability(state);
+	}
+	return !state->failed && state->reliable;
 }
 NOKPROBE_SYMBOL(unwind);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:10 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:10 -0600
Subject: [PATCH v12 08/10] arm64: Create a list of SYM_CODE functions,
 check return PC against list
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-9-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_check_reliability() that compares a
return PC with sym_code_functions[]. If there is a match, then return
failure.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/linkage.h  | 12 +++++++
 arch/arm64/include/asm/sections.h |  1 +
 arch/arm64/kernel/stacktrace.c    | 55 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S   | 10 ++++++
 4 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index 9906541a6861..616bad74e297 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -68,4 +68,16 @@
 		SYM_FUNC_END_ALIAS(x);		\
 		SYM_FUNC_END_ALIAS(__pi_##x)
 
+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name)				\
+	SYM_END(name, SYM_T_NONE)			;\
+	99:						;\
+	.pushsection "sym_code_functions", "aw"		;\
+	.quad	name					;\
+	.quad	99b					;\
+	.popsection
+
 #endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index 152cb35bf9df..ac01189668c5 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -22,5 +22,6 @@ extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
 extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 54c3396a65c3..1db1ccb61241 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,11 +18,40 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+struct code_range {
+	unsigned long	start;
+	unsigned long	end;
+};
+
+static struct code_range	*sym_code_functions;
+static int			num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+	size_t size = (unsigned long)__sym_code_functions_end -
+		      (unsigned long)__sym_code_functions_start;
+
+	sym_code_functions = (struct code_range *)__sym_code_functions_start;
+	/*
+	 * Order it so that sym_code_functions is not visible before
+	 * num_sym_code_functions.
+	 */
+	smp_mb();
+	num_sym_code_functions = size / sizeof(struct code_range);
+
+	return 0;
+}
+early_initcall(init_sym_code_functions);
+
 /*
  * Check the stack frame for conditions that make further unwinding unreliable.
  */
 static void unwind_check_reliability(struct unwind_state *state)
 {
+	const struct code_range *range;
+	unsigned long pc;
+	int i;
+
 	if (state->fp == state->final_fp) {
 		/* Final frame; no more unwind, no need to check reliability */
 		return;
@@ -35,6 +64,32 @@ static void unwind_check_reliability(struct unwind_state *state)
 	 */
 	if (!__kernel_text_address(state->pc))
 		state->reliable = false;
+
+	/*
+	 * Check the return PC against sym_code_functions[]. If there is a
+	 * match, then the consider the stack frame unreliable.
+	 *
+	 * As SYM_CODE functions don't follow the usual calling conventions,
+	 * we assume by default that any SYM_CODE function cannot be unwound
+	 * reliably.
+	 *
+	 * Note that this includes:
+	 *
+	 * - Exception handlers and entry assembly
+	 * - Trampoline assembly (e.g., ftrace, kprobes)
+	 * - Hypervisor-related assembly
+	 * - Hibernation-related assembly
+	 * - CPU start-stop, suspend-resume assembly
+	 * - Kernel relocation assembly
+	 */
+	pc = state->pc;
+	for (i = 0; i < num_sym_code_functions; i++) {
+		range = &sym_code_functions[i];
+		if (pc >= range->start && pc < range->end) {
+			state->reliable = false;
+			return;
+		}
+	}
 }
 
 /*
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 50bab186c49b..6381e75e566e 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -122,6 +122,14 @@ jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#define SYM_CODE_FUNCTIONS				\
+	. = ALIGN(16);					\
+	.symcode : AT(ADDR(.symcode) - LOAD_OFFSET) {	\
+		__sym_code_functions_start = .;		\
+		KEEP(*(sym_code_functions))		\
+		__sym_code_functions_end = .;		\
+	}
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -209,6 +217,8 @@ SECTIONS
 	swapper_pg_dir = .;
 	. += PAGE_SIZE;
 
+	SYM_CODE_FUNCTIONS
+
 	. = ALIGN(SEGMENT_ALIGN);
 	__init_begin = .;
 	__inittext_begin = .;
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:11 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:11 -0600
Subject: [PATCH v12 09/10] arm64: Introduce arch_stack_walk_reliable()
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-10-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except that it returns -EINVAL if the stack trace is not
reliable.

Until all the reliability checks are in place, arch_stack_walk_reliable()
may not be used by livepatch. But it may be used by debug and test code.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1db1ccb61241..717d30833252 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -339,3 +339,27 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 
 	unwind(&state);
 }
+
+/*
+ * arch_stack_walk_reliable() may not be used for livepatch until all of
+ * the reliability checks are in place in unwind_consume(). However,
+ * debug and test code can choose to use it even if all the checks are not
+ * in place.
+ */
+noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
+					      void *cookie,
+					      struct task_struct *task)
+{
+	struct unwind_state state;
+	bool reliable;
+
+	unwind_init_common(&state, task, NULL, consume_fn, cookie);
+
+	if (task == current)
+		unwind_init_current(&state);
+	else
+		unwind_init_task(&state);
+
+	reliable = unwind(&state);
+	return reliable ? 0 : -EINVAL;
+}
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan  3 08:52:12 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon,  3 Jan 2022 10:52:12 -0600
Subject: [PATCH v12 10/10] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <20220103165212.9303-1-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
Message-ID: <20220103165212.9303-11-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Select HAVE_RELIABLE_STACKTRACE in arm64/Kconfig to allow
arch_stack_walk_reliable() to be used.

Note that this is conditional upon STACK_VALIDATION which will be added
when frame pointer validation is implemented (say via objtool).

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..4f6312784650 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -222,6 +222,7 @@ config ARM64
 	select THREAD_INFO_IN_TASK
 	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
 	select TRACE_IRQFLAGS_SUPPORT
+	select HAVE_RELIABLE_STACKTRACE if FRAME_POINTER && STACK_VALIDATION
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
-- 
2.25.1



From luis.machado at linaro.org  Mon Jan  3 09:27:54 2022
From: luis.machado at linaro.org (Luis Machado)
Date: Mon, 3 Jan 2022 14:27:54 -0300
Subject: [PATCH 5/5] arm64: mte: Document the core dump file format
In-Reply-To: <20211208121941.494956-6-catalin.marinas@arm.com>
References: <20211208121941.494956-1-catalin.marinas@arm.com>
 <20211208121941.494956-6-catalin.marinas@arm.com>
Message-ID: <03135b87-31f2-510c-44ec-1fe3ad0ca4b1@linaro.org>

On 12/8/21 9:19 AM, Catalin Marinas wrote:
> Add the program header definition and data layout for the
> PT_ARM_MEMTAG_MTE segments.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> ---
>   .../arm64/memory-tagging-extension.rst        | 22 +++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
> index 7b99c8f428eb..34c7eb47f61e 100644
> --- a/Documentation/arm64/memory-tagging-extension.rst
> +++ b/Documentation/arm64/memory-tagging-extension.rst
> @@ -213,6 +213,28 @@ address ABI control and MTE configuration of a process as per the
>   Documentation/arm64/tagged-address-abi.rst and above. The corresponding
>   ``regset`` is 1 element of 8 bytes (``sizeof(long))``).
>   
> +Core dump support
> +-----------------
> +
> +The allocation tags for user memory mapped with ``PROT_MTE`` are dumped
> +in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The
> +program header for such segment is defined as:
> +
> +:``p_type``: ``PT_ARM_MEMTAG_MTE``
> +:``p_flags``: 0
> +:``p_offset``: segment file offset
> +:``p_vaddr``: segment virtual address, same as the corresponding
> +  ``PT_LOAD`` segment
> +:``p_paddr``: 0
> +:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 16 / 2``

For the sake of making things extra clear, I'd describe what the 
constants (16 and 2) mean.

> +:``p_memsz``: segment size in memory, same as the corresponding
> +  ``PT_LOAD`` segment
> +:``p_align``: 0
> +
> +The tags are stored in the core file at ``p_offset`` as two 4-bit tags
> +in a byte. With the tag granule of 16 bytes, a 4K page requires 128
> +bytes in the core file.
> +
>   Example of correct usage
>   ========================
>   
> 

Otherwise looks good to me.

Acked-by: Luis Machado <luis.machado at linaro.org>


From luis.machado at linaro.org  Mon Jan  3 09:27:56 2022
From: luis.machado at linaro.org (Luis Machado)
Date: Mon, 3 Jan 2022 14:27:56 -0300
Subject: [PATCH 4/5] arm64: mte: Dump the MTE tags in the core file
In-Reply-To: <20211208121941.494956-5-catalin.marinas@arm.com>
References: <20211208121941.494956-1-catalin.marinas@arm.com>
 <20211208121941.494956-5-catalin.marinas@arm.com>
Message-ID: <613345d5-9287-801e-6f5c-eb91b5e85ad9@linaro.org>

On 12/8/21 9:19 AM, Catalin Marinas wrote:
> For each vma mapped with PROT_MTE (the VM_MTE flag set), generate a
> PT_ARM_MEMTAG_MTE segment in the core file and dump the corresponding
> tags. The in-file size for such segments is 128 bytes per page.
> 
> For pages in a VM_MTE vma which are not present in the user page tables
> or don't have the PG_mte_tagged flag set (e.g. execute-only), just write
> zeros in the core file.
> 
> An example of program headers for two vmas, one 2-page, the other 4-page
> long:
> 
>    Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
>    ...
>    LOAD           0x030000 0x0000ffff80034000 0x0000000000000000 0x000000 0x002000 RW  0x1000
>    LOAD           0x030000 0x0000ffff80036000 0x0000000000000000 0x004000 0x004000 RW  0x1000
>    ...
>    LOPROC+0x1     0x05b000 0x0000ffff80034000 0x0000000000000000 0x000100 0x002000     0
>    LOPROC+0x1     0x05b100 0x0000ffff80036000 0x0000000000000000 0x000200 0x004000     0
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> ---
>   arch/arm64/Kconfig          |   1 +
>   arch/arm64/kernel/Makefile  |   1 +
>   arch/arm64/kernel/elfcore.c | 123 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 125 insertions(+)
>   create mode 100644 arch/arm64/kernel/elfcore.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..fe5d72dd5a3b 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -10,6 +10,7 @@ config ARM64
>   	select ACPI_SPCR_TABLE if ACPI
>   	select ACPI_PPTT if ACPI
>   	select ARCH_HAS_DEBUG_WX
> +	select ARCH_BINFMT_ELF_EXTRA_PHDRS
>   	select ARCH_BINFMT_ELF_STATE
>   	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
>   	select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 88b3e2a21408..986837d7ec82 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -61,6 +61,7 @@ obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
>   obj-$(CONFIG_PARAVIRT)			+= paravirt.o
>   obj-$(CONFIG_RANDOMIZE_BASE)		+= kaslr.o
>   obj-$(CONFIG_HIBERNATION)		+= hibernate.o hibernate-asm.o
> +obj-$(CONFIG_ELF_CORE)			+= elfcore.o
>   obj-$(CONFIG_KEXEC_CORE)		+= machine_kexec.o relocate_kernel.o	\
>   					   cpu-reset.o
>   obj-$(CONFIG_KEXEC_FILE)		+= machine_kexec_file.o kexec_image.o
> diff --git a/arch/arm64/kernel/elfcore.c b/arch/arm64/kernel/elfcore.c
> new file mode 100644
> index 000000000000..3455ee4acc04
> --- /dev/null
> +++ b/arch/arm64/kernel/elfcore.c
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/coredump.h>
> +#include <linux/elfcore.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +
> +#include <asm/cpufeature.h>
> +#include <asm/mte.h>
> +
> +#define for_each_mte_vma(tsk, vma)					\
> +	if (system_supports_mte())					\
> +		for (vma = tsk->mm->mmap; vma; vma = vma->vm_next)	\
> +			if (vma->vm_flags & VM_MTE)
> +
> +static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma)
> +{
> +	if (vma->vm_flags & VM_DONTDUMP)
> +		return 0;
> +
> +	return vma_pages(vma) * MTE_PAGE_TAG_STORAGE;
> +}
> +
> +/* Derived from dump_user_range(); start/end must be page-aligned */
> +static int mte_dump_tag_range(struct coredump_params *cprm,
> +			      unsigned long start, unsigned long end)
> +{
> +	unsigned long addr;
> +
> +	for (addr = start; addr < end; addr += PAGE_SIZE) {
> +		char tags[MTE_PAGE_TAG_STORAGE];
> +		struct page *page = get_dump_page(addr);
> +
> +		/*
> +		 * get_dump_page() returns NULL when encountering an empty
> +		 * page table entry that would otherwise have been filled with
> +		 * the zero page. Skip the equivalent tag dump which would
> +		 * have been all zeros.
> +		 */
> +		if (!page) {
> +			dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
> +			continue;
> +		}
> +
> +		/*
> +		 * Pages mapped in user space as !pte_access_permitted() (e.g.
> +		 * PROT_EXEC only) may not have the PG_mte_tagged flag set.
> +		 */
> +		if (!test_bit(PG_mte_tagged, &page->flags)) {
> +			put_page(page);
> +			dump_skip(cprm, MTE_PAGE_TAG_STORAGE);
> +			continue;
> +		}
> +
> +		mte_save_page_tags(page_address(page), tags);
> +		put_page(page);
> +		if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE))
> +			return 0;
> +	}
> +
> +	return 1;
> +}
> +
> +Elf_Half elf_core_extra_phdrs(void)
> +{
> +	struct vm_area_struct *vma;
> +	int vma_count = 0;
> +
> +	for_each_mte_vma(current, vma)
> +		vma_count++;
> +
> +	return vma_count;
> +}
> +
> +int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset)
> +{
> +	struct vm_area_struct *vma;
> +
> +	for_each_mte_vma(current, vma) {
> +		struct elf_phdr phdr;
> +
> +		phdr.p_type = PT_ARM_MEMTAG_MTE;
> +		phdr.p_offset = offset;
> +		phdr.p_vaddr = vma->vm_start;
> +		phdr.p_paddr = 0;
> +		phdr.p_filesz = mte_vma_tag_dump_size(vma);
> +		phdr.p_memsz = vma->vm_end - vma->vm_start;
> +		offset += phdr.p_filesz;
> +		phdr.p_flags = 0;
> +		phdr.p_align = 0;
> +
> +		if (!dump_emit(cprm, &phdr, sizeof(phdr)))
> +			return 0;
> +	}
> +
> +	return 1;
> +}
> +
> +size_t elf_core_extra_data_size(void)
> +{
> +	struct vm_area_struct *vma;
> +	size_t data_size = 0;
> +
> +	for_each_mte_vma(current, vma)
> +		data_size += mte_vma_tag_dump_size(vma);
> +
> +	return data_size;
> +}
> +
> +int elf_core_write_extra_data(struct coredump_params *cprm)
> +{
> +	struct vm_area_struct *vma;
> +
> +	for_each_mte_vma(current, vma) {
> +		if (vma->vm_flags & VM_DONTDUMP)
> +			continue;
> +
> +		if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end))
> +			return 0;
> +	}
> +
> +	return 1;
> +}
> 

Acked-by: Luis Machado <luis.machado at linaro.org>


From luis.machado at linaro.org  Mon Jan  3 09:27:58 2022
From: luis.machado at linaro.org (Luis Machado)
Date: Mon, 3 Jan 2022 14:27:58 -0300
Subject: [PATCH 3/5] arm64: mte: Define the number of bytes for storing
 the tags in a page
In-Reply-To: <20211208121941.494956-4-catalin.marinas@arm.com>
References: <20211208121941.494956-1-catalin.marinas@arm.com>
 <20211208121941.494956-4-catalin.marinas@arm.com>
Message-ID: <decd67e4-e659-18bd-c848-f840cda98ba4@linaro.org>

On 12/8/21 9:19 AM, Catalin Marinas wrote:
> Rather than explicitly calculating the number of bytes for a compact tag
> storage format corresponding to a page, just add a MTE_PAGE_TAG_STORAGE
> macro. With the current MTE implementation of 4 bits per tag, we store
> 2 tags in a byte.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> ---
>   arch/arm64/include/asm/mte-def.h | 1 +
>   arch/arm64/lib/mte.S             | 4 ++--
>   arch/arm64/mm/mteswap.c          | 2 +-
>   3 files changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-def.h
> index 626d359b396e..14ee86b019c2 100644
> --- a/arch/arm64/include/asm/mte-def.h
> +++ b/arch/arm64/include/asm/mte-def.h
> @@ -11,6 +11,7 @@
>   #define MTE_TAG_SHIFT		56
>   #define MTE_TAG_SIZE		4
>   #define MTE_TAG_MASK		GENMASK((MTE_TAG_SHIFT + (MTE_TAG_SIZE - 1)), MTE_TAG_SHIFT)
> +#define MTE_PAGE_TAG_STORAGE	(MTE_GRANULES_PER_PAGE * MTE_TAG_SIZE / 8)
>   
>   #define __MTE_PREAMBLE		ARM64_ASM_PREAMBLE ".arch_extension memtag\n"
>   
> diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S
> index e83643b3995f..62a1025aa118 100644
> --- a/arch/arm64/lib/mte.S
> +++ b/arch/arm64/lib/mte.S
> @@ -128,7 +128,7 @@ SYM_FUNC_END(mte_copy_tags_to_user)
>   /*
>    * Save the tags in a page
>    *   x0 - page address
> - *   x1 - tag storage
> + *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
>    */
>   SYM_FUNC_START(mte_save_page_tags)
>   	multitag_transfer_size x7, x5
> @@ -152,7 +152,7 @@ SYM_FUNC_END(mte_save_page_tags)
>   /*
>    * Restore the tags in a page
>    *   x0 - page address
> - *   x1 - tag storage
> + *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
>    */
>   SYM_FUNC_START(mte_restore_page_tags)
>   	multitag_transfer_size x7, x5
> diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
> index 7c4ef56265ee..a9e50e930484 100644
> --- a/arch/arm64/mm/mteswap.c
> +++ b/arch/arm64/mm/mteswap.c
> @@ -12,7 +12,7 @@ static DEFINE_XARRAY(mte_pages);
>   void *mte_allocate_tag_storage(void)
>   {
>   	/* tags granule is 16 bytes, 2 tags stored per byte */
> -	return kmalloc(PAGE_SIZE / 16 / 2, GFP_KERNEL);
> +	return kmalloc(MTE_PAGE_TAG_STORAGE, GFP_KERNEL);
>   }
>   
>   void mte_free_tag_storage(char *storage)
> 

Acked-by: Luis Machado <luis.machado at linaro.org>


From luis.machado at linaro.org  Mon Jan  3 09:28:01 2022
From: luis.machado at linaro.org (Luis Machado)
Date: Mon, 3 Jan 2022 14:28:01 -0300
Subject: [PATCH 2/5] elf: Introduce the ARM MTE ELF segment type
In-Reply-To: <20211208121941.494956-3-catalin.marinas@arm.com>
References: <20211208121941.494956-1-catalin.marinas@arm.com>
 <20211208121941.494956-3-catalin.marinas@arm.com>
Message-ID: <44b0925a-b8d2-b9b8-d383-fd6c3fb45894@linaro.org>

On 12/8/21 9:19 AM, Catalin Marinas wrote:
> Memory tags will be dumped in the core file as segments with their own
> type. Discussions with the binutils and the generic ABI community
> settled on using new definitions in the PT_*PROC space (and to be
> documented in the processor-specific ABIs).
> 
> Introduce PT_ARM_MEMTAG_MTE as (PT_LOPROC + 0x1). Not included in this
> patch since there is no upstream support but the CHERI/BSD community
> will also reserve:
> 
>    #define PT_ARM_MEMTAG_CHERI    (PT_LOPROC + 0x2)
>    #define PT_RISCV_MEMTAG_CHERI  (PT_LOPROC + 0x3)
> 
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> ---
>   include/uapi/linux/elf.h | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index 61bf4774b8f2..fe8e5b74cb39 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -40,6 +40,9 @@ typedef __s64	Elf64_Sxword;
>   
>   #define PT_GNU_STACK	(PT_LOOS + 0x474e551)
>   
> +/* ARM MTE memory tag segment type */
> +#define PT_ARM_MEMTAG_MTE	(PT_LOPROC + 0x1)
> +
>   /*
>    * Extended Numbering
>    *
> 

Sorry for the delay. This looks good from the debugger's side.

Acked-by: Luis Machado <luis.machado at linaro.org>


From sashal at kernel.org  Mon Jan  3 09:28:37 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon,  3 Jan 2022 12:28:37 -0500
Subject: [PATCH AUTOSEL 5.15 04/16] usb: mtu3: fix interval value for intr and
 isoc
In-Reply-To: <20220103172849.1612731-1-sashal@kernel.org>
References: <20220103172849.1612731-1-sashal@kernel.org>
Message-ID: <20220103172849.1612731-4-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit e3d4621c22f90c33321ae6a6baab60cdb8e5a77c ]

Use the Interval value from isoc/intr endpoint descriptor, no need
minus one. The original code doesn't cause transfer error for
normal cases, but it may have side effect with respond time of ERDY
or tPingTimeout.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218095749.6250-1-chunfeng.yun at mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/mtu3/mtu3_gadget.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index a9a65b4bbfede..c51be015345b9 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -77,7 +77,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_int(desc) ||
 				usb_endpoint_xfer_isoc(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			if (usb_endpoint_xfer_isoc(desc) && comp_desc)
 				mult = comp_desc->bmAttributes;
 		}
@@ -89,7 +89,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_isoc(desc) ||
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
-- 
2.34.1



From sashal at kernel.org  Mon Jan  3 09:29:54 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon,  3 Jan 2022 12:29:54 -0500
Subject: [PATCH AUTOSEL 5.10 1/8] usb: mtu3: fix interval value for intr and
 isoc
Message-ID: <20220103173001.1613277-1-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit e3d4621c22f90c33321ae6a6baab60cdb8e5a77c ]

Use the Interval value from isoc/intr endpoint descriptor, no need
minus one. The original code doesn't cause transfer error for
normal cases, but it may have side effect with respond time of ERDY
or tPingTimeout.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218095749.6250-1-chunfeng.yun at mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/mtu3/mtu3_gadget.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 0b3aa7c65857a..ae480ab1415b9 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -77,7 +77,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_int(desc) ||
 				usb_endpoint_xfer_isoc(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			if (usb_endpoint_xfer_isoc(desc) && comp_desc)
 				mult = comp_desc->bmAttributes;
 		}
@@ -89,7 +89,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_isoc(desc) ||
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
-- 
2.34.1



From sashal at kernel.org  Mon Jan  3 09:30:13 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon,  3 Jan 2022 12:30:13 -0500
Subject: [PATCH AUTOSEL 5.4 1/6] usb: mtu3: fix interval value for intr and
 isoc
Message-ID: <20220103173018.1613394-1-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit e3d4621c22f90c33321ae6a6baab60cdb8e5a77c ]

Use the Interval value from isoc/intr endpoint descriptor, no need
minus one. The original code doesn't cause transfer error for
normal cases, but it may have side effect with respond time of ERDY
or tPingTimeout.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218095749.6250-1-chunfeng.yun at mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/mtu3/mtu3_gadget.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 619c4598e64ea..63f82026cca39 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -85,7 +85,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_int(desc) ||
 				usb_endpoint_xfer_isoc(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			if (usb_endpoint_xfer_isoc(desc) && comp_desc)
 				mult = comp_desc->bmAttributes;
 		}
@@ -97,7 +97,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_isoc(desc) ||
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
-- 
2.34.1



From sashal at kernel.org  Mon Jan  3 09:30:25 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon,  3 Jan 2022 12:30:25 -0500
Subject: [PATCH AUTOSEL 4.19 1/5] usb: mtu3: fix interval value for intr and
 isoc
Message-ID: <20220103173029.1613474-1-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit e3d4621c22f90c33321ae6a6baab60cdb8e5a77c ]

Use the Interval value from isoc/intr endpoint descriptor, no need
minus one. The original code doesn't cause transfer error for
normal cases, but it may have side effect with respond time of ERDY
or tPingTimeout.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218095749.6250-1-chunfeng.yun at mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/mtu3/mtu3_gadget.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c
index 270721cf229f7..c5c864a02a763 100644
--- a/drivers/usb/mtu3/mtu3_gadget.c
+++ b/drivers/usb/mtu3/mtu3_gadget.c
@@ -82,7 +82,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_int(desc) ||
 				usb_endpoint_xfer_isoc(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			if (usb_endpoint_xfer_isoc(desc) && comp_desc)
 				mult = comp_desc->bmAttributes;
 		}
@@ -94,7 +94,7 @@ static int mtu3_ep_enable(struct mtu3_ep *mep)
 		if (usb_endpoint_xfer_isoc(desc) ||
 				usb_endpoint_xfer_int(desc)) {
 			interval = desc->bInterval;
-			interval = clamp_val(interval, 1, 16) - 1;
+			interval = clamp_val(interval, 1, 16);
 			mult = usb_endpoint_maxp_mult(desc) - 1;
 		}
 		break;
-- 
2.34.1



From nicolas.ferre at microchip.com  Mon Jan  3 09:35:50 2022
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 3 Jan 2022 18:35:50 +0100
Subject: [PATCH 3/8] dt-bindings: rng: atmel,at91-trng: document sama7g5
 TRNG
In-Reply-To: <20211227183251.132525-3-krzysztof.kozlowski@canonical.com>
References: <20211227183251.132525-1-krzysztof.kozlowski@canonical.com>
 <20211227183251.132525-3-krzysztof.kozlowski@canonical.com>
Message-ID: <806f614d-4c83-53fa-dd1d-8054bc84d755@microchip.com>

On 27/12/2021 at 19:32, Krzysztof Kozlowski wrote:
> Add compatbile for Microchip sama7g5 TRNG.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

As far as I understand:
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Thanks for having taken care of this.
Best regards,
   Nicolas

> ---
>   .../devicetree/bindings/rng/atmel,at91-trng.yaml      | 11 ++++++++---
>   1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> index 0324e863dab8..c1527637eb74 100644
> --- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> +++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> @@ -13,9 +13,14 @@ maintainers:
> 
>   properties:
>     compatible:
> -    enum:
> -      - atmel,at91sam9g45-trng
> -      - microchip,sam9x60-trng
> +    oneOf:
> +      - enum:
> +          - atmel,at91sam9g45-trng
> +          - microchip,sam9x60-trng
> +      - items:
> +          - enum:
> +              - microchip,sama7g5-trng
> +          - const: atmel,at91sam9g45-trng
> 
>     clocks:
>       maxItems: 1
> --
> 2.32.0
> 


-- 
Nicolas Ferre


From nicolas.ferre at microchip.com  Mon Jan  3 09:36:37 2022
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Mon, 3 Jan 2022 18:36:37 +0100
Subject: [PATCH 2/8] dt-bindings: rng: atmel, at91-trng: convert Atmel TRNG
 to dtschema
In-Reply-To: <5a3d7233-8ce0-dbb5-aac4-393caadf2a6a@canonical.com>
References: <20211227183251.132525-1-krzysztof.kozlowski@canonical.com>
 <20211227183251.132525-2-krzysztof.kozlowski@canonical.com>
 <1640696040.235226.685116.nullmailer@robh.at.kernel.org>
 <5a3d7233-8ce0-dbb5-aac4-393caadf2a6a@canonical.com>
Message-ID: <045f43d9-58e5-72a6-10fc-e47d875aeb21@microchip.com>

On 28/12/2021 at 14:07, Krzysztof Kozlowski wrote:
> On 28/12/2021 13:54, Rob Herring wrote:
>> On Mon, 27 Dec 2021 19:32:45 +0100, Krzysztof Kozlowski wrote:
>>> Convert the Atmel TRNG bindings to DT schema.
>>>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>> ---
>>>   .../bindings/rng/atmel,at91-trng.yaml         | 46 +++++++++++++++++++
>>>   .../devicetree/bindings/rng/atmel-trng.txt    | 16 -------
>>>   2 files changed, 46 insertions(+), 16 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
>>>   delete mode 100644 Documentation/devicetree/bindings/rng/atmel-trng.txt
>>>
>>
>> Running 'make dtbs_check' with the schema in this patch gives the
>> following warnings. Consider if they are expected or the schema is
>> incorrect. These may not be new warnings.
>>
>> Note that it is not yet a requirement to have 0 warnings for dtbs_check.
>> This will change in the future.
>>
>> Full log is available here: https://patchwork.ozlabs.org/patch/1573492
>>
>>
>> rng at e2010000: compatible:0: 'microchip,sama7g5-trng' is not one of ['atmel,at91sam9g45-trng', 'microchip,sam9x60-trng']
>>        arch/arm/boot/dts/at91-sama7g5ek.dt.yaml
>>
>> rng at e2010000: compatible: Additional items are not allowed ('atmel,at91sam9g45-trng' was unexpected)
>>        arch/arm/boot/dts/at91-sama7g5ek.dt.yaml
>>
>> rng at e2010000: compatible: ['microchip,sama7g5-trng', 'atmel,at91sam9g45-trng'] is too long
>>        arch/arm/boot/dts/at91-sama7g5ek.dt.yaml
>>
> 
> This patch is only converting the existing bindings, so new compatible
> is not added. The issue reported here is being fixed in the next patch
> (3/8).

Thanks Krzysztof!
Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Best regards,
   Nicolas


-- 
Nicolas Ferre


From sebastian.reichel at collabora.com  Mon Jan  3 09:39:34 2022
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Mon, 3 Jan 2022 18:39:34 +0100
Subject: [PATCH] rtc: mt6397: Check for null res pointer
In-Reply-To: <20211220083811.907261-1-jiasheng@iscas.ac.cn>
References: <20211220083811.907261-1-jiasheng@iscas.ac.cn>
Message-ID: <20220103173934.qupnu5gne2v2tpig@earth.universe>

Hi,

On Mon, Dec 20, 2021 at 04:38:11PM +0800, Jiasheng Jiang wrote:
> The return value of platform_get_resource() needs to be checked.
> To avoid use of error pointer in case that there is no suitable
> resource.
> 
> Fixes: d28c74c10751 ("power: reset: add driver for mt6323 poweroff")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---

Thanks, I fixed the subject and queued the patch.

-- Sebastian

>  drivers/power/reset/mt6323-poweroff.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c
> index 0532803e6cbc..d90e76fcb938 100644
> --- a/drivers/power/reset/mt6323-poweroff.c
> +++ b/drivers/power/reset/mt6323-poweroff.c
> @@ -57,6 +57,9 @@ static int mt6323_pwrc_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  
>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res)
> +		return -EINVAL;
> +
>  	pwrc->base = res->start;
>  	pwrc->regmap = mt6397_chip->regmap;
>  	pwrc->dev = &pdev->dev;
> -- 
> 2.25.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220103/927bc186/attachment.sig>

From narmstrong at baylibre.com  Mon Jan  3 09:56:36 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon,  3 Jan 2022 18:56:36 +0100
Subject: [PATCH net-next 1/3] dt-bindings: net: oxnas-dwmac: Add bindings for
 OX810SE
In-Reply-To: <20220103175638.89625-1-narmstrong@baylibre.com>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
Message-ID: <20220103175638.89625-2-narmstrong@baylibre.com>

Add SoC specific bindings for OX810SE support.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 Documentation/devicetree/bindings/net/oxnas-dwmac.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
index d7117a22fd87..27db496f1ce8 100644
--- a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
@@ -9,6 +9,9 @@ Required properties on all platforms:
 - compatible:	For the OX820 SoC, it should be :
 		- "oxsemi,ox820-dwmac" to select glue
 		- "snps,dwmac-3.512" to select IP version.
+		For the OX810SE SoC, it should be :
+		- "oxsemi,ox810se-dwmac" to select glue
+		- "snps,dwmac-3.512" to select IP version.
 
 - clocks: Should contain phandles to the following clocks
 - clock-names:	Should contain the following:
-- 
2.25.1



From narmstrong at baylibre.com  Mon Jan  3 09:56:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon,  3 Jan 2022 18:56:35 +0100
Subject: [PATCH 0/3] ARM: ox810se: Add Ethernet support
Message-ID: <20220103175638.89625-1-narmstrong@baylibre.com>

This adds support for the Synopsys DWMAC controller found in the
OX820SE SoC, by using almost the same glue code as the OX820.

Neil Armstrong (3):
  dt-bindings: net: oxnas-dwmac: Add bindings for OX810SE
  net: stmmac: dwmac-oxnas: Add support for OX810SE
  ARM: dts: ox810se: Add Ethernet support

 .../devicetree/bindings/net/oxnas-dwmac.txt   |  3 +
 arch/arm/boot/dts/ox810se-wd-mbwe.dts         |  4 +
 arch/arm/boot/dts/ox810se.dtsi                | 18 ++++
 .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 92 ++++++++++++++-----
 4 files changed, 95 insertions(+), 22 deletions(-)

-- 
2.25.1



From narmstrong at baylibre.com  Mon Jan  3 09:56:37 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon,  3 Jan 2022 18:56:37 +0100
Subject: [PATCH net-next 2/3] net: stmmac: dwmac-oxnas: Add support for OX810SE
In-Reply-To: <20220103175638.89625-1-narmstrong@baylibre.com>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
Message-ID: <20220103175638.89625-3-narmstrong@baylibre.com>

Add support for OX810SE dwmac glue setup, which is a simplified version
of the OX820 introduced later with more control on the PHY interface.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 92 ++++++++++++++-----
 1 file changed, 70 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
index adfeb8d3293d..7ffa4a4eb30f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
@@ -48,12 +49,58 @@
 #define DWMAC_RX_VARDELAY(d)		((d) << DWMAC_RX_VARDELAY_SHIFT)
 #define DWMAC_RXN_VARDELAY(d)		((d) << DWMAC_RXN_VARDELAY_SHIFT)
 
+struct oxnas_dwmac;
+
+struct oxnas_dwmac_data {
+	void (*setup)(struct oxnas_dwmac *dwmac);
+};
+
 struct oxnas_dwmac {
 	struct device	*dev;
 	struct clk	*clk;
 	struct regmap	*regmap;
+	const struct oxnas_dwmac_data	*data;
 };
 
+static void oxnas_dwmac_setup_ox810se(struct oxnas_dwmac *dwmac)
+{
+	unsigned int value;
+
+	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
+	value = BIT(DWMAC_CKEN_GTX)		|
+		 /* Use simple mux for 25/125 Mhz clock switching */
+		 BIT(DWMAC_SIMPLE_MUX);
+
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
+}
+
+static void oxnas_dwmac_setup_ox820(struct oxnas_dwmac *dwmac)
+{
+	unsigned int value;
+
+	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
+	value = BIT(DWMAC_CKEN_GTX)		|
+		 /* Use simple mux for 25/125 Mhz clock switching */
+		BIT(DWMAC_SIMPLE_MUX)		|
+		/* set auto switch tx clock source */
+		BIT(DWMAC_AUTO_TX_SOURCE)	|
+		/* enable tx & rx vardelay */
+		BIT(DWMAC_CKEN_TX_OUT)		|
+		BIT(DWMAC_CKEN_TXN_OUT)	|
+		BIT(DWMAC_CKEN_TX_IN)		|
+		BIT(DWMAC_CKEN_RX_OUT)		|
+		BIT(DWMAC_CKEN_RXN_OUT)	|
+		BIT(DWMAC_CKEN_RX_IN);
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
+
+	/* set tx & rx vardelay */
+	value = DWMAC_TX_VARDELAY(4)	|
+		DWMAC_TXN_VARDELAY(2)	|
+		DWMAC_RX_VARDELAY(10)	|
+		DWMAC_RXN_VARDELAY(8);
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
+}
+
 static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
 {
 	struct oxnas_dwmac *dwmac = priv;
@@ -75,27 +122,7 @@ static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
 		return ret;
 	}
 
-	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
-	value |= BIT(DWMAC_CKEN_GTX)		|
-		 /* Use simple mux for 25/125 Mhz clock switching */
-		 BIT(DWMAC_SIMPLE_MUX)		|
-		 /* set auto switch tx clock source */
-		 BIT(DWMAC_AUTO_TX_SOURCE)	|
-		 /* enable tx & rx vardelay */
-		 BIT(DWMAC_CKEN_TX_OUT)		|
-		 BIT(DWMAC_CKEN_TXN_OUT)	|
-		 BIT(DWMAC_CKEN_TX_IN)		|
-		 BIT(DWMAC_CKEN_RX_OUT)		|
-		 BIT(DWMAC_CKEN_RXN_OUT)	|
-		 BIT(DWMAC_CKEN_RX_IN);
-	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
-
-	/* set tx & rx vardelay */
-	value = DWMAC_TX_VARDELAY(4)	|
-		DWMAC_TXN_VARDELAY(2)	|
-		DWMAC_RX_VARDELAY(10)	|
-		DWMAC_RXN_VARDELAY(8);
-	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
+	dwmac->data->setup(dwmac);
 
 	return 0;
 }
@@ -128,6 +155,12 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
 		goto err_remove_config_dt;
 	}
 
+	dwmac->data = (const struct oxnas_dwmac_data *)of_device_get_match_data(&pdev->dev);
+	if (!dwmac->data) {
+		ret = -EINVAL;
+		goto err_remove_config_dt;
+	}
+
 	dwmac->dev = &pdev->dev;
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->init = oxnas_dwmac_init;
@@ -166,8 +199,23 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static const struct oxnas_dwmac_data ox810se_dwmac_data = {
+	.setup = oxnas_dwmac_setup_ox810se,
+};
+
+static const struct oxnas_dwmac_data ox820_dwmac_data = {
+	.setup = oxnas_dwmac_setup_ox820,
+};
+
 static const struct of_device_id oxnas_dwmac_match[] = {
-	{ .compatible = "oxsemi,ox820-dwmac" },
+	{
+		.compatible = "oxsemi,ox810se-dwmac",
+		.data = &ox810se_dwmac_data,
+	},
+	{
+		.compatible = "oxsemi,ox820-dwmac",
+		.data = &ox820_dwmac_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);
-- 
2.25.1



From semen.protsenko at linaro.org  Mon Jan  3 10:18:26 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon,  3 Jan 2022 20:18:26 +0200
Subject: [PATCH] arm64: dts: exynos: Add missing gpm6 and gpm7 nodes to
 Exynos850
Message-ID: <20220103181826.2136-1-semen.protsenko@linaro.org>

gpm6 and gpm7 nodes are missing in Exynos850 device tree. Next errors
are reported because of that:

    Missing node for bank gpm6 - invalid DTB
    Missing node for bank gpm7 - invalid DTB

Add missing nodes to make those available to use, and to fix boot
errors.

Fixes: e3493220fd3e ("arm64: dts: exynos: Add initial Exynos850 SoC support")
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
NOTES:
  - Recommend to apply this patch after "arm64: dts: exynos: align
    pinctrl with dtschema in Exynos850"
  - This patch also brings back two interrupts removed in "arm64:
    dts: exynos: drop incorrectly placed wakeup interrupts in Exynos850"

 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
index a71acf358d2d..f43e4a206282 100644
--- a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
@@ -194,6 +194,26 @@ gpm5: gpm5-gpio-bank {
 		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	gpm6: gpm6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	gpm7: gpm7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	/* USI_CMGP0: HSI2C function */
 	hsi2c3_pins: hsi2c3-pins {
 		samsung,pins = "gpm0-0", "gpm1-0";
-- 
2.30.2



From jbx6244 at gmail.com  Mon Jan  3 10:26:36 2022
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 3 Jan 2022 19:26:36 +0100
Subject: [PATCH v7 3/4] phy: rockchip: add naneng combo phy for RK3568
In-Reply-To: <20211230084815.28110-4-yifeng.zhao@rock-chips.com>
References: <20211230084815.28110-1-yifeng.zhao@rock-chips.com>
 <20211230084815.28110-4-yifeng.zhao@rock-chips.com>
Message-ID: <4838413b-c424-cf55-0699-9cd8ac23d9c2@gmail.com>

Hi Yifeng, Kishon, rob+dt,

Some comments, have a look if it's useful.

====

Could the DT and phy maintainer advise the correct/right driver
structure to Yifeng, so that we can move forward!

====

This driver still follows the wrong approach.
Things used in the manufacturer tree are not necessary future proof in a
mainline kernel.
In order to switch SGMII input between lane1 and lanes2 phy structures
it is needed that there is a parent node.

Could you look at combo phy example:

https://elixir.bootlin.com/linux/latest/source/drivers/phy/marvell/phy-mvebu-a3700-comphy.c

To prevent accidents with a DT from the manefucturer tree and mainline
use a differnet compatible string for each SoC.

See version 6:
Use for_each_available_child_of_node to find all available subnodes.

Make for each SoC a structure with supported features.

Make better use of the phy frame work ops  (setmode, poweron).

====
Use enum phy_mode instead of PHY_TYPE.

PHY_TYPE are used in DT.
phy_mode are used in struct phy *phy
====

Example to generate the capabilities structure:
static const struct rk3568_multiphy_conf rk3568_multiphy_modes[] = {
	/* lane 0 */
	RK3568_MULTI_CONF_GEN(0, PHY_MODE_SATA, 0,
				    MULTI_FW_MODE_SATA),
	RK3568_MULTI_CONF_GEN(0, PHY_MODE_USB_HOST_SS, 0,
				    MULTI_FW_MODE_USB3H),
	/* lane 1 */
	RK3568_MULTI_CONF_GEN(1, PHY_MODE_SATA, 0,
				    MULTI_FW_MODE_SATA),
	RK3568_MULTI_CONF_GEN(1, PHY_MODE_USB_HOST_SS, 0,
				    MULTI_FW_MODE_USB3H),
	RK3568_MULTI_CONF_ETH(1, PHY_INTERFACE_MODE_SGMII, 0,
				    MULTI_FW_MODE_SGMII),
	/* lane 2 */
	RK3568_MULTI_CONF_GEN(2, PHY_MODE_SATA, 0,
				    MULTI_FW_MODE_SATA),
	RK3568_MULTI_CONF_ETH(2, PHY_INTERFACE_MODE_SGMII, 1,
				    MULTI_FW_MODE_SGMII),
	RK3568_MULTI_CONF_GEN(2, PHY_MODE_PCIE, 0,
				    MULTI_FW_MODE_PCIE),
};

On 12/30/21 9:48 AM, Yifeng Zhao wrote:
> This patch implements a combo phy driver for Rockchip SoCs
> with NaNeng IP block. This phy can be used as pcie-phy, usb3-phy,
> sata-phy or sgmii-phy.
> 
> Signed-off-by: Yifeng Zhao <yifeng.zhao at rock-chips.com>
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
> 
> Changes in v7:
> - rename regs
> - remove pipe_sgmii_mac_sel, u3otg0_port_en and u3otg1_port_en
> 
> Changes in v5:
> - add rockchip_combphy_updatel()
> - restyle
> 
> Changes in v4:
> - restyle
> - add devm_reset_control_array_get()
> - remove clk structure
> - change refclk DT parse
> - change dev_err message
> - add dot to phrase
> - add ext_refclk variable
> - add enable_ssc variable
> - rename rockchip_combphy_param_write
> - remove param_read
> - replace rockchip-naneng-combphy driver name
> 
> Changes in v3:
> - Using api devm_reset_control_get_optional_exclusive and dev_err_probe.
> - Remove apb_rst.
> - Redefine registers address.
> 
> Changes in v2:
> - Using api devm_platform_get_and_ioremap_resource.
> - Modify rockchip_combphy_set_Mode.
> - Add some PHY registers definition.
> 
>  drivers/phy/rockchip/Kconfig                  |   8 +
>  drivers/phy/rockchip/Makefile                 |   1 +
>  .../rockchip/phy-rockchip-naneng-combphy.c    | 589 ++++++++++++++++++
>  3 files changed, 598 insertions(+)
>  create mode 100644 drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> 
> diff --git a/drivers/phy/rockchip/Kconfig b/drivers/phy/rockchip/Kconfig
> index e812adad7242..9022e395c056 100644
> --- a/drivers/phy/rockchip/Kconfig
> +++ b/drivers/phy/rockchip/Kconfig
> @@ -66,6 +66,14 @@ config PHY_ROCKCHIP_INNO_DSIDPHY
>  	  Enable this to support the Rockchip MIPI/LVDS/TTL PHY with
>  	  Innosilicon IP block.
>  
> +config PHY_ROCKCHIP_NANENG_COMBO_PHY
> +	tristate "Rockchip NANENG COMBO PHY Driver"
> +	depends on ARCH_ROCKCHIP && OF
> +	select GENERIC_PHY
> +	help
> +	  Enable this to support the Rockchip PCIe/USB3.0/SATA/QSGMII
> +	  combo PHY with NaNeng IP block.
> +
>  config PHY_ROCKCHIP_PCIE
>  	tristate "Rockchip PCIe PHY Driver"
>  	depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
> diff --git a/drivers/phy/rockchip/Makefile b/drivers/phy/rockchip/Makefile
> index f0eec212b2aa..a5041efb5b8f 100644
> --- a/drivers/phy/rockchip/Makefile
> +++ b/drivers/phy/rockchip/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY)	+= phy-rockchip-inno-csidphy.o
>  obj-$(CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY)	+= phy-rockchip-inno-dsidphy.o
>  obj-$(CONFIG_PHY_ROCKCHIP_INNO_HDMI)	+= phy-rockchip-inno-hdmi.o
>  obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2)	+= phy-rockchip-inno-usb2.o
> +obj-$(CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY)	+= phy-rockchip-naneng-combphy.o
>  obj-$(CONFIG_PHY_ROCKCHIP_PCIE)		+= phy-rockchip-pcie.o
>  obj-$(CONFIG_PHY_ROCKCHIP_TYPEC)	+= phy-rockchip-typec.o
>  obj-$(CONFIG_PHY_ROCKCHIP_USB)		+= phy-rockchip-usb.o
> diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> new file mode 100644
> index 000000000000..47137a5c448a
> --- /dev/null
> +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c
> @@ -0,0 +1,589 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Rockchip PIPE USB3.0 PCIE SATA Combo Phy driver
> + *
> + * Copyright (C) 2021 Rockchip Electronics Co., Ltd.
> + */
> +
> +#include <dt-bindings/phy/phy.h>
> +#include <linux/clk.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_device.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +#include <linux/units.h>
> +
> +#define BIT_WRITEABLE_SHIFT		16
> +#define REF_CLOCK_24MHz			(24 * HZ_PER_MHZ)
> +#define REF_CLOCK_25MHz			(25 * HZ_PER_MHZ)
> +#define REF_CLOCK_100MHz		(100 * HZ_PER_MHZ)
> +
> +/* COMBO PHY REG */
> +#define PHYREG6				0x14
> +#define PHYREG6_PLL_DIV_MASK		GENMASK(7, 6)
> +#define PHYREG6_PLL_DIV_SHIFT		6
> +#define PHYREG6_PLL_DIV_2		1
> +
> +#define PHYREG7				0x18
> +#define PHYREG7_TX_RTERM_MASK		GENMASK(7, 4)
> +#define PHYREG7_TX_RTERM_SHIFT		4
> +#define PHYREG7_TX_RTERM_50OHM		8
> +#define PHYREG7_RX_RTERM_MASK		GENMASK(3, 0)
> +#define PHYREG7_RX_RTERM_SHIFT		0
> +#define PHYREG7_RX_RTERM_44OHM		15
> +
> +#define PHYREG8				0x1C
> +#define PHYREG8_SSC_EN			BIT(4)
> +
> +#define PHYREG11			0x28
> +#define PHYREG11_SU_TRIM_0_7		0xF0
> +
> +#define PHYREG12			0x2C
> +#define PHYREG12_PLL_LPF_ADJ_VALUE	4
> +
> +#define PHYREG13			0x30
> +#define PHYREG13_RESISTER_MASK		GENMASK(5, 4)
> +#define PHYREG13_RESISTER_SHIFT		0x4
> +#define PHYREG13_RESISTER_HIGH_Z	3
> +#define PHYREG13_CKRCV_AMP0		BIT(7)
> +
> +#define PHYREG14			0x34
> +#define PHYREG14_CKRCV_AMP1		BIT(0)
> +
> +#define PHYREG15			0x38
> +#define PHYREG15_CTLE_EN		BIT(0)
> +#define PHYREG15_SSC_CNT_MASK		GENMASK(7, 6)
> +#define PHYREG15_SSC_CNT_SHIFT		6
> +#define PHYREG15_SSC_CNT_VALUE		1
> +
> +#define PHYREG16			0x3C
> +#define PHYREG16_SSC_CNT_VALUE		0x5f
> +
> +#define PHYREG18			0x44
> +#define PHYREG18_PLL_LOOP		0x32
> +
> +#define PHYREG32			0x7C
> +#define PHYREG32_SSC_MASK		GENMASK(7, 4)
> +#define PHYREG32_SSC_DIR_SHIFT		4
> +#define PHYREG32_SSC_UPWARD		0
> +#define PHYREG32_SSC_DOWNWARD		1
> +#define PHYREG32_SSC_OFFSET_SHIFT	6
> +#define PHYREG32_SSC_OFFSET_500PPM	1
> +
> +#define PHYREG33			0x80
> +#define PHYREG33_PLL_KVCO_MASK		GENMASK(4, 2)
> +#define PHYREG33_PLL_KVCO_SHIFT		2
> +#define PHYREG33_PLL_KVCO_VALUE		2
> +
> +struct rockchip_combphy_priv;
> +
> +struct combphy_reg {
> +	u16 offset;
> +	u16 bitend;
> +	u16 bitstart;
> +	u16 disable;
> +	u16 enable;
> +};
> +
> +struct rockchip_combphy_grfcfg {
> +	struct combphy_reg pcie_mode_set;
> +	struct combphy_reg usb_mode_set;
> +	struct combphy_reg sgmii_mode_set;
> +	struct combphy_reg qsgmii_mode_set;
> +	struct combphy_reg pipe_rxterm_set;
> +	struct combphy_reg pipe_txelec_set;
> +	struct combphy_reg pipe_txcomp_set;
> +	struct combphy_reg pipe_clk_25m;
> +	struct combphy_reg pipe_clk_100m;
> +	struct combphy_reg pipe_phymode_sel;
> +	struct combphy_reg pipe_rate_sel;
> +	struct combphy_reg pipe_rxterm_sel;
> +	struct combphy_reg pipe_txelec_sel;
> +	struct combphy_reg pipe_txcomp_sel;
> +	struct combphy_reg pipe_clk_ext;
> +	struct combphy_reg pipe_sel_usb;
> +	struct combphy_reg pipe_sel_qsgmii;
> +	struct combphy_reg pipe_phy_status;
> +	struct combphy_reg con0_for_pcie;
> +	struct combphy_reg con1_for_pcie;
> +	struct combphy_reg con2_for_pcie;
> +	struct combphy_reg con3_for_pcie;
> +	struct combphy_reg con0_for_sata;
> +	struct combphy_reg con1_for_sata;
> +	struct combphy_reg con2_for_sata;
> +	struct combphy_reg con3_for_sata;
> +	struct combphy_reg pipe_con0_for_sata;
> +	struct combphy_reg pipe_xpcs_phy_ready;
> +};
> +
> +struct rockchip_combphy_cfg {
> +	const struct rockchip_combphy_grfcfg *grfcfg;
> +	int (*combphy_cfg)(struct rockchip_combphy_priv *priv);
> +};
> +
> +struct rockchip_combphy_priv {
> +	u8 mode;
> +	void __iomem *mmio;
> +	int num_clks;
> +	struct clk_bulk_data *clks;
> +	struct device *dev;
> +	struct regmap *pipe_grf;
> +	struct regmap *phy_grf;
> +	struct phy *phy;
> +	struct reset_control *phy_rst;
> +	const struct rockchip_combphy_cfg *cfg;
> +	bool enable_ssc;
> +	bool ext_refclk;
> +	struct clk *refclk;
> +};
> +
> +static void rockchip_combphy_updatel(struct rockchip_combphy_priv *priv,
> +				     int mask, int val, int reg)
> +{
> +	unsigned int temp;
> +
> +	temp = readl(priv->mmio + reg);
> +	temp = (temp & ~(mask)) | val;
> +	writel(temp, priv->mmio + reg);
> +}
> +
> +static int rockchip_combphy_param_write(struct regmap *base,
> +					const struct combphy_reg *reg, bool en)
> +{
> +	u32 val, mask, tmp;
> +
> +	tmp = en ? reg->enable : reg->disable;
> +	mask = GENMASK(reg->bitend, reg->bitstart);
> +	val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT);
> +
> +	return regmap_write(base, reg->offset, val);
> +}
> +
> +static u32 rockchip_combphy_is_ready(struct rockchip_combphy_priv *priv)
> +{
> +	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> +	u32 mask, val;
> +
> +	mask = GENMASK(cfg->pipe_phy_status.bitend,
> +		       cfg->pipe_phy_status.bitstart);
> +
> +	regmap_read(priv->phy_grf, cfg->pipe_phy_status.offset, &val);
> +	val = (val & mask) >> cfg->pipe_phy_status.bitstart;
> +
> +	return val;
> +}
> +

> +static int rockchip_combphy_set_mode(struct rockchip_combphy_priv *priv)

static int rockchip_combphy_set_mode(struct phy *phy, enum phy_mode
mode, int submode)

	/* Use this function to remember the mode, ->power_on() will do the
real setup */

> +{
> +	int ret = 0;
> +
> +	switch (priv->mode) {
> +	case PHY_TYPE_PCIE:
> +	case PHY_TYPE_USB3:
> +	case PHY_TYPE_SATA:
> +	case PHY_TYPE_SGMII:
> +	case PHY_TYPE_QSGMII:
> +		if (priv->cfg->combphy_cfg)
> +			ret = priv->cfg->combphy_cfg(priv);
> +		break;
> +	default:
> +		dev_err(priv->dev, "incompatible PHY type\n");
> +		return -EINVAL;
> +	}
> +
> +	if (ret)
> +		dev_err(priv->dev, "failed to init phy for phy mode %x\n", priv->mode);
> +



> +	return ret;
> +}
> +

> +static int rockchip_combphy_init(struct phy *phy)

poweron

> +{
> +	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
> +	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> +	u32 val;
> +	int ret;
> +
> +	ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks);
> +	if (ret) {
> +		dev_err(priv->dev, "failed to enable clks\n");
> +		return ret;
> +	}
> +

> +	ret = rockchip_combphy_set_mode(priv);
> +	if (ret)
> +		goto err_clk;
> +

Make use of phy frame work for setmode.

> +	ret = reset_control_deassert(priv->phy_rst);
> +	if (ret)
> +		goto err_clk;
> +
> +	if (priv->mode == PHY_TYPE_USB3) {
> +		ret = readx_poll_timeout_atomic(rockchip_combphy_is_ready,
> +						priv, val,
> +						val == cfg->pipe_phy_status.enable,
> +						10, 1000);
> +		if (ret)
> +			dev_warn(priv->dev, "wait phy status ready timeout\n");
> +	}
> +
> +	return 0;
> +
> +err_clk:
> +	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
> +
> +	return ret;
> +}
> +

> +static int rockchip_combphy_exit(struct phy *phy)

poweroff

> +{
> +	struct rockchip_combphy_priv *priv = phy_get_drvdata(phy);
> +
> +	clk_bulk_disable_unprepare(priv->num_clks, priv->clks);
> +	reset_control_assert(priv->phy_rst);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops rochchip_combphy_ops = {
> +	.init = rockchip_combphy_init,
> +	.exit = rockchip_combphy_exit,

Maybe use poweron poweroff

.set_mode = rockchip_combphy_set_mode,

> +	.owner = THIS_MODULE,
> +};
> +
> +static struct phy *rockchip_combphy_xlate(struct device *dev, struct of_phandle_args *args)

use xlate to translate phy structure to lanes.

> +{
> +	struct rockchip_combphy_priv *priv = dev_get_drvdata(dev);
> +
> +	if (args->args_count != 1) {
> +		dev_err(dev, "invalid number of arguments\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (priv->mode != PHY_NONE && priv->mode != args->args[0])
> +		dev_warn(dev, "phy type select %d overwriting type %d\n",
> +			 args->args[0], priv->mode);
> +
> +	priv->mode = args->args[0];




> +
> +	return priv->phy;
> +}
> +
> +static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv)
> +{
> +	int i;
> +
> +	priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks);
> +	if (priv->num_clks < 1)
> +		return -EINVAL;
> +
> +	priv->refclk = NULL;
> +	for (i = 0; i < priv->num_clks; i++) {
> +		if (!strncmp(priv->clks[i].id, "ref", 3)) {
> +			priv->refclk = priv->clks[i].clk;
> +			break;
> +		}
> +	}
> +
> +	if (!priv->refclk) {
> +		dev_err(dev, "no refclk found\n");
> +		return -EINVAL;
> +	}
> +
> +	priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-grf");
> +	if (IS_ERR(priv->pipe_grf)) {
> +		dev_err(dev, "failed to find peri_ctrl pipe-grf regmap\n");
> +		return PTR_ERR(priv->pipe_grf);
> +	}
> +
> +	priv->phy_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pipe-phy-grf");
> +	if (IS_ERR(priv->phy_grf)) {
> +		dev_err(dev, "failed to find peri_ctrl pipe-phy-grf regmap\n");
> +		return PTR_ERR(priv->phy_grf);
> +	}
> +
> +	priv->enable_ssc = device_property_present(dev, "rockchip,enable-ssc");
> +
> +	priv->ext_refclk = device_property_present(dev, "rockchip,ext-refclk");
> +
> +	priv->phy_rst = devm_reset_control_array_get(dev, false, false);
> +	if (IS_ERR(priv->phy_rst))
> +		return dev_err_probe(dev, PTR_ERR(priv->phy_rst), "failed to get phy reset\n");
> +
> +	return 0;
> +}
> +
> +static int rockchip_combphy_probe(struct platform_device *pdev)
> +{
> +	struct phy_provider *phy_provider;
> +	struct device *dev = &pdev->dev;
> +	struct rockchip_combphy_priv *priv;
> +	const struct rockchip_combphy_cfg *phy_cfg;
> +	struct resource *res;
> +	int ret;
> +
> +	phy_cfg = of_device_get_match_data(dev);
> +	if (!phy_cfg) {
> +		dev_err(dev, "no OF match data provided\n");
> +		return -EINVAL;
> +	}
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(priv->mmio)) {
> +		ret = PTR_ERR(priv->mmio);
> +		return ret;
> +	}
> +
> +	priv->dev = dev;
> +	priv->mode = PHY_NONE;
> +	priv->cfg = phy_cfg;
> +
> +	ret = rockchip_combphy_parse_dt(dev, priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = reset_control_assert(priv->phy_rst);
> +	if (ret) {
> +		dev_err(dev, "failed to reset phy\n");
> +		return ret;
> +	}
> +
> +	priv->phy = devm_phy_create(dev, NULL, &rochchip_combphy_ops);
> +	if (IS_ERR(priv->phy)) {
> +		dev_err(dev, "failed to create combphy\n");
> +		return PTR_ERR(priv->phy);
> +	}
> +
> +	dev_set_drvdata(dev, priv);
> +	phy_set_drvdata(priv->phy, priv);
> +
> +	phy_provider = devm_of_phy_provider_register(dev, rockchip_combphy_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv)
struct phy *phy

Use phy structure to pass data.
See version 6.

> +{
> +	const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg;
> +	unsigned long rate;
> +	u32 val;
> +


> +	switch (priv->mode) {

switch phy/lane modes

> +	case PHY_TYPE_PCIE:
PHY_MODE_PCIE

> +		/* Set SSC downward spread spectrum. */
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
> +					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
> +					 PHYREG32);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true);
> +		break;
> +

> +	case PHY_TYPE_USB3:

PHY_MODE_USB_DEVICE_SS

> +		/* Set SSC downward spread spectrum. */
> +		rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK,
> +					 PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT,
> +					 PHYREG32);
> +
> +		/* Enable adaptive CTLE for USB3.0 Rx. */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +
> +		/* Set PLL KVCO fine tuning signals. */
> +		rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +					 PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT,
> +					 PHYREG33);
> +
> +		/* Enable controlling random jitter. */
> +		writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> +		/* Set PLL input clock divider 1/2. */
> +		rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
> +					 PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT,
> +					 PHYREG6);
> +
> +		writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +		writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true);
> +		break;
> +

> +	case PHY_TYPE_SATA:

PHY_MODE_SATA

> +		/* Enable adaptive CTLE for SATA Rx. */
> +		val = readl(priv->mmio + PHYREG15);
> +		val |= PHYREG15_CTLE_EN;
> +		writel(val, priv->mmio + PHYREG15);
> +		/*
> +		 * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA.
> +		 * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm)
> +		 */
> +		val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT;
> +		val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT;
> +		writel(val, priv->mmio + PHYREG7);
> +
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_sata, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_sata, true);

> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_con0_for_sata, true);

3xSATA -> 3xprobe -> 3x: call rk3568_combphy_cfg -> 3xaccess pipe_grf

Pipe_grf is not reset, so previous (modules,probe,u-boot) state is
unknown. This driver is just assuming all bit are right.
Fix writing to common grf. Make it idiot proof!


> +		break;
> +


Use sub nodes.
Use phy structure to pass INTERFACE_MODE with arg[]

	case PHY_MODE_ETHERNET:
		switch (lane->submode) {
		case PHY_INTERFACE_MODE_SGMII

> +	case PHY_TYPE_SGMII:

> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->sgmii_mode_set, true);
> +		break;
> +

		case PHY_INTERFACE_MODE_QSGMII:
> +	case PHY_TYPE_QSGMII:


> +		rockchip_combphy_param_write(priv->pipe_grf, &cfg->pipe_xpcs_phy_ready, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_phymode_sel, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_rate_sel, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_qsgmii, true);
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->qsgmii_mode_set, true);
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "incompatible PHY type\n");
> +		return -EINVAL;
> +	}
> +
> +	rate = clk_get_rate(priv->refclk);
> +
> +	switch (rate) {
> +	case REF_CLOCK_24MHz:
> +		if (priv->mode == PHY_TYPE_USB3 || priv->mode == PHY_TYPE_SATA) {
> +			/* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */
> +			val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT;
> +			rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK,
> +						 val, PHYREG15);
> +
> +			writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16);
> +		}
> +		break;
> +
> +	case REF_CLOCK_25MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_25m, true);
> +		break;
> +
> +	case REF_CLOCK_100MHz:
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true);
> +		if (priv->mode == PHY_TYPE_PCIE) {
> +			/* PLL KVCO  fine tuning. */
> +			val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT;
> +			rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK,
> +						 val, PHYREG33);
> +
> +			/* Enable controlling random jitter. */
> +			writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12);
> +
> +			val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT;
> +			rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK,
> +						 val, PHYREG6);
> +
> +			writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18);
> +			writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11);
> +		} else if (priv->mode == PHY_TYPE_SATA) {
> +			/* downward spread spectrum +500ppm */
> +			val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT;
> +			val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT;
> +			rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32);
> +		}
> +		break;
> +
> +	default:
> +		dev_err(priv->dev, "unsupported rate: %lu\n", rate);
> +		return -EINVAL;
> +	}
> +
> +	if (priv->ext_refclk) {
> +		rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true);
> +		if (priv->mode == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) {
> +			val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT;
> +			val |= PHYREG13_CKRCV_AMP0;
> +			rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13);
> +
> +			val = readl(priv->mmio + PHYREG14);
> +			val |= PHYREG14_CKRCV_AMP1;
> +			writel(val, priv->mmio + PHYREG14);
> +		}
> +	}
> +
> +	if (priv->enable_ssc) {
> +		val = readl(priv->mmio + PHYREG8);
> +		val |= PHYREG8_SSC_EN;
> +		writel(val, priv->mmio + PHYREG8);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = {
> +	/* pipe-phy-grf */
> +	.pcie_mode_set		= { 0x0000, 5, 0, 0x00, 0x11 },
> +	.usb_mode_set		= { 0x0000, 5, 0, 0x00, 0x04 },
> +	.sgmii_mode_set		= { 0x0000, 5, 0, 0x00, 0x01 },
> +	.qsgmii_mode_set	= { 0x0000, 5, 0, 0x00, 0x21 },
> +	.pipe_rxterm_set	= { 0x0000, 12, 12, 0x00, 0x01 },
> +	.pipe_txelec_set	= { 0x0004, 1, 1, 0x00, 0x01 },
> +	.pipe_txcomp_set	= { 0x0004, 4, 4, 0x00, 0x01 },
> +	.pipe_clk_25m		= { 0x0004, 14, 13, 0x00, 0x01 },
> +	.pipe_clk_100m		= { 0x0004, 14, 13, 0x00, 0x02 },
> +	.pipe_phymode_sel	= { 0x0008, 1, 1, 0x00, 0x01 },
> +	.pipe_rate_sel		= { 0x0008, 2, 2, 0x00, 0x01 },
> +	.pipe_rxterm_sel	= { 0x0008, 8, 8, 0x00, 0x01 },
> +	.pipe_txelec_sel	= { 0x0008, 12, 12, 0x00, 0x01 },
> +	.pipe_txcomp_sel	= { 0x0008, 15, 15, 0x00, 0x01 },
> +	.pipe_clk_ext		= { 0x000c, 9, 8, 0x02, 0x01 },
> +	.pipe_sel_usb		= { 0x000c, 14, 13, 0x00, 0x01 },
> +	.pipe_sel_qsgmii	= { 0x000c, 15, 13, 0x00, 0x07 },
> +	.pipe_phy_status	= { 0x0034, 6, 6, 0x01, 0x00 },
> +	.con0_for_pcie		= { 0x0000, 15, 0, 0x00, 0x1000 },
> +	.con1_for_pcie		= { 0x0004, 15, 0, 0x00, 0x0000 },
> +	.con2_for_pcie		= { 0x0008, 15, 0, 0x00, 0x0101 },
> +	.con3_for_pcie		= { 0x000c, 15, 0, 0x00, 0x0200 },
> +	.con0_for_sata		= { 0x0000, 15, 0, 0x00, 0x0119 },
> +	.con1_for_sata		= { 0x0004, 15, 0, 0x00, 0x0040 },
> +	.con2_for_sata		= { 0x0008, 15, 0, 0x00, 0x80c3 },
> +	.con3_for_sata		= { 0x000c, 15, 0, 0x00, 0x4407 },
> +	/* pipe-grf */
> +	.pipe_con0_for_sata	= { 0x0000, 15, 0, 0x00, 0x2220 },
> +	.pipe_xpcs_phy_ready	= { 0x0040, 2, 2, 0x00, 0x01 },
> +};
> +

rk3568_multiphy_modes structure

> +static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = {
> +	.grfcfg		= &rk3568_combphy_grfcfgs,
> +	.combphy_cfg	= rk3568_combphy_cfg,
> +};
> +
> +static const struct of_device_id rockchip_combphy_of_match[] = {

rk3566
rk3568
rk3588

> +	{
> +		.compatible = "rockchip,rk3568-naneng-combphy",
> +		.data = &rk3568_combphy_cfgs,
> +	},
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, rockchip_combphy_of_match);
> +
> +static struct platform_driver rockchip_combphy_driver = {
> +	.probe	= rockchip_combphy_probe,
> +	.driver = {
> +		.name = "rockchip-naneng-combphy",
> +		.of_match_table = rockchip_combphy_of_match,
> +	},
> +};
> +module_platform_driver(rockchip_combphy_driver);
> +
> +MODULE_DESCRIPTION("Rockchip NANENG COMBPHY driver");
> +MODULE_LICENSE("GPL v2");
> 


From mathieu.poirier at linaro.org  Mon Jan  3 10:28:48 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 3 Jan 2022 11:28:48 -0700
Subject: [RFC V3 PATCH] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <20211221120437.4781-1-jkchen@linux.alibaba.com>
References: <20211221120437.4781-1-jkchen@linux.alibaba.com>
Message-ID: <20220103182848.GA398730@p14s>

Good day Jay,

For your next iteration, please remove the "RFC" from the patch title, we are
well pass that now.

On Tue, Dec 21, 2021 at 08:04:37PM +0800, Jay Chen wrote:
> Currently, there are 130 etr and etf on our machine,
> but the current coresight tmc driver uses misc_register
> to register the device, which leads to the error that
> the device number is not enough.
> 
> coresight-tmc: probe of xxxxx failed with error -16
> 
> This patch changes the device registration method
> to cdev's dynamic registration method to solve the
> problem of insufficient device numbers.

This is much better.

> 
> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> ---
>  .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
>  drivers/hwtracing/coresight/coresight-tmc.h   | 10 +-
>  2 files changed, 83 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index d0276af82494..0d51071e9f88 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -31,6 +31,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>  DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>  
> +static DEFINE_IDA(tmc_ida);
> +static dev_t tmc_major;
> +static struct class *tmc_class;
> +
> +#define TMC_DEV_MAX	(MINORMASK + 1)
> +
>  void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>  {
>  	struct coresight_device *csdev = drvdata->csdev;
> @@ -147,7 +153,7 @@ static int tmc_open(struct inode *inode, struct file *file)
>  {
>  	int ret;
>  	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>  
>  	ret = tmc_read_prepare(drvdata);
>  	if (ret)
> @@ -179,7 +185,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>  	char *bufp;
>  	ssize_t actual;
>  	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>  	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>  	if (actual <= 0)
>  		return 0;
> @@ -200,7 +206,7 @@ static int tmc_release(struct inode *inode, struct file *file)
>  {
>  	int ret;
>  	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>  
>  	ret = tmc_read_unprepare(drvdata);
>  	if (ret)
> @@ -451,6 +457,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>  {
>  	int ret = 0;
>  	u32 devid;
> +	dev_t devt;
>  	void __iomem *base;
>  	struct device *dev = &adev->dev;
>  	struct coresight_platform_data *pdata = NULL;
> @@ -546,14 +553,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>  		goto out;
>  	}
>  
> -	drvdata->miscdev.name = desc.name;
> -	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> -	drvdata->miscdev.fops = &tmc_fops;
> -	ret = misc_register(&drvdata->miscdev);
> +	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> +	if (ret < 0)
> +		goto err_coresight_unregister;
> +
> +	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> +	drvdata->cdev.cdev.owner = THIS_MODULE;
> +	devt = MKDEV(MAJOR(tmc_major), ret);
> +	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>  	if (ret)
> -		coresight_unregister(drvdata->csdev);
> -	else
> +		goto err_free_tmc_ida;
> +
> +	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> +	if (IS_ERR(drvdata->cdev.dev)) {
> +		ret = PTR_ERR(drvdata->cdev.dev);
> +		goto err_delete_cdev;
> +	} else
>  		pm_runtime_put(&adev->dev);
> +
> +	return 0;
> +
> +err_delete_cdev:
> +	cdev_del(&drvdata->cdev.cdev);
> +err_free_tmc_ida:
> +	ida_simple_remove(&tmc_ida, MINOR(devt));
> +err_coresight_unregister:
> +	coresight_unregister(drvdata->csdev);
>  out:
>  	return ret;
>  }
> @@ -583,13 +608,11 @@ static void tmc_shutdown(struct amba_device *adev)
>  static void tmc_remove(struct amba_device *adev)
>  {
>  	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +	struct device *dev = drvdata->cdev.dev;
>  
> -	/*
> -	 * Since misc_open() holds a refcount on the f_ops, which is
> -	 * etb fops in this case, device is there until last file
> -	 * handler to this device is closed.
> -	 */
> -	misc_deregister(&drvdata->miscdev);
> +	ida_simple_remove(&tmc_ida, dev->devt);

	ida_simple_remove(&tmc_ida, MINOR(dev->devt));

> +	device_destroy(tmc_class, dev->devt);
> +	cdev_del(&drvdata->cdev.cdev);
>  	coresight_unregister(drvdata->csdev);
>  }
>  
> @@ -618,7 +641,43 @@ static struct amba_driver tmc_driver = {
>  	.id_table	= tmc_ids,
>  };
>  
> -module_amba_driver(tmc_driver);
> +static int __init tmc_init(void)
> +{
> +	int ret;
> +
> +	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> +	if (ret < 0) {
> +		pr_err("tmc: failed to allocate char dev region\n");
> +		return ret;
> +	}
> +
> +	tmc_class = class_create(THIS_MODULE, "tmc");
> +	if (IS_ERR(tmc_class)) {
> +		pr_err("tmc: failed to create class\n");
> +		ret = PTR_ERR(tmc_class);
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +		return ret;

You can simply return PTR_ERR(tmc_class)...

> +	}
> +
> +	ret = amba_driver_register(&tmc_driver);
> +	if (ret) {
> +		pr_err("tmc: error registering amba driver\n");
> +		class_destroy(tmc_class);
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +	}
> +
> +	return ret;
> +}
> +
> +static void __exit tmc_exit(void)
> +{
> +	amba_driver_unregister(&tmc_driver);
> +	class_destroy(tmc_class);
> +	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +}
> +
> +module_init(tmc_init);
> +module_exit(tmc_exit);
>  
>  MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>  MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6bec20a392b3..b65ac363f9e4 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -7,6 +7,7 @@
>  #ifndef _CORESIGHT_TMC_H
>  #define _CORESIGHT_TMC_H
>  
> +#include <linux/cdev.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/idr.h>
>  #include <linux/miscdevice.h>

miscdevice.h can likely be removed in both .c and .h files.

Thanks,
Mathieu

> @@ -163,11 +164,16 @@ struct etr_buf {
>  	void				*private;
>  };
>  
> +struct tmc_cdev {
> +	struct cdev cdev;
> +	struct device *dev;
> +};
> +
>  /**
>   * struct tmc_drvdata - specifics associated to an TMC component
>   * @base:	memory mapped base address for this component.
>   * @csdev:	component vitals needed by the framework.
> - * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
> + * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
>   * @spinlock:	only one at a time pls.
>   * @pid:	Process ID of the process being monitored by the session
>   *		that is using this component.
> @@ -191,7 +197,7 @@ struct etr_buf {
>  struct tmc_drvdata {
>  	void __iomem		*base;
>  	struct coresight_device	*csdev;
> -	struct miscdevice	miscdev;
> +	struct tmc_cdev		cdev;
>  	spinlock_t		spinlock;
>  	pid_t			pid;
>  	bool			reading;
> -- 
> 2.27.0
> 


From toke at redhat.com  Mon Jan  3 10:33:02 2022
From: toke at redhat.com (Toke =?utf-8?Q?H=C3=B8iland-J=C3=B8rgensen?=)
Date: Mon, 03 Jan 2022 19:33:02 +0100
Subject: Adding arch_prepare_bpf_trampoline support for aarch64?
In-Reply-To: <CAADnVQJ9W99v-_P_zE+fPfnR45=jry7RxPNYRL1enYcKF547Hg@mail.gmail.com>
References: <CAFbkdV3Bj=gM0dd6LBaXyc-V79Y0Ewy7xKF5TQT_6H0sCpxE6A@mail.gmail.com>
 <CAADnVQJ9W99v-_P_zE+fPfnR45=jry7RxPNYRL1enYcKF547Hg@mail.gmail.com>
Message-ID: <87ee5od601.fsf@toke.dk>

Alexei Starovoitov <alexei.starovoitov at gmail.com> writes:

> On Wed, Dec 29, 2021 at 2:12 AM Huichun Feng <foxhoundsk.tw at gmail.com> wrote:
>>
>> Hi Jean and the list,
>>
>> Attaching BPF to fentry/fexit hooks requires
>> arch_prepare_bpf_trampoline(), which
>> AFAIK has only been implemented on x86. Is there any related ongoing patch for
>> aarch64?
>>
>> I've found a discussion [0] on this, and seems there has no further discussion.
>
> No patches have been posted since then.
> If you have cycles to pick up this work it would be awesome!

+1, would love to see this! :)

-Toke



From lkp at intel.com  Mon Jan  3 10:39:22 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 4 Jan 2022 02:39:22 +0800
Subject: [arm-platforms:kvm-arm64/pmu-bl 4/5]
 arch/arm64/kvm/pmu-emul.c:895:24: error: use of undeclared identifier 'kvm'
Message-ID: <202201040228.xRreWFaE-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/pmu-bl
head:   877a6850e9bc0d29fa60dbedf345300c0f3396e4
commit: 0071239cd4ab9fc0b5cb9b911b36adee31598f3f [4/5] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU attribute
config: arm64-randconfig-r013-20220103 (https://download.01.org/0day-ci/archive/20220104/202201040228.xRreWFaE-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 104a827ea6de0cbe0f5faef4407552ede31d165c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=0071239cd4ab9fc0b5cb9b911b36adee31598f3f
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms kvm-arm64/pmu-bl
        git checkout 0071239cd4ab9fc0b5cb9b911b36adee31598f3f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kvm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> arch/arm64/kvm/pmu-emul.c:895:24: error: use of undeclared identifier 'kvm'
           if (irqchip_in_kernel(kvm)) {
                                 ^
   arch/arm64/kvm/pmu-emul.c:903:25: error: use of undeclared identifier 'kvm'
                   if (!vgic_initialized(kvm))
                                         ^
>> arch/arm64/kvm/pmu-emul.c:906:8: error: no member named 'pmu' in 'struct kvm_arch'
                   if (!kvm_arm_pmu_irq_initialized(vcpu->kvm))
                        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/kvm/arm_pmu.h:45:51: note: expanded from macro 'kvm_arm_pmu_irq_initialized'
   #define kvm_arm_pmu_irq_initialized(v)  ((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
                                            ~~~~~~~~~ ^
   3 errors generated.


vim +/kvm +895 arch/arm64/kvm/pmu-emul.c

   892	
   893	static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
   894	{
 > 895		if (irqchip_in_kernel(kvm)) {
   896			int ret;
   897	
   898			/*
   899			 * If using the PMU with an in-kernel virtual GIC
   900			 * implementation, we require the GIC to be already
   901			 * initialized when initializing the PMU.
   902			 */
   903			if (!vgic_initialized(kvm))
   904				return -ENODEV;
   905	
 > 906			if (!kvm_arm_pmu_irq_initialized(vcpu->kvm))
   907				return -ENXIO;
   908	
   909			ret = kvm_vgic_set_owner(vcpu, vcpu->arch.pmu.irq_num,
   910						 &vcpu->arch.pmu);
   911			if (ret)
   912				return ret;
   913		}
   914	
   915		init_irq_work(&vcpu->arch.pmu.overflow_work,
   916			      kvm_pmu_perf_overflow_notify_vcpu);
   917	
   918		atomic_set(&vcpu->arch.pmu.created, 1);
   919	
   920		return 0;
   921	}
   922	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From semen.protsenko at linaro.org  Mon Jan  3 10:43:02 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 20:43:02 +0200
Subject: [PATCH 02/24] pinctrl: samsung: accept GPIO bank nodes with a
 suffix
In-Reply-To: <20211231161930.256733-3-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-3-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4kVjswvcx7PjkBq_cPrmoi1_yJw9qGOO2tcRCDm27zKmA@mail.gmail.com>

On Fri, 31 Dec 2021 at 18:20, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Existing dt-bindings expected that each GPIO/pin bank within pin
> controller has its own node with name matching the bank (e.g. gpa0,
> gpx2) and "gpio-controller" property.  The node name is then used for
> matching between driver data and DTS.
>
> Newly introduced dtschema expects to have nodes ending with "-gpio-bank"
> suffix, so rewrite bank-devicetree matching to look for old and new
> style of naming.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  drivers/pinctrl/samsung/pinctrl-samsung.c | 57 ++++++++++++++++++-----
>  1 file changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index f2864a7869b3..561853df8ef7 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1011,13 +1011,56 @@ static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
>                 of_node_put(bank->of_node);
>  }
>
> +/*
> + * Iterate over all driver pin banks to find one matching the name of node,
> + * skipping optional "-gpio" node suffix. When found, assign node to the bank.
> + */
> +static void samsung_banks_of_node_get(struct device *dev,
> +                                     struct samsung_pinctrl_drv_data *d,
> +                                     struct device_node *node)
> +{
> +       const char *suffix = "-gpio-bank";
> +       struct samsung_pin_bank *bank;
> +       struct device_node *child;
> +       /* Pin bank names are up to 4 characters */
> +       char node_name[20];
> +       unsigned int i;
> +       size_t len;
> +
> +       bank = d->pin_banks;
> +       for (i = 0; i < d->nr_banks; ++i, ++bank) {
> +               strscpy(node_name, bank->name, sizeof(node_name));
> +               len = strlcat(node_name, suffix, sizeof(node_name));
> +               if (len == sizeof(sizeof(node_name))) {

Double sizeof is probably wrong?

> +                       dev_err(dev, "Too long pin bank name '%s', ignoring\n",
> +                               bank->name);
> +                       continue;
> +               }
> +
> +               for_each_child_of_node(node, child) {
> +                       if (!of_find_property(child, "gpio-controller", NULL))
> +                               continue;
> +                       if (of_node_name_eq(child, node_name))
> +                               break;
> +                       else if (of_node_name_eq(child, bank->name))
> +                               break;
> +               }
> +
> +               if (child)
> +                       bank->of_node = child;
> +               else
> +                       dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
> +                                bank->name);
> +               /* child reference dropped in samsung_drop_banks_of_node() */
> +       }
> +}
> +
>  /* retrieve the soc specific data */
>  static const struct samsung_pin_ctrl *
>  samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
>                              struct platform_device *pdev)
>  {
>         struct device_node *node = pdev->dev.of_node;
> -       struct device_node *np;
>         const struct samsung_pin_bank_data *bdata;
>         const struct samsung_pin_ctrl *ctrl;
>         struct samsung_pin_bank *bank;
> @@ -1081,17 +1124,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
>          */
>         d->virt_base = virt_base[0];
>
> -       for_each_child_of_node(node, np) {
> -               if (!of_find_property(np, "gpio-controller", NULL))
> -                       continue;
> -               bank = d->pin_banks;
> -               for (i = 0; i < d->nr_banks; ++i, ++bank) {
> -                       if (of_node_name_eq(np, bank->name)) {
> -                               bank->of_node = np;
> -                               break;
> -                       }
> -               }
> -       }
> +       samsung_banks_of_node_get(&pdev->dev, d, node);
>
>         d->pin_base = pin_base;
>         pin_base += d->nr_pins;
> --
> 2.32.0
>


From john.stultz at linaro.org  Mon Jan  3 10:57:30 2022
From: john.stultz at linaro.org (John Stultz)
Date: Mon, 3 Jan 2022 10:57:30 -0800
Subject: [PATCH v2] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <20211227095102.6054-1-guangming.cao@mediatek.com>
References: <20211217094104.24977-1-guangming.cao@mediatek.com>
 <20211227095102.6054-1-guangming.cao@mediatek.com>
Message-ID: <CALAqxLVA4jUk-2o28RZobrPDUnuXfV1xN77Pt8Pu1o27V3aUQQ@mail.gmail.com>

On Mon, Dec 27, 2021 at 1:52 AM <guangming.cao at mediatek.com> wrote:
>
> From: Guangming <Guangming.Cao at mediatek.com>
>

Thanks for submitting this!

> Add a size check for allcation since the allocation size is

nit: "allocation" above.

> always less than the total DRAM size.

In general, it might be good to add more context to the commit message
to better answer *why* this change is needed rather than what the
change is doing.  ie: What negative thing happens without this change?
And so how does this change avoid or improve things?


> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
> ---
> v2: 1. update size limitation as total_dram page size.
>     2. update commit message
> ---
>  drivers/dma-buf/dma-heap.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
> index 56bf5ad01ad5..e39d2be98d69 100644
> --- a/drivers/dma-buf/dma-heap.c
> +++ b/drivers/dma-buf/dma-heap.c
> @@ -55,6 +55,8 @@ static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
>         struct dma_buf *dmabuf;
>         int fd;
>
> +       if (len / PAGE_SIZE > totalram_pages())
> +               return -EINVAL;

This seems sane. I know ION used to have some 1/2 of memory cap to
avoid unnecessary memory pressure on crazy allocations.

Could you send again with an improved commit message?

thanks
-john


From maz at kernel.org  Mon Jan  3 11:22:06 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 03 Jan 2022 19:22:06 +0000
Subject: [arm-platforms:kvm-arm64/pmu-bl 4/5]
 arch/arm64/kvm/pmu-emul.c:895:24: error: use of undeclared identifier 'kvm'
In-Reply-To: <202201040228.xRreWFaE-lkp@intel.com>
References: <202201040228.xRreWFaE-lkp@intel.com>
Message-ID: <1982120cc9c7e58e5a8b8c1f41e6068f@kernel.org>

On 2022-01-03 18:39, kernel test robot wrote:
> tree:
> https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
> kvm-arm64/pmu-bl
> head:   877a6850e9bc0d29fa60dbedf345300c0f3396e4
> commit: 0071239cd4ab9fc0b5cb9b911b36adee31598f3f [4/5] KVM: arm64: Add
> KVM_ARM_VCPU_PMU_V3_SET_PMU attribute
> config: arm64-randconfig-r013-20220103
> (https://download.01.org/0day-ci/archive/20220104/202201040228.xRreWFaE-lkp at intel.com/config)
> compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project
> 104a827ea6de0cbe0f5faef4407552ede31d165c)
> reproduce (this is a W=1 build):
>         wget
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
> -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # install arm64 cross compiling tool for clang build
>         # apt-get install binutils-aarch64-linux-gnu
>         #
> https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=0071239cd4ab9fc0b5cb9b911b36adee31598f3f
>         git remote add arm-platforms
> https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
>         git fetch --no-tags arm-platforms kvm-arm64/pmu-bl
>         git checkout 0071239cd4ab9fc0b5cb9b911b36adee31598f3f
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1
> O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/kvm/
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>>> arch/arm64/kvm/pmu-emul.c:895:24: error: use of undeclared identifier 
>>> 'kvm'
>            if (irqchip_in_kernel(kvm)) {

Fixed branch pushed out, thanks for the heads up.

         M.
-- 
Jazz is not dead. It just smells funny...


From abel.vesa at nxp.com  Mon Jan  3 11:28:58 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Mon,  3 Jan 2022 21:28:58 +0200
Subject: [PATCH v3 1/3] dt-bindings: interconnect: imx8m-noc: Add fsl,
 icc-id property
Message-ID: <20220103192900.946521-1-abel.vesa@nxp.com>

Add documentation for fsl,icc-id property.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 .../devicetree/bindings/interconnect/fsl,imx8m-noc.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
index b8204ed22dd5..4924743e8cb1 100644
--- a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
+++ b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
@@ -47,6 +47,11 @@ properties:
   operating-points-v2: true
   opp-table: true
 
+  fsl,icc-id:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description:
+      unique ID used for linking i.MX bus or ddrc node to inteconnect
+
   fsl,ddrc:
     $ref: "/schemas/types.yaml#/definitions/phandle"
     description:
-- 
2.31.1



From abel.vesa at nxp.com  Mon Jan  3 11:28:59 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Mon,  3 Jan 2022 21:28:59 +0200
Subject: [PATCH v3 2/3] interconnect: imx: Switch from imx_icc_node_adj_desc
 to fsl, icc-id node assignment
In-Reply-To: <20220103192900.946521-1-abel.vesa@nxp.com>
References: <20220103192900.946521-1-abel.vesa@nxp.com>
Message-ID: <20220103192900.946521-2-abel.vesa@nxp.com>

In order to be able to have more than one NoCs in the interconnect net
we need to decouple the NoC from the dram. So instead of using the
imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
each NoC (or pl301) to the icc node (based on the id) to it.
Along with all the NoC and pl301 nodes in the dts we will have a
interconnect dedicated node. This node will be the actual device of the
icc provider.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v2:
 * switch to use only peak_bw rather than choosing max between peak_bw
   and avg_bw. This renders the imx_icc_aggregate from v2 unnecessary.

 drivers/interconnect/imx/imx.c | 70 +++++++++++++++-------------------
 1 file changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index c770951a909c..d5b36c478911 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -34,8 +34,8 @@ static int imx_icc_node_set(struct icc_node *node)
 	if (!node_data->qos_dev)
 		return 0;
 
-	freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
-	do_div(freq, node_data->desc->adj->bw_div);
+	freq = node->peak_bw;
+
 	dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq %llukHz\n",
 		node->name, dev_name(node_data->qos_dev),
 		node->avg_bw, node->peak_bw, freq);
@@ -79,41 +79,35 @@ static int imx_icc_node_init_qos(struct icc_provider *provider,
 				 struct icc_node *node)
 {
 	struct imx_icc_node *node_data = node->data;
-	const struct imx_icc_node_adj_desc *adj = node_data->desc->adj;
 	struct device *dev = provider->dev;
-	struct device_node *dn = NULL;
 	struct platform_device *pdev;
+	struct device_node *np = NULL, *dn = NULL;
+	int idx;
 
-	if (adj->main_noc) {
-		node_data->qos_dev = dev;
-		dev_dbg(dev, "icc node %s[%d] is main noc itself\n",
-			node->name, node->id);
-	} else {
-		dn = of_parse_phandle(dev->of_node, adj->phandle_name, 0);
-		if (!dn) {
-			dev_warn(dev, "Failed to parse %s\n",
-				 adj->phandle_name);
-			return -ENODEV;
-		}
-		/* Allow scaling to be disabled on a per-node basis */
-		if (!of_device_is_available(dn)) {
-			dev_warn(dev, "Missing property %s, skip scaling %s\n",
-				 adj->phandle_name, node->name);
-			of_node_put(dn);
-			return 0;
-		}
+	for_each_node_with_property(np, "fsl,icc-id") {
+		of_property_read_u32(np, "fsl,icc-id", &idx);
+		if (idx == node_data->desc->id)
+			dn = np;
+	}
 
-		pdev = of_find_device_by_node(dn);
-		of_node_put(dn);
-		if (!pdev) {
-			dev_warn(dev, "node %s[%d] missing device for %pOF\n",
-				 node->name, node->id, dn);
-			return -EPROBE_DEFER;
-		}
-		node_data->qos_dev = &pdev->dev;
-		dev_dbg(dev, "node %s[%d] has device node %pOF\n",
-			node->name, node->id, dn);
+	if (!dn)
+		return 0;
+
+	if (!of_device_is_available(dn)) {
+		dev_warn(dev, "%pOF is disabled\n", dn);
+		return 0;
+	}
+
+	pdev = of_find_device_by_node(dn);
+	of_node_put(dn);
+	if (!pdev) {
+		dev_warn(dev, "node %s[%d] missing device for %pOF\n",
+			 node->name, node->id, dn);
+		return -EPROBE_DEFER;
 	}
+	node_data->qos_dev = &pdev->dev;
+	dev_dbg(dev, "node %s[%d] has device node %pOF\n", node->name,
+							node->id, dn);
 
 	return dev_pm_qos_add_request(node_data->qos_dev,
 				      &node_data->qos_req,
@@ -151,12 +145,10 @@ static struct icc_node *imx_icc_node_add(struct icc_provider *provider,
 	node_data->desc = node_desc;
 	icc_node_add(node, provider);
 
-	if (node_desc->adj) {
-		ret = imx_icc_node_init_qos(provider, node);
-		if (ret < 0) {
-			imx_icc_node_destroy(node);
-			return ERR_PTR(ret);
-		}
+	ret = imx_icc_node_init_qos(provider, node);
+	if (ret < 0) {
+		imx_icc_node_destroy(node);
+		return ERR_PTR(ret);
 	}
 
 	return node;
@@ -244,7 +236,7 @@ int imx_icc_register(struct platform_device *pdev,
 	provider->aggregate = icc_std_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
-	provider->dev = dev->parent;
+	provider->dev = dev;
 	platform_set_drvdata(pdev, provider);
 
 	ret = icc_provider_add(provider);
-- 
2.31.1



From abel.vesa at nxp.com  Mon Jan  3 11:29:00 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Mon,  3 Jan 2022 21:29:00 +0200
Subject: [PATCH v3 3/3] interconnect: imx: Remove the imx_icc_node_adj_desc
In-Reply-To: <20220103192900.946521-1-abel.vesa@nxp.com>
References: <20220103192900.946521-1-abel.vesa@nxp.com>
Message-ID: <20220103192900.946521-3-abel.vesa@nxp.com>

Now that the imx generic interconnect doesn't use the
imx_icc_node_adj_desc, we remove it from all the i.MX8M
platform drivers.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/interconnect/imx/imx.h    | 19 ++++-------------
 drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
 drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
 drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
 4 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
index 75da51076c68..5c9f5138f6aa 100644
--- a/drivers/interconnect/imx/imx.h
+++ b/drivers/interconnect/imx/imx.h
@@ -14,15 +14,6 @@
 
 #define IMX_ICC_MAX_LINKS	4
 
-/*
- * struct imx_icc_node_adj - Describe a dynamic adjustable node
- */
-struct imx_icc_node_adj_desc {
-	unsigned int bw_mul, bw_div;
-	const char *phandle_name;
-	bool main_noc;
-};
-
 /*
  * struct imx_icc_node - Describe an interconnect node
  * @name: name of the node
@@ -35,23 +26,21 @@ struct imx_icc_node_desc {
 	u16 id;
 	u16 links[IMX_ICC_MAX_LINKS];
 	u16 num_links;
-	const struct imx_icc_node_adj_desc *adj;
 };
 
-#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
+#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
 	{								\
 		.id = _id,						\
 		.name = _name,						\
-		.adj = _adj,						\
 		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
 		.links = { __VA_ARGS__ },				\
 	}
 
 #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
+	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
 
-#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
+#define DEFINE_BUS_SLAVE(_name, _id)					\
+	DEFINE_BUS_INTERCONNECT(_name, _id)
 
 int imx_icc_register(struct platform_device *pdev,
 		     struct imx_icc_node_desc *nodes,
diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
index 1083490bb391..0c16110bef9d 100644
--- a/drivers/interconnect/imx/imx8mm.c
+++ b/drivers/interconnect/imx/imx8mm.c
@@ -14,18 +14,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
 			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
 	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
 
 	/* HSIO */
 	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
-	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
 
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
@@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
 			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
index ad97e55fd4e5..f03f8db00917 100644
--- a/drivers/interconnect/imx/imx8mn.c
+++ b/drivers/interconnect/imx/imx8mn.c
@@ -11,18 +11,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
 			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
 
 	/* USB goes straight to NOC */
 	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
@@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
@@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN,
 			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
index d7768d3c6d8a..b8c36d668946 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -12,18 +12,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
-			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
 
 	/* DISPMIX (only for DCSS) */
 	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
-	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
 
 	/* USBMIX */
 	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
 	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
-	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
 
 	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
 	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
-	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
 
 	/* AUDIO */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
 
 	/* ENET */
 	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
 
 	/* OTHER */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
@@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
 			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
 };
 
-- 
2.31.1



From abel.vesa at nxp.com  Mon Jan  3 11:46:32 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Mon, 3 Jan 2022 21:46:32 +0200
Subject: [PATCH 1/3] dt-bindings: fsl: scu: Add i.MX8QM rtc binding
In-Reply-To: <YczU26vFxiO0wWKa@piout.net>
References: <1640088948-3690-1-git-send-email-abel.vesa@nxp.com>
 <1640088948-3690-2-git-send-email-abel.vesa@nxp.com>
 <YczU26vFxiO0wWKa@piout.net>
Message-ID: <YdNSmA2wXINLXvFx@abelvesa>

On 21-12-29 22:36:27, Alexandre Belloni wrote:
> On 21/12/2021 14:15:46+0200, Abel Vesa wrote:
> > Add i.MX8QM rtc compatible to the SCU bindings documentation.
> > 
> > Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> > ---
> >  Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > index f1470d562156..4633be2182dd 100644
> > --- a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > @@ -134,7 +134,9 @@ RTC bindings based on SCU Message Protocol
> >  ------------------------------------------------------------
> >  
> >  Required properties:
> > -- compatible: should be "fsl,imx8qxp-sc-rtc";
> > +- compatible:		Should be one of:
> > +			"fsl,imx8qm-sc-rtc",
> > +			"fsl,imx8qxp-sc-rtc".
> 
> Are the imx8qm and imx8qxp SCU actually different? I would hope you
> won't had a third messaging protocol for the RTC...
> 

Sorry, my bad.

No, there is no difference between imx8mq and imx8qxp.

I'll replace the compatible in the imx8qm.dtsi with fsl,imx8qxp-sc-rtc,
drop this patch and the one that adds the compatible to the rtc driver.

> 
> -- 
> Alexandre Belloni, co-owner and COO, Bootlin
> Embedded Linux and Kernel engineering
> https://bootlin.com/


From semen.protsenko at linaro.org  Mon Jan  3 13:09:51 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 23:09:51 +0200
Subject: [RFT][PATCH 3/3] arm64: dts: exynos: drop incorrectly placed
 wakeup interrupts in Exynos850
In-Reply-To: <20211230195325.328220-3-krzysztof.kozlowski@canonical.com>
References: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
 <20211230195325.328220-3-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4mDWg1xAGEALNVN1vs8jb3rzH2VqEBfacTkM_gNxeuhRg@mail.gmail.com>

On Thu, 30 Dec 2021 at 21:53, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The pin controller device node is expected to have one (optional)
> interrupt.  Its pin banks capable of external interrupts, should define
> interrupts for each pin, unless a muxed interrupt is used.
>
> Exynos850 defined the second part - interrupt for each pin in wake-up
> pin controller - but also added these interrupts in main device node,
> which is not correct.
>
> Fixes: e3493220fd3e ("arm64: dts: exynos: Add initial Exynos850 SoC support")
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

Despite some errors brought by this change:

    samsung-pinctrl 11850000.pinctrl: irq number not available
    samsung-pinctrl 11c30000.pinctrl: irq number not available

the interrupts seem to be functional still. Tested on E850-96 board,
by pressing buttons connected to gpa0..gpa1, and checking
/proc/interrupts info. I guess it's ok to merge this one as is, and
then work further to fix the driver (or dts?) accordingly.

Also, I submitted related patch ("arm64: dts: exynos: Add missing gpm6
and gpm7 nodes to Exynos850"), please take a look.

>  arch/arm64/boot/dts/exynos/exynos850.dtsi | 40 -----------------------
>  1 file changed, 40 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> index 2abbb972b610..4f0a40de5e67 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> @@ -344,38 +344,6 @@ cmu_hsi: clock-controller at 13400000 {
>                 pinctrl_alive: pinctrl at 11850000 {
>                         compatible = "samsung,exynos850-pinctrl";
>                         reg = <0x11850000 0x1000>;
> -                       interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
>
>                         wakeup-interrupt-controller {
>                                 compatible = "samsung,exynos7-wakeup-eint";
> @@ -385,14 +353,6 @@ wakeup-interrupt-controller {
>                 pinctrl_cmgp: pinctrl at 11c30000 {
>                         compatible = "samsung,exynos850-pinctrl";
>                         reg = <0x11c30000 0x1000>;
> -                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
> -                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
>
>                         wakeup-interrupt-controller {
>                                 compatible = "samsung,exynos7-wakeup-eint";
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Mon Jan  3 13:19:41 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 3 Jan 2022 23:19:41 +0200
Subject: [PATCH 24/24] dt-bindings: pinctrl: samsung: convert to dtschema
In-Reply-To: <20211231162309.257587-7-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162309.257587-7-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4kbn9-gCOy3f_ykVN_fbrKvQkYHR_wwj=4ETLS1PHKNFQ@mail.gmail.com>

On Fri, 31 Dec 2021 at 18:23, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) pin
> controller bindings to DT schema format.  Parts of description and DTS
> example was copied from existing sources, so keep the license as
> GPL-2.0-only.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

Kudos for doing that, converting and splitting. It's fascinating how
time consuming that bindings conversion work can be (at least for me,
hehe).

>  .../pinctrl/samsung,pinctrl-gpio-bank.yaml    |  52 +++
>  .../pinctrl/samsung,pinctrl-pins-cfg.yaml     |  81 ++++
>  .../samsung,pinctrl-wakeup-interrupt.yaml     |  76 ++++
>  .../bindings/pinctrl/samsung,pinctrl.yaml     | 381 +++++++++++++++++
>  .../bindings/pinctrl/samsung-pinctrl.txt      | 383 ------------------
>  MAINTAINERS                                   |   2 +-
>  6 files changed, 591 insertions(+), 384 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
> new file mode 100644
> index 000000000000..f73348c54748
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
> @@ -0,0 +1,52 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-gpio-bank.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC pin controller - gpio bank
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
> +  controller.
> +
> +  GPIO bank description for Samsung S3C/S5P/Exynos SoC pin controller.
> +
> +  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
> +  additional information and example.
> +
> +properties:
> +  '#gpio-cells':
> +    const: 2
> +
> +  gpio-controller: true
> +
> +  '#interrupt-cells':
> +    description:
> +      For GPIO banks supporting external GPIO interrupts or external wake-up
> +      interrupts.
> +    const: 2
> +
> +  interrupt-controller:
> +    description:
> +      For GPIO banks supporting external GPIO interrupts or external wake-up
> +      interrupts.
> +
> +  interrupts:
> +    description:
> +      For GPIO banks supporting direct external wake-up interrupts (without
> +      multiplexing).  Number of interrupts must match number of wake-up capable
> +      pins of this bank.
> +    minItems: 1
> +    maxItems: 8
> +
> +required:
> +  - '#gpio-cells'
> +  - gpio-controller
> +
> +additionalProperties: false
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
> new file mode 100644
> index 000000000000..637f4c05b344
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
> @@ -0,0 +1,81 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-pins-cfg.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC pin controller - pins configuration
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
> +  controller.
> +
> +  Pins configuration for Samsung S3C/S5P/Exynos SoC pin controller.
> +
> +  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
> +  additional information and example.
> +
> +  The values used for config properties should be derived from the hardware
> +  manual and these values are programmed as-is into the pin pull up/down and
> +  driver strength register of the pin-controller.
> +  See also include/dt-bindings/pinctrl/samsung.h with useful constants.
> +
> +properties:
> +  samsung,pins:
> +    description: |
> +      List of pins to configure. For initial and sleep states, the maximum
> +      number is one pin. In other cases there is no upper limit.
> +
> +      The pins should use lowercase names matching hardware manual, e.g. for
> +      GPA0 bank: gpa0-0, gpa0-1, gpa0-2.
> +    $ref: /schemas/types.yaml#/definitions/string-array
> +
> +  samsung,pin-function:
> +    description: |
> +      The pin function selection that should be applied on the pins listed in the
> +      child node is specified using the "samsung,pin-function" property. The value
> +      of this property that should be applied to each of the pins listed in the
> +      "samsung,pins" property should be picked from the hardware manual of the SoC
> +      for the specified pin group. This property is optional in the child node if
> +      no specific function selection is desired for the pins listed in the child
> +      node. The value of this property is used as-is to program the pin-controller
> +      function selector register of the pin-bank.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 15
> +
> +  samsung,pin-drv:
> +    description: Drive strength configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 0
> +    maximum: 15
> +
> +  samsung,pin-pud:
> +    description: Pull up/down configuration.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 1, 2, 3]
> +
> +  samsung,pin-val:
> +    description: Initial value of pin output buffer.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 1]
> +
> +  samsung,pin-con-pdn:
> +    description: Function in power down mode.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 1, 2, 3]
> +
> +  samsung,pin-pud-pdn:
> +    description: Pull up/down configuration in power down mode.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [0, 1, 2, 3]
> +
> +required:
> +  - samsung,pins
> +
> +additionalProperties: false
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
> new file mode 100644
> index 000000000000..eac56a087643
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
> @@ -0,0 +1,76 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC pin controller - wakeup interrupt controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
> +  controller.
> +
> +  External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
> +  Only one pin-controller device node can include external wakeup interrupts
> +  child node (in other words, only one External wake-up interrupts
> +  pin-controller is supported).
> +
> +  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
> +  additional information and example.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - samsung,s3c2410-wakeup-eint
> +      - samsung,s3c2412-wakeup-eint
> +      - samsung,s3c64xx-wakeup-eint
> +      - samsung,s5pv210-wakeup-eint
> +      - samsung,exynos4210-wakeup-eint
> +      - samsung,exynos7-wakeup-eint
> +
> +  interrupts:
> +    description:
> +      Interrupt used by multiplexed external wake-up interrupts.
> +    minItems: 1
> +    maxItems: 6
> +
> +required:
> +  - compatible
> +  - interrupts
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,s3c2410-wakeup-eint
> +              - samsung,s3c2412-wakeup-eint
> +    then:
> +      properties:
> +        interrupts:
> +          minItems: 6
> +          maxItems: 6
> +    else:
> +      if:
> +        properties:
> +          compatible:
> +            contains:
> +              const: samsung,s3c64xx-wakeup-eint
> +      then:
> +        properties:
> +          interrupts:
> +            minItems: 4
> +            maxItems: 4
> +      else:
> +        properties:
> +          interrupts:
> +            minItems: 1
> +            maxItems: 1
> +
> +additionalProperties: false
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
> new file mode 100644
> index 000000000000..37cd03805cab
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
> @@ -0,0 +1,381 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC pin controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +  - Sylwester Nawrocki <s.nawrocki at samsung.com>
> +  - Tomasz Figa <tomasz.figa at gmail.com>
> +
> +description: |
> +  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
> +  controller.
> +
> +  Pin group settings (like drive strength, pull up/down) are available as
> +  macros in include/dt-bindings/pinctrl/samsung.h.
> +
> +  All the pin controller nodes should be represented in the aliases node using
> +  the following format 'pinctrl{n}' where n is a unique number for the alias.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pinctrl(@.*)?"
> +
> +  compatible:
> +    enum:
> +      - samsung,s3c2412-pinctrl
> +      - samsung,s3c2416-pinctrl
> +      - samsung,s3c2440-pinctrl
> +      - samsung,s3c2450-pinctrl
> +      - samsung,s3c64xx-pinctrl
> +      - samsung,s5pv210-pinctrl
> +      - samsung,exynos3250-pinctrl
> +      - samsung,exynos4210-pinctrl
> +      - samsung,exynos4x12-pinctrl
> +      - samsung,exynos5250-pinctrl
> +      - samsung,exynos5260-pinctrl
> +      - samsung,exynos5410-pinctrl
> +      - samsung,exynos5420-pinctrl
> +      - samsung,exynos5433-pinctrl
> +      - samsung,exynos7-pinctrl
> +      - samsung,exynos7885-pinctrl
> +      - samsung,exynos850-pinctrl
> +      - samsung,exynosautov9-pinctrl
> +
> +  interrupts:
> +    description:
> +      Required for GPIO banks supporting external GPIO interrupts.
> +    maxItems: 1
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  reg:
> +    description:
> +      Second base address of the pin controller if the specific registers of
> +      the pin controller are separated into the different base address.
> +      Only certain banks of certain pin controller might need it.
> +    minItems: 1
> +    maxItems: 2
> +
> +  wakeup-interrupt-controller:
> +    $ref: samsung,pinctrl-wakeup-interrupt.yaml
> +
> +patternProperties:
> +  "^[a-z]+[0-9]*-gpio-bank$":
> +    description:
> +      Pin banks of the controller are represented by child nodes of the
> +      controller node. Bank name is taken from name of the node.
> +    $ref: samsung,pinctrl-gpio-bank.yaml
> +
> +  "^[a-z0-9-]+-pins$":
> +    oneOf:
> +      - $ref: samsung,pinctrl-pins-cfg.yaml
> +        required:
> +          - samsung,pins
> +      - type: object
> +        patternProperties:
> +          "^[a-z0-9-]+-pins$":
> +            $ref: samsung,pinctrl-pins-cfg.yaml
> +
> +        additionalProperties: false
> +
> +  "^(initial|sleep)-state$":
> +    patternProperties:
> +      "^(pin-[a-z0-9-]+|[a-z0-9-]+-pin)$":
> +        $ref: samsung,pinctrl-pins-cfg.yaml
> +
> +        properties:
> +          samsung,pins:
> +            description: See samsung,pinctrl-pins-cfg.yaml
> +            $ref: /schemas/types.yaml#/definitions/string-array
> +            maxItems: 1
> +
> +        required:
> +          - samsung,pins
> +
> +        unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +
> +allOf:
> +  - $ref: "pinctrl.yaml#"
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos5433-pinctrl
> +    then:
> +      properties:
> +        reg:
> +          minItems: 1
> +          maxItems: 2
> +    else:
> +      properties:
> +        reg:
> +          minItems: 1
> +          maxItems: 1
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/pinctrl/samsung.h>
> +
> +    pinctrl at 7f008000 {
> +        compatible = "samsung,s3c64xx-pinctrl";
> +        reg = <0x7f008000 0x1000>;
> +        interrupt-parent = <&vic1>;
> +        interrupts = <21>;
> +
> +        wakeup-interrupt-controller {
> +            compatible = "samsung,s3c64xx-wakeup-eint";
> +            interrupts-extended = <&vic0 0>,
> +                                  <&vic0 1>,
> +                                  <&vic1 0>,
> +                                  <&vic1 1>;
> +        };
> +
> +        /* Pin bank with external GPIO or muxed external wake-up interrupts */
> +        gpa-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        // ...
> +
> +        uart0-data-pins {
> +            samsung,pins = "gpa-0", "gpa-1";
> +            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +            samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
> +        };
> +
> +        // ...
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/samsung.h>
> +
> +    pinctrl at 11400000 {
> +        compatible = "samsung,exynos4210-pinctrl";
> +        reg = <0x11400000 0x1000>;
> +        interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&sleep0>;
> +
> +        /* Pin bank with external GPIO or muxed external wake-up interrupts */
> +        gpa0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        // ...
> +
> +        uart0-data-pins {
> +            samsung,pins = "gpa0-0", "gpa0-1";
> +            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +        };
> +
> +        // ...
> +
> +        sleep0: sleep-state {
> +            gpa0-0-pin {
> +                samsung,pins = "gpa0-0";
> +                samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
> +                samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
> +            };
> +
> +            gpa0-1-pin {
> +                samsung,pins = "gpa0-1";
> +                samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
> +                samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
> +            };
> +
> +            // ...
> +        };
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/samsung.h>
> +
> +    pinctrl at 11000000 {
> +        compatible = "samsung,exynos4210-pinctrl";
> +        reg = <0x11000000 0x1000>;
> +        interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        wakeup-interrupt-controller {
> +            compatible = "samsung,exynos4210-wakeup-eint";
> +            interrupt-parent = <&gic>;
> +            interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
> +        };
> +
> +        /* Pin bank with external GPIO or muxed external wake-up interrupts */
> +        gpj0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        /* Pin bank without external interrupts */
> +        gpy0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +        };
> +
> +        /* Pin bank with external direct wake-up interrupts */
> +        gpx0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +
> +            interrupt-controller;
> +            interrupt-parent = <&gic>;
> +            interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        // ...
> +
> +        sd0-clk-pins {
> +            samsung,pins = "gpk0-0";
> +            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> +        };
> +
> +        sd4-bus-width8-pins {
> +            part-1-pins {
> +                samsung,pins = "gpk0-3", "gpk0-4",
> +                               "gpk0-5", "gpk0-6";
> +                samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> +                samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> +            };
> +
> +            part-2-pins {
> +                samsung,pins = "gpk1-3", "gpk1-4",
> +                               "gpk1-5", "gpk1-6";
> +                samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
> +                samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> +            };
> +        };
> +
> +        // ...
> +
> +        otg-gp-pins {
> +            samsung,pins = "gpx3-3";
> +            samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> +            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +            samsung,pin-val = <0>;
> +        };
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/samsung.h>
> +
> +    pinctrl at 10580000 {
> +        compatible = "samsung,exynos5433-pinctrl";
> +        reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
> +
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&initial_alive>;
> +
> +        wakeup-interrupt-controller {
> +            compatible = "samsung,exynos7-wakeup-eint";
> +            interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
> +        };
> +
> +        /* Pin bank with external direct wake-up interrupts */
> +        gpa0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +
> +            interrupt-controller;
> +            interrupt-parent = <&gic>;
> +            interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
> +                         <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        // ...
> +
> +        te-irq-pins {
> +            samsung,pins = "gpf1-3";
> +            samsung,pin-function = <0xf>;
> +        };
> +
> +        // ..
> +
> +        initial_alive: initial-state {
> +            gpa0-0-pin {
> +                samsung,pins = "gpa0-0";
> +                samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
> +                samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
> +                samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
> +            };
> +
> +            // ...
> +        };
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/pinctrl/samsung.h>
> +
> +    pinctrl at 114b0000 {
> +        compatible = "samsung,exynos5433-pinctrl";
> +        reg = <0x114b0000 0x1000>;
> +        interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
> +        power-domains = <&pd_aud>;
> +
> +        /* Pin bank with external GPIO or muxed external wake-up interrupts */
> +        gpz0-gpio-bank {
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +        };
> +
> +        // ...
> +
> +        i2s0-bus-pins {
> +            samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
> +                           "gpz0-4", "gpz0-5", "gpz0-6";
> +            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +            samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
> +        };
> +
> +        // ...
> +    };
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> deleted file mode 100644
> index 9e70edceb21b..000000000000
> --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> +++ /dev/null
> @@ -1,383 +0,0 @@
> -Samsung GPIO and Pin Mux/Config controller
> -
> -Samsung's ARM based SoC's integrates a GPIO and Pin mux/config hardware
> -controller. It controls the input/output settings on the available pads/pins
> -and also provides ability to multiplex and configure the output of various
> -on-chip controllers onto these pads.
> -
> -Required Properties:
> -- compatible: should be one of the following.
> -  - "samsung,s3c2412-pinctrl": for S3C2412-compatible pin-controller,
> -  - "samsung,s3c2416-pinctrl": for S3C2416-compatible pin-controller,
> -  - "samsung,s3c2440-pinctrl": for S3C2440-compatible pin-controller,
> -  - "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
> -  - "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
> -  - "samsung,s5pv210-pinctrl": for S5PV210-compatible pin-controller,
> -  - "samsung,exynos3250-pinctrl": for Exynos3250 compatible pin-controller.
> -  - "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
> -  - "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
> -  - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
> -  - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
> -  - "samsung,exynos5410-pinctrl": for Exynos5410 compatible pin-controller.
> -  - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
> -  - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
> -  - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
> -  - "samsung,exynos7885-pinctrl": for Exynos7885 compatible pin-controller.
> -  - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
> -  - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
> -
> -- reg: Base address of the pin controller hardware module and length of
> -  the address space it occupies.
> -
> -  - reg: Second base address of the pin controller if the specific registers
> -  of the pin controller are separated into the different base address.
> -
> -       Eg: GPF[1-5] of Exynos5433 are separated into the two base address.
> -       - First base address is for GPAx and GPF[1-5] external interrupt
> -         registers.
> -       - Second base address is for GPF[1-5] pinctrl registers.
> -
> -       pinctrl_0: pinctrl at 10580000 {
> -               compatible = "samsung,exynos5433-pinctrl";
> -               reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
> -
> -               wakeup-interrupt-controller {
> -                       compatible = "samsung,exynos7-wakeup-eint";
> -                       interrupts = <0 16 0>;
> -               };
> -       };
> -
> -- Pin banks as child nodes: Pin banks of the controller are represented by child
> -  nodes of the controller node. Bank name is taken from name of the node. Each
> -  bank node must contain following properties:
> -
> -  - gpio-controller: identifies the node as a gpio controller and pin bank.
> -  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
> -    binding is used, the amount of cells must be specified as 2. See the below
> -    mentioned gpio binding representation for description of particular cells.
> -
> -       Eg: <&gpx2 6 0>
> -       <[phandle of the gpio controller node]
> -       [pin number within the gpio controller]
> -       [flags]>
> -
> -       Values for gpio specifier:
> -       - Pin number: is a value between 0 to 7.
> -       - Flags: 0 - Active High
> -                1 - Active Low
> -
> -- Pin mux/config groups as child nodes: The pin mux (selecting pin function
> -  mode) and pin config (pull up/down, driver strength) settings are represented
> -  as child nodes of the pin-controller node. There should be at least one
> -  child node and there is no limit on the count of these child nodes. It is
> -  also possible for a child node to consist of several further child nodes
> -  to allow grouping multiple pinctrl groups into one. The format of second
> -  level child nodes is exactly the same as for first level ones and is
> -  described below.
> -
> -  The child node should contain a list of pin(s) on which a particular pin
> -  function selection or pin configuration (or both) have to applied. This
> -  list of pins is specified using the property name "samsung,pins". There
> -  should be at least one pin specified for this property and there is no upper
> -  limit on the count of pins that can be specified. The pins are specified
> -  using pin names which are derived from the hardware manual of the SoC. As
> -  an example, the pins in GPA0 bank of the pin controller can be represented
> -  as "gpa0-0", "gpa0-1", "gpa0-2" and so on. The names should be in lower case.
> -  The format of the pin names should be (as per the hardware manual)
> -  "[pin bank name]-[pin number within the bank]".
> -
> -  The pin function selection that should be applied on the pins listed in the
> -  child node is specified using the "samsung,pin-function" property. The value
> -  of this property that should be applied to each of the pins listed in the
> -  "samsung,pins" property should be picked from the hardware manual of the SoC
> -  for the specified pin group. This property is optional in the child node if
> -  no specific function selection is desired for the pins listed in the child
> -  node. The value of this property is used as-is to program the pin-controller
> -  function selector register of the pin-bank.
> -
> -  The child node can also optionally specify one or more of the pin
> -  configuration that should be applied on all the pins listed in the
> -  "samsung,pins" property of the child node. The following pin configuration
> -  properties are supported.
> -
> -  - samsung,pin-val: Initial value of pin output buffer.
> -  - samsung,pin-pud: Pull up/down configuration.
> -  - samsung,pin-drv: Drive strength configuration.
> -  - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
> -  - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
> -
> -  The values specified by these config properties should be derived from the
> -  hardware manual and these values are programmed as-is into the pin
> -  pull up/down and driver strength register of the pin-controller.
> -
> -  Note: A child should include at least a pin function selection property or
> -  pin configuration property (one or more) or both.
> -
> -  The client nodes that require a particular pin function selection and/or
> -  pin configuration should use the bindings listed in the "pinctrl-bindings.txt"
> -  file.
> -
> -External GPIO and Wakeup Interrupts:
> -
> -The controller supports two types of external interrupts over gpio. The first
> -is the external gpio interrupt and second is the external wakeup interrupts.
> -The difference between the two is that the external wakeup interrupts can be
> -used as system wakeup events.
> -
> -A. External GPIO Interrupts: For supporting external gpio interrupts, the
> -   following properties should be specified in the pin-controller device node.
> -
> -   - interrupts: interrupt specifier for the controller. The format and value of
> -     the interrupt specifier depends on the interrupt parent for the controller.
> -
> -   In addition, following properties must be present in node of every bank
> -   of pins supporting GPIO interrupts:
> -
> -   - interrupt-controller: identifies the controller node as interrupt-parent.
> -   - #interrupt-cells: the value of this property should be 2.
> -     - First Cell: represents the external gpio interrupt number local to the
> -       external gpio interrupt space of the controller.
> -     - Second Cell: flags to identify the type of the interrupt
> -       - 1 = rising edge triggered
> -       - 2 = falling edge triggered
> -       - 3 = rising and falling edge triggered
> -       - 4 = high level triggered
> -       - 8 = low level triggered
> -
> -B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
> -   child node representing the external wakeup interrupt controller should be
> -   included in the pin-controller device node.
> -
> -   Only one pin-controller device node can include external wakeup interrupts
> -   child node (in other words, only one External Wakeup Interrupts
> -   pin-controller is supported).
> -
> -   This child node should include following properties:
> -
> -   - compatible: identifies the type of the external wakeup interrupt controller
> -     The possible values are:
> -     - samsung,s3c2410-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung S3C24xx SoCs except S3C2412 and S3C2413,
> -     - samsung,s3c2412-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung S3C2412 and S3C2413 SoCs,
> -     - samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung S3C64xx SoCs,
> -     - samsung,s5pv210-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung S5Pv210 SoCs,
> -     - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung Exynos4210 and S5PC110/S5PV210 SoCs.
> -     - samsung,exynos7-wakeup-eint: represents wakeup interrupt controller
> -       found on Samsung Exynos7 SoC.
> -   - interrupts: interrupt used by multiplexed wakeup interrupts.
> -
> -   In addition, following properties must be present in node of every bank
> -   of pins supporting wake-up interrupts:
> -
> -   - interrupt-controller: identifies the node as interrupt-parent.
> -   - #interrupt-cells: the value of this property should be 2
> -     - First Cell: represents the external wakeup interrupt number local to
> -       the external wakeup interrupt space of the controller.
> -     - Second Cell: flags to identify the type of the interrupt
> -       - 1 = rising edge triggered
> -       - 2 = falling edge triggered
> -       - 3 = rising and falling edge triggered
> -       - 4 = high level triggered
> -       - 8 = low level triggered
> -
> -   Node of every bank of pins supporting direct wake-up interrupts (without
> -   multiplexing) must contain following properties:
> -
> -   - interrupts: interrupts of the interrupt parent which are used for external
> -     wakeup interrupts from pins of the bank, must contain interrupts for all
> -     pins of the bank.
> -
> -Aliases:
> -
> -All the pin controller nodes should be represented in the aliases node using
> -the following format 'pinctrl{n}' where n is a unique number for the alias.
> -
> -Aliases for controllers compatible with "samsung,exynos7-pinctrl":
> -- pinctrl0: pin controller of ALIVE block,
> -- pinctrl1: pin controller of BUS0 block,
> -- pinctrl2: pin controller of NFC block,
> -- pinctrl3: pin controller of TOUCH block,
> -- pinctrl4: pin controller of FF block,
> -- pinctrl5: pin controller of ESE block,
> -- pinctrl6: pin controller of FSYS0 block,
> -- pinctrl7: pin controller of FSYS1 block,
> -- pinctrl8: pin controller of BUS1 block,
> -- pinctrl9: pin controller of AUDIO block,
> -
> -Example: A pin-controller node with pin banks:
> -
> -       pinctrl_0: pinctrl at 11400000 {
> -               compatible = "samsung,exynos4210-pinctrl";
> -               reg = <0x11400000 0x1000>;
> -               interrupts = <0 47 0>;
> -
> -               /* ... */
> -
> -               /* Pin bank without external interrupts */
> -               gpy0: gpy0 {
> -                       gpio-controller;
> -                       #gpio-cells = <2>;
> -               };
> -
> -               /* ... */
> -
> -               /* Pin bank with external GPIO or muxed wake-up interrupts */
> -               gpj0: gpj0 {
> -                       gpio-controller;
> -                       #gpio-cells = <2>;
> -
> -                       interrupt-controller;
> -                       #interrupt-cells = <2>;
> -               };
> -
> -               /* ... */
> -
> -               /* Pin bank with external direct wake-up interrupts */
> -               gpx0: gpx0 {
> -                       gpio-controller;
> -                       #gpio-cells = <2>;
> -
> -                       interrupt-controller;
> -                       interrupt-parent = <&gic>;
> -                       interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
> -                                    <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
> -                       #interrupt-cells = <2>;
> -               };
> -
> -               /* ... */
> -       };
> -
> -Example 1: A pin-controller node with pin groups.
> -
> -       #include <dt-bindings/pinctrl/samsung.h>
> -
> -       pinctrl_0: pinctrl at 11400000 {
> -               compatible = "samsung,exynos4210-pinctrl";
> -               reg = <0x11400000 0x1000>;
> -               interrupts = <0 47 0>;
> -
> -               /* ... */
> -
> -               uart0_data: uart0-data {
> -                       samsung,pins = "gpa0-0", "gpa0-1";
> -                       samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> -                       samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> -                       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> -               };
> -
> -               uart0_fctl: uart0-fctl {
> -                       samsung,pins = "gpa0-2", "gpa0-3";
> -                       samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> -                       samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> -                       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> -               };
> -
> -               uart1_data: uart1-data {
> -                       samsung,pins = "gpa0-4", "gpa0-5";
> -                       samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> -                       samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> -                       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> -               };
> -
> -               uart1_fctl: uart1-fctl {
> -                       samsung,pins = "gpa0-6", "gpa0-7";
> -                       samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> -                       samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> -                       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> -               };
> -
> -               i2c2_bus: i2c2-bus {
> -                       samsung,pins = "gpa0-6", "gpa0-7";
> -                       samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> -                       samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> -                       samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> -               };
> -
> -               sd4_bus8: sd4-bus-width8 {
> -                       part-1 {
> -                               samsung,pins = "gpk0-3", "gpk0-4",
> -                                               "gpk0-5", "gpk0-6";
> -                               samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
> -                               samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> -                               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> -                       };
> -                       part-2 {
> -                               samsung,pins = "gpk1-3", "gpk1-4",
> -                                               "gpk1-5", "gpk1-6";
> -                               samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
> -                               samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> -                               samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> -                       };
> -               };
> -       };
> -
> -Example 2: A pin-controller node with external wakeup interrupt controller node.
> -
> -       pinctrl_1: pinctrl at 11000000 {
> -               compatible = "samsung,exynos4210-pinctrl";
> -               reg = <0x11000000 0x1000>;
> -               interrupts = <0 46 0>
> -
> -               /* ... */
> -
> -               wakeup-interrupt-controller {
> -                       compatible = "samsung,exynos4210-wakeup-eint";
> -                       interrupt-parent = <&gic>;
> -                       interrupts = <0 32 0>;
> -               };
> -       };
> -
> -Example 3: A uart client node that supports 'default' and 'flow-control' states.
> -
> -       uart at 13800000 {
> -               compatible = "samsung,exynos4210-uart";
> -               reg = <0x13800000 0x100>;
> -               interrupts = <0 52 0>;
> -               pinctrl-names = "default", "flow-control;
> -               pinctrl-0 = <&uart0_data>;
> -               pinctrl-1 = <&uart0_data>, <&uart0_fctl>;
> -       };
> -
> -Example 4: Set up the default pin state for uart controller.
> -
> -       static int s3c24xx_serial_probe(struct platform_device *pdev) {
> -               struct pinctrl *pinctrl;
> -
> -               /* ... */
> -
> -               pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
> -       }
> -
> -Example 5: A display port client node that supports 'default' pinctrl state
> -          and gpio binding.
> -
> -       display-port-controller {
> -               /* ... */
> -
> -               samsung,hpd-gpio = <&gpx2 6 0>;
> -               pinctrl-names = "default";
> -               pinctrl-0 = <&dp_hpd>;
> -       };
> -
> -Example 6: Request the gpio for display port controller
> -
> -       static int exynos_dp_probe(struct platform_device *pdev)
> -       {
> -               int hpd_gpio, ret;
> -               struct device *dev = &pdev->dev;
> -               struct device_node *dp_node = dev->of_node;
> -
> -               /* ... */
> -
> -               hpd_gpio = of_get_named_gpio(dp_node, "samsung,hpd-gpio", 0);
> -
> -               /* ... */
> -
> -               ret = devm_gpio_request_one(&pdev->dev, hpd_gpio, GPIOF_IN,
> -                                           "hpd_gpio");
> -               /* ... */
> -       }
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5ea5655a29c3..33005c10e956 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15242,7 +15242,7 @@ L:      linux-samsung-soc at vger.kernel.org
>  S:     Maintained
>  Q:     https://patchwork.kernel.org/project/linux-samsung-soc/list/
>  T:     git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
> -F:     Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> +F:     Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
>  F:     drivers/pinctrl/samsung/
>  F:     include/dt-bindings/pinctrl/samsung.h
>
> --
> 2.32.0
>


From abel.vesa at nxp.com  Mon Jan  3 14:49:00 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue,  4 Jan 2022 00:49:00 +0200
Subject: [PATCH v2] arm64: dts: imx8qm: Add SCU RTC node
Message-ID: <20220103224900.1439756-1-abel.vesa@nxp.com>

Add SCU RTC node to support SC RTC driver.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v1:
 * switched to fsl,imx8qxp-sc-rtc compatible and dropped dt-bindings
   and rtc driver patches

 arch/arm64/boot/dts/freescale/imx8qm.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
index 4a7c017b5f31..ac43315a470c 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
@@ -201,6 +201,9 @@ iomuxc: pinctrl {
 			compatible = "fsl,imx8qm-iomuxc";
 		};
 
+		rtc: rtc {
+			compatible = "fsl,imx8qxp-sc-rtc";
+		};
 	};
 
 	/* sorted in register address */
-- 
2.31.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:41 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:41 -0500
Subject: [PATCH v7 0/7] Add initial support for the i.MXRTxxxx SoC family
 starting from i.IMXRT1050 SoC.
Message-ID: <20220103233948.198119-1-Mr.Bossman075@gmail.com>

This patchset contains:
- i.MXRT10xx family infrastructure
- i.MXRT1050 pinctrl driver adaption
- i.MXRT1050 clock driver adaption
- i.MXRT1050 sd-card driver adaption
- i.MXRT1050 uart driver adaption
- i.MXRT1050-evk basic support

The i.MXRTxxxx family that could have support by Linux actually spreads
from i.MXRT1020 to i.MXRT1170 with the first one supporting 1 USB OTG &
100M ethernet with a cortex-M7 at 500Mhz up to the latter with i.MXRT1170
with cortex-M7 at 1Ghz and cortex-M4 at 400Mhz, 2MB of internal SRAM, 2D GPU,
2x 1Gb and 1x 100Mb ENET. The i.MXRT family is NXP's answer to
STM32F7XX, as it uses only simple SDRAM, it gives the chance of a 4 or
less layer PCBs. Seeing that these chips are comparable to the
STM32F7XXs which have linux ported to them it seems reasonable to add
support for them.

Giving Linux support to this family should ease the development process,
instead of using a RTOS they could use Embedded Linux allowing for more
portability, ease of design and will broaden the scope of people using
embedded linux.

The EVK has very little SDRAM, generally 32MB starting from
i.MXRT1020(the lowest P/N), although the i.MXRT1160/70 provide instead
64MB of SDRAM for more functionality.

At the moment we do not support XIP for either u-boot or Linux but it
should be done in the future. XIP will also save SDRAM.

Another interesting fact is the amount of internal SRAM, as the P/N
increases the SRAM will reach up to 2MB(some could be for cache and
some would be for video).

Also, some parts have embed flash of 4MB that can be used for
u-boot/Linux, if both correctly sized it will leave the SDRAM free.

External flash can be Quad SPI and HyperFlash, so throughput would be
decent.

The i.MXRT11xx series supports MIPI interface too.

The family in general provide CAN bus, audio I/O, 1 or more
USB(otg/host), 1 or more 100Mb/1Gb ethernet, camera interface, sd-card.

All this can be used for simple GUIs, web-servers, point-of-sale
stations, etc.


Giulio Benetti (4):
  ARM: imx: Add initial support for i.MXRT10xx family
  dt-bindings: imx: Add clock binding for i.MXRT1050
  ARM: dts: imx: Add i.MXRT1050-EVK support
  ARM: imxrt_defconfig: Add i.MXRT family defconfig

Jesse Taube (3):
  ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
  dt-bindings: clock: imx: Add documentation for i.MXRT1050 clock
  clk: imx: Add initial support for i.MXRT1050 clock driver

 .../bindings/clock/imxrt1050-clock.yaml       |  67 ++
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts           |  72 ++
 arch/arm/boot/dts/imxrt1050-pinfunc.h         | 993 ++++++++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi              | 160 +++
 arch/arm/configs/imxrt_defconfig              |  35 +
 arch/arm/mach-imx/Kconfig                     |   7 +
 arch/arm/mach-imx/Makefile                    |   2 +
 arch/arm/mach-imx/mach-imxrt.c                |  19 +
 drivers/clk/imx/Kconfig                       |   5 +
 drivers/clk/imx/Makefile                      |   1 +
 drivers/clk/imx/clk-imxrt1050.c               | 181 ++++
 include/dt-bindings/clock/imxrt1050-clock.h   |  72 ++
 13 files changed, 1616 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi
 create mode 100644 arch/arm/configs/imxrt_defconfig
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:42 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:42 -0500
Subject: [PATCH v7 1/7] ARM: imx: Add initial support for i.MXRT10xx family
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-2-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The i.MXRT10xx family of processors features NXP's implementation of the
Arm Cortex-M7 core and in some case the Arm Cortex-M4 core too.

This patch aims to add an initial support for imxrt.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: removed SOC_IMXRT's 'depends on ARCH_MULTI_V7' and 'select
ARM_GIC if ARCH_MULTI_V7']
---
V1->V2:
* Remove depends ARCH_MULTI_V7
* Remove select PINCTRL_IMXRT
* Change commit description
V2->V3:
* Nothing done
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
---
 arch/arm/mach-imx/Kconfig      |  7 +++++++
 arch/arm/mach-imx/Makefile     |  2 ++
 arch/arm/mach-imx/mach-imxrt.c | 19 +++++++++++++++++++
 3 files changed, 28 insertions(+)
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b407b024dde3..5ad3a8b9b4b6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -239,6 +239,13 @@ config SOC_IMX7ULP
 	help
 	  This enables support for Freescale i.MX7 Ultra Low Power processor.
 
+config SOC_IMXRT
+	bool "i.MXRT support"
+	depends on ARM_SINGLE_ARMV7M
+	select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+	help
+	  This enables support for Freescale i.MXRT Crossover processor.
+
 config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d1506ef7a537..3b1145722a44 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -65,6 +65,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
+obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
+
 obj-$(CONFIG_SOC_VF610) += mach-vf610.o
 
 obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
diff --git a/arch/arm/mach-imx/mach-imxrt.c b/arch/arm/mach-imx/mach-imxrt.c
new file mode 100644
index 000000000000..2063a3059c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imxrt.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include <asm/v7m.h>
+
+static const char *const imxrt_compat[] __initconst = {
+	"fsl,imxrt1050",
+	NULL
+};
+
+DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
+	.dt_compat = imxrt_compat,
+	.restart = armv7m_restart,
+MACHINE_END
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:44 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:44 -0500
Subject: [PATCH v7 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-4-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add the clock binding doc for i.MXRT1050.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
[Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]
---
V1->V2:
* Nothing done
V2->V3:
* Added GPT binding
V3->V4:
* Change License to MIT or GPL-2
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Fix typo in numbering
* Remove GPT
---
 include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h
new file mode 100644
index 000000000000..93bef0832d16
--- /dev/null
+++ b/include/dt-bindings/clock/imxrt1050-clock.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright(C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMXRT1050_H
+#define __DT_BINDINGS_CLOCK_IMXRT1050_H
+
+#define IMXRT1050_CLK_DUMMY			0
+#define IMXRT1050_CLK_CKIL			1
+#define IMXRT1050_CLK_CKIH			2
+#define IMXRT1050_CLK_OSC			3
+#define IMXRT1050_CLK_PLL2_PFD0_352M		4
+#define IMXRT1050_CLK_PLL2_PFD1_594M		5
+#define IMXRT1050_CLK_PLL2_PFD2_396M		6
+#define IMXRT1050_CLK_PLL3_PFD0_720M		7
+#define IMXRT1050_CLK_PLL3_PFD1_664_62M		8
+#define IMXRT1050_CLK_PLL3_PFD2_508_24M		9
+#define IMXRT1050_CLK_PLL3_PFD3_454_74M		10
+#define IMXRT1050_CLK_PLL2_198M			11
+#define IMXRT1050_CLK_PLL3_120M			12
+#define IMXRT1050_CLK_PLL3_80M			13
+#define IMXRT1050_CLK_PLL3_60M			14
+#define IMXRT1050_CLK_PLL1_BYPASS		15
+#define IMXRT1050_CLK_PLL2_BYPASS		16
+#define IMXRT1050_CLK_PLL3_BYPASS		17
+#define IMXRT1050_CLK_PLL5_BYPASS		19
+#define IMXRT1050_CLK_PLL1_REF_SEL		20
+#define IMXRT1050_CLK_PLL2_REF_SEL		21
+#define IMXRT1050_CLK_PLL3_REF_SEL		22
+#define IMXRT1050_CLK_PLL5_REF_SEL		23
+#define IMXRT1050_CLK_PRE_PERIPH_SEL		24
+#define IMXRT1050_CLK_PERIPH_SEL		25
+#define IMXRT1050_CLK_SEMC_ALT_SEL		26
+#define IMXRT1050_CLK_SEMC_SEL			27
+#define IMXRT1050_CLK_USDHC1_SEL		28
+#define IMXRT1050_CLK_USDHC2_SEL		29
+#define IMXRT1050_CLK_LPUART_SEL		30
+#define IMXRT1050_CLK_LCDIF_SEL			31
+#define IMXRT1050_CLK_VIDEO_POST_DIV_SEL	32
+#define IMXRT1050_CLK_VIDEO_DIV			33
+#define IMXRT1050_CLK_ARM_PODF			34
+#define IMXRT1050_CLK_LPUART_PODF		35
+#define IMXRT1050_CLK_USDHC1_PODF		36
+#define IMXRT1050_CLK_USDHC2_PODF		37
+#define IMXRT1050_CLK_SEMC_PODF			38
+#define IMXRT1050_CLK_AHB_PODF			39
+#define IMXRT1050_CLK_LCDIF_PRED		40
+#define IMXRT1050_CLK_LCDIF_PODF		41
+#define IMXRT1050_CLK_USDHC1			42
+#define IMXRT1050_CLK_USDHC2			43
+#define IMXRT1050_CLK_LPUART1			44
+#define IMXRT1050_CLK_SEMC			45
+#define IMXRT1050_CLK_LCDIF_APB			46
+#define IMXRT1050_CLK_PLL1_ARM			47
+#define IMXRT1050_CLK_PLL2_SYS			48
+#define IMXRT1050_CLK_PLL3_USB_OTG		49
+#define IMXRT1050_CLK_PLL4_AUDIO		50
+#define IMXRT1050_CLK_PLL5_VIDEO		51
+#define IMXRT1050_CLK_PLL6_ENET			52
+#define IMXRT1050_CLK_PLL7_USB_HOST		53
+#define IMXRT1050_CLK_LCDIF_PIX			54
+#define IMXRT1050_CLK_USBOH3			55
+#define IMXRT1050_CLK_IPG_PDOF			56
+#define IMXRT1050_CLK_PER_CLK_SEL		57
+#define IMXRT1050_CLK_PER_PDOF			58
+#define IMXRT1050_CLK_DMA			59
+#define IMXRT1050_CLK_DMA_MUX			60
+#define IMXRT1050_CLK_END			61
+
+#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:45 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:45 -0500
Subject: [PATCH v7 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-5-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add DT binding documentation for i.MXRT1050 clock driver.

Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Replace macros with values
V2->V3:
* Remove anatop
* Use lpuart not gpt
* include imxrt1050-clock.h
* 2 space tabs to 4
* Remove oneOf enum
* Change maxItems to 2
V3->V4:
* Nothing done
V4->V5:
* Remove extra newline
* Rename ccm to clock-controller
* Change minItems to const
* Change minItems to description
* Rename file to add 1050
* Change commit description to just 1050
V5->V6:
* Add maxItems for clocks description
V6->V7:
* Nothing done
---
 .../bindings/clock/imxrt1050-clock.yaml       | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
new file mode 100644
index 000000000000..35fd08c143f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imxrt1050-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MXRT
+
+maintainers:
+  - Giulio Benetti <giulio.benetti at benettiengineering.com>
+  - Jesse Taube <Mr.Bossman075 at gmail.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imxrt*-clock.h
+  for the full list of i.MXRT clock IDs.
+
+properties:
+  compatible:
+    const: fsl,imxrt1050-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 2
+
+  clocks:
+    description: 24m osc
+    maxItems: 1
+
+  clock-names:
+    const: osc
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imxrt1050-clock.h>
+
+    clks: clock-controller at 400fc000 {
+        compatible = "fsl,imxrt1050-ccm";
+        reg = <0x400fc000 0x4000>;
+        interrupts = <95>, <96>;
+        clocks = <&osc>;
+        clock-names = "osc";
+        #clock-cells = <1>;
+    };
+
+    lpuart1: serial at 40184000 {
+        compatible = "fsl,imxrt1050-lpuart";
+        reg = <0x40184000 0x4000>;
+        interrupts = <20>;
+        clocks = <&clks IMXRT1050_CLK_LPUART1>;
+        clock-names = "ipg";
+    };
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:43 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:43 -0500
Subject: [PATCH v7 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-3-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add binding header for i.MXRT1050 pinctrl device tree.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: move pinfunc from dt-bindings to dts folder]
---
V1->V2:
* Move pinfunc from dt-binding to dts
* Change subject and description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Change License comment style
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
---
 arch/arm/boot/dts/imxrt1050-pinfunc.h | 993 ++++++++++++++++++++++++++
 1 file changed, 993 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h

diff --git a/arch/arm/boot/dts/imxrt1050-pinfunc.h b/arch/arm/boot/dts/imxrt1050-pinfunc.h
new file mode 100644
index 000000000000..22c14a3262ad
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-pinfunc.h
@@ -0,0 +1,993 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+#define _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+
+#define IMX_PAD_SION	0x40000000
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MXRT1050_IOMUXC_GPIO_EMC_00_SEMC_DA00				0x014 0x204 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXPWM4_PWM0_A			0x014 0x204 0x494 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_LPSPI2_SCK				0x014 0x204 0x500 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_00_XBAR_INOUT2				0x014 0x204 0x60C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXIO1_D00				0x014 0x204 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_GPIO4_IO00				0x014 0x204 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_01_SEMC_DA01				0x018 0x208 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXPWM4_PWM0_B			0x018 0x208 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_LPSPI2_PCS0				0x018 0x208 0x4FC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_01_XBAR_INOUT3				0x018 0x208 0x610 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXIO1_D01				0x018 0x208 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_GPIO4_IO01				0x018 0x208 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_02_SEMC_DA02				0x01C 0x20C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXPWM4_PWM1_A			0x01C 0x20C 0x498 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_LPSPI2_SDO				0x01C 0x20C 0x508 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_02_XBAR_INOUT4				0x01C 0x20C 0x614 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXIO1_D02				0x01C 0x20C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_GPIO4_IO02				0x01C 0x20C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_03_SEMC_DA03				0x020 0x210 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXPWM4_PWM1_B			0x020 0x210 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_LPSPI2_SDI				0x020 0x210 0x504 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_03_XBAR_INOUT5				0x020 0x210 0x618 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXIO1_D03				0x020 0x210 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_GPIO4_IO03				0x020 0x210 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SEMC_DA04				0x024 0x214 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXPWM4_PWM2_A			0x024 0x214 0x49C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SAI2_TX_DATA			0x024 0x214 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_XBAR_INOUT6				0x024 0x214 0x61C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXIO1_D04				0x024 0x214 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_GPIO4_IO04				0x024 0x214 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SEMC_DA05				0x028 0x218 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXPWM4_PWM2_B			0x028 0x218 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SAI2_TX_SYNC			0x028 0x218 0x5C4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_XBAR_INOUT7				0x028 0x218 0x620 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXIO1_D05				0x028 0x218 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_GPIO4_IO05				0x028 0x218 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SEMC_DA06				0x02C 0x21C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXPWM2_PWM0_A			0x02C 0x21C 0x478 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SAI2_TX_BCLK			0x02C 0x21C 0x5C0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_XBAR_INOUT8				0x02C 0x21C 0x624 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXIO1_D06				0x02C 0x21C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_GPIO4_IO06				0x02C 0x21C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SEMC_DA07				0x030 0x220 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXPWM2_PWM0_B			0x030 0x220 0x488 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SAI2_MCLK				0x030 0x220 0x5B0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_XBAR_INOUT9				0x030 0x220 0x628 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXIO1_D07				0x030 0x220 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_GPIO4_IO07				0x030 0x220 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SEMC_DM00				0x034 0x224 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXPWM2_PWM1_A			0x034 0x224 0x47C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SAI2_RX_DATA			0x034 0x224 0x5B8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_XBAR_INOUT17			0x034 0x224 0x62C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXIO1_D08				0x034 0x224 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_GPIO4_IO08				0x034 0x224 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SEMC_ADDR00				0x038 0x228 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXPWM2_PWM1_B			0x038 0x228 0x48C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SAI2_RX_SYNC			0x038 0x228 0x5BC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXCAN2_TX				0x038 0x228 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXIO1_D09				0x038 0x228 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_GPIO4_IO09				0x038 0x228 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SEMC_ADDR01				0x03C 0x22C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXPWM2_PWM2_A			0x03C 0x22C 0x480 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SAI2_RX_BCLK			0x03C 0x22C 0x5B4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXCAN2_RX				0x03C 0x22C 0x450 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXIO1_D10				0x03C 0x22C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_GPIO4_IO10				0x03C 0x22C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_11_SEMC_ADDR02				0x040 0x230 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXPWM2_PWM2_B			0x040 0x230 0x490 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_LPI2C4_SDA				0x040 0x230 0x4E8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_USDHC2_RESET_B			0x040 0x230 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXIO1_D11				0x040 0x230 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_GPIO4_IO11				0x040 0x230 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_12_SEMC_ADDR03				0x044 0x234 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_XBAR_INOUT24			0x044 0x234 0x640 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_LPI2C4_SCL				0x044 0x234 0x4E4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_USDHC2_WP				0x044 0x234 0x5D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_FLEXPWM1_PWM3_A			0x044 0x234 0x454 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_12_GPIO4_IO12				0x044 0x234 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_13_SEMC_ADDR04				0x048 0x238 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_XBAR_INOUT25			0x048 0x238 0x650 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_LPUART3_TXD				0x048 0x238 0x53C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_MQS_RIGHT				0x048 0x238 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_FLEXPWM1_PWM3_B			0x048 0x238 0x464 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_GPIO4_IO13				0x048 0x238 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_14_SEMC_ADDR05				0x04C 0x23C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_XBAR_INOUT19			0x04C 0x23C 0x654 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPUART3_RXD				0x04C 0x23C 0x538 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_MQS_LEFT				0x04C 0x23C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPSPI2_PCS1				0x04C 0x23C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_GPIO4_IO14				0x04C 0x23C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SEMC_ADDR06				0x050 0x240 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_XBAR_INOUT20			0x050 0x240 0x634 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_LPUART3_CTS_B			0x050 0x240 0x534 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SPDIF_OUT				0x050 0x240 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_TMR3_TIMER0				0x050 0x240 0x57C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_GPIO4_IO15				0x050 0x240 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SEMC_ADDR07				0x054 0x244 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_XBAR_INOUT21			0x054 0x244 0x658 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_LPUART3_RTS_B			0x054 0x244 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SPDIF_IN				0x054 0x244 0x5C8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_16_TMR3_TIMER1				0x054 0x244 0x580 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_GPIO4_IO16				0x054 0x244 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_17_SEMC_ADDR08				0x058 0x248 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXPWM4_PWM3_A			0x058 0x248 0x4A0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_LPUART4_CTS_B			0x058 0x248 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXCAN1_TX				0x058 0x248 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_TMR3_TIMER2				0x058 0x248 0x584 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_GPIO4_IO17				0x058 0x248 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SEMC_ADDR09				0x05C 0x24C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXPWM4_PWM3_B			0x05C 0x24C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_LPUART4_RTS_B			0x05C 0x24C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXCAN1_RX				0x05C 0x24C 0x44C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_18_TMR3_TIMER3				0x05C 0x24C 0x588 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_GPIO4_IO18				0x05C 0x24C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SNVS_VIO_5_CTL			0x05C 0x24C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SEMC_ADDR11				0x060 0x250 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_FLEXPWM2_PWM3_A			0x060 0x250 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_LPUART4_TXD				0x060 0x250 0x544 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_19_ENET_RX_DATA01			0x060 0x250 0x438 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_TMR2_TIMER0				0x060 0x250 0x56C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_GPIO4_IO19				0x060 0x250 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SNVS_VIO_5				0x060 0x250 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_20_SEMC_ADDR12				0x064 0x254 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_FLEXPWM2_PWM3_B			0x064 0x254 0x484 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_LPUART4_RXD				0x064 0x254 0x540 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_ENET_RX_DATA00			0x064 0x254 0x434 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_TMR2_TIMER0				0x064 0x254 0x570 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_GPIO4_IO20				0x064 0x254 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_21_SEMC_BA0				0x068 0x258 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_FLEXPWM3_PWM3_A			0x068 0x258 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_LPI2C3_SDA				0x068 0x258 0x4E0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_ENET_TX_DATA01			0x068 0x258 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_TMR2_TIMER2				0x068 0x258 0x574 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_GPIO4_IO21				0x068 0x258 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_22_SEMC_BA1				0x06C 0x25C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_FLEXPWM3_PWM3_B			0x06C 0x25C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_LPI2C3_SCL				0x06C 0x25C 0x4DC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_ENET_TX_DATA00			0x06C 0x25C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_TMR2_TIMER3				0x06C 0x25C 0x578 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_GPIO4_IO22				0x06C 0x25C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_23_SEMC_ADDR10				0x070 0x260 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_FLEXPWM1_PWM0_A			0x070 0x260 0x458 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_LPUART5_TXD				0x070 0x260 0x54C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_ENET_RX_EN				0x070 0x260 0x43C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPT1_CAPTURE2			0x070 0x260 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPIO4_IO23				0x070 0x260 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_24_SEMC_CAS				0x074 0x264 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_FLEXPWM1_PWM0_B			0x074 0x264 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_LPUART5_RXD				0x074 0x264 0x548 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_ENET_TX_EN				0x074 0x264 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPT1_CAPTURE1			0x074 0x264 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPIO4_IO24				0x074 0x264 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_25_SEMC_RAS				0x078 0x268 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_FLEXPWM1_PWM1_A			0x078 0x268 0x45C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_LPUART6_TXD				0x078 0x268 0x554 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_TX_CLK				0x078 0x268 0x448 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_REF_CLK			0x078 0x268 0x42C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_GPIO4_IO25				0x078 0x268 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_26_SEMC_CLK				0x07C 0x26C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXPWM1_PWM1_B			0x07C 0x26C 0x46C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_LPUART6_RXD				0x07C 0x26C 0x550 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_ENET_RX_ER				0x07C 0x26C 0x440 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXIO1_D12				0x07C 0x26C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_GPIO4_IO26				0x07C 0x26C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_27_SEMC_CKE				0x080 0x270 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXPWM1_PWM2_A			0x080 0x270 0x460 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPUART5_RTS_B			0x080 0x270 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPSPI1_SCK				0x080 0x270 0x4F0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXIO1_D13				0x080 0x270 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_GPIO4_IO27				0x080 0x270 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_28_SEMC_WE				0x084 0x274 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXPWM1_PWM2_B			0x084 0x274 0x470 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPUART5_CTS_B			0x084 0x274 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPSPI1_SDO				0x084 0x274 0x4F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXIO1_D14				0x084 0x274 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_GPIO4_IO28				0x084 0x274 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_29_SEMC_CS0				0x088 0x278 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXPWM3_PWM0_A			0x088 0x278 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPUART6_RTS_B			0x088 0x278 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPSPI1_SDI				0x088 0x278 0x4F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXIO1_D15				0x088 0x278 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_GPIO4_IO29				0x088 0x278 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_30_SEMC_DA08				0x08C 0x27C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_FLEXPWM3_PWM0_B			0x08C 0x27C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPUART6_CTS_B			0x08C 0x27C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPSPI1_PCS0				0x08C 0x27C 0x4EC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_30_CSI_DATA23				0x08C 0x27C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_GPIO4_IO30				0x08C 0x27C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_31_SEMC_DA09				0x090 0x280 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_FLEXPWM3_PWM1_A			0x090 0x280 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPUART7_TXD				0x090 0x280 0x55C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPSPI1_PCS1				0x090 0x280 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_CSI_DATA22				0x090 0x280 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_GPIO4_IO31				0x090 0x280 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_32_SEMC_DA10				0x094 0x284 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_FLEXPWM3_PWM1_B			0x094 0x284 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_LPUART7_RXD				0x094 0x284 0x558 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CCM_PMIC_READY			0x094 0x284 0x3FC 0x3 0x4
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CSI_DATA21				0x094 0x284 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_GPIO3_IO18				0x094 0x284 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SEMC_DA11				0x098 0x288 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_FLEXPWM3_PWM2_A			0x098 0x288 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_USDHC1_RESET_B			0x098 0x288 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SAI3_RX_DATA			0x098 0x288 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_CSI_DATA20				0x098 0x288 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_GPIO3_IO19				0x098 0x288 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SEMC_DA12				0x09C 0x28C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_FLEXPWM3_PWM2_B			0x09C 0x28C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_USDHC1_VSELECT			0x09C 0x28C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SAI3_RX_SYNC			0x09C 0x28C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_CSI_DATA19				0x09C 0x28C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_GPIO3_IO20				0x09C 0x28C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SEMC_DA13				0x0A0 0x290 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_XBAR_INOUT18			0x0A0 0x290 0x630 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPT1_COMPARE1			0x0A0 0x290 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SAI3_RX_BCLK			0x0A0 0x290 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_CSI_DATA18				0x0A0 0x290 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPIO3_IO21				0x0A0 0x290 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_USDHC1_CD_B				0x0A0 0x290 0x5D4 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SEMC_DA14				0x0A4 0x294 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_XBAR_INOUT22			0x0A4 0x294 0x638 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPT1_COMPARE2			0x0A4 0x294 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SAI3_TX_DATA			0x0A4 0x294 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_CSI_DATA17				0x0A4 0x294 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPIO3_IO22				0x0A4 0x294 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_USDHC1_WP				0x0A4 0x294 0x5D8 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SEMC_DA15				0x0A8 0x298 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_XBAR_INOUT23			0x0A8 0x298 0x63C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPT1_COMPARE3			0x0A8 0x298 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SAI3_MCLK				0x0A8 0x298 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_CSI_DATA16				0x0A8 0x298 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPIO3_IO23				0x0A8 0x298 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_USDHC2_WP				0x0A8 0x298 0x608 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SEMC_DM01				0x0AC 0x29C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_FLEXPWM1_PWM3_A			0x0AC 0x29C 0x454 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_LPUART8_TXD				0x0AC 0x29C 0x564 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SAI3_TX_BCLK			0x0AC 0x29C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_CSI_FIELD				0x0AC 0x29C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_GPIO3_IO24				0x0AC 0x29C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_USDHC2_VSELECT			0x0AC 0x29C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SEMC_DQS				0x0B0 0x2A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_FLEXPWM1_PWM3_B			0x0B0 0x2A0 0x464 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_LPUART8_RXD				0x0B0 0x2A0 0x560 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SAI3_TX_SYNC			0x0B0 0x2A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_WDOG1_B				0x0B0 0x2A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_GPIO3_IO25				0x0B0 0x2A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_USDHC2_CD_B				0x0B0 0x2A0 0x5E0 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_40_SEMC_RDY				0x0B4 0x2A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPT2_CAPTURE2			0x0B4 0x2A4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_LPSPI1_PCS2				0x0B4 0x2A4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USB_OTG2_OC				0x0B4 0x2A4 0x5CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_40_ENET_MDC				0x0B4 0x2A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPIO3_IO26				0x0B4 0x2A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USDHC2_RESET_B			0x0B4 0x2A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_41_SEMC_CSX0				0x0B8 0x2A8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPT2_CAPTURE1			0x0B8 0x2A8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_LPSPI1_PCS3				0x0B8 0x2A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USB_OTG2_PWR			0x0B8 0x2A8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_ENET_MDIO				0x0B8 0x2A8 0x430 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPIO3_IO27				0x0B8 0x2A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USDHC2_VSELECT			0x0B8 0x2A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_FLEXPWM2_PWM3_A			0x0BC 0x2AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_XBAR_INOUT14			0x0BC 0x2AC 0x644 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_REF_CLK_32K			0x0BC 0x2AC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USB_OTG2_ID			0x0BC 0x2AC 0x3F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPI2C1_SCLS			0x0BC 0x2AC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_GPIO1_IO00			0x0BC 0x2AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USDHC1_RESET_B			0x0BC 0x2AC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK			0x0BC 0x2AC 0x510 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_FLEXPWM2_PWM3_B			0x0C0 0x2B0 0x484 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_XBAR_INOUT15			0x0C0 0x2B0 0x648 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_REF_CLK_24M			0x0C0 0x2B0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_USB_OTG1_ID			0x0C0 0x2B0 0x3F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPI2C1_SDAS			0x0C0 0x2B0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_GPIO1_IO01			0x0C0 0x2B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_EWM_OUT_B				0x0C0 0x2B0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO			0x0C0 0x2B0 0x518 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXCAN2_TX			0x0C4 0x2B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_XBAR_INOUT16			0x0C4 0x2B4 0x64C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPUART6_TXD			0x0C4 0x2B4 0x554 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_USB_OTG1_PWR			0x0C4 0x2B4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXPWM1_PWM0_X			0x0C4 0x2B4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_GPIO1_IO02			0x0C4 0x2B4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPI2C1_HREQ			0x0C4 0x2B4 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI			0x0C4 0x2B4 0x514 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXCAN2_RX			0x0C8 0x2B8 0x450 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_XBAR_INOUT17			0x0C8 0x2B8 0x62C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPUART6_RXD			0x0C8 0x2B8 0x550 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_USB_OTG1_OC			0x0C8 0x2B8 0x5D0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXPWM1_PWM1_X			0x0C8 0x2B8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_GPIO1_IO03			0x0C8 0x2B8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_REF_CLK_24M			0x0C8 0x2B8 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0			0x0C8 0x2B8 0x50C 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SRC_BOOT_MODE00			0x0CC 0x2BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_MQS_RIGHT				0x0CC 0x2BC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_ENET_TX_DATA03			0x0CC 0x2BC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SAI2_TX_SYNC			0x0CC 0x2BC 0x5C4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_CSI_DATA09			0x0CC 0x2BC 0x41C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_GPIO1_IO04			0x0CC 0x2BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_PIT_TRIGGER00			0x0CC 0x2BC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_LPSPI3_PCS1			0x0CC 0x2BC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SRC_BOOT_MODE01			0x0D0 0x2C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_MQS_LEFT				0x0D0 0x2C0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_ENET_TX_DATA02			0x0D0 0x2C0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SAI2_TX_BCLK			0x0D0 0x2C0 0x5C0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_CSI_DATA08			0x0D0 0x2C0 0x418 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_GPIO1_IO05			0x0D0 0x2C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_XBAR_INOUT17			0x0D0 0x2C0 0x62C 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_LPSPI3_PCS2			0x0D0 0x2C0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_JTAG_TMS				0x0D4 0x2C4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPT2_COMPARE1			0x0D4 0x2C4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_ENET_RX_CLK			0x0D4 0x2C4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_SAI2_RX_BCLK			0x0D4 0x2C4 0x5B4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_CSI_DATA07			0x0D4 0x2C4 0x414 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPIO1_IO06			0x0D4 0x2C4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_XBAR_INOUT18			0x0D4 0x2C4 0x630 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_LPSPI3_PCS3			0x0D4 0x2C4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_JTAG_TCK				0x0D8 0x2C8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPT2_COMPARE2			0x0D8 0x2C8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_TX_ER			0x0D8 0x2C8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_SAI2_RX_SYNC			0x0D8 0x2C8 0x5BC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_CSI_DATA06			0x0D8 0x2C8 0x410 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPIO1_IO07			0x0D8 0x2C8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_XBAR_INOUT19			0x0D8 0x2C8 0x654 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_1588_EVENT3_OUT		0x0D8 0x2C8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_JTAG_MOD				0x0DC 0x2CC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPT2_COMPARE3			0x0DC 0x2CC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_RX_DATA03			0x0DC 0x2CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_SAI2_RX_DATA			0x0DC 0x2CC 0x5B8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_CSI_DATA05			0x0DC 0x2CC 0x40C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPIO1_IO08			0x0DC 0x2CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_XBAR_INOUT20			0x0DC 0x2CC 0x634 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_1588_EVENT3_IN		0x0DC 0x2CC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_JTAG_TDI				0x0E0 0x2D0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_FLEXPWM2_PWM3_A			0x0E0 0x2D0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_ENET_RX_DATA02			0x0E0 0x2D0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_SAI2_TX_DATA			0x0E0 0x2D0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_CSI_DATA04			0x0E0 0x2D0 0x408 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPIO1_IO09			0x0E0 0x2D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_XBAR_INOUT21			0x0E0 0x2D0 0x658 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPT2_CLK				0x0E0 0x2D0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_JTAG_TDO				0x0E4 0x2D4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWM3_A			0x0E4 0x2D4 0x454 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_CRS				0x0E4 0x2D4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_SAI2_MCLK				0x0E4 0x2D4 0x5B0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_CSI_DATA03			0x0E4 0x2D4 0x404 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_GPIO1_IO10			0x0E4 0x2D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_XBAR_INOUT22			0x0E4 0x2D4 0x638 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_1588_EVENT0_OUT		0x0E4 0x2D4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_JTAG_TRSTB			0x0E8 0x2D8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_FLEXPWM1_PWM3_B			0x0E8 0x2D8 0x464 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_COL				0x0E8 0x2D8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_WDOG1_B				0x0E8 0x2D8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_CSI_DATA02			0x0E8 0x2D8 0x400 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_GPIO1_IO11			0x0E8 0x2D8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_XBAR_INOUT23			0x0E8 0x2D8 0x63C 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_1588_EVENT0_IN		0x0E8 0x2D8 0x444 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL			0x0EC 0x2DC 0x4E4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_CCM_PMIC_READY			0x0EC 0x2DC 0x3FC 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD			0x0EC 0x2DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_WDOG2_B				0x0EC 0x2DC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_FLEXPWM1_PWM2_X			0x0EC 0x2DC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_GPIO1_IO12			0x0EC 0x2DC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_ENET_1588_EVENT1_OUT		0x0EC 0x2DC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_NMI				0x0EC 0x2DC 0x568 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA			0x0F0 0x2E0 0x4E8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPT1_CLK				0x0F0 0x2E0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD			0x0F0 0x2E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_EWM_OUT_B				0x0F0 0x2E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_FLEXPWM1_PWM3_X			0x0F0 0x2E0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPIO1_IO13			0x0F0 0x2E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_ENET_1588_EVENT1_IN		0x0F0 0x2E0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_REF_CLK_24M			0x0F0 0x2E0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_USB_OTG2_OC			0x0F4 0x2E4 0x5CC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_XBAR_INOUT24			0x0F4 0x2E4 0x640 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_LPUART1_CTS_B			0x0F4 0x2E4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_ENET_1588_EVENT0_OUT		0x0F4 0x2E4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_CSI_VSYNC				0x0F4 0x2E4 0x428 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_GPIO1_IO14			0x0F4 0x2E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX			0x0F4 0x2E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_USB_OTG2_PWR			0x0F8 0x2E8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_XBAR_INOUT25			0x0F8 0x2E8 0x650 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_LPUART1_RTS_B			0x0F8 0x2E8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_ENET_1588_EVENT0_IN		0x0F8 0x2E8 0x444 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_CSI_HSYNC				0x0F8 0x2E8 0x420 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_GPIO1_IO15			0x0F8 0x2E8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX			0x0F8 0x2E8 0x450 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_WDOG1_WDOG_RST_B_DEB		0x0F8 0x2E8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USB_OTG2_ID			0x0FC 0x2EC 0x3F8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_TMR3_TIMER0			0x0FC 0x2EC 0x57C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPUART2_CTS_B			0x0FC 0x2EC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL			0x0FC 0x2EC 0x4CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_WDOG1_B				0x0FC 0x2EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_GPIO1_IO16			0x0FC 0x2EC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USDHC1_WP				0x0FC 0x2EC 0x5D8 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_KPP_ROW07				0x0FC 0x2EC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USB_OTG1_PWR			0x100 0x2F0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_TMR3_TIMER1			0x100 0x2F0 0x580 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPUART2_RTS_B			0x100 0x2F0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA			0x100 0x2F0 0x4D0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_CCM_PMIC_READY			0x100 0x2F0 0x3FC 0x4 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_GPIO1_IO17			0x100 0x2F0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USDHC1_VSELECT			0x100 0x2F0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_KPP_COL07				0x100 0x2F0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USB_OTG1_ID			0x104 0x2F4 0x3F4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_TMR3_TIMER2			0x104 0x2F4 0x584 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_LPUART2_TXD			0x104 0x2F4 0x530 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_SPDIF_OUT				0x104 0x2F4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_ENET_1588_EVENT2_OUT		0x104 0x2F4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_GPIO1_IO18			0x104 0x2F4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USDHC1_CD_B			0x104 0x2F4 0x5D4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_KPP_ROW06				0x104 0x2F4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USB_OTG1_OC			0x108 0x2F8 0x5D0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_TMR3_TIMER3			0x108 0x2F8 0x588 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_LPUART2_RXD			0x108 0x2F8 0x52C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_SPDIF_IN				0x108 0x2F8 0x5C8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_ENET_1588_EVENT2_IN		0x108 0x2F8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_GPIO1_IO19			0x108 0x2F8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USDHC2_CD_B			0x108 0x2F8 0x5E0 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_KPP_COL06				0x108 0x2F8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_FLEXSPI_B_DATA3			0x10C 0x2FC 0x4C4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_ENET_MDC				0x10C 0x2FC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_LPUART3_CTS_B			0x10C 0x2FC 0x534 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_SPDIF_SR_CLK			0x10C 0x2FC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK			0x10C 0x2FC 0x424 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_GPIO1_IO20			0x10C 0x2FC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_USDHC2_DATA0			0x10C 0x2FC 0x5E8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_KPP_ROW05				0x10C 0x2FC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_FLEXSPI_B_DATA2			0x110 0x300 0x4C0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_ENET_MDIO				0x110 0x300 0x430 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_LPUART3_RTS_B			0x110 0x300 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_SPDIF_OUT				0x110 0x300 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_CSI_MCLK				0x110 0x300 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_GPIO1_IO21			0x110 0x300 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_USDHC2_DATA1			0x110 0x300 0x5EC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_KPP_COL05				0x110 0x300 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_FLEXSPI_B_DATA1			0x114 0x304 0x4BC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA			0x114 0x304 0x4E0 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPUART3_TXD			0x114 0x304 0x53C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_SPDIF_LOCK			0x114 0x304 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_CSI_VSYNC				0x114 0x304 0x428 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_GPIO1_IO22			0x114 0x304 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_USDHC2_DATA2			0x114 0x304 0x5F0 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_KPP_ROW04				0x114 0x304 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_FLEXSPI_B_DATA0			0x118 0x308 0x4B8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL			0x118 0x308 0x4DC 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPUART3_RXD			0x118 0x308 0x538 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_SPDIF_EXT_CLK			0x118 0x308 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_CSI_HSYNC				0x118 0x308 0x420 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_GPIO1_IO23			0x118 0x308 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_USDHC2_DATA3			0x118 0x308 0x5F4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_KPP_COL04				0x118 0x308 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXSPI_A_SS1_B			0x11C 0x30C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXPWM4_PWM0_A			0x11C 0x30C 0x494 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX			0x11C 0x30C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CCM_PMIC_READY			0x11C 0x30C 0x3FC 0x3 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CSI_DATA09			0x11C 0x30C 0x41C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_GPIO1_IO24			0x11C 0x30C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_USDHC2_CMD			0x11C 0x30C 0x5E4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_KPP_ROW03				0x11C 0x30C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXSPI_A_DQS			0x120 0x310 0x4A4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXPWM4_PWM1_A			0x120 0x310 0x498 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX			0x120 0x310 0x44C 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_SAI1_MCLK				0x120 0x310 0x58C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_CSI_DATA08			0x120 0x310 0x418 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_GPIO1_IO25			0x120 0x310 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_USDHC2_CLK			0x120 0x310 0x5DC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_KPP_COL03				0x120 0x310 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_FLEXSPI_A_DATA3			0x124 0x314 0x4B4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_WDOG1_B				0x124 0x314 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_LPUART8_TXD			0x124 0x314 0x564 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_SAI1_RX_SYNC			0x124 0x314 0x5A4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_CSI_DATA07			0x124 0x314 0x414 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_GPIO1_IO26			0x124 0x314 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_USDHC2_WP				0x124 0x314 0x608 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_KPP_ROW02				0x124 0x314 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_FLEXSPI_A_DATA2			0x128 0x318 0x4B0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_EWM_OUT_B				0x128 0x318 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_LPUART8_RXD			0x128 0x318 0x560 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_SAI1_RX_BCLK			0x128 0x318 0x590 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_CSI_DATA06			0x128 0x318 0x410 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_GPIO1_IO27			0x128 0x318 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_USDHC2_RESET_B			0x128 0x318 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_KPP_COL02				0x128 0x318 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_FLEXSPI_A_DATA1			0x12C 0x31C 0x4AC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_ACMP1_OUT				0x12C 0x31C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0			0x12C 0x31C 0x50C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00			0x12C 0x31C 0x594 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_CSI_DATA05			0x12C 0x31C 0x40C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_GPIO1_IO28			0x12C 0x31C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_USDHC2_DATA4			0x12C 0x31C 0x5F8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_KPP_ROW01				0x12C 0x31C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_FLEXSPI_A_DATA0			0x130 0x320 0x4A8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_ACMP2_OUT				0x130 0x320 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI			0x130 0x320 0x514 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00			0x130 0x320 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_CSI_DATA04			0x130 0x320 0x408 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_GPIO1_IO29			0x130 0x320 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_USDHC2_DATA5			0x130 0x320 0x5FC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_KPP_COL01				0x130 0x320 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_FLEXSPI_A_SCLK			0x134 0x324 0x4C8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_ACMP3_OUT				0x134 0x324 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO			0x134 0x324 0x518 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK			0x134 0x324 0x5A8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_CSI_DATA03			0x134 0x324 0x404 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_GPIO1_IO30			0x134 0x324 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_USDHC2_DATA6			0x134 0x324 0x600 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_KPP_ROW00				0x134 0x324 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_FLEXSPI_A_SS0_B			0x138 0x328 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_ACMP4_OUT				0x138 0x328 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK			0x138 0x328 0x510 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC			0x138 0x328 0x5AC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_CSI_DATA02			0x138 0x328 0x400 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_GPIO1_IO31			0x138 0x328 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_USDHC2_DATA7			0x138 0x328 0x604 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_KPP_COL00				0x138 0x328 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_00_LCD_CLK				0x13C 0x32C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_TMR1_TIMER0				0x13C 0x32C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_MQS_RIGHT				0x13C 0x32C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_LPSPI4_PCS0				0x13C 0x32C 0x51C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_FLEXIO2_D00				0x13C 0x32C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_GPIO2_IO00				0x13C 0x32C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_SEMC_CSX1				0x13C 0x32C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_01_LCD_ENABLE				0x140 0x330 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_TMR1_TIMER1				0x140 0x330 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_MQS_LEFT				0x140 0x330 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_LPSPI4_SDI				0x140 0x330 0x524 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_FLEXIO2_D01				0x140 0x330 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_GPIO2_IO01				0x140 0x330 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_SEMC_CSX2				0x140 0x330 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_02_LCD_HSYNC				0x144 0x334 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_TMR1_TIMER2				0x144 0x334 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXCAN1_TX				0x144 0x334 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_LPSPI4_SDO				0x144 0x334 0x528 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXIO2_D02				0x144 0x334 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_GPIO2_IO02				0x144 0x334 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_SEMC_CSX3				0x144 0x334 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_03_LCD_VSYNC				0x148 0x338 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_TMR2_TIMER0				0x148 0x338 0x56C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXCAN1_RX				0x148 0x338 0x44C 0x2 0x3
+#define MXRT1050_IOMUXC_GPIO_B0_03_LPSPI4_SCK				0x148 0x338 0x520 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXIO2_D03				0x148 0x338 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_GPIO2_IO03				0x148 0x338 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_WDOG2_RESET_B_DEB			0x148 0x338 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_04_LCD_DATA00				0x14C 0x33C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_TMR2_TIMER1				0x14C 0x33C 0x570 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_LPI2C2_SCL				0x14C 0x33C 0x4D4 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_ARM_TRACE00				0x14C 0x33C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_FLEXIO2_D04				0x14C 0x33C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_GPIO2_IO04				0x14C 0x33C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_SRC_BT_CFG00				0x14C 0x33C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_05_LCD_DATA01				0x150 0x340 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_TMR2_TIMER2				0x150 0x340 0x574 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_LPI2C2_SDA				0x150 0x340 0x4D8 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_ARM_TRACE01				0x150 0x340 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_FLEXIO2_D05				0x150 0x340 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_GPIO2_IO05				0x150 0x340 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_SRC_BT_CFG01				0x150 0x340 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_06_LCD_DATA02				0x154 0x344 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_TMR3_TIMER0				0x154 0x344 0x57C 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXPWM2_PWM0_A			0x154 0x344 0x478 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_06_ARM_TRACE02				0x154 0x344 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXIO2_D06				0x154 0x344 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_GPIO2_IO06				0x154 0x344 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_SRC_BT_CFG02				0x154 0x344 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_07_LCD_DATA03				0x158 0x348 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_TMR3_TIMER1				0x158 0x348 0x580 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXPWM2_PWM0_B			0x158 0x348 0x488 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_07_ARM_TRACE03				0x158 0x348 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXIO2_D07				0x158 0x348 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_GPIO2_IO07				0x158 0x348 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_SRC_BT_CFG03				0x158 0x348 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_08_LCD_DATA04				0x15C 0x34C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_TMR3_TIMER2				0x15C 0x34C 0x584 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXPWM2_PWM1_A			0x15C 0x34C 0x47C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_08_LPUART3_TXD				0x15C 0x34C 0x53C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXIO2_D08				0x15C 0x34C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_GPIO2_IO08				0x15C 0x34C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_SRC_BT_CFG04				0x15C 0x34C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_09_LCD_DATA05				0x160 0x350 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_TMR4_TIMER0				0x160 0x350 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXPWM2_PWM1_B			0x160 0x350 0x48C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_09_LPUART3_RXD				0x160 0x350 0x538 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXIO2_D09				0x160 0x350 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_GPIO2_IO09				0x160 0x350 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_SRC_BT_CFG05				0x160 0x350 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_10_LCD_DATA06				0x164 0x354 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_TMR4_TIMER1				0x164 0x354 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXPWM2_PWM2_A			0x164 0x354 0x480 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_SAI1_TX_DATA03			0x164 0x354 0x598 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXIO2_D10				0x164 0x354 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_GPIO2_IO10				0x164 0x354 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_SRC_BT_CFG06				0x164 0x354 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_11_LCD_DATA07				0x168 0x358 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_TMR4_TIMER2				0x168 0x358 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXPWM2_PWM2_B			0x168 0x358 0x490 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_SAI1_TX_DATA02			0x168 0x358 0x59C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXIO2_D11				0x168 0x358 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_GPIO2_IO11				0x168 0x358 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_SRC_BT_CFG07				0x168 0x358 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_12_LCD_DATA08				0x16C 0x35C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_XBAR_INOUT10				0x16C 0x35C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_ARM_TRACE_CLK			0x16C 0x35C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SAI1_TX_DATA01			0x16C 0x35C 0x5A0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_12_FLEXIO2_D12				0x16C 0x35C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_GPIO2_IO12				0x16C 0x35C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SRC_BT_CFG08				0x16C 0x35C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_13_LCD_DATA09				0x170 0x360 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_XBAR_INOUT11				0x170 0x360 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_ARM_TRACE_SWO			0x170 0x360 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SAI1_MCLK				0x170 0x360 0x58C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_13_FLEXIO2_D13				0x170 0x360 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_GPIO2_IO13				0x170 0x360 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SRC_BT_CFG09				0x170 0x360 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_14_LCD_DATA10				0x174 0x364 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_XBAR_INOUT12				0x174 0x364 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_ARM_CM7_TXEV				0x174 0x364 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SAI1_RX_SYNC				0x174 0x364 0x5A4 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_14_FLEXIO2_D14				0x174 0x364 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_GPIO2_IO14				0x174 0x364 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SRC_BT_CFG10				0x174 0x364 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_15_LCD_DATA11				0x178 0x368 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_XBAR_INOUT13				0x178 0x368 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_ARM_CM7_RXEV				0x178 0x368 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SAI1_RX_BCLK				0x178 0x368 0x590 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_15_FLEXIO2_D15				0x178 0x368 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_GPIO2_IO15				0x178 0x368 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SRC_BT_CFG11				0x178 0x368 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_00_LCD_DATA12				0x17C 0x36C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_XBAR_INOUT14				0x17C 0x36C 0x644 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_00_LPUART4_TXD				0x17C 0x36C 0x544 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_SAI1_RX_DATA00			0x17C 0x36C 0x594 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXIO2_D16				0x17C 0x36C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_GPIO2_IO16				0x17C 0x36C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXPWM1_PWM3_A			0x17C 0x36C 0x454 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_01_LCD_DATA13				0x180 0x370 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_XBAR_INOUT15				0x180 0x370 0x648 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_01_LPUART4_RXD				0x180 0x370 0x540 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_01_SAI1_TX_DATA00			0x180 0x370 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXIO2_D17				0x180 0x370 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_GPIO2_IO17				0x180 0x370 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXPWM1_PWM3_B			0x180 0x370 0x464 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_02_LCD_DATA14				0x184 0x374 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_XBAR_INOUT16				0x184 0x374 0x64C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_02_LPSPI4_PCS2				0x184 0x374 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_SAI1_TX_BCLK				0x184 0x374 0x5A8 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXIO2_D18				0x184 0x374 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_GPIO2_IO18				0x184 0x374 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXPWM2_PWM3_A			0x184 0x374 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_03_LCD_DATA15				0x188 0x378 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_XBAR_INOUT17				0x188 0x378 0x62C 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_B1_03_LPSPI4_PCS1				0x188 0x378 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_SAI1_TX_SYNC				0x188 0x378 0x5AC 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXIO2_D19				0x188 0x378 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_GPIO2_IO19				0x188 0x378 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXPWM2_PWM3_B			0x188 0x378 0x484 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_04_LCD_DATA16				0x18C 0x37C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_LPSPI4_PCS0				0x18C 0x37C 0x51C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_CSI_DATA15				0x18C 0x37C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_ENET_RX_DATA00			0x18C 0x37C 0x434 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_FLEXIO2_D20				0x18C 0x37C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_GPIO2_IO20				0x18C 0x37C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_05_LCD_DATA17				0x190 0x380 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_LPSPI4_SDI				0x190 0x380 0x524 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_CSI_DATA14				0x190 0x380 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_ENET_RX_DATA01			0x190 0x380 0x438 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_FLEXIO2_D21				0x190 0x380 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_GPIO2_IO21				0x190 0x380 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_06_LCD_DATA18				0x194 0x384 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_LPSPI4_SDO				0x194 0x384 0x528 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_CSI_DATA13				0x194 0x384 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_ENET_RX_EN				0x194 0x384 0x43C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_FLEXIO2_D22				0x194 0x384 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_GPIO2_IO22				0x194 0x384 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_07_LCD_DATA19				0x198 0x388 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_LPSPI4_SCK				0x198 0x388 0x520 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_07_CSI_DATA12				0x198 0x388 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_ENET_TX_DATA00			0x198 0x388 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_FLEXIO2_D23				0x198 0x388 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_GPIO2_IO23				0x198 0x388 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_08_LCD_DATA20				0x19C 0x38C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_TMR1_TIMER3				0x19C 0x38C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_CSI_DATA11				0x19C 0x38C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_ENET_TX_DATA01			0x19C 0x38C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXIO2_D24				0x19C 0x38C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_GPIO2_IO24				0x19C 0x38C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXCAN2_TX				0x19C 0x38C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_09_LCD_DATA21				0x1A0 0x390 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_TMR2_TIMER3				0x1A0 0x390 0x578 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_09_CSI_DATA10				0x1A0 0x390 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_ENET_TX_EN				0x1A0 0x390 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXIO2_D25				0x1A0 0x390 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_GPIO2_IO25				0x1A0 0x390 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXCAN2_RX				0x1A0 0x390 0x450 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_10_LCD_DATA22				0x1A4 0x394 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_TMR3_TIMER3				0x1A4 0x394 0x588 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_10_CSI_DATA00				0x1A4 0x394 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_TX_CLK				0x1A4 0x394 0x448 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_10_FLEXIO2_D26				0x1A4 0x394 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_GPIO2_IO26				0x1A4 0x394 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_REF_CLK				0x1A4 0x394 0x42C 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_B1_11_LCD_DATA23				0x1A8 0x398 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_TMR4_TIMER3				0x1A8 0x398 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_CSI_DATA01				0x1A8 0x398 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_ENET_RX_ER				0x1A8 0x398 0x440 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_11_FLEXIO2_D27				0x1A8 0x398 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_GPIO2_IO27				0x1A8 0x398 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_LPSPI4_PCS3				0x1A8 0x398 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_12_LPUART5_TXD				0x1AC 0x39C 0x54C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_CSI_PIXCLK				0x1AC 0x39C 0x424 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_ENET_1588_EVENT0_IN			0x1AC 0x39C 0x444 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_12_FLEXIO2_D28				0x1AC 0x39C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_GPIO2_IO28				0x1AC 0x39C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B				0x1AC 0x39C 0x5D4 0x6 0x2
+
+#define MXRT1050_IOMUXC_GPIO_B1_13_WDOG1_B				0x1B0 0x3A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_LPUART5_RXD				0x1B0 0x3A0 0x548 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_13_CSI_VSYNC				0x1B0 0x3A0 0x428 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_13_ENET_1588_EVENT0_OUT			0x1B0 0x3A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_FLEXIO2_D29				0x1B0 0x3A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_GPIO2_IO29				0x1B0 0x3A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_USDHC1_WP				0x1B0 0x3A0 0x5D8 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_14_ENET_MDC				0x1B4 0x3A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXPWM4_PWM2_A			0x1B4 0x3A4 0x49C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_CSI_HSYNC				0x1B4 0x3A4 0x420 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_14_XBAR_INOUT02				0x1B4 0x3A4 0x60C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXIO2_D30				0x1B4 0x3A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_GPIO2_IO30				0x1B4 0x3A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT			0x1B4 0x3A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_15_ENET_MDIO				0x1B8 0x3A8 0x430 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXPWM4_PWM3_A			0x1B8 0x3A8 0x4A0 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_CSI_MCLK				0x1B8 0x3A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_XBAR_INOUT03				0x1B8 0x3A8 0x610 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXIO2_D31				0x1B8 0x3A8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_GPIO2_IO31				0x1B8 0x3A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_USDHC1_RESET_B			0x1B8 0x3A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD			0x1BC 0x3AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXPWM1_PWM0_A			0x1BC 0x3AC 0x458 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPI2C3_SCL			0x1BC 0x3AC 0x4DC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_XBAR_INOUT04			0x1BC 0x3AC 0x614 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK			0x1BC 0x3AC 0x4F0 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_GPIO3_IO12			0x1BC 0x3AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXSPI_A_SS1_B			0x1BC 0x3AC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK			0x1C0 0x3B0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXPWM1_PWM0_B			0x1C0 0x3B0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPI2C3_SDA			0x1C0 0x3B0 0x4E0 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_XBAR_INOUT05			0x1C0 0x3B0 0x618 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0			0x1C0 0x3B0 0x4EC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_GPIO3_IO13			0x1C0 0x3B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXSPI_B_SS1_B			0x1C0 0x3B0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0			0x1C4 0x3B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_FLEXPWM1_PWM1_A			0x1C4 0x3B4 0x45C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPUART8_CTS_B			0x1C4 0x3B4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_XBAR_INOUT06			0x1C4 0x3B4 0x61C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO			0x1C4 0x3B4 0x4F8 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_GPIO3_IO14			0x1C4 0x3B4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1			0x1C8 0x3B8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_FLEXPWM1_PWM1_B			0x1C8 0x3B8 0x46C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPUART8_RTS_B			0x1C8 0x3B8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_XBAR_INOUT07			0x1C8 0x3B8 0x620 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI			0x1C8 0x3B8 0x4F4 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_GPIO3_IO15			0x1C8 0x3B8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2			0x1CC 0x3BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXPWM1_PWM2_A			0x1CC 0x3BC 0x460 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_LPUART8_TXD			0x1CC 0x3BC 0x564 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_XBAR_INOUT08			0x1CC 0x3BC 0x624 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXSPI_B_SS0_B			0x1CC 0x3BC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_GPIO3_IO16			0x1CC 0x3BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_CCM_CLKO1				0x1CC 0x3BC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3			0x1D0 0x3C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXPWM1_PWM2_B			0x1D0 0x3C0 0x470 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_LPUART8_RXD			0x1D0 0x3C0 0x560 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_XBAR_INOUT09			0x1D0 0x3C0 0x628 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXSPI_B_DQS			0x1D0 0x3C0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_GPIO3_IO17			0x1D0 0x3C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_CCM_CLKO2				0x1D0 0x3C0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3			0x1D4 0x3C4 0x5F4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3			0x1D4 0x3C4 0x4C4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXPWM1_PWM3_A			0x1D4 0x3C4 0x454 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_SAI1_TX_DATA03			0x1D4 0x3C4 0x598 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_LPUART4_TXD			0x1D4 0x3C4 0x544 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_GPIO3_IO00			0x1D4 0x3C4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2			0x1D8 0x3C8 0x5F0 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2			0x1D8 0x3C8 0x4C0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXPWM1_PWM3_B			0x1D8 0x3C8 0x464 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_SAI1_TX_DATA02			0x1D8 0x3C8 0x59C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_LPUART4_RXD			0x1D8 0x3C8 0x540 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_GPIO3_IO01			0x1D8 0x3C8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1			0x1DC 0x3CC 0x5EC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1			0x1DC 0x3CC 0x4BC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWM3_A			0x1DC 0x3CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_SAI1_TX_DATA01			0x1DC 0x3CC 0x5A0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXCAN1_TX			0x1DC 0x3CC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_GPIO3_IO02			0x1DC 0x3CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_CCM_WAIT				0x1DC 0x3CC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0			0x1E0 0x3D0 0x5E8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0			0x1E0 0x3D0 0x4B8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWM3_B			0x1E0 0x3D0 0x484 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_SAI1_MCLK				0x1E0 0x3D0 0x58C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXCAN1_RX			0x1E0 0x3D0 0x44C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_GPIO3_IO03			0x1E0 0x3D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_CCM_PMIC_READY			0x1E0 0x3D0 0x3FC 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_USDHC2_CLK			0x1E4 0x3D4 0x5DC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK			0x1E4 0x3D4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_LPI2C1_SCL			0x1E4 0x3D4 0x4CC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_SAI1_RX_SYNC			0x1E4 0x3D4 0x5A4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXCAN1_A_SS1_B			0x1E4 0x3D4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_GPIO3_IO04			0x1E4 0x3D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_CCM_STOP				0x1E4 0x3D4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_USDHC2_CMD			0x1E8 0x3D8 0x5E4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS			0x1E8 0x3D8 0x4A4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_LPI2C1_SDA			0x1E8 0x3D8 0x4D0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_SAI1_RX_BCLK			0x1E8 0x3D8 0x590 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXCAN1_B_SS0_B			0x1E8 0x3D8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_GPIO3_IO05			0x1E8 0x3D8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_USDHC2_RESET_B			0x1EC 0x3DC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B			0x1EC 0x3DC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPUART7_CTS_B			0x1EC 0x3DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_SAI1_RX_DATA00			0x1EC 0x3DC 0x594 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPSPI2_PCS0			0x1EC 0x3DC 0x4FC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_GPIO3_IO06			0x1EC 0x3DC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SEMC_CSX1				0x1F0 0x3E0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK			0x1F0 0x3E0 0x4C8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPUART7_RTS_B			0x1F0 0x3E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SAI1_TX_DATA00			0x1F0 0x3E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK			0x1F0 0x3E0 0x500 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_GPIO3_IO07			0x1F0 0x3E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_CCM_REF_EN_B			0x1F0 0x3E0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4			0x1F4 0x3E4 0x5F8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA0			0x1F4 0x3E4 0x4A8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPUART7_TXD			0x1F4 0x3E4 0x55C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SAI1_TX_BLCK			0x1F4 0x3E4 0x5A8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPSPI2_SDO			0x1F4 0x3E4 0x508 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_GPIO3_IO08			0x1F4 0x3E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SEMC_CSX2				0x1F4 0x3E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5			0x1F8 0x3E8 0x5FC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1			0x1F8 0x3E8 0x4AC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPUART7_RXD			0x1F8 0x3E8 0x558 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_SAI1_TX_SYNC			0x1F8 0x3E8 0x5AC 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI			0x1F8 0x3E8 0x504 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_GPIO3_IO09			0x1F8 0x3E8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6			0x1FC 0x3EC 0x600 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2			0x1FC 0x3EC 0x4B0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPUART2_RXD			0x1FC 0x3EC 0x52C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPI2C2_SDA			0x1FC 0x3EC 0x4D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPSPI2_PCS2			0x1FC 0x3EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_GPIO3_IO10			0x1FC 0x3EC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7			0x200 0x3F0 0x604 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3			0x200 0x3F0 0x4B4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPUART2_TXD			0x200 0x3F0 0x530 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPI2C2_SCL			0x200 0x3F0 0x4D4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPSPI2_PCS3			0x200 0x3F0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_GPIO3_IO11			0x200 0x3F0 0x000 0x5 0x0
+
+#endif /* _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:46 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:46 -0500
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-6-Mr.Bossman075@gmail.com>

Add clock driver support for i.MXRT1050.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
---
V1->V2:
* Kconfig: Add new line
* clk-imxrt.c: Remove unused const
* clk-imxrt.c: Remove set parents
* clk-imxrt.c: Use fsl,imxrt-anatop for anatop base address
V2->V3:
* Remove unused ANATOP_BASE_ADDR
* Move to hw API
* Add GPT's own clock
* Add SEMC clocks to set muxing to CRITICAL
V3->V4:
* Rename clk-imxrt.c to clk-imxrt1050.c
* Rename CONFIG_CLK_IMXRT to CONFIG_CLK_IMXRT1050
* Make CONFIG_CLK_IMXRT1050 selectable
V4->V5:
* Move to platform driver
V5->V6:
* Remove "fsl" from platform driver name
V6->V7:
* Remove GPT
* Remove of_match_ptr
---
 drivers/clk/imx/Kconfig         |   5 +
 drivers/clk/imx/Makefile        |   1 +
 drivers/clk/imx/clk-imxrt1050.c | 181 ++++++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index c08edbd04d22..f697652ab19c 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -105,3 +105,8 @@ config CLK_IMX8ULP
 	select MXC_CLK
 	help
 	    Build the driver for i.MX8ULP CCM Clock Driver
+
+config CLK_IMXRT1050
+	bool "IMXRT1050 CCM Clock Driver"
+	depends on SOC_IMXRT
+	select MXC_CLK
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index b5e040026dfb..3d9a1e3b5fc6 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
 obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
 obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
 obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
+obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
new file mode 100644
index 000000000000..a2f0e8663030
--- /dev/null
+++ b/drivers/clk/imx/clk-imxrt1050.c
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2021
+ * Author(s):
+ * Jesse Taube <Mr.Bossman075 at gmail.com>
+ * Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sizes.h>
+#include <linux/platform_device.h>
+#include <soc/imx/revision.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+
+#include "clk.h"
+
+static const char * const pll_ref_sels[] = {"osc", "dummy", };
+static const char * const per_sels[] = {"ipg_pdof", "osc", };
+static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
+static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
+static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
+static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
+static const char *const pre_periph_sels[] = {
+	"pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
+static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
+static const char *const lcdif_sels[] = {
+	"pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
+	"pll2_pfd1_594m", "pll3_pfd1_664_62m", };
+static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
+static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
+
+static struct clk_hw **hws;
+static struct clk_hw_onecell_data *clk_hw_data;
+
+static void __init imxrt_clocks_common_init(void __iomem *base)
+{
+	/* Anatop clocks */
+	hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
+
+	hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
+		base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
+		base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
+		base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
+		base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
+		"pll1_arm_ref_sel", base + 0x0, 0x7f);
+	hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
+		"pll2_sys_ref_sel", base + 0x30, 0x1);
+	hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
+		"pll3_usb_otg_ref_sel", base + 0x10, 0x1);
+	hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
+		"pll5_video_ref_sel", base + 0xa0, 0x7f);
+
+	/* PLL bypass out */
+	hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x0, 16, 1,
+		pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1,
+		pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1,
+		pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1,
+		pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+
+	hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
+		"pll5_video", base + 0xa0, 19, 2);
+	hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
+		"video_post_div_sel", base + 0x170, 30, 2);
+
+	hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
+
+	hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", base + 0x100, 0);
+	hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", base + 0x100, 1);
+	hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", base + 0x100, 2);
+	hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", base + 0xf0, 1);
+	hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", base + 0xf0, 3);
+}
+
+static int imxrt1050_clocks_probe(struct platform_device *pdev)
+{
+	void __iomem *ccm_base;
+	void __iomem *pll_base;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *anp;
+	int ret;
+
+	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+					  IMXRT1050_CLK_END), GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMXRT1050_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
+
+	anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
+	pll_base = of_iomap(anp, 0);
+	of_node_put(anp);
+	if (WARN_ON(!pll_base))
+		return -ENOMEM;
+	imxrt_clocks_common_init(pll_base);
+	/* CCM clocks */
+	ccm_base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(ccm_base)))
+		return PTR_ERR(ccm_base);
+
+	hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
+	hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
+		pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+	hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
+		periph_sels, ARRAY_SIZE(periph_sels));
+	hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
+		lpuart_sels, ARRAY_SIZE(lpuart_sels));
+	hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
+		lcdif_sels, ARRAY_SIZE(lcdif_sels));
+	hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
+		per_sels, ARRAY_SIZE(per_sels));
+	hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
+		semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
+	hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
+		semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
+
+	hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
+	hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
+	hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
+
+	hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
+	hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
+	hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
+	hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
+	hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
+
+	hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
+	hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
+	hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
+	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
+	hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
+	hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
+	imx_check_clk_hws(hws, IMXRT1050_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
+		imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
+		return ret;
+	}
+	return 0;
+}
+static const struct of_device_id imxrt1050_clk_of_match[] = {
+	{ .compatible = "fsl,imxrt1050-ccm" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
+
+static struct platform_driver imxrt1050_clk_driver = {
+	.probe = imxrt1050_clocks_probe,
+	.driver = {
+		.name = "imxrt1050-ccm",
+		.of_match_table = imxrt1050_clk_of_match,
+	},
+};
+module_platform_driver(imxrt1050_clk_driver);
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:47 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:47 -0500
Subject: [PATCH v7 6/7] ARM: dts: imx: Add i.MXRT1050-EVK support
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-7-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The NXP i.MXRT1050 Evaluation Kit (EVK) provides a platform for rapid
evaluation of the i.MXRT, which features NXP's implementation of the Arm
Cortex-M7 core.

The EVK provides 32 MB SDRAM, 64 MB Quad SPI flash, Micro SD card socket,
USB 2.0 OTG.

This patch aims to support the preliminary booting up features
as follows:
GPIO
LPUART
SD/MMC

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: Add clock-parents, edma, usdhc, anatop, remove old pinctl]
---
V1->V2:
* dtsi: Add clock parent definitions
* dtsi: Change hex values to lowercase
* dtsi: Move anatop definition from driver
* dts: Remove unused pin controll (semc)
* dts: Use moved pin controll header
* Move aliases from dtsi to dts
* Change commit description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Remove bootargs, comments, unused container
* Remove unnecessary new lines
* Rename imxrt to imxrt1050 for seiral and mmc
* GPT uses own clock
* fix memory at 0
* Change GPT compatible handles
V3->V4:
* Remove "fsl,imx-osc"
* Add space on serial compatible
* Change "iomuxc@" to "pinctrl@"
* Change "ccm@" to "clock-controller@"
* Change "fsl,imxrt-gpio" to "fsl,imxrt1050-gpio"
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Add fixed clock for GPT
* Fix lpuart compatible
* Add usdhc compatible
---
 arch/arm/boot/dts/Makefile          |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts |  72 +++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi    | 160 ++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..07acd6189cae 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_IMXRT) += \
+	imxrt1050-evk.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/imxrt1050-evk.dts b/arch/arm/boot/dts/imxrt1050-evk.dts
new file mode 100644
index 000000000000..6a9c10decf52
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-evk.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+/dts-v1/;
+#include "imxrt1050.dtsi"
+#include "imxrt1050-pinfunc.h"
+
+/ {
+	model = "NXP IMXRT1050-evk board";
+	compatible = "fsl,imxrt1050-evk", "fsl,imxrt1050";
+
+	chosen {
+		stdout-path = &lpuart1;
+	};
+
+	aliases {
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		mmc0 = &usdhc1;
+		serial0 = &lpuart1;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x2000000>;
+	};
+};
+
+&lpuart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart1>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl_lpuart1: lpuart1grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD	0xf1
+			MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD	0xf1
+		>;
+	};
+
+	pinctrl_usdhc0: usdhc0grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B		0x1B000
+			MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT	0xB069
+			MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0	0x17061
+		>;
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+	pinctrl-0 = <&pinctrl_usdhc0>;
+	pinctrl-1 = <&pinctrl_usdhc0>;
+	pinctrl-2 = <&pinctrl_usdhc0>;
+	pinctrl-3 = <&pinctrl_usdhc0>;
+	cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imxrt1050.dtsi b/arch/arm/boot/dts/imxrt1050.dtsi
new file mode 100644
index 000000000000..77b911b06041
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050.dtsi
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include "armv7-m.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	clocks {
+		osc: osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+		};
+
+		osc3M: osc3M {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <3000000>;
+		};
+	};
+
+	soc {
+		lpuart1: serial at 40184000 {
+			compatible = "fsl,imxrt1050-lpuart", "fsl,imx7ulp-lpuart";
+			reg = <0x40184000 0x4000>;
+			interrupts = <20>;
+			clocks = <&clks IMXRT1050_CLK_LPUART1>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		iomuxc: pinctrl at 401f8000 {
+			compatible = "fsl,imxrt1050-iomuxc";
+			reg = <0x401f8000 0x4000>;
+			fsl,mux_mask = <0x7>;
+		};
+
+		anatop: anatop at 400d8000 {
+			compatible = "fsl,imxrt-anatop";
+			reg = <0x400d8000 0x4000>;
+		};
+
+		clks: clock-controller at 400fc000 {
+			compatible = "fsl,imxrt1050-ccm";
+			reg = <0x400fc000 0x4000>;
+			interrupts = <95>, <96>;
+			clocks = <&osc>;
+			clock-names = "osc";
+			#clock-cells = <1>;
+			assigned-clocks = <&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL2_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_PFD1_664_62M>,
+				<&clks IMXRT1050_CLK_PLL2_PFD2_396M>;
+			assigned-clock-parents = <&clks IMXRT1050_CLK_PLL1_REF_SEL>,
+				<&clks IMXRT1050_CLK_PLL1_ARM>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>;
+		};
+
+		edma1: dma-controller at 400e8000 {
+			#dma-cells = <2>;
+			compatible = "fsl,imx7ulp-edma";
+			reg = <0x400e8000 0x4000>,
+				<0x400ec000 0x4000>;
+			dma-channels = <32>;
+			interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>,
+				<9>, <10>, <11>, <12>, <13>, <14>, <15>, <16>;
+			clock-names = "dma", "dmamux0";
+			clocks = <&clks IMXRT1050_CLK_DMA>,
+				 <&clks IMXRT1050_CLK_DMA_MUX>;
+		};
+
+		usdhc1: mmc at 402c0000 {
+			compatible ="fsl,imxrt1050-usdhc", "fsl,imx6sl-usdhc";
+			reg = <0x402c0000 0x4000>;
+			interrupts = <110>;
+			clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
+				<&clks IMXRT1050_CLK_OSC>,
+				<&clks IMXRT1050_CLK_USDHC1>;
+			clock-names = "ipg", "ahb", "per";
+			bus-width = <4>;
+			fsl,wp-controller;
+			no-1-8-v;
+			max-frequency = <4000000>;
+			fsl,tuning-start-tap = <20>;
+			fsl,tuning-step= <2>;
+			status = "disabled";
+		};
+
+		gpio1: gpio at 401b8000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401b8000 0x4000>;
+			interrupts = <80>, <81>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio at 401bc000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401bc000 0x4000>;
+			interrupts = <82>, <83>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio at 401c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c0000 0x4000>;
+			interrupts = <84>, <85>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio at 401c4000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c4000 0x4000>;
+			interrupts = <86>, <87>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio5: gpio at 400c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x400c0000 0x4000>;
+			interrupts = <88>, <89>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpt: timer at 401ec000 {
+			compatible = "fsl,imxrt1050-gpt", "fsl,imx6dl-gpt", "fsl,imx6sl-gpt";
+			reg = <0x401ec000 0x4000>;
+			interrupts = <100>;
+			clocks = <&osc3M>;
+			clock-names = "per";
+		};
+	};
+};
-- 
2.34.1



From mr.bossman075 at gmail.com  Mon Jan  3 15:39:48 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon,  3 Jan 2022 18:39:48 -0500
Subject: [PATCH v7 7/7] ARM: imxrt_defconfig: Add i.MXRT family defconfig
In-Reply-To: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
Message-ID: <20220103233948.198119-8-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add generic i.MXRT family defconfig.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Nothing done
V2->V3:
* Nothing done
V3->V4:
* Remove unnecessary CONFIGs
* Add futex suport after "ARM: 9122/1: select HAVE_FUTEX_CMPXCHG"
9d417cbe36eee7afdd85c2e871685f8dab7c2dba
V4->V5:
* Change commit description
V5->V6:
* Nothing done
V6->V7:
* Nothing done
---
 arch/arm/configs/imxrt_defconfig | 35 ++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 arch/arm/configs/imxrt_defconfig

diff --git a/arch/arm/configs/imxrt_defconfig b/arch/arm/configs/imxrt_defconfig
new file mode 100644
index 000000000000..52dba3762996
--- /dev/null
+++ b/arch/arm/configs/imxrt_defconfig
@@ -0,0 +1,35 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BPF_SYSCALL=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_MMU is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMXRT=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x80000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_LEGACY_PTY_COUNT=2
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_PINCTRL_IMXRT1050=y
+CONFIG_GPIO_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_IMXRT1050=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_UTF8=y
-- 
2.34.1



From chunkuang.hu at kernel.org  Mon Jan  3 16:00:54 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Tue, 4 Jan 2022 08:00:54 +0800
Subject: [PATCH v4] drm/mediatek: Fix mtk_cec_mask()
In-Reply-To: <20220103054706.8072-1-miles.chen@mediatek.com>
References: <20220103054706.8072-1-miles.chen@mediatek.com>
Message-ID: <CAAOTY_-WX8p=Ba_4JPgnX4Wmh66bNF09RiP5C7+0=7V-ngdsLA@mail.gmail.com>

Hi, Miles:

Miles Chen <miles.chen at mediatek.com> ? 2022?1?3? ?? ??1:47???
>
> In current implementation, mtk_cec_mask() writes val into target register
> and ignores the mask. After talking to our hdmi experts, mtk_cec_mask()
> should read a register, clean only mask bits, and update (val | mask) bits
> to the register.

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
>
> Cc: Zhiqiang Lin <zhiqiang.lin at mediatek.com>
> Cc: CK Hu <ck.hu at mediatek.com>
> Cc: Matthias Brugger <matthias.bgg at gmail.com>
>
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>
>
> ---
>
> Change since v1:
> add Fixes tag
>
> Change since v2:
> add explanation of mtk_cec_mask()
>
> Change since v3:
> change misleading subject and modify the commit message since this is a bug fix patch
>
> ---
>  drivers/gpu/drm/mediatek/mtk_cec.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
> index e9cef5c0c8f7..cdfa648910b2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_cec.c
> +++ b/drivers/gpu/drm/mediatek/mtk_cec.c
> @@ -85,7 +85,7 @@ static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset,
>         u32 tmp = readl(cec->regs + offset) & ~mask;
>
>         tmp |= val & mask;
> -       writel(val, cec->regs + offset);
> +       writel(tmp, cec->regs + offset);
>  }
>
>  void mtk_cec_set_hpd_event(struct device *dev,
> --
> 2.18.0
>


From houtao1 at huawei.com  Mon Jan  3 17:42:36 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Tue, 4 Jan 2022 09:42:36 +0800
Subject: [PATCH bpf] bpf,
 arm64: calculate offset as byte-offset for bpf line info
Message-ID: <20220104014236.1512639-1-houtao1@huawei.com>

The bpf line info for arm64 is broken due to two reasons:
(1) insn_to_jit_off passed to bpf_prog_fill_jited_linfo() is
    calculated in instruction granularity instead of bytes
    granularity.
(2) insn_to_jit_off only considers the body itself and ignores
    prologue before the body.

So fix it by calculating offset as byte-offset and do build_prologue()
first in the first JIT pass.

Fixes: 37ab566c178d ("bpf: arm64: Enable arm64 jit to provide bpf_line_info")
Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 148ca51325bb..d7a6d4b523c9 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -24,6 +24,8 @@
 
 #include "bpf_jit.h"
 
+#define INSN_SZ (sizeof(u32))
+
 #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
 #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
@@ -154,10 +156,11 @@ static inline int bpf2a64_offset(int bpf_insn, int off,
 	bpf_insn++;
 	/*
 	 * Whereas arm64 branch instructions encode the offset
-	 * from the branch itself, so we must subtract 1 from the
+	 * from the branch itself, so we must subtract 4 from the
 	 * instruction offset.
 	 */
-	return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1);
+	return (ctx->offset[bpf_insn + off] -
+		(ctx->offset[bpf_insn] - INSN_SZ)) / INSN_SZ;
 }
 
 static void jit_fill_hole(void *area, unsigned int size)
@@ -955,13 +958,14 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
 		const struct bpf_insn *insn = &prog->insnsi[i];
 		int ret;
 
+		/* BPF line info needs byte-offset instead of insn-offset */
 		if (ctx->image == NULL)
-			ctx->offset[i] = ctx->idx;
+			ctx->offset[i] = ctx->idx * INSN_SZ;
 		ret = build_insn(insn, ctx, extra_pass);
 		if (ret > 0) {
 			i++;
 			if (ctx->image == NULL)
-				ctx->offset[i] = ctx->idx;
+				ctx->offset[i] = ctx->idx * INSN_SZ;
 			continue;
 		}
 		if (ret)
@@ -973,7 +977,7 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
 	 * instruction (end of program)
 	 */
 	if (ctx->image == NULL)
-		ctx->offset[i] = ctx->idx;
+		ctx->offset[i] = ctx->idx * INSN_SZ;
 
 	return 0;
 }
@@ -1058,15 +1062,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 		goto out_off;
 	}
 
-	/* 1. Initial fake pass to compute ctx->idx. */
-
-	/* Fake pass to fill in ctx->offset. */
-	if (build_body(&ctx, extra_pass)) {
+	/*
+	 * 1. Initial fake pass to compute ctx->idx and ctx->offset.
+	 *
+	 * BPF line info needs ctx->offset[i] to be the byte offset
+	 * of instruction[i] in jited image, so build prologue first.
+	 */
+	if (build_prologue(&ctx, was_classic)) {
 		prog = orig_prog;
 		goto out_off;
 	}
 
-	if (build_prologue(&ctx, was_classic)) {
+	if (build_body(&ctx, extra_pass)) {
 		prog = orig_prog;
 		goto out_off;
 	}
-- 
2.27.0



From liuqi115 at huawei.com  Mon Jan  3 17:59:55 2022
From: liuqi115 at huawei.com (liuqi (BA))
Date: Tue, 4 Jan 2022 09:59:55 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
Message-ID: <1d9b5c3e-63e1-6a0e-b99f-799b3b6ad1a8@huawei.com>



On 2022/1/3 17:03, Jianhua Liu wrote:
> On Thu, Dec 16, 2021 at 8:26 PM Jianhua Liu <jianhua.ljh at gmail.com> wrote:
>>
>> On Thu, Dec 16, 2021 at 7:18 PM liuqi (BA) <liuqi115 at huawei.com> wrote:
>>>
>>>
>>>
>>> On 2021/12/14 23:55, Jianhua Liu wrote:
>>>> On Tue, Dec 14, 2021 at 8:27 AM Masami Hiramatsu <mhiramat at kernel.org> wrote:
>>>>>
>>>>> On Mon, 13 Dec 2021 18:38:52 +0000
>>>>> Will Deacon <will at kernel.org> wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> [+Janet Liu]
>>>>>>
>>>>>> On Tue, Dec 07, 2021 at 08:40:02PM +0800, Qi Liu wrote:
>>>>>>> This patch introduce optprobe for ARM64. In optprobe, probed
>>>>>>> instruction is replaced by a branch instruction to trampoline.
>>>>>>>
>>>>>>> Performance of optprobe on Hip08 platform is test using kprobe
>>>>>>> example module[1] to analyze the latency of a kernel function,
>>>>>>> and here is the result:
>>>>>>>
>>>>>>> common kprobe:
>>>>>>> [280709.846380] do_empty returned 0 and took 1530 ns to execute
>>>>>>> [280709.852057] do_empty returned 0 and took 550 ns to execute
>>>>>>> [280709.857631] do_empty returned 0 and took 440 ns to execute
>>>>>>> [280709.863215] do_empty returned 0 and took 380 ns to execute
>>>>>>> [280709.868787] do_empty returned 0 and took 360 ns to execute
>>>>>>> [280709.874362] do_empty returned 0 and took 340 ns to execute
>>>>>>> [280709.879936] do_empty returned 0 and took 320 ns to execute
>>>>>>> [280709.885505] do_empty returned 0 and took 300 ns to execute
>>>>>>> [280709.891075] do_empty returned 0 and took 280 ns to execute
>>>>>>> [280709.896646] do_empty returned 0 and took 290 ns to execute
>>>>>>>
>>>>>>> optprobe:
>>>>>>> [ 2965.964572] do_empty returned 0 and took 90 ns to execute
>>>>>>> [ 2965.969952] do_empty returned 0 and took 80 ns to execute
>>>>>>> [ 2965.975332] do_empty returned 0 and took 70 ns to execute
>>>>>>> [ 2965.980714] do_empty returned 0 and took 60 ns to execute
>>>>>>> [ 2965.986128] do_empty returned 0 and took 80 ns to execute
>>>>>>> [ 2965.991507] do_empty returned 0 and took 70 ns to execute
>>>>>>> [ 2965.996884] do_empty returned 0 and took 70 ns to execute
>>>>>>> [ 2966.002262] do_empty returned 0 and took 80 ns to execute
>>>>>>> [ 2966.007642] do_empty returned 0 and took 70 ns to execute
>>>>>>> [ 2966.013020] do_empty returned 0 and took 70 ns to execute
>>>>>>> [ 2966.018400] do_empty returned 0 and took 70 ns to execute
>>>>>>>
>>>>>>> As the result shows, optprobe can greatly reduce the latency. Big
>>>>>>> latency of common kprobe will significantly impact the real result
>>>>>>> while doing performance analysis or debugging performance issues
>>>>>>> in lab, so optprobe is useful in this scenario.
>>>>>>>
>>>>>>> Acked-by: Masami Hiramatsu <mhiramat at kernel.org>
>>>>>>> Signed-off-by: Qi Liu <liuqi115 at huawei.com>
>>>>>>>
>>>>>>> Note:
>>>>>>> As branch instruction in Arm64 has a 128M range limitation, optprobe
>>>>>>> could only used when offset between probe point and trampoline
>>>>>>> is less than 128M, otherwise kernel will choose common kprobe
>>>>>>> automaticly.
>>>>>>>
>>>>>>> Limitation caused by branch isn't unique to Arm64, but also to
>>>>>>> x86/arm/powerpc.
>>>>>>>
>>>>>>> In fact, Module PLT has been tried to get rid of limiation, but
>>>>>>> destination of PLT must be a fixed value, and we need to modify
>>>>>>> the destination (as each optprobe has its own trampoline).
>>>>>>>
>>>>>>> As discussed with Masami[2], we can start with core-kernel point
>>>>>>> (within 128M) as the first step, like other architectures.
>>>>>>>
>>>>>>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/kretprobe_example.c
>>>>>>> [2] https://lore.kernel.org/lkml/20211201105001.5164f98ba783e7207df1229c at kernel.org/
>>>>>>> ---
>>>>>>>    arch/arm64/Kconfig                            |   1 +
>>>>>>>    arch/arm64/include/asm/kprobes.h              |  21 ++
>>>>>>>    arch/arm64/kernel/probes/Makefile             |   2 +
>>>>>>>    arch/arm64/kernel/probes/opt_arm64.c          | 199 ++++++++++++++++++
>>>>>>>    .../arm64/kernel/probes/optprobe_trampoline.S |  97 +++++++++
>>>>>>>    include/linux/kprobes.h                       |   2 +
>>>>>>>    kernel/kprobes.c                              |  22 ++
>>>>>>>    7 files changed, 344 insertions(+)
>>>>>>>    create mode 100644 arch/arm64/kernel/probes/opt_arm64.c
>>>>>>>    create mode 100644 arch/arm64/kernel/probes/optprobe_trampoline.S
>>>>>>
>>>>>> I've not looked at these changes in detail, but it looks like there is an
>>>>>> independent patch from Janet Liu trying to do the same thing:
>>>>>>
>>>>>> https://lore.kernel.org/r/1635858706-27320-1-git-send-email-jianhua.ljh at gmail.com
>>>>>>
>>>>>
>>>>> Thanks for noticing. I missed it.
>>>>>
>>>>>> The patch here from Qi Liu looks like it's a bit further along, but it
>>>>>> would be good for Janet to at least test it out and confirm that it works
>>>>>> for them.
>>>>>
>>>>> Yeah, it's now v5.
>>>>> But it seems Janet's one also has good points. I would like Janet's sharing
>>>>> save_all_base_regs macro and the comment about the branch instruction.
>>>>>
>>>>>>
>>>>>> Cheers,
>>>>>>
>>>>>> Will
>>>>>>
>>>>>> [Kept diff inline for Janet]
>>>>>
>>>>> Janet, please feel free to review and test it. It is important that you confirm
>>>>> this can work with your envionment too.
>>>>> I will review your KPROBE_ON_FTRACE patch.
>>>>>
>>>> I have tested these patch on UNISOC s9863a platform before sending.
>>>>
>>>> The test case from:
>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/samples/kprobes/
>>>>
>>>> And I do the following change for kprobe_example.c before testing:
>>>> 1. delete function handler_post,
>>>>      kprobe_init does "kp.post_handler = handler_post; --->
>>>> p.post_handler = NULL;"
>>>> 2. handler_pre calls dump_stack.
>>>>
>>>
>>> Hi Jianhua,
>>>
>>> Could you kindly review this patch and test it on your UNISOC s9863a
>>> platform? Let's work together to make arm64 optprobe work : )
>>>
>>> Thanks,
>>> Qi
>>
>> OK, I will review. I have left UNISOC, I get some help from old
>> colleage to do the test.
>> Only on weekend, he can do it. So the time will be longer a little.
>>
>> Thanks
>> Jianhua
>>
>>
> Hi Qi,
> I have tested your patch on UNISOC s9863a.
> Test case "kprobe_example & kretprobe_example" is OK.
> 
Hi Jianhua,

Thanks for your test.

> Two point:
> 1. backtrace is not perfect.
>     optprobe_common does not saved frame pointer,
>     backtrace lacks two calls.
Got it, I'll check optprobe_common to see the lost frame pointer, thanks.
> such as for dup_mm: lack copy_process-->dup_mm
> dup_mm backtrace from your patch:
> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> [  832.387083] Call trace:
> [  832.387086]  dump_backtrace+0x0/0x1e0
> [  832.387103]  show_stack+0x24/0x30
> [  832.387112]  dump_stack_lvl+0x68/0x84
> [  832.387123]  dump_stack+0x18/0x34
> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
> [  832.387143]  opt_pre_handler+0x84/0xc0
> [  832.387154]  optprobe_optimized_callback+0xec/0x164
> [  832.387164]  optprobe_common+0x70/0xc4
> [  832.387173]  kernel_clone+0x98/0x440
> [  832.387182]  __do_sys_clone+0x54/0x80
> [  832.387191]  __arm64_sys_clone+0x2c/0x40
> [  832.387199]  invoke_syscall+0x50/0x120
> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
> [  832.387217]  do_el0_svc+0x30/0x9c
> [  832.387225]  el0_svc+0x20/0x60
> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
> 
> 
> dup_mm backtrace from other:
> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> [  173.352304] Call trace:
> [  173.352307]  dump_backtrace+0x0/0x1d4
> [  173.352319]  show_stack+0x18/0x24
> [  173.352326]  dump_stack_lvl+0x68/0x84
> [  173.352333]  dump_stack+0x18/0x34
> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
> [  173.352347]  opt_pre_handler+0x74/0xb0
> [  173.352354]  optimized_callback+0x108/0x130
> [  173.352361]  optinsn_slot+0x258/0x1000
> [  173.352366]  dup_mm+0x4/0x4b0
> [  173.352373]  copy_process+0x1284/0x1360
> [  173.352378]  kernel_clone+0x5c/0x3c0
> [  173.352384]  __do_sys_clone+0x54/0x80
> [  173.352390]  __arm64_sys_clone+0x24/0x30
> [  173.352396]  invoke_syscall+0x48/0x114
> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
> [  173.352408]  do_el0_svc+0x24/0x90
> [  173.352413]  el0_svc+0x20/0x60
> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
> 
> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
>     kernel/kprobe.c used only one PAGE_SIZE slot memory.
> 
Got it, will fix this. By the way, could I add your test-by tag in next 
version?

Thanks,
Qi
> Thanks
> Jianhua
> 
>>> Thanks for  the review.
>>>>
>>>>> Thank you,
>>>>>
>>>>>>
>>>>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>>>>> index c4207cf9bb17..6b68ec498e67 100644
>>>>>>> --- a/arch/arm64/Kconfig
>>>>>>> +++ b/arch/arm64/Kconfig
>>>>>>> @@ -200,6 +200,7 @@ config ARM64
>>>>>>>       select HAVE_STACKPROTECTOR
>>>>>>>       select HAVE_SYSCALL_TRACEPOINTS
>>>>>>>       select HAVE_KPROBES
>>>>>>> +   select HAVE_OPTPROBES
>>>>>>>       select HAVE_KRETPROBES
>>>>>>>       select HAVE_GENERIC_VDSO
>>>>>>>       select IOMMU_DMA if IOMMU_SUPPORT
>>>>>>> diff --git a/arch/arm64/include/asm/kprobes.h b/arch/arm64/include/asm/kprobes.h
>>>>>>> index 05cd82eeca13..3838e4317877 100644
>>>>>>> --- a/arch/arm64/include/asm/kprobes.h
>>>>>>> +++ b/arch/arm64/include/asm/kprobes.h
>>>>>>> @@ -39,6 +39,27 @@ void arch_remove_kprobe(struct kprobe *);
>>>>>>>    int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>>>>>>>    int kprobe_exceptions_notify(struct notifier_block *self,
>>>>>>>                            unsigned long val, void *data);
>>>>>>> +
>>>>>>> +struct arch_optimized_insn {
>>>>>>> +   kprobe_opcode_t orig_insn[1];
>>>>>>> +   kprobe_opcode_t *trampoline;
>>>>>>> +};
>>>>>>> +
>>>>>>> +#define MAX_OPTIMIZED_LENGTH       sizeof(kprobe_opcode_t)
>>>>>>> +#define MAX_OPTINSN_SIZE                                                       \
>>>>>>> +   ((unsigned long)optprobe_template_restore_end - (unsigned long)optprobe_template_entry)
>>>>>>> +
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_entry[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_val[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_common[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_end[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
>>>>>>> +extern __visible kprobe_opcode_t optprobe_template_restore_end[];
>>>>>>> +extern __visible kprobe_opcode_t optinsn_slot[];
>>>>>>> +
>>>>>>> +void optprobe_common(void);
>>>>>>> +
>>>>>>>    void __kretprobe_trampoline(void);
>>>>>>>    void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
>>>>>>>
>>>>>>> diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
>>>>>>> index 8e4be92e25b1..07105fd3261d 100644
>>>>>>> --- a/arch/arm64/kernel/probes/Makefile
>>>>>>> +++ b/arch/arm64/kernel/probes/Makefile
>>>>>>> @@ -4,3 +4,5 @@ obj-$(CONFIG_KPROBES)               += kprobes.o decode-insn.o      \
>>>>>>>                                  simulate-insn.o
>>>>>>>    obj-$(CONFIG_UPROBES)              += uprobes.o decode-insn.o      \
>>>>>>>                                  simulate-insn.o
>>>>>>> +obj-$(CONFIG_OPTPROBES)            += opt_arm64.o                  \
>>>>>>> +                              optprobe_trampoline.o
>>>>>>> diff --git a/arch/arm64/kernel/probes/opt_arm64.c b/arch/arm64/kernel/probes/opt_arm64.c
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..1bad5cddcdf2
>>>>>>> --- /dev/null
>>>>>>> +++ b/arch/arm64/kernel/probes/opt_arm64.c
>>>>>>> @@ -0,0 +1,199 @@
>>>>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>>>>> +/*
>>>>>>> + * Code for Kernel probes Jump optimization.
>>>>>>> + *
>>>>>>> + * Copyright (C) 2021 Hisilicon Limited
>>>>>>> + */
>>>>>>> +
>>>>>>> +#include <linux/jump_label.h>
>>>>>>> +#include <linux/kprobes.h>
>>>>>>> +
>>>>>>> +#include <asm/cacheflush.h>
>>>>>>> +#include <asm/compiler.h>
>>>>>>> +#include <asm/insn.h>
>>>>>>> +#include <asm/kprobes.h>
>>>>>>> +#include <asm/patching.h>
>>>>>>> +
>>>>>>> +#define OPTPROBE_BATCH_SIZE 64
>>>>>>> +#define GET_LO_VAL(val)            FIELD_GET(GENMASK(31, 0), val)
>>>>>>> +#define GET_HI_VAL(val)            FIELD_GET(GENMASK(63, 32), val)
>>>>>>> +
>>>>>>> +#define TMPL_VAL_IDX \
>>>>>>> +   (optprobe_template_val - optprobe_template_entry)
>>>>>>> +#define TMPL_CALL_COMMON \
>>>>>>> +   (optprobe_template_common - optprobe_template_entry)
>>>>>>> +#define TMPL_RESTORE_ORIGN_INSN \
>>>>>>> +   (optprobe_template_restore_orig_insn - optprobe_template_entry)
>>>>>>> +#define TMPL_RESTORE_END \
>>>>>>> +   (optprobe_template_restore_end - optprobe_template_entry)
>>>>>>> +#define TMPL_END_IDX \
>>>>>>> +   (optprobe_template_end - optprobe_template_entry)
>>>>>>> +
>>>>>>> +static bool insn_page_in_use;
>>>>>>> +
>>>>>>> +void *alloc_optinsn_page(void)
>>>>>>> +{
>>>>>>> +   if (insn_page_in_use)
>>>>>>> +           return NULL;
>>>>>>> +   insn_page_in_use = true;
>>>>>>> +   return &optinsn_slot;
>>>>>>> +}
>>>>>>> +
>>>>>>> +void free_optinsn_page(void *page)
>>>>>>> +{
>>>>>>> +   insn_page_in_use = false;
>>>>>>> +}
>>>>>>> +
>>>>>>> +int arch_check_optimized_kprobe(struct optimized_kprobe *op)
>>>>>>> +{
>>>>>>> +   return 0;
>>>>>>> +}
>>>>>>> +
>>>>>>> +int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
>>>>>>> +{
>>>>>>> +   return optinsn->trampoline != NULL;
>>>>>>> +}
>>>>>>> +
>>>>>>> +int arch_within_optimized_kprobe(struct optimized_kprobe *op, kprobe_opcode_t *addr)
>>>>>>> +{
>>>>>>> +   return op->kp.addr == addr;
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void optprobe_set_pc_value(struct optimized_kprobe *op, struct pt_regs *regs)
>>>>>>> +{
>>>>>>> +   regs->pc = (unsigned long)op->kp.addr;
>>>>>>> +}
>>>>>>> +
>>>>>>> +static int optprobe_check_branch_limit(unsigned long pc, unsigned long addr)
>>>>>>> +{
>>>>>>> +   long offset;
>>>>>>> +
>>>>>>> +   if ((pc & 0x3) || (addr & 0x3))
>>>>>>> +           return -ERANGE;
>>>>>>> +
>>>>>>> +   offset = (long)addr - (long)pc;
>>>>>>> +   if (offset < -SZ_128M || offset >= SZ_128M)
>>>>>>> +           return -ERANGE;
>>>>>>> +
>>>>>>> +   return 0;
>>>>>>> +}
>>>>>>> +
>>>>>>> +int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
>>>>>>> +{
>>>>>>> +   kprobe_opcode_t *code, *buf;
>>>>>>> +   u32 insn;
>>>>>>> +   int ret = -ENOMEM;
>>>>>>> +   int i;
>>>>>>> +
>>>>>>> +   buf = kcalloc(MAX_OPTINSN_SIZE, sizeof(kprobe_opcode_t), GFP_KERNEL);
>>>>>>> +   if (!buf)
>>>>>>> +           return ret;
>>>>>>> +
>>>>>>> +   code = get_optinsn_slot();
>>>>>>> +   if (!code)
>>>>>>> +           goto out;
>>>>>>> +
>>>>>>> +   if (optprobe_check_branch_limit((unsigned long)code, (unsigned long)orig->addr + 8)) {
>>>>>>> +           ret = -ERANGE;
>>>>>>> +           goto error;
>>>>>>> +   }
>>>>>>> +
>>>>>>> +   op->set_pc = optprobe_set_pc_value;
>>>>>>> +   memcpy(buf, optprobe_template_entry, MAX_OPTINSN_SIZE * sizeof(kprobe_opcode_t));
>>>>>>> +
>>>>>>> +   insn = aarch64_insn_gen_branch_imm((unsigned long)&code[TMPL_CALL_COMMON],
>>>>>>> +                                      (unsigned long)&optprobe_common,
>>>>>>> +                                      AARCH64_INSN_BRANCH_LINK);
>>>>>>> +   buf[TMPL_CALL_COMMON] = insn;
>>>>>>> +
>>>>>>> +   insn = aarch64_insn_gen_branch_imm((unsigned long)&code[TMPL_RESTORE_END],
>>>>>>> +                                      (unsigned long)op->kp.addr + 4,
>>>>>>> +                                      AARCH64_INSN_BRANCH_NOLINK);
>>>>>>> +   buf[TMPL_RESTORE_END] = insn;
>>>>>>> +
>>>>>>> +   buf[TMPL_VAL_IDX] = cpu_to_le32(GET_LO_VAL((unsigned long)op));
>>>>>>> +   buf[TMPL_VAL_IDX + 1] = cpu_to_le32(GET_HI_VAL((unsigned long)op));
>>>>>>> +   buf[TMPL_RESTORE_ORIGN_INSN] = orig->opcode;
>>>>>>> +
>>>>>>> +   /* Setup template */
>>>>>>> +   for (i = 0; i < MAX_OPTINSN_SIZE; i++)
>>>>>>> +           aarch64_insn_patch_text_nosync(code + i, buf[i]);
>>>>>>> +
>>>>>>> +   flush_icache_range((unsigned long)code, (unsigned long)(&code[TMPL_VAL_IDX]));
>>>>>>> +   /* Set op->optinsn.trampoline means prepared. */
>>>>>>> +   op->optinsn.trampoline = code;
>>>>>>> +
>>>>>>> +out:
>>>>>>> +   kfree(buf);
>>>>>>> +   return ret;
>>>>>>> +
>>>>>>> +error:
>>>>>>> +   free_optinsn_slot(code, 0);
>>>>>>> +   goto out;
>>>>>>> +}
>>>>>>> +
>>>>>>> +void arch_optimize_kprobes(struct list_head *oplist)
>>>>>>> +{
>>>>>>> +   struct optimized_kprobe *op, *tmp;
>>>>>>> +   kprobe_opcode_t insns[OPTPROBE_BATCH_SIZE];
>>>>>>> +   void *addrs[OPTPROBE_BATCH_SIZE];
>>>>>>> +   int i = 0;
>>>>>>> +
>>>>>>> +   list_for_each_entry_safe(op, tmp, oplist, list) {
>>>>>>> +           WARN_ON(kprobe_disabled(&op->kp));
>>>>>>> +
>>>>>>> +           /*
>>>>>>> +            * Backup instructions which will be replaced
>>>>>>> +            * by jump address
>>>>>>> +            */
>>>>>>> +           memcpy(op->optinsn.orig_insn, op->kp.addr, AARCH64_INSN_SIZE);
>>>>>>> +
>>>>>>> +           addrs[i] = (void *)op->kp.addr;
>>>>>>> +           insns[i] = aarch64_insn_gen_branch_imm((unsigned long)op->kp.addr,
>>>>>>> +                                                  (unsigned long)op->optinsn.trampoline,
>>>>>>> +                                                  AARCH64_INSN_BRANCH_NOLINK);
>>>>>>> +
>>>>>>> +           list_del_init(&op->list);
>>>>>>> +           if (++i == OPTPROBE_BATCH_SIZE)
>>>>>>> +                   break;
>>>>>>> +   }
>>>>>>> +
>>>>>>> +   aarch64_insn_patch_text(addrs, insns, i);
>>>>>>> +}
>>>>>>> +
>>>>>>> +void arch_unoptimize_kprobe(struct optimized_kprobe *op)
>>>>>>> +{
>>>>>>> +   arch_arm_kprobe(&op->kp);
>>>>>>> +}
>>>>>>> +
>>>>>>> +/*
>>>>>>> + * Recover original instructions and breakpoints from relative jumps.
>>>>>>> + * Caller must call with locking kprobe_mutex.
>>>>>>> + */
>>>>>>> +void arch_unoptimize_kprobes(struct list_head *oplist,
>>>>>>> +                       struct list_head *done_list)
>>>>>>> +{
>>>>>>> +   struct optimized_kprobe *op, *tmp;
>>>>>>> +   kprobe_opcode_t insns[OPTPROBE_BATCH_SIZE];
>>>>>>> +   void *addrs[OPTPROBE_BATCH_SIZE];
>>>>>>> +   int i = 0;
>>>>>>> +
>>>>>>> +   list_for_each_entry_safe(op, tmp, oplist, list) {
>>>>>>> +           addrs[i] = (void *)op->kp.addr;
>>>>>>> +           insns[i] = BRK64_OPCODE_KPROBES;
>>>>>>> +           list_move(&op->list, done_list);
>>>>>>> +
>>>>>>> +           if (++i == OPTPROBE_BATCH_SIZE)
>>>>>>> +                   break;
>>>>>>> +   }
>>>>>>> +
>>>>>>> +   aarch64_insn_patch_text(addrs, insns, i);
>>>>>>> +}
>>>>>>> +
>>>>>>> +void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>>>>>>> +{
>>>>>>> +   if (op->optinsn.trampoline) {
>>>>>>> +           free_optinsn_slot(op->optinsn.trampoline, 1);
>>>>>>> +           op->optinsn.trampoline = NULL;
>>>>>>> +   }
>>>>>>> +}
>>>>>>> diff --git a/arch/arm64/kernel/probes/optprobe_trampoline.S b/arch/arm64/kernel/probes/optprobe_trampoline.S
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..1376daeae844
>>>>>>> --- /dev/null
>>>>>>> +++ b/arch/arm64/kernel/probes/optprobe_trampoline.S
>>>>>>> @@ -0,0 +1,97 @@
>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>> +/*
>>>>>>> + * trampoline entry and return code for optprobes.
>>>>>>> + */
>>>>>>> +
>>>>>>> +#include <linux/linkage.h>
>>>>>>> +#include <asm/asm-offsets.h>
>>>>>>> +#include <asm/assembler.h>
>>>>>>> +
>>>>>>> +#define        OPT_SLOT_SIZE   65536
>>>>>>> +
>>>>>>> +   .global optinsn_slot
>>>>>>> +optinsn_slot:
>>>>>>> +   .space  OPT_SLOT_SIZE
>>>>>>> +
>>>>>>> +SYM_CODE_START(optprobe_common)
>>>>>>> +   stp x2, x3, [sp, #S_X2]
>>>>>>> +   stp x4, x5, [sp, #S_X4]
>>>>>>> +   stp x6, x7, [sp, #S_X6]
>>>>>>> +   stp x8, x9, [sp, #S_X8]
>>>>>>> +   stp x10, x11, [sp, #S_X10]
>>>>>>> +   stp x12, x13, [sp, #S_X12]
>>>>>>> +   stp x14, x15, [sp, #S_X14]
>>>>>>> +   stp x16, x17, [sp, #S_X16]
>>>>>>> +   stp x18, x19, [sp, #S_X18]
>>>>>>> +   stp x20, x21, [sp, #S_X20]
>>>>>>> +   stp x22, x23, [sp, #S_X22]
>>>>>>> +   stp x24, x25, [sp, #S_X24]
>>>>>>> +   stp x26, x27, [sp, #S_X26]
>>>>>>> +   stp x28, x29, [sp, #S_X28]
>>>>>>> +   add x2, sp, #PT_REGS_SIZE
>>>>>>> +   str x2, [sp, #S_SP]
>>>>>>> +   /* Construct a useful saved PSTATE */
>>>>>>> +   mrs x2, nzcv
>>>>>>> +   mrs x3, daif
>>>>>>> +   orr x2, x2, x3
>>>>>>> +   mrs x3, CurrentEL
>>>>>>> +   orr x2, x2, x3
>>>>>>> +   mrs x3, SPSel
>>>>>>> +   orr x2, x2, x3
>>>>>>> +   stp xzr, x2, [sp, #S_PC]
>>>>>>> +
>>>>>>> +   /* set the pt_regs address to x1 */
>>>>>>> +   mov     x1, sp
>>>>>>> +   /* store lr of optprobe_common temporary */
>>>>>>> +   sub sp, sp, #0x10
>>>>>>> +   str lr, [sp, #0x8]
>>>>>>> +
>>>>>>> +   bl optprobe_optimized_callback
>>>>>>> +
>>>>>>> +   ldr lr, [sp, #0x8]
>>>>>>> +   add sp, sp, #0x10
>>>>>>> +   ldr x0, [sp, #S_PSTATE]
>>>>>>> +   and x0, x0, #(PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT)
>>>>>>> +   msr nzcv, x0
>>>>>>> +   ldp x0, x1, [sp, #S_X0]
>>>>>>> +   ldp x2, x3, [sp, #S_X2]
>>>>>>> +   ldp x4, x5, [sp, #S_X4]
>>>>>>> +   ldp x6, x7, [sp, #S_X6]
>>>>>>> +   ldp x8, x9, [sp, #S_X8]
>>>>>>> +   ldp x10, x11, [sp, #S_X10]
>>>>>>> +   ldp x12, x13, [sp, #S_X12]
>>>>>>> +   ldp x14, x15, [sp, #S_X14]
>>>>>>> +   ldp x16, x17, [sp, #S_X16]
>>>>>>> +   ldp x18, x19, [sp, #S_X18]
>>>>>>> +   ldp x20, x21, [sp, #S_X20]
>>>>>>> +   ldp x22, x23, [sp, #S_X22]
>>>>>>> +   ldp x24, x25, [sp, #S_X24]
>>>>>>> +   ldp x26, x27, [sp, #S_X26]
>>>>>>> +   ldp x28, x29, [sp, #S_X28]
>>>>>>> +   ret
>>>>>>> +SYM_CODE_END(optprobe_common)
>>>>>>> +
>>>>>>> +   .global optprobe_template_entry
>>>>>>> +optprobe_template_entry:
>>>>>>> +   sub sp, sp, #PT_REGS_SIZE
>>>>>>> +   str lr, [sp, #S_LR]
>>>>>>> +   stp x0, x1, [sp, #S_X0]
>>>>>>> +   /* Get parameters to optimized_callback() */
>>>>>>> +   ldr x0, 1f
>>>>>>> +   .global optprobe_template_common
>>>>>>> +optprobe_template_common:
>>>>>>> +   nop
>>>>>>> +   ldr lr, [sp, #S_LR]
>>>>>>> +       add sp, sp, #PT_REGS_SIZE
>>>>>>> +   .global optprobe_template_restore_orig_insn
>>>>>>> +optprobe_template_restore_orig_insn:
>>>>>>> +   nop
>>>>>>> +   .global optprobe_template_restore_end
>>>>>>> +optprobe_template_restore_end:
>>>>>>> +   nop
>>>>>>> +   .global optprobe_template_val
>>>>>>> +optprobe_template_val:
>>>>>>> +   1:      .long 0
>>>>>>> +           .long 0
>>>>>>> +   .global optprobe_template_end
>>>>>>> +optprobe_template_end:
>>>>>>> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
>>>>>>> index 8c8f7a4d93af..7be680155df7 100644
>>>>>>> --- a/include/linux/kprobes.h
>>>>>>> +++ b/include/linux/kprobes.h
>>>>>>> @@ -329,6 +329,7 @@ struct optimized_kprobe {
>>>>>>>       struct kprobe kp;
>>>>>>>       struct list_head list;  /* list for optimizing queue */
>>>>>>>       struct arch_optimized_insn optinsn;
>>>>>>> +   void (*set_pc)(struct optimized_kprobe *op, struct pt_regs *regs);
>>>>>>>    };
>>>>>>>
>>>>>>>    /* Architecture dependent functions for direct jump optimization */
>>>>>>> @@ -345,6 +346,7 @@ extern int arch_within_optimized_kprobe(struct optimized_kprobe *op,
>>>>>>>                                       kprobe_opcode_t *addr);
>>>>>>>
>>>>>>>    extern void opt_pre_handler(struct kprobe *p, struct pt_regs *regs);
>>>>>>> +extern void optprobe_optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs);
>>>>>>>
>>>>>>>    DEFINE_INSN_CACHE_OPS(optinsn);
>>>>>>>
>>>>>>> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
>>>>>>> index 21eccc961bba..d799e562a39a 100644
>>>>>>> --- a/kernel/kprobes.c
>>>>>>> +++ b/kernel/kprobes.c
>>>>>>> @@ -430,6 +430,28 @@ void opt_pre_handler(struct kprobe *p, struct pt_regs *regs)
>>>>>>>    }
>>>>>>>    NOKPROBE_SYMBOL(opt_pre_handler);
>>>>>>>
>>>>>>> +void optprobe_optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
>>>>>>> +{
>>>>>>> +   if (kprobe_disabled(&op->kp))
>>>>>>> +           return;
>>>>>>> +
>>>>>>> +   preempt_disable();
>>>>>>> +
>>>>>>> +   if (kprobe_running()) {
>>>>>>> +           kprobes_inc_nmissed_count(&op->kp);
>>>>>>> +   } else {
>>>>>>> +           op->set_pc(op, regs);
>>>>>>> +           __this_cpu_write(current_kprobe, &op->kp);
>>>>>>> +           get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
>>>>>>> +           opt_pre_handler(&op->kp, regs);
>>>>>>> +           __this_cpu_write(current_kprobe, NULL);
>>>>>>> +   }
>>>>>>> +
>>>>>>> +   preempt_enable();
>>>>>>> +}
>>>>>>> +NOKPROBE_SYMBOL(optprobe_optimized_callback)
>>>>>>> +
>>>>>>> +
>>>>>>>    /* Free optimized instructions and optimized_kprobe */
>>>>>>>    static void free_aggr_kprobe(struct kprobe *p)
>>>>>>>    {
>>>>>>> --
>>>>>>> 2.33.0
>>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Masami Hiramatsu <mhiramat at kernel.org>
>>>> .
>>>>
> .
> 


From mhiramat at kernel.org  Mon Jan  3 18:35:59 2022
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Tue, 4 Jan 2022 11:35:59 +0900
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
Message-ID: <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>

Hi Jianhua,

On Mon, 3 Jan 2022 17:03:33 +0800
Jianhua Liu <jianhua.ljh at gmail.com> wrote:

> Hi Qi,
> I have tested your patch on UNISOC s9863a.
> Test case "kprobe_example & kretprobe_example" is OK.
> 
> Two point:
> 1. backtrace is not perfect.
>    optprobe_common does not saved frame pointer,
>    backtrace lacks two calls.
> such as for dup_mm: lack copy_process-->dup_mm
> dup_mm backtrace from your patch:
> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> [  832.387083] Call trace:
> [  832.387086]  dump_backtrace+0x0/0x1e0
> [  832.387103]  show_stack+0x24/0x30
> [  832.387112]  dump_stack_lvl+0x68/0x84
> [  832.387123]  dump_stack+0x18/0x34
> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
> [  832.387143]  opt_pre_handler+0x84/0xc0
> [  832.387154]  optprobe_optimized_callback+0xec/0x164
> [  832.387164]  optprobe_common+0x70/0xc4
> [  832.387173]  kernel_clone+0x98/0x440
> [  832.387182]  __do_sys_clone+0x54/0x80
> [  832.387191]  __arm64_sys_clone+0x2c/0x40
> [  832.387199]  invoke_syscall+0x50/0x120
> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
> [  832.387217]  do_el0_svc+0x30/0x9c
> [  832.387225]  el0_svc+0x20/0x60
> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
> 
> 
> dup_mm backtrace from other:
> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> [  173.352304] Call trace:
> [  173.352307]  dump_backtrace+0x0/0x1d4
> [  173.352319]  show_stack+0x18/0x24
> [  173.352326]  dump_stack_lvl+0x68/0x84
> [  173.352333]  dump_stack+0x18/0x34
> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
> [  173.352347]  opt_pre_handler+0x74/0xb0
> [  173.352354]  optimized_callback+0x108/0x130
> [  173.352361]  optinsn_slot+0x258/0x1000
> [  173.352366]  dup_mm+0x4/0x4b0
> [  173.352373]  copy_process+0x1284/0x1360
> [  173.352378]  kernel_clone+0x5c/0x3c0
> [  173.352384]  __do_sys_clone+0x54/0x80
> [  173.352390]  __arm64_sys_clone+0x24/0x30
> [  173.352396]  invoke_syscall+0x48/0x114
> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
> [  173.352408]  do_el0_svc+0x24/0x90
> [  173.352413]  el0_svc+0x20/0x60
> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
> [  173.352427]  el0t_64_sync+0x1a0/0x1a4

Is the second one with your patch?

> 
> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
>    kernel/kprobe.c used only one PAGE_SIZE slot memory.

Good catch!
Qi, can you make an array (or bit map) of usage flags and
manage the reserved memory?

#define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
static bool insn_page_in_use[OPT_INSN_PAGES];

void *alloc_optinsn_page(void)
{
	int i;

	for (i = 0; i < OPT_INSN_PAGES; i++)
		if (!insn_page_in_use[i])
			goto found;
	return NULL;
found:
	insn_page_in_use[i] = true;
	return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
}

void free_optinsn_page(void *page)
{
	unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;

	WARN_ONCE(idx & (PAGE_SIZE - 1));
	idx >>= PAGE_SHIFT;
	if (WARN_ONCE(idx >= OPT_INSN_PAGES))
		return;
	insn_page_in_use[idx] = false;
}

Thank you,




-- 
Masami Hiramatsu <mhiramat at kernel.org>


From biao.huang at mediatek.com  Mon Jan  3 19:39:34 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:34 +0800
Subject: [PATCH net-next v11 0/6] MediaTek Ethernet Patches on MT8195
Message-ID: <20220104033940.5497-1-biao.huang@mediatek.com>

Changes in v11:
1. add reivewed-by in "net: dt-bindings: dwmac: Convert mediatek-dwmac to
   DT schema" as Rob's comments.
2. fall back "net: dt-bindings: dwmac: add support for mt8195" to v8 version
   as mentioned in previous reply(https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20211216055328.15953-7-biao.huang at mediatek.com/):
   2.1 there is already a special clock named "rmii_internal", which need to
       be put to the end of the clock list(driver special handling),
       so we can't simply put new "mac_cg" for mt8195 to the end of the clock
       list.
   2.2 we prefer the if-then schema, which will make mt8195 clock list clearer
       with some duplicated information.
   2.3 we expect the future IC will follow mt2712 or mt8195, so we only need
       add new IC name to compatible list for future IC, and will not make the
       clock list binding files worse.

Changes in v10:
1. add detailed description in "arm64: dts: mt2712: update ethernet
   device node" to make the modifications clearer as Matthias's comments.
2. modify dt-binding description as Rob's comments, and "make dtbs_check" runs
   pass locally with "arm64: dts: mt2712: update ethernet device node"
   in this series.

Changes in v9:
1. remove oneOf for 1 entry as Rob's comments.
2. add new clocks to the end of existing clocks to simplify
   the binding as Rob's comments.

Changes in v8:
1. add acked-by in "stmmac: dwmac-mediatek: add platform level clocks
   management" patch

Changes in v7:
1. fix uninitialized warning as Jakub's comments.

Changes in v6:
1. update commit message as Jakub's comments.
2. split mt8195 eth dts patch("arm64: dts: mt8195: add ethernet device
   node") from this series, since mt8195 dtsi/dts basic patches is still
   under reviewing.
   https://patchwork.kernel.org/project/linux-mediatek/list/?series=579071
   we'll resend mt8195 eth dts patch once all the dependent patches are
   accepted.

Changes in v5:
1. remove useless inclusion in dwmac-mediatek.c as Angelo's comments.
2. add acked-by in "net-next: stmmac: dwmac-mediatek: add support for
   mt8195" patch

Changes in v4:
1. add changes in commit message in "net-next: dt-bindings: dwmac:
   Convert mediatek-dwmac to DT schema" patch.
2. remove ethernet-controller.yaml since snps,dwmac.yaml already include it.

Changes in v3:
1. Add prefix "net-next" to support new IC as Denis's suggestion.
2. Split dt-bindings to two patches, one for conversion, and the other for
   new IC.
3. add a new patch to update device node in mt2712-evb.dts to accommodate to
   changes in driver.
4. remove unnecessary wrapper as Angelo's suggestion.
5. Add acked-by in "net-next: stmmac: dwmac-mediatek: Reuse more common
   features" patch.

Changes in v2:
1. fix errors/warnings in mediatek-dwmac.yaml with upgraded dtschema tools

This series include 5 patches:
1. add platform level clocks management for dwmac-mediatek
2. resue more common features defined in stmmac_platform.c
3. add ethernet entry for mt8195

Biao Huang (6):
  stmmac: dwmac-mediatek: add platform level clocks management
  stmmac: dwmac-mediatek: Reuse more common features
  arm64: dts: mt2712: update ethernet device node
  net: dt-bindings: dwmac: Convert mediatek-dwmac to DT schema
  stmmac: dwmac-mediatek: add support for mt8195
  net: dt-bindings: dwmac: add support for mt8195

 .../bindings/net/mediatek-dwmac.txt           |  91 ------
 .../bindings/net/mediatek-dwmac.yaml          | 210 ++++++++++++
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts   |   1 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi     |  14 +-
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 306 ++++++++++++++++--
 5 files changed, 503 insertions(+), 119 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
 create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.yaml

--
2.18.0




From biao.huang at mediatek.com  Mon Jan  3 19:39:36 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:36 +0800
Subject: [PATCH net-next v11 2/6] stmmac: dwmac-mediatek: Reuse more common
 features
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-3-biao.huang@mediatek.com>

This patch makes dwmac-mediatek reuse more features
supported by stmmac_platform.c.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 32 +++++++++----------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 0ff57c268dca..8747aa4403e8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -334,22 +334,20 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
 	const struct mediatek_dwmac_variant *variant = plat->variant;
 	int ret;
 
-	ret = dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(variant->dma_bit_mask));
-	if (ret) {
-		dev_err(plat->dev, "No suitable DMA available, err = %d\n", ret);
-		return ret;
-	}
-
-	ret = variant->dwmac_set_phy_interface(plat);
-	if (ret) {
-		dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
-		return ret;
+	if (variant->dwmac_set_phy_interface) {
+		ret = variant->dwmac_set_phy_interface(plat);
+		if (ret) {
+			dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
+			return ret;
+		}
 	}
 
-	ret = variant->dwmac_set_delay(plat);
-	if (ret) {
-		dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
-		return ret;
+	if (variant->dwmac_set_delay) {
+		ret = variant->dwmac_set_delay(plat);
+		if (ret) {
+			dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
+			return ret;
+		}
 	}
 
 	ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
@@ -422,15 +420,15 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 		return PTR_ERR(plat_dat);
 
 	plat_dat->interface = priv_plat->phy_mode;
-	plat_dat->has_gmac4 = 1;
-	plat_dat->has_gmac = 0;
-	plat_dat->pmt = 0;
+	plat_dat->use_phy_wol = 1;
 	plat_dat->riwt_off = 1;
 	plat_dat->maxmtu = ETH_DATA_LEN;
+	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
 	plat_dat->bsp_priv = priv_plat;
 	plat_dat->init = mediatek_dwmac_init;
 	plat_dat->exit = mediatek_dwmac_exit;
 	plat_dat->clks_config = mediatek_dwmac_clks_config;
+
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-- 
2.25.1



From biao.huang at mediatek.com  Mon Jan  3 19:39:35 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:35 +0800
Subject: [PATCH net-next v11 1/6] stmmac: dwmac-mediatek: add platform level
 clocks management
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-2-biao.huang@mediatek.com>

This patch implements clks_config callback for dwmac-mediatek platform,
which could support platform level clocks management.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 25 +++++++++++++------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 58c0feaa8131..0ff57c268dca 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -9,7 +9,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_net.h>
-#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/stmmac.h>
 
@@ -359,9 +358,6 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
 		return ret;
 	}
 
-	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
-
 	return 0;
 }
 
@@ -370,11 +366,25 @@ static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
 	struct mediatek_dwmac_plat_data *plat = priv;
 
 	clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
-
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
 }
 
+static int mediatek_dwmac_clks_config(void *priv, bool enabled)
+{
+	struct mediatek_dwmac_plat_data *plat = priv;
+	int ret = 0;
+
+	if (enabled) {
+		ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
+		if (ret) {
+			dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
+			return ret;
+		}
+	} else {
+		clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
+	}
+
+	return ret;
+}
 static int mediatek_dwmac_probe(struct platform_device *pdev)
 {
 	struct mediatek_dwmac_plat_data *priv_plat;
@@ -420,6 +430,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	plat_dat->bsp_priv = priv_plat;
 	plat_dat->init = mediatek_dwmac_init;
 	plat_dat->exit = mediatek_dwmac_exit;
+	plat_dat->clks_config = mediatek_dwmac_clks_config;
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-- 
2.25.1



From biao.huang at mediatek.com  Mon Jan  3 19:39:40 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:40 +0800
Subject: [PATCH net-next v11 6/6] net: dt-bindings: dwmac: add support for
 mt8195
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-7-biao.huang@mediatek.com>

Add binding document for the ethernet on mt8195.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 .../bindings/net/mediatek-dwmac.yaml          | 95 +++++++++++++++----
 1 file changed, 75 insertions(+), 20 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
index 8ad6e19661b8..fb04166404d8 100644
--- a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
@@ -19,34 +19,79 @@ select:
       contains:
         enum:
           - mediatek,mt2712-gmac
+          - mediatek,mt8195-gmac
   required:
     - compatible
 
 allOf:
   - $ref: "snps,dwmac.yaml#"
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt2712-gmac
+
+    then:
+      properties:
+        clocks:
+          minItems: 5
+          items:
+            - description: AXI clock
+            - description: APB clock
+            - description: MAC Main clock
+            - description: PTP clock
+            - description: RMII reference clock provided by MAC
+
+        clock-names:
+          minItems: 5
+          items:
+            - const: axi
+            - const: apb
+            - const: mac_main
+            - const: ptp_ref
+            - const: rmii_internal
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8195-gmac
+
+    then:
+      properties:
+        clocks:
+          minItems: 6
+          items:
+            - description: AXI clock
+            - description: APB clock
+            - description: MAC clock gate
+            - description: MAC Main clock
+            - description: PTP clock
+            - description: RMII reference clock provided by MAC
+
+        clock-names:
+          minItems: 6
+          items:
+            - const: axi
+            - const: apb
+            - const: mac_cg
+            - const: mac_main
+            - const: ptp_ref
+            - const: rmii_internal
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt2712-gmac
-      - const: snps,dwmac-4.20a
-
-  clocks:
-    items:
-      - description: AXI clock
-      - description: APB clock
-      - description: MAC Main clock
-      - description: PTP clock
-      - description: RMII reference clock provided by MAC
-
-  clock-names:
-    items:
-      - const: axi
-      - const: apb
-      - const: mac_main
-      - const: ptp_ref
-      - const: rmii_internal
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt2712-gmac
+          - const: snps,dwmac-4.20a
+      - items:
+          - enum:
+              - mediatek,mt8195-gmac
+          - const: snps,dwmac-5.10a
 
   mediatek,pericfg:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -61,6 +106,8 @@ properties:
       or will round down. Range 0~31*170.
       For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
       or will round down. Range 0~31*550.
+      For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple of 290,
+      or will round down. Range 0~31*290.
 
   mediatek,rx-delay-ps:
     description:
@@ -69,6 +116,8 @@ properties:
       or will round down. Range 0~31*170.
       For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
       or will round down. Range 0~31*550.
+      For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple
+      of 290, or will round down. Range 0~31*290.
 
   mediatek,rmii-rxc:
     type: boolean
@@ -102,6 +151,12 @@ properties:
       3. the inside clock, which be sent to MAC, will be inversed in RMII case when
          the reference clock is from MAC.
 
+  mediatek,mac-wol:
+    type: boolean
+    description:
+      If present, indicates that MAC supports WOL(Wake-On-LAN), and MAC WOL will be enabled.
+      Otherwise, PHY WOL is perferred.
+
 required:
   - compatible
   - reg
-- 
2.25.1



From biao.huang at mediatek.com  Mon Jan  3 19:39:38 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:38 +0800
Subject: [PATCH net-next v11 4/6] net: dt-bindings: dwmac: Convert
 mediatek-dwmac to DT schema
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-5-biao.huang@mediatek.com>

Convert mediatek-dwmac to DT schema, and delete old mediatek-dwmac.txt.
And there are some changes in .yaml than .txt, others almost keep the same:
  1. compatible "const: snps,dwmac-4.20".
  2. delete "snps,reset-active-low;" in example, since driver remove this
     property long ago.
  3. add "snps,reset-delay-us = <0 10000 10000>" in example.
  4. the example is for rgmii interface, keep related properties only.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/net/mediatek-dwmac.txt           |  91 ----------
 .../bindings/net/mediatek-dwmac.yaml          | 155 ++++++++++++++++++
 2 files changed, 155 insertions(+), 91 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
 create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.yaml

diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
deleted file mode 100644
index afbcaebf062e..000000000000
--- a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-MediaTek DWMAC glue layer controller
-
-This file documents platform glue layer for stmmac.
-Please see stmmac.txt for the other unchanged properties.
-
-The device node has following properties.
-
-Required properties:
-- compatible:  Should be "mediatek,mt2712-gmac" for MT2712 SoC
-- reg:  Address and length of the register set for the device
-- interrupts:  Should contain the MAC interrupts
-- interrupt-names: Should contain a list of interrupt names corresponding to
-	the interrupts in the interrupts property, if available.
-	Should be "macirq" for the main MAC IRQ
-- clocks: Must contain a phandle for each entry in clock-names.
-- clock-names: The name of the clock listed in the clocks property. These are
-	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal" for MT2712 SoC.
-- mac-address: See ethernet.txt in the same directory
-- phy-mode: See ethernet.txt in the same directory
-- mediatek,pericfg: A phandle to the syscon node that control ethernet
-	interface and timing delay.
-
-Optional properties:
-- mediatek,tx-delay-ps: TX clock delay macro value. Default is 0.
-	It should be defined for RGMII/MII interface.
-	It should be defined for RMII interface when the reference clock is from MT2712 SoC.
-- mediatek,rx-delay-ps: RX clock delay macro value. Default is 0.
-	It should be defined for RGMII/MII interface.
-	It should be defined for RMII interface.
-Both delay properties need to be a multiple of 170 for RGMII interface,
-or will round down. Range 0~31*170.
-Both delay properties need to be a multiple of 550 for MII/RMII interface,
-or will round down. Range 0~31*550.
-
-- mediatek,rmii-rxc: boolean property, if present indicates that the RMII
-	reference clock, which is from external PHYs, is connected to RXC pin
-	on MT2712 SoC.
-	Otherwise, is connected to TXC pin.
-- mediatek,rmii-clk-from-mac: boolean property, if present indicates that
-	MT2712 SoC provides the RMII reference clock, which outputs to TXC pin only.
-- mediatek,txc-inverse: boolean property, if present indicates that
-	1. tx clock will be inversed in MII/RGMII case,
-	2. tx clock inside MAC will be inversed relative to reference clock
-	   which is from external PHYs in RMII case, and it rarely happen.
-	3. the reference clock, which outputs to TXC pin will be inversed in RMII case
-	   when the reference clock is from MT2712 SoC.
-- mediatek,rxc-inverse: boolean property, if present indicates that
-	1. rx clock will be inversed in MII/RGMII case.
-	2. reference clock will be inversed when arrived at MAC in RMII case, when
-	   the reference clock is from external PHYs.
-	3. the inside clock, which be sent to MAC, will be inversed in RMII case when
-	   the reference clock is from MT2712 SoC.
-- assigned-clocks: mac_main and ptp_ref clocks
-- assigned-clock-parents: parent clocks of the assigned clocks
-
-Example:
-	eth: ethernet at 1101c000 {
-		compatible = "mediatek,mt2712-gmac";
-		reg = <0 0x1101c000 0 0x1300>;
-		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-names = "macirq";
-		phy-mode ="rgmii-rxid";
-		mac-address = [00 55 7b b5 7d f7];
-		clock-names = "axi",
-			      "apb",
-			      "mac_main",
-			      "ptp_ref",
-			      "rmii_internal";
-		clocks = <&pericfg CLK_PERI_GMAC>,
-			 <&pericfg CLK_PERI_GMAC_PCLK>,
-			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
-		assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
-		assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
-					 <&topckgen CLK_TOP_APLL1_D3>,
-					 <&topckgen CLK_TOP_ETHERPLL_50M>;
-		power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
-		mediatek,pericfg = <&pericfg>;
-		mediatek,tx-delay-ps = <1530>;
-		mediatek,rx-delay-ps = <1530>;
-		mediatek,rmii-rxc;
-		mediatek,txc-inverse;
-		mediatek,rxc-inverse;
-		snps,txpbl = <1>;
-		snps,rxpbl = <1>;
-		snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
-		snps,reset-active-low;
-	};
diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
new file mode 100644
index 000000000000..8ad6e19661b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
@@ -0,0 +1,155 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/mediatek-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek DWMAC glue layer controller
+
+maintainers:
+  - Biao Huang <biao.huang at mediatek.com>
+
+description:
+  This file documents platform glue layer for stmmac.
+
+# We need a select here so we don't match all nodes with 'snps,dwmac'
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - mediatek,mt2712-gmac
+  required:
+    - compatible
+
+allOf:
+  - $ref: "snps,dwmac.yaml#"
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt2712-gmac
+      - const: snps,dwmac-4.20a
+
+  clocks:
+    items:
+      - description: AXI clock
+      - description: APB clock
+      - description: MAC Main clock
+      - description: PTP clock
+      - description: RMII reference clock provided by MAC
+
+  clock-names:
+    items:
+      - const: axi
+      - const: apb
+      - const: mac_main
+      - const: ptp_ref
+      - const: rmii_internal
+
+  mediatek,pericfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle to the syscon node that control ethernet
+      interface and timing delay.
+
+  mediatek,tx-delay-ps:
+    description:
+      The internal TX clock delay (provided by this driver) in nanoseconds.
+      For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+      or will round down. Range 0~31*170.
+      For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+      or will round down. Range 0~31*550.
+
+  mediatek,rx-delay-ps:
+    description:
+      The internal RX clock delay (provided by this driver) in nanoseconds.
+      For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+      or will round down. Range 0~31*170.
+      For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+      or will round down. Range 0~31*550.
+
+  mediatek,rmii-rxc:
+    type: boolean
+    description:
+      If present, indicates that the RMII reference clock, which is from external
+      PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+  mediatek,rmii-clk-from-mac:
+    type: boolean
+    description:
+      If present, indicates that MAC provides the RMII reference clock, which
+      outputs to TXC pin only.
+
+  mediatek,txc-inverse:
+    type: boolean
+    description:
+      If present, indicates that
+      1. tx clock will be inversed in MII/RGMII case,
+      2. tx clock inside MAC will be inversed relative to reference clock
+         which is from external PHYs in RMII case, and it rarely happen.
+      3. the reference clock, which outputs to TXC pin will be inversed in RMII case
+         when the reference clock is from MAC.
+
+  mediatek,rxc-inverse:
+    type: boolean
+    description:
+      If present, indicates that
+      1. rx clock will be inversed in MII/RGMII case.
+      2. reference clock will be inversed when arrived at MAC in RMII case, when
+         the reference clock is from external PHYs.
+      3. the inside clock, which be sent to MAC, will be inversed in RMII case when
+         the reference clock is from MAC.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - phy-mode
+  - mediatek,pericfg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2712-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt2712-power.h>
+
+    eth: ethernet at 1101c000 {
+        compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
+        reg = <0x1101c000 0x1300>;
+        interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
+        interrupt-names = "macirq";
+        phy-mode ="rgmii-rxid";
+        mac-address = [00 55 7b b5 7d f7];
+        clock-names = "axi",
+                      "apb",
+                      "mac_main",
+                      "ptp_ref",
+                      "rmii_internal";
+        clocks = <&pericfg CLK_PERI_GMAC>,
+                 <&pericfg CLK_PERI_GMAC_PCLK>,
+                 <&topckgen CLK_TOP_ETHER_125M_SEL>,
+                 <&topckgen CLK_TOP_ETHER_50M_SEL>,
+                 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+        assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
+                          <&topckgen CLK_TOP_ETHER_50M_SEL>,
+                          <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
+                                 <&topckgen CLK_TOP_APLL1_D3>,
+                                 <&topckgen CLK_TOP_ETHERPLL_50M>;
+        power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
+        mediatek,pericfg = <&pericfg>;
+        mediatek,tx-delay-ps = <1530>;
+        snps,txpbl = <1>;
+        snps,rxpbl = <1>;
+        snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+        snps,reset-delays-us = <0 10000 10000>;
+    };
-- 
2.25.1



From biao.huang at mediatek.com  Mon Jan  3 19:39:37 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:37 +0800
Subject: [PATCH net-next v11 3/6] arm64: dts: mt2712: update ethernet device
 node
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-4-biao.huang@mediatek.com>

Since there are some changes in ethernet driver:
update ethernet device node in dts to accommodate to it.

1. stmmac_probe_config_dt() in stmmac_platform.c will initialize specified
   parameters according to compatible string "snps,dwmac-4.20a", then,
   dwmac-mediatek.c can skip the initialization if add compatible string
   "snps,dwmac-4.20a" in eth device node.
2. commit 882007ed7832 added rmii internal support, we should add
   corresponding clocks/clocks-names in eth device node.
3. add "snps,reset-delays-us = <0 10000 10000>;" to ensure reset delay
   can meet PHY requirement.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts |  1 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi   | 14 +++++++++-----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 7d369fdd3117..11aa135aa0f3 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -110,6 +110,7 @@ &eth {
 	phy-handle = <&ethernet_phy0>;
 	mediatek,tx-delay-ps = <1530>;
 	snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+	snps,reset-delays-us = <0 10000 10000>;
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth_default>;
 	pinctrl-1 = <&eth_sleep>;
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index a9cca9c146fd..9e850e04fffb 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -726,7 +726,7 @@ queue2 {
 	};
 
 	eth: ethernet at 1101c000 {
-		compatible = "mediatek,mt2712-gmac";
+		compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
 		reg = <0 0x1101c000 0 0x1300>;
 		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-names = "macirq";
@@ -734,15 +734,19 @@ eth: ethernet at 1101c000 {
 		clock-names = "axi",
 			      "apb",
 			      "mac_main",
-			      "ptp_ref";
+			      "ptp_ref",
+			      "rmii_internal";
 		clocks = <&pericfg CLK_PERI_GMAC>,
 			 <&pericfg CLK_PERI_GMAC_PCLK>,
 			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_SEL>;
+			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
+			 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
 		assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_SEL>;
+				  <&topckgen CLK_TOP_ETHER_50M_SEL>,
+				  <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
 		assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
-					 <&topckgen CLK_TOP_APLL1_D3>;
+					 <&topckgen CLK_TOP_APLL1_D3>,
+					 <&topckgen CLK_TOP_ETHERPLL_50M>;
 		power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
 		mediatek,pericfg = <&pericfg>;
 		snps,axi-config = <&stmmac_axi_setup>;
-- 
2.25.1



From biao.huang at mediatek.com  Mon Jan  3 19:39:39 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 4 Jan 2022 11:39:39 +0800
Subject: [PATCH net-next v11 5/6] stmmac: dwmac-mediatek: add support for
 mt8195
In-Reply-To: <20220104033940.5497-1-biao.huang@mediatek.com>
References: <20220104033940.5497-1-biao.huang@mediatek.com>
Message-ID: <20220104033940.5497-6-biao.huang@mediatek.com>

Add Ethernet support for MediaTek SoCs from the mt8195 family.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 253 +++++++++++++++++-
 1 file changed, 252 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 8747aa4403e8..bbb94aeee104 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -39,6 +39,33 @@
 #define ETH_FINE_DLY_GTXC	BIT(1)
 #define ETH_FINE_DLY_RXC	BIT(0)
 
+/* Peri Configuration register for mt8195 */
+#define MT8195_PERI_ETH_CTRL0		0xFD0
+#define MT8195_RMII_CLK_SRC_INTERNAL	BIT(28)
+#define MT8195_RMII_CLK_SRC_RXC		BIT(27)
+#define MT8195_ETH_INTF_SEL		GENMASK(26, 24)
+#define MT8195_RGMII_TXC_PHASE_CTRL	BIT(22)
+#define MT8195_EXT_PHY_MODE		BIT(21)
+#define MT8195_DLY_GTXC_INV		BIT(12)
+#define MT8195_DLY_GTXC_ENABLE		BIT(5)
+#define MT8195_DLY_GTXC_STAGES		GENMASK(4, 0)
+
+#define MT8195_PERI_ETH_CTRL1		0xFD4
+#define MT8195_DLY_RXC_INV		BIT(25)
+#define MT8195_DLY_RXC_ENABLE		BIT(18)
+#define MT8195_DLY_RXC_STAGES		GENMASK(17, 13)
+#define MT8195_DLY_TXC_INV		BIT(12)
+#define MT8195_DLY_TXC_ENABLE		BIT(5)
+#define MT8195_DLY_TXC_STAGES		GENMASK(4, 0)
+
+#define MT8195_PERI_ETH_CTRL2		0xFD8
+#define MT8195_DLY_RMII_RXC_INV		BIT(25)
+#define MT8195_DLY_RMII_RXC_ENABLE	BIT(18)
+#define MT8195_DLY_RMII_RXC_STAGES	GENMASK(17, 13)
+#define MT8195_DLY_RMII_TXC_INV		BIT(12)
+#define MT8195_DLY_RMII_TXC_ENABLE	BIT(5)
+#define MT8195_DLY_RMII_TXC_STAGES	GENMASK(4, 0)
+
 struct mac_delay_struct {
 	u32 tx_delay;
 	u32 rx_delay;
@@ -57,11 +84,13 @@ struct mediatek_dwmac_plat_data {
 	int num_clks_to_config;
 	bool rmii_clk_from_mac;
 	bool rmii_rxc;
+	bool mac_wol;
 };
 
 struct mediatek_dwmac_variant {
 	int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat);
 	int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
+	void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed);
 
 	/* clock ids to be requested */
 	const char * const *clk_list;
@@ -77,6 +106,10 @@ static const char * const mt2712_dwmac_clk_l[] = {
 	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
 };
 
+static const char * const mt8195_dwmac_clk_l[] = {
+	"axi", "apb", "mac_cg", "mac_main", "ptp_ref", "rmii_internal"
+};
+
 static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
 {
 	int rmii_clk_from_mac = plat->rmii_clk_from_mac ? RMII_CLK_SRC_INTERNAL : 0;
@@ -267,6 +300,204 @@ static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
 		.tx_delay_max = 17600,
 };
 
+static int mt8195_set_interface(struct mediatek_dwmac_plat_data *plat)
+{
+	int rmii_clk_from_mac = plat->rmii_clk_from_mac ? MT8195_RMII_CLK_SRC_INTERNAL : 0;
+	int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
+	u32 intf_val = 0;
+
+	/* The clock labeled as "rmii_internal" in mt8195_dwmac_clk_l is needed
+	 * only in RMII(when MAC provides the reference clock), and useless for
+	 * RGMII/MII/RMII(when PHY provides the reference clock).
+	 * num_clks_to_config indicates the real number of clocks should be
+	 * configured, equals to (plat->variant->num_clks - 1) in default for all the case,
+	 * then +1 for rmii_clk_from_mac case.
+	 */
+	plat->num_clks_to_config = plat->variant->num_clks - 1;
+
+	/* select phy interface in top control domain */
+	switch (plat->phy_mode) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_MII);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (plat->rmii_clk_from_mac)
+			plat->num_clks_to_config++;
+		intf_val |= (rmii_rxc | rmii_clk_from_mac);
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RMII);
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RGMII);
+		break;
+	default:
+		dev_err(plat->dev, "phy interface not supported\n");
+		return -EINVAL;
+	}
+
+	/* MT8195 only support external PHY */
+	intf_val |= MT8195_EXT_PHY_MODE;
+
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL0, intf_val);
+
+	return 0;
+}
+
+static void mt8195_delay_ps2stage(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+
+	/* 290ps per stage */
+	mac_delay->tx_delay /= 290;
+	mac_delay->rx_delay /= 290;
+}
+
+static void mt8195_delay_stage2ps(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+
+	/* 290ps per stage */
+	mac_delay->tx_delay *= 290;
+	mac_delay->rx_delay *= 290;
+}
+
+static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+	u32 gtxc_delay_val = 0, delay_val = 0, rmii_delay_val = 0;
+
+	mt8195_delay_ps2stage(plat);
+
+	switch (plat->phy_mode) {
+	case PHY_INTERFACE_MODE_MII:
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE, !!mac_delay->tx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES, mac_delay->tx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV, mac_delay->tx_inv);
+
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES, mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay->rx_inv);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (plat->rmii_clk_from_mac) {
+			/* case 1: mac provides the rmii reference clock,
+			 * and the clock output to TXC pin.
+			 * The egress timing can be adjusted by RMII_TXC delay macro circuit.
+			 * The ingress timing can be adjusted by RMII_RXC delay macro circuit.
+			 */
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_ENABLE,
+						     !!mac_delay->tx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_STAGES,
+						     mac_delay->tx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_INV,
+						     mac_delay->tx_inv);
+
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_ENABLE,
+						     !!mac_delay->rx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_STAGES,
+						     mac_delay->rx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_INV,
+						     mac_delay->rx_inv);
+		} else {
+			/* case 2: the rmii reference clock is from external phy,
+			 * and the property "rmii_rxc" indicates which pin(TXC/RXC)
+			 * the reference clk is connected to. The reference clock is a
+			 * received signal, so rx_delay/rx_inv are used to indicate
+			 * the reference clock timing adjustment
+			 */
+			if (plat->rmii_rxc) {
+				/* the rmii reference clock from outside is connected
+				 * to RXC pin, the reference clock will be adjusted
+				 * by RXC delay macro circuit.
+				 */
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
+							!!mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
+							mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV,
+							mac_delay->rx_inv);
+			} else {
+				/* the rmii reference clock from outside is connected
+				 * to TXC pin, the reference clock will be adjusted
+				 * by TXC delay macro circuit.
+				 */
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE,
+							!!mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES,
+							mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV,
+							mac_delay->rx_inv);
+			}
+		}
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_ENABLE, !!mac_delay->tx_delay);
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_STAGES, mac_delay->tx_delay);
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_INV, mac_delay->tx_inv);
+
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES, mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay->rx_inv);
+
+		break;
+	default:
+		dev_err(plat->dev, "phy interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_update_bits(plat->peri_regmap,
+			   MT8195_PERI_ETH_CTRL0,
+			   MT8195_RGMII_TXC_PHASE_CTRL |
+			   MT8195_DLY_GTXC_INV |
+			   MT8195_DLY_GTXC_ENABLE |
+			   MT8195_DLY_GTXC_STAGES,
+			   gtxc_delay_val);
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL1, delay_val);
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL2, rmii_delay_val);
+
+	mt8195_delay_stage2ps(plat);
+
+	return 0;
+}
+
+static void mt8195_fix_mac_speed(void *priv, unsigned int speed)
+{
+	struct mediatek_dwmac_plat_data *priv_plat = priv;
+
+	if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) {
+		/* prefer 2ns fixed delay which is controlled by TXC_PHASE_CTRL,
+		 * when link speed is 1Gbps with RGMII interface,
+		 * Fall back to delay macro circuit for 10/100Mbps link speed.
+		 */
+		if (speed == SPEED_1000)
+			regmap_update_bits(priv_plat->peri_regmap,
+					   MT8195_PERI_ETH_CTRL0,
+					   MT8195_RGMII_TXC_PHASE_CTRL |
+					   MT8195_DLY_GTXC_ENABLE |
+					   MT8195_DLY_GTXC_INV |
+					   MT8195_DLY_GTXC_STAGES,
+					   MT8195_RGMII_TXC_PHASE_CTRL);
+		else
+			mt8195_set_delay(priv_plat);
+	}
+}
+
+static const struct mediatek_dwmac_variant mt8195_gmac_variant = {
+	.dwmac_set_phy_interface = mt8195_set_interface,
+	.dwmac_set_delay = mt8195_set_delay,
+	.dwmac_fix_mac_speed = mt8195_fix_mac_speed,
+	.clk_list = mt8195_dwmac_clk_l,
+	.num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l),
+	.dma_bit_mask = 35,
+	.rx_delay_max = 9280,
+	.tx_delay_max = 9280,
+};
+
 static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
 {
 	struct mac_delay_struct *mac_delay = &plat->mac_delay;
@@ -307,6 +538,7 @@ static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
 	mac_delay->rx_inv = of_property_read_bool(plat->np, "mediatek,rxc-inverse");
 	plat->rmii_rxc = of_property_read_bool(plat->np, "mediatek,rmii-rxc");
 	plat->rmii_clk_from_mac = of_property_read_bool(plat->np, "mediatek,rmii-clk-from-mac");
+	plat->mac_wol = of_property_read_bool(plat->np, "mediatek,mac-wol");
 
 	return 0;
 }
@@ -383,6 +615,7 @@ static int mediatek_dwmac_clks_config(void *priv, bool enabled)
 
 	return ret;
 }
+
 static int mediatek_dwmac_probe(struct platform_device *pdev)
 {
 	struct mediatek_dwmac_plat_data *priv_plat;
@@ -420,7 +653,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 		return PTR_ERR(plat_dat);
 
 	plat_dat->interface = priv_plat->phy_mode;
-	plat_dat->use_phy_wol = 1;
+	plat_dat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
 	plat_dat->riwt_off = 1;
 	plat_dat->maxmtu = ETH_DATA_LEN;
 	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
@@ -428,7 +661,23 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	plat_dat->init = mediatek_dwmac_init;
 	plat_dat->exit = mediatek_dwmac_exit;
 	plat_dat->clks_config = mediatek_dwmac_clks_config;
+	if (priv_plat->variant->dwmac_fix_mac_speed)
+		plat_dat->fix_mac_speed = priv_plat->variant->dwmac_fix_mac_speed;
+	plat_dat->safety_feat_cfg = devm_kzalloc(&pdev->dev,
+						 sizeof(*plat_dat->safety_feat_cfg),
+						 GFP_KERNEL);
+	if (!plat_dat->safety_feat_cfg)
+		return -ENOMEM;
 
+	plat_dat->safety_feat_cfg->tsoee = 1;
+	plat_dat->safety_feat_cfg->mrxpee = 0;
+	plat_dat->safety_feat_cfg->mestee = 1;
+	plat_dat->safety_feat_cfg->mrxee = 1;
+	plat_dat->safety_feat_cfg->mtxee = 1;
+	plat_dat->safety_feat_cfg->epsi = 0;
+	plat_dat->safety_feat_cfg->edpp = 1;
+	plat_dat->safety_feat_cfg->prtyen = 1;
+	plat_dat->safety_feat_cfg->tmouten = 1;
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
@@ -443,6 +692,8 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 static const struct of_device_id mediatek_dwmac_match[] = {
 	{ .compatible = "mediatek,mt2712-gmac",
 	  .data = &mt2712_gmac_variant },
+	{ .compatible = "mediatek,mt8195-gmac",
+	  .data = &mt8195_gmac_variant },
 	{ }
 };
 
-- 
2.25.1



From liuqi115 at huawei.com  Mon Jan  3 19:50:58 2022
From: liuqi115 at huawei.com (liuqi (BA))
Date: Tue, 4 Jan 2022 11:50:58 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
Message-ID: <56ed3ad1-eb99-97f5-d505-2dce17c4b8b1@huawei.com>



On 2022/1/4 10:35, Masami Hiramatsu wrote:
> Hi Jianhua,
> 
> On Mon, 3 Jan 2022 17:03:33 +0800
> Jianhua Liu <jianhua.ljh at gmail.com> wrote:
> 
>> Hi Qi,
>> I have tested your patch on UNISOC s9863a.
>> Test case "kprobe_example & kretprobe_example" is OK.
>>
>> Two point:
>> 1. backtrace is not perfect.
>>     optprobe_common does not saved frame pointer,
>>     backtrace lacks two calls.
>> such as for dup_mm: lack copy_process-->dup_mm
>> dup_mm backtrace from your patch:
>> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
>> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>> [  832.387083] Call trace:
>> [  832.387086]  dump_backtrace+0x0/0x1e0
>> [  832.387103]  show_stack+0x24/0x30
>> [  832.387112]  dump_stack_lvl+0x68/0x84
>> [  832.387123]  dump_stack+0x18/0x34
>> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
>> [  832.387143]  opt_pre_handler+0x84/0xc0
>> [  832.387154]  optprobe_optimized_callback+0xec/0x164
>> [  832.387164]  optprobe_common+0x70/0xc4
>> [  832.387173]  kernel_clone+0x98/0x440
>> [  832.387182]  __do_sys_clone+0x54/0x80
>> [  832.387191]  __arm64_sys_clone+0x2c/0x40
>> [  832.387199]  invoke_syscall+0x50/0x120
>> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
>> [  832.387217]  do_el0_svc+0x30/0x9c
>> [  832.387225]  el0_svc+0x20/0x60
>> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
>> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
>>
>>
>> dup_mm backtrace from other:
>> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
>> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>> [  173.352304] Call trace:
>> [  173.352307]  dump_backtrace+0x0/0x1d4
>> [  173.352319]  show_stack+0x18/0x24
>> [  173.352326]  dump_stack_lvl+0x68/0x84
>> [  173.352333]  dump_stack+0x18/0x34
>> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
>> [  173.352347]  opt_pre_handler+0x74/0xb0
>> [  173.352354]  optimized_callback+0x108/0x130
>> [  173.352361]  optinsn_slot+0x258/0x1000
>> [  173.352366]  dup_mm+0x4/0x4b0
>> [  173.352373]  copy_process+0x1284/0x1360
>> [  173.352378]  kernel_clone+0x5c/0x3c0
>> [  173.352384]  __do_sys_clone+0x54/0x80
>> [  173.352390]  __arm64_sys_clone+0x24/0x30
>> [  173.352396]  invoke_syscall+0x48/0x114
>> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
>> [  173.352408]  do_el0_svc+0x24/0x90
>> [  173.352413]  el0_svc+0x20/0x60
>> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
>> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
> 
> Is the second one with your patch?
> 
>>
>> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
>>     kernel/kprobe.c used only one PAGE_SIZE slot memory.
> 
Hi Masami,
> Good catch!
> Qi, can you make an array (or bit map) of usage flags and
> manage the reserved memory?
> 

Sure, I'll add and test this in bext version, thanks.
Qi
> #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
> static bool insn_page_in_use[OPT_INSN_PAGES];
> 
> void *alloc_optinsn_page(void)
> {
> 	int i;
> 
> 	for (i = 0; i < OPT_INSN_PAGES; i++)
> 		if (!insn_page_in_use[i])
> 			goto found;
> 	return NULL;
> found:
> 	insn_page_in_use[i] = true;
> 	return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
> }
> 
> void free_optinsn_page(void *page)
> {
> 	unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
> 
> 	WARN_ONCE(idx & (PAGE_SIZE - 1));
> 	idx >>= PAGE_SHIFT;
> 	if (WARN_ONCE(idx >= OPT_INSN_PAGES))
> 		return;
> 	insn_page_in_use[idx] = false;
> }
> 
> Thank you,
> 
> 
> 
> 


From kuba at kernel.org  Mon Jan  3 20:06:37 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 3 Jan 2022 20:06:37 -0800
Subject: [PATCH 0/3] ARM: ox810se: Add Ethernet support
In-Reply-To: <20220103175638.89625-1-narmstrong@baylibre.com>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
Message-ID: <20220103200637.0b9d7e4f@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Mon,  3 Jan 2022 18:56:35 +0100 Neil Armstrong wrote:
> This adds support for the Synopsys DWMAC controller found in the
> OX820SE SoC, by using almost the same glue code as the OX820.
> 
> Neil Armstrong (3):
>   dt-bindings: net: oxnas-dwmac: Add bindings for OX810SE
>   net: stmmac: dwmac-oxnas: Add support for OX810SE
>   ARM: dts: ox810se: Add Ethernet support

Judging by the subject tag on patches 1 and 2 and To: I presume you
intend this series to be merged via net-next? Can you please repost
with patch 3 CCed to netdev as well? It didn't register in patchwork.


From anshuman.khandual at arm.com  Mon Jan  3 20:16:10 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 4 Jan 2022 09:46:10 +0530
Subject: [PATCH V2] arm64/mm/hotplug: Warn when memory limit has been
 reduced
In-Reply-To: <d8753c88-95f3-75ec-d6b6-27105a9a5968@redhat.com>
References: <1641190916-24751-1-git-send-email-anshuman.khandual@arm.com>
 <bd3f2157-858c-b091-0982-12c425b2029a@redhat.com>
 <c4104b5d-45b8-732a-45e9-0a1cb4954dde@arm.com>
 <d8753c88-95f3-75ec-d6b6-27105a9a5968@redhat.com>
Message-ID: <749bfac7-00b9-0350-18b7-2c3388646853@arm.com>



On 1/3/22 6:27 PM, David Hildenbrand wrote:
> 
>>> Via which mechanism would the unplug of that memory happen? On arm64,
>>> this should only be possible via ACPI, when unplugging a DIMM that was
>>> available since boot.
>>>
>>> But won't acpi_memory_enable_device() try adding that memory while
>>> ignoring the memory limit? And adding should work, no?
>>
>> Adding that memory via hotplug into the kernel first ? In that case
>> removal would still go via the kernel and user would know about it.
> 
> Can we please add details on how to actually trigger it (below) to the
> patch description? Otherwise it's really hard to get about which senario
> we do care, and about which we don't care.

Sure, will try and add those details in the commit message.

> 
>>
>>>
>>> Can you share some details on how to trigger this on arm64?
>>
>> The primary scenario this proposal is targeted towards is when boot
>> memory is set aside from the host, hot-plugged back into the kernel
>> and repurposed (via hotplug-hotremove path) for guest kernel usage.
>> This new warning would reassert that "mem=" cmdline option is debug
>> only on arm64 platform, and should not be used for production.
> Let me get this straight:
> 
> 1. Restrict physical memory to use via "mem="
> 
> -> Some boot memory is !present and, therefore !early
> 
> 2. Hotplug that memory to the kernel
> 
> -> How?
> 
> a) dax/kmem? Does not apply I think.
> b) DIMM? Does not apply I think.
> c) CONFIG_ARCH_MEMORY_PROBE ?
> 
> 3. Trigger physical hotunplug and actually remove the memory
> 
> -> How?
> 
> 4. kexec; will try using hotunplugged memory
> 
> 


From sam.shih at mediatek.com  Mon Jan  3 20:52:40 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 4 Jan 2022 12:52:40 +0800
Subject: No subject
Message-ID: <20220104045243.21521-1-sam.shih@mediatek.com>

Subject: [PATCH v8 0/3] Mediatek MT7986 basic clock support

This patch series add basic clock support for mediatek mt7986 SoC.
It is based on patch series "Add basic SoC support for mediatek mt7986"
https://lore.kernel.org/all/20211018114009.13350-1-sam.shih at mediatek.com/
that has been merged into matthias's tree recently:
https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/log/?h=v5.16-next/dts64

---
v8: update the git message, and add a Reviewed-by tag for this series 
v7: exclude DTS changes in the patch series
v5: used builtin_platform_driver instead of CLK_OF_DECLARE
    follow recent clk-mt8195 clock patch series:
    https://lore.kernel.org/linux-arm-kernel/20210914021633.26377-1-chun-jie.chen at mediatek.com/

v4:
According to the maintainer??s suggestion, this patch splits the previous
thread into independent patch series.
This patch include clock driver and device tree update

Original thread:
https://lore.kernel.org/all/20210914085137.31761-1-sam.shih at mediatek.com/
https://lore.kernel.org/linux-arm-kernel/20210914085137.31761-2-sam.shih at mediatek.com/
---

Sam Shih (3):
  dt-bindings: clock: mediatek: document clk bindings for mediatek
    mt7986 SoC
  clk: mediatek: add mt7986 clock IDs
  clk: mediatek: add mt7986 clock support

 .../arm/mediatek/mediatek,apmixedsys.txt      |   1 +
 .../bindings/arm/mediatek/mediatek,ethsys.txt |   1 +
 .../arm/mediatek/mediatek,infracfg.txt        |   1 +
 .../arm/mediatek/mediatek,sgmiisys.txt        |   2 +
 .../arm/mediatek/mediatek,topckgen.txt        |   1 +
 drivers/clk/mediatek/Kconfig                  |  17 +
 drivers/clk/mediatek/Makefile                 |   4 +
 drivers/clk/mediatek/clk-mt7986-apmixed.c     | 100 +++++
 drivers/clk/mediatek/clk-mt7986-eth.c         | 132 +++++++
 drivers/clk/mediatek/clk-mt7986-infracfg.c    | 224 ++++++++++++
 drivers/clk/mediatek/clk-mt7986-topckgen.c    | 342 ++++++++++++++++++
 include/dt-bindings/clock/mt7986-clk.h        | 169 +++++++++
 12 files changed, 994 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7986-apmixed.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-eth.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-infracfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-topckgen.c
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

-- 
2.29.2



From sam.shih at mediatek.com  Mon Jan  3 20:52:41 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 4 Jan 2022 12:52:41 +0800
Subject: [PATCH v8 1/3] dt-bindings: clock: mediatek: document clk bindings
 for mediatek mt7986 SoC
In-Reply-To: <20220104045243.21521-1-sam.shih@mediatek.com>
References: <20220104045243.21521-1-sam.shih@mediatek.com>
Message-ID: <20220104045243.21521-2-sam.shih@mediatek.com>

This patch adds the binding documentation for topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Ryder Lee <ryder.lee at kernel.org>
---
v8: add a Reviewed-by tag
v7: exclude DTS changes in the patch series
v4: separate clock part into a single patch series

Original thread:
https://lore.kernel.org/linux-arm-kernel/20210914085137.31761-2-sam.shih at mediatek.com/

v3: Added an Acked-by tag
v2: remove compatiable string 'mt7986-sgmiisys'
---
---
 .../devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt    | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,ethsys.txt        | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,infracfg.txt      | 1 +
 .../devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt      | 2 ++
 .../devicetree/bindings/arm/mediatek/mediatek,topckgen.txt      | 1 +
 5 files changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
index ea827e8763de..3fa755866528 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt
@@ -14,6 +14,7 @@ Required Properties:
 	- "mediatek,mt7622-apmixedsys"
 	- "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
 	- "mediatek,mt7629-apmixedsys"
+	- "mediatek,mt7986-apmixedsys"
 	- "mediatek,mt8135-apmixedsys"
 	- "mediatek,mt8167-apmixedsys", "syscon"
 	- "mediatek,mt8173-apmixedsys"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
index 6b7e8067e7aa..0502db73686b 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,ethsys.txt
@@ -10,6 +10,7 @@ Required Properties:
 	- "mediatek,mt7622-ethsys", "syscon"
 	- "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
 	- "mediatek,mt7629-ethsys", "syscon"
+	- "mediatek,mt7986-ethsys", "syscon"
 - #clock-cells: Must be 1
 - #reset-cells: Must be 1
 
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
index eb3523c7a7be..f66bd720571d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt
@@ -15,6 +15,7 @@ Required Properties:
 	- "mediatek,mt7622-infracfg", "syscon"
 	- "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
 	- "mediatek,mt7629-infracfg", "syscon"
+	- "mediatek,mt7986-infracfg", "syscon"
 	- "mediatek,mt8135-infracfg", "syscon"
 	- "mediatek,mt8167-infracfg", "syscon"
 	- "mediatek,mt8173-infracfg", "syscon"
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
index 30cb645c0e54..29ca7a10b315 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,sgmiisys.txt
@@ -8,6 +8,8 @@ Required Properties:
 - compatible: Should be:
 	- "mediatek,mt7622-sgmiisys", "syscon"
 	- "mediatek,mt7629-sgmiisys", "syscon"
+	- "mediatek,mt7986-sgmiisys_0", "syscon"
+	- "mediatek,mt7986-sgmiisys_1", "syscon"
 - #clock-cells: Must be 1
 
 The SGMIISYS controller uses the common clk binding from
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
index 5ce7578cf274..b82422bb717f 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt
@@ -14,6 +14,7 @@ Required Properties:
 	- "mediatek,mt7622-topckgen"
 	- "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
 	- "mediatek,mt7629-topckgen"
+	- "mediatek,mt7986-topckgen", "syscon"
 	- "mediatek,mt8135-topckgen"
 	- "mediatek,mt8167-topckgen", "syscon"
 	- "mediatek,mt8173-topckgen"
-- 
2.29.2



From sam.shih at mediatek.com  Mon Jan  3 20:52:42 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 4 Jan 2022 12:52:42 +0800
Subject: [PATCH v8 2/3] clk: mediatek: add mt7986 clock IDs
In-Reply-To: <20220104045243.21521-1-sam.shih@mediatek.com>
References: <20220104045243.21521-1-sam.shih@mediatek.com>
Message-ID: <20220104045243.21521-3-sam.shih@mediatek.com>

Add MT7986 clock dt-bindings, include topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Ryder Lee <ryder.lee at kernel.org>
---
v8: add a Reviewed-by tag
v7: exclude DTS changes in the patch series
v4: separate clock part into a single patch series

Original thread:
https://lore.kernel.org/lkml/20210914085137.31761-3-sam.shih at mediatek.com/
https://lore.kernel.org/lkml/YRxgXso7qQcAqg6+ at robh.at.kernel.org/

v3: Fixed SGMII wrong ID and added an Acked-by tag
v2: changed to dual licience
    applied the comment suggested by reviewers:
    - removed 1:1 factor clock
    - renamed factor clock for easier to understand
---
---
 include/dt-bindings/clock/mt7986-clk.h | 169 +++++++++++++++++++++++++
 1 file changed, 169 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h
new file mode 100644
index 000000000000..5a9b169324b0
--- /dev/null
+++ b/include/dt-bindings/clock/mt7986-clk.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7986_H
+#define _DT_BINDINGS_CLK_MT7986_H
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL		0
+#define CLK_APMIXED_NET2PLL		1
+#define CLK_APMIXED_MMPLL		2
+#define CLK_APMIXED_SGMPLL		3
+#define CLK_APMIXED_WEDMCUPLL		4
+#define CLK_APMIXED_NET1PLL		5
+#define CLK_APMIXED_MPLL		6
+#define CLK_APMIXED_APLL2		7
+
+/* TOPCKGEN */
+
+#define CLK_TOP_XTAL			0
+#define CLK_TOP_XTAL_D2			1
+#define CLK_TOP_RTC_32K			2
+#define CLK_TOP_RTC_32P7K		3
+#define CLK_TOP_MPLL_D2			4
+#define CLK_TOP_MPLL_D4			5
+#define CLK_TOP_MPLL_D8			6
+#define CLK_TOP_MPLL_D8_D2		7
+#define CLK_TOP_MPLL_D3_D2		8
+#define CLK_TOP_MMPLL_D2		9
+#define CLK_TOP_MMPLL_D4		10
+#define CLK_TOP_MMPLL_D8		11
+#define CLK_TOP_MMPLL_D8_D2		12
+#define CLK_TOP_MMPLL_D3_D8		13
+#define CLK_TOP_MMPLL_U2PHY		14
+#define CLK_TOP_APLL2_D4		15
+#define CLK_TOP_NET1PLL_D4		16
+#define CLK_TOP_NET1PLL_D5		17
+#define CLK_TOP_NET1PLL_D5_D2		18
+#define CLK_TOP_NET1PLL_D5_D4		19
+#define CLK_TOP_NET1PLL_D8_D2		20
+#define CLK_TOP_NET1PLL_D8_D4		21
+#define CLK_TOP_NET2PLL_D4		22
+#define CLK_TOP_NET2PLL_D4_D2		23
+#define CLK_TOP_NET2PLL_D3_D2		24
+#define CLK_TOP_WEDMCUPLL_D5_D2		25
+#define CLK_TOP_NFI1X_SEL		26
+#define CLK_TOP_SPINFI_SEL		27
+#define CLK_TOP_SPI_SEL			28
+#define CLK_TOP_SPIM_MST_SEL		29
+#define CLK_TOP_UART_SEL		30
+#define CLK_TOP_PWM_SEL			31
+#define CLK_TOP_I2C_SEL			32
+#define CLK_TOP_PEXTP_TL_SEL		33
+#define CLK_TOP_EMMC_250M_SEL		34
+#define CLK_TOP_EMMC_416M_SEL		35
+#define CLK_TOP_F_26M_ADC_SEL		36
+#define CLK_TOP_DRAMC_SEL		37
+#define CLK_TOP_DRAMC_MD32_SEL		38
+#define CLK_TOP_SYSAXI_SEL		39
+#define CLK_TOP_SYSAPB_SEL		40
+#define CLK_TOP_ARM_DB_MAIN_SEL		41
+#define CLK_TOP_ARM_DB_JTSEL		42
+#define CLK_TOP_NETSYS_SEL		43
+#define CLK_TOP_NETSYS_500M_SEL		44
+#define CLK_TOP_NETSYS_MCU_SEL		45
+#define CLK_TOP_NETSYS_2X_SEL		46
+#define CLK_TOP_SGM_325M_SEL		47
+#define CLK_TOP_SGM_REG_SEL		48
+#define CLK_TOP_A1SYS_SEL		49
+#define CLK_TOP_CONN_MCUSYS_SEL		50
+#define CLK_TOP_EIP_B_SEL		51
+#define CLK_TOP_PCIE_PHY_SEL		52
+#define CLK_TOP_USB3_PHY_SEL		53
+#define CLK_TOP_F26M_SEL		54
+#define CLK_TOP_AUD_L_SEL		55
+#define CLK_TOP_A_TUNER_SEL		56
+#define CLK_TOP_U2U3_SEL		57
+#define CLK_TOP_U2U3_SYS_SEL		58
+#define CLK_TOP_U2U3_XHCI_SEL		59
+#define CLK_TOP_DA_U2_REFSEL		60
+#define CLK_TOP_DA_U2_CK_1P_SEL		61
+#define CLK_TOP_AP2CNN_HOST_SEL		62
+#define CLK_TOP_JTAG			63
+
+/* INFRACFG */
+
+#define CLK_INFRA_SYSAXI_D2		0
+#define CLK_INFRA_UART0_SEL		1
+#define CLK_INFRA_UART1_SEL		2
+#define CLK_INFRA_UART2_SEL		3
+#define CLK_INFRA_SPI0_SEL		4
+#define CLK_INFRA_SPI1_SEL		5
+#define CLK_INFRA_PWM1_SEL		6
+#define CLK_INFRA_PWM2_SEL		7
+#define CLK_INFRA_PWM_BSEL		8
+#define CLK_INFRA_PCIE_SEL		9
+#define CLK_INFRA_GPT_STA		10
+#define CLK_INFRA_PWM_HCK		11
+#define CLK_INFRA_PWM_STA		12
+#define CLK_INFRA_PWM1_CK		13
+#define CLK_INFRA_PWM2_CK		14
+#define CLK_INFRA_CQ_DMA_CK		15
+#define CLK_INFRA_EIP97_CK		16
+#define CLK_INFRA_AUD_BUS_CK		17
+#define CLK_INFRA_AUD_26M_CK		18
+#define CLK_INFRA_AUD_L_CK		19
+#define CLK_INFRA_AUD_AUD_CK		20
+#define CLK_INFRA_AUD_EG2_CK		21
+#define CLK_INFRA_DRAMC_26M_CK		22
+#define CLK_INFRA_DBG_CK		23
+#define CLK_INFRA_AP_DMA_CK		24
+#define CLK_INFRA_SEJ_CK		25
+#define CLK_INFRA_SEJ_13M_CK		26
+#define CLK_INFRA_THERM_CK		27
+#define CLK_INFRA_I2C0_CK		28
+#define CLK_INFRA_UART0_CK		29
+#define CLK_INFRA_UART1_CK		30
+#define CLK_INFRA_UART2_CK		31
+#define CLK_INFRA_NFI1_CK		32
+#define CLK_INFRA_SPINFI1_CK		33
+#define CLK_INFRA_NFI_HCK_CK		34
+#define CLK_INFRA_SPI0_CK		35
+#define CLK_INFRA_SPI1_CK		36
+#define CLK_INFRA_SPI0_HCK_CK		37
+#define CLK_INFRA_SPI1_HCK_CK		38
+#define CLK_INFRA_FRTC_CK		39
+#define CLK_INFRA_MSDC_CK		40
+#define CLK_INFRA_MSDC_HCK_CK		41
+#define CLK_INFRA_MSDC_133M_CK		42
+#define CLK_INFRA_MSDC_66M_CK		43
+#define CLK_INFRA_ADC_26M_CK		44
+#define CLK_INFRA_ADC_FRC_CK		45
+#define CLK_INFRA_FBIST2FPC_CK		46
+#define CLK_INFRA_IUSB_133_CK		47
+#define CLK_INFRA_IUSB_66M_CK		48
+#define CLK_INFRA_IUSB_SYS_CK		49
+#define CLK_INFRA_IUSB_CK		50
+#define CLK_INFRA_IPCIE_CK		51
+#define CLK_INFRA_IPCIE_PIPE_CK		52
+#define CLK_INFRA_IPCIER_CK		53
+#define CLK_INFRA_IPCIEB_CK		54
+#define CLK_INFRA_TRNG_CK		55
+
+/* SGMIISYS_0 */
+
+#define CLK_SGMII0_TX250M_EN		0
+#define CLK_SGMII0_RX250M_EN		1
+#define CLK_SGMII0_CDR_REF		2
+#define CLK_SGMII0_CDR_FB		3
+
+/* SGMIISYS_1 */
+
+#define CLK_SGMII1_TX250M_EN		0
+#define CLK_SGMII1_RX250M_EN		1
+#define CLK_SGMII1_CDR_REF		2
+#define CLK_SGMII1_CDR_FB		3
+
+/* ETHSYS */
+
+#define CLK_ETH_FE_EN			0
+#define CLK_ETH_GP2_EN			1
+#define CLK_ETH_GP1_EN			2
+#define CLK_ETH_WOCPU1_EN		3
+#define CLK_ETH_WOCPU0_EN		4
+
+#endif /* _DT_BINDINGS_CLK_MT7986_H */
-- 
2.29.2



From sam.shih at mediatek.com  Mon Jan  3 20:52:43 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 4 Jan 2022 12:52:43 +0800
Subject: [PATCH v8 3/3] clk: mediatek: add mt7986 clock support
In-Reply-To: <20220104045243.21521-1-sam.shih@mediatek.com>
References: <20220104045243.21521-1-sam.shih@mediatek.com>
Message-ID: <20220104045243.21521-4-sam.shih@mediatek.com>

Add MT7986 clock support, include topckgen, apmixedsys,
infracfg, and ethernet subsystem clocks.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
Reviewed-by: Ryder Lee <ryder.lee at kernel.org>
---
v8: fix the description in Kconfg, and add a Reviewed-by tag
v7: exclude DTS changes in the patch series
v5: used builtin_platform_driver instead of CLK_OF_DECLARE
    follow recent clk-mt8195 clock patch series:
    https://lore.kernel.org/linux-arm-kernel/20210914021633.26377-1-chun-jie.chen at mediatek.com/

v4: separate clock part into a single patch series

Original thread:
https://lore.kernel.org/lkml/20210914085137.31761-4-sam.shih at mediatek.com/

v2: applied the comment suggested by reviewers:
    - splited basic clock driver to apmixed, topckgen, and infracfg
    - removed 1:1 factor clock
    - renamed factor clock for easier to understand
---
---
 drivers/clk/mediatek/Kconfig               |  17 +
 drivers/clk/mediatek/Makefile              |   4 +
 drivers/clk/mediatek/clk-mt7986-apmixed.c  | 100 ++++++
 drivers/clk/mediatek/clk-mt7986-eth.c      | 132 ++++++++
 drivers/clk/mediatek/clk-mt7986-infracfg.c | 224 ++++++++++++++
 drivers/clk/mediatek/clk-mt7986-topckgen.c | 342 +++++++++++++++++++++
 6 files changed, 819 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7986-apmixed.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-eth.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-infracfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-topckgen.c

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 3ce6fb04d8ff..01ef02c54725 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -344,6 +344,23 @@ config COMMON_CLK_MT7629_HIFSYS
 	  This driver supports MediaTek MT7629 HIFSYS clocks providing
 	  to PCI-E and USB.
 
+config COMMON_CLK_MT7986
+	bool "Clock driver for MediaTek MT7986"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	select COMMON_CLK_MEDIATEK
+	default ARCH_MEDIATEK
+	help
+	  This driver supports MediaTek MT7986 basic clocks and clocks
+	  required for various peripherals found on MediaTek.
+
+config COMMON_CLK_MT7986_ETHSYS
+	bool "Clock driver for MediaTek MT7986 ETHSYS"
+	depends on COMMON_CLK_MT7986
+	default COMMON_CLK_MT7986
+	help
+	  This driver adds support for clocks for Ethernet and SGMII
+	  required on MediaTek MT7986 SoC.
+
 config COMMON_CLK_MT8135
 	bool "Clock driver for MediaTek MT8135"
 	depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index dc96038a0155..7b0c2646ce4a 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -46,6 +46,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
 obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
 obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
 obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
+obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
 obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
 obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
 obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
new file mode 100644
index 000000000000..76c8ebdeae96
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+#define MT7986_PLL_FMAX (2500UL * MHZ)
+#define CON0_MT7986_RST_BAR BIT(27)
+
+#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+		 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift,         \
+		 _div_table, _parent_name)                                     \
+	{                                                                      \
+		.id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg,    \
+		.en_mask = _en_mask, .flags = _flags,                          \
+		.rst_bar_mask = CON0_MT7986_RST_BAR, .fmax = MT7986_PLL_FMAX,  \
+		.pcwbits = _pcwbits, .pd_reg = _pd_reg, .pd_shift = _pd_shift, \
+		.tuner_reg = _tuner_reg, .pcw_reg = _pcw_reg,                  \
+		.pcw_shift = _pcw_shift, .div_table = _div_table,              \
+		.parent_name = _parent_name,                                   \
+	}
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg,   \
+	    _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift)                       \
+	PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits,       \
+		 _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift, NULL,   \
+		 "clkxtal")
+
+static const struct mtk_pll_data plls[] = {
+	PLL(CLK_APMIXED_ARMPLL, "armpll", 0x0200, 0x020C, 0x00000001, 0, 32,
+	    0x0200, 4, 0, 0x0204, 0),
+	PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0210, 0x021C, 0x00000001, 0, 32,
+	    0x0210, 4, 0, 0x0214, 0),
+	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0220, 0x022C, 0x00000001, 0, 32,
+	    0x0220, 4, 0, 0x0224, 0),
+	PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0230, 0x023c, 0x00000001, 0, 32,
+	    0x0230, 4, 0, 0x0234, 0),
+	PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0240, 0x024c, 0x00000001, 0,
+	    32, 0x0240, 4, 0, 0x0244, 0),
+	PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0250, 0x025c, 0x00000001, 0, 32,
+	    0x0250, 4, 0, 0x0254, 0),
+	PLL(CLK_APMIXED_MPLL, "mpll", 0x0260, 0x0270, 0x00000001, 0, 32, 0x0260,
+	    4, 0, 0x0264, 0),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x0278, 0x0288, 0x00000001, 0, 32,
+	    0x0278, 4, 0, 0x027c, 0),
+};
+
+static const struct of_device_id of_match_clk_mt7986_apmixed[] = {
+	{ .compatible = "mediatek,mt7986-apmixedsys", },
+	{}
+};
+
+static int clk_mt7986_apmixed_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMPLL]);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r) {
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+		goto free_apmixed_data;
+	}
+	return r;
+
+free_apmixed_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt7986_apmixed_drv = {
+	.probe = clk_mt7986_apmixed_probe,
+	.driver = {
+		.name = "clk-mt7986-apmixed",
+		.of_match_table = of_match_clk_mt7986_apmixed,
+	},
+};
+builtin_platform_driver(clk_mt7986_apmixed_drv);
diff --git a/drivers/clk/mediatek/clk-mt7986-eth.c b/drivers/clk/mediatek/clk-mt7986-eth.c
new file mode 100644
index 000000000000..495d023ccad7
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-eth.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+
+static const struct mtk_gate_regs sgmii0_cg_regs = {
+	.set_ofs = 0xe4,
+	.clr_ofs = 0xe4,
+	.sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII0(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &sgmii0_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate sgmii0_clks[] __initconst = {
+	GATE_SGMII0(CLK_SGMII0_TX250M_EN, "sgmii0_tx250m_en", "top_xtal", 2),
+	GATE_SGMII0(CLK_SGMII0_RX250M_EN, "sgmii0_rx250m_en", "top_xtal", 3),
+	GATE_SGMII0(CLK_SGMII0_CDR_REF, "sgmii0_cdr_ref", "top_xtal", 4),
+	GATE_SGMII0(CLK_SGMII0_CDR_FB, "sgmii0_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs sgmii1_cg_regs = {
+	.set_ofs = 0xe4,
+	.clr_ofs = 0xe4,
+	.sta_ofs = 0xe4,
+};
+
+#define GATE_SGMII1(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &sgmii1_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate sgmii1_clks[] __initconst = {
+	GATE_SGMII1(CLK_SGMII1_TX250M_EN, "sgmii1_tx250m_en", "top_xtal", 2),
+	GATE_SGMII1(CLK_SGMII1_RX250M_EN, "sgmii1_rx250m_en", "top_xtal", 3),
+	GATE_SGMII1(CLK_SGMII1_CDR_REF, "sgmii1_cdr_ref", "top_xtal", 4),
+	GATE_SGMII1(CLK_SGMII1_CDR_FB, "sgmii1_cdr_fb", "top_xtal", 5),
+};
+
+static const struct mtk_gate_regs eth_cg_regs = {
+	.set_ofs = 0x30,
+	.clr_ofs = 0x30,
+	.sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _name, _parent, _shift)                                  \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &eth_cg_regs, .shift = _shift,                         \
+		.ops = &mtk_clk_gate_ops_no_setclr_inv,                        \
+	}
+
+static const struct mtk_gate eth_clks[] __initconst = {
+	GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x_sel", 6),
+	GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m_sel", 7),
+	GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m_sel", 8),
+	GATE_ETH(CLK_ETH_WOCPU1_EN, "eth_wocpu1_en", "netsys_mcu_sel", 14),
+	GATE_ETH(CLK_ETH_WOCPU0_EN, "eth_wocpu0_en", "netsys_mcu_sel", 15),
+};
+
+static void __init mtk_sgmiisys_0_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
+
+	mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_0, "mediatek,mt7986-sgmiisys_0",
+	       mtk_sgmiisys_0_init);
+
+static void __init mtk_sgmiisys_1_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
+
+	mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_sgmiisys_1, "mediatek,mt7986-sgmiisys_1",
+	       mtk_sgmiisys_1_init);
+
+static void __init mtk_ethsys_init(struct device_node *node)
+{
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(ARRAY_SIZE(eth_clks));
+
+	mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r)
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+}
+CLK_OF_DECLARE(mtk_ethsys, "mediatek,mt7986-ethsys_ck", mtk_ethsys_init);
diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
new file mode 100644
index 000000000000..3be168c34fc0
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
@@ -0,0 +1,224 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_factor infra_divs[] = {
+	FACTOR(CLK_INFRA_SYSAXI_D2, "infra_sysaxi_d2", "sysaxi_sel", 1, 2),
+};
+
+static const char *const infra_uart_parent[] __initconst = { "csw_f26m_sel",
+							     "uart_sel" };
+
+static const char *const infra_spi_parents[] __initconst = { "i2c_sel",
+							     "spi_sel" };
+
+static const char *const infra_pwm_bsel_parents[] __initconst = {
+	"top_rtc_32p7k", "csw_f26m_sel", "infra_sysaxi_d2", "pwm_sel"
+};
+
+static const char *const infra_pcie_parents[] __initconst = {
+	"top_rtc_32p7k", "csw_f26m_sel", "top_xtal", "pextp_tl_ck_sel"
+};
+
+static const struct mtk_mux infra_muxes[] = {
+	/* MODULE_CLK_SEL_0 */
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART0_SEL, "infra_uart0_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 0, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART1_SEL, "infra_uart1_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 1, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_UART2_SEL, "infra_uart2_sel",
+			     infra_uart_parent, 0x0018, 0x0010, 0x0014, 2, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI0_SEL, "infra_spi0_sel",
+			     infra_spi_parents, 0x0018, 0x0010, 0x0014, 4, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_SPI1_SEL, "infra_spi1_sel",
+			     infra_spi_parents, 0x0018, 0x0010, 0x0014, 5, 1,
+			     -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM1_SEL, "infra_pwm1_sel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 9,
+			     2, -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM2_SEL, "infra_pwm2_sel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 11,
+			     2, -1, -1, -1),
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_BSEL, "infra_pwm_bsel",
+			     infra_pwm_bsel_parents, 0x0018, 0x0010, 0x0014, 13,
+			     2, -1, -1, -1),
+	/* MODULE_CLK_SEL_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_SEL, "infra_pcie_sel",
+			     infra_pcie_parents, 0x0028, 0x0020, 0x0024, 0, 2,
+			     -1, -1, -1),
+};
+
+static const struct mtk_gate_regs infra0_cg_regs = {
+	.set_ofs = 0x40,
+	.clr_ofs = 0x44,
+	.sta_ofs = 0x48,
+};
+
+static const struct mtk_gate_regs infra1_cg_regs = {
+	.set_ofs = 0x50,
+	.clr_ofs = 0x54,
+	.sta_ofs = 0x58,
+};
+
+static const struct mtk_gate_regs infra2_cg_regs = {
+	.set_ofs = 0x60,
+	.clr_ofs = 0x64,
+	.sta_ofs = 0x68,
+};
+
+#define GATE_INFRA0(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra0_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+#define GATE_INFRA1(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra1_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+#define GATE_INFRA2(_id, _name, _parent, _shift)                               \
+	{                                                                      \
+		.id = _id, .name = _name, .parent_name = _parent,              \
+		.regs = &infra2_cg_regs, .shift = _shift,                      \
+		.ops = &mtk_clk_gate_ops_setclr,                               \
+	}
+
+static const struct mtk_gate infra_clks[] = {
+	/* INFRA0 */
+	GATE_INFRA0(CLK_INFRA_GPT_STA, "infra_gpt_sta", "infra_sysaxi_d2", 0),
+	GATE_INFRA0(CLK_INFRA_PWM_HCK, "infra_pwm_hck", "infra_sysaxi_d2", 1),
+	GATE_INFRA0(CLK_INFRA_PWM_STA, "infra_pwm_sta", "infra_pwm_bsel", 2),
+	GATE_INFRA0(CLK_INFRA_PWM1_CK, "infra_pwm1", "infra_pwm1_sel", 3),
+	GATE_INFRA0(CLK_INFRA_PWM2_CK, "infra_pwm2", "infra_pwm2_sel", 4),
+	GATE_INFRA0(CLK_INFRA_CQ_DMA_CK, "infra_cq_dma", "sysaxi_sel", 6),
+	GATE_INFRA0(CLK_INFRA_EIP97_CK, "infra_eip97", "eip_b_sel", 7),
+	GATE_INFRA0(CLK_INFRA_AUD_BUS_CK, "infra_aud_bus", "sysaxi_sel", 8),
+	GATE_INFRA0(CLK_INFRA_AUD_26M_CK, "infra_aud_26m", "csw_f26m_sel", 9),
+	GATE_INFRA0(CLK_INFRA_AUD_L_CK, "infra_aud_l", "aud_l_sel", 10),
+	GATE_INFRA0(CLK_INFRA_AUD_AUD_CK, "infra_aud_aud", "a1sys_sel", 11),
+	GATE_INFRA0(CLK_INFRA_AUD_EG2_CK, "infra_aud_eg2", "a_tuner_sel", 13),
+	GATE_INFRA0(CLK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", "csw_f26m_sel",
+		    14),
+	GATE_INFRA0(CLK_INFRA_DBG_CK, "infra_dbg", "infra_sysaxi_d2", 15),
+	GATE_INFRA0(CLK_INFRA_AP_DMA_CK, "infra_ap_dma", "infra_sysaxi_d2", 16),
+	GATE_INFRA0(CLK_INFRA_SEJ_CK, "infra_sej", "infra_sysaxi_d2", 24),
+	GATE_INFRA0(CLK_INFRA_SEJ_13M_CK, "infra_sej_13m", "csw_f26m_sel", 25),
+	GATE_INFRA0(CLK_INFRA_TRNG_CK, "infra_trng", "sysaxi_sel", 26),
+	/* INFRA1 */
+	GATE_INFRA1(CLK_INFRA_THERM_CK, "infra_therm", "csw_f26m_sel", 0),
+	GATE_INFRA1(CLK_INFRA_I2C0_CK, "infra_i2c0", "i2c_sel", 1),
+	GATE_INFRA1(CLK_INFRA_UART0_CK, "infra_uart0", "infra_uart0_sel", 2),
+	GATE_INFRA1(CLK_INFRA_UART1_CK, "infra_uart1", "infra_uart1_sel", 3),
+	GATE_INFRA1(CLK_INFRA_UART2_CK, "infra_uart2", "infra_uart2_sel", 4),
+	GATE_INFRA1(CLK_INFRA_NFI1_CK, "infra_nfi1", "nfi1x_sel", 8),
+	GATE_INFRA1(CLK_INFRA_SPINFI1_CK, "infra_spinfi1", "spinfi_sel", 9),
+	GATE_INFRA1(CLK_INFRA_NFI_HCK_CK, "infra_nfi_hck", "infra_sysaxi_d2",
+		    10),
+	GATE_INFRA1(CLK_INFRA_SPI0_CK, "infra_spi0", "infra_spi0_sel", 11),
+	GATE_INFRA1(CLK_INFRA_SPI1_CK, "infra_spi1", "infra_spi1_sel", 12),
+	GATE_INFRA1(CLK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", "infra_sysaxi_d2",
+		    13),
+	GATE_INFRA1(CLK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", "infra_sysaxi_d2",
+		    14),
+	GATE_INFRA1(CLK_INFRA_FRTC_CK, "infra_frtc", "top_rtc_32k", 15),
+	GATE_INFRA1(CLK_INFRA_MSDC_CK, "infra_msdc", "emmc_416m_sel", 16),
+	GATE_INFRA1(CLK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", "emmc_250m_sel",
+		    17),
+	GATE_INFRA1(CLK_INFRA_MSDC_133M_CK, "infra_msdc_133m", "sysaxi_sel",
+		    18),
+	GATE_INFRA1(CLK_INFRA_MSDC_66M_CK, "infra_msdc_66m", "infra_sysaxi_d2",
+		    19),
+	GATE_INFRA1(CLK_INFRA_ADC_26M_CK, "infra_adc_26m", "csw_f26m_sel", 20),
+	GATE_INFRA1(CLK_INFRA_ADC_FRC_CK, "infra_adc_frc", "csw_f26m_sel", 21),
+	GATE_INFRA1(CLK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", "nfi1x_sel", 23),
+	/* INFRA2 */
+	GATE_INFRA2(CLK_INFRA_IUSB_133_CK, "infra_iusb_133", "sysaxi_sel", 0),
+	GATE_INFRA2(CLK_INFRA_IUSB_66M_CK, "infra_iusb_66m", "infra_sysaxi_d2",
+		    1),
+	GATE_INFRA2(CLK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", "u2u3_sys_sel", 2),
+	GATE_INFRA2(CLK_INFRA_IUSB_CK, "infra_iusb", "u2u3_sel", 3),
+	GATE_INFRA2(CLK_INFRA_IPCIE_CK, "infra_ipcie", "pextp_tl_ck_sel", 12),
+	GATE_INFRA2(CLK_INFRA_IPCIE_PIPE_CK, "infra_ipcie_pipe", "top_xtal",
+		    13),
+	GATE_INFRA2(CLK_INFRA_IPCIER_CK, "infra_ipcier", "csw_f26m_sel", 14),
+	GATE_INFRA2(CLK_INFRA_IPCIEB_CK, "infra_ipcieb", "sysaxi_sel", 15),
+};
+
+static int clk_mt7986_infracfg_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
+	int nr = ARRAY_SIZE(infra_divs) + ARRAY_SIZE(infra_muxes) +
+		 ARRAY_SIZE(infra_clks);
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	clk_data = mtk_alloc_clk_data(nr);
+
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_factors(infra_divs, ARRAY_SIZE(infra_divs), clk_data);
+	mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
+			       &mt7986_clk_lock, clk_data);
+	mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
+			       clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r) {
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+		goto free_infracfg_data;
+	}
+	return r;
+
+free_infracfg_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+
+}
+
+static const struct of_device_id of_match_clk_mt7986_infracfg[] = {
+	{ .compatible = "mediatek,mt7986-infracfg", },
+	{}
+};
+
+static struct platform_driver clk_mt7986_infracfg_drv = {
+	.probe = clk_mt7986_infracfg_probe,
+	.driver = {
+		.name = "clk-mt7986-infracfg",
+		.of_match_table = of_match_clk_mt7986_infracfg,
+	},
+};
+builtin_platform_driver(clk_mt7986_infracfg_drv);
diff --git a/drivers/clk/mediatek/clk-mt7986-topckgen.c b/drivers/clk/mediatek/clk-mt7986-topckgen.c
new file mode 100644
index 000000000000..8550e2be7773
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
@@ -0,0 +1,342 @@
+// SPDX-License-Identifier: GPL-1.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ * Author: Wenzhen Yu <wenzhen.yu at mediatek.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include "clk-mtk.h"
+#include "clk-gate.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt7986-clk.h>
+#include <linux/clk.h>
+
+static DEFINE_SPINLOCK(mt7986_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
+	FIXED_CLK(CLK_TOP_JTAG, "top_jtag", "clkxtal", 50000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+	/* XTAL */
+	FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
+	FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
+	FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
+	/* MPLL */
+	FACTOR(CLK_TOP_MPLL_D2, "top_mpll_d2", "mpll", 1, 2),
+	FACTOR(CLK_TOP_MPLL_D4, "top_mpll_d4", "mpll", 1, 4),
+	FACTOR(CLK_TOP_MPLL_D8, "top_mpll_d8", "mpll", 1, 8),
+	FACTOR(CLK_TOP_MPLL_D8_D2, "top_mpll_d8_d2", "mpll", 1, 16),
+	FACTOR(CLK_TOP_MPLL_D3_D2, "top_mpll_d3_d2", "mpll", 1, 6),
+	/* MMPLL */
+	FACTOR(CLK_TOP_MMPLL_D2, "top_mmpll_d2", "mmpll", 1, 2),
+	FACTOR(CLK_TOP_MMPLL_D4, "top_mmpll_d4", "mmpll", 1, 4),
+	FACTOR(CLK_TOP_MMPLL_D8, "top_mmpll_d8", "mmpll", 1, 8),
+	FACTOR(CLK_TOP_MMPLL_D8_D2, "top_mmpll_d8_d2", "mmpll", 1, 16),
+	FACTOR(CLK_TOP_MMPLL_D3_D8, "top_mmpll_d3_d8", "mmpll", 1, 24),
+	FACTOR(CLK_TOP_MMPLL_U2PHY, "top_mmpll_u2phy", "mmpll", 1, 30),
+	/* APLL2 */
+	FACTOR(CLK_TOP_APLL2_D4, "top_apll2_d4", "apll2", 1, 4),
+	/* NET1PLL */
+	FACTOR(CLK_TOP_NET1PLL_D4, "top_net1pll_d4", "net1pll", 1, 4),
+	FACTOR(CLK_TOP_NET1PLL_D5, "top_net1pll_d5", "net1pll", 1, 5),
+	FACTOR(CLK_TOP_NET1PLL_D5_D2, "top_net1pll_d5_d2", "net1pll", 1, 10),
+	FACTOR(CLK_TOP_NET1PLL_D5_D4, "top_net1pll_d5_d4", "net1pll", 1, 20),
+	FACTOR(CLK_TOP_NET1PLL_D8_D2, "top_net1pll_d8_d2", "net1pll", 1, 16),
+	FACTOR(CLK_TOP_NET1PLL_D8_D4, "top_net1pll_d8_d4", "net1pll", 1, 32),
+	/* NET2PLL */
+	FACTOR(CLK_TOP_NET2PLL_D4, "top_net2pll_d4", "net2pll", 1, 4),
+	FACTOR(CLK_TOP_NET2PLL_D4_D2, "top_net2pll_d4_d2", "net2pll", 1, 8),
+	FACTOR(CLK_TOP_NET2PLL_D3_D2, "top_net2pll_d3_d2", "net2pll", 1, 2),
+	/* WEDMCUPLL */
+	FACTOR(CLK_TOP_WEDMCUPLL_D5_D2, "top_wedmcupll_d5_d2", "wedmcupll", 1,
+	       10),
+};
+
+static const char *const nfi1x_parents[] __initconst = { "top_xtal",
+							 "top_mmpll_d8",
+							 "top_net1pll_d8_d2",
+							 "top_net2pll_d3_d2",
+							 "top_mpll_d4",
+							 "top_mmpll_d8_d2",
+							 "top_wedmcupll_d5_d2",
+							 "top_mpll_d8" };
+
+static const char *const spinfi_parents[] __initconst = {
+	"top_xtal_d2",     "top_xtal",	"top_net1pll_d5_d4",
+	"top_mpll_d4",     "top_mmpll_d8_d2", "top_wedmcupll_d5_d2",
+	"top_mmpll_d3_d8", "top_mpll_d8"
+};
+
+static const char *const spi_parents[] __initconst = {
+	"top_xtal",	  "top_mpll_d2",	"top_mmpll_d8",
+	"top_net1pll_d8_d2", "top_net2pll_d3_d2",  "top_net1pll_d5_d4",
+	"top_mpll_d4",       "top_wedmcupll_d5_d2"
+};
+
+static const char *const uart_parents[] __initconst = { "top_xtal",
+							"top_mpll_d8",
+							"top_mpll_d8_d2" };
+
+static const char *const pwm_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d8_d2", "top_net1pll_d5_d4", "top_mpll_d4"
+};
+
+static const char *const i2c_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4", "top_mpll_d4", "top_net1pll_d8_d4"
+};
+
+static const char *const pextp_tl_ck_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4", "top_net2pll_d4_d2", "top_rtc_32k"
+};
+
+static const char *const emmc_250m_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d2"
+};
+
+static const char *const emmc_416m_parents[] __initconst = { "top_xtal",
+							     "mpll" };
+
+static const char *const f_26m_adc_parents[] __initconst = { "top_xtal",
+							     "top_mpll_d8_d2" };
+
+static const char *const dramc_md32_parents[] __initconst = { "top_xtal",
+							      "top_mpll_d2" };
+
+static const char *const sysaxi_parents[] __initconst = { "top_xtal",
+							  "top_net1pll_d8_d2",
+							  "top_net2pll_d4" };
+
+static const char *const sysapb_parents[] __initconst = { "top_xtal",
+							  "top_mpll_d3_d2",
+							  "top_net2pll_d4_d2" };
+
+static const char *const arm_db_main_parents[] __initconst = {
+	"top_xtal", "top_net2pll_d3_d2"
+};
+
+static const char *const arm_db_jtsel_parents[] __initconst = { "top_jtag",
+								"top_xtal" };
+
+static const char *const netsys_parents[] __initconst = { "top_xtal",
+							  "top_mmpll_d4" };
+
+static const char *const netsys_500m_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5"
+};
+
+static const char *const netsys_mcu_parents[] __initconst = {
+	"top_xtal", "wedmcupll", "top_mmpll_d2", "top_net1pll_d4",
+	"top_net1pll_d5"
+};
+
+static const char *const netsys_2x_parents[] __initconst = {
+	"top_xtal", "net2pll", "wedmcupll", "top_mmpll_d2"
+};
+
+static const char *const sgm_325m_parents[] __initconst = { "top_xtal",
+							    "sgmpll" };
+
+static const char *const sgm_reg_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d8_d4"
+};
+
+static const char *const a1sys_parents[] __initconst = { "top_xtal",
+							 "top_apll2_d4" };
+
+static const char *const conn_mcusys_parents[] __initconst = { "top_xtal",
+							       "top_mmpll_d2" };
+
+static const char *const eip_b_parents[] __initconst = { "top_xtal",
+							 "net2pll" };
+
+static const char *const aud_l_parents[] __initconst = { "top_xtal", "apll2",
+							 "top_mpll_d8_d2" };
+
+static const char *const a_tuner_parents[] __initconst = { "top_xtal",
+							   "top_apll2_d4",
+							   "top_mpll_d8_d2" };
+
+static const char *const u2u3_sys_parents[] __initconst = {
+	"top_xtal", "top_net1pll_d5_d4"
+};
+
+static const char *const da_u2_refsel_parents[] __initconst = {
+	"top_xtal", "top_mmpll_u2phy"
+};
+
+static const struct mtk_mux top_muxes[] = {
+	/* CLK_CFG_0 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
+			     0x000, 0x004, 0x008, 0, 3, 7, 0x1C0, 0),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
+			     0x000, 0x004, 0x008, 8, 3, 15, 0x1C0, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000,
+			     0x004, 0x008, 16, 3, 23, 0x1C0, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
+			     0x000, 0x004, 0x008, 24, 3, 31, 0x1C0, 3),
+	/* CLK_CFG_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010,
+			     0x014, 0x018, 0, 2, 7, 0x1C0, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010,
+			     0x014, 0x018, 8, 2, 15, 0x1C0, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010,
+			     0x014, 0x018, 16, 2, 23, 0x1C0, 6),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel",
+			     pextp_tl_ck_parents, 0x010, 0x014, 0x018, 24, 2,
+			     31, 0x1C0, 7),
+	/* CLK_CFG_2 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
+			     emmc_250m_parents, 0x020, 0x024, 0x028, 0, 1, 7,
+			     0x1C0, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_416M_SEL, "emmc_416m_sel",
+			     emmc_416m_parents, 0x020, 0x024, 0x028, 8, 1, 15,
+			     0x1C0, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel",
+			     f_26m_adc_parents, 0x020, 0x024, 0x028, 16, 1, 23,
+			     0x1C0, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents,
+			     0x020, 0x024, 0x028, 24, 1, 31, 0x1C0, 11),
+	/* CLK_CFG_3 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
+			     dramc_md32_parents, 0x030, 0x034, 0x038, 0, 1, 7,
+			     0x1C0, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents,
+			     0x030, 0x034, 0x038, 8, 2, 15, 0x1C0, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents,
+			     0x030, 0x034, 0x038, 16, 2, 23, 0x1C0, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel",
+			     arm_db_main_parents, 0x030, 0x034, 0x038, 24, 1,
+			     31, 0x1C0, 15),
+	/* CLK_CFG_4 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ARM_DB_JTSEL, "arm_db_jtsel",
+			     arm_db_jtsel_parents, 0x040, 0x044, 0x048, 0, 1, 7,
+			     0x1C0, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
+			     0x040, 0x044, 0x048, 8, 1, 15, 0x1C0, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
+			     netsys_500m_parents, 0x040, 0x044, 0x048, 16, 1,
+			     23, 0x1C0, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
+			     netsys_mcu_parents, 0x040, 0x044, 0x048, 24, 3, 31,
+			     0x1C0, 19),
+	/* CLK_CFG_5 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
+			     netsys_2x_parents, 0x050, 0x054, 0x058, 0, 2, 7,
+			     0x1C0, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
+			     sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
+			     0x1C0, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel",
+			     sgm_reg_parents, 0x050, 0x054, 0x058, 16, 1, 23,
+			     0x1C0, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
+			     0x050, 0x054, 0x058, 24, 1, 31, 0x1C0, 23),
+	/* CLK_CFG_6 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel",
+			     conn_mcusys_parents, 0x060, 0x064, 0x068, 0, 1, 7,
+			     0x1C0, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents,
+			     0x060, 0x064, 0x068, 8, 1, 15, 0x1C0, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_PHY_SEL, "pcie_phy_sel",
+			     f_26m_adc_parents, 0x060, 0x064, 0x068, 16, 1, 23,
+			     0x1C0, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB3_PHY_SEL, "usb3_phy_sel",
+			     f_26m_adc_parents, 0x060, 0x064, 0x068, 24, 1, 31,
+			     0x1C0, 27),
+	/* CLK_CFG_7 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_F26M_SEL, "csw_f26m_sel",
+			     f_26m_adc_parents, 0x070, 0x074, 0x078, 0, 1, 7,
+			     0x1C0, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
+			     0x070, 0x074, 0x078, 8, 2, 15, 0x1C0, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel",
+			     a_tuner_parents, 0x070, 0x074, 0x078, 16, 2, 23,
+			     0x1C0, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents,
+			     0x070, 0x074, 0x078, 24, 1, 31, 0x1C4, 0),
+	/* CLK_CFG_8 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel",
+			     u2u3_sys_parents, 0x080, 0x084, 0x088, 0, 1, 7,
+			     0x1C4, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel",
+			     u2u3_sys_parents, 0x080, 0x084, 0x088, 8, 1, 15,
+			     0x1C4, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_REFSEL, "da_u2_refsel",
+			     da_u2_refsel_parents, 0x080, 0x084, 0x088, 16, 1,
+			     23, 0x1C4, 3),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel",
+			     da_u2_refsel_parents, 0x080, 0x084, 0x088, 24, 1,
+			     31, 0x1C4, 4),
+	/* CLK_CFG_9 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel",
+			     sgm_reg_parents, 0x090, 0x094, 0x098, 0, 1, 7,
+			     0x1C4, 5),
+};
+
+static int clk_mt7986_topckgen_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
+	int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
+		 ARRAY_SIZE(top_muxes);
+
+	base = of_iomap(node, 0);
+	if (!base) {
+		pr_err("%s(): ioremap failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	clk_data = mtk_alloc_clk_data(nr);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+				    clk_data);
+	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+	mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
+			       &mt7986_clk_lock, clk_data);
+
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAXI_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SYSAPB_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_DRAMC_MD32_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_F26M_SEL]);
+	clk_prepare_enable(clk_data->clks[CLK_TOP_SGM_REG_SEL]);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+
+	if (r) {
+		pr_err("%s(): could not register clock provider: %d\n",
+		       __func__, r);
+		goto free_topckgen_data;
+	}
+	return r;
+
+free_topckgen_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static const struct of_device_id of_match_clk_mt7986_topckgen[] = {
+	{ .compatible = "mediatek,mt7986-topckgen", },
+	{}
+};
+
+static struct platform_driver clk_mt7986_topckgen_drv = {
+	.probe = clk_mt7986_topckgen_probe,
+	.driver = {
+		.name = "clk-mt7986-topckgen",
+		.of_match_table = of_match_clk_mt7986_topckgen,
+	},
+};
+builtin_platform_driver(clk_mt7986_topckgen_drv);
-- 
2.29.2



From sam.shih at mediatek.com  Mon Jan  3 20:55:08 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Tue, 4 Jan 2022 12:55:08 +0800
Subject: [PATCH v8 0/3] Mediatek MT7986 basic clock support
Message-ID: <20220104045508.21614-1-sam.shih@mediatek.com>

This patch series add basic clock support for mediatek mt7986 SoC.
It is based on patch series "Add basic SoC support for mediatek mt7986"
https://lore.kernel.org/all/20211018114009.13350-1-sam.shih at mediatek.com/
that has been merged into matthias's tree recently:
https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/log/?h=v5.16-next/dts64

---
v8: update the git message, and add a Reviewed-by tag for this series 
v7: exclude DTS changes in the patch series
v5: used builtin_platform_driver instead of CLK_OF_DECLARE
    follow recent clk-mt8195 clock patch series:
    https://lore.kernel.org/linux-arm-kernel/20210914021633.26377-1-chun-jie.chen at mediatek.com/

v4:
According to the maintainer??s suggestion, this patch splits the previous
thread into independent patch series.
This patch include clock driver and device tree update

Original thread:
https://lore.kernel.org/all/20210914085137.31761-1-sam.shih at mediatek.com/
https://lore.kernel.org/linux-arm-kernel/20210914085137.31761-2-sam.shih at mediatek.com/
---

Sam Shih (3):
  dt-bindings: clock: mediatek: document clk bindings for mediatek
    mt7986 SoC
  clk: mediatek: add mt7986 clock IDs
  clk: mediatek: add mt7986 clock support

 .../arm/mediatek/mediatek,apmixedsys.txt      |   1 +
 .../bindings/arm/mediatek/mediatek,ethsys.txt |   1 +
 .../arm/mediatek/mediatek,infracfg.txt        |   1 +
 .../arm/mediatek/mediatek,sgmiisys.txt        |   2 +
 .../arm/mediatek/mediatek,topckgen.txt        |   1 +
 drivers/clk/mediatek/Kconfig                  |  17 +
 drivers/clk/mediatek/Makefile                 |   4 +
 drivers/clk/mediatek/clk-mt7986-apmixed.c     | 100 +++++
 drivers/clk/mediatek/clk-mt7986-eth.c         | 132 +++++++
 drivers/clk/mediatek/clk-mt7986-infracfg.c    | 224 ++++++++++++
 drivers/clk/mediatek/clk-mt7986-topckgen.c    | 342 ++++++++++++++++++
 include/dt-bindings/clock/mt7986-clk.h        | 169 +++++++++
 12 files changed, 994 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt7986-apmixed.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-eth.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-infracfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt7986-topckgen.c
 create mode 100644 include/dt-bindings/clock/mt7986-clk.h

-- 
2.29.2



From Kavyasree.Kotagiri at microchip.com  Mon Jan  3 21:20:18 2022
From: Kavyasree.Kotagiri at microchip.com (Kavyasree.Kotagiri at microchip.com)
Date: Tue, 4 Jan 2022 05:20:18 +0000
Subject: [PATCH] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
In-Reply-To: <76804bd6-00e5-02ab-59df-d32586a55422@microchip.com>
References: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
 <76804bd6-00e5-02ab-59df-d32586a55422@microchip.com>
Message-ID: <CO1PR11MB48651B354ABAF04ABB53FB04924A9@CO1PR11MB4865.namprd11.prod.outlook.com>

> On 1/3/22 2:48 PM, Kavyasree Kotagiri wrote:
> > diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts
> b/arch/arm/boot/dts/lan966x_pcb8291.dts
> > new file mode 100644
> > index 000000000000..cd0454a795e7
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
> > @@ -0,0 +1,55 @@
> 
> > +&flx3 {
> > +       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> > +       status = "okay";
> > +
> > +       usart0: serial at 200 {
> > +               compatible = "atmel,at91sam9260-usart";
> 
> The flexcom usart mode should be defined in the dtsi file, so that you
> won't duplicate the definition in each dts that includes the dtsi file.
> 
defining flexcom mode in dts as flx3 can be used as USART/I2C/SPI on different boards.
And it is not the same mode for all boards.

> Cheers,
> ta

From michael at allwinnertech.com  Mon Jan  3 22:03:25 2022
From: michael at allwinnertech.com (Michael Wu)
Date: Tue,  4 Jan 2022 14:03:25 +0800
Subject: [PATCH v2] mmc: sunxi-mmc: check ocr_avail on resource request
Message-ID: <20220104060325.3957-1-michael@allwinnertech.com>

Some platforms have no regulator, discrete power devices are used instead.
However, sunxi_mmc_probe does not catch this exception when regulator is
absent in DTS. This leads to sd or eMMC init failure.

To solve this, a fixed vmmc regulator must be hooked up in DTS, like this:
reg_dummy_vmmc: dummy_vmmc {
	compatible = "regulator-fixed";
	regulator-name = "dummy-vmmc";
	regulator-min-microvolt = <3300000>;
	regulator-max-microvolt = <3300000>;
};

mmc0:mmc at 4020000 {
	compatible = "allwinner,sun50i-a100-emmc";
	device_type = "mmc0";
	vmmc-supply = <&reg_dummy_vmmc>;
}

In this patch, we print an error message and abort the probe process if
the regulator is not specified in DTS.

Signed-off-by: Michael Wu <michael at allwinnertech.com>
---
 drivers/mmc/host/sunxi-mmc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 2702736a1c57..0da74bddaf87 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1300,6 +1300,11 @@ static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
 	if (ret)
 		return ret;
 
+	if (!host->mmc->ocr_avail) {
+		dev_err(&pdev->dev, "Could not get mmc regulator\n");
+		return -EINVAL;
+	}
+
 	host->reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(host->reg_base))
 		return PTR_ERR(host->reg_base);
-- 
2.29.0



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:40 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:40 +0800
Subject: [PATCH 0/7] mailbox: imx: misc fix and SECO MU support
Message-ID: <20220104062547.2103016-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

This patchset includes a few fixes for low power and i.MX8 SECO MU support

Franck LENORMAND (1):
  mailbox: imx: add i.MX8 SECO MU support

Peng Fan (2):
  dt-bindings: mailbox: imx-mu: add i.MX8 SECO MU support
  mailbox: imx: introduce rxdb callback

Ranjani Vaidyanathan (2):
  mailbox: imx: Add support for identifying SCU wakeup source from sysfs
  mailbox: imx: enlarge timeout while reading/writing messages to SCFW

Robin Gong (2):
  mailbox: imx: fix wakeup failure from freeze mode
  mailbox: imx: fix crash in resume on i.mx8ulp

 .../devicetree/bindings/mailbox/fsl,mu.yaml   |   1 +
 drivers/mailbox/imx-mailbox.c                 | 249 +++++++++++++++++-
 2 files changed, 243 insertions(+), 7 deletions(-)

-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:41 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:41 +0800
Subject: [PATCH 1/7] mailbox: imx: fix wakeup failure from freeze mode
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-2-peng.fan@oss.nxp.com>

From: Robin Gong <yibin.gong at nxp.com>

Since IRQF_NO_SUSPEND used for imx mailbox driver, that means this irq
can't be used for wakeup source so that can't wakeup from freeze mode.
Add pm_system_wakeup() to wakeup from freeze mode.

Fixes: b7b2796b9b31e("mailbox: imx: ONLY IPC MU needs IRQF_NO_SUSPEND flag")
Reviewed-by: Jacky Bai <ping.bai at nxp.com>
Reviewed-by: Peng Fan <peng.fan at nxp.com>
Signed-off-by: Robin Gong <yibin.gong at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index ffe36a6bef9e..b3a2772f0aa1 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/suspend.h>
 #include <linux/slab.h>
 
 #define IMX_MU_CHANS		16
@@ -76,6 +77,7 @@ struct imx_mu_priv {
 	const struct imx_mu_dcfg	*dcfg;
 	struct clk		*clk;
 	int			irq;
+	bool			suspend;
 
 	u32 xcr[4];
 
@@ -334,6 +336,9 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
 		return IRQ_NONE;
 	}
 
+	if (priv->suspend)
+		pm_system_wakeup();
+
 	return IRQ_HANDLED;
 }
 
@@ -702,6 +707,8 @@ static int __maybe_unused imx_mu_suspend_noirq(struct device *dev)
 			priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]);
 	}
 
+	priv->suspend = true;
+
 	return 0;
 }
 
@@ -723,6 +730,8 @@ static int __maybe_unused imx_mu_resume_noirq(struct device *dev)
 			imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]);
 	}
 
+	priv->suspend = false;
+
 	return 0;
 }
 
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:42 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:42 +0800
Subject: [PATCH 2/7] mailbox: imx: fix crash in resume on i.mx8ulp
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-3-peng.fan@oss.nxp.com>

From: Robin Gong <yibin.gong at nxp.com>

check 'priv->clk' before 'imx_mu_read()' otherwise crash happens on
i.mx8ulp, since clock not enabled.

Fixes: 4f0b776ef5831 ("mailbox: imx-mailbox: support i.MX8ULP MU")
Reviewed-by: Jacky Bai <ping.bai at nxp.com>
Signed-off-by: Robin Gong <yibin.gong at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index b3a2772f0aa1..76d7d399790f 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -725,7 +725,7 @@ static int __maybe_unused imx_mu_resume_noirq(struct device *dev)
 	 * send failed, may lead to system freeze. This issue
 	 * is observed by testing freeze mode suspend.
 	 */
-	if (!imx_mu_read(priv, priv->dcfg->xCR[0]) && !priv->clk) {
+	if (!priv->clk && !imx_mu_read(priv, priv->dcfg->xCR[0])) {
 		for (i = 0; i < IMX_MU_xCR_MAX; i++)
 			imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]);
 	}
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:43 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:43 +0800
Subject: [PATCH 3/7] mailbox: imx: Add support for identifying SCU wakeup
 source from sysfs
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-4-peng.fan@oss.nxp.com>

From: Ranjani Vaidyanathan <ranjani.vaidyanathan at nxp.com>

Record SCU wakeup interrupt in /sys/power/pm_wakeup_irq

Signed-off-by: Ranjani Vaidyanathan <ranjani.vaidyanathan at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 76d7d399790f..1f44ee11054d 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -337,7 +337,7 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
 	}
 
 	if (priv->suspend)
-		pm_system_wakeup();
+		pm_system_irq_wakeup(priv->irq);
 
 	return IRQ_HANDLED;
 }
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:45 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:45 +0800
Subject: [PATCH 5/7] dt-bindings: mailbox: imx-mu: add i.MX8 SECO MU support
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-6-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Similar to i.MX8QM/QXP SCU, i.MX8 SECO MU is dedicated for
communication between SECO and Cortex-A cores from hardware design,
it could not be reused for other purpose. To use SECO MU more
effectivly, add "fsl,imx8-mu-seco" compatile to support fast IPC.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 Documentation/devicetree/bindings/mailbox/fsl,mu.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
index a337bcd80c4a..f865b806ae6a 100644
--- a/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
+++ b/Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
@@ -28,6 +28,7 @@ properties:
       - const: fsl,imx7ulp-mu
       - const: fsl,imx8ulp-mu
       - const: fsl,imx8-mu-scu
+      - const: fsl,imx8-mu-seco
       - const: fsl,imx8ulp-mu-s4
       - items:
           - enum:
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:46 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:46 +0800
Subject: [PATCH 6/7] mailbox: imx: introduce rxdb callback
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-7-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add a rxdb callback to prepare for i.MX8 SECO MU rxdb which has a
different logic.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index e8a212d0da2f..a727eee49563 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -93,6 +93,7 @@ enum imx_mu_type {
 struct imx_mu_dcfg {
 	int (*tx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data);
 	int (*rx)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
+	int (*rxdb)(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp);
 	void (*init)(struct imx_mu_priv *priv);
 	enum imx_mu_type type;
 	u32	xTR;		/* Transmit Register0 */
@@ -179,6 +180,16 @@ static int imx_mu_generic_rx(struct imx_mu_priv *priv,
 	return 0;
 }
 
+static int imx_mu_generic_rxdb(struct imx_mu_priv *priv,
+			       struct imx_mu_con_priv *cp)
+{
+	imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
+		     priv->dcfg->xSR[IMX_MU_GSR]);
+	mbox_chan_received_data(cp->chan, NULL);
+
+	return 0;
+}
+
 static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp, void *data)
 {
 	u32 *arg = data;
@@ -329,9 +340,7 @@ static irqreturn_t imx_mu_isr(int irq, void *p)
 		priv->dcfg->rx(priv, cp);
 	} else if ((val == IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx)) &&
 		   (cp->type == IMX_MU_TYPE_RXDB)) {
-		imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
-			     priv->dcfg->xSR[IMX_MU_GSR]);
-		mbox_chan_received_data(chan, NULL);
+		priv->dcfg->rxdb(priv, cp);
 	} else {
 		dev_warn_ratelimited(priv->dev, "Not handled interrupt\n");
 		return IRQ_NONE;
@@ -639,6 +648,7 @@ static int imx_mu_remove(struct platform_device *pdev)
 static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
 	.tx	= imx_mu_generic_tx,
 	.rx	= imx_mu_generic_rx,
+	.rxdb	= imx_mu_generic_rxdb,
 	.init	= imx_mu_init_generic,
 	.xTR	= 0x0,
 	.xRR	= 0x10,
@@ -649,6 +659,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx6sx = {
 static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
 	.tx	= imx_mu_generic_tx,
 	.rx	= imx_mu_generic_rx,
+	.rxdb	= imx_mu_generic_rxdb,
 	.init	= imx_mu_init_generic,
 	.xTR	= 0x20,
 	.xRR	= 0x40,
@@ -659,7 +670,9 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = {
 static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = {
 	.tx	= imx_mu_generic_tx,
 	.rx	= imx_mu_generic_rx,
+	.rxdb	= imx_mu_generic_rxdb,
 	.init	= imx_mu_init_generic,
+	.rxdb	= imx_mu_generic_rxdb,
 	.type	= IMX_MU_V2,
 	.xTR	= 0x200,
 	.xRR	= 0x280,
@@ -682,6 +695,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
 	.tx	= imx_mu_specific_tx,
 	.rx	= imx_mu_specific_rx,
 	.init	= imx_mu_init_specific,
+	.rxdb	= imx_mu_generic_rxdb,
 	.xTR	= 0x0,
 	.xRR	= 0x10,
 	.xSR	= {0x20, 0x20, 0x20, 0x20},
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:47 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:47 +0800
Subject: [PATCH 7/7] mailbox: imx: add i.MX8 SECO MU support
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-8-peng.fan@oss.nxp.com>

From: Franck LENORMAND <franck.lenormand at nxp.com>

i.MX8/8X SECO firmware IPC is an implementation of passing messages.
But current imx-mailbox driver only support one word  message,
i.MX8/8X linux side firmware has to request four TX, four RX and a
TXDB to support IPC to SECO firmware. This is low efficent and
more interrupts triggered compared with one TX and one RX.

To make SECO MU work,
  - parse the size of msg.
  - Only enable TR0/RR0 interrupt for transmit/receive message.
  - For TX/RX, only support one TX channel and one RX channel
  - For RX, support receive msg of any size, limited by hardcoded value
    of 30.

Signed-off-by: Franck LENORMAND <franck.lenormand at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 213 +++++++++++++++++++++++++++++++++-
 1 file changed, 212 insertions(+), 1 deletion(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index a727eee49563..d70f730ff47e 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/mailbox_controller.h>
 #include <linux/module.h>
@@ -24,6 +25,9 @@
 #define IMX_MU_S4_CHANS		2
 #define IMX_MU_CHAN_NAME_SIZE	20
 
+#define IMX_MU_SECO_TX_TOUT (msecs_to_jiffies(3000))
+#define IMX_MU_SECO_RX_TOUT (msecs_to_jiffies(3000))
+
 enum imx_mu_chan_type {
 	IMX_MU_TYPE_TX,		/* Tx */
 	IMX_MU_TYPE_RX,		/* Rx */
@@ -48,7 +52,7 @@ enum imx_mu_xsr {
 
 struct imx_sc_rpc_msg_max {
 	struct imx_sc_rpc_msg hdr;
-	u32 data[7];
+	u32 data[30];
 };
 
 struct imx_s4_rpc_msg_max {
@@ -131,6 +135,55 @@ static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
 	return ioread32(priv->base + offs);
 }
 
+static int imx_mu_tx_waiting_write(struct imx_mu_priv *priv, u32 val, u32 idx)
+{
+	u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_TX_TOUT;
+	u32 status;
+	u32 can_write;
+
+	dev_dbg(priv->dev, "Trying to write %.8x to idx %d\n", val, idx);
+
+	do {
+		status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_TSR]);
+		can_write = status & IMX_MU_xSR_TEn(priv->dcfg->type, idx % 4);
+	} while (!can_write && time_is_after_jiffies64(timeout_time));
+
+	if (!can_write) {
+		dev_err(priv->dev, "timeout trying to write %.8x at %d(%.8x)\n",
+			val, idx, status);
+		return -ETIME;
+	}
+
+	imx_mu_write(priv, val, priv->dcfg->xTR + (idx % 4) * 4);
+
+	return 0;
+}
+
+static int imx_mu_rx_waiting_read(struct imx_mu_priv *priv, u32 *val, u32 idx)
+{
+	u64 timeout_time = get_jiffies_64() + IMX_MU_SECO_RX_TOUT;
+	u32 status;
+	u32 can_read;
+
+	dev_dbg(priv->dev, "Trying to read from idx %d\n", idx);
+
+	do {
+		status = imx_mu_read(priv, priv->dcfg->xSR[IMX_MU_RSR]);
+		can_read = status & IMX_MU_xSR_RFn(priv->dcfg->type, idx % 4);
+	} while (!can_read && time_is_after_jiffies64(timeout_time));
+
+	if (!can_read) {
+		dev_err(priv->dev, "timeout trying to read idx %d (%.8x)\n",
+			idx, status);
+		return -ETIME;
+	}
+
+	*val = imx_mu_read(priv, priv->dcfg->xRR + (idx % 4) * 4);
+	dev_dbg(priv->dev, "Read %.8x\n", *val);
+
+	return 0;
+}
+
 static u32 imx_mu_xcr_rmw(struct imx_mu_priv *priv, enum imx_mu_xcr type, u32 set, u32 clr)
 {
 	unsigned long flags;
@@ -289,6 +342,125 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
 	return 0;
 }
 
+static int imx_mu_seco_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp,
+			  void *data)
+{
+	struct imx_sc_rpc_msg_max *msg = data;
+	u32 *arg = data;
+	u32 byte_size;
+	int err;
+	int i;
+
+	dev_dbg(priv->dev, "Sending message\n");
+
+	switch (cp->type) {
+	case IMX_MU_TYPE_TXDB:
+		byte_size = msg->hdr.size * sizeof(u32);
+		if (byte_size > sizeof(*msg)) {
+			/*
+			 * The real message size can be different to
+			 * struct imx_sc_rpc_msg_max size
+			 */
+			dev_err(priv->dev,
+				"Exceed max msg size (%zu) on TX, got: %i\n",
+				sizeof(*msg), byte_size);
+			return -EINVAL;
+		}
+
+		print_hex_dump_debug("from client ", DUMP_PREFIX_OFFSET, 4, 4,
+				     data, byte_size, false);
+
+		/* Send first word */
+		dev_dbg(priv->dev, "Sending header\n");
+		imx_mu_write(priv, *arg++, priv->dcfg->xTR);
+
+		/* Send signaling */
+		dev_dbg(priv->dev, "Sending signaling\n");
+		imx_mu_xcr_rmw(priv, IMX_MU_GCR,
+			       IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
+
+		/* Send words to fill the mailbox */
+		for (i = 1; i < 4 && i < msg->hdr.size; i++) {
+			dev_dbg(priv->dev, "Sending word %d\n", i);
+			imx_mu_write(priv, *arg++,
+				     priv->dcfg->xTR + (i % 4) * 4);
+		}
+
+		/* Send rest of message waiting for remote read */
+		for (; i < msg->hdr.size; i++) {
+			dev_dbg(priv->dev, "Sending word %d\n", i);
+			err = imx_mu_tx_waiting_write(priv, *arg++, i);
+			if (err) {
+				dev_err(priv->dev, "Timeout tx %d\n", i);
+				return err;
+			}
+		}
+
+		/* Simulate hack for mbox framework */
+		tasklet_schedule(&cp->txdb_tasklet);
+
+		break;
+	default:
+		dev_warn_ratelimited(priv->dev,
+				     "Send data on wrong channel type: %d\n",
+				     cp->type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int imx_mu_seco_rxdb(struct imx_mu_priv *priv, struct imx_mu_con_priv *cp)
+{
+	struct imx_sc_rpc_msg_max msg;
+	u32 *data = (u32 *)&msg;
+	u32 byte_size;
+	int err = 0;
+	int i;
+
+	dev_dbg(priv->dev, "Receiving message\n");
+
+	/* Read header */
+	dev_dbg(priv->dev, "Receiving header\n");
+	*data++ = imx_mu_read(priv, priv->dcfg->xRR);
+	byte_size = msg.hdr.size * sizeof(u32);
+	if (byte_size > sizeof(msg)) {
+		dev_err(priv->dev, "Exceed max msg size (%zu) on RX, got: %i\n",
+			sizeof(msg), byte_size);
+		err = -EINVAL;
+		goto error;
+	}
+
+	/* Read message waiting they are written */
+	for (i = 1; i < msg.hdr.size; i++) {
+		dev_dbg(priv->dev, "Receiving word %d\n", i);
+		err = imx_mu_rx_waiting_read(priv, data++, i);
+		if (err) {
+			dev_err(priv->dev, "Timeout rx %d\n", i);
+			goto error;
+		}
+	}
+
+	/* Clear GIP */
+	imx_mu_write(priv, IMX_MU_xSR_GIPn(priv->dcfg->type, cp->idx),
+		     priv->dcfg->xSR[IMX_MU_GSR]);
+
+	print_hex_dump_debug("to client ", DUMP_PREFIX_OFFSET, 4, 4,
+			     &msg, byte_size, false);
+
+	/* send data to client */
+	dev_dbg(priv->dev, "Sending message to client\n");
+	mbox_chan_received_data(cp->chan, (void *)&msg);
+
+	goto exit;
+
+error:
+	mbox_chan_received_data(cp->chan, ERR_PTR(err));
+
+exit:
+	return err;
+}
+
 static void imx_mu_txdb_tasklet(unsigned long data)
 {
 	struct imx_mu_con_priv *cp = (struct imx_mu_con_priv *)data;
@@ -494,6 +666,27 @@ static struct mbox_chan * imx_mu_xlate(struct mbox_controller *mbox,
 	return &mbox->chans[chan];
 }
 
+static struct mbox_chan *imx_mu_seco_xlate(struct mbox_controller *mbox,
+					   const struct of_phandle_args *sp)
+{
+	u32 type;
+
+	if (sp->args_count < 1) {
+		dev_err(mbox->dev, "Invalid argument count %d\n", sp->args_count);
+		return ERR_PTR(-EINVAL);
+	}
+
+	type = sp->args[0]; /* channel type */
+
+	/* Only supports TXDB and RXDB */
+	if (type == IMX_MU_TYPE_TX || type == IMX_MU_TYPE_RX) {
+		dev_err(mbox->dev, "Invalid type: %d\n", type);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return imx_mu_xlate(mbox, sp);
+}
+
 static void imx_mu_init_generic(struct imx_mu_priv *priv)
 {
 	unsigned int i;
@@ -544,6 +737,12 @@ static void imx_mu_init_specific(struct imx_mu_priv *priv)
 		imx_mu_write(priv, 0, priv->dcfg->xCR[i]);
 }
 
+static void imx_mu_init_seco(struct imx_mu_priv *priv)
+{
+	imx_mu_init_generic(priv);
+	priv->mbox.of_xlate = imx_mu_seco_xlate;
+}
+
 static int imx_mu_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -702,12 +901,24 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8_scu = {
 	.xCR	= {0x24, 0x24, 0x24, 0x24},
 };
 
+static const struct imx_mu_dcfg imx_mu_cfg_imx8_seco = {
+	.tx	= imx_mu_seco_tx,
+	.rx	= imx_mu_generic_rx,
+	.rxdb	= imx_mu_seco_rxdb,
+	.init	= imx_mu_init_seco,
+	.xTR	= 0x0,
+	.xRR	= 0x10,
+	.xSR	= {0x20, 0x20, 0x20, 0x20},
+	.xCR	= {0x24, 0x24, 0x24, 0x24},
+};
+
 static const struct of_device_id imx_mu_dt_ids[] = {
 	{ .compatible = "fsl,imx7ulp-mu", .data = &imx_mu_cfg_imx7ulp },
 	{ .compatible = "fsl,imx6sx-mu", .data = &imx_mu_cfg_imx6sx },
 	{ .compatible = "fsl,imx8ulp-mu", .data = &imx_mu_cfg_imx8ulp },
 	{ .compatible = "fsl,imx8ulp-mu-s4", .data = &imx_mu_cfg_imx8ulp_s4 },
 	{ .compatible = "fsl,imx8-mu-scu", .data = &imx_mu_cfg_imx8_scu },
+	{ .compatible = "fsl,imx8-mu-seco", .data = &imx_mu_cfg_imx8_seco },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, imx_mu_dt_ids);
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan  3 22:25:44 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue,  4 Jan 2022 14:25:44 +0800
Subject: [PATCH 4/7] mailbox: imx: enlarge timeout while reading/writing
 messages to SCFW
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <20220104062547.2103016-5-peng.fan@oss.nxp.com>

From: Ranjani Vaidyanathan <ranjani.vaidyanathan at nxp.com>

Mailbox driver needs to wait and read all the words in response to a
SCFW API call, else the protocol gets messed up and results in kernel hang.
When the responses are longer than 3 words its possible that SCFW will
take some time to fill up the rest of the words in the MU, a timeout of
100us is arbritrary and too short. While waiting for Linux to consume the
first 3 words of the response SCFW can be busy doing other stuff and hence
Linux needs to wait for the rest of the words.
Similar restriction applies when writing messages that are longer than
3 words.
This patch increases the timeout to 5secs while waiting for response
or writing long messages to SCFW.

Signed-off-by: Ranjani Vaidyanathan <ranjani.vaidyanathan at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/mailbox/imx-mailbox.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
index 1f44ee11054d..e8a212d0da2f 100644
--- a/drivers/mailbox/imx-mailbox.c
+++ b/drivers/mailbox/imx-mailbox.c
@@ -218,7 +218,7 @@ static int imx_mu_specific_tx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
 			ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_TSR],
 						 xsr,
 						 xsr & IMX_MU_xSR_TEn(priv->dcfg->type, i % num_tr),
-						 0, 100);
+						 0, 5 * USEC_PER_SEC);
 			if (ret) {
 				dev_err(priv->dev, "Send data index: %d timeout\n", i);
 				return ret;
@@ -263,7 +263,8 @@ static int imx_mu_specific_rx(struct imx_mu_priv *priv, struct imx_mu_con_priv *
 
 	for (i = 1; i < size; i++) {
 		ret = readl_poll_timeout(priv->base + priv->dcfg->xSR[IMX_MU_RSR], xsr,
-					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % 4), 0, 100);
+					 xsr & IMX_MU_xSR_RFn(priv->dcfg->type, i % 4), 0,
+					 5 * USEC_PER_SEC);
 		if (ret) {
 			dev_err(priv->dev, "timeout read idx %d\n", i);
 			return ret;
-- 
2.25.1



From Tudor.Ambarus at microchip.com  Mon Jan  3 23:07:12 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Tue, 4 Jan 2022 07:07:12 +0000
Subject: [PATCH] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
In-Reply-To: <CO1PR11MB48651B354ABAF04ABB53FB04924A9@CO1PR11MB4865.namprd11.prod.outlook.com>
References: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
 <76804bd6-00e5-02ab-59df-d32586a55422@microchip.com>
 <CO1PR11MB48651B354ABAF04ABB53FB04924A9@CO1PR11MB4865.namprd11.prod.outlook.com>
Message-ID: <29f7e062-5669-ef1c-a80c-5e5b7b01af79@microchip.com>

On 1/4/22 7:20 AM, Kavyasree Kotagiri - I30978 wrote:
>> On 1/3/22 2:48 PM, Kavyasree Kotagiri wrote:
>>> diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts
>> b/arch/arm/boot/dts/lan966x_pcb8291.dts
>>> new file mode 100644
>>> index 000000000000..cd0454a795e7
>>> --- /dev/null
>>> +++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
>>> @@ -0,0 +1,55 @@
>>
>>> +&flx3 {
>>> +       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
>>> +       status = "okay";
>>> +
>>> +       usart0: serial at 200 {
>>> +               compatible = "atmel,at91sam9260-usart";
>>
>> The flexcom usart mode should be defined in the dtsi file, so that you
>> won't duplicate the definition in each dts that includes the dtsi file.
>>
> defining flexcom mode in dts as flx3 can be used as USART/I2C/SPI on different boards.

Right, you should define the mode in dtsi and enable it in the dts file.

> And it is not the same mode for all boards.
> 
>> Cheers,
>> ta


From benjamin.gaignard at collabora.com  Mon Jan  3 23:38:40 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue,  4 Jan 2022 08:38:40 +0100
Subject: [PATCH v4 0/2] media: HEVC: RPS clean up
Message-ID: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>

This series aims to clean up Reference Picture Set usage and flags.

Long term flag was named with RPS prefix while it is not used for RPS
but for mark long term references in DBP. Remane it and remove the two
other useless RPS flags.

Clarify documentation about RPS lists content and make sure that Hantro
driver use them correctly (i.e without look up in DBP).

version 4:
- check flags with & and not ==
- remove the 2 last patches which becomes useless since VPU ctrl-blk
  driver introduction.

version 3:
- rebased on top of v5.16-rc1

version 2:
- change DPB field name from rps to flags

GStreamer HEVC plugin merge request can be found here:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1079

With those piece of code fluster score is 77/147.

Benjamin Gaignard (2):
  media: hevc: Remove RPS named flags
  media: hevc: Embedded indexes in RPS

 .../media/v4l/ext-ctrls-codec.rst             | 14 +++++-----
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 27 +++++--------------
 .../staging/media/sunxi/cedrus/cedrus_h265.c  |  2 +-
 include/media/hevc-ctrls.h                    |  6 ++---
 4 files changed, 16 insertions(+), 33 deletions(-)

-- 
2.30.2



From benjamin.gaignard at collabora.com  Mon Jan  3 23:38:41 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue,  4 Jan 2022 08:38:41 +0100
Subject: [PATCH v4 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
Message-ID: <20220104073842.1791639-2-benjamin.gaignard@collabora.com>

Marking a picture as long-term reference is valid for DPB but not for RPS.
Change flag name to match with it description in HEVC spec chapiter
"8.3.2 Decoding process for reference picture set".
Remove the other unused RPS flags.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
version 4:
- check flags with & and not ==

 Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 8 +++-----
 drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
 drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
 include/media/hevc-ctrls.h                                | 6 ++----
 4 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index e141f0e4eec9..38da33e61c3d 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3166,11 +3166,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
 	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
     * - __u8
-      - ``rps``
-      - The reference set for the reference frame
-        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
-        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
-        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+      - ``flags``
+      - Long term flag for the reference frame
+        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
     * - __u8
       - ``field_pic``
       - Whether the reference is a field picture or a frame.
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 99d8ea7543da..14e0e6414100 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -433,7 +433,7 @@ static int set_ref(struct hantro_ctx *ctx)
 		chroma_addr = luma_addr + cr_offset;
 		mv_addr = luma_addr + mv_offset;
 
-		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[i].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
 
 		hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 8829a7bab07e..8ab2d9c6f048 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
 		unsigned int index = list[i];
 		u8 value = list[i];
 
-		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[index].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
 
 		/* Each SRAM word gathers up to 4 references. */
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
index ef63bc205756..01ccda48d8c5 100644
--- a/include/media/hevc-ctrls.h
+++ b/include/media/hevc-ctrls.h
@@ -127,15 +127,13 @@ struct v4l2_ctrl_hevc_pps {
 	__u64	flags;
 };
 
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
-#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
 
 #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
 
 struct v4l2_hevc_dpb_entry {
 	__u64	timestamp;
-	__u8	rps;
+	__u8	flags;
 	__u8	field_pic;
 	__u16	pic_order_cnt[2];
 	__u8	padding[2];
-- 
2.30.2



From benjamin.gaignard at collabora.com  Mon Jan  3 23:38:42 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue,  4 Jan 2022 08:38:42 +0100
Subject: [PATCH v4 2/2] media: hevc: Embedded indexes in RPS
In-Reply-To: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
Message-ID: <20220104073842.1791639-3-benjamin.gaignard@collabora.com>

Reference Picture Set lists provide indexes of short and long term
reference in DBP array.
Fix Hantro to not do a look up in DBP entries.
Make documentation more clear about it.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 .../media/v4l/ext-ctrls-codec.rst             |  6 ++---
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++--------------
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 38da33e61c3d..b12ad5b3eaba 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3381,15 +3381,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
     * - __u8
       - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term before references in DPB array.
     * - __u8
       - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term after references in DPB array.
     * - __u8
       - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocLtCurr as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the long term references in DPB array.
     * - __u64
       - ``flags``
       - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 14e0e6414100..c524af41baf5 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -255,24 +255,11 @@ static void set_params(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &g2_apf_threshold, 8);
 }
 
-static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt)
-{
-	int i;
-
-	for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
-		if (dpb[i].pic_order_cnt[0] == pic_order_cnt)
-			return i;
-	}
-
-	return 0x0;
-}
-
 static void set_ref_pic_list(struct hantro_ctx *ctx)
 {
 	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
 	struct hantro_dev *vpu = ctx->dev;
 	const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
-	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
 	u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	static const struct hantro_reg ref_pic_regs0[] = {
@@ -316,11 +303,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 	/* List 0 contains: short term before, short term after and long term */
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list0[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list0[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list0[j++] = decode_params->poc_lt_curr[i];
 
 	/* Fill the list, copying over and over */
 	i = 0;
@@ -329,11 +316,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list1[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list1[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list1[j++] = decode_params->poc_lt_curr[i];
 
 	i = 0;
 	while (j < ARRAY_SIZE(list1))
-- 
2.30.2



From wenst at chromium.org  Mon Jan  3 23:40:55 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 4 Jan 2022 15:40:55 +0800
Subject: [PATCH 1/3] pinctrl: mediatek: pinctrl-moore: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAGXv+5HJSDZe-Ob4jpPcPnsCn=4Pqu=JHz9B4S4hANQF80r2kg@mail.gmail.com>

On Mon, Jan 3, 2022 at 6:19 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Use the dev_err_probe() helper to simplify error handling during probe.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From wenst at chromium.org  Mon Jan  3 23:44:36 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 4 Jan 2022 15:44:36 +0800
Subject: [PATCH 2/3] pinctrl: mediatek: pinctrl-paris: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-2-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
 <20220103101855.17350-2-angelogioacchino.delregno@collabora.com>
Message-ID: <CAGXv+5EONgNiQDk0eOVSnVG_U6_=XSpDWADt73x2=tZPt1gL7Q@mail.gmail.com>

On Mon, Jan 3, 2022 at 6:19 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Use the dev_err_probe() helper to simplify error handling during probe.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From christian.koenig at amd.com  Mon Jan  3 23:47:54 2022
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Tue, 4 Jan 2022 08:47:54 +0100
Subject: [PATCH v2] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <CALAqxLVA4jUk-2o28RZobrPDUnuXfV1xN77Pt8Pu1o27V3aUQQ@mail.gmail.com>
References: <20211217094104.24977-1-guangming.cao@mediatek.com>
 <20211227095102.6054-1-guangming.cao@mediatek.com>
 <CALAqxLVA4jUk-2o28RZobrPDUnuXfV1xN77Pt8Pu1o27V3aUQQ@mail.gmail.com>
Message-ID: <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>

Am 03.01.22 um 19:57 schrieb John Stultz:
> On Mon, Dec 27, 2021 at 1:52 AM <guangming.cao at mediatek.com> wrote:
>> From: Guangming <Guangming.Cao at mediatek.com>
>>
> Thanks for submitting this!
>
>> Add a size check for allcation since the allocation size is
> nit: "allocation" above.
>
>> always less than the total DRAM size.
> In general, it might be good to add more context to the commit message
> to better answer *why* this change is needed rather than what the
> change is doing.  ie: What negative thing happens without this change?
> And so how does this change avoid or improve things?

Completely agree, just one little addition: Could you also add this why 
as comment to the code?

When we stumble over this five years from now it is absolutely not 
obvious why we do this.

Thanks,
Christian.

>
>
>> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
>> Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
>> ---
>> v2: 1. update size limitation as total_dram page size.
>>      2. update commit message
>> ---
>>   drivers/dma-buf/dma-heap.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
>> index 56bf5ad01ad5..e39d2be98d69 100644
>> --- a/drivers/dma-buf/dma-heap.c
>> +++ b/drivers/dma-buf/dma-heap.c
>> @@ -55,6 +55,8 @@ static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
>>          struct dma_buf *dmabuf;
>>          int fd;
>>
>> +       if (len / PAGE_SIZE > totalram_pages())
>> +               return -EINVAL;
> This seems sane. I know ION used to have some 1/2 of memory cap to
> avoid unnecessary memory pressure on crazy allocations.
>
> Could you send again with an improved commit message?
>
> thanks
> -john



From wenst at chromium.org  Mon Jan  3 23:52:31 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 4 Jan 2022 15:52:31 +0800
Subject: [PATCH 3/3] pinctrl: mediatek: pinctrl-mtk-common: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-3-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
 <20220103101855.17350-3-angelogioacchino.delregno@collabora.com>
Message-ID: <CAGXv+5EEU4Kg4pgGBsAgN4TFBc8X-Euar9aMzM_0it3chGasKQ@mail.gmail.com>

Hi,

On Mon, Jan 3, 2022 at 6:19 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Use the dev_err_probe() helper to simplify error handling during probe.

You should mention the additional comment you added, and the error message
you fixed up.

> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Otherwise,

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From harinik at xilinx.com  Mon Jan  3 23:56:28 2022
From: harinik at xilinx.com (Harini Katakam)
Date: Tue, 4 Jan 2022 13:26:28 +0530
Subject: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <CAFcVECJeRwgjGsxtcGpMuA23nnmywsNkA2Yngk6aDK_JuVE3NQ@mail.gmail.com>
References: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
 <E1mxqBh-00GWxo-51@rmk-PC.armlinux.org.uk>
 <20211216071513.6d1e0f55@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
 <YbtxGLrXoR9oHRmM@shell.armlinux.org.uk>
 <CAFcVECJeRwgjGsxtcGpMuA23nnmywsNkA2Yngk6aDK_JuVE3NQ@mail.gmail.com>
Message-ID: <CAFcVEC+N0Y7ESFe-qcfpmkbPjRSvCJ=AOXoM6XSK6xGo=J1YNw@mail.gmail.com>

On Fri, Dec 17, 2021 at 1:55 PM Harini Katakam <harinik at xilinx.com> wrote:
>
> Hi Russell,
>
> On Fri, Dec 17, 2021 at 5:26 AM Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> >
> > On Thu, Dec 16, 2021 at 07:15:13AM -0800, Jakub Kicinski wrote:
> > > On Thu, 16 Dec 2021 12:48:45 +0000 Russell King (Oracle) wrote:
> > > > Convert axienet to use the phylink_pcs layer, resulting in it no longer
> > > > being a legacy driver.
> > > >
> > > > One oddity in this driver is that lp->switch_x_sgmii controls whether
> > > > we support switching between SGMII and 1000baseX. However, when clear,
> > > > this also blocks updating the 1000baseX advertisement, which it
> > > > probably should not be doing. Nevertheless, this behaviour is preserved
> > > > but a comment is added.
> > > >
> > > > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > >
> > > drivers/net/ethernet/xilinx/xilinx_axienet.h:479: warning: Function parameter or member 'pcs' not described in 'axienet_local'
> >
> > Fixed that and the sha1 issue you raised in patch 2. Since both are
> > "documentation" issues, I won't send out replacement patches until
> > I've heard they've been tested on hardware though.
>
> Thanks for the patches.
> Series looks good and we're testing at our end; will get back to you
> early next week.

Thanks Russell. I've tested AXI Ethernet and it works fine.

Regards,
Harini


From Tudor.Ambarus at microchip.com  Tue Jan  4 00:02:10 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Tue, 4 Jan 2022 08:02:10 +0000
Subject: [PATCH] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
In-Reply-To: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
References: <20220103124857.24351-1-kavyasree.kotagiri@microchip.com>
Message-ID: <30161c1d-97f2-851e-7d57-6f604758f72f@microchip.com>

On 1/3/22 2:48 PM, Kavyasree Kotagiri wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> This patch adds basic DT for Microchip lan966x SoC and associated board
> pcb8291(2-port EVB). Adds peripherals required to allow booting: IRQs,
> clocks, timers, memory, flexcoms, GPIOs. Also adds other peripherals like
> crypto(AES,SHA), DMA and watchdog.
> 
> Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> ---
>  arch/arm/boot/dts/Makefile            |   2 +
>  arch/arm/boot/dts/lan966x.dtsi        | 235 ++++++++++++++++++++++++++
>  arch/arm/boot/dts/lan966x_pcb8291.dts |  55 ++++++
>  3 files changed, 292 insertions(+)
>  create mode 100644 arch/arm/boot/dts/lan966x.dtsi
>  create mode 100644 arch/arm/boot/dts/lan966x_pcb8291.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..dc1bd216ed58 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
>  dtb-$(CONFIG_SOC_IMX7ULP) += \
>         imx7ulp-com.dtb \
>         imx7ulp-evk.dtb
> +dtb-$(CONFIG_SOC_LAN966) += \
> +       lan966x_pcb8291.dtb
>  dtb-$(CONFIG_SOC_LS1021A) += \
>         ls1021a-moxa-uc-8410a.dtb \
>         ls1021a-qds.dtb \
> diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
> new file mode 100644
> index 000000000000..7e56394b036f
> --- /dev/null
> +++ b/arch/arm/boot/dts/lan966x.dtsi
> @@ -0,0 +1,235 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * lan966x.dtsi - Device Tree Include file for Microchip LAN966x family SoC
> + *
> + * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
> + *
> + * Author: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> + *
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/dma/at91.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clock/microchip,lan966x.h>
> +
> +/ {
> +       model = "Microchip LAN966x family SoC";
> +       compatible = "microchip,lan966x";
> +       interrupt-parent = <&gic>;
> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               cpu at 0 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a7";
> +                       clock-frequency = <600000000>;
> +                       reg = <0x0>;
> +               };
> +       };
> +
> +       memory at 60000000 {
> +               device_type = "memory";
> +               reg = <0x60000000 0x40000000>;  /* 1GB */
> +       };
> +
> +       clocks {
> +               sys_clk: sys_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <162500000>;
> +               };
> +
> +               cpu_clk: cpu_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <600000000>;
> +               };
> +
> +               ddr_clk: ddr_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <300000000>;
> +               };
> +
> +               nic_clk: nic_clk {
> +                       compatible = "fixed-clock";
> +                       #clock-cells = <0>;
> +                       clock-frequency = <200000000>;
> +               };
> +       };
> +
> +       clks: clock-controller at e00c00a8 {
> +               compatible = "microchip,lan966x-gck";
> +               #clock-cells = <1>;
> +               clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
> +               clock-names = "cpu", "ddr", "sys";
> +               reg = <0xe00c00a8 0x38>;
> +       };
> +
> +       timer {
> +               compatible = "arm,armv7-timer";
> +               interrupt-parent = <&gic>;
> +               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
> +               clock-frequency = <37500000>;
> +               arm,cpu-registers-not-fw-configured;
> +       };
> +
> +       soc {
> +               compatible = "simple-bus";
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               ranges;
> +
> +               flx0: flexcom at e0040000 {
> +                       compatible = "atmel,sama5d2-flexcom";
> +                       reg = <0xe0040000 0x100>;
> +                       clocks = <&clks GCK_ID_FLEXCOM0>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges = <0x0 0xe0040000 0x800>;
> +                       status = "disabled";
> +               };
> +
> +               flx1: flexcom at e0044000 {
> +                       compatible = "atmel,sama5d2-flexcom";
> +                       reg = <0xe0044000 0x100>;
> +                       clocks = <&clks GCK_ID_FLEXCOM1>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges = <0x0 0xe0044000 0x800>;
> +                       status = "disabled";
> +               };
> +
> +               trng: trng at e0048000 {
> +                       compatible = "atmel,at91sam9g45-trng";
> +                       reg = <0xe0048000 0x100>;
> +                       clocks = <&nic_clk>;
> +                       status = "disabled";
> +               };
> +
> +               aes: aes at e004c000 {
> +                       compatible = "atmel,at91sam9g46-aes";
> +                       reg = <0xe004c000 0x100>;
> +                       interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +                       dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
> +                              <&dma0 AT91_XDMAC_DT_PERID(12)>;
> +                       dma-names = "rx", "tx";
> +                       clocks = <&nic_clk>;
> +                       clock-names = "aes_clk";

status = "disabled";?

> +               };
> +
> +               flx2: flexcom at e0060000 {
> +                       compatible = "atmel,sama5d2-flexcom";
> +                       reg = <0xe0060000 0x100>;
> +                       clocks = <&clks GCK_ID_FLEXCOM2>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges = <0x0 0xe0060000 0x800>;
> +                       status = "disabled";
> +               };
> +
> +               flx3: flexcom at e0064000 {
> +                       compatible = "atmel,sama5d2-flexcom";
> +                       reg = <0xe0064000 0x100>,
> +                             <0xe2004180 0x8>;
> +                       clocks = <&clks GCK_ID_FLEXCOM3>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges = <0x0 0xe0064000 0x800>;
> +                       status = "disabled";
> +                     };
> +
> +               dma0: dma-controller at e0068000 {
> +                       compatible = "microchip,sama7g5-dma";
> +                       reg = <0xe0068000 0x1000>;
> +                       interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
> +                       #dma-cells = <1>;
> +                       clocks = <&nic_clk>;
> +                       clock-names = "dma_clk";
> +                       status = "okay";
> +               };
> +
> +               sha: sha at e006c000 {
> +                       compatible = "atmel,at91sam9g46-sha";
> +                       reg = <0xe006c000 0xec>;
> +                       interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
> +                       dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
> +                       dma-names = "tx";
> +                       clocks = <&nic_clk>;
> +                       clock-names = "sha_clk";

status?

> +               };
> +
> +               flx4: flexcom at e0070000 {
> +                       compatible = "atmel,sama5d2-flexcom";
> +                       reg = <0xe0070000 0x100>;
> +                       clocks = <&clks GCK_ID_FLEXCOM4>;
> +                       #address-cells = <1>;
> +                       #size-cells = <1>;
> +                       ranges = <0x0 0xe0070000 0x800>;
> +                       status = "disabled";
> +               };
> +
> +               timer0: timer at e008c000 {
> +                       compatible = "snps,dw-apb-timer";
> +                       reg = <0xe008c000 0x400>;
> +                       clocks = <&nic_clk>;
> +                       clock-names = "timer";
> +                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> +               };
> +
> +               watchdog: watchdog at e0090000 {
> +                       compatible = "snps,dw-wdt";
> +                       reg = <0xe0090000 0x1000>;
> +                       interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&nic_clk>;

status?

Cheers,
ta

From yunfei.dong at mediatek.com  Tue Jan  4 00:01:29 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:29 +0800
Subject: [PATCH v3,
 04/13] media: mtk-vcodec: Read max resolution from dec_capability
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-5-yunfei.dong@mediatek.com>

Supported max resolution for different platforms are not the same: 2K
or 4K, getting it according to dec_capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 31 +++++++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +++
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 130ecef2e766..65a224d788bf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -152,13 +152,15 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
 	q_data->field = V4L2_FIELD_NONE;
+	ctx->max_width = MTK_VDEC_MAX_W;
+	ctx->max_height = MTK_VDEC_MAX_H;
 
 	v4l_bound_align_image(&q_data->coded_width,
 				MTK_VDEC_MIN_W,
-				MTK_VDEC_MAX_W, 4,
+				ctx->max_width, 4,
 				&q_data->coded_height,
 				MTK_VDEC_MIN_H,
-				MTK_VDEC_MAX_H, 5, 6);
+				ctx->max_height, 5, 6);
 
 	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
 	q_data->bytesperline[0] = q_data->coded_width;
@@ -217,17 +219,17 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
 	}
 }
 
-static int vidioc_try_fmt(struct v4l2_format *f,
-			  const struct mtk_video_fmt *fmt)
+static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx,
+	struct v4l2_format *f, const struct mtk_video_fmt *fmt)
 {
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 
 	pix_fmt_mp->field = V4L2_FIELD_NONE;
 
 	pix_fmt_mp->width =
-		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
+		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width);
 	pix_fmt_mp->height =
-		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
+		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height);
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		pix_fmt_mp->num_planes = 1;
@@ -245,16 +247,16 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 		tmp_h = pix_fmt_mp->height;
 		v4l_bound_align_image(&pix_fmt_mp->width,
 					MTK_VDEC_MIN_W,
-					MTK_VDEC_MAX_W, 6,
+					ctx->max_width, 6,
 					&pix_fmt_mp->height,
 					MTK_VDEC_MIN_H,
-					MTK_VDEC_MAX_H, 6, 9);
+					ctx->max_height, 6, 9);
 
 		if (pix_fmt_mp->width < tmp_w &&
-			(pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W)
+			(pix_fmt_mp->width + 64) <= ctx->max_width)
 			pix_fmt_mp->width += 64;
 		if (pix_fmt_mp->height < tmp_h &&
-			(pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H)
+			(pix_fmt_mp->height + 64) <= ctx->max_height)
 			pix_fmt_mp->height += 64;
 
 		mtk_v4l2_debug(0,
@@ -294,7 +296,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
@@ -317,7 +319,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 		return -EINVAL;
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -445,7 +447,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		return -EINVAL;
 
 	q_data->fmt = fmt;
-	vidioc_try_fmt(f, q_data->fmt);
+	vidioc_try_fmt(ctx, f, q_data->fmt);
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
 		q_data->coded_width = pix_mp->width;
@@ -545,6 +547,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 				fsize->stepwise.min_height,
 				fsize->stepwise.max_height,
 				fsize->stepwise.step_height);
+
+		ctx->max_width = fsize->stepwise.max_width;
+		ctx->max_height = fsize->stepwise.max_height;
 		return 0;
 	}
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index a23a7646437c..2d7ec1e16423 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -287,6 +287,8 @@ struct vdec_pic_info {
  *	  mtk_video_dec_buf.
  * @hw_id: hardware index used to identify different hardware.
  *
+ * @max_width: hardware supported max width
+ * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
@@ -332,6 +334,8 @@ struct mtk_vcodec_ctx {
 	struct mutex lock;
 	int hw_id;
 
+	unsigned int max_width;
+	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:27 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:27 +0800
Subject: [PATCH v3,
 02/13] media: mtk-vcodec: Using firmware type to separate different
 firmware architecture
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-3-yunfei.dong@mediatek.com>

MT8173 platform use vpu firmware, mt8183/mt8192 will use scp
firmware instead, using chip name is not reasonable to separate
different firmware architecture. Using firmware type is much better.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c | 1 -
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c    | 2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h          | 2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c           | 6 ++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h           | 1 +
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c             | 4 ++--
 6 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 04ca43c77e5f..7966c132be8f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -613,7 +613,6 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
-	.chip = MTK_MT8173,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23d997ac114d..5aebf88f997b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -343,7 +343,6 @@ static struct vb2_ops mtk_vdec_request_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
-	.chip = MTK_MT8183,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
@@ -362,7 +361,6 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 
 /* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
-	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3fc747cea5c9..a23a7646437c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -367,7 +367,6 @@ enum mtk_vdec_hw_arch {
  * @vdec_framesizes: supported video decoder frame sizes
  * @num_framesizes: count of video decoder frame sizes
  *
- * @chip: chip this decoder is compatible with
  * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
@@ -390,7 +389,6 @@ struct mtk_vcodec_dec_pdata {
 	const struct mtk_codec_framesizes *vdec_framesizes;
 	const int num_framesizes;
 
-	enum mtk_chip chip;
 	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
index 94b39ae5c2e1..556e54aadac9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
@@ -65,3 +65,9 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
 	return fw->ops->ipi_send(fw, id, buf, len, wait);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_send);
+
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
+{
+	return fw->type;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
index 539bb626772c..acd355961e3a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
@@ -39,5 +39,6 @@ int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
 			       const char *name, void *priv);
 int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
 			   void *buf, unsigned int len, unsigned int wait);
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
 
 #endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index c84fac52fe26..21f6d9c5a371 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -33,8 +33,8 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	 */
 	vpu->inst_id = 0xdeadbeef;
 
-	/* Firmware version field does not exist on MT8173. */
-	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
+	/* VPU firmware does not contain a version field. */
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:38 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:38 +0800
Subject: [PATCH 13/13] media: mtk-vcodec: Add h264 decoder driver for mt8192
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-14-yunfei.dong@mediatek.com>

Adds h264 lat and core driver for mt8192, and the decode mode is frame
based for stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_lat_if.c    | 620 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 include/linux/remoteproc/mtk_scp.h            |   2 +
 5 files changed, 631 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_lat_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 3f41d748eee5..1777d7606f0d 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
+		vdec/vdec_h264_req_lat_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_lat_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_lat_if.c
new file mode 100644
index 000000000000..403d7df00e1d
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_lat_if.c
@@ -0,0 +1,620 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+#include "vdec_h264_req_common.h"
+
+/**
+ * enum vdec_h264_core_dec_err_type  - core decode error type
+ */
+enum vdec_h264_core_dec_err_type {
+	TRANS_BUFFER_FULL = 1,
+	SLICE_HEADER_FULL,
+};
+
+/**
+ * struct vdec_h264_slice_lat_dec_param  - parameters for decode current frame
+ * @sps : h264 sps syntax parameters
+ * @pps : h264 pps syntax parameters
+ * @slice_header: h264 slice header syntax parameters
+ * @scaling_matrix : h264 scaling list parameters
+ * @decode_params : decoder parameters of each frame used for hardware decode
+ * @h264_dpb_info : dpb reference list
+ */
+struct vdec_h264_slice_lat_dec_param {
+	struct mtk_h264_sps_param sps;
+	struct mtk_h264_pps_param pps;
+	struct mtk_h264_slice_hd_param slice_header;
+	struct slice_api_h264_scaling_matrix scaling_matrix;
+	struct slice_api_h264_decode_param decode_params;
+	struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+/**
+ * struct vdec_h264_slice_info - decode information
+ * @nal_info    : nal info of current picture
+ * @timeout     : Decode timeout: 1 timeout, 0 no timeount
+ * @bs_buf_size : bitstream size
+ * @bs_buf_addr : bitstream buffer dma address
+ * @y_fb_dma    : Y frame buffer dma address
+ * @c_fb_dma    : C frame buffer dma address
+ * @vdec_fb_va  : VDEC frame buffer struct virtual address
+ * @crc         : Used to check whether hardware's status is right
+ */
+struct vdec_h264_slice_info {
+	uint16_t nal_info;
+	uint16_t timeout;
+	uint32_t bs_buf_size;
+	uint64_t bs_buf_addr;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+	uint32_t crc[8];
+};
+
+/**
+ * struct vdec_h264_slice_vsi - shared memory for decode information exchange
+ *        between VPU and Host. The memory is allocated by VPU then mapping to
+ *        Host in vdec_h264_slice_init() and freed in vdec_h264_slice_deinit()
+ *        by VPU. AP-W/R : AP is writer/reader on this item. VPU-W/R: VPU is
+ *        write/reader on this item.
+ * @wdma_err_addr       : wdma error dma address
+ * @wdma_start_addr     : wdma start dma address
+ * @wdma_end_addr       : wdma end dma address
+ * @slice_bc_start_addr : slice bc start dma address
+ * @slice_bc_end_addr   : slice bc end dma address
+ * @row_info_start_addr : row info start dma address
+ * @row_info_end_addr   : row info end dma address
+ * @trans_start         : trans start dma address
+ * @trans_end           : trans end dma address
+ * @wdma_end_addr_offset: wdma end address offset
+ * @mv_buf_dma          : HW working motion vector buffer
+ *                        dma address (AP-W, VPU-R)
+ * @dec                 : decode information (AP-R, VPU-W)
+ * @h264_slice_params   : decode parameters for hw used
+ */
+struct vdec_h264_slice_vsi {
+	/* LAT dec addr */
+	uint64_t wdma_err_addr;
+	uint64_t wdma_start_addr;
+	uint64_t wdma_end_addr;
+	uint64_t slice_bc_start_addr;
+	uint64_t slice_bc_end_addr;
+	uint64_t row_info_start_addr;
+	uint64_t row_info_end_addr;
+	uint64_t trans_start;
+	uint64_t trans_end;
+	uint64_t wdma_end_addr_offset;
+
+	uint64_t mv_buf_dma[H264_MAX_MV_NUM];
+	struct vdec_h264_slice_info dec;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+};
+
+/**
+ * struct vdec_h264_slice_share_info - shared information used to exchange
+ *                                     message between lat and core
+ * @sps	              : sequence header information from user space
+ * @dec_params        : decoder params from user space
+ * @h264_slice_params : decoder params used for hardware
+ * @trans_start       : trans start dma address
+ * @trans_end         : trans end dma address
+ * @nal_info          : nal info of current picture
+ */
+struct vdec_h264_slice_share_info {
+	struct v4l2_ctrl_h264_sps sps;
+	struct v4l2_ctrl_h264_decode_params dec_params;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+	uint64_t trans_start;
+	uint64_t trans_end;
+	uint16_t nal_info;
+};
+
+/**
+ * struct vdec_h264_slice_inst - h264 decoder instance
+ * @num_nalu            : how many nalus be decoded
+ * @ctx                 : point to mtk_vcodec_ctx
+ * @pred_buf            : HW working predication buffer
+ * @mv_buf              : HW working motion vector buffer
+ * @vpu                 : VPU instance
+ * @vsi                 : vsi used for lat
+ * @vsi_core            : vsi used for core
+ * @resolution_changed  : resolution changed
+ * @realloc_mv_buf      : reallocate mv buffer
+ * @cap_num_planes      : number of capture queue plane
+ */
+struct vdec_h264_slice_inst {
+	unsigned int num_nalu;
+	struct mtk_vcodec_ctx *ctx;
+	struct mtk_vcodec_mem pred_buf;
+	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
+	struct vdec_vpu_inst vpu;
+	struct vdec_h264_slice_vsi *vsi;
+	struct vdec_h264_slice_vsi *vsi_core;
+
+	unsigned int resolution_changed;
+	unsigned int realloc_mv_buf;
+	unsigned int cap_num_planes;
+
+	struct v4l2_h264_dpb_entry dpb[16];
+};
+
+static void vdec_h264_slice_fill_decode_parameters(
+	struct vdec_h264_slice_inst *inst,
+	struct vdec_h264_slice_share_info *share_info)
+{
+	struct vdec_h264_slice_lat_dec_param *slice_param =
+		&inst->vsi->h264_slice_params;
+	const struct v4l2_ctrl_h264_decode_params *dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	const struct v4l2_ctrl_h264_sps *sps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_SPS);
+	const struct v4l2_ctrl_h264_pps *pps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_PPS);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps,sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(
+		&slice_param->scaling_matrix, src_matrix);
+
+	memcpy(&share_info->sps, sps, sizeof(*sps));
+	memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params));
+}
+
+/*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
+static void fixup_ref_list(u8 *ref_list, size_t num_valid)
+{
+	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
+}
+
+static void vdec_h264_slice_fill_decode_reflist(
+	struct vdec_h264_slice_inst *inst,
+	struct vdec_h264_slice_lat_dec_param *slice_param,
+	struct vdec_h264_slice_share_info *share_info)
+{
+	struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
+	struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params,
+		inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+		slice_param->h264_dpb_info);
+
+	mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt);
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
+				       inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+
+	/* Adapt the built lists to the firmware's expectations */
+	fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+}
+
+static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	int i;
+	int err;
+	struct mtk_vcodec_mem *mem;
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(
+		pic->buf_w, pic->buf_h);
+
+	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+		mem->size = buf_sz;
+		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+		if (err) {
+			mtk_vcodec_err(inst, "failed to allocate mv buf");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst)
+{
+	int i;
+	struct mtk_vcodec_mem *mem;
+
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+	}
+}
+
+static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+	inst->cap_num_planes =
+		ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
+		ctx->picinfo.fb_sz[1]);
+
+	if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
+		(ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h)) {
+		inst->resolution_changed = true;
+		if ((ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w) ||
+			(ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h))
+			inst->realloc_mv_buf = true;
+
+		mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
+			inst->resolution_changed,
+			inst->realloc_mv_buf,
+			ctx->last_decoded_picinfo.pic_w,
+			ctx->last_decoded_picinfo.pic_h,
+			ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+	}
+}
+
+static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
+	struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->ctx->picinfo.pic_w;
+	cr->height = inst->ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_h264_slice_inst *inst;
+	int err, vsi_size;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), 64);
+	inst->vsi = inst->vpu.vsi;
+	inst->vsi_core =
+		(struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+	inst->resolution_changed = true;
+	inst->realloc_mv_buf = true;
+
+	mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n",
+		(int)sizeof(struct mtk_h264_sps_param),
+		(int)sizeof(struct mtk_h264_pps_param),
+		(int)sizeof(struct vdec_h264_slice_lat_dec_param),
+		(int)sizeof(struct mtk_h264_dpb_info),
+		vsi_size);
+	mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x",
+		inst, inst->vpu.codec_type);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static void vdec_h264_slice_deinit(void *h_vdec)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_h264_slice_free_mv_buf(inst);
+	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
+
+	kfree(inst);
+}
+
+static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_fb *fb;
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma, c_fb_dma;
+	int err, timeout, i, dec_err;
+	struct vdec_vpu_inst *vpu;
+	struct mtk_vcodec_ctx *ctx = lat_buf->ctx;
+	struct vdec_h264_slice_inst *inst = ctx->drv_handle;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
+	struct mtk_vcodec_mem *mem;
+
+	mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode");
+	memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params,
+		sizeof(share_info->h264_slice_params));
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	vpu = &inst->vpu;
+	vdec_fb_va = (unsigned long)fb;
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma =
+			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+		c_fb_dma);
+
+	inst->vsi_core->dec.y_fb_dma = y_fb_dma;
+	inst->vsi_core->dec.c_fb_dma = c_fb_dma;
+	inst->vsi_core->dec.vdec_fb_va = vdec_fb_va;
+	inst->vsi_core->dec.nal_info = share_info->nal_info;
+	inst->vsi_core->wdma_start_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi_core->wdma_end_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+	inst->vsi_core->trans_start = share_info->trans_start;
+	inst->vsi_core->trans_end = share_info->trans_end;
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi_core->mv_buf_dma[i] = mem->dma_addr;
+	}
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	vb2_v4l2->vb2_buf.timestamp = lat_buf->ts_info.vb2_buf.timestamp;
+	vb2_v4l2->timecode = lat_buf->ts_info.timecode;
+	vb2_v4l2->field = lat_buf->ts_info.field;
+	vb2_v4l2->flags = lat_buf->ts_info.flags;
+	vb2_v4l2->vb2_buf.copied_timestamp =
+		lat_buf->ts_info.vb2_buf.copied_timestamp;
+
+	vdec_h264_slice_fill_decode_reflist(inst,
+		&inst->vsi_core->h264_slice_params, share_info);
+
+	err = vpu_dec_core(vpu);
+	if (err) {
+		dec_err = 1;
+		mtk_vcodec_err(inst, "core decode err=%d", err);
+		goto vdec_dec_end;
+	} else {
+		dec_err = 0;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(
+		inst->ctx, MTK_INST_IRQ_RECEIVED,
+		WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+	if (timeout)
+		mtk_vcodec_err(inst, "core decode timeout: pic_%d",
+			ctx->decoded_frame_cnt);
+	inst->vsi_core->dec.timeout = !!timeout;
+
+	vpu_dec_core_end(vpu);
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+		ctx->decoded_frame_cnt,
+		inst->vsi_core->dec.crc[0],	inst->vsi_core->dec.crc[1],
+		inst->vsi_core->dec.crc[2],	inst->vsi_core->dec.crc[3],
+		inst->vsi_core->dec.crc[4],	inst->vsi_core->dec.crc[5],
+		inst->vsi_core->dec.crc[6],	inst->vsi_core->dec.crc[7]);
+vdec_dec_end:
+	vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue,
+		inst->vsi_core->trans_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, dec_err);
+	mtk_vcodec_debug(inst, "core decode done err=%d", err);
+	ctx->decoded_frame_cnt++;
+
+	return 0;
+}
+
+static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+	struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	int nal_start_idx, err, timeout = 0, i;
+	unsigned int nal_type, data[2];
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_h264_slice_share_info *share_info;
+	unsigned char *buf;
+	struct mtk_vcodec_mem *mem;
+
+	mtk_vcodec_debug(inst, "+ [%d] ", ++inst->num_nalu);
+
+	if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
+		vdec_h264_slice_core_decode, sizeof(*share_info)))
+	return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs) {
+		vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue);
+		return vpu_dec_reset(vpu);
+	}
+
+	lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(inst, "failed to get lat buffer");
+		return -EINVAL;
+	}
+	share_info = lat_buf->private_data;
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	buf = (unsigned char *)bs->va;
+	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
+	if (nal_start_idx < 0) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	inst->vsi->dec.nal_info = buf[nal_start_idx];
+	nal_type = NAL_TYPE(buf[nal_start_idx]);
+	mtk_vcodec_debug(inst, "\n + NALU[%d] type %d +\n", inst->num_nalu,
+			 nal_type);
+
+	inst->vsi->dec.bs_buf_addr = (uint64_t)bs->dma_addr;
+	inst->vsi->dec.bs_buf_size = bs->size;
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+		&lat_buf->ts_info, true);
+
+	vdec_h264_slice_fill_decode_parameters(inst, share_info);
+	*res_chg = inst->resolution_changed;
+	if (inst->resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->realloc_mv_buf) {
+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		inst->resolution_changed = false;
+	}
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi->mv_buf_dma[i] = mem->dma_addr;
+	}
+	inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+
+	inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr;
+	inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx)err:0x%llx",
+		inst->vsi->wdma_start_addr,
+		inst->vsi->wdma_end_addr,
+		inst->vsi->wdma_err_addr);
+
+	mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))",
+		inst->vsi->slice_bc_start_addr,
+		inst->vsi->slice_bc_end_addr,
+		inst->vsi->trans_start,
+		inst->vsi->trans_end);
+	err = vpu_dec_start(vpu, data, 2);
+	if (err) {
+		mtk_vcodec_debug(inst, "lat decode err: %d", err);
+		goto err_free_fb_out;
+	}
+
+	if (nal_type == NAL_NON_IDR_SLICE || nal_type == NAL_IDR_SLICE) {
+		/* wait decoder done interrupt */
+		timeout = mtk_vcodec_wait_for_done_ctx(
+			inst->ctx, MTK_INST_IRQ_RECEIVED,
+			WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+		inst->vsi->dec.timeout = !!timeout;
+	}
+	err = vpu_dec_end(vpu);
+	if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
+		share_info->trans_end);
+
+	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		sizeof(share_info->h264_slice_params));
+	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	mtk_vcodec_debug(inst, "- NALU[%d] type=%d -\n", inst->num_nalu,
+			 nal_type);
+	return 0;
+
+err_free_fb_out:
+	mtk_vcodec_err(inst, "- NALU[%d] err=%d -\n", inst->num_nalu, err);
+	return err;
+}
+
+static int vdec_h264_slice_get_param(void *h_vdec,
+	enum vdec_get_param_type type, void *out)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_h264_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*(unsigned int *)out = 6;
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_h264_slice_get_crop_info(inst, out);
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+const struct vdec_common_if vdec_h264_slice_lat_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c93dd0ea3537..c17a7815e1bb 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -20,7 +20,13 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
-		ctx->dec_if = &vdec_h264_slice_if;
+		if (ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) {
+			ctx->dec_if = &vdec_h264_slice_if;
+			ctx->hw_id = MTK_VDEC_CORE;
+		} else {
+			ctx->dec_if = &vdec_h264_slice_lat_if;
+			ctx->hw_id = MTK_VDEC_LAT0;
+		}
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index d467e8af4a84..6ce848e74167 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -56,6 +56,7 @@ struct vdec_fb_node {
 
 extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
+extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
diff --git a/include/linux/remoteproc/mtk_scp.h b/include/linux/remoteproc/mtk_scp.h
index b47416f7aeb8..a32ffd736e7b 100644
--- a/include/linux/remoteproc/mtk_scp.h
+++ b/include/linux/remoteproc/mtk_scp.h
@@ -41,6 +41,8 @@ enum scp_ipi_id {
 	SCP_IPI_ISP_FRAME,
 	SCP_IPI_FD_CMD,
 	SCP_IPI_CROS_HOST_CMD,
+	SCP_IPI_VDEC_LAT,
+	SPC_IPI_VDEC_CORE,
 	SCP_IPI_NS_SERVICE = 0xFF,
 	SCP_IPI_MAX = 0x100,
 };
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:37 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:37 +0800
Subject: [PATCH v3, 12/13] media: mtk-vcodec: Extract H264 common code
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-13-yunfei.dong@mediatek.com>

Mt8192 can use some of common code with mt8183. Moves them to
a new file in order to reuse.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 303 ++++++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 247 +++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 386 +-----------------
 4 files changed, 571 insertions(+), 366 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 359619653a0e..3f41d748eee5 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
+		vdec/vdec_h264_req_common.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
new file mode 100644
index 000000000000..7e248e247628
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
@@ -0,0 +1,303 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include "vdec_h264_req_common.h"
+
+/* get used parameters for sps/pps */
+#define GET_MTK_VDEC_FLAG(cond, flag) \
+	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
+#define GET_MTK_VDEC_PARAM(param) \
+	{ dst_param->param = src_param->param; }
+
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+	struct slice_api_h264_decode_param *decode_params,
+	struct mtk_h264_dpb_info *h264_dpb_info)
+{
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	int index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
+		const struct slice_h264_dpb_entry *dpb;
+		int vb2_index;
+
+		dpb = &decode_params->dpb[index];
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
+			h264_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+
+		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
+		if (vb2_index < 0) {
+			dev_err(&ctx->dev->plat_dev->dev,
+				"Reference invalid: dpb_index(%d) reference_ts(%lld)",
+				index, dpb->reference_ts);
+			continue;
+		}
+
+		/* 1 for short term reference, 2 for long term reference */
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			h264_dpb_info[index].reference_flag = 1;
+		else
+			h264_dpb_info[index].reference_flag = 2;
+
+		vb = vq->bufs[vb2_index];
+		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
+		h264_dpb_info[index].field = vb2_v4l2->field;
+
+		h264_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			h264_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			h264_dpb_info[index].c_dma_addr =
+				h264_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+}
+
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+	const struct v4l2_ctrl_h264_sps *src_param)
+{
+	GET_MTK_VDEC_PARAM(chroma_format_idc);
+	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
+	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
+	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
+	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
+	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
+	GET_MTK_VDEC_PARAM(max_num_ref_frames);
+	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
+	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
+
+	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
+		V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
+	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
+		V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
+		V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
+		V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
+		V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
+		V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+}
+
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+	const struct v4l2_ctrl_h264_pps *src_param)
+{
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
+	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
+	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
+	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
+	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
+
+	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
+		V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	GET_MTK_VDEC_FLAG(pic_order_present_flag,
+		V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	GET_MTK_VDEC_FLAG(weighted_pred_flag,
+		V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
+		V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
+		V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
+		V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
+		V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
+		V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+}
+
+void mtk_vdec_h264_copy_slice_hd_params(
+	struct mtk_h264_slice_hd_param *dst_param,
+	const struct v4l2_ctrl_h264_slice_params *src_param,
+	const struct v4l2_ctrl_h264_decode_params *dec_param)
+{
+	int temp;
+
+	GET_MTK_VDEC_PARAM(first_mb_in_slice);
+	GET_MTK_VDEC_PARAM(slice_type);
+	GET_MTK_VDEC_PARAM(cabac_init_idc);
+	GET_MTK_VDEC_PARAM(slice_qp_delta);
+	GET_MTK_VDEC_PARAM(disable_deblocking_filter_idc);
+	GET_MTK_VDEC_PARAM(slice_alpha_c0_offset_div2);
+	GET_MTK_VDEC_PARAM(slice_beta_offset_div2);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_active_minus1);
+
+	dst_param->frame_num = dec_param->frame_num;
+	dst_param->pic_order_cnt_lsb = dec_param->pic_order_cnt_lsb;
+
+	dst_param->delta_pic_order_cnt_bottom =
+		dec_param->delta_pic_order_cnt_bottom;
+	dst_param->delta_pic_order_cnt0 =
+		dec_param->delta_pic_order_cnt0;
+	dst_param->delta_pic_order_cnt1 =
+		dec_param->delta_pic_order_cnt1;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
+	dst_param->field_pic_flag = temp ? 1 : 0;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD;
+	dst_param->bottom_field_flag = temp ? 1 : 0;
+
+	GET_MTK_VDEC_FLAG(direct_spatial_mv_pred_flag,
+		V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
+}
+
+void mtk_vdec_h264_copy_scaling_matrix(
+	struct slice_api_h264_scaling_matrix *dst_matrix,
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
+{
+	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
+	       sizeof(dst_matrix->scaling_list_4x4));
+
+	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
+	       sizeof(dst_matrix->scaling_list_8x8));
+}
+
+void mtk_vdec_h264_copy_decode_params(
+	struct slice_api_h264_decode_param *dst_params,
+	const struct v4l2_ctrl_h264_decode_params *src_params,
+	const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
+		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
+		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
+
+		dst_entry->reference_ts = src_entry->reference_ts;
+		dst_entry->frame_num = src_entry->frame_num;
+		dst_entry->pic_num = src_entry->pic_num;
+		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
+		dst_entry->bottom_field_order_cnt =
+			src_entry->bottom_field_order_cnt;
+		dst_entry->flags = src_entry->flags;
+	}
+
+	/* num_slices is a leftover from the old H.264 support and is ignored
+	 * by the firmware.
+	 */
+	dst_params->num_slices = 0;
+	dst_params->nal_ref_idc = src_params->nal_ref_idc;
+	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
+	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
+	dst_params->flags = src_params->flags;
+}
+
+static bool mtk_vdec_h264_dpb_entry_match(
+	const struct v4l2_h264_dpb_entry *a,
+	const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+/*
+ * Move DPB entries of dec_param that refer to a frame already existing in dpb
+ * into the already existing slot in dpb, and move other entries into new slots.
+ *
+ * This function is an adaptation of the similarly-named function in
+ * hantro_h264.c.
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+	struct v4l2_h264_dpb_entry *dpb)
+{
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	/* Disable all entries by default, and mark the ones in use. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			set_bit(i, in_use);
+		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+	}
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries were already used.
+		 */
+		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &dpb[j];
+			if (!mtk_vdec_h264_dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			/* Don't reiterate on this one. */
+			clear_bit(j, in_use);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(dec_param->dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
+			return;
+
+		cdpb = &dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+unsigned int mtk_vdec_h264_get_mv_buf_size(
+	unsigned int width, unsigned int height)
+{
+	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
+
+	return HW_MB_STORE_SZ * unit_size;
+}
+
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz)
+{
+	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
+		return 3;
+
+	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
+	    data[3] == 1)
+		return 4;
+
+	return -1;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
new file mode 100644
index 000000000000..71372fcae168
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_H264_REQ_COMMON_H_
+#define _VDEC_H264_REQ_COMMON_H_
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_drv.h"
+
+#define NAL_NON_IDR_SLICE			0x01
+#define NAL_IDR_SLICE				0x05
+#define NAL_TYPE(value)				((value) & 0x1F)
+
+#define BUF_PREDICTION_SZ			(64 * 4096)
+#define MB_UNIT_LEN				16
+
+/* motion vector size (bytes) for every macro block */
+#define HW_MB_STORE_SZ				64
+
+#define H264_MAX_MV_NUM				32
+
+/**
+ * struct mtk_h264_dpb_info  - h264 dpb information
+ * @y_dma_addr: Y bitstream physical address
+ * @c_dma_addr: CbCr bitstream physical address
+ * @reference_flag: reference picture flag (short/long term reference picture)
+ * @field: field picture flag
+ */
+struct mtk_h264_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int field;
+};
+
+/**
+ * struct mtk_h264_sps_param  - parameters for sps
+ */
+struct mtk_h264_sps_param {
+	unsigned char chroma_format_idc;
+	unsigned char bit_depth_luma_minus8;
+	unsigned char bit_depth_chroma_minus8;
+	unsigned char log2_max_frame_num_minus4;
+	unsigned char pic_order_cnt_type;
+	unsigned char log2_max_pic_order_cnt_lsb_minus4;
+	unsigned char max_num_ref_frames;
+	unsigned char separate_colour_plane_flag;
+	unsigned short pic_width_in_mbs_minus1;
+	unsigned short pic_height_in_map_units_minus1;
+	unsigned int max_frame_nums;
+	unsigned char qpprime_y_zero_transform_bypass_flag;
+	unsigned char delta_pic_order_always_zero_flag;
+	unsigned char frame_mbs_only_flag;
+	unsigned char mb_adaptive_frame_field_flag;
+	unsigned char direct_8x8_inference_flag;
+	unsigned char reserved[3];
+};
+
+/**
+ * struct mtk_h264_pps_param  - parameters for pps
+ */
+struct mtk_h264_pps_param {
+	unsigned char num_ref_idx_l0_default_active_minus1;
+	unsigned char num_ref_idx_l1_default_active_minus1;
+	unsigned char weighted_bipred_idc;
+	char pic_init_qp_minus26;
+	char chroma_qp_index_offset;
+	char second_chroma_qp_index_offset;
+	unsigned char entropy_coding_mode_flag;
+	unsigned char pic_order_present_flag;
+	unsigned char deblocking_filter_control_present_flag;
+	unsigned char constrained_intra_pred_flag;
+	unsigned char weighted_pred_flag;
+	unsigned char redundant_pic_cnt_present_flag;
+	unsigned char transform_8x8_mode_flag;
+	unsigned char scaling_matrix_present_flag;
+	unsigned char reserved[2];
+};
+
+/**
+ * struct mtk_h264_slice_hd_param  - parameters for slice header
+ */
+struct mtk_h264_slice_hd_param {
+	unsigned int first_mb_in_slice;
+	unsigned int field_pic_flag;
+	unsigned int slice_type;
+	unsigned int frame_num;
+	int pic_order_cnt_lsb;
+	int delta_pic_order_cnt_bottom;
+	unsigned int bottom_field_flag;
+	unsigned int direct_spatial_mv_pred_flag;
+	int delta_pic_order_cnt0;
+	int delta_pic_order_cnt1;
+	unsigned int cabac_init_idc;
+	int slice_qp_delta;
+	unsigned int disable_deblocking_filter_idc;
+	int slice_alpha_c0_offset_div2;
+	int slice_beta_offset_div2;
+	unsigned int num_ref_idx_l0_active_minus1;
+	unsigned int num_ref_idx_l1_active_minus1;
+	unsigned int reserved;
+};
+
+struct slice_api_h264_scaling_matrix {
+	unsigned char scaling_list_4x4[6][16];
+	unsigned char scaling_list_8x8[6][64];
+};
+
+struct slice_h264_dpb_entry {
+	unsigned long long reference_ts;
+	unsigned short frame_num;
+	unsigned short pic_num;
+	/* Note that field is indicated by v4l2_buffer.field */
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+/**
+ * struct slice_api_h264_decode_param - parameters for decode.
+ */
+struct slice_api_h264_decode_param {
+	struct slice_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
+	unsigned short num_slices;
+	unsigned short nal_ref_idc;
+	unsigned char ref_pic_list_p0[32];
+	unsigned char ref_pic_list_b0[32];
+	unsigned char ref_pic_list_b1[32];
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+};
+
+/**
+ * struct h264_fb - h264 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct h264_fb {
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	int32_t poc;
+	uint32_t reserved;
+};
+
+/**
+ * mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @id: CID control ID
+ */
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id);
+
+/**
+ * mtk_vdec_h264_fill_dpb_info - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @decode_params: slice decode params
+ * @h264_dpb_info: dpb buffer information
+ */
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+	struct slice_api_h264_decode_param *decode_params,
+	struct mtk_h264_dpb_info *h264_dpb_info);
+
+/**
+ * mtk_vdec_h264_copy_sps_params - get sps params.
+ * @dst_params: sps params for hw decoder
+ * @src_params: sps params from user driver
+ */
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+	const struct v4l2_ctrl_h264_sps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_pps_params - get pps params.
+ * @dst_params: pps params for hw decoder
+ * @src_params: pps params from user driver
+ */
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+	const struct v4l2_ctrl_h264_pps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_slice_hd_params - get slice header params.
+ * @dst_params: slice params for hw decoder
+ * @src_params: slice params from user driver
+ * @dec_param: decode params from user driver
+ */
+void mtk_vdec_h264_copy_slice_hd_params(
+	struct mtk_h264_slice_hd_param *dst_param,
+	const struct v4l2_ctrl_h264_slice_params *src_param,
+	const struct v4l2_ctrl_h264_decode_params *dec_param);
+
+/**
+ * mtk_vdec_h264_copy_scaling_matrix - get each CID contrl address.
+ * @dst_matrix: scaling list params for hw decoder
+ * @src_matrix: scaling list params from user driver
+ */
+void mtk_vdec_h264_copy_scaling_matrix(
+	struct slice_api_h264_scaling_matrix *dst_matrix,
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix);
+
+/**
+ * mtk_vdec_h264_copy_decode_params - get decode params.
+ * @dst_params: dst params for hw decoder
+ * @src_params: decode params from user driver
+ * @dpb: dpb information
+ */
+void mtk_vdec_h264_copy_decode_params(
+	struct slice_api_h264_decode_param *dst_params,
+	const struct v4l2_ctrl_h264_decode_params *src_params,
+	const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);
+
+
+/**
+ * mtk_vdec_h264_update_dpb - updata dpb list.
+ * @dec_param: v4l2 control decode params
+ * @dpb: dpb entry informaton
+ */
+void mtk_vdec_h264_update_dpb(
+	const struct v4l2_ctrl_h264_decode_params *dec_param,
+	struct v4l2_h264_dpb_entry *dpb);
+
+/**
+ * mtk_vdec_h264_find_start_code - find h264 start code using sofeware.
+ * @data: input buffer address
+ * @data_sz: input buffer size
+ */
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz);
+
+/**
+ * mtk_vdec_h264_get_mv_buf_size - get mv buffer size.
+ * @width: picture width
+ * @height: picture height
+ */
+unsigned int mtk_vdec_h264_get_mv_buf_size(
+	unsigned int width, unsigned int height);
+
+#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index d00219a7587c..1c92e71e7fa0 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -12,109 +12,7 @@
 #include "../vdec_drv_base.h"
 #include "../vdec_drv_if.h"
 #include "../vdec_vpu_if.h"
-
-#define BUF_PREDICTION_SZ			(64 * 4096)
-#define MB_UNIT_LEN				16
-
-/* get used parameters for sps/pps */
-#define GET_MTK_VDEC_FLAG(cond, flag) \
-	{ dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
-#define GET_MTK_VDEC_PARAM(param) \
-	{ dst_param->param = src_param->param; }
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ				64
-
-#define H264_MAX_FB_NUM				17
-#define H264_MAX_MV_NUM				32
-#define HDR_PARSING_BUF_SZ			1024
-
-/**
- * struct mtk_h264_dpb_info  - h264 dpb information
- * @y_dma_addr: Y bitstream physical address
- * @c_dma_addr: CbCr bitstream physical address
- * @reference_flag: reference picture flag (short/long term reference picture)
- * @field: field picture flag
- */
-struct mtk_h264_dpb_info {
-	dma_addr_t y_dma_addr;
-	dma_addr_t c_dma_addr;
-	int reference_flag;
-	int field;
-};
-
-/*
- * struct mtk_h264_sps_param  - parameters for sps
- */
-struct mtk_h264_sps_param {
-	unsigned char chroma_format_idc;
-	unsigned char bit_depth_luma_minus8;
-	unsigned char bit_depth_chroma_minus8;
-	unsigned char log2_max_frame_num_minus4;
-	unsigned char pic_order_cnt_type;
-	unsigned char log2_max_pic_order_cnt_lsb_minus4;
-	unsigned char max_num_ref_frames;
-	unsigned char separate_colour_plane_flag;
-	unsigned short pic_width_in_mbs_minus1;
-	unsigned short pic_height_in_map_units_minus1;
-	unsigned int max_frame_nums;
-	unsigned char qpprime_y_zero_transform_bypass_flag;
-	unsigned char delta_pic_order_always_zero_flag;
-	unsigned char frame_mbs_only_flag;
-	unsigned char mb_adaptive_frame_field_flag;
-	unsigned char direct_8x8_inference_flag;
-	unsigned char reserved[3];
-};
-
-/*
- * struct mtk_h264_pps_param  - parameters for pps
- */
-struct mtk_h264_pps_param {
-	unsigned char num_ref_idx_l0_default_active_minus1;
-	unsigned char num_ref_idx_l1_default_active_minus1;
-	unsigned char weighted_bipred_idc;
-	char pic_init_qp_minus26;
-	char chroma_qp_index_offset;
-	char second_chroma_qp_index_offset;
-	unsigned char entropy_coding_mode_flag;
-	unsigned char pic_order_present_flag;
-	unsigned char deblocking_filter_control_present_flag;
-	unsigned char constrained_intra_pred_flag;
-	unsigned char weighted_pred_flag;
-	unsigned char redundant_pic_cnt_present_flag;
-	unsigned char transform_8x8_mode_flag;
-	unsigned char scaling_matrix_present_flag;
-	unsigned char reserved[2];
-};
-
-struct slice_api_h264_scaling_matrix {
-	unsigned char scaling_list_4x4[6][16];
-	unsigned char scaling_list_8x8[6][64];
-};
-
-struct slice_h264_dpb_entry {
-	unsigned long long reference_ts;
-	unsigned short frame_num;
-	unsigned short pic_num;
-	/* Note that field is indicated by v4l2_buffer.field */
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
-};
-
-/*
- * struct slice_api_h264_decode_param - parameters for decode.
- */
-struct slice_api_h264_decode_param {
-	struct slice_h264_dpb_entry dpb[16];
-	unsigned short num_slices;
-	unsigned short nal_ref_idc;
-	unsigned char ref_pic_list_p0[32];
-	unsigned char ref_pic_list_b0[32];
-	unsigned char ref_pic_list_b1[32];
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
-};
+#include "vdec_h264_req_common.h"
 
 /*
  * struct mtk_h264_dec_slice_param  - parameters for decode current frame
@@ -127,22 +25,6 @@ struct mtk_h264_dec_slice_param {
 	struct mtk_h264_dpb_info h264_dpb_info[16];
 };
 
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va  : virtual address of struct vdec_fb
- * @y_fb_dma    : dma address of Y frame buffer (luma)
- * @c_fb_dma    : dma address of C frame buffer (chroma)
- * @poc         : picture order count of frame buffer
- * @reserved    : for 8 bytes alignment
- */
-struct h264_fb {
-	u64 vdec_fb_va;
-	u64 y_fb_dma;
-	u64 c_fb_dma;
-	s32 poc;
-	u32 reserved;
-};
-
 /**
  * struct vdec_h264_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
@@ -212,233 +94,6 @@ struct vdec_h264_slice_inst {
 	struct v4l2_h264_dpb_entry dpb[16];
 };
 
-static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
-{
-	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
-
-	return ctrl->p_cur.p;
-}
-
-static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
-			      struct mtk_h264_dec_slice_param *slice_param)
-{
-	struct vb2_queue *vq;
-	struct vb2_buffer *vb;
-	struct vb2_v4l2_buffer *vb2_v4l2;
-	u64 index;
-
-	vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-
-	for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
-		const struct slice_h264_dpb_entry *dpb;
-		int vb2_index;
-
-		dpb = &slice_param->decode_params.dpb[index];
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
-			slice_param->h264_dpb_info[index].reference_flag = 0;
-			continue;
-		}
-
-		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
-		if (vb2_index < 0) {
-			mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
-				       index, dpb->reference_ts);
-			continue;
-		}
-		/* 1 for short term reference, 2 for long term reference */
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
-			slice_param->h264_dpb_info[index].reference_flag = 1;
-		else
-			slice_param->h264_dpb_info[index].reference_flag = 2;
-
-		vb = vq->bufs[vb2_index];
-		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-		slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
-
-		slice_param->h264_dpb_info[index].y_dma_addr =
-			vb2_dma_contig_plane_dma_addr(vb, 0);
-		if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-			slice_param->h264_dpb_info[index].c_dma_addr =
-				vb2_dma_contig_plane_dma_addr(vb, 1);
-		}
-	}
-}
-
-static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
-				    const struct v4l2_ctrl_h264_sps *src_param)
-{
-	GET_MTK_VDEC_PARAM(chroma_format_idc);
-	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
-	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
-	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
-	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
-	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
-	GET_MTK_VDEC_PARAM(max_num_ref_frames);
-	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
-	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
-
-	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
-			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
-	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
-			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
-	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
-			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
-	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
-			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
-	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
-			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
-	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
-			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-}
-
-static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
-				    const struct v4l2_ctrl_h264_pps *src_param)
-{
-	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
-	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
-	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
-	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
-	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
-	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
-
-	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
-			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
-	GET_MTK_VDEC_FLAG(pic_order_present_flag,
-			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
-	GET_MTK_VDEC_FLAG(weighted_pred_flag,
-			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
-	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
-			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
-	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
-			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
-	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
-			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
-	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
-			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
-	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
-			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-}
-
-static void
-get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
-			const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
-{
-	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
-	       sizeof(dst_matrix->scaling_list_4x4));
-
-	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
-	       sizeof(dst_matrix->scaling_list_8x8));
-}
-
-static void
-get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
-			   const struct v4l2_ctrl_h264_decode_params *src_params,
-			   const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
-		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
-		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
-
-		dst_entry->reference_ts = src_entry->reference_ts;
-		dst_entry->frame_num = src_entry->frame_num;
-		dst_entry->pic_num = src_entry->pic_num;
-		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
-		dst_entry->bottom_field_order_cnt =
-			src_entry->bottom_field_order_cnt;
-		dst_entry->flags = src_entry->flags;
-	}
-
-	/*
-	 * num_slices is a leftover from the old H.264 support and is ignored
-	 * by the firmware.
-	 */
-	dst_params->num_slices = 0;
-	dst_params->nal_ref_idc = src_params->nal_ref_idc;
-	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
-	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
-	dst_params->flags = src_params->flags;
-}
-
-static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
-			    const struct v4l2_h264_dpb_entry *b)
-{
-	return a->top_field_order_cnt == b->top_field_order_cnt &&
-	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
-}
-
-/*
- * Move DPB entries of dec_param that refer to a frame already existing in dpb
- * into the already existing slot in dpb, and move other entries into new slots.
- *
- * This function is an adaptation of the similarly-named function in
- * hantro_h264.c.
- */
-static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
-		       struct v4l2_h264_dpb_entry *dpb)
-{
-	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	unsigned int i, j;
-
-	/* Disable all entries by default, and mark the ones in use. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
-			set_bit(i, in_use);
-		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
-	}
-
-	/* Try to match new DPB entries with existing ones by their POCs. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-
-		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-			continue;
-
-		/*
-		 * To cut off some comparisons, iterate only on target DPB
-		 * entries were already used.
-		 */
-		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
-			struct v4l2_h264_dpb_entry *cdpb;
-
-			cdpb = &dpb[j];
-			if (!dpb_entry_match(cdpb, ndpb))
-				continue;
-
-			*cdpb = *ndpb;
-			set_bit(j, used);
-			/* Don't reiterate on this one. */
-			clear_bit(j, in_use);
-			break;
-		}
-
-		if (j == ARRAY_SIZE(dec_param->dpb))
-			set_bit(i, new);
-	}
-
-	/* For entries that could not be matched, use remaining free slots. */
-	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-		struct v4l2_h264_dpb_entry *cdpb;
-
-		/*
-		 * Both arrays are of the same sizes, so there is no way
-		 * we can end up with no space in target array, unless
-		 * something is buggy.
-		 */
-		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
-		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
-			return;
-
-		cdpb = &dpb[j];
-		*cdpb = *ndpb;
-		set_bit(j, used);
-	}
-}
-
 /*
  * The firmware expects unused reflist entries to have the value 0x20.
  */
@@ -450,27 +105,32 @@ static void fixup_ref_list(u8 *ref_list, size_t num_valid)
 static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 {
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	const struct v4l2_ctrl_h264_sps *sps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_SPS);
 	const struct v4l2_ctrl_h264_pps *pps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
 	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_SCALING_MATRIX);
 	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
 	struct v4l2_h264_reflist_builder reflist_builder;
 	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
 	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
 	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
 
-	update_dpb(dec_params, inst->dpb);
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
 
-	get_h264_sps_parameters(&slice_param->sps, sps);
-	get_h264_pps_parameters(&slice_param->pps, pps);
-	get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
-	get_h264_decode_parameters(&slice_param->decode_params, dec_params,
-				   inst->dpb);
-	get_h264_dpb_list(inst, slice_param);
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix,
+		scaling_matrix);
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params,
+		dec_params, inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+		slice_param->h264_dpb_info);
 
 	/* Build the reference lists */
 	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
@@ -486,13 +146,6 @@ static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 	       sizeof(inst->vsi_ctx.h264_slice_params));
 }
 
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
-	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
-
-	return HW_MB_STORE_SZ * unit_size;
-}
-
 static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
 {
 	int err;
@@ -525,7 +178,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
 	int i;
 	int err;
 	struct mtk_vcodec_mem *mem = NULL;
-	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
 
 	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
 	for (i = 0; i < H264_MAX_MV_NUM; i++) {
@@ -674,7 +327,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
 	struct mtk_video_dec_buf *src_buf_info;
 	struct mtk_video_dec_buf *dst_buf_info;
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:30 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:30 +0800
Subject: [PATCH v3,
 05/13] media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set
 capture buffer buffered
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-6-yunfei.dong@mediatek.com>

lat thread: output queue      \
                               -> lat hardware -> lat trans buffer
            lat trans buffer  /

core thread: capture queue     \
                                ->core hardware -> capture queue
             lat trans buffer  /

Lat and core work in different thread, setting capture buffer buffered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 5aebf88f997b..23a154c4e321 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -314,6 +314,9 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 
+	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
+		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
 	src_vq->requires_requests = true;
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:36 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:36 +0800
Subject: [PATCH v3, 11/13] media: mtk-vcodec: record capture queue format type
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-12-yunfei.dong@mediatek.com>

Capture queue format type is difference for different platform,
need to calculate capture buffer size according to capture queue
format type in scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 75210eb829d0..4533cb44551d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -468,6 +468,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 			}
 			ctx->state = MTK_STATE_INIT;
 		}
+	} else {
+		ctx->capture_fourcc = fmt->fourcc;
 	}
 
 	/*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 6c084a172e4b..364d2d794af4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -277,6 +277,7 @@ struct vdec_pic_info {
  *		     to be used with encoder and stateful decoder.
  * @is_flushing: set to true if flushing is in progress.
  * @current_codec: current set input codec, in V4L2 pixel format
+ * @capture_fourcc: capture queue type in V4L2 pixel format
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -324,6 +325,7 @@ struct mtk_vcodec_ctx {
 	bool is_flushing;
 
 	u32 current_codec;
+	u32 capture_fourcc;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:32 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:32 +0800
Subject: [PATCH v3,
 07/13] media: mtk-vcodec: Refactor supported vdec formats and
 framesizes
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-8-yunfei.dong@mediatek.com>

Supported output and capture format types for mt8192 are different
with mt8183. Needs to get format types according to decoder capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   8 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 117 +++++++++++++-----
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  13 +-
 4 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 65a224d788bf..519f2b9d9b5b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -26,7 +26,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	const struct mtk_video_fmt *fmt;
 	unsigned int k;
 
-	for (k = 0; k < dec_pdata->num_formats; k++) {
+	for (k = 0; k < *dec_pdata->num_formats; k++) {
 		fmt = &dec_pdata->vdec_formats[k];
 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
 			return fmt;
@@ -525,7 +525,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	for (i = 0; i < dec_pdata->num_framesizes; ++i) {
+	for (i = 0; i < *dec_pdata->num_framesizes; ++i) {
 		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
 			continue;
 
@@ -564,7 +564,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 	const struct mtk_video_fmt *fmt;
 	int i, j = 0;
 
-	for (i = 0; i < dec_pdata->num_formats; i++) {
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
 		if (output_queue &&
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
 			continue;
@@ -577,7 +577,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		++j;
 	}
 
-	if (i == dec_pdata->num_formats)
+	if (i == *dec_pdata->num_formats)
 		return -EINVAL;
 
 	fmt = &dec_pdata->vdec_formats[i];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 7966c132be8f..3f33beb9c551 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -37,7 +37,9 @@ static const struct mtk_video_fmt mtk_video_formats[] = {
 	},
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+static const unsigned int num_supported_formats =
+	ARRAY_SIZE(mtk_video_formats);
+
 #define DEFAULT_OUT_FMT_IDX 0
 #define DEFAULT_CAP_FMT_IDX 3
 
@@ -59,7 +61,8 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 	},
 };
 
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+static const unsigned int num_supported_framesize =
+	ARRAY_SIZE(mtk_vdec_framesizes);
 
 /*
  * This function tries to clean all display buffers, the buffers will return
@@ -235,7 +238,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
 	unsigned int k;
 
 	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (k = 0; k < NUM_FORMATS; k++) {
+	for (k = 0; k < num_supported_formats; k++) {
 		fmt = &mtk_video_formats[k];
 		if (fmt->fourcc == pixelformat) {
 			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
@@ -617,11 +620,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
+	.num_formats = &num_supported_formats,
 	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
 	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_supported_framesize,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index f3036c3f223b..01bb96f3b30e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,33 +81,23 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static const struct mtk_video_fmt mtk_video_formats[] = {
-	{
-		.fourcc = V4L2_PIX_FMT_H264_SLICE,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_MM21,
-		.type = MTK_FMT_FRAME,
-		.num_planes = 2,
-	},
+static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+
+static struct mtk_video_fmt default_out_format;
+static struct mtk_video_fmt default_cap_format;
+static unsigned int num_formats = 0;
+static unsigned int num_framesizes = 0;
+
+static struct v4l2_frmsize_stepwise stepwise_fhd = {
+	.min_width = MTK_VDEC_MIN_W,
+	.max_width = MTK_VDEC_MAX_W,
+	.step_width = 16,
+	.min_height = MTK_VDEC_MIN_H,
+	.max_height = MTK_VDEC_MAX_H,
+	.step_height = 16
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX    0
-#define DEFAULT_CAP_FMT_IDX    1
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_H264_SLICE,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
 static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
 					   struct mtk_vcodec_mem *bs, int error)
 {
@@ -352,6 +342,63 @@ const struct media_device_ops mtk_vcodec_media_ops = {
 	.req_queue	= v4l2_m2m_request_queue,
 };
 
+static void mtk_vcodec_add_formats(unsigned int fourcc,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata;
+	int count_formats = *pdata->num_formats;
+	int count_framesizes = *pdata->num_framesizes;
+
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264_SLICE:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
+		mtk_video_formats[count_formats].num_planes = 1;
+
+		mtk_vdec_framesizes[count_framesizes].fourcc = fourcc;
+		mtk_vdec_framesizes[count_framesizes].stepwise = stepwise_fhd;
+		num_framesizes++;
+		break;
+	case V4L2_PIX_FMT_MM21:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
+		mtk_video_formats[count_formats].num_planes = 2;
+		break;
+	default:
+		mtk_v4l2_err("Can not add unsupported format type");
+		return;
+	}
+
+	num_formats++;
+	mtk_v4l2_debug(3, "num_formats: %d num_frames:%d dec_capability: 0x%x",
+		*(pdata->num_formats), *(pdata->num_framesizes),
+		ctx->dev->dec_capability);
+}
+
+static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
+{
+	int cap_format_count = 0, out_format_count = 0;
+
+	if (num_formats && num_framesizes)
+		return;
+
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
+		cap_format_count++;
+	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
+		out_format_count++;
+	}
+
+	if (cap_format_count)
+		default_cap_format = mtk_video_formats[cap_format_count - 1];
+	if (out_format_count)
+		default_out_format =
+			mtk_video_formats[cap_format_count + out_format_count - 1];
+}
+
 static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct vb2_queue *src_vq;
@@ -361,6 +408,10 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 
 	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
 		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+	else
+		ctx->dev->dec_capability |=
+			MTK_VDEC_FORMAT_H264_SLICE | MTK_VDEC_FORMAT_MM21;
+	mtk_vcodec_get_supported_formats(ctx);
 
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
@@ -395,11 +446,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
@@ -415,11 +466,11 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 5347d77300fa..4ae80d2e77d2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -354,6 +354,15 @@ enum mtk_vdec_hw_arch {
 	MTK_VDEC_LAT_SINGLE_CORE,
 };
 
+/**
+ * struct mtk_vdec_format_types - Structure used to get supported
+ *		  format types according to decoder capability
+ */
+enum mtk_vdec_format_types {
+	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -389,12 +398,12 @@ struct mtk_vcodec_dec_pdata {
 	struct vb2_ops *vdec_vb2_ops;
 
 	const struct mtk_video_fmt *vdec_formats;
-	const int num_formats;
+	const int *num_formats;
 	const struct mtk_video_fmt *default_out_fmt;
 	const struct mtk_video_fmt *default_cap_fmt;
 
 	const struct mtk_codec_framesizes *vdec_framesizes;
-	const int num_framesizes;
+	const int *num_framesizes;
 
 	enum mtk_vdec_hw_arch hw_arch;
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:28 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:28 +0800
Subject: [PATCH v3,
 03/13] media: mtk-vcodec: get capture queue buffer size from scp
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-4-yunfei.dong@mediatek.com>

Different capture buffer format has different buffer size, need to get
real buffer size according to buffer type from scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
comments:
+static void handle_get_param_msg_ack(
+	const struct vdec_vpu_ipi_get_param_ack *msg)
+{
+	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
+					(unsigned long)msg->ap_inst_addr;
> ap inst addr is uint64_t, but for 32bit system, only use 32bit address, so add unsigned long.

+	case GET_PARAM_PIC_INFO:
+		vpu->fb_sz[0] = msg->data[0];
+		vpu->fb_sz[1] = msg->data[1];
> fb_sz is used here.
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 37 ++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 51 +++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   | 15 ++++++
 3 files changed, 103 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5daca8d52ebb..476fc5777a0f 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -20,6 +20,7 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_RESET = 0xA004,
 	AP_IPIMSG_DEC_CORE = 0xA005,
 	AP_IPIMSG_DEC_CORE_END = 0xA006,
+	AP_IPIMSG_DEC_GET_PARAM = 0xA007,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
@@ -28,6 +29,7 @@ enum vdec_ipi_msgid {
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
 	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
 	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
+	VPU_IPIMSG_DEC_GET_PARAM_ACK = 0xB007,
 };
 
 /**
@@ -114,4 +116,39 @@ struct vdec_vpu_ipi_init_ack {
 	uint32_t inst_id;
 };
 
+/**
+ * struct vdec_ap_ipi_get_param - for AP_IPIMSG_GET_PARAM
+ * @msg_id	: AP_IPIMSG_DEC_GET_PARAM
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @data	: picture information
+ * @param_type	: get param type
+ * @codec_type	: Codec fourcc
+ */
+struct vdec_ap_ipi_get_param {
+	uint32_t msg_id;
+	uint32_t inst_id;
+	uint32_t data[4];
+	uint32_t param_type;
+	uint32_t codec_type;
+};
+
+
+/**
+ * struct vdec_vpu_ipi_get_param_ack - for VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @msg_id	: VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @status	: VPU exeuction result
+ * @ap_inst_addr	: AP vcodec_vpu_inst instance address
+ * @data     : picture information from SCP.
+ * @param_type	: get param type
+ * @reserved : reserved param
+ */
+struct vdec_vpu_ipi_get_param_ack {
+	uint32_t msg_id;
+	int32_t status;
+	uint64_t ap_inst_addr;
+	uint32_t data[4];
+	uint32_t param_type;
+	uint32_t reserved;
+};
+
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 21f6d9c5a371..2fb9a4184b27 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -6,6 +6,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
+#include "vdec_drv_if.h"
 #include "vdec_ipi_msg.h"
 #include "vdec_vpu_if.h"
 #include "mtk_vcodec_fw.h"
@@ -54,6 +55,27 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	}
 }
 
+static void handle_get_param_msg_ack(
+	const struct vdec_vpu_ipi_get_param_ack *msg)
+{
+	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
+					(unsigned long)msg->ap_inst_addr;
+
+	mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr);
+
+	/* param_type is enum vdec_get_param_type */
+	switch(msg->param_type) {
+	case GET_PARAM_PIC_INFO:
+		vpu->fb_sz[0] = msg->data[0];
+		vpu->fb_sz[1] = msg->data[1];
+		break;
+	default:
+		mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type);
+		vpu->failure = 1;
+		break;
+	}
+}
+
 /*
  * vpu_dec_ipi_handler - Handler for VPU ipi message.
  *
@@ -89,6 +111,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
+		case VPU_IPIMSG_DEC_GET_PARAM_ACK:
+			handle_get_param_msg_ack(data);
+			break;
 		default:
 			mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id);
 			break;
@@ -217,6 +242,32 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+	unsigned int len, unsigned int param_type)
+{
+	struct vdec_ap_ipi_get_param msg;
+	int i;
+	int err;
+
+	mtk_vcodec_debug_enter(vpu);
+
+	if (len > ARRAY_SIZE(msg.data)) {
+		mtk_vcodec_err(vpu, "invalid len = %d\n", len);
+		return -EINVAL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_id = AP_IPIMSG_DEC_GET_PARAM;
+	msg.inst_id = vpu->inst_id;
+	memcpy(msg.data, data, sizeof(unsigned int) * i);
+	msg.param_type = param_type;
+	msg.codec_type = vpu->codec_type;
+
+	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
+	mtk_vcodec_debug(vpu, "- ret=%d", err);
+	return err;
+}
+
 int vpu_dec_core(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 4cb3c7f5a3ad..963f8d4877b7 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -28,6 +28,8 @@ struct mtk_vcodec_ctx;
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
  * @codec_type     : use codec type to separate different codecs
+ * @capture_type    : used capture type to separate different capture format
+ * @fb_sz  : frame buffer size of each plane
  */
 struct vdec_vpu_inst {
 	int id;
@@ -42,6 +44,8 @@ struct vdec_vpu_inst {
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
 	unsigned int codec_type;
+	unsigned int capture_type;
+	unsigned int fb_sz[2];
 };
 
 /**
@@ -104,4 +108,15 @@ int vpu_dec_core(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_get_param - get param from scp
+ *
+ * @vpu : instance for vdec_vpu_inst
+ * @data: meta data to pass bitstream info to VPU decoder
+ * @len : meta data length
+ * @param_type : get param type
+ */
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+	unsigned int len, unsigned int param_type);
+
 #endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:35 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:35 +0800
Subject: [PATCH v3, 10/13] media: mtk-vcodec: Fix v4l2-compliance fail
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-11-yunfei.dong@mediatek.com>

Need to use default pic info when get pic info fail.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 34ee4a0092ff..75210eb829d0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -478,11 +478,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ctx->picinfo.pic_w = pix_mp->width;
 		ctx->picinfo.pic_h = pix_mp->height;
 
+		/*
+		 * If get pic info fail, need to use the default pic info params, or
+		 * v4l2-compliance will fail
+		 */
 		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
 		if (ret) {
 			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
 				     ctx->id);
-			return -EINVAL;
 		}
 
 		ctx->last_decoded_picinfo = ctx->picinfo;
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:31 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:31 +0800
Subject: [PATCH v3,
 06/13] media: mtk-vcodec: Refactor get and put capture buffer flow
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-7-yunfei.dong@mediatek.com>

For lat and core decode in parallel, need to get capture buffer
when core start to decode and put put capture buffer to display
list when core decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 123 ++++++++++++------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  16 ++-
 3 files changed, 104 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23a154c4e321..f3036c3f223b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -108,37 +108,89 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 
 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
 
-static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
-					       struct vdec_fb *fb)
+static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
+					   struct mtk_vcodec_mem *bs, int error)
 {
-	struct mtk_video_dec_buf *vdec_frame_buf =
-		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
-	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
-	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	struct mtk_video_dec_buf *out_buf;
+	struct vb2_v4l2_buffer *vb;
 
-	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
-	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		unsigned int cap_c_size =
-			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+	if (!bs) {
+		mtk_v4l2_err("Free bitstream buffer fail.");
+		return;
+	}
+	out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	vb = &out_buf->m2m_buf.vb;
+
+	mtk_v4l2_debug(2,
+		"Free bitsteam buffer id = %d to done_list",
+		vb->vb2_buf.index);
+
+	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+	if (error) {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		if (error == -EIO)
+			out_buf->error = true;
+	} else {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+	}
+}
 
-		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx,
+					   struct vdec_fb *fb, int error)
+{
+	struct mtk_video_dec_buf *vdec_frame_buf;
+	struct vb2_v4l2_buffer *vb;
+	unsigned int cap_y_size, cap_c_size;
+
+	if (!fb) {
+		mtk_v4l2_err("Free frame buffer fail.");
+		return;
 	}
+	vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf,
+				      frame_buffer);
+	vb = &vdec_frame_buf->m2m_buf.vb;
+
+	cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+
+	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+
+	mtk_v4l2_debug(2,
+		"Free frame buffer id = %d to done_list",
+		vb->vb2_buf.index);
+	if (error)
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+	else
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
 }
 
-static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
-					   struct vb2_v4l2_buffer *vb2_v4l2)
+static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
 {
-	struct mtk_video_dec_buf *framebuf =
-		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
-	struct vdec_fb *pfb = &framebuf->frame_buffer;
-	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+	struct mtk_video_dec_buf *framebuf;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vb2_buffer *dst_buf;
+	struct vdec_fb *pfb;
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2) {
+		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
+		return NULL;
+	}
 
-	pfb->base_y.va = NULL;
+	dst_buf = &vb2_v4l2->vb2_buf;
+	framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	pfb = &framebuf->frame_buffer;
+	pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
 	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
 	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
 
 	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		pfb->base_c.va = NULL;
+		pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
 		pfb->base_c.dma_addr =
 			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
 		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
@@ -162,12 +214,11 @@ static void mtk_vdec_worker(struct work_struct *work)
 	struct mtk_vcodec_ctx *ctx =
 		container_of(work, struct mtk_vcodec_ctx, decode_work);
 	struct mtk_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
+	struct vb2_v4l2_buffer *vb2_v4l2_src;
 	struct vb2_buffer *vb2_src;
 	struct mtk_vcodec_mem *bs_src;
 	struct mtk_video_dec_buf *dec_buf_src;
 	struct media_request *src_buf_req;
-	struct vdec_fb *dst_buf;
 	bool res_chg = false;
 	int ret;
 
@@ -178,13 +229,6 @@ static void mtk_vdec_worker(struct work_struct *work)
 		return;
 	}
 
-	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	if (!vb2_v4l2_dst) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
-		return;
-	}
-
 	vb2_src = &vb2_v4l2_src->vb2_buf;
 	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
 				   m2m_buf.vb);
@@ -193,9 +237,15 @@ static void mtk_vdec_worker(struct work_struct *work)
 	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
 		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
 
-	bs_src->va = NULL;
+	bs_src->va = vb2_plane_vaddr(vb2_src, 0);
 	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
 	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
+	if (!bs_src->va) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id,
+			vb2_src->index);
+		return;
+	}
 
 	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
 		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
@@ -206,9 +256,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 	else
 		mtk_v4l2_err("vb2 buffer media request is NULL");
 
-	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
-	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
-	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+	ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
 	if (ret) {
 		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
 			     ctx->id, vb2_src->index, bs_src->size,
@@ -220,12 +268,9 @@ static void mtk_vdec_worker(struct work_struct *work)
 		}
 	}
 
-	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
-
-	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
-					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
+	mtk_vdec_stateless_out_to_done(ctx, bs_src, ret);
 	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
 static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
@@ -358,6 +403,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = false,
 	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
@@ -376,6 +423,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = true,
 	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 2d7ec1e16423..5347d77300fa 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -360,7 +360,8 @@ enum mtk_vdec_hw_arch {
  * @ctrls_setup: init vcodec dec ctrls
  * @worker: worker to start a decode job
  * @flush_decoder: function that flushes the decoder
- *
+ * @get_cap_buffer: get capture buffer from capture queue
+ * @cap_to_disp: put capture buffer to disp list
  * @vdec_vb2_ops: struct vb2_ops
  *
  * @vdec_formats: supported video decoder formats
@@ -382,6 +383,8 @@ struct mtk_vcodec_dec_pdata {
 	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
 	void (*worker)(struct work_struct *work);
 	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
+	struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
+	void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, struct vdec_fb *fb, int error);
 
 	struct vb2_ops *vdec_vb2_ops;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 43542de11e9c..d00219a7587c 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -670,32 +670,42 @@ static void vdec_h264_slice_deinit(void *h_vdec)
 }
 
 static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
-				  struct vdec_fb *fb, bool *res_chg)
+				  struct vdec_fb *unused, bool *res_chg)
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
 		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	struct mtk_video_dec_buf *dst_buf_info;
+	struct vdec_fb *fb;
 	u32 data[2];
 	u64 y_fb_dma;
 	u64 c_fb_dma;
 	int err;
 
+	inst->num_nalu++;
 	/* bs NULL means flush decoder */
 	if (!bs)
 		return vpu_dec_reset(vpu);
 
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
 	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
 	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
 
 	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
-			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+			 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
 
 	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
 	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
 	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
 	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
 
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+		&dst_buf_info->m2m_buf.vb, true);
 	get_vdec_decode_parameters(inst);
 	data[0] = bs->size;
 	/*
@@ -734,6 +744,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
 	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
+
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, 0);
 	return 0;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:33 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:33 +0800
Subject: [PATCH v3, 08/13] media: mtk-vcodec: Add format to support MT21C
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-9-yunfei.dong@mediatek.com>

Needs to use mediatek compressed mode for mt8192 decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c   | 7 ++++++-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h         | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 01bb96f3b30e..21895fbed4c5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,7 +81,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_video_fmt mtk_video_formats[3];
 static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
 
 static struct mtk_video_fmt default_out_format;
@@ -361,6 +361,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 		num_framesizes++;
 		break;
 	case V4L2_PIX_FMT_MM21:
+	case V4L2_PIX_FMT_MT21C:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
 		mtk_video_formats[count_formats].num_planes = 2;
@@ -387,6 +388,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
 		cap_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx);
+		cap_format_count++;
+	}
 	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 4ae80d2e77d2..6c084a172e4b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -360,6 +360,7 @@ enum mtk_vdec_hw_arch {
  */
 enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:34 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:34 +0800
Subject: [PATCH v3, 09/13] media: mtk-vcodec: disable vp8 4K capability
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-10-yunfei.dong@mediatek.com>

For vp8 not support 4K, need to disable it.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 519f2b9d9b5b..34ee4a0092ff 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -532,7 +532,8 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
 		if (!(ctx->dev->dec_capability &
-				VCODEC_CAPABILITY_4K_DISABLED)) {
+				VCODEC_CAPABILITY_4K_DISABLED) &&
+				fsize->pixel_format != V4L2_PIX_FMT_VP8_FRAME) {
 			mtk_v4l2_debug(3, "4K is enabled");
 			fsize->stepwise.max_width =
 					VCODEC_DEC_4K_CODED_WIDTH;
-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:25 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:25 +0800
Subject: [PATCH v3, 00/13] media: mtk-vcodec: support for MT8192 decoder
Message-ID: <20220104080138.7472-1-yunfei.dong@mediatek.com>

This series adds support for mt8192 h264 decoder. Firstly, need to refactor
power/clock/interrupt interfaces for mt8192 is lat and core architecture.

Secondly, add new functions to get frame buffer size and resolution according
to decoder capability from scp side. Then add callback function to get/put
capture buffer in order to enable lat and core decoder in parallel. 

Then add to support MT21C compressed mode and fix v4l2-compliance fail.

Lastly, extract H264 request api driver to let mt8183 and mt8192 use the same
code, and adds mt8192 frame based h264 driver for stateless decoder.

Patches 1 refactor power/clock/interrupt interface.
Patches 2~4 get frame buffer size and resolution according to decoder capability.
Patches 5~6 enable lat and core decode in parallel.
Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail.
patch 11 record capture queue format type
Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder.
----
Dependents on "Support multi hardware decode using of_platform_populate"[1].

This patches are the second part used to add mt8192 h264 decoder. And the base part is [1].

[1]https://patchwork.linuxtv.org/project/linux-media/cover/20211215061552.8523-1-yunfei.dong at mediatek.com/
---
changes compared with v2:
- add new patch 11 to record capture queue format type.
- separate patch 4 according to tzung-bi's suggestion.
- re-write commit message for patch 5 according to tzung-bi's suggestion.
changes compared with v1:
- rewrite commit message for patch 12.
- rewrite cover-letter message.
---
Yunfei Dong (13):
  media: mtk-vcodec: Add vdec enable/disable hardware helpers
  media: mtk-vcodec: Using firmware type to separate different firmware
    architecture
  media: mtk-vcodec: get capture queue buffer size from scp
  media: mtk-vcodec: Read max resolution from dec_capability
  media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer
    buffered
  media: mtk-vcodec: Refactor get and put capture buffer flow
  media: mtk-vcodec: Refactor supported vdec formats and framesizes
  media: mtk-vcodec: Add format to support MT21C
  media: mtk-vcodec: disable vp8 4K capability
  media: mtk-vcodec: Fix v4l2-compliance fail
  media: mtk-vcodec: record capture queue format type
  media: mtk-vcodec: Extract H264 common code
  media: mtk-vcodec: Add h264 decoder driver for mt8192

 drivers/media/platform/mtk-vcodec/Makefile    |   2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |  49 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 168 +++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |   6 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  14 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 246 +++++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  27 +-
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |   6 +
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 303 +++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 247 +++++++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 402 +-----------
 .../mtk-vcodec/vdec/vdec_h264_req_lat_if.c    | 620 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  28 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  37 ++
 .../platform/mtk-vcodec/vdec_msg_queue.c      |   2 +
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  55 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  15 +
 include/linux/remoteproc/mtk_scp.h            |   2 +
 21 files changed, 1681 insertions(+), 555 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_lat_if.c

-- 
2.25.1



From yunfei.dong at mediatek.com  Tue Jan  4 00:01:26 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Tue, 4 Jan 2022 16:01:26 +0800
Subject: [PATCH v3,
 01/13] media: mtk-vcodec: Add vdec enable/disable hardware helpers
In-Reply-To: <20220104080138.7472-1-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
Message-ID: <20220104080138.7472-2-yunfei.dong@mediatek.com>

Lock, power and clock are highly coupled operations. Adds vdec
enable/disable hardware helpers and uses them.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 168 +++++++++++-------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |   6 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  20 +--
 .../platform/mtk-vcodec/vdec_msg_queue.c      |   2 +
 5 files changed, 117 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index d44894fa2f6e..fc3e272d2059 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -195,9 +195,6 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
-		if (ret < 0)
-			goto err_load_fw;
 		/*
 		 * Does nothing if firmware was already loaded.
 		 */
@@ -254,8 +251,6 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_dec_release(ctx);
 
-	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index b9f5ef979c69..c2ed79bce686 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -80,74 +80,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return -EINVAL;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int ret, i;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		enable_irq(subdev_dev->dec_irq);
-	} else {
-		pm = &vdec_dev->pm;
-		enable_irq(vdec_dev->dec_irq);
-	}
-
 	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
@@ -169,31 +126,120 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int i;
 
+	dec_clk = &pm->vdec_clk;
+	mtk_smi_larb_put(pm->larbvdec);
+	for (i = dec_clk->clk_num - 1; i >= 0; i--)
+		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+}
+
+static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+ {
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
 	if (vdec_dev->vdec_pdata->is_subdev_supported) {
 		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
+		if (subdev_dev)
+			enable_irq(subdev_dev->dec_irq);
+		else
+			mtk_v4l2_err("Failed to get hw dev\n");
+	} else {
+		enable_irq(vdec_dev->dec_irq);
+	}
+}
+
+static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			disable_irq(subdev_dev->dec_irq);
+		else
 			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		disable_irq(subdev_dev->dec_irq);
 	} else {
-		pm = &vdec_dev->pm;
 		disable_irq(vdec_dev->dec_irq);
 	}
+}
 
-	dec_clk = &pm->vdec_clk;
-	mtk_smi_larb_put(pm->larbvdec);
-	for (i = dec_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return NULL;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			return &subdev_dev->pm;
+
+		mtk_v4l2_err("Failed to get hw dev\n");
+		return NULL;
+	}
+
+	return &vdec_dev->pm;
+}
+
+static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_pw_on(pm);
+		mtk_vcodec_dec_clock_on(pm);
+	}
+}
+
+static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_clock_off(pm);
+		mtk_vcodec_dec_pw_off(pm);
+	}
+}
+
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
+
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+		hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
+	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
+
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+		hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_off(ctx->dev, MTK_VDEC_LAT0);
+
+	mutex_unlock(&ctx->dev->dec_mutex[hw_idx]);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_disable_hardware);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index c4121df9764f..b420739b373d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -12,9 +12,7 @@
 int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 05a5b240e906..c93dd0ea3537 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -38,11 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -70,15 +68,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 	if (!ctx->drv_handle)
 		return -EIO;
 
-	mtk_vdec_lock(ctx);
-
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
-
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -103,11 +97,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return;
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	ctx->drv_handle = NULL;
 }
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index 576e08200a10..900d04fd4e66 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -212,11 +212,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
 		return;
 
 	ctx = lat_buf->ctx;
+	mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
 	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
 
 	lat_buf->core_decode(lat_buf);
 
 	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
 	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
 
 	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
-- 
2.25.1



From wenst at chromium.org  Tue Jan  4 00:06:39 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 4 Jan 2022 16:06:39 +0800
Subject: [PATCH 2/2] clk: mediatek: clk-gate: Use regmap_{set/clear}_bits
 helpers
In-Reply-To: <20220103143712.46675-2-angelogioacchino.delregno@collabora.com>
References: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
 <20220103143712.46675-2-angelogioacchino.delregno@collabora.com>
Message-ID: <CAGXv+5FPG=cRmDzo5P7axHuV22RA0UNBJr3KtjZ5ThYw8XVB0g@mail.gmail.com>

On Mon, Jan 3, 2022 at 10:38 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Appropriately change calls to regmap_update_bits() with regmap_set_bits()
> and regmap_clear_bits() for improved readability.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From narmstrong at baylibre.com  Tue Jan  4 00:10:30 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 4 Jan 2022 09:10:30 +0100
Subject: [PATCH 0/3] ARM: ox810se: Add Ethernet support
In-Reply-To: <20220103200637.0b9d7e4f@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
 <20220103200637.0b9d7e4f@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <151bbcee-2f3b-4454-4244-523917cd4900@baylibre.com>

Hi,

On 04/01/2022 05:06, Jakub Kicinski wrote:
> On Mon,  3 Jan 2022 18:56:35 +0100 Neil Armstrong wrote:
>> This adds support for the Synopsys DWMAC controller found in the
>> OX820SE SoC, by using almost the same glue code as the OX820.
>>
>> Neil Armstrong (3):
>>   dt-bindings: net: oxnas-dwmac: Add bindings for OX810SE
>>   net: stmmac: dwmac-oxnas: Add support for OX810SE
>>   ARM: dts: ox810se: Add Ethernet support
> 
> Judging by the subject tag on patches 1 and 2 and To: I presume you
> intend this series to be merged via net-next? Can you please repost
> with patch 3 CCed to netdev as well? It didn't register in patchwork.

It was on purpose, I planned to push the DT through arm-soc, sorry it wasn't
explicit in the cover letter.

Neil


From narmstrong at baylibre.com  Tue Jan  4 00:11:55 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 09:11:55 +0100
Subject: [PATCH 3/3] ARM: dts: ox810se: Add Ethernet support
In-Reply-To: <20220103175638.89625-1-narmstrong@baylibre.com>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
Message-ID: <20220104081155.91120-1-narmstrong@baylibre.com>

Add nodes for the embedded Synopsys DWMAC Ethernet controller.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 arch/arm/boot/dts/ox810se-wd-mbwe.dts |  4 ++++
 arch/arm/boot/dts/ox810se.dtsi        | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/ox810se-wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
index 7e2fcb220aea..c59e06ff2423 100644
--- a/arch/arm/boot/dts/ox810se-wd-mbwe.dts
+++ b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
@@ -103,6 +103,10 @@ rtc0: rtc at 48 {
 	};
 };
 
+&etha {
+	status = "okay";
+};
+
 &uart1 {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/ox810se.dtsi b/arch/arm/boot/dts/ox810se.dtsi
index 0755e5864c4a..96c0745f7b70 100644
--- a/arch/arm/boot/dts/ox810se.dtsi
+++ b/arch/arm/boot/dts/ox810se.dtsi
@@ -81,6 +81,24 @@ soc {
 		ranges;
 		interrupt-parent = <&intc>;
 
+		etha: ethernet at 40400000 {
+			compatible = "oxsemi,ox810se-dwmac", "snps,dwmac";
+			reg = <0x40400000 0x2000>;
+			interrupts = <8>;
+			interrupt-names = "macirq";
+			mac-address = [000000000000]; /* Filled in by U-Boot */
+			phy-mode = "rgmii";
+
+			clocks = <&stdclk 6>, <&gmacclk>;
+			clock-names = "gmac", "stmmaceth";
+			resets = <&reset 6>;
+
+			/* Regmap for sys registers */
+			oxsemi,sys-ctrl = <&sys>;
+
+			status = "disabled";
+		};
+
 		apb-bridge at 44000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.25.1



From yu.tu at amlogic.com  Tue Jan  4 00:20:33 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 16:20:33 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <CAFBinCCL-QaeSRCLzfyNXcRQZ7YC1D85rP2y4OGkAjCmQEqGgQ@mail.gmail.com>
 <3e1e40aa-7865-0f7a-5772-e2ad96c8141d@amlogic.com>
 <CAFBinCB2nF0TwRE1uJ4UTB_avcqRBfOHR1CDSe29dB1o-YjEHQ@mail.gmail.com>
 <7278bace-a2b9-0cfc-55b3-c19311e3352e@amlogic.com>
 <CAFBinCCwE1DbP+Y49o3WxNdeE11ZK=HcGbXa0Sq52tch+eNhrQ@mail.gmail.com>
Message-ID: <1f16f430-677e-d1f0-1a7f-bf1d1a7c3c47@amlogic.com>

Hi Martin,
	Thank you very much for your reply.
On 2022/1/3 3:36, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On Sat, Jan 1, 2022 at 2:30 PM Yu Tu <yu.tu at amlogic.com> wrote:
> [...]
>>> Interesting, thanks for sharing that u-boot turns these clocks on.
>>> Let's say someone wanted to make u-boot save power and turn off all
>>> UART clocks except the one for uart_AO (where we typically connect the
>>> serial console).
>>> In that case the pclk of uart_C (just to choose an example here) is
>>> turned off. Would there be a problem then accessing the registers of
>>> uart_C before clk_prepare_enable is called?
>> The way you describe it, it does hang. This would not be recommended on
>> actual projects.
>>
>> At present, AmLogic chips are older than S4 Soc, and we have no way to
>> deal with this problem. We have to tell customers not to use it in this
>> way?Customers rarely use it in real projects.On the S4 SOC we will use
>> a clock like the UART pclk to control the shutdown using two registers,
>> one safe (need to operate in EL3) and one normal (EL1). It will only be
>> closed if both registers are closed. This mainly prevents misoperation.
> oh, interesting that there's some updates specifically with the S4 SoCs :-)
> 
>> With your experience, I'd like to know how you deal with this kind of
>> problem.
> Before this patch the driver simply turns on the clock from within
> meson_uart_probe() (specifically it does so in
> meson_uart_probe_clock()).
> I think there's advanced power-saving techniques. Maybe for now we
> keep it simple and just enable the clock(s) at probe time and disable
> them at driver remove time. What do you think?
> 
I agree with you.
> 
> Best regards,
> Martin
> 


From narmstrong at baylibre.com  Tue Jan  4 00:42:21 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 4 Jan 2022 09:42:21 +0100
Subject: [PATCH net-next 2/3] net: stmmac: dwmac-oxnas: Add support for
 OX810SE
In-Reply-To: <20220103175638.89625-3-narmstrong@baylibre.com>
References: <20220103175638.89625-1-narmstrong@baylibre.com>
 <20220103175638.89625-3-narmstrong@baylibre.com>
Message-ID: <4a0ea0f1-9cc5-a242-75af-ed4bd0537b16@baylibre.com>

On 03/01/2022 18:56, Neil Armstrong wrote:
> Add support for OX810SE dwmac glue setup, which is a simplified version
> of the OX820 introduced later with more control on the PHY interface.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 92 ++++++++++++++-----
>  1 file changed, 70 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
> index adfeb8d3293d..7ffa4a4eb30f 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
> @@ -12,6 +12,7 @@
>  #include <linux/io.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/regmap.h>
>  #include <linux/mfd/syscon.h>
> @@ -48,12 +49,58 @@
>  #define DWMAC_RX_VARDELAY(d)		((d) << DWMAC_RX_VARDELAY_SHIFT)
>  #define DWMAC_RXN_VARDELAY(d)		((d) << DWMAC_RXN_VARDELAY_SHIFT)
>  
> +struct oxnas_dwmac;
> +
> +struct oxnas_dwmac_data {
> +	void (*setup)(struct oxnas_dwmac *dwmac);
> +};
> +
>  struct oxnas_dwmac {
>  	struct device	*dev;
>  	struct clk	*clk;
>  	struct regmap	*regmap;
> +	const struct oxnas_dwmac_data	*data;
>  };
>  
> +static void oxnas_dwmac_setup_ox810se(struct oxnas_dwmac *dwmac)
> +{
> +	unsigned int value;
> +
> +	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
> +	value = BIT(DWMAC_CKEN_GTX)		|
> +		 /* Use simple mux for 25/125 Mhz clock switching */
> +		 BIT(DWMAC_SIMPLE_MUX);
> +
> +	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
> +}
> +
> +static void oxnas_dwmac_setup_ox820(struct oxnas_dwmac *dwmac)
> +{
> +	unsigned int value;
> +
> +	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
> +	value = BIT(DWMAC_CKEN_GTX)		|
> +		 /* Use simple mux for 25/125 Mhz clock switching */
> +		BIT(DWMAC_SIMPLE_MUX)		|
> +		/* set auto switch tx clock source */
> +		BIT(DWMAC_AUTO_TX_SOURCE)	|
> +		/* enable tx & rx vardelay */
> +		BIT(DWMAC_CKEN_TX_OUT)		|
> +		BIT(DWMAC_CKEN_TXN_OUT)	|
> +		BIT(DWMAC_CKEN_TX_IN)		|
> +		BIT(DWMAC_CKEN_RX_OUT)		|
> +		BIT(DWMAC_CKEN_RXN_OUT)	|
> +		BIT(DWMAC_CKEN_RX_IN);
> +	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
> +
> +	/* set tx & rx vardelay */
> +	value = DWMAC_TX_VARDELAY(4)	|
> +		DWMAC_TXN_VARDELAY(2)	|
> +		DWMAC_RX_VARDELAY(10)	|
> +		DWMAC_RXN_VARDELAY(8);
> +	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
> +}
> +
>  static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
>  {
>  	struct oxnas_dwmac *dwmac = priv;
> @@ -75,27 +122,7 @@ static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
>  		return ret;
>  	}

There's an issue with the patch, the value read from register is not used, I'll send a V2 with the fix.

Neil

>  
> -	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
> -	value |= BIT(DWMAC_CKEN_GTX)		|
> -		 /* Use simple mux for 25/125 Mhz clock switching */
> -		 BIT(DWMAC_SIMPLE_MUX)		|
> -		 /* set auto switch tx clock source */
> -		 BIT(DWMAC_AUTO_TX_SOURCE)	|
> -		 /* enable tx & rx vardelay */
> -		 BIT(DWMAC_CKEN_TX_OUT)		|
> -		 BIT(DWMAC_CKEN_TXN_OUT)	|
> -		 BIT(DWMAC_CKEN_TX_IN)		|
> -		 BIT(DWMAC_CKEN_RX_OUT)		|
> -		 BIT(DWMAC_CKEN_RXN_OUT)	|
> -		 BIT(DWMAC_CKEN_RX_IN);
> -	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
> -
> -	/* set tx & rx vardelay */
> -	value = DWMAC_TX_VARDELAY(4)	|
> -		DWMAC_TXN_VARDELAY(2)	|
> -		DWMAC_RX_VARDELAY(10)	|
> -		DWMAC_RXN_VARDELAY(8);
> -	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
> +	dwmac->data->setup(dwmac);
>  
>  	return 0;
>  }
> @@ -128,6 +155,12 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
>  		goto err_remove_config_dt;
>  	}
>  
> +	dwmac->data = (const struct oxnas_dwmac_data *)of_device_get_match_data(&pdev->dev);
> +	if (!dwmac->data) {
> +		ret = -EINVAL;
> +		goto err_remove_config_dt;
> +	}
> +
>  	dwmac->dev = &pdev->dev;
>  	plat_dat->bsp_priv = dwmac;
>  	plat_dat->init = oxnas_dwmac_init;
> @@ -166,8 +199,23 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
>  	return ret;
>  }
>  
> +static const struct oxnas_dwmac_data ox810se_dwmac_data = {
> +	.setup = oxnas_dwmac_setup_ox810se,
> +};
> +
> +static const struct oxnas_dwmac_data ox820_dwmac_data = {
> +	.setup = oxnas_dwmac_setup_ox820,
> +};
> +
>  static const struct of_device_id oxnas_dwmac_match[] = {
> -	{ .compatible = "oxsemi,ox820-dwmac" },
> +	{
> +		.compatible = "oxsemi,ox810se-dwmac",
> +		.data = &ox810se_dwmac_data,
> +	},
> +	{
> +		.compatible = "oxsemi,ox820-dwmac",
> +		.data = &ox820_dwmac_data,
> +	},
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);
> 



From Claudiu.Beznea at microchip.com  Tue Jan  4 00:42:58 2022
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Tue, 4 Jan 2022 08:42:58 +0000
Subject: [PATCH] ARM: dts: at91: sama7g5: fix compilation warning
In-Reply-To: <20211220082058.21687-1-claudiu.beznea@microchip.com>
References: <20211220082058.21687-1-claudiu.beznea@microchip.com>
Message-ID: <158f6ea1-b903-9bb0-33e4-468940c01f13@microchip.com>

Hi Nicolas,

Please ignore this as it seems it is already integrated on at91-next.

Thank you,
Claudiu Beznea

On 20.12.2021 10:20, Claudiu Beznea wrote:
> Fix the following compilation warning:
> "Warning (unit_address_vs_reg): /memory: node has a reg or ranges
> property, but no unit name".
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---
>  arch/arm/boot/dts/sama7g5.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
> index 8961d2851df3..cc75d0593729 100644
> --- a/arch/arm/boot/dts/sama7g5.dtsi
> +++ b/arch/arm/boot/dts/sama7g5.dtsi
> @@ -108,7 +108,7 @@ map1 {
>  	};
>  
>  	/* 512 M */
> -	memory {
> +	memory at 60000000 {
>  		device_type = "memory";
>  		reg = <0x60000000 0x20000000>;
>  	};


From angelogioacchino.delregno at collabora.com  Tue Jan  4 00:43:24 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 09:43:24 +0100
Subject: [PATCH 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220103075854.10438-2-allen-kh.cheng@mediatek.com>
References: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>
 <20220103075854.10438-2-allen-kh.cheng@mediatek.com>
Message-ID: <39f95db9-9d52-e64c-7444-ccd8d88cc522@collabora.com>

Il 03/01/22 08:58, allen-kh.cheng ha scritto:
> Add SCP support for mt8186
> 
> Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>

Hello! Thanks for the patch!
However, there's something to improve...

> ---
>   drivers/remoteproc/mtk_scp.c | 39 ++++++++++++++++++++++++++++++++++++
>   1 file changed, 39 insertions(+)
> 
> diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
> index 36e48cf58ed6..38eab6b86fd7 100644
> --- a/drivers/remoteproc/mtk_scp.c
> +++ b/drivers/remoteproc/mtk_scp.c
> @@ -365,6 +365,31 @@ static int mt8183_scp_before_load(struct mtk_scp *scp)
>   	return 0;
>   }
>   
> +static int mt8186_scp_before_load(struct mtk_scp *scp)
> +{
> +	int i;
> +
> +	/* Clear SCP to host interrupt */
> +	writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
> +
> +	/* Reset clocks before loading FW */
> +	writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
> +	writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
> +

.............

> +	/* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
> +	for (i = 31; i >= 0; i--)
> +		writel(GENMASK(i, 0), scp->reg_base + MT8183_SCP_SRAM_PDN);
> +	writel(0, scp->reg_base + MT8183_SCP_SRAM_PDN);
> +

.............

This snippet corresponds exactly to the mt8192_power_on_sram() helper:
please avoid code duplication by simply calling that function instead.

Thanks,
- Angelo


From angelogioacchino.delregno at collabora.com  Tue Jan  4 00:43:27 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 09:43:27 +0100
Subject: [PATCH 1/2] dt-bindings: remoteproc: mediatek: Add binding for
 mt8186 scp
In-Reply-To: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>
References: <20220103075854.10438-1-allen-kh.cheng@mediatek.com>
Message-ID: <1e729a4f-8cc1-7f7f-eddb-fc7ba1df7f32@collabora.com>

Il 03/01/22 08:58, allen-kh.cheng ha scritto:
> Add mt8186 compatible to binding document.
> 
> Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
> ---
>   Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> index d21a25ee96e6..5b693a2d049c 100644
> --- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
> @@ -17,6 +17,7 @@ properties:
>     compatible:
>       enum:
>         - mediatek,mt8183-scp
> +      - mediatek,mt8186-scp
>         - mediatek,mt8192-scp
>         - mediatek,mt8195-scp
>   
> 

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From jianhua.ljh at gmail.com  Tue Jan  4 00:49:29 2022
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Tue, 4 Jan 2022 16:49:29 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
Message-ID: <CAAgTQPUL-DPTD2-sPQzYB+Eoko7aw40-bhyE_9Kjd90qowQBfw@mail.gmail.com>

On Tue, Jan 4, 2022 at 10:36 AM Masami Hiramatsu <mhiramat at kernel.org> wrote:
>
> Hi Jianhua,
>
> On Mon, 3 Jan 2022 17:03:33 +0800
> Jianhua Liu <jianhua.ljh at gmail.com> wrote:
>
> > Hi Qi,
> > I have tested your patch on UNISOC s9863a.
> > Test case "kprobe_example & kretprobe_example" is OK.
> >
> > Two point:
> > 1. backtrace is not perfect.
> >    optprobe_common does not saved frame pointer,
> >    backtrace lacks two calls.
> > such as for dup_mm: lack copy_process-->dup_mm
> > dup_mm backtrace from your patch:
> > [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
> > [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> > [  832.387083] Call trace:
> > [  832.387086]  dump_backtrace+0x0/0x1e0
> > [  832.387103]  show_stack+0x24/0x30
> > [  832.387112]  dump_stack_lvl+0x68/0x84
> > [  832.387123]  dump_stack+0x18/0x34
> > [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
> > [  832.387143]  opt_pre_handler+0x84/0xc0
> > [  832.387154]  optprobe_optimized_callback+0xec/0x164
> > [  832.387164]  optprobe_common+0x70/0xc4
> > [  832.387173]  kernel_clone+0x98/0x440
> > [  832.387182]  __do_sys_clone+0x54/0x80
> > [  832.387191]  __arm64_sys_clone+0x2c/0x40
> > [  832.387199]  invoke_syscall+0x50/0x120
> > [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
> > [  832.387217]  do_el0_svc+0x30/0x9c
> > [  832.387225]  el0_svc+0x20/0x60
> > [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
> > [  832.387242]  el0t_64_sync+0x1a0/0x1a4
> >
> >
> > dup_mm backtrace from other:
> > [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
> > [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> > [  173.352304] Call trace:
> > [  173.352307]  dump_backtrace+0x0/0x1d4
> > [  173.352319]  show_stack+0x18/0x24
> > [  173.352326]  dump_stack_lvl+0x68/0x84
> > [  173.352333]  dump_stack+0x18/0x34
> > [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
> > [  173.352347]  opt_pre_handler+0x74/0xb0
> > [  173.352354]  optimized_callback+0x108/0x130
> > [  173.352361]  optinsn_slot+0x258/0x1000
> > [  173.352366]  dup_mm+0x4/0x4b0
> > [  173.352373]  copy_process+0x1284/0x1360
> > [  173.352378]  kernel_clone+0x5c/0x3c0
> > [  173.352384]  __do_sys_clone+0x54/0x80
> > [  173.352390]  __arm64_sys_clone+0x24/0x30
> > [  173.352396]  invoke_syscall+0x48/0x114
> > [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
> > [  173.352408]  do_el0_svc+0x24/0x90
> > [  173.352413]  el0_svc+0x20/0x60
> > [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
> > [  173.352427]  el0t_64_sync+0x1a0/0x1a4
>
> Is the second one with your patch?
Yes, the second one is from my patch.

Thanks,
Jianhua

>
> >
> > 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
> >    kernel/kprobe.c used only one PAGE_SIZE slot memory.
>
> Good catch!
> Qi, can you make an array (or bit map) of usage flags and
> manage the reserved memory?
>
> #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
> static bool insn_page_in_use[OPT_INSN_PAGES];
>
> void *alloc_optinsn_page(void)
> {
>         int i;
>
>         for (i = 0; i < OPT_INSN_PAGES; i++)
>                 if (!insn_page_in_use[i])
>                         goto found;
>         return NULL;
> found:
>         insn_page_in_use[i] = true;
>         return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
> }
>
> void free_optinsn_page(void *page)
> {
>         unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
>
>         WARN_ONCE(idx & (PAGE_SIZE - 1));
>         idx >>= PAGE_SHIFT;
>         if (WARN_ONCE(idx >= OPT_INSN_PAGES))
>                 return;
>         insn_page_in_use[idx] = false;
> }
>
> Thank you,
>
>
>
>
> --
> Masami Hiramatsu <mhiramat at kernel.org>


From gankulkarni at os.amperecomputing.com  Tue Jan  4 00:53:42 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 4 Jan 2022 14:23:42 +0530
Subject: [PATCH v5 34/69] KVM: arm64: nv: Configure HCR_EL2 for nested
 virtualization
In-Reply-To: <20211129200150.351436-35-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-35-maz@kernel.org>
Message-ID: <bbf31da5-ca1b-7499-e23c-9b5281ca7901@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> We enable nested virtualization by setting the HCR NV and NV1 bit.
> 
> When the virtual E2H bit is set, we can support EL2 register accesses
> via EL1 registers from the virtual EL2 by doing trap-and-emulate. A
> better alternative, however, is to allow the virtual EL2 to access EL2
> register states without trap. This can be easily achieved by not traping
> EL1 registers since those registers already have EL2 register states.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_arm.h |  1 +
>   arch/arm64/kvm/hyp/vhe/switch.c  | 38 +++++++++++++++++++++++++++++---
>   2 files changed, 36 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 68af5509e4b0..b8a0d410035b 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -87,6 +87,7 @@
>   			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
>   			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
>   			 HCR_FMO | HCR_IMO | HCR_PTW )
> +#define HCR_GUEST_NV_FILTER_FLAGS (HCR_ATA | HCR_API | HCR_APK | HCR_RW)
>   #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
>   #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
>   #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index 57f43e607819..da80c969e623 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -36,9 +36,41 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>   	u64 hcr = vcpu->arch.hcr_el2;
>   	u64 val;
>   
> -	/* Trap VM sysreg accesses if an EL2 guest is not using VHE. */
> -	if (vcpu_mode_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
> -		hcr |= HCR_TVM | HCR_TRVM;
> +	if (is_hyp_ctxt(vcpu)) {
> +		hcr |= HCR_NV;
> +
> +		if (!vcpu_el2_e2h_is_set(vcpu)) {
> +			/*
> +			 * For a guest hypervisor on v8.0, trap and emulate
> +			 * the EL1 virtual memory control register accesses.
> +			 */
> +			hcr |= HCR_TVM | HCR_TRVM | HCR_NV1;
> +		} else {
> +			/*
> +			 * For a guest hypervisor on v8.1 (VHE), allow to
> +			 * access the EL1 virtual memory control registers
> +			 * natively. These accesses are to access EL2 register
> +			 * states.
> +			 * Note that we still need to respect the virtual
> +			 * HCR_EL2 state.
> +			 */
> +			u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
> +
> +			vhcr_el2 &= ~HCR_GUEST_NV_FILTER_FLAGS;

Why HCR_RW is cleared here, May I know please?

> +
> +			/*
> +			 * We already set TVM to handle set/way cache maint
> +			 * ops traps, this somewhat collides with the nested
> +			 * virt trapping for nVHE. So turn this off for now
> +			 * here, in the hope that VHE guests won't ever do this.
> +			 * TODO: find out whether it's worth to support both
> +			 * cases at the same time.
> +			 */
> +			hcr &= ~HCR_TVM;
> +
> +			hcr |= vhcr_el2 & (HCR_TVM | HCR_TRVM);
> +		}
> +	}
>   
>   	___activate_traps(vcpu, hcr);
>   

Thanks,
Ganapat



From guangming.cao at mediatek.com  Tue Jan  4 00:44:45 2022
From: guangming.cao at mediatek.com (Guangming.Cao)
Date: Tue, 4 Jan 2022 16:44:45 +0800
Subject: [PATCH v2] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>
References: <20211217094104.24977-1-guangming.cao@mediatek.com>
 <20211227095102.6054-1-guangming.cao@mediatek.com>
 <CALAqxLVA4jUk-2o28RZobrPDUnuXfV1xN77Pt8Pu1o27V3aUQQ@mail.gmail.com>
 <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>
Message-ID: <ae7c424a02b5b0ef30239ca65bd58086f13bc42b.camel@mediatek.com>

On Tue, 2022-01-04 at 08:47 +0100, Christian K?nig wrote:
> Am 03.01.22 um 19:57 schrieb John Stultz:
> > On Mon, Dec 27, 2021 at 1:52 AM <guangming.cao at mediatek.com> wrote:
> > > From: Guangming <Guangming.Cao at mediatek.com>
> > > 
> > 
> > Thanks for submitting this!
> > 
> > > Add a size check for allcation since the allocation size is
> > 
> > nit: "allocation" above.
> > 
> > > always less than the total DRAM size.
> > 
> > In general, it might be good to add more context to the commit
> > message
> > to better answer *why* this change is needed rather than what the
> > change is doing.  ie: What negative thing happens without this
> > change?
> > And so how does this change avoid or improve things?
> 
> Completely agree, just one little addition: Could you also add this
> why 
> as comment to the code?
> 
> When we stumble over this five years from now it is absolutely not 
> obvious why we do this.
Thanks for your reply!
I will update the related reason in the patch later.

The reason for adding this check is that we met a case that the user
sent an invalid size(It seems it's a negative value, MSB is 0xff, it's
larger than DRAM size after convert it to size_t) to dma-heap to alloc
memory, and this allocation was running on a process(such as "gralloc"
on Android device) can't be killed by OOM flow, and we also couldn't
find the related dmabuf in "dma_buf_debug_show" because the related
dmabuf was not exported yet since the allocation is still on going.

Since this invalid argument case can be prevented at dma-heap side, so,
I added this size check, and moreover, to let debug it easily, I also
added logs when size is bigger than a threshold we set in mtk system
heap.
If you think that print logs in dma-heap framework is better, I will
update it in next version.

If you have better solution(such as dump the size under allocating
in "dma_buf_debug_show", which maybe need add global variable to record
it), please kindly let me know, thanks :)

> 
> Thanks,
> Christian.
> 
> > 
> > 
> > > Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> > > Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
> > > ---
> > > v2: 1. update size limitation as total_dram page size.
> > >      2. update commit message
> > > ---
> > >   drivers/dma-buf/dma-heap.c | 2 ++
> > >   1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-
> > > heap.c
> > > index 56bf5ad01ad5..e39d2be98d69 100644
> > > --- a/drivers/dma-buf/dma-heap.c
> > > +++ b/drivers/dma-buf/dma-heap.c
> > > @@ -55,6 +55,8 @@ static int dma_heap_buffer_alloc(struct
> > > dma_heap *heap, size_t len,
> > >          struct dma_buf *dmabuf;
> > >          int fd;
> > > 
> > > +       if (len / PAGE_SIZE > totalram_pages())
> > > +               return -EINVAL;
> > 
> > This seems sane. I know ION used to have some 1/2 of memory cap to
> > avoid unnecessary memory pressure on crazy allocations.
> > 
> > Could you send again with an improved commit message?
> > 
> > thanks
> > -john
> 
> 

From linux at armlinux.org.uk  Tue Jan  4 01:00:57 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 09:00:57 +0000
Subject: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <CAFcVEC+N0Y7ESFe-qcfpmkbPjRSvCJ=AOXoM6XSK6xGo=J1YNw@mail.gmail.com>
References: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
 <E1mxqBh-00GWxo-51@rmk-PC.armlinux.org.uk>
 <20211216071513.6d1e0f55@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
 <YbtxGLrXoR9oHRmM@shell.armlinux.org.uk>
 <CAFcVECJeRwgjGsxtcGpMuA23nnmywsNkA2Yngk6aDK_JuVE3NQ@mail.gmail.com>
 <CAFcVEC+N0Y7ESFe-qcfpmkbPjRSvCJ=AOXoM6XSK6xGo=J1YNw@mail.gmail.com>
Message-ID: <YdQMyfYU0wxHrT40@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 01:26:28PM +0530, Harini Katakam wrote:
> On Fri, Dec 17, 2021 at 1:55 PM Harini Katakam <harinik at xilinx.com> wrote:
> >
> > Hi Russell,
> >
> > On Fri, Dec 17, 2021 at 5:26 AM Russell King (Oracle)
> > <linux at armlinux.org.uk> wrote:
> > >
> > > On Thu, Dec 16, 2021 at 07:15:13AM -0800, Jakub Kicinski wrote:
> > > > On Thu, 16 Dec 2021 12:48:45 +0000 Russell King (Oracle) wrote:
> > > > > Convert axienet to use the phylink_pcs layer, resulting in it no longer
> > > > > being a legacy driver.
> > > > >
> > > > > One oddity in this driver is that lp->switch_x_sgmii controls whether
> > > > > we support switching between SGMII and 1000baseX. However, when clear,
> > > > > this also blocks updating the 1000baseX advertisement, which it
> > > > > probably should not be doing. Nevertheless, this behaviour is preserved
> > > > > but a comment is added.
> > > > >
> > > > > Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> > > >
> > > > drivers/net/ethernet/xilinx/xilinx_axienet.h:479: warning: Function parameter or member 'pcs' not described in 'axienet_local'
> > >
> > > Fixed that and the sha1 issue you raised in patch 2. Since both are
> > > "documentation" issues, I won't send out replacement patches until
> > > I've heard they've been tested on hardware though.
> >
> > Thanks for the patches.
> > Series looks good and we're testing at our end; will get back to you
> > early next week.
> 
> Thanks Russell. I've tested AXI Ethernet and it works fine.

Happy new year!

Thanks - can I use that as a tested-by please, and would you be happy
for me to send the patches for merging this week?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:05:15 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 10:05:15 +0100
Subject: [PATCH 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186 SoC
In-Reply-To: <20211230114913.9829-2-johnson.wang@mediatek.com>
References: <20211230114913.9829-1-johnson.wang@mediatek.com>
 <20211230114913.9829-2-johnson.wang@mediatek.com>
Message-ID: <3dd41039-0151-4ee0-3940-3aceeaff17d1@collabora.com>

Il 30/12/21 12:49, Johnson Wang ha scritto:
> MT8186 are highly integrated SoC and use PMIC_MT6366 for
> power management. This patch adds pwrap master driver to
> access PMIC_MT6366.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>

Hello Johnson,
thanks for the patch!

However, there's something to improve...

> ---
>   drivers/soc/mediatek/mtk-pmic-wrap.c | 86 ++++++++++++++++++++++++++--
>   1 file changed, 80 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
> index 952bc554f443..4af713274468 100644
> --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> @@ -30,6 +30,7 @@
>   #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) & 0x00000001)
>   #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
>   #define PWRAP_STATE_INIT_DONE0		BIT(21)
> +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
>   #define PWRAP_STATE_INIT_DONE1		BIT(15)
>   
>   /* macro for WACS FSM */
> @@ -77,6 +78,8 @@
>   #define PWRAP_CAP_INT1_EN	BIT(3)
>   #define PWRAP_CAP_WDT_SRC1	BIT(4)
>   #define PWRAP_CAP_ARB		BIT(5)
> +#define PWRAP_CAP_MONITOR_V2	BIT(6)
> +#define PWRAP_CAP_ARB_V2	BIT(8)
>   
>   /* defines for slave device wrapper registers */
>   enum dew_regs {
> @@ -1063,6 +1066,55 @@ static int mt8516_regs[] = {
>   	[PWRAP_MSB_FIRST] =		0x170,
>   };
>   
> +static int mt8186_regs[] = {
> +	[PWRAP_MUX_SEL] =		0x0,
> +	[PWRAP_WRAP_EN] =		0x4,
> +	[PWRAP_DIO_EN] =		0x8,
> +	[PWRAP_RDDMY] =			0x20,
> +	[PWRAP_CSHEXT_WRITE] =		0x24,
> +	[PWRAP_CSHEXT_READ] =		0x28,
> +	[PWRAP_CSLEXT_WRITE] =		0x2C,
> +	[PWRAP_CSLEXT_READ] =		0x30,
> +	[PWRAP_EXT_CK_WRITE] =		0x34,
> +	[PWRAP_STAUPD_CTRL] =		0x3C,
> +	[PWRAP_STAUPD_GRPEN] =		0x40,
> +	[PWRAP_EINT_STA0_ADR] =		0x44,
> +	[PWRAP_EINT_STA1_ADR] =		0x48,
> +	[PWRAP_INT_CLR] =		0xC8,
> +	[PWRAP_INT_FLG] =		0xC4,
> +	[PWRAP_MAN_EN] =		0x7C,
> +	[PWRAP_MAN_CMD] =		0x80,
> +	[PWRAP_WACS0_EN] =		0x8C,
> +	[PWRAP_WACS1_EN] =		0x94,
> +	[PWRAP_WACS2_EN] =		0x9C,
> +	[PWRAP_INIT_DONE0] =		0x90,
> +	[PWRAP_INIT_DONE1] =		0x98,
> +	[PWRAP_INIT_DONE2] =		0xA0,
> +	[PWRAP_INT_EN] =		0xBC,
> +	[PWRAP_INT1_EN] =		0xCC,
> +	[PWRAP_INT1_FLG] =		0xD4,
> +	[PWRAP_INT1_CLR] =		0xD8,
> +	[PWRAP_TIMER_EN] =		0xF0,
> +	[PWRAP_WDT_UNIT] =		0xF8,
> +	[PWRAP_WDT_SRC_EN] =		0xFC,
> +	[PWRAP_WDT_SRC_EN_1] =		0x100,
> +	[PWRAP_WDT_FLG] =		0x104,
> +	[PWRAP_SPMINF_STA] =		0x1B4,
> +	[PWRAP_DCM_EN] =		0x1EC,
> +	[PWRAP_DCM_DBC_PRD] =		0x1F0,
> +	[PWRAP_GPSINF_0_STA] =		0x204,
> +	[PWRAP_GPSINF_1_STA] =		0x208,
> +	[PWRAP_WACS0_CMD] =		0xC00,
> +	[PWRAP_WACS0_RDATA] =		0xC04,
> +	[PWRAP_WACS0_VLDCLR] =		0xC08,
> +	[PWRAP_WACS1_CMD] =		0xC10,
> +	[PWRAP_WACS1_RDATA] =		0xC14,
> +	[PWRAP_WACS1_VLDCLR] =		0xC18,
> +	[PWRAP_WACS2_CMD] =		0xC20,
> +	[PWRAP_WACS2_RDATA] =		0xC24,
> +	[PWRAP_WACS2_VLDCLR] =		0xC28,
> +};
> +
>   enum pmic_type {
>   	PMIC_MT6323,
>   	PMIC_MT6351,
> @@ -1083,6 +1135,7 @@ enum pwrap_type {
>   	PWRAP_MT8135,
>   	PWRAP_MT8173,
>   	PWRAP_MT8183,
> +	PWRAP_MT8186,
>   	PWRAP_MT8195,
>   	PWRAP_MT8516,
>   };
> @@ -1535,6 +1588,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
>   	case PWRAP_MT6779:
>   	case PWRAP_MT6797:
>   	case PWRAP_MT8173:
> +	case PWRAP_MT8186:
>   	case PWRAP_MT8516:
>   		pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
>   		break;
> @@ -2069,6 +2123,19 @@ static struct pmic_wrapper_type pwrap_mt8516 = {
>   	.init_soc_specific = NULL,
>   };
>   
> +static struct pmic_wrapper_type pwrap_mt8186 = {
> +	.regs = mt8186_regs,
> +	.type = PWRAP_MT8186,
> +	.arb_en_all = 0xfb27f,
> +	.int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1 */
> +	.int1_en_all =  0x000017ff, /* disable Matching interrupt for bit 13 */
> +	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
> +	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
> +	.caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_MONITOR_V2 | PWRAP_CAP_ARB_V2,
> +	.init_reg_clock = pwrap_common_init_reg_clock,
> +	.init_soc_specific = NULL,
> +};
> +
>   static const struct of_device_id of_pwrap_match_tbl[] = {
>   	{
>   		.compatible = "mediatek,mt2701-pwrap",
> @@ -2097,6 +2164,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
>   	}, {
>   		.compatible = "mediatek,mt8183-pwrap",
>   		.data = &pwrap_mt8183,
> +	}, {
> +		.compatible = "mediatek,mt8186-pwrap",
> +		.data = &pwrap_mt8186,
>   	}, {
>   		.compatible = "mediatek,mt8195-pwrap",
>   		.data = &pwrap_mt8195,
> @@ -2112,7 +2182,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
>   static int pwrap_probe(struct platform_device *pdev)
>   {
>   	int ret, irq;
> -	u32 mask_done;
> +	u32 rdata;
>   	struct pmic_wrapper *wrp;
>   	struct device_node *np = pdev->dev.of_node;
>   	const struct of_device_id *of_slave_id = NULL;
> @@ -2207,12 +2277,16 @@ static int pwrap_probe(struct platform_device *pdev)
>   		}
>   	}
>   
> -	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
> -		mask_done = PWRAP_STATE_INIT_DONE1;
> +	if (!HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
> +		rdata = pwrap_readl(wrp, PWRAP_WACS2_RDATA) &
> +				    PWRAP_STATE_INIT_DONE0;
> +	else if (!HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))
> +		rdata = pwrap_readl(wrp, PWRAP_WACS2_RDATA) &
> +				    PWRAP_STATE_INIT_DONE0_V2;

Why are you changing the logic here?
I think that assigning to `mask_done` is a good option, reducing duplication and
also reducing the amount of changes for this patch.

That said, I would simply do it as follows:

	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))

		mask_done = PWRAP_STATE_INIT_DONE1;

	else if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))

		mask_done = PWRAP_STATE_INIT_DONE0_V2;

	else

		mask_done = PWRAP_STATE_INIT_DONE0;

Regards,
- Angelo


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:05:47 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 10:05:47 +0100
Subject: [PATCH 2/2] dt-bindings: mediatek: add compatible for MT8186 pwrap
In-Reply-To: <20211230114913.9829-3-johnson.wang@mediatek.com>
References: <20211230114913.9829-1-johnson.wang@mediatek.com>
 <20211230114913.9829-3-johnson.wang@mediatek.com>
Message-ID: <e5992de7-2570-8610-8acf-78313ff74718@collabora.com>

Il 30/12/21 12:49, Johnson Wang ha scritto:
> This adds dt-binding documentation of pwrap for Mediatek MT8186
> SoCs Platform.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>   Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> index d74a7a5ae9f2..214a34633824 100644
> --- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> +++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
> @@ -27,6 +27,7 @@ Required properties in pwrap device node.
>   	"mediatek,mt8135-pwrap" for MT8135 SoCs
>   	"mediatek,mt8173-pwrap" for MT8173 SoCs
>   	"mediatek,mt8183-pwrap" for MT8183 SoCs
> +	"mediatek,mt8186-pwrap" for MT8186 SoCs
>   	"mediatek,mt8195-pwrap" for MT8195 SoCs
>   	"mediatek,mt8516-pwrap" for MT8516 SoCs
>   - interrupts: IRQ for pwrap in SOC
> 

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:08:02 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 10:08:02 +0100
Subject: [PATCH v4] drm/mediatek: Fix mtk_cec_mask()
In-Reply-To: <20220103054706.8072-1-miles.chen@mediatek.com>
References: <20220103054706.8072-1-miles.chen@mediatek.com>
Message-ID: <1c57eecc-de2d-b3dc-6ea6-ddd50db70e95@collabora.com>

Il 03/01/22 06:47, Miles Chen ha scritto:
> In current implementation, mtk_cec_mask() writes val into target register
> and ignores the mask. After talking to our hdmi experts, mtk_cec_mask()
> should read a register, clean only mask bits, and update (val | mask) bits
> to the register.
> 
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
> 
> Cc: Zhiqiang Lin <zhiqiang.lin at mediatek.com>
> Cc: CK Hu <ck.hu at mediatek.com>
> Cc: Matthias Brugger <matthias.bgg at gmail.com>
> 
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
> 
> Change since v1:
> add Fixes tag
> 
> Change since v2:
> add explanation of mtk_cec_mask()
> 
> Change since v3:
> change misleading subject and modify the commit message since this is a bug fix patch
> 
> ---
>   drivers/gpu/drm/mediatek/mtk_cec.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
> index e9cef5c0c8f7..cdfa648910b2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_cec.c
> +++ b/drivers/gpu/drm/mediatek/mtk_cec.c
> @@ -85,7 +85,7 @@ static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset,
>   	u32 tmp = readl(cec->regs + offset) & ~mask;
>   
>   	tmp |= val & mask;
> -	writel(val, cec->regs + offset);
> +	writel(tmp, cec->regs + offset);
>   }
>   
>   void mtk_cec_set_hpd_event(struct device *dev,
> 



From harinik at xilinx.com  Tue Jan  4 01:12:06 2022
From: harinik at xilinx.com (Harini Katakam)
Date: Tue, 4 Jan 2022 09:12:06 +0000
Subject: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <YdQMyfYU0wxHrT40@shell.armlinux.org.uk>
References: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
 <E1mxqBh-00GWxo-51@rmk-PC.armlinux.org.uk>
 <20211216071513.6d1e0f55@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
 <YbtxGLrXoR9oHRmM@shell.armlinux.org.uk>
 <CAFcVECJeRwgjGsxtcGpMuA23nnmywsNkA2Yngk6aDK_JuVE3NQ@mail.gmail.com>
 <CAFcVEC+N0Y7ESFe-qcfpmkbPjRSvCJ=AOXoM6XSK6xGo=J1YNw@mail.gmail.com>
 <YdQMyfYU0wxHrT40@shell.armlinux.org.uk>
Message-ID: <BL3PR02MB8187165DAF278F65C8024567C94A9@BL3PR02MB8187.namprd02.prod.outlook.com>



> -----Original Message-----
> From: Russell King <linux at armlinux.org.uk>
> Sent: Tuesday, January 4, 2022 2:31 PM
> To: Harini Katakam <harinik at xilinx.com>
> Cc: Jakub Kicinski <kuba at kernel.org>; Michal Simek <michals at xilinx.com>;
> Radhey Shyam Pandey <radheys at xilinx.com>; Sean Anderson
> <sean.anderson at seco.com>; David S. Miller <davem at davemloft.net>;
> netdev <netdev at vger.kernel.org>; linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
> 
> On Tue, Jan 04, 2022 at 01:26:28PM +0530, Harini Katakam wrote:
> > On Fri, Dec 17, 2021 at 1:55 PM Harini Katakam <harinik at xilinx.com> wrote:
> > >
> > > Hi Russell,
> > >
> > > On Fri, Dec 17, 2021 at 5:26 AM Russell King (Oracle)
> > > <linux at armlinux.org.uk> wrote:
> > > >
> > > > On Thu, Dec 16, 2021 at 07:15:13AM -0800, Jakub Kicinski wrote:
> > > > > On Thu, 16 Dec 2021 12:48:45 +0000 Russell King (Oracle) wrote:
> > > > > > Convert axienet to use the phylink_pcs layer, resulting in it
> > > > > > no longer being a legacy driver.
> > > > > >
> > > > > > One oddity in this driver is that lp->switch_x_sgmii controls
> > > > > > whether we support switching between SGMII and 1000baseX.
> > > > > > However, when clear, this also blocks updating the 1000baseX
> > > > > > advertisement, which it probably should not be doing.
> > > > > > Nevertheless, this behaviour is preserved but a comment is added.
> > > > > >
> > > > > > Signed-off-by: Russell King (Oracle)
> > > > > > <rmk+kernel at armlinux.org.uk>
> > > > >
> > > > > drivers/net/ethernet/xilinx/xilinx_axienet.h:479: warning: Function
> parameter or member 'pcs' not described in 'axienet_local'
> > > >
> > > > Fixed that and the sha1 issue you raised in patch 2. Since both
> > > > are "documentation" issues, I won't send out replacement patches
> > > > until I've heard they've been tested on hardware though.
> > >
> > > Thanks for the patches.
> > > Series looks good and we're testing at our end; will get back to you
> > > early next week.
> >
> > Thanks Russell. I've tested AXI Ethernet and it works fine.
> 
> Happy new year!
> 
> Thanks - can I use that as a tested-by please, and would you be happy for me
> to send the patches for merging this week?

Sure, yes and yes.
Tested-by: Harini Katakam <harini.katakam at xilinx.com>

Happy new year to you too!

Regards,
Harini


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:13:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 10:13:44 +0100
Subject: [PATCH] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <20211210113617.196204-1-angelogioacchino.delregno@collabora.com>
References: <20211210113617.196204-1-angelogioacchino.delregno@collabora.com>
Message-ID: <a2c54a49-b052-ab41-d2af-1869c63878e3@collabora.com>

Il 10/12/21 12:36, AngeloGioacchino Del Regno ha scritto:
> DRM bridge drivers are now attaching their DSI device at probe time,
> which requires us to register our DSI host in order to let the bridge
> to probe: this recently started producing an endless -EPROBE_DEFER
> loop on some machines that are using external bridges, like the
> parade-ps8640, found on the ACER Chromebook R13.
> 
> Now that the DSI hosts/devices probe sequence is documented, we can
> do adjustments to the mtk_dsi driver as to both fix now and make sure
> to avoid this situation in the future: for this, following what is
> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> mtk_dsi_ops.attach callback and delete it in the detach callback;
> keeping in mind that we are registering a drm_bridge for our DSI,
> which is only used/attached if the DSI Host is bound, it wouldn't
> make sense to keep adding our bridge at probe time (as it would
> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> that one to the dsi host attach function (and remove it in detach).
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Due to the latest changes in drm bridge, we need this patch to land as soon as
possible, otherwise breakages will be seen on all MediaTek powered devices using
DSI to eDP/DP bridges...

...hence, friendly ping for a review :)


From moudy.ho at mediatek.com  Tue Jan  4 01:17:10 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 4 Jan 2022 17:17:10 +0800
Subject: [PATCH v11 2/4] soc: mediatek: mmsys: add support for ISP control
In-Reply-To: <20220104091712.25670-1-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
Message-ID: <20220104091712.25670-3-moudy.ho@mediatek.com>

This patch adds 8183 ISP settings in MMSYS domain and interface.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mt8183-mmsys.h    |  26 ++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 115 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |   1 +
 include/linux/soc/mediatek/mtk-mmsys.h |  30 +++++++
 4 files changed, 172 insertions(+)

diff --git a/drivers/soc/mediatek/mt8183-mmsys.h b/drivers/soc/mediatek/mt8183-mmsys.h
index 9dee485807c9..179d5996c659 100644
--- a/drivers/soc/mediatek/mt8183-mmsys.h
+++ b/drivers/soc/mediatek/mt8183-mmsys.h
@@ -13,6 +13,18 @@
 #define MT8183_DISP_RDMA0_SOUT_SEL_IN		0xf50
 #define MT8183_DISP_RDMA1_SOUT_SEL_IN		0xf54
 
+#define MT8183_ISP_REG_MMSYS_SW0_RST_B		0x140
+#define MT8183_ISP_REG_MMSYS_SW1_RST_B		0x144
+#define MT8183_ISP_REG_MDP_ASYNC_CFG_WD		0x934
+#define MT8183_ISP_REG_MDP_ASYNC_IPU_CFG_WD	0x93C
+#define MT8183_ISP_REG_ISP_RELAY_CFG_WD		0x994
+#define MT8183_ISP_REG_IPU_RELAY_CFG_WD		0x9a0
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_TX		BIT(3)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_TX2		BIT(4)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_RX		BIT(10)
+#define MT8183_ISP_BIT_MDP_DL_ASYNC_RX2		BIT(11)
+#define MT8183_ISP_BIT_NO_SOF_MODE		BIT(31)
+
 #define MT8183_OVL0_MOUT_EN_OVL0_2L		BIT(4)
 #define MT8183_OVL0_2L_MOUT_EN_DISP_PATH0	BIT(0)
 #define MT8183_OVL1_2L_MOUT_EN_RDMA1		BIT(4)
@@ -57,5 +69,19 @@ static const struct mtk_mmsys_routes mmsys_mt8183_routing_table[] = {
 	}
 };
 
+static const unsigned int mmsys_mt8183_mdp_isp_ctrl_table[ISP_CTRL_MAX] = {
+	[ISP_REG_MMSYS_SW0_RST_B] = MT8183_ISP_REG_MMSYS_SW0_RST_B,
+	[ISP_REG_MMSYS_SW1_RST_B] = MT8183_ISP_REG_MMSYS_SW1_RST_B,
+	[ISP_REG_MDP_ASYNC_CFG_WD] = MT8183_ISP_REG_MDP_ASYNC_CFG_WD,
+	[ISP_REG_MDP_ASYNC_IPU_CFG_WD] = MT8183_ISP_REG_MDP_ASYNC_IPU_CFG_WD,
+	[ISP_REG_ISP_RELAY_CFG_WD] = MT8183_ISP_REG_ISP_RELAY_CFG_WD,
+	[ISP_REG_IPU_RELAY_CFG_WD] = MT8183_ISP_REG_IPU_RELAY_CFG_WD,
+	[ISP_BIT_MDP_DL_ASYNC_TX] = MT8183_ISP_BIT_MDP_DL_ASYNC_TX,
+	[ISP_BIT_MDP_DL_ASYNC_TX2] = MT8183_ISP_BIT_MDP_DL_ASYNC_TX2,
+	[ISP_BIT_MDP_DL_ASYNC_RX] = MT8183_ISP_BIT_MDP_DL_ASYNC_RX,
+	[ISP_BIT_MDP_DL_ASYNC_RX2] = MT8183_ISP_BIT_MDP_DL_ASYNC_RX2,
+	[ISP_BIT_NO_SOF_MODE] = MT8183_ISP_BIT_NO_SOF_MODE,
+};
+
 #endif /* __SOC_MEDIATEK_MT8183_MMSYS_H */
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index d2994f717cc1..5f79c7e039ad 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -57,6 +57,7 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.routes = mmsys_mt8183_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
 	.has_gce_client_reg = true,
+	.mdp_isp_ctrl = mmsys_mt8183_mdp_isp_ctrl_table,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -128,6 +129,120 @@ void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_write_reg_by_cmdq);
 
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	/* Direct link */
+	if (id == MDP_COMP_CAMIN) {
+		/* Reset MDP_DL_ASYNC_TX */
+		if (isp_ctrl[ISP_REG_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX]);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX],
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX]);
+		}
+
+		/* Reset MDP_DL_ASYNC_RX */
+		if (isp_ctrl[ISP_REG_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX]);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX],
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX]);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_NO_SOF_MODE]);
+		}
+	}
+
+	if (id == MDP_COMP_CAMIN2) {
+		/* Reset MDP_DL_ASYNC2_TX */
+		if (isp_ctrl[ISP_REG_MMSYS_SW0_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW0_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2]);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2],
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_TX2]);
+		}
+
+		/* Reset MDP_DL_ASYNC2_RX */
+		if (isp_ctrl[ISP_REG_MMSYS_SW1_RST_B]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MMSYS_SW1_RST_B];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2]);
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2],
+					    isp_ctrl[ISP_BIT_MDP_DL_ASYNC_RX2]);
+		}
+
+		/* Enable sof mode */
+		if (isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    0x0,
+					    isp_ctrl[ISP_BIT_NO_SOF_MODE]);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_isp_ctrl);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id, u32 camin_w, u32 camin_h)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const unsigned int *isp_ctrl = mmsys->data->mdp_isp_ctrl;
+	u32 reg;
+
+	/* Config for direct link */
+	if (id == MDP_COMP_CAMIN) {
+		if (isp_ctrl[ISP_REG_MDP_ASYNC_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MDP_ASYNC_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+
+		if (isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_ISP_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+	if (id == MDP_COMP_CAMIN2) {
+		if (isp_ctrl[ISP_REG_MDP_ASYNC_IPU_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_MDP_ASYNC_IPU_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+		if (isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD]) {
+			reg = mmsys->addr + isp_ctrl[ISP_REG_IPU_RELAY_CFG_WD];
+			cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys, reg,
+					    (camin_h << 16) + camin_w,
+					    0x3FFF3FFF);
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_camin_ctrl);
+
 static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
 				  bool assert)
 {
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 9fce400507d2..ad8b92389b54 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -93,6 +93,7 @@ struct mtk_mmsys_driver_data {
 	const struct mtk_mmsys_routes *routes;
 	const unsigned int num_routes;
 	bool has_gce_client_reg;
+	const unsigned int *mdp_isp_ctrl;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 7f8ecc98d023..45e77d1cd6c1 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -91,6 +91,29 @@ enum mtk_mdp_comp_id {
 	MDP_MAX_COMP_COUNT	/* ALWAYS keep at the end */
 };
 
+enum mtk_mdp_pipe_id {
+	MDP_PIPE_RDMA0,
+	MDP_PIPE_IMGI,
+	MDP_PIPE_WPEI,
+	MDP_PIPE_WPEI2,
+	MDP_PIPE_MAX
+};
+
+enum mtk_isp_ctrl {
+	ISP_REG_MMSYS_SW0_RST_B,
+	ISP_REG_MMSYS_SW1_RST_B,
+	ISP_REG_MDP_ASYNC_CFG_WD,
+	ISP_REG_MDP_ASYNC_IPU_CFG_WD,
+	ISP_REG_ISP_RELAY_CFG_WD,
+	ISP_REG_IPU_RELAY_CFG_WD,
+	ISP_BIT_MDP_DL_ASYNC_TX,
+	ISP_BIT_MDP_DL_ASYNC_TX2,
+	ISP_BIT_MDP_DL_ASYNC_RX,
+	ISP_BIT_MDP_DL_ASYNC_RX2,
+	ISP_BIT_NO_SOF_MODE,
+	ISP_CTRL_MAX
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -103,4 +126,11 @@ void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
 				 struct mmsys_cmdq_cmd *cmd,
 				 u32 alias_id, u32 value, u32 mask);
 
+void mtk_mmsys_mdp_isp_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			    enum mtk_mdp_comp_id id);
+
+void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
+			      enum mtk_mdp_comp_id id,
+			      u32 camin_w, u32 camin_h);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



From moudy.ho at mediatek.com  Tue Jan  4 01:17:09 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 4 Jan 2022 17:17:09 +0800
Subject: [PATCH v11 1/4] soc: mediatek: mmsys: add CMDQ write register function
In-Reply-To: <20220104091712.25670-1-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
Message-ID: <20220104091712.25670-2-moudy.ho@mediatek.com>

Adding the interface of writing MMSYS register via CMDQ,
users do not need to parse related dts information.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/Kconfig           |  1 +
 drivers/soc/mediatek/mtk-mmsys.c       | 30 ++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |  1 +
 include/linux/soc/mediatek/mtk-mmsys.h | 50 ++++++++++++++++++++++++++
 4 files changed, 82 insertions(+)

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index fdd8bc08569e..172bc7828aca 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -69,6 +69,7 @@ config MTK_MMSYS
 	bool "MediaTek MMSYS Support"
 	default ARCH_MEDIATEK
 	depends on HAS_IOMEM
+	select MTK_CMDQ
 	help
 	  Say yes here to add support for the MediaTek Multimedia
 	  Subsystem (MMSYS).
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 1e448f1ffefb..d2994f717cc1 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -8,9 +8,11 @@
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
@@ -54,6 +56,7 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.clk_driver = "clk-mt8183-mm",
 	.routes = mmsys_mt8183_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+	.has_gce_client_reg = true,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -73,6 +76,8 @@ struct mtk_mmsys {
 	const struct mtk_mmsys_driver_data *data;
 	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
 	struct reset_controller_dev rcdev;
+	struct cmdq_client_reg cmdq_base;
+	phys_addr_t addr;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -112,6 +117,17 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
+				 struct mmsys_cmdq_cmd *cmd,
+				 u32 offset, u32 value, u32 mask)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+
+	cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys,
+			    mmsys->addr + offset, value, mask);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_write_reg_by_cmdq);
+
 static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
 				  bool assert)
 {
@@ -170,6 +186,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	struct platform_device *clks;
 	struct platform_device *drm;
 	struct mtk_mmsys *mmsys;
+	struct resource res;
 	int ret;
 
 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
@@ -195,6 +212,19 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &res) < 0)
+		mmsys->addr = 0L;
+	else
+		mmsys->addr = res.start;
+
+	if (mmsys->data->has_gce_client_reg) {
+		ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+		if (ret) {
+			dev_err(dev, "No mediatek,gce-client-reg!\n");
+			return ret;
+		}
+	}
+
 	mmsys->data = of_device_get_match_data(&pdev->dev);
 	platform_set_drvdata(pdev, mmsys);
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 8b0ed05117ea..9fce400507d2 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -92,6 +92,7 @@ struct mtk_mmsys_driver_data {
 	const char *clk_driver;
 	const struct mtk_mmsys_routes *routes;
 	const unsigned int num_routes;
+	bool has_gce_client_reg;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 4bba275e235a..7f8ecc98d023 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -7,8 +7,14 @@
 #define __MTK_MMSYS_H
 
 enum mtk_ddp_comp_id;
+enum mtk_mdp_comp_id;
 struct device;
 
+struct mmsys_cmdq_cmd {
+	struct cmdq_pkt *pkt;
+	s32 *event;
+};
+
 enum mtk_ddp_comp_id {
 	DDP_COMPONENT_AAL0,
 	DDP_COMPONENT_AAL1,
@@ -45,6 +51,46 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mdp_comp_id {
+	MDP_COMP_NONE = -1,	/* Invalid engine */
+
+	/* ISP */
+	MDP_COMP_WPEI = 0,
+	MDP_COMP_WPEO,		/* 1 */
+	MDP_COMP_WPEI2,		/* 2 */
+	MDP_COMP_WPEO2,		/* 3 */
+	MDP_COMP_ISP_IMGI,	/* 4 */
+	MDP_COMP_ISP_IMGO,	/* 5 */
+	MDP_COMP_ISP_IMG2O,	/* 6 */
+
+	/* IPU */
+	MDP_COMP_IPUI,		/* 7 */
+	MDP_COMP_IPUO,		/* 8 */
+
+	/* MDP */
+	MDP_COMP_CAMIN,		/* 9 */
+	MDP_COMP_CAMIN2,	/* 10 */
+	MDP_COMP_RDMA0,		/* 11 */
+	MDP_COMP_AAL0,		/* 12 */
+	MDP_COMP_CCORR0,	/* 13 */
+	MDP_COMP_RSZ0,		/* 14 */
+	MDP_COMP_RSZ1,		/* 15 */
+	MDP_COMP_TDSHP0,	/* 16 */
+	MDP_COMP_COLOR0,	/* 17 */
+	MDP_COMP_PATH0_SOUT,	/* 18 */
+	MDP_COMP_PATH1_SOUT,	/* 19 */
+	MDP_COMP_WROT0,		/* 20 */
+	MDP_COMP_WDMA,		/* 21 */
+
+	/* Dummy Engine */
+	MDP_COMP_RDMA1,		/* 22 */
+	MDP_COMP_RSZ2,		/* 23 */
+	MDP_COMP_TDSHP1,	/* 24 */
+	MDP_COMP_WROT1,		/* 25 */
+
+	MDP_MAX_COMP_COUNT	/* ALWAYS keep at the end */
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -53,4 +99,8 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
+				 struct mmsys_cmdq_cmd *cmd,
+				 u32 alias_id, u32 value, u32 mask);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



From moudy.ho at mediatek.com  Tue Jan  4 01:17:11 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 4 Jan 2022 17:17:11 +0800
Subject: [PATCH v11 3/4] soc: mediatek: mutex: add support for MDP
In-Reply-To: <20220104091712.25670-1-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
Message-ID: <20220104091712.25670-4-moudy.ho@mediatek.com>

For the purpose of module independence, related settings should be moved
from MDP to the corresponding driver.
This patch adds more 8183 MDP settings and interface.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mtk-mutex.c       | 68 ++++++++++++++++++++++++++
 include/linux/soc/mediatek/mtk-mutex.h |  3 ++
 2 files changed, 71 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2ca55bb5a8be..64a4f79e432e 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -119,6 +119,18 @@
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
 
+#define MT8183_MUTEX_MDP_START			5
+#define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
+#define MT8183_MUTEX_MDP_SOF_MASK		0x00000007
+#define MT8183_MUTEX_MOD_MDP_RDMA0		BIT(2)
+#define MT8183_MUTEX_MOD_MDP_RSZ0		BIT(4)
+#define MT8183_MUTEX_MOD_MDP_RSZ1		BIT(5)
+#define MT8183_MUTEX_MOD_MDP_TDSHP0		BIT(6)
+#define MT8183_MUTEX_MOD_MDP_WROT0		BIT(7)
+#define MT8183_MUTEX_MOD_MDP_WDMA		BIT(8)
+#define MT8183_MUTEX_MOD_MDP_AAL0		BIT(23)
+#define MT8183_MUTEX_MOD_MDP_CCORR0		BIT(24)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -139,6 +151,10 @@ struct mtk_mutex_data {
 	const unsigned int *mutex_sof;
 	const unsigned int mutex_mod_reg;
 	const unsigned int mutex_sof_reg;
+	const unsigned int *mutex_mdp_offset;
+	const unsigned int *mutex_mdp_mod;
+	const unsigned int mutex_mdp_mod_mask;
+	const unsigned int mutex_mdp_sof_mask;
 	const bool no_clk;
 };
 
@@ -226,6 +242,17 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
+static const unsigned int mt8183_mutex_mdp_mod[MDP_MAX_COMP_COUNT] = {
+	[MDP_COMP_RDMA0] = MT8183_MUTEX_MOD_MDP_RDMA0,
+	[MDP_COMP_RSZ0] = MT8183_MUTEX_MOD_MDP_RSZ0,
+	[MDP_COMP_RSZ1] = MT8183_MUTEX_MOD_MDP_RSZ1,
+	[MDP_COMP_TDSHP0] = MT8183_MUTEX_MOD_MDP_TDSHP0,
+	[MDP_COMP_WROT0] = MT8183_MUTEX_MOD_MDP_WROT0,
+	[MDP_COMP_WDMA] = MT8183_MUTEX_MOD_MDP_WDMA,
+	[MDP_COMP_AAL0] = MT8183_MUTEX_MOD_MDP_AAL0,
+	[MDP_COMP_CCORR0] = MT8183_MUTEX_MOD_MDP_CCORR0,
+};
+
 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
@@ -264,6 +291,14 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+/* indicate which mutex is used by each pipepline */
+static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
+	[MDP_PIPE_IMGI] = MT8183_MUTEX_MDP_START,
+	[MDP_PIPE_RDMA0] = MT8183_MUTEX_MDP_START + 1,
+	[MDP_PIPE_WPEI] = MT8183_MUTEX_MDP_START + 2,
+	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -298,6 +333,10 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.mutex_sof = mt8183_mutex_sof,
 	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
+	.mutex_mdp_offset = mt8183_mutex_mdp_offset,
+	.mutex_mdp_mod = mt8183_mutex_mdp_mod,
+	.mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK,
+	.mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK,
 	.no_clk = true,
 };
 
@@ -323,6 +362,21 @@ struct mtk_mutex *mtk_mutex_get(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_get);
 
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id)
+{
+	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
+	int i = mtx->data->mutex_mdp_offset[id];
+
+	if (!mtx->mutex[i].claimed) {
+		mtx->mutex[i].claimed = true;
+		return &mtx->mutex[i];
+	}
+
+	return ERR_PTR(-EBUSY);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_mdp_get);
+
 void mtk_mutex_put(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -442,6 +496,20 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_remove_comp);
 
+u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	if (mtx->data->mutex_mdp_mod)
+		return mtx->data->mutex_mdp_mod[id];
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_get_mdp_mod);
+
 void mtk_mutex_enable(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
index 6fe4ffbde290..b2608f4220ee 100644
--- a/include/linux/soc/mediatek/mtk-mutex.h
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -11,9 +11,12 @@ struct device;
 struct mtk_mutex;
 
 struct mtk_mutex *mtk_mutex_get(struct device *dev);
+struct mtk_mutex *mtk_mutex_mdp_get(struct device *dev,
+				    enum mtk_mdp_pipe_id id);
 int mtk_mutex_prepare(struct mtk_mutex *mutex);
 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 			enum mtk_ddp_comp_id id);
+u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id);
 void mtk_mutex_enable(struct mtk_mutex *mutex);
 void mtk_mutex_disable(struct mtk_mutex *mutex);
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
-- 
2.18.0



From moudy.ho at mediatek.com  Tue Jan  4 01:17:12 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 4 Jan 2022 17:17:12 +0800
Subject: [PATCH v11 4/4] soc: mediatek: mutex: add functions that operate
 registers by CMDQ
In-Reply-To: <20220104091712.25670-1-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
Message-ID: <20220104091712.25670-5-moudy.ho@mediatek.com>

Considering that some functions have timing requirements
in specific situation, this patch adds several interface that
operate registers by CMDQ.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c       | 72 +++++++++++++++++++++++++-
 include/linux/soc/mediatek/mtk-mutex.h |  6 +++
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 64a4f79e432e..615c42260a50 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -7,10 +7,14 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#define MTK_MUTEX_ENABLE			BIT(0)
 
 #define MT2701_MUTEX0_MOD0			0x2c
 #define MT2701_MUTEX0_SOF0			0x30
@@ -156,6 +160,7 @@ struct mtk_mutex_data {
 	const unsigned int mutex_mdp_mod_mask;
 	const unsigned int mutex_mdp_sof_mask;
 	const bool no_clk;
+	const bool has_gce_client_reg;
 };
 
 struct mtk_mutex_ctx {
@@ -164,6 +169,8 @@ struct mtk_mutex_ctx {
 	void __iomem			*regs;
 	struct mtk_mutex		mutex[10];
 	const struct mtk_mutex_data	*data;
+	phys_addr_t			addr;
+	struct cmdq_client_reg		cmdq_reg;
 };
 
 static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
@@ -338,6 +345,7 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.mutex_mdp_mod_mask = MT8183_MUTEX_MDP_MOD_MASK,
 	.mutex_mdp_sof_mask = MT8183_MUTEX_MDP_SOF_MASK,
 	.no_clk = true,
+	.has_gce_client_reg = true,
 };
 
 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
@@ -510,6 +518,25 @@ u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_get_mdp_mod);
 
+void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod,
+			       struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+	unsigned int offset;
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset,
+			    mod, mtx->data->mutex_mdp_mod_mask);
+
+	offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset,
+			    0, mtx->data->mutex_mdp_sof_mask);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_add_mod_by_cmdq);
+
 void mtk_mutex_enable(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -521,6 +548,20 @@ void mtk_mutex_enable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_enable);
 
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    MTK_MUTEX_ENABLE, MTK_MUTEX_ENABLE);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_enable_by_cmdq);
+
 void mtk_mutex_disable(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -532,6 +573,20 @@ void mtk_mutex_disable(struct mtk_mutex *mutex)
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_disable);
 
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd)
+{
+	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
+						 mutex[mutex->id]);
+
+	WARN_ON(&mtx->mutex[mutex->id] != mutex);
+
+	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys,
+			    mtx->addr + DISP_REG_MUTEX_EN(mutex->id),
+			    0x0, MTK_MUTEX_ENABLE);
+}
+EXPORT_SYMBOL_GPL(mtk_mutex_disable_by_cmdq);
+
 void mtk_mutex_acquire(struct mtk_mutex *mutex)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
@@ -559,8 +614,8 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct mtk_mutex_ctx *mtx;
-	struct resource *regs;
-	int i;
+	struct resource *regs, addr;
+	int i, ret;
 
 	mtx = devm_kzalloc(dev, sizeof(*mtx), GFP_KERNEL);
 	if (!mtx)
@@ -580,6 +635,19 @@ static int mtk_mutex_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_address_to_resource(dev->of_node, 0, &addr) < 0)
+		mtx->addr = 0L;
+	else
+		mtx->addr = addr.start;
+
+	if (mtx->data->has_gce_client_reg) {
+		ret = cmdq_dev_get_client_reg(dev, &mtx->cmdq_reg, 0);
+		if (ret) {
+			dev_err(dev, "No mediatek,gce-client-reg!\n");
+			return ret;
+		}
+	}
+
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mtx->regs = devm_ioremap_resource(dev, regs);
 	if (IS_ERR(mtx->regs)) {
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
index b2608f4220ee..05de7ad4a124 100644
--- a/include/linux/soc/mediatek/mtk-mutex.h
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -17,8 +17,14 @@ int mtk_mutex_prepare(struct mtk_mutex *mutex);
 void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 			enum mtk_ddp_comp_id id);
 u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id);
+void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod,
+			       struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_enable(struct mtk_mutex *mutex);
+void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
+			      struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_disable(struct mtk_mutex *mutex);
+void mtk_mutex_disable_by_cmdq(struct mtk_mutex *mutex,
+			       struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 			   enum mtk_ddp_comp_id id);
 void mtk_mutex_unprepare(struct mtk_mutex *mutex);
-- 
2.18.0



From moudy.ho at mediatek.com  Tue Jan  4 01:17:08 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Tue, 4 Jan 2022 17:17:08 +0800
Subject: [PATCH v11 0/4] Add mmsys and mutex support for MDP
Message-ID: <20220104091712.25670-1-moudy.ho@mediatek.com>

Change since v10:
- For some ISP application scenarios, such as preview and recording
  at the same time.
  The routing table needs to be discarded, and the calculation result
  on the SCP side is used to write a suitable mux setting for
  1 input and 2 output.
- Adjust the GCE client register parsing method to avoid redundant warning logs.

Change since v9:
- Add API for MDP getting mutex mod.

Hi,

This patch splits mmsys and mutex settings from Media Data Path 3 (MDP3),
and original mailling list list below:
https://patchwork.kernel.org/project/linux-mediatek/cover/20211201095031.31606-1-moudy.ho at mediatek.com/
Corresponding settings and interfaces are added for MDP operation in the
mmsys and mutex drivers, which increases the independence of the modules

Moudy Ho (4):
  soc: mediatek: mmsys: add CMDQ write register function
  soc: mediatek: mmsys: add support for ISP control
  soc: mediatek: mutex: add support for MDP
  soc: mediatek: mutex: add functions that operate registers by CMDQ

 drivers/soc/mediatek/Kconfig           |   1 +
 drivers/soc/mediatek/mt8183-mmsys.h    |  26 +++++
 drivers/soc/mediatek/mtk-mmsys.c       | 145 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |   2 +
 drivers/soc/mediatek/mtk-mutex.c       | 140 +++++++++++++++++++++++-
 include/linux/soc/mediatek/mtk-mmsys.h |  80 ++++++++++++++
 include/linux/soc/mediatek/mtk-mutex.h |   9 ++
 7 files changed, 401 insertions(+), 2 deletions(-)

-- 
2.18.0



From geert at linux-m68k.org  Tue Jan  4 01:29:09 2022
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Tue, 4 Jan 2022 10:29:09 +0100
Subject: [PATCH v5 5/6] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <CAPDyKFqWUJTKte3dM=7xG6EtKR8i9neCCNYFs7Jf1J34TezUEQ@mail.gmail.com>
References: <20211218130014.4037640-1-daniel.lezcano@linaro.org>
 <20211218130014.4037640-6-daniel.lezcano@linaro.org>
 <CAPDyKFqWUJTKte3dM=7xG6EtKR8i9neCCNYFs7Jf1J34TezUEQ@mail.gmail.com>
Message-ID: <CAMuHMdXzs9WMksQAJXdYaQndsqK3CnQZTGYw=TSFVrDEdX8PCA@mail.gmail.com>

On Fri, Dec 31, 2021 at 2:58 PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
> On Sat, 18 Dec 2021 at 14:00, Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
> > The DTPM framework does support now the hierarchy description.
> >
> > The platform specific code can call the hierarchy creation function
> > with an array of struct dtpm_node pointing to their parent.
> >
> > This patch provides a description of the big and Little CPUs and the
> > GPU and tie them together under a virtual package name. Only rk3399 is
> > described now.
> >
> > The description could be extended in the future with the memory
> > controller with devfreq if it has the energy information.
> >
> > The hierarchy uses the GPU devfreq with the panfrost driver, and this
> > one could be loaded as a module. If the hierarchy is created before
> > the panfrost driver is loaded, it will fail. For this reason the
> > Kconfig option depends on the panfrost Kconfig's option. If this one
> > is compiled as a module, automatically the dtpm hierarchy code will be
> > a module also. Module loading ordering will fix this chicken-egg
> > problem.
> >
> > Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>

> > --- /dev/null
> > +++ b/drivers/soc/rockchip/dtpm.c
> > @@ -0,0 +1,56 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright 2021 Linaro Limited
> > + *
> > + * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
> > + *
> > + * DTPM hierarchy description
> > + */
> > +#include <linux/dtpm.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/platform_device.h>
> > +
> > +static struct dtpm_node __initdata rk3399_hierarchy[] = {
> > +       [0]{ .name = "rk3399" },
> > +       [1]{ .name = "package",
> > +            .parent = &rk3399_hierarchy[0] },
> > +       [2]{ .name = "/cpus/cpu at 0",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [3]{ .name = "/cpus/cpu at 1",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [4]{ .name = "/cpus/cpu at 2",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [5]{ .name = "/cpus/cpu at 3",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [6]{ .name = "/cpus/cpu at 100",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [7]{ .name = "/cpus/cpu at 101",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [8]{ .name = "rockchip,rk3399-mali",
> > +            .type = DTPM_NODE_DT,
> > +            .parent = &rk3399_hierarchy[1] },
> > +       [9]{ },
> > +};
>
> I will not object to this, as in the end this seems like what we need
> to do, unless we can describe things through generic DT bindings for
> DTPM. Right?
>
> Although, if the above is correct, I need to stress that I am kind of
> worried that this doesn't really scale. We would need to copy lots of
> information from the DTS files into platform specific c-files, to be
> able to describe the DTPM hierarchy.

The description in rk3399_hierarchy[] looks fairly similar to a
power-domains hierarchy, like we have in e.g. the various
drivers/soc/renesas/r8*-sysc.c files.  One big difference is that the
latter do not hardcode the node paths in the driver, but use power
domain indices, referenced from DT in power-domains properties.

Perhaps a similar approach can be used for DTPM?
Does DTPM differ a lot from PM Domains? If not, perhaps no new
properties are needed, and power-domains/#power-domain-cells can be
used as is?

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:31:05 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 10:31:05 +0100
Subject: [PATCH v3, 02/13] media: mtk-vcodec: Using firmware type to
 separate different firmware architecture
In-Reply-To: <20220104080138.7472-3-yunfei.dong@mediatek.com>
References: <20220104080138.7472-1-yunfei.dong@mediatek.com>
 <20220104080138.7472-3-yunfei.dong@mediatek.com>
Message-ID: <94e51db2-c44a-b2fe-36af-d58c9e5ca29c@collabora.com>

Il 04/01/22 09:01, Yunfei Dong ha scritto:
> MT8173 platform use vpu firmware, mt8183/mt8192 will use scp
> firmware instead, using chip name is not reasonable to separate
> different firmware architecture. Using firmware type is much better.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>

Hello Yunfei,

I agree with this change, it looks better as it separates behaviors in
a more generic way.

Anyway, it looks like you're removing all users of `enum mtk_chip` but, in
this case, you forgot to also remove the declaration of this enumeration
from mtk_vcodec_drv.h! :)

Can you please send a v4 with the requested removal?

so, for v4...
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From maz at kernel.org  Tue Jan  4 01:39:59 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 04 Jan 2022 09:39:59 +0000
Subject: [PATCH v5 34/69] KVM: arm64: nv: Configure HCR_EL2 for nested
 virtualization
In-Reply-To: <bbf31da5-ca1b-7499-e23c-9b5281ca7901@os.amperecomputing.com>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-35-maz@kernel.org>
 <bbf31da5-ca1b-7499-e23c-9b5281ca7901@os.amperecomputing.com>
Message-ID: <87o84rvnyo.wl-maz@kernel.org>

On Tue, 04 Jan 2022 08:53:42 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> 
> 
> On 30-11-2021 01:31 am, Marc Zyngier wrote:
> > From: Jintack Lim <jintack.lim at linaro.org>
> > 
> > We enable nested virtualization by setting the HCR NV and NV1 bit.
> > 
> > When the virtual E2H bit is set, we can support EL2 register accesses
> > via EL1 registers from the virtual EL2 by doing trap-and-emulate. A
> > better alternative, however, is to allow the virtual EL2 to access EL2
> > register states without trap. This can be easily achieved by not traping
> > EL1 registers since those registers already have EL2 register states.
> > 
> > Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >   arch/arm64/include/asm/kvm_arm.h |  1 +
> >   arch/arm64/kvm/hyp/vhe/switch.c  | 38 +++++++++++++++++++++++++++++---
> >   2 files changed, 36 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index 68af5509e4b0..b8a0d410035b 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -87,6 +87,7 @@
> >   			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
> >   			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
> >   			 HCR_FMO | HCR_IMO | HCR_PTW )
> > +#define HCR_GUEST_NV_FILTER_FLAGS (HCR_ATA | HCR_API | HCR_APK | HCR_RW)
> >   #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
> >   #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
> >   #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
> > diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> > index 57f43e607819..da80c969e623 100644
> > --- a/arch/arm64/kvm/hyp/vhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> > @@ -36,9 +36,41 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
> >   	u64 hcr = vcpu->arch.hcr_el2;
> >   	u64 val;
> >   -	/* Trap VM sysreg accesses if an EL2 guest is not using
> > VHE. */
> > -	if (vcpu_mode_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
> > -		hcr |= HCR_TVM | HCR_TRVM;
> > +	if (is_hyp_ctxt(vcpu)) {
> > +		hcr |= HCR_NV;
> > +
> > +		if (!vcpu_el2_e2h_is_set(vcpu)) {
> > +			/*
> > +			 * For a guest hypervisor on v8.0, trap and emulate
> > +			 * the EL1 virtual memory control register accesses.
> > +			 */
> > +			hcr |= HCR_TVM | HCR_TRVM | HCR_NV1;
> > +		} else {
> > +			/*
> > +			 * For a guest hypervisor on v8.1 (VHE), allow to
> > +			 * access the EL1 virtual memory control registers
> > +			 * natively. These accesses are to access EL2 register
> > +			 * states.
> > +			 * Note that we still need to respect the virtual
> > +			 * HCR_EL2 state.
> > +			 */
> > +			u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
> > +
> > +			vhcr_el2 &= ~HCR_GUEST_NV_FILTER_FLAGS;
> 
> Why HCR_RW is cleared here, May I know please?

Good question. That's clearly a leftover from an early rework. It
really doesn't matter, as we are merging the guest's configuration
into the host's, and the host already has HCR_EL2.RW set.

What HCR_GUEST_NV_FILTER_FLAGS should contain is only the bits we
don't want to deal with at this stage of the NV support. I'll fix that
for the next round.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From kavyasree.kotagiri at microchip.com  Tue Jan  4 01:41:13 2022
From: kavyasree.kotagiri at microchip.com (Kavyasree Kotagiri)
Date: Tue, 4 Jan 2022 15:11:13 +0530
Subject: [PATCH v2] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
Message-ID: <20220104094113.3338-1-kavyasree.kotagiri@microchip.com>

This patch adds basic DT for Microchip lan966x SoC and associated board
pcb8291(2-port EVB). Adds peripherals required to allow booting: IRQs,
clocks, timers, memory, flexcoms, GPIOs. Also adds other peripherals like
crypto(AES,SHA), DMA and watchdog.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
---
v1 -> v2:
- Moved flx3 usart0 node to dtsi file.
- Removed status="okay" for dma0 to maintain consistency across nodes
  (which means enabling dma0 by default)

 arch/arm/boot/dts/Makefile            |   2 +
 arch/arm/boot/dts/lan966x.dtsi        | 243 ++++++++++++++++++++++++++
 arch/arm/boot/dts/lan966x_pcb8291.dts |  49 ++++++
 3 files changed, 294 insertions(+)
 create mode 100644 arch/arm/boot/dts/lan966x.dtsi
 create mode 100644 arch/arm/boot/dts/lan966x_pcb8291.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..dc1bd216ed58 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_LAN966) += \
+	lan966x_pcb8291.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
new file mode 100644
index 000000000000..bc9084752409
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x.dtsi
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x.dtsi - Device Tree Include file for Microchip LAN966x family SoC
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/microchip,lan966x.h>
+
+/ {
+	model = "Microchip LAN966x family SoC";
+	compatible = "microchip,lan966x";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			clock-frequency = <600000000>;
+			reg = <0x0>;
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;  /* 1GB */
+	};
+
+	clocks {
+		sys_clk: sys_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <162500000>;
+		};
+
+		cpu_clk: cpu_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <600000000>;
+		};
+
+		ddr_clk: ddr_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <300000000>;
+		};
+
+		nic_clk: nic_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+		};
+	};
+
+	clks: clock-controller at e00c00a8 {
+		compatible = "microchip,lan966x-gck";
+		#clock-cells = <1>;
+		clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
+		clock-names = "cpu", "ddr", "sys";
+		reg = <0xe00c00a8 0x38>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <37500000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		flx0: flexcom at e0040000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0040000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0040000 0x800>;
+			status = "disabled";
+		};
+
+		flx1: flexcom at e0044000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0044000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0044000 0x800>;
+			status = "disabled";
+		};
+
+		trng: trng at e0048000 {
+			compatible = "atmel,at91sam9g45-trng";
+			reg = <0xe0048000 0x100>;
+			clocks = <&nic_clk>;
+			status = "disabled";
+		};
+
+		aes: aes at e004c000 {
+			compatible = "atmel,at91sam9g46-aes";
+			reg = <0xe004c000 0x100>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
+			       <&dma0 AT91_XDMAC_DT_PERID(12)>;
+			dma-names = "rx", "tx";
+			clocks = <&nic_clk>;
+			clock-names = "aes_clk";
+		};
+
+		flx2: flexcom at e0060000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0060000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0060000 0x800>;
+			status = "disabled";
+		};
+
+		flx3: flexcom at e0064000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0064000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM3>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0064000 0x800>;
+			status = "disabled";
+
+			usart0: serial at 200 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0x200 0x200>;
+				interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&nic_clk>;
+				clock-names = "usart";
+				atmel,fifo-size = <32>;
+				status = "disabled";
+			};
+		};
+
+		dma0: dma-controller at e0068000 {
+			compatible = "microchip,sama7g5-dma";
+			reg = <0xe0068000 0x1000>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&nic_clk>;
+			clock-names = "dma_clk";
+		};
+
+		sha: sha at e006c000 {
+			compatible = "atmel,at91sam9g46-sha";
+			reg = <0xe006c000 0xec>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
+			dma-names = "tx";
+			clocks = <&nic_clk>;
+			clock-names = "sha_clk";
+		};
+
+		flx4: flexcom at e0070000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0070000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM4>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0070000 0x800>;
+			status = "disabled";
+		};
+
+		timer0: timer at e008c000 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0xe008c000 0x400>;
+			clocks = <&nic_clk>;
+			clock-names = "timer";
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		watchdog: watchdog at e0090000 {
+			compatible = "snps,dw-wdt";
+			reg = <0xe0090000 0x1000>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&nic_clk>;
+		};
+
+		can0: can at e081c000 {
+			compatible = "bosch,m_can";
+			reg = <0xe081c000 0xfc>, <0x00100000 0x4000>;
+			reg-names = "m_can", "message_ram";
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "int0", "int1";
+			clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
+			clock-names = "hclk", "cclk";
+			assigned-clocks = <&clks GCK_ID_MCAN0>;
+			assigned-clock-rates = <40000000>;
+			bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+			status = "disabled";
+		};
+
+		gpio: pinctrl at e2004064 {
+			compatible = "microchip,lan966x-pinctrl";
+			reg = <0xe2004064 0xb4>,
+			    <0xe2010024 0x138>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 78>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <2>;
+		};
+
+		gic: interrupt-controller at e8c11000 {
+			compatible = "arm,gic-400", "arm,cortex-a7-gic";
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			reg = <0xe8c11000 0x1000>,
+			      <0xe8c12000 0x2000>,
+			      <0xe8c14000 0x2000>,
+			      <0xe8c16000 0x2000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts b/arch/arm/boot/dts/lan966x_pcb8291.dts
new file mode 100644
index 000000000000..3ff86f15ea3d
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x_pcb8291.dts - Device Tree file for PCB8291
+ */
+/dts-v1/;
+#include "lan966x.dtsi"
+
+/ {
+	model = "Microchip EVB - LAN9662";
+	compatible = "microchip,lan9662-pcb8291", "microchip,lan9662", "microchip,lan966";
+};
+
+&gpio {
+	fc_shrd7_pins: fc_shrd7-pins {
+		pins = "GPIO_49";
+		function = "fc_shrd7";
+	};
+
+	fc_shrd8_pins: fc_shrd8-pins {
+		pins = "GPIO_54";
+		function = "fc_shrd8";
+	};
+
+	fc3_b_pins: fcb3-spi-pins {
+		/* SCK, RXD, TXD */
+		pins = "GPIO_51", "GPIO_52", "GPIO_53";
+		function = "fc3_b";
+	};
+};
+
+&can0 {
+	status = "okay";
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	usart0: serial at 200 {
+		pinctrl-0 = <&fc3_b_pins>, <&fc_shrd7_pins>, <&fc_shrd8_pins>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
+};
+
+&trng {
+	status = "okay";
+};
+
-- 
2.17.1



From andrzej.hajda at intel.com  Tue Jan  4 01:52:56 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 4 Jan 2022 10:52:56 +0100
Subject: [PATCH] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <20211210113617.196204-1-angelogioacchino.delregno@collabora.com>
References: <20211210113617.196204-1-angelogioacchino.delregno@collabora.com>
Message-ID: <2c69d44c-5e33-03d3-d981-425ee2167cf9@intel.com>

Hi,

On 10.12.2021 12:36, AngeloGioacchino Del Regno wrote:
> DRM bridge drivers are now attaching their DSI device at probe time,
> which requires us to register our DSI host in order to let the bridge
> to probe: this recently started producing an endless -EPROBE_DEFER
> loop on some machines that are using external bridges, like the
> parade-ps8640, found on the ACER Chromebook R13.
>
> Now that the DSI hosts/devices probe sequence is documented, we can
> do adjustments to the mtk_dsi driver as to both fix now and make sure
> to avoid this situation in the future: for this, following what is
> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> mtk_dsi_ops.attach callback and delete it in the detach callback;
> keeping in mind that we are registering a drm_bridge for our DSI,
> which is only used/attached if the DSI Host is bound, it wouldn't
> make sense to keep adding our bridge at probe time (as it would
> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> that one to the dsi host attach function (and remove it in detach).
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>   1 file changed, 84 insertions(+), 83 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..2ff347da35c2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>   	mtk_dsi_poweroff(dsi);
>   }
>   
> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> +{
> +	int ret;
> +
> +	ret = drm_simple_encoder_init(drm, &dsi->encoder,
> +				      DRM_MODE_ENCODER_DSI);
> +	if (ret) {
> +		DRM_ERROR("Failed to encoder init to drm\n");
> +		return ret;
> +	}
> +
> +	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> +
> +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +	if (ret)
> +		goto err_cleanup_encoder;
> +
> +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> +	if (IS_ERR(dsi->connector)) {
> +		DRM_ERROR("Unable to create bridge connector\n");
> +		ret = PTR_ERR(dsi->connector);
> +		goto err_cleanup_encoder;
> +	}
> +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> +
> +	return 0;
> +
> +err_cleanup_encoder:
> +	drm_encoder_cleanup(&dsi->encoder);
> +	return ret;
> +}
> +
> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> +{
> +	int ret;
> +	struct drm_device *drm = data;
> +	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +	ret = mtk_dsi_encoder_init(drm, dsi);
> +	if (ret)
> +		return ret;
> +
> +	return device_reset_optional(dev);
> +}
> +
> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
> +			   void *data)
> +{
> +	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +	drm_encoder_cleanup(&dsi->encoder);
> +}
> +
> +static const struct component_ops mtk_dsi_component_ops = {
> +	.bind = mtk_dsi_bind,
> +	.unbind = mtk_dsi_unbind,
> +};
> +
>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>   			       struct mipi_dsi_device *device)
>   {
>   	struct mtk_dsi *dsi = host_to_dsi(host);
> +	struct device *dev = host->dev;
> +	int ret;
>   
>   	dsi->lanes = device->lanes;
>   	dsi->format = device->format;
>   	dsi->mode_flags = device->mode_flags;
> +	dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> +	if (IS_ERR(dsi->next_bridge))
> +		return PTR_ERR(dsi->next_bridge);


Here we have implicit assumption that port node (0,0) points always to 
the 'device'. I guess it is true for now, but could bite someday. Anyway 
improving it? would require adding some additional helper for getting 
bridge based on mipi_dsi_device and should be done in separate patchset.


> +
> +	drm_bridge_add(&dsi->bridge);
> +
> +	ret = component_add(host->dev, &mtk_dsi_component_ops);
> +	if (ret) {
> +		DRM_ERROR("failed to add dsi_host component: %d\n", ret);
> +		drm_bridge_remove(&dsi->bridge);
> +		return ret;
> +	}
>   
>   	return 0;
>   }
>   
> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
> +			       struct mipi_dsi_device *device)
> +{
> +	struct mtk_dsi *dsi = host_to_dsi(host);
> +
> +	drm_bridge_remove(&dsi->bridge);
> +	component_del(host->dev, &mtk_dsi_component_ops);


Order should be reversed.

With this fixed:

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>


Regards

Andrzej


> +	return 0;
> +}
> +
>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>   {
>   	int ret;
> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>   
>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>   	.attach = mtk_dsi_host_attach,
> +	.detach = mtk_dsi_host_detach,
>   	.transfer = mtk_dsi_host_transfer,
>   };
>   
> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> -{
> -	int ret;
> -
> -	ret = drm_simple_encoder_init(drm, &dsi->encoder,
> -				      DRM_MODE_ENCODER_DSI);
> -	if (ret) {
> -		DRM_ERROR("Failed to encoder init to drm\n");
> -		return ret;
> -	}
> -
> -	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> -
> -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> -				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -	if (ret)
> -		goto err_cleanup_encoder;
> -
> -	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> -	if (IS_ERR(dsi->connector)) {
> -		DRM_ERROR("Unable to create bridge connector\n");
> -		ret = PTR_ERR(dsi->connector);
> -		goto err_cleanup_encoder;
> -	}
> -	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> -
> -	return 0;
> -
> -err_cleanup_encoder:
> -	drm_encoder_cleanup(&dsi->encoder);
> -	return ret;
> -}
> -
> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> -{
> -	int ret;
> -	struct drm_device *drm = data;
> -	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -	ret = mtk_dsi_encoder_init(drm, dsi);
> -	if (ret)
> -		return ret;
> -
> -	return device_reset_optional(dev);
> -}
> -
> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
> -			   void *data)
> -{
> -	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -	drm_encoder_cleanup(&dsi->encoder);
> -}
> -
> -static const struct component_ops mtk_dsi_component_ops = {
> -	.bind = mtk_dsi_bind,
> -	.unbind = mtk_dsi_unbind,
> -};
> -
>   static int mtk_dsi_probe(struct platform_device *pdev)
>   {
>   	struct mtk_dsi *dsi;
>   	struct device *dev = &pdev->dev;
> -	struct drm_panel *panel;
>   	struct resource *regs;
>   	int irq_num;
>   	int ret;
> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -					  &panel, &dsi->next_bridge);
> -	if (ret)
> -		goto err_unregister_host;
> -
> -	if (panel) {
> -		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
> -		if (IS_ERR(dsi->next_bridge)) {
> -			ret = PTR_ERR(dsi->next_bridge);
> -			goto err_unregister_host;
> -		}
> -	}
> -
>   	dsi->driver_data = of_device_get_match_data(dev);
>   
>   	dsi->engine_clk = devm_clk_get(dev, "engine");
> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>   	dsi->bridge.of_node = dev->of_node;
>   	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>   
> -	drm_bridge_add(&dsi->bridge);
> -
> -	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
> -	if (ret) {
> -		dev_err(&pdev->dev, "failed to add component: %d\n", ret);
> -		goto err_unregister_host;
> -	}
> -
>   	return 0;
>   
>   err_unregister_host:
> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>   	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>   
>   	mtk_output_dsi_disable(dsi);
> -	drm_bridge_remove(&dsi->bridge);
> -	component_del(&pdev->dev, &mtk_dsi_component_ops);
>   	mipi_dsi_host_unregister(&dsi->host);
>   
>   	return 0;


From tan.shaopeng at fujitsu.com  Tue Jan  4 01:53:21 2022
From: tan.shaopeng at fujitsu.com (tan.shaopeng at fujitsu.com)
Date: Tue, 4 Jan 2022 09:53:21 +0000
Subject: About resctrl code rebase
In-Reply-To: <TYAPR01MB6330D06BD91DF10852E763028B6F9@TYAPR01MB6330.jpnprd01.prod.outlook.com>
References: <TYAPR01MB6330CE3CB67CF8F602D44D098BCD9@TYAPR01MB6330.jpnprd01.prod.outlook.com>
 <97164928-e2d7-fd3f-e063-9174b028ed65@arm.com>
 <TYAPR01MB6330F3B97D23A214FB4DA7C48B619@TYAPR01MB6330.jpnprd01.prod.outlook.com>
 <TYAPR01MB6330606C7AA6A633806D90118B6A9@TYAPR01MB6330.jpnprd01.prod.outlook.com>
 <Ya50FGj6ar7lVQ7P@robh.at.kernel.org>
 <TYAPR01MB6330D06BD91DF10852E763028B6F9@TYAPR01MB6330.jpnprd01.prod.outlook.com>
Message-ID: <TYAPR01MB633063F783F8BAD9616EA4808B4A9@TYAPR01MB6330.jpnprd01.prod.outlook.com>

Hi Rob,


> > On Fri, Dec 03, 2021 at 07:58:28AM +0000, tan.shaopeng at fujitsu.com wrote:
> > > Hi James
> > >
> > > > > On 01/09/2021 09:35, tan.shaopeng at fujitsu.com wrote:
> > > > > >> As you known, Fujitsu is implementing a feature that add
> > > > > >> A64FX's cache control function into resctrl.
> > > > >
> > > > > >> Fujitsu will implement this feature base on your rebased code.
> > > > > >> I think the commit of refactoring arch/x86 implementation of
> > > > > >> resctrl has been merged into the x86/cache branch.
> > > > > >>
> > https://lore.kernel.org/lkml/162871088112.395.12879267279872673224.
> > > > > >> ti
> > > > > >> p-bot2 at tip-bot2/
> > > > >
> > > > > I'm afraid this was only a small part of it.
> > > > >
> > > > > I've also posted the next series here:
> > > > > https://lore.kernel.org/lkml/20210729223610.29373-1-james.morse@
> > > > > ar
> > > > > m.co
> > > > > m
> > > > > /
> > > > >
> > > > > and there are a couple more after that.
> > > >
> > > > When will you post patches v3? And are there any other patches after
> this?
> > > >
> > > > > >> I would like to know whether you have rebased these codes
> > > > > >> that move the common parts of multiple architectures to
> somewhere.
> > > > > >> And where is the rebase code?
> > > > > >> In addition, when will you release the latest MPAM patch?
> > > > >
> > > > > I will keep posting 'the next part' of the x86 changes once the
> > > > > earlier part is reviewed.
> > > > > (please help!)
> > > > >
> > > > > I can't push the latest branch until the ACPI spec is published,
> > > > > but I hope that will happen this month.
> > > >
> > > > Could you tell me when you are planning to push the rebase code?
> > > > Is there anything I can do for you?
> > >
> > > I look forward to hearing from you.
> >
> > There's a branch published here[1].
> >
> > Rob
> >
> > [1]
> > https://git.kernel.org/pub/scm/linux/kernel/git/morse/linux.git/log/?h
> > =mpa
> > m/snapshot/v5.15
> 
Could you tell me when will you post these codes on kernel development community?

Best regards
Tan Shaopeng


From gankulkarni at os.amperecomputing.com  Tue Jan  4 01:53:42 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 4 Jan 2022 15:23:42 +0530
Subject: [PATCH v5 34/69] KVM: arm64: nv: Configure HCR_EL2 for nested
 virtualization
In-Reply-To: <87o84rvnyo.wl-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-35-maz@kernel.org>
 <bbf31da5-ca1b-7499-e23c-9b5281ca7901@os.amperecomputing.com>
 <87o84rvnyo.wl-maz@kernel.org>
Message-ID: <2e8f9806-f11b-4aee-db44-8a5a0f30cc6d@os.amperecomputing.com>



On 04-01-2022 03:09 pm, Marc Zyngier wrote:
> On Tue, 04 Jan 2022 08:53:42 +0000,
> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>
>>
>>
>> On 30-11-2021 01:31 am, Marc Zyngier wrote:
>>> From: Jintack Lim <jintack.lim at linaro.org>
>>>
>>> We enable nested virtualization by setting the HCR NV and NV1 bit.
>>>
>>> When the virtual E2H bit is set, we can support EL2 register accesses
>>> via EL1 registers from the virtual EL2 by doing trap-and-emulate. A
>>> better alternative, however, is to allow the virtual EL2 to access EL2
>>> register states without trap. This can be easily achieved by not traping
>>> EL1 registers since those registers already have EL2 register states.
>>>
>>> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>> ---
>>>    arch/arm64/include/asm/kvm_arm.h |  1 +
>>>    arch/arm64/kvm/hyp/vhe/switch.c  | 38 +++++++++++++++++++++++++++++---
>>>    2 files changed, 36 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
>>> index 68af5509e4b0..b8a0d410035b 100644
>>> --- a/arch/arm64/include/asm/kvm_arm.h
>>> +++ b/arch/arm64/include/asm/kvm_arm.h
>>> @@ -87,6 +87,7 @@
>>>    			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
>>>    			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
>>>    			 HCR_FMO | HCR_IMO | HCR_PTW )
>>> +#define HCR_GUEST_NV_FILTER_FLAGS (HCR_ATA | HCR_API | HCR_APK | HCR_RW)
>>>    #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
>>>    #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
>>>    #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
>>> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
>>> index 57f43e607819..da80c969e623 100644
>>> --- a/arch/arm64/kvm/hyp/vhe/switch.c
>>> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
>>> @@ -36,9 +36,41 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>>>    	u64 hcr = vcpu->arch.hcr_el2;
>>>    	u64 val;
>>>    -	/* Trap VM sysreg accesses if an EL2 guest is not using
>>> VHE. */
>>> -	if (vcpu_mode_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
>>> -		hcr |= HCR_TVM | HCR_TRVM;
>>> +	if (is_hyp_ctxt(vcpu)) {
>>> +		hcr |= HCR_NV;
>>> +
>>> +		if (!vcpu_el2_e2h_is_set(vcpu)) {
>>> +			/*
>>> +			 * For a guest hypervisor on v8.0, trap and emulate
>>> +			 * the EL1 virtual memory control register accesses.
>>> +			 */
>>> +			hcr |= HCR_TVM | HCR_TRVM | HCR_NV1;
>>> +		} else {
>>> +			/*
>>> +			 * For a guest hypervisor on v8.1 (VHE), allow to
>>> +			 * access the EL1 virtual memory control registers
>>> +			 * natively. These accesses are to access EL2 register
>>> +			 * states.
>>> +			 * Note that we still need to respect the virtual
>>> +			 * HCR_EL2 state.
>>> +			 */
>>> +			u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
>>> +
>>> +			vhcr_el2 &= ~HCR_GUEST_NV_FILTER_FLAGS;
>>
>> Why HCR_RW is cleared here, May I know please?
> 
> Good question. That's clearly a leftover from an early rework. It
> really doesn't matter, as we are merging the guest's configuration
> into the host's, and the host already has HCR_EL2.RW set.

Thanks, I too felt the same.

x>
> What HCR_GUEST_NV_FILTER_FLAGS should contain is only the bits we
> don't want to deal with at this stage of the NV support. I'll fix that
> for the next round.
> 
sure, thanks.

> Thanks,
> 
> 	M.
> 

Thanks,
Ganapat


From yu.tu at amlogic.com  Tue Jan  4 01:57:03 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 17:57:03 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
Message-ID: <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>

Hi Jerome,
	Thank you very much for your reply.

On 2022/1/3 20:40, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Using the common Clock code to describe the UART baud rate clock makes
>> it easier for the UART driver to be compatible with the baud rate
>> requirements of the UART IP on different meson chips
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/Kconfig      |   1 +
>>   drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>   2 files changed, 257 insertions(+), 55 deletions(-)
>>
>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>> index 780908d43557..32e238173036 100644
>> --- a/drivers/tty/serial/Kconfig
>> +++ b/drivers/tty/serial/Kconfig
>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>   config SERIAL_MESON
>>   	tristate "Meson serial port support"
>>   	depends on ARCH_MESON
>> +	depends on COMMON_CLK
>>   	select SERIAL_CORE
>>   	help
>>   	  This enables the driver for the on-chip UARTs of the Amlogic
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 99efe62a1507..07eb1f40aaaa 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,21 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct uart_port	port;
>> +	struct clk		*pclk;
>> +	struct clk		*baud_clk;
>> +	struct clk_divider	baud_div;
>> +	struct clk_mux		use_xtal_mux;
>> +	struct clk_mux		xtal_clk_sel_mux;
>> +	struct clk_mux		xtal2_clk_sel_mux;
>> +	struct clk_fixed_factor	xtal_div2;
>> +	struct clk_fixed_factor	xtal_div3;
>> +	struct clk_fixed_factor	clk81_div4;
> 
> Keeping all these internal elements around is not useful since they are
> registered using devm_
> 
I'm sorry. I don't know what you mean. That's exactly what you said, but 
what's wrong, I don't understand. Do you have any better suggestions, 
please specify specific points, preferably give examples.
>> +	bool			no_clk81_input;
> 
> What is this ?
> 
To distinguish between clK81 and XTAL.
>> +	bool			has_xtal_clk_sel;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>   static int meson_uart_startup(struct uart_port *port)
>>   {
>>   	u32 val;
>> -	int ret = 0;
>> +	int ret;
>>   
>> -	val = readl(port->membase + AML_UART_CONTROL);
>> -	val |= AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> -	val &= ~AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> +	meson_uart_reset(port);
>>   
>> +	val = readl(port->membase + AML_UART_CONTROL);
>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>   	writel(val, port->membase + AML_UART_CONTROL);
>>   
>> @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
> 
> This check shows that previous code assumed bit 24 was left untouched
> Below you can see that GXBB and newer used the XTAL path while older
> used the other
> 
> Your change makes this dynamic which is another "unexpected" change.
> Please make the bit 24 mux RO to start with so the behavior remains unchanged
> for older SoCs.
I agree with what you say, and I will correct it.
> 
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>> +	clk_disable_unprepare(private_data->pclk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->pclk);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret) {
>> +		clk_disable_unprepare(private_data->pclk);
>> +		return ret;
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> +static int meson_uart_register_clk(struct uart_port *port,
>> +				   const char *name_suffix,
>> +				   const struct clk_parent_data *parent_data,
>> +				   unsigned int num_parents,
>> +				   const struct clk_ops *ops,
>> +				   struct clk_hw *hw)
>>   {
>> -	struct clk *clk = NULL;
>> +	struct clk_init_data init = { };
>> +	char clk_name[32];
>>   	int ret;
>>   
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 name_suffix);
>>   
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> +	init.name = clk_name;
>> +	init.ops = ops;
>> +	init.flags = CLK_SET_RATE_PARENT;
>> +	init.parent_data = parent_data;
>> +	init.num_parents = num_parents;
>> +
>> +	hw->init = &init;
>>   
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> +	ret = devm_clk_hw_register(port->dev, hw);
>> +	if (ret)
>> +		return dev_err_probe(port->dev, ret,
>> +				     "Failed to register the '%s' clock\n",
>> +				     clk_name);
>>   
>> -	return clk;
>> +	return ret;
>>   }
>>   
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> -{
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> +static int meson_uart_probe_clocks(struct uart_port *port,
>> +				   bool register_clk81_div4)
>> +{
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>> +	struct clk_parent_data baud_div_parent = { };
>> +	struct clk *clk_baud, *clk_xtal;
>> +	int ret;
>>   
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud))
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>> +				     "Failed to get the 'baud' clock\n");
>>   
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	private_data->xtal_div3.mult = 1;
>> +	private_data->xtal_div3.div = 3;
>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>> +				      1, &clk_fixed_factor_ops,
>> +				      &private_data->xtal_div3.hw);
>> +	if (ret)
>> +		return ret;
>>   
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +	if (register_clk81_div4) {
> 
> Clock dividers represent HW elements. The presence of an HW element cannot
> dependent on the current of the input clocks. There is no way this is right
> 
>> +		private_data->clk81_div4.mult = 1;
>> +		private_data->clk81_div4.div = 4;
>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>> +					      &clk81_div_parent, 1,
>> +					      &clk_fixed_factor_ops,
>> +					      &private_data->clk81_div4.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
> 
> This is only going to be used on meson8 and older. Worst case it should depend
> on this compatible but I don't think this would be right here.
> 
> IMO, this shows that the UART "baud" input was actually fed by a
> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
> 
> So instead of registering what I suspect to be a fake element, the
> meson8 clock controller driver and DT should be fixed a this should go away.
> 
Virtually all UART controllers are supported, but they are not used 
after Meson8. So the description is more reasonable in UART driver.
>> +	}
>>   
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	if (private_data->has_xtal_clk_sel) {
>> +		private_data->xtal_div2.mult = 1;
>> +		private_data->xtal_div2.div = 2;
>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>> +					      &xtal_div_parent, 1,
>> +					      &clk_fixed_factor_ops,
>> +					      &private_data->xtal_div2.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>> +
>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>> +		private_data->xtal_clk_sel_mux.shift = 26;
>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>> +					      xtal_clk_sel_mux_parents,
>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>> +					      &clk_mux_ops,
>> +					      &private_data->xtal_clk_sel_mux.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>> +
>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>> +					      xtal2_clk_sel_mux_parents,
>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>> +					      &clk_mux_ops,
>> +					      &private_data->xtal2_clk_sel_mux.hw);
>> +		if (ret)
>> +			return ret;
>> +
>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>> +	} else {
>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
> 
> Well the above is a bit over-complicated. If I summarize:
> 
> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
> 0 according to the documentation.
> 
> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
> selects which of these dividers is used.
> 
> So the above could be replaced with a single divider covering bits 26 and 27
> with the following divider table { 2, 2, 1, 3 }. The divider should use
> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
> variant like this, including the older ones.
> 
As you say, the way you say it is complicated. I think you're 
complicating things.I don't understand what you're trying to achieve.
Can you be more specific?

> The only information you need to carry if whether or not you want to
> make this divider modifiable. This means using the dt data to store
> clk_div_ops or clk_div_ro_ops pointer.
> 
> To avoid changing the behavior of the older platforms in this patch, I would
> suggest to make everything use clk_div_ro_ops first, and make another
> patch to use clk_div_ops if necessary.
> 
> 
>> +	}
>> +
>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>> +	private_data->use_xtal_mux.mask = 0x1;
>> +	private_data->use_xtal_mux.shift = 24;
>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>> +				      &clk_mux_ops,
> 
> Use RO ops here to start with.
> You can make this writable with another patch explicitly describing the change.
I agree with what you say, and I will correct it.
> 
>> +				      &private_data->use_xtal_mux.hw);
>> +	if (ret)
>> +		return ret;
>> +
>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>> +
>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>> +	private_data->baud_div.shift = 0;
>> +	private_data->baud_div.width = 23;
>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>> +	ret = meson_uart_register_clk(port, "baud_div",
>> +				      &baud_div_parent, 1,
>> +				      &clk_divider_ops,
>> +				      &private_data->baud_div.hw);
>> +	if (ret)
>> +		return ret;
>> +
>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>> +						     &private_data->baud_div.hw,
>> +						     "baud_rate");
> 
> There is a problem with this function in CCF. It will pin the driver to
> itself, making it unremovable. It is an ongoing topic. For now, just use
> "hw->clk" to get the struct *clk.
> 
>> +	if (IS_ERR(private_data->baud_clk))
>> +		return dev_err_probe(port->dev,
> 
> I don't think anything can defer here, so dev_err_probe() is not
> necessary I think
> 
I agree with what you say, and I will correct it.
>> +				     PTR_ERR(private_data->baud_clk),
>> +				     "Failed to request the 'baud_rate' clock\n");
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem, *res_irq;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	bool register_clk81_div4;
>>   	struct uart_port *port;
>>   	int ret = 0;
>>   	int id = -1;
>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   		return -EBUSY;
>>   	}
>>   
>> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
>> -	if (!port)
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>>   		return -ENOMEM;
>>   
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->has_xtal_clk_sel = true;
>> +
>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>> +	if (IS_ERR(clk_baud))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>> +				     "Failed to get the 'baud' clock\n");
>> +
>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>> +	if (IS_ERR(clk_xtal))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
> 
> This is second time you call devm_clk_get() on these clocks. One
> instance has to go away
> 
I agree with what you say, and I will correct it.
>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>> +
> 
> The above is a ugly way to distinguish the meson8 (32bit) SoC family
> from the rest. This definitely not the way to achieve it.
> 
> The right is the compatible data but here I think it is not
> necessary. The clock input should be fixed.
> 
>> +	port = &private_data->port;
>> +
>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> -
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>>   	port->mapsize = resource_size(res_mem);
>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = 64;
>> +	port->uartclk = clk_get_rate(clk_baud);
>> +	port->private_data = private_data;
>> +
>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>> +	if (ret)
>> +		return ret;
>>   
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxbb-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxl-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-g12a-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-s4-uart",
>> +		.data = (void *)true,
>> +	},
>> +	/*
>> +	 * deprecated, don't use anymore because it doesn't differentiate
>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>> +	 */
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)false,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From angelogioacchino.delregno at collabora.com  Tue Jan  4 01:59:54 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue,  4 Jan 2022 10:59:54 +0100
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
Message-ID: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>

DRM bridge drivers are now attaching their DSI device at probe time,
which requires us to register our DSI host in order to let the bridge
to probe: this recently started producing an endless -EPROBE_DEFER
loop on some machines that are using external bridges, like the
parade-ps8640, found on the ACER Chromebook R13.

Now that the DSI hosts/devices probe sequence is documented, we can
do adjustments to the mtk_dsi driver as to both fix now and make sure
to avoid this situation in the future: for this, following what is
documented in drm_bridge.c, move the mtk_dsi component_add() to the
mtk_dsi_ops.attach callback and delete it in the detach callback;
keeping in mind that we are registering a drm_bridge for our DSI,
which is only used/attached if the DSI Host is bound, it wouldn't
make sense to keep adding our bridge at probe time (as it would
be useless to have it if mtk_dsi_ops.attach() fails!), so also move
that one to the dsi host attach function (and remove it in detach).

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
 1 file changed, 84 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..bced4c7d668e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
 	mtk_dsi_poweroff(dsi);
 }
 
+static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
+{
+	int ret;
+
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		DRM_ERROR("Failed to encoder init to drm\n");
+		return ret;
+	}
+
+	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
+
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret)
+		goto err_cleanup_encoder;
+
+	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
+	if (IS_ERR(dsi->connector)) {
+		DRM_ERROR("Unable to create bridge connector\n");
+		ret = PTR_ERR(dsi->connector);
+		goto err_cleanup_encoder;
+	}
+	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
+
+	return 0;
+
+err_cleanup_encoder:
+	drm_encoder_cleanup(&dsi->encoder);
+	return ret;
+}
+
+static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	int ret;
+	struct drm_device *drm = data;
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	ret = mtk_dsi_encoder_init(drm, dsi);
+	if (ret)
+		return ret;
+
+	return device_reset_optional(dev);
+}
+
+static void mtk_dsi_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	drm_encoder_cleanup(&dsi->encoder);
+}
+
+static const struct component_ops mtk_dsi_component_ops = {
+	.bind = mtk_dsi_bind,
+	.unbind = mtk_dsi_unbind,
+};
+
 static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 			       struct mipi_dsi_device *device)
 {
 	struct mtk_dsi *dsi = host_to_dsi(host);
+	struct device *dev = host->dev;
+	int ret;
 
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
+	dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
+	if (IS_ERR(dsi->next_bridge))
+		return PTR_ERR(dsi->next_bridge);
+
+	drm_bridge_add(&dsi->bridge);
+
+	ret = component_add(host->dev, &mtk_dsi_component_ops);
+	if (ret) {
+		DRM_ERROR("failed to add dsi_host component: %d\n", ret);
+		drm_bridge_remove(&dsi->bridge);
+		return ret;
+	}
 
 	return 0;
 }
 
+static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
+			       struct mipi_dsi_device *device)
+{
+	struct mtk_dsi *dsi = host_to_dsi(host);
+
+	component_del(host->dev, &mtk_dsi_component_ops);
+	drm_bridge_remove(&dsi->bridge);
+	return 0;
+}
+
 static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
 {
 	int ret;
@@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 
 static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.attach = mtk_dsi_host_attach,
+	.detach = mtk_dsi_host_detach,
 	.transfer = mtk_dsi_host_transfer,
 };
 
-static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
-{
-	int ret;
-
-	ret = drm_simple_encoder_init(drm, &dsi->encoder,
-				      DRM_MODE_ENCODER_DSI);
-	if (ret) {
-		DRM_ERROR("Failed to encoder init to drm\n");
-		return ret;
-	}
-
-	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
-
-	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
-				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-	if (ret)
-		goto err_cleanup_encoder;
-
-	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
-	if (IS_ERR(dsi->connector)) {
-		DRM_ERROR("Unable to create bridge connector\n");
-		ret = PTR_ERR(dsi->connector);
-		goto err_cleanup_encoder;
-	}
-	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
-
-	return 0;
-
-err_cleanup_encoder:
-	drm_encoder_cleanup(&dsi->encoder);
-	return ret;
-}
-
-static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
-{
-	int ret;
-	struct drm_device *drm = data;
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	ret = mtk_dsi_encoder_init(drm, dsi);
-	if (ret)
-		return ret;
-
-	return device_reset_optional(dev);
-}
-
-static void mtk_dsi_unbind(struct device *dev, struct device *master,
-			   void *data)
-{
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	drm_encoder_cleanup(&dsi->encoder);
-}
-
-static const struct component_ops mtk_dsi_component_ops = {
-	.bind = mtk_dsi_bind,
-	.unbind = mtk_dsi_unbind,
-};
-
 static int mtk_dsi_probe(struct platform_device *pdev)
 {
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
-	struct drm_panel *panel;
 	struct resource *regs;
 	int irq_num;
 	int ret;
@@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &panel, &dsi->next_bridge);
-	if (ret)
-		goto err_unregister_host;
-
-	if (panel) {
-		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
-		if (IS_ERR(dsi->next_bridge)) {
-			ret = PTR_ERR(dsi->next_bridge);
-			goto err_unregister_host;
-		}
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.of_node = dev->of_node;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
-	drm_bridge_add(&dsi->bridge);
-
-	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to add component: %d\n", ret);
-		goto err_unregister_host;
-	}
-
 	return 0;
 
 err_unregister_host:
@@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
 	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
 
 	mtk_output_dsi_disable(dsi);
-	drm_bridge_remove(&dsi->bridge);
-	component_del(&pdev->dev, &mtk_dsi_component_ops);
 	mipi_dsi_host_unregister(&dsi->host);
 
 	return 0;
-- 
2.33.1



From philippe.cornu at foss.st.com  Tue Jan  4 02:22:16 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:22:16 +0100
Subject: [PATCH 1/5] drm/stm: ltdc: switch to regmap
In-Reply-To: <20211215214738.19946-1-yannick.fertre@foss.st.com>
References: <20211215214738.19946-1-yannick.fertre@foss.st.com>
Message-ID: <71173a7e-a367-f5ea-1b6e-97e73f69a7da@foss.st.com>



On 12/15/21 10:47 PM, Yannick Fertre wrote:
> Replace the legacy register access by regmap API.
> 
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 138 ++++++++++++++++++-------------------
>   drivers/gpu/drm/stm/ltdc.h |   1 +
>   2 files changed, 68 insertions(+), 71 deletions(-)
> 


Hi Yannick,
many thanks for your patch.
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From angelogioacchino.delregno at collabora.com  Tue Jan  4 02:23:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 11:23:49 +0100
Subject: [PATCH v1 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20211227083641.12538-3-axe.yang@mediatek.com>
References: <20211227083641.12538-1-axe.yang@mediatek.com>
 <20211227083641.12538-3-axe.yang@mediatek.com>
Message-ID: <a0eec26b-0148-a208-be67-888766b88137@collabora.com>

Il 27/12/21 09:36, Axe Yang ha scritto:
> If cap-sdio-async-int flag is set in host dts node, parse EAI
> information from SDIO CCCR interrupt externsion segment. If async
> interrupt is supported by SDIO card then send command to card to
> enable it and set enable_async_int flag in sdio_cccr structure to 1.
> The parse flow is implemented in sdio_read_cccr().
> 
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/mmc/core/host.c  |  2 ++
>   drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
>   include/linux/mmc/card.h |  3 ++-
>   include/linux/mmc/host.h |  1 +
>   include/linux/mmc/sdio.h |  5 +++++
>   5 files changed, 27 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
> index d4683b1d263f..7ad60fab099a 100644
> --- a/drivers/mmc/core/host.c
> +++ b/drivers/mmc/core/host.c
> @@ -401,6 +401,8 @@ int mmc_of_parse(struct mmc_host *host)
>   	if (device_property_read_bool(dev, "no-mmc-hs400"))
>   		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
>   				 MMC_CAP2_HS400_ES);
> +	if (device_property_read_bool(dev, "cap-sdio-async-int"))
> +		host->caps2 |= MMC_CAP2_SDIO_ASYNC_INT;
>   
>   	/* Must be after "non-removable" check */
>   	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
> diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
> index 68edf7a615be..335e4ada733a 100644
> --- a/drivers/mmc/core/sdio.c
> +++ b/drivers/mmc/core/sdio.c
> @@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
>   				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
>   			if (data & SDIO_DRIVE_SDTD)
>   				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
> +
> +			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_INT) {
> +				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
> +						       &data);
> +				if (ret)
> +					goto out;
> +
> +				if (data & SDIO_INTERRUPT_EXT_SAI) {
> +					data |= SDIO_INTERRUPT_EXT_EAI;
> +					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
> +							       data, NULL);
> +					if (ret)
> +						goto out;
> +
> +					card->cccr.enable_async_int = 1;
> +				}
> +			}
>   		}
>   
>   		/* if no uhs mode ensure we check for high speed */
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 37f975875102..b0deb8ca8eeb 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -219,7 +219,8 @@ struct sdio_cccr {
>   				wide_bus:1,
>   				high_power:1,
>   				high_speed:1,
> -				disable_cd:1;
> +				disable_cd:1,
> +				enable_async_int:1;
>   };
>   
>   struct sdio_cis {
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 0c0c9a0fdf57..60c8ebe1a5e8 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -399,6 +399,7 @@ struct mmc_host {
>   #define MMC_CAP2_CRYPTO		0
>   #endif
>   #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
> +#define MMC_CAP2_SDIO_ASYNC_INT	(1 << 29)	/* SDIO host supports asynchronous interrupt */
>   
>   	int			fixed_drv_type;	/* fixed driver type for non-removable media */
>   
> diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
> index 2a05d1ac4f0e..1ef400f28642 100644
> --- a/include/linux/mmc/sdio.h
> +++ b/include/linux/mmc/sdio.h
> @@ -159,6 +159,11 @@
>   #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
>   #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
>   #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
> +
> +#define SDIO_CCCR_INTERRUPT_EXT	0x16
> +#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
> +#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
> +
>   /*
>    * Function Basic Registers (FBR)
>    */
> 




From philippe.cornu at foss.st.com  Tue Jan  4 02:24:02 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:24:02 +0100
Subject: [PATCH 2/5] drm/stm: ltdc: add YCbCr 422 output support
In-Reply-To: <20211215214750.20105-1-yannick.fertre@foss.st.com>
References: <20211215214750.20105-1-yannick.fertre@foss.st.com>
Message-ID: <e324c3cc-6109-7862-1cdf-2f8e3cc50cca@foss.st.com>



On 12/15/21 10:47 PM, Yannick Fertre wrote:
> LTDC 40100 hw version supports the YCbCr 422 output,
> reducing the output pins from 24 to 16. This feature
> is useful for some external devices like HDMI bridges.
> 
> Both ITU-R BT.601 & ITU-R BT.709 are supported.
> 
> It is also possible to choose the chrominance order between
> * Cb is output first (Y0Cb, then Y1Cr, Y2Cb and so on).
> * Cr is output first (Y0Cr, then Y1Cb, Y2Cr and so on).
> 
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 44 +++++++++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/stm/ltdc.h |  1 +
>   2 files changed, 44 insertions(+), 1 deletion(-)
> 

Hi Yannick,
many thanks for your patch.
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From gankulkarni at os.amperecomputing.com  Tue Jan  4 02:24:04 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 4 Jan 2022 15:54:04 +0530
Subject: [PATCH v5 36/69] KVM: arm64: nv: Filter out unsupported features
 from ID regs
In-Reply-To: <20211129200150.351436-37-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-37-maz@kernel.org>
Message-ID: <8102049c-7dad-e52b-482b-c1a1fd6b53fd@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> As there is a number of features that we either can't support,
> or don't want to support right away with NV, let's add some
> basic filtering so that we don't advertize silly things to the
> EL2 guest.
> 
> Whilst we are at it, avertize ARMv8.4-TTL as well as ARMv8.5-GTG.
> 

Typo: advertize.

> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_nested.h |   6 ++
>   arch/arm64/kvm/nested.c             | 152 ++++++++++++++++++++++++++++
>   arch/arm64/kvm/sys_regs.c           |   4 +-
>   arch/arm64/kvm/sys_regs.h           |   2 +
>   4 files changed, 163 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 07c15f51cf86..026ddaad972c 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -67,4 +67,10 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
>   extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
>   extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
>   
> +struct sys_reg_params;
> +struct sys_reg_desc;
> +
> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
> +			  const struct sys_reg_desc *r);
> +
>   #endif /* __ARM64_KVM_NESTED_H */
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 42a96c8d2adc..19b674983e13 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -20,6 +20,10 @@
>   #include <linux/kvm_host.h>
>   
>   #include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
> +#include <asm/sysreg.h>
> +
> +#include "sys_regs.h"
>   
>   /*
>    * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
> @@ -38,3 +42,151 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
>   
>   	return -EINVAL;
>   }
> +
> +/*
> + * Our emulated CPU doesn't support all the possible features. For the
> + * sake of simplicity (and probably mental sanity), wipe out a number
> + * of feature bits we don't intend to support for the time being.
> + * This list should get updated as new features get added to the NV
> + * support, and new extension to the architecture.
> + */
> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
> +			  const struct sys_reg_desc *r)
> +{
> +	u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
> +			 (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
> +	u64 val, tmp;
> +
> +	if (!nested_virt_in_use(v))
> +		return;
> +
> +	val = p->regval;
> +
> +	switch (id) {
> +	case SYS_ID_AA64ISAR0_EL1:
> +		/* Support everything but O.S. and Range TLBIs */
> +		val &= ~(FEATURE(ID_AA64ISAR0_TLB)	|
> +			 GENMASK_ULL(27, 24)		|
> +			 GENMASK_ULL(3, 0));
> +		break;
> +
> +	case SYS_ID_AA64ISAR1_EL1:
> +		/* Support everything but PtrAuth and Spec Invalidation */
> +		val &= ~(GENMASK_ULL(63, 56)		|
> +			 FEATURE(ID_AA64ISAR1_SPECRES)	|
> +			 FEATURE(ID_AA64ISAR1_GPI)	|
> +			 FEATURE(ID_AA64ISAR1_GPA)	|
> +			 FEATURE(ID_AA64ISAR1_API)	|
> +			 FEATURE(ID_AA64ISAR1_APA));
> +		break;
> +
> +	case SYS_ID_AA64PFR0_EL1:
> +		/* No AMU, MPAM, S-EL2, RAS or SVE */
> +		val &= ~(GENMASK_ULL(55, 52)		|
> +			 FEATURE(ID_AA64PFR0_AMU)	|
> +			 FEATURE(ID_AA64PFR0_MPAM)	|
> +			 FEATURE(ID_AA64PFR0_SEL2)	|
> +			 FEATURE(ID_AA64PFR0_RAS)	|
> +			 FEATURE(ID_AA64PFR0_SVE)	|
> +			 FEATURE(ID_AA64PFR0_EL3)	|
> +			 FEATURE(ID_AA64PFR0_EL2));
> +		/* 64bit EL2/EL3 only */
> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), 0b0001);
> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), 0b0001);
> +		break;
> +
> +	case SYS_ID_AA64PFR1_EL1:
> +		/* Only support SSBS */
> +		val &= FEATURE(ID_AA64PFR1_SSBS);
> +		break;
> +
> +	case SYS_ID_AA64MMFR0_EL1:
> +		/* Hide ECV, FGT, ExS, Secure Memory */
> +		val &= ~(GENMASK_ULL(63, 43)			|
> +			 FEATURE(ID_AA64MMFR0_TGRAN4_2)		|
> +			 FEATURE(ID_AA64MMFR0_TGRAN16_2)	|
> +			 FEATURE(ID_AA64MMFR0_TGRAN64_2)	|
> +			 FEATURE(ID_AA64MMFR0_SNSMEM));
> +
> +		/* Disallow unsupported S2 page sizes */
> +		switch (PAGE_SIZE) {
> +		case SZ_64K:
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0001);
> +			fallthrough;
> +		case SZ_16K:
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0001);
> +			fallthrough;
> +		case SZ_4K:
> +			/* Support everything */
> +			break;
> +		}
> +		/* Advertize supported S2 page sizes */
> +		switch (PAGE_SIZE) {
> +		case SZ_4K:
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0010);
> +			fallthrough;
> +		case SZ_16K:
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0010);
> +			fallthrough;
> +		case SZ_64K:
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64_2), 0b0010);
> +			break;
> +		}
> +		/* Cap PARange to 40bits */
> +		tmp = FIELD_GET(FEATURE(ID_AA64MMFR0_PARANGE), val);
> +		if (tmp > 0b0010) {
> +			val &= ~FEATURE(ID_AA64MMFR0_PARANGE);
> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE), 0b0010);
> +		}
> +		break;
> +
> +	case SYS_ID_AA64MMFR1_EL1:
> +		val &= (FEATURE(ID_AA64MMFR1_PAN)	|
> +			FEATURE(ID_AA64MMFR1_LOR)	|
> +			FEATURE(ID_AA64MMFR1_HPD)	|
> +			FEATURE(ID_AA64MMFR1_VHE)	|
> +			FEATURE(ID_AA64MMFR1_VMIDBITS));
> +		break;
> +
> +	case SYS_ID_AA64MMFR2_EL1:
> +		val &= ~(FEATURE(ID_AA64MMFR2_EVT)	|
> +			 FEATURE(ID_AA64MMFR2_BBM)	|
> +			 FEATURE(ID_AA64MMFR2_TTL)	|
> +			 GENMASK_ULL(47, 44)		|
> +			 FEATURE(ID_AA64MMFR2_ST)	|
> +			 FEATURE(ID_AA64MMFR2_CCIDX)	|
> +			 FEATURE(ID_AA64MMFR2_LVA));
> +
> +		/* Force TTL support */
> +		val |= FIELD_PREP(FEATURE(ID_AA64MMFR2_TTL), 0b0001);
> +		break;
> +
> +	case SYS_ID_AA64DFR0_EL1:
> +		/* Only limited support for PMU, Debug, BPs and WPs */
> +		val &= (FEATURE(ID_AA64DFR0_PMSVER)	|
> +			FEATURE(ID_AA64DFR0_WRPS)	|
> +			FEATURE(ID_AA64DFR0_BRPS)	|
> +			FEATURE(ID_AA64DFR0_DEBUGVER));
> +
> +		/* Cap PMU to ARMv8.1 */
> +		tmp = FIELD_GET(FEATURE(ID_AA64DFR0_PMUVER), val);
> +		if (tmp > 0b0100) {
> +			val &= ~FEATURE(ID_AA64DFR0_PMUVER);
> +			val |= FIELD_PREP(FEATURE(ID_AA64DFR0_PMUVER), 0b0100);
> +		}
> +		/* Cap Debug to ARMv8.1 */
> +		tmp = FIELD_GET(FEATURE(ID_AA64DFR0_DEBUGVER), val);
> +		if (tmp > 0b0111) {
> +			val &= ~FEATURE(ID_AA64DFR0_DEBUGVER);
> +			val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 0b0111);
> +		}
> +		break;
> +
> +	default:
> +		/* Unknown register, just wipe it clean */
> +		val = 0;
> +		break;
> +	}
> +
> +	p->regval = val;
> +}
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 9deedd5a058f..19b33ccb61b8 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1431,8 +1431,10 @@ static bool access_id_reg(struct kvm_vcpu *vcpu,
>   			  const struct sys_reg_desc *r)
>   {
>   	bool raz = sysreg_visible_as_raz(vcpu, r);
> +	bool ret = __access_id_reg(vcpu, p, r, raz);
>   
> -	return __access_id_reg(vcpu, p, r, raz);
> +	access_nested_id_reg(vcpu, p, r);
> +	return ret;
>   }
>   
>   static bool access_raz_id_reg(struct kvm_vcpu *vcpu,
> diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
> index cc0cc95a0280..d260c26b1834 100644
> --- a/arch/arm64/kvm/sys_regs.h
> +++ b/arch/arm64/kvm/sys_regs.h
> @@ -201,4 +201,6 @@ const struct sys_reg_desc *find_reg_by_id(u64 id,
>   	CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)),	\
>   	Op2(sys_reg_Op2(reg))
>   
> +#define FEATURE(x)	(GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
> +
>   #endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */

Thanks,
Ganapat


From philippe.cornu at foss.st.com  Tue Jan  4 02:24:30 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:24:30 +0100
Subject: [PATCH 3/5] drm/stm: ltdc: add per plane update support
In-Reply-To: <20211215214817.20310-1-yannick.fertre@foss.st.com>
References: <20211215214817.20310-1-yannick.fertre@foss.st.com>
Message-ID: <f40fef15-48ac-07fa-ef83-dac92a7461f9@foss.st.com>



On 12/15/21 10:48 PM, Yannick Fertre wrote:
> Recent ltdc hardware versions offer the ability
> to update a plane independently of others planes.
> This is could be useful especially if a plane is
> assigned to another OS.
> 
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 26 +++++++++++++++++++++++---
>   drivers/gpu/drm/stm/ltdc.h |  1 +
>   2 files changed, 24 insertions(+), 3 deletions(-)
> 

Hi Yannick,
many thanks for your patch.
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From philippe.cornu at foss.st.com  Tue Jan  4 02:27:11 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:27:11 +0100
Subject: [PATCH 4/5] drm/stm: ltdc: add support of flexible pixel formats
In-Reply-To: <20211215214835.20593-1-yannick.fertre@foss.st.com>
References: <20211215214835.20593-1-yannick.fertre@foss.st.com>
Message-ID: <ce982156-3e67-835d-4de6-bb3cfc70fe5b@foss.st.com>



On 12/15/21 10:48 PM, Yannick Fertre wrote:
> This feature allows the generation of any RGB pixel format.
> The list of supported formats is no longer linked to the
> register LXPFCR_PF, that the reason why a list of drm formats is
> defined for each display controller version.
> 
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 196 ++++++++++++++++++++++++++-----------
>   drivers/gpu/drm/stm/ltdc.h |   5 +-
>   2 files changed, 145 insertions(+), 56 deletions(-)
> 

Hi Yannick,
many thanks for your patch.
Nice hw feature.
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From philippe.cornu at foss.st.com  Tue Jan  4 02:27:56 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:27:56 +0100
Subject: [PATCH 5/5] drm/stm: ltdc: add support of ycbcr pixel formats
In-Reply-To: <20211215214843.20703-1-yannick.fertre@foss.st.com>
References: <20211215214843.20703-1-yannick.fertre@foss.st.com>
Message-ID: <5f198ef8-5db1-072f-9e8a-a80e0a6e9113@foss.st.com>



On 12/15/21 10:48 PM, Yannick Fertre wrote:
> This patch adds the following YCbCr input pixel formats on the latest
> LTDC hardware version:
> 
> 1 plane  (co-planar)  : YUYV, YVYU, UYVY, VYUY
> 2 planes (semi-planar): NV12, NV21
> 3 planes (full-planar): YU12=I420=DRM YUV420, YV12=DRM YVU420
> 
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 251 +++++++++++++++++++++++++++++++++++--
>   drivers/gpu/drm/stm/ltdc.h |   1 +
>   2 files changed, 245 insertions(+), 7 deletions(-)
> 

Hi Yannick,
many thanks for your patch.
Nice hw features!
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From linux at armlinux.org.uk  Tue Jan  4 02:34:31 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 10:34:31 +0000
Subject: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <BL3PR02MB8187165DAF278F65C8024567C94A9@BL3PR02MB8187.namprd02.prod.outlook.com>
References: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
 <E1mxqBh-00GWxo-51@rmk-PC.armlinux.org.uk>
 <20211216071513.6d1e0f55@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
 <YbtxGLrXoR9oHRmM@shell.armlinux.org.uk>
 <CAFcVECJeRwgjGsxtcGpMuA23nnmywsNkA2Yngk6aDK_JuVE3NQ@mail.gmail.com>
 <CAFcVEC+N0Y7ESFe-qcfpmkbPjRSvCJ=AOXoM6XSK6xGo=J1YNw@mail.gmail.com>
 <YdQMyfYU0wxHrT40@shell.armlinux.org.uk>
 <BL3PR02MB8187165DAF278F65C8024567C94A9@BL3PR02MB8187.namprd02.prod.outlook.com>
Message-ID: <YdQity1FDX0oNEN5@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 09:12:06AM +0000, Harini Katakam wrote:
> > -----Original Message-----
> > From: Russell King <linux at armlinux.org.uk>
> > Sent: Tuesday, January 4, 2022 2:31 PM
> > To: Harini Katakam <harinik at xilinx.com>
> > Cc: Jakub Kicinski <kuba at kernel.org>; Michal Simek <michals at xilinx.com>;
> > Radhey Shyam Pandey <radheys at xilinx.com>; Sean Anderson
> > <sean.anderson at seco.com>; David S. Miller <davem at davemloft.net>;
> > netdev <netdev at vger.kernel.org>; linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH CFT net-next 1/2] net: axienet: convert to phylink_pcs
> > 
> > On Tue, Jan 04, 2022 at 01:26:28PM +0530, Harini Katakam wrote:
> > > On Fri, Dec 17, 2021 at 1:55 PM Harini Katakam <harinik at xilinx.com> wrote:
> > > >
> > > > Hi Russell,
> > > >
> > > > On Fri, Dec 17, 2021 at 5:26 AM Russell King (Oracle)
> > > > <linux at armlinux.org.uk> wrote:
> > > > >
> > > > > On Thu, Dec 16, 2021 at 07:15:13AM -0800, Jakub Kicinski wrote:
> > > > > > On Thu, 16 Dec 2021 12:48:45 +0000 Russell King (Oracle) wrote:
> > > > > > > Convert axienet to use the phylink_pcs layer, resulting in it
> > > > > > > no longer being a legacy driver.
> > > > > > >
> > > > > > > One oddity in this driver is that lp->switch_x_sgmii controls
> > > > > > > whether we support switching between SGMII and 1000baseX.
> > > > > > > However, when clear, this also blocks updating the 1000baseX
> > > > > > > advertisement, which it probably should not be doing.
> > > > > > > Nevertheless, this behaviour is preserved but a comment is added.
> > > > > > >
> > > > > > > Signed-off-by: Russell King (Oracle)
> > > > > > > <rmk+kernel at armlinux.org.uk>
> > > > > >
> > > > > > drivers/net/ethernet/xilinx/xilinx_axienet.h:479: warning: Function
> > parameter or member 'pcs' not described in 'axienet_local'
> > > > >
> > > > > Fixed that and the sha1 issue you raised in patch 2. Since both
> > > > > are "documentation" issues, I won't send out replacement patches
> > > > > until I've heard they've been tested on hardware though.
> > > >
> > > > Thanks for the patches.
> > > > Series looks good and we're testing at our end; will get back to you
> > > > early next week.
> > >
> > > Thanks Russell. I've tested AXI Ethernet and it works fine.
> > 
> > Happy new year!
> > 
> > Thanks - can I use that as a tested-by please, and would you be happy for me
> > to send the patches for merging this week?
> 
> Sure, yes and yes.
> Tested-by: Harini Katakam <harini.katakam at xilinx.com>
> 
> Happy new year to you too!

Thanks. While adding the attributation, I was reminded of this comment in
the commit message:

  One oddity in this driver is that lp->switch_x_sgmii controls whether
  we support switching between SGMII and 1000baseX. However, when clear,
  this also blocks updating the 1000baseX advertisement, which it
  probably should not be doing. Nevertheless, this behaviour is preserved
  but a comment is added.

went back to look at that, and realised that this was not the case at
all, so patch 1 introduces a behaviour that wasn't originally there.
I'll post an update, but essentially the change to patch 1 is:

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index a556f0215049..fbe0de4bc8dd 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1533,18 +1533,17 @@ static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 	struct axienet_local *lp = netdev_priv(ndev);
 	int ret;
 
-	/* We don't support changing the advertisement in 1000base-X? --rmk */
-	if (!lp->switch_x_sgmii)
-		return 0;
-
-	ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
-			    XLNX_MII_STD_SELECT_REG,
-			    interface == PHY_INTERFACE_MODE_SGMII ?
-				XLNX_MII_STD_SELECT_SGMII : 0);
-	if (ret < 0) {
-		netdev_warn(ndev, "Failed to switch PHY interface: %d\n",
-			    ret);
-		return ret;
+	if (lp->switch_x_sgmii) {
+		ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
+				    XLNX_MII_STD_SELECT_REG,
+				    interface == PHY_INTERFACE_MODE_SGMII ?
+					XLNX_MII_STD_SELECT_SGMII : 0);
+		if (ret < 0) {
+			netdev_warn(ndev,
+				    "Failed to switch PHY interface: %d\n",
+				    ret);
+			return ret;
+		}
 	}
 
 	ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);

and a corresponding change to patch 2 for the change in code formatting.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mark.rutland at arm.com  Tue Jan  4 02:40:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 4 Jan 2022 10:40:51 +0000
Subject: [PATCH] [RFC] aarch64: scs: reload shadow call stack in user
 exception entry
In-Reply-To: <20211228010604.109572-1-ashimida@linux.alibaba.com>
References: <20211228010604.109572-1-ashimida@linux.alibaba.com>
Message-ID: <YdQkM8IlonhEhU/R@FVFF77S0Q05N>

Hi,

On Mon, Dec 27, 2021 at 05:06:04PM -0800, Dan Li wrote:
> When el0 exception occurs, kernel_entry/exit will load/save tsk->scs_sp
> to ensure scs working properly. AFAIK, the SCS offset should always be
> 0 at this time.
> 
> Is it reasonable to reload x18 to scs_base directly in kernel_entry
> here, or am I missing something?
> 
> Signed-off-by: Dan Li <ashimida at linux.alibaba.com>

AFAICT the saving here is just that we avoid storing the SCS SP upon return to
EL0, and I suspect that in practice that's not measureable.

So without numbers to show otherwise, I'd prefer to leave this as-is, though I
agree that this patch should work.  If we do want to change this, I think we
need a comment in the `kernel_exit` path to pair with the `scs_load` in
`kernel_entry`.

Thanks,
Mark.

> ---
>  arch/arm64/include/asm/scs.h | 7 +++++++
>  arch/arm64/kernel/entry.S    | 3 +--
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
> index 8297bccf0784..2bc0d0575e75 100644
> --- a/arch/arm64/include/asm/scs.h
> +++ b/arch/arm64/include/asm/scs.h
> @@ -9,6 +9,10 @@
>  #ifdef CONFIG_SHADOW_CALL_STACK
>  	scs_sp	.req	x18
>  
> +	.macro scs_reload tsk
> +	ldr	scs_sp, [\tsk, #TSK_TI_SCS_BASE]
> +	.endm
> +
>  	.macro scs_load tsk
>  	ldr	scs_sp, [\tsk, #TSK_TI_SCS_SP]
>  	.endm
> @@ -17,6 +21,9 @@
>  	str	scs_sp, [\tsk, #TSK_TI_SCS_SP]
>  	.endm
>  #else
> +	.macro scs_reload tsk
> +	.endm
> +
>  	.macro scs_load tsk
>  	.endm
>  
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index bc6d5a970a13..57547a3e4f7c 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -265,7 +265,7 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
>  alternative_else_nop_endif
>  1:
>  
> -	scs_load tsk
> +	scs_reload tsk
>  	.else
>  	add	x21, sp, #PT_REGS_SIZE
>  	get_current_task tsk
> @@ -365,7 +365,6 @@ alternative_if ARM64_WORKAROUND_845719
>  alternative_else_nop_endif
>  #endif
>  3:
> -	scs_save tsk
>  
>  	/* Ignore asynchronous tag check faults in the uaccess routines */
>  	ldr	x0, [tsk, THREAD_SCTLR_USER]
> -- 
> 2.17.1
> 


From cgel.zte at gmail.com  Tue Jan  4 02:41:39 2022
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Tue,  4 Jan 2022 10:41:39 +0000
Subject: [PATCH] drivers/regulator: remove redundant ret variable
Message-ID: <20220104104139.601031-1-chi.minghao@zte.com.cn>

From: Minghao Chi <chi.minghao at zte.com.cn>

Return value from regmap_update_bits() directly instead
of taking this in another redundant variable.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Minghao Chi <chi.minghao at zte.com.cn>
Signed-off-by: CGEL ZTE <cgel.zte at gmail.com>
---
 drivers/regulator/mt6380-regulator.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/regulator/mt6380-regulator.c b/drivers/regulator/mt6380-regulator.c
index 9efd8710a6f3..2e6b61d3b0cf 100644
--- a/drivers/regulator/mt6380-regulator.c
+++ b/drivers/regulator/mt6380-regulator.c
@@ -183,7 +183,7 @@ static const unsigned int ldo_volt_table4[] = {
 static int mt6380_regulator_set_mode(struct regulator_dev *rdev,
 				     unsigned int mode)
 {
-	int ret, val = 0;
+	int val = 0;
 	struct mt6380_regulator_info *info = rdev_get_drvdata(rdev);
 
 	switch (mode) {
@@ -199,10 +199,8 @@ static int mt6380_regulator_set_mode(struct regulator_dev *rdev,
 
 	val <<= ffs(info->modeset_mask) - 1;
 
-	ret = regmap_update_bits(rdev->regmap, info->modeset_reg,
+	return regmap_update_bits(rdev->regmap, info->modeset_reg,
 				 info->modeset_mask, val);
-
-	return ret;
 }
 
 static unsigned int mt6380_regulator_get_mode(struct regulator_dev *rdev)
-- 
2.25.1



From angelogioacchino.delregno at collabora.com  Tue Jan  4 02:44:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 11:44:23 +0100
Subject: [PATCH v1 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <20211227083641.12538-4-axe.yang@mediatek.com>
References: <20211227083641.12538-1-axe.yang@mediatek.com>
 <20211227083641.12538-4-axe.yang@mediatek.com>
Message-ID: <63cd9b04-8ff5-00ff-bbc4-7bc110080e41@collabora.com>

Il 27/12/21 09:36, Axe Yang ha scritto:
> Add support for eint irq when MSDC is used as an SDIO host. This
> feature requires SDIO device support async irq function. With this
> feature,SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in msdc node
> to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-int flag is necessary since this
> feature depends on asynchronous interrupt:
> 	&mmcX {
> 		...
> 		pinctrl-names = "default", "state_uhs", "state_eint",
> 						"state_dat1";
> 		...
> 		pinctrl-2 = <&mmc2_pins_eint>;
> 		pinctrl-3 = <&mmc2_pins_dat1>;
> 		...
> 		cap-sdio-async-int;
> 		...
> 	};
> 
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>

Hello Axe,
I agree on Andy's review, and I have some more comments...

> ---
>   drivers/mmc/host/mtk-sd.c | 113 ++++++++++++++++++++++++++++++++++++--
>   1 file changed, 107 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 4dfc246c5f95..8f23349f2963 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only
>   /*
> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2014-2021 MediaTek Inc.
>    * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
>    */
>   
> @@ -432,9 +432,13 @@ struct msdc_host {
>   	struct pinctrl *pinctrl;
>   	struct pinctrl_state *pins_default;
>   	struct pinctrl_state *pins_uhs;
> +	struct pinctrl_state *pins_eint;
> +	struct pinctrl_state *pins_dat1;
>   	struct delayed_work req_timeout;
>   	int irq;		/* host interrupt */

int eint_irq; should be here, under the host interrupt, for the sake of perfection.

>   	struct reset_control *reset;
> +	int eint_irq;		/* device interrupt */
> +	int sdio_irq_cnt;	/* irq enable cnt */
>   
>   	struct clk *src_clk;	/* msdc source clock */
>   	struct clk *h_clk;      /* msdc h_clk */
> @@ -1519,10 +1523,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
>   	__msdc_enable_sdio_irq(host, enb);
>   	spin_unlock_irqrestore(&host->lock, flags);
>   
> -	if (enb)
> -		pm_runtime_get_noresume(host->dev);
> -	else
> -		pm_runtime_put_noidle(host->dev);
> +	if (mmc->card && !mmc->card->cccr.enable_async_int) {
> +		if (enb)

If you are going to rename `enb` to `enable, this means that you're changing the
function signature... so, please, do that as a separated commit.

> +			pm_runtime_get_noresume(host->dev);
> +		else
> +			pm_runtime_put_noidle(host->dev);
> +	}
>   }
>   
>   static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
> @@ -2380,6 +2386,49 @@ static const struct mmc_host_ops mt_msdc_ops = {
>   	.hw_reset = msdc_hw_reset,
>   };
>   
> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +	unsigned long flags;
> +	struct msdc_host *host = (struct msdc_host *)dev_id;
> +	struct mmc_host *mmc = mmc_from_priv(host);
> +
> +	spin_lock_irqsave(&host->lock, flags);
> +	if (likely(host->sdio_irq_cnt > 0)) {
> +		disable_irq_nosync(host->eint_irq);
> +		disable_irq_wake(host->eint_irq);
> +		host->sdio_irq_cnt--;
> +	}
> +	spin_unlock_irqrestore(&host->lock, flags);
> +
> +	sdio_signal_irq(mmc);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> +{
> +	struct gpio_desc *desc;
> +	int ret = 0;
> +	int irq;
> +
> +	desc = devm_gpiod_get_index(host->dev, "eint", 0, GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
> +
> +	irq = gpiod_to_irq(desc);
> +	if (irq >= 0) {
> +		irq_set_status_flags(irq, IRQ_NOAUTOEN);
> +		ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
> +						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> +						"sdio-eint", host);

I think you may have misunderstood what Andy tried to say in his review: your call
to the function irq_set_status_flags() is using the right flag -- the suggestion
here is to add the IRQF_NO_AUTOEN flag to the call to devm_request_threaded_irq()
(ex: IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN) and remove the now redundant
call to irq_set_status_flags().


> +	} else {
> +		ret = irq;
> +	}
> +
> +	host->eint_irq = irq;
> +	return ret;
> +}
> +
>   static const struct cqhci_host_ops msdc_cmdq_ops = {
>   	.enable         = msdc_cqe_enable,
>   	.disable        = msdc_cqe_disable,
> @@ -2534,6 +2583,19 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   		goto host_free;
>   	}
>   
> +	/* Support for SDIO eint irq */
> +	host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
> +	if (IS_ERR(host->pins_eint)) {
> +		dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
> +	} else {
> +		host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
> +		if (IS_ERR(host->pins_dat1)) {
> +			ret = PTR_ERR(host->pins_dat1);
> +			dev_err(&pdev->dev, "Cannot find pinctrl dat1!\n");
> +			goto host_free;
> +		}
> +	}
> +
>   	msdc_of_property_parse(pdev, host);
>   
>   	host->dev = &pdev->dev;
> @@ -2621,6 +2683,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   	if (ret)
>   		goto release;
>   
> +	if (!IS_ERR(host->pins_eint) && !IS_ERR(host->pins_dat1)) {
> +		ret = msdc_request_dat1_eint_irq(host);
> +		if (ret) {
> +			dev_err(host->dev, "Failed to register data1 eint irq!\n");
> +			goto release;
> +		}
> +
> +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> +	}
> +
>   	pm_runtime_set_active(host->dev);
>   	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
>   	pm_runtime_use_autosuspend(host->dev);
> @@ -2740,21 +2812,50 @@ static void msdc_restore_reg(struct msdc_host *host)
>   
>   static int __maybe_unused msdc_runtime_suspend(struct device *dev)
>   {
> +	unsigned long flags;
>   	struct mmc_host *mmc = dev_get_drvdata(dev);
>   	struct msdc_host *host = mmc_priv(mmc);
>   
>   	msdc_save_reg(host);
> +
> +	if (!IS_ERR(host->pins_eint)) {
> +		disable_irq(host->irq);
> +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt == 0) {
> +			enable_irq(host->eint_irq);
> +			enable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt++;
> +		}
> +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
>   	msdc_gate_clock(host);
>   	return 0;
>   }
>   
>   static int __maybe_unused msdc_runtime_resume(struct device *dev)
>   {
> +	unsigned long flags;
>   	struct mmc_host *mmc = dev_get_drvdata(dev);
>   	struct msdc_host *host = mmc_priv(mmc);
>   
>   	msdc_ungate_clock(host);
>   	msdc_restore_reg(host);
> +	if (!IS_ERR(host->pins_eint)) {
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt > 0) {
> +			disable_irq_nosync(host->eint_irq);
> +			disable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt--;
> +			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		} else {
> +			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> +		}
> +		spin_unlock_irqrestore(&host->lock, flags);
> +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> +		enable_irq(host->irq);
> +	}
>   	return 0;
>   }
>   
> @@ -2778,7 +2879,7 @@ static int __maybe_unused msdc_resume(struct device *dev)
>   }
>   
>   static const struct dev_pm_ops msdc_dev_pm_ops = {
> -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)

Just a nitpick: msdc_{suspend,resume} are now noirq, so you should change the
function names to msdc_suspend_noirq, msdc_resume_noirq.

>   	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
>   };
>   
> 

Regards,
- Angelo



From linux at armlinux.org.uk  Tue Jan  4 02:44:51 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 10:44:51 +0000
Subject: [PATCH CFT v2 0/2] net: axienet: modernise pcs implementation
In-Reply-To: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
References: <Ybs1cdM3KUTsq4Vx@shell.armlinux.org.uk>
Message-ID: <YdQlI8gcVwg2sR+5@shell.armlinux.org.uk>

Hi,

These two patches modernise the Xilinx axienet PCS implementation to
use the phylink split PCS support.

The first patch adds split PCS support and makes use of the newly
introduced mac_select_pcs() function, which is the preferred way to
conditionally attach a PCS.

The second patch cleans up the use of mdiobus_write() since we now have
bus accessors for mdio devices.

There should be no functional change to the driver.

Please test, thanks.

v2: remove question over switch_x_sgmii

 drivers/net/ethernet/xilinx/xilinx_axienet.h      |   2 +
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 108 +++++++++++-----------
 2 files changed, 55 insertions(+), 55 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Tue Jan  4 02:46:55 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 04 Jan 2022 10:46:55 +0000
Subject: [PATCH CFT v2 net-next 2/2] net: axienet: replace mdiobus_write()
 with mdiodev_write()
In-Reply-To: <YdQlI8gcVwg2sR+5@shell.armlinux.org.uk>
References: <YdQlI8gcVwg2sR+5@shell.armlinux.org.uk>
Message-ID: <E1n4hLD-002NWF-0a@rmk-PC.armlinux.org.uk>

Commit 0ebecb2644c8 ("net: mdio: Add helper functions for accessing
MDIO devices") added support for mdiodev accessor operations that
neatly wrap the mdiobus accessor operations. Since we are dealing with
a mdio device here, update the driver to use mdiodev_write().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 7a28355114a8..42ffa8500c2b 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1540,8 +1540,7 @@ static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 	int ret;
 
 	if (lp->switch_x_sgmii) {
-		ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
-				    XLNX_MII_STD_SELECT_REG,
+		ret = mdiodev_write(pcs_phy, XLNX_MII_STD_SELECT_REG,
 				    interface == PHY_INTERFACE_MODE_SGMII ?
 					XLNX_MII_STD_SELECT_SGMII : 0);
 		if (ret < 0) {
-- 
2.30.2



From philippe.cornu at foss.st.com  Tue Jan  4 02:47:03 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:47:03 +0100
Subject: [PATCH 1/3] drm/stm: dsi: move lane capability detection in
 probe()
In-Reply-To: <20211218215055.212421-1-antonio.borneo@foss.st.com>
References: <20211218215055.212421-1-antonio.borneo@foss.st.com>
Message-ID: <20c77dc1-7e7e-ec0e-f545-593d1cfeb3b3@foss.st.com>



On 12/18/21 10:50 PM, Antonio Borneo wrote:
> There is no need to re-compute the dsi lane capability because it
> only depends on dsi hw version.
> Since dsi hw version is detected at probe(), move there also the
> assignment of dsi lane capability.
> 
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> ---
> To: David Airlie <airlied at linux.ie>
> To: Daniel Vetter <daniel at ffwll.ch>
> To: Andrzej Hajda <a.hajda at samsung.com>
> To: Neil Armstrong <narmstrong at baylibre.com>
> To: Robert Foss <robert.foss at linaro.org>
> To: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> To: Jonas Karlman <jonas at kwiboo.se>
> To: Jernej Skrabec <jernej.skrabec at gmail.com>
> To: Yannick Fertre <yannick.fertre at foss.st.com>
> To: Philippe Cornu <philippe.cornu at foss.st.com>
> To: Benjamin Gaignard <benjamin.gaignard at linaro.org>
> To: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> To: Alexandre Torgue <alexandre.torgue at foss.st.com>
> To: Philipp Zabel <p.zabel at pengutronix.de>
> To: dri-devel at lists.freedesktop.org
> To: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>   drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 

Hi Antonio,
many thanks for your patch.
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From rmk+kernel at armlinux.org.uk  Tue Jan  4 02:46:49 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 04 Jan 2022 10:46:49 +0000
Subject: [PATCH CFT v2 net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <YdQlI8gcVwg2sR+5@shell.armlinux.org.uk>
References: <YdQlI8gcVwg2sR+5@shell.armlinux.org.uk>
Message-ID: <E1n4hL7-002NW4-Q9@rmk-PC.armlinux.org.uk>

Convert axienet to use the phylink_pcs layer, resulting in it no longer
being a legacy driver.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/xilinx/xilinx_axienet.h  |   2 +
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 107 +++++++++---------
 2 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index 5b4d153b1492..40108968b350 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -386,6 +386,7 @@ struct axidma_bd {
  * @phylink:	Pointer to phylink instance
  * @phylink_config: phylink configuration settings
  * @pcs_phy:	Reference to PCS/PMA PHY if used
+ * @pcs:	phylink pcs structure for PCS PHY
  * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
  * @axi_clk:	AXI4-Lite bus clock
  * @misc_clks:	Misc ethernet clocks (AXI4-Stream, Ref, MGT clocks)
@@ -434,6 +435,7 @@ struct axienet_local {
 	struct phylink_config phylink_config;
 
 	struct mdio_device *pcs_phy;
+	struct phylink_pcs pcs;
 
 	bool switch_x_sgmii;
 
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 23ac353b35fe..7a28355114a8 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1509,78 +1509,79 @@ static const struct ethtool_ops axienet_ethtool_ops = {
 	.nway_reset	= axienet_ethtools_nway_reset,
 };
 
-static void axienet_mac_pcs_get_state(struct phylink_config *config,
-				      struct phylink_link_state *state)
+static struct axienet_local *pcs_to_axienet_local(struct phylink_pcs *pcs)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
-	struct axienet_local *lp = netdev_priv(ndev);
+	return container_of(pcs, struct axienet_local, pcs);
+}
 
-	switch (state->interface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		phylink_mii_c22_pcs_get_state(lp->pcs_phy, state);
-		break;
-	default:
-		break;
-	}
+static void axienet_pcs_get_state(struct phylink_pcs *pcs,
+				  struct phylink_link_state *state)
+{
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
+
+	phylink_mii_c22_pcs_get_state(pcs_phy, state);
 }
 
-static void axienet_mac_an_restart(struct phylink_config *config)
+static void axienet_pcs_an_restart(struct phylink_pcs *pcs)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
-	struct axienet_local *lp = netdev_priv(ndev);
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
 
-	phylink_mii_c22_pcs_an_restart(lp->pcs_phy);
+	phylink_mii_c22_pcs_an_restart(pcs_phy);
 }
 
-static int axienet_mac_prepare(struct phylink_config *config, unsigned int mode,
-			       phy_interface_t iface)
+static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+			      phy_interface_t interface,
+			      const unsigned long *advertising,
+			      bool permit_pause_to_mac)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
+	struct net_device *ndev = pcs_to_axienet_local(pcs)->ndev;
 	struct axienet_local *lp = netdev_priv(ndev);
 	int ret;
 
-	switch (iface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		if (!lp->switch_x_sgmii)
-			return 0;
-
-		ret = mdiobus_write(lp->pcs_phy->bus,
-				    lp->pcs_phy->addr,
+	if (lp->switch_x_sgmii) {
+		ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
 				    XLNX_MII_STD_SELECT_REG,
-				    iface == PHY_INTERFACE_MODE_SGMII ?
+				    interface == PHY_INTERFACE_MODE_SGMII ?
 					XLNX_MII_STD_SELECT_SGMII : 0);
-		if (ret < 0)
-			netdev_warn(ndev, "Failed to switch PHY interface: %d\n",
+		if (ret < 0) {
+			netdev_warn(ndev,
+				    "Failed to switch PHY interface: %d\n",
 				    ret);
-		return ret;
-	default:
-		return 0;
+			return ret;
+		}
 	}
+
+	ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);
+	if (ret < 0)
+		netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
+
+	return ret;
 }
 
-static void axienet_mac_config(struct phylink_config *config, unsigned int mode,
-			       const struct phylink_link_state *state)
+static const struct phylink_pcs_ops axienet_pcs_ops = {
+	.pcs_get_state = axienet_pcs_get_state,
+	.pcs_config = axienet_pcs_config,
+	.pcs_an_restart = axienet_pcs_an_restart,
+};
+
+static struct phylink_pcs *axienet_mac_select_pcs(struct phylink_config *config,
+						  phy_interface_t interface)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct axienet_local *lp = netdev_priv(ndev);
-	int ret;
 
-	switch (state->interface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		ret = phylink_mii_c22_pcs_config(lp->pcs_phy, mode,
-						 state->interface,
-						 state->advertising);
-		if (ret < 0)
-			netdev_warn(ndev, "Failed to configure PCS: %d\n",
-				    ret);
-		break;
+	if (interface == PHY_INTERFACE_MODE_1000BASEX ||
+	    interface ==  PHY_INTERFACE_MODE_SGMII)
+		return &lp->pcs;
 
-	default:
-		break;
-	}
+	return NULL;
+}
+
+static void axienet_mac_config(struct phylink_config *config, unsigned int mode,
+			       const struct phylink_link_state *state)
+{
+	/* nothing meaningful to do */
 }
 
 static void axienet_mac_link_down(struct phylink_config *config,
@@ -1635,9 +1636,7 @@ static void axienet_mac_link_up(struct phylink_config *config,
 
 static const struct phylink_mac_ops axienet_phylink_ops = {
 	.validate = phylink_generic_validate,
-	.mac_pcs_get_state = axienet_mac_pcs_get_state,
-	.mac_an_restart = axienet_mac_an_restart,
-	.mac_prepare = axienet_mac_prepare,
+	.mac_select_pcs = axienet_mac_select_pcs,
 	.mac_config = axienet_mac_config,
 	.mac_link_down = axienet_mac_link_down,
 	.mac_link_up = axienet_mac_link_up,
@@ -2046,12 +2045,12 @@ static int axienet_probe(struct platform_device *pdev)
 			ret = -EPROBE_DEFER;
 			goto cleanup_mdio;
 		}
-		lp->phylink_config.pcs_poll = true;
+		lp->pcs.ops = &axienet_pcs_ops;
+		lp->pcs.poll = true;
 	}
 
 	lp->phylink_config.dev = &ndev->dev;
 	lp->phylink_config.type = PHYLINK_NETDEV;
-	lp->phylink_config.legacy_pre_march2020 = true;
 	lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
 		MAC_10FD | MAC_100FD | MAC_1000FD;
 
-- 
2.30.2



From philippe.cornu at foss.st.com  Tue Jan  4 02:55:40 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 11:55:40 +0100
Subject: [PATCH 2/3] drm/bridge/synopsys: dsi: extend the prototype of
 mode_valid()
In-Reply-To: <20211218215055.212421-2-antonio.borneo@foss.st.com>
References: <20211218215055.212421-1-antonio.borneo@foss.st.com>
 <20211218215055.212421-2-antonio.borneo@foss.st.com>
Message-ID: <4d731e12-0ecd-8f86-e5b7-89c03c23d2fc@foss.st.com>



On 12/18/21 10:50 PM, Antonio Borneo wrote:
> To evaluate the validity of a video mode, some additional internal
> value has to be passed to the platform implementation.
> 
> Extend the prototype of mode_valid().
> 
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> ---
> To: David Airlie <airlied at linux.ie>
> To: Daniel Vetter <daniel at ffwll.ch>
> To: Andrzej Hajda <a.hajda at samsung.com>
> To: Neil Armstrong <narmstrong at baylibre.com>
> To: Robert Foss <robert.foss at linaro.org>
> To: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> To: Jonas Karlman <jonas at kwiboo.se>
> To: Jernej Skrabec <jernej.skrabec at gmail.com>
> To: Yannick Fertre <yannick.fertre at foss.st.com>
> To: Philippe Cornu <philippe.cornu at foss.st.com>
> To: Benjamin Gaignard <benjamin.gaignard at linaro.org>
> To: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> To: Alexandre Torgue <alexandre.torgue at foss.st.com>
> To: Philipp Zabel <p.zabel at pengutronix.de>
> To: dri-devel at lists.freedesktop.org
> To: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>   drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 5 ++++-
>   include/drm/bridge/dw_mipi_dsi.h              | 4 +++-
>   2 files changed, 7 insertions(+), 2 deletions(-)
> 

Hi Antonio,
many thanks for your patch.
(I should have done like that from the beginning as validating a mode in 
dsi requires dsi related information...)
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From clabbe.montjoie at gmail.com  Tue Jan  4 02:58:01 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 11:58:01 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
Message-ID: <YdQoOSXS98+Af1wO@Red>

Hello

I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
By not working, I mean kernel started with ip=dhcp cannot get an IP.

Without CONFIG_MARVELL_PHY, the PHY is detected as generic:
Generic PHY gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
but with a 1Gbit link, network is now working.
I am able to get an IP via DHCP and iperf give:
Test Complete. Summary Results:
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.04  sec   185 MBytes   154 Mbits/sec    2             sender
[  5]   0.00-10.09  sec   185 MBytes   154 Mbits/sec                  receiver
CPU Utilization: local/sender 77.8% (0.5%u/77.2%s), remote/receiver 13.3% (0.6%u/12.7%s)

ethtool confirms the gigabit link:
Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Supported pause frame use: Symmetric Receive-only
	Supports auto-negotiation: Yes
	Supported FEC modes: Not reported
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Advertised pause frame use: Symmetric Receive-only
	Advertised auto-negotiation: Yes
	Advertised FEC modes: Not reported
	Link partner advertised link modes:  10baseT/Half 10baseT/Full 
	                                     100baseT/Half 100baseT/Full 
	                                     1000baseT/Full 
	Link partner advertised pause frame use: No
	Link partner advertised auto-negotiation: Yes
	Link partner advertised FEC modes: Not reported
	Speed: 1000Mb/s
	Duplex: Full
	Port: MII
	PHYAD: 1
	Transceiver: external
	Auto-negotiation: on
	Current message level: 0x00000007 (7)
			       drv probe link
	Link detected: yes

With the marvell PHY, ethtool reports:
Settings for eth0:
	Supported ports: [ TP MII ]
	Supported link modes:   10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Supported pause frame use: Symmetric Receive-only
	Supports auto-negotiation: Yes
	Supported FEC modes: Not reported
	Advertised link modes:  10baseT/Half 10baseT/Full 
	                        100baseT/Half 100baseT/Full 
	                        1000baseT/Half 1000baseT/Full 
	Advertised pause frame use: Symmetric Receive-only
	Advertised auto-negotiation: Yes
	Advertised FEC modes: Not reported
	Link partner advertised link modes:  10baseT/Half 10baseT/Full 
	                                     100baseT/Half 100baseT/Full 
	                                     1000baseT/Full 
	Link partner advertised pause frame use: No
	Link partner advertised auto-negotiation: Yes
	Link partner advertised FEC modes: Not reported
	Speed: 1000Mb/s
	Duplex: Full
	Port: Twisted Pair
	PHYAD: 1
	Transceiver: external
	Auto-negotiation: on
	MDI-X: Unknown
	Current message level: 0x00000007 (7)
			       drv probe link
	Link detected: yes
Only change vs generic I saw is MDI-X and Port: values

Do you have any idea why the marvell PHY "break" the network ?

Regards


From angelogioacchino.delregno at collabora.com  Tue Jan  4 03:00:26 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 12:00:26 +0100
Subject: [PATCH RFC 03/13] mmc: mtk-sd: fix deferred probing
In-Reply-To: <20211223171202.8224-4-s.shtylyov@omp.ru>
References: <20211223171202.8224-1-s.shtylyov@omp.ru>
 <20211223171202.8224-4-s.shtylyov@omp.ru>
Message-ID: <669ea14c-d6e7-ebaa-891d-ad30b82dae49@collabora.com>

Il 23/12/21 18:11, Sergey Shtylyov ha scritto:
> The driver overrides the error codes returned by platform_get_irq() to
> -EINVAL, so if it returns -EPROBE_DEFER, the driver will fail the probe
> permanently instead of the deferred probing. Switch to propagating the
> error codes upstream.
> 
> Fixes: 208489032bdd ("mmc: mediatek: Add Mediatek MMC driver")
> Signed-off-by: Sergey Shtylyov <s.shtylyov at omp.ru>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/mmc/host/mtk-sd.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 632775217d35..4bd070a458e9 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -2590,7 +2590,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   
>   	host->irq = platform_get_irq(pdev, 0);
>   	if (host->irq < 0) {
> -		ret = -EINVAL;
> +		ret = host->irq;
>   		goto host_free;
>   	}
>   
> 



From philippe.cornu at foss.st.com  Tue Jan  4 03:01:37 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 12:01:37 +0100
Subject: [PATCH 3/3] drm/stm: dsi: provide the implementation of
 mode_valid()
In-Reply-To: <20211218215055.212421-3-antonio.borneo@foss.st.com>
References: <20211218215055.212421-1-antonio.borneo@foss.st.com>
 <20211218215055.212421-3-antonio.borneo@foss.st.com>
Message-ID: <9a8beb43-7a59-f042-7b14-d6d2ea360b6f@foss.st.com>



On 12/18/21 10:50 PM, Antonio Borneo wrote:
> The dsi has several constraints on the video modes it can support,
> mainly due to the frequencies that can be generated by the PLL
> integrated in the DSI device.
> 
> Verify that the required HS clock can be generated by the PLL.
> 
> The dsi clock from the dsi PLL and the ltdc pixel clock are
> asynchronous. The dsi needs to return in LP mode during HFP or HBP
> to re-synchronize at each video line.
> 
> Verify that the duration of HFP and HBP allows the dsi to enter in
> LP mode.
> 
> Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> ---
> To: David Airlie <airlied at linux.ie>
> To: Daniel Vetter <daniel at ffwll.ch>
> To: Andrzej Hajda <a.hajda at samsung.com>
> To: Neil Armstrong <narmstrong at baylibre.com>
> To: Robert Foss <robert.foss at linaro.org>
> To: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> To: Jonas Karlman <jonas at kwiboo.se>
> To: Jernej Skrabec <jernej.skrabec at gmail.com>
> To: Yannick Fertre <yannick.fertre at foss.st.com>
> To: Philippe Cornu <philippe.cornu at foss.st.com>
> To: Benjamin Gaignard <benjamin.gaignard at linaro.org>
> To: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> To: Alexandre Torgue <alexandre.torgue at foss.st.com>
> To: Philipp Zabel <p.zabel at pengutronix.de>
> To: dri-devel at lists.freedesktop.org
> To: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>   drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 98 +++++++++++++++++++++++++++
>   1 file changed, 98 insertions(+)

Hi Antonio,
many thanks for your patch.
Nice improvement for better filtering supported modes...
Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
Philippe :-)


From jbrunet at baylibre.com  Tue Jan  4 02:36:25 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Tue, 04 Jan 2022 11:36:25 +0100
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate
 calculation is described using the common clock code. Also added S4 chip
 uart Compatible.
In-Reply-To: <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
Message-ID: <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>


On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Jerome,
> 	Thank you very much for your reply.
>
> On 2022/1/3 20:40, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>> 
>>> Using the common Clock code to describe the UART baud rate clock makes
>>> it easier for the UART driver to be compatible with the baud rate
>>> requirements of the UART IP on different meson chips
>>>
>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>> ---
>>>   drivers/tty/serial/Kconfig      |   1 +
>>>   drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>>   2 files changed, 257 insertions(+), 55 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>> index 780908d43557..32e238173036 100644
>>> --- a/drivers/tty/serial/Kconfig
>>> +++ b/drivers/tty/serial/Kconfig
>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>   config SERIAL_MESON
>>>   	tristate "Meson serial port support"
>>>   	depends on ARCH_MESON
>>> +	depends on COMMON_CLK
>>>   	select SERIAL_CORE
>>>   	help
>>>   	  This enables the driver for the on-chip UARTs of the Amlogic
>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>> index 99efe62a1507..07eb1f40aaaa 100644
>>> --- a/drivers/tty/serial/meson_uart.c
>>> +++ b/drivers/tty/serial/meson_uart.c
>>> @@ -6,6 +6,7 @@
>>>    */
>>>     #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/console.h>
>>>   #include <linux/delay.h>
>>>   #include <linux/init.h>
>>> @@ -65,9 +66,7 @@
>>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>     /* AML_UART_REG5 bits */
>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>   #define AML_UART_BAUD_USE		BIT(23)
>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>     #define AML_UART_PORT_NUM		12
>>>   #define AML_UART_PORT_OFFSET		6
>>> @@ -76,6 +75,21 @@
>>>   #define AML_UART_POLL_USEC		5
>>>   #define AML_UART_TIMEOUT_USEC		10000
>>>   +struct meson_uart_data {
>>> +	struct uart_port	port;
>>> +	struct clk		*pclk;
>>> +	struct clk		*baud_clk;
>>> +	struct clk_divider	baud_div;
>>> +	struct clk_mux		use_xtal_mux;
>>> +	struct clk_mux		xtal_clk_sel_mux;
>>> +	struct clk_mux		xtal2_clk_sel_mux;
>>> +	struct clk_fixed_factor	xtal_div2;
>>> +	struct clk_fixed_factor	xtal_div3;
>>> +	struct clk_fixed_factor	clk81_div4;
>> Keeping all these internal elements around is not useful since they are
>> registered using devm_
>> 
> I'm sorry. I don't know what you mean. That's exactly what you said, but
> what's wrong, I don't understand. Do you have any better suggestions, 
> please specify specific points, preferably give examples.

I'm saying that you don't need to keep reference to the internal
elements of the clock tree you have registered since devm_ will take
care of the removal later on. IOW, Once they are registered, the pointer
is never used again so you don't need it in the private data.


>>> +	bool			no_clk81_input;
>> What is this ?
>> 
> To distinguish between clK81 and XTAL.

... Yet, it is not used

>>> +	bool			has_xtal_clk_sel;
>>> +};
>>> +
>>>   static struct uart_driver meson_uart_driver;
>>>     static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>   static int meson_uart_startup(struct uart_port *port)
>>>   {
>>>   	u32 val;
>>> -	int ret = 0;
>>> +	int ret;
>>>   -	val = readl(port->membase + AML_UART_CONTROL);
>>> -	val |= AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> -	val &= ~AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> +	meson_uart_reset(port);
>>>   +	val = readl(port->membase + AML_UART_CONTROL);
>>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>   	writel(val, port->membase + AML_UART_CONTROL);
>>>   @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port
>>> *port)
>>>     static void meson_uart_change_speed(struct uart_port *port, unsigned
>>> long baud)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>>   	u32 val;
>>>     	while (!meson_uart_tx_empty(port))
>>>   		cpu_relax();
>>>   -	if (port->uartclk == 24000000) {
>> This check shows that previous code assumed bit 24 was left untouched
>> Below you can see that GXBB and newer used the XTAL path while older
>> used the other
>> Your change makes this dynamic which is another "unexpected" change.
>> Please make the bit 24 mux RO to start with so the behavior remains unchanged
>> for older SoCs.
> I agree with what you say, and I will correct it.
>> 
>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>> -		val |= AML_UART_BAUD_XTAL;
>>> -	} else {
>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>> -	}
>>> +	val = readl(port->membase + AML_UART_REG5);
>>>   	val |= AML_UART_BAUD_USE;
>>>   	writel(val, port->membase + AML_UART_REG5);
>>> +
>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>   }
>>>     static void meson_uart_set_termios(struct uart_port *port,
>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>     static void meson_uart_release_port(struct uart_port *port)
>>>   {
>>> -	/* nothing to do */
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +
>>> +	clk_disable_unprepare(private_data->baud_clk);
>>> +	clk_disable_unprepare(private_data->pclk);
>>>   }
>>>     static int meson_uart_request_port(struct uart_port *port)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	int ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->pclk);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>> +	if (ret) {
>>> +		clk_disable_unprepare(private_data->pclk);
>>> +		return ret;
>>> +	}
>>> +
>>>   	return 0;
>>>   }
>>>   @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>>   	.cons		= MESON_SERIAL_CONSOLE,
>>>   };
>>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>> -						 const char *id)
>>> +static int meson_uart_register_clk(struct uart_port *port,
>>> +				   const char *name_suffix,
>>> +				   const struct clk_parent_data *parent_data,
>>> +				   unsigned int num_parents,
>>> +				   const struct clk_ops *ops,
>>> +				   struct clk_hw *hw)
>>>   {
>>> -	struct clk *clk = NULL;
>>> +	struct clk_init_data init = { };
>>> +	char clk_name[32];
>>>   	int ret;
>>>   -	clk = devm_clk_get(dev, id);
>>> -	if (IS_ERR(clk))
>>> -		return clk;
>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>>> +		 name_suffix);
>>>   -	ret = clk_prepare_enable(clk);
>>> -	if (ret) {
>>> -		dev_err(dev, "couldn't enable clk\n");
>>> -		return ERR_PTR(ret);
>>> -	}
>>> +	init.name = clk_name;
>>> +	init.ops = ops;
>>> +	init.flags = CLK_SET_RATE_PARENT;
>>> +	init.parent_data = parent_data;
>>> +	init.num_parents = num_parents;
>>> +
>>> +	hw->init = &init;
>>>   -	devm_add_action_or_reset(dev,
>>> -			(void(*)(void *))clk_disable_unprepare,
>>> -			clk);
>>> +	ret = devm_clk_hw_register(port->dev, hw);
>>> +	if (ret)
>>> +		return dev_err_probe(port->dev, ret,
>>> +				     "Failed to register the '%s' clock\n",
>>> +				     clk_name);
>>>   -	return clk;
>>> +	return ret;
>>>   }
>>>   -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>> -				   struct uart_port *port)
>>> -{
>>> -	struct clk *clk_xtal = NULL;
>>> -	struct clk *clk_pclk = NULL;
>>> -	struct clk *clk_baud = NULL;
>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>> +				   bool register_clk81_div4)
>>> +{
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>> +		{ .index = -1, },
>>> +		{ .index = -1, },
>>> +	};
>>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>> +	struct clk_parent_data baud_div_parent = { };
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	int ret;
>>>   -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>> -	if (IS_ERR(clk_pclk))
>>> -		return PTR_ERR(clk_pclk);
>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>> +
>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>> +	if (IS_ERR(clk_baud))
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>> +				     "Failed to get the 'baud' clock\n");
>>>   -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>   	if (IS_ERR(clk_xtal))
>>> -		return PTR_ERR(clk_xtal);
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>>> +	private_data->xtal_div3.mult = 1;
>>> +	private_data->xtal_div3.div = 3;
>>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>>> +				      1, &clk_fixed_factor_ops,
>>> +				      &private_data->xtal_div3.hw);
>>> +	if (ret)
>>> +		return ret;
>>>   -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>> -	if (IS_ERR(clk_baud))
>>> -		return PTR_ERR(clk_baud);
>>> +	if (register_clk81_div4) {
>> Clock dividers represent HW elements. The presence of an HW element
>> cannot
>> dependent on the current of the input clocks. There is no way this is right
>> 
>>> +		private_data->clk81_div4.mult = 1;
>>> +		private_data->clk81_div4.div = 4;
>>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>>> +					      &clk81_div_parent, 1,
>>> +					      &clk_fixed_factor_ops,
>>> +					      &private_data->clk81_div4.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>> This is only going to be used on meson8 and older. Worst case it should
>> depend
>> on this compatible but I don't think this would be right here.
>> IMO, this shows that the UART "baud" input was actually fed by a
>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>> So instead of registering what I suspect to be a fake element, the
>> meson8 clock controller driver and DT should be fixed a this should go away.
>> 
> Virtually all UART controllers are supported, but they are not used after
> Meson8. So the description is more reasonable in UART driver.

No it is not. It's not virtual, the support for meson8 is there in
mainline.

Unless you tell me there is an actual /4 divider in the UART block of
the meson8 and older and that is was removed from the newer SoC,
the bit above should be removed and the meson8 clock tree fixed.

I think it is more probable that the /4 was never there to begin with,
and that clk81/4 aka "fclk_div4", which is already available from the
clock controller, was actually routed on these older SoCs.

>>> +	}
>>>   -	port->uartclk = clk_get_rate(clk_baud);
>>> +	if (private_data->has_xtal_clk_sel) {
>>> +		private_data->xtal_div2.mult = 1;
>>> +		private_data->xtal_div2.div = 2;
>>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>>> +					      &xtal_div_parent, 1,
>>> +					      &clk_fixed_factor_ops,
>>> +					      &private_data->xtal_div2.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>> +
>>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>>> +		private_data->xtal_clk_sel_mux.shift = 26;
>>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>> +					      xtal_clk_sel_mux_parents,
>>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>> +					      &clk_mux_ops,
>>> +					      &private_data->xtal_clk_sel_mux.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>>> +
>>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>> +					      xtal2_clk_sel_mux_parents,
>>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>> +					      &clk_mux_ops,
>>> +					      &private_data->xtal2_clk_sel_mux.hw);
>>> +		if (ret)
>>> +			return ret;
>>> +
>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>>> +	} else {
>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>> Well the above is a bit over-complicated. If I summarize:
>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>> 0 according to the documentation.
>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>> selects which of these dividers is used.
>> So the above could be replaced with a single divider covering bits 26 and
>> 27
>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>> variant like this, including the older ones.
>> 
> As you say, the way you say it is complicated. I think you're complicating
> things.I don't understand what you're trying to achieve.
> Can you be more specific?

I'm proposing to replace the 4 elements above, paths, parent_table and
all with a single divider with a specific table. It accomplishes the same thing.

|--------+--------+-----------|
| Bit 27 | Bit 26 | Div Value |
|--------+--------+-----------|
|      0 |      0 |         3 |
|--------+--------+-----------|
|      0 |      1 |         1 |
|--------+--------+-----------|
|      1 |      0 |         2 |
|--------+--------+-----------|
|      1 |      1 |         2 |
|--------+--------+-----------|

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602

something like:

static struct clk_div_table reg5_table[] = {
	{ 0, 3 },
        { 1, 1 },
        { 2, 2 },
        { 3, 2 },
};

I'm also pointing out that, since bit 26 and 27 reads 0 on the older
SoCs, the divider would work for these too, as long as the Ops is
read-only. So you don't even need to register different element
depending on the SoC which simplify things a bit more.

If you prefer to keep a fixed divider for the older ones, It's fine by
me. It gives a bit more work but it is closer to reality. The newer SoC
could still use the custom divider regardless.

Last, and as explained on other bits, that part of the clock path should
remain RO at first, to keep behavior stable with this change. You may
change that later on, in a dedicated patch describing the change.

>
>> The only information you need to carry if whether or not you want to
>> make this divider modifiable. This means using the dt data to store
>> clk_div_ops or clk_div_ro_ops pointer.
>> To avoid changing the behavior of the older platforms in this patch, I
>> would
>> suggest to make everything use clk_div_ro_ops first, and make another
>> patch to use clk_div_ops if necessary.
>> 
>>> +	}
>>> +
>>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>> +	private_data->use_xtal_mux.mask = 0x1;
>>> +	private_data->use_xtal_mux.shift = 24;
>>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>>> +				      &clk_mux_ops,
>> Use RO ops here to start with.
>> You can make this writable with another patch explicitly describing the change.
> I agree with what you say, and I will correct it.
>> 
>>> +				      &private_data->use_xtal_mux.hw);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>> +
>>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>> +	private_data->baud_div.shift = 0;
>>> +	private_data->baud_div.width = 23;
>>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>> +	ret = meson_uart_register_clk(port, "baud_div",
>>> +				      &baud_div_parent, 1,
>>> +				      &clk_divider_ops,
>>> +				      &private_data->baud_div.hw);
>>> +	if (ret)
>>> +		return ret;
>>> +
>>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>> +						     &private_data->baud_div.hw,
>>> +						     "baud_rate");
>> There is a problem with this function in CCF. It will pin the driver to
>> itself, making it unremovable. It is an ongoing topic. For now, just use
>> "hw->clk" to get the struct *clk.
>> 
>>> +	if (IS_ERR(private_data->baud_clk))
>>> +		return dev_err_probe(port->dev,
>> I don't think anything can defer here, so dev_err_probe() is not
>> necessary I think
>> 
> I agree with what you say, and I will correct it.
>>> +				     PTR_ERR(private_data->baud_clk),
>>> +				     "Failed to request the 'baud_rate' clock\n");
>>>     	return 0;
>>>   }
>>>     static int meson_uart_probe(struct platform_device *pdev)
>>>   {
>>> +	struct meson_uart_data *private_data;
>>>   	struct resource *res_mem, *res_irq;
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	bool register_clk81_div4;
>>>   	struct uart_port *port;
>>>   	int ret = 0;
>>>   	int id = -1;
>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   		return -EBUSY;
>>>   	}
>>>   -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>> GFP_KERNEL);
>>> -	if (!port)
>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>> +				    GFP_KERNEL);
>>> +	if (!private_data)
>>>   		return -ENOMEM;
>>>   +	if (device_get_match_data(&pdev->dev))
>>> +		private_data->has_xtal_clk_sel = true;
>>> +
>>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>> +
>>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>>> +	if (IS_ERR(clk_baud))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>> +				     "Failed to get the 'baud' clock\n");
>>> +
>>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>> +	if (IS_ERR(clk_xtal))
>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>> This is second time you call devm_clk_get() on these clocks. One
>> instance has to go away
>> 
> I agree with what you say, and I will correct it.
>>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>>> +
>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>> from the rest. This definitely not the way to achieve it.
>> The right is the compatible data but here I think it is not
>> necessary. The clock input should be fixed.
>> 
>>> +	port = &private_data->port;
>>> +
>>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>   	if (IS_ERR(port->membase))
>>>   		return PTR_ERR(port->membase);
>>>   -	ret = meson_uart_probe_clocks(pdev, port);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>   	port->iotype = UPIO_MEM;
>>>   	port->mapbase = res_mem->start;
>>>   	port->mapsize = resource_size(res_mem);
>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   	port->x_char = 0;
>>>   	port->ops = &meson_uart_ops;
>>>   	port->fifosize = 64;
>>> +	port->uartclk = clk_get_rate(clk_baud);
>>> +	port->private_data = private_data;
>>> +
>>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>> +	if (ret)
>>> +		return ret;
>>>     	meson_ports[pdev->id] = port;
>>>   	platform_set_drvdata(pdev, port);
>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>>   }
>>>     static const struct of_device_id meson_uart_dt_match[] = {
>>> -	{ .compatible = "amlogic,meson6-uart" },
>>> -	{ .compatible = "amlogic,meson8-uart" },
>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>> +	{
>>> +		.compatible = "amlogic,meson6-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8b-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxl-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-g12a-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-s4-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	/*
>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>>> +	 */
>>> +	{
>>> +		.compatible = "amlogic,meson-gx-uart",
>>> +		.data = (void *)false,
>>> +	},
>>>   	{ /* sentinel */ },
>>>   };
>>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>> 



From linux at armlinux.org.uk  Tue Jan  4 03:14:46 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 11:14:46 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQoOSXS98+Af1wO@Red>
References: <YdQoOSXS98+Af1wO@Red>
Message-ID: <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> Hello
> 
> I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> By not working, I mean kernel started with ip=dhcp cannot get an IP.

How is the PHY connected to the host (which interface mode?) If it's
RGMII, it could be that the wrong RGMII interface mode is specified in
DT.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From andreyknvl at gmail.com  Tue Jan  4 03:28:58 2022
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Tue, 4 Jan 2022 12:28:58 +0100
Subject: [PATCH mm v5 29/39] kasan, page_alloc: allow skipping memory init
 for HW_TAGS
In-Reply-To: <b968e485f4d7f201fdb4e39f64ca757180e7374a.camel@mediatek.com>
References: <cover.1640891329.git.andreyknvl@google.com>
 <88f2964f4063aa6fd935ef8c8302d02d8d67005b.1640891329.git.andreyknvl@google.com>
 <b968e485f4d7f201fdb4e39f64ca757180e7374a.camel@mediatek.com>
Message-ID: <CA+fCnZd4p+80MqOLJTa0-SwcXPbXe+n3FsCCN2dFHJ+bAsdZ-A@mail.gmail.com>

On Mon, Jan 3, 2022 at 3:32 AM Kuan-Ying Lee <Kuan-Ying.Lee at mediatek.com> wrote:
>
> On Fri, 2021-12-31 at 03:14 +0800, andrey.konovalov at linux.dev wrote:
> > From: Andrey Konovalov <andreyknvl at google.com>
> >
> > Add a new GFP flag __GFP_SKIP_ZERO that allows to skip memory
> > initialization. The flag is only effective with HW_TAGS KASAN.
> >
> > This flag will be used by vmalloc code for page_alloc allocations
> > backing vmalloc() mappings in a following patch. The reason to skip
> > memory initialization for these pages in page_alloc is because
> > vmalloc
> > code will be initializing them instead.
> >
> > With the current implementation, when __GFP_SKIP_ZERO is provided,
> > __GFP_ZEROTAGS is ignored. This doesn't matter, as these two flags
> > are
> > never provided at the same time. However, if this is changed in the
> > future, this particular implementation detail can be changed as well.
> >
> > Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
> >
> > ---
> >
> > Changes v4->v5:
> > - Cosmetic changes to __def_gfpflag_names_kasan and __GFP_BITS_SHIFT.
> >
> > Changes v3->v4:
> > - Only define __GFP_SKIP_ZERO when CONFIG_KASAN_HW_TAGS is enabled.
> > - Add __GFP_SKIP_ZERO to include/trace/events/mmflags.h.
> > - Use proper kasan_hw_tags_enabled() check instead of
> >   IS_ENABLED(CONFIG_KASAN_HW_TAGS). Also add explicit checks for
> >   software modes.
> >
> > Changes v2->v3:
> > - Update patch description.
> >
> > Changes v1->v2:
> > - Add this patch.
> > ---
> >  include/linux/gfp.h            | 18 +++++++++++-------
> >  include/trace/events/mmflags.h |  1 +
> >  mm/page_alloc.c                | 18 +++++++++++++++++-
> >  3 files changed, 29 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/linux/gfp.h b/include/linux/gfp.h
> > index 487126f089e1..6eef3e447540 100644
> > --- a/include/linux/gfp.h
> > +++ b/include/linux/gfp.h
> > @@ -55,14 +55,16 @@ struct vm_area_struct;
> >  #define ___GFP_ACCOUNT               0x400000u
> >  #define ___GFP_ZEROTAGS              0x800000u
> >  #ifdef CONFIG_KASAN_HW_TAGS
> > -#define ___GFP_SKIP_KASAN_UNPOISON   0x1000000u
> > -#define ___GFP_SKIP_KASAN_POISON     0x2000000u
> > +#define ___GFP_SKIP_ZERO             0x1000000u
> > +#define ___GFP_SKIP_KASAN_UNPOISON   0x2000000u
> > +#define ___GFP_SKIP_KASAN_POISON     0x4000000u
> >  #else
> > +#define ___GFP_SKIP_ZERO             0
> >  #define ___GFP_SKIP_KASAN_UNPOISON   0
> >  #define ___GFP_SKIP_KASAN_POISON     0
> >  #endif
> >  #ifdef CONFIG_LOCKDEP
> > -#define ___GFP_NOLOCKDEP     0x4000000u
> > +#define ___GFP_NOLOCKDEP     0x8000000u
> >  #else
> >  #define ___GFP_NOLOCKDEP     0
> >  #endif
> > @@ -235,9 +237,10 @@ struct vm_area_struct;
> >   * %__GFP_ZERO returns a zeroed page on success.
> >   *
> >   * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the
> > memory itself
> > - * is being zeroed (either via __GFP_ZERO or via init_on_alloc).
> > This flag is
> > - * intended for optimization: setting memory tags at the same time
> > as zeroing
> > - * memory has minimal additional performace impact.
> > + * is being zeroed (either via __GFP_ZERO or via init_on_alloc,
> > provided that
> > + * __GFP_SKIP_ZERO is not set). This flag is intended for
> > optimization: setting
> > + * memory tags at the same time as zeroing memory has minimal
> > additional
> > + * performace impact.
> >   *
> >   * %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page
> > allocation.
> >   * Only effective in HW_TAGS mode.
> > @@ -249,6 +252,7 @@ struct vm_area_struct;
> >  #define __GFP_COMP   ((__force gfp_t)___GFP_COMP)
> >  #define __GFP_ZERO   ((__force gfp_t)___GFP_ZERO)
> >  #define __GFP_ZEROTAGS       ((__force gfp_t)___GFP_ZEROTAGS)
> > +#define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO)
> >  #define __GFP_SKIP_KASAN_UNPOISON ((__force
> > gfp_t)___GFP_SKIP_KASAN_UNPOISON)
> >  #define __GFP_SKIP_KASAN_POISON   ((__force
> > gfp_t)___GFP_SKIP_KASAN_POISON)
> >
> > @@ -257,7 +261,7 @@ struct vm_area_struct;
> >
> >  /* Room for N __GFP_FOO bits */
> >  #define __GFP_BITS_SHIFT (24 +
> >       \
> > -                       2 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +        \
> > +                       3 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +        \
> >                         IS_ENABLED(CONFIG_LOCKDEP))
> >  #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) -
> > 1))
> >
> > diff --git a/include/trace/events/mmflags.h
> > b/include/trace/events/mmflags.h
> > index 5ffc7bdce91f..0698c5d0f194 100644
> > --- a/include/trace/events/mmflags.h
> > +++ b/include/trace/events/mmflags.h
> > @@ -52,6 +52,7 @@
> >
> >  #ifdef CONFIG_KASAN_HW_TAGS
> >  #define __def_gfpflag_names_kasan ,
> >        \
> > +     {(unsigned long)__GFP_SKIP_ZERO,           "__GFP_SKIP_ZERO"},
> >   \
> >       {(unsigned
> > long)__GFP_SKIP_KASAN_POISON,   "__GFP_SKIP_KASAN_POISON"}, \
> >       {(unsigned long)__GFP_SKIP_KASAN_UNPOISON,
> > "__GFP_SKIP_KASAN_UNPOISON"}
> >  #else
> > diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> > index 102f0cd8815e..30da0e1f94f8 100644
> > --- a/mm/page_alloc.c
> > +++ b/mm/page_alloc.c
> > @@ -2415,10 +2415,26 @@ static inline bool
> > should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
> >       return init_tags || (flags & __GFP_SKIP_KASAN_UNPOISON);
> >  }
> >
> > +static inline bool should_skip_init(gfp_t flags)
> > +{
> > +     /* Don't skip if a software KASAN mode is enabled. */
> > +     if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
> > +         IS_ENABLED(CONFIG_KASAN_SW_TAGS))
> > +             return false;
>
> Forget to drop the above check?
>
> I saw v4 mentioned that this check can be dropped. [1]
>
> Do I miss something?
>
> [1] https://lkml.org/lkml/2021/12/30/450

Right, forgot to include this change. Will include into v5 or post as
a standalone fix closer to rc1. Thanks for noticing!


From allen-kh.cheng at mediatek.com  Tue Jan  4 03:31:02 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:31:02 +0800
Subject: [PATCH v2 0/2] Add SCP support for mt8186
Message-ID: <20220104113104.27136-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

changes since v1:
- use mt8192_power_on_sram() helper
- add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
- add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h

Based on v5.16-rc8

allen-kh.cheng (2):
  dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
  remoteproc: mediatek: Support mt8186 scp

 .../bindings/remoteproc/mtk,scp.yaml          |  1 +
 drivers/remoteproc/mtk_common.h               |  3 ++
 drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
 3 files changed, 39 insertions(+)

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 03:31:04 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:31:04 +0800
Subject: [PATCH v2 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220104113104.27136-1-allen-kh.cheng@mediatek.com>
References: <20220104113104.27136-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104113104.27136-3-allen-kh.cheng@mediatek.com>

Add SCP support for mt8186

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/remoteproc/mtk_common.h |  3 +++
 drivers/remoteproc/mtk_scp.c    | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 5ff3867c72f3..71ce4977cb0b 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -32,6 +32,9 @@
 #define MT8183_SCP_CACHESIZE_8KB	BIT(8)
 #define MT8183_SCP_CACHE_CON_WAYEN	BIT(10)
 
+#define MT8186_SCP_L1_SRAM_PD_P1	0x40B0
+#define MT8186_SCP_L1_SRAM_PD_p2	0x40B4
+
 #define MT8192_L2TCM_SRAM_PD_0		0x10C0
 #define MT8192_L2TCM_SRAM_PD_1		0x10C4
 #define MT8192_L2TCM_SRAM_PD_2		0x10C8
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..ef355eafeb9c 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -383,6 +383,27 @@ static void mt8192_power_off_sram(void __iomem *addr)
 		writel(GENMASK(i, 0), addr);
 }
 
+static int mt8186_scp_before_load(struct mtk_scp *scp)
+{
+        /* Clear SCP to host interrupt */
+        writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+        /* Reset clocks before loading FW */
+        writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+        writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+        /* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
+        mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+        /* Initialize TCM before loading FW. */
+        writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+        writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+        writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1);
+        writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2);
+
+        return 0;
+}
+
 static int mt8192_scp_before_load(struct mtk_scp *scp)
 {
 	/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -887,6 +908,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 	.ipi_buf_offset = 0x7bdb0,
 };
 
+static const struct mtk_scp_of_data mt8186_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
+	.scp_before_load = mt8186_scp_before_load,
+	.scp_irq_handler = mt8183_scp_irq_handler,
+	.scp_reset_assert = mt8183_scp_reset_assert,
+	.scp_reset_deassert = mt8183_scp_reset_deassert,
+	.scp_stop = mt8183_scp_stop,
+	.scp_da_to_va = mt8183_scp_da_to_va,
+	.host_to_scp_reg = MT8183_HOST_TO_SCP,
+	.host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT,
+	.ipi_buf_offset = 0x7bdb0,
+};
+
 static const struct mtk_scp_of_data mt8192_of_data = {
 	.scp_clk_get = mt8192_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
@@ -913,6 +947,7 @@ static const struct mtk_scp_of_data mt8195_of_data = {
 
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
+	{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
 	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 03:31:03 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:31:03 +0800
Subject: [PATCH v2 1/2] dt-bindings: remoteproc: mediatek: Add binding for
 mt8186 scp
In-Reply-To: <20220104113104.27136-1-allen-kh.cheng@mediatek.com>
References: <20220104113104.27136-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104113104.27136-2-allen-kh.cheng@mediatek.com>

Add mt8186 compatible to binding document.

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index d21a25ee96e6..5b693a2d049c 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-scp
+      - mediatek,mt8186-scp
       - mediatek,mt8192-scp
       - mediatek,mt8195-scp
 
-- 
2.18.0



From clabbe.montjoie at gmail.com  Tue Jan  4 03:33:15 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 12:33:15 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red>
 <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
Message-ID: <YdQwexJVfrdzEfZK@Red>

Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > Hello
> > 
> > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> 
> How is the PHY connected to the host (which interface mode?) If it's
> RGMII, it could be that the wrong RGMII interface mode is specified in
> DT.
> 

The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
The only change to the mainline dtb is removing the max-speed.

Regards


From linux at armlinux.org.uk  Tue Jan  4 03:41:40 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 11:41:40 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQwexJVfrdzEfZK@Red>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red>
Message-ID: <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > Hello
> > > 
> > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > 
> > How is the PHY connected to the host (which interface mode?) If it's
> > RGMII, it could be that the wrong RGMII interface mode is specified in
> > DT.
> > 
> 
> The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> The only change to the mainline dtb is removing the max-speed.

So, it's using "rgmii" with no delay configured at the PHY with the
speed limited to 100Mbps. You then remove the speed limitation and
it doesn't work at 1Gbps.

I think I've seen this on other platforms (imx6 + ar8035) when the
RGMII delay is not correctly configured - it will work at slower
speeds but not 1G.

The RGMII spec specifies that there will be a delay - and the delay can
be introduced by either the MAC, PHY or by PCB track routing. It sounds
to me like your boot environment configures the PHY to introduce the
necessary delay, but then, because the DT "rgmii" mode means "no delay
at the PHY" when you use the Marvell driver (which respects that), the
Marvell driver configures the PHY for no delay, resulting in a non-
working situation at 1G.

I would suggest checking how the boot environment configures the PHY,
and change the "rgmii" mode in DT to match. There is a description of
the four RGMII modes in Documentation/networking/phy.rst that may help
understand what each one means.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From daniel at makrotopia.org  Tue Jan  4 03:41:34 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 11:41:34 +0000
Subject: [PATCH v11 0/3] net: ethernet: mtk_eth_soc: refactoring and Clause 45
Message-ID: <YdQybnk9eJmjaLAw@makrotopia.org>

Rework value and type of mdio read and write functions in mtk_eth_soc
and generally clean up and unify both functions.
Then add support to access Clause 45 phy registers, using newly
introduced helper inline functions added by a patch Russell King has
suggested in a reply to an earlier version of this series [1].

All three commits are tested on the Bananapi BPi-R64 board having
MediaTek MT7531BE DSA gigE switch using clause 22 MDIO and
Ubiquiti UniFi 6 LR access point having Aquantia AQR112C PHY using
clause 45 MDIO.

[1]: https://lore.kernel.org/netdev/Ycr5Cna76eg2B0An at shell.armlinux.org.uk/

v11: also address return value of mtk_mdio_busy_wait
v10: correct order of SoB lines in 2/3, change patch order in series
v9: improved formatting and Cc missing maintainer
v8: add patch from Russel King, switch to bitfield helper macros
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

Daniel Golle (2):
  net: ethernet: mtk_eth_soc: fix return values and refactor MDIO ops
  net: ethernet: mtk_eth_soc: implement Clause 45 MDIO access

Russell King (Oracle) (1):
  net: mdio: add helpers to extract clause 45 regad and devad fields

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 101 +++++++++++++++-----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  19 +++-
 include/linux/mdio.h                        |  12 +++
 3 files changed, 102 insertions(+), 30 deletions(-)

-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 03:42:14 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 11:42:14 +0000
Subject: [PATCH v11 1/3] net: ethernet: mtk_eth_soc: fix return values and
 refactor MDIO ops
Message-ID: <YdQylhz+WNkxZDMn@makrotopia.org>

Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
while writing or 0xffff if it happens while reading, return the
appropriate -ETIMEDOUT. Also fix return type to int instead of u32.
Refactor functions to use bitfield helpers instead of having various
masking and shifting constants in the code, which also results in the
register definitions in the header file being more obviously related
to what is stated in the MediaTek's Reference Manual.

Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v11: also address return value of mtk_mdio_busy_wait
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros
v7: remove unneeded variables
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++++++++++++---------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++++--
 2 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index bcb91b01e69f5..3809ea6e31ce2 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -91,46 +91,53 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
 	}
 
 	dev_err(eth->dev, "mdio: MDIO timeout\n");
-	return -1;
+	return -ETIMEDOUT;
 }
 
-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
-			   u32 phy_register, u32 write_data)
+static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
+			   u32 write_data)
 {
-	if (mtk_mdio_busy_wait(eth))
-		return -1;
+	int ret;
 
-	write_data &= 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret)
+		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
-		(phy_register << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_WRITE |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr) |
+		     PHY_IAC_DATA(write_data),
 		MTK_PHY_IAC);
 
-	if (mtk_mdio_busy_wait(eth))
-		return -1;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
 	return 0;
 }
 
-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
+static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 {
-	u32 d;
+	int ret;
 
-	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret)
+		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
-		(phy_reg << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT),
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_C22_READ |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr),
 		MTK_PHY_IAC);
 
-	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
-
-	d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
-	return d;
+	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
 }
 
 static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 5ef70dd8b49c6..f2d90639d7ed1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -341,11 +341,17 @@
 /* PHY Indirect Access Control registers */
 #define MTK_PHY_IAC		0x10004
 #define PHY_IAC_ACCESS		BIT(31)
-#define PHY_IAC_READ		BIT(19)
-#define PHY_IAC_WRITE		BIT(18)
-#define PHY_IAC_START		BIT(16)
-#define PHY_IAC_ADDR_SHIFT	20
-#define PHY_IAC_REG_SHIFT	25
+#define PHY_IAC_REG_MASK	GENMASK(29, 25)
+#define PHY_IAC_REG(x)		FIELD_PREP(PHY_IAC_REG_MASK, (x))
+#define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
+#define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
+#define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
+#define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
+#define PHY_IAC_DATA_MASK	GENMASK(15, 0)
+#define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
 #define PHY_IAC_TIMEOUT		HZ
 
 #define MTK_MAC_MISC		0x1000c
-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 03:43:28 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 11:43:28 +0000
Subject: [PATCH v11 2/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
Message-ID: <YdQy4HOftY6ASoJH@makrotopia.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

Add a couple of helpers and definitions to extract the clause 45 regad
and devad fields from the regnum passed into MDIO drivers.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Tested-by: Daniel Golle <daniel at makrotopia.org>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v11: unchanged, added Reviewed-by: line from Andrew Lunn
v10: correct order of SoB lines
v9: unchanged
v8: First inclusing upon comment on mailing list

 include/linux/mdio.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 9f3587a61e145..ecac96d52e010 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -7,6 +7,7 @@
 #define __LINUX_MDIO_H__
 
 #include <uapi/linux/mdio.h>
+#include <linux/bitfield.h>
 #include <linux/mod_devicetable.h>
 
 /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
@@ -14,6 +15,7 @@
  */
 #define MII_ADDR_C45		(1<<30)
 #define MII_DEVADDR_C45_SHIFT	16
+#define MII_DEVADDR_C45_MASK	GENMASK(20, 16)
 #define MII_REGADDR_C45_MASK	GENMASK(15, 0)
 
 struct gpio_desc;
@@ -381,6 +383,16 @@ static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
 	return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
 }
 
+static inline u16 mdiobus_c45_regad(u32 regnum)
+{
+	return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
+}
+
+static inline u16 mdiobus_c45_devad(u32 regnum)
+{
+	return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
+}
+
 static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
 				     u16 regnum)
 {
-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 03:43:56 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 11:43:56 +0000
Subject: [PATCH v11 3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
 access
Message-ID: <YdQy/Mh4RA61pe9J@makrotopia.org>

Implement read and write access to IEEE 802.3 Clause 45 Ethernet
phy registers while making use of new mdiobus_c45_regad and
mdiobus_c45_devad helpers.

Tested on the Ubiquiti UniFi 6 LR access point featuring
MediaTek MT7622BV WiSoC with Aquantia AQR112C.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v11: pass return value of mtk_mdio_wait_busy
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros, incl. newly introduced ones
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 70 +++++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +
 2 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3809ea6e31ce2..d1f9ea3ec9c0d 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -103,13 +103,35 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
 	if (ret)
 		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_WRITE |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr) |
-		     PHY_IAC_DATA(write_data),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		ret = mtk_mdio_busy_wait(eth);
+		if (ret < 0)
+			return ret;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	}
 
 	ret = mtk_mdio_busy_wait(eth);
 	if (ret < 0)
@@ -126,12 +148,33 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 	if (ret)
 		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_C22_READ |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		ret = mtk_mdio_busy_wait(eth);
+		if (ret < 0)
+			return ret;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_READ |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_C22_READ |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	}
 
 	ret = mtk_mdio_busy_wait(eth);
 	if (ret < 0)
@@ -504,6 +547,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
 	eth->mii_bus->name = "mdio";
 	eth->mii_bus->read = mtk_mdio_read;
 	eth->mii_bus->write = mtk_mdio_write;
+	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
 	eth->mii_bus->priv = eth;
 	eth->mii_bus->parent = eth->dev;
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f2d90639d7ed1..c9d42be314b5a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -346,9 +346,12 @@
 #define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
 #define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
 #define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_C45_ADDR	FIELD_PREP(PHY_IAC_CMD_MASK, 0)
 #define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
 #define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_CMD_C45_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 3)
 #define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C45	FIELD_PREP(PHY_IAC_START_MASK, 0)
 #define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
 #define PHY_IAC_DATA_MASK	GENMASK(15, 0)
 #define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
-- 
2.34.1



From allen-kh.cheng at mediatek.com  Tue Jan  4 03:47:04 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:47:04 +0800
Subject: [PATCH 0/2] Add SCP support for mt8186 
Message-ID: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

changes since v1:
- use mt8192_power_on_sram() helper
- add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
- add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h

Based on v5.16-rc8

allen-kh.cheng (2):
  dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
  remoteproc: mediatek: Support mt8186 scp

 .../bindings/remoteproc/mtk,scp.yaml          |  1 +
 drivers/remoteproc/mtk_common.h               |  3 ++
 drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
 3 files changed, 39 insertions(+)

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 03:47:05 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:47:05 +0800
Subject: [PATCH 1/2] dt-bindings: remoteproc: mediatek: Add binding for mt8186
 scp
In-Reply-To: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
References: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104114706.27461-2-allen-kh.cheng@mediatek.com>

Add mt8186 compatible to binding document.

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index d21a25ee96e6..5b693a2d049c 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-scp
+      - mediatek,mt8186-scp
       - mediatek,mt8192-scp
       - mediatek,mt8195-scp
 
-- 
2.18.0



From robert.foss at linaro.org  Tue Jan  4 03:56:51 2022
From: robert.foss at linaro.org (Robert Foss)
Date: Tue, 4 Jan 2022 12:56:51 +0100
Subject: [PATCH 1/3] drm/stm: dsi: move lane capability detection in
 probe()
In-Reply-To: <20c77dc1-7e7e-ec0e-f545-593d1cfeb3b3@foss.st.com>
References: <20211218215055.212421-1-antonio.borneo@foss.st.com>
 <20c77dc1-7e7e-ec0e-f545-593d1cfeb3b3@foss.st.com>
Message-ID: <CAG3jFyu-btTaP+6YFTzPi13jD3RyqAWQq1QJUk3A_dVKjT4T4w@mail.gmail.com>

On Tue, 4 Jan 2022 at 11:47, Philippe CORNU <philippe.cornu at foss.st.com> wrote:
>
>
>
> On 12/18/21 10:50 PM, Antonio Borneo wrote:
> > There is no need to re-compute the dsi lane capability because it
> > only depends on dsi hw version.
> > Since dsi hw version is detected at probe(), move there also the
> > assignment of dsi lane capability.
> >
> > Signed-off-by: Antonio Borneo <antonio.borneo at foss.st.com>
> > ---
> > To: David Airlie <airlied at linux.ie>
> > To: Daniel Vetter <daniel at ffwll.ch>
> > To: Andrzej Hajda <a.hajda at samsung.com>
> > To: Neil Armstrong <narmstrong at baylibre.com>
> > To: Robert Foss <robert.foss at linaro.org>
> > To: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> > To: Jonas Karlman <jonas at kwiboo.se>
> > To: Jernej Skrabec <jernej.skrabec at gmail.com>
> > To: Yannick Fertre <yannick.fertre at foss.st.com>
> > To: Philippe Cornu <philippe.cornu at foss.st.com>
> > To: Benjamin Gaignard <benjamin.gaignard at linaro.org>
> > To: Maxime Coquelin <mcoquelin.stm32 at gmail.com>
> > To: Alexandre Torgue <alexandre.torgue at foss.st.com>
> > To: Philipp Zabel <p.zabel at pengutronix.de>
> > To: dri-devel at lists.freedesktop.org
> > To: linux-stm32 at st-md-mailman.stormreply.com
> > To: linux-arm-kernel at lists.infradead.org
> > Cc: linux-kernel at vger.kernel.org
> > ---
> >   drivers/gpu/drm/stm/dw_mipi_dsi-stm.c | 16 ++++++++--------
> >   1 file changed, 8 insertions(+), 8 deletions(-)
> >
>
> Hi Antonio,
> many thanks for your patch.
> Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
> Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>
> Philippe :-)

Thanks for the series and the Acks.

Applied series to drm-misc-next


From allen-kh.cheng at mediatek.com  Tue Jan  4 03:47:06 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 19:47:06 +0800
Subject: [PATCH 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
References: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104114706.27461-3-allen-kh.cheng@mediatek.com>

Add SCP support for mt8186

Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
---
 drivers/remoteproc/mtk_common.h |  3 +++
 drivers/remoteproc/mtk_scp.c    | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 5ff3867c72f3..71ce4977cb0b 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -32,6 +32,9 @@
 #define MT8183_SCP_CACHESIZE_8KB	BIT(8)
 #define MT8183_SCP_CACHE_CON_WAYEN	BIT(10)
 
+#define MT8186_SCP_L1_SRAM_PD_P1	0x40B0
+#define MT8186_SCP_L1_SRAM_PD_p2	0x40B4
+
 #define MT8192_L2TCM_SRAM_PD_0		0x10C0
 #define MT8192_L2TCM_SRAM_PD_1		0x10C4
 #define MT8192_L2TCM_SRAM_PD_2		0x10C8
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..6860ea4d5125 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -383,6 +383,27 @@ static void mt8192_power_off_sram(void __iomem *addr)
 		writel(GENMASK(i, 0), addr);
 }
 
+static int mt8186_scp_before_load(struct mtk_scp *scp)
+{
+	/* Clear SCP to host interrupt */
+	writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+	/* Reset clocks before loading FW */
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+	/* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
+	mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+	/* Initialize TCM before loading FW. */
+	writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2);
+
+	return 0;
+}
+
 static int mt8192_scp_before_load(struct mtk_scp *scp)
 {
 	/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -887,6 +908,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 	.ipi_buf_offset = 0x7bdb0,
 };
 
+static const struct mtk_scp_of_data mt8186_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
+	.scp_before_load = mt8186_scp_before_load,
+	.scp_irq_handler = mt8183_scp_irq_handler,
+	.scp_reset_assert = mt8183_scp_reset_assert,
+	.scp_reset_deassert = mt8183_scp_reset_deassert,
+	.scp_stop = mt8183_scp_stop,
+	.scp_da_to_va = mt8183_scp_da_to_va,
+	.host_to_scp_reg = MT8183_HOST_TO_SCP,
+	.host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT,
+	.ipi_buf_offset = 0x7bdb0,
+};
+
 static const struct mtk_scp_of_data mt8192_of_data = {
 	.scp_clk_get = mt8192_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
@@ -913,6 +947,7 @@ static const struct mtk_scp_of_data mt8195_of_data = {
 
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
+	{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
 	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
-- 
2.18.0



From daniel at makrotopia.org  Tue Jan  4 04:05:51 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 12:05:51 +0000
Subject: [PATCH v12 0/3] net: ethernet: mtk_eth_soc: refactoring and Clause 45
Message-ID: <YdQ4HzLjpuVW4YFi@makrotopia.org>

Rework value and type of mdio read and write functions in mtk_eth_soc
and generally clean up and unify both functions.
Then add support to access Clause 45 phy registers, using newly
introduced helper macros added by a patch Russell King has suggested
in a reply to an earlier version of this series [1].

All three commits are tested on the Bananapi BPi-R64 board having
MediaTek MT7531BE DSA gigE switch using clause 22 MDIO and
Ubiquiti UniFi 6 LR access point having Aquantia AQR112C PHY using
clause 45 MDIO.

[1]: https://lore.kernel.org/netdev/Ycr5Cna76eg2B0An at shell.armlinux.org.uk/

v12: replace 'ret != 0' forgotten from an earlier iteration with
     'ret < 0' checks of mtk_mdio_busy_wait return value (purely
     cosmetical as anyway either 0 or -ETIMEDOUT is returned, sorry
     for the noise)
v11: also address return value of mtk_mdio_busy_wait
v10: correct order of SoB lines in 2/3, change patch order in series
v9: improved formatting and Cc missing maintainer
v8: add patch from Russel King, switch to bitfield helper macros
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

Daniel Golle (2):
  net: ethernet: mtk_eth_soc: fix return values and refactor MDIO ops
  net: ethernet: mtk_eth_soc: implement Clause 45 MDIO access

Russell King (Oracle) (1):
  net: mdio: add helpers to extract clause 45 regad and devad fields

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 101 +++++++++++++++-----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  19 +++-
 include/linux/mdio.h                        |  12 +++
 3 files changed, 102 insertions(+), 30 deletions(-)

-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 04:06:22 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 12:06:22 +0000
Subject: [PATCH v12 1/3] net: ethernet: mtk_eth_soc: fix return values and
 refactor MDIO ops
Message-ID: <YdQ4PpiYFt90iUoS@makrotopia.org>

Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
while writing or 0xffff if it happens while reading, return the
appropriate -ETIMEDOUT. Also fix return type to int instead of u32.
Refactor functions to use bitfield helpers instead of having various
masking and shifting constants in the code, which also results in the
register definitions in the header file being more obviously related
to what is stated in the MediaTek's Reference Manual.

Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v12: check for 'ret < 0' in all places instead of 'ret != 0' in some
v11: also address return value of mtk_mdio_busy_wait
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros
v7: remove unneeded variables
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++++++++++++---------
 drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++++--
 2 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index bcb91b01e69f5..3809ea6e31ce2 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -91,46 +91,53 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
 	}
 
 	dev_err(eth->dev, "mdio: MDIO timeout\n");
-	return -1;
+	return -ETIMEDOUT;
 }
 
-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
-			   u32 phy_register, u32 write_data)
+static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
+			   u32 write_data)
 {
-	if (mtk_mdio_busy_wait(eth))
-		return -1;
+	int ret;
 
-	write_data &= 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
-		(phy_register << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_WRITE |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr) |
+		     PHY_IAC_DATA(write_data),
 		MTK_PHY_IAC);
 
-	if (mtk_mdio_busy_wait(eth))
-		return -1;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
 	return 0;
 }
 
-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
+static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 {
-	u32 d;
+	int ret;
 
-	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
-		(phy_reg << PHY_IAC_REG_SHIFT) |
-		(phy_addr << PHY_IAC_ADDR_SHIFT),
+	mtk_w32(eth, PHY_IAC_ACCESS |
+		     PHY_IAC_START_C22 |
+		     PHY_IAC_CMD_C22_READ |
+		     PHY_IAC_REG(phy_reg) |
+		     PHY_IAC_ADDR(phy_addr),
 		MTK_PHY_IAC);
 
-	if (mtk_mdio_busy_wait(eth))
-		return 0xffff;
-
-	d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
+	ret = mtk_mdio_busy_wait(eth);
+	if (ret < 0)
+		return ret;
 
-	return d;
+	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
 }
 
 static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 5ef70dd8b49c6..f2d90639d7ed1 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -341,11 +341,17 @@
 /* PHY Indirect Access Control registers */
 #define MTK_PHY_IAC		0x10004
 #define PHY_IAC_ACCESS		BIT(31)
-#define PHY_IAC_READ		BIT(19)
-#define PHY_IAC_WRITE		BIT(18)
-#define PHY_IAC_START		BIT(16)
-#define PHY_IAC_ADDR_SHIFT	20
-#define PHY_IAC_REG_SHIFT	25
+#define PHY_IAC_REG_MASK	GENMASK(29, 25)
+#define PHY_IAC_REG(x)		FIELD_PREP(PHY_IAC_REG_MASK, (x))
+#define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
+#define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
+#define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
+#define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
+#define PHY_IAC_DATA_MASK	GENMASK(15, 0)
+#define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
 #define PHY_IAC_TIMEOUT		HZ
 
 #define MTK_MAC_MISC		0x1000c
-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 04:07:00 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 12:07:00 +0000
Subject: [PATCH v12 2/3] net: mdio: add helpers to extract clause 45 regad
 and devad fields
Message-ID: <YdQ4ZGhkKVRzqG7G@makrotopia.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

Add a couple of helpers and definitions to extract the clause 45 regad
and devad fields from the regnum passed into MDIO drivers.

Tested-by: Daniel Golle <daniel at makrotopia.org>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v12: unchanged
v11: unchanged, added Reviewed-by: line from Andrew Lunn
v10: correct order of SoB lines
v9: unchanged
v8: First inclusing upon comment on mailing list

 include/linux/mdio.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 9f3587a61e145..ecac96d52e010 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -7,6 +7,7 @@
 #define __LINUX_MDIO_H__
 
 #include <uapi/linux/mdio.h>
+#include <linux/bitfield.h>
 #include <linux/mod_devicetable.h>
 
 /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
@@ -14,6 +15,7 @@
  */
 #define MII_ADDR_C45		(1<<30)
 #define MII_DEVADDR_C45_SHIFT	16
+#define MII_DEVADDR_C45_MASK	GENMASK(20, 16)
 #define MII_REGADDR_C45_MASK	GENMASK(15, 0)
 
 struct gpio_desc;
@@ -381,6 +383,16 @@ static inline u32 mdiobus_c45_addr(int devad, u16 regnum)
 	return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
 }
 
+static inline u16 mdiobus_c45_regad(u32 regnum)
+{
+	return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
+}
+
+static inline u16 mdiobus_c45_devad(u32 regnum)
+{
+	return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
+}
+
 static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
 				     u16 regnum)
 {
-- 
2.34.1



From daniel at makrotopia.org  Tue Jan  4 04:07:46 2022
From: daniel at makrotopia.org (Daniel Golle)
Date: Tue, 4 Jan 2022 12:07:46 +0000
Subject: [PATCH v12 3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
 access
Message-ID: <YdQ4kvyhR0kZ2GDL@makrotopia.org>

Implement read and write access to IEEE 802.3 Clause 45 Ethernet
phy registers while making use of new mdiobus_c45_regad and
mdiobus_c45_devad helpers.

Tested on the Ubiquiti UniFi 6 LR access point featuring
MediaTek MT7622BV WiSoC with Aquantia AQR112C.

Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
v12: unchanged
v11: pass return value of mtk_mdio_wait_busy
v10: unchanged
v9: improved formatting and Cc missing maintainer
v8: switch to bitfield helper macros, incl. newly introduced ones
v7: remove unneeded variables and order OR-ed call parameters
v6: further clean up functions and more cleanly separate patches
v5: fix wrong variable name in first patch covered by follow-up patch
v4: clean-up return values and types, split into two commits
v3: return -1 instead of 0xffff on error in _mtk_mdio_write
v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
    device id and register address. Unify read and write functions to
    have identical types and parameter names where possible as we are
    anyway already replacing both function bodies.

 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 70 +++++++++++++++++----
 drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +
 2 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3809ea6e31ce2..d1f9ea3ec9c0d 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -103,13 +103,35 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
 	if (ret < 0)
 		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_WRITE |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr) |
-		     PHY_IAC_DATA(write_data),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		ret = mtk_mdio_busy_wait(eth);
+		if (ret < 0)
+			return ret;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_WRITE |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(write_data),
+			MTK_PHY_IAC);
+	}
 
 	ret = mtk_mdio_busy_wait(eth);
 	if (ret < 0)
@@ -126,12 +148,33 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
 	if (ret < 0)
 		return ret;
 
-	mtk_w32(eth, PHY_IAC_ACCESS |
-		     PHY_IAC_START_C22 |
-		     PHY_IAC_CMD_C22_READ |
-		     PHY_IAC_REG(phy_reg) |
-		     PHY_IAC_ADDR(phy_addr),
-		MTK_PHY_IAC);
+	if (phy_reg & MII_ADDR_C45) {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_ADDR |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr) |
+			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
+			MTK_PHY_IAC);
+
+		ret = mtk_mdio_busy_wait(eth);
+		if (ret < 0)
+			return ret;
+
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C45 |
+			     PHY_IAC_CMD_C45_READ |
+			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	} else {
+		mtk_w32(eth, PHY_IAC_ACCESS |
+			     PHY_IAC_START_C22 |
+			     PHY_IAC_CMD_C22_READ |
+			     PHY_IAC_REG(phy_reg) |
+			     PHY_IAC_ADDR(phy_addr),
+			MTK_PHY_IAC);
+	}
 
 	ret = mtk_mdio_busy_wait(eth);
 	if (ret < 0)
@@ -504,6 +547,7 @@ static int mtk_mdio_init(struct mtk_eth *eth)
 	eth->mii_bus->name = "mdio";
 	eth->mii_bus->read = mtk_mdio_read;
 	eth->mii_bus->write = mtk_mdio_write;
+	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
 	eth->mii_bus->priv = eth;
 	eth->mii_bus->parent = eth->dev;
 
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index f2d90639d7ed1..c9d42be314b5a 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -346,9 +346,12 @@
 #define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
 #define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
 #define PHY_IAC_CMD_MASK	GENMASK(19, 18)
+#define PHY_IAC_CMD_C45_ADDR	FIELD_PREP(PHY_IAC_CMD_MASK, 0)
 #define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
 #define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
+#define PHY_IAC_CMD_C45_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 3)
 #define PHY_IAC_START_MASK	GENMASK(17, 16)
+#define PHY_IAC_START_C45	FIELD_PREP(PHY_IAC_START_MASK, 0)
 #define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
 #define PHY_IAC_DATA_MASK	GENMASK(15, 0)
 #define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
-- 
2.34.1



From clabbe.montjoie at gmail.com  Tue Jan  4 04:09:13 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 13:09:13 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
Message-ID: <YdQ46conUeZ3Qaac@Red>

Le Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) a ?crit :
> On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > Hello
> > > > 
> > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > 
> > > How is the PHY connected to the host (which interface mode?) If it's
> > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > DT.
> > > 
> > 
> > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > The only change to the mainline dtb is removing the max-speed.
> 
> So, it's using "rgmii" with no delay configured at the PHY with the
> speed limited to 100Mbps. You then remove the speed limitation and
> it doesn't work at 1Gbps.
> 
> I think I've seen this on other platforms (imx6 + ar8035) when the
> RGMII delay is not correctly configured - it will work at slower
> speeds but not 1G.
> 
> The RGMII spec specifies that there will be a delay - and the delay can
> be introduced by either the MAC, PHY or by PCB track routing. It sounds
> to me like your boot environment configures the PHY to introduce the
> necessary delay, but then, because the DT "rgmii" mode means "no delay
> at the PHY" when you use the Marvell driver (which respects that), the
> Marvell driver configures the PHY for no delay, resulting in a non-
> working situation at 1G.
> 
> I would suggest checking how the boot environment configures the PHY,
> and change the "rgmii" mode in DT to match. There is a description of
> the four RGMII modes in Documentation/networking/phy.rst that may help
> understand what each one means.
> 

So if I understand, the generic PHY does not touch delays and so values set by bootloader are kept.

The boot environment give no clue on how the PHY is set.
Only debug showed is:
PHY 0 Addr 1 Vendor ID: 0x01410e11
mii_write: phy_addr=0x1 reg_addr=0x4 value=0x5e1 
mii_write: phy_addr=0x1 reg_addr=0x9 value=0x300 
mii_write: phy_addr=0x1 reg_addr=0x0 value=0x1200 
mii_write: phy_addr=0x1 reg_addr=0x0 value=0x9200 
mii_write: phy_addr=0x1 reg_addr=0x0 value=0x1200

Does it is possible to dump PHY registers when using generic PHY and find delay values ?
For example ethtool -d eth0 ?

If not, my only choice is to bruteforce all delay values until it works.


From linux at armlinux.org.uk  Tue Jan  4 04:11:55 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 12:11:55 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
Message-ID: <YdQ5i+//UITSbxS/@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) wrote:
> On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > Hello
> > > > 
> > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > 
> > > How is the PHY connected to the host (which interface mode?) If it's
> > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > DT.
> > > 
> > 
> > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > The only change to the mainline dtb is removing the max-speed.
> 
> So, it's using "rgmii" with no delay configured at the PHY with the
> speed limited to 100Mbps. You then remove the speed limitation and
> it doesn't work at 1Gbps.
> 
> I think I've seen this on other platforms (imx6 + ar8035) when the
> RGMII delay is not correctly configured - it will work at slower
> speeds but not 1G.
> 
> The RGMII spec specifies that there will be a delay - and the delay can
> be introduced by either the MAC, PHY or by PCB track routing. It sounds
> to me like your boot environment configures the PHY to introduce the
> necessary delay, but then, because the DT "rgmii" mode means "no delay
> at the PHY" when you use the Marvell driver (which respects that), the
> Marvell driver configures the PHY for no delay, resulting in a non-
> working situation at 1G.
> 
> I would suggest checking how the boot environment configures the PHY,
> and change the "rgmii" mode in DT to match. There is a description of
> the four RGMII modes in Documentation/networking/phy.rst that may help
> understand what each one means.

Hmm. Sorry, I'm leading you stray. It looks like the 88E1118 code does
not program any delays depending on the interface mode, so changing that
will have no effect.

I suspect, looking at m88e1118_config_init(), that the write to register
0x15 in the MSCR page could be the problem.

0x15 is 21, which is MII_88E1121_PHY_MSCR_REG. In other Marvell PHYs,
bits 4 and 5 are the tx and rx delays, both of which are set. Looking
at m88e1121_config_aneg_rgmii_delays(), this would seem to indicate
that the PHY is being placed into rgmii-id mode.

Can you try changing:

	err = phy_write(phydev, 0x15, 0x1070);

to:

	err = phy_write(phydev, 0x15, 0x1040);

and see what happens? Maybe trying other combinations of bits 4 and 5
to find a working combination.

I think if we discover a setting there that works, we may have a problem,
since changing this could end up breaking some platforms. Looking at the
commit history...

2f495c398edc net/phy/marvell: Expose IDs and flags in a .h and add dns323 LEDs setup flag
605f196efbf8 phy: Add support for Marvell 88E1118 PHY

and the second is a less than helpful commit message...

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan  4 04:17:11 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 12:17:11 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQ46conUeZ3Qaac@Red>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ46conUeZ3Qaac@Red>
Message-ID: <YdQ6x2Mz2lOJOQdp@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 01:09:13PM +0100, Corentin Labbe wrote:
> Le Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) a ?crit :
> > On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > > Hello
> > > > > 
> > > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > > 
> > > > How is the PHY connected to the host (which interface mode?) If it's
> > > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > > DT.
> > > > 
> > > 
> > > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > > The only change to the mainline dtb is removing the max-speed.
> > 
> > So, it's using "rgmii" with no delay configured at the PHY with the
> > speed limited to 100Mbps. You then remove the speed limitation and
> > it doesn't work at 1Gbps.
> > 
> > I think I've seen this on other platforms (imx6 + ar8035) when the
> > RGMII delay is not correctly configured - it will work at slower
> > speeds but not 1G.
> > 
> > The RGMII spec specifies that there will be a delay - and the delay can
> > be introduced by either the MAC, PHY or by PCB track routing. It sounds
> > to me like your boot environment configures the PHY to introduce the
> > necessary delay, but then, because the DT "rgmii" mode means "no delay
> > at the PHY" when you use the Marvell driver (which respects that), the
> > Marvell driver configures the PHY for no delay, resulting in a non-
> > working situation at 1G.
> > 
> > I would suggest checking how the boot environment configures the PHY,
> > and change the "rgmii" mode in DT to match. There is a description of
> > the four RGMII modes in Documentation/networking/phy.rst that may help
> > understand what each one means.
> > 
> 
> So if I understand, the generic PHY does not touch delays and so values set by bootloader are kept.

Correct - the RGMII delays are not part of the standard 802.3 clause 22
register set, so the generic driver has no knowledge how to change
these.

> The boot environment give no clue on how the PHY is set.
> Only debug showed is:
> PHY 0 Addr 1 Vendor ID: 0x01410e11
> mii_write: phy_addr=0x1 reg_addr=0x4 value=0x5e1 
> mii_write: phy_addr=0x1 reg_addr=0x9 value=0x300 
> mii_write: phy_addr=0x1 reg_addr=0x0 value=0x1200 
> mii_write: phy_addr=0x1 reg_addr=0x0 value=0x9200 
> mii_write: phy_addr=0x1 reg_addr=0x0 value=0x1200

Hmm, it doesn't. The first two register writes set the advertisement.
The last three are just the PHY reset.

> Does it is possible to dump PHY registers when using generic PHY and
> find delay values ? For example ethtool -d eth0 ?

Even if that were possible, Marvell PHYs use a paged scheme to access
configuration registers, so merely reading the 32 registers would
probably not help. However, see my follow-up to my previous reply for
some further thoughts.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From catalin.marinas at arm.com  Tue Jan  4 04:33:17 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 4 Jan 2022 12:33:17 +0000
Subject: [PATCH 5/5] arm64: mte: Document the core dump file format
In-Reply-To: <03135b87-31f2-510c-44ec-1fe3ad0ca4b1@linaro.org>
References: <20211208121941.494956-1-catalin.marinas@arm.com>
 <20211208121941.494956-6-catalin.marinas@arm.com>
 <03135b87-31f2-510c-44ec-1fe3ad0ca4b1@linaro.org>
Message-ID: <YdQ+jcu+ZD7Q2Tki@arm.com>

Hi Luis,

On Mon, Jan 03, 2022 at 02:27:54PM -0300, Luis Machado wrote:
> On 12/8/21 9:19 AM, Catalin Marinas wrote:
> > diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
> > index 7b99c8f428eb..34c7eb47f61e 100644
> > --- a/Documentation/arm64/memory-tagging-extension.rst
> > +++ b/Documentation/arm64/memory-tagging-extension.rst
> > @@ -213,6 +213,28 @@ address ABI control and MTE configuration of a process as per the
> >   Documentation/arm64/tagged-address-abi.rst and above. The corresponding
> >   ``regset`` is 1 element of 8 bytes (``sizeof(long))``).
> > +Core dump support
> > +-----------------
> > +
> > +The allocation tags for user memory mapped with ``PROT_MTE`` are dumped
> > +in the core file as additional ``PT_ARM_MEMTAG_MTE`` segments. The
> > +program header for such segment is defined as:
> > +
> > +:``p_type``: ``PT_ARM_MEMTAG_MTE``
> > +:``p_flags``: 0
> > +:``p_offset``: segment file offset
> > +:``p_vaddr``: segment virtual address, same as the corresponding
> > +  ``PT_LOAD`` segment
> > +:``p_paddr``: 0
> > +:``p_filesz``: segment size in file, calculated as ``p_mem_sz / 16 / 2``
> 
> For the sake of making things extra clear, I'd describe what the constants
> (16 and 2) mean.

I'll rewrite this as: "``p_mem_sz / 32`` (two 4-bit tags cover 32 bytes
of memory)". I find the "16 / 2" more confusing.

> Acked-by: Luis Machado <luis.machado at linaro.org>

Thanks for the acks.

-- 
Catalin


From broonie at kernel.org  Tue Jan  4 04:58:16 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Jan 2022 12:58:16 +0000
Subject: [PATCH 3/3] spi: apple: Add driver for Apple SPI controller
In-Reply-To: <20220101072548.GA28593@wunner.de>
References: <20211212034726.26306-1-marcan@marcan.st>
 <20211212034726.26306-4-marcan@marcan.st>
 <20220101072548.GA28593@wunner.de>
Message-ID: <YdREaCo5BXHqtoex@sirena.org.uk>

On Sat, Jan 01, 2022 at 08:25:48AM +0100, Lukas Wunner wrote:

> This is especially important if there are slaves attached to the
> controller which perform SPI transfers in their ->remove hooks,
> e.g. to quiesce interrupts on the slaves.  Those transfers won't
> work the way you've structured the code now.

The client drivers shouldn't notice - their remove callbacks will have
completed before we start removing the controller.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/38698a47/attachment.sig>

From catalin.marinas at arm.com  Tue Jan  4 05:02:27 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 4 Jan 2022 13:02:27 +0000
Subject: [PATCH] arm64: Drop outdated links in comments
In-Reply-To: <YbsZkr4gfhcQGON6@arm.com>
References: <20211215191835.1420010-1-keescook@chromium.org>
 <YbsZkr4gfhcQGON6@arm.com>
Message-ID: <YdRFY5P+gutrtSzr@arm.com>

On Thu, Dec 16, 2021 at 10:48:50AM +0000, Catalin Marinas wrote:
> On Wed, Dec 15, 2021 at 11:18:35AM -0800, Kees Cook wrote:
> > As started by commit 05a5f51ca566 ("Documentation: Replace lkml.org links
> > with lore"), an effort was made to replace lkml.org links with lore to
> > better use a single source that's more likely to stay available long-term.
> > However, it seems these links don't offer much value here, so just
> > remove them entirely.
> > 
> > Cc: Joe Perches <joe at perches.com>
> > Suggested-by: Will Deacon <will at kernel.org>
> > Link: https://lore.kernel.org/lkml/20210211100213.GA29813 at willie-the-truck/
> > Signed-off-by: Kees Cook <keescook at chromium.org>
> > ---
> >  arch/arm/kernel/hibernate.c   | 4 ----
> >  arch/arm64/kernel/hibernate.c | 4 ----
> >  2 files changed, 8 deletions(-)
> > 
> > diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c
> > index 2373020af965..2c1f290342e4 100644
> > --- a/arch/arm/kernel/hibernate.c
> > +++ b/arch/arm/kernel/hibernate.c
> > @@ -7,10 +7,6 @@
> >   * Ubuntu project, hibernation support for mach-dove
> >   * Copyright (C) 2010 Nokia Corporation (Hiroshi Doyu)
> >   * Copyright (C) 2010 Texas Instruments, Inc. (Teerth Reddy et al.)
> > - *  https://lkml.org/lkml/2010/6/18/4
> > - *  https://lists.linux-foundation.org/pipermail/linux-pm/2010-June/027422.html
> > - *  https://patchwork.kernel.org/patch/96442/
> > - *
> >   * Copyright (C) 2006 Rafael J. Wysocki <rjw at sisk.pl>
> >   */
> 
> Happy to take the patch through the arm64 tree if Russell acks,
> otherwise I'll just take the arm64 hunk.

Russell, any objections to this patch going through the arm64 tree?

-- 
Catalin


From mark.rutland at arm.com  Tue Jan  4 05:24:02 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 4 Jan 2022 13:24:02 +0000
Subject: Possible nohz-full/RCU issue in arm64 KVM
In-Reply-To: <20211220161014.GC918551@lothringen>
References: <d80e440375896f75d45e227d40af60ca7ba24ceb.camel@redhat.com>
 <YbyO40zDW/kvUHEE@FVFF77S0Q05N>
 <20211220161014.GC918551@lothringen>
Message-ID: <YdRJA79bs1Im7h01@FVFF77S0Q05N>

On Mon, Dec 20, 2021 at 05:10:14PM +0100, Frederic Weisbecker wrote:
> On Fri, Dec 17, 2021 at 01:21:39PM +0000, Mark Rutland wrote:
> > On Fri, Dec 17, 2021 at 12:51:57PM +0100, Nicolas Saenz Julienne wrote:
> > > Hi All,
> > 
> > Hi,
> > 
> > > arm64's guest entry code does the following:
> > > 
> > > int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
> > > {
> > > 	[...]
> > > 
> > > 	guest_enter_irqoff();
> > > 
> > > 	ret = kvm_call_hyp_ret(__kvm_vcpu_run, vcpu);
> > > 
> > > 	[...]
> > > 
> > > 	local_irq_enable();
> > > 
> > > 	/*
> > > 	 * We do local_irq_enable() before calling guest_exit() so
> > > 	 * that if a timer interrupt hits while running the guest we
> > > 	 * account that tick as being spent in the guest.  We enable
> > > 	 * preemption after calling guest_exit() so that if we get
> > > 	 * preempted we make sure ticks after that is not counted as
> > > 	 * guest time.
> > > 	 */
> > > 	guest_exit();
> > > 	[...]
> > > }
> > > 
> > > 
> > > On a nohz-full CPU, guest_{enter,exit}() delimit an RCU extended quiescent
> > > state (EQS). Any interrupt happening between local_irq_enable() and
> > > guest_exit() should disable that EQS. Now, AFAICT all el0 interrupt handlers
> > > do the right thing if trggered in this context, but el1's won't. Is it
> > > possible to hit an el1 handler (for example __el1_irq()) there?
> > 
> > I think you're right that the EL1 handlers can trigger here and won't exit the
> > EQS.
> > 
> > I'm not immediately sure what we *should* do here. What does x86 do for an IRQ
> > taken from a guest mode? I couldn't spot any handling of that case, but I'm not
> > familiar enough with the x86 exception model to know if I'm looking in the
> > right place.
> 
> This is one of the purposes of rcu_irq_enter(). el1 handlers don't call irq_enter()?

Due to lockep/tracing/etc ordering, we don't use irq_enter() directly and
instead call rcu_irq_enter() and irq_enter_rcu() separately. Critically we only
call rcu_irq_enter() for IRQs taken from the idle thread, as this was
previously thought to be the only place where we could take an IRQ from an EL1
EQS.

See __el1_irq(), __enter_from_kernel_mode(), and __exit_to_kernel_mode() in
arch/arm64/kernel/entry-common.c. The latter two are largely analogous to the
common irqentry_enter9) and irqentry_exit() helpers in kernel/entry/common.c.

We need to either rework the KVM code or that entry code. I'll dig into this a
bit more...

Thanks,
Mark.


From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:22 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:22 +0800
Subject: [PATCH 0/6] Add basic node support for Mediatek MT8186 SoC
Message-ID: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

MT8186 is a SoC based on 64bit ARMv8 architecture.
It contains 6 CA55 and 2 CA78 cores.
MT8186 share many HW IP with MT65xx series.

This patchset was tested on MT8186 evaluation board to shell.

Based on v5.16-rc8

Allen-KH Cheng (6):
  dt-bindings: timer: Add compatible for Mediatek MT8186
  dt-bindings: serial: Add compatible for Mediatek MT8186
  dt-bindings: watchdog: Add compatible for Mediatek MT8186
  dt-bindings: mmc: Add compatible for Mediatek MT8186
  dt-bindings: phy: Add compatible for Mediatek MT8186
  arm64: dts: Add Mediatek SoC MT8186 dts and evaluation board and
    Makefile

 .../devicetree/bindings/mmc/mtk-sd.yaml       |   3 +
 .../bindings/phy/mediatek,tphy.yaml           |   1 +
 .../devicetree/bindings/serial/mtk-uart.txt   |   1 +
 .../bindings/timer/mediatek,mtk-timer.txt     |   1 +
 .../devicetree/bindings/watchdog/mtk-wdt.txt  |   1 +
 arch/arm64/boot/dts/mediatek/Makefile         |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts   |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi      | 352 ++++++++++++++++++
 8 files changed, 384 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:25 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:25 +0800
Subject: [PATCH 3/6] dt-bindings: watchdog: Add compatible for Mediatek MT8186
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of watchdog for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 0114871f887a..74db01e3658b 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -15,6 +15,7 @@ Required properties:
 	"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
 	"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
 	"mediatek,mt8183-wdt": for MT8183
+	"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
 	"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
 	"mediatek,mt8192-wdt": for MT8192
 	"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:27 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:27 +0800
Subject: [PATCH 5/6] dt-bindings: phy: Add compatible for Mediatek MT8186
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of T-Phy for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 9e6c0f43f1c6..cadbc696b3f5 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -80,6 +80,7 @@ properties:
               - mediatek,mt2712-tphy
               - mediatek,mt7629-tphy
               - mediatek,mt8183-tphy
+              - mediatek,mt8186-tphy
           - const: mediatek,generic-tphy-v2
       - items:
           - enum:
-- 
2.18.0



From maz at kernel.org  Tue Jan  4 05:44:31 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 04 Jan 2022 13:44:31 +0000
Subject: [PATCH v1 1/1] KVM: arm64: vgic: Replace kernel.h with the
 necessary inclusions
In-Reply-To: <YcN5FKnbT9BHLn9f@smile.fi.intel.com>
References: <20211222165552.69288-1-andriy.shevchenko@linux.intel.com>
 <8735mk1pgt.wl-maz@kernel.org>
 <YcNtpnxbyDA/CGgc@smile.fi.intel.com>
 <YcN5FKnbT9BHLn9f@smile.fi.intel.com>
Message-ID: <87iluzvcn4.wl-maz@kernel.org>

On Wed, 22 Dec 2021 19:14:28 +0000,
Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> 
> On Wed, Dec 22, 2021 at 08:25:43PM +0200, Andy Shevchenko wrote:
> > On Wed, Dec 22, 2021 at 06:09:22PM +0000, Marc Zyngier wrote:
> > > On Wed, 22 Dec 2021 16:55:52 +0000,
> > > Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> > > > 
> > > > When kernel.h is used in the headers it adds a lot into dependency hell,
> > > > especially when there are circular dependencies are involved.
> > > 
> > > Which circular dependencies? What problem are you solving?
> > 
> > In particular moving bitmap_*alloc() APIs to the headers.
> > 
> > But this may be a side effect of what I realized during the attempts
> > of solving that issue. In any case there is no need to take entire
> > mess of kernel.h in another header.
> 
> For the record  `make headerdep` doesn't make any difference with
> or without this patch. But I consider it's better not to use kernel.h
> in the headers due to a full mess behind it.

Can you then please write a commit message that matches what this is
actually doing instead of mentioning a problem that doesn't seem to
exist?

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:23 +0800
Subject: [PATCH 1/6] dt-bindings: timer: Add compatible for Mediatek MT8186
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of timer for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index e5c57d6e0186..e0d20d6adf81 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -22,6 +22,7 @@ Required properties:
 
 	For those SoCs that use SYST
 	* "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
+	* "mediatek,mt8186-timer" for MT8186 compatible timers (SYST)
 	* "mediatek,mt8192-timer" for MT8192 compatible timers (SYST)
 	* "mediatek,mt8195-timer" for MT8195 compatible timers (SYST)
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:26 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:26 +0800
Subject: [PATCH 4/6] dt-bindings: mmc: Add compatible for Mediatek MT8186
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of mmc for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index 82768a807294..164df702482f 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -29,6 +29,9 @@ properties:
       - items:
           - const: mediatek,mt7623-mmc
           - const: mediatek,mt2701-mmc
+      - items:
+          - const: mediatek,mt8186-mmc
+          - const: mediatek,mt8183-mmc
       - items:
           - const: mediatek,mt8192-mmc
           - const: mediatek,mt8183-mmc
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:24 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:24 +0800
Subject: [PATCH 2/6] dt-bindings: serial: Add compatible for Mediatek MT8186
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of uart for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index b3a0bfef0d54..113b5d6a2245 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -20,6 +20,7 @@ Required properties:
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
   * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
+  * "mediatek,mt8186-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
   * "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS
   * "mediatek,mt8195-uart", "mediatek,mt6577-uart" for MT8195 compatible UARTS
   * "mediatek,mt8516-uart" for MT8516 compatible UARTS
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 05:34:28 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:34:28 +0800
Subject: [PATCH 6/6] arm64: dts: Add Mediatek SoC MT8186 dts and evaluation
 board and Makefile
In-Reply-To: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
References: <20220104133428.28893-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104133428.28893-7-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add basic chip support for Mediatek MT8186

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi    | 352 ++++++++++++++++++++
 3 files changed, 377 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 4f68ebed2e31..2271c3452c64 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -31,5 +31,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
new file mode 100644
index 000000000000..eb23d1f19f87
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+#include "mt8186.dtsi"
+
+/ {
+	model = "MediaTek MT8186 evaluation board";
+	compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
new file mode 100644
index 000000000000..fce84c341291
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+
+/ {
+	compatible = "mediatek,mt8186";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0000>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu1: cpu at 001 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0100>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu2: cpu at 002 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0200>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu3: cpu at 003 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0300>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu4: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0400>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu5: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0500>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu6: cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0600>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu7: cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0700>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+				
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+
+				core4 {
+					cpu = <&cpu4>;
+				};
+
+				core5 {
+					cpu = <&cpu5>;
+				};
+
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu6>;
+				};
+
+				core1 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpuoff_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1600>;
+			};
+
+			cpuoff_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1400>;
+			};
+
+			clusteroff_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <2100>;
+			};
+
+			clusteroff_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <1900>;
+			};
+
+			mcusysoff: mcusys-off {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <300>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2600>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+	};
+
+	psci {
+		compatible      = "arm,psci-1.0";
+		method          = "smc";
+	};
+
+	gic: interrupt-controller {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#redistributor-regions = <1>;
+		interrupt-parent = <&gic>;
+		interrupt-controller;
+		reg = <0 0x0c000000 0 0x40000>, // distributor
+		      <0 0x0c040000 0 0x200000>; // redistributor
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	watchdog: watchdog at 10007000 {
+		compatible = "mediatek,mt8186-wdt",
+				"mediatek,mt6589-wdt";
+		reg = <0 0x10007000 0 0x1000>;
+	};
+
+	sys_timer at 10017000 {
+		compatible = "mediatek,mt8186_timer",
+			     "mediatek,mt6765-timer";
+		reg = <0 0x10017000 0 0x1000>;
+		interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>;
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		clock-frequency = <13000000>;
+	};
+
+	uart0: serial at 11002000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11002000 0 0x1000>;
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+	};
+
+	uart1: serial at 11003000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11003000 0 0x1000>;
+		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart2: serial at 11018000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11018000 0 0x1000>;
+		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	mmc0: mmc at 11230000 {
+		compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
+		reg = <0 0x11230000 0 0x1000>,
+		      <0 0x11cd0000 0 0x1000>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>;
+		clock-names = "source", "hclk", "source_cg",
+			      "ahb_clk";
+		status = "disabled";
+	};
+
+	mmc1: mmc at 11240000 {
+		compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
+		reg = <0 0x11240000 0 0x1000>,
+		      <0 0x11c90000 0 0x1000>;
+		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>;
+		clock-names = "source", "hclk", "source_cg";
+		status = "disabled";
+	};
+
+	u3phy1: usb-phy1 at 11c80000 {
+		compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "okay";
+
+		u2port1: usb2-phy1 at 11c80000 {
+			reg = <0 0x11c80000 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+
+		u3port1: usb3-phy1 at 11c80900 {
+			reg = <0 0x11c80900 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
+	u3phy0: usb-phy at 11ca0000 {
+		compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "okay";
+
+		u2port0: usb2-phy at 11ca0000 {
+			reg = <0 0x11ca0000 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			mediatek,discth = <0x8>;
+			status = "okay";
+		};
+	};
+};
-- 
2.18.0



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 05:45:12 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 13:45:12 +0000
Subject: [PATCH v4] soc: ti: smartreflex: Use platform_get_irq_optional() to
 get the interrupt
Message-ID: <20220104134512.18498-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq_optional().

While at it return 0 instead of returning ret in the probe success path.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v3->v4:
* Used dev_err_probe() to print error message
* Returning 0 in probe success path.

v2->v3
* Switch back to platform_get_irq_optional()
* Only print error in case of error, and not when interrupt is missing.

v1->v2
* Updated commit message
* Drop check for IRQ0
* Switched to using platform_get_irq() so that the probe won't
  fail silently as requested by Nishanth.

v1:
* https://www.spinics.net/lists/arm-kernel/msg942549.html
---
 drivers/soc/ti/smartreflex.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
index b5b2fa538d5c..a219c003a63f 100644
--- a/drivers/soc/ti/smartreflex.c
+++ b/drivers/soc/ti/smartreflex.c
@@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info;
 	struct omap_sr_data *pdata = pdev->dev.platform_data;
-	struct resource *mem, *irq;
+	struct resource *mem;
 	struct dentry *nvalue_dir;
 	int i, ret = 0;
 
@@ -844,7 +844,13 @@ static int omap_sr_probe(struct platform_device *pdev)
 	if (IS_ERR(sr_info->base))
 		return PTR_ERR(sr_info->base);
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	ret = platform_get_irq_optional(pdev, 0);
+	if (ret < 0 && ret != -ENXIO) {
+		dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);
+		return ret;
+	}
+	if (ret > 0)
+		sr_info->irq = ret;
 
 	sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
 	if (IS_ERR(sr_info->fck))
@@ -870,9 +876,6 @@ static int omap_sr_probe(struct platform_device *pdev)
 	sr_info->autocomp_active = false;
 	sr_info->ip_type = pdata->ip_type;
 
-	if (irq)
-		sr_info->irq = irq->start;
-
 	sr_set_clk_length(sr_info);
 
 	list_add(&sr_info->node, &sr_list);
@@ -926,7 +929,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 
 	}
 
-	return ret;
+	return 0;
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
-- 
2.17.1



From andriy.shevchenko at linux.intel.com  Tue Jan  4 05:45:47 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue, 4 Jan 2022 15:45:47 +0200
Subject: [PATCH v1 1/1] KVM: arm64: vgic: Replace kernel.h with the
 necessary inclusions
In-Reply-To: <87iluzvcn4.wl-maz@kernel.org>
References: <20211222165552.69288-1-andriy.shevchenko@linux.intel.com>
 <8735mk1pgt.wl-maz@kernel.org>
 <YcNtpnxbyDA/CGgc@smile.fi.intel.com>
 <YcN5FKnbT9BHLn9f@smile.fi.intel.com>
 <87iluzvcn4.wl-maz@kernel.org>
Message-ID: <YdRPi65NyiigKPPG@smile.fi.intel.com>

On Tue, Jan 04, 2022 at 01:44:31PM +0000, Marc Zyngier wrote:
> On Wed, 22 Dec 2021 19:14:28 +0000,
> Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> > On Wed, Dec 22, 2021 at 08:25:43PM +0200, Andy Shevchenko wrote:
> > > On Wed, Dec 22, 2021 at 06:09:22PM +0000, Marc Zyngier wrote:
> > > > On Wed, 22 Dec 2021 16:55:52 +0000,
> > > > Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> > > > > 
> > > > > When kernel.h is used in the headers it adds a lot into dependency hell,
> > > > > especially when there are circular dependencies are involved.
> > > > 
> > > > Which circular dependencies? What problem are you solving?
> > > 
> > > In particular moving bitmap_*alloc() APIs to the headers.
> > > 
> > > But this may be a side effect of what I realized during the attempts
> > > of solving that issue. In any case there is no need to take entire
> > > mess of kernel.h in another header.
> > 
> > For the record  `make headerdep` doesn't make any difference with
> > or without this patch. But I consider it's better not to use kernel.h
> > in the headers due to a full mess behind it.
> 
> Can you then please write a commit message that matches what this is
> actually doing instead of mentioning a problem that doesn't seem to
> exist?

Sure, thanks for review!

-- 
With Best Regards,
Andy Shevchenko




From philippe.cornu at foss.st.com  Tue Jan  4 05:52:52 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 14:52:52 +0100
Subject: [PATCH] drm/stm: remove conflicting framebuffers
In-Reply-To: <58cc264b-7b46-7869-1c38-f6d79a4daafe@foss.st.com>
References: <20211206134735.13537-1-yannick.fertre@foss.st.com>
 <10c5672d-a228-ed9e-2f32-1ce9ae86dbcc@suse.de>
 <58cc264b-7b46-7869-1c38-f6d79a4daafe@foss.st.com>
Message-ID: <5c58402b-9219-2789-f8c1-67cf2149beac@foss.st.com>



On 12/14/21 11:15 AM, Philippe CORNU wrote:
> 
> 
> On 12/6/21 3:23 PM, Thomas Zimmermann wrote:
>> Hi
>>
>> Am 06.12.21 um 14:47 schrieb Yannick Fertre:
>>> In case of using simplefb or another conflicting framebuffer,
>>> call drm_aperture_remove_framebuffers() to remove memory allocated.
>>>
>>> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
>>
>> The patch should have contained a note that this is version 2 of the 
>> change with a short changelog. Anyway
>>
>> Reviewed-by: Thomas Zimmermann <tzimmermann at suse.de>
>>
>> Best regards
>> Thomas
>>
>>> ---
>>> ? drivers/gpu/drm/stm/drv.c | 5 +++++
>>> ? 1 file changed, 5 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c
>>> index 222869b232ae..9f441aadf2d5 100644
>>> --- a/drivers/gpu/drm/stm/drv.c
>>> +++ b/drivers/gpu/drm/stm/drv.c
>>> @@ -14,6 +14,7 @@
>>> ? #include <linux/of_platform.h>
>>> ? #include <linux/pm_runtime.h>
>>> +#include <drm/drm_aperture.h>
>>> ? #include <drm/drm_atomic.h>
>>> ? #include <drm/drm_atomic_helper.h>
>>> ? #include <drm/drm_drv.h>
>>> @@ -183,6 +184,10 @@ static int stm_drm_platform_probe(struct 
>>> platform_device *pdev)
>>> ????? DRM_DEBUG("%s\n", __func__);
>>> +??? ret = drm_aperture_remove_framebuffers(false, &drv_driver);
>>> +??? if (ret)
>>> +??????? return ret;
>>> +
> 
> Hi Yannick,
> and many thanks for your patch.
> Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
> Philippe :-)
> 
> 
>>> ????? dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
>>> ????? ddev = drm_dev_alloc(&drv_driver, dev);
>>>
>>

Applied on drm-misc-next.
Many thanks for your patch,
Philippe :-)


From allen-kh.cheng at mediatek.com  Tue Jan  4 05:53:17 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 4 Jan 2022 21:53:17 +0800
Subject: [RESEND PATCH v10 0/3] This patches provide ADSP IPC support
 for MT8195
In-Reply-To: <20211210104153.24181-1-allen-kh.cheng@mediatek.com>
References: <20211210104153.24181-1-allen-kh.cheng@mediatek.com>
Message-ID: <2652267e57e4095e9d0bc265b93cf31f545b7683.camel@mediatek.com>

On Fri, 2021-12-10 at 18:41 +0800, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> Mediatek ADSP IPC is used to send notification or short message
> between
> processors with dsp.?
> 
> It will place the message to the share buffer and will access the
> ADSP mailbox
> registers to kick dsp.
> 
> Two mailboxes used to send notification or short message between
> processors with
> dsp
> 

Dear Matthias,

Do you have any comment about this patch series?

Thanks.

> changes since v9:
> - rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops
> 
> changes since v8:
> - remove struct adsp_mbox_ch_info
> - add get_mtk_adsp_mbox_priv
> - use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
> - add struct mtk_adsp_mbox_cfg for DSP mbox register offset
> - remove adsp mbox register offset hard code define
> - remove mtk-adsp-ipc.h reference in adsp mbox driver
> 
> changes since v7:
> - add mtk prefix for adsp ipc functions
> - rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
> - remove incorrect reviewers in commit message
> 
> changes since v6:
> - dt-bindings: change example dtsi node.
> - rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
> - remove unused variable
> - add reviewers
> 
> changes since v5:
> - remove some redundant code
> 
> changes since v4:
> - use switch ... case in adsp_ipc_recv
> - add error handling path for chan_name pointer
> - refine some code to be concise
> 
> changes since v3:
> - reorder MTK_ADSP_IPC_MBOX config
> - remove some redundant code
> - remove lock in mtk-adsp-mailbox
> 
> changes since v2:
> - separate adsp_mailbox into two instances
> 
> changes since v1:
> - fix dt_binding_check error
> 
> 
> Allen-KH Cheng (3):
>   dt-bindings: mediatek: add adsp-mbox document
>   firmware: mediatek: add adsp ipc protocol interface
>   mailbox: mediatek: add support for adsp mailbox controller
> 
>  .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
>  drivers/firmware/Kconfig                      |   1 +
>  drivers/firmware/Makefile                     |   1 +
>  drivers/firmware/mediatek/Kconfig             |   9 +
>  drivers/firmware/mediatek/Makefile            |   2 +
>  drivers/firmware/mediatek/mtk-adsp-ipc.c      | 135 ++++++++++++++
>  drivers/mailbox/Kconfig                       |   7 +
>  drivers/mailbox/Makefile                      |   2 +
>  drivers/mailbox/mtk-adsp-mailbox.c            | 176
> ++++++++++++++++++
>  .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
>  10 files changed, 450 insertions(+)
>  create mode 100644
> Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
>  create mode 100644 drivers/firmware/mediatek/Kconfig
>  create mode 100644 drivers/firmware/mediatek/Makefile
>  create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
>  create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c
>  create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h
> 



From philippe.cornu at foss.st.com  Tue Jan  4 05:53:34 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Tue, 4 Jan 2022 14:53:34 +0100
Subject: [PATCH] drm/stm: ltdc: support of new hardware version
In-Reply-To: <73ed4015-c707-53e5-394f-c74cd2f69df2@foss.st.com>
References: <20211203085618.11314-1-yannick.fertre@foss.st.com>
 <73ed4015-c707-53e5-394f-c74cd2f69df2@foss.st.com>
Message-ID: <a7cffc9a-1cf4-8900-22f8-fe2826198b3a@foss.st.com>



On 12/14/21 11:19 AM, Philippe CORNU wrote:
> 
> 
> On 12/3/21 9:56 AM, Yannick Fertre wrote:
>> Add support of new hardware version 0x40100.
>>
>> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
>> ---
>> ? drivers/gpu/drm/stm/ltdc.c | 172 ++++++++++++++++++++++++++++++-------
>> ? drivers/gpu/drm/stm/ltdc.h |?? 3 +-
>> ? 2 files changed, 145 insertions(+), 30 deletions(-)
>>
> 
> Hi Yannick,
> This looks great, many thanks for your patch.
> Acked-by: Philippe Cornu <philippe.cornu at foss.st.com>
> Philippe :-)

Applied on drm-misc-next.
Many thanks for your patch,
Philippe :-)


From will at kernel.org  Tue Jan  4 05:56:59 2022
From: will at kernel.org (Will Deacon)
Date: Tue, 4 Jan 2022 13:56:59 +0000
Subject: [PATCH v13 3/5] arm64: perf: Add userspace counter access
 disable switch
In-Reply-To: <CAMuHMdVcDxR9sGzc5pcnORiotonERBgc6dsXZXMd6wTvLGA9iw@mail.gmail.com>
References: <20211208201124.310740-1-robh@kernel.org>
 <20211208201124.310740-4-robh@kernel.org>
 <CAMuHMdVcDxR9sGzc5pcnORiotonERBgc6dsXZXMd6wTvLGA9iw@mail.gmail.com>
Message-ID: <20220104135658.GC1827@willie-the-truck>

Hi Geert,

On Tue, Dec 28, 2021 at 12:07:02PM +0100, Geert Uytterhoeven wrote:
> On Wed, Dec 8, 2021 at 9:19 PM Rob Herring <robh at kernel.org> wrote:
> > Like x86, some users may want to disable userspace PMU counter
> > altogether. Add a sysctl 'perf_user_access' file to control userspace
> > counter access. The default is '0' which is disabled. Writing '1'
> > enables access.
> >
> > Note that x86 supports globally enabling user access by writing '2' to
> > /sys/bus/event_source/devices/cpu/rdpmc. As there's not existing
> > userspace support to worry about, this shouldn't be necessary for Arm.
> > It could be added later if the need arises.
> 
> Thanks for your patch, which is now commit e2012600810c9ded ("arm64:
> perf: Add userspace counter access disable switch") in arm64/for-next/core.
> 
> This is causing two issues on Renesas Salvator-XS with R-Car H3.
> One during kernel boot:
> 
>      hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7
> counters available
>     +sysctl duplicate entry: /kernel//perf_user_access
>     +CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> 5.16.0-rc3-arm64-renesas-00003-ge2012600810c #1420
>     +Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
>     +Call trace:
>     + dump_backtrace+0x0/0x190
>     + show_stack+0x14/0x20
>     + dump_stack_lvl+0x88/0xb0
>     + dump_stack+0x14/0x2c
>     + __register_sysctl_table+0x384/0x818
>     + register_sysctl+0x20/0x28
>     + armv8_pmu_init.constprop.0+0x118/0x150
>     + armv8_a57_pmu_init+0x1c/0x28
>     + arm_pmu_device_probe+0x1b4/0x558
>     + armv8_pmu_device_probe+0x18/0x20
>     + platform_probe+0x64/0xd0
>     + really_probe+0xb4/0x2f8
>     + __driver_probe_device+0x74/0xd8
>     + driver_probe_device+0x3c/0xe0
>     + __driver_attach+0x80/0x110
>     + bus_for_each_dev+0x6c/0xc0
>     + driver_attach+0x20/0x28
>     + bus_add_driver+0x138/0x1e0
>     + driver_register+0x60/0x110
>     + __platform_driver_register+0x24/0x30
>     + armv8_pmu_driver_init+0x18/0x20
>     + do_one_initcall+0x15c/0x31c
>     + kernel_init_freeable+0x2f0/0x354
>     + kernel_init+0x20/0x120
>     + ret_from_fork+0x10/0x20
>      hw perfevents: enabled with armv8_cortex_a57 PMU driver, 7
> counters available
> 
> Presumably the same entry is added twice, once for the A53 PMU,
> and a second time for the A57 PMU?

Looks like it, and perhaps that's also what is confusing systemd?
Rob -- how come you didn't see this during your testing?

Anywho, please can you try the untested diff below?

Thanks,

Will

--->8

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 81cc9f0e718a..639f632aaa66 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1214,6 +1214,14 @@ static struct ctl_table armv8_pmu_sysctl_table[] = {
        { }
 };
 
+static void armv8_pmu_register_sysctl_table(void)
+{
+       static u32 tbl_registered = 0;
+
+       if (!cmpxchg_relaxed(&tbl_registered, 0, 1))
+               register_sysctl("kernel", armv8_pmu_sysctl_table);
+}
+
 static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
                          int (*map_event)(struct perf_event *event),
                          const struct attribute_group *events,
@@ -1248,8 +1256,7 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
        cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ?
                        caps : &armv8_pmuv3_caps_attr_group;
 
-       register_sysctl("kernel", armv8_pmu_sysctl_table);
-
+       armv8_pmu_register_sysctl_table();
        return 0;
 }
 



From clabbe.montjoie at gmail.com  Tue Jan  4 05:57:55 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 14:57:55 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQ5i+//UITSbxS/@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk>
Message-ID: <YdRSY50wyF7u8KCA@Red>

Le Tue, Jan 04, 2022 at 12:11:55PM +0000, Russell King (Oracle) a ?crit :
> On Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) wrote:
> > On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > > Hello
> > > > > 
> > > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > > 
> > > > How is the PHY connected to the host (which interface mode?) If it's
> > > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > > DT.
> > > > 
> > > 
> > > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > > The only change to the mainline dtb is removing the max-speed.
> > 
> > So, it's using "rgmii" with no delay configured at the PHY with the
> > speed limited to 100Mbps. You then remove the speed limitation and
> > it doesn't work at 1Gbps.
> > 
> > I think I've seen this on other platforms (imx6 + ar8035) when the
> > RGMII delay is not correctly configured - it will work at slower
> > speeds but not 1G.
> > 
> > The RGMII spec specifies that there will be a delay - and the delay can
> > be introduced by either the MAC, PHY or by PCB track routing. It sounds
> > to me like your boot environment configures the PHY to introduce the
> > necessary delay, but then, because the DT "rgmii" mode means "no delay
> > at the PHY" when you use the Marvell driver (which respects that), the
> > Marvell driver configures the PHY for no delay, resulting in a non-
> > working situation at 1G.
> > 
> > I would suggest checking how the boot environment configures the PHY,
> > and change the "rgmii" mode in DT to match. There is a description of
> > the four RGMII modes in Documentation/networking/phy.rst that may help
> > understand what each one means.
> 
> Hmm. Sorry, I'm leading you stray. It looks like the 88E1118 code does
> not program any delays depending on the interface mode, so changing that
> will have no effect.
> 
> I suspect, looking at m88e1118_config_init(), that the write to register
> 0x15 in the MSCR page could be the problem.
> 
> 0x15 is 21, which is MII_88E1121_PHY_MSCR_REG. In other Marvell PHYs,
> bits 4 and 5 are the tx and rx delays, both of which are set. Looking
> at m88e1121_config_aneg_rgmii_delays(), this would seem to indicate
> that the PHY is being placed into rgmii-id mode.
> 
> Can you try changing:
> 
> 	err = phy_write(phydev, 0x15, 0x1070);
> 
> to:
> 
> 	err = phy_write(phydev, 0x15, 0x1040);
> 
> and see what happens? Maybe trying other combinations of bits 4 and 5
> to find a working combination.
> 

I tried more than all combinaisons (0x1010, 0x1020, 0x1030, 0x1040, 0x1050, 0x1060) without success.
A phy_read() just before the phy_write() give 0x1040.
I have also removed the phy_write() without success.


From maz at kernel.org  Tue Jan  4 06:05:19 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue,  4 Jan 2022 14:05:19 +0000
Subject: [PATCH] KVM: arm64: Fix comment typo in kvm_vcpu_finalize_sve()
In-Reply-To: <20211230141535.1389-1-yuzenghui@huawei.com>
References: <20211230141535.1389-1-yuzenghui@huawei.com>
Message-ID: <164130511055.3362481.10306211546953262745.b4-ty@kernel.org>

On Thu, 30 Dec 2021 22:15:35 +0800, Zenghui Yu wrote:
> kvm_arm_init_arch_resources() was renamed to kvm_arm_init_sve() in
> commit a3be836df7cb ("KVM: arm/arm64: Demote
> kvm_arm_init_arch_resources() to just set up SVE"). Fix the function
> name in comment of kvm_vcpu_finalize_sve().

Applied to next, thanks!

[1/1] KVM: arm64: Fix comment typo in kvm_vcpu_finalize_sve()
      commit: e938eddbeb85f4c0c47e56cd9e09ee196ea1bc1a

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 06:09:13 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 14:09:13 +0000
Subject: [PATCH v2] pinctrl: at91-pio4: Use platform_get_irq() to get the
 interrupt
Message-ID: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

While at it, replace the dev_err() with dev_dbg() as platform_get_irq()
prints an error message upon error.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* Switched using platform_get_irq()
* Replaced dev_err() with dev_dbg()

v1: https://lore.kernel.org/lkml/20211224145748.18754-3-prabhakar.mahadev-lad.rj at bp.renesas.com/
---
 drivers/pinctrl/pinctrl-at91-pio4.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
index fafd1f55cba7..517f2a6330ad 100644
--- a/drivers/pinctrl/pinctrl-at91-pio4.c
+++ b/drivers/pinctrl/pinctrl-at91-pio4.c
@@ -1045,7 +1045,6 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
 	const char **group_names;
 	const struct of_device_id *match;
 	int i, ret;
-	struct resource	*res;
 	struct atmel_pioctrl *atmel_pioctrl;
 	const struct atmel_pioctrl_data *atmel_pioctrl_data;
 
@@ -1164,16 +1163,15 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
 
 	/* There is one controller but each bank has its own irq line. */
 	for (i = 0; i < atmel_pioctrl->nbanks; i++) {
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		if (!res) {
-			dev_err(dev, "missing irq resource for group %c\n",
+		ret = platform_get_irq(pdev, i);
+		if (ret < 0) {
+			dev_dbg(dev, "missing irq resource for group %c\n",
 				'A' + i);
-			return -EINVAL;
+			return ret;
 		}
-		atmel_pioctrl->irqs[i] = res->start;
-		irq_set_chained_handler_and_data(res->start,
-			atmel_gpio_irq_handler, atmel_pioctrl);
-		dev_dbg(dev, "bank %i: irq=%pr\n", i, res);
+		atmel_pioctrl->irqs[i] = ret;
+		irq_set_chained_handler_and_data(ret, atmel_gpio_irq_handler, atmel_pioctrl);
+		dev_dbg(dev, "bank %i: irq=%d\n", i, ret);
 	}
 
 	atmel_pioctrl->irq_domain = irq_domain_add_linear(dev->of_node,
-- 
2.17.1



From clabbe.montjoie at gmail.com  Tue Jan  4 06:11:46 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 15:11:46 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdQ5i+//UITSbxS/@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk>
Message-ID: <YdRVovG9mgEWffkn@Red>

Le Tue, Jan 04, 2022 at 12:11:55PM +0000, Russell King (Oracle) a ?crit :
> On Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) wrote:
> > On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > > Hello
> > > > > 
> > > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > > 
> > > > How is the PHY connected to the host (which interface mode?) If it's
> > > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > > DT.
> > > > 
> > > 
> > > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > > The only change to the mainline dtb is removing the max-speed.
> > 
> > So, it's using "rgmii" with no delay configured at the PHY with the
> > speed limited to 100Mbps. You then remove the speed limitation and
> > it doesn't work at 1Gbps.
> > 
> > I think I've seen this on other platforms (imx6 + ar8035) when the
> > RGMII delay is not correctly configured - it will work at slower
> > speeds but not 1G.
> > 
> > The RGMII spec specifies that there will be a delay - and the delay can
> > be introduced by either the MAC, PHY or by PCB track routing. It sounds
> > to me like your boot environment configures the PHY to introduce the
> > necessary delay, but then, because the DT "rgmii" mode means "no delay
> > at the PHY" when you use the Marvell driver (which respects that), the
> > Marvell driver configures the PHY for no delay, resulting in a non-
> > working situation at 1G.
> > 
> > I would suggest checking how the boot environment configures the PHY,
> > and change the "rgmii" mode in DT to match. There is a description of
> > the four RGMII modes in Documentation/networking/phy.rst that may help
> > understand what each one means.
> 
> Hmm. Sorry, I'm leading you stray. It looks like the 88E1118 code does
> not program any delays depending on the interface mode, so changing that
> will have no effect.
> 
> I suspect, looking at m88e1118_config_init(), that the write to register
> 0x15 in the MSCR page could be the problem.
> 
> 0x15 is 21, which is MII_88E1121_PHY_MSCR_REG. In other Marvell PHYs,
> bits 4 and 5 are the tx and rx delays, both of which are set. Looking
> at m88e1121_config_aneg_rgmii_delays(), this would seem to indicate
> that the PHY is being placed into rgmii-id mode.
> 
> Can you try changing:
> 
> 	err = phy_write(phydev, 0x15, 0x1070);
> 
> to:
> 
> 	err = phy_write(phydev, 0x15, 0x1040);
> 
> and see what happens? Maybe trying other combinations of bits 4 and 5
> to find a working combination.
> 

Forget my other message, using 0x1040 lead to success.
My problem was that I tried rgmii-id which net/ethernet/cortina does not support on some code path. (everything test PHY_INTERFACE_MODE_RGMII only)
So I retry tests with original phy-mode = "rgmii".

So with the following changes everything is ok:
diff --git a/arch/arm/boot/dts/gemini-ssi1328.dts b/arch/arm/boot/dts/gemini-ssi1328.dts
index 113feb1c4922..7543d117a13a 100644
--- a/arch/arm/boot/dts/gemini-ssi1328.dts
+++ b/arch/arm/boot/dts/gemini-ssi1328.dts
@@ -40,10 +40,6 @@ mdio0: mdio {
                phy0: ethernet-phy at 1 {
                        reg = <1>;
                        device_type = "ethernet-phy";
-                       /* We lack the knowledge of necessary GPIO to achieve
-                        * Gigabit
-                        */
-                       max-speed = <100>;
                };
                /* WAN ICPlus IP101A */
                phy1: ethernet-phy at 2 {
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4fcfca4e1702..af7fc9d8eaa7 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1233,7 +1233,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
                return err;
 
        /* Enable 1000 Mbit */
-       err = phy_write(phydev, 0x15, 0x1070);
+       err = phy_write(phydev, 0x15, 0x1040);
        if (err < 0)
                return err;
 



From lorenzo.pieralisi at arm.com  Tue Jan  4 06:17:52 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue, 4 Jan 2022 14:17:52 +0000
Subject: [PATCH v10 0/7] PCI: brcmstb: root port turns on sub-device power
In-Reply-To: <d659ec6c-ddf8-87b9-ebf1-b32c3730d038@gmail.com>
References: <20211209211407.8102-1-jim2101024@gmail.com>
 <YbOf836C58fUSmCO@robh.at.kernel.org>
 <d659ec6c-ddf8-87b9-ebf1-b32c3730d038@gmail.com>
Message-ID: <20220104141742.GA27804@lpieralisi>

On Fri, Dec 10, 2021 at 12:31:10PM -0800, Florian Fainelli wrote:
> On 12/10/21 10:44 AM, Rob Herring wrote:
> > On Thu, Dec 09, 2021 at 04:13:58PM -0500, Jim Quinlan wrote:
> >> v10 -- Bindings commit example: in comment, refer to bridge under
> >>        controller node as a root port. (Pali)
> >>     -- Bindings commit example: remove three properties that are not
> >>        appropriate for a PCIe endpoint node. (Rob)
> >>
> >> v9  -- Simplify where this mechanism works: instead of looking for
> >>        regulators below every bridge, just look for them at the
> >>        bridge under the root bus (root port).  Now there is no
> >>        modification of portdrv_{pci,core}.c in this submission.
> >>     -- Although Pali is working on support for probing native
> >>        PCIe controller drivers, this work may take some time to
> >>        implement and it still might not be able to accomodate
> >>        our driver's requirements (e.g. vreg suspend/resume control).
> >>     -- Move regulator suspend/resume control to Brcm RC driver.  It
> >>        must reside there because (a) in order to know when to
> >>        initiate linkup during resume and (b) to turn on the
> >>        regulators before any config-space accesses occur.
> > 
> > You now have a mixture of 'generic' add/remove_bus hooks and the host 
> > controller suspend/resume managing the regulators. I think long term, 
> > the portdrv is going to be the right place for all of this with some 
> > interface defined for link control. So I think this solution moves 
> > sideways rather than towards anything common.
> > 
> > Unfortunately, the only leverage maintainers have to get folks to care 
> > about any refactoring is to reject features. We're lucky to find anyone 
> > to test refactoring when posted if done independently. There's a long 
> > list of commits of PCI hosts that I've broken to prove that. So it's 
> > up to Lorenzo and Bjorn on what they want to do here.
> 
> After version 10, it would seem pretty clear that we are still very much
> committed to and interested in getting that set merged and do it the
> most acceptable way possible. Common code with a single user is always a
> little bit of a grey area to me as it tends to be developed to cater for
> the specific needs of that single user, so the entire common aspect is
> debatable. I suppose as long as we have the binding right, the code can
> change at will.
> 
> Not trying to coerce Bjorn and Lorenzo into accepting these patches if
> they don't feel comfortable, but what about getting it included so we
> can sort of move on from that topic for a little bit (as we have other
> PCIe changes coming in, supporting additional chips etc.) and we work
> with Pali on a common solution and ensure it works on our pcie-brcmstb.c
> based devices? We are not going to vanish and not come back looking at this.

Sorry for being late on reviewing this set. I agree with both of you.

I don't think Bjorn had a chance to have a look at patch (4) now I am
delegating it to him; I am not very keen on adding functionality to PCI
core where it is still a question whether it can be reused by other
drivers (forgive me if I missed some details on previous review
versions).

Is it possible to keep patch (4) brcmstb specific (ie keep the code
out of PCI core for now), we then merge this series and help Pali
implement a generic version based on Rob's suggestion ?

Just let me know please, thanks.

Lorenzo


From jolsa at redhat.com  Tue Jan  4 06:19:35 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Tue, 4 Jan 2022 15:19:35 +0100
Subject: [PATCH v3 03/48] perf stat: Correct aggregation CPU map
In-Reply-To: <20211230072030.302559-5-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-5-irogers@google.com>
Message-ID: <YdRXd4jBUfduSSAY@krava>

On Wed, Dec 29, 2021 at 11:19:45PM -0800, Ian Rogers wrote:
> Switch the perf_cpu_map in aggr_update_shadow from
> the evlist to the counter's cpu map, so the index is appropriate. This
> addresses a problem where uncore counts, with a cpumap like:
> $ cat /sys/devices/uncore_imc_0/cpumask
> 0,18
> Don't aggregate counts in CPUs based on the index of those values in the
> cpumap (0 and 1) but on the actual CPU (0 and 18). Thereby correcting
> metric calculations in per-socket mode for counters without a full
> cpumask.
> 
> On a SkylakeX with a tweaked DRAM_BW_Use metric, to remove unnecessary
> scaling, this gives:
> 
> Before:
> $ /perf stat --per-socket -M DRAM_BW_Use -I 1000
>      1.001102293 S0        1              27.01 MiB  uncore_imc/cas_count_write/ #   103.00 DRAM_BW_Use
>      1.001102293 S0        1              30.22 MiB  uncore_imc/cas_count_read/
>      1.001102293 S0        1      1,001,102,293 ns   duration_time
>      1.001102293 S1        1              20.10 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
>      1.001102293 S1        1              32.74 MiB  uncore_imc/cas_count_read/
>      1.001102293 S1        0      <not counted> ns   duration_time
>      2.003517973 S0        1              83.04 MiB  uncore_imc/cas_count_write/ #   920.00 DRAM_BW_Use
>      2.003517973 S0        1             145.95 MiB  uncore_imc/cas_count_read/
>      2.003517973 S0        1      1,002,415,680 ns   duration_time
>      2.003517973 S1        1             302.45 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
>      2.003517973 S1        1             290.99 MiB  uncore_imc/cas_count_read/
>      2.003517973 S1        0      <not counted> ns   duration_time
> 
> After:
> $ perf stat --per-socket -M DRAM_BW_Use -I 1000
>      1.001080840 S0        1              24.96 MiB  uncore_imc/cas_count_write/ #    54.00 DRAM_BW_Use
>      1.001080840 S0        1              33.64 MiB  uncore_imc/cas_count_read/
>      1.001080840 S0        1      1,001,080,840 ns   duration_time
>      1.001080840 S1        1              42.43 MiB  uncore_imc/cas_count_write/ #    84.00 DRAM_BW_Use
>      1.001080840 S1        1              47.05 MiB  uncore_imc/cas_count_read/
>      1.001080840 S1        0      <not counted> ns   duration_time
> 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/util/stat-display.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
> index 588601000f3f..b0fa81ffce61 100644
> --- a/tools/perf/util/stat-display.c
> +++ b/tools/perf/util/stat-display.c
> @@ -526,7 +526,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,
>  		evlist__for_each_entry(evlist, counter) {
>  			val = 0;
>  			for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
> -				s2 = config->aggr_get_id(config, evlist->core.cpus, cpu);
> +				s2 = config->aggr_get_id(config, evsel__cpus(counter), cpu);
>  				if (!cpu_map__compare_aggr_cpu_id(s2, id))
>  					continue;
>  				val += perf_counts(counter->counts, cpu, 0)->val;

makes sense, there's another instance of this in first_shadow_cpu

thanks,
jirka

> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 



From jolsa at redhat.com  Tue Jan  4 06:19:44 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Tue, 4 Jan 2022 15:19:44 +0100
Subject: [PATCH v3 08/48] perf cpumap: Remove map+index get_die
In-Reply-To: <20211230072030.302559-10-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-10-irogers@google.com>
Message-ID: <YdRXgF4OoFnU6MUo@krava>

On Wed, Dec 29, 2021 at 11:19:50PM -0800, Ian Rogers wrote:
> Migrate final users to appropriate cpu variant.
> 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/tests/topology.c | 2 +-
>  tools/perf/util/cpumap.c    | 9 ---------
>  tools/perf/util/cpumap.h    | 1 -
>  tools/perf/util/stat.c      | 2 +-
>  4 files changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
> index 69a64074b897..ce085b6f379b 100644
> --- a/tools/perf/tests/topology.c
> +++ b/tools/perf/tests/topology.c
> @@ -136,7 +136,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
>  
>  	// Test that die ID contains socket and die
>  	for (i = 0; i < map->nr; i++) {
> -		id = cpu_map__get_die(map, i, NULL);
> +		id = cpu_map__get_die_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
>  		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
>  			session->header.env.cpu[map->map[i]].socket_id == id.socket);
>  
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 342a5eaee9d3..ff91c32da688 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -216,15 +216,6 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
>  	return id;
>  }
>  
> -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
> -				    void *data)
> -{
> -	if (idx < 0 || idx > map->nr)
> -		return cpu_map__empty_aggr_cpu_id();
> -
> -	return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
> -}
> -
>  int cpu_map__get_core_id(int cpu)
>  {
>  	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index a53af24301d2..365ed69699e1 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -34,7 +34,6 @@ int cpu_map__get_socket_id(int cpu);
>  struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
>  int cpu_map__get_die_id(int cpu);
>  struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
> -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
>  int cpu_map__get_core_id(int cpu);
>  struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
>  struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
> diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
> index 9eca1111fa52..5ed99bcfe91e 100644
> --- a/tools/perf/util/stat.c
> +++ b/tools/perf/util/stat.c
> @@ -336,7 +336,7 @@ static int check_per_pkg(struct evsel *counter,
>  	 * On multi-die system, die_id > 0. On no-die system, die_id = 0.
>  	 * We use hashmap(socket, die) to check the used socket+die pair.
>  	 */
> -	d = cpu_map__get_die(cpus, cpu, NULL).die;
> +	d = cpu_map__get_die_id(cpu);
>  	if (d < 0)
>  		return -1;

looking on this I realized that probably we have broken

  perf stat record
  perf stat report

if that report is run on different machine, because we
take die from current system

should be fixed in another patchset though

jirka



From jolsa at redhat.com  Tue Jan  4 06:20:01 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Tue, 4 Jan 2022 15:20:01 +0100
Subject: [PATCH v3 18/48] perf cpumap: Refactor cpu_map__build_map
In-Reply-To: <20211230072030.302559-20-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-20-irogers@google.com>
Message-ID: <YdRXkXIVAkgO1p0d@krava>

On Wed, Dec 29, 2021 at 11:20:00PM -0800, Ian Rogers wrote:

SNIP

> +		return 0;
> +
> +	stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.cpus, get_id, env);
> +	if (!stat_config.aggr_map) {
> +		pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]);
> +		return -1;
> +	}
> +	stat_config.aggr_get_id = aggr_mode__get_id_file(stat_config.aggr_mode);
>  	return 0;
>  }
>  
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 32f9fc2dd389..ba4468f691c8 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -140,7 +140,7 @@ struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_u
>  	return id;
>  }
>  
> -static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
> +static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
>  {
>  	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
>  	struct aggr_cpu_id *b = (struct aggr_cpu_id *)b_pointer;
> @@ -157,37 +157,40 @@ static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
>  		return a->thread - b->thread;
>  }
>  
> -int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> -		       struct aggr_cpu_id (*f)(int cpu, void *data),
> -		       void *data)
> +struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
> +				       aggr_cpu_id_get_t f,

s/f/get_id/ ?

jirka


> +				       void *data)
>  {
> -	int nr = cpus->nr;
> -	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(nr);
> -	int cpu, s2;
> -	struct aggr_cpu_id s1;
> +	int cpu, idx;
> +	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(cpus->nr);

SNIP



From jolsa at redhat.com  Tue Jan  4 06:21:27 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Tue, 4 Jan 2022 15:21:27 +0100
Subject: [PATCH v3] perf evlist: Remove group option.
In-Reply-To: <20211230072030.302559-3-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-3-irogers@google.com>
Message-ID: <YdRX5zgB3AORM/Wd@krava>

On Wed, Dec 29, 2021 at 11:19:43PM -0800, Ian Rogers wrote:
> The group option predates grouping events using curly braces added in
> commit 89efb029502d ("perf tools: Add support to parse event group syntax")
> The --group option was retained for legacy support (in August 2012) but
> keeping it adds complexity.
> 
> v2 and v3. were rebases.
> 
> Signed-off-by: Ian Rogers <irogers at google.com>

it should not be part of this patchset right?
I see it was posted separately

jirka

> ---
>  tools/perf/Documentation/perf-record.txt |  4 ----
>  tools/perf/Documentation/perf-top.txt    |  7 ++-----
>  tools/perf/builtin-record.c              |  2 --
>  tools/perf/builtin-stat.c                |  6 ------
>  tools/perf/builtin-top.c                 |  2 --
>  tools/perf/tests/attr/README             |  2 --
>  tools/perf/tests/attr/test-record-group  | 22 ----------------------
>  tools/perf/tests/attr/test-stat-group    | 17 -----------------
>  tools/perf/util/evlist.c                 |  2 +-
>  tools/perf/util/evlist.h                 |  2 --
>  tools/perf/util/python.c                 |  8 --------
>  tools/perf/util/record.c                 |  7 -------
>  tools/perf/util/record.h                 |  1 -
>  13 files changed, 3 insertions(+), 79 deletions(-)
>  delete mode 100644 tools/perf/tests/attr/test-record-group
>  delete mode 100644 tools/perf/tests/attr/test-stat-group
> 
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index 55df7b073a55..960fb1ad3f27 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -238,10 +238,6 @@ OPTIONS
>  	Also, by adding a comma, the number of mmap pages for AUX
>  	area tracing can be specified.
>  
> ---group::
> -	Put all events in a single event group.  This precedes the --event
> -	option and remains only for backward compatibility.  See --event.
> -
>  -g::
>  	Enables call-graph (stack chain/backtrace) recording for both
>  	kernel space and user space.
> diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
> index cac3dfbee7d8..acbafe777e52 100644
> --- a/tools/perf/Documentation/perf-top.txt
> +++ b/tools/perf/Documentation/perf-top.txt
> @@ -51,9 +51,6 @@ Default is to monitor all CPUS.
>  --count-filter=<count>::
>  	Only display functions with more events than this.
>  
> ---group::
> -        Put the counters into a counter group.
> -
>  --group-sort-idx::
>  	Sort the output by the event at the index n in group. If n is invalid,
>  	sort by the first event. It can support multiple groups with different
> @@ -313,10 +310,10 @@ use '-e e1 -e e2 -G foo,foo' or just use '-e e1 -e e2 -G foo'.
>  
>  		perf top -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
>  
> -	   Alternatively one can ask for --group and then two overhead columns
> +	   Alternatively one can ask for a group and then two overhead columns
>             will appear, the first for cycles and the second for the switch-on event.
>  
> -		perf top --group -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
> +		perf top -e '{cycles,probe:icmp_rcv}' --switch-on=probe:icmp_rcv
>  
>  	This may be interesting to measure a workload only after some initialization
>  	phase is over, i.e. insert a perf probe at that point and use the above
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index 6ac2160913ea..54eff61f78eb 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -2521,8 +2521,6 @@ static struct option __record_options[] = {
>  	OPT_CALLBACK(0, "mmap-flush", &record.opts, "number",
>  		     "Minimal number of bytes that is extracted from mmap data pages (default: 1)",
>  		     record__mmap_flush_parse),
> -	OPT_BOOLEAN(0, "group", &record.opts.group,
> -		    "put the counters into a counter group"),
>  	OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
>  			   NULL, "enables call-graph recording" ,
>  			   &record_callchain_opt),
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index f6ca2b054c5b..8ce4ca6111ae 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -180,7 +180,6 @@ static bool			topdown_run			= false;
>  static bool			smi_cost			= false;
>  static bool			smi_reset			= false;
>  static int			big_num_opt			=  -1;
> -static bool			group				= false;
>  static const char		*pre_cmd			= NULL;
>  static const char		*post_cmd			= NULL;
>  static bool			sync_run			= false;
> @@ -800,9 +799,6 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
>  		child_pid = evsel_list->workload.pid;
>  	}
>  
> -	if (group)
> -		evlist__set_leader(evsel_list);
> -
>  	if (affinity__setup(&affinity) < 0)
>  		return -1;
>  
> @@ -1212,8 +1208,6 @@ static struct option stat_options[] = {
>  #endif
>  	OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
>  		    "system-wide collection from all CPUs"),
> -	OPT_BOOLEAN('g', "group", &group,
> -		    "put the counters into a counter group"),
>  	OPT_BOOLEAN(0, "scale", &stat_config.scale,
>  		    "Use --no-scale to disable counter scaling for multiplexing"),
>  	OPT_INCR('v', "verbose", &verbose,
> diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
> index 1fc390f136dd..0d8441942f34 100644
> --- a/tools/perf/builtin-top.c
> +++ b/tools/perf/builtin-top.c
> @@ -1472,8 +1472,6 @@ int cmd_top(int argc, const char **argv)
>  			    "dump the symbol table used for profiling"),
>  	OPT_INTEGER('f', "count-filter", &top.count_filter,
>  		    "only display functions with more events than this"),
> -	OPT_BOOLEAN(0, "group", &opts->group,
> -			    "put the counters into a counter group"),
>  	OPT_BOOLEAN('i', "no-inherit", &opts->no_inherit,
>  		    "child tasks do not inherit counters"),
>  	OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name",
> diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README
> index a36f49fb4dbe..f538272af57b 100644
> --- a/tools/perf/tests/attr/README
> +++ b/tools/perf/tests/attr/README
> @@ -47,7 +47,6 @@ Following tests are defined (with perf commands):
>    perf record -g kill                           (test-record-graph-default)
>    perf record --call-graph dwarf kill		(test-record-graph-dwarf)
>    perf record --call-graph fp kill              (test-record-graph-fp)
> -  perf record --group -e cycles,instructions kill (test-record-group)
>    perf record -e '{cycles,instructions}' kill   (test-record-group1)
>    perf record -e '{cycles/period=1/,instructions/period=2/}:S' kill (test-record-group2)
>    perf record -D kill                           (test-record-no-delay)
> @@ -61,6 +60,5 @@ Following tests are defined (with perf commands):
>    perf stat -d kill                             (test-stat-detailed-1)
>    perf stat -dd kill                            (test-stat-detailed-2)
>    perf stat -ddd kill                           (test-stat-detailed-3)
> -  perf stat --group -e cycles,instructions kill (test-stat-group)
>    perf stat -e '{cycles,instructions}' kill     (test-stat-group1)
>    perf stat -i -e cycles kill                   (test-stat-no-inherit)
> diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group
> deleted file mode 100644
> index 14ee60fd3f41..000000000000
> --- a/tools/perf/tests/attr/test-record-group
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -[config]
> -command = record
> -args    = --no-bpf-event --group -e cycles,instructions kill >/dev/null 2>&1
> -ret     = 1
> -
> -[event-1:base-record]
> -fd=1
> -group_fd=-1
> -sample_type=327
> -read_format=4
> -
> -[event-2:base-record]
> -fd=2
> -group_fd=1
> -config=1
> -sample_type=327
> -read_format=4
> -mmap=0
> -comm=0
> -task=0
> -enable_on_exec=0
> -disabled=0
> diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group
> deleted file mode 100644
> index e15d6946e9b3..000000000000
> --- a/tools/perf/tests/attr/test-stat-group
> +++ /dev/null
> @@ -1,17 +0,0 @@
> -[config]
> -command = stat
> -args    = --group -e cycles,instructions kill >/dev/null 2>&1
> -ret     = 1
> -
> -[event-1:base-stat]
> -fd=1
> -group_fd=-1
> -read_format=3|15
> -
> -[event-2:base-stat]
> -fd=2
> -group_fd=1
> -config=1
> -disabled=0
> -enable_on_exec=0
> -read_format=3|15
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 5f92319ce258..2e11d82d15e0 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -224,7 +224,7 @@ int __evlist__set_tracepoints_handlers(struct evlist *evlist,
>  	return err;
>  }
>  
> -void evlist__set_leader(struct evlist *evlist)
> +static void evlist__set_leader(struct evlist *evlist)
>  {
>  	perf_evlist__set_leader(&evlist->core);
>  }
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index 27594900a052..ebab48a8120f 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -203,8 +203,6 @@ void evlist__set_selected(struct evlist *evlist, struct evsel *evsel);
>  int evlist__create_maps(struct evlist *evlist, struct target *target);
>  int evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel);
>  
> -void evlist__set_leader(struct evlist *evlist);
> -
>  u64 __evlist__combined_sample_type(struct evlist *evlist);
>  u64 evlist__combined_sample_type(struct evlist *evlist);
>  u64 evlist__combined_branch_type(struct evlist *evlist);
> diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
> index 7f782a31bda3..d063375c346a 100644
> --- a/tools/perf/util/python.c
> +++ b/tools/perf/util/python.c
> @@ -1121,14 +1121,6 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
>  				   PyObject *args, PyObject *kwargs)
>  {
>  	struct evlist *evlist = &pevlist->evlist;
> -	int group = 0;
> -	static char *kwlist[] = { "group", NULL };
> -
> -	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
> -		return NULL;
> -
> -	if (group)
> -		evlist__set_leader(evlist);
>  
>  	if (evlist__open(evlist) < 0) {
>  		PyErr_SetFromErrno(PyExc_OSError);
> diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
> index bff669b615ee..9e694db7c7ee 100644
> --- a/tools/perf/util/record.c
> +++ b/tools/perf/util/record.c
> @@ -99,13 +99,6 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
>  	bool use_comm_exec;
>  	bool sample_id = opts->sample_id;
>  
> -	/*
> -	 * Set the evsel leader links before we configure attributes,
> -	 * since some might depend on this info.
> -	 */
> -	if (opts->group)
> -		evlist__set_leader(evlist);
> -
>  	if (evlist->core.cpus->map[0] < 0)
>  		opts->no_inherit = true;
>  
> diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h
> index ef6c2715fdd9..0a7a8dbbea9c 100644
> --- a/tools/perf/util/record.h
> +++ b/tools/perf/util/record.h
> @@ -13,7 +13,6 @@ struct option;
>  
>  struct record_opts {
>  	struct target target;
> -	bool	      group;
>  	bool	      inherit_stat;
>  	bool	      no_buffering;
>  	bool	      no_inherit;
> -- 
> 2.34.1.307.g9b7440fafd-goog
> 



From jolsa at redhat.com  Tue Jan  4 06:24:19 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Tue, 4 Jan 2022 15:24:19 +0100
Subject: [PATCH v3 00/48] Refactor perf cpumap
In-Reply-To: <20211230072030.302559-1-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
Message-ID: <YdRYk8Ic8qdEAhQz@krava>

On Wed, Dec 29, 2021 at 11:19:41PM -0800, Ian Rogers wrote:
> Perf cpu map has various functions where a cpumap and index are passed
> in order to load the cpu. A problem with this is that the wrong index
> may be passed for the cpumap, causing problems like aggregation on the
> wrong CPU:
> https://lore.kernel.org/lkml/20211204023409.969668-1-irogers at google.com/
> 
> This patch set refactors the cpu map API, reducing it and explicitly
> passing the cpu (rather than the pair) to functions that need
> it. Comments are added at the same time. Changes modify the same
> file/function more than once as refactoring and fixes are broken apart
> for the sake of bisection.
> 
> v2. Incorproates fixes suggested Jiri Olsa, rewrites the evlist CPU
>     iterator in part in a way suggested by Riccardo Mancini. The new
>     fixes start at patch 23. The final change was suggested by John
>     Garry to make the CPUs have their own struct wrapper.
> 
> v3. Incorporates fixes suggested by Namhyung Kim.
> 
> Ian Rogers (48):

you doubled the amount of patches from v1? ;-)

I had small comments for the first 22 patches and would be ok
with them merged.. will try to go through the rest soon

thanks,
jirka

>   libperf: Add comments to perf_cpu_map.
>   perf stat: Add aggr creators that are passed a cpu.
>   perf stat: Correct aggregation CPU map
>   perf stat: Switch aggregation to use for_each loop
>   perf stat: Switch to cpu version of cpu_map__get
>   perf cpumap: Switch cpu_map__build_map to cpu function
>   perf cpumap: Remove map+index get_socket
>   perf cpumap: Remove map+index get_die
>   perf cpumap: Remove map+index get_core
>   perf cpumap: Remove map+index get_node
>   perf cpumap: Add comments to aggr_cpu_id
>   perf cpumap: Remove unused cpu_map__socket
>   perf cpumap: Simplify equal function name.
>   perf cpumap: Rename empty functions.
>   perf cpumap: Document cpu__get_node and remove redundant function
>   perf cpumap: Remove map from function names that don't use a map.
>   perf cpumap: Remove cpu_map__cpu, use libperf function.
>   perf cpumap: Refactor cpu_map__build_map
>   perf cpumap: Rename cpu_map__get_X_aggr_by_cpu functions
>   perf cpumap: Move 'has' function to libperf
>   perf cpumap: Add some comments to cpu_aggr_map
>   perf cpumap: Trim the cpu_aggr_map
>   perf stat: Fix memory leak in check_per_pkg
>   perf cpumap: Add CPU to aggr_cpu_id
>   perf stat-display: Avoid use of core for CPU.
>   perf evsel: Derive CPUs and threads in alloc_counts
>   libperf: Switch cpu to more accurate cpu_map_idx
>   libperf: Use cpu not index for evsel mmap
>   perf counts: Switch name cpu to cpu_map_idx
>   perf stat: Rename aggr_data cpu to imply it's an index
>   perf stat: Use perf_cpu_map__for_each_cpu
>   perf script: Use for each cpu to aid readability
>   libperf: Allow NULL in perf_cpu_map__idx
>   perf evlist: Refactor evlist__for_each_cpu.
>   perf evsel: Pass cpu not cpu map index to synthesize
>   perf stat: Correct variable name for read counter
>   perf evsel: Rename CPU around get_group_fd
>   perf evsel: Reduce scope of evsel__ignore_missing_thread
>   perf evsel: Rename variable cpu to index
>   perf test: Use perf_cpu_map__for_each_cpu
>   perf stat: Correct check_per_pkg cpu
>   perf stat: Swap variable name cpu to index
>   libperf: Sync evsel documentation
>   perf bpf: Rename cpu to cpu_map_idx
>   perf c2c: Use more intention revealing iterator
>   perf script: Fix flipped index and cpu
>   perf stat: Correct first_shadow_cpu to return index
>   perf cpumap: Give CPUs their own type.
> 
>  tools/lib/perf/Documentation/libperf.txt      |  11 +-
>  tools/lib/perf/cpumap.c                       | 131 +++--
>  tools/lib/perf/evlist.c                       |   4 +-
>  tools/lib/perf/evsel.c                        |  92 ++--
>  tools/lib/perf/include/internal/cpumap.h      |  18 +-
>  tools/lib/perf/include/internal/evlist.h      |   3 +-
>  tools/lib/perf/include/internal/evsel.h       |   4 +-
>  tools/lib/perf/include/internal/mmap.h        |   5 +-
>  tools/lib/perf/include/perf/cpumap.h          |   8 +-
>  tools/lib/perf/include/perf/evsel.h           |  10 +-
>  tools/lib/perf/libperf.map                    |   1 +
>  tools/lib/perf/mmap.c                         |   2 +-
>  tools/perf/arch/arm/util/cs-etm.c             |  16 +-
>  tools/perf/bench/epoll-ctl.c                  |   2 +-
>  tools/perf/bench/epoll-wait.c                 |   2 +-
>  tools/perf/bench/futex-hash.c                 |   2 +-
>  tools/perf/bench/futex-lock-pi.c              |   2 +-
>  tools/perf/bench/futex-requeue.c              |   2 +-
>  tools/perf/bench/futex-wake-parallel.c        |   2 +-
>  tools/perf/bench/futex-wake.c                 |   2 +-
>  tools/perf/builtin-c2c.c                      |  15 +-
>  tools/perf/builtin-ftrace.c                   |   2 +-
>  tools/perf/builtin-kmem.c                     |   2 +-
>  tools/perf/builtin-record.c                   |   2 +-
>  tools/perf/builtin-sched.c                    |  71 +--
>  tools/perf/builtin-script.c                   |  10 +-
>  tools/perf/builtin-stat.c                     | 516 +++++++++---------
>  tools/perf/tests/attr.c                       |   6 +-
>  tools/perf/tests/bitmap.c                     |   2 +-
>  tools/perf/tests/cpumap.c                     |   6 +-
>  tools/perf/tests/event_update.c               |   6 +-
>  tools/perf/tests/mem2node.c                   |   2 +-
>  tools/perf/tests/mmap-basic.c                 |   4 +-
>  tools/perf/tests/openat-syscall-all-cpus.c    |  39 +-
>  tools/perf/tests/stat.c                       |   3 +-
>  tools/perf/tests/topology.c                   |  43 +-
>  tools/perf/util/affinity.c                    |   2 +-
>  tools/perf/util/auxtrace.c                    |  12 +-
>  tools/perf/util/auxtrace.h                    |   5 +-
>  tools/perf/util/bpf_counter.c                 |  16 +-
>  tools/perf/util/bpf_counter.h                 |   4 +-
>  tools/perf/util/counts.c                      |   8 +-
>  tools/perf/util/counts.h                      |  14 +-
>  tools/perf/util/cpumap.c                      | 253 ++++-----
>  tools/perf/util/cpumap.h                      | 116 ++--
>  tools/perf/util/cputopo.c                     |   6 +-
>  tools/perf/util/env.c                         |  29 +-
>  tools/perf/util/env.h                         |   3 +-
>  tools/perf/util/evlist.c                      | 148 ++---
>  tools/perf/util/evlist.h                      |  50 +-
>  tools/perf/util/evsel.c                       | 143 ++---
>  tools/perf/util/evsel.h                       |  27 +-
>  tools/perf/util/expr.c                        |   2 +-
>  tools/perf/util/header.c                      |   6 +-
>  tools/perf/util/mmap.c                        |  19 +-
>  tools/perf/util/mmap.h                        |   3 +-
>  tools/perf/util/perf_api_probe.c              |  15 +-
>  tools/perf/util/python.c                      |   4 +-
>  tools/perf/util/record.c                      |  11 +-
>  .../scripting-engines/trace-event-python.c    |   6 +-
>  tools/perf/util/session.c                     |  10 +-
>  tools/perf/util/stat-display.c                | 138 ++---
>  tools/perf/util/stat-shadow.c                 | 308 +++++------
>  tools/perf/util/stat.c                        |  47 +-
>  tools/perf/util/stat.h                        |   9 +-
>  tools/perf/util/svghelper.c                   |   6 +-
>  tools/perf/util/synthetic-events.c            |  12 +-
>  tools/perf/util/synthetic-events.h            |   3 +-
>  tools/perf/util/util.h                        |   5 +-
>  69 files changed, 1333 insertions(+), 1155 deletions(-)
> 
> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 



From linux at armlinux.org.uk  Tue Jan  4 06:27:14 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 14:27:14 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRVovG9mgEWffkn@Red>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
Message-ID: <YdRZQl6U0y19P/0+@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 03:11:46PM +0100, Corentin Labbe wrote:
> Le Tue, Jan 04, 2022 at 12:11:55PM +0000, Russell King (Oracle) a ?crit :
> > On Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) wrote:
> > > On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > > > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > > > Hello
> > > > > > 
> > > > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > > > 
> > > > > How is the PHY connected to the host (which interface mode?) If it's
> > > > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > > > DT.
> > > > > 
> > > > 
> > > > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > > > The only change to the mainline dtb is removing the max-speed.
> > > 
> > > So, it's using "rgmii" with no delay configured at the PHY with the
> > > speed limited to 100Mbps. You then remove the speed limitation and
> > > it doesn't work at 1Gbps.
> > > 
> > > I think I've seen this on other platforms (imx6 + ar8035) when the
> > > RGMII delay is not correctly configured - it will work at slower
> > > speeds but not 1G.
> > > 
> > > The RGMII spec specifies that there will be a delay - and the delay can
> > > be introduced by either the MAC, PHY or by PCB track routing. It sounds
> > > to me like your boot environment configures the PHY to introduce the
> > > necessary delay, but then, because the DT "rgmii" mode means "no delay
> > > at the PHY" when you use the Marvell driver (which respects that), the
> > > Marvell driver configures the PHY for no delay, resulting in a non-
> > > working situation at 1G.
> > > 
> > > I would suggest checking how the boot environment configures the PHY,
> > > and change the "rgmii" mode in DT to match. There is a description of
> > > the four RGMII modes in Documentation/networking/phy.rst that may help
> > > understand what each one means.
> > 
> > Hmm. Sorry, I'm leading you stray. It looks like the 88E1118 code does
> > not program any delays depending on the interface mode, so changing that
> > will have no effect.
> > 
> > I suspect, looking at m88e1118_config_init(), that the write to register
> > 0x15 in the MSCR page could be the problem.
> > 
> > 0x15 is 21, which is MII_88E1121_PHY_MSCR_REG. In other Marvell PHYs,
> > bits 4 and 5 are the tx and rx delays, both of which are set. Looking
> > at m88e1121_config_aneg_rgmii_delays(), this would seem to indicate
> > that the PHY is being placed into rgmii-id mode.
> > 
> > Can you try changing:
> > 
> > 	err = phy_write(phydev, 0x15, 0x1070);
> > 
> > to:
> > 
> > 	err = phy_write(phydev, 0x15, 0x1040);
> > 
> > and see what happens? Maybe trying other combinations of bits 4 and 5
> > to find a working combination.
> > 
> 
> Forget my other message, using 0x1040 lead to success.
> My problem was that I tried rgmii-id which net/ethernet/cortina does not support on some code path. (everything test PHY_INTERFACE_MODE_RGMII only)
> So I retry tests with original phy-mode = "rgmii".
> 
> So with the following changes everything is ok:
> diff --git a/arch/arm/boot/dts/gemini-ssi1328.dts b/arch/arm/boot/dts/gemini-ssi1328.dts
> index 113feb1c4922..7543d117a13a 100644
> --- a/arch/arm/boot/dts/gemini-ssi1328.dts
> +++ b/arch/arm/boot/dts/gemini-ssi1328.dts
> @@ -40,10 +40,6 @@ mdio0: mdio {
>                 phy0: ethernet-phy at 1 {
>                         reg = <1>;
>                         device_type = "ethernet-phy";
> -                       /* We lack the knowledge of necessary GPIO to achieve
> -                        * Gigabit
> -                        */
> -                       max-speed = <100>;
>                 };
>                 /* WAN ICPlus IP101A */
>                 phy1: ethernet-phy at 2 {
> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index 4fcfca4e1702..af7fc9d8eaa7 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -1233,7 +1233,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
>                 return err;
>  
>         /* Enable 1000 Mbit */
> -       err = phy_write(phydev, 0x15, 0x1070);
> +       err = phy_write(phydev, 0x15, 0x1040);
>         if (err < 0)
>                 return err;
>  

Okay, so we have two things that need fixing:

1) We need m88e1118_config_init() to take note of the interface mode
if it's RGMII, and program MSCR appropriately.

2) We need drivers/net/ethernet/cortina/gemini.c to accept any RGMII
interface mode.

Here's an untested patch for both - I've also converted the MSCR write
to be more modern. Please let me know if this resolves your issue.
We then need to consider whether it breaks any existing platform.

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 07add311f65d..c78b99a497df 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4fcfca4e1702..ccf142ce55d8 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1227,16 +1227,18 @@ static int m88e1118_config_init(struct phy_device *phydev)
 {
 	int err;
 
-	/* Change address */
-	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
-	if (err < 0)
-		return err;
-
 	/* Enable 1000 Mbit */
-	err = phy_write(phydev, 0x15, 0x1070);
+	err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
+			      MII_88E1121_PHY_MSCR_REG, 0x1070);
 	if (err < 0)
 		return err;
 
+	if (phy_interface_is_rgmii(phydev)) {
+		err = m88e1121_config_aneg_rgmii_delays(phydev);
+		if (err < 0)
+			return err;
+	}
+
 	/* Change address */
 	err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE);
 	if (err < 0)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From rafael at kernel.org  Tue Jan  4 06:28:57 2022
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Tue, 4 Jan 2022 15:28:57 +0100
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <20211231033725.21109-3-ilkka@os.amperecomputing.com>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
Message-ID: <CAJZ5v0g7OeQ=pa-7j+5NDMjbAsr89FUg09u0i2k98uJWf_GgTg@mail.gmail.com>

On Fri, Dec 31, 2021 at 4:37 AM Ilkka Koskinen
<ilkka at os.amperecomputing.com> wrote:
>
> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
> issue diagnostic dump and reset via an SDEI event or an interrupt.
> This patch implements SDEI path.
>
> [0] https://developer.arm.com/documentation/den0093/latest/
>
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>

This requires an ACK from the arm64 side if you want me to take it.

However, I can apply patch 1 from this series if that helps.

> ---
>  drivers/acpi/arm64/Kconfig  |   8 +++
>  drivers/acpi/arm64/Makefile |   1 +
>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 134 insertions(+)
>  create mode 100644 drivers/acpi/arm64/agdi.c
>
> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
> index 6dba187f4f2e..24869ba5b365 100644
> --- a/drivers/acpi/arm64/Kconfig
> +++ b/drivers/acpi/arm64/Kconfig
> @@ -8,3 +8,11 @@ config ACPI_IORT
>
>  config ACPI_GTDT
>         bool
> +
> +config ACPI_AGDI
> +       bool "Arm Generic Diagnostic Dump and Reset Device Interface"
> +       depends on ARM_SDE_INTERFACE
> +       help
> +         Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
> +         a standard that enables issuing a non-maskable diagnostic dump and
> +         reset command.
> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
> index 66acbe77f46e..7b9e4045659d 100644
> --- a/drivers/acpi/arm64/Makefile
> +++ b/drivers/acpi/arm64/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_ACPI_AGDI)        += agdi.o
>  obj-$(CONFIG_ACPI_IORT)        += iort.o
>  obj-$(CONFIG_ACPI_GTDT)        += gtdt.o
>  obj-y                          += dma.o
> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
> new file mode 100644
> index 000000000000..6525ccbae5c1
> --- /dev/null
> +++ b/drivers/acpi/arm64/agdi.c
> @@ -0,0 +1,125 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * This file implements handling of
> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
> + *
> + * Copyright (c) 2021, Ampere Computing LLC
> + */
> +
> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/acpi.h>
> +#include <linux/arm_sdei.h>
> +#include <linux/io.h>
> +
> +struct agdi_data {
> +       int sdei_event;
> +};
> +
> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
> +{
> +       nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
> +       return 0;
> +}
> +
> +static int agdi_sdei_probe(struct platform_device *pdev,
> +                          struct agdi_data *adata)
> +{
> +       int err;
> +
> +       err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
> +       if (err) {
> +               dev_err(&pdev->dev, "Failed to register for SDEI event %d",
> +                       adata->sdei_event);
> +               return err;
> +       }
> +
> +       err = sdei_event_enable(adata->sdei_event);
> +       if (err)  {
> +               sdei_event_unregister(adata->sdei_event);
> +               dev_err(&pdev->dev, "Failed to enable event %d\n",
> +                       adata->sdei_event);
> +               return err;
> +       }
> +
> +       return 0;
> +}
> +
> +static int agdi_probe(struct platform_device *pdev)
> +{
> +       struct agdi_data *adata;
> +
> +       adata = dev_get_platdata(&pdev->dev);
> +       if (!adata)
> +               return -EINVAL;
> +
> +       return agdi_sdei_probe(pdev, adata);
> +}
> +
> +static int agdi_remove(struct platform_device *pdev)
> +{
> +       struct agdi_data *adata = platform_get_drvdata(pdev);
> +
> +       sdei_event_disable(adata->sdei_event);
> +       sdei_event_unregister(adata->sdei_event);
> +
> +       return 0;
> +}
> +
> +static struct platform_driver agdi_driver = {
> +       .driver = {
> +               .name = "agdi",
> +       },
> +       .probe = agdi_probe,
> +       .remove = agdi_remove,
> +};
> +
> +static int __init agdi_init(void)
> +{
> +       int ret;
> +       acpi_status status;
> +       struct acpi_table_agdi *agdi_table;
> +       struct agdi_data pdata;
> +       struct platform_device *pdev;
> +
> +       if (acpi_disabled)
> +               return 0;
> +
> +       status = acpi_get_table(ACPI_SIG_AGDI, 0,
> +                               (struct acpi_table_header **) &agdi_table);
> +       if (ACPI_FAILURE(status))
> +               return -ENODEV;
> +
> +       if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
> +               pr_warn("Interrupt signaling is not supported");
> +               ret = -ENODEV;
> +               goto err_put_table;
> +       }
> +
> +       pdata.sdei_event = agdi_table->sdei_event;
> +
> +       pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
> +       if (IS_ERR(pdev)) {
> +               ret = PTR_ERR(pdev);
> +               goto err_put_table;
> +       }
> +
> +       ret = platform_driver_register(&agdi_driver);
> +       if (ret)
> +               goto err_device_unregister;
> +
> +       acpi_put_table((struct acpi_table_header *)agdi_table);
> +       return 0;
> +
> +err_device_unregister:
> +       platform_device_unregister(pdev);
> +err_put_table:
> +       acpi_put_table((struct acpi_table_header *)agdi_table);
> +       return ret;
> +}
> +device_initcall(agdi_init);
> --
> 2.17.1
>


From ashimida at linux.alibaba.com  Tue Jan  4 06:32:16 2022
From: ashimida at linux.alibaba.com (Dan Li)
Date: Tue, 4 Jan 2022 06:32:16 -0800
Subject: [PATCH] [RFC] aarch64: scs: reload shadow call stack in user
 exception entry
In-Reply-To: <YdQkM8IlonhEhU/R@FVFF77S0Q05N>
References: <20211228010604.109572-1-ashimida@linux.alibaba.com>
 <YdQkM8IlonhEhU/R@FVFF77S0Q05N>
Message-ID: <4d79d1e0-8320-4d9f-d847-ac83032c71df@linux.alibaba.com>



On 1/4/22 2:40 AM, Mark Rutland wrote:
> Hi,
> 
> On Mon, Dec 27, 2021 at 05:06:04PM -0800, Dan Li wrote:
>> When el0 exception occurs, kernel_entry/exit will load/save tsk->scs_sp
>> to ensure scs working properly. AFAIK, the SCS offset should always be
>> 0 at this time.
>>
>> Is it reasonable to reload x18 to scs_base directly in kernel_entry
>> here, or am I missing something?
>>
>> Signed-off-by: Dan Li <ashimida at linux.alibaba.com>
> 
> AFAICT the saving here is just that we avoid storing the SCS SP upon return to
> EL0, and I suspect that in practice that's not measureable.
> 
> So without numbers to show otherwise, I'd prefer to leave this as-is, though I
> agree that this patch should work.  If we do want to change this, I think we
> need a comment in the `kernel_exit` path to pair with the `scs_load` in
> `kernel_entry`.
> 
> Thanks,
> Mark.
>
Yes, there is only one instruction saved here, which should have a
minimal impact on performance.
The current code is also good for me :)

Thanks,
Dan.

>> ---
>>   arch/arm64/include/asm/scs.h | 7 +++++++
>>   arch/arm64/kernel/entry.S    | 3 +--
>>   2 files changed, 8 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/scs.h b/arch/arm64/include/asm/scs.h
>> index 8297bccf0784..2bc0d0575e75 100644
>> --- a/arch/arm64/include/asm/scs.h
>> +++ b/arch/arm64/include/asm/scs.h
>> @@ -9,6 +9,10 @@
>>   #ifdef CONFIG_SHADOW_CALL_STACK
>>   	scs_sp	.req	x18
>>   
>> +	.macro scs_reload tsk
>> +	ldr	scs_sp, [\tsk, #TSK_TI_SCS_BASE]
>> +	.endm
>> +
>>   	.macro scs_load tsk
>>   	ldr	scs_sp, [\tsk, #TSK_TI_SCS_SP]
>>   	.endm
>> @@ -17,6 +21,9 @@
>>   	str	scs_sp, [\tsk, #TSK_TI_SCS_SP]
>>   	.endm
>>   #else
>> +	.macro scs_reload tsk
>> +	.endm
>> +
>>   	.macro scs_load tsk
>>   	.endm
>>   
>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>> index bc6d5a970a13..57547a3e4f7c 100644
>> --- a/arch/arm64/kernel/entry.S
>> +++ b/arch/arm64/kernel/entry.S
>> @@ -265,7 +265,7 @@ alternative_if ARM64_HAS_ADDRESS_AUTH
>>   alternative_else_nop_endif
>>   1:
>>   
>> -	scs_load tsk
>> +	scs_reload tsk
>>   	.else
>>   	add	x21, sp, #PT_REGS_SIZE
>>   	get_current_task tsk
>> @@ -365,7 +365,6 @@ alternative_if ARM64_WORKAROUND_845719
>>   alternative_else_nop_endif
>>   #endif
>>   3:
>> -	scs_save tsk
>>   
>>   	/* Ignore asynchronous tag check faults in the uaccess routines */
>>   	ldr	x0, [tsk, THREAD_SCTLR_USER]
>> -- 
>> 2.17.1
>>


From yu.tu at amlogic.com  Tue Jan  4 06:35:54 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 4 Jan 2022 22:35:54 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
 <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
Message-ID: <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>

Hi Jerome,
	Thank you very much for your patient reply. I have learned a lot from it.

On 2022/1/4 18:36, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Hi Jerome,
>> 	Thank you very much for your reply.
>>
>> On 2022/1/3 20:40, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>>>
>>>> Using the common Clock code to describe the UART baud rate clock makes
>>>> it easier for the UART driver to be compatible with the baud rate
>>>> requirements of the UART IP on different meson chips
>>>>
>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>> ---
>>>>    drivers/tty/serial/Kconfig      |   1 +
>>>>    drivers/tty/serial/meson_uart.c | 311 ++++++++++++++++++++++++++------
>>>>    2 files changed, 257 insertions(+), 55 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>>> index 780908d43557..32e238173036 100644
>>>> --- a/drivers/tty/serial/Kconfig
>>>> +++ b/drivers/tty/serial/Kconfig
>>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>>    config SERIAL_MESON
>>>>    	tristate "Meson serial port support"
>>>>    	depends on ARCH_MESON
>>>> +	depends on COMMON_CLK
>>>>    	select SERIAL_CORE
>>>>    	help
>>>>    	  This enables the driver for the on-chip UARTs of the Amlogic
>>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>>> index 99efe62a1507..07eb1f40aaaa 100644
>>>> --- a/drivers/tty/serial/meson_uart.c
>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>> @@ -6,6 +6,7 @@
>>>>     */
>>>>      #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/console.h>
>>>>    #include <linux/delay.h>
>>>>    #include <linux/init.h>
>>>> @@ -65,9 +66,7 @@
>>>>    #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>>      /* AML_UART_REG5 bits */
>>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>>    #define AML_UART_BAUD_USE		BIT(23)
>>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>>      #define AML_UART_PORT_NUM		12
>>>>    #define AML_UART_PORT_OFFSET		6
>>>> @@ -76,6 +75,21 @@
>>>>    #define AML_UART_POLL_USEC		5
>>>>    #define AML_UART_TIMEOUT_USEC		10000
>>>>    +struct meson_uart_data {
>>>> +	struct uart_port	port;
>>>> +	struct clk		*pclk;
>>>> +	struct clk		*baud_clk;
>>>> +	struct clk_divider	baud_div;
>>>> +	struct clk_mux		use_xtal_mux;
>>>> +	struct clk_mux		xtal_clk_sel_mux;
>>>> +	struct clk_mux		xtal2_clk_sel_mux;
>>>> +	struct clk_fixed_factor	xtal_div2;
>>>> +	struct clk_fixed_factor	xtal_div3;
>>>> +	struct clk_fixed_factor	clk81_div4;
>>> Keeping all these internal elements around is not useful since they are
>>> registered using devm_
>>>
>> I'm sorry. I don't know what you mean. That's exactly what you said, but
>> what's wrong, I don't understand. Do you have any better suggestions,
>> please specify specific points, preferably give examples.
> 
> I'm saying that you don't need to keep reference to the internal
> elements of the clock tree you have registered since devm_ will take
> care of the removal later on. IOW, Once they are registered, the pointer
> is never used again so you don't need it in the private data.
> 
I understand you now. What you say is right. I will correct it.
> 
>>>> +	bool			no_clk81_input;
>>> What is this ?
>>>
>> To distinguish between clK81 and XTAL.
> 
> ... Yet, it is not used
> 
>>>> +	bool			has_xtal_clk_sel;
>>>> +};
>>>> +
>>>>    static struct uart_driver meson_uart_driver;
>>>>      static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>>    static int meson_uart_startup(struct uart_port *port)
>>>>    {
>>>>    	u32 val;
>>>> -	int ret = 0;
>>>> +	int ret;
>>>>    -	val = readl(port->membase + AML_UART_CONTROL);
>>>> -	val |= AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> -	val &= ~AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> +	meson_uart_reset(port);
>>>>    +	val = readl(port->membase + AML_UART_CONTROL);
>>>>    	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>    	writel(val, port->membase + AML_UART_CONTROL);
>>>>    @@ -295,19 +306,17 @@ static int meson_uart_startup(struct uart_port
>>>> *port)
>>>>      static void meson_uart_change_speed(struct uart_port *port, unsigned
>>>> long baud)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>>    	u32 val;
>>>>      	while (!meson_uart_tx_empty(port))
>>>>    		cpu_relax();
>>>>    -	if (port->uartclk == 24000000) {
>>> This check shows that previous code assumed bit 24 was left untouched
>>> Below you can see that GXBB and newer used the XTAL path while older
>>> used the other
>>> Your change makes this dynamic which is another "unexpected" change.
>>> Please make the bit 24 mux RO to start with so the behavior remains unchanged
>>> for older SoCs.
>> I agree with what you say, and I will correct it.
>>>
>>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>>> -		val |= AML_UART_BAUD_XTAL;
>>>> -	} else {
>>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>> -	}
>>>> +	val = readl(port->membase + AML_UART_REG5);
>>>>    	val |= AML_UART_BAUD_USE;
>>>>    	writel(val, port->membase + AML_UART_REG5);
>>>> +
>>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>>    }
>>>>      static void meson_uart_set_termios(struct uart_port *port,
>>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>>      static void meson_uart_release_port(struct uart_port *port)
>>>>    {
>>>> -	/* nothing to do */
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +
>>>> +	clk_disable_unprepare(private_data->baud_clk);
>>>> +	clk_disable_unprepare(private_data->pclk);
>>>>    }
>>>>      static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	int ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->pclk);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>>> +	if (ret) {
>>>> +		clk_disable_unprepare(private_data->pclk);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>>    	return 0;
>>>>    }
>>>>    @@ -629,56 +654,175 @@ static struct uart_driver meson_uart_driver = {
>>>>    	.cons		= MESON_SERIAL_CONSOLE,
>>>>    };
>>>>    -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>>> -						 const char *id)
>>>> +static int meson_uart_register_clk(struct uart_port *port,
>>>> +				   const char *name_suffix,
>>>> +				   const struct clk_parent_data *parent_data,
>>>> +				   unsigned int num_parents,
>>>> +				   const struct clk_ops *ops,
>>>> +				   struct clk_hw *hw)
>>>>    {
>>>> -	struct clk *clk = NULL;
>>>> +	struct clk_init_data init = { };
>>>> +	char clk_name[32];
>>>>    	int ret;
>>>>    -	clk = devm_clk_get(dev, id);
>>>> -	if (IS_ERR(clk))
>>>> -		return clk;
>>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>>>> +		 name_suffix);
>>>>    -	ret = clk_prepare_enable(clk);
>>>> -	if (ret) {
>>>> -		dev_err(dev, "couldn't enable clk\n");
>>>> -		return ERR_PTR(ret);
>>>> -	}
>>>> +	init.name = clk_name;
>>>> +	init.ops = ops;
>>>> +	init.flags = CLK_SET_RATE_PARENT;
>>>> +	init.parent_data = parent_data;
>>>> +	init.num_parents = num_parents;
>>>> +
>>>> +	hw->init = &init;
>>>>    -	devm_add_action_or_reset(dev,
>>>> -			(void(*)(void *))clk_disable_unprepare,
>>>> -			clk);
>>>> +	ret = devm_clk_hw_register(port->dev, hw);
>>>> +	if (ret)
>>>> +		return dev_err_probe(port->dev, ret,
>>>> +				     "Failed to register the '%s' clock\n",
>>>> +				     clk_name);
>>>>    -	return clk;
>>>> +	return ret;
>>>>    }
>>>>    -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>> -				   struct uart_port *port)
>>>> -{
>>>> -	struct clk *clk_xtal = NULL;
>>>> -	struct clk *clk_pclk = NULL;
>>>> -	struct clk *clk_baud = NULL;
>>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>>> +				   bool register_clk81_div4)
>>>> +{
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>>> +		{ .index = -1, },
>>>> +		{ .index = -1, },
>>>> +	};
>>>> +	struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>>> +	struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>>> +	struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>>> +	struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>>> +	struct clk_parent_data baud_div_parent = { };
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	int ret;
>>>>    -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>> -	if (IS_ERR(clk_pclk))
>>>> -		return PTR_ERR(clk_pclk);
>>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>> +
>>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>>> +	if (IS_ERR(clk_baud))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>>> +				     "Failed to get the 'baud' clock\n");
>>>>    -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>    	if (IS_ERR(clk_xtal))
>>>> -		return PTR_ERR(clk_xtal);
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>>> +	private_data->xtal_div3.mult = 1;
>>>> +	private_data->xtal_div3.div = 3;
>>>> +	ret = meson_uart_register_clk(port, "xtal_div3", &xtal_div_parent,
>>>> +				      1, &clk_fixed_factor_ops,
>>>> +				      &private_data->xtal_div3.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>>    -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>> -	if (IS_ERR(clk_baud))
>>>> -		return PTR_ERR(clk_baud);
>>>> +	if (register_clk81_div4) {
>>> Clock dividers represent HW elements. The presence of an HW element
>>> cannot
>>> dependent on the current of the input clocks. There is no way this is right
>>>
>>>> +		private_data->clk81_div4.mult = 1;
>>>> +		private_data->clk81_div4.div = 4;
>>>> +		ret = meson_uart_register_clk(port, "clk81_div4",
>>>> +					      &clk81_div_parent, 1,
>>>> +					      &clk_fixed_factor_ops,
>>>> +					      &private_data->clk81_div4.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>>> This is only going to be used on meson8 and older. Worst case it should
>>> depend
>>> on this compatible but I don't think this would be right here.
>>> IMO, this shows that the UART "baud" input was actually fed by a
>>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>>> So instead of registering what I suspect to be a fake element, the
>>> meson8 clock controller driver and DT should be fixed a this should go away.
>>>
>> Virtually all UART controllers are supported, but they are not used after
>> Meson8. So the description is more reasonable in UART driver.
> 
> No it is not. It's not virtual, the support for meson8 is there in
> mainline.
> 
> Unless you tell me there is an actual /4 divider in the UART block of
> the meson8 and older and that is was removed from the newer SoC,
> the bit above should be removed and the meson8 clock tree fixed.
> 
> I think it is more probable that the /4 was never there to begin with,
> and that clk81/4 aka "fclk_div4", which is already available from the
> clock controller, was actually routed on these older SoCs.
I will check with the chip design department if it is divided by 4. I'll 
get back to you.
> 
>>>> +	}
>>>>    -	port->uartclk = clk_get_rate(clk_baud);
>>>> +	if (private_data->has_xtal_clk_sel) {
>>>> +		private_data->xtal_div2.mult = 1;
>>>> +		private_data->xtal_div2.div = 2;
>>>> +		ret = meson_uart_register_clk(port, "xtal_div2",
>>>> +					      &xtal_div_parent, 1,
>>>> +					      &clk_fixed_factor_ops,
>>>> +					      &private_data->xtal_div2.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>>> +		xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>>> +
>>>> +		private_data->xtal_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>>> +		private_data->xtal_clk_sel_mux.mask = 0x1;
>>>> +		private_data->xtal_clk_sel_mux.shift = 26;
>>>> +		private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +		ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>>> +					      xtal_clk_sel_mux_parents,
>>>> +					      ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>>> +					      &clk_mux_ops,
>>>> +					      &private_data->xtal_clk_sel_mux.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		xtal2_clk_sel_mux_parents[0].hw = &private_data->xtal_clk_sel_mux.hw;
>>>> +		xtal2_clk_sel_mux_parents[1].hw = &private_data->xtal_div2.hw;
>>>> +
>>>> +		private_data->xtal2_clk_sel_mux.reg = port->membase + AML_UART_REG5;
>>>> +		private_data->xtal2_clk_sel_mux.mask = 0x1;
>>>> +		private_data->xtal2_clk_sel_mux.shift = 27;
>>>> +		private_data->xtal2_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +		ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>>> +					      xtal2_clk_sel_mux_parents,
>>>> +					      ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>>> +					      &clk_mux_ops,
>>>> +					      &private_data->xtal2_clk_sel_mux.hw);
>>>> +		if (ret)
>>>> +			return ret;
>>>> +
>>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal2_clk_sel_mux.hw;
>>>> +	} else {
>>>> +		use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>>> Well the above is a bit over-complicated. If I summarize:
>>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>>> 0 according to the documentation.
>>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>>> selects which of these dividers is used.
>>> So the above could be replaced with a single divider covering bits 26 and
>>> 27
>>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>>> variant like this, including the older ones.
>>>
>> As you say, the way you say it is complicated. I think you're complicating
>> things.I don't understand what you're trying to achieve.
>> Can you be more specific?
> 
> I'm proposing to replace the 4 elements above, paths, parent_table and
> all with a single divider with a specific table. It accomplishes the same thing.
> 
> |--------+--------+-----------|
> | Bit 27 | Bit 26 | Div Value |
> |--------+--------+-----------|
> |      0 |      0 |         3 |
> |--------+--------+-----------|
> |      0 |      1 |         1 |
> |--------+--------+-----------|
> |      1 |      0 |         2 |
> |--------+--------+-----------|
> |      1 |      1 |         2 |
> |--------+--------+-----------|
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602
> 
> something like:
> 
> static struct clk_div_table reg5_table[] = {
> 	{ 0, 3 },
>          { 1, 1 },
>          { 2, 2 },
>          { 3, 2 },
> };
> 
> I'm also pointing out that, since bit 26 and 27 reads 0 on the older
> SoCs, the divider would work for these too, as long as the Ops is
> read-only. So you don't even need to register different element
> depending on the SoC which simplify things a bit more.
> 
> If you prefer to keep a fixed divider for the older ones, It's fine by
> me. It gives a bit more work but it is closer to reality. The newer SoC
> could still use the custom divider regardless.
> 
> Last, and as explained on other bits, that part of the clock path should
> remain RO at first, to keep behavior stable with this change. You may
> change that later on, in a dedicated patch describing the change.
> 
I understand what you mean, and i will try to realize it. I hope you can 
help review and give me your suggestions.
>>
>>> The only information you need to carry if whether or not you want to
>>> make this divider modifiable. This means using the dt data to store
>>> clk_div_ops or clk_div_ro_ops pointer.
>>> To avoid changing the behavior of the older platforms in this patch, I
>>> would
>>> suggest to make everything use clk_div_ro_ops first, and make another
>>> patch to use clk_div_ops if necessary.
>>>
>>>> +	}
>>>> +
>>>> +	private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>>> +	private_data->use_xtal_mux.mask = 0x1;
>>>> +	private_data->use_xtal_mux.shift = 24;
>>>> +	private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>> +	ret = meson_uart_register_clk(port, "use_xtal", use_xtal_mux_parents,
>>>> +				      ARRAY_SIZE(use_xtal_mux_parents),
>>>> +				      &clk_mux_ops,
>>> Use RO ops here to start with.
>>> You can make this writable with another patch explicitly describing the change.
>> I agree with what you say, and I will correct it.
>>>
>>>> +				      &private_data->use_xtal_mux.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>>> +
>>>> +	private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>>> +	private_data->baud_div.shift = 0;
>>>> +	private_data->baud_div.width = 23;
>>>> +	private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>>> +	ret = meson_uart_register_clk(port, "baud_div",
>>>> +				      &baud_div_parent, 1,
>>>> +				      &clk_divider_ops,
>>>> +				      &private_data->baud_div.hw);
>>>> +	if (ret)
>>>> +		return ret;
>>>> +
>>>> +	private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>>> +						     &private_data->baud_div.hw,
>>>> +						     "baud_rate");
>>> There is a problem with this function in CCF. It will pin the driver to
>>> itself, making it unremovable. It is an ongoing topic. For now, just use
>>> "hw->clk" to get the struct *clk.
>>>
>>>> +	if (IS_ERR(private_data->baud_clk))
>>>> +		return dev_err_probe(port->dev,
>>> I don't think anything can defer here, so dev_err_probe() is not
>>> necessary I think
>>>
>> I agree with what you say, and I will correct it.
>>>> +				     PTR_ERR(private_data->baud_clk),
>>>> +				     "Failed to request the 'baud_rate' clock\n");
>>>>      	return 0;
>>>>    }
>>>>      static int meson_uart_probe(struct platform_device *pdev)
>>>>    {
>>>> +	struct meson_uart_data *private_data;
>>>>    	struct resource *res_mem, *res_irq;
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	bool register_clk81_div4;
>>>>    	struct uart_port *port;
>>>>    	int ret = 0;
>>>>    	int id = -1;
>>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    		return -EBUSY;
>>>>    	}
>>>>    -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>> GFP_KERNEL);
>>>> -	if (!port)
>>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>> +				    GFP_KERNEL);
>>>> +	if (!private_data)
>>>>    		return -ENOMEM;
>>>>    +	if (device_get_match_data(&pdev->dev))
>>>> +		private_data->has_xtal_clk_sel = true;
>>>> +
>>>> +	private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>> +
>>>> +	clk_baud = devm_clk_get(&pdev->dev, "baud");
>>>> +	if (IS_ERR(clk_baud))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>>> +				     "Failed to get the 'baud' clock\n");
>>>> +
>>>> +	clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>>> +	if (IS_ERR(clk_xtal))
>>>> +		return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>> This is second time you call devm_clk_get() on these clocks. One
>>> instance has to go away
>>>
>> I agree with what you say, and I will correct it.
>>>> +	register_clk81_div4 = clk_get_rate(clk_xtal) != clk_get_rate(clk_baud);
>>>> +
>>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>>> from the rest. This definitely not the way to achieve it.
>>> The right is the compatible data but here I think it is not
>>> necessary. The clock input should be fixed.
>>>
>>>> +	port = &private_data->port;
>>>> +
>>>>    	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>    	if (IS_ERR(port->membase))
>>>>    		return PTR_ERR(port->membase);
>>>>    -	ret = meson_uart_probe_clocks(pdev, port);
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>    	port->iotype = UPIO_MEM;
>>>>    	port->mapbase = res_mem->start;
>>>>    	port->mapsize = resource_size(res_mem);
>>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    	port->x_char = 0;
>>>>    	port->ops = &meson_uart_ops;
>>>>    	port->fifosize = 64;
>>>> +	port->uartclk = clk_get_rate(clk_baud);
>>>> +	port->private_data = private_data;
>>>> +
>>>> +	ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>>> +	if (ret)
>>>> +		return ret;
>>>>      	meson_ports[pdev->id] = port;
>>>>    	platform_set_drvdata(pdev, port);
>>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct platform_device *pdev)
>>>>    }
>>>>      static const struct of_device_id meson_uart_dt_match[] = {
>>>> -	{ .compatible = "amlogic,meson6-uart" },
>>>> -	{ .compatible = "amlogic,meson8-uart" },
>>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>>> +	{
>>>> +		.compatible = "amlogic,meson6-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8b-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxl-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-g12a-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-s4-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	/*
>>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>>> +	 * between GXBB and GXL which have different revisions of the UART IP.
>>>> +	 */
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gx-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>>    	{ /* sentinel */ },
>>>>    };
>>>>    MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>
> 


From andrew at lunn.ch  Tue Jan  4 06:36:37 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 4 Jan 2022 15:36:37 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRVovG9mgEWffkn@Red>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
Message-ID: <YdRbdaxdWSFyVjFp@lunn.ch>

> Forget my other message, using 0x1040 lead to success.

O.K. this is going to be messy :-(

diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 4fcfca4e1702..4bc7a44f613a 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1227,15 +1227,11 @@ static int m88e1118_config_init(struct phy_device *phydev)
 {
        int err;
 
-       /* Change address */
-       err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
-       if (err < 0)
-               return err;
-
-       /* Enable 1000 Mbit */
-       err = phy_write(phydev, 0x15, 0x1070);
-       if (err < 0)
-               return err;
+       if (phy_interface_is_rgmii(phydev)) {
+               err = m88e1121_config_aneg_rgmii_delays(phydev);
+               if (err < 0)
+                       return err;
+       }
 
        /* Change address */
        err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE);


will make the PHY driver respect the delays passed to it. But as
Russell already said, it is likely to break with boards which have
"rgmii" in their DT, which is currently being ignored and rgmii-id
programmed into hardware.

We have been here before, with another PHY driver. We decided to make
the change anyway, and fix broken DT when they were reported. It
caused some pain, but in the end, we avoided having odd DT properties
like:

       phy-mode = 'we-really-do-want-rgmii'

There is one more instance of phy_write(phydev, 0x15, 0x1070) for the
m88e1149. I suggest we leave that one alone, until we have a board
which actually requires it.

One thing i would like to understand is where is the delay actually
getting added? If you need the PHY to not add the delay, it is either
the MAC or the PCB. Can you look at the MAC driver and see if it has
any such configuration registers.

       Andrew


From maz at kernel.org  Tue Jan  4 06:39:59 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 04 Jan 2022 14:39:59 +0000
Subject: [PATCH kvmtool 9/9] arm64: Add support for
 KVM_ARM_VCPU_PMU_V3_SET_PMU
In-Reply-To: <20211115165705.195736-10-alexandru.elisei@arm.com>
References: <20211115165705.195736-1-alexandru.elisei@arm.com>
 <20211115165705.195736-10-alexandru.elisei@arm.com>
Message-ID: <87h7ajva2o.wl-maz@kernel.org>

On Mon, 15 Nov 2021 16:57:05 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is
> used to assign a physical PMU to the events that KVM creates when emulating
> the PMU for that VCPU. This is useful on heterogeneous systems, when there
> is more than one hardware PMU present.
> 
> The assumption that is made in the implementation is that the user will
> pin the kvmtool process on a set of CPUs that share the same PMU. This
> allows kvmtool to set the same PMU for all VCPUs from the main thread,
> instead of in the individual VCPU threads.

May I suggest a slightly different use model? Ideally, you'd be able
to run the vcpu threads on the CPUs matching the PMU affinity, and
leave all the other threads to roam on other CPUs.

With your implementation, the whole of kvmtool gets stuck to a given
CPU type, which can be problematic.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From andrew at lunn.ch  Tue Jan  4 06:46:19 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 4 Jan 2022 15:46:19 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRZQl6U0y19P/0+@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
 <YdRZQl6U0y19P/0+@shell.armlinux.org.uk>
Message-ID: <YdRdu3jFPnGd1DsH@lunn.ch>

> @@ -1227,16 +1227,18 @@ static int m88e1118_config_init(struct phy_device *phydev)
>  {
>  	int err;
>  
> -	/* Change address */
> -	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
> -	if (err < 0)
> -		return err;
> -
>  	/* Enable 1000 Mbit */
> -	err = phy_write(phydev, 0x15, 0x1070);
> +	err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
> +			      MII_88E1121_PHY_MSCR_REG, 0x1070);

Ah, yes, keeping this makes it more backwards compatible.

It would be nice to replace the 0x1070 with #defines.

We already have:

#define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
#define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
#define MII_88E1121_PHY_MSCR_DELAY_MASK	(BIT(5) | BIT(4))

Bits 6 is the MSB of the default MAC speed.
Bit 13 is the LSB of the default MAC speed. These two should default to 10b = 1000Mbps
Bit 12 is reserved, and should be written 1.

    Andrew


From andy.shevchenko at gmail.com  Tue Jan  4 06:48:35 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 4 Jan 2022 16:48:35 +0200
Subject: [PATCH v4] soc: ti: smartreflex: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <20220104134512.18498-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104134512.18498-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAHp75Vcx1Ey-SHBCgBh1RM=PTBRcncGOwAx9_6PL+sDJtzezvw@mail.gmail.com>

On Tue, Jan 4, 2022 at 3:45 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
>
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq_optional().
>
> While at it return 0 instead of returning ret in the probe success path.

...

> +       ret = platform_get_irq_optional(pdev, 0);
> +       if (ret < 0 && ret != -ENXIO) {

> +               dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);
> +               return ret;

return dev_err_probe(...); ?

> +       }

-- 
With Best Regards,
Andy Shevchenko


From narmstrong at baylibre.com  Tue Jan  4 06:52:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:52:02 +0100
Subject: [PATCH 0/4] dmaengine: Add support Oxford Semiconductor OXNAS DMA
 Engine
Message-ID: <20220104145206.135524-1-narmstrong@baylibre.com>

This serie adds support for the DMA engine found in Oxford Semiconductor SoCs,
notably in the OX810SE where it's heavily used for SATA transfers.

The driver was on my pipe since 2016 and a courageous person managed to get
the SATA driver work up mainline kernel with this driver, so I cleaned it up
in order to be upstreamed.

I plan to push the last patch through arm-soc when bindings is applied.

Neil Armstrong (4):
  dt-bindings: dma: Add bindings for ox810se dma engine
  dmaengine: Add Oxford Semiconductor OXNAS DMA Controller
  MAINTAINERS: add OX810SE DMA driver files under Oxnas entry
  ARM: dts: ox810se: Add DMA Support

 .../bindings/dma/oxsemi,ox810se-dma.yaml      |   97 ++
 MAINTAINERS                                   |    2 +
 arch/arm/boot/dts/ox810se-wd-mbwe.dts         |    4 +
 arch/arm/boot/dts/ox810se.dtsi                |   21 +
 drivers/dma/Kconfig                           |    8 +
 drivers/dma/Makefile                          |    1 +
 drivers/dma/oxnas_adma.c                      | 1045 +++++++++++++++++
 7 files changed, 1178 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
 create mode 100644 drivers/dma/oxnas_adma.c


base-commit: fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:52:03 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:52:03 +0100
Subject: [PATCH 1/4] dt-bindings: dma: Add bindings for ox810se dma engine
In-Reply-To: <20220104145206.135524-1-narmstrong@baylibre.com>
References: <20220104145206.135524-1-narmstrong@baylibre.com>
Message-ID: <20220104145206.135524-2-narmstrong@baylibre.com>

This adds the YAML dt-bindings for the DMA engine found in the
Oxford Semiconductor OX810SE SoC.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../bindings/dma/oxsemi,ox810se-dma.yaml      | 97 +++++++++++++++++++
 1 file changed, 97 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml

diff --git a/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml b/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
new file mode 100644
index 000000000000..6efa28e8b124
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/oxsemi,ox810se-dma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Oxford Semiconductor DMA Controller Device Tree Bindings
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+allOf:
+  - $ref: "dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+    const: 1
+
+  compatible:
+    const: oxsemi,ox810se-dma
+
+  reg:
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: dma
+      - const: sgdma
+
+  interrupts:
+    maxItems: 5
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: dma
+      - const: sgdma
+
+  dma-channels: true
+
+  oxsemi,targets-types:
+    description:
+      Table with allowed memory ranges and memory type associated.
+    $ref: "/schemas/types.yaml#/definitions/uint32-matrix"
+    minItems: 4
+    items:
+      items:
+        - description:
+            The first cell defines the memory range start address
+        - description:
+            The first cell defines the memory range end address
+        - description:
+            The third cell represents memory type, 0 for SATA,
+            1 for DPE RX, 2 for DPE TX, 5 for AUDIO TX, 6 for AUDIO RX,
+            15 for DRAM MEMORY.
+          enum: [ 0, 1, 2, 5, 6, 15 ]
+
+required:
+  - "#dma-cells"
+  - dma-channels
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+  - reset-names
+  - oxsemi,targets-types
+
+additionalProperties: false
+
+examples:
+  - |
+    dma: dma-controller at 600000 {
+        compatible = "oxsemi,ox810se-dma";
+        reg = <0x600000 0x100000>, <0xc00000 0x100000>;
+        reg-names = "dma", "sgdma";
+        interrupts = <13>, <14>, <15>, <16>, <20>;
+        clocks = <&stdclk 1>;
+        resets = <&reset 8>, <&reset 24>;
+        reset-names = "dma", "sgdma";
+
+        /* Encodes the authorized memory types */
+        oxsemi,targets-types =
+            <0x45900000 0x45a00000 0>,  /* SATA */
+            <0x42000000 0x43000000 0>,  /* SATA DATA */
+            <0x48000000 0x58000000 15>, /* DDR */
+            <0x58000000 0x58020000 15>; /* SRAM */
+
+        #dma-cells = <1>;
+        dma-channels = <5>;
+    };
+...
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:52:05 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:52:05 +0100
Subject: [PATCH 3/4] MAINTAINERS: add OX810SE DMA driver files under Oxnas
 entry
In-Reply-To: <20220104145206.135524-1-narmstrong@baylibre.com>
References: <20220104145206.135524-1-narmstrong@baylibre.com>
Message-ID: <20220104145206.135524-4-narmstrong@baylibre.com>

Add the DMA driver file and bindings in the Oxnas maintainers entry.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2345ce8521..782332ab0d9b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2371,8 +2371,10 @@ M:	Neil Armstrong <narmstrong at baylibre.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 L:	linux-oxnas at groups.io (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
 F:	arch/arm/boot/dts/ox8*.dts*
 F:	arch/arm/mach-oxnas/
+F:	drivers/dma/oxnas_adma.c
 F:	drivers/power/reset/oxnas-restart.c
 N:	oxnas
 
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:52:06 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:52:06 +0100
Subject: [PATCH 4/4] ARM: dts: ox810se: Add DMA Support
In-Reply-To: <20220104145206.135524-1-narmstrong@baylibre.com>
References: <20220104145206.135524-1-narmstrong@baylibre.com>
Message-ID: <20220104145206.135524-5-narmstrong@baylibre.com>

This adds the DMA engine node.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 arch/arm/boot/dts/ox810se-wd-mbwe.dts |  4 ++++
 arch/arm/boot/dts/ox810se.dtsi        | 21 +++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/ox810se-wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
index 7e2fcb220aea..19e5d510e425 100644
--- a/arch/arm/boot/dts/ox810se-wd-mbwe.dts
+++ b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
@@ -103,6 +103,10 @@ rtc0: rtc at 48 {
 	};
 };
 
+&dma {
+	status = "okay";
+};
+
 &uart1 {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/ox810se.dtsi b/arch/arm/boot/dts/ox810se.dtsi
index 0755e5864c4a..79b2b49dcfbb 100644
--- a/arch/arm/boot/dts/ox810se.dtsi
+++ b/arch/arm/boot/dts/ox810se.dtsi
@@ -334,6 +334,27 @@ timer0: timer at 200 {
 					interrupts = <4 5>;
 				};
 			};
+
+			dma: dma-controller at 600000 {
+				compatible = "oxsemi,ox810se-dma";
+				reg = <0x600000 0x100000>,
+				      <0xc00000 0x100000>;
+				reg-names = "dma", "sgdma";
+				interrupts = <13>, <14>, <15>, <16>, <20>;
+				clocks = <&stdclk 1>;
+				resets = <&reset 8>, <&reset 24>;
+				reset-names = "dma", "sgdma";
+
+				/* Encodes the authorized memory types */
+				oxsemi,targets-types =
+					<0x45900000 0x45a00000 0>,  /* SATA */
+					<0x42000000 0x43000000 0>,  /* SATA DATA */
+					<0x48000000 0x58000000 15>, /* DDR */
+					<0x58000000 0x58020000 15>; /* SRAM */
+
+				#dma-cells = <1>;
+				dma-channels = <5>;
+			};
 		};
 	};
 };
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:52:04 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:52:04 +0100
Subject: [PATCH 2/4] dmaengine: Add Oxford Semiconductor OXNAS DMA Controller
In-Reply-To: <20220104145206.135524-1-narmstrong@baylibre.com>
References: <20220104145206.135524-1-narmstrong@baylibre.com>
Message-ID: <20220104145206.135524-3-narmstrong@baylibre.com>

The Oxford Semiconductor OX810SE contains a DMA engine mainly used
for the SATA controller which doesn't have an embedded DMA engine.

This DMA engine support single and scatter-gather memory-to-memory
transfers and device-to-memory/memory-to-device transfers.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/dma/Kconfig      |    8 +
 drivers/dma/Makefile     |    1 +
 drivers/dma/oxnas_adma.c | 1045 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 1054 insertions(+)
 create mode 100644 drivers/dma/oxnas_adma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6bcdb4e6a0d1..8925ffd85ac2 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -505,6 +505,14 @@ config OWL_DMA
 	help
 	  Enable support for the Actions Semi Owl SoCs DMA controller.
 
+config OXNAS_DMA
+	bool "Oxford Semiconductor OXNAS SoC Family DMA support"
+	select DMA_ENGINE
+	select DMA_VIRTUAL_CHANNELS
+	depends on ARCH_OXNAS || COMPILE_TEST
+	help
+	  Support for Oxford Semiconductor OXNAS SoC Family DMA engine
+
 config PCH_DMA
 	tristate "Intel EG20T PCH / LAPIS Semicon IOH(ML7213/ML7223/ML7831) DMA"
 	depends on PCI && (X86_32 || COMPILE_TEST)
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index 616d926cf2a5..ba1111785bb8 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_MXS_DMA) += mxs-dma.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o
 obj-$(CONFIG_OWL_DMA) += owl-dma.o
+obj-$(CONFIG_OXNAS_DMA) += oxnas_adma.o
 obj-$(CONFIG_PCH_DMA) += pch_dma.o
 obj-$(CONFIG_PL330_DMA) += pl330.o
 obj-$(CONFIG_PLX_DMA) += plx_dma.o
diff --git a/drivers/dma/oxnas_adma.c b/drivers/dma/oxnas_adma.c
new file mode 100644
index 000000000000..586c23187de1
--- /dev/null
+++ b/drivers/dma/oxnas_adma.c
@@ -0,0 +1,1045 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2008 Oxford Semiconductor Ltd
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_dma.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/bitfield.h>
+#include <linux/dma-mapping.h>
+
+#include "dmaengine.h"
+#include "virt-dma.h"
+
+/* Normal (non-SG) registers */
+#define DMA_REGS_PER_CHANNEL 8
+
+#define DMA_CTRL_STATUS      0x00
+#define DMA_BASE_SRC_ADR     0x04
+#define DMA_BASE_DST_ADR     0x08
+#define DMA_BYTE_CNT         0x0c
+#define DMA_CURRENT_SRC_ADR  0x10
+#define DMA_CURRENT_DST_ADR  0x14
+#define DMA_CURRENT_BYTE_CNT 0x18
+#define DMA_INTR_ID          0x1c
+#define DMA_INTR_CLEAR_REG   (DMA_CURRENT_SRC_ADR)
+
+/* 8 quad-sized registers per channel arranged contiguously */
+#define DMA_CALC_REG_ADR(channel, register) (((channel) << 5) + (register))
+
+#define DMA_CTRL_STATUS_FAIR_SHARE_ARB            BIT(0)
+#define DMA_CTRL_STATUS_IN_PROGRESS               BIT(1)
+#define DMA_CTRL_STATUS_SRC_DREQ                  GENMASK(5, 2)
+#define DMA_CTRL_STATUS_DEST_DREQ                 GENMASK(10, 7)
+#define DMA_CTRL_STATUS_INTR                      BIT(10)
+#define DMA_CTRL_STATUS_NXT_FREE                  BIT(11)
+#define DMA_CTRL_STATUS_RESET                     BIT(12)
+#define DMA_CTRL_STATUS_DIR                       GENMASK(14, 13)
+#define DMA_CTRL_STATUS_SRC_ADR_MODE              BIT(15)
+#define DMA_CTRL_STATUS_DEST_ADR_MODE             BIT(16)
+#define DMA_CTRL_STATUS_TRANSFER_MODE_A           BIT(17)
+#define DMA_CTRL_STATUS_TRANSFER_MODE_B           BIT(18)
+#define DMA_CTRL_STATUS_SRC_WIDTH                 GENMASK(21, 19)
+#define DMA_CTRL_STATUS_DEST_WIDTH                GENMASK(24, 22)
+#define DMA_CTRL_STATUS_PAUSE                     BIT(25)
+#define DMA_CTRL_STATUS_INTERRUPT_ENABLE          BIT(26)
+#define DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED      BIT(27)
+#define DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED BIT(28)
+#define DMA_CTRL_STATUS_STARVE_LOW_PRIORITY       BIT(29)
+#define DMA_CTRL_STATUS_INTR_CLEAR_ENABLE         BIT(30)
+
+#define DMA_BYTE_CNT_MASK                         GENMASK(20, 0)
+#define DMA_BYTE_CNT_INC4_SET_MASK                BIT(28)
+#define DMA_BYTE_CNT_HPROT_MASK                   BIT(29)
+#define DMA_BYTE_CNT_WR_EOT_MASK                  BIT(30)
+#define DMA_BYTE_CNT_RD_EOT_MASK                  BIT(31)
+
+#define DMA_INTR_ID_GET_NUM_CHANNELS(reg_contents) (((reg_contents) >> 16) & 0xFF)
+#define DMA_INTR_ID_GET_VERSION(reg_contents)      (((reg_contents) >> 24) & 0xFF)
+#define DMA_INTR_ID_INT_MASK        GENMASK(MAX_OXNAS_DMA_CHANNELS, 0)
+
+#define DMA_HAS_V4_INTR_CLEAR(version) ((version) > 3)
+
+/* H/W scatter gather controller registers */
+#define OXNAS_DMA_NUM_SG_REGS 4
+
+#define DMA_SG_CONTROL  0x00
+#define DMA_SG_STATUS   0x04
+#define DMA_SG_REQ_PTR  0x08
+#define DMA_SG_RESETS   0x0c
+
+#define DMA_SG_CALC_REG_ADR(channel, register) (((channel) << 4) + (register))
+
+/* SG DMA controller control register field definitions */
+#define DMA_SG_CONTROL_START		BIT(0)
+#define DMA_SG_CONTROL_QUEUING_ENABLE	BIT(1)
+#define DMA_SG_CONTROL_HBURST_ENABLE	BIT(2)
+
+/* SG DMA controller status register field definitions */
+#define DMA_SG_STATUS_ERROR_CODE	GENMASK(5, 0)
+#define DMA_SG_STATUS_BUSY		BIT(7)
+
+/* SG DMA controller sub-block resets register field definitions */
+#define DMA_SG_RESETS_CONTROL		BIT(0)
+#define DMA_SG_RESETS_ARBITER		BIT(1)
+#define DMA_SG_RESETS_AHB		BIT(2)
+
+/* SG DMA controller qualifier field definitions */
+#define OXNAS_DMA_SG_QUALIFIER		GENMASK(15, 0)
+#define OXNAS_DMA_SG_DST_EOT		GENMASK(17, 16)
+#define OXNAS_DMA_SG_SRC_EOT		GENMASK(22, 20)
+#define OXNAS_DMA_SG_CHANNEL		GENMASK(31, 24)
+
+#define OXNAS_DMA_ADR_MASK		GENMASK(29, 0)
+#define OXNAS_DMA_MAX_TRANSFER_LENGTH	DMA_BYTE_CNT_MASK
+
+/* The available buses to which the DMA controller is attached */
+enum {
+	OXNAS_DMA_SIDE_A = 0,
+	OXNAS_DMA_SIDE_B
+};
+
+/* Direction of data flow between the DMA controller's pair of interfaces */
+enum {
+	OXNAS_DMA_A_TO_A = 0,
+	OXNAS_DMA_B_TO_A,
+	OXNAS_DMA_A_TO_B,
+	OXNAS_DMA_B_TO_B
+};
+
+/* The available data widths */
+enum {
+	OXNAS_DMA_TRANSFER_WIDTH_8BITS = 0,
+	OXNAS_DMA_TRANSFER_WIDTH_16BITS,
+	OXNAS_DMA_TRANSFER_WIDTH_32BITS
+};
+
+/* The mode of the DMA transfer */
+enum {
+	OXNAS_DMA_TRANSFER_MODE_SINGLE = 0,
+	OXNAS_DMA_TRANSFER_MODE_BURST
+};
+
+/* The available transfer targets */
+enum {
+	OXNAS_DMA_DREQ_PATA     = 0,
+	OXNAS_DMA_DREQ_SATA     = 0,
+	OXNAS_DMA_DREQ_DPE_RX   = 1,
+	OXNAS_DMA_DREQ_DPE_TX   = 2,
+	OXNAS_DMA_DREQ_AUDIO_TX = 5,
+	OXNAS_DMA_DREQ_AUDIO_RX = 6,
+	OXNAS_DMA_DREQ_MEMORY   = 15
+};
+
+enum {
+	OXNAS_DMA_TYPE_SIMPLE = 0,
+	OXNAS_DMA_TYPE_SG,
+};
+
+#define MAX_OXNAS_DMA_CHANNELS	5
+#define MAX_OXNAS_SG_ENTRIES	512
+
+/* Will be exchanged with SG DMA controller */
+struct oxnas_dma_sg_entry {
+	dma_addr_t                 data_addr;   /* physical address of the buffer */
+	unsigned long              data_length; /* length of the buffer */
+	dma_addr_t                 p_next_entry; /* physical address of next descriptor */
+	struct oxnas_dma_sg_entry *next_entry;   /* virtual address of the next descriptor */
+	dma_addr_t                 this_paddr;  /* physical address of this descriptor */
+	struct list_head	   entry;  /* Linked list entry */
+} __attribute((aligned(4), packed));
+
+/* Will be exchanged with SG DMA controller */
+struct oxnas_dma_sg_info {
+	unsigned long         qualifier;
+	unsigned long         control;
+	dma_addr_t            p_src_entries; /* physical address of the first source SG desc */
+	dma_addr_t            p_dst_entries; /* physical address of the first dest SG desc */
+	struct oxnas_dma_sg_entry *src_entries; /* virtual address of the first source SG desc */
+	struct oxnas_dma_sg_entry *dst_entries; /* virtual address of the first dest SG desc */
+} __attribute((aligned(4), packed));
+
+struct oxnas_dma_sg_data {
+	struct oxnas_dma_sg_entry entries[MAX_OXNAS_SG_ENTRIES];
+	struct oxnas_dma_sg_info infos[MAX_OXNAS_DMA_CHANNELS];
+} __attribute((aligned(4)));
+
+struct oxnas_dma_device;
+struct oxnas_dma_channel;
+
+struct oxnas_dma_desc {
+	struct virt_dma_desc vd;
+	struct oxnas_dma_channel *channel;
+	unsigned long ctrl;
+	unsigned long len;
+	dma_addr_t src_adr;
+	dma_addr_t dst_adr;
+	unsigned int type;
+	struct oxnas_dma_sg_info sg_info;
+	unsigned int entries;
+	struct list_head sg_entries;
+};
+
+struct oxnas_dma_channel {
+	struct virt_dma_chan vc;
+	struct list_head node;
+	struct oxnas_dma_device	*dmadev;
+	unsigned int id;
+	unsigned int irq;
+
+	struct dma_slave_config	cfg;
+
+	dma_addr_t p_sg_info; /* physical address of the array of sg_info structs */
+	struct oxnas_dma_sg_info *sg_info; /* virtual address of the array of sg_info structs */
+
+	atomic_t active;
+
+	struct oxnas_dma_desc *cur;
+};
+
+struct oxnas_dma_device {
+	struct platform_device *pdev;
+	struct dma_device common;
+	void __iomem *dma_base;
+	void __iomem *sgdma_base;
+	struct reset_control *dma_rst;
+	struct reset_control *sgdma_rst;
+	struct clk *dma_clk;
+
+	unsigned int channels_count;
+
+	struct oxnas_dma_channel channels[MAX_OXNAS_DMA_CHANNELS];
+
+	unsigned int hwversion;
+
+	/* Protects concurrent access to channels */
+	spinlock_t lock;
+	struct tasklet_struct tasklet;
+
+	struct list_head pending;
+
+	struct {
+		dma_addr_t start;
+		dma_addr_t end;
+		unsigned int type;
+	} *authorized_types;
+	unsigned int authorized_types_count;
+
+	struct list_head free_entries;
+	atomic_t free_entries_count;
+	dma_addr_t p_sg_data;
+	struct oxnas_dma_sg_data *sg_data;
+};
+
+static void oxnas_dma_start_next(struct oxnas_dma_channel *channel);
+
+static irqreturn_t oxnas_dma_interrupt(int irq, void *dev_id)
+{
+	struct oxnas_dma_channel *channel = dev_id;
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+	unsigned long error_code;
+	unsigned long flags;
+
+	dev_vdbg(&dmadev->pdev->dev, "irq for channel %d\n", channel->id);
+
+	while (readl(dmadev->dma_base + DMA_CALC_REG_ADR(0, DMA_INTR_ID)) & BIT(channel->id)) {
+		dev_dbg(&dmadev->pdev->dev, "Acking interrupt for channel %u\n",
+			channel->id);
+
+		/* Write to the interrupt clear register to clear interrupt */
+		writel(0, dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_INTR_CLEAR_REG));
+	}
+
+	if (channel->cur && channel->cur->type == OXNAS_DMA_TYPE_SG) {
+		error_code = readl(dmadev->sgdma_base +
+				DMA_SG_CALC_REG_ADR(channel->id, DMA_SG_STATUS));
+		error_code &= DMA_SG_STATUS_ERROR_CODE;
+
+		/* TOFIX report it to the core */
+		if (error_code)
+			dev_err(&dmadev->pdev->dev, "ch%d: sgdma err %x\n",
+				channel->id, (unsigned int)error_code);
+
+		writel(1, dmadev->sgdma_base + DMA_SG_CALC_REG_ADR(channel->id, DMA_SG_STATUS));
+	}
+
+	spin_lock_irqsave(&channel->vc.lock, flags);
+
+	if (atomic_read(&channel->active)) {
+		struct oxnas_dma_desc *cur = channel->cur;
+
+		oxnas_dma_start_next(channel);
+		if (cur)
+			vchan_cookie_complete(&cur->vd);
+	} else {
+		dev_warn(&dmadev->pdev->dev, "spurious irq for channel %d\n",
+			 channel->id);
+	}
+
+	spin_unlock_irqrestore(&channel->vc.lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void oxnas_dma_start_next(struct oxnas_dma_channel *channel)
+{
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+	struct virt_dma_desc *vd = vchan_next_desc(&channel->vc);
+	struct oxnas_dma_desc *desc;
+	unsigned long ctrl_status;
+
+	if (!vd) {
+		channel->cur = NULL;
+		return;
+	}
+
+	list_del(&vd->node);
+
+	desc = container_of(&vd->tx, struct oxnas_dma_desc, vd.tx);
+	channel->cur = desc;
+
+	if (desc->type == OXNAS_DMA_TYPE_SIMPLE) {
+		/* Write the control/status value to the DMAC */
+		writel(desc->ctrl,
+		       dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_CTRL_STATUS));
+
+		/* Ensure control/status word makes it to the DMAC before
+		 * we write address/length info
+		 */
+		wmb();
+
+		/* Write the source addresses to the DMAC */
+		writel(desc->src_adr & OXNAS_DMA_ADR_MASK,
+		       dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_BASE_SRC_ADR));
+
+		/* Write the destination addresses to the DMAC */
+		writel(desc->dst_adr & OXNAS_DMA_ADR_MASK,
+		       dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_BASE_DST_ADR));
+
+		/* Write the length, with EOT configuration
+		 * for the single transfer
+		 */
+		writel(desc->len,
+		       dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_BYTE_CNT));
+
+		/* Ensure adr/len info makes it to DMAC before later modifications to
+		 * control/status register due to starting the transfer, which happens in
+		 * oxnas_dma_start()
+		 */
+		wmb();
+
+		/* Setup channel data */
+		atomic_set(&channel->active, 1);
+
+		/* Single transfer mode, so unpause the DMA controller channel */
+		ctrl_status = readl(dmadev->dma_base +
+				    DMA_CALC_REG_ADR(channel->id, DMA_CTRL_STATUS));
+		writel(ctrl_status & ~DMA_CTRL_STATUS_PAUSE,
+		       dmadev->dma_base + DMA_CALC_REG_ADR(channel->id, DMA_CTRL_STATUS));
+
+		dev_dbg(&dmadev->pdev->dev, "ch%d: started req %d from %08x to %08x, %lubytes\n",
+			channel->id, vd->tx.cookie,
+			desc->src_adr, desc->dst_adr,
+			desc->len & OXNAS_DMA_MAX_TRANSFER_LENGTH);
+	} else if (desc->type == OXNAS_DMA_TYPE_SG) {
+		/* Write to the SG-DMA channel's reset register to reset the control
+		 * in case the previous SG-DMA transfer failed in some way, thus
+		 * leaving the SG-DMA controller hung up part way through processing
+		 * its SG list. The reset bits are self-clearing
+		 */
+		writel(DMA_SG_RESETS_CONTROL,
+		       dmadev->sgdma_base + DMA_SG_CALC_REG_ADR(channel->id, DMA_SG_RESETS));
+
+		/* Copy the sg_info structure */
+		memcpy(channel->sg_info, &desc->sg_info, sizeof(struct oxnas_dma_sg_info));
+
+		/* Ensure adr/len info makes it to DMAC before later modifications to
+		 * control/status register due to starting the transfer, which happens in
+		 * oxnas_dma_start()
+		 */
+		wmb();
+
+		/* Write the pointer to the SG info struct into the Request Pointer reg */
+		writel(channel->p_sg_info,
+		       dmadev->sgdma_base + DMA_SG_CALC_REG_ADR(channel->id, DMA_SG_REQ_PTR));
+
+		/* Setup channel data */
+		atomic_set(&channel->active, 1);
+
+		/* Start the transfert */
+		writel(DMA_SG_CONTROL_START |
+		       DMA_SG_CONTROL_QUEUING_ENABLE |
+		       DMA_SG_CONTROL_HBURST_ENABLE,
+		       dmadev->sgdma_base + DMA_SG_CALC_REG_ADR(channel->id, DMA_SG_CONTROL));
+
+		dev_dbg(&dmadev->pdev->dev, "ch%d: started %d sg req with %d entries\n",
+			channel->id, vd->tx.cookie,
+			desc->entries);
+	}
+}
+
+static void oxnas_dma_sched(unsigned long data)
+{
+	struct oxnas_dma_device *dmadev = (struct oxnas_dma_device *)data;
+	LIST_HEAD(head);
+
+	spin_lock_irq(&dmadev->lock);
+	list_splice_tail_init(&dmadev->pending, &head);
+	spin_unlock_irq(&dmadev->lock);
+
+	while (!list_empty(&head)) {
+		struct oxnas_dma_channel *ch = list_first_entry(&head,
+								struct oxnas_dma_channel, node);
+
+		spin_lock_irq(&ch->vc.lock);
+
+		list_del_init(&ch->node);
+		oxnas_dma_start_next(ch);
+
+		spin_unlock_irq(&ch->vc.lock);
+	}
+}
+
+static int oxnas_check_address(struct oxnas_dma_device *dmadev, dma_addr_t address)
+{
+	int i;
+
+	for (i = 0 ; i <  dmadev->authorized_types_count ; ++i) {
+		if (address >= dmadev->authorized_types[i].start &&
+		    address < dmadev->authorized_types[i].end)
+			return dmadev->authorized_types[i].type;
+	}
+
+	return -1;
+}
+
+static struct dma_async_tx_descriptor *oxnas_dma_prep_slave_sg(struct dma_chan *chan,
+							       struct scatterlist *sgl,
+							       unsigned int sglen,
+							       enum dma_transfer_direction dir,
+							       unsigned long flags, void *context)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+	struct oxnas_dma_desc *desc;
+	struct scatterlist *sgent;
+	struct oxnas_dma_sg_entry *entry_mem = NULL, *prev_entry_mem = NULL;
+	struct oxnas_dma_sg_entry *entry_dev = NULL;
+	unsigned int i;
+	int src_memory = OXNAS_DMA_DREQ_MEMORY;
+	int dst_memory = OXNAS_DMA_DREQ_MEMORY;
+
+	if (dir == DMA_DEV_TO_MEM) {
+		src_memory = oxnas_check_address(dmadev, channel->cfg.src_addr);
+		if (src_memory == -1) {
+			dev_err(&dmadev->pdev->dev, "invalid memory address %08x\n",
+				channel->cfg.src_addr);
+			return NULL;
+		}
+
+		if (src_memory == OXNAS_DMA_DREQ_MEMORY) {
+			dev_err(&dmadev->pdev->dev, "In DEV_TO_MEM, src cannot be memory\n");
+			return NULL;
+		}
+	} else if (dir == DMA_MEM_TO_DEV) {
+		dst_memory = oxnas_check_address(dmadev, channel->cfg.dst_addr);
+		if (dst_memory == -1) {
+			dev_err(&dmadev->pdev->dev, "invalid memory address %08x\n",
+				channel->cfg.dst_addr);
+			return NULL;
+		}
+
+		if (dst_memory == OXNAS_DMA_DREQ_MEMORY) {
+			dev_err(&dmadev->pdev->dev, "In MEM_TO_DEV, dst cannot be memory\n");
+			return NULL;
+		}
+	} else {
+		dev_err(&dmadev->pdev->dev, "invalid direction\n");
+		return NULL;
+	}
+
+	if (atomic_read(&dmadev->free_entries_count) < (sglen + 1)) {
+		dev_err(&dmadev->pdev->dev, "Missing sg entries...\n");
+		return NULL;
+	}
+
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (unlikely(!desc))
+		return NULL;
+	desc->channel = channel;
+
+	INIT_LIST_HEAD(&desc->sg_entries);
+	desc->entries = 0;
+
+	/* Device single entry */
+	entry_dev = list_first_entry_or_null(&dmadev->free_entries,
+					     struct oxnas_dma_sg_entry, entry);
+	if (!entry_dev) {
+		dev_err(&dmadev->pdev->dev, "Fatal error: Missing dev sg entry...\n");
+		goto entries_cleanup;
+	}
+
+	atomic_dec(&dmadev->free_entries_count);
+	list_move(&entry_dev->entry, &desc->sg_entries);
+	++desc->entries;
+	dev_dbg(&dmadev->pdev->dev, "got entry %p (%08x)\n", entry_dev, entry_dev->this_paddr);
+
+	entry_dev->next_entry = NULL;
+	entry_dev->p_next_entry = 0;
+	entry_dev->data_length = 0; /* Completed by mem sg entries */
+
+	if (dir == DMA_DEV_TO_MEM) {
+		entry_dev->data_addr = channel->cfg.src_addr & OXNAS_DMA_ADR_MASK;
+		desc->sg_info.src_entries = entry_dev;
+		desc->sg_info.p_src_entries = entry_dev->this_paddr;
+
+		dev_dbg(&dmadev->pdev->dev, "src set %p\n", entry_dev);
+	} else if (dir == DMA_MEM_TO_DEV) {
+		entry_dev->data_addr = channel->cfg.dst_addr & OXNAS_DMA_ADR_MASK;
+		desc->sg_info.dst_entries = entry_dev;
+		desc->sg_info.p_dst_entries = entry_dev->this_paddr;
+
+		dev_dbg(&dmadev->pdev->dev, "dst set %p\n", entry_dev);
+	}
+
+	dev_dbg(&dmadev->pdev->dev, "src = %p (%08x) dst = %p (%08x)\n",
+		desc->sg_info.src_entries, desc->sg_info.p_src_entries,
+		desc->sg_info.dst_entries, desc->sg_info.p_dst_entries);
+
+	/* Memory entries */
+	for_each_sg(sgl, sgent, sglen, i) {
+		entry_mem = list_first_entry_or_null(&dmadev->free_entries,
+						     struct oxnas_dma_sg_entry, entry);
+		if (!entry_mem) {
+			dev_err(&dmadev->pdev->dev, "Fatal error: Missing mem sg entries...\n");
+			goto entries_cleanup;
+		}
+
+		atomic_dec(&dmadev->free_entries_count);
+		list_move(&entry_mem->entry, &desc->sg_entries);
+		++desc->entries;
+		dev_dbg(&dmadev->pdev->dev, "got entry %p (%08x)\n",
+			entry_mem, entry_mem->this_paddr);
+
+		/* Fill the linked list */
+		if (prev_entry_mem) {
+			prev_entry_mem->next_entry = entry_mem;
+			prev_entry_mem->p_next_entry = entry_mem->this_paddr;
+		} else {
+			if (dir == DMA_DEV_TO_MEM) {
+				desc->sg_info.dst_entries = entry_mem;
+				desc->sg_info.p_dst_entries = entry_mem->this_paddr;
+				dev_dbg(&dmadev->pdev->dev, "src set %p\n", entry_mem);
+			} else if (dir == DMA_MEM_TO_DEV) {
+				desc->sg_info.src_entries = entry_mem;
+				desc->sg_info.p_src_entries = entry_mem->this_paddr;
+				dev_dbg(&dmadev->pdev->dev, "dst set %p\n", entry_mem);
+			}
+
+			dev_dbg(&dmadev->pdev->dev, "src = %p (%08x) dst = %p (%08x)\n",
+				desc->sg_info.src_entries, desc->sg_info.p_src_entries,
+				desc->sg_info.dst_entries, desc->sg_info.p_dst_entries);
+		}
+		prev_entry_mem = entry_mem;
+
+		/* Fill the entry from the SG */
+		entry_mem->next_entry = NULL;
+		entry_mem->p_next_entry = 0;
+
+		entry_mem->data_addr = sg_dma_address(sgent) & OXNAS_DMA_ADR_MASK;
+		entry_mem->data_length = sg_dma_len(sgent);
+		dev_dbg(&dmadev->pdev->dev, "sg = %08x len = %d\n",
+			sg_dma_address(sgent), sg_dma_len(sgent));
+
+		/* Add to dev sg length */
+		entry_dev->data_length += sg_dma_len(sgent);
+	}
+	dev_dbg(&dmadev->pdev->dev, "allocated %d sg entries\n", desc->entries);
+
+	desc->sg_info.qualifier = FIELD_PREP(OXNAS_DMA_SG_CHANNEL, channel->id) |
+				  OXNAS_DMA_SG_QUALIFIER;
+
+	if (dir == DMA_DEV_TO_MEM)
+		desc->sg_info.qualifier |= FIELD_PREP(OXNAS_DMA_SG_SRC_EOT, 2);
+	else if (dir == DMA_MEM_TO_DEV)
+		desc->sg_info.qualifier |= FIELD_PREP(OXNAS_DMA_SG_DST_EOT, 2);
+
+	desc->sg_info.control = (DMA_CTRL_STATUS_INTERRUPT_ENABLE |
+				 DMA_CTRL_STATUS_FAIR_SHARE_ARB |
+				 DMA_CTRL_STATUS_INTR_CLEAR_ENABLE);
+	desc->sg_info.control |= FIELD_PREP(DMA_CTRL_STATUS_SRC_DREQ, src_memory);
+	desc->sg_info.control |= FIELD_PREP(DMA_CTRL_STATUS_DEST_DREQ, dst_memory);
+
+	if (dir == DMA_DEV_TO_MEM) {
+		desc->sg_info.control |= DMA_CTRL_STATUS_SRC_ADR_MODE;
+		desc->sg_info.control &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
+		desc->sg_info.control |= DMA_CTRL_STATUS_DEST_ADR_MODE;
+		desc->sg_info.control &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
+	} else if (dir == DMA_MEM_TO_DEV) {
+		desc->sg_info.control |= DMA_CTRL_STATUS_SRC_ADR_MODE;
+		desc->sg_info.control &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
+		desc->sg_info.control |= DMA_CTRL_STATUS_DEST_ADR_MODE;
+		desc->sg_info.control &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
+	}
+	desc->sg_info.control |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
+	desc->sg_info.control |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
+	desc->sg_info.control |= FIELD_PREP(DMA_CTRL_STATUS_DIR, OXNAS_DMA_A_TO_B);
+
+	desc->sg_info.control |= FIELD_PREP(DMA_CTRL_STATUS_SRC_WIDTH,
+					    OXNAS_DMA_TRANSFER_WIDTH_32BITS);
+	desc->sg_info.control |= FIELD_PREP(DMA_CTRL_STATUS_DEST_WIDTH,
+					    OXNAS_DMA_TRANSFER_WIDTH_32BITS);
+	desc->sg_info.control &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY;
+
+	desc->type = OXNAS_DMA_TYPE_SG;
+
+	return vchan_tx_prep(&channel->vc, &desc->vd, flags);
+
+entries_cleanup:
+	/* Put back all entries in the free entries... */
+	list_splice_tail_init(&desc->sg_entries, &dmadev->free_entries);
+	atomic_add(desc->entries, &dmadev->free_entries_count);
+	dev_dbg(&dmadev->pdev->dev, "freed %d sg entries\n", desc->entries);
+
+	kfree(desc);
+
+	return NULL;
+}
+
+/** Allocate descriptors capable of mapping the requested length of memory */
+static struct dma_async_tx_descriptor  *oxnas_dma_prep_dma_memcpy(struct dma_chan *chan,
+								  dma_addr_t dst, dma_addr_t src,
+								  size_t len, unsigned long flags)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+	struct oxnas_dma_desc *desc;
+	int src_memory = OXNAS_DMA_DREQ_MEMORY;
+	int dst_memory = OXNAS_DMA_DREQ_MEMORY;
+
+	if (len > OXNAS_DMA_MAX_TRANSFER_LENGTH)
+		return NULL;
+
+	src_memory = oxnas_check_address(dmadev, src);
+	if (src_memory == -1) {
+		dev_err(&dmadev->pdev->dev, "invalid memory address %08x\n", src);
+		return NULL;
+	}
+
+	dst_memory = oxnas_check_address(dmadev, dst);
+	if (dst_memory == -1) {
+		dev_err(&dmadev->pdev->dev, "invalid memory address %08x\n", src);
+		return NULL;
+	}
+
+	desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+	if (unlikely(!desc))
+		return NULL;
+	desc->channel = channel;
+
+	dev_dbg(&dmadev->pdev->dev, "preparing memcpy from %08x to %08x, %lubytes (flags %x)\n",
+		src, dst, (unsigned long)len, (unsigned int)flags);
+
+	/* CTRL STATUS Preparation */
+
+	/* Pause while start */
+	desc->ctrl = DMA_CTRL_STATUS_PAUSE;
+
+	/* Interrupts enabled
+	 * High priority
+	 * Use new interrupt clearing register
+	 */
+	desc->ctrl |= DMA_CTRL_STATUS_INTERRUPT_ENABLE |
+		      DMA_CTRL_STATUS_FAIR_SHARE_ARB |
+		      DMA_CTRL_STATUS_INTR_CLEAR_ENABLE;
+
+	/* Type Memory */
+	desc->ctrl |= FIELD_PREP(DMA_CTRL_STATUS_SRC_DREQ, src_memory);
+	desc->ctrl |= FIELD_PREP(DMA_CTRL_STATUS_DEST_DREQ, dst_memory);
+
+	/* Setup the transfer direction and burst/single mode for the two DMA busses */
+	desc->ctrl |= DMA_CTRL_STATUS_TRANSFER_MODE_A;
+	desc->ctrl |= DMA_CTRL_STATUS_TRANSFER_MODE_B;
+	desc->ctrl |= FIELD_PREP(DMA_CTRL_STATUS_DIR, OXNAS_DMA_A_TO_B);
+
+	/* Incrementing addresses */
+	desc->ctrl |= DMA_CTRL_STATUS_SRC_ADR_MODE;
+	desc->ctrl &= ~DMA_CTRL_STATUS_SOURCE_ADDRESS_FIXED;
+	desc->ctrl |= DMA_CTRL_STATUS_DEST_ADR_MODE;
+	desc->ctrl &= ~DMA_CTRL_STATUS_DESTINATION_ADDRESS_FIXED;
+
+	/* Set up the width of the transfers on the DMA buses */
+	desc->ctrl |= FIELD_PREP(DMA_CTRL_STATUS_SRC_WIDTH, OXNAS_DMA_TRANSFER_WIDTH_32BITS);
+	desc->ctrl |= FIELD_PREP(DMA_CTRL_STATUS_DEST_WIDTH, OXNAS_DMA_TRANSFER_WIDTH_32BITS);
+
+	/* Setup the priority arbitration scheme */
+	desc->ctrl &= ~DMA_CTRL_STATUS_STARVE_LOW_PRIORITY;
+
+	/* LENGTH and End Of Transfert Preparation */
+	desc->len = len |
+		    DMA_BYTE_CNT_INC4_SET_MASK |    /* Always enable INC4 transfers */
+		    DMA_BYTE_CNT_HPROT_MASK |       /* Always enable HPROT assertion */
+		    DMA_BYTE_CNT_RD_EOT_MASK;       /* EOT at last Read */
+
+	desc->src_adr = src;
+	desc->dst_adr = dst;
+	desc->type = OXNAS_DMA_TYPE_SIMPLE;
+
+	return vchan_tx_prep(&channel->vc, &desc->vd, flags);
+}
+
+static int oxnas_dma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+
+	memcpy(&channel->cfg, cfg, sizeof(channel->cfg));
+
+	return 0;
+}
+
+static void oxnas_dma_desc_free(struct virt_dma_desc *vd)
+{
+	struct oxnas_dma_desc *desc = container_of(&vd->tx, struct oxnas_dma_desc, vd.tx);
+	struct oxnas_dma_channel *channel = desc->channel;
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+
+	/* Free SG entries */
+	if (desc->type == OXNAS_DMA_TYPE_SG) {
+		list_splice_tail_init(&desc->sg_entries, &dmadev->free_entries);
+		atomic_add(desc->entries, &dmadev->free_entries_count);
+		dev_dbg(&dmadev->pdev->dev, "freed %d sg entries\n", desc->entries);
+	}
+
+	kfree(container_of(vd, struct oxnas_dma_desc, vd));
+}
+
+/** Poll for the DMA channel's active status. There can be multiple transfers
+ *  queued with the DMA channel identified by cookies, so should be checking
+ *  lists containing all pending transfers and all completed transfers that have
+ *  not yet been polled for completion
+ */
+static enum dma_status oxnas_dma_tx_status(struct dma_chan *chan,
+					   dma_cookie_t cookie,
+					   struct dma_tx_state *txstate)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+	struct virt_dma_desc *vd;
+	enum dma_status ret;
+	unsigned long flags;
+
+	ret = dma_cookie_status(chan, cookie, txstate);
+	if (ret == DMA_COMPLETE || !txstate)
+		return ret;
+
+	spin_lock_irqsave(&channel->vc.lock, flags);
+	vd = vchan_find_desc(&channel->vc, cookie);
+	if (vd) {
+		struct oxnas_dma_desc *desc = container_of(&vd->tx, struct oxnas_dma_desc, vd.tx);
+
+		txstate->residue = desc->len & OXNAS_DMA_MAX_TRANSFER_LENGTH;
+	} else {
+		txstate->residue = 0;
+	}
+	spin_unlock_irqrestore(&channel->vc.lock, flags);
+
+	return ret;
+}
+
+/** To push outstanding transfers to h/w. This should use the list of pending
+ *  transfers identified by cookies to select the next transfer and pass this to
+ *  the hardware
+ */
+static void oxnas_dma_issue_pending(struct dma_chan *chan)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+	struct oxnas_dma_device *dmadev = channel->dmadev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&channel->vc.lock, flags);
+	if (vchan_issue_pending(&channel->vc) && !channel->cur) {
+		spin_lock(&dmadev->lock);
+
+		if (list_empty(&channel->node))
+			list_add_tail(&channel->node, &dmadev->pending);
+
+		spin_unlock(&dmadev->lock);
+
+		tasklet_schedule(&dmadev->tasklet);
+	}
+
+	spin_unlock_irqrestore(&channel->vc.lock, flags);
+}
+
+static void oxnas_dma_free_chan_resources(struct dma_chan *chan)
+{
+	struct oxnas_dma_channel *channel = container_of(chan, struct oxnas_dma_channel, vc.chan);
+
+	vchan_free_chan_resources(&channel->vc);
+}
+
+static int oxnas_dma_probe(struct platform_device *pdev)
+{
+	struct oxnas_dma_device *dmadev;
+	struct resource *res;
+	int hwid, i, ret;
+
+	dmadev = devm_kzalloc(&pdev->dev, sizeof(struct oxnas_dma_device), GFP_KERNEL);
+	if (!dmadev)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	dmadev->dma_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dmadev->dma_base))
+		return PTR_ERR(dmadev->dma_base);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	dmadev->sgdma_base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(dmadev->sgdma_base))
+		return PTR_ERR(dmadev->sgdma_base);
+
+	dmadev->dma_rst = devm_reset_control_get(&pdev->dev, "dma");
+	if (IS_ERR(dmadev->dma_rst))
+		return PTR_ERR(dmadev->dma_rst);
+
+	dmadev->sgdma_rst = devm_reset_control_get(&pdev->dev, "sgdma");
+	if (IS_ERR(dmadev->sgdma_rst))
+		return PTR_ERR(dmadev->sgdma_rst);
+
+	dmadev->dma_clk = devm_clk_get(&pdev->dev, 0);
+	if (IS_ERR(dmadev->dma_clk))
+		return PTR_ERR(dmadev->dma_clk);
+
+	ret = of_property_count_elems_of_size(pdev->dev.of_node, "oxsemi,targets-types", 4);
+	if (ret <= 0 || (ret % 3) != 0) {
+		dev_err(&pdev->dev, "malformed or missing oxsemi,targets-types\n");
+		return -EINVAL;
+	}
+
+	dmadev->authorized_types_count = ret / 3;
+	dmadev->authorized_types = devm_kzalloc(&pdev->dev,
+		sizeof(*dmadev->authorized_types) * dmadev->authorized_types_count, GFP_KERNEL);
+
+	if (!dmadev->authorized_types)
+		return -ENOMEM;
+
+	for (i = 0 ; i < dmadev->authorized_types_count ; ++i) {
+		u32 value;
+
+		ret = of_property_read_u32_index(pdev->dev.of_node,
+						 "oxsemi,targets-types",
+						 (i * 3), &value);
+		if (ret < 0)
+			return ret;
+
+		dmadev->authorized_types[i].start = value;
+		ret = of_property_read_u32_index(pdev->dev.of_node,
+						 "oxsemi,targets-types",
+						 (i * 3) + 1, &value);
+		if (ret < 0)
+			return ret;
+
+		dmadev->authorized_types[i].end = value;
+		ret = of_property_read_u32_index(pdev->dev.of_node,
+						 "oxsemi,targets-types",
+						 (i * 3) + 2, &value);
+		if (ret < 0)
+			return ret;
+
+		dmadev->authorized_types[i].type = value;
+	}
+
+	dev_dbg(&pdev->dev, "Authorized memory ranges :\n");
+	dev_dbg(&pdev->dev, " Start    - End      = Type\n");
+	for (i = 0 ; i <  dmadev->authorized_types_count ; ++i)
+		dev_dbg(&pdev->dev, "0x%08x-0x%08x = %d\n",
+			dmadev->authorized_types[i].start,
+			dmadev->authorized_types[i].end,
+			dmadev->authorized_types[i].type);
+
+	dmadev->pdev = pdev;
+
+	spin_lock_init(&dmadev->lock);
+
+	tasklet_init(&dmadev->tasklet, oxnas_dma_sched, (unsigned long)dmadev);
+	INIT_LIST_HEAD(&dmadev->common.channels);
+	INIT_LIST_HEAD(&dmadev->pending);
+	INIT_LIST_HEAD(&dmadev->free_entries);
+
+	/* Enable HW & Clocks */
+	reset_control_reset(dmadev->dma_rst);
+	reset_control_reset(dmadev->sgdma_rst);
+	clk_prepare_enable(dmadev->dma_clk);
+
+	/* Discover the number of channels available */
+	hwid = readl(dmadev->dma_base + DMA_CALC_REG_ADR(0, DMA_INTR_ID));
+	dmadev->channels_count = DMA_INTR_ID_GET_NUM_CHANNELS(hwid);
+	dmadev->hwversion = DMA_INTR_ID_GET_VERSION(hwid);
+
+	dev_dbg(&pdev->dev, "OXNAS DMA v%x with %d channels\n",
+		dmadev->hwversion, dmadev->channels_count);
+
+	/* Limit channels count */
+	if (dmadev->channels_count > MAX_OXNAS_DMA_CHANNELS)
+		dmadev->channels_count = MAX_OXNAS_DMA_CHANNELS;
+
+	/* Allocate coherent memory for sg descriptors */
+	dmadev->sg_data = dma_alloc_coherent(&pdev->dev, sizeof(struct oxnas_dma_sg_data),
+					     &dmadev->p_sg_data, GFP_KERNEL);
+	if (!dmadev->sg_data) {
+		ret = -ENOMEM;
+		goto disable_clks;
+	}
+
+	/* Reset SG descritors */
+	memset(dmadev->sg_data, 0, sizeof(struct oxnas_dma_sg_data));
+	atomic_set(&dmadev->free_entries_count, 0);
+
+	/* Initialize and add all sg entries to the free list */
+	for (i = 0 ; i < MAX_OXNAS_SG_ENTRIES ; ++i) {
+		dmadev->sg_data->entries[i].this_paddr =
+			(dma_addr_t)&(((struct oxnas_dma_sg_data *)dmadev->p_sg_data)->entries[i]);
+		INIT_LIST_HEAD(&dmadev->sg_data->entries[i].entry);
+		list_add_tail(&dmadev->sg_data->entries[i].entry,
+			      &dmadev->free_entries);
+		atomic_inc(&dmadev->free_entries_count);
+	}
+
+	/* Init all channels */
+	for (i = 0 ; i < dmadev->channels_count ; ++i) {
+		struct oxnas_dma_channel *ch = &dmadev->channels[i];
+
+		ch->dmadev = dmadev;
+		ch->id = i;
+
+		ch->irq = irq_of_parse_and_map(pdev->dev.of_node, i);
+		if (ch->irq <= 0) {
+			dev_err(&pdev->dev, "invalid irq%d from platform\n", i);
+			goto free_coherent;
+		}
+
+		ret = devm_request_irq(&pdev->dev, ch->irq,
+				       oxnas_dma_interrupt, 0,
+				       "DMA", ch);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "failed to request irq%d\n", i);
+			goto free_coherent;
+		}
+
+		ch->p_sg_info =
+			(dma_addr_t)&((struct oxnas_dma_sg_data *)dmadev->p_sg_data)->infos[i];
+		ch->sg_info = &dmadev->sg_data->infos[i];
+		memset(ch->sg_info, 0, sizeof(struct oxnas_dma_sg_info));
+
+		atomic_set(&ch->active, 0);
+
+		ch->vc.desc_free = oxnas_dma_desc_free;
+		vchan_init(&ch->vc, &dmadev->common);
+		INIT_LIST_HEAD(&ch->node);
+	}
+
+	platform_set_drvdata(pdev, dmadev);
+
+	dma_cap_set(DMA_MEMCPY, dmadev->common.cap_mask);
+	dmadev->common.chancnt = dmadev->channels_count;
+	dmadev->common.device_free_chan_resources = oxnas_dma_free_chan_resources;
+	dmadev->common.device_tx_status = oxnas_dma_tx_status;
+	dmadev->common.device_issue_pending = oxnas_dma_issue_pending;
+	dmadev->common.device_prep_dma_memcpy = oxnas_dma_prep_dma_memcpy;
+	dmadev->common.device_prep_slave_sg = oxnas_dma_prep_slave_sg;
+	dmadev->common.device_config = oxnas_dma_slave_config;
+	dmadev->common.copy_align = DMAENGINE_ALIGN_4_BYTES;
+	dmadev->common.src_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dmadev->common.dst_addr_widths = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	dmadev->common.directions = BIT(DMA_MEM_TO_MEM);
+	dmadev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+	dmadev->common.dev = &pdev->dev;
+
+	ret = dma_async_device_register(&dmadev->common);
+	if (ret)
+		goto free_coherent;
+
+	ret = of_dma_controller_register(pdev->dev.of_node,
+					 of_dma_xlate_by_chan_id,
+					 &dmadev->common);
+	if (ret) {
+		dev_warn(&pdev->dev, "Failed to register DMA Controller\n");
+		goto dma_unregister;
+	}
+
+	dev_info(&pdev->dev, "OXNAS DMA Registered\n");
+
+	return 0;
+
+dma_unregister:
+	dma_async_device_unregister(&dmadev->common);
+
+free_coherent:
+	dma_free_coherent(&pdev->dev, sizeof(struct oxnas_dma_sg_data),
+			  dmadev->sg_data, dmadev->p_sg_data);
+
+disable_clks:
+	clk_disable_unprepare(dmadev->dma_clk);
+
+	return ret;
+}
+
+static int oxnas_dma_remove(struct platform_device *pdev)
+{
+	struct oxnas_dma_device *dmadev = platform_get_drvdata(pdev);
+
+	dma_async_device_unregister(&dmadev->common);
+
+	dma_free_coherent(&pdev->dev, sizeof(struct oxnas_dma_sg_data),
+			  dmadev->sg_data, dmadev->p_sg_data);
+
+	clk_disable_unprepare(dmadev->dma_clk);
+
+	return 0;
+}
+
+static const struct of_device_id oxnas_dma_of_dev_id[] = {
+	{ .compatible = "oxsemi,ox810se-dma", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, oxnas_dma_of_dev_id);
+
+static struct platform_driver oxnas_dma_driver = {
+	.probe		= oxnas_dma_probe,
+	.remove		= oxnas_dma_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "oxnas-dma",
+		.of_match_table = oxnas_dma_of_dev_id,
+	},
+};
+
+static int __init oxnas_dma_init_module(void)
+{
+	return platform_driver_register(&oxnas_dma_driver);
+}
+subsys_initcall(oxnas_dma_init_module);
+
+static void __exit oxnas_dma_exit_module(void)
+{
+	platform_driver_unregister(&oxnas_dma_driver);
+}
+module_exit(oxnas_dma_exit_module);
+
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:56:43 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:56:43 +0100
Subject: [PATCH v2 0/3] ARM: ox810se: Add Ethernet support
Message-ID: <20220104145646.135877-1-narmstrong@baylibre.com>

This adds support for the Synopsys DWMAC controller found in the
OX820SE SoC, by using almost the same glue code as the OX820.

Patch 1 & 2 are for net branch, patch 3 will be queued to arm-soc.

Changes since v1:
- correctly update value read from register
- add proper tag on patch 3 for arm-soc tree

Neil Armstrong (3):
  dt-bindings: net: oxnas-dwmac: Add bindings for OX810SE
  net: stmmac: dwmac-oxnas: Add support for OX810SE
  ARM: dts: ox810se: Add Ethernet support

 .../devicetree/bindings/net/oxnas-dwmac.txt   |   3 +
 arch/arm/boot/dts/ox810se-wd-mbwe.dts         |   4 +
 arch/arm/boot/dts/ox810se.dtsi                |  18 +++
 .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 115 +++++++++++++-----
 4 files changed, 111 insertions(+), 29 deletions(-)

-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:56:44 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:56:44 +0100
Subject: [PATCH net-next v2 1/3] dt-bindings: net: oxnas-dwmac: Add bindings
 for OX810SE
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <20220104145646.135877-2-narmstrong@baylibre.com>

Add SoC specific bindings for OX810SE support.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 Documentation/devicetree/bindings/net/oxnas-dwmac.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
index d7117a22fd87..27db496f1ce8 100644
--- a/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/oxnas-dwmac.txt
@@ -9,6 +9,9 @@ Required properties on all platforms:
 - compatible:	For the OX820 SoC, it should be :
 		- "oxsemi,ox820-dwmac" to select glue
 		- "snps,dwmac-3.512" to select IP version.
+		For the OX810SE SoC, it should be :
+		- "oxsemi,ox810se-dwmac" to select glue
+		- "snps,dwmac-3.512" to select IP version.
 
 - clocks: Should contain phandles to the following clocks
 - clock-names:	Should contain the following:
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:56:45 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:56:45 +0100
Subject: [PATCH net-next v2 2/3] net: stmmac: dwmac-oxnas: Add support for
 OX810SE
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <20220104145646.135877-3-narmstrong@baylibre.com>

Add support for OX810SE dwmac glue setup, which is a simplified version
of the OX820 introduced later with more control on the PHY interface.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-oxnas.c | 115 +++++++++++++-----
 1 file changed, 86 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
index adfeb8d3293d..62a69a91ab22 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-oxnas.c
@@ -12,6 +12,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/mfd/syscon.h>
@@ -48,16 +49,75 @@
 #define DWMAC_RX_VARDELAY(d)		((d) << DWMAC_RX_VARDELAY_SHIFT)
 #define DWMAC_RXN_VARDELAY(d)		((d) << DWMAC_RXN_VARDELAY_SHIFT)
 
+struct oxnas_dwmac;
+
+struct oxnas_dwmac_data {
+	int (*setup)(struct oxnas_dwmac *dwmac);
+};
+
 struct oxnas_dwmac {
 	struct device	*dev;
 	struct clk	*clk;
 	struct regmap	*regmap;
+	const struct oxnas_dwmac_data	*data;
 };
 
+static int oxnas_dwmac_setup_ox810se(struct oxnas_dwmac *dwmac)
+{
+	unsigned int value;
+	int ret;
+
+	ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
+	if (ret < 0)
+		return ret;
+
+	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
+	value |= BIT(DWMAC_CKEN_GTX)		|
+		 /* Use simple mux for 25/125 Mhz clock switching */
+		 BIT(DWMAC_SIMPLE_MUX);
+
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
+
+	return 0;
+}
+
+static int oxnas_dwmac_setup_ox820(struct oxnas_dwmac *dwmac)
+{
+	unsigned int value;
+	int ret;
+
+	ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
+	if (ret < 0)
+		return ret;
+
+	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
+	value |= BIT(DWMAC_CKEN_GTX)		|
+		 /* Use simple mux for 25/125 Mhz clock switching */
+		BIT(DWMAC_SIMPLE_MUX)		|
+		/* set auto switch tx clock source */
+		BIT(DWMAC_AUTO_TX_SOURCE)	|
+		/* enable tx & rx vardelay */
+		BIT(DWMAC_CKEN_TX_OUT)		|
+		BIT(DWMAC_CKEN_TXN_OUT)	|
+		BIT(DWMAC_CKEN_TX_IN)		|
+		BIT(DWMAC_CKEN_RX_OUT)		|
+		BIT(DWMAC_CKEN_RXN_OUT)	|
+		BIT(DWMAC_CKEN_RX_IN);
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
+
+	/* set tx & rx vardelay */
+	value = DWMAC_TX_VARDELAY(4)	|
+		DWMAC_TXN_VARDELAY(2)	|
+		DWMAC_RX_VARDELAY(10)	|
+		DWMAC_RXN_VARDELAY(8);
+	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
+
+	return 0;
+}
+
 static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
 {
 	struct oxnas_dwmac *dwmac = priv;
-	unsigned int value;
 	int ret;
 
 	/* Reset HW here before changing the glue configuration */
@@ -69,35 +129,11 @@ static int oxnas_dwmac_init(struct platform_device *pdev, void *priv)
 	if (ret)
 		return ret;
 
-	ret = regmap_read(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, &value);
-	if (ret < 0) {
+	ret = dwmac->data->setup(dwmac);
+	if (ret)
 		clk_disable_unprepare(dwmac->clk);
-		return ret;
-	}
 
-	/* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */
-	value |= BIT(DWMAC_CKEN_GTX)		|
-		 /* Use simple mux for 25/125 Mhz clock switching */
-		 BIT(DWMAC_SIMPLE_MUX)		|
-		 /* set auto switch tx clock source */
-		 BIT(DWMAC_AUTO_TX_SOURCE)	|
-		 /* enable tx & rx vardelay */
-		 BIT(DWMAC_CKEN_TX_OUT)		|
-		 BIT(DWMAC_CKEN_TXN_OUT)	|
-		 BIT(DWMAC_CKEN_TX_IN)		|
-		 BIT(DWMAC_CKEN_RX_OUT)		|
-		 BIT(DWMAC_CKEN_RXN_OUT)	|
-		 BIT(DWMAC_CKEN_RX_IN);
-	regmap_write(dwmac->regmap, OXNAS_DWMAC_CTRL_REGOFFSET, value);
-
-	/* set tx & rx vardelay */
-	value = DWMAC_TX_VARDELAY(4)	|
-		DWMAC_TXN_VARDELAY(2)	|
-		DWMAC_RX_VARDELAY(10)	|
-		DWMAC_RXN_VARDELAY(8);
-	regmap_write(dwmac->regmap, OXNAS_DWMAC_DELAY_REGOFFSET, value);
-
-	return 0;
+	return ret;
 }
 
 static void oxnas_dwmac_exit(struct platform_device *pdev, void *priv)
@@ -128,6 +164,12 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
 		goto err_remove_config_dt;
 	}
 
+	dwmac->data = (const struct oxnas_dwmac_data *)of_device_get_match_data(&pdev->dev);
+	if (!dwmac->data) {
+		ret = -EINVAL;
+		goto err_remove_config_dt;
+	}
+
 	dwmac->dev = &pdev->dev;
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->init = oxnas_dwmac_init;
@@ -166,8 +208,23 @@ static int oxnas_dwmac_probe(struct platform_device *pdev)
 	return ret;
 }
 
+static const struct oxnas_dwmac_data ox810se_dwmac_data = {
+	.setup = oxnas_dwmac_setup_ox810se,
+};
+
+static const struct oxnas_dwmac_data ox820_dwmac_data = {
+	.setup = oxnas_dwmac_setup_ox820,
+};
+
 static const struct of_device_id oxnas_dwmac_match[] = {
-	{ .compatible = "oxsemi,ox820-dwmac" },
+	{
+		.compatible = "oxsemi,ox810se-dwmac",
+		.data = &ox810se_dwmac_data,
+	},
+	{
+		.compatible = "oxsemi,ox820-dwmac",
+		.data = &ox820_dwmac_data,
+	},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, oxnas_dwmac_match);
-- 
2.25.1



From narmstrong at baylibre.com  Tue Jan  4 06:56:46 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue,  4 Jan 2022 15:56:46 +0100
Subject: [PATCH arm-soc-next v2 3/3] ARM: dts: ox810se: Add Ethernet support
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <20220104145646.135877-4-narmstrong@baylibre.com>

Add nodes for the embedded Synopsys DWMAC Ethernet controller.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 arch/arm/boot/dts/ox810se-wd-mbwe.dts |  4 ++++
 arch/arm/boot/dts/ox810se.dtsi        | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/arch/arm/boot/dts/ox810se-wd-mbwe.dts b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
index 7e2fcb220aea..c59e06ff2423 100644
--- a/arch/arm/boot/dts/ox810se-wd-mbwe.dts
+++ b/arch/arm/boot/dts/ox810se-wd-mbwe.dts
@@ -103,6 +103,10 @@ rtc0: rtc at 48 {
 	};
 };
 
+&etha {
+	status = "okay";
+};
+
 &uart1 {
 	status = "okay";
 
diff --git a/arch/arm/boot/dts/ox810se.dtsi b/arch/arm/boot/dts/ox810se.dtsi
index 0755e5864c4a..96c0745f7b70 100644
--- a/arch/arm/boot/dts/ox810se.dtsi
+++ b/arch/arm/boot/dts/ox810se.dtsi
@@ -81,6 +81,24 @@ soc {
 		ranges;
 		interrupt-parent = <&intc>;
 
+		etha: ethernet at 40400000 {
+			compatible = "oxsemi,ox810se-dwmac", "snps,dwmac";
+			reg = <0x40400000 0x2000>;
+			interrupts = <8>;
+			interrupt-names = "macirq";
+			mac-address = [000000000000]; /* Filled in by U-Boot */
+			phy-mode = "rgmii";
+
+			clocks = <&stdclk 6>, <&gmacclk>;
+			clock-names = "gmac", "stmmaceth";
+			resets = <&reset 6>;
+
+			/* Regmap for sys registers */
+			oxsemi,sys-ctrl = <&sys>;
+
+			status = "disabled";
+		};
+
 		apb-bridge at 44000000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.25.1



From linux at armlinux.org.uk  Tue Jan  4 06:57:33 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 4 Jan 2022 14:57:33 +0000
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRdu3jFPnGd1DsH@lunn.ch>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
 <YdRZQl6U0y19P/0+@shell.armlinux.org.uk> <YdRdu3jFPnGd1DsH@lunn.ch>
Message-ID: <YdRgXbpK6CFB/eCU@shell.armlinux.org.uk>

On Tue, Jan 04, 2022 at 03:46:19PM +0100, Andrew Lunn wrote:
> > @@ -1227,16 +1227,18 @@ static int m88e1118_config_init(struct phy_device *phydev)
> >  {
> >  	int err;
> >  
> > -	/* Change address */
> > -	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
> > -	if (err < 0)
> > -		return err;
> > -
> >  	/* Enable 1000 Mbit */
> > -	err = phy_write(phydev, 0x15, 0x1070);
> > +	err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
> > +			      MII_88E1121_PHY_MSCR_REG, 0x1070);
> 
> Ah, yes, keeping this makes it more backwards compatible.
> 
> It would be nice to replace the 0x1070 with #defines.
> 
> We already have:
> 
> #define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
> #define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
> #define MII_88E1121_PHY_MSCR_DELAY_MASK	(BIT(5) | BIT(4))
> 
> Bits 6 is the MSB of the default MAC speed.
> Bit 13 is the LSB of the default MAC speed. These two should default to 10b = 1000Mbps
> Bit 12 is reserved, and should be written 1.

Hmm, seems odd that these speed bits match BMCR, and I'm not sure why
the default MAC speed would have any bearing on whether gigabit mode
is enabled. If they default to 10b, then the write should have no effect
unless boot firmware has changed them.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From richard.genoud at gmail.com  Tue Jan  4 06:57:56 2022
From: richard.genoud at gmail.com (Richard Genoud)
Date: Tue,  4 Jan 2022 14:57:56 +0000
Subject: [PATCH] serial: atmel: Use platform_get_irq() to get the interrupt
In-Reply-To: <20211215224832.1985402-1-robh@kernel.org>
References: <20211215224832.1985402-1-robh@kernel.org>
Message-ID: <c5c4176f-2a55-6fc5-d5dd-ce3b43fd11ff@posteo.net>


Le 15/12/2021 ? 23:48, Rob Herring a ?crit?:
> Accessing platform device resources directly has long been deprecated for
> DT as IRQ resources may not be available at device creation time. Drivers
> continuing to use static IRQ resources is blocking removing the static setup
> from the DT core code.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
Acked-by: Richard Genoud <richard.genoud at gmail.com>

> ---
>   drivers/tty/serial/atmel_serial.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
> index 2c99a47a2535..9e57bfe523cf 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -2479,7 +2479,7 @@ static int atmel_init_port(struct atmel_uart_port *atmel_port,
>   	port->fifosize		= 1;
>   	port->dev		= &pdev->dev;
>   	port->mapbase		= mpdev->resource[0].start;
> -	port->irq		= mpdev->resource[1].start;
> +	port->irq		= platform_get_irq(mpdev, 0);
>   	port->rs485_config	= atmel_config_rs485;
>   	port->iso7816_config	= atmel_config_iso7816;
>   	port->membase		= NULL;

Thanks !


From broonie at kernel.org  Tue Jan  4 06:59:45 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Jan 2022 14:59:45 +0000
Subject: [PATCH v12 03/10] arm64: Rename stackframe to unwind_state
In-Reply-To: <20220103165212.9303-4-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-4-madvenka@linux.microsoft.com>
Message-ID: <YdRg4YoQK1q2D18w@sirena.org.uk>

On Mon, Jan 03, 2022 at 10:52:05AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Rename "struct stackframe" to "struct unwind_state" for consistency and
> better naming. Accordingly, rename variable/argument "frame" to "state".

Reviewed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/ae6203aa/attachment.sig>

From broonie at kernel.org  Tue Jan  4 07:00:59 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Jan 2022 15:00:59 +0000
Subject: [PATCH] drivers/regulator: remove redundant ret variable
In-Reply-To: <20220104104139.601031-1-chi.minghao@zte.com.cn>
References: <20220104104139.601031-1-chi.minghao@zte.com.cn>
Message-ID: <YdRhK55op7XzJAuj@sirena.org.uk>

On Tue, Jan 04, 2022 at 10:41:39AM +0000, cgel.zte at gmail.com wrote:
> From: Minghao Chi <chi.minghao at zte.com.cn>
> 
> Return value from regmap_update_bits() directly instead
> of taking this in another redundant variable.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/6b7349d2/attachment.sig>

From andrew at lunn.ch  Tue Jan  4 07:02:45 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 4 Jan 2022 16:02:45 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRgXbpK6CFB/eCU@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
 <YdRZQl6U0y19P/0+@shell.armlinux.org.uk> <YdRdu3jFPnGd1DsH@lunn.ch>
 <YdRgXbpK6CFB/eCU@shell.armlinux.org.uk>
Message-ID: <YdRhlUR4ukwS5WMH@lunn.ch>

> > #define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
> > #define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
> > #define MII_88E1121_PHY_MSCR_DELAY_MASK	(BIT(5) | BIT(4))
> > 
> > Bits 6 is the MSB of the default MAC speed.
> > Bit 13 is the LSB of the default MAC speed. These two should default to 10b = 1000Mbps
> > Bit 12 is reserved, and should be written 1.
> 
> Hmm, seems odd that these speed bits match BMCR, and I'm not sure why
> the default MAC speed would have any bearing on whether gigabit mode
> is enabled. If they default to 10b, then the write should have no effect
> unless boot firmware has changed them.

There is a bit more, which is did not copy:

    Also, used for setting speed of MAC interface during MAC side
    loop-back. Requires that customer set both these bits and force
    speed using register 0 to the same speed.  MAC Interface Speed
    during Link down.

So i don't think they matter during normal operation.

   Andrew


From robh at kernel.org  Tue Jan  4 07:03:54 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:03:54 -0600
Subject: [PATCH 2/8] dt-bindings: nvmem: add transformation bindings
In-Reply-To: <20211228142549.1275412-3-michael@walle.cc>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-3-michael@walle.cc>
Message-ID: <YdRh2lp5Ca08gHtR@robh.at.kernel.org>

On Tue, Dec 28, 2021 at 03:25:43PM +0100, Michael Walle wrote:
> Just add a simple list of the supported devices which need a nvmem
> transformations.
> 
> Also, since the compatible string is prepended to the actual nvmem
> compatible string, we need to match using "contains" instead of an exact
> match.
> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
>  .../devicetree/bindings/mtd/mtd.yaml          |  7 +--
>  .../bindings/nvmem/nvmem-transformations.yaml | 46 +++++++++++++++++++
>  2 files changed, 50 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml b/Documentation/devicetree/bindings/mtd/mtd.yaml
> index 376b679cfc70..0291e439b6a6 100644
> --- a/Documentation/devicetree/bindings/mtd/mtd.yaml
> +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml
> @@ -33,9 +33,10 @@ patternProperties:
>  
>      properties:
>        compatible:
> -        enum:
> -          - user-otp
> -          - factory-otp
> +        contains:
> +          enum:
> +            - user-otp
> +            - factory-otp

If the addition is only compatible strings, then I would just add them 
here. Otherwise this needs to be structured a bit differently. More on 
that below.

>  
>      required:
>        - compatible
> diff --git a/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> new file mode 100644
> index 000000000000..8c8d85fd6d27
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> @@ -0,0 +1,46 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/nvmem/nvmem-transformations.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NVMEM transformations Device Tree Bindings
> +
> +maintainers:
> +  - Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> +
> +description: |
> +  This is a list NVMEM devices which need transformations.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +        - enum:
> +          - kontron,sl28-vpd
> +        - const: user-otp
> +      - const: user-otp

This will be applied to any node containing 'user-otp'. You need a 
custom 'select' to avoid that.

> +
> +required:
> +  - compatible
> +
> +additionalProperties: true

True is only allowed for common schema intended to be included (i.e. a 
$ref) by other schemas. IOW, ones that are incomplete on their own. So 
you need to reference mtd.yaml and make this 'unevaluatedProperties: false'.

> +
> +examples:
> +  - |
> +    otp-1 {
> +            compatible = "kontron,sl28-vpd", "user-otp";
> +            #address-cells = <1>;
> +            #size-cells = <1>;
> +
> +            serial at 2 {
> +                    reg = <2 15>;
> +            };
> +
> +            base_mac_address: base-mac-address at 17 {
> +                    #nvmem-cell-cells = <1>;
> +                    reg = <17 6>;
> +            };
> +    };
> +
> +...
> -- 
> 2.30.2
> 
> 


From clabbe.montjoie at gmail.com  Tue Jan  4 07:04:12 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 16:04:12 +0100
Subject: net: phy: marvell: network working with generic PHY and not with
 marvell PHY
In-Reply-To: <YdRZQl6U0y19P/0+@shell.armlinux.org.uk>
References: <YdQoOSXS98+Af1wO@Red> <YdQsJnfqjaFrtC0m@shell.armlinux.org.uk>
 <YdQwexJVfrdzEfZK@Red> <YdQydK4GhI0P5RYL@shell.armlinux.org.uk>
 <YdQ5i+//UITSbxS/@shell.armlinux.org.uk> <YdRVovG9mgEWffkn@Red>
 <YdRZQl6U0y19P/0+@shell.armlinux.org.uk>
Message-ID: <YdRh7Jq3WxkiJMbs@Red>

Le Tue, Jan 04, 2022 at 02:27:14PM +0000, Russell King (Oracle) a ?crit :
> On Tue, Jan 04, 2022 at 03:11:46PM +0100, Corentin Labbe wrote:
> > Le Tue, Jan 04, 2022 at 12:11:55PM +0000, Russell King (Oracle) a ?crit :
> > > On Tue, Jan 04, 2022 at 11:41:40AM +0000, Russell King (Oracle) wrote:
> > > > On Tue, Jan 04, 2022 at 12:33:15PM +0100, Corentin Labbe wrote:
> > > > > Le Tue, Jan 04, 2022 at 11:14:46AM +0000, Russell King (Oracle) a ?crit :
> > > > > > On Tue, Jan 04, 2022 at 11:58:01AM +0100, Corentin Labbe wrote:
> > > > > > > Hello
> > > > > > > 
> > > > > > > I have a gemini SSI 1328 box which has a cortina ethernet MAC with a Marvell 88E1118 as given by:
> > > > > > > Marvell 88E1118 gpio-0:01: attached PHY driver (mii_bus:phy_addr=gpio-0:01, irq=POLL)
> > > > > > > So booting with CONFIG_MARVELL_PHY=y lead to a non-working network with link set at 1Gbit
> > > > > > > Setting 'max-speed = <100>;' (as current state in mainline dtb) lead to a working network.
> > > > > > > By not working, I mean kernel started with ip=dhcp cannot get an IP.
> > > > > > 
> > > > > > How is the PHY connected to the host (which interface mode?) If it's
> > > > > > RGMII, it could be that the wrong RGMII interface mode is specified in
> > > > > > DT.
> > > > > > 
> > > > > 
> > > > > The PHY is set as RGMII in DT (arch/arm/boot/dts/gemini-ssi1328.dts)
> > > > > The only change to the mainline dtb is removing the max-speed.
> > > > 
> > > > So, it's using "rgmii" with no delay configured at the PHY with the
> > > > speed limited to 100Mbps. You then remove the speed limitation and
> > > > it doesn't work at 1Gbps.
> > > > 
> > > > I think I've seen this on other platforms (imx6 + ar8035) when the
> > > > RGMII delay is not correctly configured - it will work at slower
> > > > speeds but not 1G.
> > > > 
> > > > The RGMII spec specifies that there will be a delay - and the delay can
> > > > be introduced by either the MAC, PHY or by PCB track routing. It sounds
> > > > to me like your boot environment configures the PHY to introduce the
> > > > necessary delay, but then, because the DT "rgmii" mode means "no delay
> > > > at the PHY" when you use the Marvell driver (which respects that), the
> > > > Marvell driver configures the PHY for no delay, resulting in a non-
> > > > working situation at 1G.
> > > > 
> > > > I would suggest checking how the boot environment configures the PHY,
> > > > and change the "rgmii" mode in DT to match. There is a description of
> > > > the four RGMII modes in Documentation/networking/phy.rst that may help
> > > > understand what each one means.
> > > 
> > > Hmm. Sorry, I'm leading you stray. It looks like the 88E1118 code does
> > > not program any delays depending on the interface mode, so changing that
> > > will have no effect.
> > > 
> > > I suspect, looking at m88e1118_config_init(), that the write to register
> > > 0x15 in the MSCR page could be the problem.
> > > 
> > > 0x15 is 21, which is MII_88E1121_PHY_MSCR_REG. In other Marvell PHYs,
> > > bits 4 and 5 are the tx and rx delays, both of which are set. Looking
> > > at m88e1121_config_aneg_rgmii_delays(), this would seem to indicate
> > > that the PHY is being placed into rgmii-id mode.
> > > 
> > > Can you try changing:
> > > 
> > > 	err = phy_write(phydev, 0x15, 0x1070);
> > > 
> > > to:
> > > 
> > > 	err = phy_write(phydev, 0x15, 0x1040);
> > > 
> > > and see what happens? Maybe trying other combinations of bits 4 and 5
> > > to find a working combination.
> > > 
> > 
> > Forget my other message, using 0x1040 lead to success.
> > My problem was that I tried rgmii-id which net/ethernet/cortina does not support on some code path. (everything test PHY_INTERFACE_MODE_RGMII only)
> > So I retry tests with original phy-mode = "rgmii".
> > 
> > So with the following changes everything is ok:
> > diff --git a/arch/arm/boot/dts/gemini-ssi1328.dts b/arch/arm/boot/dts/gemini-ssi1328.dts
> > index 113feb1c4922..7543d117a13a 100644
> > --- a/arch/arm/boot/dts/gemini-ssi1328.dts
> > +++ b/arch/arm/boot/dts/gemini-ssi1328.dts
> > @@ -40,10 +40,6 @@ mdio0: mdio {
> >                 phy0: ethernet-phy at 1 {
> >                         reg = <1>;
> >                         device_type = "ethernet-phy";
> > -                       /* We lack the knowledge of necessary GPIO to achieve
> > -                        * Gigabit
> > -                        */
> > -                       max-speed = <100>;
> >                 };
> >                 /* WAN ICPlus IP101A */
> >                 phy1: ethernet-phy at 2 {
> > diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> > index 4fcfca4e1702..af7fc9d8eaa7 100644
> > --- a/drivers/net/phy/marvell.c
> > +++ b/drivers/net/phy/marvell.c
> > @@ -1233,7 +1233,7 @@ static int m88e1118_config_init(struct phy_device *phydev)
> >                 return err;
> >  
> >         /* Enable 1000 Mbit */
> > -       err = phy_write(phydev, 0x15, 0x1070);
> > +       err = phy_write(phydev, 0x15, 0x1040);
> >         if (err < 0)
> >                 return err;
> >  
> 
> Okay, so we have two things that need fixing:
> 
> 1) We need m88e1118_config_init() to take note of the interface mode
> if it's RGMII, and program MSCR appropriately.
> 
> 2) We need drivers/net/ethernet/cortina/gemini.c to accept any RGMII
> interface mode.
> 
> Here's an untested patch for both - I've also converted the MSCR write
> to be more modern. Please let me know if this resolves your issue.
> We then need to consider whether it breaks any existing platform.

Patch works for me.
Furthermore, I have an other board with the same issue (but with a Realtek PHY).
But in that case, it was just a missing rgmii-id (and your ethernet/cortina/gemini change).

Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Tested-on: gemini-ssi1328
Tested-on: gemini-ns2502

I wait for patch to be sent before sending DTB changes on my side.

Thanks for your help

> 
> diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
> index 07add311f65d..c78b99a497df 100644
> --- a/drivers/net/ethernet/cortina/gemini.c
> +++ b/drivers/net/ethernet/cortina/gemini.c
> @@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
>  	switch (phydev->speed) {
>  	case 1000:
>  		status.bits.speed = GMAC_SPEED_1000;
> -		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
> +		if (phy_interface_mode_is_rgmii(phydev->interface))
>  			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
>  		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
>  			   phydev_name(phydev));
>  		break;
>  	case 100:
>  		status.bits.speed = GMAC_SPEED_100;
> -		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
> +		if (phy_interface_mode_is_rgmii(phydev->interface))
>  			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
>  		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
>  			   phydev_name(phydev));
>  		break;
>  	case 10:
>  		status.bits.speed = GMAC_SPEED_10;
> -		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
> +		if (phy_interface_mode_is_rgmii(phydev->interface))
>  			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
>  		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
>  			   phydev_name(phydev));
> @@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
>  		status.bits.mii_rmii = GMAC_PHY_GMII;
>  		break;
>  	case PHY_INTERFACE_MODE_RGMII:
> +	case PHY_INTERFACE_MODE_RGMII_ID:
> +	case PHY_INTERFACE_MODE_RGMII_TXID:
> +	case PHY_INTERFACE_MODE_RGMII_RXID:
>  		netdev_dbg(netdev,
>  			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
>  		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index 4fcfca4e1702..ccf142ce55d8 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -1227,16 +1227,18 @@ static int m88e1118_config_init(struct phy_device *phydev)
>  {
>  	int err;
>  
> -	/* Change address */
> -	err = marvell_set_page(phydev, MII_MARVELL_MSCR_PAGE);
> -	if (err < 0)
> -		return err;
> -
>  	/* Enable 1000 Mbit */
> -	err = phy_write(phydev, 0x15, 0x1070);
> +	err = phy_write_paged(phydev, MII_MARVELL_MSCR_PAGE,
> +			      MII_88E1121_PHY_MSCR_REG, 0x1070);
>  	if (err < 0)
>  		return err;
>  
> +	if (phy_interface_is_rgmii(phydev)) {
> +		err = m88e1121_config_aneg_rgmii_delays(phydev);
> +		if (err < 0)
> +			return err;
> +	}
> +
>  	/* Change address */
>  	err = marvell_set_page(phydev, MII_MARVELL_LED_PAGE);
>  	if (err < 0)
> 
> -- 
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From lorenzo.pieralisi at arm.com  Tue Jan  4 07:04:28 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Tue,  4 Jan 2022 15:04:28 +0000
Subject: [PATCH 00/15] pci: mvebu: Various fixes
In-Reply-To: <20211125124605.25915-1-pali@kernel.org>
References: <20211125124605.25915-1-pali@kernel.org>
Message-ID: <164130858682.16382.8296252945836815553.b4-ty@arm.com>

On Thu, 25 Nov 2021 13:45:50 +0100, Pali Roh?r wrote:
> This patch series contains various fixes for pci-mvebu.c driver. Only
> bugfixes, no new features.
> 
> For pci-mvebu.c I have prepared another 30+ patches with cleanups and
> new features, they are currently available in my git branch:
> https://git.kernel.org/pub/scm/linux/kernel/git/pali/linux.git/log/?h=pci-mvebu
> 
> [...]

Dropped stable tags and applied on top of my pci/mvebu branch (please
check I rebased commits correctly), thanks!

[01/15] PCI: mvebu: Check for valid ports
        https://git.kernel.org/lpieralisi/pci/c/8cdabfdd5a
[02/15] PCI: mvebu: Check for errors from pci_bridge_emul_init() call
        https://git.kernel.org/lpieralisi/pci/c/5d18d702e5
[03/15] PCI: mvebu: Check that PCI bridge specified in DT has function number zero
        https://git.kernel.org/lpieralisi/pci/c/489bfc5187
[04/15] PCI: mvebu: Handle invalid size of read config request
        https://git.kernel.org/lpieralisi/pci/c/11c2bf4a20
[05/15] PCI: mvebu: Disallow mapping interrupts on emulated bridges
        https://git.kernel.org/lpieralisi/pci/c/319e6046bd
[06/15] PCI: mvebu: Fix support for bus mastering and PCI_COMMAND on emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/e42b855837
[07/15] PCI: mvebu: Do not modify PCI IO type bits in conf_write
        https://git.kernel.org/lpieralisi/pci/c/2cf150216e
[08/15] PCI: mvebu: Propagate errors when updating PCI_IO_BASE and PCI_MEM_BASE registers
        https://git.kernel.org/lpieralisi/pci/c/e7a0187672
[09/15] PCI: mvebu: Setup PCIe controller to Root Complex mode
        https://git.kernel.org/lpieralisi/pci/c/df08ac0161
[10/15] PCI: mvebu: Set PCI Bridge Class Code to PCI Bridge
        https://git.kernel.org/lpieralisi/pci/c/f587775828
[11/15] PCI: mvebu: Fix configuring secondary bus of PCIe Root Port via emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/91a8d79fc7
[12/15] PCI: mvebu: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/d75404cc08
[13/15] PCI: mvebu: Fix support for PCI_EXP_DEVCTL on emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/ecae073e39
[14/15] PCI: mvebu: Fix support for PCI_EXP_RTSTA on emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/838ff44a39
[15/15] PCI: mvebu: Fix support for DEVCAP2, DEVCTL2 and LNKCTL2 registers on emulated bridge
        https://git.kernel.org/lpieralisi/pci/c/4ab34548c5

Thanks,
Lorenzo


From prabhakar.csengg at gmail.com  Tue Jan  4 07:05:12 2022
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Tue, 4 Jan 2022 15:05:12 +0000
Subject: [PATCH v4] soc: ti: smartreflex: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <CAHp75Vcx1Ey-SHBCgBh1RM=PTBRcncGOwAx9_6PL+sDJtzezvw@mail.gmail.com>
References: <20220104134512.18498-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CAHp75Vcx1Ey-SHBCgBh1RM=PTBRcncGOwAx9_6PL+sDJtzezvw@mail.gmail.com>
Message-ID: <CA+V-a8uduHrVr4HWAgPt3YP_g27xhi4FdsrANn9S5mY0TBSvbg@mail.gmail.com>

On Tue, Jan 4, 2022 at 2:50 PM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Tue, Jan 4, 2022 at 3:45 PM Lad Prabhakar
> <prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
> >
> > platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> > allocation of IRQ resources in DT core code, this causes an issue
> > when using hierarchical interrupt domains using "interrupts" property
> > in the node as this bypasses the hierarchical setup and messes up the
> > irq chaining.
> >
> > In preparation for removal of static setup of IRQ resource from DT core
> > code use platform_get_irq_optional().
> >
> > While at it return 0 instead of returning ret in the probe success path.
>
> ...
>
> > +       ret = platform_get_irq_optional(pdev, 0);
> > +       if (ret < 0 && ret != -ENXIO) {
>
> > +               dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);
> > +               return ret;
>
> return dev_err_probe(...); ?
>
Argh my bad.

Cheers,
Prabhakar


From will at kernel.org  Tue Jan  4 07:11:23 2022
From: will at kernel.org (Will Deacon)
Date: Tue, 4 Jan 2022 15:11:23 +0000
Subject: [PATCH -next] perf/marvell_cn10k_tad_pmu: Fix return value check
 in tad_pmu_probe()
In-Reply-To: <20211221112252.306558-1-yangyingliang@huawei.com>
References: <20211221112252.306558-1-yangyingliang@huawei.com>
Message-ID: <20220104151123.GA2005@willie-the-truck>

On Tue, Dec 21, 2021 at 07:22:52PM +0800, Yang Yingliang wrote:
> In case of error, the function devm_ioremap() returns NULL
> pointer not ERR_PTR(). The IS_ERR() test in the return value
> check should be replaced with NULL test.
> 
> Fixes: 036a7584bede ("drivers: perf: Add LLC-TAD perf counter support")
> Reported-by: Hulk Robot <hulkci at huawei.com>
> Signed-off-by: Yang Yingliang <yangyingliang at huawei.com>
> ---
>  drivers/perf/marvell_cn10k_tad_pmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/perf/marvell_cn10k_tad_pmu.c b/drivers/perf/marvell_cn10k_tad_pmu.c
> index 250dd4c52d70..7f4d292658e3 100644
> --- a/drivers/perf/marvell_cn10k_tad_pmu.c
> +++ b/drivers/perf/marvell_cn10k_tad_pmu.c
> @@ -312,7 +312,7 @@ static int tad_pmu_probe(struct platform_device *pdev)
>  		regions[i].base = devm_ioremap(&pdev->dev,
>  					       res->start,
>  					       tad_pmu_page_size);
> -		if (IS_ERR(regions[i].base)) {
> +		if (!regions[i].base) {
>  			dev_err(&pdev->dev, "TAD%d ioremap fail\n", i);
>  			return -ENOMEM;

Thanks, but Dan already caught this:

https://lore.kernel.org/r/20211217145907.GA16611 at kili

I'll push out his fix soon.

Will


From andriy.shevchenko at linux.intel.com  Tue Jan  4 07:19:40 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue,  4 Jan 2022 17:19:40 +0200
Subject: [PATCH v2 1/1] KVM: arm64: vgic: Replace kernel.h with the necessary
 inclusions
Message-ID: <20220104151940.55399-1-andriy.shevchenko@linux.intel.com>

The arm_vgic.h does not require all the stuff the kernel.h provides.
Replace kernel.h inclusion with the list of what is really being used.

Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
---
v2: updated commit message by dropping unrelated paragraph (Marc)
 include/kvm/arm_vgic.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index e602d848fc1a..bb30a6803d9f 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -5,9 +5,11 @@
 #ifndef __KVM_ARM_VGIC_H
 #define __KVM_ARM_VGIC_H
 
-#include <linux/kernel.h>
+#include <linux/bits.h>
 #include <linux/kvm.h>
 #include <linux/irqreturn.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/static_key.h>
 #include <linux/types.h>
-- 
2.34.1



From robh at kernel.org  Tue Jan  4 07:33:29 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:33:29 -0600
Subject: [PATCH 2/3] regulator: dt-bindings: maxim,max77802: Convert to
 dtschema
In-Reply-To: <20211228164305.35877-3-krzysztof.kozlowski@canonical.com>
References: <20211228164305.35877-1-krzysztof.kozlowski@canonical.com>
 <20211228164305.35877-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YdRoyQsABBGen54D@robh.at.kernel.org>

On Tue, Dec 28, 2021 at 05:43:04PM +0100, Krzysztof Kozlowski wrote:
> Convert the regulators of Maxim MAX77802 PMIC to DT schema format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/regulator/max77802.txt           | 111 ----------------
>  .../bindings/regulator/maxim,max77802.yaml    | 118 ++++++++++++++++++
>  2 files changed, 118 insertions(+), 111 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/regulator/max77802.txt
>  create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
> 
> diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt
> deleted file mode 100644
> index b82943d83677..000000000000
> --- a/Documentation/devicetree/bindings/regulator/max77802.txt
> +++ /dev/null
> @@ -1,111 +0,0 @@
> -Binding for Maxim MAX77802 regulators
> -
> -This is a part of device tree bindings of MAX77802 multi-function device.
> -More information can be found in bindings/mfd/max77802.txt file.
> -
> -The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO)
> -regulators that can be controlled over I2C.
> -
> -Following properties should be present in main device node of the MFD chip.
> -
> -Optional properties:
> -- inb1-supply:  The input supply for BUCK1
> -- inb2-supply:  The input supply for BUCK2
> -- inb3-supply:  The input supply for BUCK3
> -- inb4-supply:  The input supply for BUCK4
> -- inb5-supply:  The input supply for BUCK5
> -- inb6-supply:  The input supply for BUCK6
> -- inb7-supply:  The input supply for BUCK7
> -- inb8-supply:  The input supply for BUCK8
> -- inb9-supply:  The input supply for BUCK9
> -- inb10-supply: The input supply for BUCK10
> -- inl1-supply:  The input supply for LDO8 and LDO15
> -- inl2-supply:  The input supply for LDO17, LDO27, LDO30 and LDO35
> -- inl3-supply:  The input supply for LDO3, LDO5, LDO6 and LDO7
> -- inl4-supply:  The input supply for LDO10, LDO11, LDO13 and LDO14
> -- inl5-supply:  The input supply for LDO9 and LDO19
> -- inl6-supply:  The input supply for LDO4, LDO21, LDO24 and LDO33
> -- inl7-supply:  The input supply for LDO18, LDO20, LDO28 and LDO29
> -- inl9-supply:  The input supply for LDO12, LDO23, LDO25, LDO26, LDO32 and LDO34
> -- inl10-supply: The input supply for LDO1 and LDO2
> -
> -Optional nodes:
> -- regulators : The regulators of max77802 have to be instantiated
> -  under subnode named "regulators" using the following format.
> -
> -	regulator-name {
> -		standard regulator constraints....
> -	};
> -	refer Documentation/devicetree/bindings/regulator/regulator.txt
> -
> -The regulator node name should be initialized with a string to get matched
> -with their hardware counterparts as follow. The valid names are:
> -
> -	-LDOn 	:	for LDOs, where n can lie in ranges 1-15, 17-21, 23-30
> -			and 32-35.
> -			example: LDO1, LDO2, LDO35.
> -	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 10.
> -			example: BUCK1, BUCK5, BUCK10.
> -
> -The max77802 regulator supports two different operating modes: Normal and Low
> -Power Mode. Some regulators support the modes to be changed at startup or by
> -the consumers during normal operation while others only support to change the
> -mode during system suspend. The standard regulator suspend states binding can
> -be used to configure the regulator operating mode.
> -
> -The regulators that support the standard "regulator-initial-mode" property,
> -changing their mode during normal operation are: LDOs 1, 3, 20 and 21.
> -
> -The possible values for "regulator-initial-mode" and "regulator-mode" are:
> -	1: Normal regulator voltage output mode.
> -	3: Low Power which reduces the quiescent current down to only 1uA
> -
> -The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
> -header and can be included by device tree source files.
> -
> -The standard "regulator-mode" property can only be used for regulators that
> -support changing their mode to Low Power Mode during suspend. These regulators
> -are: BUCKs 2-4 and LDOs 1-35. Also, it only takes effect if the regulator has
> -been enabled for the given suspend state using "regulator-on-in-suspend" and
> -has not been disabled for that state using "regulator-off-in-suspend".
> -
> -Example:
> -
> -	max77802 at 9 {
> -		compatible = "maxim,max77802";
> -		interrupt-parent = <&wakeup_eint>;
> -		interrupts = <26 0>;
> -		reg = <0x09>;
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -
> -		inb1-supply = <&parent_reg>;
> -
> -		regulators {
> -			ldo1_reg: LDO1 {
> -				regulator-name = "vdd_1v0";
> -				regulator-min-microvolt = <1000000>;
> -				regulator-max-microvolt = <1000000>;
> -				regulator-always-on;
> -				regulator-initial-mode = <MAX77802_OPMODE_LP>;
> -			};
> -
> -			ldo11_reg: LDO11 {
> -				regulator-name = "vdd_ldo11";
> -				regulator-min-microvolt = <1900000>;
> -				regulator-max-microvolt = <1900000>;
> -				regulator-always-on;
> -				regulator-state-mem {
> -					regulator-on-in-suspend;
> -					regulator-mode = <MAX77802_OPMODE_LP>;
> -				};
> -			};
> -
> -			buck1_reg: BUCK1 {
> -				regulator-name = "vdd_mif";
> -				regulator-min-microvolt = <950000>;
> -				regulator-max-microvolt = <1300000>;
> -				regulator-always-on;
> -				regulator-boot-on;
> -			};
> -	};
> diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
> new file mode 100644
> index 000000000000..01e1c40685ff
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
> @@ -0,0 +1,118 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/regulator/maxim,max77802.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX77802 Power Management IC regulators
> +
> +maintainers:
> +  - Javier Martinez Canillas <javier at dowhile0.org>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX77802 Power Management
> +  Integrated Circuit (PMIC).
> +
> +  The Maxim MAX77686 provides 10 high-efficiency Buck and 32 Low-DropOut (LDO)
> +  regulators.
> +
> +  See also Documentation/devicetree/bindings/mfd/maxim,max77802.yaml for
> +  additional information and example.
> +
> +  Certain regulators support "regulator-initial-mode" and "regulator-mode".
> +  The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
> +  and their meaning is:
> +    1 - Normal regulator voltage output mode.
> +    3 - Low Power which reduces the quiescent current down to only 1uA
> +
> +  The standard "regulator-mode" property can only be used for regulators that
> +  support changing their mode to Low Power Mode during suspend. These
> +  regulators are: bucks 2-4 and LDOs 1-35. Also, it only takes effect if the
> +  regulator has been enabled for the given suspend state using
> +  "regulator-on-in-suspend" and has not been disabled for that state using
> +  "regulator-off-in-suspend".
> +
> +patternProperties:
> +  # LDO1, LDO3, LDO20, LDO21
> +  "^LDO([13]|2[01])$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +    description:
> +      LDOs supporting the regulator-initial-mode property and changing their
> +      mode during normal operation.
> +
> +    properties:
> +      regulator-initial-mode: true

Same issues here as the other series.

> +
> +    patternProperties:
> +      regulator-state-(standby|mem|disk):
> +        type: object
> +        properties:
> +          regulator-mode: true

Is this the only valid property? 

> +
> +    required:
> +      - regulator-name
> +
> +  # LDO2, LDO4-15, LDO17-19, LDO23-30, LDO32-35
> +  "^LDO([24-9]|1[0-5789]|2[3-9]|3[02345])$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +    description:
> +      LDOs supporting the regulator-mode property (changing mode to Low Power
> +      Mode during suspend).
> +
> +    properties:
> +      regulator-initial-mode: false
> +
> +    patternProperties:
> +      regulator-state-(standby|mem|disk):
> +        type: object
> +        properties:
> +          regulator-mode: true
> +
> +    required:
> +      - regulator-name
> +
> +  # buck2-4
> +  "^BUCK[2-4]$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +    description:
> +      bucks supporting the regulator-mode property (changing mode to Low Power
> +      Mode during suspend).
> +
> +    properties:
> +      regulator-initial-mode: false
> +
> +    patternProperties:
> +      regulator-state-(standby|mem|disk):
> +        type: object
> +        properties:
> +          regulator-mode: true
> +
> +    required:
> +      - regulator-name
> +
> +  # buck1, buck5-10
> +  "^BUCK([15-9]|10)$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +
> +    properties:
> +      regulator-initial-mode: false
> +
> +    patternProperties:
> +      regulator-state-(standby|mem|disk):
> +        type: object
> +        properties:
> +          regulator-mode: false
> +
> +    required:
> +      - regulator-name
> +
> +additionalProperties: false
> -- 
> 2.32.0
> 
> 


From jernej.skrabec at gmail.com  Tue Jan  4 07:34:51 2022
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Tue, 04 Jan 2022 16:34:51 +0100
Subject: [PATCH v4 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20220104073842.1791639-2-benjamin.gaignard@collabora.com>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
 <20220104073842.1791639-2-benjamin.gaignard@collabora.com>
Message-ID: <2610538.mvXUDI8C0e@kista>

Hi Benjamin!

Dne torek, 04. januar 2022 ob 08:38:41 CET je Benjamin Gaignard napisal(a):
> Marking a picture as long-term reference is valid for DPB but not for RPS.
> Change flag name to match with it description in HEVC spec chapiter
> "8.3.2 Decoding process for reference picture set".
> Remove the other unused RPS flags.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From robh at kernel.org  Tue Jan  4 07:35:31 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:35:31 -0600
Subject: [PATCH 3/3] dt-bindings: mfd: maxim, max77802: Convert to dtschema
In-Reply-To: <20211228164305.35877-4-krzysztof.kozlowski@canonical.com>
References: <20211228164305.35877-1-krzysztof.kozlowski@canonical.com>
 <20211228164305.35877-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YdRpQ2jIJ+vvg33q@robh.at.kernel.org>

On Tue, Dec 28, 2021 at 05:43:05PM +0100, Krzysztof Kozlowski wrote:
> Convert the MFD part of Maxim MAX77802 PMIC to DT schema format.  The
> example DTS was copied from existing DTS (exynos5800-peach-pi.dts), so
> keep the license as GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/mfd/max77802.txt      |  25 ---
>  .../bindings/mfd/maxim,max77802.yaml          | 194 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 195 insertions(+), 26 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mfd/max77802.txt
>  create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77802.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/max77802.txt b/Documentation/devicetree/bindings/mfd/max77802.txt
> deleted file mode 100644
> index 09decac20d91..000000000000
> --- a/Documentation/devicetree/bindings/mfd/max77802.txt
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -Maxim MAX77802 multi-function device
> -
> -The Maxim MAX77802 is a Power Management IC (PMIC) that contains 10 high
> -efficiency Buck regulators, 32 Low-DropOut (LDO) regulators used to power
> -up application processors and peripherals, a 2-channel 32kHz clock outputs,
> -a Real-Time-Clock (RTC) and a I2C interface to program the individual
> -regulators, clocks outputs and the RTC.
> -
> -Bindings for the built-in 32k clock generator block and
> -regulators are defined in ../clk/maxim,max77802.txt and
> -../regulator/max77802.txt respectively.
> -
> -Required properties:
> -- compatible		: Must be "maxim,max77802"
> -- reg			: Specifies the I2C slave address of PMIC block.
> -- interrupts		: I2C device IRQ line connected to the main SoC.
> -
> -Example:
> -
> -	max77802: pmic at 9 {
> -		compatible = "maxim,max77802";
> -		interrupt-parent = <&intc>;
> -		interrupts = <26 IRQ_TYPE_NONE>;
> -		reg = <0x09>;
> -	};
> diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml
> new file mode 100644
> index 000000000000..26f49fbace18
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/maxim,max77802.yaml
> @@ -0,0 +1,194 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/maxim,max77802.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX77802 Power Management IC
> +
> +maintainers:
> +  - Javier Martinez Canillas <javier at dowhile0.org>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX77802 Power Management
> +  Integrated Circuit (PMIC).
> +
> +  The Maxim MAX77802 is a Power Management IC which includes voltage and
> +  current regulators (10 high efficiency Buck regulators and 32 Low-DropOut
> +  (LDO)), RTC and clock outputs.
> +
> +  The MAX77802 provides two 32.768khz clock outputs that can be controlled
> +  (gated/ungated) over I2C.  The clock IDs are defined as preprocessor macros
> +  in dt-bindings/clock/maxim,max77802.h.
> +
> +properties:
> +  compatible:
> +    const: maxim,max77802
> +
> +  '#clock-cells':
> +    const: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +  regulators:
> +    $ref: ../regulator/maxim,max77802.yaml

Use absolute path: /schemas/regulator/...

With that,

Reviewed-by: Rob Herring <robh at kernel.org>


From pali at kernel.org  Tue Jan  4 07:35:22 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:22 +0100
Subject: [PATCH v2 04/11] PCI: pci-bridge-emul: Add support for new flag
 PCI_BRIDGE_EMUL_NO_IO_FORWARD
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-5-pali@kernel.org>

Like PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD, this new flag specifies that
emulated PCI bridge does not support forwarding of IO requests in given
range between primary and secondary buses. This flag should be used as
argument for pci_bridge_emul_init() for hardware setup without IO support.

Setting this flag cause that IO base and limit registers are read-only.

Signed-off-by: Pali Roh?r <pali at kernel.org>

---
Changes in v2:
* Add comment into code.
---
 drivers/pci/pci-bridge-emul.c | 9 +++++++++
 drivers/pci/pci-bridge-emul.h | 6 ++++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 432b1bec2e22..033bbeb99176 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -378,6 +378,15 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
 		bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
 	}
 
+	if (flags & PCI_BRIDGE_EMUL_NO_IO_FORWARD) {
+		bridge->pci_regs_behavior[PCI_COMMAND / 4].ro |= PCI_COMMAND_IO;
+		bridge->pci_regs_behavior[PCI_COMMAND / 4].rw &= ~PCI_COMMAND_IO;
+		bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro |= GENMASK(15, 0);
+		bridge->pci_regs_behavior[PCI_IO_BASE / 4].rw &= ~GENMASK(15, 0);
+		bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].ro = ~0;
+		bridge->pci_regs_behavior[PCI_IO_BASE_UPPER16 / 4].rw = 0;
+	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(pci_bridge_emul_init);
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 087b5fa01bcf..4953274cac18 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -125,6 +125,12 @@ enum {
 	 * requests between primary and secondary buses.
 	 */
 	PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD = BIT(0),
+
+	/*
+	 * PCI bridge does not support forwarding of IO requests between
+	 * primary and secondary buses.
+	 */
+	PCI_BRIDGE_EMUL_NO_IO_FORWARD = BIT(1),
 };
 
 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:19 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:19 +0100
Subject: [PATCH v2 01/11] =?UTF-8?q?MAINTAINERS:=20Add=20Pali=20Roh=C3=A1r?=
 =?UTF-8?q?=20as=20pci-mvebu.c=20maintainer?=
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-2-pali@kernel.org>

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>

---
I discussed with Thomas and he ask me for taking maintenance of pci-mvebu.c driver.
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2345ce8521..24527789d933 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14617,6 +14617,7 @@ F:	drivers/pci/controller/mobiveil/pcie-mobiveil*
 
 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
 M:	Thomas Petazzoni <thomas.petazzoni at bootlin.com>
+M:	Pali Roh?r <pali at kernel.org>
 L:	linux-pci at vger.kernel.org
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:24 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:24 +0100
Subject: [PATCH v2 06/11] PCI: mvebu: Remove duplicate nports assignment
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-7-pali@kernel.org>

Member pcie->nports is initialized to correct value before the previous
for-loop. There is not need to initialize it more times.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
---
 drivers/pci/controller/pci-mvebu.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 2e10ade660a1..016f709b3067 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -1337,8 +1337,6 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 		mvebu_pcie_set_local_bus_nr(port, 0);
 	}
 
-	pcie->nports = i;
-
 	bridge->sysdata = pcie;
 	bridge->ops = &mvebu_pcie_ops;
 	bridge->align_resource = mvebu_pcie_align_resource;
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:21 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:21 +0100
Subject: [PATCH v2 03/11] PCI: pci-bridge-emul: Rename
 PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR to PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-4-pali@kernel.org>

This flag describe whether PCI bridge supports forwarding of prefetchable
memory requests in given range between primary and secondary buses. It does
not specify if bridge has support for prefetchable memory BAR (moreover
this pci-bridge-emul.c driver does not provide support for BARs).

So change name of this flag to be less misleading and add comment.

Signed-off-by: Pali Roh?r <pali at kernel.org>

---
Changes in v2:
* Add comment into code.
---
 drivers/pci/controller/pci-mvebu.c | 2 +-
 drivers/pci/pci-bridge-emul.c      | 2 +-
 drivers/pci/pci-bridge-emul.h      | 6 +++++-
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 2ecc1ab12249..2e10ade660a1 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -747,7 +747,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	bridge->data = port;
 	bridge->ops = &mvebu_pci_bridge_emul_ops;
 
-	return pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR);
+	return pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD);
 }
 
 static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 79b947528455..432b1bec2e22 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -373,7 +373,7 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
 			~(BIT(10) << 16);
 	}
 
-	if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) {
+	if (flags & PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD) {
 		bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].ro = ~0;
 		bridge->pci_regs_behavior[PCI_PREF_MEMORY_BASE / 4].rw = 0;
 	}
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 0690b6369755..087b5fa01bcf 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -120,7 +120,11 @@ struct pci_bridge_emul {
 };
 
 enum {
-	PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR = BIT(0),
+	/*
+	 * PCI bridge does not support forwarding of prefetchable memory
+	 * requests between primary and secondary buses.
+	 */
+	PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD = BIT(0),
 };
 
 int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:23 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:23 +0100
Subject: [PATCH v2 05/11] PCI: mvebu: Add help string for CONFIG_PCI_MVEBU
 option
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-6-pali@kernel.org>

There is no description for CONFIG_PCI_MVEBU option. Add it.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
---
 drivers/pci/controller/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 67189bcd5d89..534b446f2cf0 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -10,6 +10,10 @@ config PCI_MVEBU
 	depends on ARM
 	depends on OF
 	select PCI_BRIDGE_EMUL
+	help
+	 Add support for Marvell EBU PCIe controller. This PCIe controller
+	 is used on 32-bit Marvell ARM SoCs: Dove, Kirkwood, Armada 370,
+	 Armada XP, Armada 375, Armada 38x and Armada 39x.
 
 config PCI_AARDVARK
 	tristate "Aardvark PCIe controller"
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:20 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:20 +0100
Subject: [PATCH v2 02/11] PCI: pci-bridge-emul: Make struct
 pci_bridge_emul_ops as const
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-3-pali@kernel.org>

It is read-only constant structure, so properly mark it with const keyword.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
---
 drivers/pci/controller/pci-aardvark.c | 2 +-
 drivers/pci/controller/pci-mvebu.c    | 2 +-
 drivers/pci/pci-bridge-emul.h         | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 62fc55f2ed40..1fa6fe1e022a 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -928,7 +928,7 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 	}
 }
 
-static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = {
+static const struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = {
 	.read_base = advk_pci_bridge_emul_base_conf_read,
 	.write_base = advk_pci_bridge_emul_base_conf_write,
 	.read_pcie = advk_pci_bridge_emul_pcie_conf_read,
diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 68aa94a258ff..2ecc1ab12249 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -709,7 +709,7 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 	}
 }
 
-static struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
+static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
 	.read_base = mvebu_pci_bridge_emul_base_conf_read,
 	.write_base = mvebu_pci_bridge_emul_base_conf_write,
 	.read_pcie = mvebu_pci_bridge_emul_pcie_conf_read,
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 49bbd37ee318..0690b6369755 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -112,7 +112,7 @@ struct pci_bridge_reg_behavior;
 struct pci_bridge_emul {
 	struct pci_bridge_emul_conf conf;
 	struct pci_bridge_emul_pcie_conf pcie_conf;
-	struct pci_bridge_emul_ops *ops;
+	const struct pci_bridge_emul_ops *ops;
 	struct pci_bridge_reg_behavior *pci_regs_behavior;
 	struct pci_bridge_reg_behavior *pcie_cap_regs_behavior;
 	void *data;
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:18 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:18 +0100
Subject: [PATCH v2 00/11] PCI: Small improvements for pci-bridge-emul and mvebu
In-Reply-To: <20211221141455.30011-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
Message-ID: <20220104153529.31647-1-pali@kernel.org>

This patch series contains small improvements for pci-bridge-emul and
mvebu drivers. This patch series is based on top of the patches:
https://lore.kernel.org/linux-pci/20211125124605.25915-1-pali at kernel.org/
(which are now in pci/mvebu branch)

In V2 was added comment into code explaining PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
and PCI_BRIDGE_EMUL_NO_IO_FORWARD flags.

Pali Roh?r (11):
  MAINTAINERS: Add Pali Roh?r as pci-mvebu.c maintainer
  PCI: pci-bridge-emul: Make struct pci_bridge_emul_ops as const
  PCI: pci-bridge-emul: Rename PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR to
    PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
  PCI: pci-bridge-emul: Add support for new flag
    PCI_BRIDGE_EMUL_NO_IO_FORWARD
  PCI: mvebu: Add help string for CONFIG_PCI_MVEBU option
  PCI: mvebu: Remove duplicate nports assignment
  PCI: mvebu: Set PCI_BRIDGE_EMUL_NO_IO_FORWARD when IO is unsupported
  PCI: mvebu: Properly initialize vendor, device and revision of
    emulated bridge
  PCI: mvebu: Update comment for PCI_EXP_LNKCAP register on emulated
    bridge
  PCI: mvebu: Update comment for PCI_EXP_LNKCTL register on emulated
    bridge
  PCI: mvebu: Fix reporting Data Link Layer Link Active on emulated
    bridge

 MAINTAINERS                           |  1 +
 drivers/pci/controller/Kconfig        |  4 ++
 drivers/pci/controller/pci-aardvark.c |  2 +-
 drivers/pci/controller/pci-mvebu.c    | 64 ++++++++++++---------------
 drivers/pci/pci-bridge-emul.c         | 11 ++++-
 drivers/pci/pci-bridge-emul.h         | 14 +++++-
 6 files changed, 57 insertions(+), 39 deletions(-)

-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:25 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:25 +0100
Subject: [PATCH v2 07/11] PCI: mvebu: Set PCI_BRIDGE_EMUL_NO_IO_FORWARD when
 IO is unsupported
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-8-pali@kernel.org>

This will make PCI bridge to return zeros when accessing IO base and limit
registers, as required by PCIe base specification.

This allows to remove adhoc checks around mvebu_pcie_handle_iobase_change()
function for unsupported IO ranges. PCI_BRIDGE_EMUL_NO_IO_FORWARD ensures
that there will be no non-zeros write to IO registers when IO is not
supported.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 29 ++++++++++-------------------
 1 file changed, 10 insertions(+), 19 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 016f709b3067..551f55af5226 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -438,12 +438,6 @@ static int mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
 		return mvebu_pcie_set_window(port, port->io_target, port->io_attr,
 					     &desired, &port->iowin);
 
-	if (!mvebu_has_ioport(port)) {
-		dev_WARN(&port->pcie->pdev->dev,
-			 "Attempt to set IO when IO is disabled\n");
-		return -EOPNOTSUPP;
-	}
-
 	/*
 	 * We read the PCI-to-PCI bridge emulated registers, and
 	 * calculate the base address and size of the address decoding
@@ -599,24 +593,18 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 
 	switch (reg) {
 	case PCI_COMMAND:
-		if (!mvebu_has_ioport(port)) {
-			conf->command = cpu_to_le16(
-				le16_to_cpu(conf->command) & ~PCI_COMMAND_IO);
-			new &= ~PCI_COMMAND_IO;
-		}
-
 		mvebu_writel(port, new, PCIE_CMD_OFF);
 		break;
 
 	case PCI_IO_BASE:
-		if ((mask & 0xffff) && mvebu_pcie_handle_iobase_change(port)) {
+		if ((mask & 0xffff) && mvebu_has_ioport(port) &&
+		    mvebu_pcie_handle_iobase_change(port)) {
 			/* On error disable IO range */
 			conf->iobase &= ~0xf0;
 			conf->iolimit &= ~0xf0;
+			conf->iobase |= 0xf0;
 			conf->iobaseupper = cpu_to_le16(0x0000);
 			conf->iolimitupper = cpu_to_le16(0x0000);
-			if (mvebu_has_ioport(port))
-				conf->iobase |= 0xf0;
 		}
 		break;
 
@@ -630,14 +618,14 @@ mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 		break;
 
 	case PCI_IO_BASE_UPPER16:
-		if (mvebu_pcie_handle_iobase_change(port)) {
+		if (mvebu_has_ioport(port) &&
+		    mvebu_pcie_handle_iobase_change(port)) {
 			/* On error disable IO range */
 			conf->iobase &= ~0xf0;
 			conf->iolimit &= ~0xf0;
+			conf->iobase |= 0xf0;
 			conf->iobaseupper = cpu_to_le16(0x0000);
 			conf->iolimitupper = cpu_to_le16(0x0000);
-			if (mvebu_has_ioport(port))
-				conf->iobase |= 0xf0;
 		}
 		break;
 
@@ -722,6 +710,7 @@ static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
  */
 static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 {
+	unsigned int bridge_flags = PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD;
 	struct pci_bridge_emul *bridge = &port->bridge;
 	u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
 	u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
@@ -735,6 +724,8 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 		/* We support 32 bits I/O addressing */
 		bridge->conf.iobase = PCI_IO_RANGE_TYPE_32;
 		bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32;
+	} else {
+		bridge_flags |= PCI_BRIDGE_EMUL_NO_IO_FORWARD;
 	}
 
 	/*
@@ -747,7 +738,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	bridge->data = port;
 	bridge->ops = &mvebu_pci_bridge_emul_ops;
 
-	return pci_bridge_emul_init(bridge, PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD);
+	return pci_bridge_emul_init(bridge, bridge_flags);
 }
 
 static inline struct mvebu_pcie *sys_to_pcie(struct pci_sys_data *sys)
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:27 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:27 +0100
Subject: [PATCH v2 09/11] PCI: mvebu: Update comment for PCI_EXP_LNKCAP
 register on emulated bridge
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-10-pali@kernel.org>

Reason for clearing this bit is because mvebu hw returns incorrectly this bit set to 1.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 94ef00b6d697..1aac65977b97 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -546,8 +546,8 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 
 	case PCI_EXP_LNKCAP:
 		/*
-		 * PCIe requires the clock power management capability to be
-		 * hard-wired to zero for downstream ports
+		 * PCIe requires that the Clock Power Management capability bit
+		 * is hard-wired to zero for downstream ports but HW returns 1.
 		 */
 		*value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP) &
 			 ~PCI_EXP_LNKCAP_CLKPM;
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:26 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:26 +0100
Subject: [PATCH v2 08/11] PCI: mvebu: Properly initialize vendor,
 device and revision of emulated bridge
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-9-pali@kernel.org>

With this change also PCI vendor id is read from mvebu registers.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 551f55af5226..94ef00b6d697 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -712,13 +712,14 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 {
 	unsigned int bridge_flags = PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD;
 	struct pci_bridge_emul *bridge = &port->bridge;
+	u32 dev_id = mvebu_readl(port, PCIE_DEV_ID_OFF);
+	u32 dev_rev = mvebu_readl(port, PCIE_DEV_REV_OFF);
 	u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
 	u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
 
-	bridge->conf.vendor = PCI_VENDOR_ID_MARVELL;
-	bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16;
-	bridge->conf.class_revision =
-		mvebu_readl(port, PCIE_DEV_REV_OFF) & 0xff;
+	bridge->conf.vendor = cpu_to_le16(dev_id & 0xffff);
+	bridge->conf.device = cpu_to_le16(dev_id >> 16);
+	bridge->conf.class_revision = cpu_to_le32(dev_rev & 0xff);
 
 	if (mvebu_has_ioport(port)) {
 		/* We support 32 bits I/O addressing */
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:29 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:29 +0100
Subject: [PATCH v2 11/11] PCI: mvebu: Fix reporting Data Link Layer Link
 Active on emulated bridge
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-12-pali@kernel.org>

Add support for reporting PCI_EXP_LNKSTA_DLLLA bit in Link Control register
on emulated bridge via PCIE_STAT_OFF reg. Function mvebu_pcie_link_up()
already parses this register and returns if Data Link is Active or not.

Also correctly indicate DLLLA capability via PCI_EXP_LNKCAP_DLLLARC bit in
Link Control Capability register which is required for reporting DLLLA bit.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index dffa330de174..a075ba26cff1 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -548,13 +548,18 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 		/*
 		 * PCIe requires that the Clock Power Management capability bit
 		 * is hard-wired to zero for downstream ports but HW returns 1.
+		 * Additionally enable Data Link Layer Link Active Reporting
+		 * Capable bit as DL_Active indication is provided too.
 		 */
-		*value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP) &
-			 ~PCI_EXP_LNKCAP_CLKPM;
+		*value = (mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP) &
+			  ~PCI_EXP_LNKCAP_CLKPM) | PCI_EXP_LNKCAP_DLLLARC;
 		break;
 
 	case PCI_EXP_LNKCTL:
-		*value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL);
+		/* DL_Active indication is provided via PCIE_STAT_OFF */
+		*value = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL) |
+			 (mvebu_pcie_link_up(port) ?
+			  (PCI_EXP_LNKSTA_DLLLA << 16) : 0);
 		break;
 
 	case PCI_EXP_SLTCTL:
-- 
2.20.1



From pali at kernel.org  Tue Jan  4 07:35:28 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Tue,  4 Jan 2022 16:35:28 +0100
Subject: [PATCH v2 10/11] PCI: mvebu: Update comment for PCI_EXP_LNKCTL
 register on emulated bridge
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220104153529.31647-11-pali@kernel.org>

Logic and code for clearing PCI_EXP_LNKCTL_CLKREQ_EN bit is correct, but
comment describing it is misleading. PCI_EXP_LNKCTL_CLKREQ_EN bit should be
hardwired to zero but mvebu hw allows to change it.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 1aac65977b97..dffa330de174 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -663,10 +663,9 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 
 	case PCI_EXP_LNKCTL:
 		/*
-		 * If we don't support CLKREQ, we must ensure that the
-		 * CLKREQ enable bit always reads zero.  Since we haven't
-		 * had this capability, and it's dependent on board wiring,
-		 * disable it for the time being.
+		 * PCIe requires that the Enable Clock Power Management bit
+		 * is hard-wired to zero for downstream ports but HW allows
+		 * to change it.
 		 */
 		new &= ~PCI_EXP_LNKCTL_CLKREQ_EN;
 
-- 
2.20.1



From robh at kernel.org  Tue Jan  4 07:42:32 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:42:32 -0600
Subject: [PATCH 2/5] dt-bindings: extcon: maxim,max77843: add MAX77843
 bindings
In-Reply-To: <20211229124631.21576-3-krzysztof.kozlowski@canonical.com>
References: <20211229124631.21576-1-krzysztof.kozlowski@canonical.com>
 <20211229124631.21576-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YdRq6JVeeOVJj8ww@robh.at.kernel.org>

On Wed, Dec 29, 2021 at 01:46:28PM +0100, Krzysztof Kozlowski wrote:
> Document the bindings for MAX77843 MUIC/extcon driver, based on
> Exynos5433 TM2 devicetree.  These are neither accurate nor finished
> bindings but at least allow parsing existing DTS files.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/extcon/maxim,max77843.yaml       | 40 +++++++++++++++++++
>  1 file changed, 40 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
> 
> diff --git a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
> new file mode 100644
> index 000000000000..1f15a6c700f6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
> @@ -0,0 +1,40 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/extcon/maxim,max77843.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX77843 MicroUSB and Companion Power Management IC Extcon
> +
> +maintainers:
> +  - Chanwoo Choi <cw00.choi at samsung.com>
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX77843 MicroUSB
> +  Integrated Circuit (MUIC).
> +
> +  See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
> +  additional information and example.
> +
> +properties:
> +  compatible:
> +    const: maxim,max77843-muic
> +
> +  connector:
> +    $ref: ../connector/usb-connector.yaml#

/schemas/connector/...

With that,

Reviewed-by: Rob Herring <robh at kernel.org>

> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/port
> +    description:
> +      Any connector to the data bus of this controller should be modelled using
> +      the OF graph bindings specified
> +    properties:
> +      port:
> +        $ref: /schemas/graph.yaml#/properties/port
> +
> +required:
> +  - compatible
> +  - connector
> +
> +additionalProperties: false
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Jan  4 07:44:24 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:44:24 -0600
Subject: [PATCH 3/5] regulator: dt-bindings:  maxim,max77843: add
 MAX77843 bindings
In-Reply-To: <20211229124631.21576-4-krzysztof.kozlowski@canonical.com>
References: <20211229124631.21576-1-krzysztof.kozlowski@canonical.com>
 <20211229124631.21576-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YdRrWGry08M+h2IZ@robh.at.kernel.org>

On Wed, Dec 29, 2021 at 01:46:29PM +0100, Krzysztof Kozlowski wrote:
> Document the bindings for MAX77843 regulator driver.  The bindings are
> almost identical to MAX77693 bindings, except the actual names of
> regulators.

Same issues here as your other Maxim regulator conversions.

> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/regulator/maxim,max77843.yaml    | 55 +++++++++++++++++++
>  1 file changed, 55 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
> 
> diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
> new file mode 100644
> index 000000000000..1ab58c756d7c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
> @@ -0,0 +1,55 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/regulator/maxim,max77843.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX77843 MicroUSB and Companion Power Management IC regulators
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX77843 MicroUSB Integrated
> +  Circuit (MUIC).
> +
> +  See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
> +  additional information and example.
> +
> +properties:
> +  compatible:
> +    const: maxim,max77843-regulator
> +
> +patternProperties:
> +  "^SAFEOUT[12]$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +    description: |
> +      Safeout LDO regulator.
> +
> +    properties:
> +      regulator-min-microvolt: true
> +      regulator-max-microvolt: true
> +
> +    required:
> +      - regulator-name
> +
> +  "^CHARGER$":
> +    type: object
> +    $ref: regulator.yaml#
> +    unevaluatedProperties: false
> +    description: |
> +      Current regulator.
> +
> +    properties:
> +      regulator-min-microamp: true
> +      regulator-max-microamp: true
> +
> +    required:
> +      - regulator-name
> +
> +required:
> +  - compatible
> +
> +additionalProperties: false
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Jan  4 07:45:50 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 09:45:50 -0600
Subject: [PATCH 4/5] dt-bindings: mfd: maxim,max77843: add MAX77843
 bindings
In-Reply-To: <20211229124631.21576-5-krzysztof.kozlowski@canonical.com>
References: <20211229124631.21576-1-krzysztof.kozlowski@canonical.com>
 <20211229124631.21576-5-krzysztof.kozlowski@canonical.com>
Message-ID: <YdRrrsp1/UFYx5GN@robh.at.kernel.org>

On Wed, Dec 29, 2021 at 01:46:30PM +0100, Krzysztof Kozlowski wrote:
> Document the bindings for MAX77843 MFD driver, based on Exynos5433 TM2
> devicetree.  These are neither accurate nor finished bindings but at
> least allow parsing existing DTS files.
> 
> The example DTS was copied from existing DTS
> (exynos5433-tm2-common.dtsi), so keep the license as GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/mfd/maxim,max77843.yaml          | 144 ++++++++++++++++++
>  1 file changed, 144 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
> new file mode 100644
> index 000000000000..7f3d74f254af
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
> @@ -0,0 +1,144 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/maxim,max77843.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX77843 MicroUSB and Companion Power Management IC
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX77843 MicroUSB
> +  Integrated Circuit (MUIC).
> +
> +  The Maxim MAX77843 is a MicroUSB and Companion Power Management IC which
> +  includes voltage current regulators, charger, fuel-gauge, haptic motor driver
> +  and MicroUSB management IC.
> +
> +properties:
> +  compatible:
> +    const: maxim,max77843
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +  extcon:
> +    $ref: ../extcon/maxim,max77843.yaml

/schemas/extcon/...

> +
> +  motor-driver:
> +    type: object
> +    properties:
> +      compatible:
> +        const: maxim,max77843-haptic
> +
> +      haptic-supply:
> +        description: Power supply to the haptic motor
> +
> +      pwms:
> +        maxItems: 1
> +
> +    required:
> +      - compatible
> +      - haptic-supply
> +      - pwms
> +
> +  regulators:
> +    $ref: ../regulator/maxim,max77843.yaml

And here.

With that,

Reviewed-by: Rob Herring <robh at kernel.org>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:53:22 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:53:22 +0100
Subject: [PATCH v3 28/33] iommu/mediatek: Add bank_nr and bank_enable
In-Reply-To: <20210923115840.17813-29-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-29-yong.wu@mediatek.com>
Message-ID: <48493504-8877-b78d-0476-118a8b1441e0@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Prepare for supporting multi banks, Adds two variables in the plat_data:
> bank_nr: the bank number that this SoC support;
> bank_enable: list if the banks is enabled.
> 
> Add them for all the current SoC, bank_nr always is 1 and only
> bank_enable[0] is enabled.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 18 ++++++++++++++++++
>   drivers/iommu/mtk_iommu.h |  3 +++
>   2 files changed, 21 insertions(+)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index c139675d99e6..4ad85469f68f 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1134,6 +1134,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
>   			NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
>   	.hw_list      = &m4ulist,
>   	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
> +	.bank_nr      = 1,
> +	.bank_enable  = {true},
>   	.iova_region  = single_domain,
>   	.iova_region_nr = ARRAY_SIZE(single_domain),
>   	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}},
> @@ -1144,6 +1146,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
>   	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
>   			 NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
>   	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
> +	.bank_nr       = 1,
> +	.bank_enable   = {true},
>   	.iova_region   = single_domain,
>   	.iova_region_nr = ARRAY_SIZE(single_domain),
>   	.larbid_remap  = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}},
> @@ -1154,6 +1158,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
>   	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
>   			MTK_IOMMU_TYPE_MM,
>   	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
> +	.bank_nr      = 1,
> +	.bank_enable  = {true},
>   	.iova_region  = single_domain,
>   	.iova_region_nr = ARRAY_SIZE(single_domain),
>   	.larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */
> @@ -1165,6 +1171,8 @@ static const struct mtk_iommu_plat_data mt8173_data = {
>   			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
>   			MTK_IOMMU_TYPE_MM,
>   	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
> +	.bank_nr      = 1,
> +	.bank_enable  = {true},
>   	.iova_region  = single_domain,
>   	.iova_region_nr = ARRAY_SIZE(single_domain),
>   	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */
> @@ -1174,6 +1182,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
>   	.m4u_plat     = M4U_MT8183,
>   	.flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
>   	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
> +	.bank_nr      = 1,
> +	.bank_enable  = {true},
>   	.iova_region  = single_domain,
>   	.iova_region_nr = ARRAY_SIZE(single_domain),
>   	.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
> @@ -1185,6 +1195,8 @@ static const struct mtk_iommu_plat_data mt8192_data = {
>   			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
>   			  MTK_IOMMU_TYPE_MM,
>   	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
> +	.bank_nr        = 1,
> +	.bank_enable    = {true},
>   	.iova_region    = mt8192_multi_dom,
>   	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
>   	.larbid_remap   = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20},
> @@ -1196,6 +1208,8 @@ static const struct mtk_iommu_plat_data mt8195_data_infra = {
>   	.flags            = WR_THROT_EN | DCM_DISABLE |
>   			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIe_SUPPORT,
>   	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
> +	.bank_nr	  = 1,
> +	.bank_enable      = {true},
>   	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
>   	.iova_region      = single_domain,
>   	.iova_region_nr   = ARRAY_SIZE(single_domain),
> @@ -1208,6 +1222,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vdo = {
>   			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
>   	.hw_list        = &m4ulist,
>   	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
> +	.bank_nr	= 1,
> +	.bank_enable    = {true},
>   	.iova_region	= mt8192_multi_dom,
>   	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
>   	.larbid_remap   = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11},
> @@ -1221,6 +1237,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vpp = {
>   			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
>   	.hw_list        = &m4ulist,
>   	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
> +	.bank_nr	= 1,
> +	.bank_enable    = {true},
>   	.iova_region	= mt8192_multi_dom,
>   	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
>   	.larbid_remap   = {{1}, {3}, {22, 0, 0, 0, 23}, {8},
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> index 881fade8d39a..dc0190edebf0 100644
> --- a/drivers/iommu/mtk_iommu.h
> +++ b/drivers/iommu/mtk_iommu.h
> @@ -62,6 +62,9 @@ struct mtk_iommu_plat_data {
>   	struct list_head			*hw_list;
>   	unsigned int				iova_region_nr;
>   	const struct mtk_iommu_iova_region	*iova_region;
> +
> +	unsigned int        bank_nr;

As said in the review for patch 26/33, maybe this can be renamed as `num_banks`
instead... and also, this can be a `u8` to save some memory.

> +	bool                bank_enable[MTK_IOMMU_BANK_MAX];
>   	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
>   };
>   
> 



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:53:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:53:18 +0100
Subject: [PATCH v3 26/33] iommu/mediatek: Add mtk_iommu_bank_data structure
In-Reply-To: <20210923115840.17813-27-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-27-yong.wu@mediatek.com>
Message-ID: <5ac9dd6b-43cd-0f76-eb34-906ab84196c1@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Prepare for supporting multi-banks for the IOMMU HW, No functional change.
> 
> Add a new structure(mtk_iommu_bank_data) for each a bank. Each a bank have
> the independent HW base/IRQ/tlb-range ops, and each a bank has its special
> iommu-domain(independent pgtable), thus, also move the domain information
> into it.
> 
> In previous SoC, we have only one bank which could be treated as bank0(
> bankid always is 0 for the previous SoC).
> 
> After adding this structure, the tlb operations and irq could use
> bank_data as parameter.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 137 ++++++++++++++++++++++----------------
>   drivers/iommu/mtk_iommu.h |  24 ++++++-
>   2 files changed, 99 insertions(+), 62 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index ac31fe8b7aaf..6ef3eb3cad92 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -146,7 +146,7 @@ struct mtk_iommu_domain {
>   	struct io_pgtable_cfg		cfg;
>   	struct io_pgtable_ops		*iop;
>   
> -	struct mtk_iommu_data		*data;
> +	struct mtk_iommu_bank_data	*bank;
>   	struct iommu_domain		domain;
>   };
>   
> @@ -221,25 +221,29 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
>   
>   static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
>   {
> -	void __iomem *base = data->base;
> +	/* Tlb flush all always is in bank0. */
> +	struct mtk_iommu_bank_data *bank = &data->bank[0];
> +	void __iomem *base = bank->base;
>   	unsigned long flags;
>   
>   	/*
>   	 * No need get power status since the HW PM status nearly is active
>   	 * when entering here.
>   	 */
> -	spin_lock_irqsave(&data->tlb_lock, flags);
> +	spin_lock_irqsave(&bank->tlb_lock, flags);
>   	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + data->plat_data->inv_sel_reg);
>   	writel_relaxed(F_ALL_INVLD, base + REG_MMU_INVALIDATE);
>   	wmb(); /* Make sure the tlb flush all done */
> -	spin_unlock_irqrestore(&data->tlb_lock, flags);
> +	spin_unlock_irqrestore(&bank->tlb_lock, flags);
>   }
>   
>   static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
> -					   struct mtk_iommu_data *data)
> +					   struct mtk_iommu_bank_data *bank)
>   {
> -	struct list_head *head = data->hw_list;
> -	bool has_pm = !!data->dev->pm_domain;
> +	struct list_head *head = bank->pdata->hw_list;
> +	bool has_pm = !!bank->pdev->pm_domain;
> +	struct mtk_iommu_bank_data *curbank;
> +	struct mtk_iommu_data *data;
>   	unsigned long flags;
>   	void __iomem *base;
>   	int ret;
> @@ -251,9 +255,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
>   				continue;
>   		}
>   
> -		base = data->base;
> +		curbank = &data->bank[bank->id];
> +		base = curbank->base;
>   
> -		spin_lock_irqsave(&data->tlb_lock, flags);
> +		spin_lock_irqsave(&curbank->tlb_lock, flags);
>   		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>   			       base + data->plat_data->inv_sel_reg);
>   
> @@ -268,7 +273,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
>   
>   		/* Clear the CPE status */
>   		writel_relaxed(0, base + REG_MMU_CPE_DONE);
> -		spin_unlock_irqrestore(&data->tlb_lock, flags);
> +		spin_unlock_irqrestore(&curbank->tlb_lock, flags);
>   
>   		if (ret) {
>   			dev_warn(data->dev,
> @@ -283,12 +288,13 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
>   
>   static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
>   {
> -	struct mtk_iommu_data *data = dev_id;
> -	struct mtk_iommu_domain *dom = data->m4u_dom;
> +	struct mtk_iommu_bank_data *bank = dev_id;
> +	struct mtk_iommu_data *data = bank->pdata;
> +	struct mtk_iommu_domain *dom = bank->m4u_dom;
>   	unsigned int fault_larb = 0, fault_port = 0, sub_comm = 0;
>   	u32 int_state, regval, va34_32, pa34_32;
>   	const struct mtk_iommu_plat_data *plat_data = data->plat_data;
> -	void __iomem *base = data->base;
> +	void __iomem *base = bank->base;
>   	u64 fault_iova, fault_pa;
>   	bool layer, write;
>   
> @@ -327,10 +333,10 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
>   		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
>   	}
>   
> -	if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
> +	if (report_iommu_fault(&dom->domain, bank->pdev, fault_iova,
>   			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
>   		dev_err_ratelimited(
> -			data->dev,
> +			bank->pdev,
>   			"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
>   			int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
>   			layer, write ? "write" : "read");
> @@ -427,12 +433,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
>   				     unsigned int domid)
>   {
>   	const struct mtk_iommu_iova_region *region;
> -
> -	/* Use the exist domain as there is only one pgtable here. */
> -	if (data->m4u_dom) {
> -		dom->iop = data->m4u_dom->iop;
> -		dom->cfg = data->m4u_dom->cfg;
> -		dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap;
> +	struct mtk_iommu_domain	*m4u_dom;
> +
> +	/* Always use bank0 in sharing pgtable case */
> +	m4u_dom = data->bank[0].m4u_dom;
> +	if (m4u_dom) {
> +		dom->iop = m4u_dom->iop;
> +		dom->cfg = m4u_dom->cfg;
> +		dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap;
>   		goto update_iova_region;
>   	}
>   
> @@ -493,23 +501,26 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
>   	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
>   	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
>   	struct list_head *hw_list = data->hw_list;
> +	struct mtk_iommu_bank_data *bank;
>   	struct device *m4udev = data->dev;
> +	unsigned int bankid = 0;
>   	int ret, domid;
>   
>   	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
>   	if (domid < 0)
>   		return domid;
>   
> -	if (!dom->data) {
> +	bank = &data->bank[bankid];
> +	if (!dom->bank) {
>   		/* Data is in the frstdata in sharing pgtable case. */
>   		frstdata = mtk_iommu_get_frst_data(hw_list);
>   
>   		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
>   			return -ENODEV;
> -		dom->data = data;
> +		dom->bank = bank;
>   	}
>   
> -	if (!data->m4u_dom) { /* Initialize the M4U HW */
> +	if (!bank->m4u_dom) { /* Initialize the M4U HW */
>   		ret = pm_runtime_resume_and_get(m4udev);
>   		if (ret < 0)
>   			return ret;
> @@ -519,9 +530,9 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
>   			pm_runtime_put(m4udev);
>   			return ret;
>   		}
> -		data->m4u_dom = dom;
> +		bank->m4u_dom = dom;
>   		writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
> -		       data->base + REG_MMU_PT_BASE_ADDR);
> +		       bank->base + REG_MMU_PT_BASE_ADDR);
>   
>   		pm_runtime_put(m4udev);
>   	}
> @@ -543,7 +554,7 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
>   	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
>   
>   	/* The "4GB mode" M4U physically can not use the lower remap of Dram. */
> -	if (dom->data->enable_4GB)
> +	if (dom->bank->pdata->enable_4GB)
>   		paddr |= BIT_ULL(32);
>   
>   	/* Synchronize with the tlb_lock */
> @@ -564,7 +575,7 @@ static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain)
>   {
>   	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
>   
> -	mtk_iommu_tlb_flush_all(dom->data);
> +	mtk_iommu_tlb_flush_all(dom->bank->pdata);
>   }
>   
>   static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
> @@ -573,7 +584,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
>   	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
>   	size_t length = gather->end - gather->start + 1;
>   
> -	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->data);
> +	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->bank);
>   }
>   
>   static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
> @@ -581,7 +592,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
>   {
>   	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
>   
> -	mtk_iommu_tlb_flush_range_sync(iova, size, dom->data);
> +	mtk_iommu_tlb_flush_range_sync(iova, size, dom->bank);
>   }
>   
>   static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
> @@ -591,7 +602,7 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
>   	phys_addr_t pa;
>   
>   	pa = dom->iop->iova_to_phys(dom->iop, iova);
> -	if (dom->data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
> +	if (dom->bank->pdata->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
>   		pa &= ~BIT_ULL(32);
>   
>   	return pa;
> @@ -720,16 +731,17 @@ static const struct iommu_ops mtk_iommu_ops = {
>   
>   static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
>   {
> +	const struct mtk_iommu_bank_data *bank0 = &data->bank[0];
>   	u32 regval;
>   
>   	if (data->plat_data->m4u_plat == M4U_MT8173) {
>   		regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
>   			 F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
>   	} else {
> -		regval = readl_relaxed(data->base + REG_MMU_CTRL_REG);
> +		regval = readl_relaxed(bank0->base + REG_MMU_CTRL_REG);
>   		regval |= F_MMU_TF_PROT_TO_PROGRAM_ADDR;
>   	}
> -	writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
> +	writel_relaxed(regval, bank0->base + REG_MMU_CTRL_REG);
>   
>   	if (data->enable_4GB &&
>   	    MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) {
> @@ -738,31 +750,31 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
>   		 * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30].
>   		 */
>   		regval = F_MMU_VLD_PA_RNG(7, 4);
> -		writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
> +		writel_relaxed(regval, bank0->base + REG_MMU_VLD_PA_RNG);
>   	}
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE))
> -		writel_relaxed(F_MMU_DCM, data->base + REG_MMU_DCM_DIS);
> +		writel_relaxed(F_MMU_DCM, bank0->base + REG_MMU_DCM_DIS);
>   	else
> -		writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
> +		writel_relaxed(0, bank0->base + REG_MMU_DCM_DIS);
>   
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
>   		/* write command throttling mode */
> -		regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
> +		regval = readl_relaxed(bank0->base + REG_MMU_WR_LEN_CTRL);
>   		regval &= ~F_MMU_WR_THROT_DIS_MASK;
> -		writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL);
> +		writel_relaxed(regval, bank0->base + REG_MMU_WR_LEN_CTRL);
>   	}
>   
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) {
>   		/* The register is called STANDARD_AXI_MODE in this case */
>   		regval = 0;
>   	} else {
> -		regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL);
> +		regval = readl_relaxed(bank0->base + REG_MMU_MISC_CTRL);
>   		if (MTK_IOMMU_HAS_FLAG(data->plat_data, NOT_STD_AXI_MODE))
>   			regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
>   		if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN))
>   			regval &= ~F_MMU_IN_ORDER_WR_EN_MASK;
>   	}
> -	writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL);
> +	writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL);
>   
>   	regval = F_L2_MULIT_HIT_EN |
>   		F_TABLE_WALK_FAULT_INT_EN |
> @@ -770,7 +782,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
>   		F_MISS_FIFO_OVERFLOW_INT_EN |
>   		F_PREFETCH_FIFO_ERR_INT_EN |
>   		F_MISS_FIFO_ERR_INT_EN;
> -	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
> +	writel_relaxed(regval, bank0->base + REG_MMU_INT_CONTROL0);
>   
>   	regval = F_INT_TRANSLATION_FAULT |
>   		F_INT_MAIN_MULTI_HIT_FAULT |
> @@ -779,19 +791,19 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
>   		F_INT_TLB_MISS_FAULT |
>   		F_INT_MISS_TRANSACTION_FIFO_FAULT |
>   		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
> -	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
> +	writel_relaxed(regval, bank0->base + REG_MMU_INT_MAIN_CONTROL);
>   
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
>   		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
>   	else
>   		regval = lower_32_bits(data->protect_base) |
>   			 upper_32_bits(data->protect_base);
> -	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
> +	writel_relaxed(regval, bank0->base + REG_MMU_IVRP_PADDR);
>   
> -	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
> -			     dev_name(data->dev), (void *)data)) {
> -		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
> -		dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq);
> +	if (devm_request_irq(bank0->pdev, bank0->irq, mtk_iommu_isr, 0,
> +			     dev_name(bank0->pdev), (void *)bank0)) {
> +		writel_relaxed(0, bank0->base + REG_MMU_PT_BASE_ADDR);
> +		dev_err(bank0->pdev, "Failed @ IRQ-%d Request\n", bank0->irq);
>   		return -ENODEV;
>   	}
>   
> @@ -884,6 +896,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   	int                     ret;
>   	u32			val;
>   	char                    *p;
> +	struct mtk_iommu_bank_data *bank;
> +	void __iomem		*base;
>   
>   	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
>   	if (!data)
> @@ -921,14 +935,20 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   	}
>   
>   	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	data->base = devm_ioremap_resource(dev, res);
> -	if (IS_ERR(data->base))
> -		return PTR_ERR(data->base);
> +	base = devm_ioremap_resource(dev, res);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
>   	ioaddr = res->start;
>   
> -	data->irq = platform_get_irq(pdev, 0);
> -	if (data->irq < 0)
> -		return data->irq;
> +	bank = &data->bank[0];
> +	bank->id = 0;
> +	bank->base = base;
> +	bank->irq = platform_get_irq(pdev, 0);
> +	if (bank->irq < 0)
> +		return bank->irq;
> +	bank->pdev = dev;
> +	bank->pdata = data;
> +	spin_lock_init(&bank->tlb_lock);
>   
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
>   		data->bclk = devm_clk_get(dev, "bclk");
> @@ -964,8 +984,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   	if (ret)
>   		goto out_sysfs_remove;
>   
> -	spin_lock_init(&data->tlb_lock);
> -
>   	if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
>   		list_add_tail(&data->list, data->plat_data->hw_list);
>   		data->hw_list = data->plat_data->hw_list;
> @@ -1015,6 +1033,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   static int mtk_iommu_remove(struct platform_device *pdev)
>   {
>   	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
> +	struct mtk_iommu_bank_data *bank = &data->bank[0];
>   
>   	iommu_device_sysfs_remove(&data->iommu);
>   	iommu_device_unregister(&data->iommu);
> @@ -1031,7 +1050,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
>   		#endif
>   	}
>   	pm_runtime_disable(&pdev->dev);
> -	devm_free_irq(&pdev->dev, data->irq, data);
> +	devm_free_irq(&pdev->dev, bank->irq, bank);
>   	return 0;
>   }
>   
> @@ -1039,7 +1058,7 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
>   	struct mtk_iommu_suspend_reg *reg = &data->reg;
> -	void __iomem *base = data->base;
> +	void __iomem *base = data->bank[0].base;
>   
>   	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
>   	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
> @@ -1057,8 +1076,8 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
>   	struct mtk_iommu_suspend_reg *reg = &data->reg;
> -	struct mtk_iommu_domain *m4u_dom = data->m4u_dom;
> -	void __iomem *base = data->base;
> +	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
> +	void __iomem *base = data->bank[0].base;
>   	int ret;
>   
>   	ret = clk_prepare_enable(data->bclk);
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> index a9dc79c5a724..881fade8d39a 100644
> --- a/drivers/iommu/mtk_iommu.h
> +++ b/drivers/iommu/mtk_iommu.h
> @@ -24,6 +24,8 @@
>   
>   #define MTK_IOMMU_GROUP_MAX	8
>   
> +#define MTK_IOMMU_BANK_MAX	5
> +
>   struct mtk_iommu_suspend_reg {
>   	union {
>   		u32			standard_axi_mode;/* v1 */
> @@ -65,17 +67,33 @@ struct mtk_iommu_plat_data {
>   
>   struct mtk_iommu_domain;
>   
> -struct mtk_iommu_data {
> +struct mtk_iommu_bank_data {
>   	void __iomem			*base;
>   	int				irq;
> +	unsigned int			id;
> +	struct device			*pdev;

`pdev` may be a bit misleading, as it's conventionally read as "platform device"
and not as the intended "parent device"... perhaps calling it parent_dev would be
more appropriate.

> +	struct mtk_iommu_data		*pdata;   /* parent data */

Same here, pdata -> parent_data

> +	spinlock_t			tlb_lock; /* lock for tlb range flush */
> +	struct mtk_iommu_domain		*m4u_dom; /* Each bank has a domain */
> +};
> +
> +struct mtk_iommu_data {
> +	union {
> +		struct { /* only for gen1 */
> +			void __iomem		*base;
> +			int			irq;
> +			struct mtk_iommu_domain	*m4u_dom;
> +		};
> +
> +		/* only for gen2 that support multi-banks */
> +		struct mtk_iommu_bank_data	bank[MTK_IOMMU_BANK_MAX];
> +	};

Sorry, but I really don't like this union... please, update mtk_iommu_v1 to always
use bank[0] or, more appropriately, dynamically allocate the bank array with a
devm_kzalloc call (as to not waste memory on platforms with less available banks).

In that case, you would have...

>   	struct device			*dev;
>   	struct clk			*bclk;
>   	phys_addr_t			protect_base; /* protect memory base */
>   	struct mtk_iommu_suspend_reg	reg;
> -	struct mtk_iommu_domain		*m4u_dom;
>   	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
>   	bool                            enable_4GB;
> -	spinlock_t			tlb_lock; /* lock for tlb range flush */

	struct mtk_iommu_bank_data	*banks;
	u8				num_banks;

... where `num_banks` gets copied from the same in mtk_iommu_plat_data, defined
for each SoC, and where `banks` is dynamically allocated in mtk_iommu.c and
mtk_iommu_v1.c's probe() callback.

>   
>   	struct iommu_device		iommu;
>   	const struct mtk_iommu_plat_data *plat_data;
> 




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:53:29 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:53:29 +0100
Subject: [PATCH v3 32/33] iommu/mediatek: Backup/restore regsiters for
 multi banks
In-Reply-To: <20210923115840.17813-33-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-33-yong.wu@mediatek.com>
Message-ID: <aa3bdf14-582c-2636-cdd4-cec2013d2b10@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Each bank has some independent registers. thus backup/restore them for
> each a bank when suspend and resume.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 39 +++++++++++++++++++++++++++------------
>   drivers/iommu/mtk_iommu.h | 14 +++++++++++---
>   2 files changed, 38 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 3925d1d4f2cf..3cb18ed28132 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -1114,16 +1114,23 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
>   	struct mtk_iommu_suspend_reg *reg = &data->reg;
> -	void __iomem *base = data->bank[0].base;
> +	void __iomem *base;
> +	int i = 0;
>   
> +	base = data->bank[i].base;
>   	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
>   	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
>   	reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS);
>   	reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG);
> -	reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
> -	reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
> -	reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
>   	reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
> +	do {
> +		if (!data->plat_data->bank_enable[i])
> +			continue;
> +		base = data->bank[i].base;
> +		reg->int_control[i] = readl_relaxed(base + REG_MMU_INT_CONTROL0);
> +		reg->int_main_control[i] = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
> +		reg->ivrp_paddr[i] = readl_relaxed(base + REG_MMU_IVRP_PADDR);
> +	} while (++i < data->plat_data->bank_nr);
>   	clk_disable_unprepare(data->bclk);
>   	return 0;
>   }
> @@ -1132,9 +1139,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
>   	struct mtk_iommu_suspend_reg *reg = &data->reg;
> -	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
> -	void __iomem *base = data->bank[0].base;
> -	int ret;
> +	struct mtk_iommu_domain *m4u_dom;
> +	void __iomem *base;
> +	int ret, i = 0;
>   
>   	ret = clk_prepare_enable(data->bclk);
>   	if (ret) {
> @@ -1157,18 +1164,26 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
>   	 * Uppon first resume, only enable the clk and return, since the values of the
>   	 * registers are not yet set.
>   	 */
> -	if (!m4u_dom)
> +	if (!reg->wr_len_ctrl)
>   		return 0;
>   
> +	base = data->bank[i].base;
>   	writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL);
>   	writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL);
>   	writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS);
>   	writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
> -	writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
> -	writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
> -	writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
>   	writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
> -	writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + REG_MMU_PT_BASE_ADDR);
> +	do {
> +		m4u_dom = data->bank[i].m4u_dom;
> +		if (!data->plat_data->bank_enable[i] || !m4u_dom)
> +			continue;
> +		base = data->bank[i].base;
> +		writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0);
> +		writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL);
> +		writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR);
> +		writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
> +		       base + REG_MMU_PT_BASE_ADDR);
> +	} while (++i < data->plat_data->bank_nr);
>   	return 0;
>   }
>   
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> index cf4b3d10cf2c..e781ad583131 100644
> --- a/drivers/iommu/mtk_iommu.h
> +++ b/drivers/iommu/mtk_iommu.h
> @@ -33,11 +33,19 @@ struct mtk_iommu_suspend_reg {
>   	};
>   	u32				dcm_dis;
>   	u32				ctrl_reg;
> -	u32				int_control0;
> -	u32				int_main_control;
> -	u32				ivrp_paddr;
>   	u32				vld_pa_rng;
>   	u32				wr_len_ctrl;
> +	union {
> +		struct { /* only for gen1 */
> +			u32		int_control0;
> +		};
> +
> +		struct { /* only for gen2 that support multi-banks */
> +			u32		int_control[MTK_IOMMU_BANK_MAX];
> +			u32		int_main_control[MTK_IOMMU_BANK_MAX];
> +			u32		ivrp_paddr[MTK_IOMMU_BANK_MAX];
> +		};
> +	};

There's no need for yet another union... just update mtk_iommu_v1.c to use
int_control[0] instead of int_control0.

>   };
>   
>   enum mtk_iommu_plat {
> 




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:53:31 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:53:31 +0100
Subject: [PATCH v3 29/33] iommu/mediatek: Change the domid to
 iova_region_id
In-Reply-To: <20210923115840.17813-30-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-30-yong.wu@mediatek.com>
Message-ID: <bd0a2a6f-5edc-e036-d82a-81dffe31e293@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Prepare for adding bankid, also no functional change.
> 
> In the previous SoC, each a iova_region is a domain; In the multi-banks
> case, each a bank is a domain, then the original function name
> "mtk_iommu_get_domain_id" is not proper. Use "iova_region_id" instead of
> "domain_id".
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>






From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:53:36 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:53:36 +0100
Subject: [PATCH v3 25/33] iommu/mediatek: Just move code position in
 hw_init
In-Reply-To: <20210923115840.17813-26-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-26-yong.wu@mediatek.com>
Message-ID: <4186725d-07ab-07c1-6c58-7b496fa02225@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> No functional change too, prepare for mt8195 IOMMU support bank functions.
> Some global control settings are in bank0 while the other banks have
> their bank independent setting. Here only move the global control
> settings and the independent registers together.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:20 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:20 +0100
Subject: [PATCH v3 27/33] iommu/mediatek: Initialise bank HW for each a
 bank
In-Reply-To: <20210923115840.17813-28-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-28-yong.wu@mediatek.com>
Message-ID: <af588804-041c-b382-e5e4-4dfd0506b439@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> The mt8195 IOMMU HW max support 5 banks, and regarding the banks'
> registers, it looks like:
> 
>   ----------------------------------------
>   |bank0  | bank1 | bank2 | bank3 | bank4|
>   ----------------------------------------
>   |global |
>   |control|         null
>   |regs   |
>   -----------------------------------------
>   |bank   |bank   |bank   |bank   |bank   |
>   |regs   |regs   |regs   |regs   |regs   |
>   |       |       |       |       |       |
>   -----------------------------------------
> 
> Each bank has some special bank registers and it share bank0's global
> control registers. this patch initialise the bank hw with the bankid.
> 
> In the hw_init, we always initialise bank0's control register since
> we don't know if the bank0 is initialised.
> 
> Additionally, About each bank's register base, always delta 0x1000.
> like bank[x + 1] = bank[x] + 0x1000.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:22 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:22 +0100
Subject: [PATCH v3 24/33] iommu/mediatek: Only adjust code about register
 base
In-Reply-To: <20210923115840.17813-25-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-25-yong.wu@mediatek.com>
Message-ID: <4dce6fff-1c8f-3ec3-f540-4028241036e1@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> No functional change. Use "base" instead of the data->base. This is
> avoid to touch too many lines in the next patches.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:25 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:25 +0100
Subject: [PATCH v3 16/33] iommu/mediatek: Add IOMMU_TYPE flag
In-Reply-To: <20210923115840.17813-17-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-17-yong.wu@mediatek.com>
Message-ID: <b51db2d3-2788-2d6a-ef40-d842c88eae27@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Add IOMMU_TYPE definition. In the mt8195, we have another IOMMU_TYPE:
> infra iommu, also there will be another APU_IOMMU, thus, use 2bits for the
> IOMMU_TYPE.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:26 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:26 +0100
Subject: [PATCH v3 06/33] iommu/mediatek: Add 12G~16G support for multi
 domains
In-Reply-To: <20210923115840.17813-7-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-7-yong.wu@mediatek.com>
Message-ID: <0b4a4b95-813a-ef79-395d-da6ea80147d8@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> In mt8192, we preassign 0-4G; 4G-8G; 8G-12G for different multimedia
> engines. This depends on the "dma-ranges=" in the iommu consumer's dtsi
> node.
> 
> Adds 12G-16G region here. and reword the previous comment. we don't limit
> which master locate in which region.
> 
> CCU still is 8G-12G. Don't change it here.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:40 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:40 +0100
Subject: [PATCH v3 23/33] iommu/mediatek: Add mt8195 support
In-Reply-To: <20210923115840.17813-24-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-24-yong.wu@mediatek.com>
Message-ID: <64436ab1-064b-3a99-8ce0-6af6e23d4db8@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> mt8195 has 3 IOMMU, containing 2 MM IOMMUs, one is for vdo, the other
> is for vpp. and 1 INFRA IOMMU.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:44 +0100
Subject: [PATCH v3 11/33] iommu/mediatek: Remove the granule in the tlb
 flush
In-Reply-To: <20210923115840.17813-12-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-12-yong.wu@mediatek.com>
Message-ID: <428bbee6-d680-6188-9961-f13f64cc7c40@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> The MediaTek IOMMU don't care about granule when tlb flushing.
> Remove this variable.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:47 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:47 +0100
Subject: [PATCH v3 08/33] iommu/mediatek: Add a flag NON_STD_AXI
In-Reply-To: <20210923115840.17813-9-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-9-yong.wu@mediatek.com>
Message-ID: <c8c44971-482d-6806-8209-e4da6f86551d@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Add a new flag NON_STD_AXI, All the previous SoC support this flag.
> Prepare for adding infra and apu iommu which don't support this.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:48 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:48 +0100
Subject: [PATCH v3 07/33] iommu/mediatek: Add a flag DCM_DISABLE
In-Reply-To: <20210923115840.17813-8-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-8-yong.wu@mediatek.com>
Message-ID: <4b48b8ee-422b-b3b1-acdc-4e0c0085a20a@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> In the infra iommu, we should disable DCM. add a new flag for this.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:51 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:51 +0100
Subject: [PATCH v3 21/33] iommu/mediatek: Add infra iommu support
In-Reply-To: <20210923115840.17813-22-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-22-yong.wu@mediatek.com>
Message-ID: <f1e93e9e-cc89-146a-410f-13ea94445d31@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> The infra iommu enable bits in mt8195 is in the pericfg register segment,
> use regmap to update it.
> 
> If infra iommu master translation fault, It don't have the larbid/portid,
> thus print out the whole register value.
> 
> Since regmap_update_bits may fail, add return value for mtk_iommu_config.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:54 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:54 +0100
Subject: [PATCH v3 20/33] iommu/mediatek: Allow IOMMU_DOMAIN_UNMANAGED for
 PCIe VFIO
In-Reply-To: <20210923115840.17813-21-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-21-yong.wu@mediatek.com>
Message-ID: <d10be4b8-c095-7a20-c6b5-c3b63dfd31e6@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Allow the type IOMMU_DOMAIN_UNMANAGED since vfio_iommu_type1.c always call
> iommu_domain_alloc. The PCIe EP works ok when going through vfio.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:54:57 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:54:57 +0100
Subject: [PATCH v3 22/33] iommu/mediatek: Add PCIe support
In-Reply-To: <20210923115840.17813-23-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-23-yong.wu@mediatek.com>
Message-ID: <3b5e7072-0935-4383-27a1-dd8d623cc608@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Currently the code for of_iommu_configure_dev_id is like this:
> 
> static int of_iommu_configure_dev_id(struct device_node *master_np,
>                                       struct device *dev,
>                                       const u32 *id)
> {
>         struct of_phandle_args iommu_spec = { .args_count = 1 };
> 
>         err = of_map_id(master_np, *id, "iommu-map",
>                         "iommu-map-mask", &iommu_spec.np,
>                         iommu_spec.args);
> ...
> }
> 
> It supports only one id output. BUT our PCIe HW has two ID(one is for
> writing, the other is for reading). I'm not sure if we should change
> of_map_id to support output MAX_PHANDLE_ARGS.
> 
> Here add the solution in ourselve drivers. If it's pcie case, enable one
> more bit.
> 
> Not all infra iommu support PCIe, thus add a PCIe support flag here.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 21 ++++++++++++++++++++-
>   1 file changed, 20 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 37d6dfb4feab..3f1fd8036345 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -20,6 +20,7 @@
>   #include <linux/of_address.h>
>   #include <linux/of_irq.h>
>   #include <linux/of_platform.h>
> +#include <linux/pci.h>
>   #include <linux/platform_device.h>
>   #include <linux/pm_runtime.h>
>   #include <linux/regmap.h>
> @@ -132,6 +133,7 @@
>   #define MTK_IOMMU_TYPE_MM		(0x0 << 13)
>   #define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
>   #define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
> +#define IFA_IOMMU_PCIe_SUPPORT		BIT(15)

This definition looks like "breaking" the naming convention that's used in this
driver... what about MTK_INFRA_IOMMU_PCIE_SUPPORT?

>   
>   #define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
>   
> @@ -401,8 +403,11 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
>   				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
>   		} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
>   			peri_mmuen_msk = BIT(portid);
> -			peri_mmuen = enable ? peri_mmuen_msk : 0;
> +			/* PCIdev has only one output id, enable the next writing bit for PCIe */
> +			if (dev_is_pci(dev))
> +				peri_mmuen_msk |= BIT(portid + 1);
>   
> +			peri_mmuen = enable ? peri_mmuen_msk : 0;
>   			ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
>   						 peri_mmuen_msk, peri_mmuen);
>   			if (ret)
> @@ -977,6 +982,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   		ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
>   		if (ret)
>   			goto out_bus_set_null;
> +	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
> +		   MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIe_SUPPORT)) {
> +		#ifdef CONFIG_PCI

Please fix the indentation of this ifdef (do not indent).

> +		if (!iommu_present(&pci_bus_type)) {
> +			ret = bus_set_iommu(&pci_bus_type, &mtk_iommu_ops);
> +			if (ret) /* PCIe fail don't affect platform_bus. */
> +				goto out_list_del;
> +		}
> +		#endif
>   	}
>   	return ret;
>   
> @@ -1007,6 +1021,11 @@ static int mtk_iommu_remove(struct platform_device *pdev)
>   	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
>   		device_link_remove(data->smicomm_dev, &pdev->dev);
>   		component_master_del(&pdev->dev, &mtk_iommu_com_ops);
> +	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
> +		   MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIe_SUPPORT)) {
> +		#ifdef CONFIG_PCI

ditto.

> +		bus_set_iommu(&pci_bus_type, NULL);
> +		#endif
>   	}
>   	pm_runtime_disable(&pdev->dev);
>   	devm_free_irq(&pdev->dev, data->irq, data);
> 




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:00 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:00 +0100
Subject: [PATCH v3 18/33] iommu/mediatek: Adjust device link when it is
 sub-common
In-Reply-To: <20210923115840.17813-19-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-19-yong.wu@mediatek.com>
Message-ID: <bc973fde-bf87-570b-ccac-25a200cac4f1@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> For MM IOMMU, We always add device link between smi-common and IOMMU HW.
> In mt8195, we add smi-sub-common. Thus, if the node is sub-common, we still
> need find again to get smi-common, then do device link.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:02 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:02 +0100
Subject: [PATCH v3 17/33] iommu/mediatek: Contain MM IOMMU flow with the
 MM TYPE
In-Reply-To: <20210923115840.17813-18-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-18-yong.wu@mediatek.com>
Message-ID: <9e65ac5b-1b8b-03e6-c7f1-7104e96e06d2@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Prepare for supporting INFRA_IOMMU, and APU_IOMMU later.
> 
> For Infra IOMMU/APU IOMMU, it doesn't have the "larb""port". thus, Use
> the MM flag contain the MM_IOMMU special flow, Also, it moves a big
> chunk code about parsing the mediatek,larbs into a function, this is
> only needed for MM IOMMU. and all the current SoC are MM_IOMMU.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:06 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:06 +0100
Subject: [PATCH v3 13/33] iommu/mediatek: Remove the power status checking
 in tlb flush all
In-Reply-To: <20210923115840.17813-14-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-14-yong.wu@mediatek.com>
Message-ID: <1cb7458d-a012-2e84-82bd-7e4f30ed9162@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> To simplify the code, Remove the power status checking in the
> tlb_flush_all, remove this:
>     if (pm_runtime_get_if_in_use(data->dev) <= 0)
> 	    continue;
> 
> After this patch, the mtk_iommu_tlb_flush_all will be called from
> a) isr
> b) pm runtime resume callback
> c) tlb flush range fail case
> d) iommu_create_device_direct_mappings
>     -> iommu_flush_iotlb_all
> In first three cases, the power and clock always are enabled; d) is direct
> mapping, the tlb flush is unnecessay since we already have tlb_flush_all
> in the pm_runtime_resume callback. When the iommu's power status is
> changed to active, the tlb always is clean.
> 
> In addition, there still are 2 reasons that don't add PM status checking
> in the tlb flush all:
> a) Write tlb flush all register also is ok even though the HW has no
> power and clocks. Write ignore.

Do you mean that the register write seemingly succeeds but the hardware
discards it?
Please, reword the `a` sentence to be clearer.

> b) pm_runtime_get_if_in_use(m4udev) is 0 when the tlb_flush_all
> is called frm pm_runtime_resume cb. From this point, we can not add
> this code above in this tlb_flush_all.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 20 +++++++-------------
>   1 file changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index e9e94944ed91..4a33b6c6b1db 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -204,10 +204,14 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
>   	return container_of(dom, struct mtk_iommu_domain, domain);
>   }
>   
> -static void mtk_iommu_tlb_do_flush_all(struct mtk_iommu_data *data)
> +static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
>   {
>   	unsigned long flags;
>   
> +	/*
> +	 * No need get power status since the HW PM status nearly is active
> +	 * when entering here.

Please reword this comment to explain the entire situation.

> +	 */
>   	spin_lock_irqsave(&data->tlb_lock, flags);
>   	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>   		       data->base + data->plat_data->inv_sel_reg);
> @@ -216,16 +220,6 @@ static void mtk_iommu_tlb_do_flush_all(struct mtk_iommu_data *data)
>   	spin_unlock_irqrestore(&data->tlb_lock, flags);
>   }
>   
> -static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
> -{
> -	if (pm_runtime_get_if_in_use(data->dev) <= 0)
> -		return;
> -
> -	mtk_iommu_tlb_do_flush_all(data);
> -
> -	pm_runtime_put(data->dev);
> -}
> -
>   static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
>   					   struct mtk_iommu_data *data)
>   {
> @@ -263,7 +257,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
>   		if (ret) {
>   			dev_warn(data->dev,
>   				 "Partial TLB flush timed out, falling back to full flush\n");
> -			mtk_iommu_tlb_do_flush_all(data);
> +			mtk_iommu_tlb_flush_all(data);
>   		}
>   
>   		if (has_pm)
> @@ -993,7 +987,7 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
>   	 *
>   	 * Thus, Make sure the tlb always is clean after each PM resume.
>   	 */
> -	mtk_iommu_tlb_do_flush_all(data);
> +	mtk_iommu_tlb_flush_all(data);
>   
>   	/*
>   	 * Uppon first resume, only enable the clk and return, since the values of the
> 



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:10 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:10 +0100
Subject: [PATCH v3 04/33] iommu/mediatek: Remove clk_disable in
 mtk_iommu_remove
In-Reply-To: <20210923115840.17813-5-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-5-yong.wu@mediatek.com>
Message-ID: <f18d8bc0-f6da-9c20-941f-3880ff0d60fb@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> After the commit b34ea31fe013 ("iommu/mediatek: Always enable the clk on
> resume"), the iommu clock is controlled by the runtime callback.
> thus remove the clk control in the mtk_iommu_remove.
> 
> Otherwise, it will warning like:
> 
> echo 14018000.iommu > /sys/bus/platform/drivers/mtk-iommu/unbind
> 
> [   51.413044] ------------[ cut here ]------------
> [   51.413648] vpp0_smi_iommu already disabled
> [   51.414233] WARNING: CPU: 2 PID: 157 at */v5.15-rc1/kernel/mediatek/
>                            drivers/clk/clk.c:952 clk_core_disable+0xb0/0xb8
> [   51.417174] Hardware name: MT8195V/C(ENG) (DT)
> [   51.418635] pc : clk_core_disable+0xb0/0xb8
> [   51.419177] lr : clk_core_disable+0xb0/0xb8
> ...
> [   51.429375] Call trace:
> [   51.429694]  clk_core_disable+0xb0/0xb8
> [   51.430193]  clk_core_disable_lock+0x24/0x40
> [   51.430745]  clk_disable+0x20/0x30
> [   51.431189]  mtk_iommu_remove+0x58/0x118
> [   51.431705]  platform_remove+0x28/0x60
> [   51.432197]  device_release_driver_internal+0x110/0x1f0
> [   51.432873]  device_driver_detach+0x18/0x28
> [   51.433418]  unbind_store+0xd4/0x108
> [   51.433886]  drv_attr_store+0x24/0x38
> [   51.434363]  sysfs_kf_write+0x40/0x58
> [   51.434843]  kernfs_fop_write_iter+0x164/0x1e0
> 
> Fixes: b34ea31fe013 ("iommu/mediatek: Always enable the clk on resume")
> Reported-by: Hsin-Yi Wang <hsinyi at chromium.org>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:18 +0100
Subject: [PATCH v3 09/33] iommu/mediatek: Remove for_each_m4u in
 tlb_sync_all
In-Reply-To: <20210923115840.17813-10-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-10-yong.wu@mediatek.com>
Message-ID: <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> The tlb_sync_all is called from these three functions:
> a) flush_iotlb_all: it will be called for each a iommu HW.
> b) tlb_flush_range_sync: it already has for_each_m4u.
> c) in irq: When IOMMU HW translation fault, Only need flush itself.
> 
> Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 18 +++++++-----------
>   1 file changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 6f4f6624e3ac..0b4c30baa864 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -206,19 +206,15 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
>   
>   static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
>   {
> -	struct list_head *head = data->hw_list;
> -
> -	for_each_m4u(data, head) {
> -		if (pm_runtime_get_if_in_use(data->dev) <= 0)
> -			continue;
> +	if (pm_runtime_get_if_in_use(data->dev) <= 0)
> +		return;
>   
> -		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> -			       data->base + data->plat_data->inv_sel_reg);
> -		writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
> -		wmb(); /* Make sure the tlb flush all done */
> +	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> +		       data->base + data->plat_data->inv_sel_reg);
> +	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
> +	wmb(); /* Make sure the tlb flush all done */

There aren't a lot of writes here - not anymore, since you are no longer doing
this for_each_m4u()...
...so, please change writel_relaxed() to writel() calls, allowing you to also
remove the write barrier at the end (since in the non relaxed version, order
is already ensured).

>   
> -		pm_runtime_put(data->dev);
> -	}
> +	pm_runtime_put(data->dev);
>   }
>   
>   static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
> 


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:21 +0100
Subject: [PATCH v3 10/33] iommu/mediatek: Add tlb_lock in tlb_flush_all
In-Reply-To: <20210923115840.17813-11-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-11-yong.wu@mediatek.com>
Message-ID: <4444ddfd-c028-9549-0a1a-a3380fdd2d54@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> The tlb_flush_all also touches the registers about tlb operations.
> Add spinlock in it to protect the tlb registers. since the tlb_range
> already hold the spinlock, move it a bit outside the spinlock to
> print log.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:28 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:28 +0100
Subject: [PATCH v3 19/33] iommu/mediatek: Add list_del in mtk_iommu_remove
In-Reply-To: <20210923115840.17813-20-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-20-yong.wu@mediatek.com>
Message-ID: <301a89d6-13ca-25db-facd-1860bc77f02b@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Lack the list_del in the mtk_iommu_remove, and remove
> bus_set_iommu(*, NULL) since there may be several iommu HWs.
> we can not bus_set_iommu null when one iommu driver unbind.
> This issue is not so important, No need fix tags.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

I would still add a Fixes tag on this commit, as that would schedule it for
backporting - and that's rather important, solidifying older releases.

Please add the required tag, after which...


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:33 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:33 +0100
Subject: [PATCH v3 14/33] iommu/mediatek: Always enable output PA over
 32bits in isr
In-Reply-To: <20210923115840.17813-15-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-15-yong.wu@mediatek.com>
Message-ID: <ea6a6cf3-9215-f7f9-d049-afaa3f58a7cd@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Currently the output PA[32:33] is contained by the flag IOVA_34.
> This is not right. the iova_34 has no relation with pa[32:33], the 32bits
> iova still could map to pa[32:33]. Move it out from the flag.
> 
> No need fix tag since currently only mt8192 use the calulation and it
> always has this IOVA_34 flag.
> 
> Prepare for the IOMMU that still use IOVA 32bits but its dram size may be
> over 4GB.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:39 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:39 +0100
Subject: [PATCH v3 12/33] iommu/mediatek: Always tlb_flush_all when each
 PM resume
In-Reply-To: <20210923115840.17813-13-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-13-yong.wu@mediatek.com>
Message-ID: <5228acea-3bf4-987a-caaf-11b90aa0beae@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> Prepare for 2 HWs that sharing pgtable in different power-domains.
> 
> When there are 2 M4U HWs, it may has problem in the flush_range in which
> we get the pm_status via the m4u dev, BUT that function don't reflect the
> real power-domain status of the HW since there may be other HW also use
> that power-domain.
> 
> The function dma_alloc_attrs help allocate the iommu buffer which
> need the corresponding power domain since tlb flush is needed when
> preparing iova. BUT this function only is for allocating buffer,
> we have no good reason to request the user always call pm_runtime_get
> before calling dma_alloc_xxx. Therefore, we add a tlb_flush_all
> in the pm_runtime_resume to make sure the tlb always is clean.
> 
> Another solution is always call pm_runtime_get in the tlb_flush_range.
> This will trigger pm runtime resume/backup so often when the iommu
> power is not active at some time(means user don't call pm_runtime_get
> before calling dma_alloc_xxx), This may cause the performance drop.
> thus we don't use this.
> 
> In other case, the iommu's power should always be active via device
> link with smi.
> 
> The previous SoC don't have PM except mt8192. the mt8192 IOMMU is display's
> power-domain which nearly always is enabled. thus no need fix tags here.
> Prepare for mt8195.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:42 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:42 +0100
Subject: [PATCH v3 05/33] iommu/mediatek: Adapt sharing and non-sharing
 pgtable case
In-Reply-To: <20210923115840.17813-6-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-6-yong.wu@mediatek.com>
Message-ID: <06b124b3-fadc-da03-648f-907c622e2272@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> In previous mt2712, Both IOMMUs are MM IOMMU, and they will share pgtable.
> However in the latest SoC, another is infra IOMMU, there is no reason to
> share pgtable between MM with INFRA IOMMU. This patch manage to
> implement the two case(sharing and non-sharing pgtable).
> 
> Currently we use for_each_m4u to loop the 2 HWs. Add the list_head into
> this macro.
> In the sharing pgtable case, the list_head is the global "m4ulist".
> In the non-sharing pgtable case, the list_head is hw_list_head which is a
> variable in the "data". then for_each_m4u will only loop itself.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan  4 07:55:47 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 4 Jan 2022 16:55:47 +0100
Subject: [PATCH v3 15/33] iommu/mediatek: Add SUB_COMMON_3BITS flag
In-Reply-To: <20210923115840.17813-16-yong.wu@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-16-yong.wu@mediatek.com>
Message-ID: <4a9660ad-032a-5319-de29-d088e607310d@collabora.com>

Il 23/09/21 13:58, Yong Wu ha scritto:
> In prevous SoC, the sub common id occupy 2 bits. the mt8195's sub common
> id has 3bits. Add a new flag for this. and rename the prevous flag to
> _2BITS. For readable, I put these two flags together, then move the
> other flags. no functional change.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From broonie at kernel.org  Tue Jan  4 08:02:15 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 04 Jan 2022 16:02:15 +0000
Subject: [PATCH] drivers/regulator: remove redundant ret variable
In-Reply-To: <20220104104139.601031-1-chi.minghao@zte.com.cn>
References: <20220104104139.601031-1-chi.minghao@zte.com.cn>
Message-ID: <164131213558.2665148.2101695497540419615.b4-ty@kernel.org>

On Tue, 4 Jan 2022 10:41:39 +0000, cgel.zte at gmail.com wrote:
> From: Minghao Chi <chi.minghao at zte.com.cn>
> 
> Return value from regmap_update_bits() directly instead
> of taking this in another redundant variable.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-next

Thanks!

[1/1] drivers/regulator: remove redundant ret variable
      commit: 1f156b4285865dc2eb66e7a78c7ba80c17bb2b0a

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From catalin.marinas at arm.com  Tue Jan  4 08:09:54 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 4 Jan 2022 16:09:54 +0000
Subject: [PATCH v6 03/14] mm: Add len and flags parameters to
 arch_get_mmap_end()
In-Reply-To: <f1014efff7d26279d8c687d759af9f709cd50453.1639736449.git.christophe.leroy@csgroup.eu>
References: <cover.1639736449.git.christophe.leroy@csgroup.eu>
 <f1014efff7d26279d8c687d759af9f709cd50453.1639736449.git.christophe.leroy@csgroup.eu>
Message-ID: <YdRxUhy/lmfwGKYI@arm.com>

On Fri, Dec 17, 2021 at 10:27:23AM +0000, Christophe Leroy wrote:
> Powerpc needs flags and len to make decision on arch_get_mmap_end().
> 
> So add them as parameters to arch_get_mmap_end().
> 
> Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
> Cc: Steve Capper <steve.capper at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> ---
>  arch/arm64/include/asm/processor.h | 4 ++--
>  mm/mmap.c                          | 6 +++---
>  2 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index 6f41b65f9962..88c696350ace 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -91,8 +91,8 @@
>  #endif /* CONFIG_COMPAT */
>  
>  #ifndef CONFIG_ARM64_FORCE_52BIT
> -#define arch_get_mmap_end(addr) ((addr > DEFAULT_MAP_WINDOW) ? TASK_SIZE :\
> -				DEFAULT_MAP_WINDOW)
> +#define arch_get_mmap_end(addr, len, flags) ((addr > DEFAULT_MAP_WINDOW) ? TASK_SIZE :\
> +									   DEFAULT_MAP_WINDOW)

Nitpick, move the "((addr > ...." on the following line. Either way,

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Tue Jan  4 08:21:36 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 4 Jan 2022 16:21:36 +0000
Subject: [PATCH v6 04/14] mm, hugetlbfs: Allow for "high" userspace
 addresses
In-Reply-To: <db238c1ca2d46e33c57328f8d450f2563e92f8c2.1639736449.git.christophe.leroy@csgroup.eu>
References: <cover.1639736449.git.christophe.leroy@csgroup.eu>
 <db238c1ca2d46e33c57328f8d450f2563e92f8c2.1639736449.git.christophe.leroy@csgroup.eu>
Message-ID: <YdR0EN2mdJuysugk@arm.com>

On Fri, Dec 17, 2021 at 10:27:28AM +0000, Christophe Leroy wrote:
> This is a complement of f6795053dac8 ("mm: mmap: Allow for "high"
> userspace addresses") for hugetlb.
> 
> This patch adds support for "high" userspace addresses that are
> optionally supported on the system and have to be requested via a hint
> mechanism ("high" addr parameter to mmap).
> 
> Architectures such as powerpc and x86 achieve this by making changes to
> their architectural versions of hugetlb_get_unmapped_area() function.
> However, arm64 uses the generic version of that function.
> 
> So take into account arch_get_mmap_base() and arch_get_mmap_end() in
> hugetlb_get_unmapped_area(). To allow that, move those two macros
> out of mm/mmap.c into include/linux/sched/mm.h
> 
> If these macros are not defined in architectural code then they default
> to (TASK_SIZE) and (base) so should not introduce any behavioural
> changes to architectures that do not define them.
> 
> For the time being, only ARM64 is affected by this change.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
> Cc: Steve Capper <steve.capper at arm.com>
> Cc: Will Deacon <will.deacon at arm.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> ---
>  fs/hugetlbfs/inode.c     | 9 +++++----
>  include/linux/sched/mm.h | 8 ++++++++
>  mm/mmap.c                | 8 --------
>  3 files changed, 13 insertions(+), 12 deletions(-)

This would be an ABI change but I'm fine with it. Basically with this
patch, getting hugetblfs addresses above 48-bit require explicit hint
passed to mmap().

I wonder whether we should add a fixes tag (or at least the cc stable):

Fixes: f6795053dac8 ("mm: mmap: Allow for "high" userspace addresses")
Cc: <stable at vger.kernel.org> # 5.0.x

I think the original commit should have changed
hugetlb_get_unmapped_area() to have the same behaviour as
arch_get_unmapped_area(). Steve, any thoughts?

FWIW,

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 08:35:16 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 16:35:16 +0000
Subject: [PATCH v2 0/3] dmaengine: Use platform_get_irq*() variants to fetch
 IRQ's
Message-ID: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

Hi All,

This patch series aims to drop using platform_get_resource() for IRQ types
in preparation for removal of static setup of IRQ resource from DT core
code.

Dropping usage of platform_get_resource() was agreed based on
the discussion [0].

[0] https://patchwork.kernel.org/project/linux-renesas-soc/
patch/20211209001056.29774-1-prabhakar.mahadev-lad.rj at bp.renesas.com/

Cheers,
Prabhakar

Lad Prabhakar (3):
  dmaengine: nbpfaxi: Use platform_get_irq_optional() to get the
    interrupt
  dmaengine: mediatek: mtk-hsdma: Use platform_get_irq() to get the
    interrupt
  dmaengine: mediatek-cqdma: Use platform_get_irq() to get the interrupt

 drivers/dma/mediatek/mtk-cqdma.c | 12 ++++--------
 drivers/dma/mediatek/mtk-hsdma.c | 11 ++++-------
 drivers/dma/nbpfaxi.c            | 14 ++++++--------
 3 files changed, 14 insertions(+), 23 deletions(-)

-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 08:35:18 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 16:35:18 +0000
Subject: [PATCH v2 2/3] dmaengine: mediatek: mtk-hsdma: Use platform_get_irq()
 to get the interrupt
In-Reply-To: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220104163519.21929-3-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change
---
 drivers/dma/mediatek/mtk-hsdma.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
index 6ad8afbb95f2..c0fffde7fe08 100644
--- a/drivers/dma/mediatek/mtk-hsdma.c
+++ b/drivers/dma/mediatek/mtk-hsdma.c
@@ -923,13 +923,10 @@ static int mtk_hsdma_probe(struct platform_device *pdev)
 		return PTR_ERR(hsdma->clk);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "No irq resource for %s\n",
-			dev_name(&pdev->dev));
-		return -EINVAL;
-	}
-	hsdma->irq = res->start;
+	err = platform_get_irq(pdev, 0);
+	if (err < 0)
+		return err;
+	hsdma->irq = err;
 
 	refcount_set(&hsdma->pc_refcnt, 0);
 	spin_lock_init(&hsdma->lock);
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 08:35:19 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 16:35:19 +0000
Subject: [PATCH v2 3/3] dmaengine: mediatek-cqdma: Use platform_get_irq() to
 get the interrupt
In-Reply-To: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220104163519.21929-4-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change
---
 drivers/dma/mediatek/mtk-cqdma.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c
index 41ef9f15d3d5..f8847c48ba03 100644
--- a/drivers/dma/mediatek/mtk-cqdma.c
+++ b/drivers/dma/mediatek/mtk-cqdma.c
@@ -751,7 +751,6 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
 	struct mtk_cqdma_device *cqdma;
 	struct mtk_cqdma_vchan *vc;
 	struct dma_device *dd;
-	struct resource *res;
 	int err;
 	u32 i;
 
@@ -824,13 +823,10 @@ static int mtk_cqdma_probe(struct platform_device *pdev)
 			return PTR_ERR(cqdma->pc[i]->base);
 
 		/* allocate IRQ resource */
-		res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		if (!res) {
-			dev_err(&pdev->dev, "No irq resource for %s\n",
-				dev_name(&pdev->dev));
-			return -EINVAL;
-		}
-		cqdma->pc[i]->irq = res->start;
+		err = platform_get_irq(pdev, i);
+		if (err < 0)
+			return err;
+		cqdma->pc[i]->irq = err;
 
 		err = devm_request_irq(&pdev->dev, cqdma->pc[i]->irq,
 				       mtk_cqdma_irq, 0, dev_name(&pdev->dev),
-- 
2.17.1



From rmk+kernel at armlinux.org.uk  Tue Jan  4 08:38:31 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 04 Jan 2022 16:38:31 +0000
Subject: [PATCH net-next] net: gemini: allow any RGMII interface mode
Message-ID: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 07add311f65d..c78b99a497df 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan  4 08:39:19 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 4 Jan 2022 16:39:19 +0000
Subject: Possible nohz-full/RCU issue in arm64 KVM
In-Reply-To: <9ab8107f-ff41-6a9e-57e1-a261bea93aca@redhat.com>
References: <d80e440375896f75d45e227d40af60ca7ba24ceb.camel@redhat.com>
 <YbyO40zDW/kvUHEE@FVFF77S0Q05N>
 <70f112072d9496d21901946ea82832d3ed3a8cb2.camel@redhat.com>
 <Ybyg1r/Q6EfeuXGV@FVFF77S0Q05N>
 <9ab8107f-ff41-6a9e-57e1-a261bea93aca@redhat.com>
Message-ID: <YdR4N9QVYOzjowAb@FVFF77S0Q05N>

On Fri, Dec 17, 2021 at 04:54:22PM +0100, Paolo Bonzini wrote:
> On 12/17/21 15:38, Mark Rutland wrote:
> > For example kvm_guest_enter_irqoff() calls guest_enter_irq_off() which calls
> > vtime_account_guest_enter(), but kvm_guest_exit_irqoff() doesn't call
> > guest_exit_irq_off() and the call to vtime_account_guest_exit() is open-coded
> > elsewhere. Also, guest_enter_irq_off() conditionally calls
> > rcu_virt_note_context_switch(), but I can't immediately spot anything on the
> > exit side that corresponded with that, which looks suspicious.
> 
> rcu_note_context_switch() is a point-in-time notification; it's not strictly
> necessary, but it may improve performance a bit by avoiding unnecessary IPIs
> from the RCU subsystem.
> 
> There's no benefit from doing it when you're back from the guest, because at
> that point the CPU is just running normal kernel code.

I see.

My main issue here was just that it's really difficult to see how the
entry/exit logic is balanced, and I reckon we can solve that by splitting
guest_{enter,exit}_irqoff() into helper functions to handle the vtime
accounting separately from the context tracking, so that arch code can do
something like:

  guest_timing_enter_irqoff();
  
  guest_eqs_enter_irqoff();
  < actually run vCPU here >
  guest_eqs_exit_irqoff();
  
  < handle pending IRQs here >
  
  guest_timing_exit_irqoff();

... which I hope should work for RISC-V too.

I've had a go, and I've pushed out a WIP to:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/kvm/rcu

I also see we'll need to add some lockdep/irq-tracing management to arm64, and
it probably makes sense to fold that into common helpers, so I'll have a play
with that tomorrow.

Thanks,
Mark.


From prabhakar.mahadev-lad.rj at bp.renesas.com  Tue Jan  4 08:45:04 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue,  4 Jan 2022 16:45:04 +0000
Subject: [PATCH v5] soc: ti: smartreflex: Use platform_get_irq_optional() to
 get the interrupt
Message-ID: <20220104164504.24707-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq_optional().

While at it return 0 instead of returning ret in the probe success path.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v4->v5:
* Fixed missing return while using dev_err_probe().

v3->v4:
* Used dev_err_probe() to print error message
* Returning 0 in probe success path.

v2->v3
* Switch back to platform_get_irq_optional()
* Only print error in case of error, and not when interrupt is missing.

v1->v2
* Updated commit message
* Drop check for IRQ0
* Switched to using platform_get_irq() so that the probe won't
  fail silently as requested by Nishanth.

v1:
* https://www.spinics.net/lists/arm-kernel/msg942549.html
---
 drivers/soc/ti/smartreflex.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
index b5b2fa538d5c..8a0e97a7edc6 100644
--- a/drivers/soc/ti/smartreflex.c
+++ b/drivers/soc/ti/smartreflex.c
@@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info;
 	struct omap_sr_data *pdata = pdev->dev.platform_data;
-	struct resource *mem, *irq;
+	struct resource *mem;
 	struct dentry *nvalue_dir;
 	int i, ret = 0;
 
@@ -844,7 +844,11 @@ static int omap_sr_probe(struct platform_device *pdev)
 	if (IS_ERR(sr_info->base))
 		return PTR_ERR(sr_info->base);
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	ret = platform_get_irq_optional(pdev, 0);
+	if (ret < 0 && ret != -ENXIO)
+		return dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);
+	if (ret > 0)
+		sr_info->irq = ret;
 
 	sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
 	if (IS_ERR(sr_info->fck))
@@ -870,9 +874,6 @@ static int omap_sr_probe(struct platform_device *pdev)
 	sr_info->autocomp_active = false;
 	sr_info->ip_type = pdata->ip_type;
 
-	if (irq)
-		sr_info->irq = irq->start;
-
 	sr_set_clk_length(sr_info);
 
 	list_add(&sr_info->node, &sr_list);
@@ -926,7 +927,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 
 	}
 
-	return ret;
+	return 0;
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
-- 
2.17.1



From robh at kernel.org  Tue Jan  4 08:47:02 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 10:47:02 -0600
Subject: [PATCH 2/2] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
 <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
Message-ID: <YdR6BsyVaBnnFz7x@robh.at.kernel.org>

On Sun, Jan 02, 2022 at 04:58:07PM +0100, Krzysztof Kozlowski wrote:
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> controller bindings to DT schema format
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/spi/samsung,spi.yaml  | 220 ++++++++++++++++++
>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ----------
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 221 insertions(+), 123 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> new file mode 100644
> index 000000000000..195bfafe05fd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -0,0 +1,220 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC SPI controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description:
> +  All the SPI controller nodes should be represented in the aliases node using
> +  the following format 'spi{n}' where n is a unique number for the alias.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - samsung,s3c2443-spi
> +          - samsung,s3c6410-spi
> +          - samsung,s5pv210-spi
> +          - samsung,exynos5433-spi
> +      - const: samsung,exynos7-spi
> +        deprecated: true
> +
> +  clocks:
> +    minItems: 2
> +    maxItems: 3
> +
> +  clock-names:
> +    minItems: 2
> +    maxItems: 3
> +
> +  cs-gpios: true
> +
> +  dmas:
> +    minItems: 2
> +    maxItems: 2
> +
> +  dma-names:
> +    items:
> +      - const: tx
> +      - const: rx
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  no-cs-readback:
> +    description:
> +      The CS line is disconnected, therefore the device should not operate
> +      based on CS signalling.
> +    type: boolean
> +
> +  num-cs:
> +    minimum: 1
> +    maximum: 4
> +    default: 1
> +
> +  samsung,spi-src-clk:
> +    description:
> +      If the spi controller includes a internal clock mux to select the clock
> +      source for the spi bus clock, this property can be used to indicate the
> +      clock to be used for driving the spi bus clock. If not specified, the
> +      clock number 0 is used as default.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 0
> +
> +  reg:
> +    maxItems: 1
> +
> +patternProperties:
> +  "^.*@[0-9a-f]+$":
> +    type: object
> +
> +    allOf:
> +      - $ref: spi-peripheral-props.yaml
> +
> +    properties:
> +      controller-data:
> +        type: object
> +        additionalProperties: false
> +
> +        properties:
> +          samsung,spi-feedback-delay:

All this has to go in it's own schema which then needs to be added to 
spi-peripheral-props.yaml.

> +            description: |
> +              The sampling phase shift to be applied on the miso line (to account
> +              for any lag in the miso line). Valid values:
> +               - 0: No phase shift.
> +               - 1: 90 degree phase shift sampling.
> +               - 2: 180 degree phase shift sampling.
> +               - 3: 270 degree phase shift sampling.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3]
> +
> +        required:
> +          - samsung,spi-feedback-delay
> +
> +    required:
> +      - controller-data

Not really great that this is required and there's not some default that 
works.

> +
> +    unevaluatedProperties: false
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - dmas
> +  - dma-names
> +  - interrupts
> +  - reg
> +
> +allOf:
> +  - $ref: spi-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos5433-spi
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +            - const: spi_ioclk
> +    else:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5433.h>
> +    #include <dt-bindings/clock/samsung,s2mps11.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    spi at 14d30000 {
> +        compatible = "samsung,exynos5433-spi";
> +        reg = <0x14d30000 0x100>;
> +        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
> +        dmas = <&pdma0 11>, <&pdma0 10>;
> +        dma-names = "tx", "rx";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        clocks = <&cmu_peric CLK_PCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
> +        clock-names = "spi",
> +                      "spi_busclk0",
> +                      "spi_ioclk";
> +        samsung,spi-src-clk = <0>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&spi1_bus>;
> +        num-cs = <1>;
> +
> +        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
> +        status = "okay";

Don't need 'status' in examples.

> +        audio-codec at 0 {
> +            compatible = "wlf,wm5110";
> +            reg = <0x0>;
> +            spi-max-frequency = <20000000>;
> +            interrupt-parent = <&gpa0>;
> +            interrupts = <4 IRQ_TYPE_NONE>;
> +            clocks = <&pmu_system_controller 0>,
> +                     <&s2mps13_osc S2MPS11_CLK_BT>;
> +            clock-names = "mclk1", "mclk2";
> +
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +
> +            wlf,micd-detect-debounce = <300>;
> +            wlf,micd-bias-start-time = <0x1>;
> +            wlf,micd-rate = <0x7>;
> +            wlf,micd-dbtime = <0x2>;
> +            wlf,micd-force-micbias;
> +            wlf,micd-configs = <0x0 1 0>;
> +            wlf,hpdet-channel = <1>;
> +            wlf,gpsw = <0x1>;
> +            wlf,inmode = <2 0 2 0>;
> +
> +            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
> +            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
> +
> +            /* core supplies */
> +            AVDD-supply = <&ldo18_reg>;
> +            DBVDD1-supply = <&ldo18_reg>;
> +            CPVDD-supply = <&ldo18_reg>;
> +            DBVDD2-supply = <&ldo18_reg>;
> +            DBVDD3-supply = <&ldo18_reg>;
> +            SPKVDDL-supply = <&ldo18_reg>;
> +            SPKVDDR-supply = <&ldo18_reg>;
> +
> +            controller-data {

The schema didn't get checked since spi-peripheral-props.yaml isn't 
yet in my tree, but I'd expect this to be a warning. If not its schema 
needs to be a bit stricter. The schema for "wlf,wm5110" will need to 
reference spi-peripheral-props.yaml. (Actually, all SPI peripheral 
device schemas will need a reference in theory, but really we only care 
for devices used with controllers with extra properties). 

Rob


From linus.walleij at linaro.org  Tue Jan  4 08:48:58 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 4 Jan 2022 17:48:58 +0100
Subject: [PATCH net-next] net: gemini: allow any RGMII interface mode
In-Reply-To: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
References: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
Message-ID: <CACRpkdZCACEHEFq93CHvr4E+xMFa3YHUVcJXt=Uc1THZ8_3psQ@mail.gmail.com>

On Tue, Jan 4, 2022 at 5:38 PM Russell King (Oracle)
<rmk+kernel at armlinux.org.uk> wrote:

> The four RGMII interface modes take care of the required RGMII delay
> configuration at the PHY and should not be limited by the network MAC
> driver. Sadly, gemini was only permitting RGMII mode with no delays,
> which would require the required delay to be inserted via PCB tracking
> or by the MAC.
>
> However, there are designs that require the PHY to add the delay, which
> is impossible without Gemini permitting the other three PHY interface
> modes. Fix the driver to allow these.
>
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Excellent root-cause analysis of this and thanks!
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From mathieu.poirier at linaro.org  Tue Jan  4 08:53:33 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 4 Jan 2022 09:53:33 -0700
Subject: [PATCH 0/2] Add SCP support for mt8186
In-Reply-To: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
References: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220104165333.GA539868@p14s>

Hi Allen,

On Tue, Jan 04, 2022 at 07:47:04PM +0800, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> changes since v1:
> - use mt8192_power_on_sram() helper
> - add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
> - add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h

It is quite hard to follow the evolution of this patchset.  The second revision
had a "v2" tag but this one doesn't, which can be confused with the patchset
sent on January 3rd.  Please send another one (v4) with:

1) A cover letter.
2) The right SoB.
3) The right version tag.

> 
> Based on v5.16-rc8

This should be based on rproc-next[1].

Thanks,
Mathieu

https://git.kernel.org/pub/scm/linux/kernel/git/remoteproc/linux.git/log/?h=rproc-next

> 
> allen-kh.cheng (2):
>   dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
>   remoteproc: mediatek: Support mt8186 scp
> 
>  .../bindings/remoteproc/mtk,scp.yaml          |  1 +
>  drivers/remoteproc/mtk_common.h               |  3 ++
>  drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
>  3 files changed, 39 insertions(+)
> 
> -- 
> 2.18.0
> 


From irogers at google.com  Tue Jan  4 09:01:32 2022
From: irogers at google.com (Ian Rogers)
Date: Tue, 4 Jan 2022 09:01:32 -0800
Subject: [PATCH v3] perf evlist: Remove group option.
In-Reply-To: <YdRX5zgB3AORM/Wd@krava>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-3-irogers@google.com>
 <YdRX5zgB3AORM/Wd@krava>
Message-ID: <CAP-5=fXyBU4yF=S2FSjd6sZXCwqqJ=BS5eOynPk0C4KTs9EcsQ@mail.gmail.com>

On Tue, Jan 4, 2022 at 6:21 AM Jiri Olsa <jolsa at redhat.com> wrote:
>
> On Wed, Dec 29, 2021 at 11:19:43PM -0800, Ian Rogers wrote:
> > The group option predates grouping events using curly braces added in
> > commit 89efb029502d ("perf tools: Add support to parse event group syntax")
> > The --group option was retained for legacy support (in August 2012) but
> > keeping it adds complexity.
> >
> > v2 and v3. were rebases.
> >
> > Signed-off-by: Ian Rogers <irogers at google.com>
>
> it should not be part of this patchset right?
> I see it was posted separately

Yep, sorry. Not part of this patch set I hadn't realized I had another
v3 patch when I ran send-mail. This patch was sent out a little
earlier already.

Thanks,
Ian

> jirka
>
> > ---
> >  tools/perf/Documentation/perf-record.txt |  4 ----
> >  tools/perf/Documentation/perf-top.txt    |  7 ++-----
> >  tools/perf/builtin-record.c              |  2 --
> >  tools/perf/builtin-stat.c                |  6 ------
> >  tools/perf/builtin-top.c                 |  2 --
> >  tools/perf/tests/attr/README             |  2 --
> >  tools/perf/tests/attr/test-record-group  | 22 ----------------------
> >  tools/perf/tests/attr/test-stat-group    | 17 -----------------
> >  tools/perf/util/evlist.c                 |  2 +-
> >  tools/perf/util/evlist.h                 |  2 --
> >  tools/perf/util/python.c                 |  8 --------
> >  tools/perf/util/record.c                 |  7 -------
> >  tools/perf/util/record.h                 |  1 -
> >  13 files changed, 3 insertions(+), 79 deletions(-)
> >  delete mode 100644 tools/perf/tests/attr/test-record-group
> >  delete mode 100644 tools/perf/tests/attr/test-stat-group
> >
> > diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> > index 55df7b073a55..960fb1ad3f27 100644
> > --- a/tools/perf/Documentation/perf-record.txt
> > +++ b/tools/perf/Documentation/perf-record.txt
> > @@ -238,10 +238,6 @@ OPTIONS
> >       Also, by adding a comma, the number of mmap pages for AUX
> >       area tracing can be specified.
> >
> > ---group::
> > -     Put all events in a single event group.  This precedes the --event
> > -     option and remains only for backward compatibility.  See --event.
> > -
> >  -g::
> >       Enables call-graph (stack chain/backtrace) recording for both
> >       kernel space and user space.
> > diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
> > index cac3dfbee7d8..acbafe777e52 100644
> > --- a/tools/perf/Documentation/perf-top.txt
> > +++ b/tools/perf/Documentation/perf-top.txt
> > @@ -51,9 +51,6 @@ Default is to monitor all CPUS.
> >  --count-filter=<count>::
> >       Only display functions with more events than this.
> >
> > ---group::
> > -        Put the counters into a counter group.
> > -
> >  --group-sort-idx::
> >       Sort the output by the event at the index n in group. If n is invalid,
> >       sort by the first event. It can support multiple groups with different
> > @@ -313,10 +310,10 @@ use '-e e1 -e e2 -G foo,foo' or just use '-e e1 -e e2 -G foo'.
> >
> >               perf top -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
> >
> > -        Alternatively one can ask for --group and then two overhead columns
> > +        Alternatively one can ask for a group and then two overhead columns
> >             will appear, the first for cycles and the second for the switch-on event.
> >
> > -             perf top --group -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
> > +             perf top -e '{cycles,probe:icmp_rcv}' --switch-on=probe:icmp_rcv
> >
> >       This may be interesting to measure a workload only after some initialization
> >       phase is over, i.e. insert a perf probe at that point and use the above
> > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> > index 6ac2160913ea..54eff61f78eb 100644
> > --- a/tools/perf/builtin-record.c
> > +++ b/tools/perf/builtin-record.c
> > @@ -2521,8 +2521,6 @@ static struct option __record_options[] = {
> >       OPT_CALLBACK(0, "mmap-flush", &record.opts, "number",
> >                    "Minimal number of bytes that is extracted from mmap data pages (default: 1)",
> >                    record__mmap_flush_parse),
> > -     OPT_BOOLEAN(0, "group", &record.opts.group,
> > -                 "put the counters into a counter group"),
> >       OPT_CALLBACK_NOOPT('g', NULL, &callchain_param,
> >                          NULL, "enables call-graph recording" ,
> >                          &record_callchain_opt),
> > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > index f6ca2b054c5b..8ce4ca6111ae 100644
> > --- a/tools/perf/builtin-stat.c
> > +++ b/tools/perf/builtin-stat.c
> > @@ -180,7 +180,6 @@ static bool                       topdown_run                     = false;
> >  static bool                  smi_cost                        = false;
> >  static bool                  smi_reset                       = false;
> >  static int                   big_num_opt                     =  -1;
> > -static bool                  group                           = false;
> >  static const char            *pre_cmd                        = NULL;
> >  static const char            *post_cmd                       = NULL;
> >  static bool                  sync_run                        = false;
> > @@ -800,9 +799,6 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
> >               child_pid = evsel_list->workload.pid;
> >       }
> >
> > -     if (group)
> > -             evlist__set_leader(evsel_list);
> > -
> >       if (affinity__setup(&affinity) < 0)
> >               return -1;
> >
> > @@ -1212,8 +1208,6 @@ static struct option stat_options[] = {
> >  #endif
> >       OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
> >                   "system-wide collection from all CPUs"),
> > -     OPT_BOOLEAN('g', "group", &group,
> > -                 "put the counters into a counter group"),
> >       OPT_BOOLEAN(0, "scale", &stat_config.scale,
> >                   "Use --no-scale to disable counter scaling for multiplexing"),
> >       OPT_INCR('v', "verbose", &verbose,
> > diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
> > index 1fc390f136dd..0d8441942f34 100644
> > --- a/tools/perf/builtin-top.c
> > +++ b/tools/perf/builtin-top.c
> > @@ -1472,8 +1472,6 @@ int cmd_top(int argc, const char **argv)
> >                           "dump the symbol table used for profiling"),
> >       OPT_INTEGER('f', "count-filter", &top.count_filter,
> >                   "only display functions with more events than this"),
> > -     OPT_BOOLEAN(0, "group", &opts->group,
> > -                         "put the counters into a counter group"),
> >       OPT_BOOLEAN('i', "no-inherit", &opts->no_inherit,
> >                   "child tasks do not inherit counters"),
> >       OPT_STRING(0, "sym-annotate", &top.sym_filter, "symbol name",
> > diff --git a/tools/perf/tests/attr/README b/tools/perf/tests/attr/README
> > index a36f49fb4dbe..f538272af57b 100644
> > --- a/tools/perf/tests/attr/README
> > +++ b/tools/perf/tests/attr/README
> > @@ -47,7 +47,6 @@ Following tests are defined (with perf commands):
> >    perf record -g kill                           (test-record-graph-default)
> >    perf record --call-graph dwarf kill                (test-record-graph-dwarf)
> >    perf record --call-graph fp kill              (test-record-graph-fp)
> > -  perf record --group -e cycles,instructions kill (test-record-group)
> >    perf record -e '{cycles,instructions}' kill   (test-record-group1)
> >    perf record -e '{cycles/period=1/,instructions/period=2/}:S' kill (test-record-group2)
> >    perf record -D kill                           (test-record-no-delay)
> > @@ -61,6 +60,5 @@ Following tests are defined (with perf commands):
> >    perf stat -d kill                             (test-stat-detailed-1)
> >    perf stat -dd kill                            (test-stat-detailed-2)
> >    perf stat -ddd kill                           (test-stat-detailed-3)
> > -  perf stat --group -e cycles,instructions kill (test-stat-group)
> >    perf stat -e '{cycles,instructions}' kill     (test-stat-group1)
> >    perf stat -i -e cycles kill                   (test-stat-no-inherit)
> > diff --git a/tools/perf/tests/attr/test-record-group b/tools/perf/tests/attr/test-record-group
> > deleted file mode 100644
> > index 14ee60fd3f41..000000000000
> > --- a/tools/perf/tests/attr/test-record-group
> > +++ /dev/null
> > @@ -1,22 +0,0 @@
> > -[config]
> > -command = record
> > -args    = --no-bpf-event --group -e cycles,instructions kill >/dev/null 2>&1
> > -ret     = 1
> > -
> > -[event-1:base-record]
> > -fd=1
> > -group_fd=-1
> > -sample_type=327
> > -read_format=4
> > -
> > -[event-2:base-record]
> > -fd=2
> > -group_fd=1
> > -config=1
> > -sample_type=327
> > -read_format=4
> > -mmap=0
> > -comm=0
> > -task=0
> > -enable_on_exec=0
> > -disabled=0
> > diff --git a/tools/perf/tests/attr/test-stat-group b/tools/perf/tests/attr/test-stat-group
> > deleted file mode 100644
> > index e15d6946e9b3..000000000000
> > --- a/tools/perf/tests/attr/test-stat-group
> > +++ /dev/null
> > @@ -1,17 +0,0 @@
> > -[config]
> > -command = stat
> > -args    = --group -e cycles,instructions kill >/dev/null 2>&1
> > -ret     = 1
> > -
> > -[event-1:base-stat]
> > -fd=1
> > -group_fd=-1
> > -read_format=3|15
> > -
> > -[event-2:base-stat]
> > -fd=2
> > -group_fd=1
> > -config=1
> > -disabled=0
> > -enable_on_exec=0
> > -read_format=3|15
> > diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> > index 5f92319ce258..2e11d82d15e0 100644
> > --- a/tools/perf/util/evlist.c
> > +++ b/tools/perf/util/evlist.c
> > @@ -224,7 +224,7 @@ int __evlist__set_tracepoints_handlers(struct evlist *evlist,
> >       return err;
> >  }
> >
> > -void evlist__set_leader(struct evlist *evlist)
> > +static void evlist__set_leader(struct evlist *evlist)
> >  {
> >       perf_evlist__set_leader(&evlist->core);
> >  }
> > diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> > index 27594900a052..ebab48a8120f 100644
> > --- a/tools/perf/util/evlist.h
> > +++ b/tools/perf/util/evlist.h
> > @@ -203,8 +203,6 @@ void evlist__set_selected(struct evlist *evlist, struct evsel *evsel);
> >  int evlist__create_maps(struct evlist *evlist, struct target *target);
> >  int evlist__apply_filters(struct evlist *evlist, struct evsel **err_evsel);
> >
> > -void evlist__set_leader(struct evlist *evlist);
> > -
> >  u64 __evlist__combined_sample_type(struct evlist *evlist);
> >  u64 evlist__combined_sample_type(struct evlist *evlist);
> >  u64 evlist__combined_branch_type(struct evlist *evlist);
> > diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
> > index 7f782a31bda3..d063375c346a 100644
> > --- a/tools/perf/util/python.c
> > +++ b/tools/perf/util/python.c
> > @@ -1121,14 +1121,6 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
> >                                  PyObject *args, PyObject *kwargs)
> >  {
> >       struct evlist *evlist = &pevlist->evlist;
> > -     int group = 0;
> > -     static char *kwlist[] = { "group", NULL };
> > -
> > -     if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
> > -             return NULL;
> > -
> > -     if (group)
> > -             evlist__set_leader(evlist);
> >
> >       if (evlist__open(evlist) < 0) {
> >               PyErr_SetFromErrno(PyExc_OSError);
> > diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
> > index bff669b615ee..9e694db7c7ee 100644
> > --- a/tools/perf/util/record.c
> > +++ b/tools/perf/util/record.c
> > @@ -99,13 +99,6 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
> >       bool use_comm_exec;
> >       bool sample_id = opts->sample_id;
> >
> > -     /*
> > -      * Set the evsel leader links before we configure attributes,
> > -      * since some might depend on this info.
> > -      */
> > -     if (opts->group)
> > -             evlist__set_leader(evlist);
> > -
> >       if (evlist->core.cpus->map[0] < 0)
> >               opts->no_inherit = true;
> >
> > diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h
> > index ef6c2715fdd9..0a7a8dbbea9c 100644
> > --- a/tools/perf/util/record.h
> > +++ b/tools/perf/util/record.h
> > @@ -13,7 +13,6 @@ struct option;
> >
> >  struct record_opts {
> >       struct target target;
> > -     bool          group;
> >       bool          inherit_stat;
> >       bool          no_buffering;
> >       bool          no_inherit;
> > --
> > 2.34.1.307.g9b7440fafd-goog
> >
>


From linus.walleij at linaro.org  Tue Jan  4 09:02:47 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue,  4 Jan 2022 18:02:47 +0100
Subject: [PATCH] ARM: dts: gpio-ranges property is now required
Message-ID: <20220104170247.956760-1-linus.walleij@linaro.org>

From: Phil Elwell <phil at raspberrypi.com>

Since [1], added in 5.7, the absence of a gpio-ranges property has
prevented GPIOs from being restored to inputs when released.
Add those properties for BCM283x and BCM2711 devices.

[1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
    pin-ranges")

Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
Reported-by: Florian Fainelli <f.fainelli at gmail.com>
Reported-by: Jan Kiszka <jan.kiszka at web.de>
Signed-off-by: Phil Elwell <phil at raspberrypi.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Hi SoC maintainers, please apply this directly for fixes, the
missing patch is wreacking havoc in the RPi world.
---
 arch/arm/boot/dts/bcm2711.dtsi | 2 ++
 arch/arm/boot/dts/bcm283x.dtsi | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index 9e01dbca4a01..dff18fc9a906 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -582,6 +582,8 @@ &gpio {
 		     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
 		     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
 
+	gpio-ranges = <&gpio 0 0 58>;
+
 	gpclk0_gpio49: gpclk0_gpio49 {
 		pin-gpclk {
 			pins = "gpio49";
diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index a3e06b680947..c113661a6668 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -126,6 +126,8 @@ gpio: gpio at 7e200000 {
 			interrupt-controller;
 			#interrupt-cells = <2>;
 
+			gpio-ranges = <&gpio 0 0 54>;
+
 			/* Defines common pin muxing groups
 			 *
 			 * While each pin can have its mux selected
-- 
2.33.1



From irogers at google.com  Tue Jan  4 09:08:27 2022
From: irogers at google.com (Ian Rogers)
Date: Tue, 4 Jan 2022 09:08:27 -0800
Subject: [PATCH v3 00/48] Refactor perf cpumap
In-Reply-To: <YdRYk8Ic8qdEAhQz@krava>
References: <20211230072030.302559-1-irogers@google.com>
 <YdRYk8Ic8qdEAhQz@krava>
Message-ID: <CAP-5=fUbM-miTBqQNhuTdevBF7VMBmd=LH+GxXkP2_z5n9nmtQ@mail.gmail.com>

On Tue, Jan 4, 2022 at 6:24 AM Jiri Olsa <jolsa at redhat.com> wrote:
>
> On Wed, Dec 29, 2021 at 11:19:41PM -0800, Ian Rogers wrote:
> > Perf cpu map has various functions where a cpumap and index are passed
> > in order to load the cpu. A problem with this is that the wrong index
> > may be passed for the cpumap, causing problems like aggregation on the
> > wrong CPU:
> > https://lore.kernel.org/lkml/20211204023409.969668-1-irogers at google.com/
> >
> > This patch set refactors the cpu map API, reducing it and explicitly
> > passing the cpu (rather than the pair) to functions that need
> > it. Comments are added at the same time. Changes modify the same
> > file/function more than once as refactoring and fixes are broken apart
> > for the sake of bisection.
> >
> > v2. Incorproates fixes suggested Jiri Olsa, rewrites the evlist CPU
> >     iterator in part in a way suggested by Riccardo Mancini. The new
> >     fixes start at patch 23. The final change was suggested by John
> >     Garry to make the CPUs have their own struct wrapper.
> >
> > v3. Incorporates fixes suggested by Namhyung Kim.
> >
> > Ian Rogers (48):
>
> you doubled the amount of patches from v1? ;-)

Ah yes, sorry about that. I wasn't trying to imply you'd reviewed the
new patches but I see where the wording is confusing. I was worried
about the number of patches, but less so after:
https://lore.kernel.org/lkml/YdIfz+LMewetSaEB at gmail.com/
:-)

> I had small comments for the first 22 patches and would be ok
> with them merged.. will try to go through the rest soon

Thanks. The v1 wasn't as complete as I'd have liked and Namhyung had
some feedback to that effect as well (it was great to get feedback to
make sure I wasn't flogging a dead horse). For v4 I see a request to
rename a variable/parameter, which I can do. I'll hold off a bit and
send out a v4 later today hopefully.

Thanks,
Ian

> thanks,
> jirka
>
> >   libperf: Add comments to perf_cpu_map.
> >   perf stat: Add aggr creators that are passed a cpu.
> >   perf stat: Correct aggregation CPU map
> >   perf stat: Switch aggregation to use for_each loop
> >   perf stat: Switch to cpu version of cpu_map__get
> >   perf cpumap: Switch cpu_map__build_map to cpu function
> >   perf cpumap: Remove map+index get_socket
> >   perf cpumap: Remove map+index get_die
> >   perf cpumap: Remove map+index get_core
> >   perf cpumap: Remove map+index get_node
> >   perf cpumap: Add comments to aggr_cpu_id
> >   perf cpumap: Remove unused cpu_map__socket
> >   perf cpumap: Simplify equal function name.
> >   perf cpumap: Rename empty functions.
> >   perf cpumap: Document cpu__get_node and remove redundant function
> >   perf cpumap: Remove map from function names that don't use a map.
> >   perf cpumap: Remove cpu_map__cpu, use libperf function.
> >   perf cpumap: Refactor cpu_map__build_map
> >   perf cpumap: Rename cpu_map__get_X_aggr_by_cpu functions
> >   perf cpumap: Move 'has' function to libperf
> >   perf cpumap: Add some comments to cpu_aggr_map
> >   perf cpumap: Trim the cpu_aggr_map
> >   perf stat: Fix memory leak in check_per_pkg
> >   perf cpumap: Add CPU to aggr_cpu_id
> >   perf stat-display: Avoid use of core for CPU.
> >   perf evsel: Derive CPUs and threads in alloc_counts
> >   libperf: Switch cpu to more accurate cpu_map_idx
> >   libperf: Use cpu not index for evsel mmap
> >   perf counts: Switch name cpu to cpu_map_idx
> >   perf stat: Rename aggr_data cpu to imply it's an index
> >   perf stat: Use perf_cpu_map__for_each_cpu
> >   perf script: Use for each cpu to aid readability
> >   libperf: Allow NULL in perf_cpu_map__idx
> >   perf evlist: Refactor evlist__for_each_cpu.
> >   perf evsel: Pass cpu not cpu map index to synthesize
> >   perf stat: Correct variable name for read counter
> >   perf evsel: Rename CPU around get_group_fd
> >   perf evsel: Reduce scope of evsel__ignore_missing_thread
> >   perf evsel: Rename variable cpu to index
> >   perf test: Use perf_cpu_map__for_each_cpu
> >   perf stat: Correct check_per_pkg cpu
> >   perf stat: Swap variable name cpu to index
> >   libperf: Sync evsel documentation
> >   perf bpf: Rename cpu to cpu_map_idx
> >   perf c2c: Use more intention revealing iterator
> >   perf script: Fix flipped index and cpu
> >   perf stat: Correct first_shadow_cpu to return index
> >   perf cpumap: Give CPUs their own type.
> >
> >  tools/lib/perf/Documentation/libperf.txt      |  11 +-
> >  tools/lib/perf/cpumap.c                       | 131 +++--
> >  tools/lib/perf/evlist.c                       |   4 +-
> >  tools/lib/perf/evsel.c                        |  92 ++--
> >  tools/lib/perf/include/internal/cpumap.h      |  18 +-
> >  tools/lib/perf/include/internal/evlist.h      |   3 +-
> >  tools/lib/perf/include/internal/evsel.h       |   4 +-
> >  tools/lib/perf/include/internal/mmap.h        |   5 +-
> >  tools/lib/perf/include/perf/cpumap.h          |   8 +-
> >  tools/lib/perf/include/perf/evsel.h           |  10 +-
> >  tools/lib/perf/libperf.map                    |   1 +
> >  tools/lib/perf/mmap.c                         |   2 +-
> >  tools/perf/arch/arm/util/cs-etm.c             |  16 +-
> >  tools/perf/bench/epoll-ctl.c                  |   2 +-
> >  tools/perf/bench/epoll-wait.c                 |   2 +-
> >  tools/perf/bench/futex-hash.c                 |   2 +-
> >  tools/perf/bench/futex-lock-pi.c              |   2 +-
> >  tools/perf/bench/futex-requeue.c              |   2 +-
> >  tools/perf/bench/futex-wake-parallel.c        |   2 +-
> >  tools/perf/bench/futex-wake.c                 |   2 +-
> >  tools/perf/builtin-c2c.c                      |  15 +-
> >  tools/perf/builtin-ftrace.c                   |   2 +-
> >  tools/perf/builtin-kmem.c                     |   2 +-
> >  tools/perf/builtin-record.c                   |   2 +-
> >  tools/perf/builtin-sched.c                    |  71 +--
> >  tools/perf/builtin-script.c                   |  10 +-
> >  tools/perf/builtin-stat.c                     | 516 +++++++++---------
> >  tools/perf/tests/attr.c                       |   6 +-
> >  tools/perf/tests/bitmap.c                     |   2 +-
> >  tools/perf/tests/cpumap.c                     |   6 +-
> >  tools/perf/tests/event_update.c               |   6 +-
> >  tools/perf/tests/mem2node.c                   |   2 +-
> >  tools/perf/tests/mmap-basic.c                 |   4 +-
> >  tools/perf/tests/openat-syscall-all-cpus.c    |  39 +-
> >  tools/perf/tests/stat.c                       |   3 +-
> >  tools/perf/tests/topology.c                   |  43 +-
> >  tools/perf/util/affinity.c                    |   2 +-
> >  tools/perf/util/auxtrace.c                    |  12 +-
> >  tools/perf/util/auxtrace.h                    |   5 +-
> >  tools/perf/util/bpf_counter.c                 |  16 +-
> >  tools/perf/util/bpf_counter.h                 |   4 +-
> >  tools/perf/util/counts.c                      |   8 +-
> >  tools/perf/util/counts.h                      |  14 +-
> >  tools/perf/util/cpumap.c                      | 253 ++++-----
> >  tools/perf/util/cpumap.h                      | 116 ++--
> >  tools/perf/util/cputopo.c                     |   6 +-
> >  tools/perf/util/env.c                         |  29 +-
> >  tools/perf/util/env.h                         |   3 +-
> >  tools/perf/util/evlist.c                      | 148 ++---
> >  tools/perf/util/evlist.h                      |  50 +-
> >  tools/perf/util/evsel.c                       | 143 ++---
> >  tools/perf/util/evsel.h                       |  27 +-
> >  tools/perf/util/expr.c                        |   2 +-
> >  tools/perf/util/header.c                      |   6 +-
> >  tools/perf/util/mmap.c                        |  19 +-
> >  tools/perf/util/mmap.h                        |   3 +-
> >  tools/perf/util/perf_api_probe.c              |  15 +-
> >  tools/perf/util/python.c                      |   4 +-
> >  tools/perf/util/record.c                      |  11 +-
> >  .../scripting-engines/trace-event-python.c    |   6 +-
> >  tools/perf/util/session.c                     |  10 +-
> >  tools/perf/util/stat-display.c                | 138 ++---
> >  tools/perf/util/stat-shadow.c                 | 308 +++++------
> >  tools/perf/util/stat.c                        |  47 +-
> >  tools/perf/util/stat.h                        |   9 +-
> >  tools/perf/util/svghelper.c                   |   6 +-
> >  tools/perf/util/synthetic-events.c            |  12 +-
> >  tools/perf/util/synthetic-events.h            |   3 +-
> >  tools/perf/util/util.h                        |   5 +-
> >  69 files changed, 1333 insertions(+), 1155 deletions(-)
> >
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
>


From pbonzini at redhat.com  Tue Jan  4 09:07:32 2022
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Tue, 4 Jan 2022 18:07:32 +0100
Subject: Possible nohz-full/RCU issue in arm64 KVM
In-Reply-To: <YdR4N9QVYOzjowAb@FVFF77S0Q05N>
References: <d80e440375896f75d45e227d40af60ca7ba24ceb.camel@redhat.com>
 <YbyO40zDW/kvUHEE@FVFF77S0Q05N>
 <70f112072d9496d21901946ea82832d3ed3a8cb2.camel@redhat.com>
 <Ybyg1r/Q6EfeuXGV@FVFF77S0Q05N>
 <9ab8107f-ff41-6a9e-57e1-a261bea93aca@redhat.com>
 <YdR4N9QVYOzjowAb@FVFF77S0Q05N>
Message-ID: <b8e273bf-ae2c-cc5c-0d20-33f3dd12053c@redhat.com>

On 1/4/22 17:39, Mark Rutland wrote:
> My main issue here was just that it's really difficult to see how the
> entry/exit logic is balanced, and I reckon we can solve that by splitting
> guest_{enter,exit}_irqoff() into helper functions to handle the vtime
> accounting separately from the context tracking, so that arch code can do
> something like:
> 
>    guest_timing_enter_irqoff();
>    
>    guest_eqs_enter_irqoff();
>    < actually run vCPU here >
>    guest_eqs_exit_irqoff();
>    
>    < handle pending IRQs here >
>    
>    guest_timing_exit_irqoff();
> 
> ... which I hope should work for RISC-V too.
> 
> I've had a go, and I've pushed out a WIP to:
> 
>    https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/kvm/rcu

Yes, you have a point and it makes sense for x86 too.  You can send me a 
topic branch once you get all the acks.  Thanks!

Paolo



From alexandre.torgue at foss.st.com  Tue Jan  4 09:14:14 2022
From: alexandre.torgue at foss.st.com (Alexandre TORGUE)
Date: Tue, 4 Jan 2022 18:14:14 +0100
Subject: [PATCH v2 1/5] dt-bindings: interrupt-controller: Update STM32
 EXTI interrupt controller
In-Reply-To: <87bl1bwj2z.wl-maz@kernel.org>
References: <20211215105847.2328-1-alexandre.torgue@foss.st.com>
 <20211215105847.2328-2-alexandre.torgue@foss.st.com>
 <YbueUmqyzwS9rOu5@robh.at.kernel.org>
 <3f8acbb8-0b7e-2f47-eefc-67e5a7632445@foss.st.com>
 <87bl1bwj2z.wl-maz@kernel.org>
Message-ID: <e5754264-b263-1090-3017-1a6fec284614@foss.st.com>

Hi Marc

On 12/20/21 1:34 PM, Marc Zyngier wrote:
> On Fri, 17 Dec 2021 13:39:11 +0000,
> Alexandre TORGUE <alexandre.torgue at foss.st.com> wrote:
>>
>> On 12/16/21 9:15 PM, Rob Herring wrote:
>>> On Wed, Dec 15, 2021 at 11:58:43AM +0100, Alexandre Torgue wrote:
>>>> Document new entry "st,exti-mapping" which links EXTI lines with GIC
>>>> interrupt lines and add an include file to define EXTI interrupt type.
>>>>
>>>> Signed-off-by: Alexandre Torgue <alexandre.torgue at foss.st.com>
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
>>>> index d19c881b4abc..e08bb51e97a8 100644
>>>> --- a/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
>>>> +++ b/Documentation/devicetree/bindings/interrupt-controller/st,stm32-exti.yaml
>>>> @@ -41,6 +41,17 @@ properties:
>>>>        description:
>>>>          Interrupts references to primary interrupt controller
>>>>    +  st,exti-mapping:
>>>> +    $ref: "/schemas/types.yaml#/definitions/uint32-matrix"
>>>> +    description: |
>>>> +            Define mapping between EXTI lines and GIC irq lines. Should be:
>>>> +            st,exti-mapping = <EXTI_LINE GIC_IRQ EXTI_TYPE>, ...;
>>>> +            With:
>>>> +            - EXTI_LINE: EXTI line number.
>>>> +            - GIC_IRQ: GIC IRQ associated to the EXTI line.
>>>> +            - EXTI_TYPE: STM32_EXTI_TYPE_CONFIGURABLE or STM32_EXTI_TYPE_DIRECT.
>>>> +              Defined in include/dt-bindings/interrupt-controller/stm32-exti.h
>>>
>>> No custom properties for this. See[1][2][3].
>>>
>>
>> Thanks for inputs. In my case the mapping consists to map an EXTI line
>> with a GIC irq line which could be done using interrupt-map (avoiding
>> to parse it in my driver).
> 
> The problem is that 'interrupt-map' defines an interrupt mapping
> between an input and an output, and that mentioning the GIC in such a
> table will only result in your EXTI to be bypassed.
> 
> 'interrupt-map' really is a dispatch table for targeting an interrupt
> controller (or multiple controllers, even), but really isn't the
> correct tool to carry configuration informations to an interrupt
> controller driver.

Ok so let's forget "interrupt-map"

>> But for each EXTI/GIC association I would
>> like also to describe the EXTI_TYPE (which actually describe the well
>> irqchip to use inside my exti driver) . This property is not generic
>> and so I assume I can't use a generic binding such "interrupt-map".
>>
>> If the solution consists to use a common binding (i.e. interrupt-map)
>> plus a conversion table in exti driver to affect the well irq_chip to
>> the well EXTI line then we could envisage to keep the whole mapping
>> inside the driver (even if it's not the best solution).
> 
> A possible solution would be to have:
> 
> - A set of standard 'interrupts' properties describing the output
> signals
> 
> - A set of properties describing the input to output mapping (if
> relevant) and additional configuration information that for the
> interrupt controller driver.

Does it means to have my own description of "interrupt" property using 
xlate function in EXTI driver ?

something like that:

interrupt = <GIC_SPI 6 EXTI_LINE EXTI_TYPE>, ...

regards
Alex
> 
> 	M.
> 



From maz at kernel.org  Tue Jan  4 09:18:23 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue,  4 Jan 2022 17:18:23 +0000
Subject: [PATCH v2 1/1] KVM: arm64: vgic: Replace kernel.h with the
 necessary inclusions
In-Reply-To: <20220104151940.55399-1-andriy.shevchenko@linux.intel.com>
References: <20220104151940.55399-1-andriy.shevchenko@linux.intel.com>
Message-ID: <164131669019.3722270.11121664995774113019.b4-ty@kernel.org>

On Tue, 4 Jan 2022 17:19:40 +0200, Andy Shevchenko wrote:
> The arm_vgic.h does not require all the stuff the kernel.h provides.
> Replace kernel.h inclusion with the list of what is really being used.

Applied to next, thanks!

[1/1] KVM: arm64: vgic: Replace kernel.h with the necessary inclusions
      commit: 6c9eeb5f4a9bb2b11a40fd0f15efde7bd33ee908

Cheers,

	M.
-- 
Without deviation from the norm, progress is not possible.




From broonie at kernel.org  Tue Jan  4 09:32:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 4 Jan 2022 17:32:02 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <20211209111048.GM3294453@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
Message-ID: <YdSEkt72V1oeVx5E@sirena.org.uk>

On Thu, Dec 09, 2021 at 11:10:48AM +0000, Szabolcs Nagy wrote:
> The 12/08/2021 18:23, Catalin Marinas wrote:
> > On Mon, Nov 15, 2021 at 03:27:10PM +0000, Mark Brown wrote:

> > > memory is already mapped with PROT_EXEC.  This series resolves this by
> > > handling the BTI property for both the interpreter and the main
> > > executable.

> > Given the silence on this series over the past months, I propose we drop
> > it. It's a bit unfortunate that systemd's MemoryDenyWriteExecute cannot
> > work with BTI but I also think the former is a pretty blunt hardening
> > mechanism (rejecting any mprotect(PROT_EXEC) regardless of the previous
> > attributes).

> i still think it would be better if the kernel dealt with
> PROT_BTI for the exe loaded by the kernel.

The above message from Catalin isn't quite the full story here - my
understanding from backchannel is that there's concern from others that
we might be creating future issues by enabling PROT_BTI, especially in
the case where the same permissions issue prevents the dynamic linker
disabling PROT_BTI.  They'd therefore rather stick with the status quo
and not create any new ABI.  Unfortunately that's not something people
have been willing to say on the list, hopefully the above captures the
thinking well enough.

Personally I'm a bit ambivalent on this, I do see the potential issue
but I'm having trouble constructing an actual scenario and my instinct
is that since we handle PROT_EXEC we should also handle PROT_BTI for
consistency.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/5e34d71d/attachment.sig>

From patrick at stwcx.xyz  Tue Jan  4 10:20:26 2022
From: patrick at stwcx.xyz (Patrick Williams)
Date: Tue, 4 Jan 2022 12:20:26 -0600
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <20220103171721.46c8e697@xps13>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com>
 <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com>
 <20220103171721.46c8e697@xps13>
Message-ID: <YdSP6tKyQ2ZRUC+2@heinlein>

Hi Miquel,

On Mon, Jan 03, 2022 at 05:17:21PM +0100, Miquel Raynal wrote:

> > I am fine with taking in bug fixes but no longer want to take in any new 
> > features. My main intention was to nudge you to convert it to SPI MEM 
> > regardless of whether this is a bug fix or a new feature, because 
> > eventually we want to get rid of drivers/mtd/spi-nor/controllers/ and 
> > the API that comes along with it.
> 
> I totally agree with Pratyush here, we no longer want to support the
> spi-nor controller API so if, as you say, there are boards failing
> in the field, it means there are still users and these users must be
> warned that at some point we might discontinue the support of these
> drivers if it becomes too painful.
>

Your response here makes it seem like you don't realize the scope of this
driver.  There are probably, by my estimates, on the order of 10s of millions of
deployed systems using this driver in the world.  The vast majority of servers
in the world use an AST2400, AST2500, or AST2600 chip, which needs this driver
in order access its own flash storage device.  Both OpenBMC and most of the
proprietary alternatives use this driver.

The company I work for has a LOT of systems using this code.  After I made this
fix, for a new design being developed, it was pointed out to me that our ODM ran
into this problem a few years ago and we've been really bad about upstreaming
those fixes.  For this new system I'm trying to keep us on top of all
upstreaming efforts.

To me the inability to access your own storage, resulting in a kernel panic, is
a pretty serious issue.  Bug or feature I guess is always in the eye of the
beholder though.  I think this is pretty valuable to get in, from an impact
standpoint, and pretty minimal in terms of maintenance efforts on the
maintainers part.

I had an offline discussion with someone who knew more history on this driver.
My understanding is that the linux-aspeed team is aware of this being deprecated
but that there was some missing support for interface training that nobody has
gotten around to write?  If that is the case this really isn't even a "simple"
port to a new API at this point.

-- 
Patrick Williams
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/4be800be/attachment.sig>

From valentin.caron at foss.st.com  Tue Jan  4 10:24:41 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 4 Jan 2022 19:24:41 +0100
Subject: [PATCH 0/4] Add improvements for STM32 USART DMA TX
Message-ID: <20220104182445.4195-1-valentin.caron@foss.st.com>

This series reworks STM32 USART DMA TX state management, and fix flow control.

Valentin Caron (4):
  serial: stm32: move tx dma terminate DMA to shutdown
  serial: stm32: rework TX DMA state condition
  serial: stm32: fix flow control transfer in DMA mode
  serial: stm32: correct loop for dma error handling

 drivers/tty/serial/stm32-usart.c | 74 ++++++++++++++++++++++++--------
 drivers/tty/serial/stm32-usart.h |  2 +-
 2 files changed, 56 insertions(+), 20 deletions(-)

-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan  4 10:24:42 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 4 Jan 2022 19:24:42 +0100
Subject: [PATCH 1/4] serial: stm32: move tx dma terminate DMA to shutdown
In-Reply-To: <20220104182445.4195-1-valentin.caron@foss.st.com>
References: <20220104182445.4195-1-valentin.caron@foss.st.com>
Message-ID: <20220104182445.4195-2-valentin.caron@foss.st.com>

Terminate DMA transaction and clear CR3_DMAT when shutdown is requested,
instead of when remove is requested. If DMA transfer is not stopped in
shutdown ops, driver will fail to start a new DMA transfer after next
startup ops.

Fixes: 3489187204eb ("serial: stm32: adding dma support")

Signed-off-by: Erwan Le Ray <erwan.leray at foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 3244e7f6818c..6cfc3bec6749 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -883,6 +883,11 @@ static void stm32_usart_shutdown(struct uart_port *port)
 	u32 val, isr;
 	int ret;
 
+	if (stm32_port->tx_dma_busy) {
+		dmaengine_terminate_async(stm32_port->tx_ch);
+		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+	}
+
 	/* Disable modem control interrupts */
 	stm32_usart_disable_ms(port);
 
@@ -1570,7 +1575,6 @@ static int stm32_usart_serial_remove(struct platform_device *pdev)
 	writel_relaxed(cr3, port->membase + ofs->cr3);
 
 	if (stm32_port->tx_ch) {
-		dmaengine_terminate_async(stm32_port->tx_ch);
 		stm32_usart_of_dma_tx_remove(stm32_port, pdev);
 		dma_release_channel(stm32_port->tx_ch);
 	}
-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan  4 10:24:45 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 4 Jan 2022 19:24:45 +0100
Subject: [PATCH 4/4] serial: stm32: correct loop for dma error handling
In-Reply-To: <20220104182445.4195-1-valentin.caron@foss.st.com>
References: <20220104182445.4195-1-valentin.caron@foss.st.com>
Message-ID: <20220104182445.4195-5-valentin.caron@foss.st.com>

In this error handling, "transmit_chars_dma" function will call
"transmit_chars_pio" once per characters. But "transmit_chars_pio" will
continue to send characters while xmit buffer is not empty.

Remove this useless loop, one call is sufficient.

Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 788e002688f2..1f89ab0e49ac 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -477,7 +477,7 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port)
 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
 	struct circ_buf *xmit = &port->state->xmit;
 	struct dma_async_tx_descriptor *desc = NULL;
-	unsigned int count, i;
+	unsigned int count;
 
 	if (stm32_usart_tx_dma_started(stm32port)) {
 		if (!stm32_usart_tx_dma_enabled(stm32port))
@@ -542,8 +542,7 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port)
 	return;
 
 fallback_err:
-	for (i = count; i > 0; i--)
-		stm32_usart_transmit_chars_pio(port);
+	stm32_usart_transmit_chars_pio(port);
 }
 
 static void stm32_usart_transmit_chars(struct uart_port *port)
-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan  4 10:24:44 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 4 Jan 2022 19:24:44 +0100
Subject: [PATCH 3/4] serial: stm32: fix flow control transfer in DMA mode
In-Reply-To: <20220104182445.4195-1-valentin.caron@foss.st.com>
References: <20220104182445.4195-1-valentin.caron@foss.st.com>
Message-ID: <20220104182445.4195-4-valentin.caron@foss.st.com>

If flow control is enabled, framework will call stop_tx to
pause transfer and then call start_tx to resume transfer.

Clear USART_CR3_DMAT bit in stop_tx ops to pause DMA transfer.

Signed-off-by: Erwan Le Ray <erwan.leray at foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 52755a576bc2..788e002688f2 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -707,8 +707,11 @@ static void stm32_usart_stop_tx(struct uart_port *port)
 {
 	struct stm32_port *stm32_port = to_stm32_port(port);
 	struct serial_rs485 *rs485conf = &port->rs485;
+	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 
 	stm32_usart_tx_interrupt_disable(port);
+	if (stm32_usart_tx_dma_started(stm32_port) && stm32_usart_tx_dma_enabled(stm32_port))
+		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
 
 	if (rs485conf->flags & SER_RS485_ENABLED) {
 		if (rs485conf->flags & SER_RS485_RTS_ON_SEND) {
-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan  4 10:24:43 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 4 Jan 2022 19:24:43 +0100
Subject: [PATCH 2/4] serial: stm32: rework TX DMA state condition
In-Reply-To: <20220104182445.4195-1-valentin.caron@foss.st.com>
References: <20220104182445.4195-1-valentin.caron@foss.st.com>
Message-ID: <20220104182445.4195-3-valentin.caron@foss.st.com>

TX DMA state condition is handled by tx_dma_busy boolean.
This boolean is set when dma descriptor is requested and reset when dma
channel is stopped (dma_terminate).

In stm32_usart_serial_remove(), stm32_usart_stop_tx() and
stm32_usart_transmit_chars_dma() fallback error case, DMA channel is
stopped but tx_dma_busy is not handled.

Rework the driver by using two new functions to solve this issue:
- stm32_usart_tx_dma_started return true if DMA TX have a descriptor.
- stm32_usart_tx_dma_enabled return true if DMAT bit is set.

stm32_usart_tx_dma_started uses tx_dma_busy flag to prevent dual DMA
transaction at the same time. This flag is set when a DMA transaction
begins and is unset when dmaengine_terminate_async function is called.
A new DMA transaction cannot be created if this flag is set.

Create a new function "stm32_usart_tx_dma_terminate" to be sure the flag
is unset after each call of dmaengine_terminate_async.

Signed-off-by: Erwan Le Ray <erwan.leray at foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 66 +++++++++++++++++++++++---------
 drivers/tty/serial/stm32-usart.h |  2 +-
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 6cfc3bec6749..52755a576bc2 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -365,6 +365,31 @@ static unsigned int stm32_usart_receive_chars(struct uart_port *port, bool force
 	return size;
 }
 
+static void stm32_usart_tx_dma_terminate(struct stm32_port *stm32_port)
+{
+	dmaengine_terminate_async(stm32_port->tx_ch);
+	stm32_port->tx_dma_busy = false;
+}
+
+static bool stm32_usart_tx_dma_started(struct stm32_port *stm32_port)
+{
+	/*
+	 * We cannot use the function "dmaengine_tx_status" to know the
+	 * status of DMA. This function does not show if the "dma complete"
+	 * callback of the DMA transaction has been called. So we prefer
+	 * to use "tx_dma_busy" flag to prevent dual DMA transaction at the
+	 * same time.
+	 */
+	return stm32_port->tx_dma_busy;
+}
+
+static bool stm32_usart_tx_dma_enabled(struct stm32_port *stm32_port)
+{
+	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
+
+	return !!(readl_relaxed(stm32_port->port.membase + ofs->cr3) & USART_CR3_DMAT);
+}
+
 static void stm32_usart_tx_dma_complete(void *arg)
 {
 	struct uart_port *port = arg;
@@ -372,9 +397,8 @@ static void stm32_usart_tx_dma_complete(void *arg)
 	const struct stm32_usart_offsets *ofs = &stm32port->info->ofs;
 	unsigned long flags;
 
-	dmaengine_terminate_async(stm32port->tx_ch);
 	stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
-	stm32port->tx_dma_busy = false;
+	stm32_usart_tx_dma_terminate(stm32port);
 
 	/* Let's see if we have pending data to send */
 	spin_lock_irqsave(&port->lock, flags);
@@ -428,10 +452,8 @@ static void stm32_usart_transmit_chars_pio(struct uart_port *port)
 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 	struct circ_buf *xmit = &port->state->xmit;
 
-	if (stm32_port->tx_dma_busy) {
+	if (stm32_usart_tx_dma_enabled(stm32_port))
 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
-		stm32_port->tx_dma_busy = false;
-	}
 
 	while (!uart_circ_empty(xmit)) {
 		/* Check that TDR is empty before filling FIFO */
@@ -457,10 +479,11 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port)
 	struct dma_async_tx_descriptor *desc = NULL;
 	unsigned int count, i;
 
-	if (stm32port->tx_dma_busy)
+	if (stm32_usart_tx_dma_started(stm32port)) {
+		if (!stm32_usart_tx_dma_enabled(stm32port))
+			stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT);
 		return;
-
-	stm32port->tx_dma_busy = true;
+	}
 
 	count = uart_circ_chars_pending(xmit);
 
@@ -491,13 +514,21 @@ static void stm32_usart_transmit_chars_dma(struct uart_port *port)
 	if (!desc)
 		goto fallback_err;
 
+	/*
+	 * Set "tx_dma_busy" flag. This flag will be released when
+	 * dmaengine_terminate_async will be called. This flag helps
+	 * transmit_chars_dma not to start another DMA transaction
+	 * if the callback of the previous is not yet called.
+	 */
+	stm32port->tx_dma_busy = true;
+
 	desc->callback = stm32_usart_tx_dma_complete;
 	desc->callback_param = port;
 
 	/* Push current DMA TX transaction in the pending queue */
 	if (dma_submit_error(dmaengine_submit(desc))) {
 		/* dma no yet started, safe to free resources */
-		dmaengine_terminate_async(stm32port->tx_ch);
+		stm32_usart_tx_dma_terminate(stm32port);
 		goto fallback_err;
 	}
 
@@ -522,12 +553,13 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
 	struct circ_buf *xmit = &port->state->xmit;
 
 	if (port->x_char) {
-		if (stm32_port->tx_dma_busy)
+		if (stm32_usart_tx_dma_started(stm32_port) &&
+		    stm32_usart_tx_dma_enabled(stm32_port))
 			stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
 		writel_relaxed(port->x_char, port->membase + ofs->tdr);
 		port->x_char = 0;
 		port->icount.tx++;
-		if (stm32_port->tx_dma_busy)
+		if (stm32_usart_tx_dma_started(stm32_port))
 			stm32_usart_set_bits(port, ofs->cr3, USART_CR3_DMAT);
 		return;
 	}
@@ -719,9 +751,8 @@ static void stm32_usart_flush_buffer(struct uart_port *port)
 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 
 	if (stm32_port->tx_ch) {
-		dmaengine_terminate_async(stm32_port->tx_ch);
+		stm32_usart_tx_dma_terminate(stm32_port);
 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
-		stm32_port->tx_dma_busy = false;
 	}
 }
 
@@ -883,10 +914,11 @@ static void stm32_usart_shutdown(struct uart_port *port)
 	u32 val, isr;
 	int ret;
 
-	if (stm32_port->tx_dma_busy) {
-		dmaengine_terminate_async(stm32_port->tx_ch);
+	if (stm32_usart_tx_dma_enabled(stm32_port))
 		stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
-	}
+
+	if (stm32_usart_tx_dma_started(stm32_port))
+		stm32_usart_tx_dma_terminate(stm32_port);
 
 	/* Disable modem control interrupts */
 	stm32_usart_disable_ms(port);
@@ -1424,8 +1456,6 @@ static int stm32_usart_of_dma_tx_probe(struct stm32_port *stm32port,
 	struct dma_slave_config config;
 	int ret;
 
-	stm32port->tx_dma_busy = false;
-
 	stm32port->tx_buf = dma_alloc_coherent(dev, TX_BUF_L,
 					       &stm32port->tx_dma_buf,
 					       GFP_KERNEL);
diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h
index e23916bfbb60..feab952aec16 100644
--- a/drivers/tty/serial/stm32-usart.h
+++ b/drivers/tty/serial/stm32-usart.h
@@ -264,7 +264,7 @@ struct stm32_port {
 	u32 cr1_irq;		 /* USART_CR1_RXNEIE or RTOIE */
 	u32 cr3_irq;		 /* USART_CR3_RXFTIE */
 	int last_res;
-	bool tx_dma_busy;	 /* dma tx busy               */
+	bool tx_dma_busy;	 /* dma tx transaction in progress */
 	bool throttled;		 /* port throttled            */
 	bool hw_flow_control;
 	bool swap;		 /* swap RX & TX pins */
-- 
2.17.1



From ray.jui at broadcom.com  Tue Jan  4 10:34:43 2022
From: ray.jui at broadcom.com (Ray Jui)
Date: Tue, 4 Jan 2022 10:34:43 -0800
Subject: [PATCH v2 11/23] PCI: iproc: Rename iproc_pcie_bcma_ to
 iproc_bcma_pcie_
In-Reply-To: <20211223011054.1227810-12-helgaas@kernel.org>
References: <20211223011054.1227810-1-helgaas@kernel.org>
 <20211223011054.1227810-12-helgaas@kernel.org>
Message-ID: <c8c8942a-3247-4ac8-8878-9a5406480316@broadcom.com>



On 12/22/2021 5:10 PM, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> Rename iproc_pcie_bcma_* to iproc_bcma_pcie_* for consistency with other
> drivers.  No functional change intended.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Ray Jui <rjui at broadcom.com>
> Cc: Scott Branden <sbranden at broadcom.com>
> Cc: bcm-kernel-feedback-list at broadcom.com
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/pci/controller/pcie-iproc-bcma.c | 22 +++++++++++-----------
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-iproc-bcma.c b/drivers/pci/controller/pcie-iproc-bcma.c
> index f918c713afb0..54b6e6d5bc64 100644
> --- a/drivers/pci/controller/pcie-iproc-bcma.c
> +++ b/drivers/pci/controller/pcie-iproc-bcma.c
> @@ -23,7 +23,7 @@ static void bcma_pcie2_fixup_class(struct pci_dev *dev)
>  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8011, bcma_pcie2_fixup_class);
>  DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x8012, bcma_pcie2_fixup_class);
>  
> -static int iproc_pcie_bcma_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> +static int iproc_bcma_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>  {
>  	struct iproc_pcie *pcie = dev->sysdata;
>  	struct bcma_device *bdev = container_of(pcie->dev, struct bcma_device, dev);
> @@ -31,7 +31,7 @@ static int iproc_pcie_bcma_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>  	return bcma_core_irq(bdev, 5);
>  }
>  
> -static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
> +static int iproc_bcma_pcie_probe(struct bcma_device *bdev)
>  {
>  	struct device *dev = &bdev->dev;
>  	struct iproc_pcie *pcie;
> @@ -64,33 +64,33 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
>  	if (ret)
>  		return ret;
>  
> -	pcie->map_irq = iproc_pcie_bcma_map_irq;
> +	pcie->map_irq = iproc_bcma_pcie_map_irq;
>  
>  	bcma_set_drvdata(bdev, pcie);
>  
>  	return iproc_pcie_setup(pcie, &bridge->windows);
>  }
>  
> -static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
> +static void iproc_bcma_pcie_remove(struct bcma_device *bdev)
>  {
>  	struct iproc_pcie *pcie = bcma_get_drvdata(bdev);
>  
>  	iproc_pcie_remove(pcie);
>  }
>  
> -static const struct bcma_device_id iproc_pcie_bcma_table[] = {
> +static const struct bcma_device_id iproc_bcma_pcie_table[] = {
>  	BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_PCIEG2, BCMA_ANY_REV, BCMA_ANY_CLASS),
>  	{},
>  };
> -MODULE_DEVICE_TABLE(bcma, iproc_pcie_bcma_table);
> +MODULE_DEVICE_TABLE(bcma, iproc_bcma_pcie_table);
>  
> -static struct bcma_driver iproc_pcie_bcma_driver = {
> +static struct bcma_driver iproc_bcma_pcie_driver = {
>  	.name		= KBUILD_MODNAME,
> -	.id_table	= iproc_pcie_bcma_table,
> -	.probe		= iproc_pcie_bcma_probe,
> -	.remove		= iproc_pcie_bcma_remove,
> +	.id_table	= iproc_bcma_pcie_table,
> +	.probe		= iproc_bcma_pcie_probe,
> +	.remove		= iproc_bcma_pcie_remove,
>  };
> -module_bcma_driver(iproc_pcie_bcma_driver);
> +module_bcma_driver(iproc_bcma_pcie_driver);
>  
>  MODULE_AUTHOR("Hauke Mehrtens");
>  MODULE_DESCRIPTION("Broadcom iProc PCIe BCMA driver");
> 

Acked-by: Ray Jui <ray.jui at broadcom.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4194 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/b3d3af0b/attachment-0001.p7s>

From ray.jui at broadcom.com  Tue Jan  4 10:34:57 2022
From: ray.jui at broadcom.com (Ray Jui)
Date: Tue, 4 Jan 2022 10:34:57 -0800
Subject: [PATCH v2 12/23] PCI: iproc: Rename iproc_pcie_pltfm_ to
 iproc_pltfm_pcie_
In-Reply-To: <20211223011054.1227810-13-helgaas@kernel.org>
References: <20211223011054.1227810-1-helgaas@kernel.org>
 <20211223011054.1227810-13-helgaas@kernel.org>
Message-ID: <567c6e66-1baf-2942-87fc-17c5e0f4b0b9@broadcom.com>



On 12/22/2021 5:10 PM, Bjorn Helgaas wrote:
> From: Bjorn Helgaas <bhelgaas at google.com>
> 
> Rename iproc_pcie_pltfm_* to iproc_pltfm_pcie_* for consistency with other
> drivers.  No functional change intended.
> 
> Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
> Cc: Ray Jui <rjui at broadcom.com>
> Cc: Scott Branden <sbranden at broadcom.com>
> Cc: bcm-kernel-feedback-list at broadcom.com
> Cc: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/pci/controller/pcie-iproc-platform.c | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-iproc-platform.c b/drivers/pci/controller/pcie-iproc-platform.c
> index b93e7bda101b..538115246c79 100644
> --- a/drivers/pci/controller/pcie-iproc-platform.c
> +++ b/drivers/pci/controller/pcie-iproc-platform.c
> @@ -37,7 +37,7 @@ static const struct of_device_id iproc_pcie_of_match_table[] = {
>  };
>  MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table);
>  
> -static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
> +static int iproc_pltfm_pcie_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
>  	struct iproc_pcie *pcie;
> @@ -115,30 +115,30 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
>  	return 0;
>  }
>  
> -static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
> +static int iproc_pltfm_pcie_remove(struct platform_device *pdev)
>  {
>  	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
>  
>  	return iproc_pcie_remove(pcie);
>  }
>  
> -static void iproc_pcie_pltfm_shutdown(struct platform_device *pdev)
> +static void iproc_pltfm_pcie_shutdown(struct platform_device *pdev)
>  {
>  	struct iproc_pcie *pcie = platform_get_drvdata(pdev);
>  
>  	iproc_pcie_shutdown(pcie);
>  }
>  
> -static struct platform_driver iproc_pcie_pltfm_driver = {
> +static struct platform_driver iproc_pltfm_pcie_driver = {
>  	.driver = {
>  		.name = "iproc-pcie",
>  		.of_match_table = of_match_ptr(iproc_pcie_of_match_table),
>  	},
> -	.probe = iproc_pcie_pltfm_probe,
> -	.remove = iproc_pcie_pltfm_remove,
> -	.shutdown = iproc_pcie_pltfm_shutdown,
> +	.probe = iproc_pltfm_pcie_probe,
> +	.remove = iproc_pltfm_pcie_remove,
> +	.shutdown = iproc_pltfm_pcie_shutdown,
>  };
> -module_platform_driver(iproc_pcie_pltfm_driver);
> +module_platform_driver(iproc_pltfm_pcie_driver);
>  
>  MODULE_AUTHOR("Ray Jui <rjui at broadcom.com>");
>  MODULE_DESCRIPTION("Broadcom iPROC PCIe platform driver");
> 

Acked-by: Ray Jui <ray.jui at broadcom.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4194 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/c9302a1c/attachment.p7s>

From robh at kernel.org  Tue Jan  4 11:06:57 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 13:06:57 -0600
Subject: [PATCH v7 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding
 header
In-Reply-To: <20220103233948.198119-3-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-3-Mr.Bossman075@gmail.com>
Message-ID: <YdSa0ScOpb/5sMF/@robh.at.kernel.org>

On Mon, 03 Jan 2022 18:39:43 -0500, Jesse Taube wrote:
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add binding header for i.MXRT1050 pinctrl device tree.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: move pinfunc from dt-bindings to dts folder]
> ---
> V1->V2:
> * Move pinfunc from dt-binding to dts
> * Change subject and description
> * Change licence to "GPL-2.0+ OR MIT"
> V2->V3:
> * Change License comment style
> V3->V4:
> * Nothing done
> V4->V5:
> * Nothing done
> V5->V6:
> * Nothing done
> V6->V7:
> * Nothing done
> ---
>  arch/arm/boot/dts/imxrt1050-pinfunc.h | 993 ++++++++++++++++++++++++++
>  1 file changed, 993 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From robh at kernel.org  Tue Jan  4 11:07:43 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 13:07:43 -0600
Subject: [PATCH v7 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220103233948.198119-4-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-4-Mr.Bossman075@gmail.com>
Message-ID: <YdSa/7BZBDJO3J0V@robh.at.kernel.org>

On Mon, 03 Jan 2022 18:39:44 -0500, Jesse Taube wrote:
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> Add the clock binding doc for i.MXRT1050.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> [Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
> IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]
> ---
> V1->V2:
> * Nothing done
> V2->V3:
> * Added GPT binding
> V3->V4:
> * Change License to MIT or GPL-2
> V4->V5:
> * Nothing done
> V5->V6:
> * Nothing done
> V6->V7:
> * Fix typo in numbering
> * Remove GPT
> ---
>  include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++
>  1 file changed, 72 insertions(+)
>  create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From robh at kernel.org  Tue Jan  4 11:07:57 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 13:07:57 -0600
Subject: [PATCH v7 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220103233948.198119-5-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-5-Mr.Bossman075@gmail.com>
Message-ID: <YdSbDTcA6qyZdJJv@robh.at.kernel.org>

On Mon, 03 Jan 2022 18:39:45 -0500, Jesse Taube wrote:
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add DT binding documentation for i.MXRT1050 clock driver.
> 
> Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> ---
> V1->V2:
> * Replace macros with values
> V2->V3:
> * Remove anatop
> * Use lpuart not gpt
> * include imxrt1050-clock.h
> * 2 space tabs to 4
> * Remove oneOf enum
> * Change maxItems to 2
> V3->V4:
> * Nothing done
> V4->V5:
> * Remove extra newline
> * Rename ccm to clock-controller
> * Change minItems to const
> * Change minItems to description
> * Rename file to add 1050
> * Change commit description to just 1050
> V5->V6:
> * Add maxItems for clocks description
> V6->V7:
> * Nothing done
> ---
>  .../bindings/clock/imxrt1050-clock.yaml       | 67 +++++++++++++++++++
>  1 file changed, 67 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From robh at kernel.org  Tue Jan  4 11:26:18 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 13:26:18 -0600
Subject: [PATCH] dt-bindings: display: st,stm32-dsi: Fix panel node name
 in example
In-Reply-To: <20211221125145.1195234-1-robh@kernel.org>
References: <20211221125145.1195234-1-robh@kernel.org>
Message-ID: <YdSfWqj34Ragg+Yj@robh.at.kernel.org>

On Tue, 21 Dec 2021 08:51:45 -0400, Rob Herring wrote:
> With 'unevaluatedProperties' support enabled, the st,stm32-dsi binding
> has a new warning:
> 
> Documentation/devicetree/bindings/display/st,stm32-dsi.example.dt.yaml: dsi at 5a000000: Unevaluated properties are not allowed ('panel-dsi at 0' was unexpected)
> 
> The documented child node name is 'panel', so update the example.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/display/st,stm32-dsi.yaml | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Tue Jan  4 11:30:26 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 13:30:26 -0600
Subject: [PATCH v4 2/4] dt-bindings: input: Add Cypress TT2100
 touchscreen controller
In-Reply-To: <20211222124603.326920-3-alistair@alistair23.me>
References: <20211222124603.326920-1-alistair@alistair23.me>
 <20211222124603.326920-3-alistair@alistair23.me>
Message-ID: <YdSgUgdETb12TEVf@robh.at.kernel.org>

On Wed, Dec 22, 2021 at 10:46:01PM +1000, Alistair Francis wrote:
> From: Myl?ne Josserand <mylene.josserand at free-electrons.com>
> 
> Add the Cypress TrueTouch Generation 5 touchscreen device tree bindings
> documentation. It can use I2C or SPI bus.
> This touchscreen can handle some defined zone that are designed and
> sent as button. To be able to customize the keycode sent, the
> "linux,code" property in a "button" sub-node can be used.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand at free-electrons.com>
> Signed-off-by: Alistair Francis <alistair at alistair23.me>
> ---
>  .../input/touchscreen/cypress,tt21000.yaml    | 92 +++++++++++++++++++
>  1 file changed, 92 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> new file mode 100644
> index 000000000000..5a721d789c87
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> @@ -0,0 +1,92 @@
> +# SPDX-License-Identifier: GPL-2.0-only

Dual license new bindings. GPL-2.0-only OR BSD-2-Clause


> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/touchscreen/cypress,tt21000.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cypress TT2100 touchscreen controller
> +
> +description: The Cypress TT2100 series (also known as "CYTTSP5" after
> +  the marketing name Cypress TrueTouch Standard Product series 5).
> +
> +maintainers:
> +  - Alistair Francis <alistair at alistair23.me>
> +
> +allOf:
> +  - $ref: touchscreen.yaml#
> +
> +properties:
> +  compatible:
> +    const: cypress,tt21000
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  vdd-supply:
> +    description: Regulator for voltage.
> +
> +  reset-gpios:
> +    maxItems: 1
> +
> +  linux,code:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: EV_ABS specific event code generated by the axis.
> +
> +patternProperties:
> +  "^button-[0-9]+$":
> +    type: object
> +    properties:
> +      linux,code:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: Keycode to emit
> +
> +    required:
> +      - linux,code
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - vdd-supply
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/input/linux-event-codes.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        touchscreen at 24 {
> +            compatible = "cypress,tt21000";
> +            reg = <0x24>;
> +            pinctrl-names = "default";
> +            pinctrl-0 = <&tp_reset_ds203>;
> +            interrupt-parent = <&pio>;
> +            interrupts = <1 5 IRQ_TYPE_LEVEL_LOW>;
> +            reset-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>;
> +            vdd-supply = <&reg_touch>;
> +
> +            button-0 {
> +                linux,code = <KEY_HOMEPAGE>;
> +            };
> +
> +            button-1 {
> +                linux,code = <KEY_MENU>;
> +            };
> +
> +            button-2 {
> +                linux,code = <KEY_BACK>;
> +            };
> +        };
> +    };
> +...
> -- 
> 2.31.1
> 
> 


From mike.rudenko at gmail.com  Tue Jan  4 11:37:18 2022
From: mike.rudenko at gmail.com (Mikhail Rudenko)
Date: Tue,  4 Jan 2022 22:37:18 +0300
Subject: [PATCH] ARM: dts: nanopi-neo-air: Add eMMC and bluetooth
Message-ID: <20220104193719.87091-1-mike.rudenko@gmail.com>

Enable the bluetooth part of AP6212 chip (connected to UART3) and the
onboard eMMC (connected to MMC2) for the NanoPi NEO Air board.

Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
---
 arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
index be49eabbff94..cd3df12b6573 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo-air.dts
@@ -103,12 +103,40 @@ brcmf: bcrmf at 1 {
 	};
 };
 
+&mmc2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&mmc2_8bit_pins>;
+	vmmc-supply = <&reg_vcc3v3>;
+	vqmmc-supply = <&reg_vcc3v3>;
+	bus-width = <8>;
+	non-removable;
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pa_pins>;
 	status = "okay";
 };
 
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart3_pins>, <&uart3_rts_cts_pins>;
+	uart-has-rtscts;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		clocks = <&rtc 1>;
+		clock-names = "lpo";
+		vbat-supply = <&reg_vcc3v3>;
+		vddio-supply = <&reg_vcc3v3>;
+		device-wakeup-gpios = <&pio 0 8 GPIO_ACTIVE_HIGH>; /* PA8 */
+		host-wakeup-gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA7 */
+		shutdown-gpios = <&pio 6 13 GPIO_ACTIVE_HIGH>; /* PG13 */
+	};
+};
+
 &usbphy {
 	/* USB VBUS is always on */
 	status = "okay";
-- 
2.34.1



From rananta at google.com  Tue Jan  4 11:49:07 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:07 +0000
Subject: [RFC PATCH v3 00/11] KVM: arm64: Add support for hypercall services
 selection
Message-ID: <20220104194918.373612-1-rananta@google.com>

Hello,

Continuing the discussion from [1], the series tries to add support
for the user-space to elect the hypercall services that it wishes
to expose to the guest, rather than the guest discovering them
unconditionally. The idea employed by the series was taken from
[1] as suggested by Marc Z.

In a broad sense, the idea is similar to the current implementation
of PSCI interface- create a 'firmware psuedo-register' to handle the
firmware revisions. The series extends this idea to all the other
hypercalls such as TRNG (True Random Number Generator), PV_TIME
(Paravirtualized Time), and PTP (Precision Time protocol).

For better categorization and future scaling, these firmware registers
are categorized based on the service call owners, but unlike the
existing firmware psuedo-registers, they hold the features supported
in the form of a bitmap.

The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is introduced to announce
this extension, which returns the number of psuedo-firmware
registers supported. During the VM initialization, the registers
holds an upper-limit of the features supported by each one of them.
It's expected that the VMMs discover the features provided by each
register via GET_ONE_REG, and writeback the desired values using
SET_ONE_REG. KVM allows this modification only until the VM has started.

Older VMMs can simply ignore the capability and the hypercall services
will be exposed unconditionally to the guests, thus ensuring backward
compatibility.

The patches are based off of mainline kernel 5.16-rc8, with the selftest
patches from [2] applied.

Patch-1 tracks if the VM has started running, which would be used in the
upcoming patches.

Patch-2 factors out the non-PSCI related interface from psci.c to
hypercalls.c, as the series would extend the list in the upcoming
patches.

Patch-3 introduces the KVM_CAP_ARM_HVC_FW_REG_BMAP capability
definition.

Patch-4 sets up the framework for the bitmap firmware psuedo-registers.
It includes read/write helpers for the registers, and a helper to check
if a particular hypercall service is supported for the guest.
It also adds the register KVM_REG_ARM_STD_HYP_BMAP to support ARM's
standard secure services.

Patch-5 introduces the firmware register, KVM_REG_ARM_STD_HYP_BMAP,
which holds the standard hypervisor services (such as PV_TIME).

Patch-6 introduces the firmware register, KVM_REG_ARM_VENDOR_HYP_BMAP,
which holds the vendor specific hypercall services.

Patch-7,8 Add the necessary documentation for the newly added firmware
registers.

Patch-9 imports the SMCCC definitions from linux/arm-smccc.h into tools/
for further use in selftests.

Patch-10 adds the selftest to test the guest (using 'hvc') and VMM
interfaces (SET/GET_ONE_REG).

Patch-11 adds these firmware registers into the get-reg-list selftest.

[1]: https://lore.kernel.org/kvmarm/874kbcpmlq.wl-maz at kernel.org/T/
[2]: https://lore.kernel.org/kvmarm/YUzgdbYk8BeCnHyW at google.com/

Regards,
Raghavendra

v2 -> v3

Addressed comments by Marc and Andrew:

- Dropped kvm_vcpu_has_run_once() implementation.
- Redifined kvm_vm_has_run_once() as kvm_vm_has_started() in the core
  KVM code that introduces a new field, 'vm_started', to track this.
- KVM_CAP_ARM_HVC_FW_REG_BMAP returns the number of psuedo-firmware
  bitmap registers upon a 'read'. Support for 'write' removed.
- Removed redundant spinlock, 'fw_reg_bmap_enabled' fields from the
  hypercall descriptor structure.
- A separate sub-struct to hold the bitmap info is removed. The bitmap
  info is directly stored in the hypercall descriptor structure
  (struct kvm_hvc_desc).

v1 -> v2

Addressed comments by Oliver (thanks!):

- Introduced kvm_vcpu_has_run_once() and kvm_vm_has_run_once() in the
  core kvm code, rather than relying on ARM specific vcpu->arch.has_run_once.
- Writing to KVM_REG_ARM_PSCI_VERSION is done in hypercalls.c itself,
  rather than separating out to psci.c.
- Introduced KVM_CAP_ARM_HVC_FW_REG_BMAP to enable the extension.
- Tracks the register accesses from VMM to decide whether to sanitize
  a register or not, as opposed to sanitizing upon the first 'write'
  in v1.
- kvm_hvc_call_supported() is implemented using a direct switch-case
  statement, instead of looping over all the registers to pick the
  register for the function-id.
- Replaced the register bit definitions with #defines, instead of enums.
- Removed the patch v1-06/08 that imports the firmware register
  definitions as it's not needed.
- Separated out the documentations in its own patch, and the renaming
  of hypercalls.rst to psci.rst into another patch.
- Add the new firmware registers to get-reg-list KVM selftest.

v1: https://lore.kernel.org/kvmarm/20211102002203.1046069-1-rananta at google.com/
v2: https://lore.kernel.org/kvmarm/20211113012234.1443009-1-rananta at google.com/

Raghavendra Rao Ananta (11):
  KVM: Capture VM start
  KVM: arm64: Factor out firmware register handling from psci.c
  KVM: Introduce KVM_CAP_ARM_HVC_FW_REG_BMAP
  KVM: arm64: Setup a framework for hypercall bitmap firmware registers
  KVM: arm64: Add standard hypervisor firmware register
  KVM: arm64: Add vendor hypervisor firmware register
  Docs: KVM: Add doc for the bitmap firmware registers
  Docs: KVM: Rename psci.rst to hypercalls.rst
  tools: Import ARM SMCCC definitions
  selftests: KVM: aarch64: Introduce hypercall ABI test
  selftests: KVM: aarch64: Add the bitmap firmware registers to
    get-reg-list

 Documentation/virt/kvm/api.rst                |  21 +
 Documentation/virt/kvm/arm/hypercalls.rst     | 128 +++++++
 Documentation/virt/kvm/arm/psci.rst           |  77 ----
 arch/arm64/include/asm/kvm_host.h             |  16 +
 arch/arm64/include/uapi/asm/kvm.h             |  12 +
 arch/arm64/kvm/arm.c                          |   4 +
 arch/arm64/kvm/guest.c                        |   2 +-
 arch/arm64/kvm/hypercalls.c                   | 311 ++++++++++++++-
 arch/arm64/kvm/psci.c                         | 166 --------
 arch/arm64/kvm/pvtime.c                       |   3 +
 arch/arm64/kvm/trng.c                         |   8 +-
 include/kvm/arm_hypercalls.h                  |  19 +
 include/kvm/arm_psci.h                        |   7 -
 include/linux/kvm_host.h                      |   3 +
 include/uapi/linux/kvm.h                      |   1 +
 tools/include/linux/arm-smccc.h               | 188 +++++++++
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/aarch64/get-reg-list.c      |   3 +
 .../selftests/kvm/aarch64/hypercalls.c        | 358 ++++++++++++++++++
 virt/kvm/kvm_main.c                           |   9 +
 21 files changed, 1078 insertions(+), 260 deletions(-)
 create mode 100644 Documentation/virt/kvm/arm/hypercalls.rst
 delete mode 100644 Documentation/virt/kvm/arm/psci.rst
 create mode 100644 tools/include/linux/arm-smccc.h
 create mode 100644 tools/testing/selftests/kvm/aarch64/hypercalls.c

-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:08 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:08 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-2-rananta@google.com>

Capture the start of the KVM VM, which is basically the
start of any vCPU run. This state of the VM is helpful
in the upcoming patches to prevent user-space from
configuring certain VM features after the VM has started
running.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 include/linux/kvm_host.h | 3 +++
 virt/kvm/kvm_main.c      | 9 +++++++++
 2 files changed, 12 insertions(+)

diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index c310648cc8f1..d0bd8f7a026c 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -623,6 +623,7 @@ struct kvm {
 	struct notifier_block pm_notifier;
 #endif
 	char stats_id[KVM_STATS_NAME_SIZE];
+	bool vm_started;
 };
 
 #define kvm_err(fmt, ...) \
@@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
 	}
 }
 
+#define kvm_vm_has_started(kvm) (kvm->vm_started)
+
 extern bool kvm_rebooting;
 
 extern unsigned int halt_poll_ns;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 72c4e6b39389..962b91ac2064 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
 	int r;
 	struct kvm_fpu *fpu = NULL;
 	struct kvm_sregs *kvm_sregs = NULL;
+	struct kvm *kvm = vcpu->kvm;
 
 	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
 		return -EIO;
@@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
 			if (oldpid)
 				synchronize_rcu();
 			put_pid(oldpid);
+
+			/*
+			 * Since we land here even on the first vCPU run,
+			 * we can mark that the VM has started running.
+			 */
+			mutex_lock(&kvm->lock);
+			kvm->vm_started = true;
+			mutex_unlock(&kvm->lock);
 		}
 		r = kvm_arch_vcpu_ioctl_run(vcpu);
 		trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:09 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:09 +0000
Subject: [RFC PATCH v3 02/11] KVM: arm64: Factor out firmware register
 handling from psci.c
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-3-rananta@google.com>

Common hypercall firmware register handing is currently employed
by psci.c. Since the upcoming patches add more of these registers,
it's better to move the generic handling to hypercall.c for a
cleaner presentation.

While we are at it, collect all the firmware registers under
fw_reg_ids[] to help implement kvm_arm_get_fw_num_regs() and
kvm_arm_copy_fw_reg_indices() in a generic way.

No functional change intended.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/kvm/guest.c       |   2 +-
 arch/arm64/kvm/hypercalls.c  | 170 +++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/psci.c        | 166 ----------------------------------
 include/kvm/arm_hypercalls.h |   7 ++
 include/kvm/arm_psci.h       |   7 --
 5 files changed, 178 insertions(+), 174 deletions(-)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index e116c7767730..8238e52d890d 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -18,7 +18,7 @@
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 #include <linux/fs.h>
-#include <kvm/arm_psci.h>
+#include <kvm/arm_hypercalls.h>
 #include <asm/cputype.h>
 #include <linux/uaccess.h>
 #include <asm/fpsimd.h>
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..3c2fcf31ad3d 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -146,3 +146,173 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 	smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
 	return 1;
 }
+
+static const u64 kvm_arm_fw_reg_ids[] = {
+	KVM_REG_ARM_PSCI_VERSION,
+	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1,
+	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
+};
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
+{
+	return ARRAY_SIZE(kvm_arm_fw_reg_ids);
+}
+
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_ids); i++) {
+		if (put_user(kvm_arm_fw_reg_ids[i], uindices++))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+#define KVM_REG_FEATURE_LEVEL_WIDTH	4
+#define KVM_REG_FEATURE_LEVEL_MASK	(BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1)
+
+/*
+ * Convert the workaround level into an easy-to-compare number, where higher
+ * values mean better protection.
+ */
+static int get_kernel_wa_level(u64 regid)
+{
+	switch (regid) {
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
+		switch (arm64_get_spectre_v2_state()) {
+		case SPECTRE_VULNERABLE:
+			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
+		case SPECTRE_MITIGATED:
+			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL;
+		case SPECTRE_UNAFFECTED:
+			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED;
+		}
+		return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
+		switch (arm64_get_spectre_v4_state()) {
+		case SPECTRE_MITIGATED:
+			/*
+			 * As for the hypercall discovery, we pretend we
+			 * don't have any FW mitigation if SSBS is there at
+			 * all times.
+			 */
+			if (cpus_have_final_cap(ARM64_SSBS))
+				return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
+			fallthrough;
+		case SPECTRE_UNAFFECTED:
+			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
+		case SPECTRE_VULNERABLE:
+			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
+		}
+	}
+
+	return -EINVAL;
+}
+
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	void __user *uaddr = (void __user *)(long)reg->addr;
+	u64 val;
+
+	switch (reg->id) {
+	case KVM_REG_ARM_PSCI_VERSION:
+		val = kvm_psci_version(vcpu, vcpu->kvm);
+		break;
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
+		val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
+		return -EFAULT;
+
+	return 0;
+}
+
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
+{
+	void __user *uaddr = (void __user *)(long)reg->addr;
+	u64 val;
+	int wa_level;
+
+	if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
+		return -EFAULT;
+
+	switch (reg->id) {
+	case KVM_REG_ARM_PSCI_VERSION:
+	{
+		bool wants_02;
+
+		wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
+
+		switch (val) {
+		case KVM_ARM_PSCI_0_1:
+			if (wants_02)
+				return -EINVAL;
+			vcpu->kvm->arch.psci_version = val;
+			return 0;
+		case KVM_ARM_PSCI_0_2:
+		case KVM_ARM_PSCI_1_0:
+			if (!wants_02)
+				return -EINVAL;
+			vcpu->kvm->arch.psci_version = val;
+			return 0;
+		}
+		break;
+	}
+
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
+		if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
+			return -EINVAL;
+
+		if (get_kernel_wa_level(reg->id) < val)
+			return -EINVAL;
+
+		return 0;
+
+	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
+		if (val & ~(KVM_REG_FEATURE_LEVEL_MASK |
+			    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED))
+			return -EINVAL;
+
+		/* The enabled bit must not be set unless the level is AVAIL. */
+		if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) &&
+		    (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL)
+			return -EINVAL;
+
+		/*
+		 * Map all the possible incoming states to the only two we
+		 * really want to deal with.
+		 */
+		switch (val & KVM_REG_FEATURE_LEVEL_MASK) {
+		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
+		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
+			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
+			break;
+		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
+		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
+			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
+			break;
+		default:
+			return -EINVAL;
+		}
+
+		/*
+		 * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
+		 * other way around.
+		 */
+		if (get_kernel_wa_level(reg->id) < wa_level)
+			return -EINVAL;
+
+		return 0;
+	default:
+		return -ENOENT;
+	}
+
+	return -EINVAL;
+}
diff --git a/arch/arm64/kvm/psci.c b/arch/arm64/kvm/psci.c
index 74c47d420253..6c8323ae32f2 100644
--- a/arch/arm64/kvm/psci.c
+++ b/arch/arm64/kvm/psci.c
@@ -403,169 +403,3 @@ int kvm_psci_call(struct kvm_vcpu *vcpu)
 		return -EINVAL;
 	};
 }
-
-int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
-{
-	return 3;		/* PSCI version and two workaround registers */
-}
-
-int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
-{
-	if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices++))
-		return -EFAULT;
-
-	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, uindices++))
-		return -EFAULT;
-
-	if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++))
-		return -EFAULT;
-
-	return 0;
-}
-
-#define KVM_REG_FEATURE_LEVEL_WIDTH	4
-#define KVM_REG_FEATURE_LEVEL_MASK	(BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1)
-
-/*
- * Convert the workaround level into an easy-to-compare number, where higher
- * values mean better protection.
- */
-static int get_kernel_wa_level(u64 regid)
-{
-	switch (regid) {
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
-		switch (arm64_get_spectre_v2_state()) {
-		case SPECTRE_VULNERABLE:
-			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
-		case SPECTRE_MITIGATED:
-			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL;
-		case SPECTRE_UNAFFECTED:
-			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED;
-		}
-		return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL;
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
-		switch (arm64_get_spectre_v4_state()) {
-		case SPECTRE_MITIGATED:
-			/*
-			 * As for the hypercall discovery, we pretend we
-			 * don't have any FW mitigation if SSBS is there at
-			 * all times.
-			 */
-			if (cpus_have_final_cap(ARM64_SSBS))
-				return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
-			fallthrough;
-		case SPECTRE_UNAFFECTED:
-			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
-		case SPECTRE_VULNERABLE:
-			return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
-		}
-	}
-
-	return -EINVAL;
-}
-
-int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
-{
-	void __user *uaddr = (void __user *)(long)reg->addr;
-	u64 val;
-
-	switch (reg->id) {
-	case KVM_REG_ARM_PSCI_VERSION:
-		val = kvm_psci_version(vcpu, vcpu->kvm);
-		break;
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
-		val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
-		break;
-	default:
-		return -ENOENT;
-	}
-
-	if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)))
-		return -EFAULT;
-
-	return 0;
-}
-
-int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
-{
-	void __user *uaddr = (void __user *)(long)reg->addr;
-	u64 val;
-	int wa_level;
-
-	if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id)))
-		return -EFAULT;
-
-	switch (reg->id) {
-	case KVM_REG_ARM_PSCI_VERSION:
-	{
-		bool wants_02;
-
-		wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features);
-
-		switch (val) {
-		case KVM_ARM_PSCI_0_1:
-			if (wants_02)
-				return -EINVAL;
-			vcpu->kvm->arch.psci_version = val;
-			return 0;
-		case KVM_ARM_PSCI_0_2:
-		case KVM_ARM_PSCI_1_0:
-			if (!wants_02)
-				return -EINVAL;
-			vcpu->kvm->arch.psci_version = val;
-			return 0;
-		}
-		break;
-	}
-
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1:
-		if (val & ~KVM_REG_FEATURE_LEVEL_MASK)
-			return -EINVAL;
-
-		if (get_kernel_wa_level(reg->id) < val)
-			return -EINVAL;
-
-		return 0;
-
-	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
-		if (val & ~(KVM_REG_FEATURE_LEVEL_MASK |
-			    KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED))
-			return -EINVAL;
-
-		/* The enabled bit must not be set unless the level is AVAIL. */
-		if ((val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED) &&
-		    (val & KVM_REG_FEATURE_LEVEL_MASK) != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL)
-			return -EINVAL;
-
-		/*
-		 * Map all the possible incoming states to the only two we
-		 * really want to deal with.
-		 */
-		switch (val & KVM_REG_FEATURE_LEVEL_MASK) {
-		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL:
-		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN:
-			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL;
-			break;
-		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL:
-		case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
-			wa_level = KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED;
-			break;
-		default:
-			return -EINVAL;
-		}
-
-		/*
-		 * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the
-		 * other way around.
-		 */
-		if (get_kernel_wa_level(reg->id) < wa_level)
-			return -EINVAL;
-
-		return 0;
-	default:
-		return -ENOENT;
-	}
-
-	return -EINVAL;
-}
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 0e2509d27910..5d38628a8d04 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -40,4 +40,11 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
 	vcpu_set_reg(vcpu, 3, a3);
 }
 
+struct kvm_one_reg;
+
+int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
+int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
+int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+
 #endif
diff --git a/include/kvm/arm_psci.h b/include/kvm/arm_psci.h
index 5b58bd2fe088..080c2d0bd6e7 100644
--- a/include/kvm/arm_psci.h
+++ b/include/kvm/arm_psci.h
@@ -42,11 +42,4 @@ static inline int kvm_psci_version(struct kvm_vcpu *vcpu, struct kvm *kvm)
 
 int kvm_psci_call(struct kvm_vcpu *vcpu);
 
-struct kvm_one_reg;
-
-int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
-int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
-int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
-int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
-
 #endif /* __KVM_ARM_PSCI_H__ */
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:10 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:10 +0000
Subject: [RFC PATCH v3 03/11] KVM: Introduce KVM_CAP_ARM_HVC_FW_REG_BMAP
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-4-rananta@google.com>

Introduce the KVM ARM64 capability, KVM_CAP_ARM_HVC_FW_REG_BMAP,
to indicate the support for psuedo-firmware bitmap extension.
Each of these registers holds a feature-set exposed to the guest
in the form of a bitmap. If supported, a simple 'read' of the
capability should return the number of psuedo-firmware registers
supported. User-space can utilize this to discover the registers.
It can further explore or modify the features using the classical
GET/SET_ONE_REG interface.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
 include/uapi/linux/kvm.h       |  1 +
 2 files changed, 22 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index aeeb071c7688..646176537f2c 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -6925,6 +6925,27 @@ indicated by the fd to the VM this is called on.
 This is intended to support intra-host migration of VMs between userspace VMMs,
 upgrading the VMM process without interrupting the guest.
 
+7.30 KVM_CAP_ARM_HVC_FW_REG_BMAP
+--------------------------------
+
+:Architectures: arm64
+:Parameters: None
+:Returns: Number of psuedo-firmware registers supported
+
+This capability indicates that KVM for arm64 supports the psuedo-firmware
+register bitmap extension. Each of these registers represent the features
+supported by a particular type in the form of a bitmap. By default, these
+registers are set with the upper limit of the features that are supported.
+
+The registers can be accessed via the standard SET_ONE_REG and KVM_GET_ONE_REG
+interfaces. The user-space is expected to read the number of these registers
+available by reading KVM_CAP_ARM_HVC_FW_REG_BMAP, read the current bitmap
+configuration via GET_ONE_REG for each register, and then write back the
+desired bitmap of features that it wishes the guest to see via SET_ONE_REG.
+
+Note that KVM doesn't allow the user-space to modify these registers after
+the VM (any of the vCPUs) has started running.
+
 8. Other capabilities.
 ======================
 
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 1daa45268de2..209b43dbbc3c 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1131,6 +1131,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_ARM_HVC_FW_REG_BMAP 207
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:11 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:11 +0000
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-5-rananta@google.com>

KVM regularly introduces new hypercall services to the guests without
any consent from the Virtual Machine Manager (VMM). This means, the
guests can observe hypercall services in and out as they migrate
across various host kernel versions. This could be a major problem
if the guest discovered a hypercall, started using it, and after
getting migrated to an older kernel realizes that it's no longer
available. Depending on how the guest handles the change, there's
a potential chance that the guest would just panic.

As a result, there's a need for the VMM to elect the services that
it wishes the guest to discover. VMM can elect these services based
on the kernels spread across its (migration) fleet. To remedy this,
extend the existing firmware psuedo-registers, such as
KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.

These firmware registers are categorized based on the service call
owners, and unlike the existing firmware psuedo-registers, they hold
the features supported in the form of a bitmap.

The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
this extension, which returns the number of psuedo-firmware
registers supported. During the VM initialization, the registers
holds an upper-limit of the features supported by the corresponding
registers. It's expected that the VMMs discover the features
provided by each register via GET_ONE_REG, and writeback the
desired values using SET_ONE_REG. KVM allows this modification
only until the VM has started.

Older VMMs can simply ignore the capability and the hypercall services
will be exposed unconditionally to the guests, thus ensuring backward
compatibility.

In this patch, the framework adds the register only for ARM's standard
secure services (owner value 4). Currently, this includes support only
for ARM True Random Number Generator (TRNG) service, with bit-0 of the
register representing mandatory features of v1.0. Other services are
momentarily added in the upcoming patches.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  12 ++++
 arch/arm64/include/uapi/asm/kvm.h |   4 ++
 arch/arm64/kvm/arm.c              |   4 ++
 arch/arm64/kvm/hypercalls.c       | 103 +++++++++++++++++++++++++++++-
 arch/arm64/kvm/trng.c             |   8 +--
 include/kvm/arm_hypercalls.h      |   6 ++
 6 files changed, 129 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2a5f7f38006f..a32cded0371b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -102,6 +102,15 @@ struct kvm_s2_mmu {
 struct kvm_arch_memory_slot {
 };
 
+/**
+ * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
+ *
+ * @hvc_std_bmap: Bitmap of standard secure service calls
+ */
+struct kvm_hvc_desc {
+	u64 hvc_std_bmap;
+};
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -137,6 +146,9 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+
+	/* Hypercall firmware register' descriptor */
+	struct kvm_hvc_desc hvc_desc;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..0d6f29c58456 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -281,6 +281,10 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED	3
 #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED     	(1U << 4)
 
+#define KVM_REG_ARM_STD_BMAP			KVM_REG_ARM_FW_REG(3)
+#define KVM_REG_ARM_STD_BIT_TRNG_V1_0		BIT(0)
+#define KVM_REG_ARM_STD_BMAP_BIT_MAX		0       /* Last valid bit */
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e4727dc771bf..56fe81565235 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
 
 	set_default_spectre(kvm);
+	kvm_arm_init_hypercalls(kvm);
 
 	return ret;
 out_free_stage2_pgd:
@@ -283,6 +284,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_PTRAUTH_GENERIC:
 		r = system_has_full_ptr_auth();
 		break;
+	case KVM_CAP_ARM_HVC_FW_REG_BMAP:
+		r = kvm_arm_num_fw_bmap_regs();
+		break;
 	default:
 		r = 0;
 	}
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 3c2fcf31ad3d..06243e4670eb 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -58,6 +58,29 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
 	val[3] = lower_32_bits(cycles);
 }
 
+static bool kvm_arm_fw_reg_feat_enabled(u64 reg_bmap, u64 feat_bit)
+{
+	return reg_bmap & feat_bit;
+}
+
+bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
+{
+	struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
+
+	switch (func_id) {
+	case ARM_SMCCC_TRNG_VERSION:
+	case ARM_SMCCC_TRNG_FEATURES:
+	case ARM_SMCCC_TRNG_GET_UUID:
+	case ARM_SMCCC_TRNG_RND32:
+	case ARM_SMCCC_TRNG_RND64:
+		return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
+						KVM_REG_ARM_STD_BIT_TRNG_V1_0);
+	default:
+		/* By default, allow the services that aren't listed here */
+		return true;
+	}
+}
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 {
 	u32 func_id = smccc_get_function(vcpu);
@@ -65,6 +88,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 	u32 feature;
 	gpa_t gpa;
 
+	if (!kvm_hvc_call_supported(vcpu, func_id))
+		goto out;
+
 	switch (func_id) {
 	case ARM_SMCCC_VERSION_FUNC_ID:
 		val[0] = ARM_SMCCC_VERSION_1_1;
@@ -143,6 +169,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 		return kvm_psci_call(vcpu);
 	}
 
+out:
 	smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
 	return 1;
 }
@@ -153,9 +180,25 @@ static const u64 kvm_arm_fw_reg_ids[] = {
 	KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
 };
 
+static const u64 kvm_arm_fw_reg_bmap_ids[] = {
+	KVM_REG_ARM_STD_BMAP,
+};
+
+void kvm_arm_init_hypercalls(struct kvm *kvm)
+{
+	struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
+
+	hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
+}
+
+int kvm_arm_num_fw_bmap_regs(void)
+{
+	return ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids);
+}
+
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
 {
-	return ARRAY_SIZE(kvm_arm_fw_reg_ids);
+	return ARRAY_SIZE(kvm_arm_fw_reg_ids) + kvm_arm_num_fw_bmap_regs();
 }
 
 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
@@ -167,6 +210,11 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 			return -EFAULT;
 	}
 
+	for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids); i++) {
+		if (put_user(kvm_arm_fw_reg_bmap_ids[i], uindices++))
+			return -EFAULT;
+	}
+
 	return 0;
 }
 
@@ -211,9 +259,20 @@ static int get_kernel_wa_level(u64 regid)
 	return -EINVAL;
 }
 
+static void
+kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
+{
+	struct kvm *kvm = vcpu->kvm;
+
+	mutex_lock(&kvm->lock);
+	*val = fw_reg_bmap;
+	mutex_unlock(&kvm->lock);
+}
+
 int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
 	void __user *uaddr = (void __user *)(long)reg->addr;
+	struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
 	u64 val;
 
 	switch (reg->id) {
@@ -224,6 +283,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
 		val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
 		break;
+	case KVM_REG_ARM_STD_BMAP:
+		kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -234,6 +296,43 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	return 0;
 }
 
+static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
+{
+	int ret = 0;
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
+	u64 *fw_reg_bmap, fw_reg_features;
+
+	switch (reg_id) {
+	case KVM_REG_ARM_STD_BMAP:
+		fw_reg_bmap = &hvc_desc->hvc_std_bmap;
+		fw_reg_features = ARM_SMCCC_STD_FEATURES;
+		break;
+	default:
+		return -ENOENT;
+	}
+
+	/* Check for unsupported bit */
+	if (val & ~fw_reg_features)
+		return -EINVAL;
+
+	mutex_lock(&kvm->lock);
+
+	/*
+	 * If the VM (any vCPU) has already started running, return success
+	 * if there's no change in the value. Else, return -EBUSY.
+	 */
+	if (kvm_vm_has_started(kvm)) {
+		ret = *fw_reg_bmap != val ? -EBUSY : 0;
+		goto out;
+	}
+
+	*fw_reg_bmap = val;
+out:
+	mutex_unlock(&kvm->lock);
+	return ret;
+}
+
 int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 {
 	void __user *uaddr = (void __user *)(long)reg->addr;
@@ -310,6 +409,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 			return -EINVAL;
 
 		return 0;
+	case KVM_REG_ARM_STD_BMAP:
+		return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
 	default:
 		return -ENOENT;
 	}
diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c
index 99bdd7103c9c..23f912514b06 100644
--- a/arch/arm64/kvm/trng.c
+++ b/arch/arm64/kvm/trng.c
@@ -60,14 +60,8 @@ int kvm_trng_call(struct kvm_vcpu *vcpu)
 		val = ARM_SMCCC_TRNG_VERSION_1_0;
 		break;
 	case ARM_SMCCC_TRNG_FEATURES:
-		switch (smccc_get_arg1(vcpu)) {
-		case ARM_SMCCC_TRNG_VERSION:
-		case ARM_SMCCC_TRNG_FEATURES:
-		case ARM_SMCCC_TRNG_GET_UUID:
-		case ARM_SMCCC_TRNG_RND32:
-		case ARM_SMCCC_TRNG_RND64:
+		if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu)))
 			val = TRNG_SUCCESS;
-		}
 		break;
 	case ARM_SMCCC_TRNG_GET_UUID:
 		smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]),
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 5d38628a8d04..8fe68d8d6d96 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -6,6 +6,9 @@
 
 #include <asm/kvm_emulate.h>
 
+#define ARM_SMCCC_STD_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
@@ -42,9 +45,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
 
 struct kvm_one_reg;
 
+void kvm_arm_init_hypercalls(struct kvm *kvm);
+int kvm_arm_num_fw_bmap_regs(void);
 int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
 int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
 int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
 int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
+bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id);
 
 #endif
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:12 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:12 +0000
Subject: [RFC PATCH v3 05/11] KVM: arm64: Add standard hypervisor firmware
 register
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-6-rananta@google.com>

Introduce the firmware register to hold the standard hypervisor
service calls (owner value 5) as a bitmap. The bitmap represents
the features that'll be enabled for the guest, as configured by
the user-space. Currently, this includes support only for
Paravirtualized time, represented by bit-0.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 ++
 arch/arm64/include/uapi/asm/kvm.h |  4 ++++
 arch/arm64/kvm/hypercalls.c       | 17 ++++++++++++++++-
 arch/arm64/kvm/pvtime.c           |  3 +++
 include/kvm/arm_hypercalls.h      |  3 +++
 5 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a32cded0371b..1daf2c0b3b85 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -106,9 +106,11 @@ struct kvm_arch_memory_slot {
  * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
  *
  * @hvc_std_bmap: Bitmap of standard secure service calls
+ * @hvc_std_hyp_bmap: Bitmap of standard hypervisor service calls
  */
 struct kvm_hvc_desc {
 	u64 hvc_std_bmap;
+	u64 hvc_std_hyp_bmap;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 0d6f29c58456..af59c434ae33 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -285,6 +285,10 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_STD_BIT_TRNG_V1_0		BIT(0)
 #define KVM_REG_ARM_STD_BMAP_BIT_MAX		0       /* Last valid bit */
 
+#define KVM_REG_ARM_STD_HYP_BMAP		KVM_REG_ARM_FW_REG(4)
+#define KVM_REG_ARM_STD_HYP_BIT_PV_TIME		BIT(0)
+#define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX	0       /* Last valid bit */
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 06243e4670eb..9df0221834a3 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -75,6 +75,10 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 	case ARM_SMCCC_TRNG_RND64:
 		return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
 						KVM_REG_ARM_STD_BIT_TRNG_V1_0);
+	case ARM_SMCCC_HV_PV_TIME_FEATURES:
+	case ARM_SMCCC_HV_PV_TIME_ST:
+		return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_hyp_bmap,
+					KVM_REG_ARM_STD_HYP_BIT_PV_TIME);
 	default:
 		/* By default, allow the services that aren't listed here */
 		return true;
@@ -134,7 +138,8 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 			}
 			break;
 		case ARM_SMCCC_HV_PV_TIME_FEATURES:
-			val[0] = SMCCC_RET_SUCCESS;
+			if (kvm_hvc_call_supported(vcpu, feature))
+				val[0] = SMCCC_RET_SUCCESS;
 			break;
 		}
 		break;
@@ -182,6 +187,7 @@ static const u64 kvm_arm_fw_reg_ids[] = {
 
 static const u64 kvm_arm_fw_reg_bmap_ids[] = {
 	KVM_REG_ARM_STD_BMAP,
+	KVM_REG_ARM_STD_HYP_BMAP,
 };
 
 void kvm_arm_init_hypercalls(struct kvm *kvm)
@@ -189,6 +195,7 @@ void kvm_arm_init_hypercalls(struct kvm *kvm)
 	struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
 
 	hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
+	hvc_desc->hvc_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
 }
 
 int kvm_arm_num_fw_bmap_regs(void)
@@ -286,6 +293,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_STD_BMAP:
 		kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
 		break;
+	case KVM_REG_ARM_STD_HYP_BMAP:
+		kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_hyp_bmap, &val);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -308,6 +318,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
 		fw_reg_bmap = &hvc_desc->hvc_std_bmap;
 		fw_reg_features = ARM_SMCCC_STD_FEATURES;
 		break;
+	case KVM_REG_ARM_STD_HYP_BMAP:
+		fw_reg_bmap = &hvc_desc->hvc_std_hyp_bmap;
+		fw_reg_features = ARM_SMCCC_STD_HYP_FEATURES;
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -410,6 +424,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 
 		return 0;
 	case KVM_REG_ARM_STD_BMAP:
+	case KVM_REG_ARM_STD_HYP_BMAP:
 		return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
 	default:
 		return -ENOENT;
diff --git a/arch/arm64/kvm/pvtime.c b/arch/arm64/kvm/pvtime.c
index 78a09f7a6637..4fa436dbd0b7 100644
--- a/arch/arm64/kvm/pvtime.c
+++ b/arch/arm64/kvm/pvtime.c
@@ -37,6 +37,9 @@ long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu)
 	u32 feature = smccc_get_arg1(vcpu);
 	long val = SMCCC_RET_NOT_SUPPORTED;
 
+	if (!kvm_hvc_call_supported(vcpu, feature))
+		return val;
+
 	switch (feature) {
 	case ARM_SMCCC_HV_PV_TIME_FEATURES:
 	case ARM_SMCCC_HV_PV_TIME_ST:
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 8fe68d8d6d96..1a79b5f89a24 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -9,6 +9,9 @@
 #define ARM_SMCCC_STD_FEATURES \
 	GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
 
+#define ARM_SMCCC_STD_HYP_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:13 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:13 +0000
Subject: [RFC PATCH v3 06/11] KVM: arm64: Add vendor hypervisor firmware
 register
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-7-rananta@google.com>

Introduce the firmware register to hold the vendor specific
hypervisor service calls (owner value 6) as a bitmap. The
bitmap represents the features that'll be enabled for the
guest, as configured by the user-space. Currently, this
includes support only for Precision Time Protocol (PTP),
represented by bit-0.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 ++
 arch/arm64/include/uapi/asm/kvm.h |  4 ++++
 arch/arm64/kvm/hypercalls.c       | 23 ++++++++++++++++++++++-
 include/kvm/arm_hypercalls.h      |  3 +++
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 1daf2c0b3b85..877096737ee1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -107,10 +107,12 @@ struct kvm_arch_memory_slot {
  *
  * @hvc_std_bmap: Bitmap of standard secure service calls
  * @hvc_std_hyp_bmap: Bitmap of standard hypervisor service calls
+ * @hvc_vendor_hyp_bmap: Bitmap of vendor specific hypervisor service calls
  */
 struct kvm_hvc_desc {
 	u64 hvc_std_bmap;
 	u64 hvc_std_hyp_bmap;
+	u64 hvc_vendor_hyp_bmap;
 };
 
 struct kvm_arch {
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index af59c434ae33..7f076da55f30 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -289,6 +289,10 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_REG_ARM_STD_HYP_BIT_PV_TIME		BIT(0)
 #define KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX	0       /* Last valid bit */
 
+#define KVM_REG_ARM_VENDOR_HYP_BMAP		KVM_REG_ARM_FW_REG(5)
+#define KVM_REG_ARM_VENDOR_HYP_BIT_PTP		BIT(0)
+#define KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX	0       /* Last valid bit */
+
 /* SVE registers */
 #define KVM_REG_ARM64_SVE		(0x15 << KVM_REG_ARM_COPROC_SHIFT)
 
diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 9df0221834a3..2403ad50d759 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -79,6 +79,9 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 	case ARM_SMCCC_HV_PV_TIME_ST:
 		return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_hyp_bmap,
 					KVM_REG_ARM_STD_HYP_BIT_PV_TIME);
+	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
+		return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_vendor_hyp_bmap,
+					KVM_REG_ARM_VENDOR_HYP_BIT_PTP);
 	default:
 		/* By default, allow the services that aren't listed here */
 		return true;
@@ -87,6 +90,7 @@ bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
 
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 {
+	struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
 	u32 func_id = smccc_get_function(vcpu);
 	u64 val[4] = {SMCCC_RET_NOT_SUPPORTED};
 	u32 feature;
@@ -159,7 +163,14 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
 		break;
 	case ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID:
 		val[0] = BIT(ARM_SMCCC_KVM_FUNC_FEATURES);
-		val[0] |= BIT(ARM_SMCCC_KVM_FUNC_PTP);
+
+		/*
+		 * The feature bits exposed to user-space doesn't include
+		 * ARM_SMCCC_KVM_FUNC_FEATURES. However, we expose this to
+		 * the guest as bit-0. Hence, left-shift the user-space
+		 * exposed bitmap by 1 to accommodate this.
+		 */
+		val[0] |= hvc_desc->hvc_vendor_hyp_bmap << 1;
 		break;
 	case ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID:
 		kvm_ptp_get_time(vcpu, val);
@@ -188,6 +199,7 @@ static const u64 kvm_arm_fw_reg_ids[] = {
 static const u64 kvm_arm_fw_reg_bmap_ids[] = {
 	KVM_REG_ARM_STD_BMAP,
 	KVM_REG_ARM_STD_HYP_BMAP,
+	KVM_REG_ARM_VENDOR_HYP_BMAP,
 };
 
 void kvm_arm_init_hypercalls(struct kvm *kvm)
@@ -196,6 +208,7 @@ void kvm_arm_init_hypercalls(struct kvm *kvm)
 
 	hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
 	hvc_desc->hvc_std_hyp_bmap = ARM_SMCCC_STD_HYP_FEATURES;
+	hvc_desc->hvc_vendor_hyp_bmap = ARM_SMCCC_VENDOR_HYP_FEATURES;
 }
 
 int kvm_arm_num_fw_bmap_regs(void)
@@ -296,6 +309,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 	case KVM_REG_ARM_STD_HYP_BMAP:
 		kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_hyp_bmap, &val);
 		break;
+	case KVM_REG_ARM_VENDOR_HYP_BMAP:
+		kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_vendor_hyp_bmap, &val);
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -322,6 +338,10 @@ static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
 		fw_reg_bmap = &hvc_desc->hvc_std_hyp_bmap;
 		fw_reg_features = ARM_SMCCC_STD_HYP_FEATURES;
 		break;
+	case KVM_REG_ARM_VENDOR_HYP_BMAP:
+		fw_reg_bmap = &hvc_desc->hvc_vendor_hyp_bmap;
+		fw_reg_features = ARM_SMCCC_VENDOR_HYP_FEATURES;
+		break;
 	default:
 		return -ENOENT;
 	}
@@ -425,6 +445,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 		return 0;
 	case KVM_REG_ARM_STD_BMAP:
 	case KVM_REG_ARM_STD_HYP_BMAP:
+	case KVM_REG_ARM_VENDOR_HYP_BMAP:
 		return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
 	default:
 		return -ENOENT;
diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
index 1a79b5f89a24..8f54cacfbf40 100644
--- a/include/kvm/arm_hypercalls.h
+++ b/include/kvm/arm_hypercalls.h
@@ -12,6 +12,9 @@
 #define ARM_SMCCC_STD_HYP_FEATURES \
 	GENMASK_ULL(KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX, 0)
 
+#define ARM_SMCCC_VENDOR_HYP_FEATURES \
+	GENMASK_ULL(KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX, 0)
+
 int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
 
 static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:14 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:14 +0000
Subject: [RFC PATCH v3 07/11] Docs: KVM: Add doc for the bitmap firmware
 registers
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-8-rananta@google.com>

Add the documentation for the bitmap firmware registers in
psci.rst. This includes the details for KVM_REG_ARM_STD_BMAP,
KVM_REG_ARM_STD_HYP_BMAP, and KVM_REG_ARM_VENDOR_HYP_BMAP
registers.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 Documentation/virt/kvm/arm/psci.rst | 85 +++++++++++++++++++++++------
 1 file changed, 68 insertions(+), 17 deletions(-)

diff --git a/Documentation/virt/kvm/arm/psci.rst b/Documentation/virt/kvm/arm/psci.rst
index d52c2e83b5b8..edc3caf927ae 100644
--- a/Documentation/virt/kvm/arm/psci.rst
+++ b/Documentation/virt/kvm/arm/psci.rst
@@ -1,32 +1,32 @@
 .. SPDX-License-Identifier: GPL-2.0
 
-=========================================
-Power State Coordination Interface (PSCI)
-=========================================
+=======================
+ARM Hypercall Interface
+=======================
 
-KVM implements the PSCI (Power State Coordination Interface)
-specification in order to provide services such as CPU on/off, reset
-and power-off to the guest.
+KVM handles the hypercall services as requested by the guests. New hypercall
+services are regularly made available by the ARM specification or by KVM (as
+vendor services) if they make sense from a virtualization point of view.
 
-The PSCI specification is regularly updated to provide new features,
-and KVM implements these updates if they make sense from a virtualization
-point of view.
-
-This means that a guest booted on two different versions of KVM can
-observe two different "firmware" revisions. This could cause issues if
-a given guest is tied to a particular PSCI revision (unlikely), or if
-a migration causes a different PSCI version to be exposed out of the
-blue to an unsuspecting guest.
+This means that a guest booted on two different versions of KVM can observe
+two different "firmware" revisions. This could cause issues if a given guest
+is tied to a particular version of a hypercall service, or if a migration
+causes a different version to be exposed out of the blue to an unsuspecting
+guest.
 
 In order to remedy this situation, KVM exposes a set of "firmware
 pseudo-registers" that can be manipulated using the GET/SET_ONE_REG
 interface. These registers can be saved/restored by userspace, and set
 to a convenient value if required.
 
-The following register is defined:
+The following registers are defined:
 
 * KVM_REG_ARM_PSCI_VERSION:
 
+  KVM implements the PSCI (Power State Coordination Interface)
+  specification in order to provide services such as CPU on/off, reset
+  and power-off to the guest.
+
   - Only valid if the vcpu has the KVM_ARM_VCPU_PSCI_0_2 feature set
     (and thus has already been initialized)
   - Returns the current PSCI version on GET_ONE_REG (defaulting to the
@@ -74,4 +74,55 @@ The following register is defined:
     KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED:
       The workaround is always active on this vCPU or it is not needed.
 
-.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
+Contrary to the above registers, the following registers exposes the hypercall
+services in the form of a feature-bitmap. This bitmap is translated to the
+services that are exposed to the guest. There is a register defined per service
+call owner and can be accessed via GET/SET_ONE_REG interface.
+
+A new KVM capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is introduced to let
+user-space know of this extension. A simple 'read' of the capability would
+return the number of bitmapped registers. The user-space is expected to
+make a not of this value and configure each of the register.
+
+By default, these registers are set with the upper limit of the features that
+are supported. User-space can discover this configuration via GET_ONE_REG. If
+unsatisfied, the user-space can write back the desired bitmap back via
+SET_ONE_REG.
+
+The psuedo-firmware bitmap register are as follows:
+
+* KVM_REG_ARM_STD_BMAP:
+    Controls the bitmap of the ARM Standard Secure Service Calls.
+
+  The following bits are accepted:
+
+    KVM_REG_ARM_STD_BIT_TRNG_V1_0:
+      The bit represents the services offered under v1.0 of ARM True Random
+      Number Generator (TRNG) specification, ARM DEN0098.
+
+* KVM_REG_ARM_STD_HYP_BMAP:
+    Controls the bitmap of the ARM Standard Hypervisor Service Calls.
+
+  The following bits are accepted:
+
+    KVM_REG_ARM_STD_HYP_BIT_PV_TIME:
+      The bit represents the Paravirtualized Time service as represented by
+      ARM DEN0057A.
+
+* KVM_REG_ARM_VENDOR_HYP_BMAP:
+    Controls the bitmap of the Vendor specific Hypervisor Service Calls.
+
+  The following bits are accepted:
+
+    KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
+      The bit represents the Precision Time Protocol KVM service.
+
+Errors:
+
+    =======  =============================================================
+    -ENOENT   Unknown register accessed.
+    -EBUSY    Attempt a 'write' to the register after the VM has started.
+    -EINVAL   Invalid bitmap written to the register.
+    =======  =============================================================
+
+.. [1] https://developer.arm.com/-/media/developer/pdf/ARM_DEN_0070A_Firmware_interfaces_for_mitigating_CVE-2017-5715.pdf
\ No newline at end of file
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:15 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:15 +0000
Subject: [RFC PATCH v3 08/11] Docs: KVM: Rename psci.rst to hypercalls.rst
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-9-rananta@google.com>

Since the doc now covers more of general hypercalls'
details, rather than just PSCI, rename the file to a
more appropriate name- hypercalls.rst.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 Documentation/virt/kvm/arm/{psci.rst => hypercalls.rst} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/virt/kvm/arm/{psci.rst => hypercalls.rst} (100%)

diff --git a/Documentation/virt/kvm/arm/psci.rst b/Documentation/virt/kvm/arm/hypercalls.rst
similarity index 100%
rename from Documentation/virt/kvm/arm/psci.rst
rename to Documentation/virt/kvm/arm/hypercalls.rst
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:16 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:16 +0000
Subject: [RFC PATCH v3 09/11] tools: Import ARM SMCCC definitions
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-10-rananta@google.com>

Import the standard SMCCC definitions from include/linux/arm-smccc.h.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 tools/include/linux/arm-smccc.h | 188 ++++++++++++++++++++++++++++++++
 1 file changed, 188 insertions(+)
 create mode 100644 tools/include/linux/arm-smccc.h

diff --git a/tools/include/linux/arm-smccc.h b/tools/include/linux/arm-smccc.h
new file mode 100644
index 000000000000..a11c0bbabd5b
--- /dev/null
+++ b/tools/include/linux/arm-smccc.h
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, Linaro Limited
+ */
+#ifndef __LINUX_ARM_SMCCC_H
+#define __LINUX_ARM_SMCCC_H
+
+#include <linux/const.h>
+
+/*
+ * This file provides common defines for ARM SMC Calling Convention as
+ * specified in
+ * https://developer.arm.com/docs/den0028/latest
+ *
+ * This code is up-to-date with version DEN 0028 C
+ */
+
+#define ARM_SMCCC_STD_CALL	        _AC(0,U)
+#define ARM_SMCCC_FAST_CALL	        _AC(1,U)
+#define ARM_SMCCC_TYPE_SHIFT		31
+
+#define ARM_SMCCC_SMC_32		0
+#define ARM_SMCCC_SMC_64		1
+#define ARM_SMCCC_CALL_CONV_SHIFT	30
+
+#define ARM_SMCCC_OWNER_MASK		0x3F
+#define ARM_SMCCC_OWNER_SHIFT		24
+
+#define ARM_SMCCC_FUNC_MASK		0xFFFF
+
+#define ARM_SMCCC_IS_FAST_CALL(smc_val)	\
+	((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
+#define ARM_SMCCC_IS_64(smc_val) \
+	((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
+#define ARM_SMCCC_FUNC_NUM(smc_val)	((smc_val) & ARM_SMCCC_FUNC_MASK)
+#define ARM_SMCCC_OWNER_NUM(smc_val) \
+	(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
+
+#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
+	(((type) << ARM_SMCCC_TYPE_SHIFT) | \
+	((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
+	(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
+	((func_num) & ARM_SMCCC_FUNC_MASK))
+
+#define ARM_SMCCC_OWNER_ARCH		0
+#define ARM_SMCCC_OWNER_CPU		1
+#define ARM_SMCCC_OWNER_SIP		2
+#define ARM_SMCCC_OWNER_OEM		3
+#define ARM_SMCCC_OWNER_STANDARD	4
+#define ARM_SMCCC_OWNER_STANDARD_HYP	5
+#define ARM_SMCCC_OWNER_VENDOR_HYP	6
+#define ARM_SMCCC_OWNER_TRUSTED_APP	48
+#define ARM_SMCCC_OWNER_TRUSTED_APP_END	49
+#define ARM_SMCCC_OWNER_TRUSTED_OS	50
+#define ARM_SMCCC_OWNER_TRUSTED_OS_END	63
+
+#define ARM_SMCCC_FUNC_QUERY_CALL_UID  0xff01
+
+#define ARM_SMCCC_QUIRK_NONE		0
+#define ARM_SMCCC_QUIRK_QCOM_A6		1 /* Save/restore register a6 */
+
+#define ARM_SMCCC_VERSION_1_0		0x10000
+#define ARM_SMCCC_VERSION_1_1		0x10001
+#define ARM_SMCCC_VERSION_1_2		0x10002
+#define ARM_SMCCC_VERSION_1_3		0x10003
+
+#define ARM_SMCCC_1_3_SVE_HINT		0x10000
+
+#define ARM_SMCCC_VERSION_FUNC_ID					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 0)
+
+#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 1)
+
+#define ARM_SMCCC_ARCH_SOC_ID						\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 2)
+
+#define ARM_SMCCC_ARCH_WORKAROUND_1					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 0x8000)
+
+#define ARM_SMCCC_ARCH_WORKAROUND_2					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   0, 0x7fff)
+
+#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID				\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+			   ARM_SMCCC_FUNC_QUERY_CALL_UID)
+
+/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_0	0xb66fb428U
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_1	0xe911c52eU
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_2	0x564bcaa9U
+#define ARM_SMCCC_VENDOR_HYP_UID_KVM_REG_3	0x743a004dU
+
+/* KVM "vendor specific" services */
+#define ARM_SMCCC_KVM_FUNC_FEATURES		0
+#define ARM_SMCCC_KVM_FUNC_PTP			1
+#define ARM_SMCCC_KVM_FUNC_FEATURES_2		127
+#define ARM_SMCCC_KVM_NUM_FUNCS			128
+
+#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID			\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+			   ARM_SMCCC_KVM_FUNC_FEATURES)
+
+#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED	1
+
+/*
+ * ptp_kvm is a feature used for time sync between vm and host.
+ * ptp_kvm module in guest kernel will get service from host using
+ * this hypercall ID.
+ */
+#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID				\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,				\
+			   ARM_SMCCC_SMC_32,				\
+			   ARM_SMCCC_OWNER_VENDOR_HYP,			\
+			   ARM_SMCCC_KVM_FUNC_PTP)
+
+/* ptp_kvm counter type ID */
+#define KVM_PTP_VIRT_COUNTER			0
+#define KVM_PTP_PHYS_COUNTER			1
+
+/* Paravirtualised time calls (defined by ARM DEN0057A) */
+#define ARM_SMCCC_HV_PV_TIME_FEATURES				\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_64,			\
+			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
+			   0x20)
+
+#define ARM_SMCCC_HV_PV_TIME_ST					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_64,			\
+			   ARM_SMCCC_OWNER_STANDARD_HYP,	\
+			   0x21)
+
+/* TRNG entropy source calls (defined by ARM DEN0098) */
+#define ARM_SMCCC_TRNG_VERSION					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_32,			\
+			   ARM_SMCCC_OWNER_STANDARD,		\
+			   0x50)
+
+#define ARM_SMCCC_TRNG_FEATURES					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_32,			\
+			   ARM_SMCCC_OWNER_STANDARD,		\
+			   0x51)
+
+#define ARM_SMCCC_TRNG_GET_UUID					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_32,			\
+			   ARM_SMCCC_OWNER_STANDARD,		\
+			   0x52)
+
+#define ARM_SMCCC_TRNG_RND32					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_32,			\
+			   ARM_SMCCC_OWNER_STANDARD,		\
+			   0x53)
+
+#define ARM_SMCCC_TRNG_RND64					\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,			\
+			   ARM_SMCCC_SMC_64,			\
+			   ARM_SMCCC_OWNER_STANDARD,		\
+			   0x53)
+
+/*
+ * Return codes defined in ARM DEN 0070A
+ * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
+ */
+#define SMCCC_RET_SUCCESS			0
+#define SMCCC_RET_NOT_SUPPORTED			-1
+#define SMCCC_RET_NOT_REQUIRED			-2
+#define SMCCC_RET_INVALID_PARAMETER		-3
+
+#endif /*__LINUX_ARM_SMCCC_H*/
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:17 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:17 +0000
Subject: [RFC PATCH v3 10/11] selftests: KVM: aarch64: Introduce hypercall ABI
 test
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-11-rananta@google.com>

Introduce a KVM selftest to check the hypercall interface
for arm64 platforms. The test validates the user-space's
IOCTL interface to read/write the psuedo-firmware registers
as well as its effects on the guest upon certain configurations.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/aarch64/hypercalls.c        | 358 ++++++++++++++++++
 3 files changed, 360 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/hypercalls.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 99ed78ddd63f..bdecb27411ad 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -2,6 +2,7 @@
 /aarch64/arch_timer
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
+/aarch64/hypercalls
 /aarch64/psci_test
 /aarch64/vgic_init
 /s390x/memop
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 5be2690168a8..ea96a92493d5 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -94,6 +94,7 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
+TEST_GEN_PROGS_aarch64 += aarch64/hypercalls
 TEST_GEN_PROGS_aarch64 += aarch64/psci_test
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
 TEST_GEN_PROGS_aarch64 += demand_paging_test
diff --git a/tools/testing/selftests/kvm/aarch64/hypercalls.c b/tools/testing/selftests/kvm/aarch64/hypercalls.c
new file mode 100644
index 000000000000..386f754ca99d
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/hypercalls.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <errno.h>
+#include <linux/arm-smccc.h>
+#include <asm/kvm.h>
+#include <kvm_util.h>
+
+#include "processor.h"
+
+#define FW_REG_ULIMIT_VAL(max_feat_bit) (GENMASK_ULL(max_feat_bit, 0))
+
+struct kvm_fw_reg_info {
+	uint64_t reg;		/* Register definition */
+	uint64_t max_feat_bit;	/* Bit that represents the upper limit of the feature-map */
+};
+
+#define FW_REG_INFO(r, bit_max)			\
+	{					\
+		.reg = r,			\
+		.max_feat_bit = bit_max,	\
+	}
+
+static const struct kvm_fw_reg_info fw_reg_info[] = {
+	FW_REG_INFO(KVM_REG_ARM_STD_BMAP, KVM_REG_ARM_STD_BMAP_BIT_MAX),
+	FW_REG_INFO(KVM_REG_ARM_STD_HYP_BMAP, KVM_REG_ARM_STD_HYP_BMAP_BIT_MAX),
+	FW_REG_INFO(KVM_REG_ARM_VENDOR_HYP_BMAP, KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_MAX),
+};
+
+enum test_stage {
+	TEST_STAGE_REG_IFACE,
+	TEST_STAGE_HVC_IFACE_FEAT_DISABLED,
+	TEST_STAGE_HVC_IFACE_FEAT_ENABLED,
+	TEST_STAGE_END,
+};
+
+static int stage;
+
+struct test_hvc_info {
+	uint32_t func_id;
+	int64_t arg0;
+
+	void (*test_hvc_disabled)(const struct test_hvc_info *hc_info,
+					struct arm_smccc_res *res);
+	void (*test_hvc_enabled)(const struct test_hvc_info *hc_info,
+					struct arm_smccc_res *res);
+};
+
+#define TEST_HVC_INFO(f, a0, test_disabled, test_enabled)	\
+	{							\
+		.func_id = f,					\
+		.arg0 = a0,					\
+		.test_hvc_disabled = test_disabled,		\
+		.test_hvc_enabled = test_enabled,		\
+	}
+
+static void
+test_ptp_feat_hvc_disabled(const struct test_hvc_info *hc_info, struct arm_smccc_res *res)
+{
+	GUEST_ASSERT_3((res->a0 & BIT(ARM_SMCCC_KVM_FUNC_PTP)) == 0,
+			res->a0, hc_info->func_id, hc_info->arg0);
+}
+
+static void
+test_ptp_feat_hvc_enabled(const struct test_hvc_info *hc_info, struct arm_smccc_res *res)
+{
+	GUEST_ASSERT_3((res->a0 & BIT(ARM_SMCCC_KVM_FUNC_PTP)) != 0,
+			res->a0, hc_info->func_id, hc_info->arg0);
+}
+
+static const struct test_hvc_info hvc_info[] = {
+	/* KVM_REG_ARM_STD_BMAP: KVM_REG_ARM_STD_BIT_TRNG_V1_0 */
+	TEST_HVC_INFO(ARM_SMCCC_TRNG_VERSION, 0, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_TRNG_FEATURES, ARM_SMCCC_TRNG_RND64, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_TRNG_GET_UUID, 0, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_TRNG_RND32, 0, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_TRNG_RND64, 0, NULL, NULL),
+
+	/* KVM_REG_ARM_STD_HYP_BMAP: KVM_REG_ARM_STD_HYP_BIT_PV_TIME */
+	TEST_HVC_INFO(ARM_SMCCC_ARCH_FEATURES_FUNC_ID,
+			ARM_SMCCC_HV_PV_TIME_FEATURES, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_FEATURES,
+			ARM_SMCCC_HV_PV_TIME_ST, NULL, NULL),
+	TEST_HVC_INFO(ARM_SMCCC_HV_PV_TIME_ST, 0, NULL, NULL),
+
+	/* KVM_REG_ARM_VENDOR_HYP_BMAP: KVM_REG_ARM_VENDOR_HYP_BIT_PTP */
+	TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID,
+			ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID,
+			test_ptp_feat_hvc_disabled, test_ptp_feat_hvc_enabled),
+	TEST_HVC_INFO(ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID,
+			KVM_PTP_VIRT_COUNTER, NULL, NULL),
+};
+
+static void guest_test_hvc(int stage)
+{
+	unsigned int i;
+	struct arm_smccc_res res;
+
+	for (i = 0; i < ARRAY_SIZE(hvc_info); i++) {
+		const struct test_hvc_info *hc_info  = &hvc_info[i];
+
+		memset(&res, 0, sizeof(res));
+		smccc_hvc(hc_info->func_id, hc_info->arg0, 0, 0, 0, 0, 0, 0, &res);
+
+		switch (stage) {
+		case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
+			if (hc_info->test_hvc_disabled)
+				hc_info->test_hvc_disabled(hc_info, &res);
+			else
+				GUEST_ASSERT_3(res.a0 == SMCCC_RET_NOT_SUPPORTED,
+					res.a0, hc_info->func_id, hc_info->arg0);
+			break;
+		case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
+			if (hc_info->test_hvc_enabled)
+				hc_info->test_hvc_enabled(hc_info, &res);
+			else
+				GUEST_ASSERT_3(res.a0 != SMCCC_RET_NOT_SUPPORTED,
+					res.a0, hc_info->func_id, hc_info->arg0);
+			break;
+		default:
+			GUEST_ASSERT_1(0, stage);
+		}
+	}
+}
+
+static void guest_code(void)
+{
+	while (stage != TEST_STAGE_END) {
+		switch (stage) {
+		case TEST_STAGE_REG_IFACE:
+			break;
+		case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
+		case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
+			guest_test_hvc(stage);
+			break;
+		default:
+			GUEST_ASSERT_1(0, stage);
+		}
+
+		GUEST_SYNC(stage);
+	}
+
+	GUEST_DONE();
+}
+
+static int set_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t val)
+{
+	struct kvm_one_reg reg = {
+		.id = KVM_REG_ARM_FW_REG(id),
+		.addr = (uint64_t)&val,
+	};
+
+	return _vcpu_ioctl(vm, 0, KVM_SET_ONE_REG, &reg);
+}
+
+static void get_fw_reg(struct kvm_vm *vm, uint64_t id, uint64_t *addr)
+{
+	struct kvm_one_reg reg = {
+		.id = KVM_REG_ARM_FW_REG(id),
+		.addr = (uint64_t)addr,
+	};
+
+	return vcpu_ioctl(vm, 0, KVM_GET_ONE_REG, &reg);
+}
+
+struct st_time {
+	uint32_t rev;
+	uint32_t attr;
+	uint64_t st_time;
+};
+
+#define STEAL_TIME_SIZE		((sizeof(struct st_time) + 63) & ~63)
+#define ST_GPA_BASE		(1 << 30)
+
+static void steal_time_init(struct kvm_vm *vm)
+{
+	uint64_t st_ipa = (ulong)ST_GPA_BASE;
+	unsigned int gpages;
+	struct kvm_device_attr dev = {
+		.group = KVM_ARM_VCPU_PVTIME_CTRL,
+		.attr = KVM_ARM_VCPU_PVTIME_IPA,
+		.addr = (uint64_t)&st_ipa,
+	};
+
+	gpages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, STEAL_TIME_SIZE);
+	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, ST_GPA_BASE, 1, gpages, 0);
+
+	vcpu_ioctl(vm, 0, KVM_SET_DEVICE_ATTR, &dev);
+}
+
+static void test_fw_regs_before_vm_start(struct kvm_vm *vm)
+{
+	uint64_t val;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
+		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
+
+		/* First read should be an upper limit of the features supported */
+		get_fw_reg(vm, reg_info->reg, &val);
+		TEST_ASSERT(val == FW_REG_ULIMIT_VAL(reg_info->max_feat_bit),
+			"Expected all the features to be set for reg: 0x%lx; expected: 0x%llx; read: 0x%lx\n",
+			reg_info->reg, GENMASK_ULL(reg_info->max_feat_bit, 0), val);
+
+		/* Test 'write' by disabling all the features of the register map */
+		ret = set_fw_reg(vm, reg_info->reg, 0);
+		TEST_ASSERT(ret == 0,
+			"Failed to clear all the features of reg: 0x%lx; ret: %d\n",
+			reg_info->reg, errno);
+
+		get_fw_reg(vm, reg_info->reg, &val);
+		TEST_ASSERT(val == 0,
+			"Expected all the features to be cleared for reg: 0x%lx\n", reg_info->reg);
+
+		/*
+		 * Test enabling a feature that's not supported.
+		 * Avoid this check if all the bits are occupied.
+		 */
+		if (reg_info->max_feat_bit < 63) {
+			ret = set_fw_reg(vm, reg_info->reg, BIT(reg_info->max_feat_bit + 1));
+			TEST_ASSERT(ret != 0 && errno == EINVAL,
+			"Unexpected behavior or return value (%d) while setting an unsupported feature for reg: 0x%lx\n",
+			errno, reg_info->reg);
+		}
+	}
+}
+
+static void test_fw_regs_after_vm_start(struct kvm_vm *vm)
+{
+	uint64_t val;
+	unsigned int i;
+	int ret;
+
+	for (i = 0; i < ARRAY_SIZE(fw_reg_info); i++) {
+		const struct kvm_fw_reg_info *reg_info = &fw_reg_info[i];
+
+		/*
+		 * Before starting the VM, the test clears all the bits.
+		 * Check if that's still the case.
+		 */
+		get_fw_reg(vm, reg_info->reg, &val);
+		TEST_ASSERT(val == 0,
+			"Expected all the features to be cleared for reg: 0x%lx\n",
+			reg_info->reg);
+
+		/*
+		 * Test setting the last known value. KVM should allow this
+		 * even if VM has started running.
+		 */
+		ret = set_fw_reg(vm, reg_info->reg, val);
+		TEST_ASSERT(ret == 0,
+			"Failed to clear all the features of reg: 0x%lx; ret: %d\n",
+			reg_info->reg, errno);
+
+		/*
+		 * Set all the features for this register again. KVM shouldn't
+		 * allow this as the VM is running.
+		 */
+		ret = set_fw_reg(vm, reg_info->reg, FW_REG_ULIMIT_VAL(reg_info->max_feat_bit));
+		TEST_ASSERT(ret != 0 && errno == EBUSY,
+		"Unexpected behavior or return value (%d) while setting a feature while VM is running for reg: 0x%lx\n",
+		errno, reg_info->reg);
+	}
+}
+
+static struct kvm_vm *test_vm_create(void)
+{
+	struct kvm_vm *vm;
+
+	vm = vm_create_default(0, 0, guest_code);
+
+	ucall_init(vm, NULL);
+	steal_time_init(vm);
+
+	return vm;
+}
+
+static struct kvm_vm *test_guest_stage(struct kvm_vm *vm)
+{
+	struct kvm_vm *ret_vm = vm;
+
+	pr_debug("Stage: %d\n", stage);
+
+	switch (stage) {
+	case TEST_STAGE_REG_IFACE:
+		test_fw_regs_after_vm_start(vm);
+		break;
+	case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
+		/* Start a new VM so that all the features are now enabled by default */
+		kvm_vm_free(vm);
+		ret_vm = test_vm_create();
+		break;
+	case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
+		break;
+	default:
+		TEST_FAIL("Unknown test stage: %d\n", stage);
+	}
+
+	stage++;
+	sync_global_to_guest(vm, stage);
+
+	return ret_vm;
+}
+
+static void test_run(void)
+{
+	struct kvm_vm *vm;
+	struct ucall uc;
+	bool guest_done = false;
+
+	vm = test_vm_create();
+
+	test_fw_regs_before_vm_start(vm);
+
+	while (!guest_done) {
+		vcpu_run(vm, 0);
+
+		switch (get_ucall(vm, 0, &uc)) {
+		case UCALL_SYNC:
+			vm = test_guest_stage(vm);
+			break;
+		case UCALL_DONE:
+			guest_done = true;
+			break;
+		case UCALL_ABORT:
+			TEST_FAIL("%s at %s:%ld\n\tvalues: 0x%lx, %lu; %lu, stage: %u",
+			(const char *)uc.args[0], __FILE__, uc.args[1],
+			uc.args[2], uc.args[3], uc.args[4], stage);
+			break;
+		default:
+			TEST_FAIL("Unexpected guest exit\n");
+		}
+	}
+
+	kvm_vm_free(vm);
+}
+
+int main(void)
+{
+	unsigned int num_fw_bmap_regs;
+
+	setbuf(stdout, NULL);
+
+	num_fw_bmap_regs = kvm_check_cap(KVM_CAP_ARM_HVC_FW_REG_BMAP);
+	if (!num_fw_bmap_regs) {
+		print_skip("ARM64 fw registers bitmap not supported\n");
+		exit(KSFT_SKIP);
+	} else if (num_fw_bmap_regs != ARRAY_SIZE(fw_reg_info)) {
+		print_skip("Mismatched fw registers between kernel (%u) and test (%lu)\n",
+				num_fw_bmap_regs, ARRAY_SIZE(fw_reg_info));
+		exit(KSFT_SKIP);
+	}
+
+	pr_info("Number of firmware bitmap registers discovered: %u\n", num_fw_bmap_regs);
+
+	test_run();
+	return 0;
+}
-- 
2.34.1.448.ga2b2bfdf31-goog



From rananta at google.com  Tue Jan  4 11:49:18 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue,  4 Jan 2022 19:49:18 +0000
Subject: [RFC PATCH v3 11/11] selftests: KVM: aarch64: Add the bitmap firmware
 registers to get-reg-list
In-Reply-To: <20220104194918.373612-1-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
Message-ID: <20220104194918.373612-12-rananta@google.com>

Add the psuedo-firmware registers KVM_REG_ARM_STD_BMAP,
KVM_REG_ARM_STD_HYP_BMAP, and KVM_REG_ARM_VENDOR_HYP_BMAP to
the base_regs[] list.

Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
---
 tools/testing/selftests/kvm/aarch64/get-reg-list.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/testing/selftests/kvm/aarch64/get-reg-list.c b/tools/testing/selftests/kvm/aarch64/get-reg-list.c
index cc898181faab..6321f4472fdf 100644
--- a/tools/testing/selftests/kvm/aarch64/get-reg-list.c
+++ b/tools/testing/selftests/kvm/aarch64/get-reg-list.c
@@ -686,6 +686,9 @@ static __u64 base_regs[] = {
 	KVM_REG_ARM_FW_REG(0),
 	KVM_REG_ARM_FW_REG(1),
 	KVM_REG_ARM_FW_REG(2),
+	KVM_REG_ARM_FW_REG(3),          /* KVM_REG_ARM_STD_BMAP */
+	KVM_REG_ARM_FW_REG(4),          /* KVM_REG_ARM_STD_HYP_BMAP */
+	KVM_REG_ARM_FW_REG(5),          /* KVM_REG_ARM_VENDOR_HYP_BMAP */
 	ARM64_SYS_REG(3, 3, 14, 3, 1),	/* CNTV_CTL_EL0 */
 	ARM64_SYS_REG(3, 3, 14, 3, 2),	/* CNTV_CVAL_EL0 */
 	ARM64_SYS_REG(3, 3, 14, 0, 2),
-- 
2.34.1.448.ga2b2bfdf31-goog



From clabbe.montjoie at gmail.com  Tue Jan  4 11:53:41 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 4 Jan 2022 20:53:41 +0100
Subject: [PATCH net-next] net: gemini: allow any RGMII interface mode
In-Reply-To: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
References: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
Message-ID: <YdSlxW8mi+Xa4zlr@Red>

Le Tue, Jan 04, 2022 at 04:38:31PM +0000, Russell King (Oracle) a ?crit :
> The four RGMII interface modes take care of the required RGMII delay
> configuration at the PHY and should not be limited by the network MAC
> driver. Sadly, gemini was only permitting RGMII mode with no delays,
> which would require the required delay to be inserted via PCB tracking
> or by the MAC.
> 
> However, there are designs that require the PHY to add the delay, which
> is impossible without Gemini permitting the other three PHY interface
> modes. Fix the driver to allow these.
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)

Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>

Thanks!


From robh at kernel.org  Tue Jan  4 12:17:20 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 14:17:20 -0600
Subject: [PATCH] dt-bindings: vendor-prefixes: add OnePlus
In-Reply-To: <20211223141002.GA5979@standask-GA-A55M-S2HP>
References: <20211223141002.GA5979@standask-GA-A55M-S2HP>
Message-ID: <YdSrUB4FHyJjf/jV@robh.at.kernel.org>

On Thu, 23 Dec 2021 15:10:02 +0100, Stanislav Jakubek wrote:
> Add vendor prefix for OnePlus (https://www.oneplus.com/)
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!


From yuzhao at google.com  Tue Jan  4 12:22:19 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:19 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
Message-ID: <20220104202227.2903605-1-yuzhao@google.com>

TLDR
====
The current page reclaim is too expensive in terms of CPU usage and it
often makes poor choices about what to evict. This patchset offers an
alternative solution that is performant, versatile and
straightforward.

Design objectives
=================
The design objectives are:
1. Better representation of access recency
2. Try to profit from spatial locality
3. Clear fast path making obvious choices
4. Simple self-correcting heuristics

The representation of access recency is at the core of all LRU
approximations. The multigenerational LRU (MGLRU) divides pages into
multiple lists (generations), each having bounded access recency (a
time interval). Generations establish a common frame of reference and
help make better choices, e.g., between different memcgs on a computer
or different computers in a data center (for cluster job scheduling).

Exploiting spatial locality improves the efficiency when gathering the
accessed bit. A rmap walk targets a single page and doesn't try to
profit from discovering an accessed PTE. A page table walk can sweep
all hotspots in an address space, but its search space can be too
large to make a profit. The key is to optimize both methods and use
them in combination. (PMU is another option for further exploration.)

Fast path reduces code complexity and runtime overhead. Unmapped pages
don't require TLB flushes; clean pages don't require writeback. These
facts are only helpful when other conditions, e.g., access recency,
are similar. With generations as a common frame of reference,
additional factors stand out. But obvious choices might not be good
choices; thus self-correction is required (the next objective).

The benefits of simple self-correcting heuristics are self-evident.
Again with generations as a common frame of reference, this becomes
attainable. Specifically, pages in the same generation are categorized
based on additional factors, and a closed-loop control statistically
compares the refault percentages across all categories and throttles
the eviction of those that have higher percentages.

Patchset overview
=================
1. mm: x86, arm64: add arch_has_hw_pte_young()
2. mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
Materializing hardware optimizations when trying to clear the accessed
bit in many PTEs. If hardware automatically sets the accessed bit in
PTEs, there is no need to worry about bursty page faults (emulating
the accessed bit). If it also sets the accessed bit in non-leaf PMD
entries, there is no need to search the PTE table pointed to by a PMD
entry that doesn't have the accessed bit set.

3. mm/vmscan.c: refactor shrink_node()
A minor refactor.

4. mm: multigenerational lru: groundwork
Adding the basic data structure and the functions to initialize it and
insert/remove pages.

5. mm: multigenerational lru: mm_struct list
An infra keeps track of mm_struct's for page table walkers and
provides them with optimizations, i.e., switch_mm() tracking and Bloom
filters.

6. mm: multigenerational lru: aging
7. mm: multigenerational lru: eviction
"The page reclaim" is a producer/consumer model. "The aging" produces
cold pages, whereas "the eviction " consumes them. Cold pages flow
through generations. The aging uses the mm_struct list infra to sweep
dense hotspots in page tables. During a page table walk, the aging
clears the accessed bit and tags accessed pages with the youngest
generation number. The eviction sorts those pages when it encounters
them. For pages in the oldest generation, eviction walks the rmap to
check the accessed bit one more time before evicting them. During an
rmap walk, the eviction feeds dense hotspots back to the aging. Dense
hotspots flow through the Bloom filters. For pages not mapped in page
tables, the eviction uses the PID controller to statistically
determine whether they have higher refaults. If so, the eviction
throttles their eviction by moving them to the next generation (the
second oldest).

8. mm: multigenerational lru: user interface
The knobs to turn on/off MGLRU and provide the userspace with
thrashing prevention, working set estimation (the aging) and proactive
reclaim (the eviction).

9. mm: multigenerational lru: Kconfig
The Kconfig options.

Benchmark results
=================
Independent lab results
-----------------------
Based on the popularity of searches [01] and the memory usage in
Google's public cloud, the most popular open-source memory-hungry
applications, in alphabetical order, are:
      Apache Cassandra      Memcached
      Apache Hadoop         MongoDB
      Apache Spark          PostgreSQL
      MariaDB (MySQL)       Redis

An independent lab evaluated MGLRU with the most widely used benchmark
suites for the above applications. They posted 960 data points along
with kernel metrics and perf profiles collected over more than 500
hours of total benchmark time. Their final reports show that, with 95%
confidence intervals (CIs), the above applications all performed
significantly better for at least part of their benchmark matrices.

On 5.14:
1. Apache Spark [02] took 95% CIs [9.28, 11.19]% and [12.20, 14.93]%
   less wall time to sort three billion random integers, respectively,
   under the medium- and the high-concurrency conditions, when
   overcommitting memory. There were no statistically significant
   changes in wall time for the rest of the benchmark matrix.
2. MariaDB [03] achieved 95% CIs [5.24, 10.71]% and [20.22, 25.97]%
   more transactions per minute (TPM), respectively, under the medium-
   and the high-concurrency conditions, when overcommitting memory.
   There were no statistically significant changes in TPM for the rest
   of the benchmark matrix.
3. Memcached [04] achieved 95% CIs [23.54, 32.25]%, [20.76, 41.61]%
   and [21.59, 30.02]% more operations per second (OPS), respectively,
   for sequential access, random access and Gaussian (distribution)
   access, when THP=always; 95% CIs [13.85, 15.97]% and
   [23.94, 29.92]% more OPS, respectively, for random access and
   Gaussian access, when THP=never. There were no statistically
   significant changes in OPS for the rest of the benchmark matrix.
4. MongoDB [05] achieved 95% CIs [2.23, 3.44]%, [6.97, 9.73]% and
   [2.16, 3.55]% more operations per second (OPS), respectively, for
   exponential (distribution) access, random access and Zipfian
   (distribution) access, when underutilizing memory; 95% CIs
   [8.83, 10.03]%, [21.12, 23.14]% and [5.53, 6.46]% more OPS,
   respectively, for exponential access, random access and Zipfian
   access, when overcommitting memory.

On 5.15:
5. Apache Cassandra [06] achieved 95% CIs [1.06, 4.10]%, [1.94, 5.43]%
   and [4.11, 7.50]% more operations per second (OPS), respectively,
   for exponential (distribution) access, random access and Zipfian
   (distribution) access, when swap was off; 95% CIs [0.50, 2.60]%,
   [6.51, 8.77]% and [3.29, 6.75]% more OPS, respectively, for
   exponential access, random access and Zipfian access, when swap was
   on.
6. Apache Hadoop [07] took 95% CIs [5.31, 9.69]% and [2.02, 7.86]%
   less average wall time to finish twelve parallel TeraSort jobs,
   respectively, under the medium- and the high-concurrency
   conditions, when swap was on. There were no statistically
   significant changes in average wall time for the rest of the
   benchmark matrix.
7. PostgreSQL [08] achieved 95% CI [1.75, 6.42]% more transactions per
   minute (TPM) under the high-concurrency condition, when swap was
   off; 95% CIs [12.82, 18.69]% and [22.70, 46.86]% more TPM,
   respectively, under the medium- and the high-concurrency
   conditions, when swap was on. There were no statistically
   significant changes in TPM for the rest of the benchmark matrix.
8. Redis [09] achieved 95% CIs [0.58, 5.94]%, [6.55, 14.58]% and
   [11.47, 19.36]% more total operations per second (OPS),
   respectively, for sequential access, random access and Gaussian
   (distribution) access, when THP=always; 95% CIs [1.27, 3.54]%,
   [10.11, 14.81]% and [8.75, 13.64]% more total OPS, respectively,
   for sequential access, random access and Gaussian access, when
   THP=never.

Our lab results
---------------
To supplement the above results, we ran the following benchmark suites
on 5.16-rc7 and found no regressions [10]. (These synthetic benchmarks
are popular among MM developers, but we prefer large-scale A/B
experiments to validate improvements.)
      fs_fio_bench_hdd_mq      pft
      fs_lmbench               pgsql-hammerdb
      fs_parallelio            redis
      fs_postmark              stream
      hackbench                sysbenchthread
      kernbench                tpcc_spark
      memcached                unixbench
      multichase               vm-scalability
      mutilate                 will-it-scale
      nginx

[01] https://trends.google.com
[02] https://lore.kernel.org/linux-mm/20211102002002.92051-1-bot at edi.works/
[03] https://lore.kernel.org/linux-mm/20211009054315.47073-1-bot at edi.works/
[04] https://lore.kernel.org/linux-mm/20211021194103.65648-1-bot at edi.works/
[05] https://lore.kernel.org/linux-mm/20211109021346.50266-1-bot at edi.works/
[06] https://lore.kernel.org/linux-mm/20211202062806.80365-1-bot at edi.works/
[07] https://lore.kernel.org/linux-mm/20211209072416.33606-1-bot at edi.works/
[08] https://lore.kernel.org/linux-mm/20211218071041.24077-1-bot at edi.works/
[09] https://lore.kernel.org/linux-mm/20211122053248.57311-1-bot at edi.works/
[10] https://lore.kernel.org/linux-mm/20220104202247.2903702-1-yuzhao at google.com/

Read-world applications
=======================
Third-party testimonials
------------------------
Konstantin wrote [11]:
   I have Archlinux with 8G RAM + zswap + swap. While developing, I
   have lots of apps opened such as multiple LSP-servers for different
   langs, chats, two browsers, etc... Usually, my system gets quickly
   to a point of SWAP-storms, where I have to kill LSP-servers,
   restart browsers to free memory, etc, otherwise the system lags
   heavily and is barely usable.
   
   1.5 day ago I migrated from 5.11.15 kernel to 5.12 + the LRU
   patchset, and I started up by opening lots of apps to create memory
   pressure, and worked for a day like this. Till now I had *not a
   single SWAP-storm*, and mind you I got 3.4G in SWAP. I was never
   getting to the point of 3G in SWAP before without a single
   SWAP-storm.

The Arch Linux Zen kernel [12] has been using MGLRU since 5.12. Many
of its users reported their positive experiences to me, e.g., Shivodit
wrote:
   I've tried the latest Zen kernel (5.14.13-zen1-1-zen in the
   archlinux testing repos), everything's been smooth so far. I also
   decided to copy a large volume of files to check performance under
   I/O load, and everything went smoothly - no stuttering was present,
   everything was responsive.

Large-scale deployments
-----------------------
We've rolled out MGLRU to tens of millions of Chrome OS users and
about a million Android users. Google's fleetwide profiling [13] shows
an overall 40% decrease in kswapd CPU usage, in addition to
improvements in other UX metrics, e.g., an 85% decrease in the number
of low-memory kills at the 75th percentile and an 18% decrease in
rendering latency at the 50th percentile.

[11] https://lore.kernel.org/linux-mm/140226722f2032c86301fbd326d91baefe3d7d23.camel at yandex.ru/
[12] https://github.com/zen-kernel/zen-kernel/
[13] https://research.google/pubs/pub44271/

Summery
=======
The facts are:
1. The independent lab results and the real-world applications
   indicate substantial improvements; there are no known regressions.
2. Thrashing prevention, working set estimation and proactive reclaim
   work out of the box; there are no equivalent solutions.
3. There is a lot of new code; nobody has demonstrated smaller changes
   with similar effects.

Our options, accordingly, are:
1. Given the amount of evidence, the reported improvements will likely
   materialize for a wide range of workloads.
2. Gauging the interest from the past discussions [14][15][16], the
   new features will likely be put to use for both personal computers
   and data centers.
3. Based on Google's track record, the new code will likely be well
   maintained in the long term. It'd be more difficult if not
   impossible to achieve similar effects on top of the existing
   design.

[14] https://lore.kernel.org/lkml/20201005081313.732745-1-andrea.righi at canonical.com/
[15] https://lore.kernel.org/lkml/20210716081449.22187-1-sj38.park at gmail.com/
[16] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/

Yu Zhao (9):
  mm: x86, arm64: add arch_has_hw_pte_young()
  mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
  mm/vmscan.c: refactor shrink_node()
  mm: multigenerational lru: groundwork
  mm: multigenerational lru: mm_struct list
  mm: multigenerational lru: aging
  mm: multigenerational lru: eviction
  mm: multigenerational lru: user interface
  mm: multigenerational lru: Kconfig

 Documentation/vm/index.rst          |    1 +
 Documentation/vm/multigen_lru.rst   |   80 +
 arch/Kconfig                        |    9 +
 arch/arm64/include/asm/cpufeature.h |    5 +
 arch/arm64/include/asm/pgtable.h    |   13 +-
 arch/arm64/kernel/cpufeature.c      |   19 +
 arch/arm64/tools/cpucaps            |    1 +
 arch/x86/Kconfig                    |    1 +
 arch/x86/include/asm/pgtable.h      |    9 +-
 arch/x86/mm/pgtable.c               |    5 +-
 fs/exec.c                           |    2 +
 fs/fuse/dev.c                       |    3 +-
 include/linux/cgroup.h              |   15 +-
 include/linux/memcontrol.h          |   11 +
 include/linux/mm.h                  |   42 +
 include/linux/mm_inline.h           |  204 ++
 include/linux/mm_types.h            |   78 +
 include/linux/mmzone.h              |  175 ++
 include/linux/nodemask.h            |    1 +
 include/linux/oom.h                 |   16 +
 include/linux/page-flags-layout.h   |   19 +-
 include/linux/page-flags.h          |    4 +-
 include/linux/pgtable.h             |   17 +-
 include/linux/sched.h               |    4 +
 include/linux/swap.h                |    4 +
 kernel/bounds.c                     |    3 +
 kernel/cgroup/cgroup-internal.h     |    1 -
 kernel/exit.c                       |    1 +
 kernel/fork.c                       |    9 +
 kernel/sched/core.c                 |    1 +
 mm/Kconfig                          |   48 +
 mm/huge_memory.c                    |    3 +-
 mm/memcontrol.c                     |   26 +
 mm/memory.c                         |   21 +-
 mm/mm_init.c                        |    6 +-
 mm/oom_kill.c                       |    4 +-
 mm/page_alloc.c                     |    1 +
 mm/rmap.c                           |    7 +
 mm/swap.c                           |   51 +-
 mm/vmscan.c                         | 2691 ++++++++++++++++++++++++++-
 mm/workingset.c                     |  119 +-
 41 files changed, 3591 insertions(+), 139 deletions(-)
 create mode 100644 Documentation/vm/multigen_lru.rst

-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:20 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:20 -0700
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-2-yuzhao@google.com>

Some architectures automatically set the accessed bit in PTEs, e.g.,
x86 and arm64 v8.2. On architectures that don't have this capability,
clearing the accessed bit in a PTE usually triggers a page fault
following the TLB miss of this PTE.

Being aware of this capability can help make better decisions, e.g.,
whether to spread the work out over a period of time to avoid bursty
page faults when trying to clear the accessed bit in a large number of
PTEs.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 arch/arm64/include/asm/cpufeature.h |  5 +++++
 arch/arm64/include/asm/pgtable.h    | 13 ++++++++-----
 arch/arm64/kernel/cpufeature.c      | 19 +++++++++++++++++++
 arch/arm64/tools/cpucaps            |  1 +
 arch/x86/include/asm/pgtable.h      |  6 +++---
 include/linux/pgtable.h             | 13 +++++++++++++
 mm/memory.c                         | 14 +-------------
 7 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..99518b4b2a9e 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -779,6 +779,11 @@ static inline bool system_supports_tlb_range(void)
 		cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
 }
 
+static inline bool system_has_hw_af(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && cpus_have_const_cap(ARM64_HW_AF);
+}
+
 extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
 
 static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c4ba047a82d2..e736f47436c7 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -999,13 +999,16 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  * page after fork() + CoW for pfn mappings. We don't always have a
  * hardware-managed access flag on arm64.
  */
-static inline bool arch_faults_on_old_pte(void)
+static inline bool arch_has_hw_pte_young(bool local)
 {
-	WARN_ON(preemptible());
+	if (local) {
+		WARN_ON(preemptible());
+		return cpu_has_hw_af();
+	}
 
-	return !cpu_has_hw_af();
+	return system_has_hw_af();
 }
-#define arch_faults_on_old_pte		arch_faults_on_old_pte
+#define arch_has_hw_pte_young		arch_has_hw_pte_young
 
 /*
  * Experimentally, it's cheap to set the access flag in hardware and we
@@ -1013,7 +1016,7 @@ static inline bool arch_faults_on_old_pte(void)
  */
 static inline bool arch_wants_old_prefaulted_pte(void)
 {
-	return !arch_faults_on_old_pte();
+	return arch_has_hw_pte_young(true);
 }
 #define arch_wants_old_prefaulted_pte	arch_wants_old_prefaulted_pte
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6f3e677d88f1..5bb553ee2c0e 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2171,6 +2171,25 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
 	},
+	{
+		/*
+		 * __cpu_setup always enables this capability. But if the boot
+		 * CPU has it and a late CPU doesn't, the absent
+		 * ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU will prevent this late CPU
+		 * from going online. There is neither known hardware does that
+		 * nor obvious reasons to design hardware works that way, hence
+		 * no point leaving the door open here. If the need arises, a
+		 * new weak system feature flag should do the trick.
+		 */
+		.desc = "Hardware update of the Access flag",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_HW_AF,
+		.sys_reg = SYS_ID_AA64MMFR1_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+		.min_field_value = 1,
+		.matches = has_cpuid_feature,
+	},
 #endif
 	{
 		.desc = "CRC32 instructions",
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..56e4ef5d95fa 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -36,6 +36,7 @@ HAS_STAGE2_FWB
 HAS_SYSREG_GIC_CPUIF
 HAS_TLB_RANGE
 HAS_VIRT_HOST_EXTN
+HW_AF
 HW_DBM
 KVM_PROTECTED_MODE
 MISMATCHED_CACHE_TYPE
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 448cd01eb3ec..c60b16f8b741 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -1397,10 +1397,10 @@ static inline bool arch_has_pfn_modify_check(void)
 	return boot_cpu_has_bug(X86_BUG_L1TF);
 }
 
-#define arch_faults_on_old_pte arch_faults_on_old_pte
-static inline bool arch_faults_on_old_pte(void)
+#define arch_has_hw_pte_young arch_has_hw_pte_young
+static inline bool arch_has_hw_pte_young(bool local)
 {
-	return false;
+	return true;
 }
 
 #endif	/* __ASSEMBLY__ */
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index e24d2c992b11..53bd6a26918f 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -258,6 +258,19 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma,
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 #endif
 
+#ifndef arch_has_hw_pte_young
+/*
+ * Return whether the accessed bit is supported by the local CPU or system-wide.
+ *
+ * This stub assumes accessing thru an old PTE triggers a page fault.
+ * Architectures that automatically set the access bit should overwrite it.
+ */
+static inline bool arch_has_hw_pte_young(bool local)
+{
+	return false;
+}
+#endif
+
 #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long address,
diff --git a/mm/memory.c b/mm/memory.c
index 8f1de811a1dc..ead6c7d4b9a1 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -121,18 +121,6 @@ int randomize_va_space __read_mostly =
 					2;
 #endif
 
-#ifndef arch_faults_on_old_pte
-static inline bool arch_faults_on_old_pte(void)
-{
-	/*
-	 * Those arches which don't have hw access flag feature need to
-	 * implement their own helper. By default, "true" means pagefault
-	 * will be hit on old pte.
-	 */
-	return true;
-}
-#endif
-
 #ifndef arch_wants_old_prefaulted_pte
 static inline bool arch_wants_old_prefaulted_pte(void)
 {
@@ -2755,7 +2743,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
 	 * On architectures with software "accessed" bits, we would
 	 * take a double page fault, so mark it accessed here.
 	 */
-	if (arch_faults_on_old_pte() && !pte_young(vmf->orig_pte)) {
+	if (!arch_has_hw_pte_young(true) && !pte_young(vmf->orig_pte)) {
 		pte_t entry;
 
 		vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:21 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:21 -0700
Subject: [PATCH v6 2/9] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-3-yuzhao@google.com>

Some architectures support the accessed bit in non-leaf PMD entries,
e.g., x86_64 sets the accessed bit in a non-leaf PMD entry when using
it as part of linear address translation [1]. Page table walkers that
clear the accessed bit may use this feature to reduce their search
space.

Although an inline function is preferable, this capability is added as
a configuration option for the consistency with the existing macros.

[1]: Intel 64 and IA-32 Architectures Software Developer's Manual
     Volume 3 (June 2021), section 4.8

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 arch/Kconfig                   | 9 +++++++++
 arch/x86/Kconfig               | 1 +
 arch/x86/include/asm/pgtable.h | 3 ++-
 arch/x86/mm/pgtable.c          | 5 ++++-
 include/linux/pgtable.h        | 4 ++--
 5 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index d3c4ab249e9c..10f564340f79 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1312,6 +1312,15 @@ config ARCH_HAS_PARANOID_L1D_FLUSH
 config DYNAMIC_SIGFRAME
 	bool
 
+config ARCH_HAS_NONLEAF_PMD_YOUNG
+	bool
+	depends on PGTABLE_LEVELS > 2
+	help
+	  Architectures that select this option are capable of setting the
+	  accessed bit in non-leaf PMD entries when using them as part of linear
+	  address translations. Page table walkers that clear the accessed bit
+	  may use this feature to reduce their search space.
+
 source "kernel/gcov/Kconfig"
 
 source "scripts/gcc-plugins/Kconfig"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c2ccb85f2ef..5a4843242f09 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -85,6 +85,7 @@ config X86
 	select ARCH_HAS_PMEM_API		if X86_64
 	select ARCH_HAS_PTE_DEVMAP		if X86_64
 	select ARCH_HAS_PTE_SPECIAL
+	select ARCH_HAS_NONLEAF_PMD_YOUNG	if X86_64
 	select ARCH_HAS_UACCESS_FLUSHCACHE	if X86_64
 	select ARCH_HAS_COPY_MC			if X86_64
 	select ARCH_HAS_SET_MEMORY
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index c60b16f8b741..36205ec0acac 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -817,7 +817,8 @@ static inline unsigned long pmd_page_vaddr(pmd_t pmd)
 
 static inline int pmd_bad(pmd_t pmd)
 {
-	return (pmd_flags(pmd) & ~_PAGE_USER) != _KERNPG_TABLE;
+	return (pmd_flags(pmd) & ~(_PAGE_USER | _PAGE_ACCESSED)) !=
+	       (_KERNPG_TABLE & ~_PAGE_ACCESSED);
 }
 
 static inline unsigned long pages_to_mb(unsigned long npg)
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 3481b35cb4ec..a224193d84bf 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -550,7 +550,7 @@ int ptep_test_and_clear_young(struct vm_area_struct *vma,
 	return ret;
 }
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
 int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 			      unsigned long addr, pmd_t *pmdp)
 {
@@ -562,6 +562,9 @@ int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 
 	return ret;
 }
+#endif
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 int pudp_test_and_clear_young(struct vm_area_struct *vma,
 			      unsigned long addr, pud_t *pudp)
 {
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 53bd6a26918f..b51f939a73f7 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -211,7 +211,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
 #endif
 
 #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
 static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 					    unsigned long address,
 					    pmd_t *pmdp)
@@ -232,7 +232,7 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 	BUILD_BUG();
 	return 0;
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG */
 #endif
 
 #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:22 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:22 -0700
Subject: [PATCH v6 3/9] mm/vmscan.c: refactor shrink_node()
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-4-yuzhao@google.com>

This patch refactors shrink_node() to improve readability for the
upcoming changes to mm/vmscan.c.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 mm/vmscan.c | 198 +++++++++++++++++++++++++++-------------------------
 1 file changed, 104 insertions(+), 94 deletions(-)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 700434db5735..b6c5fd885216 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2716,6 +2716,109 @@ enum scan_balance {
 	SCAN_FILE,
 };
 
+static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc)
+{
+	unsigned long file;
+	struct lruvec *target_lruvec;
+
+	target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
+
+	/*
+	 * Flush the memory cgroup stats, so that we read accurate per-memcg
+	 * lruvec stats for heuristics.
+	 */
+	mem_cgroup_flush_stats();
+
+	/*
+	 * Determine the scan balance between anon and file LRUs.
+	 */
+	spin_lock_irq(&target_lruvec->lru_lock);
+	sc->anon_cost = target_lruvec->anon_cost;
+	sc->file_cost = target_lruvec->file_cost;
+	spin_unlock_irq(&target_lruvec->lru_lock);
+
+	/*
+	 * Target desirable inactive:active list ratios for the anon
+	 * and file LRU lists.
+	 */
+	if (!sc->force_deactivate) {
+		unsigned long refaults;
+
+		refaults = lruvec_page_state(target_lruvec,
+				WORKINGSET_ACTIVATE_ANON);
+		if (refaults != target_lruvec->refaults[0] ||
+			inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
+			sc->may_deactivate |= DEACTIVATE_ANON;
+		else
+			sc->may_deactivate &= ~DEACTIVATE_ANON;
+
+		/*
+		 * When refaults are being observed, it means a new
+		 * workingset is being established. Deactivate to get
+		 * rid of any stale active pages quickly.
+		 */
+		refaults = lruvec_page_state(target_lruvec,
+				WORKINGSET_ACTIVATE_FILE);
+		if (refaults != target_lruvec->refaults[1] ||
+		    inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
+			sc->may_deactivate |= DEACTIVATE_FILE;
+		else
+			sc->may_deactivate &= ~DEACTIVATE_FILE;
+	} else
+		sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
+
+	/*
+	 * If we have plenty of inactive file pages that aren't
+	 * thrashing, try to reclaim those first before touching
+	 * anonymous pages.
+	 */
+	file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
+	if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
+		sc->cache_trim_mode = 1;
+	else
+		sc->cache_trim_mode = 0;
+
+	/*
+	 * Prevent the reclaimer from falling into the cache trap: as
+	 * cache pages start out inactive, every cache fault will tip
+	 * the scan balance towards the file LRU.  And as the file LRU
+	 * shrinks, so does the window for rotation from references.
+	 * This means we have a runaway feedback loop where a tiny
+	 * thrashing file LRU becomes infinitely more attractive than
+	 * anon pages.  Try to detect this based on file LRU size.
+	 */
+	if (!cgroup_reclaim(sc)) {
+		unsigned long total_high_wmark = 0;
+		unsigned long free, anon;
+		int z;
+
+		free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
+		file = node_page_state(pgdat, NR_ACTIVE_FILE) +
+			   node_page_state(pgdat, NR_INACTIVE_FILE);
+
+		for (z = 0; z < MAX_NR_ZONES; z++) {
+			struct zone *zone = &pgdat->node_zones[z];
+
+			if (!managed_zone(zone))
+				continue;
+
+			total_high_wmark += high_wmark_pages(zone);
+		}
+
+		/*
+		 * Consider anon: if that's low too, this isn't a
+		 * runaway file reclaim problem, but rather just
+		 * extreme pressure. Reclaim as per usual then.
+		 */
+		anon = node_page_state(pgdat, NR_INACTIVE_ANON);
+
+		sc->file_is_tiny =
+			file + free <= total_high_wmark &&
+			!(sc->may_deactivate & DEACTIVATE_ANON) &&
+			anon >> sc->priority;
+	}
+}
+
 /*
  * Determine how aggressively the anon and file LRU lists should be
  * scanned.  The relative value of each set of LRU lists is determined
@@ -3186,109 +3289,16 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
 	unsigned long nr_reclaimed, nr_scanned;
 	struct lruvec *target_lruvec;
 	bool reclaimable = false;
-	unsigned long file;
 
 	target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
 
 again:
-	/*
-	 * Flush the memory cgroup stats, so that we read accurate per-memcg
-	 * lruvec stats for heuristics.
-	 */
-	mem_cgroup_flush_stats();
-
 	memset(&sc->nr, 0, sizeof(sc->nr));
 
 	nr_reclaimed = sc->nr_reclaimed;
 	nr_scanned = sc->nr_scanned;
 
-	/*
-	 * Determine the scan balance between anon and file LRUs.
-	 */
-	spin_lock_irq(&target_lruvec->lru_lock);
-	sc->anon_cost = target_lruvec->anon_cost;
-	sc->file_cost = target_lruvec->file_cost;
-	spin_unlock_irq(&target_lruvec->lru_lock);
-
-	/*
-	 * Target desirable inactive:active list ratios for the anon
-	 * and file LRU lists.
-	 */
-	if (!sc->force_deactivate) {
-		unsigned long refaults;
-
-		refaults = lruvec_page_state(target_lruvec,
-				WORKINGSET_ACTIVATE_ANON);
-		if (refaults != target_lruvec->refaults[0] ||
-			inactive_is_low(target_lruvec, LRU_INACTIVE_ANON))
-			sc->may_deactivate |= DEACTIVATE_ANON;
-		else
-			sc->may_deactivate &= ~DEACTIVATE_ANON;
-
-		/*
-		 * When refaults are being observed, it means a new
-		 * workingset is being established. Deactivate to get
-		 * rid of any stale active pages quickly.
-		 */
-		refaults = lruvec_page_state(target_lruvec,
-				WORKINGSET_ACTIVATE_FILE);
-		if (refaults != target_lruvec->refaults[1] ||
-		    inactive_is_low(target_lruvec, LRU_INACTIVE_FILE))
-			sc->may_deactivate |= DEACTIVATE_FILE;
-		else
-			sc->may_deactivate &= ~DEACTIVATE_FILE;
-	} else
-		sc->may_deactivate = DEACTIVATE_ANON | DEACTIVATE_FILE;
-
-	/*
-	 * If we have plenty of inactive file pages that aren't
-	 * thrashing, try to reclaim those first before touching
-	 * anonymous pages.
-	 */
-	file = lruvec_page_state(target_lruvec, NR_INACTIVE_FILE);
-	if (file >> sc->priority && !(sc->may_deactivate & DEACTIVATE_FILE))
-		sc->cache_trim_mode = 1;
-	else
-		sc->cache_trim_mode = 0;
-
-	/*
-	 * Prevent the reclaimer from falling into the cache trap: as
-	 * cache pages start out inactive, every cache fault will tip
-	 * the scan balance towards the file LRU.  And as the file LRU
-	 * shrinks, so does the window for rotation from references.
-	 * This means we have a runaway feedback loop where a tiny
-	 * thrashing file LRU becomes infinitely more attractive than
-	 * anon pages.  Try to detect this based on file LRU size.
-	 */
-	if (!cgroup_reclaim(sc)) {
-		unsigned long total_high_wmark = 0;
-		unsigned long free, anon;
-		int z;
-
-		free = sum_zone_node_page_state(pgdat->node_id, NR_FREE_PAGES);
-		file = node_page_state(pgdat, NR_ACTIVE_FILE) +
-			   node_page_state(pgdat, NR_INACTIVE_FILE);
-
-		for (z = 0; z < MAX_NR_ZONES; z++) {
-			struct zone *zone = &pgdat->node_zones[z];
-			if (!managed_zone(zone))
-				continue;
-
-			total_high_wmark += high_wmark_pages(zone);
-		}
-
-		/*
-		 * Consider anon: if that's low too, this isn't a
-		 * runaway file reclaim problem, but rather just
-		 * extreme pressure. Reclaim as per usual then.
-		 */
-		anon = node_page_state(pgdat, NR_INACTIVE_ANON);
-
-		sc->file_is_tiny =
-			file + free <= total_high_wmark &&
-			!(sc->may_deactivate & DEACTIVATE_ANON) &&
-			anon >> sc->priority;
-	}
+	prepare_scan_count(pgdat, sc);
 
 	shrink_node_memcgs(pgdat, sc);
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:23 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:23 -0700
Subject: [PATCH v6 4/9] mm: multigenerational lru: groundwork
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-5-yuzhao@google.com>

Evictable pages are divided into multiple generations for each lruvec.
The youngest generation number is stored in lrugen->max_seq for both
anon and file types as they're aged on an equal footing. The oldest
generation numbers are stored in lrugen->min_seq[] separately for anon
and file types as clean file pages may be evicted regardless of swap
constraints. These three variables are monotonically increasing.

Generation numbers are truncated into order_base_2(MAX_NR_GENS+1) bits
in order to fit into the gen counter in folio->flags. Each truncated
generation number is an index to lrugen->lists[]. The sliding window
technique is used to track at least MIN_NR_GENS and at most
MAX_NR_GENS generations.

There are two conceptually independent processes (as in manufacturing
process): "the aging", which produces young generations, and "the
eviction", which consumes old generations. They form a closed-loop
system, i.e., "the page reclaim". Both processes can be triggered
separately from userspace for the purposes of working set estimation
and proactive reclaim. These features are required to optimize job
scheduling in data centers. The variable size of the sliding window is
designed for such use cases.

To avoid confusions, the terms "hot" and "cold" will be applied to the
multigenerational lru, as a new convention; the terms "active" and
"inactive" will be applied to the active/inactive lru, as usual.

The protection of hot pages and the selection of cold pages are based
on page access channels and patterns. There are two access channels:
one thru page tables and the other thru file descriptors. The
protection of the former channel is by design stronger because:
1) The uncertainty in determining the access patterns of the former
   channel is higher due to the approximation of the accessed bit.
2) The cost of evicting the former channel is higher due to the TLB
   flushes required and the likelihood of encountering the dirty bit.
3) The penalty of underprotecting the former channel is higher because
   applications usually don't prepare themselves for major faults like
   they do for blocked I/O. For example, GUI applications commonly use
   dedicated I/O threads to avoid blocking the rendering threads.
There are also two access patterns: one with temporal locality and the
other without. For the reasons listed above, the former channel is
assumed to follow the former pattern unless VM_SEQ_READ or
VM_RAND_READ is present and the latter channel is assumed to follow
the latter pattern unless outlying refaults have been observed.

The "outlying refaults" will be addressed in [PATCH 07/10]. A few
macros, i.e., LRU_REFS_*, used in that patch are added in this one to
make the patchset less diffy.

A page is added to the youngest generation on faulting. The aging
needs to check the accessed bit at least twice before handing this
page over to the eviction. The first check takes care of the accessed
bit set on the initial fault; the second check makes sure this page
hasn't been used since then. This process, AKA second chance, requires
a minimum of two generations, hence MIN_NR_GENS.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 fs/fuse/dev.c                     |   3 +-
 include/linux/cgroup.h            |  15 +-
 include/linux/mm.h                |  37 +++++
 include/linux/mm_inline.h         | 189 ++++++++++++++++++++++
 include/linux/mmzone.h            |  76 +++++++++
 include/linux/page-flags-layout.h |  19 ++-
 include/linux/page-flags.h        |   4 +-
 include/linux/sched.h             |   4 +
 kernel/bounds.c                   |   3 +
 kernel/cgroup/cgroup-internal.h   |   1 -
 mm/huge_memory.c                  |   3 +-
 mm/memcontrol.c                   |   2 +
 mm/memory.c                       |   7 +
 mm/mm_init.c                      |   6 +-
 mm/page_alloc.c                   |   1 +
 mm/swap.c                         |   9 +-
 mm/vmscan.c                       | 259 ++++++++++++++++++++++++++++++
 17 files changed, 623 insertions(+), 15 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index cd54a529460d..769139a8be86 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -785,7 +785,8 @@ static int fuse_check_page(struct page *page)
 	       1 << PG_active |
 	       1 << PG_workingset |
 	       1 << PG_reclaim |
-	       1 << PG_waiters))) {
+	       1 << PG_waiters |
+	       LRU_GEN_MASK | LRU_REFS_MASK))) {
 		dump_page(page, "fuse: trying to steal weird page");
 		return 1;
 	}
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 75c151413fda..b145025f3eac 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -432,6 +432,18 @@ static inline void cgroup_put(struct cgroup *cgrp)
 	css_put(&cgrp->self);
 }
 
+extern struct mutex cgroup_mutex;
+
+static inline void cgroup_lock(void)
+{
+	mutex_lock(&cgroup_mutex);
+}
+
+static inline void cgroup_unlock(void)
+{
+	mutex_unlock(&cgroup_mutex);
+}
+
 /**
  * task_css_set_check - obtain a task's css_set with extra access conditions
  * @task: the task to obtain css_set for
@@ -446,7 +458,6 @@ static inline void cgroup_put(struct cgroup *cgrp)
  * as locks used during the cgroup_subsys::attach() methods.
  */
 #ifdef CONFIG_PROVE_RCU
-extern struct mutex cgroup_mutex;
 extern spinlock_t css_set_lock;
 #define task_css_set_check(task, __c)					\
 	rcu_dereference_check((task)->cgroups,				\
@@ -707,6 +718,8 @@ struct cgroup;
 static inline u64 cgroup_id(const struct cgroup *cgrp) { return 1; }
 static inline void css_get(struct cgroup_subsys_state *css) {}
 static inline void css_put(struct cgroup_subsys_state *css) {}
+static inline void cgroup_lock(void) {}
+static inline void cgroup_unlock(void) {}
 static inline int cgroup_attach_task_all(struct task_struct *from,
 					 struct task_struct *t) { return 0; }
 static inline int cgroupstats_build(struct cgroupstats *stats,
diff --git a/include/linux/mm.h b/include/linux/mm.h
index a7e4a9e7d807..fadbf8e6abcd 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -227,6 +227,7 @@ int overcommit_policy_handler(struct ctl_table *, int, void *, size_t *,
 #define PAGE_ALIGNED(addr)	IS_ALIGNED((unsigned long)(addr), PAGE_SIZE)
 
 #define lru_to_page(head) (list_entry((head)->prev, struct page, lru))
+#define lru_to_folio(head) (list_entry((head)->prev, struct folio, lru))
 
 void setup_initial_init_mm(void *start_code, void *end_code,
 			   void *end_data, void *brk);
@@ -1070,6 +1071,8 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf);
 #define ZONES_PGOFF		(NODES_PGOFF - ZONES_WIDTH)
 #define LAST_CPUPID_PGOFF	(ZONES_PGOFF - LAST_CPUPID_WIDTH)
 #define KASAN_TAG_PGOFF		(LAST_CPUPID_PGOFF - KASAN_TAG_WIDTH)
+#define LRU_GEN_PGOFF		(KASAN_TAG_PGOFF - LRU_GEN_WIDTH)
+#define LRU_REFS_PGOFF		(LRU_GEN_PGOFF - LRU_REFS_WIDTH)
 
 /*
  * Define the bit shifts to access each section.  For non-existent
@@ -1920,6 +1923,40 @@ static inline void unmap_mapping_range(struct address_space *mapping,
 		loff_t const holebegin, loff_t const holelen, int even_cows) { }
 #endif
 
+#ifdef CONFIG_LRU_GEN
+static inline void task_enter_lru_fault(void)
+{
+	WARN_ON_ONCE(current->in_lru_fault);
+
+	current->in_lru_fault = 1;
+}
+
+static inline void task_exit_lru_fault(void)
+{
+	WARN_ON_ONCE(!current->in_lru_fault);
+
+	current->in_lru_fault = 0;
+}
+
+static inline bool task_in_lru_fault(void)
+{
+	return current->in_lru_fault;
+}
+#else
+static inline void task_enter_lru_fault(void)
+{
+}
+
+static inline void task_exit_lru_fault(void)
+{
+}
+
+static inline bool task_in_lru_fault(void)
+{
+	return false;
+}
+#endif /* CONFIG_LRU_GEN */
+
 static inline void unmap_shared_mapping_range(struct address_space *mapping,
 		loff_t const holebegin, loff_t const holelen)
 {
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index e2ec68b0515c..5f239f67f36b 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -90,11 +90,194 @@ static __always_inline enum lru_list folio_lru_list(struct folio *folio)
 	return lru;
 }
 
+#ifdef CONFIG_LRU_GEN
+
+static inline bool lru_gen_enabled(void)
+{
+#ifdef CONFIG_LRU_GEN_ENABLED
+	DECLARE_STATIC_KEY_TRUE(lru_gen_static_key);
+
+	return static_branch_likely(&lru_gen_static_key);
+#else
+	DECLARE_STATIC_KEY_FALSE(lru_gen_static_key);
+
+	return static_branch_unlikely(&lru_gen_static_key);
+#endif
+}
+
+static inline int lru_gen_from_seq(unsigned long seq)
+{
+	return seq % MAX_NR_GENS;
+}
+
+static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
+{
+	unsigned long max_seq = lruvec->lrugen.max_seq;
+
+	VM_BUG_ON(gen >= MAX_NR_GENS);
+
+	/* see the comment on MIN_NR_GENS */
+	return gen == lru_gen_from_seq(max_seq) || gen == lru_gen_from_seq(max_seq - 1);
+}
+
+static inline void lru_gen_update_size(struct lruvec *lruvec, enum lru_list lru,
+				       int zone, long delta)
+{
+	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+
+	lockdep_assert_held(&lruvec->lru_lock);
+	WARN_ON_ONCE(delta != (int)delta);
+
+	__mod_lruvec_state(lruvec, NR_LRU_BASE + lru, delta);
+	__mod_zone_page_state(&pgdat->node_zones[zone], NR_ZONE_LRU_BASE + lru, delta);
+}
+
+static inline void lru_gen_balance_size(struct lruvec *lruvec, struct folio *folio,
+					int old_gen, int new_gen)
+{
+	int type = folio_is_file_lru(folio);
+	int zone = folio_zonenum(folio);
+	int delta = folio_nr_pages(folio);
+	enum lru_list lru = type * LRU_FILE;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	VM_BUG_ON(old_gen != -1 && old_gen >= MAX_NR_GENS);
+	VM_BUG_ON(new_gen != -1 && new_gen >= MAX_NR_GENS);
+	VM_BUG_ON(old_gen == -1 && new_gen == -1);
+
+	if (old_gen >= 0)
+		WRITE_ONCE(lrugen->nr_pages[old_gen][type][zone],
+			   lrugen->nr_pages[old_gen][type][zone] - delta);
+	if (new_gen >= 0)
+		WRITE_ONCE(lrugen->nr_pages[new_gen][type][zone],
+			   lrugen->nr_pages[new_gen][type][zone] + delta);
+
+	if (old_gen < 0) {
+		if (lru_gen_is_active(lruvec, new_gen))
+			lru += LRU_ACTIVE;
+		lru_gen_update_size(lruvec, lru, zone, delta);
+		return;
+	}
+
+	if (new_gen < 0) {
+		if (lru_gen_is_active(lruvec, old_gen))
+			lru += LRU_ACTIVE;
+		lru_gen_update_size(lruvec, lru, zone, -delta);
+		return;
+	}
+
+	if (!lru_gen_is_active(lruvec, old_gen) && lru_gen_is_active(lruvec, new_gen)) {
+		lru_gen_update_size(lruvec, lru, zone, -delta);
+		lru_gen_update_size(lruvec, lru + LRU_ACTIVE, zone, delta);
+	}
+
+	/* Promotion is legit while a page is on an lru list, but demotion isn't. */
+	VM_BUG_ON(lru_gen_is_active(lruvec, old_gen) && !lru_gen_is_active(lruvec, new_gen));
+}
+
+static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
+{
+	int gen;
+	unsigned long old_flags, new_flags;
+	int type = folio_is_file_lru(folio);
+	int zone = folio_zonenum(folio);
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	if (folio_test_unevictable(folio) || !lrugen->enabled)
+		return false;
+	/*
+	 * There are three cases for this page:
+	 * 1) If it shouldn't be evicted, e.g., it was just faulted in, add it
+	 *    to the youngest generation.
+	 * 2) If it can't be evicted immediately, i.e., it's an anon page and
+	 *    not in swapcache, or a dirty page pending writeback, add it to the
+	 *    second oldest generation.
+	 * 3) If it may be evicted immediately, e.g., it's a clean page, add it
+	 *    to the oldest generation.
+	 */
+	if (folio_test_active(folio))
+		gen = lru_gen_from_seq(lrugen->max_seq);
+	else if ((!type && !folio_test_swapcache(folio)) ||
+		 (folio_test_reclaim(folio) &&
+		  (folio_test_dirty(folio) || folio_test_writeback(folio))))
+		gen = lru_gen_from_seq(lrugen->min_seq[type] + 1);
+	else
+		gen = lru_gen_from_seq(lrugen->min_seq[type]);
+
+	do {
+		new_flags = old_flags = READ_ONCE(folio->flags);
+		VM_BUG_ON_FOLIO(new_flags & LRU_GEN_MASK, folio);
+
+		new_flags &= ~(LRU_GEN_MASK | BIT(PG_active));
+		new_flags |= (gen + 1UL) << LRU_GEN_PGOFF;
+	} while (cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
+
+	lru_gen_balance_size(lruvec, folio, -1, gen);
+	/* for folio_rotate_reclaimable() */
+	if (reclaiming)
+		list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]);
+	else
+		list_add(&folio->lru, &lrugen->lists[gen][type][zone]);
+
+	return true;
+}
+
+static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
+{
+	int gen;
+	unsigned long old_flags, new_flags;
+
+	do {
+		new_flags = old_flags = READ_ONCE(folio->flags);
+		if (!(new_flags & LRU_GEN_MASK))
+			return false;
+
+		VM_BUG_ON_FOLIO(folio_test_active(folio), folio);
+		VM_BUG_ON_FOLIO(folio_test_unevictable(folio), folio);
+
+		gen = ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+
+		new_flags &= ~LRU_GEN_MASK;
+		/* for shrink_page_list() */
+		if (reclaiming)
+			new_flags &= ~(BIT(PG_referenced) | BIT(PG_reclaim));
+		else if (lru_gen_is_active(lruvec, gen))
+			new_flags |= BIT(PG_active);
+	} while (cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
+
+	lru_gen_balance_size(lruvec, folio, gen, -1);
+	list_del(&folio->lru);
+
+	return true;
+}
+
+#else
+
+static inline bool lru_gen_enabled(void)
+{
+	return false;
+}
+
+static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
+{
+	return false;
+}
+
+static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
+{
+	return false;
+}
+
+#endif /* CONFIG_LRU_GEN */
+
 static __always_inline
 void lruvec_add_folio(struct lruvec *lruvec, struct folio *folio)
 {
 	enum lru_list lru = folio_lru_list(folio);
 
+	if (lru_gen_add_folio(lruvec, folio, false))
+		return;
+
 	update_lru_size(lruvec, lru, folio_zonenum(folio),
 			folio_nr_pages(folio));
 	list_add(&folio->lru, &lruvec->lists[lru]);
@@ -111,6 +294,9 @@ void lruvec_add_folio_tail(struct lruvec *lruvec, struct folio *folio)
 {
 	enum lru_list lru = folio_lru_list(folio);
 
+	if (lru_gen_add_folio(lruvec, folio, true))
+		return;
+
 	update_lru_size(lruvec, lru, folio_zonenum(folio),
 			folio_nr_pages(folio));
 	list_add_tail(&folio->lru, &lruvec->lists[lru]);
@@ -125,6 +311,9 @@ static __always_inline void add_page_to_lru_list_tail(struct page *page,
 static __always_inline
 void lruvec_del_folio(struct lruvec *lruvec, struct folio *folio)
 {
+	if (lru_gen_del_folio(lruvec, folio, false))
+		return;
+
 	list_del(&folio->lru);
 	update_lru_size(lruvec, folio_lru_list(folio), folio_zonenum(folio),
 			-folio_nr_pages(folio));
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 936dc0b6c226..371c7210d510 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -303,6 +303,78 @@ enum lruvec_flags {
 					 */
 };
 
+struct lruvec;
+
+#define LRU_GEN_MASK		((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
+#define LRU_REFS_MASK		((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
+
+#ifdef CONFIG_LRU_GEN
+
+#define MIN_LRU_BATCH		BITS_PER_LONG
+#define MAX_LRU_BATCH		(MIN_LRU_BATCH * 128)
+
+/*
+ * Evictable pages are divided into multiple generations. The youngest and the
+ * oldest generation numbers, max_seq and min_seq, are monotonically increasing.
+ * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
+ * offset within MAX_NR_GENS, gen, indexes the lru list of the corresponding
+ * generation. The gen counter in folio->flags stores gen+1 while a page is on
+ * lrugen->lists[]. Otherwise, it stores 0.
+ *
+ * A page is added to the youngest generation on faulting. The aging needs to
+ * check the accessed bit at least twice before handing this page over to the
+ * eviction. The first check takes care of the accessed bit set on the initial
+ * fault; the second check makes sure this page hasn't been used since then.
+ * This process, AKA second chance, requires a minimum of two generations,
+ * hence MIN_NR_GENS. And to be compatible with the active/inactive lru, these
+ * two generations are mapped to the active; the rest of generations, if they
+ * exist, are mapped to the inactive. PG_active is always cleared while a page
+ * is on lrugen->lists[] so that demotion, which happens consequently when the
+ * aging creates a new generation, needs not to worry about it.
+ */
+#define MIN_NR_GENS		2U
+#define MAX_NR_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
+
+struct lru_gen_struct {
+	/* the aging increments the youngest generation number */
+	unsigned long max_seq;
+	/* the eviction increments the oldest generation numbers */
+	unsigned long min_seq[ANON_AND_FILE];
+	/* the birth time of each generation in jiffies */
+	unsigned long timestamps[MAX_NR_GENS];
+	/* the multigenerational lru lists */
+	struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
+	/* the sizes of the above lists */
+	unsigned long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
+	/* whether the multigenerational lru is enabled */
+	bool enabled;
+};
+
+void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec);
+
+#ifdef CONFIG_MEMCG
+void lru_gen_init_memcg(struct mem_cgroup *memcg);
+void lru_gen_free_memcg(struct mem_cgroup *memcg);
+#endif
+
+#else /* !CONFIG_LRU_GEN */
+
+static inline void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec)
+{
+}
+
+#ifdef CONFIG_MEMCG
+static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
+{
+}
+
+static inline void lru_gen_free_memcg(struct mem_cgroup *memcg)
+{
+}
+#endif
+
+#endif /* CONFIG_LRU_GEN */
+
 struct lruvec {
 	struct list_head		lists[NR_LRU_LISTS];
 	/* per lruvec lru_lock for memcg */
@@ -320,6 +392,10 @@ struct lruvec {
 	unsigned long			refaults[ANON_AND_FILE];
 	/* Various lruvec state flags (enum lruvec_flags) */
 	unsigned long			flags;
+#ifdef CONFIG_LRU_GEN
+	/* evictable pages divided into generations */
+	struct lru_gen_struct		lrugen;
+#endif
 #ifdef CONFIG_MEMCG
 	struct pglist_data *pgdat;
 #endif
diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-layout.h
index ef1e3e736e14..8cdbbdccb5ad 100644
--- a/include/linux/page-flags-layout.h
+++ b/include/linux/page-flags-layout.h
@@ -26,6 +26,14 @@
 
 #define ZONES_WIDTH		ZONES_SHIFT
 
+#ifdef CONFIG_LRU_GEN
+/* LRU_GEN_WIDTH is generated from order_base_2(CONFIG_NR_LRU_GENS + 1). */
+#define LRU_REFS_WIDTH		(CONFIG_TIERS_PER_GEN - 2)
+#else
+#define LRU_GEN_WIDTH		0
+#define LRU_REFS_WIDTH		0
+#endif /* CONFIG_LRU_GEN */
+
 #ifdef CONFIG_SPARSEMEM
 #include <asm/sparsemem.h>
 #define SECTIONS_SHIFT	(MAX_PHYSMEM_BITS - SECTION_SIZE_BITS)
@@ -55,7 +63,8 @@
 #define SECTIONS_WIDTH		0
 #endif
 
-#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_REFS_WIDTH + SECTIONS_WIDTH + NODES_SHIFT \
+	<= BITS_PER_LONG - NR_PAGEFLAGS
 #define NODES_WIDTH		NODES_SHIFT
 #elif defined(CONFIG_SPARSEMEM_VMEMMAP)
 #error "Vmemmap: No space for nodes field in page flags"
@@ -89,8 +98,8 @@
 #define LAST_CPUPID_SHIFT 0
 #endif
 
-#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT \
-	<= BITS_PER_LONG - NR_PAGEFLAGS
+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_REFS_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
+	KASAN_TAG_WIDTH + LAST_CPUPID_SHIFT <= BITS_PER_LONG - NR_PAGEFLAGS
 #define LAST_CPUPID_WIDTH LAST_CPUPID_SHIFT
 #else
 #define LAST_CPUPID_WIDTH 0
@@ -100,8 +109,8 @@
 #define LAST_CPUPID_NOT_IN_PAGE_FLAGS
 #endif
 
-#if ZONES_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH \
-	> BITS_PER_LONG - NR_PAGEFLAGS
+#if ZONES_WIDTH + LRU_GEN_WIDTH + LRU_REFS_WIDTH + SECTIONS_WIDTH + NODES_WIDTH + \
+	KASAN_TAG_WIDTH + LAST_CPUPID_WIDTH > BITS_PER_LONG - NR_PAGEFLAGS
 #error "Not enough bits in page flags"
 #endif
 
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index b5f14d581113..d609c71ea228 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -961,7 +961,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
 	 1UL << PG_private	| 1UL << PG_private_2	|	\
 	 1UL << PG_writeback	| 1UL << PG_reserved	|	\
 	 1UL << PG_slab		| 1UL << PG_active 	|	\
-	 1UL << PG_unevictable	| __PG_MLOCKED)
+	 1UL << PG_unevictable	| __PG_MLOCKED | LRU_GEN_MASK)
 
 /*
  * Flags checked when a page is prepped for return by the page allocator.
@@ -972,7 +972,7 @@ static inline void ClearPageSlabPfmemalloc(struct page *page)
  * alloc-free cycle to prevent from reusing the page.
  */
 #define PAGE_FLAGS_CHECK_AT_PREP	\
-	(PAGEFLAGS_MASK & ~__PG_HWPOISON)
+	((PAGEFLAGS_MASK & ~__PG_HWPOISON) | LRU_GEN_MASK | LRU_REFS_MASK)
 
 #define PAGE_FLAGS_PRIVATE				\
 	(1UL << PG_private | 1UL << PG_private_2)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 78c351e35fec..69b35d61c017 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -909,6 +909,10 @@ struct task_struct {
 #ifdef CONFIG_MEMCG
 	unsigned			in_user_fault:1;
 #endif
+#ifdef CONFIG_LRU_GEN
+	/* whether the lru algorithm may apply for this access */
+	unsigned			in_lru_fault:1;
+#endif
 #ifdef CONFIG_COMPAT_BRK
 	unsigned			brk_randomized:1;
 #endif
diff --git a/kernel/bounds.c b/kernel/bounds.c
index 9795d75b09b2..aba13aa7336c 100644
--- a/kernel/bounds.c
+++ b/kernel/bounds.c
@@ -22,6 +22,9 @@ int main(void)
 	DEFINE(NR_CPUS_BITS, ilog2(CONFIG_NR_CPUS));
 #endif
 	DEFINE(SPINLOCK_SIZE, sizeof(spinlock_t));
+#ifdef CONFIG_LRU_GEN
+	DEFINE(LRU_GEN_WIDTH, order_base_2(CONFIG_NR_LRU_GENS + 1));
+#endif
 	/* End of constants */
 
 	return 0;
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index bfbeabc17a9d..bec59189e206 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -146,7 +146,6 @@ struct cgroup_mgctx {
 #define DEFINE_CGROUP_MGCTX(name)						\
 	struct cgroup_mgctx name = CGROUP_MGCTX_INIT(name)
 
-extern struct mutex cgroup_mutex;
 extern spinlock_t css_set_lock;
 extern struct cgroup_subsys *cgroup_subsys[];
 extern struct list_head cgroup_roots;
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index e5483347291c..2e2ca7ecff63 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2364,7 +2364,8 @@ static void __split_huge_page_tail(struct page *head, int tail,
 #ifdef CONFIG_64BIT
 			 (1L << PG_arch_2) |
 #endif
-			 (1L << PG_dirty)));
+			 (1L << PG_dirty) |
+			 LRU_GEN_MASK | LRU_REFS_MASK));
 
 	/* ->mapping in first tail page is compound_mapcount */
 	VM_BUG_ON_PAGE(tail > 2 && page_tail->mapping != TAIL_MAPPING,
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 2ed5f2a0879d..a4359a278e31 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -5098,6 +5098,7 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
 
 static void mem_cgroup_free(struct mem_cgroup *memcg)
 {
+	lru_gen_free_memcg(memcg);
 	memcg_wb_domain_exit(memcg);
 	__mem_cgroup_free(memcg);
 }
@@ -5161,6 +5162,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
 	memcg->deferred_split_queue.split_queue_len = 0;
 #endif
 	idr_replace(&mem_cgroup_idr, memcg, memcg->id.id);
+	lru_gen_init_memcg(memcg);
 	return memcg;
 fail:
 	mem_cgroup_id_remove(memcg);
diff --git a/mm/memory.c b/mm/memory.c
index ead6c7d4b9a1..bc54be1d613f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4745,6 +4745,7 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
 			   unsigned int flags, struct pt_regs *regs)
 {
 	vm_fault_t ret;
+	bool lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));
 
 	__set_current_state(TASK_RUNNING);
 
@@ -4766,11 +4767,17 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
 	if (flags & FAULT_FLAG_USER)
 		mem_cgroup_enter_user_fault();
 
+	if (lru_fault)
+		task_enter_lru_fault();
+
 	if (unlikely(is_vm_hugetlb_page(vma)))
 		ret = hugetlb_fault(vma->vm_mm, vma, address, flags);
 	else
 		ret = __handle_mm_fault(vma, address, flags);
 
+	if (lru_fault)
+		task_exit_lru_fault();
+
 	if (flags & FAULT_FLAG_USER) {
 		mem_cgroup_exit_user_fault();
 		/*
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 9ddaf0e1b0ab..0d7b2bd2454a 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -65,14 +65,16 @@ void __init mminit_verify_pageflags_layout(void)
 
 	shift = 8 * sizeof(unsigned long);
 	width = shift - SECTIONS_WIDTH - NODES_WIDTH - ZONES_WIDTH
-		- LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH;
+		- LAST_CPUPID_SHIFT - KASAN_TAG_WIDTH - LRU_GEN_WIDTH - LRU_REFS_WIDTH;
 	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_widths",
-		"Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Flags %d\n",
+		"Section %d Node %d Zone %d Lastcpupid %d Kasantag %d Gen %d Tier %d Flags %d\n",
 		SECTIONS_WIDTH,
 		NODES_WIDTH,
 		ZONES_WIDTH,
 		LAST_CPUPID_WIDTH,
 		KASAN_TAG_WIDTH,
+		LRU_GEN_WIDTH,
+		LRU_REFS_WIDTH,
 		NR_PAGEFLAGS);
 	mminit_dprintk(MMINIT_TRACE, "pageflags_layout_shifts",
 		"Section %d Node %d Zone %d Lastcpupid %d Kasantag %d\n",
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c5952749ad40..05e02fbd1e5d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -7416,6 +7416,7 @@ static void __meminit pgdat_init_internals(struct pglist_data *pgdat)
 
 	pgdat_page_ext_init(pgdat);
 	lruvec_init(&pgdat->__lruvec);
+	lru_gen_init_state(NULL, &pgdat->__lruvec);
 }
 
 static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx, int nid,
diff --git a/mm/swap.c b/mm/swap.c
index e8c9dc6d0377..d7dde3b7d4b5 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -462,6 +462,11 @@ void folio_add_lru(struct folio *folio)
 	VM_BUG_ON_FOLIO(folio_test_active(folio) && folio_test_unevictable(folio), folio);
 	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
 
+	/* see the comment in lru_gen_add_folio() */
+	if (lru_gen_enabled() && !folio_test_unevictable(folio) &&
+	    task_in_lru_fault() && !(current->flags & PF_MEMALLOC))
+		folio_set_active(folio);
+
 	folio_get(folio);
 	local_lock(&lru_pvecs.lock);
 	pvec = this_cpu_ptr(&lru_pvecs.lru_add);
@@ -563,7 +568,7 @@ static void lru_deactivate_file_fn(struct page *page, struct lruvec *lruvec)
 
 static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec)
 {
-	if (PageActive(page) && !PageUnevictable(page)) {
+	if (!PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) {
 		int nr_pages = thp_nr_pages(page);
 
 		del_page_from_lru_list(page, lruvec);
@@ -677,7 +682,7 @@ void deactivate_file_page(struct page *page)
  */
 void deactivate_page(struct page *page)
 {
-	if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) {
+	if (PageLRU(page) && !PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) {
 		struct pagevec *pvec;
 
 		local_lock(&lru_pvecs.lock);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b6c5fd885216..0e487c0ffe17 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -50,6 +50,7 @@
 #include <linux/printk.h>
 #include <linux/dax.h>
 #include <linux/psi.h>
+#include <linux/memory.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -3040,6 +3041,264 @@ static bool can_age_anon_pages(struct pglist_data *pgdat,
 	return can_demote(pgdat->node_id, sc);
 }
 
+#ifdef CONFIG_LRU_GEN
+
+/******************************************************************************
+ *                          shorthand helpers
+ ******************************************************************************/
+
+#define for_each_gen_type_zone(gen, type, zone)				\
+	for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++)			\
+		for ((type) = 0; (type) < ANON_AND_FILE; (type)++)	\
+			for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
+
+static int folio_lru_gen(struct folio *folio)
+{
+	unsigned long flags = READ_ONCE(folio->flags);
+
+	return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+}
+
+static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
+{
+	struct pglist_data *pgdat = NODE_DATA(nid);
+
+#ifdef CONFIG_MEMCG
+	if (memcg) {
+		struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
+
+		/* for hotadd_new_pgdat() */
+		if (!lruvec->pgdat)
+			lruvec->pgdat = pgdat;
+
+		return lruvec;
+	}
+#endif
+	return pgdat ? &pgdat->__lruvec : NULL;
+}
+
+static int get_nr_gens(struct lruvec *lruvec, int type)
+{
+	return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1;
+}
+
+static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
+{
+	/*
+	 * Ideally anon and file min_seq should be in sync. But swapping isn't
+	 * as reliable as dropping clean file pages, e.g., out of swap space. So
+	 * allow file min_seq to advance and leave anon min_seq behind, but not
+	 * the other way around.
+	 */
+	return get_nr_gens(lruvec, 1) >= MIN_NR_GENS &&
+	       get_nr_gens(lruvec, 1) <= get_nr_gens(lruvec, 0) &&
+	       get_nr_gens(lruvec, 0) <= MAX_NR_GENS;
+}
+
+/******************************************************************************
+ *                          state change
+ ******************************************************************************/
+
+#ifdef CONFIG_LRU_GEN_ENABLED
+DEFINE_STATIC_KEY_TRUE(lru_gen_static_key);
+#else
+DEFINE_STATIC_KEY_FALSE(lru_gen_static_key);
+#endif
+
+static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
+{
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	if (lrugen->enabled) {
+		enum lru_list lru;
+
+		for_each_evictable_lru(lru) {
+			if (!list_empty(&lruvec->lists[lru]))
+				return false;
+		}
+	} else {
+		int gen, type, zone;
+
+		for_each_gen_type_zone(gen, type, zone) {
+			if (!list_empty(&lrugen->lists[gen][type][zone]))
+				return false;
+
+			/* unlikely but not a bug when reset_batch_size() is pending */
+			VM_WARN_ON(lrugen->nr_pages[gen][type][zone]);
+		}
+	}
+
+	return true;
+}
+
+static bool fill_evictable(struct lruvec *lruvec)
+{
+	enum lru_list lru;
+	int remaining = MAX_LRU_BATCH;
+
+	for_each_evictable_lru(lru) {
+		int type = is_file_lru(lru);
+		bool active = is_active_lru(lru);
+		struct list_head *head = &lruvec->lists[lru];
+
+		while (!list_empty(head)) {
+			bool success;
+			struct folio *folio = lru_to_folio(head);
+
+			VM_BUG_ON_FOLIO(folio_test_unevictable(folio), folio);
+			VM_BUG_ON_FOLIO(folio_test_active(folio) != active, folio);
+			VM_BUG_ON_FOLIO(folio_is_file_lru(folio) != type, folio);
+			VM_BUG_ON_FOLIO(folio_lru_gen(folio) < MAX_NR_GENS, folio);
+
+			lruvec_del_folio(lruvec, folio);
+			success = lru_gen_add_folio(lruvec, folio, false);
+			VM_BUG_ON(!success);
+
+			if (!--remaining)
+				return false;
+		}
+	}
+
+	return true;
+}
+
+static bool drain_evictable(struct lruvec *lruvec)
+{
+	int gen, type, zone;
+	int remaining = MAX_LRU_BATCH;
+
+	for_each_gen_type_zone(gen, type, zone) {
+		struct list_head *head = &lruvec->lrugen.lists[gen][type][zone];
+
+		while (!list_empty(head)) {
+			bool success;
+			struct folio *folio = lru_to_folio(head);
+
+			VM_BUG_ON_FOLIO(folio_test_unevictable(folio), folio);
+			VM_BUG_ON_FOLIO(folio_test_active(folio), folio);
+			VM_BUG_ON_FOLIO(folio_is_file_lru(folio) != type, folio);
+			VM_BUG_ON_FOLIO(folio_zonenum(folio) != zone, folio);
+
+			success = lru_gen_del_folio(lruvec, folio, false);
+			VM_BUG_ON(!success);
+			lruvec_add_folio(lruvec, folio);
+
+			if (!--remaining)
+				return false;
+		}
+	}
+
+	return true;
+}
+
+static void lru_gen_change_state(bool enable)
+{
+	static DEFINE_MUTEX(state_mutex);
+
+	struct mem_cgroup *memcg;
+
+	mem_hotplug_begin();
+	cgroup_lock();
+	mutex_lock(&state_mutex);
+
+	if (enable == lru_gen_enabled())
+		goto unlock;
+
+	if (enable)
+		static_branch_enable(&lru_gen_static_key);
+	else
+		static_branch_disable(&lru_gen_static_key);
+
+	memcg = mem_cgroup_iter(NULL, NULL, NULL);
+	do {
+		int nid;
+
+		for_each_node(nid) {
+			struct lruvec *lruvec = get_lruvec(memcg, nid);
+
+			if (!lruvec)
+				continue;
+
+			spin_lock_irq(&lruvec->lru_lock);
+
+			VM_BUG_ON(!seq_is_valid(lruvec));
+			VM_BUG_ON(!state_is_valid(lruvec));
+
+			lruvec->lrugen.enabled = enable;
+
+			while (!(enable ? fill_evictable(lruvec) : drain_evictable(lruvec))) {
+				spin_unlock_irq(&lruvec->lru_lock);
+				cond_resched();
+				spin_lock_irq(&lruvec->lru_lock);
+			}
+
+			spin_unlock_irq(&lruvec->lru_lock);
+		}
+
+		cond_resched();
+	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
+unlock:
+	mutex_unlock(&state_mutex);
+	cgroup_unlock();
+	mem_hotplug_done();
+}
+
+/******************************************************************************
+ *                          initialization
+ ******************************************************************************/
+
+void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec)
+{
+	int i;
+	int gen, type, zone;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	lrugen->max_seq = MIN_NR_GENS + 1;
+	lrugen->enabled = lru_gen_enabled();
+
+	for (i = 0; i <= MIN_NR_GENS + 1; i++)
+		lrugen->timestamps[i] = jiffies;
+
+	for_each_gen_type_zone(gen, type, zone)
+		INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
+}
+
+#ifdef CONFIG_MEMCG
+void lru_gen_init_memcg(struct mem_cgroup *memcg)
+{
+	int nid;
+
+	for_each_node(nid) {
+		struct lruvec *lruvec = get_lruvec(memcg, nid);
+
+		lru_gen_init_state(memcg, lruvec);
+	}
+}
+
+void lru_gen_free_memcg(struct mem_cgroup *memcg)
+{
+	int nid;
+
+	for_each_node(nid) {
+		struct lruvec *lruvec = get_lruvec(memcg, nid);
+
+		VM_BUG_ON(memchr_inv(lruvec->lrugen.nr_pages, 0,
+				     sizeof(lruvec->lrugen.nr_pages)));
+	}
+}
+#endif
+
+static int __init init_lru_gen(void)
+{
+	BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS);
+	BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS);
+
+	return 0;
+};
+late_initcall(init_lru_gen);
+
+#endif /* CONFIG_LRU_GEN */
+
 static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
 {
 	unsigned long nr[NR_LRU_LISTS];
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:24 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:24 -0700
Subject: [PATCH v6 5/9] mm: multigenerational lru: mm_struct list
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-6-yuzhao@google.com>

To exploit spatial locality, the aging prefers to walk page tables to
search for young PTEs. And this patch paves the way for that.

An mm_struct list is maintained for each memcg, and an mm_struct
follows its owner task to the new memcg when this task is migrated.

To avoid confusions, the term "iteration" specifically means the
traversal of an entire mm_struct list; the term "walk" will be applied
to page tables and the rmap, as usual.

A page table walker, i.e., a thread in the aging path, iterates an
mm_struct list and calls walk_page_range() with each mm_struct on this
list. The iteration finishes when it reaches the end of this list.
When multiple page table walkers iterate the same list, each of them
gets a unique mm_struct; therefore the aging can run concurrently.

This infra also provides the following optimizations:
1) It tracks the usage of mm_struct's between context switches so that
   page table walkers may skip processes that have been sleeping since
   the last iteration.
2) It provides generational Bloom filters to record populated branches
   so that page table walkers may reduce their search space based on
   the query results.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 fs/exec.c                  |   2 +
 include/linux/memcontrol.h |   5 +
 include/linux/mm_inline.h  |   5 +
 include/linux/mm_types.h   |  78 ++++++++
 include/linux/mmzone.h     |  61 +++++++
 kernel/exit.c              |   1 +
 kernel/fork.c              |   9 +
 kernel/sched/core.c        |   1 +
 mm/memcontrol.c            |  24 +++
 mm/vmscan.c                | 352 +++++++++++++++++++++++++++++++++++++
 10 files changed, 538 insertions(+)

diff --git a/fs/exec.c b/fs/exec.c
index 537d92c41105..308aa88ca15f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1005,6 +1005,7 @@ static int exec_mmap(struct mm_struct *mm)
 	active_mm = tsk->active_mm;
 	tsk->active_mm = mm;
 	tsk->mm = mm;
+	lru_gen_add_mm(mm);
 	/*
 	 * This prevents preemption while active_mm is being loaded and
 	 * it and mm are being updated, which could cause problems for
@@ -1015,6 +1016,7 @@ static int exec_mmap(struct mm_struct *mm)
 	if (!IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
 		local_irq_enable();
 	activate_mm(active_mm, mm);
+	lru_gen_use_mm(mm);
 	if (IS_ENABLED(CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM))
 		local_irq_enable();
 	tsk->mm->vmacache_seqnum = 0;
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 0c5c403f4be6..aba18cd101db 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -340,6 +340,11 @@ struct mem_cgroup {
 	struct deferred_split deferred_split_queue;
 #endif
 
+#ifdef CONFIG_LRU_GEN
+	/* per-memcg mm_struct list */
+	struct lru_gen_mm_list mm_list;
+#endif
+
 	struct mem_cgroup_per_node *nodeinfo[];
 };
 
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 5f239f67f36b..717a2290acb3 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -110,6 +110,11 @@ static inline int lru_gen_from_seq(unsigned long seq)
 	return seq % MAX_NR_GENS;
 }
 
+static inline int lru_hist_from_seq(unsigned long seq)
+{
+	return seq % NR_HIST_GENS;
+}
+
 static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
 {
 	unsigned long max_seq = lruvec->lrugen.max_seq;
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index c3a6e6209600..bdbd9390adb3 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -3,6 +3,7 @@
 #define _LINUX_MM_TYPES_H
 
 #include <linux/mm_types_task.h>
+#include <linux/sched.h>
 
 #include <linux/auxvec.h>
 #include <linux/list.h>
@@ -16,6 +17,8 @@
 #include <linux/page-flags-layout.h>
 #include <linux/workqueue.h>
 #include <linux/seqlock.h>
+#include <linux/nodemask.h>
+#include <linux/mmdebug.h>
 
 #include <asm/mmu.h>
 
@@ -646,6 +649,22 @@ struct mm_struct {
 #ifdef CONFIG_IOMMU_SUPPORT
 		u32 pasid;
 #endif
+#ifdef CONFIG_LRU_GEN
+		struct {
+			/* this mm_struct is on lru_gen_mm_list */
+			struct list_head list;
+#ifdef CONFIG_MEMCG
+			/* points to the memcg of "owner" above */
+			struct mem_cgroup *memcg;
+#endif
+			/*
+			 * Set when switching to this mm_struct, as a hint of
+			 * whether it has been used since the last time per-node
+			 * page table walkers cleared the corresponding bits.
+			 */
+			nodemask_t nodes;
+		} lru_gen;
+#endif /* CONFIG_LRU_GEN */
 	} __randomize_layout;
 
 	/*
@@ -672,6 +691,65 @@ static inline cpumask_t *mm_cpumask(struct mm_struct *mm)
 	return (struct cpumask *)&mm->cpu_bitmap;
 }
 
+#ifdef CONFIG_LRU_GEN
+
+struct lru_gen_mm_list {
+	/* mm_struct list for page table walkers */
+	struct list_head fifo;
+	/* protects the list above */
+	spinlock_t lock;
+};
+
+void lru_gen_add_mm(struct mm_struct *mm);
+void lru_gen_del_mm(struct mm_struct *mm);
+#ifdef CONFIG_MEMCG
+void lru_gen_migrate_mm(struct mm_struct *mm);
+#endif
+
+static inline void lru_gen_init_mm(struct mm_struct *mm)
+{
+	INIT_LIST_HEAD(&mm->lru_gen.list);
+#ifdef CONFIG_MEMCG
+	mm->lru_gen.memcg = NULL;
+#endif
+	nodes_clear(mm->lru_gen.nodes);
+}
+
+static inline void lru_gen_use_mm(struct mm_struct *mm)
+{
+	/* unlikely but not a bug when racing with lru_gen_migrate_mm() */
+	VM_WARN_ON(list_empty(&mm->lru_gen.list));
+
+	if (!(current->flags & PF_KTHREAD) && !nodes_full(mm->lru_gen.nodes))
+		nodes_setall(mm->lru_gen.nodes);
+}
+
+#else /* !CONFIG_LRU_GEN */
+
+static inline void lru_gen_add_mm(struct mm_struct *mm)
+{
+}
+
+static inline void lru_gen_del_mm(struct mm_struct *mm)
+{
+}
+
+#ifdef CONFIG_MEMCG
+static inline void lru_gen_migrate_mm(struct mm_struct *mm)
+{
+}
+#endif
+
+static inline void lru_gen_init_mm(struct mm_struct *mm)
+{
+}
+
+static inline void lru_gen_use_mm(struct mm_struct *mm)
+{
+}
+
+#endif /* CONFIG_LRU_GEN */
+
 struct mmu_gather;
 extern void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm);
 extern void tlb_gather_mmu_fullmm(struct mmu_gather *tlb, struct mm_struct *mm);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 371c7210d510..5b9bc2532c5b 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -335,6 +335,13 @@ struct lruvec;
 #define MIN_NR_GENS		2U
 #define MAX_NR_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
 
+/* whether to keep historical stats for evicted generations */
+#ifdef CONFIG_LRU_GEN_STATS
+#define NR_HIST_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
+#else
+#define NR_HIST_GENS		1U
+#endif
+
 struct lru_gen_struct {
 	/* the aging increments the youngest generation number */
 	unsigned long max_seq;
@@ -350,6 +357,58 @@ struct lru_gen_struct {
 	bool enabled;
 };
 
+enum {
+	MM_PTE_TOTAL,	/* total leaf entries */
+	MM_PTE_OLD,	/* old leaf entries */
+	MM_PTE_YOUNG,	/* young leaf entries */
+	MM_PMD_TOTAL,	/* total non-leaf entries */
+	MM_PMD_FOUND,	/* non-leaf entries found in Bloom filters */
+	MM_PMD_ADDED,	/* non-leaf entries added to Bloom filters */
+	NR_MM_STATS
+};
+
+/* mnemonic codes for the mm stats above */
+#define MM_STAT_CODES		"toydfa"
+
+/* double-buffering Bloom filters */
+#define NR_BLOOM_FILTERS	2
+
+struct lru_gen_mm_state {
+	/* set to max_seq after each iteration */
+	unsigned long seq;
+	/* where the current iteration starts (inclusive) */
+	struct list_head *head;
+	/* where the last iteration ends (exclusive) */
+	struct list_head *tail;
+	/* to wait for the last page table walker to finish */
+	struct wait_queue_head wait;
+	/* Bloom filters flip after each iteration */
+	unsigned long *filters[NR_BLOOM_FILTERS];
+	/* the mm stats for debugging */
+	unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
+	/* the number of concurrent page table walkers */
+	int nr_walkers;
+};
+
+struct lru_gen_mm_walk {
+	/* the lruvec under reclaim */
+	struct lruvec *lruvec;
+	/* unstable max_seq from lru_gen_struct */
+	unsigned long max_seq;
+	/* the next address within an mm to scan */
+	unsigned long next_addr;
+	/* to batch page table entries */
+	unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)];
+	/* to batch promoted pages */
+	int nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
+	/* to batch the mm stats */
+	int mm_stats[NR_MM_STATS];
+	/* total batched items */
+	int batched;
+	bool can_swap;
+	bool full_scan;
+};
+
 void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec);
 
 #ifdef CONFIG_MEMCG
@@ -395,6 +454,8 @@ struct lruvec {
 #ifdef CONFIG_LRU_GEN
 	/* evictable pages divided into generations */
 	struct lru_gen_struct		lrugen;
+	/* to concurrently iterate lru_gen_mm_list */
+	struct lru_gen_mm_state		mm_state;
 #endif
 #ifdef CONFIG_MEMCG
 	struct pglist_data *pgdat;
diff --git a/kernel/exit.c b/kernel/exit.c
index f702a6a63686..f8bf605c9ba5 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -463,6 +463,7 @@ void mm_update_next_owner(struct mm_struct *mm)
 		goto retry;
 	}
 	WRITE_ONCE(mm->owner, c);
+	lru_gen_migrate_mm(mm);
 	task_unlock(c);
 	put_task_struct(c);
 }
diff --git a/kernel/fork.c b/kernel/fork.c
index 3244cc56b697..be1b58bf11bb 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1078,6 +1078,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
 		goto fail_nocontext;
 
 	mm->user_ns = get_user_ns(user_ns);
+	lru_gen_init_mm(mm);
 	return mm;
 
 fail_nocontext:
@@ -1120,6 +1121,7 @@ static inline void __mmput(struct mm_struct *mm)
 	}
 	if (mm->binfmt)
 		module_put(mm->binfmt->module);
+	lru_gen_del_mm(mm);
 	mmdrop(mm);
 }
 
@@ -2603,6 +2605,13 @@ pid_t kernel_clone(struct kernel_clone_args *args)
 		get_task_struct(p);
 	}
 
+	if (IS_ENABLED(CONFIG_LRU_GEN) && !(clone_flags & CLONE_VM)) {
+		/* lock the task to synchronize with memcg migration */
+		task_lock(p);
+		lru_gen_add_mm(p->mm);
+		task_unlock(p);
+	}
+
 	wake_up_new_task(p);
 
 	/* forking complete and child started to run, tell ptracer */
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 77563109c0ea..268b869d326e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4956,6 +4956,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
 		 * finish_task_switch()'s mmdrop().
 		 */
 		switch_mm_irqs_off(prev->active_mm, next->mm, next);
+		lru_gen_use_mm(next->mm);
 
 		if (!prev->mm) {                        // from kernel
 			/* will mmdrop() in finish_task_switch(). */
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index a4359a278e31..33576f6814b5 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -6135,6 +6135,29 @@ static void mem_cgroup_move_task(void)
 }
 #endif
 
+#ifdef CONFIG_LRU_GEN
+static void mem_cgroup_attach(struct cgroup_taskset *tset)
+{
+	struct cgroup_subsys_state *css;
+	struct task_struct *task = NULL;
+
+	cgroup_taskset_for_each_leader(task, css, tset)
+		break;
+
+	if (!task)
+		return;
+
+	task_lock(task);
+	if (task->mm && task->mm->owner == task)
+		lru_gen_migrate_mm(task->mm);
+	task_unlock(task);
+}
+#else
+static void mem_cgroup_attach(struct cgroup_taskset *tset)
+{
+}
+#endif /* CONFIG_LRU_GEN */
+
 static int seq_puts_memcg_tunable(struct seq_file *m, unsigned long value)
 {
 	if (value == PAGE_COUNTER_MAX)
@@ -6478,6 +6501,7 @@ struct cgroup_subsys memory_cgrp_subsys = {
 	.css_reset = mem_cgroup_css_reset,
 	.css_rstat_flush = mem_cgroup_css_rstat_flush,
 	.can_attach = mem_cgroup_can_attach,
+	.attach = mem_cgroup_attach,
 	.cancel_attach = mem_cgroup_cancel_attach,
 	.post_attach = mem_cgroup_move_task,
 	.dfl_cftypes = memory_files,
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 0e487c0ffe17..5eaf22aa446a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3095,6 +3095,342 @@ static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
 	       get_nr_gens(lruvec, 0) <= MAX_NR_GENS;
 }
 
+/******************************************************************************
+ *                          mm_struct list
+ ******************************************************************************/
+
+static struct lru_gen_mm_list *get_mm_list(struct mem_cgroup *memcg)
+{
+	static struct lru_gen_mm_list mm_list = {
+		.fifo = LIST_HEAD_INIT(mm_list.fifo),
+		.lock = __SPIN_LOCK_UNLOCKED(mm_list.lock),
+	};
+
+#ifdef CONFIG_MEMCG
+	if (memcg)
+		return &memcg->mm_list;
+#endif
+	return &mm_list;
+}
+
+void lru_gen_add_mm(struct mm_struct *mm)
+{
+	int nid;
+	struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm);
+	struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
+
+	VM_BUG_ON_MM(!list_empty(&mm->lru_gen.list), mm);
+#ifdef CONFIG_MEMCG
+	VM_BUG_ON_MM(mm->lru_gen.memcg, mm);
+	mm->lru_gen.memcg = memcg;
+#endif
+	spin_lock(&mm_list->lock);
+
+	list_add_tail(&mm->lru_gen.list, &mm_list->fifo);
+
+	for_each_node(nid) {
+		struct lruvec *lruvec = get_lruvec(memcg, nid);
+
+		if (!lruvec)
+			continue;
+
+		if (lruvec->mm_state.tail == &mm_list->fifo)
+			lruvec->mm_state.tail = lruvec->mm_state.tail->prev;
+	}
+
+	spin_unlock(&mm_list->lock);
+}
+
+void lru_gen_del_mm(struct mm_struct *mm)
+{
+	int nid;
+	struct lru_gen_mm_list *mm_list;
+	struct mem_cgroup *memcg = NULL;
+
+	if (list_empty(&mm->lru_gen.list))
+		return;
+
+#ifdef CONFIG_MEMCG
+	memcg = mm->lru_gen.memcg;
+#endif
+	mm_list = get_mm_list(memcg);
+
+	spin_lock(&mm_list->lock);
+
+	for_each_node(nid) {
+		struct lruvec *lruvec = get_lruvec(memcg, nid);
+
+		if (!lruvec)
+			continue;
+
+		if (lruvec->mm_state.tail == &mm->lru_gen.list)
+			lruvec->mm_state.tail = lruvec->mm_state.tail->next;
+
+		if (lruvec->mm_state.head != &mm->lru_gen.list)
+			continue;
+
+		lruvec->mm_state.head = lruvec->mm_state.head->next;
+		if (lruvec->mm_state.head == &mm_list->fifo)
+			WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
+	}
+
+	list_del_init(&mm->lru_gen.list);
+
+	spin_unlock(&mm_list->lock);
+
+#ifdef CONFIG_MEMCG
+	mem_cgroup_put(mm->lru_gen.memcg);
+	mm->lru_gen.memcg = NULL;
+#endif
+}
+
+#ifdef CONFIG_MEMCG
+void lru_gen_migrate_mm(struct mm_struct *mm)
+{
+	struct mem_cgroup *memcg;
+
+	lockdep_assert_held(&mm->owner->alloc_lock);
+
+	if (mem_cgroup_disabled())
+		return;
+
+	rcu_read_lock();
+	memcg = mem_cgroup_from_task(mm->owner);
+	rcu_read_unlock();
+	if (memcg == mm->lru_gen.memcg)
+		return;
+
+	VM_BUG_ON_MM(!mm->lru_gen.memcg, mm);
+	VM_BUG_ON_MM(list_empty(&mm->lru_gen.list), mm);
+
+	lru_gen_del_mm(mm);
+	lru_gen_add_mm(mm);
+}
+#endif
+
+/*
+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
+ * bits in a bitmap, k is the number of hash functions and n is the number of
+ * inserted items.
+ *
+ * Page table walkers use one of the two filters to reduce their search space.
+ * To get rid of non-leaf entries that no longer have enough leaf entries, the
+ * aging uses the double-buffering technique to flip to the other filter each
+ * time it creates a new generation. For non-leaf entries that have enough
+ * leaf entries, the aging carries them over to the next generation in
+ * walk_pmd_range(); the eviction also report them when walking the rmap
+ * in lru_gen_look_around().
+ *
+ * For future optimizations:
+ * 1) It's not necessary to keep both filters all the time. The spare one can be
+ *    freed after the RCU grace period and reallocated if needed again.
+ * 2) And when reallocating, it's worth scaling its size according to the number
+ *    of inserted entries in the other filter, to reduce the memory overhead on
+ *    small systems and false positives on large systems.
+ * 3) Jenkins' hash function is an alternative to Knuth's.
+ */
+#define BLOOM_FILTER_SHIFT	15
+
+static inline int filter_gen_from_seq(unsigned long seq)
+{
+	return seq % NR_BLOOM_FILTERS;
+}
+
+static void get_item_key(void *item, int *key)
+{
+	u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
+
+	BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
+
+	key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
+	key[1] = hash >> BLOOM_FILTER_SHIFT;
+}
+
+static void clear_bloom_filter(struct lruvec *lruvec, unsigned long seq)
+{
+	unsigned long *filter;
+	int gen = filter_gen_from_seq(seq);
+
+	lockdep_assert_held(&get_mm_list(lruvec_memcg(lruvec))->lock);
+
+	filter = lruvec->mm_state.filters[gen];
+	if (filter) {
+		bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
+		return;
+	}
+
+	filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT), GFP_ATOMIC);
+	WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
+}
+
+static void set_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
+{
+	int key[2];
+	unsigned long *filter;
+	int gen = filter_gen_from_seq(seq);
+
+	filter = READ_ONCE(lruvec->mm_state.filters[gen]);
+	if (!filter)
+		return;
+
+	get_item_key(item, key);
+
+	if (!test_bit(key[0], filter))
+		set_bit(key[0], filter);
+	if (!test_bit(key[1], filter))
+		set_bit(key[1], filter);
+}
+
+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
+{
+	int key[2];
+	unsigned long *filter;
+	int gen = filter_gen_from_seq(seq);
+
+	filter = READ_ONCE(lruvec->mm_state.filters[gen]);
+	if (!filter)
+		return false;
+
+	get_item_key(item, key);
+
+	return test_bit(key[0], filter) && test_bit(key[1], filter);
+}
+
+static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
+{
+	int i;
+	int hist = lru_hist_from_seq(walk->max_seq);
+
+	lockdep_assert_held(&get_mm_list(lruvec_memcg(lruvec))->lock);
+
+	for (i = 0; i < NR_MM_STATS; i++) {
+		WRITE_ONCE(lruvec->mm_state.stats[hist][i],
+			   lruvec->mm_state.stats[hist][i] + walk->mm_stats[i]);
+		walk->mm_stats[i] = 0;
+	}
+
+	if (NR_HIST_GENS == 1 || !last)
+		return;
+
+	hist = lru_hist_from_seq(walk->max_seq + 1);
+	for (i = 0; i < NR_MM_STATS; i++)
+		WRITE_ONCE(lruvec->mm_state.stats[hist][i], 0);
+}
+
+static bool should_skip_mm(struct mm_struct *mm, struct lru_gen_mm_walk *walk)
+{
+	int type;
+	unsigned long size = 0;
+	struct pglist_data *pgdat = lruvec_pgdat(walk->lruvec);
+
+	if (!walk->full_scan && cpumask_empty(mm_cpumask(mm)) &&
+	    !node_isset(pgdat->node_id, mm->lru_gen.nodes))
+		return true;
+
+	for (type = !walk->can_swap; type < ANON_AND_FILE; type++) {
+		size += type ? get_mm_counter(mm, MM_FILEPAGES) :
+			       get_mm_counter(mm, MM_ANONPAGES) +
+			       get_mm_counter(mm, MM_SHMEMPAGES);
+	}
+
+	if (size < MIN_LRU_BATCH)
+		return true;
+
+	if (mm_is_oom_victim(mm))
+		return true;
+
+	if (!mmget_not_zero(mm))
+		return true;
+
+	node_clear(pgdat->node_id, mm->lru_gen.nodes);
+
+	return false;
+}
+
+static bool get_next_mm(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
+			struct mm_struct **iter)
+{
+	bool first = false;
+	bool last = true;
+	struct mm_struct *mm = NULL;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
+	struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
+
+	/*
+	 * There are four interesting cases for this page table walker:
+	 * 1) It tries to start a new iteration of this list with a stale
+	 *    max_seq; there is nothing to be done.
+	 * 2) It's the first of the current generation, and it needs to prepare
+	 *    the Bloom filter for the next generation.
+	 * 3) It reaches the end of this list, and it needs to increment
+	 *    mm_state->seq; the iteration is done.
+	 * 4) It's the last of the current generation, and it needs to clear the
+	 *    historical mm stats for the next generation.
+	 */
+	if (*iter)
+		mmput_async(*iter);
+	else if (walk->max_seq <= READ_ONCE(mm_state->seq))
+		return false;
+
+	spin_lock(&mm_list->lock);
+
+	VM_BUG_ON(walk->max_seq > mm_state->seq + 1);
+	VM_BUG_ON(*iter && walk->max_seq < mm_state->seq);
+	VM_BUG_ON(*iter && !mm_state->nr_walkers);
+
+	if (walk->max_seq <= mm_state->seq) {
+		if (!*iter)
+			last = false;
+		goto done;
+	}
+
+	if (mm_state->head == &mm_list->fifo) {
+		VM_BUG_ON(mm_state->nr_walkers);
+		mm_state->head = mm_state->head->next;
+		first = true;
+	}
+
+	while (!mm && mm_state->head != &mm_list->fifo) {
+		mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
+
+		mm_state->head = mm_state->head->next;
+
+		/* full scan for those added after the last iteration */
+		if (mm_state->tail == &mm->lru_gen.list) {
+			mm_state->tail = mm_state->tail->next;
+			walk->full_scan = true;
+		}
+
+		if (should_skip_mm(mm, walk))
+			mm = NULL;
+	}
+
+	if (mm_state->head == &mm_list->fifo)
+		WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
+done:
+	if (*iter && !mm)
+		mm_state->nr_walkers--;
+	if (!*iter && mm)
+		mm_state->nr_walkers++;
+
+	if (mm_state->nr_walkers)
+		last = false;
+
+	if (mm && first)
+		clear_bloom_filter(lruvec, walk->max_seq + 1);
+
+	if (*iter || last)
+		reset_mm_stats(lruvec, walk, last);
+
+	spin_unlock(&mm_list->lock);
+
+	*iter = mm;
+
+	return last;
+}
+
 /******************************************************************************
  *                          state change
  ******************************************************************************/
@@ -3252,6 +3588,7 @@ void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec)
 	int i;
 	int gen, type, zone;
 	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
 
 	lrugen->max_seq = MIN_NR_GENS + 1;
 	lrugen->enabled = lru_gen_enabled();
@@ -3261,6 +3598,11 @@ void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec)
 
 	for_each_gen_type_zone(gen, type, zone)
 		INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]);
+
+	lruvec->mm_state.seq = MIN_NR_GENS;
+	lruvec->mm_state.head = &mm_list->fifo;
+	lruvec->mm_state.tail = &mm_list->fifo;
+	init_waitqueue_head(&lruvec->mm_state.wait);
 }
 
 #ifdef CONFIG_MEMCG
@@ -3268,6 +3610,9 @@ void lru_gen_init_memcg(struct mem_cgroup *memcg)
 {
 	int nid;
 
+	INIT_LIST_HEAD(&memcg->mm_list.fifo);
+	spin_lock_init(&memcg->mm_list.lock);
+
 	for_each_node(nid) {
 		struct lruvec *lruvec = get_lruvec(memcg, nid);
 
@@ -3280,10 +3625,16 @@ void lru_gen_free_memcg(struct mem_cgroup *memcg)
 	int nid;
 
 	for_each_node(nid) {
+		int i;
 		struct lruvec *lruvec = get_lruvec(memcg, nid);
 
 		VM_BUG_ON(memchr_inv(lruvec->lrugen.nr_pages, 0,
 				     sizeof(lruvec->lrugen.nr_pages)));
+
+		for (i = 0; i < NR_BLOOM_FILTERS; i++) {
+			bitmap_free(lruvec->mm_state.filters[i]);
+			lruvec->mm_state.filters[i] = NULL;
+		}
 	}
 }
 #endif
@@ -3292,6 +3643,7 @@ static int __init init_lru_gen(void)
 {
 	BUILD_BUG_ON(MIN_NR_GENS + 1 >= MAX_NR_GENS);
 	BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS);
+	BUILD_BUG_ON(sizeof(MM_STAT_CODES) != NR_MM_STATS + 1);
 
 	return 0;
 };
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:25 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:25 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-7-yuzhao@google.com>

To avoid confusions, the term "scan" will be applied to PTEs in a page
table and pages on an lru list. It emphasizes on consecutive elements
in a set rather than the data structure holding this set together.

The aging produces young generations. Given an lruvec, it iterates
lruvec_memcg()->mm_list and calls walk_page_range() with each
mm_struct on this list to scan PTEs for accessed pages. On finding a
young PTE, it clears the accessed bit and updates the gen counter of
the page mapped by this PTE to (max_seq%MAX_NR_GENS)+1. After each
iteration of this list, it increments max_seq. The aging is needed
before the eviction can continue when max_seq-min_seq+1 reaches
MIN_NR_GENS.

To avoid confusions, the terms "promotion" and "demotion" will be
applied to the multigenerational lru, as a new convention; the terms
"activation" and "deactivation" will be applied to the active/inactive
lru, as usual.

IOW, the aging promotes a page to the youngest generation when it
finds this page accessed thru page tables; demotion happens
consequently when it creates a new generation. Note that promotion
doesn't require any lru list operations in the aging path, only the
update of the gen counter and the lru sizes; demotion, unless as the
result of the creation of a new generation, requires lru list
operations, e.g., lru_deactivate_fn().

The aging uses the following optimizations when walking page tables:
1) It uses the accessed bit in non-leaf PMD entries, the hint from the
   CPU scheduler and the Bloom filters to reduce its search space.
2) It doesn't zigzag between a PGD table and the same PMD or PTE table
   spanning multiple VMAs. In other words, it finishes all the VMAs
   within the range of the same PMD or PTE table before it returns to
   a PGD table. This improves the cache performance for workloads that
   have large numbers of tiny VMAs, especially when
   CONFIG_PGTABLE_LEVELS=5.

The aging is only interested in accessed pages and therefore has the
complexity of O(nr_hot_evictable_pages). The worst case scenario is
the aging fails to exploit any spatial locality and the eviction has
to promote all accessed pages when walking the rmap, which is similar
to the active/inactive lru. However, generations still can provide
better temporal locality.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 include/linux/memcontrol.h |   6 +
 include/linux/mm.h         |   5 +
 include/linux/mmzone.h     |  10 +
 include/linux/oom.h        |  16 +
 include/linux/swap.h       |   4 +
 mm/oom_kill.c              |   4 +-
 mm/rmap.c                  |   7 +
 mm/vmscan.c                | 896 +++++++++++++++++++++++++++++++++++++
 8 files changed, 946 insertions(+), 2 deletions(-)

diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index aba18cd101db..028afdb81c10 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -1393,18 +1393,24 @@ mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
 
 static inline void lock_page_memcg(struct page *page)
 {
+	/* to match folio_memcg_rcu() */
+	rcu_read_lock();
 }
 
 static inline void unlock_page_memcg(struct page *page)
 {
+	rcu_read_unlock();
 }
 
 static inline void folio_memcg_lock(struct folio *folio)
 {
+	/* to match folio_memcg_rcu() */
+	rcu_read_lock();
 }
 
 static inline void folio_memcg_unlock(struct folio *folio)
 {
+	rcu_read_unlock();
 }
 
 static inline void mem_cgroup_handle_over_high(void)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index fadbf8e6abcd..3d42118b7f5e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -1599,6 +1599,11 @@ static inline unsigned long folio_pfn(struct folio *folio)
 	return page_to_pfn(&folio->page);
 }
 
+static inline struct folio *pfn_folio(unsigned long pfn)
+{
+	return page_folio(pfn_to_page(pfn));
+}
+
 /* MIGRATE_CMA and ZONE_MOVABLE do not allow pin pages */
 #ifdef CONFIG_MIGRATION
 static inline bool is_pinnable_page(struct page *page)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 5b9bc2532c5b..94af12507788 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -304,6 +304,7 @@ enum lruvec_flags {
 };
 
 struct lruvec;
+struct page_vma_mapped_walk;
 
 #define LRU_GEN_MASK		((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
 #define LRU_REFS_MASK		((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
@@ -410,6 +411,7 @@ struct lru_gen_mm_walk {
 };
 
 void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *lruvec);
+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
 
 #ifdef CONFIG_MEMCG
 void lru_gen_init_memcg(struct mem_cgroup *memcg);
@@ -422,6 +424,10 @@ static inline void lru_gen_init_state(struct mem_cgroup *memcg, struct lruvec *l
 {
 }
 
+static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
+{
+}
+
 #ifdef CONFIG_MEMCG
 static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
 {
@@ -1048,6 +1054,10 @@ typedef struct pglist_data {
 
 	unsigned long		flags;
 
+#ifdef CONFIG_LRU_GEN
+	/* kswap mm walk data */
+	struct lru_gen_mm_walk	mm_walk;
+#endif
 	ZONE_PADDING(_pad2_)
 
 	/* Per-node vmstats */
diff --git a/include/linux/oom.h b/include/linux/oom.h
index 2db9a1432511..9c7a4fae0661 100644
--- a/include/linux/oom.h
+++ b/include/linux/oom.h
@@ -57,6 +57,22 @@ struct oom_control {
 extern struct mutex oom_lock;
 extern struct mutex oom_adj_mutex;
 
+#ifdef CONFIG_MMU
+extern struct task_struct *oom_reaper_list;
+extern struct wait_queue_head oom_reaper_wait;
+
+static inline bool oom_reaping_in_progress(void)
+{
+	/* a racy check can be used to reduce the chance of overkilling */
+	return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait);
+}
+#else
+static inline bool oom_reaping_in_progress(void)
+{
+	return false;
+}
+#endif
+
 static inline void set_current_oom_origin(void)
 {
 	current->signal->oom_flag_origin = true;
diff --git a/include/linux/swap.h b/include/linux/swap.h
index d1ea44b31f19..bb93bba97115 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -137,6 +137,10 @@ union swap_header {
  */
 struct reclaim_state {
 	unsigned long reclaimed_slab;
+#ifdef CONFIG_LRU_GEN
+	/* per-thread mm walk data */
+	struct lru_gen_mm_walk *mm_walk;
+#endif
 };
 
 #ifdef __KERNEL__
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index 1ddabefcfb5a..ef5860fc7d22 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -508,8 +508,8 @@ bool process_shares_mm(struct task_struct *p, struct mm_struct *mm)
  * victim (if that is possible) to help the OOM killer to move on.
  */
 static struct task_struct *oom_reaper_th;
-static DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);
-static struct task_struct *oom_reaper_list;
+DECLARE_WAIT_QUEUE_HEAD(oom_reaper_wait);
+struct task_struct *oom_reaper_list;
 static DEFINE_SPINLOCK(oom_reaper_lock);
 
 bool __oom_reap_task_mm(struct mm_struct *mm)
diff --git a/mm/rmap.c b/mm/rmap.c
index 163ac4e6bcee..2f023e6c0f82 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -73,6 +73,7 @@
 #include <linux/page_idle.h>
 #include <linux/memremap.h>
 #include <linux/userfaultfd_k.h>
+#include <linux/mm_inline.h>
 
 #include <asm/tlbflush.h>
 
@@ -790,6 +791,12 @@ static bool page_referenced_one(struct page *page, struct vm_area_struct *vma,
 		}
 
 		if (pvmw.pte) {
+			if (lru_gen_enabled() && pte_young(*pvmw.pte) &&
+			    !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))) {
+				lru_gen_look_around(&pvmw);
+				referenced++;
+			}
+
 			if (ptep_clear_flush_young_notify(vma, address,
 						pvmw.pte)) {
 				/*
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 5eaf22aa446a..fbf1337a1632 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -51,6 +51,8 @@
 #include <linux/dax.h>
 #include <linux/psi.h>
 #include <linux/memory.h>
+#include <linux/pagewalk.h>
+#include <linux/shmem_fs.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -1555,6 +1557,11 @@ static unsigned int shrink_page_list(struct list_head *page_list,
 		if (!sc->may_unmap && page_mapped(page))
 			goto keep_locked;
 
+		/* folio_update_gen() tried to promote this page? */
+		if (lru_gen_enabled() && !ignore_references &&
+		    page_mapped(page) && PageReferenced(page))
+			goto keep_locked;
+
 		may_enter_fs = (sc->gfp_mask & __GFP_FS) ||
 			(PageSwapCache(page) && (sc->gfp_mask & __GFP_IO));
 
@@ -3047,6 +3054,15 @@ static bool can_age_anon_pages(struct pglist_data *pgdat,
  *                          shorthand helpers
  ******************************************************************************/
 
+#define DEFINE_MAX_SEQ(lruvec)						\
+	unsigned long max_seq = READ_ONCE((lruvec)->lrugen.max_seq)
+
+#define DEFINE_MIN_SEQ(lruvec)						\
+	unsigned long min_seq[ANON_AND_FILE] = {			\
+		READ_ONCE((lruvec)->lrugen.min_seq[0]),			\
+		READ_ONCE((lruvec)->lrugen.min_seq[1]),			\
+	}
+
 #define for_each_gen_type_zone(gen, type, zone)				\
 	for ((gen) = 0; (gen) < MAX_NR_GENS; (gen)++)			\
 		for ((type) = 0; (type) < ANON_AND_FILE; (type)++)	\
@@ -3077,6 +3093,12 @@ static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
 	return pgdat ? &pgdat->__lruvec : NULL;
 }
 
+static int get_swappiness(struct mem_cgroup *memcg)
+{
+	return mem_cgroup_get_nr_swap_pages(memcg) >= MIN_LRU_BATCH ?
+	       mem_cgroup_swappiness(memcg) : 0;
+}
+
 static int get_nr_gens(struct lruvec *lruvec, int type)
 {
 	return lruvec->lrugen.max_seq - lruvec->lrugen.min_seq[type] + 1;
@@ -3431,6 +3453,869 @@ static bool get_next_mm(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
 	return last;
 }
 
+/******************************************************************************
+ *                          the aging
+ ******************************************************************************/
+
+static void folio_update_gen(struct folio *folio, struct lru_gen_mm_walk *walk)
+{
+	unsigned long old_flags, new_flags;
+	int type = folio_is_file_lru(folio);
+	int zone = folio_zonenum(folio);
+	int delta = folio_nr_pages(folio);
+	int old_gen, new_gen = lru_gen_from_seq(walk->max_seq);
+
+	do {
+		new_flags = old_flags = READ_ONCE(folio->flags);
+
+		/* for shrink_page_list() */
+		if (!(new_flags & LRU_GEN_MASK)) {
+			new_flags |= BIT(PG_referenced);
+			continue;
+		}
+
+		new_flags &= ~LRU_GEN_MASK;
+		new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
+	} while (new_flags != old_flags &&
+		 cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
+
+	old_gen = ((old_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+	if (old_gen < 0 || old_gen == new_gen)
+		return;
+
+	walk->batched++;
+	walk->nr_pages[old_gen][type][zone] -= delta;
+	walk->nr_pages[new_gen][type][zone] += delta;
+}
+
+static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
+{
+	unsigned long old_flags, new_flags;
+	int type = folio_is_file_lru(folio);
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
+
+	do {
+		new_flags = old_flags = READ_ONCE(folio->flags);
+		VM_BUG_ON_FOLIO(!(new_flags & LRU_GEN_MASK), folio);
+
+		new_gen = ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
+		/* folio_update_gen() has promoted this page? */
+		if (new_gen >= 0 && new_gen != old_gen)
+			return new_gen;
+
+		new_gen = (old_gen + 1) % MAX_NR_GENS;
+
+		new_flags &= ~LRU_GEN_MASK;
+		new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
+		/* for folio_end_writeback() */
+		if (reclaiming)
+			new_flags |= BIT(PG_reclaim);
+	} while (cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
+
+	lru_gen_balance_size(lruvec, folio, old_gen, new_gen);
+
+	return new_gen;
+}
+
+static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
+{
+	int gen, type, zone;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	walk->batched = 0;
+
+	for_each_gen_type_zone(gen, type, zone) {
+		enum lru_list lru = type * LRU_FILE;
+		int delta = walk->nr_pages[gen][type][zone];
+
+		if (!delta)
+			continue;
+
+		walk->nr_pages[gen][type][zone] = 0;
+		WRITE_ONCE(lrugen->nr_pages[gen][type][zone],
+			   lrugen->nr_pages[gen][type][zone] + delta);
+
+		if (lru_gen_is_active(lruvec, gen))
+			lru += LRU_ACTIVE;
+		lru_gen_update_size(lruvec, lru, zone, delta);
+	}
+}
+
+static int should_skip_vma(unsigned long start, unsigned long end, struct mm_walk *walk)
+{
+	struct address_space *mapping;
+	struct vm_area_struct *vma = walk->vma;
+	struct lru_gen_mm_walk *priv = walk->private;
+
+	if (!vma_is_accessible(vma) || is_vm_hugetlb_page(vma) ||
+	    (vma->vm_flags & (VM_LOCKED | VM_SPECIAL | VM_SEQ_READ | VM_RAND_READ)))
+		return true;
+
+	if (vma_is_anonymous(vma))
+		return !priv->can_swap;
+
+	if (WARN_ON_ONCE(!vma->vm_file || !vma->vm_file->f_mapping))
+		return true;
+
+	mapping = vma->vm_file->f_mapping;
+	if (!mapping->a_ops->writepage)
+		return true;
+
+	return (shmem_mapping(mapping) && !priv->can_swap) || mapping_unevictable(mapping);
+}
+
+/*
+ * Some userspace memory allocators map many single-page VMAs. Instead of
+ * returning back to the PGD table for each of such VMAs, finish an entire PMD
+ * table to reduce zigzags and improve cache performance.
+ */
+static bool get_next_vma(struct mm_walk *walk, unsigned long mask, unsigned long size,
+			 unsigned long *start, unsigned long *end)
+{
+	unsigned long next = round_up(*end, size);
+
+	VM_BUG_ON(mask & size);
+	VM_BUG_ON(*start >= *end);
+	VM_BUG_ON((next & mask) != (*start & mask));
+
+	while (walk->vma) {
+		if (next >= walk->vma->vm_end) {
+			walk->vma = walk->vma->vm_next;
+			continue;
+		}
+
+		if ((next & mask) != (walk->vma->vm_start & mask))
+			return false;
+
+		if (should_skip_vma(walk->vma->vm_start, walk->vma->vm_end, walk)) {
+			walk->vma = walk->vma->vm_next;
+			continue;
+		}
+
+		*start = max(next, walk->vma->vm_start);
+		next = (next | ~mask) + 1;
+		/* rounded-up boundaries can wrap to 0 */
+		*end = next && next < walk->vma->vm_end ? next : walk->vma->vm_end;
+
+		return true;
+	}
+
+	return false;
+}
+
+static bool suitable_to_scan(int total, int young)
+{
+	int n = clamp_t(int, cache_line_size() / sizeof(pte_t), 2, 8);
+
+	/* suitable if the average number of young PTEs per cacheline is >=1 */
+	return young * n >= total;
+}
+
+static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
+			   struct mm_walk *walk)
+{
+	int i;
+	pte_t *pte;
+	spinlock_t *ptl;
+	unsigned long addr;
+	int total = 0;
+	int young = 0;
+	struct lru_gen_mm_walk *priv = walk->private;
+	struct mem_cgroup *memcg = lruvec_memcg(priv->lruvec);
+	struct pglist_data *pgdat = lruvec_pgdat(priv->lruvec);
+
+	VM_BUG_ON(pmd_leaf(*pmd));
+
+	pte = pte_offset_map_lock(walk->mm, pmd, start & PMD_MASK, &ptl);
+	arch_enter_lazy_mmu_mode();
+restart:
+	for (i = pte_index(start), addr = start; addr != end; i++, addr += PAGE_SIZE) {
+		struct folio *folio;
+		unsigned long pfn = pte_pfn(pte[i]);
+
+		total++;
+		priv->mm_stats[MM_PTE_TOTAL]++;
+
+		if (!pte_present(pte[i]) || is_zero_pfn(pfn))
+			continue;
+
+		if (WARN_ON_ONCE(pte_devmap(pte[i]) || pte_special(pte[i])))
+			continue;
+
+		if (!pte_young(pte[i])) {
+			priv->mm_stats[MM_PTE_OLD]++;
+			continue;
+		}
+
+		VM_BUG_ON(!pfn_valid(pfn));
+		if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
+			continue;
+
+		folio = pfn_folio(pfn);
+		if (folio_nid(folio) != pgdat->node_id)
+			continue;
+
+		if (folio_memcg_rcu(folio) != memcg)
+			continue;
+
+		VM_BUG_ON(addr < walk->vma->vm_start || addr >= walk->vma->vm_end);
+		if (ptep_test_and_clear_young(walk->vma, addr, pte + i)) {
+			folio_update_gen(folio, priv);
+			priv->mm_stats[MM_PTE_YOUNG]++;
+			young++;
+		}
+
+		if (pte_dirty(pte[i]) && !folio_test_dirty(folio) &&
+		    !(folio_test_anon(folio) && folio_test_swapbacked(folio) &&
+		      !folio_test_swapcache(folio)))
+			folio_mark_dirty(folio);
+	}
+
+	if (i < PTRS_PER_PTE && get_next_vma(walk, PMD_MASK, PAGE_SIZE, &start, &end))
+		goto restart;
+
+	arch_leave_lazy_mmu_mode();
+	pte_unmap_unlock(pte, ptl);
+
+	return suitable_to_scan(total, young);
+}
+
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
+				  struct mm_walk *walk, unsigned long *start)
+{
+	int i;
+	pmd_t *pmd;
+	spinlock_t *ptl;
+	struct lru_gen_mm_walk *priv = walk->private;
+	struct mem_cgroup *memcg = lruvec_memcg(priv->lruvec);
+	struct pglist_data *pgdat = lruvec_pgdat(priv->lruvec);
+
+	VM_BUG_ON(pud_leaf(*pud));
+
+	/* try to batch at most 1+MIN_LRU_BATCH+1 entries */
+	if (*start == -1) {
+		*start = next;
+		return;
+	}
+
+	i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start);
+	if (i && i <= MIN_LRU_BATCH) {
+		__set_bit(i - 1, priv->bitmap);
+		return;
+	}
+
+	pmd = pmd_offset(pud, *start);
+	ptl = pmd_lock(walk->mm, pmd);
+	arch_enter_lazy_mmu_mode();
+
+	do {
+		struct folio *folio;
+		unsigned long pfn = pmd_pfn(pmd[i]);
+		unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start;
+
+		if (!pmd_present(pmd[i]) || is_huge_zero_pmd(pmd[i]))
+			goto next;
+
+		if (WARN_ON_ONCE(pmd_devmap(pmd[i])))
+			goto next;
+
+		if (!pmd_trans_huge(pmd[i])) {
+			if (IS_ENABLED(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG))
+				pmdp_test_and_clear_young(vma, addr, pmd + i);
+			goto next;
+		}
+
+		VM_BUG_ON(!pfn_valid(pfn));
+		if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
+			goto next;
+
+		folio = pfn_folio(pfn);
+		if (folio_nid(folio) != pgdat->node_id)
+			goto next;
+
+		if (folio_memcg_rcu(folio) != memcg)
+			goto next;
+
+		VM_BUG_ON(addr < vma->vm_start || addr >= vma->vm_end);
+		if (pmdp_test_and_clear_young(vma, addr, pmd + i)) {
+			folio_update_gen(folio, priv);
+			priv->mm_stats[MM_PTE_YOUNG]++;
+		}
+
+		if (pmd_dirty(pmd[i]) && !folio_test_dirty(folio) &&
+		    !(folio_test_anon(folio) && folio_test_swapbacked(folio) &&
+		      !folio_test_swapcache(folio)))
+			folio_mark_dirty(folio);
+next:
+		i = i > MIN_LRU_BATCH ? 0 :
+		    find_next_bit(priv->bitmap, MIN_LRU_BATCH, i) + 1;
+	} while (i <= MIN_LRU_BATCH);
+
+	arch_leave_lazy_mmu_mode();
+	spin_unlock(ptl);
+
+	*start = -1;
+	bitmap_zero(priv->bitmap, MIN_LRU_BATCH);
+}
+#else
+static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
+				  struct mm_walk *walk, unsigned long *start)
+{
+}
+#endif
+
+static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
+			   struct mm_walk *walk)
+{
+	int i;
+	pmd_t *pmd;
+	unsigned long next;
+	unsigned long addr;
+	struct vm_area_struct *vma;
+	unsigned long pos = -1;
+	struct lru_gen_mm_walk *priv = walk->private;
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	struct pglist_data *pgdat = lruvec_pgdat(priv->lruvec);
+#endif
+
+	VM_BUG_ON(pud_leaf(*pud));
+
+	/*
+	 * Finish an entire PMD in two passes: the first only reaches to PTE
+	 * tables to avoid taking the PMD lock; the second, if necessary, takes
+	 * the PMD lock to clear the accessed bit in PMD entries.
+	 */
+	pmd = pmd_offset(pud, start & PUD_MASK);
+restart:
+	/* walk_pte_range() may call get_next_vma() */
+	vma = walk->vma;
+	for (i = pmd_index(start), addr = start; addr != end; i++, addr = next) {
+		pmd_t val = pmd_read_atomic(pmd + i);
+
+		/* for pmd_read_atomic() */
+		barrier();
+
+		next = pmd_addr_end(addr, end);
+
+		if (!pmd_present(val)) {
+			priv->mm_stats[MM_PTE_TOTAL]++;
+			continue;
+		}
+
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+		if (pmd_trans_huge(val)) {
+			unsigned long pfn = pmd_pfn(val);
+
+			priv->mm_stats[MM_PTE_TOTAL]++;
+
+			if (is_huge_zero_pmd(val))
+				continue;
+
+			if (!pmd_young(val)) {
+				priv->mm_stats[MM_PTE_OLD]++;
+				continue;
+			}
+
+			if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
+				continue;
+
+			walk_pmd_range_locked(pud, addr, vma, walk, &pos);
+			continue;
+		}
+#endif
+		priv->mm_stats[MM_PMD_TOTAL]++;
+
+#ifdef CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
+		if (!pmd_young(val))
+			continue;
+
+		walk_pmd_range_locked(pud, addr, vma, walk, &pos);
+#endif
+		if (!priv->full_scan && !test_bloom_filter(priv->lruvec, priv->max_seq, pmd + i))
+			continue;
+
+		priv->mm_stats[MM_PMD_FOUND]++;
+
+		if (!walk_pte_range(&val, addr, next, walk))
+			continue;
+
+		set_bloom_filter(priv->lruvec, priv->max_seq + 1, pmd + i);
+
+		priv->mm_stats[MM_PMD_ADDED]++;
+	}
+
+	walk_pmd_range_locked(pud, -1, vma, walk, &pos);
+
+	if (i < PTRS_PER_PMD && get_next_vma(walk, PUD_MASK, PMD_SIZE, &start, &end))
+		goto restart;
+}
+
+static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
+			  struct mm_walk *walk)
+{
+	int i;
+	pud_t *pud;
+	unsigned long addr;
+	unsigned long next;
+	struct lru_gen_mm_walk *priv = walk->private;
+
+	VM_BUG_ON(p4d_leaf(*p4d));
+
+	pud = pud_offset(p4d, start & P4D_MASK);
+restart:
+	for (i = pud_index(start), addr = start; addr != end; i++, addr = next) {
+		pud_t val = READ_ONCE(pud[i]);
+
+		next = pud_addr_end(addr, end);
+
+		if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val)))
+			continue;
+
+		walk_pmd_range(&val, addr, next, walk);
+
+		if (priv->batched >= MAX_LRU_BATCH) {
+			end = (addr | ~PUD_MASK) + 1;
+			goto done;
+		}
+	}
+
+	if (i < PTRS_PER_PUD && get_next_vma(walk, P4D_MASK, PUD_SIZE, &start, &end))
+		goto restart;
+
+	end = round_up(end, P4D_SIZE);
+done:
+	/* rounded-up boundaries can wrap to 0 */
+	priv->next_addr = end && walk->vma ? max(end, walk->vma->vm_start) : 0;
+
+	return -EAGAIN;
+}
+
+static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
+{
+	static const struct mm_walk_ops mm_walk_ops = {
+		.test_walk = should_skip_vma,
+		.p4d_entry = walk_pud_range,
+	};
+
+	int err;
+#ifdef CONFIG_MEMCG
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+#endif
+
+	walk->next_addr = FIRST_USER_ADDRESS;
+
+	do {
+		unsigned long start = walk->next_addr;
+		unsigned long end = mm->highest_vm_end;
+
+		err = -EBUSY;
+
+		rcu_read_lock();
+#ifdef CONFIG_MEMCG
+		if (memcg && atomic_read(&memcg->moving_account))
+			goto contended;
+#endif
+		if (!mmap_read_trylock(mm))
+			goto contended;
+
+		err = walk_page_range(mm, start, end, &mm_walk_ops, walk);
+
+		mmap_read_unlock(mm);
+
+		if (walk->batched) {
+			spin_lock_irq(&lruvec->lru_lock);
+			reset_batch_size(lruvec, walk);
+			spin_unlock_irq(&lruvec->lru_lock);
+		}
+contended:
+		rcu_read_unlock();
+
+		cond_resched();
+	} while (err == -EAGAIN && walk->next_addr && !mm_is_oom_victim(mm));
+}
+
+static struct lru_gen_mm_walk *alloc_mm_walk(void)
+{
+	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
+		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
+
+	return current->reclaim_state->mm_walk;
+}
+
+static void free_mm_walk(struct lru_gen_mm_walk *walk)
+{
+	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
+		kvfree(walk);
+}
+
+static void inc_min_seq(struct lruvec *lruvec)
+{
+	int gen, type;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	VM_BUG_ON(!seq_is_valid(lruvec));
+
+	for (type = 0; type < ANON_AND_FILE; type++) {
+		if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
+			continue;
+
+		WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
+	}
+}
+
+static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
+{
+	int gen, type, zone;
+	bool success = false;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	DEFINE_MIN_SEQ(lruvec);
+
+	VM_BUG_ON(!seq_is_valid(lruvec));
+
+	for (type = !can_swap; type < ANON_AND_FILE; type++) {
+		while (lrugen->max_seq >= min_seq[type] + MIN_NR_GENS) {
+			gen = lru_gen_from_seq(min_seq[type]);
+
+			for (zone = 0; zone < MAX_NR_ZONES; zone++) {
+				if (!list_empty(&lrugen->lists[gen][type][zone]))
+					goto next;
+			}
+
+			min_seq[type]++;
+		}
+next:
+		;
+	}
+
+	/* see the comment in seq_is_valid() */
+	if (can_swap) {
+		min_seq[0] = min(min_seq[0], min_seq[1]);
+		min_seq[1] = max(min_seq[0], lrugen->min_seq[1]);
+	}
+
+	for (type = !can_swap; type < ANON_AND_FILE; type++) {
+		if (min_seq[type] == lrugen->min_seq[type])
+			continue;
+
+		WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
+		success = true;
+	}
+
+	return success;
+}
+
+static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq)
+{
+	int prev, next;
+	int type, zone;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	spin_lock_irq(&lruvec->lru_lock);
+
+	VM_BUG_ON(!seq_is_valid(lruvec));
+
+	if (max_seq != lrugen->max_seq)
+		goto unlock;
+
+	inc_min_seq(lruvec);
+
+	/* update the active/inactive lru sizes for compatibility */
+	prev = lru_gen_from_seq(lrugen->max_seq - 1);
+	next = lru_gen_from_seq(lrugen->max_seq + 1);
+
+	for (type = 0; type < ANON_AND_FILE; type++) {
+		for (zone = 0; zone < MAX_NR_ZONES; zone++) {
+			enum lru_list lru = type * LRU_FILE;
+			long delta = lrugen->nr_pages[prev][type][zone] -
+				     lrugen->nr_pages[next][type][zone];
+
+			if (!delta)
+				continue;
+
+			lru_gen_update_size(lruvec, lru, zone, delta);
+			lru_gen_update_size(lruvec, lru + LRU_ACTIVE, zone, -delta);
+		}
+	}
+
+	WRITE_ONCE(lrugen->timestamps[next], jiffies);
+	/* make sure preceding modifications appear */
+	smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
+unlock:
+	spin_unlock_irq(&lruvec->lru_lock);
+}
+
+static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
+			       struct scan_control *sc, bool can_swap, bool full_scan)
+{
+	bool last;
+	struct lru_gen_mm_walk *walk;
+	struct mm_struct *mm = NULL;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	VM_BUG_ON(max_seq > READ_ONCE(lrugen->max_seq));
+
+	/*
+	 * If the hardware doesn't automatically set the accessed bit, fallback
+	 * to lru_gen_look_around(), which only clears the accessed bit in a
+	 * handful of PTEs. Spreading the work out over a period of time usually
+	 * is less efficient, but it avoids bursty page faults.
+	 */
+	if (!full_scan && !arch_has_hw_pte_young(false)) {
+		inc_max_seq(lruvec, max_seq);
+		return true;
+	}
+
+	walk = alloc_mm_walk();
+	if (!walk)
+		return false;
+
+	walk->lruvec = lruvec;
+	walk->max_seq = max_seq;
+	walk->can_swap = can_swap;
+	walk->full_scan = full_scan;
+
+	do {
+		last = get_next_mm(lruvec, walk, &mm);
+		if (mm)
+			walk_mm(lruvec, mm, walk);
+
+		cond_resched();
+	} while (mm);
+
+	free_mm_walk(walk);
+
+	if (!last) {
+		if (!current_is_kswapd() && sc->priority < DEF_PRIORITY - 2)
+			wait_event_killable(lruvec->mm_state.wait,
+					    max_seq < READ_ONCE(lrugen->max_seq));
+
+		return max_seq < READ_ONCE(lrugen->max_seq);
+	}
+
+	VM_BUG_ON(max_seq != READ_ONCE(lrugen->max_seq));
+
+	inc_max_seq(lruvec, max_seq);
+	/* either this sees any waiters or they will see updated max_seq */
+	if (wq_has_sleeper(&lruvec->mm_state.wait))
+		wake_up_all(&lruvec->mm_state.wait);
+
+	wakeup_flusher_threads(WB_REASON_VMSCAN);
+
+	return true;
+}
+
+static long get_nr_evictable(struct lruvec *lruvec, unsigned long max_seq, unsigned long *min_seq,
+			     struct scan_control *sc, bool can_swap, bool *need_aging)
+{
+	int gen, type, zone;
+	long max = 0;
+	long min = 0;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	/*
+	 * The upper bound of evictable pages is all eligible pages; the lower
+	 * bound is aged eligible file pages. The aging is due if the number of
+	 * aged generations and the number of aged eligible file pages are both
+	 * low.
+	 */
+	for (type = !can_swap; type < ANON_AND_FILE; type++) {
+		unsigned long seq;
+
+		for (seq = min_seq[type]; seq <= max_seq; seq++) {
+			long size = 0;
+
+			gen = lru_gen_from_seq(seq);
+
+			for (zone = 0; zone <= sc->reclaim_idx; zone++)
+				size += READ_ONCE(lrugen->nr_pages[gen][type][zone]);
+
+			max += size;
+			if (type && max_seq >= seq + MIN_NR_GENS)
+				min += size;
+		}
+	}
+
+	*need_aging = max_seq <= min_seq[1] + MIN_NR_GENS && min < MIN_LRU_BATCH;
+
+	return max > 0 ? max : 0;
+}
+
+static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc,
+		       unsigned long min_ttl)
+{
+	bool need_aging;
+	long nr_to_scan;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	int swappiness = get_swappiness(memcg);
+	DEFINE_MAX_SEQ(lruvec);
+	DEFINE_MIN_SEQ(lruvec);
+
+	if (mem_cgroup_below_min(memcg))
+		return false;
+
+	if (min_ttl) {
+		int gen = lru_gen_from_seq(min_seq[1]);
+		unsigned long birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
+
+		if (time_is_after_jiffies(birth + min_ttl))
+			return false;
+	}
+
+	nr_to_scan = get_nr_evictable(lruvec, max_seq, min_seq, sc, swappiness, &need_aging);
+	if (!nr_to_scan)
+		return false;
+
+	nr_to_scan >>= sc->priority;
+
+	if (!mem_cgroup_online(memcg))
+		nr_to_scan++;
+
+	if (nr_to_scan && need_aging && (!mem_cgroup_below_low(memcg) || sc->memcg_low_reclaim))
+		try_to_inc_max_seq(lruvec, max_seq, sc, swappiness, false);
+
+	return true;
+}
+
+/* to protect the working set of the last N jiffies */
+static unsigned long lru_gen_min_ttl __read_mostly;
+
+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
+{
+	struct mem_cgroup *memcg;
+	bool success = false;
+	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
+
+	VM_BUG_ON(!current_is_kswapd());
+
+	current->reclaim_state->mm_walk = &pgdat->mm_walk;
+
+	memcg = mem_cgroup_iter(NULL, NULL, NULL);
+	do {
+		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
+
+		if (age_lruvec(lruvec, sc, min_ttl))
+			success = true;
+
+		cond_resched();
+	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
+
+	if (!success && mutex_trylock(&oom_lock)) {
+		struct oom_control oc = {
+			.gfp_mask = sc->gfp_mask,
+			.order = sc->order,
+		};
+
+		if (!oom_reaping_in_progress())
+			out_of_memory(&oc);
+
+		mutex_unlock(&oom_lock);
+	}
+
+	current->reclaim_state->mm_walk = NULL;
+}
+
+/*
+ * This function exploits spatial locality when shrink_page_list() walks the
+ * rmap. It scans the vicinity of a young PTE in a PTE table and promotes
+ * accessed pages. If the scan was done cacheline efficiently, it adds the PMD
+ * entry pointing to this PTE table to the Bloom filter. This process is a
+ * feedback loop from the eviction to the aging.
+ */
+void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
+{
+	int i;
+	pte_t *pte;
+	unsigned long start;
+	unsigned long end;
+	unsigned long addr;
+	struct lru_gen_mm_walk *walk;
+	int total = 0;
+	int young = 0;
+	struct mem_cgroup *memcg = page_memcg(pvmw->page);
+	struct pglist_data *pgdat = page_pgdat(pvmw->page);
+	struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
+	DEFINE_MAX_SEQ(lruvec);
+
+	lockdep_assert_held(pvmw->ptl);
+	VM_BUG_ON_PAGE(PageLRU(pvmw->page), pvmw->page);
+
+	walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
+	if (!walk)
+		return;
+
+	walk->max_seq = max_seq;
+
+	start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start);
+	end = pmd_addr_end(pvmw->address, pvmw->vma->vm_end);
+
+	if (end - start > MIN_LRU_BATCH * PAGE_SIZE) {
+		if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
+			end = start + MIN_LRU_BATCH * PAGE_SIZE;
+		else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2)
+			start = end - MIN_LRU_BATCH * PAGE_SIZE;
+		else {
+			start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2;
+			end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2;
+		}
+	}
+
+	pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE;
+
+	lock_page_memcg(pvmw->page);
+	arch_enter_lazy_mmu_mode();
+
+	for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
+		struct folio *folio;
+		unsigned long pfn = pte_pfn(pte[i]);
+
+		total++;
+
+		if (!pte_present(pte[i]) || is_zero_pfn(pfn))
+			continue;
+
+		if (WARN_ON_ONCE(pte_devmap(pte[i]) || pte_special(pte[i])))
+			continue;
+
+		if (!pte_young(pte[i]))
+			continue;
+
+		VM_BUG_ON(!pfn_valid(pfn));
+		if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
+			continue;
+
+		folio = pfn_folio(pfn);
+		if (folio_nid(folio) != pgdat->node_id)
+			continue;
+
+		if (folio_memcg_rcu(folio) != memcg)
+			continue;
+
+		VM_BUG_ON(addr < pvmw->vma->vm_start || addr >= pvmw->vma->vm_end);
+		if (ptep_test_and_clear_young(pvmw->vma, addr, pte + i)) {
+			folio_update_gen(folio, walk);
+			young++;
+		}
+
+		if (pte_dirty(pte[i]) && !folio_test_dirty(folio) &&
+		    !(folio_test_anon(folio) && folio_test_swapbacked(folio) &&
+		      !folio_test_swapcache(folio)))
+			__set_bit(i, walk->bitmap);
+	}
+
+	arch_leave_lazy_mmu_mode();
+	unlock_page_memcg(pvmw->page);
+
+	if (suitable_to_scan(total, young))
+		set_bloom_filter(lruvec, max_seq, pvmw->pmd);
+
+	for_each_set_bit(i, walk->bitmap, MIN_LRU_BATCH)
+		set_page_dirty(pte_page(pte[i]));
+
+	bitmap_zero(walk->bitmap, MIN_LRU_BATCH);
+}
+
 /******************************************************************************
  *                          state change
  ******************************************************************************/
@@ -3649,6 +4534,12 @@ static int __init init_lru_gen(void)
 };
 late_initcall(init_lru_gen);
 
+#else
+
+static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
+{
+}
+
 #endif /* CONFIG_LRU_GEN */
 
 static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
@@ -4536,6 +5427,11 @@ static void age_active_anon(struct pglist_data *pgdat,
 	struct mem_cgroup *memcg;
 	struct lruvec *lruvec;
 
+	if (lru_gen_enabled()) {
+		lru_gen_age_node(pgdat, sc);
+		return;
+	}
+
 	if (!can_age_anon_pages(pgdat, sc))
 		return;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:27 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:27 -0700
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-9-yuzhao@google.com>

Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.

Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention.
Compared with the size-based approach, e.g., [1], this time-based
approach has the following advantages:
1) It's easier to configure because it's agnostic to applications and
   memory sizes.
2) It's more reliable because it's directly wired to the OOM killer.

Add /sys/kernel/debug/lru_gen for working set estimation and proactive
reclaim. Compared with the page table-based approach and the PFN-based
approach, e.g., mm/damon/[vp]addr.c, this lruvec-based approach has
the following advantages:
1) It offers better choices because it's aware of memcgs, NUMA nodes,
   shared mappings and unmapped page cache.
2) It's more scalable because it's O(nr_hot_evictable_pages), whereas
   the PFN-based approach is O(nr_total_pages).

Add /sys/kernel/debug/lru_gen_full for debugging.

[1] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 Documentation/vm/index.rst        |   1 +
 Documentation/vm/multigen_lru.rst |  62 +++++
 include/linux/nodemask.h          |   1 +
 mm/vmscan.c                       | 415 ++++++++++++++++++++++++++++++
 4 files changed, 479 insertions(+)
 create mode 100644 Documentation/vm/multigen_lru.rst

diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
index 6f5ffef4b716..f25e755b4ff4 100644
--- a/Documentation/vm/index.rst
+++ b/Documentation/vm/index.rst
@@ -38,3 +38,4 @@ algorithms.  If you are looking for advice on simply allocating memory, see the
    unevictable-lru
    z3fold
    zsmalloc
+   multigen_lru
diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
new file mode 100644
index 000000000000..6f9e0181348b
--- /dev/null
+++ b/Documentation/vm/multigen_lru.rst
@@ -0,0 +1,62 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=====================
+Multigenerational LRU
+=====================
+
+Quick start
+===========
+Runtime configurations
+----------------------
+:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
+ feature wasn't enabled by default.
+
+Recipes
+=======
+Personal computers
+------------------
+:Thrashing prevention: Write ``N`` to
+ ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
+ ``N`` milliseconds from getting evicted. The OOM killer is invoked if
+ this working set can't be kept in memory. Based on the average human
+ detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
+ lags due to thrashing. Larger values like ``N=3000`` make lags less
+ noticeable at the cost of more OOM kills.
+
+Data centers
+------------
+:Debugfs interface: ``/sys/kernel/debug/lru_gen`` has the following
+ format:
+ ::
+
+   memcg  memcg_id  memcg_path
+     node  node_id
+       min_gen  birth_time  anon_size  file_size
+       ...
+       max_gen  birth_time  anon_size  file_size
+
+ ``min_gen`` is the oldest generation number and ``max_gen`` is the
+ youngest generation number. ``birth_time`` is in milliseconds.
+ ``anon_size`` and ``file_size`` are in pages.
+
+ This file also accepts commands in the following subsections.
+ Multiple command lines are supported, so does concatenation with
+ delimiters ``,`` and ``;``.
+
+ ``/sys/kernel/debug/lru_gen_full`` contains additional stats for
+ debugging.
+
+:Working set estimation: Write ``+ memcg_id node_id max_gen
+ [can_swap [full_scan]]`` to ``/sys/kernel/debug/lru_gen`` to trigger
+ the aging. It scans PTEs for accessed pages and promotes them to the
+ youngest generation ``max_gen``. Then it creates a new generation
+ ``max_gen+1``. Set ``can_swap`` to 1 to scan for accessed anon pages
+ when swap is off. Set ``full_scan`` to 0 to reduce the overhead as
+ well as the coverage when scanning PTEs.
+
+:Proactive reclaim: Write ``- memcg_id node_id min_gen [swappiness
+ [nr_to_reclaim]]`` to ``/sys/kernel/debug/lru_gen`` to trigger the
+ eviction. It evicts generations less than or equal to ``min_gen``.
+ ``min_gen`` should be less than ``max_gen-1`` as ``max_gen`` and
+ ``max_gen-1`` aren't fully aged and therefore can't be evicted. Use
+ ``nr_to_reclaim`` to limit the number of pages to evict.
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 567c3ddba2c4..90840c459abc 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -486,6 +486,7 @@ static inline int num_node_state(enum node_states state)
 #define first_online_node	0
 #define first_memory_node	0
 #define next_online_node(nid)	(MAX_NUMNODES)
+#define next_memory_node(nid)	(MAX_NUMNODES)
 #define nr_node_ids		1U
 #define nr_online_nodes		1U
 
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b232f711dbdb..20f45ff849fc 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -53,6 +53,8 @@
 #include <linux/memory.h>
 #include <linux/pagewalk.h>
 #include <linux/shmem_fs.h>
+#include <linux/ctype.h>
+#include <linux/debugfs.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -5021,6 +5023,413 @@ static void lru_gen_change_state(bool enable)
 	mem_hotplug_done();
 }
 
+/******************************************************************************
+ *                          sysfs interface
+ ******************************************************************************/
+
+static ssize_t show_min_ttl(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%u\n", jiffies_to_msecs(READ_ONCE(lru_gen_min_ttl)));
+}
+
+static ssize_t store_min_ttl(struct kobject *kobj, struct kobj_attribute *attr,
+			     const char *buf, size_t len)
+{
+	unsigned int msecs;
+
+	if (kstrtouint(buf, 10, &msecs))
+		return -EINVAL;
+
+	WRITE_ONCE(lru_gen_min_ttl, msecs_to_jiffies(msecs));
+
+	return len;
+}
+
+static struct kobj_attribute lru_gen_min_ttl_attr = __ATTR(
+	min_ttl_ms, 0644, show_min_ttl, store_min_ttl
+);
+
+static ssize_t show_enable(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "%d\n", lru_gen_enabled());
+}
+
+static ssize_t store_enable(struct kobject *kobj, struct kobj_attribute *attr,
+			    const char *buf, size_t len)
+{
+	bool enable;
+
+	if (kstrtobool(buf, &enable))
+		return -EINVAL;
+
+	lru_gen_change_state(enable);
+
+	return len;
+}
+
+static struct kobj_attribute lru_gen_enabled_attr = __ATTR(
+	enabled, 0644, show_enable, store_enable
+);
+
+static struct attribute *lru_gen_attrs[] = {
+	&lru_gen_min_ttl_attr.attr,
+	&lru_gen_enabled_attr.attr,
+	NULL
+};
+
+static struct attribute_group lru_gen_attr_group = {
+	.name = "lru_gen",
+	.attrs = lru_gen_attrs,
+};
+
+/******************************************************************************
+ *                          debugfs interface
+ ******************************************************************************/
+
+static void *lru_gen_seq_start(struct seq_file *m, loff_t *pos)
+{
+	struct mem_cgroup *memcg;
+	loff_t nr_to_skip = *pos;
+
+	m->private = kvmalloc(PATH_MAX, GFP_KERNEL);
+	if (!m->private)
+		return ERR_PTR(-ENOMEM);
+
+	memcg = mem_cgroup_iter(NULL, NULL, NULL);
+	do {
+		int nid;
+
+		for_each_node_state(nid, N_MEMORY) {
+			if (!nr_to_skip--)
+				return get_lruvec(memcg, nid);
+		}
+	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
+
+	return NULL;
+}
+
+static void lru_gen_seq_stop(struct seq_file *m, void *v)
+{
+	if (!IS_ERR_OR_NULL(v))
+		mem_cgroup_iter_break(NULL, lruvec_memcg(v));
+
+	kvfree(m->private);
+	m->private = NULL;
+}
+
+static void *lru_gen_seq_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	int nid = lruvec_pgdat(v)->node_id;
+	struct mem_cgroup *memcg = lruvec_memcg(v);
+
+	++*pos;
+
+	nid = next_memory_node(nid);
+	if (nid == MAX_NUMNODES) {
+		memcg = mem_cgroup_iter(NULL, memcg, NULL);
+		if (!memcg)
+			return NULL;
+
+		nid = first_memory_node;
+	}
+
+	return get_lruvec(memcg, nid);
+}
+
+static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
+				  unsigned long max_seq, unsigned long *min_seq,
+				  unsigned long seq)
+{
+	int i;
+	int type, tier;
+	int hist = lru_hist_from_seq(seq);
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	for (tier = 0; tier < MAX_NR_TIERS; tier++) {
+		seq_printf(m, "            %10d", tier);
+		for (type = 0; type < ANON_AND_FILE; type++) {
+			unsigned long n[3] = {};
+
+			if (seq == max_seq) {
+				n[0] = READ_ONCE(lrugen->avg_refaulted[type][tier]);
+				n[1] = READ_ONCE(lrugen->avg_total[type][tier]);
+
+				seq_printf(m, " %10luR %10luT %10lu ", n[0], n[1], n[2]);
+			} else if (seq == min_seq[type] || NR_HIST_GENS > 1) {
+				n[0] = atomic_long_read(&lrugen->refaulted[hist][type][tier]);
+				n[1] = atomic_long_read(&lrugen->evicted[hist][type][tier]);
+				if (tier)
+					n[2] = READ_ONCE(lrugen->promoted[hist][type][tier - 1]);
+
+				seq_printf(m, " %10lur %10lue %10lup", n[0], n[1], n[2]);
+			} else
+				seq_puts(m, "          0           0           0 ");
+		}
+		seq_putc(m, '\n');
+	}
+
+	seq_puts(m, "                      ");
+	for (i = 0; i < NR_MM_STATS; i++) {
+		if (seq == max_seq && NR_HIST_GENS == 1)
+			seq_printf(m, " %10lu%c", READ_ONCE(lruvec->mm_state.stats[hist][i]),
+				   toupper(MM_STAT_CODES[i]));
+		else if (seq != max_seq && NR_HIST_GENS > 1)
+			seq_printf(m, " %10lu%c", READ_ONCE(lruvec->mm_state.stats[hist][i]),
+				   MM_STAT_CODES[i]);
+		else
+			seq_puts(m, "          0 ");
+	}
+	seq_putc(m, '\n');
+}
+
+static int lru_gen_seq_show(struct seq_file *m, void *v)
+{
+	unsigned long seq;
+	bool full = !debugfs_real_fops(m->file)->write;
+	struct lruvec *lruvec = v;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	int nid = lruvec_pgdat(lruvec)->node_id;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	DEFINE_MAX_SEQ(lruvec);
+	DEFINE_MIN_SEQ(lruvec);
+
+	if (nid == first_memory_node) {
+		const char *path = memcg ? m->private : "";
+
+#ifdef CONFIG_MEMCG
+		if (memcg)
+			cgroup_path(memcg->css.cgroup, m->private, PATH_MAX);
+#endif
+		seq_printf(m, "memcg %5hu %s\n", mem_cgroup_id(memcg), path);
+	}
+
+	seq_printf(m, " node %5d\n", nid);
+
+	if (!full)
+		seq = min_seq[0];
+	else if (max_seq >= MAX_NR_GENS)
+		seq = max_seq - MAX_NR_GENS + 1;
+	else
+		seq = 0;
+
+	for (; seq <= max_seq; seq++) {
+		int gen, type, zone;
+		unsigned int msecs;
+
+		gen = lru_gen_from_seq(seq);
+		msecs = jiffies_to_msecs(jiffies - READ_ONCE(lrugen->timestamps[gen]));
+
+		seq_printf(m, " %10lu %10u", seq, msecs);
+
+		for (type = 0; type < ANON_AND_FILE; type++) {
+			long size = 0;
+
+			if (seq < min_seq[type]) {
+				seq_puts(m, "         -0 ");
+				continue;
+			}
+
+			for (zone = 0; zone < MAX_NR_ZONES; zone++)
+				size += READ_ONCE(lrugen->nr_pages[gen][type][zone]);
+
+			seq_printf(m, " %10lu ", max(size, 0L));
+		}
+
+		seq_putc(m, '\n');
+
+		if (full)
+			lru_gen_seq_show_full(m, lruvec, max_seq, min_seq, seq);
+	}
+
+	return 0;
+}
+
+static const struct seq_operations lru_gen_seq_ops = {
+	.start = lru_gen_seq_start,
+	.stop = lru_gen_seq_stop,
+	.next = lru_gen_seq_next,
+	.show = lru_gen_seq_show,
+};
+
+static int run_aging(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc,
+		     bool can_swap, bool full_scan)
+{
+	DEFINE_MAX_SEQ(lruvec);
+
+	if (seq == max_seq)
+		try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, full_scan);
+
+	return seq > max_seq ? -EINVAL : 0;
+}
+
+static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_control *sc,
+			int swappiness, unsigned long nr_to_reclaim)
+{
+	struct blk_plug plug;
+	int err = -EINTR;
+	DEFINE_MAX_SEQ(lruvec);
+
+	if (max_seq < seq + MIN_NR_GENS)
+		return -EINVAL;
+
+	sc->nr_reclaimed = 0;
+
+	blk_start_plug(&plug);
+
+	while (!signal_pending(current)) {
+		DEFINE_MIN_SEQ(lruvec);
+
+		if (seq < min_seq[!swappiness] || sc->nr_reclaimed >= nr_to_reclaim ||
+		    !evict_folios(lruvec, sc, swappiness, NULL)) {
+			err = 0;
+			break;
+		}
+
+		cond_resched();
+	}
+
+	blk_finish_plug(&plug);
+
+	return err;
+}
+
+static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
+		   struct scan_control *sc, int swappiness, unsigned long opt)
+{
+	struct lruvec *lruvec;
+	int err = -EINVAL;
+	struct mem_cgroup *memcg = NULL;
+
+	if (!mem_cgroup_disabled()) {
+		rcu_read_lock();
+		memcg = mem_cgroup_from_id(memcg_id);
+#ifdef CONFIG_MEMCG
+		if (memcg && !css_tryget(&memcg->css))
+			memcg = NULL;
+#endif
+		rcu_read_unlock();
+
+		if (!memcg)
+			goto done;
+	}
+	if (memcg_id != mem_cgroup_id(memcg))
+		goto done;
+
+	if (nid < 0 || nid >= MAX_NUMNODES || !node_state(nid, N_MEMORY))
+		goto done;
+
+	lruvec = get_lruvec(memcg, nid);
+
+	if (swappiness < 0)
+		swappiness = get_swappiness(memcg);
+	else if (swappiness > 200)
+		goto done;
+
+	switch (cmd) {
+	case '+':
+		err = run_aging(lruvec, seq, sc, swappiness, opt);
+		break;
+	case '-':
+		err = run_eviction(lruvec, seq, sc, swappiness, opt);
+		break;
+	}
+done:
+	mem_cgroup_put(memcg);
+
+	return err;
+}
+
+static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
+				 size_t len, loff_t *pos)
+{
+	void *buf;
+	char *cur, *next;
+	unsigned int flags;
+	int err = 0;
+	struct scan_control sc = {
+		.may_writepage = 1,
+		.may_unmap = 1,
+		.may_swap = 1,
+		.reclaim_idx = MAX_NR_ZONES - 1,
+		.gfp_mask = GFP_KERNEL,
+	};
+
+	buf = kvmalloc(len + 1, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (copy_from_user(buf, src, len)) {
+		kvfree(buf);
+		return -EFAULT;
+	}
+
+	next = buf;
+	next[len] = '\0';
+
+	sc.reclaim_state.mm_walk = alloc_mm_walk();
+	if (!sc.reclaim_state.mm_walk) {
+		kvfree(buf);
+		return -ENOMEM;
+	}
+
+	flags = memalloc_noreclaim_save();
+	set_task_reclaim_state(current, &sc.reclaim_state);
+
+	while ((cur = strsep(&next, ",;\n"))) {
+		int n;
+		int end;
+		char cmd;
+		unsigned int memcg_id;
+		unsigned int nid;
+		unsigned long seq;
+		unsigned int swappiness = -1;
+		unsigned long opt = -1;
+
+		cur = skip_spaces(cur);
+		if (!*cur)
+			continue;
+
+		n = sscanf(cur, "%c %u %u %lu %n %u %n %lu %n", &cmd, &memcg_id, &nid,
+			   &seq, &end, &swappiness, &end, &opt, &end);
+		if (n < 4 || cur[end]) {
+			err = -EINVAL;
+			break;
+		}
+
+		err = run_cmd(cmd, memcg_id, nid, seq, &sc, swappiness, opt);
+		if (err)
+			break;
+	}
+
+	set_task_reclaim_state(current, NULL);
+	memalloc_noreclaim_restore(flags);
+
+	free_mm_walk(sc.reclaim_state.mm_walk);
+	kvfree(buf);
+
+	return err ? : len;
+}
+
+static int lru_gen_seq_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &lru_gen_seq_ops);
+}
+
+static const struct file_operations lru_gen_rw_fops = {
+	.open = lru_gen_seq_open,
+	.read = seq_read,
+	.write = lru_gen_seq_write,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
+static const struct file_operations lru_gen_ro_fops = {
+	.open = lru_gen_seq_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = seq_release,
+};
+
 /******************************************************************************
  *                          initialization
  ******************************************************************************/
@@ -5087,6 +5496,12 @@ static int __init init_lru_gen(void)
 	BUILD_BUG_ON(BIT(LRU_GEN_WIDTH) <= MAX_NR_GENS);
 	BUILD_BUG_ON(sizeof(MM_STAT_CODES) != NR_MM_STATS + 1);
 
+	if (sysfs_create_group(mm_kobj, &lru_gen_attr_group))
+		pr_err("lru_gen: failed to create sysfs group\n");
+
+	debugfs_create_file("lru_gen", 0644, NULL, NULL, &lru_gen_rw_fops);
+	debugfs_create_file("lru_gen_full", 0444, NULL, NULL, &lru_gen_ro_fops);
+
 	return 0;
 };
 late_initcall(init_lru_gen);
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:26 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:26 -0700
Subject: [PATCH v6 7/9] mm: multigenerational lru: eviction
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-8-yuzhao@google.com>

The eviction consumes old generations. Given an lruvec, it scans pages
on lrugen->lists[] indexed by min_seq%MAX_NR_GENS. A feedback loop
modeled after the PID controller monitors refaults over anon and file
types and decides which type to evict when both are available from the
same generation.

Each generation is divided into multiple tiers. Tiers represent
different ranges of numbers of accesses thru file descriptors. A page
accessed N times thru file descriptors is in tier order_base_2(N). The
feedback loop also monitors refaults over all tiers and decides when
to promote pages in which tiers (N>1), using the first tier (N=0,1) as
a baseline.

The eviction sorts a page according to the gen counter if the aging
has found this page accessed thru page tables, which completes the
promotion of this page. The eviction also promotes a page to the next
generation (min_seq+1 rather than max_seq) if this page was accessed
multiple times thru file descriptors and the feedback loop has
detected higher refaults from the tier this page is in. This approach
has the following advantages:
1) It removes the cost of activation (recall the terms) in the
   buffered access path by inferring whether pages accessed multiple
   times thru file descriptors are statistically hot and thus worth
   promoting in the eviction path.
2) It takes pages accessed thru page tables into account and avoids
   overprotecting pages accessed multiple times thru file descriptors.
3) More tiers, which require additional bits in folio->flags, provide
   better protection for pages accessed more than twice thru file
   descriptors, when under heavy buffered I/O workloads.

The eviction increments min_seq when lrugen->lists[] indexed by
min_seq%MAX_NR_GENS is empty.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 include/linux/mm_inline.h |  10 +
 include/linux/mmzone.h    |  28 ++
 mm/swap.c                 |  42 +++
 mm/vmscan.c               | 571 +++++++++++++++++++++++++++++++++++++-
 mm/workingset.c           | 119 +++++++-
 5 files changed, 767 insertions(+), 3 deletions(-)

diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 717a2290acb3..1907098ba908 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -115,6 +115,14 @@ static inline int lru_hist_from_seq(unsigned long seq)
 	return seq % NR_HIST_GENS;
 }
 
+static inline int lru_tier_from_refs(int refs)
+{
+	VM_BUG_ON(refs > BIT(LRU_REFS_WIDTH));
+
+	/* see the comment on MAX_NR_TIERS */
+	return order_base_2(refs + 1);
+}
+
 static inline bool lru_gen_is_active(struct lruvec *lruvec, int gen)
 {
 	unsigned long max_seq = lruvec->lrugen.max_seq;
@@ -243,6 +251,8 @@ static inline bool lru_gen_del_folio(struct lruvec *lruvec, struct folio *folio,
 		gen = ((new_flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
 
 		new_flags &= ~LRU_GEN_MASK;
+		if ((new_flags & LRU_REFS_FLAGS) != LRU_REFS_FLAGS)
+			new_flags &= ~(LRU_REFS_MASK | LRU_REFS_FLAGS);
 		/* for shrink_page_list() */
 		if (reclaiming)
 			new_flags &= ~(BIT(PG_referenced) | BIT(PG_reclaim));
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 94af12507788..8f1262bb815a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -336,6 +336,25 @@ struct page_vma_mapped_walk;
 #define MIN_NR_GENS		2U
 #define MAX_NR_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
 
+/*
+ * Each generation is divided into multiple tiers. Tiers represent different
+ * ranges of numbers of accesses thru file descriptors. A page accessed N times
+ * thru file descriptors is in tier order_base_2(N). A page in the first tier
+ * (N=0,1) is marked by PG_referenced unless it was faulted in thru page tables
+ * or read ahead. A page in any other tier (N>1) is marked by PG_referenced and
+ * PG_workingset. Additional bits in folio->flags are required to support more
+ * than two tiers.
+ *
+ * In contrast to moving across generations (promotion), moving across tiers
+ * only requires operations on folio->flags and therefore has a negligible cost
+ * in the buffered access path. In the eviction path, comparisons of
+ * refaulted/(evicted+promoted) from the first tier and the rest infer whether
+ * pages accessed multiple times thru file descriptors are statistically hot
+ * and thus worth promoting.
+ */
+#define MAX_NR_TIERS		((unsigned int)CONFIG_TIERS_PER_GEN)
+#define LRU_REFS_FLAGS		(BIT(PG_referenced) | BIT(PG_workingset))
+
 /* whether to keep historical stats for evicted generations */
 #ifdef CONFIG_LRU_GEN_STATS
 #define NR_HIST_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
@@ -354,6 +373,15 @@ struct lru_gen_struct {
 	struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
 	/* the sizes of the above lists */
 	unsigned long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
+	/* the exponential moving average of refaulted */
+	unsigned long avg_refaulted[ANON_AND_FILE][MAX_NR_TIERS];
+	/* the exponential moving average of evicted+promoted */
+	unsigned long avg_total[ANON_AND_FILE][MAX_NR_TIERS];
+	/* the first tier doesn't need promotion, hence the minus one */
+	unsigned long promoted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS - 1];
+	/* can be modified without holding the lru lock */
+	atomic_long_t evicted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
+	atomic_long_t refaulted[NR_HIST_GENS][ANON_AND_FILE][MAX_NR_TIERS];
 	/* whether the multigenerational lru is enabled */
 	bool enabled;
 };
diff --git a/mm/swap.c b/mm/swap.c
index d7dde3b7d4b5..ae8d56848602 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -407,6 +407,43 @@ static void __lru_cache_activate_folio(struct folio *folio)
 	local_unlock(&lru_pvecs.lock);
 }
 
+#ifdef CONFIG_LRU_GEN
+static void folio_inc_refs(struct folio *folio)
+{
+	unsigned long refs;
+	unsigned long old_flags, new_flags;
+
+	if (folio_test_unevictable(folio))
+		return;
+
+	/* see the comment on MAX_NR_TIERS */
+	do {
+		new_flags = old_flags = READ_ONCE(folio->flags);
+
+		if (!(new_flags & BIT(PG_referenced))) {
+			new_flags |= BIT(PG_referenced);
+			continue;
+		}
+
+		if (!(new_flags & BIT(PG_workingset))) {
+			new_flags |= BIT(PG_workingset);
+			continue;
+		}
+
+		refs = new_flags & LRU_REFS_MASK;
+		refs = min(refs + BIT(LRU_REFS_PGOFF), LRU_REFS_MASK);
+
+		new_flags &= ~LRU_REFS_MASK;
+		new_flags |= refs;
+	} while (new_flags != old_flags &&
+		 cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
+}
+#else
+static void folio_inc_refs(struct folio *folio)
+{
+}
+#endif /* CONFIG_LRU_GEN */
+
 /*
  * Mark a page as having seen activity.
  *
@@ -419,6 +456,11 @@ static void __lru_cache_activate_folio(struct folio *folio)
  */
 void folio_mark_accessed(struct folio *folio)
 {
+	if (lru_gen_enabled()) {
+		folio_inc_refs(folio);
+		return;
+	}
+
 	if (!folio_test_referenced(folio)) {
 		folio_set_referenced(folio);
 	} else if (folio_test_unevictable(folio)) {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fbf1337a1632..b232f711dbdb 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -128,6 +128,13 @@ struct scan_control {
 	/* Always discard instead of demoting to lower tier memory */
 	unsigned int no_demotion:1;
 
+#ifdef CONFIG_LRU_GEN
+	/* help make better choices when multiple memcgs are eligible */
+	unsigned int memcgs_need_aging:1;
+	unsigned int memcgs_need_swapping:1;
+	unsigned int memcgs_avoid_swapping:1;
+#endif
+
 	/* Allocation order */
 	s8 order;
 
@@ -1288,9 +1295,11 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
 
 	if (PageSwapCache(page)) {
 		swp_entry_t swap = { .val = page_private(page) };
-		mem_cgroup_swapout(page, swap);
+
+		/* get a shadow entry before mem_cgroup_swapout() clears memcg_data */
 		if (reclaimed && !mapping_exiting(mapping))
 			shadow = workingset_eviction(page, target_memcg);
+		mem_cgroup_swapout(page, swap);
 		__delete_from_swap_cache(page, swap, shadow);
 		xa_unlock_irq(&mapping->i_pages);
 		put_swap_page(page, swap);
@@ -2729,6 +2738,9 @@ static void prepare_scan_count(pg_data_t *pgdat, struct scan_control *sc)
 	unsigned long file;
 	struct lruvec *target_lruvec;
 
+	if (lru_gen_enabled())
+		return;
+
 	target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
 
 	/*
@@ -3075,6 +3087,17 @@ static int folio_lru_gen(struct folio *folio)
 	return ((flags & LRU_GEN_MASK) >> LRU_GEN_PGOFF) - 1;
 }
 
+static int folio_lru_tier(struct folio *folio)
+{
+	int refs;
+	unsigned long flags = READ_ONCE(folio->flags);
+
+	refs = (flags & LRU_REFS_FLAGS) == LRU_REFS_FLAGS ?
+	       ((flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF) + 1 : 0;
+
+	return lru_tier_from_refs(refs);
+}
+
 static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
 {
 	struct pglist_data *pgdat = NODE_DATA(nid);
@@ -3453,6 +3476,92 @@ static bool get_next_mm(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
 	return last;
 }
 
+/******************************************************************************
+ *                          refault feedback loop
+ ******************************************************************************/
+
+/*
+ * A feedback loop based on Proportional-Integral-Derivative (PID) controller.
+ *
+ * The P term is refaulted/(evicted+promoted) from a tier in the generation
+ * currently being evicted; the I term is the exponential moving average of the
+ * P term over the generations previously evicted, using the smoothing factor
+ * 1/2; the D term isn't used.
+ *
+ * The setpoint (SP) is always the first tier of one type; the process variable
+ * (PV) is either any tier of the other type or any other tier of the same
+ * type.
+ *
+ * The error is the difference between the SP and the PV; the correction is
+ * turn off promotion when SP>PV or turn on promotion when SP<PV.
+ */
+struct ctrl_pos {
+	unsigned long refaulted;
+	unsigned long total;
+	int gain;
+};
+
+static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
+			  struct ctrl_pos *pos)
+{
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	int hist = lru_hist_from_seq(lrugen->min_seq[type]);
+
+	pos->refaulted = lrugen->avg_refaulted[type][tier] +
+			 atomic_long_read(&lrugen->refaulted[hist][type][tier]);
+	pos->total = lrugen->avg_total[type][tier] +
+		     atomic_long_read(&lrugen->evicted[hist][type][tier]);
+	if (tier)
+		pos->total += lrugen->promoted[hist][type][tier - 1];
+	pos->gain = gain;
+}
+
+static void reset_ctrl_pos(struct lruvec *lruvec, int gen, int type)
+{
+	int tier;
+	int hist = lru_hist_from_seq(gen);
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	bool carryover = gen == lru_gen_from_seq(lrugen->min_seq[type]);
+	bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
+
+	if (!carryover && !clear)
+		return;
+
+	for (tier = 0; tier < MAX_NR_TIERS; tier++) {
+		if (carryover) {
+			unsigned long sum;
+
+			sum = lrugen->avg_refaulted[type][tier] +
+			      atomic_long_read(&lrugen->refaulted[hist][type][tier]);
+			WRITE_ONCE(lrugen->avg_refaulted[type][tier], sum / 2);
+
+			sum = lrugen->avg_total[type][tier] +
+			      atomic_long_read(&lrugen->evicted[hist][type][tier]);
+			if (tier)
+				sum += lrugen->promoted[hist][type][tier - 1];
+			WRITE_ONCE(lrugen->avg_total[type][tier], sum / 2);
+		}
+
+		if (clear) {
+			atomic_long_set(&lrugen->refaulted[hist][type][tier], 0);
+			atomic_long_set(&lrugen->evicted[hist][type][tier], 0);
+			if (tier)
+				WRITE_ONCE(lrugen->promoted[hist][type][tier - 1], 0);
+		}
+	}
+}
+
+static bool positive_ctrl_err(struct ctrl_pos *sp, struct ctrl_pos *pv)
+{
+	/*
+	 * Return true if the PV has a limited number of refaults or a lower
+	 * refaulted/total than the SP.
+	 */
+	return pv->refaulted < MIN_LRU_BATCH ||
+	       pv->refaulted * (sp->total + MIN_LRU_BATCH) * sp->gain <=
+	       (sp->refaulted + 1) * pv->total * pv->gain;
+}
+
 /******************************************************************************
  *                          the aging
  ******************************************************************************/
@@ -3476,6 +3585,7 @@ static void folio_update_gen(struct folio *folio, struct lru_gen_mm_walk *walk)
 
 		new_flags &= ~LRU_GEN_MASK;
 		new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
+		new_flags &= ~(LRU_REFS_MASK | LRU_REFS_FLAGS);
 	} while (new_flags != old_flags &&
 		 cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);
 
@@ -3508,6 +3618,7 @@ static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclai
 
 		new_flags &= ~LRU_GEN_MASK;
 		new_flags |= (new_gen + 1UL) << LRU_GEN_PGOFF;
+		new_flags &= ~(LRU_REFS_MASK | LRU_REFS_FLAGS);
 		/* for folio_end_writeback() */
 		if (reclaiming)
 			new_flags |= BIT(PG_reclaim);
@@ -3961,6 +4072,8 @@ static void inc_min_seq(struct lruvec *lruvec)
 		if (get_nr_gens(lruvec, type) != MAX_NR_GENS)
 			continue;
 
+		gen = lru_gen_from_seq(lrugen->min_seq[type]);
+		reset_ctrl_pos(lruvec, gen, type);
 		WRITE_ONCE(lrugen->min_seq[type], lrugen->min_seq[type] + 1);
 	}
 }
@@ -3999,6 +4112,8 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
 		if (min_seq[type] == lrugen->min_seq[type])
 			continue;
 
+		gen = lru_gen_from_seq(lrugen->min_seq[type]);
+		reset_ctrl_pos(lruvec, gen, type);
 		WRITE_ONCE(lrugen->min_seq[type], min_seq[type]);
 		success = true;
 	}
@@ -4039,6 +4154,9 @@ static void inc_max_seq(struct lruvec *lruvec, unsigned long max_seq)
 		}
 	}
 
+	for (type = 0; type < ANON_AND_FILE; type++)
+		reset_ctrl_pos(lruvec, next, type);
+
 	WRITE_ONCE(lrugen->timestamps[next], jiffies);
 	/* make sure preceding modifications appear */
 	smp_store_release(&lrugen->max_seq, lrugen->max_seq + 1);
@@ -4189,6 +4307,22 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
 
 	VM_BUG_ON(!current_is_kswapd());
 
+	/*
+	 * To avoid the aging path and reduce the chance of swapping, which can
+	 * be costly, optimistically skip them unless their corresponding flags
+	 * were cleared in the eviction path. This improves the overall
+	 * performance when multiple memcgs are eligible.
+	 */
+	if (!sc->memcgs_need_aging) {
+		sc->memcgs_need_aging = 1;
+		sc->memcgs_avoid_swapping = !sc->memcgs_need_swapping;
+		sc->memcgs_need_swapping = 1;
+		return;
+	}
+
+	sc->memcgs_need_swapping = 1;
+	sc->memcgs_avoid_swapping = 1;
+
 	current->reclaim_state->mm_walk = &pgdat->mm_walk;
 
 	memcg = mem_cgroup_iter(NULL, NULL, NULL);
@@ -4316,6 +4450,429 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
 	bitmap_zero(walk->bitmap, MIN_LRU_BATCH);
 }
 
+/******************************************************************************
+ *                          the eviction
+ ******************************************************************************/
+
+static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
+{
+	bool success;
+	int gen = folio_lru_gen(folio);
+	int type = folio_is_file_lru(folio);
+	int zone = folio_zonenum(folio);
+	int tier = folio_lru_tier(folio);
+	int delta = folio_nr_pages(folio);
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+
+	VM_BUG_ON_FOLIO(gen >= MAX_NR_GENS, folio);
+
+	if (!folio_evictable(folio)) {
+		success = lru_gen_del_folio(lruvec, folio, true);
+		VM_BUG_ON_FOLIO(!success, folio);
+		folio_set_unevictable(folio);
+		lruvec_add_folio(lruvec, folio);
+		__count_vm_events(UNEVICTABLE_PGCULLED, delta);
+		return true;
+	}
+
+	if (type && folio_test_anon(folio) && folio_test_dirty(folio)) {
+		success = lru_gen_del_folio(lruvec, folio, true);
+		VM_BUG_ON_FOLIO(!success, folio);
+		folio_set_swapbacked(folio);
+		lruvec_add_folio_tail(lruvec, folio);
+		return true;
+	}
+
+	if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
+		list_move(&folio->lru, &lrugen->lists[gen][type][zone]);
+		return true;
+	}
+
+	if (tier > tier_idx) {
+		int hist = lru_hist_from_seq(gen);
+
+		gen = folio_inc_gen(lruvec, folio, false);
+		list_move_tail(&folio->lru, &lrugen->lists[gen][type][zone]);
+
+		WRITE_ONCE(lrugen->promoted[hist][type][tier - 1],
+			   lrugen->promoted[hist][type][tier - 1] + delta);
+		__mod_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + type, delta);
+		return true;
+	}
+
+	if (folio_test_writeback(folio) || (type && folio_test_dirty(folio))) {
+		gen = folio_inc_gen(lruvec, folio, true);
+		list_move(&folio->lru, &lrugen->lists[gen][type][zone]);
+		return true;
+	}
+
+	return false;
+}
+
+static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc)
+{
+	bool success;
+
+	if (!sc->may_unmap && folio_mapped(folio))
+		return false;
+
+	if (!(sc->may_writepage && (sc->gfp_mask & __GFP_IO)) &&
+	    (folio_test_dirty(folio) ||
+	     (folio_test_anon(folio) && !folio_test_swapcache(folio))))
+		return false;
+
+	if (!folio_try_get(folio))
+		return false;
+
+	if (!folio_test_clear_lru(folio)) {
+		folio_put(folio);
+		return false;
+	}
+
+	success = lru_gen_del_folio(lruvec, folio, true);
+	VM_BUG_ON_FOLIO(!success, folio);
+
+	return true;
+}
+
+static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
+		       int type, int tier, struct list_head *list)
+{
+	int gen, zone;
+	enum vm_event_item item;
+	int sorted = 0;
+	int scanned = 0;
+	int isolated = 0;
+	int remaining = MAX_LRU_BATCH;
+	struct lru_gen_struct *lrugen = &lruvec->lrugen;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+
+	VM_BUG_ON(!list_empty(list));
+
+	if (get_nr_gens(lruvec, type) == MIN_NR_GENS)
+		return 0;
+
+	gen = lru_gen_from_seq(lrugen->min_seq[type]);
+
+	for (zone = sc->reclaim_idx; zone >= 0; zone--) {
+		LIST_HEAD(moved);
+		int skipped = 0;
+		struct list_head *head = &lrugen->lists[gen][type][zone];
+
+		while (!list_empty(head)) {
+			struct folio *folio = lru_to_folio(head);
+			int delta = folio_nr_pages(folio);
+
+			VM_BUG_ON_FOLIO(folio_test_unevictable(folio), folio);
+			VM_BUG_ON_FOLIO(folio_test_active(folio), folio);
+			VM_BUG_ON_FOLIO(folio_is_file_lru(folio) != type, folio);
+			VM_BUG_ON_FOLIO(folio_zonenum(folio) != zone, folio);
+
+			scanned += delta;
+
+			if (sort_folio(lruvec, folio, tier))
+				sorted += delta;
+			else if (isolate_folio(lruvec, folio, sc)) {
+				list_add(&folio->lru, list);
+				isolated += delta;
+			} else {
+				list_move(&folio->lru, &moved);
+				skipped += delta;
+			}
+
+			if (!--remaining || max(isolated, skipped) >= MIN_LRU_BATCH)
+				break;
+		}
+
+		if (skipped) {
+			list_splice(&moved, head);
+			__count_zid_vm_events(PGSCAN_SKIP, zone, skipped);
+		}
+
+		if (!remaining || isolated >= MIN_LRU_BATCH)
+			break;
+	}
+
+	item = current_is_kswapd() ? PGSCAN_KSWAPD : PGSCAN_DIRECT;
+	if (!cgroup_reclaim(sc)) {
+		__count_vm_events(item, isolated);
+		__count_vm_events(PGREFILL, sorted);
+	}
+	__count_memcg_events(memcg, item, isolated);
+	__count_memcg_events(memcg, PGREFILL, sorted);
+	__count_vm_events(PGSCAN_ANON + type, isolated);
+
+	/*
+	 * There might not be eligible pages due to reclaim_idx, may_unmap and
+	 * may_writepage. Check the remaining to prevent livelock if there is no
+	 * progress.
+	 */
+	return isolated || !remaining ? scanned : 0;
+}
+
+static int get_tier_idx(struct lruvec *lruvec, int type)
+{
+	int tier;
+	struct ctrl_pos sp, pv;
+
+	/*
+	 * To leave a margin for fluctuations, use a larger gain factor (1:2).
+	 * This value is chosen because any other tier would have at least twice
+	 * as many refaults as the first tier.
+	 */
+	read_ctrl_pos(lruvec, type, 0, 1, &sp);
+	for (tier = 1; tier < MAX_NR_TIERS; tier++) {
+		read_ctrl_pos(lruvec, type, tier, 2, &pv);
+		if (!positive_ctrl_err(&sp, &pv))
+			break;
+	}
+
+	return tier - 1;
+}
+
+static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_idx)
+{
+	int type, tier;
+	struct ctrl_pos sp, pv;
+	int gain[ANON_AND_FILE] = { swappiness, 200 - swappiness };
+
+	/*
+	 * Compare the first tier of anon with that of file to determine which
+	 * type to scan. Also need to compare other tiers of the selected type
+	 * with the first tier of the other type to determine the last tier (of
+	 * the selected type) to evict.
+	 */
+	read_ctrl_pos(lruvec, 0, 0, gain[0], &sp);
+	read_ctrl_pos(lruvec, 1, 0, gain[1], &pv);
+	type = positive_ctrl_err(&sp, &pv);
+
+	read_ctrl_pos(lruvec, !type, 0, gain[!type], &sp);
+	for (tier = 1; tier < MAX_NR_TIERS; tier++) {
+		read_ctrl_pos(lruvec, type, tier, gain[type], &pv);
+		if (!positive_ctrl_err(&sp, &pv))
+			break;
+	}
+
+	*tier_idx = tier - 1;
+
+	return type;
+}
+
+static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
+			  int *type_scanned, struct list_head *list)
+{
+	int i;
+	int type;
+	int scanned;
+	int tier = -1;
+	DEFINE_MIN_SEQ(lruvec);
+
+	VM_BUG_ON(!seq_is_valid(lruvec));
+
+	/*
+	 * Try to make the obvious choice first. When anon and file are both
+	 * available from the same generation, interpret swappiness 1 as file
+	 * first and 200 as anon first.
+	 */
+	if (!swappiness)
+		type = 1;
+	else if (min_seq[0] < min_seq[1])
+		type = 0;
+	else if (swappiness == 1)
+		type = 1;
+	else if (swappiness == 200)
+		type = 0;
+	else
+		type = get_type_to_scan(lruvec, swappiness, &tier);
+
+	for (i = !swappiness; i < ANON_AND_FILE; i++) {
+		if (tier < 0)
+			tier = get_tier_idx(lruvec, type);
+
+		scanned = scan_folios(lruvec, sc, type, tier, list);
+		if (scanned)
+			break;
+
+		type = !type;
+		tier = -1;
+	}
+
+	*type_scanned = type;
+
+	return scanned;
+}
+
+static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
+			bool *swapped)
+{
+	int type;
+	int scanned;
+	int reclaimed;
+	LIST_HEAD(list);
+	struct folio *folio;
+	enum vm_event_item item;
+	struct reclaim_stat stat;
+	struct lru_gen_mm_walk *walk;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+
+	spin_lock_irq(&lruvec->lru_lock);
+
+	scanned = isolate_folios(lruvec, sc, swappiness, &type, &list);
+
+	if (try_to_inc_min_seq(lruvec, swappiness))
+		scanned++;
+
+	if (get_nr_gens(lruvec, 1) == MIN_NR_GENS)
+		scanned = 0;
+
+	spin_unlock_irq(&lruvec->lru_lock);
+
+	if (list_empty(&list))
+		return scanned;
+
+	reclaimed = shrink_page_list(&list, pgdat, sc, &stat, false);
+
+	/*
+	 * To avoid livelock, don't add rejected pages back to the same lists
+	 * they were isolated from.
+	 */
+	list_for_each_entry(folio, &list, lru) {
+		if (!folio_test_reclaim(folio) ||
+		    !(folio_test_dirty(folio) || folio_test_writeback(folio)))
+			folio_set_active(folio);
+
+		folio_clear_referenced(folio);
+		folio_clear_workingset(folio);
+	}
+
+	spin_lock_irq(&lruvec->lru_lock);
+
+	move_pages_to_lru(lruvec, &list);
+
+	walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
+	if (walk && walk->batched)
+		reset_batch_size(lruvec, walk);
+
+	item = current_is_kswapd() ? PGSTEAL_KSWAPD : PGSTEAL_DIRECT;
+	if (!cgroup_reclaim(sc))
+		__count_vm_events(item, reclaimed);
+	__count_memcg_events(memcg, item, reclaimed);
+	__count_vm_events(PGSTEAL_ANON + type, reclaimed);
+
+	spin_unlock_irq(&lruvec->lru_lock);
+
+	mem_cgroup_uncharge_list(&list);
+	free_unref_page_list(&list);
+
+	sc->nr_reclaimed += reclaimed;
+
+	if (!type && swapped)
+		*swapped = true;
+
+	return scanned;
+}
+
+static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool can_swap)
+{
+	bool need_aging;
+	long nr_to_scan;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	DEFINE_MAX_SEQ(lruvec);
+	DEFINE_MIN_SEQ(lruvec);
+
+	if (mem_cgroup_below_min(memcg) ||
+	    (mem_cgroup_below_low(memcg) && !sc->memcg_low_reclaim))
+		return 0;
+
+	nr_to_scan = get_nr_evictable(lruvec, max_seq, min_seq, sc, can_swap, &need_aging);
+	if (!nr_to_scan)
+		return 0;
+
+	nr_to_scan >>= sc->priority;
+
+	if (!mem_cgroup_online(memcg))
+		nr_to_scan++;
+
+	if (!nr_to_scan)
+		return 0;
+
+	if (current_is_kswapd()) {
+		/* leave the work to lru_gen_age_node() */
+		if (need_aging)
+			return 0;
+
+		sc->memcgs_need_aging = 0;
+		return nr_to_scan;
+	}
+
+	if (max_seq >= min_seq[1] + MIN_NR_GENS)
+		return nr_to_scan;
+
+	/* try slab and other memcgs before going to the aging path */
+	if (!sc->force_deactivate) {
+		sc->skipped_deactivate = 1;
+		return 0;
+	}
+
+	return try_to_inc_max_seq(lruvec, max_seq, sc, can_swap, false) ? nr_to_scan : 0;
+}
+
+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+{
+	struct blk_plug plug;
+	long scanned = 0;
+	bool swapped = false;
+	unsigned long reclaimed = sc->nr_reclaimed;
+	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
+	struct pglist_data *pgdat = lruvec_pgdat(lruvec);
+
+	lru_add_drain();
+
+	if (current_is_kswapd())
+		current->reclaim_state->mm_walk = &pgdat->mm_walk;
+
+	blk_start_plug(&plug);
+
+	while (true) {
+		int delta;
+		int swappiness;
+		long nr_to_scan;
+
+		if (sc->may_swap)
+			swappiness = get_swappiness(memcg);
+		else if (!cgroup_reclaim(sc) && get_swappiness(memcg))
+			swappiness = 1;
+		else
+			swappiness = 0;
+
+		nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
+		if (!nr_to_scan)
+			break;
+
+		delta = evict_folios(lruvec, sc, swappiness, &swapped);
+		if (!delta)
+			break;
+
+		if (sc->memcgs_avoid_swapping && swappiness < 200 && swapped)
+			break;
+
+		scanned += delta;
+		if (scanned >= nr_to_scan) {
+			if (!swapped && sc->nr_reclaimed - reclaimed >= MIN_LRU_BATCH)
+				sc->memcgs_need_swapping = 0;
+			break;
+		}
+
+		cond_resched();
+	}
+
+	blk_finish_plug(&plug);
+
+	if (current_is_kswapd())
+		current->reclaim_state->mm_walk = NULL;
+}
+
 /******************************************************************************
  *                          state change
  ******************************************************************************/
@@ -4540,6 +5097,10 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
 {
 }
 
+static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
+{
+}
+
 #endif /* CONFIG_LRU_GEN */
 
 static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
@@ -4553,6 +5114,11 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
 	struct blk_plug plug;
 	bool scan_adjusted;
 
+	if (lru_gen_enabled()) {
+		lru_gen_shrink_lruvec(lruvec, sc);
+		return;
+	}
+
 	get_scan_count(lruvec, sc, nr);
 
 	/* Record the original scan target for proportional adjustments later */
@@ -5057,6 +5623,9 @@ static void snapshot_refaults(struct mem_cgroup *target_memcg, pg_data_t *pgdat)
 	struct lruvec *target_lruvec;
 	unsigned long refaults;
 
+	if (lru_gen_enabled())
+		return;
+
 	target_lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
 	refaults = lruvec_page_state(target_lruvec, WORKINGSET_ACTIVATE_ANON);
 	target_lruvec->refaults[0] = refaults;
diff --git a/mm/workingset.c b/mm/workingset.c
index 8c03afe1d67c..c2e433d76de1 100644
--- a/mm/workingset.c
+++ b/mm/workingset.c
@@ -187,7 +187,6 @@ static unsigned int bucket_order __read_mostly;
 static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction,
 			 bool workingset)
 {
-	eviction >>= bucket_order;
 	eviction &= EVICTION_MASK;
 	eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid;
 	eviction = (eviction << NODES_SHIFT) | pgdat->node_id;
@@ -212,10 +211,116 @@ static void unpack_shadow(void *shadow, int *memcgidp, pg_data_t **pgdat,
 
 	*memcgidp = memcgid;
 	*pgdat = NODE_DATA(nid);
-	*evictionp = entry << bucket_order;
+	*evictionp = entry;
 	*workingsetp = workingset;
 }
 
+#ifdef CONFIG_LRU_GEN
+
+static int folio_lru_refs(struct folio *folio)
+{
+	unsigned long flags = READ_ONCE(folio->flags);
+
+	BUILD_BUG_ON(LRU_GEN_WIDTH + LRU_REFS_WIDTH > BITS_PER_LONG - EVICTION_SHIFT);
+
+	/* see the comment on MAX_NR_TIERS */
+	return flags & BIT(PG_workingset) ? (flags & LRU_REFS_MASK) >> LRU_REFS_PGOFF : 0;
+}
+
+static void *lru_gen_eviction(struct folio *folio)
+{
+	int hist, tier;
+	unsigned long token;
+	unsigned long min_seq;
+	struct lruvec *lruvec;
+	struct lru_gen_struct *lrugen;
+	int type = folio_is_file_lru(folio);
+	int refs = folio_lru_refs(folio);
+	int delta = folio_nr_pages(folio);
+	bool workingset = folio_test_workingset(folio);
+	struct mem_cgroup *memcg = folio_memcg(folio);
+	struct pglist_data *pgdat = folio_pgdat(folio);
+
+	lruvec = mem_cgroup_lruvec(memcg, pgdat);
+	lrugen = &lruvec->lrugen;
+	min_seq = READ_ONCE(lrugen->min_seq[type]);
+	token = (min_seq << LRU_REFS_WIDTH) | refs;
+
+	hist = lru_hist_from_seq(min_seq);
+	tier = lru_tier_from_refs(refs + workingset);
+	atomic_long_add(delta, &lrugen->evicted[hist][type][tier]);
+
+	return pack_shadow(mem_cgroup_id(memcg), pgdat, token, workingset);
+}
+
+static void lru_gen_refault(struct folio *folio, void *shadow)
+{
+	int hist, tier, refs;
+	int memcg_id;
+	bool workingset;
+	unsigned long token;
+	unsigned long min_seq;
+	struct lruvec *lruvec;
+	struct lru_gen_struct *lrugen;
+	struct mem_cgroup *memcg;
+	struct pglist_data *pgdat;
+	int type = folio_is_file_lru(folio);
+	int delta = folio_nr_pages(folio);
+
+	unpack_shadow(shadow, &memcg_id, &pgdat, &token, &workingset);
+
+	refs = token & (BIT(LRU_REFS_WIDTH) - 1);
+	if (refs && !workingset)
+		return;
+
+	if (folio_pgdat(folio) != pgdat)
+		return;
+
+	rcu_read_lock();
+	memcg = folio_memcg_rcu(folio);
+	if (mem_cgroup_id(memcg) != memcg_id)
+		goto unlock;
+
+	token >>= LRU_REFS_WIDTH;
+	lruvec = mem_cgroup_lruvec(memcg, pgdat);
+	lrugen = &lruvec->lrugen;
+	min_seq = READ_ONCE(lrugen->min_seq[type]);
+	if (token != (min_seq & (EVICTION_MASK >> LRU_REFS_WIDTH)))
+		goto unlock;
+
+	hist = lru_hist_from_seq(min_seq);
+	tier = lru_tier_from_refs(refs + workingset);
+	atomic_long_add(delta, &lrugen->refaulted[hist][type][tier]);
+	mod_lruvec_state(lruvec, WORKINGSET_REFAULT_BASE + type, delta);
+
+	/*
+	 * Count the following two cases as stalls:
+	 * 1) For pages accessed thru page tables, hotter pages pushed out hot
+	 *    pages which refaulted immediately.
+	 * 2) For pages accessed thru file descriptors, numbers of accesses
+	 *    might have been beyond the limit.
+	 */
+	if (task_in_lru_fault() || refs + workingset == BIT(LRU_REFS_WIDTH)) {
+		folio_set_workingset(folio);
+		mod_lruvec_state(lruvec, WORKINGSET_RESTORE_BASE + type, delta);
+	}
+unlock:
+	rcu_read_unlock();
+}
+
+#else
+
+static void *lru_gen_eviction(struct folio *folio)
+{
+	return NULL;
+}
+
+static void lru_gen_refault(struct folio *folio, void *shadow)
+{
+}
+
+#endif /* CONFIG_LRU_GEN */
+
 /**
  * workingset_age_nonresident - age non-resident entries as LRU ages
  * @lruvec: the lruvec that was aged
@@ -264,10 +369,14 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
 	VM_BUG_ON_PAGE(page_count(page), page);
 	VM_BUG_ON_PAGE(!PageLocked(page), page);
 
+	if (lru_gen_enabled())
+		return lru_gen_eviction(page_folio(page));
+
 	lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
 	/* XXX: target_memcg can be NULL, go through lruvec */
 	memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
 	eviction = atomic_long_read(&lruvec->nonresident_age);
+	eviction >>= bucket_order;
 	workingset_age_nonresident(lruvec, thp_nr_pages(page));
 	return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page));
 }
@@ -297,7 +406,13 @@ void workingset_refault(struct folio *folio, void *shadow)
 	int memcgid;
 	long nr;
 
+	if (lru_gen_enabled()) {
+		lru_gen_refault(folio, shadow);
+		return;
+	}
+
 	unpack_shadow(shadow, &memcgid, &pgdat, &eviction, &workingset);
+	eviction <<= bucket_order;
 
 	rcu_read_lock();
 	/*
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:22:28 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue,  4 Jan 2022 13:22:28 -0700
Subject: [PATCH v6 9/9] mm: multigenerational lru: Kconfig
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220104202227.2903605-10-yuzhao@google.com>

Add configuration options for the multigenerational lru.

Signed-off-by: Yu Zhao <yuzhao at google.com>
Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
 Documentation/vm/multigen_lru.rst | 18 ++++++++++++
 mm/Kconfig                        | 48 +++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
index 6f9e0181348b..a54c5637c455 100644
--- a/Documentation/vm/multigen_lru.rst
+++ b/Documentation/vm/multigen_lru.rst
@@ -6,6 +6,13 @@ Multigenerational LRU
 
 Quick start
 ===========
+Build configurations
+--------------------
+:Required: Set ``CONFIG_LRU_GEN=y``.
+
+:Optional: Set ``CONFIG_LRU_GEN_ENABLED=y`` to enable this feature by
+ default.
+
 Runtime configurations
 ----------------------
 :Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
@@ -25,6 +32,17 @@ Personal computers
 
 Data centers
 ------------
+:Optional: Change ``CONFIG_NR_LRU_GENS`` to a larger value to support
+ more generations for ``Working set estimation`` and
+ ``Proactive reclaim``.
+
+:Optional: Change ``CONFIG_TIERS_PER_GEN`` to a larger value to
+ support more tiers, which generally provide better protection for
+ page cache when under heavy buffered I/O workloads.
+
+:Optional: Set ``CONFIG_LRU_GEN_STATS=y`` to enable full stats for
+ debugging. See ``Debugfs interface``.
+
 :Debugfs interface: ``/sys/kernel/debug/lru_gen`` has the following
  format:
  ::
diff --git a/mm/Kconfig b/mm/Kconfig
index 356f4f2c779e..8a33605917f5 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -900,6 +900,54 @@ config IO_MAPPING
 config SECRETMEM
 	def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED
 
+# multigenerational lru {
+config LRU_GEN
+	bool "Multigenerational LRU"
+	depends on MMU
+	# the following options can use up the spare bits in page flags
+	depends on !MAXSMP && (64BIT || !SPARSEMEM || SPARSEMEM_VMEMMAP)
+	help
+	  A high performance LRU implementation for memory overcommit. See
+	  Documentation/vm/multigen_lru.rst for details.
+
+config LRU_GEN_ENABLED
+	bool "Enable by default"
+	depends on LRU_GEN
+	help
+	  This option enables the multigenerational lru by default.
+
+config NR_LRU_GENS
+	int "Max number of generations"
+	depends on LRU_GEN
+	range 4 31
+	default 4
+	help
+	  This option uses order_base_2(N+1) bits in page flags.
+
+	  Do not configure more generations than you plan to use. They have a
+	  per-memcg and per-node memory overhead.
+
+config TIERS_PER_GEN
+	int "Number of tiers per generation"
+	depends on LRU_GEN
+	range 2 5
+	default 4
+	help
+	  This option uses N-2 bits in page flags.
+
+	  Larger values generally provide better protection for page cache when
+	  under heavy buffered I/O workloads.
+
+config LRU_GEN_STATS
+	bool "Full stats for debugging"
+	depends on LRU_GEN
+	help
+	  This option keeps historical stats for evicted generations.
+
+	  Do not enable full stats unless you plan to look at them. They have a
+	  per-memcg and per-node memory overhead.
+# }
+
 source "mm/damon/Kconfig"
 
 endmenu
-- 
2.34.1.448.ga2b2bfdf31-goog



From yuzhao at google.com  Tue Jan  4 12:30:00 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 4 Jan 2022 13:30:00 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <YdSuSHa/Vjl6bPkg@google.com>

On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> TLDR
> ====
> The current page reclaim is too expensive in terms of CPU usage and it
> often makes poor choices about what to evict. This patchset offers an
> alternative solution that is performant, versatile and
> straightforward.

<snipped>

> Summery
> =======
> The facts are:
> 1. The independent lab results and the real-world applications
>    indicate substantial improvements; there are no known regressions.
> 2. Thrashing prevention, working set estimation and proactive reclaim
>    work out of the box; there are no equivalent solutions.
> 3. There is a lot of new code; nobody has demonstrated smaller changes
>    with similar effects.
> 
> Our options, accordingly, are:
> 1. Given the amount of evidence, the reported improvements will likely
>    materialize for a wide range of workloads.
> 2. Gauging the interest from the past discussions [14][15][16], the
>    new features will likely be put to use for both personal computers
>    and data centers.
> 3. Based on Google's track record, the new code will likely be well
>    maintained in the long term. It'd be more difficult if not
>    impossible to achieve similar effects on top of the existing
>    design.

Hi Andrew, Linus,

Can you please take a look at this patchset and let me know if it's
5.17 material?

My goal is to get it merged asap so that users can reap the benefits
and I can push the sequels. Please examine the data provided -- I
think the unprecedented coverage and the magnitude of the improvements
warrant a green light.

Thanks!


From robh at kernel.org  Tue Jan  4 12:59:05 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 14:59:05 -0600
Subject: [PATCH] sun7i-a20-marsboard.dts: add marsboard-a20 support
In-Reply-To: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
Message-ID: <YdS1GVkRopRSoD5S@robh.at.kernel.org>

On Sat, Dec 25, 2021 at 12:43:41AM +0800, conleylee at foxmail.com wrote:
> From: Conley Lee <conleylee at foxmail.com>
> 
> ARM dts: sun7i: Add Marsboard A20 board
> 
> This patch add support for Marsboard A20 board.
> 
> The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
> card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
> USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
>  .../devicetree/bindings/arm/sunxi.yaml        |   5 +
>  arch/arm/boot/dts/Makefile                    |   1 +
>  arch/arm/boot/dts/sun7i-a20-marsboard.dts     | 220 ++++++++++++++++++

Bindings and dts files should be separate patches.

>  3 files changed, 226 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sun7i-a20-marsboard.dts
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index 889128acf49a..4bd93ae26bd1 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -444,6 +444,11 @@ properties:
>            - const: haoyu,a10-marsboard
>            - const: allwinner,sun4i-a10
>  
> +      - description: HAOYU Electronics Marsboard A20
> +        items:
> +          - const: haoyu,a20-marsboard
> +          - const: allwinner,sun7i-a20
> +
>        - description: MapleBoard MP130
>          items:
>            - const: mapleboard,mp130
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..4628a2617313 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
>  	sun7i-a20-icnova-swac.dtb \
>  	sun7i-a20-lamobo-r1.dtb \
>  	sun7i-a20-linutronix-testbox-v2.dtb \
> +	sun7i-a20-marsboard.dtb \
>  	sun7i-a20-m3.dtb \
>  	sun7i-a20-mk808c.dtb \
>  	sun7i-a20-olimex-som-evb.dtb \
> diff --git a/arch/arm/boot/dts/sun7i-a20-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> new file mode 100644
> index 000000000000..159e69e148e7
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> @@ -0,0 +1,220 @@
> +/*
> + * Copyright 2021 Conley Lee
> + * Conley Lee <conleylee at foxmail.com>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + *  a) This file 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 file 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.
> + *
> + * Or, alternatively,
> + *
> + *  b) Permission is hereby granted, free of charge, to any person
> + *     obtaining a copy of this software and associated documentation
> + *     files (the "Software"), to deal in the Software without
> + *     restriction, including without limitation the rights to use,
> + *     copy, modify, merge, publish, distribute, sublicense, and/or
> + *     sell copies of the Software, and to permit persons to whom the
> + *     Software is furnished to do so, subject to the following
> + *     conditions:
> + *
> + *     The above copyright notice and this permission notice shall be
> + *     included in all copies or substantial portions of the Software.
> + *
> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + *     OTHER DEALINGS IN THE SOFTWARE.

Use SPDX tag instead.

> + */
> +
> +/dts-v1/;
> +#include "sun7i-a20.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> +	model = "HAOYU Electronics Marsboard A20";
> +	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +};
> +
> +&ahci {
> +	target-supply = <&reg_ahci_5v>;
> +	status = "okay";
> +};
> +
> +&codec {
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&de {
> +	status = "okay";
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&gmac_mii_pins {
> +	pins = "PA0", "PA1", "PA2",
> +	"PA3", "PA4", "PA5", "PA6",
> +	"PA7", "PA8", "PA9", "PA10",
> +	"PA11", "PA12", "PA13", "PA14",
> +	"PA15", "PA16", "PA17";
> +};
> +
> +&gmac {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac_mii_pins>;
> +	phy-handle = <&phy0>;
> +	phy-mode = "mii";
> +	status = "okay";
> +};
> +
> +&hdmi {
> +	status = "okay";
> +};
> +
> +&hdmi_out {
> +	hdmi_out_con: endpoint {
> +		remote-endpoint = <&hdmi_con_in>;
> +	};
> +};
> +
> +&i2c0 {
> +	status = "okay";
> +
> +	axp209: pmic at 34 {
> +		reg = <0x34>;
> +		interrupt-parent = <&nmi_intc>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +};
> +
> +&mmc0 {
> +	vmmc-supply = <&reg_vcc3v3>;
> +	bus-width = <4>;
> +	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
> +	status = "okay";
> +};
> +
> +&gmac_mdio {
> +	phy0: ethernet-phy at 0 {
> +		reg = <0>;
> +	};
> +};
> +
> +&ohci0 {
> +	status = "okay";
> +};
> +
> +&ohci1 {
> +	status = "okay";
> +};
> +
> +&otg_sram {
> +	status = "okay";
> +};
> +
> +&reg_ahci_5v {
> +	status = "okay";
> +};
> +
> +#include "axp209.dtsi"
> +
> +&ac_power_supply {
> +	status = "okay";
> +};
> +
> +&reg_dcdc2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1450000>;
> +	regulator-name = "vdd-cpu";
> +};
> +
> +&reg_dcdc3 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <1000000>;
> +	regulator-max-microvolt = <1400000>;
> +	regulator-name = "vdd-int-dll";
> +};
> +
> +&reg_ldo1 {
> +	regulator-name = "vdd-rtc";
> +};
> +
> +&reg_ldo2 {
> +	regulator-always-on;
> +	regulator-min-microvolt = <3000000>;
> +	regulator-max-microvolt = <3000000>;
> +	regulator-name = "avcc";
> +};
> +
> +&reg_usb1_vbus {
> +	status = "okay";
> +};
> +
> +&reg_usb2_vbus {
> +	status = "okay";
> +};
> +
> +&uart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&uart0_pb_pins>;
> +	status = "okay";
> +};
> +
> +&usb_otg {
> +	dr_mode = "otg";
> +	status = "okay";
> +};
> +
> +&usbphy {
> +	usb0_id_det-gpios = <&pio 7 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH4 */
> +	usb1_vbus-supply = <&reg_usb1_vbus>;
> +	usb2_vbus-supply = <&reg_usb2_vbus>;
> +	status = "okay";
> +};
> -- 
> 2.34.1
> 
> 


From sboyd at kernel.org  Tue Jan  4 13:04:59 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 04 Jan 2022 13:04:59 -0800
Subject: [GIT PULL] clk: imx: Updates for v5.17
In-Reply-To: <1639866882-9578-1-git-send-email-abel.vesa@nxp.com>
References: <1639866882-9578-1-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220104210500.59ADFC36AE0@smtp.kernel.org>

Quoting Abel Vesa (2021-12-18 14:34:42)
> The following changes since commit fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf:
> 
>   Linux 5.16-rc1 (2021-11-14 13:56:52 -0800)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git/ tags/clk-imx-5.17
> 
> for you to fetch changes up to 9dd81021084ff22cf88a180d720f4f4b47392059:
> 
>   clk: imx8mp: Fix the parent clk of the audio_root_clk (2021-11-22 17:33:12 +0200)
> 
> ----------------------------------------------------------------

Thanks. Pulled into clk-next


From torvalds at linux-foundation.org  Tue Jan  4 13:24:17 2022
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Tue, 4 Jan 2022 13:24:17 -0800
Subject: [PATCH v6 2/9] mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
In-Reply-To: <20220104202227.2903605-3-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-3-yuzhao@google.com>
Message-ID: <CAHk-=wgvOqj6LUhNp8V5ddT8eZyYdFDzMZE73KgPggOnc28VWg@mail.gmail.com>

On Tue, Jan 4, 2022 at 12:23 PM Yu Zhao <yuzhao at google.com> wrote:
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 5c2ccb85f2ef..5a4843242f09 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -85,6 +85,7 @@ config X86
> +       select ARCH_HAS_NONLEAF_PMD_YOUNG       if X86_64

Why is this limited to 64-bit?

I'm ok with that - maybe it's a simple case of "this is not worth
doing on 32-bit", but I'd like the explanation to be written out.

Right now the commit message literally points the architecture manual
that sio relevant for both 32-bit and 64-bit - and then the patch
itself makes it 64-bit only.

              Linus


From torvalds at linux-foundation.org  Tue Jan  4 13:34:18 2022
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Tue, 4 Jan 2022 13:34:18 -0800
Subject: [PATCH v6 4/9] mm: multigenerational lru: groundwork
In-Reply-To: <20220104202227.2903605-5-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-5-yuzhao@google.com>
Message-ID: <CAHk-=wib5-tUrf2=zYL9hjCqqFykZmTr_-vMAvSo48boCA+-Wg@mail.gmail.com>

On Tue, Jan 4, 2022 at 12:23 PM Yu Zhao <yuzhao at google.com> wrote:
>

> index a7e4a9e7d807..fadbf8e6abcd 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
>
> +#ifdef CONFIG_LRU_GEN
> +static inline void task_enter_lru_fault(void)
> +{
> +       WARN_ON_ONCE(current->in_lru_fault);
...

Why are these in this very core header file?

They are used in one single file - mm/memory.c.

They should be just static functions there.

I'm also not sure why the calling convention is

        if (lru_fault)
                task_enter_lru_fault();

instead of doing just

        task_enter_lru_fault(vma);

and having that function do

        /* Don't do LRU fault accounting for SEQ/RAND files */
        if (unlikely(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ)))
                return;

which would seem to be a lot more legible and straightforward.

In fact, you could do it without any conditionals at all, if you just
remove the WARN_ON_ONCE() from the exit path, turning it into just

        current->in_lru_fault = !(vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ));

for 'enter' and just

        current->in_lru_fault = 0;

for exit.

It seems pointless to have that extra variable, and the extra
conditionals, for a case that is probably very unusual indeed.

                  Linus


From torvalds at linux-foundation.org  Tue Jan  4 13:39:49 2022
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Tue, 4 Jan 2022 13:39:49 -0800
Subject: [PATCH v6 9/9] mm: multigenerational lru: Kconfig
In-Reply-To: <20220104202227.2903605-10-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-10-yuzhao@google.com>
Message-ID: <CAHk-=wjc3vpQfSTzJ8DwCVfmj6Mhq16d375cMPOgFB5A1EL2tw@mail.gmail.com>

On Tue, Jan 4, 2022 at 12:23 PM Yu Zhao <yuzhao at google.com> wrote:
>
> Add configuration options for the multigenerational lru.
>         def_bool ARCH_HAS_SET_DIRECT_MAP && !EMBEDDED
>
> +config NR_LRU_GENS
> +       int "Max number of generations"
> +       depends on LRU_GEN
> +       range 4 31
> +       default 4
> +       help
> +         This option uses order_base_2(N+1) bits in page flags.
> +
> +         Do not configure more generations than you plan to use. They have a
> +         per-memcg and per-node memory overhead.
> +
> +config TIERS_PER_GEN
> +       int "Number of tiers per generation"
> +       depends on LRU_GEN
> +       range 2 5
> +       default 4
> +       help
> +         This option uses N-2 bits in page flags.
> +
> +         Larger values generally provide better protection for page cache when
> +         under heavy buffered I/O workloads.

These are not appropriate questions to ask users.

No user has any idea what the answer should be. And no, we don't add
"benchmark tuning Kconfig questions" to the kernel. We leave those
kinds of games to companies that need to fake their benchmark numbers.

If *you* can't give a good number for these config options, then no
user or distro can either.

So just pick a number, and stand by it.

Don't do this kind of "I don't know what the right number is, so I'll
just push the blame on the user".

                Linus


From torvalds at linux-foundation.org  Tue Jan  4 13:43:13 2022
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Tue, 4 Jan 2022 13:43:13 -0800
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdSuSHa/Vjl6bPkg@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
Message-ID: <CAHk-=whMbX+GUBY=Fyxo3r-XVvfNyFA+4hUJS7UxgYDxf9Wbcw@mail.gmail.com>

On Tue, Jan 4, 2022 at 12:30 PM Yu Zhao <yuzhao at google.com> wrote:
>
> My goal is to get it merged asap so that users can reap the benefits
> and I can push the sequels. Please examine the data provided -- I
> think the unprecedented coverage and the magnitude of the improvements
> warrant a green light.

I'll leave this to Andrew. I had some stylistic nits, but all the
actual complexity is in that aging and eviction, and while I looked at
the patches, I certainly couldn't make much of a judgement on them.

The proof is in the numbers, and they look fine, but who knows what
happens when others test it. I don't see anything that looks worrisome
per se, I just see the silly small things that made me go "Eww".

             Linus


From f.fainelli at gmail.com  Tue Jan  4 13:57:30 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 4 Jan 2022 13:57:30 -0800
Subject: [PATCH] ARM: dts: gpio-ranges property is now required
In-Reply-To: <20220104170247.956760-1-linus.walleij@linaro.org>
References: <20220104170247.956760-1-linus.walleij@linaro.org>
Message-ID: <6f42ceda-c000-7506-65ec-53534b5aef7d@gmail.com>

On 1/4/22 9:02 AM, Linus Walleij wrote:
> From: Phil Elwell <phil at raspberrypi.com>
> 
> Since [1], added in 5.7, the absence of a gpio-ranges property has
> prevented GPIOs from being restored to inputs when released.
> Add those properties for BCM283x and BCM2711 devices.
> 
> [1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
>     pin-ranges")
> 
> Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
> Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
> Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
> Reported-by: Florian Fainelli <f.fainelli at gmail.com>
> Reported-by: Jan Kiszka <jan.kiszka at web.de>
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Hi SoC maintainers, please apply this directly for fixes, the
> missing patch is wreacking havoc in the RPi world.

Acked-by: Florian Fainelli <f.fainelli at gmail.com>

Now that "pinctrl: bcm2835: Change init order for gpio hogs" is in
Linus' master this patch can go in... what a mess, let's not do this again.
-- 
Florian


From f.fainelli at gmail.com  Tue Jan  4 13:58:09 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 4 Jan 2022 13:58:09 -0800
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
Message-ID: <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>

On 12/24/21 9:11 AM, Florian Fainelli wrote:
> Hi Arnd, Olof,
> 
> On 12/23/2021 13:31, Arnd Bergmann wrote:
>> I'm sending out the pull requests for 5.17 early, as I won't have
>> access to
>> my workstation for the next two weeks. With only 760 non-merge commits,
>> this again feels quieter than the massive previous merge window, but the
>> number of changed lines was actually slightly higher.
>>
>> There are very few changes aside from devicetree patches, most of
>> which are for the i.MX, Tegra, Qualcomm, Apple, K3 and Aspeed
>> platforms.
>>
>> We have a couple of new SoCs in existing families:
>>
>> ? - Qualcomm Snapdragon 8 Gen1
>> ? - Qualcomm Snapdragon SDX65
>> ? - NXP i.MX8ULP
>> ? - Texas Instruments j721s2
>> ? - Renesas R-Car S4-8
>>
>> The time between product announcement and kernel support is fairly short
>> for all of these, which is nice. In particular the two Snapdragons
>> were only
>> announced this month and are the current high end of Qualcomm's products.
>> On the other end of the spectrum, we also add support for ST SPEAr320s,
>> which was launched 10 years ago.
>>
>> Aside from the Arm chips, there is also a pull request for a new
>> RISC-V SoC,
>> the Starfive JH7100, including some of the basic drivers to make it boot.
> 
> There seems to half of the submitted Broadcom SoCs pull request missing
> in this one, was there issues with those below:
> 
> defconfigs:
> 
> https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-1-f.fainelli at gmail.com/
> 
> https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-2-f.fainelli at gmail.com/
> 
> 
> drivers:
> 
> https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-5-f.fainelli at gmail.com/
> 
> 
> Should I resend or fix something in those? Thanks!


Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
Thanks and happy new year.
-- 
Florian


From robh at kernel.org  Tue Jan  4 14:05:30 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 16:05:30 -0600
Subject: [PATCH] dt-bindings: clock: Add binding for TI clksel
In-Reply-To: <YcLElm04V47kP0Z9@atomide.com>
References: <20211217113640.59840-1-tony@atomide.com>
 <YcIZNfTn37uNbj0F@robh.at.kernel.org>
 <YcLElm04V47kP0Z9@atomide.com>
Message-ID: <CAL_JsqLek5SOypZhTxpLK13x2HEYbLbYYotLGOfM-JTb=QE-Eg@mail.gmail.com>

On Wed, Dec 22, 2021 at 12:24 AM Tony Lindgren <tony at atomide.com> wrote:
>
> Hi,
>
> * Rob Herring <robh at kernel.org> [211221 18:13]:
> > On Fri, Dec 17, 2021 at 01:36:40PM +0200, Tony Lindgren wrote:
> > > +additionalProperties: true
> >
> > Like what properties?
> >
> > true is only used for common, incomplete schemas referenced by device
> > schemas.
>
> There is a collection of the current component clock child nodes for each
> clksel instance. I got warnings with "additionalProperties: false", but
> maybe the child clock nodes need to be somehow specified in the binding?

If everything else is a child node, then you can do:

additionalProperties:
  type: object

>
> For example, below is a sample patch for am335x CLKSEL_GFX_FCLK using a
> clksel parent node with the child nodes moved to fix warnings for
> unique_unit_address. It also has clock-output-names property added to
> avoid the node naming warnings. For the other clksel instances, they can
> be a collection of dividers, multipliers, gates and muxes.
>
> Regards,
>
> Tony
>
> 8< --------
> diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi
> --- a/arch/arm/boot/dts/am33xx-clocks.dtsi
> +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi
> @@ -494,20 +494,27 @@ mmc_clk: mmc_clk {
>                 clock-div = <2>;
>         };
>
> -       gfx_fclk_clksel_ck: gfx_fclk_clksel_ck at 52c {
> -               #clock-cells = <0>;
> -               compatible = "ti,mux-clock";
> -               clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>;
> -               ti,bit-shift = <1>;
> -               reg = <0x052c>;
> -       };
> +       clock at 52c {
> +               compatible = "ti,clksel";
> +               reg = <0x52c>;
> +               #clock-cells = <1>;
> +               #address-cells = <0>;
> +
> +               gfx_fclk_clksel_ck: clock-gfx-fclk-clksel {
> +                       #clock-cells = <0>;
> +                       compatible = "ti,mux-clock";
> +                       clock-output-names = "gfx_fclk_clksel_ck";
> +                       clocks = <&dpll_core_m4_ck>, <&dpll_per_m2_ck>;
> +                       ti,bit-shift = <1>;
> +               };
>
> -       gfx_fck_div_ck: gfx_fck_div_ck at 52c {
> -               #clock-cells = <0>;
> -               compatible = "ti,divider-clock";
> -               clocks = <&gfx_fclk_clksel_ck>;
> -               reg = <0x052c>;
> -               ti,max-div = <2>;
> +               gfx_fck_div_ck: clock-gfx-fck-div {
> +                       #clock-cells = <0>;
> +                       compatible = "ti,divider-clock";
> +                       clock-output-names = "gfx_fck_div_ck";
> +                       clocks = <&gfx_fclk_clksel_ck>;
> +                       ti,max-div = <2>;
> +               };
>         };
>
>         sysclkout_pre_ck: sysclkout_pre_ck at 700 {


From robh at kernel.org  Tue Jan  4 14:33:07 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 16:33:07 -0600
Subject: [PATCH v1 1/3] dt-bindings: mmc: add cap-sdio-async-int flag
In-Reply-To: <20211227083641.12538-2-axe.yang@mediatek.com>
References: <20211227083641.12538-1-axe.yang@mediatek.com>
 <20211227083641.12538-2-axe.yang@mediatek.com>
Message-ID: <YdTLI/Nms4JiNutt@robh.at.kernel.org>

On Mon, Dec 27, 2021 at 04:36:39PM +0800, Axe Yang wrote:
> Asynchronous interrupt is a mechanism that allow SDIO devices alarm
> interrupt when host stop providing clock to card. Add a DT flag to
> enable this feature if it is supported by SDIO card.

A card property should be in the card node. Is this not discoverable?

> 
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
> index 25ac8e200970..7230421583c6 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
> +++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
> @@ -165,6 +165,11 @@ properties:
>      description:
>        eMMC hardware reset is supported
>  
> +  cap-sdio-async-int:

Perhaps be consistent with the next property and use 'irq'.

> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      SDIO async interrupt is supported.
> +
>    cap-sdio-irq:
>      $ref: /schemas/types.yaml#/definitions/flag
>      description:
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Tue Jan  4 14:50:55 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 4 Jan 2022 16:50:55 -0600
Subject: [PATCH RFC 02/11] dt-bindings: dma: Convert brcm,bcm2835-dma to
 json-schema
In-Reply-To: <1640606743-10993-3-git-send-email-stefan.wahren@i2se.com>
References: <1640606743-10993-1-git-send-email-stefan.wahren@i2se.com>
 <1640606743-10993-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <YdTPT4osjSDYzzRg@robh.at.kernel.org>

On Mon, Dec 27, 2021 at 01:05:36PM +0100, Stefan Wahren wrote:
> This convert the BCM2835 DMA bindings to YAML format.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>  .../devicetree/bindings/dma/brcm,bcm2835-dma.txt   |  83 ----------------
>  .../devicetree/bindings/dma/brcm,bcm2835-dma.yaml  | 107 +++++++++++++++++++++
>  2 files changed, 107 insertions(+), 83 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
>  create mode 100644 Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> 
> diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
> deleted file mode 100644
> index b6a8cc0..0000000
> --- a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.txt
> +++ /dev/null
> @@ -1,83 +0,0 @@
> -* BCM2835 DMA controller
> -
> -The BCM2835 DMA controller has 16 channels in total.
> -Only the lower 13 channels have an associated IRQ.
> -Some arbitrary channels are used by the firmware
> -(1,3,6,7 in the current firmware version).
> -The channels 0,2 and 3 have special functionality
> -and should not be used by the driver.
> -
> -Required properties:
> -- compatible: Should be "brcm,bcm2835-dma".
> -- reg: Should contain DMA registers location and length.
> -- interrupts: Should contain the DMA interrupts associated
> -		to the DMA channels in ascending order.
> -- interrupt-names: Should contain the names of the interrupt
> -		   in the form "dmaXX".
> -		   Use "dma-shared-all" for the common interrupt line
> -		   that is shared by all dma channels.
> -- #dma-cells: Must be <1>, the cell in the dmas property of the
> -		client device represents the DREQ number.
> -- brcm,dma-channel-mask: Bit mask representing the channels
> -			 not used by the firmware in ascending order,
> -			 i.e. first channel corresponds to LSB.
> -
> -Example:
> -
> -dma: dma at 7e007000 {
> -	compatible = "brcm,bcm2835-dma";
> -	reg = <0x7e007000 0xf00>;
> -	interrupts = <1 16>,
> -		     <1 17>,
> -		     <1 18>,
> -		     <1 19>,
> -		     <1 20>,
> -		     <1 21>,
> -		     <1 22>,
> -		     <1 23>,
> -		     <1 24>,
> -		     <1 25>,
> -		     <1 26>,
> -		     /* dma channel 11-14 share one irq */
> -		     <1 27>,
> -		     <1 27>,
> -		     <1 27>,
> -		     <1 27>,
> -		     /* unused shared irq for all channels */
> -		     <1 28>;
> -	interrupt-names = "dma0",
> -			  "dma1",
> -			  "dma2",
> -			  "dma3",
> -			  "dma4",
> -			  "dma5",
> -			  "dma6",
> -			  "dma7",
> -			  "dma8",
> -			  "dma9",
> -			  "dma10",
> -			  "dma11",
> -			  "dma12",
> -			  "dma13",
> -			  "dma14",
> -			  "dma-shared-all";
> -
> -	#dma-cells = <1>;
> -	brcm,dma-channel-mask = <0x7f35>;
> -};
> -
> -
> -DMA clients connected to the BCM2835 DMA controller must use the format
> -described in the dma.txt file, using a two-cell specifier for each channel.
> -
> -Example:
> -
> -bcm2835_i2s: i2s at 7e203000 {
> -	compatible = "brcm,bcm2835-i2s";
> -	reg = <	0x7e203000 0x24>;
> -	clocks = <&clocks BCM2835_CLOCK_PCM>;
> -
> -	dmas = <&dma 2>,
> -	       <&dma 3>;
> -	dma-names = "tx", "rx";
> -};
> diff --git a/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> new file mode 100644
> index 0000000..44cb83f
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/brcm,bcm2835-dma.yaml
> @@ -0,0 +1,107 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/dma/brcm,bcm2835-dma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: BCM2835 DMA controller
> +
> +maintainers:
> +  - Nicolas Saenz Julienne <nsaenz at kernel.org>
> +
> +description: |

Don't need '|' unless there is formatting to preserve.

> +  The BCM2835 DMA controller has 16 channels in total.
> +  Only the lower 13 channels have an associated IRQ.
> +  Some arbitrary channels are used by the firmware
> +  (1,3,6,7 in the current firmware version).
> +  The channels 0,2 and 3 have special functionality
> +  and should not be used by the driver.

Re-wrap the lines.

> +
> +allOf:
> +  - $ref: "dma-controller.yaml#"
> +
> +properties:
> +  compatible:
> +    const: brcm,bcm2835-dma
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    description:
> +      Should contain the DMA interrupts associated to the DMA channels in
> +      ascending order.
> +    minItems: 1
> +    maxItems: 16
> +
> +  interrupt-names:
> +    minItems: 1
> +    maxItems: 16

The names must be defined. You can do:

items:
  pattern: ...

> +
> +  "#dma-cells":
> +    const: 1
> +    description: >
> +      DMA clients must use the format described in dma.txt, giving a phandle

Please read dma.txt.

> +      to the DMA controller while the second cell in the dmas property of the

Cells don't include the phandle, so 'second cell' is odd. Reword all 
this to be just what is specific to this binding.

> +      client device represents the DREQ number.
> +
> +  brcm,dma-channel-mask:
> +    description:
> +      Bit mask representing the channels not used by the firmware in
> +      ascending order, i.e. first channel corresponds to LSB.
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - "#dma-cells"
> +  - brcm,dma-channel-mask
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dma: dma-controller at 7e007000 {
> +      compatible = "brcm,bcm2835-dma";
> +      reg = <0x7e007000 0xf00>;
> +      interrupts = <1 16>,
> +                   <1 17>,
> +                   <1 18>,
> +                   <1 19>,
> +                   <1 20>,
> +                   <1 21>,
> +                   <1 22>,
> +                   <1 23>,
> +                   <1 24>,
> +                   <1 25>,
> +                   <1 26>,
> +                   /* dma channel 11-14 share one irq */
> +                   <1 27>,
> +                   <1 27>,
> +                   <1 27>,
> +                   <1 27>,
> +                   /* unused shared irq for all channels */
> +                   <1 28>;
> +      interrupt-names = "dma0",
> +                        "dma1",
> +                        "dma2",
> +                        "dma3",
> +                        "dma4",
> +                        "dma5",
> +                        "dma6",
> +                        "dma7",
> +                        "dma8",
> +                        "dma9",
> +                        "dma10",
> +                        "dma11",
> +                        "dma12",
> +                        "dma13",
> +                        "dma14",
> +                        "dma-shared-all";
> +        #dma-cells = <1>;
> +        brcm,dma-channel-mask = <0x7f35>;
> +    };
> +
> +...
> -- 
> 2.7.4
> 
> 


From james.quinlan at broadcom.com  Tue Jan  4 15:01:05 2022
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Tue, 4 Jan 2022 18:01:05 -0500
Subject: [PATCH v10 0/7] PCI: brcmstb: root port turns on sub-device power
In-Reply-To: <20220104141742.GA27804@lpieralisi>
References: <20211209211407.8102-1-jim2101024@gmail.com>
 <YbOf836C58fUSmCO@robh.at.kernel.org>
 <d659ec6c-ddf8-87b9-ebf1-b32c3730d038@gmail.com>
 <20220104141742.GA27804@lpieralisi>
Message-ID: <CA+-6iNxiRqYNbBYcZqg13K4RExrVZfbJjUDH3x9Rh7E_dQ7JGg@mail.gmail.com>

On Tue, Jan 4, 2022 at 9:18 AM Lorenzo Pieralisi
<lorenzo.pieralisi at arm.com> wrote:
>
> On Fri, Dec 10, 2021 at 12:31:10PM -0800, Florian Fainelli wrote:
> > On 12/10/21 10:44 AM, Rob Herring wrote:
> > > On Thu, Dec 09, 2021 at 04:13:58PM -0500, Jim Quinlan wrote:
> > >> v10 -- Bindings commit example: in comment, refer to bridge under
> > >>        controller node as a root port. (Pali)
> > >>     -- Bindings commit example: remove three properties that are not
> > >>        appropriate for a PCIe endpoint node. (Rob)
> > >>
> > >> v9  -- Simplify where this mechanism works: instead of looking for
> > >>        regulators below every bridge, just look for them at the
> > >>        bridge under the root bus (root port).  Now there is no
> > >>        modification of portdrv_{pci,core}.c in this submission.
> > >>     -- Although Pali is working on support for probing native
> > >>        PCIe controller drivers, this work may take some time to
> > >>        implement and it still might not be able to accomodate
> > >>        our driver's requirements (e.g. vreg suspend/resume control).
> > >>     -- Move regulator suspend/resume control to Brcm RC driver.  It
> > >>        must reside there because (a) in order to know when to
> > >>        initiate linkup during resume and (b) to turn on the
> > >>        regulators before any config-space accesses occur.
> > >
> > > You now have a mixture of 'generic' add/remove_bus hooks and the host
> > > controller suspend/resume managing the regulators. I think long term,
> > > the portdrv is going to be the right place for all of this with some
> > > interface defined for link control. So I think this solution moves
> > > sideways rather than towards anything common.
> > >
> > > Unfortunately, the only leverage maintainers have to get folks to care
> > > about any refactoring is to reject features. We're lucky to find anyone
> > > to test refactoring when posted if done independently. There's a long
> > > list of commits of PCI hosts that I've broken to prove that. So it's
> > > up to Lorenzo and Bjorn on what they want to do here.
> >
> > After version 10, it would seem pretty clear that we are still very much
> > committed to and interested in getting that set merged and do it the
> > most acceptable way possible. Common code with a single user is always a
> > little bit of a grey area to me as it tends to be developed to cater for
> > the specific needs of that single user, so the entire common aspect is
> > debatable. I suppose as long as we have the binding right, the code can
> > change at will.
> >
> > Not trying to coerce Bjorn and Lorenzo into accepting these patches if
> > they don't feel comfortable, but what about getting it included so we
> > can sort of move on from that topic for a little bit (as we have other
> > PCIe changes coming in, supporting additional chips etc.) and we work
> > with Pali on a common solution and ensure it works on our pcie-brcmstb.c
> > based devices? We are not going to vanish and not come back looking at this.
>
> Sorry for being late on reviewing this set. I agree with both of you.
>
> I don't think Bjorn had a chance to have a look at patch (4) now I am
> delegating it to him; I am not very keen on adding functionality to PCI
> core where it is still a question whether it can be reused by other
> drivers (forgive me if I missed some details on previous review
> versions).
>
> Is it possible to keep patch (4) brcmstb specific (ie keep the code
> out of PCI core for now), we then merge this series and help Pali
> implement a generic version based on Rob's suggestion ?
>
> Just let me know please, thanks.
Hi Lorenzo,

That sounds good to me.  Pullreq coming tomorrow.

Thanks,
Jim Quinlan
Broadcom STB
>
> Lorenzo


From patrick at stwcx.xyz  Tue Jan  4 15:18:22 2022
From: patrick at stwcx.xyz (Patrick Williams)
Date: Tue, 4 Jan 2022 17:18:22 -0600
Subject: [PATCH] ARM: dts: aspeed: update dts of Bletchley platform
In-Reply-To: <20220104093008.624-1-potin.lai@quantatw.com>
References: <20220104093008.624-1-potin.lai@quantatw.com>
Message-ID: <YdTVvuXiPPRaMw99@heinlein>

Hi Potin,

A few minor comments.  You might want to leave more information in the device
tree for a few of these since they seem like non-obvious settings.

On Tue, Jan 04, 2022 at 05:30:08PM +0800, Potin Lai wrote:
> updates:
> * seperate leds into multiple groups
> * switch sled numbering to 1-based
> * disable inchip rtc
> * add flash1 in fmc
> * switch spi2 pnor using spi-gpio
> * update gpio-line-names
> 
> Signed-off-by: Potin Lai <potin.lai at quantatw.com>
> ---
>  .../dts/aspeed-bmc-facebook-bletchley.dts     | 277 +++++++++++-------
>  1 file changed, 163 insertions(+), 114 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
> index f973ea883b97..d617cfebcb18 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-facebook-bletchley.dts
...
>  
>  &rtc {
> -	status = "okay";
> +	status = "disabled";
>  };

Since it is more atypical to disable the in-chip RTC would you mind leaving a
comment in the DTS as to why?  I see we have the nxp,pcf85263 later on.

>  &spi2 {
>  	status = "okay";
> -	pinctrl-names = "default";
> -	pinctrl-0 = <&pinctrl_spi2_default>;
> +
> +	compatible = "spi-gpio";
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +
> +	gpio-sck = <&gpio0 ASPEED_GPIO(X, 3) GPIO_ACTIVE_HIGH>;
> +	gpio-mosi = <&gpio0 ASPEED_GPIO(X, 4) GPIO_ACTIVE_HIGH>;
> +	gpio-miso = <&gpio0 ASPEED_GPIO(X, 5) GPIO_ACTIVE_HIGH>;
> +	num-chipselects = <1>;
> +	cs-gpios = <&gpio0 ASPEED_GPIO(X, 0) GPIO_ACTIVE_LOW>;
>  
>  	flash at 0 {
>  		status = "okay";
>  		m25p,fast-read;
>  		label = "pnor";
> -		spi-max-frequency = <100000000>;
> +		spi-max-frequency = <12000000>;
>  	};
>  };

Why is this one being changed to spi-gpio?  That is significantly worse
performance.  Is there another (non-NOR) SPI device on this bus that is missing
from the device tree?

-- 
Patrick Williams
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220104/0126caf3/attachment.sig>

From alexandre.belloni at bootlin.com  Tue Jan  4 15:44:44 2022
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Wed, 5 Jan 2022 00:44:44 +0100
Subject: [PATCH V3 1/2] dt-bindings: rtc: zynqmp: Add clock information
In-Reply-To: <SA1PR02MB8560D9A6A6C90DC1A90A2364C7679@SA1PR02MB8560.namprd02.prod.outlook.com>
References: <20211130055541.2789-1-srinivas.neeli@xilinx.com>
 <SA1PR02MB8560D9A6A6C90DC1A90A2364C7679@SA1PR02MB8560.namprd02.prod.outlook.com>
Message-ID: <YdTb7IixX6JsUtJ4@piout.net>

Hello Srinivas,

On 30/11/2021 06:37:45+0000, Radhey Shyam Pandey wrote:
> > -----Original Message-----
> > From: Srinivas Neeli <srinivas.neeli at xilinx.com>
> > Sent: Tuesday, November 30, 2021 11:26 AM
> > To: a.zummo at towertech.it; alexandre.belloni at bootlin.com; Michal Simek
> > <michals at xilinx.com>; Srinivas Goud <sgoud at xilinx.com>; Shubhrajyoti Datta
> > <shubhraj at xilinx.com>; Radhey Shyam Pandey <radheys at xilinx.com>
> > Cc: linux-rtc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> > kernel at vger.kernel.org; git <git at xilinx.com>; Srinivas Neeli
> > <sneeli at xilinx.com>
> > Subject: [PATCH V3 1/2] dt-bindings: rtc: zynqmp: Add clock information
> > 
> > Added clock information and deprecated calibration support.
> 
> Better to also add some background for this change.
> > 
> > Signed-off-by: Srinivas Neeli <srinivas.neeli at xilinx.com>
> 
> Please add Rob and DT mailing list.
> 

I'm indeed waiting on Rob's review...

> ./scripts/get_maintainer.pl <.patch>
> > ---
> > Changes in V3:
> > -New patch
> > ---
> >  .../bindings/rtc/xlnx,zynqmp-rtc.yaml         | 20 +++++++++----------
> >  1 file changed, 10 insertions(+), 10 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
> > b/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
> > index bdb72d3ddf2a..7e87bc1ef9df 100644
> > --- a/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
> > +++ b/Documentation/devicetree/bindings/rtc/xlnx,zynqmp-rtc.yaml
> > @@ -26,20 +26,19 @@ properties:
> >    interrupts:
> >      minItems: 2
> > 
> > +  clocks:
> > +    items:
> > +      - description: rtc_clk is the operating frequency of crystal.
> > +
> > +  clock-names:
> > +    items:
> > +      - const: "rtc_clk"
> > +
> >    interrupt-names:
> >      items:
> >        - const: alarm
> >        - const: sec
> > 
> > -  calibration:
> 
> What about existing users for this property?
> > -    description: |
> > -      calibration value for 1 sec period which will
> > -      be programmed directly to calibration register.
> > -    $ref: /schemas/types.yaml#/definitions/uint32
> > -    minimum: 0x1
> > -    maximum: 0x1FFFFF
> > -    default: 0x198233
> > -

I think this needs to stay to mark it as deprecated.

> >  required:
> >    - compatible
> >    - reg
> > @@ -60,6 +59,7 @@ examples:
> >          interrupt-parent = <&gic>;
> >          interrupts = <0 26 4>, <0 27 4>;
> >          interrupt-names = "alarm", "sec";
> > -        calibration = <0x198233>;
> > +        clock-names = "rtc_clk";
> > +        clocks = <&rtc_clk>;
> >        };
> >      };
> > --
> > 2.17.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From alexandre.belloni at bootlin.com  Tue Jan  4 15:48:09 2022
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Wed, 5 Jan 2022 00:48:09 +0100
Subject: [PATCH V3 2/2] rtc: zynqmp: Add calibration set and get support
In-Reply-To: <20211130055541.2789-2-srinivas.neeli@xilinx.com>
References: <20211130055541.2789-1-srinivas.neeli@xilinx.com>
 <20211130055541.2789-2-srinivas.neeli@xilinx.com>
Message-ID: <YdTcuX9q+m+GRLdk@piout.net>

On 30/11/2021 11:25:41+0530, Srinivas Neeli wrote:
> Zynqmp RTC controller has a calibration feature to compensate
> time deviation due to input clock inaccuracy.
> Set and get calibration API's are used for setting and getting
> calibration value from the controller calibration register.
> 
> Signed-off-by: Srinivas Neeli <srinivas.neeli at xilinx.com>
> ---
> Changes in V3:
>  -Calculated tick_mult using crystal frequency.
>  -Calibration register updating based on crystal frequency in probe.
>  -Supressed MIN an MAX calibration values,Will send separate patch in future.

I believe this should go in with this patch and it shouldn't be too
complicated to know whether the calculated value overflows the register.

> Changes in V2:
>  -Removed unused macro.
>  -Updated code with review comments.
> ---
>  drivers/rtc/rtc-zynqmp.c | 104 +++++++++++++++++++++++++++++++--------
>  1 file changed, 84 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c
> index f440bb52be92..eb6ee55ca725 100644
> --- a/drivers/rtc/rtc-zynqmp.c
> +++ b/drivers/rtc/rtc-zynqmp.c
> @@ -6,6 +6,7 @@
>   *
>   */
>  
> +#include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/io.h>
> @@ -36,17 +37,21 @@
>  #define RTC_OSC_EN		BIT(24)
>  #define RTC_BATT_EN		BIT(31)
>  
> -#define RTC_CALIB_DEF		0x198233
> +#define RTC_CALIB_DEF		0x8000
>  #define RTC_CALIB_MASK		0x1FFFFF
>  #define RTC_ALRM_MASK          BIT(1)
>  #define RTC_MSEC               1000
> +#define RTC_FR_MASK		0xF0000
> +#define RTC_FR_MAX_TICKS	16
> +#define RTC_PPB			1000000000LL
>  
>  struct xlnx_rtc_dev {
>  	struct rtc_device	*rtc;
>  	void __iomem		*reg_base;
>  	int			alarm_irq;
>  	int			sec_irq;
> -	unsigned int		calibval;
> +	struct clk		*rtc_clk;
> +	unsigned int		freq;
>  };
>  
>  static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
> @@ -61,13 +66,6 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
>  	 */
>  	new_time = rtc_tm_to_time64(tm) + 1;
>  
> -	/*
> -	 * Writing into calibration register will clear the Tick Counter and
> -	 * force the next second to be signaled exactly in 1 second period
> -	 */
> -	xrtcdev->calibval &= RTC_CALIB_MASK;
> -	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> -
>  	writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
>  
>  	/*
> @@ -173,15 +171,71 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev)
>  	rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL);
>  	rtc_ctrl |= RTC_BATT_EN;
>  	writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL);
> +}
>  
> -	/*
> -	 * Based on crystal freq of 33.330 KHz
> -	 * set the seconds counter and enable, set fractions counter
> -	 * to default value suggested as per design spec
> -	 * to correct RTC delay in frequency over period of time.
> +static int xlnx_rtc_read_offset(struct device *dev, long *offset)
> +{
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	long offset_val = 0;
> +	unsigned int tick_mult = RTC_PPB / xrtcdev->freq;
> +	unsigned int calibval;
> +
> +	calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD);
> +	/* Offset with seconds ticks */
> +	offset_val = calibval & RTC_TICK_MASK;
> +	offset_val = offset_val - RTC_CALIB_DEF;
> +	offset_val = offset_val * tick_mult;
> +
> +	/* Offset with fractional ticks */
> +	if (calibval & RTC_FR_EN)
> +		offset_val += ((calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT)
> +			* (tick_mult / RTC_FR_MAX_TICKS);
> +	*offset = offset_val;
> +
> +	return 0;
> +}
> +
> +static int xlnx_rtc_set_offset(struct device *dev, long offset)
> +{
> +	struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
> +	short int  max_tick;
> +	unsigned char fract_tick = 0;
> +	unsigned int calibval;
> +	int fract_offset;
> +	unsigned int tick_mult = RTC_PPB / xrtcdev->freq;
> +
> +	/* Number ticks for given offset */
> +	max_tick = div_s64_rem(offset, tick_mult, &fract_offset);
> +
> +	/* Number fractional ticks for given offset */
> +	if (fract_offset) {
> +		if (fract_offset < 0) {
> +			fract_offset = fract_offset + tick_mult;
> +			max_tick--;
> +		}
> +		if (fract_offset > (tick_mult / RTC_FR_MAX_TICKS)) {
> +			for (fract_tick = 1; fract_tick < 16; fract_tick++) {
> +				if (fract_offset <=
> +				    (fract_tick *
> +				     (tick_mult / RTC_FR_MAX_TICKS)))
> +					break;
> +			}
> +		}
> +	}
> +
> +	/* Zynqmp RTC uses second and fractional tick
> +	 * counters for compensation
>  	 */
> -	xrtcdev->calibval &= RTC_CALIB_MASK;
> -	writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +	calibval = max_tick + RTC_CALIB_DEF;
> +
> +	if (fract_tick)
> +		calibval |= RTC_FR_EN;
> +
> +	calibval |= (fract_tick << RTC_FR_DATSHIFT);
> +
> +	writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
> +
> +	return 0;
>  }
>  
>  static const struct rtc_class_ops xlnx_rtc_ops = {
> @@ -190,6 +244,8 @@ static const struct rtc_class_ops xlnx_rtc_ops = {
>  	.read_alarm	  = xlnx_rtc_read_alarm,
>  	.set_alarm	  = xlnx_rtc_set_alarm,
>  	.alarm_irq_enable = xlnx_rtc_alarm_irq_enable,
> +	.read_offset	  = xlnx_rtc_read_offset,
> +	.set_offset	  = xlnx_rtc_set_offset,
>  };
>  
>  static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
> @@ -255,10 +311,18 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = of_property_read_u32(pdev->dev.of_node, "calibration",
> -				   &xrtcdev->calibval);
> -	if (ret)
> -		xrtcdev->calibval = RTC_CALIB_DEF;
> +	/* Getting the rtc_clk info */
> +	xrtcdev->rtc_clk = devm_clk_get_optional(&pdev->dev, "rtc_clk");
> +	if (IS_ERR(xrtcdev->rtc_clk)) {
> +		if (PTR_ERR(xrtcdev->rtc_clk) != -EPROBE_DEFER)
> +			dev_warn(&pdev->dev, "Device clock not found.\n");
> +	}
> +	xrtcdev->freq = clk_get_rate(xrtcdev->rtc_clk);
> +	if (!xrtcdev->freq)
> +		xrtcdev->freq = RTC_CALIB_DEF;

Because you changed the value of RTC_CALIB_DEF, I think this breaks
existing DTs.

> +	ret = readl(xrtcdev->reg_base + RTC_CALIB_RD);
> +	if (!ret)
> +		writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR));
>  
>  	xlnx_init_rtc(xrtcdev);
>  
> -- 
> 2.17.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From alexandre.belloni at bootlin.com  Tue Jan  4 16:05:36 2022
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Wed,  5 Jan 2022 01:05:36 +0100
Subject: [PATCH] rtc: ftrtc010: Use platform_get_irq() to get the interrupt
In-Reply-To: <20211220011524.17206-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20211220011524.17206-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <164134112610.1688528.10619491377155917684.b4-ty@bootlin.com>

On Mon, 20 Dec 2021 01:15:24 +0000, Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> [...]

Applied, thanks!

[1/1] rtc: ftrtc010: Use platform_get_irq() to get the interrupt
      commit: 05020a733b02cf7a474305e620fb306cd3abfe84

Best regards,
-- 
Alexandre Belloni <alexandre.belloni at bootlin.com>


From olof at lixom.net  Tue Jan  4 16:40:34 2022
From: olof at lixom.net (Olof Johansson)
Date: Tue, 4 Jan 2022 16:40:34 -0800
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
 <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
Message-ID: <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>

Hi Florian,

On Tue, Jan 4, 2022 at 1:58 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
>
> On 12/24/21 9:11 AM, Florian Fainelli wrote:
> > Hi Arnd, Olof,
> >
> > On 12/23/2021 13:31, Arnd Bergmann wrote:
> >> I'm sending out the pull requests for 5.17 early, as I won't have
> >> access to
> >> my workstation for the next two weeks. With only 760 non-merge commits,
> >> this again feels quieter than the massive previous merge window, but the
> >> number of changed lines was actually slightly higher.
> >>
> >> There are very few changes aside from devicetree patches, most of
> >> which are for the i.MX, Tegra, Qualcomm, Apple, K3 and Aspeed
> >> platforms.
> >>
> >> We have a couple of new SoCs in existing families:
> >>
> >>   - Qualcomm Snapdragon 8 Gen1
> >>   - Qualcomm Snapdragon SDX65
> >>   - NXP i.MX8ULP
> >>   - Texas Instruments j721s2
> >>   - Renesas R-Car S4-8
> >>
> >> The time between product announcement and kernel support is fairly short
> >> for all of these, which is nice. In particular the two Snapdragons
> >> were only
> >> announced this month and are the current high end of Qualcomm's products.
> >> On the other end of the spectrum, we also add support for ST SPEAr320s,
> >> which was launched 10 years ago.
> >>
> >> Aside from the Arm chips, there is also a pull request for a new
> >> RISC-V SoC,
> >> the Starfive JH7100, including some of the basic drivers to make it boot.
> >
> > There seems to half of the submitted Broadcom SoCs pull request missing
> > in this one, was there issues with those below:
> >
> > defconfigs:
> >
> > https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-1-f.fainelli at gmail.com/
> >
> > https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-2-f.fainelli at gmail.com/
> >
> >
> > drivers:
> >
> > https://lore.kernel.org/linux-arm-kernel/20211221220642.2862218-5-f.fainelli at gmail.com/
> >
> >
> > Should I resend or fix something in those? Thanks!
>
>
> Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
> Thanks and happy new year.

I'm about to make a pass of merges, likely tomorrow -- I had to get my
Honeycomb working again since it hosts all the trees and mailboxes for
me.

No need to resend at this time.


-Olof


From guohanjun at huawei.com  Tue Jan  4 17:34:57 2022
From: guohanjun at huawei.com (Hanjun Guo)
Date: Wed, 5 Jan 2022 09:34:57 +0800
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <20211231033725.21109-3-ilkka@os.amperecomputing.com>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
Message-ID: <f0fecf95-0b7d-eeec-94fd-76bea61fdd0f@huawei.com>

Hi Ilkka,

On 2021/12/31 11:37, Ilkka Koskinen wrote:
> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
> issue diagnostic dump and reset via an SDEI event or an interrupt.
> This patch implements SDEI path.
> 
> [0] https://developer.arm.com/documentation/den0093/latest/
> 
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
>   drivers/acpi/arm64/Kconfig  |   8 +++
>   drivers/acpi/arm64/Makefile |   1 +
>   drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>   3 files changed, 134 insertions(+)
>   create mode 100644 drivers/acpi/arm64/agdi.c
> 
> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
> index 6dba187f4f2e..24869ba5b365 100644
> --- a/drivers/acpi/arm64/Kconfig
> +++ b/drivers/acpi/arm64/Kconfig
> @@ -8,3 +8,11 @@ config ACPI_IORT
>   
>   config ACPI_GTDT
>   	bool
> +
> +config ACPI_AGDI
> +	bool "Arm Generic Diagnostic Dump and Reset Device Interface"
> +	depends on ARM_SDE_INTERFACE
> +	help
> +	  Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
> +	  a standard that enables issuing a non-maskable diagnostic dump and
> +	  reset command.
> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
> index 66acbe77f46e..7b9e4045659d 100644
> --- a/drivers/acpi/arm64/Makefile
> +++ b/drivers/acpi/arm64/Makefile
> @@ -1,4 +1,5 @@
>   # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_ACPI_AGDI) 	+= agdi.o
>   obj-$(CONFIG_ACPI_IORT) 	+= iort.o
>   obj-$(CONFIG_ACPI_GTDT) 	+= gtdt.o
>   obj-y				+= dma.o
> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
> new file mode 100644
> index 000000000000..6525ccbae5c1
> --- /dev/null
> +++ b/drivers/acpi/arm64/agdi.c
> @@ -0,0 +1,125 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * This file implements handling of
> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
> + *
> + * Copyright (c) 2021, Ampere Computing LLC
> + */
> +
> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/acpi.h>
> +#include <linux/arm_sdei.h>
> +#include <linux/io.h>

Please keep the head files in alphabetical order.

> +
> +struct agdi_data {
> +	int sdei_event;
> +};
> +
> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
> +{
> +	nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
> +	return 0;
> +}
> +
> +static int agdi_sdei_probe(struct platform_device *pdev,
> +			   struct agdi_data *adata)
> +{
> +	int err;
> +
> +	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
> +			adata->sdei_event);
> +		return err;
> +	}
> +
> +	err = sdei_event_enable(adata->sdei_event);
> +	if (err)  {
> +		sdei_event_unregister(adata->sdei_event);
> +		dev_err(&pdev->dev, "Failed to enable event %d\n",
> +			adata->sdei_event);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static int agdi_probe(struct platform_device *pdev)
> +{
> +	struct agdi_data *adata;
> +
> +	adata = dev_get_platdata(&pdev->dev);
> +	if (!adata)
> +		return -EINVAL;
> +
> +	return agdi_sdei_probe(pdev, adata);
> +}
> +
> +static int agdi_remove(struct platform_device *pdev)
> +{
> +	struct agdi_data *adata = platform_get_drvdata(pdev);
> +
> +	sdei_event_disable(adata->sdei_event);
> +	sdei_event_unregister(adata->sdei_event);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver agdi_driver = {
> +	.driver = {
> +		.name = "agdi",
> +	},
> +	.probe = agdi_probe,
> +	.remove = agdi_remove,
> +};
> +
> +static int __init agdi_init(void)
> +{
> +	int ret;
> +	acpi_status status;
> +	struct acpi_table_agdi *agdi_table;
> +	struct agdi_data pdata;
> +	struct platform_device *pdev;
> +
> +	if (acpi_disabled)
> +		return 0;
> +
> +	status = acpi_get_table(ACPI_SIG_AGDI, 0,
> +				(struct acpi_table_header **) &agdi_table);
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
> +		pr_warn("Interrupt signaling is not supported");
> +		ret = -ENODEV;
> +		goto err_put_table;
> +	}
> +
> +	pdata.sdei_event = agdi_table->sdei_event;
> +
> +	pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
> +	if (IS_ERR(pdev)) {
> +		ret = PTR_ERR(pdev);
> +		goto err_put_table;
> +	}
> +
> +	ret = platform_driver_register(&agdi_driver);
> +	if (ret)
> +		goto err_device_unregister;
> +
> +	acpi_put_table((struct acpi_table_header *)agdi_table);
> +	return 0;
> +
> +err_device_unregister:
> +	platform_device_unregister(pdev);
> +err_put_table:
> +	acpi_put_table((struct acpi_table_header *)agdi_table);
> +	return ret;
> +}
> +device_initcall(agdi_init);

The rest are looking good to me.

Thanks
Hanjun


From arnd at kernel.org  Tue Jan  4 17:40:43 2022
From: arnd at kernel.org (Arnd Bergmann)
Date: Tue, 4 Jan 2022 20:40:43 -0500
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
 <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
 <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>
Message-ID: <CAK8P3a3sBADt4Cu=LGbjHQpQ32O-BtFk1aQFwhL8Ar=M_gj6Xw@mail.gmail.com>

On Tue, Jan 4, 2022 at 7:40 PM Olof Johansson <olof at lixom.net> wrote:
> On Tue, Jan 4, 2022 at 1:58 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> > On 12/24/21 9:11 AM, Florian Fainelli wrote:
> > >
> > > Should I resend or fix something in those? Thanks!
> >
> >
> > Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
> > Thanks and happy new year.
>
> I'm about to make a pass of merges, likely tomorrow -- I had to get my
> Honeycomb working again since it hosts all the trees and mailboxes for
> me.
>
> No need to resend at this time.

It's possible that I had accidentally merged them in the end but tagged
the branch without those merge commits, so have a look if it's in there.

I'm still traveling, so I have no access to my reflog. I'm sure there was
nothing wrong with the contents, so either they came after I had
tagged the branches, or I made a mistake.

        Arnd


From jkchen at linux.alibaba.com  Tue Jan  4 18:08:02 2022
From: jkchen at linux.alibaba.com (Jay Chen)
Date: Wed,  5 Jan 2022 10:08:02 +0800
Subject: [PATCH] coresight: change tmc from misc device to cdev device
Message-ID: <20220105020802.3732-1-jkchen@linux.alibaba.com>

Currently, there are 130 etr and etf on our machine,
but the current coresight tmc driver uses misc_register
to register the device, which leads to the error that
the device number is not enough.

coresight-tmc: probe of xxxxx failed with error -16

This patch changes the device registration method
to cdev's dynamic registration method to solve the
problem of insufficient device numbers.

Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   | 10 +-
 2 files changed, 83 insertions(+), 18 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index d0276af82494..0d51071e9f88 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -31,6 +31,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+static DEFINE_IDA(tmc_ida);
+static dev_t tmc_major;
+static struct class *tmc_class;
+
+#define TMC_DEV_MAX	(MINORMASK + 1)
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -147,7 +153,7 @@ static int tmc_open(struct inode *inode, struct file *file)
 {
 	int ret;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_prepare(drvdata);
 	if (ret)
@@ -179,7 +185,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 	char *bufp;
 	ssize_t actual;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
 	if (actual <= 0)
 		return 0;
@@ -200,7 +206,7 @@ static int tmc_release(struct inode *inode, struct file *file)
 {
 	int ret;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_unprepare(drvdata);
 	if (ret)
@@ -451,6 +457,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	u32 devid;
+	dev_t devt;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -546,14 +553,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		goto out;
 	}
 
-	drvdata->miscdev.name = desc.name;
-	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
-	drvdata->miscdev.fops = &tmc_fops;
-	ret = misc_register(&drvdata->miscdev);
+	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err_coresight_unregister;
+
+	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
+	drvdata->cdev.cdev.owner = THIS_MODULE;
+	devt = MKDEV(MAJOR(tmc_major), ret);
+	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
 	if (ret)
-		coresight_unregister(drvdata->csdev);
-	else
+		goto err_free_tmc_ida;
+
+	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
+	if (IS_ERR(drvdata->cdev.dev)) {
+		ret = PTR_ERR(drvdata->cdev.dev);
+		goto err_delete_cdev;
+	} else
 		pm_runtime_put(&adev->dev);
+
+	return 0;
+
+err_delete_cdev:
+	cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
+	ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
+	coresight_unregister(drvdata->csdev);
 out:
 	return ret;
 }
@@ -583,13 +608,11 @@ static void tmc_shutdown(struct amba_device *adev)
 static void tmc_remove(struct amba_device *adev)
 {
 	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct device *dev = drvdata->cdev.dev;
 
-	/*
-	 * Since misc_open() holds a refcount on the f_ops, which is
-	 * etb fops in this case, device is there until last file
-	 * handler to this device is closed.
-	 */
-	misc_deregister(&drvdata->miscdev);
+	ida_simple_remove(&tmc_ida, dev->devt);
+	device_destroy(tmc_class, dev->devt);
+	cdev_del(&drvdata->cdev.cdev);
 	coresight_unregister(drvdata->csdev);
 }
 
@@ -618,7 +641,43 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int __init tmc_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
+	if (ret < 0) {
+		pr_err("tmc: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	tmc_class = class_create(THIS_MODULE, "tmc");
+	if (IS_ERR(tmc_class)) {
+		pr_err("tmc: failed to create class\n");
+		ret = PTR_ERR(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+		return ret;
+	}
+
+	ret = amba_driver_register(&tmc_driver);
+	if (ret) {
+		pr_err("tmc: error registering amba driver\n");
+		class_destroy(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+	}
+
+	return ret;
+}
+
+static void __exit tmc_exit(void)
+{
+	amba_driver_unregister(&tmc_driver);
+	class_destroy(tmc_class);
+	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+
+module_init(tmc_init);
+module_exit(tmc_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6bec20a392b3..b65ac363f9e4 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -7,6 +7,7 @@
 #ifndef _CORESIGHT_TMC_H
 #define _CORESIGHT_TMC_H
 
+#include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
 #include <linux/miscdevice.h>
@@ -163,11 +164,16 @@ struct etr_buf {
 	void				*private;
 };
 
+struct tmc_cdev {
+	struct cdev cdev;
+	struct device *dev;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
- * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process being monitored by the session
  *		that is using this component.
@@ -191,7 +197,7 @@ struct etr_buf {
 struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
-	struct miscdevice	miscdev;
+	struct tmc_cdev		cdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
-- 
2.27.0



From jkchen at linux.alibaba.com  Tue Jan  4 18:13:12 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Wed, 5 Jan 2022 10:13:12 +0800
Subject: [PATCH] coresight: change tmc from misc device to cdev device
In-Reply-To: <20220105020802.3732-1-jkchen@linux.alibaba.com>
References: <20220105020802.3732-1-jkchen@linux.alibaba.com>
Message-ID: <a007c395-1803-15a3-464c-9ba4ca9e558f@linux.alibaba.com>


Sorry, please ignore. This patch was sent incorrectly. I will resend it

? 2022/1/5 10:08, Jay Chen ??:
> Currently, there are 130 etr and etf on our machine,
> but the current coresight tmc driver uses misc_register
> to register the device, which leads to the error that
> the device number is not enough.
>
> coresight-tmc: probe of xxxxx failed with error -16
>
> This patch changes the device registration method
> to cdev's dynamic registration method to solve the
> problem of insufficient device numbers.
>
> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> ---
>   .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
>   drivers/hwtracing/coresight/coresight-tmc.h   | 10 +-
>   2 files changed, 83 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index d0276af82494..0d51071e9f88 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -31,6 +31,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>   
> +static DEFINE_IDA(tmc_ida);
> +static dev_t tmc_major;
> +static struct class *tmc_class;
> +
> +#define TMC_DEV_MAX	(MINORMASK + 1)
> +
>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>   {
>   	struct coresight_device *csdev = drvdata->csdev;
> @@ -147,7 +153,7 @@ static int tmc_open(struct inode *inode, struct file *file)
>   {
>   	int ret;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>   
>   	ret = tmc_read_prepare(drvdata);
>   	if (ret)
> @@ -179,7 +185,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>   	char *bufp;
>   	ssize_t actual;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>   	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>   	if (actual <= 0)
>   		return 0;
> @@ -200,7 +206,7 @@ static int tmc_release(struct inode *inode, struct file *file)
>   {
>   	int ret;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>   
>   	ret = tmc_read_unprepare(drvdata);
>   	if (ret)
> @@ -451,6 +457,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   {
>   	int ret = 0;
>   	u32 devid;
> +	dev_t devt;
>   	void __iomem *base;
>   	struct device *dev = &adev->dev;
>   	struct coresight_platform_data *pdata = NULL;
> @@ -546,14 +553,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   		goto out;
>   	}
>   
> -	drvdata->miscdev.name = desc.name;
> -	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> -	drvdata->miscdev.fops = &tmc_fops;
> -	ret = misc_register(&drvdata->miscdev);
> +	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> +	if (ret < 0)
> +		goto err_coresight_unregister;
> +
> +	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> +	drvdata->cdev.cdev.owner = THIS_MODULE;
> +	devt = MKDEV(MAJOR(tmc_major), ret);
> +	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>   	if (ret)
> -		coresight_unregister(drvdata->csdev);
> -	else
> +		goto err_free_tmc_ida;
> +
> +	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> +	if (IS_ERR(drvdata->cdev.dev)) {
> +		ret = PTR_ERR(drvdata->cdev.dev);
> +		goto err_delete_cdev;
> +	} else
>   		pm_runtime_put(&adev->dev);
> +
> +	return 0;
> +
> +err_delete_cdev:
> +	cdev_del(&drvdata->cdev.cdev);
> +err_free_tmc_ida:
> +	ida_simple_remove(&tmc_ida, MINOR(devt));
> +err_coresight_unregister:
> +	coresight_unregister(drvdata->csdev);
>   out:
>   	return ret;
>   }
> @@ -583,13 +608,11 @@ static void tmc_shutdown(struct amba_device *adev)
>   static void tmc_remove(struct amba_device *adev)
>   {
>   	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +	struct device *dev = drvdata->cdev.dev;
>   
> -	/*
> -	 * Since misc_open() holds a refcount on the f_ops, which is
> -	 * etb fops in this case, device is there until last file
> -	 * handler to this device is closed.
> -	 */
> -	misc_deregister(&drvdata->miscdev);
> +	ida_simple_remove(&tmc_ida, dev->devt);
> +	device_destroy(tmc_class, dev->devt);
> +	cdev_del(&drvdata->cdev.cdev);
>   	coresight_unregister(drvdata->csdev);
>   }
>   
> @@ -618,7 +641,43 @@ static struct amba_driver tmc_driver = {
>   	.id_table	= tmc_ids,
>   };
>   
> -module_amba_driver(tmc_driver);
> +static int __init tmc_init(void)
> +{
> +	int ret;
> +
> +	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> +	if (ret < 0) {
> +		pr_err("tmc: failed to allocate char dev region\n");
> +		return ret;
> +	}
> +
> +	tmc_class = class_create(THIS_MODULE, "tmc");
> +	if (IS_ERR(tmc_class)) {
> +		pr_err("tmc: failed to create class\n");
> +		ret = PTR_ERR(tmc_class);
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +		return ret;
> +	}
> +
> +	ret = amba_driver_register(&tmc_driver);
> +	if (ret) {
> +		pr_err("tmc: error registering amba driver\n");
> +		class_destroy(tmc_class);
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +	}
> +
> +	return ret;
> +}
> +
> +static void __exit tmc_exit(void)
> +{
> +	amba_driver_unregister(&tmc_driver);
> +	class_destroy(tmc_class);
> +	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +}
> +
> +module_init(tmc_init);
> +module_exit(tmc_exit);
>   
>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6bec20a392b3..b65ac363f9e4 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -7,6 +7,7 @@
>   #ifndef _CORESIGHT_TMC_H
>   #define _CORESIGHT_TMC_H
>   
> +#include <linux/cdev.h>
>   #include <linux/dma-mapping.h>
>   #include <linux/idr.h>
>   #include <linux/miscdevice.h>
> @@ -163,11 +164,16 @@ struct etr_buf {
>   	void				*private;
>   };
>   
> +struct tmc_cdev {
> +	struct cdev cdev;
> +	struct device *dev;
> +};
> +
>   /**
>    * struct tmc_drvdata - specifics associated to an TMC component
>    * @base:	memory mapped base address for this component.
>    * @csdev:	component vitals needed by the framework.
> - * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
> + * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
>    * @spinlock:	only one at a time pls.
>    * @pid:	Process ID of the process being monitored by the session
>    *		that is using this component.
> @@ -191,7 +197,7 @@ struct etr_buf {
>   struct tmc_drvdata {
>   	void __iomem		*base;
>   	struct coresight_device	*csdev;
> -	struct miscdevice	miscdev;
> +	struct tmc_cdev		cdev;
>   	spinlock_t		spinlock;
>   	pid_t			pid;
>   	bool			reading;


From jkchen at linux.alibaba.com  Tue Jan  4 18:16:31 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Wed, 5 Jan 2022 10:16:31 +0800
Subject: [RFC V3 PATCH] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <20220103182848.GA398730@p14s>
References: <20211221120437.4781-1-jkchen@linux.alibaba.com>
 <20220103182848.GA398730@p14s>
Message-ID: <0ce54a1d-294e-26da-27a9-14fb6eda0560@linux.alibaba.com>

Hi Mathieu:

 ?I will resend the patch again

tks

jay

? 2022/1/4 02:28, Mathieu Poirier ??:
> Good day Jay,
>
> For your next iteration, please remove the "RFC" from the patch title, we are
> well pass that now.
>
> On Tue, Dec 21, 2021 at 08:04:37PM +0800, Jay Chen wrote:
>> Currently, there are 130 etr and etf on our machine,
>> but the current coresight tmc driver uses misc_register
>> to register the device, which leads to the error that
>> the device number is not enough.
>>
>> coresight-tmc: probe of xxxxx failed with error -16
>>
>> This patch changes the device registration method
>> to cdev's dynamic registration method to solve the
>> problem of insufficient device numbers.
> This is much better.
>
>> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
>> ---
>>   .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
>>   drivers/hwtracing/coresight/coresight-tmc.h   | 10 +-
>>   2 files changed, 83 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> index d0276af82494..0d51071e9f88 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> @@ -31,6 +31,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>>   
>> +static DEFINE_IDA(tmc_ida);
>> +static dev_t tmc_major;
>> +static struct class *tmc_class;
>> +
>> +#define TMC_DEV_MAX	(MINORMASK + 1)
>> +
>>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>>   {
>>   	struct coresight_device *csdev = drvdata->csdev;
>> @@ -147,7 +153,7 @@ static int tmc_open(struct inode *inode, struct file *file)
>>   {
>>   	int ret;
>>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -						   struct tmc_drvdata, miscdev);
>> +						   struct tmc_drvdata, cdev);
>>   
>>   	ret = tmc_read_prepare(drvdata);
>>   	if (ret)
>> @@ -179,7 +185,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>   	char *bufp;
>>   	ssize_t actual;
>>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -						   struct tmc_drvdata, miscdev);
>> +						   struct tmc_drvdata, cdev);
>>   	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>>   	if (actual <= 0)
>>   		return 0;
>> @@ -200,7 +206,7 @@ static int tmc_release(struct inode *inode, struct file *file)
>>   {
>>   	int ret;
>>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -						   struct tmc_drvdata, miscdev);
>> +						   struct tmc_drvdata, cdev);
>>   
>>   	ret = tmc_read_unprepare(drvdata);
>>   	if (ret)
>> @@ -451,6 +457,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>   {
>>   	int ret = 0;
>>   	u32 devid;
>> +	dev_t devt;
>>   	void __iomem *base;
>>   	struct device *dev = &adev->dev;
>>   	struct coresight_platform_data *pdata = NULL;
>> @@ -546,14 +553,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>   		goto out;
>>   	}
>>   
>> -	drvdata->miscdev.name = desc.name;
>> -	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>> -	drvdata->miscdev.fops = &tmc_fops;
>> -	ret = misc_register(&drvdata->miscdev);
>> +	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
>> +	if (ret < 0)
>> +		goto err_coresight_unregister;
>> +
>> +	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
>> +	drvdata->cdev.cdev.owner = THIS_MODULE;
>> +	devt = MKDEV(MAJOR(tmc_major), ret);
>> +	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>>   	if (ret)
>> -		coresight_unregister(drvdata->csdev);
>> -	else
>> +		goto err_free_tmc_ida;
>> +
>> +	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
>> +	if (IS_ERR(drvdata->cdev.dev)) {
>> +		ret = PTR_ERR(drvdata->cdev.dev);
>> +		goto err_delete_cdev;
>> +	} else
>>   		pm_runtime_put(&adev->dev);
>> +
>> +	return 0;
>> +
>> +err_delete_cdev:
>> +	cdev_del(&drvdata->cdev.cdev);
>> +err_free_tmc_ida:
>> +	ida_simple_remove(&tmc_ida, MINOR(devt));
>> +err_coresight_unregister:
>> +	coresight_unregister(drvdata->csdev);
>>   out:
>>   	return ret;
>>   }
>> @@ -583,13 +608,11 @@ static void tmc_shutdown(struct amba_device *adev)
>>   static void tmc_remove(struct amba_device *adev)
>>   {
>>   	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>> +	struct device *dev = drvdata->cdev.dev;
>>   
>> -	/*
>> -	 * Since misc_open() holds a refcount on the f_ops, which is
>> -	 * etb fops in this case, device is there until last file
>> -	 * handler to this device is closed.
>> -	 */
>> -	misc_deregister(&drvdata->miscdev);
>> +	ida_simple_remove(&tmc_ida, dev->devt);
> 	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
>
>> +	device_destroy(tmc_class, dev->devt);
>> +	cdev_del(&drvdata->cdev.cdev);
>>   	coresight_unregister(drvdata->csdev);
>>   }
>>   
>> @@ -618,7 +641,43 @@ static struct amba_driver tmc_driver = {
>>   	.id_table	= tmc_ids,
>>   };
>>   
>> -module_amba_driver(tmc_driver);
>> +static int __init tmc_init(void)
>> +{
>> +	int ret;
>> +
>> +	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
>> +	if (ret < 0) {
>> +		pr_err("tmc: failed to allocate char dev region\n");
>> +		return ret;
>> +	}
>> +
>> +	tmc_class = class_create(THIS_MODULE, "tmc");
>> +	if (IS_ERR(tmc_class)) {
>> +		pr_err("tmc: failed to create class\n");
>> +		ret = PTR_ERR(tmc_class);
>> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +		return ret;
> You can simply return PTR_ERR(tmc_class)...
>
>> +	}
>> +
>> +	ret = amba_driver_register(&tmc_driver);
>> +	if (ret) {
>> +		pr_err("tmc: error registering amba driver\n");
>> +		class_destroy(tmc_class);
>> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +	}
>> +
>> +	return ret;
>> +}
>> +
>> +static void __exit tmc_exit(void)
>> +{
>> +	amba_driver_unregister(&tmc_driver);
>> +	class_destroy(tmc_class);
>> +	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +}
>> +
>> +module_init(tmc_init);
>> +module_exit(tmc_exit);
>>   
>>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
>> index 6bec20a392b3..b65ac363f9e4 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc.h
>> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
>> @@ -7,6 +7,7 @@
>>   #ifndef _CORESIGHT_TMC_H
>>   #define _CORESIGHT_TMC_H
>>   
>> +#include <linux/cdev.h>
>>   #include <linux/dma-mapping.h>
>>   #include <linux/idr.h>
>>   #include <linux/miscdevice.h>
> miscdevice.h can likely be removed in both .c and .h files.
>
> Thanks,
> Mathieu
>
>> @@ -163,11 +164,16 @@ struct etr_buf {
>>   	void				*private;
>>   };
>>   
>> +struct tmc_cdev {
>> +	struct cdev cdev;
>> +	struct device *dev;
>> +};
>> +
>>   /**
>>    * struct tmc_drvdata - specifics associated to an TMC component
>>    * @base:	memory mapped base address for this component.
>>    * @csdev:	component vitals needed by the framework.
>> - * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
>> + * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
>>    * @spinlock:	only one at a time pls.
>>    * @pid:	Process ID of the process being monitored by the session
>>    *		that is using this component.
>> @@ -191,7 +197,7 @@ struct etr_buf {
>>   struct tmc_drvdata {
>>   	void __iomem		*base;
>>   	struct coresight_device	*csdev;
>> -	struct miscdevice	miscdev;
>> +	struct tmc_cdev		cdev;
>>   	spinlock_t		spinlock;
>>   	pid_t			pid;
>>   	bool			reading;
>> -- 
>> 2.27.0
>>


From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:20 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:20 +0800
Subject: [PATCH v2 1/7] dt-bindings: timer: Add compatible for Mediatek MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of timer for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index e5c57d6e0186..e0d20d6adf81 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -22,6 +22,7 @@ Required properties:
 
 	For those SoCs that use SYST
 	* "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
+	* "mediatek,mt8186-timer" for MT8186 compatible timers (SYST)
 	* "mediatek,mt8192-timer" for MT8192 compatible timers (SYST)
 	* "mediatek,mt8195-timer" for MT8195 compatible timers (SYST)
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:19 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:19 +0800
Subject: [PATCH v2 0/7] Add basic node support for Mediatek MT8186 SoC
Message-ID: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

MT8186 is a SoC based on 64bit ARMv8 architecture.
It contains 6 CA55 and 2 CA78 cores.
MT8186 share many HW IP with MT65xx series.

This patchset was tested on MT8186 evaluation board to shell.

Based on v5.16-rc8

changes since v1:
 - add dt-bindings: arm: Add compatible for Mediatek MT8186

Allen-KH Cheng (7):
  dt-bindings: timer: Add compatible for Mediatek MT8186
  dt-bindings: serial: Add compatible for Mediatek MT8186
  dt-bindings: watchdog: Add compatible for Mediatek MT8186
  dt-bindings: mmc: Add compatible for Mediatek MT8186
  dt-bindings: phy: Add compatible for Mediatek MT8186
  dt-bindings: arm: Add compatible for Mediatek MT8186
  arm64: dts: Add Mediatek SoC MT8186 dts and evaluation board and
    Makefile

 .../devicetree/bindings/arm/mediatek.yaml     |   4 +
 .../devicetree/bindings/mmc/mtk-sd.yaml       |   3 +
 .../bindings/phy/mediatek,tphy.yaml           |   1 +
 .../devicetree/bindings/serial/mtk-uart.txt   |   1 +
 .../bindings/timer/mediatek,mtk-timer.txt     |   1 +
 .../devicetree/bindings/watchdog/mtk-wdt.txt  |   1 +
 arch/arm64/boot/dts/mediatek/Makefile         |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts   |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi      | 352 ++++++++++++++++++
 9 files changed, 388 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:22 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:22 +0800
Subject: [PATCH v2 3/7] dt-bindings: watchdog: Add compatible for Mediatek
 MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of watchdog for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 0114871f887a..74db01e3658b 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -15,6 +15,7 @@ Required properties:
 	"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
 	"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
 	"mediatek,mt8183-wdt": for MT8183
+	"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
 	"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
 	"mediatek,mt8192-wdt": for MT8192
 	"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:24 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:24 +0800
Subject: [PATCH v2 5/7] dt-bindings: phy: Add compatible for Mediatek MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of T-Phy for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 9e6c0f43f1c6..cadbc696b3f5 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -80,6 +80,7 @@ properties:
               - mediatek,mt2712-tphy
               - mediatek,mt7629-tphy
               - mediatek,mt8183-tphy
+              - mediatek,mt8186-tphy
           - const: mediatek,generic-tphy-v2
       - items:
           - enum:
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:23 +0800
Subject: [PATCH v2 4/7] dt-bindings: mmc: Add compatible for Mediatek MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of mmc for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index 82768a807294..164df702482f 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -29,6 +29,9 @@ properties:
       - items:
           - const: mediatek,mt7623-mmc
           - const: mediatek,mt2701-mmc
+      - items:
+          - const: mediatek,mt8186-mmc
+          - const: mediatek,mt8183-mmc
       - items:
           - const: mediatek,mt8192-mmc
           - const: mediatek,mt8183-mmc
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:25 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:25 +0800
Subject: [PATCH v2 6/7] dt-bindings: arm: Add compatible for Mediatek MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-7-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation for the Mediatek MT8186
reference board.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 0fa55497b96f..8fd78bd9931c 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -119,6 +119,10 @@ properties:
           - enum:
               - mediatek,mt8183-evb
           - const: mediatek,mt8183
+      - items:
+          - enum:
+              - mediatek,mt8186-evb
+          - const: mediatek,mt8186
       - items:
           - enum:
               - mediatek,mt8195-evb
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:26 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:26 +0800
Subject: [PATCH v2 7/7] arm64: dts: Add Mediatek SoC MT8186 dts and evaluation
 board and Makefile
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-8-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add basic chip support for Mediatek MT8186

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi    | 352 ++++++++++++++++++++
 3 files changed, 377 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 4f68ebed2e31..2271c3452c64 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -31,5 +31,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
new file mode 100644
index 000000000000..eb23d1f19f87
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+#include "mt8186.dtsi"
+
+/ {
+	model = "MediaTek MT8186 evaluation board";
+	compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
new file mode 100644
index 000000000000..fce84c341291
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+
+/ {
+	compatible = "mediatek,mt8186";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0000>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu1: cpu at 001 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0100>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu2: cpu at 002 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0200>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu3: cpu at 003 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0300>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu4: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0400>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu5: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0500>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu6: cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0600>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu7: cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0700>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+				
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+
+				core4 {
+					cpu = <&cpu4>;
+				};
+
+				core5 {
+					cpu = <&cpu5>;
+				};
+
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu6>;
+				};
+
+				core1 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpuoff_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1600>;
+			};
+
+			cpuoff_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1400>;
+			};
+
+			clusteroff_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <2100>;
+			};
+
+			clusteroff_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <1900>;
+			};
+
+			mcusysoff: mcusys-off {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <300>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2600>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+	};
+
+	psci {
+		compatible      = "arm,psci-1.0";
+		method          = "smc";
+	};
+
+	gic: interrupt-controller {
+		compatible = "arm,gic-v3";
+		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+		#redistributor-regions = <1>;
+		interrupt-parent = <&gic>;
+		interrupt-controller;
+		reg = <0 0x0c000000 0 0x40000>, // distributor
+		      <0 0x0c040000 0 0x200000>; // redistributor
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	watchdog: watchdog at 10007000 {
+		compatible = "mediatek,mt8186-wdt",
+				"mediatek,mt6589-wdt";
+		reg = <0 0x10007000 0 0x1000>;
+	};
+
+	sys_timer at 10017000 {
+		compatible = "mediatek,mt8186_timer",
+			     "mediatek,mt6765-timer";
+		reg = <0 0x10017000 0 0x1000>;
+		interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>;
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+				<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		clock-frequency = <13000000>;
+	};
+
+	uart0: serial at 11002000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11002000 0 0x1000>;
+		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+	};
+
+	uart1: serial at 11003000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11003000 0 0x1000>;
+		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	uart2: serial at 11018000 {
+		compatible = "mediatek,mt8186-uart",
+			     "mediatek,mt6577-uart";
+		reg = <0 0x11018000 0 0x1000>;
+		interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>, <&clk26m>;
+		clock-names = "baud", "bus";
+		status = "disabled";
+	};
+
+	mmc0: mmc at 11230000 {
+		compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
+		reg = <0 0x11230000 0 0x1000>,
+		      <0 0x11cd0000 0 0x1000>;
+		interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>;
+		clock-names = "source", "hclk", "source_cg",
+			      "ahb_clk";
+		status = "disabled";
+	};
+
+	mmc1: mmc at 11240000 {
+		compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
+		reg = <0 0x11240000 0 0x1000>,
+		      <0 0x11c90000 0 0x1000>;
+		interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&clk26m>,
+			 <&clk26m>,
+			 <&clk26m>;
+		clock-names = "source", "hclk", "source_cg";
+		status = "disabled";
+	};
+
+	u3phy1: usb-phy1 at 11c80000 {
+		compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "okay";
+
+		u2port1: usb2-phy1 at 11c80000 {
+			reg = <0 0x11c80000 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+
+		u3port1: usb3-phy1 at 11c80900 {
+			reg = <0 0x11c80900 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			status = "okay";
+		};
+	};
+
+	u3phy0: usb-phy at 11ca0000 {
+		compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		status = "okay";
+
+		u2port0: usb2-phy at 11ca0000 {
+			reg = <0 0x11ca0000 0 0x700>;
+			clocks = <&clk26m>;
+			clock-names = "ref";
+			#phy-cells = <1>;
+			mediatek,discth = <0x8>;
+			status = "okay";
+		};
+	};
+};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Tue Jan  4 18:27:21 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 10:27:21 +0800
Subject: [PATCH v2 2/7] dt-bindings: serial: Add compatible for Mediatek MT8186
In-Reply-To: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105022726.2458-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of uart for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index b3a0bfef0d54..113b5d6a2245 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -20,6 +20,7 @@ Required properties:
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
   * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
+  * "mediatek,mt8186-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
   * "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS
   * "mediatek,mt8195-uart", "mediatek,mt6577-uart" for MT8195 compatible UARTS
   * "mediatek,mt8516-uart" for MT8516 compatible UARTS
-- 
2.18.0



From jkchen at linux.alibaba.com  Tue Jan  4 18:38:31 2022
From: jkchen at linux.alibaba.com (Jay Chen)
Date: Wed,  5 Jan 2022 10:38:31 +0800
Subject: [RESEND PATCH] coresight: change tmc from misc device to cdev device
Message-ID: <20220105023832.4729-1-jkchen@linux.alibaba.com>

Currently, there are 130 etr and etf on our machine,
but the current coresight tmc driver uses misc_register
to register the device, which leads to the error that
the device number is not enough.

coresight-tmc: probe of xxxxx failed with error -16

This patch changes the device registration method
to cdev's dynamic registration method to solve the
problem of insufficient device numbers.

Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   | 11 ++-
 2 files changed, 82 insertions(+), 20 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index d0276af82494..55a131c059fe 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -12,7 +12,6 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
@@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+static DEFINE_IDA(tmc_ida);
+static dev_t tmc_major;
+static struct class *tmc_class;
+
+#define TMC_DEV_MAX	(MINORMASK + 1)
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -147,7 +152,7 @@ static int tmc_open(struct inode *inode, struct file *file)
 {
 	int ret;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_prepare(drvdata);
 	if (ret)
@@ -179,7 +184,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 	char *bufp;
 	ssize_t actual;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
 	if (actual <= 0)
 		return 0;
@@ -200,7 +205,7 @@ static int tmc_release(struct inode *inode, struct file *file)
 {
 	int ret;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_unprepare(drvdata);
 	if (ret)
@@ -451,6 +456,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	u32 devid;
+	dev_t devt;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -546,14 +552,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		goto out;
 	}
 
-	drvdata->miscdev.name = desc.name;
-	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
-	drvdata->miscdev.fops = &tmc_fops;
-	ret = misc_register(&drvdata->miscdev);
+	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err_coresight_unregister;
+
+	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
+	drvdata->cdev.cdev.owner = THIS_MODULE;
+	devt = MKDEV(MAJOR(tmc_major), ret);
+	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
 	if (ret)
-		coresight_unregister(drvdata->csdev);
-	else
+		goto err_free_tmc_ida;
+
+	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
+	if (IS_ERR(drvdata->cdev.dev)) {
+		ret = PTR_ERR(drvdata->cdev.dev);
+		goto err_delete_cdev;
+	} else
 		pm_runtime_put(&adev->dev);
+
+	return 0;
+
+err_delete_cdev:
+	cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
+	ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
+	coresight_unregister(drvdata->csdev);
 out:
 	return ret;
 }
@@ -583,13 +607,11 @@ static void tmc_shutdown(struct amba_device *adev)
 static void tmc_remove(struct amba_device *adev)
 {
 	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct device *dev = drvdata->cdev.dev;
 
-	/*
-	 * Since misc_open() holds a refcount on the f_ops, which is
-	 * etb fops in this case, device is there until last file
-	 * handler to this device is closed.
-	 */
-	misc_deregister(&drvdata->miscdev);
+	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
+	device_destroy(tmc_class, dev->devt);
+	cdev_del(&drvdata->cdev.cdev);
 	coresight_unregister(drvdata->csdev);
 }
 
@@ -618,7 +640,42 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int __init tmc_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
+	if (ret < 0) {
+		pr_err("tmc: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	tmc_class = class_create(THIS_MODULE, "tmc");
+	if (IS_ERR(tmc_class)) {
+		pr_err("tmc: failed to create class\n");
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+		return PTR_ERR(tmc_class);
+	}
+
+	ret = amba_driver_register(&tmc_driver);
+	if (ret) {
+		pr_err("tmc: error registering amba driver\n");
+		class_destroy(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+	}
+
+	return ret;
+}
+
+static void __exit tmc_exit(void)
+{
+	amba_driver_unregister(&tmc_driver);
+	class_destroy(tmc_class);
+	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+
+module_init(tmc_init);
+module_exit(tmc_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6bec20a392b3..11441c6b9c26 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -7,9 +7,9 @@
 #ifndef _CORESIGHT_TMC_H
 #define _CORESIGHT_TMC_H
 
+#include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 
@@ -163,11 +163,16 @@ struct etr_buf {
 	void				*private;
 };
 
+struct tmc_cdev {
+	struct cdev cdev;
+	struct device *dev;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
- * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process being monitored by the session
  *		that is using this component.
@@ -191,7 +196,7 @@ struct etr_buf {
 struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
-	struct miscdevice	miscdev;
+	struct tmc_cdev		cdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
-- 
2.27.0



From szhai2 at cs.rochester.edu  Tue Jan  4 18:44:23 2022
From: szhai2 at cs.rochester.edu (Shuang Zhai)
Date: Tue,  4 Jan 2022 21:44:23 -0500
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220105024423.26409-1-szhai2@cs.rochester.edu>

Fio / pmem benchmark with MGLRU

TLDR
====
With the MGLRU, fio achieved 95% CIs [38.95, 40.26]%, [4.12, 6.64]%
and [9.26, 10.36]% higher throughput, respectively, for random
access, Zipfian (distribution) access and Gaussian (distribution)
access, when the average number of jobs per CPU is 1; 95% CIs
[42.32, 49.15]%, [9.44, 9.89]% and [20.99, 22.86]% higher throughput,
respectively, for random access, Zipfian access and Gaussian access,
when the average number of jobs per CPU is 2.

Background
==========
Many applications running on warehouse-scale computers heavily use
POSIX read(2)/write(2) and page cache, e.g., Apache Kafka, a
distributed streaming application used by "more than 80% of all
Fortune 100 companies" [1] and PostgreSQL, "the world's most advanced
open source relational database" [2].

Intel DC Persistent Memory, as an affordable alternative to DRAM, can
deliver large capacity and data persistence. Specifically, the device
used in this benchmark can achieve up to 36 GiB/s and 15 GiB/s
throughput, respectively, for sequential and random read access.

Our research group at the University of Rochester focuses on the
intersection of computer architecture and system software. My current
research interest is memory management on tiered memory systems.

Matrix
======
Kernels: version [+ patchset]
* Baseline: 5.15
* Patched: 5.15 + MGLRU

Access patterns (4KB read):
* Random (uniform)
* Zipfian (theta 0.8; the recommended range is 0-2)
* Gaussian (deviation 40; the possible range is 0-100)

Concurrency conditions (the average number of jobs per CPU):
* 1
* 2

Total file size (GB): 400 (~2x memory capacity)
Total configurations: 12
Data points per configuration: 10
Total run duration (minutes) per data point: ~30

Notes
-----
1. All files were stored on pmem. Each job had the exclusive access to
   a single file.
2. Due to the hardware limitation when accessing remote pmem [3],
   numactl was used to bind the fio processes to the local pmem. Only
   one of the two NUMA nodes was used during the benchmark.
3. During dry runs, we observed that the throughput doesn't improve
   beyond 2 jobs per CPU for random access. Moreover, the patched
   kernel showed consistent improvements over the baseline kernel
   when using 3 or 4 jobs per CPU.
4. We wanted to simulate the real-world scenarios and therefore used
   default swap configuration (on). Moreover, we didn't observe any
   negative impact on performance with dry runs that disabled swap.

Procedure
=========
<for each kernel>
    grub2-reboot <baseline, patched>
    <for each concurrency condition>
        <generate test files>
        <for each access pattern>
            <for each data point>
                <reboot>
                <run fio>

Hardware
--------
Memory (GiB per socket): 192
CPU (# per socket): 40
Pmem (GiB per socket): 768

Fio
---
$ fio -version
fio-3.28

$ numactl --cpubind=0 --membind=0 fio --name=randread \
  --directory=/mnt/pmem/ --size={10G, 5G} --io_size=1000TB \
  --time_based --numjobs={40, 80} --ioengine=io_uring \
  --ramp_time=20m --runtime=10m --iodepth=128 \
  --iodepth_batch_submit=32 --iodepth_batch_complete=32 \
  --rw=randread --random_distribution={random, zipf:0.8, normal:40} \
  --direct=0 --norandommap --group_reporting

Results
=======
Throughput
----------
The patched kernel achieved substantially higher throughput for all
three access patterns and two concurrency conditions. Specifically,
comparing the patched with the baseline kernel, fio achieved 95% CIs
[38.95, 40.26]%, [4.12, 6.64]% and [9.26, 10.36]% higher throughput,
respectively, for random access, Zipfian access, and Gaussian access,
when the average number of jobs per CPU is 1; 95% CIs [42.32, 49.15]%,
[9.44, 9.89]% and [20.99, 22.86]% higher throughput, respectively, for
random access, Zipfian access and Gaussian access, when the average
number of jobs per CPU is 2.

+---------------------+---------------+---------------+
| Mean MiB/s [95% CI] | 1 job / CPU   | 2 jobs / CPU  |
+---------------------+---------------+---------------+
| Random access       | 8411 / 11742  | 8417 / 12267  |
|                     | [3275, 3387]  | [3562, 4137]  |
+---------------------+---------------+---------------+
| Zipfian access      | 14576 / 15360 | 12932 / 14181 |
|                     | [600, 967]    | [1220, 1279]  |
+---------------------+---------------+---------------+
| Gaussian access     | 14564 / 15993 | 11513 / 14037 |
|                     | [1348, 1508]  | [2417, 2631]  |
+---------------------+---------------+---------------+
Table 1. Throughput comparison between the baseline and the patched
         kernels

The patched kernel exhibited less degradation in throughput when
running more concurrent jobs. Comparing 2 jobs per CPU with 1 job per
CPU, fio achieved 95% CIs [-11.54, -11.02]%, [-16.91, -12.01]% and
[-21.61, -20.30]% higher throughput, respectively, for random access,
Zipfian access and Gaussian access, when using the baseline kernel;
95% CIs [2.04, 6.92]%, [-8.86, -6.48]% and [-12.83, -11.64]% higher
throughput, respectively, for random access, Zipfian access and
Gaussian access, when using the patched kernel. There were no
statistically significant changes in throughput for the rest of the
test matrix.

+---------------------+-----------------+----------------+
| Mean MiB/s [95% CI] | Baseline kernel | Patched kernel |
+---------------------+-----------------+----------------+
| Random access       | 8411 / 8417     | 11741 / 12267  |
|                     | [-55, 69]       | [239, 812]     |
+---------------------+-----------------+----------------+
| Zipfian access      | 14576 / 12932   | 15360/ 14181   |
|                     | [-1682, -1607]  | [-1361, -996]  |
+---------------------+-----------------+----------------+
| Gaussian access     | 14565 / 11513   | 15993 / 14037  |
|                     | [-3147, -2957]  | [-2051, -1861] |
+---------------------+-----------------+----------------+
Table 2. Throughput comparison between 1 job per CPU and 2 jobs per
         CPU

Tail Latency
------------
Comparing the patched with the baseline kernel, fio experienced 95%
CIs [-41.77, -40.35]% and [6.64, 13.95]% higher latency at the 99th
percentile, respectively, for random access and Gaussian access, when
the average number of jobs per CPU is 1; 95% CIs [-41.97, -40.59]%,
[-47.74, -47.04]% and [-51.32, -50.27]% higher latency at the 99th
percentile, respectively, for random access, Zipfian access and
Gaussian access, when the average number of jobs per CPU is 2. There
were no statistically significant changes in latency at the 99th
percentile for the rest of the test matrix.

+------------------------------+----------------+------------------+
| 99th percentile latency (us) | 1 job / CPU    | 2 jobs / CPU     |
+------------------------------+----------------+------------------+
| Random access                | 12466 / 7347   | 25560 / 15008    |
|                              | [-5207, -5030] | [-10729, -10375] |
+------------------------------+----------------+------------------+
| Zipfian access               | 3395 / 3382    | 14563 / 7661     |
|                              | [-131, 105]    | [-6953,-6850]    |
+------------------------------+----------------+------------------+
| Gaussian access              | 3280 / 3618    | 15611 / 7681     |
|                              | [217, 457]     | [-8012, -7848]   |
+------------------------------+----------------+------------------+
Table 3. Comparison of the 99th percentile latency between the
         baseline and the patched kernels (lower is better)

Metrics collected during each run are available at:
https://github.com/zhaishuang1/MglruPerf/tree/master

A peek at 5.16-rc6
------------------
We also ran the benchmark on 5.16-rc6 with swap off. However, we
haven't collected enough data points to establish a 95% CI. Here are
a few numbers we've collected:

+----------------+------------+----------+----------------+----------+
| Access pattern | Jobs / CPU | 5.16-rc6 | 5.16-rc6-mglru | % change |
+----------------+------------+----------+----------------+----------+
| Random access  | 1          | 7467     | 10440          | 39.8%    |
+----------------+------------+----------+----------------+----------+
| Random access  | 2          | 7504     | 13417          | 78.8%    |
+----------------+------------+----------+----------------+----------+
| Random access  | 3          | 7511     | 13954          | 85.8%    |
+----------------+------------+----------+----------------+----------+
| Random access  | 4          | 7542     | 13925          | 84.6%    |
+----------------+------------+----------+----------------+----------+

Reference
=========
[1] https://kafka.apache.org/documentation/#design_filesystem
[2] https://www.postgresql.org/docs/11/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-MEMORY
[3] System Evaluation of the Intel Optane byte-addressable NVM, MEMSYS 2019.

Appendix
========
Throughput
----------
$ cat raw_data_fio.r
v <- c(
    # baseline 40 procs random
    8467.89, 8428.34, 8383.32, 8253.12, 8464.65, 8307.42, 8424.78, 8434.44, 8474.88, 8468.26,
    # baseline 40 procs zipf
    14570.44, 14598.03, 14550.74, 14640.29, 14591.4, 14573.35, 14503.18, 14613.39, 14598.61, 14522.27,
    # baseline 40 procs gaussian
    14504.95, 14427.23, 14652.19, 14519.47, 14557.97, 14617.92, 14555.87, 14446.94, 14678.12, 14688.33,
    # baseline 80 procs random
    8427.51, 8267.23, 8437.48, 8432.37, 8441.4, 8454.26, 8413.13, 8412.44, 8444.36, 8444.32,
    # baseline 80 procs zipf
    12980.12, 12946.43, 12911.95, 12925.83, 12952.75, 12841.44, 12920.35, 12924.19, 12944.38, 12967.72,
    # baseline 80 procs gaussian
    11666.29, 11624.72, 11454.82, 11482.36, 11462.24, 11379.46, 11691.5, 11471.19, 11402.08, 11494.13,
    # patched 40 procs random
    11706.69, 11778.1, 11774.07, 11750.07, 11744.97, 11766.65, 11727.79, 11708.41, 11745.3, 11716.45,
    # patched 40 procs zipf
    15498.31, 14647.94, 15423.35, 15467.32, 15467.05, 15342.49, 15511.34, 15414.06, 15401.1, 15431.57,
    # patched 40 procs gaussian
    15957.86, 15957.13, 16022.69, 16035.85, 16150.2, 15904.5, 15943.36, 16036.78, 16025.95, 15900.56,
    # patched 80 procs random
    12568.51, 11772.25, 11622.15, 12057.66, 11971.72, 12693.36, 12399.71, 12553.23, 12242.74, 12793.34,
    # patched 80 procs zipf
    14194.78, 14213.61, 14148.66, 14182.35, 14183.91, 14192.23, 14163.2, 14179.7, 14162.12, 14196.34,
    # patched 80 procs gaussian
    14084.86, 13706.34, 14089.42, 14058.4, 14096.74, 14108.06, 14043.41, 14072.15, 14088.44, 14024.51
)

a <- array(v, dim = c(10, 3, 2, 2))

# baseline vs patched
for (concurr in 1:2) {
    for (dist in 1:3) {
        r <- t.test(a[, dist, concurr, 1], a[, dist, concurr, 2])
        print(r)

        p <- r$conf.int * 100 / r$estimate[1]
        if ((p[1] > 0 && p[2] < 0) || (p[1] < 0 && p[2] > 0)) {
            s <- sprintf("concurr%d dist%d: no significance", concurr, dist)
        } else {
            s <- sprintf("concurr%d dist%d: [%.2f, %.2f]%%", concurr, dist, -p[2], -p[1])
        }
        print(s)
    }
}

# low concurr vs high concurr
for (kern in 1:2) {
    for (dist in 1:3) {
        r <- t.test(a[, dist, 1, kern], a[, dist, 2, kern])
        print(r)

        p <- r$conf.int * 100 / r$estimate[1]
        if ((p[1] > 0 && p[2] < 0) || (p[1] < 0 && p[2] > 0)) {
            s <- sprintf("kern%d dist%d: no significance", kern, dist)
        } else {
            s <- sprintf("kern%d dist%d: [%.2f, %.2f]%%", kern, dist, -p[2], -p[1])
        }
        print(s)
    }
}

$ R -q -s -f raw_data_fio.r

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -132.15, df = 11.177, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -3386.514 -3275.766
sample estimates:
mean of x mean of y
  8410.71  11741.85

[1] "concurr1 dist1: [38.95, 40.26]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -9.5917, df = 9.4797, p-value = 3.463e-06
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -967.8353 -600.7307
sample estimates:
mean of x mean of y
 14576.17  15360.45

[1] "concurr1 dist2: [4.12, 6.64]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -37.744, df = 17.33, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1508.328 -1348.850
sample estimates:
mean of x mean of y
 14564.90  15993.49

[1] "concurr1 dist3: [9.26, 10.36]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -30.144, df = 9.3334, p-value = 1.281e-10
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -4137.381 -3562.653
sample estimates:
mean of x mean of y
  8417.45  12267.47

[1] "concurr2 dist1: [42.32, 49.15]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -92.164, df = 13.276, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -1279.417 -1220.931
sample estimates:
mean of x mean of y
 12931.52  14181.69

[1] "concurr2 dist2: [9.44, 9.89]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -49.453, df = 17.863, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2631.656 -2417.052
sample estimates:
mean of x mean of y
 11512.88  14037.23

[1] "concurr2 dist3: [20.99, 22.86]%"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = -0.22947, df = 16.403, p-value = 0.8213
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -68.88155  55.40155
sample estimates:
mean of x mean of y
  8410.71   8417.45

[1] "kern1 dist1: no significance"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = 91.86, df = 17.875, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 1607.021 1682.287
sample estimates:
mean of x mean of y
 14576.17  12931.52

[1] "kern1 dist2: [-11.54, -11.02]%"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = 67.477, df = 17.539, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 2956.815 3147.225
sample estimates:
mean of x mean of y
 14564.90  11512.88

[1] "kern1 dist3: [-21.61, -20.30]%"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = -4.1443, df = 9.0781, p-value = 0.002459
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -812.1507 -239.0833
sample estimates:
mean of x mean of y
 11741.85  12267.47

[1] "kern2 dist1: [2.04, 6.92]%"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = 14.566, df = 9.1026, p-value = 1.291e-07
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  996.0064 1361.5196
sample estimates:
mean of x mean of y
 15360.45  14181.69

[1] "kern2 dist2: [-8.86, -6.48]%"

	Welch Two Sample t-test

data:  a[, dist, 1, kern] and a[, dist, 2, kern]
t = 43.826, df = 15.275, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 1861.263 2051.247
sample estimates:
mean of x mean of y
 15993.49  14037.23

[1] "kern2 dist3: [-12.83, -11.64]%"

99th Percentile Latency
-----------------------
$ cat raw_data_fio_lat.r
v <- c(
    # baseline 40 procs random
    12649, 12387, 12518, 12518, 12518, 12387, 12518, 12518, 12387, 12256,
    # baseline 40 procs zipf
    3458, 3294, 3425, 3294, 3294, 3359, 3752, 3326, 3294, 3458,
    # baseline 40 procs gaussian
    3326, 3458, 3195, 3392, 3326, 3228, 3228, 3326, 3130, 3195,
    # baseline 80 procs random
    25560, 26084, 25560, 25560, 25297, 25297, 25822, 25560, 25560, 25297,
    # baseline 80 procs zipf
    14484, 14615, 14615, 14484, 14484, 14615, 14615, 14615, 14615, 14484,
    # baseline 80 procs gaussian
    15664, 15664, 15533, 15533, 15533, 15664, 15795, 15533, 15664, 15533,
    # patched 40 procs random
    7439, 7242, 7373, 7373, 7373, 7439, 7242, 7308, 7308, 7373,
    # patched 40 procs zipf
    3261, 3425, 3392, 3294, 3359, 3556, 3228, 3490, 3458, 3359,
    # patched 40 procs gaussian
    3687, 3523, 3556, 3523, 3752, 3654, 3884, 3490, 3392, 3720,
    # patched 80 procs random
    15008, 15008, 15008, 15008, 15008, 15008, 15008, 15008, 15008, 15008,
    # patched 80 procs zipf
    7701, 7635, 7701, 7701, 7635, 7635, 7701, 7635, 7635, 7635,
    # patched 80 procs gaussian
    7635, 7898, 7701, 7635, 7635, 7635, 7635, 7635, 7701, 7701
)

a <- array(v, dim = c(10, 3, 2, 2))

# baseline vs patched
for (concurr in 1:2) {
    for (dist in 1:3) {
        r <- t.test(a[, dist, concurr, 1], a[, dist, concurr, 2])
        print(r)

        p <- r$conf.int * 100 / r$estimate[1]
        if ((p[1] > 0 && p[2] < 0) || (p[1] < 0 && p[2] > 0)) {
            s <- sprintf("concurr%d dist%d: no significance", concurr, dist)
        } else {
            s <- sprintf("concurr%d dist%d: [%.2f, %.2f]%%", concurr, dist, -p[2], -p[1])
        }
        print(s)
    }
}

$ R -q -s -f raw_data_fio_lat.r

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = 123.52, df = 15.287, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 5030.417 5206.783
sample estimates:
mean of x mean of y
  12465.6    7347.0

[1] "concurr1 dist1: [-41.77, -40.35]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = 0.23667, df = 16.437, p-value = 0.8158
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -104.7812  131.1812
sample estimates:
mean of x mean of y
   3395.4    3382.2

[1] "concurr1 dist2: no significance"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = -5.9754, df = 16.001, p-value = 1.94e-05
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -457.5065 -217.8935
sample estimates:
mean of x mean of y
   3280.4    3618.1

[1] "concurr1 dist3: [6.64, 13.95]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = 134.89, df = 9, p-value = 3.437e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 10374.74 10728.66
sample estimates:
mean of x mean of y
  25559.7   15008.0

[1] "concurr2 dist1: [-41.97, -40.59]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = 288.1, df = 13.292, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 6849.566 6952.834
sample estimates:
mean of x mean of y
  14562.6    7661.4

[1] "concurr2 dist2: [-47.74, -47.04]%"

	Welch Two Sample t-test

data:  a[, dist, concurr, 1] and a[, dist, concurr, 2]
t = 203.64, df = 17.798, p-value < 2.2e-16
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 7848.616 8012.384
sample estimates:
mean of x mean of y
  15611.6    7681.1

[1] "concurr2 dist3: [-51.32, -50.27]%"


From conleylee at foxmail.com  Tue Jan  4 18:45:51 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Wed,  5 Jan 2022 10:45:51 +0800
Subject: [PATCH v2 2/2] sunxi.yaml: add HAOYU Electronics Marsboard A20
In-Reply-To: <20220105024551.807713-1-conleylee@foxmail.com>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <20220105024551.807713-1-conleylee@foxmail.com>
Message-ID: <tencent_9A79E4BC3715D4948E6D69363916D4B26D0A@qq.com>

From: conley <conleylee at foxmail.com>

Signed-off-by: conley <conleylee at foxmail.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..4bd93ae26bd1 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,11 @@ properties:
           - const: haoyu,a10-marsboard
           - const: allwinner,sun4i-a10
 
+      - description: HAOYU Electronics Marsboard A20
+        items:
+          - const: haoyu,a20-marsboard
+          - const: allwinner,sun7i-a20
+
       - description: MapleBoard MP130
         items:
           - const: mapleboard,mp130
-- 
2.31.1



From conleylee at foxmail.com  Tue Jan  4 18:45:50 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Wed,  5 Jan 2022 10:45:50 +0800
Subject: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20 support
In-Reply-To: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
Message-ID: <tencent_13C536D91764B05D794CBCF3156C963E6C0A@qq.com>

From: conley <conleylee at foxmail.com>

ARM dts: sun7i: Add Marsboard A20 board

This patch add support for Marsboard A20 board.

The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.

Change since v1.
  - Spearate biddings and dts as two patches.
  - use SPDX tag

Signed-off-by: conley <conleylee at foxmail.com>
---
 arch/arm/boot/dts/Makefile                |   1 +
 arch/arm/boot/dts/sun7i-a20-marsboard.dts | 183 ++++++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-marsboard.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..4628a2617313 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-icnova-swac.dtb \
 	sun7i-a20-lamobo-r1.dtb \
 	sun7i-a20-linutronix-testbox-v2.dtb \
+	sun7i-a20-marsboard.dtb \
 	sun7i-a20-m3.dtb \
 	sun7i-a20-mk808c.dtb \
 	sun7i-a20-olimex-som-evb.dtb \
diff --git a/arch/arm/boot/dts/sun7i-a20-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
new file mode 100644
index 000000000000..7ab6aa30fee6
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: LGPL-2.1+
+/*
+ * Copyright 2021 Conley Lee
+ * Conley Lee <conleylee at foxmail.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "HAOYU Electronics Marsboard A20";
+	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&codec {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac_mii_pins {
+	pins = "PA0", "PA1", "PA2",
+	"PA3", "PA4", "PA5", "PA6",
+	"PA7", "PA8", "PA9", "PA10",
+	"PA11", "PA12", "PA13", "PA14",
+	"PA15", "PA16", "PA17";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_mii_pins>;
+	phy-handle = <&phy0>;
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	axp209: pmic at 34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
+	status = "okay";
+};
+
+&gmac_mdio {
+	phy0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&reg_ahci_5v {
+	status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1450000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&pio 7 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH4 */
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
-- 
2.31.1



From alios_sys_security at linux.alibaba.com  Tue Jan  4 19:07:55 2022
From: alios_sys_security at linux.alibaba.com (AliOS system security)
Date: Wed,  5 Jan 2022 11:07:55 +0800
Subject: [PATCH] arm64: fix build error when use rodata_enabled
Message-ID: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>

rodata_enabled should be used when CONFIG_STRICT_KERNEL_RWX
or CONFIG_STRICT_MODULE_RWX is selected

Signed-off-by: AliOS system security <alios_sys_security at linux.alibaba.com>
---
 arch/arm64/mm/mmu.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index acfae9b..47f8754 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -596,6 +596,7 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
 	vm_area_add_early(vma);
 }
 
+#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
 static int __init parse_rodata(char *arg)
 {
 	int ret = strtobool(arg, &rodata_enabled);
@@ -613,11 +614,16 @@ static int __init parse_rodata(char *arg)
 	return 0;
 }
 early_param("rodata", parse_rodata);
+#endif
 
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
 static int __init map_entry_trampoline(void)
 {
-	pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
+	pgprot_t prot = PAGE_KERNEL_EXEC;
+#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
+	if (rodata_enabled)
+		prot = PAGE_KERNEL_ROX;
+#endif
 	phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
 
 	/* The trampoline is always mapped and can therefore be global */
@@ -672,7 +678,11 @@ static void __init map_kernel(pgd_t *pgdp)
 	 * mapping to install SW breakpoints. Allow this (only) when
 	 * explicitly requested with rodata=off.
 	 */
-	pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
+	pgprot_t text_prot = PAGE_KERNEL_EXEC;
+#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
+	if (rodata_enabled)
+		text_prot = PAGE_KERNEL_ROX;
+#endif
 
 	/*
 	 * If we have a CPU that supports BTI and a kernel built for
-- 
2.7.4



From anshuman.khandual at arm.com  Tue Jan  4 21:05:55 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed,  5 Jan 2022 10:35:55 +0530
Subject: [PATCH 0/4] coresight: trbe: Workaround Cortex-A510 erratas
Message-ID: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>

	This series adds three different workarounds in the TRBE driver for
Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
part number definition in the platform. This series applies on 5.16-rc8.

Relevant errata documents can be found here.

https://developer.arm.com/documentation/SDEN2397239/900
https://developer.arm.com/documentation/SDEN2397589/900

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (4):
  arm64: Add Cortex-A510 CPU part definition
  coresight: trbe: Work around the ignored system register writes
  coresight: trbe: Work around the invalid prohibited states
  coresight: trbe: Workaround TRBE trace data corruption

 Documentation/arm64/silicon-errata.rst       |   6 +
 arch/arm64/Kconfig                           |  57 ++++++++++
 arch/arm64/include/asm/cputype.h             |   2 +
 arch/arm64/kernel/cpu_errata.c               |  27 +++++
 arch/arm64/tools/cpucaps                     |   3 +
 drivers/hwtracing/coresight/coresight-trbe.c | 111 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-trbe.h |   8 --
 7 files changed, 181 insertions(+), 33 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan  4 21:05:56 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed,  5 Jan 2022 10:35:56 +0530
Subject: [PATCH 1/4] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641359159-22726-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan  4 21:05:57 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed,  5 Jan 2022 10:35:57 +0530
Subject: [PATCH 2/4] coresight: trbe: Work around the ignored system register
 writes
In-Reply-To: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected.

Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
just after the trace collection has stopped and before performing a system
register write to one of the affected registers. This adds a new cpu errata
in arm64 errata framework and also updates TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst       |  2 +
 arch/arm64/Kconfig                           | 18 +++++++
 arch/arm64/kernel/cpu_errata.c               |  9 ++++
 arch/arm64/tools/cpucaps                     |  1 +
 drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
 drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
 6 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..c9b30e6c2b6c 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -52,6 +52,8 @@ stable kernels.
 | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..2105b68d88db 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2064142
+	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
+	depends on CORESIGHT_TRBE
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
+
+	  Affected Cortex-A510 core might fail to write into system registers after the
+	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
+	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
+	  and TRBTRG_EL1 will be ignored and will not be effected.
+
+	  Work around this in the driver by executing TSB CSYNC and DSB after collection
+	  is stopped and before performing a system register write to one of the affected
+	  registers.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..cbb7d5a9aee7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2064142
+	{
+		.desc = "ARM erratum 2064142",
+		.capability = ARM64_WORKAROUND_2064142,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..fca3cb329e1d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2064142
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 276862c07e32..ec24b62b2cec 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -91,10 +91,12 @@ struct trbe_buf {
  */
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
+#define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
+	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
 }
 
+static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -174,30 +181,42 @@ static int trbe_alloc_node(struct perf_event *event)
 	return cpu_to_node(event->cpu);
 }
 
-static void trbe_drain_buffer(void)
+static inline void trbe_drain_buffer(void)
 {
 	tsb_csync();
 	dsb(nsh);
 }
 
-static void trbe_drain_and_disable_local(void)
+static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
-	trbe_drain_buffer();
-
 	/*
 	 * Disable the TRBE without clearing LIMITPTR which
 	 * might be required for fetching the buffer limits.
 	 */
 	trblimitr &= ~TRBLIMITR_ENABLE;
 	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/*
+	 * Errata affected TRBE implementation will need TSB CSYNC and
+	 * DSB in order to prevent subsequent writes into certain TRBE
+	 * system registers from being ignored and not effected.
+	 */
+	if (trbe_may_fail_sysreg_write(cpudata))
+		trbe_drain_buffer();
 	isb();
 }
 
-static void trbe_reset_local(void)
+static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
 {
-	trbe_drain_and_disable_local();
+	trbe_drain_buffer();
+	set_trbe_disabled(cpudata);
+}
+
+static void trbe_reset_local(struct trbe_cpudata *cpudata)
+{
+	trbe_drain_and_disable_local(cpudata);
 	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
 	write_sysreg_s(0, SYS_TRBPTR_EL1);
 	write_sysreg_s(0, SYS_TRBBASER_EL1);
@@ -234,7 +253,7 @@ static void trbe_stop_and_truncate_event(struct perf_output_handle *handle)
 	 * at event_stop(). So disable the TRBE here and leave
 	 * the update_buffer() to return a 0 size.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	perf_aux_output_end(handle, 0);
 	*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
@@ -579,8 +598,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	WARN_ON(buf->trbe_hw_base < buf->trbe_base);
 	WARN_ON(buf->trbe_write < buf->trbe_hw_base);
 	WARN_ON(buf->trbe_write >= buf->trbe_limit);
-	set_trbe_disabled();
-	isb();
+	set_trbe_disabled(buf->cpudata);
 	clr_trbe_status();
 	set_trbe_base_pointer(buf->trbe_hw_base);
 	set_trbe_write_pointer(buf->trbe_write);
@@ -775,7 +793,7 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
 	 * the TRBE here will ensure that no IRQ could be generated when the perf
 	 * handle gets freed in etm_event_stop().
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 
 	/* Check if there is a pending interrupt and handle it here */
 	status = read_sysreg_s(SYS_TRBSR_EL1);
@@ -986,7 +1004,7 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 	if (cpudata->mode != CS_MODE_PERF)
 		return -EINVAL;
 
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 	buf->cpudata = NULL;
 	cpudata->buf = NULL;
 	cpudata->mode = CS_MODE_DISABLED;
@@ -1028,7 +1046,7 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
 		 * is able to detect this with a disconnected handle
 		 * (handle->event = NULL).
 		 */
-		trbe_drain_and_disable_local();
+		trbe_drain_and_disable_local(buf->cpudata);
 		*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
 		return -EINVAL;
 	}
@@ -1062,6 +1080,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 {
 	struct perf_output_handle **handle_ptr = dev;
 	struct perf_output_handle *handle = *handle_ptr;
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
 	enum trbe_fault_action act;
 	u64 status;
 	bool truncated = false;
@@ -1082,7 +1101,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 	 * Ensure the trace is visible to the CPUs and
 	 * any external aborts have been resolved.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	clr_trbe_irq();
 	isb();
 
@@ -1167,8 +1186,9 @@ static const struct attribute_group *arm_trbe_groups[] = {
 static void arm_trbe_enable_cpu(void *info)
 {
 	struct trbe_drvdata *drvdata = info;
+	struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
 
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
 }
 
@@ -1276,7 +1296,7 @@ static void arm_trbe_remove_coresight_cpu(void *info)
 	struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
 
 	disable_percpu_irq(drvdata->irq);
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	if (trbe_csdev) {
 		coresight_unregister(trbe_csdev);
 		cpudata->drvdata = NULL;
@@ -1349,8 +1369,10 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 	struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
 
 	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
+		struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+
 		disable_percpu_irq(drvdata->irq);
-		trbe_reset_local();
+		trbe_reset_local(cpudata);
 	}
 	return 0;
 }
diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h
index abf3e36082f0..30e4d7db4f8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.h
+++ b/drivers/hwtracing/coresight/coresight-trbe.h
@@ -91,14 +91,6 @@ static inline bool is_trbe_running(u64 trbsr)
 #define TRBE_FILL_MODE_WRAP		1
 #define TRBE_FILL_MODE_CIRCULAR_BUFFER	3
 
-static inline void set_trbe_disabled(void)
-{
-	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
-
-	trblimitr &= ~TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-}
-
 static inline bool get_trbe_flag_update(u64 trbidr)
 {
 	return trbidr & TRBIDR_FLAG;
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan  4 21:05:58 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed,  5 Jan 2022 10:35:58 +0530
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited states
In-Reply-To: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted.

Work around this problem in the TRBE driver by preventing an inconsistent
view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
immediately following a change to TRBLIMITR_EL1.E with at least one ISB
instruction before an ERET, or two ISB instructions if no ERET is to take
place. This adds a new cpu errata in arm64 errata framework and also
updates TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst       |  2 +
 arch/arm64/Kconfig                           | 23 ++++++++++
 arch/arm64/kernel/cpu_errata.c               |  9 ++++
 arch/arm64/tools/cpucaps                     |  1 +
 drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
 5 files changed, 72 insertions(+), 10 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index c9b30e6c2b6c..e0ef3e9a4b8b 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2105b68d88db..026e34fb6fad 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2038923
+	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
+	depends on CORESIGHT_TRBE
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
+
+	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
+	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
+	  might be corrupted. This happens after TRBE buffer has been enabled by setting
+	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
+	  execution changes from a context, in which trace is prohibited to one where it
+	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
+	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
+	  the trace buffer state might be corrupted.
+
+	  Work around this in the driver by preventing an inconsistent view of whether the
+	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
+	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
+	  two ISB instructions if no ERET is to take place.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cbb7d5a9aee7..60b0c1f1d912 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_2038923
+	{
+		.desc = "ARM erratum 2038923",
+		.capability = ARM64_WORKAROUND_2038923,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
+#endif
 	{
 	}
 };
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index fca3cb329e1d..45a06d36d080 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -56,6 +56,7 @@ WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
+WORKAROUND_2038923
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index ec24b62b2cec..0689c6dab96d 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -92,11 +92,13 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
+#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE	3
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
+	[TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
 }
 
+static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
 	dsb(nsh);
 }
 
+static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
+{
+	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+
+	/*
+	 * Enable the TRBE without clearing LIMITPTR which
+	 * might be required for fetching the buffer limits.
+	 */
+	trblimitr |= TRBLIMITR_ENABLE;
+	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/* Synchronize the TRBE enable event */
+	isb();
+
+	/*
+	 * Errata affected TRBE implementation will need an additional
+	 * context synchronization in order to prevent an inconsistent
+	 * TRBE prohibited region view on the CPU which could possibly
+	 * corrupt the TRBE buffer or the TRBE state.
+	 */
+	if (trbe_may_corrupt_with_enable(cpudata))
+		isb();
+}
+
 static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
@@ -555,9 +586,10 @@ static void clr_trbe_status(void)
 	write_sysreg_s(trbsr, SYS_TRBSR_EL1);
 }
 
-static void set_trbe_limit_pointer_enabled(unsigned long addr)
+static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	unsigned long addr = buf->trbe_limit;
 
 	WARN_ON(!IS_ALIGNED(addr, (1UL << TRBLIMITR_LIMIT_SHIFT)));
 	WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
@@ -586,11 +618,8 @@ static void set_trbe_limit_pointer_enabled(unsigned long addr)
 		      TRBLIMITR_TRIG_MODE_SHIFT;
 	trblimitr |= (addr & PAGE_MASK);
 
-	trblimitr |= TRBLIMITR_ENABLE;
 	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-
-	/* Synchronize the TRBE enable event */
-	isb();
+	set_trbe_enabled(buf->cpudata);
 }
 
 static void trbe_enable_hw(struct trbe_buf *buf)
@@ -608,7 +637,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	 * till now before enabling the TRBE.
 	 */
 	isb();
-	set_trbe_limit_pointer_enabled(buf->trbe_limit);
+	set_trbe_limit_pointer_enabled(buf);
 }
 
 static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *handle,
@@ -1013,16 +1042,14 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 
 static void trbe_handle_spurious(struct perf_output_handle *handle)
 {
-	u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
 
 	/*
 	 * If the IRQ was spurious, simply re-enable the TRBE
 	 * back without modifying the buffer parameters to
 	 * retain the trace collected so far.
 	 */
-	limitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
-	isb();
+	set_trbe_enabled(buf->cpudata);
 }
 
 static int trbe_handle_overflow(struct perf_output_handle *handle)
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan  4 21:05:59 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed,  5 Jan 2022 10:35:59 +0530
Subject: [PATCH 4/4] coresight: trbe: Workaround TRBE trace data corruption
In-Reply-To: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641359159-22726-5-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. Workaround this
problem in the driver, by preventing TRBE initialization on affected cpus.
This adds a new cpu errata in arm64 errata framework and also updates TRBE
driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst       |  2 ++
 arch/arm64/Kconfig                           | 16 ++++++++++++++++
 arch/arm64/kernel/cpu_errata.c               |  9 +++++++++
 arch/arm64/tools/cpucaps                     |  1 +
 drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
 5 files changed, 40 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index e0ef3e9a4b8b..50018f60c4d4 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -56,6 +56,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #1902691        | ARM64_ERRATUM_1902691       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 026e34fb6fad..1ea5c3b4aac0 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -819,6 +819,22 @@ config ARM64_ERRATUM_2038923
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_1902691
+	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
+	depends on CORESIGHT_TRBE
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
+
+	  Affected Cortex-A510 core might cause trace data corruption, when being written
+	  into the memory. Effectively TRBE is broken and hence cannot be used to capture
+	  trace data.
+
+	  Work around this problem in the driver by just preventing TRBE initialization on
+	  affected cpus.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 60b0c1f1d912..a3336dfb5a8a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		/* Cortex-A510 r0p0 - r0p2 */
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1902691
+	{
+		.desc = "ARM erratum 1902691",
+		.capability = ARM64_WORKAROUND_1902691,
+
+		/* Cortex-A510 r0p0 - r0p1 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 45a06d36d080..e7719e8f18de 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -57,6 +57,7 @@ WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
 WORKAROUND_2038923
+WORKAROUND_1902691
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 0689c6dab96d..b9b4e34fac15 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -93,12 +93,14 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
 #define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE	3
+#define TRBE_IS_BROKEN	4
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
 	[TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
+	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -181,6 +183,11 @@ static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
 }
 
+static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -1291,6 +1298,11 @@ static void arm_trbe_probe_cpu(void *info)
 	 */
 	trbe_check_errata(cpudata);
 
+	if (trbe_is_broken(cpudata)) {
+		pr_err("TRBE might corrupt the trace on cpu %d\n", cpu);
+		goto cpu_clear;
+	}
+
 	/*
 	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
 	 * we must always program the TBRPTR_EL1, 256bytes from a page
-- 
2.25.1



From yu.tu at amlogic.com  Tue Jan  4 21:53:56 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Wed, 5 Jan 2022 13:53:56 +0800
Subject: [PATCH V3 4/6] tty: serial: meson: The UART baud rate calculation
 is described using the common clock code. Also added S4 chip uart
 Compatible.
In-Reply-To: <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>
References: <20211230102110.3861-1-yu.tu@amlogic.com>
 <20211230102110.3861-5-yu.tu@amlogic.com>
 <1jfsq57wym.fsf@starbuckisacylon.baylibre.com>
 <264367c8-2de1-ebd1-0843-e4e33a8407a6@amlogic.com>
 <1jpmp7rc1z.fsf@starbuckisacylon.baylibre.com>
 <318ec2df-b73b-520b-f5ac-d0d2fce0eff0@amlogic.com>
Message-ID: <61568e98-b450-c9c0-a60b-1e7c850591c7@amlogic.com>

  Hi Jerome,

On 2022/1/4 22:35, Yu Tu wrote:
> Hi Jerome,
>  ????Thank you very much for your patient reply. I have learned a lot 
> from it.
> 
> On 2022/1/4 18:36, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>>
>>
>> On Tue 04 Jan 2022 at 17:57, Yu Tu <yu.tu at amlogic.com> wrote:
>>
>>> Hi Jerome,
>>> ????Thank you very much for your reply.
>>>
>>> On 2022/1/3 20:40, Jerome Brunet wrote:
>>>> [ EXTERNAL EMAIL ]
>>>>
>>>> On Thu 30 Dec 2021 at 18:21, Yu Tu <yu.tu at amlogic.com> wrote:
>>>>
>>>>> Using the common Clock code to describe the UART baud rate clock makes
>>>>> it easier for the UART driver to be compatible with the baud rate
>>>>> requirements of the UART IP on different meson chips
>>>>>
>>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>>> ---
>>>>> ?? drivers/tty/serial/Kconfig????? |?? 1 +
>>>>> ?? drivers/tty/serial/meson_uart.c | 311 
>>>>> ++++++++++++++++++++++++++------
>>>>> ?? 2 files changed, 257 insertions(+), 55 deletions(-)
>>>>>
>>>>> diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
>>>>> index 780908d43557..32e238173036 100644
>>>>> --- a/drivers/tty/serial/Kconfig
>>>>> +++ b/drivers/tty/serial/Kconfig
>>>>> @@ -198,6 +198,7 @@ config SERIAL_KGDB_NMI
>>>>> ?? config SERIAL_MESON
>>>>> ?????? tristate "Meson serial port support"
>>>>> ?????? depends on ARCH_MESON
>>>>> +??? depends on COMMON_CLK
>>>>> ?????? select SERIAL_CORE
>>>>> ?????? help
>>>>> ???????? This enables the driver for the on-chip UARTs of the Amlogic
>>>>> diff --git a/drivers/tty/serial/meson_uart.c 
>>>>> b/drivers/tty/serial/meson_uart.c
>>>>> index 99efe62a1507..07eb1f40aaaa 100644
>>>>> --- a/drivers/tty/serial/meson_uart.c
>>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>>> @@ -6,6 +6,7 @@
>>>>> ??? */
>>>>> ???? #include <linux/clk.h>
>>>>> +#include <linux/clk-provider.h>
>>>>> ?? #include <linux/console.h>
>>>>> ?? #include <linux/delay.h>
>>>>> ?? #include <linux/init.h>
>>>>> @@ -65,9 +66,7 @@
>>>>> ?? #define AML_UART_RECV_IRQ(c)??????? ((c) & 0xff)
>>>>> ???? /* AML_UART_REG5 bits */
>>>>> -#define AML_UART_BAUD_MASK??????? 0x7fffff
>>>>> ?? #define AML_UART_BAUD_USE??????? BIT(23)
>>>>> -#define AML_UART_BAUD_XTAL??????? BIT(24)
>>>>> ???? #define AML_UART_PORT_NUM??????? 12
>>>>> ?? #define AML_UART_PORT_OFFSET??????? 6
>>>>> @@ -76,6 +75,21 @@
>>>>> ?? #define AML_UART_POLL_USEC??????? 5
>>>>> ?? #define AML_UART_TIMEOUT_USEC??????? 10000
>>>>> ?? +struct meson_uart_data {
>>>>> +??? struct uart_port??? port;
>>>>> +??? struct clk??????? *pclk;
>>>>> +??? struct clk??????? *baud_clk;
>>>>> +??? struct clk_divider??? baud_div;
>>>>> +??? struct clk_mux??????? use_xtal_mux;
>>>>> +??? struct clk_mux??????? xtal_clk_sel_mux;
>>>>> +??? struct clk_mux??????? xtal2_clk_sel_mux;
>>>>> +??? struct clk_fixed_factor??? xtal_div2;
>>>>> +??? struct clk_fixed_factor??? xtal_div3;
>>>>> +??? struct clk_fixed_factor??? clk81_div4;
>>>> Keeping all these internal elements around is not useful since they are
>>>> registered using devm_
>>>>
>>> I'm sorry. I don't know what you mean. That's exactly what you said, but
>>> what's wrong, I don't understand. Do you have any better suggestions,
>>> please specify specific points, preferably give examples.
>>
>> I'm saying that you don't need to keep reference to the internal
>> elements of the clock tree you have registered since devm_ will take
>> care of the removal later on. IOW, Once they are registered, the pointer
>> is never used again so you don't need it in the private data.
>>
> I understand you now. What you say is right. I will correct it.
>>
>>>>> +??? bool??????????? no_clk81_input;
>>>> What is this ?
>>>>
>>> To distinguish between clK81 and XTAL.
>>
>> ... Yet, it is not used
>>
>>>>> +??? bool??????????? has_xtal_clk_sel;
>>>>> +};
>>>>> +
>>>>> ?? static struct uart_driver meson_uart_driver;
>>>>> ???? static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>>> @@ -270,14 +284,11 @@ static void meson_uart_reset(struct uart_port 
>>>>> *port)
>>>>> ?? static int meson_uart_startup(struct uart_port *port)
>>>>> ?? {
>>>>> ?????? u32 val;
>>>>> -??? int ret = 0;
>>>>> +??? int ret;
>>>>> ?? -??? val = readl(port->membase + AML_UART_CONTROL);
>>>>> -??? val |= AML_UART_CLEAR_ERR;
>>>>> -??? writel(val, port->membase + AML_UART_CONTROL);
>>>>> -??? val &= ~AML_UART_CLEAR_ERR;
>>>>> -??? writel(val, port->membase + AML_UART_CONTROL);
>>>>> +??? meson_uart_reset(port);
>>>>> ?? +??? val = readl(port->membase + AML_UART_CONTROL);
>>>>> ?????? val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>> ?????? writel(val, port->membase + AML_UART_CONTROL);
>>>>> ?? @@ -295,19 +306,17 @@ static int meson_uart_startup(struct 
>>>>> uart_port
>>>>> *port)
>>>>> ???? static void meson_uart_change_speed(struct uart_port *port, 
>>>>> unsigned
>>>>> long baud)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> ?????? u32 val;
>>>>> ???????? while (!meson_uart_tx_empty(port))
>>>>> ?????????? cpu_relax();
>>>>> ?? -??? if (port->uartclk == 24000000) {
>>>> This check shows that previous code assumed bit 24 was left untouched
>>>> Below you can see that GXBB and newer used the XTAL path while older
>>>> used the other
>>>> Your change makes this dynamic which is another "unexpected" change.
>>>> Please make the bit 24 mux RO to start with so the behavior remains 
>>>> unchanged
>>>> for older SoCs.
>>> I agree with what you say, and I will correct it.
>>>>
>>>>> -??????? val = ((port->uartclk / 3) / baud) - 1;
>>>>> -??????? val |= AML_UART_BAUD_XTAL;
>>>>> -??? } else {
>>>>> -??????? val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>>> -??? }
>>>>> +??? val = readl(port->membase + AML_UART_REG5);
>>>>> ?????? val |= AML_UART_BAUD_USE;
>>>>> ?????? writel(val, port->membase + AML_UART_REG5);
>>>>> +
>>>>> +??? clk_set_rate(private_data->baud_clk, baud);
>>>>> ?? }
>>>>> ???? static void meson_uart_set_termios(struct uart_port *port,
>>>>> @@ -397,11 +406,27 @@ static int meson_uart_verify_port(struct 
>>>>> uart_port *port,
>>>>> ???? static void meson_uart_release_port(struct uart_port *port)
>>>>> ?? {
>>>>> -??? /* nothing to do */
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +
>>>>> +??? clk_disable_unprepare(private_data->baud_clk);
>>>>> +??? clk_disable_unprepare(private_data->pclk);
>>>>> ?? }
>>>>> ???? static int meson_uart_request_port(struct uart_port *port)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +??? int ret;
>>>>> +
>>>>> +??? ret = clk_prepare_enable(private_data->pclk);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? ret = clk_prepare_enable(private_data->baud_clk);
>>>>> +??? if (ret) {
>>>>> +??????? clk_disable_unprepare(private_data->pclk);
>>>>> +??????? return ret;
>>>>> +??? }
>>>>> +
>>>>> ?????? return 0;
>>>>> ?? }
>>>>> ?? @@ -629,56 +654,175 @@ static struct uart_driver 
>>>>> meson_uart_driver = {
>>>>> ?????? .cons??????? = MESON_SERIAL_CONSOLE,
>>>>> ?? };
>>>>> ?? -static inline struct clk *meson_uart_probe_clock(struct device 
>>>>> *dev,
>>>>> -???????????????????????? const char *id)
>>>>> +static int meson_uart_register_clk(struct uart_port *port,
>>>>> +?????????????????? const char *name_suffix,
>>>>> +?????????????????? const struct clk_parent_data *parent_data,
>>>>> +?????????????????? unsigned int num_parents,
>>>>> +?????????????????? const struct clk_ops *ops,
>>>>> +?????????????????? struct clk_hw *hw)
>>>>> ?? {
>>>>> -??? struct clk *clk = NULL;
>>>>> +??? struct clk_init_data init = { };
>>>>> +??? char clk_name[32];
>>>>> ?????? int ret;
>>>>> ?? -??? clk = devm_clk_get(dev, id);
>>>>> -??? if (IS_ERR(clk))
>>>>> -??????? return clk;
>>>>> +??? snprintf(clk_name, sizeof(clk_name), "%s#%s", 
>>>>> dev_name(port->dev),
>>>>> +???????? name_suffix);
>>>>> ?? -??? ret = clk_prepare_enable(clk);
>>>>> -??? if (ret) {
>>>>> -??????? dev_err(dev, "couldn't enable clk\n");
>>>>> -??????? return ERR_PTR(ret);
>>>>> -??? }
>>>>> +??? init.name = clk_name;
>>>>> +??? init.ops = ops;
>>>>> +??? init.flags = CLK_SET_RATE_PARENT;
>>>>> +??? init.parent_data = parent_data;
>>>>> +??? init.num_parents = num_parents;
>>>>> +
>>>>> +??? hw->init = &init;
>>>>> ?? -??? devm_add_action_or_reset(dev,
>>>>> -??????????? (void(*)(void *))clk_disable_unprepare,
>>>>> -??????????? clk);
>>>>> +??? ret = devm_clk_hw_register(port->dev, hw);
>>>>> +??? if (ret)
>>>>> +??????? return dev_err_probe(port->dev, ret,
>>>>> +???????????????????? "Failed to register the '%s' clock\n",
>>>>> +???????????????????? clk_name);
>>>>> ?? -??? return clk;
>>>>> +??? return ret;
>>>>> ?? }
>>>>> ?? -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>>> -?????????????????? struct uart_port *port)
>>>>> -{
>>>>> -??? struct clk *clk_xtal = NULL;
>>>>> -??? struct clk *clk_pclk = NULL;
>>>>> -??? struct clk *clk_baud = NULL;
>>>>> +static int meson_uart_probe_clocks(struct uart_port *port,
>>>>> +?????????????????? bool register_clk81_div4)
>>>>> +{
>>>>> +??? struct meson_uart_data *private_data = port->private_data;
>>>>> +??? struct clk_parent_data use_xtal_mux_parents[2] = {
>>>>> +??????? { .index = -1, },
>>>>> +??????? { .index = -1, },
>>>>> +??? };
>>>>> +??? struct clk_parent_data xtal_clk_sel_mux_parents[2] = { };
>>>>> +??? struct clk_parent_data xtal2_clk_sel_mux_parents[2] = { };
>>>>> +??? struct clk_parent_data xtal_div_parent = { .fw_name = "xtal", };
>>>>> +??? struct clk_parent_data clk81_div_parent = { .fw_name = "baud", };
>>>>> +??? struct clk_parent_data baud_div_parent = { };
>>>>> +??? struct clk *clk_baud, *clk_xtal;
>>>>> +??? int ret;
>>>>> ?? -??? clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>>> -??? if (IS_ERR(clk_pclk))
>>>>> -??????? return PTR_ERR(clk_pclk);
>>>>> +??? private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>>> +??? if (IS_ERR(private_data->pclk))
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>>> +???????????????????? "Failed to get the 'pclk' clock\n");
>>>>> +
>>>>> +??? clk_baud = devm_clk_get(port->dev, "baud");
>>>>> +??? if (IS_ERR(clk_baud))
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_baud),
>>>>> +???????????????????? "Failed to get the 'baud' clock\n");
>>>>> ?? -??? clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>>> +??? clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>> ?????? if (IS_ERR(clk_xtal))
>>>>> -??????? return PTR_ERR(clk_xtal);
>>>>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>>> +???????????????????? "Failed to get the 'xtal' clock\n");
>>>>> +
>>>>> +??? private_data->xtal_div3.mult = 1;
>>>>> +??? private_data->xtal_div3.div = 3;
>>>>> +??? ret = meson_uart_register_clk(port, "xtal_div3", 
>>>>> &xtal_div_parent,
>>>>> +????????????????????? 1, &clk_fixed_factor_ops,
>>>>> +????????????????????? &private_data->xtal_div3.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> ?? -??? clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>>> -??? if (IS_ERR(clk_baud))
>>>>> -??????? return PTR_ERR(clk_baud);
>>>>> +??? if (register_clk81_div4) {
>>>> Clock dividers represent HW elements. The presence of an HW element
>>>> cannot
>>>> dependent on the current of the input clocks. There is no way this 
>>>> is right
>>>>
>>>>> +??????? private_data->clk81_div4.mult = 1;
>>>>> +??????? private_data->clk81_div4.div = 4;
>>>>> +??????? ret = meson_uart_register_clk(port, "clk81_div4",
>>>>> +????????????????????????? &clk81_div_parent, 1,
>>>>> +????????????????????????? &clk_fixed_factor_ops,
>>>>> +????????????????????????? &private_data->clk81_div4.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? use_xtal_mux_parents[0].hw = &private_data->clk81_div4.hw;
>>>> This is only going to be used on meson8 and older. Worst case it should
>>>> depend
>>>> on this compatible but I don't think this would be right here.
>>>> IMO, this shows that the UART "baud" input was actually fed by a
>>>> derivation of "fclk_div4" instead of "clk_81" on these older SoCs.
>>>> So instead of registering what I suspect to be a fake element, the
>>>> meson8 clock controller driver and DT should be fixed a this should 
>>>> go away.
>>>>
>>> Virtually all UART controllers are supported, but they are not used 
>>> after
>>> Meson8. So the description is more reasonable in UART driver.
>>
>> No it is not. It's not virtual, the support for meson8 is there in
>> mainline.
>>
>> Unless you tell me there is an actual /4 divider in the UART block of
>> the meson8 and older and that is was removed from the newer SoC,
>> the bit above should be removed and the meson8 clock tree fixed.
>>
>> I think it is more probable that the /4 was never there to begin with,
>> and that clk81/4 aka "fclk_div4", which is already available from the
>> clock controller, was actually routed on these older SoCs.
> I will check with the chip design department if it is divided by 4. I'll 
> get back to you.
I confirmed with the chip design department that there is a 4 divider 
inside. So I'm going to use the divider 4 for the description, but only 
the older meson8 is in use, so I'm going to pass the parameter through 
compatible. Do you have any better suggestions?

>>
>>>>> +??? }
>>>>> ?? -??? port->uartclk = clk_get_rate(clk_baud);
>>>>> +??? if (private_data->has_xtal_clk_sel) {
>>>>> +??????? private_data->xtal_div2.mult = 1;
>>>>> +??????? private_data->xtal_div2.div = 2;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal_div2",
>>>>> +????????????????????????? &xtal_div_parent, 1,
>>>>> +????????????????????????? &clk_fixed_factor_ops,
>>>>> +????????????????????????? &private_data->xtal_div2.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? xtal_clk_sel_mux_parents[0].hw = &private_data->xtal_div3.hw;
>>>>> +??????? xtal_clk_sel_mux_parents[1].fw_name = "xtal";
>>>>> +
>>>>> +??????? private_data->xtal_clk_sel_mux.reg = port->membase + 
>>>>> AML_UART_REG5;
>>>>> +??????? private_data->xtal_clk_sel_mux.mask = 0x1;
>>>>> +??????? private_data->xtal_clk_sel_mux.shift = 26;
>>>>> +??????? private_data->xtal_clk_sel_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal_clk_sel",
>>>>> +????????????????????????? xtal_clk_sel_mux_parents,
>>>>> +????????????????????????? ARRAY_SIZE(xtal_clk_sel_mux_parents),
>>>>> +????????????????????????? &clk_mux_ops,
>>>>> +????????????????????????? &private_data->xtal_clk_sel_mux.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? xtal2_clk_sel_mux_parents[0].hw = 
>>>>> &private_data->xtal_clk_sel_mux.hw;
>>>>> +??????? xtal2_clk_sel_mux_parents[1].hw = 
>>>>> &private_data->xtal_div2.hw;
>>>>> +
>>>>> +??????? private_data->xtal2_clk_sel_mux.reg = port->membase + 
>>>>> AML_UART_REG5;
>>>>> +??????? private_data->xtal2_clk_sel_mux.mask = 0x1;
>>>>> +??????? private_data->xtal2_clk_sel_mux.shift = 27;
>>>>> +??????? private_data->xtal2_clk_sel_mux.flags = 
>>>>> CLK_MUX_ROUND_CLOSEST;
>>>>> +??????? ret = meson_uart_register_clk(port, "xtal2_clk_sel",
>>>>> +????????????????????????? xtal2_clk_sel_mux_parents,
>>>>> +????????????????????????? ARRAY_SIZE(xtal2_clk_sel_mux_parents),
>>>>> +????????????????????????? &clk_mux_ops,
>>>>> +????????????????????????? &private_data->xtal2_clk_sel_mux.hw);
>>>>> +??????? if (ret)
>>>>> +??????????? return ret;
>>>>> +
>>>>> +??????? use_xtal_mux_parents[1].hw = 
>>>>> &private_data->xtal2_clk_sel_mux.hw;
>>>>> +??? } else {
>>>>> +??????? use_xtal_mux_parents[1].hw = &private_data->xtal_div3.hw;
>>>> Well the above is a bit over-complicated. If I summarize:
>>>> GXBB and older used a fixed divider of 3. Bits 26 and 27 read
>>>> 0 according to the documentation.
>>>> Chips after GXBB have 2 configurable divider of 2 and 3. bits 26 and 27
>>>> selects which of these dividers is used.
>>>> So the above could be replaced with a single divider covering bits 
>>>> 26 and
>>>> 27
>>>> with the following divider table { 2, 2, 1, 3 }. The divider should use
>>>> RO ops and not have CLK_SET_RATE_PARENT. It can be used for all chips
>>>> variant like this, including the older ones.
>>>>
>>> As you say, the way you say it is complicated. I think you're 
>>> complicating
>>> things.I don't understand what you're trying to achieve.
>>> Can you be more specific?
>>
>> I'm proposing to replace the 4 elements above, paths, parent_table and
>> all with a single divider with a specific table. It accomplishes the 
>> same thing.
>>
>> |--------+--------+-----------|
>> | Bit 27 | Bit 26 | Div Value |
>> |--------+--------+-----------|
>> |????? 0 |????? 0 |???????? 3 |
>> |--------+--------+-----------|
>> |????? 0 |????? 1 |???????? 1 |
>> |--------+--------+-----------|
>> |????? 1 |????? 0 |???????? 2 |
>> |--------+--------+-----------|
>> |????? 1 |????? 1 |???????? 2 |
>> |--------+--------+-----------|
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/clk-provider.h?h=v5.16-rc8#n602 
>>
>>
>> something like:
>>
>> static struct clk_div_table reg5_table[] = {
>> ????{ 0, 3 },
>> ???????? { 1, 1 },
>> ???????? { 2, 2 },
>> ???????? { 3, 2 },
>> };
>>
>> I'm also pointing out that, since bit 26 and 27 reads 0 on the older
>> SoCs, the divider would work for these too, as long as the Ops is
>> read-only. So you don't even need to register different element
>> depending on the SoC which simplify things a bit more.
>>
>> If you prefer to keep a fixed divider for the older ones, It's fine by
>> me. It gives a bit more work but it is closer to reality. The newer SoC
>> could still use the custom divider regardless.
>>
>> Last, and as explained on other bits, that part of the clock path should
>> remain RO at first, to keep behavior stable with this change. You may
>> change that later on, in a dedicated patch describing the change.
>>
> I understand what you mean, and i will try to realize it. I hope you can 
> help review and give me your suggestions.
>>>
>>>> The only information you need to carry if whether or not you want to
>>>> make this divider modifiable. This means using the dt data to store
>>>> clk_div_ops or clk_div_ro_ops pointer.
>>>> To avoid changing the behavior of the older platforms in this patch, I
>>>> would
>>>> suggest to make everything use clk_div_ro_ops first, and make another
>>>> patch to use clk_div_ops if necessary.
>>>>
>>>>> +??? }
>>>>> +
>>>>> +??? private_data->use_xtal_mux.reg = port->membase + AML_UART_REG5;
>>>>> +??? private_data->use_xtal_mux.mask = 0x1;
>>>>> +??? private_data->use_xtal_mux.shift = 24;
>>>>> +??? private_data->use_xtal_mux.flags = CLK_MUX_ROUND_CLOSEST;
>>>>> +??? ret = meson_uart_register_clk(port, "use_xtal", 
>>>>> use_xtal_mux_parents,
>>>>> +????????????????????? ARRAY_SIZE(use_xtal_mux_parents),
>>>>> +????????????????????? &clk_mux_ops,
>>>> Use RO ops here to start with.
>>>> You can make this writable with another patch explicitly describing 
>>>> the change.
>>> I agree with what you say, and I will correct it.
>>>>
>>>>> +????????????????????? &private_data->use_xtal_mux.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? baud_div_parent.hw = &private_data->use_xtal_mux.hw;
>>>>> +
>>>>> +??? private_data->baud_div.reg = port->membase + AML_UART_REG5;
>>>>> +??? private_data->baud_div.shift = 0;
>>>>> +??? private_data->baud_div.width = 23;
>>>>> +??? private_data->baud_div.flags = CLK_DIVIDER_ROUND_CLOSEST;
>>>>> +??? ret = meson_uart_register_clk(port, "baud_div",
>>>>> +????????????????????? &baud_div_parent, 1,
>>>>> +????????????????????? &clk_divider_ops,
>>>>> +????????????????????? &private_data->baud_div.hw);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> +
>>>>> +??? private_data->baud_clk = devm_clk_hw_get_clk(port->dev,
>>>>> +???????????????????????????? &private_data->baud_div.hw,
>>>>> +???????????????????????????? "baud_rate");
>>>> There is a problem with this function in CCF. It will pin the driver to
>>>> itself, making it unremovable. It is an ongoing topic. For now, just 
>>>> use
>>>> "hw->clk" to get the struct *clk.
>>>>
>>>>> +??? if (IS_ERR(private_data->baud_clk))
>>>>> +??????? return dev_err_probe(port->dev,
>>>> I don't think anything can defer here, so dev_err_probe() is not
>>>> necessary I think
>>>>
>>> I agree with what you say, and I will correct it.
>>>>> +???????????????????? PTR_ERR(private_data->baud_clk),
>>>>> +???????????????????? "Failed to request the 'baud_rate' clock\n");
>>>>> ???????? return 0;
>>>>> ?? }
>>>>> ???? static int meson_uart_probe(struct platform_device *pdev)
>>>>> ?? {
>>>>> +??? struct meson_uart_data *private_data;
>>>>> ?????? struct resource *res_mem, *res_irq;
>>>>> +??? struct clk *clk_baud, *clk_xtal;
>>>>> +??? bool register_clk81_div4;
>>>>> ?????? struct uart_port *port;
>>>>> ?????? int ret = 0;
>>>>> ?????? int id = -1;
>>>>> @@ -711,18 +855,37 @@ static int meson_uart_probe(struct 
>>>>> platform_device *pdev)
>>>>> ?????????? return -EBUSY;
>>>>> ?????? }
>>>>> ?? -??? port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>>> GFP_KERNEL);
>>>>> -??? if (!port)
>>>>> +??? private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>>> +??????????????????? GFP_KERNEL);
>>>>> +??? if (!private_data)
>>>>> ?????????? return -ENOMEM;
>>>>> ?? +??? if (device_get_match_data(&pdev->dev))
>>>>> +??????? private_data->has_xtal_clk_sel = true;
>>>>> +
>>>>> +??? private_data->pclk = devm_clk_get(&pdev->dev, "pclk");
>>>>> +??? if (IS_ERR(private_data->pclk))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(private_data->pclk),
>>>>> +???????????????????? "Failed to get the 'pclk' clock\n");
>>>>> +
>>>>> +??? clk_baud = devm_clk_get(&pdev->dev, "baud");
>>>>> +??? if (IS_ERR(clk_baud))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(clk_baud),
>>>>> +???????????????????? "Failed to get the 'baud' clock\n");
>>>>> +
>>>>> +??? clk_xtal = devm_clk_get(&pdev->dev, "xtal");
>>>>> +??? if (IS_ERR(clk_xtal))
>>>>> +??????? return dev_err_probe(&pdev->dev, PTR_ERR(clk_xtal),
>>>>> +???????????????????? "Failed to get the 'xtal' clock\n");
>>>>> +
>>>> This is second time you call devm_clk_get() on these clocks. One
>>>> instance has to go away
>>>>
>>> I agree with what you say, and I will correct it.
>>>>> +??? register_clk81_div4 = clk_get_rate(clk_xtal) != 
>>>>> clk_get_rate(clk_baud);
>>>>> +
>>>> The above is a ugly way to distinguish the meson8 (32bit) SoC family
>>>> from the rest. This definitely not the way to achieve it.
>>>> The right is the compatible data but here I think it is not
>>>> necessary. The clock input should be fixed.
>>>>
>>>>> +??? port = &private_data->port;
>>>>> +
>>>>> ?????? port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>> ?????? if (IS_ERR(port->membase))
>>>>> ?????????? return PTR_ERR(port->membase);
>>>>> ?? -??? ret = meson_uart_probe_clocks(pdev, port);
>>>>> -??? if (ret)
>>>>> -??????? return ret;
>>>>> -
>>>>> ?????? port->iotype = UPIO_MEM;
>>>>> ?????? port->mapbase = res_mem->start;
>>>>> ?????? port->mapsize = resource_size(res_mem);
>>>>> @@ -735,6 +898,12 @@ static int meson_uart_probe(struct 
>>>>> platform_device *pdev)
>>>>> ?????? port->x_char = 0;
>>>>> ?????? port->ops = &meson_uart_ops;
>>>>> ?????? port->fifosize = 64;
>>>>> +??? port->uartclk = clk_get_rate(clk_baud);
>>>>> +??? port->private_data = private_data;
>>>>> +
>>>>> +??? ret = meson_uart_probe_clocks(port, register_clk81_div4);
>>>>> +??? if (ret)
>>>>> +??????? return ret;
>>>>> ???????? meson_ports[pdev->id] = port;
>>>>> ?????? platform_set_drvdata(pdev, port);
>>>>> @@ -761,10 +930,42 @@ static int meson_uart_remove(struct 
>>>>> platform_device *pdev)
>>>>> ?? }
>>>>> ???? static const struct of_device_id meson_uart_dt_match[] = {
>>>>> -??? { .compatible = "amlogic,meson6-uart" },
>>>>> -??? { .compatible = "amlogic,meson8-uart" },
>>>>> -??? { .compatible = "amlogic,meson8b-uart" },
>>>>> -??? { .compatible = "amlogic,meson-gx-uart" },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson6-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson8-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson8b-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gxbb-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gxl-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-g12a-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-s4-uart",
>>>>> +??????? .data = (void *)true,
>>>>> +??? },
>>>>> +??? /*
>>>>> +???? * deprecated, don't use anymore because it doesn't differentiate
>>>>> +???? * between GXBB and GXL which have different revisions of the 
>>>>> UART IP.
>>>>> +???? */
>>>>> +??? {
>>>>> +??????? .compatible = "amlogic,meson-gx-uart",
>>>>> +??????? .data = (void *)false,
>>>>> +??? },
>>>>> ?????? { /* sentinel */ },
>>>>> ?? };
>>>>> ?? MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>>
>>


From irogers at google.com  Tue Jan  4 22:13:03 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:03 -0800
Subject: [PATCH v4 00/48] Refactor perf cpumap
Message-ID: <20220105061351.120843-1-irogers@google.com>

Perf cpu map has various functions where a cpumap and index are passed
in order to load the cpu. A problem with this is that the wrong index
may be passed for the cpumap, causing problems like aggregation on the
wrong CPU:
https://lore.kernel.org/lkml/20211204023409.969668-1-irogers at google.com/

This patch set refactors the cpu map API, reducing it and explicitly
passing the cpu (rather than the pair) to functions that need
it. Comments are added at the same time. Changes modify the same
file/function more than once as refactoring and fixes are broken apart
for the sake of bisection.

v2. Incorproates fixes suggested Jiri Olsa, rewrites the evlist CPU
    iterator in part in a way suggested by Riccardo Mancini. The new
    fixes start at patch 23. The final change was suggested by John
    Garry to make the CPUs have their own struct wrapper.

v3. Incorporates fixes suggested by Namhyung Kim.

v4. Rebases and incorporates fixes suggested by Jiri Olsa.

Ian Rogers (48):
  libperf: Add comments to perf_cpu_map.
  perf stat: Add aggr creators that are passed a cpu.
  perf stat: Correct aggregation CPU map
  perf stat: Switch aggregation to use for_each loop
  perf stat: Switch to cpu version of cpu_map__get
  perf cpumap: Switch cpu_map__build_map to cpu function
  perf cpumap: Remove map+index get_socket
  perf cpumap: Remove map+index get_die
  perf cpumap: Remove map+index get_core
  perf cpumap: Remove map+index get_node
  perf cpumap: Add comments to aggr_cpu_id
  perf cpumap: Remove unused cpu_map__socket
  perf cpumap: Simplify equal function name.
  perf cpumap: Rename empty functions.
  perf cpumap: Document cpu__get_node and remove redundant function
  perf cpumap: Remove map from function names that don't use a map.
  perf cpumap: Remove cpu_map__cpu, use libperf function.
  perf cpumap: Refactor cpu_map__build_map
  perf cpumap: Rename cpu_map__get_X_aggr_by_cpu functions
  perf cpumap: Move 'has' function to libperf
  perf cpumap: Add some comments to cpu_aggr_map
  perf cpumap: Trim the cpu_aggr_map
  perf stat: Fix memory leak in check_per_pkg
  perf cpumap: Add CPU to aggr_cpu_id
  perf stat-display: Avoid use of core for CPU.
  perf evsel: Derive CPUs and threads in alloc_counts
  libperf: Switch cpu to more accurate cpu_map_idx
  libperf: Use cpu not index for evsel mmap
  perf counts: Switch name cpu to cpu_map_idx
  perf stat: Rename aggr_data cpu to imply it's an index
  perf stat: Use perf_cpu_map__for_each_cpu
  perf script: Use for each cpu to aid readability
  libperf: Allow NULL in perf_cpu_map__idx
  perf evlist: Refactor evlist__for_each_cpu.
  perf evsel: Pass cpu not cpu map index to synthesize
  perf stat: Correct variable name for read counter
  perf evsel: Rename CPU around get_group_fd
  perf evsel: Reduce scope of evsel__ignore_missing_thread
  perf evsel: Rename variable cpu to index
  perf test: Use perf_cpu_map__for_each_cpu
  perf stat: Correct check_per_pkg cpu
  perf stat: Swap variable name cpu to index
  libperf: Sync evsel documentation
  perf bpf: Rename cpu to cpu_map_idx
  perf c2c: Use more intention revealing iterator
  perf script: Fix flipped index and cpu
  perf stat: Correct first_shadow_cpu to return index
  perf cpumap: Give CPUs their own type.

 tools/lib/perf/Documentation/libperf.txt      |  11 +-
 tools/lib/perf/cpumap.c                       | 131 +++--
 tools/lib/perf/evlist.c                       |   4 +-
 tools/lib/perf/evsel.c                        |  92 ++--
 tools/lib/perf/include/internal/cpumap.h      |  18 +-
 tools/lib/perf/include/internal/evlist.h      |   3 +-
 tools/lib/perf/include/internal/evsel.h       |   4 +-
 tools/lib/perf/include/internal/mmap.h        |   5 +-
 tools/lib/perf/include/perf/cpumap.h          |   8 +-
 tools/lib/perf/include/perf/evsel.h           |  10 +-
 tools/lib/perf/libperf.map                    |   1 +
 tools/lib/perf/mmap.c                         |   2 +-
 tools/perf/arch/arm/util/cs-etm.c             |  16 +-
 tools/perf/bench/epoll-ctl.c                  |   2 +-
 tools/perf/bench/epoll-wait.c                 |   2 +-
 tools/perf/bench/futex-hash.c                 |   2 +-
 tools/perf/bench/futex-lock-pi.c              |   2 +-
 tools/perf/bench/futex-requeue.c              |   2 +-
 tools/perf/bench/futex-wake-parallel.c        |   2 +-
 tools/perf/bench/futex-wake.c                 |   2 +-
 tools/perf/builtin-c2c.c                      |  15 +-
 tools/perf/builtin-ftrace.c                   |   2 +-
 tools/perf/builtin-kmem.c                     |   2 +-
 tools/perf/builtin-record.c                   |   2 +-
 tools/perf/builtin-sched.c                    |  71 +--
 tools/perf/builtin-script.c                   |  10 +-
 tools/perf/builtin-stat.c                     | 516 +++++++++---------
 tools/perf/tests/attr.c                       |   6 +-
 tools/perf/tests/bitmap.c                     |   2 +-
 tools/perf/tests/cpumap.c                     |   6 +-
 tools/perf/tests/event_update.c               |   6 +-
 tools/perf/tests/mem2node.c                   |   2 +-
 tools/perf/tests/mmap-basic.c                 |   4 +-
 tools/perf/tests/openat-syscall-all-cpus.c    |  39 +-
 tools/perf/tests/stat.c                       |   3 +-
 tools/perf/tests/topology.c                   |  43 +-
 tools/perf/util/affinity.c                    |   2 +-
 tools/perf/util/auxtrace.c                    |  12 +-
 tools/perf/util/auxtrace.h                    |   5 +-
 tools/perf/util/bpf_counter.c                 |  16 +-
 tools/perf/util/bpf_counter.h                 |   4 +-
 tools/perf/util/counts.c                      |   8 +-
 tools/perf/util/counts.h                      |  14 +-
 tools/perf/util/cpumap.c                      | 253 ++++-----
 tools/perf/util/cpumap.h                      | 116 ++--
 tools/perf/util/cputopo.c                     |   6 +-
 tools/perf/util/env.c                         |  29 +-
 tools/perf/util/env.h                         |   3 +-
 tools/perf/util/evlist.c                      | 148 ++---
 tools/perf/util/evlist.h                      |  50 +-
 tools/perf/util/evsel.c                       | 143 ++---
 tools/perf/util/evsel.h                       |  27 +-
 tools/perf/util/expr.c                        |   2 +-
 tools/perf/util/header.c                      |   6 +-
 tools/perf/util/mmap.c                        |  19 +-
 tools/perf/util/mmap.h                        |   3 +-
 tools/perf/util/perf_api_probe.c              |  15 +-
 tools/perf/util/python.c                      |   4 +-
 tools/perf/util/record.c                      |  11 +-
 .../scripting-engines/trace-event-python.c    |   6 +-
 tools/perf/util/session.c                     |  10 +-
 tools/perf/util/stat-display.c                | 138 ++---
 tools/perf/util/stat-shadow.c                 | 308 +++++------
 tools/perf/util/stat.c                        |  47 +-
 tools/perf/util/stat.h                        |   9 +-
 tools/perf/util/svghelper.c                   |   6 +-
 tools/perf/util/synthetic-events.c            |  12 +-
 tools/perf/util/synthetic-events.h            |   3 +-
 tools/perf/util/util.h                        |   5 +-
 69 files changed, 1333 insertions(+), 1155 deletions(-)

-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:04 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:04 -0800
Subject: [PATCH v4 01/48] libperf: Add comments to perf_cpu_map.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-2-irogers@google.com>

A particular observed problem is confusing the index with the CPU value,
documentation should hopefully reduce this type of problem.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/include/internal/cpumap.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
index 840d4032587b..4054169c12c5 100644
--- a/tools/lib/perf/include/internal/cpumap.h
+++ b/tools/lib/perf/include/internal/cpumap.h
@@ -4,9 +4,18 @@
 
 #include <linux/refcount.h>
 
+/**
+ * A sized, reference counted, sorted array of integers representing CPU
+ * numbers. This is commonly used to capture which CPUs a PMU is associated
+ * with. The indices into the cpumap are frequently used as they avoid having
+ * gaps if CPU numbers were used. For events associated with a pid, rather than
+ * a CPU, a single dummy map with an entry of -1 is used.
+ */
 struct perf_cpu_map {
 	refcount_t	refcnt;
+	/** Length of the map array. */
 	int		nr;
+	/** The CPU values. */
 	int		map[];
 };
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:05 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:05 -0800
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a cpu.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-3-irogers@google.com>

The cpu_map and index can get confused. Add variants of the cpu_map__get
routines that are passed a cpu. Make the existing cpu_map__get routines
use the new functions with a view to remove them when no longer used.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.c | 79 +++++++++++++++++++++++-----------------
 tools/perf/util/cpumap.h |  6 ++-
 2 files changed, 51 insertions(+), 34 deletions(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 87d3eca9b872..49fba2c53822 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -128,21 +128,23 @@ int cpu_map__get_socket_id(int cpu)
 	return ret ?: value;
 }
 
-struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
-					void *data __maybe_unused)
+struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
 {
-	int cpu;
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
-	if (idx > map->nr)
-		return id;
-
-	cpu = map->map[idx];
-
 	id.socket = cpu_map__get_socket_id(cpu);
 	return id;
 }
 
+struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
+				       void *data)
+{
+	if (idx < 0 || idx > map->nr)
+		return cpu_map__empty_aggr_cpu_id();
+
+	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
+}
+
 static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
 {
 	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
@@ -200,15 +202,10 @@ int cpu_map__get_die_id(int cpu)
 	return ret ?: value;
 }
 
-struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data)
+struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 {
-	int cpu, die;
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
-
-	if (idx > map->nr)
-		return id;
-
-	cpu = map->map[idx];
+	struct aggr_cpu_id id;
+	int die;
 
 	die = cpu_map__get_die_id(cpu);
 	/* There is no die_id on legacy system. */
@@ -220,7 +217,7 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
 	 * with the socket ID and then add die to
 	 * make a unique ID.
 	 */
-	id = cpu_map__get_socket(map, idx, data);
+	id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
 	if (cpu_map__aggr_cpu_id_is_empty(id))
 		return id;
 
@@ -228,6 +225,15 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
 	return id;
 }
 
+struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
+				    void *data)
+{
+	if (idx < 0 || idx > map->nr)
+		return cpu_map__empty_aggr_cpu_id();
+
+	return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
+}
+
 int cpu_map__get_core_id(int cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
@@ -239,20 +245,13 @@ int cpu_map__get_node_id(int cpu)
 	return cpu__get_node(cpu);
 }
 
-struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
+struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 {
-	int cpu;
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
-
-	if (idx > map->nr)
-		return id;
-
-	cpu = map->map[idx];
-
-	cpu = cpu_map__get_core_id(cpu);
+	struct aggr_cpu_id id;
+	int core = cpu_map__get_core_id(cpu);
 
 	/* cpu_map__get_die returns a struct with socket and die set*/
-	id = cpu_map__get_die(map, idx, data);
+	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
 	if (cpu_map__aggr_cpu_id_is_empty(id))
 		return id;
 
@@ -260,19 +259,33 @@ struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *da
 	 * core_id is relative to socket and die, we need a global id.
 	 * So we combine the result from cpu_map__get_die with the core id
 	 */
-	id.core = cpu;
+	id.core = core;
 	return id;
+
 }
 
-struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data __maybe_unused)
+struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
+{
+	if (idx < 0 || idx > map->nr)
+		return cpu_map__empty_aggr_cpu_id();
+
+	return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
+}
+
+struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
+	id.node = cpu_map__get_node_id(cpu);
+	return id;
+}
+
+struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
+{
 	if (idx < 0 || idx >= map->nr)
-		return id;
+		return cpu_map__empty_aggr_cpu_id();
 
-	id.node = cpu_map__get_node_id(map->map[idx]);
-	return id;
+	return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
 }
 
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index a27eeaf086e8..c62d67704425 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -31,13 +31,17 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
 int cpu_map__get_socket_id(int cpu);
+struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_die_id(int cpu);
+struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_core_id(int cpu);
+struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_node_id(int cpu);
-struct aggr_cpu_id  cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
+struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
+struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
 int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
 int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:06 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:06 -0800
Subject: [PATCH v4 03/48] perf stat: Correct aggregation CPU map
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-4-irogers@google.com>

Switch the perf_cpu_map in aggr_update_shadow from
the evlist to the counter's cpu map, so the index is appropriate. This
addresses a problem where uncore counts, with a cpumap like:
$ cat /sys/devices/uncore_imc_0/cpumask
0,18
Don't aggregate counts in CPUs based on the index of those values in the
cpumap (0 and 1) but on the actual CPU (0 and 18). Thereby correcting
metric calculations in per-socket mode for counters without a full
cpumask.

On a SkylakeX with a tweaked DRAM_BW_Use metric, to remove unnecessary
scaling, this gives:

Before:
$ /perf stat --per-socket -M DRAM_BW_Use -I 1000
     1.001102293 S0        1              27.01 MiB  uncore_imc/cas_count_write/ #   103.00 DRAM_BW_Use
     1.001102293 S0        1              30.22 MiB  uncore_imc/cas_count_read/
     1.001102293 S0        1      1,001,102,293 ns   duration_time
     1.001102293 S1        1              20.10 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
     1.001102293 S1        1              32.74 MiB  uncore_imc/cas_count_read/
     1.001102293 S1        0      <not counted> ns   duration_time
     2.003517973 S0        1              83.04 MiB  uncore_imc/cas_count_write/ #   920.00 DRAM_BW_Use
     2.003517973 S0        1             145.95 MiB  uncore_imc/cas_count_read/
     2.003517973 S0        1      1,002,415,680 ns   duration_time
     2.003517973 S1        1             302.45 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
     2.003517973 S1        1             290.99 MiB  uncore_imc/cas_count_read/
     2.003517973 S1        0      <not counted> ns   duration_time

After:
$ perf stat --per-socket -M DRAM_BW_Use -I 1000
     1.001080840 S0        1              24.96 MiB  uncore_imc/cas_count_write/ #    54.00 DRAM_BW_Use
     1.001080840 S0        1              33.64 MiB  uncore_imc/cas_count_read/
     1.001080840 S0        1      1,001,080,840 ns   duration_time
     1.001080840 S1        1              42.43 MiB  uncore_imc/cas_count_write/ #    84.00 DRAM_BW_Use
     1.001080840 S1        1              47.05 MiB  uncore_imc/cas_count_read/
     1.001080840 S1        0      <not counted> ns   duration_time

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 588601000f3f..b0fa81ffce61 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -526,7 +526,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,
 		evlist__for_each_entry(evlist, counter) {
 			val = 0;
 			for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
-				s2 = config->aggr_get_id(config, evlist->core.cpus, cpu);
+				s2 = config->aggr_get_id(config, evsel__cpus(counter), cpu);
 				if (!cpu_map__compare_aggr_cpu_id(s2, id))
 					continue;
 				val += perf_counts(counter->counts, cpu, 0)->val;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:07 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:07 -0800
Subject: [PATCH v4 04/48] perf stat: Switch aggregation to use for_each loop
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-5-irogers@google.com>

Tidy up the use of cpu and index to hopefully make the code less error
prone. Avoid unused warnings with (void) which will be removed in a
later patch.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 48 +++++++++++++++++++---------------
 1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index b0fa81ffce61..efab39a759ff 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -330,8 +330,8 @@ static void print_metric_header(struct perf_stat_config *config,
 static int first_shadow_cpu(struct perf_stat_config *config,
 			    struct evsel *evsel, struct aggr_cpu_id id)
 {
-	struct evlist *evlist = evsel->evlist;
-	int i;
+	struct perf_cpu_map *cpus;
+	int cpu, idx;
 
 	if (config->aggr_mode == AGGR_NONE)
 		return id.core;
@@ -339,14 +339,11 @@ static int first_shadow_cpu(struct perf_stat_config *config,
 	if (!config->aggr_get_id)
 		return 0;
 
-	for (i = 0; i < evsel__nr_cpus(evsel); i++) {
-		int cpu2 = evsel__cpus(evsel)->map[i];
-
-		if (cpu_map__compare_aggr_cpu_id(
-					config->aggr_get_id(config, evlist->core.cpus, cpu2),
-					id)) {
-			return cpu2;
-		}
+	cpus = evsel__cpus(evsel);
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpus, idx),
+						 id))
+			return cpu;
 	}
 	return 0;
 }
@@ -516,20 +513,23 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
 static void aggr_update_shadow(struct perf_stat_config *config,
 			       struct evlist *evlist)
 {
-	int cpu, s;
+	int cpu, idx, s;
 	struct aggr_cpu_id s2, id;
 	u64 val;
 	struct evsel *counter;
+	struct perf_cpu_map *cpus;
 
 	for (s = 0; s < config->aggr_map->nr; s++) {
 		id = config->aggr_map->map[s];
 		evlist__for_each_entry(evlist, counter) {
+			cpus = evsel__cpus(counter);
 			val = 0;
-			for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
-				s2 = config->aggr_get_id(config, evsel__cpus(counter), cpu);
+			perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+				(void)cpu;
+				s2 = config->aggr_get_id(config, cpus, idx);
 				if (!cpu_map__compare_aggr_cpu_id(s2, id))
 					continue;
-				val += perf_counts(counter->counts, cpu, 0)->val;
+				val += perf_counts(counter->counts, idx, 0)->val;
 			}
 			perf_stat__update_shadow_stats(counter, val,
 					first_shadow_cpu(config, counter, id),
@@ -634,18 +634,21 @@ static void aggr_cb(struct perf_stat_config *config,
 		    struct evsel *counter, void *data, bool first)
 {
 	struct aggr_data *ad = data;
-	int cpu;
+	int idx, cpu;
+	struct perf_cpu_map *cpus;
 	struct aggr_cpu_id s2;
 
-	for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
+	cpus = evsel__cpus(counter);
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		struct perf_counts_values *counts;
 
-		s2 = config->aggr_get_id(config, evsel__cpus(counter), cpu);
+		(void)cpu;
+		s2 = config->aggr_get_id(config, cpus, idx);
 		if (!cpu_map__compare_aggr_cpu_id(s2, ad->id))
 			continue;
 		if (first)
 			ad->nr++;
-		counts = perf_counts(counter->counts, cpu, 0);
+		counts = perf_counts(counter->counts, idx, 0);
 		/*
 		 * When any result is bad, make them all to give
 		 * consistent output in interval mode.
@@ -1208,10 +1211,13 @@ static void print_percore_thread(struct perf_stat_config *config,
 {
 	int s;
 	struct aggr_cpu_id s2, id;
+	struct perf_cpu_map *cpus;
 	bool first = true;
+	int idx, cpu;
 
-	for (int i = 0; i < evsel__nr_cpus(counter); i++) {
-		s2 = config->aggr_get_id(config, evsel__cpus(counter), i);
+	cpus = evsel__cpus(counter);
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		s2 = config->aggr_get_id(config, cpus, idx);
 		for (s = 0; s < config->aggr_map->nr; s++) {
 			id = config->aggr_map->map[s];
 			if (cpu_map__compare_aggr_cpu_id(s2, id))
@@ -1220,7 +1226,7 @@ static void print_percore_thread(struct perf_stat_config *config,
 
 		print_counter_aggrdata(config, counter, s,
 				       prefix, false,
-				       &first, i);
+				       &first, cpu);
 	}
 }
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:08 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:08 -0800
Subject: [PATCH v4 05/48] perf stat: Switch to cpu version of cpu_map__get
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-6-irogers@google.com>

Avoid bugs where the wrong index is passed with the cpu_map.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c      | 93 +++++++++++++++++++---------------
 tools/perf/util/stat-display.c | 11 ++--
 tools/perf/util/stat.h         |  3 +-
 3 files changed, 57 insertions(+), 50 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f6ca2b054c5b..9791ae9b1a53 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1323,69 +1323,63 @@ static struct option stat_options[] = {
 };
 
 static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
-				 struct perf_cpu_map *map, int cpu)
+						int cpu)
 {
-	return cpu_map__get_socket(map, cpu, NULL);
+	return cpu_map__get_socket_aggr_by_cpu(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
-			      struct perf_cpu_map *map, int cpu)
+					     int cpu)
 {
-	return cpu_map__get_die(map, cpu, NULL);
+	return cpu_map__get_die_aggr_by_cpu(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
-			       struct perf_cpu_map *map, int cpu)
+					      int cpu)
 {
-	return cpu_map__get_core(map, cpu, NULL);
+	return cpu_map__get_core_aggr_by_cpu(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused,
-			       struct perf_cpu_map *map, int cpu)
+					      int cpu)
 {
-	return cpu_map__get_node(map, cpu, NULL);
+	return cpu_map__get_node_aggr_by_cpu(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
-			       aggr_get_id_t get_id, struct perf_cpu_map *map, int idx)
+					      aggr_get_id_t get_id, int cpu)
 {
-	int cpu;
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
-	if (idx >= map->nr)
-		return id;
-
-	cpu = map->map[idx];
-
 	if (cpu_map__aggr_cpu_id_is_empty(config->cpus_aggr_map->map[cpu]))
-		config->cpus_aggr_map->map[cpu] = get_id(config, map, idx);
+		config->cpus_aggr_map->map[cpu] = get_id(config, cpu);
 
 	id = config->cpus_aggr_map->map[cpu];
 	return id;
 }
 
 static struct aggr_cpu_id perf_stat__get_socket_cached(struct perf_stat_config *config,
-					struct perf_cpu_map *map, int idx)
+						       int cpu)
 {
-	return perf_stat__get_aggr(config, perf_stat__get_socket, map, idx);
+	return perf_stat__get_aggr(config, perf_stat__get_socket, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *config,
-					struct perf_cpu_map *map, int idx)
+						    int cpu)
 {
-	return perf_stat__get_aggr(config, perf_stat__get_die, map, idx);
+	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_core_cached(struct perf_stat_config *config,
-				      struct perf_cpu_map *map, int idx)
+						     int cpu)
 {
-	return perf_stat__get_aggr(config, perf_stat__get_core, map, idx);
+	return perf_stat__get_aggr(config, perf_stat__get_core, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *config,
-				      struct perf_cpu_map *map, int idx)
+						     int cpu)
 {
-	return perf_stat__get_aggr(config, perf_stat__get_node, map, idx);
+	return perf_stat__get_aggr(config, perf_stat__get_node, cpu);
 }
 
 static bool term_percore_set(void)
@@ -1483,8 +1477,9 @@ static void perf_stat__exit_aggr_mode(void)
 	stat_config.cpus_aggr_map = NULL;
 }
 
-static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *map, int idx)
+static inline int perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
 {
+	struct perf_env *env = data;
 	int cpu;
 
 	if (idx > map->nr)
@@ -1498,10 +1493,9 @@ static inline int perf_env__get_cpu(struct perf_env *env, struct perf_cpu_map *m
 	return cpu;
 }
 
-static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
+static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
-	int cpu = perf_env__get_cpu(env, map, idx);
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
 	if (cpu != -1)
@@ -1510,11 +1504,15 @@ static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
+static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
+{
+	return perf_env__get_socket_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
+}
+
+static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
-	int cpu = perf_env__get_cpu(env, map, idx);
 
 	if (cpu != -1) {
 		/*
@@ -1529,11 +1527,15 @@ static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, v
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
+static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
+{
+	return perf_env__get_die_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
+}
+
+static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
-	int cpu = perf_env__get_cpu(env, map, idx);
 
 	if (cpu != -1) {
 		/*
@@ -1549,15 +1551,24 @@ static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx,
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
+static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
+{
+	return perf_env__get_core_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
+}
+
+static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 {
-	int cpu = perf_env__get_cpu(data, map, idx);
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
 	id.node = perf_env__numa_node(data, cpu);
 	return id;
 }
 
+static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
+{
+	return perf_env__get_node_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
+}
+
 static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
 				      struct cpu_aggr_map **sockp)
 {
@@ -1583,26 +1594,26 @@ static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *c
 }
 
 static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
-				      struct perf_cpu_map *map, int idx)
+						     int cpu)
 {
-	return perf_env__get_socket(map, idx, &perf_stat.session->header.env);
+	return perf_env__get_socket_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused,
-				   struct perf_cpu_map *map, int idx)
+						  int cpu)
 {
-	return perf_env__get_die(map, idx, &perf_stat.session->header.env);
+	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
 static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
-				    struct perf_cpu_map *map, int idx)
+						   int cpu)
 {
-	return perf_env__get_core(map, idx, &perf_stat.session->header.env);
+	return perf_env__get_core_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
 static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused,
-				    struct perf_cpu_map *map, int idx)
+						   int cpu)
 {
-	return perf_env__get_node(map, idx, &perf_stat.session->header.env);
+	return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
 static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index efab39a759ff..6c40b91d5e32 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -341,8 +341,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,
 
 	cpus = evsel__cpus(evsel);
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-		if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpus, idx),
-						 id))
+		if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpu), id))
 			return cpu;
 	}
 	return 0;
@@ -525,8 +524,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,
 			cpus = evsel__cpus(counter);
 			val = 0;
 			perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-				(void)cpu;
-				s2 = config->aggr_get_id(config, cpus, idx);
+				s2 = config->aggr_get_id(config, cpu);
 				if (!cpu_map__compare_aggr_cpu_id(s2, id))
 					continue;
 				val += perf_counts(counter->counts, idx, 0)->val;
@@ -642,8 +640,7 @@ static void aggr_cb(struct perf_stat_config *config,
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		struct perf_counts_values *counts;
 
-		(void)cpu;
-		s2 = config->aggr_get_id(config, cpus, idx);
+		s2 = config->aggr_get_id(config, cpu);
 		if (!cpu_map__compare_aggr_cpu_id(s2, ad->id))
 			continue;
 		if (first)
@@ -1217,7 +1214,7 @@ static void print_percore_thread(struct perf_stat_config *config,
 
 	cpus = evsel__cpus(counter);
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-		s2 = config->aggr_get_id(config, cpus, idx);
+		s2 = config->aggr_get_id(config, cpu);
 		for (s = 0; s < config->aggr_map->nr; s++) {
 			id = config->aggr_map->map[s];
 			if (cpu_map__compare_aggr_cpu_id(s2, id))
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 32c8527de347..32cf24186229 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -108,8 +108,7 @@ struct runtime_stat {
 	struct rblist value_list;
 };
 
-typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config,
-			     struct perf_cpu_map *m, int cpu);
+typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, int cpu);
 
 struct perf_stat_config {
 	enum aggr_mode		 aggr_mode;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:09 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:09 -0800
Subject: [PATCH v4 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-7-irogers@google.com>

Avoid error prone cpu_map + idx variant. Remove now unused functions.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c | 28 ++++------------------------
 tools/perf/util/cpumap.c  | 12 ++++++------
 tools/perf/util/cpumap.h  |  2 +-
 3 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9791ae9b1a53..6b985abaa2d2 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1504,11 +1504,6 @@ static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
-{
-	return perf_env__get_socket_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
-}
-
 static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
@@ -1527,11 +1522,6 @@ static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
-{
-	return perf_env__get_die_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
-}
-
 static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
@@ -1551,11 +1541,6 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
-{
-	return perf_env__get_core_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
-}
-
 static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 {
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
@@ -1564,33 +1549,28 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
-{
-	return perf_env__get_node_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
-}
-
 static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
 				      struct cpu_aggr_map **sockp)
 {
-	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
+	return cpu_map__build_map(cpus, sockp, perf_env__get_socket_aggr_by_cpu, env);
 }
 
 static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
 				   struct cpu_aggr_map **diep)
 {
-	return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
+	return cpu_map__build_map(cpus, diep, perf_env__get_die_aggr_by_cpu, env);
 }
 
 static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
 				    struct cpu_aggr_map **corep)
 {
-	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
+	return cpu_map__build_map(cpus, corep, perf_env__get_core_aggr_by_cpu, env);
 }
 
 static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
 				    struct cpu_aggr_map **nodep)
 {
-	return cpu_map__build_map(cpus, nodep, perf_env__get_node, env);
+	return cpu_map__build_map(cpus, nodep, perf_env__get_node_aggr_by_cpu, env);
 }
 
 static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 49fba2c53822..feaf34b25efc 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -163,7 +163,7 @@ static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
 }
 
 int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
-		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
+		       struct aggr_cpu_id (*f)(int cpu, void *data),
 		       void *data)
 {
 	int nr = cpus->nr;
@@ -178,7 +178,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 	c->nr = 0;
 
 	for (cpu = 0; cpu < nr; cpu++) {
-		s1 = f(cpus, cpu, data);
+		s1 = f(cpu, data);
 		for (s2 = 0; s2 < c->nr; s2++) {
 			if (cpu_map__compare_aggr_cpu_id(s1, c->map[s2]))
 				break;
@@ -290,22 +290,22 @@ struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *da
 
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
 {
-	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL);
+	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket_aggr_by_cpu, NULL);
 }
 
 int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep)
 {
-	return cpu_map__build_map(cpus, diep, cpu_map__get_die, NULL);
+	return cpu_map__build_map(cpus, diep, cpu_map__get_die_aggr_by_cpu, NULL);
 }
 
 int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep)
 {
-	return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL);
+	return cpu_map__build_map(cpus, corep, cpu_map__get_core_aggr_by_cpu, NULL);
 }
 
 int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **numap)
 {
-	return cpu_map__build_map(cpus, numap, cpu_map__get_node, NULL);
+	return cpu_map__build_map(cpus, numap, cpu_map__get_node_aggr_by_cpu, NULL);
 }
 
 /* setup simple routines to easily access node numbers given a cpu number */
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index c62d67704425..9648816c4255 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -63,7 +63,7 @@ int cpu__max_present_cpu(void);
 int cpu__get_node(int cpu);
 
 int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
-		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
+		       struct aggr_cpu_id (*f)(int cpu, void *data),
 		       void *data);
 
 int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:10 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:10 -0800
Subject: [PATCH v4 07/48] perf cpumap: Remove map+index get_socket
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-8-irogers@google.com>

Migrate final users to appropriate cpu variant.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/topology.c | 2 +-
 tools/perf/util/cpumap.c    | 9 ---------
 tools/perf/util/cpumap.h    | 1 -
 tools/perf/util/stat.c      | 2 +-
 4 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 869986139146..69a64074b897 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -150,7 +150,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that socket ID contains only socket
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_socket(map, i, NULL);
+		id = cpu_map__get_socket_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
 			session->header.env.cpu[map->map[i]].socket_id == id.socket);
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index feaf34b25efc..342a5eaee9d3 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -136,15 +136,6 @@ struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_u
 	return id;
 }
 
-struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
-				       void *data)
-{
-	if (idx < 0 || idx > map->nr)
-		return cpu_map__empty_aggr_cpu_id();
-
-	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
-}
-
 static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
 {
 	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 9648816c4255..a53af24301d2 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -32,7 +32,6 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
 int cpu_map__get_socket_id(int cpu);
 struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_die_id(int cpu);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 09ea334586f2..9eca1111fa52 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -328,7 +328,7 @@ static int check_per_pkg(struct evsel *counter,
 	if (!(vals->run && vals->ena))
 		return 0;
 
-	s = cpu_map__get_socket(cpus, cpu, NULL).socket;
+	s = cpu_map__get_socket_id(cpu);
 	if (s < 0)
 		return -1;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:11 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:11 -0800
Subject: [PATCH v4 08/48] perf cpumap: Remove map+index get_die
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-9-irogers@google.com>

Migrate final users to appropriate cpu variant.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/topology.c | 2 +-
 tools/perf/util/cpumap.c    | 9 ---------
 tools/perf/util/cpumap.h    | 1 -
 tools/perf/util/stat.c      | 2 +-
 4 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 69a64074b897..ce085b6f379b 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -136,7 +136,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that die ID contains socket and die
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_die(map, i, NULL);
+		id = cpu_map__get_die_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
 			session->header.env.cpu[map->map[i]].socket_id == id.socket);
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 342a5eaee9d3..ff91c32da688 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -216,15 +216,6 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
-				    void *data)
-{
-	if (idx < 0 || idx > map->nr)
-		return cpu_map__empty_aggr_cpu_id();
-
-	return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
-}
-
 int cpu_map__get_core_id(int cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index a53af24301d2..365ed69699e1 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -34,7 +34,6 @@ int cpu_map__get_socket_id(int cpu);
 struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
 int cpu_map__get_die_id(int cpu);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_core_id(int cpu);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 9eca1111fa52..5ed99bcfe91e 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -336,7 +336,7 @@ static int check_per_pkg(struct evsel *counter,
 	 * On multi-die system, die_id > 0. On no-die system, die_id = 0.
 	 * We use hashmap(socket, die) to check the used socket+die pair.
 	 */
-	d = cpu_map__get_die(cpus, cpu, NULL).die;
+	d = cpu_map__get_die_id(cpu);
 	if (d < 0)
 		return -1;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:12 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:12 -0800
Subject: [PATCH v4 09/48] perf cpumap: Remove map+index get_core
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-10-irogers@google.com>

Migrate final users to appropriate cpu variant.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/topology.c | 2 +-
 tools/perf/util/cpumap.c    | 8 --------
 tools/perf/util/cpumap.h    | 1 -
 3 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index ce085b6f379b..9a671670415a 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -121,7 +121,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that core ID contains socket, die and core
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_core(map, i, NULL);
+		id = cpu_map__get_core_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
 			session->header.env.cpu[map->map[i]].core_id == id.core);
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index ff91c32da688..e8149bcf8bfa 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -246,14 +246,6 @@ struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 
 }
 
-struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
-{
-	if (idx < 0 || idx > map->nr)
-		return cpu_map__empty_aggr_cpu_id();
-
-	return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
-}
-
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 365ed69699e1..7e1829468bd6 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -36,7 +36,6 @@ int cpu_map__get_die_id(int cpu);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
 int cpu_map__get_core_id(int cpu);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__get_node_id(int cpu);
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:13 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:13 -0800
Subject: [PATCH v4 10/48] perf cpumap: Remove map+index get_node
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-11-irogers@google.com>

Migrate final users to appropriate cpu variant.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/topology.c | 2 +-
 tools/perf/util/cpumap.c    | 8 --------
 tools/perf/util/cpumap.h    | 1 -
 3 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 9a671670415a..5992b323c4f5 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -162,7 +162,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that node ID contains only node
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_node(map, i, NULL);
+		id = cpu_map__get_node_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
 			cpu__get_node(map->map[i]) == id.node);
 		TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index e8149bcf8bfa..f67b2e7aac13 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -254,14 +254,6 @@ struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unu
 	return id;
 }
 
-struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
-{
-	if (idx < 0 || idx >= map->nr)
-		return cpu_map__empty_aggr_cpu_id();
-
-	return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
-}
-
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
 {
 	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket_aggr_by_cpu, NULL);
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 7e1829468bd6..f0121dd4fdcb 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -38,7 +38,6 @@ int cpu_map__get_core_id(int cpu);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
 int cpu_map__get_node_id(int cpu);
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
 int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
 int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:14 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:14 -0800
Subject: [PATCH v4 11/48] perf cpumap: Add comments to aggr_cpu_id
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-12-irogers@google.com>

This code is already tested in topology.c.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index f0121dd4fdcb..edd93e1db36a 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -7,11 +7,20 @@
 #include <internal/cpumap.h>
 #include <perf/cpumap.h>
 
+/** Identify where counts are aggregated, -1 implies not to aggregate. */
 struct aggr_cpu_id {
+	/** A value in the range 0 to number of threads. */
 	int thread;
+	/** The numa node X as read from /sys/devices/system/node/nodeX. */
 	int node;
+	/**
+	 * The socket number as read from
+	 * /sys/devices/system/cpu/cpuX/topology/physical_package_id.
+	 */
 	int socket;
+	/** The die id as read from /sys/devices/system/cpu/cpuX/topology/die_id. */
 	int die;
+	/** The core id as read from /sys/devices/system/cpu/cpuX/topology/core_id. */
 	int core;
 };
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:15 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:15 -0800
Subject: [PATCH v4 12/48] perf cpumap: Remove unused cpu_map__socket
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-13-irogers@google.com>

Unused function so remove.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.h | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index edd93e1db36a..22e53fd54657 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -53,13 +53,6 @@ int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **cor
 int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **nodep);
 const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */
 
-static inline int cpu_map__socket(struct perf_cpu_map *sock, int s)
-{
-	if (!sock || s > sock->nr || s < 0)
-		return 0;
-	return sock->map[s];
-}
-
 int cpu__setup_cpunode_map(void);
 
 int cpu__max_node(void);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:16 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:16 -0800
Subject: [PATCH v4 13/48] perf cpumap: Simplify equal function name.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-14-irogers@google.com>

Rename cpu_map__compare_aggr_cpu_id to aggr_cpu_id__equal, the cpu_map
part of the name is misleading. Equal better describes the function than
compare.
Switch to const pointer rather than value as struct given the number of
variables in aggr_cpu_id.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.c       | 14 +++++++-------
 tools/perf/util/cpumap.h       |  2 +-
 tools/perf/util/stat-display.c | 18 ++++++++++--------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index f67b2e7aac13..8fa00a6221c8 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -171,7 +171,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 	for (cpu = 0; cpu < nr; cpu++) {
 		s1 = f(cpu, data);
 		for (s2 = 0; s2 < c->nr; s2++) {
-			if (cpu_map__compare_aggr_cpu_id(s1, c->map[s2]))
+			if (aggr_cpu_id__equal(&s1, &c->map[s2]))
 				break;
 		}
 		if (s2 == c->nr) {
@@ -593,13 +593,13 @@ const struct perf_cpu_map *cpu_map__online(void) /* thread unsafe */
 	return online;
 }
 
-bool cpu_map__compare_aggr_cpu_id(struct aggr_cpu_id a, struct aggr_cpu_id b)
+bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b)
 {
-	return a.thread == b.thread &&
-		a.node == b.node &&
-		a.socket == b.socket &&
-		a.die == b.die &&
-		a.core == b.core;
+	return a->thread == b->thread &&
+		a->node == b->node &&
+		a->socket == b->socket &&
+		a->die == b->die &&
+		a->core == b->core;
 }
 
 bool cpu_map__aggr_cpu_id_is_empty(struct aggr_cpu_id a)
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 22e53fd54657..652b76c69376 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -67,7 +67,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
 bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
 
-bool cpu_map__compare_aggr_cpu_id(struct aggr_cpu_id a, struct aggr_cpu_id b);
+bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
 bool cpu_map__aggr_cpu_id_is_empty(struct aggr_cpu_id a);
 struct aggr_cpu_id cpu_map__empty_aggr_cpu_id(void);
 
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 6c40b91d5e32..0241436bb1fb 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -328,20 +328,22 @@ static void print_metric_header(struct perf_stat_config *config,
 }
 
 static int first_shadow_cpu(struct perf_stat_config *config,
-			    struct evsel *evsel, struct aggr_cpu_id id)
+			    struct evsel *evsel, const struct aggr_cpu_id *id)
 {
 	struct perf_cpu_map *cpus;
 	int cpu, idx;
 
 	if (config->aggr_mode == AGGR_NONE)
-		return id.core;
+		return id->core;
 
 	if (!config->aggr_get_id)
 		return 0;
 
 	cpus = evsel__cpus(evsel);
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
-		if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpu), id))
+		struct aggr_cpu_id cpu_id = config->aggr_get_id(config, cpu);
+
+		if (aggr_cpu_id__equal(&cpu_id, id))
 			return cpu;
 	}
 	return 0;
@@ -501,7 +503,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
 	}
 
 	perf_stat__print_shadow_stats(config, counter, uval,
-				first_shadow_cpu(config, counter, id),
+				first_shadow_cpu(config, counter, &id),
 				&out, &config->metric_events, st);
 	if (!config->csv_output && !config->metric_only) {
 		print_noise(config, counter, noise);
@@ -525,12 +527,12 @@ static void aggr_update_shadow(struct perf_stat_config *config,
 			val = 0;
 			perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 				s2 = config->aggr_get_id(config, cpu);
-				if (!cpu_map__compare_aggr_cpu_id(s2, id))
+				if (!aggr_cpu_id__equal(&s2, &id))
 					continue;
 				val += perf_counts(counter->counts, idx, 0)->val;
 			}
 			perf_stat__update_shadow_stats(counter, val,
-					first_shadow_cpu(config, counter, id),
+					first_shadow_cpu(config, counter, &id),
 					&rt_stat);
 		}
 	}
@@ -641,7 +643,7 @@ static void aggr_cb(struct perf_stat_config *config,
 		struct perf_counts_values *counts;
 
 		s2 = config->aggr_get_id(config, cpu);
-		if (!cpu_map__compare_aggr_cpu_id(s2, ad->id))
+		if (!aggr_cpu_id__equal(&s2, &ad->id))
 			continue;
 		if (first)
 			ad->nr++;
@@ -1217,7 +1219,7 @@ static void print_percore_thread(struct perf_stat_config *config,
 		s2 = config->aggr_get_id(config, cpu);
 		for (s = 0; s < config->aggr_map->nr; s++) {
 			id = config->aggr_map->map[s];
-			if (cpu_map__compare_aggr_cpu_id(s2, id))
+			if (aggr_cpu_id__equal(&s2, &id))
 				break;
 		}
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:17 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:17 -0800
Subject: [PATCH v4 14/48] perf cpumap: Rename empty functions.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-15-irogers@google.com>

Remove cpu_map from name as a cpu_map isn't used. Pass a const pointer
rather than by value to avoid unnecessary copying.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c      | 12 ++++++------
 tools/perf/util/cpumap.c       | 24 ++++++++++++------------
 tools/perf/util/cpumap.h       |  4 ++--
 tools/perf/util/stat-display.c | 10 +++++-----
 4 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6b985abaa2d2..d229fb71b577 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1349,9 +1349,9 @@ static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __
 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
 					      aggr_get_id_t get_id, int cpu)
 {
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	if (cpu_map__aggr_cpu_id_is_empty(config->cpus_aggr_map->map[cpu]))
+	if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu]))
 		config->cpus_aggr_map->map[cpu] = get_id(config, cpu);
 
 	id = config->cpus_aggr_map->map[cpu];
@@ -1496,7 +1496,7 @@ static inline int perf_env__get_cpu(void *data, struct perf_cpu_map *map, int id
 static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	if (cpu != -1)
 		id.socket = env->cpu[cpu].socket_id;
@@ -1507,7 +1507,7 @@ static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
 static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	if (cpu != -1) {
 		/*
@@ -1525,7 +1525,7 @@ static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
 static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
 {
 	struct perf_env *env = data;
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	if (cpu != -1) {
 		/*
@@ -1543,7 +1543,7 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
 
 static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 {
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	id.node = perf_env__numa_node(data, cpu);
 	return id;
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 8fa00a6221c8..b3e1304aca0c 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -104,7 +104,7 @@ struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr)
 
 		cpus->nr = nr;
 		for (i = 0; i < nr; i++)
-			cpus->map[i] = cpu_map__empty_aggr_cpu_id();
+			cpus->map[i] = aggr_cpu_id__empty();
 
 		refcount_set(&cpus->refcnt, 1);
 	}
@@ -130,7 +130,7 @@ int cpu_map__get_socket_id(int cpu)
 
 struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
 {
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	id.socket = cpu_map__get_socket_id(cpu);
 	return id;
@@ -209,7 +209,7 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 	 * make a unique ID.
 	 */
 	id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
-	if (cpu_map__aggr_cpu_id_is_empty(id))
+	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
 	id.die = die;
@@ -234,7 +234,7 @@ struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 
 	/* cpu_map__get_die returns a struct with socket and die set*/
 	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
-	if (cpu_map__aggr_cpu_id_is_empty(id))
+	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
 	/*
@@ -248,7 +248,7 @@ struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
 {
-	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
+	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
 	id.node = cpu_map__get_node_id(cpu);
 	return id;
@@ -602,16 +602,16 @@ bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b
 		a->core == b->core;
 }
 
-bool cpu_map__aggr_cpu_id_is_empty(struct aggr_cpu_id a)
+bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
 {
-	return a.thread == -1 &&
-		a.node == -1 &&
-		a.socket == -1 &&
-		a.die == -1 &&
-		a.core == -1;
+	return a->thread == -1 &&
+		a->node == -1 &&
+		a->socket == -1 &&
+		a->die == -1 &&
+		a->core == -1;
 }
 
-struct aggr_cpu_id cpu_map__empty_aggr_cpu_id(void)
+struct aggr_cpu_id aggr_cpu_id__empty(void)
 {
 	struct aggr_cpu_id ret = {
 		.thread = -1,
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 652b76c69376..9589b0001a28 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -68,7 +68,7 @@ int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
 bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
 
 bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
-bool cpu_map__aggr_cpu_id_is_empty(struct aggr_cpu_id a);
-struct aggr_cpu_id cpu_map__empty_aggr_cpu_id(void);
+bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a);
+struct aggr_cpu_id aggr_cpu_id__empty(void);
 
 #endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 0241436bb1fb..870b1db71fbc 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -698,7 +698,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
 
 	uval = val * counter->scale;
 	if (cpu != -1) {
-		id = cpu_map__empty_aggr_cpu_id();
+		id = aggr_cpu_id__empty();
 		id.core = cpu;
 	}
 	printout(config, id, nr, counter, uval,
@@ -780,7 +780,7 @@ static struct perf_aggr_thread_value *sort_aggr_thread(
 			continue;
 
 		buf[i].counter = counter;
-		buf[i].id = cpu_map__empty_aggr_cpu_id();
+		buf[i].id = aggr_cpu_id__empty();
 		buf[i].id.thread = thread;
 		buf[i].uval = uval;
 		buf[i].val = val;
@@ -868,7 +868,7 @@ static void print_counter_aggr(struct perf_stat_config *config,
 		fprintf(output, "%s", prefix);
 
 	uval = cd.avg * counter->scale;
-	printout(config, cpu_map__empty_aggr_cpu_id(), 0, counter, uval, prefix, cd.avg_running,
+	printout(config, aggr_cpu_id__empty(), 0, counter, uval, prefix, cd.avg_running,
 		 cd.avg_enabled, cd.avg, &rt_stat);
 	if (!metric_only)
 		fprintf(output, "\n");
@@ -911,7 +911,7 @@ static void print_counter(struct perf_stat_config *config,
 			fprintf(output, "%s", prefix);
 
 		uval = val * counter->scale;
-		id = cpu_map__empty_aggr_cpu_id();
+		id = aggr_cpu_id__empty();
 		id.core = cpu;
 		printout(config, id, 0, counter, uval, prefix,
 			 run, ena, 1.0, &rt_stat);
@@ -938,7 +938,7 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
 		if (prefix)
 			fputs(prefix, config->output);
 		evlist__for_each_entry(evlist, counter) {
-			id = cpu_map__empty_aggr_cpu_id();
+			id = aggr_cpu_id__empty();
 			id.core = cpu;
 			if (first) {
 				aggr_printout(config, counter, id, 0);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:18 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:18 -0800
Subject: [PATCH v4 15/48] perf cpumap: Document cpu__get_node and remove
 redundant function
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-16-irogers@google.com>

cpu_map__get_node_id isn't used externally and merely delegates to
cpu__get_node.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.c | 11 +++++------
 tools/perf/util/cpumap.h |  5 ++++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index b3e1304aca0c..1626b0991408 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -16,6 +16,10 @@
 static int max_cpu_num;
 static int max_present_cpu_num;
 static int max_node_num;
+/**
+ * The numa node X as read from /sys/devices/system/node/nodeX indexed by the
+ * CPU number.
+ */
 static int *cpunode_map;
 
 static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus)
@@ -222,11 +226,6 @@ int cpu_map__get_core_id(int cpu)
 	return ret ?: value;
 }
 
-int cpu_map__get_node_id(int cpu)
-{
-	return cpu__get_node(cpu);
-}
-
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 {
 	struct aggr_cpu_id id;
@@ -250,7 +249,7 @@ struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unu
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	id.node = cpu_map__get_node_id(cpu);
+	id.node = cpu__get_node(cpu);
 	return id;
 }
 
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 9589b0001a28..f849f01c5860 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -45,7 +45,6 @@ int cpu_map__get_die_id(int cpu);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
 int cpu_map__get_core_id(int cpu);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
-int cpu_map__get_node_id(int cpu);
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
 int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
@@ -58,6 +57,10 @@ int cpu__setup_cpunode_map(void);
 int cpu__max_node(void);
 int cpu__max_cpu(void);
 int cpu__max_present_cpu(void);
+/**
+ * cpu__get_node - Returns the numa node X as read from
+ * /sys/devices/system/node/nodeX for the given CPU.
+ */
 int cpu__get_node(int cpu);
 
 int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:19 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:19 -0800
Subject: [PATCH v4 16/48] perf cpumap: Remove map from function names that
 don't use a map.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-17-irogers@google.com>

Move to the cpu name and document for consistency.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.c | 12 ++++++------
 tools/perf/util/cpumap.h | 19 ++++++++++++++++---
 tools/perf/util/env.c    |  6 +++---
 tools/perf/util/stat.c   |  4 ++--
 4 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 1626b0991408..e0d7f1da5858 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -126,7 +126,7 @@ static int cpu__get_topology_int(int cpu, const char *name, int *value)
 	return sysfs__read_int(path, value);
 }
 
-int cpu_map__get_socket_id(int cpu)
+int cpu__get_socket_id(int cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu, "physical_package_id", &value);
 	return ret ?: value;
@@ -136,7 +136,7 @@ struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_u
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	id.socket = cpu_map__get_socket_id(cpu);
+	id.socket = cpu__get_socket_id(cpu);
 	return id;
 }
 
@@ -190,7 +190,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 	return 0;
 }
 
-int cpu_map__get_die_id(int cpu)
+int cpu__get_die_id(int cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu, "die_id", &value);
 
@@ -202,7 +202,7 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 	struct aggr_cpu_id id;
 	int die;
 
-	die = cpu_map__get_die_id(cpu);
+	die = cpu__get_die_id(cpu);
 	/* There is no die_id on legacy system. */
 	if (die == -1)
 		die = 0;
@@ -220,7 +220,7 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-int cpu_map__get_core_id(int cpu)
+int cpu__get_core_id(int cpu)
 {
 	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
 	return ret ?: value;
@@ -229,7 +229,7 @@ int cpu_map__get_core_id(int cpu)
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 {
 	struct aggr_cpu_id id;
-	int core = cpu_map__get_core_id(cpu);
+	int core = cpu__get_core_id(cpu);
 
 	/* cpu_map__get_die returns a struct with socket and die set*/
 	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index f849f01c5860..a053bf31a3f0 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -39,11 +39,8 @@ struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data);
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
-int cpu_map__get_socket_id(int cpu);
 struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
-int cpu_map__get_die_id(int cpu);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
-int cpu_map__get_core_id(int cpu);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
 int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
@@ -62,6 +59,22 @@ int cpu__max_present_cpu(void);
  * /sys/devices/system/node/nodeX for the given CPU.
  */
 int cpu__get_node(int cpu);
+/**
+ * cpu__get_socket_id - Returns the socket number as read from
+ * /sys/devices/system/cpu/cpuX/topology/physical_package_id for the given CPU.
+ */
+int cpu__get_socket_id(int cpu);
+/**
+ * cpu__get_die_id - Returns the die id as read from
+ * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
+ */
+int cpu__get_die_id(int cpu);
+/**
+ * cpu__get_core_id - Returns the core id as read from
+ * /sys/devices/system/cpu/cpuX/topology/core_id for the given CPU.
+ */
+int cpu__get_core_id(int cpu);
+
 
 int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 		       struct aggr_cpu_id (*f)(int cpu, void *data),
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index b9904896eb97..fd12c0dcaefb 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -302,9 +302,9 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
 		return -ENOMEM;
 
 	for (cpu = 0; cpu < nr_cpus; ++cpu) {
-		env->cpu[cpu].core_id	= cpu_map__get_core_id(cpu);
-		env->cpu[cpu].socket_id	= cpu_map__get_socket_id(cpu);
-		env->cpu[cpu].die_id	= cpu_map__get_die_id(cpu);
+		env->cpu[cpu].core_id	= cpu__get_core_id(cpu);
+		env->cpu[cpu].socket_id	= cpu__get_socket_id(cpu);
+		env->cpu[cpu].die_id	= cpu__get_die_id(cpu);
 	}
 
 	env->nr_cpus_avail = nr_cpus;
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 5ed99bcfe91e..5c24aca0968c 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -328,7 +328,7 @@ static int check_per_pkg(struct evsel *counter,
 	if (!(vals->run && vals->ena))
 		return 0;
 
-	s = cpu_map__get_socket_id(cpu);
+	s = cpu__get_socket_id(cpu);
 	if (s < 0)
 		return -1;
 
@@ -336,7 +336,7 @@ static int check_per_pkg(struct evsel *counter,
 	 * On multi-die system, die_id > 0. On no-die system, die_id = 0.
 	 * We use hashmap(socket, die) to check the used socket+die pair.
 	 */
-	d = cpu_map__get_die_id(cpu);
+	d = cpu__get_die_id(cpu);
 	if (d < 0)
 		return -1;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:20 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:20 -0800
Subject: [PATCH v4 17/48] perf cpumap: Remove cpu_map__cpu,
 use libperf function.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-18-irogers@google.com>

Switch the remaining few users of cpu_map__cpu to perf_cpu_map__cpu and
remove the function.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-ftrace.c | 2 +-
 tools/perf/util/cpumap.c    | 9 ++-------
 tools/perf/util/cpumap.h    | 1 -
 3 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index 2b54e2ddc80a..f16c39a37a52 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -281,7 +281,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpumap)
 	int ret;
 	int last_cpu;
 
-	last_cpu = cpu_map__cpu(cpumap, cpumap->nr - 1);
+	last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1);
 	mask_size = last_cpu / 4 + 2; /* one more byte for EOS */
 	mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index e0d7f1da5858..32f9fc2dd389 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -485,11 +485,6 @@ bool cpu_map__has(struct perf_cpu_map *cpus, int cpu)
 	return perf_cpu_map__idx(cpus, cpu) != -1;
 }
 
-int cpu_map__cpu(struct perf_cpu_map *cpus, int idx)
-{
-	return cpus->map[idx];
-}
-
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
 {
 	int i, cpu, start = -1;
@@ -547,7 +542,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
 	int i, cpu;
 	char *ptr = buf;
 	unsigned char *bitmap;
-	int last_cpu = cpu_map__cpu(map, map->nr - 1);
+	int last_cpu = perf_cpu_map__cpu(map, map->nr - 1);
 
 	if (buf == NULL)
 		return 0;
@@ -559,7 +554,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
 	}
 
 	for (i = 0; i < map->nr; i++) {
-		cpu = cpu_map__cpu(map, i);
+		cpu = perf_cpu_map__cpu(map, i);
 		bitmap[cpu / 8] |= 1 << (cpu % 8);
 	}
 
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index a053bf31a3f0..87545bcd461d 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -80,7 +80,6 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
 		       struct aggr_cpu_id (*f)(int cpu, void *data),
 		       void *data);
 
-int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
 bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
 
 bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:21 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:21 -0800
Subject: [PATCH v4 18/48] perf cpumap: Refactor cpu_map__build_map
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-19-irogers@google.com>

Turn it into a cpu_aggr_map__new. Pass helper functions. Refactor
builtin-stat calls to manually pass function pointers. Try to reduce
some copy-paste code.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c | 187 ++++++++++++++++++++------------------
 tools/perf/util/cpumap.c  |  59 +++++-------
 tools/perf/util/cpumap.h  |  16 ++--
 3 files changed, 130 insertions(+), 132 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d229fb71b577..2b04a948cf37 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1322,6 +1322,17 @@ static struct option stat_options[] = {
 	OPT_END()
 };
 
+static const char *const aggr_mode__string[] = {
+	[AGGR_CORE] = "core",
+	[AGGR_DIE] = "die",
+	[AGGR_GLOBAL] = "global",
+	[AGGR_NODE] = "node",
+	[AGGR_NONE] = "none",
+	[AGGR_SOCKET] = "socket",
+	[AGGR_THREAD] = "thread",
+	[AGGR_UNSET] = "unset",
+};
+
 static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
 						int cpu)
 {
@@ -1394,54 +1405,67 @@ static bool term_percore_set(void)
 	return false;
 }
 
-static int perf_stat_init_aggr_mode(void)
+static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
 {
-	int nr;
+	switch (aggr_mode) {
+	case AGGR_SOCKET:
+		return cpu_map__get_socket_aggr_by_cpu;
+	case AGGR_DIE:
+		return cpu_map__get_die_aggr_by_cpu;
+	case AGGR_CORE:
+		return cpu_map__get_core_aggr_by_cpu;
+	case AGGR_NODE:
+		return cpu_map__get_node_aggr_by_cpu;
+	case AGGR_NONE:
+		if (term_percore_set())
+			return cpu_map__get_core_aggr_by_cpu;
+
+		return NULL;
+	case AGGR_GLOBAL:
+	case AGGR_THREAD:
+	case AGGR_UNSET:
+	default:
+		return NULL;
+	}
+}
 
-	switch (stat_config.aggr_mode) {
+static aggr_get_id_t aggr_mode__get_id(enum aggr_mode aggr_mode)
+{
+	switch (aggr_mode) {
 	case AGGR_SOCKET:
-		if (cpu_map__build_socket_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build socket map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_socket_cached;
-		break;
+		return perf_stat__get_socket_cached;
 	case AGGR_DIE:
-		if (cpu_map__build_die_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build die map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_die_cached;
-		break;
+		return perf_stat__get_die_cached;
 	case AGGR_CORE:
-		if (cpu_map__build_core_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build core map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_core_cached;
-		break;
+		return perf_stat__get_core_cached;
 	case AGGR_NODE:
-		if (cpu_map__build_node_map(evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build core map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_node_cached;
-		break;
+		return perf_stat__get_node_cached;
 	case AGGR_NONE:
 		if (term_percore_set()) {
-			if (cpu_map__build_core_map(evsel_list->core.cpus,
-						    &stat_config.aggr_map)) {
-				perror("cannot build core map");
-				return -1;
-			}
-			stat_config.aggr_get_id = perf_stat__get_core_cached;
+			return perf_stat__get_core_cached;
 		}
-		break;
+		return NULL;
 	case AGGR_GLOBAL:
 	case AGGR_THREAD:
 	case AGGR_UNSET:
 	default:
-		break;
+		return NULL;
+	}
+}
+
+static int perf_stat_init_aggr_mode(void)
+{
+	int nr;
+	aggr_cpu_id_get_t get_id = aggr_mode__get_aggr(stat_config.aggr_mode);
+
+	if (get_id) {
+		stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.cpus,
+							 get_id, /*data=*/NULL);
+		if (!stat_config.aggr_map) {
+			pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]);
+			return -1;
+		}
+		stat_config.aggr_get_id = aggr_mode__get_id(stat_config.aggr_mode);
 	}
 
 	/*
@@ -1549,30 +1573,6 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 	return id;
 }
 
-static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
-				      struct cpu_aggr_map **sockp)
-{
-	return cpu_map__build_map(cpus, sockp, perf_env__get_socket_aggr_by_cpu, env);
-}
-
-static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
-				   struct cpu_aggr_map **diep)
-{
-	return cpu_map__build_map(cpus, diep, perf_env__get_die_aggr_by_cpu, env);
-}
-
-static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
-				    struct cpu_aggr_map **corep)
-{
-	return cpu_map__build_map(cpus, corep, perf_env__get_core_aggr_by_cpu, env);
-}
-
-static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
-				    struct cpu_aggr_map **nodep)
-{
-	return cpu_map__build_map(cpus, nodep, perf_env__get_node_aggr_by_cpu, env);
-}
-
 static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
 						     int cpu)
 {
@@ -1596,47 +1596,60 @@ static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *conf
 	return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
-static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
+static aggr_cpu_id_get_t aggr_mode__get_aggr_file(enum aggr_mode aggr_mode)
 {
-	struct perf_env *env = &st->session->header.env;
+	switch (aggr_mode) {
+	case AGGR_SOCKET:
+		return perf_env__get_socket_aggr_by_cpu;
+	case AGGR_DIE:
+		return perf_env__get_die_aggr_by_cpu;
+	case AGGR_CORE:
+		return perf_env__get_core_aggr_by_cpu;
+	case AGGR_NODE:
+		return perf_env__get_node_aggr_by_cpu;
+	case AGGR_NONE:
+	case AGGR_GLOBAL:
+	case AGGR_THREAD:
+	case AGGR_UNSET:
+	default:
+		return NULL;
+	}
+}
 
-	switch (stat_config.aggr_mode) {
+static aggr_get_id_t aggr_mode__get_id_file(enum aggr_mode aggr_mode)
+{
+	switch (aggr_mode) {
 	case AGGR_SOCKET:
-		if (perf_env__build_socket_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build socket map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_socket_file;
-		break;
+		return perf_stat__get_socket_file;
 	case AGGR_DIE:
-		if (perf_env__build_die_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build die map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_die_file;
-		break;
+		return perf_stat__get_die_file;
 	case AGGR_CORE:
-		if (perf_env__build_core_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build core map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_core_file;
-		break;
+		return perf_stat__get_core_file;
 	case AGGR_NODE:
-		if (perf_env__build_node_map(env, evsel_list->core.cpus, &stat_config.aggr_map)) {
-			perror("cannot build core map");
-			return -1;
-		}
-		stat_config.aggr_get_id = perf_stat__get_node_file;
-		break;
+		return perf_stat__get_node_file;
 	case AGGR_NONE:
 	case AGGR_GLOBAL:
 	case AGGR_THREAD:
 	case AGGR_UNSET:
 	default:
-		break;
+		return NULL;
 	}
+}
+
+static int perf_stat_init_aggr_mode_file(struct perf_stat *st)
+{
+	struct perf_env *env = &st->session->header.env;
+	aggr_cpu_id_get_t get_id = aggr_mode__get_aggr_file(stat_config.aggr_mode);
 
+	if (!get_id)
+		return 0;
+
+	stat_config.aggr_map = cpu_aggr_map__new(evsel_list->core.cpus, get_id, env);
+	if (!stat_config.aggr_map) {
+		pr_err("cannot build %s map", aggr_mode__string[stat_config.aggr_mode]);
+		return -1;
+	}
+	stat_config.aggr_get_id = aggr_mode__get_id_file(stat_config.aggr_mode);
 	return 0;
 }
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 32f9fc2dd389..c8f9b3f15759 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -140,7 +140,7 @@ struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_u
 	return id;
 }
 
-static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
+static int aggr_cpu_id__cmp(const void *a_pointer, const void *b_pointer)
 {
 	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
 	struct aggr_cpu_id *b = (struct aggr_cpu_id *)b_pointer;
@@ -157,37 +157,40 @@ static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
 		return a->thread - b->thread;
 }
 
-int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
-		       struct aggr_cpu_id (*f)(int cpu, void *data),
-		       void *data)
+struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
+				       aggr_cpu_id_get_t get_id,
+				       void *data)
 {
-	int nr = cpus->nr;
-	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(nr);
-	int cpu, s2;
-	struct aggr_cpu_id s1;
+	int cpu, idx;
+	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(cpus->nr);
 
 	if (!c)
-		return -1;
+		return NULL;
 
 	/* Reset size as it may only be partially filled */
 	c->nr = 0;
 
-	for (cpu = 0; cpu < nr; cpu++) {
-		s1 = f(cpu, data);
-		for (s2 = 0; s2 < c->nr; s2++) {
-			if (aggr_cpu_id__equal(&s1, &c->map[s2]))
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		bool duplicate = false;
+		struct aggr_cpu_id cpu_id = get_id(cpu, data);
+
+		for (int j = 0; j < c->nr; j++) {
+			if (aggr_cpu_id__equal(&cpu_id, &c->map[j])) {
+				duplicate = true;
 				break;
+			}
 		}
-		if (s2 == c->nr) {
-			c->map[c->nr] = s1;
+		if (!duplicate) {
+			c->map[c->nr] = cpu_id;
 			c->nr++;
 		}
 	}
+
 	/* ensure we process id in increasing order */
-	qsort(c->map, c->nr, sizeof(struct aggr_cpu_id), cmp_aggr_cpu_id);
+	qsort(c->map, c->nr, sizeof(struct aggr_cpu_id), aggr_cpu_id__cmp);
+
+	return c;
 
-	*res = c;
-	return 0;
 }
 
 int cpu__get_die_id(int cpu)
@@ -253,26 +256,6 @@ struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unu
 	return id;
 }
 
-int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
-{
-	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket_aggr_by_cpu, NULL);
-}
-
-int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep)
-{
-	return cpu_map__build_map(cpus, diep, cpu_map__get_die_aggr_by_cpu, NULL);
-}
-
-int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep)
-{
-	return cpu_map__build_map(cpus, corep, cpu_map__get_core_aggr_by_cpu, NULL);
-}
-
-int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **numap)
-{
-	return cpu_map__build_map(cpus, numap, cpu_map__get_node_aggr_by_cpu, NULL);
-}
-
 /* setup simple routines to easily access node numbers given a cpu number */
 static int get_max_num(char *path, int *max)
 {
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 87545bcd461d..611048e2a592 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -43,10 +43,6 @@ struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
 struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
-int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
-int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
-int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
-int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **nodep);
 const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */
 
 int cpu__setup_cpunode_map(void);
@@ -75,10 +71,16 @@ int cpu__get_die_id(int cpu);
  */
 int cpu__get_core_id(int cpu);
 
+typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(int cpu, void *data);
 
-int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
-		       struct aggr_cpu_id (*f)(int cpu, void *data),
-		       void *data);
+/**
+ * cpu_aggr_map__new - Create a cpu_aggr_map with an aggr_cpu_id for each cpu in
+ * cpus. The aggr_cpu_id is created with 'get_id' that may have a data value
+ * passed to it. The cpu_aggr_map is sorted with duplicate values removed.
+ */
+struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
+				       aggr_cpu_id_get_t get_id,
+				       void *data);
 
 bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:22 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:22 -0800
Subject: [PATCH v4 19/48] perf cpumap: Rename cpu_map__get_X_aggr_by_cpu
 functions
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-20-irogers@google.com>

The functions don't use a cpu_map so reduce them to being like
constructors of aggr_cpu_id.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c   | 18 +++++++++---------
 tools/perf/tests/topology.c |  8 ++++----
 tools/perf/util/cpumap.c    | 14 +++++++-------
 tools/perf/util/cpumap.h    | 29 +++++++++++++++++++++++++----
 4 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2b04a948cf37..98f80c217279 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1336,25 +1336,25 @@ static const char *const aggr_mode__string[] = {
 static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
 						int cpu)
 {
-	return cpu_map__get_socket_aggr_by_cpu(cpu, /*data=*/NULL);
+	return aggr_cpu_id__socket(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
 					     int cpu)
 {
-	return cpu_map__get_die_aggr_by_cpu(cpu, /*data=*/NULL);
+	return aggr_cpu_id__die(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
 					      int cpu)
 {
-	return cpu_map__get_core_aggr_by_cpu(cpu, /*data=*/NULL);
+	return aggr_cpu_id__core(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused,
 					      int cpu)
 {
-	return cpu_map__get_node_aggr_by_cpu(cpu, /*data=*/NULL);
+	return aggr_cpu_id__node(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
@@ -1409,16 +1409,16 @@ static aggr_cpu_id_get_t aggr_mode__get_aggr(enum aggr_mode aggr_mode)
 {
 	switch (aggr_mode) {
 	case AGGR_SOCKET:
-		return cpu_map__get_socket_aggr_by_cpu;
+		return aggr_cpu_id__socket;
 	case AGGR_DIE:
-		return cpu_map__get_die_aggr_by_cpu;
+		return aggr_cpu_id__die;
 	case AGGR_CORE:
-		return cpu_map__get_core_aggr_by_cpu;
+		return aggr_cpu_id__core;
 	case AGGR_NODE:
-		return cpu_map__get_node_aggr_by_cpu;
+		return aggr_cpu_id__node;
 	case AGGR_NONE:
 		if (term_percore_set())
-			return cpu_map__get_core_aggr_by_cpu;
+			return aggr_cpu_id__core;
 
 		return NULL;
 	case AGGR_GLOBAL:
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 5992b323c4f5..0cb7b015b4b9 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -121,7 +121,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that core ID contains socket, die and core
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_core_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
+		id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
 			session->header.env.cpu[map->map[i]].core_id == id.core);
 
@@ -136,7 +136,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that die ID contains socket and die
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_die_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
+		id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
 			session->header.env.cpu[map->map[i]].socket_id == id.socket);
 
@@ -150,7 +150,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that socket ID contains only socket
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_socket_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
+		id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
 			session->header.env.cpu[map->map[i]].socket_id == id.socket);
 
@@ -162,7 +162,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 	// Test that node ID contains only node
 	for (i = 0; i < map->nr; i++) {
-		id = cpu_map__get_node_aggr_by_cpu(perf_cpu_map__cpu(map, i), NULL);
+		id = aggr_cpu_id__node(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Node map - Node ID doesn't match",
 			cpu__get_node(map->map[i]) == id.node);
 		TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index c8f9b3f15759..19e502cc65e7 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -132,7 +132,7 @@ int cpu__get_socket_id(int cpu)
 	return ret ?: value;
 }
 
-struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
+struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
@@ -200,7 +200,7 @@ int cpu__get_die_id(int cpu)
 	return ret ?: value;
 }
 
-struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
+struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data)
 {
 	struct aggr_cpu_id id;
 	int die;
@@ -215,7 +215,7 @@ struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
 	 * with the socket ID and then add die to
 	 * make a unique ID.
 	 */
-	id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
+	id = aggr_cpu_id__socket(cpu, data);
 	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
@@ -229,13 +229,13 @@ int cpu__get_core_id(int cpu)
 	return ret ?: value;
 }
 
-struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
+struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data)
 {
 	struct aggr_cpu_id id;
 	int core = cpu__get_core_id(cpu);
 
-	/* cpu_map__get_die returns a struct with socket and die set*/
-	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
+	/* aggr_cpu_id__die returns a struct with socket and die set*/
+	id = aggr_cpu_id__die(cpu, data);
 	if (aggr_cpu_id__is_empty(&id))
 		return id;
 
@@ -248,7 +248,7 @@ struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
 
 }
 
-struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
+struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 611048e2a592..ecd658293a2d 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -39,10 +39,6 @@ struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data);
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
 size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
-struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
-struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
 const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */
 
 int cpu__setup_cpunode_map(void);
@@ -88,4 +84,29 @@ bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b
 bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a);
 struct aggr_cpu_id aggr_cpu_id__empty(void);
 
+
+/**
+ * aggr_cpu_id__socket - Create an aggr_cpu_id with the socket populated with
+ * the socket for cpu. The function signature is compatible with
+ * aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data);
+/**
+ * aggr_cpu_id__die - Create an aggr_cpu_id with the die and socket populated
+ * with the die and socket for cpu. The function signature is compatible with
+ * aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data);
+/**
+ * aggr_cpu_id__core - Create an aggr_cpu_id with the core, die and socket
+ * populated with the core, die and socket for cpu. The function signature is
+ * compatible with aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data);
+/**
+ * aggr_cpu_id__node - Create an aggr_cpu_id with the numa node populated for
+ * cpu. The function signature is compatible with aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data);
+
 #endif /* __PERF_CPUMAP_H */
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:23 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:23 -0800
Subject: [PATCH v4 20/48] perf cpumap: Move 'has' function to libperf
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-21-irogers@google.com>

Make the cpu map argument const for consistency with the rest of the
API. Modify cpu_map__idx accordingly.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/Documentation/libperf.txt |  1 +
 tools/lib/perf/cpumap.c                  |  7 ++++++-
 tools/lib/perf/include/internal/cpumap.h |  2 +-
 tools/lib/perf/include/perf/cpumap.h     |  1 +
 tools/lib/perf/libperf.map               |  1 +
 tools/perf/arch/arm/util/cs-etm.c        | 16 ++++++++--------
 tools/perf/builtin-sched.c               |  6 +++---
 tools/perf/tests/topology.c              |  2 +-
 tools/perf/util/cpumap.c                 |  5 -----
 tools/perf/util/cpumap.h                 |  2 --
 tools/perf/util/cputopo.c                |  2 +-
 11 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index 63ae5e0195ce..faef9ba3a540 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -48,6 +48,7 @@ SYNOPSIS
   int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
   bool perf_cpu_map__empty(const struct perf_cpu_map *map);
   int perf_cpu_map__max(struct perf_cpu_map *map);
+  bool perf_cpu_map__has(const struct perf_cpu_map *map, int cpu);
 
   #define perf_cpu_map__for_each_cpu(cpu, idx, cpus)
 --
diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
index adaad3dddf6e..3c36a06771af 100644
--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -268,7 +268,7 @@ bool perf_cpu_map__empty(const struct perf_cpu_map *map)
 	return map ? map->map[0] == -1 : true;
 }
 
-int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu)
+int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu)
 {
 	int low = 0, high = cpus->nr;
 
@@ -288,6 +288,11 @@ int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu)
 	return -1;
 }
 
+bool perf_cpu_map__has(const struct perf_cpu_map *cpus, int cpu)
+{
+	return perf_cpu_map__idx(cpus, cpu) != -1;
+}
+
 int perf_cpu_map__max(struct perf_cpu_map *map)
 {
 	// cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as well.
diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
index 4054169c12c5..71a31ed738c9 100644
--- a/tools/lib/perf/include/internal/cpumap.h
+++ b/tools/lib/perf/include/internal/cpumap.h
@@ -23,6 +23,6 @@ struct perf_cpu_map {
 #define MAX_NR_CPUS	2048
 #endif
 
-int perf_cpu_map__idx(struct perf_cpu_map *cpus, int cpu);
+int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu);
 
 #endif /* __LIBPERF_INTERNAL_CPUMAP_H */
diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h
index 7c27766ea0bf..3f1c0afa3ccd 100644
--- a/tools/lib/perf/include/perf/cpumap.h
+++ b/tools/lib/perf/include/perf/cpumap.h
@@ -20,6 +20,7 @@ LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
 LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
 LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
 LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map);
+LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, int cpu);
 
 #define perf_cpu_map__for_each_cpu(cpu, idx, cpus)		\
 	for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx);	\
diff --git a/tools/lib/perf/libperf.map b/tools/lib/perf/libperf.map
index 5979bf92d98f..93696affda2e 100644
--- a/tools/lib/perf/libperf.map
+++ b/tools/lib/perf/libperf.map
@@ -10,6 +10,7 @@ LIBPERF_0.0.1 {
 		perf_cpu_map__cpu;
 		perf_cpu_map__empty;
 		perf_cpu_map__max;
+		perf_cpu_map__has;
 		perf_thread_map__new_dummy;
 		perf_thread_map__set_pid;
 		perf_thread_map__comm;
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 8a3d54a86c9c..129c0272d65b 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -204,8 +204,8 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
 
 	/* Set option of each CPU we have */
 	for (i = 0; i < cpu__max_cpu(); i++) {
-		if (!cpu_map__has(event_cpus, i) ||
-		    !cpu_map__has(online_cpus, i))
+		if (!perf_cpu_map__has(event_cpus, i) ||
+		    !perf_cpu_map__has(online_cpus, i))
 			continue;
 
 		if (option & BIT(ETM_OPT_CTXTID)) {
@@ -523,8 +523,8 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 	/* cpu map is not empty, we have specific CPUs to work with */
 	if (!perf_cpu_map__empty(event_cpus)) {
 		for (i = 0; i < cpu__max_cpu(); i++) {
-			if (!cpu_map__has(event_cpus, i) ||
-			    !cpu_map__has(online_cpus, i))
+			if (!perf_cpu_map__has(event_cpus, i) ||
+			    !perf_cpu_map__has(online_cpus, i))
 				continue;
 
 			if (cs_etm_is_ete(itr, i))
@@ -537,7 +537,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 	} else {
 		/* get configuration for all CPUs in the system */
 		for (i = 0; i < cpu__max_cpu(); i++) {
-			if (!cpu_map__has(online_cpus, i))
+			if (!perf_cpu_map__has(online_cpus, i))
 				continue;
 
 			if (cs_etm_is_ete(itr, i))
@@ -722,8 +722,8 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 	} else {
 		/* Make sure all specified CPUs are online */
 		for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
-			if (cpu_map__has(event_cpus, i) &&
-			    !cpu_map__has(online_cpus, i))
+			if (perf_cpu_map__has(event_cpus, i) &&
+			    !perf_cpu_map__has(online_cpus, i))
 				return -EINVAL;
 		}
 
@@ -744,7 +744,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 	offset = CS_ETM_SNAPSHOT + 1;
 
 	for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
-		if (cpu_map__has(cpu_map, i))
+		if (perf_cpu_map__has(cpu_map, i))
 			cs_etm_get_metadata(i, &offset, itr, info);
 
 	perf_cpu_map__put(online_cpus);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 4527f632ebe4..9da1da4749c9 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1617,10 +1617,10 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 		if (curr_thread && thread__has_color(curr_thread))
 			pid_color = COLOR_PIDS;
 
-		if (sched->map.cpus && !cpu_map__has(sched->map.cpus, cpu))
+		if (sched->map.cpus && !perf_cpu_map__has(sched->map.cpus, cpu))
 			continue;
 
-		if (sched->map.color_cpus && cpu_map__has(sched->map.color_cpus, cpu))
+		if (sched->map.color_cpus && perf_cpu_map__has(sched->map.color_cpus, cpu))
 			cpu_color = COLOR_CPUS;
 
 		if (cpu != this_cpu)
@@ -1639,7 +1639,7 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 			color_fprintf(stdout, color, "   ");
 	}
 
-	if (sched->map.cpus && !cpu_map__has(sched->map.cpus, this_cpu))
+	if (sched->map.cpus && !perf_cpu_map__has(sched->map.cpus, this_cpu))
 		goto out;
 
 	timestamp__scnprintf_usec(timestamp, stimestamp, sizeof(stimestamp));
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 0cb7b015b4b9..cb29ea7ec409 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -112,7 +112,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
 
 	for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
-		if (!cpu_map__has(map, i))
+		if (!perf_cpu_map__has(map, i))
 			continue;
 		pr_debug("CPU %d, core %d, socket %d\n", i,
 			 session->header.env.cpu[i].core_id,
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 19e502cc65e7..f1d76a8e92e8 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -463,11 +463,6 @@ int cpu__setup_cpunode_map(void)
 	return 0;
 }
 
-bool cpu_map__has(struct perf_cpu_map *cpus, int cpu)
-{
-	return perf_cpu_map__idx(cpus, cpu) != -1;
-}
-
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
 {
 	int i, cpu, start = -1;
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index ecd658293a2d..32b8b5178f01 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -78,8 +78,6 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 				       aggr_cpu_id_get_t get_id,
 				       void *data);
 
-bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
-
 bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
 bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a);
 struct aggr_cpu_id aggr_cpu_id__empty(void);
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c
index 51b429c86f98..8affb37d90e7 100644
--- a/tools/perf/util/cputopo.c
+++ b/tools/perf/util/cputopo.c
@@ -218,7 +218,7 @@ struct cpu_topology *cpu_topology__new(void)
 	tp->core_cpus_list = addr;
 
 	for (i = 0; i < nr; i++) {
-		if (!cpu_map__has(map, i))
+		if (!perf_cpu_map__has(map, i))
 			continue;
 
 		ret = build_cpu_topology(tp, i);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:24 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:24 -0800
Subject: [PATCH v4 21/48] perf cpumap: Add some comments to cpu_aggr_map
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-22-irogers@google.com>

Move cpu_aggr_map__empty_new to be with other cpu_aggr_map function.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.h | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 32b8b5178f01..25a08d640d81 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -24,16 +24,18 @@ struct aggr_cpu_id {
 	int core;
 };
 
+/** A collection of aggr_cpu_id values, the "built" version is sorted and uniqued. */
 struct cpu_aggr_map {
 	refcount_t refcnt;
+	/** Number of valid entries. */
 	int nr;
+	/** The entries. */
 	struct aggr_cpu_id map[];
 };
 
 struct perf_record_cpu_map_data;
 
 struct perf_cpu_map *perf_cpu_map__empty_new(int nr);
-struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr);
 
 struct perf_cpu_map *cpu_map__new_data(struct perf_record_cpu_map_data *data);
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
@@ -67,6 +69,12 @@ int cpu__get_die_id(int cpu);
  */
 int cpu__get_core_id(int cpu);
 
+/**
+ * cpu_aggr_map__empty_new - Create a cpu_aggr_map of size nr with every entry
+ * being empty.
+ */
+struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr);
+
 typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(int cpu, void *data);
 
 /**
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:25 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:25 -0800
Subject: [PATCH v4 22/48] perf cpumap: Trim the cpu_aggr_map
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-23-irogers@google.com>

cpu_aggr_map__new removes duplicates, when this happens shrink the
array.

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/cpumap.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index f1d76a8e92e8..2779474f39db 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -185,7 +185,15 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 			c->nr++;
 		}
 	}
-
+	/* Trim. */
+	if (c->nr != cpus->nr) {
+		struct cpu_aggr_map *trimmed_c =
+			realloc(c,
+				sizeof(struct cpu_aggr_map) + sizeof(struct aggr_cpu_id) * c->nr);
+
+		if (trimmed_c)
+			c = trimmed_c;
+	}
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(struct aggr_cpu_id), aggr_cpu_id__cmp);
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:26 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:26 -0800
Subject: [PATCH v4 23/48] perf stat: Fix memory leak in check_per_pkg
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-24-irogers@google.com>

If the key is already present then free the key used for lookup.

Found with:
$ perf stat -M IO_Read_BW /bin/true

==1749112==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 32 byte(s) in 4 object(s) allocated from:
    #0 0x7f6f6fa7d7cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x55acecd9d7a6 in check_per_pkg util/stat.c:343
    #2 0x55acecd9d9c5 in process_counter_values util/stat.c:365
    #3 0x55acecd9e0ab in process_counter_maps util/stat.c:421
    #4 0x55acecd9e292 in perf_stat_process_counter util/stat.c:443
    #5 0x55aceca8553e in read_counters ./tools/perf/builtin-stat.c:470
    #6 0x55aceca88fe3 in __run_perf_stat ./tools/perf/builtin-stat.c:1023
    #7 0x55aceca89146 in run_perf_stat ./tools/perf/builtin-stat.c:1048
    #8 0x55aceca90858 in cmd_stat ./tools/perf/builtin-stat.c:2555
    #9 0x55acecc05fa5 in run_builtin ./tools/perf/perf.c:313
    #10 0x55acecc064fe in handle_internal_command ./tools/perf/perf.c:365
    #11 0x55acecc068bb in run_argv ./tools/perf/perf.c:409
    #12 0x55acecc070aa in main ./tools/perf/perf.c:539

Reviewed-by: James Clark <james.clark at arm.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 5c24aca0968c..c69b221f5e3e 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -345,9 +345,10 @@ static int check_per_pkg(struct evsel *counter,
 		return -ENOMEM;
 
 	*key = (uint64_t)d << 32 | s;
-	if (hashmap__find(mask, (void *)key, NULL))
+	if (hashmap__find(mask, (void *)key, NULL)) {
 		*skip = true;
-	else
+		free(key);
+	} else
 		ret = hashmap__add(mask, (void *)key, (void *)1);
 
 	return ret;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:27 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:27 -0800
Subject: [PATCH v4 24/48] perf cpumap: Add CPU to aggr_cpu_id
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-25-irogers@google.com>

With no aggregration, such as 'perf stat -A', the aggr_cpu_id lacks a
way to describe per CPU aggregation and the core is set to the CPU in
places like print_counter_aggrdata in stat-display.c. Setting the core
to the CPU is undesirable as the CPU will exceed valid core values and
lead to confusion. Add a CPU variable to address this.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/topology.c | 19 +++++++++++++++++++
 tools/perf/util/cpumap.c    | 25 +++++++++++++++++++++----
 tools/perf/util/cpumap.h    |  8 ++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index cb29ea7ec409..33e4cb81265c 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -119,6 +119,22 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 			 session->header.env.cpu[i].socket_id);
 	}
 
+	// Test that CPU ID contains socket, die, core and CPU
+	for (i = 0; i < map->nr; i++) {
+		id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL);
+		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i] == id.cpu);
+
+		TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
+			session->header.env.cpu[map->map[i]].core_id == id.core);
+		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
+			session->header.env.cpu[map->map[i]].socket_id == id.socket);
+
+		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
+			session->header.env.cpu[map->map[i]].die_id == id.die);
+		TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
+		TEST_ASSERT_VAL("Cpu map - Thread is set", id.thread == -1);
+	}
+
 	// Test that core ID contains socket, die and core
 	for (i = 0; i < map->nr; i++) {
 		id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
@@ -145,6 +161,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 
 		TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
+		TEST_ASSERT_VAL("Die map - CPU is set", id.cpu == -1);
 		TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
 	}
 
@@ -157,6 +174,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 		TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
 		TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
+		TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu == -1);
 		TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
 	}
 
@@ -168,6 +186,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 		TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
 		TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
 		TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
+		TEST_ASSERT_VAL("Node map - CPU is set", id.cpu == -1);
 		TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
 	}
 	perf_session__delete(session);
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 2779474f39db..48ce583af0ec 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -242,7 +242,7 @@ struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data)
 	struct aggr_cpu_id id;
 	int core = cpu__get_core_id(cpu);
 
-	/* aggr_cpu_id__die returns a struct with socket and die set*/
+	/* aggr_cpu_id__die returns a struct with socket and die set. */
 	id = aggr_cpu_id__die(cpu, data);
 	if (aggr_cpu_id__is_empty(&id))
 		return id;
@@ -256,6 +256,20 @@ struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data)
 
 }
 
+struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data)
+{
+	struct aggr_cpu_id id;
+
+	/* aggr_cpu_id__core returns a struct with socket, die and core set. */
+	id = aggr_cpu_id__core(cpu, data);
+	if (aggr_cpu_id__is_empty(&id))
+		return id;
+
+	id.cpu = cpu;
+	return id;
+
+}
+
 struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
@@ -579,7 +593,8 @@ bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b
 		a->node == b->node &&
 		a->socket == b->socket &&
 		a->die == b->die &&
-		a->core == b->core;
+		a->core == b->core &&
+		a->cpu == b->cpu;
 }
 
 bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
@@ -588,7 +603,8 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
 		a->node == -1 &&
 		a->socket == -1 &&
 		a->die == -1 &&
-		a->core == -1;
+		a->core == -1 &&
+		a->cpu == -1;
 }
 
 struct aggr_cpu_id aggr_cpu_id__empty(void)
@@ -598,7 +614,8 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
 		.node = -1,
 		.socket = -1,
 		.die = -1,
-		.core = -1
+		.core = -1,
+		.cpu = -1
 	};
 	return ret;
 }
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 25a08d640d81..b98cd1739677 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -22,6 +22,8 @@ struct aggr_cpu_id {
 	int die;
 	/** The core id as read from /sys/devices/system/cpu/cpuX/topology/core_id. */
 	int core;
+	/** CPU aggregation, note there is one CPU for each SMT thread. */
+	int cpu;
 };
 
 /** A collection of aggr_cpu_id values, the "built" version is sorted and uniqued. */
@@ -109,6 +111,12 @@ struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data);
  * compatible with aggr_cpu_id_get_t.
  */
 struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data);
+/**
+ * aggr_cpu_id__core - Create an aggr_cpu_id with the cpu, core, die and socket
+ * populated with the cpu, core, die and socket for cpu. The function signature
+ * is compatible with aggr_cpu_id_get_t.
+ */
+struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data);
 /**
  * aggr_cpu_id__node - Create an aggr_cpu_id with the numa node populated for
  * cpu. The function signature is compatible with aggr_cpu_id_get_t.
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:28 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:28 -0800
Subject: [PATCH v4 25/48] perf stat-display: Avoid use of core for CPU.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-26-irogers@google.com>

Correct use of cpumap index in print_no_aggr_metric.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 45 +++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 870b1db71fbc..f48d1678861c 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -120,11 +120,10 @@ static void aggr_printout(struct perf_stat_config *config,
 				id.die,
 				config->csv_output ? 0 : -3,
 				id.core, config->csv_sep);
-		} else if (id.core > -1) {
+		} else if (id.cpu > -1) {
 			fprintf(config->output, "CPU%*d%s",
 				config->csv_output ? 0 : -7,
-				evsel__cpus(evsel)->map[id.core],
-				config->csv_sep);
+				id.cpu, config->csv_sep);
 		}
 		break;
 	case AGGR_THREAD:
@@ -334,7 +333,7 @@ static int first_shadow_cpu(struct perf_stat_config *config,
 	int cpu, idx;
 
 	if (config->aggr_mode == AGGR_NONE)
-		return id->core;
+		return id->cpu;
 
 	if (!config->aggr_get_id)
 		return 0;
@@ -697,10 +696,9 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
 		fprintf(output, "%s", prefix);
 
 	uval = val * counter->scale;
-	if (cpu != -1) {
-		id = aggr_cpu_id__empty();
-		id.core = cpu;
-	}
+	if (cpu != -1)
+		id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
+
 	printout(config, id, nr, counter, uval,
 		 prefix, run, ena, 1.0, &rt_stat);
 	if (!metric_only)
@@ -911,8 +909,7 @@ static void print_counter(struct perf_stat_config *config,
 			fprintf(output, "%s", prefix);
 
 		uval = val * counter->scale;
-		id = aggr_cpu_id__empty();
-		id.core = cpu;
+		id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
 		printout(config, id, 0, counter, uval, prefix,
 			 run, ena, 1.0, &rt_stat);
 
@@ -924,29 +921,31 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
 				 struct evlist *evlist,
 				 char *prefix)
 {
-	int cpu;
-	int nrcpus = 0;
-	struct evsel *counter;
-	u64 ena, run, val;
-	double uval;
-	struct aggr_cpu_id id;
+	int all_idx, cpu;
 
-	nrcpus = evlist->core.cpus->nr;
-	for (cpu = 0; cpu < nrcpus; cpu++) {
+	perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.cpus) {
+		struct evsel *counter;
 		bool first = true;
 
 		if (prefix)
 			fputs(prefix, config->output);
 		evlist__for_each_entry(evlist, counter) {
-			id = aggr_cpu_id__empty();
-			id.core = cpu;
+			u64 ena, run, val;
+			double uval;
+			struct aggr_cpu_id id;
+			int counter_idx = perf_cpu_map__idx(evsel__cpus(counter), cpu);
+
+			if (counter_idx < 0)
+				continue;
+
+			id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
 			if (first) {
 				aggr_printout(config, counter, id, 0);
 				first = false;
 			}
-			val = perf_counts(counter->counts, cpu, 0)->val;
-			ena = perf_counts(counter->counts, cpu, 0)->ena;
-			run = perf_counts(counter->counts, cpu, 0)->run;
+			val = perf_counts(counter->counts, counter_idx, 0)->val;
+			ena = perf_counts(counter->counts, counter_idx, 0)->ena;
+			run = perf_counts(counter->counts, counter_idx, 0)->run;
 
 			uval = val * counter->scale;
 			printout(config, id, 0, counter, uval, prefix,
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:29 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:29 -0800
Subject: [PATCH v4 26/48] perf evsel: Derive CPUs and threads in alloc_counts
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-27-irogers@google.com>

Passing the number of CPUs and threads allows for an evsel's counts to
be mismatched to its cpu map. To avoid this always derive the counts
size from the cpu map. Change openat-syscall-all-cpus to set the cpus
to allow for this to work.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/openat-syscall-all-cpus.c | 10 +---------
 tools/perf/util/counts.c                   |  8 ++++++--
 tools/perf/util/counts.h                   |  2 +-
 tools/perf/util/evsel.c                    |  2 +-
 tools/perf/util/stat.c                     | 13 ++++++-------
 5 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index cd3dd463783f..544db0839b3b 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -85,15 +85,7 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 		CPU_CLR(cpus->map[cpu], &cpu_set);
 	}
 
-	/*
-	 * Here we need to explicitly preallocate the counts, as if
-	 * we use the auto allocation it will allocate just for 1 cpu,
-	 * as we start by cpu 0.
-	 */
-	if (evsel__alloc_counts(evsel, cpus->nr, 1) < 0) {
-		pr_debug("evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
-		goto out_close_fd;
-	}
+	evsel->core.cpus = perf_cpu_map__get(cpus);
 
 	err = 0;
 
diff --git a/tools/perf/util/counts.c b/tools/perf/util/counts.c
index 582f3aeaf5e4..2b81707b9dba 100644
--- a/tools/perf/util/counts.c
+++ b/tools/perf/util/counts.c
@@ -4,6 +4,7 @@
 #include <string.h>
 #include "evsel.h"
 #include "counts.h"
+#include <perf/threadmap.h>
 #include <linux/zalloc.h>
 
 struct perf_counts *perf_counts__new(int ncpus, int nthreads)
@@ -55,9 +56,12 @@ void evsel__reset_counts(struct evsel *evsel)
 	perf_counts__reset(evsel->counts);
 }
 
-int evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads)
+int evsel__alloc_counts(struct evsel *evsel)
 {
-	evsel->counts = perf_counts__new(ncpus, nthreads);
+	struct perf_cpu_map *cpus = evsel__cpus(evsel);
+	int nthreads = perf_thread_map__nr(evsel->core.threads);
+
+	evsel->counts = perf_counts__new(cpus ? cpus->nr : 1, nthreads);
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
index 7ff36bf6d644..3e275e9c60d1 100644
--- a/tools/perf/util/counts.h
+++ b/tools/perf/util/counts.h
@@ -40,7 +40,7 @@ void perf_counts__delete(struct perf_counts *counts);
 void perf_counts__reset(struct perf_counts *counts);
 
 void evsel__reset_counts(struct evsel *evsel);
-int evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads);
+int evsel__alloc_counts(struct evsel *evsel);
 void evsel__free_counts(struct evsel *evsel);
 
 #endif /* __PERF_COUNTS_H */
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 656c30b988ce..6c9af21776e6 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1578,7 +1578,7 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale)
 	if (FD(evsel, cpu, thread) < 0)
 		return -EINVAL;
 
-	if (evsel->counts == NULL && evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
+	if (evsel->counts == NULL && evsel__alloc_counts(evsel) < 0)
 		return -ENOMEM;
 
 	if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index c69b221f5e3e..995cb5003133 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -152,11 +152,13 @@ static void evsel__free_stat_priv(struct evsel *evsel)
 	zfree(&evsel->stats);
 }
 
-static int evsel__alloc_prev_raw_counts(struct evsel *evsel, int ncpus, int nthreads)
+static int evsel__alloc_prev_raw_counts(struct evsel *evsel)
 {
+	int cpu_map_nr = evsel__nr_cpus(evsel);
+	int nthreads = perf_thread_map__nr(evsel->core.threads);
 	struct perf_counts *counts;
 
-	counts = perf_counts__new(ncpus, nthreads);
+	counts = perf_counts__new(cpu_map_nr, nthreads);
 	if (counts)
 		evsel->prev_raw_counts = counts;
 
@@ -177,12 +179,9 @@ static void evsel__reset_prev_raw_counts(struct evsel *evsel)
 
 static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
 {
-	int ncpus = evsel__nr_cpus(evsel);
-	int nthreads = perf_thread_map__nr(evsel->core.threads);
-
 	if (evsel__alloc_stat_priv(evsel) < 0 ||
-	    evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-	    (alloc_raw && evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+	    evsel__alloc_counts(evsel) < 0 ||
+	    (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0))
 		return -ENOMEM;
 
 	return 0;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:30 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:30 -0800
Subject: [PATCH v4 27/48] libperf: Switch cpu to more accurate cpu_map_idx
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-28-irogers@google.com>

Modify variable names and adopt perf_cpu_map__for_each_cpu in
perf_evsel__open. Renaming is done by looking for consistency in API
usage.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/evsel.c              | 88 +++++++++++++++--------------
 tools/lib/perf/include/perf/evsel.h | 10 ++--
 2 files changed, 50 insertions(+), 48 deletions(-)

diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 68f83d2c27c1..8028b5a4da69 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -43,18 +43,22 @@ void perf_evsel__delete(struct perf_evsel *evsel)
 	free(evsel);
 }
 
-#define FD(e, x, y) ((int *) xyarray__entry(e->fd, x, y))
-#define MMAP(e, x, y) (e->mmap ? ((struct perf_mmap *) xyarray__entry(e->mmap, x, y)) : NULL)
+#define FD(_evsel, _cpu_map_idx, _thread)				\
+	((int *)xyarray__entry(_evsel->fd, _cpu_map_idx, _thread))
+#define MMAP(_evsel, _cpu_map_idx, _thread)				\
+	(_evsel->mmap ? ((struct perf_mmap *) xyarray__entry(_evsel->mmap, _cpu_map_idx, _thread)) \
+		      : NULL)
 
 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
 	evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
 
 	if (evsel->fd) {
-		int cpu, thread;
-		for (cpu = 0; cpu < ncpus; cpu++) {
+		int idx, thread;
+
+		for (idx = 0; idx < ncpus; idx++) {
 			for (thread = 0; thread < nthreads; thread++) {
-				int *fd = FD(evsel, cpu, thread);
+				int *fd = FD(evsel, idx, thread);
 
 				if (fd)
 					*fd = -1;
@@ -80,7 +84,7 @@ sys_perf_event_open(struct perf_event_attr *attr,
 	return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
 }
 
-static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *group_fd)
+static int get_group_fd(struct perf_evsel *evsel, int cpu_map_idx, int thread, int *group_fd)
 {
 	struct perf_evsel *leader = evsel->leader;
 	int *fd;
@@ -97,7 +101,7 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *grou
 	if (!leader->fd)
 		return -ENOTCONN;
 
-	fd = FD(leader, cpu, thread);
+	fd = FD(leader, cpu_map_idx, thread);
 	if (fd == NULL || *fd == -1)
 		return -EBADF;
 
@@ -109,7 +113,7 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread, int *grou
 int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
 		     struct perf_thread_map *threads)
 {
-	int cpu, thread, err = 0;
+	int cpu, idx, thread, err = 0;
 
 	if (cpus == NULL) {
 		static struct perf_cpu_map *empty_cpu_map;
@@ -139,21 +143,21 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
 	    perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
 		return -ENOMEM;
 
-	for (cpu = 0; cpu < cpus->nr; cpu++) {
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		for (thread = 0; thread < threads->nr; thread++) {
 			int fd, group_fd, *evsel_fd;
 
-			evsel_fd = FD(evsel, cpu, thread);
+			evsel_fd = FD(evsel, idx, thread);
 			if (evsel_fd == NULL)
 				return -EINVAL;
 
-			err = get_group_fd(evsel, cpu, thread, &group_fd);
+			err = get_group_fd(evsel, idx, thread, &group_fd);
 			if (err < 0)
 				return err;
 
 			fd = sys_perf_event_open(&evsel->attr,
 						 threads->map[thread].pid,
-						 cpus->map[cpu], group_fd, 0);
+						 cpu, group_fd, 0);
 
 			if (fd < 0)
 				return -errno;
@@ -165,12 +169,12 @@ int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
 	return err;
 }
 
-static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu)
+static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu_map_idx)
 {
 	int thread;
 
 	for (thread = 0; thread < xyarray__max_y(evsel->fd); ++thread) {
-		int *fd = FD(evsel, cpu, thread);
+		int *fd = FD(evsel, cpu_map_idx, thread);
 
 		if (fd && *fd >= 0) {
 			close(*fd);
@@ -181,10 +185,8 @@ static void perf_evsel__close_fd_cpu(struct perf_evsel *evsel, int cpu)
 
 void perf_evsel__close_fd(struct perf_evsel *evsel)
 {
-	int cpu;
-
-	for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++)
-		perf_evsel__close_fd_cpu(evsel, cpu);
+	for (int idx = 0; idx < xyarray__max_x(evsel->fd); idx++)
+		perf_evsel__close_fd_cpu(evsel, idx);
 }
 
 void perf_evsel__free_fd(struct perf_evsel *evsel)
@@ -202,29 +204,29 @@ void perf_evsel__close(struct perf_evsel *evsel)
 	perf_evsel__free_fd(evsel);
 }
 
-void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu)
+void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu_map_idx)
 {
 	if (evsel->fd == NULL)
 		return;
 
-	perf_evsel__close_fd_cpu(evsel, cpu);
+	perf_evsel__close_fd_cpu(evsel, cpu_map_idx);
 }
 
 void perf_evsel__munmap(struct perf_evsel *evsel)
 {
-	int cpu, thread;
+	int idx, thread;
 
 	if (evsel->fd == NULL || evsel->mmap == NULL)
 		return;
 
-	for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
+	for (idx = 0; idx < xyarray__max_x(evsel->fd); idx++) {
 		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
-			int *fd = FD(evsel, cpu, thread);
+			int *fd = FD(evsel, idx, thread);
 
 			if (fd == NULL || *fd < 0)
 				continue;
 
-			perf_mmap__munmap(MMAP(evsel, cpu, thread));
+			perf_mmap__munmap(MMAP(evsel, idx, thread));
 		}
 	}
 
@@ -234,7 +236,7 @@ void perf_evsel__munmap(struct perf_evsel *evsel)
 
 int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 {
-	int ret, cpu, thread;
+	int ret, idx, thread;
 	struct perf_mmap_param mp = {
 		.prot = PROT_READ | PROT_WRITE,
 		.mask = (pages * page_size) - 1,
@@ -246,18 +248,18 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 	if (perf_evsel__alloc_mmap(evsel, xyarray__max_x(evsel->fd), xyarray__max_y(evsel->fd)) < 0)
 		return -ENOMEM;
 
-	for (cpu = 0; cpu < xyarray__max_x(evsel->fd); cpu++) {
+	for (idx = 0; idx < xyarray__max_x(evsel->fd); idx++) {
 		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
-			int *fd = FD(evsel, cpu, thread);
+			int *fd = FD(evsel, idx, thread);
 			struct perf_mmap *map;
 
 			if (fd == NULL || *fd < 0)
 				continue;
 
-			map = MMAP(evsel, cpu, thread);
+			map = MMAP(evsel, idx, thread);
 			perf_mmap__init(map, NULL, false, NULL);
 
-			ret = perf_mmap__mmap(map, &mp, *fd, cpu);
+			ret = perf_mmap__mmap(map, &mp, *fd, idx);
 			if (ret) {
 				perf_evsel__munmap(evsel);
 				return ret;
@@ -268,14 +270,14 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 	return 0;
 }
 
-void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread)
+void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu_map_idx, int thread)
 {
-	int *fd = FD(evsel, cpu, thread);
+	int *fd = FD(evsel, cpu_map_idx, thread);
 
-	if (fd == NULL || *fd < 0 || MMAP(evsel, cpu, thread) == NULL)
+	if (fd == NULL || *fd < 0 || MMAP(evsel, cpu_map_idx, thread) == NULL)
 		return NULL;
 
-	return MMAP(evsel, cpu, thread)->base;
+	return MMAP(evsel, cpu_map_idx, thread)->base;
 }
 
 int perf_evsel__read_size(struct perf_evsel *evsel)
@@ -303,19 +305,19 @@ int perf_evsel__read_size(struct perf_evsel *evsel)
 	return size;
 }
 
-int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread,
 		     struct perf_counts_values *count)
 {
 	size_t size = perf_evsel__read_size(evsel);
-	int *fd = FD(evsel, cpu, thread);
+	int *fd = FD(evsel, cpu_map_idx, thread);
 
 	memset(count, 0, sizeof(*count));
 
 	if (fd == NULL || *fd < 0)
 		return -EINVAL;
 
-	if (MMAP(evsel, cpu, thread) &&
-	    !perf_mmap__read_self(MMAP(evsel, cpu, thread), count))
+	if (MMAP(evsel, cpu_map_idx, thread) &&
+	    !perf_mmap__read_self(MMAP(evsel, cpu_map_idx, thread), count))
 		return 0;
 
 	if (readn(*fd, count->values, size) <= 0)
@@ -326,13 +328,13 @@ int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
 
 static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
 				 int ioc,  void *arg,
-				 int cpu)
+				 int cpu_map_idx)
 {
 	int thread;
 
 	for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
 		int err;
-		int *fd = FD(evsel, cpu, thread);
+		int *fd = FD(evsel, cpu_map_idx, thread);
 
 		if (fd == NULL || *fd < 0)
 			return -1;
@@ -346,9 +348,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel,
 	return 0;
 }
 
-int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu)
+int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
 {
-	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, cpu);
+	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_ENABLE, NULL, cpu_map_idx);
 }
 
 int perf_evsel__enable(struct perf_evsel *evsel)
@@ -361,9 +363,9 @@ int perf_evsel__enable(struct perf_evsel *evsel)
 	return err;
 }
 
-int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu)
+int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx)
 {
-	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, cpu);
+	return perf_evsel__run_ioctl(evsel, PERF_EVENT_IOC_DISABLE, NULL, cpu_map_idx);
 }
 
 int perf_evsel__disable(struct perf_evsel *evsel)
diff --git a/tools/lib/perf/include/perf/evsel.h b/tools/lib/perf/include/perf/evsel.h
index f401c7484bec..2a9516b42d15 100644
--- a/tools/lib/perf/include/perf/evsel.h
+++ b/tools/lib/perf/include/perf/evsel.h
@@ -28,16 +28,16 @@ LIBPERF_API void perf_evsel__delete(struct perf_evsel *evsel);
 LIBPERF_API int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
 				 struct perf_thread_map *threads);
 LIBPERF_API void perf_evsel__close(struct perf_evsel *evsel);
-LIBPERF_API void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu);
+LIBPERF_API void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu_map_idx);
 LIBPERF_API int perf_evsel__mmap(struct perf_evsel *evsel, int pages);
 LIBPERF_API void perf_evsel__munmap(struct perf_evsel *evsel);
-LIBPERF_API void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread);
-LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+LIBPERF_API void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu_map_idx, int thread);
+LIBPERF_API int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread,
 				 struct perf_counts_values *count);
 LIBPERF_API int perf_evsel__enable(struct perf_evsel *evsel);
-LIBPERF_API int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu);
+LIBPERF_API int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
 LIBPERF_API int perf_evsel__disable(struct perf_evsel *evsel);
-LIBPERF_API int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu);
+LIBPERF_API int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
 LIBPERF_API struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
 LIBPERF_API struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
 LIBPERF_API struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:31 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:31 -0800
Subject: [PATCH v4 28/48] libperf: Use cpu not index for evsel mmap
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-29-irogers@google.com>

Fix issue where evsel's CPU map index was being used as the mmap cpu.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/evsel.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index 8028b5a4da69..f1e1665ef4bd 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -252,6 +252,7 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
 			int *fd = FD(evsel, idx, thread);
 			struct perf_mmap *map;
+			int cpu = perf_cpu_map__cpu(evsel->cpus, idx);
 
 			if (fd == NULL || *fd < 0)
 				continue;
@@ -259,7 +260,7 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 			map = MMAP(evsel, idx, thread);
 			perf_mmap__init(map, NULL, false, NULL);
 
-			ret = perf_mmap__mmap(map, &mp, *fd, idx);
+			ret = perf_mmap__mmap(map, &mp, *fd, cpu);
 			if (ret) {
 				perf_evsel__munmap(evsel);
 				return ret;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:32 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:32 -0800
Subject: [PATCH v4 29/48] perf counts: Switch name cpu to cpu_map_idx
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-30-irogers@google.com>

Try to reduce confusion in particular when the cpu map doesn't contain
an entry for every CPU.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/counts.h | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
index 3e275e9c60d1..5de275194f2b 100644
--- a/tools/perf/util/counts.h
+++ b/tools/perf/util/counts.h
@@ -18,21 +18,21 @@ struct perf_counts {
 
 
 static inline struct perf_counts_values*
-perf_counts(struct perf_counts *counts, int cpu, int thread)
+perf_counts(struct perf_counts *counts, int cpu_map_idx, int thread)
 {
-	return xyarray__entry(counts->values, cpu, thread);
+	return xyarray__entry(counts->values, cpu_map_idx, thread);
 }
 
 static inline bool
-perf_counts__is_loaded(struct perf_counts *counts, int cpu, int thread)
+perf_counts__is_loaded(struct perf_counts *counts, int cpu_map_idx, int thread)
 {
-	return *((bool *) xyarray__entry(counts->loaded, cpu, thread));
+	return *((bool *) xyarray__entry(counts->loaded, cpu_map_idx, thread));
 }
 
 static inline void
-perf_counts__set_loaded(struct perf_counts *counts, int cpu, int thread, bool loaded)
+perf_counts__set_loaded(struct perf_counts *counts, int cpu_map_idx, int thread, bool loaded)
 {
-	*((bool *) xyarray__entry(counts->loaded, cpu, thread)) = loaded;
+	*((bool *) xyarray__entry(counts->loaded, cpu_map_idx, thread)) = loaded;
 }
 
 struct perf_counts *perf_counts__new(int ncpus, int nthreads);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:33 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:33 -0800
Subject: [PATCH v4 30/48] perf stat: Rename aggr_data cpu to imply it's an
 index
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-31-irogers@google.com>

Trying to make cpu maps less error prone.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index f48d1678861c..7e933a8fee68 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -626,7 +626,7 @@ struct aggr_data {
 	u64 ena, run, val;
 	struct aggr_cpu_id id;
 	int nr;
-	int cpu;
+	int cpu_map_idx;
 };
 
 static void aggr_cb(struct perf_stat_config *config,
@@ -878,9 +878,9 @@ static void counter_cb(struct perf_stat_config *config __maybe_unused,
 {
 	struct aggr_data *ad = data;
 
-	ad->val += perf_counts(counter->counts, ad->cpu, 0)->val;
-	ad->ena += perf_counts(counter->counts, ad->cpu, 0)->ena;
-	ad->run += perf_counts(counter->counts, ad->cpu, 0)->run;
+	ad->val += perf_counts(counter->counts, ad->cpu_map_idx, 0)->val;
+	ad->ena += perf_counts(counter->counts, ad->cpu_map_idx, 0)->ena;
+	ad->run += perf_counts(counter->counts, ad->cpu_map_idx, 0)->run;
 }
 
 /*
@@ -897,7 +897,7 @@ static void print_counter(struct perf_stat_config *config,
 	struct aggr_cpu_id id;
 
 	for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
-		struct aggr_data ad = { .cpu = cpu };
+		struct aggr_data ad = { .cpu_map_idx = cpu };
 
 		if (!collect_data(config, counter, counter_cb, &ad))
 			return;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:34 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:34 -0800
Subject: [PATCH v4 31/48] perf stat: Use perf_cpu_map__for_each_cpu
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-32-irogers@google.com>

Correct in print_counter where an index was being used as a cpu.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 7e933a8fee68..0f192360b6c6 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -4,6 +4,7 @@
 #include <linux/string.h>
 #include <linux/time64.h>
 #include <math.h>
+#include <perf/cpumap.h>
 #include "color.h"
 #include "counts.h"
 #include "evlist.h"
@@ -732,7 +733,7 @@ static void print_aggr(struct perf_stat_config *config,
 		evlist__for_each_entry(evlist, counter) {
 			print_counter_aggrdata(config, counter, s,
 					       prefix, metric_only,
-					       &first, -1);
+					       &first, /*cpu=*/-1);
 		}
 		if (metric_only)
 			fputc('\n', output);
@@ -893,11 +894,11 @@ static void print_counter(struct perf_stat_config *config,
 	FILE *output = config->output;
 	u64 ena, run, val;
 	double uval;
-	int cpu;
+	int idx, cpu;
 	struct aggr_cpu_id id;
 
-	for (cpu = 0; cpu < evsel__nr_cpus(counter); cpu++) {
-		struct aggr_data ad = { .cpu_map_idx = cpu };
+	perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
+		struct aggr_data ad = { .cpu_map_idx = idx };
 
 		if (!collect_data(config, counter, counter_cb, &ad))
 			return;
@@ -1248,7 +1249,7 @@ static void print_percore(struct perf_stat_config *config,
 
 		print_counter_aggrdata(config, counter, s,
 				       prefix, metric_only,
-				       &first, -1);
+				       &first, /*cpu=*/-1);
 	}
 
 	if (metric_only)
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:35 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:35 -0800
Subject: [PATCH v4 32/48] perf script: Use for each cpu to aid readability
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-33-irogers@google.com>

Use perf_cpu_map__for_each_cpu to help with readability.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-script.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index c9b3002ec254..f40319144856 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2115,8 +2115,7 @@ static struct scripting_ops	*scripting_ops;
 static void __process_stat(struct evsel *counter, u64 tstamp)
 {
 	int nthreads = perf_thread_map__nr(counter->core.threads);
-	int ncpus = evsel__nr_cpus(counter);
-	int cpu, thread;
+	int idx, cpu, thread;
 	static int header_printed;
 
 	if (counter->core.system_wide)
@@ -2129,13 +2128,13 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
 	}
 
 	for (thread = 0; thread < nthreads; thread++) {
-		for (cpu = 0; cpu < ncpus; cpu++) {
+		perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
 			struct perf_counts_values *counts;
 
 			counts = perf_counts(counter->counts, cpu, thread);
 
 			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
-				counter->core.cpus->map[cpu],
+				cpu,
 				perf_thread_map__pid(counter->core.threads, thread),
 				counts->val,
 				counts->ena,
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:36 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:36 -0800
Subject: [PATCH v4 33/48] libperf: Allow NULL in perf_cpu_map__idx
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-34-irogers@google.com>

Return -1, not found, if NULL is passed.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/cpumap.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
index 3c36a06771af..eacea3ab965a 100644
--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -270,8 +270,13 @@ bool perf_cpu_map__empty(const struct perf_cpu_map *map)
 
 int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu)
 {
-	int low = 0, high = cpus->nr;
+	int low, high;
 
+	if (!cpus)
+		return -1;
+
+	low = 0;
+	high = cpus->nr;
 	while (low < high) {
 		int idx = (low + high) / 2,
 		    cpu_at_idx = cpus->map[idx];
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:37 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:37 -0800
Subject: [PATCH v4 34/48] perf evlist: Refactor evlist__for_each_cpu.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-35-irogers@google.com>

Previously evlist__for_each_cpu needed to iterate over the evlist in an
inner loop and call "skip" routines. Refactor this so that the iteratr
is smarter and the next function can update both the current CPU and
evsel.

By using a cpu map index, fix apparent off-by-1 in __run_perf_stat's
call to perf_evsel__close_cpu.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c | 179 ++++++++++++++++++--------------------
 tools/perf/util/evlist.c  | 146 +++++++++++++++++--------------
 tools/perf/util/evlist.h  |  50 +++++++++--
 tools/perf/util/evsel.h   |   1 -
 4 files changed, 210 insertions(+), 166 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 98f80c217279..f31bc34bd4cc 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -405,36 +405,33 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
 
 static int read_affinity_counters(struct timespec *rs)
 {
-	struct evsel *counter;
-	struct affinity affinity;
-	int i, ncpus, cpu;
+	struct evlist_cpu_iterator evlist_cpu_itr;
+	struct affinity saved_affinity, *affinity;
 
 	if (all_counters_use_bpf)
 		return 0;
 
-	if (affinity__setup(&affinity) < 0)
+	if (!target__has_cpu(&target) || target__has_per_thread(&target))
+		affinity = NULL;
+	else if (affinity__setup(&saved_affinity) < 0)
 		return -1;
+	else
+		affinity = &saved_affinity;
 
-	ncpus = perf_cpu_map__nr(evsel_list->core.all_cpus);
-	if (!target__has_cpu(&target) || target__has_per_thread(&target))
-		ncpus = 1;
-	evlist__for_each_cpu(evsel_list, i, cpu) {
-		if (i >= ncpus)
-			break;
-		affinity__set(&affinity, cpu);
+	evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) {
+		struct evsel *counter = evlist_cpu_itr.evsel;
 
-		evlist__for_each_entry(evsel_list, counter) {
-			if (evsel__cpu_iter_skip(counter, cpu))
-				continue;
-			if (evsel__is_bpf(counter))
-				continue;
-			if (!counter->err) {
-				counter->err = read_counter_cpu(counter, rs,
-								counter->cpu_iter - 1);
-			}
+		if (evsel__is_bpf(counter))
+			continue;
+
+		if (!counter->err) {
+			counter->err = read_counter_cpu(counter, rs,
+							evlist_cpu_itr.cpu_map_idx);
 		}
 	}
-	affinity__cleanup(&affinity);
+	if (affinity)
+		affinity__cleanup(&saved_affinity);
+
 	return 0;
 }
 
@@ -788,8 +785,9 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
 	int status = 0;
 	const bool forks = (argc > 0);
 	bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false;
+	struct evlist_cpu_iterator evlist_cpu_itr;
 	struct affinity affinity;
-	int i, cpu, err;
+	int err;
 	bool second_pass = false;
 
 	if (forks) {
@@ -813,102 +811,97 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx)
 			all_counters_use_bpf = false;
 	}
 
-	evlist__for_each_cpu (evsel_list, i, cpu) {
+	evlist__for_each_cpu(evlist_cpu_itr, evsel_list, &affinity) {
+		counter = evlist_cpu_itr.evsel;
+
 		/*
 		 * bperf calls evsel__open_per_cpu() in bperf__load(), so
 		 * no need to call it again here.
 		 */
 		if (target.use_bpf)
 			break;
-		affinity__set(&affinity, cpu);
 
-		evlist__for_each_entry(evsel_list, counter) {
-			if (evsel__cpu_iter_skip(counter, cpu))
+		if (counter->reset_group || counter->errored)
+			continue;
+		if (evsel__is_bpf(counter))
+			continue;
+try_again:
+		if (create_perf_stat_counter(counter, &stat_config, &target,
+					     evlist_cpu_itr.cpu_map_idx) < 0) {
+
+			/*
+			 * Weak group failed. We cannot just undo this here
+			 * because earlier CPUs might be in group mode, and the kernel
+			 * doesn't support mixing group and non group reads. Defer
+			 * it to later.
+			 * Don't close here because we're in the wrong affinity.
+			 */
+			if ((errno == EINVAL || errno == EBADF) &&
+				evsel__leader(counter) != counter &&
+				counter->weak_group) {
+				evlist__reset_weak_group(evsel_list, counter, false);
+				assert(counter->reset_group);
+				second_pass = true;
 				continue;
-			if (counter->reset_group || counter->errored)
+			}
+
+			switch (stat_handle_error(counter)) {
+			case COUNTER_FATAL:
+				return -1;
+			case COUNTER_RETRY:
+				goto try_again;
+			case COUNTER_SKIP:
 				continue;
-			if (evsel__is_bpf(counter))
+			default:
+				break;
+			}
+
+		}
+		counter->supported = true;
+	}
+
+	if (second_pass) {
+		/*
+		 * Now redo all the weak group after closing them,
+		 * and also close errored counters.
+		 */
+
+		/* First close errored or weak retry */
+		evlist__for_each_cpu(evlist_cpu_itr, evsel_list, &affinity) {
+			counter = evlist_cpu_itr.evsel;
+
+			if (!counter->reset_group && !counter->errored)
 				continue;
-try_again:
+
+			perf_evsel__close_cpu(&counter->core, evlist_cpu_itr.cpu_map_idx);
+		}
+		/* Now reopen weak */
+		evlist__for_each_cpu(evlist_cpu_itr, evsel_list, &affinity) {
+			counter = evlist_cpu_itr.evsel;
+
+			if (!counter->reset_group && !counter->errored)
+				continue;
+			if (!counter->reset_group)
+				continue;
+try_again_reset:
+			pr_debug2("reopening weak %s\n", evsel__name(counter));
 			if (create_perf_stat_counter(counter, &stat_config, &target,
-						     counter->cpu_iter - 1) < 0) {
-
-				/*
-				 * Weak group failed. We cannot just undo this here
-				 * because earlier CPUs might be in group mode, and the kernel
-				 * doesn't support mixing group and non group reads. Defer
-				 * it to later.
-				 * Don't close here because we're in the wrong affinity.
-				 */
-				if ((errno == EINVAL || errno == EBADF) &&
-				    evsel__leader(counter) != counter &&
-				    counter->weak_group) {
-					evlist__reset_weak_group(evsel_list, counter, false);
-					assert(counter->reset_group);
-					second_pass = true;
-					continue;
-				}
+						     evlist_cpu_itr.cpu_map_idx) < 0) {
 
 				switch (stat_handle_error(counter)) {
 				case COUNTER_FATAL:
 					return -1;
 				case COUNTER_RETRY:
-					goto try_again;
+					goto try_again_reset;
 				case COUNTER_SKIP:
 					continue;
 				default:
 					break;
 				}
-
 			}
 			counter->supported = true;
 		}
 	}
-
-	if (second_pass) {
-		/*
-		 * Now redo all the weak group after closing them,
-		 * and also close errored counters.
-		 */
-
-		evlist__for_each_cpu(evsel_list, i, cpu) {
-			affinity__set(&affinity, cpu);
-			/* First close errored or weak retry */
-			evlist__for_each_entry(evsel_list, counter) {
-				if (!counter->reset_group && !counter->errored)
-					continue;
-				if (evsel__cpu_iter_skip_no_inc(counter, cpu))
-					continue;
-				perf_evsel__close_cpu(&counter->core, counter->cpu_iter);
-			}
-			/* Now reopen weak */
-			evlist__for_each_entry(evsel_list, counter) {
-				if (!counter->reset_group && !counter->errored)
-					continue;
-				if (evsel__cpu_iter_skip(counter, cpu))
-					continue;
-				if (!counter->reset_group)
-					continue;
-try_again_reset:
-				pr_debug2("reopening weak %s\n", evsel__name(counter));
-				if (create_perf_stat_counter(counter, &stat_config, &target,
-							     counter->cpu_iter - 1) < 0) {
-
-					switch (stat_handle_error(counter)) {
-					case COUNTER_FATAL:
-						return -1;
-					case COUNTER_RETRY:
-						goto try_again_reset;
-					case COUNTER_SKIP:
-						continue;
-					default:
-						break;
-					}
-				}
-				counter->supported = true;
-			}
-		}
-	}
 	affinity__cleanup(&affinity);
 
 	evlist__for_each_entry(evsel_list, counter) {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 5f92319ce258..39d294f6c321 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -342,36 +342,65 @@ static int evlist__nr_threads(struct evlist *evlist, struct evsel *evsel)
 		return perf_thread_map__nr(evlist->core.threads);
 }
 
-void evlist__cpu_iter_start(struct evlist *evlist)
-{
-	struct evsel *pos;
-
-	/*
-	 * Reset the per evsel cpu_iter. This is needed because
-	 * each evsel's cpumap may have a different index space,
-	 * and some operations need the index to modify
-	 * the FD xyarray (e.g. open, close)
-	 */
-	evlist__for_each_entry(evlist, pos)
-		pos->cpu_iter = 0;
-}
+struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affinity *affinity)
+{
+	struct evlist_cpu_iterator itr = {
+		.container = evlist,
+		.evsel = evlist__first(evlist),
+		.cpu_map_idx = 0,
+		.evlist_cpu_map_idx = 0,
+		.evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus),
+		.cpu = -1,
+		.affinity = affinity,
+	};
 
-bool evsel__cpu_iter_skip_no_inc(struct evsel *ev, int cpu)
-{
-	if (ev->cpu_iter >= ev->core.cpus->nr)
-		return true;
-	if (cpu >= 0 && ev->core.cpus->map[ev->cpu_iter] != cpu)
-		return true;
-	return false;
+	if (itr.affinity) {
+		itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0);
+		affinity__set(itr.affinity, itr.cpu);
+		itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu);
+		/*
+		 * If this CPU isn't in the evsel's cpu map then advance through
+		 * the list.
+		 */
+		if (itr.cpu_map_idx == -1)
+			evlist_cpu_iterator__next(&itr);
+	}
+	return itr;
+}
+
+void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr)
+{
+	while (evlist_cpu_itr->evsel != evlist__last(evlist_cpu_itr->container)) {
+		evlist_cpu_itr->evsel = evsel__next(evlist_cpu_itr->evsel);
+		evlist_cpu_itr->cpu_map_idx =
+			perf_cpu_map__idx(evlist_cpu_itr->evsel->core.cpus,
+					  evlist_cpu_itr->cpu);
+		if (evlist_cpu_itr->cpu_map_idx != -1)
+			return;
+	}
+	evlist_cpu_itr->evlist_cpu_map_idx++;
+	if (evlist_cpu_itr->evlist_cpu_map_idx < evlist_cpu_itr->evlist_cpu_map_nr) {
+		evlist_cpu_itr->evsel = evlist__first(evlist_cpu_itr->container);
+		evlist_cpu_itr->cpu =
+			perf_cpu_map__cpu(evlist_cpu_itr->container->core.all_cpus,
+					  evlist_cpu_itr->evlist_cpu_map_idx);
+		if (evlist_cpu_itr->affinity)
+			affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu);
+		evlist_cpu_itr->cpu_map_idx =
+			perf_cpu_map__idx(evlist_cpu_itr->evsel->core.cpus,
+					  evlist_cpu_itr->cpu);
+		/*
+		 * If this CPU isn't in the evsel's cpu map then advance through
+		 * the list.
+		 */
+		if (evlist_cpu_itr->cpu_map_idx == -1)
+			evlist_cpu_iterator__next(evlist_cpu_itr);
+	}
 }
 
-bool evsel__cpu_iter_skip(struct evsel *ev, int cpu)
+bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu_itr)
 {
-	if (!evsel__cpu_iter_skip_no_inc(ev, cpu)) {
-		ev->cpu_iter++;
-		return false;
-	}
-	return true;
+	return evlist_cpu_itr->evlist_cpu_map_idx >= evlist_cpu_itr->evlist_cpu_map_nr;
 }
 
 static int evsel__strcmp(struct evsel *pos, char *evsel_name)
@@ -400,31 +429,26 @@ static int evlist__is_enabled(struct evlist *evlist)
 static void __evlist__disable(struct evlist *evlist, char *evsel_name)
 {
 	struct evsel *pos;
+	struct evlist_cpu_iterator evlist_cpu_itr;
 	struct affinity affinity;
-	int cpu, i, imm = 0;
 	bool has_imm = false;
 
 	if (affinity__setup(&affinity) < 0)
 		return;
 
 	/* Disable 'immediate' events last */
-	for (imm = 0; imm <= 1; imm++) {
-		evlist__for_each_cpu(evlist, i, cpu) {
-			affinity__set(&affinity, cpu);
-
-			evlist__for_each_entry(evlist, pos) {
-				if (evsel__strcmp(pos, evsel_name))
-					continue;
-				if (evsel__cpu_iter_skip(pos, cpu))
-					continue;
-				if (pos->disabled || !evsel__is_group_leader(pos) || !pos->core.fd)
-					continue;
-				if (pos->immediate)
-					has_imm = true;
-				if (pos->immediate != imm)
-					continue;
-				evsel__disable_cpu(pos, pos->cpu_iter - 1);
-			}
+	for (int imm = 0; imm <= 1; imm++) {
+		evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) {
+			pos = evlist_cpu_itr.evsel;
+			if (evsel__strcmp(pos, evsel_name))
+				continue;
+			if (pos->disabled || !evsel__is_group_leader(pos) || !pos->core.fd)
+				continue;
+			if (pos->immediate)
+				has_imm = true;
+			if (pos->immediate != imm)
+				continue;
+			evsel__disable_cpu(pos, evlist_cpu_itr.cpu_map_idx);
 		}
 		if (!has_imm)
 			break;
@@ -462,24 +486,19 @@ void evlist__disable_evsel(struct evlist *evlist, char *evsel_name)
 static void __evlist__enable(struct evlist *evlist, char *evsel_name)
 {
 	struct evsel *pos;
+	struct evlist_cpu_iterator evlist_cpu_itr;
 	struct affinity affinity;
-	int cpu, i;
 
 	if (affinity__setup(&affinity) < 0)
 		return;
 
-	evlist__for_each_cpu(evlist, i, cpu) {
-		affinity__set(&affinity, cpu);
-
-		evlist__for_each_entry(evlist, pos) {
-			if (evsel__strcmp(pos, evsel_name))
-				continue;
-			if (evsel__cpu_iter_skip(pos, cpu))
-				continue;
-			if (!evsel__is_group_leader(pos) || !pos->core.fd)
-				continue;
-			evsel__enable_cpu(pos, pos->cpu_iter - 1);
-		}
+	evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) {
+		pos = evlist_cpu_itr.evsel;
+		if (evsel__strcmp(pos, evsel_name))
+			continue;
+		if (!evsel__is_group_leader(pos) || !pos->core.fd)
+			continue;
+		evsel__enable_cpu(pos, evlist_cpu_itr.cpu_map_idx);
 	}
 	affinity__cleanup(&affinity);
 	evlist__for_each_entry(evlist, pos) {
@@ -1264,8 +1283,8 @@ void evlist__set_selected(struct evlist *evlist, struct evsel *evsel)
 void evlist__close(struct evlist *evlist)
 {
 	struct evsel *evsel;
+	struct evlist_cpu_iterator evlist_cpu_itr;
 	struct affinity affinity;
-	int cpu, i;
 
 	/*
 	 * With perf record core.cpus is usually NULL.
@@ -1279,15 +1298,12 @@ void evlist__close(struct evlist *evlist)
 
 	if (affinity__setup(&affinity) < 0)
 		return;
-	evlist__for_each_cpu(evlist, i, cpu) {
-		affinity__set(&affinity, cpu);
 
-		evlist__for_each_entry_reverse(evlist, evsel) {
-			if (evsel__cpu_iter_skip(evsel, cpu))
-			    continue;
-			perf_evsel__close_cpu(&evsel->core, evsel->cpu_iter - 1);
-		}
+	evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) {
+		perf_evsel__close_cpu(&evlist_cpu_itr.evsel->core,
+				      evlist_cpu_itr.cpu_map_idx);
 	}
+
 	affinity__cleanup(&affinity);
 	evlist__for_each_entry_reverse(evlist, evsel) {
 		perf_evsel__free_fd(&evsel->core);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 27594900a052..57828ebfcb61 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -327,17 +327,53 @@ void evlist__to_front(struct evlist *evlist, struct evsel *move_evsel);
 #define evlist__for_each_entry_safe(evlist, tmp, evsel) \
 	__evlist__for_each_entry_safe(&(evlist)->core.entries, tmp, evsel)
 
-#define evlist__for_each_cpu(evlist, index, cpu)	\
-	evlist__cpu_iter_start(evlist);			\
-	perf_cpu_map__for_each_cpu (cpu, index, (evlist)->core.all_cpus)
+/** Iterator state for evlist__for_each_cpu */
+struct evlist_cpu_iterator {
+	/** The list being iterated through. */
+	struct evlist *container;
+	/** The current evsel of the iterator. */
+	struct evsel *evsel;
+	/** The CPU map index corresponding to the evsel->core.cpus for the current CPU. */
+	int cpu_map_idx;
+	/**
+	 * The CPU map index corresponding to evlist->core.all_cpus for the
+	 * current CPU.  Distinct from cpu_map_idx as the evsel's cpu map may
+	 * contain fewer entries.
+	 */
+	int evlist_cpu_map_idx;
+	/** The number of CPU map entries in evlist->core.all_cpus. */
+	int evlist_cpu_map_nr;
+	/** The current CPU of the iterator. */
+	int cpu;
+	/** If present, used to set the affinity when switching between CPUs. */
+	struct affinity *affinity;
+};
+
+/**
+ * evlist__for_each_cpu - without affinity, iterate over the evlist. With
+ *                        affinity, iterate over all CPUs and then the evlist
+ *                        for each evsel on that CPU. When switching between
+ *                        CPUs the affinity is set to the CPU to avoid IPIs
+ *                        during syscalls.
+ * @evlist_cpu_itr: the iterator instance.
+ * @evlist: evlist instance to iterate.
+ * @affinity: NULL or used to set the affinity to the current CPU.
+ */
+#define evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity)		\
+	for ((evlist_cpu_itr) = evlist__cpu_begin(evlist, affinity);	\
+	     !evlist_cpu_iterator__end(&evlist_cpu_itr);		\
+	     evlist_cpu_iterator__next(&evlist_cpu_itr))
+
+/** Returns an iterator set to the first CPU/evsel of evlist. */
+struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affinity *affinity);
+/** Move to next element in iterator, updating CPU, evsel and the affinity. */
+void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr);
+/** Returns true when iterator is at the end of the CPUs and evlist. */
+bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu_itr);
 
 struct evsel *evlist__get_tracking_event(struct evlist *evlist);
 void evlist__set_tracking_event(struct evlist *evlist, struct evsel *tracking_evsel);
 
-void evlist__cpu_iter_start(struct evlist *evlist);
-bool evsel__cpu_iter_skip(struct evsel *ev, int cpu);
-bool evsel__cpu_iter_skip_no_inc(struct evsel *ev, int cpu);
-
 struct evsel *evlist__find_evsel_by_str(struct evlist *evlist, const char *str);
 
 struct evsel *evlist__event2evsel(struct evlist *evlist, union perf_event *event);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 99aa3363def7..7cb7c9c77ab0 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -121,7 +121,6 @@ struct evsel {
 	bool			errored;
 	struct hashmap		*per_pkg_mask;
 	int			err;
-	int			cpu_iter;
 	struct {
 		evsel__sb_cb_t	*cb;
 		void		*data;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:38 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:38 -0800
Subject: [PATCH v4 35/48] perf evsel: Pass cpu not cpu map index to synthesize
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-36-irogers@google.com>

evsel__write_stat_event was incorrectly passing a cpu map index rather
than a CPU to perf_event__synthesize_stat.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index f31bc34bd4cc..ec252579b587 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -327,10 +327,11 @@ static int write_stat_round_event(u64 tm, u64 type)
 
 #define SID(e, x, y) xyarray__entry(e->core.sample_id, x, y)
 
-static int evsel__write_stat_event(struct evsel *counter, u32 cpu, u32 thread,
+static int evsel__write_stat_event(struct evsel *counter, int cpu_map_idx, u32 thread,
 				   struct perf_counts_values *count)
 {
-	struct perf_sample_id *sid = SID(counter, cpu, thread);
+	struct perf_sample_id *sid = SID(counter, cpu_map_idx, thread);
+	int cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx);
 
 	return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
 					   process_synthesized_event, NULL);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:39 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:39 -0800
Subject: [PATCH v4 36/48] perf stat: Correct variable name for read counter
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-37-irogers@google.com>

Switch from cpu to cpu_map_idx to reduce confusion.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-stat.c | 24 ++++++++++++------------
 tools/perf/util/evsel.c   | 30 +++++++++++++++---------------
 tools/perf/util/evsel.h   | 16 ++++++++--------
 3 files changed, 35 insertions(+), 35 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ec252579b587..68543bc7459f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -337,25 +337,25 @@ static int evsel__write_stat_event(struct evsel *counter, int cpu_map_idx, u32 t
 					   process_synthesized_event, NULL);
 }
 
-static int read_single_counter(struct evsel *counter, int cpu,
+static int read_single_counter(struct evsel *counter, int cpu_map_idx,
 			       int thread, struct timespec *rs)
 {
 	if (counter->tool_event == PERF_TOOL_DURATION_TIME) {
 		u64 val = rs->tv_nsec + rs->tv_sec*1000000000ULL;
 		struct perf_counts_values *count =
-			perf_counts(counter->counts, cpu, thread);
+			perf_counts(counter->counts, cpu_map_idx, thread);
 		count->ena = count->run = val;
 		count->val = val;
 		return 0;
 	}
-	return evsel__read_counter(counter, cpu, thread);
+	return evsel__read_counter(counter, cpu_map_idx, thread);
 }
 
 /*
  * Read out the results of a single counter:
  * do not aggregate counts across CPUs in system-wide mode
  */
-static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
+static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu_map_idx)
 {
 	int nthreads = perf_thread_map__nr(evsel_list->core.threads);
 	int thread;
@@ -369,24 +369,24 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
 	for (thread = 0; thread < nthreads; thread++) {
 		struct perf_counts_values *count;
 
-		count = perf_counts(counter->counts, cpu, thread);
+		count = perf_counts(counter->counts, cpu_map_idx, thread);
 
 		/*
 		 * The leader's group read loads data into its group members
 		 * (via evsel__read_counter()) and sets their count->loaded.
 		 */
-		if (!perf_counts__is_loaded(counter->counts, cpu, thread) &&
-		    read_single_counter(counter, cpu, thread, rs)) {
+		if (!perf_counts__is_loaded(counter->counts, cpu_map_idx, thread) &&
+		    read_single_counter(counter, cpu_map_idx, thread, rs)) {
 			counter->counts->scaled = -1;
-			perf_counts(counter->counts, cpu, thread)->ena = 0;
-			perf_counts(counter->counts, cpu, thread)->run = 0;
+			perf_counts(counter->counts, cpu_map_idx, thread)->ena = 0;
+			perf_counts(counter->counts, cpu_map_idx, thread)->run = 0;
 			return -1;
 		}
 
-		perf_counts__set_loaded(counter->counts, cpu, thread, false);
+		perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, false);
 
 		if (STAT_RECORD) {
-			if (evsel__write_stat_event(counter, cpu, thread, count)) {
+			if (evsel__write_stat_event(counter, cpu_map_idx, thread, count)) {
 				pr_err("failed to write stat event\n");
 				return -1;
 			}
@@ -396,7 +396,7 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu)
 			fprintf(stat_config.output,
 				"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
 					evsel__name(counter),
-					cpu,
+					perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx),
 					count->val, count->ena, count->run);
 		}
 	}
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 6c9af21776e6..b4a2c5034cfe 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1476,11 +1476,11 @@ void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
 	count->run = count->run - tmp.run;
 }
 
-static int evsel__read_one(struct evsel *evsel, int cpu, int thread)
+static int evsel__read_one(struct evsel *evsel, int cpu_map_idx, int thread)
 {
-	struct perf_counts_values *count = perf_counts(evsel->counts, cpu, thread);
+	struct perf_counts_values *count = perf_counts(evsel->counts, cpu_map_idx, thread);
 
-	return perf_evsel__read(&evsel->core, cpu, thread, count);
+	return perf_evsel__read(&evsel->core, cpu_map_idx, thread, count);
 }
 
 static void evsel__set_count(struct evsel *counter, int cpu, int thread, u64 val, u64 ena, u64 run)
@@ -1530,7 +1530,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu, int thread,
 	return 0;
 }
 
-static int evsel__read_group(struct evsel *leader, int cpu, int thread)
+static int evsel__read_group(struct evsel *leader, int cpu_map_idx, int thread)
 {
 	struct perf_stat_evsel *ps = leader->stats;
 	u64 read_format = leader->core.attr.read_format;
@@ -1551,42 +1551,42 @@ static int evsel__read_group(struct evsel *leader, int cpu, int thread)
 		ps->group_data = data;
 	}
 
-	if (FD(leader, cpu, thread) < 0)
+	if (FD(leader, cpu_map_idx, thread) < 0)
 		return -EINVAL;
 
-	if (readn(FD(leader, cpu, thread), data, size) <= 0)
+	if (readn(FD(leader, cpu_map_idx, thread), data, size) <= 0)
 		return -errno;
 
-	return evsel__process_group_data(leader, cpu, thread, data);
+	return evsel__process_group_data(leader, cpu_map_idx, thread, data);
 }
 
-int evsel__read_counter(struct evsel *evsel, int cpu, int thread)
+int evsel__read_counter(struct evsel *evsel, int cpu_map_idx, int thread)
 {
 	u64 read_format = evsel->core.attr.read_format;
 
 	if (read_format & PERF_FORMAT_GROUP)
-		return evsel__read_group(evsel, cpu, thread);
+		return evsel__read_group(evsel, cpu_map_idx, thread);
 
-	return evsel__read_one(evsel, cpu, thread);
+	return evsel__read_one(evsel, cpu_map_idx, thread);
 }
 
-int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale)
+int __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool scale)
 {
 	struct perf_counts_values count;
 	size_t nv = scale ? 3 : 1;
 
-	if (FD(evsel, cpu, thread) < 0)
+	if (FD(evsel, cpu_map_idx, thread) < 0)
 		return -EINVAL;
 
 	if (evsel->counts == NULL && evsel__alloc_counts(evsel) < 0)
 		return -ENOMEM;
 
-	if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0)
+	if (readn(FD(evsel, cpu_map_idx, thread), &count, nv * sizeof(u64)) <= 0)
 		return -errno;
 
-	evsel__compute_deltas(evsel, cpu, thread, &count);
+	evsel__compute_deltas(evsel, cpu_map_idx, thread, &count);
 	perf_counts_values__scale(&count, scale, NULL);
-	*perf_counts(evsel->counts, cpu, thread) = count;
+	*perf_counts(evsel->counts, cpu_map_idx, thread) = count;
 	return 0;
 }
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 7cb7c9c77ab0..c3db41282400 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -333,32 +333,32 @@ static inline bool evsel__match2(struct evsel *e1, struct evsel *e2)
 	       (e1->core.attr.config == e2->core.attr.config);
 }
 
-int evsel__read_counter(struct evsel *evsel, int cpu, int thread);
+int evsel__read_counter(struct evsel *evsel, int cpu_map_idx, int thread);
 
-int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale);
+int __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool scale);
 
 /**
  * evsel__read_on_cpu - Read out the results on a CPU and thread
  *
  * @evsel - event selector to read value
- * @cpu - CPU of interest
+ * @cpu_map_idx - CPU of interest
  * @thread - thread of interest
  */
-static inline int evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread)
+static inline int evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread)
 {
-	return __evsel__read_on_cpu(evsel, cpu, thread, false);
+	return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, false);
 }
 
 /**
  * evsel__read_on_cpu_scaled - Read out the results on a CPU and thread, scaled
  *
  * @evsel - event selector to read value
- * @cpu - CPU of interest
+ * @cpu_map_idx - CPU of interest
  * @thread - thread of interest
  */
-static inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu, int thread)
+static inline int evsel__read_on_cpu_scaled(struct evsel *evsel, int cpu_map_idx, int thread)
 {
-	return __evsel__read_on_cpu(evsel, cpu, thread, true);
+	return __evsel__read_on_cpu(evsel, cpu_map_idx, thread, true);
 }
 
 int evsel__parse_sample(struct evsel *evsel, union perf_event *event,
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:40 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:40 -0800
Subject: [PATCH v4 37/48] perf evsel: Rename CPU around get_group_fd
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-38-irogers@google.com>

CPU is really a cpu map index, change names to make code more intention
revealing.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/evsel.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b4a2c5034cfe..4b3ba4408af2 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1591,27 +1591,27 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool
 }
 
 static int evsel__match_other_cpu(struct evsel *evsel, struct evsel *other,
-				  int cpu)
+				  int cpu_map_idx)
 {
-	int cpuid;
+	int cpu;
 
-	cpuid = perf_cpu_map__cpu(evsel->core.cpus, cpu);
-	return perf_cpu_map__idx(other->core.cpus, cpuid);
+	cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx);
+	return perf_cpu_map__idx(other->core.cpus, cpu);
 }
 
-static int evsel__hybrid_group_cpu(struct evsel *evsel, int cpu)
+static int evsel__hybrid_group_cpu_map_idx(struct evsel *evsel, int cpu_map_idx)
 {
 	struct evsel *leader = evsel__leader(evsel);
 
 	if ((evsel__is_hybrid(evsel) && !evsel__is_hybrid(leader)) ||
 	    (!evsel__is_hybrid(evsel) && evsel__is_hybrid(leader))) {
-		return evsel__match_other_cpu(evsel, leader, cpu);
+		return evsel__match_other_cpu(evsel, leader, cpu_map_idx);
 	}
 
-	return cpu;
+	return cpu_map_idx;
 }
 
-static int get_group_fd(struct evsel *evsel, int cpu, int thread)
+static int get_group_fd(struct evsel *evsel, int cpu_map_idx, int thread)
 {
 	struct evsel *leader = evsel__leader(evsel);
 	int fd;
@@ -1625,11 +1625,11 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread)
 	 */
 	BUG_ON(!leader->core.fd);
 
-	cpu = evsel__hybrid_group_cpu(evsel, cpu);
-	if (cpu == -1)
+	cpu_map_idx = evsel__hybrid_group_cpu_map_idx(evsel, cpu_map_idx);
+	if (cpu_map_idx == -1)
 		return -1;
 
-	fd = FD(leader, cpu, thread);
+	fd = FD(leader, cpu_map_idx, thread);
 	BUG_ON(fd == -1);
 
 	return fd;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:41 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:41 -0800
Subject: [PATCH v4 38/48] perf evsel: Reduce scope of
 evsel__ignore_missing_thread
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-39-irogers@google.com>

Move to being static.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/evsel.c | 8 ++++----
 tools/perf/util/evsel.h | 4 ----
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 4b3ba4408af2..8911ebde54d6 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1666,10 +1666,10 @@ static int update_fds(struct evsel *evsel,
 	return 0;
 }
 
-bool evsel__ignore_missing_thread(struct evsel *evsel,
-				  int nr_cpus, int cpu,
-				  struct perf_thread_map *threads,
-				  int thread, int err)
+static bool evsel__ignore_missing_thread(struct evsel *evsel,
+					 int nr_cpus, int cpu,
+					 struct perf_thread_map *threads,
+					 int thread, int err)
 {
 	pid_t ignore_pid = perf_thread_map__pid(threads, thread);
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index c3db41282400..84e597f6c395 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -301,10 +301,6 @@ bool evsel__detect_missing_features(struct evsel *evsel);
 enum rlimit_action { NO_CHANGE, SET_TO_MAX, INCREASED_MAX };
 bool evsel__increase_rlimit(enum rlimit_action *set_rlimit);
 
-bool evsel__ignore_missing_thread(struct evsel *evsel,
-				  int nr_cpus, int cpu,
-				  struct perf_thread_map *threads,
-				  int thread, int err);
 bool evsel__precise_ip_fallback(struct evsel *evsel);
 
 struct perf_sample;
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:42 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:42 -0800
Subject: [PATCH v4 39/48] perf evsel: Rename variable cpu to index
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-40-irogers@google.com>

Make naming less error prone.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/evsel.c | 83 +++++++++++++++++++++--------------------
 tools/perf/util/evsel.h |  6 +--
 tools/perf/util/stat.c  |  4 +-
 tools/perf/util/stat.h  |  2 +-
 4 files changed, 48 insertions(+), 47 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 8911ebde54d6..2b18b29a534f 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1372,9 +1372,9 @@ int evsel__append_addr_filter(struct evsel *evsel, const char *filter)
 }
 
 /* Caller has to clear disabled after going through all CPUs. */
-int evsel__enable_cpu(struct evsel *evsel, int cpu)
+int evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx)
 {
-	return perf_evsel__enable_cpu(&evsel->core, cpu);
+	return perf_evsel__enable_cpu(&evsel->core, cpu_map_idx);
 }
 
 int evsel__enable(struct evsel *evsel)
@@ -1387,9 +1387,9 @@ int evsel__enable(struct evsel *evsel)
 }
 
 /* Caller has to set disabled after going through all CPUs. */
-int evsel__disable_cpu(struct evsel *evsel, int cpu)
+int evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx)
 {
-	return perf_evsel__disable_cpu(&evsel->core, cpu);
+	return perf_evsel__disable_cpu(&evsel->core, cpu_map_idx);
 }
 
 int evsel__disable(struct evsel *evsel)
@@ -1455,7 +1455,7 @@ void evsel__delete(struct evsel *evsel)
 	free(evsel);
 }
 
-void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
+void evsel__compute_deltas(struct evsel *evsel, int cpu_map_idx, int thread,
 			   struct perf_counts_values *count)
 {
 	struct perf_counts_values tmp;
@@ -1463,12 +1463,12 @@ void evsel__compute_deltas(struct evsel *evsel, int cpu, int thread,
 	if (!evsel->prev_raw_counts)
 		return;
 
-	if (cpu == -1) {
+	if (cpu_map_idx == -1) {
 		tmp = evsel->prev_raw_counts->aggr;
 		evsel->prev_raw_counts->aggr = *count;
 	} else {
-		tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread);
-		*perf_counts(evsel->prev_raw_counts, cpu, thread) = *count;
+		tmp = *perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread);
+		*perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread) = *count;
 	}
 
 	count->val = count->val - tmp.val;
@@ -1483,20 +1483,21 @@ static int evsel__read_one(struct evsel *evsel, int cpu_map_idx, int thread)
 	return perf_evsel__read(&evsel->core, cpu_map_idx, thread, count);
 }
 
-static void evsel__set_count(struct evsel *counter, int cpu, int thread, u64 val, u64 ena, u64 run)
+static void evsel__set_count(struct evsel *counter, int cpu_map_idx, int thread,
+			     u64 val, u64 ena, u64 run)
 {
 	struct perf_counts_values *count;
 
-	count = perf_counts(counter->counts, cpu, thread);
+	count = perf_counts(counter->counts, cpu_map_idx, thread);
 
 	count->val    = val;
 	count->ena    = ena;
 	count->run    = run;
 
-	perf_counts__set_loaded(counter->counts, cpu, thread, true);
+	perf_counts__set_loaded(counter->counts, cpu_map_idx, thread, true);
 }
 
-static int evsel__process_group_data(struct evsel *leader, int cpu, int thread, u64 *data)
+static int evsel__process_group_data(struct evsel *leader, int cpu_map_idx, int thread, u64 *data)
 {
 	u64 read_format = leader->core.attr.read_format;
 	struct sample_read_value *v;
@@ -1515,7 +1516,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu, int thread,
 
 	v = (struct sample_read_value *) data;
 
-	evsel__set_count(leader, cpu, thread, v[0].value, ena, run);
+	evsel__set_count(leader, cpu_map_idx, thread, v[0].value, ena, run);
 
 	for (i = 1; i < nr; i++) {
 		struct evsel *counter;
@@ -1524,7 +1525,7 @@ static int evsel__process_group_data(struct evsel *leader, int cpu, int thread,
 		if (!counter)
 			return -EINVAL;
 
-		evsel__set_count(counter, cpu, thread, v[i].value, ena, run);
+		evsel__set_count(counter, cpu_map_idx, thread, v[i].value, ena, run);
 	}
 
 	return 0;
@@ -1643,16 +1644,16 @@ static void evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int
 }
 
 static int update_fds(struct evsel *evsel,
-		      int nr_cpus, int cpu_idx,
+		      int nr_cpus, int cpu_map_idx,
 		      int nr_threads, int thread_idx)
 {
 	struct evsel *pos;
 
-	if (cpu_idx >= nr_cpus || thread_idx >= nr_threads)
+	if (cpu_map_idx >= nr_cpus || thread_idx >= nr_threads)
 		return -EINVAL;
 
 	evlist__for_each_entry(evsel->evlist, pos) {
-		nr_cpus = pos != evsel ? nr_cpus : cpu_idx;
+		nr_cpus = pos != evsel ? nr_cpus : cpu_map_idx;
 
 		evsel__remove_fd(pos, nr_cpus, nr_threads, thread_idx);
 
@@ -1667,7 +1668,7 @@ static int update_fds(struct evsel *evsel,
 }
 
 static bool evsel__ignore_missing_thread(struct evsel *evsel,
-					 int nr_cpus, int cpu,
+					 int nr_cpus, int cpu_map_idx,
 					 struct perf_thread_map *threads,
 					 int thread, int err)
 {
@@ -1692,7 +1693,7 @@ static bool evsel__ignore_missing_thread(struct evsel *evsel,
 	 * We should remove fd for missing_thread first
 	 * because thread_map__remove() will decrease threads->nr.
 	 */
-	if (update_fds(evsel, nr_cpus, cpu, threads->nr, thread))
+	if (update_fds(evsel, nr_cpus, cpu_map_idx, threads->nr, thread))
 		return false;
 
 	if (thread_map__remove(threads, thread))
@@ -1974,9 +1975,9 @@ bool evsel__increase_rlimit(enum rlimit_action *set_rlimit)
 
 static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 		struct perf_thread_map *threads,
-		int start_cpu, int end_cpu)
+		int start_cpu_map_idx, int end_cpu_map_idx)
 {
-	int cpu, thread, nthreads;
+	int idx, thread, nthreads;
 	int pid = -1, err, old_errno;
 	enum rlimit_action set_rlimit = NO_CHANGE;
 
@@ -2003,7 +2004,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 
 	display_attr(&evsel->core.attr);
 
-	for (cpu = start_cpu; cpu < end_cpu; cpu++) {
+	for (idx = start_cpu_map_idx; idx < end_cpu_map_idx; idx++) {
 
 		for (thread = 0; thread < nthreads; thread++) {
 			int fd, group_fd;
@@ -2014,17 +2015,17 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 			if (!evsel->cgrp && !evsel->core.system_wide)
 				pid = perf_thread_map__pid(threads, thread);
 
-			group_fd = get_group_fd(evsel, cpu, thread);
+			group_fd = get_group_fd(evsel, idx, thread);
 
 			test_attr__ready();
 
 			pr_debug2_peo("sys_perf_event_open: pid %d  cpu %d  group_fd %d  flags %#lx",
-				pid, cpus->map[cpu], group_fd, evsel->open_flags);
+				pid, cpus->map[idx], group_fd, evsel->open_flags);
 
-			fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[cpu],
+			fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx],
 						group_fd, evsel->open_flags);
 
-			FD(evsel, cpu, thread) = fd;
+			FD(evsel, idx, thread) = fd;
 
 			if (fd < 0) {
 				err = -errno;
@@ -2034,10 +2035,10 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 				goto try_fallback;
 			}
 
-			bpf_counter__install_pe(evsel, cpu, fd);
+			bpf_counter__install_pe(evsel, idx, fd);
 
 			if (unlikely(test_attr__enabled)) {
-				test_attr__open(&evsel->core.attr, pid, cpus->map[cpu],
+				test_attr__open(&evsel->core.attr, pid, cpus->map[idx],
 						fd, group_fd, evsel->open_flags);
 			}
 
@@ -2078,7 +2079,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 	if (evsel__precise_ip_fallback(evsel))
 		goto retry_open;
 
-	if (evsel__ignore_missing_thread(evsel, cpus->nr, cpu, threads, thread, err)) {
+	if (evsel__ignore_missing_thread(evsel, cpus->nr, idx, threads, thread, err)) {
 		/* We just removed 1 thread, so lower the upper nthreads limit. */
 		nthreads--;
 
@@ -2093,7 +2094,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 	if (err == -EMFILE && evsel__increase_rlimit(&set_rlimit))
 		goto retry_open;
 
-	if (err != -EINVAL || cpu > 0 || thread > 0)
+	if (err != -EINVAL || idx > 0 || thread > 0)
 		goto out_close;
 
 	if (evsel__detect_missing_features(evsel))
@@ -2105,12 +2106,12 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 	old_errno = errno;
 	do {
 		while (--thread >= 0) {
-			if (FD(evsel, cpu, thread) >= 0)
-				close(FD(evsel, cpu, thread));
-			FD(evsel, cpu, thread) = -1;
+			if (FD(evsel, idx, thread) >= 0)
+				close(FD(evsel, idx, thread));
+			FD(evsel, idx, thread) = -1;
 		}
 		thread = nthreads;
-	} while (--cpu >= 0);
+	} while (--idx >= 0);
 	errno = old_errno;
 	return err;
 }
@@ -2127,13 +2128,13 @@ void evsel__close(struct evsel *evsel)
 	perf_evsel__free_id(&evsel->core);
 }
 
-int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu)
+int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx)
 {
-	if (cpu == -1)
+	if (cpu_map_idx == -1)
 		return evsel__open_cpu(evsel, cpus, NULL, 0,
 					cpus ? cpus->nr : 1);
 
-	return evsel__open_cpu(evsel, cpus, NULL, cpu, cpu + 1);
+	return evsel__open_cpu(evsel, cpus, NULL, cpu_map_idx, cpu_map_idx + 1);
 }
 
 int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads)
@@ -2954,15 +2955,15 @@ struct perf_env *evsel__env(struct evsel *evsel)
 
 static int store_evsel_ids(struct evsel *evsel, struct evlist *evlist)
 {
-	int cpu, thread;
+	int cpu_map_idx, thread;
 
-	for (cpu = 0; cpu < xyarray__max_x(evsel->core.fd); cpu++) {
+	for (cpu_map_idx = 0; cpu_map_idx < xyarray__max_x(evsel->core.fd); cpu_map_idx++) {
 		for (thread = 0; thread < xyarray__max_y(evsel->core.fd);
 		     thread++) {
-			int fd = FD(evsel, cpu, thread);
+			int fd = FD(evsel, cpu_map_idx, thread);
 
 			if (perf_evlist__id_add_fd(&evlist->core, &evsel->core,
-						   cpu, thread, fd) < 0)
+						   cpu_map_idx, thread, fd) < 0)
 				return -1;
 		}
 	}
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 84e597f6c395..5720ceebffac 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -284,12 +284,12 @@ void arch_evsel__fixup_new_cycles(struct perf_event_attr *attr);
 int evsel__set_filter(struct evsel *evsel, const char *filter);
 int evsel__append_tp_filter(struct evsel *evsel, const char *filter);
 int evsel__append_addr_filter(struct evsel *evsel, const char *filter);
-int evsel__enable_cpu(struct evsel *evsel, int cpu);
+int evsel__enable_cpu(struct evsel *evsel, int cpu_map_idx);
 int evsel__enable(struct evsel *evsel);
 int evsel__disable(struct evsel *evsel);
-int evsel__disable_cpu(struct evsel *evsel, int cpu);
+int evsel__disable_cpu(struct evsel *evsel, int cpu_map_idx);
 
-int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu);
+int evsel__open_per_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, int cpu_map_idx);
 int evsel__open_per_thread(struct evsel *evsel, struct perf_thread_map *threads);
 int evsel__open(struct evsel *evsel, struct perf_cpu_map *cpus,
 		struct perf_thread_map *threads);
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 995cb5003133..f7f9757eba23 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -531,7 +531,7 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp)
 int create_perf_stat_counter(struct evsel *evsel,
 			     struct perf_stat_config *config,
 			     struct target *target,
-			     int cpu)
+			     int cpu_map_idx)
 {
 	struct perf_event_attr *attr = &evsel->core.attr;
 	struct evsel *leader = evsel__leader(evsel);
@@ -585,7 +585,7 @@ int create_perf_stat_counter(struct evsel *evsel,
 	}
 
 	if (target__has_cpu(target) && !target__has_per_thread(target))
-		return evsel__open_per_cpu(evsel, evsel__cpus(evsel), cpu);
+		return evsel__open_per_cpu(evsel, evsel__cpus(evsel), cpu_map_idx);
 
 	return evsel__open_per_thread(evsel, evsel->core.threads);
 }
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 32cf24186229..5e25d53e891b 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -248,7 +248,7 @@ size_t perf_event__fprintf_stat_config(union perf_event *event, FILE *fp);
 int create_perf_stat_counter(struct evsel *evsel,
 			     struct perf_stat_config *config,
 			     struct target *target,
-			     int cpu);
+			     int cpu_map_idx);
 void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config,
 			    struct target *_target, struct timespec *ts, int argc, const char **argv);
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:43 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:43 -0800
Subject: [PATCH v4 40/48] perf test: Use perf_cpu_map__for_each_cpu
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-41-irogers@google.com>

Clean up variable naming to make cpu and index clearer.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/tests/openat-syscall-all-cpus.c | 28 +++++++++++-----------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 544db0839b3b..ca0a50e92839 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -22,7 +22,7 @@
 static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __maybe_unused,
 						  int subtest __maybe_unused)
 {
-	int err = -1, fd, cpu;
+	int err = -1, fd, idx, cpu;
 	struct perf_cpu_map *cpus;
 	struct evsel *evsel;
 	unsigned int nr_openat_calls = 111, i;
@@ -58,23 +58,23 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 		goto out_evsel_delete;
 	}
 
-	for (cpu = 0; cpu < cpus->nr; ++cpu) {
-		unsigned int ncalls = nr_openat_calls + cpu;
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
+		unsigned int ncalls = nr_openat_calls + idx;
 		/*
 		 * XXX eventually lift this restriction in a way that
 		 * keeps perf building on older glibc installations
 		 * without CPU_ALLOC. 1024 cpus in 2010 still seems
 		 * a reasonable upper limit tho :-)
 		 */
-		if (cpus->map[cpu] >= CPU_SETSIZE) {
-			pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
+		if (cpu >= CPU_SETSIZE) {
+			pr_debug("Ignoring CPU %d\n", cpu);
 			continue;
 		}
 
-		CPU_SET(cpus->map[cpu], &cpu_set);
+		CPU_SET(cpu, &cpu_set);
 		if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
 			pr_debug("sched_setaffinity() failed on CPU %d: %s ",
-				 cpus->map[cpu],
+				 cpu,
 				 str_error_r(errno, sbuf, sizeof(sbuf)));
 			goto out_close_fd;
 		}
@@ -82,29 +82,29 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 			fd = openat(0, "/etc/passwd", O_RDONLY);
 			close(fd);
 		}
-		CPU_CLR(cpus->map[cpu], &cpu_set);
+		CPU_CLR(cpu, &cpu_set);
 	}
 
 	evsel->core.cpus = perf_cpu_map__get(cpus);
 
 	err = 0;
 
-	for (cpu = 0; cpu < cpus->nr; ++cpu) {
+	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		unsigned int expected;
 
-		if (cpus->map[cpu] >= CPU_SETSIZE)
+		if (cpu >= CPU_SETSIZE)
 			continue;
 
-		if (evsel__read_on_cpu(evsel, cpu, 0) < 0) {
+		if (evsel__read_on_cpu(evsel, idx, 0) < 0) {
 			pr_debug("evsel__read_on_cpu\n");
 			err = -1;
 			break;
 		}
 
-		expected = nr_openat_calls + cpu;
-		if (perf_counts(evsel->counts, cpu, 0)->val != expected) {
+		expected = nr_openat_calls + idx;
+		if (perf_counts(evsel->counts, idx, 0)->val != expected) {
 			pr_debug("evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu, 0)->val);
+				 expected, cpu, perf_counts(evsel->counts, idx, 0)->val);
 			err = -1;
 		}
 	}
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:44 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:44 -0800
Subject: [PATCH v4 41/48] perf stat: Correct check_per_pkg cpu
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-42-irogers@google.com>

Code was incorrectly using the cpu map index as the CPU.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index f7f9757eba23..86ab427e87fc 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -292,11 +292,12 @@ static bool pkg_id_equal(const void *__key1, const void *__key2,
 	return *key1 == *key2;
 }
 
-static int check_per_pkg(struct evsel *counter,
-			 struct perf_counts_values *vals, int cpu, bool *skip)
+static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals,
+			 int cpu_map_idx, bool *skip)
 {
 	struct hashmap *mask = counter->per_pkg_mask;
 	struct perf_cpu_map *cpus = evsel__cpus(counter);
+	int cpu = perf_cpu_map__cpu(cpus, cpu_map_idx);
 	int s, d, ret = 0;
 	uint64_t *key;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:46 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:46 -0800
Subject: [PATCH v4 43/48] libperf: Sync evsel documentation
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-44-irogers@google.com>

cpu was renamed cpu_map_idx, for clarity.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/Documentation/libperf.txt | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt
index faef9ba3a540..32c5051c24eb 100644
--- a/tools/lib/perf/Documentation/libperf.txt
+++ b/tools/lib/perf/Documentation/libperf.txt
@@ -136,16 +136,16 @@ SYNOPSIS
   int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
                        struct perf_thread_map *threads);
   void perf_evsel__close(struct perf_evsel *evsel);
-  void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu);
+  void perf_evsel__close_cpu(struct perf_evsel *evsel, int cpu_map_idx);
   int perf_evsel__mmap(struct perf_evsel *evsel, int pages);
   void perf_evsel__munmap(struct perf_evsel *evsel);
-  void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu, int thread);
-  int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+  void *perf_evsel__mmap_base(struct perf_evsel *evsel, int cpu_map_idx, int thread);
+  int perf_evsel__read(struct perf_evsel *evsel, int cpu_map_idx, int thread,
                        struct perf_counts_values *count);
   int perf_evsel__enable(struct perf_evsel *evsel);
-  int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu);
+  int perf_evsel__enable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
   int perf_evsel__disable(struct perf_evsel *evsel);
-  int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu);
+  int perf_evsel__disable_cpu(struct perf_evsel *evsel, int cpu_map_idx);
   struct perf_cpu_map *perf_evsel__cpus(struct perf_evsel *evsel);
   struct perf_thread_map *perf_evsel__threads(struct perf_evsel *evsel);
   struct perf_event_attr *perf_evsel__attr(struct perf_evsel *evsel);
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:45 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:45 -0800
Subject: [PATCH v4 42/48] perf stat: Swap variable name cpu to index
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-43-irogers@google.com>

The use of CPU is error prone, switch to cpu_map_idx.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-shadow.c | 308 +++++++++++++++++-----------------
 tools/perf/util/stat.c        |  16 +-
 tools/perf/util/stat.h        |   4 +-
 3 files changed, 164 insertions(+), 164 deletions(-)

diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
index 5c7308efa768..10af7804e482 100644
--- a/tools/perf/util/stat-shadow.c
+++ b/tools/perf/util/stat-shadow.c
@@ -32,7 +32,7 @@ struct saved_value {
 	struct evsel *evsel;
 	enum stat_type type;
 	int ctx;
-	int cpu;
+	int cpu_map_idx;
 	struct cgroup *cgrp;
 	struct runtime_stat *stat;
 	struct stats stats;
@@ -47,8 +47,8 @@ static int saved_value_cmp(struct rb_node *rb_node, const void *entry)
 					     rb_node);
 	const struct saved_value *b = entry;
 
-	if (a->cpu != b->cpu)
-		return a->cpu - b->cpu;
+	if (a->cpu_map_idx != b->cpu_map_idx)
+		return a->cpu_map_idx - b->cpu_map_idx;
 
 	/*
 	 * Previously the rbtree was used to link generic metrics.
@@ -105,7 +105,7 @@ static void saved_value_delete(struct rblist *rblist __maybe_unused,
 }
 
 static struct saved_value *saved_value_lookup(struct evsel *evsel,
-					      int cpu,
+					      int cpu_map_idx,
 					      bool create,
 					      enum stat_type type,
 					      int ctx,
@@ -115,7 +115,7 @@ static struct saved_value *saved_value_lookup(struct evsel *evsel,
 	struct rblist *rblist;
 	struct rb_node *nd;
 	struct saved_value dm = {
-		.cpu = cpu,
+		.cpu_map_idx = cpu_map_idx,
 		.evsel = evsel,
 		.type = type,
 		.ctx = ctx,
@@ -213,10 +213,10 @@ struct runtime_stat_data {
 
 static void update_runtime_stat(struct runtime_stat *st,
 				enum stat_type type,
-				int cpu, u64 count,
+				int cpu_map_idx, u64 count,
 				struct runtime_stat_data *rsd)
 {
-	struct saved_value *v = saved_value_lookup(NULL, cpu, true, type,
+	struct saved_value *v = saved_value_lookup(NULL, cpu_map_idx, true, type,
 						   rsd->ctx, st, rsd->cgrp);
 
 	if (v)
@@ -229,7 +229,7 @@ static void update_runtime_stat(struct runtime_stat *st,
  * instruction rates, etc:
  */
 void perf_stat__update_shadow_stats(struct evsel *counter, u64 count,
-				    int cpu, struct runtime_stat *st)
+				    int cpu_map_idx, struct runtime_stat *st)
 {
 	u64 count_ns = count;
 	struct saved_value *v;
@@ -241,88 +241,88 @@ void perf_stat__update_shadow_stats(struct evsel *counter, u64 count,
 	count *= counter->scale;
 
 	if (evsel__is_clock(counter))
-		update_runtime_stat(st, STAT_NSECS, cpu, count_ns, &rsd);
+		update_runtime_stat(st, STAT_NSECS, cpu_map_idx, count_ns, &rsd);
 	else if (evsel__match(counter, HARDWARE, HW_CPU_CYCLES))
-		update_runtime_stat(st, STAT_CYCLES, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_CYCLES, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, CYCLES_IN_TX))
-		update_runtime_stat(st, STAT_CYCLES_IN_TX, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_CYCLES_IN_TX, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TRANSACTION_START))
-		update_runtime_stat(st, STAT_TRANSACTION, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_TRANSACTION, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, ELISION_START))
-		update_runtime_stat(st, STAT_ELISION, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_ELISION, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_TOTAL_SLOTS))
 		update_runtime_stat(st, STAT_TOPDOWN_TOTAL_SLOTS,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_ISSUED))
 		update_runtime_stat(st, STAT_TOPDOWN_SLOTS_ISSUED,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_SLOTS_RETIRED))
 		update_runtime_stat(st, STAT_TOPDOWN_SLOTS_RETIRED,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_BUBBLES))
 		update_runtime_stat(st, STAT_TOPDOWN_FETCH_BUBBLES,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_RECOVERY_BUBBLES))
 		update_runtime_stat(st, STAT_TOPDOWN_RECOVERY_BUBBLES,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_RETIRING))
 		update_runtime_stat(st, STAT_TOPDOWN_RETIRING,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_BAD_SPEC))
 		update_runtime_stat(st, STAT_TOPDOWN_BAD_SPEC,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_FE_BOUND))
 		update_runtime_stat(st, STAT_TOPDOWN_FE_BOUND,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_BE_BOUND))
 		update_runtime_stat(st, STAT_TOPDOWN_BE_BOUND,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_HEAVY_OPS))
 		update_runtime_stat(st, STAT_TOPDOWN_HEAVY_OPS,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_BR_MISPREDICT))
 		update_runtime_stat(st, STAT_TOPDOWN_BR_MISPREDICT,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_FETCH_LAT))
 		update_runtime_stat(st, STAT_TOPDOWN_FETCH_LAT,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, TOPDOWN_MEM_BOUND))
 		update_runtime_stat(st, STAT_TOPDOWN_MEM_BOUND,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_FRONTEND))
 		update_runtime_stat(st, STAT_STALLED_CYCLES_FRONT,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HARDWARE, HW_STALLED_CYCLES_BACKEND))
 		update_runtime_stat(st, STAT_STALLED_CYCLES_BACK,
-				    cpu, count, &rsd);
+				    cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HARDWARE, HW_BRANCH_INSTRUCTIONS))
-		update_runtime_stat(st, STAT_BRANCHES, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_BRANCHES, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HARDWARE, HW_CACHE_REFERENCES))
-		update_runtime_stat(st, STAT_CACHEREFS, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_CACHEREFS, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HW_CACHE, HW_CACHE_L1D))
-		update_runtime_stat(st, STAT_L1_DCACHE, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_L1_DCACHE, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HW_CACHE, HW_CACHE_L1I))
-		update_runtime_stat(st, STAT_L1_ICACHE, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_L1_ICACHE, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HW_CACHE, HW_CACHE_LL))
-		update_runtime_stat(st, STAT_LL_CACHE, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_LL_CACHE, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HW_CACHE, HW_CACHE_DTLB))
-		update_runtime_stat(st, STAT_DTLB_CACHE, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_DTLB_CACHE, cpu_map_idx, count, &rsd);
 	else if (evsel__match(counter, HW_CACHE, HW_CACHE_ITLB))
-		update_runtime_stat(st, STAT_ITLB_CACHE, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_ITLB_CACHE, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, SMI_NUM))
-		update_runtime_stat(st, STAT_SMI_NUM, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_SMI_NUM, cpu_map_idx, count, &rsd);
 	else if (perf_stat_evsel__is(counter, APERF))
-		update_runtime_stat(st, STAT_APERF, cpu, count, &rsd);
+		update_runtime_stat(st, STAT_APERF, cpu_map_idx, count, &rsd);
 
 	if (counter->collect_stat) {
-		v = saved_value_lookup(counter, cpu, true, STAT_NONE, 0, st,
+		v = saved_value_lookup(counter, cpu_map_idx, true, STAT_NONE, 0, st,
 				       rsd.cgrp);
 		update_stats(&v->stats, count);
 		if (counter->metric_leader)
 			v->metric_total += count;
 	} else if (counter->metric_leader) {
 		v = saved_value_lookup(counter->metric_leader,
-				       cpu, true, STAT_NONE, 0, st, rsd.cgrp);
+				       cpu_map_idx, true, STAT_NONE, 0, st, rsd.cgrp);
 		v->metric_total += count;
 		v->metric_other++;
 	}
@@ -464,12 +464,12 @@ void perf_stat__collect_metric_expr(struct evlist *evsel_list)
 }
 
 static double runtime_stat_avg(struct runtime_stat *st,
-			       enum stat_type type, int cpu,
+			       enum stat_type type, int cpu_map_idx,
 			       struct runtime_stat_data *rsd)
 {
 	struct saved_value *v;
 
-	v = saved_value_lookup(NULL, cpu, false, type, rsd->ctx, st, rsd->cgrp);
+	v = saved_value_lookup(NULL, cpu_map_idx, false, type, rsd->ctx, st, rsd->cgrp);
 	if (!v)
 		return 0.0;
 
@@ -477,12 +477,12 @@ static double runtime_stat_avg(struct runtime_stat *st,
 }
 
 static double runtime_stat_n(struct runtime_stat *st,
-			     enum stat_type type, int cpu,
+			     enum stat_type type, int cpu_map_idx,
 			     struct runtime_stat_data *rsd)
 {
 	struct saved_value *v;
 
-	v = saved_value_lookup(NULL, cpu, false, type, rsd->ctx, st, rsd->cgrp);
+	v = saved_value_lookup(NULL, cpu_map_idx, false, type, rsd->ctx, st, rsd->cgrp);
 	if (!v)
 		return 0.0;
 
@@ -490,7 +490,7 @@ static double runtime_stat_n(struct runtime_stat *st,
 }
 
 static void print_stalled_cycles_frontend(struct perf_stat_config *config,
-					  int cpu, double avg,
+					  int cpu_map_idx, double avg,
 					  struct perf_stat_output_ctx *out,
 					  struct runtime_stat *st,
 					  struct runtime_stat_data *rsd)
@@ -498,7 +498,7 @@ static void print_stalled_cycles_frontend(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -513,7 +513,7 @@ static void print_stalled_cycles_frontend(struct perf_stat_config *config,
 }
 
 static void print_stalled_cycles_backend(struct perf_stat_config *config,
-					 int cpu, double avg,
+					 int cpu_map_idx, double avg,
 					 struct perf_stat_output_ctx *out,
 					 struct runtime_stat *st,
 					 struct runtime_stat_data *rsd)
@@ -521,7 +521,7 @@ static void print_stalled_cycles_backend(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -532,7 +532,7 @@ static void print_stalled_cycles_backend(struct perf_stat_config *config,
 }
 
 static void print_branch_misses(struct perf_stat_config *config,
-				int cpu, double avg,
+				int cpu_map_idx, double avg,
 				struct perf_stat_output_ctx *out,
 				struct runtime_stat *st,
 				struct runtime_stat_data *rsd)
@@ -540,7 +540,7 @@ static void print_branch_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_BRANCHES, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_BRANCHES, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -551,7 +551,7 @@ static void print_branch_misses(struct perf_stat_config *config,
 }
 
 static void print_l1_dcache_misses(struct perf_stat_config *config,
-				   int cpu, double avg,
+				   int cpu_map_idx, double avg,
 				   struct perf_stat_output_ctx *out,
 				   struct runtime_stat *st,
 				   struct runtime_stat_data *rsd)
@@ -559,7 +559,7 @@ static void print_l1_dcache_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_L1_DCACHE, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_L1_DCACHE, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -570,7 +570,7 @@ static void print_l1_dcache_misses(struct perf_stat_config *config,
 }
 
 static void print_l1_icache_misses(struct perf_stat_config *config,
-				   int cpu, double avg,
+				   int cpu_map_idx, double avg,
 				   struct perf_stat_output_ctx *out,
 				   struct runtime_stat *st,
 				   struct runtime_stat_data *rsd)
@@ -578,7 +578,7 @@ static void print_l1_icache_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_L1_ICACHE, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_L1_ICACHE, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -588,7 +588,7 @@ static void print_l1_icache_misses(struct perf_stat_config *config,
 }
 
 static void print_dtlb_cache_misses(struct perf_stat_config *config,
-				    int cpu, double avg,
+				    int cpu_map_idx, double avg,
 				    struct perf_stat_output_ctx *out,
 				    struct runtime_stat *st,
 				    struct runtime_stat_data *rsd)
@@ -596,7 +596,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_DTLB_CACHE, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_DTLB_CACHE, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -606,7 +606,7 @@ static void print_dtlb_cache_misses(struct perf_stat_config *config,
 }
 
 static void print_itlb_cache_misses(struct perf_stat_config *config,
-				    int cpu, double avg,
+				    int cpu_map_idx, double avg,
 				    struct perf_stat_output_ctx *out,
 				    struct runtime_stat *st,
 				    struct runtime_stat_data *rsd)
@@ -614,7 +614,7 @@ static void print_itlb_cache_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_ITLB_CACHE, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_ITLB_CACHE, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -624,7 +624,7 @@ static void print_itlb_cache_misses(struct perf_stat_config *config,
 }
 
 static void print_ll_cache_misses(struct perf_stat_config *config,
-				  int cpu, double avg,
+				  int cpu_map_idx, double avg,
 				  struct perf_stat_output_ctx *out,
 				  struct runtime_stat *st,
 				  struct runtime_stat_data *rsd)
@@ -632,7 +632,7 @@ static void print_ll_cache_misses(struct perf_stat_config *config,
 	double total, ratio = 0.0;
 	const char *color;
 
-	total = runtime_stat_avg(st, STAT_LL_CACHE, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_LL_CACHE, cpu_map_idx, rsd);
 
 	if (total)
 		ratio = avg / total * 100.0;
@@ -690,61 +690,61 @@ static double sanitize_val(double x)
 	return x;
 }
 
-static double td_total_slots(int cpu, struct runtime_stat *st,
+static double td_total_slots(int cpu_map_idx, struct runtime_stat *st,
 			     struct runtime_stat_data *rsd)
 {
-	return runtime_stat_avg(st, STAT_TOPDOWN_TOTAL_SLOTS, cpu, rsd);
+	return runtime_stat_avg(st, STAT_TOPDOWN_TOTAL_SLOTS, cpu_map_idx, rsd);
 }
 
-static double td_bad_spec(int cpu, struct runtime_stat *st,
+static double td_bad_spec(int cpu_map_idx, struct runtime_stat *st,
 			  struct runtime_stat_data *rsd)
 {
 	double bad_spec = 0;
 	double total_slots;
 	double total;
 
-	total = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_ISSUED, cpu, rsd) -
-		runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED, cpu, rsd) +
-		runtime_stat_avg(st, STAT_TOPDOWN_RECOVERY_BUBBLES, cpu, rsd);
+	total = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_ISSUED, cpu_map_idx, rsd) -
+		runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED, cpu_map_idx, rsd) +
+		runtime_stat_avg(st, STAT_TOPDOWN_RECOVERY_BUBBLES, cpu_map_idx, rsd);
 
-	total_slots = td_total_slots(cpu, st, rsd);
+	total_slots = td_total_slots(cpu_map_idx, st, rsd);
 	if (total_slots)
 		bad_spec = total / total_slots;
 	return sanitize_val(bad_spec);
 }
 
-static double td_retiring(int cpu, struct runtime_stat *st,
+static double td_retiring(int cpu_map_idx, struct runtime_stat *st,
 			  struct runtime_stat_data *rsd)
 {
 	double retiring = 0;
-	double total_slots = td_total_slots(cpu, st, rsd);
+	double total_slots = td_total_slots(cpu_map_idx, st, rsd);
 	double ret_slots = runtime_stat_avg(st, STAT_TOPDOWN_SLOTS_RETIRED,
-					    cpu, rsd);
+					    cpu_map_idx, rsd);
 
 	if (total_slots)
 		retiring = ret_slots / total_slots;
 	return retiring;
 }
 
-static double td_fe_bound(int cpu, struct runtime_stat *st,
+static double td_fe_bound(int cpu_map_idx, struct runtime_stat *st,
 			  struct runtime_stat_data *rsd)
 {
 	double fe_bound = 0;
-	double total_slots = td_total_slots(cpu, st, rsd);
+	double total_slots = td_total_slots(cpu_map_idx, st, rsd);
 	double fetch_bub = runtime_stat_avg(st, STAT_TOPDOWN_FETCH_BUBBLES,
-					    cpu, rsd);
+					    cpu_map_idx, rsd);
 
 	if (total_slots)
 		fe_bound = fetch_bub / total_slots;
 	return fe_bound;
 }
 
-static double td_be_bound(int cpu, struct runtime_stat *st,
+static double td_be_bound(int cpu_map_idx, struct runtime_stat *st,
 			  struct runtime_stat_data *rsd)
 {
-	double sum = (td_fe_bound(cpu, st, rsd) +
-		      td_bad_spec(cpu, st, rsd) +
-		      td_retiring(cpu, st, rsd));
+	double sum = (td_fe_bound(cpu_map_idx, st, rsd) +
+		      td_bad_spec(cpu_map_idx, st, rsd) +
+		      td_retiring(cpu_map_idx, st, rsd));
 	if (sum == 0)
 		return 0;
 	return sanitize_val(1.0 - sum);
@@ -755,15 +755,15 @@ static double td_be_bound(int cpu, struct runtime_stat *st,
  * the ratios we need to recreate the sum.
  */
 
-static double td_metric_ratio(int cpu, enum stat_type type,
+static double td_metric_ratio(int cpu_map_idx, enum stat_type type,
 			      struct runtime_stat *stat,
 			      struct runtime_stat_data *rsd)
 {
-	double sum = runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu, rsd) +
-		runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu, rsd) +
-		runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu, rsd) +
-		runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu, rsd);
-	double d = runtime_stat_avg(stat, type, cpu, rsd);
+	double sum = runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu_map_idx, rsd) +
+		runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu_map_idx, rsd) +
+		runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu_map_idx, rsd) +
+		runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu_map_idx, rsd);
+	double d = runtime_stat_avg(stat, type, cpu_map_idx, rsd);
 
 	if (sum)
 		return d / sum;
@@ -775,23 +775,23 @@ static double td_metric_ratio(int cpu, enum stat_type type,
  * We allow two missing.
  */
 
-static bool full_td(int cpu, struct runtime_stat *stat,
+static bool full_td(int cpu_map_idx, struct runtime_stat *stat,
 		    struct runtime_stat_data *rsd)
 {
 	int c = 0;
 
-	if (runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu, rsd) > 0)
+	if (runtime_stat_avg(stat, STAT_TOPDOWN_RETIRING, cpu_map_idx, rsd) > 0)
 		c++;
-	if (runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu, rsd) > 0)
+	if (runtime_stat_avg(stat, STAT_TOPDOWN_BE_BOUND, cpu_map_idx, rsd) > 0)
 		c++;
-	if (runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu, rsd) > 0)
+	if (runtime_stat_avg(stat, STAT_TOPDOWN_FE_BOUND, cpu_map_idx, rsd) > 0)
 		c++;
-	if (runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu, rsd) > 0)
+	if (runtime_stat_avg(stat, STAT_TOPDOWN_BAD_SPEC, cpu_map_idx, rsd) > 0)
 		c++;
 	return c >= 2;
 }
 
-static void print_smi_cost(struct perf_stat_config *config, int cpu,
+static void print_smi_cost(struct perf_stat_config *config, int cpu_map_idx,
 			   struct perf_stat_output_ctx *out,
 			   struct runtime_stat *st,
 			   struct runtime_stat_data *rsd)
@@ -799,9 +799,9 @@ static void print_smi_cost(struct perf_stat_config *config, int cpu,
 	double smi_num, aperf, cycles, cost = 0.0;
 	const char *color = NULL;
 
-	smi_num = runtime_stat_avg(st, STAT_SMI_NUM, cpu, rsd);
-	aperf = runtime_stat_avg(st, STAT_APERF, cpu, rsd);
-	cycles = runtime_stat_avg(st, STAT_CYCLES, cpu, rsd);
+	smi_num = runtime_stat_avg(st, STAT_SMI_NUM, cpu_map_idx, rsd);
+	aperf = runtime_stat_avg(st, STAT_APERF, cpu_map_idx, rsd);
+	cycles = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, rsd);
 
 	if ((cycles == 0) || (aperf == 0))
 		return;
@@ -818,7 +818,7 @@ static void print_smi_cost(struct perf_stat_config *config, int cpu,
 static int prepare_metric(struct evsel **metric_events,
 			  struct metric_ref *metric_refs,
 			  struct expr_parse_ctx *pctx,
-			  int cpu,
+			  int cpu_map_idx,
 			  struct runtime_stat *st)
 {
 	double scale;
@@ -836,7 +836,7 @@ static int prepare_metric(struct evsel **metric_events,
 			scale = 1e-9;
 			source_count = 1;
 		} else {
-			v = saved_value_lookup(metric_events[i], cpu, false,
+			v = saved_value_lookup(metric_events[i], cpu_map_idx, false,
 					       STAT_NONE, 0, st,
 					       metric_events[i]->cgrp);
 			if (!v)
@@ -874,7 +874,7 @@ static void generic_metric(struct perf_stat_config *config,
 			   const char *metric_name,
 			   const char *metric_unit,
 			   int runtime,
-			   int cpu,
+			   int cpu_map_idx,
 			   struct perf_stat_output_ctx *out,
 			   struct runtime_stat *st)
 {
@@ -889,7 +889,7 @@ static void generic_metric(struct perf_stat_config *config,
 		return;
 
 	pctx->runtime = runtime;
-	i = prepare_metric(metric_events, metric_refs, pctx, cpu, st);
+	i = prepare_metric(metric_events, metric_refs, pctx, cpu_map_idx, st);
 	if (i < 0) {
 		expr__ctx_free(pctx);
 		return;
@@ -934,7 +934,7 @@ static void generic_metric(struct perf_stat_config *config,
 	expr__ctx_free(pctx);
 }
 
-double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_stat *st)
+double test_generic_metric(struct metric_expr *mexp, int cpu_map_idx, struct runtime_stat *st)
 {
 	struct expr_parse_ctx *pctx;
 	double ratio = 0.0;
@@ -943,7 +943,7 @@ double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_sta
 	if (!pctx)
 		return NAN;
 
-	if (prepare_metric(mexp->metric_events, mexp->metric_refs, pctx, cpu, st) < 0)
+	if (prepare_metric(mexp->metric_events, mexp->metric_refs, pctx, cpu_map_idx, st) < 0)
 		goto out;
 
 	if (expr__parse(&ratio, pctx, mexp->metric_expr))
@@ -956,7 +956,7 @@ double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_sta
 
 void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 				   struct evsel *evsel,
-				   double avg, int cpu,
+				   double avg, int cpu_map_idx,
 				   struct perf_stat_output_ctx *out,
 				   struct rblist *metric_events,
 				   struct runtime_stat *st)
@@ -975,7 +975,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 	if (config->iostat_run) {
 		iostat_print_metric(config, evsel, out);
 	} else if (evsel__match(evsel, HARDWARE, HW_INSTRUCTIONS)) {
-		total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, &rsd);
 
 		if (total) {
 			ratio = avg / total;
@@ -985,11 +985,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 			print_metric(config, ctxp, NULL, NULL, "insn per cycle", 0);
 		}
 
-		total = runtime_stat_avg(st, STAT_STALLED_CYCLES_FRONT, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_STALLED_CYCLES_FRONT, cpu_map_idx, &rsd);
 
 		total = max(total, runtime_stat_avg(st,
 						    STAT_STALLED_CYCLES_BACK,
-						    cpu, &rsd));
+						    cpu_map_idx, &rsd));
 
 		if (total && avg) {
 			out->new_line(config, ctxp);
@@ -999,8 +999,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					ratio);
 		}
 	} else if (evsel__match(evsel, HARDWARE, HW_BRANCH_MISSES)) {
-		if (runtime_stat_n(st, STAT_BRANCHES, cpu, &rsd) != 0)
-			print_branch_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_BRANCHES, cpu_map_idx, &rsd) != 0)
+			print_branch_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all branches", 0);
 	} else if (
@@ -1009,8 +1009,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
 
-		if (runtime_stat_n(st, STAT_L1_DCACHE, cpu, &rsd) != 0)
-			print_l1_dcache_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_L1_DCACHE, cpu_map_idx, &rsd) != 0)
+			print_l1_dcache_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all L1-dcache accesses", 0);
 	} else if (
@@ -1019,8 +1019,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
 
-		if (runtime_stat_n(st, STAT_L1_ICACHE, cpu, &rsd) != 0)
-			print_l1_icache_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_L1_ICACHE, cpu_map_idx, &rsd) != 0)
+			print_l1_icache_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all L1-icache accesses", 0);
 	} else if (
@@ -1029,8 +1029,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
 
-		if (runtime_stat_n(st, STAT_DTLB_CACHE, cpu, &rsd) != 0)
-			print_dtlb_cache_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_DTLB_CACHE, cpu_map_idx, &rsd) != 0)
+			print_dtlb_cache_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all dTLB cache accesses", 0);
 	} else if (
@@ -1039,8 +1039,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
 
-		if (runtime_stat_n(st, STAT_ITLB_CACHE, cpu, &rsd) != 0)
-			print_itlb_cache_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_ITLB_CACHE, cpu_map_idx, &rsd) != 0)
+			print_itlb_cache_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all iTLB cache accesses", 0);
 	} else if (
@@ -1049,27 +1049,27 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 					((PERF_COUNT_HW_CACHE_OP_READ) << 8) |
 					 ((PERF_COUNT_HW_CACHE_RESULT_MISS) << 16))) {
 
-		if (runtime_stat_n(st, STAT_LL_CACHE, cpu, &rsd) != 0)
-			print_ll_cache_misses(config, cpu, avg, out, st, &rsd);
+		if (runtime_stat_n(st, STAT_LL_CACHE, cpu_map_idx, &rsd) != 0)
+			print_ll_cache_misses(config, cpu_map_idx, avg, out, st, &rsd);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all LL-cache accesses", 0);
 	} else if (evsel__match(evsel, HARDWARE, HW_CACHE_MISSES)) {
-		total = runtime_stat_avg(st, STAT_CACHEREFS, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CACHEREFS, cpu_map_idx, &rsd);
 
 		if (total)
 			ratio = avg * 100 / total;
 
-		if (runtime_stat_n(st, STAT_CACHEREFS, cpu, &rsd) != 0)
+		if (runtime_stat_n(st, STAT_CACHEREFS, cpu_map_idx, &rsd) != 0)
 			print_metric(config, ctxp, NULL, "%8.3f %%",
 				     "of all cache refs", ratio);
 		else
 			print_metric(config, ctxp, NULL, NULL, "of all cache refs", 0);
 	} else if (evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_FRONTEND)) {
-		print_stalled_cycles_frontend(config, cpu, avg, out, st, &rsd);
+		print_stalled_cycles_frontend(config, cpu_map_idx, avg, out, st, &rsd);
 	} else if (evsel__match(evsel, HARDWARE, HW_STALLED_CYCLES_BACKEND)) {
-		print_stalled_cycles_backend(config, cpu, avg, out, st, &rsd);
+		print_stalled_cycles_backend(config, cpu_map_idx, avg, out, st, &rsd);
 	} else if (evsel__match(evsel, HARDWARE, HW_CPU_CYCLES)) {
-		total = runtime_stat_avg(st, STAT_NSECS, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_NSECS, cpu_map_idx, &rsd);
 
 		if (total) {
 			ratio = avg / total;
@@ -1078,7 +1078,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 			print_metric(config, ctxp, NULL, NULL, "Ghz", 0);
 		}
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX)) {
-		total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, &rsd);
 
 		if (total)
 			print_metric(config, ctxp, NULL,
@@ -1088,8 +1088,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 			print_metric(config, ctxp, NULL, NULL, "transactional cycles",
 				     0);
 	} else if (perf_stat_evsel__is(evsel, CYCLES_IN_TX_CP)) {
-		total = runtime_stat_avg(st, STAT_CYCLES, cpu, &rsd);
-		total2 = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CYCLES, cpu_map_idx, &rsd);
+		total2 = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu_map_idx, &rsd);
 
 		if (total2 < avg)
 			total2 = avg;
@@ -1099,19 +1099,19 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		else
 			print_metric(config, ctxp, NULL, NULL, "aborted cycles", 0);
 	} else if (perf_stat_evsel__is(evsel, TRANSACTION_START)) {
-		total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu_map_idx, &rsd);
 
 		if (avg)
 			ratio = total / avg;
 
-		if (runtime_stat_n(st, STAT_CYCLES_IN_TX, cpu, &rsd) != 0)
+		if (runtime_stat_n(st, STAT_CYCLES_IN_TX, cpu_map_idx, &rsd) != 0)
 			print_metric(config, ctxp, NULL, "%8.0f",
 				     "cycles / transaction", ratio);
 		else
 			print_metric(config, ctxp, NULL, NULL, "cycles / transaction",
 				      0);
 	} else if (perf_stat_evsel__is(evsel, ELISION_START)) {
-		total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_CYCLES_IN_TX, cpu_map_idx, &rsd);
 
 		if (avg)
 			ratio = total / avg;
@@ -1124,28 +1124,28 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		else
 			print_metric(config, ctxp, NULL, NULL, "CPUs utilized", 0);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
-		double fe_bound = td_fe_bound(cpu, st, &rsd);
+		double fe_bound = td_fe_bound(cpu_map_idx, st, &rsd);
 
 		if (fe_bound > 0.2)
 			color = PERF_COLOR_RED;
 		print_metric(config, ctxp, color, "%8.1f%%", "frontend bound",
 				fe_bound * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) {
-		double retiring = td_retiring(cpu, st, &rsd);
+		double retiring = td_retiring(cpu_map_idx, st, &rsd);
 
 		if (retiring > 0.7)
 			color = PERF_COLOR_GREEN;
 		print_metric(config, ctxp, color, "%8.1f%%", "retiring",
 				retiring * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_RECOVERY_BUBBLES)) {
-		double bad_spec = td_bad_spec(cpu, st, &rsd);
+		double bad_spec = td_bad_spec(cpu_map_idx, st, &rsd);
 
 		if (bad_spec > 0.1)
 			color = PERF_COLOR_RED;
 		print_metric(config, ctxp, color, "%8.1f%%", "bad speculation",
 				bad_spec * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_ISSUED)) {
-		double be_bound = td_be_bound(cpu, st, &rsd);
+		double be_bound = td_be_bound(cpu_map_idx, st, &rsd);
 		const char *name = "backend bound";
 		static int have_recovery_bubbles = -1;
 
@@ -1158,14 +1158,14 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 
 		if (be_bound > 0.2)
 			color = PERF_COLOR_RED;
-		if (td_total_slots(cpu, st, &rsd) > 0)
+		if (td_total_slots(cpu_map_idx, st, &rsd) > 0)
 			print_metric(config, ctxp, color, "%8.1f%%", name,
 					be_bound * 100.);
 		else
 			print_metric(config, ctxp, NULL, NULL, name, 0);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_RETIRING) &&
-		   full_td(cpu, st, &rsd)) {
-		double retiring = td_metric_ratio(cpu,
+		   full_td(cpu_map_idx, st, &rsd)) {
+		double retiring = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_RETIRING, st,
 						  &rsd);
 		if (retiring > 0.7)
@@ -1173,8 +1173,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "retiring",
 				retiring * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_FE_BOUND) &&
-		   full_td(cpu, st, &rsd)) {
-		double fe_bound = td_metric_ratio(cpu,
+		   full_td(cpu_map_idx, st, &rsd)) {
+		double fe_bound = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_FE_BOUND, st,
 						  &rsd);
 		if (fe_bound > 0.2)
@@ -1182,8 +1182,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "frontend bound",
 				fe_bound * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_BE_BOUND) &&
-		   full_td(cpu, st, &rsd)) {
-		double be_bound = td_metric_ratio(cpu,
+		   full_td(cpu_map_idx, st, &rsd)) {
+		double be_bound = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_BE_BOUND, st,
 						  &rsd);
 		if (be_bound > 0.2)
@@ -1191,8 +1191,8 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "backend bound",
 				be_bound * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_BAD_SPEC) &&
-		   full_td(cpu, st, &rsd)) {
-		double bad_spec = td_metric_ratio(cpu,
+		   full_td(cpu_map_idx, st, &rsd)) {
+		double bad_spec = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_BAD_SPEC, st,
 						  &rsd);
 		if (bad_spec > 0.1)
@@ -1200,11 +1200,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "bad speculation",
 				bad_spec * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_HEAVY_OPS) &&
-			full_td(cpu, st, &rsd) && (config->topdown_level > 1)) {
-		double retiring = td_metric_ratio(cpu,
+			full_td(cpu_map_idx, st, &rsd) && (config->topdown_level > 1)) {
+		double retiring = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_RETIRING, st,
 						  &rsd);
-		double heavy_ops = td_metric_ratio(cpu,
+		double heavy_ops = td_metric_ratio(cpu_map_idx,
 						   STAT_TOPDOWN_HEAVY_OPS, st,
 						   &rsd);
 		double light_ops = retiring - heavy_ops;
@@ -1220,11 +1220,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "light operations",
 				light_ops * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_BR_MISPREDICT) &&
-			full_td(cpu, st, &rsd) && (config->topdown_level > 1)) {
-		double bad_spec = td_metric_ratio(cpu,
+			full_td(cpu_map_idx, st, &rsd) && (config->topdown_level > 1)) {
+		double bad_spec = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_BAD_SPEC, st,
 						  &rsd);
-		double br_mis = td_metric_ratio(cpu,
+		double br_mis = td_metric_ratio(cpu_map_idx,
 						STAT_TOPDOWN_BR_MISPREDICT, st,
 						&rsd);
 		double m_clears = bad_spec - br_mis;
@@ -1240,11 +1240,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "machine clears",
 				m_clears * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_LAT) &&
-			full_td(cpu, st, &rsd) && (config->topdown_level > 1)) {
-		double fe_bound = td_metric_ratio(cpu,
+			full_td(cpu_map_idx, st, &rsd) && (config->topdown_level > 1)) {
+		double fe_bound = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_FE_BOUND, st,
 						  &rsd);
-		double fetch_lat = td_metric_ratio(cpu,
+		double fetch_lat = td_metric_ratio(cpu_map_idx,
 						   STAT_TOPDOWN_FETCH_LAT, st,
 						   &rsd);
 		double fetch_bw = fe_bound - fetch_lat;
@@ -1260,11 +1260,11 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 		print_metric(config, ctxp, color, "%8.1f%%", "fetch bandwidth",
 				fetch_bw * 100.);
 	} else if (perf_stat_evsel__is(evsel, TOPDOWN_MEM_BOUND) &&
-			full_td(cpu, st, &rsd) && (config->topdown_level > 1)) {
-		double be_bound = td_metric_ratio(cpu,
+			full_td(cpu_map_idx, st, &rsd) && (config->topdown_level > 1)) {
+		double be_bound = td_metric_ratio(cpu_map_idx,
 						  STAT_TOPDOWN_BE_BOUND, st,
 						  &rsd);
-		double mem_bound = td_metric_ratio(cpu,
+		double mem_bound = td_metric_ratio(cpu_map_idx,
 						   STAT_TOPDOWN_MEM_BOUND, st,
 						   &rsd);
 		double core_bound = be_bound - mem_bound;
@@ -1281,12 +1281,12 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 				core_bound * 100.);
 	} else if (evsel->metric_expr) {
 		generic_metric(config, evsel->metric_expr, evsel->metric_events, NULL,
-				evsel->name, evsel->metric_name, NULL, 1, cpu, out, st);
-	} else if (runtime_stat_n(st, STAT_NSECS, cpu, &rsd) != 0) {
+				evsel->name, evsel->metric_name, NULL, 1, cpu_map_idx, out, st);
+	} else if (runtime_stat_n(st, STAT_NSECS, cpu_map_idx, &rsd) != 0) {
 		char unit = ' ';
 		char unit_buf[10] = "/sec";
 
-		total = runtime_stat_avg(st, STAT_NSECS, cpu, &rsd);
+		total = runtime_stat_avg(st, STAT_NSECS, cpu_map_idx, &rsd);
 		if (total)
 			ratio = convert_unit_double(1000000000.0 * avg / total, &unit);
 
@@ -1294,7 +1294,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 			snprintf(unit_buf, sizeof(unit_buf), "%c/sec", unit);
 		print_metric(config, ctxp, NULL, "%8.3f", unit_buf, ratio);
 	} else if (perf_stat_evsel__is(evsel, SMI_NUM)) {
-		print_smi_cost(config, cpu, out, st, &rsd);
+		print_smi_cost(config, cpu_map_idx, out, st, &rsd);
 	} else {
 		num = 0;
 	}
@@ -1307,7 +1307,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config,
 				out->new_line(config, ctxp);
 			generic_metric(config, mexp->metric_expr, mexp->metric_events,
 					mexp->metric_refs, evsel->name, mexp->metric_name,
-					mexp->metric_unit, mexp->runtime, cpu, out, st);
+					mexp->metric_unit, mexp->runtime, cpu_map_idx, out, st);
 		}
 	}
 	if (num == 0)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 86ab427e87fc..7dbd7c4f3c33 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -356,14 +356,14 @@ static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals,
 
 static int
 process_counter_values(struct perf_stat_config *config, struct evsel *evsel,
-		       int cpu, int thread,
+		       int cpu_map_idx, int thread,
 		       struct perf_counts_values *count)
 {
 	struct perf_counts_values *aggr = &evsel->counts->aggr;
 	static struct perf_counts_values zero;
 	bool skip = false;
 
-	if (check_per_pkg(evsel, count, cpu, &skip)) {
+	if (check_per_pkg(evsel, count, cpu_map_idx, &skip)) {
 		pr_err("failed to read per-pkg counter\n");
 		return -1;
 	}
@@ -379,11 +379,11 @@ process_counter_values(struct perf_stat_config *config, struct evsel *evsel,
 	case AGGR_NODE:
 	case AGGR_NONE:
 		if (!evsel->snapshot)
-			evsel__compute_deltas(evsel, cpu, thread, count);
+			evsel__compute_deltas(evsel, cpu_map_idx, thread, count);
 		perf_counts_values__scale(count, config->scale, NULL);
 		if ((config->aggr_mode == AGGR_NONE) && (!evsel->percore)) {
 			perf_stat__update_shadow_stats(evsel, count->val,
-						       cpu, &rt_stat);
+						       cpu_map_idx, &rt_stat);
 		}
 
 		if (config->aggr_mode == AGGR_THREAD) {
@@ -412,15 +412,15 @@ static int process_counter_maps(struct perf_stat_config *config,
 {
 	int nthreads = perf_thread_map__nr(counter->core.threads);
 	int ncpus = evsel__nr_cpus(counter);
-	int cpu, thread;
+	int idx, thread;
 
 	if (counter->core.system_wide)
 		nthreads = 1;
 
 	for (thread = 0; thread < nthreads; thread++) {
-		for (cpu = 0; cpu < ncpus; cpu++) {
-			if (process_counter_values(config, counter, cpu, thread,
-						   perf_counts(counter->counts, cpu, thread)))
+		for (idx = 0; idx < ncpus; idx++) {
+			if (process_counter_values(config, counter, idx, thread,
+						   perf_counts(counter->counts, idx, thread)))
 				return -1;
 		}
 	}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 5e25d53e891b..691c12fd8976 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -208,7 +208,7 @@ void perf_stat__init_shadow_stats(void);
 void perf_stat__reset_shadow_stats(void);
 void perf_stat__reset_shadow_per_stat(struct runtime_stat *st);
 void perf_stat__update_shadow_stats(struct evsel *counter, u64 count,
-				    int cpu, struct runtime_stat *st);
+				    int cpu_map_idx, struct runtime_stat *st);
 struct perf_stat_output_ctx {
 	void *ctx;
 	print_metric_t print_metric;
@@ -253,5 +253,5 @@ void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *conf
 			    struct target *_target, struct timespec *ts, int argc, const char **argv);
 
 struct metric_expr;
-double test_generic_metric(struct metric_expr *mexp, int cpu, struct runtime_stat *st);
+double test_generic_metric(struct metric_expr *mexp, int cpu_map_idx, struct runtime_stat *st);
 #endif
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:47 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:47 -0800
Subject: [PATCH v4 44/48] perf bpf: Rename cpu to cpu_map_idx
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-45-irogers@google.com>

Synchronize the caller in evsel with the called function.
Shorten 3 lines of code in bperf_read by using
perf_cpu_map__for_each_cpu.
This code is frequently using variables named cpu as cpu map indices,
which doesn't matter as all CPUs are in the CPU map. It is strange in
some cases the cpumap is used at all.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/bpf_counter.c | 16 +++++++---------
 tools/perf/util/bpf_counter.h |  4 ++--
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
index c17d4a43ce06..ae5bd87ff020 100644
--- a/tools/perf/util/bpf_counter.c
+++ b/tools/perf/util/bpf_counter.c
@@ -265,7 +265,7 @@ static int bpf_program_profiler__read(struct evsel *evsel)
 	return 0;
 }
 
-static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu,
+static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu_map_idx,
 					    int fd)
 {
 	struct bpf_prog_profiler_bpf *skel;
@@ -277,7 +277,7 @@ static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu,
 		assert(skel != NULL);
 
 		ret = bpf_map_update_elem(bpf_map__fd(skel->maps.events),
-					  &cpu, &fd, BPF_ANY);
+					  &cpu_map_idx, &fd, BPF_ANY);
 		if (ret)
 			return ret;
 	}
@@ -566,12 +566,12 @@ static int bperf__load(struct evsel *evsel, struct target *target)
 	return err;
 }
 
-static int bperf__install_pe(struct evsel *evsel, int cpu, int fd)
+static int bperf__install_pe(struct evsel *evsel, int cpu_map_idx, int fd)
 {
 	struct bperf_leader_bpf *skel = evsel->leader_skel;
 
 	return bpf_map_update_elem(bpf_map__fd(skel->maps.events),
-				   &cpu, &fd, BPF_ANY);
+				   &cpu_map_idx, &fd, BPF_ANY);
 }
 
 /*
@@ -623,9 +623,7 @@ static int bperf__read(struct evsel *evsel)
 		case BPERF_FILTER_GLOBAL:
 			assert(i == 0);
 
-			num_cpu = all_cpu_map->nr;
-			for (j = 0; j < num_cpu; j++) {
-				cpu = all_cpu_map->map[j];
+			perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
 				perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
 				perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
 				perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
@@ -757,11 +755,11 @@ static inline bool bpf_counter_skip(struct evsel *evsel)
 		evsel->follower_skel == NULL;
 }
 
-int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd)
+int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd)
 {
 	if (bpf_counter_skip(evsel))
 		return 0;
-	return evsel->bpf_counter_ops->install_pe(evsel, cpu, fd);
+	return evsel->bpf_counter_ops->install_pe(evsel, cpu_map_idx, fd);
 }
 
 int bpf_counter__load(struct evsel *evsel, struct target *target)
diff --git a/tools/perf/util/bpf_counter.h b/tools/perf/util/bpf_counter.h
index 65ebaa6694fb..4dbf26408b69 100644
--- a/tools/perf/util/bpf_counter.h
+++ b/tools/perf/util/bpf_counter.h
@@ -16,7 +16,7 @@ typedef int (*bpf_counter_evsel_op)(struct evsel *evsel);
 typedef int (*bpf_counter_evsel_target_op)(struct evsel *evsel,
 					   struct target *target);
 typedef int (*bpf_counter_evsel_install_pe_op)(struct evsel *evsel,
-					       int cpu,
+					       int cpu_map_idx,
 					       int fd);
 
 struct bpf_counter_ops {
@@ -40,7 +40,7 @@ int bpf_counter__enable(struct evsel *evsel);
 int bpf_counter__disable(struct evsel *evsel);
 int bpf_counter__read(struct evsel *evsel);
 void bpf_counter__destroy(struct evsel *evsel);
-int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd);
+int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd);
 
 #else /* HAVE_BPF_SKEL */
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:48 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:48 -0800
Subject: [PATCH v4 45/48] perf c2c: Use more intention revealing iterator
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-46-irogers@google.com>

Use perf_cpu_map__for_each_cpu in setup_nodes.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-c2c.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index b5c67ef73862..ad1fbeafc93d 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2015,7 +2015,7 @@ static int setup_nodes(struct perf_session *session)
 {
 	struct numa_node *n;
 	unsigned long **nodes;
-	int node, cpu;
+	int node, cpu, idx;
 	int *cpu2node;
 
 	if (c2c.node_info > 2)
@@ -2057,13 +2057,13 @@ static int setup_nodes(struct perf_session *session)
 		if (perf_cpu_map__empty(map))
 			continue;
 
-		for (cpu = 0; cpu < map->nr; cpu++) {
-			set_bit(map->map[cpu], set);
+		perf_cpu_map__for_each_cpu(cpu, idx, map) {
+			set_bit(cpu, set);
 
-			if (WARN_ONCE(cpu2node[map->map[cpu]] != -1, "node/cpu topology bug"))
+			if (WARN_ONCE(cpu2node[cpu] != -1, "node/cpu topology bug"))
 				return -EINVAL;
 
-			cpu2node[map->map[cpu]] = node;
+			cpu2node[cpu] = node;
 		}
 	}
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:49 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:49 -0800
Subject: [PATCH v4 46/48] perf script: Fix flipped index and cpu
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-47-irogers@google.com>

perf_counts are accessed by the densely packed index.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/builtin-script.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index f40319144856..bb43529618b3 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2131,7 +2131,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
 		perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
 			struct perf_counts_values *counts;
 
-			counts = perf_counts(counter->counts, cpu, thread);
+			counts = perf_counts(counter->counts, idx, thread);
 
 			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
 				cpu,
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:50 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:50 -0800
Subject: [PATCH v4 47/48] perf stat: Correct first_shadow_cpu to return index
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-48-irogers@google.com>

perf_stat__update_shadow_stats and perf_stat__print_shadow_stats use a
cpu map index rather than a CPU, but first_shadow_cpu is returning the
wrong value for this. Change first_shadow_cpu to
first_shadow_cpu_map_idx to make things agree.

Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/perf/util/stat-display.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index 0f192360b6c6..ba95379efcfb 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -327,24 +327,23 @@ static void print_metric_header(struct perf_stat_config *config,
 		fprintf(os->fh, "%*s ", config->metric_only_len, unit);
 }
 
-static int first_shadow_cpu(struct perf_stat_config *config,
-			    struct evsel *evsel, const struct aggr_cpu_id *id)
+static int first_shadow_cpu_map_idx(struct perf_stat_config *config,
+				struct evsel *evsel, const struct aggr_cpu_id *id)
 {
-	struct perf_cpu_map *cpus;
+	struct perf_cpu_map *cpus = evsel__cpus(evsel);
 	int cpu, idx;
 
 	if (config->aggr_mode == AGGR_NONE)
-		return id->cpu;
+		return perf_cpu_map__idx(cpus, id->cpu);
 
 	if (!config->aggr_get_id)
 		return 0;
 
-	cpus = evsel__cpus(evsel);
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		struct aggr_cpu_id cpu_id = config->aggr_get_id(config, cpu);
 
 		if (aggr_cpu_id__equal(&cpu_id, id))
-			return cpu;
+			return idx;
 	}
 	return 0;
 }
@@ -503,7 +502,7 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
 	}
 
 	perf_stat__print_shadow_stats(config, counter, uval,
-				first_shadow_cpu(config, counter, &id),
+				first_shadow_cpu_map_idx(config, counter, &id),
 				&out, &config->metric_events, st);
 	if (!config->csv_output && !config->metric_only) {
 		print_noise(config, counter, noise);
@@ -532,7 +531,7 @@ static void aggr_update_shadow(struct perf_stat_config *config,
 				val += perf_counts(counter->counts, idx, 0)->val;
 			}
 			perf_stat__update_shadow_stats(counter, val,
-					first_shadow_cpu(config, counter, &id),
+					first_shadow_cpu_map_idx(config, counter, &id),
 					&rt_stat);
 		}
 	}
-- 
2.34.1.448.ga2b2bfdf31-goog



From irogers at google.com  Tue Jan  4 22:13:51 2022
From: irogers at google.com (Ian Rogers)
Date: Tue,  4 Jan 2022 22:13:51 -0800
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <20220105061351.120843-49-irogers@google.com>

A common problem is confusing CPU map indices with the CPU, by wrapping
the CPU with a struct then this is avoided. This approach is similar to
atomic_t.

Suggested-by: John Garry <john.garry at huawei.com>
Signed-off-by: Ian Rogers <irogers at google.com>
---
 tools/lib/perf/cpumap.c                       | 121 ++++++++++--------
 tools/lib/perf/evlist.c                       |   4 +-
 tools/lib/perf/evsel.c                        |   9 +-
 tools/lib/perf/include/internal/cpumap.h      |   9 +-
 tools/lib/perf/include/internal/evlist.h      |   3 +-
 tools/lib/perf/include/internal/evsel.h       |   4 +-
 tools/lib/perf/include/internal/mmap.h        |   5 +-
 tools/lib/perf/include/perf/cpumap.h          |   9 +-
 tools/lib/perf/mmap.c                         |   2 +-
 tools/perf/bench/epoll-ctl.c                  |   2 +-
 tools/perf/bench/epoll-wait.c                 |   2 +-
 tools/perf/bench/futex-hash.c                 |   2 +-
 tools/perf/bench/futex-lock-pi.c              |   2 +-
 tools/perf/bench/futex-requeue.c              |   2 +-
 tools/perf/bench/futex-wake-parallel.c        |   2 +-
 tools/perf/bench/futex-wake.c                 |   2 +-
 tools/perf/builtin-c2c.c                      |  13 +-
 tools/perf/builtin-ftrace.c                   |   2 +-
 tools/perf/builtin-kmem.c                     |   2 +-
 tools/perf/builtin-record.c                   |   2 +-
 tools/perf/builtin-sched.c                    |  65 +++++-----
 tools/perf/builtin-script.c                   |   5 +-
 tools/perf/builtin-stat.c                     |  80 ++++++------
 tools/perf/tests/attr.c                       |   6 +-
 tools/perf/tests/bitmap.c                     |   2 +-
 tools/perf/tests/cpumap.c                     |   6 +-
 tools/perf/tests/event_update.c               |   6 +-
 tools/perf/tests/mem2node.c                   |   2 +-
 tools/perf/tests/mmap-basic.c                 |   4 +-
 tools/perf/tests/openat-syscall-all-cpus.c    |  17 +--
 tools/perf/tests/stat.c                       |   3 +-
 tools/perf/tests/topology.c                   |  30 +++--
 tools/perf/util/affinity.c                    |   2 +-
 tools/perf/util/auxtrace.c                    |  12 +-
 tools/perf/util/auxtrace.h                    |   5 +-
 tools/perf/util/cpumap.c                      |  91 ++++++-------
 tools/perf/util/cpumap.h                      |  26 ++--
 tools/perf/util/cputopo.c                     |   6 +-
 tools/perf/util/env.c                         |  29 +++--
 tools/perf/util/env.h                         |   3 +-
 tools/perf/util/evlist.c                      |   8 +-
 tools/perf/util/evlist.h                      |   2 +-
 tools/perf/util/evsel.c                       |   6 +-
 tools/perf/util/expr.c                        |   2 +-
 tools/perf/util/header.c                      |   6 +-
 tools/perf/util/mmap.c                        |  19 +--
 tools/perf/util/mmap.h                        |   3 +-
 tools/perf/util/perf_api_probe.c              |  15 ++-
 tools/perf/util/python.c                      |   4 +-
 tools/perf/util/record.c                      |  11 +-
 .../scripting-engines/trace-event-python.c    |   6 +-
 tools/perf/util/session.c                     |  10 +-
 tools/perf/util/stat-display.c                |  34 +++--
 tools/perf/util/stat.c                        |   2 +-
 tools/perf/util/stat.h                        |   2 +-
 tools/perf/util/svghelper.c                   |   6 +-
 tools/perf/util/synthetic-events.c            |  12 +-
 tools/perf/util/synthetic-events.h            |   3 +-
 tools/perf/util/util.h                        |   5 +-
 59 files changed, 408 insertions(+), 347 deletions(-)

diff --git a/tools/lib/perf/cpumap.c b/tools/lib/perf/cpumap.c
index eacea3ab965a..a3afe9ef74ef 100644
--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -10,16 +10,27 @@
 #include <ctype.h>
 #include <limits.h>
 
+static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
+{
+	struct perf_cpu_map *cpus;
+
+	cpus = malloc(sizeof(*cpus) + sizeof(struct perf_cpu) * nr_cpus);
+	if (!cpus)
+		return NULL;
+
+	cpus->nr = 1;
+	refcount_set(&cpus->refcnt, 1);
+	return cpus;
+}
+
 struct perf_cpu_map *perf_cpu_map__dummy_new(void)
 {
-	struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + sizeof(int));
+	struct perf_cpu_map *cpus = perf_cpu_map__alloc(1);
 
-	if (cpus != NULL) {
-		cpus->nr = 1;
-		cpus->map[0] = -1;
-		refcount_set(&cpus->refcnt, 1);
-	}
+	if (!cpus)
+		return NULL;
 
+	cpus->map[0].cpu = -1;
 	return cpus;
 }
 
@@ -54,16 +65,12 @@ static struct perf_cpu_map *cpu_map__default_new(void)
 	if (nr_cpus < 0)
 		return NULL;
 
-	cpus = malloc(sizeof(*cpus) + nr_cpus * sizeof(int));
-	if (cpus != NULL) {
-		int i;
-
-		for (i = 0; i < nr_cpus; ++i)
-			cpus->map[i] = i;
+	cpus = perf_cpu_map__alloc(nr_cpus);
+	if (!cpus)
+		return NULL;
 
-		cpus->nr = nr_cpus;
-		refcount_set(&cpus->refcnt, 1);
-	}
+	for (int i = 0; i < nr_cpus; ++i)
+		cpus->map[i].cpu = i;
 
 	return cpus;
 }
@@ -73,31 +80,32 @@ struct perf_cpu_map *perf_cpu_map__default_new(void)
 	return cpu_map__default_new();
 }
 
-static int cmp_int(const void *a, const void *b)
+
+static int cmp_cpu(const void *a, const void *b)
 {
-	return *(const int *)a - *(const int*)b;
+	const struct perf_cpu *cpu_a = a, *cpu_b = b;
+
+	return cpu_a->cpu - cpu_b->cpu;
 }
 
-static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
+static struct perf_cpu_map *cpu_map__trim_new(int nr_cpus, const struct perf_cpu *tmp_cpus)
 {
-	size_t payload_size = nr_cpus * sizeof(int);
-	struct perf_cpu_map *cpus = malloc(sizeof(*cpus) + payload_size);
+	size_t payload_size = nr_cpus * sizeof(struct perf_cpu);
+	struct perf_cpu_map *cpus = perf_cpu_map__alloc(nr_cpus);
 	int i, j;
 
 	if (cpus != NULL) {
 		memcpy(cpus->map, tmp_cpus, payload_size);
-		qsort(cpus->map, nr_cpus, sizeof(int), cmp_int);
+		qsort(cpus->map, nr_cpus, sizeof(struct perf_cpu), cmp_cpu);
 		/* Remove dups */
 		j = 0;
 		for (i = 0; i < nr_cpus; i++) {
-			if (i == 0 || cpus->map[i] != cpus->map[i - 1])
-				cpus->map[j++] = cpus->map[i];
+			if (i == 0 || cpus->map[i].cpu != cpus->map[i - 1].cpu)
+				cpus->map[j++].cpu = cpus->map[i].cpu;
 		}
 		cpus->nr = j;
 		assert(j <= nr_cpus);
-		refcount_set(&cpus->refcnt, 1);
 	}
-
 	return cpus;
 }
 
@@ -105,7 +113,7 @@ struct perf_cpu_map *perf_cpu_map__read(FILE *file)
 {
 	struct perf_cpu_map *cpus = NULL;
 	int nr_cpus = 0;
-	int *tmp_cpus = NULL, *tmp;
+	struct perf_cpu *tmp_cpus = NULL, *tmp;
 	int max_entries = 0;
 	int n, cpu, prev;
 	char sep;
@@ -124,24 +132,24 @@ struct perf_cpu_map *perf_cpu_map__read(FILE *file)
 
 			if (new_max >= max_entries) {
 				max_entries = new_max + MAX_NR_CPUS / 2;
-				tmp = realloc(tmp_cpus, max_entries * sizeof(int));
+				tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu));
 				if (tmp == NULL)
 					goto out_free_tmp;
 				tmp_cpus = tmp;
 			}
 
 			while (++prev < cpu)
-				tmp_cpus[nr_cpus++] = prev;
+				tmp_cpus[nr_cpus++].cpu = prev;
 		}
 		if (nr_cpus == max_entries) {
 			max_entries += MAX_NR_CPUS;
-			tmp = realloc(tmp_cpus, max_entries * sizeof(int));
+			tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu));
 			if (tmp == NULL)
 				goto out_free_tmp;
 			tmp_cpus = tmp;
 		}
 
-		tmp_cpus[nr_cpus++] = cpu;
+		tmp_cpus[nr_cpus++].cpu = cpu;
 		if (n == 2 && sep == '-')
 			prev = cpu;
 		else
@@ -179,7 +187,7 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
 	unsigned long start_cpu, end_cpu = 0;
 	char *p = NULL;
 	int i, nr_cpus = 0;
-	int *tmp_cpus = NULL, *tmp;
+	struct perf_cpu *tmp_cpus = NULL, *tmp;
 	int max_entries = 0;
 
 	if (!cpu_list)
@@ -220,17 +228,17 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
 		for (; start_cpu <= end_cpu; start_cpu++) {
 			/* check for duplicates */
 			for (i = 0; i < nr_cpus; i++)
-				if (tmp_cpus[i] == (int)start_cpu)
+				if (tmp_cpus[i].cpu == (int)start_cpu)
 					goto invalid;
 
 			if (nr_cpus == max_entries) {
 				max_entries += MAX_NR_CPUS;
-				tmp = realloc(tmp_cpus, max_entries * sizeof(int));
+				tmp = realloc(tmp_cpus, max_entries * sizeof(struct perf_cpu));
 				if (tmp == NULL)
 					goto invalid;
 				tmp_cpus = tmp;
 			}
-			tmp_cpus[nr_cpus++] = (int)start_cpu;
+			tmp_cpus[nr_cpus++].cpu = (int)start_cpu;
 		}
 		if (*p)
 			++p;
@@ -250,12 +258,16 @@ struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list)
 	return cpus;
 }
 
-int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
+struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx)
 {
+	struct perf_cpu result = {
+		.cpu = -1
+	};
+
 	if (cpus && idx < cpus->nr)
-		return cpus->map[idx];
+		result = cpus->map[idx];
 
-	return -1;
+	return result;
 }
 
 int perf_cpu_map__nr(const struct perf_cpu_map *cpus)
@@ -265,10 +277,10 @@ int perf_cpu_map__nr(const struct perf_cpu_map *cpus)
 
 bool perf_cpu_map__empty(const struct perf_cpu_map *map)
 {
-	return map ? map->map[0] == -1 : true;
+	return map ? map->map[0].cpu == -1 : true;
 }
 
-int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu)
+int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu)
 {
 	int low, high;
 
@@ -278,13 +290,13 @@ int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu)
 	low = 0;
 	high = cpus->nr;
 	while (low < high) {
-		int idx = (low + high) / 2,
-		    cpu_at_idx = cpus->map[idx];
+		int idx = (low + high) / 2;
+		struct perf_cpu cpu_at_idx = cpus->map[idx];
 
-		if (cpu_at_idx == cpu)
+		if (cpu_at_idx.cpu == cpu.cpu)
 			return idx;
 
-		if (cpu_at_idx > cpu)
+		if (cpu_at_idx.cpu > cpu.cpu)
 			high = idx;
 		else
 			low = idx + 1;
@@ -293,15 +305,22 @@ int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu)
 	return -1;
 }
 
-bool perf_cpu_map__has(const struct perf_cpu_map *cpus, int cpu)
+bool perf_cpu_map__has(const struct perf_cpu_map *cpus, struct perf_cpu cpu)
 {
 	return perf_cpu_map__idx(cpus, cpu) != -1;
 }
 
-int perf_cpu_map__max(struct perf_cpu_map *map)
+struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map)
 {
+	struct perf_cpu result = {
+		.cpu = -1
+	};
+
 	// cpu_map__trim_new() qsort()s it, cpu_map__default_new() sorts it as well.
-	return map->nr > 0 ? map->map[map->nr - 1] : -1;
+	if (map->nr > 0)
+		result = map->map[map->nr - 1];
+
+	return result;
 }
 
 /*
@@ -315,7 +334,7 @@ int perf_cpu_map__max(struct perf_cpu_map *map)
 struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig,
 					 struct perf_cpu_map *other)
 {
-	int *tmp_cpus;
+	struct perf_cpu *tmp_cpus;
 	int tmp_len;
 	int i, j, k;
 	struct perf_cpu_map *merged;
@@ -329,19 +348,19 @@ struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig,
 	if (!other)
 		return orig;
 	if (orig->nr == other->nr &&
-	    !memcmp(orig->map, other->map, orig->nr * sizeof(int)))
+	    !memcmp(orig->map, other->map, orig->nr * sizeof(struct perf_cpu)))
 		return orig;
 
 	tmp_len = orig->nr + other->nr;
-	tmp_cpus = malloc(tmp_len * sizeof(int));
+	tmp_cpus = malloc(tmp_len * sizeof(struct perf_cpu));
 	if (!tmp_cpus)
 		return NULL;
 
 	/* Standard merge algorithm from wikipedia */
 	i = j = k = 0;
 	while (i < orig->nr && j < other->nr) {
-		if (orig->map[i] <= other->map[j]) {
-			if (orig->map[i] == other->map[j])
+		if (orig->map[i].cpu <= other->map[j].cpu) {
+			if (orig->map[i].cpu == other->map[j].cpu)
 				j++;
 			tmp_cpus[k++] = orig->map[i++];
 		} else
diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c
index 245acbc53bd3..9a770bfdc804 100644
--- a/tools/lib/perf/evlist.c
+++ b/tools/lib/perf/evlist.c
@@ -407,7 +407,7 @@ perf_evlist__mmap_cb_get(struct perf_evlist *evlist, bool overwrite, int idx)
 
 static int
 perf_evlist__mmap_cb_mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
-			  int output, int cpu)
+			  int output, struct perf_cpu cpu)
 {
 	return perf_mmap__mmap(map, mp, output, cpu);
 }
@@ -426,7 +426,7 @@ mmap_per_evsel(struct perf_evlist *evlist, struct perf_evlist_mmap_ops *ops,
 	       int idx, struct perf_mmap_param *mp, int cpu_idx,
 	       int thread, int *_output, int *_output_overwrite)
 {
-	int evlist_cpu = perf_cpu_map__cpu(evlist->cpus, cpu_idx);
+	struct perf_cpu evlist_cpu = perf_cpu_map__cpu(evlist->cpus, cpu_idx);
 	struct perf_evsel *evsel;
 	int revent;
 
diff --git a/tools/lib/perf/evsel.c b/tools/lib/perf/evsel.c
index f1e1665ef4bd..7ea86a44eae5 100644
--- a/tools/lib/perf/evsel.c
+++ b/tools/lib/perf/evsel.c
@@ -78,10 +78,10 @@ static int perf_evsel__alloc_mmap(struct perf_evsel *evsel, int ncpus, int nthre
 
 static int
 sys_perf_event_open(struct perf_event_attr *attr,
-		    pid_t pid, int cpu, int group_fd,
+		    pid_t pid, struct perf_cpu cpu, int group_fd,
 		    unsigned long flags)
 {
-	return syscall(__NR_perf_event_open, attr, pid, cpu, group_fd, flags);
+	return syscall(__NR_perf_event_open, attr, pid, cpu.cpu, group_fd, flags);
 }
 
 static int get_group_fd(struct perf_evsel *evsel, int cpu_map_idx, int thread, int *group_fd)
@@ -113,7 +113,8 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu_map_idx, int thread, i
 int perf_evsel__open(struct perf_evsel *evsel, struct perf_cpu_map *cpus,
 		     struct perf_thread_map *threads)
 {
-	int cpu, idx, thread, err = 0;
+	struct perf_cpu cpu;
+	int idx, thread, err = 0;
 
 	if (cpus == NULL) {
 		static struct perf_cpu_map *empty_cpu_map;
@@ -252,7 +253,7 @@ int perf_evsel__mmap(struct perf_evsel *evsel, int pages)
 		for (thread = 0; thread < xyarray__max_y(evsel->fd); thread++) {
 			int *fd = FD(evsel, idx, thread);
 			struct perf_mmap *map;
-			int cpu = perf_cpu_map__cpu(evsel->cpus, idx);
+			struct perf_cpu cpu = perf_cpu_map__cpu(evsel->cpus, idx);
 
 			if (fd == NULL || *fd < 0)
 				continue;
diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
index 71a31ed738c9..581f9ffb4237 100644
--- a/tools/lib/perf/include/internal/cpumap.h
+++ b/tools/lib/perf/include/internal/cpumap.h
@@ -4,6 +4,11 @@
 
 #include <linux/refcount.h>
 
+/** A wrapper around a CPU to avoid confusion with the perf_cpu_map's map's indices. */
+struct perf_cpu {
+	int cpu;
+};
+
 /**
  * A sized, reference counted, sorted array of integers representing CPU
  * numbers. This is commonly used to capture which CPUs a PMU is associated
@@ -16,13 +21,13 @@ struct perf_cpu_map {
 	/** Length of the map array. */
 	int		nr;
 	/** The CPU values. */
-	int		map[];
+	struct perf_cpu	map[];
 };
 
 #ifndef MAX_NR_CPUS
 #define MAX_NR_CPUS	2048
 #endif
 
-int perf_cpu_map__idx(const struct perf_cpu_map *cpus, int cpu);
+int perf_cpu_map__idx(const struct perf_cpu_map *cpus, struct perf_cpu cpu);
 
 #endif /* __LIBPERF_INTERNAL_CPUMAP_H */
diff --git a/tools/lib/perf/include/internal/evlist.h b/tools/lib/perf/include/internal/evlist.h
index 6f74269a3ad4..4cefade540bd 100644
--- a/tools/lib/perf/include/internal/evlist.h
+++ b/tools/lib/perf/include/internal/evlist.h
@@ -4,6 +4,7 @@
 
 #include <linux/list.h>
 #include <api/fd/array.h>
+#include <internal/cpumap.h>
 #include <internal/evsel.h>
 
 #define PERF_EVLIST__HLIST_BITS 8
@@ -36,7 +37,7 @@ typedef void
 typedef struct perf_mmap*
 (*perf_evlist_mmap__cb_get_t)(struct perf_evlist*, bool, int);
 typedef int
-(*perf_evlist_mmap__cb_mmap_t)(struct perf_mmap*, struct perf_mmap_param*, int, int);
+(*perf_evlist_mmap__cb_mmap_t)(struct perf_mmap*, struct perf_mmap_param*, int, struct perf_cpu);
 
 struct perf_evlist_mmap_ops {
 	perf_evlist_mmap__cb_idx_t	idx;
diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/include/internal/evsel.h
index 1f3eacbad2e8..cfc9ebd7968e 100644
--- a/tools/lib/perf/include/internal/evsel.h
+++ b/tools/lib/perf/include/internal/evsel.h
@@ -6,8 +6,8 @@
 #include <linux/perf_event.h>
 #include <stdbool.h>
 #include <sys/types.h>
+#include <internal/cpumap.h>
 
-struct perf_cpu_map;
 struct perf_thread_map;
 struct xyarray;
 
@@ -27,7 +27,7 @@ struct perf_sample_id {
 	* queue number.
 	*/
 	int			 idx;
-	int			 cpu;
+	struct perf_cpu		 cpu;
 	pid_t			 tid;
 
 	/* Holds total ID period value for PERF_SAMPLE_READ processing. */
diff --git a/tools/lib/perf/include/internal/mmap.h b/tools/lib/perf/include/internal/mmap.h
index 5e3422f40ed5..5a062af8e9d8 100644
--- a/tools/lib/perf/include/internal/mmap.h
+++ b/tools/lib/perf/include/internal/mmap.h
@@ -6,6 +6,7 @@
 #include <linux/refcount.h>
 #include <linux/types.h>
 #include <stdbool.h>
+#include <internal/cpumap.h>
 
 /* perf sample has 16 bits size limit */
 #define PERF_SAMPLE_MAX_SIZE (1 << 16)
@@ -24,7 +25,7 @@ struct perf_mmap {
 	void			*base;
 	int			 mask;
 	int			 fd;
-	int			 cpu;
+	struct perf_cpu		 cpu;
 	refcount_t		 refcnt;
 	u64			 prev;
 	u64			 start;
@@ -46,7 +47,7 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map);
 void perf_mmap__init(struct perf_mmap *map, struct perf_mmap *prev,
 		     bool overwrite, libperf_unmap_cb_t unmap_cb);
 int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
-		    int fd, int cpu);
+		    int fd, struct perf_cpu cpu);
 void perf_mmap__munmap(struct perf_mmap *map);
 void perf_mmap__get(struct perf_mmap *map);
 void perf_mmap__put(struct perf_mmap *map);
diff --git a/tools/lib/perf/include/perf/cpumap.h b/tools/lib/perf/include/perf/cpumap.h
index 3f1c0afa3ccd..15b8faafd615 100644
--- a/tools/lib/perf/include/perf/cpumap.h
+++ b/tools/lib/perf/include/perf/cpumap.h
@@ -3,11 +3,10 @@
 #define __LIBPERF_CPUMAP_H
 
 #include <perf/core.h>
+#include <perf/cpumap.h>
 #include <stdio.h>
 #include <stdbool.h>
 
-struct perf_cpu_map;
-
 LIBPERF_API struct perf_cpu_map *perf_cpu_map__dummy_new(void);
 LIBPERF_API struct perf_cpu_map *perf_cpu_map__default_new(void);
 LIBPERF_API struct perf_cpu_map *perf_cpu_map__new(const char *cpu_list);
@@ -16,11 +15,11 @@ LIBPERF_API struct perf_cpu_map *perf_cpu_map__get(struct perf_cpu_map *map);
 LIBPERF_API struct perf_cpu_map *perf_cpu_map__merge(struct perf_cpu_map *orig,
 						     struct perf_cpu_map *other);
 LIBPERF_API void perf_cpu_map__put(struct perf_cpu_map *map);
-LIBPERF_API int perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
+LIBPERF_API struct perf_cpu perf_cpu_map__cpu(const struct perf_cpu_map *cpus, int idx);
 LIBPERF_API int perf_cpu_map__nr(const struct perf_cpu_map *cpus);
 LIBPERF_API bool perf_cpu_map__empty(const struct perf_cpu_map *map);
-LIBPERF_API int perf_cpu_map__max(struct perf_cpu_map *map);
-LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, int cpu);
+LIBPERF_API struct perf_cpu perf_cpu_map__max(struct perf_cpu_map *map);
+LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
 
 #define perf_cpu_map__for_each_cpu(cpu, idx, cpus)		\
 	for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx);	\
diff --git a/tools/lib/perf/mmap.c b/tools/lib/perf/mmap.c
index aaa457904008..f7ee07cb5818 100644
--- a/tools/lib/perf/mmap.c
+++ b/tools/lib/perf/mmap.c
@@ -32,7 +32,7 @@ size_t perf_mmap__mmap_len(struct perf_mmap *map)
 }
 
 int perf_mmap__mmap(struct perf_mmap *map, struct perf_mmap_param *mp,
-		    int fd, int cpu)
+		    int fd, struct perf_cpu cpu)
 {
 	map->prev = 0;
 	map->mask = mp->mask;
diff --git a/tools/perf/bench/epoll-ctl.c b/tools/perf/bench/epoll-ctl.c
index ddaca75c3bc0..1a17ec83d3c4 100644
--- a/tools/perf/bench/epoll-ctl.c
+++ b/tools/perf/bench/epoll-ctl.c
@@ -253,7 +253,7 @@ static int do_threads(struct worker *worker, struct perf_cpu_map *cpu)
 
 		if (!noaffinity) {
 			CPU_ZERO(&cpuset);
-			CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+			CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 			ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset);
 			if (ret)
diff --git a/tools/perf/bench/epoll-wait.c b/tools/perf/bench/epoll-wait.c
index 79d13dbc0a47..0d1dd8879197 100644
--- a/tools/perf/bench/epoll-wait.c
+++ b/tools/perf/bench/epoll-wait.c
@@ -342,7 +342,7 @@ static int do_threads(struct worker *worker, struct perf_cpu_map *cpu)
 
 		if (!noaffinity) {
 			CPU_ZERO(&cpuset);
-			CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+			CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 			ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset);
 			if (ret)
diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
index fcdea3e44937..9627b6ab8670 100644
--- a/tools/perf/bench/futex-hash.c
+++ b/tools/perf/bench/futex-hash.c
@@ -177,7 +177,7 @@ int bench_futex_hash(int argc, const char **argv)
 			goto errmem;
 
 		CPU_ZERO(&cpuset);
-		CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+		CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 		ret = pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset);
 		if (ret)
diff --git a/tools/perf/bench/futex-lock-pi.c b/tools/perf/bench/futex-lock-pi.c
index 137890f78e17..a512a320df74 100644
--- a/tools/perf/bench/futex-lock-pi.c
+++ b/tools/perf/bench/futex-lock-pi.c
@@ -136,7 +136,7 @@ static void create_threads(struct worker *w, pthread_attr_t thread_attr,
 			worker[i].futex = &global_futex;
 
 		CPU_ZERO(&cpuset);
-		CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+		CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 		if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset))
 			err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
diff --git a/tools/perf/bench/futex-requeue.c b/tools/perf/bench/futex-requeue.c
index f7a5ffebb940..aca47ce8b1e7 100644
--- a/tools/perf/bench/futex-requeue.c
+++ b/tools/perf/bench/futex-requeue.c
@@ -131,7 +131,7 @@ static void block_threads(pthread_t *w,
 	/* create and block all threads */
 	for (i = 0; i < params.nthreads; i++) {
 		CPU_ZERO(&cpuset);
-		CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+		CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 		if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset))
 			err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
diff --git a/tools/perf/bench/futex-wake-parallel.c b/tools/perf/bench/futex-wake-parallel.c
index 0983f40b4b40..888ee6037945 100644
--- a/tools/perf/bench/futex-wake-parallel.c
+++ b/tools/perf/bench/futex-wake-parallel.c
@@ -152,7 +152,7 @@ static void block_threads(pthread_t *w, pthread_attr_t thread_attr,
 	/* create and block all threads */
 	for (i = 0; i < params.nthreads; i++) {
 		CPU_ZERO(&cpuset);
-		CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+		CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 		if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset))
 			err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
diff --git a/tools/perf/bench/futex-wake.c b/tools/perf/bench/futex-wake.c
index 2226a475e782..aa82db51c0ab 100644
--- a/tools/perf/bench/futex-wake.c
+++ b/tools/perf/bench/futex-wake.c
@@ -105,7 +105,7 @@ static void block_threads(pthread_t *w,
 	/* create and block all threads */
 	for (i = 0; i < params.nthreads; i++) {
 		CPU_ZERO(&cpuset);
-		CPU_SET(cpu->map[i % cpu->nr], &cpuset);
+		CPU_SET(perf_cpu_map__cpu(cpu, i % perf_cpu_map__nr(cpu)).cpu, &cpuset);
 
 		if (pthread_attr_setaffinity_np(&thread_attr, sizeof(cpu_set_t), &cpuset))
 			err(EXIT_FAILURE, "pthread_attr_setaffinity_np");
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c
index ad1fbeafc93d..77dd4afacca4 100644
--- a/tools/perf/builtin-c2c.c
+++ b/tools/perf/builtin-c2c.c
@@ -2015,7 +2015,8 @@ static int setup_nodes(struct perf_session *session)
 {
 	struct numa_node *n;
 	unsigned long **nodes;
-	int node, cpu, idx;
+	int node, idx;
+	struct perf_cpu cpu;
 	int *cpu2node;
 
 	if (c2c.node_info > 2)
@@ -2038,8 +2039,8 @@ static int setup_nodes(struct perf_session *session)
 	if (!cpu2node)
 		return -ENOMEM;
 
-	for (cpu = 0; cpu < c2c.cpus_cnt; cpu++)
-		cpu2node[cpu] = -1;
+	for (idx = 0; idx < c2c.cpus_cnt; idx++)
+		cpu2node[idx] = -1;
 
 	c2c.cpu2node = cpu2node;
 
@@ -2058,12 +2059,12 @@ static int setup_nodes(struct perf_session *session)
 			continue;
 
 		perf_cpu_map__for_each_cpu(cpu, idx, map) {
-			set_bit(cpu, set);
+			set_bit(cpu.cpu, set);
 
-			if (WARN_ONCE(cpu2node[cpu] != -1, "node/cpu topology bug"))
+			if (WARN_ONCE(cpu2node[cpu.cpu] != -1, "node/cpu topology bug"))
 				return -EINVAL;
 
-			cpu2node[cpu] = node;
+			cpu2node[cpu.cpu] = node;
 		}
 	}
 
diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
index f16c39a37a52..71452599f87d 100644
--- a/tools/perf/builtin-ftrace.c
+++ b/tools/perf/builtin-ftrace.c
@@ -281,7 +281,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpumap)
 	int ret;
 	int last_cpu;
 
-	last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1);
+	last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1).cpu;
 	mask_size = last_cpu / 4 + 2; /* one more byte for EOS */
 	mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
 
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index da03a341c63c..99d7ff9a8eff 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -192,7 +192,7 @@ static int evsel__process_alloc_node_event(struct evsel *evsel, struct perf_samp
 	int ret = evsel__process_alloc_event(evsel, sample);
 
 	if (!ret) {
-		int node1 = cpu__get_node(sample->cpu),
+		int node1 = cpu__get_node((struct perf_cpu){.cpu = sample->cpu}),
 		    node2 = evsel__intval(evsel, sample, "node");
 
 		if (node1 != node2)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 6ac2160913ea..0a63295d30f0 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -2796,7 +2796,7 @@ int cmd_record(int argc, const char **argv)
 	symbol__init(NULL);
 
 	if (rec->opts.affinity != PERF_AFFINITY_SYS) {
-		rec->affinity_mask.nbits = cpu__max_cpu();
+		rec->affinity_mask.nbits = cpu__max_cpu().cpu;
 		rec->affinity_mask.bits = bitmap_zalloc(rec->affinity_mask.nbits);
 		if (!rec->affinity_mask.bits) {
 			pr_err("Failed to allocate thread mask for %zd cpus\n", rec->affinity_mask.nbits);
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 9da1da4749c9..72d446de9c60 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -167,7 +167,7 @@ struct trace_sched_handler {
 
 struct perf_sched_map {
 	DECLARE_BITMAP(comp_cpus_mask, MAX_CPUS);
-	int			*comp_cpus;
+	struct perf_cpu		*comp_cpus;
 	bool			 comp;
 	struct perf_thread_map *color_pids;
 	const char		*color_pids_str;
@@ -191,7 +191,7 @@ struct perf_sched {
  * Track the current task - that way we can know whether there's any
  * weird events, such as a task being switched away that is not current.
  */
-	int		 max_cpu;
+	struct perf_cpu	 max_cpu;
 	u32		 curr_pid[MAX_CPUS];
 	struct thread	 *curr_thread[MAX_CPUS];
 	char		 next_shortname1;
@@ -1535,28 +1535,31 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	int new_shortname;
 	u64 timestamp0, timestamp = sample->time;
 	s64 delta;
-	int i, this_cpu = sample->cpu;
+	int i;
+	struct perf_cpu this_cpu = {
+		.cpu = sample->cpu,
+	};
 	int cpus_nr;
 	bool new_cpu = false;
 	const char *color = PERF_COLOR_NORMAL;
 	char stimestamp[32];
 
-	BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
+	BUG_ON(this_cpu.cpu >= MAX_CPUS || this_cpu.cpu < 0);
 
-	if (this_cpu > sched->max_cpu)
+	if (this_cpu.cpu > sched->max_cpu.cpu)
 		sched->max_cpu = this_cpu;
 
 	if (sched->map.comp) {
 		cpus_nr = bitmap_weight(sched->map.comp_cpus_mask, MAX_CPUS);
-		if (!test_and_set_bit(this_cpu, sched->map.comp_cpus_mask)) {
+		if (!test_and_set_bit(this_cpu.cpu, sched->map.comp_cpus_mask)) {
 			sched->map.comp_cpus[cpus_nr++] = this_cpu;
 			new_cpu = true;
 		}
 	} else
-		cpus_nr = sched->max_cpu;
+		cpus_nr = sched->max_cpu.cpu;
 
-	timestamp0 = sched->cpu_last_switched[this_cpu];
-	sched->cpu_last_switched[this_cpu] = timestamp;
+	timestamp0 = sched->cpu_last_switched[this_cpu.cpu];
+	sched->cpu_last_switched[this_cpu.cpu] = timestamp;
 	if (timestamp0)
 		delta = timestamp - timestamp0;
 	else
@@ -1577,7 +1580,7 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 		return -1;
 	}
 
-	sched->curr_thread[this_cpu] = thread__get(sched_in);
+	sched->curr_thread[this_cpu.cpu] = thread__get(sched_in);
 
 	printf("  ");
 
@@ -1608,8 +1611,10 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 	}
 
 	for (i = 0; i < cpus_nr; i++) {
-		int cpu = sched->map.comp ? sched->map.comp_cpus[i] : i;
-		struct thread *curr_thread = sched->curr_thread[cpu];
+		struct perf_cpu cpu = {
+			.cpu = sched->map.comp ? sched->map.comp_cpus[i].cpu : i,
+		};
+		struct thread *curr_thread = sched->curr_thread[cpu.cpu];
 		struct thread_runtime *curr_tr;
 		const char *pid_color = color;
 		const char *cpu_color = color;
@@ -1623,13 +1628,13 @@ static int map_switch_event(struct perf_sched *sched, struct evsel *evsel,
 		if (sched->map.color_cpus && perf_cpu_map__has(sched->map.color_cpus, cpu))
 			cpu_color = COLOR_CPUS;
 
-		if (cpu != this_cpu)
+		if (cpu.cpu != this_cpu.cpu)
 			color_fprintf(stdout, color, " ");
 		else
 			color_fprintf(stdout, cpu_color, "*");
 
-		if (sched->curr_thread[cpu]) {
-			curr_tr = thread__get_runtime(sched->curr_thread[cpu]);
+		if (sched->curr_thread[cpu.cpu]) {
+			curr_tr = thread__get_runtime(sched->curr_thread[cpu.cpu]);
 			if (curr_tr == NULL) {
 				thread__put(sched_in);
 				return -1;
@@ -1929,7 +1934,7 @@ static char *timehist_get_commstr(struct thread *thread)
 
 static void timehist_header(struct perf_sched *sched)
 {
-	u32 ncpus = sched->max_cpu + 1;
+	u32 ncpus = sched->max_cpu.cpu + 1;
 	u32 i, j;
 
 	printf("%15s %6s ", "time", "cpu");
@@ -2008,7 +2013,7 @@ static void timehist_print_sample(struct perf_sched *sched,
 	struct thread_runtime *tr = thread__priv(thread);
 	const char *next_comm = evsel__strval(evsel, sample, "next_comm");
 	const u32 next_pid = evsel__intval(evsel, sample, "next_pid");
-	u32 max_cpus = sched->max_cpu + 1;
+	u32 max_cpus = sched->max_cpu.cpu + 1;
 	char tstr[64];
 	char nstr[30];
 	u64 wait_time;
@@ -2389,7 +2394,7 @@ static void timehist_print_wakeup_event(struct perf_sched *sched,
 	timestamp__scnprintf_usec(sample->time, tstr, sizeof(tstr));
 	printf("%15s [%04d] ", tstr, sample->cpu);
 	if (sched->show_cpu_visual)
-		printf(" %*s ", sched->max_cpu + 1, "");
+		printf(" %*s ", sched->max_cpu.cpu + 1, "");
 
 	printf(" %-*s ", comm_width, timehist_get_commstr(thread));
 
@@ -2449,13 +2454,13 @@ static void timehist_print_migration_event(struct perf_sched *sched,
 {
 	struct thread *thread;
 	char tstr[64];
-	u32 max_cpus = sched->max_cpu + 1;
+	u32 max_cpus;
 	u32 ocpu, dcpu;
 
 	if (sched->summary_only)
 		return;
 
-	max_cpus = sched->max_cpu + 1;
+	max_cpus = sched->max_cpu.cpu + 1;
 	ocpu = evsel__intval(evsel, sample, "orig_cpu");
 	dcpu = evsel__intval(evsel, sample, "dest_cpu");
 
@@ -2918,7 +2923,7 @@ static void timehist_print_summary(struct perf_sched *sched,
 
 	printf("    Total scheduling time (msec): ");
 	print_sched_time(hist_time, 2);
-	printf(" (x %d)\n", sched->max_cpu);
+	printf(" (x %d)\n", sched->max_cpu.cpu);
 }
 
 typedef int (*sched_handler)(struct perf_tool *tool,
@@ -2935,9 +2940,11 @@ static int perf_timehist__process_sample(struct perf_tool *tool,
 {
 	struct perf_sched *sched = container_of(tool, struct perf_sched, tool);
 	int err = 0;
-	int this_cpu = sample->cpu;
+	struct perf_cpu this_cpu = {
+		.cpu = sample->cpu,
+	};
 
-	if (this_cpu > sched->max_cpu)
+	if (this_cpu.cpu > sched->max_cpu.cpu)
 		sched->max_cpu = this_cpu;
 
 	if (evsel->handler != NULL) {
@@ -3054,10 +3061,10 @@ static int perf_sched__timehist(struct perf_sched *sched)
 		goto out;
 
 	/* pre-allocate struct for per-CPU idle stats */
-	sched->max_cpu = session->header.env.nr_cpus_online;
-	if (sched->max_cpu == 0)
-		sched->max_cpu = 4;
-	if (init_idle_threads(sched->max_cpu))
+	sched->max_cpu.cpu = session->header.env.nr_cpus_online;
+	if (sched->max_cpu.cpu == 0)
+		sched->max_cpu.cpu = 4;
+	if (init_idle_threads(sched->max_cpu.cpu))
 		goto out;
 
 	/* summary_only implies summary option, but don't overwrite summary if set */
@@ -3209,10 +3216,10 @@ static int setup_map_cpus(struct perf_sched *sched)
 {
 	struct perf_cpu_map *map;
 
-	sched->max_cpu  = sysconf(_SC_NPROCESSORS_CONF);
+	sched->max_cpu.cpu  = sysconf(_SC_NPROCESSORS_CONF);
 
 	if (sched->map.comp) {
-		sched->map.comp_cpus = zalloc(sched->max_cpu * sizeof(int));
+		sched->map.comp_cpus = zalloc(sched->max_cpu.cpu * sizeof(int));
 		if (!sched->map.comp_cpus)
 			return -1;
 	}
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index bb43529618b3..ecd4f99a6c14 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -2115,7 +2115,8 @@ static struct scripting_ops	*scripting_ops;
 static void __process_stat(struct evsel *counter, u64 tstamp)
 {
 	int nthreads = perf_thread_map__nr(counter->core.threads);
-	int idx, cpu, thread;
+	int idx, thread;
+	struct perf_cpu cpu;
 	static int header_printed;
 
 	if (counter->core.system_wide)
@@ -2134,7 +2135,7 @@ static void __process_stat(struct evsel *counter, u64 tstamp)
 			counts = perf_counts(counter->counts, idx, thread);
 
 			printf("%3d %8d %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %15" PRIu64 " %s\n",
-				cpu,
+				cpu.cpu,
 				perf_thread_map__pid(counter->core.threads, thread),
 				counts->val,
 				counts->ena,
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 68543bc7459f..f81c7f595fd9 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -234,7 +234,7 @@ static bool cpus_map_matched(struct evsel *a, struct evsel *b)
 		return false;
 
 	for (int i = 0; i < a->core.cpus->nr; i++) {
-		if (a->core.cpus->map[i] != b->core.cpus->map[i])
+		if (a->core.cpus->map[i].cpu != b->core.cpus->map[i].cpu)
 			return false;
 	}
 
@@ -331,7 +331,7 @@ static int evsel__write_stat_event(struct evsel *counter, int cpu_map_idx, u32 t
 				   struct perf_counts_values *count)
 {
 	struct perf_sample_id *sid = SID(counter, cpu_map_idx, thread);
-	int cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx);
+	struct perf_cpu cpu = perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx);
 
 	return perf_event__synthesize_stat(NULL, cpu, thread, sid->id, count,
 					   process_synthesized_event, NULL);
@@ -396,7 +396,8 @@ static int read_counter_cpu(struct evsel *counter, struct timespec *rs, int cpu_
 			fprintf(stat_config.output,
 				"%s: %d: %" PRIu64 " %" PRIu64 " %" PRIu64 "\n",
 					evsel__name(counter),
-					perf_cpu_map__cpu(evsel__cpus(counter), cpu_map_idx),
+					perf_cpu_map__cpu(evsel__cpus(counter),
+							  cpu_map_idx).cpu,
 					count->val, count->ena, count->run);
 		}
 	}
@@ -1328,61 +1329,61 @@ static const char *const aggr_mode__string[] = {
 };
 
 static struct aggr_cpu_id perf_stat__get_socket(struct perf_stat_config *config __maybe_unused,
-						int cpu)
+						struct perf_cpu cpu)
 {
 	return aggr_cpu_id__socket(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_die(struct perf_stat_config *config __maybe_unused,
-					     int cpu)
+					     struct perf_cpu cpu)
 {
 	return aggr_cpu_id__die(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_core(struct perf_stat_config *config __maybe_unused,
-					      int cpu)
+					      struct perf_cpu cpu)
 {
 	return aggr_cpu_id__core(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_node(struct perf_stat_config *config __maybe_unused,
-					      int cpu)
+					      struct perf_cpu cpu)
 {
 	return aggr_cpu_id__node(cpu, /*data=*/NULL);
 }
 
 static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
-					      aggr_get_id_t get_id, int cpu)
+					      aggr_get_id_t get_id, struct perf_cpu cpu)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu]))
-		config->cpus_aggr_map->map[cpu] = get_id(config, cpu);
+	if (aggr_cpu_id__is_empty(&config->cpus_aggr_map->map[cpu.cpu]))
+		config->cpus_aggr_map->map[cpu.cpu] = get_id(config, cpu);
 
-	id = config->cpus_aggr_map->map[cpu];
+	id = config->cpus_aggr_map->map[cpu.cpu];
 	return id;
 }
 
 static struct aggr_cpu_id perf_stat__get_socket_cached(struct perf_stat_config *config,
-						       int cpu)
+						       struct perf_cpu cpu)
 {
 	return perf_stat__get_aggr(config, perf_stat__get_socket, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_die_cached(struct perf_stat_config *config,
-						    int cpu)
+						    struct perf_cpu cpu)
 {
 	return perf_stat__get_aggr(config, perf_stat__get_die, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_core_cached(struct perf_stat_config *config,
-						     int cpu)
+						     struct perf_cpu cpu)
 {
 	return perf_stat__get_aggr(config, perf_stat__get_core, cpu);
 }
 
 static struct aggr_cpu_id perf_stat__get_node_cached(struct perf_stat_config *config,
-						     int cpu)
+						     struct perf_cpu cpu)
 {
 	return perf_stat__get_aggr(config, perf_stat__get_node, cpu);
 }
@@ -1467,7 +1468,7 @@ static int perf_stat_init_aggr_mode(void)
 	 * taking the highest cpu number to be the size of
 	 * the aggregation translate cpumap.
 	 */
-	nr = perf_cpu_map__max(evsel_list->core.cpus);
+	nr = perf_cpu_map__max(evsel_list->core.cpus).cpu;
 	stat_config.cpus_aggr_map = cpu_aggr_map__empty_new(nr + 1);
 	return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
 }
@@ -1495,71 +1496,66 @@ static void perf_stat__exit_aggr_mode(void)
 	stat_config.cpus_aggr_map = NULL;
 }
 
-static inline int perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
+static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
 {
 	struct perf_env *env = data;
-	int cpu;
+	struct perf_cpu cpu = perf_cpu_map__cpu(map, idx);
 
-	if (idx > map->nr)
-		return -1;
-
-	cpu = map->map[idx];
-
-	if (cpu >= env->nr_cpus_avail)
-		return -1;
+	if (cpu.cpu >= env->nr_cpus_avail)
+		cpu.cpu = -1;
 
 	return cpu;
 }
 
-static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
+static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct perf_env *env = data;
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	if (cpu != -1)
-		id.socket = env->cpu[cpu].socket_id;
+	if (cpu.cpu != -1)
+		id.socket = env->cpu[cpu.cpu].socket_id;
 
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
+static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct perf_env *env = data;
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	if (cpu != -1) {
+	if (cpu.cpu != -1) {
 		/*
 		 * die_id is relative to socket, so start
 		 * with the socket ID and then add die to
 		 * make a unique ID.
 		 */
-		id.socket = env->cpu[cpu].socket_id;
-		id.die = env->cpu[cpu].die_id;
+		id.socket = env->cpu[cpu.cpu].socket_id;
+		id.die = env->cpu[cpu.cpu].die_id;
 	}
 
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
+static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct perf_env *env = data;
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
-	if (cpu != -1) {
+	if (cpu.cpu != -1) {
 		/*
 		 * core_id is relative to socket and die,
 		 * we need a global id. So we set
 		 * socket, die id and core id
 		 */
-		id.socket = env->cpu[cpu].socket_id;
-		id.die = env->cpu[cpu].die_id;
-		id.core = env->cpu[cpu].core_id;
+		id.socket = env->cpu[cpu.cpu].socket_id;
+		id.die = env->cpu[cpu.cpu].die_id;
+		id.core = env->cpu[cpu.cpu].core_id;
 	}
 
 	return id;
 }
 
-static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
+static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(struct perf_cpu cpu, void *data)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
@@ -1568,24 +1564,24 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
 }
 
 static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
-						     int cpu)
+						     struct perf_cpu cpu)
 {
 	return perf_env__get_socket_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 static struct aggr_cpu_id perf_stat__get_die_file(struct perf_stat_config *config __maybe_unused,
-						  int cpu)
+						  struct perf_cpu cpu)
 {
 	return perf_env__get_die_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
 static struct aggr_cpu_id perf_stat__get_core_file(struct perf_stat_config *config __maybe_unused,
-						   int cpu)
+						   struct perf_cpu cpu)
 {
 	return perf_env__get_core_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
 
 static struct aggr_cpu_id perf_stat__get_node_file(struct perf_stat_config *config __maybe_unused,
-						   int cpu)
+						   struct perf_cpu cpu)
 {
 	return perf_env__get_node_aggr_by_cpu(cpu, &perf_stat.session->header.env);
 }
diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c
index 0f73e300f207..56fba08a3037 100644
--- a/tools/perf/tests/attr.c
+++ b/tools/perf/tests/attr.c
@@ -65,7 +65,7 @@ do {									\
 
 #define WRITE_ASS(field, fmt) __WRITE_ASS(field, fmt, attr->field)
 
-static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
+static int store_event(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu,
 		       int fd, int group_fd, unsigned long flags)
 {
 	FILE *file;
@@ -93,7 +93,7 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
 	/* syscall arguments */
 	__WRITE_ASS(fd,       "d", fd);
 	__WRITE_ASS(group_fd, "d", group_fd);
-	__WRITE_ASS(cpu,      "d", cpu);
+	__WRITE_ASS(cpu,      "d", cpu.cpu);
 	__WRITE_ASS(pid,      "d", pid);
 	__WRITE_ASS(flags,   "lu", flags);
 
@@ -144,7 +144,7 @@ static int store_event(struct perf_event_attr *attr, pid_t pid, int cpu,
 	return 0;
 }
 
-void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
+void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu,
 		     int fd, int group_fd, unsigned long flags)
 {
 	int errno_saved = errno;
diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c
index 384856347236..0bf399c49849 100644
--- a/tools/perf/tests/bitmap.c
+++ b/tools/perf/tests/bitmap.c
@@ -18,7 +18,7 @@ static unsigned long *get_bitmap(const char *str, int nbits)
 
 	if (map && bm) {
 		for (i = 0; i < map->nr; i++)
-			set_bit(map->map[i], bm);
+			set_bit(map->map[i].cpu, bm);
 	}
 
 	if (map)
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
index 89a155092f85..84e87e31f119 100644
--- a/tools/perf/tests/cpumap.c
+++ b/tools/perf/tests/cpumap.c
@@ -38,7 +38,7 @@ static int process_event_mask(struct perf_tool *tool __maybe_unused,
 	TEST_ASSERT_VAL("wrong nr",  map->nr == 20);
 
 	for (i = 0; i < 20; i++) {
-		TEST_ASSERT_VAL("wrong cpu", map->map[i] == i);
+		TEST_ASSERT_VAL("wrong cpu", map->map[i].cpu == i);
 	}
 
 	perf_cpu_map__put(map);
@@ -67,8 +67,8 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
 
 	map = cpu_map__new_data(data);
 	TEST_ASSERT_VAL("wrong nr",  map->nr == 2);
-	TEST_ASSERT_VAL("wrong cpu", map->map[0] == 1);
-	TEST_ASSERT_VAL("wrong cpu", map->map[1] == 256);
+	TEST_ASSERT_VAL("wrong cpu", map->map[0].cpu == 1);
+	TEST_ASSERT_VAL("wrong cpu", map->map[1].cpu == 256);
 	TEST_ASSERT_VAL("wrong refcnt", refcount_read(&map->refcnt) == 1);
 	perf_cpu_map__put(map);
 	return 0;
diff --git a/tools/perf/tests/event_update.c b/tools/perf/tests/event_update.c
index d01532d40acb..16b6d6f47f38 100644
--- a/tools/perf/tests/event_update.c
+++ b/tools/perf/tests/event_update.c
@@ -76,9 +76,9 @@ static int process_event_cpus(struct perf_tool *tool __maybe_unused,
 	TEST_ASSERT_VAL("wrong id", ev->id == 123);
 	TEST_ASSERT_VAL("wrong type", ev->type == PERF_EVENT_UPDATE__CPUS);
 	TEST_ASSERT_VAL("wrong cpus", map->nr == 3);
-	TEST_ASSERT_VAL("wrong cpus", map->map[0] == 1);
-	TEST_ASSERT_VAL("wrong cpus", map->map[1] == 2);
-	TEST_ASSERT_VAL("wrong cpus", map->map[2] == 3);
+	TEST_ASSERT_VAL("wrong cpus", map->map[0].cpu == 1);
+	TEST_ASSERT_VAL("wrong cpus", map->map[1].cpu == 2);
+	TEST_ASSERT_VAL("wrong cpus", map->map[2].cpu == 3);
 	perf_cpu_map__put(map);
 	return 0;
 }
diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c
index b17b86391383..f4a4aba33f76 100644
--- a/tools/perf/tests/mem2node.c
+++ b/tools/perf/tests/mem2node.c
@@ -31,7 +31,7 @@ static unsigned long *get_bitmap(const char *str, int nbits)
 
 	if (map && bm) {
 		for (i = 0; i < map->nr; i++) {
-			set_bit(map->map[i], bm);
+			set_bit(map->map[i].cpu, bm);
 		}
 	}
 
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 90b2feda31ac..0ad62914b4d7 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -59,11 +59,11 @@ static int test__basic_mmap(struct test_suite *test __maybe_unused, int subtest
 	}
 
 	CPU_ZERO(&cpu_set);
-	CPU_SET(cpus->map[0], &cpu_set);
+	CPU_SET(cpus->map[0].cpu, &cpu_set);
 	sched_setaffinity(0, sizeof(cpu_set), &cpu_set);
 	if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
 		pr_debug("sched_setaffinity() failed on CPU %d: %s ",
-			 cpus->map[0], str_error_r(errno, sbuf, sizeof(sbuf)));
+			 cpus->map[0].cpu, str_error_r(errno, sbuf, sizeof(sbuf)));
 		goto out_free_cpus;
 	}
 
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index ca0a50e92839..1ab362323d25 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -22,7 +22,8 @@
 static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __maybe_unused,
 						  int subtest __maybe_unused)
 {
-	int err = -1, fd, idx, cpu;
+	int err = -1, fd, idx;
+	struct perf_cpu cpu;
 	struct perf_cpu_map *cpus;
 	struct evsel *evsel;
 	unsigned int nr_openat_calls = 111, i;
@@ -66,15 +67,15 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 		 * without CPU_ALLOC. 1024 cpus in 2010 still seems
 		 * a reasonable upper limit tho :-)
 		 */
-		if (cpu >= CPU_SETSIZE) {
-			pr_debug("Ignoring CPU %d\n", cpu);
+		if (cpu.cpu >= CPU_SETSIZE) {
+			pr_debug("Ignoring CPU %d\n", cpu.cpu);
 			continue;
 		}
 
-		CPU_SET(cpu, &cpu_set);
+		CPU_SET(cpu.cpu, &cpu_set);
 		if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
 			pr_debug("sched_setaffinity() failed on CPU %d: %s ",
-				 cpu,
+				 cpu.cpu,
 				 str_error_r(errno, sbuf, sizeof(sbuf)));
 			goto out_close_fd;
 		}
@@ -82,7 +83,7 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 			fd = openat(0, "/etc/passwd", O_RDONLY);
 			close(fd);
 		}
-		CPU_CLR(cpu, &cpu_set);
+		CPU_CLR(cpu.cpu, &cpu_set);
 	}
 
 	evsel->core.cpus = perf_cpu_map__get(cpus);
@@ -92,7 +93,7 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
 		unsigned int expected;
 
-		if (cpu >= CPU_SETSIZE)
+		if (cpu.cpu >= CPU_SETSIZE)
 			continue;
 
 		if (evsel__read_on_cpu(evsel, idx, 0) < 0) {
@@ -104,7 +105,7 @@ static int test__openat_syscall_event_on_all_cpus(struct test_suite *test __mayb
 		expected = nr_openat_calls + idx;
 		if (perf_counts(evsel->counts, idx, 0)->val != expected) {
 			pr_debug("evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpu, perf_counts(evsel->counts, idx, 0)->val);
+				 expected, cpu.cpu, perf_counts(evsel->counts, idx, 0)->val);
 			err = -1;
 		}
 	}
diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
index 2eb096b5e6da..500974040fe3 100644
--- a/tools/perf/tests/stat.c
+++ b/tools/perf/tests/stat.c
@@ -87,7 +87,8 @@ static int test__synthesize_stat(struct test_suite *test __maybe_unused, int sub
 	count.run = 300;
 
 	TEST_ASSERT_VAL("failed to synthesize stat_config",
-		!perf_event__synthesize_stat(NULL, 1, 2, 3, &count, process_stat_event, NULL));
+			!perf_event__synthesize_stat(NULL, (struct perf_cpu){.cpu = 1}, 2, 3,
+						     &count, process_stat_event, NULL));
 
 	return 0;
 }
diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c
index 33e4cb81265c..c4ef0c7002f1 100644
--- a/tools/perf/tests/topology.c
+++ b/tools/perf/tests/topology.c
@@ -112,7 +112,9 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	TEST_ASSERT_VAL("Session header CPU map not set", session->header.env.cpu);
 
 	for (i = 0; i < session->header.env.nr_cpus_avail; i++) {
-		if (!perf_cpu_map__has(map, i))
+		struct perf_cpu cpu = { .cpu = i };
+
+		if (!perf_cpu_map__has(map, cpu))
 			continue;
 		pr_debug("CPU %d, core %d, socket %d\n", i,
 			 session->header.env.cpu[i].core_id,
@@ -122,15 +124,15 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	// Test that CPU ID contains socket, die, core and CPU
 	for (i = 0; i < map->nr; i++) {
 		id = aggr_cpu_id__cpu(perf_cpu_map__cpu(map, i), NULL);
-		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i] == id.cpu);
+		TEST_ASSERT_VAL("Cpu map - CPU ID doesn't match", map->map[i].cpu == id.cpu.cpu);
 
 		TEST_ASSERT_VAL("Cpu map - Core ID doesn't match",
-			session->header.env.cpu[map->map[i]].core_id == id.core);
+			session->header.env.cpu[map->map[i].cpu].core_id == id.core);
 		TEST_ASSERT_VAL("Cpu map - Socket ID doesn't match",
-			session->header.env.cpu[map->map[i]].socket_id == id.socket);
+			session->header.env.cpu[map->map[i].cpu].socket_id == id.socket);
 
 		TEST_ASSERT_VAL("Cpu map - Die ID doesn't match",
-			session->header.env.cpu[map->map[i]].die_id == id.die);
+			session->header.env.cpu[map->map[i].cpu].die_id == id.die);
 		TEST_ASSERT_VAL("Cpu map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Cpu map - Thread is set", id.thread == -1);
 	}
@@ -139,13 +141,13 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	for (i = 0; i < map->nr; i++) {
 		id = aggr_cpu_id__core(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Core map - Core ID doesn't match",
-			session->header.env.cpu[map->map[i]].core_id == id.core);
+			session->header.env.cpu[map->map[i].cpu].core_id == id.core);
 
 		TEST_ASSERT_VAL("Core map - Socket ID doesn't match",
-			session->header.env.cpu[map->map[i]].socket_id == id.socket);
+			session->header.env.cpu[map->map[i].cpu].socket_id == id.socket);
 
 		TEST_ASSERT_VAL("Core map - Die ID doesn't match",
-			session->header.env.cpu[map->map[i]].die_id == id.die);
+			session->header.env.cpu[map->map[i].cpu].die_id == id.die);
 		TEST_ASSERT_VAL("Core map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Core map - Thread is set", id.thread == -1);
 	}
@@ -154,14 +156,14 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	for (i = 0; i < map->nr; i++) {
 		id = aggr_cpu_id__die(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Die map - Socket ID doesn't match",
-			session->header.env.cpu[map->map[i]].socket_id == id.socket);
+			session->header.env.cpu[map->map[i].cpu].socket_id == id.socket);
 
 		TEST_ASSERT_VAL("Die map - Die ID doesn't match",
-			session->header.env.cpu[map->map[i]].die_id == id.die);
+			session->header.env.cpu[map->map[i].cpu].die_id == id.die);
 
 		TEST_ASSERT_VAL("Die map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Die map - Core is set", id.core == -1);
-		TEST_ASSERT_VAL("Die map - CPU is set", id.cpu == -1);
+		TEST_ASSERT_VAL("Die map - CPU is set", id.cpu.cpu == -1);
 		TEST_ASSERT_VAL("Die map - Thread is set", id.thread == -1);
 	}
 
@@ -169,12 +171,12 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 	for (i = 0; i < map->nr; i++) {
 		id = aggr_cpu_id__socket(perf_cpu_map__cpu(map, i), NULL);
 		TEST_ASSERT_VAL("Socket map - Socket ID doesn't match",
-			session->header.env.cpu[map->map[i]].socket_id == id.socket);
+			session->header.env.cpu[map->map[i].cpu].socket_id == id.socket);
 
 		TEST_ASSERT_VAL("Socket map - Node ID is set", id.node == -1);
 		TEST_ASSERT_VAL("Socket map - Die ID is set", id.die == -1);
 		TEST_ASSERT_VAL("Socket map - Core is set", id.core == -1);
-		TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu == -1);
+		TEST_ASSERT_VAL("Socket map - CPU is set", id.cpu.cpu == -1);
 		TEST_ASSERT_VAL("Socket map - Thread is set", id.thread == -1);
 	}
 
@@ -186,7 +188,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map)
 		TEST_ASSERT_VAL("Node map - Socket is set", id.socket == -1);
 		TEST_ASSERT_VAL("Node map - Die ID is set", id.die == -1);
 		TEST_ASSERT_VAL("Node map - Core is set", id.core == -1);
-		TEST_ASSERT_VAL("Node map - CPU is set", id.cpu == -1);
+		TEST_ASSERT_VAL("Node map - CPU is set", id.cpu.cpu == -1);
 		TEST_ASSERT_VAL("Node map - Thread is set", id.thread == -1);
 	}
 	perf_session__delete(session);
diff --git a/tools/perf/util/affinity.c b/tools/perf/util/affinity.c
index 7b12bd7a3080..f1e30d566db3 100644
--- a/tools/perf/util/affinity.c
+++ b/tools/perf/util/affinity.c
@@ -11,7 +11,7 @@
 
 static int get_cpu_set_size(void)
 {
-	int sz = cpu__max_cpu() + 8 - 1;
+	int sz = cpu__max_cpu().cpu + 8 - 1;
 	/*
 	 * sched_getaffinity doesn't like masks smaller than the kernel.
 	 * Hopefully that's big enough.
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index c679394b898d..5632efc44738 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -123,7 +123,7 @@ int auxtrace_mmap__mmap(struct auxtrace_mmap *mm,
 	mm->prev = 0;
 	mm->idx = mp->idx;
 	mm->tid = mp->tid;
-	mm->cpu = mp->cpu;
+	mm->cpu = mp->cpu.cpu;
 
 	if (!mp->len) {
 		mm->base = NULL;
@@ -180,7 +180,7 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp,
 		else
 			mp->tid = -1;
 	} else {
-		mp->cpu = -1;
+		mp->cpu.cpu = -1;
 		mp->tid = perf_thread_map__pid(evlist->core.threads, idx);
 	}
 }
@@ -292,7 +292,7 @@ static int auxtrace_queues__queue_buffer(struct auxtrace_queues *queues,
 	if (!queue->set) {
 		queue->set = true;
 		queue->tid = buffer->tid;
-		queue->cpu = buffer->cpu;
+		queue->cpu = buffer->cpu.cpu;
 	}
 
 	buffer->buffer_nr = queues->next_buffer_nr++;
@@ -339,11 +339,11 @@ static int auxtrace_queues__split_buffer(struct auxtrace_queues *queues,
 	return 0;
 }
 
-static bool filter_cpu(struct perf_session *session, int cpu)
+static bool filter_cpu(struct perf_session *session, struct perf_cpu cpu)
 {
 	unsigned long *cpu_bitmap = session->itrace_synth_opts->cpu_bitmap;
 
-	return cpu_bitmap && cpu != -1 && !test_bit(cpu, cpu_bitmap);
+	return cpu_bitmap && cpu.cpu != -1 && !test_bit(cpu.cpu, cpu_bitmap);
 }
 
 static int auxtrace_queues__add_buffer(struct auxtrace_queues *queues,
@@ -399,7 +399,7 @@ int auxtrace_queues__add_event(struct auxtrace_queues *queues,
 	struct auxtrace_buffer buffer = {
 		.pid = -1,
 		.tid = event->auxtrace.tid,
-		.cpu = event->auxtrace.cpu,
+		.cpu = { event->auxtrace.cpu },
 		.data_offset = data_offset,
 		.offset = event->auxtrace.offset,
 		.reference = event->auxtrace.reference,
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index bbf0d78c6401..19910b9011f3 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/perf_event.h>
 #include <linux/types.h>
+#include <internal/cpumap.h>
 #include <asm/bitsperlong.h>
 #include <asm/barrier.h>
 
@@ -240,7 +241,7 @@ struct auxtrace_buffer {
 	size_t			size;
 	pid_t			pid;
 	pid_t			tid;
-	int			cpu;
+	struct perf_cpu		cpu;
 	void			*data;
 	off_t			data_offset;
 	void			*mmap_addr;
@@ -350,7 +351,7 @@ struct auxtrace_mmap_params {
 	int		prot;
 	int		idx;
 	pid_t		tid;
-	int		cpu;
+	struct perf_cpu	cpu;
 };
 
 /**
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 48ce583af0ec..12b2243222b0 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -13,8 +13,8 @@
 #include <linux/ctype.h>
 #include <linux/zalloc.h>
 
-static int max_cpu_num;
-static int max_present_cpu_num;
+static struct perf_cpu max_cpu_num;
+static struct perf_cpu max_present_cpu_num;
 static int max_node_num;
 /**
  * The numa node X as read from /sys/devices/system/node/nodeX indexed by the
@@ -37,9 +37,9 @@ static struct perf_cpu_map *cpu_map__from_entries(struct cpu_map_entries *cpus)
 			 * otherwise it would become 65535.
 			 */
 			if (cpus->cpu[i] == (u16) -1)
-				map->map[i] = -1;
+				map->map[i].cpu = -1;
 			else
-				map->map[i] = (int) cpus->cpu[i];
+				map->map[i].cpu = (int) cpus->cpu[i];
 		}
 	}
 
@@ -58,7 +58,7 @@ static struct perf_cpu_map *cpu_map__from_mask(struct perf_record_record_cpu_map
 		int cpu, i = 0;
 
 		for_each_set_bit(cpu, mask->mask, nbits)
-			map->map[i++] = cpu;
+			map->map[i++].cpu = cpu;
 	}
 	return map;
 
@@ -91,7 +91,7 @@ struct perf_cpu_map *perf_cpu_map__empty_new(int nr)
 
 		cpus->nr = nr;
 		for (i = 0; i < nr; i++)
-			cpus->map[i] = -1;
+			cpus->map[i].cpu = -1;
 
 		refcount_set(&cpus->refcnt, 1);
 	}
@@ -126,13 +126,13 @@ static int cpu__get_topology_int(int cpu, const char *name, int *value)
 	return sysfs__read_int(path, value);
 }
 
-int cpu__get_socket_id(int cpu)
+int cpu__get_socket_id(struct perf_cpu cpu)
 {
-	int value, ret = cpu__get_topology_int(cpu, "physical_package_id", &value);
+	int value, ret = cpu__get_topology_int(cpu.cpu, "physical_package_id", &value);
 	return ret ?: value;
 }
 
-struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data __maybe_unused)
+struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
@@ -161,7 +161,8 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 				       aggr_cpu_id_get_t get_id,
 				       void *data)
 {
-	int cpu, idx;
+	int idx;
+	struct perf_cpu cpu;
 	struct cpu_aggr_map *c = cpu_aggr_map__empty_new(cpus->nr);
 
 	if (!c)
@@ -201,14 +202,14 @@ struct cpu_aggr_map *cpu_aggr_map__new(const struct perf_cpu_map *cpus,
 
 }
 
-int cpu__get_die_id(int cpu)
+int cpu__get_die_id(struct perf_cpu cpu)
 {
-	int value, ret = cpu__get_topology_int(cpu, "die_id", &value);
+	int value, ret = cpu__get_topology_int(cpu.cpu, "die_id", &value);
 
 	return ret ?: value;
 }
 
-struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data)
+struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data)
 {
 	struct aggr_cpu_id id;
 	int die;
@@ -231,13 +232,13 @@ struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data)
 	return id;
 }
 
-int cpu__get_core_id(int cpu)
+int cpu__get_core_id(struct perf_cpu cpu)
 {
-	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
+	int value, ret = cpu__get_topology_int(cpu.cpu, "core_id", &value);
 	return ret ?: value;
 }
 
-struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data)
+struct aggr_cpu_id aggr_cpu_id__core(struct perf_cpu cpu, void *data)
 {
 	struct aggr_cpu_id id;
 	int core = cpu__get_core_id(cpu);
@@ -256,7 +257,7 @@ struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data)
 
 }
 
-struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data)
+struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data)
 {
 	struct aggr_cpu_id id;
 
@@ -270,7 +271,7 @@ struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data)
 
 }
 
-struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data __maybe_unused)
+struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data __maybe_unused)
 {
 	struct aggr_cpu_id id = aggr_cpu_id__empty();
 
@@ -318,8 +319,8 @@ static void set_max_cpu_num(void)
 	int ret = -1;
 
 	/* set up default */
-	max_cpu_num = 4096;
-	max_present_cpu_num = 4096;
+	max_cpu_num.cpu = 4096;
+	max_present_cpu_num.cpu = 4096;
 
 	mnt = sysfs__mountpoint();
 	if (!mnt)
@@ -332,7 +333,7 @@ static void set_max_cpu_num(void)
 		goto out;
 	}
 
-	ret = get_max_num(path, &max_cpu_num);
+	ret = get_max_num(path, &max_cpu_num.cpu);
 	if (ret)
 		goto out;
 
@@ -343,11 +344,11 @@ static void set_max_cpu_num(void)
 		goto out;
 	}
 
-	ret = get_max_num(path, &max_present_cpu_num);
+	ret = get_max_num(path, &max_present_cpu_num.cpu);
 
 out:
 	if (ret)
-		pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num);
+		pr_err("Failed to read max cpus, using default of %d\n", max_cpu_num.cpu);
 }
 
 /* Determine highest possible node in the system for sparse allocation */
@@ -386,31 +387,31 @@ int cpu__max_node(void)
 	return max_node_num;
 }
 
-int cpu__max_cpu(void)
+struct perf_cpu cpu__max_cpu(void)
 {
-	if (unlikely(!max_cpu_num))
+	if (unlikely(!max_cpu_num.cpu))
 		set_max_cpu_num();
 
 	return max_cpu_num;
 }
 
-int cpu__max_present_cpu(void)
+struct perf_cpu cpu__max_present_cpu(void)
 {
-	if (unlikely(!max_present_cpu_num))
+	if (unlikely(!max_present_cpu_num.cpu))
 		set_max_cpu_num();
 
 	return max_present_cpu_num;
 }
 
 
-int cpu__get_node(int cpu)
+int cpu__get_node(struct perf_cpu cpu)
 {
 	if (unlikely(cpunode_map == NULL)) {
 		pr_debug("cpu_map not initialized\n");
 		return -1;
 	}
 
-	return cpunode_map[cpu];
+	return cpunode_map[cpu.cpu];
 }
 
 static int init_cpunode_map(void)
@@ -420,13 +421,13 @@ static int init_cpunode_map(void)
 	set_max_cpu_num();
 	set_max_node_num();
 
-	cpunode_map = calloc(max_cpu_num, sizeof(int));
+	cpunode_map = calloc(max_cpu_num.cpu, sizeof(int));
 	if (!cpunode_map) {
 		pr_err("%s: calloc failed\n", __func__);
 		return -1;
 	}
 
-	for (i = 0; i < max_cpu_num; i++)
+	for (i = 0; i < max_cpu_num.cpu; i++)
 		cpunode_map[i] = -1;
 
 	return 0;
@@ -487,35 +488,37 @@ int cpu__setup_cpunode_map(void)
 
 size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
 {
-	int i, cpu, start = -1;
+	int i, start = -1;
 	bool first = true;
 	size_t ret = 0;
 
 #define COMMA first ? "" : ","
 
 	for (i = 0; i < map->nr + 1; i++) {
+		struct perf_cpu cpu = { .cpu = INT_MAX };
 		bool last = i == map->nr;
 
-		cpu = last ? INT_MAX : map->map[i];
+		if (!last)
+			cpu = map->map[i];
 
 		if (start == -1) {
 			start = i;
 			if (last) {
 				ret += snprintf(buf + ret, size - ret,
 						"%s%d", COMMA,
-						map->map[i]);
+						map->map[i].cpu);
 			}
-		} else if (((i - start) != (cpu - map->map[start])) || last) {
+		} else if (((i - start) != (cpu.cpu - map->map[start].cpu)) || last) {
 			int end = i - 1;
 
 			if (start == end) {
 				ret += snprintf(buf + ret, size - ret,
 						"%s%d", COMMA,
-						map->map[start]);
+						map->map[start].cpu);
 			} else {
 				ret += snprintf(buf + ret, size - ret,
 						"%s%d-%d", COMMA,
-						map->map[start], map->map[end]);
+						map->map[start].cpu, map->map[end].cpu);
 			}
 			first = false;
 			start = i;
@@ -542,23 +545,23 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
 	int i, cpu;
 	char *ptr = buf;
 	unsigned char *bitmap;
-	int last_cpu = perf_cpu_map__cpu(map, map->nr - 1);
+	struct perf_cpu last_cpu = perf_cpu_map__cpu(map, map->nr - 1);
 
 	if (buf == NULL)
 		return 0;
 
-	bitmap = zalloc(last_cpu / 8 + 1);
+	bitmap = zalloc(last_cpu.cpu / 8 + 1);
 	if (bitmap == NULL) {
 		buf[0] = '\0';
 		return 0;
 	}
 
 	for (i = 0; i < map->nr; i++) {
-		cpu = perf_cpu_map__cpu(map, i);
+		cpu = perf_cpu_map__cpu(map, i).cpu;
 		bitmap[cpu / 8] |= 1 << (cpu % 8);
 	}
 
-	for (cpu = last_cpu / 4 * 4; cpu >= 0; cpu -= 4) {
+	for (cpu = last_cpu.cpu / 4 * 4; cpu >= 0; cpu -= 4) {
 		unsigned char bits = bitmap[cpu / 8];
 
 		if (cpu % 8)
@@ -594,7 +597,7 @@ bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b
 		a->socket == b->socket &&
 		a->die == b->die &&
 		a->core == b->core &&
-		a->cpu == b->cpu;
+		a->cpu.cpu == b->cpu.cpu;
 }
 
 bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
@@ -604,7 +607,7 @@ bool aggr_cpu_id__is_empty(const struct aggr_cpu_id *a)
 		a->socket == -1 &&
 		a->die == -1 &&
 		a->core == -1 &&
-		a->cpu == -1;
+		a->cpu.cpu == -1;
 }
 
 struct aggr_cpu_id aggr_cpu_id__empty(void)
@@ -615,7 +618,7 @@ struct aggr_cpu_id aggr_cpu_id__empty(void)
 		.socket = -1,
 		.die = -1,
 		.core = -1,
-		.cpu = -1
+		.cpu = (struct perf_cpu){ .cpu = -1 },
 	};
 	return ret;
 }
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index b98cd1739677..afc15027d678 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -23,7 +23,7 @@ struct aggr_cpu_id {
 	/** The core id as read from /sys/devices/system/cpu/cpuX/topology/core_id. */
 	int core;
 	/** CPU aggregation, note there is one CPU for each SMT thread. */
-	int cpu;
+	struct perf_cpu cpu;
 };
 
 /** A collection of aggr_cpu_id values, the "built" version is sorted and uniqued. */
@@ -48,28 +48,28 @@ const struct perf_cpu_map *cpu_map__online(void); /* thread unsafe */
 int cpu__setup_cpunode_map(void);
 
 int cpu__max_node(void);
-int cpu__max_cpu(void);
-int cpu__max_present_cpu(void);
+struct perf_cpu cpu__max_cpu(void);
+struct perf_cpu cpu__max_present_cpu(void);
 /**
  * cpu__get_node - Returns the numa node X as read from
  * /sys/devices/system/node/nodeX for the given CPU.
  */
-int cpu__get_node(int cpu);
+int cpu__get_node(struct perf_cpu cpu);
 /**
  * cpu__get_socket_id - Returns the socket number as read from
  * /sys/devices/system/cpu/cpuX/topology/physical_package_id for the given CPU.
  */
-int cpu__get_socket_id(int cpu);
+int cpu__get_socket_id(struct perf_cpu cpu);
 /**
  * cpu__get_die_id - Returns the die id as read from
  * /sys/devices/system/cpu/cpuX/topology/die_id for the given CPU.
  */
-int cpu__get_die_id(int cpu);
+int cpu__get_die_id(struct perf_cpu cpu);
 /**
  * cpu__get_core_id - Returns the core id as read from
  * /sys/devices/system/cpu/cpuX/topology/core_id for the given CPU.
  */
-int cpu__get_core_id(int cpu);
+int cpu__get_core_id(struct perf_cpu cpu);
 
 /**
  * cpu_aggr_map__empty_new - Create a cpu_aggr_map of size nr with every entry
@@ -77,7 +77,7 @@ int cpu__get_core_id(int cpu);
  */
 struct cpu_aggr_map *cpu_aggr_map__empty_new(int nr);
 
-typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(int cpu, void *data);
+typedef struct aggr_cpu_id (*aggr_cpu_id_get_t)(struct perf_cpu cpu, void *data);
 
 /**
  * cpu_aggr_map__new - Create a cpu_aggr_map with an aggr_cpu_id for each cpu in
@@ -98,29 +98,29 @@ struct aggr_cpu_id aggr_cpu_id__empty(void);
  * the socket for cpu. The function signature is compatible with
  * aggr_cpu_id_get_t.
  */
-struct aggr_cpu_id aggr_cpu_id__socket(int cpu, void *data);
+struct aggr_cpu_id aggr_cpu_id__socket(struct perf_cpu cpu, void *data);
 /**
  * aggr_cpu_id__die - Create an aggr_cpu_id with the die and socket populated
  * with the die and socket for cpu. The function signature is compatible with
  * aggr_cpu_id_get_t.
  */
-struct aggr_cpu_id aggr_cpu_id__die(int cpu, void *data);
+struct aggr_cpu_id aggr_cpu_id__die(struct perf_cpu cpu, void *data);
 /**
  * aggr_cpu_id__core - Create an aggr_cpu_id with the core, die and socket
  * populated with the core, die and socket for cpu. The function signature is
  * compatible with aggr_cpu_id_get_t.
  */
-struct aggr_cpu_id aggr_cpu_id__core(int cpu, void *data);
+struct aggr_cpu_id aggr_cpu_id__core(struct perf_cpu cpu, void *data);
 /**
  * aggr_cpu_id__core - Create an aggr_cpu_id with the cpu, core, die and socket
  * populated with the cpu, core, die and socket for cpu. The function signature
  * is compatible with aggr_cpu_id_get_t.
  */
-struct aggr_cpu_id aggr_cpu_id__cpu(int cpu, void *data);
+struct aggr_cpu_id aggr_cpu_id__cpu(struct perf_cpu cpu, void *data);
 /**
  * aggr_cpu_id__node - Create an aggr_cpu_id with the numa node populated for
  * cpu. The function signature is compatible with aggr_cpu_id_get_t.
  */
-struct aggr_cpu_id aggr_cpu_id__node(int cpu, void *data);
+struct aggr_cpu_id aggr_cpu_id__node(struct perf_cpu cpu, void *data);
 
 #endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/cputopo.c b/tools/perf/util/cputopo.c
index 8affb37d90e7..84ca106a3246 100644
--- a/tools/perf/util/cputopo.c
+++ b/tools/perf/util/cputopo.c
@@ -187,7 +187,7 @@ struct cpu_topology *cpu_topology__new(void)
 	struct perf_cpu_map *map;
 	bool has_die = has_die_topology();
 
-	ncpus = cpu__max_present_cpu();
+	ncpus = cpu__max_present_cpu().cpu;
 
 	/* build online CPU map */
 	map = perf_cpu_map__new(NULL);
@@ -218,7 +218,7 @@ struct cpu_topology *cpu_topology__new(void)
 	tp->core_cpus_list = addr;
 
 	for (i = 0; i < nr; i++) {
-		if (!perf_cpu_map__has(map, i))
+		if (!perf_cpu_map__has(map, (struct perf_cpu){ .cpu = i }))
 			continue;
 
 		ret = build_cpu_topology(tp, i);
@@ -333,7 +333,7 @@ struct numa_topology *numa_topology__new(void)
 	tp->nr = nr;
 
 	for (i = 0; i < nr; i++) {
-		if (load_numa_node(&tp->nodes[i], node_map->map[i])) {
+		if (load_numa_node(&tp->nodes[i], node_map->map[i].cpu)) {
 			numa_topology__delete(tp);
 			tp = NULL;
 			break;
diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
index fd12c0dcaefb..579e44c59914 100644
--- a/tools/perf/util/env.c
+++ b/tools/perf/util/env.c
@@ -285,13 +285,13 @@ int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
 
 int perf_env__read_cpu_topology_map(struct perf_env *env)
 {
-	int cpu, nr_cpus;
+	int idx, nr_cpus;
 
 	if (env->cpu != NULL)
 		return 0;
 
 	if (env->nr_cpus_avail == 0)
-		env->nr_cpus_avail = cpu__max_present_cpu();
+		env->nr_cpus_avail = cpu__max_present_cpu().cpu;
 
 	nr_cpus = env->nr_cpus_avail;
 	if (nr_cpus == -1)
@@ -301,10 +301,12 @@ int perf_env__read_cpu_topology_map(struct perf_env *env)
 	if (env->cpu == NULL)
 		return -ENOMEM;
 
-	for (cpu = 0; cpu < nr_cpus; ++cpu) {
-		env->cpu[cpu].core_id	= cpu__get_core_id(cpu);
-		env->cpu[cpu].socket_id	= cpu__get_socket_id(cpu);
-		env->cpu[cpu].die_id	= cpu__get_die_id(cpu);
+	for (idx = 0; idx < nr_cpus; ++idx) {
+		struct perf_cpu cpu = { .cpu = idx };
+
+		env->cpu[idx].core_id	= cpu__get_core_id(cpu);
+		env->cpu[idx].socket_id	= cpu__get_socket_id(cpu);
+		env->cpu[idx].die_id	= cpu__get_die_id(cpu);
 	}
 
 	env->nr_cpus_avail = nr_cpus;
@@ -381,7 +383,7 @@ static int perf_env__read_arch(struct perf_env *env)
 static int perf_env__read_nr_cpus_avail(struct perf_env *env)
 {
 	if (env->nr_cpus_avail == 0)
-		env->nr_cpus_avail = cpu__max_present_cpu();
+		env->nr_cpus_avail = cpu__max_present_cpu().cpu;
 
 	return env->nr_cpus_avail ? 0 : -ENOENT;
 }
@@ -487,7 +489,7 @@ const char *perf_env__pmu_mappings(struct perf_env *env)
 	return env->pmu_mappings;
 }
 
-int perf_env__numa_node(struct perf_env *env, int cpu)
+int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu)
 {
 	if (!env->nr_numa_map) {
 		struct numa_node *nn;
@@ -495,7 +497,7 @@ int perf_env__numa_node(struct perf_env *env, int cpu)
 
 		for (i = 0; i < env->nr_numa_nodes; i++) {
 			nn = &env->numa_nodes[i];
-			nr = max(nr, perf_cpu_map__max(nn->map));
+			nr = max(nr, perf_cpu_map__max(nn->map).cpu);
 		}
 
 		nr++;
@@ -514,13 +516,14 @@ int perf_env__numa_node(struct perf_env *env, int cpu)
 		env->nr_numa_map = nr;
 
 		for (i = 0; i < env->nr_numa_nodes; i++) {
-			int tmp, j;
+			struct perf_cpu tmp;
+			int j;
 
 			nn = &env->numa_nodes[i];
-			perf_cpu_map__for_each_cpu(j, tmp, nn->map)
-				env->numa_map[j] = i;
+			perf_cpu_map__for_each_cpu(tmp, j, nn->map)
+				env->numa_map[tmp.cpu] = i;
 		}
 	}
 
-	return cpu >= 0 && cpu < env->nr_numa_map ? env->numa_map[cpu] : -1;
+	return cpu.cpu >= 0 && cpu.cpu < env->nr_numa_map ? env->numa_map[cpu.cpu] : -1;
 }
diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
index 163e5ec503a2..a3541f98e1fc 100644
--- a/tools/perf/util/env.h
+++ b/tools/perf/util/env.h
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/rbtree.h>
+#include "cpumap.h"
 #include "rwsem.h"
 
 struct perf_cpu_map;
@@ -170,5 +171,5 @@ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
 bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
 struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id);
 
-int perf_env__numa_node(struct perf_env *env, int cpu);
+int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu);
 #endif /* __PERF_ENV_H */
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 39d294f6c321..11eb95b2106b 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -350,13 +350,13 @@ struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affin
 		.cpu_map_idx = 0,
 		.evlist_cpu_map_idx = 0,
 		.evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus),
-		.cpu = -1,
+		.cpu = (struct perf_cpu){ .cpu = -1},
 		.affinity = affinity,
 	};
 
 	if (itr.affinity) {
 		itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0);
-		affinity__set(itr.affinity, itr.cpu);
+		affinity__set(itr.affinity, itr.cpu.cpu);
 		itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu);
 		/*
 		 * If this CPU isn't in the evsel's cpu map then advance through
@@ -385,7 +385,7 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr)
 			perf_cpu_map__cpu(evlist_cpu_itr->container->core.all_cpus,
 					  evlist_cpu_itr->evlist_cpu_map_idx);
 		if (evlist_cpu_itr->affinity)
-			affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu);
+			affinity__set(evlist_cpu_itr->affinity, evlist_cpu_itr->cpu.cpu);
 		evlist_cpu_itr->cpu_map_idx =
 			perf_cpu_map__idx(evlist_cpu_itr->evsel->core.cpus,
 					  evlist_cpu_itr->cpu);
@@ -819,7 +819,7 @@ perf_evlist__mmap_cb_get(struct perf_evlist *_evlist, bool overwrite, int idx)
 
 static int
 perf_evlist__mmap_cb_mmap(struct perf_mmap *_map, struct perf_mmap_param *_mp,
-			  int output, int cpu)
+			  int output, struct perf_cpu cpu)
 {
 	struct mmap *map = container_of(_map, struct mmap, core);
 	struct mmap_params *mp = container_of(_mp, struct mmap_params, core);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 57828ebfcb61..64cba56fbc74 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -344,7 +344,7 @@ struct evlist_cpu_iterator {
 	/** The number of CPU map entries in evlist->core.all_cpus. */
 	int evlist_cpu_map_nr;
 	/** The current CPU of the iterator. */
-	int cpu;
+	struct perf_cpu cpu;
 	/** If present, used to set the affinity when switching between CPUs. */
 	struct affinity *affinity;
 };
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 2b18b29a534f..7b806cb462bb 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1594,7 +1594,7 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu_map_idx, int thread, bool
 static int evsel__match_other_cpu(struct evsel *evsel, struct evsel *other,
 				  int cpu_map_idx)
 {
-	int cpu;
+	struct perf_cpu cpu;
 
 	cpu = perf_cpu_map__cpu(evsel->core.cpus, cpu_map_idx);
 	return perf_cpu_map__idx(other->core.cpus, cpu);
@@ -2020,9 +2020,9 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
 			test_attr__ready();
 
 			pr_debug2_peo("sys_perf_event_open: pid %d  cpu %d  group_fd %d  flags %#lx",
-				pid, cpus->map[idx], group_fd, evsel->open_flags);
+				pid, cpus->map[idx].cpu, group_fd, evsel->open_flags);
 
-			fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx],
+			fd = sys_perf_event_open(&evsel->core.attr, pid, cpus->map[idx].cpu,
 						group_fd, evsel->open_flags);
 
 			FD(evsel, idx, thread) = fd;
diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c
index 666b59baeb70..e808738493e2 100644
--- a/tools/perf/util/expr.c
+++ b/tools/perf/util/expr.c
@@ -410,7 +410,7 @@ double expr__get_literal(const char *literal)
 		return smt_on() > 0 ? 1.0 : 0.0;
 
 	if (!strcmp("#num_cpus", literal))
-		return cpu__max_present_cpu();
+		return cpu__max_present_cpu().cpu;
 
 	/*
 	 * Assume that topology strings are consistent, such as CPUs "0-1"
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index e3c1a532d059..6da12e522edc 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -472,7 +472,7 @@ static int write_nrcpus(struct feat_fd *ff,
 	u32 nrc, nra;
 	int ret;
 
-	nrc = cpu__max_present_cpu();
+	nrc = cpu__max_present_cpu().cpu;
 
 	nr = sysconf(_SC_NPROCESSORS_ONLN);
 	if (nr < 0)
@@ -1163,7 +1163,7 @@ static int build_caches(struct cpu_cache_level caches[], u32 *cntp)
 	u32 nr, cpu;
 	u16 level;
 
-	nr = cpu__max_cpu();
+	nr = cpu__max_cpu().cpu;
 
 	for (cpu = 0; cpu < nr; cpu++) {
 		for (level = 0; level < MAX_CACHE_LVL; level++) {
@@ -1195,7 +1195,7 @@ static int build_caches(struct cpu_cache_level caches[], u32 *cntp)
 static int write_cache(struct feat_fd *ff,
 		       struct evlist *evlist __maybe_unused)
 {
-	u32 max_caches = cpu__max_cpu() * MAX_CACHE_LVL;
+	u32 max_caches = cpu__max_cpu().cpu * MAX_CACHE_LVL;
 	struct cpu_cache_level caches[max_caches];
 	u32 cnt = 0, i, version = 1;
 	int ret;
diff --git a/tools/perf/util/mmap.c b/tools/perf/util/mmap.c
index 23ecdba9e670..12261ed8c15b 100644
--- a/tools/perf/util/mmap.c
+++ b/tools/perf/util/mmap.c
@@ -94,7 +94,7 @@ static void perf_mmap__aio_free(struct mmap *map, int idx)
 	}
 }
 
-static int perf_mmap__aio_bind(struct mmap *map, int idx, int cpu, int affinity)
+static int perf_mmap__aio_bind(struct mmap *map, int idx, struct perf_cpu cpu, int affinity)
 {
 	void *data;
 	size_t mmap_len;
@@ -138,7 +138,7 @@ static void perf_mmap__aio_free(struct mmap *map, int idx)
 }
 
 static int perf_mmap__aio_bind(struct mmap *map __maybe_unused, int idx __maybe_unused,
-		int cpu __maybe_unused, int affinity __maybe_unused)
+		struct perf_cpu cpu __maybe_unused, int affinity __maybe_unused)
 {
 	return 0;
 }
@@ -240,7 +240,8 @@ void mmap__munmap(struct mmap *map)
 
 static void build_node_mask(int node, struct mmap_cpu_mask *mask)
 {
-	int c, cpu, nr_cpus;
+	int idx, nr_cpus;
+	struct perf_cpu cpu;
 	const struct perf_cpu_map *cpu_map = NULL;
 
 	cpu_map = cpu_map__online();
@@ -248,16 +249,16 @@ static void build_node_mask(int node, struct mmap_cpu_mask *mask)
 		return;
 
 	nr_cpus = perf_cpu_map__nr(cpu_map);
-	for (c = 0; c < nr_cpus; c++) {
-		cpu = cpu_map->map[c]; /* map c index to online cpu index */
+	for (idx = 0; idx < nr_cpus; idx++) {
+		cpu = cpu_map->map[idx]; /* map c index to online cpu index */
 		if (cpu__get_node(cpu) == node)
-			set_bit(cpu, mask->bits);
+			set_bit(cpu.cpu, mask->bits);
 	}
 }
 
 static int perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *mp)
 {
-	map->affinity_mask.nbits = cpu__max_cpu();
+	map->affinity_mask.nbits = cpu__max_cpu().cpu;
 	map->affinity_mask.bits = bitmap_zalloc(map->affinity_mask.nbits);
 	if (!map->affinity_mask.bits)
 		return -1;
@@ -265,12 +266,12 @@ static int perf_mmap__setup_affinity_mask(struct mmap *map, struct mmap_params *
 	if (mp->affinity == PERF_AFFINITY_NODE && cpu__max_node() > 1)
 		build_node_mask(cpu__get_node(map->core.cpu), &map->affinity_mask);
 	else if (mp->affinity == PERF_AFFINITY_CPU)
-		set_bit(map->core.cpu, map->affinity_mask.bits);
+		set_bit(map->core.cpu.cpu, map->affinity_mask.bits);
 
 	return 0;
 }
 
-int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu)
+int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, struct perf_cpu cpu)
 {
 	if (perf_mmap__mmap(&map->core, &mp->core, fd, cpu)) {
 		pr_debug2("failed to mmap perf event ring buffer, error %d\n",
diff --git a/tools/perf/util/mmap.h b/tools/perf/util/mmap.h
index 8e259b9610f8..83f6bd4d4082 100644
--- a/tools/perf/util/mmap.h
+++ b/tools/perf/util/mmap.h
@@ -7,6 +7,7 @@
 #include <linux/types.h>
 #include <linux/ring_buffer.h>
 #include <linux/bitops.h>
+#include <perf/cpumap.h>
 #include <stdbool.h>
 #include <pthread.h> // for cpu_set_t
 #ifdef HAVE_AIO_SUPPORT
@@ -52,7 +53,7 @@ struct mmap_params {
 	struct auxtrace_mmap_params auxtrace_mp;
 };
 
-int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, int cpu);
+int mmap__mmap(struct mmap *map, struct mmap_params *mp, int fd, struct perf_cpu cpu);
 void mmap__munmap(struct mmap *map);
 
 union perf_event *perf_mmap__read_forward(struct mmap *map);
diff --git a/tools/perf/util/perf_api_probe.c b/tools/perf/util/perf_api_probe.c
index 020411682a3c..734d006d9a8c 100644
--- a/tools/perf/util/perf_api_probe.c
+++ b/tools/perf/util/perf_api_probe.c
@@ -11,7 +11,7 @@
 
 typedef void (*setup_probe_fn_t)(struct evsel *evsel);
 
-static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
+static int perf_do_probe_api(setup_probe_fn_t fn, struct perf_cpu cpu, const char *str)
 {
 	struct evlist *evlist;
 	struct evsel *evsel;
@@ -29,7 +29,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
 	evsel = evlist__first(evlist);
 
 	while (1) {
-		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
+		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1, flags);
 		if (fd < 0) {
 			if (pid == -1 && errno == EACCES) {
 				pid = 0;
@@ -43,7 +43,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
 
 	fn(evsel);
 
-	fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1, flags);
+	fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1, flags);
 	if (fd < 0) {
 		if (errno == EINVAL)
 			err = -EINVAL;
@@ -61,7 +61,8 @@ static bool perf_probe_api(setup_probe_fn_t fn)
 {
 	const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL};
 	struct perf_cpu_map *cpus;
-	int cpu, ret, i = 0;
+	struct perf_cpu cpu;
+	int ret, i = 0;
 
 	cpus = perf_cpu_map__new(NULL);
 	if (!cpus)
@@ -136,15 +137,17 @@ bool perf_can_record_cpu_wide(void)
 		.exclude_kernel = 1,
 	};
 	struct perf_cpu_map *cpus;
-	int cpu, fd;
+	struct perf_cpu cpu;
+	int fd;
 
 	cpus = perf_cpu_map__new(NULL);
 	if (!cpus)
 		return false;
+
 	cpu = cpus->map[0];
 	perf_cpu_map__put(cpus);
 
-	fd = sys_perf_event_open(&attr, -1, cpu, -1, 0);
+	fd = sys_perf_event_open(&attr, -1, cpu.cpu, -1, 0);
 	if (fd < 0)
 		return false;
 	close(fd);
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 7f782a31bda3..95fb53899bcd 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -1057,7 +1057,7 @@ static struct mmap *get_md(struct evlist *evlist, int cpu)
 	for (i = 0; i < evlist->core.nr_mmaps; i++) {
 		struct mmap *md = &evlist->mmap[i];
 
-		if (md->core.cpu == cpu)
+		if (md->core.cpu.cpu == cpu)
 			return md;
 	}
 
@@ -1443,7 +1443,7 @@ PyMODINIT_FUNC PyInit_perf(void)
  * Dummy, to avoid dragging all the test_attr infrastructure in the python
  * binding.
  */
-void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
+void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu,
                      int fd, int group_fd, unsigned long flags)
 {
 }
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index bff669b615ee..20461f174991 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -106,7 +106,7 @@ void evlist__config(struct evlist *evlist, struct record_opts *opts, struct call
 	if (opts->group)
 		evlist__set_leader(evlist);
 
-	if (evlist->core.cpus->map[0] < 0)
+	if (evlist->core.cpus->map[0].cpu < 0)
 		opts->no_inherit = true;
 
 	use_comm_exec = perf_can_comm_exec();
@@ -229,7 +229,8 @@ bool evlist__can_select_event(struct evlist *evlist, const char *str)
 {
 	struct evlist *temp_evlist;
 	struct evsel *evsel;
-	int err, fd, cpu;
+	int err, fd;
+	struct perf_cpu cpu = { .cpu = 0 };
 	bool ret = false;
 	pid_t pid = -1;
 
@@ -246,14 +247,16 @@ bool evlist__can_select_event(struct evlist *evlist, const char *str)
 	if (!evlist || perf_cpu_map__empty(evlist->core.cpus)) {
 		struct perf_cpu_map *cpus = perf_cpu_map__new(NULL);
 
-		cpu =  cpus ? cpus->map[0] : 0;
+		if (cpus)
+			cpu =  cpus->map[0];
+
 		perf_cpu_map__put(cpus);
 	} else {
 		cpu = evlist->core.cpus->map[0];
 	}
 
 	while (1) {
-		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu, -1,
+		fd = sys_perf_event_open(&evsel->core.attr, pid, cpu.cpu, -1,
 					 perf_event_open_cloexec_flag());
 		if (fd < 0) {
 			if (pid == -1 && errno == EACCES) {
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 0445bee9290f..bd95d60018a9 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -1555,7 +1555,7 @@ static void get_handler_name(char *str, size_t size,
 }
 
 static void
-process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp,
+process_stat(struct evsel *counter, struct perf_cpu cpu, int thread, u64 tstamp,
 	     struct perf_counts_values *count)
 {
 	PyObject *handler, *t;
@@ -1575,7 +1575,7 @@ process_stat(struct evsel *counter, int cpu, int thread, u64 tstamp,
 		return;
 	}
 
-	PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu));
+	PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu.cpu));
 	PyTuple_SetItem(t, n++, _PyLong_FromLong(thread));
 
 	tuple_set_u64(t, n++, tstamp);
@@ -1599,7 +1599,7 @@ static void python_process_stat(struct perf_stat_config *config,
 	int cpu, thread;
 
 	if (config->aggr_mode == AGGR_GLOBAL) {
-		process_stat(counter, -1, -1, tstamp,
+		process_stat(counter, (struct perf_cpu){ .cpu = -1 }, -1, tstamp,
 			     &counter->counts->aggr);
 		return;
 	}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e1a273048681..f19348dddd55 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -2538,15 +2538,15 @@ int perf_session__cpu_bitmap(struct perf_session *session,
 	}
 
 	for (i = 0; i < map->nr; i++) {
-		int cpu = map->map[i];
+		struct perf_cpu cpu = map->map[i];
 
-		if (cpu >= nr_cpus) {
+		if (cpu.cpu >= nr_cpus) {
 			pr_err("Requested CPU %d too large. "
-			       "Consider raising MAX_NR_CPUS\n", cpu);
+			       "Consider raising MAX_NR_CPUS\n", cpu.cpu);
 			goto out_delete_map;
 		}
 
-		set_bit(cpu, cpu_bitmap);
+		set_bit(cpu.cpu, cpu_bitmap);
 	}
 
 	err = 0;
@@ -2598,7 +2598,7 @@ int perf_event__process_id_index(struct perf_session *session,
 		if (!sid)
 			return -ENOENT;
 		sid->idx = e->idx;
-		sid->cpu = e->cpu;
+		sid->cpu.cpu = e->cpu;
 		sid->tid = e->tid;
 	}
 	return 0;
diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c
index ba95379efcfb..5db83e51ceef 100644
--- a/tools/perf/util/stat-display.c
+++ b/tools/perf/util/stat-display.c
@@ -121,10 +121,10 @@ static void aggr_printout(struct perf_stat_config *config,
 				id.die,
 				config->csv_output ? 0 : -3,
 				id.core, config->csv_sep);
-		} else if (id.cpu > -1) {
+		} else if (id.cpu.cpu > -1) {
 			fprintf(config->output, "CPU%*d%s",
 				config->csv_output ? 0 : -7,
-				id.cpu, config->csv_sep);
+				id.cpu.cpu, config->csv_sep);
 		}
 		break;
 	case AGGR_THREAD:
@@ -331,7 +331,8 @@ static int first_shadow_cpu_map_idx(struct perf_stat_config *config,
 				struct evsel *evsel, const struct aggr_cpu_id *id)
 {
 	struct perf_cpu_map *cpus = evsel__cpus(evsel);
-	int cpu, idx;
+	struct perf_cpu cpu;
+	int idx;
 
 	if (config->aggr_mode == AGGR_NONE)
 		return perf_cpu_map__idx(cpus, id->cpu);
@@ -513,7 +514,8 @@ static void printout(struct perf_stat_config *config, struct aggr_cpu_id id, int
 static void aggr_update_shadow(struct perf_stat_config *config,
 			       struct evlist *evlist)
 {
-	int cpu, idx, s;
+	int idx, s;
+	struct perf_cpu cpu;
 	struct aggr_cpu_id s2, id;
 	u64 val;
 	struct evsel *counter;
@@ -633,7 +635,8 @@ static void aggr_cb(struct perf_stat_config *config,
 		    struct evsel *counter, void *data, bool first)
 {
 	struct aggr_data *ad = data;
-	int idx, cpu;
+	int idx;
+	struct perf_cpu cpu;
 	struct perf_cpu_map *cpus;
 	struct aggr_cpu_id s2;
 
@@ -666,7 +669,7 @@ static void aggr_cb(struct perf_stat_config *config,
 static void print_counter_aggrdata(struct perf_stat_config *config,
 				   struct evsel *counter, int s,
 				   char *prefix, bool metric_only,
-				   bool *first, int cpu)
+				   bool *first, struct perf_cpu cpu)
 {
 	struct aggr_data ad;
 	FILE *output = config->output;
@@ -696,7 +699,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config,
 		fprintf(output, "%s", prefix);
 
 	uval = val * counter->scale;
-	if (cpu != -1)
+	if (cpu.cpu != -1)
 		id = aggr_cpu_id__cpu(cpu, /*data=*/NULL);
 
 	printout(config, id, nr, counter, uval,
@@ -731,8 +734,8 @@ static void print_aggr(struct perf_stat_config *config,
 		first = true;
 		evlist__for_each_entry(evlist, counter) {
 			print_counter_aggrdata(config, counter, s,
-					       prefix, metric_only,
-					       &first, /*cpu=*/-1);
+					prefix, metric_only,
+					&first, (struct perf_cpu){ .cpu = -1 });
 		}
 		if (metric_only)
 			fputc('\n', output);
@@ -893,7 +896,8 @@ static void print_counter(struct perf_stat_config *config,
 	FILE *output = config->output;
 	u64 ena, run, val;
 	double uval;
-	int idx, cpu;
+	int idx;
+	struct perf_cpu cpu;
 	struct aggr_cpu_id id;
 
 	perf_cpu_map__for_each_cpu(cpu, idx, evsel__cpus(counter)) {
@@ -921,7 +925,8 @@ static void print_no_aggr_metric(struct perf_stat_config *config,
 				 struct evlist *evlist,
 				 char *prefix)
 {
-	int all_idx, cpu;
+	int all_idx;
+	struct perf_cpu cpu;
 
 	perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.cpus) {
 		struct evsel *counter;
@@ -1211,7 +1216,8 @@ static void print_percore_thread(struct perf_stat_config *config,
 	struct aggr_cpu_id s2, id;
 	struct perf_cpu_map *cpus;
 	bool first = true;
-	int idx, cpu;
+	int idx;
+	struct perf_cpu cpu;
 
 	cpus = evsel__cpus(counter);
 	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
@@ -1247,8 +1253,8 @@ static void print_percore(struct perf_stat_config *config,
 			fprintf(output, "%s", prefix);
 
 		print_counter_aggrdata(config, counter, s,
-				       prefix, metric_only,
-				       &first, /*cpu=*/-1);
+				prefix, metric_only,
+				&first, (struct perf_cpu){ .cpu = -1 });
 	}
 
 	if (metric_only)
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 7dbd7c4f3c33..ee6f03481215 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -297,7 +297,7 @@ static int check_per_pkg(struct evsel *counter, struct perf_counts_values *vals,
 {
 	struct hashmap *mask = counter->per_pkg_mask;
 	struct perf_cpu_map *cpus = evsel__cpus(counter);
-	int cpu = perf_cpu_map__cpu(cpus, cpu_map_idx);
+	struct perf_cpu cpu = perf_cpu_map__cpu(cpus, cpu_map_idx);
 	int s, d, ret = 0;
 	uint64_t *key;
 
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 691c12fd8976..335d19cc3063 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -108,7 +108,7 @@ struct runtime_stat {
 	struct rblist value_list;
 };
 
-typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, int cpu);
+typedef struct aggr_cpu_id (*aggr_get_id_t)(struct perf_stat_config *config, struct perf_cpu cpu);
 
 struct perf_stat_config {
 	enum aggr_mode		 aggr_mode;
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 96f941e01681..4c9f211249db 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -728,7 +728,7 @@ static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus)
 	int i;
 	int ret = 0;
 	struct perf_cpu_map *m;
-	int c;
+	struct perf_cpu c;
 
 	m = perf_cpu_map__new(s);
 	if (!m)
@@ -736,12 +736,12 @@ static int str_to_bitmap(char *s, cpumask_t *b, int nr_cpus)
 
 	for (i = 0; i < m->nr; i++) {
 		c = m->map[i];
-		if (c >= nr_cpus) {
+		if (c.cpu >= nr_cpus) {
 			ret = -1;
 			break;
 		}
 
-		set_bit(c, cpumask_bits(b));
+		set_bit(c.cpu, cpumask_bits(b));
 	}
 
 	perf_cpu_map__put(m);
diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c
index 198982109f0f..c9ba8050cc2b 100644
--- a/tools/perf/util/synthetic-events.c
+++ b/tools/perf/util/synthetic-events.c
@@ -1191,7 +1191,7 @@ static void synthesize_cpus(struct cpu_map_entries *cpus,
 	cpus->nr = map->nr;
 
 	for (i = 0; i < map->nr; i++)
-		cpus->cpu[i] = map->map[i];
+		cpus->cpu[i] = map->map[i].cpu;
 }
 
 static void synthesize_mask(struct perf_record_record_cpu_map *mask,
@@ -1203,7 +1203,7 @@ static void synthesize_mask(struct perf_record_record_cpu_map *mask,
 	mask->long_size = sizeof(long);
 
 	for (i = 0; i < map->nr; i++)
-		set_bit(map->map[i], mask->mask);
+		set_bit(map->map[i].cpu, mask->mask);
 }
 
 static size_t cpus_size(struct perf_cpu_map *map)
@@ -1219,7 +1219,7 @@ static size_t mask_size(struct perf_cpu_map *map, int *max)
 
 	for (i = 0; i < map->nr; i++) {
 		/* bit position of the cpu is + 1 */
-		int bit = map->map[i] + 1;
+		int bit = map->map[i].cpu + 1;
 
 		if (bit > *max)
 			*max = bit;
@@ -1354,7 +1354,7 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,
 }
 
 int perf_event__synthesize_stat(struct perf_tool *tool,
-				u32 cpu, u32 thread, u64 id,
+				struct perf_cpu cpu, u32 thread, u64 id,
 				struct perf_counts_values *count,
 				perf_event__handler_t process,
 				struct machine *machine)
@@ -1366,7 +1366,7 @@ int perf_event__synthesize_stat(struct perf_tool *tool,
 	event.header.misc = 0;
 
 	event.id        = id;
-	event.cpu       = cpu;
+	event.cpu       = cpu.cpu;
 	event.thread    = thread;
 	event.val       = count->val;
 	event.ena       = count->ena;
@@ -1763,7 +1763,7 @@ int perf_event__synthesize_id_index(struct perf_tool *tool, perf_event__handler_
 			}
 
 			e->idx = sid->idx;
-			e->cpu = sid->cpu;
+			e->cpu = sid->cpu.cpu;
 			e->tid = sid->tid;
 		}
 	}
diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h
index c931433bacbf..78a0450db164 100644
--- a/tools/perf/util/synthetic-events.h
+++ b/tools/perf/util/synthetic-events.h
@@ -6,6 +6,7 @@
 #include <sys/types.h> // pid_t
 #include <linux/compiler.h>
 #include <linux/types.h>
+#include <perf/cpumap.h>
 
 struct auxtrace_record;
 struct dso;
@@ -63,7 +64,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, u64 read_fo
 int perf_event__synthesize_stat_config(struct perf_tool *tool, struct perf_stat_config *config, perf_event__handler_t process, struct machine *machine);
 int perf_event__synthesize_stat_events(struct perf_stat_config *config, struct perf_tool *tool, struct evlist *evlist, perf_event__handler_t process, bool attrs);
 int perf_event__synthesize_stat_round(struct perf_tool *tool, u64 time, u64 type, perf_event__handler_t process, struct machine *machine);
-int perf_event__synthesize_stat(struct perf_tool *tool, u32 cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine);
+int perf_event__synthesize_stat(struct perf_tool *tool, struct perf_cpu cpu, u32 thread, u64 id, struct perf_counts_values *count, perf_event__handler_t process, struct machine *machine);
 int perf_event__synthesize_thread_map2(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine);
 int perf_event__synthesize_thread_map(struct perf_tool *tool, struct perf_thread_map *threads, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data);
 int perf_event__synthesize_threads(struct perf_tool *tool, perf_event__handler_t process, struct machine *machine, bool needs_mmap, bool mmap_data, unsigned int nr_threads_synthesize);
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 9f0d36ba77f2..9443c29afa52 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -11,6 +11,9 @@
 #include <stddef.h>
 #include <linux/compiler.h>
 #include <sys/types.h>
+#ifndef __cplusplus
+#include <internal/cpumap.h>
+#endif
 
 /* General helper functions */
 void usage(const char *err) __noreturn;
@@ -66,6 +69,6 @@ extern bool test_attr__enabled;
 void test_attr__ready(void);
 void test_attr__init(void);
 struct perf_event_attr;
-void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
+void test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu,
 		     int fd, int group_fd, unsigned long flags);
 #endif /* GIT_COMPAT_UTIL_H */
-- 
2.34.1.448.ga2b2bfdf31-goog



From p.yadav at ti.com  Tue Jan  4 22:32:46 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Wed, 5 Jan 2022 12:02:46 +0530
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <YdSP6tKyQ2ZRUC+2@heinlein>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com>
 <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com>
 <20220103171721.46c8e697@xps13> <YdSP6tKyQ2ZRUC+2@heinlein>
Message-ID: <20220105063244.lno3xur64uepa7i5@ti.com>

On 04/01/22 12:20PM, Patrick Williams wrote:
> Hi Miquel,
> 
> On Mon, Jan 03, 2022 at 05:17:21PM +0100, Miquel Raynal wrote:
> 
> > > I am fine with taking in bug fixes but no longer want to take in any new 
> > > features. My main intention was to nudge you to convert it to SPI MEM 
> > > regardless of whether this is a bug fix or a new feature, because 
> > > eventually we want to get rid of drivers/mtd/spi-nor/controllers/ and 
> > > the API that comes along with it.
> > 
> > I totally agree with Pratyush here, we no longer want to support the
> > spi-nor controller API so if, as you say, there are boards failing
> > in the field, it means there are still users and these users must be
> > warned that at some point we might discontinue the support of these
> > drivers if it becomes too painful.
> >
> 
> Your response here makes it seem like you don't realize the scope of this
> driver.  There are probably, by my estimates, on the order of 10s of millions of
> deployed systems using this driver in the world.  The vast majority of servers
> in the world use an AST2400, AST2500, or AST2600 chip, which needs this driver
> in order access its own flash storage device.  Both OpenBMC and most of the
> proprietary alternatives use this driver.

Then we should easily be able to find people willing to spend a couple 
days on updating the driver :-)

> 
> The company I work for has a LOT of systems using this code.  After I made this
> fix, for a new design being developed, it was pointed out to me that our ODM ran
> into this problem a few years ago and we've been really bad about upstreaming
> those fixes.  For this new system I'm trying to keep us on top of all
> upstreaming efforts.

If a company wants to use an upstream kernel for their systems I think 
they should invest into maintaining the drivers they are using.

> 
> To me the inability to access your own storage, resulting in a kernel panic, is
> a pretty serious issue.  Bug or feature I guess is always in the eye of the

One option you always have is to disable the bad flash in your device 
tree. I don't see why you would want to keep a flash that does not work 
enabled anyway.

> beholder though.  I think this is pretty valuable to get in, from an impact
> standpoint, and pretty minimal in terms of maintenance efforts on the
> maintainers part.

Yes, I agree that your patch itself has fairly low maintenance burden. I 
would not be too opposed to taking it in. But for the driver as a whole, 
that is indeed a maintenance burden since we have to carry code in SPI 
NOR to support it which makes adding new features a bit tricky.

We had a discussion along these lines for old unmaintained flashes in 
SPI NOR. The idea then was to warn the people who touched code related 
to those flashes that they can either update it or we will drop the 
flashes after X releases. They would still work on older kernels of 
course, but if there are any upstream users they would have to update 
the code or live without the flashes.

I would like to use the same approach for the controllers API as well. 
We can't keep carrying around legacy code forever just because a 
device/driver has no active developers. If people want to use some 
driver in the upstream kernel, they should help maintain it.

> 
> I had an offline discussion with someone who knew more history on this driver.
> My understanding is that the linux-aspeed team is aware of this being deprecated
> but that there was some missing support for interface training that nobody has
> gotten around to write?  If that is the case this really isn't even a "simple"
> port to a new API at this point.

Unless the controller needs some unique feature (I don't think it does 
on a quick glance), the conversion should not be too difficult. For any 
experienced developer, even if they are unfamiliar with the SPI MEM API, 
I don't think it should take more than 2-3 days to do the conversion. 
The code to program the registers would stay the same, all that needs to 
change is the API through which it is accessed.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From guangming.cao at mediatek.com  Tue Jan  4 22:36:43 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Wed, 5 Jan 2022 14:36:43 +0800
Subject: [PATCH v2] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>
References: <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>
Message-ID: <20220105063643.119874-1-guangming.cao@mediatek.com>

From: Guangming.Cao <guangming.cao at mediatek.com>

On Tue, 2022-01-04 at 08:47 +0100, Christian K?ig wrote:
> Am 03.01.22 um 19:57 schrieb John Stultz:
> > On Mon, Dec 27, 2021 at 1:52 AM <guangming.cao at mediatek.com> wrote:
> > > From: Guangming <Guangming.Cao at mediatek.com>
> > > 
> > 
> > Thanks for submitting this!
> > 
> > > Add a size check for allcation since the allocation size is
> > 
> > nit: "allocation" above.
> > 
> > > always less than the total DRAM size.
> > 
> > In general, it might be good to add more context to the commit
> > message
> > to better answer *why* this change is needed rather than what the
> > change is doing.  ie: What negative thing happens without this
> > change?
> > And so how does this change avoid or improve things?
> 
> Completely agree, just one little addition: Could you also add this
> why 
> as comment to the code?
> 
> When we stumble over this five years from now it is absolutely not 
> obvious why we do this.
> 
> Thanks,
> Christian.
> 
Thanks for your reply!
I will update the related reason in the patch later.

The reason for adding this check is that we met a case that the user
sent an invalid size(It seems it's a negative value, MSB is 0xff, it's
larger than DRAM size after convert it to size_t) to dma-heap to alloc
memory, and this allocation was running on a process(such as "gralloc"
on Android device) can't be killed by OOM flow, and we also couldn't
find the related dmabuf in "dma_buf_debug_show" because the related
dmabuf was not exported yet since the allocation is still on going.

Since this invalid argument case can be prevented at dma-heap side, so,
I added this size check, and moreover, to let debug it easily, I also
added logs when size is bigger than a threshold we set in mtk system
heap.
If you think that print logs in dma-heap framework is better, I will
update it in next version.

If you have better solution(such as dump the size under allocating
in "dma_buf_debug_show", which maybe need add global variable to record
it), please kindly let me know.
Thanks :)
Guangming

> > 
> > 
> > > Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> > > Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
> > > ---
> > > v2: 1. update size limitation as total_dram page size.
> > >      2. update commit message
> > > ---
> > >   drivers/dma-buf/dma-heap.c | 2 ++
> > >   1 file changed, 2 insertions(+)
> > > 
> > > diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-
> > > heap.c
> > > index 56bf5ad01ad5..e39d2be98d69 100644
> > > --- a/drivers/dma-buf/dma-heap.c
> > > +++ b/drivers/dma-buf/dma-heap.c
> > > @@ -55,6 +55,8 @@ static int dma_heap_buffer_alloc(struct
> > > dma_heap *heap, size_t len,
> > >          struct dma_buf *dmabuf;
> > >          int fd;
> > > 
> > > +       if (len / PAGE_SIZE > totalram_pages())
> > > +               return -EINVAL;
> > 
> > This seems sane. I know ION used to have some 1/2 of memory cap to
> > avoid unnecessary memory pressure on crazy allocations.
> > 
> > Could you send again with an improved commit message?
> > 
> > thanks
> > -john
> 
> 


From ck.hu at mediatek.com  Tue Jan  4 22:52:03 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Wed, 5 Jan 2022 14:52:03 +0800
Subject: [RFC PATCH 0/2] drm/mediatek/hdmi : split legacy driver and add
 mt8195
In-Reply-To: <CABnWg9ubi4Lr1jEh8TRGdLEDJE9raKSizhnEo08xf2vXYnA+aA@mail.gmail.com>
References: <20211108000847.14320-1-granquet@baylibre.com>
 <CABnWg9ubi4Lr1jEh8TRGdLEDJE9raKSizhnEo08xf2vXYnA+aA@mail.gmail.com>
Message-ID: <7463ce81cbce0a2d2a04a63ca9975356d261e519.camel@mediatek.com>

Hi, Guillaume:

On Thu, 2021-12-02 at 07:44 -0800, Guillaume Ranquet wrote:
> Hi Chun-Kuang,
> Quoting Guillaume Ranquet (2021-11-08 01:08:45)
> > 
> > Following the review of "[v1,4/4] drm/mediatek: add mt8195 hdmi TX
> > support" [1] , I've been asked to try to merge the "legacy
> > HDMI driver with the "new" mt8195 HDMI driver. Though the registers
> > and IPs are rather different, I've made an attempt at the
> > excercise on which I would like some comments before submitting a
> > new version of the patchset.
> > 
> > I've created a new mtk_hdmi_common.{c,h} which contains what I
> > could identify as common enough to be added in there.
> > I have not renamed the mtk_hdmi.{c,h} driver to something else yet.
> > I've then added mtk8195 hdmi driver on top of this work.
> > 
> > The code is still rather sketchy and I have some questions on best
> > practices for that kind of exercices?
> > In no particular order, here's a bunch of random questions:
> > 
> > 1 would you rather have:
> > - as presented here: a boolean with a bunch of if/else in the
> > common code to handle the discrepencies between the two drivers
> > - function pointers, with an "ops" structure set in the drvdata...
> > though the ops are a bit random and wouldn't really
> > make sense to be grouped together?

Both is OK, but I think if some difference is small, use if/else is
much simple. If the difference is large, use function pointers is
better.

> > 
> > 2 I'm not really happy with how the mt8195 driver and ddc are
> > sharing the same __iomem regs and not sure how to exactly
> > handle this now that both hdmi drivers are tied together... it was
> > hackish from the begining, but now I'm a bit out of
> > solutions to handle this peculiar "feature" of the mt8195 hdmi/ddc
> > driver. any hints would be appreciated.

Is the case the same as phy-mtk-dp with mtk display port driver? If
it's this case, mt8195 hdmi driver would use regmap_read/write() and
mt8173 hdmi would use readl/writel() and you could use if/else or
function pointer to distinguish both SoC. Or you worry about other
thing?

> > 
> > 3 Should the "legacy" and mt8195 drivers be under the same menu
> > entry?

Let's call "legacy" mt8173. If you really want config for mt8195 hdmi
driver, yes, it should be under the same menu. But also have a config
for mt8173 hdmi driver.

> > 
> > 4 I'm looking into the clock framework and I'm wondering if there
> > would be benefits to switch to the "bulk" interface? as
> > both driver seem to request them all once and for all? the code
> > might end up easier to read.

DRM framework has bulk of helper function, and it's not easy to read
the DRM framework. These helper functions are help to reduce the
duplicated code. I think the limitation of readability is: I could
understand the code. Based on the limitation, let's try to reduce
duplicated code.

> > 
> > 5 Would it be beneficial to further split the driver with audio on
> > one side and video on the other? from what I understood,
> > the main complaint was that the driver was too big to review...
> > that could help with that at least?

It's better that you could break this patch into smaller patches. But
be sure that each patch is workable. For example, if apply video patch
first, HDMI could work without audio.

> > 
> > 
> > Thx for your patience... any further comment is welcome.

I would review the RFC patch later.

Regards,
CK

> > 
> > Thx,
> > Guillaume.
> > 
> > [1] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210929094425.745-5-granquet at baylibre.com/__;!!CTRNKA9wMg0ARbw!0NxH5ig8YRgHlPWYZxLV17O_pVKkKxQK6Mimo0r89xiEmOyTWx-DUEliMqFScg$
> >  
> > 
> > --
> > Guillaume Ranquet (2):
> >   drm/mediatek: extract common functions from the mtk hdmi driver
> >   drm/mediatek: add mtk8195 hdmi display driver
> > 
> >  drivers/gpu/drm/mediatek/Kconfig              |   10 +
> >  drivers/gpu/drm/mediatek/Makefile             |    5 +-
> >  drivers/gpu/drm/mediatek/mtk_hdmi.c           |  635 +-----
> >  drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  521 +++++
> >  drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |  258 +++
> >  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c    | 1835
> > +++++++++++++++++
> >  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h    |   26 +
> >  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c    |  530 +++++
> >  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h    |   20 +
> >  .../gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h   |  329 +++
> >  10 files changed, 3560 insertions(+), 609 deletions(-)
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h
> >  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h
> > 
> > --
> > 2.32.0
> > 
> 
> Since you have requested that I merge both drivers, could you give me
> your feedback on this RFC so
> that I know how to move forward? I'm planning on making a v2 soon
> based on this RFC (and hopefully its
> outcome).
> 
> Thx,
> Guillaume.
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> 
https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!0NxH5ig8YRgHlPWYZxLV17O_pVKkKxQK6Mimo0r89xiEmOyTWx-DUEkrO9clHw$
>  



From ilkka at os.amperecomputing.com  Tue Jan  4 23:05:11 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Tue, 4 Jan 2022 23:05:11 -0800 (PST)
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <CAJZ5v0g7OeQ=pa-7j+5NDMjbAsr89FUg09u0i2k98uJWf_GgTg@mail.gmail.com>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <CAJZ5v0g7OeQ=pa-7j+5NDMjbAsr89FUg09u0i2k98uJWf_GgTg@mail.gmail.com>
Message-ID: <alpine.DEB.2.22.394.2201042253340.2515@ubuntu200401>


Hi Rafael,

On Tue, 4 Jan 2022, Rafael J. Wysocki wrote:
> On Fri, Dec 31, 2021 at 4:37 AM Ilkka Koskinen
> <ilkka at os.amperecomputing.com> wrote:
>>
>> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
>> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
>> issue diagnostic dump and reset via an SDEI event or an interrupt.
>> This patch implements SDEI path.
>>
>> [0] https://developer.arm.com/documentation/den0093/latest/
>>
>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>
> This requires an ACK from the arm64 side if you want me to take it.

That's my understanding too.

> However, I can apply patch 1 from this series if that helps.

I'm not sure, if it makes sense to pick the first patch now since there 
aren't other users for it. I'd probably keep them together although I 
don't have strong feelings about it.

Cheers, Ilkka

>
>> ---
>>  drivers/acpi/arm64/Kconfig  |   8 +++
>>  drivers/acpi/arm64/Makefile |   1 +
>>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 134 insertions(+)
>>  create mode 100644 drivers/acpi/arm64/agdi.c
>>
>> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
>> index 6dba187f4f2e..24869ba5b365 100644
>> --- a/drivers/acpi/arm64/Kconfig
>> +++ b/drivers/acpi/arm64/Kconfig
>> @@ -8,3 +8,11 @@ config ACPI_IORT
>>
>>  config ACPI_GTDT
>>         bool
>> +
>> +config ACPI_AGDI
>> +       bool "Arm Generic Diagnostic Dump and Reset Device Interface"
>> +       depends on ARM_SDE_INTERFACE
>> +       help
>> +         Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
>> +         a standard that enables issuing a non-maskable diagnostic dump and
>> +         reset command.
>> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
>> index 66acbe77f46e..7b9e4045659d 100644
>> --- a/drivers/acpi/arm64/Makefile
>> +++ b/drivers/acpi/arm64/Makefile
>> @@ -1,4 +1,5 @@
>>  # SPDX-License-Identifier: GPL-2.0-only
>> +obj-$(CONFIG_ACPI_AGDI)        += agdi.o
>>  obj-$(CONFIG_ACPI_IORT)        += iort.o
>>  obj-$(CONFIG_ACPI_GTDT)        += gtdt.o
>>  obj-y                          += dma.o
>> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
>> new file mode 100644
>> index 000000000000..6525ccbae5c1
>> --- /dev/null
>> +++ b/drivers/acpi/arm64/agdi.c
>> @@ -0,0 +1,125 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * This file implements handling of
>> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
>> + *
>> + * Copyright (c) 2021, Ampere Computing LLC
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/acpi.h>
>> +#include <linux/arm_sdei.h>
>> +#include <linux/io.h>
>> +
>> +struct agdi_data {
>> +       int sdei_event;
>> +};
>> +
>> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
>> +{
>> +       nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
>> +       return 0;
>> +}
>> +
>> +static int agdi_sdei_probe(struct platform_device *pdev,
>> +                          struct agdi_data *adata)
>> +{
>> +       int err;
>> +
>> +       err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
>> +       if (err) {
>> +               dev_err(&pdev->dev, "Failed to register for SDEI event %d",
>> +                       adata->sdei_event);
>> +               return err;
>> +       }
>> +
>> +       err = sdei_event_enable(adata->sdei_event);
>> +       if (err)  {
>> +               sdei_event_unregister(adata->sdei_event);
>> +               dev_err(&pdev->dev, "Failed to enable event %d\n",
>> +                       adata->sdei_event);
>> +               return err;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static int agdi_probe(struct platform_device *pdev)
>> +{
>> +       struct agdi_data *adata;
>> +
>> +       adata = dev_get_platdata(&pdev->dev);
>> +       if (!adata)
>> +               return -EINVAL;
>> +
>> +       return agdi_sdei_probe(pdev, adata);
>> +}
>> +
>> +static int agdi_remove(struct platform_device *pdev)
>> +{
>> +       struct agdi_data *adata = platform_get_drvdata(pdev);
>> +
>> +       sdei_event_disable(adata->sdei_event);
>> +       sdei_event_unregister(adata->sdei_event);
>> +
>> +       return 0;
>> +}
>> +
>> +static struct platform_driver agdi_driver = {
>> +       .driver = {
>> +               .name = "agdi",
>> +       },
>> +       .probe = agdi_probe,
>> +       .remove = agdi_remove,
>> +};
>> +
>> +static int __init agdi_init(void)
>> +{
>> +       int ret;
>> +       acpi_status status;
>> +       struct acpi_table_agdi *agdi_table;
>> +       struct agdi_data pdata;
>> +       struct platform_device *pdev;
>> +
>> +       if (acpi_disabled)
>> +               return 0;
>> +
>> +       status = acpi_get_table(ACPI_SIG_AGDI, 0,
>> +                               (struct acpi_table_header **) &agdi_table);
>> +       if (ACPI_FAILURE(status))
>> +               return -ENODEV;
>> +
>> +       if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
>> +               pr_warn("Interrupt signaling is not supported");
>> +               ret = -ENODEV;
>> +               goto err_put_table;
>> +       }
>> +
>> +       pdata.sdei_event = agdi_table->sdei_event;
>> +
>> +       pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
>> +       if (IS_ERR(pdev)) {
>> +               ret = PTR_ERR(pdev);
>> +               goto err_put_table;
>> +       }
>> +
>> +       ret = platform_driver_register(&agdi_driver);
>> +       if (ret)
>> +               goto err_device_unregister;
>> +
>> +       acpi_put_table((struct acpi_table_header *)agdi_table);
>> +       return 0;
>> +
>> +err_device_unregister:
>> +       platform_device_unregister(pdev);
>> +err_put_table:
>> +       acpi_put_table((struct acpi_table_header *)agdi_table);
>> +       return ret;
>> +}
>> +device_initcall(agdi_init);
>> --
>> 2.17.1
>>
>


From ilkka at os.amperecomputing.com  Tue Jan  4 23:10:23 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Tue, 4 Jan 2022 23:10:23 -0800 (PST)
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <f0fecf95-0b7d-eeec-94fd-76bea61fdd0f@huawei.com>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <f0fecf95-0b7d-eeec-94fd-76bea61fdd0f@huawei.com>
Message-ID: <alpine.DEB.2.22.394.2201042306090.2515@ubuntu200401>


Hi Hanjun,

On Wed, 5 Jan 2022, Hanjun Guo wrote:
> Hi Ilkka,
>
> On 2021/12/31 11:37, Ilkka Koskinen wrote:
>> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
>> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
>> issue diagnostic dump and reset via an SDEI event or an interrupt.
>> This patch implements SDEI path.
>> 
>> [0] https://developer.arm.com/documentation/den0093/latest/
>> 
>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>> ---
>>   drivers/acpi/arm64/Kconfig  |   8 +++
>>   drivers/acpi/arm64/Makefile |   1 +
>>   drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>>   3 files changed, 134 insertions(+)
>>   create mode 100644 drivers/acpi/arm64/agdi.c
>> 
>> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
>> index 6dba187f4f2e..24869ba5b365 100644
>> --- a/drivers/acpi/arm64/Kconfig
>> +++ b/drivers/acpi/arm64/Kconfig
>> @@ -8,3 +8,11 @@ config ACPI_IORT
>>     config ACPI_GTDT
>>   	bool
>> +
>> +config ACPI_AGDI
>> +	bool "Arm Generic Diagnostic Dump and Reset Device Interface"
>> +	depends on ARM_SDE_INTERFACE
>> +	help
>> +	  Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
>> +	  a standard that enables issuing a non-maskable diagnostic dump and
>> +	  reset command.
>> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
>> index 66acbe77f46e..7b9e4045659d 100644
>> --- a/drivers/acpi/arm64/Makefile
>> +++ b/drivers/acpi/arm64/Makefile
>> @@ -1,4 +1,5 @@
>>   # SPDX-License-Identifier: GPL-2.0-only
>> +obj-$(CONFIG_ACPI_AGDI) 	+= agdi.o
>>   obj-$(CONFIG_ACPI_IORT) 	+= iort.o
>>   obj-$(CONFIG_ACPI_GTDT) 	+= gtdt.o
>>   obj-y				+= dma.o
>> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
>> new file mode 100644
>> index 000000000000..6525ccbae5c1
>> --- /dev/null
>> +++ b/drivers/acpi/arm64/agdi.c
>> @@ -0,0 +1,125 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * This file implements handling of
>> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
>> + *
>> + * Copyright (c) 2021, Ampere Computing LLC
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/acpi.h>
>> +#include <linux/arm_sdei.h>
>> +#include <linux/io.h>
>
> Please keep the head files in alphabetical order.

I'll fix the include lines

>
>> +
>> +struct agdi_data {
>> +	int sdei_event;
>> +};
>> +
>> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void 
>> *arg)
>> +{
>> +	nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event 
>> issued");
>> +	return 0;
>> +}
>> +
>> +static int agdi_sdei_probe(struct platform_device *pdev,
>> +			   struct agdi_data *adata)
>> +{
>> +	int err;
>> +
>> +	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, 
>> pdev);
>> +	if (err) {
>> +		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
>> +			adata->sdei_event);
>> +		return err;
>> +	}
>> +
>> +	err = sdei_event_enable(adata->sdei_event);
>> +	if (err)  {
>> +		sdei_event_unregister(adata->sdei_event);
>> +		dev_err(&pdev->dev, "Failed to enable event %d\n",
>> +			adata->sdei_event);
>> +		return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int agdi_probe(struct platform_device *pdev)
>> +{
>> +	struct agdi_data *adata;
>> +
>> +	adata = dev_get_platdata(&pdev->dev);
>> +	if (!adata)
>> +		return -EINVAL;
>> +
>> +	return agdi_sdei_probe(pdev, adata);
>> +}
>> +
>> +static int agdi_remove(struct platform_device *pdev)
>> +{
>> +	struct agdi_data *adata = platform_get_drvdata(pdev);
>> +
>> +	sdei_event_disable(adata->sdei_event);
>> +	sdei_event_unregister(adata->sdei_event);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver agdi_driver = {
>> +	.driver = {
>> +		.name = "agdi",
>> +	},
>> +	.probe = agdi_probe,
>> +	.remove = agdi_remove,
>> +};
>> +
>> +static int __init agdi_init(void)
>> +{
>> +	int ret;
>> +	acpi_status status;
>> +	struct acpi_table_agdi *agdi_table;
>> +	struct agdi_data pdata;
>> +	struct platform_device *pdev;
>> +
>> +	if (acpi_disabled)
>> +		return 0;
>> +
>> +	status = acpi_get_table(ACPI_SIG_AGDI, 0,
>> +				(struct acpi_table_header **) &agdi_table);
>> +	if (ACPI_FAILURE(status))
>> +		return -ENODEV;
>> +
>> +	if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
>> +		pr_warn("Interrupt signaling is not supported");
>> +		ret = -ENODEV;
>> +		goto err_put_table;
>> +	}
>> +
>> +	pdata.sdei_event = agdi_table->sdei_event;
>> +
>> +	pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, 
>> sizeof(pdata));
>> +	if (IS_ERR(pdev)) {
>> +		ret = PTR_ERR(pdev);
>> +		goto err_put_table;
>> +	}
>> +
>> +	ret = platform_driver_register(&agdi_driver);
>> +	if (ret)
>> +		goto err_device_unregister;
>> +
>> +	acpi_put_table((struct acpi_table_header *)agdi_table);
>> +	return 0;
>> +
>> +err_device_unregister:
>> +	platform_device_unregister(pdev);
>> +err_put_table:
>> +	acpi_put_table((struct acpi_table_header *)agdi_table);
>> +	return ret;
>> +}
>> +device_initcall(agdi_init);
>
> The rest are looking good to me.

I'm glad to hear that

> Thanks
> Hanjun
>

Cheers, Ilkka


From stevensd at chromium.org  Tue Jan  4 23:14:39 2022
From: stevensd at chromium.org (David Stevens)
Date: Wed, 5 Jan 2022 16:14:39 +0900
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <Yc4G23rrSxS59br5@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
Message-ID: <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>

On Fri, Dec 31, 2021 at 4:22 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Mon, Nov 29, 2021, David Stevens wrote:
> > From: David Stevens <stevensd at chromium.org>
> >
> > Remove two warnings that require ref counts for pages to be non-zero, as
> > mapped pfns from follow_pfn may not have an initialized ref count.
> >
> > Signed-off-by: David Stevens <stevensd at chromium.org>
> > ---
> >  arch/x86/kvm/mmu/mmu.c | 7 -------
> >  virt/kvm/kvm_main.c    | 2 +-
> >  2 files changed, 1 insertion(+), 8 deletions(-)
> >
> > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
> > index 0626395ff1d9..7c4c7fededf0 100644
> > --- a/arch/x86/kvm/mmu/mmu.c
> > +++ b/arch/x86/kvm/mmu/mmu.c
> > @@ -621,13 +621,6 @@ static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep)
> >
> >       pfn = spte_to_pfn(old_spte);
> >
> > -     /*
> > -      * KVM does not hold the refcount of the page used by
> > -      * kvm mmu, before reclaiming the page, we should
> > -      * unmap it from mmu first.
> > -      */
> > -     WARN_ON(!kvm_is_reserved_pfn(pfn) && !page_count(pfn_to_page(pfn)));
> > -
> >       if (is_accessed_spte(old_spte))
> >               kvm_set_pfn_accessed(pfn);
> >
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 16a8a71f20bf..d81edcb3e107 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -170,7 +170,7 @@ bool kvm_is_zone_device_pfn(kvm_pfn_t pfn)
> >        * the device has been pinned, e.g. by get_user_pages().  WARN if the
> >        * page_count() is zero to help detect bad usage of this helper.
>
> Stale comment.
>
> >        */
> > -     if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
> > +     if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
>
> Hrm, I know the whole point of this series is to support pages without an elevated
> refcount, but this WARN was extremely helpful in catching several use-after-free
> bugs in the TDP MMU.  We talked about burying a slow check behind MMU_WARN_ON, but
> that isn't very helpful because no one runs with MMU_WARN_ON, and this is also a
> type of check that's most useful if it runs in production.
>
> IIUC, this series explicitly disallows using pfns that have a struct page without
> refcounting, and the issue with the WARN here is that kvm_is_zone_device_pfn() is
> called by kvm_is_reserved_pfn() before ensure_pfn_ref() rejects problematic pages,
> i.e. triggers false positive.
>
> So, can't we preserve the use-after-free benefits of the check by moving it to
> where KVM releases the PFN?  I.e.
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index fbca2e232e94..675b835525fa 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -2904,15 +2904,19 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
>
>  void kvm_set_pfn_dirty(kvm_pfn_t pfn)
>  {
> -       if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
> +       if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
> +               WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
>                 SetPageDirty(pfn_to_page(pfn));
> +       }
>  }
>  EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);

I'm still seeing this warning show up via __handle_changed_spte
calling kvm_set_pfn_dirty:

[  113.350473]  kvm_set_pfn_dirty+0x26/0x3e
[  113.354861]  __handle_changed_spte+0x452/0x4f6
[  113.359841]  __handle_changed_spte+0x452/0x4f6
[  113.364819]  __handle_changed_spte+0x452/0x4f6
[  113.369790]  zap_gfn_range+0x1de/0x27a
[  113.373992]  kvm_tdp_mmu_zap_invalidated_roots+0x64/0xb8
[  113.379945]  kvm_mmu_zap_all_fast+0x18c/0x1c1
[  113.384827]  kvm_page_track_flush_slot+0x55/0x87
[  113.390000]  kvm_set_memslot+0x137/0x455
[  113.394394]  kvm_delete_memslot+0x5c/0x91
[  113.398888]  __kvm_set_memory_region+0x3c0/0x5e6
[  113.404061]  kvm_set_memory_region+0x45/0x74
[  113.408844]  kvm_vm_ioctl+0x563/0x60c

I wasn't seeing it for my particular test case, but the gfn aging code
might trigger the warning as well.

I don't know if setting the dirty/accessed bits in non-refcounted
struct pages is problematic. The only way I can see to avoid it would
be to try to map from the spte to the vma and then check its flags. If
setting the flags is benign, then we'd need to do that lookup to
differentiate the safe case from the use-after-free case. Do you have
any advice on how to handle this?

-David


From jiasheng at iscas.ac.cn  Tue Jan  4 23:47:29 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Wed,  5 Jan 2022 15:47:29 +0800
Subject: [PATCH] drm/imx: imx-ldb: Check for null pointer after calling kmemdup
Message-ID: <20220105074729.2363657-1-jiasheng@iscas.ac.cn>

As the possible failure of the allocation, kmemdup() may return NULL
pointer.
Therefore, it should be better to check the return value of kmemdup()
and return error if fails.

Fixes: dc80d7038883 ("drm/imx-ldb: Add support to drm-bridge")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
 drivers/gpu/drm/imx/imx-ldb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 53132ddf9587..f9880a779678 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -574,6 +574,8 @@ static int imx_ldb_panel_ddc(struct device *dev,
 		edidp = of_get_property(child, "edid", &edid_len);
 		if (edidp) {
 			channel->edid = kmemdup(edidp, edid_len, GFP_KERNEL);
+			if (!channel->edid)
+				return -ENOMEM;
 		} else if (!channel->panel) {
 			/* fallback to display-timings node */
 			ret = of_get_drm_display_mode(child,
-- 
2.25.1



From quic_schowdhu at quicinc.com  Tue Jan  4 23:54:55 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Wed, 5 Jan 2022 13:24:55 +0530
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data Capture
 and Compare unit(DCC)
In-Reply-To: <20211214172529.GA27563@thinkpad>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <20211214172529.GA27563@thinkpad>
Message-ID: <40976c37-2eda-c586-d465-5babb2a14e4d@quicinc.com>


On 12/14/2021 10:55 PM, Manivannan Sadhasivam wrote:
> On Tue, Aug 10, 2021 at 11:24:38PM +0530, Souradeep Chowdhury wrote:
>> The DCC is a DMA Engine designed to capture and store data
>> during system crash or software triggers.The DCC operates
>> based on user inputs via the sysfs interface.The user gives
>> addresses as inputs and these addresses are stored in the
>> form of linkedlists.
> The linked lists are present in the hardware, right? You should state it
> explicitly.
Ack
>
>> In case of a system crash or a manual
> So what does a crash here means? How does DCC detect it?

In case of a system crashes like kernel panic , the dcc hardware gets 
activated

automatically and dumps the register values.Nothing needs to be done from

software side for that.

>
>> software trigger by the user through the sysfs interface,
>> the dcc captures and stores the values at these addresses.
> This could be reworded a bit:
>
> "DCC captures and stores the current values of the provided addresses in SRAM"
Ack
>
>> This patch contains the driver which has all the methods
>> pertaining to the sysfs interface, auxiliary functions to
>> support all the four fundamental operations of dcc namely
>> read, write, first read then write and loop.The probe method
>> here instantiates all the resources necessary for dcc to
>> operate mainly the dedicated dcc sram where it stores the
> Please use "DCC" everywhere.

Ack

>
>> values.The DCC driver can be used for debugging purposes
>> without going for a reboot since it can perform manual
>> triggers.
>>
> It allows users to perform software triggers for capturing values manually.
Ack
>
>> Also added the documentation for sysfs entries
>> and explained the functionalities of each sysfs file that
>> has been created for dcc.
>>
>> The following is the justification of using sysfs interface
>> over the other alternatives like ioctls
>>
>> i) As can be seen from the sysfs attribute descriptions,
>> most of it does basic hardware manipulations like dcc_enable,
>> dcc_disable, config reset etc. As a result sysfs is preferred
>> over ioctl as we just need to enter a 0 or 1.
>>
> This is not an apt reason to use sysfs. The one-value-per-file is a rule of
> sysfs not a criteria to use it.
Ack. Will be updating the justifications accordingly.
>
>> ii) Existing similar debug hardwares are there for which drivers
>> have been written using sysfs interface.One such example is the
>> coresight-etm-trace driver.A closer analog can also be the watchdog
>> subsystems though it is ioctls based.
>>
> Initially I thought that this driver could use debugfs interface, but going
> through it I feel that sysfs is more suited. Reason is, debugfs interface is
> used by drivers to expose debugging information additional to the function they
> do. But the sole usage of this driver depends on the configuration exported
> through the attributes and they looks to be an ABI to me.
Ack
>
>> Signed-off-by: Souradeep Chowdhury <schowdhu at codeaurora.org>
>> ---
>>   Documentation/ABI/testing/sysfs-driver-dcc |  114 ++
>>   drivers/soc/qcom/Kconfig                   |    8 +
>>   drivers/soc/qcom/Makefile                  |    1 +
>>   drivers/soc/qcom/dcc.c                     | 1549 ++++++++++++++++++++++++++++
>>   4 files changed, 1672 insertions(+)
>>   create mode 100644 Documentation/ABI/testing/sysfs-driver-dcc
>>   create mode 100644 drivers/soc/qcom/dcc.c
>>
>> diff --git a/Documentation/ABI/testing/sysfs-driver-dcc b/Documentation/ABI/testing/sysfs-driver-dcc
>> new file mode 100644
>> index 0000000..05d24f0
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-driver-dcc
>> @@ -0,0 +1,114 @@
>> +What:           /sys/bus/platform/devices/.../trigger
>> +Date:           March 2021
> Please fix the dates of all attributes.
Ack
>
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This is the sysfs interface for manual software
> All entries should be aligned properly.
Ack
>
>> +		triggers.The user can simply enter a 1 against
>> +		the sysfs file and enable a manual trigger.
>> +		Example:
>> +		echo  1 > /sys/bus/platform/devices/.../trigger
> Why 2 spaces after echo?
Ack
>
>> +
>> +What:           /sys/bus/platform/devices/.../enable
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This sysfs interface is used for enabling the
>> +		the dcc hardware.Without this being set to 1,
> DCC here also. And a space after "." everywhere.
Ack
>
>> +		the dcc hardware ceases to function.
>> +		Example:
>> +		echo  0 > /sys/bus/platform/devices/.../enable
>> +		(disable interface)
>> +		echo  1 > /sys/bus/platform/devices/.../enable
>> +		(enable interface)
>> +
>> +What:           /sys/bus/platform/devices/.../config
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This is the most commonly used sysfs interface
>> +		file and this basically stores the addresses of
>> +		the registers which needs to be read in case of
>> +		a hardware crash or manual software triggers.
>> +		Example:
>> +		echo  0x80000010 10 > /sys/bus/platform/devices/../config
>> +		This specifies that 10 words starting from address
> words are of width?
32 bits, will update accordingly.
>
>> +		0x80000010 is to be read.In case there are no words to be
>> +		specified we can simply enter the address.
> No word to be read? So what's the purpose then?

This will only read the value at the address. By specifying the words , 
it will read the value of the

subsequent addresses as well. For example :-

echo  0x80000010 10 > /sys/bus/platform/devices/../config

This will also read and store the value at the next 9 addresses after 0x80000010.
  

>
>> +
>> +What:           /sys/bus/platform/devices/.../config_write
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This file allows user to write a value to the register
>> +		address given as argument.The values are entered in the
>> +		form of <register_address> <value>.The reason for this
>> +		feature of dcc is that for accessing certain registers
>> +		it is necessary to set some bits of soe other register.
> soe?
Ack
>
>> +		That is achievable by giving DCC this privelege.
> privilege
Ack
>
>> +		Example:
>> +		echo 0x80000000 0xFF > /sys/bus/platform/devices/.../config_write
>> +
>> +What:           /sys/bus/platform/devices/.../config_reset
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This file is used to reset the configuration of
>> +		a dcc driver to the default configuration.
> s/"a dcc driver"/"the DCC driver"/g
Ack
>
>> +		Example:
>> +		echo  1 > /sys/bus/platform/devices/.../config_reset
>> +
>> +What:           /sys/bus/platform/devices/.../loop
>> +Date:		March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This file is used to enter the loop count as dcc
>> +		driver gives the option to loop multiple times on
>> +		the same register and store the values for each
>> +		loop.This is done to capture the changing values
>> +		of a register with time which comes handy for
>> +		debugging purposes.
>> +		Example:
>> +		echo 10 > /sys/bus/platform/devices/10a2000.dcc/loop
>> +		(Setting the loop count to 10)
>> +		echo  0x80000010 10 > /sys/bus/platform/devices/.../config
>> +                (Read 10 words starting from address 0x80000010O)
>> +		echo 1 > /sys/bus/platform/devices/.../loop
>> +		(Terminate the loop by writing a count of 1 to the loop sysfs node)
>> +
>> +What:           /sys/bus/platform/devices/.../rd_mod_wr
> Can you come up with a better name? Like config_read_write?
Ack
>
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This file is used to read the value of the register
>> +		and then write the value given as an argument to the
>> +		register address in config.The address argument should
>> +		be given of the form <mask> <value>.For debugging
>> +		purposes sometimes we need to first read from a register
>> +		and then set some values to the register.
> Reading this description gives an impression that this file is used to read the
> value of a register. But it is write only and the value will be read only during
> the trigger or crash. So this should be stated explicitly.
Ack
>
>> +		Example:
>> +		echo 0x80000000 > /sys/bus/platform/devices/.../config
>> +		(Set the address in config file)
>> +		echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
>> +		(Provide the mask and the value to write)
>> +
>> +What:           /sys/bus/platform/devices/.../ready
>> +Date:           March 2021
>> +Contact:        Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This file is used to check the status of the dcc
>> +		hardware if it's ready to take the inputs.
>> +		Example:
>> +		cat /sys/bus/platform/devices/.../ready
> Document the value read also.
Ack
>
>> +
>> +What:		/sys/bus/platform/devices/.../curr_list
>> +Date:		February 2021
>> +Contact:	Souradeep Chowdhury <schowdhu at codeaurora.org>
>> +Description:
>> +		This attribute is used to enter the linklist to be
>> +		used while appending addresses.The range of values
>> +		for this can be from 0 to 3.This feature is given in
>> +		order to use certain linkedlist for certain debugging
>> +		purposes.
>> +		Example:
>> +		echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
>> +
> How does a user will know the contents of the linked list? Basis on what
> criteria, user will know what value to write?

The purpose of creating separate linked list for the user was to provide 
them with a guidelines of

which linked list to use for which debugging purposes. There is no 
stringent rule as such for which

linked list to use but while debugging multiple components , this gives 
an advantage to the user.

>
>> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
>> index 79b568f..5101912 100644
>> --- a/drivers/soc/qcom/Kconfig
>> +++ b/drivers/soc/qcom/Kconfig
>> @@ -69,6 +69,14 @@ config QCOM_LLCC
>>   	  SDM845. This provides interfaces to clients that use the LLCC.
>>   	  Say yes here to enable LLCC slice driver.
>>   
>> +config QCOM_DCC
>> +	tristate "Qualcomm Technologies, Inc. Data Capture and Compare(DCC) engine driver"
>> +	depends on ARCH_QCOM || COMPILE_TEST
>> +	help
>> +	  This option enables driver for Data Capture and Compare engine. DCC
>> +	  driver provides interface to configure DCC block and read back
>> +	  captured data from DCC's internal SRAM.
>> +
>>   config QCOM_KRYO_L2_ACCESSORS
>>   	bool
>>   	depends on ARCH_QCOM && ARM64 || COMPILE_TEST
>> diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
>> index ad675a6..0aaf82b 100644
>> --- a/drivers/soc/qcom/Makefile
>> +++ b/drivers/soc/qcom/Makefile
>> @@ -4,6 +4,7 @@ obj-$(CONFIG_QCOM_AOSS_QMP) +=	qcom_aoss.o
>>   obj-$(CONFIG_QCOM_GENI_SE) +=	qcom-geni-se.o
>>   obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o
>>   obj-$(CONFIG_QCOM_CPR)		+= cpr.o
>> +obj-$(CONFIG_QCOM_DCC) += dcc.o
>>   obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
>>   obj-$(CONFIG_QCOM_MDT_LOADER)	+= mdt_loader.o
>>   obj-$(CONFIG_QCOM_OCMEM)	+= ocmem.o
>> diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
>> new file mode 100644
>> index 0000000..daf4388
>> --- /dev/null
>> +++ b/drivers/soc/qcom/dcc.c
>> @@ -0,0 +1,1549 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
>> + */
>> +
>> +#include <linux/bitfield.h>
>> +#include <linux/bitops.h>
>> +#include <linux/cdev.h>
>> +#include <linux/delay.h>
>> +#include <linux/fs.h>
>> +#include <linux/io.h>
>> +#include <linux/iopoll.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/uaccess.h>
>> +
>> +#define TIMEOUT_US		5000
>> +
>> +#define dcc_writel(drvdata, val, off)					\
>> +	writel((val), drvdata->base + dcc_offset_conv(drvdata, off))
>> +#define dcc_readl(drvdata, off)						\
>> +	readl(drvdata->base + dcc_offset_conv(drvdata, off))
>> +
>> +#define DCC_SRAM_NODE "dcc_sram"
>> +
>> +/* DCC registers */
>> +#define DCC_HW_INFO			0x04
>> +#define DCC_LL_NUM_INFO			0x10
>> +#define DCC_STATUS			0x1C
> Please use lower case for register offsets. Also, align the defines properly.
Ack
>
>> +#define DCC_LL_LOCK(m)			(0x34 + 0x80 * m)
>> +#define DCC_LL_CFG(m)			(0x38 + 0x80 * m)
>> +#define DCC_LL_BASE(m)			(0x3c + 0x80 * m)
>> +#define DCC_FD_BASE(m)			(0x40 + 0x80 * m)
>> +#define DCC_LL_TIMEOUT(m)		(0x44 + 0x80 * m)
>> +#define DCC_LL_INT_ENABLE(m)		(0x4C + 0x80 * m)
>> +#define DCC_LL_INT_STATUS(m)		(0x50 + 0x80 * m)
>> +#define DCC_LL_SW_TRIGGER(m)		(0x60 + 0x80 * m)
>> +#define DCC_LL_BUS_ACCESS_STATUS(m)	(0x64 + 0x80 * m)
>> +
>> +#define DCC_MAP_LEVEL1			0x18
>> +#define DCC_MAP_LEVEL2			0x34
>> +#define DCC_MAP_LEVEL3			0x4C
>> +
>> +#define DCC_MAP_OFFSET1			0x10
>> +#define DCC_MAP_OFFSET2			0x18
>> +#define DCC_MAP_OFFSET3			0x1C
>> +#define DCC_MAP_OFFSET4			0x8
>> +
>> +#define DCC_FIX_LOOP_OFFSET		16
>> +#define DCC_VER_INFO_BIT		9
>> +
>> +#define DCC_READ			0
>> +#define DCC_WRITE			1
>> +#define DCC_LOOP			2
>> +#define DCC_READ_WRITE			3
>> +
>> +#define MAX_DCC_OFFSET			GENMASK(9, 2)
>> +#define MAX_DCC_LEN			GENMASK(6, 0)
>> +#define MAX_LOOP_CNT			GENMASK(7, 0)
>> +
>> +#define DCC_ADDR_DESCRIPTOR		0x00
>> +#define DCC_ADDR_LIMIT			27
>> +#define DCC_ADDR_OFF_RANGE		8
>> +#define DCC_ADDR_RANGE			GENMASK(31, 4)
>> +#define DCC_LOOP_DESCRIPTOR		BIT(30)
>> +#define DCC_RD_MOD_WR_DESCRIPTOR	BIT(31)
>> +#define DCC_LINK_DESCRIPTOR		GENMASK(31, 30)
>> +
>> +#define DCC_READ_IND			0x00
>> +#define DCC_WRITE_IND			(BIT(28))
>> +
>> +#define DCC_AHB_IND			0x00
>> +#define DCC_APB_IND			BIT(29)
>> +
>> +#define DCC_MAX_LINK_LIST		8
>> +#define DCC_INVALID_LINK_LIST		GENMASK(7, 0)
>> +
>> +#define DCC_VER_MASK1			GENMASK(6, 0)
>> +#define DCC_VER_MASK2			GENMASK(5, 0)
>> +
>> +#define DCC_RD_MOD_WR_ADDR              0xC105E
>> +
>> +struct qcom_dcc_config {
>> +	int dcc_ram_offset;
> Are you planning to expand this structure? If not, please use "dcc_ram_offset"
> directly.
Ack
>
>> +};
>> +
>> +enum dcc_descriptor_type {
>> +	DCC_ADDR_TYPE,
>> +	DCC_LOOP_TYPE,
>> +	DCC_READ_WRITE_TYPE,
>> +	DCC_WRITE_TYPE
>> +};
>> +
>> +enum dcc_mem_map_ver {
>> +	DCC_MEM_MAP_VER1 = 1,
>> +	DCC_MEM_MAP_VER2 = 2,
>> +	DCC_MEM_MAP_VER3 = 3
>> +};
>> +
>> +struct dcc_config_entry {
>> +	u32				base;
>> +	u32				offset;
>> +	u32				len;
>> +	u32				index;
>> +	u32				loop_cnt;
>> +	u32				write_val;
>> +	u32				mask;
>> +	bool				apb_bus;
>> +	enum dcc_descriptor_type	desc_type;
>> +	struct list_head		list;
>> +};
>> +
>> +/**
>> + * struct dcc_drvdata - configuration information related to a dcc device
>> + * @base:	      Base Address of the dcc device
>> + * @dev:	      The device attached to the driver data
>> + * @mutex:	      Lock to protect access and manipulation of dcc_drvdata
> What? Are you trying to protect the whole structure or some fields?
whole structure in this case
>
>> + * @ram_base:         Base address for the SRAM dedicated for the dcc device
>> + * @ram_offset:       Offset to the SRAM dedicated for dcc device
>> + * @mem_map_ver:      Memory map version of DCC hardware
>> + * @ram_cfg:          Used for address limit calculation for dcc
>> + * @ram_start:        Starting address of DCC SRAM
>> + * @enable:	      Flag to check if DCC linked list is enabled
> This contains an array of linked list enable flags.
Ack
>
>> + * @interrupt_disable:Flag to enable/disable interrupts
> For simplicity, just use a space after colon.
Ack
>
>> + * @sram_dev:	      Character device equivalent of dcc SRAM
>> + * @sram_class:	      Class equivalent of the DCC SRAM device
>> + * @cfg_head:	      Points to the head of the linked list of addresses
>> + * @nr_config:        Stores the number of addresses currently configured for a linkedlist
>> + * @nr_link_list:     Total number of linkedlists supported by the DCC configuration
>> + * @curr_list:        The index of the current linklist with which the driver is working
>> + * @loopoff:          Loop offset bits range for the addresses
>> + */
>> +struct dcc_drvdata {
>> +	void __iomem		*base;
>> +	struct device		*dev;
>> +	struct mutex		mutex;
>> +	void __iomem		*ram_base;
>> +	phys_addr_t		ram_size;
>> +	phys_addr_t		ram_offset;
>> +	enum dcc_mem_map_ver	mem_map_ver;
>> +	phys_addr_t		ram_cfg;
>> +	phys_addr_t		ram_start;
>> +	bool			*enable;
>> +	bool			interrupt_disable;
> Move this to end to avoid holes.
Ack
>
>> +	struct cdev		sram_dev;
>> +	struct class		*sram_class;
>> +	struct list_head	*cfg_head;
>> +	size_t			*nr_config;
>> +	size_t			nr_link_list;
>> +	u8			curr_list;
>> +	u8			loopoff;
>> +};
> Is it possible to move the linked list specific members to a different struct?
Ack
>
>> +
>> +struct dcc_cfg_attr {
>> +	u32	addr;
>> +	u32	prev_addr;
>> +	u32	prev_off;
>> +	u32	link;
>> +	u32	sram_offset;
>> +};
>> +
>> +struct dcc_cfg_loop_attr {
>> +	u32	loop;
>> +	bool	loop_start;
> Move this to the end
Ack
>
>> +	u32	loop_cnt;
>> +	u32	loop_len;
>> +	u32	loop_off;
>> +};
>> +
>> +static size_t dcc_offset_conv(struct dcc_drvdata *drvdata, size_t off)
> Add comment on what this function does.
Ack
>
>> +{
>> +	if (drvdata->mem_map_ver == DCC_MEM_MAP_VER1) {
>> +		if ((off & DCC_VER_MASK1) >= DCC_MAP_LEVEL3)
> Use FIELD_* macros where applicable.
Ack
>
>> +			return off - DCC_MAP_OFFSET3;
> Use brackets ():
>
> return (off - DCC_MAP_OFFSET3);
Ack
>
>> +		if ((off & DCC_VER_MASK1) >= DCC_MAP_LEVEL2)
>> +			return off - DCC_MAP_OFFSET2;
>> +		else if ((off & DCC_VER_MASK1) >= DCC_MAP_LEVEL1)
>> +			return off - DCC_MAP_OFFSET1;
>> +	} else if (drvdata->mem_map_ver == DCC_MEM_MAP_VER2) {
>> +		if ((off & DCC_VER_MASK1) >= DCC_MAP_LEVEL2)
>> +			return off - DCC_MAP_OFFSET4;
>> +	}
>> +
>> +	return off;
>> +}
>> +
>> +static int dcc_sram_writel(struct dcc_drvdata *drvdata,
>> +					u32 val, u32 off)
>> +{
>> +	if (unlikely(off > (drvdata->ram_size - 4)))
> A comment here would be good too.
Ack
>
>> +		return -EINVAL;
>> +
>> +	writel(val, drvdata->ram_base + off);
>> +
>> +	return 0;
>> +}
>> +
>> +static bool dcc_ready(struct dcc_drvdata *drvdata)
>> +{
>> +	u32 val;
>> +
>> +	return !readl_poll_timeout((drvdata->base + dcc_offset_conv(drvdata, DCC_STATUS)),
>> +				val, (FIELD_GET(GENMASK(1, 0), val) == 0), 1, TIMEOUT_US);
> "FIELD_GET(GENMASK(1, 0)" could be wrapped in a define.
Ack
>
>> +
>> +}
>> +
>> +static int dcc_read_status(struct dcc_drvdata *drvdata)
>> +{
>> +	int curr_list;
>> +	u32 bus_status;
>> +	u32 ll_cfg;
>> +	u32 tmp_ll_cfg;
>> +
>> +	for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
>> +		if (!drvdata->enable[curr_list])
> This looks wrong to me. Why can't you simply allocate N number of linked list
> structures based on the value read from hardware and do all list manipulations
> with it? Like,
>
> struct dcc_list {
> 	struct list_head cfg_head;
> 	bool enable;
> 	...
> };
>
> struct dcc_drvdata {
> 	...
> 	struct dcc_list *lists;
> 	...
> };
>
> /* List allocation */
> dcc->lists = devm_kzalloc();
>
> ...
>
> /* List initialization */
> for (i = 0; i < dcc->nr_link_list; i++) {
> 	list = dcc->lists[i];
> 	INIT_LIST_HEAD(&list->cfg_head);
> }
>
> ...
>
> /* List manipulation */
> list = dcc->lists[i];
> list->enable = true;
Ack
>
>> +			continue;
>> +
>> +		bus_status = dcc_readl(drvdata, DCC_LL_BUS_ACCESS_STATUS(curr_list));
>> +
> No new line needed here.
Ack
>
> I'm stopping here. For the next revision, please split this patch into multiple
> ones based on the functionality added. It is hard to review 1.3k LOC in a single
> patch.

So in version 1 of this series, separate patches were posted for the 
driver but as per Bjorn's

suggestion this was merged as it was becoming difficult to review in 
that case as well.

>
> Thanks,
> Mani


From hongxing.zhu at nxp.com  Tue Jan  4 23:43:16 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:16 +0800
Subject: [PATCH v5 0/6] PCI: imx6: refine codes and add compliance tests mode
 support 
Message-ID: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>

This series patches refine pci-imx6 driver and do the following changes.
- Encapsulate the clock enable into one standalone function
- Add the error propagation from host_init
- Balance the usage of the regulator and clocks when link never came up
- Add the compliance tests mode support

Main changes from v4 to v5:
- Since i.MX8MM PCIe support had been merged. Based on Lorenzo's git repos,
  rebase and resend the patch-set.

Main changes from v3 to v4:
- Regarding Mark's comments, delete the regulator_is_enabled() check.
- Squash #3 and #6 of v3 patch into #5 patch of v4 set.

Main changes from v2 to v3:
- Add "Reviewed-by: Lucas Stach <l.stach at pengutronix.de>" tag into
  first two patches.
- Add a Fixes tag into #3 patch.
- Split the #4 of v2 to two patches, one is clock disable codes move,
  the other one is the acutal clock unbalance fix.
- Add a new host_exit() callback into dw_pcie_host_ops, then it could be
  invoked to handle the unbalance issue in the error handling after
  host_init() function when link is down.
- Add a new host_exit() callback for i.MX PCIe driver to handle this case
  in the error handling after host_init.

Main changes from v1 to v2:
Regarding Lucas' comments.
  - Move the placement of the new imx6_pcie_clk_enable() to avoid the
    forward declarition.
  - Seperate the second patch of v1 patch-set to three patches.
  - Use the module_param to replace the kernel command line.
Regarding Bjorn's comments:
  - Use the cover-letter for a multi-patch series.
  - Correct the subject line, and refine the commit logs. For example,
    remove the timestamp of the logs.

drivers/pci/controller/dwc/pci-imx6.c             | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
drivers/pci/controller/dwc/pcie-designware-host.c |   5 ++-
drivers/pci/controller/dwc/pcie-designware.h      |   1 +
3 files changed, 128 insertions(+), 75 deletions(-)

[PATCH v5 1/6] PCI: imx6: Encapsulate the clock enable into one
[PATCH v5 2/6] PCI: imx6: Add the error propagation from host_init
[PATCH v5 3/6] PCI: imx6: PCI: imx6: Move imx6_pcie_clk_disable()
[PATCH v5 4/6] PCI: dwc: Add dw_pcie_host_ops.host_exit() callback
[PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never came
[PATCH v5 6/6] PCI: imx6: Add the compliance tests mode support


From hongxing.zhu at nxp.com  Tue Jan  4 23:43:17 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:17 +0800
Subject: [PATCH v5 1/6] PCI: imx6: Encapsulate the clock enable into one
 standalone function
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-2-git-send-email-hongxing.zhu@nxp.com>

No function changes, just encapsulate the i.MX PCIe clocks enable
operations into one standalone function

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/pci/controller/dwc/pci-imx6.c | 79 ++++++++++++++++-----------
 1 file changed, 48 insertions(+), 31 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index cf139e02c376..1d324fd05d7f 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -481,38 +481,16 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie *imx6_pcie)
 	return ret;
 }
 
-static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
-{
-	u32 val;
-	struct device *dev = imx6_pcie->pci->dev;
-
-	if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr,
-				     IOMUXC_GPR22, val,
-				     val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED,
-				     PHY_PLL_LOCK_WAIT_USLEEP_MAX,
-				     PHY_PLL_LOCK_WAIT_TIMEOUT))
-		dev_err(dev, "PCIe PLL lock timeout\n");
-}
-
-static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 {
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct device *dev = pci->dev;
 	int ret;
 
-	if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
-		ret = regulator_enable(imx6_pcie->vpcie);
-		if (ret) {
-			dev_err(dev, "failed to enable vpcie regulator: %d\n",
-				ret);
-			return;
-		}
-	}
-
 	ret = clk_prepare_enable(imx6_pcie->pcie_phy);
 	if (ret) {
 		dev_err(dev, "unable to enable pcie_phy clock\n");
-		goto err_pcie_phy;
+		return ret;
 	}
 
 	ret = clk_prepare_enable(imx6_pcie->pcie_bus);
@@ -543,6 +521,51 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	}
 	/* allow the clocks to stabilize */
 	usleep_range(200, 500);
+	return 0;
+
+err_ref_clk:
+	clk_disable_unprepare(imx6_pcie->pcie);
+err_pcie:
+	clk_disable_unprepare(imx6_pcie->pcie_bus);
+err_pcie_bus:
+	clk_disable_unprepare(imx6_pcie->pcie_phy);
+
+	return ret;
+}
+
+static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
+{
+	u32 val;
+	struct device *dev = imx6_pcie->pci->dev;
+
+	if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr,
+				     IOMUXC_GPR22, val,
+				     val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED,
+				     PHY_PLL_LOCK_WAIT_USLEEP_MAX,
+				     PHY_PLL_LOCK_WAIT_TIMEOUT))
+		dev_err(dev, "PCIe PLL lock timeout\n");
+}
+
+static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+{
+	struct dw_pcie *pci = imx6_pcie->pci;
+	struct device *dev = pci->dev;
+	int ret;
+
+	if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
+		ret = regulator_enable(imx6_pcie->vpcie);
+		if (ret) {
+			dev_err(dev, "failed to enable vpcie regulator: %d\n",
+				ret);
+			return;
+		}
+	}
+
+	ret = imx6_pcie_clk_enable(imx6_pcie);
+	if (ret) {
+		dev_err(dev, "unable to enable pcie clocks\n");
+		goto err_clks;
+	}
 
 	/* Some boards don't have PCIe reset GPIO. */
 	if (gpio_is_valid(imx6_pcie->reset_gpio)) {
@@ -601,13 +624,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 
 	return;
 
-err_ref_clk:
-	clk_disable_unprepare(imx6_pcie->pcie);
-err_pcie:
-	clk_disable_unprepare(imx6_pcie->pcie_bus);
-err_pcie_bus:
-	clk_disable_unprepare(imx6_pcie->pcie_phy);
-err_pcie_phy:
+err_clks:
 	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
 		ret = regulator_disable(imx6_pcie->vpcie);
 		if (ret)
-- 
2.25.1



From hongxing.zhu at nxp.com  Tue Jan  4 23:43:19 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:19 +0800
Subject: [PATCH v5 3/6] PCI: imx6: PCI: imx6: Move imx6_pcie_clk_disable()
 earlier
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-4-git-send-email-hongxing.zhu@nxp.com>

Just move the imx6_pcie_clk_disable() to an earlier place without function
changes, since it wouldn't be only used in imx6_pcie_suspend_noirq() later.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 47 +++++++++++++--------------
 1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 13a4328bea19..15908c184953 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -533,6 +533,29 @@ static int imx6_pcie_clk_enable(struct imx6_pcie *imx6_pcie)
 	return ret;
 }
 
+static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
+{
+	clk_disable_unprepare(imx6_pcie->pcie);
+	clk_disable_unprepare(imx6_pcie->pcie_phy);
+	clk_disable_unprepare(imx6_pcie->pcie_bus);
+
+	switch (imx6_pcie->drvdata->variant) {
+	case IMX6SX:
+		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
+		break;
+	case IMX7D:
+		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
+				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
+				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
+		break;
+	case IMX8MQ:
+		clk_disable_unprepare(imx6_pcie->pcie_aux);
+		break;
+	default:
+		break;
+	}
+}
+
 static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
 {
 	u32 val;
@@ -971,30 +994,6 @@ static void imx6_pcie_pm_turnoff(struct imx6_pcie *imx6_pcie)
 	usleep_range(1000, 10000);
 }
 
-static void imx6_pcie_clk_disable(struct imx6_pcie *imx6_pcie)
-{
-	clk_disable_unprepare(imx6_pcie->pcie);
-	clk_disable_unprepare(imx6_pcie->pcie_phy);
-	clk_disable_unprepare(imx6_pcie->pcie_bus);
-
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX6SX:
-		clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
-		break;
-	case IMX7D:
-		regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
-				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL,
-				   IMX7D_GPR12_PCIE_PHY_REFCLK_SEL);
-		break;
-	case IMX8MQ:
-	case IMX8MM:
-		clk_disable_unprepare(imx6_pcie->pcie_aux);
-		break;
-	default:
-		break;
-	}
-}
-
 static int imx6_pcie_suspend_noirq(struct device *dev)
 {
 	struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev);
-- 
2.25.1



From hongxing.zhu at nxp.com  Tue Jan  4 23:43:18 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:18 +0800
Subject: [PATCH v5 2/6] PCI: imx6: Add the error propagation from host_init
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-3-git-send-email-hongxing.zhu@nxp.com>

Since there is error return check of the host_init callback, add error
check to imx6_pcie_deassert_core_reset() function, and change the
function type accordingly.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
Reviewed-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/pci/controller/dwc/pci-imx6.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 1d324fd05d7f..13a4328bea19 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -546,24 +546,24 @@ static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
 		dev_err(dev, "PCIe PLL lock timeout\n");
 }
 
-static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
+static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 {
 	struct dw_pcie *pci = imx6_pcie->pci;
 	struct device *dev = pci->dev;
-	int ret;
+	int ret, err;
 
 	if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
 		ret = regulator_enable(imx6_pcie->vpcie);
 		if (ret) {
 			dev_err(dev, "failed to enable vpcie regulator: %d\n",
 				ret);
-			return;
+			return ret;
 		}
 	}
 
-	ret = imx6_pcie_clk_enable(imx6_pcie);
-	if (ret) {
-		dev_err(dev, "unable to enable pcie clocks\n");
+	err = imx6_pcie_clk_enable(imx6_pcie);
+	if (err) {
+		dev_err(dev, "unable to enable pcie clocks: %d\n", err);
 		goto err_clks;
 	}
 
@@ -622,7 +622,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 		break;
 	}
 
-	return;
+	return 0;
 
 err_clks:
 	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
@@ -631,6 +631,7 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 			dev_err(dev, "failed to disable vpcie regulator: %d\n",
 				ret);
 	}
+	return err;
 }
 
 static void imx6_pcie_configure_type(struct imx6_pcie *imx6_pcie)
@@ -888,11 +889,18 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
 static int imx6_pcie_host_init(struct pcie_port *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct device *dev = pci->dev;
 	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+	int ret;
 
 	imx6_pcie_assert_core_reset(imx6_pcie);
 	imx6_pcie_init_phy(imx6_pcie);
-	imx6_pcie_deassert_core_reset(imx6_pcie);
+	ret = imx6_pcie_deassert_core_reset(imx6_pcie);
+	if (ret < 0) {
+		dev_err(dev, "pcie host init failed: %d.\n", ret);
+		return ret;
+	}
+
 	imx6_setup_phy_mpll(imx6_pcie);
 
 	return 0;
-- 
2.25.1



From hongxing.zhu at nxp.com  Tue Jan  4 23:43:20 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:20 +0800
Subject: [PATCH v5 4/6] PCI: dwc: Add dw_pcie_host_ops.host_exit() callback
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-5-git-send-email-hongxing.zhu@nxp.com>

When link is never came up in the link training after host_init.
The clocks and power supplies usage counter balance should be handled
properly on some DWC platforms (for example, i.MX PCIe).

Add a new host_exit() callback into dw_pcie_host_ops, then it could be
invoked to handle the unbalance issue in the error handling after
host_init() function when link is down.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 drivers/pci/controller/dwc/pcie-designware-host.c | 5 ++++-
 drivers/pci/controller/dwc/pcie-designware.h      | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index f4755f3a03be..461863bde3c9 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -405,7 +405,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	if (!dw_pcie_link_up(pci) && pci->ops && pci->ops->start_link) {
 		ret = pci->ops->start_link(pci);
 		if (ret)
-			goto err_free_msi;
+			goto err_host_init;
 	}
 
 	/* Ignore errors, the link may come up later */
@@ -417,6 +417,9 @@ int dw_pcie_host_init(struct pcie_port *pp)
 	if (!ret)
 		return 0;
 
+err_host_init:
+	if (pp->ops->host_exit)
+		pp->ops->host_exit(pp);
 err_free_msi:
 	if (pp->has_msi_ctrl)
 		dw_pcie_free_msi(pp);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 7d6e9b7576be..1153687ea9a6 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -174,6 +174,7 @@ enum dw_pcie_device_mode {
 
 struct dw_pcie_host_ops {
 	int (*host_init)(struct pcie_port *pp);
+	void (*host_exit)(struct pcie_port *pp);
 	int (*msi_host_init)(struct pcie_port *pp);
 };
 
-- 
2.25.1



From hongxing.zhu at nxp.com  Tue Jan  4 23:43:21 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:21 +0800
Subject: [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never came
 up
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-6-git-send-email-hongxing.zhu@nxp.com>

When PCIe PHY link never came up and vpcie regulator is present, there
would be following dump when try to put the regulator.
Add a new host_exit() callback for i.MX PCIe driver to disable this
regulator and fix this dump when link never came up.

The driver should undo any enables it did itself, and not undo any
enables that anything else did which means it should never be basing
decisions on regulator_is_enabled().

To keep usage counter balance of the clocks, powers and so on. Do the
clock disable in the error handling after host_init too.

  imx6q-pcie 33800000.pcie: Phy link never came up
  imx6q-pcie: probe of 33800000.pcie failed with error -110
  ------------[ cut here ]------------
  WARNING: CPU: 3 PID: 119 at drivers/regulator/core.c:2256 _regulator_put.part.0+0x14c/0x158
  Modules linked in:
  CPU: 3 PID: 119 Comm: kworker/u8:2 Not tainted 5.13.0-rc7-next-20210625-94710-ge4e92b2588a3 #10
  Hardware name: FSL i.MX8MM EVK board (DT)
  Workqueue: events_unbound async_run_entry_fn
  pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--)
  pc : _regulator_put.part.0+0x14c/0x158
  lr : regulator_put+0x34/0x48
  sp : ffff8000122ebb30
  x29: ffff8000122ebb30 x28: ffff800011be7000 x27: 0000000000000000
  x26: 0000000000000000 x25: 0000000000000000 x24: ffff00000025f2bc
  x23: ffff00000025f2c0 x22: ffff00000025f010 x21: ffff8000122ebc18
  x20: ffff800011e3fa60 x19: ffff00000375fd80 x18: 0000000000000010
  x17: 000000040044ffff x16: 00400032b5503510 x15: 0000000000000108
  x14: ffff0000003cc938 x13: 00000000ffffffea x12: 0000000000000000
  x11: 0000000000000000 x10: ffff80001076ba88 x9 : ffff80001076a540
  x8 : ffff00000025f2c0 x7 : ffff0000001f4450 x6 : ffff000000176cd8
  x5 : ffff000003857880 x4 : 0000000000000000 x3 : ffff800011e3fe30
  x2 : ffff0000003cc4c0 x1 : 0000000000000000 x0 : 0000000000000001
  Call trace:
   _regulator_put.part.0+0x14c/0x158
   regulator_put+0x34/0x48
   devm_regulator_release+0x10/0x18
   release_nodes+0x38/0x60
   devres_release_all+0x88/0xd0
   really_probe+0xd0/0x2e8
   __driver_probe_device+0x74/0xd8
   driver_probe_device+0x7c/0x108
   __device_attach_driver+0x8c/0xd0
   bus_for_each_drv+0x74/0xc0
   __device_attach_async_helper+0xb4/0xd8
   async_run_entry_fn+0x30/0x100
   process_one_work+0x19c/0x320
   worker_thread+0x48/0x418
   kthread+0x14c/0x158
   ret_from_fork+0x10/0x18
  ---[ end trace 3664ca4a50ce849b ]---

Link: https://lore.kernel.org/r/20201105211159.1814485-11-robh at kernel.org
Fixes: 886a9c134755 ("PCI: dwc: Move link handling into common code")
Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 36 +++++++++++++++++----------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 15908c184953..61b25f5cbf5c 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -369,8 +369,6 @@ static int imx6_pcie_attach_pd(struct device *dev)
 
 static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 {
-	struct device *dev = imx6_pcie->pci->dev;
-
 	switch (imx6_pcie->drvdata->variant) {
 	case IMX7D:
 	case IMX8MQ:
@@ -400,14 +398,6 @@ static void imx6_pcie_assert_core_reset(struct imx6_pcie *imx6_pcie)
 				   IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
 		break;
 	}
-
-	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
-		int ret = regulator_disable(imx6_pcie->vpcie);
-
-		if (ret)
-			dev_err(dev, "failed to disable vpcie regulator: %d\n",
-				ret);
-	}
 }
 
 static unsigned int imx6_pcie_grp_offset(const struct imx6_pcie *imx6_pcie)
@@ -575,7 +565,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	struct device *dev = pci->dev;
 	int ret, err;
 
-	if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) {
+	if (imx6_pcie->vpcie) {
 		ret = regulator_enable(imx6_pcie->vpcie);
 		if (ret) {
 			dev_err(dev, "failed to enable vpcie regulator: %d\n",
@@ -648,7 +638,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
 	return 0;
 
 err_clks:
-	if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) {
+	if (imx6_pcie->vpcie) {
 		ret = regulator_disable(imx6_pcie->vpcie);
 		if (ret)
 			dev_err(dev, "failed to disable vpcie regulator: %d\n",
@@ -905,7 +895,6 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
 	dev_dbg(dev, "PHY DEBUG_R0=0x%08x DEBUG_R1=0x%08x\n",
 		dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG0),
 		dw_pcie_readl_dbi(pci, PCIE_PORT_DEBUG1));
-	imx6_pcie_reset_phy(imx6_pcie);
 	return ret;
 }
 
@@ -929,8 +918,29 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
 	return 0;
 }
 
+static void imx6_pcie_host_exit(struct pcie_port *pp)
+{
+	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+	struct device *dev = pci->dev;
+	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
+
+	imx6_pcie_reset_phy(imx6_pcie);
+	imx6_pcie_clk_disable(imx6_pcie);
+	switch (imx6_pcie->drvdata->variant) {
+	case IMX8MM:
+		if (phy_power_off(imx6_pcie->phy))
+			dev_err(dev, "unable to power off phy\n");
+		break;
+	default:
+		break;
+	}
+	if (imx6_pcie->vpcie)
+		regulator_disable(imx6_pcie->vpcie);
+}
+
 static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
 	.host_init = imx6_pcie_host_init,
+	.host_exit = imx6_pcie_host_exit,
 };
 
 static const struct dw_pcie_ops dw_pcie_ops = {
-- 
2.25.1



From hongxing.zhu at nxp.com  Tue Jan  4 23:43:22 2022
From: hongxing.zhu at nxp.com (Richard Zhu)
Date: Wed,  5 Jan 2022 15:43:22 +0800
Subject: [PATCH v5 6/6] PCI: imx6: Add the compliance tests mode support
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <1641368602-20401-7-git-send-email-hongxing.zhu@nxp.com>

Refer to the system board signal Quality of PCIe archiecture PHY test
specification. Signal quality tests(for example: jitters,  differential
eye opening and so on ) can be executed with devices in the
polling.compliance state.

To let the device support polling.compliance stat, the clocks and powers
shouldn't be turned off when the probe of device driver is failed.

Based on CLB(Compliance Load Board) Test Fixture and so on test
equipments, the PHY link would be down during the compliance tests.
Refer to this scenario, add the i.MX PCIe compliance tests mode enable
support, and keep the clocks and powers on, and finish the driver probe
without error return.

Use the "pci_imx6.compliance=1" in kernel command line to enable the
compliance tests mode.

Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 47 ++++++++++++++++++---------
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 61b25f5cbf5c..773b9e45806b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -146,6 +146,10 @@ struct imx6_pcie {
 #define PHY_RX_OVRD_IN_LO_RX_DATA_EN		BIT(5)
 #define PHY_RX_OVRD_IN_LO_RX_PLL_EN		BIT(3)
 
+static bool imx6_pcie_cmp_mode;
+module_param_named(compliance, imx6_pcie_cmp_mode, bool, 0644);
+MODULE_PARM_DESC(compliance, "i.MX PCIe compliance test mode (1=compliance test mode enabled)");
+
 static int pcie_phy_poll_ack(struct imx6_pcie *imx6_pcie, bool exp_val)
 {
 	struct dw_pcie *pci = imx6_pcie->pci;
@@ -832,10 +836,12 @@ static int imx6_pcie_start_link(struct dw_pcie *pci)
 	 * started in Gen2 mode, there is a possibility the devices on the
 	 * bus will not be detected at all.  This happens with PCIe switches.
 	 */
-	tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
-	tmp &= ~PCI_EXP_LNKCAP_SLS;
-	tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
-	dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
+	if (!imx6_pcie_cmp_mode) {
+		tmp = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
+		tmp &= ~PCI_EXP_LNKCAP_SLS;
+		tmp |= PCI_EXP_LNKCAP_SLS_2_5GB;
+		dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, tmp);
+	}
 
 	/* Start LTSSM. */
 	imx6_pcie_ltssm_enable(dev);
@@ -924,18 +930,20 @@ static void imx6_pcie_host_exit(struct pcie_port *pp)
 	struct device *dev = pci->dev;
 	struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
 
-	imx6_pcie_reset_phy(imx6_pcie);
-	imx6_pcie_clk_disable(imx6_pcie);
-	switch (imx6_pcie->drvdata->variant) {
-	case IMX8MM:
-		if (phy_power_off(imx6_pcie->phy))
-			dev_err(dev, "unable to power off phy\n");
-		break;
-	default:
-		break;
+	if (!imx6_pcie_cmp_mode) {
+		imx6_pcie_reset_phy(imx6_pcie);
+		imx6_pcie_clk_disable(imx6_pcie);
+		switch (imx6_pcie->drvdata->variant) {
+		case IMX8MM:
+			if (phy_power_off(imx6_pcie->phy))
+				dev_err(dev, "unable to power off phy\n");
+			break;
+		default:
+			break;
+		}
+		if (imx6_pcie->vpcie)
+			regulator_disable(imx6_pcie->vpcie);
 	}
-	if (imx6_pcie->vpcie)
-		regulator_disable(imx6_pcie->vpcie);
 }
 
 static const struct dw_pcie_host_ops imx6_pcie_host_ops = {
@@ -1250,8 +1258,15 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 		return ret;
 
 	ret = dw_pcie_host_init(&pci->pp);
-	if (ret < 0)
+	if (ret < 0) {
+		if (imx6_pcie_cmp_mode) {
+			dev_info(dev, "Driver loaded with compliance test mode enabled.\n");
+			ret = 0;
+		} else {
+			dev_err(dev, "Unable to add pcie port.\n");
+		}
 		return ret;
+	}
 
 	if (pci_msi_enabled()) {
 		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
-- 
2.25.1



From djakov at kernel.org  Wed Jan  5 00:24:28 2022
From: djakov at kernel.org (Georgi Djakov)
Date: Wed, 5 Jan 2022 10:24:28 +0200
Subject: [PATCH v3 1/3] dt-bindings: interconnect: imx8m-noc: Add
 fsl,icc-id property
In-Reply-To: <20220103192900.946521-1-abel.vesa@nxp.com>
References: <20220103192900.946521-1-abel.vesa@nxp.com>
Message-ID: <73f0b849-223a-11a8-8238-4d29a3ccef0b@kernel.org>

Hi Abel,

On 3.01.22 21:28, Abel Vesa wrote:
> Add documentation for fsl,icc-id property.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>   .../devicetree/bindings/interconnect/fsl,imx8m-noc.yaml      | 5 +++++

Please CC the DT mailing list.

>   1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> index b8204ed22dd5..4924743e8cb1 100644
> --- a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> +++ b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> @@ -47,6 +47,11 @@ properties:
>     operating-points-v2: true
>     opp-table: true
>   
> +  fsl,icc-id:
> +    $ref: "/schemas/types.yaml#/definitions/uint32"
> +    description:
> +      unique ID used for linking i.MX bus or ddrc node to inteconnect

s/inteconnect/interconnect/

Thanks,
Georgi

> +
>     fsl,ddrc:
>       $ref: "/schemas/types.yaml#/definitions/phandle"
>       description:



From michael at walle.cc  Wed Jan  5 00:25:29 2022
From: michael at walle.cc (Michael Walle)
Date: Wed, 05 Jan 2022 09:25:29 +0100
Subject: [PATCH 2/8] dt-bindings: nvmem: add transformation bindings
In-Reply-To: <YdRh2lp5Ca08gHtR@robh.at.kernel.org>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-3-michael@walle.cc>
 <YdRh2lp5Ca08gHtR@robh.at.kernel.org>
Message-ID: <084b306b7c49ce8085dd867663945d29@walle.cc>

Am 2022-01-04 16:03, schrieb Rob Herring:
> On Tue, Dec 28, 2021 at 03:25:43PM +0100, Michael Walle wrote:
>> Just add a simple list of the supported devices which need a nvmem
>> transformations.
>> 
>> Also, since the compatible string is prepended to the actual nvmem
>> compatible string, we need to match using "contains" instead of an 
>> exact
>> match.
>> 
>> Signed-off-by: Michael Walle <michael at walle.cc>
>> ---
>>  .../devicetree/bindings/mtd/mtd.yaml          |  7 +--
>>  .../bindings/nvmem/nvmem-transformations.yaml | 46 
>> +++++++++++++++++++
>>  2 files changed, 50 insertions(+), 3 deletions(-)
>>  create mode 100644 
>> Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
>> 
>> diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml 
>> b/Documentation/devicetree/bindings/mtd/mtd.yaml
>> index 376b679cfc70..0291e439b6a6 100644
>> --- a/Documentation/devicetree/bindings/mtd/mtd.yaml
>> +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml
>> @@ -33,9 +33,10 @@ patternProperties:
>> 
>>      properties:
>>        compatible:
>> -        enum:
>> -          - user-otp
>> -          - factory-otp
>> +        contains:
>> +          enum:
>> +            - user-otp
>> +            - factory-otp
> 
> If the addition is only compatible strings, then I would just add them
> here. Otherwise this needs to be structured a bit differently. More on
> that below.

I wanted to avoid having these compatible strings "cluttered" all around
the various files. Esp. having a specific compatible string in a generic
mtd.yaml. But if everyone is fine with that, I'll just move it here.

>> 
>>      required:
>>        - compatible
>> diff --git 
>> a/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml 
>> b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
>> new file mode 100644
>> index 000000000000..8c8d85fd6d27
>> --- /dev/null
>> +++ 
>> b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
>> @@ -0,0 +1,46 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/nvmem/nvmem-transformations.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: NVMEM transformations Device Tree Bindings
>> +
>> +maintainers:
>> +  - Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
>> +
>> +description: |
>> +  This is a list NVMEM devices which need transformations.
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - items:
>> +        - enum:
>> +          - kontron,sl28-vpd
>> +        - const: user-otp
>> +      - const: user-otp
> 
> This will be applied to any node containing 'user-otp'. You need a
> custom 'select' to avoid that.

Out of curiosity, you mean something like:

select:
   compatible:
     contains:
       enum:
         - kontron,sl28-vpd



From sj at kernel.org  Wed Jan  5 00:55:34 2022
From: sj at kernel.org (SeongJae Park)
Date: Wed,  5 Jan 2022 08:55:34 +0000
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220105085534.22981-1-sj@kernel.org>

Hi Yu,

On Tue, 4 Jan 2022 13:22:19 -0700 Yu Zhao <yuzhao at google.com> wrote:

> TLDR
> ====
> The current page reclaim is too expensive in terms of CPU usage and it
> often makes poor choices about what to evict. This patchset offers an
> alternative solution that is performant, versatile and
> straightforward.
>  
[...]
> Summery
> =======
> The facts are:
> 1. The independent lab results and the real-world applications
>    indicate substantial improvements; there are no known regressions.

So impressive results!

> 2. Thrashing prevention, working set estimation and proactive reclaim
>    work out of the box; there are no equivalent solutions.

I think similar works are already available out of the box with the latest
mainline tree, though it might be suboptimal in some cases.

First, you can do thrashing prevention using DAMON-based Operation Scheme
(DAMOS)[1] with MADV_COLD action.  Second, for working set estimation, you can
either use the DAMOS again with statistics action, or the damon_aggregated
tracepoint[2].  The DAMON user space tool[3] helps the tracepoint analysis and
visualization.  Finally, for the proactive reclaim, you can again use the DAMOS
with MADV_PAGEOUT action, or simply the DAMON-based proactive reclaim
module (DAMON_RECLAIM)[4].

Nevertheless, as noted above, current DAMON based solutions might be suboptimal
for some cases.  First of all, DAMON currently doesn't provide page granularity
monitoring.  Though its monitoring results were useful for our users'
production usages, there could be different requirements and situations.
Secondly, the DAMON-based thrashing prevention wouldn't reduce the CPU usage of
the reclamation logic's access scanning.

So, to me, MGLRU patchset looks providing something that DAMON doesn't provide,
but also something that DAMON is already providing.  Specifically, the
efficient page granularity access scanning is what DAMON doesn't provide for
now.  However, the utilization of the access information for LRU list
manipulation (thrashing prevention) and proactive reclamation is similar to
what DAMON (specifically, DAMOS) provides.  Also, this patchset is reducing the
reclamation logic's CPU usage using the efficient page granularity access
scanning.

IMHO, we might be able to reduce the duplicates by integrating MGLRU in DAMON.
What I'm saying is, we could 1) introduce the efficient page granularity access
scanning, 2) reduce the reclamation logic's CPU usage by making it to use the
efficient page granularity access scanning, and 3) extend DAMON for page
granularity monitoring with the efficient access sacanning[5].  Then, users
could get the benefit of MGLRU by using DAMOS but setting it to use your
efficient page granularity access scanning.  To make it more simple, we can
extend existing kernel logics to use DAMON in the way, or implement a new
kernel module.  Additional advantages of this approach would be 1) reducing the
changes to the existing code, and 2) making the efficient page granularity
access information be utilized for more general cases.

Of course, the integration might not be so simple as seems to me now.  We could
put DAMON and MGLRU together as those are for now, and let users select what
they really want.  I think it's up to you.

I didn't read this patchset thoroughly yet, so I might missing many things.  If
so, please feel free to let me know.

[1] https://docs.kernel.org/admin-guide/mm/damon/usage.html#schemes
[2] https://docs.kernel.org/admin-guide/mm/damon/usage.html#tracepoint-for-monitoring-results
[3] https://github.com/awslabs/damo
[4] https://docs.kernel.org/admin-guide/mm/damon/reclaim.html
[5] https://docs.kernel.org/vm/damon/design.html#configurable-layers


Thanks,
SJ

[...]


From angelogioacchino.delregno at collabora.com  Wed Jan  5 01:19:37 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 5 Jan 2022 10:19:37 +0100
Subject: [PATCH 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220104114706.27461-3-allen-kh.cheng@mediatek.com>
References: <20220104114706.27461-1-allen-kh.cheng@mediatek.com>
 <20220104114706.27461-3-allen-kh.cheng@mediatek.com>
Message-ID: <5722750a-dc1a-3242-6371-90236b98d07b@collabora.com>

Il 04/01/22 12:47, allen-kh.cheng ha scritto:
> Add SCP support for mt8186
> 
> Signed-off-by: Allen-KH Cheng <allen-kh.cheng at mediatek.com>

Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From anshuman.khandual at arm.com  Wed Jan  5 01:21:05 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 5 Jan 2022 14:51:05 +0530
Subject: [PATCH] arm64: fix build error when use rodata_enabled
In-Reply-To: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
References: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
Message-ID: <0432f592-789b-7c92-8d7a-99191d7bc669@arm.com>

Hello,

On 1/5/22 8:37 AM, AliOS system security wrote:
> rodata_enabled should be used when CONFIG_STRICT_KERNEL_RWX
> or CONFIG_STRICT_MODULE_RWX is selected

Both these configs get selected invariably with CONFIG_ARM64 in the
platform config file (arch/arm64/Kconfig). I guess there can not be
any such situation, where both configs will be missing/not selected
given ARCH_OPTIONAL_KERNEL_RWX[or _DEFAULT] is not enabled on arm64.

config ARM64
        def_bool y
        select ACPI_CCA_REQUIRED if ACPI
	.....
        select ARCH_HAS_STRICT_KERNEL_RWX
        select ARCH_HAS_STRICT_MODULE_RWX
	.....

Hence for all practical purpose, rodata_enabled could be considered
always available. I am sure there other similar situations as well,
where code elements are not wrapped around if the config option is
always present.

> 
> Signed-off-by: AliOS system security <alios_sys_security at linux.alibaba.com>

Also please refer Documentation/process/submitting-patches.rst for
the rules regarding names, that can be used for a commit sign off.

------------------------------------------------------------------------
then you just add a line saying::

        Signed-off-by: Random J Developer <random at developer.example.org>

using your real name (sorry, no pseudonyms or anonymous contributions.)
------------------------------------------------------------------------

- Anshuman

> ---
>  arch/arm64/mm/mmu.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index acfae9b..47f8754 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -596,6 +596,7 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
>  	vm_area_add_early(vma);
>  }
>  
> +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
>  static int __init parse_rodata(char *arg)
>  {
>  	int ret = strtobool(arg, &rodata_enabled);
> @@ -613,11 +614,16 @@ static int __init parse_rodata(char *arg)
>  	return 0;
>  }
>  early_param("rodata", parse_rodata);
> +#endif
>  
>  #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
>  static int __init map_entry_trampoline(void)
>  {
> -	pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
> +	pgprot_t prot = PAGE_KERNEL_EXEC;
> +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
> +	if (rodata_enabled)
> +		prot = PAGE_KERNEL_ROX;
> +#endif
>  	phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
>  
>  	/* The trampoline is always mapped and can therefore be global */
> @@ -672,7 +678,11 @@ static void __init map_kernel(pgd_t *pgdp)
>  	 * mapping to install SW breakpoints. Allow this (only) when
>  	 * explicitly requested with rodata=off.
>  	 */
> -	pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
> +	pgprot_t text_prot = PAGE_KERNEL_EXEC;
> +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
> +	if (rodata_enabled)
> +		text_prot = PAGE_KERNEL_ROX;
> +#endif
>  
>  	/*
>  	 * If we have a CPU that supports BTI and a kernel built for
> 


From daniel.lezcano at linaro.org  Wed Jan  5 01:21:58 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 5 Jan 2022 10:21:58 +0100
Subject: [PATCH v5 5/6] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <CAMuHMdXzs9WMksQAJXdYaQndsqK3CnQZTGYw=TSFVrDEdX8PCA@mail.gmail.com>
References: <20211218130014.4037640-1-daniel.lezcano@linaro.org>
 <20211218130014.4037640-6-daniel.lezcano@linaro.org>
 <CAPDyKFqWUJTKte3dM=7xG6EtKR8i9neCCNYFs7Jf1J34TezUEQ@mail.gmail.com>
 <CAMuHMdXzs9WMksQAJXdYaQndsqK3CnQZTGYw=TSFVrDEdX8PCA@mail.gmail.com>
Message-ID: <08787cb7-439e-74a4-f268-6c8de0d60a30@linaro.org>


Hi Geert,

thanks for your feedback

On 04/01/2022 10:29, Geert Uytterhoeven wrote:
> On Fri, Dec 31, 2021 at 2:58 PM Ulf Hansson <ulf.hansson at linaro.org> wrote:
>> On Sat, 18 Dec 2021 at 14:00, Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
>>> The DTPM framework does support now the hierarchy description.
>>>
>>> The platform specific code can call the hierarchy creation function
>>> with an array of struct dtpm_node pointing to their parent.
>>>
>>> This patch provides a description of the big and Little CPUs and the
>>> GPU and tie them together under a virtual package name. Only rk3399 is
>>> described now.
>>>
>>> The description could be extended in the future with the memory
>>> controller with devfreq if it has the energy information.
>>>
>>> The hierarchy uses the GPU devfreq with the panfrost driver, and this
>>> one could be loaded as a module. If the hierarchy is created before
>>> the panfrost driver is loaded, it will fail. For this reason the
>>> Kconfig option depends on the panfrost Kconfig's option. If this one
>>> is compiled as a module, automatically the dtpm hierarchy code will be
>>> a module also. Module loading ordering will fix this chicken-egg
>>> problem.
>>>
>>> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> 
>>> --- /dev/null
>>> +++ b/drivers/soc/rockchip/dtpm.c
>>> @@ -0,0 +1,56 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright 2021 Linaro Limited
>>> + *
>>> + * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
>>> + *
>>> + * DTPM hierarchy description
>>> + */
>>> +#include <linux/dtpm.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of.h>
>>> +#include <linux/platform_device.h>
>>> +
>>> +static struct dtpm_node __initdata rk3399_hierarchy[] = {
>>> +       [0]{ .name = "rk3399" },
>>> +       [1]{ .name = "package",
>>> +            .parent = &rk3399_hierarchy[0] },
>>> +       [2]{ .name = "/cpus/cpu at 0",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [3]{ .name = "/cpus/cpu at 1",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [4]{ .name = "/cpus/cpu at 2",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [5]{ .name = "/cpus/cpu at 3",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [6]{ .name = "/cpus/cpu at 100",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [7]{ .name = "/cpus/cpu at 101",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [8]{ .name = "rockchip,rk3399-mali",
>>> +            .type = DTPM_NODE_DT,
>>> +            .parent = &rk3399_hierarchy[1] },
>>> +       [9]{ },
>>> +};
>>
>> I will not object to this, as in the end this seems like what we need
>> to do, unless we can describe things through generic DT bindings for
>> DTPM. Right?
>>
>> Although, if the above is correct, I need to stress that I am kind of
>> worried that this doesn't really scale. We would need to copy lots of
>> information from the DTS files into platform specific c-files, to be
>> able to describe the DTPM hierarchy.
> 
> The description in rk3399_hierarchy[] looks fairly similar to a
> power-domains hierarchy, like we have in e.g. the various
> drivers/soc/renesas/r8*-sysc.c files.  One big difference is that the
> latter do not hardcode the node paths in the driver, but use power
> domain indices, referenced from DT in power-domains properties.
> 
> Perhaps a similar approach can be used for DTPM?
> Does DTPM differ a lot from PM Domains? 

Yes they differ. A DTPM node is a powerzone, a place where we can get
and set the power.

That is the reason why initially a separate binding was proposed.

> If not, perhaps no new
> properties are needed, and power-domains/#power-domain-cells can be
> used as is?




-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From pali at kernel.org  Wed Jan  5 01:35:52 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 10:35:52 +0100
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
Message-ID: <20220105093552.27542-1-pali@kernel.org>

Register 0x43c in its low 24 bits contains PCI class code.

Update code to set all 24 bits of PCI class code and not only upper 16 bits
of PCI class code.

Use a new macro PCI_CLASS_BRIDGE_PCI_NORMAL which represents whole 24 bits
of normal PCI bridge class.

Signed-off-by: Pali Roh?r <pali at kernel.org>

---
Roman helped me with this change and confirmed that class code is stored
really in bits [23:0] of custom register 0x43c (normally class code is
stored in bits [31:8] of pci register 0x08).

This patch depends on patch which adds PCI_CLASS_BRIDGE_PCI_NORMAL macro:
https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
---
 drivers/pci/controller/pcie-iproc.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
index 3df4ab209253..2519201b0e51 100644
--- a/drivers/pci/controller/pcie-iproc.c
+++ b/drivers/pci/controller/pcie-iproc.c
@@ -789,14 +789,13 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
 		return -EFAULT;
 	}
 
-	/* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
+	/* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
 #define PCI_BRIDGE_CTRL_REG_OFFSET	0x43c
-#define PCI_CLASS_BRIDGE_MASK		0xffff00
-#define PCI_CLASS_BRIDGE_SHIFT		8
+#define PCI_BRIDGE_CTRL_REG_CLASS_MASK	0xffffff
 	iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
 				    4, &class);
-	class &= ~PCI_CLASS_BRIDGE_MASK;
-	class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
+	class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
+	class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
 	iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
 				     4, class);
 
-- 
2.20.1



From moudy.ho at mediatek.com  Wed Jan  5 01:37:55 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Wed, 5 Jan 2022 17:37:55 +0800
Subject: [PATCH v11 0/3] media: mediatek: support mdp3 on mt8183 platform
Message-ID: <20220105093758.6850-1-moudy.ho@mediatek.com>

Change since v10:
- The routing table needs to be discarded, and the calculation result
  on the SCP side is used to write a suitable mux setting for
  1 input port and 2 output ports.
- Adjust dts parsing flow to remove redundant HW IDs.
- Fix memory leak caused by no free path information in function "mdp_cmdq_send".

Change since v9:
- Keep only the MDP3 driver patches and split the remaining mmsys and
  mutex patches into another mail.
- Move mutex mod settings to corresponding driver and make relevant adjustments
  for this in MDP3 driver.
- Fix compile warning reported by kernel test robot.

Change since v8:
- Rebase on v5.16-rc2.
- Refer to Angelo's suggestion, adjust the register writing format to increase
  readability and significance.
- Refer to Angelo's suggestion, adjust or reduce inappropriate debugging
  messages.
- Refer to Rob Herring's suggestion to correct the the binding file
  to make it with the specification.
- Fix compile warning reported by kernel test robot.

Change since v7:
- Rebase on v5.15-rc6.
- Revise several V4L2 M2M settings to pass v4l2-compliance test.
- Integrate those same component dt-binding documents of DRM and MDP, and
  move them under the MMSYS domain.
- Split MMSYS and MUTEX into two different files according to
  their functional properties.

Changes since v6:
- Refactor GCE event to corresponding node.
- Fix dt_binding_check fail.
- Fix compilation errors.

Changes since v5:
- Rebase on v5.14-rc6.
- Move MMSYS/Mutex settings to corresponding driver.
- Revise the software license description and copyright.
- Remove unnecessary enum. or definitions.
- Optimize platform/chip definition conditions.
- Use general printing functions instead of MDP3 private ones.
- Fix compile warning.

Changes since v4:
- Rebase on v5.13-rc1.
- Remove the CMDQ flush flow to match the CMDQ API change.
- Integrate four of MDP's direct-link subcomponents into MDP controller node
  from syscon node to avoid illegal clock usage.
- Rewrite dt-binding in a JSON compatible subset of YAML
- Fix a bit of macro argument precedence.

Changes since v3:
- Rebase on v5.9-rc1.
- modify code for review comment from Rob Herring, cancel multiple nodes using
  same register base situation.
- control IOMMU port through pm runtime get/put to DMA components' device.
- SCP(VPU) driver revision.
- stop queuing jobs(remove flush_workqueue()) after mdp_m2m_release().
- add computation of plane address with data_offset.
- fix scale ratio check issue.
- add default v4l2_format setting.

Changes since v2:
- modify code for review comment from Tomasz Figa & Alexandre Courbot
- review comment from Rob Herring will offer code revision in v4, due to
  it's related to device node modification, will need to modify code
  architecture

Changes since v1:
- modify code for CMDQ v3 API support
- EC ipi cmd migration
- fix compliance test fail item (m2m cmd with -f) due to there is two problem in runing all format(-f) cmd:
1. out of memory before test complete
        Due to capture buffer mmap (refcount + 1) after reqbuf but seems
        no corresponding munmap called before device close.
        There are total 12XX items(formats) in format test and each format
        alloc 8 capture/output buffers.
2. unceasingly captureBufs() (randomly)
        Seems the break statement didn't catch the count == 0 situation:
        In v4l2-test-buffers.cpp, function: captureBufs()
                        ...
                        count--;
                        if (!node->is_m2m && !count)
                                break;
        Log is as attachment

I will paste the test result with problem part in another e-mail

Hi,

This is the first version of RFC patch for Media Data Path 3 (MDP3),
MDP3 is used for scaling and color format conversion.
support using GCE to write register in critical time limitation.
support V4L2 m2m device control.

Moudy Ho (3):
  dt-binding: mt8183: add Mediatek MDP3 dt-bindings
  dts: arm64: mt8183: add Mediatek MDP3 nodes
  media: platform: mtk-mdp3: add Mediatek MDP3 driver

 .../bindings/media/mediatek,mdp3-rdma.yaml    |  193 +++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |   55 +
 .../bindings/media/mediatek,mdp3-wrot.yaml    |   57 +
 .../bindings/soc/mediatek/mediatek,ccorr.yaml |   47 +
 .../bindings/soc/mediatek/mediatek,wdma.yaml  |   58 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  108 +-
 drivers/media/platform/Kconfig                |   20 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/mtk-mdp3/Makefile      |    6 +
 .../media/platform/mtk-mdp3/mdp_reg_ccorr.h   |   19 +
 drivers/media/platform/mtk-mdp3/mdp_reg_isp.h |   27 +
 .../media/platform/mtk-mdp3/mdp_reg_rdma.h    |   65 +
 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h |   39 +
 .../media/platform/mtk-mdp3/mdp_reg_wdma.h    |   47 +
 .../media/platform/mtk-mdp3/mdp_reg_wrot.h    |   55 +
 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h |  280 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   |  515 +++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.h   |   46 +
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 1228 +++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |  147 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  338 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |   76 +
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |  789 +++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.h    |   49 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  737 ++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  372 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    |  312 +++++
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |   78 ++
 28 files changed, 5764 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
 create mode 100644 drivers/media/platform/mtk-mdp3/Makefile
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_ccorr.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_isp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wdma.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
 create mode 100644 drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h

-- 
2.18.0



From moudy.ho at mediatek.com  Wed Jan  5 01:37:57 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Wed, 5 Jan 2022 17:37:57 +0800
Subject: [PATCH v11 2/3] dts: arm64: mt8183: add Mediatek MDP3 nodes
In-Reply-To: <20220105093758.6850-1-moudy.ho@mediatek.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
Message-ID: <20220105093758.6850-3-moudy.ho@mediatek.com>

Add device nodes for Media Data Path 3 (MDP3) modules.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 108 ++++++++++++++++++++++-
 1 file changed, 107 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index ba4584faca5a..b872ef1ff6b3 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1325,6 +1325,79 @@
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
 		};
 
+		mdp3_rdma0: mdp3_rdma0 at 14001000 {
+			compatible = "mediatek,mt8183-mdp3",
+				     "mediatek,mt8183-mdp3-rdma0";
+			mediatek,scp = <&scp>;
+			mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
+					      "mediatek,mt8183-mdp3-dl2",
+					      "mediatek,mt8183-mdp3-path1",
+					      "mediatek,mt8183-mdp3-path2",
+					      "mediatek,mt8183-mdp3-imgi",
+					      "mediatek,mt8183-mdp3-exto";
+			reg = <0 0x14001000 0 0x1000>,
+			      <0 0x14000000 0 0x1000>,
+			      <0 0x14005000 0 0x1000>,
+			      <0 0x14006000 0 0x1000>,
+			      <0 0x15020000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+						  <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+						  <&gce SUBSYS_1502XXXX 0 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+				 <&mmsys CLK_MM_MDP_RSZ1>,
+				 <&mmsys CLK_MM_MDP_DL_TXCK>,
+				 <&mmsys CLK_MM_MDP_DL_RX>,
+				 <&mmsys CLK_MM_IPU_DL_TXCK>,
+				 <&mmsys CLK_MM_IPU_DL_RX>;
+			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
+			mediatek,mmsys = <&mmsys>;
+			mediatek,mm-mutex = <&mutex>;
+			mediatek,mailbox-gce = <&gce>;
+			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
+				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
+				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
+				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;
+			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+				     <&gce 0x14010000 SUBSYS_1401XXXX>,
+				     <&gce 0x14020000 SUBSYS_1402XXXX>,
+				     <&gce 0x15020000 SUBSYS_1502XXXX>;
+		};
+
+		mdp3_rsz0: mdp3_rsz0 at 14003000 {
+			compatible = "mediatek,mt8183-mdp3-rsz0";
+			reg = <0 0x14003000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+		};
+
+		mdp3_rsz1: mdp3_rsz1 at 14004000 {
+			compatible = "mediatek,mt8183-mdp3-rsz1";
+			reg = <0 0x14004000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+		};
+
+		mdp3_wrot0: mdp3_wrot0 at 14005000 {
+			compatible = "mediatek,mt8183-mdp3-wrot0";
+			reg = <0 0x14005000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WROT0>;
+			iommus = <&iommu M4U_PORT_MDP_WROT0>;
+		};
+
+		mdp3_wdma: mdp3_wdma at 14006000 {
+			compatible = "mediatek,mt8183-mdp3-wdma";
+			reg = <0 0x14006000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+			clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+			iommus = <&iommu M4U_PORT_MDP_WDMA0>;
+		};
+
 		ovl0: ovl at 14008000 {
 			compatible = "mediatek,mt8183-disp-ovl";
 			reg = <0 0x14008000 0 0x1000>;
@@ -1449,7 +1522,33 @@
 			interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>;
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			mediatek,gce-events = <CMDQ_EVENT_MUTEX_STREAM_DONE0>,
-					      <CMDQ_EVENT_MUTEX_STREAM_DONE1>;
+					      <CMDQ_EVENT_MUTEX_STREAM_DONE1>,
+					      <CMDQ_EVENT_MDP_RDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_RDMA0_EOF>,
+					      <CMDQ_EVENT_MDP_RSZ0_SOF>,
+					      <CMDQ_EVENT_MDP_RSZ1_SOF>,
+					      <CMDQ_EVENT_MDP_TDSHP_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_SOF>,
+					      <CMDQ_EVENT_MDP_WROT0_EOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_SOF>,
+					      <CMDQ_EVENT_MDP_WDMA0_EOF>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_0>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_1>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_2>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_3>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_4>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_5>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_6>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_7>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_8>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_9>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_10>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_11>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_12>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_13>,
+					      <CMDQ_EVENT_ISP_FRAME_DONE_P2_14>,
+					      <CMDQ_EVENT_WPE_A_DONE>,
+					      <CMDQ_EVENT_SPE_B_DONE>;
 		};
 
 		larb0: larb at 14017000 {
@@ -1473,6 +1572,13 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 		};
 
+		mdp3_ccorr: mdp3_ccorr at 1401c000 {
+			compatible = "mediatek,mt8183-mdp3-ccorr";
+			reg = <0 0x1401c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+			clocks = <&mmsys CLK_MM_MDP_CCORR>;
+		};
+
 		imgsys: syscon at 15020000 {
 			compatible = "mediatek,mt8183-imgsys", "syscon";
 			reg = <0 0x15020000 0 0x1000>;
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 01:41:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 17:41:23 +0800
Subject: [PATCH v4 0/2] Add SCP support for mt8186
Message-ID: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

changes since v3:
 - use rproc-next

changes since v2:
 - remove redundant SoB

changes since v1:
 - use mt8192_power_on_sram() helper
 - add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
 - add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h

Based on rproc-next

Allen-KH Cheng (2):
  dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
  remoteproc: mediatek: Support mt8186 scp

 .../bindings/remoteproc/mtk,scp.yaml          |  1 +
 drivers/remoteproc/mtk_common.h               |  3 ++
 drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
 3 files changed, 39 insertions(+)

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 01:41:24 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 17:41:24 +0800
Subject: [PATCH v4 1/2] dt-bindings: remoteproc: mediatek: Add binding for
 mt8186 scp
In-Reply-To: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
References: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105094125.6917-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add mt8186 compatible to binding document.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index d21a25ee96e6..5b693a2d049c 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-scp
+      - mediatek,mt8186-scp
       - mediatek,mt8192-scp
       - mediatek,mt8195-scp
 
-- 
2.18.0



From moudy.ho at mediatek.com  Wed Jan  5 01:37:56 2022
From: moudy.ho at mediatek.com (Moudy Ho)
Date: Wed, 5 Jan 2022 17:37:56 +0800
Subject: [PATCH v11 1/3] dt-binding: mt8183: add Mediatek MDP3 dt-bindings
In-Reply-To: <20220105093758.6850-1-moudy.ho@mediatek.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
Message-ID: <20220105093758.6850-2-moudy.ho@mediatek.com>

This patch adds DT binding document for Media Data Path 3 (MDP3)
a unit in multimedia system used for scaling and color format convert.

Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
---
 .../bindings/media/mediatek,mdp3-rdma.yaml    | 193 ++++++++++++++++++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |  55 +++++
 .../bindings/media/mediatek,mdp3-wrot.yaml    |  57 ++++++
 .../bindings/soc/mediatek/mediatek,ccorr.yaml |  47 +++++
 .../bindings/soc/mediatek/mediatek,wdma.yaml  |  58 ++++++
 5 files changed, 410 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
new file mode 100644
index 000000000000..002503383934
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
@@ -0,0 +1,193 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Read Direct Memory Access
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  Mediatek Read Direct Memory Access(RDMA) component used to do read DMA.
+  It contains one line buffer to store the sufficient pixel data, and
+  must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+  The 1st RDMA is also used to be a controller node in Media Data Path 3(MDP3)
+  that containing MMSYS, MUTEX, GCE and SCP settings.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          # MDP3 controller node
+          - const: mediatek,mt8183-mdp3
+          - const: mediatek,mt8183-mdp3-rdma0
+      - items:
+          # normal RDMA conponent
+          - const: mediatek,mt8183-mdp3-rdma0
+
+  mediatek,scp:
+    description: The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+
+  mediatek,mdp3-comps:
+    description: MTK sub-system of direct-link or DIP
+    $ref: /schemas/types.yaml#/definitions/string-array
+    items:
+      - enum:
+          # MDP direct-link input path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-dl1
+      - enum:
+          - mediatek,mt8183-mdp3-dl2
+      - enum:
+          # MDP direct-link output path selection, create a
+          # component for path connectedness of HW pipe control
+          - mediatek,mt8183-mdp3-path1
+      - enum:
+          - mediatek,mt8183-mdp3-path2
+      - enum:
+          # Input DMA of ISP PASS2 (DIP) module for raw image input
+          - mediatek,mt8183-mdp3-imgi
+      - enum:
+          # Output DMA of ISP PASS2 (DIP) module for YUV image output
+          - mediatek,mt8183-mdp3-exto
+
+  reg:
+    items:
+      - description: basic RDMA HW address
+      - description: MDP direct-link 1st and 2nd input
+      - description: MDP direct-link 1st output
+      - description: MDP direct-link 2nd output
+      - description: ISP input and output
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - description: GCE client for RDMA
+      - description: GCR client for MDP direct-link 1st and 2nd input
+      - description: GCR client for MDP direct-link 1st output
+      - description: GCR client for MDP direct-link 2nd output
+      - description: GCR client for ISP input and output
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: RDMA clock
+      - description: RSZ clock
+      - description: direck-link TX clock in MDP side
+      - description: direck-link RX clock in MDP side
+      - description: direck-link TX clock in ISP side
+      - description: direck-link RX clock in ISP side
+
+  iommus:
+    maxItems: 1
+
+  mediatek,mmsys:
+    description: The node of mux(multiplexer) controller for HW connections.
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  mediatek,mm-mutex:
+    description: The node of sof(start of frame) signal controller.
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+
+  mediatek,mailbox-gce:
+    description: The node of global command engine (GCE), used to read/write
+      registers with critical time limitation.
+    $ref: /schemas/types.yaml#/definitions/phandle
+
+  mboxes:
+    items:
+      - description: used for 1st data pipe from RDMA
+      - description: used for 2nd data pipe from RDMA
+      - description: used for 3rd data pipe from Direct-Link
+      - description: used for 4th data pipe from Direct-Link
+
+  gce-subsys:
+    description: sub-system id corresponding to the global command engine (GCE)
+      register address.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: mediatek,mt8183-mdp3
+
+then:
+  required:
+    - mediatek,scp
+    - mediatek,mmsys
+    - mediatek,mm-mutex
+    - mediatek,mailbox-gce
+    - mboxes
+    - gce-subsys
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - mediatek,gce-client-reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_rdma0: mdp3_rdma0 at 14001000 {
+      compatible = "mediatek,mt8183-mdp3",
+                   "mediatek,mt8183-mdp3-rdma0";
+      mediatek,scp = <&scp>;
+      mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
+                            "mediatek,mt8183-mdp3-dl2",
+                            "mediatek,mt8183-mdp3-path1",
+                            "mediatek,mt8183-mdp3-path2",
+                            "mediatek,mt8183-mdp3-imgi",
+                            "mediatek,mt8183-mdp3-exto";
+      reg = <0x14001000 0x1000>,
+            <0x14000000 0x1000>,
+            <0x14005000 0x1000>,
+            <0x14006000 0x1000>,
+            <0x15020000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
+                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
+                                <&gce SUBSYS_1502XXXX 0 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
+               <&mmsys CLK_MM_MDP_RSZ1>,
+               <&mmsys CLK_MM_MDP_DL_TXCK>,
+               <&mmsys CLK_MM_MDP_DL_RX>,
+               <&mmsys CLK_MM_IPU_DL_TXCK>,
+               <&mmsys CLK_MM_IPU_DL_RX>;
+      iommus = <&iommu>;
+      mediatek,mmsys = <&mmsys>;
+      mediatek,mm-mutex = <&mutex>;
+      mediatek,mailbox-gce = <&gce>;
+      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
+               <&gce 21 CMDQ_THR_PRIO_LOWEST>,
+               <&gce 22 CMDQ_THR_PRIO_LOWEST>,
+               <&gce 23 CMDQ_THR_PRIO_LOWEST>;
+      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
+                   <&gce 0x14010000 SUBSYS_1401XXXX>,
+                   <&gce 0x14020000 SUBSYS_1402XXXX>,
+                   <&gce 0x15020000 SUBSYS_1502XXXX>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
new file mode 100644
index 000000000000..cd4cf1531535
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Resizer
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to do frame resizing.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8183-mdp3-rsz0
+          - mediatek,mt8183-mdp3-rsz1
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_rsz0: mdp3_rsz0 at 14003000 {
+      compatible = "mediatek,mt8183-mdp3-rsz0";
+      reg = <0x14003000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ0>;
+    };
+
+    mdp3_rsz1: mdp3_rsz1 at 14004000 {
+      compatible = "mediatek,mt8183-mdp3-rsz1";
+      reg = <0x14004000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x4000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_RSZ1>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
new file mode 100644
index 000000000000..7b0f9c4fffd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-wrot.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Write DMA with Rotation
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to write DMA with frame rotation.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8183-mdp3-wrot0
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    maxItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wrot0: mdp3_wrot0 at 14005000 {
+      compatible = "mediatek,mt8183-mdp3-wrot0";
+      reg = <0x14005000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WROT0>;
+      iommus = <&iommu>;
+    };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..cf23f4f5bd69
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek color correction
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  Mediatek color correction with 3X3 matrix.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8183-mdp3-ccorr
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+
+    mdp3_ccorr: mdp3_ccorr at 1401c000 {
+      compatible = "mediatek,mt8183-mdp3-ccorr";
+      reg = <0x1401c000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
+      clocks = <&mmsys CLK_MM_MDP_CCORR>;
+    };
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..4057b5232e45
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Write Direct Memory Access
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  Mediatek Write Direct Memory Access(WDMA) component used to write
+  the data into DMA.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8183-mdp3-wdma
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+
+  iommus:
+    maxItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/gce/mt8183-gce.h>
+    #include <dt-bindings/power/mt8183-power.h>
+    #include <dt-bindings/memory/mt8183-larb-port.h>
+
+    mdp3_wdma: mdp3_wdma at 14006000 {
+      compatible = "mediatek,mt8183-mdp3-wdma";
+      reg = <0x14006000 0x1000>;
+      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x6000 0x1000>;
+      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+      clocks = <&mmsys CLK_MM_MDP_WDMA0>;
+      iommus = <&iommu>;
+    };
-- 
2.18.0



From andy.shevchenko at gmail.com  Wed Jan  5 01:46:27 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Wed, 5 Jan 2022 11:46:27 +0200
Subject: [PATCH v5] soc: ti: smartreflex: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <20220104164504.24707-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104164504.24707-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAHp75Ve+0VmfU7GhC=AjZ3J1J6KtGko2YAenA9mXCSCVrcuX5w@mail.gmail.com>

On Tue, Jan 4, 2022 at 6:45 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
>
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq_optional().
>
> While at it return 0 instead of returning ret in the probe success path.

...

> +       ret = platform_get_irq_optional(pdev, 0);
> +       if (ret < 0 && ret != -ENXIO)
> +               return dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);

Sorry, I haven't noticed that you are using __func__ in the message.
Please don't. It shows either that the message is not unique (so make
the message unique enough in this driver) or the redundancy of the
__func__ (it doesn't add any value, but noise).

> +       if (ret > 0)
> +               sr_info->irq = ret;


-- 
With Best Regards,
Andy Shevchenko


From allen-kh.cheng at mediatek.com  Wed Jan  5 01:41:25 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 5 Jan 2022 17:41:25 +0800
Subject: [PATCH v4 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
References: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220105094125.6917-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add SCP support for mt8186

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/remoteproc/mtk_common.h |  3 +++
 drivers/remoteproc/mtk_scp.c    | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 5ff3867c72f3..71ce4977cb0b 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -32,6 +32,9 @@
 #define MT8183_SCP_CACHESIZE_8KB	BIT(8)
 #define MT8183_SCP_CACHE_CON_WAYEN	BIT(10)
 
+#define MT8186_SCP_L1_SRAM_PD_P1	0x40B0
+#define MT8186_SCP_L1_SRAM_PD_p2	0x40B4
+
 #define MT8192_L2TCM_SRAM_PD_0		0x10C0
 #define MT8192_L2TCM_SRAM_PD_1		0x10C4
 #define MT8192_L2TCM_SRAM_PD_2		0x10C8
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..6860ea4d5125 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -383,6 +383,27 @@ static void mt8192_power_off_sram(void __iomem *addr)
 		writel(GENMASK(i, 0), addr);
 }
 
+static int mt8186_scp_before_load(struct mtk_scp *scp)
+{
+	/* Clear SCP to host interrupt */
+	writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+	/* Reset clocks before loading FW */
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+	/* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
+	mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+	/* Initialize TCM before loading FW. */
+	writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2);
+
+	return 0;
+}
+
 static int mt8192_scp_before_load(struct mtk_scp *scp)
 {
 	/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -887,6 +908,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 	.ipi_buf_offset = 0x7bdb0,
 };
 
+static const struct mtk_scp_of_data mt8186_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
+	.scp_before_load = mt8186_scp_before_load,
+	.scp_irq_handler = mt8183_scp_irq_handler,
+	.scp_reset_assert = mt8183_scp_reset_assert,
+	.scp_reset_deassert = mt8183_scp_reset_deassert,
+	.scp_stop = mt8183_scp_stop,
+	.scp_da_to_va = mt8183_scp_da_to_va,
+	.host_to_scp_reg = MT8183_HOST_TO_SCP,
+	.host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT,
+	.ipi_buf_offset = 0x7bdb0,
+};
+
 static const struct mtk_scp_of_data mt8192_of_data = {
 	.scp_clk_get = mt8192_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
@@ -913,6 +947,7 @@ static const struct mtk_scp_of_data mt8195_of_data = {
 
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
+	{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
 	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
-- 
2.18.0



From andy.shevchenko at gmail.com  Wed Jan  5 01:56:05 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Wed, 5 Jan 2022 11:56:05 +0200
Subject: [PATCH v2 0/3] dmaengine: Use platform_get_irq*() variants to
 fetch IRQ's
In-Reply-To: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAHp75VdUYsGHbhkJoXifTPaY5GbHaiGf4nG1rYpo9=7KhfujDw@mail.gmail.com>

On Tue, Jan 4, 2022 at 6:35 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
>
> Hi All,
>
> This patch series aims to drop using platform_get_resource() for IRQ types
> in preparation for removal of static setup of IRQ resource from DT core
> code.
>
> Dropping usage of platform_get_resource() was agreed based on
> the discussion [0].


All three looks good to me, FWIW,
Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>

> [0] https://patchwork.kernel.org/project/linux-renesas-soc/
> patch/20211209001056.29774-1-prabhakar.mahadev-lad.rj at bp.renesas.com/
>
> Cheers,
> Prabhakar
>
> Lad Prabhakar (3):
>   dmaengine: nbpfaxi: Use platform_get_irq_optional() to get the
>     interrupt
>   dmaengine: mediatek: mtk-hsdma: Use platform_get_irq() to get the
>     interrupt
>   dmaengine: mediatek-cqdma: Use platform_get_irq() to get the interrupt
>
>  drivers/dma/mediatek/mtk-cqdma.c | 12 ++++--------
>  drivers/dma/mediatek/mtk-hsdma.c | 11 ++++-------
>  drivers/dma/nbpfaxi.c            | 14 ++++++--------
>  3 files changed, 14 insertions(+), 23 deletions(-)
>
> --
> 2.17.1
>


-- 
With Best Regards,
Andy Shevchenko


From angelogioacchino.delregno at collabora.com  Wed Jan  5 01:58:39 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 5 Jan 2022 10:58:39 +0100
Subject: [PATCH v20 3/7] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <20210721070904.15636-4-roger.lu@mediatek.com>
References: <20210721070904.15636-1-roger.lu@mediatek.com>
 <20210721070904.15636-4-roger.lu@mediatek.com>
Message-ID: <1480efdf-ed94-8bda-7bea-a657eddae45d@collabora.com>

Il 21/07/21 09:09, Roger Lu ha scritto:
> The Smart Voltage Scaling(SVS) engine is a piece of hardware
> which calculates suitable SVS bank voltages to OPP voltage table.
> Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
> when receiving OPP_EVENT_ADJUST_VOLTAGE.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>

Hello Roger,
thanks for the patch!

However, there are a few things to improve...

> ---
>   drivers/soc/mediatek/Kconfig   |   10 +
>   drivers/soc/mediatek/Makefile  |    1 +
>   drivers/soc/mediatek/mtk-svs.c | 1720 ++++++++++++++++++++++++++++++++
>   3 files changed, 1731 insertions(+)
>   create mode 100644 drivers/soc/mediatek/mtk-svs.c
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index fdd8bc08569e..3c3eedea35f7 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -73,4 +73,14 @@ config MTK_MMSYS
>   	  Say yes here to add support for the MediaTek Multimedia
>   	  Subsystem (MMSYS).
>   
> +config MTK_SVS
> +	tristate "MediaTek Smart Voltage Scaling(SVS)"
> +	depends on MTK_EFUSE && NVMEM
> +	help
> +	  The Smart Voltage Scaling(SVS) engine is a piece of hardware
> +	  which has several controllers(banks) for calculating suitable
> +	  voltage to different power domains(CPU/GPU/CCI) according to
> +	  chip process corner, temperatures and other factors. Then DVFS
> +	  driver could apply SVS bank voltage to PMIC/Buck.
> +
>   endmenu
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 90270f8114ed..0e9e703c931a 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
>   obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
> +obj-$(CONFIG_MTK_SVS) += mtk-svs.o
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> new file mode 100644
> index 000000000000..013667752ec2
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-svs.c
> @@ -0,0 +1,1720 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/kthread.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_opp.h>
> +#include <linux/pm_qos.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/reset.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +#include <linux/thermal.h>
> +
> +/* svs bank 1-line sw id */
> +#define SVSB_CPU_LITTLE			BIT(0)
> +#define SVSB_CPU_BIG			BIT(1)
> +#define SVSB_CCI			BIT(2)
> +#define SVSB_GPU			BIT(3)
> +
> +/* svs bank mode support */
> +#define SVSB_MODE_ALL_DISABLE		0
> +#define SVSB_MODE_INIT01		BIT(1)
> +#define SVSB_MODE_INIT02		BIT(2)
> +#define SVSB_MODE_MON			BIT(3)
> +
> +/* svs bank volt flags */
> +#define SVSB_INIT01_VOLT_IGNORE		BIT(1)
> +#define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
> +#define SVSB_INIT02_RM_DVTFIXED		BIT(8)
> +#define SVSB_MON_VOLT_IGNORE		BIT(16)
> +
> +/* svs bank common setting */
> +#define SVSB_DET_CLK_EN			BIT(31)
> +#define SVSB_TZONE_HIGH_TEMP_MAX	U32_MAX
> +#define SVSB_RUNCONFIG_DEFAULT		0x80000000
> +#define SVSB_DC_SIGNED_BIT		0x8000

SVSB_DC_SIGNED_BIT is.. clearly a bit, so this should be BIT(15)

> +#define SVSB_INTEN_INIT0x		0x00005f01
> +#define SVSB_INTEN_MONVOPEN		0x00ff0000
> +#define SVSB_EN_OFF			0x0
> +#define SVSB_EN_MASK			0x7
> +#define SVSB_EN_INIT01			0x1
> +#define SVSB_EN_INIT02			0x5
> +#define SVSB_EN_MON			0x2
> +#define SVSB_INTSTS_MONVOP		0x00ff0000
> +#define SVSB_INTSTS_COMPLETE		0x1
> +#define SVSB_INTSTS_CLEAN		0x00ffffff
> +
> +static DEFINE_SPINLOCK(mtk_svs_lock);
> +
> +/*

Looks like the great intention is to have kernel-doc here, and it's already
in the right format, but the start of the comment block should be

/**

and not

/*

to be recognized as kerneldoc.
Please refer to https://www.kernel.org/doc/html/v5.15/doc-guide/kernel-doc.html

> + * enum svsb_phase - svs bank phase enumeration
> + * @SVSB_PHASE_INIT01: basic init for svs bank
> + * @SVSB_PHASE_INIT02: svs bank can provide voltages
> + * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
> + * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition

Please move @SVSB_PHASE_ERROR before @SVSB_PHASE_INIT01: the order

is important here, and has to be the same as the actual enumeration.

> + *
> + * Each svs bank has its own independent phase. We enable each svs bank by
> + * running their phase orderly. However, When svs bank encounters unexpected
> + * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
> + *
> + * svs bank general phase-enabled order:
> + * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
> + */
> +enum svsb_phase {
> +	SVSB_PHASE_ERROR = 0,
> +	SVSB_PHASE_INIT01,
> +	SVSB_PHASE_INIT02,
> +	SVSB_PHASE_MON,
> +};
> +
> +enum svs_reg_index {
> +	DESCHAR = 0,
> +	TEMPCHAR,
> +	DETCHAR,
> +	AGECHAR,
> +	DCCONFIG,
> +	AGECONFIG,
> +	FREQPCT30,
> +	FREQPCT74,
> +	LIMITVALS,
> +	VBOOT,
> +	DETWINDOW,
> +	CONFIG,
> +	TSCALCS,
> +	RUNCONFIG,
> +	SVSEN,
> +	INIT2VALS,
> +	DCVALUES,
> +	AGEVALUES,
> +	VOP30,
> +	VOP74,
> +	TEMP,
> +	INTSTS,
> +	INTSTSRAW,
> +	INTEN,
> +	CHKINT,
> +	CHKSHIFT,
> +	STATUS,
> +	VDESIGN30,
> +	VDESIGN74,
> +	DVT30,
> +	DVT74,
> +	AGECOUNT,
> +	SMSTATE0,
> +	SMSTATE1,
> +	CTL0,
> +	DESDETSEC,
> +	TEMPAGESEC,
> +	CTRLSPARE0,
> +	CTRLSPARE1,
> +	CTRLSPARE2,
> +	CTRLSPARE3,
> +	CORESEL,
> +	THERMINTST,
> +	INTST,
> +	THSTAGE0ST,
> +	THSTAGE1ST,
> +	THSTAGE2ST,
> +	THAHBST0,
> +	THAHBST1,
> +	SPARE0,
> +	SPARE1,
> +	SPARE2,
> +	SPARE3,
> +	THSLPEVEB,
> +};
> +
> +static const u32 svs_regs_v2[] = {
> +	[DESCHAR]		= 0xc00,
> +	[TEMPCHAR]		= 0xc04,
> +	[DETCHAR]		= 0xc08,
> +	[AGECHAR]		= 0xc0c,
> +	[DCCONFIG]		= 0xc10,
> +	[AGECONFIG]		= 0xc14,
> +	[FREQPCT30]		= 0xc18,
> +	[FREQPCT74]		= 0xc1c,
> +	[LIMITVALS]		= 0xc20,
> +	[VBOOT]			= 0xc24,
> +	[DETWINDOW]		= 0xc28,
> +	[CONFIG]		= 0xc2c,
> +	[TSCALCS]		= 0xc30,
> +	[RUNCONFIG]		= 0xc34,
> +	[SVSEN]			= 0xc38,
> +	[INIT2VALS]		= 0xc3c,
> +	[DCVALUES]		= 0xc40,
> +	[AGEVALUES]		= 0xc44,
> +	[VOP30]			= 0xc48,
> +	[VOP74]			= 0xc4c,
> +	[TEMP]			= 0xc50,
> +	[INTSTS]		= 0xc54,
> +	[INTSTSRAW]		= 0xc58,
> +	[INTEN]			= 0xc5c,
> +	[CHKINT]		= 0xc60,
> +	[CHKSHIFT]		= 0xc64,
> +	[STATUS]		= 0xc68,
> +	[VDESIGN30]		= 0xc6c,
> +	[VDESIGN74]		= 0xc70,
> +	[DVT30]			= 0xc74,
> +	[DVT74]			= 0xc78,
> +	[AGECOUNT]		= 0xc7c,
> +	[SMSTATE0]		= 0xc80,
> +	[SMSTATE1]		= 0xc84,
> +	[CTL0]			= 0xc88,
> +	[DESDETSEC]		= 0xce0,
> +	[TEMPAGESEC]		= 0xce4,
> +	[CTRLSPARE0]		= 0xcf0,
> +	[CTRLSPARE1]		= 0xcf4,
> +	[CTRLSPARE2]		= 0xcf8,
> +	[CTRLSPARE3]		= 0xcfc,
> +	[CORESEL]		= 0xf00,
> +	[THERMINTST]		= 0xf04,
> +	[INTST]			= 0xf08,
> +	[THSTAGE0ST]		= 0xf0c,
> +	[THSTAGE1ST]		= 0xf10,
> +	[THSTAGE2ST]		= 0xf14,
> +	[THAHBST0]		= 0xf18,
> +	[THAHBST1]		= 0xf1c,
> +	[SPARE0]		= 0xf20,
> +	[SPARE1]		= 0xf24,
> +	[SPARE2]		= 0xf28,
> +	[SPARE3]		= 0xf2c,
> +	[THSLPEVEB]		= 0xf30,
> +};
> +
> +/*
> + * struct thermal_parameter - This is for storing thermal efuse data.
> + * We calculate thermal efuse data to produce "mts" and "bts" for
> + * svs bank mon mode.
> + */
> +struct thermal_parameter {
> +	int adc_ge_t;
> +	int adc_oe_t;
> +	int ge;
> +	int oe;
> +	int gain;
> +	int o_vtsabb;
> +	int o_vtsmcu1;
> +	int o_vtsmcu2;
> +	int o_vtsmcu3;
> +	int o_vtsmcu4;
> +	int o_vtsmcu5;
> +	int degc_cali;
> +	int adc_cali_en_t;
> +	int o_slope;
> +	int o_slope_sign;
> +	int ts_id;
> +};
> +
> +/*

... same here, /** for kerneldoc

> + * struct svs_platform - svs platform data
> + * @dev: svs platform device
> + * @base: svs platform register address base
> + * @main_clk: main clock for svs bank
> + * @pbank: phandle of svs bank and needs to be protected by spin_lock
> + * @banks: phandle of the banks that support
> + * @efuse_parsing: phandle of efuse parsing function
> + * @irqflags: irq settings flags
> + * @rst: svs reset control
> + * @regs: phandle to the registers map

@name should be here

> + * @efuse_num: the total number of svs platform efuse
> + * @tefuse_num: the total number of thermal efuse
> + * @bank_num: the total number of banks
> + * @efuse_check: the svs efuse check index
> + * @efuse: svs platform efuse data received from NVMEM framework
> + * @tefuse: thermal efuse data received from NVMEM framework
> + * @name: svs platform name
> + */
> +struct svs_platform {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct clk *main_clk;
> +	struct svs_bank *pbank;
> +	struct svs_bank *banks;
> +	bool (*efuse_parsing)(struct svs_platform *svsp);
> +	unsigned long irqflags;
> +	struct reset_control *rst;
> +	const u32 *regs;
> +	char *name;
> +	size_t efuse_num;
> +	size_t tefuse_num;
> +	u32 bank_num;
> +	u32 efuse_check;
> +	u32 *efuse;
> +	u32 *tefuse;
> +};
> +
> +/*

... and here

> + * struct svs_bank - svs bank representation
> + * @dev: svs bank device
> + * @opp_dev: device for opp table/buck control
> + * @pd_dev: power domain device for SoC mtcmos control
> + * @init_completion: the timeout completion for bank init
> + * @buck: phandle of the regulator
> + * @lock: mutex lock to protect voltage update process
> + * @phase: bank current phase
> + * @name: bank name
> + * @tzone_name: thermal zone name
> + * @buck_name: regulator name
> + * @suspended: suspend flag of this bank
> + * @pd_req: bank's power-domain on request
> + * @enable_pm_runtime_ever: bank enables pm-runtime flag
> + * @set_freqs_pct: phandle of set frequencies percent function
> + * @get_vops: phandle of get bank voltages function
> + * @volt_offset: bank voltage offset controlled by svs software
> + * @mode_support: bank mode support.
> + * @opp_freqs: signed-off frequencies from default opp table
> + * @opp_volts: signed-off voltages from default opp table
> + * @freqs_pct: percent of "opp_freqs / freq_base" for bank init
> + * @volts: bank voltages
> + * @freq_base: reference frequency for bank init
> + * @vboot: voltage request for bank init01 stage only
> + * @volt_step: bank voltage step
> + * @volt_base: bank voltage base
> + * @volt_flags: bank voltage flags
> + * @vmax: bank voltage maximum
> + * @vmin: bank voltage minimum

I love when developers take the effort to document with kerneldoc, so, great job
about that.... however, you forgot to document a few variables... can you please
add the required documentation for them?

> + * @temp: bank temperature
> + * @temp_upper_bound: bank temperature upper bound
> + * @temp_lower_bound: bank temperature lower bound
> + * @tzone_high_temp: thermal zone high temperature threshold
> + * @tzone_high_temp_offset: thermal zone high temperature offset
> + * @tzone_low_temp: thermal zone low temperature threshold
> + * @tzone_low_temp_offset: thermal zone low temperature offset
> + * @core_sel: bank selection
> + * @opp_count: bank opp count
> + * @int_st: bank interrupt identification
> + * @sw_id: bank software identification
> + * @ctl0: bank thermal sensor selection
> + * @cpu_id: cpu core id for SVS CPU only
> + *
> + * Other structure members which are not listed above are svs platform
> + * efuse data for bank init
> + */
> +struct svs_bank {
> +	struct device *dev;
> +	struct device *opp_dev;
> +	struct device *pd_dev;
> +	struct completion init_completion;
> +	struct regulator *buck;
> +	struct mutex lock;	/* lock to protect voltage update process */
> +	enum svsb_phase phase;
> +	char *name;
> +	char *tzone_name;
> +	char *buck_name;
> +	bool suspended;
> +	bool pd_req;
> +	bool enable_pm_runtime_ever;
> +	void (*set_freqs_pct)(struct svs_platform *svsp);
> +	void (*get_vops)(struct svs_platform *svsp);
> +	s32 volt_offset;
> +	u32 mode_support;
> +	u32 opp_freqs[16];

At the beginning of the file....
#define MAX_OPP_ENTRIES 16

...so you can do...
	u32 opp_freqs[MAX_OPP_ENTRIES];
	u32 opp_volts[MAX_OPP_ENTRIES];
...and the same for the other two.

> +	u32 opp_volts[16];
> +	u32 freqs_pct[16];
> +	u32 volts[16];
> +	u32 freq_base;
> +	u32 vboot;
> +	u32 volt_step;
> +	u32 volt_base;
> +	u32 volt_flags;
> +	u32 vmax;
> +	u32 vmin;

Document these entries, please.

vvvvvvvvv From here.... vvvvvvvvv

> +	u32 bts;
> +	u32 mts;
> +	u32 bdes;
> +	u32 mdes;
> +	u32 mtdes;
> +	u32 dcbdet;
> +	u32 dcmdet;
> +	u32 dthi;
> +	u32 dtlo;
> +	u32 det_window;
> +	u32 det_max;
> +	u32 age_config;
> +	u32 age_voffset_in;
> +	u32 agem;
> +	u32 dc_config;
> +	u32 dc_voffset_in;
> +	u32 dvt_fixed;
> +	u32 vco;
> +	u32 chk_shift;

^^^^^^^^^ ....to there ^^^^^^^^^

> +	u32 temp;
> +	u32 temp_upper_bound;
> +	u32 temp_lower_bound;
> +	u32 tzone_high_temp;
> +	u32 tzone_high_temp_offset;
> +	u32 tzone_low_temp;
> +	u32 tzone_low_temp_offset;
> +	u32 core_sel;
> +	u32 opp_count;
> +	u32 int_st;
> +	u32 sw_id;
> +	u32 ctl0;
> +	u32 cpu_id;
> +};
> +
> +static u32 percent(u32 numerator, u32 denominator)
> +{
> +	/* If not divide 1000, "numerator * 100" will have data overflow. */
> +	numerator /= 1000;
> +	denominator /= 1000;
> +
> +	return DIV_ROUND_UP(numerator * 100, denominator);
> +}
> +
> +static u32 svs_readl(struct svs_platform *svsp, enum svs_reg_index rg_i)
> +{
> +	return readl(svsp->base + svsp->regs[rg_i]);
> +}
> +
> +static void svs_writel(struct svs_platform *svsp, u32 val,
> +		       enum svs_reg_index rg_i)
> +{
> +	writel(val, svsp->base + svsp->regs[rg_i]);
> +}
> +
> +static void svs_switch_bank(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	svs_writel(svsp, svsb->core_sel, CORESEL);
> +}
> +
> +static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
> +				     u32 svsb_volt_base)
> +{
> +	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
> +}
> +
> +static int svs_get_bank_zone_temperature(const char *tzone_name,
> +					 int *tzone_temp)
> +{
> +	struct thermal_zone_device *tzd;
> +
> +	tzd = thermal_zone_get_zone_by_name(tzone_name);
> +	if (IS_ERR(tzd))
> +		return PTR_ERR(tzd);
> +
> +	return thermal_zone_get_temp(tzd, tzone_temp);
> +}
> +
> +static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
> +{
> +	int tzone_temp = 0, ret = -EPERM;
> +	u32 i, svsb_volt, opp_volt, temp_offset = 0;
> +
> +	mutex_lock(&svsb->lock);
> +
> +	/*
> +	 * If svs bank is suspended, it means signed-off voltages are applied.
> +	 * Don't need to update opp voltage anymore.
> +	 */
> +	if (svsb->suspended && !force_update) {
> +		dev_notice(svsb->dev, "bank is suspended\n");
> +		ret = -EPERM;
> +		goto unlock_mutex;
> +	}
> +
> +	/* Get thermal effect */
> +	if (svsb->phase == SVSB_PHASE_MON) {
> +		if (svsb->temp > svsb->temp_upper_bound &&
> +		    svsb->temp < svsb->temp_lower_bound) {
> +			dev_warn(svsb->dev, "svsb temp = 0x%x?\n", svsb->temp);
> +			ret = -EINVAL;
> +			goto unlock_mutex;
> +		}
> +
> +		ret = svs_get_bank_zone_temperature(svsb->tzone_name,
> +						    &tzone_temp);
> +		if (ret) {
> +			dev_err(svsb->dev, "no %s? (%d), run default volts\n",
> +				svsb->tzone_name, ret);
> +			svsb->phase = SVSB_PHASE_ERROR;
> +		}
> +
> +		if (tzone_temp >= svsb->tzone_high_temp)
> +			temp_offset += svsb->tzone_high_temp_offset;
> +		else if (tzone_temp <= svsb->tzone_low_temp)
> +			temp_offset += svsb->tzone_low_temp_offset;
> +	}
> +
> +	/* vmin <= svsb_volt (opp_volt) <= signed-off (default) voltage */
> +	for (i = 0; i < svsb->opp_count; i++) {



What about using switch here?



         switch (svsb->phase) {

         case SVSB_PHASE_MON:

             ......

             break;

         case .......:

             .........

             break;

         default:

             dev_err(......);

             ret = -EINVAL;

             goto unlock_mutex;

         }

> +		if (svsb->phase == SVSB_PHASE_MON) {
> +			svsb_volt = max(svsb->volts[i] + svsb->volt_offset +
> +					temp_offset, svsb->vmin);
> +			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
> +							     svsb->volt_step,
> +							     svsb->volt_base);
> +		} else if (svsb->phase == SVSB_PHASE_INIT02) {
> +			svsb_volt = max(svsb->volts[i] + svsb->volt_offset,
> +					svsb->vmin);
> +			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
> +							     svsb->volt_step,
> +							     svsb->volt_base);
> +		} else if (svsb->phase == SVSB_PHASE_ERROR) {
> +			opp_volt = svsb->opp_volts[i];
> +		} else {
> +			dev_err(svsb->dev, "unknown phase: %u?\n", svsb->phase);
> +			ret = -EINVAL;
> +			goto unlock_mutex;
> +		}
> +
> +		opp_volt = min(opp_volt, svsb->opp_volts[i]);
> +		ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
> +						svsb->opp_freqs[i],
> +						opp_volt, opp_volt,
> +						svsb->opp_volts[i]);
> +		if (ret) {
> +			dev_err(svsb->dev, "set voltage fail: %d\n", ret);
> +			goto unlock_mutex;
> +		}
> +	}
> +
> +unlock_mutex:
> +	mutex_unlock(&svsb->lock);
> +
> +	return ret;
> +}
> +
> +static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
> +{
> +	u32 vx;
> +
> +	if (v0 == v1 || f0 == f1)
> +		return v0;
> +
> +	/* *100 to have decimal fraction factor */
> +	vx = (v0 * 100) - ((((v0 - v1) * 100) / (f0 - f1)) * (f0 - fx));
> +
> +	return DIV_ROUND_UP(vx, 100);
> +}
> +
> +static void svs_get_vops_v2(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +	u32 temp, i;
> +
> +	if (svsb->phase == SVSB_PHASE_MON &&
> +	    svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
> +		return;
> +
> +	temp = svs_readl(svsp, VOP74);
> +	svsb->volts[14] = (temp >> 24) & GENMASK(7, 0);
> +	svsb->volts[12] = (temp >> 16) & GENMASK(7, 0);
> +	svsb->volts[10] = (temp >> 8)  & GENMASK(7, 0);
> +	svsb->volts[8] = (temp & GENMASK(7, 0));
> +
> +	temp = svs_readl(svsp, VOP30);
> +	svsb->volts[6] = (temp >> 24) & GENMASK(7, 0);
> +	svsb->volts[4] = (temp >> 16) & GENMASK(7, 0);
> +	svsb->volts[2] = (temp >> 8)  & GENMASK(7, 0);
> +	svsb->volts[0] = (temp & GENMASK(7, 0));
> +
> +	for (i = 0; i <= 12; i += 2)
> +		svsb->volts[i + 1] =
> +			interpolate(svsb->freqs_pct[i],
> +				    svsb->freqs_pct[i + 2],
> +				    svsb->volts[i],
> +				    svsb->volts[i + 2],
> +				    svsb->freqs_pct[i + 1]);
> +
> +	svsb->volts[15] =
> +		interpolate(svsb->freqs_pct[12],
> +			    svsb->freqs_pct[14],
> +			    svsb->volts[12],
> +			    svsb->volts[14],
> +			    svsb->freqs_pct[15]);
> +
> +	if (svsb->volt_flags & SVSB_INIT02_RM_DVTFIXED)
> +		for (i = 0; i < svsb->opp_count; i++)
> +			svsb->volts[i] -= svsb->dvt_fixed;
> +}
> +
> +static void svs_set_freqs_pct_v2(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	svs_writel(svsp,
> +		   (svsb->freqs_pct[14] << 24) |
> +		   (svsb->freqs_pct[12] << 16) |
> +		   (svsb->freqs_pct[10] << 8) |
> +		   svsb->freqs_pct[8],
> +		   FREQPCT74);
> +
> +	svs_writel(svsp,
> +		   (svsb->freqs_pct[6] << 24) |
> +		   (svsb->freqs_pct[4] << 16) |
> +		   (svsb->freqs_pct[2] << 8) |
> +		   svsb->freqs_pct[0],
> +		   FREQPCT30);
> +}
> +
> +static void svs_set_bank_phase(struct svs_platform *svsp,
> +			       enum svsb_phase target_phase)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +	u32 des_char, temp_char, det_char, limit_vals;
> +	u32 init2vals, ts_calcs, val, filter, i;
> +
> +	svs_switch_bank(svsp);
> +
> +	des_char = (svsb->bdes << 8) | svsb->mdes;
> +	svs_writel(svsp, des_char, DESCHAR);
> +
> +	temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed;
> +	svs_writel(svsp, temp_char, TEMPCHAR);
> +
> +	det_char = (svsb->dcbdet << 8) | svsb->dcmdet;
> +	svs_writel(svsp, det_char, DETCHAR);
> +
> +	svs_writel(svsp, svsb->dc_config, DCCONFIG);
> +	svs_writel(svsp, svsb->age_config, AGECONFIG);
> +
> +	if (!svsb->agem) {
> +		svs_writel(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);
> +	} else {
> +		val = 0x0;

val = 0;

> +
> +		for (i = 0; i < 24; i += 2) {
> +			filter = 0x3 << i;
> +
> +			if (!(svsb->age_config & filter))
> +				val |= (0x1 << i);

val |= BIT(i);

> +			else
> +				val |= (svsb->age_config & filter);
> +		}
> +		svs_writel(svsp, val, RUNCONFIG);
> +	}
> +
> +	svsb->set_freqs_pct(svsp);
> +
> +	limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) |
> +		     (svsb->dthi << 8) | svsb->dtlo;
> +	svs_writel(svsp, limit_vals, LIMITVALS);
> +	svs_writel(svsp, svsb->vboot, VBOOT);
> +	svs_writel(svsp, svsb->det_window, DETWINDOW);
> +	svs_writel(svsp, svsb->det_max, CONFIG);
> +
> +	if (svsb->chk_shift)
> +		svs_writel(svsp, svsb->chk_shift, CHKSHIFT);
> +
> +	if (svsb->ctl0)
> +		svs_writel(svsp, svsb->ctl0, CTL0);
> +
> +	svs_writel(svsp, SVSB_INTSTS_CLEAN, INTSTS);
> +
> +	switch (target_phase) {
> +	case SVSB_PHASE_INIT01:
> +		svs_writel(svsp, SVSB_INTEN_INIT0x, INTEN);
> +		svs_writel(svsp, SVSB_EN_INIT01, SVSEN);
> +		break;
> +	case SVSB_PHASE_INIT02:
> +		svs_writel(svsp, SVSB_INTEN_INIT0x, INTEN);
> +		init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in;
> +		svs_writel(svsp, init2vals, INIT2VALS);
> +		svs_writel(svsp, SVSB_EN_INIT02, SVSEN);
> +		break;
> +	case SVSB_PHASE_MON:
> +		ts_calcs = (svsb->bts << 12) | svsb->mts;
> +		svs_writel(svsp, ts_calcs, TSCALCS);
> +		svs_writel(svsp, SVSB_INTEN_MONVOPEN, INTEN);
> +		svs_writel(svsp, SVSB_EN_MON, SVSEN);
> +		break;
> +	default:
> +		WARN_ON(1);



I agree about printing a big warning in kmsg here, but you can do that in a

slightly more descriptive way:



         WARN(1, "Requested unknown target phase %u", target_phase);

> +		break;
> +	}
> +}
> +
> +static inline void svs_init01_isr_handler(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n",
> +		 __func__, svs_readl(svsp, VDESIGN74),
> +		 svs_readl(svsp, VDESIGN30), svs_readl(svsp, DCVALUES));
> +
> +	svsb->phase = SVSB_PHASE_INIT01;
> +	svsb->dc_voffset_in = ~(svs_readl(svsp, DCVALUES) & GENMASK(15, 0)) + 1;
> +	if (svsb->volt_flags & SVSB_INIT01_VOLT_IGNORE ||
> +	    (svsb->dc_voffset_in & SVSB_DC_SIGNED_BIT &&
> +	     svsb->volt_flags & SVSB_INIT01_VOLT_INC_ONLY))
> +		svsb->dc_voffset_in = 0;
> +
> +	svsb->age_voffset_in = svs_readl(svsp, AGEVALUES) & GENMASK(15, 0);
> +
> +	svs_writel(svsp, SVSB_EN_OFF, SVSEN);
> +	svs_writel(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
> +
> +	/* svs init01 clock gating */
> +	svsb->core_sel &= ~SVSB_DET_CLK_EN;
> +}
> +
> +static inline void svs_init02_isr_handler(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n",
> +		 __func__, svs_readl(svsp, VOP74), svs_readl(svsp, VOP30),
> +		 svs_readl(svsp, DCVALUES));
> +
> +	svsb->phase = SVSB_PHASE_INIT02;
> +	svsb->get_vops(svsp);
> +
> +	svs_writel(svsp, SVSB_EN_OFF, SVSEN);
> +	svs_writel(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
> +}
> +
> +static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	svsb->phase = SVSB_PHASE_MON;
> +	svsb->temp = svs_readl(svsp, TEMP) & GENMASK(7, 0);
> +	svsb->get_vops(svsp);
> +
> +	svs_writel(svsp, SVSB_INTSTS_MONVOP, INTSTS);
> +}
> +
> +static inline void svs_error_isr_handler(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +
> +	dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n",
> +		__func__, svs_readl(svsp, CORESEL));
> +	dev_err(svsb->dev, "SVSEN = 0x%08x, INTSTS = 0x%08x\n",
> +		svs_readl(svsp, SVSEN), svs_readl(svsp, INTSTS));
> +	dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n",
> +		svs_readl(svsp, SMSTATE0), svs_readl(svsp, SMSTATE1));
> +	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl(svsp, TEMP));
> +
> +	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
> +	svsb->phase = SVSB_PHASE_ERROR;
> +
> +	svs_writel(svsp, SVSB_EN_OFF, SVSEN);
> +	svs_writel(svsp, SVSB_INTSTS_CLEAN, INTSTS);
> +}
> +
> +static irqreturn_t svs_isr(int irq, void *data)
> +{
> +	struct svs_platform *svsp = data;
> +	struct svs_bank *svsb = NULL;
> +	unsigned long flags;
> +	u32 idx, int_sts, svs_en;
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +		WARN_ON(!svsb);
> +
> +		spin_lock_irqsave(&mtk_svs_lock, flags);
> +		svsp->pbank = svsb;
> +
> +		/* Find out which svs bank fires interrupt */
> +		if (svsb->int_st & svs_readl(svsp, INTST)) {
> +			spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +			continue;
> +		}
> +
> +		if (!svsb->suspended) {
> +			svs_switch_bank(svsp);
> +			int_sts = svs_readl(svsp, INTSTS);
> +			svs_en = svs_readl(svsp, SVSEN) & SVSB_EN_MASK;
> +
> +			if (int_sts == SVSB_INTSTS_COMPLETE &&
> +			    svs_en == SVSB_EN_INIT01)
> +				svs_init01_isr_handler(svsp);
> +			else if (int_sts == SVSB_INTSTS_COMPLETE &&
> +				 svs_en == SVSB_EN_INIT02)
> +				svs_init02_isr_handler(svsp);
> +			else if (int_sts & SVSB_INTSTS_MONVOP)
> +				svs_mon_mode_isr_handler(svsp);
> +			else
> +				svs_error_isr_handler(svsp);
> +		}
> +
> +		spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +		break;
> +	}
> +
> +	if (svsb->phase != SVSB_PHASE_INIT01)
> +		svs_adjust_pm_opp_volts(svsb, false);
> +
> +	if (svsb->phase == SVSB_PHASE_INIT01 ||
> +	    svsb->phase == SVSB_PHASE_INIT02)
> +		complete(&svsb->init_completion);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void svs_mon_mode(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb;
> +	unsigned long flags;
> +	u32 idx;
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (!(svsb->mode_support & SVSB_MODE_MON))
> +			continue;
> +
> +		spin_lock_irqsave(&mtk_svs_lock, flags);
> +		svsp->pbank = svsb;
> +		svs_set_bank_phase(svsp, SVSB_PHASE_MON);
> +		spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +	}
> +}
> +
> +static int svs_init02(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb;
> +	unsigned long flags, time_left;
> +	u32 idx;
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (!(svsb->mode_support & SVSB_MODE_INIT02))
> +			continue;
> +
> +		reinit_completion(&svsb->init_completion);
> +		spin_lock_irqsave(&mtk_svs_lock, flags);
> +		svsp->pbank = svsb;
> +		svs_set_bank_phase(svsp, SVSB_PHASE_INIT02);
> +		spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +
> +		time_left =
> +			wait_for_completion_timeout(&svsb->init_completion,
> +						    msecs_to_jiffies(5000));
> +		if (!time_left) {
> +			dev_err(svsb->dev, "init02 completion timeout\n");
> +			return -EBUSY;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int svs_init01(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb;
> +	struct pm_qos_request *qos_request;
> +	unsigned long flags, time_left;
> +	bool search_done;
> +	int ret = 0;
> +	u32 opp_freqs, opp_vboot, buck_volt, idx, i;
> +
> +	qos_request = kzalloc(sizeof(*qos_request), GFP_KERNEL);
> +	if (!qos_request)
> +		return -ENOMEM;
> +
> +	/* Let CPUs leave idle-off state for initializing svs_init01. */
> +	cpu_latency_qos_add_request(qos_request, 0);
> +
> +	/*
> +	 * Sometimes two svs banks use the same buck.
> +	 * Therefore, we set each svs bank to vboot voltage first.
> +	 */
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (!(svsb->mode_support & SVSB_MODE_INIT01))
> +			continue;
> +
> +		search_done = false;
> +
> +		if (svsb->pd_req) {
> +			ret = regulator_enable(svsb->buck);
> +			if (ret) {
> +				dev_err(svsb->dev, "%s enable fail: %d\n",
> +					svsb->buck_name, ret);
> +				goto init01_finish;
> +			}
> +
> +			if (!pm_runtime_enabled(svsb->pd_dev)) {
> +				pm_runtime_enable(svsb->pd_dev);
> +				svsb->enable_pm_runtime_ever = true;
> +			}
> +
> +			ret = pm_runtime_get_sync(svsb->pd_dev);
> +			if (ret < 0) {
> +				dev_err(svsb->dev, "mtcmos on fail: %d\n", ret);
> +				goto init01_finish;
> +			}
> +		}
> +
> +		if (regulator_set_mode(svsb->buck, REGULATOR_MODE_FAST))
> +			dev_notice(svsb->dev, "set fast mode fail\n");
> +
> +		/*
> +		 * Find the fastest freq that can be run at vboot and
> +		 * fix to that freq until svs_init01 is done.
> +		 */
> +		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
> +						      svsb->volt_step,
> +						      svsb->volt_base);
> +
> +		for (i = 0; i < svsb->opp_count; i++) {
> +			opp_freqs = svsb->opp_freqs[i];
> +			if (!search_done && svsb->opp_volts[i] <= opp_vboot) {
> +				ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
> +								opp_freqs,
> +								opp_vboot,
> +								opp_vboot,
> +								opp_vboot);
> +				if (ret) {
> +					dev_err(svsb->dev,
> +						"set voltage fail: %d\n", ret);
> +					goto init01_finish;
> +				}
> +
> +				search_done = true;
> +			} else {
> +				dev_pm_opp_disable(svsb->opp_dev,
> +						   svsb->opp_freqs[i]);
> +			}
> +		}
> +	}
> +
> +	/* svs bank init01 begins */
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (!(svsb->mode_support & SVSB_MODE_INIT01))
> +			continue;
> +
> +		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
> +						      svsb->volt_step,
> +						      svsb->volt_base);
> +
> +		buck_volt = regulator_get_voltage(svsb->buck);
> +		if (buck_volt != opp_vboot) {
> +			dev_err(svsb->dev,
> +				"buck voltage: %u, expected vboot: %u\n",
> +				buck_volt, opp_vboot);
> +			ret = -EPERM;
> +			goto init01_finish;
> +		}
> +
> +		spin_lock_irqsave(&mtk_svs_lock, flags);
> +		svsp->pbank = svsb;
> +		svs_set_bank_phase(svsp, SVSB_PHASE_INIT01);
> +		spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +
> +		time_left =
> +			wait_for_completion_timeout(&svsb->init_completion,
> +						    msecs_to_jiffies(5000));
> +		if (!time_left) {
> +			dev_err(svsb->dev, "init01 completion timeout\n");
> +			ret = -EBUSY;
> +			goto init01_finish;
> +		}
> +	}
> +
> +init01_finish:
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (!(svsb->mode_support & SVSB_MODE_INIT01))
> +			continue;
> +
> +		for (i = 0; i < svsb->opp_count; i++)
> +			dev_pm_opp_enable(svsb->opp_dev, svsb->opp_freqs[i]);
> +
> +		if (regulator_set_mode(svsb->buck, REGULATOR_MODE_NORMAL))
> +			dev_notice(svsb->dev, "fail to set normal mode\n");
> +
> +		if (svsb->pd_req) {
> +			if (pm_runtime_put_sync(svsb->pd_dev))
> +				dev_err(svsb->dev, "mtcmos off fail\n");
> +
> +			if (svsb->enable_pm_runtime_ever) {
> +				pm_runtime_disable(svsb->pd_dev);
> +				svsb->enable_pm_runtime_ever = false;
> +			}
> +
> +			if (regulator_disable(svsb->buck))
> +				dev_err(svsb->dev, "%s disable fail: %d\n",
> +					svsb->buck_name, ret);
> +		}
> +	}
> +
> +	cpu_latency_qos_remove_request(qos_request);
> +	kfree(qos_request);
> +
> +	return ret;
> +}
> +
> +static int svs_start(struct svs_platform *svsp)
> +{
> +	int ret;
> +
> +	ret = svs_init01(svsp);
> +	if (ret)
> +		return ret;
> +
> +	ret = svs_init02(svsp);
> +	if (ret)
> +		return ret;
> +
> +	svs_mon_mode(svsp);
> +
> +	return 0;
> +}
> +
> +static struct device *svs_get_subsys_device(struct svs_platform *svsp,
> +					    const char *node_name)
> +{
> +	struct platform_device *pdev;
> +	struct device_node *np;
> +
> +	np = of_find_node_by_name(NULL, node_name);
> +	if (!np) {
> +		dev_err(svsp->dev, "cannot find %s node\n", node_name);
> +		return ERR_PTR(-ENODEV);
> +	}
> +
> +	pdev = of_find_device_by_node(np);
> +	if (!pdev) {
> +		of_node_put(np);
> +		dev_err(svsp->dev, "cannot find pdev by %s\n", node_name);
> +		return ERR_PTR(-ENXIO);
> +	}
> +
> +	of_node_put(np);
> +
> +	return &pdev->dev;
> +}
> +
> +static struct device *svs_add_device_link(struct svs_platform *svsp,
> +					  const char *node_name)
> +{
> +	struct device *dev;
> +	struct device_link *sup_link;
> +
> +	if (!node_name) {
> +		dev_err(svsp->dev, "node name cannot be null\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	dev = svs_get_subsys_device(svsp, node_name);
> +	if (IS_ERR(dev))
> +		return dev;
> +
> +	sup_link = device_link_add(svsp->dev, dev,
> +				   DL_FLAG_AUTOREMOVE_CONSUMER);
> +	if (!sup_link) {
> +		dev_err(svsp->dev, "sup_link is NULL\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND)
> +		return ERR_PTR(-EPROBE_DEFER);
> +
> +	return dev;
> +}
> +
> +static int svs_resource_setup(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb;
> +	struct dev_pm_opp *opp;
> +	unsigned long freq;
> +	int count, ret;
> +	u32 idx, i;
> +
> +	dev_set_drvdata(svsp->dev, svsp);
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		switch (svsb->sw_id) {
> +		case SVSB_CPU_LITTLE:
> +			svsb->name = "SVSB_CPU_LITTLE";
> +			break;
> +		case SVSB_CPU_BIG:
> +			svsb->name = "SVSB_CPU_BIG";
> +			break;
> +		case SVSB_CCI:
> +			svsb->name = "SVSB_CCI";
> +			break;
> +		case SVSB_GPU:
> +			svsb->name = "SVSB_GPU";
> +			break;
> +		default:
> +			WARN_ON(1);
> +			return -EINVAL;
> +		}
> +
> +		svsb->dev = devm_kzalloc(svsp->dev, sizeof(*svsb->dev),
> +					 GFP_KERNEL);
> +		if (!svsb->dev)
> +			return -ENOMEM;
> +
> +		ret = dev_set_name(svsb->dev, "%s", svsb->name);
> +		if (ret)
> +			return ret;
> +
> +		dev_set_drvdata(svsb->dev, svsp);
> +
> +		ret = dev_pm_opp_of_add_table(svsb->opp_dev);
> +		if (ret) {
> +			dev_err(svsb->dev, "add opp table fail: %d\n", ret);
> +			return ret;
> +		}
> +
> +		mutex_init(&svsb->lock);
> +		init_completion(&svsb->init_completion);
> +
> +		svsb->buck = devm_regulator_get_optional(svsb->opp_dev,
> +							 svsb->buck_name);
> +		if (IS_ERR(svsb->buck)) {
> +			dev_err(svsb->dev, "cannot get \"%s-supply\"\n",
> +				svsb->buck_name);
> +			return PTR_ERR(svsb->buck);
> +		}
> +
> +		count = dev_pm_opp_get_opp_count(svsb->opp_dev);
> +		if (svsb->opp_count != count) {
> +			dev_err(svsb->dev,
> +				"opp_count not \"%u\" but get \"%d\"?\n",
> +				svsb->opp_count, count);
> +			return count;
> +		}
> +
> +		for (i = 0, freq = U32_MAX; i < svsb->opp_count; i++, freq--) {
> +			opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq);
> +			if (IS_ERR(opp)) {
> +				dev_err(svsb->dev, "cannot find freq = %ld\n",
> +					PTR_ERR(opp));
> +				return PTR_ERR(opp);
> +			}
> +
> +			svsb->opp_freqs[i] = freq;
> +			svsb->opp_volts[i] = dev_pm_opp_get_voltage(opp);
> +			svsb->freqs_pct[i] = percent(svsb->opp_freqs[i],
> +						     svsb->freq_base);
> +			dev_pm_opp_put(opp);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
> +{
> +	struct thermal_parameter tp;
> +	struct svs_bank *svsb;
> +	bool mon_mode_support = true;
> +	int format[6], x_roomt[6], tb_roomt = 0;
> +	struct nvmem_cell *cell;
> +	u32 idx, i, ft_pgm, mts, temp0, temp1, temp2;
> +
> +	for (i = 0; i < svsp->efuse_num; i++)
> +		if (svsp->efuse[i])
> +			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
> +				 i, svsp->efuse[i]);
> +
> +	/* Svs efuse parsing */
> +	ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0);
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		if (ft_pgm <= 1)
> +			svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
> +
> +		switch (svsb->sw_id) {
> +		case SVSB_CPU_LITTLE:
> +			svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
> +			svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
> +			svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
> +			svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0);
> +			svsb->mtdes  = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
> +
> +			if (ft_pgm <= 3)
> +				svsb->volt_offset += 10;
> +			else
> +				svsb->volt_offset += 2;
> +			break;
> +		case SVSB_CPU_BIG:
> +			svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
> +			svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
> +			svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
> +			svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0);
> +			svsb->mtdes  = svsp->efuse[17] & GENMASK(7, 0);
> +
> +			if (ft_pgm <= 3)
> +				svsb->volt_offset += 15;
> +			else
> +				svsb->volt_offset += 12;
> +			break;
> +		case SVSB_CCI:
> +			svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
> +			svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
> +			svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
> +			svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
> +			svsb->mtdes  = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
> +
> +			if (ft_pgm <= 3)
> +				svsb->volt_offset += 10;
> +			else
> +				svsb->volt_offset += 2;
> +			break;
> +		case SVSB_GPU:
> +			svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
> +			svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
> +			svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
> +			svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
> +			svsb->mtdes  = svsp->efuse[5] & GENMASK(7, 0);
> +
> +			if (ft_pgm >= 2) {
> +				svsb->freq_base = 800000000; /* 800MHz */
> +				svsb->dvt_fixed = 2;
> +			}
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	/* Get thermal efuse by nvmem */
> +	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
> +	if (IS_ERR_OR_NULL(cell)) {
> +		dev_err(svsp->dev, "no thermal cell, no mon mode\n");
> +		for (idx = 0; idx < svsp->bank_num; idx++) {
> +			svsb = &svsp->banks[idx];
> +			svsb->mode_support &= ~SVSB_MODE_MON;
> +		}
> +
> +		return true;
> +	}
> +
> +	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_num);



nvmem_cell_read may return an error pointer: you have to check that.



     if (IS_ERR(svsp->tefuse))

         .........



Failing to perform this check will produce unpredictable behavior

during the parsing stage.


> +	svsp->tefuse_num /= sizeof(u32);
> +	nvmem_cell_put(cell);
> +
> +	/* Thermal efuse parsing */
> +	tp.adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0);
> +	tp.adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0);
> +
> +	tp.o_vtsmcu1 = (svsp->tefuse[0] >> 17) & GENMASK(8, 0);
> +	tp.o_vtsmcu2 = (svsp->tefuse[0] >> 8) & GENMASK(8, 0);
> +	tp.o_vtsmcu3 = svsp->tefuse[1] & GENMASK(8, 0);
> +	tp.o_vtsmcu4 = (svsp->tefuse[2] >> 23) & GENMASK(8, 0);
> +	tp.o_vtsmcu5 = (svsp->tefuse[2] >> 5) & GENMASK(8, 0);
> +	tp.o_vtsabb = (svsp->tefuse[2] >> 14) & GENMASK(8, 0);
> +
> +	tp.degc_cali = (svsp->tefuse[0] >> 1) & GENMASK(5, 0);
> +	tp.adc_cali_en_t = svsp->tefuse[0] & BIT(0);
> +	tp.o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0);
> +
> +	tp.ts_id = (svsp->tefuse[1] >> 9) & BIT(0);
> +	tp.o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
> +
> +	if (tp.adc_cali_en_t == 1) {
> +		if (!tp.ts_id)
> +			tp.o_slope = 0;
> +
> +		if (tp.adc_ge_t < 265 || tp.adc_ge_t > 758 ||
> +		    tp.adc_oe_t < 265 || tp.adc_oe_t > 758 ||
> +		    tp.o_vtsmcu1 < -8 || tp.o_vtsmcu1 > 484 ||
> +		    tp.o_vtsmcu2 < -8 || tp.o_vtsmcu2 > 484 ||
> +		    tp.o_vtsmcu3 < -8 || tp.o_vtsmcu3 > 484 ||
> +		    tp.o_vtsmcu4 < -8 || tp.o_vtsmcu4 > 484 ||
> +		    tp.o_vtsmcu5 < -8 || tp.o_vtsmcu5 > 484 ||
> +		    tp.o_vtsabb < -8 || tp.o_vtsabb > 484 ||
> +		    tp.degc_cali < 1 || tp.degc_cali > 63) {
> +			dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
> +			mon_mode_support = false;
> +		}
> +	} else {
> +		dev_err(svsp->dev, "no thermal efuse, no mon mode\n");
> +		mon_mode_support = false;
> +	}
> +
> +	if (!mon_mode_support) {
> +		for (idx = 0; idx < svsp->bank_num; idx++) {
> +			svsb = &svsp->banks[idx];
> +			svsb->mode_support &= ~SVSB_MODE_MON;
> +		}
> +
> +		return true;
> +	}
> +
> +	tp.ge = ((tp.adc_ge_t - 512) * 10000) / 4096;
> +	tp.oe = (tp.adc_oe_t - 512);
> +	tp.gain = (10000 + tp.ge);
> +
> +	format[0] = (tp.o_vtsmcu1 + 3350 - tp.oe);
> +	format[1] = (tp.o_vtsmcu2 + 3350 - tp.oe);
> +	format[2] = (tp.o_vtsmcu3 + 3350 - tp.oe);
> +	format[3] = (tp.o_vtsmcu4 + 3350 - tp.oe);
> +	format[4] = (tp.o_vtsmcu5 + 3350 - tp.oe);
> +	format[5] = (tp.o_vtsabb + 3350 - tp.oe);
> +
> +	for (i = 0; i < 6; i++)
> +		x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / tp.gain;
> +
> +	temp0 = (10000 * 100000 / tp.gain) * 15 / 18;
> +
> +	if (!tp.o_slope_sign)
> +		mts = (temp0 * 10) / (1534 + tp.o_slope * 10);
> +	else
> +		mts = (temp0 * 10) / (1534 - tp.o_slope * 10);
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +		svsb->mts = mts;
> +
> +		switch (svsb->sw_id) {
> +		case SVSB_CPU_LITTLE:
> +			tb_roomt = x_roomt[3];
> +			break;
> +		case SVSB_CPU_BIG:
> +			tb_roomt = x_roomt[4];
> +			break;
> +		case SVSB_CCI:
> +			tb_roomt = x_roomt[3];
> +			break;
> +		case SVSB_GPU:
> +			tb_roomt = x_roomt[1];
> +			break;
> +		default:
> +			break;
> +		}
> +
> +		temp0 = (tp.degc_cali * 10 / 2);
> +		temp1 = ((10000 * 100000 / 4096 / tp.gain) *
> +			 tp.oe + tb_roomt * 10) * 15 / 18;
> +
> +		if (!tp.o_slope_sign)
> +			temp2 = temp1 * 100 / (1534 + tp.o_slope * 10);
> +		else
> +			temp2 = temp1 * 100 / (1534 - tp.o_slope * 10);
> +
> +		svsb->bts = (temp0 + temp2 - 250) * 4 / 10;
> +	}
> +
> +	return true;
> +}
> +
> +static bool svs_is_supported(struct svs_platform *svsp)
> +{
> +	struct nvmem_cell *cell;
> +
> +	/* Get svs efuse by nvmem */
> +	cell = nvmem_cell_get(svsp->dev, "svs-calibration-data");
> +	if (IS_ERR_OR_NULL(cell)) {
> +		dev_err(svsp->dev,
> +			"no \"svs-calibration-data\" from dts? disable svs\n");
> +		return false;
> +	}
> +
> +	svsp->efuse = nvmem_cell_read(cell, &svsp->efuse_num);
> +	svsp->efuse_num /= sizeof(u32);
> +	nvmem_cell_put(cell);
> +
> +	if (!svsp->efuse[svsp->efuse_check]) {
> +		dev_err(svsp->dev, "svs_efuse[%u] = 0x%x?\n",
> +			svsp->efuse_check, svsp->efuse[svsp->efuse_check]);
> +		return false;
> +	}
> +
> +	return svsp->efuse_parsing(svsp);
> +}
> +
> +static int svs_suspend(struct device *dev)
> +{
> +	struct svs_platform *svsp = dev_get_drvdata(dev);
> +	struct svs_bank *svsb;
> +	unsigned long flags;
> +	int ret;
> +	u32 idx;
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		/* Wait if svs_isr() is still in process. */
> +		spin_lock_irqsave(&mtk_svs_lock, flags);
> +		svsp->pbank = svsb;
> +		svs_switch_bank(svsp);
> +		svs_writel(svsp, SVSB_EN_OFF, SVSEN);
> +		svs_writel(svsp, SVSB_INTSTS_CLEAN, INTSTS);
> +		spin_unlock_irqrestore(&mtk_svs_lock, flags);
> +
> +		svsb->suspended = true;
> +		if (svsb->phase != SVSB_PHASE_INIT01) {
> +			svsb->phase = SVSB_PHASE_ERROR;
> +			svs_adjust_pm_opp_volts(svsb, true);
> +		}
> +	}
> +
> +	ret = reset_control_assert(svsp->rst);
> +	if (ret) {
> +		dev_err(svsp->dev, "cannot assert reset %d\n", ret);
> +		return ret;
> +	}
> +
> +	clk_disable_unprepare(svsp->main_clk);
> +
> +	return 0;
> +}
> +
> +static int svs_resume(struct device *dev)
> +{
> +	struct svs_platform *svsp = dev_get_drvdata(dev);
> +	struct svs_bank *svsb;
> +	int ret;
> +	u32 idx;
> +
> +	ret = clk_prepare_enable(svsp->main_clk);
> +	if (ret) {
> +		dev_err(svsp->dev, "cannot enable main_clk, disable svs\n");
> +		return ret;
> +	}
> +
> +	ret = reset_control_deassert(svsp->rst);
> +	if (ret) {
> +		dev_err(svsp->dev, "cannot deassert reset %d\n", ret);
> +		return ret;
> +	}
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +		svsb->suspended = false;
> +	}
> +
> +	ret = svs_init02(svsp);
> +	if (ret)
> +		return ret;
> +
> +	svs_mon_mode(svsp);
> +
> +	return 0;
> +}
> +
> +static struct svs_bank svs_mt8183_banks[] = {
> +	{
> +		.sw_id			= SVSB_CPU_LITTLE,
> +		.set_freqs_pct		= svs_set_freqs_pct_v2,
> +		.get_vops		= svs_get_vops_v2,
> +		.cpu_id			= 0,
> +		.tzone_name		= "tzts4",
> +		.buck_name		= "proc",
> +		.pd_req			= false,
> +		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
> +		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
> +		.opp_count		= 16,
> +		.freq_base		= 1989000000,
> +		.vboot			= 0x30,
> +		.volt_step		= 6250,
> +		.volt_base		= 500000,
> +		.volt_offset		= 0,
> +		.vmax			= 0x64,
> +		.vmin			= 0x18,
> +		.dthi			= 0x1,
> +		.dtlo			= 0xfe,
> +		.det_window		= 0xa28,
> +		.det_max		= 0xffff,
> +		.age_config		= 0x555555,
> +		.agem			= 0,
> +		.dc_config		= 0x555555,
> +		.dvt_fixed		= 0x7,
> +		.vco			= 0x10,
> +		.chk_shift		= 0x77,
> +		.temp_upper_bound	= 0x64,
> +		.temp_lower_bound	= 0xb2,
> +		.tzone_high_temp	= SVSB_TZONE_HIGH_TEMP_MAX,
> +		.tzone_low_temp		= 25000,
> +		.tzone_low_temp_offset	= 0,
> +		.core_sel		= 0x8fff0000,
> +		.int_st			= BIT(0),
> +		.ctl0			= 0x00010001,
> +	},
> +	{
> +		.sw_id			= SVSB_CPU_BIG,
> +		.set_freqs_pct		= svs_set_freqs_pct_v2,
> +		.get_vops		= svs_get_vops_v2,
> +		.cpu_id			= 4,
> +		.tzone_name		= "tzts5",
> +		.buck_name		= "proc",
> +		.pd_req			= false,
> +		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
> +		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
> +		.opp_count		= 16,
> +		.freq_base		= 1989000000,
> +		.vboot			= 0x30,
> +		.volt_step		= 6250,
> +		.volt_base		= 500000,
> +		.volt_offset		= 0,
> +		.vmax			= 0x58,
> +		.vmin			= 0x10,
> +		.dthi			= 0x1,
> +		.dtlo			= 0xfe,
> +		.det_window		= 0xa28,
> +		.det_max		= 0xffff,
> +		.age_config		= 0x555555,
> +		.agem			= 0,
> +		.dc_config		= 0x555555,
> +		.dvt_fixed		= 0x7,
> +		.vco			= 0x10,
> +		.chk_shift		= 0x77,
> +		.temp_upper_bound	= 0x64,
> +		.temp_lower_bound	= 0xb2,
> +		.tzone_high_temp	= SVSB_TZONE_HIGH_TEMP_MAX,
> +		.tzone_low_temp		= 25000,
> +		.tzone_low_temp_offset	= 0,
> +		.core_sel		= 0x8fff0001,
> +		.int_st			= BIT(1),
> +		.ctl0			= 0x00000001,
> +	},
> +	{
> +		.sw_id			= SVSB_CCI,
> +		.set_freqs_pct		= svs_set_freqs_pct_v2,
> +		.get_vops		= svs_get_vops_v2,
> +		.tzone_name		= "tzts4",
> +		.buck_name		= "proc",
> +		.pd_req			= false,
> +		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
> +		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
> +		.opp_count		= 16,
> +		.freq_base		= 1196000000,
> +		.vboot			= 0x30,
> +		.volt_step		= 6250,
> +		.volt_base		= 500000,
> +		.volt_offset		= 0,
> +		.vmax			= 0x64,
> +		.vmin			= 0x18,
> +		.dthi			= 0x1,
> +		.dtlo			= 0xfe,
> +		.det_window		= 0xa28,
> +		.det_max		= 0xffff,
> +		.age_config		= 0x555555,
> +		.agem			= 0,
> +		.dc_config		= 0x555555,
> +		.dvt_fixed		= 0x7,
> +		.vco			= 0x10,
> +		.chk_shift		= 0x77,
> +		.temp_upper_bound	= 0x64,
> +		.temp_lower_bound	= 0xb2,
> +		.tzone_high_temp	= SVSB_TZONE_HIGH_TEMP_MAX,
> +		.tzone_low_temp		= 25000,
> +		.tzone_low_temp_offset	= 0,
> +		.core_sel		= 0x8fff0002,
> +		.int_st			= BIT(2),
> +		.ctl0			= 0x00100003,
> +	},
> +	{
> +		.sw_id			= SVSB_GPU,
> +		.set_freqs_pct		= svs_set_freqs_pct_v2,
> +		.get_vops		= svs_get_vops_v2,
> +		.tzone_name		= "tzts2",
> +		.buck_name		= "mali",
> +		.pd_req			= true,
> +		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
> +		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02 |
> +					  SVSB_MODE_MON,
> +		.opp_count		= 16,
> +		.freq_base		= 900000000,
> +		.vboot			= 0x30,
> +		.volt_step		= 6250,
> +		.volt_base		= 500000,
> +		.volt_offset		= 0,
> +		.vmax			= 0x40,
> +		.vmin			= 0x14,
> +		.dthi			= 0x1,
> +		.dtlo			= 0xfe,
> +		.det_window		= 0xa28,
> +		.det_max		= 0xffff,
> +		.age_config		= 0x555555,
> +		.agem			= 0,
> +		.dc_config		= 0x555555,
> +		.dvt_fixed		= 0x3,
> +		.vco			= 0x10,
> +		.chk_shift		= 0x77,
> +		.temp_upper_bound	= 0x64,
> +		.temp_lower_bound	= 0xb2,
> +		.tzone_high_temp	= SVSB_TZONE_HIGH_TEMP_MAX,
> +		.tzone_low_temp		= 25000,
> +		.tzone_low_temp_offset	= 3,
> +		.core_sel		= 0x8fff0003,
> +		.int_st			= BIT(3),
> +		.ctl0			= 0x00050001,
> +	},
> +};
> +
> +static int svs_get_svs_mt8183_platform_data(struct svs_platform *svsp)
> +{
> +	struct device *dev;
> +	struct svs_bank *svsb;
> +	u32 idx;
> +
> +	svsp->name = "mt8183-svs";
> +	svsp->banks = svs_mt8183_banks;
> +	svsp->efuse_parsing = svs_mt8183_efuse_parsing;
> +	svsp->regs = svs_regs_v2;
> +	svsp->irqflags = IRQF_TRIGGER_LOW;
> +	svsp->rst = NULL;
> +	svsp->bank_num = ARRAY_SIZE(svs_mt8183_banks);
> +	svsp->efuse_check = 2;
> +
> +	dev = svs_add_device_link(svsp, "thermal");
> +	if (IS_ERR(dev))
> +		return PTR_ERR(dev);
> +
> +	for (idx = 0; idx < svsp->bank_num; idx++) {
> +		svsb = &svsp->banks[idx];
> +
> +		switch (svsb->sw_id) {
> +		case SVSB_CPU_LITTLE:
> +		case SVSB_CPU_BIG:
> +			svsb->opp_dev = get_cpu_device(svsb->cpu_id);
> +			break;
> +		case SVSB_CCI:
> +			svsb->opp_dev = svs_add_device_link(svsp, "cci");
> +			break;
> +		case SVSB_GPU:
> +			svsb->opp_dev = svs_add_device_link(svsp, "mali");
> +			svsb->pd_dev = svs_add_device_link(svsp,
> +							   "mali_gpu_core2");
> +			if (IS_ERR(svsb->pd_dev))
> +				return PTR_ERR(svsb->pd_dev);
> +			break;
> +		default:
> +			WARN_ON(1);
> +			return -EINVAL;
> +		}
> +
> +		if (IS_ERR(svsb->opp_dev))
> +			return PTR_ERR(svsb->opp_dev);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id mtk_svs_of_match[] = {
> +	{
> +		.compatible = "mediatek,mt8183-svs",
> +		.data = &svs_get_svs_mt8183_platform_data,
> +	}, {
> +		/* Sentinel */
> +	},
> +};
> +
> +static int svs_probe(struct platform_device *pdev)
> +{
> +	int (*svs_get_svs_platform_data)(struct svs_platform *svsp);
> +	struct svs_platform *svsp;
> +	unsigned int svsp_irq;
> +	int ret;
> +
> +	svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL);
> +	if (!svsp)
> +		return -ENOMEM;
> +
> +	svs_get_svs_platform_data = of_device_get_match_data(&pdev->dev);
> +	if (!svs_get_svs_platform_data) {
> +		dev_err(svsp->dev, "no svs platform data? why?\n");
> +		return -EPERM;
> +	}
> +
> +	svsp->dev = &pdev->dev;
> +	ret = svs_get_svs_platform_data(svsp);
> +	if (ret) {
> +		dev_err_probe(svsp->dev, ret, "fail to get svsp data\n");
> +		return ret;
> +	}
> +
> +	if (!svs_is_supported(svsp)) {
> +		dev_notice(svsp->dev, "svs is not supported\n");
> +		return -EPERM;
> +	}
> +
> +	ret = svs_resource_setup(svsp);
> +	if (ret) {
> +		dev_err(svsp->dev, "svs resource setup fail: %d\n", ret);
> +		return ret;
> +	}
> +
> +	svsp_irq = irq_of_parse_and_map(svsp->dev->of_node, 0);
> +	ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
> +					svsp->irqflags | IRQF_ONESHOT,
> +					svsp->name, svsp);
> +	if (ret) {
> +		dev_err(svsp->dev, "register irq(%d) failed: %d\n",
> +			svsp_irq, ret);
> +		return ret;
> +	}
> +
> +	svsp->main_clk = devm_clk_get(svsp->dev, "main");
> +	if (IS_ERR(svsp->main_clk)) {
> +		dev_err(svsp->dev, "failed to get clock: %ld\n",
> +			PTR_ERR(svsp->main_clk));
> +		return PTR_ERR(svsp->main_clk);
> +	}
> +
> +	ret = clk_prepare_enable(svsp->main_clk);
> +	if (ret) {
> +		dev_err(svsp->dev, "cannot enable main clk: %d\n", ret);
> +		return ret;
> +	}
> +
> +	svsp->base = of_iomap(svsp->dev->of_node, 0);
> +	if (IS_ERR_OR_NULL(svsp->base)) {
> +		dev_err(svsp->dev, "cannot find svs register base\n");
> +		ret = -EINVAL;
> +		goto svs_probe_clk_disable;
> +	}
> +
> +	ret = svs_start(svsp);
> +	if (ret) {
> +		dev_err(svsp->dev, "svs start fail: %d\n", ret);
> +		goto svs_probe_iounmap;
> +	}
> +
> +	return 0;
> +
> +svs_probe_iounmap:
> +	iounmap(svsp->base);
> +
> +svs_probe_clk_disable:
> +	clk_disable_unprepare(svsp->main_clk);
> +
> +	return ret;
> +}
> +
> +static SIMPLE_DEV_PM_OPS(svs_pm_ops, svs_suspend, svs_resume);
> +
> +static struct platform_driver svs_driver = {
> +	.probe	= svs_probe,
> +	.driver	= {
> +		.name		= "mtk-svs",
> +		.pm		= &svs_pm_ops,
> +		.of_match_table	= of_match_ptr(mtk_svs_of_match),
> +	},
> +};
> +
> +module_platform_driver(svs_driver);
> +
> +MODULE_AUTHOR("Roger Lu <roger.lu at mediatek.com>");
> +MODULE_DESCRIPTION("MediaTek SVS driver");
> +MODULE_LICENSE("GPL v2");
> 



From suzuki.poulose at arm.com  Wed Jan  5 02:01:00 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 5 Jan 2022 10:01:00 +0000
Subject: [PATCH 2/4] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <0020da84-ce90-f269-27e1-6a6c90f6317b@arm.com>

Hi Anshuman

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected.
> 
> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
> just after the trace collection has stopped and before performing a system
> register write to one of the affected registers. This adds a new cpu errata
> in arm64 errata framework and also updates TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 +
>   arch/arm64/Kconfig                           | 18 +++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 ++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>   drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
>   6 files changed, 68 insertions(+), 24 deletions(-)

I think it may be a good idea to split the patch into
two parts :

- arm64 kernel part. (cpucap defintions and detection)
- trbe driver part

So that it is easier to merge these series upstream to
avoid conflicts.

> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 5342e895fb60..c9b30e6c2b6c 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -52,6 +52,8 @@ stable kernels.
>   | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
>   +----------------+-----------------+-----------------+-----------------------------+
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..2105b68d88db 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2064142
> +	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
> +
> +	  Affected Cortex-A510 core might fail to write into system registers after the
> +	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
> +	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
> +	  and TRBTRG_EL1 will be ignored and will not be effected.
> +
> +	  Work around this in the driver by executing TSB CSYNC and DSB after collection
> +	  is stopped and before performing a system register write to one of the affected
> +	  registers.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..cbb7d5a9aee7 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>   		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>   	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2064142
> +	{
> +		.desc = "ARM erratum 2064142",
> +		.capability = ARM64_WORKAROUND_2064142,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
>   #endif
>   	{
>   	}
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..fca3cb329e1d 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>   WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
> +WORKAROUND_2064142
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 276862c07e32..ec24b62b2cec 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -91,10 +91,12 @@ struct trbe_buf {
>    */
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
> +#define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
> +	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,

super minor nit: TRBE_NEEDS_DRAIN_AFTER_DISABLE ?

>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>   }
>   
> +static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
> +{

minor nit: trbe_needs_drain_after_disable() ?

Either ways, the patch looks good to me.

Suzuki


From suzuki.poulose at arm.com  Wed Jan  5 02:05:35 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 5 Jan 2022 10:05:35 +0000
Subject: [PATCH 1/4] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1641359159-22726-2-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <49445a48-403c-6b88-1360-9f5905d8a2b8@arm.com>

On 05/01/2022 05:05, Anshuman Khandual wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   arch/arm64/include/asm/cputype.h | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 19b8441aa8f2..e8fdc10395b6 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -73,6 +73,7 @@
>   #define ARM_CPU_PART_CORTEX_A76		0xD0B
>   #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
>   #define ARM_CPU_PART_CORTEX_A77		0xD0D
> +#define ARM_CPU_PART_CORTEX_A510	0xD46
>   #define ARM_CPU_PART_CORTEX_A710	0xD47
>   #define ARM_CPU_PART_NEOVERSE_N2	0xD49

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From sam.shih at mediatek.com  Wed Jan  5 02:04:54 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 5 Jan 2022 18:04:54 +0800
Subject: [PATCH 0/2] Add toprgu reset-controller support for MT7986
Message-ID: <20220105100456.7126-1-sam.shih@mediatek.com>

These patches aim to add watchdog toprgu reset-controller support
for MT7986.

Sam Shih (2):
  dt-bindings: reset: mt7986: Add reset-controller header file
  watchdog: mtk_wdt: mt7986: Add toprgu reset controller support

 drivers/watchdog/mtk_wdt.c                |  6 +++
 include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
 2 files changed, 61 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7986-resets.h

-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan  5 02:04:56 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 5 Jan 2022 18:04:56 +0800
Subject: [PATCH 2/2] watchdog: mtk_wdt: mt7986: Add toprgu reset controller
 support
In-Reply-To: <20220105100456.7126-1-sam.shih@mediatek.com>
References: <20220105100456.7126-1-sam.shih@mediatek.com>
Message-ID: <20220105100456.7126-3-sam.shih@mediatek.com>

Besides watchdog, the mt7986 toprgu module also provides software reset
functionality for various peripheral subsystems
(eg, ethernet, pcie, and connectivity)

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 drivers/watchdog/mtk_wdt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index 543cf38bd04e..c6437fe1f4c0 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -10,6 +10,7 @@
  */
 
 #include <dt-bindings/reset/mt2712-resets.h>
+#include <dt-bindings/reset/mt7986-resets.h>
 #include <dt-bindings/reset/mt8183-resets.h>
 #include <dt-bindings/reset/mt8192-resets.h>
 #include <dt-bindings/reset/mt8195-resets.h>
@@ -76,6 +77,10 @@ static const struct mtk_wdt_data mt2712_data = {
 	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
 };
 
+static const struct mtk_wdt_data mt7986_data = {
+	.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
+};
+
 static const struct mtk_wdt_data mt8183_data = {
 	.toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
 };
@@ -418,6 +423,7 @@ static int mtk_wdt_resume(struct device *dev)
 static const struct of_device_id mtk_wdt_dt_ids[] = {
 	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
 	{ .compatible = "mediatek,mt6589-wdt" },
+	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
 	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
 	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
 	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan  5 02:04:55 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 5 Jan 2022 18:04:55 +0800
Subject: [PATCH 1/2] dt-bindings: reset: mt7986: Add reset-controller header
 file
In-Reply-To: <20220105100456.7126-1-sam.shih@mediatek.com>
References: <20220105100456.7126-1-sam.shih@mediatek.com>
Message-ID: <20220105100456.7126-2-sam.shih@mediatek.com>

Add infracfg, toprgu, and ethsys reset-controller header file
for MT7986 platform.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7986-resets.h

diff --git a/include/dt-bindings/reset/mt7986-resets.h b/include/dt-bindings/reset/mt7986-resets.h
new file mode 100644
index 000000000000..af3d16c81192
--- /dev/null
+++ b/include/dt-bindings/reset/mt7986-resets.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Sam Shih <sam.shih at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7986
+#define _DT_BINDINGS_RESET_CONTROLLER_MT7986
+
+/* INFRACFG resets */
+#define MT7986_INFRACFG_PEXTP_MAC_SW_RST	6
+#define MT7986_INFRACFG_SSUSB_SW_RST		7
+#define MT7986_INFRACFG_EIP97_SW_RST		8
+#define MT7986_INFRACFG_AUDIO_SW_RST		13
+#define MT7986_INFRACFG_CQ_DMA_SW_RST		14
+
+#define MT7986_INFRACFG_TRNG_SW_RST		17
+#define MT7986_INFRACFG_AP_DMA_SW_RST		32
+#define MT7986_INFRACFG_I2C_SW_RST		33
+#define MT7986_INFRACFG_NFI_SW_RST		34
+#define MT7986_INFRACFG_SPI0_SW_RST		35
+#define MT7986_INFRACFG_SPI1_SW_RST		36
+#define MT7986_INFRACFG_UART0_SW_RST		37
+#define MT7986_INFRACFG_UART1_SW_RST		38
+#define MT7986_INFRACFG_UART2_SW_RST		39
+#define MT7986_INFRACFG_AUXADC_SW_RST		43
+
+#define MT7986_INFRACFG_APXGPT_SW_RST		66
+#define MT7986_INFRACFG_PWM_SW_RST		68
+
+#define MT7986_INFRACFG_SW_RST_NUM		69
+
+/* TOPRGU resets */
+#define MT7986_TOPRGU_APMIXEDSYS_SW_RST		0
+#define MT7986_TOPRGU_SGMII0_SW_RST		1
+#define MT7986_TOPRGU_SGMII1_SW_RST		2
+#define MT7986_TOPRGU_INFRA_SW_RST		3
+#define MT7986_TOPRGU_U2PHY_SW_RST		5
+#define MT7986_TOPRGU_PCIE_SW_RST		6
+#define MT7986_TOPRGU_SSUSB_SW_RST		7
+#define MT7986_TOPRGU_ETHDMA_SW_RST		20
+#define MT7986_TOPRGU_CONSYS_SW_RST		23
+
+#define MT7986_TOPRGU_SW_RST_NUM		24
+
+/* ETHSYS Subsystem resets */
+#define MT7986_ETHSYS_FE_SW_RST			6
+#define MT7986_ETHSYS_PMTR_SW_RST		8
+#define MT7986_ETHSYS_GMAC_SW_RST		23
+#define MT7986_ETHSYS_PPE0_SW_RST		30
+#define MT7986_ETHSYS_PPE1_SW_RST		31
+
+#define MT7986_ETHSYS_SW_RST_NUM		32
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7986 */
-- 
2.29.2



From suzuki.poulose at arm.com  Wed Jan  5 02:13:06 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 5 Jan 2022 10:13:06 +0000
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>

Hi Anshuman

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
> an inconsistent view on whether trace is prohibited within the CPU. As a
> result, the trace buffer or trace buffer state might be corrupted. This
> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
> followed by just a single context synchronization event before execution
> changes from a context, in which trace is prohibited to one where it isn't,
> or vice versa. In these mentioned conditions, the view of whether trace is
> prohibited is inconsistent between parts of the CPU, and the trace buffer
> or the trace buffer state might be corrupted.
> 
> Work around this problem in the TRBE driver by preventing an inconsistent
> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
> instruction before an ERET, or two ISB instructions if no ERET is to take
> place. This adds a new cpu errata in arm64 errata framework and also
> updates TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 +
>   arch/arm64/Kconfig                           | 23 ++++++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 ++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>   5 files changed, 72 insertions(+), 10 deletions(-)

As with the previous patch, it may be a good idea to split the
patch to arm64 and trbe parts.

> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -54,6 +54,8 @@ stable kernels.
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 2105b68d88db..026e34fb6fad 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2038923
> +	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
> +
> +	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
> +	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
> +	  might be corrupted. This happens after TRBE buffer has been enabled by setting
> +	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
> +	  execution changes from a context, in which trace is prohibited to one where it
> +	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
> +	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
> +	  the trace buffer state might be corrupted.
> +
> +	  Work around this in the driver by preventing an inconsistent view of whether the
> +	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
> +	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
> +	  two ISB instructions if no ERET is to take place.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index cbb7d5a9aee7..60b0c1f1d912 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>   	},
>   #endif
> +#ifdef CONFIG_ARM64_ERRATUM_2038923
> +	{
> +		.desc = "ARM erratum 2038923",
> +		.capability = ARM64_WORKAROUND_2038923,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
> +#endif
>   	{
>   	}
>   };
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index fca3cb329e1d..45a06d36d080 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
>   WORKAROUND_2064142
> +WORKAROUND_2038923
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index ec24b62b2cec..0689c6dab96d 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -92,11 +92,13 @@ struct trbe_buf {
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
>   #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE	3
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>   	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
> +	[TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>   }
>   
> +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
> +{

minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?

> +	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>   	dsb(nsh);
>   }
>   
> +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
> +{
> +	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);

minor nit: This implies we do the TRBE programming in the following
manner in the common case (i.e, TRBE enabled in the beginning of a
session).
   -> set TRBE LIMIT
   -> read TRBE LIMIT
   -> set TRBE ENABLED

Could we please optimize this ? I believe the buf->trbe_limit
must hold the LIMITR value at any point in time. And thus this
function could simply be :

set_trbe_enabled(trbe_buf)
{
	limitr = trbe_buf->limit | LIMITR_ENABLE
	write(limitr, TRBLIMITR_EL1);
	...
}

Otherwise looks good to me

Suzuki


From gregkh at linuxfoundation.org  Wed Jan  5 02:15:52 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Wed, 5 Jan 2022 11:15:52 +0100
Subject: [PATCH v5 0/6] PCI: imx6: refine codes and add compliance tests
 mode support
In-Reply-To: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <YdVv2K+ezwv2iG80@kroah.com>

On Wed, Jan 05, 2022 at 03:43:16PM +0800, Richard Zhu wrote:
> This series patches refine pci-imx6 driver and do the following changes.
> - Encapsulate the clock enable into one standalone function
> - Add the error propagation from host_init
> - Balance the usage of the regulator and clocks when link never came up
> - Add the compliance tests mode support
> 
> Main changes from v4 to v5:
> - Since i.MX8MM PCIe support had been merged. Based on Lorenzo's git repos,
>   rebase and resend the patch-set.
> 
> Main changes from v3 to v4:
> - Regarding Mark's comments, delete the regulator_is_enabled() check.
> - Squash #3 and #6 of v3 patch into #5 patch of v4 set.
> 
> Main changes from v2 to v3:
> - Add "Reviewed-by: Lucas Stach <l.stach at pengutronix.de>" tag into
>   first two patches.
> - Add a Fixes tag into #3 patch.
> - Split the #4 of v2 to two patches, one is clock disable codes move,
>   the other one is the acutal clock unbalance fix.
> - Add a new host_exit() callback into dw_pcie_host_ops, then it could be
>   invoked to handle the unbalance issue in the error handling after
>   host_init() function when link is down.
> - Add a new host_exit() callback for i.MX PCIe driver to handle this case
>   in the error handling after host_init.
> 
> Main changes from v1 to v2:
> Regarding Lucas' comments.
>   - Move the placement of the new imx6_pcie_clk_enable() to avoid the
>     forward declarition.
>   - Seperate the second patch of v1 patch-set to three patches.
>   - Use the module_param to replace the kernel command line.
> Regarding Bjorn's comments:
>   - Use the cover-letter for a multi-patch series.
>   - Correct the subject line, and refine the commit logs. For example,
>     remove the timestamp of the logs.
> 
> drivers/pci/controller/dwc/pci-imx6.c             | 197 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------
> drivers/pci/controller/dwc/pcie-designware-host.c |   5 ++-
> drivers/pci/controller/dwc/pcie-designware.h      |   1 +
> 3 files changed, 128 insertions(+), 75 deletions(-)
> 
> [PATCH v5 1/6] PCI: imx6: Encapsulate the clock enable into one
> [PATCH v5 2/6] PCI: imx6: Add the error propagation from host_init
> [PATCH v5 3/6] PCI: imx6: PCI: imx6: Move imx6_pcie_clk_disable()
> [PATCH v5 4/6] PCI: dwc: Add dw_pcie_host_ops.host_exit() callback
> [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never came
> [PATCH v5 6/6] PCI: imx6: Add the compliance tests mode support

<formletter>

This is not the correct way to submit patches for inclusion in the
stable kernel tree.  Please read:
    https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html
for how to do this properly.

</formletter>


From linmq006 at gmail.com  Wed Jan  5 02:16:19 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Wed,  5 Jan 2022 10:16:19 +0000
Subject: [PATCH] iommu/arm-smmu: Add missing pm_runtime_disable() in
 qcom_iommu_device_probe
Message-ID: <20220105101619.29108-1-linmq006@gmail.com>

If the probe fails, we should use pm_runtime_disable() to balance
pm_runtime_enable().
Add missing pm_runtime_disable() for error handling.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/iommu/arm/arm-smmu/qcom_iommu.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
index b91874cb6cf3..2f227bc88bd9 100644
--- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c
+++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c
@@ -827,20 +827,20 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 	ret = devm_of_platform_populate(dev);
 	if (ret) {
 		dev_err(dev, "Failed to populate iommu contexts\n");
-		return ret;
+		goto err_pm_disable;
 	}
 
 	ret = iommu_device_sysfs_add(&qcom_iommu->iommu, dev, NULL,
 				     dev_name(dev));
 	if (ret) {
 		dev_err(dev, "Failed to register iommu in sysfs\n");
-		return ret;
+		goto err_pm_disable;
 	}
 
 	ret = iommu_device_register(&qcom_iommu->iommu, &qcom_iommu_ops, dev);
 	if (ret) {
 		dev_err(dev, "Failed to register iommu\n");
-		return ret;
+		goto err_pm_disable;
 	}
 
 	bus_set_iommu(&platform_bus_type, &qcom_iommu_ops);
@@ -852,6 +852,10 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
 	}
 
 	return 0;
+
+err_pm_disable:
+	pm_runtime_disable(dev);
+	return ret;
 }
 
 static int qcom_iommu_device_remove(struct platform_device *pdev)
-- 
2.17.1



From zev at bewilderbeest.net  Wed Jan  5 02:17:19 2022
From: zev at bewilderbeest.net (Zev Weiss)
Date: Wed,  5 Jan 2022 02:17:19 -0800
Subject: [PATCH] ARM: dts: aspeed: Add ASRock ROMED8HM3 BMC
Message-ID: <20220105101719.7093-1-zev@bewilderbeest.net>

This is a half-width, single-socket Epyc server board with an AST2500
BMC.  This device tree is sufficient for basic OpenBMC functionality,
but we'll need to add a few more devices (as driver support becomes
available) before it's fully usable.

Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/aspeed-bmc-asrock-romed8hm3.dts  | 259 ++++++++++++++++++
 2 files changed, 260 insertions(+)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..4008d2143b44 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1481,6 +1481,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-arm-centriq2400-rep.dtb \
 	aspeed-bmc-arm-stardragon4800-rep2.dtb \
 	aspeed-bmc-asrock-e3c246d4i.dtb \
+	aspeed-bmc-asrock-romed8hm3.dtb \
 	aspeed-bmc-bytedance-g220a.dtb \
 	aspeed-bmc-facebook-cloudripper.dtb \
 	aspeed-bmc-facebook-cmm.dtb \
diff --git a/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
new file mode 100644
index 000000000000..e71ccfd1df63
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/{
+	model = "ASRock ROMED8HM3 BMC v1.00";
+	compatible = "asrock,romed8hm3-bmc", "aspeed,ast2500";
+
+	aliases {
+		serial4 = &uart5;
+	};
+
+	chosen {
+		stdout-path = &uart5;
+		bootargs = "console=tty0 console=ttyS4,115200 earlycon";
+	};
+
+	memory at 80000000 {
+		reg = <0x80000000 0x20000000>;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		heartbeat {
+			gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
+			linux,default-trigger = "timer";
+		};
+
+		system-fault {
+			gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+			panic-indicator;
+		};
+	};
+
+	iio-hwmon {
+		compatible = "iio-hwmon";
+		io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+			<&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
+			<&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>,
+			<&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>;
+	};
+};
+
+&fmc {
+	status = "okay";
+	flash at 0 {
+		status = "okay";
+		m25p,fast-read;
+		label = "bmc";
+		spi-max-frequency = <100000000>; /* 100 MHz */
+#include "openbmc-flash-layout-64.dtsi"
+	};
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&vuart {
+	status = "okay";
+	aspeed,lpc-io-reg = <0x2f8>;
+	aspeed,lpc-interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mac0 {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	/* inlet temp sensor */
+	w83773g at 4c {
+		compatible = "nuvoton,w83773g";
+		reg = <0x4c>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&i2c2 {
+	status = "okay";
+
+	/* IPB temp sensor */
+	w83773g at 4c {
+		compatible = "nuvoton,w83773g";
+		reg = <0x4c>;
+	};
+
+	/* IPB PMIC */
+	lm25066 at 40 {
+		compatible = "lm25066";
+		reg = <0x40>;
+	};
+
+	/* 12VSB PMIC */
+	lm25066 at 41 {
+		compatible = "lm25066";
+		reg = <0x41>;
+	};
+};
+
+&i2c4 {
+	status = "okay";
+};
+
+&i2c5 {
+	status = "okay";
+};
+
+&i2c6 {
+	status = "okay";
+};
+
+&i2c7 {
+	status = "okay";
+
+	/* Baseboard FRU eeprom */
+	eeprom at 50 {
+		compatible = "st,24c128", "atmel,24c128";
+		reg = <0x50>;
+		pagesize = <16>;
+	};
+};
+
+&i2c8 {
+	status = "okay";
+};
+
+&i2c9 {
+	status = "okay";
+};
+
+&video {
+	status = "okay";
+};
+
+&vhub {
+	status = "okay";
+};
+
+&lpc_ctrl {
+	status = "okay";
+};
+
+&lpc_snoop {
+	status = "okay";
+	snoop-ports = <0x80>;
+};
+
+&kcs3 {
+	status = "okay";
+	aspeed,lpc-io-reg = <0xca2>;
+};
+
+&pwm_tacho {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3_default
+		&pinctrl_pwm4_default
+		&pinctrl_pwm5_default
+		&pinctrl_pwm6_default>;
+
+	fan at 3 {
+		reg = <0x03>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x03 0x0b>;
+	};
+
+	fan at 4 {
+		reg = <0x04>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x04 0x0c>;
+	};
+
+	fan at 5 {
+		reg = <0x05>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x05 0x0d>;
+	};
+
+	fan at 6 {
+		reg = <0x06>;
+		aspeed,fan-tach-ch = /bits/ 8 <0x06 0x0e>;
+	};
+};
+
+&gpio {
+	status = "okay";
+	gpio-line-names =
+		/*  A */ "LOCATORLED_STATUS_N", "BMC_MAC2_INTB", "NMI_BTN_N", "BMC_NMI",
+			"", "", "", "",
+		/*  B */ "DDR_MEM_TEMP", "", "", "", "", "", "", "",
+		/*  C */ "", "", "", "", "PCIE_HP_SEL_N", "PCIE_SATA_SEL_N", "LOCATORBTN", "",
+		/*  D */ "BMC_PSIN", "BMC_PSOUT", "BMC_RESETCON", "RESETCON",
+			"", "", "", "PSU_FAN_FAIL_N",
+		/*  E */ "", "", "", "", "", "", "", "",
+		/*  F */ "NIC_PWR_GOOD", "PRSNTB0", "PRSNTB1", "PRSNTB2",
+			"PRSNTB3", "", "3VSB_PCIE1_PG", "12V_PCIE1_PG",
+		/*  G */ "HWM_BAT_EN", "CHASSIS_ID0", "CHASSIS_ID1", "CHASSIS_ID2",
+			"BMC_ALERT1_N_R", "BMC_ALERT2_N_R", "BMC_ALERT3_N", "BMC_ALERT4_N",
+		/*  H */ "X24_C1_PRSNT", "X24_C2_PRSNT", "X24_C3_PRSNT", "FM_MEM_THERM_EVENT_BMC_R_N",
+			"FACMODE", "BMC_RTCRST", "BMC_HB_LED_N", "BMC_CASEOPEN",
+		/*  I */ "", "", "", "", "", "", "", "",
+		/*  J */ "BMC_READY", "BMC_PCH_BIOS_CS_N", "", "P0_MA_DDR_QS_CS_N",
+			"", "", "", "",
+		/*  K */ "", "", "", "", "", "", "", "",
+		/*  L */ "", "", "", "", "", "", "", "",
+		/*  M */ "", "", "MEZZ_PWRBRK_N", "OCP_HP_RST_EN",
+			"MAIN_PWR_EN_G", "BMC_MAIN_EN", "AUX_PWR_EN_G", "BMC_AUX_EN",
+		/*  N */ "", "", "", "", "", "", "", "",
+		/*  O */ "", "", "", "", "", "", "", "",
+		/*  P */ "", "", "", "", "", "", "", "",
+		/*  Q */ "", "", "", "",
+			"BMC_SMB_PRESENT_1_N", "BMC_SMB_PRESENT_2_N",
+			"BMC_SMB_PRESENT_3_N", "BMC_PCIE_WAKE_N",
+		/*  R */ "", "", "THERMALTRIP_CLEAR_N", "", "", "", "", "",
+		/*  S */ "", "", "", "", "", "", "", "",
+		/*  T */ "", "", "", "", "", "", "", "",
+		/*  U */ "", "", "", "", "", "", "", "",
+		/*  V */ "", "", "", "", "", "", "", "",
+		/*  W */ "", "", "", "", "", "", "", "",
+		/*  X */ "", "", "", "", "", "", "", "",
+		/*  Y */ "SLP_S3", "SLP_S4_S5", "NODE_ID_1", "NODE_ID_2", "", "", "", "",
+		/*  Z */ "", "", "SYSTEM_FAULT_LED_N", "FAST_THROTTLE_N",
+			"", "", "", "",
+		/* AA */ "FM_CPU0_IBMC_THERMTRIP_N", "", "PROCHOT_L_G", "",
+			"", "", "", "",
+		/* AB */ "BMC_FORCE_SELFREFRESH", "PWRGD_OUT", "", "IRQ_BMC_PCH_SMI_LPC_N",
+			"", "", "", "",
+		/* AC */ "", "", "", "", "", "", "", "";
+};
+
+&adc {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_adc0_default
+		&pinctrl_adc1_default
+		&pinctrl_adc2_default
+		&pinctrl_adc3_default
+		&pinctrl_adc4_default
+		&pinctrl_adc5_default
+		&pinctrl_adc6_default
+		&pinctrl_adc7_default
+		&pinctrl_adc8_default
+		&pinctrl_adc9_default
+		&pinctrl_adc10_default
+		&pinctrl_adc11_default
+		&pinctrl_adc12_default
+		&pinctrl_adc13_default
+		&pinctrl_adc14_default
+		&pinctrl_adc15_default>;
+};
-- 
2.34.1



From vkoul at kernel.org  Wed Jan  5 02:20:17 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Wed, 5 Jan 2022 15:50:17 +0530
Subject: [PATCH v3 00/12] dmaengine: at_xdmac: Various fixes
In-Reply-To: <20211215110115.191749-1-tudor.ambarus@microchip.com>
References: <20211215110115.191749-1-tudor.ambarus@microchip.com>
Message-ID: <YdVw4f4y44iRUM5z@matsya>

On 15-12-21, 13:01, Tudor Ambarus wrote:
> Bugs identified when debugging a hang encountered when operating
> an octal DTR SPI NOR memory. The culprit was the flash, not the
> DMA driver, so all these bugs are not experienced in real life,
> they are all theoretical fixes. Nevertheless the bugs are there
> and I think they should be squashed.
> 
> Tested the serial with DMA on sama5d2_xplained. Tested QSPI with DMA on
> sama7g5ek. All went well.

Applied all, thanks

-- 
~Vinod


From lkp at intel.com  Wed Jan  5 02:22:29 2022
From: lkp at intel.com (kernel test robot)
Date: Wed, 5 Jan 2022 18:22:29 +0800
Subject: [PATCH] arm64: fix build error when use rodata_enabled
In-Reply-To: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
References: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
Message-ID: <202201051817.4KPMZJag-lkp@intel.com>

Hi AliOS,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on v5.16-rc8 next-20220105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/AliOS-system-security/arm64-fix-build-error-when-use-rodata_enabled/20220105-110838
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-randconfig-s032-20220105 (https://download.01.org/0day-ci/archive/20220105/202201051817.4KPMZJag-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/6af4245e93d33d4f4a79a560a707539be994f73e
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review AliOS-system-security/arm64-fix-build-error-when-use-rodata_enabled/20220105-110838
        git checkout 6af4245e93d33d4f4a79a560a707539be994f73e
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=arm64 SHELL=/bin/bash arch/arm64/mm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   arch/arm64/mm/mmu.c: In function 'map_entry_trampoline':
>> arch/arm64/mm/mmu.c:627:9: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
     627 |         phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
         |         ^~~~~~~~~~~


vim +627 arch/arm64/mm/mmu.c

28b066da69b937 Ard Biesheuvel        2017-03-09  618  
51a0048beb4496 Will Deacon           2017-11-14  619  #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
51a0048beb4496 Will Deacon           2017-11-14  620  static int __init map_entry_trampoline(void)
51a0048beb4496 Will Deacon           2017-11-14  621  {
6af4245e93d33d AliOS system security 2022-01-05  622  	pgprot_t prot = PAGE_KERNEL_EXEC;
6af4245e93d33d AliOS system security 2022-01-05  623  #if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
6af4245e93d33d AliOS system security 2022-01-05  624  	if (rodata_enabled)
6af4245e93d33d AliOS system security 2022-01-05  625  		prot = PAGE_KERNEL_ROX;
6af4245e93d33d AliOS system security 2022-01-05  626  #endif
51a0048beb4496 Will Deacon           2017-11-14 @627  	phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
51a0048beb4496 Will Deacon           2017-11-14  628  
51a0048beb4496 Will Deacon           2017-11-14  629  	/* The trampoline is always mapped and can therefore be global */
51a0048beb4496 Will Deacon           2017-11-14  630  	pgprot_val(prot) &= ~PTE_NG;
51a0048beb4496 Will Deacon           2017-11-14  631  
51a0048beb4496 Will Deacon           2017-11-14  632  	/* Map only the text into the trampoline page table */
51a0048beb4496 Will Deacon           2017-11-14  633  	memset(tramp_pg_dir, 0, PGD_SIZE);
51a0048beb4496 Will Deacon           2017-11-14  634  	__create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, PAGE_SIZE,
475ba3fc194b64 Will Deacon           2019-04-08  635  			     prot, __pgd_pgtable_alloc, 0);
51a0048beb4496 Will Deacon           2017-11-14  636  
6c27c4082f4f70 Will Deacon           2017-12-06  637  	/* Map both the text and data into the kernel page table */
51a0048beb4496 Will Deacon           2017-11-14  638  	__set_fixmap(FIX_ENTRY_TRAMP_TEXT, pa_start, prot);
6c27c4082f4f70 Will Deacon           2017-12-06  639  	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
6c27c4082f4f70 Will Deacon           2017-12-06  640  		extern char __entry_tramp_data_start[];
6c27c4082f4f70 Will Deacon           2017-12-06  641  
6c27c4082f4f70 Will Deacon           2017-12-06  642  		__set_fixmap(FIX_ENTRY_TRAMP_DATA,
6c27c4082f4f70 Will Deacon           2017-12-06  643  			     __pa_symbol(__entry_tramp_data_start),
6c27c4082f4f70 Will Deacon           2017-12-06  644  			     PAGE_KERNEL_RO);
6c27c4082f4f70 Will Deacon           2017-12-06  645  	}
6c27c4082f4f70 Will Deacon           2017-12-06  646  
51a0048beb4496 Will Deacon           2017-11-14  647  	return 0;
51a0048beb4496 Will Deacon           2017-11-14  648  }
51a0048beb4496 Will Deacon           2017-11-14  649  core_initcall(map_entry_trampoline);
51a0048beb4496 Will Deacon           2017-11-14  650  #endif
51a0048beb4496 Will Deacon           2017-11-14  651  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From tsbogend at alpha.franken.de  Wed Jan  5 02:42:02 2022
From: tsbogend at alpha.franken.de (Thomas Bogendoerfer)
Date: Wed, 5 Jan 2022 11:42:02 +0100
Subject: [PATCH v1 0/4] PCI: brcmstb: Augment driver for MIPs SOCs
In-Reply-To: <20211209204726.6676-1-jim2101024@gmail.com>
References: <20211209204726.6676-1-jim2101024@gmail.com>
Message-ID: <20220105104202.GD7009@alpha.franken.de>

On Thu, Dec 09, 2021 at 03:47:21PM -0500, Jim Quinlan wrote:
> With this patchset, the Broadcom STB PCIe controller driver 
> supports Arm, Arm64, and now MIPs.
> 
> Jim Quinlan (4):
>   dt-bindings: PCI: Add compatible string for Brcmstb 74[23]5 MIPs SOCs
>   MIPS: bmips: Add support PCIe controller device nodes
>   MIPS: bmips: Remove obsolete DMA mapping support
>   PCI: brcmstb: Augment driver for MIPs SOCs
> 
>  .../bindings/pci/brcm,stb-pcie.yaml           |   2 +
>  arch/mips/Kconfig                             |   1 -
>  arch/mips/bmips/dma.c                         | 106 +-----------------
>  arch/mips/boot/dts/brcm/bcm7425.dtsi          |  30 +++++
>  arch/mips/boot/dts/brcm/bcm7435.dtsi          |  30 +++++
>  arch/mips/boot/dts/brcm/bcm97425svmb.dts      |   9 ++
>  arch/mips/boot/dts/brcm/bcm97435svmb.dts      |   9 ++
>  drivers/pci/controller/Kconfig                |   2 +-
>  drivers/pci/controller/pcie-brcmstb.c         |  82 +++++++++++++-
>  9 files changed, 161 insertions(+), 110 deletions(-)

if nobody objects I'd like to add this series to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]


From p.zabel at pengutronix.de  Wed Jan  5 02:43:35 2022
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed, 05 Jan 2022 11:43:35 +0100
Subject: [PATCH v7 3/4] phy: rockchip: add naneng combo phy for RK3568
In-Reply-To: <20211230084815.28110-4-yifeng.zhao@rock-chips.com>
References: <20211230084815.28110-1-yifeng.zhao@rock-chips.com>
 <20211230084815.28110-4-yifeng.zhao@rock-chips.com>
Message-ID: <13c43c38b8494d374e204c4fa43f160770e7b662.camel@pengutronix.de>

On Thu, 2021-12-30 at 16:48 +0800, Yifeng Zhao wrote:
[...]
> +static int rockchip_combphy_parse_dt(struct device *dev, struct rockchip_combphy_priv *priv)
> +{
[...]
> +	priv->phy_rst = devm_reset_control_array_get(dev, false, false);

Please use devm_reset_control_array_get_exclusive() instead.

regards
Philipp


From angelogioacchino.delregno at collabora.com  Wed Jan  5 02:45:00 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 5 Jan 2022 11:45:00 +0100
Subject: [PATCH v10] drm/bridge: add it6505 driver
In-Reply-To: <20211014033031.38459-1-allen.chen@ite.com.tw>
References: <20211014033031.38459-1-allen.chen@ite.com.tw>
Message-ID: <9513a22c-5b84-88d9-ff5d-ac071df53ba3@collabora.com>

Il 14/10/21 05:30, allen ha scritto:
> This adds support for the iTE IT6505.
> This device can convert DPI signal to DP output.
> 
> From: Allen Chen <allen.chen at ite.com.tw>
> Tested-by: Hsin-yi Wang <hsinyi at chromium.org>
> Signed-off-by: Hermes Wu <hermes.wu at ite.com.tw>
> Signed-off-by: Allen Chen <allen.chen at ite.com.tw>
> ---
> This patch depends on https://patchwork.kernel.org/project/linux-mediatek/patch/20210722062246.2512666-4-sam at ravnborg.org/
> ---
>   drivers/gpu/drm/bridge/Kconfig      |    8 +
>   drivers/gpu/drm/bridge/Makefile     |    1 +
>   drivers/gpu/drm/bridge/ite-it6505.c | 3335 +++++++++++++++++++++++++++
>   3 files changed, 3344 insertions(+)
>   create mode 100644 drivers/gpu/drm/bridge/ite-it6505.c

Hello Allen,

since the dependency that you mentioned seems to be requiring some time to get
merged in, can you please open-code the call to drm_bridge_new_crtc_state() as
to stop requiring the commit you pointed to?

We can perhaps update this driver later, whenever the series you mentioned will
get applied.

The reason for this request is due to a breakage on MT8183 Kukui: since DPI is
supported in the drm-mediatek driver for this SoC, on platforms that are using
a DSI<->DP/eDP bridge, a probe failure occurs for the DPI0 component.
Leaving apart that drm-mediatek should be fixed to account for this as a non
critical error (and keep going with DSI only, simply ignoring DPI0), the Kukui
family of devices do have this functionality and it should be brought up as
soon as possible at this point - especially since the driver that you've sent
is ok to have.

Looking forward to see a v11 without unsatisfiable dependencies!

Thank you.

Regards,
- Angelo


From will at kernel.org  Wed Jan  5 02:45:26 2022
From: will at kernel.org (Will Deacon)
Date: Wed, 5 Jan 2022 10:45:26 +0000
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20220104202227.2903605-2-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
Message-ID: <20220105104526.GA3015@willie-the-truck>

On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> Some architectures automatically set the accessed bit in PTEs, e.g.,
> x86 and arm64 v8.2. On architectures that don't have this capability,
> clearing the accessed bit in a PTE usually triggers a page fault
> following the TLB miss of this PTE.
> 
> Being aware of this capability can help make better decisions, e.g.,
> whether to spread the work out over a period of time to avoid bursty
> page faults when trying to clear the accessed bit in a large number of
> PTEs.
> 
> Signed-off-by: Yu Zhao <yuzhao at google.com>
> Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> ---
>  arch/arm64/include/asm/cpufeature.h |  5 +++++
>  arch/arm64/include/asm/pgtable.h    | 13 ++++++++-----
>  arch/arm64/kernel/cpufeature.c      | 19 +++++++++++++++++++
>  arch/arm64/tools/cpucaps            |  1 +
>  arch/x86/include/asm/pgtable.h      |  6 +++---
>  include/linux/pgtable.h             | 13 +++++++++++++
>  mm/memory.c                         | 14 +-------------
>  7 files changed, 50 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef6be92b1921..99518b4b2a9e 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -779,6 +779,11 @@ static inline bool system_supports_tlb_range(void)
>  		cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
>  }
>  
> +static inline bool system_has_hw_af(void)
> +{
> +	return IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && cpus_have_const_cap(ARM64_HW_AF);
> +}
> +
>  extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
>  
>  static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index c4ba047a82d2..e736f47436c7 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -999,13 +999,16 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
>   * page after fork() + CoW for pfn mappings. We don't always have a
>   * hardware-managed access flag on arm64.
>   */
> -static inline bool arch_faults_on_old_pte(void)
> +static inline bool arch_has_hw_pte_young(bool local)
>  {
> -	WARN_ON(preemptible());
> +	if (local) {
> +		WARN_ON(preemptible());
> +		return cpu_has_hw_af();
> +	}
>  
> -	return !cpu_has_hw_af();
> +	return system_has_hw_af();
>  }
> -#define arch_faults_on_old_pte		arch_faults_on_old_pte
> +#define arch_has_hw_pte_young		arch_has_hw_pte_young
>  
>  /*
>   * Experimentally, it's cheap to set the access flag in hardware and we
> @@ -1013,7 +1016,7 @@ static inline bool arch_faults_on_old_pte(void)
>   */
>  static inline bool arch_wants_old_prefaulted_pte(void)
>  {
> -	return !arch_faults_on_old_pte();
> +	return arch_has_hw_pte_young(true);
>  }
>  #define arch_wants_old_prefaulted_pte	arch_wants_old_prefaulted_pte
>  
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6f3e677d88f1..5bb553ee2c0e 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2171,6 +2171,25 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
>  		.matches = has_hw_dbm,
>  		.cpu_enable = cpu_enable_hw_dbm,
>  	},
> +	{
> +		/*
> +		 * __cpu_setup always enables this capability. But if the boot
> +		 * CPU has it and a late CPU doesn't, the absent
> +		 * ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU will prevent this late CPU
> +		 * from going online. There is neither known hardware does that
> +		 * nor obvious reasons to design hardware works that way, hence
> +		 * no point leaving the door open here. If the need arises, a
> +		 * new weak system feature flag should do the trick.
> +		 */
> +		.desc = "Hardware update of the Access flag",
> +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> +		.capability = ARM64_HW_AF,
> +		.sys_reg = SYS_ID_AA64MMFR1_EL1,
> +		.sign = FTR_UNSIGNED,
> +		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
> +		.min_field_value = 1,
> +		.matches = has_cpuid_feature,
> +	},
>  #endif
>  	{
>  		.desc = "CRC32 instructions",
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..56e4ef5d95fa 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
>  HAS_SYSREG_GIC_CPUIF
>  HAS_TLB_RANGE
>  HAS_VIRT_HOST_EXTN
> +HW_AF
>  HW_DBM
>  KVM_PROTECTED_MODE
>  MISMATCHED_CACHE_TYPE

As discussed in the previous threads, we really don't need the complexity
of the additional cap for the arm64 part. Please can you just use the
existing code instead? It's both simpler and, as you say, it's equivalent
for existing hardware.

That way, this patch just ends up being a renaming exercise and we're all
good.

Thanks,

Will


From lorenzo.pieralisi at arm.com  Wed Jan  5 02:46:02 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 5 Jan 2022 10:46:02 +0000
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <20211231033725.21109-3-ilkka@os.amperecomputing.com>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
Message-ID: <20220105104602.GA4752@lpieralisi>

[+James, for SDEI bits]

On Thu, Dec 30, 2021 at 07:37:25PM -0800, Ilkka Koskinen wrote:
> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
> issue diagnostic dump and reset via an SDEI event or an interrupt.
> This patch implements SDEI path.
> 
> [0] https://developer.arm.com/documentation/den0093/latest/
> 
> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> ---
>  drivers/acpi/arm64/Kconfig  |   8 +++
>  drivers/acpi/arm64/Makefile |   1 +
>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>  3 files changed, 134 insertions(+)
>  create mode 100644 drivers/acpi/arm64/agdi.c
> 
> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
> index 6dba187f4f2e..24869ba5b365 100644
> --- a/drivers/acpi/arm64/Kconfig
> +++ b/drivers/acpi/arm64/Kconfig
> @@ -8,3 +8,11 @@ config ACPI_IORT
>  
>  config ACPI_GTDT
>  	bool
> +
> +config ACPI_AGDI
> +	bool "Arm Generic Diagnostic Dump and Reset Device Interface"
> +	depends on ARM_SDE_INTERFACE
> +	help
> +	  Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
> +	  a standard that enables issuing a non-maskable diagnostic dump and
> +	  reset command.
> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
> index 66acbe77f46e..7b9e4045659d 100644
> --- a/drivers/acpi/arm64/Makefile
> +++ b/drivers/acpi/arm64/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_ACPI_AGDI) 	+= agdi.o
>  obj-$(CONFIG_ACPI_IORT) 	+= iort.o
>  obj-$(CONFIG_ACPI_GTDT) 	+= gtdt.o
>  obj-y				+= dma.o
> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
> new file mode 100644
> index 000000000000..6525ccbae5c1
> --- /dev/null
> +++ b/drivers/acpi/arm64/agdi.c
> @@ -0,0 +1,125 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * This file implements handling of
> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
> + *
> + * Copyright (c) 2021, Ampere Computing LLC
> + */
> +
> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/acpi.h>
> +#include <linux/arm_sdei.h>
> +#include <linux/io.h>

Nit: alphabetical order.

> +
> +struct agdi_data {
> +	int sdei_event;
> +};
> +
> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
> +{
> +	nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
> +	return 0;
> +}
> +
> +static int agdi_sdei_probe(struct platform_device *pdev,
> +			   struct agdi_data *adata)
> +{
> +	int err;
> +
> +	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
> +	if (err) {
> +		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
> +			adata->sdei_event);
> +		return err;
> +	}
> +
> +	err = sdei_event_enable(adata->sdei_event);
> +	if (err)  {
> +		sdei_event_unregister(adata->sdei_event);
> +		dev_err(&pdev->dev, "Failed to enable event %d\n",
> +			adata->sdei_event);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static int agdi_probe(struct platform_device *pdev)
> +{
> +	struct agdi_data *adata;
> +
> +	adata = dev_get_platdata(&pdev->dev);
> +	if (!adata)
> +		return -EINVAL;
> +
> +	return agdi_sdei_probe(pdev, adata);
> +}
> +
> +static int agdi_remove(struct platform_device *pdev)
> +{
> +	struct agdi_data *adata = platform_get_drvdata(pdev);
> +
> +	sdei_event_disable(adata->sdei_event);
> +	sdei_event_unregister(adata->sdei_event);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver agdi_driver = {
> +	.driver = {
> +		.name = "agdi",
> +	},
> +	.probe = agdi_probe,
> +	.remove = agdi_remove,
> +};

May I ask why we need a platform device (and driver) to register
an SDEI event ?

> +static int __init agdi_init(void)
> +{
> +	int ret;
> +	acpi_status status;
> +	struct acpi_table_agdi *agdi_table;
> +	struct agdi_data pdata;
> +	struct platform_device *pdev;
> +
> +	if (acpi_disabled)
> +		return 0;

Why don't we call agdi_init() from acpi_init() as we do for IORT/VIOT ?

I don't think it is necessary to add a device_initcall(), with related
ordering dependencies.

> +
> +	status = acpi_get_table(ACPI_SIG_AGDI, 0,
> +				(struct acpi_table_header **) &agdi_table);
> +	if (ACPI_FAILURE(status))
> +		return -ENODEV;
> +
> +	if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {

Is this because specs need updating ?

> +		pr_warn("Interrupt signaling is not supported");
> +		ret = -ENODEV;
> +		goto err_put_table;
> +	}
> +
> +	pdata.sdei_event = agdi_table->sdei_event;
> +
> +	pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
> +	if (IS_ERR(pdev)) {
> +		ret = PTR_ERR(pdev);
> +		goto err_put_table;
> +	}
> +
> +	ret = platform_driver_register(&agdi_driver);
> +	if (ret)
> +		goto err_device_unregister;
> +
> +	acpi_put_table((struct acpi_table_header *)agdi_table);
> +	return 0;
> +
> +err_device_unregister:
> +	platform_device_unregister(pdev);
> +err_put_table:
> +	acpi_put_table((struct acpi_table_header *)agdi_table);
> +	return ret;
> +}
> +device_initcall(agdi_init);

See above.

Thanks,
Lorenzo


From mark.rutland at arm.com  Wed Jan  5 02:47:35 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 5 Jan 2022 10:47:35 +0000
Subject: [PATCH] arm64: fix build error when use rodata_enabled
In-Reply-To: <0432f592-789b-7c92-8d7a-99191d7bc669@arm.com>
References: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
 <0432f592-789b-7c92-8d7a-99191d7bc669@arm.com>
Message-ID: <YdV3RzQcGb2xFPhS@FVFF77S0Q05N>

On Wed, Jan 05, 2022 at 02:51:05PM +0530, Anshuman Khandual wrote:
> Hello,
> 
> On 1/5/22 8:37 AM, AliOS system security wrote:
> > rodata_enabled should be used when CONFIG_STRICT_KERNEL_RWX
> > or CONFIG_STRICT_MODULE_RWX is selected

Further to Anshuman's comments here, for a build issue, please include the
specific build error in the commit log, and describe the configuration where
this manifests.

For the reasons Anshuman gives below I do not see how this can be a problem in
mainline.

Thanks,
Mark.

> Both these configs get selected invariably with CONFIG_ARM64 in the
> platform config file (arch/arm64/Kconfig). I guess there can not be
> any such situation, where both configs will be missing/not selected
> given ARCH_OPTIONAL_KERNEL_RWX[or _DEFAULT] is not enabled on arm64.
> 
> config ARM64
>         def_bool y
>         select ACPI_CCA_REQUIRED if ACPI
> 	.....
>         select ARCH_HAS_STRICT_KERNEL_RWX
>         select ARCH_HAS_STRICT_MODULE_RWX
> 	.....
> 
> Hence for all practical purpose, rodata_enabled could be considered
> always available. I am sure there other similar situations as well,
> where code elements are not wrapped around if the config option is
> always present.
> 
> > 
> > Signed-off-by: AliOS system security <alios_sys_security at linux.alibaba.com>
> 
> Also please refer Documentation/process/submitting-patches.rst for
> the rules regarding names, that can be used for a commit sign off.
> 
> ------------------------------------------------------------------------
> then you just add a line saying::
> 
>         Signed-off-by: Random J Developer <random at developer.example.org>
> 
> using your real name (sorry, no pseudonyms or anonymous contributions.)
> ------------------------------------------------------------------------
> 
> - Anshuman
> 
> > ---
> >  arch/arm64/mm/mmu.c | 14 ++++++++++++--
> >  1 file changed, 12 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> > index acfae9b..47f8754 100644
> > --- a/arch/arm64/mm/mmu.c
> > +++ b/arch/arm64/mm/mmu.c
> > @@ -596,6 +596,7 @@ static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
> >  	vm_area_add_early(vma);
> >  }
> >  
> > +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
> >  static int __init parse_rodata(char *arg)
> >  {
> >  	int ret = strtobool(arg, &rodata_enabled);
> > @@ -613,11 +614,16 @@ static int __init parse_rodata(char *arg)
> >  	return 0;
> >  }
> >  early_param("rodata", parse_rodata);
> > +#endif
> >  
> >  #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
> >  static int __init map_entry_trampoline(void)
> >  {
> > -	pgprot_t prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
> > +	pgprot_t prot = PAGE_KERNEL_EXEC;
> > +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
> > +	if (rodata_enabled)
> > +		prot = PAGE_KERNEL_ROX;
> > +#endif
> >  	phys_addr_t pa_start = __pa_symbol(__entry_tramp_text_start);
> >  
> >  	/* The trampoline is always mapped and can therefore be global */
> > @@ -672,7 +678,11 @@ static void __init map_kernel(pgd_t *pgdp)
> >  	 * mapping to install SW breakpoints. Allow this (only) when
> >  	 * explicitly requested with rodata=off.
> >  	 */
> > -	pgprot_t text_prot = rodata_enabled ? PAGE_KERNEL_ROX : PAGE_KERNEL_EXEC;
> > +	pgprot_t text_prot = PAGE_KERNEL_EXEC;
> > +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX)
> > +	if (rodata_enabled)
> > +		text_prot = PAGE_KERNEL_ROX;
> > +#endif
> >  
> >  	/*
> >  	 * If we have a CPU that supports BTI and a kernel built for
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From anshuman.khandual at arm.com  Wed Jan  5 02:51:53 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 5 Jan 2022 16:21:53 +0530
Subject: [PATCH 2/4] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <0020da84-ce90-f269-27e1-6a6c90f6317b@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-3-git-send-email-anshuman.khandual@arm.com>
 <0020da84-ce90-f269-27e1-6a6c90f6317b@arm.com>
Message-ID: <464d0ab9-1d72-a0da-73e9-4eeccfc784c6@arm.com>


On 1/5/22 3:31 PM, Suzuki K Poulose wrote:
> Hi Anshuman
> 
> On 05/01/2022 05:05, Anshuman Khandual wrote:
>> TRBE implementations affected by Arm erratum #2064142 might fail to write
>> into certain system registers after the TRBE has been disabled. Under some
>> conditions after TRBE has been disabled, writes into certain TRBE registers
>> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
>> ignored and not be effected.
>>
>> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
>> just after the trace collection has stopped and before performing a system
>> register write to one of the affected registers. This adds a new cpu errata
>> in arm64 errata framework and also updates TRBE driver as required.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ? Documentation/arm64/silicon-errata.rst?????? |? 2 +
>> ? arch/arm64/Kconfig?????????????????????????? | 18 +++++++
>> ? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 ++++
>> ? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>> ? drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>> ? drivers/hwtracing/coresight/coresight-trbe.h |? 8 ---
>> ? 6 files changed, 68 insertions(+), 24 deletions(-)
> 
> I think it may be a good idea to split the patch into
> two parts :
> 
> - arm64 kernel part. (cpucap defintions and detection)
> - trbe driver part
> 
> So that it is easier to merge these series upstream to
> avoid conflicts.

Sure, will do.

> 
>>
>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>> index 5342e895fb60..c9b30e6c2b6c 100644
>> --- a/Documentation/arm64/silicon-errata.rst
>> +++ b/Documentation/arm64/silicon-errata.rst
>> @@ -52,6 +52,8 @@ stable kernels.
>> ? | Allwinner????? | A64/R18???????? | UNKNOWN1??????? | SUN50I_ERRATUM_UNKNOWN1???? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> +| ARM??????????? | Cortex-A510???? | #2064142??????? | ARM64_ERRATUM_2064142?????? |
>> ++----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index c4207cf9bb17..2105b68d88db 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
>> ? ??????? If unsure, say Y.
>> ? +config ARM64_ERRATUM_2064142
>> +??? bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
>> +??? depends on CORESIGHT_TRBE
>> +??? default y
>> +??? help
>> +????? This option adds the workaround for ARM Cortex-A510 erratum 2064142.
>> +
>> +????? Affected Cortex-A510 core might fail to write into system registers after the
>> +????? TRBE has been disabled. Under some conditions after the TRBE has been disabled
>> +????? writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
>> +????? and TRBTRG_EL1 will be ignored and will not be effected.
>> +
>> +????? Work around this in the driver by executing TSB CSYNC and DSB after collection
>> +????? is stopped and before performing a system register write to one of the affected
>> +????? registers.
>> +
>> +????? If unsure, say Y.
>> +
>> ? config CAVIUM_ERRATUM_22375
>> ????? bool "Cavium erratum 22375, 24313"
>> ????? default y
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index 9e1c1aef9ebd..cbb7d5a9aee7 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>> ????????? .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>> ????????? CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>> ????? },
>> +#endif
>> +#ifdef CONFIG_ARM64_ERRATUM_2064142
>> +??? {
>> +??????? .desc = "ARM erratum 2064142",
>> +??????? .capability = ARM64_WORKAROUND_2064142,
>> +
>> +??????? /* Cortex-A510 r0p0 - r0p2 */
>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>> +??? },
>> ? #endif
>> ????? {
>> ????? }
>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>> index 870c39537dd0..fca3cb329e1d 100644
>> --- a/arch/arm64/tools/cpucaps
>> +++ b/arch/arm64/tools/cpucaps
>> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>> ? WORKAROUND_1463225
>> ? WORKAROUND_1508412
>> ? WORKAROUND_1542419
>> +WORKAROUND_2064142
>> ? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>> ? WORKAROUND_TSB_FLUSH_FAILURE
>> ? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>> index 276862c07e32..ec24b62b2cec 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -91,10 +91,12 @@ struct trbe_buf {
>> ?? */
>> ? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>> ? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>> +#define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>> ? ? static int trbe_errata_cpucaps[] = {
>> ????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>> ????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>> +??? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
> 
> super minor nit: TRBE_NEEDS_DRAIN_AFTER_DISABLE
>>> ????? -1,??????? /* Sentinel, must be the last entry */
>> ? };
>> ? @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>> ????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>> ? }
>> ? +static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>> +{
> 
> minor nit: trbe_needs_drain_after_disable() ?

Changing this helper name and its index above would reflect actual
workaround implemented, instead of the errata which it is trying
to solve. Although the series has already broken that convention
in the last patch with trbe_is_broken() and TRBE_IS_BROKEN. If we
are going with TRBE_<work around required> format, I will have to
change the next workaround patch as well.

> 
> Either ways, the patch looks good to me.> 
> Suzuki


From yuzhao at google.com  Wed Jan  5 02:53:07 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 5 Jan 2022 03:53:07 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220105085534.22981-1-sj@kernel.org>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220105085534.22981-1-sj@kernel.org>
Message-ID: <YdV4k1+zEbtzmUkK@google.com>

On Wed, Jan 05, 2022 at 08:55:34AM +0000, SeongJae Park wrote:
> Hi Yu,
> 
> On Tue, 4 Jan 2022 13:22:19 -0700 Yu Zhao <yuzhao at google.com> wrote:
> 
> > TLDR
> > ====
> > The current page reclaim is too expensive in terms of CPU usage and it
> > often makes poor choices about what to evict. This patchset offers an
> > alternative solution that is performant, versatile and
> > straightforward.
> >  
> [...]
> > Summery
> > =======
> > The facts are:
> > 1. The independent lab results and the real-world applications
> >    indicate substantial improvements; there are no known regressions.
> 
> So impressive results!
> 
> > 2. Thrashing prevention, working set estimation and proactive reclaim
> >    work out of the box; there are no equivalent solutions.
> 
> I think similar works are already available out of the box with the latest
> mainline tree, though it might be suboptimal in some cases.

Ok, I will sound harsh because I hate it when people challenge facts
while having no idea what they are talking about.

Our jobs are help the leadership make best decisions by providing them
with facts, not feeding them crap.

Don't get me wrong -- you are welcome to start another thread and have
a casual discussion with me. But this thread is not for that; it's for
the leadership and stakeholder to make a decision. Check who are in
"To" and "Cc" and what my request is.

> I didn't read this patchset thoroughly yet, so I might missing many things.  If
> so, please feel free to let me know.

Yes, apparently you didn't read this patchset thoroughly, and you have
missed all things that matter to this thread.

> First, you can do thrashing prevention using DAMON-based Operation Scheme
> (DAMOS)[1] with MADV_COLD action.

Here is thrashing prevention really means, from patch 8:
  +Personal computers
  +------------------
  +:Thrashing prevention: Write ``N`` to
  + ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
  + ``N`` milliseconds from getting evicted. The OOM killer is invoked if
  + this working set can't be kept in memory. Based on the average human
  + detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
  + lags due to thrashing. Larger values like ``N=3000`` make lags less
  + noticeable at the cost of more OOM kills.

It's about when to trigger OOM kills. Got it? Or probably you don't
understand what MADV_COLD is either?

> Second, for working set estimation, you can either use the DAMOS
> again with statistics action, or the damon_aggregated tracepoint[2].

This is you are suggesting:
  TRACE_EVENT(damon_aggregated,
    TP_printk("target_id=%lu nr_regions=%u %lu-%lu: %u",
              __entry->target_id, __entry->nr_regions,
              __entry->start, __entry->end, __entry->nr_accesses)

Now read my doc again:
  +Data centers
  +------------
  +:Debugfs interface: ``/sys/kernel/debug/lru_gen`` has the following
  + format:
  +   memcg  memcg_id  memcg_path
  +     node  node_id

Have you heard of something called memcg? And NUMA node? How exactly
can this tracepoint provide information about different memcgs and
NUMA node?

> The DAMON user space tool[3] helps the tracepoint analysis and
> visualization.

What does "work out of box" mean? Should every Linux desktop, laptop
and phone user install this tool?

> Finally, for the proactive reclaim, you can again use the DAMOS
> with MADV_PAGEOUT action

How exactly does MADV_PAGEOUT find pages that are NOT mapped in page
tables? Let me tell you another fact: they are usually the cheapest to
reclaim.

> or simply the DAMON-based proactive reclaim module (DAMON_RECLAIM)[4].
> [4] https://docs.kernel.org/admin-guide/mm/damon/reclaim.html

How many knob does DAMON_RECLAIM have? 14? I lost count.

> Of course, the integration might not be so simple as seems to me now.

Look, I'm open to your suggestion. I probably should have been nicer.
So I'm sorry. I just don't appreciate alternative facts.


From o.rempel at pengutronix.de  Wed Jan  5 03:04:34 2022
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Wed, 5 Jan 2022 12:04:34 +0100
Subject: [PATCH v1 4/4] ARM: dts: imx6dl: plym2m, prtvt7, victgo:  make
 use of new resistive-adc-touch driver
In-Reply-To: <20211206010627.GK4216@dragon>
References: <20211122124310.2796505-1-o.rempel@pengutronix.de>
 <20211122124310.2796505-4-o.rempel@pengutronix.de>
 <20211206010627.GK4216@dragon>
Message-ID: <20220105110434.GG303@pengutronix.de>

Hi Shawn,

sorry for the delay, I just came back to work.

On Mon, Dec 06, 2021 at 09:06:28AM +0800, Shawn Guo wrote:
> On Mon, Nov 22, 2021 at 01:43:10PM +0100, Oleksij Rempel wrote:
> > The tsc2046 is an ADC used as touchscreen controller. To share as mach
> > code as possible, we should use it as actual ADC + virtual tochscreen
> > controller.
> > With this patch we make use of the new kernel IIO and HID infrastructure.
> > 
> > Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> 
> One space is enough in subject "victgo:  make".

done.

> > ---
> >  arch/arm/boot/dts/imx6dl-plym2m.dts | 55 ++++++++++++++++++++---------
> >  arch/arm/boot/dts/imx6dl-prtvt7.dts | 53 ++++++++++++++++++++-------
> >  arch/arm/boot/dts/imx6dl-victgo.dts | 55 +++++++++++++++++++++--------
> >  3 files changed, 120 insertions(+), 43 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/imx6dl-plym2m.dts b/arch/arm/boot/dts/imx6dl-plym2m.dts
> > index 60fe5f14666e..e2afedae85cb 100644
> > --- a/arch/arm/boot/dts/imx6dl-plym2m.dts
> > +++ b/arch/arm/boot/dts/imx6dl-plym2m.dts
> > @@ -101,6 +101,17 @@ reg_12v0: regulator-12v0 {
> >  		regulator-min-microvolt = <12000000>;
> >  		regulator-max-microvolt = <12000000>;
> >  	};
> > +
> > +	touchscreen {
> > +		compatible = "resistive-adc-touch";
> > +		io-channels = <&adc 1>, <&adc 3>, <&adc 4>, <&adc 5>;
> > +		io-channel-names = "y", "z1", "z2", "x";
> > +		touchscreen-min-pressure = <64687>;
> > +		touchscreen-inverted-x;
> > +		touchscreen-inverted-y;
> > +		touchscreen-x-plate-ohms = <300>;
> > +		touchscreen-y-plate-ohms = <800>;
> > +	};
> >  };
> >  
> >  &can1 {
> > @@ -129,26 +140,38 @@ &ecspi2 {
> >  	pinctrl-0 = <&pinctrl_ecspi2>;
> >  	status = "okay";
> >  
> > -	touchscreen at 0 {
> > -		compatible = "ti,tsc2046";
> > +	adc: adc at 0 {
> 
> Isn't label name "adc" too generic?

I do not have strong opinion about this. Currently we have no
restrictions for the node names:
Documentation/devicetree/bindings/iio/adc/ti,tsc2046.yaml
Documentation/devicetree/bindings/iio/adc/adc.yaml

I can name it touchscreen-adc at 0 or something like this. What are your
preferences?

Regards,
Oleksij
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From jonathanh at nvidia.com  Wed Jan  5 03:08:38 2022
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 5 Jan 2022 11:08:38 +0000
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
References: <20211122092816.2865873-1-ardb@kernel.org>
 <CGME20211221103854eucas1p2592e38fcc84c1c3506fce87f1dab6739@eucas1p2.samsung.com>
 <20211122092816.2865873-8-ardb@kernel.org>
 <0ffc858f-27e7-6789-4be1-c4c5ad61eb9d@samsung.com>
 <CAMj1kXG+P5AU-26t_16FL5xfQNd+ByQH_cfBLiwMSdoGPmvCuw@mail.gmail.com>
 <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
Message-ID: <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>

Hi Ard,

On 28/12/2021 14:39, Geert Uytterhoeven wrote:

...

>> As i don't have access to this hardware, I am going to have to rely on
>> someone who does to debug this further. The only alternative is
>> marking CONFIG_VMAP_STACK broken on MACH_EXYNOS but that would be
>> unfortunate.
> 
> Wish I had seen this thread before...
> 
> I've just bisected a resume after s2ram failure on R-Car Gen2 to the same
> commit a1c510d0adc604bb ("ARM: implement support for vmap'ed stacks")
> in arm/for-next.
> 
> Expected output:
> 
>      PM: suspend entry (deep)
>      Filesystems sync: 0.000 seconds
>      Freezing user space processes ... (elapsed 0.010 seconds) done.
>      OOM killer disabled.
>      Freezing remaining freezable tasks ... (elapsed 0.009 seconds) done.
>      Disabling non-boot CPUs ...
> 
> [system suspended, this is also where it hangs on failure]
> 
>      Enabling non-boot CPUs ...
>      CPU1 is up
>      sh-eth ee700000.ethernet eth0: Link is Down
>      Micrel KSZ8041RNLI ee700000.ethernet-ffffffff:01: attached PHY
> driver (mii_bus:phy_addr=ee700000.ethernet-ffffffff:01, irq=193)
>      OOM killer enabled.
>      Restarting tasks ... done.
>      PM: suspend exit
> 
> Both wake-on-LAN and wake-up by gpio-keys fail.
> Nothing interesting in the kernel log, cfr. above.
> 
> Disabling CONFIG_VMAP_STACK fixes the issue for me.
> 
> Just like arch/arm/mach-exynos/ (and others), arch/arm/mach-shmobile/
> has several *.S files related to secondary CPU bringup.


This is also breaking suspend on our 32-bit Tegra platforms. Reverting 
this change on top of -next fixes the problem.

Cheers
Jon

-- 
nvpublic


From linmq006 at gmail.com  Wed Jan  5 03:10:54 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Wed,  5 Jan 2022 11:10:54 +0000
Subject: [PATCH] media: atmel: atmel-isc: Fix PM disable depth imbalance in
 atmel_isc_probe
Message-ID: <20220105111056.4662-1-linmq006@gmail.com>

The pm_runtime_enable will increase power disable depth.
If the probe fails, we should use pm_runtime_disable() to balance
pm_runtime_enable().

Fixes: 0a0e265 ("media: atmel: atmel-isc: split driver into driver base and isc")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/media/platform/atmel/atmel-sama5d2-isc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index 1b2063cce0f7..88a81c3ada90 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -559,6 +559,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
 cleanup_subdev:
 	isc_subdev_cleanup(isc);
 
+disable_pm_runtime:
+	pm_runtime_disable(dev);
+
 unregister_v4l2_device:
 	v4l2_device_unregister(&isc->v4l2_dev);
 
-- 
2.17.1



From bp at alien8.de  Wed Jan  5 03:12:20 2022
From: bp at alien8.de (Borislav Petkov)
Date: Wed, 5 Jan 2022 12:12:20 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdV4k1+zEbtzmUkK@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220105085534.22981-1-sj@kernel.org>
 <YdV4k1+zEbtzmUkK@google.com>
Message-ID: <YdV9FNxYDRrgiejD@zn.tnic>

On Wed, Jan 05, 2022 at 03:53:07AM -0700, Yu Zhao wrote:
> Look, I'm open to your suggestion. I probably should have been nicer.
> So I'm sorry. I just don't appreciate alternative facts.

Yes, you should've been *much* nicer. I'm reading lkml for pretty much
20 years now and you just made my eyebrows go up - something which
pretty much never happens these days.

So you need to check yourself before replying. Looking at git history,
you're not a newbie so you've probably picked up - at least from the
sidelines - all those code of conduct discussions. And I'm not going to
point you to it - I'm sure you can find it yourself and peruse it at
your own convenience.

Long story short: we all try to be civil to each other now, even if it
is hard sometimes.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette


From ardb at kernel.org  Wed Jan  5 03:12:38 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 5 Jan 2022 12:12:38 +0100
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
References: <20211122092816.2865873-1-ardb@kernel.org>
 <CGME20211221103854eucas1p2592e38fcc84c1c3506fce87f1dab6739@eucas1p2.samsung.com>
 <20211122092816.2865873-8-ardb@kernel.org>
 <0ffc858f-27e7-6789-4be1-c4c5ad61eb9d@samsung.com>
 <CAMj1kXG+P5AU-26t_16FL5xfQNd+ByQH_cfBLiwMSdoGPmvCuw@mail.gmail.com>
 <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
 <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
Message-ID: <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>

On Wed, 5 Jan 2022 at 12:08, Jon Hunter <jonathanh at nvidia.com> wrote:
>
> Hi Ard,
>
> On 28/12/2021 14:39, Geert Uytterhoeven wrote:
>
> ...
>
> >> As i don't have access to this hardware, I am going to have to rely on
> >> someone who does to debug this further. The only alternative is
> >> marking CONFIG_VMAP_STACK broken on MACH_EXYNOS but that would be
> >> unfortunate.
> >
> > Wish I had seen this thread before...
> >
> > I've just bisected a resume after s2ram failure on R-Car Gen2 to the same
> > commit a1c510d0adc604bb ("ARM: implement support for vmap'ed stacks")
> > in arm/for-next.
> >
> > Expected output:
> >
> >      PM: suspend entry (deep)
> >      Filesystems sync: 0.000 seconds
> >      Freezing user space processes ... (elapsed 0.010 seconds) done.
> >      OOM killer disabled.
> >      Freezing remaining freezable tasks ... (elapsed 0.009 seconds) done.
> >      Disabling non-boot CPUs ...
> >
> > [system suspended, this is also where it hangs on failure]
> >
> >      Enabling non-boot CPUs ...
> >      CPU1 is up
> >      sh-eth ee700000.ethernet eth0: Link is Down
> >      Micrel KSZ8041RNLI ee700000.ethernet-ffffffff:01: attached PHY
> > driver (mii_bus:phy_addr=ee700000.ethernet-ffffffff:01, irq=193)
> >      OOM killer enabled.
> >      Restarting tasks ... done.
> >      PM: suspend exit
> >
> > Both wake-on-LAN and wake-up by gpio-keys fail.
> > Nothing interesting in the kernel log, cfr. above.
> >
> > Disabling CONFIG_VMAP_STACK fixes the issue for me.
> >
> > Just like arch/arm/mach-exynos/ (and others), arch/arm/mach-shmobile/
> > has several *.S files related to secondary CPU bringup.
>
>
> This is also breaking suspend on our 32-bit Tegra platforms. Reverting
> this change on top of -next fixes the problem.
>

Thanks for the report.

It would be helpful if you could provide some more context:
- does it happen on a LPAE build too?
- does it only happen on SMP capable systems?
- does it reproduce on such systems when using only a single CPU?
(i.e., pass 'nosmp' on the kernel command line)
- when passing 'no_console_suspend' on the kernel command line, are
any useful diagnostics produced?
- is there any way you could tell whether the crash/hang (assuming
that is what you are observing) occurs on the suspend path or on
resume?
- any other observations that could narrow this down?

Thanks,
Ard.


From anshuman.khandual at arm.com  Wed Jan  5 03:16:34 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 5 Jan 2022 16:46:34 +0530
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
 <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>
Message-ID: <68961242-3d9b-a26d-3a0f-0d2ace04a17b@arm.com>



On 1/5/22 3:43 PM, Suzuki K Poulose wrote:
> Hi Anshuman
> 
> On 05/01/2022 05:05, Anshuman Khandual wrote:
>> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
>> an inconsistent view on whether trace is prohibited within the CPU. As a
>> result, the trace buffer or trace buffer state might be corrupted. This
>> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
>> followed by just a single context synchronization event before execution
>> changes from a context, in which trace is prohibited to one where it isn't,
>> or vice versa. In these mentioned conditions, the view of whether trace is
>> prohibited is inconsistent between parts of the CPU, and the trace buffer
>> or the trace buffer state might be corrupted.
>>
>> Work around this problem in the TRBE driver by preventing an inconsistent
>> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
>> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
>> instruction before an ERET, or two ISB instructions if no ERET is to take
>> place. This adds a new cpu errata in arm64 errata framework and also
>> updates TRBE driver as required.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ? Documentation/arm64/silicon-errata.rst?????? |? 2 +
>> ? arch/arm64/Kconfig?????????????????????????? | 23 ++++++++++
>> ? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 ++++
>> ? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>> ? drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>> ? 5 files changed, 72 insertions(+), 10 deletions(-)
> 
> As with the previous patch, it may be a good idea to split the
> patch to arm64 and trbe parts.

Sure, will do.

> 
>>
>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
>> --- a/Documentation/arm64/silicon-errata.rst
>> +++ b/Documentation/arm64/silicon-errata.rst
>> @@ -54,6 +54,8 @@ stable kernels.
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A510???? | #2064142??????? | ARM64_ERRATUM_2064142?????? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> +| ARM??????????? | Cortex-A510???? | #2038923??????? | ARM64_ERRATUM_2038923?????? |
>> ++----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 2105b68d88db..026e34fb6fad 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>> ? ??????? If unsure, say Y.
>> ? +config ARM64_ERRATUM_2038923
>> +??? bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
>> +??? depends on CORESIGHT_TRBE
>> +??? default y
>> +??? help
>> +????? This option adds the workaround for ARM Cortex-A510 erratum 2038923.
>> +
>> +????? Affected Cortex-A510 core might cause an inconsistent view on whether trace is
>> +????? prohibited within the CPU. As a result, the trace buffer or trace buffer state
>> +????? might be corrupted. This happens after TRBE buffer has been enabled by setting
>> +????? TRBLIMITR_EL1.E, followed by just a single context synchronization event before
>> +????? execution changes from a context, in which trace is prohibited to one where it
>> +????? isn't, or vice versa. In these mentioned conditions, the view of whether trace
>> +????? is prohibited is inconsistent between parts of the CPU, and the trace buffer or
>> +????? the trace buffer state might be corrupted.
>> +
>> +????? Work around this in the driver by preventing an inconsistent view of whether the
>> +????? trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
>> +????? change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
>> +????? two ISB instructions if no ERET is to take place.
>> +
>> +????? If unsure, say Y.
>> +
>> ? config CAVIUM_ERRATUM_22375
>> ????? bool "Cavium erratum 22375, 24313"
>> ????? default y
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index cbb7d5a9aee7..60b0c1f1d912 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>> ????????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>> ????? },
>> ? #endif
>> +#ifdef CONFIG_ARM64_ERRATUM_2038923
>> +??? {
>> +??????? .desc = "ARM erratum 2038923",
>> +??????? .capability = ARM64_WORKAROUND_2038923,
>> +
>> +??????? /* Cortex-A510 r0p0 - r0p2 */
>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>> +??? },
>> +#endif
>> ????? {
>> ????? }
>> ? };
>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>> index fca3cb329e1d..45a06d36d080 100644
>> --- a/arch/arm64/tools/cpucaps
>> +++ b/arch/arm64/tools/cpucaps
>> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>> ? WORKAROUND_1508412
>> ? WORKAROUND_1542419
>> ? WORKAROUND_2064142
>> +WORKAROUND_2038923
>> ? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>> ? WORKAROUND_TSB_FLUSH_FAILURE
>> ? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>> index ec24b62b2cec..0689c6dab96d 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -92,11 +92,13 @@ struct trbe_buf {
>> ? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>> ? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>> ? #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE??? 3
>> ? ? static int trbe_errata_cpucaps[] = {
>> ????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>> ????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>> ????? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>> +??? [TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>> ????? -1,??????? /* Sentinel, must be the last entry */
>> ? };
>> ? @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>> ????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>> ? }
>> ? +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>> +{
> 
> minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?

trbe_needs_ctxt_sync_after_enable() sounds better. Also will have to change
the index above as well .. TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE.

> 
>> +??? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>> +}
>> +
>> ? static int trbe_alloc_node(struct perf_event *event)
>> ? {
>> ????? if (event->cpu == -1)
>> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>> ????? dsb(nsh);
>> ? }
>> ? +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
>> +{
>> +??? u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
> 
> minor nit: This implies we do the TRBE programming in the following
> manner in the common case (i.e, TRBE enabled in the beginning of a
> session).
> ? -> set TRBE LIMIT
> ? -> read TRBE LIMIT
> ? -> set TRBE ENABLED
> 
> Could we please optimize this ? I believe the buf->trbe_limit
> must hold the LIMITR value at any point in time. And thus this

But is not bit risky though ! We have got the following places where
given trbe_limit instance changes its value.

drivers/../coresight-trbe.c:   buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE;
drivers/../coresight-trbe.c:   buf->trbe_limit = compute_trbe_buffer_limit(handle);
drivers/../coresight-trbe.c:   buf->trbe_limit -= PAGE_SIZE;

> function could simply be :
> 
> set_trbe_enabled(trbe_buf)
> {
> ????limitr = trbe_buf->limit | LIMITR_ENABLE
> ????write(limitr, TRBLIMITR_EL1);
> ????...
> }

Is the potential for performance improvement here, out weigh possible
risks of using buf->trbe_limit directly while enabling the TRBE ?

> 
> Otherwise looks good to me
> 
> Suzuki


From sj at kernel.org  Wed Jan  5 03:25:27 2022
From: sj at kernel.org (SeongJae Park)
Date: Wed,  5 Jan 2022 11:25:27 +0000
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdV4k1+zEbtzmUkK@google.com>
Message-ID: <20220105112527.23399-1-sj@kernel.org>

On Wed, 5 Jan 2022 03:53:07 -0700 Yu Zhao <yuzhao at google.com> wrote:

> On Wed, Jan 05, 2022 at 08:55:34AM +0000, SeongJae Park wrote:
> > Hi Yu,
> > 
> > On Tue, 4 Jan 2022 13:22:19 -0700 Yu Zhao <yuzhao at google.com> wrote:
[...]
> > I think similar works are already available out of the box with the latest
> > mainline tree, though it might be suboptimal in some cases.
> 
> Ok, I will sound harsh because I hate it when people challenge facts
> while having no idea what they are talking about.
> 
> Our jobs are help the leadership make best decisions by providing them
> with facts, not feeding them crap.

I was using the word "similar", to represent this is only for a rough concept
level similarity, rather than detailed facts.  But, seems it was not enough,
sorry.  Anyway, I will not talk more and thus disturb you having the important
discussion with leaders here, as you are asking.

> 
> Don't get me wrong -- you are welcome to start another thread and have
> a casual discussion with me. But this thread is not for that; it's for
> the leadership and stakeholder to make a decision. Check who are in
> "To" and "Cc" and what my request is.

Haha.  Ok, good luck for you.


Thanks,
SJ

[...]


From daniel.lezcano at linaro.org  Wed Jan  5 03:25:56 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 5 Jan 2022 12:25:56 +0100
Subject: [PATCH v5 5/6] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <CAPDyKFqWUJTKte3dM=7xG6EtKR8i9neCCNYFs7Jf1J34TezUEQ@mail.gmail.com>
References: <20211218130014.4037640-1-daniel.lezcano@linaro.org>
 <20211218130014.4037640-6-daniel.lezcano@linaro.org>
 <CAPDyKFqWUJTKte3dM=7xG6EtKR8i9neCCNYFs7Jf1J34TezUEQ@mail.gmail.com>
Message-ID: <dee9df5e-acab-579a-017c-d5f22e9e042c@linaro.org>

On 31/12/2021 14:57, Ulf Hansson wrote:

[ ... ]

>> +static struct dtpm_node __initdata rk3399_hierarchy[] = {
>> +       [0]{ .name = "rk3399" },
>> +       [1]{ .name = "package",
>> +            .parent = &rk3399_hierarchy[0] },
>> +       [2]{ .name = "/cpus/cpu at 0",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [3]{ .name = "/cpus/cpu at 1",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [4]{ .name = "/cpus/cpu at 2",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [5]{ .name = "/cpus/cpu at 3",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [6]{ .name = "/cpus/cpu at 100",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [7]{ .name = "/cpus/cpu at 101",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [8]{ .name = "rockchip,rk3399-mali",
>> +            .type = DTPM_NODE_DT,
>> +            .parent = &rk3399_hierarchy[1] },
>> +       [9]{ },
>> +};
> 
> I will not object to this, as in the end this seems like what we need
> to do, unless we can describe things through generic DT bindings for
> DTPM. Right?

Yes, as asked by Rob, we should try to describe in the kernel first.

> Although, if the above is correct, I need to stress that I am kind of
> worried that this doesn't really scale. We would need to copy lots of
> information from the DTS files into platform specific c-files, to be
> able to describe the DTPM hierarchy.

TBH I don't think it is a lot and it is a __initdata. At least we should
begin with something and see later how to consolidate if it is needed, no?


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From will at kernel.org  Wed Jan  5 03:25:55 2022
From: will at kernel.org (Will Deacon)
Date: Wed, 5 Jan 2022 11:25:55 +0000
Subject: [PATCH v13 3/5] arm64: perf: Add userspace counter access
 disable switch
In-Reply-To: <20220104135658.GC1827@willie-the-truck>
References: <20211208201124.310740-1-robh@kernel.org>
 <20211208201124.310740-4-robh@kernel.org>
 <CAMuHMdVcDxR9sGzc5pcnORiotonERBgc6dsXZXMd6wTvLGA9iw@mail.gmail.com>
 <20220104135658.GC1827@willie-the-truck>
Message-ID: <20220105112555.GA3113@willie-the-truck>

On Tue, Jan 04, 2022 at 01:56:59PM +0000, Will Deacon wrote:
> On Tue, Dec 28, 2021 at 12:07:02PM +0100, Geert Uytterhoeven wrote:
> > On Wed, Dec 8, 2021 at 9:19 PM Rob Herring <robh at kernel.org> wrote:
> > > Like x86, some users may want to disable userspace PMU counter
> > > altogether. Add a sysctl 'perf_user_access' file to control userspace
> > > counter access. The default is '0' which is disabled. Writing '1'
> > > enables access.
> > >
> > > Note that x86 supports globally enabling user access by writing '2' to
> > > /sys/bus/event_source/devices/cpu/rdpmc. As there's not existing
> > > userspace support to worry about, this shouldn't be necessary for Arm.
> > > It could be added later if the need arises.
> > 
> > Thanks for your patch, which is now commit e2012600810c9ded ("arm64:
> > perf: Add userspace counter access disable switch") in arm64/for-next/core.
> > 
> > This is causing two issues on Renesas Salvator-XS with R-Car H3.
> > One during kernel boot:
> > 
> >      hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7
> > counters available
> >     +sysctl duplicate entry: /kernel//perf_user_access
> >     +CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> > 5.16.0-rc3-arm64-renesas-00003-ge2012600810c #1420
> >     +Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
> >     +Call trace:
> >     + dump_backtrace+0x0/0x190
> >     + show_stack+0x14/0x20
> >     + dump_stack_lvl+0x88/0xb0
> >     + dump_stack+0x14/0x2c
> >     + __register_sysctl_table+0x384/0x818
> >     + register_sysctl+0x20/0x28
> >     + armv8_pmu_init.constprop.0+0x118/0x150
> >     + armv8_a57_pmu_init+0x1c/0x28
> >     + arm_pmu_device_probe+0x1b4/0x558
> >     + armv8_pmu_device_probe+0x18/0x20
> >     + platform_probe+0x64/0xd0
> >     + really_probe+0xb4/0x2f8
> >     + __driver_probe_device+0x74/0xd8
> >     + driver_probe_device+0x3c/0xe0
> >     + __driver_attach+0x80/0x110
> >     + bus_for_each_dev+0x6c/0xc0
> >     + driver_attach+0x20/0x28
> >     + bus_add_driver+0x138/0x1e0
> >     + driver_register+0x60/0x110
> >     + __platform_driver_register+0x24/0x30
> >     + armv8_pmu_driver_init+0x18/0x20
> >     + do_one_initcall+0x15c/0x31c
> >     + kernel_init_freeable+0x2f0/0x354
> >     + kernel_init+0x20/0x120
> >     + ret_from_fork+0x10/0x20
> >      hw perfevents: enabled with armv8_cortex_a57 PMU driver, 7
> > counters available
> > 
> > Presumably the same entry is added twice, once for the A53 PMU,
> > and a second time for the A57 PMU?
> 
> Looks like it, and perhaps that's also what is confusing systemd?
> Rob -- how come you didn't see this during your testing?
> 
> Anywho, please can you try the untested diff below?

I just remembered I have a big/little SoC on my desk after borrowing a
NanoPi (RK3399) from Marc Z, so I took this diff for a spin there and
both the kernel and systemd seem happy.

Will


From patchwork-bot+netdevbpf at kernel.org  Wed Jan  5 03:30:11 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 05 Jan 2022 11:30:11 +0000
Subject: [PATCH v12 0/3] net: ethernet: mtk_eth_soc: refactoring and
 Clause 45
In-Reply-To: <YdQ4HzLjpuVW4YFi@makrotopia.org>
References: <YdQ4HzLjpuVW4YFi@makrotopia.org>
Message-ID: <164138221163.4307.616203536271666789.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <davem at davemloft.net>:

On Tue, 4 Jan 2022 12:05:51 +0000 you wrote:
> Rework value and type of mdio read and write functions in mtk_eth_soc
> and generally clean up and unify both functions.
> Then add support to access Clause 45 phy registers, using newly
> introduced helper macros added by a patch Russell King has suggested
> in a reply to an earlier version of this series [1].
> 
> All three commits are tested on the Bananapi BPi-R64 board having
> MediaTek MT7531BE DSA gigE switch using clause 22 MDIO and
> Ubiquiti UniFi 6 LR access point having Aquantia AQR112C PHY using
> clause 45 MDIO.
> 
> [...]

Here is the summary with links:
  - [v12,1/3] net: ethernet: mtk_eth_soc: fix return values and refactor MDIO ops
    https://git.kernel.org/netdev/net-next/c/eda80b249df7
  - [v12,2/3] net: mdio: add helpers to extract clause 45 regad and devad fields
    https://git.kernel.org/netdev/net-next/c/c6af53f038aa
  - [v12,3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO access
    https://git.kernel.org/netdev/net-next/c/e2e7f6e29c99

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From jonathanh at nvidia.com  Wed Jan  5 03:33:48 2022
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 5 Jan 2022 11:33:48 +0000
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
References: <20211122092816.2865873-1-ardb@kernel.org>
 <CGME20211221103854eucas1p2592e38fcc84c1c3506fce87f1dab6739@eucas1p2.samsung.com>
 <20211122092816.2865873-8-ardb@kernel.org>
 <0ffc858f-27e7-6789-4be1-c4c5ad61eb9d@samsung.com>
 <CAMj1kXG+P5AU-26t_16FL5xfQNd+ByQH_cfBLiwMSdoGPmvCuw@mail.gmail.com>
 <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
 <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
 <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
Message-ID: <4ae3e371-68d0-64d7-713e-88af45875b3f@nvidia.com>


On 05/01/2022 11:12, Ard Biesheuvel wrote:

...

> Thanks for the report.
> 
> It would be helpful if you could provide some more context:
> - does it happen on a LPAE build too?
> - does it only happen on SMP capable systems?

These are all SMP systems.

> - does it reproduce on such systems when using only a single CPU?
> (i.e., pass 'nosmp' on the kernel command line)

I would need to try this.

> - when passing 'no_console_suspend' on the kernel command line, are
> any useful diagnostics produced?
> - is there any way you could tell whether the crash/hang (assuming
> that is what you are observing) occurs on the suspend path or on
> resume?
> - any other observations that could narrow this down?

I can run the above and let you know what I find.

Cheers
Jon

-- 
nvpublic


From suzuki.poulose at arm.com  Wed Jan  5 03:59:31 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 5 Jan 2022 11:59:31 +0000
Subject: [PATCH 4/4] coresight: trbe: Workaround TRBE trace data corruption
In-Reply-To: <1641359159-22726-5-git-send-email-anshuman.khandual@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-5-git-send-email-anshuman.khandual@arm.com>
Message-ID: <adbe2a0a-4ed8-4b86-453d-94fec96757e2@arm.com>

On 05/01/2022 05:05, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #1902691 might corrupt trace
> data or deadlock, when it's being written into the memory. Workaround this
> problem in the driver, by preventing TRBE initialization on affected cpus.
> This adds a new cpu errata in arm64 errata framework and also updates TRBE
> driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst       |  2 ++
>   arch/arm64/Kconfig                           | 16 ++++++++++++++++
>   arch/arm64/kernel/cpu_errata.c               |  9 +++++++++
>   arch/arm64/tools/cpucaps                     |  1 +
>   drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
>   5 files changed, 40 insertions(+)
> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index e0ef3e9a4b8b..50018f60c4d4 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -56,6 +56,8 @@ stable kernels.
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #1902691        | ARM64_ERRATUM_1902691       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 026e34fb6fad..1ea5c3b4aac0 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -819,6 +819,22 @@ config ARM64_ERRATUM_2038923
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_1902691
> +	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
> +	depends on CORESIGHT_TRBE
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
> +
> +	  Affected Cortex-A510 core might cause trace data corruption, when being written
> +	  into the memory. Effectively TRBE is broken and hence cannot be used to capture
> +	  trace data.
> +
> +	  Work around this problem in the driver by just preventing TRBE initialization on
> +	  affected cpus.
> +
> +	  If unsure, say Y.
> +

It might be better to add :

"The firmware must have disabled the access to TRBE for the kernel on 
such implementations. This will cover the kernel for any firmware that
doesn't do this already"


>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 60b0c1f1d912..a3336dfb5a8a 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {	
>   		/* Cortex-A510 r0p0 - r0p2 */
>   		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>   	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_1902691
> +	{
> +		.desc = "ARM erratum 1902691",
> +		.capability = ARM64_WORKAROUND_1902691,
> +
> +		/* Cortex-A510 r0p0 - r0p1 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
> +	},
>   #endif
>   	{
>   	}
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 45a06d36d080..e7719e8f18de 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -57,6 +57,7 @@ WORKAROUND_1508412
>   WORKAROUND_1542419
>   WORKAROUND_2064142
>   WORKAROUND_2038923
> +WORKAROUND_1902691
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 0689c6dab96d..b9b4e34fac15 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -93,12 +93,14 @@ struct trbe_buf {
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
>   #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE	2
>   #define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE	3
> +#define TRBE_IS_BROKEN	4
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>   	[TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>   	[TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
> +	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -181,6 +183,11 @@ static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>   }
>   
> +static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
> +{
> +	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -1291,6 +1298,11 @@ static void arm_trbe_probe_cpu(void *info)
>   	 */
>   	trbe_check_errata(cpudata);
>   
> +	if (trbe_is_broken(cpudata)) {
> +		pr_err("TRBE might corrupt the trace on cpu %d\n", cpu);

It may be better to say:

		"Disabling TRBE on CPU%d due to erratum"

Otherwise looks good to me.

Suzuki


From s.hauer at pengutronix.de  Wed Jan  5 04:20:39 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 5 Jan 2022 13:20:39 +0100
Subject: [PATCH 22/22] drm: rockchip: Add VOP2 driver
In-Reply-To: <a0942adc-52c1-811e-0de6-d0616266ce2d@rock-chips.com>
References: <20211220110630.3521121-1-s.hauer@pengutronix.de>
 <20211220110630.3521121-23-s.hauer@pengutronix.de>
 <a0942adc-52c1-811e-0de6-d0616266ce2d@rock-chips.com>
Message-ID: <20220105122039.GU6003@pengutronix.de>

Hi Andy,

On Tue, Jan 04, 2022 at 07:07:23PM +0800, Andy Yan wrote:
> 
> 
> I thinks we should be very carefully about switch to regmap.
> 
> Most of the registers are take effect by frame sync(that is you write the
> config done bit and when vsync interrupt come),
> 
> Not only windows register, but also the SYS_CTRL, post processor(VP0/1/2),?
> OVERLAY, hdr and so on.

That's why I marked these as nonvolatile, so that reading the registers
comes from the cache. I may have missed some registers, these could be
added when needed.

> > +	ret = vop2_win_init(vop2);
> > +	if (ret)
> > +		return ret;
> Do you have a count about how much time the function vop2_win_init cost ?

No. Why does that matter?

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From ezequiel at vanguardiasur.com.ar  Wed Jan  5 04:26:33 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 5 Jan 2022 09:26:33 -0300
Subject: [PATCH v4 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20220104073842.1791639-2-benjamin.gaignard@collabora.com>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
 <20220104073842.1791639-2-benjamin.gaignard@collabora.com>
Message-ID: <YdWOecbZHO+Skbnn@eze-laptop>

Hi Benjamin,

On Tue, Jan 04, 2022 at 08:38:41AM +0100, Benjamin Gaignard wrote:
> Marking a picture as long-term reference is valid for DPB but not for RPS.
> Change flag name to match with it description in HEVC spec chapiter
> "8.3.2 Decoding process for reference picture set".
> Remove the other unused RPS flags.
> 

A change like this, which is affecting a kernel interface and has impact
on userspace and drivers, requires a lot more attention in the commit description.

If I understand correctly, this change is related to how HEVC was first
introduced and how the DPB was originally represented in V4L2.

Originally, a DPB entry struct v4l2_hevc_dpb_entry had an rps field
which can be:

  V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE
  V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER
  V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR

Perhaps this idea followed libva, where a VAPictureHEVC has flags field
which can be:

  VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE, 
  VA_PICTURE_HEVC_RPS_ST_CURR_AFTER,
  VA_PICTURE_HEVC_RPS_LT_CURR,
  VA_PICTURE_HEVC_LONG_TERM_REFERENCE

In this representation, the sets PocStCurrBefore, PocStCurrAfter,
PocLtCurr are implicit, and must be built by the kernel from the DPB
entries struct v4l2_hevc_dpb_entry, using the information in the rps field.

Last year, we changed this with your commit:

commit d395a78db9eabd12633b39e05c80e803543b6590
Author: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Date:   Thu Jun 3 13:49:57 2021 +0200

    media: hevc: Add decode params control

Which added the control v4l2_ctrl_hevc_decode_params, which includes
the sets PocStCurrBefore, PocStCurrAfter, PocLtCurr explicitly and therefore
moved the responsability of creating and maintaining the sets to userspace.

This effectively made the rps field in the struct v4l2_hevc_dpb_entry
useless. The longterm flag is still needed though for a DPB entry.

With this in mind, you could even say this commit is doing actually two
things:

1. Removes the unused rps field.
2. Adds a flag field, for the longterm DPB entry boolean.

Do you think a single byte of flags will be OK for a DPB entry?
I think so, but I'd love yours/others input here.

If the above is more or less accurate then, and provided you
submit a new version with a more detailed commit description:

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Also, a small question:

> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> ---
> version 4:
> - check flags with & and not ==
> 
>  Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 8 +++-----
>  drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
>  drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
>  include/media/hevc-ctrls.h                                | 6 ++----
>  4 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index e141f0e4eec9..38da33e61c3d 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -3166,11 +3166,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>  	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
>  	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
>      * - __u8
> -      - ``rps``
> -      - The reference set for the reference frame
> -        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
> -        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
> -        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
> +      - ``flags``
> +      - Long term flag for the reference frame
> +        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)

Is this longterm flag associated in any way to a syntax element
or an HEVC process? If so, please document that.

Thanks,
Ezequiel


From ezequiel at vanguardiasur.com.ar  Wed Jan  5 04:28:39 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Wed, 5 Jan 2022 09:28:39 -0300
Subject: [PATCH v4 2/2] media: hevc: Embedded indexes in RPS
In-Reply-To: <20220104073842.1791639-3-benjamin.gaignard@collabora.com>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
 <20220104073842.1791639-3-benjamin.gaignard@collabora.com>
Message-ID: <YdWO9+6XUh3SFnvj@eze-laptop>


On Tue, Jan 04, 2022 at 08:38:42AM +0100, Benjamin Gaignard wrote:
> Reference Picture Set lists provide indexes of short and long term
> reference in DBP array.
> Fix Hantro to not do a look up in DBP entries.
> Make documentation more clear about it.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

> ---
>  .../media/v4l/ext-ctrls-codec.rst             |  6 ++---
>  .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++--------------
>  2 files changed, 9 insertions(+), 22 deletions(-)
> 
> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> index 38da33e61c3d..b12ad5b3eaba 100644
> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
> @@ -3381,15 +3381,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>      * - __u8
>        - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>        - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
> -        picture set.
> +        picture set": provides the index of the short term before references in DPB array.
>      * - __u8
>        - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>        - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
> -        picture set.
> +        picture set": provides the index of the short term after references in DPB array.
>      * - __u8
>        - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
>        - PocLtCurr as described in section 8.3.2 "Decoding process for reference
> -        picture set.
> +        picture set": provides the index of the long term references in DPB array.
>      * - __u64
>        - ``flags``
>        - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
> diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> index 14e0e6414100..c524af41baf5 100644
> --- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> +++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
> @@ -255,24 +255,11 @@ static void set_params(struct hantro_ctx *ctx)
>  	hantro_reg_write(vpu, &g2_apf_threshold, 8);
>  }
>  
> -static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt)
> -{
> -	int i;
> -
> -	for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
> -		if (dpb[i].pic_order_cnt[0] == pic_order_cnt)
> -			return i;
> -	}
> -
> -	return 0x0;
> -}
> -
>  static void set_ref_pic_list(struct hantro_ctx *ctx)
>  {
>  	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
>  	struct hantro_dev *vpu = ctx->dev;
>  	const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
> -	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
>  	u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
>  	u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
>  	static const struct hantro_reg ref_pic_regs0[] = {
> @@ -316,11 +303,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
>  	/* List 0 contains: short term before, short term after and long term */
>  	j = 0;
>  	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++)
> -		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
> +		list0[j++] = decode_params->poc_st_curr_before[i];
>  	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++)
> -		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
> +		list0[j++] = decode_params->poc_st_curr_after[i];
>  	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++)
> -		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
> +		list0[j++] = decode_params->poc_lt_curr[i];
>  
>  	/* Fill the list, copying over and over */
>  	i = 0;
> @@ -329,11 +316,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
>  
>  	j = 0;
>  	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++)
> -		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
> +		list1[j++] = decode_params->poc_st_curr_after[i];
>  	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++)
> -		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
> +		list1[j++] = decode_params->poc_st_curr_before[i];
>  	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++)
> -		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
> +		list1[j++] = decode_params->poc_lt_curr[i];
>  
>  	i = 0;
>  	while (j < ARRAY_SIZE(list1))
> -- 
> 2.30.2
> 


From anshuman.khandual at arm.com  Wed Jan  5 04:39:15 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 5 Jan 2022 18:09:15 +0530
Subject: [PATCH 4/4] coresight: trbe: Workaround TRBE trace data corruption
In-Reply-To: <adbe2a0a-4ed8-4b86-453d-94fec96757e2@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-5-git-send-email-anshuman.khandual@arm.com>
 <adbe2a0a-4ed8-4b86-453d-94fec96757e2@arm.com>
Message-ID: <03220d4a-281e-20b5-0962-3831ce3a8ec1@arm.com>



On 1/5/22 5:29 PM, Suzuki K Poulose wrote:
> On 05/01/2022 05:05, Anshuman Khandual wrote:
>> TRBE implementations affected by Arm erratum #1902691 might corrupt trace
>> data or deadlock, when it's being written into the memory. Workaround this
>> problem in the driver, by preventing TRBE initialization on affected cpus.
>> This adds a new cpu errata in arm64 errata framework and also updates TRBE
>> driver as required.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ? Documentation/arm64/silicon-errata.rst?????? |? 2 ++
>> ? arch/arm64/Kconfig?????????????????????????? | 16 ++++++++++++++++
>> ? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 +++++++++
>> ? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>> ? drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
>> ? 5 files changed, 40 insertions(+)
>>
>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>> index e0ef3e9a4b8b..50018f60c4d4 100644
>> --- a/Documentation/arm64/silicon-errata.rst
>> +++ b/Documentation/arm64/silicon-errata.rst
>> @@ -56,6 +56,8 @@ stable kernels.
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A510???? | #2038923??????? | ARM64_ERRATUM_2038923?????? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> +| ARM??????????? | Cortex-A510???? | #1902691??????? | ARM64_ERRATUM_1902691?????? |
>> ++----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>> ? +----------------+-----------------+-----------------+-----------------------------+
>> ? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 026e34fb6fad..1ea5c3b4aac0 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -819,6 +819,22 @@ config ARM64_ERRATUM_2038923
>> ? ??????? If unsure, say Y.
>> ? +config ARM64_ERRATUM_1902691
>> +??? bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
>> +??? depends on CORESIGHT_TRBE
>> +??? default y
>> +??? help
>> +????? This option adds the workaround for ARM Cortex-A510 erratum 1902691.
>> +
>> +????? Affected Cortex-A510 core might cause trace data corruption, when being written
>> +????? into the memory. Effectively TRBE is broken and hence cannot be used to capture
>> +????? trace data.
>> +
>> +????? Work around this problem in the driver by just preventing TRBE initialization on
>> +????? affected cpus.
>> +
>> +????? If unsure, say Y.
>> +
> 
> It might be better to add :
> 
> "The firmware must have disabled the access to TRBE for the kernel on such implementations. This will cover the kernel for any firmware that
> doesn't do this already"

Right, will add it.

> 
> 
>> ? config CAVIUM_ERRATUM_22375
>> ????? bool "Cavium erratum 22375, 24313"
>> ????? default y
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index 60b0c1f1d912..a3336dfb5a8a 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {???
>> ????????? /* Cortex-A510 r0p0 - r0p2 */
>> ????????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>> ????? },
>> +#endif
>> +#ifdef CONFIG_ARM64_ERRATUM_1902691
>> +??? {
>> +??????? .desc = "ARM erratum 1902691",
>> +??????? .capability = ARM64_WORKAROUND_1902691,
>> +
>> +??????? /* Cortex-A510 r0p0 - r0p1 */
>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
>> +??? },
>> ? #endif
>> ????? {
>> ????? }
>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>> index 45a06d36d080..e7719e8f18de 100644
>> --- a/arch/arm64/tools/cpucaps
>> +++ b/arch/arm64/tools/cpucaps
>> @@ -57,6 +57,7 @@ WORKAROUND_1508412
>> ? WORKAROUND_1542419
>> ? WORKAROUND_2064142
>> ? WORKAROUND_2038923
>> +WORKAROUND_1902691
>> ? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>> ? WORKAROUND_TSB_FLUSH_FAILURE
>> ? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>> index 0689c6dab96d..b9b4e34fac15 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -93,12 +93,14 @@ struct trbe_buf {
>> ? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>> ? #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>> ? #define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE??? 3
>> +#define TRBE_IS_BROKEN??? 4
>> ? ? static int trbe_errata_cpucaps[] = {
>> ????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>> ????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>> ????? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>> ????? [TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>> +??? [TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
>> ????? -1,??????? /* Sentinel, must be the last entry */
>> ? };
>> ? @@ -181,6 +183,11 @@ static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>> ????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>> ? }
>> ? +static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
>> +{
>> +??? return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
>> +}
>> +
>> ? static int trbe_alloc_node(struct perf_event *event)
>> ? {
>> ????? if (event->cpu == -1)
>> @@ -1291,6 +1298,11 @@ static void arm_trbe_probe_cpu(void *info)
>> ?????? */
>> ????? trbe_check_errata(cpudata);
>> ? +??? if (trbe_is_broken(cpudata)) {
>> +??????? pr_err("TRBE might corrupt the trace on cpu %d\n", cpu);
> 
> It may be better to say:
> 
> ??????? "Disabling TRBE on CPU%d due to erratum"

Mention the erratum #1902691 as well or not required ?

> 
> Otherwise looks good to me.
> 
> Suzuki


From peng.fan at oss.nxp.com  Wed Jan  5 04:43:04 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Wed,  5 Jan 2022 20:43:04 +0800
Subject: [PATCH] clocksource/drivers/imx-tpm: exclude sched clock for ARM64
Message-ID: <20220105124304.3567629-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

For ARM64 platform such as i.MX8ULP which has ARMv8 generic timer as sched
clock, which is much faster compared with tpm sched clock. Reading the
tpm count register in i.MX8ULP requires about 290ns, this is slow and
introduce scheduler latency. So exclude tpm sched clock for ARM64
platform.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/clocksource/timer-imx-tpm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-imx-tpm.c b/drivers/clocksource/timer-imx-tpm.c
index 2cdc077a39f5..2bd530b9adc4 100644
--- a/drivers/clocksource/timer-imx-tpm.c
+++ b/drivers/clocksource/timer-imx-tpm.c
@@ -150,10 +150,10 @@ static int __init tpm_clocksource_init(void)
 	tpm_delay_timer.read_current_timer = &tpm_read_current_timer;
 	tpm_delay_timer.freq = timer_of_rate(&to_tpm) >> 3;
 	register_current_timer_delay(&tpm_delay_timer);
-#endif
 
 	sched_clock_register(tpm_read_sched_clock, counter_width,
 			     timer_of_rate(&to_tpm) >> 3);
+#endif
 
 	return clocksource_mmio_init(timer_base + TPM_CNT,
 				     "imx-tpm",
-- 
2.25.1



From anshuman.khandual at arm.com  Wed Jan  5 04:48:37 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 5 Jan 2022 18:18:37 +0530
Subject: =?UTF-8?B?UmU6IOWbnuWkje+8mltQQVRDSF0gYXJtNjQ6IGZpeCBidWlsZCBlcnJv?=
 =?UTF-8?Q?r_when_use_rodata=5fenabled?=
In-Reply-To: <6f37012b-b082-457f-9aee-2315a461c031.alios_sys_security@linux.alibaba.com>
References: <1641352075-25200-1-git-send-email-alios_sys_security@linux.alibaba.com>
 <0432f592-789b-7c92-8d7a-99191d7bc669@arm.com>
 <6f37012b-b082-457f-9aee-2315a461c031.alios_sys_security@linux.alibaba.com>
Message-ID: <0380f75f-ac8f-5f0f-93e7-20ed07a0d549@arm.com>



On 1/5/22 6:07 PM, AliOS system security wrote:
> Hello,
> When I commen out these configs like below to disable rodata function for debug purpose

Then it's a modified custom kernel, not mainline anymore.

> 
> diff?--git?a/arch/arm64/Kconfig?b/arch/arm64/Kconfig
> index?3bb0b67..40fbd85?100644
> ---?a/arch/arm64/Kconfig
> +++?b/arch/arm64/Kconfig
> @@?-36,8?+36,8?@@?config?ARM64
> ????????select?ARCH_HAS_SET_DIRECT_MAP
> ????????select?ARCH_HAS_SET_MEMORY
> ????????select?ARCH_STACKWALK
> -???????select?ARCH_HAS_STRICT_KERNEL_RWX
> -???????select?ARCH_HAS_STRICT_MODULE_RWX
> +#??????select?ARCH_HAS_STRICT_KERNEL_RWX
> +#??????select?ARCH_HAS_STRICT_MODULE_RWX
> ????????select?ARCH_HAS_SYNC_DMA_FOR_DEVICE
> 
> then build failed with below log:
> arch/arm64/mm/mmu.c:?In?function??parse_rodata?:
> arch/arm64/mm/mmu.c:601:28:?error:??rodata_enabled??undeclared?(first?use?in?this?function);?did?you?mean??kasan_enabled??
> ??int?ret?=?strtobool(arg,?&rodata_enabled);
> ????????????????????????????^~~~~~~~~~~~~~
> ????????????????????????????kasan_enabled
> arch/arm64/mm/mmu.c:601:28:?note:?each?undeclared?identifier?is?reported?only?once?for?each?function?it?appears?in
> ??CC??????net/core/skbuff.o
> arch/arm64/mm/mmu.c:?In?function??map_entry_trampoline?:
> arch/arm64/mm/mmu.c:620:18:?error:??rodata_enabled??undeclared?(first?use?in?this?function);?did?you?mean??kasan_enabled??
> ??pgprot_t?prot?=?rodata_enabled???PAGE_KERNEL_ROX?:?PAGE_KERNEL_EXEC;

These build errors are caused on a modified kernel, not mainline.

> 
> I hope these configs can be used at least for function test.
> And wrap around variable when it is defined within?macro should be better.?

If the config options are not user selectable (which is the case here), they
should not be used for testing. Because there might be already assumptions in
the kernel, around its availability.

> 
> Thanks!
> 
>     ------------------------------------------------------------------
>     ????Anshuman Khandual <anshuman.khandual at arm.com>
>     ?????2022?1?5?(???) 17:21
>     ????AliOS system security <alios_sys_security at linux.alibaba.com>; catalin.marinas <catalin.marinas at arm.com>; will <will at kernel.org>
>     ????linux-arm-kernel <linux-arm-kernel at lists.infradead.org>; linux-kernel <linux-kernel at vger.kernel.org>
>     ????Re: [PATCH] arm64: fix build error when use rodata_enabled
> 
>     Hello,
> 
>     On?1/5/22?8:37?AM,?AliOS?system?security?wrote:
>     >?rodata_enabled?should?be?used?when?CONFIG_STRICT_KERNEL_RWX
>     >?or?CONFIG_STRICT_MODULE_RWX?is?selected
> 
>     Both?these?configs?get?selected?invariably?with?CONFIG_ARM64?in?the
>     platform?config?file?(arch/arm64/Kconfig).?I?guess?there?can?not?be
>     any?such?situation,?where?both?configs?will?be?missing/not?selected
>     given?ARCH_OPTIONAL_KERNEL_RWX[or?_DEFAULT]?is?not?enabled?on?arm64.
> 
>     config?ARM64
>     ????????def_bool?y
>     ????????select?ACPI_CCA_REQUIRED?if?ACPI
>     ?.....
>     ????????select?ARCH_HAS_STRICT_KERNEL_RWX
>     ????????select?ARCH_HAS_STRICT_MODULE_RWX
>     ?.....
> 
>     Hence?for?all?practical?purpose,?rodata_enabled?could?be?considered
>     always?available.?I?am?sure?there?other?similar?situations?as?well,
>     where?code?elements?are?not?wrapped?around?if?the?config?option?is
>     always?present.
> 
>     >?
>     >?Signed-off-by:?AliOS?system?security?<alios_sys_security at linux.alibaba.com>
> 
>     Also?please?refer?Documentation/process/submitting-patches.rst?for
>     the?rules?regarding?names,?that?can?be?used?for?a?commit?sign?off.
> 
>     ------------------------------------------------------------------------
>     then?you?just?add?a?line?saying::
> 
>     ????????Signed-off-by:?Random?J?Developer?<random at developer.example.org>
> 
>     using?your?real?name?(sorry,?no?pseudonyms?or?anonymous?contributions.)
>     ------------------------------------------------------------------------
> 
>     -?Anshuman
> 
>     >?---
>     >??arch/arm64/mm/mmu.c?|?14?++++++++++++--
>     >??1?file?changed,?12?insertions(+),?2?deletions(-)
>     >?
>     >?diff?--git?a/arch/arm64/mm/mmu.c?b/arch/arm64/mm/mmu.c
>     >?index?acfae9b..47f8754?100644
>     >?---?a/arch/arm64/mm/mmu.c
>     >?+++?b/arch/arm64/mm/mmu.c
>     >?@@?-596,6?+596,7?@@?static?void?__init?map_kernel_segment(pgd_t?*pgdp,?void?*va_start,?void?*va_end,
>     >???vm_area_add_early(vma);
>     >??}
>     >??
>     >?+#if?defined(CONFIG_STRICT_KERNEL_RWX)?||?defined(CONFIG_STRICT_MODULE_RWX)
>     >??static?int?__init?parse_rodata(char?*arg)
>     >??{
>     >???int?ret?=?strtobool(arg,?&rodata_enabled);
>     >?@@?-613,11?+614,16?@@?static?int?__init?parse_rodata(char?*arg)
>     >???return?0;
>     >??}
>     >??early_param("rodata",?parse_rodata);
>     >?+#endif
>     >??
>     >??#ifdef?CONFIG_UNMAP_KERNEL_AT_EL0
>     >??static?int?__init?map_entry_trampoline(void)
>     >??{
>     >?-?pgprot_t?prot?=?rodata_enabled???PAGE_KERNEL_ROX?:?PAGE_KERNEL_EXEC;
>     >?+?pgprot_t?prot?=?PAGE_KERNEL_EXEC;
>     >?+#if?defined(CONFIG_STRICT_KERNEL_RWX)?||?defined(CONFIG_STRICT_MODULE_RWX)
>     >?+?if?(rodata_enabled)
>     >?+??prot?=?PAGE_KERNEL_ROX;
>     >?+#endif
>     >???phys_addr_t?pa_start?=?__pa_symbol(__entry_tramp_text_start);
>     >??
>     >???/*?The?trampoline?is?always?mapped?and?can?therefore?be?global?*/
>     >?@@?-672,7?+678,11?@@?static?void?__init?map_kernel(pgd_t?*pgdp)
>     >????*?mapping?to?install?SW?breakpoints.?Allow?this?(only)?when
>     >????*?explicitly?requested?with?rodata=off.
>     >????*/
>     >?-?pgprot_t?text_prot?=?rodata_enabled???PAGE_KERNEL_ROX?:?PAGE_KERNEL_EXEC;
>     >?+?pgprot_t?text_prot?=?PAGE_KERNEL_EXEC;
>     >?+#if?defined(CONFIG_STRICT_KERNEL_RWX)?||?defined(CONFIG_STRICT_MODULE_RWX)
>     >?+?if?(rodata_enabled)
>     >?+??text_prot?=?PAGE_KERNEL_ROX;
>     >?+#endif
>     >??
>     >???/*
>     >????*?If?we?have?a?CPU?that?supports?BTI?and?a?kernel?built?for
>     >?
> 
> 


From shameerali.kolothum.thodi at huawei.com  Wed Jan  5 05:25:13 2022
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Wed, 5 Jan 2022 13:25:13 +0000
Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
In-Reply-To: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <d82034bb5c954de692a02bd13ccbf5d8@huawei.com>

Hi,

A gentle ping on this series. Please take a look and let me know the new approach
taken in this revision is good enough or not. 

Appreciate your feedback.

Thanks,
Shameer

> -----Original Message-----
> From: linux-arm-kernel [mailto:linux-arm-kernel-bounces at lists.infradead.org]
> On Behalf Of Shameer Kolothum
> Sent: 22 November 2021 12:19
> To: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org
> Cc: maz at kernel.org; will at kernel.org; catalin.marinas at arm.com;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Jonathan Cameron
> <jonathan.cameron at huawei.com>; Linuxarm <linuxarm at huawei.com>
> Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
> 
> Changes from v3:
> - Main change is in patch #4, where the VMID is now set to an
>   invalid one on vCPU schedule out. Introduced an
>   INVALID_ACTIVE_VMID which is basically a VMID 0 with generation 1.
> ? Since the basic allocator algorithm reserves vmid #0, it is never
>   used as an active VMID. This (hopefully) will fix the issue of
>   unnecessarily reserving VMID space with active_vmids when those
>   VMs are no longer active[0] and at the same time address the
>   problem noted in v3 wherein everything ends up in slow-path[1].
> 
> Testing:
> ?-Run with VMID bit set to 4 and maxcpus to 8 on D06. The test
>   involves running concurrently 50 guests with 4 vCPUs. Each
>   guest will then execute hackbench 5 times before exiting.
>   No crash was observed for a 4-day continuous run.
> ? The latest branch is here,
> ? ?https://github.com/hisilicon/kernel-dev/tree/private-v5.16-rc1-vmid-v4
> 
> ?-TLA+ model. Modified the asidalloc model to incorporate the new
>   VMID algo. The main differences are,
> ? -flush_tlb_all() instead of local_tlb_flush_all() on rollover.
> ? -Introduced INVALID_VMID and vCPU Sched Out logic.
> ? -No CnP (Removed UniqueASIDAllCPUs & UniqueASIDActiveTask invariants).
> ? -Removed ?UniqueVMIDPerCPU invariant for now as it looks like
>    because of the speculative fetching with flush_tlb_all() there
>    is a small window where this gets triggered. If I change the
>    logic back to local_flush_tlb_all(), UniqueVMIDPerCPU seems to
>    be fine. With my limited knowledge on TLA+ model, it is not
>    clear to me whether this is a problem with the above logic
>    or the VMID model implementation. Really appreciate any help
>    with the model.
>    The initial VMID TLA+ model is here,
>    https://github.com/shamiali2008/kernel-tla/tree/private-vmidalloc-v1
> 
> Please take a look and let me know.
> 
> Thanks,
> Shameer
> 
> [0]
> https://lore.kernel.org/kvmarm/20210721160614.GC11003 at willie-the-truck/
> [1]
> https://lore.kernel.org/kvmarm/20210803114034.GB30853 at willie-the-truck/
> 
> History:
> --------
> v2 --> v3
>   -Dropped adding a new static key and cpufeature for retrieving
>    supported VMID bits. Instead, we now make use of the
>    kvm_arm_vmid_bits variable (patch #2).
> 
>   -Since we expect less frequent rollover in the case of VMIDs,
>    the TLB invalidation is now broadcasted on rollover instead
>    of keeping per CPU flush_pending info and issuing a local
>    context flush.
> 
>   -Clear active_vmids on vCPU schedule out to avoid unnecessarily
>    reserving the VMID space(patch #3).
> 
>   -I have kept the struct kvm_vmid as it is for now(instead of a
>    typedef as suggested), as we may soon add another variable to
>    it when we introduce Pinned KVM VMID support.
> 
> RFCv1 --> v2
>    -Dropped "pinned VMID" support for now.
>    -Dropped RFC tag.
> RFCv1
> 
> https://lore.kernel.org/kvmarm/20210506165232.1969-1-shameerali.kolothu
> m.thodi at huawei.com/
> 
> Julien Grall (1):
>   KVM: arm64: Align the VMID allocation with the arm64 ASID
> 
> Shameer Kolothum (3):
>   KVM: arm64: Introduce a new VMID allocator for KVM
>   KVM: arm64: Make VMID bits accessible outside of allocator
>   KVM: arm64: Make active_vmids invalid on vCPU schedule out
> 
>  arch/arm64/include/asm/kvm_host.h     |  10 +-
>  arch/arm64/include/asm/kvm_mmu.h      |   4 +-
>  arch/arm64/kernel/image-vars.h        |   3 +
>  arch/arm64/kvm/Makefile               |   2 +-
>  arch/arm64/kvm/arm.c                  | 106 +++-----------
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c |   3 +-
>  arch/arm64/kvm/mmu.c                  |   1 -
>  arch/arm64/kvm/vmid.c                 | 196
> ++++++++++++++++++++++++++
>  8 files changed, 228 insertions(+), 97 deletions(-)  create mode 100644
> arch/arm64/kvm/vmid.c
> 
> --
> 2.17.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

From robh at kernel.org  Wed Jan  5 05:30:21 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 5 Jan 2022 07:30:21 -0600
Subject: [PATCH 1/8] dt-bindings: rng: apm, x-gene-rng: convert APM RNG to
 dtschema
In-Reply-To: <20211227183251.132525-1-krzysztof.kozlowski@canonical.com>
References: <20211227183251.132525-1-krzysztof.kozlowski@canonical.com>
Message-ID: <YdWdbac/WQloqU57@robh.at.kernel.org>

On Mon, Dec 27, 2021 at 07:32:44PM +0100, Krzysztof Kozlowski wrote:
> Convert the APM X-Gene RNG bindings to DT schema.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/rng/apm,rng.txt       | 17 -------
>  .../bindings/rng/apm,x-gene-rng.yaml          | 47 +++++++++++++++++++
>  2 files changed, 47 insertions(+), 17 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/rng/apm,rng.txt
>  create mode 100644 Documentation/devicetree/bindings/rng/apm,x-gene-rng.yaml

Series applied, thanks.

Rob


From linux at armlinux.org.uk  Wed Jan  5 05:53:08 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 5 Jan 2022 13:53:08 +0000
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <4ae3e371-68d0-64d7-713e-88af45875b3f@nvidia.com>
References: <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
 <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
 <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
 <4ae3e371-68d0-64d7-713e-88af45875b3f@nvidia.com>
Message-ID: <YdWixPrYkR1JoFHW@shell.armlinux.org.uk>

On Wed, Jan 05, 2022 at 11:33:48AM +0000, Jon Hunter wrote:
> On 05/01/2022 11:12, Ard Biesheuvel wrote:
> > Thanks for the report.
> > 
> > It would be helpful if you could provide some more context:
> > - does it happen on a LPAE build too?
> > - does it only happen on SMP capable systems?
> 
> These are all SMP systems.
> 
> > - does it reproduce on such systems when using only a single CPU?
> > (i.e., pass 'nosmp' on the kernel command line)
> 
> I would need to try this.

Please note that I want an answer on the vmap stack patches by the
end of today (UK time - so about five hours after this email has
been sent) as we have only tonight and tomorrow's linux-next before
the probable opening of the merge window.

The options are:

1. The problem gets fixed today and I merge the fix today so it can
   get tested in linux-next over the next few days by the various
   build farms and test setups.
2. We postpone the merging of this until the very end of the merge
   window to give more time to sort out this mess - but what it
   means is keeping it in linux-next and keeping various platforms
   broken during that period. However, this is really not fair for
   other people, and some would say this isn't even an option.
3. We drop the entire series for this merge window, meaning it gets
   dropped from linux-next, and have another go for the neext merge
   window.

Sorry for being so demanding, but we're far too close to the merge
window to be trying to debug a feature that is clearly causing a
regression for several platforms.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From suzuki.poulose at arm.com  Wed Jan  5 05:54:30 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 5 Jan 2022 13:54:30 +0000
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <68961242-3d9b-a26d-3a0f-0d2ace04a17b@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
 <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>
 <68961242-3d9b-a26d-3a0f-0d2ace04a17b@arm.com>
Message-ID: <298ad877-56ea-58f8-02ed-a9edd7608c12@arm.com>

On 05/01/2022 11:16, Anshuman Khandual wrote:
> 
> 
> On 1/5/22 3:43 PM, Suzuki K Poulose wrote:
>> Hi Anshuman
>>
>> On 05/01/2022 05:05, Anshuman Khandual wrote:
>>> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
>>> an inconsistent view on whether trace is prohibited within the CPU. As a
>>> result, the trace buffer or trace buffer state might be corrupted. This
>>> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
>>> followed by just a single context synchronization event before execution
>>> changes from a context, in which trace is prohibited to one where it isn't,
>>> or vice versa. In these mentioned conditions, the view of whether trace is
>>> prohibited is inconsistent between parts of the CPU, and the trace buffer
>>> or the trace buffer state might be corrupted.
>>>
>>> Work around this problem in the TRBE driver by preventing an inconsistent
>>> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
>>> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
>>> instruction before an ERET, or two ISB instructions if no ERET is to take
>>> place. This adds a new cpu errata in arm64 errata framework and also
>>> updates TRBE driver as required.
>>>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Will Deacon <will at kernel.org>
>>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>>> Cc: coresight at lists.linaro.org
>>> Cc: linux-doc at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>> ---
>>>  ? Documentation/arm64/silicon-errata.rst?????? |? 2 +
>>>  ? arch/arm64/Kconfig?????????????????????????? | 23 ++++++++++
>>>  ? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 ++++
>>>  ? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>>>  ? drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>>>  ? 5 files changed, 72 insertions(+), 10 deletions(-)
>>
>> As with the previous patch, it may be a good idea to split the
>> patch to arm64 and trbe parts.
> 
> Sure, will do.
> 
>>
>>>
>>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>>> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
>>> --- a/Documentation/arm64/silicon-errata.rst
>>> +++ b/Documentation/arm64/silicon-errata.rst
>>> @@ -54,6 +54,8 @@ stable kernels.
>>>  ? +----------------+-----------------+-----------------+-----------------------------+
>>>  ? | ARM??????????? | Cortex-A510???? | #2064142??????? | ARM64_ERRATUM_2064142?????? |
>>>  ? +----------------+-----------------+-----------------+-----------------------------+
>>> +| ARM??????????? | Cortex-A510???? | #2038923??????? | ARM64_ERRATUM_2038923?????? |
>>> ++----------------+-----------------+-----------------+-----------------------------+
>>>  ? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>>>  ? +----------------+-----------------+-----------------+-----------------------------+
>>>  ? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>> index 2105b68d88db..026e34fb6fad 100644
>>> --- a/arch/arm64/Kconfig
>>> +++ b/arch/arm64/Kconfig
>>> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>>>  ? ??????? If unsure, say Y.
>>>  ? +config ARM64_ERRATUM_2038923
>>> +??? bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
>>> +??? depends on CORESIGHT_TRBE
>>> +??? default y
>>> +??? help
>>> +????? This option adds the workaround for ARM Cortex-A510 erratum 2038923.
>>> +
>>> +????? Affected Cortex-A510 core might cause an inconsistent view on whether trace is
>>> +????? prohibited within the CPU. As a result, the trace buffer or trace buffer state
>>> +????? might be corrupted. This happens after TRBE buffer has been enabled by setting
>>> +????? TRBLIMITR_EL1.E, followed by just a single context synchronization event before
>>> +????? execution changes from a context, in which trace is prohibited to one where it
>>> +????? isn't, or vice versa. In these mentioned conditions, the view of whether trace
>>> +????? is prohibited is inconsistent between parts of the CPU, and the trace buffer or
>>> +????? the trace buffer state might be corrupted.
>>> +
>>> +????? Work around this in the driver by preventing an inconsistent view of whether the
>>> +????? trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
>>> +????? change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
>>> +????? two ISB instructions if no ERET is to take place.
>>> +
>>> +????? If unsure, say Y.
>>> +
>>>  ? config CAVIUM_ERRATUM_22375
>>>  ????? bool "Cavium erratum 22375, 24313"
>>>  ????? default y
>>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>>> index cbb7d5a9aee7..60b0c1f1d912 100644
>>> --- a/arch/arm64/kernel/cpu_errata.c
>>> +++ b/arch/arm64/kernel/cpu_errata.c
>>> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>>  ????????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>>  ????? },
>>>  ? #endif
>>> +#ifdef CONFIG_ARM64_ERRATUM_2038923
>>> +??? {
>>> +??????? .desc = "ARM erratum 2038923",
>>> +??????? .capability = ARM64_WORKAROUND_2038923,
>>> +
>>> +??????? /* Cortex-A510 r0p0 - r0p2 */
>>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>> +??? },
>>> +#endif
>>>  ????? {
>>>  ????? }
>>>  ? };
>>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>>> index fca3cb329e1d..45a06d36d080 100644
>>> --- a/arch/arm64/tools/cpucaps
>>> +++ b/arch/arm64/tools/cpucaps
>>> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>>>  ? WORKAROUND_1508412
>>>  ? WORKAROUND_1542419
>>>  ? WORKAROUND_2064142
>>> +WORKAROUND_2038923
>>>  ? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>>>  ? WORKAROUND_TSB_FLUSH_FAILURE
>>>  ? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>>> index ec24b62b2cec..0689c6dab96d 100644
>>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>>> @@ -92,11 +92,13 @@ struct trbe_buf {
>>>  ? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>>>  ? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>>>  ? #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>>> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE??? 3
>>>  ? ? static int trbe_errata_cpucaps[] = {
>>>  ????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>>>  ????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>>>  ????? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>>> +??? [TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>>>  ????? -1,??????? /* Sentinel, must be the last entry */
>>>  ? };
>>>  ? @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>>>  ????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>>>  ? }
>>>  ? +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>>> +{
>>
>> minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?
> 
> trbe_needs_ctxt_sync_after_enable() sounds better. Also will have to change
> the index above as well .. TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE.
> 
>>
>>> +??? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>>> +}
>>> +
>>>  ? static int trbe_alloc_node(struct perf_event *event)
>>>  ? {
>>>  ????? if (event->cpu == -1)
>>> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>>>  ????? dsb(nsh);
>>>  ? }
>>>  ? +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
>>> +{
>>> +??? u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>>
>> minor nit: This implies we do the TRBE programming in the following
>> manner in the common case (i.e, TRBE enabled in the beginning of a
>> session).
>>  ? -> set TRBE LIMIT
>>  ? -> read TRBE LIMIT
>>  ? -> set TRBE ENABLED
>>
>> Could we please optimize this ? I believe the buf->trbe_limit
>> must hold the LIMITR value at any point in time. And thus this
> 
> But is not bit risky though ! We have got the following places where
> given trbe_limit instance changes its value.
> 
> drivers/../coresight-trbe.c:   buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE;
> drivers/../coresight-trbe.c:   buf->trbe_limit = compute_trbe_buffer_limit(handle);
> drivers/../coresight-trbe.c:   buf->trbe_limit -= PAGE_SIZE;

Those are the places where we compute the trbe_limit, *before*
we enable the TRBE. And we don't change recompute the limit
*without disabling* the TRBE. To make it more clear, the
only place where we set TRBE enabled without "computing"
the trbe_limit is when we hit a spurious interrupt.
But the value in the TRBLIMITR should already match the
buf->trbe_limit and we are only going to re-enable the
TRBE with the same limit. The other option is to
pass down the "limit" to the set_trbe_enabled().

> 
>> function could simply be :
>>
>> set_trbe_enabled(trbe_buf)
>> {
>>  ????limitr = trbe_buf->limit | LIMITR_ENABLE
>>  ????write(limitr, TRBLIMITR_EL1);
>>  ????...
>> }
> 
> Is the potential for performance improvement here, out weigh possible
> risks of using buf->trbe_limit directly while enabling the TRBE ?

I somehow don't like the fact that we have additional write and read
for the most common case of the TRBE usage (i.e, for arm_trbe_enable()).
If we could avoid that, that may be better.

Cheers
Suzuki


From robh at kernel.org  Wed Jan  5 06:20:55 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 5 Jan 2022 08:20:55 -0600
Subject: [PATCH 2/8] dt-bindings: nvmem: add transformation bindings
In-Reply-To: <084b306b7c49ce8085dd867663945d29@walle.cc>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-3-michael@walle.cc>
 <YdRh2lp5Ca08gHtR@robh.at.kernel.org>
 <084b306b7c49ce8085dd867663945d29@walle.cc>
Message-ID: <CAL_JsqLm9M2HJWbDnWxdMNiL2W40h2n=F1kj0XWizQUcmVk0+w@mail.gmail.com>

On Wed, Jan 5, 2022 at 2:25 AM Michael Walle <michael at walle.cc> wrote:
>
> Am 2022-01-04 16:03, schrieb Rob Herring:
> > On Tue, Dec 28, 2021 at 03:25:43PM +0100, Michael Walle wrote:
> >> Just add a simple list of the supported devices which need a nvmem
> >> transformations.
> >>
> >> Also, since the compatible string is prepended to the actual nvmem
> >> compatible string, we need to match using "contains" instead of an
> >> exact
> >> match.
> >>
> >> Signed-off-by: Michael Walle <michael at walle.cc>
> >> ---
> >>  .../devicetree/bindings/mtd/mtd.yaml          |  7 +--
> >>  .../bindings/nvmem/nvmem-transformations.yaml | 46
> >> +++++++++++++++++++
> >>  2 files changed, 50 insertions(+), 3 deletions(-)
> >>  create mode 100644
> >> Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> >>
> >> diff --git a/Documentation/devicetree/bindings/mtd/mtd.yaml
> >> b/Documentation/devicetree/bindings/mtd/mtd.yaml
> >> index 376b679cfc70..0291e439b6a6 100644
> >> --- a/Documentation/devicetree/bindings/mtd/mtd.yaml
> >> +++ b/Documentation/devicetree/bindings/mtd/mtd.yaml
> >> @@ -33,9 +33,10 @@ patternProperties:
> >>
> >>      properties:
> >>        compatible:
> >> -        enum:
> >> -          - user-otp
> >> -          - factory-otp
> >> +        contains:
> >> +          enum:
> >> +            - user-otp
> >> +            - factory-otp
> >
> > If the addition is only compatible strings, then I would just add them
> > here. Otherwise this needs to be structured a bit differently. More on
> > that below.
>
> I wanted to avoid having these compatible strings "cluttered" all around
> the various files. Esp. having a specific compatible string in a generic
> mtd.yaml. But if everyone is fine with that, I'll just move it here.
>
> >>
> >>      required:
> >>        - compatible
> >> diff --git
> >> a/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> >> b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> >> new file mode 100644
> >> index 000000000000..8c8d85fd6d27
> >> --- /dev/null
> >> +++
> >> b/Documentation/devicetree/bindings/nvmem/nvmem-transformations.yaml
> >> @@ -0,0 +1,46 @@
> >> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/nvmem/nvmem-transformations.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: NVMEM transformations Device Tree Bindings
> >> +
> >> +maintainers:
> >> +  - Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
> >> +
> >> +description: |
> >> +  This is a list NVMEM devices which need transformations.
> >> +
> >> +properties:
> >> +  compatible:
> >> +    oneOf:
> >> +      - items:
> >> +        - enum:
> >> +          - kontron,sl28-vpd
> >> +        - const: user-otp
> >> +      - const: user-otp
> >
> > This will be applied to any node containing 'user-otp'. You need a
> > custom 'select' to avoid that.
>
> Out of curiosity, you mean something like:
>
> select:
>    compatible:
>      contains:
>        enum:
>          - kontron,sl28-vpd

Yes, that's correct.

Rob


From lkp at intel.com  Wed Jan  5 06:16:23 2022
From: lkp at intel.com (kernel test robot)
Date: Wed, 5 Jan 2022 22:16:23 +0800
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220105093552.27542-1-pali@kernel.org>
References: <20220105093552.27542-1-pali@kernel.org>
Message-ID: <202201052225.XMsg2fG3-lkp@intel.com>

Hi "Pali,

I love your patch! Yet something to improve:

[auto build test ERROR on helgaas-pci/next]
[also build test ERROR on v5.16-rc8 next-20220105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Pali-Roh-r/PCI-iproc-Set-all-24-bits-of-PCI-class-code/20220105-173704
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: arm-randconfig-c002-20220105 (https://download.01.org/0day-ci/archive/20220105/202201052225.XMsg2fG3-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/8ef1acfb84c08a0331930f9a60884fdd6d7c5e88
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Pali-Roh-r/PCI-iproc-Set-all-24-bits-of-PCI-class-code/20220105-173704
        git checkout 8ef1acfb84c08a0331930f9a60884fdd6d7c5e88
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/pci/controller/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/pci/controller/pcie-iproc.c: In function 'iproc_pcie_check_link':
>> drivers/pci/controller/pcie-iproc.c:798:18: error: 'PCI_CLASS_BRIDGE_PCI_NORMAL' undeclared (first use in this function); did you mean 'PCI_CLASS_BRIDGE_PCMCIA'?
     798 |         class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
         |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |                  PCI_CLASS_BRIDGE_PCMCIA
   drivers/pci/controller/pcie-iproc.c:798:18: note: each undeclared identifier is reported only once for each function it appears in


vim +798 drivers/pci/controller/pcie-iproc.c

   765	
   766	static int iproc_pcie_check_link(struct iproc_pcie *pcie)
   767	{
   768		struct device *dev = pcie->dev;
   769		u32 hdr_type, link_ctrl, link_status, class, val;
   770		bool link_is_active = false;
   771	
   772		/*
   773		 * PAXC connects to emulated endpoint devices directly and does not
   774		 * have a Serdes.  Therefore skip the link detection logic here.
   775		 */
   776		if (pcie->ep_is_internal)
   777			return 0;
   778	
   779		val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
   780		if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
   781			dev_err(dev, "PHY or data link is INACTIVE!\n");
   782			return -ENODEV;
   783		}
   784	
   785		/* make sure we are not in EP mode */
   786		iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type);
   787		if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
   788			dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
   789			return -EFAULT;
   790		}
   791	
   792		/* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
   793	#define PCI_BRIDGE_CTRL_REG_OFFSET	0x43c
   794	#define PCI_BRIDGE_CTRL_REG_CLASS_MASK	0xffffff
   795		iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
   796					    4, &class);
   797		class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
 > 798		class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
   799		iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
   800					     4, class);
   801	
   802		/* check link status to see if link is active */
   803		iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
   804					    2, &link_status);
   805		if (link_status & PCI_EXP_LNKSTA_NLW)
   806			link_is_active = true;
   807	
   808		if (!link_is_active) {
   809			/* try GEN 1 link speed */
   810	#define PCI_TARGET_LINK_SPEED_MASK	0xf
   811	#define PCI_TARGET_LINK_SPEED_GEN2	0x2
   812	#define PCI_TARGET_LINK_SPEED_GEN1	0x1
   813			iproc_pci_raw_config_read32(pcie, 0,
   814						    IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
   815						    4, &link_ctrl);
   816			if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) ==
   817			    PCI_TARGET_LINK_SPEED_GEN2) {
   818				link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK;
   819				link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1;
   820				iproc_pci_raw_config_write32(pcie, 0,
   821						IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
   822						4, link_ctrl);
   823				msleep(100);
   824	
   825				iproc_pci_raw_config_read32(pcie, 0,
   826						IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
   827						2, &link_status);
   828				if (link_status & PCI_EXP_LNKSTA_NLW)
   829					link_is_active = true;
   830			}
   831		}
   832	
   833		dev_info(dev, "link: %s\n", link_is_active ? "UP" : "DOWN");
   834	
   835		return link_is_active ? 0 : -ENODEV;
   836	}
   837	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From ardb at kernel.org  Wed Jan  5 06:34:59 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed,  5 Jan 2022 15:34:59 +0100
Subject: [PATCH] ARM: disable vmap'ed stacks on suspend-capable SMP configs
Message-ID: <20220105143459.3365530-1-ardb@kernel.org>

There are several reports about the new vmap'ed stacks code breaking
suspend/resume on Exynos, Renesas and Tegra SMP platforms. While this is
under investigation, let's disable the vmap'ed stacks feature for the
time being for SMP configurations that have suspend/resume enabled.

[0] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-8-ardb at kernel.org/

Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Jon Hunter <jonathanh at nvidia.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4817343b1d97..938f7c392cc7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -129,7 +129,7 @@ config ARM
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select THREAD_INFO_IN_TASK
-	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000)
+	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000) && !PM_SLEEP_SMP
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
-- 
2.30.2



From lorenzo.pieralisi at arm.com  Wed Jan  5 06:50:06 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Wed, 5 Jan 2022 14:50:06 +0000
Subject: [PATCH v8 10/14] PCI: mediatek: Allow building for ARCH_AIROHA
In-Reply-To: <20211220211854.89452-11-nbd@nbd.name>
References: <20211220211854.89452-1-nbd@nbd.name>
 <20211220211854.89452-11-nbd@nbd.name>
Message-ID: <20220105145006.GA7465@lpieralisi>

On Mon, Dec 20, 2021 at 10:18:50PM +0100, Felix Fietkau wrote:
> Allow selecting the pcie-mediatek driver if ARCH_AIROHA is set, because the
> Airoha EN7523 SoC uses the same controller as MT7622.
> The driver itself is not modified. The PCIe controller DT node should use
> mediatek,mt7622-pcie after airoha,en7523-pcie.
> 
> Signed-off-by: Felix Fietkau <nbd at nbd.name>
> ---
>  drivers/pci/controller/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>

> diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
> index 93b141110537..f1342059c2a3 100644
> --- a/drivers/pci/controller/Kconfig
> +++ b/drivers/pci/controller/Kconfig
> @@ -233,7 +233,7 @@ config PCIE_ROCKCHIP_EP
>  
>  config PCIE_MEDIATEK
>  	tristate "MediaTek PCIe controller"
> -	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
>  	depends on OF
>  	depends on PCI_MSI_IRQ_DOMAIN
>  	help
> -- 
> 2.34.1
> 


From pali at kernel.org  Wed Jan  5 07:02:31 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:31 +0100
Subject: [PATCH 03/11] PCI: pci-bridge-emul: Add support for PCI Bridge
 Subsystem Vendor ID capability
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-4-pali@kernel.org>

This is read-only capability in PCI config space. Put it between base PCI
capability and base PCI Express capability.

Driver just have to specify subsystem_vendor_id and subsystem_id fields in
emulated bridge structure and pci-bridge-emul takes care of correctly
compose PCI Bridge Subsystem Vendor ID capability.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 69 +++++++++++++++++++++++++----------
 drivers/pci/pci-bridge-emul.h |  2 +
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 9f4f173f0650..c84f423a5893 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -21,8 +21,11 @@
 #include "pci-bridge-emul.h"
 
 #define PCI_BRIDGE_CONF_END	PCI_STD_HEADER_SIZEOF
+#define PCI_CAP_SSID_SIZEOF	(PCI_SSVID_DEVICE_ID + 2)
+#define PCI_CAP_SSID_START	PCI_BRIDGE_CONF_END
+#define PCI_CAP_SSID_END	(PCI_CAP_SSID_START + PCI_CAP_SSID_SIZEOF)
 #define PCI_CAP_PCIE_SIZEOF	(PCI_EXP_SLTSTA2 + 2)
-#define PCI_CAP_PCIE_START	PCI_BRIDGE_CONF_END
+#define PCI_CAP_PCIE_START	PCI_CAP_SSID_END
 #define PCI_CAP_PCIE_END	(PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF)
 
 /**
@@ -315,6 +318,25 @@ struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] =
 	},
 };
 
+static pci_bridge_emul_read_status_t
+pci_bridge_emul_read_ssid(struct pci_bridge_emul *bridge, int reg, u32 *value)
+{
+	switch (reg) {
+	case PCI_CAP_LIST_ID:
+		*value = PCI_CAP_ID_SSVID |
+			(bridge->has_pcie ? (PCI_CAP_PCIE_START << 8) : 0);
+		return PCI_BRIDGE_EMUL_HANDLED;
+
+	case PCI_SSVID_VENDOR_ID:
+		*value = bridge->subsystem_vendor_id |
+			(bridge->subsystem_id << 16);
+		return PCI_BRIDGE_EMUL_HANDLED;
+
+	default:
+		return PCI_BRIDGE_EMUL_NOT_HANDLED;
+	}
+}
+
 /*
  * Initialize a pci_bridge_emul structure to represent a fake PCI
  * bridge configuration space. The caller needs to have initialized
@@ -337,9 +359,17 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
 	if (!bridge->pci_regs_behavior)
 		return -ENOMEM;
 
-	if (bridge->has_pcie) {
+	if (bridge->subsystem_vendor_id)
+		bridge->conf.capabilities_pointer = PCI_CAP_SSID_START;
+	else if (bridge->has_pcie)
 		bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
+	else
+		bridge->conf.capabilities_pointer = 0;
+
+	if (bridge->conf.capabilities_pointer)
 		bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST);
+
+	if (bridge->has_pcie) {
 		bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
 		bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4);
 		bridge->pcie_cap_regs_behavior =
@@ -423,26 +453,28 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 		read_op = bridge->ops->read_base;
 		cfgspace = (__le32 *) &bridge->conf;
 		behavior = bridge->pci_regs_behavior;
-	} else if (!bridge->has_pcie) {
-		/* PCIe space is not implemented, and no PCI capabilities */
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	} else if (reg < PCI_CAP_PCIE_END) {
+	} else if (reg >= PCI_CAP_SSID_START && reg < PCI_CAP_SSID_END && bridge->subsystem_vendor_id) {
+		/* Emulated PCI Bridge Subsystem Vendor ID capability */
+		reg -= PCI_CAP_SSID_START;
+		read_op = pci_bridge_emul_read_ssid;
+		cfgspace = NULL;
+		behavior = NULL;
+	} else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) {
 		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else if (reg < PCI_CFG_SPACE_SIZE) {
-		/* Rest of PCI space not implemented */
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	} else {
+	} else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
 		/* PCIe extended capability space */
 		reg -= PCI_CFG_SPACE_SIZE;
 		read_op = bridge->ops->read_ext;
 		cfgspace = NULL;
 		behavior = NULL;
+	} else {
+		/* Not implemented */
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	if (read_op)
@@ -500,24 +532,21 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 		write_op = bridge->ops->write_base;
 		cfgspace = (__le32 *) &bridge->conf;
 		behavior = bridge->pci_regs_behavior;
-	} else if (!bridge->has_pcie) {
-		/* PCIe space is not implemented, and no PCI capabilities */
-		return PCIBIOS_SUCCESSFUL;
-	} else if (reg < PCI_CAP_PCIE_END) {
+	} else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) {
 		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		write_op = bridge->ops->write_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else if (reg < PCI_CFG_SPACE_SIZE) {
-		/* Rest of PCI space not implemented */
-		return PCIBIOS_SUCCESSFUL;
-	} else {
+	} else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
 		/* PCIe extended capability space */
 		reg -= PCI_CFG_SPACE_SIZE;
 		write_op = bridge->ops->write_ext;
 		cfgspace = NULL;
 		behavior = NULL;
+	} else {
+		/* Not implemented */
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	shift = (where & 0x3) * 8;
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 6b5f75b2ad02..71392b67471d 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -132,6 +132,8 @@ struct pci_bridge_emul {
 	struct pci_bridge_reg_behavior *pcie_cap_regs_behavior;
 	void *data;
 	bool has_pcie;
+	u16 subsystem_vendor_id;
+	u16 subsystem_id;
 };
 
 enum {
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:30 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:30 +0100
Subject: [PATCH 02/11] PCI: pci-bridge-emul: Add support for PCIe extended
 capabilities
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-3-pali@kernel.org>

From: Russell King <rmk+kernel at armlinux.org.uk>

Add support for PCIe extended capabilities, which we just redirect to the
emulating driver.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
[pali: Fix writing new value with W1C bits]
Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 77 +++++++++++++++++++++++------------
 drivers/pci/pci-bridge-emul.h | 15 +++++++
 2 files changed, 67 insertions(+), 25 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 56b2cb741498..9f4f173f0650 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -433,10 +433,16 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
-		/* Beyond our PCIe space */
+	} else if (reg < PCI_CFG_SPACE_SIZE) {
+		/* Rest of PCI space not implemented */
 		*value = 0;
 		return PCIBIOS_SUCCESSFUL;
+	} else {
+		/* PCIe extended capability space */
+		reg -= PCI_CFG_SPACE_SIZE;
+		read_op = bridge->ops->read_ext;
+		cfgspace = NULL;
+		behavior = NULL;
 	}
 
 	if (read_op)
@@ -444,15 +450,20 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 	else
 		ret = PCI_BRIDGE_EMUL_NOT_HANDLED;
 
-	if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED)
-		*value = le32_to_cpu(cfgspace[reg / 4]);
+	if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED) {
+		if (cfgspace)
+			*value = le32_to_cpu(cfgspace[reg / 4]);
+		else
+			*value = 0;
+	}
 
 	/*
 	 * Make sure we never return any reserved bit with a value
 	 * different from 0.
 	 */
-	*value &= behavior[reg / 4].ro | behavior[reg / 4].rw |
-		  behavior[reg / 4].w1c;
+	if (behavior)
+		*value &= behavior[reg / 4].ro | behavior[reg / 4].rw |
+			  behavior[reg / 4].w1c;
 
 	if (size == 1)
 		*value = (*value >> (8 * (where & 3))) & 0xff;
@@ -498,8 +509,15 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 		write_op = bridge->ops->write_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
+	} else if (reg < PCI_CFG_SPACE_SIZE) {
+		/* Rest of PCI space not implemented */
 		return PCIBIOS_SUCCESSFUL;
+	} else {
+		/* PCIe extended capability space */
+		reg -= PCI_CFG_SPACE_SIZE;
+		write_op = bridge->ops->write_ext;
+		cfgspace = NULL;
+		behavior = NULL;
 	}
 
 	shift = (where & 0x3) * 8;
@@ -513,29 +531,38 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	else
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	/* Keep all bits, except the RW bits */
-	new = old & (~mask | ~behavior[reg / 4].rw);
+	if (behavior) {
+		/* Keep all bits, except the RW bits */
+		new = old & (~mask | ~behavior[reg / 4].rw);
 
-	/* Update the value of the RW bits */
-	new |= (value << shift) & (behavior[reg / 4].rw & mask);
+		/* Update the value of the RW bits */
+		new |= (value << shift) & (behavior[reg / 4].rw & mask);
 
-	/* Clear the W1C bits */
-	new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+		/* Clear the W1C bits */
+		new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+	} else {
+		new = old & ~mask;
+		new |= (value << shift) & mask;
+	}
 
-	/* Save the new value with the cleared W1C bits into the cfgspace */
-	cfgspace[reg / 4] = cpu_to_le32(new);
+	if (cfgspace) {
+		/* Save the new value with the cleared W1C bits into the cfgspace */
+		cfgspace[reg / 4] = cpu_to_le32(new);
+	}
 
-	/*
-	 * Clear the W1C bits not specified by the write mask, so that the
-	 * write_op() does not clear them.
-	 */
-	new &= ~(behavior[reg / 4].w1c & ~mask);
+	if (behavior) {
+		/*
+		 * Clear the W1C bits not specified by the write mask, so that the
+		 * write_op() does not clear them.
+		 */
+		new &= ~(behavior[reg / 4].w1c & ~mask);
 
-	/*
-	 * Set the W1C bits specified by the write mask, so that write_op()
-	 * knows about that they are to be cleared.
-	 */
-	new |= (value << shift) & (behavior[reg / 4].w1c & mask);
+		/*
+		 * Set the W1C bits specified by the write mask, so that write_op()
+		 * knows about that they are to be cleared.
+		 */
+		new |= (value << shift) & (behavior[reg / 4].w1c & mask);
+	}
 
 	if (write_op)
 		write_op(bridge, reg, old, new, mask);
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 4953274cac18..6b5f75b2ad02 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -90,6 +90,14 @@ struct pci_bridge_emul_ops {
 	 */
 	pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge,
 						   int reg, u32 *value);
+
+	/*
+	 * Same as ->read_base(), except it is for reading from the
+	 * PCIe extended capability configuration space.
+	 */
+	pci_bridge_emul_read_status_t (*read_ext)(struct pci_bridge_emul *bridge,
+						  int reg, u32 *value);
+
 	/*
 	 * Called when writing to the regular PCI bridge configuration
 	 * space. old is the current value, new is the new value being
@@ -105,6 +113,13 @@ struct pci_bridge_emul_ops {
 	 */
 	void (*write_pcie)(struct pci_bridge_emul *bridge, int reg,
 			   u32 old, u32 new, u32 mask);
+
+	/*
+	 * Same as ->write_base(), except it is for writing from the
+	 * PCIe extended capability configuration space.
+	 */
+	void (*write_ext)(struct pci_bridge_emul *bridge, int reg,
+			  u32 old, u32 new, u32 mask);
 };
 
 struct pci_bridge_reg_behavior;
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:28 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:28 +0100
Subject: [PATCH 00/11] PCI: mvebu: subsystem ids, AER and INTx
Message-ID: <20220105150239.9628-1-pali@kernel.org>

This patch series extends pci-bridge-emul.c driver to emulate PCI Subsystem
Vendor ID capability and PCIe extended capabilities. And then implement
in pci-mvebu.c driver support for PCI Subsystem Vendor IDs, PCIe AER
registers, support for legacy INTx interrupts, configuration for X1/X4
mode and usage of new PCI child_ops API.

This patch series depends on other pci-mvebu and pci-bridge-emul patches from:
https://lore.kernel.org/linux-pci/20220104153529.31647-1-pali at kernel.org/

Pali Roh?r (9):
  PCI: pci-bridge-emul: Add support for PCI Bridge Subsystem Vendor ID
    capability
  dt-bindings: PCI: mvebu: Add num-lanes property
  PCI: mvebu: Correctly configure x1/x4 mode
  PCI: mvebu: Add support for PCI Bridge Subsystem Vendor ID on emulated
    bridge
  PCI: mvebu: Add support for Advanced Error Reporting registers on
    emulated bridge
  PCI: mvebu: Use child_ops API
  dt-bindings: PCI: mvebu: Update information about intx interrupts
  PCI: mvebu: Implement support for legacy INTx interrupts
  ARM: dts: armada-385.dtsi: Add definitions for PCIe legacy INTx
    interrupts

Russell King (2):
  PCI: pci-bridge-emul: Re-arrange register tests
  PCI: pci-bridge-emul: Add support for PCIe extended capabilities

 .../devicetree/bindings/pci/mvebu-pci.txt     |  16 +
 arch/arm/boot/dts/armada-385.dtsi             |  52 ++-
 drivers/pci/controller/pci-mvebu.c            | 352 +++++++++++++++---
 drivers/pci/pci-bridge-emul.c                 | 167 ++++++---
 drivers/pci/pci-bridge-emul.h                 |  17 +
 5 files changed, 494 insertions(+), 110 deletions(-)

-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:29 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:29 +0100
Subject: [PATCH 01/11] PCI: pci-bridge-emul: Re-arrange register tests
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-2-pali@kernel.org>

From: Russell King <rmk+kernel at armlinux.org.uk>

Re-arrange the tests for which sets of registers are being accessed so that
it is easier to add further regions later. No functional change.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
[pali: Fix reading old value in pci_bridge_emul_conf_write]
Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 61 ++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 30 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 033bbeb99176..56b2cb741498 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -418,25 +418,25 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 	__le32 *cfgspace;
 	const struct pci_bridge_reg_behavior *behavior;
 
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END) {
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	}
-
-	if (!bridge->has_pcie && reg >= PCI_BRIDGE_CONF_END) {
+	if (reg < PCI_BRIDGE_CONF_END) {
+		/* Emulated PCI space */
+		read_op = bridge->ops->read_base;
+		cfgspace = (__le32 *) &bridge->conf;
+		behavior = bridge->pci_regs_behavior;
+	} else if (!bridge->has_pcie) {
+		/* PCIe space is not implemented, and no PCI capabilities */
 		*value = 0;
 		return PCIBIOS_SUCCESSFUL;
-	}
-
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
+	} else if (reg < PCI_CAP_PCIE_END) {
+		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
 	} else {
-		read_op = bridge->ops->read_base;
-		cfgspace = (__le32 *) &bridge->conf;
-		behavior = bridge->pci_regs_behavior;
+		/* Beyond our PCIe space */
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	if (read_op)
@@ -480,11 +480,27 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	__le32 *cfgspace;
 	const struct pci_bridge_reg_behavior *behavior;
 
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END)
-		return PCIBIOS_SUCCESSFUL;
+	ret = pci_bridge_emul_conf_read(bridge, reg, 4, &old);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
 
-	if (!bridge->has_pcie && reg >= PCI_BRIDGE_CONF_END)
+	if (reg < PCI_BRIDGE_CONF_END) {
+		/* Emulated PCI space */
+		write_op = bridge->ops->write_base;
+		cfgspace = (__le32 *) &bridge->conf;
+		behavior = bridge->pci_regs_behavior;
+	} else if (!bridge->has_pcie) {
+		/* PCIe space is not implemented, and no PCI capabilities */
 		return PCIBIOS_SUCCESSFUL;
+	} else if (reg < PCI_CAP_PCIE_END) {
+		/* Our emulated PCIe capability */
+		reg -= PCI_CAP_PCIE_START;
+		write_op = bridge->ops->write_pcie;
+		cfgspace = (__le32 *) &bridge->pcie_conf;
+		behavior = bridge->pcie_cap_regs_behavior;
+	} else {
+		return PCIBIOS_SUCCESSFUL;
+	}
 
 	shift = (where & 0x3) * 8;
 
@@ -497,21 +513,6 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	else
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	ret = pci_bridge_emul_conf_read(bridge, reg, 4, &old);
-	if (ret != PCIBIOS_SUCCESSFUL)
-		return ret;
-
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
-		reg -= PCI_CAP_PCIE_START;
-		write_op = bridge->ops->write_pcie;
-		cfgspace = (__le32 *) &bridge->pcie_conf;
-		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
-		write_op = bridge->ops->write_base;
-		cfgspace = (__le32 *) &bridge->conf;
-		behavior = bridge->pci_regs_behavior;
-	}
-
 	/* Keep all bits, except the RW bits */
 	new = old & (~mask | ~behavior[reg / 4].rw);
 
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:33 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:33 +0100
Subject: [PATCH 05/11] PCI: mvebu: Correctly configure x1/x4 mode
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-6-pali@kernel.org>

If x1/x4 mode is not set correctly then link with endpoint card is not
established.

Use DTS property 'num-lanes' to deteriminate x1/x4 mode.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index a075ba26cff1..0f2ec0a17874 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -93,6 +93,7 @@ struct mvebu_pcie_port {
 	void __iomem *base;
 	u32 port;
 	u32 lane;
+	bool is_x4;
 	int devfn;
 	unsigned int mem_target;
 	unsigned int mem_attr;
@@ -233,13 +234,25 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, cmd, dev_rev, mask;
+	u32 ctrl, lnkcap, cmd, dev_rev, mask;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
 	ctrl |= PCIE_CTRL_RC_MODE;
 	mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
 
+	/*
+	 * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
+	 * Capability register. This register is defined by PCIe specification
+	 * as read-only but this mvebu controller has it as read-write and must
+	 * be set to number of SerDes PCIe lanes (1 or 4). If this register is
+	 * not set correctly then link with endpoint card is not established.
+	 */
+	lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
+	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
+	lnkcap |= (port->is_x4 ? 4 : 1) << 4;
+	mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
+
 	/* Disable Root Bridge I/O space, memory space and bus mastering. */
 	cmd = mvebu_readl(port, PCIE_CMD_OFF);
 	cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
@@ -986,6 +999,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 	struct device *dev = &pcie->pdev->dev;
 	enum of_gpio_flags flags;
 	int reset_gpio, ret;
+	u32 num_lanes;
 
 	port->pcie = pcie;
 
@@ -998,6 +1012,9 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 	if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane))
 		port->lane = 0;
 
+	if (!of_property_read_u32(child, "num-lanes", &num_lanes) && num_lanes == 4)
+		port->is_x4 = true;
+
 	port->name = devm_kasprintf(dev, GFP_KERNEL, "pcie%d.%d", port->port,
 				    port->lane);
 	if (!port->name) {
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:32 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:32 +0100
Subject: [PATCH 04/11] dt-bindings: PCI: mvebu: Add num-lanes property
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-5-pali@kernel.org>

Controller driver needs to correctly configure PCIe link if it contains 1
or 4 SerDes PCIe lanes. Therefore add a new 'num-lanes' DT property for
mvebu PCIe controller. Property 'num-lanes' seems to be de-facto standard
way how number of lanes is specified in other PCIe controllers.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 Documentation/devicetree/bindings/pci/mvebu-pci.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 6173af6885f8..24225852bce0 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -77,6 +77,7 @@ and the following optional properties:
 - marvell,pcie-lane: the physical PCIe lane number, for ports having
   multiple lanes. If this property is not found, we assume that the
   value is 0.
+- num-lanes: number of SerDes PCIe lanes for this link (1 or 4)
 - reset-gpios: optional GPIO to PERST#
 - reset-delay-us: delay in us to wait after reset de-assertion, if not
   specified will default to 100ms, as required by the PCIe specification.
@@ -141,6 +142,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 58>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		/* low-active PERST# reset on GPIO 25 */
 		reset-gpios = <&gpio0 25 1>;
 		/* wait 20ms for device settle after reset deassertion */
@@ -161,6 +163,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 59>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <1>;
+		num-lanes = <1>;
 		clocks = <&gateclk 6>;
 	};
 
@@ -177,6 +180,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 60>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <2>;
+		num-lanes = <1>;
 		clocks = <&gateclk 7>;
 	};
 
@@ -193,6 +197,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 61>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <3>;
+		num-lanes = <1>;
 		clocks = <&gateclk 8>;
 	};
 
@@ -209,6 +214,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 62>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 9>;
 	};
 
@@ -225,6 +231,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 63>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <1>;
+		num-lanes = <1>;
 		clocks = <&gateclk 10>;
 	};
 
@@ -241,6 +248,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 64>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <2>;
+		num-lanes = <1>;
 		clocks = <&gateclk 11>;
 	};
 
@@ -257,6 +265,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 65>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <3>;
+		num-lanes = <1>;
 		clocks = <&gateclk 12>;
 	};
 
@@ -273,6 +282,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 99>;
 		marvell,pcie-port = <2>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 26>;
 	};
 
@@ -289,6 +299,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 103>;
 		marvell,pcie-port = <3>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 27>;
 	};
 };
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:34 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:34 +0100
Subject: [PATCH 06/11] PCI: mvebu: Add support for PCI Bridge Subsystem Vendor
 ID on emulated bridge
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-7-pali@kernel.org>

Register with Subsystem Device/Vendor ID is at offset 0x2c. Export is via
emulated bridge.

After this change Subsystem ID is visible in lspci output at line:

  Capabilities: [40] Subsystem

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 0f2ec0a17874..811af9e6ede5 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -32,6 +32,7 @@
 #define PCIE_DEV_REV_OFF	0x0008
 #define PCIE_BAR_LO_OFF(n)	(0x0010 + ((n) << 3))
 #define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
+#define PCIE_SSDEV_ID_OFF	0x002c
 #define PCIE_CAP_PCIEXP		0x0060
 #define PCIE_HEADER_LOG_4_OFF	0x0128
 #define PCIE_BAR_CTRL_OFF(n)	(0x1804 + (((n) - 1) * 4))
@@ -731,6 +732,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	struct pci_bridge_emul *bridge = &port->bridge;
 	u32 dev_id = mvebu_readl(port, PCIE_DEV_ID_OFF);
 	u32 dev_rev = mvebu_readl(port, PCIE_DEV_REV_OFF);
+	u32 ssdev_id = mvebu_readl(port, PCIE_SSDEV_ID_OFF);
 	u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
 	u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
 
@@ -752,6 +754,8 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	 */
 	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
 
+	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
+	bridge->subsystem_id = ssdev_id >> 16;
 	bridge->has_pcie = true;
 	bridge->data = port;
 	bridge->ops = &mvebu_pci_bridge_emul_ops;
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:35 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:35 +0100
Subject: [PATCH 07/11] PCI: mvebu: Add support for Advanced Error Reporting
 registers on emulated bridge
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-8-pali@kernel.org>

AER registers start at mvebu offset 0x0100. Registers PCI_ERR_ROOT_COMMAND,
PCI_ERR_ROOT_STATUS and PCI_ERR_ROOT_ERR_SRC are not supported on pre-XP
hardware and returns zeros.

Note that AER interrupt is not supported yet as mvebu emulated bridge does
not implement interrupts support at all yet.

Also remove custom macro PCIE_HEADER_LOG_4_OFF as it is unused and
correctly this register should be referenced via standard macros with
offset, e.g. as: PCIE_CAP_PCIERR_OFF + PCI_ERR_HEADER_LOG + 4.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 67 +++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 811af9e6ede5..9ea2f6a7c2b0 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -34,7 +34,7 @@
 #define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
 #define PCIE_SSDEV_ID_OFF	0x002c
 #define PCIE_CAP_PCIEXP		0x0060
-#define PCIE_HEADER_LOG_4_OFF	0x0128
+#define PCIE_CAP_PCIERR_OFF	0x0100
 #define PCIE_BAR_CTRL_OFF(n)	(0x1804 + (((n) - 1) * 4))
 #define PCIE_WIN04_CTRL_OFF(n)	(0x1820 + ((n) << 4))
 #define PCIE_WIN04_BASE_OFF(n)	(0x1824 + ((n) << 4))
@@ -603,6 +603,37 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 	return PCI_BRIDGE_EMUL_HANDLED;
 }
 
+static pci_bridge_emul_read_status_t
+mvebu_pci_bridge_emul_ext_conf_read(struct pci_bridge_emul *bridge,
+				    int reg, u32 *value)
+{
+	struct mvebu_pcie_port *port = bridge->data;
+
+	switch (reg) {
+	case 0:
+	case PCI_ERR_UNCOR_STATUS:
+	case PCI_ERR_UNCOR_MASK:
+	case PCI_ERR_UNCOR_SEVER:
+	case PCI_ERR_COR_STATUS:
+	case PCI_ERR_COR_MASK:
+	case PCI_ERR_CAP:
+	case PCI_ERR_HEADER_LOG+0:
+	case PCI_ERR_HEADER_LOG+4:
+	case PCI_ERR_HEADER_LOG+8:
+	case PCI_ERR_HEADER_LOG+12:
+	case PCI_ERR_ROOT_COMMAND:
+	case PCI_ERR_ROOT_STATUS:
+	case PCI_ERR_ROOT_ERR_SRC:
+		*value = mvebu_readl(port, PCIE_CAP_PCIERR_OFF + reg);
+		break;
+
+	default:
+		return PCI_BRIDGE_EMUL_NOT_HANDLED;
+	}
+
+	return PCI_BRIDGE_EMUL_HANDLED;
+}
+
 static void
 mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 				      int reg, u32 old, u32 new, u32 mask)
@@ -715,11 +746,45 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 	}
 }
 
+static void
+mvebu_pci_bridge_emul_ext_conf_write(struct pci_bridge_emul *bridge,
+				     int reg, u32 old, u32 new, u32 mask)
+{
+	struct mvebu_pcie_port *port = bridge->data;
+
+	switch (reg) {
+	/* These are W1C registers, so clear other bits */
+	case PCI_ERR_UNCOR_STATUS:
+	case PCI_ERR_COR_STATUS:
+	case PCI_ERR_ROOT_STATUS:
+		new &= mask;
+		fallthrough;
+
+	case PCI_ERR_UNCOR_MASK:
+	case PCI_ERR_UNCOR_SEVER:
+	case PCI_ERR_COR_MASK:
+	case PCI_ERR_CAP:
+	case PCI_ERR_HEADER_LOG+0:
+	case PCI_ERR_HEADER_LOG+4:
+	case PCI_ERR_HEADER_LOG+8:
+	case PCI_ERR_HEADER_LOG+12:
+	case PCI_ERR_ROOT_COMMAND:
+	case PCI_ERR_ROOT_ERR_SRC:
+		mvebu_writel(port, new, PCIE_CAP_PCIERR_OFF + reg);
+		break;
+
+	default:
+		break;
+	}
+}
+
 static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
 	.read_base = mvebu_pci_bridge_emul_base_conf_read,
 	.write_base = mvebu_pci_bridge_emul_base_conf_write,
 	.read_pcie = mvebu_pci_bridge_emul_pcie_conf_read,
 	.write_pcie = mvebu_pci_bridge_emul_pcie_conf_write,
+	.read_ext = mvebu_pci_bridge_emul_ext_conf_read,
+	.write_ext = mvebu_pci_bridge_emul_ext_conf_write,
 };
 
 /*
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:36 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:36 +0100
Subject: [PATCH 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-9-pali@kernel.org>

Split struct pci_ops between ops and child_ops. Member ops is used for
accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
accessing real PCIe cards.

There is no need to mix these two struct pci_ops into one as PCI core code
already provides separate callbacks via bridge->ops and bridge->child_ops.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
 1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 9ea2f6a7c2b0..1e90ab888075 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	mvebu_writel(port, mask, PCIE_MASK_OFF);
 }
 
-static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
-				 struct pci_bus *bus,
-				 u32 devfn, int where, int size, u32 *val)
+static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
+						    struct pci_bus *bus,
+						    int devfn);
+
+static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+				    int size, u32 *val)
 {
-	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+	struct mvebu_pcie *pcie = bus->sysdata;
+	struct mvebu_pcie_port *port;
+	void __iomem *conf_data;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (!mvebu_pcie_link_up(port)) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	conf_data = port->base + PCIE_CONF_DATA_OFF;
 
 	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
 		     PCIE_CONF_ADDR_OFF);
@@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
-				 struct pci_bus *bus,
-				 u32 devfn, int where, int size, u32 val)
+static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
+				    int where, int size, u32 val)
 {
-	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+	struct mvebu_pcie *pcie = bus->sysdata;
+	struct mvebu_pcie_port *port;
+	void __iomem *conf_data;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (!mvebu_pcie_link_up(port))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	conf_data = port->base + PCIE_CONF_DATA_OFF;
 
 	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
 		     PCIE_CONF_ADDR_OFF);
@@ -347,6 +375,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
 	return PCIBIOS_SUCCESSFUL;
 }
 
+static struct pci_ops mvebu_pcie_child_ops = {
+	.read = mvebu_pcie_child_rd_conf,
+	.write = mvebu_pcie_child_wr_conf,
+};
+
 /*
  * Remove windows, starting from the largest ones to the smallest
  * ones.
@@ -862,25 +895,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 {
 	struct mvebu_pcie *pcie = bus->sysdata;
 	struct mvebu_pcie_port *port;
-	int ret;
 
 	port = mvebu_pcie_find_port(pcie, bus, devfn);
 	if (!port)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	/* Access the emulated PCI-to-PCI bridge */
-	if (bus->number == 0)
-		return pci_bridge_emul_conf_write(&port->bridge, where,
-						  size, val);
-
-	if (!mvebu_pcie_link_up(port))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	/* Access the real PCIe interface */
-	ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
-				    where, size, val);
-
-	return ret;
+	return pci_bridge_emul_conf_write(&port->bridge, where, size, val);
 }
 
 /* PCI configuration space read function */
@@ -889,7 +909,6 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 {
 	struct mvebu_pcie *pcie = bus->sysdata;
 	struct mvebu_pcie_port *port;
-	int ret;
 
 	port = mvebu_pcie_find_port(pcie, bus, devfn);
 	if (!port) {
@@ -897,21 +916,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
 
-	/* Access the emulated PCI-to-PCI bridge */
-	if (bus->number == 0)
-		return pci_bridge_emul_conf_read(&port->bridge, where,
-						 size, val);
-
-	if (!mvebu_pcie_link_up(port)) {
-		*val = 0xffffffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
-	/* Access the real PCIe interface */
-	ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
-				    where, size, val);
-
-	return ret;
+	return pci_bridge_emul_conf_read(&port->bridge, where, size, val);
 }
 
 static struct pci_ops mvebu_pcie_ops = {
@@ -1421,6 +1426,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &mvebu_pcie_ops;
+	bridge->child_ops = &mvebu_pcie_child_ops;
 	bridge->align_resource = mvebu_pcie_align_resource;
 	bridge->map_irq = mvebu_pcie_map_irq;
 
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:37 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:37 +0100
Subject: [PATCH 09/11] dt-bindings: PCI: mvebu: Update information about intx
 interrupts
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-10-pali@kernel.org>

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 Documentation/devicetree/bindings/pci/mvebu-pci.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 24225852bce0..6d022a9d36ee 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -81,6 +81,11 @@ and the following optional properties:
 - reset-gpios: optional GPIO to PERST#
 - reset-delay-us: delay in us to wait after reset de-assertion, if not
   specified will default to 100ms, as required by the PCIe specification.
+- interrupt-names: list of interrupt names, supported are:
+   - "intx" - interrupt line triggered by one of the legacy interrupt
+- interrupts or interrupts-extended: List of the interrupt sources which
+  corresponding to the "interrupt-names". If non-empty then also additional
+  'interrupt-controller' subnode must be defined.
 
 Example:
 
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:39 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:39 +0100
Subject: [PATCH 11/11] ARM: dts: armada-385.dtsi: Add definitions for PCIe
 legacy INTx interrupts
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-12-pali@kernel.org>

With this change legacy INTA, INTB, INTC and INTD interrupts are reported
separately and not mixed into one Linux virq source anymore.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 arch/arm/boot/dts/armada-385.dtsi | 52 ++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
index f0022d10c715..83392b92dae2 100644
--- a/arch/arm/boot/dts/armada-385.dtsi
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -69,16 +69,25 @@
 				reg = <0x0800 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
 					  0x81000000 0 0 0x81000000 0x1 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie1_intc 0>,
+						<0 0 0 2 &pcie1_intc 1>,
+						<0 0 0 3 &pcie1_intc 2>,
+						<0 0 0 4 &pcie1_intc 3>;
 				marvell,pcie-port = <0>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 8>;
 				status = "disabled";
+				pcie1_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/* x1 port */
@@ -88,16 +97,25 @@
 				reg = <0x1000 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
 					  0x81000000 0 0 0x81000000 0x2 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie2_intc 0>,
+						<0 0 0 2 &pcie2_intc 1>,
+						<0 0 0 3 &pcie2_intc 2>,
+						<0 0 0 4 &pcie2_intc 3>;
 				marvell,pcie-port = <1>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 5>;
 				status = "disabled";
+				pcie2_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/* x1 port */
@@ -107,16 +125,25 @@
 				reg = <0x1800 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
 					  0x81000000 0 0 0x81000000 0x3 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie3_intc 0>,
+						<0 0 0 2 &pcie3_intc 1>,
+						<0 0 0 3 &pcie3_intc 2>,
+						<0 0 0 4 &pcie3_intc 3>;
 				marvell,pcie-port = <2>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 6>;
 				status = "disabled";
+				pcie3_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/*
@@ -129,16 +156,25 @@
 				reg = <0x2000 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
 					  0x81000000 0 0 0x81000000 0x4 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie4_intc 0>,
+						<0 0 0 2 &pcie4_intc 1>,
+						<0 0 0 3 &pcie4_intc 2>,
+						<0 0 0 4 &pcie4_intc 3>;
 				marvell,pcie-port = <3>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 7>;
 				status = "disabled";
+				pcie4_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 		};
 	};
-- 
2.20.1



From pali at kernel.org  Wed Jan  5 07:02:38 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed,  5 Jan 2022 16:02:38 +0100
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx interrupts
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220105150239.9628-11-pali@kernel.org>

This adds support for legacy INTx interrupts received from other PCIe
devices and which are reported by a new INTx irq chip.

With this change, kernel can distinguish between INTA, INTB, INTC and INTD
interrupts.

Note that for this support, device tree files has to be properly adjusted
to provide "interrupts" or "interrupts-extended" property with intx
interrupt source, "interrupt-names" property with "intx" string and also
'interrupt-controller' subnode must be defined.

If device tree files do not provide these nodes then driver would work as
before.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
 1 file changed, 174 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 1e90ab888075..04bcdd7b7a6d 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -54,9 +54,10 @@
 	 PCIE_CONF_ADDR_EN)
 #define PCIE_CONF_DATA_OFF	0x18fc
 #define PCIE_INT_CAUSE_OFF	0x1900
+#define PCIE_INT_UNMASK_OFF	0x1910
+#define  PCIE_INT_INTX(i)		BIT(24+i)
 #define  PCIE_INT_PM_PME		BIT(28)
-#define PCIE_MASK_OFF		0x1910
-#define  PCIE_MASK_ENABLE_INTS          0x0f000000
+#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
 #define PCIE_CTRL_OFF		0x1a00
 #define  PCIE_CTRL_X1_MODE		0x0001
 #define  PCIE_CTRL_RC_MODE		BIT(1)
@@ -110,6 +111,10 @@ struct mvebu_pcie_port {
 	struct mvebu_pcie_window iowin;
 	u32 saved_pcie_stat;
 	struct resource regs;
+	struct irq_domain *intx_irq_domain;
+	struct irq_chip intx_irq_chip;
+	raw_spinlock_t irq_lock;
+	int intx_irq;
 };
 
 static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
@@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, lnkcap, cmd, dev_rev, mask;
+	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
@@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	/* Point PCIe unit MBUS decode windows to DRAM space. */
 	mvebu_pcie_setup_wins(port);
 
-	/* Enable interrupt lines A-D. */
-	mask = mvebu_readl(port, PCIE_MASK_OFF);
-	mask |= PCIE_MASK_ENABLE_INTS;
-	mvebu_writel(port, mask, PCIE_MASK_OFF);
+	/* Mask all interrupt sources. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+	/* Clear all interrupt causes. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+	if (port->intx_irq <= 0) {
+		/*
+		 * When neither "summary" interrupt, nor "intx" interrupt was
+		 * specified in DT then unmask all legacy INTx interrupts as in
+		 * this case driver does not provide a way for masking and
+		 * unmasking of individual legacy INTx interrupts. In this case
+		 * all interrupts, including legacy INTx are reported via one
+		 * shared GIC source and therefore kernel cannot distinguish
+		 * which individual legacy INTx was triggered. These interrupts
+		 * are shared, so it should not cause any issue. Just
+		 * performance penalty as every PCIe interrupt handler needs to
+		 * be called when some interrupt is triggered.
+		 */
+		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
+			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
+		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	}
 }
 
 static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
@@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
 	.write = mvebu_pcie_wr_conf,
 };
 
+static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask &= ~PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask |= PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
+				   unsigned int virq, irq_hw_number_t hwirq)
+{
+	struct mvebu_pcie_port *port = h->host_data;
+
+	irq_set_status_flags(virq, IRQ_LEVEL);
+	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
+	irq_set_chip_data(virq, port);
+
+	return 0;
+}
+
+static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
+	.map = mvebu_pcie_intx_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
+{
+	struct device *dev = &port->pcie->pdev->dev;
+	struct device_node *pcie_intc_node;
+
+	raw_spin_lock_init(&port->irq_lock);
+
+	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
+						  "mvebu-%s-INTx",
+						  port->name);
+	port->intx_irq_chip.irq_mask = mvebu_pcie_intx_irq_mask;
+	port->intx_irq_chip.irq_unmask = mvebu_pcie_intx_irq_unmask;
+
+	pcie_intc_node = of_get_next_child(port->dn, NULL);
+	if (!pcie_intc_node) {
+		dev_err(dev, "No PCIe Intc node found for %s\n", port->name);
+		return -ENODEV;
+	}
+
+	port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+						      &mvebu_pcie_intx_irq_domain_ops,
+						      port);
+	of_node_put(pcie_intc_node);
+	if (!port->intx_irq_domain) {
+		devm_kfree(dev, port->intx_irq_chip.name);
+		dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void mvebu_pcie_irq_handler(struct irq_desc *desc)
+{
+	struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct device *dev = &port->pcie->pdev->dev;
+	u32 cause, unmask, status;
+	int i;
+
+	chained_irq_enter(chip, desc);
+
+	cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	status = cause & unmask;
+
+	/* Process legacy INTx interrupts */
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		if (!(status & PCIE_INT_INTX(i)))
+			continue;
+
+		if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL)
+			dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A');
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
 static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	/* Interrupt support on mvebu emulated bridges is not implemented yet */
@@ -1121,6 +1249,16 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 		port->io_attr = -1;
 	}
 
+	/*
+	 * Old DT bindings do not contain "intx" interrupt
+	 * so do not fail probing driver when interrupt does not exist.
+	 */
+	port->intx_irq = of_irq_get_byname(child, "intx");
+	if (port->intx_irq == -EPROBE_DEFER) {
+		ret = port->intx_irq;
+		goto err;
+	}
+
 	reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags);
 	if (reset_gpio == -EPROBE_DEFER) {
 		ret = reset_gpio;
@@ -1317,6 +1455,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		child = port->dn;
 		if (!child)
@@ -1344,6 +1483,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (irq > 0) {
+			ret = mvebu_pcie_init_irq_domain(port);
+			if (ret) {
+				dev_err(dev, "%s: cannot init irq domain\n",
+					port->name);
+				pci_bridge_emul_cleanup(&port->bridge);
+				devm_iounmap(dev, port->base);
+				port->base = NULL;
+				mvebu_pcie_powerdown(port);
+				continue;
+			}
+			irq_set_chained_handler_and_data(irq,
+							 mvebu_pcie_irq_handler,
+							 port);
+		}
+
 		/*
 		 * PCIe topology exported by mvebu hw is quite complicated. In
 		 * reality has something like N fully independent host bridges
@@ -1448,6 +1603,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		if (!port->base)
 			continue;
@@ -1458,7 +1614,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 		mvebu_writel(port, cmd, PCIE_CMD_OFF);
 
 		/* Mask all interrupt sources. */
-		mvebu_writel(port, 0, PCIE_MASK_OFF);
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+		/* Clear all interrupt causes. */
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+		/* Remove IRQ domains. */
+		if (port->intx_irq_domain)
+			irq_domain_remove(port->intx_irq_domain);
+
+		if (irq > 0)
+			irq_set_chained_handler_and_data(irq, NULL, NULL);
 
 		/* Free config space for emulated root bridge. */
 		pci_bridge_emul_cleanup(&port->bridge);
-- 
2.20.1



From robh+dt at kernel.org  Wed Jan  5 07:41:51 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 5 Jan 2022 09:41:51 -0600
Subject: [PATCH 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220105150239.9628-9-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-9-pali@kernel.org>
Message-ID: <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>

On Wed, Jan 5, 2022 at 9:03 AM Pali Roh?r <pali at kernel.org> wrote:
>
> Split struct pci_ops between ops and child_ops. Member ops is used for
> accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> accessing real PCIe cards.
>
> There is no need to mix these two struct pci_ops into one as PCI core code
> already provides separate callbacks via bridge->ops and bridge->child_ops.

I had similar patches including mvebu that I never got around to
sending out. I pushed the branch out now at least[1].

> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
>  1 file changed, 44 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 9ea2f6a7c2b0..1e90ab888075 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>         mvebu_writel(port, mask, PCIE_MASK_OFF);
>  }
>
> -static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> -                                struct pci_bus *bus,
> -                                u32 devfn, int where, int size, u32 *val)
> +static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> +                                                   struct pci_bus *bus,
> +                                                   int devfn);
> +
> +static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> +                                   int size, u32 *val)
>  {
> -       void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> +       struct mvebu_pcie *pcie = bus->sysdata;
> +       struct mvebu_pcie_port *port;
> +       void __iomem *conf_data;
> +
> +       port = mvebu_pcie_find_port(pcie, bus, devfn);
> +       if (!port) {
> +               *val = 0xffffffff;
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +       }
> +
> +       if (!mvebu_pcie_link_up(port)) {
> +               *val = 0xffffffff;
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +       }
> +
> +       conf_data = port->base + PCIE_CONF_DATA_OFF;
>
>         mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
>                      PCIE_CONF_ADDR_OFF);
> @@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
>         return PCIBIOS_SUCCESSFUL;
>  }
>
> -static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
> -                                struct pci_bus *bus,
> -                                u32 devfn, int where, int size, u32 val)
> +static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
> +                                   int where, int size, u32 val)
>  {
> -       void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> +       struct mvebu_pcie *pcie = bus->sysdata;
> +       struct mvebu_pcie_port *port;
> +       void __iomem *conf_data;
> +
> +       port = mvebu_pcie_find_port(pcie, bus, devfn);
> +       if (!port)
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +       if (!mvebu_pcie_link_up(port))
> +               return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +       conf_data = port->base + PCIE_CONF_DATA_OFF;

The same code in read and write is a hint to use .map_bus().

>
>         mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
>                      PCIE_CONF_ADDR_OFF);
> @@ -347,6 +375,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
>         return PCIBIOS_SUCCESSFUL;
>  }
>
> +static struct pci_ops mvebu_pcie_child_ops = {
> +       .read = mvebu_pcie_child_rd_conf,
> +       .write = mvebu_pcie_child_wr_conf,
> +};
> +
>  /*
>   * Remove windows, starting from the largest ones to the smallest
>   * ones.
> @@ -862,25 +895,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  {
>         struct mvebu_pcie *pcie = bus->sysdata;
>         struct mvebu_pcie_port *port;
> -       int ret;
>
>         port = mvebu_pcie_find_port(pcie, bus, devfn);
>         if (!port)
>                 return PCIBIOS_DEVICE_NOT_FOUND;

It would be nice to go from 'bus' to 'bridge' ptr directly, but I
still had this in my version. I guess a standard RP struct as part of
decoupling host bridges from RPs would solve this issue.

Rob

[1] https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/log/?h=pci-child-bus-ops


From pali at kernel.org  Wed Jan  5 07:49:55 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Wed, 5 Jan 2022 16:49:55 +0100
Subject: [PATCH 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-9-pali@kernel.org>
 <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>
Message-ID: <20220105154955.lxhnhjgjsiwhuffq@pali>

On Wednesday 05 January 2022 09:41:51 Rob Herring wrote:
> > @@ -347,6 +375,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
> >         return PCIBIOS_SUCCESSFUL;
> >  }
> >
> > +static struct pci_ops mvebu_pcie_child_ops = {
> > +       .read = mvebu_pcie_child_rd_conf,
> > +       .write = mvebu_pcie_child_wr_conf,
> > +};
> > +
> >  /*
> >   * Remove windows, starting from the largest ones to the smallest
> >   * ones.
> > @@ -862,25 +895,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> >  {
> >         struct mvebu_pcie *pcie = bus->sysdata;
> >         struct mvebu_pcie_port *port;
> > -       int ret;
> >
> >         port = mvebu_pcie_find_port(pcie, bus, devfn);
> >         if (!port)
> >                 return PCIBIOS_DEVICE_NOT_FOUND;
> 
> It would be nice to go from 'bus' to 'bridge' ptr directly, but I
> still had this in my version. I guess a standard RP struct as part of
> decoupling host bridges from RPs would solve this issue.

Hello!

The problem is somewhere else. This driver is misusing bus 0 for doing
non-transparent bus-bridging between multiple PCI domains by registering
roots ports across all domains into domain 0, bus 0. All details are
in this my patch which documents this strange driver behavior:
https://lore.kernel.org/linux-pci/20211125124605.25915-12-pali at kernel.org/

So the correct solution is is split these multidomain mixing and then
every domain would have exactly one root port (as it is designed in HW).


From daniel.baluta at gmail.com  Wed Jan  5 07:53:51 2022
From: daniel.baluta at gmail.com (Daniel Baluta)
Date: Wed, 5 Jan 2022 17:53:51 +0200
Subject: [PATCH v3] dt-bindings: dsp: mediatek: add mt8195 dsp document
In-Reply-To: <20220103043202.6524-1-yc.hung@mediatek.com>
References: <20220103043202.6524-1-yc.hung@mediatek.com>
Message-ID: <CAEnQRZBH4uwMmyBLY2bCtY9QZooBiK5PqF3T+4K8WAtQV1QN-Q@mail.gmail.com>

On Mon, Jan 3, 2022 at 1:00 PM YC Hung <yc.hung at mediatek.com> wrote:
>
> From: "YC Hung" <yc.hung at mediatek.com>
>
> This patch adds mt8195 dsp document. The dsp is used for Sound Open
> Firmware driver node. It includes registers,  clocks, memory regions,
> and mailbox for dsp.
>
> Signed-off-by: yc.hung <yc.hung at mediatek.com>

The code patch should be created against original source code from
Rob's tree. Here it seems the patch is against v2.

This isn't going to work! Because when Rob will try to apply the patch
it will fail since he doesn't have (and doesnt need to have)
your previous versions.

So, please keep the changes history (that's a good thing!) but always
rebase your patch on maintainer's tree.


> ---
> Changes since v2:
>   Remove useless watchdog interrupt.
>   Add commit message more detail description.
>
> Changes since v1:
>   Rename yaml file name as mediatek,mt8195-dsp.yaml
>   Refine descriptions for mailbox, memory-region and drop unused labels
>   in examples.
> ---
> ---
>  .../devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml | 12 ------------
>  1 file changed, 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
> index bde763191d86..779daa786739 100644
> --- a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
> +++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
> @@ -27,14 +27,6 @@ properties:
>        - const: cfg
>        - const: sram
>
> -  interrupts:
> -    items:
> -      - description: watchdog interrupt
> -
> -  interrupt-names:
> -    items:
> -      - const: wdt
> -
>    clocks:
>      items:
>        - description: mux for audio dsp clock
> @@ -75,8 +67,6 @@ required:
>    - compatible
>    - reg
>    - reg-names
> -  - interrupts
> -  - interrupt-names
>    - clocks
>    - clock-names
>    - memory-region
> @@ -95,8 +85,6 @@ examples:
>         reg = <0x10803000  0x1000>,
>               <0x10840000  0x40000>;
>         reg-names = "cfg", "sram";
> -       interrupts = <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH 0>;
> -       interrupt-names = "wdt";
>         clocks = <&topckgen 10>, //CLK_TOP_ADSP
>                  <&clk26m>,
>                  <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS
> --
> 2.18.0
>


From robh+dt at kernel.org  Wed Jan  5 08:39:02 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 5 Jan 2022 10:39:02 -0600
Subject: [PATCH v3 01/15] dt-bindings: mmc: Convert Broadcom STB SDHCI
 binding to YAML
In-Reply-To: <20211208003727.3596577-2-f.fainelli@gmail.com>
References: <20211208003727.3596577-1-f.fainelli@gmail.com>
 <20211208003727.3596577-2-f.fainelli@gmail.com>
Message-ID: <CAL_Jsq+0E8CPeAegp0mV_qBTVcoLuywppRiOvCtHGp6_cOxH3Q@mail.gmail.com>

On Tue, Dec 7, 2021 at 6:37 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
>
> Convert the Broadcom STB SDHCI controller Device Tree binding to YAML.
>
> Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
> ---
>  .../bindings/mmc/brcm,sdhci-brcmstb.txt       |  53 ----------
>  .../bindings/mmc/brcm,sdhci-brcmstb.yaml      | 100 ++++++++++++++++++
>  2 files changed, 100 insertions(+), 53 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.txt
>  create mode 100644 Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml
>
> diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.txt b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.txt
> deleted file mode 100644
> index ae2074184528..000000000000
> --- a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.txt
> +++ /dev/null
> @@ -1,53 +0,0 @@
> -* BROADCOM BRCMSTB/BMIPS SDHCI Controller
> -
> -This file documents differences between the core properties in mmc.txt
> -and the properties used by the sdhci-brcmstb driver.
> -
> -NOTE: The driver disables all UHS speed modes by default and depends
> -on Device Tree properties to enable them for SoC/Board combinations
> -that support them.
> -
> -Required properties:
> -- compatible: should be one of the following
> -  - "brcm,bcm7425-sdhci"
> -  - "brcm,bcm7445-sdhci"
> -  - "brcm,bcm7216-sdhci"
> -
> -Refer to clocks/clock-bindings.txt for generic clock consumer properties.
> -
> -Example:
> -
> -       sdhci at 84b0000 {
> -               sd-uhs-sdr50;
> -               sd-uhs-ddr50;
> -               sd-uhs-sdr104;
> -               sdhci,auto-cmd12;
> -               compatible = "brcm,bcm7216-sdhci",
> -                          "brcm,bcm7445-sdhci",
> -                          "brcm,sdhci-brcmstb";
> -               reg = <0x84b0000 0x260 0x84b0300 0x200>;
> -               reg-names = "host", "cfg";
> -               interrupts = <0x0 0x26 0x4>;
> -               interrupt-names = "sdio0_0";
> -               clocks = <&scmi_clk 245>;
> -               clock-names = "sw_sdio";
> -       };
> -
> -       sdhci at 84b1000 {
> -               mmc-ddr-1_8v;
> -               mmc-hs200-1_8v;
> -               mmc-hs400-1_8v;
> -               mmc-hs400-enhanced-strobe;
> -               supports-cqe;
> -               non-removable;
> -               bus-width = <0x8>;
> -               compatible = "brcm,bcm7216-sdhci",
> -                          "brcm,bcm7445-sdhci",
> -                          "brcm,sdhci-brcmstb";
> -               reg = <0x84b1000 0x260 0x84b1300 0x200>;
> -               reg-names = "host", "cfg";
> -               interrupts = <0x0 0x27 0x4>;
> -               interrupt-names = "sdio1_0";
> -               clocks = <&scmi_clk 245>;
> -               clock-names = "sw_sdio";
> -       };
> diff --git a/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml
> new file mode 100644
> index 000000000000..dccd5ad96981
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/brcm,sdhci-brcmstb.yaml
> @@ -0,0 +1,100 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mmc/brcm,sdhci-brcmstb.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BRCMSTB/BMIPS SDHCI Controller binding
> +
> +maintainers:
> +  - Al Cooper <alcooperx at gmail.com>
> +  - Florian Fainelli <f.fainelli at gmail.com>
> +
> +allOf:
> +  - $ref: mmc-controller.yaml#
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - brcm,bcm7216-sdhci
> +          - const: brcm,bcm7445-sdhci
> +          - const: brcm,sdhci-brcmstb
> +      - items:
> +          - enum:
> +              - brcm,bcm7445-sdhci
> +          - const: brcm,sdhci-brcmstb
> +      - items:
> +          - enum:
> +              - brcm,bcm7425-sdhci
> +          - const: brcm,sdhci-brcmstb
> +
> +  reg:
> +    minItems: 2
> +
> +  reg-names:
> +    items:
> +      - const: host
> +      - const: cfg
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description:
> +      handle to core clock for the sdhci controller.
> +
> +  clock-names:
> +    items:
> +      - const: sw_sdio
> +
> +  sdhci,auto-cmd12:
> +    type: boolean
> +    description: Specifies that controller should use auto CMD12
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    mmc at 84b0000 {
> +      sd-uhs-sdr50;
> +      sd-uhs-ddr50;
> +      sd-uhs-sdr104;
> +      sdhci,auto-cmd12;
> +      compatible = "brcm,bcm7216-sdhci",
> +                   "brcm,bcm7445-sdhci",
> +                   "brcm,sdhci-brcmstb";
> +      reg = <0x84b0000 0x260>, <0x84b0300 0x200>;
> +      reg-names = "host", "cfg";
> +      interrupts = <0x0 0x26 0x4>;
> +      interrupt-names = "sdio0_0";

Not documented.

Rob


From jonathanh at nvidia.com  Wed Jan  5 08:49:47 2022
From: jonathanh at nvidia.com (Jon Hunter)
Date: Wed, 5 Jan 2022 16:49:47 +0000
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
References: <20211122092816.2865873-1-ardb@kernel.org>
 <CGME20211221103854eucas1p2592e38fcc84c1c3506fce87f1dab6739@eucas1p2.samsung.com>
 <20211122092816.2865873-8-ardb@kernel.org>
 <0ffc858f-27e7-6789-4be1-c4c5ad61eb9d@samsung.com>
 <CAMj1kXG+P5AU-26t_16FL5xfQNd+ByQH_cfBLiwMSdoGPmvCuw@mail.gmail.com>
 <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
 <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
 <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
Message-ID: <c0d71f87-1329-205c-c4fb-d82d0f118a7b@nvidia.com>


On 05/01/2022 11:12, Ard Biesheuvel wrote:

...

> Thanks for the report.
> 
> It would be helpful if you could provide some more context:
> - does it happen on a LPAE build too?

Enabling CONFIG_ARM_LPAE does work.

> - does it only happen on SMP capable systems?
> - does it reproduce on such systems when using only a single CPU?
> (i.e., pass 'nosmp' on the kernel command line)

Adding 'nosmp' does not help.

> - when passing 'no_console_suspend' on the kernel command line, are
> any useful diagnostics produced?

Adding 'no_console_suspend' does not produce any interesting logs.

> - is there any way you could tell whether the crash/hang (assuming
> that is what you are observing) occurs on the suspend path or on
> resume?

That is not clear. I see it entering suspend, but not clear if it is 
failing on entering suspend or resuming.

Cheers
Jon

-- 
nvpublic


From broonie at kernel.org  Wed Jan  5 08:57:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 5 Jan 2022 16:57:02 +0000
Subject: [PATCH v12 05/10] arm64: Copy unwind arguments to unwind_state
In-Reply-To: <20220103165212.9303-6-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-6-madvenka@linux.microsoft.com>
Message-ID: <YdXN3h2YASnjaIUu@sirena.org.uk>

On Mon, Jan 03, 2022 at 10:52:07AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Copy the following arguments passed to arch_stack_walk() to unwind_state
> so that they can be passed to unwind functions via unwind_state rather
> than as separate arguments:

Reviwed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220105/ce01d741/attachment.sig>

From roman.bacik at broadcom.com  Wed Jan  5 08:57:09 2022
From: roman.bacik at broadcom.com (Roman Bacik)
Date: Wed, 5 Jan 2022 08:57:09 -0800
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220105093552.27542-1-pali@kernel.org>
References: <20220105093552.27542-1-pali@kernel.org>
Message-ID: <CAGQAs7xHpfftf4=_zyhdJhRHaN-P3BaY+n1NQ-ED8cFRJ1+EAA@mail.gmail.com>

On Wed, Jan 5, 2022 at 1:36 AM Pali Roh?r <pali at kernel.org> wrote:
>
> Register 0x43c in its low 24 bits contains PCI class code.
>
> Update code to set all 24 bits of PCI class code and not only upper 16 bits
> of PCI class code.
>
> Use a new macro PCI_CLASS_BRIDGE_PCI_NORMAL which represents whole 24 bits
> of normal PCI bridge class.
>
> Signed-off-by: Pali Roh?r <pali at kernel.org>
>
> ---
> Roman helped me with this change and confirmed that class code is stored
> really in bits [23:0] of custom register 0x43c (normally class code is
> stored in bits [31:8] of pci register 0x08).
>
> This patch depends on patch which adds PCI_CLASS_BRIDGE_PCI_NORMAL macro:
> https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
> ---
>  drivers/pci/controller/pcie-iproc.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
> index 3df4ab209253..2519201b0e51 100644
> --- a/drivers/pci/controller/pcie-iproc.c
> +++ b/drivers/pci/controller/pcie-iproc.c
> @@ -789,14 +789,13 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
>                 return -EFAULT;
>         }
>
> -       /* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
> +       /* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
>  #define PCI_BRIDGE_CTRL_REG_OFFSET     0x43c
> -#define PCI_CLASS_BRIDGE_MASK          0xffff00
> -#define PCI_CLASS_BRIDGE_SHIFT         8
> +#define PCI_BRIDGE_CTRL_REG_CLASS_MASK 0xffffff
>         iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
>                                     4, &class);
> -       class &= ~PCI_CLASS_BRIDGE_MASK;
> -       class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
> +       class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
> +       class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
>         iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
>                                      4, class);
>
> --
> 2.20.1
>

Acked-by: Roman Bacik <roman.bacik at broadcom.com>

-- 
This electronic communication and the information and any files transmitted 
with it, or attached to it, are confidential and are intended solely for 
the use of the individual or entity to whom it is addressed and may contain 
information that is confidential, legally privileged, protected by privacy 
laws, or otherwise restricted from disclosure to anyone else. If you are 
not the intended recipient or the person responsible for delivering the 
e-mail to the intended recipient, you are hereby notified that any use, 
copying, distributing, dissemination, forwarding, printing, or copying of 
this e-mail is strictly prohibited. If you received this e-mail in error, 
please return the e-mail to the sender, delete it from your computer, and 
destroy any printed copy of it.


From broonie at kernel.org  Wed Jan  5 08:58:41 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 5 Jan 2022 16:58:41 +0000
Subject: [PATCH v12 07/10] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <20220103165212.9303-8-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-8-madvenka@linux.microsoft.com>
Message-ID: <YdXOQTXscVaVFMJ3@sirena.org.uk>

On Mon, Jan 03, 2022 at 10:52:09AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> There are some kernel features and conditions that make a stack trace
> unreliable. Callers may require the unwinder to detect these cases.
> E.g., livepatch.

Reviwed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220105/33de431e/attachment-0001.sig>

From andrew.kilroy at arm.com  Wed Jan  5 08:58:42 2022
From: andrew.kilroy at arm.com (Andrew Kilroy)
Date: Wed, 5 Jan 2022 16:58:42 +0000
Subject: [RFC PATCH 1/1] perf arm64: Implement --topdown with metrics
In-Reply-To: <48437bee-9c39-38ba-e990-ba9a6a5378b4@huawei.com>
References: <4c375d34-bf20-496d-22fc-aed8597126e2@huawei.com>
 <20211214184240.24215-1-andrew.kilroy@arm.com>
 <20211214184240.24215-2-andrew.kilroy@arm.com>
 <48437bee-9c39-38ba-e990-ba9a6a5378b4@huawei.com>
Message-ID: <6ba550d1-61bc-e229-2a64-331cfa59c388@arm.com>



On 17/12/2021 10:19, John Garry wrote:
> 
> And there is no colouring for results which are above/below standard 
> thresholds (see stat-shadow.c:get_radio_color()).
> 
> My impression is that we're not plugging the results from 
> metricgroup__parse_groups_to_evlist() into the --topdown print 
> functionality properly.
> 

The --topdown kernel event colouring is dictated by a large if-else 
statement in stat-shadow.c:perf_stat__print_shadow_stats.

There are branches depending on what is returned by 
perf_stat_evsel__is() for example

	} else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
		double fe_bound = td_fe_bound(cpu, st, &rsd);

		if (fe_bound > 0.2)
			color = PERF_COLOR_RED;
		print_metric(config, ctxp, color, "%8.1f%%", "frontend bound",
				fe_bound * 100.);
	} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) {



Because the patches are enabling metrics (equivalent of the -M 
'somemetricname' option), the perf_stat__print_shadow_stats function 
always makes calls to generic_metric(), where colours are never picked.

Seeing thresholds like:

   retiring > 0.7
   fe_bound > 0.2
   be_bound > 0.2
   bad_spec > 0.1


I'm not sure about adding the colouring really.  Are these thresholds 
x86 specific?


> Thanks,
> John


Andrew


From ardb at kernel.org  Wed Jan  5 09:02:23 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 5 Jan 2022 18:02:23 +0100
Subject: [PATCH v4 7/7] ARM: implement support for vmap'ed stacks
In-Reply-To: <c0d71f87-1329-205c-c4fb-d82d0f118a7b@nvidia.com>
References: <20211122092816.2865873-1-ardb@kernel.org>
 <CGME20211221103854eucas1p2592e38fcc84c1c3506fce87f1dab6739@eucas1p2.samsung.com>
 <20211122092816.2865873-8-ardb@kernel.org>
 <0ffc858f-27e7-6789-4be1-c4c5ad61eb9d@samsung.com>
 <CAMj1kXG+P5AU-26t_16FL5xfQNd+ByQH_cfBLiwMSdoGPmvCuw@mail.gmail.com>
 <e07a229a-e565-0077-9f8a-a24ffa45f395@samsung.com>
 <CAMj1kXG3neg0riLAaU32KLvB2PLBNzwqgO0F21nbK1ivS=FwMg@mail.gmail.com>
 <b22077f6-0925-ee00-41ea-3e52241926e2@samsung.com>
 <CAMj1kXHQrqZSE1kHaQyQyK6R58EV3cUyvJFmM1JYifaMemyUhQ@mail.gmail.com>
 <f469726d-86fb-cf54-2775-d4658d2f3a5d@samsung.com>
 <CAMj1kXGyL7yTV4+pOs9iBWYuVvVmPTZrV5r=nzqttqpZ6-vYJA@mail.gmail.com>
 <CAMuHMdWNuCVeFiDrhnFmX0F1jxz8Fs4eFx55ojJF3d2ro-udrA@mail.gmail.com>
 <bbb0c788-bd83-833c-9445-87cff525f728@nvidia.com>
 <CAMj1kXEYjUspxOnvK=3O4pkVtXT+iBPz6mkskn=K6TTUZc+W2g@mail.gmail.com>
 <c0d71f87-1329-205c-c4fb-d82d0f118a7b@nvidia.com>
Message-ID: <CAMj1kXG5+jH9kLLeeArPpDQr8fhKOYYutRqJ4Qusb5+brs+tzg@mail.gmail.com>

On Wed, 5 Jan 2022 at 17:50, Jon Hunter <jonathanh at nvidia.com> wrote:
>
>
> On 05/01/2022 11:12, Ard Biesheuvel wrote:
>
> ...
>
> > Thanks for the report.
> >
> > It would be helpful if you could provide some more context:
> > - does it happen on a LPAE build too?
>
> Enabling CONFIG_ARM_LPAE does work.
>
> > - does it only happen on SMP capable systems?
> > - does it reproduce on such systems when using only a single CPU?
> > (i.e., pass 'nosmp' on the kernel command line)
>
> Adding 'nosmp' does not help.
>
> > - when passing 'no_console_suspend' on the kernel command line, are
> > any useful diagnostics produced?
>
> Adding 'no_console_suspend' does not produce any interesting logs.
>
> > - is there any way you could tell whether the crash/hang (assuming
> > that is what you are observing) occurs on the suspend path or on
> > resume?
>
> That is not clear. I see it entering suspend, but not clear if it is
> failing on entering suspend or resuming.
>

Thanks a lot for providing this info.

The fact that enabling LPAE makes the issue go away is a fairly strong
hint that one of the CPUs comes up running in an address space that
lacks the stack's vmapping in its copy of the swapper_pg_dir region -
LPAE builds map swapper_pg_dir directly so there it can never go out
of sync.

Given that vmappings are global, and therefore cached in the TLB
across context switches, it is not unlikely that the missing vmapping
of the stack is in a task that runs before suspend, but does not cause
any issues until after the CPU is reset completely (which takes cached
TLB entries down with it)

So in summary, this gives me something to chew on, and hopefully, I
will be able to provide a proper fix shortly.


From p.zabel at pengutronix.de  Wed Jan  5 09:25:15 2022
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed,  5 Jan 2022 18:25:15 +0100
Subject: [GIT PULL] Reset controller fixes for v5.16, part 2
Message-ID: <20220105172515.273947-1-p.zabel@pengutronix.de>

Dear arm-soc maintainers,

The following changes since commit 69125b4b9440be015783312e1b8753ec96febde0:

  reset: tegra-bpmp: Revert Handle errors in BPMP response (2021-11-17 17:22:27 +0100)

are available in the Git repository at:

  git://git.pengutronix.de/pza/linux.git tags/reset-fixes-for-v5.16-2

for you to fetch changes up to 92c959bae2e54ba1e2540ba5f813f7752bd76be1:

  reset: renesas: Fix Runtime PM usage (2021-12-15 11:20:30 +0100)

----------------------------------------------------------------
Reset controller fixes for v5.16, part 2

Fix pm_runtime_resume_and_get() error handling in the
reset-rzg2l-usbphy-ctrl driver.

----------------------------------------------------------------
Heiner Kallweit (1):
      reset: renesas: Fix Runtime PM usage

 drivers/reset/reset-rzg2l-usbphy-ctrl.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)


From p.zabel at pengutronix.de  Wed Jan  5 09:26:18 2022
From: p.zabel at pengutronix.de (Philipp Zabel)
Date: Wed,  5 Jan 2022 18:26:18 +0100
Subject: [GIT PULL] Reset controller updates vor v5.17
Message-ID: <20220105172618.302522-1-p.zabel@pengutronix.de>

Dear arm-soc maintainers,

The following changes since commit fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf:

  Linux 5.16-rc1 (2021-11-14 13:56:52 -0800)

are available in the Git repository at:

  git://git.pengutronix.de/pza/linux.git tags/reset-for-v5.17

for you to fetch changes up to 89e7a6698fdd6d0cccf5bab11abc51f813944cd8:

  reset: uniphier-glue: Use devm_add_action_or_reset() (2021-12-16 09:59:55 +0100)

----------------------------------------------------------------
Reset controller updates vor v5.17

Add an optional variant of of_reset_control_get_exclusive(), document
a deprecated hi3660-reset device tree property, check whether reset
deassertion worked in the reset-rzg2l-usbphy-ctrl driver, and simplify
the uniphier-glue driver a bit.

----------------------------------------------------------------
Biju Das (1):
      reset: Add of_reset_control_get_optional_exclusive()

David Heidelberg (1):
      dt-bindings: reset: document deprecated HiSilicon property

Heiner Kallweit (1):
      reset: renesas: Check return value of reset_control_deassert()

Philipp Zabel (2):
      reset: uniphier-glue: Use reset_control_bulk API
      reset: uniphier-glue: Use devm_add_action_or_reset()

 .../bindings/reset/hisilicon,hi3660-reset.yaml     |  5 ++
 drivers/reset/reset-rzg2l-usbphy-ctrl.c            |  4 +-
 drivers/reset/reset-uniphier-glue.c                | 75 ++++++++++------------
 include/linux/reset.h                              | 20 ++++++
 4 files changed, 62 insertions(+), 42 deletions(-)


From andre.przywara at arm.com  Wed Jan  5 09:29:52 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed,  5 Jan 2022 17:29:52 +0000
Subject: [PATCH] pinctrl: sunxi: Fix H616 I2S3 pin data
Message-ID: <20220105172952.23347-1-andre.przywara@arm.com>

Two bugs have sneaked in the H616 pinctrl data:
- PH9 uses the mux value of 0x3 twice (one should be 0x5 instead)
- PH8 and PH9 use the "i2s3" function name twice in each pin

For the double pin name we use the same trick we pulled for i2s0: append
the pin function to the group name to designate the special function.

Fixes: 25adc29407fb ("pinctrl: sunxi: Add support for the Allwinner H616 pin controller")
Reported-by: SASANO Takayoshi <uaa at mx5.nisiq.net>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
index ce1917e230f4..152b71226a80 100644
--- a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
@@ -363,16 +363,16 @@ static const struct sunxi_desc_pin h616_pins[] = {
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
 		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
-		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DO0 */
+		  SUNXI_FUNCTION(0x3, "i2s3_dout0"),	/* DO0 */
 		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO */
-		  SUNXI_FUNCTION(0x5, "i2s3"),	/* DI1 */
+		  SUNXI_FUNCTION(0x5, "i2s3_din1"),	/* DI1 */
 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 8)),	/* PH_EINT8 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DI0 */
+		  SUNXI_FUNCTION(0x3, "i2s3_din0"),	/* DI0 */
 		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS1 */
-		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DO1 */
+		  SUNXI_FUNCTION(0x5, "i2s3_dout1"),	/* DO1 */
 		  SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 9)),	/* PH_EINT9 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
-- 
2.17.6



From will at kernel.org  Wed Jan  5 09:31:38 2022
From: will at kernel.org (Will Deacon)
Date: Wed,  5 Jan 2022 17:31:38 +0000
Subject: [PATCH] drivers: perf: marvell_cn10k: fix an IS_ERR() vs NULL
 check
In-Reply-To: <20211217145907.GA16611@kili>
References: <20211217145907.GA16611@kili>
Message-ID: <164130469774.128143.15567596913293745739.b4-ty@kernel.org>

On Fri, 17 Dec 2021 17:59:08 +0300, Dan Carpenter wrote:
> The devm_ioremap() function does not return error pointers.  It returns
> NULL.
> 
> 

Applied to will (for-next/perf), thanks!

[1/1] drivers: perf: marvell_cn10k: fix an IS_ERR() vs NULL check
      https://git.kernel.org/will/c/2da56881a7f8

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev


From ray.jui at broadcom.com  Wed Jan  5 09:51:48 2022
From: ray.jui at broadcom.com (Ray Jui)
Date: Wed, 5 Jan 2022 09:51:48 -0800
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220105093552.27542-1-pali@kernel.org>
References: <20220105093552.27542-1-pali@kernel.org>
Message-ID: <244e74d9-1b46-2abc-6c2a-c089fa5b68b4@broadcom.com>

Hi Pali,

On 1/5/2022 1:35 AM, Pali Roh?r wrote:
> Register 0x43c in its low 24 bits contains PCI class code.
> 
> Update code to set all 24 bits of PCI class code and not only upper 16 bits
> of PCI class code.
> 
> Use a new macro PCI_CLASS_BRIDGE_PCI_NORMAL which represents whole 24 bits
> of normal PCI bridge class.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> 
> ---
> Roman helped me with this change and confirmed that class code is stored
> really in bits [23:0] of custom register 0x43c (normally class code is
> stored in bits [31:8] of pci register 0x08).
> 
> This patch depends on patch which adds PCI_CLASS_BRIDGE_PCI_NORMAL macro:
> https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
> ---
>  drivers/pci/controller/pcie-iproc.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
> index 3df4ab209253..2519201b0e51 100644
> --- a/drivers/pci/controller/pcie-iproc.c
> +++ b/drivers/pci/controller/pcie-iproc.c
> @@ -789,14 +789,13 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
>  		return -EFAULT;
>  	}
>  
> -	/* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
> +	/* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
>  #define PCI_BRIDGE_CTRL_REG_OFFSET	0x43c
> -#define PCI_CLASS_BRIDGE_MASK		0xffff00
> -#define PCI_CLASS_BRIDGE_SHIFT		8
> +#define PCI_BRIDGE_CTRL_REG_CLASS_MASK	0xffffff
>  	iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
>  				    4, &class);
> -	class &= ~PCI_CLASS_BRIDGE_MASK;
> -	class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
> +	class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
> +	class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
>  	iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
>  				     4, class);
>  

I have two comments:

1. You do not seem to generate the email list using the
get_maintainer.pl script, so the two maintainers for Broadcom ARM
architecture (Ray Jui and Scott Branden) are left out.

2. I suppose 'PCI_CLASS_BRIDGE_PCI_NORMAL' is defined in some common PCI
header in a separate patch as described in the commit message. Then how
come these patches are not constructed with a patch series?

Other than, the change itself is exactly what I sent to Roman and looks
good to me. Thanks.

Acked-by: Ray Jui <ray.jui at broadcom.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4194 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220105/166c70ad/attachment.p7s>

From prabhakar.csengg at gmail.com  Wed Jan  5 09:55:32 2022
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Wed, 5 Jan 2022 17:55:32 +0000
Subject: [PATCH v5] soc: ti: smartreflex: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <CAHp75Ve+0VmfU7GhC=AjZ3J1J6KtGko2YAenA9mXCSCVrcuX5w@mail.gmail.com>
References: <20220104164504.24707-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CAHp75Ve+0VmfU7GhC=AjZ3J1J6KtGko2YAenA9mXCSCVrcuX5w@mail.gmail.com>
Message-ID: <CA+V-a8uvuuk_t43COPVnaf2cFOhMxuPkK1Bj5OO9DtygTpy1ag@mail.gmail.com>

Hi Andy,

Thank you for the review.

On Wed, Jan 5, 2022 at 9:47 AM Andy Shevchenko
<andy.shevchenko at gmail.com> wrote:
>
> On Tue, Jan 4, 2022 at 6:45 PM Lad Prabhakar
> <prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
> >
> > platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> > allocation of IRQ resources in DT core code, this causes an issue
> > when using hierarchical interrupt domains using "interrupts" property
> > in the node as this bypasses the hierarchical setup and messes up the
> > irq chaining.
> >
> > In preparation for removal of static setup of IRQ resource from DT core
> > code use platform_get_irq_optional().
> >
> > While at it return 0 instead of returning ret in the probe success path.
>
> ...
>
> > +       ret = platform_get_irq_optional(pdev, 0);
> > +       if (ret < 0 && ret != -ENXIO)
> > +               return dev_err_probe(&pdev->dev, ret, "%s: failed to get IRQ resource\n", __func__);
>
> Sorry, I haven't noticed that you are using __func__ in the message.
> Please don't. It shows either that the message is not unique (so make
> the message unique enough in this driver) or the redundancy of the
> __func__ (it doesn't add any value, but noise).
>
Thanks for the pointer, I was just keeping the messages in-sync with the driver.

Cheers,
Prabhakar


From prabhakar.mahadev-lad.rj at bp.renesas.com  Wed Jan  5 10:03:22 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Wed,  5 Jan 2022 18:03:22 +0000
Subject: [PATCH v6] soc: ti: smartreflex: Use platform_get_irq_optional() to
 get the interrupt
Message-ID: <20220105180323.8563-1-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq_optional().

While at it return 0 instead of returning ret in the probe success path.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v5->v6:
* Dropped printing function name in error message.

v4->v5:
* Fixed missing return while using dev_err_probe().

v3->v4:
* Used dev_err_probe() to print error message
* Returning 0 in probe success path.

v2->v3
* Switch back to platform_get_irq_optional()
* Only print error in case of error, and not when interrupt is missing.

v1->v2
* Updated commit message
* Drop check for IRQ0
* Switched to using platform_get_irq() so that the probe won't
  fail silently as requested by Nishanth.

v1:
* https://www.spinics.net/lists/arm-kernel/msg942549.html
---
 drivers/soc/ti/smartreflex.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
index b5b2fa538d5c..ad2bb72e640c 100644
--- a/drivers/soc/ti/smartreflex.c
+++ b/drivers/soc/ti/smartreflex.c
@@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 {
 	struct omap_sr *sr_info;
 	struct omap_sr_data *pdata = pdev->dev.platform_data;
-	struct resource *mem, *irq;
+	struct resource *mem;
 	struct dentry *nvalue_dir;
 	int i, ret = 0;
 
@@ -844,7 +844,11 @@ static int omap_sr_probe(struct platform_device *pdev)
 	if (IS_ERR(sr_info->base))
 		return PTR_ERR(sr_info->base);
 
-	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	ret = platform_get_irq_optional(pdev, 0);
+	if (ret < 0 && ret != -ENXIO)
+		return dev_err_probe(&pdev->dev, ret, "failed to get IRQ resource\n");
+	if (ret > 0)
+		sr_info->irq = ret;
 
 	sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
 	if (IS_ERR(sr_info->fck))
@@ -870,9 +874,6 @@ static int omap_sr_probe(struct platform_device *pdev)
 	sr_info->autocomp_active = false;
 	sr_info->ip_type = pdata->ip_type;
 
-	if (irq)
-		sr_info->irq = irq->start;
-
 	sr_set_clk_length(sr_info);
 
 	list_add(&sr_info->node, &sr_list);
@@ -926,7 +927,7 @@ static int omap_sr_probe(struct platform_device *pdev)
 
 	}
 
-	return ret;
+	return 0;
 
 err_debugfs:
 	debugfs_remove_recursive(sr_info->dbg_dir);
-- 
2.17.1



From catalin.marinas at arm.com  Wed Jan  5 10:03:57 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 5 Jan 2022 18:03:57 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <20211216082812.165387-1-jianyong.wu@arm.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
Message-ID: <YdXdjcJ7jbnkFsqp@arm.com>

On Thu, Dec 16, 2021 at 04:28:12PM +0800, Jianyong Wu wrote:
> The 'fixmap' is a global resource and is used recursively by
> create pud mapping(), leading to a potential race condition in the
> presence of a concurrent call to alloc_init_pud():
> 
> kernel_init thread                          virtio-mem workqueue thread
> ==================                          ===========================
> 
>   alloc_init_pud(...)                       alloc_init_pud(...)
>   pudp = pud_set_fixmap_offset(...)         pudp = pud_set_fixmap_offset(...)
>   READ_ONCE(*pudp)
>   pud_clear_fixmap(...)
>                                             READ_ONCE(*pudp) // CRASH!
> 
> As kernel may sleep during creating pud mapping, introduce a mutex lock to
> serialise use of the fixmap entries by alloc_init_pud().
> 
> Signed-off-by: Jianyong Wu <jianyong.wu at arm.com>

I tried to queue this patch but with certain configurations it doesn't
boot under Qemu. Starting from defconfig, update .config with (I had
this in one of my build scripts):

$ ./scripts/config \
		-e DEBUG_KERNEL \
		-e DEBUG_PAGEALLOC \
		-e DEBUG_PAGEALLOC_ENABLE_DEFAULT \
		-e DEBUG_WX \
		-e DEBUG_SET_MODULE_RONX \
		-e DEBUG_ALIGN_RODATA \
		-e ARM64_PTDUMP_DEBUGFS \
		-e DEBUG_OBJECTS \
		-e DEBUG_OBJECTS_FREE \
		-e DEBUG_OBJECTS_TIMERS \
		-e DEBUG_KOBJECT_RELEASE \
		-e DEBUG_LOCKING_API_SELFTESTS \
		-e DEBUG_PREEMPT \
		-e DEBUG_TIMEKEEPING \
		-e DEBUG_VM \
		-e DEBUG_VM_VMACACHE \
		-e DEBUG_VM_RB \
		-e DEBUG_VM_PGFLAGS \
		-e DEBUG_VIRTUAL \
		-e DEBUG_LIST \
		-e DEBUG_PI_LIST \
		-e DEBUG_SG \
		-e PROVE_LOCKING \
		-e DEBUG_RT_MUTEXES \
		-e DEBUG_ATOMIC_SLEEP \
		-e ATOMIC64_SELFTEST

It stop after exiting the EFI boot services. I did not have time to
debug.

-- 
Catalin


From pali at kernel.org  Wed Jan  5 10:13:06 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Wed, 5 Jan 2022 19:13:06 +0100
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <244e74d9-1b46-2abc-6c2a-c089fa5b68b4@broadcom.com>
References: <20220105093552.27542-1-pali@kernel.org>
 <244e74d9-1b46-2abc-6c2a-c089fa5b68b4@broadcom.com>
Message-ID: <20220105181306.mkratasqg36tjf4e@pali>

Hello!

On Wednesday 05 January 2022 09:51:48 Ray Jui wrote:
> Hi Pali,
> 
> On 1/5/2022 1:35 AM, Pali Roh?r wrote:
> > Register 0x43c in its low 24 bits contains PCI class code.
> > 
> > Update code to set all 24 bits of PCI class code and not only upper 16 bits
> > of PCI class code.
> > 
> > Use a new macro PCI_CLASS_BRIDGE_PCI_NORMAL which represents whole 24 bits
> > of normal PCI bridge class.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > 
> > ---
> > Roman helped me with this change and confirmed that class code is stored
> > really in bits [23:0] of custom register 0x43c (normally class code is
> > stored in bits [31:8] of pci register 0x08).
> > 
> > This patch depends on patch which adds PCI_CLASS_BRIDGE_PCI_NORMAL macro:
> > https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
> > ---
> >  drivers/pci/controller/pcie-iproc.c | 9 ++++-----
> >  1 file changed, 4 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
> > index 3df4ab209253..2519201b0e51 100644
> > --- a/drivers/pci/controller/pcie-iproc.c
> > +++ b/drivers/pci/controller/pcie-iproc.c
> > @@ -789,14 +789,13 @@ static int iproc_pcie_check_link(struct iproc_pcie *pcie)
> >  		return -EFAULT;
> >  	}
> >  
> > -	/* force class to PCI_CLASS_BRIDGE_PCI (0x0604) */
> > +	/* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
> >  #define PCI_BRIDGE_CTRL_REG_OFFSET	0x43c
> > -#define PCI_CLASS_BRIDGE_MASK		0xffff00
> > -#define PCI_CLASS_BRIDGE_SHIFT		8
> > +#define PCI_BRIDGE_CTRL_REG_CLASS_MASK	0xffffff
> >  	iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
> >  				    4, &class);
> > -	class &= ~PCI_CLASS_BRIDGE_MASK;
> > -	class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT);
> > +	class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
> > +	class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
> >  	iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
> >  				     4, class);
> >  
> 
> I have two comments:
> 
> 1. You do not seem to generate the email list using the
> get_maintainer.pl script, so the two maintainers for Broadcom ARM
> architecture (Ray Jui and Scott Branden) are left out.

Ou, sorry for that! I have generated this patch for U-Boot and Linux
kernel and probably mixed or forgot to include correct recipients for
correct project.

> 2. I suppose 'PCI_CLASS_BRIDGE_PCI_NORMAL' is defined in some common PCI
> header in a separate patch as described in the commit message. Then how
> come these patches are not constructed with a patch series?

Yes, PCI_CLASS_BRIDGE_PCI_NORMAL is a new constant for common pci header
file defined in patch linked in commit message.
https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/

Originally I included this change in v1 of linked patch in December but
I realized that it does not match standard PCI config space (different
offset 0x43c vs 0x08 and also different shift 0x8 vs 0x0) and probably
there is something either incorrect or really non-standard. So later in
December I dropped iproc_pcie_check_link() change in v2 of the linked
patch where is introduced PCI_CLASS_BRIDGE_PCI_NORMAL and now sent new
change for iproc_pcie_check_link() separately.

Technically, linked patch in commit message is just extracting code into
the common macros without any functional changed. But change in this
iproc_pcie_check_link() has also functional change as now also lower 8
bits of class code are changed. So in my opinion this patch should be
really separate of linked patch.

I hope that Lorenzo and Bjorn take patches in correct order...

> Other than, the change itself is exactly what I sent to Roman and looks
> good to me. Thanks.
> 
> Acked-by: Ray Jui <ray.jui at broadcom.com>

Perfect!


From catalin.marinas at arm.com  Wed Jan  5 10:20:16 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed,  5 Jan 2022 18:20:16 +0000
Subject: [PATCH] arm64: Use correct method to calculate nomap region
 boundaries
In-Reply-To: <20211022070646.41923-1-chenhuacai@loongson.cn>
References: <20211022070646.41923-1-chenhuacai@loongson.cn>
Message-ID: <164140680920.1009829.4040216260169936358.b4-ty@arm.com>

On Fri, 22 Oct 2021 15:06:46 +0800, Huacai Chen wrote:
> Nomap regions are treated as "reserved". When region boundaries are not
> page aligned, we usually increase the "reserved" regions rather than
> decrease them. So, we should use memblock_region_reserved_base_pfn()/
> memblock_region_reserved_end_pfn() instead of memblock_region_memory_
> base_pfn()/memblock_region_memory_base_pfn() to calculate boundaries.
> 
> 
> [...]

Applied to arm64 (for-next/misc), thanks!

[1/1] arm64: Use correct method to calculate nomap region boundaries
      https://git.kernel.org/arm64/c/daa149dd8cd4

-- 
Catalin



From catalin.marinas at arm.com  Wed Jan  5 10:21:07 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed,  5 Jan 2022 18:21:07 +0000
Subject: [PATCH] arm64: Drop outdated links in comments
In-Reply-To: <20211215191835.1420010-1-keescook@chromium.org>
References: <20211215191835.1420010-1-keescook@chromium.org>
Message-ID: <164140680919.1009829.13407592428112416247.b4-ty@arm.com>

On Wed, 15 Dec 2021 11:18:35 -0800, Kees Cook wrote:
> As started by commit 05a5f51ca566 ("Documentation: Replace lkml.org links
> with lore"), an effort was made to replace lkml.org links with lore to
> better use a single source that's more likely to stay available long-term.
> However, it seems these links don't offer much value here, so just
> remove them entirely.
> 
> 
> [...]

Applied to arm64 (for-next/misc) but without the arch/arm changes.
Please send them separately to Russell's patch system. Thanks!

[1/1] arm64: Drop outdated links in comments
      https://git.kernel.org/arm64/c/89d30b11507d

-- 
Catalin



From patchwork-bot+netdevbpf at kernel.org  Wed Jan  5 10:40:09 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 05 Jan 2022 18:40:09 +0000
Subject: [PATCH net-next] net: gemini: allow any RGMII interface mode
In-Reply-To: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
References: <E1n4mpT-002PLd-Ha@rmk-PC.armlinux.org.uk>
Message-ID: <164140800991.26997.2579550480629301772.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba at kernel.org>:

On Tue, 04 Jan 2022 16:38:31 +0000 you wrote:
> The four RGMII interface modes take care of the required RGMII delay
> configuration at the PHY and should not be limited by the network MAC
> driver. Sadly, gemini was only permitting RGMII mode with no delays,
> which would require the required delay to be inserted via PCB tracking
> or by the MAC.
> 
> However, there are designs that require the PHY to add the delay, which
> is impossible without Gemini permitting the other three PHY interface
> modes. Fix the driver to allow these.
> 
> [...]

Here is the summary with links:
  - [net-next] net: gemini: allow any RGMII interface mode
    https://git.kernel.org/netdev/net-next/c/4e4f325a0a55

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From seanjc at google.com  Wed Jan  5 11:02:41 2022
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 5 Jan 2022 19:02:41 +0000
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
Message-ID: <YdXrURHO/R82puD4@google.com>

On Wed, Jan 05, 2022, David Stevens wrote:
> On Fri, Dec 31, 2021 at 4:22 AM Sean Christopherson <seanjc at google.com> wrote:
> > >        */
> > > -     if (!pfn_valid(pfn) || WARN_ON_ONCE(!page_count(pfn_to_page(pfn))))
> > > +     if (!pfn_valid(pfn) || !page_count(pfn_to_page(pfn)))
> >
> > Hrm, I know the whole point of this series is to support pages without an elevated
> > refcount, but this WARN was extremely helpful in catching several use-after-free
> > bugs in the TDP MMU.  We talked about burying a slow check behind MMU_WARN_ON, but
> > that isn't very helpful because no one runs with MMU_WARN_ON, and this is also a
> > type of check that's most useful if it runs in production.
> >
> > IIUC, this series explicitly disallows using pfns that have a struct page without
> > refcounting, and the issue with the WARN here is that kvm_is_zone_device_pfn() is
> > called by kvm_is_reserved_pfn() before ensure_pfn_ref() rejects problematic pages,
> > i.e. triggers false positive.
> >
> > So, can't we preserve the use-after-free benefits of the check by moving it to
> > where KVM releases the PFN?  I.e.
> >
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index fbca2e232e94..675b835525fa 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -2904,15 +2904,19 @@ EXPORT_SYMBOL_GPL(kvm_release_pfn_dirty);
> >
> >  void kvm_set_pfn_dirty(kvm_pfn_t pfn)
> >  {
> > -       if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn))
> > +       if (!kvm_is_reserved_pfn(pfn) && !kvm_is_zone_device_pfn(pfn)) {
> > +               WARN_ON_ONCE(!page_count(pfn_to_page(pfn)));
> >                 SetPageDirty(pfn_to_page(pfn));
> > +       }
> >  }
> >  EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
> 
> I'm still seeing this warning show up via __handle_changed_spte
> calling kvm_set_pfn_dirty:
> 
> [  113.350473]  kvm_set_pfn_dirty+0x26/0x3e
> [  113.354861]  __handle_changed_spte+0x452/0x4f6
> [  113.359841]  __handle_changed_spte+0x452/0x4f6
> [  113.364819]  __handle_changed_spte+0x452/0x4f6
> [  113.369790]  zap_gfn_range+0x1de/0x27a
> [  113.373992]  kvm_tdp_mmu_zap_invalidated_roots+0x64/0xb8
> [  113.379945]  kvm_mmu_zap_all_fast+0x18c/0x1c1
> [  113.384827]  kvm_page_track_flush_slot+0x55/0x87
> [  113.390000]  kvm_set_memslot+0x137/0x455
> [  113.394394]  kvm_delete_memslot+0x5c/0x91
> [  113.398888]  __kvm_set_memory_region+0x3c0/0x5e6
> [  113.404061]  kvm_set_memory_region+0x45/0x74
> [  113.408844]  kvm_vm_ioctl+0x563/0x60c
> 
> I wasn't seeing it for my particular test case, but the gfn aging code
> might trigger the warning as well.

Ah, I got royally confused by ensure_pfn_ref()'s comment

  * Certain IO or PFNMAP mappings can be backed with valid
  * struct pages, but be allocated without refcounting e.g.,
  * tail pages of non-compound higher order allocations, which
  * would then underflow the refcount when the caller does the
  * required put_page. Don't allow those pages here.
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
that doesn't apply here because kvm_faultin_pfn() uses the low level
__gfn_to_pfn_page_memslot().

and my understanding is that @page will be non-NULL in ensure_pfn_ref() iff the
page has an elevated refcount.

Can you update the changelogs for the x86+arm64 "use gfn_to_pfn_page" patches to
explicitly call out the various ramifications of moving to gfn_to_pfn_page()?

Side topic, s/covert/convert in both changelogs :-)

> I don't know if setting the dirty/accessed bits in non-refcounted
> struct pages is problematic.

Without knowing exactly what lies behind such pages, KVM needs to set dirty bits,
otherwise there's a potential for data lost.

> The only way I can see to avoid it would be to try to map from the spte to
> the vma and then check its flags. If setting the flags is benign, then we'd
> need to do that lookup to differentiate the safe case from the use-after-free
> case. Do you have any advice on how to handle this?

Hrm.  I can't think of a clever generic solution.  But for x86-64, we can use a
software available bit to mark SPTEs as being refcounted use that flag to assert
the refcount is elevated when marking the backing pfn dirty/accessed.  It'd be
64-bit only because we're out of software available bits for PAE paging, but (a)
practically no one cares about 32-bit and (b) odds are slim that a use-after-free
would be unique to 32-bit KVM.

But that can all go in after your series is merged, e.g. I'd prefer to cleanup
make_spte()'s prototype to use @fault adding yet another parameter, and that'll
take a few patches to make happen since FNAME(sync_page) also uses make_spte().

TL;DR: continue as you were, I'll stop whining about this :-)


From helgaas at kernel.org  Wed Jan  5 11:04:04 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 5 Jan 2022 13:04:04 -0600
Subject: [PATCH v5 3/6] PCI: imx6: PCI: imx6: Move
 imx6_pcie_clk_disable() earlier
In-Reply-To: <1641368602-20401-4-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <20220105190404.GA213307@bhelgaas>

Remove repeated words from subject line.

On Wed, Jan 05, 2022 at 03:43:19PM +0800, Richard Zhu wrote:
> Just move the imx6_pcie_clk_disable() to an earlier place without function
> changes, since it wouldn't be only used in imx6_pcie_suspend_noirq() later.


From seanjc at google.com  Wed Jan  5 11:19:45 2022
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 5 Jan 2022 19:19:45 +0000
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <YdXrURHO/R82puD4@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com>
Message-ID: <YdXvUaBUvaRPsv6m@google.com>

On Wed, Jan 05, 2022, Sean Christopherson wrote:
> Ah, I got royally confused by ensure_pfn_ref()'s comment
> 
>   * Certain IO or PFNMAP mappings can be backed with valid
>   * struct pages, but be allocated without refcounting e.g.,
>   * tail pages of non-compound higher order allocations, which
>   * would then underflow the refcount when the caller does the
>   * required put_page. Don't allow those pages here.
>                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> that doesn't apply here because kvm_faultin_pfn() uses the low level
> __gfn_to_pfn_page_memslot().

On fifth thought, I think this is wrong and doomed to fail.  By mapping these pages
into the guest, KVM is effectively saying it supports these pages.  But if the guest
uses the corresponding gfns for an action that requires KVM to access the page,
e.g. via kvm_vcpu_map(), ensure_pfn_ref() will reject the access and all sorts of
bad things will happen to the guest.

So, why not fully reject these types of pages?  If someone is relying on KVM to
support these types of pages, then we'll fail fast and get a bug report letting us
know we need to properly support these types of pages.  And if not, then we reduce
KVM's complexity and I get to keep my precious WARN :-)


From patchwork-bot+netdevbpf at kernel.org  Wed Jan  5 11:50:09 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 05 Jan 2022 19:50:09 +0000
Subject: [PATCH] bpf, arm64: use emit_addr_mov_i64() for BPF_PSEUDO_FUNC
In-Reply-To: <20211231151018.3781550-1-houtao1@huawei.com>
References: <20211231151018.3781550-1-houtao1@huawei.com>
Message-ID: <164141220979.28548.10398527104221522201.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to bpf/bpf-next.git (master)
by Daniel Borkmann <daniel at iogearbox.net>:

On Fri, 31 Dec 2021 23:10:18 +0800 you wrote:
> The following error is reported when running "./test_progs -t for_each"
> under arm64:
> 
>     bpf_jit: multi-func JIT bug 58 != 56
>     ......
>     JIT doesn't support bpf-to-bpf calls
> 
> [...]

Here is the summary with links:
  - bpf, arm64: use emit_addr_mov_i64() for BPF_PSEUDO_FUNC
    https://git.kernel.org/bpf/bpf-next/c/e4a41c2c1fa9

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From krzysztof.kozlowski at canonical.com  Wed Jan  5 12:24:29 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 5 Jan 2022 21:24:29 +0100
Subject: [PATCH 01/24] pinctrl: samsung: drop pin banks references on
 error paths
In-Reply-To: <CAPLW+4mosbk2_NPFFP=sUmKjBoZOG3vNcmT+7sMtTunhbVqcxA@mail.gmail.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-2-krzysztof.kozlowski@canonical.com>
 <CAPLW+4mosbk2_NPFFP=sUmKjBoZOG3vNcmT+7sMtTunhbVqcxA@mail.gmail.com>
Message-ID: <e54c289c-6aeb-fcf4-67fe-fc8e375149f9@canonical.com>

On 03/01/2022 15:49, Sam Protsenko wrote:
> On Fri, 31 Dec 2021 at 18:20, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> The driver iterates over its devicetree children with
>> for_each_child_of_node() and stores for later found node pointer.  This
>> has to be put in error paths to avoid leak during re-probing.
>>
>> Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device nodes")
>> Cc: <stable at vger.kernel.org>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  drivers/pinctrl/samsung/pinctrl-samsung.c | 29 +++++++++++++++++------
>>  1 file changed, 22 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
>> index 8941f658e7f1..f2864a7869b3 100644
>> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
>> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
>> @@ -1002,6 +1002,15 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
>>         return &(of_data->ctrl[id]);
>>  }
>>
>> +static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
>> +{
>> +       struct samsung_pin_bank *bank;
>> +       unsigned int i;
>> +
>> +       for (i = 0; i < d->nr_banks; ++i, ++bank)
>> +               of_node_put(bank->of_node);
> 
> But "bank" variable wasn't actually assigned before, only declared?

Good point, bank has to be assigned just like in patch 2/24.

> 
>> +}
>> +

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Jan  5 12:31:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 5 Jan 2022 21:31:36 +0100
Subject: [PATCH 02/24] pinctrl: samsung: accept GPIO bank nodes with a
 suffix
In-Reply-To: <CAPLW+4kVjswvcx7PjkBq_cPrmoi1_yJw9qGOO2tcRCDm27zKmA@mail.gmail.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-3-krzysztof.kozlowski@canonical.com>
 <CAPLW+4kVjswvcx7PjkBq_cPrmoi1_yJw9qGOO2tcRCDm27zKmA@mail.gmail.com>
Message-ID: <9c4d825a-1f35-3e47-b91c-499525213343@canonical.com>

On 03/01/2022 19:43, Sam Protsenko wrote:
> On Fri, 31 Dec 2021 at 18:20, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Existing dt-bindings expected that each GPIO/pin bank within pin
>> controller has its own node with name matching the bank (e.g. gpa0,
>> gpx2) and "gpio-controller" property.  The node name is then used for
>> matching between driver data and DTS.
>>
>> Newly introduced dtschema expects to have nodes ending with "-gpio-bank"
>> suffix, so rewrite bank-devicetree matching to look for old and new
>> style of naming.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  drivers/pinctrl/samsung/pinctrl-samsung.c | 57 ++++++++++++++++++-----
>>  1 file changed, 45 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
>> index f2864a7869b3..561853df8ef7 100644
>> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
>> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
>> @@ -1011,13 +1011,56 @@ static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
>>                 of_node_put(bank->of_node);
>>  }
>>
>> +/*
>> + * Iterate over all driver pin banks to find one matching the name of node,
>> + * skipping optional "-gpio" node suffix. When found, assign node to the bank.
>> + */
>> +static void samsung_banks_of_node_get(struct device *dev,
>> +                                     struct samsung_pinctrl_drv_data *d,
>> +                                     struct device_node *node)
>> +{
>> +       const char *suffix = "-gpio-bank";
>> +       struct samsung_pin_bank *bank;
>> +       struct device_node *child;
>> +       /* Pin bank names are up to 4 characters */
>> +       char node_name[20];
>> +       unsigned int i;
>> +       size_t len;
>> +
>> +       bank = d->pin_banks;
>> +       for (i = 0; i < d->nr_banks; ++i, ++bank) {
>> +               strscpy(node_name, bank->name, sizeof(node_name));
>> +               len = strlcat(node_name, suffix, sizeof(node_name));
>> +               if (len == sizeof(sizeof(node_name))) {
> 
> Double sizeof is probably wrong?

Thanks, copy-paste error... it should be also "len >= sizeof".


Best regards,
Krzysztof


From gascoar at gmail.com  Wed Jan  5 12:35:41 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:41 -0300
Subject: [PATCH 0/6] staging: vc04_services: rename ocurrences of 'bm2835*' to
 'bcm2835*'
Message-ID: <cover.1641414449.git.gascoar@gmail.com>

This patch set renames ocurrences of 'bm2835*' to 'bcm2835*'.

Gaston Gonzalez (6):
  staging: vc04_services: rename structures bm2835_mmal_dev and
    bm2835_mmal_v4l2_ctrl
  staging: vc04_services: rename functions containing bm2835_* to
    bcm2835_*
  staging: vc04_services: rename variables containing bm2835_* to
    bcm2835_*
  staging: vc04_services: rename string literal containing bm2835_* to
    bcm2835*_
  staging: vc04_services: rename macros BM2835_MMAL_VERSION and
    BM2835_MMAL_MODULE_NAME
  staging: vc04_services: rename BM2835 to BCM2835 in headers comments

 .../bcm2835-camera/bcm2835-camera.c           | 103 +++++++------
 .../bcm2835-camera/bcm2835-camera.h           |  12 +-
 .../vc04_services/bcm2835-camera/controls.c   | 137 ++++++++----------
 .../vc04_services/vchiq-mmal/mmal-common.h    |   2 +-
 .../vc04_services/vchiq-mmal/mmal-encodings.h |   2 +-
 .../vchiq-mmal/mmal-msg-common.h              |   2 +-
 .../vchiq-mmal/mmal-msg-format.h              |   2 +-
 .../vc04_services/vchiq-mmal/mmal-msg-port.h  |   2 +-
 .../vc04_services/vchiq-mmal/mmal-msg.h       |   2 +-
 .../vchiq-mmal/mmal-parameters.h              |   2 +-
 .../vc04_services/vchiq-mmal/mmal-vchiq.c     |   2 +-
 .../vc04_services/vchiq-mmal/mmal-vchiq.h     |   2 +-
 12 files changed, 127 insertions(+), 143 deletions(-)

-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:43 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:43 -0300
Subject: [PATCH 1/6] staging: vc04_services: rename structures bm2835_mmal_dev
 and bm2835_mmal_v4l2_ctrl
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <a893f24fc5ee6c276ea982f141b42ec0a00d7194.1641414449.git.gascoar@gmail.com>

In the kernel, all names related to the chip BCM2835 are always named
bcm2835_*. To avoid confusion, and to make things more consistent,
rename the structures bm2835_mmal_dev and bm2835_mmal_v4l2_ctrl
accordingly.

While at it, one realignment was made to improve readability.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../bcm2835-camera/bcm2835-camera.c           | 68 ++++++-------
 .../bcm2835-camera/bcm2835-camera.h           |  8 +-
 .../vc04_services/bcm2835-camera/controls.c   | 99 +++++++++----------
 3 files changed, 87 insertions(+), 88 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 1b184d5c6b82..109021643c3f 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -64,7 +64,7 @@ MODULE_PARM_DESC(max_video_height, "Threshold for video mode");
 static atomic_t camera_instance = ATOMIC_INIT(0);
 
 /* global device data array */
-static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
+static struct bcm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
 
 #define FPS_MIN 1
 #define FPS_MAX 90
@@ -210,7 +210,7 @@ static int queue_setup(struct vb2_queue *vq,
 		       unsigned int *nbuffers, unsigned int *nplanes,
 		       unsigned int sizes[], struct device *alloc_ctxs[])
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 	unsigned long size;
 
 	/* refuse queue setup if port is not configured */
@@ -265,7 +265,7 @@ static int queue_setup(struct vb2_queue *vq,
 
 static int buffer_init(struct vb2_buffer *vb)
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 	struct vb2_mmal_buffer *buf =
 				container_of(vb2, struct vb2_mmal_buffer, vb);
@@ -280,7 +280,7 @@ static int buffer_init(struct vb2_buffer *vb)
 
 static int buffer_prepare(struct vb2_buffer *vb)
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 	unsigned long size;
 
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
@@ -302,7 +302,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
 
 static void buffer_cleanup(struct vb2_buffer *vb)
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 	struct vb2_mmal_buffer *buf =
 				container_of(vb2, struct vb2_mmal_buffer, vb);
@@ -313,7 +313,7 @@ static void buffer_cleanup(struct vb2_buffer *vb)
 	mmal_vchi_buffer_cleanup(&buf->mmal);
 }
 
-static inline bool is_capturing(struct bm2835_mmal_dev *dev)
+static inline bool is_capturing(struct bcm2835_mmal_dev *dev)
 {
 	return dev->capture.camera_port ==
 	    &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
@@ -324,7 +324,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 		      int status,
 		      struct mmal_buffer *mmal_buf)
 {
-	struct bm2835_mmal_dev *dev = port->cb_ctx;
+	struct bcm2835_mmal_dev *dev = port->cb_ctx;
 	struct vb2_mmal_buffer *buf =
 			container_of(mmal_buf, struct vb2_mmal_buffer, mmal);
 
@@ -416,7 +416,7 @@ static void buffer_cb(struct vchiq_mmal_instance *instance,
 	}
 }
 
-static int enable_camera(struct bm2835_mmal_dev *dev)
+static int enable_camera(struct bcm2835_mmal_dev *dev)
 {
 	int ret;
 
@@ -447,7 +447,7 @@ static int enable_camera(struct bm2835_mmal_dev *dev)
 	return 0;
 }
 
-static int disable_camera(struct bm2835_mmal_dev *dev)
+static int disable_camera(struct bcm2835_mmal_dev *dev)
 {
 	int ret;
 
@@ -482,7 +482,7 @@ static int disable_camera(struct bm2835_mmal_dev *dev)
 
 static void buffer_queue(struct vb2_buffer *vb)
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 	struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 	struct vb2_mmal_buffer *buf =
 				container_of(vb2, struct vb2_mmal_buffer, vb);
@@ -501,7 +501,7 @@ static void buffer_queue(struct vb2_buffer *vb)
 
 static int start_streaming(struct vb2_queue *vq, unsigned int count)
 {
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 	int ret;
 	u32 parameter_size;
 
@@ -596,7 +596,7 @@ static void stop_streaming(struct vb2_queue *vq)
 {
 	int ret;
 	unsigned long timeout;
-	struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
+	struct bcm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 	struct vchiq_mmal_port *port = dev->capture.port;
 
 	v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
@@ -671,7 +671,7 @@ static const struct vb2_ops bm2835_mmal_video_qops = {
  * ------------------------------------------------------------------
  */
 
-static int set_overlay_params(struct bm2835_mmal_dev *dev,
+static int set_overlay_params(struct bcm2835_mmal_dev *dev,
 			      struct vchiq_mmal_port *port)
 {
 	struct mmal_parameter_displayregion prev_config = {
@@ -713,7 +713,7 @@ static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv,
 static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
 				    struct v4l2_format *f)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 
 	f->fmt.win = dev->overlay;
 
@@ -723,7 +723,7 @@ static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
 				      struct v4l2_format *f)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 
 	f->fmt.win.field = V4L2_FIELD_NONE;
 	f->fmt.win.chromakey = 0;
@@ -754,7 +754,7 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
 static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
 				    struct v4l2_format *f)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 
 	vidioc_try_fmt_vid_overlay(file, priv, f);
 
@@ -770,7 +770,7 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
 static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 {
 	int ret;
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	struct vchiq_mmal_port *src;
 	struct vchiq_mmal_port *dst;
 
@@ -829,7 +829,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh,
 	/* The video overlay must stay within the framebuffer and can't be
 	 * positioned independently.
 	 */
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	struct vchiq_mmal_port *preview_port =
 		&dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
 
@@ -878,7 +878,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 static int vidioc_querycap(struct file *file, void *priv,
 			   struct v4l2_capability *cap)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	u32 major;
 	u32 minor;
 
@@ -911,7 +911,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 
 	f->fmt.pix.width = dev->capture.width;
 	f->fmt.pix.height = dev->capture.height;
@@ -936,7 +936,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 				  struct v4l2_format *f)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	struct mmal_fmt *mfmt;
 
 	mfmt = get_format(f);
@@ -1010,7 +1010,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 }
 
 
-static int mmal_setup_video_component(struct bm2835_mmal_dev *dev,
+static int mmal_setup_video_component(struct bcm2835_mmal_dev *dev,
 				      struct v4l2_format *f)
 {
 	bool overlay_enabled = !!dev->component[COMP_PREVIEW]->enabled;
@@ -1056,7 +1056,7 @@ static int mmal_setup_video_component(struct bm2835_mmal_dev *dev,
 	return ret;
 }
 
-static int mmal_setup_encode_component(struct bm2835_mmal_dev *dev,
+static int mmal_setup_encode_component(struct bcm2835_mmal_dev *dev,
 				       struct v4l2_format *f,
 				       struct vchiq_mmal_port *port,
 				       struct vchiq_mmal_port *camera_port,
@@ -1144,7 +1144,7 @@ static int mmal_setup_encode_component(struct bm2835_mmal_dev *dev,
 	return 0;
 }
 
-static int mmal_setup_components(struct bm2835_mmal_dev *dev,
+static int mmal_setup_components(struct bcm2835_mmal_dev *dev,
 				 struct v4l2_format *f)
 {
 	int ret;
@@ -1290,7 +1290,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	int ret;
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	struct mmal_fmt *mfmt;
 
 	/* try the format to set valid parameters */
@@ -1333,7 +1333,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
 static int vidioc_enum_framesizes(struct file *file, void *fh,
 				  struct v4l2_frmsizeenum *fsize)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	static const struct v4l2_frmsize_stepwise sizes = {
 		MIN_WIDTH, 0, 2,
 		MIN_HEIGHT, 0, 2
@@ -1358,7 +1358,7 @@ static int vidioc_enum_framesizes(struct file *file, void *fh,
 static int vidioc_enum_frameintervals(struct file *file, void *priv,
 				      struct v4l2_frmivalenum *fival)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	int i;
 
 	if (fival->index)
@@ -1388,7 +1388,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
 static int vidioc_g_parm(struct file *file, void *priv,
 			 struct v4l2_streamparm *parm)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -1402,7 +1402,7 @@ static int vidioc_g_parm(struct file *file, void *priv,
 static int vidioc_s_parm(struct file *file, void *priv,
 			 struct v4l2_streamparm *parm)
 {
-	struct bm2835_mmal_dev *dev = video_drvdata(file);
+	struct bcm2835_mmal_dev *dev = video_drvdata(file);
 	struct v4l2_fract tpf;
 
 	if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1530,7 +1530,7 @@ static int get_num_cameras(struct vchiq_mmal_instance *instance,
 
 static int set_camera_parameters(struct vchiq_mmal_instance *instance,
 				 struct vchiq_mmal_component *camera,
-				 struct bm2835_mmal_dev *dev)
+				 struct bcm2835_mmal_dev *dev)
 {
 	struct mmal_parameter_camera_config cam_config = {
 		.max_stills_w = dev->max_width,
@@ -1555,7 +1555,7 @@ static int set_camera_parameters(struct vchiq_mmal_instance *instance,
 #define MAX_SUPPORTED_ENCODINGS 20
 
 /* MMAL instance and component init */
-static int mmal_init(struct bm2835_mmal_dev *dev)
+static int mmal_init(struct bcm2835_mmal_dev *dev)
 {
 	int ret;
 	struct mmal_es_format_local *format;
@@ -1769,7 +1769,7 @@ static int mmal_init(struct bm2835_mmal_dev *dev)
 	return ret;
 }
 
-static int bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
+static int bm2835_mmal_init_device(struct bcm2835_mmal_dev *dev,
 				   struct video_device *vfd)
 {
 	int ret;
@@ -1798,7 +1798,7 @@ static int bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
 	return 0;
 }
 
-static void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev)
+static void bcm2835_cleanup_instance(struct bcm2835_mmal_dev *dev)
 {
 	if (!dev)
 		return;
@@ -1849,7 +1849,7 @@ static struct v4l2_format default_v4l2_format = {
 static int bcm2835_mmal_probe(struct platform_device *pdev)
 {
 	int ret;
-	struct bm2835_mmal_dev *dev;
+	struct bcm2835_mmal_dev *dev;
 	struct vb2_queue *q;
 	int camera;
 	unsigned int num_cameras;
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
index 75524adff0f5..338b7c142ae3 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
@@ -32,7 +32,7 @@ enum {
 
 extern int bcm2835_v4l2_debug;
 
-struct bm2835_mmal_dev {
+struct bcm2835_mmal_dev {
 	/* v4l2 devices */
 	struct v4l2_device v4l2_dev;
 	struct video_device vdev;
@@ -111,11 +111,11 @@ struct bm2835_mmal_dev {
 };
 
 int bm2835_mmal_init_controls(
-			struct bm2835_mmal_dev *dev,
+			struct bcm2835_mmal_dev *dev,
 			struct v4l2_ctrl_handler *hdl);
 
-int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev);
-int set_framerate_params(struct bm2835_mmal_dev *dev);
+int bm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev);
+int set_framerate_params(struct bcm2835_mmal_dev *dev);
 
 /* Debug helpers */
 
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 3696dfb5a020..03967a7d99a0 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -65,7 +65,7 @@ enum bm2835_mmal_ctrl_type {
 	MMAL_CONTROL_TYPE_CLUSTER, /* special cluster entry */
 };
 
-struct bm2835_mmal_v4l2_ctrl {
+struct bcm2835_mmal_v4l2_ctrl {
 	u32 id; /* v4l2 control identifier */
 	enum bm2835_mmal_ctrl_type type;
 	/* control minimum value or
@@ -77,8 +77,8 @@ struct bm2835_mmal_v4l2_ctrl {
 	u64 step; /* step size of the control */
 	const s64 *imenu; /* integer menu array */
 	u32 mmal_id; /* mmal parameter id */
-	int (*setter)(struct bm2835_mmal_dev *dev, struct v4l2_ctrl *ctrl,
-		      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl);
+	int (*setter)(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl *ctrl,
+		      const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl);
 };
 
 struct v4l2_to_mmal_effects_setting {
@@ -150,9 +150,9 @@ static const struct v4l2_mmal_scene_config scene_configs[] = {
 
 /* control handlers*/
 
-static int ctrl_set_rational(struct bm2835_mmal_dev *dev,
+static int ctrl_set_rational(struct bcm2835_mmal_dev *dev,
 			     struct v4l2_ctrl *ctrl,
-			     const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			     const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	struct mmal_parameter_rational rational_value;
 	struct vchiq_mmal_port *control;
@@ -168,9 +168,9 @@ static int ctrl_set_rational(struct bm2835_mmal_dev *dev,
 					     sizeof(rational_value));
 }
 
-static int ctrl_set_value(struct bm2835_mmal_dev *dev,
+static int ctrl_set_value(struct bcm2835_mmal_dev *dev,
 			  struct v4l2_ctrl *ctrl,
-			  const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			  const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *control;
@@ -184,9 +184,9 @@ static int ctrl_set_value(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_iso(struct bm2835_mmal_dev *dev,
+static int ctrl_set_iso(struct bcm2835_mmal_dev *dev,
 			struct v4l2_ctrl *ctrl,
-			const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *control;
@@ -212,9 +212,9 @@ static int ctrl_set_iso(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev,
+static int ctrl_set_value_ev(struct bcm2835_mmal_dev *dev,
 			     struct v4l2_ctrl *ctrl,
-			     const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			     const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	s32 s32_value;
 	struct vchiq_mmal_port *control;
@@ -228,9 +228,9 @@ static int ctrl_set_value_ev(struct bm2835_mmal_dev *dev,
 					     &s32_value, sizeof(s32_value));
 }
 
-static int ctrl_set_rotate(struct bm2835_mmal_dev *dev,
+static int ctrl_set_rotate(struct bcm2835_mmal_dev *dev,
 			   struct v4l2_ctrl *ctrl,
-			   const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			   const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret;
 	u32 u32_value;
@@ -257,9 +257,9 @@ static int ctrl_set_rotate(struct bm2835_mmal_dev *dev,
 					    &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_flip(struct bm2835_mmal_dev *dev,
+static int ctrl_set_flip(struct bcm2835_mmal_dev *dev,
 			 struct v4l2_ctrl *ctrl,
-			 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			 const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret;
 	u32 u32_value;
@@ -298,9 +298,9 @@ static int ctrl_set_flip(struct bm2835_mmal_dev *dev,
 					    &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
+static int ctrl_set_exposure(struct bcm2835_mmal_dev *dev,
 			     struct v4l2_ctrl *ctrl,
-			     const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			     const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	enum mmal_parameter_exposuremode exp_mode = dev->exposure_mode_user;
 	u32 shutter_speed = 0;
@@ -354,9 +354,9 @@ static int ctrl_set_exposure(struct bm2835_mmal_dev *dev,
 	return ret;
 }
 
-static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev,
+static int ctrl_set_metering_mode(struct bcm2835_mmal_dev *dev,
 				  struct v4l2_ctrl *ctrl,
-				  const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+				  const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	switch (ctrl->val) {
 	case V4L2_EXPOSURE_METERING_AVERAGE:
@@ -390,9 +390,9 @@ static int ctrl_set_metering_mode(struct bm2835_mmal_dev *dev,
 	}
 }
 
-static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev,
+static int ctrl_set_flicker_avoidance(struct bcm2835_mmal_dev *dev,
 				      struct v4l2_ctrl *ctrl,
-				      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+				      const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *control;
@@ -419,9 +419,9 @@ static int ctrl_set_flicker_avoidance(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev,
+static int ctrl_set_awb_mode(struct bcm2835_mmal_dev *dev,
 			     struct v4l2_ctrl *ctrl,
-			     const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			     const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *control;
@@ -475,9 +475,9 @@ static int ctrl_set_awb_mode(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_awb_gains(struct bm2835_mmal_dev *dev,
+static int ctrl_set_awb_gains(struct bcm2835_mmal_dev *dev,
 			      struct v4l2_ctrl *ctrl,
-			      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			      const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	struct vchiq_mmal_port *control;
 	struct mmal_parameter_awbgains gains;
@@ -498,9 +498,9 @@ static int ctrl_set_awb_gains(struct bm2835_mmal_dev *dev,
 					     &gains, sizeof(gains));
 }
 
-static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev,
+static int ctrl_set_image_effect(struct bcm2835_mmal_dev *dev,
 				 struct v4l2_ctrl *ctrl,
-				 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+				 const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret = -EINVAL;
 	int i, j;
@@ -555,9 +555,9 @@ static int ctrl_set_image_effect(struct bm2835_mmal_dev *dev,
 	return (ret == 0 ? 0 : -EINVAL);
 }
 
-static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
+static int ctrl_set_colfx(struct bcm2835_mmal_dev *dev,
 			  struct v4l2_ctrl *ctrl,
-			  const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			  const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret;
 	struct vchiq_mmal_port *control;
@@ -579,9 +579,9 @@ static int ctrl_set_colfx(struct bm2835_mmal_dev *dev,
 	return (ret == 0 ? 0 : -EINVAL);
 }
 
-static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev,
+static int ctrl_set_bitrate(struct bcm2835_mmal_dev *dev,
 			    struct v4l2_ctrl *ctrl,
-			    const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			    const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret;
 	struct vchiq_mmal_port *encoder_out;
@@ -607,9 +607,9 @@ static int ctrl_set_bitrate(struct bm2835_mmal_dev *dev,
 	return 0;
 }
 
-static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev,
+static int ctrl_set_bitrate_mode(struct bcm2835_mmal_dev *dev,
 				 struct v4l2_ctrl *ctrl,
-				 const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+				 const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 bitrate_mode;
 	struct vchiq_mmal_port *encoder_out;
@@ -634,9 +634,9 @@ static int ctrl_set_bitrate_mode(struct bm2835_mmal_dev *dev,
 	return 0;
 }
 
-static int ctrl_set_image_encode_output(struct bm2835_mmal_dev *dev,
+static int ctrl_set_image_encode_output(struct bcm2835_mmal_dev *dev,
 					struct v4l2_ctrl *ctrl,
-					const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+					const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *jpeg_out;
@@ -650,9 +650,9 @@ static int ctrl_set_image_encode_output(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev,
+static int ctrl_set_video_encode_param_output(struct bcm2835_mmal_dev *dev,
 					      struct v4l2_ctrl *ctrl,
-					      const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+					      const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	u32 u32_value;
 	struct vchiq_mmal_port *vid_enc_ctl;
@@ -666,9 +666,9 @@ static int ctrl_set_video_encode_param_output(struct bm2835_mmal_dev *dev,
 					     &u32_value, sizeof(u32_value));
 }
 
-static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev,
+static int ctrl_set_video_encode_profile_level(struct bcm2835_mmal_dev *dev,
 					       struct v4l2_ctrl *ctrl,
-					       const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+					       const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	struct mmal_parameter_video_profile param;
 	int ret = 0;
@@ -777,9 +777,9 @@ static int ctrl_set_video_encode_profile_level(struct bm2835_mmal_dev *dev,
 	return ret;
 }
 
-static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev,
+static int ctrl_set_scene_mode(struct bcm2835_mmal_dev *dev,
 			       struct v4l2_ctrl *ctrl,
-			       const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl)
+			       const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl)
 {
 	int ret = 0;
 	int shutter_speed;
@@ -886,10 +886,9 @@ static int ctrl_set_scene_mode(struct bm2835_mmal_dev *dev,
 
 static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
 {
-	struct bm2835_mmal_dev *dev =
-		container_of(ctrl->handler, struct bm2835_mmal_dev,
-			     ctrl_handler);
-	const struct bm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
+	struct bcm2835_mmal_dev *dev = container_of(ctrl->handler, struct bcm2835_mmal_dev,
+						    ctrl_handler);
+	const struct bcm2835_mmal_v4l2_ctrl *mmal_ctrl = ctrl->priv;
 	int ret;
 
 	if (!mmal_ctrl || mmal_ctrl->id != ctrl->id || !mmal_ctrl->setter) {
@@ -908,7 +907,7 @@ static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = {
 	.s_ctrl = bm2835_mmal_s_ctrl,
 };
 
-static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
+static const struct bcm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
 	{
 		.id = V4L2_CID_SATURATION,
 		.type = MMAL_CONTROL_TYPE_STD,
@@ -1247,7 +1246,7 @@ static const struct bm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
 	},
 };
 
-int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
+int bm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev)
 {
 	int c;
 	int ret = 0;
@@ -1267,7 +1266,7 @@ int bm2835_mmal_set_all_camera_controls(struct bm2835_mmal_dev *dev)
 	return ret;
 }
 
-int set_framerate_params(struct bm2835_mmal_dev *dev)
+int set_framerate_params(struct bcm2835_mmal_dev *dev)
 {
 	struct mmal_parameter_fps_range fps_range;
 	int ret;
@@ -1312,11 +1311,11 @@ int set_framerate_params(struct bm2835_mmal_dev *dev)
 	return ret;
 }
 
-int bm2835_mmal_init_controls(struct bm2835_mmal_dev *dev,
+int bm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev,
 			      struct v4l2_ctrl_handler *hdl)
 {
 	int c;
-	const struct bm2835_mmal_v4l2_ctrl *ctrl;
+	const struct bcm2835_mmal_v4l2_ctrl *ctrl;
 
 	v4l2_ctrl_handler_init(hdl, V4L2_CTRL_COUNT);
 
-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:44 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:44 -0300
Subject: [PATCH 2/6] staging: vc04_services: rename functions containing
 bm2835_* to bcm2835_*
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <d3b6f67421c75829105f793cfb9ec1414b926bf6.1641414449.git.gascoar@gmail.com>

In the kernel, all names related to the chip BCM2835 are always named
bcm2835_*. To avoid confusion, and to make things more consistent,
rename functions using bm2835_* to bcm2835_*.

While at it, some realignments were made to improve readability.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c        | 9 ++++-----
 .../vc04_services/bcm2835-camera/bcm2835-camera.h        | 6 ++----
 drivers/staging/vc04_services/bcm2835-camera/controls.c  | 9 ++++-----
 3 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 109021643c3f..159ac600d11e 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1735,7 +1735,7 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
 					      &enable,
 					      sizeof(enable));
 	}
-	ret = bm2835_mmal_set_all_camera_controls(dev);
+	ret = bcm2835_mmal_set_all_camera_controls(dev);
 	if (ret < 0) {
 		v4l2_err(&dev->v4l2_dev, "%s: failed to set all camera controls: %d\n",
 			 __func__, ret);
@@ -1769,8 +1769,7 @@ static int mmal_init(struct bcm2835_mmal_dev *dev)
 	return ret;
 }
 
-static int bm2835_mmal_init_device(struct bcm2835_mmal_dev *dev,
-				   struct video_device *vfd)
+static int bcm2835_mmal_init_device(struct bcm2835_mmal_dev *dev, struct video_device *vfd)
 {
 	int ret;
 
@@ -1908,7 +1907,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 		}
 
 		/* setup v4l controls */
-		ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler);
+		ret = bcm2835_mmal_init_controls(dev, &dev->ctrl_handler);
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev, "%s: could not init controls: %d\n",
 				 __func__, ret);
@@ -1940,7 +1939,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 			goto unreg_dev;
 
 		/* initialise video devices */
-		ret = bm2835_mmal_init_device(dev, &dev->vdev);
+		ret = bcm2835_mmal_init_device(dev, &dev->vdev);
 		if (ret < 0) {
 			v4l2_err(&dev->v4l2_dev, "%s: could not init device: %d\n",
 				 __func__, ret);
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
index 338b7c142ae3..84ba789af120 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
@@ -110,11 +110,9 @@ struct bcm2835_mmal_dev {
 	unsigned int rgb_bgr_swapped;
 };
 
-int bm2835_mmal_init_controls(
-			struct bcm2835_mmal_dev *dev,
-			struct v4l2_ctrl_handler *hdl);
+int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_handler *hdl);
 
-int bm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev);
+int bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev);
 int set_framerate_params(struct bcm2835_mmal_dev *dev);
 
 /* Debug helpers */
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 03967a7d99a0..08fadc164b02 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -884,7 +884,7 @@ static int ctrl_set_scene_mode(struct bcm2835_mmal_dev *dev,
 	return 0;
 }
 
-static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
+static int bcm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
 {
 	struct bcm2835_mmal_dev *dev = container_of(ctrl->handler, struct bcm2835_mmal_dev,
 						    ctrl_handler);
@@ -904,7 +904,7 @@ static int bm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
 }
 
 static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = {
-	.s_ctrl = bm2835_mmal_s_ctrl,
+	.s_ctrl = bcm2835_mmal_s_ctrl,
 };
 
 static const struct bcm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
@@ -1246,7 +1246,7 @@ static const struct bcm2835_mmal_v4l2_ctrl v4l2_ctrls[V4L2_CTRL_COUNT] = {
 	},
 };
 
-int bm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev)
+int bcm2835_mmal_set_all_camera_controls(struct bcm2835_mmal_dev *dev)
 {
 	int c;
 	int ret = 0;
@@ -1311,8 +1311,7 @@ int set_framerate_params(struct bcm2835_mmal_dev *dev)
 	return ret;
 }
 
-int bm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev,
-			      struct v4l2_ctrl_handler *hdl)
+int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_handler *hdl)
 {
 	int c;
 	const struct bcm2835_mmal_v4l2_ctrl *ctrl;
-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:45 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:45 -0300
Subject: [PATCH 3/6] staging: vc04_services: rename variables containing
 bm2835_* to bcm2835_*
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <a0af5deacebc2da9b21772c7677e1a9627edbed6.1641414449.git.gascoar@gmail.com>

In the kernel, all names related to the chip BCM2835 are always named
bcm2835_*. To avoid confusion, and to make things more consistent,
rename all variables using bm2835_* to bcm2835_*.

While at it, some realignments were made to improve readability.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../bcm2835-camera/bcm2835-camera.c           |  4 +--
 .../vc04_services/bcm2835-camera/controls.c   | 31 +++++++------------
 2 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 159ac600d11e..cbc881e19f65 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -654,7 +654,7 @@ static void stop_streaming(struct vb2_queue *vq)
 		v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
 }
 
-static const struct vb2_ops bm2835_mmal_video_qops = {
+static const struct vb2_ops bcm2835_mmal_video_qops = {
 	.queue_setup = queue_setup,
 	.buf_init = buffer_init,
 	.buf_prepare = buffer_prepare,
@@ -1930,7 +1930,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 		q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
 		q->drv_priv = dev;
 		q->buf_struct_size = sizeof(struct vb2_mmal_buffer);
-		q->ops = &bm2835_mmal_video_qops;
+		q->ops = &bcm2835_mmal_video_qops;
 		q->mem_ops = &vb2_vmalloc_memops;
 		q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
 		q->lock = &dev->mutex;
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 08fadc164b02..178fb310b89a 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -58,7 +58,7 @@ static const u32 iso_values[] = {
 	0, 100, 200, 400, 800,
 };
 
-enum bm2835_mmal_ctrl_type {
+enum bcm2835_mmal_ctrl_type {
 	MMAL_CONTROL_TYPE_STD,
 	MMAL_CONTROL_TYPE_STD_MENU,
 	MMAL_CONTROL_TYPE_INT_MENU,
@@ -67,7 +67,7 @@ enum bm2835_mmal_ctrl_type {
 
 struct bcm2835_mmal_v4l2_ctrl {
 	u32 id; /* v4l2 control identifier */
-	enum bm2835_mmal_ctrl_type type;
+	enum bcm2835_mmal_ctrl_type type;
 	/* control minimum value or
 	 * mask for MMAL_CONTROL_TYPE_STD_MENU
 	 */
@@ -903,7 +903,7 @@ static int bcm2835_mmal_s_ctrl(struct v4l2_ctrl *ctrl)
 	return ret;
 }
 
-static const struct v4l2_ctrl_ops bm2835_mmal_ctrl_ops = {
+static const struct v4l2_ctrl_ops bcm2835_mmal_ctrl_ops = {
 	.s_ctrl = bcm2835_mmal_s_ctrl,
 };
 
@@ -1323,12 +1323,9 @@ int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_ha
 
 		switch (ctrl->type) {
 		case MMAL_CONTROL_TYPE_STD:
-			dev->ctrls[c] =
-				v4l2_ctrl_new_std(hdl,
-						  &bm2835_mmal_ctrl_ops,
-						  ctrl->id, ctrl->min,
-						  ctrl->max, ctrl->step,
-						  ctrl->def);
+			dev->ctrls[c] = v4l2_ctrl_new_std(hdl, &bcm2835_mmal_ctrl_ops,
+							  ctrl->id, ctrl->min, ctrl->max,
+							  ctrl->step, ctrl->def);
 			break;
 
 		case MMAL_CONTROL_TYPE_STD_MENU:
@@ -1352,20 +1349,16 @@ int bcm2835_mmal_init_controls(struct bcm2835_mmal_dev *dev, struct v4l2_ctrl_ha
 				mask = ~mask;
 			}
 
-			dev->ctrls[c] =
-				v4l2_ctrl_new_std_menu(hdl,
-						       &bm2835_mmal_ctrl_ops,
-						       ctrl->id, ctrl->max,
-						       mask, ctrl->def);
+			dev->ctrls[c] = v4l2_ctrl_new_std_menu(hdl, &bcm2835_mmal_ctrl_ops,
+							       ctrl->id, ctrl->max, mask,
+							       ctrl->def);
 			break;
 		}
 
 		case MMAL_CONTROL_TYPE_INT_MENU:
-			dev->ctrls[c] =
-				v4l2_ctrl_new_int_menu(hdl,
-						       &bm2835_mmal_ctrl_ops,
-						       ctrl->id, ctrl->max,
-						       ctrl->def, ctrl->imenu);
+			dev->ctrls[c] = v4l2_ctrl_new_int_menu(hdl, &bcm2835_mmal_ctrl_ops,
+							       ctrl->id, ctrl->max,
+							       ctrl->def, ctrl->imenu);
 			break;
 
 		case MMAL_CONTROL_TYPE_CLUSTER:
-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:46 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:46 -0300
Subject: [PATCH 4/6] staging: vc04_services: rename string literal containing
 bm2835_* to bcm2835*_
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <91caae07fce0e4511f283388304e935526ba29ed.1641414449.git.gascoar@gmail.com>

In the kernel, all names related to the chip BCM2835 are always named
bcm2835_*. To avoid confusion, and to make things more consistent,
rename the string term bm2835_* to bcm2835_*.

While at it, some realignments were made to improve readability.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index cbc881e19f65..aaf529f2186c 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -884,12 +884,10 @@ static int vidioc_querycap(struct file *file, void *priv,
 
 	vchiq_mmal_version(dev->instance, &major, &minor);
 
-	strscpy(cap->driver, "bm2835 mmal", sizeof(cap->driver));
-	snprintf((char *)cap->card, sizeof(cap->card), "mmal service %d.%d",
-		 major, minor);
+	strscpy(cap->driver, "bcm2835 mmal", sizeof(cap->driver));
+	snprintf((char *)cap->card, sizeof(cap->card), "mmal service %d.%d", major, minor);
 
-	snprintf((char *)cap->bus_info, sizeof(cap->bus_info),
-		 "platform:%s", dev->v4l2_dev.name);
+	snprintf((char *)cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev->v4l2_dev.name);
 	return 0;
 }
 
-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:47 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:47 -0300
Subject: [PATCH 5/6] staging: vc04_services: rename macros BM2835_MMAL_VERSION
 and BM2835_MMAL_MODULE_NAME
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <d450b9e22e5ab335a61591dbf0d2104031c9fc46.1641414449.git.gascoar@gmail.com>

In the kernel, all names related to the chip BCM2835 are always named
bcm2835_*. To avoid confusion, and to make things more consistent,
rename the macros BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
accordingly.

While at it, some realignments were made to improve readability.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../vc04_services/bcm2835-camera/bcm2835-camera.c  | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index aaf529f2186c..c729b1b7de71 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -33,8 +33,8 @@
 #include "mmal-parameters.h"
 #include "bcm2835-camera.h"
 
-#define BM2835_MMAL_VERSION "0.0.2"
-#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
+#define BCM2835_MMAL_VERSION "0.0.2"
+#define BCM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
 #define MIN_WIDTH 32
 #define MIN_HEIGHT 32
 #define MIN_BUFFER_SIZE (80 * 1024)
@@ -1894,8 +1894,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 		dev->capture.fmt = &formats[3]; /* JPEG */
 
 		/* v4l device registration */
-		dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev,
-						       BM2835_MMAL_MODULE_NAME,
+		dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev, BCM2835_MMAL_MODULE_NAME,
 						       &camera_instance);
 		ret = v4l2_device_register(NULL, &dev->v4l2_dev);
 		if (ret) {
@@ -1954,9 +1953,8 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 			goto unreg_dev;
 		}
 
-		v4l2_info(&dev->v4l2_dev,
-			  "Broadcom 2835 MMAL video capture ver %s loaded.\n",
-			  BM2835_MMAL_VERSION);
+		v4l2_info(&dev->v4l2_dev, "Broadcom 2835 MMAL video capture ver %s loaded.\n",
+			  BCM2835_MMAL_VERSION);
 
 		gdev[camera] = dev;
 	}
@@ -2008,5 +2006,5 @@ module_platform_driver(bcm2835_camera_driver)
 MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture");
 MODULE_AUTHOR("Vincent Sanders");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(BM2835_MMAL_VERSION);
+MODULE_VERSION(BCM2835_MMAL_VERSION);
 MODULE_ALIAS("platform:bcm2835-camera");
-- 
2.34.1



From gascoar at gmail.com  Wed Jan  5 12:35:48 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Wed,  5 Jan 2022 17:35:48 -0300
Subject: [PATCH 6/6] staging: vc04_services: rename BM2835 to BCM2835 in
 headers comments
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <19acea9e9da0d3ebb1a7e6bce511a3c09e8c80c3.1641414449.git.gascoar@gmail.com>

In the kernel, when referring to the chip BCM2835, it is more suitable
to use BCM2835 to BM2835. To avoid confusion, and to make things more
consistent, rename the headers titles accordingly.

Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 2 +-
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h | 2 +-
 drivers/staging/vc04_services/bcm2835-camera/controls.c       | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-common.h        | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h     | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h    | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h    | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h      | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h           | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h    | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c         | 2 +-
 drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h         | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index c729b1b7de71..597c51e8ddf4 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
index 84ba789af120..0f0c6f7a3764 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/bcm2835-camera/controls.c b/drivers/staging/vc04_services/bcm2835-camera/controls.c
index 178fb310b89a..eb722f16fb91 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/controls.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/controls.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
index 5bd7410a034a..b33129403a30 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-common.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
index 2be9941a1f30..e15ae7b24f73 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-encodings.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
index 342c9b670f7e..d77e15f25dda 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-common.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
index a118efd21d98..1e996d8cd283 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-format.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
index 3fa3f2a578f0..6ee4c1ed7f19 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg-port.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
index b636e889c8a1..471413248a14 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-msg.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
index a1e39b1b1701..2277e05b1e31 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-parameters.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
index 76d3f0399964..cb6cdbfaf6ec 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
index 1dc81ecf9268..6006e29232b3 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Broadcom BM2835 V4L2 driver
+ * Broadcom BCM2835 V4L2 driver
  *
  * Copyright ? 2013 Raspberry Pi (Trading) Ltd.
  *
-- 
2.34.1



From yuzhao at google.com  Wed Jan  5 12:47:08 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 5 Jan 2022 13:47:08 -0700
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20220105104526.GA3015@willie-the-truck>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
 <20220105104526.GA3015@willie-the-truck>
Message-ID: <YdYDzKvYbBwjfU3W@google.com>

On Wed, Jan 05, 2022 at 10:45:26AM +0000, Will Deacon wrote:
> On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> > Some architectures automatically set the accessed bit in PTEs, e.g.,
> > x86 and arm64 v8.2. On architectures that don't have this capability,
> > clearing the accessed bit in a PTE usually triggers a page fault
> > following the TLB miss of this PTE.
> > 
> > Being aware of this capability can help make better decisions, e.g.,
> > whether to spread the work out over a period of time to avoid bursty
> > page faults when trying to clear the accessed bit in a large number of
> > PTEs.
> > 
> > Signed-off-by: Yu Zhao <yuzhao at google.com>
> > Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> > ---
> >  arch/arm64/include/asm/cpufeature.h |  5 +++++
> >  arch/arm64/include/asm/pgtable.h    | 13 ++++++++-----
> >  arch/arm64/kernel/cpufeature.c      | 19 +++++++++++++++++++
> >  arch/arm64/tools/cpucaps            |  1 +
> >  arch/x86/include/asm/pgtable.h      |  6 +++---
> >  include/linux/pgtable.h             | 13 +++++++++++++
> >  mm/memory.c                         | 14 +-------------
> >  7 files changed, 50 insertions(+), 21 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> > index ef6be92b1921..99518b4b2a9e 100644
> > --- a/arch/arm64/include/asm/cpufeature.h
> > +++ b/arch/arm64/include/asm/cpufeature.h
> > @@ -779,6 +779,11 @@ static inline bool system_supports_tlb_range(void)
> >  		cpus_have_const_cap(ARM64_HAS_TLB_RANGE);
> >  }
> >  
> > +static inline bool system_has_hw_af(void)
> > +{
> > +	return IS_ENABLED(CONFIG_ARM64_HW_AFDBM) && cpus_have_const_cap(ARM64_HW_AF);
> > +}
> > +
> >  extern int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
> >  
> >  static inline u32 id_aa64mmfr0_parange_to_phys_shift(int parange)
> > diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> > index c4ba047a82d2..e736f47436c7 100644
> > --- a/arch/arm64/include/asm/pgtable.h
> > +++ b/arch/arm64/include/asm/pgtable.h
> > @@ -999,13 +999,16 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
> >   * page after fork() + CoW for pfn mappings. We don't always have a
> >   * hardware-managed access flag on arm64.
> >   */
> > -static inline bool arch_faults_on_old_pte(void)
> > +static inline bool arch_has_hw_pte_young(bool local)
> >  {
> > -	WARN_ON(preemptible());
> > +	if (local) {
> > +		WARN_ON(preemptible());
> > +		return cpu_has_hw_af();
> > +	}
> >  
> > -	return !cpu_has_hw_af();
> > +	return system_has_hw_af();
> >  }
> > -#define arch_faults_on_old_pte		arch_faults_on_old_pte
> > +#define arch_has_hw_pte_young		arch_has_hw_pte_young
> >  
> >  /*
> >   * Experimentally, it's cheap to set the access flag in hardware and we
> > @@ -1013,7 +1016,7 @@ static inline bool arch_faults_on_old_pte(void)
> >   */
> >  static inline bool arch_wants_old_prefaulted_pte(void)
> >  {
> > -	return !arch_faults_on_old_pte();
> > +	return arch_has_hw_pte_young(true);
> >  }
> >  #define arch_wants_old_prefaulted_pte	arch_wants_old_prefaulted_pte
> >  
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 6f3e677d88f1..5bb553ee2c0e 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -2171,6 +2171,25 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> >  		.matches = has_hw_dbm,
> >  		.cpu_enable = cpu_enable_hw_dbm,
> >  	},
> > +	{
> > +		/*
> > +		 * __cpu_setup always enables this capability. But if the boot
> > +		 * CPU has it and a late CPU doesn't, the absent
> > +		 * ARM64_CPUCAP_OPTIONAL_FOR_LATE_CPU will prevent this late CPU
> > +		 * from going online. There is neither known hardware does that
> > +		 * nor obvious reasons to design hardware works that way, hence
> > +		 * no point leaving the door open here. If the need arises, a
> > +		 * new weak system feature flag should do the trick.
> > +		 */
> > +		.desc = "Hardware update of the Access flag",
> > +		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
> > +		.capability = ARM64_HW_AF,
> > +		.sys_reg = SYS_ID_AA64MMFR1_EL1,
> > +		.sign = FTR_UNSIGNED,
> > +		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
> > +		.min_field_value = 1,
> > +		.matches = has_cpuid_feature,
> > +	},
> >  #endif
> >  	{
> >  		.desc = "CRC32 instructions",
> > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > index 870c39537dd0..56e4ef5d95fa 100644
> > --- a/arch/arm64/tools/cpucaps
> > +++ b/arch/arm64/tools/cpucaps
> > @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
> >  HAS_SYSREG_GIC_CPUIF
> >  HAS_TLB_RANGE
> >  HAS_VIRT_HOST_EXTN
> > +HW_AF
> >  HW_DBM
> >  KVM_PROTECTED_MODE
> >  MISMATCHED_CACHE_TYPE
> 
> As discussed in the previous threads, we really don't need the complexity
> of the additional cap for the arm64 part. Please can you just use the
> existing code instead? It's both simpler and, as you say, it's equivalent
> for existing hardware.
> 
> That way, this patch just ends up being a renaming exercise and we're all
> good.

No, renaming alone isn't enough. A caller needs to disable preemption
before calling system_has_hw_af(), and I don't think it's reasonable
to ask this caller to do it on x86 as well.

It seems you really prefer not to have HW_AF. So the best I can
accommodate, considering other potential archs, e.g., risc-v (I do
plan to provide benchmark results on risc-v, btw), is:

  static inline bool arch_has_hw_pte_young(bool local)
  {
	bool hw_af;

  	if (local) {
  		WARN_ON(preemptible());
  		return cpu_has_hw_af();
  	}
  
	preempt_disable();
  	hw_af = system_has_hw_af();
	preempt_enable();

	return hw_af;
  }

Or please give me something else I can call without disabling
preemption, sounds good?


From yuzhao at google.com  Wed Jan  5 13:06:24 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 5 Jan 2022 14:06:24 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220105112527.23399-1-sj@kernel.org>
References: <YdV4k1+zEbtzmUkK@google.com>
 <20220105112527.23399-1-sj@kernel.org>
Message-ID: <YdYIUAC0gopuy8r/@google.com>

On Wed, Jan 05, 2022 at 11:25:27AM +0000, SeongJae Park wrote:
> On Wed, 5 Jan 2022 03:53:07 -0700 Yu Zhao <yuzhao at google.com> wrote:
> 
> > On Wed, Jan 05, 2022 at 08:55:34AM +0000, SeongJae Park wrote:
> > > Hi Yu,
> > > 
> > > On Tue, 4 Jan 2022 13:22:19 -0700 Yu Zhao <yuzhao at google.com> wrote:
> [...]
> > > I think similar works are already available out of the box with the latest
> > > mainline tree, though it might be suboptimal in some cases.
> > 
> > Ok, I will sound harsh because I hate it when people challenge facts
> > while having no idea what they are talking about.
> > 
> > Our jobs are help the leadership make best decisions by providing them
> > with facts, not feeding them crap.
> 
> I was using the word "similar", to represent this is only for a rough concept
> level similarity, rather than detailed facts.  But, seems it was not enough,
> sorry.  Anyway, I will not talk more and thus disturb you having the important
> discussion with leaders here, as you are asking.

First of all, I want to apologize.

I detested what I read, and I still don't like "a rough concept level
similarity" sitting next to a factual statement. But as Borislav has
reminded me, my tone did cross the line. I should have had used an
objective approach to express my (very) different views.

I hope that's all water under the bridge now. And I do plan to carry
on with what I should have had done.


From lkp at intel.com  Wed Jan  5 13:05:55 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 6 Jan 2022 05:05:55 +0800
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220105093552.27542-1-pali@kernel.org>
References: <20220105093552.27542-1-pali@kernel.org>
Message-ID: <202201060511.mczwwaNF-lkp@intel.com>

Hi "Pali,

I love your patch! Yet something to improve:

[auto build test ERROR on helgaas-pci/next]
[also build test ERROR on v5.16-rc8 next-20220105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Pali-Roh-r/PCI-iproc-Set-all-24-bits-of-PCI-class-code/20220105-173704
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
config: arm-randconfig-r001-20220105 (https://download.01.org/0day-ci/archive/20220106/202201060511.mczwwaNF-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d5b6e30ed3acad794dd0aec400e617daffc6cc3d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/8ef1acfb84c08a0331930f9a60884fdd6d7c5e88
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Pali-Roh-r/PCI-iproc-Set-all-24-bits-of-PCI-class-code/20220105-173704
        git checkout 8ef1acfb84c08a0331930f9a60884fdd6d7c5e88
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/pci/controller/pcie-iproc.c:798:11: error: use of undeclared identifier 'PCI_CLASS_BRIDGE_PCI_NORMAL'
           class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
                    ^
   1 error generated.


vim +/PCI_CLASS_BRIDGE_PCI_NORMAL +798 drivers/pci/controller/pcie-iproc.c

   765	
   766	static int iproc_pcie_check_link(struct iproc_pcie *pcie)
   767	{
   768		struct device *dev = pcie->dev;
   769		u32 hdr_type, link_ctrl, link_status, class, val;
   770		bool link_is_active = false;
   771	
   772		/*
   773		 * PAXC connects to emulated endpoint devices directly and does not
   774		 * have a Serdes.  Therefore skip the link detection logic here.
   775		 */
   776		if (pcie->ep_is_internal)
   777			return 0;
   778	
   779		val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS);
   780		if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) {
   781			dev_err(dev, "PHY or data link is INACTIVE!\n");
   782			return -ENODEV;
   783		}
   784	
   785		/* make sure we are not in EP mode */
   786		iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type);
   787		if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) {
   788			dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type);
   789			return -EFAULT;
   790		}
   791	
   792		/* force class to PCI_CLASS_BRIDGE_PCI_NORMAL (0x060400) */
   793	#define PCI_BRIDGE_CTRL_REG_OFFSET	0x43c
   794	#define PCI_BRIDGE_CTRL_REG_CLASS_MASK	0xffffff
   795		iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
   796					    4, &class);
   797		class &= ~PCI_BRIDGE_CTRL_REG_CLASS_MASK;
 > 798		class |= PCI_CLASS_BRIDGE_PCI_NORMAL;
   799		iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET,
   800					     4, class);
   801	
   802		/* check link status to see if link is active */
   803		iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
   804					    2, &link_status);
   805		if (link_status & PCI_EXP_LNKSTA_NLW)
   806			link_is_active = true;
   807	
   808		if (!link_is_active) {
   809			/* try GEN 1 link speed */
   810	#define PCI_TARGET_LINK_SPEED_MASK	0xf
   811	#define PCI_TARGET_LINK_SPEED_GEN2	0x2
   812	#define PCI_TARGET_LINK_SPEED_GEN1	0x1
   813			iproc_pci_raw_config_read32(pcie, 0,
   814						    IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
   815						    4, &link_ctrl);
   816			if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) ==
   817			    PCI_TARGET_LINK_SPEED_GEN2) {
   818				link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK;
   819				link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1;
   820				iproc_pci_raw_config_write32(pcie, 0,
   821						IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2,
   822						4, link_ctrl);
   823				msleep(100);
   824	
   825				iproc_pci_raw_config_read32(pcie, 0,
   826						IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA,
   827						2, &link_status);
   828				if (link_status & PCI_EXP_LNKSTA_NLW)
   829					link_is_active = true;
   830			}
   831		}
   832	
   833		dev_info(dev, "link: %s\n", link_is_active ? "UP" : "DOWN");
   834	
   835		return link_is_active ? 0 : -ENODEV;
   836	}
   837	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From yuzhao at google.com  Wed Jan  5 13:12:33 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 5 Jan 2022 14:12:33 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <CAHk-=whMbX+GUBY=Fyxo3r-XVvfNyFA+4hUJS7UxgYDxf9Wbcw@mail.gmail.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
 <CAHk-=whMbX+GUBY=Fyxo3r-XVvfNyFA+4hUJS7UxgYDxf9Wbcw@mail.gmail.com>
Message-ID: <YdYJwRQ22qgRsS63@google.com>

On Tue, Jan 04, 2022 at 01:43:13PM -0800, Linus Torvalds wrote:
> On Tue, Jan 4, 2022 at 12:30 PM Yu Zhao <yuzhao at google.com> wrote:
> >
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.
> 
> I'll leave this to Andrew. I had some stylistic nits, but all the
> actual complexity is in that aging and eviction, and while I looked at
> the patches, I certainly couldn't make much of a judgement on them.
> 
> The proof is in the numbers, and they look fine, but who knows what
> happens when others test it. I don't see anything that looks worrisome
> per se, I just see the silly small things that made me go "Eww".

I appreciate your time, I'll address all your comments togather with
others' in the next spin, after I hear from Andrew. (I'm assuming he
will have comments too.)


From markyacoub at chromium.org  Wed Jan  5 13:23:27 2022
From: markyacoub at chromium.org (Mark Yacoub)
Date: Wed,  5 Jan 2022 16:23:27 -0500
Subject: [PATCH v3] drm/mediatek: Set default value for Panel Orientation
 connector prop.
In-Reply-To: <20211229184420.793234-1-markyacoub@chromium.org>
References: <20211229184420.793234-1-markyacoub@chromium.org>
Message-ID: <20220105212330.2199045-1-markyacoub@chromium.org>

[Why]
Creating the prop uses UNKNOWN as the initial value, which is not a
supported value if the prop is to be supported.

[How]
Set the panel orientation default value to NORMAL right after creating
the prop if no DSI panel exists.
Panels have their own orientations, and panel orientation can't be
overriden once initialized to a value.

v2:
Move to the latest code where struct mtk_dsi{} has no member 'panel'.
v1:
Set panel orientation only if DSI panel does not exist.

Tested on Jacuzzi(MTK)
Fixes IGT at kms_properties@get_properties-sanity-{atomic,non-atomic}

Signed-off-by: Mark Yacoub <markyacoub at chromium.org>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb00193..9e1d4e297ca48 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -941,8 +941,10 @@ static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.transfer = mtk_dsi_host_transfer,
 };
 
-static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
+static int mtk_dsi_encoder_init(struct device *dev, struct drm_device *drm)
 {
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+	struct drm_panel *panel;
 	int ret;
 
 	ret = drm_simple_encoder_init(drm, &dsi->encoder,
@@ -967,6 +969,15 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
 	}
 	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
 
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel,
+					  &dsi->next_bridge);
+	/* A drm_panel can have its own orientation. If there is no panel, set the
+	 * orientation to NORMAL. */
+	if (ret || !panel) {
+		drm_connector_set_panel_orientation(
+			dsi->connector, DRM_MODE_PANEL_ORIENTATION_NORMAL);
+	}
+
 	return 0;
 
 err_cleanup_encoder:
@@ -976,11 +987,8 @@ static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
 
 static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 {
-	int ret;
 	struct drm_device *drm = data;
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	ret = mtk_dsi_encoder_init(drm, dsi);
+	int ret = mtk_dsi_encoder_init(dev, drm);
 	if (ret)
 		return ret;
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From festevam at gmail.com  Wed Jan  5 13:51:58 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 5 Jan 2022 18:51:58 -0300
Subject: [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never
 came up
In-Reply-To: <1641368602-20401-6-git-send-email-hongxing.zhu@nxp.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
 <1641368602-20401-6-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <CAOMZO5AqgOOo3+r3yQSsfaNxW9eHXhCi=m+mqR=sf=K6dXA8tw@mail.gmail.com>

Hi Richard,

On Wed, Jan 5, 2022 at 5:12 AM Richard Zhu <hongxing.zhu at nxp.com> wrote:
>
> When PCIe PHY link never came up and vpcie regulator is present, there
> would be following dump when try to put the regulator.
> Add a new host_exit() callback for i.MX PCIe driver to disable this
> regulator and fix this dump when link never came up.
>
> The driver should undo any enables it did itself, and not undo any
> enables that anything else did which means it should never be basing
> decisions on regulator_is_enabled().
>
> To keep usage counter balance of the clocks, powers and so on. Do the
> clock disable in the error handling after host_init too.
>
>   imx6q-pcie 33800000.pcie: Phy link never came up
>   imx6q-pcie: probe of 33800000.pcie failed with error -110

Shouldn't we ignore the dw_pcie_wait_for_link() error?

At least, this was the intention of 886a9c134755 ("PCI: dwc: Move link
handling into
common code").

>   ------------[ cut here ]------------
>   WARNING: CPU: 3 PID: 119 at drivers/regulator/core.c:2256 _regulator_put.part.0+0x14c/0x158
>   Modules linked in:

My concern is that this issue is still present in 5.15, which is LTS.

You only address this problem in 5/6 and I am not sure if the previous
patches could be applied to stable as they are cleanups.

How can we fix this for 5.15 stable?

Could you make a minimal fix as the first patch of the series and
cleanup patches later?


From jeremy.linton at arm.com  Wed Jan  5 14:42:01 2022
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Wed, 5 Jan 2022 16:42:01 -0600
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YdSEkt72V1oeVx5E@sirena.org.uk>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
Message-ID: <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>

Hi,

On 1/4/22 11:32, Mark Brown wrote:
> On Thu, Dec 09, 2021 at 11:10:48AM +0000, Szabolcs Nagy wrote:
>> The 12/08/2021 18:23, Catalin Marinas wrote:
>>> On Mon, Nov 15, 2021 at 03:27:10PM +0000, Mark Brown wrote:
> 
>>>> memory is already mapped with PROT_EXEC.  This series resolves this by
>>>> handling the BTI property for both the interpreter and the main
>>>> executable.
> 
>>> Given the silence on this series over the past months, I propose we drop
>>> it. It's a bit unfortunate that systemd's MemoryDenyWriteExecute cannot
>>> work with BTI but I also think the former is a pretty blunt hardening
>>> mechanism (rejecting any mprotect(PROT_EXEC) regardless of the previous
>>> attributes).
> 
>> i still think it would be better if the kernel dealt with
>> PROT_BTI for the exe loaded by the kernel.
> 
> The above message from Catalin isn't quite the full story here - my
> understanding from backchannel is that there's concern from others that
> we might be creating future issues by enabling PROT_BTI, especially in
> the case where the same permissions issue prevents the dynamic linker
> disabling PROT_BTI.  They'd therefore rather stick with the status quo
> and not create any new ABI.  Unfortunately that's not something people
> have been willing to say on the list, hopefully the above captures the
> thinking well enough.
> 
> Personally I'm a bit ambivalent on this, I do see the potential issue
> but I'm having trouble constructing an actual scenario and my instinct
> is that since we handle PROT_EXEC we should also handle PROT_BTI for
> consistency.
> 

I'm hardly a security expert, but it seems to me that BTI hardens 
against a wider set of possible exploits than MDWE. Yet, we are silently 
turning it off for systemd services which are considered some of the 
most security critical things in the machine right now (ex:logind, etc). 
So despite 'systemd-analyze secuirty` flagging those services as the 
most secure ones on a system, they might actually be less secure.

It also seems that getting BTI turned on earlier, as this patch is doing 
is itself a win.

So, mentally i'm having a hard time balancing the hypothetical problem 
laid out, as it should only really exist in an environment similar to 
the MDWE one, since AFAIK, its possible today to just flip it back off 
unless MDWE stops that from happening.

What are the the remaining alternatives? A new syscall? But that is by 
definition a new ABI, and wouldn't benefit from having BTI turned on as 
early as this patch is doing. Should we disable MDWE on a BTI machine? 
I'm not sure that is a good look, particularly if MDWE happens to 
successfully stop some exploit. AFAIK, MDWE+BTI are a good strong 
combination, it seems a shame if we can't get them both working together.

I hesitate to suggest it, but maybe this patch should be conditional 
somehow, that way !systemd/MDWE machines can behave as they do today, 
and systemd/MDWE machines can request BTI be turned on by the kernel 
automatically?




From ilkka at os.amperecomputing.com  Wed Jan  5 15:46:38 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Wed, 5 Jan 2022 15:46:38 -0800 (PST)
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <20220105104602.GA4752@lpieralisi>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <20220105104602.GA4752@lpieralisi>
Message-ID: <alpine.DEB.2.22.394.2201051530290.2489@ubuntu200401>


Hi Lorenzo,

On Wed, 5 Jan 2022, Lorenzo Pieralisi wrote:
> [+James, for SDEI bits]
>
> On Thu, Dec 30, 2021 at 07:37:25PM -0800, Ilkka Koskinen wrote:
>> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
>> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
>> issue diagnostic dump and reset via an SDEI event or an interrupt.
>> This patch implements SDEI path.
>>
>> [0] https://developer.arm.com/documentation/den0093/latest/
>>
>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>> ---
>>  drivers/acpi/arm64/Kconfig  |   8 +++
>>  drivers/acpi/arm64/Makefile |   1 +
>>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>>  3 files changed, 134 insertions(+)
>>  create mode 100644 drivers/acpi/arm64/agdi.c
>>
>> diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
>> index 6dba187f4f2e..24869ba5b365 100644
>> --- a/drivers/acpi/arm64/Kconfig
>> +++ b/drivers/acpi/arm64/Kconfig
>> @@ -8,3 +8,11 @@ config ACPI_IORT
>>
>>  config ACPI_GTDT
>>  	bool
>> +
>> +config ACPI_AGDI
>> +	bool "Arm Generic Diagnostic Dump and Reset Device Interface"
>> +	depends on ARM_SDE_INTERFACE
>> +	help
>> +	  Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
>> +	  a standard that enables issuing a non-maskable diagnostic dump and
>> +	  reset command.
>> diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
>> index 66acbe77f46e..7b9e4045659d 100644
>> --- a/drivers/acpi/arm64/Makefile
>> +++ b/drivers/acpi/arm64/Makefile
>> @@ -1,4 +1,5 @@
>>  # SPDX-License-Identifier: GPL-2.0-only
>> +obj-$(CONFIG_ACPI_AGDI) 	+= agdi.o
>>  obj-$(CONFIG_ACPI_IORT) 	+= iort.o
>>  obj-$(CONFIG_ACPI_GTDT) 	+= gtdt.o
>>  obj-y				+= dma.o
>> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
>> new file mode 100644
>> index 000000000000..6525ccbae5c1
>> --- /dev/null
>> +++ b/drivers/acpi/arm64/agdi.c
>> @@ -0,0 +1,125 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * This file implements handling of
>> + * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
>> + *
>> + * Copyright (c) 2021, Ampere Computing LLC
>> + */
>> +
>> +#define pr_fmt(fmt) "ACPI: AGDI: " fmt
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/slab.h>
>> +#include <linux/module.h>
>> +#include <linux/kernel.h>
>> +#include <linux/acpi.h>
>> +#include <linux/arm_sdei.h>
>> +#include <linux/io.h>
>
> Nit: alphabetical order.

I clean them

>
>> +
>> +struct agdi_data {
>> +	int sdei_event;
>> +};
>> +
>> +static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
>> +{
>> +	nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
>> +	return 0;
>> +}
>> +
>> +static int agdi_sdei_probe(struct platform_device *pdev,
>> +			   struct agdi_data *adata)
>> +{
>> +	int err;
>> +
>> +	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
>> +	if (err) {
>> +		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
>> +			adata->sdei_event);
>> +		return err;
>> +	}
>> +
>> +	err = sdei_event_enable(adata->sdei_event);
>> +	if (err)  {
>> +		sdei_event_unregister(adata->sdei_event);
>> +		dev_err(&pdev->dev, "Failed to enable event %d\n",
>> +			adata->sdei_event);
>> +		return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int agdi_probe(struct platform_device *pdev)
>> +{
>> +	struct agdi_data *adata;
>> +
>> +	adata = dev_get_platdata(&pdev->dev);
>> +	if (!adata)
>> +		return -EINVAL;
>> +
>> +	return agdi_sdei_probe(pdev, adata);
>> +}
>> +
>> +static int agdi_remove(struct platform_device *pdev)
>> +{
>> +	struct agdi_data *adata = platform_get_drvdata(pdev);
>> +
>> +	sdei_event_disable(adata->sdei_event);
>> +	sdei_event_unregister(adata->sdei_event);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver agdi_driver = {
>> +	.driver = {
>> +		.name = "agdi",
>> +	},
>> +	.probe = agdi_probe,
>> +	.remove = agdi_remove,
>> +};
>
> May I ask why we need a platform device (and driver) to register
> an SDEI event ?

Well, I guess I thought to have a device/driver to handle SDEI events and 
interrupts since the spec calls it a device. I can certainly remove those, 
if that's preferred.

>
>> +static int __init agdi_init(void)
>> +{
>> +	int ret;
>> +	acpi_status status;
>> +	struct acpi_table_agdi *agdi_table;
>> +	struct agdi_data pdata;
>> +	struct platform_device *pdev;
>> +
>> +	if (acpi_disabled)
>> +		return 0;
>
> Why don't we call agdi_init() from acpi_init() as we do for IORT/VIOT ?
>
> I don't think it is necessary to add a device_initcall(), with related
> ordering dependencies.

That's a good point. I change it.

>
>> +
>> +	status = acpi_get_table(ACPI_SIG_AGDI, 0,
>> +				(struct acpi_table_header **) &agdi_table);
>> +	if (ACPI_FAILURE(status))
>> +		return -ENODEV;
>> +
>> +	if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
>
> Is this because specs need updating ?

Yes, that's the reason. AGDI table is missing flags that would define 
trigger type and polarity.

>
>> +		pr_warn("Interrupt signaling is not supported");
>> +		ret = -ENODEV;
>> +		goto err_put_table;
>> +	}
>> +
>> +	pdata.sdei_event = agdi_table->sdei_event;
>> +
>> +	pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
>> +	if (IS_ERR(pdev)) {
>> +		ret = PTR_ERR(pdev);
>> +		goto err_put_table;
>> +	}
>> +
>> +	ret = platform_driver_register(&agdi_driver);
>> +	if (ret)
>> +		goto err_device_unregister;
>> +
>> +	acpi_put_table((struct acpi_table_header *)agdi_table);
>> +	return 0;
>> +
>> +err_device_unregister:
>> +	platform_device_unregister(pdev);
>> +err_put_table:
>> +	acpi_put_table((struct acpi_table_header *)agdi_table);
>> +	return ret;
>> +}
>> +device_initcall(agdi_init);
>
> See above.
>
> Thanks,
> Lorenzo
>

Cheers, Ilkka



From sboyd at kernel.org  Wed Jan  5 15:51:56 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 15:51:56 -0800
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220103233948.198119-6-Mr.Bossman075@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
Message-ID: <20220105235157.8ED80C36AEB@smtp.kernel.org>

Quoting Jesse Taube (2022-01-03 15:39:46)
> Add clock driver support for i.MXRT1050.
> 
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>

What is suggested by for a new driver?

> ---
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -105,3 +105,8 @@ config CLK_IMX8ULP
>         select MXC_CLK
>         help
>             Build the driver for i.MX8ULP CCM Clock Driver
> +
> +config CLK_IMXRT1050
> +       bool "IMXRT1050 CCM Clock Driver"
> +       depends on SOC_IMXRT
> +       select MXC_CLK

Please add some help text here.

> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index b5e040026dfb..3d9a1e3b5fc6 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -47,3 +47,4 @@ obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
>  obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
>  obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
>  obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
> +obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o

Please keep this sorted, maybe on config symbol name? 

> diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
> new file mode 100644
> index 000000000000..a2f0e8663030
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imxrt1050.c
> @@ -0,0 +1,181 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright (C) 2021
> + * Author(s):
> + * Jesse Taube <Mr.Bossman075 at gmail.com>
> + * Giulio Benetti <giulio.benetti at benettiengineering.com>
> + */
> +#include <linux/mm.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>

Is this include used?

> +#include <linux/io.h>
> +#include <linux/clkdev.h>

Drop unused includes.

> +#include <linux/clk-provider.h>
> +#include <linux/err.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>

Used?

> +#include <linux/sizes.h>
> +#include <linux/platform_device.h>
> +#include <soc/imx/revision.h>

Is this used?

> +#include <dt-bindings/clock/imxrt1050-clock.h>
> +
> +#include "clk.h"
> +
> +static const char * const pll_ref_sels[] = {"osc", "dummy", };
> +static const char * const per_sels[] = {"ipg_pdof", "osc", };
> +static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
> +static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
> +static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
> +static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
> +static const char *const pre_periph_sels[] = {
> +       "pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
> +static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
> +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
> +static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
> +static const char *const lcdif_sels[] = {
> +       "pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
> +       "pll2_pfd1_594m", "pll3_pfd1_664_62m", };
> +static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
> +static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };

Any chance this can use clk_parent_data instead of string names for
parents?

> +
> +static struct clk_hw **hws;
> +static struct clk_hw_onecell_data *clk_hw_data;
> +
> +static void __init imxrt_clocks_common_init(void __iomem *base)

Drop __init and preferably inline this to the callsite.

> +{
> +       /* Anatop clocks */
> +       hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
> +
> +       hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
> +               base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +       hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
> +               base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +       hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
> +               base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +       hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
> +               base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +
> +       hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
> +               "pll1_arm_ref_sel", base + 0x0, 0x7f);
> +       hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
> +               "pll2_sys_ref_sel", base + 0x30, 0x1);
> +       hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
> +               "pll3_usb_otg_ref_sel", base + 0x10, 0x1);
> +       hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
> +               "pll5_video_ref_sel", base + 0xa0, 0x7f);
> +
> +       /* PLL bypass out */
> +       hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x0, 16, 1,
> +               pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
> +       hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1,
> +               pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
> +       hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1,
> +               pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
> +       hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1,
> +               pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
> +
> +       hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
> +               "pll5_video", base + 0xa0, 19, 2);
> +       hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
> +               "video_post_div_sel", base + 0x170, 30, 2);
> +
> +       hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
> +
> +       hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", base + 0x100, 0);
> +       hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", base + 0x100, 1);
> +       hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", base + 0x100, 2);
> +       hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", base + 0xf0, 1);
> +       hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", base + 0xf0, 3);
> +}
> +
> +static int imxrt1050_clocks_probe(struct platform_device *pdev)
> +{
> +       void __iomem *ccm_base;
> +       void __iomem *pll_base;
> +       struct device *dev = &pdev->dev;
> +       struct device_node *np = dev->of_node;
> +       struct device_node *anp;
> +       int ret;
> +
> +       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
> +                                         IMXRT1050_CLK_END), GFP_KERNEL);
> +       if (WARN_ON(!clk_hw_data))
> +               return -ENOMEM;
> +
> +       clk_hw_data->num = IMXRT1050_CLK_END;
> +       hws = clk_hw_data->hws;
> +
> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));

Use clk_parent_data instead and reference the binding name with .fw_name

> +
> +       anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
> +       pll_base = of_iomap(anp, 0);
> +       of_node_put(anp);
> +       if (WARN_ON(!pll_base))
> +               return -ENOMEM;
> +       imxrt_clocks_common_init(pll_base);
> +       /* CCM clocks */
> +       ccm_base = devm_platform_ioremap_resource(pdev, 0);
> +       if (WARN_ON(IS_ERR(ccm_base)))
> +               return PTR_ERR(ccm_base);
> +
> +       hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
> +       hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
> +               pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
> +       hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
> +               periph_sels, ARRAY_SIZE(periph_sels));
> +       hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
> +               usdhc_sels, ARRAY_SIZE(usdhc_sels));
> +       hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
> +               usdhc_sels, ARRAY_SIZE(usdhc_sels));
> +       hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
> +               lpuart_sels, ARRAY_SIZE(lpuart_sels));
> +       hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
> +               lcdif_sels, ARRAY_SIZE(lcdif_sels));
> +       hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
> +               per_sels, ARRAY_SIZE(per_sels));
> +       hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
> +               semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
> +       hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
> +               semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
> +
> +       hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
> +       hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
> +       hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
> +
> +       hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
> +       hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
> +       hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
> +       hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
> +       hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
> +
> +       hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
> +       hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
> +       hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
> +       hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
> +       hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
> +       hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
> +       imx_check_clk_hws(hws, IMXRT1050_CLK_END);
> +
> +       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
> +       if (ret < 0) {
> +               dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
> +               imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
> +               return ret;

Drop return

> +       }

Newline here please

> +       return 0;

return ret;

> +}
> +static const struct of_device_id imxrt1050_clk_of_match[] = {
> +       { .compatible = "fsl,imxrt1050-ccm" },
> +       { /* Sentinel */ },

Drop comma please so nothing can come after without causing compile fail.

> +};
> +MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
> +
> +static struct platform_driver imxrt1050_clk_driver = {
> +       .probe = imxrt1050_clocks_probe,
> +       .driver = {
> +               .name = "imxrt1050-ccm",
> +               .of_match_table = imxrt1050_clk_of_match,
> +       },
> +};
> +module_platform_driver(imxrt1050_clk_driver);

It's not a module though, unless the Kconfig is made into a tristate.


From contact at emersion.fr  Wed Jan  5 15:54:43 2022
From: contact at emersion.fr (Simon Ser)
Date: Wed, 05 Jan 2022 23:54:43 +0000
Subject: [PATCH v3 2/6] drm/plane: Fix typo in format_mod_supported
 documentation
In-Reply-To: <20211226112503.31771-3-jose.exposito89@gmail.com>
References: <20211226112503.31771-1-jose.exposito89@gmail.com>
 <20211226112503.31771-3-jose.exposito89@gmail.com>
Message-ID: <3DdB6YPUQr4O063yNreefZcIm6p5Z6HORoVVbk5RTMmjz8qvnxMse42hLvfDmA323KG-TWLc_JUFZEEEIkoINXQuAzjLVe2jRRM01tQgYOU=@emersion.fr>

Pushed patches 1 & 2 to drm-misc-next. Thanks for your contribution!


From madvenka at linux.microsoft.com  Wed Jan  5 15:58:59 2022
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Wed, 5 Jan 2022 17:58:59 -0600
Subject: [PATCH v12 07/10] arm64: Introduce stack trace reliability checks
 in the unwinder
In-Reply-To: <YdXOQTXscVaVFMJ3@sirena.org.uk>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-8-madvenka@linux.microsoft.com>
 <YdXOQTXscVaVFMJ3@sirena.org.uk>
Message-ID: <85156eb8-df63-29c0-cbfc-37bc0356d9e8@linux.microsoft.com>

Thanks for the review. Do you have any comments on:

[PATCH v12 04/10] arm64: Split unwind_init()
[PATCH v12 10/10] arm64: Select HAVE_RELIABLE_STACKTRACE

Madhavan

On 1/5/22 10:58 AM, Mark Brown wrote:
> On Mon, Jan 03, 2022 at 10:52:09AM -0600, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> There are some kernel features and conditions that make a stack trace
>> unreliable. Callers may require the unwinder to detect these cases.
>> E.g., livepatch.
> 
> Reviwed-by: Mark Brown <broonie at kernel.org>
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From sboyd at kernel.org  Wed Jan  5 16:36:48 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 16:36:48 -0800
Subject: [PATCH v7 05/10] dt-bindings: clock: Add bindings for SP7021
 clock driver
In-Reply-To: <504303c7cf92af8368dcda0cdde3b9c15a833418.1640154492.git.qinjian@cqplus1.com>
References: <cover.1640154492.git.qinjian@cqplus1.com>
 <504303c7cf92af8368dcda0cdde3b9c15a833418.1640154492.git.qinjian@cqplus1.com>
Message-ID: <20220106003649.7FA94C36AEB@smtp.kernel.org>

Quoting Qin Jian (2021-12-21 23:06:01)
> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian at cqplus1.com>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Wed Jan  5 16:42:48 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 16:42:48 -0800
Subject: [PATCH v7 06/10] clk: Add Sunplus SP7021 clock driver
In-Reply-To: <7f8302e2c1d02141dd69d2524eaa857d6494fdc7.1640154492.git.qinjian@cqplus1.com>
References: <cover.1640154492.git.qinjian@cqplus1.com>
 <7f8302e2c1d02141dd69d2524eaa857d6494fdc7.1640154492.git.qinjian@cqplus1.com>
Message-ID: <20220106004249.90484C36AEB@smtp.kernel.org>

Quoting Qin Jian (2021-12-21 23:06:02)
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc973..4a186ccf6 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -334,6 +334,15 @@ config COMMON_CLK_VC5
>           This driver supports the IDT VersaClock 5 and VersaClock 6
>           programmable clock generators.
>  
> +config COMMON_CLK_SP7021
> +       bool "Clock driver for Sunplus SP7021 SoC"
> +       default SOC_SP7021
> +       help
> +         This driver supports the Sunplus SP7021 SoC clocks.
> +         It implements SP7021 PLLs/gate.
> +         Not all features of the PLL are currently supported
> +         by the driver.
> +
>  config COMMON_CLK_STM32MP157
>         def_bool COMMON_CLK && MACH_STM32MP157
>         help
> @@ -366,7 +375,6 @@ config COMMON_CLK_MMP2
>  
>  config COMMON_CLK_MMP2_AUDIO
>          tristate "Clock driver for MMP2 Audio subsystem"
> -        depends on COMMON_CLK_MMP2 || COMPILE_TEST
>          help
>            This driver supports clocks for Audio subsystem on MMP2 SoC.
>  

What's the relevance of this hunk to this patch? Can you drop this part?

> diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
> new file mode 100644
> index 000000000..6df87f0a6
> --- /dev/null
> +++ b/drivers/clk/clk-sp7021.c
> @@ -0,0 +1,705 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Copyright (C) Sunplus Technology Co., Ltd.
> + *       All rights reserved.
> + */
> +//#define DEBUG
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/bitfield.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <dt-bindings/clock/sp-sp7021.h>
> +
> +#define REG(i)         (pll_regs + (i) * 4)
> +
[....]
> +
> +static long plltv_div(struct sp_pll *clk, unsigned long freq)
> +{
> +       if (freq % 100)
> +               return plltv_fractional_div(clk, freq);
> +       else
> +               return plltv_integer_div(clk, freq);

Drop else please

> +}
> +
> +static void plltv_set_rate(struct sp_pll *clk)
> +{
> +       u32 reg;
> +
> +       reg  = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
> +       reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
> +       reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
> +       reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
> +       writel(reg, clk->reg);
> +
> +       reg  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
[...]
> +       .set_rate = sp_pll_set_rate
> +};
> +
> +static const struct clk_ops sp_pll_sub_ops = {
> +       .enable = sp_pll_enable,
> +       .disable = sp_pll_disable,
> +       .is_enabled = sp_pll_is_enabled,
> +       .recalc_rate = sp_pll_recalc_rate,
> +};
> +
> +struct clk_hw *sp_pll_register(const char *name, const char *parent,
> +                              void __iomem *reg, int pd_bit, int bp_bit,
> +                              unsigned long brate, int shift, int width,
> +                              spinlock_t *lock)
> +{
> +       struct sp_pll *pll;
> +       struct clk_hw *hw;
> +       struct clk_init_data initd = {
> +               .name = name,
> +               .parent_names = &parent,

Any chance clk_parent_data can be used instead of string names?

> +               .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
> +               .num_parents = 1,
> +       };
> +       int ret;
> +
> +       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +       if (!pll)
> +               return ERR_PTR(-ENOMEM);
> +
> +       if (reg == PLLSYS_CTL) /* system clock, should not be closed */

s/closed/disabled/

> +               initd.flags |= CLK_IS_CRITICAL;
> +
> +       pll->hw.init = &initd;
> +       pll->reg = reg;
> +       pll->pd_bit = pd_bit;
> +       pll->bp_bit = bp_bit;
> +       pll->brate = brate;
> +       pll->div_shift = shift;
> +       pll->div_width = width;
> +       pll->lock = lock;
> +
> +       hw = &pll->hw;
> +       ret = clk_hw_register(NULL, hw);
> +       if (ret) {
> +               kfree(pll);
> +               hw = ERR_PTR(ret);
> +       } else {
> +               pr_info("%-20s%lu\n", name, clk_hw_get_rate(hw));

Drop this print or make it pr_debug()

> +               clk_hw_register_clkdev(hw, NULL, name);
> +       }
> +
> +       return hw;
> +}
> +
> +static void __init sp_clk_setup(struct device_node *np)
> +{
> +       int i, j;
> +       struct clk_hw **hws;
> +
> +       sp_clk_base = of_iomap(np, 0);
> +       if (WARN_ON(!sp_clk_base))
> +               return; /* -ENXIO */
> +
> +       sp_clk_data = kzalloc(struct_size(sp_clk_data, hws, CLK_MAX), GFP_KERNEL);
> +       if (!sp_clk_data)
> +               return; /* -ENOMEM */
> +
> +       hws = sp_clk_data->hws;
> +
> +       /* PLL_A */
> +       hws[PLL_A] = sp_pll_register("plla", EXTCLK, PLLA_CTL, 11, 12,
> +                                    27000000, 0, DIV_A, &plla_lock);
> +
> +       /* PLL_E */
> +       hws[PLL_E] = sp_pll_register("plle", EXTCLK, PLLE_CTL, 6, 2,
> +                                    50000000, 0, 0, &plle_lock);
> +       hws[PLL_E_2P5] = sp_pll_register("plle_2p5", "plle", PLLE_CTL, 13, -1,
> +                                        2500000, 0, 0, &plle_lock);
> +       hws[PLL_E_25] = sp_pll_register("plle_25", "plle", PLLE_CTL, 12, -1,
> +                                       25000000, 0, 0, &plle_lock);
> +       hws[PLL_E_112P5] = sp_pll_register("plle_112p5", "plle", PLLE_CTL, 11, -1,
> +                                          112500000, 0, 0, &plle_lock);
> +
> +       /* PLL_F */
> +       hws[PLL_F] = sp_pll_register("pllf", EXTCLK, PLLF_CTL, 0, 10,
> +                                    13500000, 1, 4, &pllf_lock);
> +
> +       /* PLL_TV */
> +       hws[PLL_TV] = sp_pll_register("plltv", EXTCLK, PLLTV_CTL, 0, 15,
> +                                     27000000, 0, DIV_TV, &plltv_lock);
> +       hws[PLL_TV_A] = clk_hw_register_divider(NULL, "plltv_a", "plltv", 0,
> +                                               PLLTV_CTL + 4, 5, 1,
> +                                               CLK_DIVIDER_POWER_OF_TWO,
> +                                               &plltv_lock);
> +       clk_hw_register_clkdev(hws[PLL_TV_A], NULL, "plltv_a");
> +
> +       /* PLL_SYS */
> +       hws[PLL_SYS] = sp_pll_register("pllsys", EXTCLK, PLLSYS_CTL, 10, 9,
> +                                      13500000, 0, 4, &pllsys_lock);
> +
> +       /* gates */
> +       for (i = 0; i < ARRAY_SIZE(gates); i++) {
> +               char s[10];
> +
> +               j = gates[i] & 0xffff;
> +               sprintf(s, "clken%02x", j);
> +               hws[j] = clk_hw_register_gate(NULL, s,
> +                                             parents[gates[i] >> 16].fw_name,
> +                                             CLK_IGNORE_UNUSED,

Why CLK_IGNORE_UNUSED? There should be a comment or it should be
replaced with CLK_IS_CRITICAL.

> +                                             clk_regs + (j >> 4) * 4, j & 0x0f,
> +                                             CLK_GATE_HIWORD_MASK, NULL);
> +       }
> +
> +       sp_clk_data->num = CLK_MAX;
> +       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, sp_clk_data);
> +}
> +
> +CLK_OF_DECLARE_DRIVER(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);

Why CLK_OF_DECLARE_DRIVER? There should be a comment but better would be
to make a platform driver instead. If the platform driver can't be used,
we need to know what other device driver is probing based on this clkc
compatible string.


From sboyd at kernel.org  Wed Jan  5 17:14:19 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:14:19 -0800
Subject: [PATCH v5 1/4] dt-bindings: clock: Add DT bindings for PLL of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <20211025031038.4180686-2-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20211025031038.4180686-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20211025031038.4180686-2-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20220106011420.5B5AFC36AEB@smtp.kernel.org>

Quoting Nobuhiro Iwamatsu (2021-10-24 20:10:35)
> Add device tree bindings for PLL of Toshiba Visconti TMPV770x SoC series.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> Reviewed-by: Rob Herring <robh at kernel.org>
> 
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:14:24 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:14:24 -0800
Subject: [PATCH v5 2/4] dt-bindings: clock: Add DT bindings for SMU of
 Toshiba Visconti TMPV770x SoC
In-Reply-To: <20211025031038.4180686-3-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20211025031038.4180686-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20211025031038.4180686-3-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20220106011425.CA762C36AFE@smtp.kernel.org>

Quoting Nobuhiro Iwamatsu (2021-10-24 20:10:36)
> Add device tree bindings for SMU (System Management Unit) controller of
> Toshiba Visconti TMPV770x SoC series.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> Reviewed-by: Rob Herring <robh at kernel.org>
> 
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:14:30 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:14:30 -0800
Subject: [PATCH v5 3/4] clk: visconti: Add support common clock driver and
 reset driver
In-Reply-To: <20211025031038.4180686-4-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20211025031038.4180686-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20211025031038.4180686-4-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20220106011431.4BACAC36AEB@smtp.kernel.org>

Quoting Nobuhiro Iwamatsu (2021-10-24 20:10:37)
> Add support for common interface of the common clock and reset driver
> for Toshiba Visconti5 and its SoC, TMPV7708. The PIPLLCT provides the PLL,
> and the PISMU provides clock and reset functionality.
> Each drivers are provided in this patch.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> 
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:14:36 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:14:36 -0800
Subject: [PATCH v5 4/4] MAINTAINERS: Add entries for Toshiba Visconti PLL
 and clock controller
In-Reply-To: <20211025031038.4180686-5-nobuhiro1.iwamatsu@toshiba.co.jp>
References: <20211025031038.4180686-1-nobuhiro1.iwamatsu@toshiba.co.jp>
 <20211025031038.4180686-5-nobuhiro1.iwamatsu@toshiba.co.jp>
Message-ID: <20220106011437.2CAFDC36AEB@smtp.kernel.org>

Quoting Nobuhiro Iwamatsu (2021-10-24 20:10:38)
> Add entries for Toshiba Visconti PLL and clock controller binding and
> driver.
> 
> Signed-off-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:21:58 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:21:58 -0800
Subject: [PATCH v2 1/2] clk: st: clkgen-fsyn: search reg within node or
 parent
In-Reply-To: <20211218211157.188214-2-avolmat@me.com>
References: <20211218211157.188214-1-avolmat@me.com>
 <20211218211157.188214-2-avolmat@me.com>
Message-ID: <20220106012159.6418EC36AE3@smtp.kernel.org>

Quoting Alain Volmat (2021-12-18 13:11:56)
> In order to avoid having duplicated addresses within the DT,
> only have one unit-address per clockgen and each driver within
> the clockgen should look at the parent node (overall clockgen)
> to figure out the reg property.  Such behavior is already in
> place in other STi platform clock drivers such as clk-flexgen
> and clkgen-pll.  Keep backward compatibility by first looking
> at reg within the node before looking into the parent node.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:22:05 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:22:05 -0800
Subject: [PATCH v2 2/2] clk: st: clkgen-mux: search reg within node or
 parent
In-Reply-To: <20211218211157.188214-3-avolmat@me.com>
References: <20211218211157.188214-1-avolmat@me.com>
 <20211218211157.188214-3-avolmat@me.com>
Message-ID: <20220106012206.A2B6CC36AEB@smtp.kernel.org>

Quoting Alain Volmat (2021-12-18 13:11:57)
> In order to avoid having duplicated addresses within the DT,
> only have one unit-address per clockgen and each driver within
> the clockgen should look at the parent node (overall clockgen)
> to figure out the reg property.  Such behavior is already in
> place in other STi platform clock drivers such as clk-flexgen
> and clkgen-pll.  Keep backward compatibility by first looking
> at reg within the node before looking into the parent node.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Wed Jan  5 17:29:54 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:29:54 -0800
Subject: [PATCH v7 07/14] clk: en7523: Add clock driver for Airoha EN7523
 SoC
In-Reply-To: <20211217112345.14029-8-nbd@nbd.name>
References: <20211217112345.14029-1-nbd@nbd.name>
 <20211217112345.14029-8-nbd@nbd.name>
Message-ID: <20220106012955.69302C36AE9@smtp.kernel.org>

Quoting Felix Fietkau (2021-12-17 03:23:37)
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc97396a..c973ac1a4890 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -192,6 +192,15 @@ config COMMON_CLK_CS2000_CP
>         help
>           If you say yes here you get support for the CS2000 clock multiplier.
>  
> +config COMMON_CLK_EN7523
> +       bool "Clock driver for Airoha EN7523 SoC system clocks"
> +       depends on OF

What depends on OF?

> +       depends on ARCH_AIROHA || COMPILE_TEST
> +       default ARCH_AIROHA
> +       help
> +         This driver provides the fixed clocks and gates present on Airoha
> +         ARM silicon.
> +
>  config COMMON_CLK_FSL_FLEXSPI
>         tristate "Clock driver for FlexSPI on Layerscape SoCs"
>         depends on ARCH_LAYERSCAPE || COMPILE_TEST
> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
> diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
> new file mode 100644
> index 000000000000..828c35da0968
> --- /dev/null
> +++ b/drivers/clk/clk-en7523.c
> @@ -0,0 +1,350 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include <linux/regmap.h>

Is this include used? Please remove unused includes.

> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/en7523-clk.h>
> +
> +#define REG_PCI_CONTROL                        0x88
> +#define   REG_PCI_CONTROL_PERSTOUT     BIT(29)
> +#define   REG_PCI_CONTROL_PERSTOUT1    BIT(26)
> +#define   REG_PCI_CONTROL_REFCLK_EN1   BIT(22)
> +#define REG_GSW_CLK_DIV_SEL            0x1b4
> +#define REG_EMI_CLK_DIV_SEL            0x1b8
> +#define REG_BUS_CLK_DIV_SEL            0x1bc
> +#define REG_SPI_CLK_DIV_SEL            0x1c4
> +#define REG_SPI_CLK_FREQ_SEL           0x1c8
> +#define REG_NPU_CLK_DIV_SEL            0x1fc
> +#define REG_CRYPTO_CLKSRC              0x200
> +#define REG_RESET_CONTROL              0x834
> +#define   REG_RESET_CONTROL_PCIEHB     BIT(29)
> +#define   REG_RESET_CONTROL_PCIE1      BIT(27)
> +#define   REG_RESET_CONTROL_PCIE2      BIT(26)
> +
> +struct en_clk_desc {
> +       int id;
> +       const char *name;
> +       u32 base_reg;
> +       u32 base_bits;
> +       u32 base_shift;
> +       union {
> +               const u32 *base_values;
> +               u32 base_value;
> +       };
> +       int n_base_values;
> +
> +       u32 div_reg;
> +       u32 div_bits;
> +       u32 div_shift;
> +       u32 div_val0;
> +       u32 div_step;
> +};
> +
> +struct en_clk_gate {
> +       void __iomem *base;
> +       struct clk_hw hw;
> +};
> +
> +static const u32 gsw_base[] = { 400000000, 500000000 };
> +static const u32 emi_base[] = { 333000000, 400000000 };
> +static const u32 bus_base[] = { 500000000, 540000000 };
> +static const u32 slic_base[] = { 100000000, 3125000 };
> +static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
> +
> +static const struct en_clk_desc en7523_base_clks[] = {
> +       {
> +               .id = EN7523_CLK_GSW,
> +               .name = "gsw",
> +
> +               .base_reg = REG_GSW_CLK_DIV_SEL,
> +               .base_bits = 1,
> +               .base_shift = 8,
> +               .base_values = gsw_base,
> +               .n_base_values = ARRAY_SIZE(gsw_base),
> +
> +               .div_bits = 3,
> +               .div_shift = 0,
> +               .div_step = 1,
> +       }, {
> +               .id = EN7523_CLK_EMI,
> +               .name = "emi",
> +
> +               .base_reg = REG_EMI_CLK_DIV_SEL,
> +               .base_bits = 1,
> +               .base_shift = 8,
> +               .base_values = emi_base,
> +               .n_base_values = ARRAY_SIZE(emi_base),
> +
> +               .div_bits = 3,
> +               .div_shift = 0,
> +               .div_step = 1,
> +       }, {
> +               .id = EN7523_CLK_BUS,
> +               .name = "bus",
> +
> +               .base_reg = REG_BUS_CLK_DIV_SEL,
> +               .base_bits = 1,
> +               .base_shift = 8,
> +               .base_values = bus_base,
> +               .n_base_values = ARRAY_SIZE(bus_base),
> +
> +               .div_bits = 3,
> +               .div_shift = 0,
> +               .div_step = 1,
> +       }, {
> +               .id = EN7523_CLK_SLIC,
> +               .name = "slic",
> +
> +               .base_reg = REG_SPI_CLK_FREQ_SEL,
> +               .base_bits = 1,
> +               .base_shift = 0,
> +               .base_values = slic_base,
> +               .n_base_values = ARRAY_SIZE(slic_base),
> +
> +               .div_reg = REG_SPI_CLK_DIV_SEL,
> +               .div_bits = 5,
> +               .div_shift = 24,
> +               .div_val0 = 20,
> +               .div_step = 2,
> +       }, {
> +               .id = EN7523_CLK_SPI,
> +               .name = "spi",
> +
> +               .base_reg = REG_SPI_CLK_DIV_SEL,
> +
> +               .base_value = 400000000,
> +
> +               .div_bits = 5,
> +               .div_shift = 8,
> +               .div_val0 = 40,
> +               .div_step = 2,
> +       }, {
> +               .id = EN7523_CLK_NPU,
> +               .name = "npu",
> +
> +               .base_reg = REG_NPU_CLK_DIV_SEL,
> +               .base_bits = 2,
> +               .base_shift = 8,
> +               .base_values = npu_base,
> +               .n_base_values = ARRAY_SIZE(npu_base),
> +
> +               .div_bits = 3,
> +               .div_shift = 0,
> +               .div_step = 1,
> +       }, {
> +               .id = EN7523_CLK_CRYPTO,
> +               .name = "crypto",
> +
> +               .base_reg = REG_CRYPTO_CLKSRC,
> +               .base_bits = 1,
> +               .base_shift = 8,
> +               .base_values = emi_base,
> +               .n_base_values = ARRAY_SIZE(emi_base),
> +       }
> +};
> +
> +static const struct of_device_id of_match_clk_en7523[] = {

Please move this down near the driver struct that uses it.

> +       { .compatible = "airoha,en7523-scu", },
> +       { /* sentinel */ }
> +};
> +
> +static u32 en7523_get_base_rate(void __iomem *base, int i)
> +{
> +       const struct en_clk_desc *desc = &en7523_base_clks[i];
> +       u32 val;
> +
> +       if (!desc->base_bits)
> +               return desc->base_value;
> +
> +       val = readl(base + desc->base_reg);
> +       val >>= desc->base_shift;
> +       val &= (1 << desc->base_bits) - 1;
> +
> +       if (val >= desc->n_base_values)
> +               return 0;
> +
> +       return desc->base_values[val];
> +}
> +
> +static u32 en7523_get_div(void __iomem *base, int i)
> +{
> +       const struct en_clk_desc *desc = &en7523_base_clks[i];
> +       u32 reg, val;
> +
> +       if (!desc->div_bits)
> +               return 1;
> +
> +       reg = desc->div_reg ? desc->div_reg : desc->base_reg;
> +       val = readl(base + reg);
> +       val >>= desc->div_shift;
> +       val &= (1 << desc->div_bits) - 1;
> +
> +       if (!val && desc->div_val0)
> +               return desc->div_val0;
> +
> +       return (val + 1) * desc->div_step;
> +}
> +
> +static int en7523_pci_is_enabled(struct clk_hw *hw)
> +{
> +       struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
> +
> +       return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
> +}
> +
> +static int en7523_pci_enable(struct clk_hw *hw)
> +{
> +       struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
> +       void __iomem *np_base = cg->base;
> +       u32 val, mask;
> +
> +       /* Need to pull device low before reset */
> +       val = readl(np_base + REG_PCI_CONTROL);
> +       val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
> +       writel(val, np_base + REG_PCI_CONTROL);
> +       usleep_range(1000, 2000);

This clk_op is called under a spinlock and thus nothing in here can
sleep. These need to be udelays and mdelays instead, or this needs to be
a prepare clk_op.

> +
> +       /* Enable PCIe port 1 */
> +       val |= REG_PCI_CONTROL_REFCLK_EN1;
> +       writel(val, np_base + REG_PCI_CONTROL);
> +       usleep_range(1000, 2000);
> +
> +       /* Reset to default */
> +       val = readl(np_base + REG_RESET_CONTROL);
> +       mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
> +              REG_RESET_CONTROL_PCIEHB;
> +       writel(val & ~mask, np_base + REG_RESET_CONTROL);
> +       usleep_range(1000, 2000);
> +       writel(val | mask, np_base + REG_RESET_CONTROL);
> +       msleep(100);
> +       writel(val & ~mask, np_base + REG_RESET_CONTROL);
> +       usleep_range(5000, 10000);
> +
> +       /* Release device */
> +       mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
> +       val = readl(np_base + REG_PCI_CONTROL);
> +       writel(val & ~mask, np_base + REG_PCI_CONTROL);
> +       usleep_range(1000, 2000);
> +       writel(val | mask, np_base + REG_PCI_CONTROL);
> +       msleep(250);
> +
> +       return 0;
> +}
> +
> +static void en7523_pci_disable(struct clk_hw *hw)
> +{
> +       struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
> +       void *np_base = cg->base;
> +       u32 val;
> +
> +       val = readl(np_base + REG_PCI_CONTROL);
> +       val &= ~REG_PCI_CONTROL_REFCLK_EN1;
> +       writel(val, np_base + REG_PCI_CONTROL);
> +}
> +
> +static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
> +                                              void __iomem *np_base)
> +{
> +       static const struct clk_ops pcie_gate_ops = {
> +               .is_enabled = en7523_pci_is_enabled,
> +               .enable = en7523_pci_enable,
> +               .disable = en7523_pci_disable,
> +       };
> +       struct clk_init_data init = {
> +               .name = "pcie",
> +               .ops = &pcie_gate_ops,
> +       };
> +       struct en_clk_gate *cg;
> +
> +       cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
> +       if (!cg)
> +               return NULL;
> +
> +       cg->base = np_base;
> +       cg->hw.init = &init;
> +       en7523_pci_disable(&cg->hw);
> +
> +       if (clk_hw_register(NULL, &cg->hw))
> +               return NULL;
> +
> +       return &cg->hw;
> +}
> +
> +static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
> +                                  void __iomem *base, void __iomem *np_base)
> +{
> +       struct clk_hw *hw;
> +       u32 rate;
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
> +               const struct en_clk_desc *desc = &en7523_base_clks[i];
> +
> +               rate = en7523_get_base_rate(base, i);
> +               rate /= en7523_get_div(base, i);
> +
> +               hw = clk_hw_register_fixed_rate(NULL, desc->name, NULL, 0, rate);

Please pass 'dev' to this function.

> +               if (IS_ERR(hw)) {
> +                       pr_err("Failed to register clk %s: %ld\n",
> +                              desc->name, PTR_ERR(hw));
> +                       continue;
> +               }
> +
> +               clk_data->hws[desc->id] = hw;
> +       }
> +
> +       hw = en7523_register_pcie_clk(dev, np_base);
> +       clk_data->hws[EN7523_CLK_PCIE] = hw;
> +
> +       clk_data->num = EN7523_NUM_CLOCKS;
> +}
> +
> +static int en7523_clk_probe(struct platform_device *pdev)
> +{
> +       struct device_node *node = pdev->dev.of_node;
> +       struct clk_hw_onecell_data *clk_data;
> +       void __iomem *base, *np_base;
> +       int r;
> +
> +       base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(base))
> +               return PTR_ERR(base);
> +
> +       np_base = devm_platform_ioremap_resource(pdev, 1);
> +       if (IS_ERR(base))
> +               return PTR_ERR(np_base);
> +
> +       clk_data = devm_kzalloc(&pdev->dev,
> +                               struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
> +                               GFP_KERNEL);
> +       if (!clk_data)
> +               return -ENOMEM;
> +
> +       en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
> +
> +       r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
> +       if (r)
> +               dev_err(&pdev->dev,
> +                       "could not register clock provider: %s: %d\n",
> +                       pdev->name, r);
> +
> +       return r;
> +}
> +
> +static struct platform_driver clk_en7523_drv = {
> +       .probe = en7523_clk_probe,
> +       .driver = {
> +               .name = "clk-en7523",
> +               .of_match_table = of_match_clk_en7523,
> +       },
> +};
> +
> +static int clk_en7523_init(void)

Add __init

> +{
> +       return platform_driver_register(&clk_en7523_drv);
> +}
> +
> +arch_initcall(clk_en7523_init);


From sboyd at kernel.org  Wed Jan  5 17:30:58 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 05 Jan 2022 17:30:58 -0800
Subject: [PATCH v7 06/14] dt-bindings: Add en7523-scu device tree binding
 documentation
In-Reply-To: <20211217112345.14029-7-nbd@nbd.name>
References: <20211217112345.14029-1-nbd@nbd.name>
 <20211217112345.14029-7-nbd@nbd.name>
Message-ID: <20220106013100.842FCC36AEB@smtp.kernel.org>

Quoting Felix Fietkau (2021-12-17 03:23:36)
> diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
> new file mode 100644
> index 000000000000..79660f8126fa
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
> @@ -0,0 +1,58 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/airoha,en7523-scu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: EN7523 Clock Device Tree Bindings
> +
> +maintainers:
> +  - Felix Fietkau <nbd at nbd.name>
> +  - John Crispin <nbd at nbd.name>
> +
> +description: |
> +  This node defines the System Control Unit of the EN7523 SoC,
> +  a collection of registers configuring many different aspects of the SoC.
> +
> +  The clock driver uses it to read and configure settings of the
> +  PLL controller, which provides clocks for the CPU, the bus and
> +  other SoC internal peripherals.
> +
> +  Each clock is assigned an identifier and client nodes use this identifier
> +  to specify which clock they consume.
> +
> +  All these identifiers can be found in:
> +  [1]: <include/dt-bindings/clock/en7523-clk.h>.
> +
> +  The clocks are provided inside a system controller node.
> +
> +properties:
> +  compatible:
> +    items:
> +      - const: airoha,en7523-scu
> +
> +  reg:
> +    maxItems: 2
> +
> +  "#clock-cells":
> +    description:
> +      The first cell indicates the clock number, see [1] for available
> +      clocks.
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - '#clock-cells'
> +

Any input clocks?

> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/en7523-clk.h>
> +    scu: scu at 1fa20000 {

Maybe that should be system-controller at 1fa20000 instead?

> +      compatible = "airoha,en7523-scu";
> +      reg = <0x1fa20000 0x400>,
> +            <0x1fb00000 0x1000>;
> +      #clock-cells = <1>;
> +    };


From stevensd at chromium.org  Wed Jan  5 18:42:39 2022
From: stevensd at chromium.org (David Stevens)
Date: Thu, 6 Jan 2022 11:42:39 +0900
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <YdXvUaBUvaRPsv6m@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
Message-ID: <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>

On Thu, Jan 6, 2022 at 4:19 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Wed, Jan 05, 2022, Sean Christopherson wrote:
> > Ah, I got royally confused by ensure_pfn_ref()'s comment
> >
> >   * Certain IO or PFNMAP mappings can be backed with valid
> >   * struct pages, but be allocated without refcounting e.g.,
> >   * tail pages of non-compound higher order allocations, which
> >   * would then underflow the refcount when the caller does the
> >   * required put_page. Don't allow those pages here.
> >                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > that doesn't apply here because kvm_faultin_pfn() uses the low level
> > __gfn_to_pfn_page_memslot().
>
> On fifth thought, I think this is wrong and doomed to fail.  By mapping these pages
> into the guest, KVM is effectively saying it supports these pages.  But if the guest
> uses the corresponding gfns for an action that requires KVM to access the page,
> e.g. via kvm_vcpu_map(), ensure_pfn_ref() will reject the access and all sorts of
> bad things will happen to the guest.
>
> So, why not fully reject these types of pages?  If someone is relying on KVM to
> support these types of pages, then we'll fail fast and get a bug report letting us
> know we need to properly support these types of pages.  And if not, then we reduce
> KVM's complexity and I get to keep my precious WARN :-)

Our current use case here is virtio-gpu blob resources [1]. Blob
resources are useful because they avoid a guest shadow buffer and the
associated memcpys, and as I understand it they are also required for
virtualized vulkan.

One type of blob resources requires mapping dma-bufs allocated by the
host directly into the guest. This works on Intel platforms and the
ARM platforms I've tested. However, the amdgpu driver sometimes
allocates higher order, non-compound pages via ttm_pool_alloc_page.
These are the type of pages which KVM is currently rejecting. Is this
something that KVM can support?

+olv, who has done some of the blob resource work.

[1] https://patchwork.kernel.org/project/dri-devel/cover/20200814024000.2485-1-gurchetansingh at chromium.org/

-David


From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:20 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:20 +0800
Subject: [PATCH v2 5/5] arm64: dts: mediatek: Correct system timer clock of
 MT8192
In-Reply-To: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220106032420.11544-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the systimer clock property to point to the actual

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 1eb5874c09a9..4f6c4ce885af 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -312,7 +312,7 @@
 				     "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
 			interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>;
+			clocks = <&topckgen CLK_TOP_CSW_F26M_D2>;
 			clock-names = "clk13m";
 		};
 
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:18 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:18 +0800
Subject: [PATCH v2 3/5] arm64: dts: mediatek: Correct Nor Flash clock of MT8192
In-Reply-To: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220106032420.11544-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the Nor Flash clock property to point to the actual

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 47d056cc5dad..8584a20440c5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -464,10 +464,12 @@
 			compatible = "mediatek,mt8192-nor";
 			reg = <0 0x11234000 0 0xe0>;
 			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_SFLASH_SEL>,
+				 <&infracfg CLK_INFRA_FLASHIF_SFLASH>,
+				 <&infracfg CLK_INFRA_FLASHIF_TOP_H_133M>;
 			clock-names = "spi", "sf", "axi";
+			assigned-clocks = <&topckgen CLK_TOP_SFLASH_SEL>;
+			assigned-clock-parents = <&clk26m>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disable";
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:17 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:17 +0800
Subject: [PATCH v2 2/5] arm64: dts: mediatek: Correct SPI clock of MT8192
In-Reply-To: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220106032420.11544-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the SPI clock property to point to the actual

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 48 ++++++++++++------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index cfb67cc40c2c..47d056cc5dad 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -355,9 +355,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1100a000 0 0x1000>;
 			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI0>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -369,9 +369,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11010000 0 0x1000>;
 			interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI1>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -383,9 +383,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11012000 0 0x1000>;
 			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI2>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -397,9 +397,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11013000 0 0x1000>;
 			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI3>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -411,9 +411,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11018000 0 0x1000>;
 			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI4>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -425,9 +425,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11019000 0 0x1000>;
 			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI5>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -439,9 +439,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101d000 0 0x1000>;
 			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI6>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -453,9 +453,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101e000 0 0x1000>;
 			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI7>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:19 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:19 +0800
Subject: [PATCH v2 4/5] arm64: dts: mediatek: Correct I2C clock of MT8192
In-Reply-To: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220106032420.11544-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the I2C clock property to point to the actual

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 30 ++++++++++++++++--------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 8584a20440c5..1eb5874c09a9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -486,7 +486,8 @@
 			reg = <0 0x11cb0000 0 0x1000>,
 			      <0 0x10217300 0 0x80>;
 			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -505,7 +506,8 @@
 			reg = <0 0x11d00000 0 0x1000>,
 			      <0 0x10217600 0 0x180>;
 			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -518,7 +520,8 @@
 			reg = <0 0x11d01000 0 0x1000>,
 			      <0 0x10217780 0 0x180>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -531,7 +534,8 @@
 			reg = <0 0x11d02000 0 0x1000>,
 			      <0 0x10217900 0 0x180>;
 			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -550,7 +554,8 @@
 			reg = <0 0x11d20000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -563,7 +568,8 @@
 			reg = <0 0x11d21000 0 0x1000>,
 			      <0 0x10217180 0 0x180>;
 			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -576,7 +582,8 @@
 			reg = <0 0x11d22000 0 0x1000>,
 			      <0 0x10217380 0 0x180>;
 			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -595,7 +602,8 @@
 			reg = <0 0x11e00000 0 0x1000>,
 			      <0 0x10217500 0 0x80>;
 			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -614,7 +622,8 @@
 			reg = <0 0x11f00000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C0>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -627,7 +636,8 @@
 			reg = <0 0x11f01000 0 0x1000>,
 			      <0 0x10217580 0 0x80>;
 			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C6>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:16 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:16 +0800
Subject: [PATCH v2 1/5] arm64: dts: mediatek: Correct uart clock of MT8192
In-Reply-To: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220106032420.11544-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the uart clock property to point to the actual

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..cfb67cc40c2c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -327,7 +327,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11002000 0 0x1000>;
 			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
@@ -337,7 +337,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11003000 0 0x1000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
-- 
2.18.0



From liang.yang at amlogic.com  Wed Jan  5 19:25:04 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 6 Jan 2022 11:25:04 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
Message-ID: <20220106032504.23310-1-liang.yang@amlogic.com>

Because EMMC and NAND have the same control clock register, so we
implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:

	sd_emmc_c_clkc: mmc at 7000 {
		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
		reg = <0x0 0x7000 0x0 0x800>;
	};

	nand-controller at 7800 {
		......

		clocks = <&clkc CLKID_SD_EMMC_C>,
			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
		clock-names = "core", "device", "rx", "tx";
		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;

		......
	}

but in fact, above implementation is rejected. so now registering
a nand_divider.

Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
 1 file changed, 49 insertions(+), 39 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index ac3be92872d0..4472363059c2 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -2,7 +2,7 @@
 /*
  * Amlogic Meson Nand Flash Controller Driver
  *
- * Copyright (c) 2018 Amlogic, inc.
+ * Copyright (c) 2018-2021 Amlogic, inc.
  * Author: Liang Yang <liang.yang at amlogic.com>
  */
 
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mfd/syscon.h>
@@ -55,6 +56,7 @@
 #define NFC_REG_VER		0x38
 
 #define NFC_RB_IRQ_EN		BIT(21)
+#define NFC_CMD_FIFO_RESET	BIT(31)
 
 #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
 	(								\
@@ -104,6 +106,9 @@
 
 #define PER_INFO_BYTE		8
 
+#define CLK_DIV_SHIFT		0
+#define CLK_DIV_WIDTH		6
+
 struct meson_nfc_nand_chip {
 	struct list_head node;
 	struct nand_chip nand;
@@ -151,15 +156,15 @@ struct meson_nfc {
 	struct nand_controller controller;
 	struct clk *core_clk;
 	struct clk *device_clk;
-	struct clk *phase_tx;
-	struct clk *phase_rx;
+	struct clk *nand_clk;
+	struct clk_divider nand_divider;
 
 	unsigned long clk_rate;
 	u32 bus_timing;
 
 	struct device *dev;
 	void __iomem *reg_base;
-	struct regmap *reg_clk;
+	void __iomem *reg_clk;
 	struct completion completion;
 	struct list_head chips;
 	const struct meson_nfc_data *data;
@@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
 	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
 		| nfc->param.chip_select | nfc->timing.tbers_max;
 	writel(cmd, nfc->reg_base + NFC_REG_CMD);
-
+	meson_nfc_drain_cmd(nfc);
 	ret = wait_for_completion_timeout(&nfc->completion,
 					  msecs_to_jiffies(timeout_ms));
 	if (ret == 0)
 		ret = -1;
 
+	/* reset command fifo to avoid lock */
+	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
 	return ret;
 }
 
@@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
 	int ret;
+	struct clk_init_data init = {0};
+	const char *fix_div2_pll_name[1];
 
-	/* request core clock */
 	nfc->core_clk = devm_clk_get(nfc->dev, "core");
 	if (IS_ERR(nfc->core_clk)) {
 		dev_err(nfc->dev, "failed to get core clock\n");
@@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		return PTR_ERR(nfc->device_clk);
 	}
 
-	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
-	if (IS_ERR(nfc->phase_tx)) {
-		dev_err(nfc->dev, "failed to get TX clk\n");
-		return PTR_ERR(nfc->phase_tx);
-	}
-
-	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
-	if (IS_ERR(nfc->phase_rx)) {
-		dev_err(nfc->dev, "failed to get RX clk\n");
-		return PTR_ERR(nfc->phase_rx);
-	}
+	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
+	init.ops = &clk_divider_ops;
+	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
+	init.parent_names = fix_div2_pll_name;
+	init.num_parents = 1;
+	nfc->nand_divider.reg = nfc->reg_clk;
+	nfc->nand_divider.shift = CLK_DIV_SHIFT;
+	nfc->nand_divider.width = CLK_DIV_WIDTH;
+	nfc->nand_divider.hw.init = &init;
+	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
+				  CLK_DIVIDER_ROUND_CLOSEST |
+          			  CLK_DIVIDER_ALLOW_ZERO;
+
+	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
+	if (IS_ERR(nfc->nand_clk))
+		return PTR_ERR(nfc->nand_clk);
 
 	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
-	regmap_update_bits(nfc->reg_clk,
-			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
+	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
 
 	ret = clk_prepare_enable(nfc->core_clk);
 	if (ret) {
@@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		goto err_device_clk;
 	}
 
-	ret = clk_prepare_enable(nfc->phase_tx);
+	ret = clk_prepare_enable(nfc->nand_clk);
 	if (ret) {
-		dev_err(nfc->dev, "failed to enable TX clock\n");
-		goto err_phase_tx;
-	}
-
-	ret = clk_prepare_enable(nfc->phase_rx);
-	if (ret) {
-		dev_err(nfc->dev, "failed to enable RX clock\n");
-		goto err_phase_rx;
+		dev_err(nfc->dev, "pre enable NFC divider fail\n");
+		goto err_nand_clk;
 	}
 
 	ret = clk_set_rate(nfc->device_clk, 24000000);
 	if (ret)
-		goto err_disable_rx;
+		goto err_disable_clk;
 
 	return 0;
 
-err_disable_rx:
-	clk_disable_unprepare(nfc->phase_rx);
-err_phase_rx:
-	clk_disable_unprepare(nfc->phase_tx);
-err_phase_tx:
+err_disable_clk:
+	clk_disable_unprepare(nfc->nand_clk);
+err_nand_clk:
 	clk_disable_unprepare(nfc->device_clk);
 err_device_clk:
 	clk_disable_unprepare(nfc->core_clk);
@@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 
 static void meson_nfc_disable_clk(struct meson_nfc *nfc)
 {
-	clk_disable_unprepare(nfc->phase_rx);
-	clk_disable_unprepare(nfc->phase_tx);
+	clk_disable_unprepare(nfc->nand_clk);
 	clk_disable_unprepare(nfc->device_clk);
 	clk_disable_unprepare(nfc->core_clk);
 }
@@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct meson_nfc *nfc;
 	struct resource *res;
+	u32 ext_clk_reg;
 	int ret, irq;
 
 	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	if (IS_ERR(nfc->reg_base))
 		return PTR_ERR(nfc->reg_base);
 
-	nfc->reg_clk =
-		syscon_regmap_lookup_by_phandle(dev->of_node,
-						"amlogic,mmc-syscon");
+	ret = of_property_read_u32(pdev->dev.of_node,
+				   "sd_emmc_c_clkc",
+				   &ext_clk_reg);
+	if (ret) {
+		dev_err(dev, "failed to get NAND external clock register\n");
+		return ret;
+	}
+
+	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
 	if (IS_ERR(nfc->reg_clk)) {
 		dev_err(dev, "Failed to lookup clock base\n");
 		return PTR_ERR(nfc->reg_clk);
-- 
2.34.1



From allen-kh.cheng at mediatek.com  Wed Jan  5 19:24:15 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 6 Jan 2022 11:24:15 +0800
Subject: [PATCH v2 0/5] Update MT8192 Clock Setting
Message-ID: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is base on v5.16-rc8,
series "Mediatek MT8192 clock support"[1], [2] annd [3].
[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/
[3] https://lore.kernel.org/all/20210825011120.30481-1-chun-jie.chen at mediatek.com/

changes since v1:
 - update the commit message

Allen-KH Cheng (5):
  arm64: dts: mediatek: Correct uart clock of MT8192
  arm64: dts: mediatek: Correct SPI clock of MT8192
  arm64: dts: mediatek: Correct Nor Flash clock of MT8192
  arm64: dts: mediatek: Correct I2C clock of MT8192
  arm64: dts: mediatek: Correct system timer clock of MT8192

 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++-----------
 1 file changed, 52 insertions(+), 40 deletions(-)

-- 
2.18.0



From liang.yang at amlogic.com  Wed Jan  5 19:31:30 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 6 Jan 2022 11:31:30 +0800
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
Message-ID: <20220106033130.37623-1-liang.yang@amlogic.com>

Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
---
 .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
index 5794ab1147c1..37f16fe4fe66 100644
--- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
@@ -14,11 +14,6 @@ Required properties:
 - clock-names: Should contain the following:
 	"core" - NFC module gate clock
 	"device" - device clock from eMMC sub clock controller
-	"rx" - rx clock phase
-	"tx" - tx clock phase
-
-- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
-				controller port C
 
 Optional children nodes:
 Children nodes represent the available nand chips.
@@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
 
 Example demonstrate on AXG SoC:
 
-	sd_emmc_c_clkc: mmc at 7000 {
-		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
-		reg = <0x0 0x7000 0x0 0x800>;
-	};
-
 	nand-controller at 7800 {
 		compatible = "amlogic,meson-axg-nfc";
 		reg = <0x0 0x7800 0x0 0x100>;
@@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
 		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
 
 		clocks = <&clkc CLKID_SD_EMMC_C>,
-			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
-		clock-names = "core", "device", "rx", "tx";
-		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
+			<&clkc CLKID_FCLK_DIV2>;
+		clock-names = "core", "device";
+		sd_emmc_c_clkc = <0xffe07000>;
 
 		pinctrl-names = "default";
 		pinctrl-0 = <&nand_pins>;
-- 
2.34.1



From hongxing.zhu at nxp.com  Wed Jan  5 19:49:38 2022
From: hongxing.zhu at nxp.com (Hongxing Zhu)
Date: Thu, 6 Jan 2022 03:49:38 +0000
Subject: [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never
 came up
In-Reply-To: <CAOMZO5AqgOOo3+r3yQSsfaNxW9eHXhCi=m+mqR=sf=K6dXA8tw@mail.gmail.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
 <1641368602-20401-6-git-send-email-hongxing.zhu@nxp.com>
 <CAOMZO5AqgOOo3+r3yQSsfaNxW9eHXhCi=m+mqR=sf=K6dXA8tw@mail.gmail.com>
Message-ID: <AS8PR04MB867662FF5FC56A7613D509CC8C4C9@AS8PR04MB8676.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Fabio Estevam <festevam at gmail.com>
> Sent: Thursday, January 6, 2022 5:52 AM
> To: Hongxing Zhu <hongxing.zhu at nxp.com>
> Cc: Lucas Stach <l.stach at pengutronix.de>; Bjorn Helgaas
> <bhelgaas at google.com>; Mark Brown <broonie at kernel.org>;
> lorenzo.pieralisi at arm.com; jingoohan1 at gmail.com;
> stable at vger.kernel.org; linux-pci at vger.kernel.org; dl-linux-imx
> <linux-imx at nxp.com>; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; kernel at pengutronix.de
> Subject: Re: [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link
> never came up
> 
> Hi Richard,
> 
> On Wed, Jan 5, 2022 at 5:12 AM Richard Zhu <hongxing.zhu at nxp.com>
> wrote:
> >
> > When PCIe PHY link never came up and vpcie regulator is present, there
> > would be following dump when try to put the regulator.
> > Add a new host_exit() callback for i.MX PCIe driver to disable this
> > regulator and fix this dump when link never came up.
> >
> > The driver should undo any enables it did itself, and not undo any
> > enables that anything else did which means it should never be basing
> > decisions on regulator_is_enabled().
> >
> > To keep usage counter balance of the clocks, powers and so on. Do the
> > clock disable in the error handling after host_init too.
> >
> >   imx6q-pcie 33800000.pcie: Phy link never came up
> >   imx6q-pcie: probe of 33800000.pcie failed with error -110
> 
> Shouldn't we ignore the dw_pcie_wait_for_link() error?
> 
> At least, this was the intention of 886a9c134755 ("PCI: dwc: Move link
> handling into common code").
> 
> >   ------------[ cut here ]------------
> >   WARNING: CPU: 3 PID: 119 at drivers/regulator/core.c:2256
> _regulator_put.part.0+0x14c/0x158
> >   Modules linked in:
> 
> My concern is that this issue is still present in 5.15, which is LTS.
> 
> You only address this problem in 5/6 and I am not sure if the previous
> patches could be applied to stable as they are cleanups.
> 
> How can we fix this for 5.15 stable?
> 
> Could you make a minimal fix as the first patch of the series and cleanup
> patches later?
[Richard Zhu] Remove the stable kernel mail list firstly.
Yes, you're right.
It's difficult to merge this series back to 5.15 stable kernel, since the
 i.MX8MM PCIe support patch-set had been merged, and there are codes
 conflictions.

How about continue proceed your previous fix firstly?
https://patchwork.kernel.org/project/linux-pci/patch/20211104000202.4028036-1-festevam at gmail.com/
Then, I clean up the fix patch, and re-send my series later.
Because that I still want to save power consumption as much as possible
 when link is down.
BTW, please remove the timestamp in your patch if you agree this method,
and resend your patch.

Best Regards
Richard Zhu

From hongxing.zhu at nxp.com  Wed Jan  5 19:49:54 2022
From: hongxing.zhu at nxp.com (Hongxing Zhu)
Date: Thu, 6 Jan 2022 03:49:54 +0000
Subject: [PATCH v5 3/6] PCI: imx6: PCI: imx6: Move imx6_pcie_clk_disable()
 earlier
In-Reply-To: <20220105190404.GA213307@bhelgaas>
References: <1641368602-20401-4-git-send-email-hongxing.zhu@nxp.com>
 <20220105190404.GA213307@bhelgaas>
Message-ID: <AS8PR04MB867679F2DD3E130109E2C44B8C4C9@AS8PR04MB8676.eurprd04.prod.outlook.com>


> -----Original Message-----
> From: Bjorn Helgaas <helgaas at kernel.org>
> Sent: Thursday, January 6, 2022 3:04 AM
> To: Hongxing Zhu <hongxing.zhu at nxp.com>
> Cc: l.stach at pengutronix.de; bhelgaas at google.com; broonie at kernel.org;
> lorenzo.pieralisi at arm.com; jingoohan1 at gmail.com;
> festevam at gmail.com; stable at vger.kernel.org; linux-pci at vger.kernel.org;
> dl-linux-imx <linux-imx at nxp.com>; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; kernel at pengutronix.de
> Subject: Re: [PATCH v5 3/6] PCI: imx6: PCI: imx6: Move
> imx6_pcie_clk_disable() earlier
> 
> Remove repeated words from subject line.
[Richard Zhu] Remove the stable kernel mail list.
Sorry to add one edit mistake here.
Would remove them later, thanks.

Best Regards
Richard Zhu
> 
> On Wed, Jan 05, 2022 at 03:43:19PM +0800, Richard Zhu wrote:
> > Just move the imx6_pcie_clk_disable() to an earlier place without
> > function changes, since it wouldn't be only used in
> imx6_pcie_suspend_noirq() later.


From reijiw at google.com  Wed Jan  5 20:26:42 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:42 -0800
Subject: [RFC PATCH v4 00/26] KVM: arm64: Make CPU ID registers writable by
 userspace
Message-ID: <20220106042708.2869332-1-reijiw@google.com>

In KVM/arm64, values of ID registers for a guest are mostly same as
its host's values except for bits for feature that KVM doesn't support
and for opt-in features that userspace didn't configure.  Userspace
can use KVM_SET_ONE_REG to a set ID register value, but it fails
if userspace attempts to modify the register value.

This patch series adds support to allow userspace to modify a value of
ID registers (as long as KVM can support features that are indicated
in the registers) so userspace can have more control of configuring
and unconfiguring features for guests.  We need this because we would
like to expose a uniform set/level of features for a group of guests on
systems with different ARM CPUs.  Since some features are not binary
in nature (e.g. AA64DFR0_EL1.BRPs fields indicate number of
breakpoints minus 1), using KVM_ARM_VCPU_INIT to control such features
is inconvenient.

The patch series is for both VHE and non-VHE, except for protected VMs,
which have a different way of configuring ID registers based on its
different requirements [1].
There was a patch series that tried to achieve the same thing [2].
A few snippets of codes in this series were inspired by or came from [2].

The initial value of ID registers for a vCPU will be the host's value
with bits cleared for unsupported features and for opt-in features that
were not configured. So, the initial value userspace can see (via
KVM_GET_ONE_REG) is the upper limit that can be set for the register.
Any requests to change the value that conflicts with opt-in features'
configuration will fail (e.g. if KVM_ARM_VCPU_PMU_V3 is configured by
KVM_ARM_VCPU_INIT, ID_AA64DFR0_EL1.PMUVER cannot be set to zero.
Otherwise, the initial value of ID_AA64DFR0_EL1.PMUVER will be zero,
and cannot be changed from zero).

When a guest tries to use a CPU feature that is not exposed to the guest,
trapping it (to emulate a real CPU's behavior) would generally be a
desirable behavior (when it is possible with no or little side effects).
The later patches in the series add codes for this.  Only features that
can be trapped independently will be trapped by this series though.

This series adds kunit tests for new functions in sys_regs.c (except for
trivial ones), and these tests are enabled with a new configuration
option 'CONFIG_KVM_KUNIT_TEST'.

The series is based on v5.16-rc8 with the patch [3] applied.

v4:
  - Make ID registers storage per VM instead of per vCPU. [Marc]
  - Implement arm64_check_features() in arch/arm64/kernel/cpufeature.c
    by using existing codes in the file. [Marc]
  - Use a configuration function to enable traps for disabled
    features. [Marc]
  - Document ID registers become immutable after the first KVM_RUN [Eric]
  - Update ID_AA64PFR0.GIC at the point where a GICv3 is created. [Marc]
  - Get TGranX's bit position by substracting 12 from TGranX_2's bit
    position. [Eric]
  - Don't validate AArch32 ID registers when the system doesn't support
    32bit EL0. [Eric]
  - Add/fixes comments for patches. [Eric]
  - Made bug fixes/improvements of the selftest. [Eric]
  - Added .kunitconfig for arm64 KUnit tests

v3: https://lore.kernel.org/all/20211117064359.2362060-1-reijiw at google.com/
  - Remove ID register consistency checking across vCPUs. [Oliver]
  - Change KVM_CAP_ARM_ID_REG_WRITABLE to
    KVM_CAP_ARM_ID_REG_CONFIGURABLE. [Oliver]
  - Add KUnit testing for ID register validation and trap initialization.
  - Change read_id_reg() to take care of ID_AA64PFR0_EL1.GIC.
  - Add a helper of read_id_reg() (__read_id_reg()) and use the helper
    instead of directly using __vcpu_sys_reg().
  - Change not to run kvm_id_regs_consistency_check() and
    kvm_vcpu_init_traps() for protected VMs.
  - Update selftest to remove test cases for ID register consistency.
    checking across vCPUs and to add test cases for ID_AA64PFR0_EL1.GIC.

v2: https://lore.kernel.org/all/20211103062520.1445832-1-reijiw at google.com/
  - Remove unnecessary line breaks. [Andrew]
  - Use @params for comments. [Andrew]
  - Move arm64_check_features to arch/arm64/kvm/sys_regs.c and
    change that KVM specific feature check function.  [Andrew]
  - Remove unnecessary raz handling from __set_id_reg. [Andrew]
  - Remove sys_val field from the initial id_reg_info and add it
    in the later patch. [Andrew]
  - Call id_reg->init() from id_reg_info_init(). [Andrew]
  - Fix cpuid_feature_cap_perfmon_field() to convert 0xf to 0x0
    (and use it in the following patches).
  - Change kvm_vcpu_first_run_init to set has_run_once to false
    when kvm_id_regs_consistency_check() fails.
  - Add a patch to introduce id_reg_info for ID_AA64MMFR0_EL1,
    which requires special validity checking for TGran*_2 fields.
  - Add patches to introduce id_reg_info for ID_DFR1_EL1 and
    ID_MMFR0_EL1, which are required due to arm64_check_features
    implementation change.
  - Add a new argument, which is a pointer to id_reg_info, for
    id_reg_info's validate().

v1: https://lore.kernel.org/all/20211012043535.500493-1-reijiw at google.com/

[1] https://lore.kernel.org/kvmarm/20211010145636.1950948-1-tabba at google.com/
[2] https://lore.kernel.org/kvm/20201102033422.657391-1-liangpeng10 at huawei.com/
[3] https://lore.kernel.org/all/20220104194918.373612-2-rananta at google.com/

Reiji Watanabe (26):
  KVM: arm64: Introduce a validation function for an ID register
  KVM: arm64: Save ID registers' sanitized value per guest
  KVM: arm64: Introduce struct id_reg_info
  KVM: arm64: Make ID_AA64PFR0_EL1 writable
  KVM: arm64: Make ID_AA64PFR1_EL1 writable
  KVM: arm64: Make ID_AA64ISAR0_EL1 writable
  KVM: arm64: Make ID_AA64ISAR1_EL1 writable
  KVM: arm64: Make ID_AA64MMFR0_EL1 writable
  KVM: arm64: Hide IMPLEMENTATION DEFINED PMU support for the guest
  KVM: arm64: Make ID_AA64DFR0_EL1 writable
  KVM: arm64: Make ID_DFR0_EL1 writable
  KVM: arm64: Make MVFR1_EL1 writable
  KVM: arm64: Make ID registers without id_reg_info writable
  KVM: arm64: Add consistency checking for frac fields of ID registers
  KVM: arm64: Introduce KVM_CAP_ARM_ID_REG_CONFIGURABLE capability
  KVM: arm64: Add kunit test for ID register validation
  KVM: arm64: Use vcpu->arch cptr_el2 to track value of cptr_el2 for VHE
  KVM: arm64: Use vcpu->arch.mdcr_el2 to track value of mdcr_el2
  KVM: arm64: Introduce framework to trap disabled features
  KVM: arm64: Trap disabled features of ID_AA64PFR0_EL1
  KVM: arm64: Trap disabled features of ID_AA64PFR1_EL1
  KVM: arm64: Trap disabled features of ID_AA64DFR0_EL1
  KVM: arm64: Trap disabled features of ID_AA64MMFR1_EL1
  KVM: arm64: Trap disabled features of ID_AA64ISAR1_EL1
  KVM: arm64: Add kunit test for trap initialization
  KVM: arm64: selftests: Introduce id_reg_test

 Documentation/virt/kvm/api.rst                |   12 +
 arch/arm64/include/asm/cpufeature.h           |    3 +-
 arch/arm64/include/asm/kvm_arm.h              |   32 +
 arch/arm64/include/asm/kvm_host.h             |   19 +
 arch/arm64/include/asm/sysreg.h               |    3 +
 arch/arm64/kernel/cpufeature.c                |  228 +++
 arch/arm64/kvm/.kunitconfig                   |    4 +
 arch/arm64/kvm/Kconfig                        |   11 +
 arch/arm64/kvm/arm.c                          |   24 +-
 arch/arm64/kvm/debug.c                        |   13 +-
 arch/arm64/kvm/hyp/vhe/switch.c               |   14 +-
 arch/arm64/kvm/sys_regs.c                     | 1329 +++++++++++++++--
 arch/arm64/kvm/sys_regs_test.c                | 1247 ++++++++++++++++
 arch/arm64/kvm/vgic/vgic-init.c               |    5 +
 include/uapi/linux/kvm.h                      |    1 +
 tools/arch/arm64/include/asm/sysreg.h         |    1 +
 tools/testing/selftests/kvm/.gitignore        |    1 +
 tools/testing/selftests/kvm/Makefile          |    1 +
 .../selftests/kvm/aarch64/id_reg_test.c       | 1239 +++++++++++++++
 19 files changed, 4041 insertions(+), 146 deletions(-)
 create mode 100644 arch/arm64/kvm/.kunitconfig
 create mode 100644 arch/arm64/kvm/sys_regs_test.c
 create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c


base-commit: d399b107ee49bf5ea0391bd7614d512809e927b0
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:43 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:43 -0800
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function for
 an ID register
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-2-reijiw@google.com>

Introduce arm64_check_features(), which does a basic validity checking
of an ID register value against the register's limit value, which is
generally the host's sanitized value.

This function will be used by the following patches to check if an ID
register value that userspace tries to set for a guest can be supported
on the host.

The validation is done using arm64_ftr_bits_kvm, which is created from
arm64_ftr_regs, with some entries overwritten by entries from
arm64_ftr_bits_kvm_override.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/cpufeature.h |   1 +
 arch/arm64/kernel/cpufeature.c      | 228 ++++++++++++++++++++++++++++
 2 files changed, 229 insertions(+)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..eda7ddbed8cf 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -631,6 +631,7 @@ void check_local_cpu_capabilities(void);
 
 u64 read_sanitised_ftr_reg(u32 id);
 u64 __read_sysreg_by_encoding(u32 sys_id);
+int arm64_check_features(u32 sys_reg, u64 val, u64 limit);
 
 static inline bool cpu_supports_mixed_endian_el0(void)
 {
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6f3e677d88f1..48dff8b101d9 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -3140,3 +3140,231 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
 		return sprintf(buf, "Vulnerable\n");
 	}
 }
+
+#ifdef CONFIG_KVM
+/*
+ * arm64_ftr_bits_kvm[] is used for KVM to check if features that are
+ * indicated in an ID register value for the guest are available on the host.
+ * arm64_ftr_bits_kvm[] is created based on arm64_ftr_regs[].  But, for
+ * registers for which arm64_ftr_bits_kvm_override[] has a corresponding
+ * entry, replace arm64_ftr_bits entries in arm64_ftr_bits_kvm[] with the
+ * ones in arm64_ftr_bits_kvm_override[].
+ */
+static struct __ftr_reg_bits_entry *arm64_ftr_bits_kvm;
+static size_t arm64_ftr_bits_kvm_nentries;
+static DEFINE_MUTEX(arm64_ftr_bits_kvm_lock);
+
+/*
+ * Number of arm64_ftr_bits entries for each register.
+ * (Number of 4 bits fields in 64 bit register + 1 entry for ARM64_FTR_END)
+ */
+#define	MAX_FTR_BITS_LEN	17
+
+/* Use FTR_LOWER_SAFE for AA64DFR0_EL1.PMUVER and AA64DFR0_EL1.DEBUGVER. */
+static struct arm64_ftr_bits ftr_id_aa64dfr0_kvm[MAX_FTR_BITS_LEN] = {
+	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
+	ARM64_FTR_END,
+};
+
+#define	ARM64_FTR_REG_BITS(id, table)	{	\
+	.sys_id = id,				\
+	.ftr_bits = &((table)[0]),		\
+}
+
+struct __ftr_reg_bits_entry {
+	u32	sys_id;
+	struct arm64_ftr_bits	*ftr_bits;
+};
+
+/*
+ * All entries in arm64_ftr_bits_kvm_override[] are used to override
+ * the corresponding entries in arm64_ftr_bits_kvm[].
+ */
+static struct __ftr_reg_bits_entry arm64_ftr_bits_kvm_override[] = {
+	ARM64_FTR_REG_BITS(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0_kvm),
+};
+
+/*
+ * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
+ * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
+ * ARM64_FTR_END (.width == 0).
+ */
+static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,
+					struct arm64_ftr_bits *new_ftrp)
+{
+	struct arm64_ftr_bits *o_ftrp, *n_ftrp;
+
+	for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
+		for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
+			if (o_ftrp->shift == n_ftrp->shift) {
+				*o_ftrp = *n_ftrp;
+				break;
+			}
+		}
+	}
+}
+
+/*
+ * Copy arm64_ftr_bits entries from @src_ftrp to @dst_ftrp.  The last entries
+ * of @dst_ftrp and @src_ftrp must be ARM64_FTR_END (.width == 0).
+ */
+static void copy_arm64_ftr_bits(struct arm64_ftr_bits *dst_ftrp,
+				const struct arm64_ftr_bits *src_ftrp)
+{
+	int i = 0;
+
+	for (; src_ftrp[i].width; i++) {
+		if (WARN_ON_ONCE(i >= (MAX_FTR_BITS_LEN - 1)))
+			break;
+
+		dst_ftrp[i] = src_ftrp[i];
+	}
+
+	dst_ftrp[i].width = 0;
+}
+
+/*
+ * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
+ * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
+ * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
+ */
+static int init_arm64_ftr_bits_kvm(void)
+{
+	struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
+	static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
+	int i, j, nent, ret;
+
+	mutex_lock(&arm64_ftr_bits_kvm_lock);
+	if (arm64_ftr_bits_kvm) {
+		/* Already initialized */
+		ret = 0;
+		goto unlock_exit;
+	}
+
+	nent = ARRAY_SIZE(arm64_ftr_regs);
+	reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
+				 GFP_KERNEL);
+	if (!reg_bits_array) {
+		ret = ENOMEM;
+		goto unlock_exit;
+	}
+
+	/* Copy entries from arm64_ftr_regs to reg_bits_array */
+	for (i = 0; i < nent; i++) {
+		bits = &reg_bits_array[i];
+		bits->sys_id = arm64_ftr_regs[i].sys_id;
+		bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
+	};
+
+	/*
+	 * Override the entries in reg_bits_array with the ones in
+	 * arm64_ftr_bits_kvm_override.
+	 */
+	for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
+		o_bits = &arm64_ftr_bits_kvm_override[i];
+		for (j = 0; j < nent; j++) {
+			bits = &reg_bits_array[j];
+			if (bits->sys_id != o_bits->sys_id)
+				continue;
+
+			memset(ftr_temp, 0, sizeof(ftr_temp));
+
+			/*
+			 * Temporary save all entries in o_bits->ftr_bits
+			 * to ftr_temp.
+			 */
+			copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
+
+			/*
+			 * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
+			 */
+			copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
+
+			/*
+			 * Override entries in o_bits->ftr_bits with the
+			 * saved ones, and update bits->ftr_bits with
+			 * o_bits->ftr_bits.
+			 */
+			arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
+			bits->ftr_bits = o_bits->ftr_bits;
+			break;
+		}
+	}
+
+	arm64_ftr_bits_kvm_nentries = nent;
+	arm64_ftr_bits_kvm = reg_bits_array;
+	ret = 0;
+
+unlock_exit:
+	mutex_unlock(&arm64_ftr_bits_kvm_lock);
+	return ret;
+}
+
+static int search_cmp_ftr_reg_bits(const void *id, const void *regp)
+{
+	return ((int)(unsigned long)id -
+		(int)((const struct __ftr_reg_bits_entry *)regp)->sys_id);
+}
+
+static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
+{
+	const struct __ftr_reg_bits_entry *ret;
+	int err;
+
+	if (!arm64_ftr_bits_kvm) {
+		/* arm64_ftr_bits_kvm is not initialized yet. */
+		err = init_arm64_ftr_bits_kvm();
+		if (err)
+			return NULL;
+	}
+
+	ret = bsearch((const void *)(unsigned long)sys_id,
+		      arm64_ftr_bits_kvm,
+		      arm64_ftr_bits_kvm_nentries,
+		      sizeof(arm64_ftr_bits_kvm[0]),
+		      search_cmp_ftr_reg_bits);
+	if (ret)
+		return ret->ftr_bits;
+
+	return NULL;
+}
+
+/*
+ * Check if features (or levels of features) that are indicated in the ID
+ * register value @val are also indicated in @limit.
+ * This function is for KVM to check if features that are indicated in @val,
+ * which will be used as the ID register value for its guest, are supported
+ * on the host.
+ * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
+ * scheme, the function checks if values of the fields in @val are the same
+ * as the ones in @limit.
+ */
+int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
+{
+	const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);
+	u64 exposed_mask = 0;
+
+	if (!ftrp)
+		return -ENOENT;
+
+	for (; ftrp->width; ftrp++) {
+		s64 ftr_val = arm64_ftr_value(ftrp, val);
+		s64 ftr_lim = arm64_ftr_value(ftrp, limit);
+
+		exposed_mask |= arm64_ftr_mask(ftrp);
+
+		if (ftr_val == ftr_lim)
+			continue;
+
+		if (ftr_val != arm64_ftr_safe_value(ftrp, ftr_val, ftr_lim))
+			return -E2BIG;
+	}
+
+	/* Make sure that no unrecognized fields are set in @val. */
+	if (val & ~exposed_mask)
+		return -E2BIG;
+
+	return 0;
+}
+#endif /* CONFIG_KVM */
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:44 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:44 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized value
 per guest
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-3-reijiw@google.com>

Introduce id_regs[] in kvm_arch as a storage of guest's ID registers,
and save ID registers' sanitized value in the array at KVM_CREATE_VM.
Use the saved ones when ID registers are read by the guest or
userspace (via KVM_GET_ONE_REG).

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 16 ++++++++
 arch/arm64/kvm/arm.c              |  1 +
 arch/arm64/kvm/sys_regs.c         | 62 ++++++++++++++++++++++---------
 3 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2a5f7f38006f..c789a0137f58 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -102,6 +102,17 @@ struct kvm_s2_mmu {
 struct kvm_arch_memory_slot {
 };
 
+/*
+ * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
+ * where 0<=crm<8, 0<=op2<8.
+ */
+#define KVM_ARM_ID_REG_MAX_NUM	64
+#define IDREG_IDX(id)		((sys_reg_CRm(id) << 3) | sys_reg_Op2(id))
+#define is_id_reg(id)	\
+	(sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&	\
+	 sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&	\
+	 sys_reg_CRm(id) < 8)
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -137,6 +148,9 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+
+	/* ID registers for the guest. */
+	u64 id_regs[KVM_ARM_ID_REG_MAX_NUM];
 };
 
 struct kvm_vcpu_fault_info {
@@ -734,6 +748,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
 long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 				struct kvm_arm_copy_mte_tags *copy_tags);
 
+void set_default_id_regs(struct kvm *kvm);
+
 /* Guest/host FPSIMD coordination helpers */
 int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
 void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e4727dc771bf..5f497a0af254 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
 
 	set_default_spectre(kvm);
+	set_default_id_regs(kvm);
 
 	return ret;
 out_free_stage2_pgd:
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index e3ec1a44f94d..80dc62f98ef0 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -33,6 +33,8 @@
 
 #include "trace.h"
 
+static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
+
 /*
  * All of this file is extremely similar to the ARM coproc.c, but the
  * types are different. My gut feeling is that it should be pretty
@@ -273,7 +275,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
-	u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
+	u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
 	u32 sr = reg_to_encoding(r);
 
 	if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
@@ -1059,17 +1061,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-/* Read a sanitised cpufeature ID register by sys_reg_desc */
-static u64 read_id_reg(const struct kvm_vcpu *vcpu,
-		struct sys_reg_desc const *r, bool raz)
+static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
-	u32 id = reg_to_encoding(r);
-	u64 val;
-
-	if (raz)
-		return 0;
-
-	val = read_sanitised_ftr_reg(id);
+	u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
 
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
@@ -1119,6 +1113,14 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 	return val;
 }
 
+static u64 read_id_reg(const struct kvm_vcpu *vcpu,
+		       struct sys_reg_desc const *r, bool raz)
+{
+	u32 id = reg_to_encoding(r);
+
+	return raz ? 0 : __read_id_reg(vcpu, id);
+}
+
 static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
 				  const struct sys_reg_desc *r)
 {
@@ -1223,9 +1225,8 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 /*
  * cpufeature ID register user accessors
  *
- * For now, these registers are immutable for userspace, so no values
- * are stored, and for set_id_reg() we don't allow the effective value
- * to be changed.
+ * For now, these registers are immutable for userspace, so for set_id_reg()
+ * we don't allow the effective value to be changed.
  */
 static int __get_id_reg(const struct kvm_vcpu *vcpu,
 			const struct sys_reg_desc *rd, void __user *uaddr,
@@ -1237,7 +1238,7 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
 	return reg_to_user(uaddr, &val, id);
 }
 
-static int __set_id_reg(const struct kvm_vcpu *vcpu,
+static int __set_id_reg(struct kvm_vcpu *vcpu,
 			const struct sys_reg_desc *rd, void __user *uaddr,
 			bool raz)
 {
@@ -1837,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
 	if (p->is_write) {
 		return ignore_write(vcpu, p);
 	} else {
-		u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
-		u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+		u64 dfr = __read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
+		u64 pfr = __read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
 		u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
 
 		p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
@@ -2850,3 +2851,30 @@ void kvm_sys_reg_table_init(void)
 	/* Clear all higher bits. */
 	cache_levels &= (1 << (i*3))-1;
 }
+
+/*
+ * Set the guest's ID registers that are defined in sys_reg_descs[]
+ * with ID_SANITISED() to the host's sanitized value.
+ */
+void set_default_id_regs(struct kvm *kvm)
+{
+	int i;
+	u32 id;
+	const struct sys_reg_desc *rd;
+	u64 val;
+
+	for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
+		rd = &sys_reg_descs[i];
+		if (rd->access != access_id_reg)
+			/* Not ID register, or hidden/reserved ID register */
+			continue;
+
+		id = reg_to_encoding(rd);
+		if (WARN_ON_ONCE(!is_id_reg(id)))
+			/* Shouldn't happen */
+			continue;
+
+		val = read_sanitised_ftr_reg(id);
+		kvm->arch.id_regs[IDREG_IDX(id)] = val;
+	}
+}
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:45 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:45 -0800
Subject: [RFC PATCH v4 03/26] KVM: arm64: Introduce struct id_reg_info
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-4-reijiw@google.com>

This patch lays the groundwork to make ID registers writable.

Introduce struct id_reg_info for an ID register to manage the
register specific control of its value for the guest, and provide set
of functions commonly used for ID registers to make them writable.

The id_reg_info is used to do register specific initialization,
validation of the ID register and etc.  Not all ID registers must
have the id_reg_info. ID registers that don't have the id_reg_info
are handled in a common way that is applied to all ID registers.

At present, changing an ID register from userspace is allowed only
if the ID register has the id_reg_info, but that will be changed
by the following patches.

No ID register has the structure yet and the following patches
will add the id_reg_info for some ID registers.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 243 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 230 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 80dc62f98ef0..971018288bee 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -265,6 +265,101 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 		return read_zero(vcpu, p);
 }
 
+struct id_reg_info {
+	u32	sys_reg;	/* Register ID */
+
+	/*
+	 * Limit value of the register for a vcpu. The value is the sanitized
+	 * system value with bits cleared for unsupported features for the
+	 * guest.
+	 */
+	u64	vcpu_limit_val;
+
+	/* Fields that we don't to validate by arm64_check_features. */
+	u64	ignore_mask;
+
+	/* Initialization function of the id_reg_info */
+	void (*init)(struct id_reg_info *id_reg);
+
+	/*
+	 * This is an optional ID register specific validation function.
+	 * When userspace tries to set the ID register, arm64_check_features()
+	 * will check if the requested value indicates any features that cannot
+	 * be supported by KVM on the host.  But, some ID register fields need
+	 * a special checking, and this function can be used for such fields.
+	 * e.g. When SVE is configured for a vCPU by KVM_ARM_VCPU_INIT,
+	 * ID_AA64PFR0_EL1.SVE shouldn't be set to 0 for the vCPU.
+	 * The validation function for ID_AA64PFR0_EL1 could be used to check
+	 * the field is consistent with SVE configuration.
+	 */
+	int (*validate)(struct kvm_vcpu *vcpu, const struct id_reg_info *id_reg,
+			u64 val);
+
+	/*
+	 * Return a bitmask of the vCPU's ID register fields that are not
+	 * synced with saved (per VM) ID register value, which usually
+	 * indicates opt-in CPU features that is not configured for the vCPU.
+	 * ID registers are saved per VM, but some opt-in CPU features can
+	 * be configured per vCPU.  The saved (per VM) values for such
+	 * features are for vCPUs with the features (and zero for
+	 * vCPUs without the features).
+	 * Return value of this function is used to handle such fields
+	 * for per vCPU ID register read/write request with saved per VM
+	 * ID register.  See the __write_id_reg's comment for more detail.
+	 */
+	u64 (*vcpu_mask)(const struct kvm_vcpu *vcpu,
+			 const struct id_reg_info *id_reg);
+};
+
+static void id_reg_info_init(struct id_reg_info *id_reg)
+{
+	id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg);
+	if (id_reg->init)
+		id_reg->init(id_reg);
+}
+
+/*
+ * An ID register that needs special handling to control the value for the
+ * guest must have its own id_reg_info in id_reg_info_table.
+ * (i.e. the reset value is different from the host's sanitized value,
+ * the value is affected by opt-in features, some fields need specific
+ * validation, etc.)
+ */
+#define	GET_ID_REG_INFO(id)	(id_reg_info_table[IDREG_IDX(id)])
+static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
+
+static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
+{
+	const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
+	u64 limit, tmp_val;
+	int err;
+
+	if (id_reg) {
+		limit = id_reg->vcpu_limit_val;
+		/*
+		 * Replace the fields that are indicated in ignore_mask with
+		 * the value in the limit to not have arm64_check_features()
+		 * check the field in @val.
+		 */
+		tmp_val = val & ~id_reg->ignore_mask;
+		tmp_val |= (limit & id_reg->ignore_mask);
+	} else {
+		limit = read_sanitised_ftr_reg(id);
+		tmp_val = val;
+	}
+
+	/* Check if the value indicates any feature that is not in the limit. */
+	err = arm64_check_features(id, tmp_val, limit);
+	if (err)
+		return err;
+
+	if (id_reg && id_reg->validate)
+		/* Run the ID register specific validity check. */
+		err = id_reg->validate(vcpu, id_reg, val);
+
+	return err;
+}
+
 /*
  * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
  * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
@@ -1061,9 +1156,81 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
+{
+	return kvm->arch.id_regs[IDREG_IDX(id)];
+}
+
+static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
+			     u64 preserve_mask)
+{
+	u64 old, new;
+
+	mutex_lock(&kvm->lock);
+
+	old = kvm->arch.id_regs[IDREG_IDX(id)];
+
+	/* Preserve the value at the bit position set in preserve_mask */
+	new = old & preserve_mask;
+	new |= (val & ~preserve_mask);
+
+	/* Don't allow to modify ID register value after KVM_RUN on any vCPUs */
+	if (kvm_vm_has_started(kvm) && new != old)
+		return -EBUSY;
+
+	WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
+	mutex_unlock(&kvm->lock);
+
+	return 0;
+}
+
+static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
+{
+	return modify_kvm_id_reg(kvm, id, val, 0);
+}
+
+
+/*
+ * KVM basically forces all vCPUs of the guest to have a uniform value for
+ * each ID register (, which means KVM_SET_ONE_REG for a vCPU affects all
+ * the vCPUs of the guest), and the id_regs[] of kvm_arch holds values
+ * of ID registers for the guest.  However, there is an exception for
+ * ID register fields corresponding to CPU features that can be
+ * configured per vCPU by KVM_ARM_VCPU_INIT, or etc (e.g. PMUv3, SVE, etc).
+ * For such fields, all vCPUs that have the feature will have a non-zero
+ * uniform value (, which can be updated by userspace), but the vCPUs that
+ * don't have the feature will have zero for the fields.
+ * Values that @id_regs holds are for vCPUs that have such features.  So,
+ * to get the ID register value for a vCPU that doesn't have those features,
+ * the corresponding fields in id_regs[] needs to be cleared.
+ * A bitmask of the fields are provided by id_reg_info's vcpu_mask(), and
+ * __write_id_reg() and __read_id_reg() take care of those fields using
+ * the bitmask.
+ */
+static int __write_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
+{
+	const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
+	u64 mask = 0;
+
+	if (id_reg && id_reg->vcpu_mask)
+		mask = id_reg->vcpu_mask(vcpu, id_reg);
+
+	/*
+	 * Update the ID register for the guest with @val, except for fields
+	 * that are set in the mask, which indicates fields for opt-in
+	 * features that are not configured for the vCPU.
+	 */
+	return modify_kvm_id_reg(vcpu->kvm, id, val, mask);
+}
+
 static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 {
-	u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
+	const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
+	u64 val = read_kvm_id_reg(vcpu->kvm, id);
+
+	if (id_reg && id_reg->vcpu_mask)
+		/* Clear fields for opt-in features that are not configured. */
+		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
 	switch (id) {
 	case SYS_ID_AA64PFR0_EL1:
@@ -1222,12 +1389,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
-/*
- * cpufeature ID register user accessors
- *
- * For now, these registers are immutable for userspace, so for set_id_reg()
- * we don't allow the effective value to be changed.
- */
+/* cpufeature ID register user accessors */
 static int __get_id_reg(const struct kvm_vcpu *vcpu,
 			const struct sys_reg_desc *rd, void __user *uaddr,
 			bool raz)
@@ -1238,11 +1400,31 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
 	return reg_to_user(uaddr, &val, id);
 }
 
+/*
+ * Check if the given id indicates AArch32 ID register encoding.
+ */
+static bool is_aarch32_id_reg(u32 id)
+{
+	u32 crm, op2;
+
+	if (!is_id_reg(id))
+		return false;
+
+	crm = sys_reg_CRm(id);
+	op2 = sys_reg_Op2(id);
+	if (crm == 1 || crm == 2 || (crm == 3 && (op2 != 3 && op2 != 7)))
+		/* AArch32 ID register */
+		return true;
+
+	return false;
+}
+
 static int __set_id_reg(struct kvm_vcpu *vcpu,
 			const struct sys_reg_desc *rd, void __user *uaddr,
 			bool raz)
 {
 	const u64 id = sys_reg_to_index(rd);
+	u32 encoding = reg_to_encoding(rd);
 	int err;
 	u64 val;
 
@@ -1250,11 +1432,28 @@ static int __set_id_reg(struct kvm_vcpu *vcpu,
 	if (err)
 		return err;
 
-	/* This is what we mean by invariant: you can't change it. */
-	if (val != read_id_reg(vcpu, rd, raz))
+	if (val == read_id_reg(vcpu, rd, raz))
+		/* The value is same as the current value. Nothing to do. */
+		return 0;
+
+	/*
+	 * Don't allow to modify the register's value if the register is raz,
+	 * or the reg doesn't have the id_reg_info.
+	 */
+	if (raz || !GET_ID_REG_INFO(encoding))
 		return -EINVAL;
 
-	return 0;
+	/*
+	 * Skip the validation of AArch32 ID registers if the system doesn't
+	 * 32bit EL0 (their value are UNKNOWN).
+	 */
+	if (system_supports_32bit_el0() || !is_aarch32_id_reg(encoding)) {
+		err = validate_id_reg(vcpu, encoding, val);
+		if (err)
+			return err;
+	}
+
+	return __write_id_reg(vcpu, encoding, val);
 }
 
 static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
@@ -2816,6 +3015,20 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	return write_demux_regids(uindices);
 }
 
+static void id_reg_info_init_all(void)
+{
+	int i;
+	struct id_reg_info *id_reg;
+
+	for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) {
+		id_reg = (struct id_reg_info *)id_reg_info_table[i];
+		if (!id_reg)
+			continue;
+
+		id_reg_info_init(id_reg);
+	}
+}
+
 void kvm_sys_reg_table_init(void)
 {
 	unsigned int i;
@@ -2850,6 +3063,8 @@ void kvm_sys_reg_table_init(void)
 			break;
 	/* Clear all higher bits. */
 	cache_levels &= (1 << (i*3))-1;
+
+	id_reg_info_init_all();
 }
 
 /*
@@ -2862,11 +3077,12 @@ void set_default_id_regs(struct kvm *kvm)
 	u32 id;
 	const struct sys_reg_desc *rd;
 	u64 val;
+	struct id_reg_info *idr;
 
 	for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
 		rd = &sys_reg_descs[i];
 		if (rd->access != access_id_reg)
-			/* Not ID register, or hidden/reserved ID register */
+			/* Not ID register or hidden/reserved ID register */
 			continue;
 
 		id = reg_to_encoding(rd);
@@ -2874,7 +3090,8 @@ void set_default_id_regs(struct kvm *kvm)
 			/* Shouldn't happen */
 			continue;
 
-		val = read_sanitised_ftr_reg(id);
-		kvm->arch.id_regs[IDREG_IDX(id)] = val;
+		idr = GET_ID_REG_INFO(id);
+		val = idr ? idr->vcpu_limit_val : read_sanitised_ftr_reg(id);
+		(void)write_kvm_id_reg(kvm, id, val);
 	}
 }
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:46 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:46 -0800
Subject: [RFC PATCH v4 04/26] KVM: arm64: Make ID_AA64PFR0_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-5-reijiw@google.com>

This patch adds id_reg_info for ID_AA64PFR0_EL1 to make it writable by
userspace.

Return an error if userspace tries to set SVE/GIC field of the register
to a value that conflicts with SVE/GIC configuration for the guest.
SIMD/FP/SVE fields of the requested value are validated according to
Arm ARM.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_host.h |   1 +
 arch/arm64/include/asm/sysreg.h   |   2 +
 arch/arm64/kvm/sys_regs.c         | 177 +++++++++++++++++++-----------
 arch/arm64/kvm/vgic/vgic-init.c   |   5 +
 4 files changed, 123 insertions(+), 62 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index c789a0137f58..4509f9e7472d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -749,6 +749,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 				struct kvm_arm_copy_mte_tags *copy_tags);
 
 void set_default_id_regs(struct kvm *kvm);
+int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
 
 /* Guest/host FPSIMD coordination helpers */
 int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 16b3f1a1d468..e26027817171 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -798,6 +798,7 @@
 #define ID_AA64PFR0_ASIMD_SUPPORTED	0x0
 #define ID_AA64PFR0_ELx_64BIT_ONLY	0x1
 #define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
+#define ID_AA64PFR0_GIC3		0x1
 
 /* id_aa64pfr1 */
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
@@ -1197,6 +1198,7 @@
 #define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
 
 #define ARM64_FEATURE_FIELD_BITS	4
+#define ARM64_FEATURE_FIELD_MASK	((1ull << ARM64_FEATURE_FIELD_BITS) - 1)
 
 /* Create a mask for the feature bits of the specified feature. */
 #define ARM64_FEATURE_MASK(x)	(GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT))
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 971018288bee..1eb5c5fb614f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -318,6 +318,92 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
 		id_reg->init(id_reg);
 }
 
+static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
+				    const struct id_reg_info *id_reg, u64 val)
+{
+	int fp, simd;
+	unsigned int gic;
+	bool vcpu_has_sve = vcpu_has_sve(vcpu);
+	bool pfr0_has_sve = id_aa64pfr0_sve(val);
+
+	simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_ASIMD_SHIFT);
+	fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_FP_SHIFT);
+	if (simd != fp)
+		return -EINVAL;
+
+	/* fp must be supported when sve is supported */
+	if (pfr0_has_sve && (fp < 0))
+		return -EINVAL;
+
+	/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
+	if (vcpu_has_sve ^ pfr0_has_sve)
+		return -EPERM;
+
+	if ((irqchip_in_kernel(vcpu->kvm) &&
+	     vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)) {
+		gic = cpuid_feature_extract_unsigned_field(val,
+							ID_AA64PFR0_GIC_SHIFT);
+		if (gic == 0)
+			return -EPERM;
+
+		if (gic > ID_AA64PFR0_GIC3)
+			return -E2BIG;
+	} else {
+		u64 mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
+		int err = arm64_check_features(id_reg->sys_reg, val & mask,
+					       id_reg->vcpu_limit_val & mask);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
+{
+	u64 limit = id_reg->vcpu_limit_val;
+	unsigned int gic;
+
+	limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
+	if (!system_supports_sve())
+		limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
+
+	/*
+	 * The default is to expose CSV2 == 1 and CSV3 == 1 if the HW
+	 * isn't affected.  Userspace can override this as long as it
+	 * doesn't promise the impossible.
+	 */
+	limit &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2) |
+		   ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3));
+
+	if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
+		limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), 1);
+	if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED)
+		limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), 1);
+
+	gic = cpuid_feature_extract_unsigned_field(limit, ID_AA64PFR0_GIC_SHIFT);
+	if (gic > 1) {
+		/* Limit to GICv3.0/4.0 */
+		limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
+		limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), ID_AA64PFR0_GIC3);
+	}
+	id_reg->vcpu_limit_val = limit;
+}
+
+static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
+					 const struct id_reg_info *idr)
+{
+	return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
+}
+
+static struct id_reg_info id_aa64pfr0_el1_info = {
+	.sys_reg = SYS_ID_AA64PFR0_EL1,
+	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
+	.init = init_id_aa64pfr0_el1_info,
+	.validate = validate_id_aa64pfr0_el1,
+	.vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -326,7 +412,9 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
  * validation, etc.)
  */
 #define	GET_ID_REG_INFO(id)	(id_reg_info_table[IDREG_IDX(id)])
-static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
+static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
+	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
+};
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
 {
@@ -1161,12 +1249,12 @@ static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
 	return kvm->arch.id_regs[IDREG_IDX(id)];
 }
 
-static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
+static int __modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
 			     u64 preserve_mask)
 {
 	u64 old, new;
 
-	mutex_lock(&kvm->lock);
+	lockdep_assert_held(&kvm->lock);
 
 	old = kvm->arch.id_regs[IDREG_IDX(id)];
 
@@ -1179,11 +1267,21 @@ static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
 		return -EBUSY;
 
 	WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
-	mutex_unlock(&kvm->lock);
 
 	return 0;
 }
 
+static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
+			     u64 preserve_mask)
+{
+	int ret;
+
+	mutex_lock(&kvm->lock);
+	ret = __modify_kvm_id_reg(kvm, id, val, preserve_mask);
+	mutex_unlock(&kvm->lock);
+
+	return ret;
+}
 static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
 {
 	return modify_kvm_id_reg(kvm, id, val, 0);
@@ -1233,20 +1331,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
 	switch (id) {
-	case SYS_ID_AA64PFR0_EL1:
-		if (!vcpu_has_sve(vcpu))
-			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
-		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
-		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2);
-		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2);
-		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3);
-		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
-		if (irqchip_in_kernel(vcpu->kvm) &&
-		    vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
-			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
-			val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), 1);
-		}
-		break;
 	case SYS_ID_AA64PFR1_EL1:
 		if (!kvm_has_mte(vcpu->kvm))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
@@ -1347,48 +1431,6 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
 	return REG_HIDDEN;
 }
 
-static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
-			       const struct sys_reg_desc *rd,
-			       const struct kvm_one_reg *reg, void __user *uaddr)
-{
-	const u64 id = sys_reg_to_index(rd);
-	u8 csv2, csv3;
-	int err;
-	u64 val;
-
-	err = reg_from_user(&val, uaddr, id);
-	if (err)
-		return err;
-
-	/*
-	 * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
-	 * it doesn't promise more than what is actually provided (the
-	 * guest could otherwise be covered in ectoplasmic residue).
-	 */
-	csv2 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV2_SHIFT);
-	if (csv2 > 1 ||
-	    (csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED))
-		return -EINVAL;
-
-	/* Same thing for CSV3 */
-	csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT);
-	if (csv3 > 1 ||
-	    (csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED))
-		return -EINVAL;
-
-	/* We can only differ with CSV[23], and anything else is an error */
-	val ^= read_id_reg(vcpu, rd, false);
-	val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) |
-		 (0xFUL << ID_AA64PFR0_CSV3_SHIFT));
-	if (val)
-		return -EINVAL;
-
-	vcpu->kvm->arch.pfr0_csv2 = csv2;
-	vcpu->kvm->arch.pfr0_csv3 = csv3 ;
-
-	return 0;
-}
-
 /* cpufeature ID register user accessors */
 static int __get_id_reg(const struct kvm_vcpu *vcpu,
 			const struct sys_reg_desc *rd, void __user *uaddr,
@@ -1702,8 +1744,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	/* AArch64 ID registers */
 	/* CRm=4 */
-	{ SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = access_id_reg,
-	  .get_user = get_id_reg, .set_user = set_id_aa64pfr0_el1, },
+	ID_SANITISED(ID_AA64PFR0_EL1),
 	ID_SANITISED(ID_AA64PFR1_EL1),
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
@@ -3095,3 +3136,15 @@ void set_default_id_regs(struct kvm *kvm)
 		(void)write_kvm_id_reg(kvm, id, val);
 	}
 }
+
+/*
+ * Update the ID register's field with @fval for the guest.
+ * The caller is expected to hold the kvm->lock.
+ */
+int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval)
+{
+	u64 val = ((u64)fval & ARM64_FEATURE_FIELD_MASK) << field_shift;
+	u64 preserve_mask = ~(ARM64_FEATURE_FIELD_MASK << field_shift);
+
+	return __modify_kvm_id_reg(kvm, id, val, preserve_mask);
+}
diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index 0a06d0648970..28d9bf0e178c 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -116,6 +116,11 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
 	else
 		INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
 
+	if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
+		/* Set ID_AA64PFR0_EL1.GIC to 1 */
+		(void)kvm_set_id_reg_feature(kvm, SYS_ID_AA64PFR0_EL1,
+				     ID_AA64PFR0_GIC3, ID_AA64PFR0_GIC_SHIFT);
+
 out_unlock:
 	unlock_all_vcpus(kvm);
 	return ret;
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:47 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:47 -0800
Subject: [RFC PATCH v4 05/26] KVM: arm64: Make ID_AA64PFR1_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-6-reijiw@google.com>

This patch adds id_reg_info for ID_AA64PFR1_EL1 to make it writable
by userspace.

Return an error if userspace tries to set MTE field of the register
to a value that conflicts with KVM_CAP_ARM_MTE configuration for
the guest.
Skip fractional feature fields validation at present and they will
be handled by the following patches.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/sysreg.h |  1 +
 arch/arm64/kvm/sys_regs.c       | 42 +++++++++++++++++++++++++++++----
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index e26027817171..f55513002281 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -801,6 +801,7 @@
 #define ID_AA64PFR0_GIC3		0x1
 
 /* id_aa64pfr1 */
+#define ID_AA64PFR1_CSV2FRAC_SHIFT	32
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
 #define ID_AA64PFR1_RASFRAC_SHIFT	12
 #define ID_AA64PFR1_MTE_SHIFT		8
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1eb5c5fb614f..ae9ca341a2e4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -359,6 +359,21 @@ static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int validate_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
+				    const struct id_reg_info *id_reg, u64 val)
+{
+	bool kvm_mte = kvm_has_mte(vcpu->kvm);
+	unsigned int mte;
+
+	mte = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR1_MTE_SHIFT);
+
+	/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT. */
+	if (kvm_mte ^ (mte > 0))
+		return -EPERM;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -390,12 +405,24 @@ static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 	id_reg->vcpu_limit_val = limit;
 }
 
+static void init_id_aa64pfr1_el1_info(struct id_reg_info *id_reg)
+{
+	if (!system_supports_mte())
+		id_reg->vcpu_limit_val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
+}
+
 static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
 					 const struct id_reg_info *idr)
 {
 	return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
 }
 
+static u64 vcpu_mask_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu,
+					 const struct id_reg_info *idr)
+{
+	return kvm_has_mte(vcpu->kvm) ? 0 : (ARM64_FEATURE_MASK(ID_AA64PFR1_MTE));
+}
+
 static struct id_reg_info id_aa64pfr0_el1_info = {
 	.sys_reg = SYS_ID_AA64PFR0_EL1,
 	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
@@ -404,6 +431,16 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
 	.vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
 };
 
+static struct id_reg_info id_aa64pfr1_el1_info = {
+	.sys_reg = SYS_ID_AA64PFR1_EL1,
+	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR1_RASFRAC) |
+		       ARM64_FEATURE_MASK(ID_AA64PFR1_MPAMFRAC) |
+		       ARM64_FEATURE_MASK(ID_AA64PFR1_CSV2FRAC),
+	.init = init_id_aa64pfr1_el1_info,
+	.validate = validate_id_aa64pfr1_el1,
+	.vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -414,6 +451,7 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
 #define	GET_ID_REG_INFO(id)	(id_reg_info_table[IDREG_IDX(id)])
 static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
+	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
 };
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
@@ -1331,10 +1369,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
 	switch (id) {
-	case SYS_ID_AA64PFR1_EL1:
-		if (!kvm_has_mte(vcpu->kvm))
-			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
-		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
 			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) |
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:48 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:48 -0800
Subject: [RFC PATCH v4 06/26] KVM: arm64: Make ID_AA64ISAR0_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-7-reijiw@google.com>

This patch adds id_reg_info for ID_AA64ISAR0_EL1 to make it writable
by userspace.

Updating sm3, sm4, sha1, sha2 and sha3 fields are allowed only
if values of those fields follow Arm ARM.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ae9ca341a2e4..3f1313875be5 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -374,6 +374,29 @@ static int validate_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int validate_id_aa64isar0_el1(struct kvm_vcpu *vcpu,
+				     const struct id_reg_info *id_reg, u64 val)
+{
+	unsigned int sm3, sm4, sha1, sha2, sha3;
+
+	/* Run consistency checkings according to Arm ARM */
+	sm3 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM3_SHIFT);
+	sm4 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SM4_SHIFT);
+	if (sm3 != sm4)
+		return -EINVAL;
+
+	sha1 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA1_SHIFT);
+	sha2 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA2_SHIFT);
+	if ((sha1 == 0) ^ (sha2 == 0))
+		return -EINVAL;
+
+	sha3 = cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR0_SHA3_SHIFT);
+	if (((sha2 == 2) ^ (sha3 == 1)) || (!sha1 && sha3))
+		return -EINVAL;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -441,6 +464,11 @@ static struct id_reg_info id_aa64pfr1_el1_info = {
 	.vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
 };
 
+static struct id_reg_info id_aa64isar0_el1_info = {
+	.sys_reg = SYS_ID_AA64ISAR0_EL1,
+	.validate = validate_id_aa64isar0_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -452,6 +480,7 @@ static struct id_reg_info id_aa64pfr1_el1_info = {
 static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
+	[IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
 };
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:49 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:49 -0800
Subject: [RFC PATCH v4 07/26] KVM: arm64: Make ID_AA64ISAR1_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-8-reijiw@google.com>

This patch adds id_reg_info for ID_AA64ISAR1_EL1 to make it
writable by userspace.

Return an error if userspace tries to set PTRAUTH related fields
of the register to values that conflict with PTRAUTH configuration,
which was configured by KVM_ARM_VCPU_INIT, for the guest.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 77 +++++++++++++++++++++++++++++++++++----
 1 file changed, 69 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 3f1313875be5..2f79997016a4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -265,6 +265,24 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 		return read_zero(vcpu, p);
 }
 
+#define PTRAUTH_MASK	(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) |	\
+			 ARM64_FEATURE_MASK(ID_AA64ISAR1_API) | \
+			 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |	\
+			 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI))
+
+#define aa64isar1_has_apa(val)	\
+	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_APA_SHIFT) >= \
+	 ID_AA64ISAR1_APA_ARCHITECTED)
+#define aa64isar1_has_api(val)	\
+	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_API_SHIFT) >= \
+	 ID_AA64ISAR1_API_IMP_DEF)
+#define aa64isar1_has_gpa(val)	\
+	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPA_SHIFT) >= \
+	 ID_AA64ISAR1_GPA_ARCHITECTED)
+#define aa64isar1_has_gpi(val)	\
+	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \
+	 ID_AA64ISAR1_GPI_IMP_DEF)
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 
@@ -397,6 +415,36 @@ static int validate_id_aa64isar0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int validate_id_aa64isar1_el1(struct kvm_vcpu *vcpu,
+				     const struct id_reg_info *id_reg, u64 val)
+{
+	bool has_gpi, has_gpa, has_api, has_apa;
+	bool generic, address;
+
+	has_gpi = aa64isar1_has_gpi(val);
+	has_gpa = aa64isar1_has_gpa(val);
+	has_api = aa64isar1_has_api(val);
+	has_apa = aa64isar1_has_apa(val);
+	if ((has_gpi && has_gpa) || (has_api && has_apa))
+		return -EINVAL;
+
+	generic = has_gpi || has_gpa;
+	address = has_api || has_apa;
+	/*
+	 * Since the current KVM guest implementation works by enabling
+	 * both address/generic pointer authentication features,
+	 * return an error if they conflict.
+	 */
+	if (generic ^ address)
+		return -EPERM;
+
+	/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
+	if (vcpu_has_ptrauth(vcpu) ^ (generic && address))
+		return -EPERM;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -434,8 +482,14 @@ static void init_id_aa64pfr1_el1_info(struct id_reg_info *id_reg)
 		id_reg->vcpu_limit_val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
 }
 
+static void init_id_aa64isar1_el1_info(struct id_reg_info *id_reg)
+{
+	if (!system_has_full_ptr_auth())
+		id_reg->vcpu_limit_val &= ~PTRAUTH_MASK;
+}
+
 static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
-					 const struct id_reg_info *idr)
+				     const struct id_reg_info *idr)
 {
 	return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
 }
@@ -446,6 +500,12 @@ static u64 vcpu_mask_id_aa64pfr1_el1(const struct kvm_vcpu *vcpu,
 	return kvm_has_mte(vcpu->kvm) ? 0 : (ARM64_FEATURE_MASK(ID_AA64PFR1_MTE));
 }
 
+static u64 vcpu_mask_id_aa64isar1_el1(const struct kvm_vcpu *vcpu,
+					  const struct id_reg_info *idr)
+{
+	return vcpu_has_ptrauth(vcpu) ? 0 : PTRAUTH_MASK;
+}
+
 static struct id_reg_info id_aa64pfr0_el1_info = {
 	.sys_reg = SYS_ID_AA64PFR0_EL1,
 	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
@@ -469,6 +529,13 @@ static struct id_reg_info id_aa64isar0_el1_info = {
 	.validate = validate_id_aa64isar0_el1,
 };
 
+static struct id_reg_info id_aa64isar1_el1_info = {
+	.sys_reg = SYS_ID_AA64ISAR1_EL1,
+	.init = init_id_aa64isar1_el1_info,
+	.validate = validate_id_aa64isar1_el1,
+	.vcpu_mask = vcpu_mask_id_aa64isar1_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -481,6 +548,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
+	[IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
 };
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
@@ -1398,13 +1466,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
 	switch (id) {
-	case SYS_ID_AA64ISAR1_EL1:
-		if (!vcpu_has_ptrauth(vcpu))
-			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR1_APA) |
-				 ARM64_FEATURE_MASK(ID_AA64ISAR1_API) |
-				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
-				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
-		break;
 	case SYS_ID_AA64DFR0_EL1:
 		/* Limit debug to ARMv8.0 */
 		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:50 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:50 -0800
Subject: [RFC PATCH v4 08/26] KVM: arm64: Make ID_AA64MMFR0_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-9-reijiw@google.com>

This patch adds id_reg_info for ID_AA64MMFR0_EL1 to make it
writable by userspace.

Since ID_AA64MMFR0_EL1 stage 2 granule size fields don't follow the
standard ID scheme, we need a special handling to validate those fields.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 127 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 127 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 2f79997016a4..723910267966 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -445,6 +445,118 @@ static int validate_id_aa64isar1_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+/*
+ * Check if the requested stage2 translation granule size indicated in
+ * @mmfr0 is also indicated in @mmfr0_lim.
+ * If TGranX_2 field is zero, the value must be validated based on TGranX
+ * field because that indicates the feature support is identified in
+ * TGranX field.
+ * This function relies on the fact TGranX fields are validated before
+ * through the arm64_check_features.
+ */
+static int aa64mmfr0_tgran2_check(int field, u64 mmfr0, u64 mmfr0_lim)
+{
+	s64 tgran2, lim_tgran2, rtgran1;
+	int f1;
+	bool is_signed;
+
+	tgran2 = cpuid_feature_extract_unsigned_field(mmfr0, field);
+	lim_tgran2 = cpuid_feature_extract_unsigned_field(mmfr0_lim, field);
+	if (tgran2 && lim_tgran2)
+		/*
+		 * We don't need to check TGranX field. We can simply
+		 * compare tgran2 and lim_tgran2.
+		 */
+		return (tgran2 > lim_tgran2) ? -E2BIG : 0;
+
+	if (tgran2 == lim_tgran2)
+		/*
+		 * Both of them are zero.  Since TGranX in @mmfr0 is already
+		 * validated by arm64_check_features, tgran2 must be fine.
+		 */
+		return 0;
+
+	/*
+	 * Either tgran2 or lim_tgran2 is zero.
+	 * Need stage1 granule size to validate tgran2.
+	 */
+
+	/*
+	 * Get TGranX's bit position by subtracting 12 from TGranX_2's bit
+	 * position.
+	 */
+	f1 = field - 12;
+
+	/* TGran4/TGran64 is signed and TGran16 is unsigned field. */
+	is_signed = (f1 == ID_AA64MMFR0_TGRAN16_SHIFT) ? false : true;
+
+	/*
+	 * If tgran2 == 0 (&& lim_tgran2 != 0), the requested stage2 granule
+	 * size is indicated in the stage1 granule size field of @mmfr0.
+	 * So, validate the stage1 granule size against the stage2 limit
+	 * granule size.
+	 * If lim_tgran2 == 0 (&& tgran2 != 0), the stage2 limit granule size
+	 * is indicated in the stage1 granule size field of @mmfr0_lim.
+	 * So, validate the requested stage2 granule size against the stage1
+	 * limit granule size.
+	 */
+
+	 /* Get the relevant stage1 granule size to validate tgran2 */
+	if (tgran2 == 0)
+		/* The requested stage1 granule size */
+		rtgran1 = cpuid_feature_extract_field(mmfr0, f1, is_signed);
+	else /* lim_tgran2 == 0 */
+		/* The stage1 limit granule size */
+		rtgran1 = cpuid_feature_extract_field(mmfr0_lim, f1, is_signed);
+
+	/*
+	 * Adjust the value of rtgran1 to compare with stage2 granule size,
+	 * which indicates: 1: Not supported, 2: Supported, etc.
+	 */
+	if (is_signed)
+		/* For signed, -1: Not supported, 0: Supported, etc. */
+		rtgran1 += 0x2;
+	else
+		/* For unsigned, 0: Not supported, 1: Supported, etc. */
+		rtgran1 += 0x1;
+
+	if ((tgran2 == 0) && (rtgran1 > lim_tgran2))
+		/*
+		 * The requested stage1 granule size (== the requested stage2
+		 * granule size) is larger than the stage2 limit granule size.
+		 */
+		return -E2BIG;
+	else if ((lim_tgran2 == 0) && (tgran2 > rtgran1))
+		/*
+		 * The requested stage2 granule size is larger than the stage1
+		 * limit granulze size (== the stage2 limit granule size).
+		 */
+		return -E2BIG;
+
+	return 0;
+}
+
+static int validate_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu,
+				     const struct id_reg_info *id_reg, u64 val)
+{
+	u64 limit = id_reg->vcpu_limit_val;
+	int ret;
+
+	ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN4_2_SHIFT, val, limit);
+	if (ret)
+		return ret;
+
+	ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN64_2_SHIFT, val, limit);
+	if (ret)
+		return ret;
+
+	ret = aa64mmfr0_tgran2_check(ID_AA64MMFR0_TGRAN16_2_SHIFT, val, limit);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -536,6 +648,20 @@ static struct id_reg_info id_aa64isar1_el1_info = {
 	.vcpu_mask = vcpu_mask_id_aa64isar1_el1,
 };
 
+static struct id_reg_info id_aa64mmfr0_el1_info = {
+	.sys_reg = SYS_ID_AA64MMFR0_EL1,
+	/*
+	 * When TGranX_2 value is 0, validity of the value depend on TGranX
+	 * value, and TGranX_2 value must be validated against TGranX value,
+	 * which is done by validate_id_aa64mmfr0_el1.
+	 * So, skip the regular validity checking for TGranX_2 fields.
+	 */
+	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64MMFR0_TGRAN4_2) |
+		       ARM64_FEATURE_MASK(ID_AA64MMFR0_TGRAN64_2) |
+		       ARM64_FEATURE_MASK(ID_AA64MMFR0_TGRAN16_2),
+	.validate = validate_id_aa64mmfr0_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -549,6 +675,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
+	[IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info,
 };
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:51 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:51 -0800
Subject: [RFC PATCH v4 09/26] KVM: arm64: Hide IMPLEMENTATION DEFINED PMU
 support for the guest
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-10-reijiw@google.com>

When ID_AA64DFR0_EL1.PMUVER or ID_DFR0_EL1.PERFMON is 0xf, which
means IMPLEMENTATION DEFINED PMU supported, KVM unconditionally
expose the value for the guest as it is.  Since KVM doesn't support
IMPLEMENTATION DEFINED PMU for the guest, in that case KVM should
expose 0x0 (PMU is not implemented) instead.

Change cpuid_feature_cap_perfmon_field() to update the field value
to 0x0 when it is 0xf.

Fixes: 8e35aa642ee4 ("arm64: cpufeature: Extract capped perfmon fields")
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/cpufeature.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index eda7ddbed8cf..487ca7555c18 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -553,7 +553,7 @@ cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
 
 	/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
 	if (val == ID_AA64DFR0_PMUVER_IMP_DEF)
-		val = 0;
+		return (features & ~mask);
 
 	if (val > cap) {
 		features &= ~mask;
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:52 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:52 -0800
Subject: [RFC PATCH v4 10/26] KVM: arm64: Make ID_AA64DFR0_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-11-reijiw@google.com>

This patch adds id_reg_info for ID_AA64DFR0_EL1 to make it writable
by userspace.

Return an error if userspace tries to set PMUVER field of the
register to a value that conflicts with the PMU configuration.

Since number of context-aware breakpoints must be no more than number
of supported breakpoints according to Arm ARM, return an error
if userspace tries to set CTX_CMPS field to such value.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 83 +++++++++++++++++++++++++++++++++------
 1 file changed, 71 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 723910267966..9a9055d60223 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -557,6 +557,45 @@ static int validate_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static bool id_reg_has_pmu(u64 val, u64 shift, unsigned int min)
+{
+	unsigned int pmu = cpuid_feature_extract_unsigned_field(val, shift);
+
+	/*
+	 * Treat IMPLEMENTATION DEFINED functionality as unimplemented for
+	 * ID_AA64DFR0_EL1.PMUVer/ID_DFR0_EL1.PerfMon.
+	 */
+	if (pmu == 0xf)
+		pmu = 0;
+
+	return (pmu >= min);
+}
+
+static int validate_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
+				    const struct id_reg_info *id_reg, u64 val)
+{
+	unsigned int brps, ctx_cmps;
+	bool vcpu_pmu, dfr0_pmu;
+
+	brps = cpuid_feature_extract_unsigned_field(val, ID_AA64DFR0_BRPS_SHIFT);
+	ctx_cmps = cpuid_feature_extract_unsigned_field(val, ID_AA64DFR0_CTX_CMPS_SHIFT);
+
+	/*
+	 * Number of context-aware breakpoints can be no more than number of
+	 * supported breakpoints.
+	 */
+	if (ctx_cmps > brps)
+		return -EINVAL;
+
+	vcpu_pmu = kvm_vcpu_has_pmu(vcpu);
+	dfr0_pmu = id_reg_has_pmu(val, ID_AA64DFR0_PMUVER_SHIFT, ID_AA64DFR0_PMUVER_8_0);
+	/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
+	if (vcpu_pmu ^ dfr0_pmu)
+		return -EPERM;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -600,8 +639,25 @@ static void init_id_aa64isar1_el1_info(struct id_reg_info *id_reg)
 		id_reg->vcpu_limit_val &= ~PTRAUTH_MASK;
 }
 
+static void init_id_aa64dfr0_el1_info(struct id_reg_info *id_reg)
+{
+	u64 limit = id_reg->vcpu_limit_val;
+
+	/* Limit guests to PMUv3 for ARMv8.4 */
+	limit = cpuid_feature_cap_perfmon_field(limit, ID_AA64DFR0_PMUVER_SHIFT,
+						ID_AA64DFR0_PMUVER_8_4);
+	/* Limit debug to ARMv8.0 */
+	limit &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
+	limit |= (FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6));
+
+	/* Hide SPE from guests */
+	limit &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER);
+
+	id_reg->vcpu_limit_val = limit;
+}
+
 static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
-				     const struct id_reg_info *idr)
+					 const struct id_reg_info *idr)
 {
 	return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
 }
@@ -618,6 +674,12 @@ static u64 vcpu_mask_id_aa64isar1_el1(const struct kvm_vcpu *vcpu,
 	return vcpu_has_ptrauth(vcpu) ? 0 : PTRAUTH_MASK;
 }
 
+static u64 vcpu_mask_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu,
+					 const struct id_reg_info *idr)
+{
+	return kvm_vcpu_has_pmu(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER);
+}
+
 static struct id_reg_info id_aa64pfr0_el1_info = {
 	.sys_reg = SYS_ID_AA64PFR0_EL1,
 	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
@@ -662,6 +724,13 @@ static struct id_reg_info id_aa64mmfr0_el1_info = {
 	.validate = validate_id_aa64mmfr0_el1,
 };
 
+static struct id_reg_info id_aa64dfr0_el1_info = {
+	.sys_reg = SYS_ID_AA64DFR0_EL1,
+	.init = init_id_aa64dfr0_el1_info,
+	.validate = validate_id_aa64dfr0_el1,
+	.vcpu_mask = vcpu_mask_id_aa64dfr0_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -673,6 +742,7 @@ static struct id_reg_info id_aa64mmfr0_el1_info = {
 static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
+	[IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info,
@@ -1593,17 +1663,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
 	switch (id) {
-	case SYS_ID_AA64DFR0_EL1:
-		/* Limit debug to ARMv8.0 */
-		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
-		val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER), 6);
-		/* Limit guests to PMUv3 for ARMv8.4 */
-		val = cpuid_feature_cap_perfmon_field(val,
-						      ID_AA64DFR0_PMUVER_SHIFT,
-						      kvm_vcpu_has_pmu(vcpu) ? ID_AA64DFR0_PMUVER_8_4 : 0);
-		/* Hide SPE from guests */
-		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_PMSVER);
-		break;
 	case SYS_ID_DFR0_EL1:
 		/* Limit guests to PMUv3 for ARMv8.4 */
 		val = cpuid_feature_cap_perfmon_field(val,
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:53 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:53 -0800
Subject: [RFC PATCH v4 11/26] KVM: arm64: Make ID_DFR0_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-12-reijiw@google.com>

This patch adds id_reg_info for ID_DFR0_EL1 to make it writable
by userspace.

Return an error if userspace tries to set PerfMon field of the
register to a value that conflicts with the PMU configuration.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 55 ++++++++++++++++++++++++++++++++-------
 1 file changed, 45 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9a9055d60223..1707c7832593 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -596,6 +596,27 @@ static int validate_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int validate_id_dfr0_el1(struct kvm_vcpu *vcpu,
+				const struct id_reg_info *id_reg, u64 val)
+{
+	bool vcpu_pmu, dfr0_pmu;
+	unsigned int perfmon;
+
+	perfmon = cpuid_feature_extract_unsigned_field(val, ID_DFR0_PERFMON_SHIFT);
+	if (perfmon == 1 || perfmon == 2)
+		/* PMUv1 or PMUv2 is not allowed on ARMv8. */
+		return -EINVAL;
+
+	vcpu_pmu = kvm_vcpu_has_pmu(vcpu);
+	dfr0_pmu = id_reg_has_pmu(val, ID_DFR0_PERFMON_SHIFT, ID_DFR0_PERFMON_8_0);
+
+	/* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
+	if (vcpu_pmu ^ dfr0_pmu)
+		return -EPERM;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -656,8 +677,17 @@ static void init_id_aa64dfr0_el1_info(struct id_reg_info *id_reg)
 	id_reg->vcpu_limit_val = limit;
 }
 
+static void init_id_dfr0_el1_info(struct id_reg_info *id_reg)
+{
+	/* Limit guests to PMUv3 for ARMv8.4 */
+	id_reg->vcpu_limit_val =
+		cpuid_feature_cap_perfmon_field(id_reg->vcpu_limit_val,
+						ID_DFR0_PERFMON_SHIFT,
+						ID_DFR0_PERFMON_8_4);
+}
+
 static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
-					 const struct id_reg_info *idr)
+				     const struct id_reg_info *idr)
 {
 	return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
 }
@@ -680,6 +710,12 @@ static u64 vcpu_mask_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu,
 	return kvm_vcpu_has_pmu(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64DFR0_PMUVER);
 }
 
+static u64 vcpu_mask_id_dfr0_el1(const struct kvm_vcpu *vcpu,
+				     const struct id_reg_info *idr)
+{
+	return kvm_vcpu_has_pmu(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_DFR0_PERFMON);
+}
+
 static struct id_reg_info id_aa64pfr0_el1_info = {
 	.sys_reg = SYS_ID_AA64PFR0_EL1,
 	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
@@ -731,6 +767,13 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
 	.vcpu_mask = vcpu_mask_id_aa64dfr0_el1,
 };
 
+static struct id_reg_info id_dfr0_el1_info = {
+	.sys_reg = SYS_ID_DFR0_EL1,
+	.init = init_id_dfr0_el1_info,
+	.validate = validate_id_dfr0_el1,
+	.vcpu_mask = vcpu_mask_id_dfr0_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -740,6 +783,7 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
  */
 #define	GET_ID_REG_INFO(id)	(id_reg_info_table[IDREG_IDX(id)])
 static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
+	[IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info,
@@ -1662,15 +1706,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		/* Clear fields for opt-in features that are not configured. */
 		val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
 
-	switch (id) {
-	case SYS_ID_DFR0_EL1:
-		/* Limit guests to PMUv3 for ARMv8.4 */
-		val = cpuid_feature_cap_perfmon_field(val,
-						      ID_DFR0_PERFMON_SHIFT,
-						      kvm_vcpu_has_pmu(vcpu) ? ID_DFR0_PERFMON_8_4 : 0);
-		break;
-	}
-
 	return val;
 }
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:54 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:54 -0800
Subject: [RFC PATCH v4 12/26] KVM: arm64: Make MVFR1_EL1 writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-13-reijiw@google.com>

This patch adds id_reg_info for MVFR1_EL1 to make it writable
by userspace.

There are only a few valid combinations of values that can be set
for FPHP and SIMDHP fields according to Arm ARM.  Return an error
when userspace tries to set those fields to values that don't match
any of the valid combinations.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1707c7832593..1c18a19c5785 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -617,6 +617,36 @@ static int validate_id_dfr0_el1(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
+static int validate_mvfr1_el1(struct kvm_vcpu *vcpu,
+			      const struct id_reg_info *id_reg, u64 val)
+{
+	unsigned int fphp, simdhp;
+	struct fphp_simdhp {
+		unsigned int fphp;
+		unsigned int simdhp;
+	};
+	/* Permitted fphp/simdhp value combinations according to Arm ARM */
+	struct fphp_simdhp valid_fphp_simdhp[3] = {{0, 0}, {2, 1}, {3, 2}};
+	int i;
+	bool is_valid_fphp_simdhp = false;
+
+	fphp = cpuid_feature_extract_unsigned_field(val, MVFR1_FPHP_SHIFT);
+	simdhp = cpuid_feature_extract_unsigned_field(val, MVFR1_SIMDHP_SHIFT);
+
+	for (i = 0; i < ARRAY_SIZE(valid_fphp_simdhp); i++) {
+		if (valid_fphp_simdhp[i].fphp == fphp &&
+		    valid_fphp_simdhp[i].simdhp == simdhp) {
+			is_valid_fphp_simdhp = true;
+			break;
+		}
+	}
+
+	if (!is_valid_fphp_simdhp)
+		return -EINVAL;
+
+	return 0;
+}
+
 static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
 {
 	u64 limit = id_reg->vcpu_limit_val;
@@ -774,6 +804,11 @@ static struct id_reg_info id_dfr0_el1_info = {
 	.vcpu_mask = vcpu_mask_id_dfr0_el1,
 };
 
+static struct id_reg_info mvfr1_el1_info = {
+	.sys_reg = SYS_MVFR1_EL1,
+	.validate = validate_mvfr1_el1,
+};
+
 /*
  * An ID register that needs special handling to control the value for the
  * guest must have its own id_reg_info in id_reg_info_table.
@@ -784,6 +819,7 @@ static struct id_reg_info id_dfr0_el1_info = {
 #define	GET_ID_REG_INFO(id)	(id_reg_info_table[IDREG_IDX(id)])
 static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_DFR0_EL1)] = &id_dfr0_el1_info,
+	[IDREG_IDX(SYS_MVFR1_EL1)] = &mvfr1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64PFR1_EL1)] = &id_aa64pfr1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64DFR0_EL1)] = &id_aa64dfr0_el1_info,
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:55 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:55 -0800
Subject: [RFC PATCH v4 13/26] KVM: arm64: Make ID registers without
 id_reg_info writable
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-14-reijiw@google.com>

Make ID registers that don't have id_reg_info writable.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 1c18a19c5785..ddbeefc3881c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1859,11 +1859,8 @@ static int __set_id_reg(struct kvm_vcpu *vcpu,
 		/* The value is same as the current value. Nothing to do. */
 		return 0;
 
-	/*
-	 * Don't allow to modify the register's value if the register is raz,
-	 * or the reg doesn't have the id_reg_info.
-	 */
-	if (raz || !GET_ID_REG_INFO(encoding))
+	/* Don't allow to modify the register's value if the register is raz. */
+	if (raz)
 		return -EINVAL;
 
 	/*
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:56 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:56 -0800
Subject: [RFC PATCH v4 14/26] KVM: arm64: Add consistency checking for frac
 fields of ID registers
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-15-reijiw@google.com>

Feature fractional field of an ID register cannot be simply validated
at KVM_SET_ONE_REG because its validity depends on its (main) feature
field value, which could be in a different ID register (and might be
set later).
Validate fractional fields at the first KVM_RUN instead.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_host.h |   1 +
 arch/arm64/kvm/arm.c              |   3 +
 arch/arm64/kvm/sys_regs.c         | 116 +++++++++++++++++++++++++++++-
 3 files changed, 117 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4509f9e7472d..7b3f86bd6a6b 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -750,6 +750,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 
 void set_default_id_regs(struct kvm *kvm);
 int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
+int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu);
 
 /* Guest/host FPSIMD coordination helpers */
 int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 5f497a0af254..16fc2ce32069 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -596,6 +596,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 	if (!kvm_arm_vcpu_is_finalized(vcpu))
 		return -EPERM;
 
+	if (!kvm_vm_is_protected(kvm) && kvm_id_regs_consistency_check(vcpu))
+		return -EPERM;
+
 	vcpu->arch.has_run_once = true;
 
 	kvm_arm_vcpu_init_debug(vcpu);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ddbeefc3881c..6adb7b04620c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -756,9 +756,6 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
 
 static struct id_reg_info id_aa64pfr1_el1_info = {
 	.sys_reg = SYS_ID_AA64PFR1_EL1,
-	.ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR1_RASFRAC) |
-		       ARM64_FEATURE_MASK(ID_AA64PFR1_MPAMFRAC) |
-		       ARM64_FEATURE_MASK(ID_AA64PFR1_CSV2FRAC),
 	.init = init_id_aa64pfr1_el1_info,
 	.validate = validate_id_aa64pfr1_el1,
 	.vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
@@ -3434,10 +3431,109 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	return write_demux_regids(uindices);
 }
 
+/* ID register's fractional field information with its feature field. */
+struct feature_frac {
+	u32	id;
+	u32	shift;
+	u32	frac_id;
+	u32	frac_shift;
+	u8	frac_ftr_check;
+};
+
+static struct feature_frac feature_frac_table[] = {
+	{
+		.frac_id = SYS_ID_AA64PFR1_EL1,
+		.frac_shift = ID_AA64PFR1_RASFRAC_SHIFT,
+		.id = SYS_ID_AA64PFR0_EL1,
+		.shift = ID_AA64PFR0_RAS_SHIFT,
+	},
+	{
+		.frac_id = SYS_ID_AA64PFR1_EL1,
+		.frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT,
+		.id = SYS_ID_AA64PFR0_EL1,
+		.shift = ID_AA64PFR0_MPAM_SHIFT,
+	},
+	{
+		.frac_id = SYS_ID_AA64PFR1_EL1,
+		.frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT,
+		.id = SYS_ID_AA64PFR0_EL1,
+		.shift = ID_AA64PFR0_CSV2_SHIFT,
+	},
+};
+
+/*
+ * Return non-zero if the feature/fractional fields pair are not
+ * supported. Return zero otherwise.
+ * This function validates only the fractional feature field,
+ * and relies on the fact the feature field is validated before
+ * through arm64_check_features.
+ */
+static int vcpu_id_reg_feature_frac_check(const struct kvm_vcpu *vcpu,
+					  const struct feature_frac *ftr_frac)
+{
+	const struct id_reg_info *id_reg;
+	u32 id;
+	u64 val, lim, mask;
+
+	/* Check if the feature field value is same as the limit */
+	id = ftr_frac->id;
+	id_reg = GET_ID_REG_INFO(id);
+
+	mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->shift;
+	val = __read_id_reg(vcpu, id) & mask;
+	lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
+	lim &= mask;
+
+	if (val != lim)
+		/*
+		 * The feature level is lower than the limit.
+		 * Any fractional version should be fine.
+		 */
+		return 0;
+
+	/* Check the fractional feature field */
+	id = ftr_frac->frac_id;
+	id_reg = GET_ID_REG_INFO(id);
+
+	mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->frac_shift;
+	val = __read_id_reg(vcpu, id) & mask;
+	lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
+	lim &= mask;
+
+	if (val == lim)
+		/*
+		 * Both the feature and fractional fields are the same
+		 * as limit.
+		 */
+		return 0;
+
+	return arm64_check_features(id, val, lim);
+}
+
+int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu)
+{
+	int i, err;
+	const struct feature_frac *frac;
+
+	/*
+	 * Check ID registers' fractional fields, which aren't checked
+	 * at KVM_SET_ONE_REG.
+	 */
+	for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) {
+		frac = &feature_frac_table[i];
+		err = vcpu_id_reg_feature_frac_check(vcpu, frac);
+		if (err)
+			return err;
+	}
+	return 0;
+}
+
 static void id_reg_info_init_all(void)
 {
 	int i;
 	struct id_reg_info *id_reg;
+	struct feature_frac *frac;
+	u64 ftr_mask = ARM64_FEATURE_FIELD_MASK;
 
 	for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) {
 		id_reg = (struct id_reg_info *)id_reg_info_table[i];
@@ -3446,6 +3542,20 @@ static void id_reg_info_init_all(void)
 
 		id_reg_info_init(id_reg);
 	}
+
+	/*
+	 * Update ignore_mask of ID registers based on fractional fields
+	 * information.  Any ID register that have fractional fields
+	 * is expected to have its own id_reg_info.
+	 */
+	for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) {
+		frac = &feature_frac_table[i];
+		id_reg = GET_ID_REG_INFO(frac->frac_id);
+		if (WARN_ON_ONCE(!id_reg))
+			continue;
+
+		id_reg->ignore_mask |= ftr_mask << frac->frac_shift;
+	}
 }
 
 void kvm_sys_reg_table_init(void)
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:57 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:57 -0800
Subject: [RFC PATCH v4 15/26] KVM: arm64: Introduce
 KVM_CAP_ARM_ID_REG_CONFIGURABLE capability
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-16-reijiw@google.com>

Introduce a new capability KVM_CAP_ARM_ID_REG_CONFIGURABLE to indicate
that ID registers are writable by userspace.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 Documentation/virt/kvm/api.rst | 12 ++++++++++++
 arch/arm64/kvm/arm.c           |  1 +
 include/uapi/linux/kvm.h       |  1 +
 3 files changed, 14 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index aeeb071c7688..86099a9b0bae 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -2574,6 +2574,10 @@ EINVAL.
 After the vcpu's SVE configuration is finalized, further attempts to
 write this register will fail with EPERM.
 
+The arm64 ID registers (where Op0=3, Op1=0, CRn=0, 0<=CRm<8, 0<=Op2<8)
+are allowed to set by userspace if KVM_CAP_ARM_ID_REG_CONFIGURABLE is
+available.  They become immutable after calling KVM_RUN on any of the
+vcpus in the guest (modifying values of those registers will fail).
 
 MIPS registers are mapped using the lower 32 bits.  The upper 16 of that is
 the register group type:
@@ -7484,3 +7488,11 @@ The argument to KVM_ENABLE_CAP is also a bitmask, and must be a subset
 of the result of KVM_CHECK_EXTENSION.  KVM will forward to userspace
 the hypercalls whose corresponding bit is in the argument, and return
 ENOSYS for the others.
+
+8.35 KVM_CAP_ARM_ID_REG_CONFIGURABLE
+------------------------------------
+
+:Architectures: arm64
+
+This capability indicates that userspace can modify the ID registers
+via KVM_SET_ONE_REG ioctl.
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 16fc2ce32069..876f2777acf2 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -216,6 +216,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_SET_GUEST_DEBUG:
 	case KVM_CAP_VCPU_ATTRIBUTES:
 	case KVM_CAP_PTP_KVM:
+	case KVM_CAP_ARM_ID_REG_CONFIGURABLE:
 		r = 1;
 		break;
 	case KVM_CAP_SET_GUEST_DEBUG2:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 1daa45268de2..9697c06a7f5b 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1131,6 +1131,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_ARM_ID_REG_CONFIGURABLE 207
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:59 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:59 -0800
Subject: [RFC PATCH v4 17/26] KVM: arm64: Use vcpu->arch cptr_el2 to track
 value of cptr_el2 for VHE
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-18-reijiw@google.com>

Track the baseline guest value for cptr_el2 in struct kvm_vcpu_arch
for VHE.  Use this value when setting cptr_el2 for the guest.

Currently this value is unchanged, but the following patches will set
trapping bits based on features supported for the guest.

No functional change intended.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 16 ++++++++++++++++
 arch/arm64/kvm/arm.c             |  5 ++++-
 arch/arm64/kvm/hyp/vhe/switch.c  | 14 ++------------
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..8ab6ea038721 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -288,6 +288,22 @@
 				 GENMASK(19, 14) |	\
 				 BIT(11))
 
+/*
+ * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
+ * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
+ * except for some missing controls, such as TAM.
+ * In this case, CPTR_EL2.TAM has the same position with or without
+ * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
+ * shift value for trapping the AMU accesses.
+ */
+#define CPTR_EL2_VHE_GUEST_DEFAULT	(CPACR_EL1_TTA | CPTR_EL2_TAM)
+
+/*
+ * Bits that are copied from vcpu->arch.cptr_el2 to set cptr_el2 for
+ * guest with VHE.
+ */
+#define CPTR_EL2_VHE_GUEST_TRACKED_MASK	(CPACR_EL1_TTA | CPTR_EL2_TAM)
+
 /* Hyp Debug Configuration Register bits */
 #define MDCR_EL2_E2TB_MASK	(UL(0x3))
 #define MDCR_EL2_E2TB_SHIFT	(UL(24))
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 876f2777acf2..3700144f6271 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1136,7 +1136,10 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu_reset_hcr(vcpu);
-	vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT;
+	if (has_vhe())
+		vcpu->arch.cptr_el2 = CPTR_EL2_VHE_GUEST_DEFAULT;
+	else
+		vcpu->arch.cptr_el2 = CPTR_EL2_DEFAULT;
 
 	/*
 	 * Handle the "start in power-off" case.
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index fbb26b93c347..572b2669ae84 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,20 +38,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	___activate_traps(vcpu);
 
 	val = read_sysreg(cpacr_el1);
-	val |= CPACR_EL1_TTA;
+	val &= ~CPTR_EL2_VHE_GUEST_TRACKED_MASK;
+	val |= (vcpu->arch.cptr_el2 & CPTR_EL2_VHE_GUEST_TRACKED_MASK);
 	val &= ~CPACR_EL1_ZEN;
 
-	/*
-	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
-	 * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
-	 * except for some missing controls, such as TAM.
-	 * In this case, CPTR_EL2.TAM has the same position with or without
-	 * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
-	 * shift value for trapping the AMU accesses.
-	 */
-
-	val |= CPTR_EL2_TAM;
-
 	if (update_fp_enabled(vcpu)) {
 		if (vcpu_has_sve(vcpu))
 			val |= CPACR_EL1_ZEN;
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:26:58 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:26:58 -0800
Subject: [RFC PATCH v4 16/26] KVM: arm64: Add kunit test for ID register
 validation
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-17-reijiw@google.com>

Add kunit tests for functions that are used for validation of ID
registers, CONFIG_KVM_KUNIT_TEST option to enable the tests, and
.kunitconfig to run the kunit tests.

One line change below is needed in the default arm64.py to fully
run all of those kunit tests.
-----------------------------------------------------------------------
$ diff tools/testing/kunit/qemu_configs/arm64.py arm64_kvm_min.py
12c12
< 			   extra_qemu_params=['-machine virt', '-cpu cortex-a57'])
---
> 			   extra_qemu_params=['-M virt,virtualization=on,mte=on', '-cpu max,sve=on'])
-----------------------------------------------------------------------

The outputs from the tests are:
-----------------------------------------------------------------------
$ tools/testing/kunit/kunit.py run --timeout=60 --jobs=`nproc --all` \
          --arch=arm64 --cross_compile=aarch64-linux-gnu- \
          --qemu_config arm64_kvm_min.py \
          --kunitconfig=arch/arm64/kvm/.kunitconfig
[12:14:24] Configuring KUnit Kernel ...
[12:14:24] Building KUnit Kernel ...
Populating config with:
$ make ARCH=arm64 olddefconfig CROSS_COMPILE=aarch64-linux-gnu- O=.kunit
Building with:
$ make ARCH=arm64 --jobs=96 CROSS_COMPILE=aarch64-linux-gnu- O=.kunit
[12:14:31] Starting KUnit Kernel (1/1)...
[12:14:31] ============================================================
Running tests with:
$ qemu-system-aarch64 -nodefaults -m 1024 -kernel .kunit/arch/arm64/boot/Image.gz -append 'mem=1G console=tty kunit_shutdown=halt console=ttyAMA0 kunit_shutdown=reboot' -no-reboot -nographic -serial stdio -M virt,virtualization=on,mte=on -cpu max,sve=on
[12:14:32] ========== kvm-sys-regs-test-suite (13 subtests) ===========
[12:14:32] [PASSED] vcpu_id_reg_feature_frac_check_test
[12:14:32] [PASSED] validate_id_aa64mmfr0_tgran2_test
[12:14:32] [PASSED] validate_id_aa64mmfr0_tgran2_test
[12:14:32] [PASSED] validate_id_aa64mmfr0_tgran2_test
[12:14:32] [PASSED] validate_id_aa64pfr0_el1_test
[12:14:32] [PASSED] validate_id_aa64pfr1_el1_test
[12:14:32] [PASSED] validate_id_aa64isar0_el1_test
[12:14:32] [PASSED] validate_id_aa64isar1_el1_test
[12:14:32] [PASSED] validate_id_aa64mmfr0_el1_test
[12:14:32] [PASSED] validate_id_aa64dfr0_el1_test
[12:14:32] [PASSED] validate_id_dfr0_el1_test
[12:14:32] [PASSED] validate_mvfr1_el1_test
[12:14:32] [PASSED] validate_id_reg_test
[12:14:32] ============= [PASSED] kvm-sys-regs-test-suite =============
[12:14:32] ============================================================
[12:14:32] Testing complete. Passed: 13, Failed: 0, Crashed: 0, Skipped: 0, Errors: 0
[12:14:32] Elapsed time: 8.223s total, 0.002s configuring, 6.655s building, 1.565s running
-----------------------------------------------------------------------

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/.kunitconfig    |   4 +
 arch/arm64/kvm/Kconfig         |  11 +
 arch/arm64/kvm/sys_regs.c      |   4 +
 arch/arm64/kvm/sys_regs_test.c | 985 +++++++++++++++++++++++++++++++++
 4 files changed, 1004 insertions(+)
 create mode 100644 arch/arm64/kvm/.kunitconfig
 create mode 100644 arch/arm64/kvm/sys_regs_test.c

diff --git a/arch/arm64/kvm/.kunitconfig b/arch/arm64/kvm/.kunitconfig
new file mode 100644
index 000000000000..c564c98fc319
--- /dev/null
+++ b/arch/arm64/kvm/.kunitconfig
@@ -0,0 +1,4 @@
+CONFIG_KUNIT=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_KVM_KUNIT_TEST=y
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 8ffcbe29395e..48fbdd17b2fd 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -54,4 +54,15 @@ config NVHE_EL2_DEBUG
 
 	  If unsure, say N.
 
+config KVM_KUNIT_TEST
+	bool "KUnit tests for KVM on ARM64 processors" if !KUNIT_ALL_TESTS
+	depends on KVM && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Say Y here to enable KUnit tests for the KVM on ARM64.
+	  Only useful for KVM/ARM development and are not for inclusion into
+	  a production build.
+
+	  If unsure, say N.
+
 endif # VIRTUALIZATION
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 6adb7b04620c..d5bd04c68cd4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3636,3 +3636,7 @@ int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval)
 
 	return __modify_kvm_id_reg(kvm, id, val, preserve_mask);
 }
+
+#if IS_ENABLED(CONFIG_KVM_KUNIT_TEST)
+#include "sys_regs_test.c"
+#endif
diff --git a/arch/arm64/kvm/sys_regs_test.c b/arch/arm64/kvm/sys_regs_test.c
new file mode 100644
index 000000000000..5b1b95bd9ec4
--- /dev/null
+++ b/arch/arm64/kvm/sys_regs_test.c
@@ -0,0 +1,985 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * KUnit tests for arch/arm64/kvm/sys_regs.c.
+ */
+
+#include <linux/module.h>
+#include <kunit/test.h>
+#include <kunit/test.h>
+#include <linux/kvm_host.h>
+#include <asm/cpufeature.h>
+#include "asm/sysreg.h"
+
+/*
+ * Create a vcpu with the minimum fields required for testing in this file
+ * including the struct kvm.  Any resources that are allocated by this
+ * function must be allocated by kunit_* so that we don't need to explicitly
+ * free them.
+ */
+static struct kvm_vcpu *test_kvm_vcpu_init(struct kunit *test)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm *kvm;
+
+	kvm = kunit_kzalloc(test, sizeof(struct kvm), GFP_KERNEL);
+	if (!kvm)
+		return NULL;
+
+	vcpu = kunit_kzalloc(test, sizeof(struct kvm_vcpu), GFP_KERNEL);
+	if (!vcpu) {
+		kunit_kfree(test, kvm);
+		return NULL;
+	}
+
+	vcpu->cpu = -1;
+	vcpu->kvm = kvm;
+	vcpu->vcpu_id = 0;
+
+	return vcpu;
+}
+
+static void test_kvm_vcpu_fini(struct kunit *test, struct kvm_vcpu *vcpu)
+{
+	if (vcpu->kvm)
+		kunit_kfree(test, vcpu->kvm);
+
+	kunit_kfree(test, vcpu);
+}
+
+/* Test parameter information to test arm64_check_features */
+struct check_features_test {
+	u64	check_types;
+	u64	value;
+	u64	limit;
+	int	expected;
+};
+
+
+/* Used to define test parameters of vcpu_id_reg_feature_frac_check_test() */
+struct feat_info {
+	u32	id;
+	u32	shift;
+	u32	value;
+	u32	limit;
+};
+
+struct frac_check_test {
+	struct feat_info feat;
+	struct feat_info frac_feat;
+	int ret;
+};
+
+#define	FRAC_FEAT(id, shift, value, limit)	{id, shift, value, limit}
+
+/* Tests parameters of vcpu_id_reg_feature_frac_check_test() */
+struct frac_check_test frac_params[] = {
+	{
+		/*
+		 * The feature value is smaller than its limit.
+		 * Expect no error regardless of the frac value.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 2),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 1, 1),
+		0,
+	},
+	{
+		/*
+		 * The feature value is smaller than its limit.
+		 * Expect no error regardless of the frac value.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 2),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 1, 2),
+		0,
+	},
+	{
+		/*
+		 * The feature value is smaller than its limit.
+		 * Expect no error regardless of the frac value.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 2),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 2, 1),
+		0,
+	},
+	{
+		/*
+		 * Both the feature and frac values are same as their limits.
+		 * Expect no error.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 1),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 1, 1),
+		0,
+	},
+	{
+		/*
+		 * The feature value is same as its limit, and the frac value
+		 * is smaller than its limit. Expect no error.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 1),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 1, 2),
+		0,
+	},
+	{
+		/*
+		 * The feature value is same as its limit, and the frac value
+		 * is larger than its limit. Expect an error.
+		 */
+		FRAC_FEAT(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_RAS_SHIFT, 1, 1),
+		FRAC_FEAT(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_RASFRAC_SHIFT, 2, 1),
+		-E2BIG,
+	},
+
+};
+
+static void frac_case_to_desc(struct frac_check_test *t, char *desc)
+{
+	struct feat_info *feat = &t->feat;
+	struct feat_info *frac = &t->frac_feat;
+
+	snprintf(desc, KUNIT_PARAM_DESC_SIZE,
+		 "feat - shift:%d, val:%d, lim:%d, frac - shift:%d, val:%d, lim:%d\n",
+		 feat->shift, feat->value, feat->limit,
+		 frac->shift, frac->value, frac->limit);
+}
+
+KUNIT_ARRAY_PARAM(frac, frac_params, frac_case_to_desc);
+
+/* Tests for vcpu_id_reg_feature_frac_check(). */
+static void vcpu_id_reg_feature_frac_check_test(struct kunit *test)
+{
+	struct kvm_vcpu *vcpu;
+	u32 id, frac_id;
+	struct id_reg_info id_data, frac_id_data;
+	struct id_reg_info *idr, *frac_idr;
+	struct feature_frac frac_data, *frac = &frac_data;
+	const struct frac_check_test *frct = test->param_value;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	id = frct->feat.id;
+	frac_id = frct->frac_feat.id;
+
+	frac->id = id;
+	frac->shift = frct->feat.shift;
+	frac->frac_id = frac_id;
+	frac->frac_shift = frct->frac_feat.shift;
+
+	idr = GET_ID_REG_INFO(id);
+	frac_idr = GET_ID_REG_INFO(frac_id);
+
+	/* Save the original id_reg_info (and restore later) */
+	memcpy(&id_data, idr, sizeof(id_data));
+	memcpy(&frac_id_data, frac_idr, sizeof(frac_id_data));
+
+	/* The id could be same as the frac_id */
+	idr->vcpu_limit_val = (u64)frct->feat.limit << frac->shift;
+	frac_idr->vcpu_limit_val |=
+			(u64)frct->frac_feat.limit << frac->frac_shift;
+
+	write_kvm_id_reg(vcpu->kvm, id, (u64)frct->feat.value << frac->shift);
+	write_kvm_id_reg(vcpu->kvm, frac_id,
+			  (u64)frct->frac_feat.value << frac->frac_shift);
+
+	KUNIT_EXPECT_EQ(test,
+			vcpu_id_reg_feature_frac_check(vcpu, frac),
+			frct->ret);
+
+	/* Restore id_reg_info */
+	memcpy(idr, &id_data, sizeof(id_data));
+	memcpy(frac_idr, &frac_id_data, sizeof(frac_id_data));
+}
+
+/*
+ * Test parameter information to test validate_id_aa64mmfr0_tgran2
+ * and validate_id_aa64mmfr0_el1_test.
+ */
+struct tgran_test {
+	int gran2_field;
+	int gran2;
+	int gran2_lim;
+	int gran1;
+	int gran1_lim;
+	int ret;
+};
+
+/*
+ * Test parameters of validate_id_aa64mmfr0_tgran2_test() for TGran4_2.
+ * Defined values for the field are:
+ *  0x0: Support for 4KB granule at stage 2 is identified in TGran4.
+ *  0x1: 4KB granule not supported at stage 2.
+ *  0x2: 4KB granule supported at stage 2.
+ *  0x3: 4KB granule at stage 2 supports 52-bit input and output addresses.
+ *
+ * Defined values for the TGran4 are:
+ *  0x0: 4KB granule supported.
+ *  0x1: 4KB granule supports 52-bit input and output addresses.
+ *  0xf: 4KB granule not supported.
+ */
+struct tgran_test tgran4_2_test_params[] = {
+	/* Enable 4KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 2, 2,  0,   0, 0},
+	/* Enable 4KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 2, 1,  0,   0, -E2BIG},
+	/* Disable 4KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 1, 2,  0,   0, 0},
+	/* Enable 4KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 0, 0,  0,   0, 0},
+	/* Disable 4KB granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 0, 1, 0xf,   0, 0},
+	/* Enable 4KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 0, 1,   0,   0, -E2BIG},
+	/* Disable 4KB granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 0, 2, 0xf,   0, 0},
+	/*
+	 * Enable 4KB granule with 52 bit address on the host that doesn't
+	 * support it.
+	 */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 0, 2,   1,   0, -E2BIG},
+	/* Disable 4KB granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 1, 0,   0, 0xf,  0},
+	/* Disable 4KB granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 1, 0,   0,   0,  0},
+	/* Enable 4KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 2, 0, 0xf, 0xf,  -E2BIG},
+	/* Enable 4KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN4_2_SHIFT, 2, 0,   0,   0,  0},
+};
+
+/*
+ * Test parameters of validate_id_aa64mmfr0_tgran2_test() for TGran64_2.
+ * Defined values for the field are:
+ *  0x0: Support for 64KB granule at stage 2 is identified in TGran64.
+ *  0x1: 64KB granule not supported at stage 2.
+ *  0x2: 64KB granule supported at stage 2.
+ *  0x3: 64KB granule at stage 2 supports 52-bit input and output addresses.
+ *
+ * Defined values for the TGran64 are:
+ *  0x0: 64KB granule supported.
+ *  0xf: 64KB granule not supported.
+ */
+struct tgran_test tgran64_2_test_params[] = {
+	/* Enable 64KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 2, 2,   0,   0, 0},
+	/* Enable 64KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 2, 1,   0,   0, -E2BIG},
+	/* Enable 64KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 1, 2,   0,   0, 0},
+	/* Enable 64KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 0, 0,   0,   0, 0},
+	/* Disable 64KB granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 0, 1, 0xf,   0, 0},
+	/* Enable 64KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 0, 1,   0,   0, -E2BIG},
+	/* Disable 64KB granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 0, 2, 0xf,   0, 0},
+	/* Disable 64KB granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 1, 0,   0, 0xf, 0},
+	/* Disable 64KB granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 1, 0,   0,   0, 0},
+	/* Enable 64KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 2, 0, 0xf, 0xf, -E2BIG},
+	/* Enable 64KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN64_2_SHIFT, 2, 0,   0,   0, 0},
+};
+
+/*
+ * Test parameters of validate_id_aa64mmfr0_tgran2_test() for TGran16_2
+ * Defined values for the field are:
+ *  0x0: Support for 16KB granule at stage 2 is identified in TGran16.
+ *  0x1: 16KB granule not supported at stage 2.
+ *  0x2: 16KB granule supported at stage 2.
+ *  0x3: 16KB granule at stage 2 supports 52-bit input and output addresses.
+ *
+ * Defined values for the TGran16 are:
+ *  0x0: 16KB granule not supported.
+ *  0x1: 16KB granule supported.
+ *  0x2: 16KB granule supports 52-bit input and output addresses.
+ */
+struct tgran_test tgran16_2_test_params[] = {
+	/* Enable 16KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 2, 2,  0,  0, 0},
+	/* Enable 16KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 2, 1,  0,  0, -E2BIG},
+	/* Disable 16KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 1, 2,  0,  0, 0},
+	/* Disable 16KB granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 0, 0,  0,  0, 0},
+	/* Disable 16KB granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 0, 1,  0,  0, 0},
+	/* Enable 16KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 0, 1,  1,  0, -E2BIG},
+	/* Disable 16KB granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 0, 2,  0,  0, 0},
+	/*
+	 * Enable 16KB granule with 52 bit address on the host that doesn't
+	 * support it.
+	 */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 0, 2,  2,  2, -E2BIG},
+	/* Disable 16KB granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 1, 0,  0,  0, 0},
+	/* Disable 16KB granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 1, 0,  0,  1, 0},
+	/* Enable 16KB granule on the host that doesn't support the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 2, 0,  0,  0, -E2BIG},
+	/* Enable 16KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 2, 0,  0,  1, 0},
+	/* Enable 16KB granule on the host that supports the granule */
+	{ID_AA64MMFR0_TGRAN16_2_SHIFT, 2, 0,  0,  2, 0},
+};
+
+static void tgran2_case_to_desc(struct tgran_test *t, char *desc)
+{
+	snprintf(desc, KUNIT_PARAM_DESC_SIZE,
+		 "gran2(field=%d): val=%d, lim=%d gran1: val=%d limit=%d\n",
+		 t->gran2_field, t->gran2, t->gran2_lim,
+		 t->gran1, t->gran1_lim);
+}
+
+KUNIT_ARRAY_PARAM(tgran4_2, tgran4_2_test_params, tgran2_case_to_desc);
+KUNIT_ARRAY_PARAM(tgran64_2, tgran64_2_test_params, tgran2_case_to_desc);
+KUNIT_ARRAY_PARAM(tgran16_2, tgran16_2_test_params, tgran2_case_to_desc);
+
+#define	MAKE_MMFR0_TGRAN(shift1, gran1, shift2, gran2)		\
+	(((u64)((gran1) & 0xf) << (shift1)) |			\
+	 ((u64)((gran2) & 0xf) << (shift2)))
+
+/* Return the bit position of TGranX field for the given TGranX_2 field. */
+static int tgran2_to_tgran1_shift(int tgran2_shift)
+{
+	int tgran1_shift = -1;
+
+	switch (tgran2_shift) {
+	case ID_AA64MMFR0_TGRAN4_2_SHIFT:
+		tgran1_shift = ID_AA64MMFR0_TGRAN4_SHIFT;
+		break;
+	case ID_AA64MMFR0_TGRAN64_2_SHIFT:
+		tgran1_shift = ID_AA64MMFR0_TGRAN64_SHIFT;
+		break;
+	case ID_AA64MMFR0_TGRAN16_2_SHIFT:
+		tgran1_shift = ID_AA64MMFR0_TGRAN16_SHIFT;
+		break;
+	default:
+		break;
+	}
+
+	return tgran1_shift;
+}
+
+/* Tests for validate_id_aa64mmfr0_el1(). */
+static void validate_id_aa64mmfr0_tgran2_test(struct kunit *test)
+{
+	const struct tgran_test *t = test->param_value;
+	int shift1, shift2;
+	u64 v, lim;
+
+	shift2 = t->gran2_field;
+	shift1 = tgran2_to_tgran1_shift(shift2);
+	v = MAKE_MMFR0_TGRAN(shift1, t->gran1, shift2, t->gran2);
+	lim = MAKE_MMFR0_TGRAN(shift1, t->gran1_lim, shift2, t->gran2_lim);
+
+	KUNIT_EXPECT_EQ(test, aa64mmfr0_tgran2_check(shift2, v, lim), t->ret);
+}
+
+/* Tests for validate_id_aa64pfr0_el1(). */
+static void validate_id_aa64pfr0_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64PFR0_EL1);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	/*
+	 * Tests for GIC.
+	 * GIC must be 1 when vGIC3 is configured.
+	 */
+	v = 0x0000000;	/* GIC = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Test with VGIC_V2 */
+	vcpu->kvm->arch.vgic.in_kernel = true;
+	vcpu->kvm->arch.vgic.vgic_model = KVM_DEV_TYPE_ARM_VGIC_V2;
+
+	v = 0x0000000;	/* GIC = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Test with VGIC_V3 */
+	vcpu->kvm->arch.vgic.vgic_model = KVM_DEV_TYPE_ARM_VGIC_V3;
+
+	v = 0x0000000;	/* GIC = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+	v = 0x1000000;	/* GIC = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Restore the original VGIC state */
+	vcpu->kvm->arch.vgic.in_kernel = false;
+	vcpu->kvm->arch.vgic.vgic_model = 0;
+
+	/*
+	 * Tests for AdvSIMD/FP.
+	 * AdvSIMD must have the same value as FP.
+	 */
+
+	/* Tests with SVE disabled */
+	v = 0x000010000;	/* AdvSIMD = 0, FP = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000100000;	/* AdvSIMD = 1, FP = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000ff0000;	/* AdvSIMD = 0xf, FP = 0xf */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100000000;	/* SVE =1, AdvSIMD = 0, FP = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+	if (!system_supports_sve()) {
+		kunit_skip(test, "No SVE support. Partial skip)");
+		/* Not reached */
+	}
+
+	/* Tests with SVE enabled */
+	vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_SVE;
+
+	v = 0x100000000;	/* SVE =1, AdvSIMD = 0, FP = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100ff0000;	/* SVE =1, AdvSIMD = 0, FP = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr0_el1(vcpu, id_reg, v), 0);
+
+	vcpu->arch.flags &= ~KVM_ARM64_GUEST_HAS_SVE;
+}
+
+/* Tests for validate_id_aa64pfr1_el1() */
+static void validate_id_aa64pfr1_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64PFR1_EL1);
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr1_el1(vcpu, id_reg, v), 0);
+
+	/* Tests for MTE */
+
+	/* Tests with MTE disabled */
+	KUNIT_EXPECT_FALSE(test, vcpu->kvm->arch.mte_enabled);
+
+	v = 0x000;	/* MTE = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100;	/* MTE = 1*/
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr1_el1(vcpu, id_reg, v), 0);
+
+	if (!system_supports_mte()) {
+		kunit_skip(test, "(No MTE support. Partial skip)");
+		/* Not reached */
+	}
+
+	/* Tests with MTE enabled */
+	vcpu->kvm->arch.mte_enabled = true;
+
+	v = 0x100;	/* MTE = 1*/
+	KUNIT_EXPECT_EQ(test, validate_id_aa64pfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x0;	/* MTE = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64pfr1_el1(vcpu, id_reg, v), 0);
+}
+
+/* Tests for validate_id_aa64isar0_el1(). */
+static void validate_id_aa64isar0_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64ISAR0_EL1);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	/*
+	 * Tests for SM3/SM4.
+	 * Arm ARM says SM3 must have the same value as SM4.
+	 */
+
+	v = 0x01000000000;	/* SM4 = 0, SM3 = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x10000000000;	/* SM4 = 1, SM3 = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x11000000000;	/* SM3 = SM4 = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+
+	/*
+	 * Tests for SHA1/SHA2/SHA3.  Arm ARM says:
+	 * If SHA1 is 0x0, both SHA2 and SHA3 must be 0x0.
+	 * If SHA2 is 0x0, SHA1 must be 0x0.
+	 * If SHA2 is 0x2, SHA3 must be 0x1.
+	 * If SHA3 is 0x1, SHA2 msut be 0x2.
+	 */
+
+	v = 0x000000100;	/* SHA2 = 0, SHA1 = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000001000;	/* SHA2 = 1, SHA1 = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000001100;	/* SHA2 = 1, SHA1 = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100002000;	/* SHA3 = 1, SHA2 = 2 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000002000;	/* SHA3 = 0, SHA2 = 2 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100001000;	/* SHA3 = 1, SHA2 = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x200000000;	/* SHA3 = 2, SHA1 = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x200001100;	/* SHA3 = 2, SHA2= 1, SHA1 = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x300003300;	/* SHA3 = 3, SHA2 = 3, SHA1 = 3 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar0_el1(vcpu, id_reg, v), 0);
+}
+
+/* Tests for validate_id_aa64isar1_el1() */
+static void validate_id_aa64isar1_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64ISAR1_EL1);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	/*
+	 * Tests for GPI/GPA/API/APA.
+	 * Arm ARM says:
+	 * If GPA is non-zero, GPI must be zero.
+	 * If GPI is non-zero, GPA must be zero.
+	 * If APA is non-zero, API must be zero.
+	 * If API is non-zero, APA must be zero.
+	 */
+
+	/* Tests with PTRAUTH disabled */
+	v = 0x11000110;	/* GPI = 1, GPA = 1, API = 1, APA = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x11000100;	/* GPI = 1, GPA = 1, API = 1, APA = 0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x11000010;	/* GPI = 1, GPA = 1, API = 0, APA = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x10000110;	/* GPI = 1, GPA = 0, API = 1, APA = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x01000110;	/* GPI = 0, GPA = 1, API = 1, APA = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	if (!system_has_full_ptr_auth()) {
+		kunit_skip(test, "(No PTRAUTH support. Partial skip)");
+		/* Not reached */
+	}
+
+	/* Tests with PTRAUTH enabled */
+	vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_PTRAUTH;
+
+	v = 0x10000100;	/* GPI = 1, GPA = 0, API = 1, APA = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x10000010;	/* GPI = 1, GPA = 0, API = 0, APA = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x01000100;	/* GPI = 0, GPA = 1, API = 1, APA = 0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x01000010;	/* GPI = 0, GPA = 1, API = 0, APA = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+
+	v = 0;
+	KUNIT_EXPECT_NE(test, validate_id_aa64isar1_el1(vcpu, id_reg, v), 0);
+}
+
+/* Tests for validate_id_aa64mmfr0_el1() */
+static void validate_id_aa64mmfr0_el1_test(struct kunit *test)
+{
+	struct id_reg_info id_data, *id_reg;
+	const struct tgran_test *t4, *t64, *t16;
+	struct kvm_vcpu *vcpu;
+	int field4, field4_2, field64, field64_2, field16, field16_2;
+	u64 v, v4, lim4, v64, lim64, v16, lim16;
+	int i, j, ret;
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64MMFR0_EL1);
+
+	/* Save the original id_reg_info (and restore later) */
+	memcpy(&id_data, id_reg, sizeof(id_data));
+
+	vcpu = test_kvm_vcpu_init(test);
+
+	t4 = test->param_value;
+	field4_2 = t4->gran2_field;
+	field4 = tgran2_to_tgran1_shift(field4_2);
+	v4 = MAKE_MMFR0_TGRAN(field4, t4->gran1, field4_2, t4->gran2);
+	lim4 = MAKE_MMFR0_TGRAN(field4, t4->gran1_lim, field4_2, t4->gran2_lim);
+
+	/*
+	 * For each given gran4_2 params, test validate_id_aa64mmfr0_el1
+	 * with each of tgran64_2 and tgran16_2 params.
+	 */
+	for (i = 0; i < ARRAY_SIZE(tgran64_2_test_params); i++) {
+		t64 = &tgran64_2_test_params[i];
+		field64_2 = t64->gran2_field;
+		field64 = tgran2_to_tgran1_shift(field64_2);
+		v64 = MAKE_MMFR0_TGRAN(field64, t64->gran1,
+				       field64_2, t64->gran2);
+		lim64 = MAKE_MMFR0_TGRAN(field64, t64->gran1_lim,
+					 field64_2, t64->gran2_lim);
+
+		for (j = 0; j < ARRAY_SIZE(tgran16_2_test_params); j++) {
+			t16 = &tgran16_2_test_params[j];
+
+			field16_2 = t16->gran2_field;
+			field16 = tgran2_to_tgran1_shift(field16_2);
+			v16 = MAKE_MMFR0_TGRAN(field16, t16->gran1,
+					       field16_2, t16->gran2);
+			lim16 = MAKE_MMFR0_TGRAN(field16, t16->gran1_lim,
+						 field16_2, t16->gran2_lim);
+
+			/* Build id_aa64mmfr0_el1 from tgran16/64/4 values */
+			v = v16 | v64 | v4;
+			id_reg->vcpu_limit_val = lim16 | lim64 | lim4;
+
+			ret = t4->ret ? t4->ret : t64->ret;
+			ret = ret ? ret : t16->ret;
+			KUNIT_EXPECT_EQ(test,
+				validate_id_aa64mmfr0_el1(vcpu, id_reg, v),
+				ret);
+		}
+	}
+
+	/* Restore id_reg_info */
+	memcpy(id_reg, &id_data, sizeof(id_data));
+}
+
+/* Tests for validate_id_aa64dfr0_el1() */
+static void validate_id_aa64dfr0_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_AA64DFR0_EL1);
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	/*
+	 * Tests for CTX_CMPS/BRPS.
+	 * Number of context-aware breakpoints can be no more than number
+	 * of supported breakpoints.
+	 */
+	v = 0x10001000;	/* CTX_CMPS = 1, BRPS = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x20001000;	/* CTX_CMPS = 2, BRPS = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Tests for PMUVer */
+
+	/* Tests with PMUv3 disabled. */
+
+	v = 0x000;	/* PMUVER = 0x0 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0xf00;	/* PMUVER = 0xf */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100;	/* PMUVER = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Tests with PMUv3 enabled */
+	set_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features);
+
+	v = 0x000;	/* PMUVER = 0x0 */
+	KUNIT_EXPECT_NE(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x000;	/* PMUVER = 0xf */
+	KUNIT_EXPECT_NE(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x100;	/* PMUVER = 1 */
+	KUNIT_EXPECT_EQ(test, validate_id_aa64dfr0_el1(vcpu, id_reg, v), 0);
+}
+
+/* Tests for validate_id_dfr0_el1() */
+static void validate_id_dfr0_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	id_reg = GET_ID_REG_INFO(SYS_ID_DFR0_EL1);
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	/* Tests for PERFMON */
+
+	/* Tests with PMUv3 disabled */
+
+	v = 0x0000000;	/* PERFMON = 0x0 */
+	KUNIT_EXPECT_EQ(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0xf000000;	/* PERFMON = 0xf */
+	KUNIT_EXPECT_EQ(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x1000000;	/* PERFMON = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x2000000;	/* PERFMON = 2 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x3000000;	/* PERFMON = 3 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+
+	/* Tests with PMUv3 enabled */
+	set_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features);
+
+	v = 0x0000000;	/* PERFMON = 0x0 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0xf000000;	/* PERFMON = 0xf */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x1000000;	/* PERFMON = 1 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x2000000;	/* PERFMON = 2 */
+	KUNIT_EXPECT_NE(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+
+	v = 0x3000000;	/* PERFMON = 3 */
+	KUNIT_EXPECT_EQ(test, validate_id_dfr0_el1(vcpu, id_reg, v), 0);
+}
+
+/* Tests for validate_mvfr1_el1(). */
+static void validate_mvfr1_el1_test(struct kunit *test)
+{
+	struct id_reg_info *id_reg;
+	struct kvm_vcpu *vcpu;
+	u64 v;
+
+	id_reg = GET_ID_REG_INFO(SYS_MVFR1_EL1);
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	v = 0;
+	KUNIT_EXPECT_EQ(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	/*
+	 * Tests for FPHP/SIMDHP.
+	 * Arm ARM says the level of support indicated by FPHP must be
+	 * equivalent to the level of support indicated by the SIMDHP,
+	 * meaning the permitted values are:
+	 * FPHP = 0x0, SIMDHP = 0x0
+	 * FPHP = 0x2, SIMDHP = 0x1
+	 * FPHP = 0x3, SIMDHP = 0x2
+	 */
+	v = 0x0000000;	/* FPHP = 0, SIMDHP = 0 */
+	KUNIT_EXPECT_EQ(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x2100000;	/* FPHP = 2, SIMDHP = 1 */
+	KUNIT_EXPECT_EQ(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x3200000;	/* FPHP = 3, SIMDHP = 2 */
+	KUNIT_EXPECT_EQ(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x1100000;	/* FPHP = 1, SIMDHP = 1 */
+	KUNIT_EXPECT_NE(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x2200000;	/* FPHP = 2, SIMDHP = 2 */
+	KUNIT_EXPECT_NE(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = 0x3300000;	/* FPHP = 3, SIMDHP = 3 */
+	KUNIT_EXPECT_NE(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+
+	v = (u64)-1;
+	KUNIT_EXPECT_NE(test, validate_mvfr1_el1(vcpu, id_reg, v), 0);
+}
+
+/*
+ * Helper function for validate_id_reg_test().
+ * We don't use KUNIT_ASSERT or kunit_skip because this is a helper test
+ * function and we are not sure if it's safe to exist from the test case.
+ */
+static void validate_id_reg_test_one_field(struct kunit *test,
+		u32 id, int pos, int fval, int flimit,
+		bool is_signed, struct id_reg_info *idr)
+{
+	struct kvm_vcpu *vcpu;
+	int fmin = is_signed ? -1 : 0;
+	int fmax = is_signed ? 7 : 15;
+	u64 fmask = ARM64_FEATURE_FIELD_MASK;
+	u64 val;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	if (flimit > fmax) {
+		/* Shouldn't happen. Make the test failure. */
+		KUNIT_EXPECT_FALSE(test, flimit > fmax);
+		kunit_err(test, "%s: flimit(%d) > fmax(%d). Must be test bug",
+			  __func__, flimit, fmax);
+		return;
+	}
+
+	if (fval > fmin) {
+		/* Set the field to a smaller value */
+		val = ((u64)(fval - 1) & fmask) << pos;
+		KUNIT_EXPECT_EQ(test, validate_id_reg(vcpu, id, val), 0);
+	}
+
+	if (fval < flimit) {
+		/* Set the field to a larger value, but smaller than flimit */
+		val = ((u64)(fval + 1) & fmask) << pos;
+		KUNIT_EXPECT_EQ(test, validate_id_reg(vcpu, id, val), 0);
+		/* Set the field to the flimit */
+		val = ((u64)flimit & fmask) << pos;
+		KUNIT_EXPECT_EQ(test, validate_id_reg(vcpu, id, val), 0);
+	}
+
+	if (flimit < fmax) {
+		/* Set the field to a larger value than flimit */
+		val = ((u64)(flimit + 1) & fmask) << pos;
+		KUNIT_EXPECT_NE(test, validate_id_reg(vcpu, id, val), 0);
+
+		/* Test with ignore_mask */
+		if (idr) {
+			idr->ignore_mask = fmask << pos;
+			KUNIT_EXPECT_EQ(test,
+					validate_id_reg(vcpu, id, val),
+					0);
+		}
+	}
+	test_kvm_vcpu_fini(test, vcpu);
+}
+
+/*
+ * Test for validate_id_reg().
+ */
+static void validate_id_reg_test(struct kunit *test)
+{
+	struct id_reg_info idr_data, *idr, *original_idr;
+	u32 id;
+	int fval, flim, pos;
+	u64 val;
+	bool sign;
+
+	/* Use AA64PFR0_EL1 because it includes both sign/unsigned fields */
+	id = SYS_ID_AA64PFR0_EL1;
+
+	/* Save the original id_reg_info */
+	original_idr = GET_ID_REG_INFO(id);
+
+	/* Test with a temporary id_reg_info for testing */
+	idr = &idr_data;
+	GET_ID_REG_INFO(id) = idr;
+
+	fval = 0x1;
+	flim = 0x2;
+
+	/* Test with unsigned field */
+	pos = ID_AA64PFR0_RAS_SHIFT;
+
+	/* Set up id_reg_info for testing */
+	memset(idr, 0, sizeof(*idr));
+	idr->sys_reg = id;
+	idr->vcpu_limit_val = (u64)flim << pos;
+	validate_id_reg_test_one_field(test, id, pos, fval, flim, false, idr);
+
+	/* Test with signed field */
+	pos = ID_AA64PFR0_FP_SHIFT;
+
+	/* Set up id_reg_info for testing */
+	memset(idr, 0, sizeof(*idr));
+	idr->sys_reg = id;
+	idr->vcpu_limit_val = (u64)flim << pos;
+	validate_id_reg_test_one_field(test, id, pos, fval, flim, true, idr);
+
+
+	/* Test without id_reg_info */
+	GET_ID_REG_INFO(id) = NULL;
+	if (original_idr)
+		val = original_idr->vcpu_limit_val;
+	else
+		val = read_sanitised_ftr_reg(id);
+
+	for (pos = 0; pos < 64; pos += 4) {
+		if (pos == ID_AA64PFR0_FP_SHIFT ||
+		    pos == ID_AA64PFR0_ASIMD_SHIFT)
+			sign = true;
+		else
+			sign = false;
+
+		fval = cpuid_feature_extract_field(val, pos, sign);
+		validate_id_reg_test_one_field(test, id, pos, fval, fval,
+					       sign, NULL);
+	}
+
+	/* Restore the original id_reg_info */
+	GET_ID_REG_INFO(id) = original_idr;
+}
+
+static struct kunit_case kvm_sys_regs_test_cases[] = {
+	KUNIT_CASE_PARAM(vcpu_id_reg_feature_frac_check_test, frac_gen_params),
+	KUNIT_CASE_PARAM(validate_id_aa64mmfr0_tgran2_test, tgran4_2_gen_params),
+	KUNIT_CASE_PARAM(validate_id_aa64mmfr0_tgran2_test, tgran64_2_gen_params),
+	KUNIT_CASE_PARAM(validate_id_aa64mmfr0_tgran2_test, tgran16_2_gen_params),
+	KUNIT_CASE(validate_id_aa64pfr0_el1_test),
+	KUNIT_CASE(validate_id_aa64pfr1_el1_test),
+	KUNIT_CASE(validate_id_aa64isar0_el1_test),
+	KUNIT_CASE(validate_id_aa64isar1_el1_test),
+	KUNIT_CASE_PARAM(validate_id_aa64mmfr0_el1_test, tgran4_2_gen_params),
+	KUNIT_CASE(validate_id_aa64dfr0_el1_test),
+	KUNIT_CASE(validate_id_dfr0_el1_test),
+	KUNIT_CASE(validate_mvfr1_el1_test),
+	KUNIT_CASE(validate_id_reg_test),
+	{}
+};
+
+static struct kunit_suite kvm_sys_regs_test_suite = {
+	.name = "kvm-sys-regs-test-suite",
+	.test_cases = kvm_sys_regs_test_cases,
+};
+
+kunit_test_suites(&kvm_sys_regs_test_suite);
+MODULE_LICENSE("GPL");
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:00 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:00 -0800
Subject: [RFC PATCH v4 18/26] KVM: arm64: Use vcpu->arch.mdcr_el2 to track
 value of mdcr_el2
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-19-reijiw@google.com>

Track the baseline guest value for mdcr_el2 in struct kvm_vcpu_arch.
Use this value when setting mdcr_el2 for the guest.

Currently this value is unchanged, but the following patches will set
trapping bits based on features supported for the guest.

No functional change intended.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_arm.h | 16 ++++++++++++++++
 arch/arm64/kvm/arm.c             |  1 +
 arch/arm64/kvm/debug.c           | 13 ++++---------
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 8ab6ea038721..4b2ac9e32a36 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -333,6 +333,22 @@
 				 BIT(18) |		\
 				 GENMASK(16, 15))
 
+/*
+ * The default value for the guest below also clears MDCR_EL2_E2PB_MASK
+ * and MDCR_EL2_E2TB_MASK to disable guest access to the profiling and
+ * trace buffers.
+ */
+#define MDCR_GUEST_FLAGS_DEFAULT				\
+	(MDCR_EL2_TPM  | MDCR_EL2_TPMS | MDCR_EL2_TTRF |	\
+	 MDCR_EL2_TPMCR | MDCR_EL2_TDRA | MDCR_EL2_TDOSA)
+
+/* Bits that are copied from vcpu->arch.mdcr_el2 to set mdcr_el2 for guest. */
+#define MDCR_GUEST_FLAGS_TRACKED_MASK				\
+	(MDCR_EL2_TPM  | MDCR_EL2_TPMS | MDCR_EL2_TTRF |	\
+	 MDCR_EL2_TPMCR | MDCR_EL2_TDRA | MDCR_EL2_TDOSA |	\
+	 (MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT))
+
+
 /* For compatibility with fault code shared with 32-bit */
 #define FSC_FAULT	ESR_ELx_FSC_FAULT
 #define FSC_ACCESS	ESR_ELx_FSC_ACCESS
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 3700144f6271..33acbae7a7ed 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1136,6 +1136,7 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu_reset_hcr(vcpu);
+	vcpu->arch.mdcr_el2 = MDCR_GUEST_FLAGS_DEFAULT;
 	if (has_vhe())
 		vcpu->arch.cptr_el2 = CPTR_EL2_VHE_GUEST_DEFAULT;
 	else
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index db9361338b2a..83330968a411 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -84,16 +84,11 @@ void kvm_arm_init_debug(void)
 static void kvm_arm_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 {
 	/*
-	 * This also clears MDCR_EL2_E2PB_MASK and MDCR_EL2_E2TB_MASK
-	 * to disable guest access to the profiling and trace buffers
+	 * Keep the vcpu->arch.mdcr_el2 bits that are specified by
+	 * MDCR_GUEST_FLAGS_TRACKED_MASK.
 	 */
-	vcpu->arch.mdcr_el2 = __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
-	vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM |
-				MDCR_EL2_TPMS |
-				MDCR_EL2_TTRF |
-				MDCR_EL2_TPMCR |
-				MDCR_EL2_TDRA |
-				MDCR_EL2_TDOSA);
+	vcpu->arch.mdcr_el2 &= MDCR_GUEST_FLAGS_TRACKED_MASK;
+	vcpu->arch.mdcr_el2 |= __this_cpu_read(mdcr_el2) & MDCR_EL2_HPMN_MASK;
 
 	/* Is the VM being debugged by userspace? */
 	if (vcpu->guest_debug)
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:01 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:01 -0800
Subject: [RFC PATCH v4 19/26] KVM: arm64: Introduce framework to trap disabled
 features
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-20-reijiw@google.com>

When a CPU feature that is supported on the host is not exposed to
its guest, emulating a real CPU's behavior (by trapping or disabling
guest's using the feature) is generally a desirable behavior (when
it's possible without any or little side effect).

Introduce feature_config_ctrl structure, which manages feature
information to program configuration register to trap or disable
the feature when the feature is not exposed to the guest, and
functions that uses the structure to activate the vcpu's trapping the
feature.  Those codes don't update trap configuration registers
themselves (HCR_EL2, etc) but values for the registers in
kvm_vcpu_arch at the first KVM_RUN.

At present, no feature has feature_config_ctrl yet and the following
patches will add the feature_config_ctrl for some features.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_host.h |   1 +
 arch/arm64/kvm/arm.c              |  13 ++--
 arch/arm64/kvm/sys_regs.c         | 105 +++++++++++++++++++++++++++++-
 3 files changed, 113 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7b3f86bd6a6b..0274009cb05d 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -751,6 +751,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
 void set_default_id_regs(struct kvm *kvm);
 int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
 int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu);
+void kvm_vcpu_init_traps(struct kvm_vcpu *vcpu);
 
 /* Guest/host FPSIMD coordination helpers */
 int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 33acbae7a7ed..e2f52eb84618 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -626,13 +626,16 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 
 	ret = kvm_arm_pmu_v3_enable(vcpu);
 
-	/*
-	 * Initialize traps for protected VMs.
-	 * NOTE: Move to run in EL2 directly, rather than via a hypercall, once
-	 * the code is in place for first run initialization at EL2.
-	 */
+	/* Initialize traps for the guest. */
 	if (kvm_vm_is_protected(kvm))
+		/*
+		 * NOTE: Move to run in EL2 directly, rather than via a
+		 * hypercall, once the code is in place for first run
+		 * initialization at EL2.
+		 */
 		kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
+	else
+		kvm_vcpu_init_traps(vcpu);
 
 	return ret;
 }
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index d5bd04c68cd4..33893a501475 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -283,8 +283,30 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \
 	 ID_AA64ISAR1_GPI_IMP_DEF)
 
+/*
+ * Feature information to program configuration register to trap or disable
+ * guest's using a feature when the feature is not exposed to the guest.
+ */
+struct feature_config_ctrl {
+	/* ID register/field for the feature */
+	u32	ftr_reg;	/* ID register */
+	bool	ftr_signed;	/* Is the feature field signed ? */
+	u8	ftr_shift;	/* Field of ID register for the feature */
+	s8	ftr_min;	/* Min value that indicate the feature */
+
+	/*
+	 * Function to check trapping is needed. This is used when the above
+	 * fields are not enough to determine if trapping is needed.
+	 */
+	bool	(*ftr_need_trap)(struct kvm_vcpu *vcpu);
+
+	/* Function to activate trapping the feature. */
+	void	(*trap_activate)(struct kvm_vcpu *vcpu);
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
+	u64	sys_val;	/* Sanitized system value */
 
 	/*
 	 * Limit value of the register for a vcpu. The value is the sanitized
@@ -327,11 +349,15 @@ struct id_reg_info {
 	 */
 	u64 (*vcpu_mask)(const struct kvm_vcpu *vcpu,
 			 const struct id_reg_info *id_reg);
+
+	/* Information to trap features that are disabled for the guest */
+	const struct feature_config_ctrl *(*trap_features)[];
 };
 
 static void id_reg_info_init(struct id_reg_info *id_reg)
 {
-	id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg);
+	id_reg->sys_val = read_sanitised_ftr_reg(id_reg->sys_reg);
+	id_reg->vcpu_limit_val = id_reg->sys_val;
 	if (id_reg->init)
 		id_reg->init(id_reg);
 }
@@ -857,6 +883,24 @@ static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
 	return err;
 }
 
+static inline bool feature_avail(const struct feature_config_ctrl *ctrl,
+				 u64 id_val)
+{
+	int field_val = cpuid_feature_extract_field(id_val,
+				ctrl->ftr_shift, ctrl->ftr_signed);
+
+	return (field_val >= ctrl->ftr_min);
+}
+
+static inline bool vcpu_feature_is_available(struct kvm_vcpu *vcpu,
+					const struct feature_config_ctrl *ctrl)
+{
+	u64 val;
+
+	val = __read_id_reg(vcpu, ctrl->ftr_reg);
+	return feature_avail(ctrl, val);
+}
+
 /*
  * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
  * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
@@ -1799,6 +1843,46 @@ static int reg_from_user(u64 *val, const void __user *uaddr, u64 id);
 static int reg_to_user(void __user *uaddr, const u64 *val, u64 id);
 static u64 sys_reg_to_index(const struct sys_reg_desc *reg);
 
+static void id_reg_features_trap_activate(struct kvm_vcpu *vcpu,
+					  const struct id_reg_info *id_reg)
+{
+	u64 val;
+	int i = 0;
+	const struct feature_config_ctrl **ctrlp_array, *ctrl;
+
+	if (!id_reg || !id_reg->trap_features)
+		/* No information to trap a feature */
+		return;
+
+	val = __read_id_reg(vcpu, id_reg->sys_reg);
+	if (val == id_reg->sys_val)
+		/* No feature needs to be trapped (no feature is disabled). */
+		return;
+
+	ctrlp_array = *id_reg->trap_features;
+	while ((ctrl = ctrlp_array[i++]) != NULL) {
+		if (WARN_ON_ONCE(!ctrl->trap_activate))
+			/* Shouldn't happen */
+			continue;
+
+		if (ctrl->ftr_need_trap && ctrl->ftr_need_trap(vcpu)) {
+			ctrl->trap_activate(vcpu);
+			continue;
+		}
+
+		if (!feature_avail(ctrl, id_reg->sys_val))
+			/* The feature is not supported on the host. */
+			continue;
+
+		if (feature_avail(ctrl, val))
+			/* The feature is enabled for the guest. */
+			continue;
+
+		/* The feature is supported but disabled. */
+		ctrl->trap_activate(vcpu);
+	}
+}
+
 /* Visibility overrides for SVE-specific control registers */
 static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
 				   const struct sys_reg_desc *rd)
@@ -3431,6 +3515,25 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
 	return write_demux_regids(uindices);
 }
 
+/*
+ * This function activates vcpu's trapping of features that are included in
+ * trap_features[] of id_reg_info if the features are supported on the
+ * host, but are hidden from the guest (i.e. values of ID registers for
+ * the guest are modified to not show the features' availability).
+ * This function just updates values for trap configuration registers (e.g.
+ * HCR_EL2, etc) in kvm_vcpu_arch, which will be restored before switching
+ * to the guest, but doesn't update the registers themselves.
+ * This function should be called once at the first KVM_RUN (ID registers
+ * are immutable after the first KVM_RUN).
+ */
+void kvm_vcpu_init_traps(struct kvm_vcpu *vcpu)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++)
+		id_reg_features_trap_activate(vcpu, id_reg_info_table[i]);
+}
+
 /* ID register's fractional field information with its feature field. */
 struct feature_frac {
 	u32	id;
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:03 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:03 -0800
Subject: [RFC PATCH v4 21/26] KVM: arm64: Trap disabled features of
 ID_AA64PFR1_EL1
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-22-reijiw@google.com>

Add feature_config_ctrl for MTE, which is indicated in
ID_AA64PFR1_EL1, to program configuration register to trap the
guest's using the feature when it is not exposed to the guest.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 015d67092d5e..72e745c5a9c2 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -344,6 +344,11 @@ static void feature_amu_trap_activate(struct kvm_vcpu *vcpu)
 	feature_trap_activate(vcpu, VCPU_CPTR_EL2, CPTR_EL2_TAM, 0);
 }
 
+static void feature_mte_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TID5, HCR_DCT | HCR_ATA);
+}
+
 /* For ID_AA64PFR0_EL1 */
 static struct feature_config_ctrl ftr_ctrl_ras = {
 	.ftr_reg = SYS_ID_AA64PFR0_EL1,
@@ -361,6 +366,15 @@ static struct feature_config_ctrl ftr_ctrl_amu = {
 	.trap_activate = feature_amu_trap_activate,
 };
 
+/* For ID_AA64PFR1_EL1 */
+static struct feature_config_ctrl ftr_ctrl_mte = {
+	.ftr_reg = SYS_ID_AA64PFR1_EL1,
+	.ftr_shift = ID_AA64PFR1_MTE_SHIFT,
+	.ftr_min = ID_AA64PFR1_MTE_EL0,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_mte_trap_activate,
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 	u64	sys_val;	/* Sanitized system value */
@@ -847,6 +861,10 @@ static struct id_reg_info id_aa64pfr1_el1_info = {
 	.init = init_id_aa64pfr1_el1_info,
 	.validate = validate_id_aa64pfr1_el1,
 	.vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
+	.trap_features = &(const struct feature_config_ctrl *[]) {
+		&ftr_ctrl_mte,
+		NULL,
+	},
 };
 
 static struct id_reg_info id_aa64isar0_el1_info = {
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:02 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:02 -0800
Subject: [RFC PATCH v4 20/26] KVM: arm64: Trap disabled features of
 ID_AA64PFR0_EL1
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-21-reijiw@google.com>

Add feature_config_ctrl for RAS and AMU, which are indicated in
ID_AA64PFR0_EL1, to program configuration registers to trap
guest's using those features when they are not exposed to the guest.

Introduce trap_ras_regs() to change a behavior of guest's access to
the registers, which is currently raz/wi, depending on the feature's
availability for the guest (and inject undefined instruction
exception when guest's RAS register access are trapped and RAS is
not exposed to the guest).  In order to keep the current visibility
of the RAS registers from userspace (always visible), a visibility
function for RAS registers is not added.

No code is added for AMU's access/visibility handler because the
current code already injects the exception for Guest's AMU register
access unconditionally because AMU is never exposed to the guest.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 90 +++++++++++++++++++++++++++++++++++----
 1 file changed, 82 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 33893a501475..015d67092d5e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -304,6 +304,63 @@ struct feature_config_ctrl {
 	void	(*trap_activate)(struct kvm_vcpu *vcpu);
 };
 
+enum vcpu_config_reg {
+	VCPU_HCR_EL2 = 1,
+	VCPU_MDCR_EL2,
+	VCPU_CPTR_EL2,
+};
+
+static void feature_trap_activate(struct kvm_vcpu *vcpu,
+				  enum vcpu_config_reg cfg_reg,
+				  u64 cfg_set, u64 cfg_clear)
+{
+	u64 *reg_ptr, reg_val;
+
+	switch (cfg_reg) {
+	case VCPU_HCR_EL2:
+		reg_ptr = &vcpu->arch.hcr_el2;
+		break;
+	case VCPU_MDCR_EL2:
+		reg_ptr = &vcpu->arch.mdcr_el2;
+		break;
+	case VCPU_CPTR_EL2:
+		reg_ptr = &vcpu->arch.cptr_el2;
+		break;
+	}
+
+	/* Clear/Set fields that are indicated by cfg_clear/cfg_set. */
+	reg_val = (*reg_ptr & ~cfg_clear);
+	reg_val |= cfg_set;
+	*reg_ptr = reg_val;
+}
+
+static void feature_ras_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TERR | HCR_TEA, HCR_FIEN);
+}
+
+static void feature_amu_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_CPTR_EL2, CPTR_EL2_TAM, 0);
+}
+
+/* For ID_AA64PFR0_EL1 */
+static struct feature_config_ctrl ftr_ctrl_ras = {
+	.ftr_reg = SYS_ID_AA64PFR0_EL1,
+	.ftr_shift = ID_AA64PFR0_RAS_SHIFT,
+	.ftr_min = ID_AA64PFR0_RAS_V1,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_ras_trap_activate,
+};
+
+static struct feature_config_ctrl ftr_ctrl_amu = {
+	.ftr_reg = SYS_ID_AA64PFR0_EL1,
+	.ftr_shift = ID_AA64PFR0_AMU_SHIFT,
+	.ftr_min = ID_AA64PFR0_AMU,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_amu_trap_activate,
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 	u64	sys_val;	/* Sanitized system value */
@@ -778,6 +835,11 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
 	.init = init_id_aa64pfr0_el1_info,
 	.validate = validate_id_aa64pfr0_el1,
 	.vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
+	.trap_features = &(const struct feature_config_ctrl *[]) {
+		&ftr_ctrl_ras,
+		&ftr_ctrl_amu,
+		NULL,
+	},
 };
 
 static struct id_reg_info id_aa64pfr1_el1_info = {
@@ -901,6 +963,18 @@ static inline bool vcpu_feature_is_available(struct kvm_vcpu *vcpu,
 	return feature_avail(ctrl, val);
 }
 
+static bool trap_ras_regs(struct kvm_vcpu *vcpu,
+			  struct sys_reg_params *p,
+			  const struct sys_reg_desc *r)
+{
+	if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_ras)) {
+		kvm_inject_undefined(vcpu);
+		return false;
+	}
+
+	return trap_raz_wi(vcpu, p, r);
+}
+
 /*
  * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
  * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
@@ -2265,14 +2339,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
 	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
 
-	{ SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
-	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
+	{ SYS_DESC(SYS_ERRIDR_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERRSELR_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXFR_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXCTLR_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXSTATUS_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXADDR_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXMISC0_EL1), trap_ras_regs },
+	{ SYS_DESC(SYS_ERXMISC1_EL1), trap_ras_regs },
 
 	MTE_REG(TFSR_EL1),
 	MTE_REG(TFSRE0_EL1),
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:04 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:04 -0800
Subject: [RFC PATCH v4 22/26] KVM: arm64: Trap disabled features of
 ID_AA64DFR0_EL1
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-23-reijiw@google.com>

Add feature_config_ctrl for PMUv3, PMS and TraceFilt, which are
indicated in ID_AA64DFR0_EL1, to program configuration registers
to trap guest's using those features when they are not exposed to
the guest.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 47 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 72e745c5a9c2..229671ec3abd 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -349,6 +349,22 @@ static void feature_mte_trap_activate(struct kvm_vcpu *vcpu)
 	feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TID5, HCR_DCT | HCR_ATA);
 }
 
+static void feature_pmuv3_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPM, 0);
+}
+
+static void feature_pms_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPMS,
+			      MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
+}
+
+static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
+}
+
 /* For ID_AA64PFR0_EL1 */
 static struct feature_config_ctrl ftr_ctrl_ras = {
 	.ftr_reg = SYS_ID_AA64PFR0_EL1,
@@ -375,6 +391,31 @@ static struct feature_config_ctrl ftr_ctrl_mte = {
 	.trap_activate = feature_mte_trap_activate,
 };
 
+/* For ID_AA64DFR0_EL1 */
+static struct feature_config_ctrl ftr_ctrl_pmuv3 = {
+	.ftr_reg = SYS_ID_AA64DFR0_EL1,
+	.ftr_shift = ID_AA64DFR0_PMUVER_SHIFT,
+	.ftr_min = ID_AA64DFR0_PMUVER_8_0,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_pmuv3_trap_activate,
+};
+
+static struct feature_config_ctrl ftr_ctrl_pms = {
+	.ftr_reg = SYS_ID_AA64DFR0_EL1,
+	.ftr_shift = ID_AA64DFR0_PMSVER_SHIFT,
+	.ftr_min = ID_AA64DFR0_PMSVER_8_2,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_pms_trap_activate,
+};
+
+static struct feature_config_ctrl ftr_ctrl_tracefilt = {
+	.ftr_reg = SYS_ID_AA64DFR0_EL1,
+	.ftr_shift = ID_AA64DFR0_TRACE_FILT_SHIFT,
+	.ftr_min = 1,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_tracefilt_trap_activate,
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 	u64	sys_val;	/* Sanitized system value */
@@ -898,6 +939,12 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
 	.init = init_id_aa64dfr0_el1_info,
 	.validate = validate_id_aa64dfr0_el1,
 	.vcpu_mask = vcpu_mask_id_aa64dfr0_el1,
+	.trap_features = &(const struct feature_config_ctrl *[]) {
+		&ftr_ctrl_pmuv3,
+		&ftr_ctrl_pms,
+		&ftr_ctrl_tracefilt,
+		NULL,
+	},
 };
 
 static struct id_reg_info id_dfr0_el1_info = {
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:05 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:05 -0800
Subject: [RFC PATCH v4 23/26] KVM: arm64: Trap disabled features of
 ID_AA64MMFR1_EL1
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-24-reijiw@google.com>

Add feature_config_ctrl for LORegions, which is indicated in
ID_AA64MMFR1_EL1, to program configuration register to trap
guest's using the feature when it is not exposed to the guest.

Change trap_loregion() to use vcpu_feature_is_available()
to simplify checking of the feature's availability.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 229671ec3abd..f8a5ee927ecf 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -365,6 +365,11 @@ static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
 	feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
 }
 
+static void feature_lor_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TLOR, 0);
+}
+
 /* For ID_AA64PFR0_EL1 */
 static struct feature_config_ctrl ftr_ctrl_ras = {
 	.ftr_reg = SYS_ID_AA64PFR0_EL1,
@@ -416,6 +421,15 @@ static struct feature_config_ctrl ftr_ctrl_tracefilt = {
 	.trap_activate = feature_tracefilt_trap_activate,
 };
 
+/* For ID_AA64MMFR1_EL1 */
+static struct feature_config_ctrl ftr_ctrl_lor = {
+	.ftr_reg = SYS_ID_AA64MMFR1_EL1,
+	.ftr_shift = ID_AA64MMFR1_LOR_SHIFT,
+	.ftr_min = 1,
+	.ftr_signed = FTR_UNSIGNED,
+	.trap_activate = feature_lor_trap_activate,
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 	u64	sys_val;	/* Sanitized system value */
@@ -947,6 +961,14 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
 	},
 };
 
+static struct id_reg_info id_aa64mmfr1_el1_info = {
+	.sys_reg = SYS_ID_AA64MMFR1_EL1,
+	.trap_features = &(const struct feature_config_ctrl *[]) {
+		&ftr_ctrl_lor,
+		NULL,
+	},
+};
+
 static struct id_reg_info id_dfr0_el1_info = {
 	.sys_reg = SYS_ID_DFR0_EL1,
 	.init = init_id_dfr0_el1_info,
@@ -976,6 +998,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
 	[IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
 	[IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
 	[IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info,
+	[IDREG_IDX(SYS_ID_AA64MMFR1_EL1)] = &id_aa64mmfr1_el1_info,
 };
 
 static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
@@ -1050,10 +1073,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
-	u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
 	u32 sr = reg_to_encoding(r);
 
-	if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
+	if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_lor)) {
 		kvm_inject_undefined(vcpu);
 		return false;
 	}
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:06 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:06 -0800
Subject: [RFC PATCH v4 24/26] KVM: arm64: Trap disabled features of
 ID_AA64ISAR1_EL1
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-25-reijiw@google.com>

Add feature_config_ctrl for PTRAUTH, which is indicated in
ID_AA64ISAR1_EL1, to program configuration register to trap
guest's using the feature when it is not exposed to the guest.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f8a5ee927ecf..e6ef76f9b563 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -283,6 +283,30 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 	(cpuid_feature_extract_unsigned_field(val, ID_AA64ISAR1_GPI_SHIFT) >= \
 	 ID_AA64ISAR1_GPI_IMP_DEF)
 
+/*
+ * Return true if ptrauth needs to be trapped.
+ * (i.e. if ptrauth is supported on the host but not exposed to the guest)
+ */
+static bool vcpu_need_trap_ptrauth(struct kvm_vcpu *vcpu)
+{
+	u64 val;
+	bool generic, address;
+
+	if (!system_has_full_ptr_auth())
+		/* The feature is not supported. */
+		return false;
+
+	val = __read_id_reg(vcpu, SYS_ID_AA64ISAR1_EL1);
+	generic = aa64isar1_has_gpi(val) || aa64isar1_has_gpa(val);
+	address = aa64isar1_has_api(val) || aa64isar1_has_apa(val);
+	if (generic && address)
+		/* The feature is available. */
+		return false;
+
+	/* The feature is supported but hidden. */
+	return true;
+}
+
 /*
  * Feature information to program configuration register to trap or disable
  * guest's using a feature when the feature is not exposed to the guest.
@@ -370,6 +394,11 @@ static void feature_lor_trap_activate(struct kvm_vcpu *vcpu)
 	feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TLOR, 0);
 }
 
+static void feature_ptrauth_trap_activate(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2, 0, HCR_API | HCR_APK);
+}
+
 /* For ID_AA64PFR0_EL1 */
 static struct feature_config_ctrl ftr_ctrl_ras = {
 	.ftr_reg = SYS_ID_AA64PFR0_EL1,
@@ -430,6 +459,12 @@ static struct feature_config_ctrl ftr_ctrl_lor = {
 	.trap_activate = feature_lor_trap_activate,
 };
 
+/* For SYS_ID_AA64ISAR1_EL1 */
+static struct feature_config_ctrl ftr_ctrl_ptrauth = {
+	.ftr_need_trap = vcpu_need_trap_ptrauth,
+	.trap_activate = feature_ptrauth_trap_activate,
+};
+
 struct id_reg_info {
 	u32	sys_reg;	/* Register ID */
 	u64	sys_val;	/* Sanitized system value */
@@ -932,6 +967,10 @@ static struct id_reg_info id_aa64isar1_el1_info = {
 	.init = init_id_aa64isar1_el1_info,
 	.validate = validate_id_aa64isar1_el1,
 	.vcpu_mask = vcpu_mask_id_aa64isar1_el1,
+	.trap_features = &(const struct feature_config_ctrl *[]) {
+		&ftr_ctrl_ptrauth,
+		NULL,
+	},
 };
 
 static struct id_reg_info id_aa64mmfr0_el1_info = {
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:07 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:07 -0800
Subject: [RFC PATCH v4 25/26] KVM: arm64: Add kunit test for trap
 initialization
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-26-reijiw@google.com>

Add KUnit tests for functions in arch/arm64/kvm/sys_regs_test.c
that activates traps for disabled features.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/sys_regs_test.c | 262 +++++++++++++++++++++++++++++++++
 1 file changed, 262 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs_test.c b/arch/arm64/kvm/sys_regs_test.c
index 5b1b95bd9ec4..4a705ffef93b 100644
--- a/arch/arm64/kvm/sys_regs_test.c
+++ b/arch/arm64/kvm/sys_regs_test.c
@@ -959,6 +959,265 @@ static void validate_id_reg_test(struct kunit *test)
 	GET_ID_REG_INFO(id) = original_idr;
 }
 
+struct trap_config_test {
+	u64 set;
+	u64 clear;
+	u64 prev_val;
+	u64 expect_val;
+};
+
+struct trap_config_test trap_params[] = {
+	{0x30000800000, 0, 0, 0x30000800000},
+	{0, 0x30000800000, 0, 0},
+	{0x30000800000, 0, (u64)-1, (u64)-1},
+	{0, 0x30000800000, (u64)-1, (u64)0xfffffcffff7fffff},
+};
+
+static void trap_case_to_desc(struct trap_config_test *t, char *desc)
+{
+	snprintf(desc, KUNIT_PARAM_DESC_SIZE,
+		 "trap - set:0x%llx, clear:0x%llx, prev_val:0x%llx\n",
+		 t->set, t->clear, t->prev_val);
+}
+
+KUNIT_ARRAY_PARAM(trap, trap_params, trap_case_to_desc);
+
+/* Tests for feature_trap_activate(). */
+static void feature_trap_activate_test(struct kunit *test)
+{
+	struct kvm_vcpu *vcpu;
+	const struct trap_config_test *trap = test->param_value;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_ASSERT_TRUE(test, vcpu);
+
+	/* Test for HCR_EL2 */
+	vcpu->arch.hcr_el2 = trap->prev_val;
+	feature_trap_activate(vcpu, VCPU_HCR_EL2, trap->set, trap->clear);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, trap->expect_val);
+
+	/* Test for MDCR_EL2 */
+	vcpu->arch.mdcr_el2 = trap->prev_val;
+	feature_trap_activate(vcpu, VCPU_MDCR_EL2, trap->set, trap->clear);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.mdcr_el2, trap->expect_val);
+
+	/* Test for CPTR_EL2 */
+	vcpu->arch.cptr_el2 = trap->prev_val;
+	feature_trap_activate(vcpu, VCPU_CPTR_EL2, trap->set, trap->clear);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.cptr_el2, trap->expect_val);
+}
+
+static u64 test_trap_set0;
+static u64 test_trap_clear0;
+static void test_trap_activate0(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2,
+			      test_trap_set0, test_trap_clear0);
+}
+
+static u64 test_trap_set1;
+static u64 test_trap_clear1;
+static void test_trap_activate1(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2,
+			      test_trap_set1, test_trap_clear1);
+}
+
+static u64 test_trap_set2;
+static u64 test_trap_clear2;
+static void test_trap_activate2(struct kvm_vcpu *vcpu)
+{
+	feature_trap_activate(vcpu, VCPU_HCR_EL2,
+			      test_trap_set2, test_trap_clear2);
+}
+
+
+static void setup_feature_config_ctrl(struct feature_config_ctrl *config,
+				      u32 id, int shift, int min, bool sign,
+				      void *fn)
+{
+	memset(config, 0, sizeof(*config));
+	config->ftr_reg = id;
+	config->ftr_shift = shift;
+	config->ftr_min = min;
+	config->ftr_signed = sign;
+	config->trap_activate = fn;
+}
+
+/*
+ * Tests for id_reg_features_trap_activate.
+ * Setup a id_reg_info with three entries in id_reg_info->trap_features[].
+ * Check if the config register is updated to enable trap for the disabled
+ * features.
+ */
+static void id_reg_features_trap_activate_test(struct kunit *test)
+{
+	struct kvm_vcpu *vcpu;
+	u32 id;
+	u64 cfg_set, cfg_clear, id_reg_sys_val, id_reg_val;
+	struct id_reg_info id_reg_data;
+	struct feature_config_ctrl config0, config1, config2;
+	struct feature_config_ctrl *trap_features[] = {
+		&config0, &config1, &config2, NULL,
+	};
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_EXPECT_TRUE(test, vcpu);
+	if (!vcpu)
+		return;
+
+	/* Setup id_reg_info */
+	id_reg_sys_val = 0x7777777777777777;
+	id = SYS_ID_AA64DFR0_EL1;
+	id_reg_data.sys_reg = id;
+	id_reg_data.sys_val = id_reg_sys_val;
+	id_reg_data.vcpu_limit_val  = (u64)-1;
+	id_reg_data.trap_features =
+			(const struct feature_config_ctrl *(*)[])trap_features;
+
+	/* Setup the 1st feature_config_ctrl */
+	test_trap_set0 = 0x3;
+	test_trap_clear0 = 0x0;
+	setup_feature_config_ctrl(&config0, id, 60, 2, FTR_UNSIGNED,
+				  &test_trap_activate0);
+
+	/* Setup the 2nd feature_config_ctrl */
+	test_trap_set1 = 0x30000040;
+	test_trap_clear1 = 0x40000000;
+	setup_feature_config_ctrl(&config1, id, 0, 1, FTR_UNSIGNED,
+				  &test_trap_activate1);
+
+	/* Setup the 3rd feature_config_ctrl */
+	test_trap_set2 = 0x30000000800;
+	test_trap_clear2 = 0x40000000000;
+	setup_feature_config_ctrl(&config2, id, 4, 0, FTR_SIGNED,
+				  &test_trap_activate2);
+
+#define	ftr_dis(cfg)	\
+	((u64)(((cfg)->ftr_min - 1) & 0xf) << (cfg)->ftr_shift)
+
+#define	ftr_en(cfg)	\
+	((u64)(cfg)->ftr_min << (cfg)->ftr_shift)
+
+	/* Test with features enabled for config0, 1 and 2 */
+	id_reg_val = ftr_en(&config0) | ftr_en(&config1) | ftr_en(&config2);
+	write_kvm_id_reg(vcpu->kvm, id, id_reg_val);
+	vcpu->arch.hcr_el2 = 0;
+	id_reg_features_trap_activate(vcpu, &id_reg_data);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0);
+
+
+	/* Test with features disabled for config0 only */
+	id_reg_val = ftr_dis(&config0) | ftr_en(&config1) | ftr_en(&config2);
+	write_kvm_id_reg(vcpu->kvm, id, id_reg_val);
+	vcpu->arch.hcr_el2 = 0;
+	cfg_set = test_trap_set0;
+	cfg_clear = test_trap_clear0;
+
+	id_reg_features_trap_activate(vcpu, &id_reg_data);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_set, cfg_set);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_clear, 0);
+
+
+	/* Test with features disabled for config0 and config1  */
+	id_reg_val = ftr_dis(&config0) | ftr_dis(&config1) | ftr_en(&config2);
+	write_kvm_id_reg(vcpu->kvm, id, id_reg_val);
+	vcpu->arch.hcr_el2 = 0;
+
+	cfg_set = test_trap_set0 | test_trap_set1;
+	cfg_clear = test_trap_clear0 | test_trap_clear1;
+
+	id_reg_features_trap_activate(vcpu, &id_reg_data);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_set, cfg_set);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_clear, 0);
+
+
+	/* Test with features disabled for config0, config1, and config2 */
+	id_reg_val = ftr_dis(&config0) | ftr_dis(&config1) | ftr_dis(&config2);
+	write_kvm_id_reg(vcpu->kvm, id, id_reg_val);
+	vcpu->arch.hcr_el2 = 0;
+
+	cfg_set = test_trap_set0 | test_trap_set1 | test_trap_set2;
+	cfg_clear = test_trap_clear0 | test_trap_clear1 | test_trap_clear2;
+
+	id_reg_features_trap_activate(vcpu, &id_reg_data);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_set, cfg_set);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2 & cfg_clear, 0);
+
+
+	/* Test with id_reg_info == NULL */
+	vcpu->arch.hcr_el2 = 0;
+	id_reg_features_trap_activate(vcpu, NULL);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0);
+
+
+	/* Test with id_reg_data.trap_features = NULL */
+	id_reg_data.trap_features = NULL;
+	vcpu->arch.hcr_el2 = 0;
+	id_reg_features_trap_activate(vcpu, &id_reg_data);
+	KUNIT_EXPECT_EQ(test, vcpu->arch.hcr_el2, 0);
+
+}
+
+/* Tests for vcpu_need_trap_ptrauth(). */
+static void vcpu_need_trap_ptrauth_test(struct kunit *test)
+{
+	struct kvm_vcpu *vcpu;
+	u32 id = SYS_ID_AA64ISAR1_EL1;
+
+	vcpu = test_kvm_vcpu_init(test);
+	KUNIT_EXPECT_TRUE(test, vcpu);
+	if (!vcpu)
+		return;
+
+	if (system_has_full_ptr_auth()) {
+		/* Tests with PTRAUTH disabled vCPU */
+		write_kvm_id_reg(vcpu->kvm, id, 0x0);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPI = 1, API = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x10000100);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPI = 1, APA = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x10000010);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPA = 1, API = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x01000100);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPA = 1, APA = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x01000010);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+
+		/* Tests with PTRAUTH enabled vCPU */
+		vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_PTRAUTH;
+
+		write_kvm_id_reg(vcpu->kvm, id, 0x0);
+		KUNIT_EXPECT_TRUE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPI = 1, API = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x10000100);
+		KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPI = 1, APA = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x10000010);
+		KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPA = 1, API = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x01000100);
+		KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu));
+
+		/* GPA = 1, APA = 1 */
+		write_kvm_id_reg(vcpu->kvm, id, 0x01000010);
+		KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu));
+	} else {
+		KUNIT_EXPECT_FALSE(test, vcpu_need_trap_ptrauth(vcpu));
+	}
+}
+
 static struct kunit_case kvm_sys_regs_test_cases[] = {
 	KUNIT_CASE_PARAM(vcpu_id_reg_feature_frac_check_test, frac_gen_params),
 	KUNIT_CASE_PARAM(validate_id_aa64mmfr0_tgran2_test, tgran4_2_gen_params),
@@ -973,6 +1232,9 @@ static struct kunit_case kvm_sys_regs_test_cases[] = {
 	KUNIT_CASE(validate_id_dfr0_el1_test),
 	KUNIT_CASE(validate_mvfr1_el1_test),
 	KUNIT_CASE(validate_id_reg_test),
+	KUNIT_CASE(vcpu_need_trap_ptrauth_test),
+	KUNIT_CASE_PARAM(feature_trap_activate_test, trap_gen_params),
+	KUNIT_CASE(id_reg_features_trap_activate_test),
 	{}
 };
 
-- 
2.34.1.448.ga2b2bfdf31-goog



From reijiw at google.com  Wed Jan  5 20:27:08 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed,  5 Jan 2022 20:27:08 -0800
Subject: [RFC PATCH v4 26/26] KVM: arm64: selftests: Introduce id_reg_test
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <20220106042708.2869332-27-reijiw@google.com>

Introduce a test for aarch64 to validate basic behavior of
KVM_GET_ONE_REG and KVM_SET_ONE_REG for ID registers.

This test runs only when KVM_CAP_ARM_ID_REG_CONFIGURABLE is supported.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 tools/arch/arm64/include/asm/sysreg.h         |    1 +
 tools/testing/selftests/kvm/.gitignore        |    1 +
 tools/testing/selftests/kvm/Makefile          |    1 +
 .../selftests/kvm/aarch64/id_reg_test.c       | 1239 +++++++++++++++++
 4 files changed, 1242 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c

diff --git a/tools/arch/arm64/include/asm/sysreg.h b/tools/arch/arm64/include/asm/sysreg.h
index 7640fa27be94..be3947c125f1 100644
--- a/tools/arch/arm64/include/asm/sysreg.h
+++ b/tools/arch/arm64/include/asm/sysreg.h
@@ -793,6 +793,7 @@
 #define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
 
 /* id_aa64pfr1 */
+#define ID_AA64PFR1_CSV2FRAC_SHIFT	32
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
 #define ID_AA64PFR1_RASFRAC_SHIFT	12
 #define ID_AA64PFR1_MTE_SHIFT		8
diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 3cb5ac5da087..e0a5f304375d 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -2,6 +2,7 @@
 /aarch64/arch_timer
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
+/aarch64/id_reg_test
 /aarch64/psci_cpu_on_test
 /aarch64/vgic_init
 /s390x/memop
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 17342b575e85..0162a7d98889 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -94,6 +94,7 @@ TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
+TEST_GEN_PROGS_aarch64 += aarch64/id_reg_test
 TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
 TEST_GEN_PROGS_aarch64 += demand_paging_test
diff --git a/tools/testing/selftests/kvm/aarch64/id_reg_test.c b/tools/testing/selftests/kvm/aarch64/id_reg_test.c
new file mode 100644
index 000000000000..e2cac415ad57
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/id_reg_test.c
@@ -0,0 +1,1239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <time.h>
+#include <pthread.h>
+#include <linux/kvm.h>
+#include <linux/sizes.h>
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "vgic.h"
+
+/*
+ * id_reg_test.c - Tests reading/writing the aarch64's ID registers
+ *
+ * The test validates KVM_SET_ONE_REG/KVM_GET_ONE_REG ioctl for ID
+ * registers as well as reading ID register from the guest works fine.
+ */
+
+/* Reserved ID registers */
+#define	SYS_ID_REG_3_3_EL1		sys_reg(3, 0, 0, 3, 3)
+#define	SYS_ID_REG_3_7_EL1		sys_reg(3, 0, 0, 3, 7)
+
+#define	SYS_ID_REG_4_2_EL1		sys_reg(3, 0, 0, 4, 2)
+#define	SYS_ID_REG_4_3_EL1		sys_reg(3, 0, 0, 4, 3)
+#define	SYS_ID_REG_4_5_EL1		sys_reg(3, 0, 0, 4, 5)
+#define	SYS_ID_REG_4_6_EL1		sys_reg(3, 0, 0, 4, 6)
+#define	SYS_ID_REG_4_7_EL1		sys_reg(3, 0, 0, 4, 7)
+
+#define	SYS_ID_REG_5_2_EL1		sys_reg(3, 0, 0, 5, 2)
+#define	SYS_ID_REG_5_3_EL1		sys_reg(3, 0, 0, 5, 3)
+#define	SYS_ID_REG_5_6_EL1		sys_reg(3, 0, 0, 5, 6)
+#define	SYS_ID_REG_5_7_EL1		sys_reg(3, 0, 0, 5, 7)
+
+#define	SYS_ID_REG_6_2_EL1		sys_reg(3, 0, 0, 6, 2)
+#define	SYS_ID_REG_6_3_EL1		sys_reg(3, 0, 0, 6, 3)
+#define	SYS_ID_REG_6_4_EL1		sys_reg(3, 0, 0, 6, 4)
+#define	SYS_ID_REG_6_5_EL1		sys_reg(3, 0, 0, 6, 5)
+#define	SYS_ID_REG_6_6_EL1		sys_reg(3, 0, 0, 6, 6)
+#define	SYS_ID_REG_6_7_EL1		sys_reg(3, 0, 0, 6, 7)
+
+#define	SYS_ID_REG_7_3_EL1		sys_reg(3, 0, 0, 7, 3)
+#define	SYS_ID_REG_7_4_EL1		sys_reg(3, 0, 0, 7, 4)
+#define	SYS_ID_REG_7_5_EL1		sys_reg(3, 0, 0, 7, 5)
+#define	SYS_ID_REG_7_6_EL1		sys_reg(3, 0, 0, 7, 6)
+#define	SYS_ID_REG_7_7_EL1		sys_reg(3, 0, 0, 7, 7)
+
+#define	READ_ID_REG_FN(name)	read_## name ## _EL1
+
+#define	DEFINE_READ_SYS_REG(reg_name)			\
+uint64_t read_##reg_name(void)				\
+{							\
+	return read_sysreg_s(SYS_##reg_name);		\
+}
+
+#define DEFINE_READ_ID_REG(name)	\
+	DEFINE_READ_SYS_REG(name ## _EL1)
+
+#define	__ID_REG(reg_name)		\
+	.name = #reg_name,		\
+	.id = SYS_## reg_name ##_EL1,	\
+	.read_reg = READ_ID_REG_FN(reg_name),
+
+#define	ID_REG_ENT(reg_name)	\
+	[ID_IDX(reg_name)] = { __ID_REG(reg_name) }
+
+/* Functions to read each ID register */
+/* CRm=1 */
+DEFINE_READ_ID_REG(ID_PFR0)
+DEFINE_READ_ID_REG(ID_PFR1)
+DEFINE_READ_ID_REG(ID_DFR0)
+DEFINE_READ_ID_REG(ID_AFR0)
+DEFINE_READ_ID_REG(ID_MMFR0)
+DEFINE_READ_ID_REG(ID_MMFR1)
+DEFINE_READ_ID_REG(ID_MMFR2)
+DEFINE_READ_ID_REG(ID_MMFR3)
+
+/* CRm=2 */
+DEFINE_READ_ID_REG(ID_ISAR0)
+DEFINE_READ_ID_REG(ID_ISAR1)
+DEFINE_READ_ID_REG(ID_ISAR2)
+DEFINE_READ_ID_REG(ID_ISAR3)
+DEFINE_READ_ID_REG(ID_ISAR4)
+DEFINE_READ_ID_REG(ID_ISAR5)
+DEFINE_READ_ID_REG(ID_MMFR4)
+DEFINE_READ_ID_REG(ID_ISAR6)
+
+/* CRm=3 */
+DEFINE_READ_ID_REG(MVFR0)
+DEFINE_READ_ID_REG(MVFR1)
+DEFINE_READ_ID_REG(MVFR2)
+DEFINE_READ_ID_REG(ID_REG_3_3)
+DEFINE_READ_ID_REG(ID_PFR2)
+DEFINE_READ_ID_REG(ID_DFR1)
+DEFINE_READ_ID_REG(ID_MMFR5)
+DEFINE_READ_ID_REG(ID_REG_3_7)
+
+/* CRm=4 */
+DEFINE_READ_ID_REG(ID_AA64PFR0)
+DEFINE_READ_ID_REG(ID_AA64PFR1)
+DEFINE_READ_ID_REG(ID_REG_4_2)
+DEFINE_READ_ID_REG(ID_REG_4_3)
+DEFINE_READ_ID_REG(ID_AA64ZFR0)
+DEFINE_READ_ID_REG(ID_REG_4_5)
+DEFINE_READ_ID_REG(ID_REG_4_6)
+DEFINE_READ_ID_REG(ID_REG_4_7)
+
+/* CRm=5 */
+DEFINE_READ_ID_REG(ID_AA64DFR0)
+DEFINE_READ_ID_REG(ID_AA64DFR1)
+DEFINE_READ_ID_REG(ID_REG_5_2)
+DEFINE_READ_ID_REG(ID_REG_5_3)
+DEFINE_READ_ID_REG(ID_AA64AFR0)
+DEFINE_READ_ID_REG(ID_AA64AFR1)
+DEFINE_READ_ID_REG(ID_REG_5_6)
+DEFINE_READ_ID_REG(ID_REG_5_7)
+
+/* CRm=6 */
+DEFINE_READ_ID_REG(ID_AA64ISAR0)
+DEFINE_READ_ID_REG(ID_AA64ISAR1)
+DEFINE_READ_ID_REG(ID_REG_6_2)
+DEFINE_READ_ID_REG(ID_REG_6_3)
+DEFINE_READ_ID_REG(ID_REG_6_4)
+DEFINE_READ_ID_REG(ID_REG_6_5)
+DEFINE_READ_ID_REG(ID_REG_6_6)
+DEFINE_READ_ID_REG(ID_REG_6_7)
+
+/* CRm=7 */
+DEFINE_READ_ID_REG(ID_AA64MMFR0)
+DEFINE_READ_ID_REG(ID_AA64MMFR1)
+DEFINE_READ_ID_REG(ID_AA64MMFR2)
+DEFINE_READ_ID_REG(ID_REG_7_3)
+DEFINE_READ_ID_REG(ID_REG_7_4)
+DEFINE_READ_ID_REG(ID_REG_7_5)
+DEFINE_READ_ID_REG(ID_REG_7_6)
+DEFINE_READ_ID_REG(ID_REG_7_7)
+
+#define	ID_IDX(name)	REG_IDX_## name
+
+enum id_reg_idx {
+	/* CRm=1 */
+	ID_IDX(ID_PFR0) = 0,
+	ID_IDX(ID_PFR1),
+	ID_IDX(ID_DFR0),
+	ID_IDX(ID_AFR0),
+	ID_IDX(ID_MMFR0),
+	ID_IDX(ID_MMFR1),
+	ID_IDX(ID_MMFR2),
+	ID_IDX(ID_MMFR3),
+
+	/* CRm=2 */
+	ID_IDX(ID_ISAR0),
+	ID_IDX(ID_ISAR1),
+	ID_IDX(ID_ISAR2),
+	ID_IDX(ID_ISAR3),
+	ID_IDX(ID_ISAR4),
+	ID_IDX(ID_ISAR5),
+	ID_IDX(ID_MMFR4),
+	ID_IDX(ID_ISAR6),
+
+	/* CRm=3 */
+	ID_IDX(MVFR0),
+	ID_IDX(MVFR1),
+	ID_IDX(MVFR2),
+	ID_IDX(ID_REG_3_3),
+	ID_IDX(ID_PFR2),
+	ID_IDX(ID_DFR1),
+	ID_IDX(ID_MMFR5),
+	ID_IDX(ID_REG_3_7),
+
+	/* CRm=4 */
+	ID_IDX(ID_AA64PFR0),
+	ID_IDX(ID_AA64PFR1),
+	ID_IDX(ID_REG_4_2),
+	ID_IDX(ID_REG_4_3),
+	ID_IDX(ID_AA64ZFR0),
+	ID_IDX(ID_REG_4_5),
+	ID_IDX(ID_REG_4_6),
+	ID_IDX(ID_REG_4_7),
+
+	/* CRm=5 */
+	ID_IDX(ID_AA64DFR0),
+	ID_IDX(ID_AA64DFR1),
+	ID_IDX(ID_REG_5_2),
+	ID_IDX(ID_REG_5_3),
+	ID_IDX(ID_AA64AFR0),
+	ID_IDX(ID_AA64AFR1),
+	ID_IDX(ID_REG_5_6),
+	ID_IDX(ID_REG_5_7),
+
+	/* CRm=6 */
+	ID_IDX(ID_AA64ISAR0),
+	ID_IDX(ID_AA64ISAR1),
+	ID_IDX(ID_REG_6_2),
+	ID_IDX(ID_REG_6_3),
+	ID_IDX(ID_REG_6_4),
+	ID_IDX(ID_REG_6_5),
+	ID_IDX(ID_REG_6_6),
+	ID_IDX(ID_REG_6_7),
+
+	/* CRm=7 */
+	ID_IDX(ID_AA64MMFR0),
+	ID_IDX(ID_AA64MMFR1),
+	ID_IDX(ID_AA64MMFR2),
+	ID_IDX(ID_REG_7_3),
+	ID_IDX(ID_REG_7_4),
+	ID_IDX(ID_REG_7_5),
+	ID_IDX(ID_REG_7_6),
+	ID_IDX(ID_REG_7_7),
+};
+
+struct id_reg_test_info {
+	char		*name;
+	uint32_t	id;
+	/* Indicates the register can be set to 0 */
+	bool		can_clear;
+	uint64_t	initial_value;
+	uint64_t	current_value;
+	uint64_t	(*read_reg)(void);
+};
+
+#define	ID_REG_INFO(name)	(&id_reg_list[ID_IDX(name)])
+static struct id_reg_test_info id_reg_list[] = {
+	/* CRm=1 */
+	ID_REG_ENT(ID_PFR0),
+	ID_REG_ENT(ID_PFR1),
+	ID_REG_ENT(ID_DFR0),
+	ID_REG_ENT(ID_AFR0),
+	ID_REG_ENT(ID_MMFR0),
+	ID_REG_ENT(ID_MMFR1),
+	ID_REG_ENT(ID_MMFR2),
+	ID_REG_ENT(ID_MMFR3),
+
+	/* CRm=2 */
+	ID_REG_ENT(ID_ISAR0),
+	ID_REG_ENT(ID_ISAR1),
+	ID_REG_ENT(ID_ISAR2),
+	ID_REG_ENT(ID_ISAR3),
+	ID_REG_ENT(ID_ISAR4),
+	ID_REG_ENT(ID_ISAR5),
+	ID_REG_ENT(ID_MMFR4),
+	ID_REG_ENT(ID_ISAR6),
+
+	/* CRm=3 */
+	ID_REG_ENT(MVFR0),
+	ID_REG_ENT(MVFR1),
+	ID_REG_ENT(MVFR2),
+	ID_REG_ENT(ID_REG_3_3),
+	ID_REG_ENT(ID_PFR2),
+	ID_REG_ENT(ID_DFR1),
+	ID_REG_ENT(ID_MMFR5),
+	ID_REG_ENT(ID_REG_3_7),
+
+	/* CRm=4 */
+	ID_REG_ENT(ID_AA64PFR0),
+	ID_REG_ENT(ID_AA64PFR1),
+	ID_REG_ENT(ID_REG_4_2),
+	ID_REG_ENT(ID_REG_4_3),
+	ID_REG_ENT(ID_AA64ZFR0),
+	ID_REG_ENT(ID_REG_4_5),
+	ID_REG_ENT(ID_REG_4_6),
+	ID_REG_ENT(ID_REG_4_7),
+
+	/* CRm=5 */
+	ID_REG_ENT(ID_AA64DFR0),
+	ID_REG_ENT(ID_AA64DFR1),
+	ID_REG_ENT(ID_REG_5_2),
+	ID_REG_ENT(ID_REG_5_3),
+	ID_REG_ENT(ID_AA64AFR0),
+	ID_REG_ENT(ID_AA64AFR1),
+	ID_REG_ENT(ID_REG_5_6),
+	ID_REG_ENT(ID_REG_5_7),
+
+	/* CRm=6 */
+	ID_REG_ENT(ID_AA64ISAR0),
+	ID_REG_ENT(ID_AA64ISAR1),
+	ID_REG_ENT(ID_REG_6_2),
+	ID_REG_ENT(ID_REG_6_3),
+	ID_REG_ENT(ID_REG_6_4),
+	ID_REG_ENT(ID_REG_6_5),
+	ID_REG_ENT(ID_REG_6_6),
+	ID_REG_ENT(ID_REG_6_7),
+
+	/* CRm=7 */
+	ID_REG_ENT(ID_AA64MMFR0),
+	ID_REG_ENT(ID_AA64MMFR1),
+	ID_REG_ENT(ID_AA64MMFR2),
+	ID_REG_ENT(ID_REG_7_3),
+	ID_REG_ENT(ID_REG_7_4),
+	ID_REG_ENT(ID_REG_7_5),
+	ID_REG_ENT(ID_REG_7_6),
+	ID_REG_ENT(ID_REG_7_7),
+};
+
+static bool aarch32_support = true;
+
+/* Utilities to get a feature field from ID register value */
+static inline int
+cpuid_signed_field_width(uint64_t id_val, int field, int width)
+{
+	return (s64)(id_val << (64 - width - field)) >> (64 - width);
+}
+
+static unsigned int
+cpuid_unsigned_field_width(uint64_t id_val, int field, int width)
+{
+	return (uint64_t)(id_val << (64 - width - field)) >> (64 - width);
+}
+
+static inline int __attribute_const__
+cpuid_extract_field_width(uint64_t id_val, int field, int width, bool sign)
+{
+	return (sign) ? cpuid_signed_field_width(id_val, field, width) :
+			cpuid_unsigned_field_width(id_val, field, width);
+}
+
+#define is_id_reg(id)	\
+	(sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&	\
+	 sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&	\
+	 sys_reg_CRm(id) < 8)
+
+#define	GET_ID_FIELD(regval, shift, is_signed)	\
+	cpuid_extract_field_width(regval, shift, 4, is_signed)
+
+#define	GET_ID_UFIELD(regval, shift)	\
+	cpuid_unsigned_field_width(regval, shift, 4)
+
+#define	UPDATE_ID_UFIELD(regval, shift, fval)	\
+	(((regval) & ~(0xfULL << (shift))) |	\
+	 (((uint64_t)((fval) & 0xf)) << (shift)))
+
+void pmu_init(struct kvm_vm *vm, uint32_t vcpu)
+{
+	struct kvm_device_attr attr = {
+		.group = KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr = KVM_ARM_VCPU_PMU_V3_INIT,
+	};
+	vcpu_ioctl(vm, vcpu, KVM_SET_DEVICE_ATTR, &attr);
+}
+
+void sve_init(struct kvm_vm *vm, uint32_t vcpu)
+{
+	int feature = KVM_ARM_VCPU_SVE;
+
+	vcpu_ioctl(vm, vcpu, KVM_ARM_VCPU_FINALIZE, &feature);
+}
+
+#define GICD_BASE_GPA			0x8000000ULL
+#define GICR_BASE_GPA			0x80A0000ULL
+
+void test_vgic_init(struct kvm_vm *vm, uint32_t vcpu)
+{
+	/* We jsut need to configure gic v3 (we don't use it though) */
+	vgic_v3_setup(vm, 1, GICD_BASE_GPA, GICR_BASE_GPA);
+}
+
+static bool is_aarch32_id_reg(uint32_t id)
+{
+	uint32_t crm, op2;
+
+	if (!is_id_reg(id))
+		return false;
+
+	crm = sys_reg_CRm(id);
+	op2 = sys_reg_Op2(id);
+	if (crm == 1 || crm == 2 || (crm == 3 && (op2 != 3 && op2 != 7)))
+		/* AArch32 ID register */
+		return true;
+
+	return false;
+}
+
+#define	MAX_CAPS	2
+struct feature_test_info {
+	char	*name;	/* Feature Name (Debug information) */
+
+	/* ID register that identifies the presence of the feature */
+	struct id_reg_test_info	*sreg;
+
+	/*
+	 * Bit position of the ID register field that identifies
+	 * the presence of the feature.
+	 */
+	int	shift;
+
+	/* Min value of the field that indicates the presence of the feature. */
+	int	min;
+	bool	is_sign;	/* Is the field signed or unsigned ? */
+	int	ncaps;		/* Number of valid Capabilities in caps[] */
+
+	/* KVM_CAP_* Capabilities to indicates that KVM supports this feature */
+	long	caps[MAX_CAPS];
+
+	/* struct kvm_enable_cap to use the capability if needed */
+	struct kvm_enable_cap	*opt_in_cap;
+
+	/* Should the guest check the ID register for this feature ? */
+	bool	run_test;
+
+	/*
+	 * Extra initialization function to enable the feature if needed.
+	 * (e.g. KVM_ARM_VCPU_FINALIZE for SVE)
+	 */
+	void	(*init_feature)(struct kvm_vm *vm, uint32_t vcpuid);
+
+	/* struct kvm_vcpu_init to opt-in the feature if needed */
+	struct kvm_vcpu_init	*vcpu_init;
+};
+
+/* Information for opt-in CPU features */
+static struct feature_test_info feature_test_info_table[] = {
+	{
+		.name = "SVE",
+		.sreg = ID_REG_INFO(ID_AA64PFR0),
+		.shift = ID_AA64PFR0_SVE_SHIFT,
+		.min = 1,
+		.caps = {KVM_CAP_ARM_SVE},
+		.ncaps = 1,
+		.init_feature = sve_init,
+		.vcpu_init = &(struct kvm_vcpu_init) {
+			.features = {1ULL << KVM_ARM_VCPU_SVE},
+		},
+	},
+	{
+		.name = "GIC",
+		.sreg = ID_REG_INFO(ID_AA64PFR0),
+		.shift = ID_AA64PFR0_GIC_SHIFT,
+		.min = 1,
+		.caps = {KVM_CAP_IRQCHIP},
+		.ncaps = 1,
+		.init_feature = test_vgic_init,
+	},
+	{
+		.name = "MTE",
+		.sreg = ID_REG_INFO(ID_AA64PFR1),
+		.shift = ID_AA64PFR1_MTE_SHIFT,
+		.min = 2,
+		.caps = {KVM_CAP_ARM_MTE},
+		.ncaps = 1,
+		.opt_in_cap = &(struct kvm_enable_cap) {
+				.cap = KVM_CAP_ARM_MTE,
+		},
+	},
+	{
+		.name = "PMUV3",
+		.sreg = ID_REG_INFO(ID_AA64DFR0),
+		.shift = ID_AA64DFR0_PMUVER_SHIFT,
+		.min = 1,
+		.init_feature = pmu_init,
+		.caps = {KVM_CAP_ARM_PMU_V3},
+		.ncaps = 1,
+		.vcpu_init = &(struct kvm_vcpu_init) {
+			.features = {1ULL << KVM_ARM_VCPU_PMU_V3},
+		},
+	},
+	{
+		.name = "PERFMON",
+		.sreg = ID_REG_INFO(ID_DFR0),
+		.shift = ID_DFR0_PERFMON_SHIFT,
+		.min = 3,
+		.init_feature = pmu_init,
+		.caps = {KVM_CAP_ARM_PMU_V3},
+		.ncaps = 1,
+		.vcpu_init = &(struct kvm_vcpu_init) {
+			.features = {1ULL << KVM_ARM_VCPU_PMU_V3},
+		},
+	},
+};
+
+static void walk_id_reg_list(void (*fn)(struct id_reg_test_info *r, void *arg),
+			     void *arg)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(id_reg_list); i++)
+		fn(&id_reg_list[i], arg);
+}
+
+static void guest_code_id_reg_check_one(struct id_reg_test_info *idr, void *arg)
+{
+	uint64_t v = idr->read_reg();
+
+	GUEST_ASSERT_2(v == idr->current_value, idr->name, idr->current_value);
+}
+
+static void guest_code_id_reg_check_all(uint32_t cpu)
+{
+	walk_id_reg_list(guest_code_id_reg_check_one, NULL);
+	GUEST_DONE();
+}
+
+static void guest_code_do_nothing(uint32_t cpu)
+{
+	GUEST_DONE();
+}
+
+static void guest_code_feature_check(uint32_t cpu)
+{
+	int i;
+	struct feature_test_info *finfo;
+
+	for (i = 0; i < ARRAY_SIZE(feature_test_info_table); i++) {
+		finfo = &feature_test_info_table[i];
+		if (finfo->run_test)
+			guest_code_id_reg_check_one(finfo->sreg, NULL);
+	}
+
+	GUEST_DONE();
+}
+
+static void guest_code_ptrauth_check(uint32_t cpuid)
+{
+	struct id_reg_test_info *sreg = ID_REG_INFO(ID_AA64ISAR1);
+	uint64_t val = sreg->read_reg();
+
+	GUEST_ASSERT_2(val == sreg->current_value, "PTRAUTH", val);
+	GUEST_DONE();
+}
+
+static void reset_id_reg_info_current_value(struct id_reg_test_info *info,
+					    void *arg)
+{
+	info->current_value = info->initial_value;
+}
+
+/* Reset current_value field of each id_reg_test_info */
+static void reset_id_reg_info(void)
+{
+	walk_id_reg_list(reset_id_reg_info_current_value, NULL);
+}
+
+static struct kvm_vm *test_vm_create(uint32_t nvcpus,
+		void (*guest_code)(uint32_t), struct kvm_vcpu_init *init,
+		struct kvm_enable_cap *cap)
+{
+	struct kvm_vm *vm;
+	uint32_t cpuid;
+	uint64_t mem_pages;
+
+	mem_pages = DEFAULT_GUEST_PHY_PAGES + DEFAULT_STACK_PGS * nvcpus;
+	mem_pages += mem_pages / (PTES_PER_MIN_PAGE * 2);
+	mem_pages = vm_adjust_num_guest_pages(VM_MODE_DEFAULT, mem_pages);
+
+	vm = vm_create(VM_MODE_DEFAULT, mem_pages, O_RDWR);
+	if (cap)
+		vm_enable_cap(vm, cap);
+
+	kvm_vm_elf_load(vm, program_invocation_name);
+
+	if (init && init->target == -1) {
+		struct kvm_vcpu_init preferred;
+
+		vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &preferred);
+		init->target = preferred.target;
+	}
+
+	vm_init_descriptor_tables(vm);
+	for (cpuid = 0; cpuid < nvcpus; cpuid++) {
+		aarch64_vcpu_add_default(vm, cpuid, init, guest_code);
+		vcpu_init_descriptor_tables(vm, cpuid);
+	}
+
+	ucall_init(vm, NULL);
+	return vm;
+}
+
+static void test_vm_free(struct kvm_vm *vm)
+{
+	ucall_uninit(vm);
+	kvm_vm_free(vm);
+}
+
+#define	TEST_RUN(vm, cpu)	\
+	(test_vcpu_run(__func__, __LINE__, vm, cpu, true))
+
+#define	TEST_RUN_NO_SYNC_DATA(vm, cpu)	\
+	(test_vcpu_run(__func__, __LINE__, vm, cpu, false))
+
+static int test_vcpu_run(const char *test_name, int line,
+			 struct kvm_vm *vm, uint32_t vcpuid, bool sync_data)
+{
+	struct ucall uc;
+	int ret;
+
+	if (sync_data) {
+		sync_global_to_guest(vm, id_reg_list);
+		sync_global_to_guest(vm, feature_test_info_table);
+	}
+
+	vcpu_args_set(vm, vcpuid, 1, vcpuid);
+
+	ret = _vcpu_run(vm, vcpuid);
+	if (ret) {
+		ret = errno;
+		goto sync_exit;
+	}
+
+	switch (get_ucall(vm, vcpuid, &uc)) {
+	case UCALL_SYNC:
+	case UCALL_DONE:
+		ret = 0;
+		break;
+	case UCALL_ABORT:
+		TEST_FAIL(
+		    "%s (%s) at line %d (user %s at line %d), args[3]=0x%lx",
+		    (char *)uc.args[0], (char *)uc.args[2], (int)uc.args[1],
+		    test_name, line, uc.args[3]);
+		break;
+	default:
+		TEST_FAIL("Unexpected guest exit\n");
+	}
+
+sync_exit:
+	if (sync_data) {
+		sync_global_from_guest(vm, id_reg_list);
+		sync_global_from_guest(vm, feature_test_info_table);
+	}
+	return ret;
+}
+
+struct vm_vcpu_arg {
+	struct kvm_vm	*vm;
+	uint32_t	vcpuid;
+	bool		after_run;
+};
+
+/*
+ * Test if KVM_SET_ONE_REG can work with the value KVM_GET_ONE_REG returns,
+ * KVM_SET_ONE_REG with zero works before KVM_RUN (and fails after KVM_RUN),
+ * and KVM_GET_ONE_REG returns the value KVM_SET_ONE_REG sets.
+ */
+static void test_get_set_id_reg(struct id_reg_test_info *sreg, void *arg)
+{
+	struct kvm_vm *vm = ((struct vm_vcpu_arg *)arg)->vm;
+	uint32_t vcpuid = ((struct vm_vcpu_arg *)arg)->vcpuid;
+	bool after_run = ((struct vm_vcpu_arg *)arg)->after_run;
+	struct kvm_one_reg one_reg;
+	uint64_t reg_val, tval;
+	int ret;
+
+	one_reg.addr = (uint64_t)&reg_val;
+	one_reg.id = KVM_ARM64_SYS_REG(sreg->id);
+
+	/* Check the current register value */
+	vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg);
+	TEST_ASSERT(reg_val == sreg->current_value,
+		    "GET(%s) didn't return 0x%lx but 0x%lx",
+		    sreg->name, sreg->current_value, reg_val);
+	tval = reg_val;
+
+	/* Try to clear the register that should be able to be cleared. */
+	if ((reg_val != 0) && (sreg->can_clear)) {
+		reg_val = 0;
+		ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg);
+		if (after_run) {
+			/* Expect an error after KVM_RUN */
+			TEST_ASSERT(ret,
+				    "Clearing %s unexpectedly worked\n",
+				    sreg->name);
+		} else {
+			TEST_ASSERT(!ret,
+				    "Clearing %s didn't work\n", sreg->name);
+			/*
+			 * Make sure that KVM_GET_ONE_REG provides the value
+			 * we set.
+			 */
+			vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg);
+			TEST_ASSERT(reg_val == 0,
+				    "GET(%s) didn't return 0x%lx but 0x%lx",
+				    sreg->name, (uint64_t)0, reg_val);
+		}
+	}
+
+	/* Check if KVM_SET_ONE_REG works with the original value. */
+	reg_val = tval;
+	ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg);
+	TEST_ASSERT(ret == 0, "Setting the same ID reg value should work\n");
+
+	/* Make sure that KVM_GET_ONE_REG provides the value we set. */
+	vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg);
+	TEST_ASSERT(reg_val == tval,
+		    "GET(%s) didn't return 0x%lx but 0x%lx",
+		    sreg->name, sreg->current_value, reg_val);
+}
+
+/*
+ * Test if KVM_SET_ONE_REG with the current value works before KVM_RUN,
+ * values of ID registers the guest sees are consistent with the ones
+ * userspace sees, and KVM_SET_ONE_REG after KVM_RUN works when the
+ * specified value is the same as the current one (fails otherwise).
+ */
+static void test_id_regs_basic(void)
+{
+	struct kvm_vm *vm;
+	struct vm_vcpu_arg arg = { .vcpuid = 0 };
+	int ret;
+
+	reset_id_reg_info();
+
+	vm = test_vm_create(1, guest_code_id_reg_check_all, NULL, NULL);
+
+	arg.vm = vm;
+	walk_id_reg_list(test_get_set_id_reg, &arg);
+
+	ret = TEST_RUN(vm, 0);
+	assert(!ret);
+
+	arg.after_run = true;
+	walk_id_reg_list(test_get_set_id_reg, &arg);
+
+	test_vm_free(vm);
+}
+
+static bool caps_are_supported(long *caps, int ncaps)
+{
+	int i;
+
+	for (i = 0; i < ncaps; i++) {
+		if (kvm_check_cap(caps[i]) <= 0)
+			return false;
+	}
+	return true;
+}
+
+#define	NCAPS_PTRAUTH	2
+
+/*
+ * Test if the ID register value reflects the ptrauth feature configuration.
+ * KVM_SET_ONE_REG should work as long as the requested value is consistent
+ * with the ptrauth feature configuration.
+ */
+static void test_feature_ptrauth(void)
+{
+	struct kvm_one_reg one_reg;
+	struct kvm_vcpu_init init;
+	struct kvm_vm *vm = NULL;
+	struct id_reg_test_info *sreg = ID_REG_INFO(ID_AA64ISAR1);
+	uint32_t vcpu = 0;
+	int64_t rval;
+	int ret;
+	int apa, api, gpa, gpi;
+	char *name = "PTRAUTH";
+	long caps[NCAPS_PTRAUTH] = {KVM_CAP_ARM_PTRAUTH_ADDRESS,
+				    KVM_CAP_ARM_PTRAUTH_GENERIC};
+
+	reset_id_reg_info();
+	one_reg.addr = (uint64_t)&rval;
+	one_reg.id = KVM_ARM64_SYS_REG(sreg->id);
+
+	if (caps_are_supported(caps, NCAPS_PTRAUTH)) {
+
+		/* Test with feature enabled */
+		memset(&init, 0, sizeof(init));
+		init.target = -1;
+		init.features[0] = (1ULL << KVM_ARM_VCPU_PTRAUTH_ADDRESS |
+				    1ULL << KVM_ARM_VCPU_PTRAUTH_GENERIC);
+		vm = test_vm_create(1, guest_code_ptrauth_check, &init, NULL);
+		vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg);
+
+		/* Make sure values of apa/api/gpa/gpi fields are expected */
+		apa = GET_ID_UFIELD(rval, ID_AA64ISAR1_APA_SHIFT);
+		api = GET_ID_UFIELD(rval, ID_AA64ISAR1_API_SHIFT);
+		gpa = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPA_SHIFT);
+		gpi = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPI_SHIFT);
+
+		TEST_ASSERT((apa > 0) || (api > 0),
+			    "Either apa(0x%x) or api(0x%x) must be available",
+			    apa, gpa);
+		TEST_ASSERT((gpa > 0) || (gpi > 0),
+			    "Either gpa(0x%x) or gpi(0x%x) must be available",
+			    gpa, gpi);
+
+		TEST_ASSERT((apa > 0) ^ (api > 0),
+			    "Both apa(0x%x) and api(0x%x) must not be available",
+			    apa, api);
+		TEST_ASSERT((gpa > 0) ^ (gpi > 0),
+			    "Both gpa(0x%x) and gpi(0x%x) must not be available",
+			    gpa, gpi);
+
+		sreg->current_value = rval;
+
+		pr_debug("%s: Test with %s enabled (%s: 0x%lx)\n",
+			 __func__, name, sreg->name, sreg->current_value);
+
+		/* Make sure that the guest sees the same ID register value. */
+		ret = TEST_RUN(vm, vcpu);
+
+		TEST_ASSERT(!ret, "%s:KVM_RUN failed with %s enabled",
+			    __func__, name);
+		test_vm_free(vm);
+	}
+
+	reset_id_reg_info();
+
+	/* Test with feature disabled */
+	vm = test_vm_create(1, guest_code_feature_check, NULL, NULL);
+	vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg);
+
+	apa = GET_ID_UFIELD(rval, ID_AA64ISAR1_APA_SHIFT);
+	api = GET_ID_UFIELD(rval, ID_AA64ISAR1_API_SHIFT);
+	gpa = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPA_SHIFT);
+	gpi = GET_ID_UFIELD(rval, ID_AA64ISAR1_GPI_SHIFT);
+	TEST_ASSERT(!apa && !api && !gpa && !gpi,
+	    "apa(0x%x), api(0x%x), gpa(0x%x), gpi(0x%x) must be zero",
+	    apa, api, gpa, gpi);
+
+	pr_debug("%s: Test with %s disabled (%s: 0x%lx)\n",
+		 __func__, name, sreg->name, sreg->current_value);
+
+	/* Make sure that the guest sees the same ID register value. */
+	ret = TEST_RUN(vm, vcpu);
+	TEST_ASSERT(!ret, "%s TEST_RUN failed with %s enabled, ret=0x%x",
+		    __func__, name, ret);
+
+	test_vm_free(vm);
+}
+
+static bool feature_caps_are_available(struct feature_test_info *finfo)
+{
+	return ((finfo->ncaps > 0) &&
+		caps_are_supported(finfo->caps, finfo->ncaps));
+}
+
+/*
+ * Test if the ID register value reflects the feature configuration.
+ * KVM_SET_ONE_REG should work as long as the requested value is
+ * consistent with the feature configuration.
+ */
+static void test_feature(struct feature_test_info *finfo)
+{
+	struct id_reg_test_info *sreg = finfo->sreg;
+	struct kvm_one_reg one_reg;
+	struct kvm_vcpu_init init, *initp = NULL;
+	struct kvm_vm *vm = NULL;
+	int64_t fval, reg_val;
+	uint32_t vcpu = 0;
+	bool is_sign = finfo->is_sign;
+	int min = finfo->min;
+	int shift = finfo->shift;
+	int ret;
+
+	pr_debug("%s: %s (reg %s)\n", __func__, finfo->name, sreg->name);
+
+	reset_id_reg_info();
+
+	if (is_aarch32_id_reg(sreg->id) && !aarch32_support)
+		/*
+		 * AArch32 is not supported. Skip testing with the AArch32
+		 * ID register.
+		 */
+		return;
+
+	/* Indicate that guest runs the test for the feature */
+	finfo->run_test = 1;
+	one_reg.addr = (uint64_t)&reg_val;
+	one_reg.id = KVM_ARM64_SYS_REG(sreg->id);
+
+	/*
+	 * Test with feature enabled if the feature is exposed in the default
+	 * ID register value or the capabilities are supported at KVM level.
+	 */
+	if ((GET_ID_FIELD(sreg->initial_value, shift, is_sign) >= min) ||
+	    feature_caps_are_available(finfo)) {
+		if (finfo->vcpu_init) {
+			/* Need to enable the feature via KVM_ARM_VCPU_INIT. */
+			memset(&init, 0, sizeof(init));
+			init = *finfo->vcpu_init;
+			init.target = -1;
+			initp = &init;
+		}
+
+		vm = test_vm_create(1, guest_code_feature_check, initp,
+				    finfo->opt_in_cap);
+		if (finfo->init_feature)
+			/* Run any required extra process to use the feature */
+			finfo->init_feature(vm, vcpu);
+
+		/* Check if the ID register value indicates the feature */
+		vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg);
+		fval = GET_ID_FIELD(reg_val, shift, is_sign);
+		TEST_ASSERT(fval >= min, "%s field of %s is too small (%ld)",
+			    finfo->name, sreg->name, fval);
+		sreg->current_value = reg_val;
+
+		pr_debug("%s: Test with %s enabled (%s: 0x%lx)\n", __func__,
+			 finfo->name, sreg->name, sreg->current_value);
+
+		/* Make sure that the guest sees the same ID register value. */
+		ret = TEST_RUN(vm, vcpu);
+		TEST_ASSERT(!ret, "%s:TEST_RUN failed with %s enabled",
+			    __func__, finfo->name);
+
+		test_vm_free(vm);
+	}
+
+	reset_id_reg_info();
+
+	/* Test with feature disabled */
+	vm = test_vm_create(1, guest_code_feature_check, NULL, NULL);
+	vcpu_ioctl(vm, vcpu, KVM_GET_ONE_REG, &one_reg);
+	fval = GET_ID_FIELD(reg_val, shift, is_sign);
+	if (finfo->vcpu_init || finfo->opt_in_cap) {
+		/*
+		 * If the feature needs to be enabled with KVM_ARM_VCPU_INIT
+		 * or opt-in capabilities, the default value of the ID register
+		 * shouldn't indicate the feature.
+		 */
+		TEST_ASSERT(fval < min, "%s field of %s is too big (%ld)",
+		    finfo->name, sreg->name, fval);
+	} else {
+		/* Update the relevant field to hide the feature. */
+		fval = is_sign ? 0xf : 0x0;
+		reg_val = UPDATE_ID_UFIELD(reg_val, shift, fval);
+		ret = _vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg);
+		TEST_ASSERT(ret == 0, "Disabling %s failed %d\n",
+			    finfo->name, ret);
+		sreg->current_value = reg_val;
+	}
+
+	pr_debug("%s: Test with %s disabled (%s: 0x%lx)\n",
+		 __func__, finfo->name, sreg->name, sreg->current_value);
+
+	/* Make sure that the guest sees the same ID register value. */
+	ret = TEST_RUN(vm, vcpu);
+	finfo->run_test = 0;
+	test_vm_free(vm);
+}
+
+/*
+ * For each opt-in feature in feature_test_info_table[],
+ * test if KVM_GET_ONE_REG/KVM_SET_ONE_REG works appropriately according
+ * to the feature configuration.  See test_feature's comment for more detail.
+ */
+static void test_feature_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(feature_test_info_table); i++)
+		test_feature(&feature_test_info_table[i]);
+}
+
+int set_id_reg(struct kvm_vm *vm, uint32_t vcpu, struct id_reg_test_info *sreg,
+	       uint64_t new_val)
+{
+	int ret;
+	uint64_t reg_val;
+	struct kvm_one_reg one_reg;
+
+	one_reg.id = KVM_ARM64_SYS_REG(sreg->id);
+	one_reg.addr = (uint64_t)&reg_val;
+
+	reg_val = new_val;
+	ret = _vcpu_ioctl(vm, vcpu, KVM_SET_ONE_REG, &one_reg);
+	if (!ret)
+		sreg->current_value = new_val;
+
+	return ret;
+}
+
+
+/*
+ * Create a new VM with one vCPU, set the ID register to @new_val.
+ */
+int set_id_reg_vm(struct id_reg_test_info *sreg, uint64_t new_val)
+{
+	struct kvm_vm *vm;
+	int ret;
+	uint32_t vcpu = 0;
+
+	reset_id_reg_info();
+
+	vm = test_vm_create(1, guest_code_id_reg_check_all, NULL, NULL);
+	ret = set_id_reg(vm, vcpu, sreg, new_val);
+	test_vm_free(vm);
+
+	return ret;
+}
+
+struct frac_info {
+	char	*name;
+	struct id_reg_test_info *sreg;
+	struct id_reg_test_info *frac_sreg;
+	int	shift;
+	int	frac_shift;
+};
+
+struct frac_info frac_info_table[] = {
+	{
+		.name = "RAS",
+		.sreg = ID_REG_INFO(ID_AA64PFR0),
+		.shift = ID_AA64PFR0_RAS_SHIFT,
+		.frac_sreg = ID_REG_INFO(ID_AA64PFR1),
+		.frac_shift = ID_AA64PFR1_RASFRAC_SHIFT,
+	},
+	{
+		.name = "MPAM",
+		.sreg = ID_REG_INFO(ID_AA64PFR0),
+		.shift = ID_AA64PFR0_MPAM_SHIFT,
+		.frac_sreg = ID_REG_INFO(ID_AA64PFR1),
+		.frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT,
+	},
+	{
+		.name = "CSV2",
+		.sreg = ID_REG_INFO(ID_AA64PFR0),
+		.shift = ID_AA64PFR0_CSV2_SHIFT,
+		.frac_sreg = ID_REG_INFO(ID_AA64PFR1),
+		.frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT,
+	},
+};
+
+
+/*
+ * Make sure that we can set the fractional reg field even before setting
+ * the feature reg field.
+ */
+int test_feature_frac_vm(struct frac_info *frac, uint64_t new_val,
+			 uint64_t frac_new_val)
+{
+	struct kvm_vm *vm;
+	uint32_t vcpu = 0;
+	struct id_reg_test_info *sreg, *frac_sreg;
+	int ret;
+
+	sreg = frac->sreg;
+	frac_sreg = frac->frac_sreg;
+	reset_id_reg_info();
+
+	reset_id_reg_info();
+
+	vm = test_vm_create(1, guest_code_id_reg_check_all, NULL, NULL);
+
+	/* Set fractional reg field */
+	ret = set_id_reg(vm, vcpu, frac_sreg, frac_new_val);
+	TEST_ASSERT(!ret, "SET_REG(%s=0x%lx) failed, ret=0x%x",
+		    frac_sreg->name, frac_new_val, ret);
+
+	/* Set feature reg field */
+	ret = set_id_reg(vm, vcpu, sreg, new_val);
+	TEST_ASSERT(!ret, "SET_REG(%s=0x%lx) failed, ret=0x%x",
+		    sreg->name, new_val, ret);
+
+	ret = TEST_RUN(vm, vcpu);
+	test_vm_free(vm);
+
+	return ret;
+}
+
+/*
+ * Test for setting the feature fractional field of the ID register.
+ * When the (main) feature field of the ID register is the same as the host's,
+ * the fractional field value cannot be larger than the host's.
+ * (KVM_SET_ONE_REG should work but KVM_RUN with the larger value will fail)
+ * When the (main) feature field of the ID register is smaler than the host's,
+ * the fractional field can be any values.
+ * The function tests those behaviors.
+ */
+void test_feature_frac_one(struct frac_info *frac)
+{
+	uint64_t ftr_val, ftr_fval, frac_val, frac_fval;
+	int ret, shift, frac_shift;
+	struct id_reg_test_info *sreg, *frac_sreg;
+
+	reset_id_reg_info();
+
+	sreg = frac->sreg;
+	shift = frac->shift;
+	frac_sreg = frac->frac_sreg;
+	frac_shift = frac->frac_shift;
+
+	pr_debug("%s(%s Frac) reg:%s(shift:%d) frac reg:%s(shift:%d)\n",
+		 __func__, frac->name, sreg->name, shift, frac_sreg->name,
+		 frac_shift);
+
+	/*
+	 * Use the host's feature value for the guest.
+	 * KVM_RUN with a larger frac value than the host's should fail.
+	 * Otherwise, it should work.
+	 */
+
+	frac_fval = GET_ID_UFIELD(frac_sreg->initial_value, frac_shift);
+	if (frac_fval > 0) {
+		/* Test with smaller frac value */
+		frac_val = UPDATE_ID_UFIELD(frac_sreg->initial_value,
+					    frac_shift, frac_fval - 1);
+		ret = test_feature_frac_vm(frac, sreg->initial_value, frac_val);
+		TEST_ASSERT(!ret, "Test smaller %s frac (val:%lx) failed(%d)",
+			    frac->name, frac_val, ret);
+	}
+
+	reset_id_reg_info();
+
+	if (frac_fval != 0xf) {
+		/* Test with larger frac value */
+		frac_val = UPDATE_ID_UFIELD(frac_sreg->initial_value,
+						frac_shift, frac_fval + 1);
+
+		/* Setting larger frac shouldn't fail at ioctl */
+		ret = set_id_reg_vm(frac_sreg, frac_val);
+		TEST_ASSERT(!ret,
+			"SET larger %s frac (%s org:%lx, val:%lx) failed(%d)",
+			frac->name, frac_sreg->name, frac_sreg->initial_value,
+			frac_val, ret);
+
+		/* KVM_RUN with larger frac should fail */
+		ret = test_feature_frac_vm(frac, sreg->initial_value, frac_val);
+		TEST_ASSERT(ret,
+			"Test with larger %s frac (%s org:%lx, val:%lx) worked",
+			frac->name, frac_sreg->name, frac_sreg->initial_value,
+			frac_val);
+	}
+
+	reset_id_reg_info();
+
+	/*
+	 * Test with a smaller (main) feature value than the host's.
+	 */
+	ftr_fval = GET_ID_UFIELD(sreg->initial_value, shift);
+	if (ftr_fval == 0)
+		/* Cannot set it to the smaller value */
+		return;
+
+	ftr_val = UPDATE_ID_UFIELD(sreg->initial_value, shift, ftr_fval - 1);
+	ret = test_feature_frac_vm(frac, ftr_val, frac_sreg->initial_value);
+	TEST_ASSERT(!ret, "Test with smaller %s (val:%lx) failed(%d)",
+		    frac->name, ftr_val, ret);
+
+	if (frac_fval > 0) {
+		/* Test with smaller frac value */
+		frac_val = UPDATE_ID_UFIELD(frac_sreg->initial_value,
+					    frac_shift, frac_fval - 1);
+		ret = test_feature_frac_vm(frac, ftr_val, frac_val);
+		TEST_ASSERT(!ret,
+		    "Test with smaller %s and frac (val:%lx) failed(%d)",
+		    frac->name, ftr_val, ret);
+	}
+
+	if (frac_fval != 0xf) {
+		/* Test with larger frac value */
+		frac_val = UPDATE_ID_UFIELD(frac_sreg->initial_value,
+					    frac_shift, frac_fval + 1);
+		ret = test_feature_frac_vm(frac, ftr_val, frac_val);
+		TEST_ASSERT(!ret,
+		    "Test with smaller %s and larger frac (val:%lx) failed(%d)",
+		    frac->name, ftr_val, ret);
+	}
+}
+
+/*
+ * Test for setting feature fractional fields of ID registers.
+ * See test_feature_frac_one's comments for more detail.
+ */
+void test_feature_frac_all(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(frac_info_table); i++)
+		test_feature_frac_one(&frac_info_table[i]);
+}
+
+void run_test(void)
+{
+	test_id_regs_basic();
+	test_feature_all();
+	test_feature_ptrauth();
+	test_feature_frac_all();
+}
+
+static void init_id_reg_info_one(struct id_reg_test_info *sreg, void *arg)
+{
+	struct kvm_one_reg one_reg;
+	uint64_t reg_val;
+	struct kvm_vm *vm = ((struct vm_vcpu_arg *)arg)->vm;
+	uint32_t vcpuid = ((struct vm_vcpu_arg *)arg)->vcpuid;
+	int ret;
+
+	one_reg.addr = (uint64_t)&reg_val;
+	one_reg.id = KVM_ARM64_SYS_REG(sreg->id);
+	vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, &one_reg);
+	sreg->current_value = reg_val;
+
+	/* Keep the initial value to reset the register value later */
+	sreg->initial_value = reg_val;
+
+	/* Check if the register can be set to 0 */
+	reg_val = 0;
+	ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, &one_reg);
+	if (!ret)
+		sreg->can_clear = true;
+
+	pr_debug("%s (0x%x): 0x%lx%s\n", sreg->name, sreg->id,
+		 sreg->initial_value, sreg->can_clear ? ", can clear" : "");
+}
+
+/*
+ * Check if aarch32 is supported, and initialize id_reg_test_info for all
+ * the ID registers.  Loop over the idreg list and populates each id_reg
+ * info with the initial value, current value, and can_clear value.
+ */
+static void init_test_info(void)
+{
+	uint64_t reg_val;
+	int fval;
+	struct kvm_vm *vm;
+	struct kvm_one_reg one_reg;
+	struct vm_vcpu_arg arg = { .vcpuid = 0 };
+
+	vm = test_vm_create(1, guest_code_do_nothing, NULL, NULL);
+
+	/* Get ID_AA64PFR0_EL1 to check if AArch32 is supported */
+	one_reg.addr = (uint64_t)&reg_val;
+	one_reg.id = KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1);
+	vcpu_ioctl(vm, 0, KVM_GET_ONE_REG, &one_reg);
+	fval = GET_ID_UFIELD(reg_val, ID_AA64PFR0_EL0_SHIFT);
+	if (fval == 0x1)
+		/* No AArch32 support */
+		aarch32_support = false;
+
+	/* Initialize id_reg_test_info */
+	arg.vm = vm;
+	walk_id_reg_list(init_id_reg_info_one, &arg);
+	test_vm_free(vm);
+}
+
+int main(void)
+{
+
+	setbuf(stdout, NULL);
+
+	if (kvm_check_cap(KVM_CAP_ARM_ID_REG_CONFIGURABLE) <= 0) {
+		print_skip("KVM_CAP_ARM_ID_REG_CONFIGURABLE is not supported\n");
+		exit(KSFT_SKIP);
+	}
+
+	init_test_info();
+	run_test();
+	return 0;
+}
-- 
2.34.1.448.ga2b2bfdf31-goog



From ck.hu at mediatek.com  Wed Jan  5 21:22:51 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Thu, 6 Jan 2022 13:22:51 +0800
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
References: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
Message-ID: <c0279078032bae61e6c1d70be74d1fb8c528083f.camel@mediatek.com>

Hi, Angelo:

On Tue, 2022-01-04 at 10:59 +0100, AngeloGioacchino Del Regno wrote:
> DRM bridge drivers are now attaching their DSI device at probe time,
> which requires us to register our DSI host in order to let the bridge
> to probe: this recently started producing an endless -EPROBE_DEFER
> loop on some machines that are using external bridges, like the
> parade-ps8640, found on the ACER Chromebook R13.
> 
> Now that the DSI hosts/devices probe sequence is documented, we can
> do adjustments to the mtk_dsi driver as to both fix now and make sure
> to avoid this situation in the future: for this, following what is
> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> mtk_dsi_ops.attach callback and delete it in the detach callback;
> keeping in mind that we are registering a drm_bridge for our DSI,
> which is only used/attached if the DSI Host is bound, it wouldn't
> make sense to keep adding our bridge at probe time (as it would
> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> that one to the dsi host attach function (and remove it in detach).

This patch looks good to me, but please add 'Fixes' tag to note to
which patch this patch want to fix.

Regards,
CK

> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++----------
> ----
>  1 file changed, 84 insertions(+), 83 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..bced4c7d668e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>  	mtk_dsi_poweroff(dsi);
>  }
>  
> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct
> mtk_dsi *dsi)
> +{
> +	int ret;
> +
> +	ret = drm_simple_encoder_init(drm, &dsi->encoder,
> +				      DRM_MODE_ENCODER_DSI);
> +	if (ret) {
> +		DRM_ERROR("Failed to encoder init to drm\n");
> +		return ret;
> +	}
> +
> +	dsi->encoder.possible_crtcs =
> mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> +
> +	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> +				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +	if (ret)
> +		goto err_cleanup_encoder;
> +
> +	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> +	if (IS_ERR(dsi->connector)) {
> +		DRM_ERROR("Unable to create bridge connector\n");
> +		ret = PTR_ERR(dsi->connector);
> +		goto err_cleanup_encoder;
> +	}
> +	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> +
> +	return 0;
> +
> +err_cleanup_encoder:
> +	drm_encoder_cleanup(&dsi->encoder);
> +	return ret;
> +}
> +
> +static int mtk_dsi_bind(struct device *dev, struct device *master,
> void *data)
> +{
> +	int ret;
> +	struct drm_device *drm = data;
> +	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +	ret = mtk_dsi_encoder_init(drm, dsi);
> +	if (ret)
> +		return ret;
> +
> +	return device_reset_optional(dev);
> +}
> +
> +static void mtk_dsi_unbind(struct device *dev, struct device
> *master,
> +			   void *data)
> +{
> +	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +	drm_encoder_cleanup(&dsi->encoder);
> +}
> +
> +static const struct component_ops mtk_dsi_component_ops = {
> +	.bind = mtk_dsi_bind,
> +	.unbind = mtk_dsi_unbind,
> +};
> +
>  static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>  			       struct mipi_dsi_device *device)
>  {
>  	struct mtk_dsi *dsi = host_to_dsi(host);
> +	struct device *dev = host->dev;
> +	int ret;
>  
>  	dsi->lanes = device->lanes;
>  	dsi->format = device->format;
>  	dsi->mode_flags = device->mode_flags;
> +	dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0,
> 0);
> +	if (IS_ERR(dsi->next_bridge))
> +		return PTR_ERR(dsi->next_bridge);
> +
> +	drm_bridge_add(&dsi->bridge);
> +
> +	ret = component_add(host->dev, &mtk_dsi_component_ops);
> +	if (ret) {
> +		DRM_ERROR("failed to add dsi_host component: %d\n",
> ret);
> +		drm_bridge_remove(&dsi->bridge);
> +		return ret;
> +	}
>  
>  	return 0;
>  }
>  
> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
> +			       struct mipi_dsi_device *device)
> +{
> +	struct mtk_dsi *dsi = host_to_dsi(host);
> +
> +	component_del(host->dev, &mtk_dsi_component_ops);
> +	drm_bridge_remove(&dsi->bridge);
> +	return 0;
> +}
> +
>  static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>  {
>  	int ret;
> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct
> mipi_dsi_host *host,
>  
>  static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>  	.attach = mtk_dsi_host_attach,
> +	.detach = mtk_dsi_host_detach,
>  	.transfer = mtk_dsi_host_transfer,
>  };
>  
> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct
> mtk_dsi *dsi)
> -{
> -	int ret;
> -
> -	ret = drm_simple_encoder_init(drm, &dsi->encoder,
> -				      DRM_MODE_ENCODER_DSI);
> -	if (ret) {
> -		DRM_ERROR("Failed to encoder init to drm\n");
> -		return ret;
> -	}
> -
> -	dsi->encoder.possible_crtcs =
> mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> -
> -	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> -				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -	if (ret)
> -		goto err_cleanup_encoder;
> -
> -	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> -	if (IS_ERR(dsi->connector)) {
> -		DRM_ERROR("Unable to create bridge connector\n");
> -		ret = PTR_ERR(dsi->connector);
> -		goto err_cleanup_encoder;
> -	}
> -	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> -
> -	return 0;
> -
> -err_cleanup_encoder:
> -	drm_encoder_cleanup(&dsi->encoder);
> -	return ret;
> -}
> -
> -static int mtk_dsi_bind(struct device *dev, struct device *master,
> void *data)
> -{
> -	int ret;
> -	struct drm_device *drm = data;
> -	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -	ret = mtk_dsi_encoder_init(drm, dsi);
> -	if (ret)
> -		return ret;
> -
> -	return device_reset_optional(dev);
> -}
> -
> -static void mtk_dsi_unbind(struct device *dev, struct device
> *master,
> -			   void *data)
> -{
> -	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -	drm_encoder_cleanup(&dsi->encoder);
> -}
> -
> -static const struct component_ops mtk_dsi_component_ops = {
> -	.bind = mtk_dsi_bind,
> -	.unbind = mtk_dsi_unbind,
> -};
> -
>  static int mtk_dsi_probe(struct platform_device *pdev)
>  {
>  	struct mtk_dsi *dsi;
>  	struct device *dev = &pdev->dev;
> -	struct drm_panel *panel;
>  	struct resource *regs;
>  	int irq_num;
>  	int ret;
> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -					  &panel, &dsi->next_bridge);
> -	if (ret)
> -		goto err_unregister_host;
> -
> -	if (panel) {
> -		dsi->next_bridge = devm_drm_panel_bridge_add(dev,
> panel);
> -		if (IS_ERR(dsi->next_bridge)) {
> -			ret = PTR_ERR(dsi->next_bridge);
> -			goto err_unregister_host;
> -		}
> -	}
> -
>  	dsi->driver_data = of_device_get_match_data(dev);
>  
>  	dsi->engine_clk = devm_clk_get(dev, "engine");
> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  	dsi->bridge.of_node = dev->of_node;
>  	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>  
> -	drm_bridge_add(&dsi->bridge);
> -
> -	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
> -	if (ret) {
> -		dev_err(&pdev->dev, "failed to add component: %d\n",
> ret);
> -		goto err_unregister_host;
> -	}
> -
>  	return 0;
>  
>  err_unregister_host:
> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct
> platform_device *pdev)
>  	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>  
>  	mtk_output_dsi_disable(dsi);
> -	drm_bridge_remove(&dsi->bridge);
> -	component_del(&pdev->dev, &mtk_dsi_component_ops);
>  	mipi_dsi_host_unregister(&dsi->host);
>  
>  	return 0;



From vkoul at kernel.org  Wed Jan  5 21:27:08 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 6 Jan 2022 10:57:08 +0530
Subject: [PATCH v2 2/3] dmaengine: mediatek: mtk-hsdma: Use
 platform_get_irq() to get the interrupt
In-Reply-To: <20220104163519.21929-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20220104163519.21929-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <YdZ9rDvYtdu8L8Vb@matsya>

On 04-01-22, 16:35, Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v1->v2
> * No change
> ---
>  drivers/dma/mediatek/mtk-hsdma.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
> index 6ad8afbb95f2..c0fffde7fe08 100644
> --- a/drivers/dma/mediatek/mtk-hsdma.c
> +++ b/drivers/dma/mediatek/mtk-hsdma.c
> @@ -923,13 +923,10 @@ static int mtk_hsdma_probe(struct platform_device *pdev)
>  		return PTR_ERR(hsdma->clk);
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (!res) {
> -		dev_err(&pdev->dev, "No irq resource for %s\n",
> -			dev_name(&pdev->dev));
> -		return -EINVAL;
> -	}
> -	hsdma->irq = res->start;
> +	err = platform_get_irq(pdev, 0);

why not platform_get_irq_optional() here and 3rd patch ?

> +	if (err < 0)
> +		return err;
> +	hsdma->irq = err;
>  
>  	refcount_set(&hsdma->pc_refcnt, 0);
>  	spin_lock_init(&hsdma->lock);
> -- 
> 2.17.1

-- 
~Vinod


From xianwei.zhao at amlogic.com  Wed Jan  5 21:47:24 2022
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Thu, 6 Jan 2022 13:47:24 +0800
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
Message-ID: <20220106054724.18637-1-xianwei.zhao@amlogic.com>

Add basic support for the Amlogic S4 based Amlogic AQ222 board:
which describe components as follows: CPU, GIC, IRQ, Timer, UART.
It's capable of booting up into the serial console.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
V2 -> V3: add of dts board  compatible family
V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
          and modify GIC reg defintions.
---
 arch/arm64/boot/dts/amlogic/Makefile          |  1 +
 .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..faea74a45994 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
new file mode 100644
index 000000000000..a942d7e06d6e
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+	model = "Amlogic Meson S4 AQ222 Development Board";
+	compatible = "amlogic,aq222", "amlogic,s4";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &uart_B;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+};
+
+&uart_B {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
new file mode 100644
index 000000000000..d7083c93d3d0
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	cpus:cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0:cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		CPU1:cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		CPU2:cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		CPU3:cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	xtal: xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xtal";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller at fff01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xfff01000 0 0x1000>,
+			      <0x0 0xfff02000 0 0x2000>,
+			      <0x0 0xfff04000 0 0x2000>,
+			      <0x0 0xfff06000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		apb4: apb4 at fe000000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xfe000000 0x0 0x480000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+			uart_B: serial at 7a000 {
+				compatible = "amlogic,meson-s4-uart",
+					     "amlogic,meson-ao-uart";
+				reg = <0x0 0x7a000 0x0 0x18>;
+				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&xtal>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+		};
+	};
+};

base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
-- 
2.30.2



From roger.lu at mediatek.com  Wed Jan  5 21:50:13 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 6 Jan 2022 13:50:13 +0800
Subject: [PATCH v20 3/7] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <1480efdf-ed94-8bda-7bea-a657eddae45d@collabora.com>
References: <20210721070904.15636-1-roger.lu@mediatek.com>
 <20210721070904.15636-4-roger.lu@mediatek.com>
 <1480efdf-ed94-8bda-7bea-a657eddae45d@collabora.com>
Message-ID: <cd16a23f82c4c545e60600454aa27b99c3f5d8fb.camel@mediatek.com>

Hi AngeloGioacchino,

This patch is older comparing with the time when you left comments on v16. So,
excuse me if this patch makes you confuse and thanks for all the advices.

On Wed, 2022-01-05 at 10:58 +0100, AngeloGioacchino Del Regno wrote:
> Il 21/07/21 09:09, Roger Lu ha scritto:
> > The Smart Voltage Scaling(SVS) engine is a piece of hardware
> > which calculates suitable SVS bank voltages to OPP voltage table.
> > Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
> > when receiving OPP_EVENT_ADJUST_VOLTAGE.
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> 
> Hello Roger,
> thanks for the patch!
> 
> However, there are a few things to improve...
> 
> > ---
> >   drivers/soc/mediatek/Kconfig   |   10 +
> >   drivers/soc/mediatek/Makefile  |    1 +
> >   drivers/soc/mediatek/mtk-svs.c | 1720 ++++++++++++++++++++++++++++++++
> >   3 files changed, 1731 insertions(+)
> >   create mode 100644 drivers/soc/mediatek/mtk-svs.c

[snip]

> > +/* svs bank volt flags */
> > +#define SVSB_INIT01_VOLT_IGNORE		BIT(1)
> > +#define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
> > +#define SVSB_INIT02_RM_DVTFIXED		BIT(8)
> > +#define SVSB_MON_VOLT_IGNORE		BIT(16)
> > +
> > +/* svs bank common setting */
> > +#define SVSB_DET_CLK_EN			BIT(31)
> > +#define SVSB_TZONE_HIGH_TEMP_MAX	U32_MAX
> > +#define SVSB_RUNCONFIG_DEFAULT		0x80000000
> > +#define SVSB_DC_SIGNED_BIT		0x8000
> 
> SVSB_DC_SIGNED_BIT is.. clearly a bit, so this should be BIT(15)

Thanks. I'll update it to BIT(15) in v21.

> 
> > +#define SVSB_INTEN_INIT0x		0x00005f01
> > +#define SVSB_INTEN_MONVOPEN		0x00ff0000
> > +#define SVSB_EN_OFF			0x0
> > +#define SVSB_EN_MASK			0x7
> > +#define SVSB_EN_INIT01			0x1
> > +#define SVSB_EN_INIT02			0x5
> > +#define SVSB_EN_MON			0x2
> > +#define SVSB_INTSTS_MONVOP		0x00ff0000
> > +#define SVSB_INTSTS_COMPLETE		0x1
> > +#define SVSB_INTSTS_CLEAN		0x00ffffff
> > +
> > +static DEFINE_SPINLOCK(mtk_svs_lock);
> > +
> > +/*
> 
> Looks like the great intention is to have kernel-doc here, and it's already
> in the right format, but the start of the comment block should be
> 
> /**
> 
> and not
> 
> /*
> 
> to be recognized as kerneldoc.
> Please refer to 
> https://urldefense.com/v3/__https://www.kernel.org/doc/html/v5.15/doc-guide/kernel-doc.html__;!!CTRNKA9wMg0ARbw!zYX3rnKoCilN7h_LLkpKmqF-6FsUGN4pOnlSO9NBfevbtwA15bM5CjqcMFn75nsn$
>  

No problem. I'll follow kernel-doc. Thanks for the link.

> > + * enum svsb_phase - svs bank phase enumeration
> > + * @SVSB_PHASE_INIT01: basic init for svs bank
> > + * @SVSB_PHASE_INIT02: svs bank can provide voltages
> > + * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
> > + * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
> 
> Please move @SVSB_PHASE_ERROR before @SVSB_PHASE_INIT01: the order
> 
> is important here, and has to be the same as the actual enumeration.
> 

Sure, I'll update it in v21. Thanks.

> > + *
> > + * Each svs bank has its own independent phase. We enable each svs bank by
> > + * running their phase orderly. However, When svs bank encounters
> > unexpected
> > + * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
> > + *
> > + * svs bank general phase-enabled order:
> > + * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
> > + */
> > +enum svsb_phase {
> > +	SVSB_PHASE_ERROR = 0,
> > +	SVSB_PHASE_INIT01,
> > +	SVSB_PHASE_INIT02,
> > +	SVSB_PHASE_MON,
> > +};


> > +/*
> 
> ... same here, /** for kerneldoc

Sure, I'll update it in v21. Thanks.

> > + * struct svs_platform - svs platform data
> > + * @dev: svs platform device
> > + * @base: svs platform register address base
> > + * @main_clk: main clock for svs bank
> > + * @pbank: phandle of svs bank and needs to be protected by spin_lock
> > + * @banks: phandle of the banks that support
> > + * @efuse_parsing: phandle of efuse parsing function
> > + * @irqflags: irq settings flags
> > + * @rst: svs reset control
> > + * @regs: phandle to the registers map
> 
> @name should be here

Got it. I'll reorder them consistently in v21. Thanks for the guide.

> 
> > + * @efuse_num: the total number of svs platform efuse
> > + * @tefuse_num: the total number of thermal efuse
> > + * @bank_num: the total number of banks
> > + * @efuse_check: the svs efuse check index
> > + * @efuse: svs platform efuse data received from NVMEM framework
> > + * @tefuse: thermal efuse data received from NVMEM framework
> > + * @name: svs platform name
> > + */
> > +struct svs_platform {
> > +	struct device *dev;
> > +	void __iomem *base;
> > +	struct clk *main_clk;
> > +	struct svs_bank *pbank;
> > +	struct svs_bank *banks;
> > +	bool (*efuse_parsing)(struct svs_platform *svsp);
> > +	unsigned long irqflags;
> > +	struct reset_control *rst;
> > +	const u32 *regs;
> > +	char *name;
> > +	size_t efuse_num;
> > +	size_t tefuse_num;
> > +	u32 bank_num;
> > +	u32 efuse_check;
> > +	u32 *efuse;
> > +	u32 *tefuse;
> > +};
> > +
> > +/*
> 
> ... and here

Sure, I'll update it in v21. Thanks.

> 
> > + * struct svs_bank - svs bank representation
> > + * @dev: svs bank device
> > + * @opp_dev: device for opp table/buck control
> > + * @pd_dev: power domain device for SoC mtcmos control
> > + * @init_completion: the timeout completion for bank init
> > + * @buck: phandle of the regulator
> > + * @lock: mutex lock to protect voltage update process
> > + * @phase: bank current phase
> > + * @name: bank name
> > + * @tzone_name: thermal zone name
> > + * @buck_name: regulator name
> > + * @suspended: suspend flag of this bank
> > + * @pd_req: bank's power-domain on request
> > + * @enable_pm_runtime_ever: bank enables pm-runtime flag
> > + * @set_freqs_pct: phandle of set frequencies percent function
> > + * @get_vops: phandle of get bank voltages function
> > + * @volt_offset: bank voltage offset controlled by svs software
> > + * @mode_support: bank mode support.
> > + * @opp_freqs: signed-off frequencies from default opp table
> > + * @opp_volts: signed-off voltages from default opp table
> > + * @freqs_pct: percent of "opp_freqs / freq_base" for bank init
> > + * @volts: bank voltages
> > + * @freq_base: reference frequency for bank init
> > + * @vboot: voltage request for bank init01 stage only
> > + * @volt_step: bank voltage step
> > + * @volt_base: bank voltage base
> > + * @volt_flags: bank voltage flags
> > + * @vmax: bank voltage maximum
> > + * @vmin: bank voltage minimum
> 
> I love when developers take the effort to document with kerneldoc, so, great
> job
> about that.... however, you forgot to document a few variables... can you
> please
> add the required documentation for them?

I'll add them up and reveal the detail as many as possible. Thanks for the
gentle wording.

> 
> > + * @temp: bank temperature
> > + * @temp_upper_bound: bank temperature upper bound
> > + * @temp_lower_bound: bank temperature lower bound
> > + * @tzone_high_temp: thermal zone high temperature threshold
> > + * @tzone_high_temp_offset: thermal zone high temperature offset
> > + * @tzone_low_temp: thermal zone low temperature threshold
> > + * @tzone_low_temp_offset: thermal zone low temperature offset
> > + * @core_sel: bank selection
> > + * @opp_count: bank opp count
> > + * @int_st: bank interrupt identification
> > + * @sw_id: bank software identification
> > + * @ctl0: bank thermal sensor selection
> > + * @cpu_id: cpu core id for SVS CPU only
> > + *
> > + * Other structure members which are not listed above are svs platform
> > + * efuse data for bank init
> > + */
> > +struct svs_bank {
> > +	struct device *dev;
> > +	struct device *opp_dev;
> > +	struct device *pd_dev;
> > +	struct completion init_completion;
> > +	struct regulator *buck;
> > +	struct mutex lock;	/* lock to protect voltage update process */
> > +	enum svsb_phase phase;
> > +	char *name;
> > +	char *tzone_name;
> > +	char *buck_name;
> > +	bool suspended;
> > +	bool pd_req;
> > +	bool enable_pm_runtime_ever;
> > +	void (*set_freqs_pct)(struct svs_platform *svsp);
> > +	void (*get_vops)(struct svs_platform *svsp);
> > +	s32 volt_offset;
> > +	u32 mode_support;
> > +	u32 opp_freqs[16];
> 
> At the beginning of the file....
> #define MAX_OPP_ENTRIES 16
> 
> ...so you can do...
> 	u32 opp_freqs[MAX_OPP_ENTRIES];
> 	u32 opp_volts[MAX_OPP_ENTRIES];
> ...and the same for the other two.

Sure, I'll replace them with MAX_OPP_ENTRIES.

> > +	u32 opp_volts[16];
> > +	u32 freqs_pct[16];
> > +	u32 volts[16];
> > +	u32 freq_base;
> > +	u32 vboot;
> > +	u32 volt_step;
> > +	u32 volt_base;
> > +	u32 volt_flags;
> > +	u32 vmax;
> > +	u32 vmin;


> Document these entries, please.
> 
> vvvvvvvvv From here.... vvvvvvvvv
> 
> > +	u32 bts;
> > +	u32 mts;
> > +	u32 bdes;
> > +	u32 mdes;
> > +	u32 mtdes;
> > +	u32 dcbdet;
> > +	u32 dcmdet;
> > +	u32 dthi;
> > +	u32 dtlo;
> > +	u32 det_window;
> > +	u32 det_max;
> > +	u32 age_config;
> > +	u32 age_voffset_in;
> > +	u32 agem;
> > +	u32 dc_config;
> > +	u32 dc_voffset_in;
> > +	u32 dvt_fixed;
> > +	u32 vco;
> > +	u32 chk_shift;
> 
> ^^^^^^^^^ ....to there ^^^^^^^^^

Sure, thanks for the review.

> 
> > +	u32 temp;
> > +	u32 temp_upper_bound;
> > +	u32 temp_lower_bound;
> > +	u32 tzone_high_temp;
> > +	u32 tzone_high_temp_offset;
> > +	u32 tzone_low_temp;
> > +	u32 tzone_low_temp_offset;
> > +	u32 core_sel;
> > +	u32 opp_count;
> > +	u32 int_st;
> > +	u32 sw_id;
> > +	u32 ctl0;
> > +	u32 cpu_id;
> > +};

[snip]

> > +static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool
> > force_update)
> > +{
> > +	int tzone_temp = 0, ret = -EPERM;
> > +	u32 i, svsb_volt, opp_volt, temp_offset = 0;
> > +
> > +	mutex_lock(&svsb->lock);
> > +
> > +	/*
> > +	 * If svs bank is suspended, it means signed-off voltages are applied.
> > +	 * Don't need to update opp voltage anymore.
> > +	 */
> > +	if (svsb->suspended && !force_update) {
> > +		dev_notice(svsb->dev, "bank is suspended\n");
> > +		ret = -EPERM;
> > +		goto unlock_mutex;
> > +	}
> > +
> > +	/* Get thermal effect */
> > +	if (svsb->phase == SVSB_PHASE_MON) {
> > +		if (svsb->temp > svsb->temp_upper_bound &&
> > +		    svsb->temp < svsb->temp_lower_bound) {
> > +			dev_warn(svsb->dev, "svsb temp = 0x%x?\n", svsb->temp);
> > +			ret = -EINVAL;
> > +			goto unlock_mutex;
> > +		}
> > +
> > +		ret = svs_get_bank_zone_temperature(svsb->tzone_name,
> > +						    &tzone_temp);
> > +		if (ret) {
> > +			dev_err(svsb->dev, "no %s? (%d), run default volts\n",
> > +				svsb->tzone_name, ret);
> > +			svsb->phase = SVSB_PHASE_ERROR;
> > +		}
> > +
> > +		if (tzone_temp >= svsb->tzone_high_temp)
> > +			temp_offset += svsb->tzone_high_temp_offset;
> > +		else if (tzone_temp <= svsb->tzone_low_temp)
> > +			temp_offset += svsb->tzone_low_temp_offset;
> > +	}
> > +
> > +	/* vmin <= svsb_volt (opp_volt) <= signed-off (default) voltage */
> > +	for (i = 0; i < svsb->opp_count; i++) {
> 
> 
> 
> What about using switch here?
> 
> 
> 
>          switch (svsb->phase) {
> 
>          case SVSB_PHASE_MON:
> 
>              ......
> 
>              break;
> 
>          case .......:
> 
>              .........
> 
>              break;
> 
>          default:
> 
>              dev_err(......);
> 
>              ret = -EINVAL;
> 
>              goto unlock_mutex;
> 
>          }

No problem. I'll use switch here. Thanks.

> > +		if (svsb->phase == SVSB_PHASE_MON) {
> > +			svsb_volt = max(svsb->volts[i] + svsb->volt_offset +
> > +					temp_offset, svsb->vmin);
> > +			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
> > +							     svsb->volt_step,
> > +							     svsb->volt_base);
> > +		} else if (svsb->phase == SVSB_PHASE_INIT02) {
> > +			svsb_volt = max(svsb->volts[i] + svsb->volt_offset,
> > +					svsb->vmin);
> > +			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
> > +							     svsb->volt_step,
> > +							     svsb->volt_base);
> > +		} else if (svsb->phase == SVSB_PHASE_ERROR) {
> > +			opp_volt = svsb->opp_volts[i];
> > +		} else {
> > +			dev_err(svsb->dev, "unknown phase: %u?\n", svsb->phase);
> > +			ret = -EINVAL;
> > +			goto unlock_mutex;
> > +		}
> > +
> > +		opp_volt = min(opp_volt, svsb->opp_volts[i]);
> > +		ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
> > +						svsb->opp_freqs[i],
> > +						opp_volt, opp_volt,
> > +						svsb->opp_volts[i]);
> > +		if (ret) {
> > +			dev_err(svsb->dev, "set voltage fail: %d\n", ret);
> > +			goto unlock_mutex;
> > +		}
> > +	}
> > +
> > +unlock_mutex:
> > +	mutex_unlock(&svsb->lock);
> > +
> > +	return ret;
> > +}

[snip]

> > +static void svs_set_bank_phase(struct svs_platform *svsp,
> > +			       enum svsb_phase target_phase)
> > +{
> > +	struct svs_bank *svsb = svsp->pbank;
> > +	u32 des_char, temp_char, det_char, limit_vals;
> > +	u32 init2vals, ts_calcs, val, filter, i;
> > +
> > +	svs_switch_bank(svsp);
> > +
> > +	des_char = (svsb->bdes << 8) | svsb->mdes;
> > +	svs_writel(svsp, des_char, DESCHAR);
> > +
> > +	temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed;
> > +	svs_writel(svsp, temp_char, TEMPCHAR);
> > +
> > +	det_char = (svsb->dcbdet << 8) | svsb->dcmdet;
> > +	svs_writel(svsp, det_char, DETCHAR);
> > +
> > +	svs_writel(svsp, svsb->dc_config, DCCONFIG);
> > +	svs_writel(svsp, svsb->age_config, AGECONFIG);
> > +
> > +	if (!svsb->agem) {
> > +		svs_writel(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);
> > +	} else {
> > +		val = 0x0;
> 
> val = 0;

Got it. I'll improve this if-else statement as minimum support first.

> 
> > +
> > +		for (i = 0; i < 24; i += 2) {
> > +			filter = 0x3 << i;
> > +
> > +			if (!(svsb->age_config & filter))
> > +				val |= (0x1 << i);
> 
> val |= BIT(i);

ditto.

> 
> > +			else
> > +				val |= (svsb->age_config & filter);
> > +		}
> > +		svs_writel(svsp, val, RUNCONFIG);
> > +	}
> > +
> > +	svsb->set_freqs_pct(svsp);
> > +
> > +	limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) |
> > +		     (svsb->dthi << 8) | svsb->dtlo;
> > +	svs_writel(svsp, limit_vals, LIMITVALS);
> > +	svs_writel(svsp, svsb->vboot, VBOOT);
> > +	svs_writel(svsp, svsb->det_window, DETWINDOW);
> > +	svs_writel(svsp, svsb->det_max, CONFIG);
> > +
> > +	if (svsb->chk_shift)
> > +		svs_writel(svsp, svsb->chk_shift, CHKSHIFT);
> > +
> > +	if (svsb->ctl0)
> > +		svs_writel(svsp, svsb->ctl0, CTL0);
> > +
> > +	svs_writel(svsp, SVSB_INTSTS_CLEAN, INTSTS);
> > +
> > +	switch (target_phase) {
> > +	case SVSB_PHASE_INIT01:
> > +		svs_writel(svsp, SVSB_INTEN_INIT0x, INTEN);
> > +		svs_writel(svsp, SVSB_EN_INIT01, SVSEN);
> > +		break;
> > +	case SVSB_PHASE_INIT02:
> > +		svs_writel(svsp, SVSB_INTEN_INIT0x, INTEN);
> > +		init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in;
> > +		svs_writel(svsp, init2vals, INIT2VALS);
> > +		svs_writel(svsp, SVSB_EN_INIT02, SVSEN);
> > +		break;
> > +	case SVSB_PHASE_MON:
> > +		ts_calcs = (svsb->bts << 12) | svsb->mts;
> > +		svs_writel(svsp, ts_calcs, TSCALCS);
> > +		svs_writel(svsp, SVSB_INTEN_MONVOPEN, INTEN);
> > +		svs_writel(svsp, SVSB_EN_MON, SVSEN);
> > +		break;
> > +	default:
> > +		WARN_ON(1);
> 
> I agree about printing a big warning in kmsg here, but you can do that in a
> 
> slightly more descriptive way:
> 
> 
> 
>          WARN(1, "Requested unknown target phase %u", target_phase);
> 

Sure, I'll add more description in v21. Thanks for the example code.

> > +		break;
> > +	}
> > +}

[snip]

> > +static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
> > +{
> > +	struct thermal_parameter tp;
> > +	struct svs_bank *svsb;
> > +	bool mon_mode_support = true;
> > +	int format[6], x_roomt[6], tb_roomt = 0;
> > +	struct nvmem_cell *cell;
> > +	u32 idx, i, ft_pgm, mts, temp0, temp1, temp2;
> > +
> > +	for (i = 0; i < svsp->efuse_num; i++)
> > +		if (svsp->efuse[i])
> > +			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
> > +				 i, svsp->efuse[i]);
> > +
> > +	/* Svs efuse parsing */
> > +	ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0);
> > +
> > +	for (idx = 0; idx < svsp->bank_num; idx++) {
> > +		svsb = &svsp->banks[idx];
> > +
> > +		if (ft_pgm <= 1)
> > +			svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
> > +
> > +		switch (svsb->sw_id) {
> > +		case SVSB_CPU_LITTLE:
> > +			svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
> > +			svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
> > +			svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
> > +			svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0);
> > +			svsb->mtdes  = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
> > +
> > +			if (ft_pgm <= 3)
> > +				svsb->volt_offset += 10;
> > +			else
> > +				svsb->volt_offset += 2;
> > +			break;
> > +		case SVSB_CPU_BIG:
> > +			svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
> > +			svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
> > +			svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
> > +			svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0);
> > +			svsb->mtdes  = svsp->efuse[17] & GENMASK(7, 0);
> > +
> > +			if (ft_pgm <= 3)
> > +				svsb->volt_offset += 15;
> > +			else
> > +				svsb->volt_offset += 12;
> > +			break;
> > +		case SVSB_CCI:
> > +			svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
> > +			svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
> > +			svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
> > +			svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
> > +			svsb->mtdes  = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
> > +
> > +			if (ft_pgm <= 3)
> > +				svsb->volt_offset += 10;
> > +			else
> > +				svsb->volt_offset += 2;
> > +			break;
> > +		case SVSB_GPU:
> > +			svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
> > +			svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
> > +			svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
> > +			svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
> > +			svsb->mtdes  = svsp->efuse[5] & GENMASK(7, 0);
> > +
> > +			if (ft_pgm >= 2) {
> > +				svsb->freq_base = 800000000; /* 800MHz */
> > +				svsb->dvt_fixed = 2;
> > +			}
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +	}
> > +
> > +	/* Get thermal efuse by nvmem */
> > +	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
> > +	if (IS_ERR_OR_NULL(cell)) {
> > +		dev_err(svsp->dev, "no thermal cell, no mon mode\n");
> > +		for (idx = 0; idx < svsp->bank_num; idx++) {
> > +			svsb = &svsp->banks[idx];
> > +			svsb->mode_support &= ~SVSB_MODE_MON;
> > +		}
> > +
> > +		return true;
> > +	}
> > +
> > +	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_num);
> 
> 
> 
> nvmem_cell_read may return an error pointer: you have to check that.
> 
> 
> 
>      if (IS_ERR(svsp->tefuse))
> 
>          .........
> 
> 
> 
> Failing to perform this check will produce unpredictable behavior
> 
> during the parsing stage.

Sure, I'll add the error handling here. Thanks for the notice.

> 
> > +	svsp->tefuse_num /= sizeof(u32);
> > +	nvmem_cell_put(cell);
> > +
> > +	/* Thermal efuse parsing */
> > +	tp.adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0);
> > +	tp.adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0);
> > +
> > +	tp.o_vtsmcu1 = (svsp->tefuse[0] >> 17) & GENMASK(8, 0);
> > +	tp.o_vtsmcu2 = (svsp->tefuse[0] >> 8) & GENMASK(8, 0);
> > +	tp.o_vtsmcu3 = svsp->tefuse[1] & GENMASK(8, 0);
> > +	tp.o_vtsmcu4 = (svsp->tefuse[2] >> 23) & GENMASK(8, 0);
> > +	tp.o_vtsmcu5 = (svsp->tefuse[2] >> 5) & GENMASK(8, 0);
> > +	tp.o_vtsabb = (svsp->tefuse[2] >> 14) & GENMASK(8, 0);
> > +
> > +	tp.degc_cali = (svsp->tefuse[0] >> 1) & GENMASK(5, 0);
> > +	tp.adc_cali_en_t = svsp->tefuse[0] & BIT(0);
> > +	tp.o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0);
> > +
> > +	tp.ts_id = (svsp->tefuse[1] >> 9) & BIT(0);
> > +	tp.o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
> > +
> > +	if (tp.adc_cali_en_t == 1) {
> > +		if (!tp.ts_id)
> > +			tp.o_slope = 0;
> > +
> > +		if (tp.adc_ge_t < 265 || tp.adc_ge_t > 758 ||
> > +		    tp.adc_oe_t < 265 || tp.adc_oe_t > 758 ||
> > +		    tp.o_vtsmcu1 < -8 || tp.o_vtsmcu1 > 484 ||
> > +		    tp.o_vtsmcu2 < -8 || tp.o_vtsmcu2 > 484 ||
> > +		    tp.o_vtsmcu3 < -8 || tp.o_vtsmcu3 > 484 ||
> > +		    tp.o_vtsmcu4 < -8 || tp.o_vtsmcu4 > 484 ||
> > +		    tp.o_vtsmcu5 < -8 || tp.o_vtsmcu5 > 484 ||
> > +		    tp.o_vtsabb < -8 || tp.o_vtsabb > 484 ||
> > +		    tp.degc_cali < 1 || tp.degc_cali > 63) {
> > +			dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
> > +			mon_mode_support = false;
> > +		}
> > +	} else {
> > +		dev_err(svsp->dev, "no thermal efuse, no mon mode\n");
> > +		mon_mode_support = false;
> > +	}
> > +
> > +	if (!mon_mode_support) {
> > +		for (idx = 0; idx < svsp->bank_num; idx++) {
> > +			svsb = &svsp->banks[idx];
> > +			svsb->mode_support &= ~SVSB_MODE_MON;
> > +		}
> > +
> > +		return true;
> > +	}
> > +
> > +	tp.ge = ((tp.adc_ge_t - 512) * 10000) / 4096;
> > +	tp.oe = (tp.adc_oe_t - 512);
> > +	tp.gain = (10000 + tp.ge);
> > +
> > +	format[0] = (tp.o_vtsmcu1 + 3350 - tp.oe);
> > +	format[1] = (tp.o_vtsmcu2 + 3350 - tp.oe);
> > +	format[2] = (tp.o_vtsmcu3 + 3350 - tp.oe);
> > +	format[3] = (tp.o_vtsmcu4 + 3350 - tp.oe);
> > +	format[4] = (tp.o_vtsmcu5 + 3350 - tp.oe);
> > +	format[5] = (tp.o_vtsabb + 3350 - tp.oe);
> > +
> > +	for (i = 0; i < 6; i++)
> > +		x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / tp.gain;
> > +
> > +	temp0 = (10000 * 100000 / tp.gain) * 15 / 18;
> > +
> > +	if (!tp.o_slope_sign)
> > +		mts = (temp0 * 10) / (1534 + tp.o_slope * 10);
> > +	else
> > +		mts = (temp0 * 10) / (1534 - tp.o_slope * 10);
> > +
> > +	for (idx = 0; idx < svsp->bank_num; idx++) {
> > +		svsb = &svsp->banks[idx];
> > +		svsb->mts = mts;
> > +
> > +		switch (svsb->sw_id) {
> > +		case SVSB_CPU_LITTLE:
> > +			tb_roomt = x_roomt[3];
> > +			break;
> > +		case SVSB_CPU_BIG:
> > +			tb_roomt = x_roomt[4];
> > +			break;
> > +		case SVSB_CCI:
> > +			tb_roomt = x_roomt[3];
> > +			break;
> > +		case SVSB_GPU:
> > +			tb_roomt = x_roomt[1];
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		temp0 = (tp.degc_cali * 10 / 2);
> > +		temp1 = ((10000 * 100000 / 4096 / tp.gain) *
> > +			 tp.oe + tb_roomt * 10) * 15 / 18;
> > +
> > +		if (!tp.o_slope_sign)
> > +			temp2 = temp1 * 100 / (1534 + tp.o_slope * 10);
> > +		else
> > +			temp2 = temp1 * 100 / (1534 - tp.o_slope * 10);
> > +
> > +		svsb->bts = (temp0 + temp2 - 250) * 4 / 10;
> > +	}
> > +
> > +	return true;
> > +}

[snip]



From johnson.wang at mediatek.com  Wed Jan  5 22:54:06 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Thu, 6 Jan 2022 14:54:06 +0800
Subject: [PATCH 3/4] dt-bindings: mfd: Add compatible for the MediaTek MT6366
 PMIC
In-Reply-To: <20220106065407.16036-1-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
Message-ID: <20220106065407.16036-4-johnson.wang@mediatek.com>

This adds compatible for the MediaTek MT6366 PMIC.

Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 Documentation/devicetree/bindings/mfd/mt6397.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 99a84b69a29f..293db2a71ef2 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -20,7 +20,7 @@ This document describes the binding for MFD device and its sub module.
 Required properties:
 compatible:
 	"mediatek,mt6323" for PMIC MT6323
-	"mediatek,mt6358" for PMIC MT6358
+	"mediatek,mt6358" for PMIC MT6358 and MT6366
 	"mediatek,mt6359" for PMIC MT6359
 	"mediatek,mt6397" for PMIC MT6397
 
-- 
2.18.0



From johnson.wang at mediatek.com  Wed Jan  5 22:54:03 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Thu, 6 Jan 2022 14:54:03 +0800
Subject: [PATCH 0/4] Add Support for MediaTek PMIC MT6366
Message-ID: <20220106065407.16036-1-johnson.wang@mediatek.com>

This patchset adds support for MediaTek PMIC MT6366.
MT6366 is the primary PMIC for MT8186 and probably other SOCs.

Johnson Wang (4):
  mfd: Add support for the MediaTek MT6366 PMIC
  regulator: mt6366: Add support for MT6366 regulator
  dt-bindings: mfd: Add compatible for the MediaTek MT6366 PMIC
  dt-bindings: regulator: Add MT6358 regulators

 .../devicetree/bindings/mfd/mt6397.txt        |   2 +-
 .../bindings/regulator/mt6358-regulator.txt   |  22 +-
 drivers/mfd/mt6358-irq.c                      |   1 +
 drivers/regulator/mt6358-regulator.c          | 213 +++++++++++++++++-
 include/linux/mfd/mt6358/registers.h          |   7 +
 include/linux/mfd/mt6397/core.h               |   1 +
 include/linux/regulator/mt6358-regulator.h    |  45 ++++
 7 files changed, 280 insertions(+), 11 deletions(-)

-- 
2.18.0



From johnson.wang at mediatek.com  Wed Jan  5 22:54:04 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Thu, 6 Jan 2022 14:54:04 +0800
Subject: [PATCH 1/4] mfd: Add support for the MediaTek MT6366 PMIC
In-Reply-To: <20220106065407.16036-1-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
Message-ID: <20220106065407.16036-2-johnson.wang@mediatek.com>

This adds support for the MediaTek MT6366 PMIC. This is a
multifunction device with the following sub modules:

- Regulator
- RTC
- Codec
- Interrupt

It is interfaced to the host controller using SPI interface
by a proprietary hardware called PMIC wrapper or pwrap.
MT6366 MFD is a child device of the pwrap.

Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 drivers/mfd/mt6358-irq.c             | 1 +
 include/linux/mfd/mt6358/registers.h | 7 +++++++
 include/linux/mfd/mt6397/core.h      | 1 +
 3 files changed, 9 insertions(+)

diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c
index 83f3ffbdbb4c..ea5e452510eb 100644
--- a/drivers/mfd/mt6358-irq.c
+++ b/drivers/mfd/mt6358-irq.c
@@ -212,6 +212,7 @@ int mt6358_irq_init(struct mt6397_chip *chip)
 
 	switch (chip->chip_id) {
 	case MT6358_CHIP_ID:
+	case MT6366_CHIP_ID:
 		chip->irq_data = &mt6358_irqd;
 		break;
 
diff --git a/include/linux/mfd/mt6358/registers.h b/include/linux/mfd/mt6358/registers.h
index 201139b12140..3d33517f178c 100644
--- a/include/linux/mfd/mt6358/registers.h
+++ b/include/linux/mfd/mt6358/registers.h
@@ -94,6 +94,10 @@
 #define MT6358_BUCK_VCORE_CON0                0x1488
 #define MT6358_BUCK_VCORE_DBG0                0x149e
 #define MT6358_BUCK_VCORE_DBG1                0x14a0
+#define MT6358_BUCK_VCORE_SSHUB_CON0          0x14a4
+#define MT6358_BUCK_VCORE_SSHUB_CON1          0x14a6
+#define MT6358_BUCK_VCORE_SSHUB_ELR0          MT6358_BUCK_VCORE_SSHUB_CON1
+#define MT6358_BUCK_VCORE_SSHUB_DBG1          MT6358_BUCK_VCORE_DBG1
 #define MT6358_BUCK_VCORE_ELR0                0x14aa
 #define MT6358_BUCK_VGPU_CON0                 0x1508
 #define MT6358_BUCK_VGPU_DBG0                 0x151e
@@ -169,6 +173,9 @@
 #define MT6358_LDO_VSRAM_OTHERS_CON0          0x1ba6
 #define MT6358_LDO_VSRAM_OTHERS_DBG0          0x1bc0
 #define MT6358_LDO_VSRAM_OTHERS_DBG1          0x1bc2
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON0    0x1bc4
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1    0x1bc6
+#define MT6358_LDO_VSRAM_OTHERS_SSHUB_DBG1    MT6358_LDO_VSRAM_OTHERS_DBG1
 #define MT6358_LDO_VSRAM_GPU_CON0             0x1bc8
 #define MT6358_LDO_VSRAM_GPU_DBG0             0x1be2
 #define MT6358_LDO_VSRAM_GPU_DBG1             0x1be4
diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h
index 56f210eebc54..1cf78726503b 100644
--- a/include/linux/mfd/mt6397/core.h
+++ b/include/linux/mfd/mt6397/core.h
@@ -14,6 +14,7 @@ enum chip_id {
 	MT6323_CHIP_ID = 0x23,
 	MT6358_CHIP_ID = 0x58,
 	MT6359_CHIP_ID = 0x59,
+	MT6366_CHIP_ID = 0x66,
 	MT6391_CHIP_ID = 0x91,
 	MT6397_CHIP_ID = 0x97,
 };
-- 
2.18.0



From johnson.wang at mediatek.com  Wed Jan  5 22:54:05 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Thu, 6 Jan 2022 14:54:05 +0800
Subject: [PATCH 2/4] regulator: mt6366: Add support for MT6366 regulator
In-Reply-To: <20220106065407.16036-1-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
Message-ID: <20220106065407.16036-3-johnson.wang@mediatek.com>

The MT6366 is a regulator found on boards based on MediaTek MT8186 and
probably other SoCs. It is a so called pmic and connects as a slave to
SoC using SPI, wrapped inside the pmic-wrapper.

Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 drivers/regulator/mt6358-regulator.c       | 213 ++++++++++++++++++++-
 include/linux/regulator/mt6358-regulator.h |  45 +++++
 2 files changed, 253 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
index eb8027813b99..8a5ce990f1bf 100644
--- a/drivers/regulator/mt6358-regulator.c
+++ b/drivers/regulator/mt6358-regulator.c
@@ -130,6 +130,102 @@ struct mt6358_regulator_info {
 	.qi = BIT(15),							\
 }
 
+#define MT6366_BUCK(match, vreg, min, max, step,		\
+	volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,	\
+	_modeset_reg, _modeset_shift)		\
+[MT6366_ID_##vreg] = {	\
+	.desc = {	\
+		.name = #vreg,	\
+		.of_match = of_match_ptr(match),	\
+		.ops = &mt6358_volt_range_ops,	\
+		.type = REGULATOR_VOLTAGE,	\
+		.id = MT6366_ID_##vreg,		\
+		.owner = THIS_MODULE,		\
+		.n_voltages = ((max) - (min)) / (step) + 1,	\
+		.linear_ranges = volt_ranges,		\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),	\
+		.vsel_reg = MT6358_BUCK_##vreg##_ELR0,	\
+		.vsel_mask = vosel_mask,	\
+		.enable_reg = MT6358_BUCK_##vreg##_CON0,	\
+		.enable_mask = BIT(0),	\
+		.of_map_mode = mt6358_map_mode,	\
+	},	\
+	.status_reg = MT6358_BUCK_##vreg##_DBG1,	\
+	.qi = BIT(0),	\
+	.da_vsel_reg = _da_vsel_reg,	\
+	.da_vsel_mask = _da_vsel_mask,	\
+	.modeset_reg = _modeset_reg,	\
+	.modeset_mask = BIT(_modeset_shift),	\
+}
+
+#define MT6366_LDO(match, vreg, ldo_volt_table,	\
+	ldo_index_table, enreg, enbit, vosel,	\
+	vosel_mask)	\
+[MT6366_ID_##vreg] = {	\
+	.desc = {	\
+		.name = #vreg,	\
+		.of_match = of_match_ptr(match),	\
+		.ops = &mt6358_volt_table_ops,	\
+		.type = REGULATOR_VOLTAGE,	\
+		.id = MT6366_ID_##vreg,	\
+		.owner = THIS_MODULE,	\
+		.n_voltages = ARRAY_SIZE(ldo_volt_table),	\
+		.volt_table = ldo_volt_table,	\
+		.vsel_reg = vosel,	\
+		.vsel_mask = vosel_mask,	\
+		.enable_reg = enreg,	\
+		.enable_mask = BIT(enbit),	\
+	},	\
+	.status_reg = MT6358_LDO_##vreg##_CON1,	\
+	.qi = BIT(15),	\
+	.index_table = ldo_index_table,	\
+	.n_table = ARRAY_SIZE(ldo_index_table),	\
+}
+
+#define MT6366_LDO1(match, vreg, min, max, step,	\
+	volt_ranges, _da_vsel_reg, _da_vsel_mask,	\
+	vosel, vosel_mask)	\
+[MT6366_ID_##vreg] = {	\
+	.desc = {	\
+		.name = #vreg,	\
+		.of_match = of_match_ptr(match),	\
+		.ops = &mt6358_volt_range_ops,	\
+		.type = REGULATOR_VOLTAGE,	\
+		.id = MT6366_ID_##vreg,	\
+		.owner = THIS_MODULE,	\
+		.n_voltages = ((max) - (min)) / (step) + 1,	\
+		.linear_ranges = volt_ranges,	\
+		.n_linear_ranges = ARRAY_SIZE(volt_ranges),	\
+		.vsel_reg = vosel,	\
+		.vsel_mask = vosel_mask,	\
+		.enable_reg = MT6358_LDO_##vreg##_CON0,	\
+		.enable_mask = BIT(0),	\
+	},	\
+	.da_vsel_reg = _da_vsel_reg,	\
+	.da_vsel_mask = _da_vsel_mask,	\
+	.status_reg = MT6358_LDO_##vreg##_DBG1,	\
+	.qi = BIT(0),	\
+}
+
+#define MT6366_REG_FIXED(match, vreg,	\
+	enreg, enbit, volt)	\
+[MT6366_ID_##vreg] = {	\
+	.desc = {	\
+		.name = #vreg,	\
+		.of_match = of_match_ptr(match),	\
+		.ops = &mt6358_volt_fixed_ops,	\
+		.type = REGULATOR_VOLTAGE,	\
+		.id = MT6366_ID_##vreg,	\
+		.owner = THIS_MODULE,	\
+		.n_voltages = 1,	\
+		.enable_reg = enreg,	\
+		.enable_mask = BIT(enbit),	\
+		.min_uV = volt,	\
+	},	\
+	.status_reg = MT6358_LDO_##vreg##_CON1,	\
+	.qi = BIT(15),							\
+}
+
 static const struct linear_range buck_volt_range1[] = {
 	REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
 };
@@ -409,6 +505,9 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
 	MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
 		    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
 		    MT6358_VCORE_VGPU_ANA_CON0, 1),
+	MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+		    MT6358_VCORE_VGPU_ANA_CON0, 1),
 	MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
 		    buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
 		    MT6358_VPA_ANA_CON0, 3),
@@ -488,6 +587,10 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
 	MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
 		    buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
 		    MT6358_LDO_VSRAM_CON2, 0x7f),
+	MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+		    1293750, 6250, buck_volt_range1,
+		    MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+		    MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
 	MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
 		    buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
 		    MT6358_LDO_VSRAM_CON3, 0x7f),
@@ -496,24 +599,124 @@ static struct mt6358_regulator_info mt6358_regulators[] = {
 		    MT6358_LDO_VSRAM_CON1, 0x7f),
 };
 
+/* The array is indexed by id(MT6366_ID_XXX) */
+static struct mt6358_regulator_info mt6366_regulators[] = {
+	MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+		    buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+		    MT6358_VDRAM1_ANA_CON0, 8),
+	MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+		    MT6358_VCORE_VGPU_ANA_CON0, 1),
+	MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f,
+		    MT6358_VCORE_VGPU_ANA_CON0, 1),
+	MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+		    buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f,
+		    MT6358_VPA_ANA_CON0, 3),
+	MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+		    MT6358_VPROC_ANA_CON0, 1),
+	MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+		    MT6358_VPROC_ANA_CON0, 2),
+	MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f,
+		    MT6358_VCORE_VGPU_ANA_CON0, 2),
+	MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+		    buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f,
+		    MT6358_VS2_ANA_CON0, 8),
+	MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+		    buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+		    MT6358_VMODEM_ANA_CON0, 8),
+	MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+		    buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f,
+		    MT6358_VS1_ANA_CON0, 8),
+	MT6366_REG_FIXED("ldo_vrf12", VRF12,
+			 MT6358_LDO_VRF12_CON0, 0, 1200000),
+	MT6366_REG_FIXED("ldo_vio18", VIO18,
+			 MT6358_LDO_VIO18_CON0, 0, 1800000),
+	MT6366_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
+	MT6366_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
+	MT6366_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
+	MT6366_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
+	MT6366_REG_FIXED("ldo_vaux18", VAUX18,
+			 MT6358_LDO_VAUX18_CON0, 0, 1800000),
+	MT6366_REG_FIXED("ldo_vbif28", VBIF28,
+			 MT6358_LDO_VBIF28_CON0, 0, 2800000),
+	MT6366_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
+	MT6366_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
+	MT6366_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
+	MT6366_REG_FIXED("ldo_vaud28", VAUD28,
+			 MT6358_LDO_VAUD28_CON0, 0, 2800000),
+	MT6366_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+		   MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10),
+	MT6366_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
+		   MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00),
+	MT6366_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+		   MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00),
+	MT6366_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
+		   MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700),
+	MT6366_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
+		   MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00),
+	MT6366_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
+		   MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700),
+	MT6366_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
+		   MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700),
+	MT6366_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
+		   vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
+		   0, MT6358_VCN33_ANA_CON0, 0x300),
+	MT6366_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
+		   vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
+		   0, MT6358_VCN33_ANA_CON0, 0x300),
+	MT6366_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
+		   MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00),
+	MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+		   MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00),
+	MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+		    buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00,
+		    MT6358_LDO_VSRAM_CON0, 0x7f),
+	MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+		    buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00,
+		    MT6358_LDO_VSRAM_CON2, 0x7f),
+	MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000,
+		    1293750, 6250, buck_volt_range1,
+		    MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f,
+		    MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f),
+	MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+		    buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00,
+		    MT6358_LDO_VSRAM_CON3, 0x7f),
+	MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+		    buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00,
+		    MT6358_LDO_VSRAM_CON1, 0x7f),
+};
+
 static int mt6358_regulator_probe(struct platform_device *pdev)
 {
 	struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_config config = {};
 	struct regulator_dev *rdev;
-	int i;
+	struct mt6358_regulator_info *mt6358_info;
+	int i, max_regulator;
+
+	if (mt6397->chip_id == MT6366_CHIP_ID) {
+		max_regulator = MT6366_MAX_REGULATOR;
+		mt6358_info = mt6366_regulators;
+	} else {
+		max_regulator = MT6358_MAX_REGULATOR;
+		mt6358_info = mt6358_regulators;
+	}
 
-	for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
+	for (i = 0; i < max_regulator; i++) {
 		config.dev = &pdev->dev;
-		config.driver_data = &mt6358_regulators[i];
+		config.driver_data = &mt6358_info[i];
 		config.regmap = mt6397->regmap;
 
 		rdev = devm_regulator_register(&pdev->dev,
-					       &mt6358_regulators[i].desc,
+					       &mt6358_info[i].desc,
 					       &config);
 		if (IS_ERR(rdev)) {
 			dev_err(&pdev->dev, "failed to register %s\n",
-				mt6358_regulators[i].desc.name);
+				mt6358_info[i].desc.name);
 			return PTR_ERR(rdev);
 		}
 	}
diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h
index 1cc304946d09..bdcf83cd719e 100644
--- a/include/linux/regulator/mt6358-regulator.h
+++ b/include/linux/regulator/mt6358-regulator.h
@@ -48,9 +48,54 @@ enum {
 	MT6358_ID_VLDO28,
 	MT6358_ID_VAUD28,
 	MT6358_ID_VSIM2,
+	MT6358_ID_VCORE_SSHUB,
+	MT6358_ID_VSRAM_OTHERS_SSHUB,
 	MT6358_ID_RG_MAX,
 };
 
+enum {
+	MT6366_ID_VDRAM1 = 0,
+	MT6366_ID_VCORE,
+	MT6366_ID_VPA,
+	MT6366_ID_VPROC11,
+	MT6366_ID_VPROC12,
+	MT6366_ID_VGPU,
+	MT6366_ID_VS2,
+	MT6366_ID_VMODEM,
+	MT6366_ID_VS1,
+	MT6366_ID_VDRAM2,
+	MT6366_ID_VSIM1,
+	MT6366_ID_VIBR,
+	MT6366_ID_VRF12,
+	MT6366_ID_VIO18,
+	MT6366_ID_VUSB,
+	MT6366_ID_VCN18,
+	MT6366_ID_VFE28,
+	MT6366_ID_VSRAM_PROC11,
+	MT6366_ID_VCN28,
+	MT6366_ID_VSRAM_OTHERS,
+	MT6366_ID_VSRAM_GPU,
+	MT6366_ID_VXO22,
+	MT6366_ID_VEFUSE,
+	MT6366_ID_VAUX18,
+	MT6366_ID_VMCH,
+	MT6366_ID_VBIF28,
+	MT6366_ID_VSRAM_PROC12,
+	MT6366_ID_VEMC,
+	MT6366_ID_VIO28,
+	MT6366_ID_VA12,
+	MT6366_ID_VRF18,
+	MT6366_ID_VCN33_BT,
+	MT6366_ID_VCN33_WIFI,
+	MT6366_ID_VMC,
+	MT6366_ID_VAUD28,
+	MT6366_ID_VSIM2,
+	MT6366_ID_VCORE_SSHUB,
+	MT6366_ID_VSRAM_OTHERS_SSHUB,
+	MT6366_ID_RG_MAX,
+};
+
 #define MT6358_MAX_REGULATOR	MT6358_ID_RG_MAX
+#define MT6366_MAX_REGULATOR	MT6366_ID_RG_MAX
 
 #endif /* __LINUX_REGULATOR_MT6358_H */
-- 
2.18.0



From johnson.wang at mediatek.com  Wed Jan  5 22:54:07 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Thu, 6 Jan 2022 14:54:07 +0800
Subject: [PATCH 4/4] dt-bindings: regulator: Add MT6358 regulators
In-Reply-To: <20220106065407.16036-1-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
Message-ID: <20220106065407.16036-5-johnson.wang@mediatek.com>

Add buck_vcore_sshub and ldo_vsram_others_sshub
regulators to binding document for MT6358 and MT6366.

Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 .../bindings/regulator/mt6358-regulator.txt   | 22 ++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
index 9a90a92f2d7e..7034cdca54e0 100644
--- a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
@@ -8,14 +8,14 @@ Documentation/devicetree/bindings/regulator/regulator.txt.
 
 The valid names for regulators are::
 BUCK:
-  buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
-  buck_vs2, buck_vmodem, buck_vs1
+  buck_vdram1, buck_vcore, buck_vcore_sshub, buck_vpa, buck_vproc11,
+  buck_vproc12, buck_vgpu, buck_vs2, buck_vmodem, buck_vs1
 LDO:
   ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
   ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
-  ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
-  ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
-  ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
+  ldo_vsram_others_sshub, ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18,
+  ldo_vmch, ldo_vbif28, ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12,
+  ldo_vrf18, ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
   ldo_vsim2
 
 Example:
@@ -354,5 +354,17 @@ Example:
 				regulator-max-microvolt = <3100000>;
 				regulator-enable-ramp-delay = <540>;
 			};
+
+			mt6358_vcore_sshub_reg: buck_vcore_sshub {
+				regulator-name = "vcore_sshub";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1293750>;
+			};
+
+			mt6358_vsram_others_sshub_reg: ldo_vsram_others_sshub {
+				regulator-name = "vsram_others_sshub";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1293750>;
+			};
 		};
 	};
-- 
2.18.0



From kyrie.wu at mediatek.com  Wed Jan  5 22:52:49 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 14:52:49 +0800
Subject: [PATCH V1, 4/6] media: mtk-jpegdec: add jpeg decode worker
 interface
In-Reply-To: <1de01778-5750-c7aa-eac9-d9f91ad76ddb@collabora.com>
References: <1638509655-14296-1-git-send-email-kyrie.wu@mediatek.com>
 <1638509655-14296-5-git-send-email-kyrie.wu@mediatek.com>
 <1de01778-5750-c7aa-eac9-d9f91ad76ddb@collabora.com>
Message-ID: <065733e7f404a31985560a490910f57d9c1897c8.camel@mediatek.com>

On Mon, 2021-12-06 at 17:26 +0100, AngeloGioacchino Del Regno wrote:
> Il 03/12/21 06:34, kyrie.wu ha scritto:
> > Add jpeg decoding worker to ensure that three HWs
> > run in parallel in MT8195.
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> >   drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c   | 190
> > +++++++++++++++++++---
> >   drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h   |   5 +
> >   drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c |  17 ++
> >   3 files changed, 189 insertions(+), 23 deletions(-)
> > 
> 
> Hello Kyrie,
> thanks for the patch! However, there are some things to improve...
> 
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > index f2a5e84..2518660 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > @@ -1065,57 +1065,187 @@ static void mtk_jpeg_enc_device_run(void
> > *priv)
> >   	queue_work(jpeg->workqueue, &ctx->jpeg_work);
> >   }
> >   
> > -static void mtk_jpeg_dec_device_run(void *priv)
> > +static int mtk_jpegdec_select_hw(struct mtk_jpeg_ctx *ctx)
> >   {
> > -	struct mtk_jpeg_ctx *ctx = priv;
> > +	struct mtk_jpegdec_comp_dev *comp_jpeg;
> >   	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
> > -	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > -	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
> >   	unsigned long flags;
> > -	struct mtk_jpeg_src_buf *jpeg_src_buf;
> > +	int hw_id = -1;
> > +	int i;
> > +
> > +	spin_lock_irqsave(&jpeg->hw_lock, flags);
> > +	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
> > +		comp_jpeg = jpeg->dec_hw_dev[i];
> > +		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
> > +			hw_id = i;
> > +			comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
> > +
> > +	return hw_id;
> > +}
> > +
> > +static int mtk_jpegdec_deselect_hw(struct mtk_jpeg_dev *jpeg, int
> > hw_id)
> > +{
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&jpeg->hw_lock, flags);
> > +	jpeg->dec_hw_dev[hw_id]->hw_state =
> > +		MTK_JPEG_HW_IDLE;
> > +	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_jpegdec_set_hw_param(struct mtk_jpeg_ctx *ctx,
> > +	int hw_id,
> > +	struct vb2_v4l2_buffer *src_buf,
> > +	struct vb2_v4l2_buffer *dst_buf)
> > +{
> > +	struct mtk_jpegdec_comp_dev *jpeg =
> > +		ctx->jpeg->dec_hw_dev[hw_id];
> > +
> > +	jpeg->hw_param.curr_ctx = ctx;
> > +	jpeg->hw_param.src_buffer = src_buf;
> > +	jpeg->hw_param.dst_buffer = dst_buf;
> > +
> > +	return 0;
> > +}
> > +
> > +static void mtk_jpegdec_worker(struct work_struct *work)
> > +{
> > +	struct mtk_jpeg_ctx *ctx = container_of(work, struct
> > mtk_jpeg_ctx,
> > +		jpeg_work);
> > +	struct mtk_jpegdec_comp_dev *comp_jpeg[MTK_JPEGDEC_HW_MAX];
> > +	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
> > +	struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf;
> > +	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > +	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
> > +	atomic_t *hw_rdy[MTK_JPEGDEC_HW_MAX];
> > +	struct clk *jpegdec_clk;
> > +	int ret, i, hw_id = 0;
> >   	struct mtk_jpeg_bs bs;
> >   	struct mtk_jpeg_fb fb;
> > -	int ret;
> > +	unsigned long flags;
> > +
> > +	for (i = 0; i < MTK_JPEGDEC_HW_MAX; i++) {
> > +		comp_jpeg[i] = jpeg->dec_hw_dev[i];
> > +		hw_rdy[i] = &comp_jpeg[i]->hw_rdy;
> > +	}
> > +
> 
> This entire retry_select block should go to a helper function instead
> of being inside of here.
> 
> Also, there's a big issue with this snippet that has to be solved:
> you're
> unconditionally calling "goto retry_select" at the end of the if
> branch,
> but please consider the following scenario:
> 
> - mtk_jpegdec_select_hw() returns a hw_id < 0
> - wait_event_interruptible returns 0
> ... then we redo the same, and we still get the same result.
> 
> This may generate an infinite loop!!
> 
> After putting this into a separate function, please use a controlled
> loop
> with a well thought maximum number of retries, as to avoid this
> situation.
Dear Angelo,
I will use wait_event_interruptible_timeout to replace
wait_event_interruptible to avoid the situation you memtioned above and
use a helper function instead those code.
> 
> > +retry_select:
> > +	hw_id = mtk_jpegdec_select_hw(ctx);
> > +	if (hw_id < 0) {
> > +		ret = wait_event_interruptible(jpeg->dec_hw_wq,
> > +			(atomic_read(hw_rdy[0]) ||
> > +			atomic_read(hw_rdy[1]) ||
> > +			atomic_read(hw_rdy[2])) > 0);
> > +		if (ret != 0) {
> > +			dev_err(jpeg->dev, "%s : %d, all HW are
> > busy\n",
> > +				__func__, __LINE__);
> > +			v4l2_m2m_job_finish(jpeg->m2m_dev, ctx-
> > >fh.m2m_ctx);
> > +			return;
> > +		}
> > +
> > +		dev_err(jpeg->dev, "%s : %d, NEW HW IDLE, please retry
> > selcet!!!\n",
> > +			__func__, __LINE__);
> > +		goto retry_select;
> > +	}
> >   
> > +	atomic_dec(&comp_jpeg[hw_id]->hw_rdy);
> >   	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
> > +	if (!src_buf) {
> > +		dev_err(jpeg->dev, "%s : %d, get src_buf fail !!!\n",
> > +			__func__, __LINE__);
> > +		goto getbuf_fail;
> > +	}
> >   	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
> > +	if (!dst_buf) {
> > +		dev_err(jpeg->dev, "%s : %d, get dst_buf fail !!!\n",
> > +			__func__, __LINE__);
> > +		goto getbuf_fail;
> > +	}
> > +
> >   	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
> > +	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
> >   
> > -	if (mtk_jpeg_check_resolution_change(ctx, &jpeg_src_buf-
> > >dec_param)) {
> > +	if (mtk_jpeg_check_resolution_change(ctx,
> > +		&jpeg_src_buf->dec_param)) {
> 
> Why are you breaking this line? There's no need to.
If the resolution changed, all input and output buffer would be free
and the new size buffer would be malloc to match the lastest resolution
for jpeg decode.
> 
> >   		mtk_jpeg_queue_src_chg_event(ctx);
> >   		ctx->state = MTK_JPEG_SOURCE_CHANGE;
> > -		v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
> > -		return;
> > +		goto getbuf_fail;
> >   	}
> >   
> 
> 
> Regards,
> - Angelo

From yc.hung at mediatek.com  Wed Jan  5 22:48:48 2022
From: yc.hung at mediatek.com (YC Hung)
Date: Thu, 6 Jan 2022 14:48:48 +0800
Subject: [PATCH v4] dt-bindings: dsp: mediatek: add mt8195 dsp document
Message-ID: <20220106064847.15588-1-yc.hung@mediatek.com>

From: "YC Hung" <yc.hung at mediatek.com>

This patch adds mt8195 dsp document. The dsp is used for Sound Open
Firmware driver node. It includes registers,  clocks, memory regions,
and mailbox for dsp.

Signed-off-by: yc.hung <yc.hung at mediatek.com>
---
Changes since v3:
  Fix patch v3 error : v3 only provide difference between v3 and v2.

Changes since v2:
  Remove useless watchdog interrupt.
  Add commit message more detail description.

Changes since v1:
  Rename yaml file name as mediatek,mt8195-dsp.yaml
  Refine descriptions for mailbox, memory-region and drop unused labels
  in examples.
---
 .../bindings/dsp/mediatek,mt8195-dsp.yaml     | 105 ++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml

diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
new file mode 100644
index 000000000000..b7e68b0dfa13
--- /dev/null
+++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dsp/mediatek,mt8195-dsp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek mt8195 DSP core
+
+maintainers:
+  - YC Hung <yc.hung at mediatek.com>
+
+description: |
+  Some boards from mt8195 contain a DSP core used for
+  advanced pre- and post- audio processing.
+
+properties:
+  compatible:
+    const: mediatek,mt8195-dsp
+
+  reg:
+    items:
+      - description: Address and size of the DSP Cfg registers
+      - description: Address and size of the DSP SRAM
+
+  reg-names:
+    items:
+      - const: cfg
+      - const: sram
+
+  clocks:
+    items:
+      - description: mux for audio dsp clock
+      - description: 26M clock
+      - description: mux for audio dsp local bus
+      - description: default audio dsp local bus clock source
+      - description: clock gate for audio dsp clock
+      - description: mux for audio dsp access external bus
+
+  clock-names:
+    items:
+      - const: adsp_sel
+      - const: clk26m_ck
+      - const: audio_local_bus
+      - const: mainpll_d7_d2
+      - const: scp_adsp_audiodsp
+      - const: audio_h
+
+  power-domains:
+    maxItems: 1
+
+  mboxes:
+    items:
+      - description: ipc reply between host and audio DSP.
+      - description: ipc request between host and audio DSP.
+
+  mbox-names:
+    items:
+      - const: mbox0
+      - const: mbox1
+
+  memory-region:
+    items:
+      - description: dma buffer between host and DSP.
+      - description: DSP system memory.
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - memory-region
+  - power-domains
+  - mbox-names
+  - mboxes
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    dsp at 10803000 {
+       compatible =  "mediatek,mt8195-dsp";
+       reg = <0x10803000  0x1000>,
+             <0x10840000  0x40000>;
+       reg-names = "cfg", "sram";
+       clocks = <&topckgen 10>, //CLK_TOP_ADSP
+                <&clk26m>,
+                <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS
+                <&topckgen 136>, //CLK_TOP_MAINPLL_D7_D2
+                <&scp_adsp 0>, //CLK_SCP_ADSP_AUDIODSP
+                <&topckgen 34>; //CLK_TOP_AUDIO_H
+       clock-names = "adsp_sel",
+                     "clk26m_ck",
+                     "audio_local_bus",
+                     "mainpll_d7_d2",
+                     "scp_adsp_audiodsp",
+                     "audio_h";
+       memory-region = <&adsp_dma_mem_reserved>,
+                       <&adsp_mem_reserved>;
+       power-domains = <&spm 6>; //MT8195_POWER_DOMAIN_ADSP
+       mbox-names = "mbox0", "mbox1";
+       mboxes = <&adsp_mailbox0>, <&adsp_mailbox1>;
+    };
-- 
2.18.0



From yc.hung at mediatek.com  Wed Jan  5 23:10:08 2022
From: yc.hung at mediatek.com (YC Hung)
Date: Thu, 6 Jan 2022 15:10:08 +0800
Subject: [PATCH v3] dt-bindings: dsp: mediatek: add mt8195 dsp document
In-Reply-To: <CAEnQRZBH4uwMmyBLY2bCtY9QZooBiK5PqF3T+4K8WAtQV1QN-Q@mail.gmail.com>
References: <20220103043202.6524-1-yc.hung@mediatek.com>
 <CAEnQRZBH4uwMmyBLY2bCtY9QZooBiK5PqF3T+4K8WAtQV1QN-Q@mail.gmail.com>
Message-ID: <3e00db1d4fe71938b0274331cd49b96bdddccea4.camel@mediatek.com>

Hi Daniel,

My mistake. Thanks for review and comments. I have updated v4 to fix
it. Thanks
On Wed, 2022-01-05 at 17:53 +0200, Daniel Baluta wrote:
> On Mon, Jan 3, 2022 at 1:00 PM YC Hung <yc.hung at mediatek.com> wrote:
> > 
> > From: "YC Hung" <yc.hung at mediatek.com>
> > 
> > This patch adds mt8195 dsp document. The dsp is used for Sound Open
> > Firmware driver node. It includes registers,  clocks, memory
> > regions,
> > and mailbox for dsp.
> > 
> > Signed-off-by: yc.hung <yc.hung at mediatek.com>
> 
> The code patch should be created against original source code from
> Rob's tree. Here it seems the patch is against v2.
> 
> This isn't going to work! Because when Rob will try to apply the
> patch
> it will fail since he doesn't have (and doesnt need to have)
> your previous versions.
> 
> So, please keep the changes history (that's a good thing!) but always
> rebase your patch on maintainer's tree.
> 
> 
> > ---
> > Changes since v2:
> >   Remove useless watchdog interrupt.
> >   Add commit message more detail description.
> > 
> > Changes since v1:
> >   Rename yaml file name as mediatek,mt8195-dsp.yaml
> >   Refine descriptions for mailbox, memory-region and drop unused
> > labels
> >   in examples.
> > ---
> > ---
> >  .../devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml | 12 --------
> > ----
> >  1 file changed, 12 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-
> > dsp.yaml b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-
> > dsp.yaml
> > index bde763191d86..779daa786739 100644
> > --- a/Documentation/devicetree/bindings/dsp/mediatek,mt8195-
> > dsp.yaml
> > +++ b/Documentation/devicetree/bindings/dsp/mediatek,mt8195-
> > dsp.yaml
> > @@ -27,14 +27,6 @@ properties:
> >        - const: cfg
> >        - const: sram
> > 
> > -  interrupts:
> > -    items:
> > -      - description: watchdog interrupt
> > -
> > -  interrupt-names:
> > -    items:
> > -      - const: wdt
> > -
> >    clocks:
> >      items:
> >        - description: mux for audio dsp clock
> > @@ -75,8 +67,6 @@ required:
> >    - compatible
> >    - reg
> >    - reg-names
> > -  - interrupts
> > -  - interrupt-names
> >    - clocks
> >    - clock-names
> >    - memory-region
> > @@ -95,8 +85,6 @@ examples:
> >         reg = <0x10803000  0x1000>,
> >               <0x10840000  0x40000>;
> >         reg-names = "cfg", "sram";
> > -       interrupts = <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH 0>;
> > -       interrupt-names = "wdt";
> >         clocks = <&topckgen 10>, //CLK_TOP_ADSP
> >                  <&clk26m>,
> >                  <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS
> > --
> > 2.18.0
> > 



From kyrie.wu at mediatek.com  Wed Jan  5 23:35:17 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 15:35:17 +0800
Subject: [PATCH V6,  2/5] media: mtk-jpegenc: manage jpegenc multi-hardware
In-Reply-To: <YaovjHw74L9hNcME@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <1638501230-13417-3-git-send-email-kyrie.wu@mediatek.com>
 <YaovjHw74L9hNcME@gmail.com>
Message-ID: <305da596536f3a7da830f2552d455258f882aa5b.camel@mediatek.com>

On Fri, 2021-12-03 at 15:54 +0100, Ricardo Ribalda wrote:
> kyrie.wu wrote:
> 
> > manage each hardware information, including irq/clk/power.
> > the hardware includes HW0 and HW1.
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> > V6: use of_platform_populate to replace component framework
> > to manage multi-hardware
> > ---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c   | 103 +++++++---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h   |  55 +++++
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 232
> > +++++++++++++++++++++-
> >  3 files changed, 362 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > index a89c7b2..da7eb84 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > @@ -1353,33 +1353,40 @@ static int mtk_jpeg_probe(struct
> > platform_device *pdev)
> >  	spin_lock_init(&jpeg->hw_lock);
> >  	jpeg->dev = &pdev->dev;
> >  	jpeg->variant = of_device_get_match_data(jpeg->dev);
> > -	INIT_DELAYED_WORK(&jpeg->job_timeout_work,
> > mtk_jpeg_job_timeout_work);
> >  
> > -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -	jpeg->reg_base = devm_ioremap_resource(&pdev->dev, res);
> > -	if (IS_ERR(jpeg->reg_base)) {
> > -		ret = PTR_ERR(jpeg->reg_base);
> > -		return ret;
> > -	}
> > +	if (!jpeg->variant->is_encoder) {
> > +		INIT_DELAYED_WORK(&jpeg->job_timeout_work,
> > +				mtk_jpeg_job_timeout_work);
> >  
> > -	jpeg_irq = platform_get_irq(pdev, 0);
> > -	if (jpeg_irq < 0) {
> > -		dev_err(&pdev->dev, "Failed to get jpeg_irq %d.\n",
> > jpeg_irq);
> > -		return jpeg_irq;
> > -	}
> 
> Maybe better use  devm_platform_ioremap_resource()
It would used in the next code version.
thanks.
> > +		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +		jpeg->reg_base = devm_ioremap_resource(&pdev->dev,
> > res);
> > +		if (IS_ERR(jpeg->reg_base)) {
> > +			ret = PTR_ERR(jpeg->reg_base);
> > +			return ret;
> > +		}
> >  
> > -	ret = devm_request_irq(&pdev->dev, jpeg_irq,
> > -			       jpeg->variant->irq_handler, 0, pdev-
> > >name, jpeg);
> > -	if (ret) {
> > -		dev_err(&pdev->dev, "Failed to request jpeg_irq %d
> > (%d)\n",
> > -			jpeg_irq, ret);
> > -		goto err_req_irq;
> > -	}
> > +		jpeg_irq = platform_get_irq(pdev, 0);
> > +		if (jpeg_irq < 0) {
> > +			dev_err(&pdev->dev, "Failed to get
> > jpeg_irq.\n");
> > +			return jpeg_irq;
> > +		}
> >  
> > -	ret = mtk_jpeg_clk_init(jpeg);
> > -	if (ret) {
> > -		dev_err(&pdev->dev, "Failed to init clk, err %d\n",
> > ret);
> > -		goto err_clk_init;
> > +		ret = devm_request_irq(&pdev->dev, jpeg_irq,
> > +				       jpeg->variant->irq_handler,
> > +					   0, pdev->name, jpeg);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "Failed to request jpeg_irq
> > %d (%d)\n",
> > +				jpeg_irq, ret);
> > +			goto err_req_irq;
> > +		}
> > +
> > +		ret = mtk_jpeg_clk_init(jpeg);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "Failed to init clk(%d)\n",
> > ret);
> > +			goto err_clk_init;
> > +		}
> > +
> > +		pm_runtime_enable(&pdev->dev);
> >  	}
> >  
> >  	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
> > @@ -1426,9 +1433,16 @@ static int mtk_jpeg_probe(struct
> > platform_device *pdev)
> >  		  jpeg->variant->dev_name, jpeg->vdev->num,
> >  		  VIDEO_MAJOR, jpeg->vdev->minor);
> >  
> > -	platform_set_drvdata(pdev, jpeg);
> > +	if (jpeg->variant->is_encoder) {
> 
> Can you share a device tree that uses this?
I will supply in the next code version.
thanks.
>  
> 
> You can't you have all the device in same level, instead of making
> them
> childs of this device?
MT8195 has two encode hw, we wanna use one device node to use them, so
they can't set in same level.
> > +		ret = of_platform_populate(pdev->dev.of_node, NULL,
> > NULL,
> > +			&pdev->dev);
> 
> Maybe you want devm_of_platform_populate()?
It would fixed in the next code version.
thanks.
> > +		if (ret) {
> > +			v4l2_err(&jpeg->v4l2_dev, "Master of platform
> > populate failed.");
> > +			goto err_vfd_jpeg_register;
> > +		}
> > +	}
> >  
> > -	pm_runtime_enable(&pdev->dev);
> > +	platform_set_drvdata(pdev, jpeg);
> >  
> >  	return 0;
> >  
> > @@ -1539,6 +1553,19 @@ static const struct mtk_jpeg_variant
> > mtk_jpeg_drvdata = {
> >  	.cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
> >  };
> >  
> > +static const struct mtk_jpeg_variant mtk_jpegenc_drvdata = {
> > +	.is_encoder = true,
> > +	.formats = mtk_jpeg_enc_formats,
> > +	.num_formats = MTK_JPEG_ENC_NUM_FORMATS,
> > +	.qops = &mtk_jpeg_enc_qops,
> > +	.m2m_ops = &mtk_jpeg_enc_m2m_ops,
> > +	.dev_name = "mtk-jpeg-enc",
> > +	.ioctl_ops = &mtk_jpeg_enc_ioctl_ops,
> > +	.out_q_default_fourcc = V4L2_PIX_FMT_YUYV,
> > +	.cap_q_default_fourcc = V4L2_PIX_FMT_JPEG,
> > +};
> > +
> > +#if defined(CONFIG_OF)
> >  static const struct of_device_id mtk_jpeg_match[] = {
> >  	{
> >  		.compatible = "mediatek,mt8173-jpgdec",
> > @@ -1552,10 +1579,14 @@ static const struct of_device_id
> > mtk_jpeg_match[] = {
> >  		.compatible = "mediatek,mtk-jpgenc",
> >  		.data = &mtk_jpeg_drvdata,
> >  	},
> > +	{
> > +		.compatible = "mediatek,mt8195-jpgenc",
> > +		.data = &mtk_jpegenc_drvdata,
> > +	},
> >  	{},
> >  };
> > -
> >  MODULE_DEVICE_TABLE(of, mtk_jpeg_match);
> > +#endif
> >  
> >  static struct platform_driver mtk_jpeg_driver = {
> >  	.probe = mtk_jpeg_probe,
> > @@ -1567,7 +1598,25 @@ static struct platform_driver
> > mtk_jpeg_driver = {
> >  	},
> >  };
> 
> This is not very clear. It would be better to refactor the change and
> have a module_platform_driver() macro for jpegenc_hw_driver, where
> its
> probe and remove exists.
This suggestion would used in the next code version.
thanks.
> > 
> > -module_platform_driver(mtk_jpeg_driver);
> > +static struct platform_driver * const mtk_jpeg_source_drivers[] =
> > {
> > +	&mtk_jpegenc_hw_driver,
> > +	&mtk_jpeg_driver,
> > +};
> > +static int __init mtk_jpeg_init(void)
> > +{
> > +	return platform_register_drivers(mtk_jpeg_source_drivers,
> > +		ARRAY_SIZE(mtk_jpeg_source_drivers));
> > +}
> > +
> > +static void __exit mtk_jpeg_exit(void)
> > +{
> > +	platform_unregister_drivers(mtk_jpeg_source_drivers,
> > +		ARRAY_SIZE(mtk_jpeg_source_drivers));
> > +}
> > +
> > +module_init(mtk_jpeg_init);
> > +module_exit(mtk_jpeg_exit);
> > +
> >  
> >  MODULE_DESCRIPTION("MediaTek JPEG codec driver");
> >  MODULE_LICENSE("GPL v2");
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > index 595f7f1..7d013de 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > @@ -60,6 +60,7 @@ enum mtk_jpeg_ctx_state {
> >   * @cap_q_default_fourcc:	capture queue default fourcc
> >   */
> >  struct mtk_jpeg_variant {
> > +	bool is_encoder;
> >  	struct clk_bulk_data *clks;
> >  	int num_clks;
> >  	struct mtk_jpeg_fmt *formats;
> > @@ -74,6 +75,55 @@ struct mtk_jpeg_variant {
> >  	u32 cap_q_default_fourcc;
> >  };
> >  
> > +enum mtk_jpegenc_hw_id {
> > +	MTK_JPEGENC_HW0,
> > +	MTK_JPEGENC_HW1,
> > +	MTK_JPEGENC_HW_MAX,
> > +};
> > +
> > +/**
> > + * struct mtk_jpegenc_clk_info - Structure used to store clock
> > name
> > + */
> > +struct mtk_jpegenc_clk_info {
> > +	const char	*clk_name;
> > +	struct clk	*jpegenc_clk;
> > +};
> > +
> > +/**
> > + * struct mtk_vcodec_clk - Structure used to store vcodec clock
> > information
> > + */
> > +struct mtk_jpegenc_clk {
> > +	struct mtk_jpegenc_clk_info	*clk_info;
> > +	int	clk_num;
> > +};
> > +
> > +/**
> > + * struct mtk_vcodec_pm - Power management data structure
> > + */
> > +struct mtk_jpegenc_pm {
> > +	struct mtk_jpegenc_clk	venc_clk;
> > +	struct device	*dev;
> > +	struct mtk_jpegenc_comp_dev	*mtkdev;
> > +};
> > +
> > +/**
> > + * struct mtk_jpegenc_comp_dev - JPEG COREX abstraction
> > + * @dev:		        JPEG device
> > + * @plat_dev:		    platform device data
> > + * @reg_base:		    JPEG registers mapping
> > + * @master_dev:		    mtk_jpeg_dev device
> > + * @pm:	                mtk_jpegenc_pm
> > + * @jpegenc_irq:	    jpeg encode irq num
> > + */
> > +struct mtk_jpegenc_comp_dev {
> > +	struct device		*dev;
> > +	struct platform_device *plat_dev;
> > +	void __iomem		*reg_base;
> > +	struct mtk_jpeg_dev *master_dev;
> > +	struct mtk_jpegenc_pm pm;
> > +	int jpegenc_irq;
> > +};
> > +
> >  /**
> >   * struct mtk_jpeg_dev - JPEG IP abstraction
> >   * @lock:		the mutex protecting this structure
> > @@ -102,6 +152,9 @@ struct mtk_jpeg_dev {
> >  	struct device		*larb;
> >  	struct delayed_work job_timeout_work;
> >  	const struct mtk_jpeg_variant *variant;
> > +
> > +	void __iomem *reg_encbase[MTK_JPEGENC_HW_MAX];
> > +	struct mtk_jpegenc_comp_dev *enc_hw_dev[MTK_JPEGENC_HW_MAX];
> >  };
> >  
> >  /**
> > @@ -162,4 +215,6 @@ struct mtk_jpeg_ctx {
> >  	struct v4l2_ctrl_handler ctrl_hdl;
> >  };
> > 
> 
> Please no extern here:
It would fixed in the next code version.
thanks.
> > +extern struct platform_driver mtk_jpegenc_hw_driver;
> > +
> >  #endif /* _MTK_JPEG_CORE_H */
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > index 1cf037b..4ccda1d 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > @@ -4,12 +4,27 @@
> >   * Author: Xia Jiang <xia.jiang at mediatek.com>
> >   *
> >   */
> > -
> > +#include <linux/clk.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irq.h>
> >  #include <linux/io.h>
> >  #include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_device.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/slab.h>
> > +#include <media/media-device.h>
> >  #include <media/videobuf2-core.h>
> >  #include <media/videobuf2-dma-contig.h>
> > +#include <media/videobuf2-v4l2.h>
> > +#include <media/v4l2-mem2mem.h>
> > +#include <media/v4l2-dev.h>
> > +#include <media/v4l2-device.h>
> > +#include <media/v4l2-fh.h>
> > +#include <media/v4l2-event.h>
> >  
> > +#include "mtk_jpeg_core.h"
> >  #include "mtk_jpeg_enc_hw.h"
> >  
> >  static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = {
> > @@ -30,6 +45,21 @@ static const struct mtk_jpeg_enc_qlt
> > mtk_jpeg_enc_quality[] = {
> >  	{.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97},
> >  };
> >  
> > +#if defined(CONFIG_OF)
> > +static const struct of_device_id mtk_jpegenc_drv_ids[] = {
> > +	{
> > +		.compatible = "mediatek,mt8195-jpgenc0",
> > +		.data = (void *)MTK_JPEGENC_HW0,
> > +	},
> > +	{
> > +		.compatible = "mediatek,mt8195-jpgenc1",
> > +		.data = (void *)MTK_JPEGENC_HW1,
> > +	},
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids);
> > +#endif
> > +
> >  void mtk_jpeg_enc_reset(void __iomem *base)
> >  {
> >  	writel(0, base + JPEG_ENC_RSTB);
> > @@ -152,3 +182,203 @@ void mtk_jpeg_set_enc_params(struct
> > mtk_jpeg_ctx *ctx,  void __iomem *base)
> >  
> >  	writel(ctx->restart_interval, base + JPEG_ENC_RST_MCU_NUM);
> >  }
> > +
> > +static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> > +{
> > +	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > +	enum vb2_buffer_state buf_state;
> > +	struct mtk_jpeg_ctx *ctx;
> > +	u32 result_size;
> > +	u32 irq_status;
> > +
> > +	struct mtk_jpegenc_comp_dev *jpeg = priv;
> > +	struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev;
> > +
> > +	irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
> > +		JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
> > +	if (irq_status)
> > +		writel(0, jpeg->reg_base + JPEG_ENC_INT_STS);
> > +	if (!(irq_status & JPEG_ENC_INT_STATUS_DONE))
> > +		return IRQ_NONE;
> > +
> > +	ctx = v4l2_m2m_get_curr_priv(master_jpeg->m2m_dev);
> > +	if (!ctx) {
> > +		v4l2_err(&master_jpeg->v4l2_dev, "Context is NULL\n");
> > +		return IRQ_HANDLED;
> > +	}
> > +
> > +	src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> > +	dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> > +	result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base);
> > +	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
> > +	buf_state = VB2_BUF_STATE_DONE;
> > +	v4l2_m2m_buf_done(src_buf, buf_state);
> > +	v4l2_m2m_buf_done(dst_buf, buf_state);
> > +	v4l2_m2m_job_finish(master_jpeg->m2m_dev, ctx->fh.m2m_ctx);
> > +	pm_runtime_put(ctx->jpeg->dev);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int mtk_jpegenc_hw_init_irq(struct mtk_jpegenc_comp_dev
> > *dev)
> > +{
> > +	struct platform_device *pdev = dev->plat_dev;
> > +	int ret;
> > +
> > +	dev->jpegenc_irq = platform_get_irq(pdev, 0);
> > +	if (dev->jpegenc_irq < 0) {
> > +		dev_err(&pdev->dev, "Failed to get irq resource");
> > +		return dev->jpegenc_irq;
> > +	}
> > +
> 
> Have you tried with a threaded_irq?
> > +	ret = devm_request_irq(&pdev->dev, dev->jpegenc_irq,
> > +		mtk_jpegenc_hw_irq_handler, 0, pdev->name, dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to devm_request_irq %d
> > (%d)",
> > +			dev->jpegenc_irq, ret);
> > +		return -ENOENT;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +int mtk_jpegenc_init_pm(struct mtk_jpegenc_comp_dev *mtkdev)
> > +{
> > +	struct mtk_jpegenc_clk_info *clk_info;
> > +	struct mtk_jpegenc_clk *jpegenc_clk;
> > +	struct platform_device *pdev;
> > +	struct mtk_jpegenc_pm *pm;
> > +	int i, ret;
> > +
> > +	pdev = mtkdev->plat_dev;
> > +	pm = &mtkdev->pm;
> > +	pm->dev = &pdev->dev;
> > +	pm->mtkdev = mtkdev;
> 
> Can't you simplify with devm_clk_bulk_get_all
It would fixed in the next code version.
thanks.
> > +	jpegenc_clk = &pm->venc_clk;
> > +	jpegenc_clk->clk_num =
> > +		of_property_count_strings(pdev->dev.of_node, "clock-
> > names");
> > +	if (!jpegenc_clk->clk_num) {
> > +		dev_err(&pdev->dev, "Failed to get jpegenc clock
> > count\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	jpegenc_clk->clk_info = devm_kcalloc(&pdev->dev,
> > +		jpegenc_clk->clk_num,
> > +		sizeof(*clk_info),
> > +		GFP_KERNEL);
> > +	if (!jpegenc_clk->clk_info)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < jpegenc_clk->clk_num; i++) {
> > +		clk_info = &jpegenc_clk->clk_info[i];
> > +		ret = of_property_read_string_index(pdev->dev.of_node,
> > +			"clock-names", i,
> > +			&clk_info->clk_name);
> > +		if (ret) {
> > +			dev_err(&pdev->dev, "Failed to get jpegenc
> > clock name\n");
> > +			return ret;
> > +		}
> > +
> > +		clk_info->jpegenc_clk = devm_clk_get(&pdev->dev,
> > +			clk_info->clk_name);
> > +		if (IS_ERR(clk_info->jpegenc_clk)) {
> > +			dev_err(&pdev->dev, "devm_clk_get (%d)%s fail",
> > +				i, clk_info->clk_name);
> > +			return PTR_ERR(clk_info->jpegenc_clk);
> > +		}
> > +	}
> > +
> 
> Can't you enable the pm after all the probing is completed to
> simplify
> the error handling?
It would fixed in the next code version.
thanks.
> > +	pm_runtime_enable(&pdev->dev);
> > +
> > +	return ret;
> > +}
> > +
> > +void mtk_jpegenc_release_pm(struct mtk_jpegenc_comp_dev *mtkdev)
> > +{
> > +	struct platform_device *pdev = mtkdev->plat_dev;
> > +
> > +	pm_runtime_disable(&pdev->dev);
> > +}
> > +
> > +static int mtk_jpegenc_hw_probe(struct platform_device *pdev)
> > +{
> > +	struct mtk_jpeg_dev *master_dev;
> > +	const struct of_device_id *of_id;
> > +	struct mtk_jpegenc_comp_dev *dev;
> > +	int ret, comp_idx;
> > +
> > +	struct device *decs = &pdev->dev;
> > +
> 
> When is the parent NULL?
parent delegates the master_dev, if mtk_jpeg_probe is called after
mtk_jpegenc_hw_probe, the parent is NULL. If return -EPROBE_DEFER,
the system will call mtk_jpegenc_hw_probe later.
> > +	if (!decs->parent)
> > +		return -EPROBE_DEFER;
> > +
> > +	master_dev = dev_get_drvdata(decs->parent);
> > +	if (!master_dev)
> > +		return -EPROBE_DEFER;
> > +
> > +	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
> > +	if (!dev)
> > +		return -ENOMEM;
> > +
> > +	dev->plat_dev = pdev;
> > +
> > +	ret = mtk_jpegenc_init_pm(dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to get jpeg enc clock
> > source");
> > +		return ret;
> > +	}
> > +
> > +	dev->reg_base =
> > +		devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(dev->reg_base)) {
> > +		ret = PTR_ERR(dev->reg_base);
> > +		goto err;
> > +	}
> > +
> > +	ret = mtk_jpegenc_hw_init_irq(dev);
> > +	if (ret) {
> > +		dev_err(&pdev->dev, "Failed to register JPEGENC irq
> > handler.\n");
> > +		goto err;
> > +	}
> > +
> 
> please use of_device_get_match_data()
It would fixed in the next code version.
thanks.
> > +	of_id = of_match_device(mtk_jpegenc_drv_ids, decs);
> > +	if (!of_id) {
> > +		dev_err(&pdev->dev, "Can't get vdec comp device
> > id.\n");
> > +		ret = -EINVAL;
> > +		goto err;
> > +	}
> > +
> 
> What if the drvdata is freed before you set it?
I will supply a device tree to explain it in the next version.
thanks.
> > +	comp_idx = (enum mtk_jpegenc_hw_id)of_id->data;
> > +	if (comp_idx < MTK_JPEGENC_HW_MAX) {
> > +		master_dev->enc_hw_dev[comp_idx] = dev;
> > +		master_dev->reg_encbase[comp_idx] = dev->reg_base;
> > +		dev->master_dev = master_dev;
> > +	}
> > +
> > +	platform_set_drvdata(pdev, dev);
> > +
> > +	return 0;
> > +
> > +err:
> > +	mtk_jpegenc_release_pm(dev);
> > +	return ret;
> > +}
> > +
> > +
> > +static int mtk_jpegenc_remove(struct platform_device *pdev)
> > +{
> > +	struct mtk_jpegenc_comp_dev *dev = platform_get_drvdata(pdev);
> > +
> > +	mtk_jpegenc_release_pm(dev);
> > +
> > +	return 0;
> > +}
> > +
> > +struct platform_driver mtk_jpegenc_hw_driver = {
> > +	.probe = mtk_jpegenc_hw_probe,
> > +	.remove = mtk_jpegenc_remove,
> > +	.driver = {
> > +		.name = "mtk-jpegenc-hw",
> > +		.of_match_table = of_match_ptr(mtk_jpegenc_drv_ids),
> > +	},
> > +};
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 

From kyrie.wu at mediatek.com  Wed Jan  5 23:57:08 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 15:57:08 +0800
Subject: [PATCH V6, 3/5] media: mtk-jpegenc: add jpegenc timeout func
 interface
In-Reply-To: <YaoyuAFD8IaSij6S@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <1638501230-13417-4-git-send-email-kyrie.wu@mediatek.com>
 <YaoyuAFD8IaSij6S@gmail.com>
Message-ID: <6d4444930aba035e2653d45d606c2e0878ab95ea.camel@mediatek.com>

On Fri, 2021-12-03 at 16:07 +0100, Ricardo Ribalda wrote:
> kyrie.wu wrote:
> 
> > Generalizes jpegenc timeout func interfaces to handle HW timeout.
> 
> Where do you call schedule_delayed_work() and init hw_param?
the work of call schedule_delayed_work() and init hw_param would
execute in the function of mtk_jpegenc_worker in [PATCH V6, 4/5]
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> > V6: no change
> > ---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h   |  8 ++++++++
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 23
> > +++++++++++++++++++++++
> >  2 files changed, 31 insertions(+)
> > 
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > index 7d013de..baab305 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > @@ -75,6 +75,12 @@ struct mtk_jpeg_variant {
> >  	u32 cap_q_default_fourcc;
> >  };
> >  
> > +struct mtk_jpeg_hw_param {
> > +	struct vb2_v4l2_buffer *src_buffer;
> > +	struct vb2_v4l2_buffer *dst_buffer;
> > +	struct mtk_jpeg_ctx *curr_ctx;
> > +};
> > +
> >  enum mtk_jpegenc_hw_id {
> >  	MTK_JPEGENC_HW0,
> >  	MTK_JPEGENC_HW1,
> > @@ -122,6 +128,8 @@ struct mtk_jpegenc_comp_dev {
> >  	struct mtk_jpeg_dev *master_dev;
> >  	struct mtk_jpegenc_pm pm;
> >  	int jpegenc_irq;
> > +	struct delayed_work job_timeout_work;
> > +	struct mtk_jpeg_hw_param hw_param;
> >  };
> >  
> >  /**
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > index 4ccda1d..e62b875 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > @@ -183,6 +183,24 @@ void mtk_jpeg_set_enc_params(struct
> > mtk_jpeg_ctx *ctx,  void __iomem *base)
> >  	writel(ctx->restart_interval, base + JPEG_ENC_RST_MCU_NUM);
> >  }
> >  
> > +static void mtk_jpegenc_timeout_work(struct work_struct *work)
> > +{
> > +	struct delayed_work *Pwork =
> > +		container_of(work, struct delayed_work, work);
> 
> Please use to_delayed_work()
It would be fixed in the next code version.
Thanks.
> > +	struct mtk_jpegenc_comp_dev *cjpeg =
> > +		container_of(Pwork, struct mtk_jpegenc_comp_dev,
> > +		job_timeout_work);
> > +	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
> > +	struct vb2_v4l2_buffer *src_buf;
> > +
> > +	src_buf = cjpeg->hw_param.src_buffer;
> > +
> > +	mtk_jpeg_enc_reset(cjpeg->reg_base);
> > +	clk_disable_unprepare(cjpeg->pm.venc_clk.clk_info-
> > >jpegenc_clk);
> > +	pm_runtime_put(cjpeg->pm.dev);
> > +	v4l2_m2m_buf_done(src_buf, buf_state);
> > +}
> > +
> >  static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> >  {
> >  	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > @@ -194,6 +212,8 @@ static irqreturn_t
> > mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> >  	struct mtk_jpegenc_comp_dev *jpeg = priv;
> >  	struct mtk_jpeg_dev *master_jpeg = jpeg->master_dev;
> >  
> > +	cancel_delayed_work(&jpeg->job_timeout_work);
> 
> Isn't here a race condition is the delayed work is being exectuted?
If hw worked beyond 1 second, the delayed work is called. This setting 
is shown in the function of mtk_jpegenc_worker in [PATCH V6, 4/5].
> > +
> >  	irq_status = readl(jpeg->reg_base + JPEG_ENC_INT_STS) &
> >  		JPEG_ENC_INT_STATUS_MASK_ALLIRQ;
> >  	if (irq_status)
> > @@ -322,6 +342,9 @@ static int mtk_jpegenc_hw_probe(struct
> > platform_device *pdev)
> >  
> >  	dev->plat_dev = pdev;
> >  
> > +	INIT_DELAYED_WORK(&dev->job_timeout_work,
> > +		mtk_jpegenc_timeout_work);
> > +
> >  	ret = mtk_jpegenc_init_pm(dev);
> >  	if (ret) {
> >  		dev_err(&pdev->dev, "Failed to get jpeg enc clock
> > source");
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 

From kyrie.wu at mediatek.com  Thu Jan  6 00:03:35 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 16:03:35 +0800
Subject: [PATCH V6, 4/5] media: mtk-jpegenc: add jpeg encode worker
 interface
In-Reply-To: <Yao3z6PZ72Vpr7B0@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <1638501230-13417-5-git-send-email-kyrie.wu@mediatek.com>
 <Yao3z6PZ72Vpr7B0@gmail.com>
Message-ID: <7d1353c3c5e8d621b94341a736a4a781559b69ee.camel@mediatek.com>

On Fri, 2021-12-03 at 16:29 +0100, Ricardo Ribalda wrote:
> kyrie.wu wrote:
> 
> > Add jpeg encoding worker to ensure that two HWs
> > run in parallel in MT8195.
> 
> Have you considered using a semaphore initialized to two to arbitrate
> this?
I will consider your suggestion. Thanks.
> 
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> > V6: no change
> > ---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c   | 180
> > +++++++++++++++++++---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h   |  11 ++
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c |  17 ++
> >  3 files changed, 188 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > index da7eb84..80a6c1a 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > @@ -110,6 +110,9 @@ struct mtk_jpeg_src_buf {
> >  	struct vb2_v4l2_buffer b;
> >  	struct list_head list;
> >  	struct mtk_jpeg_dec_param dec_param;
> > +
> > +	struct mtk_jpeg_ctx *curr_ctx;
> > +	u32 frame_num;
> >  };
> >  
> >  static int debug;
> > @@ -908,38 +911,148 @@ static int mtk_jpeg_set_dec_dst(struct
> > mtk_jpeg_ctx *ctx,
> >  	return 0;
> >  }
> >  
> > -static void mtk_jpeg_enc_device_run(void *priv)
> > +static int mtk_jpegenc_select_hw(struct mtk_jpeg_ctx *ctx)
> >  {
> > -	struct mtk_jpeg_ctx *ctx = priv;
> > +	struct mtk_jpegenc_comp_dev *comp_jpeg;
> >  	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
> > -	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > +	unsigned long flags;
> > +	int hw_id = -1;
> > +	int i;
> > +
> > +	spin_lock_irqsave(&jpeg->hw_lock, flags);
> > +	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
> > +		comp_jpeg = jpeg->enc_hw_dev[i];
> > +		if (comp_jpeg->hw_state == MTK_JPEG_HW_IDLE) {
> > +			hw_id = i;
> > +			comp_jpeg->hw_state = MTK_JPEG_HW_BUSY;
> > +			break;
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
> > +
> > +	return hw_id;
> > +}
> > +
> > +static int mtk_jpegenc_set_hw_param(struct mtk_jpeg_ctx *ctx,
> > +	int hw_id,
> > +	struct vb2_v4l2_buffer *src_buf,
> > +	struct vb2_v4l2_buffer *dst_buf)
> > +{
> > +	struct mtk_jpegenc_comp_dev *jpeg = ctx->jpeg-
> > >enc_hw_dev[hw_id];
> > +
> > +	jpeg->hw_param.curr_ctx = ctx;
> > +	jpeg->hw_param.src_buffer = src_buf;
> > +	jpeg->hw_param.dst_buffer = dst_buf;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_jpegenc_deselect_hw(struct mtk_jpeg_dev *jpeg,
> > +	int hw_id)
> > +{
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&jpeg->hw_lock, flags);
> > +	jpeg->enc_hw_dev[hw_id]->hw_state = MTK_JPEG_HW_IDLE;
> > +	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
> > +
> > +	return 0;
> > +}
> > +
> > +static void mtk_jpegenc_worker(struct work_struct *work)
> > +{
> > +	struct mtk_jpegenc_comp_dev *comp_jpeg[MTK_JPEGENC_HW_MAX];
> >  	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
> > +	struct mtk_jpeg_src_buf *jpeg_src_buf, *jpeg_dst_buf;
> > +	struct vb2_v4l2_buffer *src_buf, *dst_buf;
> > +	atomic_t *hw_rdy[MTK_JPEGENC_HW_MAX];
> > +	struct clk *jpegenc_clk;
> > +	int ret, i, hw_id = 0;
> >  	unsigned long flags;
> > -	int ret;
> >  
> > +	struct mtk_jpeg_ctx *ctx = container_of(work,
> > +		struct mtk_jpeg_ctx,
> > +		jpeg_work);
> > +	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
> > +
> > +	for (i = 0; i < MTK_JPEGENC_HW_MAX; i++) {
> > +		comp_jpeg[i] = jpeg->enc_hw_dev[i];
> > +		hw_rdy[i] = &comp_jpeg[i]->hw_rdy;
> > +	}
> > +
> > +retry_select:
> > +	hw_id = mtk_jpegenc_select_hw(ctx);
> > +	if (hw_id < 0) {
> > +		ret = wait_event_interruptible(jpeg->enc_hw_wq,
> > +			(atomic_read(hw_rdy[0]) ||
> > +			atomic_read(hw_rdy[1])) > 0);
> > +		if (ret != 0) {
> > +			dev_err(jpeg->dev, "%s : %d, all HW are
> > busy\n",
> > +				__func__, __LINE__);
> > +			v4l2_m2m_job_finish(jpeg->m2m_dev, ctx-
> > >fh.m2m_ctx);
> > +			return;
> > +		}
> > +
> > +		goto retry_select;
> > +	}
> > +
> > +	atomic_dec(&comp_jpeg[hw_id]->hw_rdy);
> >  	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
> > +	if (!src_buf) {
> > +		dev_err(jpeg->dev, "%s : %d, get src_buf fail !!!\n",
> > +			__func__, __LINE__);
> > +		goto getbuf_fail;
> > +	}
> > +
> >  	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
> > +	if (!dst_buf) {
> > +		pr_info("%s : %d, get dst_buf fail !!!\n",
> > +			__func__, __LINE__);
> > +		goto getbuf_fail;
> > +	}
> >  
> > -	ret = pm_runtime_resume_and_get(jpeg->dev);
> > -	if (ret < 0)
> > -		goto enc_end;
> > +	jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf);
> > +	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
> > +	jpeg_src_buf->curr_ctx = ctx;
> > +	jpeg_src_buf->frame_num = ctx->total_frame_num;
> > +	jpeg_dst_buf->curr_ctx = ctx;
> > +	jpeg_dst_buf->frame_num = ctx->total_frame_num;
> > +	ctx->total_frame_num++;
> >  
> > -	schedule_delayed_work(&jpeg->job_timeout_work,
> > -			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC
> > ));
> > +	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
> > +	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> > +	mtk_jpegenc_set_hw_param(ctx, hw_id, src_buf, dst_buf);
> > +	ret = pm_runtime_get_sync(comp_jpeg[hw_id]->pm.dev);
> > +	if (ret < 0) {
> > +		dev_err(jpeg->dev, "%s : %d, pm_runtime_get_sync fail
> > !!!\n",
> > +			__func__, __LINE__);
> > +		goto enc_end;
> > +	}
> >  
> > -	spin_lock_irqsave(&jpeg->hw_lock, flags);
> > +	jpegenc_clk = comp_jpeg[hw_id]->pm.venc_clk.clk_info-
> > >jpegenc_clk;
> > +	ret = clk_prepare_enable(jpegenc_clk);
> > +	if (ret) {
> > +		dev_err(jpeg->dev, "%s : %d, jpegenc clk_prepare_enable
> > fail\n",
> > +			__func__, __LINE__);
> > +		goto enc_end;
> > +	}
> >  
> > -	/*
> > -	 * Resetting the hardware every frame is to ensure that all the
> > -	 * registers are cleared. This is a hardware requirement.
> > -	 */
> > -	mtk_jpeg_enc_reset(jpeg->reg_base);
> > +	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
> > +		msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
> > +
> > +	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
> > +	mtk_jpeg_enc_reset(comp_jpeg[hw_id]->reg_base);
> > +	mtk_jpeg_set_enc_dst(ctx,
> > +		comp_jpeg[hw_id]->reg_base,
> > +		&dst_buf->vb2_buf);
> > +	mtk_jpeg_set_enc_src(ctx,
> > +		comp_jpeg[hw_id]->reg_base,
> > +		&src_buf->vb2_buf);
> > +	mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base);
> > +	mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base);
> > +	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
> > +	spin_unlock_irqrestore(&comp_jpeg[hw_id]->hw_lock, flags);
> >  
> > -	mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf);
> > -	mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf);
> > -	mtk_jpeg_set_enc_params(ctx, jpeg->reg_base);
> > -	mtk_jpeg_enc_start(jpeg->reg_base);
> > -	spin_unlock_irqrestore(&jpeg->hw_lock, flags);
> >  	return;
> >  
> >  enc_end:
> > @@ -947,9 +1060,20 @@ static void mtk_jpeg_enc_device_run(void
> > *priv)
> >  	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
> >  	v4l2_m2m_buf_done(src_buf, buf_state);
> >  	v4l2_m2m_buf_done(dst_buf, buf_state);
> > +getbuf_fail:
> > +	atomic_inc(&comp_jpeg[hw_id]->hw_rdy);
> > +	mtk_jpegenc_deselect_hw(jpeg, hw_id);
> >  	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
> >  }
> >  
> > +static void mtk_jpeg_enc_device_run(void *priv)
> > +{
> > +	struct mtk_jpeg_ctx *ctx = priv;
> > +	struct mtk_jpeg_dev *jpeg = ctx->jpeg;
> 
> You are reusing the jpeg_work structure, so if you call multiple
> times
> mtk_jpeg_enc_device_run(), before the old one is completed, you would
> overwrite the old values. Is this what you want?
queue_work only queue jpeg_work to workqueue, and the worker function
will schedule to encode.The encode source data is set in output buffer,
and it would not overwrite.
> > +
> > +	queue_work(jpeg->workqueue, &ctx->jpeg_work);
> > +}
> > +
> >  static void mtk_jpeg_dec_device_run(void *priv)
> >  {
> >  	struct mtk_jpeg_ctx *ctx = priv;
> > @@ -1217,6 +1341,9 @@ static int mtk_jpeg_open(struct file *file)
> >  		goto free;
> >  	}
> >  
> > +	if (jpeg->variant->is_encoder)
> > +		INIT_WORK(&ctx->jpeg_work, mtk_jpegenc_worker);
> > +
> >  	v4l2_fh_init(&ctx->fh, vfd);
> >  	file->private_data = &ctx->fh;
> >  	v4l2_fh_add(&ctx->fh);
> > @@ -1387,6 +1514,15 @@ static int mtk_jpeg_probe(struct
> > platform_device *pdev)
> >  		}
> >  
> >  		pm_runtime_enable(&pdev->dev);
> > +	} else {
> > +		init_waitqueue_head(&jpeg->enc_hw_wq);
> > +		jpeg->workqueue =
> > alloc_ordered_workqueue(MTK_JPEG_NAME,
> > +			WQ_MEM_RECLAIM | WQ_FREEZABLE);
> > +		if (!jpeg->workqueue) {
> > +			dev_err(&pdev->dev, "Failed to create jpeg
> > workqueue!\n");
> > +			ret = -EINVAL;
> > +			goto err_alloc_workqueue;
> > +		}
> >  	}
> >  
> >  	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
> > @@ -1460,6 +1596,8 @@ static int mtk_jpeg_probe(struct
> > platform_device *pdev)
> >  
> >  err_clk_init:
> >  
> > +err_alloc_workqueue:
> > +
> >  err_req_irq:
> >  
> >  	return ret;
> > @@ -1475,6 +1613,8 @@ static int mtk_jpeg_remove(struct
> > platform_device *pdev)
> >  	v4l2_m2m_release(jpeg->m2m_dev);
> >  	v4l2_device_unregister(&jpeg->v4l2_dev);
> >  	mtk_jpeg_clk_release(jpeg);
> > +	flush_workqueue(jpeg->workqueue);
> > +	destroy_workqueue(jpeg->workqueue);
> >  
> >  	return 0;
> >  }
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > index baab305..4c669af 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > @@ -75,6 +75,11 @@ struct mtk_jpeg_variant {
> >  	u32 cap_q_default_fourcc;
> >  };
> >  
> > +enum mtk_jpeg_hw_state {
> > +	MTK_JPEG_HW_IDLE = 0,
> > +	MTK_JPEG_HW_BUSY = 1,
> > +};
> > +
> >  struct mtk_jpeg_hw_param {
> >  	struct vb2_v4l2_buffer *src_buffer;
> >  	struct vb2_v4l2_buffer *dst_buffer;
> > @@ -130,6 +135,9 @@ struct mtk_jpegenc_comp_dev {
> >  	int jpegenc_irq;
> >  	struct delayed_work job_timeout_work;
> >  	struct mtk_jpeg_hw_param hw_param;
> > +	atomic_t hw_rdy;
> > +	enum mtk_jpeg_hw_state hw_state;
> > +	spinlock_t hw_lock;
> >  };
> >  
> >  /**
> > @@ -163,6 +171,7 @@ struct mtk_jpeg_dev {
> >  
> >  	void __iomem *reg_encbase[MTK_JPEGENC_HW_MAX];
> >  	struct mtk_jpegenc_comp_dev *enc_hw_dev[MTK_JPEGENC_HW_MAX];
> > +	wait_queue_head_t enc_hw_wq;
> >  };
> >  
> >  /**
> > @@ -221,6 +230,8 @@ struct mtk_jpeg_ctx {
> >  	u8 enc_quality;
> >  	u8 restart_interval;
> >  	struct v4l2_ctrl_handler ctrl_hdl;
> > +	struct work_struct jpeg_work;
> > +	u32 total_frame_num;
> >  };
> >  
> >  extern struct platform_driver mtk_jpegenc_hw_driver;
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > index e62b875..244f9f7 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > @@ -190,6 +190,7 @@ static void mtk_jpegenc_timeout_work(struct
> > work_struct *work)
> >  	struct mtk_jpegenc_comp_dev *cjpeg =
> >  		container_of(Pwork, struct mtk_jpegenc_comp_dev,
> >  		job_timeout_work);
> > +	struct mtk_jpeg_dev *master_jpeg = cjpeg->master_dev;
> >  	enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR;
> >  	struct vb2_v4l2_buffer *src_buf;
> >  
> > @@ -198,6 +199,9 @@ static void mtk_jpegenc_timeout_work(struct
> > work_struct *work)
> >  	mtk_jpeg_enc_reset(cjpeg->reg_base);
> >  	clk_disable_unprepare(cjpeg->pm.venc_clk.clk_info-
> > >jpegenc_clk);
> >  	pm_runtime_put(cjpeg->pm.dev);
> > +	cjpeg->hw_state = MTK_JPEG_HW_IDLE;
> > +	atomic_inc(&cjpeg->hw_rdy);
> > +	wake_up(&master_jpeg->enc_hw_wq);
> >  	v4l2_m2m_buf_done(src_buf, buf_state);
> >  }
> >  
> > @@ -235,7 +239,17 @@ static irqreturn_t
> > mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> >  	v4l2_m2m_buf_done(src_buf, buf_state);
> >  	v4l2_m2m_buf_done(dst_buf, buf_state);
> >  	v4l2_m2m_job_finish(master_jpeg->m2m_dev, ctx->fh.m2m_ctx);
> > +	clk_disable_unprepare(jpeg->pm.venc_clk.clk_info->jpegenc_clk);
> >  	pm_runtime_put(ctx->jpeg->dev);
> > +	if (ctx->fh.m2m_ctx &&
> > +		(!list_empty(&ctx->fh.m2m_ctx->out_q_ctx.rdy_queue) ||
> > +		!list_empty(&ctx->fh.m2m_ctx->cap_q_ctx.rdy_queue))) {
> > +		queue_work(master_jpeg->workqueue, &ctx->jpeg_work);
> > +	}
> > +
> > +	jpeg->hw_state = MTK_JPEG_HW_IDLE;
> > +	wake_up(&master_jpeg->enc_hw_wq);
> > +	atomic_inc(&jpeg->hw_rdy);
> >  
> >  	return IRQ_HANDLED;
> >  }
> > @@ -341,6 +355,9 @@ static int mtk_jpegenc_hw_probe(struct
> > platform_device *pdev)
> >  		return -ENOMEM;
> >  
> >  	dev->plat_dev = pdev;
> > +	atomic_set(&dev->hw_rdy, 1U);
> > +	spin_lock_init(&dev->hw_lock);
> > +	dev->hw_state = MTK_JPEG_HW_IDLE;
> >  
> >  	INIT_DELAYED_WORK(&dev->job_timeout_work,
> >  		mtk_jpegenc_timeout_work);
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> > 

From kyrie.wu at mediatek.com  Thu Jan  6 00:04:48 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 16:04:48 +0800
Subject: [PATCH V6, 0/5] Support multi-hardware jpeg encoding using
 of_platform_populate
In-Reply-To: <Yaod22NaGQveuevu@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <Yaod22NaGQveuevu@gmail.com>
Message-ID: <61a813f02d90829c4df47d9ca7f26553e2b3deb3.camel@mediatek.com>

On Fri, 2021-12-03 at 14:38 +0100, Ricardo Ribalda wrote:
> Hi
> 
> Any idea why this series is not available at
> https://patchwork.linuxtv.org/ but it exists in 
> 
https://lore.kernel.org/all/1638501230-13417-1-git-send-email-kyrie.wu at mediatek.com/#r
> 
> thanks!
I will fix this issue in the next code version, thanks.
> 
> kyrie.wu wrote:
> 
> > This series adds support for multi hardware jpeg encoding, by first
> > adding use of_platform_populate to manage each hardware
> > information:
> > interrupt, clock, register bases and power. Secondly add encoding 
> > work queue to deal with the encoding requestsof multi-hardware
> > at the same time. Lastly, add output picture reorder function
> > interface to eliminate the out of order images.
> > 
> > This series has been tested with both MT8195.
> > Encoding worked for this chip.
> > 
> > Patches 1~2 use of_platform_populate to replace component framework
> > to manage multi-hardware.
> > 
> > Patch 3 add jpeg encoding timeout function to judge hardware
> > timeout.
> > 
> > Patch 4 add encoding work queue to deal with multi-hardware
> > encoding
> > at the same time.
> > 
> > Patch 5 add output picture reorder function to order images.
> > ---
> > Changes compared with v5:
> > - use of_platform_populate to replace component framework to
> > manage multi-hardware in patch 2.
> > 
> > Changes compared with v4:
> > --No change compaered with v4
> > 
> > Changes compared with v3:
> > --Structure patches for consistency, non-backward
> >   compatible and do not break any existing functionality
> > 
> > Changes compared with v2:
> > --Split the last two patches into several patches
> >   to enhance readability
> > --Correct some syntax errors
> > --Explain why the component framework is used
> > 
> > Changes compared with v1:
> > --Add jpeg encoder dt-bindings for MT8195
> > --Use component framework to manage jpegenc HW
> > --Add jpegenc output pic reorder function interface
> > 
> > kyrie.wu (5):
> >   dt-bindings: mediatek: Add mediatek, mt8195-jpgenc compatible
> >   media: mtk-jpegenc: manage jpegenc multi-hardware
> >   media: mtk-jpegenc: add jpegenc timeout func interface
> >   media: mtk-jpegenc: add jpeg encode worker interface
> >   media: mtk-jpegenc: add output pic reorder interface
> > 
> >  .../bindings/media/mediatek-jpeg-encoder.yaml      |   3 +
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c    | 287
> > +++++++++++++++----
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h    |  91 +++++-
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c  |   1 +
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h  |   3 +-
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c  | 316
> > ++++++++++++++++++++-
> >  6 files changed, 644 insertions(+), 57 deletions(-)
> > 
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 

From kyrie.wu at mediatek.com  Thu Jan  6 00:06:14 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 16:06:14 +0800
Subject: [PATCH V6, 1/5] dt-bindings: mediatek: Add mediatek,
 mt8195-jpgenc compatible
In-Reply-To: <Yaoe/Tk1wMyFoB1s@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <1638501230-13417-2-git-send-email-kyrie.wu@mediatek.com>
 <Yaoe/Tk1wMyFoB1s@gmail.com>
Message-ID: <b5a9c481f8ed42b2d8bd04ca8b727627d4a3a15a.camel@mediatek.com>

On Fri, 2021-12-03 at 14:43 +0100, Ricardo Ribalda wrote:
> kyrie.wu wrote:
> 
> > Add mediatek, mt8195-jpgenc compatible to binding document
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> > V6: no change
> 
> Hi Kyrie
> 
> Your patch does not seem to apply on top of linus or linus/next.
> 
> In linus/next they still have the .txt file:
> 
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt?id=7afeac307a9561e3a93682c1e7eb22f918aa1187
> 
> What are you using?
> 
> Thanks
I will fix this issue in the next code version, thanks.
> 
> 
> > ---
> >  Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml 
> > | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-
> > encoder.yaml b/Documentation/devicetree/bindings/media/mediatek-
> > jpeg-encoder.yaml
> > index fcd9b82..e93ccf5 100644
> > --- a/Documentation/devicetree/bindings/media/mediatek-jpeg-
> > encoder.yaml
> > +++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-
> > encoder.yaml
> > @@ -18,6 +18,9 @@ properties:
> >        - enum:
> >            - mediatek,mt2701-jpgenc
> >            - mediatek,mt8183-jpgenc
> > +          - mediatek,mt8195-jpgenc
> > +          - mediatek,mt8195-jpgenc0
> > +          - mediatek,mt8195-jpgenc1
> >        - const: mediatek,mtk-jpgenc
> >    reg:
> >      maxItems: 1
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 

From miquel.raynal at bootlin.com  Thu Jan  6 00:08:32 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:08:32 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106032504.23310-1-liang.yang@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
Message-ID: <20220106090832.42225c49@xps13>

Hi Liang,

liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:

> Because EMMC and NAND have the same control clock register, so we
> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
> 
> 	sd_emmc_c_clkc: mmc at 7000 {
> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> 		reg = <0x0 0x7000 0x0 0x800>;
> 	};
> 
> 	nand-controller at 7800 {
> 		......
> 
> 		clocks = <&clkc CLKID_SD_EMMC_C>,
> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> 		clock-names = "core", "device", "rx", "tx";
> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> 
> 		......
> 	}
> 
> but in fact, above implementation is rejected. so now registering
> a nand_divider.

What is rejected?
Why is it rejected?
What is nand_divider?


> 
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997

Change Ids are not expected in the upstream kernel.

But if you fix something you should have a Fixes:.

> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>  1 file changed, 49 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..4472363059c2 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.
>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -55,6 +56,7 @@
>  #define NFC_REG_VER		0x38
>  
>  #define NFC_RB_IRQ_EN		BIT(21)
> +#define NFC_CMD_FIFO_RESET	BIT(31)
>  
>  #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>  	(								\
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,15 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;
> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
>  	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	void __iomem *reg_clk;
>  	struct completion completion;
>  	struct list_head chips;
>  	const struct meson_nfc_data *data;
> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>  	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>  		| nfc->param.chip_select | nfc->timing.tbers_max;
>  	writel(cmd, nfc->reg_base + NFC_REG_CMD);
> -
> +	meson_nfc_drain_cmd(nfc);
>  	ret = wait_for_completion_timeout(&nfc->completion,
>  					  msecs_to_jiffies(timeout_ms));
>  	if (ret == 0)
>  		ret = -1;
>  
> +	/* reset command fifo to avoid lock */
> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>  	return ret;
>  }
>  
> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>  static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  {
>  	int ret;
> +	struct clk_init_data init = {0};
> +	const char *fix_div2_pll_name[1];
>  
> -	/* request core clock */
>  	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>  	if (IS_ERR(nfc->core_clk)) {
>  		dev_err(nfc->dev, "failed to get core clock\n");
> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		return PTR_ERR(nfc->device_clk);
>  	}
>  
> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
> -	if (IS_ERR(nfc->phase_tx)) {
> -		dev_err(nfc->dev, "failed to get TX clk\n");
> -		return PTR_ERR(nfc->phase_tx);
> -	}
> -
> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
> -	if (IS_ERR(nfc->phase_rx)) {
> -		dev_err(nfc->dev, "failed to get RX clk\n");
> -		return PTR_ERR(nfc->phase_rx);
> -	}
> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
> +	init.ops = &clk_divider_ops;
> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
> +	init.parent_names = fix_div2_pll_name;
> +	init.num_parents = 1;
> +	nfc->nand_divider.reg = nfc->reg_clk;
> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
> +	nfc->nand_divider.hw.init = &init;
> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
> +				  CLK_DIVIDER_ROUND_CLOSEST |
> +          			  CLK_DIVIDER_ALLOW_ZERO;
> +
> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
> +	if (IS_ERR(nfc->nand_clk))
> +		return PTR_ERR(nfc->nand_clk);
>  
>  	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
> -	regmap_update_bits(nfc->reg_clk,
> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>  
>  	ret = clk_prepare_enable(nfc->core_clk);
>  	if (ret) {
> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		goto err_device_clk;
>  	}
>  
> -	ret = clk_prepare_enable(nfc->phase_tx);
> +	ret = clk_prepare_enable(nfc->nand_clk);
>  	if (ret) {
> -		dev_err(nfc->dev, "failed to enable TX clock\n");
> -		goto err_phase_tx;
> -	}
> -
> -	ret = clk_prepare_enable(nfc->phase_rx);
> -	if (ret) {
> -		dev_err(nfc->dev, "failed to enable RX clock\n");
> -		goto err_phase_rx;
> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
> +		goto err_nand_clk;
>  	}
>  
>  	ret = clk_set_rate(nfc->device_clk, 24000000);
>  	if (ret)
> -		goto err_disable_rx;
> +		goto err_disable_clk;
>  
>  	return 0;
>  
> -err_disable_rx:
> -	clk_disable_unprepare(nfc->phase_rx);
> -err_phase_rx:
> -	clk_disable_unprepare(nfc->phase_tx);
> -err_phase_tx:
> +err_disable_clk:
> +	clk_disable_unprepare(nfc->nand_clk);
> +err_nand_clk:
>  	clk_disable_unprepare(nfc->device_clk);
>  err_device_clk:
>  	clk_disable_unprepare(nfc->core_clk);
> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  
>  static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>  {
> -	clk_disable_unprepare(nfc->phase_rx);
> -	clk_disable_unprepare(nfc->phase_tx);
> +	clk_disable_unprepare(nfc->nand_clk);
>  	clk_disable_unprepare(nfc->device_clk);
>  	clk_disable_unprepare(nfc->core_clk);
>  }
> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct meson_nfc *nfc;
>  	struct resource *res;
> +	u32 ext_clk_reg;
>  	int ret, irq;
>  
>  	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	if (IS_ERR(nfc->reg_base))
>  		return PTR_ERR(nfc->reg_base);
>  
> -	nfc->reg_clk =
> -		syscon_regmap_lookup_by_phandle(dev->of_node,
> -						"amlogic,mmc-syscon");
> +	ret = of_property_read_u32(pdev->dev.of_node,
> +				   "sd_emmc_c_clkc",
> +				   &ext_clk_reg);
> +	if (ret) {
> +		dev_err(dev, "failed to get NAND external clock register\n");
> +		return ret;
> +	}
> +
> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>  	if (IS_ERR(nfc->reg_clk)) {
>  		dev_err(dev, "Failed to lookup clock base\n");
>  		return PTR_ERR(nfc->reg_clk);


Thanks,
Miqu?l


From chunfeng.yun at mediatek.com  Thu Jan  6 00:08:20 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 16:08:20 +0800
Subject: [PATCH v2 3/5] phy: mediatek: add helpers to update bits of
 registers
In-Reply-To: <821f9e8b-cf35-2e53-e64f-c19e7bde957b@collabora.com>
References: <20211218082802.5256-1-chunfeng.yun@mediatek.com>
 <20211218082802.5256-3-chunfeng.yun@mediatek.com>
 <047803b9-d09f-d4f8-a674-317cc19dd055@collabora.com>
 <75b2773d1d170f42bae0774dbc58d1458cb25502.camel@mediatek.com>
 <821f9e8b-cf35-2e53-e64f-c19e7bde957b@collabora.com>
Message-ID: <f53b48c05d38c75c1e02ca5189ed19a36d13bd44.camel@mediatek.com>

On Mon, 2022-01-03 at 09:59 +0100, AngeloGioacchino Del Regno wrote:
> Il 30/12/21 03:06, Chunfeng Yun ha scritto:
> > On Fri, 2021-12-24 at 11:10 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Il 18/12/21 09:28, Chunfeng Yun ha scritto:
> > > > Add three helpers mtk_phy_clear/set/update_bits() for registers
> > > > operation
> > > > 
> > > > Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > > ---
> > > > v2: new patch, add register access helpers,
> > > >       Add updatel() macro suggested by Vinod, here add more
> > > > ones
> > > > instead.
> > > > ---
> > > >    drivers/phy/mediatek/phy-mtk-io.h | 38
> > > > +++++++++++++++++++++++++++++++
> > > >    1 file changed, 38 insertions(+)
> > > >    create mode 100644 drivers/phy/mediatek/phy-mtk-io.h
> > > > 
> > > > diff --git a/drivers/phy/mediatek/phy-mtk-io.h
> > > > b/drivers/phy/mediatek/phy-mtk-io.h
> > > > new file mode 100644
> > > > index 000000000000..500fcdab165d
> > > > --- /dev/null
> > > > +++ b/drivers/phy/mediatek/phy-mtk-io.h
> > > > @@ -0,0 +1,38 @@
> > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > +/*
> > > > + * Copyright (C) 2021 MediaTek Inc.
> > > > + *
> > > > + * Author: Chunfeng Yun <chunfeng.yun at mediatek.com>
> > > > + */
> > > > +
> > > > +#ifndef __PHY_MTK_H__
> > > > +#define __PHY_MTK_H__
> > > > +
> > > > +#include <linux/io.h>
> > > > +
> > > > +static inline void mtk_phy_clear_bits(void __iomem *reg, u32
> > > > bits)
> > > > +{
> > > > +	u32 tmp = readl(reg);
> > > > +
> > > > +	tmp &= ~bits;
> > > > +	writel(tmp, reg);
> > > > +}
> > > > +
> > > > +static inline void mtk_phy_set_bits(void __iomem *reg, u32
> > > > bits)
> > > > +{
> > > > +	u32 tmp = readl(reg);
> > > > +
> > > > +	tmp |= bits;
> > > > +	writel(tmp, reg);
> > > > +}
> > > > +
> > > > +static inline void mtk_phy_update_bits(void __iomem *reg, u32
> > > > mask, u32 val)
> > > > +{
> > > > +	u32 tmp = readl(reg);
> > > > +
> > > > +	tmp &= ~mask;
> > > > +	tmp |= val & mask;
> > > > +	writel(tmp, reg);
> > > > +}
> > > > +
> > > > +#endif
> > > > 
> > > 
> > > These helpers are almost exactly duplicating what
> > > regmap_update_bits() is doing.
> > > I appreciate the effort to stop open-coding the same sequences
> > > over
> > > and over by
> > > adding such helper functions,
> > 
> > I agree with you.
> > > but I think that the proper way of doing what you
> > > are proposing is not to add custom functions but rather reuse
> > > what
> > > the Linux APIs
> > > give you.
> > 
> > I also like to use common APIs ASAP, but not found suitable ones.
> > This may be a problem, I found that some similar custom helps
> > already
> > added under phy fold.
> > 
> > > 
> > > What about doing a conversion to use regmap on this driver?
> > 
> > No, we don't use regmap here, these registers are monopolized by t-
> > phy,
> > it's not syscon.
> > 
> > 
> 
> Hello,
> 
> The regmap API allows this kind of usage, registers don't necessarily
> have
> to be part of a syscon.
I'm sorry, I don't want to make it more complex

> 
> Regards,
> - Angelo

From miquel.raynal at bootlin.com  Thu Jan  6 00:12:09 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:12:09 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <20220106091209.6b97cf3c@xps13>

Hello,

liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:

This patch should be in a series with "mtd: rawnand: meson: fix the
clock after discarding sd_emmc_c_clk" and possibly come first.

You miss a commit message which is _very_ important given the type of
change you propose.
 
> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24

Change IDs have nothing to do here.

However a Fixes and a Signed-off-by are welcome.

You'll also need to Cc: Rob H. in your v2.

> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;
>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;


Thanks,
Miqu?l


From miquel.raynal at bootlin.com  Thu Jan  6 00:12:46 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 6 Jan 2022 09:12:46 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <20220106091246.08ca66e0@xps13>



liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:

> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------

I forgot to mention, while you're at it, after fixing the bindings,
could you please convert it to yaml?

>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;
>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;


Thanks,
Miqu?l


From dan.carpenter at oracle.com  Thu Jan  6 00:14:19 2022
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Thu, 6 Jan 2022 11:14:19 +0300
Subject: [PATCH] fsi: Aspeed: Fix a potential double free
In-Reply-To: <YcldM9sgYdjMYMtH@kroah.com>
References: <2cafa0607ca171ebd00ac6c7e073b46808e24f00.1640537669.git.christophe.jaillet@wanadoo.fr>
 <YcldM9sgYdjMYMtH@kroah.com>
Message-ID: <20220106081418.GH7674@kadam>

On Mon, Dec 27, 2021 at 07:29:07AM +0100, Greg KH wrote:
> On Sun, Dec 26, 2021 at 05:56:02PM +0100, Christophe JAILLET wrote:
> > 'aspeed' is a devm_alloc'ed, so there is no need to free it explicitly or
> > there will be a double free().
> 
> A struct device can never be devm_alloced for obvious reasons.  Perhaps
> that is the real problem here?
> 

I don't understand how "aspeed" is a struct device.

I've been working on understanding device managed memory recently for
Smatch.  It's really complicated.  There are a bunch of rules/heuristics
that I'm slowly creating to generate new warnings but I'm a long way
from understanding it well myself.

regards,
dan carpenter



From narmstrong at baylibre.com  Thu Jan  6 00:19:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 6 Jan 2022 09:19:09 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106033130.37623-1-liang.yang@amlogic.com>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
Message-ID: <8439ec98-694e-0391-2a00-89e856024823@baylibre.com>

Hi,

On 06/01/2022 04:31, Liang Yang wrote:
> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> ---
>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>  1 file changed, 3 insertions(+), 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> index 5794ab1147c1..37f16fe4fe66 100644
> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
> @@ -14,11 +14,6 @@ Required properties:
>  - clock-names: Should contain the following:
>  	"core" - NFC module gate clock
>  	"device" - device clock from eMMC sub clock controller
> -	"rx" - rx clock phase
> -	"tx" - tx clock phase
> -
> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
> -				controller port C
>  
>  Optional children nodes:
>  Children nodes represent the available nand chips.
> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>  
>  Example demonstrate on AXG SoC:
>  
> -	sd_emmc_c_clkc: mmc at 7000 {
> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> -		reg = <0x0 0x7000 0x0 0x800>;
> -	};
> -
>  	nand-controller at 7800 {
>  		compatible = "amlogic,meson-axg-nfc";
>  		reg = <0x0 0x7800 0x0 0x100>;
> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>  
>  		clocks = <&clkc CLKID_SD_EMMC_C>,
> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> -		clock-names = "core", "device", "rx", "tx";
> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
> +			<&clkc CLKID_FCLK_DIV2>;
> +		clock-names = "core", "device";
> +		sd_emmc_c_clkc = <0xffe07000>;


sd_emmc_c_clkc should be documented, but it should be either:
- a syscon
- in reg

but since 0xffe07000 is part of the emmc memory space, you can't simply
put this address like that and pass it to a random undocumented property.

Adding "syscon" to the sd_emmc_c compatibles, and passing the sd_emmc_c node as syscon
could actually work.

Neil

>  
>  		pinctrl-names = "default";
>  		pinctrl-0 = <&nand_pins>;
> 



From chunfeng.yun at mediatek.com  Thu Jan  6 00:24:42 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 16:24:42 +0800
Subject: [PATCH 1/3] phy: mediatek: phy-mtk-mipi-dsi: Switch to regmap
 for mmio access
In-Reply-To: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
Message-ID: <a886110ec8a7e85ac21a7ec98465bd67a9cd5141.camel@mediatek.com>

On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> Switch to using the generic regmap API instead of calls to
> readl/writel
> for MMIO register access, removing custom crafted
> update/set/clear_bits
> functions and also allowing us to reduce code size.
It seems make the driver more complex and may consume more cpu time. we
prefer to use readl/writel here.

> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  .../phy/mediatek/phy-mtk-mipi-dsi-mt8173.c    | 45 ++++++-------
>  .../phy/mediatek/phy-mtk-mipi-dsi-mt8183.c    | 63 ++++++++++-------
> --
>  drivers/phy/mediatek/phy-mtk-mipi-dsi.c       | 43 +++++--------
>  drivers/phy/mediatek/phy-mtk-mipi-dsi.h       |  6 +-
>  4 files changed, 72 insertions(+), 85 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> index 7a847954594f..95a0d9a3cca7 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> @@ -4,6 +4,7 @@
>   * Author: jitao.shi <jitao.shi at mediatek.com>
>   */
>  
> +#include <linux/regmap.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  #define MIPITX_DSI_CON		0x00
> @@ -145,7 +146,7 @@ static int mtk_mipi_tx_pll_prepare(struct clk_hw
> *hw)
>  		return -EINVAL;
>  	}
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_BG_CON,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_BG_CON,
>  				RG_DSI_VOUT_MSK |
>  				RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN,
>  				(4 << 20) | (4 << 17) | (4 << 14) |
> @@ -154,22 +155,22 @@ static int mtk_mipi_tx_pll_prepare(struct
> clk_hw *hw)
>  
>  	usleep_range(30, 100);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_TOP_CON,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
>  				RG_DSI_LNT_IMP_CAL_CODE |
> RG_DSI_LNT_HS_BIAS_EN,
>  				(8 << 4) | RG_DSI_LNT_HS_BIAS_EN);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_CON,
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_CON,
>  			     RG_DSI_CKG_LDOOUT_EN | RG_DSI_LDOCORE_EN);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_PWR,
>  				RG_DSI_MPPLL_SDM_PWR_ON |
>  				RG_DSI_MPPLL_SDM_ISO_EN,
>  				RG_DSI_MPPLL_SDM_PWR_ON);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
>  			       RG_DSI_MPPLL_PLL_EN);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
>  				RG_DSI_MPPLL_TXDIV0 |
> RG_DSI_MPPLL_TXDIV1 |
>  				RG_DSI_MPPLL_PREDIV,
>  				(txdiv0 << 3) | (txdiv1 << 5));
> @@ -184,19 +185,19 @@ static int mtk_mipi_tx_pll_prepare(struct
> clk_hw *hw)
>  	 */
>  	pcw = div_u64(((u64)mipi_tx->data_rate * 2 * txdiv) << 24,
>  		      26000000);
> -	writel(pcw, mipi_tx->regs + MIPITX_DSI_PLL_CON2);
> +	regmap_write(mipi_tx->regmap, MIPITX_DSI_PLL_CON2, pcw);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON1,
>  			     RG_DSI_MPPLL_SDM_FRA_EN);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
> RG_DSI_MPPLL_PLL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
> RG_DSI_MPPLL_PLL_EN);
>  
>  	usleep_range(20, 100);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON1,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON1,
>  			       RG_DSI_MPPLL_SDM_SSC_EN);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_TOP,
>  				RG_DSI_MPPLL_PRESERVE,
>  				mipi_tx->driver_data->mppll_preserve);
>  
> @@ -209,27 +210,27 @@ static void mtk_mipi_tx_pll_unprepare(struct
> clk_hw *hw)
>  
>  	dev_dbg(mipi_tx->dev, "unprepare\n");
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
>  			       RG_DSI_MPPLL_PLL_EN);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_TOP,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_TOP,
>  				RG_DSI_MPPLL_PRESERVE, 0);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_DSI_PLL_PWR,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_DSI_PLL_PWR,
>  				RG_DSI_MPPLL_SDM_ISO_EN |
>  				RG_DSI_MPPLL_SDM_PWR_ON,
>  				RG_DSI_MPPLL_SDM_ISO_EN);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
>  			       RG_DSI_LNT_HS_BIAS_EN);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_CON,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_CON,
>  			       RG_DSI_CKG_LDOOUT_EN |
> RG_DSI_LDOCORE_EN);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_BG_CON,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_BG_CON,
>  			       RG_DSI_BG_CKEN | RG_DSI_BG_CORE_EN);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_PLL_CON0,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_PLL_CON0,
>  			       RG_DSI_MPPLL_DIV_MSK);
>  }
>  
> @@ -254,9 +255,9 @@ static void mtk_mipi_tx_power_on_signal(struct
> phy *phy)
>  
>  	for (reg = MIPITX_DSI_CLOCK_LANE;
>  	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
> -		mtk_mipi_tx_set_bits(mipi_tx, reg,
> RG_DSI_LNTx_LDOOUT_EN);
> +		regmap_set_bits(mipi_tx->regmap, reg,
> RG_DSI_LNTx_LDOOUT_EN);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_DSI_TOP_CON,
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
>  			       RG_DSI_PAD_TIE_LOW_EN);
>  }
>  
> @@ -265,12 +266,12 @@ static void mtk_mipi_tx_power_off_signal(struct
> phy *phy)
>  	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
>  	u32 reg;
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_DSI_TOP_CON,
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_DSI_TOP_CON,
>  			     RG_DSI_PAD_TIE_LOW_EN);
>  
>  	for (reg = MIPITX_DSI_CLOCK_LANE;
>  	     reg <= MIPITX_DSI_DATA_LANE3; reg += 4)
> -		mtk_mipi_tx_clear_bits(mipi_tx, reg,
> RG_DSI_LNTx_LDOOUT_EN);
> +		regmap_clear_bits(mipi_tx->regmap, reg,
> RG_DSI_LNTx_LDOOUT_EN);
>  }
>  
>  const struct mtk_mipitx_data mt2701_mipitx_data = {
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> index 99108426d57c..01b59527669e 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> @@ -4,6 +4,7 @@
>   * Author: jitao.shi <jitao.shi at mediatek.com>
>   */
>  
> +#include <linux/regmap.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  #define MIPITX_LANE_CON		0x000c
> @@ -70,17 +71,17 @@ static int mtk_mipi_tx_pll_enable(struct clk_hw
> *hw)
>  		return -EINVAL;
>  	}
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON4,
> RG_DSI_PLL_IBIAS);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON4,
> RG_DSI_PLL_IBIAS);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_PWR_ON);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1,
> RG_DSI_PLL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_PWR_ON);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON1,
> RG_DSI_PLL_EN);
>  	udelay(1);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_ISO_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_ISO_EN);
>  	pcw = div_u64(((u64)mipi_tx->data_rate * txdiv) << 24,
> 26000000);
> -	writel(pcw, mipi_tx->regs + MIPITX_PLL_CON0);
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_PLL_CON1,
> RG_DSI_PLL_POSDIV,
> +	regmap_write(mipi_tx->regmap, MIPITX_PLL_CON0, pcw);
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_PLL_CON1,
> RG_DSI_PLL_POSDIV,
>  				txdiv0 << 8);
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_CON1, RG_DSI_PLL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_CON1,
> RG_DSI_PLL_EN);
>  
>  	return 0;
>  }
> @@ -89,10 +90,10 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw
> *hw)
>  {
>  	struct mtk_mipi_tx *mipi_tx = mtk_mipi_tx_from_clk_hw(hw);
>  
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_CON1,
> RG_DSI_PLL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_CON1,
> RG_DSI_PLL_EN);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_ISO_EN);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_PWR_ON);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_ISO_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_PLL_PWR,
> AD_DSI_PLL_SDM_PWR_ON);
>  }
>  
>  static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned
> long rate,
> @@ -121,7 +122,7 @@ static void
> mtk_mipi_tx_config_calibration_data(struct mtk_mipi_tx *mipi_tx)
>  			mipi_tx->rt_code[i] |= 0x10 << 5;
>  
>  		for (j = 0; j < 10; j++)
> -			mtk_mipi_tx_update_bits(mipi_tx,
> +			regmap_update_bits(mipi_tx->regmap,
>  				MIPITX_D2P_RTCODE * (i + 1) + j * 4,
>  				1, mipi_tx->rt_code[i] >> j & 1);
>  	}
> @@ -132,26 +133,26 @@ static void mtk_mipi_tx_power_on_signal(struct
> phy *phy)
>  	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
>  
>  	/* BG_LPF_EN / BG_CORE_EN */
> -	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
> -	       mipi_tx->regs + MIPITX_LANE_CON);
> +	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
> +		    (RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN));
>  	usleep_range(30, 100);
> -	writel(RG_DSI_BG_CORE_EN | RG_DSI_BG_LPF_EN,
> -	       mipi_tx->regs + MIPITX_LANE_CON);
> +	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
> +		    (RG_DSI_BG_LPF_EN | RG_DSI_BG_CORE_EN));
>  
>  	/* Switch OFF each Lane */
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D0_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D1_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D2_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_D3_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_clear_bits(mipi_tx, MIPITX_CK_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_D0_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_D1_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_D2_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_D3_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_clear_bits(mipi_tx->regmap, MIPITX_CK_SW_CTL_EN,
> DSI_SW_CTL_EN);
>  
> -	mtk_mipi_tx_update_bits(mipi_tx, MIPITX_VOLTAGE_SEL,
> +	regmap_update_bits(mipi_tx->regmap, MIPITX_VOLTAGE_SEL,
>  				RG_DSI_HSTX_LDO_REF_SEL,
>  				(mipi_tx->mipitx_drive - 3000) / 200 <<
> 6);
>  
>  	mtk_mipi_tx_config_calibration_data(mipi_tx);
>  
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_CKMODE_EN,
> DSI_CK_CKMODE_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_CK_CKMODE_EN,
> DSI_CK_CKMODE_EN);
>  }
>  
>  static void mtk_mipi_tx_power_off_signal(struct phy *phy)
> @@ -159,15 +160,15 @@ static void mtk_mipi_tx_power_off_signal(struct
> phy *phy)
>  	struct mtk_mipi_tx *mipi_tx = phy_get_drvdata(phy);
>  
>  	/* Switch ON each Lane */
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D0_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D1_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D2_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_D3_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -	mtk_mipi_tx_set_bits(mipi_tx, MIPITX_CK_SW_CTL_EN,
> DSI_SW_CTL_EN);
> -
> -	writel(RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN,
> -	       mipi_tx->regs + MIPITX_LANE_CON);
> -	writel(RG_DSI_PAD_TIEL_SEL, mipi_tx->regs + MIPITX_LANE_CON);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_D0_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_D1_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_D2_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_D3_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +	regmap_set_bits(mipi_tx->regmap, MIPITX_CK_SW_CTL_EN,
> DSI_SW_CTL_EN);
> +
> +	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
> +		    (RG_DSI_PAD_TIEL_SEL | RG_DSI_BG_CORE_EN));
> +	regmap_write(mipi_tx->regmap, MIPITX_LANE_CON,
> RG_DSI_PAD_TIEL_SEL);
>  }
>  
>  const struct mtk_mipitx_data mt8183_mipitx_data = {
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> index 28ad9403c441..51b1b1d4ad38 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> @@ -3,6 +3,7 @@
>   * Copyright (c) 2015 MediaTek Inc.
>   */
>  
> +#include <linux/regmap.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw
> *hw)
> @@ -10,30 +11,6 @@ inline struct mtk_mipi_tx
> *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw)
>  	return container_of(hw, struct mtk_mipi_tx, pll_hw);
>  }
>  
> -void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
> -			    u32 bits)
> -{
> -	u32 temp = readl(mipi_tx->regs + offset);
> -
> -	writel(temp & ~bits, mipi_tx->regs + offset);
> -}
> -
> -void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
> -			  u32 bits)
> -{
> -	u32 temp = readl(mipi_tx->regs + offset);
> -
> -	writel(temp | bits, mipi_tx->regs + offset);
> -}
> -
> -void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32
> offset,
> -			     u32 mask, u32 data)
> -{
> -	u32 temp = readl(mipi_tx->regs + offset);
> -
> -	writel((temp & ~mask) | (data & mask), mipi_tx->regs + offset);
> -}
> -
>  int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
>  			     unsigned long parent_rate)
>  {
> @@ -126,6 +103,13 @@ static void
> mtk_mipi_tx_get_calibration_datal(struct mtk_mipi_tx *mipi_tx)
>  	kfree(buf);
>  }
>  
> +static const struct regmap_config mtk_mipi_tx_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.disable_locking = true,
> +};
> +
>  static int mtk_mipi_tx_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -139,6 +123,7 @@ static int mtk_mipi_tx_probe(struct
> platform_device *pdev)
>  	};
>  	struct phy *phy;
>  	struct phy_provider *phy_provider;
> +	void __iomem *regs;
>  	int ret;
>  
>  	mipi_tx = devm_kzalloc(dev, sizeof(*mipi_tx), GFP_KERNEL);
> @@ -147,9 +132,13 @@ static int mtk_mipi_tx_probe(struct
> platform_device *pdev)
>  
>  	mipi_tx->driver_data = of_device_get_match_data(dev);
>  
> -	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
> -	if (IS_ERR(mipi_tx->regs))
> -		return PTR_ERR(mipi_tx->regs);
> +	regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	mipi_tx->regmap = devm_regmap_init_mmio(dev, regs,
> &mtk_mipi_tx_regmap_config);
> +	if (IS_ERR(mipi_tx->regmap))
> +		return PTR_ERR(mipi_tx->regmap);
>  
>  	ref_clk = devm_clk_get(dev, NULL);
>  	if (IS_ERR(ref_clk)) {
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> index c76f07c3fdeb..8d32e9027a15 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> @@ -27,7 +27,7 @@ struct mtk_mipitx_data {
>  
>  struct mtk_mipi_tx {
>  	struct device *dev;
> -	void __iomem *regs;
> +	struct regmap *regmap;
>  	u32 data_rate;
>  	u32 mipitx_drive;
>  	u32 rt_code[5];
> @@ -37,10 +37,6 @@ struct mtk_mipi_tx {
>  };
>  
>  struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw *hw);
> -void mtk_mipi_tx_clear_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
> u32 bits);
> -void mtk_mipi_tx_set_bits(struct mtk_mipi_tx *mipi_tx, u32 offset,
> u32 bits);
> -void mtk_mipi_tx_update_bits(struct mtk_mipi_tx *mipi_tx, u32
> offset, u32 mask,
> -			     u32 data);
>  int mtk_mipi_tx_pll_set_rate(struct clk_hw *hw, unsigned long rate,
>  			     unsigned long parent_rate);
>  unsigned long mtk_mipi_tx_pll_recalc_rate(struct clk_hw *hw,

From chunfeng.yun at mediatek.com  Thu Jan  6 00:26:12 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 16:26:12 +0800
Subject: [PATCH 1/4] phy: mediatek: phy-mtk-hdmi: Switch to regmap for
 mmio access
In-Reply-To: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
Message-ID: <709022152dd2b80c3866205c1d7b9c018b27e59f.camel@mediatek.com>

On Mon, 2022-01-03 at 16:30 +0100, AngeloGioacchino Del Regno wrote:
> Switch to using the generic regmap API instead of calls to
> readl/writel
> for MMIO register access, removing custom crafted
> update/set/clear_bits
> functions and also allowing us to reduce code size.
Using readl/writel is simpler than regmap here

Thanks

> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c | 165 ++++++++++---------
> --
>  drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c | 126 ++++++++--------
>  drivers/phy/mediatek/phy-mtk-hdmi.c        |  51 ++-----
>  drivers/phy/mediatek/phy-mtk-hdmi.h        |   9 +-
>  4 files changed, 158 insertions(+), 193 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> index b74c65a1762c..09e0dd7499d8 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> @@ -69,19 +69,19 @@ static int mtk_hdmi_pll_prepare(struct clk_hw
> *hw)
>  {
>  	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
>  
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_RLH_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
>  	usleep_range(80, 100);
>  	return 0;
>  }
> @@ -90,19 +90,19 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw
> *hw)
>  {
>  	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
>  
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_RLH_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
>  	usleep_range(80, 100);
>  }
>  
> @@ -125,37 +125,34 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw
> *hw, unsigned long rate,
>  	else
>  		pos_div = 1;
>  
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_PREDIV_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_TX_POSDIV);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IC),
> -			  RG_HTPLL_IC_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_IR),
> -			  RG_HTPLL_IR_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON2, (pos_div <<
> RG_HDMITX_TX_POSDIV),
> -			  RG_HDMITX_TX_POSDIV_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (1 << RG_HTPLL_FBKSEL),
> -			  RG_HTPLL_FBKSEL_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (19 << RG_HTPLL_FBKDIV),
> -			  RG_HTPLL_FBKDIV_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON7, (0x2 << RG_HTPLL_DIVEN),
> -			  RG_HTPLL_DIVEN_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0xc << RG_HTPLL_BP),
> -			  RG_HTPLL_BP_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x2 << RG_HTPLL_BC),
> -			  RG_HTPLL_BC_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6, (0x1 << RG_HTPLL_BR),
> -			  RG_HTPLL_BR_MASK);
> -
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PRED_IMP);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x3 <<
> RG_HDMITX_PRED_IBIAS),
> -			  RG_HDMITX_PRED_IBIAS_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_IMP_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1, (0x28 <<
> RG_HDMITX_DRV_IMP),
> -			  RG_HDMITX_DRV_IMP_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4, 0x28,
> RG_HDMITX_RESERVE_MASK);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0, (0xa <<
> RG_HDMITX_DRV_IBIAS),
> -			  RG_HDMITX_DRV_IBIAS_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_PREDIV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_TX_POSDIV);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_IC_MASK, BIT(RG_HTPLL_IC));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_IR_MASK, BIT(RG_HTPLL_IR));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_TX_POSDIV_MASK,
> +			   (pos_div << RG_HDMITX_TX_POSDIV));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_FBKSEL_MASK,
> +			   (1 << RG_HTPLL_FBKSEL));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_FBKDIV_MASK,
> +			   (19 << RG_HTPLL_FBKDIV));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON7,
> RG_HTPLL_DIVEN_MASK,
> +			   (0x2 << RG_HTPLL_DIVEN));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_BP_MASK,
> +			   (0xc << RG_HTPLL_BP));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_BC_MASK,
> +			   (0x2 << RG_HTPLL_BC));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_BR_MASK, BIT(RG_HTPLL_BR));
> +
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PRED_IMP);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PRED_IBIAS_MASK,
> +			   (0x3 << RG_HDMITX_PRED_IBIAS));
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_IMP_MASK);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_DRV_IMP_MASK,
> +			   (0x28 << RG_HDMITX_DRV_IMP));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON4,
> RG_HDMITX_RESERVE_MASK, 0x28);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_DRV_IBIAS_MASK,
> +			   (0xa << RG_HDMITX_DRV_IBIAS));
>  	return 0;
>  }
>  
> @@ -163,10 +160,11 @@ static unsigned long
> mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
>  					      unsigned long
> parent_rate)
>  {
>  	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
> -	unsigned long out_rate, val;
> +	unsigned long out_rate;
> +	u32 val;
>  
> -	val = (readl(hdmi_phy->regs + HDMI_CON6)
> -	       & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
> +	regmap_read(hdmi_phy->regmap, HDMI_CON6, &val);
> +	val = (val & RG_HTPLL_PREDIV_MASK) >> RG_HTPLL_PREDIV;
>  	switch (val) {
>  	case 0x00:
>  		out_rate = parent_rate;
> @@ -179,14 +177,15 @@ static unsigned long
> mtk_hdmi_pll_recalc_rate(struct clk_hw *hw,
>  		break;
>  	}
>  
> -	val = (readl(hdmi_phy->regs + HDMI_CON6)
> -	       & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
> +	regmap_read(hdmi_phy->regmap, HDMI_CON6, &val);
> +	val = (val & RG_HTPLL_FBKDIV_MASK) >> RG_HTPLL_FBKDIV;
>  	out_rate *= (val + 1) * 2;
> -	val = (readl(hdmi_phy->regs + HDMI_CON2)
> -	       & RG_HDMITX_TX_POSDIV_MASK);
> +	regmap_read(hdmi_phy->regmap, HDMI_CON2, &val);
> +	val &= RG_HDMITX_TX_POSDIV_MASK;
>  	out_rate >>= (val >> RG_HDMITX_TX_POSDIV);
>  
> -	if (readl(hdmi_phy->regs + HDMI_CON2) & RG_HDMITX_EN_TX_POSDIV)
> +	regmap_read(hdmi_phy->regmap, HDMI_CON2, &val);
> +	if (val & RG_HDMITX_EN_TX_POSDIV)
>  		out_rate /= 5;
>  
>  	return out_rate;
> @@ -202,37 +201,37 @@ static const struct clk_ops
> mtk_hdmi_phy_pll_ops = {
>  
>  static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
>  {
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON7, RG_HTPLL_AUTOK_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2, RG_HDMITX_EN_MBIAS);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_RLH_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
>  	usleep_range(80, 100);
>  }
>  
>  static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
>  {
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_DRV_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_PRED_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SER_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_MBIAS_LPF_EN);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_EN_SLDO_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_TX_CKLDO);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6, RG_HTPLL_EN);
>  	usleep_range(80, 100);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON6, RG_HTPLL_RLH_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON2,
> RG_HDMITX_EN_MBIAS);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_POSDIV_MASK);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON6,
> RG_HTPLL_RLH_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON7,
> RG_HTPLL_AUTOK_EN);
>  	usleep_range(80, 100);
>  }
>  
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> index 6cdfdf5a698a..e317bf4a9db9 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> @@ -111,15 +111,15 @@ static int mtk_hdmi_pll_prepare(struct clk_hw
> *hw)
>  {
>  	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
>  
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_AUTOK_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
> RG_HDMITX_MHLCK_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_AUTOK_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3,
> RG_HDMITX_MHLCK_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_EN);
>  	usleep_range(100, 150);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0, RG_HDMITX_PLL_EN);
>  	usleep_range(100, 150);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_LPF_EN);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_TXDIV_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_LPF_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_TXDIV_EN);
>  
>  	return 0;
>  }
> @@ -128,14 +128,14 @@ static void mtk_hdmi_pll_unprepare(struct
> clk_hw *hw)
>  {
>  	struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw);
>  
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_TXDIV_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_LPF_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_TXDIV_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_LPF_EN);
>  	usleep_range(100, 150);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0, RG_HDMITX_PLL_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_PLL_EN);
>  	usleep_range(100, 150);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_EN);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON1,
> RG_HDMITX_PLL_AUTOK_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_BIAS_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_AUTOK_EN);
>  	usleep_range(100, 150);
>  }
>  
> @@ -177,65 +177,59 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw
> *hw, unsigned long rate,
>  		div = 1;
>  	}
>  
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
> -			  (pre_div << PREDIV_SHIFT),
> RG_HDMITX_PLL_PREDIV);
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
> -			  (0x1 << PLL_IC_SHIFT) | (0x1 <<
> PLL_IR_SHIFT),
> -			  RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
> -			  (div << PLL_TXDIV_SHIFT),
> RG_HDMITX_PLL_TXDIV);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
> -			  (0x1 << PLL_FBKSEL_SHIFT) | (19 <<
> PLL_FBKDIV_SHIFT),
> -			  RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON1,
> -			  (0x2 << PLL_DIVEN_SHIFT),
> RG_HDMITX_PLL_DIVEN);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON0,
> -			  (0xc << PLL_BP_SHIFT) | (0x2 << PLL_BC_SHIFT)
> |
> -			  (0x1 << PLL_BR_SHIFT),
> -			  RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
> -			  RG_HDMITX_PLL_BR);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_PLL_PREDIV,
> +			   (pre_div << PREDIV_SHIFT));
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON0,
> RG_HDMITX_PLL_POSDIV);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
> +			   RG_HDMITX_PLL_IC | RG_HDMITX_PLL_IR,
> +			   BIT(PLL_IC_SHIFT) | BIT(PLL_IR_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_TXDIV,
> +			   (div << PLL_TXDIV_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
> +			   RG_HDMITX_PLL_FBKSEL | RG_HDMITX_PLL_FBKDIV,
> +			  BIT(PLL_FBKSEL_SHIFT) | (19 <<
> PLL_FBKDIV_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON1,
> RG_HDMITX_PLL_DIVEN,
> +			   (0x2 << PLL_DIVEN_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON0,
> +			   RG_HDMITX_PLL_BP | RG_HDMITX_PLL_BC |
> RG_HDMITX_PLL_BR,
> +			   (0xc << PLL_BP_SHIFT) | (0x2 <<
> PLL_BC_SHIFT) |
> +			   (0x1 << PLL_BR_SHIFT));
>  	if (rate < 165000000) {
> -		mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
> +		regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3,
>  					RG_HDMITX_PRD_IMP_EN);
>  		pre_ibias = 0x3;
>  		imp_en = 0x0;
>  		hdmi_ibias = hdmi_phy->ibias;
>  	} else {
> -		mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
> +		regmap_set_bits(hdmi_phy->regmap, HDMI_CON3,
>  				      RG_HDMITX_PRD_IMP_EN);
>  		pre_ibias = 0x6;
>  		imp_en = 0xf;
>  		hdmi_ibias = hdmi_phy->ibias_up;
>  	}
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON4,
> -			  (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
> -			  (pre_ibias << PRD_IBIAS_D2_SHIFT) |
> -			  (pre_ibias << PRD_IBIAS_D1_SHIFT) |
> -			  (pre_ibias << PRD_IBIAS_D0_SHIFT),
> -			  RG_HDMITX_PRD_IBIAS_CLK |
> -			  RG_HDMITX_PRD_IBIAS_D2 |
> -			  RG_HDMITX_PRD_IBIAS_D1 |
> -			  RG_HDMITX_PRD_IBIAS_D0);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON3,
> -			  (imp_en << DRV_IMP_EN_SHIFT),
> -			  RG_HDMITX_DRV_IMP_EN);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON6,
> -			  (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT)
> |
> -			  (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
> -			  (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
> -			  (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT),
> -			  RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2
> |
> -			  RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0);
> -	mtk_hdmi_phy_mask(hdmi_phy, HDMI_CON5,
> -			  (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
> -			  (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
> -			  (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
> -			  (hdmi_ibias << DRV_IBIAS_D0_SHIFT),
> -			  RG_HDMITX_DRV_IBIAS_CLK |
> -			  RG_HDMITX_DRV_IBIAS_D2 |
> -			  RG_HDMITX_DRV_IBIAS_D1 |
> -			  RG_HDMITX_DRV_IBIAS_D0);
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON4,
> +			   RG_HDMITX_PRD_IBIAS_CLK |
> RG_HDMITX_PRD_IBIAS_D2 |
> +			   RG_HDMITX_PRD_IBIAS_D1 |
> RG_HDMITX_PRD_IBIAS_D0,
> +			   (pre_ibias << PRD_IBIAS_CLK_SHIFT) |
> +			   (pre_ibias << PRD_IBIAS_D2_SHIFT) |
> +			   (pre_ibias << PRD_IBIAS_D1_SHIFT) |
> +			   (pre_ibias << PRD_IBIAS_D0_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON3,
> RG_HDMITX_DRV_IMP_EN,
> +			   (imp_en << DRV_IMP_EN_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON6,
> +			   RG_HDMITX_DRV_IMP_CLK | RG_HDMITX_DRV_IMP_D2
> |
> +			   RG_HDMITX_DRV_IMP_D1 | RG_HDMITX_DRV_IMP_D0,
> +			   (hdmi_phy->drv_imp_clk << DRV_IMP_CLK_SHIFT)
> |
> +			   (hdmi_phy->drv_imp_d2 << DRV_IMP_D2_SHIFT) |
> +			   (hdmi_phy->drv_imp_d1 << DRV_IMP_D1_SHIFT) |
> +			   (hdmi_phy->drv_imp_d0 << DRV_IMP_D0_SHIFT));
> +	regmap_update_bits(hdmi_phy->regmap, HDMI_CON5,
> +			   RG_HDMITX_DRV_IBIAS_CLK |
> RG_HDMITX_DRV_IBIAS_D2 |
> +			   RG_HDMITX_DRV_IBIAS_D1 |
> RG_HDMITX_DRV_IBIAS_D0,
> +			   (hdmi_ibias << DRV_IBIAS_CLK_SHIFT) |
> +			   (hdmi_ibias << DRV_IBIAS_D2_SHIFT) |
> +			   (hdmi_ibias << DRV_IBIAS_D1_SHIFT) |
> +			   (hdmi_ibias << DRV_IBIAS_D0_SHIFT));
>  	return 0;
>  }
>  
> @@ -257,17 +251,15 @@ static const struct clk_ops
> mtk_hdmi_phy_pll_ops = {
>  
>  static void mtk_hdmi_phy_enable_tmds(struct mtk_hdmi_phy *hdmi_phy)
>  {
> -	mtk_hdmi_phy_set_bits(hdmi_phy, HDMI_CON3,
> -			      RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
> -			      RG_HDMITX_DRV_EN);
> +	regmap_set_bits(hdmi_phy->regmap, HDMI_CON3,
> +			RG_HDMITX_SER_EN | RG_HDMITX_PRD_EN |
> RG_HDMITX_DRV_EN);
>  	usleep_range(100, 150);
>  }
>  
>  static void mtk_hdmi_phy_disable_tmds(struct mtk_hdmi_phy *hdmi_phy)
>  {
> -	mtk_hdmi_phy_clear_bits(hdmi_phy, HDMI_CON3,
> -				RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
> -				RG_HDMITX_SER_EN);
> +	regmap_clear_bits(hdmi_phy->regmap, HDMI_CON3,
> +			  RG_HDMITX_DRV_EN | RG_HDMITX_PRD_EN |
> RG_HDMITX_SER_EN);
>  }
>  
>  struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf = {
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c
> b/drivers/phy/mediatek/phy-mtk-hdmi.c
> index 5fb4217fb8e0..707e90691e6e 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
> @@ -15,39 +15,6 @@ static const struct phy_ops mtk_hdmi_phy_dev_ops =
> {
>  	.owner = THIS_MODULE,
>  };
>  
> -void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32
> offset,
> -			     u32 bits)
> -{
> -	void __iomem *reg = hdmi_phy->regs + offset;
> -	u32 tmp;
> -
> -	tmp = readl(reg);
> -	tmp &= ~bits;
> -	writel(tmp, reg);
> -}
> -
> -void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32
> offset,
> -			   u32 bits)
> -{
> -	void __iomem *reg = hdmi_phy->regs + offset;
> -	u32 tmp;
> -
> -	tmp = readl(reg);
> -	tmp |= bits;
> -	writel(tmp, reg);
> -}
> -
> -void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> -		       u32 val, u32 mask)
> -{
> -	void __iomem *reg = hdmi_phy->regs + offset;
> -	u32 tmp;
> -
> -	tmp = readl(reg);
> -	tmp = (tmp & ~mask) | (val & mask);
> -	writel(tmp, reg);
> -}
> -
>  inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
>  {
>  	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
> @@ -96,6 +63,13 @@ static void mtk_hdmi_phy_clk_get_data(struct
> mtk_hdmi_phy *hdmi_phy,
>  	clk_init->ops = hdmi_phy->conf->hdmi_phy_clk_ops;
>  }
>  
> +static const struct regmap_config mtk_hdmi_phy_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.disable_locking = true,
> +};
> +
>  static int mtk_hdmi_phy_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -109,15 +83,20 @@ static int mtk_hdmi_phy_probe(struct
> platform_device *pdev)
>  
>  	struct phy *phy;
>  	struct phy_provider *phy_provider;
> +	void __iomem *regs;
>  	int ret;
>  
>  	hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL);
>  	if (!hdmi_phy)
>  		return -ENOMEM;
>  
> -	hdmi_phy->regs = devm_platform_ioremap_resource(pdev, 0);
> -	if (IS_ERR(hdmi_phy->regs))
> -		return PTR_ERR(hdmi_phy->regs);
> +	regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	hdmi_phy->regmap = devm_regmap_init_mmio(dev, regs,
> &mtk_hdmi_phy_regmap_config);
> +	if (IS_ERR(hdmi_phy->regmap))
> +		return PTR_ERR(hdmi_phy->regmap);
>  
>  	ref_clk = devm_clk_get(dev, "pll_ref");
>  	if (IS_ERR(ref_clk)) {
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h
> b/drivers/phy/mediatek/phy-mtk-hdmi.h
> index dcf9bb13699b..a0571271d730 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.h
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
> @@ -15,6 +15,7 @@
>  #include <linux/of_device.h>
>  #include <linux/phy/phy.h>
>  #include <linux/platform_device.h>
> +#include <linux/regmap.h>
>  #include <linux/types.h>
>  
>  struct mtk_hdmi_phy;
> @@ -28,7 +29,7 @@ struct mtk_hdmi_phy_conf {
>  };
>  
>  struct mtk_hdmi_phy {
> -	void __iomem *regs;
> +	struct regmap *regmap;
>  	struct device *dev;
>  	struct mtk_hdmi_phy_conf *conf;
>  	struct clk *pll;
> @@ -42,12 +43,6 @@ struct mtk_hdmi_phy {
>  	unsigned int ibias_up;
>  };
>  
> -void mtk_hdmi_phy_clear_bits(struct mtk_hdmi_phy *hdmi_phy, u32
> offset,
> -			     u32 bits);
> -void mtk_hdmi_phy_set_bits(struct mtk_hdmi_phy *hdmi_phy, u32
> offset,
> -			   u32 bits);
> -void mtk_hdmi_phy_mask(struct mtk_hdmi_phy *hdmi_phy, u32 offset,
> -		       u32 val, u32 mask);
>  struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw);
>  
>  extern struct mtk_hdmi_phy_conf mtk_hdmi_phy_8173_conf;

From jbrunet at baylibre.com  Thu Jan  6 00:16:44 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 09:16:44 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106032504.23310-1-liang.yang@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
Message-ID: <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:

> Because EMMC and NAND have the same control clock register, so we
> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>
> 	sd_emmc_c_clkc: mmc at 7000 {
> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
> 		reg = <0x0 0x7000 0x0 0x800>;
> 	};
>
> 	nand-controller at 7800 {
> 		......
>
> 		clocks = <&clkc CLKID_SD_EMMC_C>,
> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
> 		clock-names = "core", "device", "rx", "tx";
> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>
> 		......
> 	}
>
> but in fact, above implementation is rejected. so now registering
> a nand_divider.

Can you give a bit of context ? a link to the discussion rejecting this

As far as remember, things were getting done for A1 and stopped before
clock part was finished. I'm saying the change is wrong, just that a
discussion is needed before a decision is made.

>
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>  1 file changed, 49 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..4472363059c2 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.
>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -55,6 +56,7 @@
>  #define NFC_REG_VER		0x38
>  
>  #define NFC_RB_IRQ_EN		BIT(21)
> +#define NFC_CMD_FIFO_RESET	BIT(31)
>  
>  #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>  	(								\
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,15 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;

I would have been nice to explain why these clock are no longer
required, in the change description maybe ?

> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
>  	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	void __iomem *reg_clk;
>  	struct completion completion;
>  	struct list_head chips;
>  	const struct meson_nfc_data *data;
> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>  	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>  		| nfc->param.chip_select | nfc->timing.tbers_max;
>  	writel(cmd, nfc->reg_base + NFC_REG_CMD);
> -
> +	meson_nfc_drain_cmd(nfc);

is this clock related ?

>  	ret = wait_for_completion_timeout(&nfc->completion,
>  					  msecs_to_jiffies(timeout_ms));
>  	if (ret == 0)
>  		ret = -1;
>  
> +	/* reset command fifo to avoid lock */
> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);

Again, not seem to be clock related - does not belong in this patch

>  	return ret;
>  }
>  
> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>  static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  {
>  	int ret;
> +	struct clk_init_data init = {0};
> +	const char *fix_div2_pll_name[1];
>  
> -	/* request core clock */

Why is the comment bothering you ?

>  	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>  	if (IS_ERR(nfc->core_clk)) {
>  		dev_err(nfc->dev, "failed to get core clock\n");
> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		return PTR_ERR(nfc->device_clk);
>  	}
>  
> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
> -	if (IS_ERR(nfc->phase_tx)) {
> -		dev_err(nfc->dev, "failed to get TX clk\n");
> -		return PTR_ERR(nfc->phase_tx);
> -	}
> -
> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
> -	if (IS_ERR(nfc->phase_rx)) {
> -		dev_err(nfc->dev, "failed to get RX clk\n");
> -		return PTR_ERR(nfc->phase_rx);
> -	}
> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
> +	init.ops = &clk_divider_ops;
> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);

You should be using "fw_name" so CCF looks a DT directly, instead of this

> +	init.parent_names = fix_div2_pll_name;
> +	init.num_parents = 1;
> +	nfc->nand_divider.reg = nfc->reg_clk;
> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
> +	nfc->nand_divider.hw.init = &init;
> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
> +				  CLK_DIVIDER_ROUND_CLOSEST |
> +          			  CLK_DIVIDER_ALLOW_ZERO;
> +
> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
> +	if (IS_ERR(nfc->nand_clk))
> +		return PTR_ERR(nfc->nand_clk);
>  
>  	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
> -	regmap_update_bits(nfc->reg_clk,
> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>  
>  	ret = clk_prepare_enable(nfc->core_clk);
>  	if (ret) {
> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  		goto err_device_clk;
>  	}
>  
> -	ret = clk_prepare_enable(nfc->phase_tx);
> +	ret = clk_prepare_enable(nfc->nand_clk);
>  	if (ret) {
> -		dev_err(nfc->dev, "failed to enable TX clock\n");
> -		goto err_phase_tx;
> -	}
> -
> -	ret = clk_prepare_enable(nfc->phase_rx);
> -	if (ret) {
> -		dev_err(nfc->dev, "failed to enable RX clock\n");
> -		goto err_phase_rx;
> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
> +		goto err_nand_clk;
>  	}
>  
>  	ret = clk_set_rate(nfc->device_clk, 24000000);
>  	if (ret)
> -		goto err_disable_rx;
> +		goto err_disable_clk;
>  
>  	return 0;
>  
> -err_disable_rx:
> -	clk_disable_unprepare(nfc->phase_rx);
> -err_phase_rx:
> -	clk_disable_unprepare(nfc->phase_tx);
> -err_phase_tx:
> +err_disable_clk:
> +	clk_disable_unprepare(nfc->nand_clk);
> +err_nand_clk:
>  	clk_disable_unprepare(nfc->device_clk);
>  err_device_clk:
>  	clk_disable_unprepare(nfc->core_clk);
> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>  
>  static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>  {
> -	clk_disable_unprepare(nfc->phase_rx);
> -	clk_disable_unprepare(nfc->phase_tx);
> +	clk_disable_unprepare(nfc->nand_clk);
>  	clk_disable_unprepare(nfc->device_clk);
>  	clk_disable_unprepare(nfc->core_clk);
>  }
> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct meson_nfc *nfc;
>  	struct resource *res;
> +	u32 ext_clk_reg;
>  	int ret, irq;
>  
>  	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>  	if (IS_ERR(nfc->reg_base))
>  		return PTR_ERR(nfc->reg_base);
>  
> -	nfc->reg_clk =
> -		syscon_regmap_lookup_by_phandle(dev->of_node,
> -						"amlogic,mmc-syscon");
> +	ret = of_property_read_u32(pdev->dev.of_node,
> +				   "sd_emmc_c_clkc",
> +				   &ext_clk_reg);
> +	if (ret) {
> +		dev_err(dev, "failed to get NAND external clock register\n");
> +		return ret;
> +	}
> +
> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));

That's how you should get a register region.
If you want an example of a device claiming several region on amlogic,
have a look at the pinctrl driver. 

>  	if (IS_ERR(nfc->reg_clk)) {
>  		dev_err(dev, "Failed to lookup clock base\n");
>  		return PTR_ERR(nfc->reg_clk);



From prabhakar.csengg at gmail.com  Thu Jan  6 00:44:25 2022
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Thu, 6 Jan 2022 08:44:25 +0000
Subject: [PATCH v2 2/3] dmaengine: mediatek: mtk-hsdma: Use
 platform_get_irq() to get the interrupt
In-Reply-To: <YdZ9rDvYtdu8L8Vb@matsya>
References: <20220104163519.21929-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20220104163519.21929-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <YdZ9rDvYtdu8L8Vb@matsya>
Message-ID: <CA+V-a8sO0AioGJh23jdFWoN_Qx9rm_3skYcCeyrWZVAuRtuOSw@mail.gmail.com>

Hi Vinod,

Thank you for the review.

On Thu, Jan 6, 2022 at 5:27 AM Vinod Koul <vkoul at kernel.org> wrote:
>
> On 04-01-22, 16:35, Lad Prabhakar wrote:
> > platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> > allocation of IRQ resources in DT core code, this causes an issue
> > when using hierarchical interrupt domains using "interrupts" property
> > in the node as this bypasses the hierarchical setup and messes up the
> > irq chaining.
> >
> > In preparation for removal of static setup of IRQ resource from DT core
> > code use platform_get_irq().
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > ---
> > v1->v2
> > * No change
> > ---
> >  drivers/dma/mediatek/mtk-hsdma.c | 11 ++++-------
> >  1 file changed, 4 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c
> > index 6ad8afbb95f2..c0fffde7fe08 100644
> > --- a/drivers/dma/mediatek/mtk-hsdma.c
> > +++ b/drivers/dma/mediatek/mtk-hsdma.c
> > @@ -923,13 +923,10 @@ static int mtk_hsdma_probe(struct platform_device *pdev)
> >               return PTR_ERR(hsdma->clk);
> >       }
> >
> > -     res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> > -     if (!res) {
> > -             dev_err(&pdev->dev, "No irq resource for %s\n",
> > -                     dev_name(&pdev->dev));
> > -             return -EINVAL;
> > -     }
> > -     hsdma->irq = res->start;
> > +     err = platform_get_irq(pdev, 0);
>
> why not platform_get_irq_optional() here and 3rd patch ?
>
For patches #2 and #3 the driver expects the IRQ to be present
strictly, that is the reason platform_get_irq_optional() isn't used so
that the behavior of the driver is unchanged with this patch.

Cheers,
Prabhakar

> > +     if (err < 0)
> > +             return err;
> > +     hsdma->irq = err;
> >
> >       refcount_set(&hsdma->pc_refcnt, 0);
> >       spin_lock_init(&hsdma->lock);
> > --
> > 2.17.1
>
> --
> ~Vinod


From chunfeng.yun at mediatek.com  Thu Jan  6 00:38:32 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 16:38:32 +0800
Subject: [PATCH 2/3] phy: mediatek: phy-mtk-mipi-dsi: Reorder and stop
 implicit header inclusion
In-Reply-To: <20220103145324.48008-2-angelogioacchino.delregno@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
 <20220103145324.48008-2-angelogioacchino.delregno@collabora.com>
Message-ID: <509b82079256ffaa0d844ae5a79a436fced16f3f.camel@mediatek.com>

On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> All the headers for phy-mtk-mipi-{dsi,dsi-mt8173,dsi-mt8183}.c were
> included from phy-mtk-mipi-dsi.h, but this isn't optimal: in order to
> increase readability and sensibly reduce build times, the inclusions
> should be done per-file, also avoiding to include unused headers and
> should not be implicit.
> 
> For this reason, move the inclusions to each file and remove unused
> ones.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c |  4 ++++
>  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c |  4 ++++
>  drivers/phy/mediatek/phy-mtk-mipi-dsi.c        |  7 +++++++
>  drivers/phy/mediatek/phy-mtk-mipi-dsi.h        | 10 ++--------
>  4 files changed, 17 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> index 95a0d9a3cca7..59f028da9d3e 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> @@ -4,7 +4,11 @@
>   * Author: jitao.shi <jitao.shi at mediatek.com>
>   */
>  
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
>  #include <linux/regmap.h>
> +#include <linux/phy/phy.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  #define MIPITX_DSI_CON		0x00
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> index 01b59527669e..6c6b192485ba 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> @@ -4,7 +4,11 @@
>   * Author: jitao.shi <jitao.shi at mediatek.com>
>   */
>  
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
>  #include <linux/regmap.h>
> +#include <linux/phy/phy.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  #define MIPITX_LANE_CON		0x000c
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> index 51b1b1d4ad38..6f7425b0bf5b 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> @@ -3,7 +3,14 @@
>   * Copyright (c) 2015 MediaTek Inc.
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/module.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
>  #include <linux/regmap.h>
> +#include <linux/phy/phy.h>
>  #include "phy-mtk-mipi-dsi.h"
>  
>  inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw
> *hw)
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> index 8d32e9027a15..4eb5fc91e083 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> @@ -7,16 +7,10 @@
>  #ifndef _MTK_MIPI_TX_H
>  #define _MTK_MIPI_TX_H
>  
> -#include <linux/clk.h>
>  #include <linux/clk-provider.h>
> -#include <linux/delay.h>
> -#include <linux/io.h>
> -#include <linux/module.h>
> -#include <linux/nvmem-consumer.h>
> -#include <linux/of_device.h>
> -#include <linux/platform_device.h>
> +#include <linux/types.h>
> +#include <linux/regmap.h>
>  #include <linux/phy/phy.h>
> -#include <linux/slab.h>
>  
I don't think it's good idea to move the common headers into .c files

>  struct mtk_mipitx_data {
>  	const u32 mppll_preserve;

From jbrunet at baylibre.com  Thu Jan  6 00:43:56 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 09:43:56 +0100
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106091246.08ca66e0@xps13>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
 <20220106091246.08ca66e0@xps13>
Message-ID: <1jbl0pz1t4.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 09:12, Miquel Raynal <miquel.raynal at bootlin.com> wrote:

> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:
>
>> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
>> ---
>>  .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>
> I forgot to mention, while you're at it, after fixing the bindings,
> could you please convert it to yaml?
>
>>  1 file changed, 3 insertions(+), 15 deletions(-)
>> 
>> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> index 5794ab1147c1..37f16fe4fe66 100644
>> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> @@ -14,11 +14,6 @@ Required properties:
>>  - clock-names: Should contain the following:
>>  	"core" - NFC module gate clock
>>  	"device" - device clock from eMMC sub clock controller

If I refer to the related driver change, this is not true anymore and
should be updated

>> -	"rx" - rx clock phase
>> -	"tx" - tx clock phase
>> -
>> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
>> -				controller port C
>>  
>>  Optional children nodes:
>>  Children nodes represent the available nand chips.
>> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>>  
>>  Example demonstrate on AXG SoC:
>>  
>> -	sd_emmc_c_clkc: mmc at 7000 {
>> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> -		reg = <0x0 0x7000 0x0 0x800>;
>> -	};
>> -
>>  	nand-controller at 7800 {
>>  		compatible = "amlogic,meson-axg-nfc";
>>  		reg = <0x0 0x7800 0x0 0x100>;
>> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>>  		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>>  
>>  		clocks = <&clkc CLKID_SD_EMMC_C>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> -		clock-names = "core", "device", "rx", "tx";
>> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>> +			<&clkc CLKID_FCLK_DIV2>;
>> +		clock-names = "core", "device";

If you want to re-implement the mmc clock part directly in the nand
driver, you should provide both clock inputs, like the mmc driver (in
addition to the pclk) ... Even if you plan on using only FDIV2 in the
driver, this what the HW is.

Something like:

clock-names = "core", "clkin0", "clkin1";
clocks = <&clkc CLKID_SD_EMMC_C>,
         <&clkc CLKID_SD_EMMC_C_CLK0>,
	 <&clkc CLKID_FCLK_DIV2>;

>> +		sd_emmc_c_clkc = <0xffe07000>;

This is not how you provide memory regions

>>  
>>  		pinctrl-names = "default";
>>  		pinctrl-0 = <&nand_pins>;
>
>
> Thanks,
> Miqu?l



From kyrie.wu at mediatek.com  Thu Jan  6 00:56:06 2022
From: kyrie.wu at mediatek.com (kyrie.wu)
Date: Thu, 6 Jan 2022 16:56:06 +0800
Subject: [PATCH V6, 5/5] media: mtk-jpegenc: add output pic reorder
 interface
In-Reply-To: <Yao8qYubCJTaGKe0@gmail.com>
References: <1638501230-13417-1-git-send-email-kyrie.wu@mediatek.com>
 <1638501230-13417-6-git-send-email-kyrie.wu@mediatek.com>
 <Yao8qYubCJTaGKe0@gmail.com>
Message-ID: <2407bcd678f2cc14e4a3ec9204f0137f8d9ebd0c.camel@mediatek.com>

On Fri, 2021-12-03 at 16:50 +0100, Ricardo Ribalda wrote:
> kyrie.wu wrote:
> 
> > There are two HWs in mt8195. Since the two HWs run
> > in parallel, it is necessary to reorder the output images
> > to ensure that the order is consistent with the input images.
> > 
> > Signed-off-by: kyrie.wu <kyrie.wu at mediatek.com>
> > ---
> > V6: no change
> > ---
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c   | 10 +----
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h   | 17 +++++++-
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c |  1 +
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h |  3 +-
> >  drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 48
> > ++++++++++++++++++++++-
> >  5 files changed, 65 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > index 80a6c1a..9e89629 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
> > @@ -106,15 +106,6 @@ static struct mtk_jpeg_fmt
> > mtk_jpeg_dec_formats[] = {
> >  #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats)
> >  #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats)
> >  
> > -struct mtk_jpeg_src_buf {
> > -	struct vb2_v4l2_buffer b;
> > -	struct list_head list;
> > -	struct mtk_jpeg_dec_param dec_param;
> > -
> > -	struct mtk_jpeg_ctx *curr_ctx;
> > -	u32 frame_num;
> > -};
> > -
> >  static int debug;
> >  module_param(debug, int, 0644);
> >  
> > @@ -1344,6 +1335,7 @@ static int mtk_jpeg_open(struct file *file)
> >  	if (jpeg->variant->is_encoder)
> >  		INIT_WORK(&ctx->jpeg_work, mtk_jpegenc_worker);
> >  
> > +	INIT_LIST_HEAD(&ctx->dst_done_queue);
> >  	v4l2_fh_init(&ctx->fh, vfd);
> >  	file->private_data = &ctx->fh;
> >  	v4l2_fh_add(&ctx->fh);
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > index 4c669af..f276221 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
> > @@ -13,10 +13,11 @@
> >  #include <media/v4l2-ctrls.h>
> >  #include <media/v4l2-device.h>
> >  #include <media/v4l2-fh.h>
> > +#include <media/videobuf2-v4l2.h>
> >  
> > -#define MTK_JPEG_NAME		"mtk-jpeg"
> > +#include "mtk_jpeg_dec_hw.h"
> >  
> > -#define MTK_JPEG_COMP_MAX		3
> > +#define MTK_JPEG_NAME		"mtk-jpeg"
> >  
> >  #define MTK_JPEG_FMT_FLAG_OUTPUT	BIT(0)
> >  #define MTK_JPEG_FMT_FLAG_CAPTURE	BIT(1)
> > @@ -75,6 +76,15 @@ struct mtk_jpeg_variant {
> >  	u32 cap_q_default_fourcc;
> >  };
> >  
> > +struct mtk_jpeg_src_buf {
> > +	struct vb2_v4l2_buffer b;
> > +	struct list_head list;
> > +	struct mtk_jpeg_dec_param dec_param;
> > +
> > +	struct mtk_jpeg_ctx *curr_ctx;
> > +	u32 frame_num;
> > +};
> > +
> >  enum mtk_jpeg_hw_state {
> >  	MTK_JPEG_HW_IDLE = 0,
> >  	MTK_JPEG_HW_BUSY = 1,
> > @@ -232,6 +242,9 @@ struct mtk_jpeg_ctx {
> >  	struct v4l2_ctrl_handler ctrl_hdl;
> >  	struct work_struct jpeg_work;
> >  	u32 total_frame_num;
> > +	struct list_head dst_done_queue;
> > +	spinlock_t done_queue_lock;
> > +	u32 last_done_frame_num;
> >  };
> >  
> >  extern struct platform_driver mtk_jpegenc_hw_driver;
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c
> > index afbbfd5..1e38522 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.c
> > @@ -9,6 +9,7 @@
> >  #include <linux/kernel.h>
> >  #include <media/videobuf2-core.h>
> >  
> > +#include "mtk_jpeg_core.h"
> >  #include "mtk_jpeg_dec_hw.h"
> >  
> >  #define MTK_JPEG_DUNUM_MASK(val)	(((val) - 1) & 0x3)
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h
> > index fa0d45f..87aaa5c 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_dec_hw.h
> > @@ -11,9 +11,10 @@
> >  
> >  #include <media/videobuf2-core.h>
> >  
> > -#include "mtk_jpeg_core.h"
> >  #include "mtk_jpeg_dec_reg.h"
> >  
> 
> Why are you moving around this define?
this micro defination is only used for jpeg decode, not for common
using, move to it.
> > +#define MTK_JPEG_COMP_MAX		3
> > +
> >  enum {
> >  	MTK_JPEG_DEC_RESULT_EOF_DONE		= 0,
> >  	MTK_JPEG_DEC_RESULT_PAUSE		= 1,
> > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > index 244f9f7..3383dc0 100644
> > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c
> > @@ -183,6 +183,50 @@ void mtk_jpeg_set_enc_params(struct
> > mtk_jpeg_ctx *ctx,  void __iomem *base)
> >  	writel(ctx->restart_interval, base + JPEG_ENC_RST_MCU_NUM);
> >  }
> >  
> > +void mtk_jpegenc_put_buf(struct mtk_jpegenc_comp_dev *jpeg)
> > +{
> > +	struct mtk_jpeg_ctx *ctx;
> > +	struct vb2_v4l2_buffer *dst_buffer;
> > +	struct list_head *temp_entry;
> > +	struct list_head *pos = NULL;
> > +	struct mtk_jpeg_src_buf *dst_done_buf, *tmp_dst_done_buf;
> > +	unsigned long flags;
> > +
> > +	ctx = jpeg->hw_param.curr_ctx;
> > +	if (!ctx) {
> > +		dev_err(jpeg->dev, "comp_jpeg ctx fail !!!\n");
> > +		return;
> > +	}
> > +
> > +	dst_buffer = jpeg->hw_param.dst_buffer;
> > +	if (!dst_buffer) {
> > +		dev_err(jpeg->dev, "comp_jpeg dst_buffer fail !!!\n");
> > +		return;
> > +	}
> > +
> > +	dst_done_buf = container_of(dst_buffer,
> > +		struct mtk_jpeg_src_buf, b);
> > +
> > +	spin_lock_irqsave(&ctx->done_queue_lock, flags);
> > +	list_add_tail(&dst_done_buf->list, &ctx->dst_done_queue);
> 
> You want to run this until there are only 0 or 1 elements? Did I got
> it
> right?
Yes.
> 
> So this means that when you enter put_buf there is max one element in
> the list. Do you need a list for that or only save one buffer in case
> they have come out of order?
The explaination is shown as below:
1. the put_buf is used to reorder output buffer;
2. the ctx->last_done_frame_num will increase when encode finished
everytime;
3. if the output buffer's frame_num(tmp_dst_done_buf->frame_num) is
equal to ctx->last_done_frame_num, call v4l2_m2m_buf_done to finish
this time encoding.
4. if there is no or only one element, the reordering is not required.

> > +	while (!list_empty(&ctx->dst_done_queue) &&
> > +		(pos != &ctx->dst_done_queue)) {
> > +		list_for_each_prev_safe(pos, temp_entry,
> > +			(&ctx->dst_done_queue)) {
> > +			tmp_dst_done_buf = list_entry(pos,
> > +				struct mtk_jpeg_src_buf, list);
> > +			if (tmp_dst_done_buf->frame_num ==
> > +				ctx->last_done_frame_num) {
> > +				list_del(&tmp_dst_done_buf->list);
> > +				v4l2_m2m_buf_done(&tmp_dst_done_buf->b,
> > +					VB2_BUF_STATE_DONE);
> > +				ctx->last_done_frame_num++;
> > +			}
> > +		}
> > +	}
> > +	spin_unlock_irqrestore(&ctx->done_queue_lock, flags);
> > +}
> > +
> >  static void mtk_jpegenc_timeout_work(struct work_struct *work)
> >  {
> >  	struct delayed_work *Pwork =
> > @@ -203,6 +247,7 @@ static void mtk_jpegenc_timeout_work(struct
> > work_struct *work)
> >  	atomic_inc(&cjpeg->hw_rdy);
> >  	wake_up(&master_jpeg->enc_hw_wq);
> >  	v4l2_m2m_buf_done(src_buf, buf_state);
> > +	mtk_jpegenc_put_buf(cjpeg);
> >  }
> >  
> >  static irqreturn_t mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> > @@ -237,8 +282,7 @@ static irqreturn_t
> > mtk_jpegenc_hw_irq_handler(int irq, void *priv)
> >  	vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size);
> >  	buf_state = VB2_BUF_STATE_DONE;
> >  	v4l2_m2m_buf_done(src_buf, buf_state);
> > -	v4l2_m2m_buf_done(dst_buf, buf_state);
> > -	v4l2_m2m_job_finish(master_jpeg->m2m_dev, ctx->fh.m2m_ctx);
> > +	mtk_jpegenc_put_buf(jpeg);
> >  	clk_disable_unprepare(jpeg->pm.venc_clk.clk_info->jpegenc_clk);
> >  	pm_runtime_put(ctx->jpeg->dev);
> >  	if (ctx->fh.m2m_ctx &&
> > -- 
> > 2.6.4
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek
> > 

From anshuman.khandual at arm.com  Thu Jan  6 01:10:00 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 6 Jan 2022 14:40:00 +0530
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <298ad877-56ea-58f8-02ed-a9edd7608c12@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
 <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>
 <68961242-3d9b-a26d-3a0f-0d2ace04a17b@arm.com>
 <298ad877-56ea-58f8-02ed-a9edd7608c12@arm.com>
Message-ID: <45c01144-40b1-f901-9c50-7e755dbca94c@arm.com>



On 1/5/22 7:24 PM, Suzuki K Poulose wrote:
> On 05/01/2022 11:16, Anshuman Khandual wrote:
>>
>>
>> On 1/5/22 3:43 PM, Suzuki K Poulose wrote:
>>> Hi Anshuman
>>>
>>> On 05/01/2022 05:05, Anshuman Khandual wrote:
>>>> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
>>>> an inconsistent view on whether trace is prohibited within the CPU. As a
>>>> result, the trace buffer or trace buffer state might be corrupted. This
>>>> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
>>>> followed by just a single context synchronization event before execution
>>>> changes from a context, in which trace is prohibited to one where it isn't,
>>>> or vice versa. In these mentioned conditions, the view of whether trace is
>>>> prohibited is inconsistent between parts of the CPU, and the trace buffer
>>>> or the trace buffer state might be corrupted.
>>>>
>>>> Work around this problem in the TRBE driver by preventing an inconsistent
>>>> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
>>>> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
>>>> instruction before an ERET, or two ISB instructions if no ERET is to take
>>>> place. This adds a new cpu errata in arm64 errata framework and also
>>>> updates TRBE driver as required.
>>>>
>>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>>> Cc: Will Deacon <will at kernel.org>
>>>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>>>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>>>> Cc: coresight at lists.linaro.org
>>>> Cc: linux-doc at vger.kernel.org
>>>> Cc: linux-arm-kernel at lists.infradead.org
>>>> Cc: linux-kernel at vger.kernel.org
>>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>>> ---
>>>> ?? Documentation/arm64/silicon-errata.rst?????? |? 2 +
>>>> ?? arch/arm64/Kconfig?????????????????????????? | 23 ++++++++++
>>>> ?? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 ++++
>>>> ?? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>>>> ?? drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>>>> ?? 5 files changed, 72 insertions(+), 10 deletions(-)
>>>
>>> As with the previous patch, it may be a good idea to split the
>>> patch to arm64 and trbe parts.
>>
>> Sure, will do.
>>
>>>
>>>>
>>>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>>>> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
>>>> --- a/Documentation/arm64/silicon-errata.rst
>>>> +++ b/Documentation/arm64/silicon-errata.rst
>>>> @@ -54,6 +54,8 @@ stable kernels.
>>>> ?? +----------------+-----------------+-----------------+-----------------------------+
>>>> ?? | ARM??????????? | Cortex-A510???? | #2064142??????? | ARM64_ERRATUM_2064142?????? |
>>>> ?? +----------------+-----------------+-----------------+-----------------------------+
>>>> +| ARM??????????? | Cortex-A510???? | #2038923??????? | ARM64_ERRATUM_2038923?????? |
>>>> ++----------------+-----------------+-----------------+-----------------------------+
>>>> ?? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>>>> ?? +----------------+-----------------+-----------------+-----------------------------+
>>>> ?? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>> index 2105b68d88db..026e34fb6fad 100644
>>>> --- a/arch/arm64/Kconfig
>>>> +++ b/arch/arm64/Kconfig
>>>> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>>>> ?? ??????? If unsure, say Y.
>>>> ?? +config ARM64_ERRATUM_2038923
>>>> +??? bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
>>>> +??? depends on CORESIGHT_TRBE
>>>> +??? default y
>>>> +??? help
>>>> +????? This option adds the workaround for ARM Cortex-A510 erratum 2038923.
>>>> +
>>>> +????? Affected Cortex-A510 core might cause an inconsistent view on whether trace is
>>>> +????? prohibited within the CPU. As a result, the trace buffer or trace buffer state
>>>> +????? might be corrupted. This happens after TRBE buffer has been enabled by setting
>>>> +????? TRBLIMITR_EL1.E, followed by just a single context synchronization event before
>>>> +????? execution changes from a context, in which trace is prohibited to one where it
>>>> +????? isn't, or vice versa. In these mentioned conditions, the view of whether trace
>>>> +????? is prohibited is inconsistent between parts of the CPU, and the trace buffer or
>>>> +????? the trace buffer state might be corrupted.
>>>> +
>>>> +????? Work around this in the driver by preventing an inconsistent view of whether the
>>>> +????? trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
>>>> +????? change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
>>>> +????? two ISB instructions if no ERET is to take place.
>>>> +
>>>> +????? If unsure, say Y.
>>>> +
>>>> ?? config CAVIUM_ERRATUM_22375
>>>> ?????? bool "Cavium erratum 22375, 24313"
>>>> ?????? default y
>>>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>>>> index cbb7d5a9aee7..60b0c1f1d912 100644
>>>> --- a/arch/arm64/kernel/cpu_errata.c
>>>> +++ b/arch/arm64/kernel/cpu_errata.c
>>>> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>>> ?????????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>>> ?????? },
>>>> ?? #endif
>>>> +#ifdef CONFIG_ARM64_ERRATUM_2038923
>>>> +??? {
>>>> +??????? .desc = "ARM erratum 2038923",
>>>> +??????? .capability = ARM64_WORKAROUND_2038923,
>>>> +
>>>> +??????? /* Cortex-A510 r0p0 - r0p2 */
>>>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>>> +??? },
>>>> +#endif
>>>> ?????? {
>>>> ?????? }
>>>> ?? };
>>>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>>>> index fca3cb329e1d..45a06d36d080 100644
>>>> --- a/arch/arm64/tools/cpucaps
>>>> +++ b/arch/arm64/tools/cpucaps
>>>> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>>>> ?? WORKAROUND_1508412
>>>> ?? WORKAROUND_1542419
>>>> ?? WORKAROUND_2064142
>>>> +WORKAROUND_2038923
>>>> ?? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>>>> ?? WORKAROUND_TSB_FLUSH_FAILURE
>>>> ?? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>>>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>>>> index ec24b62b2cec..0689c6dab96d 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>>>> @@ -92,11 +92,13 @@ struct trbe_buf {
>>>> ?? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>>>> ?? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>>>> ?? #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>>>> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE??? 3
>>>> ?? ? static int trbe_errata_cpucaps[] = {
>>>> ?????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>>>> ?????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>>>> ?????? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>>>> +??? [TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>>>> ?????? -1,??????? /* Sentinel, must be the last entry */
>>>> ?? };
>>>> ?? @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>>>> ?????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>>>> ?? }
>>>> ?? +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>>>> +{
>>>
>>> minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?
>>
>> trbe_needs_ctxt_sync_after_enable() sounds better. Also will have to change
>> the index above as well .. TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE.
>>
>>>
>>>> +??? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>>>> +}
>>>> +
>>>> ?? static int trbe_alloc_node(struct perf_event *event)
>>>> ?? {
>>>> ?????? if (event->cpu == -1)
>>>> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>>>> ?????? dsb(nsh);
>>>> ?? }
>>>> ?? +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
>>>> +{
>>>> +??? u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>>>
>>> minor nit: This implies we do the TRBE programming in the following
>>> manner in the common case (i.e, TRBE enabled in the beginning of a
>>> session).
>>> ?? -> set TRBE LIMIT
>>> ?? -> read TRBE LIMIT
>>> ?? -> set TRBE ENABLED
>>>
>>> Could we please optimize this ? I believe the buf->trbe_limit
>>> must hold the LIMITR value at any point in time. And thus this
>>
>> But is not bit risky though ! We have got the following places where
>> given trbe_limit instance changes its value.
>>
>> drivers/../coresight-trbe.c:?? buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE;
>> drivers/../coresight-trbe.c:?? buf->trbe_limit = compute_trbe_buffer_limit(handle);
>> drivers/../coresight-trbe.c:?? buf->trbe_limit -= PAGE_SIZE;
> 
> Those are the places where we compute the trbe_limit, *before*
> we enable the TRBE. And we don't change recompute the limit
> *without disabling* the TRBE. To make it more clear, the
> only place where we set TRBE enabled without "computing"
> the trbe_limit is when we hit a spurious interrupt.
> But the value in the TRBLIMITR should already match the
> buf->trbe_limit and we are only going to re-enable the
> TRBE with the same limit. The other option is to
> pass down the "limit" to the set_trbe_enabled().

Since there are just two instances where set_trbe_enabled() gets
called, passing down an additional parameter 'trblimitr' should
still be okay. Some additional code change (like the following)
will achieve this. Does this look okay ?

--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -201,10 +201,8 @@ static inline void trbe_drain_buffer(void)
        dsb(nsh);
 }
 
-static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
+static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
 {
-       u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
-
        /*
         * Enable the TRBE without clearing LIMITPTR which
         * might be required for fetching the buffer limits.
@@ -626,7 +624,7 @@ static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
        trblimitr |= (addr & PAGE_MASK);
 
        write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-       set_trbe_enabled(buf->cpudata);
+       set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static void trbe_enable_hw(struct trbe_buf *buf)
@@ -1050,13 +1048,14 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 static void trbe_handle_spurious(struct perf_output_handle *handle)
 {
        struct trbe_buf *buf = etm_perf_sink_config(handle);
+       u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
        /*
         * If the IRQ was spurious, simply re-enable the TRBE
         * back without modifying the buffer parameters to
         * retain the trace collected so far.
         */
-       set_trbe_enabled(buf->cpudata);
+       set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static int trbe_handle_overflow(struct perf_output_handle *handle)

 
> 
>>
>>> function could simply be :
>>>
>>> set_trbe_enabled(trbe_buf)
>>> {
>>> ?????limitr = trbe_buf->limit | LIMITR_ENABLE
>>> ?????write(limitr, TRBLIMITR_EL1);
>>> ?????...
>>> }
>>
>> Is the potential for performance improvement here, out weigh possible
>> risks of using buf->trbe_limit directly while enabling the TRBE ?
> 
> I somehow don't like the fact that we have additional write and read
> for the most common case of the TRBE usage (i.e, for arm_trbe_enable()).
> If we could avoid that, that may be better.
> 
> Cheers
> Suzuki


From chunfeng.yun at mediatek.com  Thu Jan  6 01:22:05 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 17:22:05 +0800
Subject: [PATCH 3/4] phy: mediatek: phy-mtk-hdmi: Reorder and stop
 implicit header inclusion
In-Reply-To: <20220103153055.50473-3-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
 <20220103153055.50473-3-angelogioacchino.delregno@collabora.com>
Message-ID: <c3773ed47126bf3810bc7d78e3ec293f144ccd7f.camel@mediatek.com>

On Mon, 2022-01-03 at 16:30 +0100, AngeloGioacchino Del Regno wrote:
> All the headers for phy-mtk-{hdmi,hdmi-mt2701,hdmi-mt8183}.c were
> included from phy-mtk-mipi-dsi.h, but this isn't optimal: in order to
> increase readability and sensibly reduce build times, the inclusions
> should be done per-file, also avoiding to include unused headers and
> should not be implicit.
> 
> For this reason, move the inclusions to each file and remove unused
> ones.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c |  5 +++++
>  drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c |  5 +++++
>  drivers/phy/mediatek/phy-mtk-hdmi.c        |  8 ++++++++
>  drivers/phy/mediatek/phy-mtk-hdmi.h        | 10 +---------
>  4 files changed, 19 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> index 09e0dd7499d8..270c5f538483 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c
> @@ -4,6 +4,11 @@
>   * Author: Chunhui Dai <chunhui.dai at mediatek.com>
>   */
>  
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
>  #include "phy-mtk-hdmi.h"
>  
>  #define HDMI_CON0	0x00
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> index e317bf4a9db9..87ba9a3687b7 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c
> @@ -4,6 +4,11 @@
>   * Author: Jie Qiu <jie.qiu at mediatek.com>
>   */
>  
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
>  #include "phy-mtk-hdmi.h"
>  
>  #define HDMI_CON0		0x00
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c
> b/drivers/phy/mediatek/phy-mtk-hdmi.c
> index b4193cb4e4e3..e037fa89696c 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
> @@ -4,6 +4,14 @@
>   * Author: Jie Qiu <jie.qiu at mediatek.com>
>   */
>  
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/regmap.h>
> +#include <linux/phy/phy.h>
>  #include "phy-mtk-hdmi.h"
>  
>  inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.h
> b/drivers/phy/mediatek/phy-mtk-hdmi.h
> index a0571271d730..ef81e44a235d 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.h
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.h
> @@ -6,17 +6,9 @@
>  
>  #ifndef _MTK_HDMI_PHY_H
>  #define _MTK_HDMI_PHY_H
> -#include <linux/clk.h>
> +
>  #include <linux/clk-provider.h>
> -#include <linux/delay.h>
> -#include <linux/io.h>
> -#include <linux/mfd/syscon.h>
> -#include <linux/module.h>
> -#include <linux/of_device.h>
> -#include <linux/phy/phy.h>
> -#include <linux/platform_device.h>
>  #include <linux/regmap.h>
> -#include <linux/types.h>
Please do not move common headers also into .c files

>  
>  struct mtk_hdmi_phy;
>  

From chunfeng.yun at mediatek.com  Thu Jan  6 01:13:43 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 17:13:43 +0800
Subject: [PATCH 3/3] phy: mediatek: phy-mtk-mipi-dsi: Simplify with
 dev_err_probe()
In-Reply-To: <20220103145324.48008-3-angelogioacchino.delregno@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
 <20220103145324.48008-3-angelogioacchino.delregno@collabora.com>
Message-ID: <4d7195c3ac9bc63a5f980548f0c880484403346d.camel@mediatek.com>

On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> Use the dev_err_probe() helper to simplify error handling during
> probe.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 29 +++++++++------------
> ----
>  1 file changed, 10 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> index 6f7425b0bf5b..4b77508f5241 100644
> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> @@ -148,11 +148,9 @@ static int mtk_mipi_tx_probe(struct
> platform_device *pdev)
>  		return PTR_ERR(mipi_tx->regmap);
>  
>  	ref_clk = devm_clk_get(dev, NULL);
> -	if (IS_ERR(ref_clk)) {
> -		ret = PTR_ERR(ref_clk);
> -		dev_err(dev, "Failed to get reference clock: %d\n",
> ret);
> -		return ret;
> -	}
> +	if (IS_ERR(ref_clk))
> +		return dev_err_probe(dev, PTR_ERR(ref_clk),
> +				     "Failed to get reference
> clock\n");
>  
>  	ret = of_property_read_u32(dev->of_node, "drive-strength-
> microamp",
>  				   &mipi_tx->mipitx_drive);
> @@ -172,27 +170,20 @@ static int mtk_mipi_tx_probe(struct
> platform_device *pdev)
>  
>  	ret = of_property_read_string(dev->of_node, "clock-output-
> names",
>  				      &clk_init.name);
> -	if (ret < 0) {
> -		dev_err(dev, "Failed to read clock-output-names: %d\n",
> ret);
> -		return ret;
> -	}
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to read clock-
> output-names\n");
Seems no need change it here. (no EPROBE_DEFER error)

Thanks
>  
>  	clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops;
>  
>  	mipi_tx->pll_hw.init = &clk_init;
>  	mipi_tx->pll = devm_clk_register(dev, &mipi_tx->pll_hw);
> -	if (IS_ERR(mipi_tx->pll)) {
> -		ret = PTR_ERR(mipi_tx->pll);
> -		dev_err(dev, "Failed to register PLL: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(mipi_tx->pll))
> +		return dev_err_probe(dev, PTR_ERR(mipi_tx->pll),
> "Cannot register PLL\n");
>  
>  	phy = devm_phy_create(dev, NULL, &mtk_mipi_tx_ops);
> -	if (IS_ERR(phy)) {
> -		ret = PTR_ERR(phy);
> -		dev_err(dev, "Failed to create MIPI D-PHY: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to
> create MIPI D-PHY\n");
> +
>  	phy_set_drvdata(phy, mipi_tx);
>  
>  	phy_provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);

From chunfeng.yun at mediatek.com  Thu Jan  6 01:24:07 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 17:24:07 +0800
Subject: [PATCH 2/4] phy: mediatek: phy-mtk-hdmi: Reorder to remove
 forward declarations
In-Reply-To: <20220103153055.50473-2-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
 <20220103153055.50473-2-angelogioacchino.delregno@collabora.com>
Message-ID: <3a1bffc6f677ef9790749a366424fe5effda90f7.camel@mediatek.com>

On Mon, 2022-01-03 at 16:30 +0100, AngeloGioacchino Del Regno wrote:
> Forward declarations for mtk_hdmi_power_{on,off} aren't necessary:
> move mtk_hdmi_phy_dev_ops down to remove forward declarations.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-hdmi.c | 15 ++++++---------
>  1 file changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c
> b/drivers/phy/mediatek/phy-mtk-hdmi.c
> index 707e90691e6e..b4193cb4e4e3 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
> @@ -6,15 +6,6 @@
>  
>  #include "phy-mtk-hdmi.h"
>  
> -static int mtk_hdmi_phy_power_on(struct phy *phy);
> -static int mtk_hdmi_phy_power_off(struct phy *phy);
> -
> -static const struct phy_ops mtk_hdmi_phy_dev_ops = {
> -	.power_on = mtk_hdmi_phy_power_on,
> -	.power_off = mtk_hdmi_phy_power_off,
> -	.owner = THIS_MODULE,
> -};
> -
>  inline struct mtk_hdmi_phy *to_mtk_hdmi_phy(struct clk_hw *hw)
>  {
>  	return container_of(hw, struct mtk_hdmi_phy, pll_hw);
> @@ -43,6 +34,12 @@ static int mtk_hdmi_phy_power_off(struct phy *phy)
>  	return 0;
>  }
>  
> +static const struct phy_ops mtk_hdmi_phy_dev_ops = {
> +	.power_on = mtk_hdmi_phy_power_on,
> +	.power_off = mtk_hdmi_phy_power_off,
> +	.owner = THIS_MODULE,
> +};
> +
>  static const struct phy_ops *
>  mtk_hdmi_phy_dev_get_ops(const struct mtk_hdmi_phy *hdmi_phy)
>  {
Reviewed-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Thanks a lot


From chunfeng.yun at mediatek.com  Thu Jan  6 01:20:22 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 6 Jan 2022 17:20:22 +0800
Subject: [PATCH 4/4] phy: mediatek: phy-mtk-hdmi: Simplify with
 dev_err_probe()
In-Reply-To: <20220103153055.50473-4-angelogioacchino.delregno@collabora.com>
References: <20220103153055.50473-1-angelogioacchino.delregno@collabora.com>
 <20220103153055.50473-4-angelogioacchino.delregno@collabora.com>
Message-ID: <78652a88b24bb4c4660d7c7fa31d4dd7b9fe5a46.camel@mediatek.com>

On Mon, 2022-01-03 at 16:30 +0100, AngeloGioacchino Del Regno wrote:
> Use the dev_err_probe() helper to simplify error handling during
> probe.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/phy/mediatek/phy-mtk-hdmi.c | 50 +++++++++++--------------
> ----
>  1 file changed, 19 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-hdmi.c
> b/drivers/phy/mediatek/phy-mtk-hdmi.c
> index e037fa89696c..4f40a6eea004 100644
> --- a/drivers/phy/mediatek/phy-mtk-hdmi.c
> +++ b/drivers/phy/mediatek/phy-mtk-hdmi.c
> @@ -104,20 +104,16 @@ static int mtk_hdmi_phy_probe(struct
> platform_device *pdev)
>  		return PTR_ERR(hdmi_phy->regmap);
>  
>  	ref_clk = devm_clk_get(dev, "pll_ref");
> -	if (IS_ERR(ref_clk)) {
> -		ret = PTR_ERR(ref_clk);
> -		dev_err(&pdev->dev, "Failed to get PLL reference clock:
> %d\n",
> -			ret);
> -		return ret;
> -	}
> +	if (IS_ERR(ref_clk))
> +		return dev_err_probe(dev, PTR_ERR(ref_clk),
> +				     "Failed to get PLL reference
> clock\n");
> +
>  	ref_clk_name = __clk_get_name(ref_clk);
>  
>  	ret = of_property_read_string(dev->of_node, "clock-output-
> names",
>  				      &clk_init.name);
> -	if (ret < 0) {
> -		dev_err(dev, "Failed to read clock-output-names: %d\n",
> ret);
> -		return ret;
> -	}
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to read clock-
> output-names\n");
Seems no need change it if no EPROBE_DEFER happens

>  
>  	hdmi_phy->dev = dev;
>  	hdmi_phy->conf =
> @@ -125,25 +121,19 @@ static int mtk_hdmi_phy_probe(struct
> platform_device *pdev)
>  	mtk_hdmi_phy_clk_get_data(hdmi_phy, &clk_init);
>  	hdmi_phy->pll_hw.init = &clk_init;
>  	hdmi_phy->pll = devm_clk_register(dev, &hdmi_phy->pll_hw);
> -	if (IS_ERR(hdmi_phy->pll)) {
> -		ret = PTR_ERR(hdmi_phy->pll);
> -		dev_err(dev, "Failed to register PLL: %d\n", ret);
> -		return ret;
> -	}
> +	if (IS_ERR(hdmi_phy->pll))
> +		return dev_err_probe(dev, PTR_ERR(hdmi_phy->pll),
> +				    "Failed to register PLL\n");
>  
>  	ret = of_property_read_u32(dev->of_node, "mediatek,ibias",
>  				   &hdmi_phy->ibias);
> -	if (ret < 0) {
> -		dev_err(&pdev->dev, "Failed to get ibias: %d\n", ret);
> -		return ret;
> -	}
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to get
> ibias\n");
ditto

Thanks
>  
>  	ret = of_property_read_u32(dev->of_node, "mediatek,ibias_up",
>  				   &hdmi_phy->ibias_up);
> -	if (ret < 0) {
> -		dev_err(&pdev->dev, "Failed to get ibias up: %d\n",
> ret);
> -		return ret;
> -	}
> +	if (ret < 0)
> +		return dev_err_probe(dev, ret, "Failed to get
> ibias_up\n");
>  
>  	dev_info(dev, "Using default TX DRV impedance: 4.2k/36\n");
>  	hdmi_phy->drv_imp_clk = 0x30;
> @@ -152,17 +142,15 @@ static int mtk_hdmi_phy_probe(struct
> platform_device *pdev)
>  	hdmi_phy->drv_imp_d0 = 0x30;
>  
>  	phy = devm_phy_create(dev, NULL,
> mtk_hdmi_phy_dev_get_ops(hdmi_phy));
> -	if (IS_ERR(phy)) {
> -		dev_err(dev, "Failed to create HDMI PHY\n");
> -		return PTR_ERR(phy);
> -	}
> +	if (IS_ERR(phy))
> +		return dev_err_probe(dev, PTR_ERR(phy), "Cannot create
> HDMI PHY\n");
> +
>  	phy_set_drvdata(phy, hdmi_phy);
>  
>  	phy_provider = devm_of_phy_provider_register(dev,
> of_phy_simple_xlate);
> -	if (IS_ERR(phy_provider)) {
> -		dev_err(dev, "Failed to register HDMI PHY\n");
> -		return PTR_ERR(phy_provider);
> -	}
> +	if (IS_ERR(phy_provider))
> +		return dev_err_probe(dev, PTR_ERR(phy_provider),
> +				     "Failed to register HDMI PHY\n");
>  
>  	if (hdmi_phy->conf->pll_default_off)
>  		hdmi_phy->conf->hdmi_phy_disable_tmds(hdmi_phy);

From suzuki.poulose at arm.com  Thu Jan  6 01:40:15 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Thu, 6 Jan 2022 09:40:15 +0000
Subject: [PATCH 3/4] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <45c01144-40b1-f901-9c50-7e755dbca94c@arm.com>
References: <1641359159-22726-1-git-send-email-anshuman.khandual@arm.com>
 <1641359159-22726-4-git-send-email-anshuman.khandual@arm.com>
 <77d59823-b975-e3ba-3aa4-fac5c61bb69f@arm.com>
 <68961242-3d9b-a26d-3a0f-0d2ace04a17b@arm.com>
 <298ad877-56ea-58f8-02ed-a9edd7608c12@arm.com>
 <45c01144-40b1-f901-9c50-7e755dbca94c@arm.com>
Message-ID: <4940d639-757f-5242-ba31-fd53ca13b461@arm.com>

On 06/01/2022 09:10, Anshuman Khandual wrote:
> 
> 
> On 1/5/22 7:24 PM, Suzuki K Poulose wrote:
>> On 05/01/2022 11:16, Anshuman Khandual wrote:
>>>
>>>
>>> On 1/5/22 3:43 PM, Suzuki K Poulose wrote:
>>>> Hi Anshuman
>>>>
>>>> On 05/01/2022 05:05, Anshuman Khandual wrote:
>>>>> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
>>>>> an inconsistent view on whether trace is prohibited within the CPU. As a
>>>>> result, the trace buffer or trace buffer state might be corrupted. This
>>>>> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
>>>>> followed by just a single context synchronization event before execution
>>>>> changes from a context, in which trace is prohibited to one where it isn't,
>>>>> or vice versa. In these mentioned conditions, the view of whether trace is
>>>>> prohibited is inconsistent between parts of the CPU, and the trace buffer
>>>>> or the trace buffer state might be corrupted.
>>>>>
>>>>> Work around this problem in the TRBE driver by preventing an inconsistent
>>>>> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
>>>>> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
>>>>> instruction before an ERET, or two ISB instructions if no ERET is to take
>>>>> place. This adds a new cpu errata in arm64 errata framework and also
>>>>> updates TRBE driver as required.
>>>>>
>>>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>>>> Cc: Will Deacon <will at kernel.org>
>>>>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>>>>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>>>>> Cc: coresight at lists.linaro.org
>>>>> Cc: linux-doc at vger.kernel.org
>>>>> Cc: linux-arm-kernel at lists.infradead.org
>>>>> Cc: linux-kernel at vger.kernel.org
>>>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>>>> ---
>>>>>  ?? Documentation/arm64/silicon-errata.rst?????? |? 2 +
>>>>>  ?? arch/arm64/Kconfig?????????????????????????? | 23 ++++++++++
>>>>>  ?? arch/arm64/kernel/cpu_errata.c?????????????? |? 9 ++++
>>>>>  ?? arch/arm64/tools/cpucaps???????????????????? |? 1 +
>>>>>  ?? drivers/hwtracing/coresight/coresight-trbe.c | 47 +++++++++++++++-----
>>>>>  ?? 5 files changed, 72 insertions(+), 10 deletions(-)
>>>>
>>>> As with the previous patch, it may be a good idea to split the
>>>> patch to arm64 and trbe parts.
>>>
>>> Sure, will do.
>>>
>>>>
>>>>>
>>>>> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
>>>>> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
>>>>> --- a/Documentation/arm64/silicon-errata.rst
>>>>> +++ b/Documentation/arm64/silicon-errata.rst
>>>>> @@ -54,6 +54,8 @@ stable kernels.
>>>>>  ?? +----------------+-----------------+-----------------+-----------------------------+
>>>>>  ?? | ARM??????????? | Cortex-A510???? | #2064142??????? | ARM64_ERRATUM_2064142?????? |
>>>>>  ?? +----------------+-----------------+-----------------+-----------------------------+
>>>>> +| ARM??????????? | Cortex-A510???? | #2038923??????? | ARM64_ERRATUM_2038923?????? |
>>>>> ++----------------+-----------------+-----------------+-----------------------------+
>>>>>  ?? | ARM??????????? | Cortex-A53????? | #826319???????? | ARM64_ERRATUM_826319??????? |
>>>>>  ?? +----------------+-----------------+-----------------+-----------------------------+
>>>>>  ?? | ARM??????????? | Cortex-A53????? | #827319???????? | ARM64_ERRATUM_827319??????? |
>>>>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>>>>> index 2105b68d88db..026e34fb6fad 100644
>>>>> --- a/arch/arm64/Kconfig
>>>>> +++ b/arch/arm64/Kconfig
>>>>> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>>>>>  ?? ??????? If unsure, say Y.
>>>>>  ?? +config ARM64_ERRATUM_2038923
>>>>> +??? bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
>>>>> +??? depends on CORESIGHT_TRBE
>>>>> +??? default y
>>>>> +??? help
>>>>> +????? This option adds the workaround for ARM Cortex-A510 erratum 2038923.
>>>>> +
>>>>> +????? Affected Cortex-A510 core might cause an inconsistent view on whether trace is
>>>>> +????? prohibited within the CPU. As a result, the trace buffer or trace buffer state
>>>>> +????? might be corrupted. This happens after TRBE buffer has been enabled by setting
>>>>> +????? TRBLIMITR_EL1.E, followed by just a single context synchronization event before
>>>>> +????? execution changes from a context, in which trace is prohibited to one where it
>>>>> +????? isn't, or vice versa. In these mentioned conditions, the view of whether trace
>>>>> +????? is prohibited is inconsistent between parts of the CPU, and the trace buffer or
>>>>> +????? the trace buffer state might be corrupted.
>>>>> +
>>>>> +????? Work around this in the driver by preventing an inconsistent view of whether the
>>>>> +????? trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
>>>>> +????? change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
>>>>> +????? two ISB instructions if no ERET is to take place.
>>>>> +
>>>>> +????? If unsure, say Y.
>>>>> +
>>>>>  ?? config CAVIUM_ERRATUM_22375
>>>>>  ?????? bool "Cavium erratum 22375, 24313"
>>>>>  ?????? default y
>>>>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>>>>> index cbb7d5a9aee7..60b0c1f1d912 100644
>>>>> --- a/arch/arm64/kernel/cpu_errata.c
>>>>> +++ b/arch/arm64/kernel/cpu_errata.c
>>>>> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>>>>>  ?????????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>>>>  ?????? },
>>>>>  ?? #endif
>>>>> +#ifdef CONFIG_ARM64_ERRATUM_2038923
>>>>> +??? {
>>>>> +??????? .desc = "ARM erratum 2038923",
>>>>> +??????? .capability = ARM64_WORKAROUND_2038923,
>>>>> +
>>>>> +??????? /* Cortex-A510 r0p0 - r0p2 */
>>>>> +??????? ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>>>>> +??? },
>>>>> +#endif
>>>>>  ?????? {
>>>>>  ?????? }
>>>>>  ?? };
>>>>> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
>>>>> index fca3cb329e1d..45a06d36d080 100644
>>>>> --- a/arch/arm64/tools/cpucaps
>>>>> +++ b/arch/arm64/tools/cpucaps
>>>>> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>>>>>  ?? WORKAROUND_1508412
>>>>>  ?? WORKAROUND_1542419
>>>>>  ?? WORKAROUND_2064142
>>>>> +WORKAROUND_2038923
>>>>>  ?? WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>>>>>  ?? WORKAROUND_TSB_FLUSH_FAILURE
>>>>>  ?? WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>>>>> index ec24b62b2cec..0689c6dab96d 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>>>>> @@ -92,11 +92,13 @@ struct trbe_buf {
>>>>>  ?? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>>>>>  ?? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>>>>>  ?? #define TRBE_WORKAROUND_SYSREG_WRITE_FAILURE??? 2
>>>>> +#define TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE??? 3
>>>>>  ?? ? static int trbe_errata_cpucaps[] = {
>>>>>  ?????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>>>>>  ?????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>>>>>  ?????? [TRBE_WORKAROUND_SYSREG_WRITE_FAILURE] = ARM64_WORKAROUND_2064142,
>>>>> +??? [TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE] = ARM64_WORKAROUND_2038923,
>>>>>  ?????? -1,??????? /* Sentinel, must be the last entry */
>>>>>  ?? };
>>>>>  ?? @@ -174,6 +176,11 @@ static inline bool trbe_may_fail_sysreg_write(struct trbe_cpudata *cpudata)
>>>>>  ?????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_SYSREG_WRITE_FAILURE);
>>>>>  ?? }
>>>>>  ?? +static inline bool trbe_may_corrupt_with_enable(struct trbe_cpudata *cpudata)
>>>>> +{
>>>>
>>>> minor nit: trbe_needs_{ctxt_sync, isb}_after_enable() ?
>>>
>>> trbe_needs_ctxt_sync_after_enable() sounds better. Also will have to change
>>> the index above as well .. TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE.
>>>
>>>>
>>>>> +??? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE);
>>>>> +}
>>>>> +
>>>>>  ?? static int trbe_alloc_node(struct perf_event *event)
>>>>>  ?? {
>>>>>  ?????? if (event->cpu == -1)
>>>>> @@ -187,6 +194,30 @@ static inline void trbe_drain_buffer(void)
>>>>>  ?????? dsb(nsh);
>>>>>  ?? }
>>>>>  ?? +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
>>>>> +{
>>>>> +??? u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>>>>
>>>> minor nit: This implies we do the TRBE programming in the following
>>>> manner in the common case (i.e, TRBE enabled in the beginning of a
>>>> session).
>>>>  ?? -> set TRBE LIMIT
>>>>  ?? -> read TRBE LIMIT
>>>>  ?? -> set TRBE ENABLED
>>>>
>>>> Could we please optimize this ? I believe the buf->trbe_limit
>>>> must hold the LIMITR value at any point in time. And thus this
>>>
>>> But is not bit risky though ! We have got the following places where
>>> given trbe_limit instance changes its value.
>>>
>>> drivers/../coresight-trbe.c:?? buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE;
>>> drivers/../coresight-trbe.c:?? buf->trbe_limit = compute_trbe_buffer_limit(handle);
>>> drivers/../coresight-trbe.c:?? buf->trbe_limit -= PAGE_SIZE;
>>
>> Those are the places where we compute the trbe_limit, *before*
>> we enable the TRBE. And we don't change recompute the limit
>> *without disabling* the TRBE. To make it more clear, the
>> only place where we set TRBE enabled without "computing"
>> the trbe_limit is when we hit a spurious interrupt.
>> But the value in the TRBLIMITR should already match the
>> buf->trbe_limit and we are only going to re-enable the
>> TRBE with the same limit. The other option is to
>> pass down the "limit" to the set_trbe_enabled().
> 
> Since there are just two instances where set_trbe_enabled() gets
> called, passing down an additional parameter 'trblimitr' should
> still be okay. Some additional code change (like the following)
> will achieve this. Does this look okay ?
> 
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -201,10 +201,8 @@ static inline void trbe_drain_buffer(void)
>          dsb(nsh);
>   }
>   
> -static inline void set_trbe_enabled(struct trbe_cpudata *cpudata)
> +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
>   {
> -       u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
> -
>          /*
>           * Enable the TRBE without clearing LIMITPTR which
>           * might be required for fetching the buffer limits.
> @@ -626,7 +624,7 @@ static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
>          trblimitr |= (addr & PAGE_MASK);
>   
>          write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);

You could skip this ^ write. Otherwise looks good to me.

Suzuki

> -       set_trbe_enabled(buf->cpudata);
> +       set_trbe_enabled(buf->cpudata, trblimitr);
>   }
>   
>   static void trbe_enable_hw(struct trbe_buf *buf)
> @@ -1050,13 +1048,14 @@ static int arm_trbe_disable(struct coresight_device *csdev)
>   static void trbe_handle_spurious(struct perf_output_handle *handle)
>   {
>          struct trbe_buf *buf = etm_perf_sink_config(handle);
> +       u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>   
>          /*
>           * If the IRQ was spurious, simply re-enable the TRBE
>           * back without modifying the buffer parameters to
>           * retain the trace collected so far.
>           */
> -       set_trbe_enabled(buf->cpudata);
> +       set_trbe_enabled(buf->cpudata, trblimitr);
>   }
>   
>   static int trbe_handle_overflow(struct perf_output_handle *handle)
> 
>   
>>
>>>
>>>> function could simply be :
>>>>
>>>> set_trbe_enabled(trbe_buf)
>>>> {
>>>>  ?????limitr = trbe_buf->limit | LIMITR_ENABLE
>>>>  ?????write(limitr, TRBLIMITR_EL1);
>>>>  ?????...
>>>> }
>>>
>>> Is the potential for performance improvement here, out weigh possible
>>> risks of using buf->trbe_limit directly while enabling the TRBE ?
>>
>> I somehow don't like the fact that we have additional write and read
>> for the most common case of the TRBE usage (i.e, for arm_trbe_enable()).
>> If we could avoid that, that may be better.
>>
>> Cheers
>> Suzuki



From Jianyong.Wu at arm.com  Thu Jan  6 02:13:06 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Thu, 6 Jan 2022 10:13:06 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <YdXdjcJ7jbnkFsqp@arm.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
Message-ID: <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi Catalin,

I test this patch in your way using both EDK2 V2.6 and EDK2 v2.7. it's peculiar that this issue shows up on v2.6 but not on v2.7.
For now, I only find that if "CONFIG_DEBUG_LOCK_ALLOC" is enabled, the kernel boot will hang. However, I can't debug it by printk as this issue happens before pl11 is ready.
I will go on debugging, but very appreciated if someone can give some hints on it.

Thanks
Jianyong

> -----Original Message-----
> From: Catalin Marinas <catalin.marinas at arm.com>
> Sent: Thursday, January 6, 2022 2:04 AM
> To: Jianyong Wu <Jianyong.Wu at arm.com>
> Cc: will at kernel.org; Anshuman Khandual <Anshuman.Khandual at arm.com>;
> akpm at linux-foundation.org; david at redhat.com; quic_qiancai at quicinc.com;
> ardb at kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; Justin He
> <Justin.He at arm.com>; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Thu, Dec 16, 2021 at 04:28:12PM +0800, Jianyong Wu wrote:
> > The 'fixmap' is a global resource and is used recursively by create
> > pud mapping(), leading to a potential race condition in the presence
> > of a concurrent call to alloc_init_pud():
> >
> > kernel_init thread                          virtio-mem workqueue thread
> > ==================                          ===========================
> >
> >   alloc_init_pud(...)                       alloc_init_pud(...)
> >   pudp = pud_set_fixmap_offset(...)         pudp = pud_set_fixmap_offset(...)
> >   READ_ONCE(*pudp)
> >   pud_clear_fixmap(...)
> >                                             READ_ONCE(*pudp) // CRASH!
> >
> > As kernel may sleep during creating pud mapping, introduce a mutex
> > lock to serialise use of the fixmap entries by alloc_init_pud().
> >
> > Signed-off-by: Jianyong Wu <jianyong.wu at arm.com>
> 
> I tried to queue this patch but with certain configurations it doesn't boot
> under Qemu. Starting from defconfig, update .config with (I had this in one
> of my build scripts):
> 
> $ ./scripts/config \
> 		-e DEBUG_KERNEL \
> 		-e DEBUG_PAGEALLOC \
> 		-e DEBUG_PAGEALLOC_ENABLE_DEFAULT \
> 		-e DEBUG_WX \
> 		-e DEBUG_SET_MODULE_RONX \
> 		-e DEBUG_ALIGN_RODATA \
> 		-e ARM64_PTDUMP_DEBUGFS \
> 		-e DEBUG_OBJECTS \
> 		-e DEBUG_OBJECTS_FREE \
> 		-e DEBUG_OBJECTS_TIMERS \
> 		-e DEBUG_KOBJECT_RELEASE \
> 		-e DEBUG_LOCKING_API_SELFTESTS \
> 		-e DEBUG_PREEMPT \
> 		-e DEBUG_TIMEKEEPING \
> 		-e DEBUG_VM \
> 		-e DEBUG_VM_VMACACHE \
> 		-e DEBUG_VM_RB \
> 		-e DEBUG_VM_PGFLAGS \
> 		-e DEBUG_VIRTUAL \
> 		-e DEBUG_LIST \
> 		-e DEBUG_PI_LIST \
> 		-e DEBUG_SG \
> 		-e PROVE_LOCKING \
> 		-e DEBUG_RT_MUTEXES \
> 		-e DEBUG_ATOMIC_SLEEP \
> 		-e ATOMIC64_SELFTEST
> 
> It stop after exiting the EFI boot services. I did not have time to debug.
> 
> --
> Catalin


From will at kernel.org  Thu Jan  6 02:30:09 2022
From: will at kernel.org (Will Deacon)
Date: Thu, 6 Jan 2022 10:30:09 +0000
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <YdYDzKvYbBwjfU3W@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
 <20220105104526.GA3015@willie-the-truck>
 <YdYDzKvYbBwjfU3W@google.com>
Message-ID: <20220106103009.GA4420@willie-the-truck>

On Wed, Jan 05, 2022 at 01:47:08PM -0700, Yu Zhao wrote:
> On Wed, Jan 05, 2022 at 10:45:26AM +0000, Will Deacon wrote:
> > On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> > > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > > index 870c39537dd0..56e4ef5d95fa 100644
> > > --- a/arch/arm64/tools/cpucaps
> > > +++ b/arch/arm64/tools/cpucaps
> > > @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
> > >  HAS_SYSREG_GIC_CPUIF
> > >  HAS_TLB_RANGE
> > >  HAS_VIRT_HOST_EXTN
> > > +HW_AF
> > >  HW_DBM
> > >  KVM_PROTECTED_MODE
> > >  MISMATCHED_CACHE_TYPE
> > 
> > As discussed in the previous threads, we really don't need the complexity
> > of the additional cap for the arm64 part. Please can you just use the
> > existing code instead? It's both simpler and, as you say, it's equivalent
> > for existing hardware.
> > 
> > That way, this patch just ends up being a renaming exercise and we're all
> > good.
> 
> No, renaming alone isn't enough. A caller needs to disable preemption
> before calling system_has_hw_af(), and I don't think it's reasonable
> to ask this caller to do it on x86 as well.
> 
> It seems you really prefer not to have HW_AF. So the best I can
> accommodate, considering other potential archs, e.g., risc-v (I do
> plan to provide benchmark results on risc-v, btw), is:
> 
>   static inline bool arch_has_hw_pte_young(bool local)
>   {
> 	bool hw_af;
> 
>   	if (local) {
>   		WARN_ON(preemptible());
>   		return cpu_has_hw_af();
>   	}
>   
> 	preempt_disable();
>   	hw_af = system_has_hw_af();
> 	preempt_enable();
> 
> 	return hw_af;
>   }
> 
> Or please give me something else I can call without disabling
> preemption, sounds good?

Sure thing, let me take a look. Do you have your series on a public git
tree someplace?

Cheers,

Will


From festevam at gmail.com  Thu Jan  6 02:38:07 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 6 Jan 2022 07:38:07 -0300
Subject: [PATCH v5 5/6] PCI: imx6: Fix the regulator dump when link never
 came up
In-Reply-To: <AS8PR04MB867662FF5FC56A7613D509CC8C4C9@AS8PR04MB8676.eurprd04.prod.outlook.com>
References: <1641368602-20401-1-git-send-email-hongxing.zhu@nxp.com>
 <1641368602-20401-6-git-send-email-hongxing.zhu@nxp.com>
 <CAOMZO5AqgOOo3+r3yQSsfaNxW9eHXhCi=m+mqR=sf=K6dXA8tw@mail.gmail.com>
 <AS8PR04MB867662FF5FC56A7613D509CC8C4C9@AS8PR04MB8676.eurprd04.prod.outlook.com>
Message-ID: <CAOMZO5BY7BYQKqEgwj2XA-B-oCHbb2LFG8Zq1e4ca=sTb4=ceA@mail.gmail.com>

Hi Richard,

On Thu, Jan 6, 2022 at 12:49 AM Hongxing Zhu <hongxing.zhu at nxp.com> wrote:

> How about continue proceed your previous fix firstly?
> https://patchwork.kernel.org/project/linux-pci/patch/20211104000202.4028036-1-festevam at gmail.com/
> Then, I clean up the fix patch, and re-send my series later.
> Because that I still want to save power consumption as much as possible
>  when link is down.
> BTW, please remove the timestamp in your patch if you agree this method,
> and resend your patch.

Sure, this sounds good. I have just sent a v2.

Thanks


From jbrunet at baylibre.com  Thu Jan  6 02:41:21 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 06 Jan 2022 11:41:21 +0100
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
References: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
Message-ID: <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>


On Thu 06 Jan 2022 at 13:47, Xianwei Zhao <xianwei.zhao at amlogic.com> wrote:

> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
> It's capable of booting up into the serial console.
>
> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
> ---
> V2 -> V3: add of dts board  compatible family
> V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
>           and modify GIC reg defintions.
> ---
>  arch/arm64/boot/dts/amlogic/Makefile          |  1 +
>  .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
>  arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
>  3 files changed, 130 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>  create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index 5148cd9e5146..faea74a45994 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
>  dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> new file mode 100644
> index 000000000000..a942d7e06d6e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> @@ -0,0 +1,30 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-s4.dtsi"
> +
> +/ {
> +	model = "Amlogic Meson S4 AQ222 Development Board";
> +	compatible = "amlogic,aq222", "amlogic,s4";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		serial0 = &uart_B;
> +	};
> +
> +	memory at 00000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x0 0x0 0x40000000>;
> +	};
> +
> +};
> +
> +&uart_B {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> new file mode 100644
> index 000000000000..d7083c93d3d0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
> @@ -0,0 +1,99 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +	cpus:cpus {
            ^ space after : ?

Do we need the alias here ?

> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		CPU0:cpu at 0 {
                    ^ space after : ?

Why is the alias uppercase ?

same for the other nodes

> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x0>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU1:cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x1>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU2:cpu at 2 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x2>;
> +			enable-method = "psci";
> +		};
> +
> +		CPU3:cpu at 3 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35","arm,armv8";
> +			reg = <0x0 0x3>;
> +			enable-method = "psci";
> +		};
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-1.0";
> +		method = "smc";
> +	};
> +
> +	xtal: xtal-clk {
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "xtal";
> +		#clock-cells = <0>;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		gic: interrupt-controller at fff01000 {
> +			compatible = "arm,gic-400";
> +			#interrupt-cells = <3>;
> +			#address-cells = <0>;
> +			interrupt-controller;
> +			reg = <0x0 0xfff01000 0 0x1000>,
> +			      <0x0 0xfff02000 0 0x2000>,
> +			      <0x0 0xfff04000 0 0x2000>,
> +			      <0x0 0xfff06000 0 0x2000>;
> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
> +		};
> +
> +		apb4: apb4 at fe000000 {
> +			compatible = "simple-bus";
> +			reg = <0x0 0xfe000000 0x0 0x480000>;
> +			#address-cells = <2>;
> +			#size-cells = <2>;
> +			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
> +
> +			uart_B: serial at 7a000 {
> +				compatible = "amlogic,meson-s4-uart",
> +					     "amlogic,meson-ao-uart";
> +				reg = <0x0 0x7a000 0x0 0x18>;
> +				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
> +				status = "disabled";
> +				clocks = <&xtal>, <&xtal>, <&xtal>;
> +				clock-names = "xtal", "pclk", "baud";
> +			};
> +		};
> +	};
> +};
>
> base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152



From rong.chen at amlogic.com  Thu Jan  6 02:54:53 2022
From: rong.chen at amlogic.com (Rong Chen)
Date: Thu, 6 Jan 2022 18:54:53 +0800
Subject: [PATCH] mmc: meson: Fix usage of meson_mmc_post_req()
Message-ID: <20220106105453.3875119-1-rong.chen@amlogic.com>

To ensure the DMA moves data correctly from memory to
peripherals, DMA unmapping when the MMC request done
with calls meson_mmc_post_req().

Signed-off-by: Rong Chen <rong.chen at amlogic.com>
---
 drivers/mmc/host/meson-gx-mmc.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
index 8f36536cb1b6..6a9554ae4b1c 100644
--- a/drivers/mmc/host/meson-gx-mmc.c
+++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -173,6 +173,7 @@ struct meson_host {
 	int irq;
 
 	bool vqmmc_enabled;
+	bool needs_pre_post_req;
 };
 
 #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
@@ -663,6 +664,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
 	struct meson_host *host = mmc_priv(mmc);
 
 	host->cmd = NULL;
+	if (host->needs_pre_post_req)
+		meson_mmc_post_req(mmc, mrq, 0);
 	mmc_request_done(host->mmc, mrq);
 }
 
@@ -880,7 +883,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
 static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct meson_host *host = mmc_priv(mmc);
-	bool needs_pre_post_req = mrq->data &&
+	host->needs_pre_post_req = mrq->data &&
 			!(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
 
 	/*
@@ -896,22 +899,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 		}
 	}
 
-	if (needs_pre_post_req) {
+	if (host->needs_pre_post_req) {
 		meson_mmc_get_transfer_mode(mmc, mrq);
 		if (!meson_mmc_desc_chain_mode(mrq->data))
-			needs_pre_post_req = false;
+			host->needs_pre_post_req = false;
 	}
 
-	if (needs_pre_post_req)
+	if (host->needs_pre_post_req)
 		meson_mmc_pre_req(mmc, mrq);
 
 	/* Stop execution */
 	writel(0, host->regs + SD_EMMC_START);
 
 	meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
-
-	if (needs_pre_post_req)
-		meson_mmc_post_req(mmc, mrq, 0);
 }
 
 static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)

base-commit: 356f3f2c5756bbb67a515760966a40fc7043cdda
-- 
2.25.1



From andrey.zhizhikin at leica-geosystems.com  Thu Jan  6 02:56:12 2022
From: andrey.zhizhikin at leica-geosystems.com (ZHIZHIKIN Andrey)
Date: Thu, 6 Jan 2022 10:56:12 +0000
Subject: [PATCH v3 0/2] CAAM Driver: re-factor and set proper JR status
In-Reply-To: <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
Message-ID: <AM6PR06MB469129E72ED6FBE0B33C693DA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>

Hello Herbert,

Gentle ping on this V3. I see that in Patchwork this series state is set to "Deferred".

Is there anything missing here to proceed further?

> -----Original Message-----
> From: Andrey Zhizhikin <andrey.zhizhikin at leica-geosystems.com>
> Sent: Wednesday, December 8, 2021 12:02 AM
> To: linux-kernel at vger.kernel.org
> Cc: robh+dt at kernel.org; shawnguo at kernel.org; michael at walle.cc;
> s.hauer at pengutronix.de; kernel at pengutronix.de; festevam at gmail.com; linux-
> imx at nxp.com; horia.geanta at nxp.com; pankaj.gupta at nxp.com;
> herbert at gondor.apana.org.au; davem at davemloft.net; l.stach at pengutronix.de;
> qiangqing.zhang at nxp.com; peng.fan at nxp.com; alice.guo at nxp.com; aford173 at gmail.com;
> frieder.schrempf at kontron.de; krzk at kernel.org; shengjiu.wang at nxp.com;
> gregkh at linuxfoundation.org; ping.bai at nxp.com; daniel.baluta at nxp.com;
> jun.li at nxp.com; marex at denx.de; thunder.leizhen at huawei.com; martink at posteo.de;
> leonard.crestez at nxp.com; hongxing.zhu at nxp.com; agx at sigxcpu.org;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> crypto at vger.kernel.org; op-tee at lists.trustedfirmware.org; Andrey Zhizhikin
> <andrey.zhizhikin at leica-geosystems.com>
> Subject: [PATCH v3 0/2] CAAM Driver: re-factor and set proper JR status
> 
> This V3 series covers points uncovered during the review of the previous
> series, one major point being that register readout should not be used
> for dynamic JR availability check due to its unreliability.
> 
> Instead, JR should have a proper status set in FDT which indicates the
> availability of the ring in NS-World. This status is aligned with what
> BootROM code configures, and can be modified by all actors in the boot
> chain.
> 
> Therefore, patch in V2 series that was handling the dynamic JR
> availability check is dropped in this series and replaced by the patch
> which sets proper DT status for JR nodes.
> 
> Andrey Zhizhikin (2):
>   crypto: caam - convert to use capabilities
>   arm64: dts: imx8m: define proper status for caam jr
> 
>  arch/arm64/boot/dts/freescale/imx8mm.dtsi |   4 +
>  arch/arm64/boot/dts/freescale/imx8mn.dtsi |   4 +
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi |   4 +
>  arch/arm64/boot/dts/freescale/imx8mq.dtsi |   4 +
>  drivers/crypto/caam/caamalg_qi.c          |   2 +-
>  drivers/crypto/caam/ctrl.c                | 115 ++++++++++++++--------
>  drivers/crypto/caam/intern.h              |  20 ++--
>  drivers/crypto/caam/jr.c                  |  19 +++-
>  drivers/crypto/caam/regs.h                |   2 -
>  9 files changed, 122 insertions(+), 52 deletions(-)
> 
> 
> base-commit: 04fe99a8d936d46a310ca61b8b63dc270962bf01
> --
> 2.25.1
> 

-- andrey

From catalin.marinas at arm.com  Thu Jan  6 03:00:54 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Jan 2022 11:00:54 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
Message-ID: <YdbL5kIzi0xqVTVd@arm.com>

Hi Jeremy,

On Wed, Jan 05, 2022 at 04:42:01PM -0600, Jeremy Linton wrote:
> On 1/4/22 11:32, Mark Brown wrote:
> > On Thu, Dec 09, 2021 at 11:10:48AM +0000, Szabolcs Nagy wrote:
> > > The 12/08/2021 18:23, Catalin Marinas wrote:
> > > > On Mon, Nov 15, 2021 at 03:27:10PM +0000, Mark Brown wrote:
> > > > > memory is already mapped with PROT_EXEC.  This series resolves this by
> > > > > handling the BTI property for both the interpreter and the main
> > > > > executable.
> > > > 
> > > > Given the silence on this series over the past months, I propose we drop
> > > > it. It's a bit unfortunate that systemd's MemoryDenyWriteExecute cannot
> > > > work with BTI but I also think the former is a pretty blunt hardening
> > > > mechanism (rejecting any mprotect(PROT_EXEC) regardless of the previous
> > > > attributes).
> > > 
> > > i still think it would be better if the kernel dealt with
> > > PROT_BTI for the exe loaded by the kernel.
> > 
> > The above message from Catalin isn't quite the full story here - my
> > understanding from backchannel is that there's concern from others that
> > we might be creating future issues by enabling PROT_BTI, especially in
> > the case where the same permissions issue prevents the dynamic linker
> > disabling PROT_BTI.  They'd therefore rather stick with the status quo
> > and not create any new ABI.  Unfortunately that's not something people
> > have been willing to say on the list, hopefully the above captures the
> > thinking well enough.
> > 
> > Personally I'm a bit ambivalent on this, I do see the potential issue
> > but I'm having trouble constructing an actual scenario and my instinct
> > is that since we handle PROT_EXEC we should also handle PROT_BTI for
> > consistency.
> 
> I'm hardly a security expert, but it seems to me that BTI hardens against a
> wider set of possible exploits than MDWE.

They are complementary features.

> Yet, we are silently turning it
> off for systemd services which are considered some of the most security
> critical things in the machine right now (ex:logind, etc). So despite
> 'systemd-analyze secuirty` flagging those services as the most secure ones
> on a system, they might actually be less secure.

Well, that's a distro decision. MDWE/MDWX is not something imposed by
the kernel but rather a seccomp bpf filter set up by systemd.

> It also seems that getting BTI turned on earlier, as this patch is doing is
> itself a win.
> 
> So, mentally i'm having a hard time balancing the hypothetical problem laid
> out, as it should only really exist in an environment similar to the MDWE
> one, since AFAIK, its possible today to just flip it back off unless MDWE
> stops that from happening.

That's a user ABI change and given that the first attempt was shown to
break with some combination of old loader and new main executable (or
the other way around), I'd rather keep things as they are.

> What are the the remaining alternatives? A new syscall? But that is by
> definition a new ABI,

A new ABI is better than changing the current ABI.

> and wouldn't benefit from having BTI turned on as early as this patch
> is doing.

In the absence of MDWX, it's not relevant how early the kernel turns BTI
on for the main executable. The dynamic loader would do this with an
mprotect() before actually executing any of the main code. Of course, we
assume there are no security bugs in the dynamic loader.

> Should we disable MDWE on a BTI machine? I'm
> not sure that is a good look, particularly if MDWE happens to successfully
> stop some exploit. AFAIK, MDWE+BTI are a good strong combination, it seems a
> shame if we can't get them both working together.

AFAICT MDWX wants (one of the filters) to prevent a previously writable
mapping from becoming executable through mprotect(PROT_EXEC). How common
is mprotect(PROT_EXEC|PROT_BTI) outside of the dynamic loader? I doubt
it is, especially in an MDWX environment. So can we not change the
filter to allow PROT_EXEC|PROT_BTI? If your code is already exploitable
to allow random syscalls, all bets are off anyway.

> I hesitate to suggest it, but maybe this patch should be conditional
> somehow, that way !systemd/MDWE machines can behave as they do today, and
> systemd/MDWE machines can request BTI be turned on by the kernel
> automatically?

That would be some big knob sysctl but I'm still not keen on toggling
the ABI like this.

-- 
Catalin


From tinghan.shen at mediatek.com  Thu Jan  6 03:14:55 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Thu, 6 Jan 2022 19:14:55 +0800
Subject: [PATCH v7 4/4] arm64: dts: Add mediatek SoC mt8195 and
 evaluation board
In-Reply-To: <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
References: <20211220121825.6446-1-tinghan.shen@mediatek.com>
 <20211220121825.6446-5-tinghan.shen@mediatek.com>
 <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
Message-ID: <18c342b20ccac520eabe8019562432030ddfe017.camel@mediatek.com>

On Thu, 2021-12-23 at 17:59 +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Mon, Dec 20, 2021 at 8:20 PM Tinghan Shen <
> tinghan.shen at mediatek.com> wrote:
> > 
> > Add basic chip support for mediatek mt8195.
> > 
> > Signed-off-by: Seiya Wang <seiya.wang at mediatek.com>
> > Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/Makefile       |    1 +
> >  arch/arm64/boot/dts/mediatek/mt8195-evb.dts |  209 ++++
> >  arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 1034
> > +++++++++++++++++++
> >  3 files changed, 1244 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/Makefile
> > b/arch/arm64/boot/dts/mediatek/Makefile
> > index 4f68ebed2e31..7aa08bb4c078 100644
> > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > @@ -32,4 +32,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-
> > krane-sku0.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
> > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > new file mode 100644
> > index 000000000000..e581c6bbead6
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > @@ -0,0 +1,209 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (C) 2021 MediaTek Inc.
> > + * Author: Seiya Wang <seiya.wang at mediatek.com>
> > + */
> > +/dts-v1/;
> > +#include "mt8195.dtsi"
> > +
> > +/ {
> > +       model = "MediaTek MT8195 evaluation board";
> > +       compatible = "mediatek,mt8195-evb", "mediatek,mt8195";
> > +
> > +       aliases {
> > +               serial0 = &uart0;
> > +       };
> > +
> > +       chosen {
> > +               stdout-path = "serial0:921600n8";
> > +       };
> > +
> > +       memory at 40000000 {
> > +               device_type = "memory";
> > +               reg = <0 0x40000000 0 0x80000000>;
> > +       };
> > +};
> > +
> > +&auxadc {
> > +       status = "okay";
> > +};
> > +
> > +&i2c0 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c0_pin>;
> > +       clock-frequency = <100000>;
> > +       status = "okay";
> > +};
> > +
> > +&i2c1 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c1_pin>;
> > +       clock-frequency = <400000>;
> > +       status = "okay";
> > +};
> > +
> > +&i2c2 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c2_pin>;
> > +       status = "disabled";
> > +};
> > +
> > +&i2c3 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c3_pin>;
> > +       status = "disabled";
> > +};
> 
> Is there any reason in particular to list "disabled" devices here?
> Are they part of some GPIO header? If they are not accessible, then
> it's better to not list them. If they are, please leave a comment
> about it.
> 
> > +
> > +&i2c4 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c4_pin>;
> > +       clock-frequency = <400000>;
> > +       status = "okay";
> > +};
> > +
> > +&i2c5 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c5_pin>;
> > +       status = "disabled";
> > +};
> > +
> > +&i2c6 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&i2c6_pin>;
> > +       clock-frequency = <400000>;
> > +       status = "disabled";
> > +};
> 
> Same here.
> 
> > +
> > +&nor_flash {
> > +       status = "okay";
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&nor_pins_default>;
> 
> Please add an empty line between properties and child device nodes.
> It helps
> with readability and also fits the style of other parts and other DT
> files.
> 
> > +       flash at 0 {
> > +               compatible = "jedec,spi-nor";
> > +               reg = <0>;
> > +               spi-max-frequency = <50000000>;
> > +       };
> > +};
> > +
> > +&pio {
> > +       i2c0_pin: i2c0-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
> > +                                <PINMUX_GPIO9__FUNC_SCL0>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> 
> Please use the MTK_PULL_SET_RSEL_* macros with the bias-pull-*
> properties.
> We spent a lot of time defining those.
> 
> > +                       mediatek,drive-strength-adv = <0>;
> 
> This property is not part of the DT binding.
> 
> > +                       drive-strength = <MTK_DRIVE_6mA>;
> 
> Please just use raw numbers here. MTK_DRIVE_6mA just translates to 6.
> The binding already specifies mA as the unit for "drive-strength".
> 
> > +               };
> > +       };
> 
> Above comments apply to all the other "pins" nodes.
> 
> Please add an empty line between different child device nodes. It
> helps
> with readability and also fits the style of other parts and other DT
> files.
> 
> > +       i2c1_pin: i2c1-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
> > +                                <PINMUX_GPIO11__FUNC_SCL1>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> > +                       mediatek,drive-strength-adv = <0>;
> > +                       drive-strength = <MTK_DRIVE_6mA>;
> > +               };
> > +       };
> > +       i2c2_pin: i2c2-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
> > +                                <PINMUX_GPIO13__FUNC_SCL2>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> > +                       mediatek,drive-strength-adv = <7>;
> > +               };
> > +       };
> > +       i2c3_pin: i2c3-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
> > +                                <PINMUX_GPIO15__FUNC_SCL3>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> > +                       mediatek,drive-strength-adv = <7>;
> > +               };
> > +       };
> > +       i2c4_pin: i2c4-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
> > +                                <PINMUX_GPIO17__FUNC_SCL4>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> > +                       mediatek,drive-strength-adv = <7>;
> > +               };
> > +       };
> > +       i2c5_pin: i2c5-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO29__FUNC_SCL5>,
> > +                                <PINMUX_GPIO30__FUNC_SDA5>;
> > +                       bias-pull-up = <1>;
> > +                       mediatek,rsel = <7>;
> > +                       mediatek,drive-strength-adv = <7>;
> > +               };
> > +       };
> > +       i2c6_pin: i2c6-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
> > +                                <PINMUX_GPIO26__FUNC_SCL6>;
> > +                       bias-pull-up = <1>;
> > +               };
> > +       };
> > +       i2c7_pin: i2c7-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO27__FUNC_SCL7>,
> > +                                <PINMUX_GPIO28__FUNC_SDA7>;
> > +                       bias-pull-up = <1>;
> > +               };
> > +       };
> > +       nor_pins_default: nor-pins {
> > +               pins0 {
> > +                       pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
> > +                                        <PINMUX_GPIO141__FUNC_SPIN
> > OR_CK>,
> > +                                        <PINMUX_GPIO143__FUNC_SPIN
> > OR_IO1>;
> > +                       bias-pull-down;
> > +               };
> > +               pins1 {
> > +                       pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>,
> > +                                    <PINMUX_GPIO130__FUNC_SPINOR_I
> > O2>,
> > +                                    <PINMUX_GPIO131__FUNC_SPINOR_I
> > O3>;
> > +                       bias-pull-up;
> > +               };
> > +       };
> > +       uart0_pin: uart0-pins {
> > +               pins {
> > +                       pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
> > +                               <PINMUX_GPIO99__FUNC_URXD0>;
> > +               };
> > +       };
> > +};
> > +
> > +&u2port0 {
> > +       status = "okay";
> > +};
> > +
> > +&u2port1 {
> > +       status = "okay";
> > +};
> > +
> > +&u3phy0 {
> > +       status="okay";
> > +};
> > +
> > +&u3phy1 {
> > +       status="okay";
> > +};
> > +
> > +&u3port0 {
> > +       status = "okay";
> > +};
> > +
> > +&u3port1 {
> > +       status = "okay";
> > +};
> > +
> > +&uart0 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&uart0_pin>;
> > +       status = "okay";
> > +};
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > new file mode 100644
> > index 000000000000..057a8492edec
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > @@ -0,0 +1,1034 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (c) 2021 MediaTek Inc.
> > + * Author: Seiya Wang <seiya.wang at mediatek.com>
> > + */
> > +
> > +/dts-v1/;
> > +#include <dt-bindings/clock/mt8195-clk.h>
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +#include <dt-bindings/phy/phy.h>
> > +#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
> > +#include <dt-bindings/reset/ti-syscon.h>
> > +
> > +/ {
> > +       compatible = "mediatek,mt8195";
> > +       interrupt-parent = <&gic>;
> > +       #address-cells = <2>;
> > +       #size-cells = <2>;
> > +
> > +       clk26m: oscillator0 {
> 
> Please order device nodes based on the node name ("oscillator0"),
> not the label. An exception to this would be the "soc" node, which
> most tend to keep as the last node in the list.
> 
> Also, naming them "oscillator-26m" and "oscillator-32k" would make
> more sense than "oscillatorN".
> 
> > +               compatible = "fixed-clock";
> > +               #clock-cells = <0>;
> > +               clock-frequency = <26000000>;
> > +               clock-output-names = "clk26m";
> > +       };
> > +
> > +       clk32k: oscillator1 {
> > +               compatible = "fixed-clock";
> > +               #clock-cells = <0>;
> > +               clock-frequency = <32768>;
> > +               clock-output-names = "clk32k";
> > +       };
> > +
> > +       cpus {
> > +               #address-cells = <1>;
> > +               #size-cells = <0>;
> > +
> > +               cpu0: cpu at 0 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55";
> > +                       reg = <0x000>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <1701000000>;
> > +                       capacity-dmips-mhz = <578>;
> > +                       cpu-idle-states = <&cpuoff_l
> > &clusteroff_l>;
> > +                       next-level-cache = <&l2_0>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu1: cpu at 100 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55";
> > +                       reg = <0x100>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <1701000000>;
> > +                       capacity-dmips-mhz = <578>;
> > +                       cpu-idle-states = <&cpuoff_l
> > &clusteroff_l>;
> > +                       next-level-cache = <&l2_0>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu2: cpu at 200 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55";
> > +                       reg = <0x200>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <1701000000>;
> > +                       capacity-dmips-mhz = <578>;
> > +                       cpu-idle-states = <&cpuoff_l
> > &clusteroff_l>;
> > +                       next-level-cache = <&l2_0>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu3: cpu at 300 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55";
> > +                       reg = <0x300>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <1701000000>;
> > +                       capacity-dmips-mhz = <578>;
> > +                       cpu-idle-states = <&cpuoff_l
> > &clusteroff_l>;
> > +                       next-level-cache = <&l2_0>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu4: cpu at 400 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a78";
> > +                       reg = <0x400>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2171000000>;
> > +                       capacity-dmips-mhz = <1024>;
> > +                       cpu-idle-states = <&cpuoff_b
> > &clusteroff_b>;
> > +                       next-level-cache = <&l2_1>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu5: cpu at 500 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a78";
> > +                       reg = <0x500>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2171000000>;
> > +                       capacity-dmips-mhz = <1024>;
> > +                       cpu-idle-states = <&cpuoff_b
> > &clusteroff_b>;
> > +                       next-level-cache = <&l2_1>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu6: cpu at 600 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a78";
> > +                       reg = <0x600>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2171000000>;
> > +                       capacity-dmips-mhz = <1024>;
> > +                       cpu-idle-states = <&cpuoff_b
> > &clusteroff_b>;
> > +                       next-level-cache = <&l2_1>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu7: cpu at 700 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a78";
> > +                       reg = <0x700>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2171000000>;
> > +                       capacity-dmips-mhz = <1024>;
> > +                       cpu-idle-states = <&cpuoff_b
> > &clusteroff_b>;
> > +                       next-level-cache = <&l2_1>;
> > +                       #cooling-cells = <2>;
> > +               };
> > +
> > +               cpu-map {
> > +                       cluster0 {
> > +                               core0 {
> > +                                       cpu = <&cpu0>;
> > +                               };
> 
> Please add an empty line between child nodes. This aids in
> readability.
> 
> > +                               core1 {
> > +                                       cpu = <&cpu1>;
> > +                               };
> > +                               core2 {
> > +                                       cpu = <&cpu2>;
> > +                               };
> > +                               core3 {
> > +                                       cpu = <&cpu3>;
> > +                               };
> > +                       };
> > +                       cluster1 {
> > +                               core0 {
> > +                                       cpu = <&cpu4>;
> > +                               };
> > +                               core1 {
> > +                                       cpu = <&cpu5>;
> > +                               };
> > +                               core2 {
> > +                                       cpu = <&cpu6>;
> > +                               };
> > +                               core3 {
> > +                                       cpu = <&cpu7>;
> > +                               };
> > +                       };
> > +               };
> > +
> > +               idle-states {
> > +                       entry-method = "arm,psci";
> 
> This should be just "psci".
> 
> Please add empty lines between properties and child device nodes, and
> in between device nodes.
> 
> > +                       cpuoff_l: cpuoff_l {
> 
> Please do not use underscores in device node names. Also, for the
> idle
> states, the binding requires the nodes to be named as "cpu-*" or
> "cluster-*". So {cpu,cluster}-off-{l,b} would work.
> 
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x00010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <50>;
> > +                               exit-latency-us = <95>;
> > +                               min-residency-us = <580>;
> > +                       };
> > +                       cpuoff_b: cpuoff_b {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x00010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <45>;
> > +                               exit-latency-us = <140>;
> > +                               min-residency-us = <740>;
> > +                       };
> > +                       clusteroff_l: clusteroff_l {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x01010002>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <55>;
> > +                               exit-latency-us = <155>;
> > +                               min-residency-us = <840>;
> > +                       };
> > +                       clusteroff_b: clusteroff_b {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x01010002>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <50>;
> > +                               exit-latency-us = <200>;
> > +                               min-residency-us = <1000>;
> > +                       };
> > +               };
> > +
> > +               l2_0: l2-cache0 {
> > +                       compatible = "cache";
> > +                       next-level-cache = <&l3_0>;
> > +               };
> > +
> > +               l2_1: l2-cache1 {
> > +                       compatible = "cache";
> > +                       next-level-cache = <&l3_0>;
> > +               };
> > +
> > +               l3_0: l3-cache {
> > +                       compatible = "cache";
> > +               };
> > +       };
> > +
> > +       dsu-pmu {
> > +               compatible = "arm,dsu-pmu";
> > +               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH 0>;
> > +               cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
> > +                      <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
> > +       };
> > +
> > +       pmu-a55 {
> > +               compatible = "arm,cortex-a55-pmu";
> > +               interrupt-parent = <&gic>;
> > +               interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH
> > &ppi_cluster0>;
> > +       };
> > +
> > +       pmu-a78 {
> > +               compatible = "arm,cortex-a78-pmu";
> > +               interrupt-parent = <&gic>;
> > +               interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH
> > &ppi_cluster1>;
> > +       };
> > +
> > +       psci {
> > +               compatible = "arm,psci-1.0";
> > +               method = "smc";
> > +       };
> > +
> > +       timer: timer {
> > +               compatible = "arm,armv8-timer";
> > +               interrupt-parent = <&gic>;
> > +               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
> > +                            <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
> > +                            <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
> > +                            <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
> > +               clock-frequency = <13000000>;
> 
> IIRC Marc already mentioned before that this should not be specified
> in
> the device tree. The firmware should have filled in the CNTFRQ
> register.
> 
> > +       };
> > +
> > +       soc {
> > +               #address-cells = <2>;
> > +               #size-cells = <2>;
> > +               compatible = "simple-bus";
> > +               ranges;
> > +
> > +               gic: interrupt-controller at c000000 {
> > +                       compatible = "arm,gic-v3";
> > +                       #interrupt-cells = <4>;
> > +                       #redistributor-regions = <1>;
> > +                       interrupt-parent = <&gic>;
> > +                       interrupt-controller;
> > +                       reg = <0 0x0c000000 0 0x40000>,
> > +                             <0 0x0c040000 0 0x200000>;
> > +                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH
> > 0>;
> > +
> > +                       ppi-partitions {
> > +                               ppi_cluster0: interrupt-partition-0 
> > {
> > +                                       affinity = <&cpu0 &cpu1
> > &cpu2 &cpu3>;
> > +                               };
> 
> Please add an extra line for readability.
> 
> > +                               ppi_cluster1: interrupt-partition-1 
> > {
> > +                                       affinity = <&cpu4 &cpu5
> > &cpu6 &cpu7>;
> > +                               };
> > +                       };
> > +               };
> > +
> > +               topckgen: syscon at 10000000 {
> > +                       compatible = "mediatek,mt8195-topckgen",
> > "syscon";
> > +                       reg = <0 0x10000000 0 0x1000>;
> > +                       #clock-cells = <1>;
> > +               };
> > +
> > +               infracfg_ao: syscon at 10001000 {
> > +                       compatible = "mediatek,mt8195-infracfg_ao", 
> > "syscon", "simple-mfd";
> > +                       reg = <0 0x10001000 0 0x1000>;
> > +                       #clock-cells = <1>;
> 
> Please add an extra line for readability.
> 
> > +                       infracfg_rst: reset-controller {
> > +                               compatible = "ti,syscon-reset";
> > +                               #reset-cells = <1>;
> > +                               ti,reset-bits = <
> > +                                       0x140 18 0x144 18 0 0
> > (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x120 0 0x124 0 0
> > 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x730 10 0x734 10 0
> > 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x150 5 0x154 5 0
> > 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> 
> This should be 7 cells per entry:
> 
>     ti,reset-bits =
>         <0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET |
> STATUS_NONE>,
>         <0x120 0 0x124 0 0 0 (ASSERT_SET | DEASSERT_SET |
> STATUS_NONE)>,
>         <...>,
>         <...>;
> 
> Also, please remove the extra spaces in each line. They aren't
> helping
> with formatting.
> 
> > +                               >;
> > +                       };
> > +               };
> > +
> > +               pio: pinctrl at 10005000 {
> > +                       compatible = "mediatek,mt8195-pinctrl";
> > +                       reg = <0 0x10005000 0 0x1000>,
> > +                             <0 0x11d10000 0 0x1000>,
> > +                             <0 0x11d30000 0 0x1000>,
> > +                             <0 0x11d40000 0 0x1000>,
> > +                             <0 0x11e20000 0 0x1000>,
> > +                             <0 0x11eb0000 0 0x1000>,
> > +                             <0 0x11f40000 0 0x1000>,
> > +                             <0 0x1000b000 0 0x1000>;
> > +                       reg-names = "iocfg0", "iocfg_bm",
> > "iocfg_bl",
> > +                                   "iocfg_br", "iocfg_lm",
> > "iocfg_rb",
> > +                                   "iocfg_tl", "eint";
> > +                       gpio-controller;
> > +                       #gpio-cells = <2>;
> > +                       gpio-ranges = <&pio 0 0 144>;
> > +                       interrupt-controller;
> > +                       interrupts = <GIC_SPI 235
> > IRQ_TYPE_LEVEL_HIGH 0>;
> 
> This looks correct now (a comment I raised in v4). Thanks.
> 
> > +                       #interrupt-cells = <2>;
> > +               };
> 
> [...]
> 
> > +               xhci0: usb at 11200000 {
> > +                       compatible = "mediatek,mt8195-xhci",
> > +                                    "mediatek,mtk-xhci";
> > +                       reg = <0 0x11200000 0 0x1000>,
> > +                             <0 0x11203e00 0 0x0100>;
> > +                       reg-names = "mac", "ippc";
> > +                       interrupts = <GIC_SPI 129
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       phys = <&u2port0 PHY_TYPE_USB2>,
> > +                              <&u3port0 PHY_TYPE_USB3>;
> > +                       assigned-clocks = <&topckgen
> > CLK_TOP_USB_TOP>,
> > +                                         <&topckgen
> > CLK_TOP_SSUSB_XHCI>;
> > +                       assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>,
> > +                                                <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>;
> > +                       clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
> > +                                <&infracfg_ao
> > CLK_INFRA_AO_SSUSB_XHCI>,
> > +                                <&topckgen CLK_TOP_SSUSB_REF>,
> > +                                <&apmixedsys CLK_APMIXED_USB1PLL>;
> > +                       clock-names = "sys_ck", "xhci_ck",
> > "ref_ck", "mcu_ck";
> 
> The binding for this needs to be fixed. It expects clocks in the
> order
> specified in the binding, and this doesn't match. 

ok

> Also, "dma_ck" is missing
> and will likely cause warnings to be generated.

only sys_ck is required, others are optional as described in binding

> 
> This goes for all the xhci device nodes.
> 
> > +                       status = "disabled";
> > +               };
> > +
> > +               mmc0: mmc at 11230000 {
> > +                       compatible = "mediatek,mt8195-mmc",
> > +                                    "mediatek,mt8183-mmc";
> > +                       reg = <0 0x11230000 0 0x10000>,
> > +                             <0 0x11f50000 0 0x1000>;
> 
> The binding only allows one entry. Please fix the binding first.
> This was added with MT8183, and the fix should list the relavent
> commit.
> 
> > +                       interrupts = <GIC_SPI 131
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       clocks = <&topckgen CLK_TOP_MSDC50_0>,
> > +                                <&infracfg_ao CLK_INFRA_AO_MSDC0>,
> > +                                <&infracfg_ao
> > CLK_INFRA_AO_MSDC0_SRC>;
> > +                       clock-names = "source", "hclk",
> > "source_cg";
> > +                       status = "disabled";
> > +               };
> > +
> 
> [...]
> 
> > +
> > +               xhci1: usb at 11290000 {
> > +                       compatible = "mediatek,mt8195-xhci",
> > +                                    "mediatek,mtk-xhci";
> > +                       reg = <0 0x11290000 0 0x1000>,
> > +                             <0 0x11293e00 0 0x0100>;
> > +                       reg-names = "mac", "ippc";
> > +                       interrupts = <GIC_SPI 530
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       phys = <&u2port1 PHY_TYPE_USB2>;
> 
> Shouldn't there be a USB3 phy?

currently only enable usb2, usb3 phy is used by pcie.

> 
> > +                       assigned-clocks = <&topckgen
> > CLK_TOP_USB_TOP_1P>,
> > +                                         <&topckgen
> > CLK_TOP_SSUSB_XHCI_1P>;
> > +                       assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>,
> > +                                                <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>;
> > +                       clocks = <&pericfg_ao
> > CLK_PERI_AO_SSUSB_1P_BUS>,
> > +                                <&topckgen CLK_TOP_SSUSB_P1_REF>,
> > +                                <&pericfg_ao
> > CLK_PERI_AO_SSUSB_1P_XHCI>,
> > +                                <&apmixedsys CLK_APMIXED_USB1PLL>;
> > +                       clock-names = "sys_ck", "ref_ck",
> > "xhci_ck", "mcu_ck";
> > +                       status = "disabled";
> > +               };
> > +
> > +               xhci2: usb at 112a0000 {
> > +                       compatible = "mediatek,mt8195-xhci",
> > +                                    "mediatek,mtk-xhci";
> > +                       reg = <0 0x112a0000 0 0x1000>,
> > +                             <0 0x112a3e00 0 0x0100>;
> > +                       reg-names = "mac", "ippc";
> > +                       interrupts = <GIC_SPI 533
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       phys = <&u2port2 PHY_TYPE_USB2>;
> > +                       assigned-clocks = <&topckgen
> > CLK_TOP_USB_TOP_2P>,
> > +                                         <&topckgen
> > CLK_TOP_SSUSB_XHCI_2P>;
> > +                       assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>,
> > +                                                <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>;
> > +                       clocks = <&pericfg_ao
> > CLK_PERI_AO_SSUSB_2P_BUS>,
> > +                                <&topckgen CLK_TOP_SSUSB_P2_REF>,
> > +                                <&pericfg_ao
> > CLK_PERI_AO_SSUSB_2P_XHCI>;
> > +                       clock-names = "sys_ck", "ref_ck",
> > "xhci_ck";
> > +                       status = "disabled";
> > +               };
> > +
> > +               xhci3: usb at 112b0000 {
> > +                       compatible = "mediatek,mt8195-xhci",
> > +                                    "mediatek,mtk-xhci";
> > +                       reg = <0 0x112b0000 0 0x1000>,
> > +                             <0 0x112b3e00 0 0x0100>;
> > +                       reg-names = "mac", "ippc";
> > +                       interrupts = <GIC_SPI 536
> > IRQ_TYPE_LEVEL_HIGH 0>;
> > +                       phys = <&u2port3 PHY_TYPE_USB2>;
> > +                       assigned-clocks = <&topckgen
> > CLK_TOP_USB_TOP_3P>,
> > +                                         <&topckgen
> > CLK_TOP_SSUSB_XHCI_3P>;
> > +                       assigned-clock-parents = <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>,
> > +                                                <&topckgen
> > CLK_TOP_UNIVPLL_D5_D4>;
> > +                       clocks = <&pericfg_ao
> > CLK_PERI_AO_SSUSB_3P_BUS>,
> > +                                <&pericfg_ao
> > CLK_PERI_AO_SSUSB_3P_XHCI>,
> > +                                <&topckgen CLK_TOP_SSUSB_P3_REF>;
> > +                       clock-names = "sys_ck", "xhci_ck",
> > "ref_ck";
> > +                       usb2-lpm-disable;
> 
> Could you explain why this is needed only for this controller?

This controller is fixed with a BT, there is something issue when
enable usb2 lpm, so just disabled tmp.

> 
> > +                       status = "disabled";
> > +               };
> > +
> > +               u3phy2: t-phy at 11c40000 {
> 
> Just "phy" for the node name. (Or maybe "serdes".) t-phy is not
> generic.

following t-phy?s dt-binding. 
here using t-phy is to avoid dt-check warning, because it has some sub-
phys.

> > +                       compatible = "mediatek,mt8195-tphy",
> > "mediatek,generic-tphy-v3";
> > +                       #address-cells = <1>;
> > +                       #size-cells = <1>;
> > +                       ranges = <0 0 0x11c40000 0x700>;
> > +                       status = "disabled";
> > +
> > +                       u2port2: usb-phy at 0 {
> > +                               reg = <0x0 0x700>;
> > +                               clocks = <&topckgen
> > CLK_TOP_SSUSB_PHY_P2_REF>;
> > +                               clock-names = "ref";
> > +                               #phy-cells = <1>;
> > +                       };
> > +               };
> > +
> 
> [...]
> 
> > +               ufsphy: ufs-phy at 11fa0000 {
> 
> I would have preferred "phy" for the device node, but this seems
> already
> defined in the binding.
> 
> This IP block is not listed in the datasheet I have, so I am unable
> to
> verify the properties listed here.
> 
> > +                       compatible = "mediatek,mt8195-ufsphy",
> > "mediatek,mt8183-ufsphy";
> > +                       reg = <0 0x11fa0000 0 0xc000>;
> > +                       clocks = <&clk26m>, <&clk26m>;
> > +                       clock-names = "unipro", "mp";
> > +                       #phy-cells = <0>;
> > +                       status = "disabled";
> > +               };
> > +
> 
> Most of the issues I raised in this version were issues with things
> not
> matching the bindings. Please apply your patches on -next and run
> `make dtbs_check`.

ok. I'll apply comments at next version. Thank you.

> 
> 
> ChenYu



From xianwei.zhao at amlogic.com  Thu Jan  6 03:20:13 2022
From: xianwei.zhao at amlogic.com (xianwei.zhao)
Date: Thu, 6 Jan 2022 19:20:13 +0800
Subject: [PATCH V3] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>
References: <20220106054724.18637-1-xianwei.zhao@amlogic.com>
 <1jv8yx5ekq.fsf@starbuckisacylon.baylibre.com>
Message-ID: <d21728fd-2258-c967-f518-ebca6ec3d9b4@amlogic.com>

Hi Jerome,

     I will modify those lines and update the patch later.

Thanks!




Best regards,





xianwei.zhao

On 2022/1/6 ??6:41, Jerome Brunet wrote:
> 
> 
> On Thu 06 Jan 2022 at 13:47, Xianwei Zhao <xianwei.zhao at amlogic.com> wrote:
> 
>> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
>> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
>> It's capable of booting up into the serial console.
>>
>> Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
>> ---
>> V2 -> V3: add of dts board  compatible family
>> V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
>>            and modify GIC reg defintions.
>> ---
>>   arch/arm64/boot/dts/amlogic/Makefile          |  1 +
>>   .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
>>   arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
>>   3 files changed, 130 insertions(+)
>>   create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>>   create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
>> index 5148cd9e5146..faea74a45994 100644
>> --- a/arch/arm64/boot/dts/amlogic/Makefile
>> +++ b/arch/arm64/boot/dts/amlogic/Makefile
>> @@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
>>   dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
>> +dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>> new file mode 100644
>> index 000000000000..a942d7e06d6e
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
>> @@ -0,0 +1,30 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +/dts-v1/;
>> +
>> +#include "meson-s4.dtsi"
>> +
>> +/ {
>> +	model = "Amlogic Meson S4 AQ222 Development Board";
>> +	compatible = "amlogic,aq222", "amlogic,s4";
>> +	interrupt-parent = <&gic>;
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	aliases {
>> +		serial0 = &uart_B;
>> +	};
>> +
>> +	memory at 00000000 {
>> +		device_type = "memory";
>> +		reg = <0x0 0x0 0x0 0x40000000>;
>> +	};
>> +
>> +};
>> +
>> +&uart_B {
>> +	status = "okay";
>> +};
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>> new file mode 100644
>> index 000000000000..d7083c93d3d0
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
>> @@ -0,0 +1,99 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +#include <dt-bindings/interrupt-controller/irq.h>
>> +#include <dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +/ {
>> +	cpus:cpus {
>              ^ space after : ?
> 
> Do we need the alias here ?
> 
>> +		#address-cells = <2>;
>> +		#size-cells = <0>;
>> +
>> +		CPU0:cpu at 0 {
>                      ^ space after : ?
> 
> Why is the alias uppercase ?
> 
> same for the other nodes
> 
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x0>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU1:cpu at 1 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x1>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU2:cpu at 2 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x2>;
>> +			enable-method = "psci";
>> +		};
>> +
>> +		CPU3:cpu at 3 {
>> +			device_type = "cpu";
>> +			compatible = "arm,cortex-a35","arm,armv8";
>> +			reg = <0x0 0x3>;
>> +			enable-method = "psci";
>> +		};
>> +	};
>> +
>> +	timer {
>> +		compatible = "arm,armv8-timer";
>> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
>> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
>> +	};
>> +
>> +	psci {
>> +		compatible = "arm,psci-1.0";
>> +		method = "smc";
>> +	};
>> +
>> +	xtal: xtal-clk {
>> +		compatible = "fixed-clock";
>> +		clock-frequency = <24000000>;
>> +		clock-output-names = "xtal";
>> +		#clock-cells = <0>;
>> +	};
>> +
>> +	soc {
>> +		compatible = "simple-bus";
>> +		#address-cells = <2>;
>> +		#size-cells = <2>;
>> +		ranges;
>> +
>> +		gic: interrupt-controller at fff01000 {
>> +			compatible = "arm,gic-400";
>> +			#interrupt-cells = <3>;
>> +			#address-cells = <0>;
>> +			interrupt-controller;
>> +			reg = <0x0 0xfff01000 0 0x1000>,
>> +			      <0x0 0xfff02000 0 0x2000>,
>> +			      <0x0 0xfff04000 0 0x2000>,
>> +			      <0x0 0xfff06000 0 0x2000>;
>> +			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
>> +		};
>> +
>> +		apb4: apb4 at fe000000 {
>> +			compatible = "simple-bus";
>> +			reg = <0x0 0xfe000000 0x0 0x480000>;
>> +			#address-cells = <2>;
>> +			#size-cells = <2>;
>> +			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
>> +
>> +			uart_B: serial at 7a000 {
>> +				compatible = "amlogic,meson-s4-uart",
>> +					     "amlogic,meson-ao-uart";
>> +				reg = <0x0 0x7a000 0x0 0x18>;
>> +				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
>> +				status = "disabled";
>> +				clocks = <&xtal>, <&xtal>, <&xtal>;
>> +				clock-names = "xtal", "pclk", "baud";
>> +			};
>> +		};
>> +	};
>> +};
>>
>> base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
> 
> .
>


From xianwei.zhao at amlogic.com  Thu Jan  6 03:22:14 2022
From: xianwei.zhao at amlogic.com (Xianwei Zhao)
Date: Thu, 6 Jan 2022 19:22:14 +0800
Subject: [PATCH V4] arm64: dts: add support for S4 based Amlogic AQ222
Message-ID: <20220106112214.6987-1-xianwei.zhao@amlogic.com>

Add basic support for the Amlogic S4 based Amlogic AQ222 board:
which describe components as follows: CPU, GIC, IRQ, Timer, UART.
It's capable of booting up into the serial console.

Signed-off-by: Xianwei Zhao <xianwei.zhao at amlogic.com>
---
V3 -> V4: cleaned up coding style.
V2 -> V3: add of dts board  compatible family.
V1 -> V2: cleaned up coding style, modify CPU affinity of timer interrups,
          and modify GIC reg defintions.
---
 arch/arm64/boot/dts/amlogic/Makefile          |  1 +
 .../dts/amlogic/meson-s4-s805x2-aq222.dts     | 30 ++++++
 arch/arm64/boot/dts/amlogic/meson-s4.dtsi     | 99 +++++++++++++++++++
 3 files changed, 130 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-s4.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..faea74a45994 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -57,3 +57,4 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-s4-s805x2-aq222.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
new file mode 100644
index 000000000000..a942d7e06d6e
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-s4.dtsi"
+
+/ {
+	model = "Amlogic Meson S4 AQ222 Development Board";
+	compatible = "amlogic,aq222", "amlogic,s4";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &uart_B;
+	};
+
+	memory at 00000000 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+};
+
+&uart_B {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-s4.dtsi b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
new file mode 100644
index 000000000000..bf9ae1e1016b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+		};
+
+		cpu2: cpu at 2 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x2>;
+			enable-method = "psci";
+		};
+
+		cpu3: cpu at 3 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a35","arm,armv8";
+			reg = <0x0 0x3>;
+			enable-method = "psci";
+		};
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	xtal: xtal-clk {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xtal";
+		#clock-cells = <0>;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gic: interrupt-controller at fff01000 {
+			compatible = "arm,gic-400";
+			#interrupt-cells = <3>;
+			#address-cells = <0>;
+			interrupt-controller;
+			reg = <0x0 0xfff01000 0 0x1000>,
+			      <0x0 0xfff02000 0 0x2000>,
+			      <0x0 0xfff04000 0 0x2000>,
+			      <0x0 0xfff06000 0 0x2000>;
+			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		};
+
+		apb4: apb4 at fe000000 {
+			compatible = "simple-bus";
+			reg = <0x0 0xfe000000 0x0 0x480000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x480000>;
+
+			uart_B: serial at 7a000 {
+				compatible = "amlogic,meson-s4-uart",
+					     "amlogic,meson-ao-uart";
+				reg = <0x0 0x7a000 0x0 0x18>;
+				interrupts = <GIC_SPI 169 IRQ_TYPE_EDGE_RISING>;
+				status = "disabled";
+				clocks = <&xtal>, <&xtal>, <&xtal>;
+				clock-names = "xtal", "pclk", "baud";
+			};
+		};
+	};
+};

base-commit: c5468e3c930d4d2937d3a842a85df0f74e95e152
-- 
2.30.2



From r.czerwinski at pengutronix.de  Thu Jan  6 03:26:30 2022
From: r.czerwinski at pengutronix.de (Rouven Czerwinski)
Date: Thu, 06 Jan 2022 12:26:30 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
Message-ID: <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>

Hi Andrey,

On Wed, 2021-12-08 at 00:02 +0100, Andrey Zhizhikin wrote:
> CAAM JR nodes are configured by BootROM and are used by various software
> entities during the boot process before they reach the Kernel.
> 
> Default BootROM configuration have JR0 and JR1 reserved for S-only
> access, while JR2 is generally available for both S and NS access. HAB
> feature of i.MX8M family does require that JR0 is reserved exclusively
> in S-only world, while JR1 and JR2 are both released to NS-World. OP-TEE
> can later reclaim the JR2 via dt_enable_secure_status() call, and modify
> the DID to hold it in S-World only.
> 
> The above setup has been discovered during review of CAAM patchset
> presented to U-Boot integration [1], and does not correspond to the
> status on jr nodes in FDT.
> 
> This missing status settings leads to the following error message during
> jr node probing:
> [    1.509894] caam 30900000.crypto: job rings = 3, qi = 0
> [    1.525201] caam_jr 30901000.jr: failed to flush job ring 0
> [    1.525214] caam_jr: probe of 30901000.jr failed with error -5
> 
> JR register readout after BootROM execution shows the following values:
> JR0DID_MS = 0x8011
> JR1DID_MS = 0x8011
> JR2DID_MS = 0x0
> 
> This shows that JR0 and JR1 have TZ_OWN bit set, which marks them to be
> reserved for S-World, while JR2 remains accessible from NS-World.
> 
> Provide the correct status for JR nodes in imx8m derivatives, which have
> a following meaning:
> - JR0: S-only
> - JR1: visible in both
> - JR2: NS-only
> 
> Note, that JR2 is initially marked to be NS-only which does correspond
> to DID readout when OP-TEE is not present. Once present, OP-TEE will
> reclaim the JR2 and set both "status" and "secure-status" to claim JR2
> for S-only access.

While I can understand that you want to fix your use case for when HAB
is enabled, note that this is disabling JR0 in the none-HAB case as
well. IMO this should be handled correctly by the bootloader and/or OP-
TEE. The default upstream configuration for OP-TEE is to not use the
CAAM at runtime as well, since linux runtime PM disablement of the CAAM
will lock up OP-TEE when it tries to access the CAAM.

Kind regards,
Rouven Czerwinski

> 
> Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin at leica-geosystems.com>
> Link: [1]: https://lore.kernel.org/u-boot/AM6PR06MB4691FC905FE5658BE4B15C11A6609 at AM6PR06MB4691.eurprd06.prod.outlook.com/
> ---
> Changes in V3:
> - No change, new patch introduced
> 
>  arch/arm64/boot/dts/freescale/imx8mm.dtsi | 4 ++++
>  arch/arm64/boot/dts/freescale/imx8mn.dtsi | 4 ++++
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 4 ++++
>  arch/arm64/boot/dts/freescale/imx8mq.dtsi | 4 ++++
>  4 files changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> index 5b9c2cca9ac4..51465974c4ea 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> @@ -914,18 +914,22 @@ sec_jr0: jr at 1000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x1000 0x1000>;
>  					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
> +					status = "disabled";
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr1: jr at 2000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x2000 0x1000>;
>  					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr2: jr at 3000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x3000 0x1000>;
>  					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "disabled";
>  				};
>  			};
>  
> diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> index ba23b416b5e6..e5edf14319b1 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> @@ -808,18 +808,22 @@ sec_jr0: jr at 1000 {
>  					 compatible = "fsl,sec-v4.0-job-ring";
>  					 reg = <0x1000 0x1000>;
>  					 interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
> +					 status = "disabled";
> +					 secure-status = "okay";
>  				};
>  
>  				sec_jr1: jr at 2000 {
>  					 compatible = "fsl,sec-v4.0-job-ring";
>  					 reg = <0x2000 0x1000>;
>  					 interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
> +					 secure-status = "okay";
>  				};
>  
>  				sec_jr2: jr at 3000 {
>  					 compatible = "fsl,sec-v4.0-job-ring";
>  					 reg = <0x3000 0x1000>;
>  					 interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
> +					 secure-status = "disabled";
>  				};
>  			};
>  
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> index 977783784342..3c23bf5c3910 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -661,18 +661,22 @@ sec_jr0: jr at 1000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x1000 0x1000>;
>  					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
> +					status = "disabled";
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr1: jr at 2000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x2000 0x1000>;
>  					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr2: jr at 3000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x3000 0x1000>;
>  					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "disabled";
>  				};
>  			};
>  
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 95d8b95d6120..16c4c9110ce7 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -999,18 +999,22 @@ sec_jr0: jr at 1000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x1000 0x1000>;
>  					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
> +					status = "disabled";
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr1: jr at 2000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x2000 0x1000>;
>  					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "okay";
>  				};
>  
>  				sec_jr2: jr at 3000 {
>  					compatible = "fsl,sec-v4.0-job-ring";
>  					reg = <0x3000 0x1000>;
>  					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
> +					secure-status = "disabled";
>  				};
>  			};
>  

-- 
Pengutronix e.K.           | Rouven Czerwinski          |
Steuerwalder Str. 21       | http://www.pengutronix.de/ |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0   |



From broonie at kernel.org  Thu Jan  6 03:43:34 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Jan 2022 11:43:34 +0000
Subject: [PATCH v12 07/10] arm64: Introduce stack trace reliability
 checks in the unwinder
In-Reply-To: <85156eb8-df63-29c0-cbfc-37bc0356d9e8@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-8-madvenka@linux.microsoft.com>
 <YdXOQTXscVaVFMJ3@sirena.org.uk>
 <85156eb8-df63-29c0-cbfc-37bc0356d9e8@linux.microsoft.com>
Message-ID: <YdbV5p9ZF3qjb1dc@sirena.org.uk>

On Wed, Jan 05, 2022 at 05:58:59PM -0600, Madhavan T. Venkataraman wrote:
> Thanks for the review. Do you have any comments on:
> 
> [PATCH v12 04/10] arm64: Split unwind_init()
> [PATCH v12 10/10] arm64: Select HAVE_RELIABLE_STACKTRACE

Not yet.  
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220106/35dfc84c/attachment-0001.sig>

From alexandru.elisei at arm.com  Thu Jan  6 03:46:42 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 6 Jan 2022 11:46:42 +0000
Subject: [PATCH v3 2/4] KVM: arm64: Keep a list of probed PMUs
In-Reply-To: <871r2fjrmh.wl-maz@kernel.org>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <20211213152309.158462-3-alexandru.elisei@arm.com>
 <871r2fjrmh.wl-maz@kernel.org>
Message-ID: <YdbWorcLtwwGg1sc@monolith.localdoman>

Hi Marc,

Sorry for the long silence, I didn't manage to get to your comments before
going on holiday.

On Tue, Dec 14, 2021 at 12:30:30PM +0000, Marc Zyngier wrote:
> On Mon, 13 Dec 2021 15:23:07 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > The ARM PMU driver calls kvm_host_pmu_init() after probing to tell KVM that
> > a hardware PMU is available for guest emulation. Heterogeneous systems can
> > have more than one PMU present, and the callback gets called multiple
> > times, once for each of them. Keep track of all the PMUs available to KVM,
> > as they're going to be needed later.
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> >  arch/arm64/kvm/pmu-emul.c | 25 +++++++++++++++++++++++--
> >  include/kvm/arm_pmu.h     |  5 +++++
> >  2 files changed, 28 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> > index a5e4bbf5e68f..eb4be96f144d 100644
> > --- a/arch/arm64/kvm/pmu-emul.c
> > +++ b/arch/arm64/kvm/pmu-emul.c
> > @@ -7,6 +7,7 @@
> >  #include <linux/cpu.h>
> >  #include <linux/kvm.h>
> >  #include <linux/kvm_host.h>
> > +#include <linux/list.h>
> >  #include <linux/perf_event.h>
> >  #include <linux/perf/arm_pmu.h>
> >  #include <linux/uaccess.h>
> > @@ -14,6 +15,9 @@
> >  #include <kvm/arm_pmu.h>
> >  #include <kvm/arm_vgic.h>
> >  
> > +static LIST_HEAD(arm_pmus);
> > +static DEFINE_MUTEX(arm_pmus_lock);
> > +
> >  static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx);
> >  static void kvm_pmu_update_pmc_chained(struct kvm_vcpu *vcpu, u64 select_idx);
> >  static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
> > @@ -742,9 +746,26 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
> >  
> >  void kvm_host_pmu_init(struct arm_pmu *pmu)
> >  {
> > -	if (pmu->pmuver != 0 && pmu->pmuver != ID_AA64DFR0_PMUVER_IMP_DEF &&
> > -	    !kvm_arm_support_pmu_v3() && !is_protected_kvm_enabled())
> > +	struct arm_pmu_entry *entry;
> > +
> > +	if (pmu->pmuver == 0 || pmu->pmuver == ID_AA64DFR0_PMUVER_IMP_DEF ||
> > +	    is_protected_kvm_enabled())
> > +		return;
> > +
> > +	mutex_lock(&arm_pmus_lock);
> > +
> > +	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
> > +	if (!entry)
> > +		goto out_unlock;
> > +
> > +	if (list_empty(&arm_pmus))
> >  		static_branch_enable(&kvm_arm_pmu_available);
> 
> I find it slightly dodgy that you switch the static key before
> actually populating the entry. I'd suggest moving it after the
> list_add_tail(), and check on list_is_singular() instead.

That's better, will do.

Thanks,
Alex

> 
> > +
> > +	entry->arm_pmu = pmu;
> > +	list_add_tail(&entry->entry, &arm_pmus);
> > +
> > +out_unlock:
> > +	mutex_unlock(&arm_pmus_lock);
> >  }
> >  
> >  static int kvm_pmu_probe_pmuver(void)
> > diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
> > index 90f21898aad8..e249c5f172aa 100644
> > --- a/include/kvm/arm_pmu.h
> > +++ b/include/kvm/arm_pmu.h
> > @@ -36,6 +36,11 @@ struct kvm_pmu {
> >  	struct irq_work overflow_work;
> >  };
> >  
> > +struct arm_pmu_entry {
> > +	struct list_head entry;
> > +	struct arm_pmu *arm_pmu;
> > +};
> > +
> >  #define kvm_arm_pmu_irq_initialized(v)	((v)->arch.pmu.irq_num >= VGIC_NR_SGIS)
> >  u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx);
> >  void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val);
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From alexandru.elisei at arm.com  Thu Jan  6 03:54:11 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 6 Jan 2022 11:54:11 +0000
Subject: [PATCH v3 3/4] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU
 attribute
In-Reply-To: <8735mvjrq8.wl-maz@kernel.org>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <20211213152309.158462-4-alexandru.elisei@arm.com>
 <8735mvjrq8.wl-maz@kernel.org>
Message-ID: <YdbYY/EZrTTPKOCp@monolith.localdoman>

Hi Marc,

On Tue, Dec 14, 2021 at 12:28:15PM +0000, Marc Zyngier wrote:
> On Mon, 13 Dec 2021 15:23:08 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > When KVM creates an event and there are more than one PMUs present on the
> > system, perf_init_event() will go through the list of available PMUs and
> > will choose the first one that can create the event. The order of the PMUs
> > in the PMU list depends on the probe order, which can change under various
> > circumstances, for example if the order of the PMU nodes change in the DTB
> > or if asynchronous driver probing is enabled on the kernel command line
> > (with the driver_async_probe=armv8-pmu option).
> > 
> > Another consequence of this approach is that, on heteregeneous systems,
> > all virtual machines that KVM creates will use the same PMU. This might
> > cause unexpected behaviour for userspace: when a VCPU is executing on
> > the physical CPU that uses this PMU, PMU events in the guest work
> > correctly; but when the same VCPU executes on another CPU, PMU events in
> > the guest will suddenly stop counting.
> > 
> > Fortunately, perf core allows user to specify on which PMU to create an
> > event by using the perf_event_attr->type field, which is used by
> > perf_init_event() as an index in the radix tree of available PMUs.
> > 
> > Add the KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU
> > attribute to allow userspace to specify the arm_pmu that KVM will use when
> > creating events for that VCPU. KVM will make no attempt to run the VCPU on
> > the physical CPUs that share this PMU, leaving it up to userspace to
> > manage the VCPU threads' affinity accordingly.
> > 
> > Setting the PMU for a VCPU is an all of nothing affair to avoid exposing an
> > asymmetric system to the guest: either all VCPUs have the same PMU, either
> > none of the VCPUs have a PMU set. Attempting to do something in between
> > will result in an error being returned when doing KVM_ARM_VCPU_PMU_V3_INIT.
> > 
> > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > ---
> > 
> > Checking that all VCPUs have the same PMU is done when the PMU is
> > initialized because setting the VCPU PMU is optional, and KVM cannot know
> > what the user intends until the KVM_ARM_VCPU_PMU_V3_INIT ioctl, which
> > prevents further changes to the VCPU PMU. vcpu->arch.pmu.created has been
> > changed to an atomic variable because changes to the VCPU PMU state now
> > need to be observable by all physical CPUs.
> > 
> >  Documentation/virt/kvm/devices/vcpu.rst | 30 ++++++++-
> >  arch/arm64/include/uapi/asm/kvm.h       |  1 +
> >  arch/arm64/kvm/pmu-emul.c               | 88 ++++++++++++++++++++-----
> >  include/kvm/arm_pmu.h                   |  4 +-
> >  tools/arch/arm64/include/uapi/asm/kvm.h |  1 +
> >  5 files changed, 104 insertions(+), 20 deletions(-)
> > 
> > [..]
> > -static u32 kvm_pmu_event_mask(struct kvm *kvm)
> > +static u32 kvm_pmu_event_mask(struct kvm_vcpu *vcpu)
> >  {
> > -	switch (kvm->arch.pmuver) {
> > +	unsigned int pmuver;
> > +
> > +	if (vcpu->arch.pmu.arm_pmu)
> > +		pmuver = vcpu->arch.pmu.arm_pmu->pmuver;
> > +	else
> > +		pmuver = vcpu->kvm->arch.pmuver;
> 
> This puzzles me throughout the whole patch. Why is the arm_pmu pointer
> a per-CPU thing? I would absolutely expect it to be stored in the kvm
> structure, making the whole thing much simpler.

Reply below.

> 
> > [..]
> > @@ -637,8 +645,7 @@ static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
> >  		return;
> >  
> >  	memset(&attr, 0, sizeof(struct perf_event_attr));
> > -	attr.type = PERF_TYPE_RAW;
> > -	attr.size = sizeof(attr);
> 
> Why is this line removed?

Typo on my part, thank you for spotting it.

> 
> > [..]
> > @@ -910,7 +922,16 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
> >  	init_irq_work(&vcpu->arch.pmu.overflow_work,
> >  		      kvm_pmu_perf_overflow_notify_vcpu);
> >  
> > -	vcpu->arch.pmu.created = true;
> > +	atomic_set(&vcpu->arch.pmu.created, 1);
> > +
> > +	kvm_for_each_vcpu(i, v, kvm) {
> > +		if (!atomic_read(&v->arch.pmu.created))
> > +			continue;
> > +
> > +		if (v->arch.pmu.arm_pmu != arm_pmu)
> > +			return -ENXIO;
> > +	}
> 
> If you did store the arm_pmu at the VM level, you wouldn't need this.
> You could detect the discrepancy in the set_pmu ioctl.

I chose to set at the VCPU level to be consistent with how KVM treats the
PMU interrupt ID when the interrupt is a PPI, where the interrupt ID must
be the same for all VCPUs and it is stored at the VCPU. However, looking at
the code again, it occurs to me that it is stored at the VCPU when it's a
PPI because it's simpler to do it that way, as the code remains the same
when the interrupt ID is a SPI, which must be *different* between VCPUs. So
in the end, having the PMU stored at the VM level does match how KVM uses
it, which looks to be better than my approach.

This is the change you proposed in your branch [1]:

+static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
+{
+       struct kvm *kvm = vcpu->kvm;
+       struct arm_pmu_entry *entry;
+       struct arm_pmu *arm_pmu;
+       int ret = -ENXIO;
+
+       mutex_lock(&kvm->lock);
+       mutex_lock(&arm_pmus_lock);
+
+       list_for_each_entry(entry, &arm_pmus, entry) {
+               arm_pmu = entry->arm_pmu;
+               if (arm_pmu->pmu.type == pmu_id) {
+                       /* Can't change PMU if filters are already in place */
+                       if (kvm->arch.arm_pmu != arm_pmu &&
+                           kvm->arch.pmu_filter) {
+                               ret = -EBUSY;
+                               break;
+                       }
+
+                       kvm->arch.arm_pmu = arm_pmu;
+                       ret = 0;
+                       break;
+               }
+       }
+
+       mutex_unlock(&arm_pmus_lock);
+       mutex_unlock(&kvm->lock);
+       return ret;
+}

As I understand the code, userspace only needs to call
KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) *once* (on one VCPU
fd) to set the PMU for all the VCPUs; subsequent calls (on the same VCPU or
on another VCPU) with a different PMU id will change the PMU for all VCPUs.

Two remarks:

1. The documentation for the VCPU ioctls states this (from
Documentation/virt/kvm/devices/vcpu.rst):

"
======================
Generic vcpu interface
======================

The virtual cpu "device" also accepts the ioctls KVM_SET_DEVICE_ATTR,
KVM_GET_DEVICE_ATTR, and KVM_HAS_DEVICE_ATTR. The interface uses the same struct
kvm_device_attr as other devices, but **targets VCPU-wide settings and
controls**" (emphasis added).

But I guess having VCPU ioctls affect *only* the VCPU hasn't really been
true ever since PMU event filtering has been added. I'll send a patch to
change that part of the documentation for arm64.

I was thinking maybe a VM capability would be better suited for changing a
VM-wide setting, what do you think? I don't have a strong preference either
way.

2. What's to stop userspace to change the PMU after at least one VCPU has
run? That can be easily observed by the guest when reading PMCEIDx_EL0.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/pmu-bl

Thanks,
Alex


From alexandru.elisei at arm.com  Thu Jan  6 04:07:38 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 6 Jan 2022 12:07:38 +0000
Subject: [PATCH v3 0/4] KVM: arm64: Improve PMU support on heterogeneous
 systems
In-Reply-To: <87bl0xzwu1.wl-maz@kernel.org>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <87bl0xzwu1.wl-maz@kernel.org>
Message-ID: <Ydbbivoqo3vUxB4j@monolith.localdoman>

Hi Marc,

On Thu, Dec 30, 2021 at 08:01:10PM +0000, Marc Zyngier wrote:
> Alex,
> 
> On Mon, 13 Dec 2021 15:23:05 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > (CC'ing Peter Maydell in case this might be of interest to qemu)
> > 
> > The series can be found on a branch at [1], and the kvmtool support at [2].
> > The kvmtool patches are also on the mailing list [3] and haven't changed
> > since v1.
> > 
> > Detailed explanation of the issue and symptoms that the patches attempt to
> > correct can be found in the cover letter for v1 [4].
> > 
> > A summary of the problem is that on heterogeneous systems KVM will always
> > use the same PMU for creating the VCPU events for *all* VCPUs regardless of
> > the physical CPU on which the VCPU is running, leading to events suddenly
> > stopping and resuming in the guest as the VCPU thread gets migrated across
> > different CPUs.
> > 
> > This series proposes to fix this behaviour by allowing the user to specify
> > which physical PMU is used when creating the VCPU events needed for guest
> > PMU emulation. When the PMU is set, KVM will refuse to the VCPU on a
> > physical which is not part of the supported CPUs for the specified PMU. The
> > restriction is that all VCPUs must use the same PMU to avoid emulating an
> > asymmetric platform.
> > 
> > The default behaviour stays the same - without userspace setting the PMU,
> > events will stop counting if the VCPU is scheduled on the wrong CPU.
> > 
> > Tested with a hacked version of kvmtool that does the PMU initialization
> > from the VCPU thread as opposed to from the main thread. Tested on
> > rockpro64 by testing what happens when all VCPUs having the same PMU, one
> > random VCPU having a different PMU than the other VCPUs and one random VCPU
> > not having the PMU set (each test was run 1,000 times on the little cores
> > and 1,000 times on the big cores).
> > 
> > Also tested on an Altra by testing all VCPUs having the same PMU, all VCPUs
> > not having a PMU set, and one random VCPU not having the PMU set; the VM
> > had 64 threads in each of the tests and each test was run 10,000 times.
> 
> Came back to this series, and found more problems. On top of the
> remarks I had earlier (the per-CPU data structures that really should
> per VM, the disappearing attribute size), what happens when event
> filters are already registered and that you set a specific PMU?

This is a good point. When I looked at how the PMU event filter works, I
saw that KVM doesn't attempt to check that the events are actually
implemented on the PMU, but somehow skipped over the fact that the PMU
affects the total number of events available.

Thanks,
Alex

> 
> I took the matter in my own hands (the joy of being in quarantine) and
> wrote whatever fixes I thought were necessary[1].
> 
> Please have a look.
> 
> 	M.
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/log/?h=kvm-arm64/pmu-bl
> 
> -- 
> Without deviation from the norm, progress is not possible.


From linmq006 at gmail.com  Thu Jan  6 04:16:05 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Thu, 6 Jan 2022 12:16:05 +0000
Subject: [PATCH] phy: mediatek: Fix missing check in mtk_mipi_tx_probe
In-Reply-To: <CAAOTY_-7-BrnkPk_5V5y20F6fX3X8Vm0tcYAA=1DNCnxjvNF8A@mail.gmail.com>
References: <20211224082103.7658-1-linmq006@gmail.com>
 <CAAOTY_-7-BrnkPk_5V5y20F6fX3X8Vm0tcYAA=1DNCnxjvNF8A@mail.gmail.com>
Message-ID: <20220106121524.GA25165@8345e2a12d0c>

Hi, Chun-Kuang:

On Fri, Dec 31, 2021 at 12:31:33AM +0800, Chun-Kuang Hu wrote:
> > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > index 28ad9403c441..67b005d5b9e3 100644
> > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > @@ -146,6 +146,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
> >                 return -ENOMEM;
> >
> >         mipi_tx->driver_data = of_device_get_match_data(dev);
> > +       if (!mipi_tx->driver_data)
> 
> I'm confused. mtk_mipi_tx_probe() is called because this device node's
> compatible match one in mtk_mipi_tx_match[]. So I think the return
> value of of_device_get_match_data(dev) would not be NULL. If this is
> true, this checking is redundant.
>
I think your are right, this checking is redundant. Thanks for your
reply.

Regards,
Miaoqian.


From lkp at intel.com  Thu Jan  6 04:42:45 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 6 Jan 2022 20:42:45 +0800
Subject: [PATCH] media: atmel: atmel-isc: Fix PM disable depth imbalance
 in atmel_isc_probe
In-Reply-To: <20220105111056.4662-1-linmq006@gmail.com>
References: <20220105111056.4662-1-linmq006@gmail.com>
Message-ID: <202201062034.BD2L4uCe-lkp@intel.com>

Hi Miaoqian,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on media-tree/master]
[also build test WARNING on v5.16-rc8 next-20220105]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Miaoqian-Lin/media-atmel-atmel-isc-Fix-PM-disable-depth-imbalance-in-atmel_isc_probe/20220105-191228
base:   git://linuxtv.org/media_tree.git master
config: riscv-randconfig-r002-20220106 (https://download.01.org/0day-ci/archive/20220106/202201062034.BD2L4uCe-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/0day-ci/linux/commit/f116d8f81c642486900c9589a7c10d137d7eb0a2
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Miaoqian-Lin/media-atmel-atmel-isc-Fix-PM-disable-depth-imbalance-in-atmel_isc_probe/20220105-191228
        git checkout f116d8f81c642486900c9589a7c10d137d7eb0a2
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/media/platform/atmel/ net/xfrm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/media/platform/atmel/atmel-sama5d2-isc.c:30:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:464:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __raw_readb(PCI_IOBASE + addr);
                             ~~~~~~~~~~ ^
   include/asm-generic/io.h:477:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:36:51: note: expanded from macro '__le16_to_cpu'
   #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
                                                     ^
   In file included from drivers/media/platform/atmel/atmel-sama5d2-isc.c:30:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:490:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
                                                           ~~~~~~~~~~ ^
   include/uapi/linux/byteorder/little_endian.h:34:51: note: expanded from macro '__le32_to_cpu'
   #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
                                                     ^
   In file included from drivers/media/platform/atmel/atmel-sama5d2-isc.c:30:
   In file included from include/linux/interrupt.h:11:
   In file included from include/linux/hardirq.h:11:
   In file included from ./arch/riscv/include/generated/asm/hardirq.h:1:
   In file included from include/asm-generic/hardirq.h:17:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:13:
   In file included from arch/riscv/include/asm/io.h:136:
   include/asm-generic/io.h:501:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writeb(value, PCI_IOBASE + addr);
                               ~~~~~~~~~~ ^
   include/asm-generic/io.h:511:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:521:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
                                                         ~~~~~~~~~~ ^
   include/asm-generic/io.h:1024:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
           return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
                                                     ~~~~~~~~~~ ^
>> drivers/media/platform/atmel/atmel-sama5d2-isc.c:562:1: warning: unused label 'disable_pm_runtime' [-Wunused-label]
   disable_pm_runtime:
   ^~~~~~~~~~~~~~~~~~~
   8 warnings generated.


vim +/disable_pm_runtime +562 drivers/media/platform/atmel/atmel-sama5d2-isc.c

   380	
   381	static int atmel_isc_probe(struct platform_device *pdev)
   382	{
   383		struct device *dev = &pdev->dev;
   384		struct isc_device *isc;
   385		struct resource *res;
   386		void __iomem *io_base;
   387		struct isc_subdev_entity *subdev_entity;
   388		int irq;
   389		int ret;
   390		u32 ver;
   391	
   392		isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL);
   393		if (!isc)
   394			return -ENOMEM;
   395	
   396		platform_set_drvdata(pdev, isc);
   397		isc->dev = dev;
   398	
   399		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
   400		io_base = devm_ioremap_resource(dev, res);
   401		if (IS_ERR(io_base))
   402			return PTR_ERR(io_base);
   403	
   404		isc->regmap = devm_regmap_init_mmio(dev, io_base, &isc_regmap_config);
   405		if (IS_ERR(isc->regmap)) {
   406			ret = PTR_ERR(isc->regmap);
   407			dev_err(dev, "failed to init register map: %d\n", ret);
   408			return ret;
   409		}
   410	
   411		irq = platform_get_irq(pdev, 0);
   412		if (irq < 0)
   413			return irq;
   414	
   415		ret = devm_request_irq(dev, irq, isc_interrupt, 0,
   416				       "atmel-sama5d2-isc", isc);
   417		if (ret < 0) {
   418			dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
   419				irq, ret);
   420			return ret;
   421		}
   422	
   423		isc->gamma_table = isc_sama5d2_gamma_table;
   424		isc->gamma_max = 2;
   425	
   426		isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH;
   427		isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT;
   428	
   429		isc->config_dpc = isc_sama5d2_config_dpc;
   430		isc->config_csc = isc_sama5d2_config_csc;
   431		isc->config_cbc = isc_sama5d2_config_cbc;
   432		isc->config_cc = isc_sama5d2_config_cc;
   433		isc->config_gam = isc_sama5d2_config_gam;
   434		isc->config_rlp = isc_sama5d2_config_rlp;
   435		isc->config_ctrls = isc_sama5d2_config_ctrls;
   436	
   437		isc->adapt_pipeline = isc_sama5d2_adapt_pipeline;
   438	
   439		isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET;
   440		isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET;
   441		isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET;
   442		isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET;
   443		isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET;
   444		isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET;
   445		isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET;
   446		isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET;
   447		isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET;
   448	
   449		isc->controller_formats = sama5d2_controller_formats;
   450		isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats);
   451		isc->formats_list = sama5d2_formats_list;
   452		isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list);
   453	
   454		/* sama5d2-isc - 8 bits per beat */
   455		isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8;
   456	
   457		/* sama5d2-isc : ISPCK is required and mandatory */
   458		isc->ispck_required = true;
   459	
   460		ret = isc_pipeline_init(isc);
   461		if (ret)
   462			return ret;
   463	
   464		isc->hclock = devm_clk_get(dev, "hclock");
   465		if (IS_ERR(isc->hclock)) {
   466			ret = PTR_ERR(isc->hclock);
   467			dev_err(dev, "failed to get hclock: %d\n", ret);
   468			return ret;
   469		}
   470	
   471		ret = clk_prepare_enable(isc->hclock);
   472		if (ret) {
   473			dev_err(dev, "failed to enable hclock: %d\n", ret);
   474			return ret;
   475		}
   476	
   477		ret = isc_clk_init(isc);
   478		if (ret) {
   479			dev_err(dev, "failed to init isc clock: %d\n", ret);
   480			goto unprepare_hclk;
   481		}
   482		ret = v4l2_device_register(dev, &isc->v4l2_dev);
   483		if (ret) {
   484			dev_err(dev, "unable to register v4l2 device.\n");
   485			goto unprepare_clk;
   486		}
   487	
   488		ret = isc_parse_dt(dev, isc);
   489		if (ret) {
   490			dev_err(dev, "fail to parse device tree\n");
   491			goto unregister_v4l2_device;
   492		}
   493	
   494		if (list_empty(&isc->subdev_entities)) {
   495			dev_err(dev, "no subdev found\n");
   496			ret = -ENODEV;
   497			goto unregister_v4l2_device;
   498		}
   499	
   500		list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
   501			struct v4l2_async_subdev *asd;
   502			struct fwnode_handle *fwnode =
   503				of_fwnode_handle(subdev_entity->epn);
   504	
   505			v4l2_async_nf_init(&subdev_entity->notifier);
   506	
   507			asd = v4l2_async_nf_add_fwnode_remote(&subdev_entity->notifier,
   508							      fwnode,
   509							      struct v4l2_async_subdev);
   510	
   511			of_node_put(subdev_entity->epn);
   512			subdev_entity->epn = NULL;
   513	
   514			if (IS_ERR(asd)) {
   515				ret = PTR_ERR(asd);
   516				goto cleanup_subdev;
   517			}
   518	
   519			subdev_entity->notifier.ops = &isc_async_ops;
   520	
   521			ret = v4l2_async_nf_register(&isc->v4l2_dev,
   522						     &subdev_entity->notifier);
   523			if (ret) {
   524				dev_err(dev, "fail to register async notifier\n");
   525				goto cleanup_subdev;
   526			}
   527	
   528			if (video_is_registered(&isc->video_dev))
   529				break;
   530		}
   531	
   532		pm_runtime_set_active(dev);
   533		pm_runtime_enable(dev);
   534		pm_request_idle(dev);
   535	
   536		isc->ispck = isc->isc_clks[ISC_ISPCK].clk;
   537	
   538		ret = clk_prepare_enable(isc->ispck);
   539		if (ret) {
   540			dev_err(dev, "failed to enable ispck: %d\n", ret);
   541			goto cleanup_subdev;
   542		}
   543	
   544		/* ispck should be greater or equal to hclock */
   545		ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock));
   546		if (ret) {
   547			dev_err(dev, "failed to set ispck rate: %d\n", ret);
   548			goto unprepare_clk;
   549		}
   550	
   551		regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
   552		dev_info(dev, "Microchip ISC version %x\n", ver);
   553	
   554		return 0;
   555	
   556	unprepare_clk:
   557		clk_disable_unprepare(isc->ispck);
   558	
   559	cleanup_subdev:
   560		isc_subdev_cleanup(isc);
   561	
 > 562	disable_pm_runtime:
   563		pm_runtime_disable(dev);
   564	
   565	unregister_v4l2_device:
   566		v4l2_device_unregister(&isc->v4l2_dev);
   567	
   568	unprepare_hclk:
   569		clk_disable_unprepare(isc->hclock);
   570	
   571		isc_clk_cleanup(isc);
   572	
   573		return ret;
   574	}
   575	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From dan.carpenter at oracle.com  Thu Jan  6 04:51:03 2022
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Thu, 6 Jan 2022 15:51:03 +0300
Subject: [PATCH v2 3/3] staging: vc04_services: update TODO file
In-Reply-To: <3f560a75063a0bb744bb34c410e49f792d2c3d21.1640776340.git.gascoar@gmail.com>
References: <cover.1640776340.git.gascoar@gmail.com>
 <3f560a75063a0bb744bb34c410e49f792d2c3d21.1640776340.git.gascoar@gmail.com>
Message-ID: <20220106125103.GM7674@kadam>

On Thu, Dec 30, 2021 at 08:31:29AM -0300, Gaston Gonzalez wrote:
> There are no struct typedef remaining inside vc04_services/. Hence, remove the
> task from the TODO file.
> 
> While at it, fix the items sequential numbering.

The previous developers who let the numbers bitrot did the right thing.
There is a kind of ethereal beauty to misnumbered TODO lists.  #Hyperart

Or just replace the numbers with asterisks.

regards,
dan carpenter



From broonie at kernel.org  Thu Jan  6 04:59:15 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Jan 2022 12:59:15 +0000
Subject: [PATCH 2/4] regulator: mt6366: Add support for MT6366 regulator
In-Reply-To: <20220106065407.16036-3-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
 <20220106065407.16036-3-johnson.wang@mediatek.com>
Message-ID: <Ydbno0JM8YP9NhNh@sirena.org.uk>

On Thu, Jan 06, 2022 at 02:54:05PM +0800, Johnson Wang wrote:
> The MT6366 is a regulator found on boards based on MediaTek MT8186 and
> probably other SoCs. It is a so called pmic and connects as a slave to
> SoC using SPI, wrapped inside the pmic-wrapper.

Reviwed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220106/8b38388d/attachment.sig>

From wei.liu at kernel.org  Thu Jan  6 05:03:37 2022
From: wei.liu at kernel.org (Wei Liu)
Date: Thu, 6 Jan 2022 13:03:37 +0000
Subject: [PATCH bpf-next v2 1/2] net: add includes masked by netdevice.h
 including uapi/bpf.h
In-Reply-To: <20211230012742.770642-2-kuba@kernel.org>
References: <20211230012742.770642-1-kuba@kernel.org>
 <20211230012742.770642-2-kuba@kernel.org>
Message-ID: <20220106130337.qtvjgffwlyzy7j2y@liuwe-devbox-debian-v2>

On Wed, Dec 29, 2021 at 05:27:41PM -0800, Jakub Kicinski wrote:
> Add missing includes unmasked by the subsequent change.
> 
> Mostly network drivers missing an include for XDP_PACKET_HEADROOM.
> 
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>
[...]
>  drivers/net/ethernet/microsoft/mana/mana_en.c      | 2 ++

This seems trivially correct, so in case an ack is needed:

Acked-by: Wei Liu <wei.liu at kernel.org>

> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index c1d5a374b967..2ece9e90dc50 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -1,6 +1,8 @@
>  // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
>  /* Copyright (c) 2021, Microsoft Corporation. */
>  
> +#include <uapi/linux/bpf.h>
> +
>  #include <linux/inetdevice.h>
>  #include <linux/etherdevice.h>
>  #include <linux/ethtool.h>


From broonie at kernel.org  Thu Jan  6 05:09:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Jan 2022 13:09:10 +0000
Subject: [PATCH 4/4] dt-bindings: regulator: Add MT6358 regulators
In-Reply-To: <20220106065407.16036-5-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
 <20220106065407.16036-5-johnson.wang@mediatek.com>
Message-ID: <Ydbp9jFDLcvpiPxa@sirena.org.uk>

On Thu, Jan 06, 2022 at 02:54:07PM +0800, Johnson Wang wrote:
> Add buck_vcore_sshub and ldo_vsram_others_sshub
> regulators to binding document for MT6358 and MT6366.

Reviwed-by: Mark Brown <broonie at kernel.org>

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220106/59c661a8/attachment.sig>

From patrice.chotard at foss.st.com  Thu Jan  6 05:20:52 2022
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Thu, 6 Jan 2022 14:20:52 +0100
Subject: spi: stm32-qspi: Update spi registering
Message-ID: <20220106132052.7227-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Replace devm_spi_register_master() by spi_register_master() to ensure
that spi sub-nodes are unregistered in the correct order when qspi driver
is removed.
This issue was put in evidence using kernel v5.11 and later
with a spi-nor which supports the software reset feature introduced
by commit d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on shutdown")

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
---
 drivers/spi/spi-stm32-qspi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 514337c86d2c..db005443aa7c 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_noresume(dev);
 
-	ret = devm_spi_register_master(dev, ctrl);
+	ret = spi_register_master(ctrl);
 	if (ret)
 		goto err_pm_runtime_free;
 
@@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
 	struct stm32_qspi *qspi = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(qspi->dev);
+	spi_unregister_master(qspi->ctrl);
 	/* disable qspi */
 	writel_relaxed(0, qspi->io_base + QSPI_CR);
 	stm32_qspi_dma_free(qspi);
-- 
2.17.1



From lorenzo.pieralisi at arm.com  Thu Jan  6 05:38:45 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu,  6 Jan 2022 13:38:45 +0000
Subject: [PATCH 0/2] PCI: mvebu: Add support for unbinding and unloading
 driver
In-Reply-To: <20211126144307.7568-1-pali@kernel.org>
References: <20211126144307.7568-1-pali@kernel.org>
Message-ID: <164147629708.11320.5014072725666944970.b4-ty@arm.com>

On Fri, 26 Nov 2021 15:43:05 +0100, Pali Roh?r wrote:
> This patch series add support for unbinding device from pci-mvebu driver,
> allow to compile pci-mvebu.c as kernel module pci-mvebu.ko and allow to
> rmmod this module.
> 
> This patch series depends on another patch series which converts
> pci-mvebu.c driver to use devm_pci_remap_iospace() function:
> 
> [...]

Applied to pci/mvebu, thanks!

[1/2] bus: mvebu-mbus: Export symbols for public API window functions
      https://git.kernel.org/lpieralisi/pci/c/859186e238
[2/2] PCI: mvebu: Add support for compiling driver as module
      https://git.kernel.org/lpieralisi/pci/c/0746ae1be1

Thanks,
Lorenzo


From gregkh at linuxfoundation.org  Thu Jan  6 05:48:25 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 6 Jan 2022 14:48:25 +0100
Subject: [PATCH 5/6] staging: vc04_services: rename macros
 BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
In-Reply-To: <d450b9e22e5ab335a61591dbf0d2104031c9fc46.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
 <d450b9e22e5ab335a61591dbf0d2104031c9fc46.1641414449.git.gascoar@gmail.com>
Message-ID: <YdbzKaKQW7N04QgA@kroah.com>

On Wed, Jan 05, 2022 at 05:35:47PM -0300, Gaston Gonzalez wrote:
> In the kernel, all names related to the chip BCM2835 are always named
> bcm2835_*. To avoid confusion, and to make things more consistent,
> rename the macros BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
> accordingly.
> 
> While at it, some realignments were made to improve readability.
> 
> Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
> Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
> ---
>  .../vc04_services/bcm2835-camera/bcm2835-camera.c  | 14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> index aaf529f2186c..c729b1b7de71 100644
> --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> @@ -33,8 +33,8 @@
>  #include "mmal-parameters.h"
>  #include "bcm2835-camera.h"
>  
> -#define BM2835_MMAL_VERSION "0.0.2"
> -#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
> +#define BCM2835_MMAL_VERSION "0.0.2"

MODULE_VERSION means nothing when the code is in the kernel tree, this
shold just be removed entirely.

> +#define BCM2835_MMAL_MODULE_NAME "bcm2835-v4l2"

KBUILD_MODULE_NAME provides this, please delete this and just use that
instead.

This can be 2 different commits because of this.

thanks,

greg k-h


From gregkh at linuxfoundation.org  Thu Jan  6 05:49:49 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 6 Jan 2022 14:49:49 +0100
Subject: [PATCH 0/6] staging: vc04_services: rename ocurrences of
 'bm2835*' to 'bcm2835*'
In-Reply-To: <cover.1641414449.git.gascoar@gmail.com>
References: <cover.1641414449.git.gascoar@gmail.com>
Message-ID: <Ydbzfbf+yUgQzVbb@kroah.com>

On Wed, Jan 05, 2022 at 05:35:41PM -0300, Gaston Gonzalez wrote:
> This patch set renames ocurrences of 'bm2835*' to 'bcm2835*'.
> 
> Gaston Gonzalez (6):
>   staging: vc04_services: rename structures bm2835_mmal_dev and
>     bm2835_mmal_v4l2_ctrl
>   staging: vc04_services: rename functions containing bm2835_* to
>     bcm2835_*
>   staging: vc04_services: rename variables containing bm2835_* to
>     bcm2835_*
>   staging: vc04_services: rename string literal containing bm2835_* to
>     bcm2835*_
>   staging: vc04_services: rename macros BM2835_MMAL_VERSION and
>     BM2835_MMAL_MODULE_NAME
>   staging: vc04_services: rename BM2835 to BCM2835 in headers comments

All but patch 5/6 now queued up, thanks,

greg k-h


From broonie at kernel.org  Thu Jan  6 05:51:20 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Jan 2022 13:51:20 +0000
Subject: spi: stm32-qspi: Update spi registering
In-Reply-To: <20220106132052.7227-1-patrice.chotard@foss.st.com>
References: <20220106132052.7227-1-patrice.chotard@foss.st.com>
Message-ID: <Ydbz2JkT8jRvNBBZ@sirena.org.uk>

On Thu, Jan 06, 2022 at 02:20:52PM +0100, patrice.chotard at foss.st.com wrote:
> From: Patrice Chotard <patrice.chotard at foss.st.com>
> 
> Replace devm_spi_register_master() by spi_register_master() to ensure
> that spi sub-nodes are unregistered in the correct order when qspi driver
> is removed.

This commit message doesn't describe the actual issue.  The change is
fixing ordering within the driver itself - the driver is freeing things
in the remove() callback which are used by the controller but thanks to
the use of devm the controller isn't unregistered from the core until
after the remove() callback has run so we might still have something
running.  "Subnodes" aren't an issue here.

Please submit patches using subject lines reflecting the style for the
subsystem, this makes it easier for people to identify relevant patches.
Look at what existing commits in the area you're changing are doing and
make sure your subject lines visually resemble what they're doing.
There's no need to resubmit to fix this alone.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220106/06208ea4/attachment.sig>

From andrey.zhizhikin at leica-geosystems.com  Thu Jan  6 06:08:20 2022
From: andrey.zhizhikin at leica-geosystems.com (ZHIZHIKIN Andrey)
Date: Thu, 6 Jan 2022 14:08:20 +0000
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
Message-ID: <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>

Hello Rouven,

> -----Original Message-----
> From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> Sent: Thursday, January 6, 2022 12:27 PM
> To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> kernel at vger.kernel.org
> Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> frieder.schrempf at kontron.de; leonard.crestez at nxp.com; festevam at gmail.com;
> marex at denx.de; herbert at gondor.apana.org.au; horia.geanta at nxp.com;
> aford173 at gmail.com; krzk at kernel.org; linux-imx at nxp.com;
> devicetree at vger.kernel.org; hongxing.zhu at nxp.com; s.hauer at pengutronix.de;
> pankaj.gupta at nxp.com; robh+dt at kernel.org; thunder.leizhen at huawei.com;
> martink at posteo.de; daniel.baluta at nxp.com; linux-arm-kernel at lists.infradead.org;
> gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-crypto at vger.kernel.org;
> kernel at pengutronix.de; jun.li at nxp.com; shawnguo at kernel.org; davem at davemloft.net;
> l.stach at pengutronix.de
> Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
> 
> Hi Andrey,
> 
> On Wed, 2021-12-08 at 00:02 +0100, Andrey Zhizhikin wrote:
> > CAAM JR nodes are configured by BootROM and are used by various software
> > entities during the boot process before they reach the Kernel.
> >
> > Default BootROM configuration have JR0 and JR1 reserved for S-only
> > access, while JR2 is generally available for both S and NS access. HAB
> > feature of i.MX8M family does require that JR0 is reserved exclusively
> > in S-only world, while JR1 and JR2 are both released to NS-World. OP-TEE
> > can later reclaim the JR2 via dt_enable_secure_status() call, and modify
> > the DID to hold it in S-World only.
> >
> > The above setup has been discovered during review of CAAM patchset
> > presented to U-Boot integration [1], and does not correspond to the
> > status on jr nodes in FDT.
> >
> > This missing status settings leads to the following error message during
> > jr node probing:
> > [    1.509894] caam 30900000.crypto: job rings = 3, qi = 0
> > [    1.525201] caam_jr 30901000.jr: failed to flush job ring 0
> > [    1.525214] caam_jr: probe of 30901000.jr failed with error -5
> >
> > JR register readout after BootROM execution shows the following values:
> > JR0DID_MS = 0x8011
> > JR1DID_MS = 0x8011
> > JR2DID_MS = 0x0
> >
> > This shows that JR0 and JR1 have TZ_OWN bit set, which marks them to be
> > reserved for S-World, while JR2 remains accessible from NS-World.
> >
> > Provide the correct status for JR nodes in imx8m derivatives, which have
> > a following meaning:
> > - JR0: S-only
> > - JR1: visible in both
> > - JR2: NS-only
> >
> > Note, that JR2 is initially marked to be NS-only which does correspond
> > to DID readout when OP-TEE is not present. Once present, OP-TEE will
> > reclaim the JR2 and set both "status" and "secure-status" to claim JR2
> > for S-only access.
> 
> While I can understand that you want to fix your use case for when HAB
> is enabled, note that this is disabling JR0 in the none-HAB case as
> well.

This is not totally correct, as this patch does address the reservation of
JR0 by BootROM in both HAB and non-HAB configurations. My current setup does
not include HAB functionality enabled, and I still do observe boot errors
that are listed in commit message. This is due to the fact that the BootROM
does not release JR0 to NS-World regardless of whether HAB is enabled or not.
This has been discussed in the U-Boot thread I provided the link in the patch.

This patch does rather bring the correct HW module description as seeing
from Linux. 

> IMO this should be handled correctly by the bootloader and/or OP-
> TEE. The default upstream configuration for OP-TEE is to not use the
> CAAM at runtime as well, since linux runtime PM disablement of the CAAM
> will lock up OP-TEE when it tries to access the CAAM.

If by handling you mean releasing JR0 reservation - then yes, it should be
done by either SPL or TF-A as they do run in S World. In such a case, DTB
bindings need to be adapted further according to the new state. Until this
done - this patch does provide a correct state of HW to the Kernel.

> 
> Kind regards,
> Rouven Czerwinski
> 
> >
> > Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin at leica-geosystems.com>
> > Link: [1]: https://lore.kernel.org/u-boot/AM6PR06MB4691FC905FE5658BE4B15C11A6609 at AM6PR06MB4691.eurprd06.prod.outlook.com/
> > ---
> > Changes in V3:
> > - No change, new patch introduced
> >
> >  arch/arm64/boot/dts/freescale/imx8mm.dtsi | 4 ++++
> >  arch/arm64/boot/dts/freescale/imx8mn.dtsi | 4 ++++
> >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 4 ++++
> >  arch/arm64/boot/dts/freescale/imx8mq.dtsi | 4 ++++
> >  4 files changed, 16 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > index 5b9c2cca9ac4..51465974c4ea 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > @@ -914,18 +914,22 @@ sec_jr0: jr at 1000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x1000 0x1000>;
> >                                       interrupts = <GIC_SPI 105
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     status = "disabled";
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr1: jr at 2000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x2000 0x1000>;
> >                                       interrupts = <GIC_SPI 106
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr2: jr at 3000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x3000 0x1000>;
> >                                       interrupts = <GIC_SPI 114
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "disabled";
> >                               };
> >                       };
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > index ba23b416b5e6..e5edf14319b1 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > @@ -808,18 +808,22 @@ sec_jr0: jr at 1000 {
> >                                        compatible = "fsl,sec-v4.0-job-ring";
> >                                        reg = <0x1000 0x1000>;
> >                                        interrupts = <GIC_SPI 105
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                      status = "disabled";
> > +                                      secure-status = "okay";
> >                               };
> >
> >                               sec_jr1: jr at 2000 {
> >                                        compatible = "fsl,sec-v4.0-job-ring";
> >                                        reg = <0x2000 0x1000>;
> >                                        interrupts = <GIC_SPI 106
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                      secure-status = "okay";
> >                               };
> >
> >                               sec_jr2: jr at 3000 {
> >                                        compatible = "fsl,sec-v4.0-job-ring";
> >                                        reg = <0x3000 0x1000>;
> >                                        interrupts = <GIC_SPI 114
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                      secure-status = "disabled";
> >                               };
> >                       };
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > index 977783784342..3c23bf5c3910 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > @@ -661,18 +661,22 @@ sec_jr0: jr at 1000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x1000 0x1000>;
> >                                       interrupts = <GIC_SPI 105
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     status = "disabled";
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr1: jr at 2000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x2000 0x1000>;
> >                                       interrupts = <GIC_SPI 106
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr2: jr at 3000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x3000 0x1000>;
> >                                       interrupts = <GIC_SPI 114
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "disabled";
> >                               };
> >                       };
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > index 95d8b95d6120..16c4c9110ce7 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > @@ -999,18 +999,22 @@ sec_jr0: jr at 1000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x1000 0x1000>;
> >                                       interrupts = <GIC_SPI 105
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     status = "disabled";
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr1: jr at 2000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x2000 0x1000>;
> >                                       interrupts = <GIC_SPI 106
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "okay";
> >                               };
> >
> >                               sec_jr2: jr at 3000 {
> >                                       compatible = "fsl,sec-v4.0-job-ring";
> >                                       reg = <0x3000 0x1000>;
> >                                       interrupts = <GIC_SPI 114
> IRQ_TYPE_LEVEL_HIGH>;
> > +                                     secure-status = "disabled";
> >                               };
> >                       };
> >
> 
> --
> Pengutronix e.K.           | Rouven Czerwinski          |
> Steuerwalder Str. 21       | http://www.pengutronix.de/ |
> 31137 Hildesheim, Germany  | Phone: +49-5121-206917-0   |


-- andrey

From andy.shevchenko at gmail.com  Thu Jan  6 06:23:28 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Thu, 6 Jan 2022 16:23:28 +0200
Subject: [PATCH v6] soc: ti: smartreflex: Use platform_get_irq_optional()
 to get the interrupt
In-Reply-To: <20220105180323.8563-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220105180323.8563-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CAHp75Veud0JbA0Gury3pK942xnyRzwums3_Kt=0ENbrDw3yrUQ@mail.gmail.com>

On Wed, Jan 5, 2022 at 8:03 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:
>
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq_optional().
>
> While at it return 0 instead of returning ret in the probe success path.

LGTM, thanks, FWIW,
Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>

> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v5->v6:
> * Dropped printing function name in error message.
>
> v4->v5:
> * Fixed missing return while using dev_err_probe().
>
> v3->v4:
> * Used dev_err_probe() to print error message
> * Returning 0 in probe success path.
>
> v2->v3
> * Switch back to platform_get_irq_optional()
> * Only print error in case of error, and not when interrupt is missing.
>
> v1->v2
> * Updated commit message
> * Drop check for IRQ0
> * Switched to using platform_get_irq() so that the probe won't
>   fail silently as requested by Nishanth.
>
> v1:
> * https://www.spinics.net/lists/arm-kernel/msg942549.html
> ---
>  drivers/soc/ti/smartreflex.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c
> index b5b2fa538d5c..ad2bb72e640c 100644
> --- a/drivers/soc/ti/smartreflex.c
> +++ b/drivers/soc/ti/smartreflex.c
> @@ -819,7 +819,7 @@ static int omap_sr_probe(struct platform_device *pdev)
>  {
>         struct omap_sr *sr_info;
>         struct omap_sr_data *pdata = pdev->dev.platform_data;
> -       struct resource *mem, *irq;
> +       struct resource *mem;
>         struct dentry *nvalue_dir;
>         int i, ret = 0;
>
> @@ -844,7 +844,11 @@ static int omap_sr_probe(struct platform_device *pdev)
>         if (IS_ERR(sr_info->base))
>                 return PTR_ERR(sr_info->base);
>
> -       irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> +       ret = platform_get_irq_optional(pdev, 0);
> +       if (ret < 0 && ret != -ENXIO)
> +               return dev_err_probe(&pdev->dev, ret, "failed to get IRQ resource\n");
> +       if (ret > 0)
> +               sr_info->irq = ret;
>
>         sr_info->fck = devm_clk_get(pdev->dev.parent, "fck");
>         if (IS_ERR(sr_info->fck))
> @@ -870,9 +874,6 @@ static int omap_sr_probe(struct platform_device *pdev)
>         sr_info->autocomp_active = false;
>         sr_info->ip_type = pdata->ip_type;
>
> -       if (irq)
> -               sr_info->irq = irq->start;
> -
>         sr_set_clk_length(sr_info);
>
>         list_add(&sr_info->node, &sr_list);
> @@ -926,7 +927,7 @@ static int omap_sr_probe(struct platform_device *pdev)
>
>         }
>
> -       return ret;
> +       return 0;
>
>  err_debugfs:
>         debugfs_remove_recursive(sr_info->dbg_dir);
> --
> 2.17.1
>


-- 
With Best Regards,
Andy Shevchenko


From lorenzo.pieralisi at arm.com  Thu Jan  6 06:45:18 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 6 Jan 2022 14:45:18 +0000
Subject: [PATCH v4 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <a2406bf515124afad50ca3c947e2cd758c0896b1.1640587131.git.baruch@tkos.co.il>
References: <cover.1640587131.git.baruch@tkos.co.il>
 <a2406bf515124afad50ca3c947e2cd758c0896b1.1640587131.git.baruch@tkos.co.il>
Message-ID: <20220106144518.GA15482@lpieralisi>

[+Pali - query on reset delay]

On Mon, Dec 27, 2021 at 08:46:05AM +0200, Baruch Siach wrote:
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> 
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
> 
> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
> win.linuxopenwrt.2.0).
> 
> Split out the DBI registers access part from .init into .post_init. DBI
> registers are only accessible after phy_power_on().
> 
> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
> 
> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> ---
> v4:
> 
>   * Rebase on v5.16-rc1
> 
> v3:
>   * Drop speed setup; rely on generic code (Rob Herring)
> 
>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
> 
>   * Minor formatting fixes (Bjorn Helgaas)
> 
>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
> 
> v2:
>   * Drop ATU configuration; rely on common code instead
> 
>   * Use more common register macros
> 
>   * Use bulk clk and reset APIs
> ---
>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>  drivers/pci/controller/dwc/pcie-qcom.c       | 145 +++++++++++++++++++
>  2 files changed, 146 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index ea87809ee298..279c3778a13b 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -76,6 +76,7 @@
>  
>  #define GEN3_RELATED_OFF			0x890
>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 1c3d1116bb60..14f86c45a8d9 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -52,6 +52,10 @@
>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
> +#define AHB_CLK_EN				BIT(0)
> +#define MSTR_AXI_CLK_EN				BIT(1)
> +#define BYPASS					BIT(4)
> +
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
>  #define PCIE20_PARF_LTSSM			0x1B0
> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
>  	struct clk *ref_clk_src;
>  };
>  
> +struct qcom_pcie_resources_2_9_0 {
> +	struct clk_bulk_data clks[5];
> +	struct reset_control *rst;
> +};
> +
>  union qcom_pcie_resources {
>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
>  };
>  
>  struct qcom_pcie;
> @@ -1297,6 +1307,127 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>  	clk_disable_unprepare(res->pipe_clk);
>  }
>  
> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +	struct dw_pcie *pci = pcie->pci;
> +	struct device *dev = pci->dev;
> +	int ret;
> +
> +	res->clks[0].id = "iface";
> +	res->clks[1].id = "axi_m";
> +	res->clks[2].id = "axi_s";
> +	res->clks[3].id = "axi_bridge";
> +	res->clks[4].id = "rchng";
> +
> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> +	if (ret < 0)
> +		return ret;
> +
> +	res->rst = devm_reset_control_array_get_exclusive(dev);
> +	if (IS_ERR(res->rst))
> +		return PTR_ERR(res->rst);
> +
> +	return 0;
> +}
> +
> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> +}
> +
> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +	struct device *dev = pcie->pci->dev;
> +	int ret;
> +
> +	ret = reset_control_assert(res->rst);
> +	if (ret) {
> +		dev_err(dev, "reset assert failed (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	usleep_range(2000, 2500);
> +
> +	ret = reset_control_deassert(res->rst);
> +	if (ret) {
> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	/*
> +	 * Don't have a way to see if the reset has completed.
> +	 * Wait for some time.

Is this arbitrary ? What does this reset represent ?

Thanks,
Lorenzo

> +	 */
> +	usleep_range(2000, 2500);
> +
> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> +	if (ret)
> +		goto err_reset;
> +
> +	return 0;
> +
> +	/*
> +	 * Not checking for failure, will anyway return
> +	 * the original failure in 'ret'.
> +	 */
> +err_reset:
> +	reset_control_assert(res->rst);
> +
> +	return ret;
> +}
> +
> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct dw_pcie *pci = pcie->pci;
> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> +	u32 val;
> +	int i;
> +
> +	writel(SLV_ADDR_SPACE_SZ,
> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> +
> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> +	val &= ~BIT(0);
> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> +
> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> +
> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> +		pci->dbi_base + GEN3_RELATED_OFF);
> +
> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
> +
> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> +
> +	dw_pcie_dbi_ro_wr_en(pci);
> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> +
> +	/* Configure PCIe link capabilities for ASPM */
> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +
> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> +			PCI_EXP_DEVCTL2);
> +
> +	for (i = 0; i < 256; i++)
> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> +				+ (4 * i));
> +
> +	return 0;
> +}
> +
>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>  {
>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> @@ -1487,6 +1618,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>  	.config_sid = qcom_pcie_config_sid_sm8250,
>  };
>  
> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> +static const struct qcom_pcie_ops ops_2_9_0 = {
> +	.get_resources = qcom_pcie_get_resources_2_9_0,
> +	.init = qcom_pcie_init_2_9_0,
> +	.post_init = qcom_pcie_post_init_2_9_0,
> +	.deinit = qcom_pcie_deinit_2_9_0,
> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct qcom_pcie_cfg apq8084_cfg = {
>  	.ops = &ops_1_0_0,
>  };
> @@ -1520,6 +1660,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
>  	.pipe_clk_need_muxing = true,
>  };
>  
> +static const struct qcom_pcie_cfg ipq6018_cfg = {
> +	.ops = &ops_2_9_0,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>  	.link_up = qcom_pcie_link_up,
>  	.start_link = qcom_pcie_start_link,
> @@ -1629,6 +1773,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
>  	{ }
>  };
>  
> -- 
> 2.34.1
> 


From quic_schowdhu at quicinc.com  Thu Jan  6 07:20:00 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Thu, 6 Jan 2022 20:50:00 +0530
Subject: [PATCH V6 0/7] Add driver support for Data Capture and Compare
 Engine(DCC) for SM8150,SC7280,SC7180,SDM845
In-Reply-To: <396edd95-4f38-6830-99da-11e73d62a0cf@linaro.org>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <396edd95-4f38-6830-99da-11e73d62a0cf@linaro.org>
Message-ID: <705c280b-bced-476d-8e21-1a5afbf3d2f3@quicinc.com>


On 12/16/2021 9:18 PM, Thara Gopinath wrote:
>
>
> On 8/10/21 1:54 PM, Souradeep Chowdhury wrote:
>> DCC(Data Capture and Compare) is a DMA engine designed for debugging 
>> purposes.In case of a system
>> crash or manual software triggers by the user the DCC hardware stores 
>> the value at the register
>> addresses which can be used for debugging purposes.The DCC driver 
>> provides the user with sysfs
>> interface to configure the register addresses.The options that the 
>> DCC hardware provides include
>> reading from registers,writing to registers,first reading and then 
>> writing to registers and looping
>> through the values of the same register.
>>
>> In certain cases a register write needs to be executed for accessing 
>> the rest of the registers,
>> also the user might want to record the changing values of a register 
>> with time for which he has the
>> option to use the loop feature.
>
> Hello Souradeep,
>
> First of all, I think this is very a useful feature to have. I have 
> some generic design related queries/comments on driver and the 
> interface exposed to the user space. Also, I do not understand the h/w 
> well here, so feel free to correct me if I am wrong.
>
> 1. Linked list looks like a very internal feature to the h/w. It 
> really is not an info that user should be aware of. I tried reading 
> the code a bit. IUC, every time a s/w trigger is issued the configs in 
> all the enabled linked lists are executed. The final ram dump that you 
> get from /dev/dcc_sram is a dump of contents from all the enabled 
> list? Is this understanding correct ? And we are talking of at-most 4 
> linked list?
> If yes, I think it might be better to have a folder per linked list 
> with config, config_write etc. Also if possible it will be better to 
> dump the results to a file in the specific folder instead of reading 
> from /dev/dcc_sram.
> If no, there is no real need for user to know the linked list, right? 
> Choosing of linked list can be done by kernel driver in this case with 
> no input needed from user.
>
> 2. Now to the sysfs interface itself, I know lot of thought has gone 
> into sysfs vs debugfs considerations. But, have you considered using 
> netlink interface instead of sysfs. Netlink interface is used for 
> asynchronous communication between kernel and user space. In case of 
> DCC, the communication appears to be asynchronous, where in user asks 
> the kernel to capture some info and kernel can indicate back to user 
> when the info is captured. Also the entire mess surrounding echoing 
> addr / value / offset repeatedly into a sysfs entry can be avoided 
> using netlink interface.
>
Hello Thara,

Thanks for your review comments. Following are some points from my end


1) Each linked list represent a particular block of memory in DCC_SRAM 
which is preserved for that particular list. That is why offset 
calculation is done on the driver based on the linked list chosen by the 
user.

 ??? This choice needs to be made by the user since the number for the 
linked list chosen is specific to the registers used to debug a 
particular component.? Also we are giving the user flexibility to 
configure multiple

 ??? linked lists at one go so that even if we don't have a separate 
folder for it , the dumps are collected as a separate list of registers. 
Also there are certain curr_list values which may be supported by the dcc

 ??? hardware but may not be accessible to the user and so the choice 
cannot be made arbitrarily from the driver.


2) From opensource, I can see that Netlink has been used in most of the 
cases where we need to notify stats to the user by taking the advantage 
of asynchronous communication. In this case, that requirement is not

 ? ? there since it is mostly one way communication from user to kernel. 
Also since this is used for debugging purposes perhaps sysfs adds more 
reliability than Netlink. In case of Netlink we have the additional

 ???? overhead of dealing with socket calls. Let me know otherwise.


Thanks,

Souradeep







From maz at kernel.org  Thu Jan  6 07:28:20 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 15:28:20 +0000
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220105150239.9628-11-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
Message-ID: <87bl0ovq7f.wl-maz@kernel.org>

On Wed, 05 Jan 2022 15:02:38 +0000,
Pali Roh?r <pali at kernel.org> wrote:
> 
> This adds support for legacy INTx interrupts received from other PCIe
> devices and which are reported by a new INTx irq chip.
> 
> With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> interrupts.
> 
> Note that for this support, device tree files has to be properly adjusted
> to provide "interrupts" or "interrupts-extended" property with intx
> interrupt source, "interrupt-names" property with "intx" string and also
> 'interrupt-controller' subnode must be defined.
> 
> If device tree files do not provide these nodes then driver would work as
> before.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
>  1 file changed, 174 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 1e90ab888075..04bcdd7b7a6d 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -54,9 +54,10 @@
>  	 PCIE_CONF_ADDR_EN)
>  #define PCIE_CONF_DATA_OFF	0x18fc
>  #define PCIE_INT_CAUSE_OFF	0x1900
> +#define PCIE_INT_UNMASK_OFF	0x1910
> +#define  PCIE_INT_INTX(i)		BIT(24+i)
>  #define  PCIE_INT_PM_PME		BIT(28)
> -#define PCIE_MASK_OFF		0x1910
> -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
>  #define PCIE_CTRL_OFF		0x1a00
>  #define  PCIE_CTRL_X1_MODE		0x0001
>  #define  PCIE_CTRL_RC_MODE		BIT(1)
> @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
>  	struct mvebu_pcie_window iowin;
>  	u32 saved_pcie_stat;
>  	struct resource regs;
> +	struct irq_domain *intx_irq_domain;
> +	struct irq_chip intx_irq_chip;

Why is this structure per port? It really should be global. Printing
the port number in the name isn't enough of a reason.

> +	raw_spinlock_t irq_lock;
> +	int intx_irq;
>  };
>  
>  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
>  
>  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  {
> -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
>  
>  	/* Setup PCIe controller to Root Complex mode. */
>  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  	/* Point PCIe unit MBUS decode windows to DRAM space. */
>  	mvebu_pcie_setup_wins(port);
>  
> -	/* Enable interrupt lines A-D. */
> -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> -	mask |= PCIE_MASK_ENABLE_INTS;
> -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> +	/* Mask all interrupt sources. */
> +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> +
> +	/* Clear all interrupt causes. */
> +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> +
> +	if (port->intx_irq <= 0) {
> +		/*
> +		 * When neither "summary" interrupt, nor "intx" interrupt was
> +		 * specified in DT then unmask all legacy INTx interrupts as in
> +		 * this case driver does not provide a way for masking and
> +		 * unmasking of individual legacy INTx interrupts. In this case
> +		 * all interrupts, including legacy INTx are reported via one
> +		 * shared GIC source and therefore kernel cannot distinguish
> +		 * which individual legacy INTx was triggered. These interrupts
> +		 * are shared, so it should not cause any issue. Just
> +		 * performance penalty as every PCIe interrupt handler needs to
> +		 * be called when some interrupt is triggered.
> +		 */
> +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);

Maybe worth printing a warning here, so that the user knows they are
on thin ice.

> +	}
>  }
>  
>  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
>  	.write = mvebu_pcie_wr_conf,
>  };
>  
> +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> +{
> +	struct mvebu_pcie_port *port = d->domain->host_data;
> +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +	unsigned long flags;
> +	u32 unmask;
> +
> +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> +	unmask &= ~PCIE_INT_INTX(hwirq);
> +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> +}
> +
> +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> +{
> +	struct mvebu_pcie_port *port = d->domain->host_data;
> +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> +	unsigned long flags;
> +	u32 unmask;
> +
> +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> +	unmask |= PCIE_INT_INTX(hwirq);
> +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> +}
> +
> +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> +				   unsigned int virq, irq_hw_number_t hwirq)
> +{
> +	struct mvebu_pcie_port *port = h->host_data;
> +
> +	irq_set_status_flags(virq, IRQ_LEVEL);
> +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> +	irq_set_chip_data(virq, port);
> +
> +	return 0;
> +}
> +
> +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> +	.map = mvebu_pcie_intx_irq_map,
> +	.xlate = irq_domain_xlate_onecell,
> +};
> +
> +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> +{
> +	struct device *dev = &port->pcie->pdev->dev;
> +	struct device_node *pcie_intc_node;
> +
> +	raw_spin_lock_init(&port->irq_lock);
> +
> +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> +						  "mvebu-%s-INTx",
> +						  port->name);

That's exactly what I really don't want to see. It prevents sharing of
the irq_chip structure, and gets in the way of making it const in the
future. Yes, I know that some drivers do that. I can't fix those,
because /proc/interrupts is ABI. But I really don't want to see more
of these.

/sys/kernel/debug/irqs already has all the information you need, as it
will happily give you the domain name and the interrupt topology.

> +	port->intx_irq_chip.irq_mask = mvebu_pcie_intx_irq_mask;
> +	port->intx_irq_chip.irq_unmask = mvebu_pcie_intx_irq_unmask;
> +
> +	pcie_intc_node = of_get_next_child(port->dn, NULL);
> +	if (!pcie_intc_node) {
> +		dev_err(dev, "No PCIe Intc node found for %s\n", port->name);
> +		return -ENODEV;
> +	}
> +
> +	port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
> +						      &mvebu_pcie_intx_irq_domain_ops,
> +						      port);
> +	of_node_put(pcie_intc_node);
> +	if (!port->intx_irq_domain) {
> +		devm_kfree(dev, port->intx_irq_chip.name);
> +		dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name);
> +		return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
> +static void mvebu_pcie_irq_handler(struct irq_desc *desc)
> +{
> +	struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc);
> +	struct irq_chip *chip = irq_desc_get_chip(desc);
> +	struct device *dev = &port->pcie->pdev->dev;
> +	u32 cause, unmask, status;
> +	int i;
> +
> +	chained_irq_enter(chip, desc);
> +
> +	cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF);
> +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);

Why do you need to read this? If the CAUSE register also returns the
masked interrupts that are pending, it may be worth keeping a shadow
copy of the this register, as you end-up having an extra MMIO read on
each and every interrupt, which can't be great for performance.

> +	status = cause & unmask;
> +
> +	/* Process legacy INTx interrupts */
> +	for (i = 0; i < PCI_NUM_INTX; i++) {
> +		if (!(status & PCIE_INT_INTX(i)))
> +			continue;
> +
> +		if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL)
> +			dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A');
> +	}
> +
> +	chained_irq_exit(chip, desc);
> +}
> +
>  static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
>  {
>  	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> @@ -1121,6 +1249,16 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  		port->io_attr = -1;
>  	}
>  
> +	/*
> +	 * Old DT bindings do not contain "intx" interrupt
> +	 * so do not fail probing driver when interrupt does not exist.
> +	 */
> +	port->intx_irq = of_irq_get_byname(child, "intx");
> +	if (port->intx_irq == -EPROBE_DEFER) {
> +		ret = port->intx_irq;
> +		goto err;
> +	}
> +
>  	reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags);
>  	if (reset_gpio == -EPROBE_DEFER) {
>  		ret = reset_gpio;
> @@ -1317,6 +1455,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
>  
>  	for (i = 0; i < pcie->nports; i++) {
>  		struct mvebu_pcie_port *port = &pcie->ports[i];
> +		int irq = port->intx_irq;
>  
>  		child = port->dn;
>  		if (!child)
> @@ -1344,6 +1483,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
>  			continue;
>  		}
>  
> +		if (irq > 0) {
> +			ret = mvebu_pcie_init_irq_domain(port);
> +			if (ret) {
> +				dev_err(dev, "%s: cannot init irq domain\n",
> +					port->name);
> +				pci_bridge_emul_cleanup(&port->bridge);
> +				devm_iounmap(dev, port->base);
> +				port->base = NULL;
> +				mvebu_pcie_powerdown(port);
> +				continue;
> +			}
> +			irq_set_chained_handler_and_data(irq,
> +							 mvebu_pcie_irq_handler,
> +							 port);
> +		}
> +
>  		/*
>  		 * PCIe topology exported by mvebu hw is quite complicated. In
>  		 * reality has something like N fully independent host bridges
> @@ -1448,6 +1603,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  
>  	for (i = 0; i < pcie->nports; i++) {
>  		struct mvebu_pcie_port *port = &pcie->ports[i];
> +		int irq = port->intx_irq;
>  
>  		if (!port->base)
>  			continue;
> @@ -1458,7 +1614,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  		mvebu_writel(port, cmd, PCIE_CMD_OFF);
>  
>  		/* Mask all interrupt sources. */
> -		mvebu_writel(port, 0, PCIE_MASK_OFF);
> +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> +
> +		/* Clear all interrupt causes. */
> +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> +
> +		/* Remove IRQ domains. */
> +		if (port->intx_irq_domain)
> +			irq_domain_remove(port->intx_irq_domain);
> +
> +		if (irq > 0)
> +			irq_set_chained_handler_and_data(irq, NULL, NULL);
>  
>  		/* Free config space for emulated root bridge. */
>  		pci_bridge_emul_cleanup(&port->bridge);

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From pali at kernel.org  Thu Jan  6 07:44:47 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 6 Jan 2022 16:44:47 +0100
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <87bl0ovq7f.wl-maz@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
Message-ID: <20220106154447.aie6taiuvav5wu6y@pali>

On Thursday 06 January 2022 15:28:20 Marc Zyngier wrote:
> On Wed, 05 Jan 2022 15:02:38 +0000,
> Pali Roh?r <pali at kernel.org> wrote:
> > 
> > This adds support for legacy INTx interrupts received from other PCIe
> > devices and which are reported by a new INTx irq chip.
> > 
> > With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> > interrupts.
> > 
> > Note that for this support, device tree files has to be properly adjusted
> > to provide "interrupts" or "interrupts-extended" property with intx
> > interrupt source, "interrupt-names" property with "intx" string and also
> > 'interrupt-controller' subnode must be defined.
> > 
> > If device tree files do not provide these nodes then driver would work as
> > before.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
> >  1 file changed, 174 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 1e90ab888075..04bcdd7b7a6d 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -54,9 +54,10 @@
> >  	 PCIE_CONF_ADDR_EN)
> >  #define PCIE_CONF_DATA_OFF	0x18fc
> >  #define PCIE_INT_CAUSE_OFF	0x1900
> > +#define PCIE_INT_UNMASK_OFF	0x1910
> > +#define  PCIE_INT_INTX(i)		BIT(24+i)
> >  #define  PCIE_INT_PM_PME		BIT(28)
> > -#define PCIE_MASK_OFF		0x1910
> > -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> > +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
> >  #define PCIE_CTRL_OFF		0x1a00
> >  #define  PCIE_CTRL_X1_MODE		0x0001
> >  #define  PCIE_CTRL_RC_MODE		BIT(1)
> > @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
> >  	struct mvebu_pcie_window iowin;
> >  	u32 saved_pcie_stat;
> >  	struct resource regs;
> > +	struct irq_domain *intx_irq_domain;
> > +	struct irq_chip intx_irq_chip;
> 
> Why is this structure per port? It really should be global. Printing
> the port number in the name isn't enough of a reason.

Because each port has its own independent set of INTA-INTD interrupts.

> > +	raw_spinlock_t irq_lock;
> > +	int intx_irq;
> >  };
> >  
> >  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> > @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> >  
> >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> >  {
> > -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> > +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> >  
> >  	/* Setup PCIe controller to Root Complex mode. */
> >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> > @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> >  	/* Point PCIe unit MBUS decode windows to DRAM space. */
> >  	mvebu_pcie_setup_wins(port);
> >  
> > -	/* Enable interrupt lines A-D. */
> > -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> > -	mask |= PCIE_MASK_ENABLE_INTS;
> > -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> > +	/* Mask all interrupt sources. */
> > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > +
> > +	/* Clear all interrupt causes. */
> > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > +
> > +	if (port->intx_irq <= 0) {
> > +		/*
> > +		 * When neither "summary" interrupt, nor "intx" interrupt was
> > +		 * specified in DT then unmask all legacy INTx interrupts as in
> > +		 * this case driver does not provide a way for masking and
> > +		 * unmasking of individual legacy INTx interrupts. In this case
> > +		 * all interrupts, including legacy INTx are reported via one
> > +		 * shared GIC source and therefore kernel cannot distinguish
> > +		 * which individual legacy INTx was triggered. These interrupts
> > +		 * are shared, so it should not cause any issue. Just
> > +		 * performance penalty as every PCIe interrupt handler needs to
> > +		 * be called when some interrupt is triggered.
> > +		 */
> > +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> > +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> > +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> 
> Maybe worth printing a warning here, so that the user knows they are
> on thin ice.

Ok. I can add it here. Anyway, this is default current state without
this patch.

> > +	}
> >  }
> >  
> >  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
> >  	.write = mvebu_pcie_wr_conf,
> >  };
> >  
> > +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> > +{
> > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > +	unsigned long flags;
> > +	u32 unmask;
> > +
> > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > +	unmask &= ~PCIE_INT_INTX(hwirq);
> > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > +}
> > +
> > +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> > +{
> > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > +	unsigned long flags;
> > +	u32 unmask;
> > +
> > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > +	unmask |= PCIE_INT_INTX(hwirq);
> > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > +}
> > +
> > +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> > +				   unsigned int virq, irq_hw_number_t hwirq)
> > +{
> > +	struct mvebu_pcie_port *port = h->host_data;
> > +
> > +	irq_set_status_flags(virq, IRQ_LEVEL);
> > +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> > +	irq_set_chip_data(virq, port);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> > +	.map = mvebu_pcie_intx_irq_map,
> > +	.xlate = irq_domain_xlate_onecell,
> > +};
> > +
> > +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> > +{
> > +	struct device *dev = &port->pcie->pdev->dev;
> > +	struct device_node *pcie_intc_node;
> > +
> > +	raw_spin_lock_init(&port->irq_lock);
> > +
> > +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> > +						  "mvebu-%s-INTx",
> > +						  port->name);
> 
> That's exactly what I really don't want to see. It prevents sharing of
> the irq_chip structure, and gets in the way of making it const in the
> future. Yes, I know that some drivers do that. I can't fix those,
> because /proc/interrupts is ABI. But I really don't want to see more
> of these.

Well, I do not understand why it should be shared and with who. HW has N
independent IRQ chips for legacy interrupts. And each one will be
specified in DT per HW layout / design.

> /sys/kernel/debug/irqs already has all the information you need, as it
> will happily give you the domain name and the interrupt topology.
> 
> > +	port->intx_irq_chip.irq_mask = mvebu_pcie_intx_irq_mask;
> > +	port->intx_irq_chip.irq_unmask = mvebu_pcie_intx_irq_unmask;
> > +
> > +	pcie_intc_node = of_get_next_child(port->dn, NULL);
> > +	if (!pcie_intc_node) {
> > +		dev_err(dev, "No PCIe Intc node found for %s\n", port->name);
> > +		return -ENODEV;
> > +	}
> > +
> > +	port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
> > +						      &mvebu_pcie_intx_irq_domain_ops,
> > +						      port);
> > +	of_node_put(pcie_intc_node);
> > +	if (!port->intx_irq_domain) {
> > +		devm_kfree(dev, port->intx_irq_chip.name);
> > +		dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void mvebu_pcie_irq_handler(struct irq_desc *desc)
> > +{
> > +	struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc);
> > +	struct irq_chip *chip = irq_desc_get_chip(desc);
> > +	struct device *dev = &port->pcie->pdev->dev;
> > +	u32 cause, unmask, status;
> > +	int i;
> > +
> > +	chained_irq_enter(chip, desc);
> > +
> > +	cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF);
> > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> 
> Why do you need to read this? If the CAUSE register also returns the
> masked interrupts that are pending,

Yes, it returns all interrupts, even those which are masked for which is
not system interested.

> it may be worth keeping a shadow
> copy of the this register, as you end-up having an extra MMIO read on
> each and every interrupt, which can't be great for performance.

Ok. I can set shadow copy of unmask register into port structure. But it
has really performance impact when reading directly unmask register from
hw and when reading it from port shadow copy structure?

> > +	status = cause & unmask;
> > +
> > +	/* Process legacy INTx interrupts */
> > +	for (i = 0; i < PCI_NUM_INTX; i++) {
> > +		if (!(status & PCIE_INT_INTX(i)))
> > +			continue;
> > +
> > +		if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL)
> > +			dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A');
> > +	}
> > +
> > +	chained_irq_exit(chip, desc);
> > +}
> > +
> >  static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> >  {
> >  	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> > @@ -1121,6 +1249,16 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> >  		port->io_attr = -1;
> >  	}
> >  
> > +	/*
> > +	 * Old DT bindings do not contain "intx" interrupt
> > +	 * so do not fail probing driver when interrupt does not exist.
> > +	 */
> > +	port->intx_irq = of_irq_get_byname(child, "intx");
> > +	if (port->intx_irq == -EPROBE_DEFER) {
> > +		ret = port->intx_irq;
> > +		goto err;
> > +	}
> > +
> >  	reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags);
> >  	if (reset_gpio == -EPROBE_DEFER) {
> >  		ret = reset_gpio;
> > @@ -1317,6 +1455,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
> >  
> >  	for (i = 0; i < pcie->nports; i++) {
> >  		struct mvebu_pcie_port *port = &pcie->ports[i];
> > +		int irq = port->intx_irq;
> >  
> >  		child = port->dn;
> >  		if (!child)
> > @@ -1344,6 +1483,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
> >  			continue;
> >  		}
> >  
> > +		if (irq > 0) {
> > +			ret = mvebu_pcie_init_irq_domain(port);
> > +			if (ret) {
> > +				dev_err(dev, "%s: cannot init irq domain\n",
> > +					port->name);
> > +				pci_bridge_emul_cleanup(&port->bridge);
> > +				devm_iounmap(dev, port->base);
> > +				port->base = NULL;
> > +				mvebu_pcie_powerdown(port);
> > +				continue;
> > +			}
> > +			irq_set_chained_handler_and_data(irq,
> > +							 mvebu_pcie_irq_handler,
> > +							 port);
> > +		}
> > +
> >  		/*
> >  		 * PCIe topology exported by mvebu hw is quite complicated. In
> >  		 * reality has something like N fully independent host bridges
> > @@ -1448,6 +1603,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
> >  
> >  	for (i = 0; i < pcie->nports; i++) {
> >  		struct mvebu_pcie_port *port = &pcie->ports[i];
> > +		int irq = port->intx_irq;
> >  
> >  		if (!port->base)
> >  			continue;
> > @@ -1458,7 +1614,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
> >  		mvebu_writel(port, cmd, PCIE_CMD_OFF);
> >  
> >  		/* Mask all interrupt sources. */
> > -		mvebu_writel(port, 0, PCIE_MASK_OFF);
> > +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > +
> > +		/* Clear all interrupt causes. */
> > +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > +
> > +		/* Remove IRQ domains. */
> > +		if (port->intx_irq_domain)
> > +			irq_domain_remove(port->intx_irq_domain);
> > +
> > +		if (irq > 0)
> > +			irq_set_chained_handler_and_data(irq, NULL, NULL);
> >  
> >  		/* Free config space for emulated root bridge. */
> >  		pci_bridge_emul_cleanup(&port->bridge);
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From maz at kernel.org  Thu Jan  6 07:55:11 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 15:55:11 +0000
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220106154447.aie6taiuvav5wu6y@pali>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
Message-ID: <878rvsvoyo.wl-maz@kernel.org>

On Thu, 06 Jan 2022 15:44:47 +0000,
Pali Roh?r <pali at kernel.org> wrote:
> 
> On Thursday 06 January 2022 15:28:20 Marc Zyngier wrote:
> > On Wed, 05 Jan 2022 15:02:38 +0000,
> > Pali Roh?r <pali at kernel.org> wrote:
> > > 
> > > This adds support for legacy INTx interrupts received from other PCIe
> > > devices and which are reported by a new INTx irq chip.
> > > 
> > > With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> > > interrupts.
> > > 
> > > Note that for this support, device tree files has to be properly adjusted
> > > to provide "interrupts" or "interrupts-extended" property with intx
> > > interrupt source, "interrupt-names" property with "intx" string and also
> > > 'interrupt-controller' subnode must be defined.
> > > 
> > > If device tree files do not provide these nodes then driver would work as
> > > before.
> > > 
> > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > ---
> > >  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
> > >  1 file changed, 174 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > index 1e90ab888075..04bcdd7b7a6d 100644
> > > --- a/drivers/pci/controller/pci-mvebu.c
> > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > @@ -54,9 +54,10 @@
> > >  	 PCIE_CONF_ADDR_EN)
> > >  #define PCIE_CONF_DATA_OFF	0x18fc
> > >  #define PCIE_INT_CAUSE_OFF	0x1900
> > > +#define PCIE_INT_UNMASK_OFF	0x1910
> > > +#define  PCIE_INT_INTX(i)		BIT(24+i)
> > >  #define  PCIE_INT_PM_PME		BIT(28)
> > > -#define PCIE_MASK_OFF		0x1910
> > > -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> > > +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
> > >  #define PCIE_CTRL_OFF		0x1a00
> > >  #define  PCIE_CTRL_X1_MODE		0x0001
> > >  #define  PCIE_CTRL_RC_MODE		BIT(1)
> > > @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
> > >  	struct mvebu_pcie_window iowin;
> > >  	u32 saved_pcie_stat;
> > >  	struct resource regs;
> > > +	struct irq_domain *intx_irq_domain;
> > > +	struct irq_chip intx_irq_chip;
> > 
> > Why is this structure per port? It really should be global. Printing
> > the port number in the name isn't enough of a reason.
> 
> Because each port has its own independent set of INTA-INTD
> interrupts.

That doesn't warrant a copy of an irq_chip structure that contains the
exact same callbacks, and only differs by *a string*. And the use of
this string is only to end-up in /proc/interrupts, which is totally
pointless.

> 
> > > +	raw_spinlock_t irq_lock;
> > > +	int intx_irq;
> > >  };
> > >  
> > >  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> > > @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > >  
> > >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > >  {
> > > -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> > > +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> > >  
> > >  	/* Setup PCIe controller to Root Complex mode. */
> > >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> > > @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > >  	/* Point PCIe unit MBUS decode windows to DRAM space. */
> > >  	mvebu_pcie_setup_wins(port);
> > >  
> > > -	/* Enable interrupt lines A-D. */
> > > -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> > > -	mask |= PCIE_MASK_ENABLE_INTS;
> > > -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> > > +	/* Mask all interrupt sources. */
> > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > > +
> > > +	/* Clear all interrupt causes. */
> > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > > +
> > > +	if (port->intx_irq <= 0) {
> > > +		/*
> > > +		 * When neither "summary" interrupt, nor "intx" interrupt was
> > > +		 * specified in DT then unmask all legacy INTx interrupts as in
> > > +		 * this case driver does not provide a way for masking and
> > > +		 * unmasking of individual legacy INTx interrupts. In this case
> > > +		 * all interrupts, including legacy INTx are reported via one
> > > +		 * shared GIC source and therefore kernel cannot distinguish
> > > +		 * which individual legacy INTx was triggered. These interrupts
> > > +		 * are shared, so it should not cause any issue. Just
> > > +		 * performance penalty as every PCIe interrupt handler needs to
> > > +		 * be called when some interrupt is triggered.
> > > +		 */
> > > +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> > > +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> > > +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > 
> > Maybe worth printing a warning here, so that the user knows they are
> > on thin ice.
> 
> Ok. I can add it here. Anyway, this is default current state without
> this patch.
> 
> > > +	}
> > >  }
> > >  
> > >  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > > @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
> > >  	.write = mvebu_pcie_wr_conf,
> > >  };
> > >  
> > > +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> > > +{
> > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > +	unsigned long flags;
> > > +	u32 unmask;
> > > +
> > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > +	unmask &= ~PCIE_INT_INTX(hwirq);
> > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > +}
> > > +
> > > +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> > > +{
> > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > +	unsigned long flags;
> > > +	u32 unmask;
> > > +
> > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > +	unmask |= PCIE_INT_INTX(hwirq);
> > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > +}
> > > +
> > > +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> > > +				   unsigned int virq, irq_hw_number_t hwirq)
> > > +{
> > > +	struct mvebu_pcie_port *port = h->host_data;
> > > +
> > > +	irq_set_status_flags(virq, IRQ_LEVEL);
> > > +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> > > +	irq_set_chip_data(virq, port);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > > +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> > > +	.map = mvebu_pcie_intx_irq_map,
> > > +	.xlate = irq_domain_xlate_onecell,
> > > +};
> > > +
> > > +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> > > +{
> > > +	struct device *dev = &port->pcie->pdev->dev;
> > > +	struct device_node *pcie_intc_node;
> > > +
> > > +	raw_spin_lock_init(&port->irq_lock);
> > > +
> > > +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> > > +						  "mvebu-%s-INTx",
> > > +						  port->name);
> > 
> > That's exactly what I really don't want to see. It prevents sharing of
> > the irq_chip structure, and gets in the way of making it const in the
> > future. Yes, I know that some drivers do that. I can't fix those,
> > because /proc/interrupts is ABI. But I really don't want to see more
> > of these.
> 
> Well, I do not understand why it should be shared and with who. HW has N
> independent IRQ chips for legacy interrupts. And each one will be
> specified in DT per HW layout / design.

If you have multiple ports, all the ports can share the irq_chip
structure. Actually scratch that. They *MUST* share the structure. The
only reason you're not sharing it is to be able to print this useless
string in /proc/interrupts.

	M.

-- 
Without deviation from the norm, progress is not possible.


From catalin.marinas at arm.com  Thu Jan  6 07:56:30 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Jan 2022 15:56:30 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <YdcRLohx777jzWah@arm.com>

On Thu, Jan 06, 2022 at 10:13:06AM +0000, Jianyong Wu wrote:
> I test this patch in your way using both EDK2 V2.6 and EDK2 v2.7. it's
> peculiar that this issue shows up on v2.6 but not on v2.7.
> For now, I only find that if "CONFIG_DEBUG_LOCK_ALLOC" is enabled, the
> kernel boot will hang. However, I can't debug it by printk as this
> issue happens before pl11 is ready.

I tried earlycon but that doesn't help either.

> I will go on debugging, but very appreciated if someone can give some
> hints on it.

FWIW, passing "nokaslr" on the kernel command line makes it boot (and
this makes debugging harder). That's as far as I've gone.

-- 
Catalin


From jim2101024 at gmail.com  Thu Jan  6 08:03:23 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:23 -0500
Subject: [PATCH v11 0/7] PCI: brcmstb: root port turns on sub-device power
Message-ID: <20220106160332.2143-1-jim2101024@gmail.com>

v11 -- Only one commit has changed from v10: "PCI: brcmstb: Add mechanism
       to turn on subdev regulators". Lorenzo requested that this commit's
       code be moved from pci/pci.h and pci/bus.c to
       pci/controller/pcie-brcmstb.c as a stopgap measure until we figure
       out a better way of offering this feature for all.  This will most
       likely involve Pali's upcoming changes to refactor PCI host probe
       code.

v10 -- Bindings commit example: in comment, refer to bridge under
       controller node as a root port. (Pali)
    -- Bindings commit example: remove three properties that are not
       appropriate for a PCIe endpoint node. (Rob)

v9  -- Simplify where this mechanism works: instead of looking for
       regulators below every bridge, just look for them at the
       bridge under the root bus (root port).  Now there is no
       modification of portdrv_{pci,core}.c in this submission.
    -- Although Pali is working on support for probing native
       PCIe controller drivers, this work may take some time to
       implement and it still might not be able to accomodate
       our driver's requirements (e.g. vreg suspend/resume control).
    -- Move regulator suspend/resume control to Brcm RC driver.  It
       must reside there because (a) in order to know when to
       initiate linkup during resume and (b) to turn on the
       regulators before any config-space accesses occur.
    -- Commit message spelling, word choice (Bjorn, Krzysztof)
    -- Refactor a small commit that was ignoring a funcs' return
       values (Bjorn).
    -- Here is a summary of this mechanism:

       If:
           -- PCIe RC driver sets pci_ops {add,remove)_bus to
              pci_subdev_regulators_{add,remove}_bus during its probe.
           -- There is a DT node "RB" under the host bridge DT node.
           -- During the RC driver's pci_host_probe() the add_bus callback
              is invoked where (bus->parent && pci_is_root_bus(bus->parent)
              is true

       Then:
           -- A struct subdev_regulators structure will be allocated and
              assigned to bus->dev.driver_data.
           -- regulator_bulk_{get,enable}() will be invoked on &bus->dev
              and the former will search for and process any
              vpcie{12v,3v3,3v3aux}-supply properties that reside in node "RB".
           -- The regulators will be turned off/on for any unbind/bind operations.
           -- The regulators will be turned off/on for any suspend/resumes, but
              only if the RC driver handles this on its own.  This will appear
              in a later commit for the pcie-brcmstb.c driver.

v8  -- Only the two binding commits and the "Change brcm_phy_stop()" commit
       are unchanged.
    -- The code has been moved to portdrv_pci.c and bus.c.  The regulators   
       are placed in bus->dev.driver_data (bus->sysdata is already occupied
       by the Broadcom PCIe).  Two functions, pci_subdev_regulators_{add,remove}_bus()
       are created to turn the regulators on/off.  The pcie_portdriver also sets
       its pci_driver methods suspend and resume when the conditions are
       right for this feature.  (Robh for suggestions, although I probably
       erred in following them).
    -- Have the root complex return 0xffffffff on accesses even when
       the link is down and the HW doesn't support such accesses (PaliR).
    -- Just call devm_bulk_regulator_get() on standard supplies; don't
       bother pre-scanning the DT for them (MarkB).

v7  -- RobH suggested putting the "vpcixxx-supply" property under the
       bridge-node rather than the endpoint device node.  Also, he said to
       use the pci-ops add_bus/remove methods.  Doing so simplifies the
       code greatly and three commits were dropped.  Thanks!

    -- Rob also suggested (I think) having this patchset be a general
       feature which is activated by an OF property under the bridge node.
       I tried to do that but realized that our root complex driver
       controls the regulators with its dev_pm_ops and there is no way to
       transfer this control when using general mechanism.  Note that
       although the regulator core deals with suspend, our RC driver wants
       the right to sometimes to preclude this for WOL scenarios.

    -- One commit was added to change the response to the return value of
       the pci_ops add_bus() method.  Currently, an error causes a WARNING,
       a dev_err(...), and continues to return the child bus.  The
       modification was, for returning -ENOLINK only, to skip WARNING &
       dev_err() and return NULL.  This is necessary for our RC HW, as if
       the code continues on it will do a pci_read_config_dword() for the
       vendor/id, and our HW flags a CPU abort (instead of returning
       0xffffffff) when the is no pcie-link established.

       [NOTE: MarkB, I did not add one of your two "Reviewed-by"s
              because the commit had a decent amount of change.]

v6   -- Dropped the idea of a placeholder regulator
        property (brcm-ep-a-supply). (MarkB)
     -- device_initialize() now called once.  Two
        commits were added for this.  (GKH)
     -- In two cases, separated a single function 
        into two or more functions (MarkB)
     -- "(void)foo();" => "foo()".  Note that although
        foo() returns an int, in this instance it is being
	invoked within a function returning void, and foo()
	already executes a dev_err() on error. (MarkB)
     -- Added a commit to correct PCIe interrupts in YAML.
     -- Removed "device_type = "pci";" for the EP node
        in the YAML example.
     -- Updated the URL related to the voltage regulator
        names on GitHub.  Note that I added vpciev3v3aux.

v5 [NOTE: It has been a while since v4.  Sorry]
     -- See "PCI: allow for callback to prepare nascent subdev"
        commit message for the cornerstone of this patchset
        and the reasons behind it.  This is a new commit.
     -- The RC driver now looks into its DT children and
        turns on regulators for a sub-device, and this occurs
	prior to PCIe link as it must.
     -- Dropped commits not related to the focus of this patchset.

v4 [NOTE: I'm not sure this fixes RobH and MarkB constraints but I'd
          like to use this pullreq as a basis for future discussion.]
   [Commit: Add bindings for ...]
     -- Fix syntax error in YAML bindings example (RobH)
     -- {vpcie12v,vpcie3v3}-supply props are back in root complex DT node
        (I believe RobH said this was okay)
   [Commit: Add control of ..]
     -- Do not do global search for regulator; now we look specifically
        for the property {vpcie12v,vpcie3v3}-supply in the root complex
	DT node and then call devm_regulator_bulk_get() (MarkB)
     -- Use devm_regulator_bulk_get() (Bjorn)
     -- s/EP/slot0 device/ (Bjorn)
     -- Spelling, capitalization (Bjorn)
     -- Have brcm_phy_stop() return a void (Bjorn)
   [Commit: Do not turn off ...]
     -- Capitalization (Bjorn)
   [Commit: Check return value ...]
     -- Commit message content (Bjorn)
     -- Move 6/6 hunk to 2/6 where it belongs (Bjorn)
     -- Move the rest of 6/6 before all other commits (Bjorn)

v3 -- Driver now searches for EP DT subnode for any regulators to turn on.
      If present, these regulators have the property names
      "vpcie12v-supply" and "vpcie3v3-supply".  The existence of these
      regulators in the EP subnode are currently pending as a pullreq
      in pci-bus.yaml at
      https://github.com/devicetree-org/dt-schema/pull/54
      (MarkB, RobH).
   -- Check return of brcm_set_regulators() (Florian)
   -- Specify one regulator string per line for easier update (Florian)
   -- Author/Committer/Signoff email changed from that of V2 from
      'james.quinlan at broadcom.com' to 'jim2101024 at gmail.com'.

v2 -- Use regulator bulk API rather than multiple calls (MarkB).

v1 -- Bindings are added for fixed regulators that may power the EP device.
   -- The brcmstb RC driver is modified to control these regulators
      during probe, suspend, and resume.
   -- 7216 type SOCs have additional error reporting HW and a
      panic handler is added to dump its info.
   -- A missing return value check is added.

Jim Quinlan (7):
  PCI: brcmstb: Fix function return value handling
  dt-bindings: PCI: Correct brcmstb interrupts, interrupt-map.
  dt-bindings: PCI: Add bindings for Brcmstb EP voltage regulators
  PCI: brcmstb: Split brcm_pcie_setup() into two funcs
  PCI: brcmstb: Add mechanism to turn on subdev regulators
  PCI: brcmstb: Add control of subdevice voltage regulators
  PCI: brcmstb: Do not turn off WOL regulators on suspend

 .../bindings/pci/brcm,stb-pcie.yaml           |  27 +-
 drivers/pci/controller/pcie-brcmstb.c         | 284 +++++++++++++++---
 2 files changed, 273 insertions(+), 38 deletions(-)


base-commit: c9e6606c7fe92b50a02ce51dda82586ebdf99b48
prerequisite-patch-id: 0905430e81a95900a1366916fe2940b848317a7c
prerequisite-patch-id: 710896210c50354d87f6025fe0bd1b89981138eb
prerequisite-patch-id: 97d3886cb911cb12ef3d514fdfff2a0ab11e8570
prerequisite-patch-id: 241f1e1878fc177d941f4982ca12779a29feb62b
prerequisite-patch-id: d856608825e2294297db5d7f88f8c180f3e5a1f2
prerequisite-patch-id: 92bcbc9772fb4d248157bcf35e799ac37be8ee45
prerequisite-patch-id: 6f4b1aac459bb54523ade0e87c04e9d6c45bd9f5
prerequisite-patch-id: 090ee7a3112a4ecb03805b23ed10e2c96b3b34ed
prerequisite-patch-id: b3de6b4a4dd7a2f57b86e6548eb345df59de497b
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:24 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:24 -0500
Subject: [PATCH v11 1/7] PCI: brcmstb: Fix function return value handling
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-2-jim2101024@gmail.com>

Do at least a dev_err() on some calls to reset_control_rearm() and
brcm_phy_stop().  In some cases it may not make sense to return this error
value "above" as doing so will cause more trouble than is warranted.

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 28 +++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 1fc7bd49a7ad..9ed79ddb6a83 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -1146,11 +1146,23 @@ static int brcm_pcie_suspend(struct device *dev)
 	int ret;
 
 	brcm_pcie_turn_off(pcie);
-	ret = brcm_phy_stop(pcie);
-	reset_control_rearm(pcie->rescal);
+	/*
+	 * If brcm_phy_stop() returns an error, just dev_err(). If we
+	 * return the error it will cause the suspend to fail and this is a
+	 * forgivable offense that will probably be erased on resume.
+	 */
+	if (brcm_phy_stop(pcie))
+		dev_err(dev, "Could not stop phy for suspend\n");
+
+	ret = reset_control_rearm(pcie->rescal);
+	if (ret) {
+		dev_err(dev, "Could not rearm rescal reset\n");
+		return ret;
+	}
+
 	clk_disable_unprepare(pcie->clk);
 
-	return ret;
+	return 0;
 }
 
 static int brcm_pcie_resume(struct device *dev)
@@ -1161,7 +1173,9 @@ static int brcm_pcie_resume(struct device *dev)
 	int ret;
 
 	base = pcie->base;
-	clk_prepare_enable(pcie->clk);
+	ret = clk_prepare_enable(pcie->clk);
+	if (ret)
+		return ret;
 
 	ret = reset_control_reset(pcie->rescal);
 	if (ret)
@@ -1202,8 +1216,10 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
 {
 	brcm_msi_remove(pcie);
 	brcm_pcie_turn_off(pcie);
-	brcm_phy_stop(pcie);
-	reset_control_rearm(pcie->rescal);
+	if (brcm_phy_stop(pcie))
+		dev_err(pcie->dev, "Could not stop phy\n");
+	if (reset_control_rearm(pcie->rescal))
+		dev_err(pcie->dev, "Could not rearm rescal reset\n");
 	clk_disable_unprepare(pcie->clk);
 }
 
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:25 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:25 -0500
Subject: [PATCH v11 2/7] dt-bindings: PCI: Correct brcmstb interrupts,
 interrupt-map.
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-3-jim2101024@gmail.com>

The "pcie" and "msi" interrupts were given the same interrupt when they are
actually different.  Interrupt-map only had the INTA entry; the INTB, INTC,
and INTD entries are added.

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
index 1fe102743f82..22f2ef446f18 100644
--- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
@@ -143,11 +143,15 @@ examples:
                     #address-cells = <3>;
                     #size-cells = <2>;
                     #interrupt-cells = <1>;
-                    interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                    interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
                                  <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
                     interrupt-names = "pcie", "msi";
                     interrupt-map-mask = <0x0 0x0 0x0 0x7>;
-                    interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+                    interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH
+                                     0 0 0 2 &gicv2 GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH
+                                     0 0 0 3 &gicv2 GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH
+                                     0 0 0 4 &gicv2 GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+
                     msi-parent = <&pcie0>;
                     msi-controller;
                     ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000 0x0 0x04000000>;
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:26 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:26 -0500
Subject: [PATCH v11 3/7] dt-bindings: PCI: Add bindings for Brcmstb EP voltage
 regulators
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-4-jim2101024@gmail.com>

Add bindings for Brcmstb EP voltage regulators.  A new mechanism is to be
added to the Linux PCI subsystem that will allocate and turn on/off
regulators.  These are standard regulators -- vpcie12v, vpcie3v3, and
vpcie3v3aux -- placed in the DT in the bridge node under the host bridge
device.

The use of a regulator property in the pcie EP subnode such as
"vpcie12v-supply" depends on a pending pullreq to the pci-bus.yaml
file at

https://github.com/devicetree-org/dt-schema/pull/63

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
---
 .../bindings/pci/brcm,stb-pcie.yaml           | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
index 22f2ef446f18..3e3c8929c97c 100644
--- a/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
@@ -159,5 +159,24 @@ examples:
                                  <0x42000000 0x1 0x80000000 0x3 0x00000000 0x0 0x80000000>;
                     brcm,enable-ssc;
                     brcm,scb-sizes =  <0x0000000080000000 0x0000000080000000>;
+
+                    /* PCIe bridge, Root Port */
+                    pci at 0,0 {
+                            #address-cells = <3>;
+                            #size-cells = <2>;
+                            reg = <0x0 0x0 0x0 0x0 0x0>;
+                            compatible = "pciclass,0604";
+                            device_type = "pci";
+                            vpcie3v3-supply = <&vreg7>;
+                            ranges;
+
+                            /* PCIe endpoint */
+                            pci-ep at 0,0 {
+                                    assigned-addresses =
+                                        <0x82010000 0x0 0xf8000000 0x6 0x00000000 0x0 0x2000>;
+                                    reg = <0x0 0x0 0x0 0x0 0x0>;
+                                    compatible = "pci14e4,1688";
+                            };
+                    };
             };
     };
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:27 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:27 -0500
Subject: [PATCH v11 4/7] PCI: brcmstb: Split brcm_pcie_setup() into two funcs
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-5-jim2101024@gmail.com>

We need to take some code in brcm_pcie_setup() and put it in a new function
brcm_pcie_linkup().  In future commits the brcm_pcie_linkup() function will
be called indirectly by pci_host_probe() as opposed to the host driver
invoking it directly.

Some code that was executed after the PCIe linkup is now placed so that it
executes prior to linkup, since this code has to run prior to the
invocation of pci_host_probe().

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 65 ++++++++++++++++-----------
 1 file changed, 39 insertions(+), 26 deletions(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 9ed79ddb6a83..5f373227aad6 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -863,16 +863,9 @@ static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie,
 
 static int brcm_pcie_setup(struct brcm_pcie *pcie)
 {
-	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
 	u64 rc_bar2_offset, rc_bar2_size;
 	void __iomem *base = pcie->base;
-	struct device *dev = pcie->dev;
-	struct resource_entry *entry;
-	bool ssc_good = false;
-	struct resource *res;
-	int num_out_wins = 0;
-	u16 nlw, cls, lnksta;
-	int i, ret, memc;
+	int ret, memc;
 	u32 tmp, burst, aspm_support;
 
 	/* Reset the bridge */
@@ -957,6 +950,40 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
 	if (pcie->gen)
 		brcm_pcie_set_gen(pcie, pcie->gen);
 
+	/* Don't advertise L0s capability if 'aspm-no-l0s' */
+	aspm_support = PCIE_LINK_STATE_L1;
+	if (!of_property_read_bool(pcie->np, "aspm-no-l0s"))
+		aspm_support |= PCIE_LINK_STATE_L0S;
+	tmp = readl(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
+	u32p_replace_bits(&tmp, aspm_support,
+		PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK);
+	writel(tmp, base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
+
+	/*
+	 * For config space accesses on the RC, show the right class for
+	 * a PCIe-PCIe bridge (the default setting is to be EP mode).
+	 */
+	tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
+	u32p_replace_bits(&tmp, 0x060400,
+			  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
+	writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
+
+	return 0;
+}
+
+static int brcm_pcie_linkup(struct brcm_pcie *pcie)
+{
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
+	struct device *dev = pcie->dev;
+	void __iomem *base = pcie->base;
+	struct resource_entry *entry;
+	struct resource *res;
+	int num_out_wins = 0;
+	u16 nlw, cls, lnksta;
+	bool ssc_good = false;
+	u32 tmp;
+	int ret, i;
+
 	/* Unassert the fundamental reset */
 	pcie->perst_set(pcie, 0);
 
@@ -994,24 +1021,6 @@ static int brcm_pcie_setup(struct brcm_pcie *pcie)
 		num_out_wins++;
 	}
 
-	/* Don't advertise L0s capability if 'aspm-no-l0s' */
-	aspm_support = PCIE_LINK_STATE_L1;
-	if (!of_property_read_bool(pcie->np, "aspm-no-l0s"))
-		aspm_support |= PCIE_LINK_STATE_L0S;
-	tmp = readl(base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
-	u32p_replace_bits(&tmp, aspm_support,
-		PCIE_RC_CFG_PRIV1_LINK_CAPABILITY_ASPM_SUPPORT_MASK);
-	writel(tmp, base + PCIE_RC_CFG_PRIV1_LINK_CAPABILITY);
-
-	/*
-	 * For config space accesses on the RC, show the right class for
-	 * a PCIe-PCIe bridge (the default setting is to be EP mode).
-	 */
-	tmp = readl(base + PCIE_RC_CFG_PRIV1_ID_VAL3);
-	u32p_replace_bits(&tmp, 0x060400,
-			  PCIE_RC_CFG_PRIV1_ID_VAL3_CLASS_CODE_MASK);
-	writel(tmp, base + PCIE_RC_CFG_PRIV1_ID_VAL3);
-
 	if (pcie->ssc) {
 		ret = brcm_pcie_set_ssc(pcie);
 		if (ret == 0)
@@ -1200,6 +1209,10 @@ static int brcm_pcie_resume(struct device *dev)
 	if (ret)
 		goto err_reset;
 
+	ret = brcm_pcie_linkup(pcie);
+	if (ret)
+		goto err_reset;
+
 	if (pcie->msi)
 		brcm_msi_set_regs(pcie->msi);
 
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:28 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:28 -0500
Subject: [PATCH v11 5/7] PCI: brcmstb: Add mechanism to turn on subdev
 regulators
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-6-jim2101024@gmail.com>

Add a mechanism to identify standard PCIe regulators in the DT, allocate
them, and turn them on before the rest of the bus is scanned during
pci_host_probe().

The allocated structure that contains the regulators is stored in the port
driver dev.driver_data field.  Here is a point-by-point of how and
when this mechanism is activated:

If:
    -- PCIe RC driver sets pci_ops {add,remove)_bus to
       pci_subdev_regulators_{add,remove}_bus during its probe.
    -- There is a DT node "RB" under the host bridge DT node.
    -- During the RC driver's pci_host_probe() the add_bus callback
       is invoked where (bus->parent && pci_is_root_bus(bus->parent)
       is true

Then:
    -- A struct subdev_regulators structure will be allocated and
       assigned to bus->dev.driver_data.
    -- regulator_bulk_{get,enable} will be invoked on &bus->dev
       and the former will search for and process any
       vpcie{12v,3v3,3v3aux}-supply properties that reside in node "RB".
    -- The regulators will be turned off/on for any unbind/bind operations.
    -- The regulators will be turned off/on for any suspend/resumes, but
       only if the RC driver handles this on its own.  This will appear
       in a later commit for the pcie-brcmstb.c driver.

The unabridged reason for doing this is as follows.  We would like the
Broadcom STB PCIe root complex driver (and others) to be able to turn
off/on regulators[1] that provide power to endpoint[2] devices.  Typically,
the drivers of these endpoint devices are stock Linux drivers that are not
aware that these regulator(s) exist and must be turned on for the driver to
be probed.  The simple solution of course is to turn these regulators on at
boot and keep them on.  However, this solution does not satisfy at least
three of our usage modes:

1. For example, one customer uses multiple PCIe controllers, but wants the
ability to, by script invoking and unbind, turn any or all of them by and
their subdevices off to save power, e.g. when in battery mode.

2. Another example is when a watchdog script discovers that an endpoint
device is in an unresponsive state and would like to unbind, power toggle,
and re-bind just the PCIe endpoint and controller.

3. Of course we also want power turned off during suspend mode.  However,
some endpoint devices may be able to "wake" during suspend and we need to
recognise this case and veto the nominal act of turning off its regulator.
Such is the case with Wake-on-LAN and Wake-on-WLAN support where PCIe
end-point device needs to be kept powered on in order to receive network
packets and wake-up the system.

In all of these cases it is advantageous for the PCIe controller to govern
the turning off/on the regulators needed by the endpoint device.  The first
two cases can be done by simply unbinding and binding the PCIe controller,
if the controller has control of these regulators.

[1] These regulators typically govern the actual power supply to the
    endpoint chip.  Sometimes they may be the official PCIe socket
    power -- such as 3.3v or aux-3.3v.  Sometimes they are truly
    the regulator(s) that supply power to the EP chip.

[2] The 99% configuration of our boards is a single endpoint device
    attached to the PCIe controller.  I use the term endpoint but it could
    possibly mean a switch as well.

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 76 +++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 5f373227aad6..7d46eccf17ff 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -24,6 +24,7 @@
 #include <linux/pci.h>
 #include <linux/pci-ecam.h>
 #include <linux/printk.h>
+#include <linux/regulator/consumer.h>
 #include <linux/reset.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
@@ -257,6 +258,14 @@ static const struct pcie_cfg_data bcm2711_cfg = {
 	.bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic,
 };
 
+struct subdev_regulators {
+	unsigned int num_supplies;
+	struct regulator_bulk_data supplies[];
+};
+
+static int pci_subdev_regulators_add_bus(struct pci_bus *bus);
+static void pci_subdev_regulators_remove_bus(struct pci_bus *bus);
+
 struct brcm_msi {
 	struct device		*dev;
 	void __iomem		*base;
@@ -406,6 +415,71 @@ static int brcm_pcie_set_ssc(struct brcm_pcie *pcie)
 	return ssc && pll ? 0 : -EIO;
 }
 
+static void *alloc_subdev_regulators(struct device *dev)
+{
+	static const char * const supplies[] = {
+		"vpcie3v3",
+		"vpcie3v3aux",
+		"vpcie12v",
+	};
+	const size_t size = sizeof(struct subdev_regulators)
+		+ sizeof(struct regulator_bulk_data) * ARRAY_SIZE(supplies);
+	struct subdev_regulators *sr;
+	int i;
+
+	sr = devm_kzalloc(dev, size, GFP_KERNEL);
+	if (sr) {
+		sr->num_supplies = ARRAY_SIZE(supplies);
+		for (i = 0; i < ARRAY_SIZE(supplies); i++)
+			sr->supplies[i].supply = supplies[i];
+	}
+
+	return sr;
+}
+
+static int pci_subdev_regulators_add_bus(struct pci_bus *bus)
+{
+	struct device *dev = &bus->dev;
+	struct subdev_regulators *sr;
+	int ret;
+
+	if (!dev->of_node || !bus->parent || !pci_is_root_bus(bus->parent))
+		return 0;
+
+	if (dev->driver_data)
+		dev_err(dev, "dev.driver_data unexpectedly non-NULL\n");
+
+	sr = alloc_subdev_regulators(dev);
+	if (!sr)
+		return -ENOMEM;
+
+	dev->driver_data = sr;
+	ret = regulator_bulk_get(dev, sr->num_supplies, sr->supplies);
+	if (ret)
+		return ret;
+
+	ret = regulator_bulk_enable(sr->num_supplies, sr->supplies);
+	if (ret) {
+		dev_err(dev, "failed to enable regulators for downstream device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void pci_subdev_regulators_remove_bus(struct pci_bus *bus)
+{
+	struct device *dev = &bus->dev;
+	struct subdev_regulators *sr = dev->driver_data;
+
+	if (!sr || !bus->parent || !pci_is_root_bus(bus->parent))
+		return;
+
+	if (regulator_bulk_disable(sr->num_supplies, sr->supplies))
+		dev_err(dev, "failed to disable regulators for downstream device\n");
+	dev->driver_data = NULL;
+}
+
 /* Limits operation to a specific generation (1, 2, or 3) */
 static void brcm_pcie_set_gen(struct brcm_pcie *pcie, int gen)
 {
@@ -722,6 +796,8 @@ static struct pci_ops brcm_pcie_ops = {
 	.map_bus = brcm_pcie_map_conf,
 	.read = pci_generic_config_read,
 	.write = pci_generic_config_write,
+	.add_bus = pci_subdev_regulators_add_bus,
+	.remove_bus = pci_subdev_regulators_remove_bus,
 };
 
 static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val)
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:29 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:29 -0500
Subject: [PATCH v11 6/7] PCI: brcmstb: Add control of subdevice voltage
 regulators
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-7-jim2101024@gmail.com>

This Broadcom STB PCIe RC driver has one port and connects directly to one
device, be it a switch or an endpoint.  We want to be able to leverage
the recently added mechansim that allocates and turns on/off subdevice
regulators.

All that needs to be done is to put the regulator DT nodes in the bridge
below host and to set the pci_ops methods add_bus and remove_bus.

Note that the pci_subdev_regulators_add_bus() method is wrapped for two
reasons:

   1. To acheive linkup after the voltage regulators are turned on.

   2. If, in the case of an unsuccessful linkup, to redirect
      any PCIe accesses to subdevices, e.g. the scan for
      DEV/ID.  This redirection is needed because the Broadcom
      PCIe HW wil issue a CPU abort if such an access is made when
      there is no linkup.

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 82 +++++++++++++++++++++++++--
 1 file changed, 77 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 7d46eccf17ff..3c1b2fefe7e1 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -192,6 +192,8 @@ static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie,
 static inline void brcm_pcie_perst_set_4908(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val);
 static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val);
+static int brcm_pcie_linkup(struct brcm_pcie *pcie);
+static int brcm_pcie_add_bus(struct pci_bus *bus);
 
 enum {
 	RGR1_SW_INIT_1,
@@ -304,6 +306,8 @@ struct brcm_pcie {
 	u32			hw_rev;
 	void			(*perst_set)(struct brcm_pcie *pcie, u32 val);
 	void			(*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
+	bool			refusal_mode;
+	struct subdev_regulators *sr;
 };
 
 /*
@@ -467,6 +471,34 @@ static int pci_subdev_regulators_add_bus(struct pci_bus *bus)
 	return 0;
 }
 
+static int brcm_pcie_add_bus(struct pci_bus *bus)
+{
+	struct device *dev = &bus->dev;
+	struct brcm_pcie *pcie = (struct brcm_pcie *) bus->sysdata;
+	int ret;
+
+	if (!dev->of_node || !bus->parent || !pci_is_root_bus(bus->parent))
+		return 0;
+
+	ret = pci_subdev_regulators_add_bus(bus);
+	if (ret)
+		return ret;
+
+	/* Grab the regulators for suspend/resume */
+	pcie->sr = bus->dev.driver_data;
+
+	/*
+	 * If we have failed linkup there is no point to return an error as
+	 * currently it will cause a WARNING() from pci_alloc_child_bus().
+	 * We return 0 and turn on the "refusal_mode" so that any further
+	 * accesses to the pci_dev just get 0xffffffff
+	 */
+	if (brcm_pcie_linkup(pcie) != 0)
+		pcie->refusal_mode = true;
+
+	return 0;
+}
+
 static void pci_subdev_regulators_remove_bus(struct pci_bus *bus)
 {
 	struct device *dev = &bus->dev;
@@ -785,6 +817,18 @@ static void __iomem *brcm_pcie_map_conf(struct pci_bus *bus, unsigned int devfn,
 	/* Accesses to the RC go right to the RC registers if slot==0 */
 	if (pci_is_root_bus(bus))
 		return PCI_SLOT(devfn) ? NULL : base + where;
+	if (pcie->refusal_mode) {
+		/*
+		 * At this point we do not have link.  There will be a CPU
+		 * abort -- a quirk with this controller --if Linux tries
+		 * to read any config-space registers besides those
+		 * targeting the host bridge.  To prevent this we hijack
+		 * the address to point to a safe access that will return
+		 * 0xffffffff.
+		 */
+		writel(0xffffffff, base + PCIE_MISC_RC_BAR2_CONFIG_HI);
+		return base + PCIE_MISC_RC_BAR2_CONFIG_HI + (where & 0x3);
+	}
 
 	/* For devices, write to the config space index register */
 	idx = PCIE_ECAM_OFFSET(bus->number, devfn, 0);
@@ -796,7 +840,7 @@ static struct pci_ops brcm_pcie_ops = {
 	.map_bus = brcm_pcie_map_conf,
 	.read = pci_generic_config_read,
 	.write = pci_generic_config_write,
-	.add_bus = pci_subdev_regulators_add_bus,
+	.add_bus = brcm_pcie_add_bus,
 	.remove_bus = pci_subdev_regulators_remove_bus,
 };
 
@@ -1245,6 +1289,14 @@ static int brcm_pcie_suspend(struct device *dev)
 		return ret;
 	}
 
+	if (pcie->sr) {
+		ret = regulator_bulk_disable(pcie->sr->num_supplies, pcie->sr->supplies);
+		if (ret) {
+			dev_err(dev, "Could not turn off regulators\n");
+			reset_control_reset(pcie->rescal);
+			return ret;
+		}
+	}
 	clk_disable_unprepare(pcie->clk);
 
 	return 0;
@@ -1262,9 +1314,17 @@ static int brcm_pcie_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (pcie->sr) {
+		ret = regulator_bulk_enable(pcie->sr->num_supplies, pcie->sr->supplies);
+		if (ret) {
+			dev_err(dev, "Could not turn on regulators\n");
+			goto err_disable_clk;
+		}
+	}
+
 	ret = reset_control_reset(pcie->rescal);
 	if (ret)
-		goto err_disable_clk;
+		goto err_regulator;
 
 	ret = brcm_phy_start(pcie);
 	if (ret)
@@ -1296,6 +1356,8 @@ static int brcm_pcie_resume(struct device *dev)
 
 err_reset:
 	reset_control_rearm(pcie->rescal);
+err_regulator:
+	regulator_bulk_disable(pcie->sr->num_supplies, pcie->sr->supplies);
 err_disable_clk:
 	clk_disable_unprepare(pcie->clk);
 	return ret;
@@ -1425,7 +1487,17 @@ static int brcm_pcie_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, pcie);
 
-	return pci_host_probe(bridge);
+	ret = pci_host_probe(bridge);
+	if (!ret && !brcm_pcie_link_up(pcie))
+		ret = -ENODEV;
+
+	if (ret) {
+		brcm_pcie_remove(pdev);
+		return ret;
+	}
+
+	return 0;
+
 fail:
 	__brcm_pcie_remove(pcie);
 	return ret;
@@ -1434,8 +1506,8 @@ static int brcm_pcie_probe(struct platform_device *pdev)
 MODULE_DEVICE_TABLE(of, brcm_pcie_match);
 
 static const struct dev_pm_ops brcm_pcie_pm_ops = {
-	.suspend = brcm_pcie_suspend,
-	.resume = brcm_pcie_resume,
+	.suspend_noirq = brcm_pcie_suspend,
+	.resume_noirq = brcm_pcie_resume,
 };
 
 static struct platform_driver brcm_pcie_driver = {
-- 
2.17.1



From jim2101024 at gmail.com  Thu Jan  6 08:03:30 2022
From: jim2101024 at gmail.com (Jim Quinlan)
Date: Thu,  6 Jan 2022 11:03:30 -0500
Subject: [PATCH v11 7/7] PCI: brcmstb: Do not turn off WOL regulators on
 suspend
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <20220106160332.2143-8-jim2101024@gmail.com>

If any downstream device can be awoken do not turn off
the regulators as the device will need them on.

Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>
---
 drivers/pci/controller/pcie-brcmstb.c | 53 ++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 3c1b2fefe7e1..8a3321314b74 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -308,6 +308,7 @@ struct brcm_pcie {
 	void			(*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val);
 	bool			refusal_mode;
 	struct subdev_regulators *sr;
+	bool			ep_wakeup_capable;
 };
 
 /*
@@ -1269,9 +1270,21 @@ static void brcm_pcie_turn_off(struct brcm_pcie *pcie)
 	pcie->bridge_sw_init_set(pcie, 1);
 }
 
+static int pci_dev_may_wakeup(struct pci_dev *dev, void *data)
+{
+	bool *ret = data;
+
+	if (device_may_wakeup(&dev->dev)) {
+		*ret = true;
+		dev_info(&dev->dev, "disable cancelled for wake-up device\n");
+	}
+	return (int) *ret;
+}
+
 static int brcm_pcie_suspend(struct device *dev)
 {
 	struct brcm_pcie *pcie = dev_get_drvdata(dev);
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
 	int ret;
 
 	brcm_pcie_turn_off(pcie);
@@ -1290,11 +1303,22 @@ static int brcm_pcie_suspend(struct device *dev)
 	}
 
 	if (pcie->sr) {
-		ret = regulator_bulk_disable(pcie->sr->num_supplies, pcie->sr->supplies);
-		if (ret) {
-			dev_err(dev, "Could not turn off regulators\n");
-			reset_control_reset(pcie->rescal);
-			return ret;
+		/*
+		 * Now turn off the regulators, but if at least one
+		 * downstream device is enabled as a wake-up source, do not
+		 * turn off regulators.
+		 */
+		pcie->ep_wakeup_capable = false;
+		pci_walk_bus(bridge->bus, pci_dev_may_wakeup,
+			     &pcie->ep_wakeup_capable);
+		if (!pcie->ep_wakeup_capable) {
+			ret = regulator_bulk_disable(pcie->sr->num_supplies,
+						     pcie->sr->supplies);
+			if (ret) {
+				dev_err(dev, "Could not turn off regulators\n");
+				reset_control_reset(pcie->rescal);
+				return ret;
+			}
 		}
 	}
 	clk_disable_unprepare(pcie->clk);
@@ -1315,10 +1339,21 @@ static int brcm_pcie_resume(struct device *dev)
 		return ret;
 
 	if (pcie->sr) {
-		ret = regulator_bulk_enable(pcie->sr->num_supplies, pcie->sr->supplies);
-		if (ret) {
-			dev_err(dev, "Could not turn on regulators\n");
-			goto err_disable_clk;
+		if (pcie->ep_wakeup_capable) {
+			/*
+			 * We are resuming from a suspend.  In the suspend we
+			 * did not disable the power supplies, so there is
+			 * no need to enable them (and falsely increase their
+			 * usage count).
+			 */
+			pcie->ep_wakeup_capable = false;
+		} else {
+			ret = regulator_bulk_enable(pcie->sr->num_supplies,
+						    pcie->sr->supplies);
+			if (ret) {
+				dev_err(dev, "Could not turn on regulators\n");
+				goto err_disable_clk;
+			}
 		}
 	}
 
-- 
2.17.1



From mhocko at suse.com  Thu Jan  6 08:06:42 2022
From: mhocko at suse.com (Michal Hocko)
Date: Thu, 6 Jan 2022 17:06:42 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-7-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
Message-ID: <YdcTkrl84Xzg2dSz@dhcp22.suse.cz>

I am still reading through the series. It is a lot of code and quite
hard to wrap ones head around so these are mostly random things I have
run into. More will likely follow up.

On Tue 04-01-22 13:22:25, Yu Zhao wrote:
[...]
> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index aba18cd101db..028afdb81c10 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -1393,18 +1393,24 @@ mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
>  
>  static inline void lock_page_memcg(struct page *page)
>  {
> +	/* to match folio_memcg_rcu() */
> +	rcu_read_lock();
>  }
>  
>  static inline void unlock_page_memcg(struct page *page)
>  {
> +	rcu_read_unlock();
>  }
>  
>  static inline void folio_memcg_lock(struct folio *folio)
>  {
> +	/* to match folio_memcg_rcu() */
> +	rcu_read_lock();
>  }
>  
>  static inline void folio_memcg_unlock(struct folio *folio)
>  {
> +	rcu_read_unlock();
>  }

This should go into a separate patch and merge it independently. I
haven't really realized that !MEMCG configuration has a different
locking scopes.

[...]
> diff --git a/include/linux/oom.h b/include/linux/oom.h
> index 2db9a1432511..9c7a4fae0661 100644
> --- a/include/linux/oom.h
> +++ b/include/linux/oom.h
> @@ -57,6 +57,22 @@ struct oom_control {
>  extern struct mutex oom_lock;
>  extern struct mutex oom_adj_mutex;
>  
> +#ifdef CONFIG_MMU
> +extern struct task_struct *oom_reaper_list;
> +extern struct wait_queue_head oom_reaper_wait;
> +
> +static inline bool oom_reaping_in_progress(void)
> +{
> +	/* a racy check can be used to reduce the chance of overkilling */
> +	return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait);
> +}
> +#else
> +static inline bool oom_reaping_in_progress(void)
> +{
> +	return false;
> +}
> +#endif

I do not like this. These are internal oom reaper's and no code should
really make any decisions based on that. oom_reaping_in_progress is not
telling much anyway. This is a global queue for oom reaper that can
contain oom victims from different oom scopes (e.g. global OOM, memcg
OOM or memory policy OOM).

Your lru_gen_age_node uses this to decide whether to trigger
out_of_memory and that is clearly wrong for the above reasons.
out_of_memory is designed to skip over any action if there is an oom
victim pending from the oom domain (have a look at oom_evaluate_task).

[...]

> +static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc,
> +		       unsigned long min_ttl)
> +{
> +	bool need_aging;
> +	long nr_to_scan;
> +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> +	int swappiness = get_swappiness(memcg);
> +	DEFINE_MAX_SEQ(lruvec);
> +	DEFINE_MIN_SEQ(lruvec);
> +
> +	if (mem_cgroup_below_min(memcg))
> +		return false;

mem_cgroup_below_min requires effective values to be calculated for the
reclaimed hierarchy. Have a look at mem_cgroup_calculate_protection
-- 
Michal Hocko
SUSE Labs


From mark.rutland at arm.com  Thu Jan  6 08:07:07 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Jan 2022 16:07:07 +0000
Subject: [PATCH v12 01/10] arm64: Remove NULL task check from
 unwind_frame()
In-Reply-To: <20220103165212.9303-2-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-2-madvenka@linux.microsoft.com>
Message-ID: <YdcTq8sk/q1zW8va@FVFF77S0Q05N>

On Mon, Jan 03, 2022 at 10:52:03AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Currently, there is a check for a NULL task in unwind_frame(). It is not
> needed since all current consumers pass a non-NULL task.
> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> Reviewed-by: Mark Brown <broonie at kernel.org>

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/kernel/stacktrace.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 0fb58fed54cb..5f5bb35b7b41 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -69,9 +69,6 @@ static int notrace unwind_frame(struct task_struct *tsk,
>  	unsigned long fp = frame->fp;
>  	struct stack_info info;
>  
> -	if (!tsk)
> -		tsk = current;
> -
>  	/* Final frame; nothing to unwind */
>  	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
>  		return -ENOENT;
> -- 
> 2.25.1
> 


From jeremy.linton at arm.com  Thu Jan  6 08:09:35 2022
From: jeremy.linton at arm.com (Jeremy Linton)
Date: Thu, 6 Jan 2022 10:09:35 -0600
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YdbL5kIzi0xqVTVd@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com> <YdbL5kIzi0xqVTVd@arm.com>
Message-ID: <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>

Hi,

On 1/6/22 05:00, Catalin Marinas wrote:
> Hi Jeremy,
> 
> On Wed, Jan 05, 2022 at 04:42:01PM -0600, Jeremy Linton wrote:
>> On 1/4/22 11:32, Mark Brown wrote:
>>> On Thu, Dec 09, 2021 at 11:10:48AM +0000, Szabolcs Nagy wrote:
>>>> The 12/08/2021 18:23, Catalin Marinas wrote:
>>>>> On Mon, Nov 15, 2021 at 03:27:10PM +0000, Mark Brown wrote:
>>>>>> memory is already mapped with PROT_EXEC.  This series resolves this by
>>>>>> handling the BTI property for both the interpreter and the main
>>>>>> executable.
>>>>>
>>>>> Given the silence on this series over the past months, I propose we drop
>>>>> it. It's a bit unfortunate that systemd's MemoryDenyWriteExecute cannot
>>>>> work with BTI but I also think the former is a pretty blunt hardening
>>>>> mechanism (rejecting any mprotect(PROT_EXEC) regardless of the previous
>>>>> attributes).
>>>>
>>>> i still think it would be better if the kernel dealt with
>>>> PROT_BTI for the exe loaded by the kernel.
>>>
>>> The above message from Catalin isn't quite the full story here - my
>>> understanding from backchannel is that there's concern from others that
>>> we might be creating future issues by enabling PROT_BTI, especially in
>>> the case where the same permissions issue prevents the dynamic linker
>>> disabling PROT_BTI.  They'd therefore rather stick with the status quo
>>> and not create any new ABI.  Unfortunately that's not something people
>>> have been willing to say on the list, hopefully the above captures the
>>> thinking well enough.
>>>
>>> Personally I'm a bit ambivalent on this, I do see the potential issue
>>> but I'm having trouble constructing an actual scenario and my instinct
>>> is that since we handle PROT_EXEC we should also handle PROT_BTI for
>>> consistency.
>>
>> I'm hardly a security expert, but it seems to me that BTI hardens against a
>> wider set of possible exploits than MDWE.
> 
> They are complementary features.
> 
>> Yet, we are silently turning it
>> off for systemd services which are considered some of the most security
>> critical things in the machine right now (ex:logind, etc). So despite
>> 'systemd-analyze secuirty` flagging those services as the most secure ones
>> on a system, they might actually be less secure.
> 
> Well, that's a distro decision. MDWE/MDWX is not something imposed by
> the kernel but rather a seccomp bpf filter set up by systemd.
> 
>> It also seems that getting BTI turned on earlier, as this patch is doing is
>> itself a win.
>>
>> So, mentally i'm having a hard time balancing the hypothetical problem laid
>> out, as it should only really exist in an environment similar to the MDWE
>> one, since AFAIK, its possible today to just flip it back off unless MDWE
>> stops that from happening.
> 
> That's a user ABI change and given that the first attempt was shown to
> break with some combination of old loader and new main executable (or
> the other way around), I'd rather keep things as they are.

This should only change the behavior for for binaries which conform to 
the new ABI containing the BTI note. So outside of the tiny window of 
things built with BTI, but run on !BTI hardware or older kernel+glibc, 
this shouldn't be a problem. (Unless i'm missing something) Put another 
way, now is the time to make a change, before there is a legacy BTI 
ecosystem we have to deal with.


> 
>> What are the the remaining alternatives? A new syscall? But that is by
>> definition a new ABI,
> 
> A new ABI is better than changing the current ABI.
> 
>> and wouldn't benefit from having BTI turned on as early as this patch
>> is doing.
> 
> In the absence of MDWX, it's not relevant how early the kernel turns BTI
> on for the main executable. The dynamic loader would do this with an
> mprotect() before actually executing any of the main code. Of course, we
> assume there are no security bugs in the dynamic loader.
> 
>> Should we disable MDWE on a BTI machine? I'm
>> not sure that is a good look, particularly if MDWE happens to successfully
>> stop some exploit. AFAIK, MDWE+BTI are a good strong combination, it seems a
>> shame if we can't get them both working together.
> 
> AFAICT MDWX wants (one of the filters) to prevent a previously writable
> mapping from becoming executable through mprotect(PROT_EXEC). How common
> is mprotect(PROT_EXEC|PROT_BTI) outside of the dynamic loader? I doubt
> it is, especially in an MDWX environment. So can we not change the
> filter to allow PROT_EXEC|PROT_BTI? If your code is already exploitable
> to allow random syscalls, all bets are off anyway.

I would expect JITs to be twittling EXEC|BTI but, those wouldn't be able 
to trivially run under MDWE anyway. So rarely?

Changing the filter to allow PROT_EXEC|PROT_BTI defeats the purpose 
because the hypothetical exploit would just add the BTI tags and turn 
BTI on as well. The filter, as is, also provides additional BTI 
protections because it makes it more difficult to disable BTI. Without 
that filter it seems likely someone could come up with a way to use an 
existing PROT_EXEC as a gadget to disable BTI anywhere they choose.

So, to your point before, BTI+MDWE are complementary, the combination 
seems considerably more robust than either by itself.

> 
>> I hesitate to suggest it, but maybe this patch should be conditional
>> somehow, that way !systemd/MDWE machines can behave as they do today, and
>> systemd/MDWE machines can request BTI be turned on by the kernel
>> automatically?
> 
> That would be some big knob sysctl but I'm still not keen on toggling
> the ABI like this.
> 



From f.fainelli at gmail.com  Thu Jan  6 08:09:35 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 6 Jan 2022 08:09:35 -0800
Subject: [PATCH v11 3/7] dt-bindings: PCI: Add bindings for Brcmstb EP
 voltage regulators
In-Reply-To: <20220106160332.2143-4-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
 <20220106160332.2143-4-jim2101024@gmail.com>
Message-ID: <990faca8-a366-c66a-85fa-6ec9361f6b67@gmail.com>

On 1/6/22 8:03 AM, Jim Quinlan wrote:
> Add bindings for Brcmstb EP voltage regulators.  A new mechanism is to be
> added to the Linux PCI subsystem that will allocate and turn on/off
> regulators.  These are standard regulators -- vpcie12v, vpcie3v3, and
> vpcie3v3aux -- placed in the DT in the bridge node under the host bridge
> device.
> 
> The use of a regulator property in the pcie EP subnode such as
> "vpcie12v-supply" depends on a pending pullreq to the pci-bus.yaml
> file at
> 
> https://github.com/devicetree-org/dt-schema/pull/63
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Jim Quinlan <jim2101024 at gmail.com>

Acked-by: Florian Fainelli <f.fainelli at gmail.com>
-- 
Florian


From mark.rutland at arm.com  Thu Jan  6 08:10:20 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Jan 2022 16:10:20 +0000
Subject: [PATCH v12 02/10] arm64: Rename unwinder functions
In-Reply-To: <20220103165212.9303-3-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-3-madvenka@linux.microsoft.com>
Message-ID: <YdcUbJoz9LwDboGJ@FVFF77S0Q05N>

On Mon, Jan 03, 2022 at 10:52:04AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Rename unwinder functions for consistency and better naming.
> 
> 	- Rename start_backtrace() to unwind_init().
> 	- Rename unwind_frame() to unwind_next().
> 	- Rename walk_stackframe() to unwind().
> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> Reviewed-by: Mark Brown <broonie at kernel.org>
> Acked-by: Mark Rutland <mark.rutland at arm.com>

For consistency, to replace my prior Acked-by:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/kernel/stacktrace.c | 32 ++++++++++++++++----------------
>  1 file changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index 5f5bb35b7b41..b980d96dccfc 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -33,8 +33,8 @@
>   */
>  
>  
> -static void start_backtrace(struct stackframe *frame, unsigned long fp,
> -			    unsigned long pc)
> +static void unwind_init(struct stackframe *frame, unsigned long fp,
> +			unsigned long pc)
>  {
>  	frame->fp = fp;
>  	frame->pc = pc;
> @@ -45,7 +45,7 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
>  	/*
>  	 * Prime the first unwind.
>  	 *
> -	 * In unwind_frame() we'll check that the FP points to a valid stack,
> +	 * In unwind_next() we'll check that the FP points to a valid stack,
>  	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
>  	 * treated as a transition to whichever stack that happens to be. The
>  	 * prev_fp value won't be used, but we set it to 0 such that it is
> @@ -63,8 +63,8 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
>   * records (e.g. a cycle), determined based on the location and fp value of A
>   * and the location (but not the fp value) of B.
>   */
> -static int notrace unwind_frame(struct task_struct *tsk,
> -				struct stackframe *frame)
> +static int notrace unwind_next(struct task_struct *tsk,
> +			       struct stackframe *frame)
>  {
>  	unsigned long fp = frame->fp;
>  	struct stack_info info;
> @@ -104,7 +104,7 @@ static int notrace unwind_frame(struct task_struct *tsk,
>  
>  	/*
>  	 * Record this frame record's values and location. The prev_fp and
> -	 * prev_type are only meaningful to the next unwind_frame() invocation.
> +	 * prev_type are only meaningful to the next unwind_next() invocation.
>  	 */
>  	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
>  	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
> @@ -137,23 +137,23 @@ static int notrace unwind_frame(struct task_struct *tsk,
>  
>  	return 0;
>  }
> -NOKPROBE_SYMBOL(unwind_frame);
> +NOKPROBE_SYMBOL(unwind_next);
>  
> -static void notrace walk_stackframe(struct task_struct *tsk,
> -				    struct stackframe *frame,
> -				    bool (*fn)(void *, unsigned long), void *data)
> +static void notrace unwind(struct task_struct *tsk,
> +			   struct stackframe *frame,
> +			   bool (*fn)(void *, unsigned long), void *data)
>  {
>  	while (1) {
>  		int ret;
>  
>  		if (!fn(data, frame->pc))
>  			break;
> -		ret = unwind_frame(tsk, frame);
> +		ret = unwind_next(tsk, frame);
>  		if (ret < 0)
>  			break;
>  	}
>  }
> -NOKPROBE_SYMBOL(walk_stackframe);
> +NOKPROBE_SYMBOL(unwind);
>  
>  static bool dump_backtrace_entry(void *arg, unsigned long where)
>  {
> @@ -195,14 +195,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  	struct stackframe frame;
>  
>  	if (regs)
> -		start_backtrace(&frame, regs->regs[29], regs->pc);
> +		unwind_init(&frame, regs->regs[29], regs->pc);
>  	else if (task == current)
> -		start_backtrace(&frame,
> +		unwind_init(&frame,
>  				(unsigned long)__builtin_frame_address(1),
>  				(unsigned long)__builtin_return_address(0));
>  	else
> -		start_backtrace(&frame, thread_saved_fp(task),
> +		unwind_init(&frame, thread_saved_fp(task),
>  				thread_saved_pc(task));
>  
> -	walk_stackframe(task, &frame, consume_entry, cookie);
> +	unwind(task, &frame, consume_entry, cookie);
>  }
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Thu Jan  6 08:11:31 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Jan 2022 16:11:31 +0000
Subject: [PATCH v12 03/10] arm64: Rename stackframe to unwind_state
In-Reply-To: <20220103165212.9303-4-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-4-madvenka@linux.microsoft.com>
Message-ID: <YdcUsyNmALulzj3/@FVFF77S0Q05N>

On Mon, Jan 03, 2022 at 10:52:05AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Rename "struct stackframe" to "struct unwind_state" for consistency and
> better naming. Accordingly, rename variable/argument "frame" to "state".
> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>

Thanks for this!

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> ---
>  arch/arm64/include/asm/stacktrace.h |  2 +-
>  arch/arm64/kernel/stacktrace.c      | 66 ++++++++++++++---------------
>  2 files changed, 34 insertions(+), 34 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
> index 3a15d376ab36..fc828c3c5dfd 100644
> --- a/arch/arm64/include/asm/stacktrace.h
> +++ b/arch/arm64/include/asm/stacktrace.h
> @@ -52,7 +52,7 @@ struct stack_info {
>   *               associated with the most recently encountered replacement lr
>   *               value.
>   */
> -struct stackframe {
> +struct unwind_state {
>  	unsigned long fp;
>  	unsigned long pc;
>  	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index b980d96dccfc..a1a7ff93b84f 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -33,13 +33,13 @@
>   */
>  
>  
> -static void unwind_init(struct stackframe *frame, unsigned long fp,
> +static void unwind_init(struct unwind_state *state, unsigned long fp,
>  			unsigned long pc)
>  {
> -	frame->fp = fp;
> -	frame->pc = pc;
> +	state->fp = fp;
> +	state->pc = pc;
>  #ifdef CONFIG_KRETPROBES
> -	frame->kr_cur = NULL;
> +	state->kr_cur = NULL;
>  #endif
>  
>  	/*
> @@ -51,9 +51,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
>  	 * prev_fp value won't be used, but we set it to 0 such that it is
>  	 * definitely not an accessible stack address.
>  	 */
> -	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
> -	frame->prev_fp = 0;
> -	frame->prev_type = STACK_TYPE_UNKNOWN;
> +	bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
> +	state->prev_fp = 0;
> +	state->prev_type = STACK_TYPE_UNKNOWN;
>  }
>  
>  /*
> @@ -64,9 +64,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
>   * and the location (but not the fp value) of B.
>   */
>  static int notrace unwind_next(struct task_struct *tsk,
> -			       struct stackframe *frame)
> +			       struct unwind_state *state)
>  {
> -	unsigned long fp = frame->fp;
> +	unsigned long fp = state->fp;
>  	struct stack_info info;
>  
>  	/* Final frame; nothing to unwind */
> @@ -79,7 +79,7 @@ static int notrace unwind_next(struct task_struct *tsk,
>  	if (!on_accessible_stack(tsk, fp, 16, &info))
>  		return -EINVAL;
>  
> -	if (test_bit(info.type, frame->stacks_done))
> +	if (test_bit(info.type, state->stacks_done))
>  		return -EINVAL;
>  
>  	/*
> @@ -95,27 +95,27 @@ static int notrace unwind_next(struct task_struct *tsk,
>  	 * stack to another, it's never valid to unwind back to that first
>  	 * stack.
>  	 */
> -	if (info.type == frame->prev_type) {
> -		if (fp <= frame->prev_fp)
> +	if (info.type == state->prev_type) {
> +		if (fp <= state->prev_fp)
>  			return -EINVAL;
>  	} else {
> -		set_bit(frame->prev_type, frame->stacks_done);
> +		set_bit(state->prev_type, state->stacks_done);
>  	}
>  
>  	/*
>  	 * Record this frame record's values and location. The prev_fp and
>  	 * prev_type are only meaningful to the next unwind_next() invocation.
>  	 */
> -	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
> -	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
> -	frame->prev_fp = fp;
> -	frame->prev_type = info.type;
> +	state->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
> +	state->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
> +	state->prev_fp = fp;
> +	state->prev_type = info.type;
>  
> -	frame->pc = ptrauth_strip_insn_pac(frame->pc);
> +	state->pc = ptrauth_strip_insn_pac(state->pc);
>  
>  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
>  	if (tsk->ret_stack &&
> -		(frame->pc == (unsigned long)return_to_handler)) {
> +		(state->pc == (unsigned long)return_to_handler)) {
>  		unsigned long orig_pc;
>  		/*
>  		 * This is a case where function graph tracer has
> @@ -123,16 +123,16 @@ static int notrace unwind_next(struct task_struct *tsk,
>  		 * to hook a function return.
>  		 * So replace it to an original value.
>  		 */
> -		orig_pc = ftrace_graph_ret_addr(tsk, NULL, frame->pc,
> -						(void *)frame->fp);
> -		if (WARN_ON_ONCE(frame->pc == orig_pc))
> +		orig_pc = ftrace_graph_ret_addr(tsk, NULL, state->pc,
> +						(void *)state->fp);
> +		if (WARN_ON_ONCE(state->pc == orig_pc))
>  			return -EINVAL;
> -		frame->pc = orig_pc;
> +		state->pc = orig_pc;
>  	}
>  #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
>  #ifdef CONFIG_KRETPROBES
> -	if (is_kretprobe_trampoline(frame->pc))
> -		frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur);
> +	if (is_kretprobe_trampoline(state->pc))
> +		state->pc = kretprobe_find_ret_addr(tsk, (void *)state->fp, &state->kr_cur);
>  #endif
>  
>  	return 0;
> @@ -140,15 +140,15 @@ static int notrace unwind_next(struct task_struct *tsk,
>  NOKPROBE_SYMBOL(unwind_next);
>  
>  static void notrace unwind(struct task_struct *tsk,
> -			   struct stackframe *frame,
> +			   struct unwind_state *state,
>  			   bool (*fn)(void *, unsigned long), void *data)
>  {
>  	while (1) {
>  		int ret;
>  
> -		if (!fn(data, frame->pc))
> +		if (!fn(data, state->pc))
>  			break;
> -		ret = unwind_next(tsk, frame);
> +		ret = unwind_next(tsk, state);
>  		if (ret < 0)
>  			break;
>  	}
> @@ -192,17 +192,17 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  			      void *cookie, struct task_struct *task,
>  			      struct pt_regs *regs)
>  {
> -	struct stackframe frame;
> +	struct unwind_state state;
>  
>  	if (regs)
> -		unwind_init(&frame, regs->regs[29], regs->pc);
> +		unwind_init(&state, regs->regs[29], regs->pc);
>  	else if (task == current)
> -		unwind_init(&frame,
> +		unwind_init(&state,
>  				(unsigned long)__builtin_frame_address(1),
>  				(unsigned long)__builtin_return_address(0));
>  	else
> -		unwind_init(&frame, thread_saved_fp(task),
> +		unwind_init(&state, thread_saved_fp(task),
>  				thread_saved_pc(task));
>  
> -	unwind(task, &frame, consume_entry, cookie);
> +	unwind(task, &state, consume_entry, cookie);
>  }
> -- 
> 2.25.1
> 


From mhocko at suse.com  Thu Jan  6 08:12:16 2022
From: mhocko at suse.com (Michal Hocko)
Date: Thu, 6 Jan 2022 17:12:16 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-7-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
Message-ID: <YdcU4P+XWkbDUUoO@dhcp22.suse.cz>

On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> +{
> +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> +
> +	return current->reclaim_state->mm_walk;
> +}
> +
> +static void free_mm_walk(struct lru_gen_mm_walk *walk)
> +{
> +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> +		kvfree(walk);
> +}

Do I get it right that you are allocating from the reclaim context? What
prevents this to completely deplete the memory as the reclaim context is
PF_MEMALLOC?
-- 
Michal Hocko
SUSE Labs


From pali at kernel.org  Thu Jan  6 08:20:47 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 6 Jan 2022 17:20:47 +0100
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <878rvsvoyo.wl-maz@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
Message-ID: <20220106162047.vqykmygs75eimfgy@pali>

On Thursday 06 January 2022 15:55:11 Marc Zyngier wrote:
> On Thu, 06 Jan 2022 15:44:47 +0000,
> Pali Roh?r <pali at kernel.org> wrote:
> > 
> > On Thursday 06 January 2022 15:28:20 Marc Zyngier wrote:
> > > On Wed, 05 Jan 2022 15:02:38 +0000,
> > > Pali Roh?r <pali at kernel.org> wrote:
> > > > 
> > > > This adds support for legacy INTx interrupts received from other PCIe
> > > > devices and which are reported by a new INTx irq chip.
> > > > 
> > > > With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> > > > interrupts.
> > > > 
> > > > Note that for this support, device tree files has to be properly adjusted
> > > > to provide "interrupts" or "interrupts-extended" property with intx
> > > > interrupt source, "interrupt-names" property with "intx" string and also
> > > > 'interrupt-controller' subnode must be defined.
> > > > 
> > > > If device tree files do not provide these nodes then driver would work as
> > > > before.
> > > > 
> > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > ---
> > > >  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
> > > >  1 file changed, 174 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > index 1e90ab888075..04bcdd7b7a6d 100644
> > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > @@ -54,9 +54,10 @@
> > > >  	 PCIE_CONF_ADDR_EN)
> > > >  #define PCIE_CONF_DATA_OFF	0x18fc
> > > >  #define PCIE_INT_CAUSE_OFF	0x1900
> > > > +#define PCIE_INT_UNMASK_OFF	0x1910
> > > > +#define  PCIE_INT_INTX(i)		BIT(24+i)
> > > >  #define  PCIE_INT_PM_PME		BIT(28)
> > > > -#define PCIE_MASK_OFF		0x1910
> > > > -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> > > > +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
> > > >  #define PCIE_CTRL_OFF		0x1a00
> > > >  #define  PCIE_CTRL_X1_MODE		0x0001
> > > >  #define  PCIE_CTRL_RC_MODE		BIT(1)
> > > > @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
> > > >  	struct mvebu_pcie_window iowin;
> > > >  	u32 saved_pcie_stat;
> > > >  	struct resource regs;
> > > > +	struct irq_domain *intx_irq_domain;
> > > > +	struct irq_chip intx_irq_chip;
> > > 
> > > Why is this structure per port? It really should be global. Printing
> > > the port number in the name isn't enough of a reason.
> > 
> > Because each port has its own independent set of INTA-INTD
> > interrupts.
> 
> That doesn't warrant a copy of an irq_chip structure that contains the
> exact same callbacks, and only differs by *a string*. And the use of
> this string is only to end-up in /proc/interrupts, which is totally
> pointless.
> 
> > 
> > > > +	raw_spinlock_t irq_lock;
> > > > +	int intx_irq;
> > > >  };
> > > >  
> > > >  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> > > > @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > >  
> > > >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > >  {
> > > > -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> > > > +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> > > >  
> > > >  	/* Setup PCIe controller to Root Complex mode. */
> > > >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> > > > @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > >  	/* Point PCIe unit MBUS decode windows to DRAM space. */
> > > >  	mvebu_pcie_setup_wins(port);
> > > >  
> > > > -	/* Enable interrupt lines A-D. */
> > > > -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> > > > -	mask |= PCIE_MASK_ENABLE_INTS;
> > > > -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> > > > +	/* Mask all interrupt sources. */
> > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > > > +
> > > > +	/* Clear all interrupt causes. */
> > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > > > +
> > > > +	if (port->intx_irq <= 0) {
> > > > +		/*
> > > > +		 * When neither "summary" interrupt, nor "intx" interrupt was
> > > > +		 * specified in DT then unmask all legacy INTx interrupts as in
> > > > +		 * this case driver does not provide a way for masking and
> > > > +		 * unmasking of individual legacy INTx interrupts. In this case
> > > > +		 * all interrupts, including legacy INTx are reported via one
> > > > +		 * shared GIC source and therefore kernel cannot distinguish
> > > > +		 * which individual legacy INTx was triggered. These interrupts
> > > > +		 * are shared, so it should not cause any issue. Just
> > > > +		 * performance penalty as every PCIe interrupt handler needs to
> > > > +		 * be called when some interrupt is triggered.
> > > > +		 */
> > > > +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> > > > +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> > > > +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > 
> > > Maybe worth printing a warning here, so that the user knows they are
> > > on thin ice.
> > 
> > Ok. I can add it here. Anyway, this is default current state without
> > this patch.
> > 
> > > > +	}
> > > >  }
> > > >  
> > > >  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > > > @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
> > > >  	.write = mvebu_pcie_wr_conf,
> > > >  };
> > > >  
> > > > +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> > > > +{
> > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > +	unsigned long flags;
> > > > +	u32 unmask;
> > > > +
> > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > +	unmask &= ~PCIE_INT_INTX(hwirq);
> > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > +}
> > > > +
> > > > +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> > > > +{
> > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > +	unsigned long flags;
> > > > +	u32 unmask;
> > > > +
> > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > +	unmask |= PCIE_INT_INTX(hwirq);
> > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > +}
> > > > +
> > > > +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> > > > +				   unsigned int virq, irq_hw_number_t hwirq)
> > > > +{
> > > > +	struct mvebu_pcie_port *port = h->host_data;
> > > > +
> > > > +	irq_set_status_flags(virq, IRQ_LEVEL);
> > > > +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> > > > +	irq_set_chip_data(virq, port);
> > > > +
> > > > +	return 0;
> > > > +}
> > > > +
> > > > +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> > > > +	.map = mvebu_pcie_intx_irq_map,
> > > > +	.xlate = irq_domain_xlate_onecell,
> > > > +};
> > > > +
> > > > +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> > > > +{
> > > > +	struct device *dev = &port->pcie->pdev->dev;
> > > > +	struct device_node *pcie_intc_node;
> > > > +
> > > > +	raw_spin_lock_init(&port->irq_lock);
> > > > +
> > > > +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> > > > +						  "mvebu-%s-INTx",
> > > > +						  port->name);
> > > 
> > > That's exactly what I really don't want to see. It prevents sharing of
> > > the irq_chip structure, and gets in the way of making it const in the
> > > future. Yes, I know that some drivers do that. I can't fix those,
> > > because /proc/interrupts is ABI. But I really don't want to see more
> > > of these.
> > 
> > Well, I do not understand why it should be shared and with who. HW has N
> > independent IRQ chips for legacy interrupts. And each one will be
> > specified in DT per HW layout / design.
> 
> If you have multiple ports, all the ports can share the irq_chip
> structure. Actually scratch that. They *MUST* share the structure. The
> only reason you're not sharing it is to be able to print this useless
> string in /proc/interrupts.

What is the point of sharing one irq chip if HW has N independent irq
chips (for legacy interrupts)? I do not catch it yet. And I do not care
here for /proc/interrupts, so also I have not caught what do you mean be
last sentence with "the only reason".

And I still do not see how it could even work to have just one irq chip
and one irq domain as each irq domain needs to know to which port it
belongs, so it can mask/unmask interrupts from correct port. Also
initialization of domain is taking DT node and for each port it is
different.

So I'm somehow confused here...

The improvement in this patch is to be able to mask INTA interrupts on
port 1 and let INTA interrupts unmasked on port 2 if there drivers are
interested only for interrupts from device connected to port 2.

And if all interrupts are going to be shared (again) then it does not
solve any problem.


From maz at kernel.org  Thu Jan  6 08:27:44 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 16:27:44 +0000
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220106162047.vqykmygs75eimfgy@pali>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
 <20220106162047.vqykmygs75eimfgy@pali>
Message-ID: <877dbcvngf.wl-maz@kernel.org>

On Thu, 06 Jan 2022 16:20:47 +0000,
Pali Roh?r <pali at kernel.org> wrote:
> 
> On Thursday 06 January 2022 15:55:11 Marc Zyngier wrote:
> > On Thu, 06 Jan 2022 15:44:47 +0000,
> > Pali Roh?r <pali at kernel.org> wrote:
> > > 
> > > On Thursday 06 January 2022 15:28:20 Marc Zyngier wrote:
> > > > On Wed, 05 Jan 2022 15:02:38 +0000,
> > > > Pali Roh?r <pali at kernel.org> wrote:
> > > > > 
> > > > > This adds support for legacy INTx interrupts received from other PCIe
> > > > > devices and which are reported by a new INTx irq chip.
> > > > > 
> > > > > With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> > > > > interrupts.
> > > > > 
> > > > > Note that for this support, device tree files has to be properly adjusted
> > > > > to provide "interrupts" or "interrupts-extended" property with intx
> > > > > interrupt source, "interrupt-names" property with "intx" string and also
> > > > > 'interrupt-controller' subnode must be defined.
> > > > > 
> > > > > If device tree files do not provide these nodes then driver would work as
> > > > > before.
> > > > > 
> > > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > > ---
> > > > >  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
> > > > >  1 file changed, 174 insertions(+), 8 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > > index 1e90ab888075..04bcdd7b7a6d 100644
> > > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > > @@ -54,9 +54,10 @@
> > > > >  	 PCIE_CONF_ADDR_EN)
> > > > >  #define PCIE_CONF_DATA_OFF	0x18fc
> > > > >  #define PCIE_INT_CAUSE_OFF	0x1900
> > > > > +#define PCIE_INT_UNMASK_OFF	0x1910
> > > > > +#define  PCIE_INT_INTX(i)		BIT(24+i)
> > > > >  #define  PCIE_INT_PM_PME		BIT(28)
> > > > > -#define PCIE_MASK_OFF		0x1910
> > > > > -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> > > > > +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
> > > > >  #define PCIE_CTRL_OFF		0x1a00
> > > > >  #define  PCIE_CTRL_X1_MODE		0x0001
> > > > >  #define  PCIE_CTRL_RC_MODE		BIT(1)
> > > > > @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
> > > > >  	struct mvebu_pcie_window iowin;
> > > > >  	u32 saved_pcie_stat;
> > > > >  	struct resource regs;
> > > > > +	struct irq_domain *intx_irq_domain;
> > > > > +	struct irq_chip intx_irq_chip;
> > > > 
> > > > Why is this structure per port? It really should be global. Printing
> > > > the port number in the name isn't enough of a reason.
> > > 
> > > Because each port has its own independent set of INTA-INTD
> > > interrupts.
> > 
> > That doesn't warrant a copy of an irq_chip structure that contains the
> > exact same callbacks, and only differs by *a string*. And the use of
> > this string is only to end-up in /proc/interrupts, which is totally
> > pointless.
> > 
> > > 
> > > > > +	raw_spinlock_t irq_lock;
> > > > > +	int intx_irq;
> > > > >  };
> > > > >  
> > > > >  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> > > > > @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > > >  
> > > > >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > > >  {
> > > > > -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> > > > > +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> > > > >  
> > > > >  	/* Setup PCIe controller to Root Complex mode. */
> > > > >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> > > > > @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > > >  	/* Point PCIe unit MBUS decode windows to DRAM space. */
> > > > >  	mvebu_pcie_setup_wins(port);
> > > > >  
> > > > > -	/* Enable interrupt lines A-D. */
> > > > > -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> > > > > -	mask |= PCIE_MASK_ENABLE_INTS;
> > > > > -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> > > > > +	/* Mask all interrupt sources. */
> > > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > > > > +
> > > > > +	/* Clear all interrupt causes. */
> > > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > > > > +
> > > > > +	if (port->intx_irq <= 0) {
> > > > > +		/*
> > > > > +		 * When neither "summary" interrupt, nor "intx" interrupt was
> > > > > +		 * specified in DT then unmask all legacy INTx interrupts as in
> > > > > +		 * this case driver does not provide a way for masking and
> > > > > +		 * unmasking of individual legacy INTx interrupts. In this case
> > > > > +		 * all interrupts, including legacy INTx are reported via one
> > > > > +		 * shared GIC source and therefore kernel cannot distinguish
> > > > > +		 * which individual legacy INTx was triggered. These interrupts
> > > > > +		 * are shared, so it should not cause any issue. Just
> > > > > +		 * performance penalty as every PCIe interrupt handler needs to
> > > > > +		 * be called when some interrupt is triggered.
> > > > > +		 */
> > > > > +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> > > > > +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> > > > > +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > 
> > > > Maybe worth printing a warning here, so that the user knows they are
> > > > on thin ice.
> > > 
> > > Ok. I can add it here. Anyway, this is default current state without
> > > this patch.
> > > 
> > > > > +	}
> > > > >  }
> > > > >  
> > > > >  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > > > > @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
> > > > >  	.write = mvebu_pcie_wr_conf,
> > > > >  };
> > > > >  
> > > > > +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> > > > > +{
> > > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > > +	unsigned long flags;
> > > > > +	u32 unmask;
> > > > > +
> > > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > +	unmask &= ~PCIE_INT_INTX(hwirq);
> > > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > > +}
> > > > > +
> > > > > +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> > > > > +{
> > > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > > +	unsigned long flags;
> > > > > +	u32 unmask;
> > > > > +
> > > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > +	unmask |= PCIE_INT_INTX(hwirq);
> > > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > > +}
> > > > > +
> > > > > +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> > > > > +				   unsigned int virq, irq_hw_number_t hwirq)
> > > > > +{
> > > > > +	struct mvebu_pcie_port *port = h->host_data;
> > > > > +
> > > > > +	irq_set_status_flags(virq, IRQ_LEVEL);
> > > > > +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> > > > > +	irq_set_chip_data(virq, port);
> > > > > +
> > > > > +	return 0;
> > > > > +}
> > > > > +
> > > > > +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> > > > > +	.map = mvebu_pcie_intx_irq_map,
> > > > > +	.xlate = irq_domain_xlate_onecell,
> > > > > +};
> > > > > +
> > > > > +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> > > > > +{
> > > > > +	struct device *dev = &port->pcie->pdev->dev;
> > > > > +	struct device_node *pcie_intc_node;
> > > > > +
> > > > > +	raw_spin_lock_init(&port->irq_lock);
> > > > > +
> > > > > +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> > > > > +						  "mvebu-%s-INTx",
> > > > > +						  port->name);
> > > > 
> > > > That's exactly what I really don't want to see. It prevents sharing of
> > > > the irq_chip structure, and gets in the way of making it const in the
> > > > future. Yes, I know that some drivers do that. I can't fix those,
> > > > because /proc/interrupts is ABI. But I really don't want to see more
> > > > of these.
> > > 
> > > Well, I do not understand why it should be shared and with who. HW has N
> > > independent IRQ chips for legacy interrupts. And each one will be
> > > specified in DT per HW layout / design.
> > 
> > If you have multiple ports, all the ports can share the irq_chip
> > structure. Actually scratch that. They *MUST* share the structure. The
> > only reason you're not sharing it is to be able to print this useless
> > string in /proc/interrupts.
> 
> What is the point of sharing one irq chip if HW has N independent irq
> chips (for legacy interrupts)? I do not catch it yet. And I do not care
> here for /proc/interrupts, so also I have not caught what do you mean be
> last sentence with "the only reason".
> 
> And I still do not see how it could even work to have just one irq chip
> and one irq domain as each irq domain needs to know to which port it
> belongs, so it can mask/unmask interrupts from correct port. Also
> initialization of domain is taking DT node and for each port it is
> different.
> 
> So I'm somehow confused here...
> 
> The improvement in this patch is to be able to mask INTA interrupts on
> port 1 and let INTA interrupts unmasked on port 2 if there drivers are
> interested only for interrupts from device connected to port 2.
> 
> And if all interrupts are going to be shared (again) then it does not
> solve any problem.

You are completely missing my point. I'm talking about data
structures, you're talking about interrupts. You have this:

struct mvebu_pcie_port {
       // Tons of stuff
       struct irq_chip intx_chip;
};

What I want you to do is:

struct mvebu_pcie_port {
       // Tons of stuff
};

static struct irq_chip intx_chip = {
	.name		= "INTx",
	.irq_mask	= mvebu_pcie_intx_irq_mask,
	.irq_unmask	= mvebu_pcie_intx_irq_unmask;
};

That's it. No more, no less.

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Thu Jan  6 08:31:28 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Jan 2022 16:31:28 +0000
Subject: [PATCH v12 04/10] arm64: Split unwind_init()
In-Reply-To: <20220103165212.9303-5-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-5-madvenka@linux.microsoft.com>
Message-ID: <YdcZYGI42h7zybqo@FVFF77S0Q05N>

On Mon, Jan 03, 2022 at 10:52:06AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> unwind_init() is currently a single function that initializes all of the
> unwind state. Split it into the following functions and call them
> appropriately:
> 
> 	- unwind_init_regs() - initialize from regs passed by caller.
> 
> 	- unwind_init_current() - initialize for the current task from the
> 	  caller of arch_stack_walk().
> 
> 	- unwind_init_from_task() - initialize from the saved state of a
> 	  task other than the current task. In this case, the other
> 	  task must not be running.
> 
> 	- unwind_init_common() - initialize fields that are common across
> 	  the above 3 cases.
> 
> This is done so that specialized initialization can be added to each case
> in the future.
> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> ---
>  arch/arm64/kernel/stacktrace.c | 50 +++++++++++++++++++++++++++-------
>  1 file changed, 40 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index a1a7ff93b84f..bd797e3f7789 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -33,11 +33,8 @@
>   */
>  
>  
> -static void unwind_init(struct unwind_state *state, unsigned long fp,
> -			unsigned long pc)
> +static void unwind_init_common(struct unwind_state *state)
>  {
> -	state->fp = fp;
> -	state->pc = pc;
>  #ifdef CONFIG_KRETPROBES
>  	state->kr_cur = NULL;
>  #endif
> @@ -56,6 +53,40 @@ static void unwind_init(struct unwind_state *state, unsigned long fp,
>  	state->prev_type = STACK_TYPE_UNKNOWN;
>  }
>  
> +/*
> + * TODO: document requirements here.
> + */
> +static inline void unwind_init_regs(struct unwind_state *state,
> +				    struct pt_regs *regs)
> +{
> +	state->fp = regs->regs[29];
> +	state->pc = regs->pc;
> +}

When I suggested this back in:

  https://lore.kernel.org/linux-arm-kernel/20211123193723.12112-1-madvenka at linux.microsoft.com/T/#md91fbfe08ceab2a02d9f5c326e17997786e53208

... my intent was that each unwind_init_from_*() helpers was the sole
initializer of the structure, and the caller only had to call one function.
That way it's not possible to construct an object with an erroneous combination
of arguments because the prototype enforces the set of arguments, and the
helper function can operate on a consistent snapshot of those arguments.

So I'd much prefer that each of these helpers called unwind_init_common(),
rather than leaving that to the caller to do. I don't mind if those pass
arguments to unwind_init_common(), or explciitly initialize their respective
fields, but I don' think the caller should have to care about unwind_init_common().

I'd also prefer the unwind_init_from*() naming I'd previously suggested, so
that it's clear which direction information is flowing.

>
> +
> +/*
> + * TODO: document requirements here.
> + *
> + * Note: this is always inlined, and we expect our caller to be a noinline
> + * function, such that this starts from our caller's caller.
> + */
> +static __always_inline void unwind_init_current(struct unwind_state *state)
> +{
> +	state->fp = (unsigned long)__builtin_frame_address(1);
> +	state->pc = (unsigned long)__builtin_return_address(0);
> +}
> +
> +/*
> + * TODO: document requirements here.
> + *
> + * The caller guarantees that the task is not running.
> + */
> +static inline void unwind_init_task(struct unwind_state *state,
> +				    struct task_struct *task)
> +{
> +	state->fp = thread_saved_fp(task);
> +	state->pc = thread_saved_pc(task);
> +}
> +
>  /*
>   * Unwind from one frame record (A) to the next frame record (B).
>   *
> @@ -194,15 +225,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  {
>  	struct unwind_state state;
>  
> +	unwind_init_common(&state);

As above, I really don't like that the caller has to call both the common
initializer and a specialized initializer here.

Thanks,
Mark.

> +
>  	if (regs)
> -		unwind_init(&state, regs->regs[29], regs->pc);
> +		unwind_init_regs(&state, regs);
>  	else if (task == current)
> -		unwind_init(&state,
> -				(unsigned long)__builtin_frame_address(1),
> -				(unsigned long)__builtin_return_address(0));
> +		unwind_init_current(&state);
>  	else
> -		unwind_init(&state, thread_saved_fp(task),
> -				thread_saved_pc(task));
> +		unwind_init_task(&state, task);
>  
>  	unwind(task, &state, consume_entry, cookie);
>  }
> -- 
> 2.25.1
> 


From andrew.kilroy at arm.com  Thu Jan  6 08:33:20 2022
From: andrew.kilroy at arm.com (Andrew Kilroy)
Date: Thu, 6 Jan 2022 16:33:20 +0000
Subject: [RFC PATCH 1/1] perf arm64: Implement --topdown with metrics
In-Reply-To: <0a14914c-063d-f9ae-be49-ae9cc6aa7ff1@huawei.com>
References: <4c375d34-bf20-496d-22fc-aed8597126e2@huawei.com>
 <20211214184240.24215-1-andrew.kilroy@arm.com>
 <20211214184240.24215-2-andrew.kilroy@arm.com>
 <CAP-5=fXJeH0ZvcHPa20N5KfLwnYSw29rpK3OrnvE0o3u-vGTLA@mail.gmail.com>
 <b1640897-10d7-c11e-4a7a-d17633916c8e@huawei.com>
 <d91a1b98-2c2b-a961-543f-d540b3c7a146@arm.com>
 <0a14914c-063d-f9ae-be49-ae9cc6aa7ff1@huawei.com>
Message-ID: <3e8c7fb6-97aa-f84e-e594-b6eb2cb674e4@arm.com>



On 15/12/2021 12:53, John Garry wrote:
>>> In addition we could also add a --topdown arg to force using JSON 
>>> metricgroups.
>>>
>>
>> What arg do think would be supplied?
> 
> something like -json or -metricgroup, meaning "Use pmu-events metric 
> events to calculate topdown results rather than kernel CPU PMU events. 
> This is default fallback if the kernel CPU PMU does not support topdown 
> events"
> 

John,

Andi requested that the json metrics be disabled on x86 in

 
https://lore.kernel.org/linux-perf-users/12e0deef-08db-445f-4958-bcd5c3e10367 at linux.intel.com/#t

If we do that, do you still think the --topdown=<arg>  modification is 
needed?  I guess it would have to report an error if someone requests 
--topdown=json-metrics on x86.

Thanks,
Andrew



From mark.rutland at arm.com  Thu Jan  6 08:37:27 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 6 Jan 2022 16:37:27 +0000
Subject: [PATCH v12 05/10] arm64: Copy unwind arguments to unwind_state
In-Reply-To: <20220103165212.9303-6-madvenka@linux.microsoft.com>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-6-madvenka@linux.microsoft.com>
Message-ID: <Ydcax2E9u4D4/3Q9@FVFF77S0Q05N>

On Mon, Jan 03, 2022 at 10:52:07AM -0600, madvenka at linux.microsoft.com wrote:
> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
> 
> Copy the following arguments passed to arch_stack_walk() to unwind_state
> so that they can be passed to unwind functions via unwind_state rather
> than as separate arguments:
> 
> 	- task

I agree the task should be placed in the unwind state, since it's a key part of
the environment for the unwind.

> 	- regs

This isn't relevant in all cases, and so for now I'd strongly prefer *not* to
have this in the unwind state as it's liable to lead to confusion and get
misused.

> 	- consume_entry
> 	- cookie

These are only relevant for the invocation of the consume_entry() function, and
so similarly I do not think they should be part of the state. It's simpler for
these to be local variables.

> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> ---
>  arch/arm64/include/asm/stacktrace.h | 12 ++++++++
>  arch/arm64/kernel/stacktrace.c      | 45 ++++++++++++++++-------------
>  2 files changed, 37 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
> index fc828c3c5dfd..322817d40a75 100644
> --- a/arch/arm64/include/asm/stacktrace.h
> +++ b/arch/arm64/include/asm/stacktrace.h
> @@ -51,6 +51,14 @@ struct stack_info {
>   * @kr_cur:      When KRETPOLINES is selected, holds the kretprobe instance
>   *               associated with the most recently encountered replacement lr
>   *               value.
> + *
> + * @task:        Pointer to the task structure.
> + *
> + * @regs:        Registers, if any.
> + *
> + * @consume_pc   Consume PC function pointer.
> + *
> + * @cookie       Argument to consume_pc().
>   */
>  struct unwind_state {
>  	unsigned long fp;
> @@ -61,6 +69,10 @@ struct unwind_state {
>  #ifdef CONFIG_KRETPROBES
>  	struct llist_node *kr_cur;
>  #endif
> +	struct task_struct *task;
> +	struct pt_regs *regs;
> +	stack_trace_consume_fn consume_pc;
> +	void *cookie;
>  };
>  
>  extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
> index bd797e3f7789..3ecb8242caa5 100644
> --- a/arch/arm64/kernel/stacktrace.c
> +++ b/arch/arm64/kernel/stacktrace.c
> @@ -33,8 +33,17 @@
>   */
>  
>  
> -static void unwind_init_common(struct unwind_state *state)
> +static void unwind_init_common(struct unwind_state *state,
> +			       struct task_struct *task,
> +			       struct pt_regs *regs,
> +			       stack_trace_consume_fn consume_pc,
> +			       void *cookie)
>  {
> +	state->task = task;
> +	state->regs = regs;
> +	state->consume_pc = consume_pc;
> +	state->cookie = cookie;
> +
>  #ifdef CONFIG_KRETPROBES
>  	state->kr_cur = NULL;
>  #endif
> @@ -56,11 +65,10 @@ static void unwind_init_common(struct unwind_state *state)
>  /*
>   * TODO: document requirements here.
>   */
> -static inline void unwind_init_regs(struct unwind_state *state,
> -				    struct pt_regs *regs)
> +static inline void unwind_init_regs(struct unwind_state *state)
>  {
> -	state->fp = regs->regs[29];
> -	state->pc = regs->pc;
> +	state->fp = state->regs->regs[29];
> +	state->pc = state->regs->pc;
>  }
>  
>  /*
> @@ -80,11 +88,10 @@ static __always_inline void unwind_init_current(struct unwind_state *state)
>   *
>   * The caller guarantees that the task is not running.
>   */
> -static inline void unwind_init_task(struct unwind_state *state,
> -				    struct task_struct *task)
> +static inline void unwind_init_task(struct unwind_state *state)
>  {
> -	state->fp = thread_saved_fp(task);
> -	state->pc = thread_saved_pc(task);
> +	state->fp = thread_saved_fp(state->task);
> +	state->pc = thread_saved_pc(state->task);
>  }
>  
>  /*
> @@ -94,9 +101,9 @@ static inline void unwind_init_task(struct unwind_state *state,
>   * records (e.g. a cycle), determined based on the location and fp value of A
>   * and the location (but not the fp value) of B.
>   */
> -static int notrace unwind_next(struct task_struct *tsk,
> -			       struct unwind_state *state)
> +static int notrace unwind_next(struct unwind_state *state)
>  {
> +	struct task_struct *tsk = state->task;
>  	unsigned long fp = state->fp;
>  	struct stack_info info;
>  
> @@ -170,16 +177,14 @@ static int notrace unwind_next(struct task_struct *tsk,
>  }
>  NOKPROBE_SYMBOL(unwind_next);
>  
> -static void notrace unwind(struct task_struct *tsk,
> -			   struct unwind_state *state,
> -			   bool (*fn)(void *, unsigned long), void *data)
> +static void notrace unwind(struct unwind_state *state)
>  {
>  	while (1) {
>  		int ret;
>  
> -		if (!fn(data, state->pc))
> +		if (!state->consume_pc(state->cookie, state->pc))
>  			break;
> -		ret = unwind_next(tsk, state);
> +		ret = unwind_next(state);
>  		if (ret < 0)
>  			break;
>  	}
> @@ -225,14 +230,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>  {
>  	struct unwind_state state;
>  
> -	unwind_init_common(&state);
> +	unwind_init_common(&state, task, regs, consume_entry, cookie);
>  
>  	if (regs)
> -		unwind_init_regs(&state, regs);
> +		unwind_init_regs(&state);
>  	else if (task == current)
>  		unwind_init_current(&state);
>  	else
> -		unwind_init_task(&state, task);
> +		unwind_init_task(&state);
>  
> -	unwind(task, &state, consume_entry, cookie);
> +	unwind(&state);

I don't like the changes here in particular since they hide the information
flow relevant to each case.

Thanks,
Mark.

>  }
> -- 
> 2.25.1
> 


From abel.vesa at nxp.com  Thu Jan  6 08:41:48 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu,  6 Jan 2022 18:41:48 +0200
Subject: [PATCH v4 1/3] dt-bindings: interconnect: imx8m-noc: Add fsl,
 icc-id property
Message-ID: <20220106164150.3474048-1-abel.vesa@nxp.com>

Add documentation for fsl,icc-id property.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v3:
 * fixed typo in property description

 .../devicetree/bindings/interconnect/fsl,imx8m-noc.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
index b8204ed22dd5..dc7f6b6f508a 100644
--- a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
+++ b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
@@ -47,6 +47,11 @@ properties:
   operating-points-v2: true
   opp-table: true
 
+  fsl,icc-id:
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    description:
+      unique ID used for linking i.MX bus or ddrc node to interconnect
+
   fsl,ddrc:
     $ref: "/schemas/types.yaml#/definitions/phandle"
     description:
-- 
2.31.1



From abel.vesa at nxp.com  Thu Jan  6 08:41:49 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu,  6 Jan 2022 18:41:49 +0200
Subject: [PATCH v4 2/3] interconnect: imx: Switch from imx_icc_node_adj_desc
 to fsl, icc-id node assignment
In-Reply-To: <20220106164150.3474048-1-abel.vesa@nxp.com>
References: <20220106164150.3474048-1-abel.vesa@nxp.com>
Message-ID: <20220106164150.3474048-2-abel.vesa@nxp.com>

In order to be able to have more than one NoCs in the interconnect net
we need to decouple the NoC from the dram. So instead of using the
imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
each NoC (or pl301) to the icc node (based on the id) to it.
Along with all the NoC and pl301 nodes in the dts we will have a
interconnect dedicated node. This node will be the actual device of the
icc provider.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v3:
 * none

 drivers/interconnect/imx/imx.c | 70 +++++++++++++++-------------------
 1 file changed, 31 insertions(+), 39 deletions(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index c770951a909c..d5b36c478911 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -34,8 +34,8 @@ static int imx_icc_node_set(struct icc_node *node)
 	if (!node_data->qos_dev)
 		return 0;
 
-	freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
-	do_div(freq, node_data->desc->adj->bw_div);
+	freq = node->peak_bw;
+
 	dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq %llukHz\n",
 		node->name, dev_name(node_data->qos_dev),
 		node->avg_bw, node->peak_bw, freq);
@@ -79,41 +79,35 @@ static int imx_icc_node_init_qos(struct icc_provider *provider,
 				 struct icc_node *node)
 {
 	struct imx_icc_node *node_data = node->data;
-	const struct imx_icc_node_adj_desc *adj = node_data->desc->adj;
 	struct device *dev = provider->dev;
-	struct device_node *dn = NULL;
 	struct platform_device *pdev;
+	struct device_node *np = NULL, *dn = NULL;
+	int idx;
 
-	if (adj->main_noc) {
-		node_data->qos_dev = dev;
-		dev_dbg(dev, "icc node %s[%d] is main noc itself\n",
-			node->name, node->id);
-	} else {
-		dn = of_parse_phandle(dev->of_node, adj->phandle_name, 0);
-		if (!dn) {
-			dev_warn(dev, "Failed to parse %s\n",
-				 adj->phandle_name);
-			return -ENODEV;
-		}
-		/* Allow scaling to be disabled on a per-node basis */
-		if (!of_device_is_available(dn)) {
-			dev_warn(dev, "Missing property %s, skip scaling %s\n",
-				 adj->phandle_name, node->name);
-			of_node_put(dn);
-			return 0;
-		}
+	for_each_node_with_property(np, "fsl,icc-id") {
+		of_property_read_u32(np, "fsl,icc-id", &idx);
+		if (idx == node_data->desc->id)
+			dn = np;
+	}
 
-		pdev = of_find_device_by_node(dn);
-		of_node_put(dn);
-		if (!pdev) {
-			dev_warn(dev, "node %s[%d] missing device for %pOF\n",
-				 node->name, node->id, dn);
-			return -EPROBE_DEFER;
-		}
-		node_data->qos_dev = &pdev->dev;
-		dev_dbg(dev, "node %s[%d] has device node %pOF\n",
-			node->name, node->id, dn);
+	if (!dn)
+		return 0;
+
+	if (!of_device_is_available(dn)) {
+		dev_warn(dev, "%pOF is disabled\n", dn);
+		return 0;
+	}
+
+	pdev = of_find_device_by_node(dn);
+	of_node_put(dn);
+	if (!pdev) {
+		dev_warn(dev, "node %s[%d] missing device for %pOF\n",
+			 node->name, node->id, dn);
+		return -EPROBE_DEFER;
 	}
+	node_data->qos_dev = &pdev->dev;
+	dev_dbg(dev, "node %s[%d] has device node %pOF\n", node->name,
+							node->id, dn);
 
 	return dev_pm_qos_add_request(node_data->qos_dev,
 				      &node_data->qos_req,
@@ -151,12 +145,10 @@ static struct icc_node *imx_icc_node_add(struct icc_provider *provider,
 	node_data->desc = node_desc;
 	icc_node_add(node, provider);
 
-	if (node_desc->adj) {
-		ret = imx_icc_node_init_qos(provider, node);
-		if (ret < 0) {
-			imx_icc_node_destroy(node);
-			return ERR_PTR(ret);
-		}
+	ret = imx_icc_node_init_qos(provider, node);
+	if (ret < 0) {
+		imx_icc_node_destroy(node);
+		return ERR_PTR(ret);
 	}
 
 	return node;
@@ -244,7 +236,7 @@ int imx_icc_register(struct platform_device *pdev,
 	provider->aggregate = icc_std_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
-	provider->dev = dev->parent;
+	provider->dev = dev;
 	platform_set_drvdata(pdev, provider);
 
 	ret = icc_provider_add(provider);
-- 
2.31.1



From abel.vesa at nxp.com  Thu Jan  6 08:41:50 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu,  6 Jan 2022 18:41:50 +0200
Subject: [PATCH v4 3/3] interconnect: imx: Remove the imx_icc_node_adj_desc
In-Reply-To: <20220106164150.3474048-1-abel.vesa@nxp.com>
References: <20220106164150.3474048-1-abel.vesa@nxp.com>
Message-ID: <20220106164150.3474048-3-abel.vesa@nxp.com>

Now that the imx generic interconnect doesn't use the
imx_icc_node_adj_desc, we remove it from all the i.MX8M
platform drivers.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v3:
 * none

 drivers/interconnect/imx/imx.h    | 19 ++++-------------
 drivers/interconnect/imx/imx8mm.c | 32 +++++++++-------------------
 drivers/interconnect/imx/imx8mn.c | 28 +++++++------------------
 drivers/interconnect/imx/imx8mq.c | 35 ++++++++++---------------------
 4 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
index 75da51076c68..5c9f5138f6aa 100644
--- a/drivers/interconnect/imx/imx.h
+++ b/drivers/interconnect/imx/imx.h
@@ -14,15 +14,6 @@
 
 #define IMX_ICC_MAX_LINKS	4
 
-/*
- * struct imx_icc_node_adj - Describe a dynamic adjustable node
- */
-struct imx_icc_node_adj_desc {
-	unsigned int bw_mul, bw_div;
-	const char *phandle_name;
-	bool main_noc;
-};
-
 /*
  * struct imx_icc_node - Describe an interconnect node
  * @name: name of the node
@@ -35,23 +26,21 @@ struct imx_icc_node_desc {
 	u16 id;
 	u16 links[IMX_ICC_MAX_LINKS];
 	u16 num_links;
-	const struct imx_icc_node_adj_desc *adj;
 };
 
-#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...)			\
+#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)			\
 	{								\
 		.id = _id,						\
 		.name = _name,						\
-		.adj = _adj,						\
 		.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),	\
 		.links = { __VA_ARGS__ },				\
 	}
 
 #define DEFINE_BUS_MASTER(_name, _id, _dest_id)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
+	DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
 
-#define DEFINE_BUS_SLAVE(_name, _id, _adj)				\
-	DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
+#define DEFINE_BUS_SLAVE(_name, _id)					\
+	DEFINE_BUS_INTERCONNECT(_name, _id)
 
 int imx_icc_register(struct platform_device *pdev,
 		     struct imx_icc_node_desc *nodes,
diff --git a/drivers/interconnect/imx/imx8mm.c b/drivers/interconnect/imx/imx8mm.c
index 1083490bb391..0c16110bef9d 100644
--- a/drivers/interconnect/imx/imx8mm.c
+++ b/drivers/interconnect/imx/imx8mm.c
@@ -14,18 +14,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 16,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, &imx8mm_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
 			IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, &imx8mm_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
 	DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, IMX8MM_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
 	DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
 
 	/* HSIO */
 	DEFINE_BUS_MASTER("USB1", IMX8MM_ICM_USB1, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("USB2", IMX8MM_ICM_USB2, IMX8MM_ICN_HSIO),
 	DEFINE_BUS_MASTER("PCIE", IMX8MM_ICM_PCIE, IMX8MM_ICN_HSIO),
-	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, NULL, IMX8MM_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_HSIO", IMX8MM_ICN_HSIO, IMX8MM_ICN_NOC),
 
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MM_ICM_SDMA2, IMX8MM_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MM_ICM_SDMA3, IMX8MM_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MM_ICN_AUDIO, IMX8MM_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MM_ICM_ENET, IMX8MM_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, NULL, IMX8MM_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MM_ICN_ENET, IMX8MM_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MM_ICM_SDMA1, IMX8MM_ICN_MAIN),
@@ -77,7 +65,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MM_ICM_USDHC1, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MM_ICM_USDHC2, IMX8MM_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MM_ICM_USDHC3, IMX8MM_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MM_ICN_MAIN,
 			IMX8MM_ICN_NOC, IMX8MM_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mn.c b/drivers/interconnect/imx/imx8mn.c
index ad97e55fd4e5..f03f8db00917 100644
--- a/drivers/interconnect/imx/imx8mn.c
+++ b/drivers/interconnect/imx/imx8mn.c
@@ -11,18 +11,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mn_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -30,23 +18,23 @@ static const struct imx_icc_node_adj_desc imx8mn_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC, &imx8mn_noc_adj,
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MN_ICN_NOC,
 			IMX8MN_ICS_DRAM, IMX8MN_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM, &imx8mn_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MN_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MN_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MN_ICM_A53, IMX8MN_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MN_ICM_GPU, IMX8MN_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MN_ICN_GPU, IMX8MN_ICN_NOC),
 
 	/* DISPLAYMIX */
 	DEFINE_BUS_MASTER("CSI1", IMX8MN_ICM_CSI1, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("CSI2", IMX8MN_ICM_CSI2, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("ISI", IMX8MN_ICM_ISI, IMX8MN_ICN_MIPI),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MN_ICM_LCDIF, IMX8MN_ICN_MIPI),
-	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, NULL, IMX8MN_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MN_ICN_MIPI, IMX8MN_ICN_NOC),
 
 	/* USB goes straight to NOC */
 	DEFINE_BUS_MASTER("USB", IMX8MN_ICM_USB, IMX8MN_ICN_NOC),
@@ -54,11 +42,11 @@ static struct imx_icc_node_desc nodes[] = {
 	/* Audio */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MN_ICM_SDMA2, IMX8MN_ICN_AUDIO),
 	DEFINE_BUS_MASTER("SDMA3", IMX8MN_ICM_SDMA3, IMX8MN_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MN_ICN_AUDIO, IMX8MN_ICN_MAIN),
 
 	/* Ethernet */
 	DEFINE_BUS_MASTER("ENET", IMX8MN_ICM_ENET, IMX8MN_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, NULL, IMX8MN_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MN_ICN_ENET, IMX8MN_ICN_MAIN),
 
 	/* Other */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MN_ICM_SDMA1, IMX8MN_ICN_MAIN),
@@ -66,7 +54,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC1", IMX8MN_ICM_USDHC1, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC2", IMX8MN_ICM_USDHC2, IMX8MN_ICN_MAIN),
 	DEFINE_BUS_MASTER("USDHC3", IMX8MN_ICM_USDHC3, IMX8MN_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MN_ICN_MAIN,
 			IMX8MN_ICN_NOC, IMX8MN_ICS_OCRAM),
 };
 
diff --git a/drivers/interconnect/imx/imx8mq.c b/drivers/interconnect/imx/imx8mq.c
index d7768d3c6d8a..b8c36d668946 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -12,18 +12,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mq_dram_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
-	.bw_mul = 1,
-	.bw_div = 4,
-	.main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -31,43 +19,42 @@ static const struct imx_icc_node_adj_desc imx8mq_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, &imx8mq_noc_adj,
-			IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("NOC", IMX8MQ_ICN_NOC, IMX8MQ_ICS_DRAM, IMX8MQ_ICN_MAIN),
 
-	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM, &imx8mq_dram_adj),
-	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM, NULL),
+	DEFINE_BUS_SLAVE("DRAM", IMX8MQ_ICS_DRAM),
+	DEFINE_BUS_SLAVE("OCRAM", IMX8MQ_ICS_OCRAM),
 	DEFINE_BUS_MASTER("A53", IMX8MQ_ICM_A53, IMX8MQ_ICN_NOC),
 
 	/* VPUMIX */
 	DEFINE_BUS_MASTER("VPU", IMX8MQ_ICM_VPU, IMX8MQ_ICN_VIDEO),
-	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MQ_ICN_VIDEO, IMX8MQ_ICN_NOC),
 
 	/* GPUMIX */
 	DEFINE_BUS_MASTER("GPU", IMX8MQ_ICM_GPU, IMX8MQ_ICN_GPU),
-	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MQ_ICN_GPU, IMX8MQ_ICN_NOC),
 
 	/* DISPMIX (only for DCSS) */
 	DEFINE_BUS_MASTER("DC", IMX8MQ_ICM_DCSS, IMX8MQ_ICN_DCSS),
-	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_DC", IMX8MQ_ICN_DCSS, IMX8MQ_ICN_NOC),
 
 	/* USBMIX */
 	DEFINE_BUS_MASTER("USB1", IMX8MQ_ICM_USB1, IMX8MQ_ICN_USB),
 	DEFINE_BUS_MASTER("USB2", IMX8MQ_ICM_USB2, IMX8MQ_ICN_USB),
-	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, NULL, IMX8MQ_ICN_NOC),
+	DEFINE_BUS_INTERCONNECT("PL301_USB", IMX8MQ_ICN_USB, IMX8MQ_ICN_NOC),
 
 	/* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
 	DEFINE_BUS_MASTER("CSI1", IMX8MQ_ICM_CSI1, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("CSI2", IMX8MQ_ICM_CSI2, IMX8MQ_ICN_DISPLAY),
 	DEFINE_BUS_MASTER("LCDIF", IMX8MQ_ICM_LCDIF, IMX8MQ_ICN_DISPLAY),
-	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_DISPLAY", IMX8MQ_ICN_DISPLAY, IMX8MQ_ICN_MAIN),
 
 	/* AUDIO */
 	DEFINE_BUS_MASTER("SDMA2", IMX8MQ_ICM_SDMA2, IMX8MQ_ICN_AUDIO),
-	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, NULL, IMX8MQ_ICN_DISPLAY),
+	DEFINE_BUS_INTERCONNECT("PL301_AUDIO", IMX8MQ_ICN_AUDIO, IMX8MQ_ICN_DISPLAY),
 
 	/* ENET */
 	DEFINE_BUS_MASTER("ENET", IMX8MQ_ICM_ENET, IMX8MQ_ICN_ENET),
-	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, NULL, IMX8MQ_ICN_MAIN),
+	DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
 
 	/* OTHER */
 	DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
@@ -76,7 +63,7 @@ static struct imx_icc_node_desc nodes[] = {
 	DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
 	DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
-	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN, NULL,
+	DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
 			IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
 };
 
-- 
2.31.1



From abel.vesa at nxp.com  Thu Jan  6 09:05:01 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu,  6 Jan 2022 19:05:01 +0200
Subject: [PATCH v3] interconnect: imx: Add imx_icc_get_bw function to set
 initial avg and peak
Message-ID: <20220106170501.3513423-1-abel.vesa@nxp.com>

Set the initial avg and peak to 0 in order to avoid setting them to
INT_MAX by the interconnect core.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---

Changes since v2:
 * sent as a separate patch
 * dropped the imx_icc_aggregate

 drivers/interconnect/imx/imx.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index d5b36c478911..734807d8ccca 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -25,6 +25,14 @@ struct imx_icc_node {
 	struct dev_pm_qos_request qos_req;
 };
 
+static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+	*avg = 0;
+	*peak = 0;
+
+	return 0;
+}
+
 static int imx_icc_node_set(struct icc_node *node)
 {
 	struct device *dev = node->provider->dev;
@@ -233,6 +241,7 @@ int imx_icc_register(struct platform_device *pdev,
 	if (!provider)
 		return -ENOMEM;
 	provider->set = imx_icc_set;
+	provider->get_bw = imx_icc_get_bw;
 	provider->aggregate = icc_std_aggregate;
 	provider->xlate = of_icc_xlate_onecell;
 	provider->data = data;
-- 
2.31.1



From kabel at kernel.org  Thu Jan  6 09:20:44 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Thu, 6 Jan 2022 18:20:44 +0100
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <877dbcvngf.wl-maz@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
 <20220106162047.vqykmygs75eimfgy@pali>
 <877dbcvngf.wl-maz@kernel.org>
Message-ID: <20220106182044.3ff0828c@thinkpad>

On Thu, 06 Jan 2022 16:27:44 +0000
Marc Zyngier <maz at kernel.org> wrote:

> On Thu, 06 Jan 2022 16:20:47 +0000,
> Pali Roh?r <pali at kernel.org> wrote:
> > 
> > On Thursday 06 January 2022 15:55:11 Marc Zyngier wrote:  
> > > On Thu, 06 Jan 2022 15:44:47 +0000,
> > > Pali Roh?r <pali at kernel.org> wrote:  
> > > > 
> > > > On Thursday 06 January 2022 15:28:20 Marc Zyngier wrote:  
> > > > > On Wed, 05 Jan 2022 15:02:38 +0000,
> > > > > Pali Roh?r <pali at kernel.org> wrote:  
> > > > > > 
> > > > > > This adds support for legacy INTx interrupts received from other PCIe
> > > > > > devices and which are reported by a new INTx irq chip.
> > > > > > 
> > > > > > With this change, kernel can distinguish between INTA, INTB, INTC and INTD
> > > > > > interrupts.
> > > > > > 
> > > > > > Note that for this support, device tree files has to be properly adjusted
> > > > > > to provide "interrupts" or "interrupts-extended" property with intx
> > > > > > interrupt source, "interrupt-names" property with "intx" string and also
> > > > > > 'interrupt-controller' subnode must be defined.
> > > > > > 
> > > > > > If device tree files do not provide these nodes then driver would work as
> > > > > > before.
> > > > > > 
> > > > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > > > ---
> > > > > >  drivers/pci/controller/pci-mvebu.c | 182 +++++++++++++++++++++++++++--
> > > > > >  1 file changed, 174 insertions(+), 8 deletions(-)
> > > > > > 
> > > > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > > > index 1e90ab888075..04bcdd7b7a6d 100644
> > > > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > > > @@ -54,9 +54,10 @@
> > > > > >  	 PCIE_CONF_ADDR_EN)
> > > > > >  #define PCIE_CONF_DATA_OFF	0x18fc
> > > > > >  #define PCIE_INT_CAUSE_OFF	0x1900
> > > > > > +#define PCIE_INT_UNMASK_OFF	0x1910
> > > > > > +#define  PCIE_INT_INTX(i)		BIT(24+i)
> > > > > >  #define  PCIE_INT_PM_PME		BIT(28)
> > > > > > -#define PCIE_MASK_OFF		0x1910
> > > > > > -#define  PCIE_MASK_ENABLE_INTS          0x0f000000
> > > > > > +#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
> > > > > >  #define PCIE_CTRL_OFF		0x1a00
> > > > > >  #define  PCIE_CTRL_X1_MODE		0x0001
> > > > > >  #define  PCIE_CTRL_RC_MODE		BIT(1)
> > > > > > @@ -110,6 +111,10 @@ struct mvebu_pcie_port {
> > > > > >  	struct mvebu_pcie_window iowin;
> > > > > >  	u32 saved_pcie_stat;
> > > > > >  	struct resource regs;
> > > > > > +	struct irq_domain *intx_irq_domain;
> > > > > > +	struct irq_chip intx_irq_chip;  
> > > > > 
> > > > > Why is this structure per port? It really should be global. Printing
> > > > > the port number in the name isn't enough of a reason.  
> > > > 
> > > > Because each port has its own independent set of INTA-INTD
> > > > interrupts.  
> > > 
> > > That doesn't warrant a copy of an irq_chip structure that contains the
> > > exact same callbacks, and only differs by *a string*. And the use of
> > > this string is only to end-up in /proc/interrupts, which is totally
> > > pointless.
> > >   
> > > >   
> > > > > > +	raw_spinlock_t irq_lock;
> > > > > > +	int intx_irq;
> > > > > >  };
> > > > > >  
> > > > > >  static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
> > > > > > @@ -235,7 +240,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> > > > > >  
> > > > > >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > > > >  {
> > > > > > -	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> > > > > > +	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> > > > > >  
> > > > > >  	/* Setup PCIe controller to Root Complex mode. */
> > > > > >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> > > > > > @@ -288,10 +293,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > > > > >  	/* Point PCIe unit MBUS decode windows to DRAM space. */
> > > > > >  	mvebu_pcie_setup_wins(port);
> > > > > >  
> > > > > > -	/* Enable interrupt lines A-D. */
> > > > > > -	mask = mvebu_readl(port, PCIE_MASK_OFF);
> > > > > > -	mask |= PCIE_MASK_ENABLE_INTS;
> > > > > > -	mvebu_writel(port, mask, PCIE_MASK_OFF);
> > > > > > +	/* Mask all interrupt sources. */
> > > > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> > > > > > +
> > > > > > +	/* Clear all interrupt causes. */
> > > > > > +	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> > > > > > +
> > > > > > +	if (port->intx_irq <= 0) {
> > > > > > +		/*
> > > > > > +		 * When neither "summary" interrupt, nor "intx" interrupt was
> > > > > > +		 * specified in DT then unmask all legacy INTx interrupts as in
> > > > > > +		 * this case driver does not provide a way for masking and
> > > > > > +		 * unmasking of individual legacy INTx interrupts. In this case
> > > > > > +		 * all interrupts, including legacy INTx are reported via one
> > > > > > +		 * shared GIC source and therefore kernel cannot distinguish
> > > > > > +		 * which individual legacy INTx was triggered. These interrupts
> > > > > > +		 * are shared, so it should not cause any issue. Just
> > > > > > +		 * performance penalty as every PCIe interrupt handler needs to
> > > > > > +		 * be called when some interrupt is triggered.
> > > > > > +		 */
> > > > > > +		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > > +		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
> > > > > > +			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
> > > > > > +		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);  
> > > > > 
> > > > > Maybe worth printing a warning here, so that the user knows they are
> > > > > on thin ice.  
> > > > 
> > > > Ok. I can add it here. Anyway, this is default current state without
> > > > this patch.
> > > >   
> > > > > > +	}
> > > > > >  }
> > > > > >  
> > > > > >  static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > > > > > @@ -924,6 +949,109 @@ static struct pci_ops mvebu_pcie_ops = {
> > > > > >  	.write = mvebu_pcie_wr_conf,
> > > > > >  };
> > > > > >  
> > > > > > +static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
> > > > > > +{
> > > > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > > > +	unsigned long flags;
> > > > > > +	u32 unmask;
> > > > > > +
> > > > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > > +	unmask &= ~PCIE_INT_INTX(hwirq);
> > > > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > > > +}
> > > > > > +
> > > > > > +static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
> > > > > > +{
> > > > > > +	struct mvebu_pcie_port *port = d->domain->host_data;
> > > > > > +	irq_hw_number_t hwirq = irqd_to_hwirq(d);
> > > > > > +	unsigned long flags;
> > > > > > +	u32 unmask;
> > > > > > +
> > > > > > +	raw_spin_lock_irqsave(&port->irq_lock, flags);
> > > > > > +	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
> > > > > > +	unmask |= PCIE_INT_INTX(hwirq);
> > > > > > +	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
> > > > > > +	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
> > > > > > +}
> > > > > > +
> > > > > > +static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
> > > > > > +				   unsigned int virq, irq_hw_number_t hwirq)
> > > > > > +{
> > > > > > +	struct mvebu_pcie_port *port = h->host_data;
> > > > > > +
> > > > > > +	irq_set_status_flags(virq, IRQ_LEVEL);
> > > > > > +	irq_set_chip_and_handler(virq, &port->intx_irq_chip, handle_level_irq);
> > > > > > +	irq_set_chip_data(virq, port);
> > > > > > +
> > > > > > +	return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
> > > > > > +	.map = mvebu_pcie_intx_irq_map,
> > > > > > +	.xlate = irq_domain_xlate_onecell,
> > > > > > +};
> > > > > > +
> > > > > > +static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
> > > > > > +{
> > > > > > +	struct device *dev = &port->pcie->pdev->dev;
> > > > > > +	struct device_node *pcie_intc_node;
> > > > > > +
> > > > > > +	raw_spin_lock_init(&port->irq_lock);
> > > > > > +
> > > > > > +	port->intx_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL,
> > > > > > +						  "mvebu-%s-INTx",
> > > > > > +						  port->name);  
> > > > > 
> > > > > That's exactly what I really don't want to see. It prevents sharing of
> > > > > the irq_chip structure, and gets in the way of making it const in the
> > > > > future. Yes, I know that some drivers do that. I can't fix those,
> > > > > because /proc/interrupts is ABI. But I really don't want to see more
> > > > > of these.  
> > > > 
> > > > Well, I do not understand why it should be shared and with who. HW has N
> > > > independent IRQ chips for legacy interrupts. And each one will be
> > > > specified in DT per HW layout / design.  
> > > 
> > > If you have multiple ports, all the ports can share the irq_chip
> > > structure. Actually scratch that. They *MUST* share the structure. The
> > > only reason you're not sharing it is to be able to print this useless
> > > string in /proc/interrupts.  
> > 
> > What is the point of sharing one irq chip if HW has N independent irq
> > chips (for legacy interrupts)? I do not catch it yet. And I do not care
> > here for /proc/interrupts, so also I have not caught what do you mean be
> > last sentence with "the only reason".
> > 
> > And I still do not see how it could even work to have just one irq chip
> > and one irq domain as each irq domain needs to know to which port it
> > belongs, so it can mask/unmask interrupts from correct port. Also
> > initialization of domain is taking DT node and for each port it is
> > different.
> > 
> > So I'm somehow confused here...
> > 
> > The improvement in this patch is to be able to mask INTA interrupts on
> > port 1 and let INTA interrupts unmasked on port 2 if there drivers are
> > interested only for interrupts from device connected to port 2.
> > 
> > And if all interrupts are going to be shared (again) then it does not
> > solve any problem.  
> 
> You are completely missing my point. I'm talking about data
> structures, you're talking about interrupts. You have this:
> 
> struct mvebu_pcie_port {
>        // Tons of stuff
>        struct irq_chip intx_chip;
> };
> 
> What I want you to do is:
> 
> struct mvebu_pcie_port {
>        // Tons of stuff
> };
> 
> static struct irq_chip intx_chip = {
> 	.name		= "INTx",
> 	.irq_mask	= mvebu_pcie_intx_irq_mask,
> 	.irq_unmask	= mvebu_pcie_intx_irq_unmask;
> };
> 
> That's it. No more, no less.
> 
> 	M.
> 

Hmm, but struct irq_chip contains a dynamic member,
  struct device *parent_device;
Isn't that used? Or are you planning to kill it?

Marek


From linux at roeck-us.net  Thu Jan  6 09:25:22 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 6 Jan 2022 09:25:22 -0800
Subject: [PATCH] fsi: Aspeed: Fix a potential double free
In-Reply-To: <20220106081418.GH7674@kadam>
References: <2cafa0607ca171ebd00ac6c7e073b46808e24f00.1640537669.git.christophe.jaillet@wanadoo.fr>
 <YcldM9sgYdjMYMtH@kroah.com> <20220106081418.GH7674@kadam>
Message-ID: <f2ba50fd-5c6b-e905-17ed-541dcc98c6c1@roeck-us.net>

On 1/6/22 12:14 AM, Dan Carpenter wrote:
> On Mon, Dec 27, 2021 at 07:29:07AM +0100, Greg KH wrote:
>> On Sun, Dec 26, 2021 at 05:56:02PM +0100, Christophe JAILLET wrote:
>>> 'aspeed' is a devm_alloc'ed, so there is no need to free it explicitly or
>>> there will be a double free().
>>
>> A struct device can never be devm_alloced for obvious reasons.  Perhaps
>> that is the real problem here?
>>
> 
> I don't understand how "aspeed" is a struct device.
> 

-static void aspeed_master_release(struct device *dev)
-{
-	struct fsi_master_aspeed *aspeed =
-		to_fsi_master_aspeed(dev_to_fsi_master(dev));
-
-	kfree(aspeed);
-}

So "dev" is embedded in struct fsi_master, and struct fsi_master is embedded
in struct fsi_master_aspeed. Since "struct device" is embedded, the data
structure embedding it must be released with the release function, as is done
here. The problem is indeed that the data structure is allocated with
devm_kzalloc(), which as Greg points out must not be devm_ allocated
(because its lifetime does not match the lifetime of devm_ allocated
memory).

> I've been working on understanding device managed memory recently for
> Smatch.  It's really complicated.  There are a bunch of rules/heuristics
> that I'm slowly creating to generate new warnings but I'm a long way
> from understanding it well myself.
> 

A data structure embedding struct device must not be devm_ allocated,
and it must be released with the release callback. Maybe there is
a means to flag that somehow ?

Guenter


From maz at kernel.org  Thu Jan  6 09:31:36 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 17:31:36 +0000
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220106182044.3ff0828c@thinkpad>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
 <20220106162047.vqykmygs75eimfgy@pali>
 <877dbcvngf.wl-maz@kernel.org> <20220106182044.3ff0828c@thinkpad>
Message-ID: <874k6gvkhz.wl-maz@kernel.org>

On Thu, 06 Jan 2022 17:20:44 +0000,
Marek Beh?n <kabel at kernel.org> wrote:
> 
> On Thu, 06 Jan 2022 16:27:44 +0000
> Marc Zyngier <maz at kernel.org> wrote:
> > You are completely missing my point. I'm talking about data
> > structures, you're talking about interrupts. You have this:
> > 
> > struct mvebu_pcie_port {
> >        // Tons of stuff
> >        struct irq_chip intx_chip;
> > };
> > 
> > What I want you to do is:
> > 
> > struct mvebu_pcie_port {
> >        // Tons of stuff
> > };
> > 
> > static struct irq_chip intx_chip = {
> > 	.name		= "INTx",
> > 	.irq_mask	= mvebu_pcie_intx_irq_mask,
> > 	.irq_unmask	= mvebu_pcie_intx_irq_unmask;
> > };
> > 
> > That's it. No more, no less.
> > 
> > 	M.
> > 
> 
> Hmm, but struct irq_chip contains a dynamic member,
>   struct device *parent_device;
> Isn't that used? Or are you planning to kill it?

Indeed, and I am definitely planning to kill it. This is the wrong
place for this stuff, and I want it gone. There are thankfully very
few users of this misfeature.

	M.

-- 
Without deviation from the norm, progress is not possible.


From jianhua.ljh at gmail.com  Thu Jan  6 09:34:16 2022
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Fri, 7 Jan 2022 01:34:16 +0800
Subject: [PATCH v2 2/2] arm64: kprobes: add support for KPROBES_ON_FTRACE
In-Reply-To: <20211217164019.7d5d9848f350fef4f709c62f@kernel.org>
References: <1635858706-27320-1-git-send-email-jianhua.ljh@gmail.com>
 <1635858706-27320-2-git-send-email-jianhua.ljh@gmail.com>
 <20211217164019.7d5d9848f350fef4f709c62f@kernel.org>
Message-ID: <CAAgTQPXi_cmi27upcLHgen3PotOtcu64oAxjYp559g6fYgkCvQ@mail.gmail.com>

On Fri, Dec 17, 2021 at 3:40 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
>
> Hi,
>
> On Tue,  2 Nov 2021 21:11:46 +0800
> Janet Liu <jianhua.ljh at gmail.com> wrote:
>
> > From: Janet Liu <janet.liu at unisoc.com>
> >
> > This patch allow kprobes on ftrace call sites. This optimization
> > avoids use of a trap with regular kprobes.
> >
> > This depends on HAVE_DYNAMIC_FTRACE_WITH_REGS which depends on
> > "patchable-function-entry" options which is only implemented with newer
> > toolchains.
> >
> > Signed-off-by: Janet Liu <janet.liu at unisoc.com>
> > ---
> >  arch/arm64/Kconfig                 |  1 +
> >  arch/arm64/kernel/probes/Makefile  |  1 +
> >  arch/arm64/kernel/probes/ftrace.c  | 73 ++++++++++++++++++++++++++++++
> >  arch/arm64/kernel/probes/kprobes.c | 27 +++++++++++
> >  4 files changed, 102 insertions(+)
> >  create mode 100644 arch/arm64/kernel/probes/ftrace.c
> >
> > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > index 339130712093..f59005608976 100644
> > --- a/arch/arm64/Kconfig
> > +++ b/arch/arm64/Kconfig
> > @@ -200,6 +200,7 @@ config ARM64
> >       select HAVE_SYSCALL_TRACEPOINTS
> >       select HAVE_KPROBES
> >       select HAVE_OPTPROBES
> > +     select HAVE_KPROBES_ON_FTRACE
> >       select HAVE_KRETPROBES
> >       select HAVE_GENERIC_VDSO
> >       select IOMMU_DMA if IOMMU_SUPPORT
> > diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> > index c77c92ac95fd..d9b204f4795a 100644
> > --- a/arch/arm64/kernel/probes/Makefile
> > +++ b/arch/arm64/kernel/probes/Makefile
> > @@ -3,5 +3,6 @@ obj-$(CONFIG_KPROBES)         += kprobes.o decode-insn.o      \
> >                                  kprobes_trampoline.o         \
> >                                  simulate-insn.o
> >  obj-$(CONFIG_OPTPROBES)      += opt.o opt_head.o
> > +obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
> >  obj-$(CONFIG_UPROBES)                += uprobes.o decode-insn.o      \
> >                                  simulate-insn.o
> > diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
> > new file mode 100644
> > index 000000000000..46ea92eb552f
> > --- /dev/null
> > +++ b/arch/arm64/kernel/probes/ftrace.c
> > @@ -0,0 +1,73 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +//
> > +// Dynamic Ftrace based Kprobes Optimization
> > +//
> > +// Copyright (C) 2021, Unisoc Inc.
> > +// Author: Janet Liu <janet.liu at unisoc.com>
> > +#include <linux/kprobes.h>
> > +#include <linux/ptrace.h>
> > +#include <linux/hardirq.h>
> > +#include <linux/preempt.h>
> > +#include <linux/ftrace.h>
> > +
> > +
> > +/* Ftrace callback handler for kprobes*/
> > +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > +                        struct ftrace_ops *ops, struct ftrace_regs *fregs)
> > +{
> > +     struct kprobe *p;
> > +     struct kprobe_ctlblk *kcb;
> > +     struct pt_regs *regs = ftrace_get_regs(fregs);
> > +     int bit;
> > +
> > +     bit = ftrace_test_recursion_trylock(ip, parent_ip);
> > +     if (bit < 0)
> > +             return;
> > +
> > +     preempt_disable_notrace();
>
> This already has been done in ftrace side.

Hi Masami,

Got it by reading code, will fix this.

>
> > +     p = get_kprobe((kprobe_opcode_t *)ip);
> > +     if (unlikely(!p) || kprobe_disabled(p))
> > +             goto end;
> > +
> > +     kcb = get_kprobe_ctlblk();
> > +     if (kprobe_running()) {
> > +             kprobes_inc_nmissed_count(p);
> > +     } else {
> > +             unsigned long orig_ip = instruction_pointer(regs);
> > +
> > +             instruction_pointer_set(regs, ip);
>
> The 'ip' is the address of the 'bl' instruction, which must be
> p->addr + AARCH64_INSN_SIZE * 2. But this is a bit strange.
>
> On aarch64, if the user probe callback is called from breakpoint handler,
> regs->pc == kp->addr. But in this case, it is not the same.
>
> So, what about this?
>
>  instruction_pointer_set(regs, ip - AARCH64_INSN_SIZE);
>

I got what you said.

But p->addr is changed when KPROBES_ON_FTRACE enable.
I implemented kprobe_lookup_name for arm64 to do the change in this patch.
because kernel/kprobe.c:check_ftrace_location check,
if p->addr != ftrace_addr, don't kprobe on ftrace entry.
so p->addr is equal to ftrace addr(the second nop), is equal to 'ip'.
here should be instruction_pointer_set(regs, ip);

> > +
> > +             __this_cpu_write(current_kprobe, p);
> > +             kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> > +             if (!p->pre_handler || !p->pre_handler(p, regs)) {
> > +                     /*
> > +                      *Emulate singlestep (and also recover regs->pc)
> > +                      *as if there is a nop
> > +                      */
> > +                     instruction_pointer_set(regs,
> > +                                     (unsigned long)p->addr + MCOUNT_INSN_SIZE);
>
> And then, this will be
>
>                         instruction_pointer_set(regs,
>                                         (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
>
> So basically, kprobes on ftrace will skips 2 NOP instructions (the compiler installed
> 2 nops) and call post handler. This means we have a virtual big NOP instruction there.
>
Ditto, skip two nop instructions should
instruction_pointer_set(regs,
                        (unsigned long)p->addr + AARCH64_INSN_SIZE);


> > +                     if (unlikely(p->post_handler)) {
> > +                             kcb->kprobe_status = KPROBE_HIT_SSDONE;
> > +                             p->post_handler(p, regs, 0);
> > +                     }
> > +                     instruction_pointer_set(regs, orig_ip);
> > +             }
> > +
> > +             /*
> > +              * If pre_handler returns !0,it changes regs->pc. We have to
> > +              * skip emulating post_handler.
> > +              */
> > +             __this_cpu_write(current_kprobe, NULL);
> > +     }
> > +end:
> > +     preempt_enable_notrace();
> > +     ftrace_test_recursion_unlock(bit);
> > +}
> > +NOKPROBE_SYMBOL(kprobe_ftrace_handler);
> > +
> > +int arch_prepare_kprobe_ftrace(struct kprobe *p)
> > +{
> > +     p->ainsn.api.insn = NULL;
> > +     p->ainsn.api.restore = 0;
> > +     return 0;
> > +}
> > diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> > index 6dbcc89f6662..3d371d3e4dfa 100644
> > --- a/arch/arm64/kernel/probes/kprobes.c
> > +++ b/arch/arm64/kernel/probes/kprobes.c
> > @@ -417,6 +417,33 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
> >       return 0;
> >  }
> >
> > +kprobe_opcode_t __kprobes *kprobe_lookup_name(const char *name, unsigned int offset)
> > +{
> > +     kprobe_opcode_t *addr;
> > +
> > +     addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
> > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > +     if (addr && !offset) {
> > +             unsigned long faddr;
> > +
> > +             faddr = ftrace_location_range((unsigned long)addr,
> > +                                           (unsigned long)addr + 8);
>
> this '8' must be (AARCH64_INSN_SIZE * 2). And here you may need to add
> a comment why search the 2 instructions. (it is because arm64 uses
> -fpatchable-function-entry=2.)
>
Got it , will fix it.
> > +             if (faddr)
> > +                     addr = (kprobe_opcode_t *)faddr;
> > +     }
This change the p->addr to ftrace_addr.

> > +#endif
> > +     return addr;
> > +}
> > +
> > +bool __kprobes arch_kprobe_on_func_entry(unsigned long offset)
> > +{
> > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > +     return offset <= 8;
>
> Ditto.
Got it, will add comment.

Thanks

Jianhua
>
> > +#else
> > +     return !offset;
> > +#endif
> > +}
> > +
> >  int __init arch_init_kprobes(void)
> >  {
> >       register_kernel_break_hook(&kprobes_break_hook);
> > --
> > 2.25.1
> >
>
> Thank you,
>
>
> --
> Masami Hiramatsu <mhiramat at kernel.org>


From seanjc at google.com  Thu Jan  6 09:38:41 2022
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 6 Jan 2022 17:38:41 +0000
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
 <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
Message-ID: <YdcpIQgMZJrqswKU@google.com>

On Thu, Jan 06, 2022, David Stevens wrote:
> On Thu, Jan 6, 2022 at 4:19 AM Sean Christopherson <seanjc at google.com> wrote:
> >
> > On Wed, Jan 05, 2022, Sean Christopherson wrote:
> > > Ah, I got royally confused by ensure_pfn_ref()'s comment
> > >
> > >   * Certain IO or PFNMAP mappings can be backed with valid
> > >   * struct pages, but be allocated without refcounting e.g.,
> > >   * tail pages of non-compound higher order allocations, which
> > >   * would then underflow the refcount when the caller does the
> > >   * required put_page. Don't allow those pages here.
> > >                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > that doesn't apply here because kvm_faultin_pfn() uses the low level
> > > __gfn_to_pfn_page_memslot().
> >
> > On fifth thought, I think this is wrong and doomed to fail.  By mapping these pages
> > into the guest, KVM is effectively saying it supports these pages.  But if the guest
> > uses the corresponding gfns for an action that requires KVM to access the page,
> > e.g. via kvm_vcpu_map(), ensure_pfn_ref() will reject the access and all sorts of
> > bad things will happen to the guest.
> >
> > So, why not fully reject these types of pages?  If someone is relying on KVM to
> > support these types of pages, then we'll fail fast and get a bug report letting us
> > know we need to properly support these types of pages.  And if not, then we reduce
> > KVM's complexity and I get to keep my precious WARN :-)
> 
> Our current use case here is virtio-gpu blob resources [1]. Blob
> resources are useful because they avoid a guest shadow buffer and the
> associated memcpys, and as I understand it they are also required for
> virtualized vulkan.
> 
> One type of blob resources requires mapping dma-bufs allocated by the
> host directly into the guest. This works on Intel platforms and the
> ARM platforms I've tested. However, the amdgpu driver sometimes
> allocates higher order, non-compound pages via ttm_pool_alloc_page.

Ah.  In the future, please provide this type of information in the cover letter,
and in this case, a paragraph in patch 01 is also warranted.  The context of _why_
is critical information, e.g. having something in the changelog explaining the use
case is very helpful for future developers wondering why on earth KVM supports
this type of odd behavior.

> These are the type of pages which KVM is currently rejecting. Is this
> something that KVM can support?

I'm not opposed to it.  My complaint is that this series is incomplete in that it
allows mapping the memory into the guest, but doesn't support accessing the memory
from KVM itself.  That means for things to work properly, KVM is relying on the
guest to use the memory in a limited capacity, e.g. isn't using the memory as
general purpose RAM.  That's not problematic for your use case, because presumably
the memory is used only by the vGPU, but as is KVM can't enforce that behavior in
any way.

The really gross part is that failures are not strictly punted to userspace;
the resulting error varies significantly depending on how the guest "illegally"
uses the memory.

My first choice would be to get the amdgpu driver "fixed", but that's likely an
unreasonable request since it sounds like the non-KVM behavior is working as intended.

One thought would be to require userspace to opt-in to mapping this type of memory
by introducing a new memslot flag that explicitly states that the memslot cannot
be accessed directly by KVM, i.e. can only be mapped into the guest.  That way,
KVM has an explicit ABI with respect to how it handles this type of memory, even
though the semantics of exactly what will happen if userspace/guest violates the
ABI are not well-defined.  And internally, KVM would also have a clear touchpoint
where it deliberately allows mapping such memslots, as opposed to the more implicit
behavior of bypassing ensure_pfn_ref().

If we're clever, we might even be able to share the flag with the "guest private
memory"[*] concept being pursued for confidential VMs.

[*] https://lore.kernel.org/all/20211223123011.41044-1-chao.p.peng at linux.intel.com


From helgaas at kernel.org  Thu Jan  6 10:00:26 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 6 Jan 2022 12:00:26 -0600
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220105181306.mkratasqg36tjf4e@pali>
Message-ID: <20220106180026.GA295674@bhelgaas>

On Wed, Jan 05, 2022 at 07:13:06PM +0100, Pali Roh?r wrote:
> On Wednesday 05 January 2022 09:51:48 Ray Jui wrote:
> > On 1/5/2022 1:35 AM, Pali Roh?r wrote:

> > 2. I suppose 'PCI_CLASS_BRIDGE_PCI_NORMAL' is defined in some common PCI
> > header in a separate patch as described in the commit message. Then how
> > come these patches are not constructed with a patch series?
> 
> Yes, PCI_CLASS_BRIDGE_PCI_NORMAL is a new constant for common pci header
> file defined in patch linked in commit message.
> https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
> 
> Originally I included this change in v1 of linked patch in December but
> I realized that it does not match standard PCI config space (different
> offset 0x43c vs 0x08 and also different shift 0x8 vs 0x0) and probably
> there is something either incorrect or really non-standard. So later in
> December I dropped iproc_pcie_check_link() change in v2 of the linked
> patch where is introduced PCI_CLASS_BRIDGE_PCI_NORMAL and now sent new
> change for iproc_pcie_check_link() separately.
> 
> Technically, linked patch in commit message is just extracting code into
> the common macros without any functional changed. But change in this
> iproc_pcie_check_link() has also functional change as now also lower 8
> bits of class code are changed. So in my opinion this patch should be
> really separate of linked patch.
> 
> I hope that Lorenzo and Bjorn take patches in correct order...

If patches are not sent together in a series, you can't assume
anything about the order they'll be applied in.  Adding a note about
"this patch depends patch X" helps a little but adds a fair amount of
friction to the process.

Bjorn


From baruch at tkos.co.il  Thu Jan  6 10:05:22 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 06 Jan 2022 20:05:22 +0200
Subject: [PATCH v4 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <20220106144518.GA15482@lpieralisi>
References: <cover.1640587131.git.baruch@tkos.co.il>
 <a2406bf515124afad50ca3c947e2cd758c0896b1.1640587131.git.baruch@tkos.co.il>
 <20220106144518.GA15482@lpieralisi>
Message-ID: <87k0fcenuw.fsf@tarshish>

Hi Lorenzo,

On Thu, Jan 06 2022, Lorenzo Pieralisi wrote:
> [+Pali - query on reset delay]
>
> On Mon, Dec 27, 2021 at 08:46:05AM +0200, Baruch Siach wrote:
>> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> 
>> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
>> platform.
>> 
>> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
>> win.linuxopenwrt.2.0).
>> 
>> Split out the DBI registers access part from .init into .post_init. DBI
>> registers are only accessible after phy_power_on().
>> 
>> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
>> 
>> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
>> ---
>> v4:
>> 
>>   * Rebase on v5.16-rc1
>> 
>> v3:
>>   * Drop speed setup; rely on generic code (Rob Herring)
>> 
>>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
>> 
>>   * Minor formatting fixes (Bjorn Helgaas)
>> 
>>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
>> 
>> v2:
>>   * Drop ATU configuration; rely on common code instead
>> 
>>   * Use more common register macros
>> 
>>   * Use bulk clk and reset APIs
>> ---
>>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>>  drivers/pci/controller/dwc/pcie-qcom.c       | 145 +++++++++++++++++++
>>  2 files changed, 146 insertions(+)
>> 
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index ea87809ee298..279c3778a13b 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -76,6 +76,7 @@
>>  
>>  #define GEN3_RELATED_OFF			0x890
>>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
>> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
>>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index 1c3d1116bb60..14f86c45a8d9 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -52,6 +52,10 @@
>>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
>>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
>>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
>> +#define AHB_CLK_EN				BIT(0)
>> +#define MSTR_AXI_CLK_EN				BIT(1)
>> +#define BYPASS					BIT(4)
>> +
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
>>  #define PCIE20_PARF_LTSSM			0x1B0
>> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
>>  	struct clk *ref_clk_src;
>>  };
>>  
>> +struct qcom_pcie_resources_2_9_0 {
>> +	struct clk_bulk_data clks[5];
>> +	struct reset_control *rst;
>> +};
>> +
>>  union qcom_pcie_resources {
>>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
>>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
>> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
>>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
>>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
>>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
>> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
>>  };
>>  
>>  struct qcom_pcie;
>> @@ -1297,6 +1307,127 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>>  	clk_disable_unprepare(res->pipe_clk);
>>  }
>>  
>> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +	struct dw_pcie *pci = pcie->pci;
>> +	struct device *dev = pci->dev;
>> +	int ret;
>> +
>> +	res->clks[0].id = "iface";
>> +	res->clks[1].id = "axi_m";
>> +	res->clks[2].id = "axi_s";
>> +	res->clks[3].id = "axi_bridge";
>> +	res->clks[4].id = "rchng";
>> +
>> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	res->rst = devm_reset_control_array_get_exclusive(dev);
>> +	if (IS_ERR(res->rst))
>> +		return PTR_ERR(res->rst);
>> +
>> +	return 0;
>> +}
>> +
>> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +
>> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
>> +}
>> +
>> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +	struct device *dev = pcie->pci->dev;
>> +	int ret;
>> +
>> +	ret = reset_control_assert(res->rst);
>> +	if (ret) {
>> +		dev_err(dev, "reset assert failed (%d)\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	usleep_range(2000, 2500);
>> +
>> +	ret = reset_control_deassert(res->rst);
>> +	if (ret) {
>> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	/*
>> +	 * Don't have a way to see if the reset has completed.
>> +	 * Wait for some time.
>
> Is this arbitrary ? What does this reset represent ?

I have no idea. I'm just porting working downstream kernel code, and I
have no access to hardware documentation.

Note that some other variants also add delays before or after reset
deassert:

  qcom_pcie_init_2_4_0()

  qcom_pcie_init_2_3_3()

  qcom_pcie_init_2_7_0()

baruch

>> +	 */
>> +	usleep_range(2000, 2500);
>> +
>> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
>> +	if (ret)
>> +		goto err_reset;
>> +
>> +	return 0;
>> +
>> +	/*
>> +	 * Not checking for failure, will anyway return
>> +	 * the original failure in 'ret'.
>> +	 */
>> +err_reset:
>> +	reset_control_assert(res->rst);
>> +
>> +	return ret;
>> +}
>> +
>> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct dw_pcie *pci = pcie->pci;
>> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> +	u32 val;
>> +	int i;
>> +
>> +	writel(SLV_ADDR_SPACE_SZ,
>> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
>> +
>> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +	val &= ~BIT(0);
>> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +
>> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
>> +
>> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
>> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
>> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
>> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
>> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
>> +		pci->dbi_base + GEN3_RELATED_OFF);
>> +
>> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
>> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
>> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
>> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
>> +
>> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
>> +
>> +	dw_pcie_dbi_ro_wr_en(pci);
>> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
>> +
>> +	/* Configure PCIe link capabilities for ASPM */
>> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
>> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +
>> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> +			PCI_EXP_DEVCTL2);
>> +
>> +	for (i = 0; i < 256; i++)
>> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
>> +				+ (4 * i));
>> +
>> +	return 0;
>> +}
>> +
>>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>>  {
>>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> @@ -1487,6 +1618,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>>  	.config_sid = qcom_pcie_config_sid_sm8250,
>>  };
>>  
>> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
>> +static const struct qcom_pcie_ops ops_2_9_0 = {
>> +	.get_resources = qcom_pcie_get_resources_2_9_0,
>> +	.init = qcom_pcie_init_2_9_0,
>> +	.post_init = qcom_pcie_post_init_2_9_0,
>> +	.deinit = qcom_pcie_deinit_2_9_0,
>> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>> +};
>> +
>>  static const struct qcom_pcie_cfg apq8084_cfg = {
>>  	.ops = &ops_1_0_0,
>>  };
>> @@ -1520,6 +1660,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
>>  	.pipe_clk_need_muxing = true,
>>  };
>>  
>> +static const struct qcom_pcie_cfg ipq6018_cfg = {
>> +	.ops = &ops_2_9_0,
>> +};
>> +
>>  static const struct dw_pcie_ops dw_pcie_ops = {
>>  	.link_up = qcom_pcie_link_up,
>>  	.start_link = qcom_pcie_start_link,
>> @@ -1629,6 +1773,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
>>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
>>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
>> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
>>  	{ }
>>  };
>>  
>> -- 
>> 2.34.1
>> 


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From alim.akhtar at gmail.com  Thu Jan  6 10:13:05 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Thu, 6 Jan 2022 23:43:05 +0530
Subject: [RFT][PATCH 1/3] ARM: dts: exynos: fix UART3 pins configuration
 in Exynos5250
In-Reply-To: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
References: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ52GgtkJ6RStGXik7PmMNfaisrqRojmsvQZWUPaNR8Qp+g@mail.gmail.com>

Hi Krzysztof

On Fri, Dec 31, 2021 at 4:02 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The gpa1-4 pin was put twice in UART3 pin configuration of Exynos5250,
> instead of proper pin gpa1-5.
>
> Fixes: f8bfe2b050f3 ("ARM: dts: add pin state information in client nodes for Exynos5 platforms")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Thanks for fixing this.
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> index d31a68672bfa..d7d756614edd 100644
> --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> @@ -260,7 +260,7 @@ i2c3_hs_bus: i2c3-hs-bus {
>         };
>
>         uart3_data: uart3-data {
> -               samsung,pins = "gpa1-4", "gpa1-4";
> +               samsung,pins = "gpa1-4", "gpa1-5";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> --
> 2.32.0
>


-- 
Regards,
Alim


From catalin.marinas at arm.com  Thu Jan  6 10:13:37 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 6 Jan 2022 18:13:37 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
Message-ID: <YdcxUZ06f60UQMKM@arm.com>

On Thu, Jan 06, 2022 at 10:09:35AM -0600, Jeremy Linton wrote:
> On 1/6/22 05:00, Catalin Marinas wrote:
> > On Wed, Jan 05, 2022 at 04:42:01PM -0600, Jeremy Linton wrote:
> > > So, mentally i'm having a hard time balancing the hypothetical problem laid
> > > out, as it should only really exist in an environment similar to the MDWE
> > > one, since AFAIK, its possible today to just flip it back off unless MDWE
> > > stops that from happening.
> > 
> > That's a user ABI change and given that the first attempt was shown to
> > break with some combination of old loader and new main executable (or
> > the other way around), I'd rather keep things as they are.
> 
> This should only change the behavior for for binaries which conform to the
> new ABI containing the BTI note. So outside of the tiny window of things
> built with BTI, but run on !BTI hardware or older kernel+glibc, this
> shouldn't be a problem. (Unless i'm missing something) Put another way, now
> is the time to make a change, before there is a legacy BTI ecosystem we have
> to deal with.

The concern is that the loader may decide in the future to not enable
(or turn off) BTI for some reason (e.g. mixed libraries, old glibc on
BTI hardware). If we force BTI on the main executable, we'd take this
option away. Note also that it's not only glibc here, there are other
loaders.

> > AFAICT MDWX wants (one of the filters) to prevent a previously writable
> > mapping from becoming executable through mprotect(PROT_EXEC). How common
> > is mprotect(PROT_EXEC|PROT_BTI) outside of the dynamic loader? I doubt
> > it is, especially in an MDWX environment. So can we not change the
> > filter to allow PROT_EXEC|PROT_BTI? If your code is already exploitable
> > to allow random syscalls, all bets are off anyway.
> 
> I would expect JITs to be twittling EXEC|BTI but, those wouldn't be able to
> trivially run under MDWE anyway. So rarely?
> 
> Changing the filter to allow PROT_EXEC|PROT_BTI defeats the purpose because
> the hypothetical exploit would just add the BTI tags and turn BTI on as
> well. The filter, as is, also provides additional BTI protections because it
> makes it more difficult to disable BTI. Without that filter it seems likely
> someone could come up with a way to use an existing PROT_EXEC as a gadget to
> disable BTI anywhere they choose.

To me, MDWX is more about protecting against making some (previously)
writable buffers executable (either inadvertently or as a programmer
decision). It's not meant to prevent the hijacking of the instruction
flow or data corruption that ends up as an mprotect(PROT_EXEC|PROT_BTI)
call. If that's possible, the MDWX mitigation is really negligible.

That said, the programmer may learn that passing PROT_BTI avoids the
filter and start using it, though it's not trivial due to the need for
landing pads.

> So, to your point before, BTI+MDWE are complementary, the combination seems
> considerably more robust than either by itself.

Before we come up with a better solution, I find allowing PROT_BTI an
acceptable compromise. I don't think we lose much with the current
codebase.

As for a better solution, we need to track the state of a memory range
as BPF denying PROT_EXEC anywhere is a pretty big hammer. We could add a
VM_WAS_WRITE flag and, in combination with a prctl() to opt in to the
feature, prevent mprotect(PROT_EXEC) on such vmas. No need for seccomp
bpf filters.

-- 
Catalin


From maz at kernel.org  Thu Jan  6 10:16:04 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 18:16:04 +0000
Subject: [PATCH v3 3/4] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU
 attribute
In-Reply-To: <YdbYY/EZrTTPKOCp@monolith.localdoman>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <20211213152309.158462-4-alexandru.elisei@arm.com>
 <8735mvjrq8.wl-maz@kernel.org>
 <YdbYY/EZrTTPKOCp@monolith.localdoman>
Message-ID: <8735m0vifv.wl-maz@kernel.org>

On Thu, 06 Jan 2022 11:54:11 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Tue, Dec 14, 2021 at 12:28:15PM +0000, Marc Zyngier wrote:
> > On Mon, 13 Dec 2021 15:23:08 +0000,
> > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > 
> > > When KVM creates an event and there are more than one PMUs present on the
> > > system, perf_init_event() will go through the list of available PMUs and
> > > will choose the first one that can create the event. The order of the PMUs
> > > in the PMU list depends on the probe order, which can change under various
> > > circumstances, for example if the order of the PMU nodes change in the DTB
> > > or if asynchronous driver probing is enabled on the kernel command line
> > > (with the driver_async_probe=armv8-pmu option).
> > > 
> > > Another consequence of this approach is that, on heteregeneous systems,
> > > all virtual machines that KVM creates will use the same PMU. This might
> > > cause unexpected behaviour for userspace: when a VCPU is executing on
> > > the physical CPU that uses this PMU, PMU events in the guest work
> > > correctly; but when the same VCPU executes on another CPU, PMU events in
> > > the guest will suddenly stop counting.
> > > 
> > > Fortunately, perf core allows user to specify on which PMU to create an
> > > event by using the perf_event_attr->type field, which is used by
> > > perf_init_event() as an index in the radix tree of available PMUs.
> > > 
> > > Add the KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU
> > > attribute to allow userspace to specify the arm_pmu that KVM will use when
> > > creating events for that VCPU. KVM will make no attempt to run the VCPU on
> > > the physical CPUs that share this PMU, leaving it up to userspace to
> > > manage the VCPU threads' affinity accordingly.
> > > 
> > > Setting the PMU for a VCPU is an all of nothing affair to avoid exposing an
> > > asymmetric system to the guest: either all VCPUs have the same PMU, either
> > > none of the VCPUs have a PMU set. Attempting to do something in between
> > > will result in an error being returned when doing KVM_ARM_VCPU_PMU_V3_INIT.
> > > 
> > > Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> > > ---
> > > 
> > > Checking that all VCPUs have the same PMU is done when the PMU is
> > > initialized because setting the VCPU PMU is optional, and KVM cannot know
> > > what the user intends until the KVM_ARM_VCPU_PMU_V3_INIT ioctl, which
> > > prevents further changes to the VCPU PMU. vcpu->arch.pmu.created has been
> > > changed to an atomic variable because changes to the VCPU PMU state now
> > > need to be observable by all physical CPUs.
> > > 
> > >  Documentation/virt/kvm/devices/vcpu.rst | 30 ++++++++-
> > >  arch/arm64/include/uapi/asm/kvm.h       |  1 +
> > >  arch/arm64/kvm/pmu-emul.c               | 88 ++++++++++++++++++++-----
> > >  include/kvm/arm_pmu.h                   |  4 +-
> > >  tools/arch/arm64/include/uapi/asm/kvm.h |  1 +
> > >  5 files changed, 104 insertions(+), 20 deletions(-)
> > > 
> > > [..]
> > > -static u32 kvm_pmu_event_mask(struct kvm *kvm)
> > > +static u32 kvm_pmu_event_mask(struct kvm_vcpu *vcpu)
> > >  {
> > > -	switch (kvm->arch.pmuver) {
> > > +	unsigned int pmuver;
> > > +
> > > +	if (vcpu->arch.pmu.arm_pmu)
> > > +		pmuver = vcpu->arch.pmu.arm_pmu->pmuver;
> > > +	else
> > > +		pmuver = vcpu->kvm->arch.pmuver;
> > 
> > This puzzles me throughout the whole patch. Why is the arm_pmu pointer
> > a per-CPU thing? I would absolutely expect it to be stored in the kvm
> > structure, making the whole thing much simpler.
> 
> Reply below.
> 
> > 
> > > [..]
> > > @@ -637,8 +645,7 @@ static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
> > >  		return;
> > >  
> > >  	memset(&attr, 0, sizeof(struct perf_event_attr));
> > > -	attr.type = PERF_TYPE_RAW;
> > > -	attr.size = sizeof(attr);
> > 
> > Why is this line removed?
> 
> Typo on my part, thank you for spotting it.
> 
> > 
> > > [..]
> > > @@ -910,7 +922,16 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
> > >  	init_irq_work(&vcpu->arch.pmu.overflow_work,
> > >  		      kvm_pmu_perf_overflow_notify_vcpu);
> > >  
> > > -	vcpu->arch.pmu.created = true;
> > > +	atomic_set(&vcpu->arch.pmu.created, 1);
> > > +
> > > +	kvm_for_each_vcpu(i, v, kvm) {
> > > +		if (!atomic_read(&v->arch.pmu.created))
> > > +			continue;
> > > +
> > > +		if (v->arch.pmu.arm_pmu != arm_pmu)
> > > +			return -ENXIO;
> > > +	}
> > 
> > If you did store the arm_pmu at the VM level, you wouldn't need this.
> > You could detect the discrepancy in the set_pmu ioctl.
> 
> I chose to set at the VCPU level to be consistent with how KVM treats the
> PMU interrupt ID when the interrupt is a PPI, where the interrupt ID must
> be the same for all VCPUs and it is stored at the VCPU. However, looking at
> the code again, it occurs to me that it is stored at the VCPU when it's a
> PPI because it's simpler to do it that way, as the code remains the same
> when the interrupt ID is a SPI, which must be *different* between VCPUs. So
> in the end, having the PMU stored at the VM level does match how KVM uses
> it, which looks to be better than my approach.
> 
> This is the change you proposed in your branch [1]:
> 
> +static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
> +{
> +       struct kvm *kvm = vcpu->kvm;
> +       struct arm_pmu_entry *entry;
> +       struct arm_pmu *arm_pmu;
> +       int ret = -ENXIO;
> +
> +       mutex_lock(&kvm->lock);
> +       mutex_lock(&arm_pmus_lock);
> +
> +       list_for_each_entry(entry, &arm_pmus, entry) {
> +               arm_pmu = entry->arm_pmu;
> +               if (arm_pmu->pmu.type == pmu_id) {
> +                       /* Can't change PMU if filters are already in place */
> +                       if (kvm->arch.arm_pmu != arm_pmu &&
> +                           kvm->arch.pmu_filter) {
> +                               ret = -EBUSY;
> +                               break;
> +                       }
> +
> +                       kvm->arch.arm_pmu = arm_pmu;
> +                       ret = 0;
> +                       break;
> +               }
> +       }
> +
> +       mutex_unlock(&arm_pmus_lock);
> +       mutex_unlock(&kvm->lock);
> +       return ret;
> +}
> 
> As I understand the code, userspace only needs to call
> KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) *once* (on one VCPU
> fd) to set the PMU for all the VCPUs; subsequent calls (on the same VCPU or
> on another VCPU) with a different PMU id will change the PMU for all VCPUs.
> 
> Two remarks:
> 
> 1. The documentation for the VCPU ioctls states this (from
> Documentation/virt/kvm/devices/vcpu.rst):
> 
> "
> ======================
> Generic vcpu interface
> ======================
> 
> The virtual cpu "device" also accepts the ioctls KVM_SET_DEVICE_ATTR,
> KVM_GET_DEVICE_ATTR, and KVM_HAS_DEVICE_ATTR. The interface uses the same struct
> kvm_device_attr as other devices, but **targets VCPU-wide settings and
> controls**" (emphasis added).
> 
> But I guess having VCPU ioctls affect *only* the VCPU hasn't really been
> true ever since PMU event filtering has been added. I'll send a patch to
> change that part of the documentation for arm64.
> 
> I was thinking maybe a VM capability would be better suited for changing a
> VM-wide setting, what do you think? I don't have a strong preference either
> way.

I'm not sure it is worth the hassle of changing the API, as we'll have
to keep the current one forever.

> 
> 2. What's to stop userspace to change the PMU after at least one VCPU has
> run? That can be easily observed by the guest when reading PMCEIDx_EL0.

That's a good point. We need something here. It is a bit odd as to do
that, you need to fully enable a PMU on one CPU, but not on the other,
then run the first while changing stuff on the other. Something along
those lines (untested):

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 4bf28905d438..4f53520e84fd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -139,6 +139,7 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+	bool ran_once;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 83297fa97243..3045d7f609df 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -606,6 +606,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
 
 	vcpu->arch.has_run_once = true;
 
+	mutex_lock(&kvm->lock);
+	kvm->arch.ran_once = true;
+	mutex_unlock(&kvm->lock);
+
 	kvm_arm_vcpu_init_debug(vcpu);
 
 	if (likely(irqchip_in_kernel(kvm))) {
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index dfc0430d6418..95100c541244 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -959,8 +959,9 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
 		arm_pmu = entry->arm_pmu;
 		if (arm_pmu->pmu.type == pmu_id) {
 			/* Can't change PMU if filters are already in place */
-			if (kvm->arch.arm_pmu != arm_pmu &&
-			    kvm->arch.pmu_filter) {
+			if ((kvm->arch.arm_pmu != arm_pmu &&
+			     kvm->arch.pmu_filter) ||
+			    kvm->arch.ran_once) {
 				ret = -EBUSY;
 				break;
 			}
@@ -1040,6 +1041,11 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 		mutex_lock(&vcpu->kvm->lock);
 
+		if (vcpu->kvm->arch.ran_once) {
+			mutex_unlock(&vcpu->kvm->lock);
+			return -EBUSY;
+		}
+
 		if (!vcpu->kvm->arch.pmu_filter) {
 			vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
 			if (!vcpu->kvm->arch.pmu_filter) {

which should prevent both PMU or filters to be changed once a single
vcpu as run.

Thoughts?

	M.

-- 
Without deviation from the norm, progress is not possible.


From rostedt at goodmis.org  Thu Jan  6 10:18:24 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Thu, 6 Jan 2022 13:18:24 -0500
Subject: [PATCHv6 4/5] tracing: Add register read/write tracing support
In-Reply-To: <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
Message-ID: <20220106131824.073fbe5c@gandalf.local.home>

On Tue, 7 Dec 2021 12:24:48 +0530
Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:

> diff --git a/kernel/trace/trace_readwrite.c b/kernel/trace/trace_readwrite.c

This should not be in the kernel/trace directory. It should be in the
directory of something that calls it.

-- Steve


> new file mode 100644
> index 000000000000..10ebe3c9687a
> --- /dev/null
> +++ b/kernel/trace/trace_readwrite.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Register read and write tracepoints
> + *
> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +


From maz at kernel.org  Thu Jan  6 10:21:27 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 06 Jan 2022 18:21:27 +0000
Subject: [PATCH v3 0/4] KVM: arm64: Improve PMU support on heterogeneous
 systems
In-Reply-To: <Ydbbivoqo3vUxB4j@monolith.localdoman>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <87bl0xzwu1.wl-maz@kernel.org>
 <Ydbbivoqo3vUxB4j@monolith.localdoman>
Message-ID: <871r1kvi6w.wl-maz@kernel.org>

On Thu, 06 Jan 2022 12:07:38 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Thu, Dec 30, 2021 at 08:01:10PM +0000, Marc Zyngier wrote:
> > Alex,
> > 
> > On Mon, 13 Dec 2021 15:23:05 +0000,
> > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > 
> > > (CC'ing Peter Maydell in case this might be of interest to qemu)
> > > 
> > > The series can be found on a branch at [1], and the kvmtool support at [2].
> > > The kvmtool patches are also on the mailing list [3] and haven't changed
> > > since v1.
> > > 
> > > Detailed explanation of the issue and symptoms that the patches attempt to
> > > correct can be found in the cover letter for v1 [4].
> > > 
> > > A summary of the problem is that on heterogeneous systems KVM will always
> > > use the same PMU for creating the VCPU events for *all* VCPUs regardless of
> > > the physical CPU on which the VCPU is running, leading to events suddenly
> > > stopping and resuming in the guest as the VCPU thread gets migrated across
> > > different CPUs.
> > > 
> > > This series proposes to fix this behaviour by allowing the user to specify
> > > which physical PMU is used when creating the VCPU events needed for guest
> > > PMU emulation. When the PMU is set, KVM will refuse to the VCPU on a
> > > physical which is not part of the supported CPUs for the specified PMU. The
> > > restriction is that all VCPUs must use the same PMU to avoid emulating an
> > > asymmetric platform.
> > > 
> > > The default behaviour stays the same - without userspace setting the PMU,
> > > events will stop counting if the VCPU is scheduled on the wrong CPU.
> > > 
> > > Tested with a hacked version of kvmtool that does the PMU initialization
> > > from the VCPU thread as opposed to from the main thread. Tested on
> > > rockpro64 by testing what happens when all VCPUs having the same PMU, one
> > > random VCPU having a different PMU than the other VCPUs and one random VCPU
> > > not having the PMU set (each test was run 1,000 times on the little cores
> > > and 1,000 times on the big cores).
> > > 
> > > Also tested on an Altra by testing all VCPUs having the same PMU, all VCPUs
> > > not having a PMU set, and one random VCPU not having the PMU set; the VM
> > > had 64 threads in each of the tests and each test was run 10,000 times.
> > 
> > Came back to this series, and found more problems. On top of the
> > remarks I had earlier (the per-CPU data structures that really should
> > per VM, the disappearing attribute size), what happens when event
> > filters are already registered and that you set a specific PMU?
> 
> This is a good point. When I looked at how the PMU event filter works, I
> saw that KVM doesn't attempt to check that the events are actually
> implemented on the PMU, but somehow skipped over the fact that the PMU
> affects the total number of events available.

That, but also the meaning of the events. Switching PMU after
programmed event filters is really odd, as you don't know what you are
filtering anymore (unless you stick to purely architected events).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From alim.akhtar at gmail.com  Thu Jan  6 10:20:56 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Thu, 6 Jan 2022 23:50:56 +0530
Subject: [PATCH 03/24] ARM: dts: exynos: drop unused pinctrl defines in
 Exynos3250
In-Reply-To: <20211231161930.256733-4-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-4-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ51OdwYFpzz1JaqHRUi3ruwqgEkLiQCCz+Yg9ROCHSQBeQ@mail.gmail.com>

Hello Krzysztof

On Sat, Jan 1, 2022 at 10:42 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The PIN_OUT/PIN_OUT_SET/PIN_CFG defines for pin controller pin
> configuration are not used.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Thanks!
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 25 -----------------------
>  1 file changed, 25 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> index dff3c6e3aa1f..a616cb1aca29 100644
> --- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
> @@ -19,31 +19,6 @@ _pin {                                                               \
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;            \
>         }
>
> -#define PIN_OUT(_pin, _drv)                                            \
> -       _pin {                                                          \
> -               samsung,pins = #_pin;                                   \
> -               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;        \
> -               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;               \
> -               samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;            \
> -       }
> -
> -#define PIN_OUT_SET(_pin, _val, _drv)                                  \
> -       _pin {                                                          \
> -               samsung,pins = #_pin;                                   \
> -               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;        \
> -               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;               \
> -               samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;            \
> -               samsung,pin-val = <_val>;                               \
> -       }
> -
> -#define PIN_CFG(_pin, _sel, _pull, _drv)                               \
> -       _pin {                                                          \
> -               samsung,pins = #_pin;                                   \
> -               samsung,pin-function = <_sel>;                          \
> -               samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>;           \
> -               samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;            \
> -       }
> -
>  #define PIN_SLP(_pin, _mode, _pull)                                    \
>         _pin {                                                          \
>                 samsung,pins = #_pin;                                   \
> --
> 2.32.0
>


-- 
Regards,
Alim


From john.garry at huawei.com  Thu Jan  6 10:24:26 2022
From: john.garry at huawei.com (John Garry)
Date: Thu, 6 Jan 2022 18:24:26 +0000
Subject: [RFC PATCH 1/1] perf arm64: Implement --topdown with metrics
In-Reply-To: <3e8c7fb6-97aa-f84e-e594-b6eb2cb674e4@arm.com>
References: <4c375d34-bf20-496d-22fc-aed8597126e2@huawei.com>
 <20211214184240.24215-1-andrew.kilroy@arm.com>
 <20211214184240.24215-2-andrew.kilroy@arm.com>
 <CAP-5=fXJeH0ZvcHPa20N5KfLwnYSw29rpK3OrnvE0o3u-vGTLA@mail.gmail.com>
 <b1640897-10d7-c11e-4a7a-d17633916c8e@huawei.com>
 <d91a1b98-2c2b-a961-543f-d540b3c7a146@arm.com>
 <0a14914c-063d-f9ae-be49-ae9cc6aa7ff1@huawei.com>
 <3e8c7fb6-97aa-f84e-e594-b6eb2cb674e4@arm.com>
Message-ID: <4fefb1bc-49b2-bc5b-23cd-cd8fabe8c588@huawei.com>

On 06/01/2022 16:33, Andrew Kilroy wrote:
> 
> Andi requested that the json metrics be disabled on x86 in
> 
> 
> https://lore.kernel.org/linux-perf-users/12e0deef-08db-445f-4958-bcd5c3e10367 at linux.intel.com/#t 
> 
> 
> If we do that, do you still think the --topdown=<arg>? modification is 
> needed? 

Probably not. I assumed that the metricgroup solution could work for x86 
also, so now no need for this option.

> I guess it would have to report an error if someone requests 
> --topdown=json-metrics on x86.
> 

Thanks,
John


From robh at kernel.org  Thu Jan  6 10:25:09 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 12:25:09 -0600
Subject: [PATCH] dt-bindings: clock: imx5: Drop clock consumer node from
 example
Message-ID: <20220106182518.1435497-1-robh@kernel.org>

The example nodes have different sized interrupt cells which is not valid
given no interrupt-parent is specified. As provider examples don't need to
show the consumer side in the first place, just drop the consumer node.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/clock/imx5-clock.yaml | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.yaml b/Documentation/devicetree/bindings/clock/imx5-clock.yaml
index b1740d7abe68..c0e19ff92c76 100644
--- a/Documentation/devicetree/bindings/clock/imx5-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx5-clock.yaml
@@ -55,11 +55,4 @@ examples:
                      <0 72 IRQ_TYPE_LEVEL_HIGH>;
         #clock-cells = <1>;
     };
-
-    can at 53fc8000 {
-        compatible = "fsl,imx53-flexcan", "fsl,imx25-flexcan";
-        reg = <0x53fc8000 0x4000>;
-        interrupts = <82>;
-        clocks = <&clks IMX5_CLK_CAN1_IPG_GATE>, <&clks IMX5_CLK_CAN1_SERIAL_GATE>;
-        clock-names = "ipg", "per";
-    };
+...
-- 
2.32.0



From robh at kernel.org  Thu Jan  6 10:25:16 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 12:25:16 -0600
Subject: [PATCH] dt-bindings: net: stm32-dwmac: Make each example a separate
 entry
Message-ID: <20220106182518.1435497-8-robh@kernel.org>

Each independent example should be a separate entry. This allows for
'interrupts' to have different cell sizes.

The first example also has a phandle in 'interrupts', so drop the phandle.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/net/stm32-dwmac.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
index 577f4e284425..f41d5e386080 100644
--- a/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/stm32-dwmac.yaml
@@ -102,7 +102,7 @@ examples:
            compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
            reg = <0x5800a000 0x2000>;
            reg-names = "stmmaceth";
-           interrupts = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+           interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
            interrupt-names = "macirq";
            clock-names = "stmmaceth",
                      "mac-clk-tx",
@@ -121,6 +121,7 @@ examples:
            phy-mode = "rgmii";
        };
 
+  - |
     //Example 2 (MCU example)
      ethernet1: ethernet at 40028000 {
            compatible = "st,stm32-dwmac", "snps,dwmac-3.50a";
@@ -136,6 +137,7 @@ examples:
            phy-mode = "mii";
        };
 
+  - |
     //Example 3
      ethernet2: ethernet at 40027000 {
            compatible = "st,stm32-dwmac", "snps,dwmac-4.10a";
-- 
2.32.0



From robh at kernel.org  Thu Jan  6 10:25:15 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 12:25:15 -0600
Subject: [PATCH] dt-bindings: rtc: st,
 stm32-rtc: Make each example a separate entry
Message-ID: <20220106182518.1435497-7-robh@kernel.org>

Each independent example should be a separate entry. This allows for
'interrupts' to have different cell sizes.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
index 2359f541b770..764717ce1873 100644
--- a/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
+++ b/Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml
@@ -127,6 +127,7 @@ examples:
       st,syscfg = <&pwrcfg 0x00 0x100>;
     };
 
+  - |
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     #include <dt-bindings/clock/stm32mp1-clks.h>
     rtc at 5c004000 {
-- 
2.32.0



From robh at kernel.org  Thu Jan  6 10:25:17 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 12:25:17 -0600
Subject: [PATCH] spi: dt-bindings: mediatek,
 spi-mtk-nor: Fix example 'interrupts' property
Message-ID: <20220106182518.1435497-9-robh@kernel.org>

A phandle for 'interrupts' value is wrong and should be one or more numbers.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml          | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
index 7393f30535df..da43a545614f 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mtk-nor.yaml
@@ -72,7 +72,7 @@ examples:
       nor_flash: spi at 1100d000 {
         compatible = "mediatek,mt8173-nor";
         reg = <0 0x1100d000 0 0xe0>;
-        interrupts = <&spi_flash_irq>;
+        interrupts = <1>;
         clocks = <&pericfg CLK_PERI_SPI>, <&topckgen CLK_TOP_SPINFI_IFR_SEL>;
         clock-names = "spi", "sf";
         #address-cells = <1>;
@@ -84,4 +84,3 @@ examples:
         };
       };
     };
-
-- 
2.32.0



From robh at kernel.org  Thu Jan  6 10:30:36 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 12:30:36 -0600
Subject: [PATCH] dt-bindings: i2c: st,
 stm32-i2c: Make each example a separate entry
Message-ID: <20220106183037.1443931-1-robh@kernel.org>

Each independent example should be a separate entry. This allows for
'interrupts' to have different cell sizes.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
index c07289a643d8..46b62e1c9273 100644
--- a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
@@ -112,6 +112,9 @@ examples:
           clocks = <&rcc 0 149>;
       };
 
+  - |
+    #include <dt-bindings/mfd/stm32f7-rcc.h>
+    #include <dt-bindings/clock/stm32fx-clock.h>
     //Example 2 (with st,stm32f7-i2c compatible)
       i2c at 40005800 {
           compatible = "st,stm32f7-i2c";
@@ -124,6 +127,9 @@ examples:
           clocks = <&rcc 1 CLK_I2C1>;
       };
 
+  - |
+    #include <dt-bindings/mfd/stm32f7-rcc.h>
+    #include <dt-bindings/clock/stm32fx-clock.h>
     //Example 3 (with st,stm32mp15-i2c compatible on stm32mp)
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     #include <dt-bindings/clock/stm32mp1-clks.h>
-- 
2.32.0



From christophe.jaillet at wanadoo.fr  Thu Jan  6 10:35:56 2022
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Thu, 6 Jan 2022 19:35:56 +0100
Subject: [PATCH] fsi: Aspeed: Fix a potential double free
In-Reply-To: <f2ba50fd-5c6b-e905-17ed-541dcc98c6c1@roeck-us.net>
References: <2cafa0607ca171ebd00ac6c7e073b46808e24f00.1640537669.git.christophe.jaillet@wanadoo.fr>
 <YcldM9sgYdjMYMtH@kroah.com> <20220106081418.GH7674@kadam>
 <f2ba50fd-5c6b-e905-17ed-541dcc98c6c1@roeck-us.net>
Message-ID: <edd19014-3b99-fa0b-912b-e058c14401d8@wanadoo.fr>

Le 06/01/2022 ? 18:25, Guenter Roeck a ?crit?:
> On 1/6/22 12:14 AM, Dan Carpenter wrote:
>> On Mon, Dec 27, 2021 at 07:29:07AM +0100, Greg KH wrote:
>>> On Sun, Dec 26, 2021 at 05:56:02PM +0100, Christophe JAILLET wrote:
>>>> 'aspeed' is a devm_alloc'ed, so there is no need to free it 
>>>> explicitly or
>>>> there will be a double free().
>>>
>>> A struct device can never be devm_alloced for obvious reasons.? Perhaps
>>> that is the real problem here?
>>>
>>
>> I don't understand how "aspeed" is a struct device.
>>
> 
> -static void aspeed_master_release(struct device *dev)
> -{
> -??? struct fsi_master_aspeed *aspeed =
> -??????? to_fsi_master_aspeed(dev_to_fsi_master(dev));
> -
> -??? kfree(aspeed);
> -}
> 
> So "dev" is embedded in struct fsi_master, and struct fsi_master is 
> embedded
> in struct fsi_master_aspeed. Since "struct device" is embedded, the data
> structure embedding it must be released with the release function, as is 
> done
> here. The problem is indeed that the data structure is allocated with
> devm_kzalloc(), which as Greg points out must not be devm_ allocated
> (because its lifetime does not match the lifetime of devm_ allocated
> memory).

Thanks a lot for the detailed explanation.
Crystal clear for me now.

Do you want me to send a patch to remove the devm_ or will you?

CJ

> 
>> I've been working on understanding device managed memory recently for
>> Smatch.? It's really complicated.? There are a bunch of rules/heuristics
>> that I'm slowly creating to generate new warnings but I'm a long way
>> from understanding it well myself.
>>
> 
> A data structure embedding struct device must not be devm_ allocated,
> and it must be released with the release callback. Maybe there is
> a means to flag that somehow ?
> 
> Guenter
> 



From alim.akhtar at gmail.com  Thu Jan  6 10:42:22 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Fri, 7 Jan 2022 00:12:22 +0530
Subject: [PATCH 05/24] ARM: dts: exynos: override pins by label in Peach
 Pit
In-Reply-To: <20211231161930.256733-6-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231161930.256733-6-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ52LR5vA-taBHhwBXaXYciKoOVN3MaWcB3_RsNcFcnO+6w@mail.gmail.com>

Hi Krzysztof

On Sat, Jan 1, 2022 at 11:15 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Using node paths to extend or override a device tree node is error
> prone.  If there was a typo error, a new node will be created instead of
> extending the existing node.  This will lead to run-time errors that
> could be hard to detect.
>
> A mistyped label on the other hand, will cause a dtc compile error
> (during build time).
>
While it makes sense to do this, was wondering if you faced any issue
with the current implementation?

> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Feel free to add
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm/boot/dts/exynos5420-peach-pit.dts | 44 +++++++++++-----------
>  1 file changed, 22 insertions(+), 22 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> index e76fb104db19..1ae5528e9ebf 100644
> --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
> +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
> @@ -868,27 +868,26 @@ pmic_dvs_1: pmic-dvs-1 {
>         };
>  };
>
> -&pinctrl_1 {
> -       /* Adjust WiFi drive strengths lower for EMI */
> -       sd1_clk: sd1-clk {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +/* pinctrl_1 */
> +/* Adjust WiFi drive strengths lower for EMI */
> +&sd1_bus1 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_cmd: sd1-cmd {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_bus4 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus1: sd1-bus-width1 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_bus8 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus4: sd1-bus-width4 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_clk {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus8: sd1-bus-width8 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_cmd {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
>  };
>
>  &pinctrl_2 {
> @@ -907,12 +906,13 @@ pmic_dvs_3: pmic-dvs-3 {
>         };
>  };
>
> -&pinctrl_3 {
> -       /* Drive SPI lines at x2 for better integrity */
> -       spi2-bus {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +/* pinctrl_3*/
> +/* Drive SPI lines at x2 for better integrity */
> +&spi2_bus {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> +&pinctrl_3 {
>         /* Drive SPI chip select at x2 for better integrity */
>         ec_spi_cs: ec-spi-cs {
>                 samsung,pins = "gpb1-2";
> --
> 2.32.0
>


-- 
Regards,
Alim


From alim.akhtar at gmail.com  Thu Jan  6 10:44:42 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Fri, 7 Jan 2022 00:14:42 +0530
Subject: [PATCH 07/24] ARM: dts: exynos: override pins by label in Peach Pi
In-Reply-To: <20211231162207.257478-1-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162207.257478-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ51cEZ2SV=GYdjFEFFhKqp0+KxWcmA0VJx7C1z=UdFqW=Q@mail.gmail.com>

Hi Krzysztof,

On Sat, Jan 1, 2022 at 1:15 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Using node paths to extend or override a device tree node is error
> prone.  If there was a typo error, a new node will be created instead of
> extending the existing node.  This will lead to run-time errors that
> could be hard to detect.
>
> A mistyped label on the other hand, will cause a dtc compile error
> (during build time).
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm/boot/dts/exynos5800-peach-pi.dts | 33 +++++++++++------------
>  1 file changed, 16 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index 77013ee586f8..6bf3fd37fb2b 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -850,27 +850,26 @@ pmic_dvs_1: pmic-dvs-1 {
>         };
>  };
>
> -&pinctrl_1 {
> -       /* Adjust WiFi drive strengths lower for EMI */
> -       sd1_clk: sd1-clk {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +/* pinctrl_1 */
> +/* Adjust WiFi drive strengths lower for EMI */
> +&sd1_bus1 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_cmd: sd1-cmd {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_bus4 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus1: sd1-bus-width1 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_bus8 {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus4: sd1-bus-width4 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_clk {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> +};
>
> -       sd1_bus8: sd1-bus-width8 {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> +&sd1_cmd {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
>  };
>
>  &pinctrl_2 {
> --
> 2.32.0
>


-- 
Regards,
Alim


From alim.akhtar at gmail.com  Thu Jan  6 10:47:39 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Fri, 7 Jan 2022 00:17:39 +0530
Subject: [PATCH 08/24] ARM: dts: exynos: simplify PMIC DVS pin
 configuration in Peach Pi
In-Reply-To: <20211231162207.257478-2-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162207.257478-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ52PjcMD0hFQa95NHO2M5Z+Gpx4HNO14+KCsYnCffLc3JQ@mail.gmail.com>

Hi Krzysztof,

On Sat, Jan 1, 2022 at 1:15 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The pin configuration for PMIC DVS (pmic-dvs-2 and pmic-dvs-3) are
> exactly the same, so merge them.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  arch/arm/boot/dts/exynos5800-peach-pi.dts | 20 +++++++-------------
>  1 file changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> index 6bf3fd37fb2b..eca805b83816 100644
> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
> @@ -221,7 +221,7 @@ max77802: pmic at 9 {
>                 interrupts = <1 IRQ_TYPE_NONE>;
>                 pinctrl-names = "default";
>                 pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
> -                           <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
> +                           <&pmic_dvs_1>, <&pmic_dvs_2>;
>                 wakeup-source;
>                 reg = <0x9>;
>                 #clock-cells = <1>;
> @@ -874,26 +874,20 @@ &sd1_cmd {
>
>  &pinctrl_2 {
>         pmic_dvs_2: pmic-dvs-2 {
> -               samsung,pins = "gpj4-2";
> +               samsung,pins = "gpj4-2", "gpj4-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
>         };
> +};
>
> -       pmic_dvs_3: pmic-dvs-3 {
> -               samsung,pins = "gpj4-3";
> -               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
> -               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> -       };
> +/* pinctrl_3*/
> +/* Drive SPI lines at x2 for better integrity */
> +&spi2_bus {
> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
>  };
>
Maybe move this spi2_bus part to patch #07 as the commit does not
mention this change.

>  &pinctrl_3 {
> -       /* Drive SPI lines at x2 for better integrity */
> -       spi2-bus {
> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
> -       };
> -
>         /* Drive SPI chip select at x2 for better integrity */
>         ec_spi_cs: ec-spi-cs {
>                 samsung,pins = "gpb1-2";
> --
> 2.32.0
>


-- 
Regards,
Alim


From catalin.marinas at arm.com  Thu Jan  6 10:55:01 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu,  6 Jan 2022 18:55:01 +0000
Subject: [GIT PULL] arm64 updates for 5.17
Message-ID: <20220106185501.1480075-1-catalin.marinas@arm.com>

Hi Linus,

Please pull the arm64 updates for 5.17. A patch from Peter Z making
ARCH_STACKWALK independent of STACKTRACE touches x86, s390 and riscv.
The perf changes also touch kernel/events/core.c and arch/x86/events/.

I generated the diffstat manually by merging against current mainline
(75acfdb6fd92), otherwise it's all over the place since I had to merge
the arm64 for-next/fixes (based on -rc1) for a BTI fix dependency into
for-next/core (based on -rc3).

Thanks,
Catalin

The following changes since commit 35b6b28e69985eafb20b3b2c7bd6eca452b56b53:

  arm64: ftrace: add missing BTIs (2021-12-02 10:18:32 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-upstream

for you to fetch changes up to 945409a6ef442cfe5f2f14e5626d4306d53100f0:

  Merge branches 'for-next/misc', 'for-next/cache-ops-dzp', 'for-next/stacktrace', 'for-next/xor-neon', 'for-next/kasan', 'for-next/armv8_7-fp', 'for-next/atomics', 'for-next/bti', 'for-next/sve', 'for-next/kselftest' and 'for-next/kcsan', remote-tracking branch 'arm64/for-next/perf' into for-next/core (2022-01-05 18:14:32 +0000)

----------------------------------------------------------------
arm64 updates for 5.17:

- KCSAN enabled for arm64.

- Additional kselftests to exercise the syscall ABI w.r.t. SVE/FPSIMD.

- Some more SVE clean-ups and refactoring in preparation for SME support
  (scalable matrix extensions).

- BTI clean-ups (SYM_FUNC macros etc.)

- arm64 atomics clean-up and codegen improvements.

- HWCAPs for FEAT_AFP (alternate floating point behaviour) and
  FEAT_RPRESS (increased precision of reciprocal estimate and reciprocal
  square root estimate).

- Use SHA3 instructions to speed-up XOR.

- arm64 unwind code refactoring/unification.

- Avoid DC (data cache maintenance) instructions when DCZID_EL0.DZP == 1
  (potentially set by a hypervisor; user-space already does this).

- Perf updates for arm64: support for CI-700, HiSilicon PCIe PMU,
  Marvell CN10K LLC-TAD PMU, miscellaneous clean-ups.

- Other fixes and clean-ups; highlights: fix the handling of erratum
  1418040, correct the calculation of the nomap region boundaries,
  introduce io_stop_wc() mapped to the new DGH instruction (data
  gathering hint).

----------------------------------------------------------------
Ard Biesheuvel (1):
      arm64/xor: use EOR3 instructions when available

Bhaskara Budiredla (2):
      drivers: perf: Add LLC-TAD perf counter support
      dt-bindings: perf: Add YAML schemas for Marvell CN10K LLC-TAD pmu bindings

Catalin Marinas (3):
      Merge 'arm64/for-next/fixes' into for-next/bti
      arm64: Ensure that the 'bti' macro is defined where linkage.h is included
      Merge branches 'for-next/misc', 'for-next/cache-ops-dzp', 'for-next/stacktrace', 'for-next/xor-neon', 'for-next/kasan', 'for-next/armv8_7-fp', 'for-next/atomics', 'for-next/bti', 'for-next/sve', 'for-next/kselftest' and 'for-next/kcsan', remote-tracking branch 'arm64/for-next/perf' into for-next/core

D Scott Phillips (1):
      arm64: errata: Fix exec handling in erratum 1418040 workaround

Dan Carpenter (1):
      drivers: perf: marvell_cn10k: fix an IS_ERR() vs NULL check

Florian Fainelli (1):
      arm64: entry: Use SDEI event constants

Guilherme G. Piccoli (1):
      arm64: Unhash early pointer print plus improve comment

Huacai Chen (1):
      arm64: Use correct method to calculate nomap region boundaries

Jean-Philippe Brucker (2):
      dt-bindings: Add Arm SMMUv3 PMCG binding
      perf/smmuv3: Add devicetree support

Jisheng Zhang (1):
      arm64: extable: remove unused ex_handler_t definition

Joey Gouly (3):
      arm64: cpufeature: add HWCAP for FEAT_AFP
      arm64: add ID_AA64ISAR2_EL1 sys register
      arm64: cpufeature: add HWCAP for FEAT_RPRES

Kees Cook (1):
      arm64: Drop outdated links in comments

Kefeng Wang (1):
      arm64: Enable KCSAN

Madhavan T. Venkataraman (5):
      arm64: Make perf_callchain_kernel() use arch_stack_walk()
      arm64: Make __get_wchan() use arch_stack_walk()
      arm64: Make return_address() use arch_stack_walk()
      arm64: Make profile_pc() use arch_stack_walk()
      arm64: Make dump_backtrace() use arch_stack_walk()

Mark Brown (12):
      arm64/kvm: Fix bitrotted comment for SVE handling in handle_exit.c
      arm64: Add macro version of the BTI instruction
      arm64: Unconditionally override SYM_FUNC macros
      arm64: Use BTI C directly and unconditionally
      arm64/sve: Make sysctl interface for SVE reusable by SME
      arm64/sve: Generalise vector length configuration prctl() for SME
      arm64/sve: Minor clarification of ABI documentation
      kselftest/arm64: Parameterise ptrace vector length information
      kselftest/arm64: Allow signal tests to trigger from a function
      kselftest/arm64: Add a test program to exercise the syscall ABI
      arm64/fp: Add comments documenting the usage of state restore functions
      kselftest/arm64: Add pidbench for floating point syscall cases

Mark Rutland (11):
      arm64: Add comment for stack_info::kr_cur
      arm64: Mark __switch_to() as __sched
      arm64: Make some stacktrace functions private
      arm64: mm: use die_kernel_fault() in do_mem_abort()
      arm64: mm: log potential KASAN shadow alias
      arm64: atomics: format whitespace consistently
      arm64: atomics lse: define SUBs in terms of ADDs
      arm64: atomics: lse: define ANDs in terms of ANDNOTs
      arm64: atomics: lse: improve constraints for simple ops
      arm64: atomics: lse: define RETURN ops in terms of FETCH ops
      arm64: remove __dma_*_area() aliases

Peter Zijlstra (1):
      arch: Make ARCH_STACKWALK independent of STACKTRACE

Qi Liu (2):
      docs: perf: Add description for HiSilicon PCIe PMU driver
      drivers/perf: hisi: Add driver for HiSilicon PCIe PMU

Raphael Gault (1):
      Documentation: arm64: Document PMU counters access from userspace

Reiji Watanabe (2):
      arm64: clear_page() shouldn't use DC ZVA when DCZID_EL0.DZP == 1
      arm64: mte: DC {GVA,GZVA} shouldn't be used when DCZID_EL0.DZP == 1

Rob Herring (5):
      arm64: Simplify checking for populated DT
      x86: perf: Move RDPMC event flag to a common definition
      perf: Add a counter for number of user access events in context
      arm64: perf: Add userspace counter access disable switch
      arm64: perf: Enable PMU counter userspace access for perf event

Robin Murphy (17):
      perf/arm-cmn: Fix CPU hotplug unregistration
      perf/arm-cmn: Account for NUMA affinity
      perf/arm-cmn: Drop compile-test restriction
      perf/arm-cmn: Refactor node ID handling
      perf/arm-cmn: Streamline node iteration
      perf/arm-cmn: Refactor DTM handling
      perf/arm-cmn: Optimise DTM counter reads
      perf/arm-cmn: Optimise DTC counter accesses
      perf/arm-cmn: Move group validation data off-stack
      perf/arm-cmn: Demarcate CMN-600 specifics
      perf/arm-cmn: Support new IP features
      dt-bindings: perf: arm-cmn: Add CI-700
      perf/arm-cmn: Add CI-700 Support
      perf/arm-cmn: Add debugfs topology info
      perf/smmuv3: Synthesize IIDR from CoreSight ID registers
      arm64: perf: Simplify registration boilerplate
      arm64: perf: Support new DT compatibles

Rongwei Wang (1):
      arm64: kexec: reduce calls to page_address()

Thierry Reding (1):
      arm64: perf: Support Denver and Carmel PMUs

Will Deacon (8):
      Merge branch 'for-next/perf-cmn' into for-next/perf
      Merge branch 'for-next/perf-cn10k' into for-next/perf
      Merge branch 'for-next/perf-hisi' into for-next/perf
      Merge branch 'for-next/perf-smmu' into for-next/perf
      Merge branch 'for-next/perf-user-counter-access' into for-next/perf
      Merge branch 'for-next/perf-cpu' into for-next/perf
      perf/smmuv3: Fix unused variable warning when CONFIG_OF=n
      arm64: perf: Don't register user access sysctl handler multiple times

Xiongfeng Wang (1):
      asm-generic: introduce io_stop_wc() and add implementation for ARM64

Yanteng Si (1):
      docs/arm64: delete a space from tagged-address-abi

Yunfeng Ye (2):
      arm64: mm: Rename asid2idx() to ctxid2asid()
      arm64: mm: Use asid feature macro for cheanup

 Documentation/admin-guide/perf/hisi-pcie-pmu.rst   |  106 ++
 Documentation/admin-guide/sysctl/kernel.rst        |   11 +
 Documentation/arm64/cpu-feature-registers.rst      |   17 +
 Documentation/arm64/elf_hwcaps.rst                 |    8 +
 Documentation/arm64/perf.rst                       |   78 +-
 Documentation/arm64/sve.rst                        |    2 +-
 Documentation/arm64/tagged-address-abi.rst         |    2 +-
 .../devicetree/bindings/perf/arm,cmn.yaml          |   21 +-
 .../devicetree/bindings/perf/arm,smmu-v3-pmcg.yaml |   70 ++
 .../bindings/perf/marvell-cn10k-tad.yaml           |   63 ++
 Documentation/memory-barriers.txt                  |    8 +
 MAINTAINERS                                        |    2 +
 arch/arm64/Kconfig                                 |    8 +
 arch/arm64/Makefile                                |    5 +
 arch/arm64/crypto/aes-modes.S                      |   10 +-
 arch/arm64/include/asm/assembler.h                 |   10 +
 arch/arm64/include/asm/atomic_ll_sc.h              |   86 +-
 arch/arm64/include/asm/atomic_lse.h                |  270 ++---
 arch/arm64/include/asm/barrier.h                   |    9 +
 arch/arm64/include/asm/cpu.h                       |    1 +
 arch/arm64/include/asm/fpsimd.h                    |    6 +-
 arch/arm64/include/asm/hwcap.h                     |    2 +
 arch/arm64/include/asm/linkage.h                   |   35 +-
 arch/arm64/include/asm/mte-kasan.h                 |    8 +-
 arch/arm64/include/asm/stacktrace.h                |   10 +-
 arch/arm64/include/asm/sysreg.h                    |   16 +
 arch/arm64/include/uapi/asm/hwcap.h                |    2 +
 arch/arm64/kernel/acpi.c                           |   35 +-
 arch/arm64/kernel/cpufeature.c                     |   13 +
 arch/arm64/kernel/cpuinfo.c                        |    3 +
 arch/arm64/kernel/entry-ftrace.S                   |    8 +-
 arch/arm64/kernel/entry.S                          |    6 +-
 arch/arm64/kernel/fpsimd.c                         |   69 +-
 arch/arm64/kernel/hibernate.c                      |    4 -
 arch/arm64/kernel/machine_kexec.c                  |    6 +-
 arch/arm64/kernel/perf_callchain.c                 |   15 +-
 arch/arm64/kernel/perf_event.c                     |  252 +++--
 arch/arm64/kernel/process.c                        |   84 +-
 arch/arm64/kernel/ptrace.c                         |    4 +-
 arch/arm64/kernel/return_address.c                 |    8 +-
 arch/arm64/kernel/setup.c                          |   13 +-
 arch/arm64/kernel/stacktrace.c                     |   60 +-
 arch/arm64/kernel/time.c                           |   25 +-
 arch/arm64/kernel/vdso/Makefile                    |    1 +
 arch/arm64/kvm/handle_exit.c                       |    5 +-
 arch/arm64/kvm/hyp/nvhe/Makefile                   |    1 +
 arch/arm64/kvm/reset.c                             |    8 +-
 arch/arm64/kvm/sys_regs.c                          |    2 +-
 arch/arm64/lib/clear_page.S                        |   10 +
 arch/arm64/lib/kasan_sw_tags.S                     |    4 +-
 arch/arm64/lib/mte.S                               |    8 +-
 arch/arm64/lib/xor-neon.c                          |  147 ++-
 arch/arm64/mm/cache.S                              |   24 +-
 arch/arm64/mm/context.c                            |   22 +-
 arch/arm64/mm/extable.c                            |    3 -
 arch/arm64/mm/fault.c                              |    9 +-
 arch/powerpc/kernel/Makefile                       |    3 +-
 arch/riscv/kernel/stacktrace.c                     |    4 -
 arch/s390/kernel/Makefile                          |    3 +-
 arch/x86/events/core.c                             |   10 +-
 arch/x86/events/perf_event.h                       |    2 +-
 arch/x86/kernel/Makefile                           |    2 +-
 drivers/perf/Kconfig                               |    9 +-
 drivers/perf/Makefile                              |    1 +
 drivers/perf/arm-cmn.c                             | 1111 +++++++++++++-------
 drivers/perf/arm_smmuv3_pmu.c                      |   68 +-
 drivers/perf/hisilicon/Kconfig                     |    9 +
 drivers/perf/hisilicon/Makefile                    |    2 +
 drivers/perf/hisilicon/hisi_pcie_pmu.c             |  948 +++++++++++++++++
 drivers/perf/marvell_cn10k_tad_pmu.c               |  429 ++++++++
 include/asm-generic/barrier.h                      |   11 +
 include/linux/cpuhotplug.h                         |    1 +
 include/linux/perf_event.h                         |   10 +
 include/linux/stacktrace.h                         |   35 +-
 kernel/events/core.c                               |    4 +
 kernel/kcsan/Makefile                              |    1 +
 tools/testing/selftests/arm64/Makefile             |    2 +-
 tools/testing/selftests/arm64/abi/.gitignore       |    1 +
 tools/testing/selftests/arm64/abi/Makefile         |    8 +
 .../testing/selftests/arm64/abi/syscall-abi-asm.S  |  240 +++++
 tools/testing/selftests/arm64/abi/syscall-abi.c    |  318 ++++++
 tools/testing/selftests/arm64/fp/.gitignore        |    1 +
 tools/testing/selftests/arm64/fp/Makefile          |    4 +-
 tools/testing/selftests/arm64/fp/fp-pidbench.S     |   71 ++
 tools/testing/selftests/arm64/fp/sve-ptrace.c      |  219 ++--
 .../selftests/arm64/signal/test_signals_utils.c    |   12 +-
 86 files changed, 4184 insertions(+), 1070 deletions(-)


From broonie at kernel.org  Thu Jan  6 11:07:46 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 6 Jan 2022 19:07:46 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YdcxUZ06f60UQMKM@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com>
Message-ID: <Ydc+AuagOD9GSooP@sirena.org.uk>

On Thu, Jan 06, 2022 at 06:13:37PM +0000, Catalin Marinas wrote:
> On Thu, Jan 06, 2022 at 10:09:35AM -0600, Jeremy Linton wrote:

> > This should only change the behavior for for binaries which conform to the
> > new ABI containing the BTI note. So outside of the tiny window of things
> > built with BTI, but run on !BTI hardware or older kernel+glibc, this
> > shouldn't be a problem. (Unless i'm missing something) Put another way, now
> > is the time to make a change, before there is a legacy BTI ecosystem we have
> > to deal with.

> The concern is that the loader may decide in the future to not enable
> (or turn off) BTI for some reason (e.g. mixed libraries, old glibc on
> BTI hardware). If we force BTI on the main executable, we'd take this
> option away. Note also that it's not only glibc here, there are other
> loaders.

Neither of those examples should be concerns - BTI is per page so you
can mix BTI and non-BTI freely in a process (as will happen now for the
case where the dynamic loader is built for BTI but the main executable
is not, and the dynamic loader should do if there's a mix of BTI and
non-BTI libraries).  The main case where there might be a change would
be the case where there's individual excutables with incorrect BTI
annotations which are run under this seccomp MWDE, then the dynamic
loader might have support for disabling BTI based on some configuration
but wouldn't be able to due to the MWDE.

Note also that we're only taking the option of disabiling BTI away in
the case where there's something like this seccomp filter disabling
permission changes.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220106/78a343c1/attachment.sig>

From ardb at kernel.org  Thu Jan  6 11:26:45 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu,  6 Jan 2022 20:26:45 +0100
Subject: [RFT PATCH] ARM: suspend: switch to swapper_pg_dir before using the
 vmap'ed stack
Message-ID: <20220106192645.3913934-1-ardb@kernel.org>

The resume from suspend code switches to the ID map so it can enable the
MMU. On !LPAE configurations, the ID map carries its own copy of the
kernel VA range, but this is not kept in sync with swapper_pg_dir, and
so it may lack the mapping of the kernel mode stack if CONFIG_VMAP_STACK
is enabled.

So let's switch to swapper_pg_dir right after re-enabling the MMU on
such configurations. This avoids a crash on resume observed on various
platforms [0].

[0] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-8-ardb at kernel.org/

Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Geert Uytterhoeven <geert at linux-m68k.org>
Cc: Jon Hunter <jonathanh at nvidia.com>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
Please test with the Kconfig patch [9177/1] reverted.

 arch/arm/kernel/sleep.S | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index b062b3738bc6..6217ef90feb0 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
 ENDPROC(cpu_resume_mmu)
 	.popsection
 cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+	@ as the ID map does not cover the vmalloc region.
+	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
+	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
+	isb
+#endif
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
-- 
2.30.2



From madvenka at linux.microsoft.com  Thu Jan  6 12:13:27 2022
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 6 Jan 2022 14:13:27 -0600
Subject: [PATCH v12 04/10] arm64: Split unwind_init()
In-Reply-To: <YdcZYGI42h7zybqo@FVFF77S0Q05N>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-5-madvenka@linux.microsoft.com>
 <YdcZYGI42h7zybqo@FVFF77S0Q05N>
Message-ID: <5e527aab-955f-00f6-c326-3a1e3ed6fcff@linux.microsoft.com>



On 1/6/22 10:31 AM, Mark Rutland wrote:
> On Mon, Jan 03, 2022 at 10:52:06AM -0600, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> unwind_init() is currently a single function that initializes all of the
>> unwind state. Split it into the following functions and call them
>> appropriately:
>>
>> 	- unwind_init_regs() - initialize from regs passed by caller.
>>
>> 	- unwind_init_current() - initialize for the current task from the
>> 	  caller of arch_stack_walk().
>>
>> 	- unwind_init_from_task() - initialize from the saved state of a
>> 	  task other than the current task. In this case, the other
>> 	  task must not be running.
>>
>> 	- unwind_init_common() - initialize fields that are common across
>> 	  the above 3 cases.
>>
>> This is done so that specialized initialization can be added to each case
>> in the future.
>>
>> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
>> ---
>>  arch/arm64/kernel/stacktrace.c | 50 +++++++++++++++++++++++++++-------
>>  1 file changed, 40 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index a1a7ff93b84f..bd797e3f7789 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -33,11 +33,8 @@
>>   */
>>  
>>  
>> -static void unwind_init(struct unwind_state *state, unsigned long fp,
>> -			unsigned long pc)
>> +static void unwind_init_common(struct unwind_state *state)
>>  {
>> -	state->fp = fp;
>> -	state->pc = pc;
>>  #ifdef CONFIG_KRETPROBES
>>  	state->kr_cur = NULL;
>>  #endif
>> @@ -56,6 +53,40 @@ static void unwind_init(struct unwind_state *state, unsigned long fp,
>>  	state->prev_type = STACK_TYPE_UNKNOWN;
>>  }
>>  
>> +/*
>> + * TODO: document requirements here.
>> + */
>> +static inline void unwind_init_regs(struct unwind_state *state,
>> +				    struct pt_regs *regs)
>> +{
>> +	state->fp = regs->regs[29];
>> +	state->pc = regs->pc;
>> +}
> 
> When I suggested this back in:
> 
>   https://lore.kernel.org/linux-arm-kernel/20211123193723.12112-1-madvenka at linux.microsoft.com/T/#md91fbfe08ceab2a02d9f5c326e17997786e53208
> 
> ... my intent was that each unwind_init_from_*() helpers was the sole
> initializer of the structure, and the caller only had to call one function.
> That way it's not possible to construct an object with an erroneous combination
> of arguments because the prototype enforces the set of arguments, and the
> helper function can operate on a consistent snapshot of those arguments.
> 
> So I'd much prefer that each of these helpers called unwind_init_common(),
> rather than leaving that to the caller to do. I don't mind if those pass
> arguments to unwind_init_common(), or explciitly initialize their respective
> fields, but I don' think the caller should have to care about unwind_init_common().
> 
> I'd also prefer the unwind_init_from*() naming I'd previously suggested, so
> that it's clear which direction information is flowing.
> 

OK. No problem.

>>
>> +
>> +/*
>> + * TODO: document requirements here.
>> + *
>> + * Note: this is always inlined, and we expect our caller to be a noinline
>> + * function, such that this starts from our caller's caller.
>> + */
>> +static __always_inline void unwind_init_current(struct unwind_state *state)
>> +{
>> +	state->fp = (unsigned long)__builtin_frame_address(1);
>> +	state->pc = (unsigned long)__builtin_return_address(0);
>> +}
>> +
>> +/*
>> + * TODO: document requirements here.
>> + *
>> + * The caller guarantees that the task is not running.
>> + */
>> +static inline void unwind_init_task(struct unwind_state *state,
>> +				    struct task_struct *task)
>> +{
>> +	state->fp = thread_saved_fp(task);
>> +	state->pc = thread_saved_pc(task);
>> +}
>> +
>>  /*
>>   * Unwind from one frame record (A) to the next frame record (B).
>>   *
>> @@ -194,15 +225,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>>  {
>>  	struct unwind_state state;
>>  
>> +	unwind_init_common(&state);
> 
> As above, I really don't like that the caller has to call both the common
> initializer and a specialized initializer here.
> 

OK. Will change this.

Thanks.

Madhavan


From madvenka at linux.microsoft.com  Thu Jan  6 12:17:30 2022
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Thu, 6 Jan 2022 14:17:30 -0600
Subject: [PATCH v12 05/10] arm64: Copy unwind arguments to unwind_state
In-Reply-To: <Ydcax2E9u4D4/3Q9@FVFF77S0Q05N>
References: <0d0eb36f348fb5a6af6eb592c0525f6e94007328>
 <20220103165212.9303-1-madvenka@linux.microsoft.com>
 <20220103165212.9303-6-madvenka@linux.microsoft.com>
 <Ydcax2E9u4D4/3Q9@FVFF77S0Q05N>
Message-ID: <6fce7dd5-2f45-5034-bdf8-6c3a3499e9e7@linux.microsoft.com>



On 1/6/22 10:37 AM, Mark Rutland wrote:
> On Mon, Jan 03, 2022 at 10:52:07AM -0600, madvenka at linux.microsoft.com wrote:
>> From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>
>>
>> Copy the following arguments passed to arch_stack_walk() to unwind_state
>> so that they can be passed to unwind functions via unwind_state rather
>> than as separate arguments:
>>
>> 	- task
> 
> I agree the task should be placed in the unwind state, since it's a key part of
> the environment for the unwind.
> 
>> 	- regs
> 
> This isn't relevant in all cases, and so for now I'd strongly prefer *not* to
> have this in the unwind state as it's liable to lead to confusion and get
> misused.
> 
>> 	- consume_entry
>> 	- cookie
> 
> These are only relevant for the invocation of the consume_entry() function, and
> so similarly I do not think they should be part of the state. It's simpler for
> these to be local variables.
> 

OK.

>>
>> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
>> ---
>>  arch/arm64/include/asm/stacktrace.h | 12 ++++++++
>>  arch/arm64/kernel/stacktrace.c      | 45 ++++++++++++++++-------------
>>  2 files changed, 37 insertions(+), 20 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
>> index fc828c3c5dfd..322817d40a75 100644
>> --- a/arch/arm64/include/asm/stacktrace.h
>> +++ b/arch/arm64/include/asm/stacktrace.h
>> @@ -51,6 +51,14 @@ struct stack_info {
>>   * @kr_cur:      When KRETPOLINES is selected, holds the kretprobe instance
>>   *               associated with the most recently encountered replacement lr
>>   *               value.
>> + *
>> + * @task:        Pointer to the task structure.
>> + *
>> + * @regs:        Registers, if any.
>> + *
>> + * @consume_pc   Consume PC function pointer.
>> + *
>> + * @cookie       Argument to consume_pc().
>>   */
>>  struct unwind_state {
>>  	unsigned long fp;
>> @@ -61,6 +69,10 @@ struct unwind_state {
>>  #ifdef CONFIG_KRETPROBES
>>  	struct llist_node *kr_cur;
>>  #endif
>> +	struct task_struct *task;
>> +	struct pt_regs *regs;
>> +	stack_trace_consume_fn consume_pc;
>> +	void *cookie;
>>  };
>>  
>>  extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
>> diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
>> index bd797e3f7789..3ecb8242caa5 100644
>> --- a/arch/arm64/kernel/stacktrace.c
>> +++ b/arch/arm64/kernel/stacktrace.c
>> @@ -33,8 +33,17 @@
>>   */
>>  
>>  
>> -static void unwind_init_common(struct unwind_state *state)
>> +static void unwind_init_common(struct unwind_state *state,
>> +			       struct task_struct *task,
>> +			       struct pt_regs *regs,
>> +			       stack_trace_consume_fn consume_pc,
>> +			       void *cookie)
>>  {
>> +	state->task = task;
>> +	state->regs = regs;
>> +	state->consume_pc = consume_pc;
>> +	state->cookie = cookie;
>> +
>>  #ifdef CONFIG_KRETPROBES
>>  	state->kr_cur = NULL;
>>  #endif
>> @@ -56,11 +65,10 @@ static void unwind_init_common(struct unwind_state *state)
>>  /*
>>   * TODO: document requirements here.
>>   */
>> -static inline void unwind_init_regs(struct unwind_state *state,
>> -				    struct pt_regs *regs)
>> +static inline void unwind_init_regs(struct unwind_state *state)
>>  {
>> -	state->fp = regs->regs[29];
>> -	state->pc = regs->pc;
>> +	state->fp = state->regs->regs[29];
>> +	state->pc = state->regs->pc;
>>  }
>>  
>>  /*
>> @@ -80,11 +88,10 @@ static __always_inline void unwind_init_current(struct unwind_state *state)
>>   *
>>   * The caller guarantees that the task is not running.
>>   */
>> -static inline void unwind_init_task(struct unwind_state *state,
>> -				    struct task_struct *task)
>> +static inline void unwind_init_task(struct unwind_state *state)
>>  {
>> -	state->fp = thread_saved_fp(task);
>> -	state->pc = thread_saved_pc(task);
>> +	state->fp = thread_saved_fp(state->task);
>> +	state->pc = thread_saved_pc(state->task);
>>  }
>>  
>>  /*
>> @@ -94,9 +101,9 @@ static inline void unwind_init_task(struct unwind_state *state,
>>   * records (e.g. a cycle), determined based on the location and fp value of A
>>   * and the location (but not the fp value) of B.
>>   */
>> -static int notrace unwind_next(struct task_struct *tsk,
>> -			       struct unwind_state *state)
>> +static int notrace unwind_next(struct unwind_state *state)
>>  {
>> +	struct task_struct *tsk = state->task;
>>  	unsigned long fp = state->fp;
>>  	struct stack_info info;
>>  
>> @@ -170,16 +177,14 @@ static int notrace unwind_next(struct task_struct *tsk,
>>  }
>>  NOKPROBE_SYMBOL(unwind_next);
>>  
>> -static void notrace unwind(struct task_struct *tsk,
>> -			   struct unwind_state *state,
>> -			   bool (*fn)(void *, unsigned long), void *data)
>> +static void notrace unwind(struct unwind_state *state)
>>  {
>>  	while (1) {
>>  		int ret;
>>  
>> -		if (!fn(data, state->pc))
>> +		if (!state->consume_pc(state->cookie, state->pc))
>>  			break;
>> -		ret = unwind_next(tsk, state);
>> +		ret = unwind_next(state);
>>  		if (ret < 0)
>>  			break;
>>  	}
>> @@ -225,14 +230,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
>>  {
>>  	struct unwind_state state;
>>  
>> -	unwind_init_common(&state);
>> +	unwind_init_common(&state, task, regs, consume_entry, cookie);
>>  
>>  	if (regs)
>> -		unwind_init_regs(&state, regs);
>> +		unwind_init_regs(&state);
>>  	else if (task == current)
>>  		unwind_init_current(&state);
>>  	else
>> -		unwind_init_task(&state, task);
>> +		unwind_init_task(&state);
>>  
>> -	unwind(task, &state, consume_entry, cookie);
>> +	unwind(&state);
> 
> I don't like the changes here in particular since they hide the information
> flow relevant to each case.
> 

Per previous comment I agreed to, I will pass all the arguments other than task
directly.

Thanks.

Madhavan


From broonie at kernel.org  Thu Jan  6 12:28:34 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 06 Jan 2022 20:28:34 +0000
Subject: [PATCH] spi: dt-bindings: mediatek,
 spi-mtk-nor: Fix example 'interrupts' property
In-Reply-To: <20220106182518.1435497-9-robh@kernel.org>
References: <20220106182518.1435497-9-robh@kernel.org>
Message-ID: <164150091444.2243644.7719770746568612726.b4-ty@kernel.org>

On Thu, 6 Jan 2022 12:25:17 -0600, Rob Herring wrote:
> A phandle for 'interrupts' value is wrong and should be one or more numbers.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: dt-bindings: mediatek,spi-mtk-nor: Fix example 'interrupts' property
      commit: 3e718b44756e2829e7189a9504aa7a6d7f394d6c

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From mr.bossman075 at gmail.com  Thu Jan  6 13:22:40 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Thu, 6 Jan 2022 16:22:40 -0500
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220105235157.8ED80C36AEB@smtp.kernel.org>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
Message-ID: <dd4c5107-bf11-4c72-602b-597d2e3db732@gmail.com>



On 1/5/22 18:51, Stephen Boyd wrote:
> Quoting Jesse Taube (2022-01-03 15:39:46)
>> Add clock driver support for i.MXRT1050.
>>
>> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
>> Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> What is suggested by for a new driver?
Uh as far is im aware sugessed by means that he gave the idea/insight 
for this driver.
Basicly he gave me tips on what to do and how i would look into porting 
this soc. I asked him how he should be given credit this was agreed on.

https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes
> 
>> ---
>> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
>> --- a/drivers/clk/imx/Kconfig
>> +++ b/drivers/clk/imx/Kconfig
>> @@ -105,3 +105,8 @@ config CLK_IMX8ULP
>>          select MXC_CLK
>>          help
>>              Build the driver for i.MX8ULP CCM Clock Driver
>> +
>> +config CLK_IMXRT1050
>> +       bool "IMXRT1050 CCM Clock Driver"
>> +       depends on SOC_IMXRT
>> +       select MXC_CLK
> 
> Please add some help text here.
> 
Will do.
>> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
>> index b5e040026dfb..3d9a1e3b5fc6 100644
>> --- a/drivers/clk/imx/Makefile
>> +++ b/drivers/clk/imx/Makefile
>> @@ -47,3 +47,4 @@ obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
>>   obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
>>   obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
>>   obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
>> +obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o
> 
> Please keep this sorted, maybe on config symbol name?
Ah sorry this happend when I rebased I will fix it.
>> diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
>> new file mode 100644
>> index 000000000000..a2f0e8663030
>> --- /dev/null
>> +++ b/drivers/clk/imx/clk-imxrt1050.c
>> @@ -0,0 +1,181 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
>> +/*
>> + * Copyright (C) 2021
>> + * Author(s):
>> + * Jesse Taube <Mr.Bossman075 at gmail.com>
>> + * Giulio Benetti <giulio.benetti at benettiengineering.com>
>> + */
>> +#include <linux/mm.h>
>> +#include <linux/delay.h>
>> +#include <linux/clk.h>
> 
> Is this include used?
> 
>> +#include <linux/io.h>
>> +#include <linux/clkdev.h>
> 
> Drop unused includes.
> 
>> +#include <linux/clk-provider.h>
>> +#include <linux/err.h>
>> +#include <linux/of.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_irq.h>
> 
> Used?
> 
>> +#include <linux/sizes.h>
>> +#include <linux/platform_device.h>
>> +#include <soc/imx/revision.h>
> 
> Is this used?
I will sort out posibly unused includes thx for pointing it out.
>> +#include <dt-bindings/clock/imxrt1050-clock.h>
>> +
>> +#include "clk.h"
>> +
>> +static const char * const pll_ref_sels[] = {"osc", "dummy", };
>> +static const char * const per_sels[] = {"ipg_pdof", "osc", };
>> +static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
>> +static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
>> +static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
>> +static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
>> +static const char *const pre_periph_sels[] = {
>> +       "pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
>> +static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
>> +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
>> +static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
>> +static const char *const lcdif_sels[] = {
>> +       "pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
>> +       "pll2_pfd1_594m", "pll3_pfd1_664_62m", };
>> +static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
>> +static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
> 
> Any chance this can use clk_parent_data instead of string names for
> parents?
I copied this from imx8 but if nessasary I will do that.
>> +
>> +static struct clk_hw **hws;
>> +static struct clk_hw_onecell_data *clk_hw_data;
>> +
>> +static void __init imxrt_clocks_common_init(void __iomem *base)
> 
> Drop __init and preferably inline this to the callsite.
Will do.
>> +{
>> +       /* Anatop clocks */
>> +       hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
>> +
>> +       hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
>> +               base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
>> +               base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
>> +               base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
>> +               base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +
>> +       hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
>> +               "pll1_arm_ref_sel", base + 0x0, 0x7f);
>> +       hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
>> +               "pll2_sys_ref_sel", base + 0x30, 0x1);
>> +       hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
>> +               "pll3_usb_otg_ref_sel", base + 0x10, 0x1);
>> +       hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
>> +               "pll5_video_ref_sel", base + 0xa0, 0x7f);
>> +
>> +       /* PLL bypass out */
>> +       hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x0, 16, 1,
>> +               pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1,
>> +               pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1,
>> +               pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1,
>> +               pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
>> +
>> +       hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
>> +               "pll5_video", base + 0xa0, 19, 2);
>> +       hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
>> +               "video_post_div_sel", base + 0x170, 30, 2);
>> +
>> +       hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
>> +
>> +       hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", base + 0x100, 0);
>> +       hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", base + 0x100, 1);
>> +       hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", base + 0x100, 2);
>> +       hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", base + 0xf0, 1);
>> +       hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", base + 0xf0, 3);
>> +}
>> +
>> +static int imxrt1050_clocks_probe(struct platform_device *pdev)
>> +{
>> +       void __iomem *ccm_base;
>> +       void __iomem *pll_base;
>> +       struct device *dev = &pdev->dev;
>> +       struct device_node *np = dev->of_node;
>> +       struct device_node *anp;
>> +       int ret;
>> +
>> +       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
>> +                                         IMXRT1050_CLK_END), GFP_KERNEL);
>> +       if (WARN_ON(!clk_hw_data))
>> +               return -ENOMEM;
>> +
>> +       clk_hw_data->num = IMXRT1050_CLK_END;
>> +       hws = clk_hw_data->hws;
>> +
>> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> 
> Use clk_parent_data instead and reference the binding name with .fw_name
> 
>> +
>> +       anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
>> +       pll_base = of_iomap(anp, 0);
>> +       of_node_put(anp);
>> +       if (WARN_ON(!pll_base))
>> +               return -ENOMEM;
>> +       imxrt_clocks_common_init(pll_base);
>> +       /* CCM clocks */
>> +       ccm_base = devm_platform_ioremap_resource(pdev, 0);
>> +       if (WARN_ON(IS_ERR(ccm_base)))
>> +               return PTR_ERR(ccm_base);
>> +
>> +       hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
>> +       hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
>> +               pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
>> +       hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
>> +               periph_sels, ARRAY_SIZE(periph_sels));
>> +       hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
>> +               usdhc_sels, ARRAY_SIZE(usdhc_sels));
>> +       hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
>> +               usdhc_sels, ARRAY_SIZE(usdhc_sels));
>> +       hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
>> +               lpuart_sels, ARRAY_SIZE(lpuart_sels));
>> +       hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
>> +               lcdif_sels, ARRAY_SIZE(lcdif_sels));
>> +       hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
>> +               per_sels, ARRAY_SIZE(per_sels));
>> +       hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
>> +               semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
>> +       hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
>> +               semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
>> +
>> +       hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
>> +       hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
>> +       hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
>> +
>> +       hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
>> +       hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
>> +       hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
>> +       hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
>> +       hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
>> +
>> +       hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
>> +       hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
>> +       hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
>> +       hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
>> +       hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
>> +       hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
>> +       imx_check_clk_hws(hws, IMXRT1050_CLK_END);
>> +
>> +       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
>> +       if (ret < 0) {
>> +               dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
>> +               imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
>> +               return ret;
> 
> Drop return
> 
>> +       }
> 
> Newline here please
> 
>> +       return 0;
> 
> return ret;
Ah makes sence.
>> +}.
>> +static const struct of_device_id imxrt1050_clk_of_match[] = {
>> +       { .compatible = "fsl,imxrt1050-ccm" },
>> +       { /* Sentinel */ },
> 
> Drop comma please so nothing can come after without causing compile fail.
Okay makes sence, but its copied from imx8.
>> +};
>> +MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
>> +
>> +static struct platform_driver imxrt1050_clk_driver = {
>> +       .probe = imxrt1050_clocks_probe,
>> +       .driver = {
>> +               .name = "imxrt1050-ccm",
>> +               .of_match_table = imxrt1050_clk_of_match,
>> +       },
>> +};
>> +module_platform_driver(imxrt1050_clk_driver);
> 
> It's not a module though, unless the Kconfig is made into a tristate.
Ah okay will look into this.



From yuzhao at google.com  Thu Jan  6 13:27:52 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 6 Jan 2022 14:27:52 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdcTkrl84Xzg2dSz@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcTkrl84Xzg2dSz@dhcp22.suse.cz>
Message-ID: <Ydde2F4Oi0wKx//y@google.com>

On Thu, Jan 06, 2022 at 05:06:42PM +0100, Michal Hocko wrote:
> I am still reading through the series. It is a lot of code and quite
> hard to wrap ones head around so these are mostly random things I have
> run into. More will likely follow up.
> 
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> [...]
> > diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> > index aba18cd101db..028afdb81c10 100644
> > --- a/include/linux/memcontrol.h
> > +++ b/include/linux/memcontrol.h
> > @@ -1393,18 +1393,24 @@ mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
> >  
> >  static inline void lock_page_memcg(struct page *page)
> >  {
> > +	/* to match folio_memcg_rcu() */
> > +	rcu_read_lock();
> >  }
> >  
> >  static inline void unlock_page_memcg(struct page *page)
> >  {
> > +	rcu_read_unlock();
> >  }
> >  
> >  static inline void folio_memcg_lock(struct folio *folio)
> >  {
> > +	/* to match folio_memcg_rcu() */
> > +	rcu_read_lock();
> >  }
> >  
> >  static inline void folio_memcg_unlock(struct folio *folio)
> >  {
> > +	rcu_read_unlock();
> >  }
> 
> This should go into a separate patch and merge it independently. I
> haven't really realized that !MEMCG configuration has a different
> locking scopes.

Considered it done.

> > diff --git a/include/linux/oom.h b/include/linux/oom.h
> > index 2db9a1432511..9c7a4fae0661 100644
> > --- a/include/linux/oom.h
> > +++ b/include/linux/oom.h
> > @@ -57,6 +57,22 @@ struct oom_control {
> >  extern struct mutex oom_lock;
> >  extern struct mutex oom_adj_mutex;
> >  
> > +#ifdef CONFIG_MMU
> > +extern struct task_struct *oom_reaper_list;
> > +extern struct wait_queue_head oom_reaper_wait;
> > +
> > +static inline bool oom_reaping_in_progress(void)
> > +{
> > +	/* a racy check can be used to reduce the chance of overkilling */
> > +	return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait);
> > +}
> > +#else
> > +static inline bool oom_reaping_in_progress(void)
> > +{
> > +	return false;
> > +}
> > +#endif
> 
> I do not like this. These are internal oom reaper's and no code should
> really make any decisions based on that. oom_reaping_in_progress is not
> telling much anyway.

There is a perfectly legitimate reason for this.

If there is already a oom kill victim and the oom reaper is making
progress, the system may still be under memory pressure until the oom
reaping is done. The page reclaim has two choices in this transient
state: kill more processes or keep reclaiming (a few more) hot pages.

The first choice, AKA overkilling, is generally a bad one. The oom
reaper is single threaded and it can't go faster with additional
victims. Additional processes are sacrificed for nothing -- this is
an overcorrection of a system that tries to strike a balance between
the tendencies to release memory pressure and to improve memory
utilization.

> This is a global queue for oom reaper that can
> contain oom victims from different oom scopes (e.g. global OOM, memcg
> OOM or memory policy OOM).

True, but this is a wrong reason to make the conclusion below. Oom
kill scopes do NOT matter; only the pool the freed memory goes into
does. And there is only one global pool free pages.

> Your lru_gen_age_node uses this to decide whether to trigger
> out_of_memory and that is clearly wrong for the above reasons.

I hope my explanation above is clear enough. There is nothing wrong
with the purpose and the usage of oom_reaping_in_progress(), and it
has been well tested in the Arch Linux Zen kernel.

Without it, overkills can be easily reproduced by the following simple
script. That is additional oom kills happen to processes other than
"tail".

  # enable zram
  while true;
  do
      tail /dev/zero
  done

> out_of_memory is designed to skip over any action if there is an oom
> victim pending from the oom domain (have a look at oom_evaluate_task).

Where exactly? Point me to the code please.

I don't see such a logic inside out_of_memory() or
oom_evaluate_task(). Currently the only thing that could remotely
prevent overkills is oom_lock. But it's inadequate.

This is the entire pipeline:
low on memory -> out_of_memory() -> oom_reaper() -> free memory

To avoid overkills, we need to consider the later half of it too.
oom_reaping_in_progress() is exactly for this purpose.

> > +static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc,
> > +		       unsigned long min_ttl)
> > +{
> > +	bool need_aging;
> > +	long nr_to_scan;
> > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > +	int swappiness = get_swappiness(memcg);
> > +	DEFINE_MAX_SEQ(lruvec);
> > +	DEFINE_MIN_SEQ(lruvec);
> > +
> > +	if (mem_cgroup_below_min(memcg))
> > +		return false;
> 
> mem_cgroup_below_min requires effective values to be calculated for the
> reclaimed hierarchy. Have a look at mem_cgroup_calculate_protection

I always keep that in mind, and age_lruvec() is called *after*
mem_cgroup_calculate_protection():

  balance_pgdat()
    memcgs_need_aging = 0
    do {
      lru_gen_age_node()
        if (!memcgs_need_aging) {
            memcgs_need_aging = 1
            return
        }
        age_lruvec()

      shrink_node_memcgs()
        mem_cgroup_calculate_protection()
        lru_gen_shrink_lruvec()
          if ...
            memcgs_need_aging = 0
    } while ...


From yuzhao at google.com  Thu Jan  6 13:41:12 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 6 Jan 2022 14:41:12 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdcU4P+XWkbDUUoO@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz>
Message-ID: <Yddh+APQGg8dKRgw@google.com>

On Thu, Jan 06, 2022 at 05:12:16PM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > +{
> > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> > +
> > +	return current->reclaim_state->mm_walk;
> > +}
> > +
> > +static void free_mm_walk(struct lru_gen_mm_walk *walk)
> > +{
> > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > +		kvfree(walk);
> > +}
> 
> Do I get it right that you are allocating from the reclaim context? What
> prevents this to completely deplete the memory as the reclaim context is
> PF_MEMALLOC?

Yes, and in general the same reason zram/zswap/etc. allocate memory in
the reclaim context: to make more free memory.

In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
reclaimer; and direct reclaimers rarely come here, i.e., only when
kswapd can't keep up in terms of the aging, which is similar to the
condition where the inactive list is empty for the active/inactive
lru.


From daniel at iogearbox.net  Thu Jan  6 14:00:35 2022
From: daniel at iogearbox.net (Daniel Borkmann)
Date: Thu, 6 Jan 2022 23:00:35 +0100
Subject: [PATCH bpf] bpf, arm64: calculate offset as byte-offset for bpf
 line info
In-Reply-To: <20220104014236.1512639-1-houtao1@huawei.com>
References: <20220104014236.1512639-1-houtao1@huawei.com>
Message-ID: <2091c1ac-2863-cdd6-5de9-d264ab54c9be@iogearbox.net>

On 1/4/22 2:42 AM, Hou Tao wrote:
> The bpf line info for arm64 is broken due to two reasons:
> (1) insn_to_jit_off passed to bpf_prog_fill_jited_linfo() is
>      calculated in instruction granularity instead of bytes
>      granularity.
> (2) insn_to_jit_off only considers the body itself and ignores
>      prologue before the body.
> 
> So fix it by calculating offset as byte-offset and do build_prologue()
> first in the first JIT pass.
> 
> Fixes: 37ab566c178d ("bpf: arm64: Enable arm64 jit to provide bpf_line_info")
> Signed-off-by: Hou Tao <houtao1 at huawei.com>
> ---
>   arch/arm64/net/bpf_jit_comp.c | 27 +++++++++++++++++----------
>   1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index 148ca51325bb..d7a6d4b523c9 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -24,6 +24,8 @@
>   
>   #include "bpf_jit.h"
>   
> +#define INSN_SZ (sizeof(u32))
> +
>   #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
>   #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
>   #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
> @@ -154,10 +156,11 @@ static inline int bpf2a64_offset(int bpf_insn, int off,
>   	bpf_insn++;
>   	/*
>   	 * Whereas arm64 branch instructions encode the offset
> -	 * from the branch itself, so we must subtract 1 from the
> +	 * from the branch itself, so we must subtract 4 from the
>   	 * instruction offset.
>   	 */
> -	return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1);
> +	return (ctx->offset[bpf_insn + off] -
> +		(ctx->offset[bpf_insn] - INSN_SZ)) / INSN_SZ;
>   }
>   
>   static void jit_fill_hole(void *area, unsigned int size)
> @@ -955,13 +958,14 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
>   		const struct bpf_insn *insn = &prog->insnsi[i];
>   		int ret;
>   
> +		/* BPF line info needs byte-offset instead of insn-offset */
>   		if (ctx->image == NULL)
> -			ctx->offset[i] = ctx->idx;
> +			ctx->offset[i] = ctx->idx * INSN_SZ;
>   		ret = build_insn(insn, ctx, extra_pass);
>   		if (ret > 0) {
>   			i++;
>   			if (ctx->image == NULL)
> -				ctx->offset[i] = ctx->idx;
> +				ctx->offset[i] = ctx->idx * INSN_SZ;
>   			continue;
>   		}
>   		if (ret)
> @@ -973,7 +977,7 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
>   	 * instruction (end of program)
>   	 */
>   	if (ctx->image == NULL)
> -		ctx->offset[i] = ctx->idx;
> +		ctx->offset[i] = ctx->idx * INSN_SZ;
>   
>   	return 0;
>   }
> @@ -1058,15 +1062,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
>   		goto out_off;
>   	}
>   
> -	/* 1. Initial fake pass to compute ctx->idx. */
> -
> -	/* Fake pass to fill in ctx->offset. */
> -	if (build_body(&ctx, extra_pass)) {
> +	/*
> +	 * 1. Initial fake pass to compute ctx->idx and ctx->offset.
> +	 *
> +	 * BPF line info needs ctx->offset[i] to be the byte offset
> +	 * of instruction[i] in jited image, so build prologue first.
> +	 */
> +	if (build_prologue(&ctx, was_classic)) {
>   		prog = orig_prog;
>   		goto out_off;
>   	}
>   
> -	if (build_prologue(&ctx, was_classic)) {
> +	if (build_body(&ctx, extra_pass)) {
>   		prog = orig_prog;
>   		goto out_off;

Could you split this into two logical patches? Both 1/2 seem independent
of each other and should have been rather 2 patches instead of 1.

Did you check if also other JITs could be affected?

Thanks,
Daniel


From lkp at intel.com  Thu Jan  6 15:13:42 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 7 Jan 2022 07:13:42 +0800
Subject: [clk:clk-toshiba 3/4] drivers/clk/visconti/pll.c:292:20: warning:
 address of array 'ctx->clk_data.hws' will always evaluate to 'true'
Message-ID: <202201070705.HU38Acnr-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-toshiba
head:   70faf946ad975c64efb2eb809f9139f304a494b0
commit: b4cbe606dc3674b25cb661e7cd1a1c6ddaaafaaa [3/4] clk: visconti: Add support common clock driver and reset driver
config: arm64-randconfig-r003-20220106 (https://download.01.org/0day-ci/archive/20220107/202201070705.HU38Acnr-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git/commit/?id=b4cbe606dc3674b25cb661e7cd1a1c6ddaaafaaa
        git remote add clk https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git
        git fetch --no-tags clk clk-toshiba
        git checkout b4cbe606dc3674b25cb661e7cd1a1c6ddaaafaaa
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/clk/visconti/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/visconti/pll.c:292:20: warning: address of array 'ctx->clk_data.hws' will always evaluate to 'true' [-Wpointer-bool-conversion]
           if (ctx->clk_data.hws && id)
               ~~~~~~~~~~~~~~^~~ ~~
   1 warning generated.


vim +292 drivers/clk/visconti/pll.c

   287	
   288	static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx,
   289					    struct clk_hw *hw_clk,
   290					    unsigned int id)
   291	{
 > 292		if (ctx->clk_data.hws && id)
   293			ctx->clk_data.hws[id] = hw_clk;
   294	}
   295	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From bjorn.andersson at linaro.org  Thu Jan  6 15:20:58 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Thu, 6 Jan 2022 15:20:58 -0800
Subject: [PATCH v4 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <87k0fcenuw.fsf@tarshish>
References: <cover.1640587131.git.baruch@tkos.co.il>
 <a2406bf515124afad50ca3c947e2cd758c0896b1.1640587131.git.baruch@tkos.co.il>
 <20220106144518.GA15482@lpieralisi> <87k0fcenuw.fsf@tarshish>
Message-ID: <Ydd5Wh0KeADBQ/h1@ripper>

On Thu 06 Jan 10:05 PST 2022, Baruch Siach wrote:

> Hi Lorenzo,
> 
> On Thu, Jan 06 2022, Lorenzo Pieralisi wrote:
> > [+Pali - query on reset delay]
> >
> > On Mon, Dec 27, 2021 at 08:46:05AM +0200, Baruch Siach wrote:
> >> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >> 
> >> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> >> platform.
> >> 
> >> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
> >> win.linuxopenwrt.2.0).
> >> 
> >> Split out the DBI registers access part from .init into .post_init. DBI
> >> registers are only accessible after phy_power_on().
> >> 
> >> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
> >> 
> >> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> >> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> >> ---
> >> v4:
> >> 
> >>   * Rebase on v5.16-rc1
> >> 
> >> v3:
> >>   * Drop speed setup; rely on generic code (Rob Herring)
> >> 
> >>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
> >> 
> >>   * Minor formatting fixes (Bjorn Helgaas)
> >> 
> >>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
> >> 
> >> v2:
> >>   * Drop ATU configuration; rely on common code instead
> >> 
> >>   * Use more common register macros
> >> 
> >>   * Use bulk clk and reset APIs
> >> ---
> >>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
> >>  drivers/pci/controller/dwc/pcie-qcom.c       | 145 +++++++++++++++++++
> >>  2 files changed, 146 insertions(+)
> >> 
> >> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> >> index ea87809ee298..279c3778a13b 100644
> >> --- a/drivers/pci/controller/dwc/pcie-designware.h
> >> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> >> @@ -76,6 +76,7 @@
> >>  
> >>  #define GEN3_RELATED_OFF			0x890
> >>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
> >> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
> >>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
> >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
> >> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> >> index 1c3d1116bb60..14f86c45a8d9 100644
> >> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> >> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> >> @@ -52,6 +52,10 @@
> >>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
> >>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
> >>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
> >> +#define AHB_CLK_EN				BIT(0)
> >> +#define MSTR_AXI_CLK_EN				BIT(1)
> >> +#define BYPASS					BIT(4)
> >> +
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
> >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
> >>  #define PCIE20_PARF_LTSSM			0x1B0
> >> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
> >>  	struct clk *ref_clk_src;
> >>  };
> >>  
> >> +struct qcom_pcie_resources_2_9_0 {
> >> +	struct clk_bulk_data clks[5];
> >> +	struct reset_control *rst;
> >> +};
> >> +
> >>  union qcom_pcie_resources {
> >>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
> >>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
> >> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
> >>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
> >>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
> >>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
> >> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
> >>  };
> >>  
> >>  struct qcom_pcie;
> >> @@ -1297,6 +1307,127 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
> >>  	clk_disable_unprepare(res->pipe_clk);
> >>  }
> >>  
> >> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> >> +	struct dw_pcie *pci = pcie->pci;
> >> +	struct device *dev = pci->dev;
> >> +	int ret;
> >> +
> >> +	res->clks[0].id = "iface";
> >> +	res->clks[1].id = "axi_m";
> >> +	res->clks[2].id = "axi_s";
> >> +	res->clks[3].id = "axi_bridge";
> >> +	res->clks[4].id = "rchng";
> >> +
> >> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> >> +	if (ret < 0)
> >> +		return ret;
> >> +
> >> +	res->rst = devm_reset_control_array_get_exclusive(dev);
> >> +	if (IS_ERR(res->rst))
> >> +		return PTR_ERR(res->rst);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> >> +
> >> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> >> +}
> >> +
> >> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> >> +	struct device *dev = pcie->pci->dev;
> >> +	int ret;
> >> +
> >> +	ret = reset_control_assert(res->rst);
> >> +	if (ret) {
> >> +		dev_err(dev, "reset assert failed (%d)\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	usleep_range(2000, 2500);
> >> +
> >> +	ret = reset_control_deassert(res->rst);
> >> +	if (ret) {
> >> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	/*
> >> +	 * Don't have a way to see if the reset has completed.
> >> +	 * Wait for some time.
> >
> > Is this arbitrary ? What does this reset represent ?
> 
> I have no idea. I'm just porting working downstream kernel code, and I
> have no access to hardware documentation.
> 

The reset here doesn't literally reset the device, it will assert (hold)
the reset line, then sleep 2ms, then deassert (release) it and the sleep
below will ensure that we don't enable the clocks etc until the hardware
has been given 2ms to "recover".

So it's not a matter of us waiting because we don't know how to check,
it's a matter of following the datasheet stating the minimum timing of
the operations to be performed to get the PCIe controller into a known
(clean) state..


I'm slightly puzzled to why this matters if the clocks are off, but if
you're porting downstream code, my suggestion is that you should just
omit the comment.

> Note that some other variants also add delays before or after reset
> deassert:
> 
>   qcom_pcie_init_2_4_0()
> 
>   qcom_pcie_init_2_3_3()
> 
>   qcom_pcie_init_2_7_0()
> 
> baruch
> 
> >> +	 */
> >> +	usleep_range(2000, 2500);
> >> +
> >> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> >> +	if (ret)
> >> +		goto err_reset;
> >> +
> >> +	return 0;
> >> +
> >> +	/*
> >> +	 * Not checking for failure, will anyway return
> >> +	 * the original failure in 'ret'.
> >> +	 */

I think you can omit this comment as well. You failed to enable the
clocks and you want to inform the caller about that error.

Also, you're asserting the reset line to put the hardware in reset
again, if that fails there's not much to do.

Regards,
Bjorn

> >> +err_reset:
> >> +	reset_control_assert(res->rst);
> >> +
> >> +	return ret;
> >> +}
> >> +
> >> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +	struct dw_pcie *pci = pcie->pci;
> >> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> >> +	u32 val;
> >> +	int i;
> >> +
> >> +	writel(SLV_ADDR_SPACE_SZ,
> >> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> >> +
> >> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +	val &= ~BIT(0);
> >> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> >> +
> >> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> >> +
> >> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> >> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> >> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> >> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> >> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> >> +		pci->dbi_base + GEN3_RELATED_OFF);
> >> +
> >> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> >> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> >> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> >> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
> >> +
> >> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> >> +
> >> +	dw_pcie_dbi_ro_wr_en(pci);
> >> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> >> +
> >> +	/* Configure PCIe link capabilities for ASPM */
> >> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
> >> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> >> +
> >> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> >> +			PCI_EXP_DEVCTL2);
> >> +
> >> +	for (i = 0; i < 256; i++)
> >> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> >> +				+ (4 * i));
> >> +
> >> +	return 0;
> >> +}
> >> +
> >>  static int qcom_pcie_link_up(struct dw_pcie *pci)
> >>  {
> >>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> >> @@ -1487,6 +1618,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
> >>  	.config_sid = qcom_pcie_config_sid_sm8250,
> >>  };
> >>  
> >> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> >> +static const struct qcom_pcie_ops ops_2_9_0 = {
> >> +	.get_resources = qcom_pcie_get_resources_2_9_0,
> >> +	.init = qcom_pcie_init_2_9_0,
> >> +	.post_init = qcom_pcie_post_init_2_9_0,
> >> +	.deinit = qcom_pcie_deinit_2_9_0,
> >> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> >> +};
> >> +
> >>  static const struct qcom_pcie_cfg apq8084_cfg = {
> >>  	.ops = &ops_1_0_0,
> >>  };
> >> @@ -1520,6 +1660,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
> >>  	.pipe_clk_need_muxing = true,
> >>  };
> >>  
> >> +static const struct qcom_pcie_cfg ipq6018_cfg = {
> >> +	.ops = &ops_2_9_0,
> >> +};
> >> +
> >>  static const struct dw_pcie_ops dw_pcie_ops = {
> >>  	.link_up = qcom_pcie_link_up,
> >>  	.start_link = qcom_pcie_start_link,
> >> @@ -1629,6 +1773,7 @@ static const struct of_device_id qcom_pcie_match[] = {
> >>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
> >>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
> >>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
> >> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
> >>  	{ }
> >>  };
> >>  
> >> -- 
> >> 2.34.1
> >> 
> 
> 
> -- 
>                                                      ~. .~   Tk Open Systems
> =}------------------------------------------------ooO--U--Ooo------------{=
>    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From pali at kernel.org  Thu Jan  6 15:54:41 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 00:54:41 +0100
Subject: [PATCH v4 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <Ydd5Wh0KeADBQ/h1@ripper>
References: <cover.1640587131.git.baruch@tkos.co.il>
 <a2406bf515124afad50ca3c947e2cd758c0896b1.1640587131.git.baruch@tkos.co.il>
 <20220106144518.GA15482@lpieralisi> <87k0fcenuw.fsf@tarshish>
 <Ydd5Wh0KeADBQ/h1@ripper>
Message-ID: <20220106235441.xb3y6hk4jjzmnbot@pali>

On Thursday 06 January 2022 15:20:58 Bjorn Andersson wrote:
> On Thu 06 Jan 10:05 PST 2022, Baruch Siach wrote:
> 
> > Hi Lorenzo,
> > 
> > On Thu, Jan 06 2022, Lorenzo Pieralisi wrote:
> > > [+Pali - query on reset delay]
> > >
> > > On Mon, Dec 27, 2021 at 08:46:05AM +0200, Baruch Siach wrote:
> > >> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> > >> 
> > >> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> > >> platform.
> > >> 
> > >> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
> > >> win.linuxopenwrt.2.0).
> > >> 
> > >> Split out the DBI registers access part from .init into .post_init. DBI
> > >> registers are only accessible after phy_power_on().
> > >> 
> > >> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
> > >> 
> > >> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> > >> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> > >> ---
> > >> v4:
> > >> 
> > >>   * Rebase on v5.16-rc1
> > >> 
> > >> v3:
> > >>   * Drop speed setup; rely on generic code (Rob Herring)
> > >> 
> > >>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
> > >> 
> > >>   * Minor formatting fixes (Bjorn Helgaas)
> > >> 
> > >>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
> > >> 
> > >> v2:
> > >>   * Drop ATU configuration; rely on common code instead
> > >> 
> > >>   * Use more common register macros
> > >> 
> > >>   * Use bulk clk and reset APIs
> > >> ---
> > >>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
> > >>  drivers/pci/controller/dwc/pcie-qcom.c       | 145 +++++++++++++++++++
> > >>  2 files changed, 146 insertions(+)
> > >> 
> > >> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > >> index ea87809ee298..279c3778a13b 100644
> > >> --- a/drivers/pci/controller/dwc/pcie-designware.h
> > >> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > >> @@ -76,6 +76,7 @@
> > >>  
> > >>  #define GEN3_RELATED_OFF			0x890
> > >>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
> > >> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
> > >>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
> > >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
> > >>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
> > >> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> > >> index 1c3d1116bb60..14f86c45a8d9 100644
> > >> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> > >> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> > >> @@ -52,6 +52,10 @@
> > >>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
> > >>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
> > >>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
> > >> +#define AHB_CLK_EN				BIT(0)
> > >> +#define MSTR_AXI_CLK_EN				BIT(1)
> > >> +#define BYPASS					BIT(4)
> > >> +
> > >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
> > >>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
> > >>  #define PCIE20_PARF_LTSSM			0x1B0
> > >> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
> > >>  	struct clk *ref_clk_src;
> > >>  };
> > >>  
> > >> +struct qcom_pcie_resources_2_9_0 {
> > >> +	struct clk_bulk_data clks[5];
> > >> +	struct reset_control *rst;
> > >> +};
> > >> +
> > >>  union qcom_pcie_resources {
> > >>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
> > >>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
> > >> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
> > >>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
> > >>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
> > >>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
> > >> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
> > >>  };
> > >>  
> > >>  struct qcom_pcie;
> > >> @@ -1297,6 +1307,127 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
> > >>  	clk_disable_unprepare(res->pipe_clk);
> > >>  }
> > >>  
> > >> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> > >> +{
> > >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> > >> +	struct dw_pcie *pci = pcie->pci;
> > >> +	struct device *dev = pci->dev;
> > >> +	int ret;
> > >> +
> > >> +	res->clks[0].id = "iface";
> > >> +	res->clks[1].id = "axi_m";
> > >> +	res->clks[2].id = "axi_s";
> > >> +	res->clks[3].id = "axi_bridge";
> > >> +	res->clks[4].id = "rchng";
> > >> +
> > >> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> > >> +	if (ret < 0)
> > >> +		return ret;
> > >> +
> > >> +	res->rst = devm_reset_control_array_get_exclusive(dev);
> > >> +	if (IS_ERR(res->rst))
> > >> +		return PTR_ERR(res->rst);
> > >> +
> > >> +	return 0;
> > >> +}
> > >> +
> > >> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> > >> +{
> > >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> > >> +
> > >> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> > >> +}
> > >> +
> > >> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> > >> +{
> > >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> > >> +	struct device *dev = pcie->pci->dev;
> > >> +	int ret;
> > >> +
> > >> +	ret = reset_control_assert(res->rst);
> > >> +	if (ret) {
> > >> +		dev_err(dev, "reset assert failed (%d)\n", ret);
> > >> +		return ret;
> > >> +	}
> > >> +
> > >> +	usleep_range(2000, 2500);
> > >> +
> > >> +	ret = reset_control_deassert(res->rst);
> > >> +	if (ret) {
> > >> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
> > >> +		return ret;
> > >> +	}
> > >> +
> > >> +	/*
> > >> +	 * Don't have a way to see if the reset has completed.
> > >> +	 * Wait for some time.
> > >
> > > Is this arbitrary ? What does this reset represent ?
> > 
> > I have no idea. I'm just porting working downstream kernel code, and I
> > have no access to hardware documentation.
> > 
> 
> The reset here doesn't literally reset the device, it will assert (hold)
> the reset line, then sleep 2ms, then deassert (release) it and the sleep
> below will ensure that we don't enable the clocks etc until the hardware
> has been given 2ms to "recover".

Hello! What kind of reset line it asserts? Some internal line to PCIe
controller IP? Or external PCIe Reset line from PCIe controller? Or some
other?

> So it's not a matter of us waiting because we don't know how to check,
> it's a matter of following the datasheet stating the minimum timing of
> the operations to be performed to get the PCIe controller into a known
> (clean) state..

It would be really useful to put comment into code to which datasheet
you are referring and also mention the information that this datasheet
states that timeout of YXZ ms is required.

Lorenzo, added me into this discussion as we found out that lot of PCIe
controller drivers are adding "random" delays into the "random" places
and lot of them just implement required delays defined in PCIe specs.
Something which is common for evert PCIe HW. This starting to be a big
mess as every driver has to reinvent wheel and so all "sleeping code"
should be properly documented. I have an idea of moving PCIe state
machine delays from drivers to PCI core code, but such thing would
require to correctly identify them. And probably there is no better way
than putting comments, why delay is required and why it was chosen to
specific value. If you want to contribute into this idea, look at email:
https://lore.kernel.org/linux-pci/20211022183808.jdeo7vntnagqkg7g at pali/

> 
> I'm slightly puzzled to why this matters if the clocks are off, but if
> you're porting downstream code, my suggestion is that you should just
> omit the comment.
> 
> > Note that some other variants also add delays before or after reset
> > deassert:
> > 
> >   qcom_pcie_init_2_4_0()
> > 
> >   qcom_pcie_init_2_3_3()
> > 
> >   qcom_pcie_init_2_7_0()
> > 
> > baruch
> > 
> > >> +	 */
> > >> +	usleep_range(2000, 2500);
> > >> +
> > >> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> > >> +	if (ret)
> > >> +		goto err_reset;
> > >> +
> > >> +	return 0;
> > >> +
> > >> +	/*
> > >> +	 * Not checking for failure, will anyway return
> > >> +	 * the original failure in 'ret'.
> > >> +	 */
> 
> I think you can omit this comment as well. You failed to enable the
> clocks and you want to inform the caller about that error.
> 
> Also, you're asserting the reset line to put the hardware in reset
> again, if that fails there's not much to do.
> 
> Regards,
> Bjorn
> 
> > >> +err_reset:
> > >> +	reset_control_assert(res->rst);
> > >> +
> > >> +	return ret;
> > >> +}
> > >> +
> > >> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> > >> +{
> > >> +	struct dw_pcie *pci = pcie->pci;
> > >> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> > >> +	u32 val;
> > >> +	int i;
> > >> +
> > >> +	writel(SLV_ADDR_SPACE_SZ,
> > >> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> > >> +
> > >> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> > >> +	val &= ~BIT(0);
> > >> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> > >> +
> > >> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> > >> +
> > >> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> > >> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> > >> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> > >> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> > >> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> > >> +		pci->dbi_base + GEN3_RELATED_OFF);
> > >> +
> > >> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> > >> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> > >> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> > >> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
> > >> +
> > >> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> > >> +
> > >> +	dw_pcie_dbi_ro_wr_en(pci);
> > >> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
> > >> +
> > >> +	/* Configure PCIe link capabilities for ASPM */
> > >> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> > >> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
> > >> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
> > >> +
> > >> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> > >> +			PCI_EXP_DEVCTL2);
> > >> +
> > >> +	for (i = 0; i < 256; i++)
> > >> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> > >> +				+ (4 * i));
> > >> +
> > >> +	return 0;
> > >> +}
> > >> +
> > >>  static int qcom_pcie_link_up(struct dw_pcie *pci)
> > >>  {
> > >>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> > >> @@ -1487,6 +1618,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
> > >>  	.config_sid = qcom_pcie_config_sid_sm8250,
> > >>  };
> > >>  
> > >> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> > >> +static const struct qcom_pcie_ops ops_2_9_0 = {
> > >> +	.get_resources = qcom_pcie_get_resources_2_9_0,
> > >> +	.init = qcom_pcie_init_2_9_0,
> > >> +	.post_init = qcom_pcie_post_init_2_9_0,
> > >> +	.deinit = qcom_pcie_deinit_2_9_0,
> > >> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> > >> +};
> > >> +
> > >>  static const struct qcom_pcie_cfg apq8084_cfg = {
> > >>  	.ops = &ops_1_0_0,
> > >>  };
> > >> @@ -1520,6 +1660,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
> > >>  	.pipe_clk_need_muxing = true,
> > >>  };
> > >>  
> > >> +static const struct qcom_pcie_cfg ipq6018_cfg = {
> > >> +	.ops = &ops_2_9_0,
> > >> +};
> > >> +
> > >>  static const struct dw_pcie_ops dw_pcie_ops = {
> > >>  	.link_up = qcom_pcie_link_up,
> > >>  	.start_link = qcom_pcie_start_link,
> > >> @@ -1629,6 +1773,7 @@ static const struct of_device_id qcom_pcie_match[] = {
> > >>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
> > >>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
> > >>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
> > >> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
> > >>  	{ }
> > >>  };
> > >>  
> > >> -- 
> > >> 2.34.1
> > >> 
> > 
> > 
> > -- 
> >                                                      ~. .~   Tk Open Systems
> > =}------------------------------------------------ooO--U--Ooo------------{=
> >    - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From bjorn.andersson at linaro.org  Thu Jan  6 16:01:39 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Thu, 6 Jan 2022 16:01:39 -0800
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data
 Capture and Compare unit(DCC)
In-Reply-To: <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <YbzvD+FFHuDWzCtZ@yoga>
 <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
Message-ID: <YdeC456prDBG7tBA@ripper>

On Wed 05 Jan 23:57 PST 2022, Souradeep Chowdhury wrote:

> 
> On 12/18/2021 1:41 AM, Bjorn Andersson wrote:
> > On Tue 10 Aug 12:54 CDT 2021, Souradeep Chowdhury wrote:
> > 
> > > The DCC is a DMA Engine designed to capture and store data
> > > during system crash or software triggers.The DCC operates
> > Please include a space after '.'
> Ack
> > > based on user inputs via the sysfs interface.The user gives
> > > addresses as inputs and these addresses are stored in the
> > > form of linkedlists.In case of a system crash or a manual
> > I think the user configures the DCC hardware with "a sequence of
> > operations to be performed as DCC is triggered".
> > 
> > Afaict the sequence is stored just as a sequence of operations in SRAM,
> > there's no linked list involved - except in your intermediate
> > implementation.
> 
> The user just enters the addresses as input whereas the sequence of
> operations takes
> 
> place as per configuration code inside the driver. The end result is storage
> of these
> 
> addresses inside the DCC SRAM. The DCC hardware will capture the value at
> these
> 
> addresses on a crash or manual trigger by the user.
> 
> > > software trigger by the user through the sysfs interface,
> > > the dcc captures and stores the values at these addresses.
> > > This patch contains the driver which has all the methods
> > > pertaining to the sysfs interface, auxiliary functions to
> > > support all the four fundamental operations of dcc namely
> > > read, write, first read then write and loop.The probe method
> > "first read then write" is called "read/modify/write"
> Ack
> > > here instantiates all the resources necessary for dcc to
> > > operate mainly the dedicated dcc sram where it stores the
> > > values.The DCC driver can be used for debugging purposes
> > > without going for a reboot since it can perform manual
> > > triggers.
> > > 
> > > Also added the documentation for sysfs entries
> > > and explained the functionalities of each sysfs file that
> > > has been created for dcc.
> > > 
> > > The following is the justification of using sysfs interface
> > > over the other alternatives like ioctls
> > > 
> > > i) As can be seen from the sysfs attribute descriptions,
> > > most of it does basic hardware manipulations like dcc_enable,
> > > dcc_disable, config reset etc. As a result sysfs is preferred
> > > over ioctl as we just need to enter a 0 or 1.
> > > 
> > As I mentioned in our chat, using sysfs allows us to operate the
> > interface using the shell without additional tools.
> > 
> > But I don't think that it's easy to implement enable/disable/reset using
> > sysfs is a strong argument. The difficult part of this ABI is the
> > operations to manipulate the sequence of operations, so that's what you
> > need to have a solid plan for.
> 
> The sysfs interface is being used to get the addresses values entered by the
> user
> 
> and to also go for manual triggers. The sequence of operations are kept as a
> part of
> 
> fixed driver code which is called when the user enters the data.
> 

But does the hardware really just operate on "addresses values entered
by the user". Given the various types of operations: read, write,
read-modify-write and loop I get the feeling that the hardware
"executes" a series of actions.

I'm don't think the proposed sysfs interface best exposes this to the
user and I don't think that "it's easy to implement enable/disable
attributes in sysfs" is reason enough to go with that approach.

> > > ii) Existing similar debug hardwares are there for which drivers
> > > have been written using sysfs interface.One such example is the
> > > coresight-etm-trace driver.
> > Afaict the etm interface has operations to enable and disable, I don't
> > see anything that's similar to the interface for defining the sequence
> > of operations.
> 
> Here I have just drawn analogy with an existing sysfs interface. The?
> argument for
> 
> using sysfs instead of other interfaces can be as folllows
> 
> 1)
> 
> Debugfs interface is used by drivers to expose debugging information additional to
> the function they do. But the sole usage of this driver depends on the configuration
> exported through the attributes and therefore it is an ABI as suggested by Mani.
> 
> 2)
> 
> Debugfs is disabled in production so this will not give the user facility to use DCC.
> 
> 3)
> 
> As you mentioned sysfs can be used with the shell without any additional tools.
> 
> 4)
> 
> Alternatives like NETLINK has also been suggested although in this case by using
> NETLINK we won't be able to exploit most it's features like duplex connection,
> asychrony and bulk data transfers. We are not showing any stats here to the user
> as such and also sysfs is considered to be a bit more reliable.
> 

I'm not sure why netlink would preferred for this; to me sysfs is much
preferred as it allows us to use DCC from scripts etc without having to
bundle additional binaries. If we can't express the configuration
appropriately in a sysfs (debugfs would be the same) interface, I think
an ioctl interface on /dev/dcc would be a reasonable alternative.

> Please let me your thoughts regarding this.
> 
> > > A closer analog can also be the watchdog
> > > subsystems though it is ioctls based.
> > > 
> > I don't think this adds value to the argument for using a sysfs based
> > interface.
> Ack
> > 
> > > Signed-off-by: Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > ---
> > >   Documentation/ABI/testing/sysfs-driver-dcc |  114 ++
> > >   drivers/soc/qcom/Kconfig                   |    8 +
> > >   drivers/soc/qcom/Makefile                  |    1 +
> > >   drivers/soc/qcom/dcc.c                     | 1549 ++++++++++++++++++++++++++++
> > >   4 files changed, 1672 insertions(+)
> > >   create mode 100644 Documentation/ABI/testing/sysfs-driver-dcc
> > >   create mode 100644 drivers/soc/qcom/dcc.c
> > > 
> > > diff --git a/Documentation/ABI/testing/sysfs-driver-dcc b/Documentation/ABI/testing/sysfs-driver-dcc
[..]
> > > +What:           /sys/bus/platform/devices/.../rd_mod_wr
> > > +Date:           March 2021
> > > +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > +Description:
> > > +		This file is used to read the value of the register
> > > +		and then write the value given as an argument to the
> > > +		register address in config.
> > It's not clear from this description how to use this operation. E.g. is
> > it appended to the same list of operations? When will this operation
> > happen?
> > 
> > Looking at the implementation I believe that "config", "config_write",
> > "loop" and "rd_mod_wr" all appends operations to the same list.
> > 
> > I think it would be much better to configure this with a single file
> > that can either be written to '>' or appended to '>>' and you would feed
> > it a sequence of the operations to be performed.
> > 
> > That said, I'm afraid that might no longer be a sysfs attribute.
> > 
> > Something like:
> >    # echo 'r 0x80000010 0x10' > config
> >    # echo 'w 0x80000000 0xff' >> config
> >    # echo 'rmw 0x80000000 0xf 0xa' >> config
> >    # echo 'l 0x80000010 10' >> config
> > 
> > and:
> >    # cat config
> >    r 0x80000010 0x10
> >    w 0x80000000 0xff
> >    rmw 0x80000000 0xf 0xa
> >    l 0x80000010 10
> > 
> > (Or read/write/modify/loop as keywords...)
> > 
> > 
> > reset could be done by just: echo '' > config
> > 
> > This would make it quite similar to several of the files in the tracing
> > framework.
> 
> Currently this is being implemented as follows
> 
> Step 1
> 
> echo 0x80000000 > /sys/bus/platform/devices/../config
> 
> Step 2
> 
> echo 0xF 0xA > /sys/bus/platform/devices/../rd_mod_wr
> 
> So the particular address is tagged as rd_mod_wr type and therefore
> 
> while the value at the address 0x80000000 is captured, 0xA is also
> 
> written to it's last 4 bits. Will be updating this in the documentation
> 
> along with details for loop and config_write as well.
> 

But can you help me confirm what is actually written in SRAM when you
run these two steps?

> > 
> > > +		The address argument should
> > > +		be given of the form <mask> <value>.For debugging
> > > +		purposes sometimes we need to first read from a register
> > > +		and then set some values to the register.
> > > +		Example:
> > > +		echo 0x80000000 > /sys/bus/platform/devices/.../config
> > > +		(Set the address in config file)
> > > +		echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
> > > +		(Provide the mask and the value to write)
> > > +
> > > +What:           /sys/bus/platform/devices/.../ready
> > > +Date:           March 2021
> > > +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > +Description:
> > > +		This file is used to check the status of the dcc
> > > +		hardware if it's ready to take the inputs.
> > When will this read "false"?
> 
> This will give false if the DCC hardware is not in an operational state.
> 
> Will update accordingly.
> 
> > 
> > > +		Example:
> > > +		cat /sys/bus/platform/devices/.../ready
> > > +
> > > +What:		/sys/bus/platform/devices/.../curr_list
> > > +Date:		February 2021
> > > +Contact:	Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > +Description:
> > > +		This attribute is used to enter the linklist to be
> > I think it would be more appropriate to use the verb "select" here and
> > afaict it's a "list" as the "linked" part only relates to your
> > implementation).
> > 
> > But that said, I don't like this ABI. I think it would be cleaner if you
> > had specific attributes for each of the lists. That way it would be
> > clear that you have N lists and they can be configured and enabled
> > independently, and there's no possible race conditions.
> 
> So we do have attributes for independent lists in this case. The user is
> given the option
> 
> to configure multiple lists at one go. For example I can do
> 
> echo 1 > curr_list
> 
> echo 0x18000010 1 > config
> echo 0x18000024 1 > config
> 
> Then followed by
> 
> echo 2 > curr_list
> 
> echo 0x18010038 6 > config
> echo 0x18020010 1 > config
> 
> We will get the output in terms of two separate list of registers values.
> 

I understand that this will define two lists of operations and that we
will get 2 and 7 registers dumped, respectively. Perhaps unlikely, but
what happens if you try to do these two operations concurrently?


What I'm suggesting here is that if you have N contexts, you should have
N interfaces to modify each one independently - simply because that's
generally a very good thing.

> > 
> > > +		used while appending addresses.The range of values
> > > +		for this can be from 0 to 3.This feature is given in
> > > +		order to use certain linkedlist for certain debugging
> > > +		purposes.
> > > +		Example:
> > > +		echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
> > > +
[..]
> > > diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
[..]
> > > +static int dcc_valid_list(struct dcc_drvdata *drvdata, int curr_list)
> > > +{
> > > +	u32 lock_reg;
> > > +
> > > +	if (list_empty(&drvdata->cfg_head[curr_list]))
> > > +		return -EINVAL;
> > > +
> > > +	if (drvdata->enable[curr_list]) {
> > > +		dev_err(drvdata->dev, "List %d is already enabled\n",
> > > +				curr_list);
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	lock_reg = dcc_readl(drvdata, DCC_LL_LOCK(curr_list));
> > Under what circumstances would this differ from
> > drvdata->enable[curr_list}?
> 
> So locking the list is done on the register as soon as the user enters the
> curr_list entry whereas
> 
> the list is marked as enabled only on successfully programming the SRAM
> contents. So a list can
> 
> be locked and not marked enabled in certain cases. The first is used so that
> the user doesn't
> 
> mistakenly enter the same curr_list twice whereas the later is used to mark
> that the list has been
> 
> successfully configured.
> 

So this will mark the list as "actively in use, but disabled"? Why is
this kept in the hardware? When is this not the same as the list of
operations for that list being non-empty?

> > 
> > > +	if (lock_reg & 0x1) {
> > > +		dev_err(drvdata->dev, "List %d is already locked\n",
> > > +				curr_list);
> > > +		return -EINVAL;
> > > +	}
> > > +
> > > +	dev_err(drvdata->dev, "DCC list passed %d\n", curr_list);
> > This is noise, please drop it.
> Ack
> > 
> > > +	return 0;
> > > +}
> > > +
> > > +static bool is_dcc_enabled(struct dcc_drvdata *drvdata)
> > > +{
> > > +	bool dcc_enable = false;
> > > +	int list;
> > > +
> > > +	for (list = 0; list < DCC_MAX_LINK_LIST; list++) {
> > > +		if (drvdata->enable[list]) {
> > 			return true;
> > 
> > > +			dcc_enable = true;
> > > +			break;
> > > +		}
> > > +	}
> > > +
> > 	return false;
> > 
> > > +	return dcc_enable;
> > > +}
> > > +
> > > +static int dcc_enable(struct dcc_drvdata *drvdata)
> > > +{
> > > +	int ret = 0;
> > > +	int list;
> > > +	u32 ram_cfg_base;
> > > +
> > > +	mutex_lock(&drvdata->mutex);
> > > +
> > > +	if (!is_dcc_enabled(drvdata)) {
> > > +		memset_io(drvdata->ram_base,
> > > +			0xDE, drvdata->ram_size);
> > No need to wrap this line, and please use lowercase hex digits.
> Ack
> > 
> > > +	}
> > > +
> > > +	for (list = 0; list < drvdata->nr_link_list; list++) {
> > > +
> > Please drop the empty line.
> Ack
> > 
> > > +		if (dcc_valid_list(drvdata, list))
> > > +			continue;
> > > +
> > > +		/* 1. Take ownership of the list */
> > > +		dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
> > Can we have a define for BIT(0)? Is it really about ownership or just
> > that we "enable" it?
> > 
> > If ownership, who's the other contenders for the ownership?
> 
> This is done to mark that the user has already entered the curr_list and
> therefore
> 
> cannot enter it again.
> 

What does "entered" mean here? Do you mean that the list of operations
that the driver kept track of has been flushed out to SRAM and we're not
not allowed to modify it?

What does this actually mean? Why is this done in the hardware and not
simply with a bool in the driver?

> > 
> > > +
> > > +		/* 2. Program linked-list in the SRAM */
> > > +		ram_cfg_base = drvdata->ram_cfg;
> > > +		ret = __dcc_ll_cfg(drvdata, list);
> > > +		if (ret) {
> > > +			dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
> > > +			goto err;
> > > +		}
> > > +
> > > +		/* 3. program DCC_RAM_CFG reg */
> > > +		dcc_writel(drvdata, ram_cfg_base +
> > > +			drvdata->ram_offset/4, DCC_LL_BASE(list));
> > > +		dcc_writel(drvdata, drvdata->ram_start +
> > > +			drvdata->ram_offset/4, DCC_FD_BASE(list));
> > > +		dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
> > > +
> > > +		/* 4. Clears interrupt status register */
> > > +		dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
> > > +		dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
> > > +					DCC_LL_INT_STATUS(list));
> > > +
> > > +		drvdata->enable[list] = true;
> > > +
> > > +		/* 5. Configure trigger */
> > > +		dcc_writel(drvdata, BIT(9), DCC_LL_CFG(list));
> > > +	}
> > > +
> > > +err:
> > > +	mutex_unlock(&drvdata->mutex);
> > > +	return ret;
> > > +}
> > > +
> > > +static void dcc_disable(struct dcc_drvdata *drvdata)
> > > +{
> > > +	int curr_list;
> > > +
> > > +	mutex_lock(&drvdata->mutex);
> > > +
> > > +	for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
> > > +		if (!drvdata->enable[curr_list])
> > > +			continue;
> > > +		dcc_writel(drvdata, 0, DCC_LL_CFG(curr_list));
> > > +		dcc_writel(drvdata, 0, DCC_LL_BASE(curr_list));
> > > +		dcc_writel(drvdata, 0, DCC_FD_BASE(curr_list));
> > > +		dcc_writel(drvdata, 0, DCC_LL_LOCK(curr_list));
> > > +		drvdata->enable[curr_list] = false;
> > > +	}
> > > +	memset_io(drvdata->ram_base, 0, drvdata->ram_size);
> > Is there any reason why DCC is filled with 0xde during initialization
> > but 0 when disabled?
> 
> Yes this poison value is required to distinguish between bus hang on
> register accesses
> 
> and a zero value for the registers. In case of the former dcc returns zero
> value on registers
> 
> which causes ambiguity.
> 

That explains why you poison ram_base with 0xde during dcc_enable(). But
why do you overwrite it with 0s in dcc_disable()?

You should be able to either just leave it as it will be poisoned again
next time dcc_enable() is called, or if you want to ensure things are
cleared you should be able to poison it with the same poison - to
distinguish it from a bunch of read 0s?

Regards,
Bjorn


From bjorn.andersson at linaro.org  Thu Jan  6 16:05:10 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Thu, 6 Jan 2022 16:05:10 -0800
Subject: [PATCH V6 0/7] Add driver support for Data Capture and Compare
 Engine(DCC) for SM8150,SC7280,SC7180,SDM845
In-Reply-To: <705c280b-bced-476d-8e21-1a5afbf3d2f3@quicinc.com>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <396edd95-4f38-6830-99da-11e73d62a0cf@linaro.org>
 <705c280b-bced-476d-8e21-1a5afbf3d2f3@quicinc.com>
Message-ID: <YdeDtlmPRQx3FU9i@ripper>

On Thu 06 Jan 07:20 PST 2022, Souradeep Chowdhury wrote:

> 
> On 12/16/2021 9:18 PM, Thara Gopinath wrote:
> > 
> > 
> > On 8/10/21 1:54 PM, Souradeep Chowdhury wrote:
> > > DCC(Data Capture and Compare) is a DMA engine designed for debugging
> > > purposes.In case of a system
> > > crash or manual software triggers by the user the DCC hardware
> > > stores the value at the register
> > > addresses which can be used for debugging purposes.The DCC driver
> > > provides the user with sysfs
> > > interface to configure the register addresses.The options that the
> > > DCC hardware provides include
> > > reading from registers,writing to registers,first reading and then
> > > writing to registers and looping
> > > through the values of the same register.
> > > 
> > > In certain cases a register write needs to be executed for accessing
> > > the rest of the registers,
> > > also the user might want to record the changing values of a register
> > > with time for which he has the
> > > option to use the loop feature.
> > 
> > Hello Souradeep,
> > 
> > First of all, I think this is very a useful feature to have. I have some
> > generic design related queries/comments on driver and the interface
> > exposed to the user space. Also, I do not understand the h/w well here,
> > so feel free to correct me if I am wrong.
> > 
> > 1. Linked list looks like a very internal feature to the h/w. It really
> > is not an info that user should be aware of. I tried reading the code a
> > bit. IUC, every time a s/w trigger is issued the configs in all the
> > enabled linked lists are executed. The final ram dump that you get from
> > /dev/dcc_sram is a dump of contents from all the enabled list? Is this
> > understanding correct ? And we are talking of at-most 4 linked list?
> > If yes, I think it might be better to have a folder per linked list with
> > config, config_write etc. Also if possible it will be better to dump the
> > results to a file in the specific folder instead of reading from
> > /dev/dcc_sram.
> > If no, there is no real need for user to know the linked list, right?
> > Choosing of linked list can be done by kernel driver in this case with
> > no input needed from user.
> > 
> > 2. Now to the sysfs interface itself, I know lot of thought has gone
> > into sysfs vs debugfs considerations. But, have you considered using
> > netlink interface instead of sysfs. Netlink interface is used for
> > asynchronous communication between kernel and user space. In case of
> > DCC, the communication appears to be asynchronous, where in user asks
> > the kernel to capture some info and kernel can indicate back to user
> > when the info is captured. Also the entire mess surrounding echoing addr
> > / value / offset repeatedly into a sysfs entry can be avoided using
> > netlink interface.
> > 
> Hello Thara,
> 
> Thanks for your review comments. Following are some points from my end
> 
> 
> 1) Each linked list represent a particular block of memory in DCC_SRAM which
> is preserved for that particular list. That is why offset calculation is
> done on the driver based on the linked list chosen by the user.
> 
> ??? This choice needs to be made by the user since the number for the linked
> list chosen is specific to the registers used to debug a particular
> component.? Also we are giving the user flexibility to configure multiple
> 
> ??? linked lists at one go so that even if we don't have a separate folder
> for it , the dumps are collected as a separate list of registers. Also there
> are certain curr_list values which may be supported by the dcc
> 
> ??? hardware but may not be accessible to the user and so the choice cannot
> be made arbitrarily from the driver.
> 

But in the end, as you write out the SRAM content, is there really any
linked lists? Afaict it's just a sequence of operations/commands. The
linked list part seems to be your data structure of choice to keep track
of these operations in the driver before flushing them out.

Regards,
Bjorn

> 
> 2) From opensource, I can see that Netlink has been used in most of the
> cases where we need to notify stats to the user by taking the advantage of
> asynchronous communication. In this case, that requirement is not
> 
> ? ? there since it is mostly one way communication from user to kernel. Also
> since this is used for debugging purposes perhaps sysfs adds more
> reliability than Netlink. In case of Netlink we have the additional
> 
> ???? overhead of dealing with socket calls. Let me know otherwise.
> 
> 
> Thanks,
> 
> Souradeep
> 
> 
> 
> 
> 


From sboyd at kernel.org  Thu Jan  6 16:20:20 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 16:20:20 -0800
Subject: [PATCH] dt-bindings: clock: imx5: Drop clock consumer node from
 example
In-Reply-To: <20220106182518.1435497-1-robh@kernel.org>
References: <20220106182518.1435497-1-robh@kernel.org>
Message-ID: <20220107002021.A5513C36AE0@smtp.kernel.org>

Quoting Rob Herring (2022-01-06 10:25:09)
> The example nodes have different sized interrupt cells which is not valid
> given no interrupt-parent is specified. As provider examples don't need to
> show the consumer side in the first place, just drop the consumer node.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From anshuman.khandual at arm.com  Thu Jan  6 17:10:01 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:01 +0530
Subject: [PATCH V2 0/7] coresight: trbe: Workaround Cortex-A510 erratas
Message-ID: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>

	This series adds three different workarounds in the TRBE driver for
Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
part number definition in the platform. This series applies on 5.16-rc8.

Relevant errata documents can be found here.

https://developer.arm.com/documentation/SDEN2397239/900
https://developer.arm.com/documentation/SDEN2397589/900

Changes in V2:

Accommodated most review comments from the previous version.

- Split all patches into CPU errata definition, detection and TRBE workarounds
- s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
- s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
- s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
- s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
- Updated Kconfig help message for config ARM64_ERRATUM_1902691
- Updated error message for trbe_is_broken() detection
- Added new trblimitr parameter to set_trbe_enabled(), improving performance
- Added COMPILE_TEST dependency in the errata, until TRBE part is available

Changes in V1:

https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (7):
  arm64: Add Cortex-A510 CPU part definition
  arm64: errata: Add detection for TRBE ignored system register writes
  arm64: errata: Add detection for TRBE invalid prohibited states
  arm64: errata: Add detection for TRBE trace data corruption
  coresight: trbe: Work around the ignored system register writes
  coresight: trbe: Work around the invalid prohibited states
  coresight: trbe: Work around the trace data corruption

 Documentation/arm64/silicon-errata.rst       |   6 +
 arch/arm64/Kconfig                           |  59 ++++++++++
 arch/arm64/include/asm/cputype.h             |   2 +
 arch/arm64/kernel/cpu_errata.c               |  27 +++++
 arch/arm64/tools/cpucaps                     |   3 +
 drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-trbe.h |   8 --
 7 files changed, 183 insertions(+), 36 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:02 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:02 +0530
Subject: [PATCH V2 1/7] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:03 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:03 +0530
Subject: [PATCH V2 2/7] arm64: errata: Add detection for TRBE ignored system
 register writes
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-3-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected. This adds a new errata ARM64_ERRATUM_2064142
in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..c9b30e6c2b6c 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -52,6 +52,8 @@ stable kernels.
 | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..e27ccfe9fa9c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2064142
+	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
+
+	  Affected Cortex-A510 core might fail to write into system registers after the
+	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
+	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
+	  and TRBTRG_EL1 will be ignored and will not be effected.
+
+	  Work around this in the driver by executing TSB CSYNC and DSB after collection
+	  is stopped and before performing a system register write to one of the affected
+	  registers.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..cbb7d5a9aee7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2064142
+	{
+		.desc = "ARM erratum 2064142",
+		.capability = ARM64_WORKAROUND_2064142,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..fca3cb329e1d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2064142
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:04 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:04 +0530
Subject: [PATCH V2 3/7] arm64: errata: Add detection for TRBE invalid
 prohibited states
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-4-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted. This adds a new errata
ARM64_ERRATUM_2038923 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 23 +++++++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 35 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index c9b30e6c2b6c..e0ef3e9a4b8b 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e27ccfe9fa9c..188eae6ef28d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2038923
+	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
+
+	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
+	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
+	  might be corrupted. This happens after TRBE buffer has been enabled by setting
+	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
+	  execution changes from a context, in which trace is prohibited to one where it
+	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
+	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
+	  the trace buffer state might be corrupted.
+
+	  Work around this in the driver by preventing an inconsistent view of whether the
+	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
+	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
+	  two ISB instructions if no ERET is to take place.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cbb7d5a9aee7..60b0c1f1d912 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_2038923
+	{
+		.desc = "ARM erratum 2038923",
+		.capability = ARM64_WORKAROUND_2038923,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
+#endif
 	{
 	}
 };
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index fca3cb329e1d..45a06d36d080 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -56,6 +56,7 @@ WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
+WORKAROUND_2038923
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:05 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:05 +0530
Subject: [PATCH V2 4/7] arm64: errata: Add detection for TRBE trace data
 corruption
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-5-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. So effectively
TRBE is broken and hence cannot be used to capture trace data. This adds
a new errata ARM64_ERRATUM_1902691 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index e0ef3e9a4b8b..50018f60c4d4 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -56,6 +56,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #1902691        | ARM64_ERRATUM_1902691       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 188eae6ef28d..f1651cb71ef3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -819,6 +819,24 @@ config ARM64_ERRATUM_2038923
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_1902691
+	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
+
+	  Affected Cortex-A510 core might cause trace data corruption, when being written
+	  into the memory. Effectively TRBE is broken and hence cannot be used to capture
+	  trace data.
+
+	  Work around this problem in the driver by just preventing TRBE initialization on
+	  affected cpus. The firmware must have disabled the access to TRBE for the kernel
+	  on such implementations. This will cover the kernel for any firmware that doesn't
+	  do this already.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 60b0c1f1d912..a3336dfb5a8a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		/* Cortex-A510 r0p0 - r0p2 */
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1902691
+	{
+		.desc = "ARM erratum 1902691",
+		.capability = ARM64_WORKAROUND_1902691,
+
+		/* Cortex-A510 r0p0 - r0p1 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 45a06d36d080..e7719e8f18de 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -57,6 +57,7 @@ WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
 WORKAROUND_2038923
+WORKAROUND_1902691
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:06 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:06 +0530
Subject: [PATCH V2 5/7] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-6-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected.

Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
just after the trace collection has stopped and before performing a system
register write to one of the affected registers. This just updates the TRBE
driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
 drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f1651cb71ef3..b6d62672bf7d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -780,7 +780,7 @@ config ARM64_ERRATUM_2224489
 
 config ARM64_ERRATUM_2064142
 	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 276862c07e32..850e9fca6847 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -91,10 +91,12 @@ struct trbe_buf {
  */
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
+#define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
+	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
 }
 
+static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -174,30 +181,42 @@ static int trbe_alloc_node(struct perf_event *event)
 	return cpu_to_node(event->cpu);
 }
 
-static void trbe_drain_buffer(void)
+static inline void trbe_drain_buffer(void)
 {
 	tsb_csync();
 	dsb(nsh);
 }
 
-static void trbe_drain_and_disable_local(void)
+static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
-	trbe_drain_buffer();
-
 	/*
 	 * Disable the TRBE without clearing LIMITPTR which
 	 * might be required for fetching the buffer limits.
 	 */
 	trblimitr &= ~TRBLIMITR_ENABLE;
 	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/*
+	 * Errata affected TRBE implementation will need TSB CSYNC and
+	 * DSB in order to prevent subsequent writes into certain TRBE
+	 * system registers from being ignored and not effected.
+	 */
+	if (trbe_needs_drain_after_disable(cpudata))
+		trbe_drain_buffer();
 	isb();
 }
 
-static void trbe_reset_local(void)
+static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
 {
-	trbe_drain_and_disable_local();
+	trbe_drain_buffer();
+	set_trbe_disabled(cpudata);
+}
+
+static void trbe_reset_local(struct trbe_cpudata *cpudata)
+{
+	trbe_drain_and_disable_local(cpudata);
 	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
 	write_sysreg_s(0, SYS_TRBPTR_EL1);
 	write_sysreg_s(0, SYS_TRBBASER_EL1);
@@ -234,7 +253,7 @@ static void trbe_stop_and_truncate_event(struct perf_output_handle *handle)
 	 * at event_stop(). So disable the TRBE here and leave
 	 * the update_buffer() to return a 0 size.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	perf_aux_output_end(handle, 0);
 	*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
@@ -579,8 +598,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	WARN_ON(buf->trbe_hw_base < buf->trbe_base);
 	WARN_ON(buf->trbe_write < buf->trbe_hw_base);
 	WARN_ON(buf->trbe_write >= buf->trbe_limit);
-	set_trbe_disabled();
-	isb();
+	set_trbe_disabled(buf->cpudata);
 	clr_trbe_status();
 	set_trbe_base_pointer(buf->trbe_hw_base);
 	set_trbe_write_pointer(buf->trbe_write);
@@ -775,7 +793,7 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
 	 * the TRBE here will ensure that no IRQ could be generated when the perf
 	 * handle gets freed in etm_event_stop().
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 
 	/* Check if there is a pending interrupt and handle it here */
 	status = read_sysreg_s(SYS_TRBSR_EL1);
@@ -986,7 +1004,7 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 	if (cpudata->mode != CS_MODE_PERF)
 		return -EINVAL;
 
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 	buf->cpudata = NULL;
 	cpudata->buf = NULL;
 	cpudata->mode = CS_MODE_DISABLED;
@@ -1028,7 +1046,7 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
 		 * is able to detect this with a disconnected handle
 		 * (handle->event = NULL).
 		 */
-		trbe_drain_and_disable_local();
+		trbe_drain_and_disable_local(buf->cpudata);
 		*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
 		return -EINVAL;
 	}
@@ -1062,6 +1080,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 {
 	struct perf_output_handle **handle_ptr = dev;
 	struct perf_output_handle *handle = *handle_ptr;
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
 	enum trbe_fault_action act;
 	u64 status;
 	bool truncated = false;
@@ -1082,7 +1101,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 	 * Ensure the trace is visible to the CPUs and
 	 * any external aborts have been resolved.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	clr_trbe_irq();
 	isb();
 
@@ -1167,8 +1186,9 @@ static const struct attribute_group *arm_trbe_groups[] = {
 static void arm_trbe_enable_cpu(void *info)
 {
 	struct trbe_drvdata *drvdata = info;
+	struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
 
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
 }
 
@@ -1276,7 +1296,7 @@ static void arm_trbe_remove_coresight_cpu(void *info)
 	struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
 
 	disable_percpu_irq(drvdata->irq);
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	if (trbe_csdev) {
 		coresight_unregister(trbe_csdev);
 		cpudata->drvdata = NULL;
@@ -1349,8 +1369,10 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 	struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
 
 	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
+		struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+
 		disable_percpu_irq(drvdata->irq);
-		trbe_reset_local();
+		trbe_reset_local(cpudata);
 	}
 	return 0;
 }
diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h
index abf3e36082f0..30e4d7db4f8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.h
+++ b/drivers/hwtracing/coresight/coresight-trbe.h
@@ -91,14 +91,6 @@ static inline bool is_trbe_running(u64 trbsr)
 #define TRBE_FILL_MODE_WRAP		1
 #define TRBE_FILL_MODE_CIRCULAR_BUFFER	3
 
-static inline void set_trbe_disabled(void)
-{
-	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
-
-	trblimitr &= ~TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-}
-
 static inline bool get_trbe_flag_update(u64 trbidr)
 {
 	return trbidr & TRBIDR_FLAG;
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:07 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:07 +0530
Subject: [PATCH V2 6/7] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-7-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted.

Work around this problem in the TRBE driver by preventing an inconsistent
view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
immediately following a change to TRBLIMITR_EL1.E with at least one ISB
instruction before an ERET, or two ISB instructions if no ERET is to take
place. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 48 +++++++++++++++-----
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b6d62672bf7d..209e481acf0d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -798,7 +798,7 @@ config ARM64_ERRATUM_2064142
 
 config ARM64_ERRATUM_2038923
 	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 850e9fca6847..c4cc529749f8 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -92,11 +92,13 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
+#define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
+	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -174,6 +176,11 @@ static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
 }
 
+static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -187,6 +194,28 @@ static inline void trbe_drain_buffer(void)
 	dsb(nsh);
 }
 
+static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
+{
+	/*
+	 * Enable the TRBE without clearing LIMITPTR which
+	 * might be required for fetching the buffer limits.
+	 */
+	trblimitr |= TRBLIMITR_ENABLE;
+	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/* Synchronize the TRBE enable event */
+	isb();
+
+	/*
+	 * Errata affected TRBE implementation will need an additional
+	 * context synchronization in order to prevent an inconsistent
+	 * TRBE prohibited region view on the CPU which could possibly
+	 * corrupt the TRBE buffer or the TRBE state.
+	 */
+	if (trbe_needs_ctxt_sync_after_enable(cpudata))
+		isb();
+}
+
 static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
@@ -555,9 +584,10 @@ static void clr_trbe_status(void)
 	write_sysreg_s(trbsr, SYS_TRBSR_EL1);
 }
 
-static void set_trbe_limit_pointer_enabled(unsigned long addr)
+static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	unsigned long addr = buf->trbe_limit;
 
 	WARN_ON(!IS_ALIGNED(addr, (1UL << TRBLIMITR_LIMIT_SHIFT)));
 	WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
@@ -585,12 +615,7 @@ static void set_trbe_limit_pointer_enabled(unsigned long addr)
 	trblimitr |= (TRBE_TRIG_MODE_IGNORE & TRBLIMITR_TRIG_MODE_MASK) <<
 		      TRBLIMITR_TRIG_MODE_SHIFT;
 	trblimitr |= (addr & PAGE_MASK);
-
-	trblimitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-
-	/* Synchronize the TRBE enable event */
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static void trbe_enable_hw(struct trbe_buf *buf)
@@ -608,7 +633,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	 * till now before enabling the TRBE.
 	 */
 	isb();
-	set_trbe_limit_pointer_enabled(buf->trbe_limit);
+	set_trbe_limit_pointer_enabled(buf);
 }
 
 static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *handle,
@@ -1013,16 +1038,15 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 
 static void trbe_handle_spurious(struct perf_output_handle *handle)
 {
-	u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
+	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
 	/*
 	 * If the IRQ was spurious, simply re-enable the TRBE
 	 * back without modifying the buffer parameters to
 	 * retain the trace collected so far.
 	 */
-	limitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static int trbe_handle_overflow(struct perf_output_handle *handle)
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan  6 17:10:08 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri,  7 Jan 2022 06:40:08 +0530
Subject: [PATCH V2 7/7] coresight: trbe: Work around the trace data corruption
In-Reply-To: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641517808-5735-8-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. Workaround this
problem in the driver, by preventing TRBE initialization on affected cpus.
The firmware must have disabled the access to TRBE for the kernel on such
implementations. This will cover the kernel for any firmware that doesn't
do this already. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 209e481acf0d..8a2245c3e857 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -821,7 +821,7 @@ config ARM64_ERRATUM_2038923
 
 config ARM64_ERRATUM_1902691
 	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index c4cc529749f8..d2f1c68e589c 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -93,12 +93,14 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 #define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
+#define TRBE_IS_BROKEN				4
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
+	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -181,6 +183,11 @@ static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudat
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
 }
 
+static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -1288,6 +1295,11 @@ static void arm_trbe_probe_cpu(void *info)
 	 */
 	trbe_check_errata(cpudata);
 
+	if (trbe_is_broken(cpudata)) {
+		pr_err("Disabling TRBE on cpu%d due to erratum\n", cpu);
+		goto cpu_clear;
+	}
+
 	/*
 	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
 	 * we must always program the TBRPTR_EL1, 256bytes from a page
-- 
2.25.1



From linux at roeck-us.net  Thu Jan  6 17:35:10 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 6 Jan 2022 17:35:10 -0800
Subject: [PATCH] fsi: Aspeed: Fix a potential double free
In-Reply-To: <edd19014-3b99-fa0b-912b-e058c14401d8@wanadoo.fr>
References: <2cafa0607ca171ebd00ac6c7e073b46808e24f00.1640537669.git.christophe.jaillet@wanadoo.fr>
 <YcldM9sgYdjMYMtH@kroah.com> <20220106081418.GH7674@kadam>
 <f2ba50fd-5c6b-e905-17ed-541dcc98c6c1@roeck-us.net>
 <edd19014-3b99-fa0b-912b-e058c14401d8@wanadoo.fr>
Message-ID: <6926bb63-836b-b37c-3605-d6df9992bfaf@roeck-us.net>

On 1/6/22 10:35 AM, Christophe JAILLET wrote:
> Le 06/01/2022 ? 18:25, Guenter Roeck a ?crit?:
>> On 1/6/22 12:14 AM, Dan Carpenter wrote:
>>> On Mon, Dec 27, 2021 at 07:29:07AM +0100, Greg KH wrote:
>>>> On Sun, Dec 26, 2021 at 05:56:02PM +0100, Christophe JAILLET wrote:
>>>>> 'aspeed' is a devm_alloc'ed, so there is no need to free it explicitly or
>>>>> there will be a double free().
>>>>
>>>> A struct device can never be devm_alloced for obvious reasons.? Perhaps
>>>> that is the real problem here?
>>>>
>>>
>>> I don't understand how "aspeed" is a struct device.
>>>
>>
>> -static void aspeed_master_release(struct device *dev)
>> -{
>> -??? struct fsi_master_aspeed *aspeed =
>> -??????? to_fsi_master_aspeed(dev_to_fsi_master(dev));
>> -
>> -??? kfree(aspeed);
>> -}
>>
>> So "dev" is embedded in struct fsi_master, and struct fsi_master is embedded
>> in struct fsi_master_aspeed. Since "struct device" is embedded, the data
>> structure embedding it must be released with the release function, as is done
>> here. The problem is indeed that the data structure is allocated with
>> devm_kzalloc(), which as Greg points out must not be devm_ allocated
>> (because its lifetime does not match the lifetime of devm_ allocated
>> memory).
> 
> Thanks a lot for the detailed explanation.
> Crystal clear for me now.
> 
> Do you want me to send a patch to remove the devm_ or will you?
> 

Sorry, I am way behind with code reviews. I won't have time to submit a patch.

Guenter


From miles.chen at mediatek.com  Thu Jan  6 17:40:46 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 7 Jan 2022 09:40:46 +0800
Subject: [PATCH v3] drm/mediatek: Fix unused-but-set variable warning
In-Reply-To: <20220102234633.31709-1-miles.chen@mediatek.com>
References: <20220102234633.31709-1-miles.chen@mediatek.com>
Message-ID: <20220107014046.30492-1-miles.chen@mediatek.com>

Hi Matthias,

>> I'm still not happy with the commit subject, I think it is misleading. Clang 
>> only helped to find the bug, but the we are fixing something else, that's not 
>> just a clang warning. But I don't want to nit-pick too much so:
>> 
>> Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> thanks. I think you are right.
> I will change the subject to "drm/mediatek: Fix mtk_cec_mask()", remove the 
> clang part and submit patch v4.

I posted patch v4 https://lore.kernel.org/linux-mediatek/20220103054706.8072-1-miles.chen at mediatek.com/
without your reviewed-by tag.

Would you mind taking a look at the patch?

Miles


From sboyd at kernel.org  Thu Jan  6 17:46:51 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:46:51 -0800
Subject: [PATCH] clk: bm1880: remove kfrees on static allocations
In-Reply-To: <20211223154244.1024062-1-conor.dooley@microchip.com>
References: <20211223154244.1024062-1-conor.dooley@microchip.com>
Message-ID: <20220107014652.E7FB7C36AE0@smtp.kernel.org>

Quoting conor.dooley at microchip.com (2021-12-23 07:42:44)
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> bm1880_clk_unregister_pll & bm1880_clk_unregister_div both try to
> free statically allocated variables, so remove those kfrees.
> 
> For example, if we take L703 kfree(div_hw):
> - div_hw is a bm1880_div_hw_clock pointer
> - in bm1880_clk_register_plls this is pointed to an element of arg1:
>   struct bm1880_div_hw_clock *clks
> - in the probe, where bm1880_clk_register_plls is called arg1 is
>   bm1880_div_clks, defined on L371:
>   static struct bm1880_div_hw_clock bm1880_div_clks[]
> 
> Signed-off-by: Conor Dooley <conor.dooley at microchip.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 17:49:13 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:49:13 -0800
Subject: [PATCH 3/8] dt-bindings: clock: samsung: convert Exynos5433 to
 dtschema
In-Reply-To: <20220102115356.75796-3-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-3-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107014915.3B246C36AE3@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:51)
> Convert Samsung Exynos5433 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Thu Jan  6 17:49:21 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:49:21 -0800
Subject: [PATCH 4/8] dt-bindings: clock: samsung: convert Exynos7 to
 dtschema
In-Reply-To: <20220102115356.75796-4-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-4-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107014922.5FE22C36B01@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:52)
> Convert Samsung Exynos7 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Thu Jan  6 17:49:33 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:49:33 -0800
Subject: [PATCH 5/8] dt-bindings: clock: samsung: extend Exynos7 bindings
 with UFS
In-Reply-To: <20220102115356.75796-5-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-5-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107014934.7A1BAC36AE3@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:53)
> The UFS for Exynos7 SoC clock controller requires additional input
> clocks for the FSYS1 clock controller.  Update the bindings to reflect
> this, at least in theory.  In practice, these input clocks are ignored,
> so it is rather adjusting of bindings to existing DTS, without affecting
> any real users.  I understand that is not how it should be done,
> though...
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Thu Jan  6 17:49:41 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:49:41 -0800
Subject: [PATCH 6/8] dt-bindings: clock: samsung: convert Exynos5260 to
 dtschema
In-Reply-To: <20220102115356.75796-6-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-6-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107014943.2217BC36AE3@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:54)
> Convert Samsung Exynos5260 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Thu Jan  6 17:50:08 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:50:08 -0800
Subject: [PATCH 7/8] dt-bindings: clock: samsung: convert Exynos5410 to
 dtschema
In-Reply-To: <20220102115356.75796-7-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-7-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107015010.14C20C36AE3@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:55)
> Convert Samsung Exynos5410 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Thu Jan  6 17:50:31 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 17:50:31 -0800
Subject: [PATCH 8/8] dt-bindings: clock: samsung: convert S5Pv210 to
 dtschema
In-Reply-To: <20220102115356.75796-8-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-8-krzysztof.kozlowski@canonical.com>
Message-ID: <20220107015032.68DA7C36AE3@smtp.kernel.org>

Quoting Krzysztof Kozlowski (2022-01-02 03:53:56)
> Convert Samsung S5Pv210 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From pgwipeout at gmail.com  Thu Jan  6 17:22:06 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu,  6 Jan 2022 20:22:06 -0500
Subject: [PATCH 0/4] add pine64 touch panel support to rockpro64
Message-ID: <20220107012207.3779449-1-pgwipeout@gmail.com>

This patch series adds support for the Pine64 touch panel to the
rockpro64 single board computer.
This panel attaches to the dsi port and includes an i2c touch screen.

The first two patches involve making the reset pin to the Feiyang
fy07024di26a30d panel optional. On the rockpro64 and quartz64-a this pin
is tied to dvdd and automatically comes high when power is applied.
The third patch adds the device tree nodes to rockpro64 to permit the
panel to be used.
The fourth patch is an example patch to enable this support, tagged do
not merge as this is something for the end user to enable only when they
have the panel attached.

Peter Geis (4):
  dt-bindings: display: panel: feiyang,fy07024di26a30d: make reset gpio
    optional
  drm/panel: feiyang-fy07024di26a30d: make reset gpio optional
  arm64: dts: rockchip: add pine64 touch panel display to rockpro64
  arm64: dts: rockchip: enable the pine64 touch screen on rockpro64

 .../panel/feiyang,fy07024di26a30d.yaml        |  1 -
 .../boot/dts/rockchip/rk3399-rockpro64.dtsi   | 80 ++++++++++++++++++-
 .../drm/panel/panel-feiyang-fy07024di26a30d.c | 11 ++-
 3 files changed, 83 insertions(+), 9 deletions(-)

-- 
2.32.0



From kernelfans at gmail.com  Thu Jan  6 18:05:07 2022
From: kernelfans at gmail.com (Pingfan Liu)
Date: Fri,  7 Jan 2022 10:05:07 +0800
Subject: [PATCH 2/3] arm: kexec: fix the primary cpu passed to
 smp_shutdown_nonboot_cpus()
In-Reply-To: <20220107020508.9778-1-kernelfans@gmail.com>
References: <20220107020508.9778-1-kernelfans@gmail.com>
Message-ID: <20220107020508.9778-2-kernelfans@gmail.com>

kernel_kexec()->migrate_to_reboot_cpu() has already pinned the
reboot thread on either reboot_cpu or the first online cpu.

So machine_shutdown() should pass smp_processor_id() as the primary cpu
to smp_shutdown_nonboot_cpus().

Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Guenter Roeck <linux at roeck-us.net>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Wolfram Sang <wsa+renesas at sang-engineering.com>
Cc: Lee Jones <lee.jones at linaro.org>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/kernel/reboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3044fcb8d073..898405682e08 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -91,7 +91,7 @@ void soft_restart(unsigned long addr)
  */
 void machine_shutdown(void)
 {
-	smp_shutdown_nonboot_cpus(reboot_cpu);
+	smp_shutdown_nonboot_cpus(smp_processor_id());
 }
 
 /*
-- 
2.31.1



From kernelfans at gmail.com  Thu Jan  6 18:05:08 2022
From: kernelfans at gmail.com (Pingfan Liu)
Date: Fri,  7 Jan 2022 10:05:08 +0800
Subject: [PATCH 3/3] arm64: kexec: fix the primary cpu passed to
 smp_shutdown_nonboot_cpus()
In-Reply-To: <20220107020508.9778-1-kernelfans@gmail.com>
References: <20220107020508.9778-1-kernelfans@gmail.com>
Message-ID: <20220107020508.9778-3-kernelfans@gmail.com>

kernel_kexec()->migrate_to_reboot_cpu() has already pinned the
reboot thread on either reboot_cpu or the first online cpu.

So machine_shutdown() should pass smp_processor_id() as the primary cpu
to smp_shutdown_nonboot_cpus().

Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Peter Collingbourne <pcc at google.com>
Cc: Marc Zyngier <maz at kernel.org>
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/kernel/process.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index aacf2f5559a8..e1d2179ca845 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -85,7 +85,7 @@ void arch_cpu_idle_dead(void)
  */
 void machine_shutdown(void)
 {
-	smp_shutdown_nonboot_cpus(reboot_cpu);
+	smp_shutdown_nonboot_cpus(smp_processor_id());
 }
 
 /*
-- 
2.31.1



From samuel at sholland.org  Thu Jan  6 18:14:33 2022
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 6 Jan 2022 20:14:33 -0600
Subject: [PATCH] pinctrl: sunxi: Fix H616 I2S3 pin data
In-Reply-To: <20220105172952.23347-1-andre.przywara@arm.com>
References: <20220105172952.23347-1-andre.przywara@arm.com>
Message-ID: <ccc2aae8-1265-adfa-d749-1a9d54bd8443@sholland.org>

On 1/5/22 11:29 AM, Andre Przywara wrote:
> Two bugs have sneaked in the H616 pinctrl data:
> - PH9 uses the mux value of 0x3 twice (one should be 0x5 instead)
> - PH8 and PH9 use the "i2s3" function name twice in each pin
> 
> For the double pin name we use the same trick we pulled for i2s0: append
> the pin function to the group name to designate the special function.
> 
> Fixes: 25adc29407fb ("pinctrl: sunxi: Add support for the Allwinner H616 pin controller")
> Reported-by: SASANO Takayoshi <uaa at mx5.nisiq.net>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Samuel Holland <samuel at sholland.org>

Verified against the manual, which ironically also has the function numbers
wrong: it lists two function 4's (and no function 5) for each pin in port H.

> ---
>  drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
> index ce1917e230f4..152b71226a80 100644
> --- a/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
> +++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-h616.c
> @@ -363,16 +363,16 @@ static const struct sunxi_desc_pin h616_pins[] = {
>  		  SUNXI_FUNCTION(0x0, "gpio_in"),
>  		  SUNXI_FUNCTION(0x1, "gpio_out"),
>  		  SUNXI_FUNCTION(0x2, "uart2"),		/* CTS */
> -		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DO0 */
> +		  SUNXI_FUNCTION(0x3, "i2s3_dout0"),	/* DO0 */
>  		  SUNXI_FUNCTION(0x4, "spi1"),		/* MISO */
> -		  SUNXI_FUNCTION(0x5, "i2s3"),	/* DI1 */
> +		  SUNXI_FUNCTION(0x5, "i2s3_din1"),	/* DI1 */
>  		  SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 8)),	/* PH_EINT8 */
>  	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 9),
>  		  SUNXI_FUNCTION(0x0, "gpio_in"),
>  		  SUNXI_FUNCTION(0x1, "gpio_out"),
> -		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DI0 */
> +		  SUNXI_FUNCTION(0x3, "i2s3_din0"),	/* DI0 */
>  		  SUNXI_FUNCTION(0x4, "spi1"),		/* CS1 */
> -		  SUNXI_FUNCTION(0x3, "i2s3"),	/* DO1 */
> +		  SUNXI_FUNCTION(0x5, "i2s3_dout1"),	/* DO1 */
>  		  SUNXI_FUNCTION_IRQ_BANK(0x6, 6, 9)),	/* PH_EINT9 */
>  	SUNXI_PIN(SUNXI_PINCTRL_PIN(H, 10),
>  		  SUNXI_FUNCTION(0x0, "gpio_in"),
> 



From johnson.wang at mediatek.com  Thu Jan  6 18:05:27 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Fri, 7 Jan 2022 10:05:27 +0800
Subject: [PATCH 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186 SoC
In-Reply-To: <3dd41039-0151-4ee0-3940-3aceeaff17d1@collabora.com>
References: <20211230114913.9829-1-johnson.wang@mediatek.com>
 <20211230114913.9829-2-johnson.wang@mediatek.com>
 <3dd41039-0151-4ee0-3940-3aceeaff17d1@collabora.com>
Message-ID: <9ce7d166768653b70106101c9478aa290dec76a3.camel@mediatek.com>

Hi AngeloGioacchino, 

On Tue, 2022-01-04 at 10:05 +0100, AngeloGioacchino Del Regno wrote:
> Il 30/12/21 12:49, Johnson Wang ha scritto:
> > MT8186 are highly integrated SoC and use PMIC_MT6366 for
> > power management. This patch adds pwrap master driver to
> > access PMIC_MT6366.
> > 
> > Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> 
> Hello Johnson,
> thanks for the patch!
> 
> However, there's something to improve...
> 
> > ---
> >   drivers/soc/mediatek/mtk-pmic-wrap.c | 86
> > ++++++++++++++++++++++++++--
> >   1 file changed, 80 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > index 952bc554f443..4af713274468 100644
> > --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > @@ -30,6 +30,7 @@
> >   #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) &
> > 0x00000001)
> >   #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
> >   #define PWRAP_STATE_INIT_DONE0		BIT(21)
> > +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
> >   #define PWRAP_STATE_INIT_DONE1		BIT(15)
> >   
> >   /* macro for WACS FSM */
> > @@ -77,6 +78,8 @@
> >   #define PWRAP_CAP_INT1_EN	BIT(3)
> >   #define PWRAP_CAP_WDT_SRC1	BIT(4)
> >   #define PWRAP_CAP_ARB		BIT(5)
> > +#define PWRAP_CAP_MONITOR_V2	BIT(6)
> > +#define PWRAP_CAP_ARB_V2	BIT(8)
> >   
> >   /* defines for slave device wrapper registers */
> >   enum dew_regs {
> > @@ -1063,6 +1066,55 @@ static int mt8516_regs[] = {
> >   	[PWRAP_MSB_FIRST] =		0x170,
> >   };
> >   
> > +static int mt8186_regs[] = {
> > +	[PWRAP_MUX_SEL] =		0x0,
> > +	[PWRAP_WRAP_EN] =		0x4,
> > +	[PWRAP_DIO_EN] =		0x8,
> > +	[PWRAP_RDDMY] =			0x20,
> > +	[PWRAP_CSHEXT_WRITE] =		0x24,
> > +	[PWRAP_CSHEXT_READ] =		0x28,
> > +	[PWRAP_CSLEXT_WRITE] =		0x2C,
> > +	[PWRAP_CSLEXT_READ] =		0x30,
> > +	[PWRAP_EXT_CK_WRITE] =		0x34,
> > +	[PWRAP_STAUPD_CTRL] =		0x3C,
> > +	[PWRAP_STAUPD_GRPEN] =		0x40,
> > +	[PWRAP_EINT_STA0_ADR] =		0x44,
> > +	[PWRAP_EINT_STA1_ADR] =		0x48,
> > +	[PWRAP_INT_CLR] =		0xC8,
> > +	[PWRAP_INT_FLG] =		0xC4,
> > +	[PWRAP_MAN_EN] =		0x7C,
> > +	[PWRAP_MAN_CMD] =		0x80,
> > +	[PWRAP_WACS0_EN] =		0x8C,
> > +	[PWRAP_WACS1_EN] =		0x94,
> > +	[PWRAP_WACS2_EN] =		0x9C,
> > +	[PWRAP_INIT_DONE0] =		0x90,
> > +	[PWRAP_INIT_DONE1] =		0x98,
> > +	[PWRAP_INIT_DONE2] =		0xA0,
> > +	[PWRAP_INT_EN] =		0xBC,
> > +	[PWRAP_INT1_EN] =		0xCC,
> > +	[PWRAP_INT1_FLG] =		0xD4,
> > +	[PWRAP_INT1_CLR] =		0xD8,
> > +	[PWRAP_TIMER_EN] =		0xF0,
> > +	[PWRAP_WDT_UNIT] =		0xF8,
> > +	[PWRAP_WDT_SRC_EN] =		0xFC,
> > +	[PWRAP_WDT_SRC_EN_1] =		0x100,
> > +	[PWRAP_WDT_FLG] =		0x104,
> > +	[PWRAP_SPMINF_STA] =		0x1B4,
> > +	[PWRAP_DCM_EN] =		0x1EC,
> > +	[PWRAP_DCM_DBC_PRD] =		0x1F0,
> > +	[PWRAP_GPSINF_0_STA] =		0x204,
> > +	[PWRAP_GPSINF_1_STA] =		0x208,
> > +	[PWRAP_WACS0_CMD] =		0xC00,
> > +	[PWRAP_WACS0_RDATA] =		0xC04,
> > +	[PWRAP_WACS0_VLDCLR] =		0xC08,
> > +	[PWRAP_WACS1_CMD] =		0xC10,
> > +	[PWRAP_WACS1_RDATA] =		0xC14,
> > +	[PWRAP_WACS1_VLDCLR] =		0xC18,
> > +	[PWRAP_WACS2_CMD] =		0xC20,
> > +	[PWRAP_WACS2_RDATA] =		0xC24,
> > +	[PWRAP_WACS2_VLDCLR] =		0xC28,
> > +};
> > +
> >   enum pmic_type {
> >   	PMIC_MT6323,
> >   	PMIC_MT6351,
> > @@ -1083,6 +1135,7 @@ enum pwrap_type {
> >   	PWRAP_MT8135,
> >   	PWRAP_MT8173,
> >   	PWRAP_MT8183,
> > +	PWRAP_MT8186,
> >   	PWRAP_MT8195,
> >   	PWRAP_MT8516,
> >   };
> > @@ -1535,6 +1588,7 @@ static int pwrap_init_cipher(struct
> > pmic_wrapper *wrp)
> >   	case PWRAP_MT6779:
> >   	case PWRAP_MT6797:
> >   	case PWRAP_MT8173:
> > +	case PWRAP_MT8186:
> >   	case PWRAP_MT8516:
> >   		pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
> >   		break;
> > @@ -2069,6 +2123,19 @@ static struct pmic_wrapper_type pwrap_mt8516
> > = {
> >   	.init_soc_specific = NULL,
> >   };
> >   
> > +static struct pmic_wrapper_type pwrap_mt8186 = {
> > +	.regs = mt8186_regs,
> > +	.type = PWRAP_MT8186,
> > +	.arb_en_all = 0xfb27f,
> > +	.int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1
> > */
> > +	.int1_en_all =  0x000017ff, /* disable Matching interrupt for
> > bit 13 */
> > +	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
> > +	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
> > +	.caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_MONITOR_V2 |
> > PWRAP_CAP_ARB_V2,
> > +	.init_reg_clock = pwrap_common_init_reg_clock,
> > +	.init_soc_specific = NULL,
> > +};
> > +
> >   static const struct of_device_id of_pwrap_match_tbl[] = {
> >   	{
> >   		.compatible = "mediatek,mt2701-pwrap",
> > @@ -2097,6 +2164,9 @@ static const struct of_device_id
> > of_pwrap_match_tbl[] = {
> >   	}, {
> >   		.compatible = "mediatek,mt8183-pwrap",
> >   		.data = &pwrap_mt8183,
> > +	}, {
> > +		.compatible = "mediatek,mt8186-pwrap",
> > +		.data = &pwrap_mt8186,
> >   	}, {
> >   		.compatible = "mediatek,mt8195-pwrap",
> >   		.data = &pwrap_mt8195,
> > @@ -2112,7 +2182,7 @@ MODULE_DEVICE_TABLE(of, of_pwrap_match_tbl);
> >   static int pwrap_probe(struct platform_device *pdev)
> >   {
> >   	int ret, irq;
> > -	u32 mask_done;
> > +	u32 rdata;
> >   	struct pmic_wrapper *wrp;
> >   	struct device_node *np = pdev->dev.of_node;
> >   	const struct of_device_id *of_slave_id = NULL;
> > @@ -2207,12 +2277,16 @@ static int pwrap_probe(struct
> > platform_device *pdev)
> >   		}
> >   	}
> >   
> > -	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
> > -		mask_done = PWRAP_STATE_INIT_DONE1;
> > +	if (!HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
> > +		rdata = pwrap_readl(wrp, PWRAP_WACS2_RDATA) &
> > +				    PWRAP_STATE_INIT_DONE0;
> > +	else if (!HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))
> > +		rdata = pwrap_readl(wrp, PWRAP_WACS2_RDATA) &
> > +				    PWRAP_STATE_INIT_DONE0_V2;
> 
> Why are you changing the logic here?
> I think that assigning to `mask_done` is a good option, reducing
> duplication and
> also reducing the amount of changes for this patch.
> 
> That said, I would simply do it as follows:
> 
> 	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
> 
> 		mask_done = PWRAP_STATE_INIT_DONE1;
> 
> 	else if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))
> 
> 		mask_done = PWRAP_STATE_INIT_DONE0_V2;
> 
> 	else
> 
> 		mask_done = PWRAP_STATE_INIT_DONE0;
> 
> Regards,
> - Angelo

Thank for your review.
Your advice looks good to me.
It makes code more straightforward and have correct logic.
I will update it in next patch.



From stevensd at chromium.org  Thu Jan  6 18:21:15 2022
From: stevensd at chromium.org (David Stevens)
Date: Fri, 7 Jan 2022 11:21:15 +0900
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <YdcpIQgMZJrqswKU@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
 <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
 <YdcpIQgMZJrqswKU@google.com>
Message-ID: <CAD=HUj5v37wZ9NuNC4QBDvCGO2SyNG2KAiTc9Jxfg=R7neCuTw@mail.gmail.com>

> > These are the type of pages which KVM is currently rejecting. Is this
> > something that KVM can support?
>
> I'm not opposed to it.  My complaint is that this series is incomplete in that it
> allows mapping the memory into the guest, but doesn't support accessing the memory
> from KVM itself.  That means for things to work properly, KVM is relying on the
> guest to use the memory in a limited capacity, e.g. isn't using the memory as
> general purpose RAM.  That's not problematic for your use case, because presumably
> the memory is used only by the vGPU, but as is KVM can't enforce that behavior in
> any way.
>
> The really gross part is that failures are not strictly punted to userspace;
> the resulting error varies significantly depending on how the guest "illegally"
> uses the memory.
>
> My first choice would be to get the amdgpu driver "fixed", but that's likely an
> unreasonable request since it sounds like the non-KVM behavior is working as intended.
>
> One thought would be to require userspace to opt-in to mapping this type of memory
> by introducing a new memslot flag that explicitly states that the memslot cannot
> be accessed directly by KVM, i.e. can only be mapped into the guest.  That way,
> KVM has an explicit ABI with respect to how it handles this type of memory, even
> though the semantics of exactly what will happen if userspace/guest violates the
> ABI are not well-defined.  And internally, KVM would also have a clear touchpoint
> where it deliberately allows mapping such memslots, as opposed to the more implicit
> behavior of bypassing ensure_pfn_ref().

Is it well defined when KVM needs to directly access a memslot? At
least for x86, it looks like most of the use cases are related to
nested virtualization, except for the call in
emulator_cmpxchg_emulated. Without being able to specifically state
what should be avoided, a flag like that would be difficult for
userspace to use.

> If we're clever, we might even be able to share the flag with the "guest private
> memory"[*] concept being pursued for confidential VMs.
>
> [*] https://lore.kernel.org/all/20211223123011.41044-1-chao.p.peng at linux.intel.com


From leoyang.li at nxp.com  Thu Jan  6 18:22:15 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 7 Jan 2022 10:22:15 +0800
Subject: [PATCH] soc: fsl: qe: Check of ioremap return value
In-Reply-To: <20211230014543.1799867-1-jiasheng@iscas.ac.cn>
References: <20211230014543.1799867-1-jiasheng@iscas.ac.cn>
Message-ID: <CADRPPNSsLYzv6ueSqVu4b3yep7JYLJBJcNwbiBVG61ADyqaPBw@mail.gmail.com>

On Thu, Dec 30, 2021 at 9:47 AM Jiasheng Jiang <jiasheng at iscas.ac.cn> wrote:
>
> As the possible failure of the ioremap(), the par_io could be NULL.
> Therefore it should be better to check it and return error in order to
> guarantee the success of the initiation.
> But, I also notice that all the caller like mpc85xx_qe_par_io_init() in
> `arch/powerpc/platforms/85xx/common.c` don't check the return value of
> the par_io_init().
> Actually, par_io_init() needs to check to handle the potential error.
> I will submit another patch to fix that.
> Anyway, par_io_init() itsely should be fixed.
>
> Fixes: 7aa1aa6ecec2 ("QE: Move QE from arch/powerpc to drivers/soc")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>

Applied for next.  Thanks.

> ---
>  drivers/soc/fsl/qe/qe_io.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/soc/fsl/qe/qe_io.c b/drivers/soc/fsl/qe/qe_io.c
> index e277c827bdf3..a5e2d0e5ab51 100644
> --- a/drivers/soc/fsl/qe/qe_io.c
> +++ b/drivers/soc/fsl/qe/qe_io.c
> @@ -35,6 +35,8 @@ int par_io_init(struct device_node *np)
>         if (ret)
>                 return ret;
>         par_io = ioremap(res.start, resource_size(&res));
> +       if (!par_io)
> +               return -ENOMEM;
>
>         if (!of_property_read_u32(np, "num-ports", &num_ports))
>                 num_par_io_ports = num_ports;
> --
> 2.25.1
>


From leoyang.li at nxp.com  Thu Jan  6 18:25:46 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 7 Jan 2022 10:25:46 +0800
Subject: [PATCH] soc: fsl: qe: fix typo in a comment
In-Reply-To: <20211211090845.252700-1-wangborong@cdjrlc.com>
References: <20211211090845.252700-1-wangborong@cdjrlc.com>
Message-ID: <CADRPPNRe=qgH0n2XMTEro2+dYXcz82x=PcvhjiPX1GRGkkbfjg@mail.gmail.com>

On Sat, Dec 11, 2021 at 5:12 PM Jason Wang <wangborong at cdjrlc.com> wrote:
>
> The double `is' in the comment in line 150 is repeated. Remove one
> of them from the comment.

Looks like you also removed a redundant tab in a new line.  We
probably can squeeze this trivial cleanup in, but we need to mention
it.

>
> Signed-off-by: Jason Wang <wangborong at cdjrlc.com>

Applied for next with commit message updated.

> ---
>  drivers/soc/fsl/qe/qe.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c
> index 4d38c80f8be8..b3c226eb5292 100644
> --- a/drivers/soc/fsl/qe/qe.c
> +++ b/drivers/soc/fsl/qe/qe.c
> @@ -147,7 +147,7 @@ EXPORT_SYMBOL(qe_issue_cmd);
>   * memory mapped space.
>   * The BRG clock is the QE clock divided by 2.
>   * It was set up long ago during the initial boot phase and is
> - * is given to us.
> + * given to us.
>   * Baud rate clocks are zero-based in the driver code (as that maps
>   * to port numbers). Documentation uses 1-based numbering.
>   */
> @@ -421,7 +421,7 @@ static void qe_upload_microcode(const void *base,
>
>         for (i = 0; i < be32_to_cpu(ucode->count); i++)
>                 iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
> -
> +
>         /* Set I-RAM Ready Register */
>         iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready);
>  }
> --
> 2.34.1
>


From sboyd at kernel.org  Thu Jan  6 18:27:27 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:27:27 -0800
Subject: [PATCH 1/2] clk: mediatek: clk-gate: Shrink by adding clockgating
 bit check helper
In-Reply-To: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
References: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220107022729.4975FC36AE3@smtp.kernel.org>

Quoting AngeloGioacchino Del Regno (2022-01-03 06:37:11)
> Add a clockgating bit check helper and use it in functions
> mtk_cg_bit_is_cleared(), mtk_cg_bit_is_set() to shrink the
> file size.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 18:27:36 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:27:36 -0800
Subject: [PATCH 2/2] clk: mediatek: clk-gate: Use regmap_{set/clear}_bits
 helpers
In-Reply-To: <20220103143712.46675-2-angelogioacchino.delregno@collabora.com>
References: <20220103143712.46675-1-angelogioacchino.delregno@collabora.com>
 <20220103143712.46675-2-angelogioacchino.delregno@collabora.com>
Message-ID: <20220107022737.6EFC8C36AE5@smtp.kernel.org>

Quoting AngeloGioacchino Del Regno (2022-01-03 06:37:12)
> Appropriately change calls to regmap_update_bits() with regmap_set_bits()
> and regmap_clear_bits() for improved readability.
> 
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 18:32:00 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:32:00 -0800
Subject: [PATCH v7 1/3] dt-bindings: clock: mediatek: document clk
 bindings for mediatek mt7986 SoC
In-Reply-To: <20211217121148.6753-2-sam.shih@mediatek.com>
References: <20211217121148.6753-1-sam.shih@mediatek.com>
 <20211217121148.6753-2-sam.shih@mediatek.com>
Message-ID: <20220107023201.DFCB9C36AE5@smtp.kernel.org>

Quoting Sam Shih (2021-12-17 04:11:46)
> This patch adds the binding documentation for topckgen, apmixedsys,
> infracfg, and ethernet subsystem clocks.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 18:32:07 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:32:07 -0800
Subject: [PATCH v7 2/3] clk: mediatek: add mt7986 clock IDs
In-Reply-To: <20211217121148.6753-3-sam.shih@mediatek.com>
References: <20211217121148.6753-1-sam.shih@mediatek.com>
 <20211217121148.6753-3-sam.shih@mediatek.com>
Message-ID: <20220107023208.C77FDC36AE5@smtp.kernel.org>

Quoting Sam Shih (2021-12-17 04:11:47)
> Add MT7986 clock dt-bindings, include topckgen, apmixedsys,
> infracfg, and ethernet subsystem clocks.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> Acked-by: Rob Herring <robh at kernel.org>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 18:32:15 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:32:15 -0800
Subject: [PATCH v7 3/3] clk: mediatek: add mt7986 clock support
In-Reply-To: <20211217121148.6753-4-sam.shih@mediatek.com>
References: <20211217121148.6753-1-sam.shih@mediatek.com>
 <20211217121148.6753-4-sam.shih@mediatek.com>
Message-ID: <20220107023216.64EC7C36AE3@smtp.kernel.org>

Quoting Sam Shih (2021-12-17 04:11:48)
> Add MT7986 clock support, include topckgen, apmixedsys,
> infracfg, and ethernet subsystem clocks.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Thu Jan  6 18:34:50 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 06 Jan 2022 18:34:50 -0800
Subject: [v1] clk: mediatek: use en_mask as a pure div_en_mask
In-Reply-To: <CAGXv+5G5vnOuW46q7b7m6BDS+R4vCLJehrofjfv95uOFbwyzEg@mail.gmail.com>
References: <20211110022258.2358-1-chun-jie.chen@mediatek.com>
 <CAGXv+5G5vnOuW46q7b7m6BDS+R4vCLJehrofjfv95uOFbwyzEg@mail.gmail.com>
Message-ID: <20220107023451.7C52CC36AEB@smtp.kernel.org>

Quoting Chen-Yu Tsai (2021-11-09 22:59:37)
> Hi,
> 
> On Wed, Nov 10, 2021 at 10:23 AM Chun-Jie Chen
> <chun-jie.chen at mediatek.com> wrote:
> >
> > We no longer allow en_mask to be a combination of
> > pll_en_bit and div_en_mask, so remove pll_en_bit(bit0)
> > from en_mask to make en_mask a pure en_mask that only
> > used for pll dividers.
> 
> AFAICT this looks like it continues the work done in commit 7cc4e1bbe300
> ("clk: mediatek: Fix asymmetrical PLL enable and disable control") and
> commit f384c44754b7 ("clk: mediatek: Add configurable enable control to
> mtk_pll_data").
> 
> It would be nice if you could mention this in your commit log to provide
> more context.

Please resend.


From yangyingliang at huawei.com  Thu Jan  6 18:40:47 2022
From: yangyingliang at huawei.com (Yang Yingliang)
Date: Fri, 7 Jan 2022 10:40:47 +0800
Subject: [PATCH -next] dmaengine: at_xdmac: Fix missing unlock in
 at_xdmac_tasklet()
Message-ID: <20220107024047.1051915-1-yangyingliang@huawei.com>

Add the missing unlock before return from at_xdmac_tasklet().

Fixes: e77e561925df ("dmaengine: at_xdmac: Fix race over irq_status")
Reported-by: Hulk Robot <hulkci at huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang at huawei.com>
---
 drivers/dma/at_xdmac.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
index a1da2b4b6d73..1476156af74b 100644
--- a/drivers/dma/at_xdmac.c
+++ b/drivers/dma/at_xdmac.c
@@ -1681,8 +1681,10 @@ static void at_xdmac_tasklet(struct tasklet_struct *t)
 		__func__, atchan->irq_status);
 
 	if (!(atchan->irq_status & AT_XDMAC_CIS_LIS) &&
-	    !(atchan->irq_status & error_mask))
+	    !(atchan->irq_status & error_mask)) {
+		spin_unlock_irq(&atchan->lock);
 		return;
+	}
 
 	if (atchan->irq_status & error_mask)
 		at_xdmac_handle_error(atchan);
-- 
2.25.1



From leoyang.li at nxp.com  Thu Jan  6 18:36:04 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 7 Jan 2022 10:36:04 +0800
Subject: [PATCH 1/2] soc: fsl: guts: Revert commit 3c0d64e867ed
In-Reply-To: <1063e5a4738d897adcaffce2ab8e4e45f07998ff.1635969326.git.christophe.jaillet@wanadoo.fr>
References: <1063e5a4738d897adcaffce2ab8e4e45f07998ff.1635969326.git.christophe.jaillet@wanadoo.fr>
Message-ID: <CADRPPNRke7ga1MsSKEpr948wkgNygNTQhcnB7Kk-f7DhMpptMQ@mail.gmail.com>

On Thu, Nov 4, 2021 at 4:09 AM Christophe JAILLET
<christophe.jaillet at wanadoo.fr> wrote:
>
> This reverts commit 3c0d64e867ed
> ("soc: fsl: guts: reuse machine name from device tree").
>
> A following patch will fix the missing memory allocation failure check
> instead.
>
> Suggested-by: Tyrel Datwyler <tyreld at linux.ibm.com>
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>

Applied for next.  Thanks.

> ---
> This is a follow-up of discussion in:
> https://lore.kernel.org/kernel-janitors/b12e8c5c5d6ab3061d9504de8fbaefcad6bbc385.1629321668.git.christophe.jaillet at wanadoo.fr/
> ---
>  drivers/soc/fsl/guts.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> index 072473a16f4d..af7741eafc57 100644
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
> @@ -28,7 +28,6 @@ struct fsl_soc_die_attr {
>  static struct guts *guts;
>  static struct soc_device_attribute soc_dev_attr;
>  static struct soc_device *soc_dev;
> -static struct device_node *root;
>
>
>  /* SoC die attribute definition for QorIQ platform */
> @@ -138,7 +137,7 @@ static u32 fsl_guts_get_svr(void)
>
>  static int fsl_guts_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       struct device_node *root, *np = pdev->dev.of_node;
>         struct device *dev = &pdev->dev;
>         const struct fsl_soc_die_attr *soc_die;
>         const char *machine;
> @@ -159,8 +158,9 @@ static int fsl_guts_probe(struct platform_device *pdev)
>         root = of_find_node_by_path("/");
>         if (of_property_read_string(root, "model", &machine))
>                 of_property_read_string_index(root, "compatible", 0, &machine);
> +       of_node_put(root);
>         if (machine)
> -               soc_dev_attr.machine = machine;
> +               soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
>
>         svr = fsl_guts_get_svr();
>         soc_die = fsl_soc_die_match(svr, fsl_soc_die);
> @@ -195,7 +195,6 @@ static int fsl_guts_probe(struct platform_device *pdev)
>  static int fsl_guts_remove(struct platform_device *dev)
>  {
>         soc_device_unregister(soc_dev);
> -       of_node_put(root);
>         return 0;
>  }
>
> --
> 2.30.2
>


From herbert at gondor.apana.org.au  Thu Jan  6 18:36:21 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 7 Jan 2022 13:36:21 +1100
Subject: [PATCH v3 0/2] CAAM Driver: re-factor and set proper JR status
In-Reply-To: <AM6PR06MB469129E72ED6FBE0B33C693DA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <AM6PR06MB469129E72ED6FBE0B33C693DA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
Message-ID: <YdenJaDAVmJB2AGd@gondor.apana.org.au>

On Thu, Jan 06, 2022 at 10:56:12AM +0000, ZHIZHIKIN Andrey wrote:
> Hello Herbert,
> 
> Gentle ping on this V3. I see that in Patchwork this series state is set to "Deferred".
> 
> Is there anything missing here to proceed further?

Please get the caam driver maintainer to review and ack the
patch series.

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From zelong.dong at amlogic.com  Thu Jan  6 18:39:28 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:28 +0800
Subject: [PATCH 0/3] reset: meson-s4: add reset driver
Message-ID: <20220107023931.13251-1-zelong.dong@amlogic.com>


This patchset adds Reset controller driver support for Meson-S4 SoC.
Meson-S4 Reset Controller has 6 banks (the number of reset register)
and the level-reset register offset is 0x40.


Zelong Dong (3):
  dt-bindings: reset: Add compatible for Meson-S4 Reset Controller
  dt-bindings: reset: add bindings for the Meson-S4 SoC Reset Controller
  reset: reset-meson: add support for the Meson-S4 SoC Reset Controller

 .../bindings/reset/amlogic,meson-reset.yaml   |   1 +
 drivers/reset/reset-meson.c                   |   6 +
 .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h

-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:29 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:29 +0800
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4 Reset
 Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-2-zelong.dong@amlogic.com>

Add new compatible for Amlogic's Meson-S4 Reset Controller

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
index 92922d3afd14..494a454928ce 100644
--- a/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
+++ b/Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml
@@ -17,6 +17,7 @@ properties:
       - amlogic,meson-gxbb-reset # Reset Controller on GXBB and compatible SoCs
       - amlogic,meson-axg-reset # Reset Controller on AXG and compatible SoCs
       - amlogic,meson-a1-reset # Reset Controller on A1 and compatible SoCs
+      - amlogic,meson-s4-reset # Reset Controller on S4 and compatible SoCs
 
   reg:
     maxItems: 1
-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:30 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:30 +0800
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-3-zelong.dong@amlogic.com>

Add DT bindings for the Meson-S4 SoC Reset Controller include file.

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
 1 file changed, 125 insertions(+)
 create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h

diff --git a/include/dt-bindings/reset/amlogic,meson-s4-reset.h b/include/dt-bindings/reset/amlogic,meson-s4-reset.h
new file mode 100644
index 000000000000..eab428eb8ad6
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-s4-reset.h
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Zelong Dong <zelong.dong at amlogic.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_S4_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_S4_RESET_H
+
+/*	RESET0					*/
+#define RESET_USB_DDR0			0
+#define RESET_USB_DDR1			1
+#define RESET_USB_DDR2			2
+#define RESET_USB_DDR3			3
+#define RESET_USBCTRL			4
+/*					5-7	*/
+#define RESET_USBPHY20			8
+#define RESET_USBPHY21			9
+/*					10-15	*/
+#define RESET_HDMITX_APB		16
+#define RESET_BRG_VCBUS_DEC		17
+#define RESET_VCBUS			18
+#define RESET_VID_PLL_DIV		19
+#define RESET_VDI6			20
+#define RESET_GE2D			21
+#define RESET_HDMITXPHY			22
+#define RESET_VID_LOCK			23
+#define RESET_VENCL			24
+#define RESET_VDAC			25
+#define RESET_VENCP			26
+#define RESET_VENCI			27
+#define RESET_RDMA			28
+#define RESET_HDMI_TX			29
+#define RESET_VIU			30
+#define RESET_VENC			31
+
+/*	RESET1					*/
+#define RESET_AUDIO			32
+#define RESET_MALI_APB			33
+#define RESET_MALI			34
+#define RESET_DDR_APB			35
+#define RESET_DDR			36
+#define RESET_DOS_APB			37
+#define RESET_DOS			38
+/*					39-47	*/
+#define RESET_ETH			48
+/*					49-51	*/
+#define RESET_DEMOD			52
+/*					53-63	*/
+
+/*	RESET2					*/
+#define RESET_ABUS_ARB			64
+#define RESET_IR_CTRL			65
+#define RESET_TEMPSENSOR_DDR		66
+#define RESET_TEMPSENSOR_PLL		67
+/*					68-71	*/
+#define RESET_SMART_CARD		72
+#define RESET_SPICC0			73
+/*					74	*/
+#define RESET_RSA			75
+/*					76-79	*/
+#define RESET_MSR_CLK			80
+#define RESET_SPIFC			81
+#define RESET_SARADC			82
+/*					83-87	*/
+#define RESET_ACODEC			88
+#define RESET_CEC			89
+#define RESET_AFIFO			90
+#define RESET_WATCHDOG			91
+/*					92-95	*/
+
+/*	RESET3					*/
+/*					96-127	*/
+
+/*	RESET4					*/
+/*					128-131	*/
+#define RESET_PWM_AB			132
+#define RESET_PWM_CD			133
+#define RESET_PWM_EF			134
+#define RESET_PWM_GH			135
+#define RESET_PWM_IJ			136
+/*					137	*/
+#define RESET_UART_A			138
+#define RESET_UART_B			139
+#define RESET_UART_C			140
+#define RESET_UART_D			141
+#define RESET_UART_E			142
+/*					143	*/
+#define RESET_I2C_S_A			144
+#define RESET_I2C_M_A			145
+#define RESET_I2C_M_B			146
+#define RESET_I2C_M_C			147
+#define RESET_I2C_M_D			148
+#define RESET_I2C_M_E			149
+/*					150-151	*/
+#define RESET_SD_EMMC_A			152
+#define RESET_SD_EMMC_B			153
+#define RESET_NAND_EMMC			154
+/*					155-159	*/
+
+/* RESET5 */
+#define RESET_BRG_VDEC_PIPL0		160
+#define RESET_BRG_HEVCF_PIPL0		161
+/*					162	*/
+#define RESET_BRG_HCODEC_PIPL0		163
+#define RESET_BRG_GE2D_PIPL0		164
+#define RESET_BRG_VPU_PIPL0		165
+#define RESET_BRG_CPU_PIPL0		166
+#define RESET_BRG_MALI_PIPL0		167
+/*					168	*/
+#define RESET_BRG_MALI_PIPL1		169
+/*					170-171	*/
+#define RESET_BRG_HEVCF_PIPL1		172
+#define RESET_BRG_HEVCB_PIPL1		173
+/*					174-183	*/
+#define RESET_RAMA			184
+/*					185-186	*/
+#define RESET_BRG_NIC_VAPB		187
+#define RESET_BRG_NIC_DSU		188
+#define RESET_BRG_NIC_SYSCLK		189
+#define RESET_BRG_NIC_MAIN		190
+#define RESET_BRG_NIC_ALL		191
+
+#endif
-- 
2.34.1



From zelong.dong at amlogic.com  Thu Jan  6 18:39:31 2022
From: zelong.dong at amlogic.com (Zelong Dong)
Date: Fri, 7 Jan 2022 10:39:31 +0800
Subject: [PATCH 3/3] reset: reset-meson: add support for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-1-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
Message-ID: <20220107023931.13251-4-zelong.dong@amlogic.com>

Compared to the A1 SoCs the number of RESET registers is different
and the offset for the level registers is the same. Add a new
compatible string and struct meson_reset_param to add support for the
reset controller on the S4 SoC.

Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
---
 drivers/reset/reset-meson.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c
index c9bc325ad65a..26dc54778615 100644
--- a/drivers/reset/reset-meson.c
+++ b/drivers/reset/reset-meson.c
@@ -98,11 +98,17 @@ static const struct meson_reset_param meson_a1_param = {
 	.level_offset	= 0x40,
 };
 
+static const struct meson_reset_param meson_s4_param = {
+	.reg_count	= 6,
+	.level_offset	= 0x40,
+};
+
 static const struct of_device_id meson_reset_dt_ids[] = {
 	 { .compatible = "amlogic,meson8b-reset",    .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-gxbb-reset", .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-axg-reset",  .data = &meson8b_param},
 	 { .compatible = "amlogic,meson-a1-reset",   .data = &meson_a1_param},
+	 { .compatible = "amlogic,meson-s4-reset",   .data = &meson_s4_param},
 	 { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_reset_dt_ids);
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan  6 18:40:35 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 10:40:35 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <20220106090832.42225c49@xps13>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
Message-ID: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>

Hi Miquel,

Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i 
don't find the commit in
linux mainline. then the information i got from 
[jianxin.pan at amlogic.com] is the rejection of
serial patches. I just look into the corresponding emails in link:
 
https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
it seems the patch never go on since V6, so [jianxin.pan at amlogic.com], 
could you help to clear it?
let us address the discussion in another email from [jbrunet at baylibre.com].

On 2022/1/6 16:08, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
> 
>> Because EMMC and NAND have the same control clock register, so we
>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>
>> 	sd_emmc_c_clkc: mmc at 7000 {
>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> 		reg = <0x0 0x7000 0x0 0x800>;
>> 	};
>>
>> 	nand-controller at 7800 {
>> 		......
>>
>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> 		clock-names = "core", "device", "rx", "tx";
>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>
>> 		......
>> 	}
>>
>> but in fact, above implementation is rejected. so now registering
>> a nand_divider.
> 
> What is rejected?
> Why is it rejected?
> What is nand_divider?
i simplify our clock framework below, so nand divider is 
SD_EMMC_CLOCK[5:0] here.
			   -----          -----		    -----
	   the other------|	\        |     |	   |	 |
          		  | mux	| -----  |  N  | ----------| NFC/|
	   FCLK_DIV2------|     |        |     |	   | EMMC|
			   -----/         ----- 	    -----
		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
> 
> 
>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> 
> Change Ids are not expected in the upstream kernel.
> 
> But if you fix something you should have a Fixes:.
> 
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..4472363059c2 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -55,6 +56,7 @@
>>   #define NFC_REG_VER		0x38
>>   
>>   #define NFC_RB_IRQ_EN		BIT(21)
>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>   
>>   #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>>   	(								\
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>>   	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	void __iomem *reg_clk;
>>   	struct completion completion;
>>   	struct list_head chips;
>>   	const struct meson_nfc_data *data;
>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>> -
>> +	meson_nfc_drain_cmd(nfc);
>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>   					  msecs_to_jiffies(timeout_ms));
>>   	if (ret == 0)
>>   		ret = -1;
>>   
>> +	/* reset command fifo to avoid lock */
>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>   	return ret;
>>   }
>>   
>> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   {
>>   	int ret;
>> +	struct clk_init_data init = {0};
>> +	const char *fix_div2_pll_name[1];
>>   
>> -	/* request core clock */
>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>   	if (IS_ERR(nfc->core_clk)) {
>>   		dev_err(nfc->dev, "failed to get core clock\n");
>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		return PTR_ERR(nfc->device_clk);
>>   	}
>>   
>> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>> -	if (IS_ERR(nfc->phase_tx)) {
>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>> -		return PTR_ERR(nfc->phase_tx);
>> -	}
>> -
>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>> -	if (IS_ERR(nfc->phase_rx)) {
>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>> -		return PTR_ERR(nfc->phase_rx);
>> -	}
>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>> +	init.ops = &clk_divider_ops;
>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>> +	init.parent_names = fix_div2_pll_name;
>> +	init.num_parents = 1;
>> +	nfc->nand_divider.reg = nfc->reg_clk;
>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>> +	nfc->nand_divider.hw.init = &init;
>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>> +
>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>> +	if (IS_ERR(nfc->nand_clk))
>> +		return PTR_ERR(nfc->nand_clk);
>>   
>>   	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>> -	regmap_update_bits(nfc->reg_clk,
>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>   
>>   	ret = clk_prepare_enable(nfc->core_clk);
>>   	if (ret) {
>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		goto err_device_clk;
>>   	}
>>   
>> -	ret = clk_prepare_enable(nfc->phase_tx);
>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>   	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>> -		goto err_phase_tx;
>> -	}
>> -
>> -	ret = clk_prepare_enable(nfc->phase_rx);
>> -	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>> -		goto err_phase_rx;
>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>> +		goto err_nand_clk;
>>   	}
>>   
>>   	ret = clk_set_rate(nfc->device_clk, 24000000);
>>   	if (ret)
>> -		goto err_disable_rx;
>> +		goto err_disable_clk;
>>   
>>   	return 0;
>>   
>> -err_disable_rx:
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -err_phase_rx:
>> -	clk_disable_unprepare(nfc->phase_tx);
>> -err_phase_tx:
>> +err_disable_clk:
>> +	clk_disable_unprepare(nfc->nand_clk);
>> +err_nand_clk:
>>   	clk_disable_unprepare(nfc->device_clk);
>>   err_device_clk:
>>   	clk_disable_unprepare(nfc->core_clk);
>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   
>>   static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>   {
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -	clk_disable_unprepare(nfc->phase_tx);
>> +	clk_disable_unprepare(nfc->nand_clk);
>>   	clk_disable_unprepare(nfc->device_clk);
>>   	clk_disable_unprepare(nfc->core_clk);
>>   }
>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	struct device *dev = &pdev->dev;
>>   	struct meson_nfc *nfc;
>>   	struct resource *res;
>> +	u32 ext_clk_reg;
>>   	int ret, irq;
>>   
>>   	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	if (IS_ERR(nfc->reg_base))
>>   		return PTR_ERR(nfc->reg_base);
>>   
>> -	nfc->reg_clk =
>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>> -						"amlogic,mmc-syscon");
>> +	ret = of_property_read_u32(pdev->dev.of_node,
>> +				   "sd_emmc_c_clkc",
>> +				   &ext_clk_reg);
>> +	if (ret) {
>> +		dev_err(dev, "failed to get NAND external clock register\n");
>> +		return ret;
>> +	}
>> +
>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>   	if (IS_ERR(nfc->reg_clk)) {
>>   		dev_err(dev, "Failed to lookup clock base\n");
>>   		return PTR_ERR(nfc->reg_clk);
> 
> 
> Thanks,
> Miqu?l
> 
> .


From leoyang.li at nxp.com  Thu Jan  6 18:40:43 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Fri, 7 Jan 2022 10:40:43 +0800
Subject: [PATCH 2/2] soc: fsl: guts: Add a missing memory allocation
 failure check
In-Reply-To: <4890990418ecbcfb8921efe8adb2019a03e5a1c1.1635969326.git.christophe.jaillet@wanadoo.fr>
References: <1063e5a4738d897adcaffce2ab8e4e45f07998ff.1635969326.git.christophe.jaillet@wanadoo.fr>
 <4890990418ecbcfb8921efe8adb2019a03e5a1c1.1635969326.git.christophe.jaillet@wanadoo.fr>
Message-ID: <CADRPPNTRE9sUX-4XxvtoQkGqOXzBPm_1h-FRSRepWsxdFz3Tvg@mail.gmail.com>

On Thu, Nov 4, 2021 at 4:10 AM Christophe JAILLET
<christophe.jaillet at wanadoo.fr> wrote:
>
> If 'devm_kstrdup()' fails, we should return -ENOMEM.
>
> While at it, move the 'of_node_put()' call in the error handling path and
> after the 'machine' has been copied.
> Better safe than sorry.
>
> Suggested-by: Tyrel Datwyler <tyreld at linux.ibm.com>
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>

Applied with Fixes tag and Depends-on tag added.  Thanks.

> ---
> Not sure of which Fixes tag to add. Should be a6fc3b698130, but since
> another commit needs to be reverted for this patch to make sense, I'm
> unsure of what to do. :(
> So, none is given.
> ---
>  drivers/soc/fsl/guts.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> index af7741eafc57..5ed2fc1c53a0 100644
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
> @@ -158,9 +158,14 @@ static int fsl_guts_probe(struct platform_device *pdev)
>         root = of_find_node_by_path("/");
>         if (of_property_read_string(root, "model", &machine))
>                 of_property_read_string_index(root, "compatible", 0, &machine);
> -       of_node_put(root);
> -       if (machine)
> +       if (machine) {
>                 soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
> +               if (!soc_dev_attr.machine) {
> +                       of_node_put(root);
> +                       return -ENOMEM;
> +               }
> +       }
> +       of_node_put(root);
>
>         svr = fsl_guts_get_svr();
>         soc_die = fsl_soc_die_match(svr, fsl_soc_die);
> --
> 2.30.2
>


From qhjin.dev at gmail.com  Thu Jan  6 18:46:31 2022
From: qhjin.dev at gmail.com (Qinghua Jin)
Date: Fri,  7 Jan 2022 10:46:31 +0800
Subject: [PATCH] spi: atmel: Fix typo
Message-ID: <20220107024631.396862-1-qhjin.dev@gmail.com>

Change 'actualy' to 'actually'

Signed-off-by: Qinghua Jin <qhjin.dev at gmail.com>
---
 drivers/spi/spi-atmel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index f872cf196c2f..c5e454acc22d 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -464,7 +464,7 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as,
 	 * However, the first data has to be written into the lowest 16 bits and
 	 * the second data into the highest 16 bits of the Transmit
 	 * Data Register. For 8bit data (the most frequent case), it would
-	 * require to rework tx_buf so each data would actualy fit 16 bits.
+	 * require to rework tx_buf so each data would actually fit 16 bits.
 	 * So we'd rather write only one data at the time. Hence the transmit
 	 * path works the same whether FIFOs are available (and enabled) or not.
 	 */
-- 
2.30.2



From liang.yang at amlogic.com  Thu Jan  6 18:48:08 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 10:48:08 +0800
Subject: [PATCH] dt-bindings: nand: meson: fix controller clock
In-Reply-To: <20220106091209.6b97cf3c@xps13>
References: <20220106033130.37623-1-liang.yang@amlogic.com>
 <20220106091209.6b97cf3c@xps13>
Message-ID: <e4e1c378-81de-5e45-e5da-68193148e1e1@amlogic.com>

Hi Miquel,

On 2022/1/6 16:12, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hello,
> 
> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:31:30 +0800:
> 
> This patch should be in a series with "mtd: rawnand: meson: fix the
> clock after discarding sd_emmc_c_clk" and possibly come first.
> 
> You miss a commit message which is _very_ important given the type of
> change you propose.
>   
>> Change-Id: I1425b491d8b95061e1ce358ef33143433fc94d24
> 
> Change IDs have nothing to do here.
> 
> However a Fixes and a Signed-off-by are welcome.
> 
> You'll also need to Cc: Rob H. in your v2.
> 
ok, i will fix these once we clarify the patch about sd_emmc_c_clk and 
decide to use this patch.
>> ---
>>   .../bindings/mtd/amlogic,meson-nand.txt        | 18 +++---------------
>>   1 file changed, 3 insertions(+), 15 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> index 5794ab1147c1..37f16fe4fe66 100644
>> --- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> +++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
>> @@ -14,11 +14,6 @@ Required properties:
>>   - clock-names: Should contain the following:
>>   	"core" - NFC module gate clock
>>   	"device" - device clock from eMMC sub clock controller
>> -	"rx" - rx clock phase
>> -	"tx" - tx clock phase
>> -
>> -- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
>> -				controller port C
>>   
>>   Optional children nodes:
>>   Children nodes represent the available nand chips.
>> @@ -28,11 +23,6 @@ see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindi
>>   
>>   Example demonstrate on AXG SoC:
>>   
>> -	sd_emmc_c_clkc: mmc at 7000 {
>> -		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> -		reg = <0x0 0x7000 0x0 0x800>;
>> -	};
>> -
>>   	nand-controller at 7800 {
>>   		compatible = "amlogic,meson-axg-nfc";
>>   		reg = <0x0 0x7800 0x0 0x100>;
>> @@ -41,11 +31,9 @@ Example demonstrate on AXG SoC:
>>   		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
>>   
>>   		clocks = <&clkc CLKID_SD_EMMC_C>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> -			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> -		clock-names = "core", "device", "rx", "tx";
>> -		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>> +			<&clkc CLKID_FCLK_DIV2>;
>> +		clock-names = "core", "device";
>> +		sd_emmc_c_clkc = <0xffe07000>;
>>   
>>   		pinctrl-names = "default";
>>   		pinctrl-0 = <&nand_pins>;
> 
> 
> Thanks,
> Miqu?l
> 
> .


From wanjiabing at vivo.com  Thu Jan  6 18:50:50 2022
From: wanjiabing at vivo.com (Wan Jiabing)
Date: Fri,  7 Jan 2022 10:50:50 +0800
Subject: [PATCH] phy: phy-mtk-tphy: Fix dumplicated argument in phy-mtk-tphy
Message-ID: <20220107025050.787720-1-wanjiabing@vivo.com>

Fix following coccicheck warning:
./drivers/phy/mediatek/phy-mtk-tphy.c:994:6-29: duplicated argument
to && or ||

The efuse_rx_imp is duplicate. Here should be efuse_tx_imp.

Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index 6d307102f4f6..8ee7682b8e93 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -992,7 +992,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instanc
 		/* no efuse, ignore it */
 		if (!instance->efuse_intr &&
 		    !instance->efuse_rx_imp &&
-		    !instance->efuse_rx_imp) {
+		    !instance->efuse_tx_imp) {
 			dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
 			instance->efuse_sw_en = 0;
 			break;
-- 
2.34.1



From robh at kernel.org  Thu Jan  6 19:04:17 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 21:04:17 -0600
Subject: [PATCH] dt-bindings: net: wireless: mt76: Fix 8-bit property sizes
Message-ID: <20220107030419.2380198-1-robh@kernel.org>

The '/bits/ 8' notation applies the next <> list of values. Another <> list
is encoded as 32-bits by default. IOW, each <> list needs to be preceeded
with '/bits/ 8'.

While the dts format allows this, as a rule we don't mix sizes for DT
properties since all size information is lost in the dtb file.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/net/wireless/mediatek,mt76.yaml       | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
index 1489d3c1cd6e..269cd63fb544 100644
--- a/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
+++ b/Documentation/devicetree/bindings/net/wireless/mediatek,mt76.yaml
@@ -191,9 +191,9 @@ examples:
                    channels = <36 48>;
                    rates-ofdm = /bits/ 8 <23 23 23 23 23 23 23 23>;
                    rates-mcs = /bits/ 8 <1 23 23 23 23 23 23 23 23 23 23>,
-                                        <3 22 22 22 22 22 22 22 22 22 22>;
+                               /bits/ 8 <3 22 22 22 22 22 22 22 22 22 22>;
                    rates-ru = /bits/ 8 <3 22 22 22 22 22 22 22 22 22 22 22 22>,
-                                       <4 20 20 20 20 20 20 20 20 20 20 20 20>;
+                              /bits/ 8 <4 20 20 20 20 20 20 20 20 20 20 20 20>;
                };
                b1 {
                    channels = <100 181>;
-- 
2.32.0



From robh at kernel.org  Thu Jan  6 19:19:04 2022
From: robh at kernel.org (Rob Herring)
Date: Thu,  6 Jan 2022 21:19:04 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
Message-ID: <20220107031905.2406176-1-robh@kernel.org>

'interrupt-parent' is never required as it can be in a parent node or a
parent node itself can be an interrupt provider. Where exactly it lives is
outside the scope of a binding schema.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
 .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
 Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
 .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
 .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
 .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
 .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
 7 files changed, 15 deletions(-)

diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
index 9ad470e01953..b085450b527f 100644
--- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
+++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
@@ -43,7 +43,6 @@ required:
   - gpio-controller
   - interrupt-controller
   - "#interrupt-cells"
-  - interrupt-parent
 
 additionalProperties: false
 
diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
index e864d798168d..d433e496ec6e 100644
--- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
+++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
@@ -175,15 +175,6 @@ required:
   - ti,mbox-num-fifos
 
 allOf:
-  - if:
-      properties:
-        compatible:
-          enum:
-            - ti,am654-mailbox
-    then:
-      required:
-        - interrupt-parent
-
   - if:
       properties:
         compatible:
diff --git a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
index 499c62c04daa..5dce62a7eff2 100644
--- a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
+++ b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
@@ -221,7 +221,6 @@ required:
   - '#gpio-cells'
   - interrupt-controller
   - '#interrupt-cells'
-  - interrupt-parent
   - interrupts
   - AVDD-supply
   - DBVDD1-supply
diff --git a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
index 437502c5ca96..3ce9f9a16baf 100644
--- a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
+++ b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
@@ -46,7 +46,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-parent
   - interrupts
   - interrupt-names
   - lantiq,tx-burst-length
diff --git a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
index 7bc074a42369..5bc1a21ca579 100644
--- a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
+++ b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
@@ -38,7 +38,6 @@ properties:
 required:
   - compatible
   - reg
-  - interrupt-parent
   - interrupts
   - interrupt-names
   - "#address-cells"
diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
index 2b9d1d6fc661..72c78f4ec269 100644
--- a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
+++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
@@ -61,7 +61,6 @@ required:
   - num-lanes
   - interrupts
   - interrupt-names
-  - interrupt-parent
   - interrupt-map-mask
   - interrupt-map
   - clock-names
diff --git a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
index a2bbc0eb7220..32f4641085bc 100644
--- a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
+++ b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
@@ -55,7 +55,6 @@ required:
   - reg-names
   - "#interrupt-cells"
   - interrupts
-  - interrupt-parent
   - interrupt-map
   - interrupt-map-mask
   - bus-range
-- 
2.32.0



From herbert at gondor.apana.org.au  Thu Jan  6 19:28:53 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 7 Jan 2022 14:28:53 +1100
Subject: [PATCH v3 2/6] crypto: arm64/sm3-ce - make dependent on sm3
 library
In-Reply-To: <20211223043547.32297-3-tianjia.zhang@linux.alibaba.com>
References: <20211223043547.32297-1-tianjia.zhang@linux.alibaba.com>
 <20211223043547.32297-3-tianjia.zhang@linux.alibaba.com>
Message-ID: <YdezdZQHZT2+iYV3@gondor.apana.org.au>

On Thu, Dec 23, 2021 at 12:35:43PM +0800, Tianjia Zhang wrote:
> SM3 generic library is stand-alone implementation, sm3-ce can depend
> on the SM3 library instead of sm3-generic.
> 
> Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
> ---
>  arch/arm64/crypto/Kconfig       |  2 +-
>  arch/arm64/crypto/sm3-ce-glue.c | 20 ++++++++++++++------
>  2 files changed, 15 insertions(+), 7 deletions(-)

This doesn't compile cleanly with C=1 W=1:

  CC [M]  arch/arm64/crypto/sm3-ce-glue.o
  AS [M]  arch/arm64/crypto/sm3-ce-core.o
  CC [M]  arch/arm64/crypto/sm4-ce-glue.o
  CHECK   ../arch/arm64/crypto/sha3-ce-glue.c
../arch/arm64/crypto/sm3-ce-glue.c: In function ?sm3_ce_update?:
../arch/arm64/crypto/sm3-ce-glue.c:30:10: error: void value not ignored as it ought to be
   30 |   return sm3_update(shash_desc_ctx(desc), data, len);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../arch/arm64/crypto/sm3-ce-glue.c: In function ?sm3_ce_final?:
../arch/arm64/crypto/sm3-ce-glue.c:42:10: error: void value not ignored as it ought to be
   42 |   return sm3_final(shash_desc_ctx(desc), out);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[3]: *** [../scripts/Makefile.build:287: arch/arm64/crypto/sm3-ce-glue.o] Error 1
make[3]: *** Waiting for unfinished jobs....

Please make sure everything builds cleanly with C=1 W=1 *before*
you submit.

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From leoyang.li at nxp.com  Thu Jan  6 19:37:36 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Thu,  6 Jan 2022 21:37:36 -0600
Subject: [GIT PULL] soc/fsl drivers changes for next(v5.17)
Message-ID: <20220107033736.26762-1-leoyang.li@nxp.com>

Hi soc maintainers,

Please merge the following new changes for soc/fsl drivers.

Regards,
Leo

The following changes since commit fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf:

  Linux 5.16-rc1 (2021-11-14 13:56:52 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux.git tags/soc-fsl-next-v5.17

for you to fetch changes up to 1ce93cb102e7fcf5d1849044d23ce92b5a71040a:

  soc: fsl: qe: Check of ioremap return value (2022-01-06 20:53:18 -0600)

----------------------------------------------------------------
NXP/FSL SoC driver updates for v5.17

- Add new SoC compatible in existing binding
- Replace kernel.h with the necessary inclusions
- MAINTAINERS file fixes
- Fix memory allocation failure check in guts driver
- Various cleanups and minor fixes

----------------------------------------------------------------
Andy Shevchenko (3):
      soc: fsl: Replace kernel.h with the necessary inclusions
      soc: fsl: Correct MAINTAINERS database (QUICC ENGINE LIBRARY)
      soc: fsl: Correct MAINTAINERS database (SOC)

Christophe JAILLET (2):
      soc: fsl: guts: Revert commit 3c0d64e867ed
      soc: fsl: guts: Add a missing memory allocation failure check

Jason Wang (1):
      soc: fsl: qe: fix typo in a comment

Jiasheng Jiang (1):
      soc: fsl: qe: Check of ioremap return value

Li Yang (2):
      dt-bindings: qoriq-clock: add missing compatible for lx2160a
      dt-bindings: fsl,layerscape-dcfg: add missing compatible for lx2160a

 .../bindings/arm/freescale/fsl,layerscape-dcfg.txt         |  2 +-
 Documentation/devicetree/bindings/clock/qoriq-clock.txt    |  1 +
 MAINTAINERS                                                |  4 ++--
 drivers/soc/fsl/guts.c                                     | 14 +++++++++-----
 drivers/soc/fsl/qe/qe.c                                    |  4 ++--
 drivers/soc/fsl/qe/qe_io.c                                 |  2 ++
 include/soc/fsl/dpaa2-fd.h                                 |  3 ++-
 include/soc/fsl/qe/immap_qe.h                              |  3 ++-
 include/soc/fsl/qe/qe_tdm.h                                |  4 +++-
 include/soc/fsl/qe/ucc_fast.h                              |  2 +-
 include/soc/fsl/qe/ucc_slow.h                              |  2 +-
 11 files changed, 26 insertions(+), 15 deletions(-)


From wenst at chromium.org  Thu Jan  6 19:57:49 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 7 Jan 2022 11:57:49 +0800
Subject: [PATCH 2/3] phy: mediatek: phy-mtk-mipi-dsi: Reorder and stop
 implicit header inclusion
In-Reply-To: <509b82079256ffaa0d844ae5a79a436fced16f3f.camel@mediatek.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
 <20220103145324.48008-2-angelogioacchino.delregno@collabora.com>
 <509b82079256ffaa0d844ae5a79a436fced16f3f.camel@mediatek.com>
Message-ID: <CAGXv+5EmnGFDnZE01mFfC=WHReOLdbuqCpAmwJNMvm6N93wRew@mail.gmail.com>

On Thu, Jan 6, 2022 at 4:48 PM Chunfeng Yun <chunfeng.yun at mediatek.com> wrote:
>
> On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
> > All the headers for phy-mtk-mipi-{dsi,dsi-mt8173,dsi-mt8183}.c were
> > included from phy-mtk-mipi-dsi.h, but this isn't optimal: in order to
> > increase readability and sensibly reduce build times, the inclusions
> > should be done per-file, also avoiding to include unused headers and
> > should not be implicit.
> >
> > For this reason, move the inclusions to each file and remove unused
> > ones.
> >
> > Signed-off-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > ---
> >  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c |  4 ++++
> >  drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c |  4 ++++
> >  drivers/phy/mediatek/phy-mtk-mipi-dsi.c        |  7 +++++++
> >  drivers/phy/mediatek/phy-mtk-mipi-dsi.h        | 10 ++--------
> >  4 files changed, 17 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> > b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> > index 95a0d9a3cca7..59f028da9d3e 100644
> > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c
> > @@ -4,7 +4,11 @@
> >   * Author: jitao.shi <jitao.shi at mediatek.com>
> >   */
> >
> > +#include <linux/clk-provider.h>
> > +#include <linux/delay.h>
> > +#include <linux/module.h>
> >  #include <linux/regmap.h>
> > +#include <linux/phy/phy.h>
> >  #include "phy-mtk-mipi-dsi.h"
> >
> >  #define MIPITX_DSI_CON               0x00
> > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> > b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> > index 01b59527669e..6c6b192485ba 100644
> > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c
> > @@ -4,7 +4,11 @@
> >   * Author: jitao.shi <jitao.shi at mediatek.com>
> >   */
> >
> > +#include <linux/clk-provider.h>
> > +#include <linux/delay.h>
> > +#include <linux/module.h>
> >  #include <linux/regmap.h>
> > +#include <linux/phy/phy.h>
> >  #include "phy-mtk-mipi-dsi.h"
> >
> >  #define MIPITX_LANE_CON              0x000c
> > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > index 51b1b1d4ad38..6f7425b0bf5b 100644
> > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > @@ -3,7 +3,14 @@
> >   * Copyright (c) 2015 MediaTek Inc.
> >   */
> >
> > +#include <linux/clk.h>
> > +#include <linux/clk-provider.h>
> > +#include <linux/module.h>
> > +#include <linux/nvmem-consumer.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> >  #include <linux/regmap.h>
> > +#include <linux/phy/phy.h>
> >  #include "phy-mtk-mipi-dsi.h"
> >
> >  inline struct mtk_mipi_tx *mtk_mipi_tx_from_clk_hw(struct clk_hw
> > *hw)
> > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> > b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> > index 8d32e9027a15..4eb5fc91e083 100644
> > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.h
> > @@ -7,16 +7,10 @@
> >  #ifndef _MTK_MIPI_TX_H
> >  #define _MTK_MIPI_TX_H
> >
> > -#include <linux/clk.h>
> >  #include <linux/clk-provider.h>
> > -#include <linux/delay.h>
> > -#include <linux/io.h>
> > -#include <linux/module.h>
> > -#include <linux/nvmem-consumer.h>
> > -#include <linux/of_device.h>
> > -#include <linux/platform_device.h>
> > +#include <linux/types.h>
> > +#include <linux/regmap.h>
> >  #include <linux/phy/phy.h>
> > -#include <linux/slab.h>
> >
> I don't think it's good idea to move the common headers into .c files

Header files should be included directly by the file that uses facilities
provided by said header file. Required ones should not be transitively
included through other header files, as that introduces a subtle dependency.

Also, needlessly including header files in places that aren't using them
increases build time. See the 2000+ patch series from Ingo Molnar [1]
increasing build performance by cleaning up header files.

ChenYu

[1] https://lwn.net/ml/linux-kernel/YdIfz+LMewetSaEB at gmail.com/

> >  struct mtk_mipitx_data {
> >       const u32 mppll_preserve;
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From aaron.ma at canonical.com  Thu Jan  6 19:59:09 2022
From: aaron.ma at canonical.com (Aaron Ma)
Date: Fri,  7 Jan 2022 11:59:09 +0800
Subject: [PATCH v2] Bluetooth: btusb: Add support for Foxconn QCA 0xe0d0
In-Reply-To: <20211227102950.17968-1-aaron.ma@canonical.com>
References: <20211227102950.17968-1-aaron.ma@canonical.com>
Message-ID: <20220107035909.14912-1-aaron.ma@canonical.com>

Add an ID of Qualcomm Bluetooth SoC WCN6855.

T:  Bus=05 Lev=01 Prnt=01 Port=03 Cnt=02 Dev#=  4 Spd=12   MxCh= 0
D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0489 ProdID=e0d0 Rev= 0.01
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:  If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:* If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
I:  If#= 1 Alt= 7 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  65 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  65 Ivl=1ms

Signed-off-by: Aaron Ma <aaron.ma at canonical.com>
---
V1 -> V2: rebase on bluetooth-next tree.

 drivers/bluetooth/btusb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 74ec7ca96b69..91bf9e24ba6e 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -311,6 +311,9 @@ static const struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x10ab, 0x9409), .driver_info = BTUSB_QCA_WCN6855 |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe0d0), .driver_info = BTUSB_QCA_WCN6855 |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
 
 	/* Broadcom BCM2035 */
 	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan  6 20:04:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 12:04:46 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
Message-ID: <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>

Hi Jerome,

On 2022/1/6 16:16, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Because EMMC and NAND have the same control clock register, so we
>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>
>> 	sd_emmc_c_clkc: mmc at 7000 {
>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>> 		reg = <0x0 0x7000 0x0 0x800>;
>> 	};
>>
>> 	nand-controller at 7800 {
>> 		......
>>
>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>> 		clock-names = "core", "device", "rx", "tx";
>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>
>> 		......
>> 	}
>>
>> but in fact, above implementation is rejected. so now registering
>> a nand_divider.
> 
> Can you give a bit of context ? a link to the discussion rejecting this
> 
Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him 
to clarify it.
> As far as remember, things were getting done for A1 and stopped before
> clock part was finished. I'm saying the change is wrong, just that a
> discussion is needed before a decision is made.
>
ok.
previous discussion in this link:
https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
it never go on since v6.

>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..4472363059c2 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -55,6 +56,7 @@
>>   #define NFC_REG_VER		0x38
>>   
>>   #define NFC_RB_IRQ_EN		BIT(21)
>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>   
>>   #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
>>   	(								\
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
> 
> I would have been nice to explain why these clock are no longer
> required, in the change description maybe ?

i got the reply from our vlsi members that rx and tx doesn't make sense 
to meson NFC timing. so previous commit about this should be wrong.
> 
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>>   	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	void __iomem *reg_clk;
>>   	struct completion completion;
>>   	struct list_head chips;
>>   	const struct meson_nfc_data *data;
>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>> -
>> +	meson_nfc_drain_cmd(nfc);
> 
> is this clock related ?
ok, i will split it in another patch.
> 
>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>   					  msecs_to_jiffies(timeout_ms));
>>   	if (ret == 0)
>>   		ret = -1;
>>   
>> +	/* reset command fifo to avoid lock */
>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
> 
> Again, not seem to be clock related - does not belong in this patch
ok, i will split it in another patch.
> 
>>   	return ret;
>>   }
>>   
>> @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   {
>>   	int ret;
>> +	struct clk_init_data init = {0};
>> +	const char *fix_div2_pll_name[1];
>>   
>> -	/* request core clock */
> 
> Why is the comment bothering you ?
> 
>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>   	if (IS_ERR(nfc->core_clk)) {
>>   		dev_err(nfc->dev, "failed to get core clock\n");
>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		return PTR_ERR(nfc->device_clk);
>>   	}
>>   
>> -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>> -	if (IS_ERR(nfc->phase_tx)) {
>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>> -		return PTR_ERR(nfc->phase_tx);
>> -	}
>> -
>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>> -	if (IS_ERR(nfc->phase_rx)) {
>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>> -		return PTR_ERR(nfc->phase_rx);
>> -	}
>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>> +	init.ops = &clk_divider_ops;
>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
> 
> You should be using "fw_name" so CCF looks a DT directly, instead of this
ok
> 
>> +	init.parent_names = fix_div2_pll_name;
>> +	init.num_parents = 1;
>> +	nfc->nand_divider.reg = nfc->reg_clk;
>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>> +	nfc->nand_divider.hw.init = &init;
>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>> +
>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>> +	if (IS_ERR(nfc->nand_clk))
>> +		return PTR_ERR(nfc->nand_clk);
>>   
>>   	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>> -	regmap_update_bits(nfc->reg_clk,
>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>   
>>   	ret = clk_prepare_enable(nfc->core_clk);
>>   	if (ret) {
>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   		goto err_device_clk;
>>   	}
>>   
>> -	ret = clk_prepare_enable(nfc->phase_tx);
>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>   	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>> -		goto err_phase_tx;
>> -	}
>> -
>> -	ret = clk_prepare_enable(nfc->phase_rx);
>> -	if (ret) {
>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>> -		goto err_phase_rx;
>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>> +		goto err_nand_clk;
>>   	}
>>   
>>   	ret = clk_set_rate(nfc->device_clk, 24000000);
>>   	if (ret)
>> -		goto err_disable_rx;
>> +		goto err_disable_clk;
>>   
>>   	return 0;
>>   
>> -err_disable_rx:
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -err_phase_rx:
>> -	clk_disable_unprepare(nfc->phase_tx);
>> -err_phase_tx:
>> +err_disable_clk:
>> +	clk_disable_unprepare(nfc->nand_clk);
>> +err_nand_clk:
>>   	clk_disable_unprepare(nfc->device_clk);
>>   err_device_clk:
>>   	clk_disable_unprepare(nfc->core_clk);
>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>   
>>   static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>   {
>> -	clk_disable_unprepare(nfc->phase_rx);
>> -	clk_disable_unprepare(nfc->phase_tx);
>> +	clk_disable_unprepare(nfc->nand_clk);
>>   	clk_disable_unprepare(nfc->device_clk);
>>   	clk_disable_unprepare(nfc->core_clk);
>>   }
>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	struct device *dev = &pdev->dev;
>>   	struct meson_nfc *nfc;
>>   	struct resource *res;
>> +	u32 ext_clk_reg;
>>   	int ret, irq;
>>   
>>   	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>   	if (IS_ERR(nfc->reg_base))
>>   		return PTR_ERR(nfc->reg_base);
>>   
>> -	nfc->reg_clk =
>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>> -						"amlogic,mmc-syscon");
>> +	ret = of_property_read_u32(pdev->dev.of_node,
>> +				   "sd_emmc_c_clkc",
>> +				   &ext_clk_reg);
>> +	if (ret) {
>> +		dev_err(dev, "failed to get NAND external clock register\n");
>> +		return ret;
>> +	}
>> +
>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
> 
> That's how you should get a register region.
> If you want an example of a device claiming several region on amlogic,
> have a look at the pinctrl driver.
ok
> 
>>   	if (IS_ERR(nfc->reg_clk)) {
>>   		dev_err(dev, "Failed to lookup clock base\n");
>>   		return PTR_ERR(nfc->reg_clk);
> 
> .


From liang.yang at amlogic.com  Thu Jan  6 20:08:39 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 7 Jan 2022 12:08:39 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
Message-ID: <3d4eff52-431d-438d-bbe6-3267d87e2d37@amlogic.com>

Hi Miquel,

refine the clock framework diagram.

On 2022/1/7 10:40, Liang Yang wrote:
>> What is nand_divider?
> i simplify our clock framework below, so nand divider is 
> SD_EMMC_CLOCK[5:0] here.
>  ?????????????? -----????????? -----??????????? -----
>  ?????? the other------|??? \??????? |???? |?????? |???? |
>  ?????????????????? | mux??? | -----? |? N? | ----------| NFC/|
>  ?????? FCLK_DIV2------|???? |??????? |???? |?????? | EMMC|
>  ?????????????? -----/???????? -----???????? -----
>  ??????????? SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]


                          -----           -------         --------
               the other-|      \        |       |       |        |
                         | mux  |--------|  N    |-------|   NFC/ |
                         |      |        |       |       |   EMMC |
               fclk_div2-|      /        |       |       |        |
                          -----           -------         --------
                   SD_EMMC_CLOCK[7:6]   SD_EMMC_CLOCK[5:0]


From quic_saipraka at quicinc.com  Thu Jan  6 21:10:05 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 7 Jan 2022 10:40:05 +0530
Subject: [PATCHv6 4/5] tracing: Add register read/write tracing support
In-Reply-To: <20220106131824.073fbe5c@gandalf.local.home>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
 <20220106131824.073fbe5c@gandalf.local.home>
Message-ID: <df9b5a82-5f00-f3ec-14cf-0b212be2a7a7@quicinc.com>

Hi Steve,

On 1/6/2022 11:48 PM, Steven Rostedt wrote:
> This should not be in the kernel/trace directory. It should be in the

Hmm these are called from low level generic io header file 
(include/asm-generic/) where
we wouldn't have any Kconfig to control this feature flexibly and as we 
can have this as
a generic feature selectable by other architectures, wouldn't this be 
suited in kernel/trace?
I thought you were ok with the folder structure in the initial versions 
of the series?

Thanks,
Sai


From pgwipeout at gmail.com  Thu Jan  6 21:13:31 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri,  7 Jan 2022 00:13:31 -0500
Subject: [PATCH 0/4] add pine64 touch panel support to rockpro64
Message-ID: <20220107051335.3812535-1-pgwipeout@gmail.com>

This patch series adds support for the Pine64 touch panel to the
rockpro64 single board computer.
This panel attaches to the dsi port and includes an i2c touch screen.

The first two patches involve making the reset pin to the Feiyang
fy07024di26a30d panel optional. On the rockpro64 and quartz64-a this pin
is tied to dvdd and automatically comes high when power is applied.
The third patch adds the device tree nodes to rockpro64 to permit the
panel to be used.
The fourth patch is an example patch to enable this support, tagged do
not merge as this is something for the end user to enable only when they
have the panel attached.

Peter Geis (4):
  dt-bindings: display: panel: feiyang,fy07024di26a30d: make reset gpio
    optional
  drm/panel: feiyang-fy07024di26a30d: make reset gpio optional
  arm64: dts: rockchip: add pine64 touch panel display to rockpro64
  arm64: dts: rockchip: enable the pine64 touch screen on rockpro64

 .../panel/feiyang,fy07024di26a30d.yaml        |  1 -
 .../boot/dts/rockchip/rk3399-rockpro64.dtsi   | 80 ++++++++++++++++++-
 .../drm/panel/panel-feiyang-fy07024di26a30d.c | 11 ++-
 3 files changed, 83 insertions(+), 9 deletions(-)

-- 
2.32.0



From pgwipeout at gmail.com  Thu Jan  6 21:13:35 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri,  7 Jan 2022 00:13:35 -0500
Subject: [PATCH 4/4] arm64: dts: rockchip: enable the pine64 touch screen on
 rockpro64
In-Reply-To: <20220107051335.3812535-1-pgwipeout@gmail.com>
References: <20220107051335.3812535-1-pgwipeout@gmail.com>
Message-ID: <20220107051335.3812535-5-pgwipeout@gmail.com>

Enable the touch screen, backlight, and dsi nodes for the Pine64 touch panel
attached to the rockpro64.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
index 158befb9a48c..f6c36fcd6db3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
@@ -26,7 +26,7 @@ backlight: backlight {
 		pwms = <&pwm0 0 1000000 0>;
 		brightness-levels = <0 4 8 16 32 64 128 255>;
 		default-brightness-level = <5>;
-		status = "disabled";
+		status = "okay";
 	};
 
 	clkin_gmac: external-gmac-clock {
@@ -594,7 +594,7 @@ touch: touchscreen at 5d {
 		interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
 		irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
 		reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
-		status = "disabled";
+		status = "okay";
 	};
 };
 
@@ -633,7 +633,7 @@ &io_domains {
 
 /* enable for pine64 panel display support */
 &mipi_dsi {
-	status = "disabled";
+	status = "okay";
 	clock-master;
 
 	ports {
-- 
2.32.0



From pgwipeout at gmail.com  Thu Jan  6 21:13:34 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Fri,  7 Jan 2022 00:13:34 -0500
Subject: [PATCH 3/4] arm64: dts: rockchip: add pine64 touch panel display to
 rockpro64
In-Reply-To: <20220107051335.3812535-1-pgwipeout@gmail.com>
References: <20220107051335.3812535-1-pgwipeout@gmail.com>
Message-ID: <20220107051335.3812535-4-pgwipeout@gmail.com>

The Pine64 touch panel is a panel consisting of the Feiyang fy07024di26a30d
panel with a Goodix gt911 touch screen.
Add the device tree nodes to the rockpro64 to permit attaching this display to
the device.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../boot/dts/rockchip/rk3399-rockpro64.dtsi   | 80 ++++++++++++++++++-
 1 file changed, 76 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
index 83db4ca67334..158befb9a48c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
@@ -20,6 +20,15 @@ chosen {
 		stdout-path = "serial2:1500000n8";
 	};
 
+	/* enable for panel backlight support */
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pwm0 0 1000000 0>;
+		brightness-levels = <0 4 8 16 32 64 128 255>;
+		default-brightness-level = <5>;
+		status = "disabled";
+	};
+
 	clkin_gmac: external-gmac-clock {
 		compatible = "fixed-clock";
 		clock-frequency = <125000000>;
@@ -220,6 +229,14 @@ vdd_log: vdd-log {
 		regulator-max-microvolt = <1700000>;
 		vin-supply = <&vcc5v0_sys>;
 	};
+
+	avdd: avdd {
+		compatible = "regulator-fixed";
+		regulator-name = "avdd";
+		regulator-min-microvolt = <11000000>;
+		regulator-max-microvolt = <11000000>;
+		vin-supply = <&vcc3v3_s0>;
+	};
 };
 
 &cpu_l0 {
@@ -301,6 +318,11 @@ &hdmi {
 	status = "okay";
 };
 
+/* force hdmi to vopb */
+&hdmi_in_vopl {
+	status = "disabled";
+};
+
 &hdmi_sound {
 	status = "okay";
 };
@@ -400,8 +422,6 @@ regulator-state-mem {
 
 			vcc3v0_touch: LDO_REG2 {
 				regulator-name = "vcc3v0_touch";
-				regulator-always-on;
-				regulator-boot-on;
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3000000>;
 				regulator-state-mem {
@@ -490,8 +510,6 @@ regulator-state-mem {
 
 			vcc3v3_s0: SWITCH_REG2 {
 				regulator-name = "vcc3v3_s0";
-				regulator-always-on;
-				regulator-boot-on;
 				regulator-state-mem {
 					regulator-off-in-suspend;
 				};
@@ -565,6 +583,19 @@ fusb0: typec-portc at 22 {
 		vbus-supply = <&vcc5v0_typec>;
 		status = "okay";
 	};
+
+	/* enable for pine64 touch screen support */
+	touch: touchscreen at 5d {
+		compatible = "goodix,gt911";
+		reg = <0x5d>;
+		AVDD28-supply = <&vcc3v0_touch>;
+		VDDIO-supply = <&vcc3v0_touch>;
+		interrupt-parent = <&gpio4>;
+		interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
+		irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
 };
 
 &i2s0 {
@@ -600,6 +631,47 @@ &io_domains {
 	gpio1830-supply = <&vcc_3v0>;
 };
 
+/* enable for pine64 panel display support */
+&mipi_dsi {
+	status = "disabled";
+	clock-master;
+
+	ports {
+		mipi_out: port at 1 {
+			reg = <1>;
+
+			mipi_out_panel: endpoint {
+				remote-endpoint = <&mipi_in_panel>;
+			};
+		};
+	};
+
+	mipi_panel: panel at 0 {
+		compatible = "feiyang,fy07024di26a30d";
+		reg = <0>;
+		avdd-supply = <&avdd>;
+		backlight = <&backlight>;
+		dvdd-supply = <&vcc3v3_s0>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port at 0 {
+				reg = <0>;
+
+				mipi_in_panel: endpoint {
+					remote-endpoint = <&mipi_out_panel>;
+				};
+			};
+		};
+	};
+};
+
+/* force dsi to vopl */
+&mipi_in_vopb {
+	status="disabled";
+};
+
 &pcie0 {
 	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
 	num-lanes = <4>;
-- 
2.32.0



From jim.cromie at gmail.com  Thu Jan  6 21:29:23 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:23 -0700
Subject: [PATCH v11 00/19] dyndbg & drm.debug to tracefs
Message-ID: <20220107052942.1349447-1-jim.cromie@gmail.com>

hi Jason, Steve, Greg, DRM-folks,

This patchset plumbs debug streams, from dynamic-debug, and from
drm.debug, into tracefs.  Enabling traffic is done on both source &
destination:

	# enable at source
	echo module usbcore +T > /proc/dynamic_debug/control
	# enable events into tracefs
	echo 1 > /sys/kernel/tracing/events/dyndbg/enable

	# enable at source
	echo 0x03 > /sys/module/drm/parameters/debug
	# enable events into tracefs
	echo 1 > /sys/kernel/tracing/events/drm/enable

This allows selectivity at the sources, and in principle, filtering at
tracefs (which is unaddressed, except for arg-passthru).


Here is v11, it differs subsantially from v10:

A: All tracefs action is via 4 new trace-events:

from dyndbg:
  pr_debug() sends trace_prdbg()
  dev_dbg()  sends trace_devdbg()
  both preserve args unchanged

similarly from drm:
  drm_dev_dbg() -> trace_drm_devdbg()
  drm_dbg()	-> trace_drm_dbg()
  again, args are captured unchanged.
  for some reason 3 other drm_vblank* events showed up, I dont know why.

These 4 events (not counting vblank) all capture the args unchanged;
ISTM full exposure of available info is best for filtering/triggering
purposes.


B: dynamic-debug gets proper .class_id, and query support (dyndbg:)

so that this is legal input:

   echo module drm class 3 +T > /proc/dynamic_debug/control

v10 used "format drm:core:", which worked, but required addition of
category string prefixes, and possible user-facing-changes issues.

New field is uint:4, big enough to fit DRMs enum drm_debug_category
(once it has been condensed). The name is .class_id, distinct from but
related to DRMs "category".

This also includes _CLS name & arg extensions of the Factory macros
that implement dyndbgs jump-label/NOOP optimizations.


C: integration of dyndbg into drm.debug (drm_print:)

The purpose here (and originally) is to avoid drm_debug_enabled()
runtime costs, and to put a more flexible substrate underneath the
sysfs bitmap api.  Ive made it CONFIG dependent, since each _ddebug is
56 bytes, and i915 & amdgpu have ~1700 & ~3800 callsites respectively,
of which 127 & ~2k are plain pr_debugs.

1. We shrink enum drm_debug_category to fit in 4 bits, at nominal
   cost of BIT(category) at runtime, which dyndbg will avoid anyway.

2. Add the trace_drm_*dbg() events

3. insert macro indirection, and use it to wrap drm_*dbg()s in
   dyndbg's _no_desc_ Factory macro.

4. add __drm_debug_enabled (optimized to true) to use behind jumplabel.

5. use _CLS extension of _no_desc_ Factory macro
   this makes cls available to initialize _ddebug.class_id

6. alter drm_*dbg, replacing category with struct _ddebug *desc.
   desc.class_id is category
   desc.flags allows selection of PRINTK or TRACE or both

7. propagate struct _ddebug *desc thru trace_drm_*dbg()
   make all of _ddebug available for filtering

8. add sysfs bitmap to dyndbg, use it to implement drm.debug


D: The "flight-recorder" special instance was unneeded, and is gone:

this handles it generically:

    mkdir instances/flightrec
    echo 1 > instances/flightrec/events/drm/enable
    echo module autopilot +T >/proc/dynamic_debug/control

v10 is here:
https://lore.kernel.org/lkml/20211105192637.2370737-1-jim.cromie at gmail.com/

patches 1-3 are from:
  https://lore.kernel.org/lkml/20200721141105.16034-1-vincent.whitchurch at axis.com/

this patchset addresses goals of:
  https://patchwork.freedesktop.org/series/78133/
  https://lore.kernel.org/lkml/3706af20bc64a320ff8f3ff8950738b988f4bdf5.1636452784.git.quic_saipraka at quicinc.com/


Jim Cromie (19):

1st 3 are basically direct from <vincent.whitchurch at axis.com>
execpt I dropped his printk:dyndbg event:
  dyndbg: add _DPRINTK_FLAGS_ENABLED
  dyndbg: add _DPRINTK_FLAGS_TRACE
  dyndbg: add write-to-tracefs code

add 2 events, and record args (could be squashed)
  dyndbg: add trace-events for pr_debug, dev_dbg
  dyndbg: add desc, dev fields to event record

add field, selection mechanisms, and CLS extensions to Factory macros
  dyndbg: add class_id to callsites

make category fit in .class_id:
  drm_print: condense enum drm_debug_category

repeat trace event addition:
  drm_print: add trace_drm_dbg, trace_drm_devdbg events

kconfig+Make-flag:
  drm_print: add CONFIG_DRM_USE_DYNDBG

macro indirection:
  drm_print: interpose drm_dev_dbg, __drm_dbg with forwarding macros

add >control entries for ~4660 drm.debug callsites:
  drm_print: wrap drm_dev_dbg in _dynamic_func_call_no_desc
  drm_print: wrap drm_dbg in _dynamic_func_call_no_desc

prep:
  drm_print: refine drm_debug_enabled for dyndbg+jump-label

drive-by:
  drm_print: prefer bare printk KERN_DEBUG on generic fn

get .class_id initialized at compile.
  drm_print: use _dynamic_func_call_no_desc_cls

need this to selectively trace/print:
  drm_print: add struct _ddebug desc to drm_dbg, drm_dev_dbg

propagate arg upgrade of HEAD~1 into trace-events:
  drm_print: add struct _ddebug *desc to trace-drm-*() params

add and use sysfs bitmap support:
  dyndbg: add DEFINE_DYNAMIC_DEBUG_CLASSBITS macro and callbacks
  drm_print: use DEFINE_DYNAMIC_DEBUG_CLASSBITS for drm.debug

 .../admin-guide/dynamic-debug-howto.rst       |  12 +
 drivers/gpu/drm/Kconfig                       |  12 +
 drivers/gpu/drm/drm_print.c                   |  66 +++--
 include/drm/drm_print.h                       |  80 +++--
 include/linux/dynamic_debug.h                 | 101 ++++++-
 include/trace/events/drm.h                    |  68 +++++
 include/trace/events/dyndbg.h                 |  74 +++++
 lib/dynamic_debug.c                           | 273 +++++++++++++++---
 8 files changed, 601 insertions(+), 85 deletions(-)
 create mode 100644 include/trace/events/drm.h
 create mode 100644 include/trace/events/dyndbg.h

-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:24 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:24 -0700
Subject: [PATCH v11 01/19] dyndbg: add _DPRINTK_FLAGS_ENABLED
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-2-jim.cromie@gmail.com>

Distinguish the condition: _DPRINTK_FLAGS_ENABLED from the bit:
_DPRINTK_FLAGS_PRINT, in preparation to add _DPRINTK_FLAGS_TRACE next.
Also add a 'K' to get _DPRINTK_FLAGS_PRINTK, to insure is not used
elsewhere with a stale meaning.

CC: vincent.whitchurch at axis.com
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/linux/dynamic_debug.h | 10 ++++++----
 lib/dynamic_debug.c           |  8 ++++----
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index dce631e678dd..257a7bcbbe36 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -27,7 +27,7 @@ struct _ddebug {
 	 * writes commands to <debugfs>/dynamic_debug/control
 	 */
 #define _DPRINTK_FLAGS_NONE	0
-#define _DPRINTK_FLAGS_PRINT	(1<<0) /* printk() a message using the format */
+#define _DPRINTK_FLAGS_PRINTK	(1<<0) /* printk() a message using the format */
 #define _DPRINTK_FLAGS_INCL_MODNAME	(1<<1)
 #define _DPRINTK_FLAGS_INCL_FUNCNAME	(1<<2)
 #define _DPRINTK_FLAGS_INCL_LINENO	(1<<3)
@@ -37,8 +37,10 @@ struct _ddebug {
 	(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 	 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
+#define _DPRINTK_FLAGS_ENABLED		_DPRINTK_FLAGS_PRINTK
+
 #if defined DEBUG
-#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
+#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
 #else
 #define _DPRINTK_FLAGS_DEFAULT 0
 #endif
@@ -120,10 +122,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #ifdef DEBUG
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-	likely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+	likely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #else
 #define DYNAMIC_DEBUG_BRANCH(descriptor) \
-	unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)
+	unlikely(descriptor.flags & _DPRINTK_FLAGS_ENABLED)
 #endif
 
 #endif /* CONFIG_JUMP_LABEL */
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index dd7f56af9aed..78a2912976c1 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -86,7 +86,7 @@ static inline const char *trim_prefix(const char *path)
 }
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
-	{ _DPRINTK_FLAGS_PRINT, 'p' },
+	{ _DPRINTK_FLAGS_PRINTK, 'p' },
 	{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
 	{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
 	{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -210,10 +210,10 @@ static int ddebug_change(const struct ddebug_query *query,
 			if (newflags == dp->flags)
 				continue;
 #ifdef CONFIG_JUMP_LABEL
-			if (dp->flags & _DPRINTK_FLAGS_PRINT) {
-				if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
+			if (dp->flags & _DPRINTK_FLAGS_ENABLED) {
+				if (!(modifiers->flags & _DPRINTK_FLAGS_ENABLED))
 					static_branch_disable(&dp->key.dd_key_true);
-			} else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
+			} else if (modifiers->flags & _DPRINTK_FLAGS_ENABLED)
 				static_branch_enable(&dp->key.dd_key_true);
 #endif
 			dp->flags = newflags;
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:25 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:25 -0700
Subject: [PATCH v11 02/19] dyndbg: add _DPRINTK_FLAGS_TRACE
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-3-jim.cromie@gmail.com>

add new flag, and OR it into _DPRINTK_FLAGS_ENABLED definition

CC: vincent.whitchurch at axis.com
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/linux/dynamic_debug.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index 257a7bcbbe36..e0c2d7c0938b 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -37,7 +37,9 @@ struct _ddebug {
 	(_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
 	 _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID)
 
-#define _DPRINTK_FLAGS_ENABLED		_DPRINTK_FLAGS_PRINTK
+#define _DPRINTK_FLAGS_TRACE		(1<<5)
+#define _DPRINTK_FLAGS_ENABLED		(_DPRINTK_FLAGS_PRINTK | \
+					 _DPRINTK_FLAGS_TRACE)
 
 #if defined DEBUG
 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINTK
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:26 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:26 -0700
Subject: [PATCH v11 03/19] dyndbg: add write-to-tracefs code
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-4-jim.cromie@gmail.com>

adds: dynamic_trace()
 uses trace_console() temporarily to issue printk:console event
 uses internal-ish __ftrace_trace_stack code:
      4-context buffer stack, barriers per Steve

call it from new funcs:
  dynamic_printk() - print to both syslog/tracefs
  dynamic_dev_printk() - dev-print to both syslog/tracefs

These handle both _DPRINTK_FLAGS_PRINTK and _DPRINTK_FLAGS_TRACE
cases, allowing to vsnprintf the message once and use it for both,
skipping past the KERN_DEBUG character for tracing.

Finally, adjust the callers: __dynamic_{pr_debug,{,net,ib}dev_dbg},
replacing printk and dev_printk with the new funcs above.

The _DPRINTK_FLAGS_TRACE flag character s 'T', so the following finds
all callsites enabled for tracing:

  grep -P =p?T /proc/dynamic_debug/control

Enabling debug-to-tracefs is 2 steps:

  # event enable
  echo 1 > /sys/kernel/tracing/events/dyndbg/enable
  # callsite enable
  echo module foo +T > /proc/dynamic_debug/control

This patch,~1,~2 are based upon:
  https://lore.kernel.org/lkml/20200825153338.17061-1-vincent.whitchurch at axis.com/

.. with simplification of temporarily reusing trace_console() rather
than adding a new printk:dyndbg event.  Soon, add 2 new events
capturing the pr_debug & dev_dbg() args.

CC: vincent.whitchurch at axis.com
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 .../admin-guide/dynamic-debug-howto.rst       |   1 +
 lib/dynamic_debug.c                           | 155 +++++++++++++++---
 2 files changed, 130 insertions(+), 26 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index a89cfa083155..3c8f104a143f 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -228,6 +228,7 @@ of the characters::
 The flags are::
 
   p    enables the pr_debug() callsite.
+  T    enables callsite to issue a dyndbg:* trace-event
   f    Include the function name in the printed message
   l    Include line number in the printed message
   m    Include module name in the printed message
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 78a2912976c1..3fd035cd4653 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -36,6 +36,7 @@
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/netdevice.h>
+#include <trace/events/printk.h>
 
 #include <rdma/ib_verbs.h>
 
@@ -87,6 +88,7 @@ static inline const char *trim_prefix(const char *path)
 
 static struct { unsigned flag:8; char opt_char; } opt_array[] = {
 	{ _DPRINTK_FLAGS_PRINTK, 'p' },
+	{ _DPRINTK_FLAGS_TRACE, 'T' },
 	{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
 	{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
 	{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
@@ -628,6 +630,96 @@ static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
 	return buf;
 }
 
+/*
+ * This code is heavily based on __ftrace_trace_stack().
+ *
+ * Allow 4 levels of nesting: normal, softirq, irq, NMI.
+ */
+#define DYNAMIC_TRACE_NESTING	4
+
+struct dynamic_trace_buf {
+	char buf[256];
+};
+
+struct dynamic_trace_bufs {
+	struct dynamic_trace_buf bufs[DYNAMIC_TRACE_NESTING];
+};
+
+static DEFINE_PER_CPU(struct dynamic_trace_bufs, dynamic_trace_bufs);
+static DEFINE_PER_CPU(int, dynamic_trace_reserve);
+
+static void dynamic_trace(const char *fmt, va_list args)
+{
+	struct dynamic_trace_buf *buf;
+	int bufidx;
+	int len;
+
+	preempt_disable_notrace();
+
+	bufidx = __this_cpu_inc_return(dynamic_trace_reserve) - 1;
+
+	if (WARN_ON_ONCE(bufidx > DYNAMIC_TRACE_NESTING))
+		goto out;
+
+	/* For the same reasons as in __ftrace_trace_stack(). */
+	barrier();
+
+	buf = this_cpu_ptr(dynamic_trace_bufs.bufs) + bufidx;
+
+	len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
+	trace_console(buf->buf, len);
+
+out:
+	/* As above. */
+	barrier();
+	__this_cpu_dec(dynamic_trace_reserve);
+	preempt_enable_notrace();
+}
+
+static void dynamic_printk(unsigned int flags, const char *fmt, ...)
+{
+	if (flags & _DPRINTK_FLAGS_TRACE) {
+		va_list args;
+
+		va_start(args, fmt);
+		/*
+		 * All callers include the KERN_DEBUG prefix to keep the
+		 * vprintk case simple; strip it out for tracing.
+		 */
+		dynamic_trace(fmt + strlen(KERN_DEBUG), args);
+		va_end(args);
+	}
+
+	if (flags & _DPRINTK_FLAGS_PRINTK) {
+		va_list args;
+
+		va_start(args, fmt);
+		vprintk(fmt, args);
+		va_end(args);
+	}
+}
+
+static void dynamic_dev_printk(unsigned int flags, const struct device *dev,
+			       const char *fmt, ...)
+{
+
+	if (flags & _DPRINTK_FLAGS_TRACE) {
+		va_list args;
+
+		va_start(args, fmt);
+		dynamic_trace(fmt, args);
+		va_end(args);
+	}
+
+	if (flags & _DPRINTK_FLAGS_PRINTK) {
+		va_list args;
+
+		va_start(args, fmt);
+		dev_vprintk_emit(LOGLEVEL_DEBUG, dev, fmt, args);
+		va_end(args);
+	}
+}
+
 void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 {
 	va_list args;
@@ -642,7 +734,8 @@ void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 	vaf.fmt = fmt;
 	vaf.va = &args;
 
-	printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
+	dynamic_printk(descriptor->flags, KERN_DEBUG "%s%pV",
+		       dynamic_emit_prefix(descriptor, buf), &vaf);
 
 	va_end(args);
 }
@@ -652,6 +745,7 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,
 		      const struct device *dev, const char *fmt, ...)
 {
 	struct va_format vaf;
+	unsigned int flags;
 	va_list args;
 
 	BUG_ON(!descriptor);
@@ -661,16 +755,18 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,
 
 	vaf.fmt = fmt;
 	vaf.va = &args;
+	flags = descriptor->flags;
 
 	if (!dev) {
-		printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
+		dynamic_printk(flags, KERN_DEBUG "(NULL device *): %pV",
+			       &vaf);
 	} else {
 		char buf[PREFIX_SIZE] = "";
 
-		dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
-				dynamic_emit_prefix(descriptor, buf),
-				dev_driver_string(dev), dev_name(dev),
-				&vaf);
+		dynamic_dev_printk(flags, dev, "%s%s %s: %pV",
+				   dynamic_emit_prefix(descriptor, buf),
+				   dev_driver_string(dev), dev_name(dev),
+				   &vaf);
 	}
 
 	va_end(args);
@@ -683,6 +779,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
 			  const struct net_device *dev, const char *fmt, ...)
 {
 	struct va_format vaf;
+	unsigned int flags;
 	va_list args;
 
 	BUG_ON(!descriptor);
@@ -692,22 +789,24 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
 
 	vaf.fmt = fmt;
 	vaf.va = &args;
+	flags = descriptor->flags;
 
 	if (dev && dev->dev.parent) {
 		char buf[PREFIX_SIZE] = "";
 
-		dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
-				"%s%s %s %s%s: %pV",
-				dynamic_emit_prefix(descriptor, buf),
-				dev_driver_string(dev->dev.parent),
-				dev_name(dev->dev.parent),
-				netdev_name(dev), netdev_reg_state(dev),
-				&vaf);
+		dynamic_dev_printk(flags, dev->dev.parent,
+				   "%s%s %s %s%s: %pV",
+				   dynamic_emit_prefix(descriptor, buf),
+				   dev_driver_string(dev->dev.parent),
+				   dev_name(dev->dev.parent),
+				   netdev_name(dev), netdev_reg_state(dev),
+				   &vaf);
 	} else if (dev) {
-		printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
-		       netdev_reg_state(dev), &vaf);
+		dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
+			       netdev_name(dev), netdev_reg_state(dev), &vaf);
 	} else {
-		printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
+		dynamic_printk(flags, KERN_DEBUG "(NULL net_device): %pV",
+			       &vaf);
 	}
 
 	va_end(args);
@@ -723,29 +822,33 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 {
 	struct va_format vaf;
 	va_list args;
+	unsigned int flags;
 
 	va_start(args, fmt);
 
 	vaf.fmt = fmt;
 	vaf.va = &args;
+	flags = descriptor->flags;
 
 	if (ibdev && ibdev->dev.parent) {
 		char buf[PREFIX_SIZE] = "";
 
-		dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
-				"%s%s %s %s: %pV",
-				dynamic_emit_prefix(descriptor, buf),
-				dev_driver_string(ibdev->dev.parent),
-				dev_name(ibdev->dev.parent),
-				dev_name(&ibdev->dev),
-				&vaf);
+		dynamic_dev_printk(flags, ibdev->dev.parent,
+				   "%s%s %s %s: %pV",
+				   dynamic_emit_prefix(descriptor, buf),
+				   dev_driver_string(ibdev->dev.parent),
+				   dev_name(ibdev->dev.parent),
+				   dev_name(&ibdev->dev),
+				   &vaf);
 	} else if (ibdev) {
-		printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
+		dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
+			       dev_name(&ibdev->dev), &vaf);
 	} else {
-		printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
+		dynamic_printk(flags, KERN_DEBUG "(NULL ip_device): %pV",
+			       &vaf);
 	}
 
-	va_end(args);
+va_end(args);
 }
 EXPORT_SYMBOL(__dynamic_ibdev_dbg);
 
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:27 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:27 -0700
Subject: [PATCH v11 04/19] dyndbg: add trace-events for pr_debug, dev_dbg
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-5-jim.cromie@gmail.com>

In commit HEAD~1, pr_debug temporarily issued a printk:console event.
Replace that use with 2 new events:

  bash-5.1# ls events/dyndbg/
  devdbg  enable  filter  prdbg

..called from pr_debug(), dev_dbg() respectively for dyndbg builds.

This links the old pr_debug API to tracefs, via dyndbg, allowing
pr_debug()s etc to add just a little more user-context to the
trace-logs, and then at users option, less syslog.

The 2 trace_* calls accept their caller's args respectively, keeping
the available info w/o alteration; ISTM this is the best basis to add
filtering later.

1- struct _ddebug *descriptor, giving tracefs all of dyndbg's info.
2- struct device *dev, for trace_devdbg(), if !!dev

To pass the descriptor into the trace_*() calls, the callchain up to
__dynamic_{pr_debug,{dev,netdev,ibdev}_dbg} are altered to provide it.

The 2nd event also gets the struct device *dev if !!dev, otherwise a
trace_prdbg() is issued, since we have an event for that, and don't
need to waste the trace-buffer space.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/trace/events/dyndbg.h | 67 +++++++++++++++++++++++++++++++++++
 lib/dynamic_debug.c           | 53 ++++++++++++++-------------
 2 files changed, 96 insertions(+), 24 deletions(-)
 create mode 100644 include/trace/events/dyndbg.h

diff --git a/include/trace/events/dyndbg.h b/include/trace/events/dyndbg.h
new file mode 100644
index 000000000000..82620b10e968
--- /dev/null
+++ b/include/trace/events/dyndbg.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dyndbg
+
+#if !defined(_TRACE_DYNDBG_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DYNDBG_H
+
+#include <linux/tracepoint.h>
+
+/* capture pr_debug() callsite descriptor and message */
+TRACE_EVENT(prdbg,
+	TP_PROTO(const struct _ddebug *desc, const char *text, size_t len),
+
+	TP_ARGS(desc, text, len),
+
+	TP_STRUCT__entry(
+		__dynamic_array(char, msg, len + 1)
+	),
+
+	TP_fast_assign(
+		/*
+		 * Each trace entry is printed in a new line.
+		 * If the msg finishes with '\n', cut it off
+		 * to avoid blank lines in the trace.
+		 */
+		if ((len > 0) && (text[len-1] == '\n'))
+			len -= 1;
+
+		memcpy(__get_str(msg), text, len);
+		__get_str(msg)[len] = 0;
+	),
+
+	TP_printk("%s", __get_str(msg))
+
+);
+
+/* capture dev_dbg() callsite descriptor, device, and message */
+TRACE_EVENT(devdbg,
+	TP_PROTO(const struct _ddebug *desc, const struct device *dev,
+		 const char *text, size_t len),
+
+	TP_ARGS(desc, dev, text, len),
+
+	TP_STRUCT__entry(
+		__dynamic_array(char, msg, len + 1)
+	),
+
+	TP_fast_assign(
+		/*
+		 * Each trace entry is printed in a new line.
+		 * If the msg finishes with '\n', cut it off
+		 * to avoid blank lines in the trace.
+		 */
+		if ((len > 0) && (text[len-1] == '\n'))
+			len -= 1;
+
+		memcpy(__get_str(msg), text, len);
+		__get_str(msg)[len] = 0;
+	),
+
+	TP_printk("%s", __get_str(msg))
+);
+
+#endif /* _TRACE_DYNDBG_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 3fd035cd4653..2efdc4f1553f 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -36,7 +36,9 @@
 #include <linux/sched.h>
 #include <linux/device.h>
 #include <linux/netdevice.h>
-#include <trace/events/printk.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/dyndbg.h>
 
 #include <rdma/ib_verbs.h>
 
@@ -648,7 +650,8 @@ struct dynamic_trace_bufs {
 static DEFINE_PER_CPU(struct dynamic_trace_bufs, dynamic_trace_bufs);
 static DEFINE_PER_CPU(int, dynamic_trace_reserve);
 
-static void dynamic_trace(const char *fmt, va_list args)
+static void dynamic_trace(struct _ddebug *desc, const struct device *dev,
+			  const char *fmt, va_list args)
 {
 	struct dynamic_trace_buf *buf;
 	int bufidx;
@@ -667,7 +670,11 @@ static void dynamic_trace(const char *fmt, va_list args)
 	buf = this_cpu_ptr(dynamic_trace_bufs.bufs) + bufidx;
 
 	len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
-	trace_console(buf->buf, len);
+
+	if (dev == NULL)
+		trace_prdbg(desc, buf->buf, len);
+	else
+		trace_devdbg(desc, dev, buf->buf, len);
 
 out:
 	/* As above. */
@@ -676,9 +683,9 @@ static void dynamic_trace(const char *fmt, va_list args)
 	preempt_enable_notrace();
 }
 
-static void dynamic_printk(unsigned int flags, const char *fmt, ...)
+static void dynamic_printk(struct _ddebug *desc, const char *fmt, ...)
 {
-	if (flags & _DPRINTK_FLAGS_TRACE) {
+	if (desc->flags & _DPRINTK_FLAGS_TRACE) {
 		va_list args;
 
 		va_start(args, fmt);
@@ -686,11 +693,11 @@ static void dynamic_printk(unsigned int flags, const char *fmt, ...)
 		 * All callers include the KERN_DEBUG prefix to keep the
 		 * vprintk case simple; strip it out for tracing.
 		 */
-		dynamic_trace(fmt + strlen(KERN_DEBUG), args);
+		dynamic_trace(desc, NULL, fmt + strlen(KERN_DEBUG), args);
 		va_end(args);
 	}
 
-	if (flags & _DPRINTK_FLAGS_PRINTK) {
+	if (desc->flags & _DPRINTK_FLAGS_PRINTK) {
 		va_list args;
 
 		va_start(args, fmt);
@@ -699,19 +706,19 @@ static void dynamic_printk(unsigned int flags, const char *fmt, ...)
 	}
 }
 
-static void dynamic_dev_printk(unsigned int flags, const struct device *dev,
+static void dynamic_dev_printk(struct _ddebug *desc, const struct device *dev,
 			       const char *fmt, ...)
 {
 
-	if (flags & _DPRINTK_FLAGS_TRACE) {
+	if (desc->flags & _DPRINTK_FLAGS_TRACE) {
 		va_list args;
 
 		va_start(args, fmt);
-		dynamic_trace(fmt, args);
+		dynamic_trace(desc, dev, fmt, args);
 		va_end(args);
 	}
 
-	if (flags & _DPRINTK_FLAGS_PRINTK) {
+	if (desc->flags & _DPRINTK_FLAGS_PRINTK) {
 		va_list args;
 
 		va_start(args, fmt);
@@ -734,7 +741,7 @@ void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
 	vaf.fmt = fmt;
 	vaf.va = &args;
 
-	dynamic_printk(descriptor->flags, KERN_DEBUG "%s%pV",
+	dynamic_printk(descriptor, KERN_DEBUG "%s%pV",
 		       dynamic_emit_prefix(descriptor, buf), &vaf);
 
 	va_end(args);
@@ -745,7 +752,6 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,
 		      const struct device *dev, const char *fmt, ...)
 {
 	struct va_format vaf;
-	unsigned int flags;
 	va_list args;
 
 	BUG_ON(!descriptor);
@@ -755,15 +761,14 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,
 
 	vaf.fmt = fmt;
 	vaf.va = &args;
-	flags = descriptor->flags;
 
 	if (!dev) {
-		dynamic_printk(flags, KERN_DEBUG "(NULL device *): %pV",
+		dynamic_printk(descriptor, KERN_DEBUG "(NULL device *): %pV",
 			       &vaf);
 	} else {
 		char buf[PREFIX_SIZE] = "";
 
-		dynamic_dev_printk(flags, dev, "%s%s %s: %pV",
+		dynamic_dev_printk(descriptor, dev, "%s%s %s: %pV",
 				   dynamic_emit_prefix(descriptor, buf),
 				   dev_driver_string(dev), dev_name(dev),
 				   &vaf);
@@ -794,7 +799,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
 	if (dev && dev->dev.parent) {
 		char buf[PREFIX_SIZE] = "";
 
-		dynamic_dev_printk(flags, dev->dev.parent,
+		dynamic_dev_printk(descriptor, dev->dev.parent,
 				   "%s%s %s %s%s: %pV",
 				   dynamic_emit_prefix(descriptor, buf),
 				   dev_driver_string(dev->dev.parent),
@@ -802,10 +807,10 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
 				   netdev_name(dev), netdev_reg_state(dev),
 				   &vaf);
 	} else if (dev) {
-		dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
-			       netdev_name(dev), netdev_reg_state(dev), &vaf);
+		dynamic_dev_printk(descriptor, &dev->dev, KERN_DEBUG "%s%s: %pV",
+				   netdev_name(dev), netdev_reg_state(dev), &vaf);
 	} else {
-		dynamic_printk(flags, KERN_DEBUG "(NULL net_device): %pV",
+		dynamic_printk(descriptor, KERN_DEBUG "(NULL net_device): %pV",
 			       &vaf);
 	}
 
@@ -833,7 +838,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 	if (ibdev && ibdev->dev.parent) {
 		char buf[PREFIX_SIZE] = "";
 
-		dynamic_dev_printk(flags, ibdev->dev.parent,
+		dynamic_dev_printk(descriptor, ibdev->dev.parent,
 				   "%s%s %s %s: %pV",
 				   dynamic_emit_prefix(descriptor, buf),
 				   dev_driver_string(ibdev->dev.parent),
@@ -841,10 +846,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 				   dev_name(&ibdev->dev),
 				   &vaf);
 	} else if (ibdev) {
-		dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
-			       dev_name(&ibdev->dev), &vaf);
+		dynamic_dev_printk(descriptor, &ibdev->dev, KERN_DEBUG "%s%s: %pV",
+				   dev_name(&ibdev->dev), &vaf);
 	} else {
-		dynamic_printk(flags, KERN_DEBUG "(NULL ip_device): %pV",
+		dynamic_printk(descriptor, KERN_DEBUG "(NULL ip_device): %pV",
 			       &vaf);
 	}
 
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:28 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:28 -0700
Subject: [PATCH v11 05/19] dyndbg: add desc, dev fields to event record
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-6-jim.cromie@gmail.com>

commit:HEAD~1 added pr_debug(), dev_dbg() params to the new events,
but didn't actually capture the params.  Do that now; add the other
TP_* parts: __fields, fast-assign, and printk elements for the
desccriptor and device params.

The message capture part is copied from printk:console, it gets the
whole message, including dyndbg's prefixing: the dev_name() etc, the
optional module:function:line decorations, and the trailing newline
(which is trimmed).

dyndbg->trace-events must be enabled on both sides:

  in tracefs:	echo 1 > /sys/kernel/tracing/events/dyndbg/enable
  in dyndbg:	echo module drm +T > /proc/dynamic_debug/control

This is good; it gives 2 orthogonal cuts at trace traffic, dyndbg can
enable callsites indvidually, tracefs can (in principle) filter and
trigger on the incoming event stream.

ATM, TP_print adds "__entry->desc->{modname,function}", which is
redundant with +Tmf enabled callsites.

RFC

Perhaps the whole decorations/prefix should be excluded from the event
capture ?  Vincent's skip-past-KERN_DEBUG trick could be extended to
skip part or all of the prefix, and leave the "decorating" of events
solely to TP_printk.  Whats the right separation of concerns ?

NB: __entry->desc is a pointer into kernel .data, a pretty stable
reference, at least while the kernel is running.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/trace/events/dyndbg.h | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/include/trace/events/dyndbg.h b/include/trace/events/dyndbg.h
index 82620b10e968..2ac296cb451c 100644
--- a/include/trace/events/dyndbg.h
+++ b/include/trace/events/dyndbg.h
@@ -14,10 +14,12 @@ TRACE_EVENT(prdbg,
 	TP_ARGS(desc, text, len),
 
 	TP_STRUCT__entry(
+		__field(const struct _ddebug *, desc)
 		__dynamic_array(char, msg, len + 1)
 	),
 
 	TP_fast_assign(
+		__entry->desc = desc;
 		/*
 		 * Each trace entry is printed in a new line.
 		 * If the msg finishes with '\n', cut it off
@@ -30,8 +32,8 @@ TRACE_EVENT(prdbg,
 		__get_str(msg)[len] = 0;
 	),
 
-	TP_printk("%s", __get_str(msg))
-
+	TP_printk("%s.%s %s", __entry->desc->modname,
+		  __entry->desc->function, __get_str(msg))
 );
 
 /* capture dev_dbg() callsite descriptor, device, and message */
@@ -42,10 +44,14 @@ TRACE_EVENT(devdbg,
 	TP_ARGS(desc, dev, text, len),
 
 	TP_STRUCT__entry(
+		__field(const struct _ddebug *, desc)
+		__field(const struct device *, dev)
 		__dynamic_array(char, msg, len + 1)
 	),
 
 	TP_fast_assign(
+		__entry->desc = desc;
+		__entry->dev = (struct device *) dev;
 		/*
 		 * Each trace entry is printed in a new line.
 		 * If the msg finishes with '\n', cut it off
@@ -58,7 +64,8 @@ TRACE_EVENT(devdbg,
 		__get_str(msg)[len] = 0;
 	),
 
-	TP_printk("%s", __get_str(msg))
+	TP_printk("%s.%s %s", __entry->desc->modname,
+		  __entry->desc->function, __get_str(msg))
 );
 
 #endif /* _TRACE_DYNDBG_H */
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:29 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:29 -0700
Subject: [PATCH v11 06/19] dyndbg: add class_id to callsites
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-7-jim.cromie@gmail.com>

DRM defines/uses a 10 enum drm_debug_category to create exclusive
classes of debug messages.  To support this directly in dynamic-debug,
add the following:

- struct _ddebug.class_id	4 bits is enough for drm_debug_category

and the query support:

- struct _ddebug_query.class_id
- ddebug_change		- looks for "class" keyword
- parse_class   	- accepts uint: 1-15, sets query->class_id
- vpr_info_dq		- displays new field
- ddebug_proc_show	- append column with "cls:%d"

With this patch, the following cmd is accepted w/o error:

  #> echo module drm class 2 +p > /proc/dynamic_debug/control

It currently does nothing, since no pr_debug callsites can yet be
initialized with class_id != 0.

Note that this is specifically an error:

  #> echo module drm class 0 +p > /proc/dynamic_debug/control

parse_class() prohibits this, we reserve "class 0" as a non-category.
This means that all good inputs are true, and 0 is special.

NOTES:

Patch extends DEFINE_DYNAMIC_DEBUG_METADATA() with a _CLS suffix, and
a new cls param, and re-adds old name using extended name.  Then,
repeats those mods up through the Factory macros that use the
METADATA* .data constructors, so as to actually supply the category
into the initializer.

CC: Rasmus Villemoes <linux at rasmusvillemoes.dk>
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 .../admin-guide/dynamic-debug-howto.rst       | 11 +++++
 include/linux/dynamic_debug.h                 | 41 +++++++++++++------
 lib/dynamic_debug.c                           | 30 ++++++++++++--
 3 files changed, 67 insertions(+), 15 deletions(-)

diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
index 3c8f104a143f..7e1322660b10 100644
--- a/Documentation/admin-guide/dynamic-debug-howto.rst
+++ b/Documentation/admin-guide/dynamic-debug-howto.rst
@@ -35,6 +35,7 @@ Dynamic debug has even more useful features:
    - line number (including ranges of line numbers)
    - module name
    - format string
+   - class number:1-15
 
  * Provides a debugfs control file: ``<debugfs>/dynamic_debug/control``
    which can be read to display the complete list of known debug
@@ -143,6 +144,7 @@ against.  Possible keywords are:::
 		 'module' string |
 		 'format' string |
 		 'line' line-range
+		 'class' integer:[1-15]
 
   line-range ::= lineno |
 		 '-'lineno |
@@ -217,6 +219,15 @@ line
 	line -1605          // the 1605 lines from line 1 to line 1605
 	line 1600-          // all lines from line 1600 to the end of the file
 
+class
+    This expects a single integer, in range: 1-15.
+    Using this specification constrains to exact class_id matches.
+    This is intended for DRM.debug enumerated categories, plus 1.
+    class_id = 0 is reserved, returns an error currently.
+
+    This differs from the others primarily in that it is not displayed
+    in the control file currently, add later as an extra column.
+
 The flags specification comprises a change operation followed
 by one or more flag characters.  The change operation is one
 of the characters::
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e0c2d7c0938b..e9483cd9ac1c 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -20,6 +20,7 @@ struct _ddebug {
 	const char *function;
 	const char *filename;
 	const char *format;
+	unsigned int class_id:4;
 	unsigned int lineno:18;
 	/*
 	 * The flags field controls the behaviour at the callsite.
@@ -91,7 +92,7 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 			 const struct ib_device *ibdev,
 			 const char *fmt, ...);
 
-#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)		\
+#define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)	\
 	static struct _ddebug  __aligned(8)			\
 	__section("__dyndbg") name = {				\
 		.modname = KBUILD_MODNAME,			\
@@ -100,9 +101,13 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 		.format = (fmt),				\
 		.lineno = __LINE__,				\
 		.flags = _DPRINTK_FLAGS_DEFAULT,		\
+		.class_id = cls,				\
 		_DPRINTK_KEY_INIT				\
 	}
 
+#define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt)	\
+	DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, 0, fmt)
+
 #ifdef CONFIG_JUMP_LABEL
 
 #ifdef DEBUG
@@ -132,17 +137,21 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #endif /* CONFIG_JUMP_LABEL */
 
-#define __dynamic_func_call(id, fmt, func, ...) do {	\
-	DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);		\
-	if (DYNAMIC_DEBUG_BRANCH(id))			\
-		func(&id, ##__VA_ARGS__);		\
+#define __dynamic_func_call_cls(id, cls, fmt, func, ...) do {	\
+	DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);	\
+	if (DYNAMIC_DEBUG_BRANCH(id))				\
+		func(&id, ##__VA_ARGS__);			\
 } while (0)
+#define __dynamic_func_call(id, fmt, func, ...)				\
+	__dynamic_func_call_cls(id, 0, fmt, func, ##__VA_ARGS__)
 
-#define __dynamic_func_call_no_desc(id, fmt, func, ...) do {	\
-	DEFINE_DYNAMIC_DEBUG_METADATA(id, fmt);			\
-	if (DYNAMIC_DEBUG_BRANCH(id))				\
-		func(__VA_ARGS__);				\
+#define __dynamic_func_call_no_desc_cls(id, cls, fmt, func, ...) do {	\
+	DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);		\
+	if (DYNAMIC_DEBUG_BRANCH(id))					\
+		func(__VA_ARGS__);					\
 } while (0)
+#define __dynamic_func_call_no_desc(id, fmt, func, ...)			\
+	__dynamic_func_call_no_desc_cls(id, 0, fmt, func, ##__VA_ARGS__)
 
 /*
  * "Factory macro" for generating a call to func, guarded by a
@@ -152,15 +161,23 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  * the varargs. Note that fmt is repeated in invocations of this
  * macro.
  */
+#define _dynamic_func_call_cls(cls, fmt, func, ...)			\
+	__dynamic_func_call_cls(__UNIQUE_ID(ddebug), cls, fmt, func, ##__VA_ARGS__)
 #define _dynamic_func_call(fmt, func, ...)				\
-	__dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+	__dynamic_func_call_cls(__UNIQUE_ID(ddebug), 0, fmt, func, ##__VA_ARGS__)
+
 /*
  * A variant that does the same, except that the descriptor is not
  * passed as the first argument to the function; it is only called
  * with precisely the macro's varargs.
  */
-#define _dynamic_func_call_no_desc(fmt, func, ...)	\
-	__dynamic_func_call_no_desc(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
+#define _dynamic_func_call_no_desc_cls(fmt, eCat, func, ...)		\
+	__dynamic_func_call_no_desc_cls(__UNIQUE_ID(ddebug), eCat,	\
+					fmt, func, ##__VA_ARGS__)
+
+#define _dynamic_func_call_no_desc(fmt, func, ...)		\
+	__dynamic_func_call_no_desc_cls(__UNIQUE_ID(ddebug), 0,	\
+					fmt, func, ##__VA_ARGS__)
 
 #define dynamic_pr_debug(fmt, ...)				\
 	_dynamic_func_call(fmt,	__dynamic_pr_debug,		\
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2efdc4f1553f..419d4664e724 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -58,6 +58,7 @@ struct ddebug_query {
 	const char *function;
 	const char *format;
 	unsigned int first_lineno, last_lineno;
+	unsigned int class_id;
 };
 
 struct ddebug_iter {
@@ -138,13 +139,13 @@ static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
 			fmtlen--;
 	}
 
-	v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
+	v3pr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u class=%u\n",
 		 msg,
 		 query->function ?: "",
 		 query->filename ?: "",
 		 query->module ?: "",
 		 fmtlen, query->format ?: "",
-		 query->first_lineno, query->last_lineno);
+		 query->first_lineno, query->last_lineno, query->class_id);
 }
 
 /*
@@ -174,6 +175,10 @@ static int ddebug_change(const struct ddebug_query *query,
 		for (i = 0; i < dt->num_ddebugs; i++) {
 			struct _ddebug *dp = &dt->ddebugs[i];
 
+			/* match against the class_id, if > 0 */
+			if (query->class_id && query->class_id != dp->class_id)
+				continue;
+
 			/* match against the source filename */
 			if (query->filename &&
 			    !match_wildcard(query->filename, dp->filename) &&
@@ -310,6 +315,22 @@ static inline int parse_lineno(const char *str, unsigned int *val)
 	}
 	return 0;
 }
+/*
+ * class_id is 0-15. 0 is default, is nonsense in active search
+ */
+static inline int parse_class(struct ddebug_query *query, const char *str)
+{
+	int rc;
+	unsigned int val;
+
+	rc = kstrtouint(str, 10, &val);
+	if (rc < 0 || !val || val > 15) {
+		pr_err("expecting class:[1-15], not %s\n", str);
+		return -EINVAL;
+	}
+	query->class_id = val;
+	return 0;
+}
 
 static int parse_linerange(struct ddebug_query *query, const char *first)
 {
@@ -424,6 +445,9 @@ static int ddebug_parse_query(char *words[], int nwords,
 		} else if (!strcmp(keyword, "line")) {
 			if (parse_linerange(query, arg))
 				return -EINVAL;
+		} else if (!strcmp(keyword, "class")) {
+			if (parse_class(query, arg))
+				return -EINVAL;
 		} else {
 			pr_err("unknown keyword \"%s\"\n", keyword);
 			return -EINVAL;
@@ -1007,7 +1031,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p)
 		   iter->table->mod_name, dp->function,
 		   ddebug_describe_flags(dp->flags, &flags));
 	seq_escape(m, dp->format, "\t\r\n\"");
-	seq_puts(m, "\"\n");
+	seq_printf(m, "\" cls:%u\n", dp->class_id);
 
 	return 0;
 }
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:30 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:30 -0700
Subject: [PATCH v11 07/19] drm_print: condense enum drm_debug_category
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-8-jim.cromie@gmail.com>

enum drm_debug_category has 10 hardcoded values, which could be
"simplified" as sequential BIT(x)s.  But lets take it one step
further, removing the explicit initializations (other than starting at
1), and move the BIT() operation into drm_debug_enabled().

This gives us a more compact representation (4 bits), without loss of
info; all DRM.debug api calls pass an enum parameter (and not a bit-OR
of them), and the bitmask-iness of the enum's values is merely a
micro-optimization to avoid doing BIT(category) at runtime.  I doubt
the extra bit-shift would be measurable here.

And the 4-bit representation means it fits into struct
_ddebug.class_id (commit:HEAD~1), setting up for further integration.

The enum starts at 1, which respects the "reservation" of 0 as a
special case; it is a non-category, and shouldn't get treated like one.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/drm/drm_print.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 22fabdeed297..b4355bfd7888 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -279,49 +279,49 @@ enum drm_debug_category {
 	 * @DRM_UT_CORE: Used in the generic drm code: drm_ioctl.c, drm_mm.c,
 	 * drm_memory.c, ...
 	 */
-	DRM_UT_CORE		= 0x01,
+	DRM_UT_CORE = 1,
 	/**
 	 * @DRM_UT_DRIVER: Used in the vendor specific part of the driver: i915,
 	 * radeon, ... macro.
 	 */
-	DRM_UT_DRIVER		= 0x02,
+	DRM_UT_DRIVER,
 	/**
 	 * @DRM_UT_KMS: Used in the modesetting code.
 	 */
-	DRM_UT_KMS		= 0x04,
+	DRM_UT_KMS,
 	/**
 	 * @DRM_UT_PRIME: Used in the prime code.
 	 */
-	DRM_UT_PRIME		= 0x08,
+	DRM_UT_PRIME,
 	/**
 	 * @DRM_UT_ATOMIC: Used in the atomic code.
 	 */
-	DRM_UT_ATOMIC		= 0x10,
+	DRM_UT_ATOMIC,
 	/**
 	 * @DRM_UT_VBL: Used for verbose debug message in the vblank code.
 	 */
-	DRM_UT_VBL		= 0x20,
+	DRM_UT_VBL,
 	/**
 	 * @DRM_UT_STATE: Used for verbose atomic state debugging.
 	 */
-	DRM_UT_STATE		= 0x40,
+	DRM_UT_STATE,
 	/**
 	 * @DRM_UT_LEASE: Used in the lease code.
 	 */
-	DRM_UT_LEASE		= 0x80,
+	DRM_UT_LEASE,
 	/**
 	 * @DRM_UT_DP: Used in the DP code.
 	 */
-	DRM_UT_DP		= 0x100,
+	DRM_UT_DP,
 	/**
 	 * @DRM_UT_DRMRES: Used in the drm managed resources code.
 	 */
-	DRM_UT_DRMRES		= 0x200,
+	DRM_UT_DRMRES
 };
 
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
-	return unlikely(__drm_debug & category);
+	return unlikely(__drm_debug & BIT(category));
 }
 
 /*
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:31 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:31 -0700
Subject: [PATCH v11 08/19] drm_print: add trace_drm_dbg,
 trace_drm_devdbg events
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-9-jim.cromie@gmail.com>

__drm_debug() and __drm_dev_dbg() currently printk to syslog.  These 2
underlay the vast bulk of DRM.debug api calls; they are a significant
source of debugging info, and could add useful context to debug traces.

Wire them to emit 2 new trace_*() events: drm_prdbg and drm_devdbg.

These events keep the args of those 2 callers:
- int/enum category, va_format *vaf
- struct device *dev, int/enum category, va_format *vaf

ISTM best to reflect args thru w/o altering; it is simple, least
surprising, and preserves info for possible filtering/selecting
events.

NOTES:

trace_*() additions are strictly redundant with printks to syslog, not
properly placed to reduce overall work.

Reuses trim-trailing-newline trick on vnsprintf

TLDR: The event called by __drm_dev_dbg() depends upon !!dev; theres
little value to storing a null in the trace. Yes, one could know that
devdbg was called with a null, but is that worthwhile ?  And if you
really needed to know the call (not available from control-file
format) the file:line gets you there.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 13 +++++--
 include/trace/events/drm.h  | 68 +++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/drm.h

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index f783d4963d4b..cfcb89ffd89d 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -36,6 +36,9 @@
 #include <drm/drm_drv.h>
 #include <drm/drm_print.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/drm.h>
+
 /*
  * __drm_debug: Enable debug output.
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
@@ -269,13 +272,15 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	vaf.fmt = format;
 	vaf.va = &args;
 
-	if (dev)
+	if (dev) {
 		dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
 			   __builtin_return_address(0), &vaf);
-	else
+		trace_drm_devdbg(dev, category, &vaf);
+	} else {
 		printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 		       __builtin_return_address(0), &vaf);
-
+		trace_drm_debug(category, &vaf);
+	}
 	va_end(args);
 }
 EXPORT_SYMBOL(drm_dev_dbg);
@@ -295,6 +300,8 @@ void __drm_dbg(enum drm_debug_category category, const char *format, ...)
 	printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 	       __builtin_return_address(0), &vaf);
 
+	trace_drm_debug(category, &vaf);
+
 	va_end(args);
 }
 EXPORT_SYMBOL(__drm_dbg);
diff --git a/include/trace/events/drm.h b/include/trace/events/drm.h
new file mode 100644
index 000000000000..944aedaf6aa6
--- /dev/null
+++ b/include/trace/events/drm.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm
+
+#if !defined(_TRACE_DRM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_DRM_H
+
+#include <linux/tracepoint.h>
+
+/* drm_debug() was called, pass its args */
+TRACE_EVENT(drm_debug,
+	TP_PROTO(int drm_debug_category, struct va_format *vaf),
+
+	TP_ARGS(drm_debug_category, vaf),
+
+	TP_STRUCT__entry(
+		__field(int, drm_debug_category)
+		__dynamic_array(char, msg, 256)
+	),
+
+	TP_fast_assign(
+		int len;
+
+		__entry->drm_debug_category = drm_debug_category;
+		vsnprintf(__get_str(msg), 256, vaf->fmt, *vaf->va);
+
+		len = strlen(__get_str(msg));
+		if ((len > 0) && (__get_str(msg)[len-1] == '\n'))
+			len -= 1;
+		__get_str(msg)[len] = 0;
+	),
+
+	TP_printk("%s", __get_str(msg))
+);
+
+/* drm_devdbg() was called, pass its args, preserving order */
+TRACE_EVENT(drm_devdbg,
+	TP_PROTO(const struct device *dev, int drm_debug_category, struct va_format *vaf),
+
+	TP_ARGS(dev, drm_debug_category, vaf),
+
+	TP_STRUCT__entry(
+		__field(const struct device*, dev)
+		__field(int, drm_debug_category)
+		__dynamic_array(char, msg, 256)
+	),
+
+	TP_fast_assign(
+		int len;
+
+		__entry->drm_debug_category = drm_debug_category;
+		__entry->dev = dev;
+		vsnprintf(__get_str(msg), 256, vaf->fmt, *vaf->va);
+
+		len = strlen(__get_str(msg));
+		if ((len > 0) && (__get_str(msg)[len-1] == '\n'))
+			len -= 1;
+		__get_str(msg)[len] = 0;
+	),
+
+	TP_printk("cat:%d, %s %s", __entry->drm_debug_category,
+		  dev_name(__entry->dev), __get_str(msg))
+);
+
+#endif /* _TRACE_DRM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:32 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:32 -0700
Subject: [PATCH v11 09/19] drm_print: add CONFIG_DRM_USE_DYNAMIC_DEBUG
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-10-jim.cromie@gmail.com>

DRM.debug API is used thousands of times in drivers/gpu/drm/*; when
these are implemented using dynamic-debug, DYNAMIC_DEBUG_METADATA adds
a struct _ddebug (56 bytes) per site.

Since i915 will have ~2k callsites, and amdgpu ~4k, the memory costs
are substantial, and thus made configurable.

For a baseline:
bash-5.1# drms_load
[   10.923093] dyndbg:   1 debug prints in module drm
[   10.928345] ACPI: bus type drm_connector registered
[   11.034012] dyndbg:   2 debug prints in module ttm
[   11.038188] dyndbg:   8 debug prints in module video
[   11.551064] dyndbg: 127 debug prints in module i915
[   11.617106] AMD-Vi: AMD IOMMUv2 functionality not available on this system - This is not a bug.
[   12.084856] dyndbg: 2196 debug prints in module amdgpu
[   12.099040] [drm] amdgpu kernel modesetting enabled.
[   12.099790] amdgpu: CRAT table not found
[   12.100523] amdgpu: Virtual CRAT table created for CPU
[   12.100901] amdgpu: Topology: Add CPU node
[   12.165382] dyndbg:   3 debug prints in module wmi
[   12.356424] dyndbg:   3 debug prints in module nouveau

i915/gvt has pr_debugs that show up here
amdgpu has many pr_debugs from macro expansions

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>

fixup-mk
---
 drivers/gpu/drm/Kconfig  | 12 ++++++++++++
 drivers/gpu/drm/Makefile |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 0039df26854b..4e7b865c3441 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -62,6 +62,18 @@ config DRM_DEBUG_MM
 
 	  If in doubt, say "N".
 
+config DRM_USE_DYNAMIC_DEBUG
+	bool "use dynamic debug to implement drm.debug"
+	default y
+	depends on DRM
+	depends on DYNAMIC_DEBUG || DYNAMIC_DEBUG_CORE
+	depends on JUMP_LABEL
+	help
+	  Use dynamic-debug to avoid drm_debug_enabled() runtime overheads.
+	  Due to callsite counts in DRM drivers (~4k in amdgpu) and 56
+	  bytes per callsite, the .data costs can be substantial, and
+	  are therefore configurable.
+
 config DRM_DEBUG_SELFTEST
 	tristate "kselftests for DRM"
 	depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0dff40bb863c..60f4d7bc27eb 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -3,6 +3,8 @@
 # Makefile for the drm device driver.  This driver provides support for the
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
+CFLAGS-$(CONFIG_DRM_USE_DYNAMIC_DEBUG)	+= -DDYNAMIC_DEBUG_MODULE
+
 drm-y       :=	drm_aperture.o drm_auth.o drm_cache.o \
 		drm_file.o drm_gem.o drm_ioctl.o drm_irq.o \
 		drm_drv.o \
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:33 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:33 -0700
Subject: [PATCH v11 10/19] drm_print: interpose drm_dev_dbg,
 __drm_dbg with forwarding macros
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-11-jim.cromie@gmail.com>

drm_dev_dbg() & _drm_dbg() sit below the categorized layer of the DRM
debug API, and thus implement most of it.  These are good places to
insert dynamic-debug jump-label mechanics, allowing DRM to avoid the
runtime cost of drm_debug_enabled().

Set up for this by changing the func names by adding '__' prefixes,
and define forwarding macros to the new names.

no functional changes.

memory cost baseline: (unchanged)
bash-5.1# drms_load
[    9.220389] dyndbg:   1 debug prints in module drm
[    9.224426] ACPI: bus type drm_connector registered
[    9.302192] dyndbg:   2 debug prints in module ttm
[    9.305033] dyndbg:   8 debug prints in module video
[    9.627563] dyndbg: 127 debug prints in module i915
[    9.721505] AMD-Vi: AMD IOMMUv2 functionality not available on this system - This is not a bug.
[   10.091345] dyndbg: 2196 debug prints in module amdgpu
[   10.106589] [drm] amdgpu kernel modesetting enabled.
[   10.107270] amdgpu: CRAT table not found
[   10.107926] amdgpu: Virtual CRAT table created for CPU
[   10.108398] amdgpu: Topology: Add CPU node
[   10.168507] dyndbg:   3 debug prints in module wmi
[   10.329587] dyndbg:   3 debug prints in module nouveau

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 10 +++++-----
 include/drm/drm_print.h     |  9 +++++++--
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index cfcb89ffd89d..5dd6713c14f2 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -259,8 +259,8 @@ void drm_dev_printk(const struct device *dev, const char *level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-		 const char *format, ...)
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+		   const char *format, ...)
 {
 	struct va_format vaf;
 	va_list args;
@@ -283,9 +283,9 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	}
 	va_end(args);
 }
-EXPORT_SYMBOL(drm_dev_dbg);
+EXPORT_SYMBOL(__drm_dev_dbg);
 
-void __drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
 {
 	struct va_format vaf;
 	va_list args;
@@ -304,7 +304,7 @@ void __drm_dbg(enum drm_debug_category category, const char *format, ...)
 
 	va_end(args);
 }
-EXPORT_SYMBOL(__drm_dbg);
+EXPORT_SYMBOL(___drm_dbg);
 
 void __drm_err(const char *format, ...)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index b4355bfd7888..f8fa5af11310 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -334,7 +334,7 @@ __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
 		    const char *format, ...);
 __printf(3, 4)
-void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
+void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 		 const char *format, ...);
 
 /**
@@ -383,6 +383,9 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	}								\
 })
 
+#define drm_dev_dbg(dev, eCat, fmt, ...)				\
+	__drm_dev_dbg(dev, eCat, fmt, ##__VA_ARGS__)
+
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
  *
@@ -484,10 +487,12 @@ void drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
  */
 
 __printf(2, 3)
-void __drm_dbg(enum drm_debug_category category, const char *format, ...);
+void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#define __drm_dbg(fmt, ...)		___drm_dbg(fmt, ##__VA_ARGS__)
+
 /* Macros to make printk easier */
 
 #define _DRM_PRINTK(once, level, fmt, ...)				\
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:34 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:34 -0700
Subject: [PATCH v11 11/19] drm_print: wrap drm_dev_dbg in
 _dynamic_func_call_no_desc
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-12-jim.cromie@gmail.com>

make drm_dev_dbg() macro CONFIG_DRM_USE_DYNAMIC_DEBUG dependent:

 =N  direct forwarding: drm_dev_dbg -> __drm_dev_dbg()
 =Y  wrap __drm_dev_dbg in _dynamic_func_call_no_desc().

This adds the metadata which creates a /proc/dynamic_debug/control
entry for each callsite, and exposes it for selective enablement.

NB: include header in header so wrapper is available

proof of function:

bash-5.1# grep 'ring test' /proc/dynamic_debug/control
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c:453 [amdgpu]amdgpu_ring_test_helper =xf "ring test on %s succeeded\012"

less
    452         else
    453                 DRM_DEV_DEBUG(adev->dev, "ring test on %s succeeded\n",
    454                               ring->name);
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c lines 417-454/458 byte 12536/12575 100%  (press RETURN)

new prdbg callsite counts:
bash-5.1# drms_load
[   20.533990] dyndbg:   1 debug prints in module drm
[   20.535637] ACPI: bus type drm_connector registered
[   20.624951] dyndbg:   2 debug prints in module ttm
[   20.627853] dyndbg:   8 debug prints in module video
[   20.922442] dyndbg: 127 debug prints in module i915
[   20.984159] AMD-Vi: AMD IOMMUv2 functionality not available on this system - This is not a bug.
[   21.310216] dyndbg: 2196 debug prints in module amdgpu
[   21.324537] [drm] amdgpu kernel modesetting enabled.
[   21.325092] amdgpu: CRAT table not found
[   21.325512] amdgpu: Virtual CRAT table created for CPU
[   21.326009] amdgpu: Topology: Add CPU node
[   21.401137] dyndbg:   3 debug prints in module wmi
[   21.532540] dyndbg:   3 debug prints in module nouveau

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/drm/drm_print.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index f8fa5af11310..1eef315a0a65 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -383,8 +383,14 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	}								\
 })
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, eCat, fmt, ...)				\
 	__drm_dev_dbg(dev, eCat, fmt, ##__VA_ARGS__)
+#else
+#define drm_dev_dbg(dev, eCat, fmt, ...)				\
+	_dynamic_func_call_no_desc(fmt, __drm_dev_dbg,			\
+				   dev, eCat, fmt, ##__VA_ARGS__)
+#endif
 
 /**
  * DRM_DEV_DEBUG() - Debug output for generic drm code
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:35 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:35 -0700
Subject: [PATCH v11 12/19] drm_print: wrap drm_dbg in
 _dynamic_func_call_no_desc
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-13-jim.cromie@gmail.com>

Change __drm_dbg() macro to be CONFIG_DRM_USE_DYNAMIC_DEBUG dependent:
  N- keep straight mapping to exported ___drm_dbg()
  Y- wrap ___drm_dbg() inside _dynamic_func_call_no_desc()

This patch places ~1/2 of drm.debug API messages behind dyndbg's
JUMP_LABEL/NOOP optimization.

The CONFIG_DRM_USE_DYNAMIC_DEBUG dependence is due to the .data
footprint cost of per-callsite control; 56 bytes/site * ~2k,3k
callsites (for i915, amdgpu), which is significant enough to make
optional.

bash-5.1# drms_load
[    7.489844] dyndbg: 239 debug prints in module drm
[    7.494010] ACPI: bus type drm_connector registered
[    7.546076] dyndbg:  81 debug prints in module drm_kms_helper
[    7.555723] dyndbg:   2 debug prints in module ttm
[    7.558920] dyndbg:   8 debug prints in module video
[    8.074699] dyndbg: 431 debug prints in module i915
[    8.158682] AMD-Vi: AMD IOMMUv2 functionality not available on this system - This is not a bug.
[    8.574456] dyndbg: 3817 debug prints in module amdgpu
[    8.589962] [drm] amdgpu kernel modesetting enabled.
[    8.590548] amdgpu: CRAT table not found
[    8.590998] amdgpu: Virtual CRAT table created for CPU
[    8.591634] amdgpu: Topology: Add CPU node
[    8.636446] dyndbg:   3 debug prints in module wmi
[    8.768667] dyndbg:  24 debug prints in module nouveau

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/drm/drm_print.h | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 1eef315a0a65..8d6b74270c50 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -319,10 +319,36 @@ enum drm_debug_category {
 	DRM_UT_DRMRES
 };
 
+/*
+ * 3 name flavors of drm_debug_enabled:
+ *   drm_debug_enabled - public/legacy, always checks bits
+ *  _drm_debug_enabled - instrumented to observe call-rates, est overheads.
+ * __drm_debug_enabled - privileged - knows jump-label state, can short-circuit
+ */
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
 	return unlikely(__drm_debug & BIT(category));
 }
+/*
+ * Wrap fn in macro, so that the pr_debug sees the actual caller, not
+ * the inline fn.  Using this name creates a callsite entry / control
+ * point in /proc/dynamic_debug/control.
+ */
+#define _drm_debug_enabled(category)				\
+	({							\
+		pr_debug("todo: maybe avoid via dyndbg\n");     \
+		drm_debug_enabled(category);			\
+	})
+#if defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+/*
+ * dyndbg is wrapping the drm.debug API, so as to avoid the runtime
+ * bit-test overheads of drm_debug_enabled() in those api calls.
+ * In this case, executed callsites are known enabled, so true.
+ */
+#define __drm_debug_enabled(category)	true
+#else
+#define __drm_debug_enabled(category)	drm_debug_enabled(category)
+#endif
 
 /*
  * struct device based logging
@@ -497,7 +523,13 @@ void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define __drm_dbg(fmt, ...)		___drm_dbg(fmt, ##__VA_ARGS__)
+#else
+#define __drm_dbg(eCat, fmt, ...)					\
+	_dynamic_func_call_no_desc(fmt, ___drm_dbg,			\
+				   eCat, fmt, ##__VA_ARGS__)
+#endif
 
 /* Macros to make printk easier */
 
@@ -569,7 +601,7 @@ void __drm_err(const char *format, ...);
 	static DEFINE_RATELIMIT_STATE(rs_, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);\
 	const struct drm_device *drm_ = (drm);							\
 												\
-	if (drm_debug_enabled(DRM_UT_ ## category) && __ratelimit(&rs_))			\
+	if (__drm_debug_enabled(DRM_UT_ ## category) && __ratelimit(&rs_))			\
 		drm_dev_printk(drm_ ? drm_->dev : NULL, KERN_DEBUG, fmt, ## __VA_ARGS__);	\
 })
 
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:36 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:36 -0700
Subject: [PATCH v11 13/19] drm_print: refine drm_debug_enabled for
 dyndbg+jump-label
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-14-jim.cromie@gmail.com>

In order to use dynamic-debug's jump-label optimization in drm-debug,
its clarifying to refine drm_debug_enabled into 3 uses:

1.   drm_debug_enabled - legacy, public
2. __drm_debug_enabled - optimized for dyndbg jump-label enablement.
3.  _drm_debug_enabled - pr_debug instrumented, observable

1. The legacy version always checks the bits.

2. is privileged, for use by __drm_dbg(), __drm_dev_dbg(), which do an
early return unless the category is enabled (free of call/NOOP side
effects).  For dyndbg builds, debug callsites are selectively
"pre-enabled", so __drm_debug_enabled() short-circuits to true there.
Remaining callers of 1 may be able to use 2, case by case.

3. is 1st wrapped in a macro, with a pr_debug, which reports each
usage in /proc/dynamic_debug/control, making it observable in the
logs.  The macro lets the pr_debug see the real caller, not the inline
function.

When plugged into 1, it identified ~10 remaining callers of the
function, leading to the follow-on cleanup patch, and would allow
activating the pr_debugs, estimating the callrate, and the potential
savings by using the wrapper macro.

It is unused ATM, but it fills out the picture.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 5dd6713c14f2..aab29dd6cad1 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -265,7 +265,7 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	struct va_format vaf;
 	va_list args;
 
-	if (!drm_debug_enabled(category))
+	if (!__drm_debug_enabled(category))
 		return;
 
 	va_start(args, format);
@@ -290,7 +290,7 @@ void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
 	struct va_format vaf;
 	va_list args;
 
-	if (!drm_debug_enabled(category))
+	if (!__drm_debug_enabled(category))
 		return;
 
 	va_start(args, format);
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:37 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:37 -0700
Subject: [PATCH v11 14/19] drm_print: prefer bare printk KERN_DEBUG on generic
 fn
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-15-jim.cromie@gmail.com>

drm_print.c calls pr_debug() just once, from __drm_printfn_debug(),
which is a generic/service fn.  The callsite is compile-time enabled
by DEBUG in both DYNAMIC_DEBUG=y/n builds.

For dyndbg builds, reverting this callsite back to bare printk is
correcting a few anti-features:

1- callsite is generic, serves multiple drm users.
   its hardwired on currently
   could accidentally: #> echo -p > /proc/dynamic_debug/control

2- optional "decorations" by dyndbg are unhelpful/misleading
   they describe only the generic site, not end users

IOW, 1,2 are unhelpful at best, and possibly confusing.

reverting yields a nominal data and text shrink:

   text    data     bss     dec     hex filename
 462583   36604   54592 553779   87333 /lib/modules/5.16.0-rc4-lm1-00008-ged3eac8ceeea/kernel/drivers/gpu/drm/drm.ko
 462515   36532   54592 553639   872a7 /lib/modules/5.16.0-rc4-lm1-00009-g6ce0b88d2539-dirty/kernel/drivers/gpu/drm/drm.ko

NB: this was noticed using _drm_debug_enabled(), added earlier.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index aab29dd6cad1..b911f949af5b 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -23,8 +23,6 @@
  * Rob Clark <robdclark at gmail.com>
  */
 
-#define DEBUG /* for pr_debug() */
-
 #include <linux/stdarg.h>
 
 #include <linux/io.h>
@@ -165,7 +163,8 @@ EXPORT_SYMBOL(__drm_printfn_info);
 
 void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
 {
-	pr_debug("%s %pV", p->prefix, vaf);
+	/* pr_debug callsite decorations are unhelpful here */
+	printk(KERN_DEBUG "%s %pV", p->prefix, vaf);
 }
 EXPORT_SYMBOL(__drm_printfn_debug);
 
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:38 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:38 -0700
Subject: [PATCH v11 15/19] drm_print: use _dynamic_func_call_no_desc_cls
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-16-jim.cromie@gmail.com>

Upgrade the current use of _dynamic_func_call_no_desc(), adding the
suffix and the category arg.  The arg has been available via the
macros implementing the drm.debug api, but dyndbg lacked a simple way
to represent it and use it until recently.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/drm/drm_print.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 8d6b74270c50..0c704610c770 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -31,6 +31,7 @@
 #include <linux/seq_file.h>
 #include <linux/device.h>
 #include <linux/debugfs.h>
+#include <linux/dynamic_debug.h>
 
 #include <drm/drm.h>
 
@@ -414,8 +415,8 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	__drm_dev_dbg(dev, eCat, fmt, ##__VA_ARGS__)
 #else
 #define drm_dev_dbg(dev, eCat, fmt, ...)				\
-	_dynamic_func_call_no_desc(fmt, __drm_dev_dbg,			\
-				   dev, eCat, fmt, ##__VA_ARGS__)
+	_dynamic_func_call_no_desc_cls(fmt, eCat, __drm_dev_dbg,	\
+				       dev, eCat, fmt, ##__VA_ARGS__)
 #endif
 
 /**
@@ -524,11 +525,11 @@ __printf(1, 2)
 void __drm_err(const char *format, ...);
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
-#define __drm_dbg(fmt, ...)		___drm_dbg(fmt, ##__VA_ARGS__)
+#define __drm_dbg(fmt, ...)		___drm_dbg(NULL, fmt, ##__VA_ARGS__)
 #else
 #define __drm_dbg(eCat, fmt, ...)					\
-	_dynamic_func_call_no_desc(fmt, ___drm_dbg,			\
-				   eCat, fmt, ##__VA_ARGS__)
+	_dynamic_func_call_no_desc_cls(fmt, eCat, ___drm_dbg,		\
+				       eCat, fmt, ##__VA_ARGS__)
 #endif
 
 /* Macros to make printk easier */
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:39 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:39 -0700
Subject: [PATCH v11 16/19] drm_print: add struct _ddebug desc to drm_*dbg
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-17-jim.cromie@gmail.com>

A recent commit adding trace-events to drm noted:

   trace_*() additions are strictly redundant with printks to syslog,
   not properly placed to reduce overall work.

That was because it didn't have the struct _ddebug *descriptor, whose
.flags specify TRACE and PRINTK actions on a controlled callsite.  So
it could only duplicate the stream (from the enabled callsites).

To issue TRACE, PRINTK selectively:

- add struct _ddebug * param to prototypes and functions:
  ___drm_dbg(), __drm_dev_dbg()
  add "struct _ddebug;" to name the ptr-type, to silence warning.

- adjust the forwarding macros: drm_dbg, drm_dev_dbg
  to provide a descriptor, or NULL.
  basically this is dropping the _no_desc_,
  ie using _dynamic_func_call_cls(), since the callee can now accept it.

- add if (desc->flags ...) TRACE / PRINTK actions.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 25 ++++++++++++++++---------
 include/drm/drm_print.h     | 20 ++++++++++----------
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index b911f949af5b..8c33302212fc 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -258,8 +258,8 @@ void drm_dev_printk(const struct device *dev, const char *level,
 }
 EXPORT_SYMBOL(drm_dev_printk);
 
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-		   const char *format, ...)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+		   enum drm_debug_category category, const char *format, ...)
 {
 	struct va_format vaf;
 	va_list args;
@@ -267,24 +267,31 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 	if (!__drm_debug_enabled(category))
 		return;
 
+	/* we know we are printing for either syslog, tracefs, or both */
 	va_start(args, format);
 	vaf.fmt = format;
 	vaf.va = &args;
 
 	if (dev) {
-		dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
-			   __builtin_return_address(0), &vaf);
-		trace_drm_devdbg(dev, category, &vaf);
+		if (desc->flags & _DPRINTK_FLAGS_PRINTK)
+			dev_printk(KERN_DEBUG, dev, "[" DRM_NAME ":%ps] %pV",
+				   __builtin_return_address(0), &vaf);
+
+		if (desc->flags & _DPRINTK_FLAGS_TRACE)
+			trace_drm_devdbg(dev, category, &vaf);
 	} else {
-		printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
-		       __builtin_return_address(0), &vaf);
-		trace_drm_debug(category, &vaf);
+		if (desc->flags & _DPRINTK_FLAGS_PRINTK)
+			printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
+			       __builtin_return_address(0), &vaf);
+
+		if (desc->flags & _DPRINTK_FLAGS_TRACE)
+			trace_drm_debug(category, &vaf);
 	}
 	va_end(args);
 }
 EXPORT_SYMBOL(__drm_dev_dbg);
 
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...)
 {
 	struct va_format vaf;
 	va_list args;
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 0c704610c770..6d43b81a0ee4 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -360,9 +360,9 @@ static inline bool drm_debug_enabled(enum drm_debug_category category)
 __printf(3, 4)
 void drm_dev_printk(const struct device *dev, const char *level,
 		    const char *format, ...);
-__printf(3, 4)
-void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
-		 const char *format, ...);
+__printf(4, 5)
+void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
+		   enum drm_debug_category category, const char *format, ...);
 
 /**
  * DRM_DEV_ERROR() - Error output.
@@ -412,11 +412,11 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
 
 #if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
 #define drm_dev_dbg(dev, eCat, fmt, ...)				\
-	__drm_dev_dbg(dev, eCat, fmt, ##__VA_ARGS__)
+	__drm_dev_dbg(NULL, dev, eCat, fmt, ##__VA_ARGS__)
 #else
 #define drm_dev_dbg(dev, eCat, fmt, ...)				\
-	_dynamic_func_call_no_desc_cls(fmt, eCat, __drm_dev_dbg,	\
-				       dev, eCat, fmt, ##__VA_ARGS__)
+	_dynamic_func_call_cls(eCat, fmt, __drm_dev_dbg,		\
+			       dev, eCat, fmt, ##__VA_ARGS__)
 #endif
 
 /**
@@ -519,8 +519,8 @@ void __drm_dev_dbg(const struct device *dev, enum drm_debug_category category,
  * Prefer drm_device based logging over device or prink based logging.
  */
 
-__printf(2, 3)
-void ___drm_dbg(enum drm_debug_category category, const char *format, ...);
+__printf(3, 4)
+void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const char *format, ...);
 __printf(1, 2)
 void __drm_err(const char *format, ...);
 
@@ -528,8 +528,8 @@ void __drm_err(const char *format, ...);
 #define __drm_dbg(fmt, ...)		___drm_dbg(NULL, fmt, ##__VA_ARGS__)
 #else
 #define __drm_dbg(eCat, fmt, ...)					\
-	_dynamic_func_call_no_desc_cls(fmt, eCat, ___drm_dbg,		\
-				       eCat, fmt, ##__VA_ARGS__)
+	_dynamic_func_call_cls(eCat, fmt, ___drm_dbg,			\
+			       eCat, fmt, ##__VA_ARGS__)
 #endif
 
 /* Macros to make printk easier */
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:40 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:40 -0700
Subject: [PATCH v11 17/19] drm_print: add struct _ddebug *desc to
 trace-drm-*() params
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-18-jim.cromie@gmail.com>

Replace trace-drm-*()s category param with struct _ddebug *desc; it
has .classid field, which is the category.

This brings the events closer in line with those added for dyndbg; at
least the 1st param, and possibly the struct device (tb-checked).
There are still differences in the tail of the prototypes; vaf vs
text + len, which probably breaks CLASS sharing.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c |  6 +++---
 include/trace/events/drm.h  | 36 ++++++++++++++++++------------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 8c33302212fc..0a15a4ec5ead 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -278,14 +278,14 @@ void __drm_dev_dbg(struct _ddebug *desc, const struct device *dev,
 				   __builtin_return_address(0), &vaf);
 
 		if (desc->flags & _DPRINTK_FLAGS_TRACE)
-			trace_drm_devdbg(dev, category, &vaf);
+			trace_drm_devdbg(dev, desc, &vaf);
 	} else {
 		if (desc->flags & _DPRINTK_FLAGS_PRINTK)
 			printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 			       __builtin_return_address(0), &vaf);
 
 		if (desc->flags & _DPRINTK_FLAGS_TRACE)
-			trace_drm_debug(category, &vaf);
+			trace_drm_debug(desc, &vaf);
 	}
 	va_end(args);
 }
@@ -306,7 +306,7 @@ void ___drm_dbg(struct _ddebug *desc, enum drm_debug_category category, const ch
 	printk(KERN_DEBUG "[" DRM_NAME ":%ps] %pV",
 	       __builtin_return_address(0), &vaf);
 
-	trace_drm_debug(category, &vaf);
+	trace_drm_debug(desc, &vaf);
 
 	va_end(args);
 }
diff --git a/include/trace/events/drm.h b/include/trace/events/drm.h
index 944aedaf6aa6..bfe1fff923d8 100644
--- a/include/trace/events/drm.h
+++ b/include/trace/events/drm.h
@@ -9,25 +9,25 @@
 
 /* drm_debug() was called, pass its args */
 TRACE_EVENT(drm_debug,
-	TP_PROTO(int drm_debug_category, struct va_format *vaf),
+	TP_PROTO(struct _ddebug *desc, struct va_format *vaf),
 
-	TP_ARGS(drm_debug_category, vaf),
+	TP_ARGS(desc, vaf),
 
 	TP_STRUCT__entry(
-		__field(int, drm_debug_category)
+		__field(struct _ddebug *, desc)
 		__dynamic_array(char, msg, 256)
 	),
 
 	TP_fast_assign(
 		int len;
+		char *p = __get_str(msg);
 
-		__entry->drm_debug_category = drm_debug_category;
-		vsnprintf(__get_str(msg), 256, vaf->fmt, *vaf->va);
+		__entry->desc = desc;
+		len = vsnprintf(p, 256, vaf->fmt, *vaf->va);
 
-		len = strlen(__get_str(msg));
-		if ((len > 0) && (__get_str(msg)[len-1] == '\n'))
+		if ((len > 0) && (len < 256) && p[len-1] == '\n')
 			len -= 1;
-		__get_str(msg)[len] = 0;
+		p[len] = 0;
 	),
 
 	TP_printk("%s", __get_str(msg))
@@ -35,30 +35,30 @@ TRACE_EVENT(drm_debug,
 
 /* drm_devdbg() was called, pass its args, preserving order */
 TRACE_EVENT(drm_devdbg,
-	TP_PROTO(const struct device *dev, int drm_debug_category, struct va_format *vaf),
+	TP_PROTO(const struct device *dev, struct _ddebug *desc, struct va_format *vaf),
 
-	TP_ARGS(dev, drm_debug_category, vaf),
+	TP_ARGS(dev, desc, vaf),
 
 	TP_STRUCT__entry(
-		__field(const struct device*, dev)
-		__field(int, drm_debug_category)
+		__field(const struct device *, dev)
+		__field(struct _ddebug *, desc)
 		__dynamic_array(char, msg, 256)
 	),
 
 	TP_fast_assign(
 		int len;
+		char *p = __get_str(msg);
 
-		__entry->drm_debug_category = drm_debug_category;
+		__entry->desc = desc;
 		__entry->dev = dev;
-		vsnprintf(__get_str(msg), 256, vaf->fmt, *vaf->va);
+		len = vsnprintf(p, 256, vaf->fmt, *vaf->va);
 
-		len = strlen(__get_str(msg));
-		if ((len > 0) && (__get_str(msg)[len-1] == '\n'))
+		if ((len > 0) && (len < 256) && p[len-1] == '\n')
 			len -= 1;
-		__get_str(msg)[len] = 0;
+		p[len] = 0;
 	),
 
-	TP_printk("cat:%d, %s %s", __entry->drm_debug_category,
+	TP_printk("cat:%d, %s %s", __entry->desc->class_id,
 		  dev_name(__entry->dev), __get_str(msg))
 );
 
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:41 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:41 -0700
Subject: [PATCH v11 18/19] dyndbg: add DEFINE_DYNAMIC_DEBUG_CLASSBITS macro
 and callbacks
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-19-jim.cromie@gmail.com>

DEFINE_DYNAMIC_DEBUG_CLASSBITS(fsname, var, bitmap_desc, classes..)
allows users to create a drm.debug style (bitmap) sysfs interface, to
control sets of pr_debug's according to their .class_id's

1st, due to a recent commit, this already works:

   echo "module drm class 1 +p ; module drm class 3 +p" >control

With the macro, this is basically equivalent:

   # this also turns off all other classes.
   echo 0x05 > /sys/module/drm/parameters/debug

To use:

DEFINE_DYNAMIC_DEBUG_CLASSBITS(debug, __drm_debug,
	"drm.debug - bits => categories:",
	/* vector of uint:4 symbols, ala enum drm_debug_category */
	DRM_UT_CORE,
	DRM_UT_DRIVER,
	DRM_UT_KMS ... );

To support the macro, the patch includes:

 - int param_set_dyndbg_classbits()
 - int param_get_dyndbg_classbits()
 - struct kernel_param_ops param_ops_dyndbg_classbits

Following the model of kernel/params.c STANDARD_PARAM_DEFS, these are
non-static and exported.

get/set use an augmented kernel_param; the arg refs a new struct
dyndbg_bitmap_param containing:

A- the vector of classes (drm.debug "categories") being controlled

For CONFIG_DRM_USE_DYNDBG=y, enum drm_debug_category is initialized
into (struct _ddebug).class_id, so its already available to select on.

B- a pointer to the user module's ulong holding the bits/state.

By sharing bit-state in __drm_debug, we coordinate with existing code
that still uses drm_debug_enabled(), so they work unchanged.

NOTES:

param_set_dyndbg_classbits() compares new vs old bits, and only
updates each class on changes.  This maximally preserves the
underlying state, which may have been customized via later `echo $cmd
>control`.  So if a user really wants to know that all prdbgs are set
precisely, they must pre-clear then set.

Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 include/linux/dynamic_debug.h | 45 ++++++++++++++++++++-
 lib/dynamic_debug.c           | 75 +++++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+), 1 deletion(-)

diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
index e9483cd9ac1c..318ac44a0d4a 100644
--- a/include/linux/dynamic_debug.h
+++ b/include/linux/dynamic_debug.h
@@ -20,7 +20,9 @@ struct _ddebug {
 	const char *function;
 	const char *filename;
 	const char *format;
-	unsigned int class_id:4;
+#define CLS_BITS 4
+#define DD_MAX_CLASSES	(1 << CLS_BITS)
+	unsigned int class_id:CLS_BITS;
 	unsigned int lineno:18;
 	/*
 	 * The flags field controls the behaviour at the callsite.
@@ -202,6 +204,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 				   KERN_DEBUG, prefix_str, prefix_type,	\
 				   rowsize, groupsize, buf, len, ascii)
 
+struct kernel_param;
+int param_set_dyndbg_classbits(const char *instr, const struct kernel_param *kp);
+int param_get_dyndbg_classbits(char *buffer, const struct kernel_param *kp);
+
 #else /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
 #include <linux/string.h>
@@ -248,6 +254,43 @@ static inline int dynamic_debug_exec_queries(const char *query, const char *modn
 	return 0;
 }
 
+struct kernel_param;
+static inline int param_set_dyndbg_classbits(const char *instr, const struct kernel_param *kp)
+{ return 0; }
+static inline int param_get_dyndbg_classbits(char *buffer, const struct kernel_param *kp)
+{ return 0; }
+
 #endif /* !CONFIG_DYNAMIC_DEBUG_CORE */
 
+struct dyndbg_classbits_param {
+	unsigned long *bits;		/* ref to shared state */
+	const int classes[];		/* indexed by bitpos */
+};
+
+#if defined(CONFIG_DYNAMIC_DEBUG) || defined(CONFIG_DYNAMIC_DEBUG_CORE)
+/**
+ * DEFINE_DYNAMIC_DEBUG_CLASSBITS() - bitmap control of classed pr_debugs
+ * @sysname: sysfs-node name
+ * @_var:    C-identifier holding bit-vector (Bits 0-15 are usable)
+ * @desc:    string summarizing the controls provided
+ * @classes: vector of callsite.class_id's (uint:4, 0 is reserved)
+ *
+ * This macro implements a DRM.debug API style bitmap, mapping bits
+ * 0-15 to classes of prdbg's, as initialized in their .class_id fields.
+ */
+#define DEFINE_DYNAMIC_DEBUG_CLASSBITS(fsname, _var, desc, ...)		\
+	MODULE_PARM_DESC(fsname, desc);					\
+	static struct dyndbg_classbits_param ddcats_##_var = {		\
+		.bits = &(_var), .classes = { __VA_ARGS__, 0 } };	\
+	module_param_cb(fsname, &param_ops_dyndbg_classbits, &ddcats_##_var, 0644)
+
+extern const struct kernel_param_ops param_ops_dyndbg_classbits;
+
+#else /* no dyndbg configured, throw error on macro use */
+
+#define DEFINE_DYNAMIC_DEBUG_CLASSBITS(fsname, var, bitmap_desc, ...)	\
+	BUILD_BUG_ON_MSG(1, "CONFIG_DYNAMIC_DEBUG|_CORE && -DDYNAMIC_DEBUG_MODULE needed to use this macro: " #fsname #var)
+
+#endif
+
 #endif
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 419d4664e724..40ca7973a0f8 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -610,6 +610,81 @@ int dynamic_debug_exec_queries(const char *query, const char *modname)
 }
 EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
 
+#ifdef CONFIG_MODULES
+#define KP_MOD_NAME kp->mod->name
+#else
+#define KP_MOD_NAME NULL /* wildcard */
+#endif
+#define FMT_QUERY_SIZE 128 /* typically need <40 */
+/**
+ * param_set_dyndbg_classbits - bits => categories >control setter
+ * @instr: string echo>d to sysfs
+ * @kp:    kp->arg has state: bits, map
+ *
+ * Enable/disable prdbgs by their "category", as specified in the
+ * DEFINE_DYNAMIC_DEBUG_BITGRPS.classbits argument.
+ *
+ * Returns: 0 or <0 if error.
+ */
+int param_set_dyndbg_classbits(const char *instr, const struct kernel_param *kp)
+{
+	unsigned long inbits;
+	int rc, i, matches = 0, totct = 0;
+	char query[FMT_QUERY_SIZE];
+	const struct dyndbg_classbits_param *dcp = kp->arg;
+
+	if (dcp) {
+		pr_err("set_dyndbg_classbits: no bits=>queries map\n");
+		return -EINVAL;
+	}
+	rc = kstrtoul(instr, 0, &inbits);
+	if (rc) {
+		pr_err("set_dyndbg_classbits: expecting unsigned int\n");
+		return rc;
+	}
+	vpr_info("set_dyndbg_classbits: new 0x%lx old 0x%lx\n", inbits, *dcp->bits);
+
+	for (i = 0; i < DD_MAX_CLASSES && dcp->classes[i]; i++) {
+		if (test_bit(i, &inbits) == test_bit(i, dcp->bits))
+			continue;
+		snprintf(query, FMT_QUERY_SIZE, "class %d %cT", dcp->classes[i],
+			 test_bit(i, &inbits) ? '+' : '-');
+
+		matches = ddebug_exec_queries(query, KP_MOD_NAME);
+
+		v2pr_info("bit-%d: %d matches on class:%u\n", i,
+			  matches, dcp->classes[i]);
+		totct += matches;
+	}
+	*dcp->bits = inbits;
+	vpr_info("total matches: %d\n", totct);
+	return 0;
+}
+EXPORT_SYMBOL(param_set_dyndbg_classbits);
+
+/**
+ * param_get_dyndbg_classbits - classbits reader
+ * @buffer: string description of controlled bits -> classes
+ * @kp:     kp->arg has state: bits, map
+ *
+ * Reads last written bits, underlying prdbg state may have changed since.
+ * Returns: #chars written or <0 on error
+ */
+int param_get_dyndbg_classbits(char *buffer, const struct kernel_param *kp)
+{
+	const struct dyndbg_classbits_param *p = kp->arg;
+	unsigned long val = *p->bits;
+
+	return scnprintf(buffer, PAGE_SIZE, "0x%lx\n", val);
+}
+EXPORT_SYMBOL(param_get_dyndbg_classbits);
+
+const struct kernel_param_ops param_ops_dyndbg_classbits = {
+	.set = param_set_dyndbg_classbits,
+	.get = param_get_dyndbg_classbits,
+};
+EXPORT_SYMBOL(param_ops_dyndbg_classbits);
+
 #define PREFIX_SIZE 64
 
 static int remaining(int wrote)
-- 
2.33.1



From jim.cromie at gmail.com  Thu Jan  6 21:29:42 2022
From: jim.cromie at gmail.com (Jim Cromie)
Date: Thu,  6 Jan 2022 22:29:42 -0700
Subject: [PATCH v11 19/19] drm_print: use DEFINE_DYNAMIC_DEBUG_CLASSBITS for
 drm.debug
In-Reply-To: <20220107052942.1349447-1-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
Message-ID: <20220107052942.1349447-20-jim.cromie@gmail.com>

if CONFIG_DRM_USE_DYNDBG=y, use new macro to create the sysfs bitmap
to control drm.debug callsites.

DEFINE_DYNAMIC_DEBUG_CLASSBITS( debug, __drm_debug,
	"drm.debug - control summary",
	/* inline vector of dyndbg.class_id (uint:4, 0 is reserved) */
	DRM_UT_CORE,
	DRM_UT_DRIVER,
	DRM_UT_KMS,
	DRM_UT_PRIME,
	DRM_UT_ATOMIC,
	DRM_UT_VBL,
	DRM_UT_STATE,
	DRM_UT_LEASE,
	DRM_UT_DP,
	DRM_UT_DRMRES );

NOTES:

dyndbg.class_id is uint:4, values 1-15 are valid. 0 is reserved
primarily for non-classified callsites (aka: prdbgs), and is thus
available to mark the end of the vector (and is added by the macro).

RFC: how to fold this in, with multiple macro expansion ?
Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
---
 drivers/gpu/drm/drm_print.c | 20 ++++++++++++++++++--
 include/drm/drm_print.h     |  2 +-
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 0a15a4ec5ead..0de562e5306a 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -41,7 +41,7 @@
  * __drm_debug: Enable debug output.
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
  */
-unsigned int __drm_debug;
+unsigned long __drm_debug;
 EXPORT_SYMBOL(__drm_debug);
 
 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug category.\n"
@@ -53,7 +53,23 @@ MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables a debug cat
 "\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
 "\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
-module_param_named(debug, __drm_debug, int, 0600);
+
+#if !defined(CONFIG_DRM_USE_DYNAMIC_DEBUG)
+module_param_named(debug, __drm_debug, ulong, 0600);
+#else
+DEFINE_DYNAMIC_DEBUG_CLASSBITS(debug, __drm_debug,
+	"enable drm.debug categories - 1 bit per category",
+	DRM_UT_CORE,
+	DRM_UT_DRIVER,
+	DRM_UT_KMS,
+	DRM_UT_PRIME,
+	DRM_UT_ATOMIC,
+	DRM_UT_VBL,
+	DRM_UT_STATE,
+	DRM_UT_LEASE,
+	DRM_UT_DP,
+	DRM_UT_DRMRES);
+#endif
 
 void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 6d43b81a0ee4..ebed5ba2dc24 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -36,7 +36,7 @@
 #include <drm/drm.h>
 
 /* Do *not* use outside of drm_print.[ch]! */
-extern unsigned int __drm_debug;
+extern unsigned long __drm_debug;
 
 /**
  * DOC: print
-- 
2.33.1



From chunfeng.yun at mediatek.com  Thu Jan  6 21:31:52 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Jan 2022 13:31:52 +0800
Subject: [PATCH] phy: phy-mtk-tphy: Fix dumplicated argument in
 phy-mtk-tphy
In-Reply-To: <20220107025050.787720-1-wanjiabing@vivo.com>
References: <20220107025050.787720-1-wanjiabing@vivo.com>
Message-ID: <54af6850e07aba2ca8002e344be86498c810067d.camel@mediatek.com>

On Fri, 2022-01-07 at 10:50 +0800, Wan Jiabing wrote:
> Fix following coccicheck warning:
> ./drivers/phy/mediatek/phy-mtk-tphy.c:994:6-29: duplicated argument
> to && or ||
> 
> The efuse_rx_imp is duplicate. Here should be efuse_tx_imp.
> 
> Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
> ---
>  drivers/phy/mediatek/phy-mtk-tphy.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c
> b/drivers/phy/mediatek/phy-mtk-tphy.c
> index 6d307102f4f6..8ee7682b8e93 100644
> --- a/drivers/phy/mediatek/phy-mtk-tphy.c
> +++ b/drivers/phy/mediatek/phy-mtk-tphy.c
> @@ -992,7 +992,7 @@ static int phy_efuse_get(struct mtk_tphy *tphy,
> struct mtk_phy_instance *instanc
>  		/* no efuse, ignore it */
>  		if (!instance->efuse_intr &&
>  		    !instance->efuse_rx_imp &&
> -		    !instance->efuse_rx_imp) {
> +		    !instance->efuse_tx_imp) {
>  			dev_warn(dev, "no u3 intr efuse, but dts enable
> it\n");
>  			instance->efuse_sw_en = 0;
>  			break;

Acked-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Thanks a lot


From chunfeng.yun at mediatek.com  Thu Jan  6 21:43:37 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 7 Jan 2022 13:43:37 +0800
Subject: [PATCH v7 4/4] arm64: dts: Add mediatek SoC mt8195 and
 evaluation board
In-Reply-To: <18c342b20ccac520eabe8019562432030ddfe017.camel@mediatek.com>
References: <20211220121825.6446-1-tinghan.shen@mediatek.com>
 <20211220121825.6446-5-tinghan.shen@mediatek.com>
 <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
 <18c342b20ccac520eabe8019562432030ddfe017.camel@mediatek.com>
Message-ID: <6dd101e4e65ef56dbf81d67496a383a7db8cefb5.camel@mediatek.com>

On Thu, 2022-01-06 at 19:14 +0800, Tinghan Shen wrote:
> On Thu, 2021-12-23 at 17:59 +0800, Chen-Yu Tsai wrote:
> > Hi,
> > 
> > On Mon, Dec 20, 2021 at 8:20 PM Tinghan Shen <
> > tinghan.shen at mediatek.com> wrote:
> > > 
> > > Add basic chip support for mediatek mt8195.
> > > 
> > > Signed-off-by: Seiya Wang <seiya.wang at mediatek.com>
> > > Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> > > ---
> > >  arch/arm64/boot/dts/mediatek/Makefile       |    1 +
> > >  arch/arm64/boot/dts/mediatek/mt8195-evb.dts |  209 ++++
> > >  arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 1034
> > > +++++++++++++++++++
> > >  3 files changed, 1244 insertions(+)
> > >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi
> > > 
> > > diff --git a/arch/arm64/boot/dts/mediatek/Makefile
> > > b/arch/arm64/boot/dts/mediatek/Makefile
> > > index 4f68ebed2e31..7aa08bb4c078 100644
> > > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > > @@ -32,4 +32,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-
> > > krane-sku0.dtb
> > >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
> > >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
> > >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
> > > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
> > >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
> > > diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > > b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > > new file mode 100644
> > > index 000000000000..e581c6bbead6
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
> > > @@ -0,0 +1,209 @@
> > > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > > +/*
> > > + * Copyright (C) 2021 MediaTek Inc.
> > > + * Author: Seiya Wang <seiya.wang at mediatek.com>
> > > + */
> > > +/dts-v1/;
> > > +#include "mt8195.dtsi"
> > > +
> > > +/ {
> > > +       model = "MediaTek MT8195 evaluation board";
> > > +       compatible = "mediatek,mt8195-evb", "mediatek,mt8195";
> > > +
> > > +       aliases {
> > > +               serial0 = &uart0;
> > > +       };
> > > +
> > > +       chosen {
> > > +               stdout-path = "serial0:921600n8";
> > > +       };
> > > +
> > > +       memory at 40000000 {
> > > +               device_type = "memory";
> > > +               reg = <0 0x40000000 0 0x80000000>;
> > > +       };
> > > +};
> > > +
> > > +&auxadc {
> > > +       status = "okay";
> > > +};
> > > +
> > > +&i2c0 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c0_pin>;
> > > +       clock-frequency = <100000>;
> > > +       status = "okay";
> > > +};
> > > +
> > > +&i2c1 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c1_pin>;
> > > +       clock-frequency = <400000>;
> > > +       status = "okay";
> > > +};
> > > +
> > > +&i2c2 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c2_pin>;
> > > +       status = "disabled";
> > > +};
> > > +
> > > +&i2c3 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c3_pin>;
> > > +       status = "disabled";
> > > +};
> > 
> > Is there any reason in particular to list "disabled" devices here?
> > Are they part of some GPIO header? If they are not accessible, then
> > it's better to not list them. If they are, please leave a comment
> > about it.
> > 
> > > +
> > > +&i2c4 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c4_pin>;
> > > +       clock-frequency = <400000>;
> > > +       status = "okay";
> > > +};
> > > +
> > > +&i2c5 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c5_pin>;
> > > +       status = "disabled";
> > > +};
> > > +
> > > +&i2c6 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&i2c6_pin>;
> > > +       clock-frequency = <400000>;
> > > +       status = "disabled";
> > > +};
> > 
> > Same here.
> > 
> > > +
> > > +&nor_flash {
> > > +       status = "okay";
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&nor_pins_default>;
> > 
> > Please add an empty line between properties and child device nodes.
> > It helps
> > with readability and also fits the style of other parts and other
> > DT
> > files.
> > 
> > > +       flash at 0 {
> > > +               compatible = "jedec,spi-nor";
> > > +               reg = <0>;
> > > +               spi-max-frequency = <50000000>;
> > > +       };
> > > +};
> > > +
> > > +&pio {
> > > +       i2c0_pin: i2c0-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
> > > +                                <PINMUX_GPIO9__FUNC_SCL0>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > 
> > Please use the MTK_PULL_SET_RSEL_* macros with the bias-pull-*
> > properties.
> > We spent a lot of time defining those.
> > 
> > > +                       mediatek,drive-strength-adv = <0>;
> > 
> > This property is not part of the DT binding.
> > 
> > > +                       drive-strength = <MTK_DRIVE_6mA>;
> > 
> > Please just use raw numbers here. MTK_DRIVE_6mA just translates to
> > 6.
> > The binding already specifies mA as the unit for "drive-strength".
> > 
> > > +               };
> > > +       };
> > 
> > Above comments apply to all the other "pins" nodes.
> > 
> > Please add an empty line between different child device nodes. It
> > helps
> > with readability and also fits the style of other parts and other
> > DT
> > files.
> > 
> > > +       i2c1_pin: i2c1-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
> > > +                                <PINMUX_GPIO11__FUNC_SCL1>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > > +                       mediatek,drive-strength-adv = <0>;
> > > +                       drive-strength = <MTK_DRIVE_6mA>;
> > > +               };
> > > +       };
> > > +       i2c2_pin: i2c2-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO12__FUNC_SDA2>,
> > > +                                <PINMUX_GPIO13__FUNC_SCL2>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > > +                       mediatek,drive-strength-adv = <7>;
> > > +               };
> > > +       };
> > > +       i2c3_pin: i2c3-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO14__FUNC_SDA3>,
> > > +                                <PINMUX_GPIO15__FUNC_SCL3>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > > +                       mediatek,drive-strength-adv = <7>;
> > > +               };
> > > +       };
> > > +       i2c4_pin: i2c4-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
> > > +                                <PINMUX_GPIO17__FUNC_SCL4>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > > +                       mediatek,drive-strength-adv = <7>;
> > > +               };
> > > +       };
> > > +       i2c5_pin: i2c5-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO29__FUNC_SCL5>,
> > > +                                <PINMUX_GPIO30__FUNC_SDA5>;
> > > +                       bias-pull-up = <1>;
> > > +                       mediatek,rsel = <7>;
> > > +                       mediatek,drive-strength-adv = <7>;
> > > +               };
> > > +       };
> > > +       i2c6_pin: i2c6-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
> > > +                                <PINMUX_GPIO26__FUNC_SCL6>;
> > > +                       bias-pull-up = <1>;
> > > +               };
> > > +       };
> > > +       i2c7_pin: i2c7-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO27__FUNC_SCL7>,
> > > +                                <PINMUX_GPIO28__FUNC_SDA7>;
> > > +                       bias-pull-up = <1>;
> > > +               };
> > > +       };
> > > +       nor_pins_default: nor-pins {
> > > +               pins0 {
> > > +                       pinmux =
> > > <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
> > > +                                        <PINMUX_GPIO141__FUNC_SP
> > > IN
> > > OR_CK>,
> > > +                                        <PINMUX_GPIO143__FUNC_SP
> > > IN
> > > OR_IO1>;
> > > +                       bias-pull-down;
> > > +               };
> > > +               pins1 {
> > > +                       pinmux =
> > > <PINMUX_GPIO140__FUNC_SPINOR_CS>,
> > > +                                    <PINMUX_GPIO130__FUNC_SPINOR
> > > _I
> > > O2>,
> > > +                                    <PINMUX_GPIO131__FUNC_SPINOR
> > > _I
> > > O3>;
> > > +                       bias-pull-up;
> > > +               };
> > > +       };
> > > +       uart0_pin: uart0-pins {
> > > +               pins {
> > > +                       pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
> > > +                               <PINMUX_GPIO99__FUNC_URXD0>;
> > > +               };
> > > +       };
> > > +};
> > > +
> > > +&u2port0 {
> > > +       status = "okay";
> > > +};
> > > +
> > > +&u2port1 {
> > > +       status = "okay";
> > > +};
> > > +
> > > +&u3phy0 {
> > > +       status="okay";
> > > +};
> > > +
> > > +&u3phy1 {
> > > +       status="okay";
> > > +};
> > > +
> > > +&u3port0 {
> > > +       status = "okay";
> > > +};
> > > +
> > > +&u3port1 {
> > > +       status = "okay";
> > > +};
No need add status property for those u*port* subnodes, add it in
parent node u*phy* is enough.

Thanks

> > > +
> > > +&uart0 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&uart0_pin>;
> > > +       status = "okay";
> > > +};
> > > 
> > 
> 
> 

From samuel at sholland.org  Thu Jan  6 21:49:50 2022
From: samuel at sholland.org (Samuel Holland)
Date: Thu, 6 Jan 2022 23:49:50 -0600
Subject: [PATCH v4 0/4] Add support for the Cypress cyttsp5
In-Reply-To: <20211222124603.326920-1-alistair@alistair23.me>
References: <20211222124603.326920-1-alistair@alistair23.me>
Message-ID: <37291fe7-7028-cd9e-7fde-01d13f85f0d9@sholland.org>

Hello!

On 12/22/21 6:45 AM, Alistair Francis wrote:
> This patch series builds on top of [1] and adds support for the cyttsp5
> touchscreen controller for the reMarkable 2.
> 
> I first tried to add an I2C HID device. Although the cyttsp5 has some HID
> looking aspects it is not HID compatible. Just in trying to probe the device
> I found:
>  - The HID descriptor has extra padding
>  - The HID descriptor sets the high bytes of the descriptor length
>  - The HID descriptor has extra unrecognised tags
>  - The HID reset command doesn't appear to work
> 
> I don't think there is a way to use the I2C HID framework with the cyttsp5.
> For anyone interested you can see the work here [2]. In that branch though I
> can only obtain a HID descriptor, nothing else works without more core
> changes.
> 
> So instead I rebased the series from [1]. Converted to the new yaml DTS
> documentation, added regulator support and fixed a x/y miscalculation bug.

I am working on the PineNote, which also uses a cyttsp5 touchscreen. I attempted
to use the driver from this series, but I could not get it to work. I found that
the cyttsp5_sensing_conf_data was filled with all zeroes, so every touch failed
the max_tch check. I noticed that cmd_done was being completed by empty
responses (which explains why the response buffer was zeroes), but I got stuck
after that.

So I looked back at the thread you linked below, and tried to implement the
workarounds described there, and those above, plus some others, and I was able
to get the touchscreen working with i2c_hid. Here are the changes I made to i2c_hid:
https://github.com/smaeul/linux/commit/a1e07425a6c4

In summary:
 - Perform a 2-byte dummy read before reading the HID descriptor.
   This is required to clear the two-byte empty message.
 - Split command/response into multiple I2C transactions.
   This is probably some sort of timing issue.
   Without these first two, HID descriptor reads return "02 00".
 - Chop 2 bytes out of the HID descriptor, as per the thread below.
 - Similarly, chop 3 bytes out of the report descriptor.
 - Skip the reset command, as above. Otherwise, the touchscreen
   sends a different, short, unusable (partial?) report descriptor.

I reused the the existing i2c_hid_of_goodix driver to handle toggling the reset
line, which is required. That existing binding is almost identical to the one in
this series. Here's the glue I added:
https://github.com/smaeul/linux/commit/65d9250d3899

And here is the result, from dmesg and debugfs:
https://gist.github.com/smaeul/60b4b0f784bfff8bb8ce3ee3b4483be9

So far, the quirks only appear to affect probing the device. The touchscreen
works normally after that.

What do you think of this approach? It certainly seems cleaner than parsing the
HID reports/responses by hand. But I don't know if all of the quirks are
acceptable for i2c_hid.

One additional quirk that I haven't handled yet is the missing min/max for ABS_*
axes in the report descriptor. This prevents libinput from working, but other
evdev users appear to work fine. The driver in this series appears to get that
information from some vendor-specific command, and I am not sure where to hook
that up.

Regards,
Samuel

> 1: https://lwn.net/ml/linux-kernel/20180703094309.18514-1-mylene.josserand at bootlin.com/
> 2: https://github.com/alistair23/linux/commits/rM2-mainline-cyttsp5-hid
> 
> Alistair Francis (2):
>   ARM: imx_v6_v7_defconfig: Enable the cyttsp5 touchscreen
>   ARM: dts: imx7d-remarkable2: Enable the cyttsp5
> 
> Myl?ne Josserand (2):
>   Input: Add driver for Cypress Generation 5 touchscreen
>   dt-bindings: input: Add Cypress TT2100 touchscreen controller
> 
>  .../input/touchscreen/cypress,tt21000.yaml    |  92 ++
>  arch/arm/boot/dts/imx7d-remarkable2.dts       |  89 ++
>  arch/arm/configs/imx_v6_v7_defconfig          |   1 +
>  drivers/input/touchscreen/Kconfig             |  14 +
>  drivers/input/touchscreen/Makefile            |   1 +
>  drivers/input/touchscreen/cyttsp5.c           | 922 ++++++++++++++++++
>  6 files changed, 1119 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
>  create mode 100644 drivers/input/touchscreen/cyttsp5.c
> 



From reijiw at google.com  Thu Jan  6 22:06:53 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 6 Jan 2022 22:06:53 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <20220104194918.373612-2-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
Message-ID: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>

Hi Raghu,

On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> Capture the start of the KVM VM, which is basically the
> start of any vCPU run. This state of the VM is helpful
> in the upcoming patches to prevent user-space from
> configuring certain VM features after the VM has started
> running.
>
> Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> ---
>  include/linux/kvm_host.h | 3 +++
>  virt/kvm/kvm_main.c      | 9 +++++++++
>  2 files changed, 12 insertions(+)
>
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index c310648cc8f1..d0bd8f7a026c 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -623,6 +623,7 @@ struct kvm {
>         struct notifier_block pm_notifier;
>  #endif
>         char stats_id[KVM_STATS_NAME_SIZE];
> +       bool vm_started;

Since KVM_RUN on any vCPUs doesn't necessarily mean that the VM
started yet, the name might be a bit misleading IMHO.  I would
think 'has_run_once' or 'ran_once' might be more clear (?).


>  };
>
>  #define kvm_err(fmt, ...) \
> @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
>         }
>  }
>
> +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> +
>  extern bool kvm_rebooting;
>
>  extern unsigned int halt_poll_ns;
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 72c4e6b39389..962b91ac2064 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
>         int r;
>         struct kvm_fpu *fpu = NULL;
>         struct kvm_sregs *kvm_sregs = NULL;
> +       struct kvm *kvm = vcpu->kvm;
>
>         if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
>                 return -EIO;
> @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
>                         if (oldpid)
>                                 synchronize_rcu();
>                         put_pid(oldpid);
> +
> +                       /*
> +                        * Since we land here even on the first vCPU run,
> +                        * we can mark that the VM has started running.
> +                        */

It might be nicer to add a comment why the code below gets kvm->lock.

Anyway, the patch generally looks good to me, and thank you
for making this change (it works for my purpose as well).

Reviewed-by: Reiji Watanabe <reijiw at google.com>

Thanks,
Reiji


> +                       mutex_lock(&kvm->lock);
> +                       kvm->vm_started = true;
> +                       mutex_unlock(&kvm->lock);
>                 }
>                 r = kvm_arch_vcpu_ioctl_run(vcpu);
>                 trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From wenst at chromium.org  Thu Jan  6 22:19:40 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 7 Jan 2022 14:19:40 +0800
Subject: [PATCH v7 4/4] arm64: dts: Add mediatek SoC mt8195 and evaluation
 board
In-Reply-To: <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
References: <20211220121825.6446-1-tinghan.shen@mediatek.com>
 <20211220121825.6446-5-tinghan.shen@mediatek.com>
 <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
Message-ID: <CAGXv+5FcDAu4yKS6MRjfnsJc0CgoREXAvS1d+UWcPQ24NmCY-Q@mail.gmail.com>

On Thu, Dec 23, 2021 at 5:59 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
> On Mon, Dec 20, 2021 at 8:20 PM Tinghan Shen <tinghan.shen at mediatek.com> wrote:

> > +                       infracfg_rst: reset-controller {
> > +                               compatible = "ti,syscon-reset";
> > +                               #reset-cells = <1>;
> > +                               ti,reset-bits = <
> > +                                       0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x120 0 0x124 0 0 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x730 10 0x734 10 0 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
> > +                                       0x150 5 0x154 5 0 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE)
>
> This should be 7 cells per entry:
>
>     ti,reset-bits =
>         <0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE>,
>         <0x120 0 0x124 0 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE)>,
>         <...>,
>         <...>;

Please ignore this comment. It looks like I misread the binding, and your
version is correct. However please format the columns so they align.

ChenYu


From quic_saipraka at quicinc.com  Thu Jan  6 23:09:43 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 7 Jan 2022 12:39:43 +0530
Subject: [PATCHv3] tty: hvc: dcc: Bind driver to core0 for reads and writes
In-Reply-To: <YcGQ72wQB1CLkvur@kroah.com>
References: <20211213141013.21464-1-quic_saipraka@quicinc.com>
 <YcGQ72wQB1CLkvur@kroah.com>
Message-ID: <8d8991cc-d0f5-bb5d-098a-e5a1a98f6b09@quicinc.com>

Hi,

On 12/21/2021 2:01 PM, Greg Kroah-Hartman wrote:
> On Mon, Dec 13, 2021 at 07:40:13PM +0530, Sai Prakash Ranjan wrote:
>> From: Shanker Donthineni <shankerd at codeaurora.org>
>>
>> Some debuggers, such as Trace32 from Lauterbach GmbH, do not handle
>> reads/writes from/to DCC on secondary cores. Each core has its
>> own DCC device registers, so when a core reads or writes from/to DCC,
>> it only accesses its own DCC device. Since kernel code can run on
>> any core, every time the kernel wants to write to the console, it
>> might write to a different DCC.
>>
>> In SMP mode, Trace32 creates multiple windows, and each window shows
>> the DCC output only from that core's DCC. The result is that console
>> output is either lost or scattered across windows.
>>
>> Selecting this option will enable code that serializes all console
>> input and output to core 0. The DCC driver will create input and
>> output FIFOs that all cores will use. Reads and writes from/to DCC
>> are handled by a workqueue that runs only core 0.
>>
>> Signed-off-by: Shanker Donthineni <shankerd at codeaurora.org>
>> Acked-by: Adam Wallis <awallis at codeaurora.org>
>> Signed-off-by: Timur Tabi <timur at codeaurora.org>
>> Signed-off-by: Elliot Berman <eberman at codeaurora.org>
>> Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
>> ---
>>
>> Changes in v3:
>>   * Handle case where core0 is not online.
>>
>> Changes in v2:
>>   * Checkpatch warning fixes.
>>   * Use of IS_ENABLED macros instead of ifdefs.
>>
>> ---
>>   drivers/tty/hvc/Kconfig   |  20 +++++
>>   drivers/tty/hvc/hvc_dcc.c | 161 +++++++++++++++++++++++++++++++++++++-
>>   2 files changed, 180 insertions(+), 1 deletion(-)
> What has changed in the kernel in the past decade that this is suddenly
> an issue?  Why can't userspace debuggers handle this today, merging all
> of the data from different cores together?

The issue is for the users of this feature, from the past 6 years (when 
the first version was posted)
or possibly more, we have been carrying it downstream because we are the 
frequent users of this
feature and the issue hits us. Just like any other feature, if it is not 
used by more people/org, then they
won't report it. So it is nothing like a sudden issue, its been there 
from a long time.

> And why does this have to be a build-time option and not a runtime
> choice?  How are you going to build a universal kernel that works for
> both types of systems?

There are no 2 types of systems here, just one system with different 
implementation to fix/increase the
usability of this feature. I can add a module parameter if that is what 
you are suggesting to make a runtime
choice?

>> diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
>> index 8d60e0ff67b4..c0754a2e3fe4 100644
>> --- a/drivers/tty/hvc/Kconfig
>> +++ b/drivers/tty/hvc/Kconfig
>> @@ -87,6 +87,26 @@ config HVC_DCC
>>   	  driver. This console is used through a JTAG only on ARM. If you don't have
>>   	  a JTAG then you probably don't want this option.
>>   
>> +config HVC_DCC_SERIALIZE_SMP
>> +	bool "Use DCC only on core 0"
>> +	depends on SMP && HVC_DCC
>> +	help
>> +	  Some debuggers, such as Trace32 from Lauterbach GmbH, do not handle
>> +	  reads/writes from/to DCC on more than one core. Each core has its
>> +	  own DCC device registers, so when a core reads or writes from/to DCC,
>> +	  it only accesses its own DCC device. Since kernel code can run on
>> +	  any core, every time the kernel wants to write to the console, it
>> +	  might write to a different DCC.
>> +
>> +	  In SMP mode, Trace32 creates multiple windows, and each window shows
>> +	  the DCC output only from that core's DCC. The result is that console
>> +	  output is either lost or scattered across windows.
>> +
>> +	  Selecting this option will enable code that serializes all console
>> +	  input and output to core 0. The DCC driver will create input and
>> +	  output FIFOs that all cores will use. Reads and writes from/to DCC
>> +	  are handled by a workqueue that runs only core 0.
> So this drops down to only one device, not multiple ones?  Or is it the
> other way around?

Yes.

>> +
>>   config HVC_RISCV_SBI
>>   	bool "RISC-V SBI console support"
>>   	depends on RISCV_SBI_V01
>> diff --git a/drivers/tty/hvc/hvc_dcc.c b/drivers/tty/hvc/hvc_dcc.c
>> index 8e0edb7d93fd..24e3770219bc 100644
>> --- a/drivers/tty/hvc/hvc_dcc.c
>> +++ b/drivers/tty/hvc/hvc_dcc.c
>> @@ -2,9 +2,12 @@
>>   /* Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.  */
>>   
>>   #include <linux/console.h>
>> +#include <linux/cpumask.h>
>>   #include <linux/init.h>
>> +#include <linux/kfifo.h>
>>   #include <linux/serial.h>
>>   #include <linux/serial_core.h>
>> +#include <linux/spinlock.h>
>>   
>>   #include <asm/dcc.h>
>>   #include <asm/processor.h>
>> @@ -67,26 +70,182 @@ static int hvc_dcc_get_chars(uint32_t vt, char *buf, int count)
>>   	return i;
>>   }
>>   
>> +/*
>> + * Check if the DCC is enabled.  If CONFIG_HVC_DCC_SERIALIZE_SMP is enabled,
>> + * then we assume then this function will be called first on core 0.  That
>> + * way, dcc_core0_available will be true only if it's available on core 0.
>> + */
>>   static bool hvc_dcc_check(void)
>>   {
>>   	unsigned long time = jiffies + (HZ / 10);
>> +	static bool dcc_core0_available;
>> +
>> +	/*
>> +	 * If we're not on core 0, but we previously confirmed that DCC is
>> +	 * active, then just return true.
> Why?  Don't you want to see if DCC works on the other cores?
>
> What if core 0 is never enabled?

It does check right based on dcc_core0_available below. Is core0 being 
never enabled an option?
I see there is nosmp and maxcpus cmdline which can modify the cores 
which need to be online but
in both cases there isn't a way to actually make core0 unavailable 
because nosmp would make core0
as the only core and maxcpus=1 would also do the same. Do you know of 
any way where core0 which
is a logical cpu 0 to be offline/never enabled other than hotplug case?

>
>> +	 */
>> +	if (IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP) && smp_processor_id() &&
>> +	    dcc_core0_available)
>> +		return true;
>>   
>>   	/* Write a test character to check if it is handled */
>>   	__dcc_putchar('\n');
>>   
>>   	while (time_is_after_jiffies(time)) {
>> -		if (!(__dcc_getstatus() & DCC_STATUS_TX))
>> +		if (!(__dcc_getstatus() & DCC_STATUS_TX)) {
>> +			if (IS_ENABLED(CONFIG_HVC_DCC_SERIALIZE_SMP))
> Why this check again?

Right, it is not required.

>> +				dcc_core0_available = true;
>>   			return true;
>> +		}
>>   	}
>
>
>>   
>>   	return false;
>>   }
>>   
>> +#if defined(CONFIG_HVC_DCC_SERIALIZE_SMP)
> No ifdefs in .c files please.  Make this a separate .c file entirely if
> this really is needed.

Hmm, separate file would cause unnecessary duplication, let me see what 
I can do for this.

>> +
>> +static void dcc_put_work_fn(struct work_struct *work);
>> +static void dcc_get_work_fn(struct work_struct *work);
>> +static DECLARE_WORK(dcc_pwork, dcc_put_work_fn);
>> +static DECLARE_WORK(dcc_gwork, dcc_get_work_fn);
> No need to put "fn" at the end of your function name, we know it's a
> function :)

Ack, will remove it.

>> +static DEFINE_SPINLOCK(dcc_lock);
>> +static DEFINE_KFIFO(inbuf, unsigned char, 128);
>> +static DEFINE_KFIFO(outbuf, unsigned char, 1024);
> Where did these size values come from?

These are random magic values, I will define this as INBUF_SIZE and 
OUTBUF_SIZE.

>> +
>> +/*
>> + * Workqueue function that writes the output FIFO to the DCC on core 0.
>> + */
>> +static void dcc_put_work_fn(struct work_struct *work)
>> +{
>> +	unsigned char ch;
>> +	unsigned long irqflags;
>> +
>> +	spin_lock_irqsave(&dcc_lock, irqflags);
>> +
>> +	/* While there's data in the output FIFO, write it to the DCC */
>> +	while (kfifo_get(&outbuf, &ch))
>> +		hvc_dcc_put_chars(0, &ch, 1);
>> +
>> +	/* While we're at it, check for any input characters */
>> +	while (!kfifo_is_full(&inbuf)) {
>> +		if (!hvc_dcc_get_chars(0, &ch, 1))
>> +			break;
>> +		kfifo_put(&inbuf, ch);
> Why is this needed?  Will not the normal input handling deal with this?

Let me check this one.

>
>> +	}
>> +
>> +	spin_unlock_irqrestore(&dcc_lock, irqflags);
>> +}
>> +
>> +/*
>> + * Workqueue function that reads characters from DCC and puts them into the
>> + * input FIFO.
>> + */
>> +static void dcc_get_work_fn(struct work_struct *work)
>> +{
>> +	unsigned char ch;
>> +	unsigned long irqflags;
>> +
>> +	/*
>> +	 * Read characters from DCC and put them into the input FIFO, as
>> +	 * long as there is room and we have characters to read.
>> +	 */
>> +	spin_lock_irqsave(&dcc_lock, irqflags);
>> +
>> +	while (!kfifo_is_full(&inbuf)) {
>> +		if (!hvc_dcc_get_chars(0, &ch, 1))
>> +			break;
>> +		kfifo_put(&inbuf, ch);
>> +	}
>> +	spin_unlock_irqrestore(&dcc_lock, irqflags);
>> +}
>> +
>> +/*
>> + * Write characters directly to the DCC if we're on core 0 and the FIFO
>> + * is empty, or write them to the FIFO if we're not.
>> + */
>> +static int hvc_dcc0_put_chars(u32 vt, const char *buf, int count)
>> +{
>> +	int len;
>> +	unsigned long irqflags;
>> +
>> +	spin_lock_irqsave(&dcc_lock, irqflags);
>> +	if (smp_processor_id() || (!kfifo_is_empty(&outbuf))) {
>> +		len = kfifo_in(&outbuf, buf, count);
>> +		spin_unlock_irqrestore(&dcc_lock, irqflags);
>> +
>> +		if (!cpu_online(0))
>> +			return 0;
>> +		/*
>> +		 * We just push data to the output FIFO, so schedule the
>> +		 * workqueue that will actually write that data to DCC.
>> +		 */
>> +		schedule_work_on(0, &dcc_pwork);
>> +		return len;
>> +	}
>> +
>> +	/*
>> +	 * If we're already on core 0, and the FIFO is empty, then just
>> +	 * write the data to DCC.
>> +	 */
>> +	len = hvc_dcc_put_chars(vt, buf, count);
>> +	spin_unlock_irqrestore(&dcc_lock, irqflags);
>> +
>> +	return len;
>> +}
>> +
>> +/*
>> + * Read characters directly from the DCC if we're on core 0 and the FIFO
>> + * is empty, or read them from the FIFO if we're not.
>> + */
>> +static int hvc_dcc0_get_chars(u32 vt, char *buf, int count)
>> +{
>> +	int len;
>> +	unsigned long irqflags;
>> +
>> +	spin_lock_irqsave(&dcc_lock, irqflags);
>> +
>> +	if (smp_processor_id() || (!kfifo_is_empty(&inbuf))) {
>> +		len = kfifo_out(&inbuf, buf, count);
>> +		spin_unlock_irqrestore(&dcc_lock, irqflags);
>> +
>> +		if (!cpu_online(0))
>> +			return 0;
> Why check this here?

I can move it down along with len check for scheduling work on CPU0 
protected by CPU hotplug lock.

>> +		/*
>> +		 * If the FIFO was empty, there may be characters in the DCC
>> +		 * that we haven't read yet.  Schedule a workqueue to fill
>> +		 * the input FIFO, so that the next time this function is
>> +		 * called, we'll have data.
>> +		 */
>> +		if (!len)
>> +			schedule_work_on(0, &dcc_gwork);
> What happened if the cpu went offline between checking and doing this
> call?

We will need to use CPU hotplug lock here.

> thanks,
>
> greg k-h

Thanks,
Sai


From reijiw at google.com  Thu Jan  6 23:12:28 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 6 Jan 2022 23:12:28 -0800
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function
 for an ID register
In-Reply-To: <20220106042708.2869332-2-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-2-reijiw@google.com>
Message-ID: <CAAeT=FxEr4N4j7tJQKpUANM1dSrpZrgDLaYEOVLRhmXWPn52NA@mail.gmail.com>

On Wed, Jan 5, 2022 at 8:28 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> Introduce arm64_check_features(), which does a basic validity checking
> of an ID register value against the register's limit value, which is
> generally the host's sanitized value.
>
> This function will be used by the following patches to check if an ID
> register value that userspace tries to set for a guest can be supported
> on the host.
>
> The validation is done using arm64_ftr_bits_kvm, which is created from
> arm64_ftr_regs, with some entries overwritten by entries from
> arm64_ftr_bits_kvm_override.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/cpufeature.h |   1 +
>  arch/arm64/kernel/cpufeature.c      | 228 ++++++++++++++++++++++++++++
>  2 files changed, 229 insertions(+)
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef6be92b1921..eda7ddbed8cf 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -631,6 +631,7 @@ void check_local_cpu_capabilities(void);
>
>  u64 read_sanitised_ftr_reg(u32 id);
>  u64 __read_sysreg_by_encoding(u32 sys_id);
> +int arm64_check_features(u32 sys_reg, u64 val, u64 limit);
>
>  static inline bool cpu_supports_mixed_endian_el0(void)
>  {
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6f3e677d88f1..48dff8b101d9 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -3140,3 +3140,231 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
>                 return sprintf(buf, "Vulnerable\n");
>         }
>  }
> +
> +#ifdef CONFIG_KVM
> +/*
> + * arm64_ftr_bits_kvm[] is used for KVM to check if features that are
> + * indicated in an ID register value for the guest are available on the host.
> + * arm64_ftr_bits_kvm[] is created based on arm64_ftr_regs[].  But, for
> + * registers for which arm64_ftr_bits_kvm_override[] has a corresponding
> + * entry, replace arm64_ftr_bits entries in arm64_ftr_bits_kvm[] with the
> + * ones in arm64_ftr_bits_kvm_override[].
> + */
> +static struct __ftr_reg_bits_entry *arm64_ftr_bits_kvm;
> +static size_t arm64_ftr_bits_kvm_nentries;
> +static DEFINE_MUTEX(arm64_ftr_bits_kvm_lock);
> +
> +/*
> + * Number of arm64_ftr_bits entries for each register.
> + * (Number of 4 bits fields in 64 bit register + 1 entry for ARM64_FTR_END)
> + */
> +#define        MAX_FTR_BITS_LEN        17
> +
> +/* Use FTR_LOWER_SAFE for AA64DFR0_EL1.PMUVER and AA64DFR0_EL1.DEBUGVER. */
> +static struct arm64_ftr_bits ftr_id_aa64dfr0_kvm[MAX_FTR_BITS_LEN] = {
> +       S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
> +       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
> +       ARM64_FTR_END,
> +};
> +
> +#define        ARM64_FTR_REG_BITS(id, table)   {       \
> +       .sys_id = id,                           \
> +       .ftr_bits = &((table)[0]),              \
> +}
> +
> +struct __ftr_reg_bits_entry {
> +       u32     sys_id;
> +       struct arm64_ftr_bits   *ftr_bits;
> +};
> +
> +/*
> + * All entries in arm64_ftr_bits_kvm_override[] are used to override
> + * the corresponding entries in arm64_ftr_bits_kvm[].
> + */
> +static struct __ftr_reg_bits_entry arm64_ftr_bits_kvm_override[] = {
> +       ARM64_FTR_REG_BITS(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0_kvm),
> +};
> +
> +/*
> + * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
> + * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
> + * ARM64_FTR_END (.width == 0).
> + */
> +static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,
> +                                       struct arm64_ftr_bits *new_ftrp)
> +{
> +       struct arm64_ftr_bits *o_ftrp, *n_ftrp;
> +
> +       for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
> +               for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
> +                       if (o_ftrp->shift == n_ftrp->shift) {
> +                               *o_ftrp = *n_ftrp;
> +                               break;
> +                       }
> +               }
> +       }
> +}
> +
> +/*
> + * Copy arm64_ftr_bits entries from @src_ftrp to @dst_ftrp.  The last entries
> + * of @dst_ftrp and @src_ftrp must be ARM64_FTR_END (.width == 0).
> + */
> +static void copy_arm64_ftr_bits(struct arm64_ftr_bits *dst_ftrp,
> +                               const struct arm64_ftr_bits *src_ftrp)
> +{
> +       int i = 0;
> +
> +       for (; src_ftrp[i].width; i++) {
> +               if (WARN_ON_ONCE(i >= (MAX_FTR_BITS_LEN - 1)))
> +                       break;
> +
> +               dst_ftrp[i] = src_ftrp[i];
> +       }
> +
> +       dst_ftrp[i].width = 0;
> +}
> +
> +/*
> + * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
> + * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
> + * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
> + */
> +static int init_arm64_ftr_bits_kvm(void)
> +{
> +       struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
> +       static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
> +       int i, j, nent, ret;
> +
> +       mutex_lock(&arm64_ftr_bits_kvm_lock);
> +       if (arm64_ftr_bits_kvm) {
> +               /* Already initialized */
> +               ret = 0;
> +               goto unlock_exit;
> +       }
> +
> +       nent = ARRAY_SIZE(arm64_ftr_regs);
> +       reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
> +                                GFP_KERNEL);
> +       if (!reg_bits_array) {
> +               ret = ENOMEM;
> +               goto unlock_exit;
> +       }
> +
> +       /* Copy entries from arm64_ftr_regs to reg_bits_array */
> +       for (i = 0; i < nent; i++) {
> +               bits = &reg_bits_array[i];
> +               bits->sys_id = arm64_ftr_regs[i].sys_id;
> +               bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
> +       };
> +
> +       /*
> +        * Override the entries in reg_bits_array with the ones in
> +        * arm64_ftr_bits_kvm_override.
> +        */
> +       for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
> +               o_bits = &arm64_ftr_bits_kvm_override[i];
> +               for (j = 0; j < nent; j++) {
> +                       bits = &reg_bits_array[j];
> +                       if (bits->sys_id != o_bits->sys_id)
> +                               continue;
> +
> +                       memset(ftr_temp, 0, sizeof(ftr_temp));
> +
> +                       /*
> +                        * Temporary save all entries in o_bits->ftr_bits
> +                        * to ftr_temp.
> +                        */
> +                       copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
> +
> +                       /*
> +                        * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
> +                        */
> +                       copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
> +
> +                       /*
> +                        * Override entries in o_bits->ftr_bits with the
> +                        * saved ones, and update bits->ftr_bits with
> +                        * o_bits->ftr_bits.
> +                        */
> +                       arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
> +                       bits->ftr_bits = o_bits->ftr_bits;
> +                       break;
> +               }
> +       }
> +
> +       arm64_ftr_bits_kvm_nentries = nent;
> +       arm64_ftr_bits_kvm = reg_bits_array;

I've just noticed that the patch has a problem in terms of memory ordering.
I'm thinking of fixing the code above as follows in the v5 patch.
---
        <...>
        arm64_ftr_bits_kvm_nentries = nent;

        /*
         * Make sure any data written earlier in this function are visible
         * from other CPUs before setting arm64_ftr_bits_kvm.
         */
        smp_wmb();

        WRITE_ONCE(arm64_ftr_bits_kvm, reg_bits_array);
        <...>
---

Also, I will fix the reader side code of those data in
get_arm64_ftr_bits_kvm().

Thanks,
Reiji


> +       ret = 0;
> +
> +unlock_exit:
> +       mutex_unlock(&arm64_ftr_bits_kvm_lock);
> +       return ret;
> +}
> +
> +static int search_cmp_ftr_reg_bits(const void *id, const void *regp)
> +{
> +       return ((int)(unsigned long)id -
> +               (int)((const struct __ftr_reg_bits_entry *)regp)->sys_id);
> +}
> +
> +static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
> +{
> +       const struct __ftr_reg_bits_entry *ret;
> +       int err;
> +
> +       if (!arm64_ftr_bits_kvm) {
> +               /* arm64_ftr_bits_kvm is not initialized yet. */
> +               err = init_arm64_ftr_bits_kvm();
> +               if (err)
> +                       return NULL;
> +       }
> +
> +       ret = bsearch((const void *)(unsigned long)sys_id,
> +                     arm64_ftr_bits_kvm,
> +                     arm64_ftr_bits_kvm_nentries,
> +                     sizeof(arm64_ftr_bits_kvm[0]),
> +                     search_cmp_ftr_reg_bits);
> +       if (ret)
> +               return ret->ftr_bits;
> +
> +       return NULL;
> +}
> +
> +/*
> + * Check if features (or levels of features) that are indicated in the ID
> + * register value @val are also indicated in @limit.
> + * This function is for KVM to check if features that are indicated in @val,
> + * which will be used as the ID register value for its guest, are supported
> + * on the host.
> + * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
> + * scheme, the function checks if values of the fields in @val are the same
> + * as the ones in @limit.
> + */
> +int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
> +{
> +       const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);
> +       u64 exposed_mask = 0;
> +
> +       if (!ftrp)
> +               return -ENOENT;
> +
> +       for (; ftrp->width; ftrp++) {
> +               s64 ftr_val = arm64_ftr_value(ftrp, val);
> +               s64 ftr_lim = arm64_ftr_value(ftrp, limit);
> +
> +               exposed_mask |= arm64_ftr_mask(ftrp);
> +
> +               if (ftr_val == ftr_lim)
> +                       continue;
> +
> +               if (ftr_val != arm64_ftr_safe_value(ftrp, ftr_val, ftr_lim))
> +                       return -E2BIG;
> +       }
> +
> +       /* Make sure that no unrecognized fields are set in @val. */
> +       if (val & ~exposed_mask)
> +               return -E2BIG;
> +
> +       return 0;
> +}
> +#endif /* CONFIG_KVM */
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From jhhwang at rtst.co.kr  Thu Jan  6 23:18:37 2022
From: jhhwang at rtst.co.kr (Jeaho Hwang)
Date: Fri, 7 Jan 2022 16:18:37 +0900
Subject: i2c-xiic: An error occurs while handling RX irq
In-Reply-To: <CAJk_X9gQnUJDz8mxbKDML_HsSEL1+FdmTbiDwo7JyoofBwntFA@mail.gmail.com>
References: <CAJk_X9gQnUJDz8mxbKDML_HsSEL1+FdmTbiDwo7JyoofBwntFA@mail.gmail.com>
Message-ID: <CAJk_X9hQZbbiCN9-DDsjcaUw-9jo7pTo2GpQGNOhpPGDCnotrA@mail.gmail.com>

>
> Hello xilinx and arm linux experts.
> We are testing periodic send & recv i2c msgs on zynq7000 based target
> board. It shows -5(EIO) errors rarely and works fine again from the
> next period.
> We use the Linux kernel 5.4.0 provided by Petalinux 2021.2, with
> RT-patch. Investigating the code I think the RT patch would not affect
> this symptom. We will also try to reproduce it with non-preempt-RT
> configuration.
> The debug log is attached below.

Hello. We investigated more and got the reason for the error return.

In general cases, 3 interrupts were raised for one i2c read as following log.

xiic_start_recv entry, ISR: 0xd0, CR: 0x1
xiic_isr entry
xiic_process: IER: 0x1b, ISR: 0xd0, pend: 0x10
xiic_process: SR: 0x8c, msg: f14e832a, nmsgs: 1
xiic_process, ISR: 0xca, CR: 0x1
xiic_process clr: 0x0
-------------------------------------------------------------------
the first irq handler was called by ISR(4): BUS NOT BUSY.
BC xiic_start_recv enabled interrupt but slave didn't start transmission yet.
This is unnecessary and the handler disables the BNB bit and ignores it.

xiic_isr entry
xiic_process: IER: 0x1b, ISR: 0xca, pend: 0xa
xiic_process: SR: 0x8c, msg: f14e832a, nmsgs: 1
xiic_process, ISR: 0xca, CR: 0x1
xiic_read_rx entry, bytes in fifo: 2, rem: 2, SR: 0x8c, CR: 0x1
xiic_process end of message, nmsgs: 1
xiic_process clr: 0xa
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The second irq handler works the real thing.

xiic_isr entry
xiic_process: IER: 0x1b, ISR: 0xd0, pend: 0x10
xiic_process: SR: 0xc8, msg: f14e832a, nmsgs: 1
xiic_process, ISR: 0xd0, CR: 0x1
xiic_process clr: 0x10

the third is raised BC the bus is idle but BNB is still enabled.

sometimes the threaded irq handler for the first irq could be delayed
so ISR could be read as 0xca.
Rarely, ISR could be read 0xC2 if the timing was between TXCOMP set
and RXFULL set.
AS PG090, pp14, RXFULL bit  is not set at the same time as Transmit
Complete bit.

In order to prevent this malfunction, We believe the best option is to
prevent the first irq. Is it possible?
The second option could be the consideration of this timing issue: the
walkaround.
We temporarily implemented the second read of ISR for the case
0x?A(TXCOMP && !RXFULL) and found that it works well.

Do you have better suggestions for this issue?

Happy new year!
Jeaho Hwang

>
> [   95.115539] i2c-dev: i2c-1 reading 2 bytes.
> [   95.115552] xiic-i2c 40700000.i2c: xiic_xfer entry SR: 0xc0
> [   95.115562] xiic-i2c 40700000.i2c: xiic_setclk entry,
> i2c->input_clk: 100000000, i2c->i2c_clk: 0
> [   95.115576] xiic-i2c 40700000.i2c: __xiic_start_xfer entry, msg:
> f14e832a, fifos space: 15
> [   95.115588] xiic-i2c 40700000.i2c: xiic_start_recv entry, ISR: 0xd0, CR: 0x1
> [   95.115605] xiic-i2c 40700000.i2c: xiic_isr entry
> [   95.115674] xiic-i2c 40700000.i2c: xiic_process: IER: 0x1b, ISR:
> 0xc2, pend: 0x2
>
>                            ~~~~~~~~
> [   95.115685] xiic-i2c 40700000.i2c: xiic_process: SR: 0x8c, msg:
> f14e832a, nmsgs: 1
> [   95.115698] xiic-i2c 40700000.i2c: xiic_process, ISR: 0xca, CR: 0x1
>
>          ~~~~~~~~
> [   95.115706] xiic-i2c 40700000.i2c: xiic_process error
>
> BC pend calculated was 0x2(XIIC_INTR_TX_ERROR_MASK without
> RX_FULL_MASK) this pended value is handled as an error. But the latter
> read value of ISR was 0xca, which means normal RX completion. It seems
> that reading ISR is too earlier or updating RXFULL bit is delayed.
>
> I found the second ISR print is added from commit
> a6183c1688142adcf55b11baff95222b47792644, by Raviteja. I wonder this
> or similar cases have been considered before. I also wonder if we
> should add the second chance of reading ISR in similar cases inside
> the irq handler (e.g. drivers/i2c/busses/i2c-xiic.c:635)
>
> Best regards.
> Jeaho Hwang.
> --
> ???, Jay Hwang, linux team manager of RTst



-- 
???, Jay Hwang, linux team manager of RTst
010-7242-1593


From yuzhao at google.com  Thu Jan  6 23:25:07 2022
From: yuzhao at google.com (Yu Zhao)
Date: Fri, 7 Jan 2022 00:25:07 -0700
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20220106103009.GA4420@willie-the-truck>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
 <20220105104526.GA3015@willie-the-truck>
 <YdYDzKvYbBwjfU3W@google.com>
 <20220106103009.GA4420@willie-the-truck>
Message-ID: <Ydfq051mnCeZjG3G@google.com>

On Thu, Jan 06, 2022 at 10:30:09AM +0000, Will Deacon wrote:
> On Wed, Jan 05, 2022 at 01:47:08PM -0700, Yu Zhao wrote:
> > On Wed, Jan 05, 2022 at 10:45:26AM +0000, Will Deacon wrote:
> > > On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> > > > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > > > index 870c39537dd0..56e4ef5d95fa 100644
> > > > --- a/arch/arm64/tools/cpucaps
> > > > +++ b/arch/arm64/tools/cpucaps
> > > > @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
> > > >  HAS_SYSREG_GIC_CPUIF
> > > >  HAS_TLB_RANGE
> > > >  HAS_VIRT_HOST_EXTN
> > > > +HW_AF
> > > >  HW_DBM
> > > >  KVM_PROTECTED_MODE
> > > >  MISMATCHED_CACHE_TYPE
> > > 
> > > As discussed in the previous threads, we really don't need the complexity
> > > of the additional cap for the arm64 part. Please can you just use the
> > > existing code instead? It's both simpler and, as you say, it's equivalent
> > > for existing hardware.
> > > 
> > > That way, this patch just ends up being a renaming exercise and we're all
> > > good.
> > 
> > No, renaming alone isn't enough. A caller needs to disable preemption
> > before calling system_has_hw_af(), and I don't think it's reasonable
> > to ask this caller to do it on x86 as well.
> > 
> > It seems you really prefer not to have HW_AF. So the best I can
> > accommodate, considering other potential archs, e.g., risc-v (I do
> > plan to provide benchmark results on risc-v, btw), is:
> > 
> >   static inline bool arch_has_hw_pte_young(bool local)
> >   {
> > 	bool hw_af;
> > 
> >   	if (local) {
> >   		WARN_ON(preemptible());
> >   		return cpu_has_hw_af();
> >   	}
> >   
> > 	preempt_disable();
> >   	hw_af = system_has_hw_af();
> > 	preempt_enable();
> > 
> > 	return hw_af;
> >   }
> > 
> > Or please give me something else I can call without disabling
> > preemption, sounds good?
> 
> Sure thing, let me take a look. Do you have your series on a public git
> tree someplace?

Thanks!

This patch (updated) on Gerrit:
https://linux-mm-review.googlesource.com/c/page-reclaim/+/1500/1

And the entire series:
git fetch https://linux-mm.googlesource.com/page-reclaim refs/changes/08/1508/1


From Tudor.Ambarus at microchip.com  Thu Jan  6 23:26:16 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Fri, 7 Jan 2022 07:26:16 +0000
Subject: [PATCH -next] dmaengine: at_xdmac: Fix missing unlock in
 at_xdmac_tasklet()
In-Reply-To: <20220107024047.1051915-1-yangyingliang@huawei.com>
References: <20220107024047.1051915-1-yangyingliang@huawei.com>
Message-ID: <40d912e2-119b-0772-59d0-7198d6879e50@microchip.com>

On 1/7/22 4:40 AM, Yang Yingliang wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Add the missing unlock before return from at_xdmac_tasklet().
> 
> Fixes: e77e561925df ("dmaengine: at_xdmac: Fix race over irq_status")
> Reported-by: Hulk Robot <hulkci at huawei.com>
> Signed-off-by: Yang Yingliang <yangyingliang at huawei.com>
> ---
>  drivers/dma/at_xdmac.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
> index a1da2b4b6d73..1476156af74b 100644
> --- a/drivers/dma/at_xdmac.c
> +++ b/drivers/dma/at_xdmac.c
> @@ -1681,8 +1681,10 @@ static void at_xdmac_tasklet(struct tasklet_struct *t)
>                 __func__, atchan->irq_status);
> 
>         if (!(atchan->irq_status & AT_XDMAC_CIS_LIS) &&
> -           !(atchan->irq_status & error_mask))
> +           !(atchan->irq_status & error_mask)) {
> +               spin_unlock_irq(&atchan->lock);
>                 return;

oh yes, thanks!
you can directly return spin_unlock_irq(&atchan->lock); to avoid the extra braces.
Anyway, it's good:
Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>

> +       }
> 
>         if (atchan->irq_status & error_mask)
>                 at_xdmac_handle_error(atchan);
> --
> 2.25.1
> 


From marcel at holtmann.org  Thu Jan  6 23:31:14 2022
From: marcel at holtmann.org (Marcel Holtmann)
Date: Fri, 7 Jan 2022 08:31:14 +0100
Subject: [PATCH v2] Bluetooth: btusb: Add support for Foxconn QCA 0xe0d0
In-Reply-To: <20220107035909.14912-1-aaron.ma@canonical.com>
References: <20211227102950.17968-1-aaron.ma@canonical.com>
 <20220107035909.14912-1-aaron.ma@canonical.com>
Message-ID: <67999A28-9971-4878-9BF3-EE16F8841B13@holtmann.org>

Hi Aaron,

> Add an ID of Qualcomm Bluetooth SoC WCN6855.
> 
> T:  Bus=05 Lev=01 Prnt=01 Port=03 Cnt=02 Dev#=  4 Spd=12   MxCh= 0
> D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
> P:  Vendor=0489 ProdID=e0d0 Rev= 0.01
> C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
> E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
> I:  If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
> I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
> I:* If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
> I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
> I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
> I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
> I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
> I:  If#= 1 Alt= 7 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E:  Ad=83(I) Atr=01(Isoc) MxPS=  65 Ivl=1ms
> E:  Ad=03(O) Atr=01(Isoc) MxPS=  65 Ivl=1ms
> 
> Signed-off-by: Aaron Ma <aaron.ma at canonical.com>
> ---
> V1 -> V2: rebase on bluetooth-next tree.
> 
> drivers/bluetooth/btusb.c | 3 +++
> 1 file changed, 3 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel



From krzysztof.kozlowski at canonical.com  Thu Jan  6 23:34:51 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 7 Jan 2022 08:34:51 +0100
Subject: [PATCH 08/24] ARM: dts: exynos: simplify PMIC DVS pin
 configuration in Peach Pi
In-Reply-To: <CAGOxZ52PjcMD0hFQa95NHO2M5Z+Gpx4HNO14+KCsYnCffLc3JQ@mail.gmail.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162207.257478-2-krzysztof.kozlowski@canonical.com>
 <CAGOxZ52PjcMD0hFQa95NHO2M5Z+Gpx4HNO14+KCsYnCffLc3JQ@mail.gmail.com>
Message-ID: <e13e70ff-1416-e0b8-93ae-991cf58a5f1d@canonical.com>

On 06/01/2022 19:47, Alim Akhtar wrote:
> Hi Krzysztof,
> 
> On Sat, Jan 1, 2022 at 1:15 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> The pin configuration for PMIC DVS (pmic-dvs-2 and pmic-dvs-3) are
>> exactly the same, so merge them.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  arch/arm/boot/dts/exynos5800-peach-pi.dts | 20 +++++++-------------
>>  1 file changed, 7 insertions(+), 13 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> index 6bf3fd37fb2b..eca805b83816 100644
>> --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
>> @@ -221,7 +221,7 @@ max77802: pmic at 9 {
>>                 interrupts = <1 IRQ_TYPE_NONE>;
>>                 pinctrl-names = "default";
>>                 pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
>> -                           <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
>> +                           <&pmic_dvs_1>, <&pmic_dvs_2>;
>>                 wakeup-source;
>>                 reg = <0x9>;
>>                 #clock-cells = <1>;
>> @@ -874,26 +874,20 @@ &sd1_cmd {
>>
>>  &pinctrl_2 {
>>         pmic_dvs_2: pmic-dvs-2 {
>> -               samsung,pins = "gpj4-2";
>> +               samsung,pins = "gpj4-2", "gpj4-3";
>>                 samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
>>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>>                 samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
>>         };
>> +};
>>
>> -       pmic_dvs_3: pmic-dvs-3 {
>> -               samsung,pins = "gpj4-3";
>> -               samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
>> -               samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>> -               samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
>> -       };
>> +/* pinctrl_3*/
>> +/* Drive SPI lines at x2 for better integrity */
>> +&spi2_bus {
>> +       samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
>>  };
>>
> Maybe move this spi2_bus part to patch #07 as the commit does not
> mention this change.
> 

Right, it should be part of #7.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan  6 23:47:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 7 Jan 2022 08:47:33 +0100
Subject: [RFT][PATCH 3/3] arm64: dts: exynos: drop incorrectly placed
 wakeup interrupts in Exynos850
In-Reply-To: <CAPLW+4mDWg1xAGEALNVN1vs8jb3rzH2VqEBfacTkM_gNxeuhRg@mail.gmail.com>
References: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
 <20211230195325.328220-3-krzysztof.kozlowski@canonical.com>
 <CAPLW+4mDWg1xAGEALNVN1vs8jb3rzH2VqEBfacTkM_gNxeuhRg@mail.gmail.com>
Message-ID: <66754058-187e-ffd5-71ba-4720101f5d98@canonical.com>

On 03/01/2022 22:09, Sam Protsenko wrote:
> On Thu, 30 Dec 2021 at 21:53, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> The pin controller device node is expected to have one (optional)
>> interrupt.  Its pin banks capable of external interrupts, should define
>> interrupts for each pin, unless a muxed interrupt is used.
>>
>> Exynos850 defined the second part - interrupt for each pin in wake-up
>> pin controller - but also added these interrupts in main device node,
>> which is not correct.
>>
>> Fixes: e3493220fd3e ("arm64: dts: exynos: Add initial Exynos850 SoC support")
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
> 
> Tested-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> 
> Despite some errors brought by this change:
> 
>     samsung-pinctrl 11850000.pinctrl: irq number not available
>     samsung-pinctrl 11c30000.pinctrl: irq number not available
> 
> the interrupts seem to be functional still. Tested on E850-96 board,
> by pressing buttons connected to gpa0..gpa1, and checking
> /proc/interrupts info. I guess it's ok to merge this one as is, and
> then work further to fix the driver (or dts?) accordingly.
> 
> Also, I submitted related patch ("arm64: dts: exynos: Add missing gpm6
> and gpm7 nodes to Exynos850"), please take a look.
> 

Several Exynos850 pinctrl banks use exynos_eint_gpio_init, so they need
the interrupt property (for external interrupts). Otherwise external
GPIO interrupts won't work. The ones you checked, could be the external
wakeup interrupts which are not affected here.

This change seems wrong. Instead one interrupt should be left. However I
don't know which - should be described in reference manual in interrupt
sources.


Best regards,
Krzysztof


From axe.yang at mediatek.com  Thu Jan  6 23:53:35 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 7 Jan 2022 15:53:35 +0800
Subject: [PATCH v1 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <63cd9b04-8ff5-00ff-bbc4-7bc110080e41@collabora.com>
References: <20211227083641.12538-1-axe.yang@mediatek.com>
 <20211227083641.12538-4-axe.yang@mediatek.com>
 <63cd9b04-8ff5-00ff-bbc4-7bc110080e41@collabora.com>
Message-ID: <ff5616ca0cbace3c304b94246f405b5831de1a41.camel@mediatek.com>

On Tue, 2022-01-04 at 11:44 +0100, AngeloGioacchino Del Regno wrote:
> Il 27/12/21 09:36, Axe Yang ha scritto:
> > Add support for eint irq when MSDC is used as an SDIO host. This
> > feature requires SDIO device support async irq function. With this
> > feature,SDIO host can be awakened by SDIO card in suspend state,
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in msdc node
> > to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
> > are mandatory. And cap-sdio-async-int flag is necessary since this
> > feature depends on asynchronous interrupt:
> > 	&mmcX {
> > 		...
> > 		pinctrl-names = "default", "state_uhs", "state_eint",
> > 						"state_dat1";
> > 		...
> > 		pinctrl-2 = <&mmc2_pins_eint>;
> > 		pinctrl-3 = <&mmc2_pins_dat1>;
> > 		...
> > 		cap-sdio-async-int;
> > 		...
> > 	};
> > 
> > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> 
> Hello Axe,
> I agree on Andy's review, and I have some more comments...
> 
> > ---
> >   drivers/mmc/host/mtk-sd.c | 113
> > ++++++++++++++++++++++++++++++++++++--
> >   1 file changed, 107 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 4dfc246c5f95..8f23349f2963 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -1,6 +1,6 @@
> >   // SPDX-License-Identifier: GPL-2.0-only
> >   /*
> > - * Copyright (c) 2014-2015 MediaTek Inc.
> > + * Copyright (c) 2014-2021 MediaTek Inc.
> >    * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
> >    */
> >   
> > @@ -432,9 +432,13 @@ struct msdc_host {
> >   	struct pinctrl *pinctrl;
> >   	struct pinctrl_state *pins_default;
> >   	struct pinctrl_state *pins_uhs;
> > +	struct pinctrl_state *pins_eint;
> > +	struct pinctrl_state *pins_dat1;
> >   	struct delayed_work req_timeout;
> >   	int irq;		/* host interrupt */
> 
> int eint_irq; should be here, under the host interrupt, for the sake
> of perfection.

Will fix it in next version.

> 
> >   	struct reset_control *reset;
> > +	int eint_irq;		/* device interrupt */
> > +	int sdio_irq_cnt;	/* irq enable cnt */
> >   
> >   	struct clk *src_clk;	/* msdc source clock */
> >   	struct clk *h_clk;      /* msdc h_clk */
> > @@ -1519,10 +1523,12 @@ static void msdc_enable_sdio_irq(struct
> > mmc_host *mmc, int enb)
> >   	__msdc_enable_sdio_irq(host, enb);
> >   	spin_unlock_irqrestore(&host->lock, flags);
> >   
> > -	if (enb)
> > -		pm_runtime_get_noresume(host->dev);
> > -	else
> > -		pm_runtime_put_noidle(host->dev);
> > +	if (mmc->card && !mmc->card->cccr.enable_async_int) {
> > +		if (enb)
> 
> If you are going to rename `enb` to `enable, this means that you're
> changing the
> function signature... so, please, do that as a separated commit.

Okay, will keep 'enb' in this commit.

> 
> > +			pm_runtime_get_noresume(host->dev);
> > +		else
> > +			pm_runtime_put_noidle(host->dev);
> > +	}
> >   }
> >   
> >   static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32
> > intsts)
> > @@ -2380,6 +2386,49 @@ static const struct mmc_host_ops mt_msdc_ops
> > = {
> >   	.hw_reset = msdc_hw_reset,
> >   };
> >   
> > +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> > +{
> > +	unsigned long flags;
> > +	struct msdc_host *host = (struct msdc_host *)dev_id;
> > +	struct mmc_host *mmc = mmc_from_priv(host);
> > +
> > +	spin_lock_irqsave(&host->lock, flags);
> > +	if (likely(host->sdio_irq_cnt > 0)) {
> > +		disable_irq_nosync(host->eint_irq);
> > +		disable_irq_wake(host->eint_irq);
> > +		host->sdio_irq_cnt--;
> > +	}
> > +	spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +	sdio_signal_irq(mmc);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> > +{
> > +	struct gpio_desc *desc;
> > +	int ret = 0;
> > +	int irq;
> > +
> > +	desc = devm_gpiod_get_index(host->dev, "eint", 0, GPIOD_IN);
> > +	if (IS_ERR(desc))
> > +		return PTR_ERR(desc);
> > +
> > +	irq = gpiod_to_irq(desc);
> > +	if (irq >= 0) {
> > +		irq_set_status_flags(irq, IRQ_NOAUTOEN);
> > +		ret = devm_request_threaded_irq(host->dev, irq, NULL,
> > msdc_sdio_eint_irq,
> > +						IRQF_TRIGGER_LOW |
> > IRQF_ONESHOT,
> > +						"sdio-eint", host);
> 
> I think you may have misunderstood what Andy tried to say in his
> review: your call
> to the function irq_set_status_flags() is using the right flag -- the
> suggestion
> here is to add the IRQF_NO_AUTOEN flag to the call to
> devm_request_threaded_irq()
> (ex: IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN) and remove the
> now redundant
> call to irq_set_status_flags().

Thank you for explanation. Will fix it in next version.

> 
> 
> > +	} else {
> > +		ret = irq;
> > +	}
> > +
> > +	host->eint_irq = irq;
> > +	return ret;
> > +}
> > +
> >   static const struct cqhci_host_ops msdc_cmdq_ops = {
> >   	.enable         = msdc_cqe_enable,
> >   	.disable        = msdc_cqe_disable,
> > @@ -2534,6 +2583,19 @@ static int msdc_drv_probe(struct
> > platform_device *pdev)
> >   		goto host_free;
> >   	}
> >   
> > +	/* Support for SDIO eint irq */
> > +	host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> > "state_eint");
> > +	if (IS_ERR(host->pins_eint)) {
> > +		dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
> > +	} else {
> > +		host->pins_dat1 = pinctrl_lookup_state(host->pinctrl,
> > "state_dat1");
> > +		if (IS_ERR(host->pins_dat1)) {
> > +			ret = PTR_ERR(host->pins_dat1);
> > +			dev_err(&pdev->dev, "Cannot find pinctrl
> > dat1!\n");
> > +			goto host_free;
> > +		}
> > +	}
> > +
> >   	msdc_of_property_parse(pdev, host);
> >   
> >   	host->dev = &pdev->dev;
> > @@ -2621,6 +2683,16 @@ static int msdc_drv_probe(struct
> > platform_device *pdev)
> >   	if (ret)
> >   		goto release;
> >   
> > +	if (!IS_ERR(host->pins_eint) && !IS_ERR(host->pins_dat1)) {
> > +		ret = msdc_request_dat1_eint_irq(host);
> > +		if (ret) {
> > +			dev_err(host->dev, "Failed to register data1
> > eint irq!\n");
> > +			goto release;
> > +		}
> > +
> > +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> > +	}
> > +
> >   	pm_runtime_set_active(host->dev);
> >   	pm_runtime_set_autosuspend_delay(host->dev,
> > MTK_MMC_AUTOSUSPEND_DELAY);
> >   	pm_runtime_use_autosuspend(host->dev);
> > @@ -2740,21 +2812,50 @@ static void msdc_restore_reg(struct
> > msdc_host *host)
> >   
> >   static int __maybe_unused msdc_runtime_suspend(struct device
> > *dev)
> >   {
> > +	unsigned long flags;
> >   	struct mmc_host *mmc = dev_get_drvdata(dev);
> >   	struct msdc_host *host = mmc_priv(mmc);
> >   
> >   	msdc_save_reg(host);
> > +
> > +	if (!IS_ERR(host->pins_eint)) {
> > +		disable_irq(host->irq);
> > +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> > +		spin_lock_irqsave(&host->lock, flags);
> > +		if (host->sdio_irq_cnt == 0) {
> > +			enable_irq(host->eint_irq);
> > +			enable_irq_wake(host->eint_irq);
> > +			host->sdio_irq_cnt++;
> > +		}
> > +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > +		spin_unlock_irqrestore(&host->lock, flags);
> > +	}
> >   	msdc_gate_clock(host);
> >   	return 0;
> >   }
> >   
> >   static int __maybe_unused msdc_runtime_resume(struct device *dev)
> >   {
> > +	unsigned long flags;
> >   	struct mmc_host *mmc = dev_get_drvdata(dev);
> >   	struct msdc_host *host = mmc_priv(mmc);
> >   
> >   	msdc_ungate_clock(host);
> >   	msdc_restore_reg(host);
> > +	if (!IS_ERR(host->pins_eint)) {
> > +		spin_lock_irqsave(&host->lock, flags);
> > +		if (host->sdio_irq_cnt > 0) {
> > +			disable_irq_nosync(host->eint_irq);
> > +			disable_irq_wake(host->eint_irq);
> > +			host->sdio_irq_cnt--;
> > +			sdr_set_bits(host->base + SDC_CFG,
> > SDC_CFG_SDIOIDE);
> > +		} else {
> > +			sdr_clr_bits(host->base + MSDC_INTEN,
> > MSDC_INTEN_SDIOIRQ);
> > +		}
> > +		spin_unlock_irqrestore(&host->lock, flags);
> > +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> > +		enable_irq(host->irq);
> > +	}
> >   	return 0;
> >   }
> >   
> > @@ -2778,7 +2879,7 @@ static int __maybe_unused msdc_resume(struct
> > device *dev)
> >   }
> >   
> >   static const struct dev_pm_ops msdc_dev_pm_ops = {
> > -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> > +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> 
> Just a nitpick: msdc_{suspend,resume} are now noirq, so you should
> change the
> function names to msdc_suspend_noirq, msdc_resume_noirq.

Will fix it in next version. Thank you for your suggestion.

> 
> >   	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume,
> > NULL)
> >   };
> >   
> > 
> 
> Regards,
> - Angelo
> 

From linmq006 at gmail.com  Thu Jan  6 23:54:24 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri,  7 Jan 2022 07:54:24 +0000
Subject: [PATCH] spi: spi-meson-spifc: Add missing pm_runtime_disable() in
 meson_spifc_probe
Message-ID: <20220107075424.7774-1-linmq006@gmail.com>

If the probe fails, we should use pm_runtime_disable() to balance
pm_runtime_enable().
Add missing pm_runtime_disable() for meson_spifc_probe.

Fixes: c3e4bc5434d2 ("spi: meson: Add support for Amlogic Meson SPIFC")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/spi/spi-meson-spifc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c
index 8eca6f24cb79..c8ed7815c4ba 100644
--- a/drivers/spi/spi-meson-spifc.c
+++ b/drivers/spi/spi-meson-spifc.c
@@ -349,6 +349,7 @@ static int meson_spifc_probe(struct platform_device *pdev)
 	return 0;
 out_clk:
 	clk_disable_unprepare(spifc->clk);
+	pm_runtime_disable(spifc->dev);
 out_err:
 	spi_master_put(master);
 	return ret;
-- 
2.17.1



From jbrunet at baylibre.com  Thu Jan  6 23:54:45 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 07 Jan 2022 08:54:45 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
Message-ID: <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>


On Fri 07 Jan 2022 at 10:40, Liang Yang <liang.yang at amlogic.com> wrote:

> Hi Miquel,
>
> Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i
> don't find the commit in
> linux mainline. then the information i got from [jianxin.pan at amlogic.com]
> is the rejection of
> serial patches. I just look into the corresponding emails in link:
>
> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
> it seems the patch never go on since V6, so [jianxin.pan at amlogic.com],
> could you help to clear it?
> let us address the discussion in another email from
> [jbrunet at baylibre.com].

That V6 was "rejected" because some comments from thre V5 were still not
addressed. 

>
> On 2022/1/6 16:08, Miquel Raynal wrote:
>> [ EXTERNAL EMAIL ]
>> Hi Liang,
>> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
>> 
>>> Because EMMC and NAND have the same control clock register, so we
>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>
>>> 	sd_emmc_c_clkc: mmc at 7000 {
>>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>> 		reg = <0x0 0x7000 0x0 0x800>;
>>> 	};
>>>
>>> 	nand-controller at 7800 {
>>> 		......
>>>
>>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>> 		clock-names = "core", "device", "rx", "tx";
>>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>
>>> 		......
>>> 	}
>>>
>>> but in fact, above implementation is rejected. so now registering
>>> a nand_divider.
>> What is rejected?
>> Why is it rejected?
>> What is nand_divider?
> i simplify our clock framework below, so nand divider is SD_EMMC_CLOCK[5:0]
> here.
> 			   -----          -----		    -----
> 	   the other------|	\        |     |	   |	 |
>          		  | mux	| -----  |  N  | ----------| NFC/|
> 	   FCLK_DIV2------|     |        |     |	   | EMMC|
> 			   -----/         ----- 	    -----
> 		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
>> 
>>>
>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>> Change Ids are not expected in the upstream kernel.
>> But if you fix something you should have a Fixes:.
>> 
>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>> ---
>>>   drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>   1 file changed, 49 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index ac3be92872d0..4472363059c2 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -2,7 +2,7 @@
>>>   /*
>>>    * Amlogic Meson Nand Flash Controller Driver
>>>    *
>>> - * Copyright (c) 2018 Amlogic, inc.
>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>>    */
>>>   @@ -10,6 +10,7 @@
>>>   #include <linux/dma-mapping.h>
>>>   #include <linux/interrupt.h>
>>>   #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/mtd/rawnand.h>
>>>   #include <linux/mtd/mtd.h>
>>>   #include <linux/mfd/syscon.h>
>>> @@ -55,6 +56,7 @@
>>>   #define NFC_REG_VER		0x38
>>>     #define NFC_RB_IRQ_EN		BIT(21)
>>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>>     #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)
>>> \
>>>   	(								\
>>> @@ -104,6 +106,9 @@
>>>     #define PER_INFO_BYTE		8
>>>   +#define CLK_DIV_SHIFT		0
>>> +#define CLK_DIV_WIDTH		6
>>> +
>>>   struct meson_nfc_nand_chip {
>>>   	struct list_head node;
>>>   	struct nand_chip nand;
>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>   	struct nand_controller controller;
>>>   	struct clk *core_clk;
>>>   	struct clk *device_clk;
>>> -	struct clk *phase_tx;
>>> -	struct clk *phase_rx;
>>> +	struct clk *nand_clk;
>>> +	struct clk_divider nand_divider;
>>>     	unsigned long clk_rate;
>>>   	u32 bus_timing;
>>>     	struct device *dev;
>>>   	void __iomem *reg_base;
>>> -	struct regmap *reg_clk;
>>> +	void __iomem *reg_clk;
>>>   	struct completion completion;
>>>   	struct list_head chips;
>>>   	const struct meson_nfc_data *data;
>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>   	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>   		| nfc->param.chip_select | nfc->timing.tbers_max;
>>>   	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>> -
>>> +	meson_nfc_drain_cmd(nfc);
>>>   	ret = wait_for_completion_timeout(&nfc->completion,
>>>   					  msecs_to_jiffies(timeout_ms));
>>>   	if (ret == 0)
>>>   		ret = -1;
>>>   +	/* reset command fifo to avoid lock */
>>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>   	return ret;
>>>   }
>>>   @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops
>>> meson_ooblayout_ops = {
>>>   static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   {
>>>   	int ret;
>>> +	struct clk_init_data init = {0};
>>> +	const char *fix_div2_pll_name[1];
>>>   -	/* request core clock */
>>>   	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>   	if (IS_ERR(nfc->core_clk)) {
>>>   		dev_err(nfc->dev, "failed to get core clock\n");
>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   		return PTR_ERR(nfc->device_clk);
>>>   	}
>>>   -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>> -	if (IS_ERR(nfc->phase_tx)) {
>>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>>> -		return PTR_ERR(nfc->phase_tx);
>>> -	}
>>> -
>>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>> -	if (IS_ERR(nfc->phase_rx)) {
>>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>>> -		return PTR_ERR(nfc->phase_rx);
>>> -	}
>>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>> +	init.ops = &clk_divider_ops;
>>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>> +	init.parent_names = fix_div2_pll_name;
>>> +	init.num_parents = 1;
>>> +	nfc->nand_divider.reg = nfc->reg_clk;
>>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>>> +	nfc->nand_divider.hw.init = &init;
>>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>>> +
>>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>> +	if (IS_ERR(nfc->nand_clk))
>>> +		return PTR_ERR(nfc->nand_clk);
>>>     	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>> -	regmap_update_bits(nfc->reg_clk,
>>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>     	ret = clk_prepare_enable(nfc->core_clk);
>>>   	if (ret) {
>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>   		goto err_device_clk;
>>>   	}
>>>   -	ret = clk_prepare_enable(nfc->phase_tx);
>>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>>   	if (ret) {
>>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>>> -		goto err_phase_tx;
>>> -	}
>>> -
>>> -	ret = clk_prepare_enable(nfc->phase_rx);
>>> -	if (ret) {
>>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>>> -		goto err_phase_rx;
>>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>> +		goto err_nand_clk;
>>>   	}
>>>     	ret = clk_set_rate(nfc->device_clk, 24000000);
>>>   	if (ret)
>>> -		goto err_disable_rx;
>>> +		goto err_disable_clk;
>>>     	return 0;
>>>   -err_disable_rx:
>>> -	clk_disable_unprepare(nfc->phase_rx);
>>> -err_phase_rx:
>>> -	clk_disable_unprepare(nfc->phase_tx);
>>> -err_phase_tx:
>>> +err_disable_clk:
>>> +	clk_disable_unprepare(nfc->nand_clk);
>>> +err_nand_clk:
>>>   	clk_disable_unprepare(nfc->device_clk);
>>>   err_device_clk:
>>>   	clk_disable_unprepare(nfc->core_clk);
>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>     static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>   {
>>> -	clk_disable_unprepare(nfc->phase_rx);
>>> -	clk_disable_unprepare(nfc->phase_tx);
>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>   	clk_disable_unprepare(nfc->device_clk);
>>>   	clk_disable_unprepare(nfc->core_clk);
>>>   }
>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>   	struct device *dev = &pdev->dev;
>>>   	struct meson_nfc *nfc;
>>>   	struct resource *res;
>>> +	u32 ext_clk_reg;
>>>   	int ret, irq;
>>>     	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>   	if (IS_ERR(nfc->reg_base))
>>>   		return PTR_ERR(nfc->reg_base);
>>>   -	nfc->reg_clk =
>>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>>> -						"amlogic,mmc-syscon");
>>> +	ret = of_property_read_u32(pdev->dev.of_node,
>>> +				   "sd_emmc_c_clkc",
>>> +				   &ext_clk_reg);
>>> +	if (ret) {
>>> +		dev_err(dev, "failed to get NAND external clock register\n");
>>> +		return ret;
>>> +	}
>>> +
>>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>   	if (IS_ERR(nfc->reg_clk)) {
>>>   		dev_err(dev, "Failed to lookup clock base\n");
>>>   		return PTR_ERR(nfc->reg_clk);
>> 
>> Thanks,
>> Miqu?l
>> .



From qinjian at cqplus1.com  Thu Jan  6 23:55:18 2022
From: qinjian at cqplus1.com (=?utf-8?B?cWluamlhblvopoPlgaVd?=)
Date: Fri, 7 Jan 2022 07:55:18 +0000
Subject: [PATCH v7 06/10] clk: Add Sunplus SP7021 clock driver
In-Reply-To: <20220106004249.90484C36AEB@smtp.kernel.org>
References: <cover.1640154492.git.qinjian@cqplus1.com>
 <7f8302e2c1d02141dd69d2524eaa857d6494fdc7.1640154492.git.qinjian@cqplus1.com>
 <20220106004249.90484C36AEB@smtp.kernel.org>
Message-ID: <51a2cbddc978400086271fc735493566@cqplus1.com>

> > +
> > +CLK_OF_DECLARE_DRIVER(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
> 
> Why CLK_OF_DECLARE_DRIVER? There should be a comment but better would be
> to make a platform driver instead. If the platform driver can't be used,
> we need to know what other device driver is probing based on this clkc
> compatible string.

Dear Stephen,

Sorry, I don't understand your comment.
Did you mean, like below:

static int sp7021_clk_probe(struct platform_device *pdev)
{
	......
	sp_clk_data->num = CLK_MAX;
	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
}

static const struct of_device_id sp7021_clk_dt_ids[] = {
	{ .compatible = "sunplus,sp7021-clkc", },
	{ }
};
MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);

static struct platform_driver sp7021_clk_driver = {
	.probe  = sp7021_clk_probe,
	.driver = {
		.name = "sp7021-clk",
		.of_match_table = sp7021_clk_dt_ids,
	},
};
builtin_platform_driver(sp7021_clk_driver);


But, It's doesn't work. 
Most other clk drivers used CLK_OF_DECLARE_DRIVER or CLK_OF_DECLARE.
I just take these as the reference and it's working.

From krzysztof.kozlowski at canonical.com  Fri Jan  7 00:05:57 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 7 Jan 2022 09:05:57 +0100
Subject: [PATCH] arm64: dts: exynos: Add missing gpm6 and gpm7 nodes to
 Exynos850
In-Reply-To: <20220103181826.2136-1-semen.protsenko@linaro.org>
References: <20220103181826.2136-1-semen.protsenko@linaro.org>
Message-ID: <b40fedf8-73d7-6f4e-d26e-2f274b15228a@canonical.com>

On 03/01/2022 19:18, Sam Protsenko wrote:
> gpm6 and gpm7 nodes are missing in Exynos850 device tree. Next errors
> are reported because of that:
> 
>     Missing node for bank gpm6 - invalid DTB
>     Missing node for bank gpm7 - invalid DTB
> 
> Add missing nodes to make those available to use, and to fix boot
> errors.
> 
> Fixes: e3493220fd3e ("arm64: dts: exynos: Add initial Exynos850 SoC support")
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
> NOTES:
>   - Recommend to apply this patch after "arm64: dts: exynos: align
>     pinctrl with dtschema in Exynos850"
>   - This patch also brings back two interrupts removed in "arm64:
>     dts: exynos: drop incorrectly placed wakeup interrupts in Exynos850"

I'll take it after the merge window and apply it before my series (so
without -gpio-bank suffix).

> 
>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 20 +++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> index a71acf358d2d..f43e4a206282 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> @@ -194,6 +194,26 @@ gpm5: gpm5-gpio-bank {
>  		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
>  	};
>  
> +	gpm6: gpm6-gpio-bank {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	gpm7: gpm7-gpio-bank {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
>  	/* USI_CMGP0: HSI2C function */
>  	hsi2c3_pins: hsi2c3-pins {
>  		samsung,pins = "gpm0-0", "gpm1-0";
> 


Best regards,
Krzysztof


From thunder.leizhen at huawei.com  Fri Jan  7 00:13:00 2022
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Fri, 7 Jan 2022 16:13:00 +0800
Subject: [PATCH v18 02/17] x86/setup: Move xen_pv_domain() check and
 insert_resource() to setup_arch()
In-Reply-To: <5d8aed79-b20f-2575-3c3f-8945d8cbac3f@huawei.com>
References: <20211222130820.1754-1-thunder.leizhen@huawei.com>
 <20211222130820.1754-3-thunder.leizhen@huawei.com> <YcSxLodOnxXHx0sV@zn.tnic>
 <d6226aa2-f1f2-24cc-c9d2-9762bd615686@huawei.com>
 <5d8aed79-b20f-2575-3c3f-8945d8cbac3f@huawei.com>
Message-ID: <7e7c8d93-e745-2bfd-b93d-aecb3b70bf33@huawei.com>



On 2021/12/25 9:53, Leizhen (ThunderTown) wrote:
> 
> 
> On 2021/12/24 14:36, Leizhen (ThunderTown) wrote:
>>
>>
>> On 2021/12/24 1:26, Borislav Petkov wrote:
>>> On Wed, Dec 22, 2021 at 09:08:05PM +0800, Zhen Lei wrote:
>>>> From: Chen Zhou <chenzhou10 at huawei.com>
>>>>
>>>> We will make the functions reserve_crashkernel() as generic, the
>>>> xen_pv_domain() check in reserve_crashkernel() is relevant only to
>>>> x86,
>>>
>>> Why is that so? Is Xen-PV x86-only?
>>>
>>>> the same as insert_resource() in reserve_crashkernel[_low]().
>>>
>>> Why?
>>>
>>> Looking at
>>>
>>>   0212f9159694 ("x86: Add Crash kernel low reservation")
>>>
>>> it *surprisingly* explains why that resources thing is being added:
>>>
>>>     We need to add another range in /proc/iomem like "Crash kernel low",
>>>     so kexec-tools could find that info and append to kdump kernel
>>>     command line.
>>>
>>> Then,
>>>
>>>   157752d84f5d ("kexec: use Crash kernel for Crash kernel low")
>>>
>>> renamed it because, as it states, kexec-tools was taught to handle
>>> multiple resources of the same name.
>>>
>>> So why does kexec-tools on arm *not* need those iomem resources? How
>>> does it parse the ranges there? Questions over questions...

Hi Borislav:
  The reason why insert_resource() cannot be used in reserve_crashkernel[_low]()
on arm64 is clear. The parent resource node of crashk[_low]_res is added by
request_resource() in request_standard_resources(), so that it will be conflicted.
All request_resource() in request_standard_resources() should be changed to
insert_resource(), to make insert_resource() can be used in reserve_crashkernel[_low]().

  I found commit e25e6e7593ca ("kdump, x86: Process multiple Crash kernel in /proc/iomem")
in kexec-tools. I'm trying to port it to arm64, or make it generic.

  Thanks.

> 
> It's a good question worth figuring out. I'm going to dig into this.
> I admire your rigorous style and sharp vision.
> 


-- 
Regards,
  Zhen Lei


From axe.yang at mediatek.com  Fri Jan  7 00:19:54 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 7 Jan 2022 16:19:54 +0800
Subject: [PATCH v1 1/3] dt-bindings: mmc: add cap-sdio-async-int flag
In-Reply-To: <YdTLI/Nms4JiNutt@robh.at.kernel.org>
References: <20211227083641.12538-1-axe.yang@mediatek.com>
 <20211227083641.12538-2-axe.yang@mediatek.com>
 <YdTLI/Nms4JiNutt@robh.at.kernel.org>
Message-ID: <21ba4c9d2f3a7a3d8c12b303fc6bea4b19ef092f.camel@mediatek.com>

On Tue, 2022-01-04 at 16:33 -0600, Rob Herring wrote:
> On Mon, Dec 27, 2021 at 04:36:39PM +0800, Axe Yang wrote:
> > Asynchronous interrupt is a mechanism that allow SDIO devices alarm
> > interrupt when host stop providing clock to card. Add a DT flag to
> > enable this feature if it is supported by SDIO card.
> 
> A card property should be in the card node. Is this not discoverable?

Thank you for your comment.
Async interrupt is not a 'card property', but more like a protocol.
The intention of this flag is to decide whether to support this feature
on SDIO host side.
Before that, host need to confirm that async interrupt is supported on
card side(by read and parse Support Async Interrupt segment in CCCR
from card).

> 
> > 
> > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> > ---
> >  Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5
> > +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mmc/mmc-
> > controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-
> > controller.yaml
> > index 25ac8e200970..7230421583c6 100644
> > --- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
> > +++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
> > @@ -165,6 +165,11 @@ properties:
> >      description:
> >        eMMC hardware reset is supported
> >  
> > +  cap-sdio-async-int:
> 
> Perhaps be consistent with the next property and use 'irq'.

Will fix it in next version.

> 
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      SDIO async interrupt is supported.
> > +
> >    cap-sdio-irq:
> >      $ref: /schemas/types.yaml#/definitions/flag
> >      description:
> > -- 
> > 2.25.1
> > 
> > 

From wenst at chromium.org  Fri Jan  7 00:36:15 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 7 Jan 2022 16:36:15 +0800
Subject: [PATCH v7 4/4] arm64: dts: Add mediatek SoC mt8195 and evaluation
 board
In-Reply-To: <18c342b20ccac520eabe8019562432030ddfe017.camel@mediatek.com>
References: <20211220121825.6446-1-tinghan.shen@mediatek.com>
 <20211220121825.6446-5-tinghan.shen@mediatek.com>
 <CAGXv+5GaFikojqYYv0TfQsz3NSqn7QPmTWyCJY8V2g8UYoV4OA@mail.gmail.com>
 <18c342b20ccac520eabe8019562432030ddfe017.camel@mediatek.com>
Message-ID: <CAGXv+5G45UP=kvk8UOiFWYfdWgdjboL-UfkBbfPuEmQpwKMNHQ@mail.gmail.com>

On Thu, Jan 6, 2022 at 7:15 PM Tinghan Shen <tinghan.shen at mediatek.com> wrote:
> On Thu, 2021-12-23 at 17:59 +0800, Chen-Yu Tsai wrote:
> > On Mon, Dec 20, 2021 at 8:20 PM Tinghan Shen <tinghan.shen at mediatek.com> wrote:

[...]

> > [...]
> >
> > > +               xhci0: usb at 11200000 {
> > > +                       compatible = "mediatek,mt8195-xhci",
> > > +                                    "mediatek,mtk-xhci";
> > > +                       reg = <0 0x11200000 0 0x1000>,
> > > +                             <0 0x11203e00 0 0x0100>;
> > > +                       reg-names = "mac", "ippc";
> > > +                       interrupts = <GIC_SPI 129
> > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > +                       phys = <&u2port0 PHY_TYPE_USB2>,
> > > +                              <&u3port0 PHY_TYPE_USB3>;
> > > +                       assigned-clocks = <&topckgen
> > > CLK_TOP_USB_TOP>,
> > > +                                         <&topckgen
> > > CLK_TOP_SSUSB_XHCI>;
> > > +                       assigned-clock-parents = <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>,
> > > +                                                <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>;
> > > +                       clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
> > > +                                <&infracfg_ao
> > > CLK_INFRA_AO_SSUSB_XHCI>,
> > > +                                <&topckgen CLK_TOP_SSUSB_REF>,
> > > +                                <&apmixedsys CLK_APMIXED_USB1PLL>;
> > > +                       clock-names = "sys_ck", "xhci_ck",
> > > "ref_ck", "mcu_ck";
> >
> > The binding for this needs to be fixed. It expects clocks in the
> > order
> > specified in the binding, and this doesn't match.
>
> ok
>
> > Also, "dma_ck" is missing
> > and will likely cause warnings to be generated.
>
> only sys_ck is required, others are optional as described in binding

I understand, but the bindings language is somewhat limited and right now
is written in a way that if "dma_ck" is missing it would fail the DT
bindings check.

> >
> > This goes for all the xhci device nodes.
> >
> > > +                       status = "disabled";
> > > +               };
> > > +
> > > +               mmc0: mmc at 11230000 {
> > > +                       compatible = "mediatek,mt8195-mmc",
> > > +                                    "mediatek,mt8183-mmc";
> > > +                       reg = <0 0x11230000 0 0x10000>,
> > > +                             <0 0x11f50000 0 0x1000>;
> >
> > The binding only allows one entry. Please fix the binding first.
> > This was added with MT8183, and the fix should list the relavent
> > commit.
> >
> > > +                       interrupts = <GIC_SPI 131
> > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > +                       clocks = <&topckgen CLK_TOP_MSDC50_0>,
> > > +                                <&infracfg_ao CLK_INFRA_AO_MSDC0>,
> > > +                                <&infracfg_ao
> > > CLK_INFRA_AO_MSDC0_SRC>;
> > > +                       clock-names = "source", "hclk",
> > > "source_cg";
> > > +                       status = "disabled";
> > > +               };
> > > +
> >
> > [...]
> >
> > > +
> > > +               xhci1: usb at 11290000 {
> > > +                       compatible = "mediatek,mt8195-xhci",
> > > +                                    "mediatek,mtk-xhci";
> > > +                       reg = <0 0x11290000 0 0x1000>,
> > > +                             <0 0x11293e00 0 0x0100>;
> > > +                       reg-names = "mac", "ippc";
> > > +                       interrupts = <GIC_SPI 530
> > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > +                       phys = <&u2port1 PHY_TYPE_USB2>;
> >
> > Shouldn't there be a USB3 phy?
>
> currently only enable usb2, usb3 phy is used by pcie.

Got it.

> >
> > > +                       assigned-clocks = <&topckgen
> > > CLK_TOP_USB_TOP_1P>,
> > > +                                         <&topckgen
> > > CLK_TOP_SSUSB_XHCI_1P>;
> > > +                       assigned-clock-parents = <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>,
> > > +                                                <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>;
> > > +                       clocks = <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_1P_BUS>,
> > > +                                <&topckgen CLK_TOP_SSUSB_P1_REF>,
> > > +                                <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_1P_XHCI>,
> > > +                                <&apmixedsys CLK_APMIXED_USB1PLL>;
> > > +                       clock-names = "sys_ck", "ref_ck",
> > > "xhci_ck", "mcu_ck";
> > > +                       status = "disabled";
> > > +               };
> > > +
> > > +               xhci2: usb at 112a0000 {
> > > +                       compatible = "mediatek,mt8195-xhci",
> > > +                                    "mediatek,mtk-xhci";
> > > +                       reg = <0 0x112a0000 0 0x1000>,
> > > +                             <0 0x112a3e00 0 0x0100>;
> > > +                       reg-names = "mac", "ippc";
> > > +                       interrupts = <GIC_SPI 533
> > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > +                       phys = <&u2port2 PHY_TYPE_USB2>;
> > > +                       assigned-clocks = <&topckgen
> > > CLK_TOP_USB_TOP_2P>,
> > > +                                         <&topckgen
> > > CLK_TOP_SSUSB_XHCI_2P>;
> > > +                       assigned-clock-parents = <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>,
> > > +                                                <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>;
> > > +                       clocks = <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_2P_BUS>,
> > > +                                <&topckgen CLK_TOP_SSUSB_P2_REF>,
> > > +                                <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_2P_XHCI>;
> > > +                       clock-names = "sys_ck", "ref_ck",
> > > "xhci_ck";
> > > +                       status = "disabled";
> > > +               };
> > > +
> > > +               xhci3: usb at 112b0000 {
> > > +                       compatible = "mediatek,mt8195-xhci",
> > > +                                    "mediatek,mtk-xhci";
> > > +                       reg = <0 0x112b0000 0 0x1000>,
> > > +                             <0 0x112b3e00 0 0x0100>;
> > > +                       reg-names = "mac", "ippc";
> > > +                       interrupts = <GIC_SPI 536
> > > IRQ_TYPE_LEVEL_HIGH 0>;
> > > +                       phys = <&u2port3 PHY_TYPE_USB2>;
> > > +                       assigned-clocks = <&topckgen
> > > CLK_TOP_USB_TOP_3P>,
> > > +                                         <&topckgen
> > > CLK_TOP_SSUSB_XHCI_3P>;
> > > +                       assigned-clock-parents = <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>,
> > > +                                                <&topckgen
> > > CLK_TOP_UNIVPLL_D5_D4>;
> > > +                       clocks = <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_3P_BUS>,
> > > +                                <&pericfg_ao
> > > CLK_PERI_AO_SSUSB_3P_XHCI>,
> > > +                                <&topckgen CLK_TOP_SSUSB_P3_REF>;
> > > +                       clock-names = "sys_ck", "xhci_ck",
> > > "ref_ck";
> > > +                       usb2-lpm-disable;
> >
> > Could you explain why this is needed only for this controller?
>
> This controller is fixed with a BT, there is something issue when
> enable usb2 lpm, so just disabled tmp.

Please add a comment explaining things.

> > > +                       status = "disabled";
> > > +               };
> > > +
> > > +               u3phy2: t-phy at 11c40000 {
> >
> > Just "phy" for the node name. (Or maybe "serdes".) t-phy is not
> > generic.
>
> following t-phy?s dt-binding.
> here using t-phy is to avoid dt-check warning, because it has some sub-
> phys.

I see. t-phy it is, then.

> > > +                       compatible = "mediatek,mt8195-tphy",
> > > "mediatek,generic-tphy-v3";
> > > +                       #address-cells = <1>;
> > > +                       #size-cells = <1>;
> > > +                       ranges = <0 0 0x11c40000 0x700>;
> > > +                       status = "disabled";
> > > +
> > > +                       u2port2: usb-phy at 0 {
> > > +                               reg = <0x0 0x700>;
> > > +                               clocks = <&topckgen
> > > CLK_TOP_SSUSB_PHY_P2_REF>;
> > > +                               clock-names = "ref";
> > > +                               #phy-cells = <1>;
> > > +                       };
> > > +               };
> > > +
> >
> > [...]
> >
> > > +               ufsphy: ufs-phy at 11fa0000 {
> >
> > I would have preferred "phy" for the device node, but this seems
> > already
> > defined in the binding.
> >
> > This IP block is not listed in the datasheet I have, so I am unable
> > to
> > verify the properties listed here.
> >
> > > +                       compatible = "mediatek,mt8195-ufsphy",
> > > "mediatek,mt8183-ufsphy";
> > > +                       reg = <0 0x11fa0000 0 0xc000>;
> > > +                       clocks = <&clk26m>, <&clk26m>;
> > > +                       clock-names = "unipro", "mp";
> > > +                       #phy-cells = <0>;
> > > +                       status = "disabled";
> > > +               };
> > > +
> >
> > Most of the issues I raised in this version were issues with things
> > not
> > matching the bindings. Please apply your patches on -next and run
> > `make dtbs_check`.
>
> ok. I'll apply comments at next version. Thank you.
>
> >
> >
> > ChenYu
>


From linmq006 at gmail.com  Fri Jan  7 00:36:32 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri,  7 Jan 2022 08:36:32 +0000
Subject: [PATCH] drm/sun4i: dw-hdmi: Fix missing put_device() call in
 sun8i_hdmi_phy_get
Message-ID: <20220107083633.20843-1-linmq006@gmail.com>

The reference taken by 'of_find_device_by_node()' must be released when
not needed anymore.
Add the corresponding 'put_device()' in the error handling path.

Fixes: 9bf3797796f5 ("drm/sun4i: dw-hdmi: Make HDMI PHY into a platform device")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index b64d93da651d..5e2b0175df36 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -658,8 +658,10 @@ int sun8i_hdmi_phy_get(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 		return -EPROBE_DEFER;
 
 	phy = platform_get_drvdata(pdev);
-	if (!phy)
+	if (!phy) {
+		put_device(&pdev->dev);
 		return -EPROBE_DEFER;
+	}
 
 	hdmi->phy = phy;
 
-- 
2.17.1



From mhocko at suse.com  Fri Jan  7 00:43:49 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 09:43:49 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydde2F4Oi0wKx//y@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcTkrl84Xzg2dSz@dhcp22.suse.cz> <Ydde2F4Oi0wKx//y@google.com>
Message-ID: <Ydf9RXPch5ddg/WC@dhcp22.suse.cz>

On Thu 06-01-22 14:27:52, Yu Zhao wrote:
> On Thu, Jan 06, 2022 at 05:06:42PM +0100, Michal Hocko wrote:
[...]
> > > diff --git a/include/linux/oom.h b/include/linux/oom.h
> > > index 2db9a1432511..9c7a4fae0661 100644
> > > --- a/include/linux/oom.h
> > > +++ b/include/linux/oom.h
> > > @@ -57,6 +57,22 @@ struct oom_control {
> > >  extern struct mutex oom_lock;
> > >  extern struct mutex oom_adj_mutex;
> > >  
> > > +#ifdef CONFIG_MMU
> > > +extern struct task_struct *oom_reaper_list;
> > > +extern struct wait_queue_head oom_reaper_wait;
> > > +
> > > +static inline bool oom_reaping_in_progress(void)
> > > +{
> > > +	/* a racy check can be used to reduce the chance of overkilling */
> > > +	return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait);
> > > +}
> > > +#else
> > > +static inline bool oom_reaping_in_progress(void)
> > > +{
> > > +	return false;
> > > +}
> > > +#endif
> > 
> > I do not like this. These are internal oom reaper's and no code should
> > really make any decisions based on that. oom_reaping_in_progress is not
> > telling much anyway.
> 
> There is a perfectly legitimate reason for this.
> 
> If there is already a oom kill victim and the oom reaper is making
> progress, the system may still be under memory pressure until the oom
> reaping is done. The page reclaim has two choices in this transient
> state: kill more processes or keep reclaiming (a few more) hot pages.
> 
> The first choice, AKA overkilling, is generally a bad one. The oom
> reaper is single threaded and it can't go faster with additional
> victims. Additional processes are sacrificed for nothing -- this is
> an overcorrection of a system that tries to strike a balance between
> the tendencies to release memory pressure and to improve memory
> utilization.
> 
> > This is a global queue for oom reaper that can
> > contain oom victims from different oom scopes (e.g. global OOM, memcg
> > OOM or memory policy OOM).
> 
> True, but this is a wrong reason to make the conclusion below. Oom
> kill scopes do NOT matter; only the pool the freed memory goes into
> does. And there is only one global pool free pages.
> 
> > Your lru_gen_age_node uses this to decide whether to trigger
> > out_of_memory and that is clearly wrong for the above reasons.
> 
> I hope my explanation above is clear enough. There is nothing wrong
> with the purpose and the usage of oom_reaping_in_progress(), and it
> has been well tested in the Arch Linux Zen kernel.

I disagree. An ongoing oom kill in one domain (say memcg A) shouldn't be
any base for any decisions in reclaim in other domain (say memcg B or
even a global reclaim). Those are fundamentally different conditions.

> Without it, overkills can be easily reproduced by the following simple
> script. That is additional oom kills happen to processes other than
> "tail".
> 
>   # enable zram
>   while true;
>   do
>       tail /dev/zero
>   done

I would be interested to hear more (care to send oom reports?).

> > out_of_memory is designed to skip over any action if there is an oom
> > victim pending from the oom domain (have a look at oom_evaluate_task).
> 
> Where exactly? Point me to the code please.
> 
> I don't see such a logic inside out_of_memory() or
> oom_evaluate_task(). Currently the only thing that could remotely
> prevent overkills is oom_lock. But it's inadequate.

OK, let me try to exaplain. The protocol is rather convoluted. Once the
oom killer is invoked it choses a victim to kill. oom_evaluate_task will
evaluate _all_ tasks from the oom respective domain (select_bad_process
which distinguishes memcg vs global oom kill and oom_cpuset_eligible for
the cpuset domains). If there is any pre-existing oom victim
(tsk_is_oom_victim) then the scan is aborted and the oom killer bails
out. OOM victim stops being considered as relevant once the oom reaper
manages to release its address space (or give up on the mmap_sem
contention) and sets MMF_OOM_SKIP flag for the mm.

That being said the out_of_memory automatically backs off and relies on
the oom reaper to process its queue.

Does it make more clear for you now?

> This is the entire pipeline:
> low on memory -> out_of_memory() -> oom_reaper() -> free memory
> 
> To avoid overkills, we need to consider the later half of it too.
> oom_reaping_in_progress() is exactly for this purpose.
> 
> > > +static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc,
> > > +		       unsigned long min_ttl)
> > > +{
> > > +	bool need_aging;
> > > +	long nr_to_scan;
> > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > +	int swappiness = get_swappiness(memcg);
> > > +	DEFINE_MAX_SEQ(lruvec);
> > > +	DEFINE_MIN_SEQ(lruvec);
> > > +
> > > +	if (mem_cgroup_below_min(memcg))
> > > +		return false;
> > 
> > mem_cgroup_below_min requires effective values to be calculated for the
> > reclaimed hierarchy. Have a look at mem_cgroup_calculate_protection
> 
> I always keep that in mind, and age_lruvec() is called *after*
> mem_cgroup_calculate_protection():

>   balance_pgdat()
>     memcgs_need_aging = 0
>     do {
>       lru_gen_age_node()
>         if (!memcgs_need_aging) {
>             memcgs_need_aging = 1
>             return
>         }
>         age_lruvec()
> 
>       shrink_node_memcgs()
>         mem_cgroup_calculate_protection()
>         lru_gen_shrink_lruvec()
>           if ...
>             memcgs_need_aging = 0
>     } while ...

Uff, this is really subtle. I really think you should be following the
existing pattern when the effective values are calculated right in the
same context as they are evaluated.
-- 
Michal Hocko
SUSE Labs


From chenxiang66 at hisilicon.com  Fri Jan  7 00:41:46 2022
From: chenxiang66 at hisilicon.com (chenxiang)
Date: Fri, 7 Jan 2022 16:41:46 +0800
Subject: [RFC PATCH] ACPI / amba: Skip creating amba device when associated
 cpu is not online
Message-ID: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>

From: Xiang Chen <chenxiang66 at hisilicon.com>

If not up all the cpus with command line "maxcpus=x", system will be
blocked.
We find that some amba devices such as ETM devices, are associated with
special cpus, and if the cpu is not up, the register of associated device
is not allowed to access. BIOS reports all the ETM device nodes and a
amba device is created for every ETM device, so even if one cpu is not up,
the amba device will still be created for the associated device, and also
the register of device (pid and cid) will be accessed when adding amba
device which will cause the issue.
To fix it, skip creating amba device if it is associated with a cpu which
is not online.

Signed-off-by: Xiang Chen <chenxiang66 at hisilicon.com>
---
 drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
index ab8a4e0191b1..2369198f734b 100644
--- a/drivers/acpi/acpi_amba.c
+++ b/drivers/acpi/acpi_amba.c
@@ -16,6 +16,7 @@
 #include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <acpi/processor.h>
 
 #include "internal.h"
 
@@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
 	clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
 }
 
+static int acpi_handle_to_cpuid(acpi_handle handle)
+{
+	int cpu = -1;
+	struct acpi_processor *pr;
+
+	for_each_possible_cpu(cpu) {
+		pr = per_cpu(processors, cpu);
+		if (pr && pr->handle == handle)
+			break;
+	}
+
+	return cpu;
+}
+
+static int acpi_dev_get_cpu(struct acpi_device *adev)
+{
+	acpi_handle cpu_handle;
+	acpi_status status;
+	int cpu;
+
+	status = acpi_get_parent(adev->handle, &cpu_handle);
+	if (ACPI_FAILURE(status))
+		return -1;
+	cpu = acpi_handle_to_cpuid(cpu_handle);
+	if (cpu >= nr_cpu_ids)
+		return -1;
+	return cpu;
+}
+
 static int amba_handler_attach(struct acpi_device *adev,
 				const struct acpi_device_id *id)
 {
@@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device *adev,
 	bool address_found = false;
 	int irq_no = 0;
 	int ret;
+	int cpu;
 
 	/* If the ACPI node already has a physical device attached, skip it. */
 	if (adev->physical_node_count)
 		return 0;
 
+	/* If the cpu associated with the device is not online, skip it. */
+	cpu = acpi_dev_get_cpu(adev);
+	if (cpu >= 0 && !cpu_online(cpu))
+		return 0;
+
 	dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
 	if (!dev) {
 		dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
-- 
2.33.0



From heying24 at huawei.com  Fri Jan  7 00:55:36 2022
From: heying24 at huawei.com (He Ying)
Date: Fri, 7 Jan 2022 03:55:36 -0500
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
Message-ID: <20220107085536.214501-1-heying24@huawei.com>

Our product has been updating its kernel from 4.4 to 5.10 recently and
found a performance issue. We do a bussiness test called ARP test, which
tests the latency for a ping-pong packets traffic with a certain payload.
The result is as following.

 - 4.4 kernel: avg = ~20s
 - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s

I have been just learning arm64 pseudo-NMI code and have a question,
why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
I wonder if this brings some performance regression.

First, I make this patch and then do the test again. Here's the result.

 - 5.10 kernel with this patch not applied: avg = ~40s
 - 5.10 kernel with this patch applied: avg = ~23s

Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
set. It seems the pseudo-NMI feature actually brings some overhead to
performance event if CONFIG_ARM64_PSEUDO_NMI is not set.

Furthermore, I find the feature also brings some overhead to vmlinux size.
I build 5.10 kernel with this patch applied or not while
CONFIG_ARM64_PSEUDO_NMI is not set.

 - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
 - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.

That means arm64 pseudo-NMI feature may bring ~200KB overhead to
vmlinux size.

Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
and performance even if config is not set. To avoid it, add macro control
all around the related code.

Signed-off-by: He Ying <heying24 at huawei.com>
---
 arch/arm64/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++--
 arch/arm64/kernel/entry.S         |  4 ++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
index b57b9b1e4344..82f771b41cf5 100644
--- a/arch/arm64/include/asm/irqflags.h
+++ b/arch/arm64/include/asm/irqflags.h
@@ -26,6 +26,7 @@
  */
 static inline void arch_local_irq_enable(void)
 {
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	if (system_has_prio_mask_debugging()) {
 		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
 
@@ -41,10 +42,18 @@ static inline void arch_local_irq_enable(void)
 		: "memory");
 
 	pmr_sync();
+#else
+	asm volatile(
+		"msr	daifclr, #3		// arch_local_irq_enable"
+		:
+		:
+		: "memory");
+#endif
 }
 
 static inline void arch_local_irq_disable(void)
 {
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	if (system_has_prio_mask_debugging()) {
 		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
 
@@ -58,6 +67,13 @@ static inline void arch_local_irq_disable(void)
 		:
 		: "r" ((unsigned long) GIC_PRIO_IRQOFF)
 		: "memory");
+#else
+	asm volatile(
+		"msr	daifset, #3		// arch_local_irq_disable"
+		:
+		:
+		: "memory");
+#endif
 }
 
 /*
@@ -66,7 +82,7 @@ static inline void arch_local_irq_disable(void)
 static inline unsigned long arch_local_save_flags(void)
 {
 	unsigned long flags;
-
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	asm volatile(ALTERNATIVE(
 		"mrs	%0, daif",
 		__mrs_s("%0", SYS_ICC_PMR_EL1),
@@ -74,12 +90,19 @@ static inline unsigned long arch_local_save_flags(void)
 		: "=&r" (flags)
 		:
 		: "memory");
-
+#else
+	asm volatile(
+		"mrs	%0, daif"
+		: "=r" (flags)
+		:
+		: "memory");
+#endif
 	return flags;
 }
 
 static inline int arch_irqs_disabled_flags(unsigned long flags)
 {
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	int res;
 
 	asm volatile(ALTERNATIVE(
@@ -91,6 +114,9 @@ static inline int arch_irqs_disabled_flags(unsigned long flags)
 		: "memory");
 
 	return res;
+#else
+	return flags & PSR_I_BIT;
+#endif
 }
 
 static inline int arch_irqs_disabled(void)
@@ -119,6 +145,7 @@ static inline unsigned long arch_local_irq_save(void)
  */
 static inline void arch_local_irq_restore(unsigned long flags)
 {
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	asm volatile(ALTERNATIVE(
 		"msr	daif, %0",
 		__msr_s(SYS_ICC_PMR_EL1, "%0"),
@@ -128,6 +155,13 @@ static inline void arch_local_irq_restore(unsigned long flags)
 		: "memory");
 
 	pmr_sync();
+#else
+	asm volatile(
+		"msr	daif, %0"
+		:
+		: "r" (flags)
+		: "memory");
+#endif
 }
 
 #endif /* __ASM_IRQFLAGS_H */
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 2f69ae43941d..ffc32d3d909a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -300,6 +300,7 @@ alternative_else_nop_endif
 	str	w21, [sp, #S_SYSCALLNO]
 	.endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	/* Save pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	mrs_s	x20, SYS_ICC_PMR_EL1
@@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
 	msr_s	SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
+#endif
 
 	/* Re-enable tag checking (TCO set on exception entry) */
 #ifdef CONFIG_ARM64_MTE
@@ -330,6 +332,7 @@ alternative_else_nop_endif
 	disable_daif
 	.endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	/* Restore pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	ldr	x20, [sp, #S_PMR_SAVE]
@@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	dsb	sy				// Ensure priority change is seen by redistributor
 .L__skip_pmr_sync\@:
 alternative_else_nop_endif
+#endif
 
 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
 
-- 
2.17.1



From mhocko at suse.com  Fri Jan  7 00:55:08 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 09:55:08 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yddh+APQGg8dKRgw@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
Message-ID: <Ydf/7DDu94fMs0CG@dhcp22.suse.cz>

On Thu 06-01-22 14:41:12, Yu Zhao wrote:
> On Thu, Jan 06, 2022 at 05:12:16PM +0100, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > > +{
> > > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> > > +
> > > +	return current->reclaim_state->mm_walk;
> > > +}
> > > +
> > > +static void free_mm_walk(struct lru_gen_mm_walk *walk)
> > > +{
> > > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > > +		kvfree(walk);
> > > +}
> > 
> > Do I get it right that you are allocating from the reclaim context? What
> > prevents this to completely deplete the memory as the reclaim context is
> > PF_MEMALLOC?
> 
> Yes, and in general the same reason zram/zswap/etc. allocate memory in
> the reclaim context: to make more free memory.

I have to admit that I am not really familiar with zram/zswap but I find
the concept of requiring memory to do the reclaim really problematic.
 
> In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
> reclaimer; and direct reclaimers rarely come here, i.e., only when
> kswapd can't keep up in terms of the aging, which is similar to the
> condition where the inactive list is empty for the active/inactive
> lru.

Well, this is not a strong argument to be honest. Kswapd being stuck
and the majority of the reclaim being done in the direct reclaim
context is a situation I have seen many many times. We used to have
problems with direct reclaimers throttling to prevent an over eager OOM
situations.

Have you considered using a pool of preallocated objects instead?
-- 
Michal Hocko
SUSE Labs


From tianjia.zhang at linux.alibaba.com  Fri Jan  7 00:57:39 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri, 7 Jan 2022 16:57:39 +0800
Subject: [PATCH v3 2/6] crypto: arm64/sm3-ce - make dependent on sm3
 library
In-Reply-To: <YdezdZQHZT2+iYV3@gondor.apana.org.au>
References: <20211223043547.32297-1-tianjia.zhang@linux.alibaba.com>
 <20211223043547.32297-3-tianjia.zhang@linux.alibaba.com>
 <YdezdZQHZT2+iYV3@gondor.apana.org.au>
Message-ID: <c3ddb561-15b0-855f-b50c-c97ebd0f5976@linux.alibaba.com>

Hi Herbert,

On 1/7/22 11:28 AM, Herbert Xu wrote:
> On Thu, Dec 23, 2021 at 12:35:43PM +0800, Tianjia Zhang wrote:
>> SM3 generic library is stand-alone implementation, sm3-ce can depend
>> on the SM3 library instead of sm3-generic.
>>
>> Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
>> ---
>>   arch/arm64/crypto/Kconfig       |  2 +-
>>   arch/arm64/crypto/sm3-ce-glue.c | 20 ++++++++++++++------
>>   2 files changed, 15 insertions(+), 7 deletions(-)
> 
> This doesn't compile cleanly with C=1 W=1:
> 
>    CC [M]  arch/arm64/crypto/sm3-ce-glue.o
>    AS [M]  arch/arm64/crypto/sm3-ce-core.o
>    CC [M]  arch/arm64/crypto/sm4-ce-glue.o
>    CHECK   ../arch/arm64/crypto/sha3-ce-glue.c
> ../arch/arm64/crypto/sm3-ce-glue.c: In function ?sm3_ce_update?:
> ../arch/arm64/crypto/sm3-ce-glue.c:30:10: error: void value not ignored as it ought to be
>     30 |   return sm3_update(shash_desc_ctx(desc), data, len);
>        |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ../arch/arm64/crypto/sm3-ce-glue.c: In function ?sm3_ce_final?:
> ../arch/arm64/crypto/sm3-ce-glue.c:42:10: error: void value not ignored as it ought to be
>     42 |   return sm3_final(shash_desc_ctx(desc), out);
>        |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> make[3]: *** [../scripts/Makefile.build:287: arch/arm64/crypto/sm3-ce-glue.o] Error 1
> make[3]: *** Waiting for unfinished jobs....
> 
> Please make sure everything builds cleanly with C=1 W=1 *before*
> you submit.
> 
> Thanks,

Thanks for pointing it out, will fix it in next patch. There will never 
be such a low-level error in the future

Kind Regards,
Tianjia


From mhocko at suse.com  Fri Jan  7 01:00:31 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 10:00:31 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydf/7DDu94fMs0CG@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz>
Message-ID: <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>

On Fri 07-01-22 09:55:09, Michal Hocko wrote:
[...]
> > In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
> > reclaimer; and direct reclaimers rarely come here, i.e., only when
> > kswapd can't keep up in terms of the aging, which is similar to the
> > condition where the inactive list is empty for the active/inactive
> > lru.
> 
> Well, this is not a strong argument to be honest. Kswapd being stuck
> and the majority of the reclaim being done in the direct reclaim
> context is a situation I have seen many many times.

Also do not forget that memcg reclaim is effectivelly only direct
reclaim. Not that the memcg reclaim indicates a global memory shortage
but it can add up and race with the global reclaim as well.

-- 
Michal Hocko
SUSE Labs


From mhocko at suse.com  Fri Jan  7 01:06:15 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 10:06:15 +0100
Subject: [PATCH v6 5/9] mm: multigenerational lru: mm_struct list
In-Reply-To: <20220104202227.2903605-6-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-6-yuzhao@google.com>
Message-ID: <YdgChw4vNb43XsU/@dhcp22.suse.cz>

On Tue 04-01-22 13:22:24, Yu Zhao wrote:
> To exploit spatial locality, the aging prefers to walk page tables to
> search for young PTEs. And this patch paves the way for that.
> 
> An mm_struct list is maintained for each memcg, and an mm_struct
> follows its owner task to the new memcg when this task is migrated.

How does this work actually for the memcg reclaim? I can see you
lru_gen_migrate_mm on the task migration. My concern is, though, that
such a task leaves all the memory behind in the previous memcg (in
cgroup v2, in v1 you can opt in for charge migration). If you move the
mm to a new memcg then you age it somewhere where the memory is not
really consumed.
-- 
Michal Hocko
SUSE Labs


From Jianyong.Wu at arm.com  Fri Jan  7 01:10:57 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Fri, 7 Jan 2022 09:10:57 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <YdcRLohx777jzWah@arm.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
Message-ID: <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi Catalin,

I roughly find the root cause.
 alloc_init_pud will be called at the very beginning of kernel boot in create_mapping_noalloc where no memory allocator is initialized. But lockdep check may need allocate memory. So, kernel take exception when acquire lock.(I have not found the exact code that cause this issue) that's say we may not be able to use a lock so early.

I come up with 2 methods to address it. 
1) skip dead lock check at the very beginning of kernel boot in lockdep code.
2) provided 2 two versions of __create_pgd_mapping, one with lock in it and the other without. There may be no possible of race for memory mapping at the very beginning time of kernel boot, thus we can use the no lock version of __create_pgd_mapping safely.
In my test, this issue is gone if there is no lock held in create_mapping_noalloc. I think create_mapping_noalloc is called early enough to avoid the race conditions of memory mapping, however, I have not proved it.

For now, I prefer 2).
The rough change for method 2:
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index acfae9b41cc8..3d3c910f446b 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -63,6 +63,7 @@ static pmd_t bm_pmd[PTRS_PER_PMD] __page_aligned_bss __maybe_unused;
 static pud_t bm_pud[PTRS_PER_PUD] __page_aligned_bss __maybe_unused;

 static DEFINE_SPINLOCK(swapper_pgdir_lock);
+static DEFINE_MUTEX(fixmap_lock);

 void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
 {
@@ -381,6 +382,41 @@ static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys,
        addr = virt & PAGE_MASK;
        end = PAGE_ALIGN(virt + size);

+       do {
+               next = pgd_addr_end(addr, end);
+               /*
+                * fixmap is used inside of alloc_init_pud, but we only have
+                * one fixmap entry per page-table level, so take the fixmap
+                * lock until we're done.
+                */
+               mutex_lock(&fixmap_lock);
+               alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
+                              flags);
+               mutex_unlock(&fixmap_lock);
+               phys += next - addr;
+       } while (pgdp++, addr = next, addr != end);
+}
+
+static void __create_pgd_mapping_nolock(pgd_t *pgdir, phys_addr_t phys,
+                                unsigned long virt, phys_addr_t size,
+                                pgprot_t prot,
+                                phys_addr_t (*pgtable_alloc)(int),
+                                int flags)
+{
+       unsigned long addr, end, next;
+       pgd_t *pgdp = pgd_offset_pgd(pgdir, virt);
+
+       /*
+        * If the virtual and physical address don't have the same offset
+        * within a page, we cannot map the region as the caller expects.
+        */
+       if (WARN_ON((phys ^ virt) & ~PAGE_MASK))
+               return;
+
+       phys &= PAGE_MASK;
+       addr = virt & PAGE_MASK;
+       end = PAGE_ALIGN(virt + size);
+
        do {
                next = pgd_addr_end(addr, end);
                alloc_init_pud(pgdp, addr, next, phys, prot, pgtable_alloc,
@@ -432,7 +468,10 @@ static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
                        &phys, virt);
                return;
        }
-       __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL,
+       /*
+        * We have no need to hold a lock at this very beginning.
+        */
+       __create_pgd_mapping_nolock(init_mm.pgd, phys, virt, size, prot, NULL,
                             NO_CONT_MAPPINGS);
 }

WDYT?

Thanks
Jianyong

> -----Original Message-----
> From: Catalin Marinas <catalin.marinas at arm.com>
> Sent: Thursday, January 6, 2022 11:57 PM
> To: Jianyong Wu <Jianyong.Wu at arm.com>
> Cc: will at kernel.org; Anshuman Khandual <Anshuman.Khandual at arm.com>;
> akpm at linux-foundation.org; david at redhat.com; quic_qiancai at quicinc.com;
> ardb at kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; Justin He
> <Justin.He at arm.com>; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Thu, Jan 06, 2022 at 10:13:06AM +0000, Jianyong Wu wrote:
> > I test this patch in your way using both EDK2 V2.6 and EDK2 v2.7. it's
> > peculiar that this issue shows up on v2.6 but not on v2.7.
> > For now, I only find that if "CONFIG_DEBUG_LOCK_ALLOC" is enabled, the
> > kernel boot will hang. However, I can't debug it by printk as this
> > issue happens before pl11 is ready.
> 
> I tried earlycon but that doesn't help either.
> 
> > I will go on debugging, but very appreciated if someone can give some
> > hints on it.
> 
> FWIW, passing "nokaslr" on the kernel command line makes it boot (and this
> makes debugging harder). That's as far as I've gone.
> 
> --
> Catalin


From geert at linux-m68k.org  Fri Jan  7 01:14:45 2022
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 7 Jan 2022 10:14:45 +0100
Subject: [RFT PATCH] ARM: suspend: switch to swapper_pg_dir before using
 the vmap'ed stack
In-Reply-To: <20220106192645.3913934-1-ardb@kernel.org>
References: <20220106192645.3913934-1-ardb@kernel.org>
Message-ID: <CAMuHMdXLSFHiQPQeb5Z1yhi0L_2Pz7x4K_GtEVJTmLSkM8o4Vw@mail.gmail.com>

Hi Ard,

On Thu, Jan 6, 2022 at 8:27 PM Ard Biesheuvel <ardb at kernel.org> wrote:
> The resume from suspend code switches to the ID map so it can enable the
> MMU. On !LPAE configurations, the ID map carries its own copy of the
> kernel VA range, but this is not kept in sync with swapper_pg_dir, and
> so it may lack the mapping of the kernel mode stack if CONFIG_VMAP_STACK
> is enabled.
>
> So let's switch to swapper_pg_dir right after re-enabling the MMU on
> such configurations. This avoids a crash on resume observed on various
> platforms [0].
>
> [0] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-8-ardb at kernel.org/
>
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Jon Hunter <jonathanh at nvidia.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Thanks for your patch!

This fixes s2ram on r8a7791/koelsch (dual Cortex-A15) with
shmobile_defconfig.
S2ram on sh73a0/kzm9g (dual Cortex-A9) works as before.

Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>

> ---
> Please test with the Kconfig patch [9177/1] reverted.
>
>  arch/arm/kernel/sleep.S | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index b062b3738bc6..6217ef90feb0 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
>  ENDPROC(cpu_resume_mmu)
>         .popsection
>  cpu_resume_after_mmu:
> +#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
> +       @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
> +       @ as the ID map does not cover the vmalloc region.
> +       mrc     p15, 0, ip, c2, c0, 1   @ read TTBR1
> +       mcr     p15, 0, ip, c2, c0, 0   @ set TTBR0
> +       isb
> +#endif
>         bl      cpu_init                @ restore the und/abt/irq banked regs
>         mov     r0, #0                  @ return zero on success
>         ldmfd   sp!, {r4 - r11, pc}

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From angelogioacchino.delregno at collabora.com  Fri Jan  7 01:23:32 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 10:23:32 +0100
Subject: [PATCH 3/3] phy: mediatek: phy-mtk-mipi-dsi: Simplify with
 dev_err_probe()
In-Reply-To: <4d7195c3ac9bc63a5f980548f0c880484403346d.camel@mediatek.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
 <20220103145324.48008-3-angelogioacchino.delregno@collabora.com>
 <4d7195c3ac9bc63a5f980548f0c880484403346d.camel@mediatek.com>
Message-ID: <ba6c0163-fc5f-2a5f-560d-240e5fe2c3c4@collabora.com>

Il 06/01/22 10:13, Chunfeng Yun ha scritto:
> On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno wrote:
>> Use the dev_err_probe() helper to simplify error handling during
>> probe.
>>
>> Signed-off-by: AngeloGioacchino Del Regno <
>> angelogioacchino.delregno at collabora.com>
>> ---
>>   drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 29 +++++++++------------
>> ----
>>   1 file changed, 10 insertions(+), 19 deletions(-)
>>
>> diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
>> b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
>> index 6f7425b0bf5b..4b77508f5241 100644
>> --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
>> +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
>> @@ -148,11 +148,9 @@ static int mtk_mipi_tx_probe(struct
>> platform_device *pdev)
>>   		return PTR_ERR(mipi_tx->regmap);
>>   
>>   	ref_clk = devm_clk_get(dev, NULL);
>> -	if (IS_ERR(ref_clk)) {
>> -		ret = PTR_ERR(ref_clk);
>> -		dev_err(dev, "Failed to get reference clock: %d\n",
>> ret);
>> -		return ret;
>> -	}
>> +	if (IS_ERR(ref_clk))
>> +		return dev_err_probe(dev, PTR_ERR(ref_clk),
>> +				     "Failed to get reference
>> clock\n");
>>   
>>   	ret = of_property_read_u32(dev->of_node, "drive-strength-
>> microamp",
>>   				   &mipi_tx->mipitx_drive);
>> @@ -172,27 +170,20 @@ static int mtk_mipi_tx_probe(struct
>> platform_device *pdev)
>>   
>>   	ret = of_property_read_string(dev->of_node, "clock-output-
>> names",
>>   				      &clk_init.name);
>> -	if (ret < 0) {
>> -		dev_err(dev, "Failed to read clock-output-names: %d\n",
>> ret);
>> -		return ret;
>> -	}
>> +	if (ret < 0)
>> +		return dev_err_probe(dev, ret, "Failed to read clock-
>> output-names\n");
> Seems no need change it here. (no EPROBE_DEFER error)
> 

Hello Chunfeng,

pasting from kernel driver-api infrastructure guidelines:

[...]Note that it is deemed acceptable to use this function for error prints during 
probe even if the err is known to never be -EPROBE_DEFER. The benefit compared to a 
normal dev_err() is the standardized format of the error code and the fact that the 
error code is returned.

https://www.kernel.org/doc/html/latest/driver-api/infrastructure.html

Regards,
- Angelo

> Thanks
>>   
>>   	clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops;
>>   
>>   	mipi_tx->pll_hw.init = &clk_init;
>>   	mipi_tx->pll = devm_clk_register(dev, &mipi_tx->pll_hw);
>> -	if (IS_ERR(mipi_tx->pll)) {
>> -		ret = PTR_ERR(mipi_tx->pll);
>> -		dev_err(dev, "Failed to register PLL: %d\n", ret);
>> -		return ret;
>> -	}
>> +	if (IS_ERR(mipi_tx->pll))
>> +		return dev_err_probe(dev, PTR_ERR(mipi_tx->pll),
>> "Cannot register PLL\n");
>>   
>>   	phy = devm_phy_create(dev, NULL, &mtk_mipi_tx_ops);
>> -	if (IS_ERR(phy)) {
>> -		ret = PTR_ERR(phy);
>> -		dev_err(dev, "Failed to create MIPI D-PHY: %d\n", ret);
>> -		return ret;
>> -	}
>> +	if (IS_ERR(phy))
>> +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to
>> create MIPI D-PHY\n");
>> +
>>   	phy_set_drvdata(phy, mipi_tx);
>>   
>>   	phy_provider = devm_of_phy_provider_register(dev,
>> of_phy_simple_xlate);
> 



From brgl at bgdev.pl  Fri Jan  7 01:31:30 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Fri, 7 Jan 2022 10:31:30 +0100
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <20220107031905.2406176-1-robh@kernel.org>
References: <20220107031905.2406176-1-robh@kernel.org>
Message-ID: <CAMRc=MdmOMfyyiguowrU52BvoxMr8u3sLQfzCiY_Rqs=qUsX-Q@mail.gmail.com>

On Fri, Jan 7, 2022 at 4:19 AM Rob Herring <robh at kernel.org> wrote:
>
> 'interrupt-parent' is never required as it can be in a parent node or a
> parent node itself can be an interrupt provider. Where exactly it lives is
> outside the scope of a binding schema.
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
>  7 files changed, 15 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> index 9ad470e01953..b085450b527f 100644
> --- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> +++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> @@ -43,7 +43,6 @@ required:
>    - gpio-controller
>    - interrupt-controller
>    - "#interrupt-cells"
> -  - interrupt-parent
>
>  additionalProperties: false
>
> diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> index e864d798168d..d433e496ec6e 100644
> --- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> +++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> @@ -175,15 +175,6 @@ required:
>    - ti,mbox-num-fifos
>
>  allOf:
> -  - if:
> -      properties:
> -        compatible:
> -          enum:
> -            - ti,am654-mailbox
> -    then:
> -      required:
> -        - interrupt-parent
> -
>    - if:
>        properties:
>          compatible:
> diff --git a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> index 499c62c04daa..5dce62a7eff2 100644
> --- a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> +++ b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> @@ -221,7 +221,6 @@ required:
>    - '#gpio-cells'
>    - interrupt-controller
>    - '#interrupt-cells'
> -  - interrupt-parent
>    - interrupts
>    - AVDD-supply
>    - DBVDD1-supply
> diff --git a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> index 437502c5ca96..3ce9f9a16baf 100644
> --- a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> +++ b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> @@ -46,7 +46,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - interrupt-parent
>    - interrupts
>    - interrupt-names
>    - lantiq,tx-burst-length
> diff --git a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> index 7bc074a42369..5bc1a21ca579 100644
> --- a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> +++ b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> @@ -38,7 +38,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - interrupt-parent
>    - interrupts
>    - interrupt-names
>    - "#address-cells"
> diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> index 2b9d1d6fc661..72c78f4ec269 100644
> --- a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> @@ -61,7 +61,6 @@ required:
>    - num-lanes
>    - interrupts
>    - interrupt-names
> -  - interrupt-parent
>    - interrupt-map-mask
>    - interrupt-map
>    - clock-names
> diff --git a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> index a2bbc0eb7220..32f4641085bc 100644
> --- a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> +++ b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> @@ -55,7 +55,6 @@ required:
>    - reg-names
>    - "#interrupt-cells"
>    - interrupts
> -  - interrupt-parent
>    - interrupt-map
>    - interrupt-map-mask
>    - bus-range
> --
> 2.32.0
>

For GPIO:

Acked-by: Bartosz Golaszewski <brgl at bgdev.pl>


From mhocko at suse.com  Fri Jan  7 01:38:18 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 10:38:18 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdSuSHa/Vjl6bPkg@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
Message-ID: <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>

On Tue 04-01-22 13:30:00, Yu Zhao wrote:
[...]
> Hi Andrew, Linus,
> 
> Can you please take a look at this patchset and let me know if it's
> 5.17 material?

I am still not done with the review and have seen at least few problems
that would need to be addressed.

But more fundamentally I believe there are really some important
questions to be answered. First and foremost this is a major addition
to the memory reclaim and there should be a wider consensus that we
really want to go that way. The patchset doesn't have a single ack nor
reviewed-by AFAICS. I haven't seen a lot of discussion since v2
(http://lkml.kernel.org/r/20210413065633.2782273-1-yuzhao at google.com)
nor do I see any clarification on how concerns raised there have been
addressed or at least how they are planned to be addressed.

Johannes has made some excellent points
http://lkml.kernel.org/r/YHcpzZYD2fQyWvEQ at cmpxchg.org. Let me quote
for reference part of it I find the most important:
: Realistically, I think incremental changes are unavoidable to get this
: merged upstream.
: 
: Not just in the sense that they need to be smaller changes, but also
: in the sense that they need to replace old code. It would be
: impossible to maintain both, focus development and testing resources,
: and provide a reasonably stable experience with both systems tugging
: at a complicated shared code base.
: 
: On the other hand, the existing code also has billions of hours of
: production testing and tuning. We can't throw this all out overnight -
: it needs to be surgical and the broader consequences of each step need
: to be well understood.
: 
: We also have millions of servers relying on being able to do upgrades
: for drivers and fixes in other subsystems that we can't put on hold
: until we stabilized a new reclaim implementation from scratch.

Fully agreed on all points here.

I do appreciate there is a lot of work behind this patchset and I
also do understand it has gained a considerable amount of testing as
well. Your numbers are impressive but my experience tells me that it is
equally important to understand the worst case behavior and there is not
really much mentioned about those in changelogs.

We also shouldn't ignore costs the code is adding. One of them would be
a further page flags depletion. We have been hitting problems on that
front for years and many features had to be reworked to bypass a lack of
space in page->flags.

I will be looking more into the code (especially the memcg side of it)
but I really believe that a consensus on above Johannes' points need to
be found first before this work can move forward.

Thanks!
-- 
Michal Hocko
SUSE Labs


From r.czerwinski at pengutronix.de  Fri Jan  7 01:46:10 2022
From: r.czerwinski at pengutronix.de (Rouven Czerwinski)
Date: Fri, 07 Jan 2022 10:46:10 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
Message-ID: <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>

On Thu, 2022-01-06 at 14:08 +0000, ZHIZHIKIN Andrey wrote:
> Hello Rouven,
> 
> > -----Original Message-----
> > From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> > Sent: Thursday, January 6, 2022 12:27 PM
> > To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> > kernel at vger.kernel.org
> > Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> > frieder.schrempf at kontron.de; leonard.crestez at nxp.com; festevam at gmail.com;
> > marex at denx.de; herbert at gondor.apana.org.au; horia.geanta at nxp.com;
> > aford173 at gmail.com; krzk at kernel.org; linux-imx at nxp.com;
> > devicetree at vger.kernel.org; hongxing.zhu at nxp.com; s.hauer at pengutronix.de;
> > pankaj.gupta at nxp.com; robh+dt at kernel.org; thunder.leizhen at huawei.com;
> > martink at posteo.de; daniel.baluta at nxp.com; linux-arm-kernel at lists.infradead.org;
> > gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> > michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-crypto at vger.kernel.org;
> > kernel at pengutronix.de; jun.li at nxp.com; shawnguo at kernel.org; davem at davemloft.net;
> > l.stach at pengutronix.de
> > Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
> > 
> > Hi Andrey,
> > 
> > On Wed, 2021-12-08 at 00:02 +0100, Andrey Zhizhikin wrote:
> > > CAAM JR nodes are configured by BootROM and are used by various software
> > > entities during the boot process before they reach the Kernel.
> > > 
> > > Default BootROM configuration have JR0 and JR1 reserved for S-only
> > > access, while JR2 is generally available for both S and NS access. HAB
> > > feature of i.MX8M family does require that JR0 is reserved exclusively
> > > in S-only world, while JR1 and JR2 are both released to NS-World. OP-TEE
> > > can later reclaim the JR2 via dt_enable_secure_status() call, and modify
> > > the DID to hold it in S-World only.
> > > 
> > > The above setup has been discovered during review of CAAM patchset
> > > presented to U-Boot integration [1], and does not correspond to the
> > > status on jr nodes in FDT.
> > > 
> > > This missing status settings leads to the following error message during
> > > jr node probing:
> > > [    1.509894] caam 30900000.crypto: job rings = 3, qi = 0
> > > [    1.525201] caam_jr 30901000.jr: failed to flush job ring 0
> > > [    1.525214] caam_jr: probe of 30901000.jr failed with error -5
> > > 
> > > JR register readout after BootROM execution shows the following values:
> > > JR0DID_MS = 0x8011
> > > JR1DID_MS = 0x8011
> > > JR2DID_MS = 0x0
> > > 
> > > This shows that JR0 and JR1 have TZ_OWN bit set, which marks them to be
> > > reserved for S-World, while JR2 remains accessible from NS-World.
> > > 
> > > Provide the correct status for JR nodes in imx8m derivatives, which have
> > > a following meaning:
> > > - JR0: S-only
> > > - JR1: visible in both
> > > - JR2: NS-only
> > > 
> > > Note, that JR2 is initially marked to be NS-only which does correspond
> > > to DID readout when OP-TEE is not present. Once present, OP-TEE will
> > > reclaim the JR2 and set both "status" and "secure-status" to claim JR2
> > > for S-only access.
> > 
> > While I can understand that you want to fix your use case for when HAB
> > is enabled, note that this is disabling JR0 in the none-HAB case as
> > well.
> 
> This is not totally correct, as this patch does address the reservation of
> JR0 by BootROM in both HAB and non-HAB configurations. My current setup does
> not include HAB functionality enabled, and I still do observe boot errors
> that are listed in commit message. This is due to the fact that the BootROM
> does not release JR0 to NS-World regardless of whether HAB is enabled or not.
> This has been discussed in the U-Boot thread I provided the link in the patch.
> 
> This patch does rather bring the correct HW module description as seeing
> from Linux. 

I took a look into i.MX8MQ, the bootrom indeed sets 0x8011 for JR0 &
JR1:
JR0:0000000000008011
JR1:0000000000008011
JR2:0000000000000000
TF-A
>CAAM
JR0:0000000000000001
JR1:0000000000000001
JR2:0000000000000001

However at least the upstream TF-A reconfigures the DIDs to 1 for all
i.MX8M* derivates.  So while it is technically correct to change the DT
values as you describe, the downstream TF-A and upstream TF-A seem to
differ in their configuration. I also think it's a bad move to hardcode
the JR configuration to the boot ROM config, since AFAIK i.MX8M* can
not be run without TF-A. And IMO the upstream kernel should follow what
the upstream TF-A does in this case.

> 
> > IMO this should be handled correctly by the bootloader and/or OP-
> > TEE. The default upstream configuration for OP-TEE is to not use the
> > CAAM at runtime as well, since linux runtime PM disablement of the CAAM
> > will lock up OP-TEE when it tries to access the CAAM.
> 
> If by handling you mean releasing JR0 reservation - then yes, it should be
> done by either SPL or TF-A as they do run in S World. In such a case, DTB
> bindings need to be adapted further according to the new state. Until this
> done - this patch does provide a correct state of HW to the Kernel.

Upstream TF-A simply releases all JRs to the normal world, matching the
current DTB description.

Kind Regards,
Rouven Czerwinski


> > 
> > Kind regards,
> > Rouven Czerwinski
> > 
> > > 
> > > Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin at leica-geosystems.com>
> > > Link: [1]: https://lore.kernel.org/u-boot/AM6PR06MB4691FC905FE5658BE4B15C11A6609 at AM6PR06MB4691.eurprd06.prod.outlook.com/
> > > ---
> > > Changes in V3:
> > > - No change, new patch introduced
> > > 
> > >  arch/arm64/boot/dts/freescale/imx8mm.dtsi | 4 ++++
> > >  arch/arm64/boot/dts/freescale/imx8mn.dtsi | 4 ++++
> > >  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 4 ++++
> > >  arch/arm64/boot/dts/freescale/imx8mq.dtsi | 4 ++++
> > >  4 files changed, 16 insertions(+)
> > > 
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > > index 5b9c2cca9ac4..51465974c4ea 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> > > @@ -914,18 +914,22 @@ sec_jr0: jr at 1000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x1000 0x1000>;
> > >                                       interrupts = <GIC_SPI 105
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     status = "disabled";
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr1: jr at 2000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x2000 0x1000>;
> > >                                       interrupts = <GIC_SPI 106
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr2: jr at 3000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x3000 0x1000>;
> > >                                       interrupts = <GIC_SPI 114
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "disabled";
> > >                               };
> > >                       };
> > > 
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > > index ba23b416b5e6..e5edf14319b1 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
> > > @@ -808,18 +808,22 @@ sec_jr0: jr at 1000 {
> > >                                        compatible = "fsl,sec-v4.0-job-ring";
> > >                                        reg = <0x1000 0x1000>;
> > >                                        interrupts = <GIC_SPI 105
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                      status = "disabled";
> > > +                                      secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr1: jr at 2000 {
> > >                                        compatible = "fsl,sec-v4.0-job-ring";
> > >                                        reg = <0x2000 0x1000>;
> > >                                        interrupts = <GIC_SPI 106
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                      secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr2: jr at 3000 {
> > >                                        compatible = "fsl,sec-v4.0-job-ring";
> > >                                        reg = <0x3000 0x1000>;
> > >                                        interrupts = <GIC_SPI 114
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                      secure-status = "disabled";
> > >                               };
> > >                       };
> > > 
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > index 977783784342..3c23bf5c3910 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> > > @@ -661,18 +661,22 @@ sec_jr0: jr at 1000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x1000 0x1000>;
> > >                                       interrupts = <GIC_SPI 105
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     status = "disabled";
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr1: jr at 2000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x2000 0x1000>;
> > >                                       interrupts = <GIC_SPI 106
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr2: jr at 3000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x3000 0x1000>;
> > >                                       interrupts = <GIC_SPI 114
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "disabled";
> > >                               };
> > >                       };
> > > 
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > > index 95d8b95d6120..16c4c9110ce7 100644
> > > --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > > @@ -999,18 +999,22 @@ sec_jr0: jr at 1000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x1000 0x1000>;
> > >                                       interrupts = <GIC_SPI 105
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     status = "disabled";
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr1: jr at 2000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x2000 0x1000>;
> > >                                       interrupts = <GIC_SPI 106
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "okay";
> > >                               };
> > > 
> > >                               sec_jr2: jr at 3000 {
> > >                                       compatible = "fsl,sec-v4.0-job-ring";
> > >                                       reg = <0x3000 0x1000>;
> > >                                       interrupts = <GIC_SPI 114
> > IRQ_TYPE_LEVEL_HIGH>;
> > > +                                     secure-status = "disabled";
> > >                               };
> > >                       };
> > > 
> > 
> > --
> > Pengutronix e.K.           | Rouven Czerwinski          |
> > Steuerwalder Str. 21       | http://www.pengutronix.de/ |
> > 31137 Hildesheim, Germany  | Phone: +49-5121-206917-0   |
> 
> 
> -- andrey

-- 
Pengutronix e.K.           | Rouven Czerwinski          |
Steuerwalder Str. 21       | http://www.pengutronix.de/ |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0   |



From roger.lu at mediatek.com  Fri Jan  7 01:51:59 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:59 +0800
Subject: [PATCH v21 7/8] arm64: dts: mt8192: add svs device information
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-8-roger.lu@mediatek.com>

Add compitable/reg/irq/clock/efuse/reset setting in svs node.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 39 ++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..c111e26489dd 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -9,6 +9,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
+#include <dt-bindings/reset/ti-syscon.h>
+
 
 / {
 	compatible = "mediatek,mt8192";
@@ -268,6 +270,14 @@
 			compatible = "mediatek,mt8192-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
+
+			infracfg_rst: reset-controller {
+				compatible = "mediatek,infra-reset", "ti,syscon-reset";
+				#reset-cells = <1>;
+				ti,reset-bits = <
+					0x150 5 0x154 5 0 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* 0: svs */
+				>;
+			};
 		};
 
 		pericfg: syscon at 10003000 {
@@ -362,6 +372,20 @@
 			status = "disabled";
 		};
 
+		svs: svs at 1100b000 {
+			compatible = "mediatek,mt8192-svs";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg CLK_INFRA_THERM>;
+			clock-names = "main";
+			nvmem-cells = <&svs_calibration>,
+				      <&lvts_e_data1>;
+			nvmem-cell-names = "svs-calibration-data",
+					   "t-calibration-data";
+			resets = <&infracfg_rst 0>;
+			reset-names = "svs_rst";
+		};
+
 		spi1: spi at 11010000 {
 			compatible = "mediatek,mt8192-spi",
 				     "mediatek,mt6765-spi";
@@ -479,6 +503,21 @@
 			#clock-cells = <1>;
 		};
 
+		efuse: efuse at 11c10000 {
+			compatible = "mediatek,efuse";
+			reg = <0 0x11c10000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			lvts_e_data1: data1 at 1c0 {
+				reg = <0x1c0 0x58>;
+			};
+
+			svs_calibration: calib at 580 {
+				reg = <0x580 0x68>;
+			};
+		};
+
 		i2c3: i2c3 at 11cb0000 {
 			compatible = "mediatek,mt8192-i2c";
 			reg = <0 0x11cb0000 0 0x1000>,
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:54 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:54 +0800
Subject: [PATCH v21 2/8] arm64: dts: mt8183: add svs device information
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-3-roger.lu@mediatek.com>

Add compitable/reg/irq/clock/efuse setting in svs node.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index ba4584faca5a..9de6aa59d9a7 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -743,6 +743,18 @@
 			status = "disabled";
 		};
 
+		svs: svs at 1100b000 {
+			compatible = "mediatek,mt8183-svs";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&infracfg CLK_INFRA_THERM>;
+			clock-names = "main";
+			nvmem-cells = <&svs_calibration>,
+				      <&thermal_calibration>;
+			nvmem-cell-names = "svs-calibration-data",
+					   "t-calibration-data";
+		};
+
 		thermal: thermal at 1100b000 {
 			#thermal-sensor-cells = <1>;
 			compatible = "mediatek,mt8183-thermal";
@@ -1261,6 +1273,10 @@
 			mipi_tx_calibration: calib at 190 {
 				reg = <0x190 0xc>;
 			};
+
+			svs_calibration: calib at 580 {
+				reg = <0x580 0x64>;
+			};
 		};
 
 		u3phy: t-phy at 11f40000 {
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:53 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:53 +0800
Subject: [PATCH v21 1/8] dt-bindings: soc: mediatek: add mtk svs dt-bindings
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-2-roger.lu@mediatek.com>

Document the binding for enabling mtk svs on MediaTek SoC.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/soc/mediatek/mtk-svs.yaml        | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml

diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
new file mode 100644
index 000000000000..a855ced410f8
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mtk-svs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Smart Voltage Scaling (SVS) Device Tree Bindings
+
+maintainers:
+  - Roger Lu <roger.lu at mediatek.com>
+  - Matthias Brugger <matthias.bgg at gmail.com>
+  - Kevin Hilman <khilman at kernel.org>
+
+description: |+
+  The SVS engine is a piece of hardware which has several
+  controllers(banks) for calculating suitable voltage to
+  different power domains(CPU/GPU/CCI) according to
+  chip process corner, temperatures and other factors. Then DVFS
+  driver could apply SVS bank voltage to PMIC/Buck.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8183-svs
+
+  reg:
+    maxItems: 1
+    description: Address range of the MTK SVS controller.
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: Main clock for MTK SVS controller to work.
+
+  clock-names:
+    const: main
+
+  nvmem-cells:
+    minItems: 1
+    maxItems: 2
+    description:
+      Phandle to the calibration data provided by a nvmem device.
+    items:
+      - description: SVS efuse for SVS controller
+      - description: Thermal efuse for SVS controller
+
+  nvmem-cell-names:
+    items:
+      - const: svs-calibration-data
+      - const: t-calibration-data
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - nvmem-cells
+  - nvmem-cell-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        svs at 1100b000 {
+            compatible = "mediatek,mt8183-svs";
+            reg = <0 0x1100b000 0 0x1000>;
+            interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+            clocks = <&infracfg CLK_INFRA_THERM>;
+            clock-names = "main";
+            nvmem-cells = <&svs_calibration>, <&thermal_calibration>;
+            nvmem-cell-names = "svs-calibration-data", "t-calibration-data";
+        };
+    };
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:52:00 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:52:00 +0800
Subject: [PATCH v21 8/8] soc: mediatek: SVS: add mt8192 SVS GPU driver
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-9-roger.lu@mediatek.com>

mt8192 SVS GPU uses 2-line (high/low bank) HW architecture to provide
bank voltages. High bank helps update higher frequency's voltage
and low bank helps update lower frequency's voltage.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 469 ++++++++++++++++++++++++++++++++-
 1 file changed, 464 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 93cdaecadd6d..bec6524ab33a 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -24,6 +24,7 @@
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -35,6 +36,10 @@
 #define SVSB_CCI			BIT(2)
 #define SVSB_GPU			BIT(3)
 
+/* svs bank 2-line type */
+#define SVSB_LOW			BIT(8)
+#define SVSB_HIGH			BIT(9)
+
 /* svs bank mode support */
 #define SVSB_MODE_ALL_DISABLE		0
 #define SVSB_MODE_INIT01		BIT(1)
@@ -45,6 +50,8 @@
 #define SVSB_INIT01_PD_REQ		BIT(0)
 #define SVSB_INIT01_VOLT_IGNORE		BIT(1)
 #define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
+#define SVSB_MON_VOLT_IGNORE		BIT(16)
+#define SVSB_REMOVE_DVTFIXED_VOLT	BIT(24)
 
 /* svs bank common setting */
 #define MAX_OPP_ENTRIES			16
@@ -249,6 +256,7 @@ static const u32 svs_regs_v2[] = {
  * @main_clk: main clock for svs bank
  * @pbank: svs bank pointer protected by spin_lock section
  * @banks: svs banks that svs platform supports
+ * @rst: svs platform reset control
  * @efuse_parsing: svs platform efuse parsing function pointer
  * @probe: svs platform probe function pointer
  * @irqflags: svs platform irq settings flags
@@ -266,6 +274,7 @@ struct svs_platform {
 	struct clk *main_clk;
 	struct svs_bank *pbank;
 	struct svs_bank *banks;
+	struct reset_control *rst;
 	bool (*efuse_parsing)(struct svs_platform *svsp);
 	int (*probe)(struct svs_platform *svsp);
 	unsigned long irqflags;
@@ -298,6 +307,7 @@ struct svs_platform {
  * @pm_runtime_enabled_count: bank pm runtime enabled count
  * @mode_support: bank mode support.
  * @freq_base: reference frequency for bank init
+ * @turn_freq_base: refenrece frequency for turn point
  * @vboot: voltage request for bank init01 only
  * @opp_dfreq: default opp frequency table
  * @opp_dvolt: default opp voltage table
@@ -333,6 +343,8 @@ struct svs_platform {
  * @mtdes: svs efuse data
  * @dcbdet: svs efuse data
  * @dcmdet: svs efuse data
+ * @turn_pt: turn point informs which opp_volt calculated by high/low bank.
+ * @type: bank type to represent it is 2-line (high/low) bank or 1-line bank.
  *
  * Svs bank will generate suitalbe voltages by below general math equation
  * and provide these voltages to opp voltage table.
@@ -359,6 +371,7 @@ struct svs_bank {
 	u32 pm_runtime_enabled_count;
 	u32 mode_support;
 	u32 freq_base;
+	u32 turn_freq_base;
 	u32 vboot;
 	u32 opp_dfreq[MAX_OPP_ENTRIES];
 	u32 opp_dvolt[MAX_OPP_ENTRIES];
@@ -394,6 +407,8 @@ struct svs_bank {
 	u32 mtdes;
 	u32 dcbdet;
 	u32 dcmdet;
+	u32 turn_pt;
+	u32 type;
 };
 
 static u32 percent(u32 numerator, u32 denominator)
@@ -429,6 +444,37 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
 	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
 }
 
+static u32 svs_opp_volt_to_bank_volt(u32 opp_u_volt, u32 svsb_volt_step,
+				     u32 svsb_volt_base)
+{
+	return (opp_u_volt - svsb_volt_base) / svsb_volt_step;
+}
+
+static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
+{
+	struct dev_pm_opp *opp;
+	u32 i, opp_u_volt;
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
+						 svsb->opp_dfreq[i],
+						 true);
+		if (IS_ERR(opp)) {
+			dev_err(svsb->dev, "cannot find freq = %u (%ld)\n",
+				svsb->opp_dfreq[i], PTR_ERR(opp));
+			return PTR_ERR(opp);
+		}
+
+		opp_u_volt = dev_pm_opp_get_voltage(opp);
+		svsb->volt[i] = svs_opp_volt_to_bank_volt(opp_u_volt,
+							  svsb->volt_step,
+							  svsb->volt_base);
+		dev_pm_opp_put(opp);
+	}
+
+	return 0;
+}
+
 static int svs_get_zone_temperature(const char *tzone_name, int *tzone_temp)
 {
 	struct thermal_zone_device *tzd;
@@ -443,7 +489,7 @@ static int svs_get_zone_temperature(const char *tzone_name, int *tzone_temp)
 static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 {
 	int ret = -EPERM, tzone_temp = 0;
-	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
+	u32 i, svsb_volt, opp_volt, temp_voffset = 0, opp_start, opp_stop;
 
 	mutex_lock(&svsb->lock);
 
@@ -457,6 +503,21 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 		goto unlock_mutex;
 	}
 
+	/*
+	 * 2-line bank updates its corresponding opp volts.
+	 * 1-line bank updates all opp volts.
+	 */
+	if (svsb->type == SVSB_HIGH) {
+		opp_start = 0;
+		opp_stop = svsb->turn_pt;
+	} else if (svsb->type == SVSB_LOW) {
+		opp_start = svsb->turn_pt;
+		opp_stop = svsb->opp_count;
+	} else {
+		opp_start = 0;
+		opp_stop = svsb->opp_count;
+	}
+
 	/* Get thermal effect */
 	if (svsb->phase == SVSB_PHASE_MON) {
 		ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
@@ -471,10 +532,16 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 			temp_voffset += svsb->tzone_htemp_voffset;
 		else if (tzone_temp <= svsb->tzone_ltemp)
 			temp_voffset += svsb->tzone_ltemp_voffset;
+
+		/* 2-line bank update all opp volts when running mode */
+		if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+			opp_start = 0;
+			opp_stop = svsb->opp_count;
+		}
 	}
 
 	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
-	for (i = 0; i < svsb->opp_count; i++) {
+	for (i = opp_start; i < opp_stop; i++) {
 		switch (svsb->phase) {
 		case SVSB_PHASE_ERROR:
 			opp_volt = svsb->opp_dvolt[i];
@@ -639,9 +706,11 @@ static int svs_status_debug_show(struct seq_file *m, void *v)
 
 	ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
 	if (ret)
-		seq_printf(m, "%s: temperature ignore\n", svsb->name);
+		seq_printf(m, "%s: temperature ignore, turn_pt = %u\n",
+			   svsb->name, svsb->turn_pt);
 	else
-		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
+		seq_printf(m, "%s: temperature = %d, turn_pt = %u\n",
+			   svsb->name, tzone_temp, svsb->turn_pt);
 
 	for (i = 0; i < svsb->opp_count; i++) {
 		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
@@ -784,6 +853,181 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
 	return DIV_ROUND_UP(vx, 100);
 }
 
+static void svs_get_bank_volts_v3(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 i, j, *vop, vop74, vop30, mask7_0 = GENMASK(7, 0);
+	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;
+	u32 middle_index = (svsb->opp_count / 2);
+	u32 opp_start = 0, opp_stop = 0, turn_pt = svsb->turn_pt;
+
+	if (svsb->phase == SVSB_PHASE_MON &&
+	    svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
+		return;
+
+	vop74 = svs_readl_relaxed(svsp, VOP74);
+	vop30 = svs_readl_relaxed(svsp, VOP30);
+
+	/* Target is to set svsb->volt[] by algorithm */
+	if (turn_pt < middle_index) {
+		if (svsb->type == SVSB_HIGH) {
+			/* volt[0] ~ volt[turn_pt - 1] */
+			for (i = 0; i < turn_pt; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				vop = (shift_byte < reg_bytes) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
+			j = svsb->opp_count - 7;
+			svsb->volt[turn_pt] = vop30 & mask7_0;
+			shift_byte++;
+			for (i = j; i < svsb->opp_count; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				vop = (shift_byte < reg_bytes) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
+				shift_byte++;
+			}
+
+			/* volt[turn_pt + 1] ~ volt[j - 1] by interpolate */
+			for (i = turn_pt + 1; i < j; i++)
+				svsb->volt[i] =
+					interpolate(svsb->freq_pct[turn_pt],
+						    svsb->freq_pct[j],
+						    svsb->volt[turn_pt],
+						    svsb->volt[j],
+						    svsb->freq_pct[i]);
+		}
+	} else {
+		if (svsb->type == SVSB_HIGH) {
+			/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
+			j = turn_pt - 7;
+			svsb->volt[0] = vop30 & mask7_0;
+			shift_byte++;
+			for (i = j; i < turn_pt; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				vop = (shift_byte < reg_bytes) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
+				shift_byte++;
+			}
+
+			/* volt[1] ~ volt[j - 1] by interpolate */
+			for (i = 1; i < j; i++)
+				svsb->volt[i] =
+					interpolate(svsb->freq_pct[0],
+						    svsb->freq_pct[j],
+						    svsb->volt[0],
+						    svsb->volt[j],
+						    svsb->freq_pct[i]);
+		} else if (svsb->type == SVSB_LOW) {
+			/* volt[turn_pt] ~ volt[opp_count - 1] */
+			for (i = turn_pt; i < svsb->opp_count; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				vop = (shift_byte < reg_bytes) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
+				shift_byte++;
+			}
+		}
+	}
+
+	if (svsb->type == SVSB_HIGH) {
+		opp_start = 0;
+		opp_stop = svsb->turn_pt;
+	} else if (svsb->type == SVSB_LOW) {
+		opp_start = svsb->turn_pt;
+		opp_stop = svsb->opp_count;
+	}
+
+	for (i = opp_start; i < opp_stop; i++)
+		if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT)
+			svsb->volt[i] -= svsb->dvt_fixed;
+}
+
+static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0;
+	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;
+	u32 middle_index = (svsb->opp_count / 2);
+	u32 turn_pt = middle_index;
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) {
+			svsb->turn_pt = i;
+			break;
+		}
+	}
+
+	turn_pt = svsb->turn_pt;
+
+	/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
+	if (turn_pt < middle_index) {
+		if (svsb->type == SVSB_HIGH) {
+			/* Edge case for preventing freq_pct30 from being 0 */
+			if (turn_pt == 0)
+				freq_pct30 = svsb->freq_pct[0];
+
+			/* freq_pct[0] ~ freq_pct[turn_pt - 1] */
+			for (i = 0; i < turn_pt; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				freq_pct = (shift_byte < reg_bytes) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/*
+			 * freq_pct[turn_pt] +
+			 * freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
+			 */
+			freq_pct30 = svsb->freq_pct[turn_pt];
+			shift_byte++;
+			j = svsb->opp_count - 7;
+			for (i = j; i < svsb->opp_count; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				freq_pct = (shift_byte < reg_bytes) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		}
+	} else {
+		if (svsb->type == SVSB_HIGH) {
+			/*
+			 * freq_pct[0] +
+			 * freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
+			 */
+			freq_pct30 = svsb->freq_pct[0];
+			shift_byte++;
+			j = turn_pt - 7;
+			for (i = j; i < turn_pt; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				freq_pct = (shift_byte < reg_bytes) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
+			for (i = turn_pt; i < svsb->opp_count; i++) {
+				b_sft = bits8 * (shift_byte % reg_bytes);
+				freq_pct = (shift_byte < reg_bytes) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		}
+	}
+
+	svs_writel_relaxed(svsp, freq_pct74, FREQPCT74);
+	svs_writel_relaxed(svsp, freq_pct30, FREQPCT30);
+}
+
 static void svs_get_bank_volts_v2(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
@@ -1247,6 +1491,25 @@ static int svs_init02(struct svs_platform *svsp)
 		}
 	}
 
+	/*
+	 * 2-line high/low bank update its corresponding opp voltages only.
+	 * Therefore, we sync voltages from opp for high/low bank voltages
+	 * consistency.
+	 */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT02))
+			continue;
+
+		if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+			if (svs_sync_bank_volts_from_opp(svsb)) {
+				dev_err(svsb->dev, "sync volt fail\n");
+				return -EPERM;
+			}
+		}
+	}
+
 	return 0;
 }
 
@@ -1291,6 +1554,7 @@ static int svs_suspend(struct device *dev)
 	struct svs_platform *svsp = dev_get_drvdata(dev);
 	struct svs_bank *svsb;
 	unsigned long flags;
+	int ret;
 	u32 idx;
 
 	for (idx = 0; idx < svsp->bank_max; idx++) {
@@ -1309,6 +1573,12 @@ static int svs_suspend(struct device *dev)
 		svs_adjust_pm_opp_volts(svsb, true);
 	}
 
+	ret = reset_control_assert(svsp->rst);
+	if (ret) {
+		dev_err(svsp->dev, "cannot assert reset %d\n", ret);
+		return ret;
+	}
+
 	clk_disable_unprepare(svsp->main_clk);
 
 	return 0;
@@ -1327,6 +1597,12 @@ static int svs_resume(struct device *dev)
 		return ret;
 	}
 
+	ret = reset_control_deassert(svsp->rst);
+	if (ret) {
+		dev_err(svsp->dev, "cannot deassert reset %d\n", ret);
+		return ret;
+	}
+
 	for (idx = 0; idx < svsp->bank_max; idx++) {
 		svsb = &svsp->banks[idx];
 		svsb->suspended = false;
@@ -1365,7 +1641,12 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 			svsb->name = "SVSB_CCI";
 			break;
 		case SVSB_GPU:
-			svsb->name = "SVSB_GPU";
+			if (svsb->type == SVSB_HIGH)
+				svsb->name = "SVSB_GPU_HIGH";
+			else if (svsb->type == SVSB_LOW)
+				svsb->name = "SVSB_GPU_LOW";
+			else
+				svsb->name = "SVSB_GPU";
 			break;
 		default:
 			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
@@ -1419,6 +1700,84 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 	return 0;
 }
 
+static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct nvmem_cell *cell;
+	u32 idx, i, vmin, golden_temp;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse[i])
+			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+				 i, svsp->efuse[i]);
+
+	if (!svsp->efuse[9]) {
+		dev_notice(svsp->dev, "svs_efuse[9] = 0x0?\n");
+		return false;
+	}
+
+	/* Svs efuse parsing */
+	vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (vmin == 0x1)
+			svsb->vmin = 0x1e;
+
+		if (svsb->type == SVSB_LOW) {
+			svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[17]) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[17] >> 8) & GENMASK(7, 0);
+		} else if (svsb->type == SVSB_HIGH) {
+			svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[17] >> 24) & GENMASK(7, 0);
+		}
+
+		svsb->vmax += svsb->dvt_fixed;
+	}
+
+	/* Thermal efuse parsing */
+	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
+	if (IS_ERR_OR_NULL(cell)) {
+		dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		return false;
+	}
+
+	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max);
+	if (IS_ERR(svsp->tefuse)) {
+		dev_err(svsp->dev, "cannot read thermal efuse: %ld\n",
+			PTR_ERR(svsp->tefuse));
+		return false;
+	}
+
+	svsp->tefuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	for (i = 0; i < svsp->tefuse_max; i++)
+		if (svsp->tefuse[i] != 0)
+			break;
+
+	if (i == svsp->tefuse_max)
+		golden_temp = 50; /* All thermal efuse data are 0 */
+	else
+		golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mts = 500;
+		svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
+	}
+
+	return true;
+}
+
 static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb;
@@ -1702,6 +2061,38 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
 	return dev;
 }
 
+static int svs_mt8192_platform_probe(struct svs_platform *svsp)
+{
+	struct device *dev;
+	struct svs_bank *svsb;
+	u32 idx;
+
+	svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
+	if (IS_ERR(svsp->rst)) {
+		dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
+			      "cannot get svs reset control\n");
+		return PTR_ERR(svsp->rst);
+	}
+
+	dev = svs_add_device_link(svsp, "lvts");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->type == SVSB_HIGH)
+			svsb->opp_dev = svs_add_device_link(svsp, "mali");
+		else if (svsb->type == SVSB_LOW)
+			svsb->opp_dev = svs_get_subsys_device(svsp, "mali");
+
+		if (IS_ERR(svsb->opp_dev))
+			return PTR_ERR(svsb->opp_dev);
+	}
+
+	return 0;
+}
+
 static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 {
 	struct device *dev;
@@ -1742,6 +2133,61 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 	return 0;
 }
 
+static struct svs_bank svs_mt8192_banks[] = {
+	{
+		.sw_id			= SVSB_GPU,
+		.type			= SVSB_LOW,
+		.set_freq_pct		= svs_set_bank_freq_pct_v3,
+		.get_volts		= svs_get_bank_volts_v3,
+		.volt_flags		= SVSB_REMOVE_DVTFIXED_VOLT,
+		.mode_support		= SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 688000000,
+		.turn_freq_base		= 688000000,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.vmax			= 0x60,
+		.vmin			= 0x1a,
+		.age_config		= 0x555555,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x1,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.core_sel		= 0x0fff0100,
+		.int_st			= BIT(0),
+		.ctl0			= 0x00540003,
+	},
+	{
+		.sw_id			= SVSB_GPU,
+		.type			= SVSB_HIGH,
+		.set_freq_pct		= svs_set_bank_freq_pct_v3,
+		.get_volts		= svs_get_bank_volts_v3,
+		.tzone_name		= "gpu1",
+		.volt_flags		= SVSB_REMOVE_DVTFIXED_VOLT |
+					  SVSB_MON_VOLT_IGNORE,
+		.mode_support		= SVSB_MODE_INIT02 | SVSB_MODE_MON,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 902000000,
+		.turn_freq_base		= 688000000,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.vmax			= 0x60,
+		.vmin			= 0x1a,
+		.age_config		= 0x555555,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x6,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.core_sel		= 0x0fff0101,
+		.int_st			= BIT(1),
+		.ctl0			= 0x00540003,
+		.tzone_htemp		= 85000,
+		.tzone_htemp_voffset	= 0,
+		.tzone_ltemp		= 25000,
+		.tzone_ltemp_voffset	= 7,
+	},
+};
+
 static struct svs_bank svs_mt8183_banks[] = {
 	{
 		.sw_id			= SVSB_CPU_LITTLE,
@@ -1856,6 +2302,16 @@ struct svs_platform_data {
 	int (*probe)(struct svs_platform *svsp);
 };
 
+static const struct svs_platform_data svs_mt8192_platform_data = {
+	.name = "mt8192-svs",
+	.banks = svs_mt8192_banks,
+	.efuse_parsing = svs_mt8192_efuse_parsing,
+	.irqflags = IRQF_TRIGGER_HIGH,
+	.regs = svs_regs_v2,
+	.bank_max = ARRAY_SIZE(svs_mt8192_banks),
+	.probe = svs_mt8192_platform_probe,
+};
+
 static const struct svs_platform_data svs_mt8183_platform_data = {
 	.name = "mt8183-svs",
 	.banks = svs_mt8183_banks,
@@ -1868,6 +2324,9 @@ static const struct svs_platform_data svs_mt8183_platform_data = {
 
 static const struct of_device_id svs_of_match[] = {
 	{
+		.compatible = "mediatek,mt8192-svs",
+		.data = &svs_mt8192_platform_data,
+	}, {
 		.compatible = "mediatek,mt8183-svs",
 		.data = &svs_mt8183_platform_data,
 	}, {
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:56 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:56 +0800
Subject: [PATCH v21 4/8] soc: mediatek: SVS: add monitor mode
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-5-roger.lu@mediatek.com>

SVS monitor mode is based on different thermal temperature
to provide suitable SVS bank voltages.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 253 ++++++++++++++++++++++++++++++++-
 1 file changed, 247 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index fc7e2ee44a92..042c6e8e9069 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -25,6 +25,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/thermal.h>
 
 /* svs bank 1-line sw id */
 #define SVSB_CPU_LITTLE			BIT(0)
@@ -36,6 +37,7 @@
 #define SVSB_MODE_ALL_DISABLE		0
 #define SVSB_MODE_INIT01		BIT(1)
 #define SVSB_MODE_INIT02		BIT(2)
+#define SVSB_MODE_MON			BIT(3)
 
 /* svs bank volt flags */
 #define SVSB_INIT01_PD_REQ		BIT(0)
@@ -53,11 +55,16 @@
 #define SVSB_EN_INIT01			0x1
 #define SVSB_EN_INIT02			0x5
 #define SVSB_EN_MASK			0x7
+#define SVSB_EN_MON			0x2
 #define SVSB_EN_OFF			0x0
 #define SVSB_INTEN_INIT0x		0x00005f01
+#define SVSB_INTEN_MONVOPEN		0x00ff0000
 #define SVSB_INTSTS_CLEAN		0x00ffffff
 #define SVSB_INTSTS_COMPLETE		0x1
+#define SVSB_INTSTS_MONVOP		0x00ff0000
 #define SVSB_RUNCONFIG_DEFAULT		0x80000000
+#define SVSB_TEMP_LOWER_BOUND		0xb2
+#define SVSB_TEMP_UPPER_BOUND		0x64
 
 static DEFINE_SPINLOCK(svs_lock);
 
@@ -66,6 +73,7 @@ static DEFINE_SPINLOCK(svs_lock);
  * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
  * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
  * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
+ * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
  * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
  *
  * Each svs bank has its own independent phase and we enable each svs bank by
@@ -73,12 +81,13 @@ static DEFINE_SPINLOCK(svs_lock);
  * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
  *
  * svs bank general phase-enabled order:
- * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02
+ * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
  */
 enum svsb_phase {
 	SVSB_PHASE_ERROR = 0,
 	SVSB_PHASE_INIT01,
 	SVSB_PHASE_INIT02,
+	SVSB_PHASE_MON,
 	SVSB_PHASE_MAX,
 };
 
@@ -209,9 +218,11 @@ static const u32 svs_regs_v2[] = {
  * @probe: svs platform probe function pointer
  * @irqflags: svs platform irq settings flags
  * @efuse_max: total number of svs efuse
+ * @tefuse_max: total number of thermal efuse
  * @regs: svs platform registers map
  * @bank_max: total number of svs banks
  * @efuse: svs efuse data received from NVMEM framework
+ * @tefuse: thermal efuse data received from NVMEM framework
  */
 struct svs_platform {
 	char *name;
@@ -224,9 +235,11 @@ struct svs_platform {
 	int (*probe)(struct svs_platform *svsp);
 	unsigned long irqflags;
 	size_t efuse_max;
+	size_t tefuse_max;
 	const u32 *regs;
 	u32 bank_max;
 	u32 *efuse;
+	u32 *tefuse;
 };
 
 /**
@@ -241,6 +254,7 @@ struct svs_platform {
  * @get_volts: function pointer to get bank voltages
  * @name: bank name
  * @buck_name: regulator name
+ * @tzone_name: thermal zone name
  * @suspended: suspend flag of this bank
  * @phase: bank current phase
  * @volt_od: bank voltage overdrive
@@ -270,6 +284,13 @@ struct svs_platform {
  * @sw_id: bank software identification
  * @cpu_id: cpu core id for SVS CPU bank use only
  * @ctl0: TS-x selection
+ * @temp: bank temperature
+ * @tzone_htemp: thermal zone high temperature threshold
+ * @tzone_htemp_voffset: thermal zone high temperature voltage offset
+ * @tzone_ltemp: thermal zone low temperature threshold
+ * @tzone_ltemp_voffset: thermal zone low temperature voltage offset
+ * @bts: svs efuse data
+ * @mts: svs efuse data
  * @bdes: svs efuse data
  * @mdes: svs efuse data
  * @mtdes: svs efuse data
@@ -292,6 +313,7 @@ struct svs_bank {
 	void (*get_volts)(struct svs_platform *svsp);
 	char *name;
 	char *buck_name;
+	char *tzone_name;
 	bool suspended;
 	enum svsb_phase phase;
 	s32 volt_od;
@@ -321,6 +343,13 @@ struct svs_bank {
 	u32 sw_id;
 	u32 cpu_id;
 	u32 ctl0;
+	u32 temp;
+	u32 tzone_htemp;
+	u32 tzone_htemp_voffset;
+	u32 tzone_ltemp;
+	u32 tzone_ltemp_voffset;
+	u32 bts;
+	u32 mts;
 	u32 bdes;
 	u32 mdes;
 	u32 mtdes;
@@ -361,10 +390,21 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
 	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
 }
 
+static int svs_get_zone_temperature(const char *tzone_name, int *tzone_temp)
+{
+	struct thermal_zone_device *tzd;
+
+	tzd = thermal_zone_get_zone_by_name(tzone_name);
+	if (IS_ERR(tzd))
+		return PTR_ERR(tzd);
+
+	return thermal_zone_get_temp(tzd, tzone_temp);
+}
+
 static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 {
-	int ret = -EPERM;
-	u32 i, svsb_volt, opp_volt;
+	int ret = -EPERM, tzone_temp = 0;
+	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
 
 	mutex_lock(&svsb->lock);
 
@@ -378,6 +418,22 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 		goto unlock_mutex;
 	}
 
+	/* Get thermal effect */
+	if (svsb->phase == SVSB_PHASE_MON) {
+		ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
+		if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
+			    svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
+			dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n",
+				svsb->tzone_name, ret, svsb->temp);
+			svsb->phase = SVSB_PHASE_ERROR;
+		}
+
+		if (tzone_temp >= svsb->tzone_htemp)
+			temp_voffset += svsb->tzone_htemp_voffset;
+		else if (tzone_temp <= svsb->tzone_ltemp)
+			temp_voffset += svsb->tzone_ltemp_voffset;
+	}
+
 	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
 	for (i = 0; i < svsb->opp_count; i++) {
 		switch (svsb->phase) {
@@ -393,6 +449,13 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 							     svsb->volt_step,
 							     svsb->volt_base);
 			break;
+		case SVSB_PHASE_MON:
+			svsb_volt = max(svsb->volt[i] + temp_voffset,
+					svsb->vmin);
+			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
+							     svsb->volt_step,
+							     svsb->volt_base);
+			break;
 		default:
 			dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase);
 			ret = -EINVAL;
@@ -488,7 +551,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 {
 	struct svs_bank *svsb = svsp->pbank;
 	u32 des_char, temp_char, det_char, limit_vals;
-	u32 init2vals;
+	u32 init2vals, ts_calcs;
 
 	svs_switch_bank(svsp);
 
@@ -529,6 +592,12 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 		svs_writel_relaxed(svsp, init2vals, INIT2VALS);
 		svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN);
 		break;
+	case SVSB_PHASE_MON:
+		ts_calcs = (svsb->bts << 12) | svsb->mts;
+		svs_writel_relaxed(svsp, ts_calcs, TSCALCS);
+		svs_writel_relaxed(svsp, SVSB_INTEN_MONVOPEN, INTEN);
+		svs_writel_relaxed(svsp, SVSB_EN_MON, SVSEN);
+		break;
 	default:
 		dev_err(svsb->dev, "requested unknown target phase: %u\n",
 			target_phase);
@@ -548,6 +617,7 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
 	dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n",
 		svs_readl_relaxed(svsp, SMSTATE0),
 		svs_readl_relaxed(svsp, SMSTATE1));
+	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
 
 	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
 	svsb->phase = SVSB_PHASE_ERROR;
@@ -599,6 +669,17 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp)
 	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
 }
 
+static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svsb->phase = SVSB_PHASE_MON;
+	svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
+	svsb->get_volts(svsp);
+
+	svs_writel_relaxed(svsp, SVSB_INTSTS_MONVOP, INTSTS);
+}
+
 static irqreturn_t svs_isr(int irq, void *data)
 {
 	struct svs_platform *svsp = data;
@@ -629,6 +710,8 @@ static irqreturn_t svs_isr(int irq, void *data)
 		else if (int_sts == SVSB_INTSTS_COMPLETE &&
 			 svs_en == SVSB_EN_INIT02)
 			svs_init02_isr_handler(svsp);
+		else if (int_sts & SVSB_INTSTS_MONVOP)
+			svs_mon_mode_isr_handler(svsp);
 		else
 			svs_error_isr_handler(svsp);
 
@@ -858,6 +941,25 @@ static int svs_init02(struct svs_platform *svsp)
 	return 0;
 }
 
+static void svs_mon_mode(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	unsigned long flags;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_MON))
+			continue;
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_MON);
+		spin_unlock_irqrestore(&svs_lock, flags);
+	}
+}
+
 static int svs_start(struct svs_platform *svsp)
 {
 	int ret;
@@ -870,6 +972,8 @@ static int svs_start(struct svs_platform *svsp)
 	if (ret)
 		return ret;
 
+	svs_mon_mode(svsp);
+
 	return 0;
 }
 
@@ -923,6 +1027,8 @@ static int svs_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	svs_mon_mode(svsp);
+
 	return 0;
 }
 
@@ -1007,7 +1113,11 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb;
-	u32 idx, i, ft_pgm;
+	struct nvmem_cell *cell;
+	int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0;
+	int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t;
+	int o_slope, o_slope_sign, ts_id;
+	u32 idx, i, ft_pgm, mts, temp0, temp1, temp2;
 
 	for (i = 0; i < svsp->efuse_max; i++)
 		if (svsp->efuse[i])
@@ -1083,6 +1193,126 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 		}
 	}
 
+	/* Get thermal efuse by nvmem */
+	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
+	if (IS_ERR(cell)) {
+		dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max);
+	if (IS_ERR(svsp->tefuse)) {
+		dev_err(svsp->dev, "cannot read thermal efuse: %ld\n",
+			PTR_ERR(svsp->tefuse));
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	svsp->tefuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	/* Thermal efuse parsing */
+	adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0);
+	adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0);
+
+	o_vtsmcu[0] = (svsp->tefuse[0] >> 17) & GENMASK(8, 0);
+	o_vtsmcu[1] = (svsp->tefuse[0] >> 8) & GENMASK(8, 0);
+	o_vtsmcu[2] = svsp->tefuse[1] & GENMASK(8, 0);
+	o_vtsmcu[3] = (svsp->tefuse[2] >> 23) & GENMASK(8, 0);
+	o_vtsmcu[4] = (svsp->tefuse[2] >> 5) & GENMASK(8, 0);
+	o_vtsabb = (svsp->tefuse[2] >> 14) & GENMASK(8, 0);
+
+	degc_cali = (svsp->tefuse[0] >> 1) & GENMASK(5, 0);
+	adc_cali_en_t = svsp->tefuse[0] & BIT(0);
+	o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0);
+
+	ts_id = (svsp->tefuse[1] >> 9) & BIT(0);
+	o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
+
+	if (adc_cali_en_t == 1) {
+		if (!ts_id)
+			o_slope = 0;
+
+		if (adc_ge_t < 265 || adc_ge_t > 758 ||
+		    adc_oe_t < 265 || adc_oe_t > 758 ||
+		    o_vtsmcu[0] < -8 || o_vtsmcu[0] > 484 ||
+		    o_vtsmcu[1] < -8 || o_vtsmcu[1] > 484 ||
+		    o_vtsmcu[2] < -8 || o_vtsmcu[2] > 484 ||
+		    o_vtsmcu[3] < -8 || o_vtsmcu[3] > 484 ||
+		    o_vtsmcu[4] < -8 || o_vtsmcu[4] > 484 ||
+		    o_vtsabb < -8 || o_vtsabb > 484 ||
+		    degc_cali < 1 || degc_cali > 63) {
+			dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
+			goto remove_mt8183_svsb_mon_mode;
+		}
+	} else {
+		dev_err(svsp->dev, "no thermal efuse, no mon mode\n");
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	ge = ((adc_ge_t - 512) * 10000) / 4096;
+	oe = (adc_oe_t - 512);
+	gain = (10000 + ge);
+
+	format[0] = (o_vtsmcu[0] + 3350 - oe);
+	format[1] = (o_vtsmcu[1] + 3350 - oe);
+	format[2] = (o_vtsmcu[2] + 3350 - oe);
+	format[3] = (o_vtsmcu[3] + 3350 - oe);
+	format[4] = (o_vtsmcu[4] + 3350 - oe);
+	format[5] = (o_vtsabb + 3350 - oe);
+
+	for (i = 0; i < 6; i++)
+		x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / gain;
+
+	temp0 = (10000 * 100000 / gain) * 15 / 18;
+
+	if (!o_slope_sign)
+		mts = (temp0 * 10) / (1534 + o_slope * 10);
+	else
+		mts = (temp0 * 10) / (1534 - o_slope * 10);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mts = mts;
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			tb_roomt = x_roomt[3];
+			break;
+		case SVSB_CPU_BIG:
+			tb_roomt = x_roomt[4];
+			break;
+		case SVSB_CCI:
+			tb_roomt = x_roomt[3];
+			break;
+		case SVSB_GPU:
+			tb_roomt = x_roomt[1];
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			goto remove_mt8183_svsb_mon_mode;
+		}
+
+		temp0 = (degc_cali * 10 / 2);
+		temp1 = ((10000 * 100000 / 4096 / gain) *
+			 oe + tb_roomt * 10) * 15 / 18;
+
+		if (!o_slope_sign)
+			temp2 = temp1 * 100 / (1534 + o_slope * 10);
+		else
+			temp2 = temp1 * 100 / (1534 - o_slope * 10);
+
+		svsb->bts = (temp0 + temp2 - 250) * 4 / 10;
+	}
+
+	return true;
+
+remove_mt8183_svsb_mon_mode:
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mode_support &= ~SVSB_MODE_MON;
+	}
+
 	return true;
 }
 
@@ -1165,9 +1395,14 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
 
 static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 {
+	struct device *dev;
 	struct svs_bank *svsb;
 	u32 idx;
 
+	dev = svs_add_device_link(svsp, "thermal");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
 	for (idx = 0; idx < svsp->bank_max; idx++) {
 		svsb = &svsp->banks[idx];
 
@@ -1275,9 +1510,11 @@ static struct svs_bank svs_mt8183_banks[] = {
 		.set_freq_pct		= svs_set_bank_freq_pct_v2,
 		.get_volts		= svs_get_bank_volts_v2,
 		.buck_name		= "mali",
+		.tzone_name		= "tzts2",
 		.volt_flags		= SVSB_INIT01_PD_REQ |
 					  SVSB_INIT01_VOLT_INC_ONLY,
-		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02 |
+					  SVSB_MODE_MON,
 		.opp_count		= MAX_OPP_ENTRIES,
 		.freq_base		= 900000000,
 		.vboot			= 0x30,
@@ -1293,6 +1530,10 @@ static struct svs_bank svs_mt8183_banks[] = {
 		.core_sel		= 0x8fff0003,
 		.int_st			= BIT(3),
 		.ctl0			= 0x00050001,
+		.tzone_htemp		= 85000,
+		.tzone_htemp_voffset	= 0,
+		.tzone_ltemp		= 25000,
+		.tzone_ltemp_voffset	= 3,
 	},
 };
 
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:57 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:57 +0800
Subject: [PATCH v21 5/8] soc: mediatek: SVS: add debug commands
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-6-roger.lu@mediatek.com>

The purpose of SVS is to help find the suitable voltages
for DVFS. Therefore, if SVS bank voltages are concerned
to be wrong, we can adjust SVS bank voltages by this patch.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 321 ++++++++++++++++++++++++++++++++-
 1 file changed, 318 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 042c6e8e9069..93cdaecadd6d 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -6,6 +6,7 @@
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -23,6 +24,7 @@
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/thermal.h>
@@ -68,6 +70,39 @@
 
 static DEFINE_SPINLOCK(svs_lock);
 
+#define debug_fops_ro(name)						\
+	static int svs_##name##_debug_open(struct inode *inode,		\
+					   struct file *filp)		\
+	{								\
+		return single_open(filp, svs_##name##_debug_show,	\
+				   inode->i_private);			\
+	}								\
+	static const struct file_operations svs_##name##_debug_fops = {	\
+		.owner = THIS_MODULE,					\
+		.open = svs_##name##_debug_open,			\
+		.read = seq_read,					\
+		.llseek = seq_lseek,					\
+		.release = single_release,				\
+	}
+
+#define debug_fops_rw(name)						\
+	static int svs_##name##_debug_open(struct inode *inode,		\
+					   struct file *filp)		\
+	{								\
+		return single_open(filp, svs_##name##_debug_show,	\
+				   inode->i_private);			\
+	}								\
+	static const struct file_operations svs_##name##_debug_fops = {	\
+		.owner = THIS_MODULE,					\
+		.open = svs_##name##_debug_open,			\
+		.read = seq_read,					\
+		.write = svs_##name##_debug_write,			\
+		.llseek = seq_lseek,					\
+		.release = single_release,				\
+	}
+
+#define svs_dentry_data(name)	{__stringify(name), &svs_##name##_debug_fops}
+
 /**
  * enum svsb_phase - svs bank phase enumeration
  * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
@@ -258,6 +293,8 @@ struct svs_platform {
  * @suspended: suspend flag of this bank
  * @phase: bank current phase
  * @volt_od: bank voltage overdrive
+ * @voffset: bank voltage offset for debug purpose
+ * @reg_data: bank register data in different phase for debug purpose
  * @pm_runtime_enabled_count: bank pm runtime enabled count
  * @mode_support: bank mode support.
  * @freq_base: reference frequency for bank init
@@ -317,6 +354,8 @@ struct svs_bank {
 	bool suspended;
 	enum svsb_phase phase;
 	s32 volt_od;
+	s32 voffset;
+	u32 reg_data[SVSB_PHASE_MAX][SVS_REG_MAX];
 	u32 pm_runtime_enabled_count;
 	u32 mode_support;
 	u32 freq_base;
@@ -444,14 +483,15 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 			/* do nothing */
 			goto unlock_mutex;
 		case SVSB_PHASE_INIT02:
-			svsb_volt = max(svsb->volt[i], svsb->vmin);
+			svsb_volt = max(svsb->volt[i] + svsb->voffset,
+					svsb->vmin);
 			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
 							     svsb->volt_step,
 							     svsb->volt_base);
 			break;
 		case SVSB_PHASE_MON:
-			svsb_volt = max(svsb->volt[i] + temp_voffset,
-					svsb->vmin);
+			svsb_volt = max(svsb->volt[i] + temp_voffset +
+					svsb->voffset, svsb->vmin);
 			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
 							     svsb->volt_step,
 							     svsb->volt_base);
@@ -480,6 +520,257 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
 	return ret;
 }
 
+static int svs_dump_debug_show(struct seq_file *m, void *p)
+{
+	struct svs_platform *svsp = (struct svs_platform *)m->private;
+	struct svs_bank *svsb;
+	unsigned long svs_reg_addr;
+	u32 idx, i, j, bank_id;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse && svsp->efuse[i])
+			seq_printf(m, "M_HW_RES%d = 0x%08x\n",
+				   i, svsp->efuse[i]);
+
+	for (i = 0; i < svsp->tefuse_max; i++)
+		if (svsp->tefuse)
+			seq_printf(m, "THERMAL_EFUSE%d = 0x%08x\n",
+				   i, svsp->tefuse[i]);
+
+	for (bank_id = 0, idx = 0; idx < svsp->bank_max; idx++, bank_id++) {
+		svsb = &svsp->banks[idx];
+
+		for (i = SVSB_PHASE_INIT01; i <= SVSB_PHASE_MON; i++) {
+			seq_printf(m, "Bank_number = %u\n", bank_id);
+
+			if (i == SVSB_PHASE_INIT01 || i == SVSB_PHASE_INIT02)
+				seq_printf(m, "mode = init%d\n", i);
+			else if (i == SVSB_PHASE_MON)
+				seq_puts(m, "mode = mon\n");
+			else
+				seq_puts(m, "mode = error\n");
+
+			for (j = DESCHAR; j < SVS_REG_MAX; j++) {
+				svs_reg_addr = (unsigned long)(svsp->base +
+							       svsp->regs[j]);
+				seq_printf(m, "0x%08lx = 0x%08x\n",
+					   svs_reg_addr, svsb->reg_data[i][j]);
+			}
+		}
+	}
+
+	return 0;
+}
+
+debug_fops_ro(dump);
+
+static int svs_enable_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+
+	switch (svsb->phase) {
+	case SVSB_PHASE_ERROR:
+		seq_puts(m, "disabled\n");
+		break;
+	case SVSB_PHASE_INIT01:
+		seq_puts(m, "init1\n");
+		break;
+	case SVSB_PHASE_INIT02:
+		seq_puts(m, "init2\n");
+		break;
+	case SVSB_PHASE_MON:
+		seq_puts(m, "mon mode\n");
+		break;
+	default:
+		seq_puts(m, "unknown\n");
+		break;
+	}
+
+	return 0;
+}
+
+static ssize_t svs_enable_debug_write(struct file *filp,
+				      const char __user *buffer,
+				      size_t count, loff_t *pos)
+{
+	struct svs_bank *svsb = file_inode(filp)->i_private;
+	struct svs_platform *svsp = dev_get_drvdata(svsb->dev);
+	unsigned long flags;
+	int enabled, ret;
+	char *buf = NULL;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+
+	buf = (char *)memdup_user_nul(buffer, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	ret = kstrtoint(buf, 10, &enabled);
+	if (ret)
+		return ret;
+
+	if (!enabled) {
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svsb->mode_support = SVSB_MODE_ALL_DISABLE;
+		svs_switch_bank(svsp);
+		svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+		svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		svsb->phase = SVSB_PHASE_ERROR;
+		svs_adjust_pm_opp_volts(svsb, true);
+	}
+
+	kfree(buf);
+
+	return count;
+}
+
+debug_fops_rw(enable);
+
+static int svs_status_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+	struct dev_pm_opp *opp;
+	int tzone_temp = 0, ret;
+	u32 i;
+
+	ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
+	if (ret)
+		seq_printf(m, "%s: temperature ignore\n", svsb->name);
+	else
+		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
+						 svsb->opp_dfreq[i], true);
+		if (IS_ERR(opp)) {
+			seq_printf(m, "%s: cannot find freq = %u (%ld)\n",
+				   svsb->name, svsb->opp_dfreq[i],
+				   PTR_ERR(opp));
+			return PTR_ERR(opp);
+		}
+
+		seq_printf(m, "opp_freq[%02u]: %u, opp_volt[%02u]: %lu, ",
+			   i, svsb->opp_dfreq[i], i,
+			   dev_pm_opp_get_voltage(opp));
+		seq_printf(m, "svsb_volt[%02u]: 0x%x, freq_pct[%02u]: %u\n",
+			   i, svsb->volt[i], i, svsb->freq_pct[i]);
+		dev_pm_opp_put(opp);
+	}
+
+	return 0;
+}
+
+debug_fops_ro(status);
+
+static int svs_voffset_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+
+	seq_printf(m, "%d\n", svsb->voffset);
+
+	return 0;
+}
+
+static ssize_t svs_voffset_debug_write(struct file *filp,
+				       const char __user *buffer,
+				       size_t count, loff_t *pos)
+{
+	struct svs_bank *svsb = file_inode(filp)->i_private;
+	char *buf = NULL;
+	s32 voffset;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+
+	buf = (char *)memdup_user_nul(buffer, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	if (!kstrtoint(buf, 10, &voffset)) {
+		svsb->voffset = voffset;
+		svs_adjust_pm_opp_volts(svsb, true);
+	}
+
+	kfree(buf);
+
+	return count;
+}
+
+debug_fops_rw(voffset);
+
+static int svs_create_debug_cmds(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct dentry *svs_dir, *svsb_dir, *file_entry;
+	const char *d = "/sys/kernel/debug/svs";
+	u32 i, idx;
+
+	struct svs_dentry {
+		const char *name;
+		const struct file_operations *fops;
+	};
+
+	struct svs_dentry svs_entries[] = {
+		svs_dentry_data(dump),
+	};
+
+	struct svs_dentry svsb_entries[] = {
+		svs_dentry_data(enable),
+		svs_dentry_data(status),
+		svs_dentry_data(voffset),
+	};
+
+	svs_dir = debugfs_create_dir("svs", NULL);
+	if (IS_ERR(svs_dir)) {
+		dev_err(svsp->dev, "cannot create %s: %ld\n",
+			d, PTR_ERR(svs_dir));
+		return PTR_ERR(svs_dir);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(svs_entries); i++) {
+		file_entry = debugfs_create_file(svs_entries[i].name, 0664,
+						 svs_dir, svsp,
+						 svs_entries[i].fops);
+		if (IS_ERR(file_entry)) {
+			dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
+				d, svs_entries[i].name, PTR_ERR(file_entry));
+			return PTR_ERR(file_entry);
+		}
+	}
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->mode_support == SVSB_MODE_ALL_DISABLE)
+			continue;
+
+		svsb_dir = debugfs_create_dir(svsb->name, svs_dir);
+		if (IS_ERR(svsb_dir)) {
+			dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
+				d, svsb->name, PTR_ERR(svsb_dir));
+			return PTR_ERR(svsb_dir);
+		}
+
+		for (i = 0; i < ARRAY_SIZE(svsb_entries); i++) {
+			file_entry = debugfs_create_file(svsb_entries[i].name,
+							 0664, svsb_dir, svsb,
+							 svsb_entries[i].fops);
+			if (IS_ERR(file_entry)) {
+				dev_err(svsp->dev, "no %s/%s/%s?: %ld\n",
+					d, svsb->name, svsb_entries[i].name,
+					PTR_ERR(file_entry));
+				return PTR_ERR(file_entry);
+			}
+		}
+	}
+
+	return 0;
+}
+
 static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
 {
 	u32 vx;
@@ -605,6 +896,16 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 	}
 }
 
+static inline void svs_save_bank_register_data(struct svs_platform *svsp,
+					       enum svsb_phase phase)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	enum svs_reg_index rg_i;
+
+	for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++)
+		svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i);
+}
+
 static inline void svs_error_isr_handler(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
@@ -619,6 +920,8 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
 		svs_readl_relaxed(svsp, SMSTATE1));
 	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR);
+
 	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
 	svsb->phase = SVSB_PHASE_ERROR;
 
@@ -635,6 +938,8 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
 		 svs_readl_relaxed(svsp, VDESIGN30),
 		 svs_readl_relaxed(svsp, DCVALUES));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01);
+
 	svsb->phase = SVSB_PHASE_INIT01;
 	svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
 				GENMASK(15, 0)) + 1;
@@ -662,6 +967,8 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp)
 		 svs_readl_relaxed(svsp, VOP30),
 		 svs_readl_relaxed(svsp, DCVALUES));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02);
+
 	svsb->phase = SVSB_PHASE_INIT02;
 	svsb->get_volts(svsp);
 
@@ -673,6 +980,8 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_MON);
+
 	svsb->phase = SVSB_PHASE_MON;
 	svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
 	svsb->get_volts(svsp);
@@ -1658,6 +1967,12 @@ static int svs_probe(struct platform_device *pdev)
 		goto svs_probe_iounmap;
 	}
 
+	ret = svs_create_debug_cmds(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret);
+		goto svs_probe_iounmap;
+	}
+
 	return 0;
 
 svs_probe_iounmap:
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:58 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:58 +0800
Subject: [PATCH v21 6/8] dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-7-roger.lu@mediatek.com>

Add mt8192 svs compatible/resets in dt-bindings.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 .../devicetree/bindings/soc/mediatek/mtk-svs.yaml         | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
index a855ced410f8..59342e627b67 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -22,6 +22,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-svs
+      - mediatek,mt8192-svs
 
   reg:
     maxItems: 1
@@ -51,6 +52,13 @@ properties:
       - const: svs-calibration-data
       - const: t-calibration-data
 
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: svs_rst
+
 required:
   - compatible
   - reg
-- 
2.18.0



From roger.lu at mediatek.com  Fri Jan  7 01:51:52 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:52 +0800
Subject: [PATCH v21 0/8] soc: mediatek: SVS: introduce MTK SVS engine
Message-ID: <20220107095200.4389-1-roger.lu@mediatek.com>

The Smart Voltage Scaling(SVS) engine is a piece of hardware
which calculates suitable SVS bank voltages to OPP voltage table.
Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
when receiving OPP_EVENT_ADJUST_VOLTAGE.

1. SVS driver uses OPP adjust event in [1] to update OPP table voltage part.
2. SVS driver gets thermal/GPU device by node [2][3] and CPU device by get_cpu_device().
After retrieving subsys device, SVS driver calls device_link_add() to make sure probe/suspend callback priority.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git/commit/?h=opp/linux-next&id=25cb20a212a1f989385dfe23230817e69c62bee5
[2] https://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git/commit/?h=opp/linux-next&id=b325ce39785b1408040d90365a6ab1aa36e94f87
[3] https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/commit/?h=v5.16-next/dts64&id=a8168cebf1bca1b5269e8a7eb2626fb76814d6e2

change since v20:
- Rebase to kernel 5.16-rc1
- Separate mt8183 svs as two patches for minimun version support. patch1 (init01 ~ init02) and patch2 (mon mode).
- Remove unused flags in each patch.
- Move @SVSB_PHASE_ERROR before @SVSB_PHASE_INIT01 for order correctness.
- Reorder the struct member comment and coding for the consistenty. Also revise the ambiguous comments.
- Use [writel,readl]_relaxed instead of [writel,readl].
- Fix ->efuse_parsing() not return "false" mistake.
- Move more commen settings out of svs bank structure for shrinking data structure size.
- Split up the "get platform data" and "platform probe" behavior.
- Change the naming of "svs_is_supported()" to "svs_is_efuse_data_correct()" for better understanding.
- SVSB_DC_SIGNED_BIT is configured as BIT(15) instead of 0x8000.
- Add the missing variables comments back in the structure.
- Add define "MAX_OPP_ENTRIES" for representing opp total count.
- Add more kernel log description when error happens.
- Add missing error handler when using nvmem_cell_read().

Roger Lu (8):
  [v21,1/8] dt-bindings: soc: mediatek: add mtk svs dt-bindings
  [v21,2/8] arm64: dts: mt8183: add svs device information
  [v21,3/8] soc: mediatek: SVS: introduce MTK SVS engine
  [v21,4/8] soc: mediatek: SVS: add monitor mode
  [v21,5/8] soc: mediatek: SVS: add debug commands
  [v21,6/8] dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
  [v21,7/8] arm64: dts: mt8192: add svs device information
  [v21,8/8] soc: mediatek: SVS: add mt8192 SVS GPU driver

 .../bindings/soc/mediatek/mtk-svs.yaml        |   92 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |   16 +
 arch/arm64/boot/dts/mediatek/mt8192.dtsi      |   39 +
 drivers/soc/mediatek/Kconfig                  |   10 +
 drivers/soc/mediatek/Makefile                 |    1 +
 drivers/soc/mediatek/mtk-svs.c                | 2461 +++++++++++++++++
 6 files changed, 2619 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
 create mode 100644 drivers/soc/mediatek/mtk-svs.c



From roger.lu at mediatek.com  Fri Jan  7 01:51:55 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Fri, 7 Jan 2022 17:51:55 +0800
Subject: [PATCH v21 3/8] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <20220107095200.4389-1-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
Message-ID: <20220107095200.4389-4-roger.lu@mediatek.com>

The Smart Voltage Scaling(SVS) engine is a piece of hardware
which calculates suitable SVS bank voltages to OPP voltage table.
Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
when receiving OPP_EVENT_ADJUST_VOLTAGE.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/Kconfig   |   10 +
 drivers/soc/mediatek/Makefile  |    1 +
 drivers/soc/mediatek/mtk-svs.c | 1446 ++++++++++++++++++++++++++++++++
 3 files changed, 1457 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-svs.c

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index fdd8bc08569e..3c3eedea35f7 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -73,4 +73,14 @@ config MTK_MMSYS
 	  Say yes here to add support for the MediaTek Multimedia
 	  Subsystem (MMSYS).
 
+config MTK_SVS
+	tristate "MediaTek Smart Voltage Scaling(SVS)"
+	depends on MTK_EFUSE && NVMEM
+	help
+	  The Smart Voltage Scaling(SVS) engine is a piece of hardware
+	  which has several controllers(banks) for calculating suitable
+	  voltage to different power domains(CPU/GPU/CCI) according to
+	  chip process corner, temperatures and other factors. Then DVFS
+	  driver could apply SVS bank voltage to PMIC/Buck.
+
 endmenu
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 90270f8114ed..0e9e703c931a 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
 obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
+obj-$(CONFIG_MTK_SVS) += mtk-svs.o
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
new file mode 100644
index 000000000000..fc7e2ee44a92
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -0,0 +1,1446 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* svs bank 1-line sw id */
+#define SVSB_CPU_LITTLE			BIT(0)
+#define SVSB_CPU_BIG			BIT(1)
+#define SVSB_CCI			BIT(2)
+#define SVSB_GPU			BIT(3)
+
+/* svs bank mode support */
+#define SVSB_MODE_ALL_DISABLE		0
+#define SVSB_MODE_INIT01		BIT(1)
+#define SVSB_MODE_INIT02		BIT(2)
+
+/* svs bank volt flags */
+#define SVSB_INIT01_PD_REQ		BIT(0)
+#define SVSB_INIT01_VOLT_IGNORE		BIT(1)
+#define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
+
+/* svs bank common setting */
+#define MAX_OPP_ENTRIES			16
+#define SVSB_DC_SIGNED_BIT		BIT(15)
+#define SVSB_DET_CLK_EN			BIT(31)
+#define SVSB_DET_MAX			0xffff
+#define SVSB_DET_WINDOW			0xa28
+#define SVSB_DTHI			0x1
+#define SVSB_DTLO			0xfe
+#define SVSB_EN_INIT01			0x1
+#define SVSB_EN_INIT02			0x5
+#define SVSB_EN_MASK			0x7
+#define SVSB_EN_OFF			0x0
+#define SVSB_INTEN_INIT0x		0x00005f01
+#define SVSB_INTSTS_CLEAN		0x00ffffff
+#define SVSB_INTSTS_COMPLETE		0x1
+#define SVSB_RUNCONFIG_DEFAULT		0x80000000
+
+static DEFINE_SPINLOCK(svs_lock);
+
+/**
+ * enum svsb_phase - svs bank phase enumeration
+ * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
+ * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
+ * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
+ * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
+ *
+ * Each svs bank has its own independent phase and we enable each svs bank by
+ * running their phase orderly. However, when svs bank encounters unexpected
+ * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
+ *
+ * svs bank general phase-enabled order:
+ * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02
+ */
+enum svsb_phase {
+	SVSB_PHASE_ERROR = 0,
+	SVSB_PHASE_INIT01,
+	SVSB_PHASE_INIT02,
+	SVSB_PHASE_MAX,
+};
+
+enum svs_reg_index {
+	DESCHAR = 0,
+	TEMPCHAR,
+	DETCHAR,
+	AGECHAR,
+	DCCONFIG,
+	AGECONFIG,
+	FREQPCT30,
+	FREQPCT74,
+	LIMITVALS,
+	VBOOT,
+	DETWINDOW,
+	CONFIG,
+	TSCALCS,
+	RUNCONFIG,
+	SVSEN,
+	INIT2VALS,
+	DCVALUES,
+	AGEVALUES,
+	VOP30,
+	VOP74,
+	TEMP,
+	INTSTS,
+	INTSTSRAW,
+	INTEN,
+	CHKINT,
+	CHKSHIFT,
+	STATUS,
+	VDESIGN30,
+	VDESIGN74,
+	DVT30,
+	DVT74,
+	AGECOUNT,
+	SMSTATE0,
+	SMSTATE1,
+	CTL0,
+	DESDETSEC,
+	TEMPAGESEC,
+	CTRLSPARE0,
+	CTRLSPARE1,
+	CTRLSPARE2,
+	CTRLSPARE3,
+	CORESEL,
+	THERMINTST,
+	INTST,
+	THSTAGE0ST,
+	THSTAGE1ST,
+	THSTAGE2ST,
+	THAHBST0,
+	THAHBST1,
+	SPARE0,
+	SPARE1,
+	SPARE2,
+	SPARE3,
+	THSLPEVEB,
+	SVS_REG_MAX,
+};
+
+static const u32 svs_regs_v2[] = {
+	[DESCHAR]		= 0xc00,
+	[TEMPCHAR]		= 0xc04,
+	[DETCHAR]		= 0xc08,
+	[AGECHAR]		= 0xc0c,
+	[DCCONFIG]		= 0xc10,
+	[AGECONFIG]		= 0xc14,
+	[FREQPCT30]		= 0xc18,
+	[FREQPCT74]		= 0xc1c,
+	[LIMITVALS]		= 0xc20,
+	[VBOOT]			= 0xc24,
+	[DETWINDOW]		= 0xc28,
+	[CONFIG]		= 0xc2c,
+	[TSCALCS]		= 0xc30,
+	[RUNCONFIG]		= 0xc34,
+	[SVSEN]			= 0xc38,
+	[INIT2VALS]		= 0xc3c,
+	[DCVALUES]		= 0xc40,
+	[AGEVALUES]		= 0xc44,
+	[VOP30]			= 0xc48,
+	[VOP74]			= 0xc4c,
+	[TEMP]			= 0xc50,
+	[INTSTS]		= 0xc54,
+	[INTSTSRAW]		= 0xc58,
+	[INTEN]			= 0xc5c,
+	[CHKINT]		= 0xc60,
+	[CHKSHIFT]		= 0xc64,
+	[STATUS]		= 0xc68,
+	[VDESIGN30]		= 0xc6c,
+	[VDESIGN74]		= 0xc70,
+	[DVT30]			= 0xc74,
+	[DVT74]			= 0xc78,
+	[AGECOUNT]		= 0xc7c,
+	[SMSTATE0]		= 0xc80,
+	[SMSTATE1]		= 0xc84,
+	[CTL0]			= 0xc88,
+	[DESDETSEC]		= 0xce0,
+	[TEMPAGESEC]		= 0xce4,
+	[CTRLSPARE0]		= 0xcf0,
+	[CTRLSPARE1]		= 0xcf4,
+	[CTRLSPARE2]		= 0xcf8,
+	[CTRLSPARE3]		= 0xcfc,
+	[CORESEL]		= 0xf00,
+	[THERMINTST]		= 0xf04,
+	[INTST]			= 0xf08,
+	[THSTAGE0ST]		= 0xf0c,
+	[THSTAGE1ST]		= 0xf10,
+	[THSTAGE2ST]		= 0xf14,
+	[THAHBST0]		= 0xf18,
+	[THAHBST1]		= 0xf1c,
+	[SPARE0]		= 0xf20,
+	[SPARE1]		= 0xf24,
+	[SPARE2]		= 0xf28,
+	[SPARE3]		= 0xf2c,
+	[THSLPEVEB]		= 0xf30,
+};
+
+/**
+ * struct svs_platform - svs platform control
+ * @name: svs platform name
+ * @base: svs platform register base
+ * @dev: svs platform device
+ * @main_clk: main clock for svs bank
+ * @pbank: svs bank pointer protected by spin_lock section
+ * @banks: svs banks that svs platform supports
+ * @efuse_parsing: svs platform efuse parsing function pointer
+ * @probe: svs platform probe function pointer
+ * @irqflags: svs platform irq settings flags
+ * @efuse_max: total number of svs efuse
+ * @regs: svs platform registers map
+ * @bank_max: total number of svs banks
+ * @efuse: svs efuse data received from NVMEM framework
+ */
+struct svs_platform {
+	char *name;
+	void __iomem *base;
+	struct device *dev;
+	struct clk *main_clk;
+	struct svs_bank *pbank;
+	struct svs_bank *banks;
+	bool (*efuse_parsing)(struct svs_platform *svsp);
+	int (*probe)(struct svs_platform *svsp);
+	unsigned long irqflags;
+	size_t efuse_max;
+	const u32 *regs;
+	u32 bank_max;
+	u32 *efuse;
+};
+
+/**
+ * struct svs_bank - svs bank representation
+ * @dev: bank device
+ * @opp_dev: device for opp table/buck control
+ * @pd_dev: power domain device for SoC mtcmos control
+ * @init_completion: the timeout completion for bank init
+ * @buck: regulator used by opp_dev
+ * @lock: mutex lock to protect voltage update process
+ * @set_freq_pct: function pointer to set bank frequency percent table
+ * @get_volts: function pointer to get bank voltages
+ * @name: bank name
+ * @buck_name: regulator name
+ * @suspended: suspend flag of this bank
+ * @phase: bank current phase
+ * @volt_od: bank voltage overdrive
+ * @pm_runtime_enabled_count: bank pm runtime enabled count
+ * @mode_support: bank mode support.
+ * @freq_base: reference frequency for bank init
+ * @vboot: voltage request for bank init01 only
+ * @opp_dfreq: default opp frequency table
+ * @opp_dvolt: default opp voltage table
+ * @freq_pct: frequency percent table for bank init
+ * @volt: bank voltage table
+ * @volt_step: bank voltage step
+ * @volt_base: bank voltage base
+ * @volt_flags: bank voltage flags
+ * @vmax: bank voltage maximum
+ * @vmin: bank voltage minimum
+ * @age_config: bank age configuration
+ * @age_voffset_in: bank age voltage offset
+ * @dc_config: bank dc configuration
+ * @dc_voffset_in: bank dc voltage offset
+ * @dvt_fixed: bank dvt fixed value
+ * @vco: bank VCO value
+ * @chk_shift: bank chicken shift
+ * @core_sel: bank selection
+ * @opp_count: bank opp count
+ * @int_st: bank interrupt identification
+ * @sw_id: bank software identification
+ * @cpu_id: cpu core id for SVS CPU bank use only
+ * @ctl0: TS-x selection
+ * @bdes: svs efuse data
+ * @mdes: svs efuse data
+ * @mtdes: svs efuse data
+ * @dcbdet: svs efuse data
+ * @dcmdet: svs efuse data
+ *
+ * Svs bank will generate suitalbe voltages by below general math equation
+ * and provide these voltages to opp voltage table.
+ *
+ * opp volt[i] = (volt_step * volt[i]) + volt_base;
+ */
+struct svs_bank {
+	struct device *dev;
+	struct device *opp_dev;
+	struct device *pd_dev;
+	struct completion init_completion;
+	struct regulator *buck;
+	struct mutex lock;	/* lock to protect voltage update process */
+	void (*set_freq_pct)(struct svs_platform *svsp);
+	void (*get_volts)(struct svs_platform *svsp);
+	char *name;
+	char *buck_name;
+	bool suspended;
+	enum svsb_phase phase;
+	s32 volt_od;
+	u32 pm_runtime_enabled_count;
+	u32 mode_support;
+	u32 freq_base;
+	u32 vboot;
+	u32 opp_dfreq[MAX_OPP_ENTRIES];
+	u32 opp_dvolt[MAX_OPP_ENTRIES];
+	u32 freq_pct[MAX_OPP_ENTRIES];
+	u32 volt[MAX_OPP_ENTRIES];
+	u32 volt_step;
+	u32 volt_base;
+	u32 volt_flags;
+	u32 vmax;
+	u32 vmin;
+	u32 age_config;
+	u32 age_voffset_in;
+	u32 dc_config;
+	u32 dc_voffset_in;
+	u32 dvt_fixed;
+	u32 vco;
+	u32 chk_shift;
+	u32 core_sel;
+	u32 opp_count;
+	u32 int_st;
+	u32 sw_id;
+	u32 cpu_id;
+	u32 ctl0;
+	u32 bdes;
+	u32 mdes;
+	u32 mtdes;
+	u32 dcbdet;
+	u32 dcmdet;
+};
+
+static u32 percent(u32 numerator, u32 denominator)
+{
+	/* If not divide 1000, "numerator * 100" will have data overflow. */
+	numerator /= 1000;
+	denominator /= 1000;
+
+	return DIV_ROUND_UP(numerator * 100, denominator);
+}
+
+static u32 svs_readl_relaxed(struct svs_platform *svsp, enum svs_reg_index rg_i)
+{
+	return readl_relaxed(svsp->base + svsp->regs[rg_i]);
+}
+
+static void svs_writel_relaxed(struct svs_platform *svsp, u32 val,
+			       enum svs_reg_index rg_i)
+{
+	writel_relaxed(val, svsp->base + svsp->regs[rg_i]);
+}
+
+static void svs_switch_bank(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svs_writel_relaxed(svsp, svsb->core_sel, CORESEL);
+}
+
+static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
+				     u32 svsb_volt_base)
+{
+	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
+}
+
+static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
+{
+	int ret = -EPERM;
+	u32 i, svsb_volt, opp_volt;
+
+	mutex_lock(&svsb->lock);
+
+	/*
+	 * If svs bank is suspended, it means default opp voltages are applied.
+	 * We don't need to update opp voltage anymore.
+	 */
+	if (svsb->suspended && !force_update) {
+		dev_notice(svsb->dev, "bank is suspended\n");
+		ret = -EPERM;
+		goto unlock_mutex;
+	}
+
+	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
+	for (i = 0; i < svsb->opp_count; i++) {
+		switch (svsb->phase) {
+		case SVSB_PHASE_ERROR:
+			opp_volt = svsb->opp_dvolt[i];
+			break;
+		case SVSB_PHASE_INIT01:
+			/* do nothing */
+			goto unlock_mutex;
+		case SVSB_PHASE_INIT02:
+			svsb_volt = max(svsb->volt[i], svsb->vmin);
+			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
+							     svsb->volt_step,
+							     svsb->volt_base);
+			break;
+		default:
+			dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase);
+			ret = -EINVAL;
+			goto unlock_mutex;
+		}
+
+		opp_volt = min(opp_volt, svsb->opp_dvolt[i]);
+		ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
+						svsb->opp_dfreq[i],
+						opp_volt, opp_volt,
+						svsb->opp_dvolt[i]);
+		if (ret) {
+			dev_err(svsb->dev, "set %uuV fail: %d\n",
+				opp_volt, ret);
+			goto unlock_mutex;
+		}
+	}
+
+unlock_mutex:
+	mutex_unlock(&svsb->lock);
+
+	return ret;
+}
+
+static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
+{
+	u32 vx;
+
+	if (v0 == v1 || f0 == f1)
+		return v0;
+
+	/* *100 to have decimal fraction factor */
+	vx = (v0 * 100) - ((((v0 - v1) * 100) / (f0 - f1)) * (f0 - fx));
+
+	return DIV_ROUND_UP(vx, 100);
+}
+
+static void svs_get_bank_volts_v2(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 temp, i;
+
+	temp = svs_readl_relaxed(svsp, VOP74);
+	svsb->volt[14] = (temp >> 24) & GENMASK(7, 0);
+	svsb->volt[12] = (temp >> 16) & GENMASK(7, 0);
+	svsb->volt[10] = (temp >> 8)  & GENMASK(7, 0);
+	svsb->volt[8] = (temp & GENMASK(7, 0));
+
+	temp = svs_readl_relaxed(svsp, VOP30);
+	svsb->volt[6] = (temp >> 24) & GENMASK(7, 0);
+	svsb->volt[4] = (temp >> 16) & GENMASK(7, 0);
+	svsb->volt[2] = (temp >> 8)  & GENMASK(7, 0);
+	svsb->volt[0] = (temp & GENMASK(7, 0));
+
+	for (i = 0; i <= 12; i += 2)
+		svsb->volt[i + 1] = interpolate(svsb->freq_pct[i],
+						svsb->freq_pct[i + 2],
+						svsb->volt[i],
+						svsb->volt[i + 2],
+						svsb->freq_pct[i + 1]);
+
+	svsb->volt[15] = interpolate(svsb->freq_pct[12],
+				     svsb->freq_pct[14],
+				     svsb->volt[12],
+				     svsb->volt[14],
+				     svsb->freq_pct[15]);
+
+	for (i = 0; i < svsb->opp_count; i++)
+		svsb->volt[i] += svsb->volt_od;
+}
+
+static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svs_writel_relaxed(svsp,
+			   (svsb->freq_pct[14] << 24) |
+			   (svsb->freq_pct[12] << 16) |
+			   (svsb->freq_pct[10] << 8) |
+			   svsb->freq_pct[8],
+			   FREQPCT74);
+
+	svs_writel_relaxed(svsp,
+			   (svsb->freq_pct[6] << 24) |
+			   (svsb->freq_pct[4] << 16) |
+			   (svsb->freq_pct[2] << 8) |
+			   svsb->freq_pct[0],
+			   FREQPCT30);
+}
+
+static void svs_set_bank_phase(struct svs_platform *svsp,
+			       enum svsb_phase target_phase)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 des_char, temp_char, det_char, limit_vals;
+	u32 init2vals;
+
+	svs_switch_bank(svsp);
+
+	des_char = (svsb->bdes << 8) | svsb->mdes;
+	svs_writel_relaxed(svsp, des_char, DESCHAR);
+
+	temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed;
+	svs_writel_relaxed(svsp, temp_char, TEMPCHAR);
+
+	det_char = (svsb->dcbdet << 8) | svsb->dcmdet;
+	svs_writel_relaxed(svsp, det_char, DETCHAR);
+
+	svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG);
+	svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG);
+	svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);
+
+	svsb->set_freq_pct(svsp);
+
+	limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) |
+		     (SVSB_DTHI << 8) | SVSB_DTLO;
+	svs_writel_relaxed(svsp, limit_vals, LIMITVALS);
+
+	svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW);
+	svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG);
+	svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT);
+	svs_writel_relaxed(svsp, svsb->ctl0, CTL0);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+
+	switch (target_phase) {
+	case SVSB_PHASE_INIT01:
+		svs_writel_relaxed(svsp, svsb->vboot, VBOOT);
+		svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN);
+		svs_writel_relaxed(svsp, SVSB_EN_INIT01, SVSEN);
+		break;
+	case SVSB_PHASE_INIT02:
+		svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN);
+		init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in;
+		svs_writel_relaxed(svsp, init2vals, INIT2VALS);
+		svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN);
+		break;
+	default:
+		dev_err(svsb->dev, "requested unknown target phase: %u\n",
+			target_phase);
+		break;
+	}
+}
+
+static inline void svs_error_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n",
+		__func__, svs_readl_relaxed(svsp, CORESEL));
+	dev_err(svsb->dev, "SVSEN = 0x%08x, INTSTS = 0x%08x\n",
+		svs_readl_relaxed(svsp, SVSEN),
+		svs_readl_relaxed(svsp, INTSTS));
+	dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n",
+		svs_readl_relaxed(svsp, SMSTATE0),
+		svs_readl_relaxed(svsp, SMSTATE1));
+
+	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
+	svsb->phase = SVSB_PHASE_ERROR;
+
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+}
+
+static inline void svs_init01_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n",
+		 __func__, svs_readl_relaxed(svsp, VDESIGN74),
+		 svs_readl_relaxed(svsp, VDESIGN30),
+		 svs_readl_relaxed(svsp, DCVALUES));
+
+	svsb->phase = SVSB_PHASE_INIT01;
+	svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
+				GENMASK(15, 0)) + 1;
+	if (svsb->volt_flags & SVSB_INIT01_VOLT_IGNORE ||
+	    (svsb->dc_voffset_in & SVSB_DC_SIGNED_BIT &&
+	     svsb->volt_flags & SVSB_INIT01_VOLT_INC_ONLY))
+		svsb->dc_voffset_in = 0;
+
+	svsb->age_voffset_in = svs_readl_relaxed(svsp, AGEVALUES) &
+			       GENMASK(15, 0);
+
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
+
+	/* svs init01 clock gating */
+	svsb->core_sel &= ~SVSB_DET_CLK_EN;
+}
+
+static inline void svs_init02_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n",
+		 __func__, svs_readl_relaxed(svsp, VOP74),
+		 svs_readl_relaxed(svsp, VOP30),
+		 svs_readl_relaxed(svsp, DCVALUES));
+
+	svsb->phase = SVSB_PHASE_INIT02;
+	svsb->get_volts(svsp);
+
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
+}
+
+static irqreturn_t svs_isr(int irq, void *data)
+{
+	struct svs_platform *svsp = data;
+	struct svs_bank *svsb = NULL;
+	unsigned long flags;
+	u32 idx, int_sts, svs_en;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name);
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+
+		/* Find out which svs bank fires interrupt */
+		if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) {
+			spin_unlock_irqrestore(&svs_lock, flags);
+			continue;
+		}
+
+		svs_switch_bank(svsp);
+		int_sts = svs_readl_relaxed(svsp, INTSTS);
+		svs_en = svs_readl_relaxed(svsp, SVSEN) & SVSB_EN_MASK;
+
+		if (int_sts == SVSB_INTSTS_COMPLETE &&
+		    svs_en == SVSB_EN_INIT01)
+			svs_init01_isr_handler(svsp);
+		else if (int_sts == SVSB_INTSTS_COMPLETE &&
+			 svs_en == SVSB_EN_INIT02)
+			svs_init02_isr_handler(svsp);
+		else
+			svs_error_isr_handler(svsp);
+
+		spin_unlock_irqrestore(&svs_lock, flags);
+		break;
+	}
+
+	svs_adjust_pm_opp_volts(svsb, false);
+
+	if (svsb->phase == SVSB_PHASE_INIT01 ||
+	    svsb->phase == SVSB_PHASE_INIT02)
+		complete(&svsb->init_completion);
+
+	return IRQ_HANDLED;
+}
+
+static int svs_init01(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct pm_qos_request *cpu_qos_request;
+	unsigned long flags, time_left;
+	bool search_done;
+	int ret = 0, r;
+	u32 opp_freq, opp_vboot, buck_volt, idx, i;
+
+	cpu_qos_request = kzalloc(sizeof(*cpu_qos_request), GFP_KERNEL);
+	if (!cpu_qos_request)
+		return -ENOMEM;
+
+	/* Let CPUs leave idle-off state for initializing svs_init01. */
+	cpu_latency_qos_add_request(cpu_qos_request, 0);
+
+	 /* Svs bank init01 preparation - power enable */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		svsb->buck = devm_regulator_get_optional(svsb->opp_dev,
+							 svsb->buck_name);
+		if (IS_ERR(svsb->buck)) {
+			dev_err(svsb->dev, "cannot get \"%s-supply\"\n",
+				svsb->buck_name);
+			ret = PTR_ERR(svsb->buck);
+			goto init01_remove_cpu_qos_request;
+		}
+
+		ret = regulator_enable(svsb->buck);
+		if (ret) {
+			dev_err(svsb->dev, "%s enable fail: %d\n",
+				svsb->buck_name, ret);
+			goto init01_remove_cpu_qos_request;
+		}
+
+		/* Some buck doesn't support mode change. Show fail msg only */
+		ret = regulator_set_mode(svsb->buck, REGULATOR_MODE_FAST);
+		if (ret)
+			dev_notice(svsb->dev, "set fast mode fail: %d\n", ret);
+
+		if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
+			if (!pm_runtime_enabled(svsb->pd_dev)) {
+				pm_runtime_enable(svsb->pd_dev);
+				svsb->pm_runtime_enabled_count++;
+			}
+
+			ret = pm_runtime_get_sync(svsb->pd_dev);
+			if (ret < 0) {
+				dev_err(svsb->dev, "mtcmos on fail: %d\n", ret);
+				goto init01_remove_cpu_qos_request;
+			}
+		}
+	}
+
+	/*
+	 * Svs bank init01 preparation - vboot voltage adjustment
+	 * Sometimes two svs banks use the same buck. Therefore,
+	 * we have to set each svs bank to target voltage(vboot) first.
+	 */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		/*
+		 * Find the fastest freq that can be run at vboot and
+		 * fix to that freq until svs_init01 is done.
+		 */
+		search_done = false;
+		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
+						      svsb->volt_step,
+						      svsb->volt_base);
+
+		for (i = 0; i < svsb->opp_count; i++) {
+			opp_freq = svsb->opp_dfreq[i];
+			if (!search_done && svsb->opp_dvolt[i] <= opp_vboot) {
+				ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
+								opp_freq,
+								opp_vboot,
+								opp_vboot,
+								opp_vboot);
+				if (ret) {
+					dev_err(svsb->dev,
+						"set opp %uuV vboot fail: %d\n",
+						opp_vboot, ret);
+					goto init01_finish;
+				}
+
+				search_done = true;
+			} else {
+				ret = dev_pm_opp_disable(svsb->opp_dev,
+							 svsb->opp_dfreq[i]);
+				if (ret) {
+					dev_err(svsb->dev,
+						"opp %uHz disable fail: %d\n",
+						svsb->opp_dfreq[i], ret);
+					goto init01_finish;
+				}
+			}
+		}
+	}
+
+	/* Svs bank init01 begins */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
+						      svsb->volt_step,
+						      svsb->volt_base);
+
+		buck_volt = regulator_get_voltage(svsb->buck);
+		if (buck_volt != opp_vboot) {
+			dev_err(svsb->dev,
+				"buck voltage: %uuV, expected vboot: %uuV\n",
+				buck_volt, opp_vboot);
+			ret = -EPERM;
+			goto init01_finish;
+		}
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_INIT01);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		time_left = wait_for_completion_timeout(&svsb->init_completion,
+							msecs_to_jiffies(5000));
+		if (!time_left) {
+			dev_err(svsb->dev, "init01 completion timeout\n");
+			ret = -EBUSY;
+			goto init01_finish;
+		}
+	}
+
+init01_finish:
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		for (i = 0; i < svsb->opp_count; i++) {
+			r = dev_pm_opp_enable(svsb->opp_dev,
+					      svsb->opp_dfreq[i]);
+			if (r)
+				dev_err(svsb->dev, "opp %uHz enable fail: %d\n",
+					svsb->opp_dfreq[i], r);
+		}
+
+		if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
+			r = pm_runtime_put_sync(svsb->pd_dev);
+			if (r)
+				dev_err(svsb->dev, "mtcmos off fail: %d\n", r);
+
+			if (svsb->pm_runtime_enabled_count > 0) {
+				pm_runtime_disable(svsb->pd_dev);
+				svsb->pm_runtime_enabled_count--;
+			}
+		}
+
+		r = regulator_set_mode(svsb->buck, REGULATOR_MODE_NORMAL);
+		if (r)
+			dev_notice(svsb->dev, "set normal mode fail: %d\n", r);
+
+		r = regulator_disable(svsb->buck);
+		if (r)
+			dev_err(svsb->dev, "%s disable fail: %d\n",
+				svsb->buck_name, r);
+	}
+
+init01_remove_cpu_qos_request:
+	cpu_latency_qos_remove_request(cpu_qos_request);
+	kfree(cpu_qos_request);
+
+	return ret;
+}
+
+static int svs_init02(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	unsigned long flags, time_left;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT02))
+			continue;
+
+		reinit_completion(&svsb->init_completion);
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_INIT02);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		time_left = wait_for_completion_timeout(&svsb->init_completion,
+							msecs_to_jiffies(5000));
+		if (!time_left) {
+			dev_err(svsb->dev, "init02 completion timeout\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int svs_start(struct svs_platform *svsp)
+{
+	int ret;
+
+	ret = svs_init01(svsp);
+	if (ret)
+		return ret;
+
+	ret = svs_init02(svsp);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int svs_suspend(struct device *dev)
+{
+	struct svs_platform *svsp = dev_get_drvdata(dev);
+	struct svs_bank *svsb;
+	unsigned long flags;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		/* This might wait for svs_isr() process */
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_switch_bank(svsp);
+		svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+		svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		svsb->suspended = true;
+		svsb->phase = SVSB_PHASE_ERROR;
+		svs_adjust_pm_opp_volts(svsb, true);
+	}
+
+	clk_disable_unprepare(svsp->main_clk);
+
+	return 0;
+}
+
+static int svs_resume(struct device *dev)
+{
+	struct svs_platform *svsp = dev_get_drvdata(dev);
+	struct svs_bank *svsb;
+	int ret;
+	u32 idx;
+
+	ret = clk_prepare_enable(svsp->main_clk);
+	if (ret) {
+		dev_err(svsp->dev, "cannot enable main_clk, disable svs\n");
+		return ret;
+	}
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->suspended = false;
+	}
+
+	ret = svs_init02(svsp);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int svs_bank_resource_setup(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct dev_pm_opp *opp;
+	unsigned long freq;
+	int count, ret;
+	u32 idx, i;
+
+	dev_set_drvdata(svsp->dev, svsp);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			svsb->name = "SVSB_CPU_LITTLE";
+			break;
+		case SVSB_CPU_BIG:
+			svsb->name = "SVSB_CPU_BIG";
+			break;
+		case SVSB_CCI:
+			svsb->name = "SVSB_CCI";
+			break;
+		case SVSB_GPU:
+			svsb->name = "SVSB_GPU";
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return -EINVAL;
+		}
+
+		svsb->dev = devm_kzalloc(svsp->dev, sizeof(*svsb->dev),
+					 GFP_KERNEL);
+		if (!svsb->dev)
+			return -ENOMEM;
+
+		ret = dev_set_name(svsb->dev, "%s", svsb->name);
+		if (ret)
+			return ret;
+
+		dev_set_drvdata(svsb->dev, svsp);
+
+		ret = dev_pm_opp_of_add_table(svsb->opp_dev);
+		if (ret) {
+			dev_err(svsb->dev, "add opp table fail: %d\n", ret);
+			return ret;
+		}
+
+		mutex_init(&svsb->lock);
+		init_completion(&svsb->init_completion);
+
+		count = dev_pm_opp_get_opp_count(svsb->opp_dev);
+		if (svsb->opp_count != count) {
+			dev_err(svsb->dev,
+				"opp_count not \"%u\" but get \"%d\"?\n",
+				svsb->opp_count, count);
+			return count;
+		}
+
+		for (i = 0, freq = U32_MAX; i < svsb->opp_count; i++, freq--) {
+			opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq);
+			if (IS_ERR(opp)) {
+				dev_err(svsb->dev, "cannot find freq = %ld\n",
+					PTR_ERR(opp));
+				return PTR_ERR(opp);
+			}
+
+			svsb->opp_dfreq[i] = freq;
+			svsb->opp_dvolt[i] = dev_pm_opp_get_voltage(opp);
+			svsb->freq_pct[i] = percent(svsb->opp_dfreq[i],
+						    svsb->freq_base);
+			dev_pm_opp_put(opp);
+		}
+	}
+
+	return 0;
+}
+
+static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	u32 idx, i, ft_pgm;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse[i])
+			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+				 i, svsp->efuse[i]);
+
+	if (!svsp->efuse[2]) {
+		dev_notice(svsp->dev, "svs_efuse[2] = 0x0?\n");
+		return false;
+	}
+
+	/* Svs efuse parsing */
+	ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (ft_pgm <= 1)
+			svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 10;
+			else
+				svsb->volt_od += 2;
+			break;
+		case SVSB_CPU_BIG:
+			svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = svsp->efuse[17] & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 15;
+			else
+				svsb->volt_od += 12;
+			break;
+		case SVSB_CCI:
+			svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 10;
+			else
+				svsb->volt_od += 2;
+			break;
+		case SVSB_GPU:
+			svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = svsp->efuse[5] & GENMASK(7, 0);
+
+			if (ft_pgm >= 2) {
+				svsb->freq_base = 800000000; /* 800MHz */
+				svsb->dvt_fixed = 2;
+			}
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool svs_is_efuse_data_correct(struct svs_platform *svsp)
+{
+	struct nvmem_cell *cell;
+
+	/* Get svs efuse by nvmem */
+	cell = nvmem_cell_get(svsp->dev, "svs-calibration-data");
+	if (IS_ERR(cell)) {
+		dev_err(svsp->dev, "no \"svs-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		return false;
+	}
+
+	svsp->efuse = nvmem_cell_read(cell, &svsp->efuse_max);
+	if (IS_ERR(svsp->efuse)) {
+		dev_err(svsp->dev, "cannot read svs efuse: %ld\n",
+			PTR_ERR(svsp->efuse));
+		return false;
+	}
+
+	svsp->efuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	return svsp->efuse_parsing(svsp);
+}
+
+static struct device *svs_get_subsys_device(struct svs_platform *svsp,
+					    const char *node_name)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+
+	np = of_find_node_by_name(NULL, node_name);
+	if (!np) {
+		dev_err(svsp->dev, "cannot find %s node\n", node_name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev) {
+		of_node_put(np);
+		dev_err(svsp->dev, "cannot find pdev by %s\n", node_name);
+		return ERR_PTR(-ENXIO);
+	}
+
+	of_node_put(np);
+
+	return &pdev->dev;
+}
+
+static struct device *svs_add_device_link(struct svs_platform *svsp,
+					  const char *node_name)
+{
+	struct device *dev;
+	struct device_link *sup_link;
+
+	if (!node_name) {
+		dev_err(svsp->dev, "node name cannot be null\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	dev = svs_get_subsys_device(svsp, node_name);
+	if (IS_ERR(dev))
+		return dev;
+
+	sup_link = device_link_add(svsp->dev, dev,
+				   DL_FLAG_AUTOREMOVE_CONSUMER);
+	if (!sup_link) {
+		dev_err(svsp->dev, "sup_link is NULL\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return dev;
+}
+
+static int svs_mt8183_platform_probe(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+		case SVSB_CPU_BIG:
+			svsb->opp_dev = get_cpu_device(svsb->cpu_id);
+			break;
+		case SVSB_CCI:
+			svsb->opp_dev = svs_add_device_link(svsp, "cci");
+			break;
+		case SVSB_GPU:
+			svsb->opp_dev = svs_add_device_link(svsp, "mali");
+			svsb->pd_dev = svs_add_device_link(svsp,
+							   "mali_gpu_core2");
+			if (IS_ERR(svsb->pd_dev))
+				return PTR_ERR(svsb->pd_dev);
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return -EINVAL;
+		}
+
+		if (IS_ERR(svsb->opp_dev))
+			return PTR_ERR(svsb->opp_dev);
+	}
+
+	return 0;
+}
+
+static struct svs_bank svs_mt8183_banks[] = {
+	{
+		.sw_id			= SVSB_CPU_LITTLE,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.cpu_id			= 0,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1989000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x64,
+		.vmin			= 0x18,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0000,
+		.int_st			= BIT(0),
+		.ctl0			= 0x00010001,
+	},
+	{
+		.sw_id			= SVSB_CPU_BIG,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.cpu_id			= 4,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1989000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x58,
+		.vmin			= 0x10,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0001,
+		.int_st			= BIT(1),
+		.ctl0			= 0x00000001,
+	},
+	{
+		.sw_id			= SVSB_CCI,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1196000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x64,
+		.vmin			= 0x18,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0002,
+		.int_st			= BIT(2),
+		.ctl0			= 0x00100003,
+	},
+	{
+		.sw_id			= SVSB_GPU,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.buck_name		= "mali",
+		.volt_flags		= SVSB_INIT01_PD_REQ |
+					  SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 900000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x40,
+		.vmin			= 0x14,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x3,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0003,
+		.int_st			= BIT(3),
+		.ctl0			= 0x00050001,
+	},
+};
+
+struct svs_platform_data {
+	char *name;
+	struct svs_bank *banks;
+	bool (*efuse_parsing)(struct svs_platform *svsp);
+	unsigned long irqflags;
+	const u32 *regs;
+	u32 bank_max;
+	int (*probe)(struct svs_platform *svsp);
+};
+
+static const struct svs_platform_data svs_mt8183_platform_data = {
+	.name = "mt8183-svs",
+	.banks = svs_mt8183_banks,
+	.efuse_parsing = svs_mt8183_efuse_parsing,
+	.irqflags = IRQF_TRIGGER_LOW,
+	.regs = svs_regs_v2,
+	.bank_max = ARRAY_SIZE(svs_mt8183_banks),
+	.probe = svs_mt8183_platform_probe,
+};
+
+static const struct of_device_id svs_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-svs",
+		.data = &svs_mt8183_platform_data,
+	}, {
+		/* Sentinel */
+	},
+};
+
+static struct svs_platform *svs_platform_probe(struct platform_device *pdev)
+{
+	struct svs_platform *svsp;
+	const struct svs_platform_data *svsp_data;
+	int ret;
+
+	svsp_data = of_device_get_match_data(&pdev->dev);
+	if (!svsp_data) {
+		dev_err(&pdev->dev, "no svs platform data?\n");
+		return ERR_PTR(-EPERM);
+	}
+
+	svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL);
+	if (!svsp)
+		return ERR_PTR(-ENOMEM);
+
+	svsp->dev = &pdev->dev;
+	svsp->name = svsp_data->name;
+	svsp->banks = svsp_data->banks;
+	svsp->efuse_parsing = svsp_data->efuse_parsing;
+	svsp->regs = svsp_data->regs;
+	svsp->irqflags = svsp_data->irqflags;
+	svsp->bank_max = svsp_data->bank_max;
+	svsp->probe = svsp_data->probe;
+
+	ret = svsp->probe(svsp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return svsp;
+}
+
+static int svs_probe(struct platform_device *pdev)
+{
+	struct svs_platform *svsp;
+	unsigned int svsp_irq;
+	int ret;
+
+	svsp = svs_platform_probe(pdev);
+	if (IS_ERR(svsp)) {
+		dev_err_probe(&pdev->dev, PTR_ERR(svsp),
+			      "svs platform probe fail\n");
+		return PTR_ERR(svsp);
+	}
+
+	if (!svs_is_efuse_data_correct(svsp)) {
+		dev_notice(svsp->dev, "efuse data isn't correct\n");
+		return -EPERM;
+	}
+
+	ret = svs_bank_resource_setup(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs bank resource setup fail: %d\n", ret);
+		return ret;
+	}
+
+	svsp_irq = irq_of_parse_and_map(svsp->dev->of_node, 0);
+	ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
+					svsp->irqflags | IRQF_ONESHOT,
+					svsp->name, svsp);
+	if (ret) {
+		dev_err(svsp->dev, "register irq(%d) failed: %d\n",
+			svsp_irq, ret);
+		return ret;
+	}
+
+	svsp->main_clk = devm_clk_get(svsp->dev, "main");
+	if (IS_ERR(svsp->main_clk)) {
+		dev_err(svsp->dev, "failed to get clock: %ld\n",
+			PTR_ERR(svsp->main_clk));
+		return PTR_ERR(svsp->main_clk);
+	}
+
+	ret = clk_prepare_enable(svsp->main_clk);
+	if (ret) {
+		dev_err(svsp->dev, "cannot enable main clk: %d\n", ret);
+		return ret;
+	}
+
+	svsp->base = of_iomap(svsp->dev->of_node, 0);
+	if (IS_ERR_OR_NULL(svsp->base)) {
+		dev_err(svsp->dev, "cannot find svs register base\n");
+		ret = -EINVAL;
+		goto svs_probe_clk_disable;
+	}
+
+	ret = svs_start(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs start fail: %d\n", ret);
+		goto svs_probe_iounmap;
+	}
+
+	return 0;
+
+svs_probe_iounmap:
+	iounmap(svsp->base);
+
+svs_probe_clk_disable:
+	clk_disable_unprepare(svsp->main_clk);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(svs_pm_ops, svs_suspend, svs_resume);
+
+static struct platform_driver svs_driver = {
+	.probe	= svs_probe,
+	.driver	= {
+		.name		= "mtk-svs",
+		.pm		= &svs_pm_ops,
+		.of_match_table	= of_match_ptr(svs_of_match),
+	},
+};
+
+module_platform_driver(svs_driver);
+
+MODULE_AUTHOR("Roger Lu <roger.lu at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SVS driver");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



From narmstrong at baylibre.com  Fri Jan  7 01:57:53 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 7 Jan 2022 10:57:53 +0100
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
 <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
Message-ID: <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>

Hi,

On 07/01/2022 05:04, Liang Yang wrote:
> Hi Jerome,
> 
> On 2022/1/6 16:16, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>>
>>
>> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
>>
>>> Because EMMC and NAND have the same control clock register, so we
>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>
>>> ????sd_emmc_c_clkc: mmc at 7000 {
>>> ??????? compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>> ??????? reg = <0x0 0x7000 0x0 0x800>;
>>> ????};
>>>
>>> ????nand-controller at 7800 {
>>> ??????? ......
>>>
>>> ??????? clocks = <&clkc CLKID_SD_EMMC_C>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>> ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>> ??????? clock-names = "core", "device", "rx", "tx";
>>> ??????? amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>
>>> ??????? ......
>>> ????}
>>>
>>> but in fact, above implementation is rejected. so now registering
>>> a nand_divider.
>>
>> Can you give a bit of context ? a link to the discussion rejecting this
>>
> Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him to clarify it.
>> As far as remember, things were getting done for A1 and stopped before
>> clock part was finished. I'm saying the change is wrong, just that a
>> discussion is needed before a decision is made.
>>
> ok.
> previous discussion in this link:
> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
> it never go on since v6.

Looking at the serie I don't see any major blockers, if you're willing to take ownership
of this patchset and send a v6 with all issues/comments addressed, it would be easier than
restarting the whole design discussion

Neil

> 
>>>
>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>> ---
>>> ? drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>> ? 1 file changed, 49 insertions(+), 39 deletions(-)
>>>
>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>> index ac3be92872d0..4472363059c2 100644
>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>> @@ -2,7 +2,7 @@
>>> ? /*
>>> ?? * Amlogic Meson Nand Flash Controller Driver
>>> ?? *
>>> - * Copyright (c) 2018 Amlogic, inc.
>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>> ?? * Author: Liang Yang <liang.yang at amlogic.com>
>>> ?? */
>>> ? @@ -10,6 +10,7 @@
>>> ? #include <linux/dma-mapping.h>
>>> ? #include <linux/interrupt.h>
>>> ? #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>> ? #include <linux/mtd/rawnand.h>
>>> ? #include <linux/mtd/mtd.h>
>>> ? #include <linux/mfd/syscon.h>
>>> @@ -55,6 +56,7 @@
>>> ? #define NFC_REG_VER??????? 0x38
>>> ? ? #define NFC_RB_IRQ_EN??????? BIT(21)
>>> +#define NFC_CMD_FIFO_RESET??? BIT(31)
>>> ? ? #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)??? \
>>> ????? (??????????????????????????????? \
>>> @@ -104,6 +106,9 @@
>>> ? ? #define PER_INFO_BYTE??????? 8
>>> ? +#define CLK_DIV_SHIFT??????? 0
>>> +#define CLK_DIV_WIDTH??????? 6
>>> +
>>> ? struct meson_nfc_nand_chip {
>>> ????? struct list_head node;
>>> ????? struct nand_chip nand;
>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>> ????? struct nand_controller controller;
>>> ????? struct clk *core_clk;
>>> ????? struct clk *device_clk;
>>> -??? struct clk *phase_tx;
>>> -??? struct clk *phase_rx;
>>
>> I would have been nice to explain why these clock are no longer
>> required, in the change description maybe ?
> 
> i got the reply from our vlsi members that rx and tx doesn't make sense to meson NFC timing. so previous commit about this should be wrong.
>>
>>> +??? struct clk *nand_clk;
>>> +??? struct clk_divider nand_divider;
>>> ? ????? unsigned long clk_rate;
>>> ????? u32 bus_timing;
>>> ? ????? struct device *dev;
>>> ????? void __iomem *reg_base;
>>> -??? struct regmap *reg_clk;
>>> +??? void __iomem *reg_clk;
>>> ????? struct completion completion;
>>> ????? struct list_head chips;
>>> ????? const struct meson_nfc_data *data;
>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>> ????? cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>> ????????? | nfc->param.chip_select | nfc->timing.tbers_max;
>>> ????? writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>> -
>>> +??? meson_nfc_drain_cmd(nfc);
>>
>> is this clock related ?
> ok, i will split it in another patch.
>>
>>> ????? ret = wait_for_completion_timeout(&nfc->completion,
>>> ??????????????????????? msecs_to_jiffies(timeout_ms));
>>> ????? if (ret == 0)
>>> ????????? ret = -1;
>>> ? +??? /* reset command fifo to avoid lock */
>>> +??? writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>
>> Again, not seem to be clock related - does not belong in this patch
> ok, i will split it in another patch.
>>
>>> ????? return ret;
>>> ? }
>>> ? @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>> ? static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ? {
>>> ????? int ret;
>>> +??? struct clk_init_data init = {0};
>>> +??? const char *fix_div2_pll_name[1];
>>> ? -??? /* request core clock */
>>
>> Why is the comment bothering you ?
>>
>>> ????? nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>> ????? if (IS_ERR(nfc->core_clk)) {
>>> ????????? dev_err(nfc->dev, "failed to get core clock\n");
>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ????????? return PTR_ERR(nfc->device_clk);
>>> ????? }
>>> ? -??? nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>> -??? if (IS_ERR(nfc->phase_tx)) {
>>> -??????? dev_err(nfc->dev, "failed to get TX clk\n");
>>> -??????? return PTR_ERR(nfc->phase_tx);
>>> -??? }
>>> -
>>> -??? nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>> -??? if (IS_ERR(nfc->phase_rx)) {
>>> -??????? dev_err(nfc->dev, "failed to get RX clk\n");
>>> -??????? return PTR_ERR(nfc->phase_rx);
>>> -??? }
>>> +??? init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>> +??? init.ops = &clk_divider_ops;
>>> +??? fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>
>> You should be using "fw_name" so CCF looks a DT directly, instead of this
> ok
>>
>>> +??? init.parent_names = fix_div2_pll_name;
>>> +??? init.num_parents = 1;
>>> +??? nfc->nand_divider.reg = nfc->reg_clk;
>>> +??? nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>> +??? nfc->nand_divider.width = CLK_DIV_WIDTH;
>>> +??? nfc->nand_divider.hw.init = &init;
>>> +??? nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>> +????????????????? CLK_DIVIDER_ROUND_CLOSEST |
>>> +??????????????????????? CLK_DIVIDER_ALLOW_ZERO;
>>> +
>>> +??? nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>> +??? if (IS_ERR(nfc->nand_clk))
>>> +??????? return PTR_ERR(nfc->nand_clk);
>>> ? ????? /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>> -??? regmap_update_bits(nfc->reg_clk,
>>> -?????????????? 0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>> +??? writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>> ? ????? ret = clk_prepare_enable(nfc->core_clk);
>>> ????? if (ret) {
>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ????????? goto err_device_clk;
>>> ????? }
>>> ? -??? ret = clk_prepare_enable(nfc->phase_tx);
>>> +??? ret = clk_prepare_enable(nfc->nand_clk);
>>> ????? if (ret) {
>>> -??????? dev_err(nfc->dev, "failed to enable TX clock\n");
>>> -??????? goto err_phase_tx;
>>> -??? }
>>> -
>>> -??? ret = clk_prepare_enable(nfc->phase_rx);
>>> -??? if (ret) {
>>> -??????? dev_err(nfc->dev, "failed to enable RX clock\n");
>>> -??????? goto err_phase_rx;
>>> +??????? dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>> +??????? goto err_nand_clk;
>>> ????? }
>>> ? ????? ret = clk_set_rate(nfc->device_clk, 24000000);
>>> ????? if (ret)
>>> -??????? goto err_disable_rx;
>>> +??????? goto err_disable_clk;
>>> ? ????? return 0;
>>> ? -err_disable_rx:
>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>> -err_phase_rx:
>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>> -err_phase_tx:
>>> +err_disable_clk:
>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>> +err_nand_clk:
>>> ????? clk_disable_unprepare(nfc->device_clk);
>>> ? err_device_clk:
>>> ????? clk_disable_unprepare(nfc->core_clk);
>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>> ? ? static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>> ? {
>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>> ????? clk_disable_unprepare(nfc->device_clk);
>>> ????? clk_disable_unprepare(nfc->core_clk);
>>> ? }
>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>> ????? struct device *dev = &pdev->dev;
>>> ????? struct meson_nfc *nfc;
>>> ????? struct resource *res;
>>> +??? u32 ext_clk_reg;
>>> ????? int ret, irq;
>>> ? ????? nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>> ????? if (IS_ERR(nfc->reg_base))
>>> ????????? return PTR_ERR(nfc->reg_base);
>>> ? -??? nfc->reg_clk =
>>> -??????? syscon_regmap_lookup_by_phandle(dev->of_node,
>>> -??????????????????????? "amlogic,mmc-syscon");
>>> +??? ret = of_property_read_u32(pdev->dev.of_node,
>>> +?????????????????? "sd_emmc_c_clkc",
>>> +?????????????????? &ext_clk_reg);
>>> +??? if (ret) {
>>> +??????? dev_err(dev, "failed to get NAND external clock register\n");
>>> +??????? return ret;
>>> +??? }
>>> +
>>> +??? nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>
>> That's how you should get a register region.
>> If you want an example of a device claiming several region on amlogic,
>> have a look at the pinctrl driver.
> ok
>>
>>> ????? if (IS_ERR(nfc->reg_clk)) {
>>> ????????? dev_err(dev, "Failed to lookup clock base\n");
>>> ????????? return PTR_ERR(nfc->reg_clk);
>>
>> .



From ardb at kernel.org  Fri Jan  7 02:00:57 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 7 Jan 2022 11:00:57 +0100
Subject: [RFT PATCH] ARM: suspend: switch to swapper_pg_dir before using
 the vmap'ed stack
In-Reply-To: <CAMuHMdXLSFHiQPQeb5Z1yhi0L_2Pz7x4K_GtEVJTmLSkM8o4Vw@mail.gmail.com>
References: <20220106192645.3913934-1-ardb@kernel.org>
 <CAMuHMdXLSFHiQPQeb5Z1yhi0L_2Pz7x4K_GtEVJTmLSkM8o4Vw@mail.gmail.com>
Message-ID: <CAMj1kXEO_4cXpvi6xa17d1qN8EBqg2MC5c7GwJetgWEjGxpx7Q@mail.gmail.com>

On Fri, 7 Jan 2022 at 10:15, Geert Uytterhoeven <geert at linux-m68k.org> wrote:
>
> Hi Ard,
>
> On Thu, Jan 6, 2022 at 8:27 PM Ard Biesheuvel <ardb at kernel.org> wrote:
> > The resume from suspend code switches to the ID map so it can enable the
> > MMU. On !LPAE configurations, the ID map carries its own copy of the
> > kernel VA range, but this is not kept in sync with swapper_pg_dir, and
> > so it may lack the mapping of the kernel mode stack if CONFIG_VMAP_STACK
> > is enabled.
> >
> > So let's switch to swapper_pg_dir right after re-enabling the MMU on
> > such configurations. This avoids a crash on resume observed on various
> > platforms [0].
> >
> > [0] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-8-ardb at kernel.org/
> >
> > Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> > Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> > Cc: Jon Hunter <jonathanh at nvidia.com>
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
>
> Thanks for your patch!
>
> This fixes s2ram on r8a7791/koelsch (dual Cortex-A15) with
> shmobile_defconfig.
> S2ram on sh73a0/kzm9g (dual Cortex-A9) works as before.
>
> Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>
>

Thanks Geert.

> > ---
> > Please test with the Kconfig patch [9177/1] reverted.
> >
> >  arch/arm/kernel/sleep.S | 7 +++++++
> >  1 file changed, 7 insertions(+)
> >
> > diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> > index b062b3738bc6..6217ef90feb0 100644
> > --- a/arch/arm/kernel/sleep.S
> > +++ b/arch/arm/kernel/sleep.S
> > @@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
> >  ENDPROC(cpu_resume_mmu)
> >         .popsection
> >  cpu_resume_after_mmu:
> > +#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
> > +       @ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
> > +       @ as the ID map does not cover the vmalloc region.
> > +       mrc     p15, 0, ip, c2, c0, 1   @ read TTBR1
> > +       mcr     p15, 0, ip, c2, c0, 0   @ set TTBR0
> > +       isb
> > +#endif
> >         bl      cpu_init                @ restore the und/abt/irq banked regs
> >         mov     r0, #0                  @ return zero on success
> >         ldmfd   sp!, {r4 - r11, pc}
>
> Gr{oetje,eeting}s,
>
>                         Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds


From lorenzo.pieralisi at arm.com  Fri Jan  7 02:04:09 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri,  7 Jan 2022 10:04:09 +0000
Subject: [PATCH v11 0/7] PCI: brcmstb: root port turns on sub-device power
In-Reply-To: <20220106160332.2143-1-jim2101024@gmail.com>
References: <20220106160332.2143-1-jim2101024@gmail.com>
Message-ID: <164154982643.27548.5471667773667990055.b4-ty@arm.com>

On Thu, 6 Jan 2022 11:03:23 -0500, Jim Quinlan wrote:
> v11 -- Only one commit has changed from v10: "PCI: brcmstb: Add mechanism
>        to turn on subdev regulators". Lorenzo requested that this commit's
>        code be moved from pci/pci.h and pci/bus.c to
>        pci/controller/pcie-brcmstb.c as a stopgap measure until we figure
>        out a better way of offering this feature for all.  This will most
>        likely involve Pali's upcoming changes to refactor PCI host probe
>        code.
> 
> [...]

Applied to pci/brcmstb, thanks!

[1/7] PCI: brcmstb: Fix function return value handling
      https://git.kernel.org/lpieralisi/pci/c/ec16b36f89
[2/7] dt-bindings: PCI: Correct brcmstb interrupts, interrupt-map.
      https://git.kernel.org/lpieralisi/pci/c/7d0ad0c8cc
[3/7] dt-bindings: PCI: Add bindings for Brcmstb EP voltage regulators
      https://git.kernel.org/lpieralisi/pci/c/9a617ffe0d
[4/7] PCI: brcmstb: Split brcm_pcie_setup() into two funcs
      https://git.kernel.org/lpieralisi/pci/c/2d8bb00647
[5/7] PCI: brcmstb: Add mechanism to turn on subdev regulators
      https://git.kernel.org/lpieralisi/pci/c/c2c8468565
[6/7] PCI: brcmstb: Add control of subdevice voltage regulators
      https://git.kernel.org/lpieralisi/pci/c/31d8fedc28
[7/7] PCI: brcmstb: Do not turn off WOL regulators on suspend
      https://git.kernel.org/lpieralisi/pci/c/d25f7bee89

Thanks,
Lorenzo


From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:17 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:17 +0800
Subject: [PATCH v14 04/12] dt-bindings: display: mediatek: dsc: add yaml for
 mt8195 SoC binding
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-5-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,dsc.yaml        | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..1ec083eff824
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments
+      defined in this property, such as phandle of gce, subsys id,
+      register offset and size.
+      Each subsys id is mapping to a base address of display function blocks
+      register which is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:13 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:13 +0800
Subject: [PATCH v14 00/12] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20220107101425.6917-1-jason-jh.lin@mediatek.com>

Change in v14:
- rebase on mediatek-drm-next-5.17
- rebase on "Add mmsys and mutex support for MDP" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=602528
- rebase on "media: mediatek: support mdp3 on mt8183 platform" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=602834

Change in v13:
- remove dts patch
- rebase on kernel-5.16-rc1
- rebase on mediatek-drm-next

Change in v12:
- add clock-names property to merge yaml
- using BIT(nr) macro to define the settings of mmsys routing table
- fix clk_get and clk_prepare_enable error handling issue

Change in v11:
- rebase on kernel-5.15-rc1
- change mbox label to gce0 for dts node of vdosys0
- change ovl compatibale to mt8192 to set smi_id_en=true in driver data
- move common module from display folder to common folder,
  such as AAL, COCLOR, CCORR and MUTEX

Change in v10:
- rebase on "drm/mediatek: add support for mediatek SOC MT8192" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489
- rebase on "soc: mediatek: mmsys: add mt8192 mmsys support" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=524857
- fix some typo and "mediatek" start with capital in every dt-bindings
- move mutex yaml from dfisplay folder to soc folder
- separate merge additional propoerties to an individual dt-bindings patch

Change in v9:
- separate power and gce properties of mmsys into another dt-binding patch
- rebase on "Separate aal module" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
- keep mtk_ddp_clk_enable/disable in the same place
- change mtk_dsc_start config register to mtk_drm_ddp_write_mask
- remove the 0 setting of merge fifo config function
- add CCORR driver data for mt8195

Change in v8:
- add DP_INTF0 mux into mmsys routing table
- add DP_INTF0 mutex mod and enum into add/remove comp function
- remove bypass DSC enum in mtk_ddp_comp_init

Change in v7:
- add dt=binding of mmsys and disp path into this series
- separate th modidfication of alphabetic order, remove unused define and
  rename the define of register offset to individual patch
- add comment for MERGE ultra and preultra setting

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as
  the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (12):
  dt-bindings: arm: mediatek: mmsys: add power and gce properties
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: display: mediatek: disp: split each block to individual
    yaml
  dt-bindings: display: mediatek: dsc: add yaml for mt8195 SoC binding
  dt-bindings: display: mediatek: merge: add additional prop for mt8195
  dt-bindings: display: mediatek: add mt8195 SoC binding for vdosys0
  dt-bindings: arm: mediatek: move out common module from display folder
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |  32 ++-
 .../display/mediatek/mediatek,disp.txt        | 219 ----------------
 .../display/mediatek/mediatek,dither.yaml     |  76 ++++++
 .../display/mediatek/mediatek,dsc.yaml        |  71 +++++
 .../display/mediatek/mediatek,gamma.yaml      |  77 ++++++
 .../display/mediatek/mediatek,merge.yaml      | 106 ++++++++
 .../display/mediatek/mediatek,od.yaml         |  53 ++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  88 +++++++
 .../display/mediatek/mediatek,ovl.yaml        | 103 ++++++++
 .../display/mediatek/mediatek,postmask.yaml   |  69 +++++
 .../display/mediatek/mediatek,rdma.yaml       | 117 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  58 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  61 +++++
 .../bindings/soc/mediatek/mediatek,aal.yaml   |  72 +++++
 .../bindings/soc/mediatek/mediatek,ccorr.yaml |  46 +++-
 .../bindings/soc/mediatek/mediatek,color.yaml |  81 ++++++
 .../bindings/soc/mediatek/mediatek,mutex.yaml |  77 ++++++
 .../bindings/soc/mediatek/mediatek,wdma.yaml  |  47 +++-
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 246 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  63 +++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  32 ++-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 220 ++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              |  95 ++++++-
 include/linux/soc/mediatek/mtk-mmsys.h        |   9 +
 30 files changed, 1914 insertions(+), 233 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:19 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:19 +0800
Subject: [PATCH v14 06/12] dt-bindings: display: mediatek: add mt8195 SoC
 binding for vdosys0
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-7-jason-jh.lin@mediatek.com>

Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
MUTEX, OVL and RDMA yaml schema for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../devicetree/bindings/display/mediatek/mediatek,aal.yaml   | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,ccorr.yaml | 5 +++++
 .../devicetree/bindings/display/mediatek/mediatek,color.yaml | 1 +
 .../bindings/display/mediatek/mediatek,dither.yaml           | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,gamma.yaml | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml | 2 ++
 .../devicetree/bindings/display/mediatek/mediatek,mutex.yaml | 5 +++--
 .../devicetree/bindings/display/mediatek/mediatek,ovl.yaml   | 5 +++++
 .../devicetree/bindings/display/mediatek/mediatek,rdma.yaml  | 2 ++
 9 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index 044331f5aacb..225f9dd726d2 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -28,6 +28,7 @@ properties:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
               - mediatek,mt8192-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index ea45b40edee7..6894b6999412 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -25,6 +25,11 @@ properties:
           - const: mediatek,mt8183-disp-ccorr
       - items:
           - const: mediatek,mt8192-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8192-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 13628f346718..bc83155b3b4c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -38,6 +38,7 @@ properties:
           - enum:
               - mediatek,mt8183-disp-color
               - mediatek,mt8192-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 2c05e3019c75..9d89297f5f1d 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -27,6 +27,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8192-disp-dither
+              - mediatek,mt8195-disp-dither
           - enum:
               - mediatek,mt8183-disp-dither
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index 89ccb8dbadd7..247baad147b3 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -28,6 +28,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8192-disp-gamma
+              - mediatek,mt8195-disp-gamma
           - enum:
               - mediatek,mt8183-disp-gamma
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index fae106cf1753..60b21ef5549b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -23,6 +23,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index 90f11e12a55e..6eca525eced0 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display mutex
+title: Mediatek mutex
 
 maintainers:
   - Chun-Kuang Hu <chunkuang.hu at kernel.org>
@@ -36,7 +36,8 @@ properties:
           - const: mediatek,mt8183-disp-mutex
       - items:
           - const: mediatek,mt8192-disp-mutex
-
+      - items:
+          - const: mediatek,mt8195-disp-mutex
   reg:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 8e4a62cb9c81..e71f79bc2dee 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -35,6 +35,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index a3c5f4c9fbcd..8ef821641672 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -29,6 +29,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:22 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:22 +0800
Subject: [PATCH v14 09/12] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-10-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
This patch is base on [1]
[1] Add mmsys and mutex support for MDP
- https://patchwork.kernel.org/project/linux-mediatek/cover/20220104091712.25670-1-moudy.ho at mediatek.com/
---
 drivers/soc/mediatek/mtk-mutex.c | 95 +++++++++++++++++++++++++++++++-
 1 file changed, 92 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 615c42260a50..89daab7e6863 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -21,6 +21,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -83,6 +86,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -119,9 +152,21 @@
 #define MT8167_MUTEX_SOF_DPI1			3
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
 
 #define MT8183_MUTEX_MDP_START			5
 #define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
@@ -148,6 +193,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -274,7 +322,23 @@ static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -284,7 +348,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -292,7 +356,7 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
@@ -306,6 +370,18 @@ static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
 	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
 };
 
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -355,6 +431,13 @@ static const struct mtk_mutex_data mt8192_mutex_driver_data = {
 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -442,6 +525,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI1:
 		sof_id = MUTEX_SOF_DPI1;
 		break;
+	case DDP_COMPONENT_DP_INTF0:
+		sof_id = MUTEX_SOF_DP_INTF0;
+		break;
 	default:
 		if (mtx->data->mutex_mod[id] < 32) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -481,6 +567,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DSI3:
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
+	case DDP_COMPONENT_DP_INTF0:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
@@ -678,6 +765,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8183_mutex_driver_data},
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = &mt8192_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:21 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:21 +0800
Subject: [PATCH v14 08/12] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-9-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
The vdosys1 impelmentation patch [1] will be dependened on this patch.
[1] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
- https://patchwork.kernel.org/project/linux-mediatek/patch/20211208024426.15595-6-nancy.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 220 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  11 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   9 +
 3 files changed, 240 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..e04cabdfa2dc
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+/*
+ * MT8195_VDO0_OVL_MOUT[2:0]: DISP_OVL0
+ *   BIT(0) : DISP_RDMA0
+ *   BIT(1) : DISP_WDMA0
+ *   BIT(2): DISP_OVL1
+ */
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+/*
+ * MT8195_VDO0_OVL_MOUT[6:4]: DISP_OVL1
+ *   BIT(0) : DISP_RDMA1
+ *   BIT(1) : DISP_WDMA1
+ *   BIT(2): DISP_OVL0
+ */
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+/*
+ * MT8195_VDO0_SEL_IN[1:0]: VPP_MERGE
+ *   0 : DSC_WRAP0_OUT
+ *   1 : DISP_DITHER1
+ *   2: VDO1_VIRTUAL0
+ */
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		0
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		BIT(0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		BIT(1)
+/*
+ * MT8195_VDO0_SEL_IN[4:4]: DSC_WRAP0_IN
+ *   0: DISP_DITHER0
+ *   1: VPP_MERGE
+ */
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		0
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		BIT(4)
+/*
+ * MT8195_VDO0_SEL_IN[5:5]: DSC_WRAP1_IN
+ *   0: DISP_DITHER1
+ *   1: VPP_MERGE
+ */
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		0
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		BIT(5)
+/*
+ * MT8195_VDO0_SEL_IN[8:8]: SINA_VIRTUAL0
+ *   0: VPP_MERGE
+ *   1: DSC_WRAP1_OUT
+ */
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		0
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		BIT(8)
+/*
+ * MT8195_VDO0_SEL_IN[9:9]: SINB_VIRTUAL0
+ *   0: DSC_WRAP0_OUT
+ */
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		0
+/*
+ * MT8195_VDO0_SEL_IN[13:12]: DP_INTF0
+ *   0 : DSC_WRAP1_OUT
+ *   1 : VPP_MERGE
+ *   2: VDO1_VIRTUAL0
+ */
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		0
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			BIT(12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		BIT(13)
+/*
+ * MT8195_VDO0_SEL_IN[16:16]: DSI0
+ *   0 : DSC_WRAP0_OUT
+ *   1 : DISP_DITHER0
+ */
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			0
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			BIT(16)
+/*
+ * MT8195_VDO0_SEL_IN[17:17]: DSI1
+ *   0 : DSC_WRAP1_OUT
+ *   1 : VPP_MERGE
+ */
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			0
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			BIT(17)
+/*
+ * MT8195_VDO0_SEL_IN[20:20]: DISP_WDMA1
+ *   0 : DISP_OVL1
+ *   1 : VPP_MERGE
+ */
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			0
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			BIT(20)
+/*
+ * MT8195_VDO0_SEL_IN[21:21]: DSC_WRAP1_OUT
+ *   0 : DSC_WRAP1_IN
+ *   1 : DITHER1
+ */
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		BIT(21)
+/*
+ * MT8195_VDO0_SEL_IN[22:22]: DISP_WDMA0
+ *   0 : DISP_OVL0
+ */
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			0
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+/*
+ * MT8195_VDO0_SOUT[0:0]: DISP_DITHER0
+ *   0 : DSC_WRAP0_IN
+ *   1 : DSI0
+ */
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		0
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			BIT(0)
+/*
+ * MT8195_VDO0_SOUT[1:1]: DISP_DITHER1
+ *   0 : DSC_WRAP1_IN
+ *   1 : VPP_MERGE
+ *   2 : DSC_WRAP1_OUT
+ */
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		0
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			BIT(1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		BIT(2)
+/*
+ * MT8195_VDO0_SOUT[4:4]: VDO1_VIRTUAL0
+ *   0 : VPP_MERGE
+ *   1 : DP_INTF0
+ */
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			0
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			BIT(4)
+/*
+ * MT8195_VDO0_SOUT[10:8]: VPP_MERGE
+ *   0 : DSI1
+ *   1 : DP_INTF0
+ *   2 : SINA_VIRTUAL0
+ *   3 : DISP_WDMA1
+ *   4 : DSC_WRAP0_IN
+ */
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				0
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			BIT(8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			BIT(9)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(BIT(9) | BIT(8))
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			BIT(10)
+/*
+ * MT8195_VDO0_SOUT[11:11]: VPP_MERGE
+ *  0 : DSC_WRAP1_IN
+ */
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			0
+/*
+ * MT8195_VDO0_SOUT[13:12]: DSC_WRAP0_OUT
+ *  0 : DSI0
+ *  1 : SINB_VIRTUAL0
+ *  2 : VPP_MERGE
+ */
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			0
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		BIT(12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			BIT(13)
+/*
+ * MT8195_VDO0_SOUT[17:16]: DSC_WRAP1_OUT
+ *  0 : DSI1
+ *  1 : DP_INTF0
+ *  2 : SINA_VIRTUAL0
+ *  3 : VPP_MERGE
+ */
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			0
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			BIT(16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		BIT(17)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(BIT(17) | BIT(16))
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
+		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,
+		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
+		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
+		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
+		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
+		MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
+		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 5f79c7e039ad..5865d268c5b4 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -18,6 +18,7 @@
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
 #include "mt8192-mmsys.h"
+#include "mt8195-mmsys.h"
 #include "mt8365-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
@@ -66,6 +67,12 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.clk_driver = "clk-mt8365-mm",
 	.routes = mt8365_mmsys_routing_table,
@@ -391,6 +398,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8192-mmsys",
 		.data = &mt8192_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 45e77d1cd6c1..c0ba22ad7229 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -23,13 +23,22 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
 	DDP_COMPONENT_DSI3,
 	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
 	DDP_COMPONENT_OD0,
 	DDP_COMPONENT_OD1,
 	DDP_COMPONENT_OVL0,
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:16 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:16 +0800
Subject: [PATCH v14 03/12] dt-bindings: display: mediatek: disp: split each
 block to individual yaml
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-4-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,aal.yaml        |  76 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  71 ++++++
 .../display/mediatek/mediatek,color.yaml      |  85 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  75 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  66 ++++++
 .../display/mediatek/mediatek,mutex.yaml      |  82 +++++++
 .../display/mediatek/mediatek,od.yaml         |  53 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  88 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  98 ++++++++
 .../display/mediatek/mediatek,postmask.yaml   |  69 ++++++
 .../display/mediatek/mediatek,rdma.yaml       | 115 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  58 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  61 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 16 files changed, 1159 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..044331f5aacb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display adaptive ambient light processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+              - mediatek,mt8192-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..ea45b40edee7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - const: mediatek,mt8192-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..13628f346718
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+              - mediatek,mt8192-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index 78044c340e20..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..2c05e3019c75
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display dither processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..89ccb8dbadd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display gamma correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display gamma correction, namely GAMMA, provides a nonlinear
+  operation used to adjust luminance in??display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..7aa6974d509d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display merge
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display merge, namely MERGE, is used to merge two slice-per-line
+  inputs into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..90f11e12a55e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display mutex
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek mutex, namely MUTEX, is used to send the triggers signals called
+  Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
+  data path or MDP data path.
+  In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
+  the shadow register.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8192-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal
+      to gce. The event id is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..7519db315217
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overdirve
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OD Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..611a2dbdefa4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay 2 layer
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overlay 2 layer, namely OVL-2L, provides 2 more layer
+  for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+      - items:
+          - const: mediatek,mt8192-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..8e4a62cb9c81
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overlay, namely OVL, can do alpha blending from
+  the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - const: mediatek,mt8192-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
new file mode 100644
index 000000000000..6ac1da2e8871
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,postmask.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display postmask
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display postmask, namely POSTMASK, provides round corner pattern
+  generation.
+  POSTMASK device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8192-disp-postmask
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: POSTMASK Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    postmask0: postmask at 1400d000 {
+        compatible = "mediatek,mt8192-disp-postmask";
+        reg = <0 0x1400d000 0 0x1000>;
+        interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&scpsys MT8192_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_POSTMASK0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..a3c5f4c9fbcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,115 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Read Direct Memory Access
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek Read Direct Memory Access(RDMA) component used to read the
+  data into DMA. It provides real time data to the back-end panel
+  driver, such as DSI, DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-rdma
+          - enum:
+              - mediatek,mt8183-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..4f08e89c1067
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display split
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display split, namely SPLIT, is used to split stream to two
+  encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..6e8748529e73
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display UFOe
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power
+  consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..aaf5649b6413
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Write Direct Memory Access
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek Write Direct Memory Access(WDMA) component used to write
+  the data into DMA.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:24 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:24 +0800
Subject: [PATCH v14 11/12] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-12-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 246 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 7 files changed, 276 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..a38e88e82d12 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -4,6 +4,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 86c3068894b1..a33b13fe2b6e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -55,6 +55,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..45face638153
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN				1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE				0
+#define FLD_SWAP_MODE				GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE		6
+#define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN				BIT(0)
+#define PREULTRA_EN				BIT(4)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE				3
+#define FLD_BUFFER_MODE				GENMASK(1, 0)
+/*
+ * For the ultra and preultra settings, 6us ~ 9us is experience value
+ * and the maximum frequency of mmsys clock is 594MHz.
+ */
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 594M pixel/sec */
+#define ULTRA_TH_LOW				(6 * 594)
+/* 8 us, 594M pixel/sec */
+#define ULTRA_TH_HIGH				(8 * 594)
+#define FLD_ULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH			GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 594M pixel/sec */
+#define PREULTRA_TH_LOW				(8 * 594)
+/* 9 us, 594M pixel/sec */
+#define PREULTRA_TH_HIGH			(9 * 594)
+#define FLD_PREULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH			GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem			*regs;
+	struct clk			*clk;
+	struct clk			*async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_ddp_write(cmdq_pkt, ULTRA_EN | PREULTRA_EN,
+		      &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36);
+
+	mtk_ddp_write_mask(cmdq_pkt, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(cmdq_pkt, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(cmdq_pkt, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, cmdq_pkt);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(cmdq_pkt, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(cmdq_pkt, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "merge clk prepare enable failed\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(priv->async_clk);
+	if (ret) {
+		/* should clean up the state of priv->clk */
+		clk_disable_unprepare(priv->clk);
+
+		dev_err(dev, "async clk prepare enable failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->async_clk);
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = devm_clk_get_optional(dev, "merge_async");
+	if (IS_ERR(priv->async_clk)) {
+		dev_err(dev, "failed to get merge async clock\n");
+		return PTR_ERR(priv->async_clk);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 90b289b5f9a4..26d197da41c0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -328,6 +328,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -385,6 +393,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -421,6 +430,12 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]		= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]		= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]		= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]		= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]		= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]		= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]		= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]		= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]		= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]		= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -555,6 +570,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 5e6ff12f16ad..221e2e3a3c8d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 56ff8c57ef8f..2f33fe8ad46b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -599,7 +599,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the AAL, CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
@@ -607,6 +607,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -708,6 +709,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 3e7d1e6fbe01..a58cebd01d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -50,6 +50,7 @@ extern struct platform_driver mtk_disp_aal_driver;
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0



From lorenzo.pieralisi at arm.com  Fri Jan  7 02:22:46 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri,  7 Jan 2022 10:22:46 +0000
Subject: [PATCH v3] PCI: mediatek: Assert PERST# for 100ms for power and
 clock to stabilize
In-Reply-To: <20211227133110.14500-1-qizhong.cheng@mediatek.com>
References: <20211227133110.14500-1-qizhong.cheng@mediatek.com>
Message-ID: <164155095225.6775.655179565397700923.b4-ty@arm.com>

On Mon, 27 Dec 2021 21:31:10 +0800, qizhong cheng wrote:
> Described in PCIe CEM specification sections 2.2 (PERST# Signal) and
> 2.2.1 (Initial Power-Up (G3 to S0)). The deassertion of PERST# should
> be delayed 100ms (TPVPERL) for the power and clock to become stable.
> 
> 

Applied to pci/mediatek, thanks!

[1/1] PCI: mediatek: Assert PERST# for 100ms for power and clock to stabilize
      https://git.kernel.org/lpieralisi/pci/c/65ace9a85f

Thanks,
Lorenzo


From geert at linux-m68k.org  Fri Jan  7 02:22:50 2022
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Fri, 7 Jan 2022 11:22:50 +0100
Subject: [PATCH v13 3/5] arm64: perf: Add userspace counter access disable
 switch
In-Reply-To: <20220104135658.GC1827@willie-the-truck>
References: <20211208201124.310740-1-robh@kernel.org>
 <20211208201124.310740-4-robh@kernel.org>
 <CAMuHMdVcDxR9sGzc5pcnORiotonERBgc6dsXZXMd6wTvLGA9iw@mail.gmail.com>
 <20220104135658.GC1827@willie-the-truck>
Message-ID: <CAMuHMdUq9rAZT5B3xUGWAhHnyg2ta_Vx8KNDWms6vbqGmrarRg@mail.gmail.com>

Hi Will,

On Tue, Jan 4, 2022 at 2:57 PM Will Deacon <will at kernel.org> wrote:
> On Tue, Dec 28, 2021 at 12:07:02PM +0100, Geert Uytterhoeven wrote:
> > On Wed, Dec 8, 2021 at 9:19 PM Rob Herring <robh at kernel.org> wrote:
> > > Like x86, some users may want to disable userspace PMU counter
> > > altogether. Add a sysctl 'perf_user_access' file to control userspace
> > > counter access. The default is '0' which is disabled. Writing '1'
> > > enables access.
> > >
> > > Note that x86 supports globally enabling user access by writing '2' to
> > > /sys/bus/event_source/devices/cpu/rdpmc. As there's not existing
> > > userspace support to worry about, this shouldn't be necessary for Arm.
> > > It could be added later if the need arises.
> >
> > Thanks for your patch, which is now commit e2012600810c9ded ("arm64:
> > perf: Add userspace counter access disable switch") in arm64/for-next/core.
> >
> > This is causing two issues on Renesas Salvator-XS with R-Car H3.
> > One during kernel boot:
> >
> >      hw perfevents: enabled with armv8_cortex_a53 PMU driver, 7
> > counters available
> >     +sysctl duplicate entry: /kernel//perf_user_access
> >     +CPU: 0 PID: 1 Comm: swapper/0 Not tainted
> > 5.16.0-rc3-arm64-renesas-00003-ge2012600810c #1420
> >     +Hardware name: Renesas Salvator-X 2nd version board based on r8a77951 (DT)
> >     +Call trace:
> >     + dump_backtrace+0x0/0x190
> >     + show_stack+0x14/0x20
> >     + dump_stack_lvl+0x88/0xb0
> >     + dump_stack+0x14/0x2c
> >     + __register_sysctl_table+0x384/0x818
> >     + register_sysctl+0x20/0x28
> >     + armv8_pmu_init.constprop.0+0x118/0x150
> >     + armv8_a57_pmu_init+0x1c/0x28
> >     + arm_pmu_device_probe+0x1b4/0x558
> >     + armv8_pmu_device_probe+0x18/0x20
> >     + platform_probe+0x64/0xd0
> >     + really_probe+0xb4/0x2f8
> >     + __driver_probe_device+0x74/0xd8
> >     + driver_probe_device+0x3c/0xe0
> >     + __driver_attach+0x80/0x110
> >     + bus_for_each_dev+0x6c/0xc0
> >     + driver_attach+0x20/0x28
> >     + bus_add_driver+0x138/0x1e0
> >     + driver_register+0x60/0x110
> >     + __platform_driver_register+0x24/0x30
> >     + armv8_pmu_driver_init+0x18/0x20
> >     + do_one_initcall+0x15c/0x31c
> >     + kernel_init_freeable+0x2f0/0x354
> >     + kernel_init+0x20/0x120
> >     + ret_from_fork+0x10/0x20
> >      hw perfevents: enabled with armv8_cortex_a57 PMU driver, 7
> > counters available
> >
> > Presumably the same entry is added twice, once for the A53 PMU,
> > and a second time for the A57 PMU?
>
> Looks like it, and perhaps that's also what is confusing systemd?
> Rob -- how come you didn't see this during your testing?
>
> Anywho, please can you try the untested diff below?

Thank you, this fixes the issue.

Tested-by: Geert Uytterhoeven <geert+renesas at glider.be>

> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -1214,6 +1214,14 @@ static struct ctl_table armv8_pmu_sysctl_table[] = {
>         { }
>  };
>
> +static void armv8_pmu_register_sysctl_table(void)
> +{
> +       static u32 tbl_registered = 0;
> +
> +       if (!cmpxchg_relaxed(&tbl_registered, 0, 1))
> +               register_sysctl("kernel", armv8_pmu_sysctl_table);
> +}
> +
>  static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
>                           int (*map_event)(struct perf_event *event),
>                           const struct attribute_group *events,
> @@ -1248,8 +1256,7 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
>         cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_CAPS] = caps ?
>                         caps : &armv8_pmuv3_caps_attr_group;
>
> -       register_sysctl("kernel", armv8_pmu_sysctl_table);
> -
> +       armv8_pmu_register_sysctl_table();
>         return 0;
>  }

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:15 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:15 +0800
Subject: [PATCH v14 02/12] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-3-jason-jh.lin@mediatek.com>

There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
Each of them is bound to a display pipeline, so add their
definition in mtk-mmsys documentation with 2 compatibles.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml        | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 474bcf9c250d..a978cdd32575 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -31,6 +31,8 @@ properties:
               - mediatek,mt8183-mmsys
               - mediatek,mt8192-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:25 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:25 +0800
Subject: [PATCH v14 12/12] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-13-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index d41a3970b944..77c952bdc88c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -357,6 +357,10 @@ static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -366,6 +370,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8183_rdma_driver_data},
 	{ .compatible = "mediatek,mt8192-disp-rdma",
 	  .data = &mt8192_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 2f33fe8ad46b..274a5bb10851 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -177,6 +177,19 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -228,6 +241,11 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -447,12 +465,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8167-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -465,6 +487,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -499,6 +523,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8192-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -535,6 +561,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8183_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8192-mmsys",
 	  .data = &mt8192_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:18 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:18 +0800
Subject: [PATCH v14 05/12] dt-bindings: display: mediatek: merge: add
 additional prop for mt8195
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-6-jason-jh.lin@mediatek.com>

add MERGE additional properties description for mt8195:
1. async clock
2. fifo setting enable
3. reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,merge.yaml      | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 7aa6974d509d..fae106cf1753 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -36,8 +36,28 @@ properties:
       Documentation/devicetree/bindings/power/power-domain.yaml for details.
 
   clocks:
+    maxItems: 2
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display
+          function blocks cross clock domain.
+
+  clock-names:
+    maxItems: 2
+    items:
+      - const: merge
+      - const: merge_async
+
+  mediatek,merge-fifo-en:
+    description:
+      The setting of merge fifo is mainly provided for the display latency
+      buffer to ensure that the back-end panel display data will not be
+      underrun, a little more data is needed in the fifo.
+      According to the merge fifo settings, when the water level is detected
+      to be insufficient, it will trigger RDMA sending ultra and preulra
+      command to SMI to speed up the data rate.
+    type: boolean
 
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
@@ -47,6 +67,11 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     maxItems: 1
 
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -64,3 +89,16 @@ examples:
         power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
+
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:20 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:20 +0800
Subject: [PATCH v14 07/12] dt-bindings: arm: mediatek: move out common module
 from display folder
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-8-jason-jh.lin@mediatek.com>

AAL, COLOR, CCORR, MUTEX, WDMA could be used by other modules,
such as MDP, so move their binding document into the common folder.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
This patch is base on [1]
[1] dt-binding: mt8183: add Mediatek MDP3 dt-bindings
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220105093758.6850-2-moudy.ho at mediatek.com/
---
 .../display/mediatek/mediatek,ccorr.yaml      | 76 ----------------
 .../display/mediatek/mediatek,wdma.yaml       | 86 -------------------
 .../mediatek/mediatek,aal.yaml                | 13 +--
 .../bindings/soc/mediatek/mediatek,ccorr.yaml | 46 ++++++++--
 .../mediatek/mediatek,color.yaml              | 15 ++--
 .../mediatek/mediatek,mutex.yaml              | 12 +--
 .../bindings/soc/mediatek/mediatek,wdma.yaml  | 47 +++++++++-
 7 files changed, 96 insertions(+), 199 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,aal.yaml (78%)
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,color.yaml (78%)
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,mutex.yaml (80%)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
deleted file mode 100644
index 6894b6999412..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Mediatek display color correction
-
-maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
-
-description: |
-  Mediatek display color correction, namely CCORR, reproduces correct color
-  on panels with different color gamut.
-  CCORR device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
-
-properties:
-  compatible:
-    oneOf:
-      - items:
-          - const: mediatek,mt8183-disp-ccorr
-      - items:
-          - const: mediatek,mt8192-disp-ccorr
-      - items:
-          - enum:
-              - mediatek,mt8195-disp-ccorr
-          - enum:
-              - mediatek,mt8192-disp-ccorr
-
-  reg:
-    maxItems: 1
-
-  interrupts:
-    maxItems: 1
-
-  power-domains:
-    description: A phandle and PM domain specifier as defined by bindings of
-      the power controller specified by phandle. See
-      Documentation/devicetree/bindings/power/power-domain.yaml for details.
-
-  clocks:
-    items:
-      - description: CCORR Clock
-
-  mediatek,gce-client-reg:
-    description: The register of client driver can be configured by gce with
-      4 arguments defined in this property, such as phandle of gce, subsys id,
-      register offset and size. Each GCE subsys id is mapping to a client
-      defined in the header include/dt-bindings/gce/<chip>-gce.h.
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    maxItems: 1
-
-required:
-  - compatible
-  - reg
-  - interrupts
-  - power-domains
-  - clocks
-
-additionalProperties: false
-
-examples:
-  - |
-
-    ccorr0: ccorr at 1400f000 {
-        compatible = "mediatek,mt8183-disp-ccorr";
-        reg = <0 0x1400f000 0 0x1000>;
-        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
-        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
-        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
-        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
-    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
deleted file mode 100644
index aaf5649b6413..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
+++ /dev/null
@@ -1,86 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Mediatek Write Direct Memory Access
-
-maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
-
-description: |
-  Mediatek Write Direct Memory Access(WDMA) component used to write
-  the data into DMA.
-  WDMA device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
-
-properties:
-  compatible:
-    oneOf:
-      - items:
-          - const: mediatek,mt8173-disp-wdma
-
-  reg:
-    maxItems: 1
-
-  interrupts:
-    maxItems: 1
-
-  power-domains:
-    description: A phandle and PM domain specifier as defined by bindings of
-      the power controller specified by phandle. See
-      Documentation/devicetree/bindings/power/power-domain.yaml for details.
-
-  clocks:
-    items:
-      - description: WDMA Clock
-
-  iommus:
-    description:
-      This property should point to the respective IOMMU block with master port as argument,
-      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
-
-  mediatek,larb:
-    description:
-      This property should contain a phandle pointing to the local arbiter devices defined in
-      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
-      It must sort according to the local arbiter index, like larb0, larb1, larb2...
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    minItems: 1
-    maxItems: 32
-
-  mediatek,gce-client-reg:
-    description: The register of client driver can be configured by gce with
-      4 arguments defined in this property, such as phandle of gce, subsys id,
-      register offset and size. Each GCE subsys id is mapping to a client
-      defined in the header include/dt-bindings/gce/<chip>-gce.h.
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    maxItems: 1
-
-required:
-  - compatible
-  - reg
-  - interrupts
-  - power-domains
-  - clocks
-  - iommus
-
-additionalProperties: false
-
-examples:
-  - |
-
-    wdma0: wdma at 14011000 {
-        compatible = "mediatek,mt8173-disp-wdma";
-        reg = <0 0x14011000 0 0x1000>;
-        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-        mediatek,larb = <&larb0>;
-        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
-    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
similarity index 78%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
index 225f9dd726d2..f9f57e073b37 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
@@ -1,22 +1,17 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,aal.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display adaptive ambient light processor
+title: Mediatek adaptive ambient light processor
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek display adaptive ambient light processor, namely AAL,
+  Mediatek adaptive ambient light processor, namely AAL,
   is responsible for backlight power saving and sunlight visibility improving.
-  AAL device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
index cf23f4f5bd69..c4db0b42cf86 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
@@ -10,17 +10,40 @@ maintainers:
   - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek color correction with 3X3 matrix.
+  Mediatek color correction, namely CCORR, reproduces correct color
+  on panels with 3X3 matrix of different color gamut.
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt8183-mdp3-ccorr
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-mdp3-ccorr
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - const: mediatek,mt8192-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8192-disp-ccorr
 
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+    minItems: 1
+
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
       4 arguments defined in this property, such as phandle of gce, subsys id,
@@ -29,8 +52,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     maxItems: 1
 
-  clocks:
-    minItems: 1
+required:
+  - compatible
+  - reg
+  - clocks
 
 additionalProperties: false
 
@@ -45,3 +70,12 @@ examples:
       mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
       clocks = <&mmsys CLK_MM_MDP_CCORR>;
     };
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
similarity index 78%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
index bc83155b3b4c..8f8b048a8407 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
@@ -1,23 +1,18 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,color.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display color processor
+title: Mediatek color processor
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek display color processor, namely COLOR, provides hue, luma and
-  saturation adjustments to get better picture quality and to have one panel
+  Mediatek color processor, namely COLOR, provides hue, luma and saturation
+  adjustments to get better picture quality and to have one panel
   resemble the other in their output characteristics.
-  COLOR device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
similarity index 80%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
index 6eca525eced0..6e1d1ea377c4 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
@@ -1,25 +1,19 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mutex.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Mediatek mutex
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
   Mediatek mutex, namely MUTEX, is used to send the triggers signals called
-  Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
-  data path or MDP data path.
+  Start Of Frame(SOF) / End Of Frame(EOF) to each sub-modules on the data path.
   In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
   the shadow register.
-  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
index 4057b5232e45..7e5d1a6a79a9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
@@ -15,13 +15,18 @@ description: |
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt8183-mdp3-wdma
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-mdp3-wdma
+      - items:
+          - const: mediatek,mt8173-disp-wdma
 
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
       4 arguments defined in this property, such as phandle of gce, subsys id,
@@ -31,14 +36,39 @@ properties:
     maxItems: 1
 
   power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
     maxItems: 1
 
   clocks:
+    items:
+      - description: WDMA Clock
     minItems: 1
 
   iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
     maxItems: 1
 
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
 additionalProperties: false
 
 examples:
@@ -56,3 +86,14 @@ examples:
       clocks = <&mmsys CLK_MM_MDP_WDMA0>;
       iommus = <&iommu>;
     };
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:14 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:14 +0800
Subject: [PATCH v14 01/12] dt-bindings: arm: mediatek: mmsys: add power and
 gce properties
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-2-jason-jh.lin@mediatek.com>

Power:
1. Add description for power-domains property.

GCE:
1. Add description for mboxes property.
2. Add description for mediatek,gce-client-reg property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,mmsys.yaml | 30 ++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 763c62323a74..474bcf9c250d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -40,6 +40,30 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mboxes:
+    description:
+      Using mailbox to communicate with GCE, it should have this
+      property and list of phandle, mailbox specifiers. See
+      Documentation/devicetree/bindings/mailbox/mtk-gce.txt for details.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments
+      defined in this property, such as phandle of gce, subsys id,
+      register offset and size.
+      Each subsys id is mapping to a base address of display function blocks
+      register which is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
   "#clock-cells":
     const: 1
 
@@ -57,7 +81,11 @@ examples:
   - |
     mmsys: syscon at 14000000 {
         compatible = "mediatek,mt8173-mmsys", "syscon";
-        reg = <0x14000000 0x1000>;
+        reg = <0 0x14000000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         #clock-cells = <1>;
         #reset-cells = <1>;
+        mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
+                 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
     };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Fri Jan  7 02:14:23 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Fri, 7 Jan 2022 18:14:23 +0800
Subject: [PATCH v14 10/12] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
Message-ID: <20220107101425.6917-11-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index b4b682bc1991..90b289b5f9a4 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -40,6 +40,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -181,6 +187,36 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* write with mask to reserve the value set in mtk_dsc_config */
+	mtk_ddp_write_mask(NULL, DSC_EN, &priv->cmdq_reg, priv->regs, DISP_REG_DSC_CON, DSC_EN);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -270,6 +306,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -339,6 +383,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -369,6 +414,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]		= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]		= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,		2, &ddp_dsi },
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 4c6a98662305..5e6ff12f16ad 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
2.18.0



From gascoar at gmail.com  Fri Jan  7 02:36:20 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Fri, 7 Jan 2022 07:36:20 -0300
Subject: [PATCH 5/6] staging: vc04_services: rename macros
 BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
In-Reply-To: <YdbzKaKQW7N04QgA@kroah.com>
References: <cover.1641414449.git.gascoar@gmail.com>
 <d450b9e22e5ab335a61591dbf0d2104031c9fc46.1641414449.git.gascoar@gmail.com>
 <YdbzKaKQW7N04QgA@kroah.com>
Message-ID: <YdgXpPS51cWgQY3a@localhost.localdomain>

On Thu, Jan 06, 2022 at 02:48:25PM +0100, Greg KH wrote:
> On Wed, Jan 05, 2022 at 05:35:47PM -0300, Gaston Gonzalez wrote:
> > In the kernel, all names related to the chip BCM2835 are always named
> > bcm2835_*. To avoid confusion, and to make things more consistent,
> > rename the macros BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
> > accordingly.
> > 
> > While at it, some realignments were made to improve readability.
> > 
> > Suggested-by: Stefan Wahren <stefan.wahren at i2se.com>
> > Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
> > ---
> >  .../vc04_services/bcm2835-camera/bcm2835-camera.c  | 14 ++++++--------
> >  1 file changed, 6 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > index aaf529f2186c..c729b1b7de71 100644
> > --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
> > @@ -33,8 +33,8 @@
> >  #include "mmal-parameters.h"
> >  #include "bcm2835-camera.h"
> >  
> > -#define BM2835_MMAL_VERSION "0.0.2"
> > -#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
> > +#define BCM2835_MMAL_VERSION "0.0.2"
> 
> MODULE_VERSION means nothing when the code is in the kernel tree, this
> shold just be removed entirely.
> 
> > +#define BCM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
> 
> KBUILD_MODULE_NAME provides this, please delete this and just use that
> instead.
> 
> This can be 2 different commits because of this.
> 
> thanks,
> 
> greg k-h
> 

Hi Greg,

Thanks for reviewing.

Ok, will do.

Gaston


From lkp at intel.com  Fri Jan  7 02:37:15 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 07 Jan 2022 18:37:15 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS 8922bb6526ac4b20bd8de7f47d6e77808670f6c4
Message-ID: <61d817db./Koc5ulOhrcRXqcO%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: 8922bb6526ac4b20bd8de7f47d6e77808670f6c4  Merge tag 'socfpga_fix_for_v5.16_part_3' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux into arm/fixes

elapsed time: 721m

configs tested: 150
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20220107
parisc                           alldefconfig
arm                           stm32_defconfig
mips                        bcm47xx_defconfig
powerpc                      ppc40x_defconfig
arm                       omap2plus_defconfig
arm                            lart_defconfig
sh                        sh7763rdp_defconfig
sh                           se7343_defconfig
sh                           se7721_defconfig
sh                     sh7710voipgw_defconfig
sh                            shmin_defconfig
arc                          axs101_defconfig
powerpc                     taishan_defconfig
sh                        edosk7705_defconfig
sh                          r7780mp_defconfig
mips                      loongson3_defconfig
ia64                      gensparse_defconfig
openrisc                    or1ksim_defconfig
xtensa                  cadence_csp_defconfig
m68k                        mvme147_defconfig
sh                          lboxre2_defconfig
powerpc                      chrp32_defconfig
powerpc                      mgcoge_defconfig
mips                           jazz_defconfig
arm                           viper_defconfig
m68k                       m5275evb_defconfig
arc                        nsimosci_defconfig
xtensa                    smp_lx200_defconfig
sparc64                          alldefconfig
arm                           h5000_defconfig
arm                          badge4_defconfig
sh                        dreamcast_defconfig
m68k                       m5475evb_defconfig
openrisc                            defconfig
arm                        realview_defconfig
powerpc                       ppc64_defconfig
arm                        trizeps4_defconfig
arm                  randconfig-c002-20220107
arm                  randconfig-c002-20220106
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
s390                                defconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20220107
x86_64               randconfig-a001-20220107
x86_64               randconfig-a004-20220107
x86_64               randconfig-a006-20220107
x86_64               randconfig-a002-20220107
x86_64               randconfig-a003-20220107
i386                 randconfig-a003-20220107
i386                 randconfig-a005-20220107
i386                 randconfig-a004-20220107
i386                 randconfig-a006-20220107
i386                 randconfig-a002-20220107
i386                 randconfig-a001-20220107
x86_64               randconfig-a012-20220106
x86_64               randconfig-a015-20220106
x86_64               randconfig-a014-20220106
x86_64               randconfig-a013-20220106
x86_64               randconfig-a011-20220106
x86_64               randconfig-a016-20220106
s390                 randconfig-r044-20220106
riscv                randconfig-r042-20220106
arc                  randconfig-r043-20220106
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
mips                 randconfig-c004-20220107
arm                  randconfig-c002-20220107
i386                 randconfig-c001-20220107
riscv                randconfig-c006-20220107
powerpc              randconfig-c003-20220107
x86_64               randconfig-c007-20220107
mips                      malta_kvm_defconfig
arm                      pxa255-idp_defconfig
mips                       lemote2f_defconfig
mips                        qi_lb60_defconfig
arm                          collie_defconfig
powerpc                          allyesconfig
arm                         s5pv210_defconfig
arm                         palmz72_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                         tb0219_defconfig
s390                             alldefconfig
mips                      bmips_stb_defconfig
i386                 randconfig-a003-20220106
i386                 randconfig-a005-20220106
i386                 randconfig-a006-20220106
i386                 randconfig-a002-20220106
i386                 randconfig-a001-20220106
x86_64               randconfig-a012-20220107
x86_64               randconfig-a015-20220107
x86_64               randconfig-a014-20220107
x86_64               randconfig-a013-20220107
x86_64               randconfig-a011-20220107
x86_64               randconfig-a016-20220107
i386                 randconfig-a012-20220107
i386                 randconfig-a016-20220107
i386                 randconfig-a014-20220107
i386                 randconfig-a015-20220107
i386                 randconfig-a011-20220107
i386                 randconfig-a013-20220107
hexagon              randconfig-r041-20220107
hexagon              randconfig-r045-20220107
riscv                randconfig-r042-20220107

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andrey.zhizhikin at leica-geosystems.com  Fri Jan  7 02:40:16 2022
From: andrey.zhizhikin at leica-geosystems.com (ZHIZHIKIN Andrey)
Date: Fri, 7 Jan 2022 10:40:16 +0000
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
Message-ID: <AM6PR06MB46919E01996D1F1DE326306DA64D9@AM6PR06MB4691.eurprd06.prod.outlook.com>

Hello Rouven,

> -----Original Message-----
> From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> Sent: Friday, January 7, 2022 10:46 AM
> To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> kernel at vger.kernel.org
> Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> krzk at kernel.org; leonard.crestez at nxp.com; festevam at gmail.com; marex at denx.de;
> herbert at gondor.apana.org.au; horia.geanta at nxp.com; daniel.baluta at nxp.com;
> frieder.schrempf at kontron.de; linux-imx at nxp.com; devicetree at vger.kernel.org;
> hongxing.zhu at nxp.com; s.hauer at pengutronix.de; pankaj.gupta at nxp.com;
> robh+dt at kernel.org; thunder.leizhen at huawei.com; martink at posteo.de;
> aford173 at gmail.com; linux-arm-kernel at lists.infradead.org;
> gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-crypto at vger.kernel.org;
> kernel at pengutronix.de; l.stach at pengutronix.de; shawnguo at kernel.org;
> davem at davemloft.net; jun.li at nxp.com
> Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
> 
> 
> On Thu, 2022-01-06 at 14:08 +0000, ZHIZHIKIN Andrey wrote:
> > Hello Rouven,
> >
> > > -----Original Message-----
> > > From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> > > Sent: Thursday, January 6, 2022 12:27 PM
> > > To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> > > kernel at vger.kernel.org
> > > Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> > > frieder.schrempf at kontron.de; leonard.crestez at nxp.com; festevam at gmail.com;
> > > marex at denx.de; herbert at gondor.apana.org.au; horia.geanta at nxp.com;
> > > aford173 at gmail.com; krzk at kernel.org; linux-imx at nxp.com;
> > > devicetree at vger.kernel.org; hongxing.zhu at nxp.com; s.hauer at pengutronix.de;
> > > pankaj.gupta at nxp.com; robh+dt at kernel.org; thunder.leizhen at huawei.com;
> > > martink at posteo.de; daniel.baluta at nxp.com; linux-arm-
> kernel at lists.infradead.org;
> > > gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> > > michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-
> crypto at vger.kernel.org;
> > > kernel at pengutronix.de; jun.li at nxp.com; shawnguo at kernel.org;
> davem at davemloft.net;
> > > l.stach at pengutronix.de
> > > Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam
> jr
> > >
> > > Hi Andrey,
> > >
> > > On Wed, 2021-12-08 at 00:02 +0100, Andrey Zhizhikin wrote:
> > > > CAAM JR nodes are configured by BootROM and are used by various software
> > > > entities during the boot process before they reach the Kernel.
> > > >
> > > > Default BootROM configuration have JR0 and JR1 reserved for S-only
> > > > access, while JR2 is generally available for both S and NS access. HAB
> > > > feature of i.MX8M family does require that JR0 is reserved exclusively
> > > > in S-only world, while JR1 and JR2 are both released to NS-World. OP-TEE
> > > > can later reclaim the JR2 via dt_enable_secure_status() call, and modify
> > > > the DID to hold it in S-World only.
> > > >
> > > > The above setup has been discovered during review of CAAM patchset
> > > > presented to U-Boot integration [1], and does not correspond to the
> > > > status on jr nodes in FDT.
> > > >
> > > > This missing status settings leads to the following error message during
> > > > jr node probing:
> > > > [    1.509894] caam 30900000.crypto: job rings = 3, qi = 0
> > > > [    1.525201] caam_jr 30901000.jr: failed to flush job ring 0
> > > > [    1.525214] caam_jr: probe of 30901000.jr failed with error -5
> > > >
> > > > JR register readout after BootROM execution shows the following values:
> > > > JR0DID_MS = 0x8011
> > > > JR1DID_MS = 0x8011
> > > > JR2DID_MS = 0x0
> > > >
> > > > This shows that JR0 and JR1 have TZ_OWN bit set, which marks them to be
> > > > reserved for S-World, while JR2 remains accessible from NS-World.
> > > >
> > > > Provide the correct status for JR nodes in imx8m derivatives, which have
> > > > a following meaning:
> > > > - JR0: S-only
> > > > - JR1: visible in both
> > > > - JR2: NS-only
> > > >
> > > > Note, that JR2 is initially marked to be NS-only which does correspond
> > > > to DID readout when OP-TEE is not present. Once present, OP-TEE will
> > > > reclaim the JR2 and set both "status" and "secure-status" to claim JR2
> > > > for S-only access.
> > >
> > > While I can understand that you want to fix your use case for when HAB
> > > is enabled, note that this is disabling JR0 in the none-HAB case as
> > > well.
> >
> > This is not totally correct, as this patch does address the reservation of
> > JR0 by BootROM in both HAB and non-HAB configurations. My current setup does
> > not include HAB functionality enabled, and I still do observe boot errors
> > that are listed in commit message. This is due to the fact that the BootROM
> > does not release JR0 to NS-World regardless of whether HAB is enabled or not.
> > This has been discussed in the U-Boot thread I provided the link in the patch.
> >
> > This patch does rather bring the correct HW module description as seeing
> > from Linux.
> 
> I took a look into i.MX8MQ, the bootrom indeed sets 0x8011 for JR0 &
> JR1:
> JR0:0000000000008011
> JR1:0000000000008011
> JR2:0000000000000000
> TF-A
> >CAAM
> JR0:0000000000000001
> JR1:0000000000000001
> JR2:0000000000000001
> 
> However at least the upstream TF-A reconfigures the DIDs to 1 for all
> i.MX8M* derivates.  So while it is technically correct to change the DT
> values as you describe, the downstream TF-A and upstream TF-A seem to
> differ in their configuration. I also think it's a bad move to hardcode
> the JR configuration to the boot ROM config, since AFAIK i.MX8M* can
> not be run without TF-A. And IMO the upstream kernel should follow what
> the upstream TF-A does in this case.

This is indeed an interesting piece of information, thanks a lot!

From what I understood in previous discussions for this series here in
the Kernel, and on U-Boot ML: JR0 is required to be held reserved in
S-World for HAB to operate, and this is clearly communicated by NXP in [1].
If my understanding is correct, then upstream TF-A either does not support
or breaks the HAB feature.

I've been following the build documentation in U-Boot, where the downstream
TF-A is listed as build prequisites [2] without any mentioning of upstream,
hence I received a readout that matched the BootROM "1-to-1".

I believe that if the information from NXP regarding JR0 reservation for
HAB is correct (and I have no reasons to doubt it), then upstream TF-A
should be adapted in order for HAB feature to work, and in that case this
patch brings correct HW state description as seeing from Linux.

And in contrary, if the upstream TF-A is not adjusted to include HAB
support - then applying this patch would effectively just "remove" one
JR device, still keeping 2 additional available nodes for HW crypto
operations in Kernel, with added benefit that both upstream and
downstream TF-A can be used during the boot without seeing issues later
in the Kernel.

> 
> >
> > > IMO this should be handled correctly by the bootloader and/or OP-
> > > TEE. The default upstream configuration for OP-TEE is to not use the
> > > CAAM at runtime as well, since linux runtime PM disablement of the CAAM
> > > will lock up OP-TEE when it tries to access the CAAM.
> >
> > If by handling you mean releasing JR0 reservation - then yes, it should be
> > done by either SPL or TF-A as they do run in S World. In such a case, DTB
> > bindings need to be adapted further according to the new state. Until this
> > done - this patch does provide a correct state of HW to the Kernel.
> 
> Upstream TF-A simply releases all JRs to the normal world, matching the
> current DTB description.
> 
> Kind Regards,
> Rouven Czerwinski
> 
> 
[snip]

Regards,
Andrey

Link: [1]: https://lore.kernel.org/u-boot/VI1PR04MB5342C8C6E651EC2CC4477EB5E79A9 at VI1PR04MB5342.eurprd04.prod.outlook.com/
Link: [2]: https://source.denx.de/u-boot/u-boot/-/blob/master/doc/board/nxp/imx8mm_evk.rst

From catalin.marinas at arm.com  Fri Jan  7 02:42:47 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:42:47 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <YdgZJ/mBG+BCxmEv@arm.com>

On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> Hi Catalin,
> 
> I roughly find the root cause.
>  alloc_init_pud will be called at the very beginning of kernel boot in create_mapping_noalloc where no memory allocator is initialized. But lockdep check may need allocate memory. So, kernel take exception when acquire lock.(I have not found the exact code that cause this issue) that's say we may not be able to use a lock so early.
> 
> I come up with 2 methods to address it. 
> 1) skip dead lock check at the very beginning of kernel boot in lockdep code.
> 2) provided 2 two versions of __create_pgd_mapping, one with lock in
> it and the other without. There may be no possible of race for memory
> mapping at the very beginning time of kernel boot, thus we can use the
> no lock version of __create_pgd_mapping safely.
> In my test, this issue is gone if there is no lock held in
> create_mapping_noalloc. I think create_mapping_noalloc is called early
> enough to avoid the race conditions of memory mapping, however, I have
> not proved it.

I think method 2 would work better but rather than implementing new
nolock functions I'd add a NO_LOCK flag and check it in
alloc_init_pud() before mutex_lock/unlock. Also add a comment when
passing the NO_LOCK flag on why it's needed and why there wouldn't be
any races at that stage (early boot etc.)

Thanks.

-- 
Catalin


From johnson.wang at mediatek.com  Fri Jan  7 02:46:31 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Fri, 7 Jan 2022 18:46:31 +0800
Subject: [PATCH v2 0/2] Add PMIC wrapper support for Mediatek MT8186 SoC IC
Message-ID: <20220107104633.7500-1-johnson.wang@mediatek.com>

This series add PMIC wrapper support for Mediatek MT8186 SoC IC

Changes since v1:
- Fix the conditional logic in pwrap_probe() function.

Johnson Wang (2):
  soc: mediatek: pwrap: add pwrap driver for MT8186 SoC
  dt-bindings: mediatek: add compatible for MT8186 pwrap

 .../bindings/soc/mediatek/pwrap.txt           |  1 +
 drivers/soc/mediatek/mtk-pmic-wrap.c          | 72 +++++++++++++++++++
 2 files changed, 73 insertions(+)

-- 
2.18.0



From johnson.wang at mediatek.com  Fri Jan  7 02:46:32 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Fri, 7 Jan 2022 18:46:32 +0800
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186 SoC
In-Reply-To: <20220107104633.7500-1-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
Message-ID: <20220107104633.7500-2-johnson.wang@mediatek.com>

MT8186 are highly integrated SoC and use PMIC_MT6366 for
power management. This patch adds pwrap master driver to
access PMIC_MT6366.

Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 drivers/soc/mediatek/mtk-pmic-wrap.c | 72 ++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
index 952bc554f443..78866ebf7f04 100644
--- a/drivers/soc/mediatek/mtk-pmic-wrap.c
+++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
@@ -30,6 +30,7 @@
 #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) & 0x00000001)
 #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
 #define PWRAP_STATE_INIT_DONE0		BIT(21)
+#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
 #define PWRAP_STATE_INIT_DONE1		BIT(15)
 
 /* macro for WACS FSM */
@@ -77,6 +78,8 @@
 #define PWRAP_CAP_INT1_EN	BIT(3)
 #define PWRAP_CAP_WDT_SRC1	BIT(4)
 #define PWRAP_CAP_ARB		BIT(5)
+#define PWRAP_CAP_MONITOR_V2	BIT(6)
+#define PWRAP_CAP_ARB_V2	BIT(8)
 
 /* defines for slave device wrapper registers */
 enum dew_regs {
@@ -1063,6 +1066,55 @@ static int mt8516_regs[] = {
 	[PWRAP_MSB_FIRST] =		0x170,
 };
 
+static int mt8186_regs[] = {
+	[PWRAP_MUX_SEL] =		0x0,
+	[PWRAP_WRAP_EN] =		0x4,
+	[PWRAP_DIO_EN] =		0x8,
+	[PWRAP_RDDMY] =			0x20,
+	[PWRAP_CSHEXT_WRITE] =		0x24,
+	[PWRAP_CSHEXT_READ] =		0x28,
+	[PWRAP_CSLEXT_WRITE] =		0x2C,
+	[PWRAP_CSLEXT_READ] =		0x30,
+	[PWRAP_EXT_CK_WRITE] =		0x34,
+	[PWRAP_STAUPD_CTRL] =		0x3C,
+	[PWRAP_STAUPD_GRPEN] =		0x40,
+	[PWRAP_EINT_STA0_ADR] =		0x44,
+	[PWRAP_EINT_STA1_ADR] =		0x48,
+	[PWRAP_INT_CLR] =		0xC8,
+	[PWRAP_INT_FLG] =		0xC4,
+	[PWRAP_MAN_EN] =		0x7C,
+	[PWRAP_MAN_CMD] =		0x80,
+	[PWRAP_WACS0_EN] =		0x8C,
+	[PWRAP_WACS1_EN] =		0x94,
+	[PWRAP_WACS2_EN] =		0x9C,
+	[PWRAP_INIT_DONE0] =		0x90,
+	[PWRAP_INIT_DONE1] =		0x98,
+	[PWRAP_INIT_DONE2] =		0xA0,
+	[PWRAP_INT_EN] =		0xBC,
+	[PWRAP_INT1_EN] =		0xCC,
+	[PWRAP_INT1_FLG] =		0xD4,
+	[PWRAP_INT1_CLR] =		0xD8,
+	[PWRAP_TIMER_EN] =		0xF0,
+	[PWRAP_WDT_UNIT] =		0xF8,
+	[PWRAP_WDT_SRC_EN] =		0xFC,
+	[PWRAP_WDT_SRC_EN_1] =		0x100,
+	[PWRAP_WDT_FLG] =		0x104,
+	[PWRAP_SPMINF_STA] =		0x1B4,
+	[PWRAP_DCM_EN] =		0x1EC,
+	[PWRAP_DCM_DBC_PRD] =		0x1F0,
+	[PWRAP_GPSINF_0_STA] =		0x204,
+	[PWRAP_GPSINF_1_STA] =		0x208,
+	[PWRAP_WACS0_CMD] =		0xC00,
+	[PWRAP_WACS0_RDATA] =		0xC04,
+	[PWRAP_WACS0_VLDCLR] =		0xC08,
+	[PWRAP_WACS1_CMD] =		0xC10,
+	[PWRAP_WACS1_RDATA] =		0xC14,
+	[PWRAP_WACS1_VLDCLR] =		0xC18,
+	[PWRAP_WACS2_CMD] =		0xC20,
+	[PWRAP_WACS2_RDATA] =		0xC24,
+	[PWRAP_WACS2_VLDCLR] =		0xC28,
+};
+
 enum pmic_type {
 	PMIC_MT6323,
 	PMIC_MT6351,
@@ -1083,6 +1135,7 @@ enum pwrap_type {
 	PWRAP_MT8135,
 	PWRAP_MT8173,
 	PWRAP_MT8183,
+	PWRAP_MT8186,
 	PWRAP_MT8195,
 	PWRAP_MT8516,
 };
@@ -1535,6 +1588,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
 	case PWRAP_MT6779:
 	case PWRAP_MT6797:
 	case PWRAP_MT8173:
+	case PWRAP_MT8186:
 	case PWRAP_MT8516:
 		pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
 		break;
@@ -2069,6 +2123,19 @@ static struct pmic_wrapper_type pwrap_mt8516 = {
 	.init_soc_specific = NULL,
 };
 
+static struct pmic_wrapper_type pwrap_mt8186 = {
+	.regs = mt8186_regs,
+	.type = PWRAP_MT8186,
+	.arb_en_all = 0xfb27f,
+	.int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1 */
+	.int1_en_all =  0x000017ff, /* disable Matching interrupt for bit 13 */
+	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
+	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
+	.caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_MONITOR_V2 | PWRAP_CAP_ARB_V2,
+	.init_reg_clock = pwrap_common_init_reg_clock,
+	.init_soc_specific = NULL,
+};
+
 static const struct of_device_id of_pwrap_match_tbl[] = {
 	{
 		.compatible = "mediatek,mt2701-pwrap",
@@ -2097,6 +2164,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
 	}, {
 		.compatible = "mediatek,mt8183-pwrap",
 		.data = &pwrap_mt8183,
+	}, {
+		.compatible = "mediatek,mt8186-pwrap",
+		.data = &pwrap_mt8186,
 	}, {
 		.compatible = "mediatek,mt8195-pwrap",
 		.data = &pwrap_mt8195,
@@ -2209,6 +2279,8 @@ static int pwrap_probe(struct platform_device *pdev)
 
 	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
 		mask_done = PWRAP_STATE_INIT_DONE1;
+	else if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))
+		mask_done = PWRAP_STATE_INIT_DONE0_V2;
 	else
 		mask_done = PWRAP_STATE_INIT_DONE0;
 
-- 
2.18.0



From johnson.wang at mediatek.com  Fri Jan  7 02:46:33 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Fri, 7 Jan 2022 18:46:33 +0800
Subject: [PATCH v2 2/2] dt-bindings: mediatek: add compatible for MT8186 pwrap
In-Reply-To: <20220107104633.7500-1-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
Message-ID: <20220107104633.7500-3-johnson.wang@mediatek.com>

This adds dt-binding documentation of pwrap for Mediatek MT8186
SoCs Platform.

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
---
 Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
index d74a7a5ae9f2..214a34633824 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
@@ -27,6 +27,7 @@ Required properties in pwrap device node.
 	"mediatek,mt8135-pwrap" for MT8135 SoCs
 	"mediatek,mt8173-pwrap" for MT8173 SoCs
 	"mediatek,mt8183-pwrap" for MT8183 SoCs
+	"mediatek,mt8186-pwrap" for MT8186 SoCs
 	"mediatek,mt8195-pwrap" for MT8195 SoCs
 	"mediatek,mt8516-pwrap" for MT8516 SoCs
 - interrupts: IRQ for pwrap in SOC
-- 
2.18.0



From catalin.marinas at arm.com  Fri Jan  7 02:53:54 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:53:54 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <YdgbwpECTXGCJZ/0@arm.com>

On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> I roughly find the root cause.
>  alloc_init_pud will be called at the very beginning of kernel boot in
>  create_mapping_noalloc where no memory allocator is initialized. But
>  lockdep check may need allocate memory. So, kernel take exception
>  when acquire lock.(I have not found the exact code that cause this
>  issue) that's say we may not be able to use a lock so early.

I couldn't find an slab or page allocation place either. It would be
nice to get to the root cause rather than just avoiding the mutex on the
early boot path.

-- 
Catalin


From catalin.marinas at arm.com  Fri Jan  7 02:56:58 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:56:58 +0000
Subject: [PATCH V2 1/7] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1641517808-5735-2-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YdgcegdfpV6eCvXl@arm.com>

On Fri, Jan 07, 2022 at 06:40:02AM +0530, Anshuman Khandual wrote:
> Add the CPU Partnumbers for the new Arm designs.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan  7 02:58:27 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:58:27 +0000
Subject: [PATCH V2 2/7] arm64: errata: Add detection for TRBE ignored
 system register writes
In-Reply-To: <1641517808-5735-3-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Ydgc06hHrMDMqMnf@arm.com>

On Fri, Jan 07, 2022 at 06:40:03AM +0530, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected. This adds a new errata ARM64_ERRATUM_2064142
> in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan  7 02:59:09 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:59:09 +0000
Subject: [PATCH V2 3/7] arm64: errata: Add detection for TRBE invalid
 prohibited states
In-Reply-To: <1641517808-5735-4-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Ydgc/dlEkQN/JBXx@arm.com>

On Fri, Jan 07, 2022 at 06:40:04AM +0530, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
> an inconsistent view on whether trace is prohibited within the CPU. As a
> result, the trace buffer or trace buffer state might be corrupted. This
> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
> followed by just a single context synchronization event before execution
> changes from a context, in which trace is prohibited to one where it isn't,
> or vice versa. In these mentioned conditions, the view of whether trace is
> prohibited is inconsistent between parts of the CPU, and the trace buffer
> or the trace buffer state might be corrupted. This adds a new errata
> ARM64_ERRATUM_2038923 in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan  7 02:59:51 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 10:59:51 +0000
Subject: [PATCH V2 4/7] arm64: errata: Add detection for TRBE trace data
 corruption
In-Reply-To: <1641517808-5735-5-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-5-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YdgdJyjvSt8iQ6RB@arm.com>

On Fri, Jan 07, 2022 at 06:40:05AM +0530, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #1902691 might corrupt trace
> data or deadlock, when it's being written into the memory. So effectively
> TRBE is broken and hence cannot be used to capture trace data. This adds
> a new errata ARM64_ERRATUM_1902691 in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From alexandru.elisei at arm.com  Fri Jan  7 03:08:05 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Fri, 7 Jan 2022 11:08:05 +0000
Subject: [PATCH v3 3/4] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU
 attribute
In-Reply-To: <8735m0vifv.wl-maz@kernel.org>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <20211213152309.158462-4-alexandru.elisei@arm.com>
 <8735mvjrq8.wl-maz@kernel.org>
 <YdbYY/EZrTTPKOCp@monolith.localdoman>
 <8735m0vifv.wl-maz@kernel.org>
Message-ID: <YdgfFa9y1CUkVC5k@monolith.localdoman>

Hi Marc,

On Thu, Jan 06, 2022 at 06:16:04PM +0000, Marc Zyngier wrote:
> On Thu, 06 Jan 2022 11:54:11 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > Hi Marc,
> > 
> > On Tue, Dec 14, 2021 at 12:28:15PM +0000, Marc Zyngier wrote:
> > > On Mon, 13 Dec 2021 15:23:08 +0000,
> > > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > >
> > > > [..]
> > > >
> > > > @@ -910,7 +922,16 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
> > > >  	init_irq_work(&vcpu->arch.pmu.overflow_work,
> > > >  		      kvm_pmu_perf_overflow_notify_vcpu);
> > > >  
> > > > -	vcpu->arch.pmu.created = true;
> > > > +	atomic_set(&vcpu->arch.pmu.created, 1);
> > > > +
> > > > +	kvm_for_each_vcpu(i, v, kvm) {
> > > > +		if (!atomic_read(&v->arch.pmu.created))
> > > > +			continue;
> > > > +
> > > > +		if (v->arch.pmu.arm_pmu != arm_pmu)
> > > > +			return -ENXIO;
> > > > +	}
> > > 
> > > If you did store the arm_pmu at the VM level, you wouldn't need this.
> > > You could detect the discrepancy in the set_pmu ioctl.
> > 
> > I chose to set at the VCPU level to be consistent with how KVM treats the
> > PMU interrupt ID when the interrupt is a PPI, where the interrupt ID must
> > be the same for all VCPUs and it is stored at the VCPU. However, looking at
> > the code again, it occurs to me that it is stored at the VCPU when it's a
> > PPI because it's simpler to do it that way, as the code remains the same
> > when the interrupt ID is a SPI, which must be *different* between VCPUs. So
> > in the end, having the PMU stored at the VM level does match how KVM uses
> > it, which looks to be better than my approach.
> > 
> > This is the change you proposed in your branch [1]:
> > 
> > +static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
> > +{
> > +       struct kvm *kvm = vcpu->kvm;
> > +       struct arm_pmu_entry *entry;
> > +       struct arm_pmu *arm_pmu;
> > +       int ret = -ENXIO;
> > +
> > +       mutex_lock(&kvm->lock);
> > +       mutex_lock(&arm_pmus_lock);
> > +
> > +       list_for_each_entry(entry, &arm_pmus, entry) {
> > +               arm_pmu = entry->arm_pmu;
> > +               if (arm_pmu->pmu.type == pmu_id) {
> > +                       /* Can't change PMU if filters are already in place */
> > +                       if (kvm->arch.arm_pmu != arm_pmu &&
> > +                           kvm->arch.pmu_filter) {
> > +                               ret = -EBUSY;
> > +                               break;
> > +                       }
> > +
> > +                       kvm->arch.arm_pmu = arm_pmu;
> > +                       ret = 0;
> > +                       break;
> > +               }
> > +       }
> > +
> > +       mutex_unlock(&arm_pmus_lock);
> > +       mutex_unlock(&kvm->lock);
> > +       return ret;
> > +}
> > 
> > As I understand the code, userspace only needs to call
> > KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) *once* (on one VCPU
> > fd) to set the PMU for all the VCPUs; subsequent calls (on the same VCPU or
> > on another VCPU) with a different PMU id will change the PMU for all VCPUs.
> > 
> > Two remarks:
> > 
> > 1. The documentation for the VCPU ioctls states this (from
> > Documentation/virt/kvm/devices/vcpu.rst):
> > 
> > "
> > ======================
> > Generic vcpu interface
> > ======================
> > 
> > The virtual cpu "device" also accepts the ioctls KVM_SET_DEVICE_ATTR,
> > KVM_GET_DEVICE_ATTR, and KVM_HAS_DEVICE_ATTR. The interface uses the same struct
> > kvm_device_attr as other devices, but **targets VCPU-wide settings and
> > controls**" (emphasis added).
> > 
> > But I guess having VCPU ioctls affect *only* the VCPU hasn't really been
> > true ever since PMU event filtering has been added. I'll send a patch to
> > change that part of the documentation for arm64.
> > 
> > I was thinking maybe a VM capability would be better suited for changing a
> > VM-wide setting, what do you think? I don't have a strong preference either
> > way.
> 
> I'm not sure it is worth the hassle of changing the API, as we'll have
> to keep the current one forever.

I was suggesting to use a capability for setting the PMU, it's too late to
change how the events filter is set.

> 
> > 
> > 2. What's to stop userspace to change the PMU after at least one VCPU has
> > run? That can be easily observed by the guest when reading PMCEIDx_EL0.
> 
> That's a good point. We need something here. It is a bit odd as to do
> that, you need to fully enable a PMU on one CPU, but not on the other,
> then run the first while changing stuff on the other. Something along
> those lines (untested):
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 4bf28905d438..4f53520e84fd 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -139,6 +139,7 @@ struct kvm_arch {
>  
>  	/* Memory Tagging Extension enabled for the guest */
>  	bool mte_enabled;
> +	bool ran_once;
>  };
>  
>  struct kvm_vcpu_fault_info {
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 83297fa97243..3045d7f609df 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -606,6 +606,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>  
>  	vcpu->arch.has_run_once = true;
>  
> +	mutex_lock(&kvm->lock);
> +	kvm->arch.ran_once = true;
> +	mutex_unlock(&kvm->lock);
> +
>  	kvm_arm_vcpu_init_debug(vcpu);
>  
>  	if (likely(irqchip_in_kernel(kvm))) {
> diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> index dfc0430d6418..95100c541244 100644
> --- a/arch/arm64/kvm/pmu-emul.c
> +++ b/arch/arm64/kvm/pmu-emul.c
> @@ -959,8 +959,9 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
>  		arm_pmu = entry->arm_pmu;
>  		if (arm_pmu->pmu.type == pmu_id) {
>  			/* Can't change PMU if filters are already in place */
> -			if (kvm->arch.arm_pmu != arm_pmu &&
> -			    kvm->arch.pmu_filter) {
> +			if ((kvm->arch.arm_pmu != arm_pmu &&
> +			     kvm->arch.pmu_filter) ||
> +			    kvm->arch.ran_once) {
>  				ret = -EBUSY;
>  				break;
>  			}
> @@ -1040,6 +1041,11 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>  
>  		mutex_lock(&vcpu->kvm->lock);
>  
> +		if (vcpu->kvm->arch.ran_once) {
> +			mutex_unlock(&vcpu->kvm->lock);
> +			return -EBUSY;
> +		}
> +
>  		if (!vcpu->kvm->arch.pmu_filter) {
>  			vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
>  			if (!vcpu->kvm->arch.pmu_filter) {
> 
> which should prevent both PMU or filters to be changed once a single
> vcpu as run.
> 
> Thoughts?

Haven't tested it either, but it looks good to me. If you agree, I can pick
the diff, turn it into a patch and send it for the next iteration of this
series as a fix for the PMU events filter, while keeping your authorship.

Thanks,
Alex


From angelogioacchino.delregno at collabora.com  Fri Jan  7 03:11:38 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 12:11:38 +0100
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186
 SoC
In-Reply-To: <20220107104633.7500-2-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
Message-ID: <b487865f-086e-9463-a698-82f14c42ff23@collabora.com>

Il 07/01/22 11:46, Johnson Wang ha scritto:
> MT8186 are highly integrated SoC and use PMIC_MT6366 for
> power management. This patch adds pwrap master driver to
> access PMIC_MT6366.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From jgross at suse.com  Fri Jan  7 03:31:30 2022
From: jgross at suse.com (Juergen Gross)
Date: Fri, 7 Jan 2022 12:31:30 +0100
Subject: [PATCH V4 0/6] xen: Add support of extended regions (safe ranges)
 on Arm
In-Reply-To: <1639080336-26573-1-git-send-email-olekstysh@gmail.com>
References: <1639080336-26573-1-git-send-email-olekstysh@gmail.com>
Message-ID: <d594a183-c7be-5fff-da7a-e4c1e707b83c@suse.com>

On 09.12.21 21:05, Oleksandr Tyshchenko wrote:
> From: Oleksandr Tyshchenko <oleksandr_tyshchenko at epam.com>
> 
> Hello all.
> 
> You can find the RFC-V3 patch series at [1],[2] and [3].
> 
> The corresponding Xen support (for both Dom0 and DomU) is already committed and
> is available in mainline Xen since the following commit:
> 57f87857dc2de452a796d6bad4f476510efd2aba libxl/arm: Add handling of extended regions for DomU
> 
> The extended region (safe range) is a region of guest physical address space
> which is unused and could be safely used to create grant/foreign mappings instead
> of ballooning out real RAM pages to obtain a physical address space for creating
> these mappings (which simply results in wasting domain memory and shattering super
> pages in P2M table).
> 
> The problem is that we cannot follow Linux advise which memory ranges are unused
> on Arm as there might be some identity mappings in P2M table (stage 2) the guest is not
> aware of or not all device I/O regions might be known (registered) by the time the guest
> starts creating grant/foreign mappings. This is why we need some hints from the hypervisor
> which knows all details in advance to be able to choose extended regions (which won't
> clash with other resources).
> 
> The extended regions are chosen at the domain creation time and advertised to it via
> "reg" property under hypervisor node in the guest device-tree [4]. As region 0 is reserved
> for grant table space (always present), the indexes for extended regions are 1...N.
> No device tree bindings update is needed, guest infers the presence of extended regions
> from the number of regions in "reg" property.
> 
> Please note the following:
> - The ACPI case is not covered for now
> - patch series was created in a way to retain existing behavior on x86
> 
> The patch series is based on v5.16-rc3 and also available at [5], it was fully
> tested on Arm64 and only compile tested on x86.
> 
> [1] https://lore.kernel.org/all/1627490656-1267-1-git-send-email-olekstysh at gmail.com/
>      https://lore.kernel.org/all/1627490656-1267-2-git-send-email-olekstysh at gmail.com/
> [2] https://lore.kernel.org/all/1635264312-3796-1-git-send-email-olekstysh at gmail.com/
> [3] https://lore.kernel.org/all/1637787223-21129-1-git-send-email-olekstysh at gmail.com/
> [4] https://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=docs/misc/arm/device-tree/guest.txt;hb=refs/heads/master
> [5] https://github.com/otyshchenko1/linux/commits/map_opt_ml7
> 
> Oleksandr Tyshchenko (6):
>    xen/unpopulated-alloc: Drop check for virt_addr_valid() in fill_list()
>    arm/xen: Switch to use gnttab_setup_auto_xlat_frames() for DT
>    xen/balloon: Bring alloc(free)_xenballooned_pages helpers back
>    xen/unpopulated-alloc: Add mechanism to use Xen resource
>    arm/xen: Read extended regions from DT and init Xen resource
>    dt-bindings: xen: Clarify "reg" purpose
> 
>   Documentation/devicetree/bindings/arm/xen.txt |  14 +--
>   arch/arm/xen/enlighten.c                      | 132 ++++++++++++++++++++++++--
>   drivers/xen/Kconfig                           |   2 +-
>   drivers/xen/balloon.c                         |  20 ++--
>   drivers/xen/unpopulated-alloc.c               |  87 ++++++++++++++++-
>   include/xen/balloon.h                         |   3 +
>   include/xen/xen.h                             |  16 ++++
>   7 files changed, 245 insertions(+), 29 deletions(-)
> 

Series pushed to xen/tip.git for-linus-5.17


Juergen
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_0xB0DE9DD628BF132F.asc
Type: application/pgp-keys
Size: 3091 bytes
Desc: OpenPGP public key
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220107/6d15991c/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220107/6d15991c/attachment.sig>

From michal.simek at xilinx.com  Fri Jan  7 03:32:28 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 7 Jan 2022 12:32:28 +0100
Subject: i2c-xiic: An error occurs while handling RX irq
In-Reply-To: <CAJk_X9hQZbbiCN9-DDsjcaUw-9jo7pTo2GpQGNOhpPGDCnotrA@mail.gmail.com>
References: <CAJk_X9gQnUJDz8mxbKDML_HsSEL1+FdmTbiDwo7JyoofBwntFA@mail.gmail.com>
 <CAJk_X9hQZbbiCN9-DDsjcaUw-9jo7pTo2GpQGNOhpPGDCnotrA@mail.gmail.com>
Message-ID: <96b0b280-9839-1009-2e9d-7fbe9911b7ae@xilinx.com>

++




On 1/7/22 08:18, Jeaho Hwang wrote:
>>
>> Hello xilinx and arm linux experts.
>> We are testing periodic send & recv i2c msgs on zynq7000 based target
>> board. It shows -5(EIO) errors rarely and works fine again from the
>> next period.
>> We use the Linux kernel 5.4.0 provided by Petalinux 2021.2, with
>> RT-patch. Investigating the code I think the RT patch would not affect
>> this symptom. We will also try to reproduce it with non-preempt-RT
>> configuration.
>> The debug log is attached below.
> 
> Hello. We investigated more and got the reason for the error return.
> 
> In general cases, 3 interrupts were raised for one i2c read as following log.
> 
> xiic_start_recv entry, ISR: 0xd0, CR: 0x1
> xiic_isr entry
> xiic_process: IER: 0x1b, ISR: 0xd0, pend: 0x10
> xiic_process: SR: 0x8c, msg: f14e832a, nmsgs: 1
> xiic_process, ISR: 0xca, CR: 0x1
> xiic_process clr: 0x0
> -------------------------------------------------------------------
> the first irq handler was called by ISR(4): BUS NOT BUSY.
> BC xiic_start_recv enabled interrupt but slave didn't start transmission yet.
> This is unnecessary and the handler disables the BNB bit and ignores it.
> 
> xiic_isr entry
> xiic_process: IER: 0x1b, ISR: 0xca, pend: 0xa
> xiic_process: SR: 0x8c, msg: f14e832a, nmsgs: 1
> xiic_process, ISR: 0xca, CR: 0x1
> xiic_read_rx entry, bytes in fifo: 2, rem: 2, SR: 0x8c, CR: 0x1
> xiic_process end of message, nmsgs: 1
> xiic_process clr: 0xa
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> The second irq handler works the real thing.
> 
> xiic_isr entry
> xiic_process: IER: 0x1b, ISR: 0xd0, pend: 0x10
> xiic_process: SR: 0xc8, msg: f14e832a, nmsgs: 1
> xiic_process, ISR: 0xd0, CR: 0x1
> xiic_process clr: 0x10
> 
> the third is raised BC the bus is idle but BNB is still enabled.
> 
> sometimes the threaded irq handler for the first irq could be delayed
> so ISR could be read as 0xca.
> Rarely, ISR could be read 0xC2 if the timing was between TXCOMP set
> and RXFULL set.
> AS PG090, pp14, RXFULL bit  is not set at the same time as Transmit
> Complete bit.
> 
> In order to prevent this malfunction, We believe the best option is to
> prevent the first irq. Is it possible?
> The second option could be the consideration of this timing issue: the
> walkaround.
> We temporarily implemented the second read of ISR for the case
> 0x?A(TXCOMP && !RXFULL) and found that it works well.
> 
> Do you have better suggestions for this issue?
> 
> Happy new year!
> Jeaho Hwang
> 
>>
>> [   95.115539] i2c-dev: i2c-1 reading 2 bytes.
>> [   95.115552] xiic-i2c 40700000.i2c: xiic_xfer entry SR: 0xc0
>> [   95.115562] xiic-i2c 40700000.i2c: xiic_setclk entry,
>> i2c->input_clk: 100000000, i2c->i2c_clk: 0
>> [   95.115576] xiic-i2c 40700000.i2c: __xiic_start_xfer entry, msg:
>> f14e832a, fifos space: 15
>> [   95.115588] xiic-i2c 40700000.i2c: xiic_start_recv entry, ISR: 0xd0, CR: 0x1
>> [   95.115605] xiic-i2c 40700000.i2c: xiic_isr entry
>> [   95.115674] xiic-i2c 40700000.i2c: xiic_process: IER: 0x1b, ISR:
>> 0xc2, pend: 0x2
>>
>>                             ~~~~~~~~
>> [   95.115685] xiic-i2c 40700000.i2c: xiic_process: SR: 0x8c, msg:
>> f14e832a, nmsgs: 1
>> [   95.115698] xiic-i2c 40700000.i2c: xiic_process, ISR: 0xca, CR: 0x1
>>
>>           ~~~~~~~~
>> [   95.115706] xiic-i2c 40700000.i2c: xiic_process error
>>
>> BC pend calculated was 0x2(XIIC_INTR_TX_ERROR_MASK without
>> RX_FULL_MASK) this pended value is handled as an error. But the latter
>> read value of ISR was 0xca, which means normal RX completion. It seems
>> that reading ISR is too earlier or updating RXFULL bit is delayed.
>>
>> I found the second ISR print is added from commit
>> a6183c1688142adcf55b11baff95222b47792644, by Raviteja. I wonder this
>> or similar cases have been considered before. I also wonder if we
>> should add the second chance of reading ISR in similar cases inside
>> the irq handler (e.g. drivers/i2c/busses/i2c-xiic.c:635)
>>

Shubhrajyoti: Please take a look at it.

M


From sudeep.holla at arm.com  Fri Jan  7 03:37:40 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Fri, 7 Jan 2022 11:37:40 +0000
Subject: [GIT PULL] firmware: arm_scmi: Updates for v5.17
In-Reply-To: <20211222141342.56395-1-sudeep.holla@arm.com>
References: <20211222141342.56395-1-sudeep.holla@arm.com>
Message-ID: <20220107113740.f4zlz25largdjcfd@bogus>


Hi again,

On Wed, Dec 22, 2021 at 02:13:42PM +0000, Sudeep Holla wrote:
> Hi ARM SoC Team,
>
> Please pull !
>

I am aware I sent this pull request just around the same time Arnd finalised
the initial set. I have seen emails suggesting that Olof might be planning
to merge additional PR, so it would be great if this gets included in
that cut. All the changes are in -next since 21st December, so there should
be no surprises.

Thanks again and sorry for nagging.

--
Regards,
Sudeep


From suzuki.poulose at arm.com  Fri Jan  7 03:39:08 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 7 Jan 2022 11:39:08 +0000
Subject: [PATCH V2 2/7] arm64: errata: Add detection for TRBE ignored
 system register writes
In-Reply-To: <1641517808-5735-3-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <267afb26-00c3-63e6-6b8f-6f20785cab82@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected. This adds a new errata ARM64_ERRATUM_2064142
> in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst |  2 ++
>   arch/arm64/Kconfig                     | 18 ++++++++++++++++++
>   arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
>   arch/arm64/tools/cpucaps               |  1 +
>   4 files changed, 30 insertions(+)
> 


Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From lorenzo.pieralisi at arm.com  Fri Jan  7 03:43:32 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Fri, 7 Jan 2022 11:43:32 +0000
Subject: [PATCH] PCI: iproc: Set all 24 bits of PCI class code
In-Reply-To: <20220106180026.GA295674@bhelgaas>
References: <20220105181306.mkratasqg36tjf4e@pali>
 <20220106180026.GA295674@bhelgaas>
Message-ID: <20220107114332.GA22419@lpieralisi>

On Thu, Jan 06, 2022 at 12:00:26PM -0600, Bjorn Helgaas wrote:
> On Wed, Jan 05, 2022 at 07:13:06PM +0100, Pali Roh?r wrote:
> > On Wednesday 05 January 2022 09:51:48 Ray Jui wrote:
> > > On 1/5/2022 1:35 AM, Pali Roh?r wrote:
> 
> > > 2. I suppose 'PCI_CLASS_BRIDGE_PCI_NORMAL' is defined in some common PCI
> > > header in a separate patch as described in the commit message. Then how
> > > come these patches are not constructed with a patch series?
> > 
> > Yes, PCI_CLASS_BRIDGE_PCI_NORMAL is a new constant for common pci header
> > file defined in patch linked in commit message.
> > https://lore.kernel.org/linux-pci/20211220145140.31898-1-pali at kernel.org/
> > 
> > Originally I included this change in v1 of linked patch in December but
> > I realized that it does not match standard PCI config space (different
> > offset 0x43c vs 0x08 and also different shift 0x8 vs 0x0) and probably
> > there is something either incorrect or really non-standard. So later in
> > December I dropped iproc_pcie_check_link() change in v2 of the linked
> > patch where is introduced PCI_CLASS_BRIDGE_PCI_NORMAL and now sent new
> > change for iproc_pcie_check_link() separately.
> > 
> > Technically, linked patch in commit message is just extracting code into
> > the common macros without any functional changed. But change in this
> > iproc_pcie_check_link() has also functional change as now also lower 8
> > bits of class code are changed. So in my opinion this patch should be
> > really separate of linked patch.
> > 
> > I hope that Lorenzo and Bjorn take patches in correct order...
> 
> If patches are not sent together in a series, you can't assume
> anything about the order they'll be applied in.  Adding a note about
> "this patch depends patch X" helps a little but adds a fair amount of
> friction to the process.

Indeed, more so given that the dependency requires an ACK from other
maintainers - I certainly can't pull this patch as-is.

Lorenzo


From maz at kernel.org  Fri Jan  7 03:45:48 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri,  7 Jan 2022 11:45:48 +0000
Subject: [GIT PULL] KVM/arm64 updates for 5.17
Message-ID: <20220107114548.4069893-1-maz@kernel.org>

Hi Paolo,

Here's the bulk of the KVM/arm64 updates for 5.17. No real new feature
this time around, but a bunch of changes that will make the merging of
upcoming features easier (pKVM is reaching a point where it will
finally be usable, and NV isn't too far off... fingers crossed). This
comes with the usual set of bug fixes and cleanups all over the shop.

We also have a sizeable chunks of selftest updates which probably
account for half of the changes.

Please pull,

	M.

The following changes since commit d58071a8a76d779eedab38033ae4c821c30295a5:

  Linux 5.16-rc3 (2021-11-28 14:09:19 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-5.17

for you to fetch changes up to 1c53a1ae36120997a82f936d044c71075852e521:

  Merge branch kvm-arm64/misc-5.17 into kvmarm-master/next (2022-01-04 17:16:15 +0000)

----------------------------------------------------------------
KVM/arm64 updates for Linux 5.16

- Simplification of the 'vcpu first run' by integrating it into
  KVM's 'pid change' flow

- Refactoring of the FP and SVE state tracking, also leading to
  a simpler state and less shared data between EL1 and EL2 in
  the nVHE case

- Tidy up the header file usage for the nvhe hyp object

- New HYP unsharing mechanism, finally allowing pages to be
  unmapped from the Stage-1 EL2 page-tables

- Various pKVM cleanups around refcounting and sharing

- A couple of vgic fixes for bugs that would trigger once
  the vcpu xarray rework is merged, but not sooner

- Add minimal support for ARMv8.7's PMU extension

- Rework kvm_pgtable initialisation ahead of the NV work

- New selftest for IRQ injection

- Teach selftests about the lack of default IPA space and
  page sizes

- Expand sysreg selftest to deal with Pointer Authentication

- The usual bunch of cleanups and doc update

----------------------------------------------------------------
Andy Shevchenko (1):
      KVM: arm64: vgic: Replace kernel.h with the necessary inclusions

Fuad Tabba (3):
      KVM: arm64: Use defined value for SCTLR_ELx_EE
      KVM: arm64: Fix comment for kvm_reset_vcpu()
      KVM: arm64: Fix comment on barrier in kvm_psci_vcpu_on()

Marc Zyngier (33):
      KVM: arm64: Reorder vcpu flag definitions
      KVM: arm64: Get rid of host SVE tracking/saving
      KVM: arm64: Remove unused __sve_save_state
      KVM: arm64: Introduce flag shadowing TIF_FOREIGN_FPSTATE
      KVM: arm64: Stop mapping current thread_info at EL2
      arm64/fpsimd: Document the use of TIF_FOREIGN_FPSTATE by KVM
      KVM: arm64: Move SVE state mapping at HYP to finalize-time
      KVM: arm64: Move kvm_arch_vcpu_run_pid_change() out of line
      KVM: arm64: Restructure the point where has_run_once is advertised
      KVM: arm64: Merge kvm_arch_vcpu_run_pid_change() and kvm_vcpu_first_run_init()
      KVM: arm64: Drop vcpu->arch.has_run_once for vcpu->pid
      Merge branch kvm-arm64/vcpu-first-run into kvmarm-master/next
      Merge branch kvm-arm64/fpsimd-tracking into kvmarm-master/next
      KVM: arm64: Add minimal handling for the ARMv8.7 PMU
      Merge branch kvm-arm64/hyp-header-split into kvmarm-master/next
      Merge branch kvm-arm64/misc-5.17 into kvmarm-master/next
      KVM: arm64: Drop unused workaround_flags vcpu field
      Merge branch kvm-arm64/pkvm-cleanups-5.17 into kvmarm-master/next
      KVM: arm64: vgic-v3: Fix vcpu index comparison
      KVM: arm64: vgic: Demote userspace-triggered console prints to kvm_debug()
      Merge branch kvm-arm64/vgic-fixes-5.17 into kvmarm-master/next
      Merge branch kvm-arm64/pkvm-hyp-sharing into kvmarm-master/next
      KVM: arm64: Rework kvm_pgtable initialisation
      KVM: selftests: arm64: Initialise default guest mode at test startup time
      KVM: selftests: arm64: Introduce a variable default IPA size
      KVM: selftests: arm64: Check for supported page sizes
      KVM: selftests: arm64: Rework TCR_EL1 configuration
      KVM: selftests: arm64: Add support for VM_MODE_P36V48_{4K,64K}
      KVM: selftests: arm64: Add support for various modes with 16kB page size
      KVM: arm64: selftests: get-reg-list: Add pauth configuration
      Merge branch kvm-arm64/selftest/ipa into kvmarm-master/next
      Merge branch kvm-arm64/selftest/irq-injection into kvmarm-master/next
      Merge branch kvm-arm64/misc-5.17 into kvmarm-master/next

Quentin Perret (12):
      KVM: arm64: pkvm: Fix hyp_pool max order
      KVM: arm64: pkvm: Disable GICv2 support
      KVM: arm64: Make the hyp memory pool static
      KVM: arm64: Make __io_map_base static
      KVM: arm64: pkvm: Stub io map functions
      KVM: arm64: pkvm: Make kvm_host_owns_hyp_mappings() robust to VHE
      KVM: arm64: Provide {get,put}_page() stubs for early hyp allocator
      KVM: arm64: Refcount hyp stage-1 pgtable pages
      KVM: arm64: Fixup hyp stage-1 refcount
      KVM: arm64: Introduce kvm_share_hyp()
      KVM: arm64: pkvm: Refcount the pages shared with EL2
      KVM: arm64: pkvm: Unshare guest structs during teardown

Ricardo Koller (17):
      KVM: selftests: aarch64: Move gic_v3.h to shared headers
      KVM: selftests: aarch64: Add function for accessing GICv3 dist and redist registers
      KVM: selftests: aarch64: Add GICv3 register accessor library functions
      KVM: selftests: Add kvm_irq_line library function
      KVM: selftests: aarch64: Add vGIC library functions to deal with vIRQ state
      KVM: selftests: aarch64: Add vgic_irq to test userspace IRQ injection
      KVM: selftests: aarch64: Abstract the injection functions in vgic_irq
      KVM: selftests: aarch64: Cmdline arg to set number of IRQs in vgic_irq test
      KVM: selftests: aarch64: Cmdline arg to set EOI mode in vgic_irq
      KVM: selftests: aarch64: Add preemption tests in vgic_irq
      KVM: selftests: aarch64: Level-sensitive interrupts tests in vgic_irq
      KVM: selftests: aarch64: Add tests for LEVEL_INFO in vgic_irq
      KVM: selftests: aarch64: Add test_inject_fail to vgic_irq
      KVM: selftests: Add IRQ GSI routing library functions
      KVM: selftests: aarch64: Add tests for IRQFD in vgic_irq
      KVM: selftests: aarch64: Add ISPENDR write tests in vgic_irq
      KVM: selftests: aarch64: Add test for restoring active IRQs

Rikard Falkeborn (1):
      KVM: arm64: Constify kvm_io_gic_ops

Vitaly Kuznetsov (1):
      KVM: Drop stale kvm_is_transparent_hugepage() declaration

Will Deacon (11):
      arm64: Add missing include of asm/cpufeature.h to asm/mmu.h
      KVM: arm64: Generate hyp_constants.h for the host
      KVM: arm64: Move host EL1 code out of hyp/ directory
      KVM: arm64: Hook up ->page_count() for hypervisor stage-1 page-table
      KVM: arm64: Implement kvm_pgtable_hyp_unmap() at EL2
      KVM: arm64: Extend pkvm_page_state enumeration to handle absent pages
      KVM: arm64: Introduce wrappers for host and hyp spin lock accessors
      KVM: arm64: Implement do_share() helper for sharing memory
      KVM: arm64: Implement __pkvm_host_share_hyp() using do_share()
      KVM: arm64: Implement do_unshare() helper for unsharing memory
      KVM: arm64: Expose unshare hypercall to the host

Zenghui Yu (1):
      KVM: arm64: Fix comment typo in kvm_vcpu_finalize_sve()

 arch/arm64/include/asm/kvm_asm.h                   |   1 +
 arch/arm64/include/asm/kvm_emulate.h               |   2 +-
 arch/arm64/include/asm/kvm_host.h                  |  46 +-
 arch/arm64/include/asm/kvm_hyp.h                   |   1 -
 arch/arm64/include/asm/kvm_mmu.h                   |   2 +
 arch/arm64/include/asm/kvm_pgtable.h               |  30 +-
 arch/arm64/include/asm/kvm_pkvm.h                  |  71 ++
 arch/arm64/include/asm/mmu.h                       |   1 +
 arch/arm64/include/asm/sysreg.h                    |   1 +
 arch/arm64/kernel/asm-offsets.c                    |   1 -
 arch/arm64/kernel/fpsimd.c                         |   6 +-
 arch/arm64/kvm/.gitignore                          |   2 +
 arch/arm64/kvm/Makefile                            |  18 +-
 arch/arm64/kvm/arm.c                               |  64 +-
 arch/arm64/kvm/fpsimd.c                            |  79 +-
 arch/arm64/kvm/hyp/Makefile                        |   2 +-
 arch/arm64/kvm/hyp/fpsimd.S                        |   6 -
 arch/arm64/kvm/hyp/hyp-constants.c                 |  10 +
 arch/arm64/kvm/hyp/include/hyp/switch.h            |  30 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h      |   6 +
 arch/arm64/kvm/hyp/include/nvhe/mm.h               |  59 --
 arch/arm64/kvm/hyp/nvhe/early_alloc.c              |   5 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |   8 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c              | 505 ++++++++++--
 arch/arm64/kvm/hyp/nvhe/mm.c                       |   4 +-
 arch/arm64/kvm/hyp/nvhe/page_alloc.c               |   2 +-
 arch/arm64/kvm/hyp/nvhe/setup.c                    |  25 +-
 arch/arm64/kvm/hyp/nvhe/switch.c                   |   1 -
 arch/arm64/kvm/hyp/pgtable.c                       | 108 ++-
 arch/arm64/kvm/hyp/vhe/switch.c                    |   1 -
 arch/arm64/kvm/mmu.c                               | 150 +++-
 arch/arm64/kvm/{hyp/reserved_mem.c => pkvm.c}      |   8 +-
 arch/arm64/kvm/pmu-emul.c                          |   1 +
 arch/arm64/kvm/psci.c                              |   2 +-
 arch/arm64/kvm/reset.c                             |  28 +-
 arch/arm64/kvm/vgic/vgic-init.c                    |   2 +-
 arch/arm64/kvm/vgic/vgic-mmio-v3.c                 |   8 +-
 arch/arm64/kvm/vgic/vgic-mmio.c                    |   2 +-
 arch/arm64/kvm/vgic/vgic-mmio.h                    |   2 +-
 arch/arm64/kvm/vgic/vgic-v2.c                      |   9 +-
 arch/arm64/kvm/vgic/vgic-v3.c                      |   6 +-
 include/kvm/arm_vgic.h                             |   4 +-
 include/linux/kvm_host.h                           |   1 -
 tools/testing/selftests/kvm/.gitignore             |   1 +
 tools/testing/selftests/kvm/Makefile               |   1 +
 tools/testing/selftests/kvm/aarch64/arch_timer.c   |   2 +-
 tools/testing/selftests/kvm/aarch64/get-reg-list.c |  50 ++
 tools/testing/selftests/kvm/aarch64/vgic_irq.c     | 853 +++++++++++++++++++++
 tools/testing/selftests/kvm/include/aarch64/gic.h  |  26 +
 .../kvm/{lib => include}/aarch64/gic_v3.h          |  12 +
 .../selftests/kvm/include/aarch64/processor.h      |   3 +
 tools/testing/selftests/kvm/include/aarch64/vgic.h |  18 +-
 tools/testing/selftests/kvm/include/kvm_util.h     |  20 +-
 tools/testing/selftests/kvm/lib/aarch64/gic.c      |  66 ++
 .../selftests/kvm/lib/aarch64/gic_private.h        |  11 +
 tools/testing/selftests/kvm/lib/aarch64/gic_v3.c   | 206 ++++-
 .../testing/selftests/kvm/lib/aarch64/processor.c  |  82 +-
 tools/testing/selftests/kvm/lib/aarch64/vgic.c     | 103 ++-
 tools/testing/selftests/kvm/lib/guest_modes.c      |  49 +-
 tools/testing/selftests/kvm/lib/kvm_util.c         |  94 +++
 60 files changed, 2532 insertions(+), 385 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_pkvm.h
 create mode 100644 arch/arm64/kvm/.gitignore
 create mode 100644 arch/arm64/kvm/hyp/hyp-constants.c
 rename arch/arm64/kvm/{hyp/reserved_mem.c => pkvm.c} (94%)
 create mode 100644 tools/testing/selftests/kvm/aarch64/vgic_irq.c
 rename tools/testing/selftests/kvm/{lib => include}/aarch64/gic_v3.h (80%)


From michael at walle.cc  Fri Jan  7 03:47:53 2022
From: michael at walle.cc (Michael Walle)
Date: Fri, 07 Jan 2022 12:47:53 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
Message-ID: <4ed84dc354eee36067ade567097ddd68@walle.cc>

Hi Rouven,

Am 2022-01-07 10:46, schrieb Rouven Czerwinski:
> .. since AFAIK i.MX8M* can not be run without TF-A.

Are you sure? There probably aren't any boards out there
without TF-A, but why shouldn't it work without it?

-michael


From pali at kernel.org  Fri Jan  7 03:50:53 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 12:50:53 +0100
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <874k6gvkhz.wl-maz@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
 <20220106162047.vqykmygs75eimfgy@pali>
 <877dbcvngf.wl-maz@kernel.org> <20220106182044.3ff0828c@thinkpad>
 <874k6gvkhz.wl-maz@kernel.org>
Message-ID: <20220107115053.k5d2uv7yrftrpcez@pali>

On Thursday 06 January 2022 17:31:36 Marc Zyngier wrote:
> On Thu, 06 Jan 2022 17:20:44 +0000,
> Marek Beh?n <kabel at kernel.org> wrote:
> > 
> > On Thu, 06 Jan 2022 16:27:44 +0000
> > Marc Zyngier <maz at kernel.org> wrote:
> > > You are completely missing my point. I'm talking about data
> > > structures, you're talking about interrupts. You have this:
> > > 
> > > struct mvebu_pcie_port {
> > >        // Tons of stuff
> > >        struct irq_chip intx_chip;
> > > };
> > > 
> > > What I want you to do is:
> > > 
> > > struct mvebu_pcie_port {
> > >        // Tons of stuff
> > > };
> > > 
> > > static struct irq_chip intx_chip = {
> > > 	.name		= "INTx",
> > > 	.irq_mask	= mvebu_pcie_intx_irq_mask,
> > > 	.irq_unmask	= mvebu_pcie_intx_irq_unmask;
> > > };
> > > 
> > > That's it. No more, no less.
> > > 
> > > 	M.
> > > 
> > 
> > Hmm, but struct irq_chip contains a dynamic member,
> >   struct device *parent_device;
> > Isn't that used? Or are you planning to kill it?
> 
> Indeed, and I am definitely planning to kill it. This is the wrong
> place for this stuff, and I want it gone. There are thankfully very
> few users of this misfeature.

Ok, so what about this change?

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 1e90ab888075..5c816338a569 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -54,9 +54,10 @@
 	 PCIE_CONF_ADDR_EN)
 #define PCIE_CONF_DATA_OFF	0x18fc
 #define PCIE_INT_CAUSE_OFF	0x1900
+#define PCIE_INT_UNMASK_OFF	0x1910
+#define  PCIE_INT_INTX(i)		BIT(24+i)
 #define  PCIE_INT_PM_PME		BIT(28)
-#define PCIE_MASK_OFF		0x1910
-#define  PCIE_MASK_ENABLE_INTS          0x0f000000
+#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
 #define PCIE_CTRL_OFF		0x1a00
 #define  PCIE_CTRL_X1_MODE		0x0001
 #define  PCIE_CTRL_RC_MODE		BIT(1)
@@ -110,6 +111,9 @@ struct mvebu_pcie_port {
 	struct mvebu_pcie_window iowin;
 	u32 saved_pcie_stat;
 	struct resource regs;
+	struct irq_domain *intx_irq_domain;
+	raw_spinlock_t irq_lock;
+	int intx_irq;
 };
 
 static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
@@ -235,7 +239,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, lnkcap, cmd, dev_rev, mask;
+	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
@@ -288,10 +292,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	/* Point PCIe unit MBUS decode windows to DRAM space. */
 	mvebu_pcie_setup_wins(port);
 
-	/* Enable interrupt lines A-D. */
-	mask = mvebu_readl(port, PCIE_MASK_OFF);
-	mask |= PCIE_MASK_ENABLE_INTS;
-	mvebu_writel(port, mask, PCIE_MASK_OFF);
+	/* Mask all interrupt sources. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+	/* Clear all interrupt causes. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+	if (port->intx_irq <= 0) {
+		/*
+		 * When neither "summary" interrupt, nor "intx" interrupt was
+		 * specified in DT then unmask all legacy INTx interrupts as in
+		 * this case driver does not provide a way for masking and
+		 * unmasking of individual legacy INTx interrupts. In this case
+		 * all interrupts, including legacy INTx are reported via one
+		 * shared GIC source and therefore kernel cannot distinguish
+		 * which individual legacy INTx was triggered. These interrupts
+		 * are shared, so it should not cause any issue. Just
+		 * performance penalty as every PCIe interrupt handler needs to
+		 * be called when some interrupt is triggered.
+		 */
+		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
+			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
+		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	}
 }
 
 static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
@@ -924,6 +948,108 @@ static struct pci_ops mvebu_pcie_ops = {
 	.write = mvebu_pcie_wr_conf,
 };
 
+static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask &= ~PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask |= PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static struct irq_chip intx_irq_chip = {
+	.name = "mvebu-INTx",
+	.irq_mask = mvebu_pcie_intx_irq_mask,
+	.irq_unmask = mvebu_pcie_intx_irq_unmask,
+};
+
+static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
+				   unsigned int virq, irq_hw_number_t hwirq)
+{
+	struct mvebu_pcie_port *port = h->host_data;
+
+	irq_set_status_flags(virq, IRQ_LEVEL);
+	irq_set_chip_and_handler(virq, &intx_irq_chip, handle_level_irq);
+	irq_set_chip_data(virq, port);
+
+	return 0;
+}
+
+static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
+	.map = mvebu_pcie_intx_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
+{
+	struct device *dev = &port->pcie->pdev->dev;
+	struct device_node *pcie_intc_node;
+
+	raw_spin_lock_init(&port->irq_lock);
+
+	pcie_intc_node = of_get_next_child(port->dn, NULL);
+	if (!pcie_intc_node) {
+		dev_err(dev, "No PCIe Intc node found for %s\n", port->name);
+		return -ENODEV;
+	}
+
+	port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+						      &mvebu_pcie_intx_irq_domain_ops,
+						      port);
+	of_node_put(pcie_intc_node);
+	if (!port->intx_irq_domain) {
+		dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void mvebu_pcie_irq_handler(struct irq_desc *desc)
+{
+	struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct device *dev = &port->pcie->pdev->dev;
+	u32 cause, unmask, status;
+	int i;
+
+	chained_irq_enter(chip, desc);
+
+	cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	status = cause & unmask;
+
+	/* Process legacy INTx interrupts */
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		if (!(status & PCIE_INT_INTX(i)))
+			continue;
+
+		if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL)
+			dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A');
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
 static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	/* Interrupt support on mvebu emulated bridges is not implemented yet */
@@ -1121,6 +1247,21 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 		port->io_attr = -1;
 	}
 
+	/*
+	 * Old DT bindings do not contain "intx" interrupt
+	 * so do not fail probing driver when interrupt does not exist.
+	 */
+	port->intx_irq = of_irq_get_byname(child, "intx");
+	if (port->intx_irq == -EPROBE_DEFER) {
+		ret = port->intx_irq;
+		goto err;
+	}
+	if (port->intx_irq <= 0) {
+		dev_warn(dev, "%s: legacy INTx interrupts cannot be masked individually, "
+			      "%pOF does not contain intx interrupt\n",
+			 port->name, child);
+	}
+
 	reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags);
 	if (reset_gpio == -EPROBE_DEFER) {
 		ret = reset_gpio;
@@ -1317,6 +1458,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		child = port->dn;
 		if (!child)
@@ -1344,6 +1486,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (irq > 0) {
+			ret = mvebu_pcie_init_irq_domain(port);
+			if (ret) {
+				dev_err(dev, "%s: cannot init irq domain\n",
+					port->name);
+				pci_bridge_emul_cleanup(&port->bridge);
+				devm_iounmap(dev, port->base);
+				port->base = NULL;
+				mvebu_pcie_powerdown(port);
+				continue;
+			}
+			irq_set_chained_handler_and_data(irq,
+							 mvebu_pcie_irq_handler,
+							 port);
+		}
+
 		/*
 		 * PCIe topology exported by mvebu hw is quite complicated. In
 		 * reality has something like N fully independent host bridges
@@ -1448,6 +1606,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		if (!port->base)
 			continue;
@@ -1458,7 +1617,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 		mvebu_writel(port, cmd, PCIE_CMD_OFF);
 
 		/* Mask all interrupt sources. */
-		mvebu_writel(port, 0, PCIE_MASK_OFF);
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+		/* Clear all interrupt causes. */
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+		/* Remove IRQ domains. */
+		if (port->intx_irq_domain)
+			irq_domain_remove(port->intx_irq_domain);
+
+		if (irq > 0)
+			irq_set_chained_handler_and_data(irq, NULL, NULL);
 
 		/* Free config space for emulated root bridge. */
 		pci_bridge_emul_cleanup(&port->bridge);
-- 
2.20.1



From tinghan.shen at mediatek.com  Fri Jan  7 03:53:42 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Fri, 7 Jan 2022 19:53:42 +0800
Subject: [PATCH v8 1/4] dt-bindings: arm: mediatek: Add mt8195 pericfg
 compatible
In-Reply-To: <20220107115345.9075-1-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
Message-ID: <20220107115345.9075-2-tinghan.shen@mediatek.com>

Add mt8195 pericfg compatible to binding document.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
index 8723dfe34bab..611f666f359d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
@@ -26,6 +26,7 @@ properties:
               - mediatek,mt8135-pericfg
               - mediatek,mt8173-pericfg
               - mediatek,mt8183-pericfg
+              - mediatek,mt8195-pericfg
               - mediatek,mt8516-pericfg
           - const: syscon
       - items:
-- 
2.18.0



From tinghan.shen at mediatek.com  Fri Jan  7 03:53:43 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Fri, 7 Jan 2022 19:53:43 +0800
Subject: [PATCH v8 2/4] dt-bindings: arm: cpus: Add cortex-a78 compatible
In-Reply-To: <20220107115345.9075-1-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
Message-ID: <20220107115345.9075-3-tinghan.shen@mediatek.com>

Add ARM cpu type cortex-a78.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 Documentation/devicetree/bindings/arm/cpus.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml
index f2ab6423b4af..452bfd1d4ecc 100644
--- a/Documentation/devicetree/bindings/arm/cpus.yaml
+++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -137,6 +137,7 @@ properties:
       - arm,cortex-a75
       - arm,cortex-a76
       - arm,cortex-a77
+      - arm,cortex-a78
       - arm,cortex-m0
       - arm,cortex-m0+
       - arm,cortex-m1
-- 
2.18.0



From tinghan.shen at mediatek.com  Fri Jan  7 03:53:41 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Fri, 7 Jan 2022 19:53:41 +0800
Subject: [PATCH v8 0/4] Add basic SoC support for mediatek mt8195
Message-ID: <20220107115345.9075-1-tinghan.shen@mediatek.com>

This series adds basic SoC support for Mediatek's SoC MT8195.

---
Changes in v8:
  - v7 mediatek,spi-mtk-nor.yaml patch is applied in branch for-5.17 at 
    kernel/git/broonie/spi.git
  - v7 pinctrl-mt8195.yaml patch is applied in branch for-next at 
    kernel/git/linusw/linux-pinctrl.git
  - add cortex-a78 compatible to cpus dt-bindings
  - add mediatek,drive-strength-adv property to pinctrl dt-bindings
  - fix evb dts
    - remove i2c nodes with disabled status from dts
    - fix pin properties not match pinctrl dt-bindings
    - remove unnecessary u3port*
  - fix dtsi
    - fix node format
    - reorder oscillator* nodes 
    - fix node name of cpu idle nodes
    - remove clock-frequency property in the timer node
    - reorder clock and clock names in usb nodes
Changes in v7:
  - refine title of spi-nor dt-bindings patch
  - refine commit message of pinctrl dt-bindings patch
  - update pinctrl-mt8195.yaml
    - change property pattern from 'pins' to '^pins'
    - update examples with new property in descriptions
    - add new example
  - drop '_' from node names of pinctrl subnodes in mt8195-evb.dts
Changes in v6:
  - rebase on 5.16-rc1
  - add new clock name to spi-nor dt-bindings
  - add "pins" property in pinctrl dt-bindings
  - fix fails of dtbs_checks
    - remove "arm,armv8" not matched in yaml from cpu compatile
    - fix node name of xhci
    - remvoe xhci upstreaming wakeup properties
    - remove xhci unused properties address-cells and size-cells
    - fix node name of ufs-phy 
    - fix node name of spi-nor
    - fix node name and sub-nodes of pinctrl
    - fix mmc compatible
Changes in v5:
  - enable basic nodes in mt8195-evb.dts
  - remove dedicated clock nodes
  - add mmc2 node
  - fix interrupt number of pinctrl node
  - update clock nodes to apply internal fixes
  - add dt-bindings for perficfg node

v4 thread:
https://lore.kernel.org/all/20210922093303.23720-2-seiya.wang at mediatek.com/
v3 thread:
https://lore.kernel.org/all/20210601075350.31515-2-seiya.wang at mediatek.com/
v2 thread:
https://lore.kernel.org/all/20210319023427.16711-10-seiya.wang at mediatek.com/
v1 thread:
https://lore.kernel.org/all/20210316111443.3332-11-seiya.wang at mediatek.com/
---

Tinghan Shen (4):
  dt-bindings: arm: mediatek: Add mt8195 pericfg compatible
  dt-bindings: arm: cpus: Add cortex-a78 compatible
  dt-bindings: pinctrl: mt8195: Add mediatek,drive-strength-adv property
  arm64: dts: Add mediatek SoC mt8195 and evaluation board

 .../devicetree/bindings/arm/cpus.yaml         |    1 +
 .../arm/mediatek/mediatek,pericfg.yaml        |    1 +
 .../bindings/pinctrl/pinctrl-mt8195.yaml      |   35 +
 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts   |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 1049 +++++++++++++++++
 6 files changed, 1248 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

-- 
2.18.0



From tinghan.shen at mediatek.com  Fri Jan  7 03:53:45 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Fri, 7 Jan 2022 19:53:45 +0800
Subject: [PATCH v8 4/4] arm64: dts: Add mediatek SoC mt8195 and evaluation
 board
In-Reply-To: <20220107115345.9075-1-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
Message-ID: <20220107115345.9075-5-tinghan.shen@mediatek.com>

Add basic chip support for mediatek mt8195.

Signed-off-by: Seiya Wang <seiya.wang at mediatek.com>
Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 1049 +++++++++++++++++++
 3 files changed, 1211 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 4f68ebed2e31..7aa08bb4c078 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -32,4 +32,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
new file mode 100644
index 000000000000..51633d91d984
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+/dts-v1/;
+#include "mt8195.dtsi"
+
+/ {
+	model = "MediaTek MT8195 evaluation board";
+	compatible = "mediatek,mt8195-evb", "mediatek,mt8195";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pin>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&nor_flash {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&pio {
+	i2c0_pin: i2c0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+				 <PINMUX_GPIO9__FUNC_SCL0>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c1_pin: i2c1-pins {
+		pins {
+			pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+				 <PINMUX_GPIO11__FUNC_SCL1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c4_pin: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <7>;
+		};
+	};
+
+	i2c6_pin: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	i2c7_pin: i2c7-pins {
+		pins {
+			pinmux = <PINMUX_GPIO27__FUNC_SCL7>,
+				 <PINMUX_GPIO28__FUNC_SDA7>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	nor_pins_default: nor-pins {
+		pins0 {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			bias-pull-down;
+		};
+
+		pins1 {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>,
+				 <PINMUX_GPIO130__FUNC_SPINOR_IO2>,
+				 <PINMUX_GPIO131__FUNC_SPINOR_IO3>;
+			bias-pull-up;
+		};
+	};
+
+	uart0_pin: uart0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+				 <PINMUX_GPIO99__FUNC_URXD0>;
+		};
+	};
+};
+
+&u2port0 {
+	status = "okay";
+};
+
+&u2port1 {
+	status = "okay";
+};
+
+&u3phy0 {
+	status="okay";
+};
+
+&u3phy1 {
+	status="okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pin>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
new file mode 100644
index 000000000000..1c708fe65828
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/reset/ti-syscon.h>
+
+/ {
+	compatible = "mediatek,mt8195";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x000>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x400>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x500>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu6: cpu at 600 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x600>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu7: cpu at 700 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x700>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_off_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <95>;
+				min-residency-us = <580>;
+			};
+
+			cpu_off_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <45>;
+				exit-latency-us = <140>;
+				min-residency-us = <740>;
+			};
+
+			cluster_off_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <55>;
+				exit-latency-us = <155>;
+				min-residency-us = <840>;
+			};
+
+			cluster_off_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <200>;
+				min-residency-us = <1000>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH 0>;
+		cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
+		       <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "clk32k";
+	};
+
+	pmu-a55 {
+		compatible = "arm,cortex-a55-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>;
+	};
+
+	pmu-a78 {
+		compatible = "arm,cortex-a78-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <4>;
+			#redistributor-regions = <1>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,
+			      <0 0x0c040000 0 0x200000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+
+			ppi-partitions {
+				ppi_cluster0: interrupt-partition-0 {
+					affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+
+				ppi_cluster1: interrupt-partition-1 {
+					affinity = <&cpu4 &cpu5 &cpu6 &cpu7>;
+				};
+			};
+		};
+
+		topckgen: syscon at 10000000 {
+			compatible = "mediatek,mt8195-topckgen", "syscon";
+			reg = <0 0x10000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		infracfg_ao: syscon at 10001000 {
+			compatible = "mediatek,mt8195-infracfg_ao", "syscon", "simple-mfd";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+
+			infracfg_rst: reset-controller {
+				compatible = "ti,syscon-reset";
+				#reset-cells = <1>;
+				ti,reset-bits = <
+					0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* pcie */
+					0x120 0  0x124 0  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x730 10 0x734 10 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x150 5  0x154 5  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* svs gpu */
+				>;
+			};
+		};
+
+		pericfg: syscon at 10003000 {
+			compatible = "mediatek,mt8195-pericfg", "syscon";
+			reg = <0 0x10003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl at 10005000 {
+			compatible = "mediatek,mt8195-pinctrl";
+			reg = <0 0x10005000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>,
+			      <0 0x11d30000 0 0x1000>,
+			      <0 0x11d40000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11eb0000 0 0x1000>,
+			      <0 0x11f40000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "iocfg0", "iocfg_bm", "iocfg_bl",
+				    "iocfg_br", "iocfg_lm", "iocfg_rb",
+				    "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 144>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH 0>;
+			#interrupt-cells = <2>;
+		};
+
+		watchdog: watchdog at 10007000 {
+			compatible = "mediatek,mt8195-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x10007000 0 0x100>;
+		};
+
+		apmixedsys: syscon at 1000c000 {
+			compatible = "mediatek,mt8195-apmixedsys", "syscon";
+			reg = <0 0x1000c000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		systimer: timer at 10017000 {
+			compatible = "mediatek,mt8195-timer",
+				     "mediatek,mt6765-timer";
+			reg = <0 0x10017000 0 0x1000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_CLK26M_D2>;
+		};
+
+		pwrap: pwrap at 10024000 {
+			compatible = "mediatek,mt8195-pwrap", "syscon";
+			reg = <0 0x10024000 0 0x1000>;
+			reg-names = "pwrap";
+			interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_PMIC_AP>,
+				 <&infracfg_ao CLK_INFRA_AO_PMIC_TMR>;
+			clock-names = "spi", "wrap";
+			assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC>;
+			assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
+		};
+
+		scp_adsp: clock-controller at 10720000 {
+			compatible = "mediatek,mt8195-scp_adsp";
+			reg = <0 0x10720000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		uart0: serial at 11001100 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001100 0 0x100>;
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART0>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart1: serial at 11001200 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001200 0 0x100>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART1>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart2: serial at 11001300 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001300 0 0x100>;
+			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART2>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart3: serial at 11001400 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001400 0 0x100>;
+			interrupts = <GIC_SPI 723 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART3>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart4: serial at 11001500 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001500 0 0x100>;
+			interrupts = <GIC_SPI 724 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART4>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart5: serial at 11001600 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001600 0 0x100>;
+			interrupts = <GIC_SPI 725 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART5>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		auxadc: auxadc at 11002000 {
+			compatible = "mediatek,mt8195-auxadc",
+				     "mediatek,mt8173-auxadc";
+			reg = <0 0x11002000 0 0x1000>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_AUXADC>;
+			clock-names = "main";
+			#io-channel-cells = <1>;
+			status = "disabled";
+		};
+
+		pericfg_ao: syscon at 11003000 {
+			compatible = "mediatek,mt8195-pericfg_ao", "syscon";
+			reg = <0 0x11003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		spi0: spi at 1100a000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI0>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi1: spi at 11010000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11010000 0 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI1>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi2: spi at 11012000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11012000 0 0x1000>;
+			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI2>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi3: spi at 11013000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11013000 0 0x1000>;
+			interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI3>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi4: spi at 11018000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11018000 0 0x1000>;
+			interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI4>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi5: spi at 11019000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11019000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI5>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spis0: spi at 1101d000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101d000 0 0x1000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS0>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		spis1: spi at 1101e000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101e000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS1>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		xhci0: usb at 11200000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11200000 0 0x1000>,
+			      <0 0x11203e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port0 PHY_TYPE_USB2>,
+			       <&u3port0 PHY_TYPE_USB3>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
+				 <&topckgen CLK_TOP_SSUSB_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11230000 0 0x10000>,
+			      <0 0x11f50000 0 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC50_0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			status = "disabled";
+		};
+
+		mmc1: mmc at 11240000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11240000 0 0x1000>,
+			      <0 0x11c70000 0 0x1000>;
+			interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_1>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		mmc2: mmc at 11250000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11250000 0 0x1000>,
+			      <0 0x11e60000 0 0x1000>;
+			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG1_MSDC2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG3_MSDC2>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_2>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		xhci1: usb at 11290000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11290000 0 0x1000>,
+			      <0 0x11293e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port1 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_1P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_1P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_1P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P1_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_1P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck","xhci_ck";
+			status = "disabled";
+		};
+
+		xhci2: usb at 112a0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112a0000 0 0x1000>,
+			      <0 0x112a3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port2 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_2P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_2P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_2P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P2_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		xhci3: usb at 112b0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112b0000 0 0x1000>,
+			      <0 0x112b3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port3 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_3P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_3P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_3P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P3_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			/* This controller is connected with a BT device.
+                         * Disable usb2 lpm to prevent konwn issues.
+                         */
+			usb2-lpm-disable;
+			status = "disabled";
+		};
+
+		nor_flash: spi at 1132c000 {
+			compatible = "mediatek,mt8195-nor",
+				     "mediatek,mt8173-nor";
+			reg = <0 0x1132c000 0 0x1000>;
+			interrupts = <GIC_SPI 825 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_SPINOR>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_FLASH>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_BUS>;
+			clock-names = "spi", "sf", "axi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		u3phy2: t-phy at 11c40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c40000 0x700>;
+			status = "disabled";
+
+			u2port2: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P2_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy3: t-phy at 11c50000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c50000 0x700>;
+			status = "disabled";
+
+			u2port3: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P3_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		i2c5: i2c at 11d00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d00000 0 0x1000>,
+			      <0 0x10220580 0 0x80>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C5>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c6: i2c at 11d01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d01000 0 0x1000>,
+			      <0 0x10220600 0 0x80>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C6>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c7: i2c at 11d02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d02000 0 0x1000>,
+			      <0 0x10220680 0 0x80>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_s: clock-controller at 11d03000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_s";
+			reg = <0 0x11d03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		i2c0: i2c at 11e00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e00000 0 0x1000>,
+			      <0 0x10220080 0 0x80>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C0>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+		};
+
+		i2c1: i2c at 11e01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e01000 0 0x1000>,
+			      <0 0x10220200 0 0x80>;
+			interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C1>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at 11e02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e02000 0 0x1000>,
+			      <0 0x10220380 0 0x80>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C2>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at 11e03000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e03000 0 0x1000>,
+			      <0 0x10220480 0 0x80>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C3>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at 11e04000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e04000 0 0x1000>,
+			      <0 0x10220500 0 0x80>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C4>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_w: clock-controller at 11e05000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_w";
+			reg = <0 0x11e05000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		u3phy1: t-phy at 11e30000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e30000 0xe00>;
+			status = "disabled";
+
+			u2port1: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port1: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy0: t-phy at 11e40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e40000 0xe00>;
+			status = "disabled";
+
+			u2port0: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port0: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		ufsphy: ufs-phy at 11fa0000 {
+			compatible = "mediatek,mt8195-ufsphy", "mediatek,mt8183-ufsphy";
+			reg = <0 0x11fa0000 0 0xc000>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "unipro", "mp";
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		mfgcfg: clock-controller at 13fbf000 {
+			compatible = "mediatek,mt8195-mfgcfg";
+			reg = <0 0x13fbf000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys: clock-controller at 14e00000 {
+			compatible = "mediatek,mt8195-wpesys";
+			reg = <0 0x14e00000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp0: clock-controller at 14e02000 {
+			compatible = "mediatek,mt8195-wpesys_vpp0";
+			reg = <0 0x14e02000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp1: clock-controller at 14e03000 {
+			compatible = "mediatek,mt8195-wpesys_vpp1";
+			reg = <0 0x14e03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys: clock-controller at 15000000 {
+			compatible = "mediatek,mt8195-imgsys";
+			reg = <0 0x15000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_top: clock-controller at 15110000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_top";
+			reg = <0 0x15110000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_nr: clock-controller at 15130000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_nr";
+			reg = <0 0x15130000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_wpe: clock-controller at 15220000 {
+			compatible = "mediatek,mt8195-imgsys1_wpe";
+			reg = <0 0x15220000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ipesys: clock-controller at 15330000 {
+			compatible = "mediatek,mt8195-ipesys";
+			reg = <0 0x15330000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys: clock-controller at 16000000 {
+			compatible = "mediatek,mt8195-camsys";
+			reg = <0 0x16000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawa: clock-controller at 1604f000 {
+			compatible = "mediatek,mt8195-camsys_rawa";
+			reg = <0 0x1604f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuva: clock-controller at 1606f000 {
+			compatible = "mediatek,mt8195-camsys_yuva";
+			reg = <0 0x1606f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawb: clock-controller at 1608f000 {
+			compatible = "mediatek,mt8195-camsys_rawb";
+			reg = <0 0x1608f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuvb: clock-controller at 160af000 {
+			compatible = "mediatek,mt8195-camsys_yuvb";
+			reg = <0 0x160af000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_mraw: clock-controller at 16140000 {
+			compatible = "mediatek,mt8195-camsys_mraw";
+			reg = <0 0x16140000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ccusys: clock-controller at 17200000 {
+			compatible = "mediatek,mt8195-ccusys";
+			reg = <0 0x17200000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_soc: clock-controller at 1800f000 {
+			compatible = "mediatek,mt8195-vdecsys_soc";
+			reg = <0 0x1800f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys: clock-controller at 1802f000 {
+			compatible = "mediatek,mt8195-vdecsys";
+			reg = <0 0x1802f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_core1: clock-controller at 1803f000 {
+			compatible = "mediatek,mt8195-vdecsys_core1";
+			reg = <0 0x1803f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		apusys_pll: clock-controller at 190f3000 {
+			compatible = "mediatek,mt8195-apusys_pll";
+			reg = <0 0x190f3000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys: clock-controller at 1a000000 {
+			compatible = "mediatek,mt8195-vencsys";
+			reg = <0 0x1a000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys_core1: clock-controller at 1b000000 {
+			compatible = "mediatek,mt8195-vencsys_core1";
+			reg = <0 0x1b000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+	};
+};
-- 
2.18.0



From tinghan.shen at mediatek.com  Fri Jan  7 03:53:44 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Fri, 7 Jan 2022 19:53:44 +0800
Subject: [PATCH v8 3/4] dt-bindings: pinctrl: mt8195: Add mediatek,
 drive-strength-adv property
In-Reply-To: <20220107115345.9075-1-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
Message-ID: <20220107115345.9075-4-tinghan.shen@mediatek.com>

Extend pin driving support for I2C pins on SoC mt8195.
This property is also documented in mediatek,mt8183-pinctrl.yaml.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
---
 .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
index 567f71cab7b4..5e27e01d6588 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
@@ -98,6 +98,32 @@ patternProperties:
           drive-strength:
             enum: [2, 4, 6, 8, 10, 12, 14, 16]
 
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
           bias-pull-down:
             description: |
               For pull down type is normal, it don't need add RSEL & R1R0 define
@@ -265,4 +291,13 @@ examples:
           bias-pull-down;
         };
       };
+
+      i2c0-pins {
+        pins {
+          pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+                   <PINMUX_GPIO9__FUNC_SCL0>;
+          bias-disable;
+          mediatek,drive-strength-adv = <7>;
+        };
+      };
     };
-- 
2.18.0



From r.czerwinski at pengutronix.de  Fri Jan  7 03:55:34 2022
From: r.czerwinski at pengutronix.de (Rouven Czerwinski)
Date: Fri, 07 Jan 2022 12:55:34 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <AM6PR06MB46919E01996D1F1DE326306DA64D9@AM6PR06MB4691.eurprd06.prod.outlook.com>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
 <AM6PR06MB46919E01996D1F1DE326306DA64D9@AM6PR06MB4691.eurprd06.prod.outlook.com>
Message-ID: <b5e37dc573f9cefc83f73f1113a632a29ba9a833.camel@pengutronix.de>

On Fri, 2022-01-07 at 10:40 +0000, ZHIZHIKIN Andrey wrote:
> Hello Rouven,
> 
> > -----Original Message-----
> > From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> > Sent: Friday, January 7, 2022 10:46 AM
> > To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> > kernel at vger.kernel.org
> > Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> > krzk at kernel.org; leonard.crestez at nxp.com; festevam at gmail.com; marex at denx.de;
> > herbert at gondor.apana.org.au; horia.geanta at nxp.com; daniel.baluta at nxp.com;
> > frieder.schrempf at kontron.de; linux-imx at nxp.com; devicetree at vger.kernel.org;
> > hongxing.zhu at nxp.com; s.hauer at pengutronix.de; pankaj.gupta at nxp.com;
> > robh+dt at kernel.org; thunder.leizhen at huawei.com; martink at posteo.de;
> > aford173 at gmail.com; linux-arm-kernel at lists.infradead.org;
> > gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> > michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-crypto at vger.kernel.org;
> > kernel at pengutronix.de; l.stach at pengutronix.de; shawnguo at kernel.org;
> > davem at davemloft.net; jun.li at nxp.com
> > Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
> > 
> > 
> > On Thu, 2022-01-06 at 14:08 +0000, ZHIZHIKIN Andrey wrote:
> > > Hello Rouven,
> > > 
> > > > -----Original Message-----
> > > > From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> > > > Sent: Thursday, January 6, 2022 12:27 PM
> > > > To: ZHIZHIKIN Andrey <andrey.zhizhikin at leica-geosystems.com>; linux-
> > > > kernel at vger.kernel.org
> > > > Cc: peng.fan at nxp.com; ping.bai at nxp.com; alice.guo at nxp.com; agx at sigxcpu.org;
> > > > frieder.schrempf at kontron.de; leonard.crestez at nxp.com; festevam at gmail.com;
> > > > marex at denx.de; herbert at gondor.apana.org.au; horia.geanta at nxp.com;
> > > > aford173 at gmail.com; krzk at kernel.org; linux-imx at nxp.com;
> > > > devicetree at vger.kernel.org; hongxing.zhu at nxp.com; s.hauer at pengutronix.de;
> > > > pankaj.gupta at nxp.com; robh+dt at kernel.org; thunder.leizhen at huawei.com;
> > > > martink at posteo.de; daniel.baluta at nxp.com; linux-arm-
> > kernel at lists.infradead.org;
> > > > gregkh at linuxfoundation.org; shengjiu.wang at nxp.com; qiangqing.zhang at nxp.com;
> > > > michael at walle.cc; op-tee at lists.trustedfirmware.org; linux-
> > crypto at vger.kernel.org;
> > > > kernel at pengutronix.de; jun.li at nxp.com; shawnguo at kernel.org;
> > davem at davemloft.net;
> > > > l.stach at pengutronix.de
> > > > Subject: Re: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam
> > jr
> > > > 
> > > > Hi Andrey,
> > > > 
> > > > On Wed, 2021-12-08 at 00:02 +0100, Andrey Zhizhikin wrote:
> > > > > CAAM JR nodes are configured by BootROM and are used by various software
> > > > > entities during the boot process before they reach the Kernel.
> > > > > 
> > > > > Default BootROM configuration have JR0 and JR1 reserved for S-only
> > > > > access, while JR2 is generally available for both S and NS access. HAB
> > > > > feature of i.MX8M family does require that JR0 is reserved exclusively
> > > > > in S-only world, while JR1 and JR2 are both released to NS-World. OP-TEE
> > > > > can later reclaim the JR2 via dt_enable_secure_status() call, and modify
> > > > > the DID to hold it in S-World only.
> > > > > 
> > > > > The above setup has been discovered during review of CAAM patchset
> > > > > presented to U-Boot integration [1], and does not correspond to the
> > > > > status on jr nodes in FDT.
> > > > > 
> > > > > This missing status settings leads to the following error message during
> > > > > jr node probing:
> > > > > [    1.509894] caam 30900000.crypto: job rings = 3, qi = 0
> > > > > [    1.525201] caam_jr 30901000.jr: failed to flush job ring 0
> > > > > [    1.525214] caam_jr: probe of 30901000.jr failed with error -5
> > > > > 
> > > > > JR register readout after BootROM execution shows the following values:
> > > > > JR0DID_MS = 0x8011
> > > > > JR1DID_MS = 0x8011
> > > > > JR2DID_MS = 0x0
> > > > > 
> > > > > This shows that JR0 and JR1 have TZ_OWN bit set, which marks them to be
> > > > > reserved for S-World, while JR2 remains accessible from NS-World.
> > > > > 
> > > > > Provide the correct status for JR nodes in imx8m derivatives, which have
> > > > > a following meaning:
> > > > > - JR0: S-only
> > > > > - JR1: visible in both
> > > > > - JR2: NS-only
> > > > > 
> > > > > Note, that JR2 is initially marked to be NS-only which does correspond
> > > > > to DID readout when OP-TEE is not present. Once present, OP-TEE will
> > > > > reclaim the JR2 and set both "status" and "secure-status" to claim JR2
> > > > > for S-only access.
> > > > 
> > > > While I can understand that you want to fix your use case for when HAB
> > > > is enabled, note that this is disabling JR0 in the none-HAB case as
> > > > well.
> > > 
> > > This is not totally correct, as this patch does address the reservation of
> > > JR0 by BootROM in both HAB and non-HAB configurations. My current setup does
> > > not include HAB functionality enabled, and I still do observe boot errors
> > > that are listed in commit message. This is due to the fact that the BootROM
> > > does not release JR0 to NS-World regardless of whether HAB is enabled or not.
> > > This has been discussed in the U-Boot thread I provided the link in the patch.
> > > 
> > > This patch does rather bring the correct HW module description as seeing
> > > from Linux.
> > 
> > I took a look into i.MX8MQ, the bootrom indeed sets 0x8011 for JR0 &
> > JR1:
> > JR0:0000000000008011
> > JR1:0000000000008011
> > JR2:0000000000000000
> > TF-A
> > > CAAM
> > JR0:0000000000000001
> > JR1:0000000000000001
> > JR2:0000000000000001
> > 
> > However at least the upstream TF-A reconfigures the DIDs to 1 for all
> > i.MX8M* derivates.  So while it is technically correct to change the DT
> > values as you describe, the downstream TF-A and upstream TF-A seem to
> > differ in their configuration. I also think it's a bad move to hardcode
> > the JR configuration to the boot ROM config, since AFAIK i.MX8M* can
> > not be run without TF-A. And IMO the upstream kernel should follow what
> > the upstream TF-A does in this case.
> 
> This is indeed an interesting piece of information, thanks a lot!
> 
> From what I understood in previous discussions for this series here in
> the Kernel, and on U-Boot ML: JR0 is required to be held reserved in
> S-World for HAB to operate, and this is clearly communicated by NXP in [1].
> If my understanding is correct, then upstream TF-A either does not support
> or breaks the HAB feature.

Yes, upstream TF-A does not implement the NXP specific SIPs to
communicate with the ROM code to do further image authentication.
Thats also the reason why all JRs are released to normal world, there
is no possible HAB use after TF-A has started.

> I've been following the build documentation in U-Boot, where the downstream
> TF-A is listed as build prequisites [2] without any mentioning of upstream,
> hence I received a readout that matched the BootROM "1-to-1".

Yes, since the downstream TF-A is required to authenticate further
images.

Aside from this the bootrom HAB interface on i.MX8MQ was broken in
interesting ways, I had to implement parsing of the HAB status SRAM
area by hand within barebox.

> I believe that if the information from NXP regarding JR0 reservation for
> HAB is correct (and I have no reasons to doubt it), then upstream TF-A
> should be adapted in order for HAB feature to work, and in that case this
> patch brings correct HW state description as seeing from Linux.

JR0 for HAB in S-World makes sense to me, otherwise the bootrom will
probably refuse to work with the JR.

> And in contrary, if the upstream TF-A is not adjusted to include HAB
> support - then applying this patch would effectively just "remove" one
> JR device, still keeping 2 additional available nodes for HW crypto
> operations in Kernel, with added benefit that both upstream and
> downstream TF-A can be used during the boot without seeing issues later
> in the Kernel.

Even with the downstream TF-A there is no reason to keep JR0 asigned to
the secure world, unless you are running OP-TEE. JR0 assignement for
HAB shouldn't be required after the bootloader has run, unless you want
to HAB authenticate images from a running Linux kernel.

The reason NXP hardcodes the configuration downstream is of course to
support HAB & OP-TEE, but this is still not a reason to hardcode this
assignement into the kernel device tree. They probably also hardcode it
in their downstream kernel versions.

I can understand that it seems easier to hardcode this in the kernel,
but as I said before, if you are running OP-TEE you need to adjust the
DT anyway since nodes need to be added and you might as well adjust the
jobring configuration than.

Kind regards,
Rouven

> 
> > 
> > > 
> > > > IMO this should be handled correctly by the bootloader and/or OP-
> > > > TEE. The default upstream configuration for OP-TEE is to not use the
> > > > CAAM at runtime as well, since linux runtime PM disablement of the CAAM
> > > > will lock up OP-TEE when it tries to access the CAAM.
> > > 
> > > If by handling you mean releasing JR0 reservation - then yes, it should be
> > > done by either SPL or TF-A as they do run in S World. In such a case, DTB
> > > bindings need to be adapted further according to the new state. Until this
> > > done - this patch does provide a correct state of HW to the Kernel.
> > 
> > Upstream TF-A simply releases all JRs to the normal world, matching the
> > current DTB description.
> > 
> > Kind Regards,
> > Rouven Czerwinski
> > 
> > 
> [snip]
> 
> Regards,
> Andrey
> 
> Link: [1]: https://lore.kernel.org/u-boot/VI1PR04MB5342C8C6E651EC2CC4477EB5E79A9 at VI1PR04MB5342.eurprd04.prod.outlook.com/
> Link: [2]: https://source.denx.de/u-boot/u-boot/-/blob/master/doc/board/nxp/imx8mm_evk.rst

-- 
Pengutronix e.K.           | Rouven Czerwinski          |
Steuerwalder Str. 21       | http://www.pengutronix.de/ |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0   |



From suzuki.poulose at arm.com  Fri Jan  7 03:56:46 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 7 Jan 2022 11:56:46 +0000
Subject: [PATCH V2 3/7] arm64: errata: Add detection for TRBE invalid
 prohibited states
In-Reply-To: <1641517808-5735-4-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <840a1ce6-a7c5-16f6-0366-8d93a3715b34@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
> an inconsistent view on whether trace is prohibited within the CPU. As a
> result, the trace buffer or trace buffer state might be corrupted. This
> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
> followed by just a single context synchronization event before execution
> changes from a context, in which trace is prohibited to one where it isn't,
> or vice versa. In these mentioned conditions, the view of whether trace is
> prohibited is inconsistent between parts of the CPU, and the trace buffer
> or the trace buffer state might be corrupted. This adds a new errata
> ARM64_ERRATUM_2038923 in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
>   Documentation/arm64/silicon-errata.rst |  2 ++
>   arch/arm64/Kconfig                     | 23 +++++++++++++++++++++++
>   arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
>   arch/arm64/tools/cpucaps               |  1 +
>   4 files changed, 35 insertions(+)
> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index c9b30e6c2b6c..e0ef3e9a4b8b 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -54,6 +54,8 @@ stable kernels.
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
>   +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
> ++----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
>   +----------------+-----------------+-----------------+-----------------------------+
>   | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index e27ccfe9fa9c..188eae6ef28d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
>   
>   	  If unsure, say Y.
>   
> +config ARM64_ERRATUM_2038923
> +	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
> +	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
> +	default y
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
> +
> +	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
> +	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
> +	  might be corrupted. This happens after TRBE buffer has been enabled by setting
> +	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
> +	  execution changes from a context, in which trace is prohibited to one where it
> +	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
> +	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
> +	  the trace buffer state might be corrupted.
> +
> +	  Work around this in the driver by preventing an inconsistent view of whether the
> +	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
> +	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
> +	  two ISB instructions if no ERET is to take place.
> +
> +	  If unsure, say Y.
> +
>   config CAVIUM_ERRATUM_22375
>   	bool "Cavium erratum 22375, 24313"
>   	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index cbb7d5a9aee7..60b0c1f1d912 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>   		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
>   	},
>   #endif
> +#ifdef CONFIG_ARM64_ERRATUM_2038923
> +	{
> +		.desc = "ARM erratum 2038923",
> +		.capability = ARM64_WORKAROUND_2038923,
> +
> +		/* Cortex-A510 r0p0 - r0p2 */
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
> +	},
> +#endif
>   	{
>   	}
>   };
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index fca3cb329e1d..45a06d36d080 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -56,6 +56,7 @@ WORKAROUND_1463225
>   WORKAROUND_1508412
>   WORKAROUND_1542419
>   WORKAROUND_2064142
> +WORKAROUND_2038923
>   WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>   WORKAROUND_TSB_FLUSH_FAILURE
>   WORKAROUND_TRBE_WRITE_OUT_OF_RANGE



From suzuki.poulose at arm.com  Fri Jan  7 03:58:28 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 7 Jan 2022 11:58:28 +0000
Subject: [PATCH V2 4/7] arm64: errata: Add detection for TRBE trace data
 corruption
In-Reply-To: <1641517808-5735-5-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-5-git-send-email-anshuman.khandual@arm.com>
Message-ID: <fb1fb13b-a685-ccda-f381-6e6919fdb707@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #1902691 might corrupt trace
> data or deadlock, when it's being written into the memory. So effectively
> TRBE is broken and hence cannot be used to capture trace data. This adds
> a new errata ARM64_ERRATUM_1902691 in arm64 errata framework.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   Documentation/arm64/silicon-errata.rst |  2 ++
>   arch/arm64/Kconfig                     | 18 ++++++++++++++++++
>   arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
>   arch/arm64/tools/cpucaps               |  1 +
>   4 files changed, 30 insertions(+)

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From l.stach at pengutronix.de  Fri Jan  7 03:58:58 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 07 Jan 2022 12:58:58 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <4ed84dc354eee36067ade567097ddd68@walle.cc>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
 <4ed84dc354eee36067ade567097ddd68@walle.cc>
Message-ID: <8fa36ec0a6252db4b0c7fbbf09de5e816d634206.camel@pengutronix.de>

Am Freitag, dem 07.01.2022 um 12:47 +0100 schrieb Michael Walle:
> Hi Rouven,
> 
> Am 2022-01-07 10:46, schrieb Rouven Czerwinski:
> > .. since AFAIK i.MX8M* can not be run without TF-A.
> 
> Are you sure? There probably aren't any boards out there
> without TF-A, but why shouldn't it work without it?

PSCI, i.e. the only means to start the secondary CPUs, is implemented
in TF-A, so it's very unlikely that anyone would want to run a system
without TF-A. Also quite a bit of the lowlevel SoC initialization is
implemented in TF-A.

Regards,
Lucas



From catalin.marinas at arm.com  Fri Jan  7 04:01:17 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 7 Jan 2022 12:01:17 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <Ydc+AuagOD9GSooP@sirena.org.uk>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
Message-ID: <YdgrjWVxRGRtnf5b@arm.com>

On Thu, Jan 06, 2022 at 07:07:46PM +0000, Mark Brown wrote:
> On Thu, Jan 06, 2022 at 06:13:37PM +0000, Catalin Marinas wrote:
> > On Thu, Jan 06, 2022 at 10:09:35AM -0600, Jeremy Linton wrote:
> > > This should only change the behavior for for binaries which conform to the
> > > new ABI containing the BTI note. So outside of the tiny window of things
> > > built with BTI, but run on !BTI hardware or older kernel+glibc, this
> > > shouldn't be a problem. (Unless i'm missing something) Put another way, now
> > > is the time to make a change, before there is a legacy BTI ecosystem we have
> > > to deal with.
> 
> > The concern is that the loader may decide in the future to not enable
> > (or turn off) BTI for some reason (e.g. mixed libraries, old glibc on
> > BTI hardware). If we force BTI on the main executable, we'd take this
> > option away. Note also that it's not only glibc here, there are other
> > loaders.
> 
> Neither of those examples should be concerns - BTI is per page so you
> can mix BTI and non-BTI freely in a process (as will happen now for the
> case where the dynamic loader is built for BTI but the main executable
> is not, and the dynamic loader should do if there's a mix of BTI and
> non-BTI libraries).  The main case where there might be a change would
> be the case where there's individual excutables with incorrect BTI
> annotations which are run under this seccomp MWDE, then the dynamic
> loader might have support for disabling BTI based on some configuration
> but wouldn't be able to due to the MWDE.
> 
> Note also that we're only taking the option of disabiling BTI away in
> the case where there's something like this seccomp filter disabling
> permission changes.

Thanks for the clarification. I think we can look at this from two
angles:

1. Ignoring MDWE, should whoever does the original mmap() also honour
   PROT_BTI? We do this for static binaries but, for consistency, should
   we extend it to dynamic executable?

2. A 'simple' fix to allow MDWE together with BTI.

Regarding (1), I don't remember whether we decided to do it this way
because it was more complicated to handle it in the kernel (like the 4
more patches in this series) or because we wanted to leave the option to
the dynamic loader. It would be good to clarify this and we may have a
small window, as Jeremy said, where changing the ABI won't cause
problems (well, hopefully, there's still a risk).

If we only want (2), I just think we are approaching it wrongly. Looking
at mprotect(), this systemd feature is not even MDWE but rather "deny
mprotect execute" disregarding the previous attributes. If we want this,
something like below would do (conditional on some personality flag or a
prctl):

diff --git a/mm/mprotect.c b/mm/mprotect.c
index e552f5e0ccbd..4262e6f1c14e 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -616,6 +616,11 @@ static int do_mprotect_pkey(unsigned long start, size_t len,
 			goto out;
 		}

+		if ((newflags & VM_EXEC) && !(vma->vm_flags & VM_EXEC)) {
+			error = -EACCES;
+			goto out;
+		}
+
 		/* Allow architectures to sanity-check the new flags */
 		if (!arch_validate_flags(newflags)) {
 			error = -EINVAL;

But we could also do a proper MDWE covering both mmap() and mprotect()
and keep track on whether a vma was previously writable. A personality
flag seems like a better option as we have READ_IMPLIES_EXEC, we could
add a DENY_WRITE_EXEC.

-- 
Catalin


From michael at walle.cc  Fri Jan  7 04:05:01 2022
From: michael at walle.cc (Michael Walle)
Date: Fri, 07 Jan 2022 13:05:01 +0100
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <8fa36ec0a6252db4b0c7fbbf09de5e816d634206.camel@pengutronix.de>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
 <4ed84dc354eee36067ade567097ddd68@walle.cc>
 <8fa36ec0a6252db4b0c7fbbf09de5e816d634206.camel@pengutronix.de>
Message-ID: <00e083278fb4a8c96fdef564a2183600@walle.cc>

Am 2022-01-07 12:58, schrieb Lucas Stach:
> Am Freitag, dem 07.01.2022 um 12:47 +0100 schrieb Michael Walle:
>> Hi Rouven,
>> 
>> Am 2022-01-07 10:46, schrieb Rouven Czerwinski:
>> > .. since AFAIK i.MX8M* can not be run without TF-A.
>> 
>> Are you sure? There probably aren't any boards out there
>> without TF-A, but why shouldn't it work without it?
> 
> PSCI, i.e. the only means to start the secondary CPUs, is implemented
> in TF-A, so it's very unlikely that anyone would want to run a system
> without TF-A. Also quite a bit of the lowlevel SoC initialization is
> implemented in TF-A.

Doesn't mean u-boot cannot implement PSCI; actually you doesn't need
it at all, you can still use spin tables. I just keep hearing the same
arguments for the LS1028A SoC and yet there is one board without TF-A ;)
Anyway, I admit it's rather unlikely.

-michael


From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:54 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:54 +0800
Subject: [PATCH v4 0/6] Introduce x86 assembly accelerated implementation for
 SM3 algorithm
Message-ID: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>

This series of patches creates an stand-alone library for SM3 hash
algorithm in the lib/crypto directory, and makes the implementations
that originally depended on sm3-generic depend on the stand-alone SM3
library, which also includes sm3-generic itself.

On this basis, the AVX assembly acceleration implementation of SM3
algorithm is introduced, the main algorithm implementation based on
SM3 AES/BMI2 accelerated work by libgcrypt at:
https://gnupg.org/software/libgcrypt/index.html

>From the performance benchmark data, the performance improvement of
SM3 algorithm after AVX optimization can reach up to 38%.

---
v4 changes:
 - Rebase on latest cryptodev-2.6/master
 - Fix the compilation error of arm64/sm3

v3 changes:
 - update git commit message for patch 01

v2 changes:
 - x86/sm3: Change K macros to signed decimal and use LEA and 32-bit offset

Tianjia Zhang (6):
  crypto: sm3 - create SM3 stand-alone library
  crypto: arm64/sm3-ce - make dependent on sm3 library
  crypto: sm2 - make dependent on sm3 library
  crypto: sm3 - make dependent on sm3 library
  crypto: x86/sm3 - add AVX assembly implementation
  crypto: tcrypt - add asynchronous speed test for SM3

 arch/arm64/crypto/Kconfig        |   2 +-
 arch/arm64/crypto/sm3-ce-glue.c  |  28 +-
 arch/x86/crypto/Makefile         |   3 +
 arch/x86/crypto/sm3-avx-asm_64.S | 517 +++++++++++++++++++++++++++++++
 arch/x86/crypto/sm3_avx_glue.c   | 134 ++++++++
 crypto/Kconfig                   |  16 +-
 crypto/sm2.c                     |  38 +--
 crypto/sm3_generic.c             | 142 +--------
 crypto/tcrypt.c                  |  14 +-
 include/crypto/sm3.h             |  34 +-
 lib/crypto/Kconfig               |   3 +
 lib/crypto/Makefile              |   3 +
 lib/crypto/sm3.c                 | 246 +++++++++++++++
 13 files changed, 1013 insertions(+), 167 deletions(-)
 create mode 100644 arch/x86/crypto/sm3-avx-asm_64.S
 create mode 100644 arch/x86/crypto/sm3_avx_glue.c
 create mode 100644 lib/crypto/sm3.c

-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:56 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:56 +0800
Subject: [PATCH v4 2/6] crypto: arm64/sm3-ce - make dependent on sm3 library
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-3-tianjia.zhang@linux.alibaba.com>

SM3 generic library is stand-alone implementation, sm3-ce can depend
on the SM3 library instead of sm3-generic.

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
---
 arch/arm64/crypto/Kconfig       |  2 +-
 arch/arm64/crypto/sm3-ce-glue.c | 28 ++++++++++++++++++++--------
 2 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index addfa413650b..2a965aa0188d 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -45,7 +45,7 @@ config CRYPTO_SM3_ARM64_CE
 	tristate "SM3 digest algorithm (ARMv8.2 Crypto Extensions)"
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_HASH
-	select CRYPTO_SM3
+	select CRYPTO_LIB_SM3
 
 config CRYPTO_SM4_ARM64_CE
 	tristate "SM4 symmetric cipher (ARMv8.2 Crypto Extensions)"
diff --git a/arch/arm64/crypto/sm3-ce-glue.c b/arch/arm64/crypto/sm3-ce-glue.c
index d71faca322f2..ee98954ae8ca 100644
--- a/arch/arm64/crypto/sm3-ce-glue.c
+++ b/arch/arm64/crypto/sm3-ce-glue.c
@@ -26,8 +26,10 @@ asmlinkage void sm3_ce_transform(struct sm3_state *sst, u8 const *src,
 static int sm3_ce_update(struct shash_desc *desc, const u8 *data,
 			 unsigned int len)
 {
-	if (!crypto_simd_usable())
-		return crypto_sm3_update(desc, data, len);
+	if (!crypto_simd_usable()) {
+		sm3_update(shash_desc_ctx(desc), data, len);
+		return 0;
+	}
 
 	kernel_neon_begin();
 	sm3_base_do_update(desc, data, len, sm3_ce_transform);
@@ -38,8 +40,10 @@ static int sm3_ce_update(struct shash_desc *desc, const u8 *data,
 
 static int sm3_ce_final(struct shash_desc *desc, u8 *out)
 {
-	if (!crypto_simd_usable())
-		return crypto_sm3_finup(desc, NULL, 0, out);
+	if (!crypto_simd_usable()) {
+		sm3_final(shash_desc_ctx(desc), out);
+		return 0;
+	}
 
 	kernel_neon_begin();
 	sm3_base_do_finalize(desc, sm3_ce_transform);
@@ -51,14 +55,22 @@ static int sm3_ce_final(struct shash_desc *desc, u8 *out)
 static int sm3_ce_finup(struct shash_desc *desc, const u8 *data,
 			unsigned int len, u8 *out)
 {
-	if (!crypto_simd_usable())
-		return crypto_sm3_finup(desc, data, len, out);
+	if (!crypto_simd_usable()) {
+		struct sm3_state *sctx = shash_desc_ctx(desc);
+
+		if (len)
+			sm3_update(sctx, data, len);
+		sm3_final(sctx, out);
+		return 0;
+	}
 
 	kernel_neon_begin();
-	sm3_base_do_update(desc, data, len, sm3_ce_transform);
+	if (len)
+		sm3_base_do_update(desc, data, len, sm3_ce_transform);
+	sm3_base_do_finalize(desc, sm3_ce_transform);
 	kernel_neon_end();
 
-	return sm3_ce_final(desc, out);
+	return sm3_base_finish(desc, out);
 }
 
 static struct shash_alg sm3_alg = {
-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:55 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:55 +0800
Subject: [PATCH v4 1/6] crypto: sm3 - create SM3 stand-alone library
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-2-tianjia.zhang@linux.alibaba.com>

Stand-alone implementation of the SM3 algorithm. It is designed
to have as little dependencies as possible. In other cases you
should generally use the hash APIs from include/crypto/hash.h.
Especially when hashing large amounts of data as those APIs may
be hw-accelerated. In the new SM3 stand-alone library,
sm3_transform() has also been optimized, instead of simply using
the code in sm3_generic.

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
Reviewed-by: Gilad Ben-Yossef <gilad at benyossef.com>
---
 include/crypto/sm3.h |  32 ++++++
 lib/crypto/Kconfig   |   3 +
 lib/crypto/Makefile  |   3 +
 lib/crypto/sm3.c     | 246 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 284 insertions(+)
 create mode 100644 lib/crypto/sm3.c

diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
index 42ea21289ba9..b5fb6d1bf247 100644
--- a/include/crypto/sm3.h
+++ b/include/crypto/sm3.h
@@ -1,5 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Common values for SM3 algorithm
+ *
+ * Copyright (C) 2017 ARM Limited or its affiliates.
+ * Copyright (C) 2017 Gilad Ben-Yossef <gilad at benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
  */
 
 #ifndef _CRYPTO_SM3_H
@@ -39,4 +44,31 @@ extern int crypto_sm3_final(struct shash_desc *desc, u8 *out);
 
 extern int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
 			     unsigned int len, u8 *hash);
+
+/*
+ * Stand-alone implementation of the SM3 algorithm. It is designed to
+ * have as little dependencies as possible so it can be used in the
+ * kexec_file purgatory. In other cases you should generally use the
+ * hash APIs from include/crypto/hash.h. Especially when hashing large
+ * amounts of data as those APIs may be hw-accelerated.
+ *
+ * For details see lib/crypto/sm3.c
+ */
+
+static inline void sm3_init(struct sm3_state *sctx)
+{
+	sctx->state[0] = SM3_IVA;
+	sctx->state[1] = SM3_IVB;
+	sctx->state[2] = SM3_IVC;
+	sctx->state[3] = SM3_IVD;
+	sctx->state[4] = SM3_IVE;
+	sctx->state[5] = SM3_IVF;
+	sctx->state[6] = SM3_IVG;
+	sctx->state[7] = SM3_IVH;
+	sctx->count = 0;
+}
+
+void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len);
+void sm3_final(struct sm3_state *sctx, u8 *out);
+
 #endif
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 545ccbddf6a1..36963e8f4eaa 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -129,5 +129,8 @@ config CRYPTO_LIB_CHACHA20POLY1305
 config CRYPTO_LIB_SHA256
 	tristate
 
+config CRYPTO_LIB_SM3
+	tristate
+
 config CRYPTO_LIB_SM4
 	tristate
diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile
index 73205ed269ba..8149bc00b627 100644
--- a/lib/crypto/Makefile
+++ b/lib/crypto/Makefile
@@ -38,6 +38,9 @@ libpoly1305-y					+= poly1305.o
 obj-$(CONFIG_CRYPTO_LIB_SHA256)			+= libsha256.o
 libsha256-y					:= sha256.o
 
+obj-$(CONFIG_CRYPTO_LIB_SM3)			+= libsm3.o
+libsm3-y					:= sm3.o
+
 obj-$(CONFIG_CRYPTO_LIB_SM4)			+= libsm4.o
 libsm4-y					:= sm4.o
 
diff --git a/lib/crypto/sm3.c b/lib/crypto/sm3.c
new file mode 100644
index 000000000000..d473e358a873
--- /dev/null
+++ b/lib/crypto/sm3.c
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * SM3 secure hash, as specified by OSCCA GM/T 0004-2012 SM3 and described
+ * at https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2017 ARM Limited or its affiliates.
+ * Copyright (C) 2017 Gilad Ben-Yossef <gilad at benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
+ */
+
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include <crypto/sm3.h>
+
+static const u32 ____cacheline_aligned K[64] = {
+	0x79cc4519, 0xf3988a32, 0xe7311465, 0xce6228cb,
+	0x9cc45197, 0x3988a32f, 0x7311465e, 0xe6228cbc,
+	0xcc451979, 0x988a32f3, 0x311465e7, 0x6228cbce,
+	0xc451979c, 0x88a32f39, 0x11465e73, 0x228cbce6,
+	0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+	0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+	0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+	0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5,
+	0x7a879d8a, 0xf50f3b14, 0xea1e7629, 0xd43cec53,
+	0xa879d8a7, 0x50f3b14f, 0xa1e7629e, 0x43cec53d,
+	0x879d8a7a, 0x0f3b14f5, 0x1e7629ea, 0x3cec53d4,
+	0x79d8a7a8, 0xf3b14f50, 0xe7629ea1, 0xcec53d43,
+	0x9d8a7a87, 0x3b14f50f, 0x7629ea1e, 0xec53d43c,
+	0xd8a7a879, 0xb14f50f3, 0x629ea1e7, 0xc53d43ce,
+	0x8a7a879d, 0x14f50f3b, 0x29ea1e76, 0x53d43cec,
+	0xa7a879d8, 0x4f50f3b1, 0x9ea1e762, 0x3d43cec5
+};
+
+/*
+ * Transform the message X which consists of 16 32-bit-words. See
+ * GM/T 004-2012 for details.
+ */
+#define R(i, a, b, c, d, e, f, g, h, t, w1, w2)			\
+	do {							\
+		ss1 = rol32((rol32((a), 12) + (e) + (t)), 7);	\
+		ss2 = ss1 ^ rol32((a), 12);			\
+		d += FF ## i(a, b, c) + ss2 + ((w1) ^ (w2));	\
+		h += GG ## i(e, f, g) + ss1 + (w1);		\
+		b = rol32((b), 9);				\
+		f = rol32((f), 19);				\
+		h = P0((h));					\
+	} while (0)
+
+#define R1(a, b, c, d, e, f, g, h, t, w1, w2) \
+	R(1, a, b, c, d, e, f, g, h, t, w1, w2)
+#define R2(a, b, c, d, e, f, g, h, t, w1, w2) \
+	R(2, a, b, c, d, e, f, g, h, t, w1, w2)
+
+#define FF1(x, y, z)  (x ^ y ^ z)
+#define FF2(x, y, z)  ((x & y) | (x & z) | (y & z))
+
+#define GG1(x, y, z)  FF1(x, y, z)
+#define GG2(x, y, z)  ((x & y) | (~x & z))
+
+/* Message expansion */
+#define P0(x) ((x) ^ rol32((x), 9) ^ rol32((x), 17))
+#define P1(x) ((x) ^ rol32((x), 15) ^ rol32((x), 23))
+#define I(i)  (W[i] = get_unaligned_be32(data + i * 4))
+#define W1(i) (W[i & 0x0f])
+#define W2(i) (W[i & 0x0f] =				\
+		P1(W[i & 0x0f]				\
+			^ W[(i-9) & 0x0f]		\
+			^ rol32(W[(i-3) & 0x0f], 15))	\
+		^ rol32(W[(i-13) & 0x0f], 7)		\
+		^ W[(i-6) & 0x0f])
+
+static void sm3_transform(struct sm3_state *sctx, u8 const *data, u32 W[16])
+{
+	u32 a, b, c, d, e, f, g, h, ss1, ss2;
+
+	a = sctx->state[0];
+	b = sctx->state[1];
+	c = sctx->state[2];
+	d = sctx->state[3];
+	e = sctx->state[4];
+	f = sctx->state[5];
+	g = sctx->state[6];
+	h = sctx->state[7];
+
+	R1(a, b, c, d, e, f, g, h, K[0], I(0), I(4));
+	R1(d, a, b, c, h, e, f, g, K[1], I(1), I(5));
+	R1(c, d, a, b, g, h, e, f, K[2], I(2), I(6));
+	R1(b, c, d, a, f, g, h, e, K[3], I(3), I(7));
+	R1(a, b, c, d, e, f, g, h, K[4], W1(4), I(8));
+	R1(d, a, b, c, h, e, f, g, K[5], W1(5), I(9));
+	R1(c, d, a, b, g, h, e, f, K[6], W1(6), I(10));
+	R1(b, c, d, a, f, g, h, e, K[7], W1(7), I(11));
+	R1(a, b, c, d, e, f, g, h, K[8], W1(8), I(12));
+	R1(d, a, b, c, h, e, f, g, K[9], W1(9), I(13));
+	R1(c, d, a, b, g, h, e, f, K[10], W1(10), I(14));
+	R1(b, c, d, a, f, g, h, e, K[11], W1(11), I(15));
+	R1(a, b, c, d, e, f, g, h, K[12], W1(12), W2(16));
+	R1(d, a, b, c, h, e, f, g, K[13], W1(13), W2(17));
+	R1(c, d, a, b, g, h, e, f, K[14], W1(14), W2(18));
+	R1(b, c, d, a, f, g, h, e, K[15], W1(15), W2(19));
+
+	R2(a, b, c, d, e, f, g, h, K[16], W1(16), W2(20));
+	R2(d, a, b, c, h, e, f, g, K[17], W1(17), W2(21));
+	R2(c, d, a, b, g, h, e, f, K[18], W1(18), W2(22));
+	R2(b, c, d, a, f, g, h, e, K[19], W1(19), W2(23));
+	R2(a, b, c, d, e, f, g, h, K[20], W1(20), W2(24));
+	R2(d, a, b, c, h, e, f, g, K[21], W1(21), W2(25));
+	R2(c, d, a, b, g, h, e, f, K[22], W1(22), W2(26));
+	R2(b, c, d, a, f, g, h, e, K[23], W1(23), W2(27));
+	R2(a, b, c, d, e, f, g, h, K[24], W1(24), W2(28));
+	R2(d, a, b, c, h, e, f, g, K[25], W1(25), W2(29));
+	R2(c, d, a, b, g, h, e, f, K[26], W1(26), W2(30));
+	R2(b, c, d, a, f, g, h, e, K[27], W1(27), W2(31));
+	R2(a, b, c, d, e, f, g, h, K[28], W1(28), W2(32));
+	R2(d, a, b, c, h, e, f, g, K[29], W1(29), W2(33));
+	R2(c, d, a, b, g, h, e, f, K[30], W1(30), W2(34));
+	R2(b, c, d, a, f, g, h, e, K[31], W1(31), W2(35));
+
+	R2(a, b, c, d, e, f, g, h, K[32], W1(32), W2(36));
+	R2(d, a, b, c, h, e, f, g, K[33], W1(33), W2(37));
+	R2(c, d, a, b, g, h, e, f, K[34], W1(34), W2(38));
+	R2(b, c, d, a, f, g, h, e, K[35], W1(35), W2(39));
+	R2(a, b, c, d, e, f, g, h, K[36], W1(36), W2(40));
+	R2(d, a, b, c, h, e, f, g, K[37], W1(37), W2(41));
+	R2(c, d, a, b, g, h, e, f, K[38], W1(38), W2(42));
+	R2(b, c, d, a, f, g, h, e, K[39], W1(39), W2(43));
+	R2(a, b, c, d, e, f, g, h, K[40], W1(40), W2(44));
+	R2(d, a, b, c, h, e, f, g, K[41], W1(41), W2(45));
+	R2(c, d, a, b, g, h, e, f, K[42], W1(42), W2(46));
+	R2(b, c, d, a, f, g, h, e, K[43], W1(43), W2(47));
+	R2(a, b, c, d, e, f, g, h, K[44], W1(44), W2(48));
+	R2(d, a, b, c, h, e, f, g, K[45], W1(45), W2(49));
+	R2(c, d, a, b, g, h, e, f, K[46], W1(46), W2(50));
+	R2(b, c, d, a, f, g, h, e, K[47], W1(47), W2(51));
+
+	R2(a, b, c, d, e, f, g, h, K[48], W1(48), W2(52));
+	R2(d, a, b, c, h, e, f, g, K[49], W1(49), W2(53));
+	R2(c, d, a, b, g, h, e, f, K[50], W1(50), W2(54));
+	R2(b, c, d, a, f, g, h, e, K[51], W1(51), W2(55));
+	R2(a, b, c, d, e, f, g, h, K[52], W1(52), W2(56));
+	R2(d, a, b, c, h, e, f, g, K[53], W1(53), W2(57));
+	R2(c, d, a, b, g, h, e, f, K[54], W1(54), W2(58));
+	R2(b, c, d, a, f, g, h, e, K[55], W1(55), W2(59));
+	R2(a, b, c, d, e, f, g, h, K[56], W1(56), W2(60));
+	R2(d, a, b, c, h, e, f, g, K[57], W1(57), W2(61));
+	R2(c, d, a, b, g, h, e, f, K[58], W1(58), W2(62));
+	R2(b, c, d, a, f, g, h, e, K[59], W1(59), W2(63));
+	R2(a, b, c, d, e, f, g, h, K[60], W1(60), W2(64));
+	R2(d, a, b, c, h, e, f, g, K[61], W1(61), W2(65));
+	R2(c, d, a, b, g, h, e, f, K[62], W1(62), W2(66));
+	R2(b, c, d, a, f, g, h, e, K[63], W1(63), W2(67));
+
+	sctx->state[0] ^= a;
+	sctx->state[1] ^= b;
+	sctx->state[2] ^= c;
+	sctx->state[3] ^= d;
+	sctx->state[4] ^= e;
+	sctx->state[5] ^= f;
+	sctx->state[6] ^= g;
+	sctx->state[7] ^= h;
+}
+#undef R
+#undef R1
+#undef R2
+#undef I
+#undef W1
+#undef W2
+
+static inline void sm3_block(struct sm3_state *sctx,
+		u8 const *data, int blocks, u32 W[16])
+{
+	while (blocks--) {
+		sm3_transform(sctx, data, W);
+		data += SM3_BLOCK_SIZE;
+	}
+}
+
+void sm3_update(struct sm3_state *sctx, const u8 *data, unsigned int len)
+{
+	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+	u32 W[16];
+
+	sctx->count += len;
+
+	if ((partial + len) >= SM3_BLOCK_SIZE) {
+		int blocks;
+
+		if (partial) {
+			int p = SM3_BLOCK_SIZE - partial;
+
+			memcpy(sctx->buffer + partial, data, p);
+			data += p;
+			len -= p;
+
+			sm3_block(sctx, sctx->buffer, 1, W);
+		}
+
+		blocks = len / SM3_BLOCK_SIZE;
+		len %= SM3_BLOCK_SIZE;
+
+		if (blocks) {
+			sm3_block(sctx, data, blocks, W);
+			data += blocks * SM3_BLOCK_SIZE;
+		}
+
+		memzero_explicit(W, sizeof(W));
+
+		partial = 0;
+	}
+	if (len)
+		memcpy(sctx->buffer + partial, data, len);
+}
+EXPORT_SYMBOL_GPL(sm3_update);
+
+void sm3_final(struct sm3_state *sctx, u8 *out)
+{
+	const int bit_offset = SM3_BLOCK_SIZE - sizeof(u64);
+	__be64 *bits = (__be64 *)(sctx->buffer + bit_offset);
+	__be32 *digest = (__be32 *)out;
+	unsigned int partial = sctx->count % SM3_BLOCK_SIZE;
+	u32 W[16];
+	int i;
+
+	sctx->buffer[partial++] = 0x80;
+	if (partial > bit_offset) {
+		memset(sctx->buffer + partial, 0, SM3_BLOCK_SIZE - partial);
+		partial = 0;
+
+		sm3_block(sctx, sctx->buffer, 1, W);
+	}
+
+	memset(sctx->buffer + partial, 0, bit_offset - partial);
+	*bits = cpu_to_be64(sctx->count << 3);
+	sm3_block(sctx, sctx->buffer, 1, W);
+
+	for (i = 0; i < 8; i++)
+		put_unaligned_be32(sctx->state[i], digest++);
+
+	/* Zeroize sensitive information. */
+	memzero_explicit(W, sizeof(W));
+	memzero_explicit(sctx, sizeof(*sctx));
+}
+EXPORT_SYMBOL_GPL(sm3_final);
+
+MODULE_DESCRIPTION("Generic SM3 library");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:57 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:57 +0800
Subject: [PATCH v4 3/6] crypto: sm2 - make dependent on sm3 library
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-4-tianjia.zhang@linux.alibaba.com>

SM3 generic library is stand-alone implementation, it is necessary
for the calculation of sm2 z digest to depends on SM3 library
instead of sm3-generic.

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
---
 crypto/Kconfig |  2 +-
 crypto/sm2.c   | 38 +++++++++++++++++++-------------------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 649ee1df05c6..555b8690f978 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -267,7 +267,7 @@ config CRYPTO_ECRDSA
 
 config CRYPTO_SM2
 	tristate "SM2 algorithm"
-	select CRYPTO_SM3
+	select CRYPTO_LIB_SM3
 	select CRYPTO_AKCIPHER
 	select CRYPTO_MANAGER
 	select MPILIB
diff --git a/crypto/sm2.c b/crypto/sm2.c
index db8a4a265669..ae3f77a66070 100644
--- a/crypto/sm2.c
+++ b/crypto/sm2.c
@@ -13,7 +13,7 @@
 #include <crypto/internal/akcipher.h>
 #include <crypto/akcipher.h>
 #include <crypto/hash.h>
-#include <crypto/sm3_base.h>
+#include <crypto/sm3.h>
 #include <crypto/rng.h>
 #include <crypto/sm2.h>
 #include "sm2signature.asn1.h"
@@ -213,7 +213,7 @@ int sm2_get_signature_s(void *context, size_t hdrlen, unsigned char tag,
 	return 0;
 }
 
-static int sm2_z_digest_update(struct shash_desc *desc,
+static int sm2_z_digest_update(struct sm3_state *sctx,
 			MPI m, unsigned int pbytes)
 {
 	static const unsigned char zero[32];
@@ -226,20 +226,20 @@ static int sm2_z_digest_update(struct shash_desc *desc,
 
 	if (inlen < pbytes) {
 		/* padding with zero */
-		crypto_sm3_update(desc, zero, pbytes - inlen);
-		crypto_sm3_update(desc, in, inlen);
+		sm3_update(sctx, zero, pbytes - inlen);
+		sm3_update(sctx, in, inlen);
 	} else if (inlen > pbytes) {
 		/* skip the starting zero */
-		crypto_sm3_update(desc, in + inlen - pbytes, pbytes);
+		sm3_update(sctx, in + inlen - pbytes, pbytes);
 	} else {
-		crypto_sm3_update(desc, in, inlen);
+		sm3_update(sctx, in, inlen);
 	}
 
 	kfree(in);
 	return 0;
 }
 
-static int sm2_z_digest_update_point(struct shash_desc *desc,
+static int sm2_z_digest_update_point(struct sm3_state *sctx,
 		MPI_POINT point, struct mpi_ec_ctx *ec, unsigned int pbytes)
 {
 	MPI x, y;
@@ -249,8 +249,8 @@ static int sm2_z_digest_update_point(struct shash_desc *desc,
 	y = mpi_new(0);
 
 	if (!mpi_ec_get_affine(x, y, point, ec) &&
-		!sm2_z_digest_update(desc, x, pbytes) &&
-		!sm2_z_digest_update(desc, y, pbytes))
+	    !sm2_z_digest_update(sctx, x, pbytes) &&
+	    !sm2_z_digest_update(sctx, y, pbytes))
 		ret = 0;
 
 	mpi_free(x);
@@ -265,7 +265,7 @@ int sm2_compute_z_digest(struct crypto_akcipher *tfm,
 	struct mpi_ec_ctx *ec = akcipher_tfm_ctx(tfm);
 	uint16_t bits_len;
 	unsigned char entl[2];
-	SHASH_DESC_ON_STACK(desc, NULL);
+	struct sm3_state sctx;
 	unsigned int pbytes;
 
 	if (id_len > (USHRT_MAX / 8) || !ec->Q)
@@ -278,17 +278,17 @@ int sm2_compute_z_digest(struct crypto_akcipher *tfm,
 	pbytes = MPI_NBYTES(ec->p);
 
 	/* ZA = H256(ENTLA | IDA | a | b | xG | yG | xA | yA) */
-	sm3_base_init(desc);
-	crypto_sm3_update(desc, entl, 2);
-	crypto_sm3_update(desc, id, id_len);
-
-	if (sm2_z_digest_update(desc, ec->a, pbytes) ||
-		sm2_z_digest_update(desc, ec->b, pbytes) ||
-		sm2_z_digest_update_point(desc, ec->G, ec, pbytes) ||
-		sm2_z_digest_update_point(desc, ec->Q, ec, pbytes))
+	sm3_init(&sctx);
+	sm3_update(&sctx, entl, 2);
+	sm3_update(&sctx, id, id_len);
+
+	if (sm2_z_digest_update(&sctx, ec->a, pbytes) ||
+	    sm2_z_digest_update(&sctx, ec->b, pbytes) ||
+	    sm2_z_digest_update_point(&sctx, ec->G, ec, pbytes) ||
+	    sm2_z_digest_update_point(&sctx, ec->Q, ec, pbytes))
 		return -EINVAL;
 
-	crypto_sm3_final(desc, dgst);
+	sm3_final(&sctx, dgst);
 	return 0;
 }
 EXPORT_SYMBOL(sm2_compute_z_digest);
-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:58 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:58 +0800
Subject: [PATCH v4 4/6] crypto: sm3 - make dependent on sm3 library
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-5-tianjia.zhang@linux.alibaba.com>

SM3 generic library is stand-alone implementation, it is necessary
making the sm3-generic implementation to depends on SM3 library.
The functions crypto_sm3_*() provided by sm3_generic is no longer
exported.

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
---
 crypto/Kconfig       |   1 +
 crypto/sm3_generic.c | 142 +++++--------------------------------------
 include/crypto/sm3.h |  10 ---
 3 files changed, 16 insertions(+), 137 deletions(-)

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 555b8690f978..c236fd0e214e 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -999,6 +999,7 @@ config CRYPTO_SHA3
 config CRYPTO_SM3
 	tristate "SM3 digest algorithm"
 	select CRYPTO_HASH
+	select CRYPTO_LIB_SM3
 	help
 	  SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
 	  It is part of the Chinese Commercial Cryptography suite.
diff --git a/crypto/sm3_generic.c b/crypto/sm3_generic.c
index 193c4584bd00..a215c1c37e73 100644
--- a/crypto/sm3_generic.c
+++ b/crypto/sm3_generic.c
@@ -5,6 +5,7 @@
  *
  * Copyright (C) 2017 ARM Limited or its affiliates.
  * Written by Gilad Ben-Yossef <gilad at benyossef.com>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
  */
 
 #include <crypto/internal/hash.h>
@@ -26,143 +27,29 @@ const u8 sm3_zero_message_hash[SM3_DIGEST_SIZE] = {
 };
 EXPORT_SYMBOL_GPL(sm3_zero_message_hash);
 
-static inline u32 p0(u32 x)
-{
-	return x ^ rol32(x, 9) ^ rol32(x, 17);
-}
-
-static inline u32 p1(u32 x)
-{
-	return x ^ rol32(x, 15) ^ rol32(x, 23);
-}
-
-static inline u32 ff(unsigned int n, u32 a, u32 b, u32 c)
-{
-	return (n < 16) ? (a ^ b ^ c) : ((a & b) | (a & c) | (b & c));
-}
-
-static inline u32 gg(unsigned int n, u32 e, u32 f, u32 g)
-{
-	return (n < 16) ? (e ^ f ^ g) : ((e & f) | ((~e) & g));
-}
-
-static inline u32 t(unsigned int n)
-{
-	return (n < 16) ? SM3_T1 : SM3_T2;
-}
-
-static void sm3_expand(u32 *t, u32 *w, u32 *wt)
-{
-	int i;
-	unsigned int tmp;
-
-	/* load the input */
-	for (i = 0; i <= 15; i++)
-		w[i] = get_unaligned_be32((__u32 *)t + i);
-
-	for (i = 16; i <= 67; i++) {
-		tmp = w[i - 16] ^ w[i - 9] ^ rol32(w[i - 3], 15);
-		w[i] = p1(tmp) ^ (rol32(w[i - 13], 7)) ^ w[i - 6];
-	}
-
-	for (i = 0; i <= 63; i++)
-		wt[i] = w[i] ^ w[i + 4];
-}
-
-static void sm3_compress(u32 *w, u32 *wt, u32 *m)
-{
-	u32 ss1;
-	u32 ss2;
-	u32 tt1;
-	u32 tt2;
-	u32 a, b, c, d, e, f, g, h;
-	int i;
-
-	a = m[0];
-	b = m[1];
-	c = m[2];
-	d = m[3];
-	e = m[4];
-	f = m[5];
-	g = m[6];
-	h = m[7];
-
-	for (i = 0; i <= 63; i++) {
-
-		ss1 = rol32((rol32(a, 12) + e + rol32(t(i), i & 31)), 7);
-
-		ss2 = ss1 ^ rol32(a, 12);
-
-		tt1 = ff(i, a, b, c) + d + ss2 + *wt;
-		wt++;
-
-		tt2 = gg(i, e, f, g) + h + ss1 + *w;
-		w++;
-
-		d = c;
-		c = rol32(b, 9);
-		b = a;
-		a = tt1;
-		h = g;
-		g = rol32(f, 19);
-		f = e;
-		e = p0(tt2);
-	}
-
-	m[0] = a ^ m[0];
-	m[1] = b ^ m[1];
-	m[2] = c ^ m[2];
-	m[3] = d ^ m[3];
-	m[4] = e ^ m[4];
-	m[5] = f ^ m[5];
-	m[6] = g ^ m[6];
-	m[7] = h ^ m[7];
-
-	a = b = c = d = e = f = g = h = ss1 = ss2 = tt1 = tt2 = 0;
-}
-
-static void sm3_transform(struct sm3_state *sst, u8 const *src)
-{
-	unsigned int w[68];
-	unsigned int wt[64];
-
-	sm3_expand((u32 *)src, w, wt);
-	sm3_compress(w, wt, sst->state);
-
-	memzero_explicit(w, sizeof(w));
-	memzero_explicit(wt, sizeof(wt));
-}
-
-static void sm3_generic_block_fn(struct sm3_state *sst, u8 const *src,
-				    int blocks)
-{
-	while (blocks--) {
-		sm3_transform(sst, src);
-		src += SM3_BLOCK_SIZE;
-	}
-}
-
-int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
 			  unsigned int len)
 {
-	return sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
+	sm3_update(shash_desc_ctx(desc), data, len);
+	return 0;
 }
-EXPORT_SYMBOL(crypto_sm3_update);
 
-int crypto_sm3_final(struct shash_desc *desc, u8 *out)
+static int crypto_sm3_final(struct shash_desc *desc, u8 *out)
 {
-	sm3_base_do_finalize(desc, sm3_generic_block_fn);
-	return sm3_base_finish(desc, out);
+	sm3_final(shash_desc_ctx(desc), out);
+	return 0;
 }
-EXPORT_SYMBOL(crypto_sm3_final);
 
-int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
+static int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
 			unsigned int len, u8 *hash)
 {
-	sm3_base_do_update(desc, data, len, sm3_generic_block_fn);
-	return crypto_sm3_final(desc, hash);
+	struct sm3_state *sctx = shash_desc_ctx(desc);
+
+	if (len)
+		sm3_update(sctx, data, len);
+	sm3_final(sctx, hash);
+	return 0;
 }
-EXPORT_SYMBOL(crypto_sm3_finup);
 
 static struct shash_alg sm3_alg = {
 	.digestsize	=	SM3_DIGEST_SIZE,
@@ -174,6 +61,7 @@ static struct shash_alg sm3_alg = {
 	.base		=	{
 		.cra_name	 =	"sm3",
 		.cra_driver_name =	"sm3-generic",
+		.cra_priority	=	100,
 		.cra_blocksize	 =	SM3_BLOCK_SIZE,
 		.cra_module	 =	THIS_MODULE,
 	}
diff --git a/include/crypto/sm3.h b/include/crypto/sm3.h
index b5fb6d1bf247..1f021ad0533f 100644
--- a/include/crypto/sm3.h
+++ b/include/crypto/sm3.h
@@ -35,16 +35,6 @@ struct sm3_state {
 	u8 buffer[SM3_BLOCK_SIZE];
 };
 
-struct shash_desc;
-
-extern int crypto_sm3_update(struct shash_desc *desc, const u8 *data,
-			      unsigned int len);
-
-extern int crypto_sm3_final(struct shash_desc *desc, u8 *out);
-
-extern int crypto_sm3_finup(struct shash_desc *desc, const u8 *data,
-			     unsigned int len, u8 *hash);
-
 /*
  * Stand-alone implementation of the SM3 algorithm. It is designed to
  * have as little dependencies as possible so it can be used in the
-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:07:00 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:07:00 +0800
Subject: [PATCH v4 6/6] crypto: tcrypt - add asynchronous speed test for SM3
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-7-tianjia.zhang@linux.alibaba.com>

tcrypt supports testing of SM3 hash algorithms that use AVX
instruction acceleration.

In order to add the sm3 asynchronous test to the appropriate
position, shift the testcase sequence number of the multi buffer
backward and start from 450.

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
---
 crypto/tcrypt.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 00149657a4bc..82b5eef2246a 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -2571,31 +2571,35 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
 	case 422:
+		test_ahash_speed("sm3", sec, generic_hash_speed_template);
+		if (mode > 400 && mode < 500) break;
+		fallthrough;
+	case 450:
 		test_mb_ahash_speed("sha1", sec, generic_hash_speed_template,
 				    num_mb);
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
-	case 423:
+	case 451:
 		test_mb_ahash_speed("sha256", sec, generic_hash_speed_template,
 				    num_mb);
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
-	case 424:
+	case 452:
 		test_mb_ahash_speed("sha512", sec, generic_hash_speed_template,
 				    num_mb);
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
-	case 425:
+	case 453:
 		test_mb_ahash_speed("sm3", sec, generic_hash_speed_template,
 				    num_mb);
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
-	case 426:
+	case 454:
 		test_mb_ahash_speed("streebog256", sec,
 				    generic_hash_speed_template, num_mb);
 		if (mode > 400 && mode < 500) break;
 		fallthrough;
-	case 427:
+	case 455:
 		test_mb_ahash_speed("streebog512", sec,
 				    generic_hash_speed_template, num_mb);
 		if (mode > 400 && mode < 500) break;
-- 
2.34.1



From tianjia.zhang at linux.alibaba.com  Fri Jan  7 04:06:59 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri,  7 Jan 2022 20:06:59 +0800
Subject: [PATCH v4 5/6] crypto: x86/sm3 - add AVX assembly implementation
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <20220107120700.730-6-tianjia.zhang@linux.alibaba.com>

This patch adds AVX assembly accelerated implementation of SM3 secure
hash algorithm. From the benchmark data, compared to pure software
implementation sm3-generic, the performance increase is up to 38%.

The main algorithm implementation based on SM3 AES/BMI2 accelerated
work by libgcrypt at:
https://gnupg.org/software/libgcrypt/index.html

Benchmark on Intel i5-6200U 2.30GHz, performance data of two
implementations, pure software sm3-generic and sm3-avx acceleration.
The data comes from the 326 mode and 422 mode of tcrypt. The abscissas
are different lengths of per update. The data is tabulated and the
unit is Mb/s:

update-size |     16      64     256    1024    2048    4096    8192
------------+-------------------------------------------------------
sm3-generic | 105.97  129.60  182.12  189.62  188.06  193.66  194.88
sm3-avx     | 119.87  163.05  244.44  260.92  257.60  264.87  265.88

Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
---
 arch/x86/crypto/Makefile         |   3 +
 arch/x86/crypto/sm3-avx-asm_64.S | 517 +++++++++++++++++++++++++++++++
 arch/x86/crypto/sm3_avx_glue.c   | 134 ++++++++
 crypto/Kconfig                   |  13 +
 4 files changed, 667 insertions(+)
 create mode 100644 arch/x86/crypto/sm3-avx-asm_64.S
 create mode 100644 arch/x86/crypto/sm3_avx_glue.c

diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index f307c93fc90a..7cbe860f6201 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -88,6 +88,9 @@ nhpoly1305-avx2-y := nh-avx2-x86_64.o nhpoly1305-avx2-glue.o
 
 obj-$(CONFIG_CRYPTO_CURVE25519_X86) += curve25519-x86_64.o
 
+obj-$(CONFIG_CRYPTO_SM3_AVX_X86_64) += sm3-avx-x86_64.o
+sm3-avx-x86_64-y := sm3-avx-asm_64.o sm3_avx_glue.o
+
 obj-$(CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64) += sm4-aesni-avx-x86_64.o
 sm4-aesni-avx-x86_64-y := sm4-aesni-avx-asm_64.o sm4_aesni_avx_glue.o
 
diff --git a/arch/x86/crypto/sm3-avx-asm_64.S b/arch/x86/crypto/sm3-avx-asm_64.S
new file mode 100644
index 000000000000..71e6aae23e17
--- /dev/null
+++ b/arch/x86/crypto/sm3-avx-asm_64.S
@@ -0,0 +1,517 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SM3 AVX accelerated transform.
+ * specified in: https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2021 Jussi Kivilinna <jussi.kivilinna at iki.fi>
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
+ */
+
+/* Based on SM3 AES/BMI2 accelerated work by libgcrypt at:
+ *  https://gnupg.org/software/libgcrypt/index.html
+ */
+
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+/* Context structure */
+
+#define state_h0 0
+#define state_h1 4
+#define state_h2 8
+#define state_h3 12
+#define state_h4 16
+#define state_h5 20
+#define state_h6 24
+#define state_h7 28
+
+/* Constants */
+
+/* Round constant macros */
+
+#define K0   2043430169  /* 0x79cc4519 */
+#define K1   -208106958  /* 0xf3988a32 */
+#define K2   -416213915  /* 0xe7311465 */
+#define K3   -832427829  /* 0xce6228cb */
+#define K4  -1664855657  /* 0x9cc45197 */
+#define K5    965255983  /* 0x3988a32f */
+#define K6   1930511966  /* 0x7311465e */
+#define K7   -433943364  /* 0xe6228cbc */
+#define K8   -867886727  /* 0xcc451979 */
+#define K9  -1735773453  /* 0x988a32f3 */
+#define K10   823420391  /* 0x311465e7 */
+#define K11  1646840782  /* 0x6228cbce */
+#define K12 -1001285732  /* 0xc451979c */
+#define K13 -2002571463  /* 0x88a32f39 */
+#define K14   289824371  /* 0x11465e73 */
+#define K15   579648742  /* 0x228cbce6 */
+#define K16 -1651869049  /* 0x9d8a7a87 */
+#define K17   991229199  /* 0x3b14f50f */
+#define K18  1982458398  /* 0x7629ea1e */
+#define K19  -330050500  /* 0xec53d43c */
+#define K20  -660100999  /* 0xd8a7a879 */
+#define K21 -1320201997  /* 0xb14f50f3 */
+#define K22  1654563303  /* 0x629ea1e7 */
+#define K23  -985840690  /* 0xc53d43ce */
+#define K24 -1971681379  /* 0x8a7a879d */
+#define K25   351604539  /* 0x14f50f3b */
+#define K26   703209078  /* 0x29ea1e76 */
+#define K27  1406418156  /* 0x53d43cec */
+#define K28 -1482130984  /* 0xa7a879d8 */
+#define K29  1330705329  /* 0x4f50f3b1 */
+#define K30 -1633556638  /* 0x9ea1e762 */
+#define K31  1027854021  /* 0x3d43cec5 */
+#define K32  2055708042  /* 0x7a879d8a */
+#define K33  -183551212  /* 0xf50f3b14 */
+#define K34  -367102423  /* 0xea1e7629 */
+#define K35  -734204845  /* 0xd43cec53 */
+#define K36 -1468409689  /* 0xa879d8a7 */
+#define K37  1358147919  /* 0x50f3b14f */
+#define K38 -1578671458  /* 0xa1e7629e */
+#define K39  1137624381  /* 0x43cec53d */
+#define K40 -2019718534  /* 0x879d8a7a */
+#define K41   255530229  /* 0x0f3b14f5 */
+#define K42   511060458  /* 0x1e7629ea */
+#define K43  1022120916  /* 0x3cec53d4 */
+#define K44  2044241832  /* 0x79d8a7a8 */
+#define K45  -206483632  /* 0xf3b14f50 */
+#define K46  -412967263  /* 0xe7629ea1 */
+#define K47  -825934525  /* 0xcec53d43 */
+#define K48 -1651869049  /* 0x9d8a7a87 */
+#define K49   991229199  /* 0x3b14f50f */
+#define K50  1982458398  /* 0x7629ea1e */
+#define K51  -330050500  /* 0xec53d43c */
+#define K52  -660100999  /* 0xd8a7a879 */
+#define K53 -1320201997  /* 0xb14f50f3 */
+#define K54  1654563303  /* 0x629ea1e7 */
+#define K55  -985840690  /* 0xc53d43ce */
+#define K56 -1971681379  /* 0x8a7a879d */
+#define K57   351604539  /* 0x14f50f3b */
+#define K58   703209078  /* 0x29ea1e76 */
+#define K59  1406418156  /* 0x53d43cec */
+#define K60 -1482130984  /* 0xa7a879d8 */
+#define K61  1330705329  /* 0x4f50f3b1 */
+#define K62 -1633556638  /* 0x9ea1e762 */
+#define K63  1027854021  /* 0x3d43cec5 */
+
+/* Register macros */
+
+#define RSTATE %rdi
+#define RDATA  %rsi
+#define RNBLKS %rdx
+
+#define t0 %eax
+#define t1 %ebx
+#define t2 %ecx
+
+#define a %r8d
+#define b %r9d
+#define c %r10d
+#define d %r11d
+#define e %r12d
+#define f %r13d
+#define g %r14d
+#define h %r15d
+
+#define W0 %xmm0
+#define W1 %xmm1
+#define W2 %xmm2
+#define W3 %xmm3
+#define W4 %xmm4
+#define W5 %xmm5
+
+#define XTMP0 %xmm6
+#define XTMP1 %xmm7
+#define XTMP2 %xmm8
+#define XTMP3 %xmm9
+#define XTMP4 %xmm10
+#define XTMP5 %xmm11
+#define XTMP6 %xmm12
+
+#define BSWAP_REG %xmm15
+
+/* Stack structure */
+
+#define STACK_W_SIZE        (32 * 2 * 3)
+#define STACK_REG_SAVE_SIZE (64)
+
+#define STACK_W             (0)
+#define STACK_REG_SAVE      (STACK_W + STACK_W_SIZE)
+#define STACK_SIZE          (STACK_REG_SAVE + STACK_REG_SAVE_SIZE)
+
+/* Instruction helpers. */
+
+#define roll2(v, reg)		\
+	roll $(v), reg;
+
+#define roll3mov(v, src, dst)	\
+	movl src, dst;		\
+	roll $(v), dst;
+
+#define roll3(v, src, dst)	\
+	rorxl $(32-(v)), src, dst;
+
+#define addl2(a, out)		\
+	leal (a, out), out;
+
+/* Round function macros. */
+
+#define GG1(x, y, z, o, t)	\
+	movl x, o;		\
+	xorl y, o;		\
+	xorl z, o;
+
+#define FF1(x, y, z, o, t) GG1(x, y, z, o, t)
+
+#define GG2(x, y, z, o, t)	\
+	andnl z, x, o;		\
+	movl y, t;		\
+	andl x, t;		\
+	addl2(t, o);
+
+#define FF2(x, y, z, o, t)	\
+	movl y, o;		\
+	xorl x, o;		\
+	movl y, t;		\
+	andl x, t;		\
+	andl z, o;		\
+	xorl t, o;
+
+#define R(i, a, b, c, d, e, f, g, h, round, widx, wtype)		\
+	/* rol(a, 12) => t0 */						\
+	roll3mov(12, a, t0); /* rorxl here would reduce perf by 6% on zen3 */ \
+	/* rol (t0 + e + t), 7) => t1 */				\
+	leal K##round(t0, e, 1), t1;					\
+	roll2(7, t1);							\
+	/* h + w1 => h */						\
+	addl wtype##_W1_ADDR(round, widx), h;				\
+	/* h + t1 => h */						\
+	addl2(t1, h);							\
+	/* t1 ^ t0 => t0 */						\
+	xorl t1, t0;							\
+	/* w1w2 + d => d */						\
+	addl wtype##_W1W2_ADDR(round, widx), d;				\
+	/* FF##i(a,b,c) => t1 */					\
+	FF##i(a, b, c, t1, t2);						\
+	/* d + t1 => d */						\
+	addl2(t1, d);							\
+	/* GG#i(e,f,g) => t2 */						\
+	GG##i(e, f, g, t2, t1);						\
+	/* h + t2 => h */						\
+	addl2(t2, h);							\
+	/* rol (f, 19) => f */						\
+	roll2(19, f);							\
+	/* d + t0 => d */						\
+	addl2(t0, d);							\
+	/* rol (b, 9) => b */						\
+	roll2(9, b);							\
+	/* P0(h) => h */						\
+	roll3(9, h, t2);						\
+	roll3(17, h, t1);						\
+	xorl t2, h;							\
+	xorl t1, h;
+
+#define R1(a, b, c, d, e, f, g, h, round, widx, wtype) \
+	R(1, a, b, c, d, e, f, g, h, round, widx, wtype)
+
+#define R2(a, b, c, d, e, f, g, h, round, widx, wtype) \
+	R(2, a, b, c, d, e, f, g, h, round, widx, wtype)
+
+/* Input expansion macros. */
+
+/* Byte-swapped input address. */
+#define IW_W_ADDR(round, widx, offs) \
+	(STACK_W + ((round) / 4) * 64 + (offs) + ((widx) * 4))(%rsp)
+
+/* Expanded input address. */
+#define XW_W_ADDR(round, widx, offs) \
+	(STACK_W + ((((round) / 3) - 4) % 2) * 64 + (offs) + ((widx) * 4))(%rsp)
+
+/* Rounds 1-12, byte-swapped input block addresses. */
+#define IW_W1_ADDR(round, widx)   IW_W_ADDR(round, widx, 0)
+#define IW_W1W2_ADDR(round, widx) IW_W_ADDR(round, widx, 32)
+
+/* Rounds 1-12, expanded input block addresses. */
+#define XW_W1_ADDR(round, widx)   XW_W_ADDR(round, widx, 0)
+#define XW_W1W2_ADDR(round, widx) XW_W_ADDR(round, widx, 32)
+
+/* Input block loading. */
+#define LOAD_W_XMM_1()							\
+	vmovdqu 0*16(RDATA), XTMP0; /* XTMP0: w3, w2, w1, w0 */		\
+	vmovdqu 1*16(RDATA), XTMP1; /* XTMP1: w7, w6, w5, w4 */		\
+	vmovdqu 2*16(RDATA), XTMP2; /* XTMP2: w11, w10, w9, w8 */	\
+	vmovdqu 3*16(RDATA), XTMP3; /* XTMP3: w15, w14, w13, w12 */	\
+	vpshufb BSWAP_REG, XTMP0, XTMP0;				\
+	vpshufb BSWAP_REG, XTMP1, XTMP1;				\
+	vpshufb BSWAP_REG, XTMP2, XTMP2;				\
+	vpshufb BSWAP_REG, XTMP3, XTMP3;				\
+	vpxor XTMP0, XTMP1, XTMP4;					\
+	vpxor XTMP1, XTMP2, XTMP5;					\
+	vpxor XTMP2, XTMP3, XTMP6;					\
+	leaq 64(RDATA), RDATA;						\
+	vmovdqa XTMP0, IW_W1_ADDR(0, 0);				\
+	vmovdqa XTMP4, IW_W1W2_ADDR(0, 0);				\
+	vmovdqa XTMP1, IW_W1_ADDR(4, 0);				\
+	vmovdqa XTMP5, IW_W1W2_ADDR(4, 0);
+
+#define LOAD_W_XMM_2()				\
+	vmovdqa XTMP2, IW_W1_ADDR(8, 0);	\
+	vmovdqa XTMP6, IW_W1W2_ADDR(8, 0);
+
+#define LOAD_W_XMM_3()							\
+	vpshufd $0b00000000, XTMP0, W0; /* W0: xx, w0, xx, xx */	\
+	vpshufd $0b11111001, XTMP0, W1; /* W1: xx, w3, w2, w1 */	\
+	vmovdqa XTMP1, W2;              /* W2: xx, w6, w5, w4 */	\
+	vpalignr $12, XTMP1, XTMP2, W3; /* W3: xx, w9, w8, w7 */	\
+	vpalignr $8, XTMP2, XTMP3, W4;  /* W4: xx, w12, w11, w10 */	\
+	vpshufd $0b11111001, XTMP3, W5; /* W5: xx, w15, w14, w13 */
+
+/* Message scheduling. Note: 3 words per XMM register. */
+#define SCHED_W_0(round, w0, w1, w2, w3, w4, w5)			\
+	/* Load (w[i - 16]) => XTMP0 */					\
+	vpshufd $0b10111111, w0, XTMP0;					\
+	vpalignr $12, XTMP0, w1, XTMP0; /* XTMP0: xx, w2, w1, w0 */	\
+	/* Load (w[i - 13]) => XTMP1 */					\
+	vpshufd $0b10111111, w1, XTMP1;					\
+	vpalignr $12, XTMP1, w2, XTMP1;					\
+	/* w[i - 9] == w3 */						\
+	/* XMM3 ^ XTMP0 => XTMP0 */					\
+	vpxor w3, XTMP0, XTMP0;
+
+#define SCHED_W_1(round, w0, w1, w2, w3, w4, w5)	\
+	/* w[i - 3] == w5 */				\
+	/* rol(XMM5, 15) ^ XTMP0 => XTMP0 */		\
+	vpslld $15, w5, XTMP2;				\
+	vpsrld $(32-15), w5, XTMP3;			\
+	vpxor XTMP2, XTMP3, XTMP3;			\
+	vpxor XTMP3, XTMP0, XTMP0;			\
+	/* rol(XTMP1, 7) => XTMP1 */			\
+	vpslld $7, XTMP1, XTMP5;			\
+	vpsrld $(32-7), XTMP1, XTMP1;			\
+	vpxor XTMP5, XTMP1, XTMP1;			\
+	/* XMM4 ^ XTMP1 => XTMP1 */			\
+	vpxor w4, XTMP1, XTMP1;				\
+	/* w[i - 6] == XMM4 */				\
+	/* P1(XTMP0) ^ XTMP1 => XMM0 */			\
+	vpslld $15, XTMP0, XTMP5;			\
+	vpsrld $(32-15), XTMP0, XTMP6;			\
+	vpslld $23, XTMP0, XTMP2;			\
+	vpsrld $(32-23), XTMP0, XTMP3;			\
+	vpxor XTMP0, XTMP1, XTMP1;			\
+	vpxor XTMP6, XTMP5, XTMP5;			\
+	vpxor XTMP3, XTMP2, XTMP2;			\
+	vpxor XTMP2, XTMP5, XTMP5;			\
+	vpxor XTMP5, XTMP1, w0;
+
+#define SCHED_W_2(round, w0, w1, w2, w3, w4, w5)	\
+	/* W1 in XMM12 */				\
+	vpshufd $0b10111111, w4, XTMP4;			\
+	vpalignr $12, XTMP4, w5, XTMP4;			\
+	vmovdqa XTMP4, XW_W1_ADDR((round), 0);		\
+	/* W1 ^ W2 => XTMP1 */				\
+	vpxor w0, XTMP4, XTMP1;				\
+	vmovdqa XTMP1, XW_W1W2_ADDR((round), 0);
+
+
+.section	.rodata.cst16, "aM", @progbits, 16
+.align 16
+
+.Lbe32mask:
+	.long 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f
+
+.text
+
+/*
+ * Transform nblocks*64 bytes (nblocks*16 32-bit words) at DATA.
+ *
+ * void sm3_transform_avx(struct sm3_state *state,
+ *                        const u8 *data, int nblocks);
+ */
+.align 16
+SYM_FUNC_START(sm3_transform_avx)
+	/* input:
+	 *	%rdi: ctx, CTX
+	 *	%rsi: data (64*nblks bytes)
+	 *	%rdx: nblocks
+	 */
+	vzeroupper;
+
+	pushq %rbp;
+	movq %rsp, %rbp;
+
+	movq %rdx, RNBLKS;
+
+	subq $STACK_SIZE, %rsp;
+	andq $(~63), %rsp;
+
+	movq %rbx, (STACK_REG_SAVE + 0 * 8)(%rsp);
+	movq %r15, (STACK_REG_SAVE + 1 * 8)(%rsp);
+	movq %r14, (STACK_REG_SAVE + 2 * 8)(%rsp);
+	movq %r13, (STACK_REG_SAVE + 3 * 8)(%rsp);
+	movq %r12, (STACK_REG_SAVE + 4 * 8)(%rsp);
+
+	vmovdqa .Lbe32mask (%rip), BSWAP_REG;
+
+	/* Get the values of the chaining variables. */
+	movl state_h0(RSTATE), a;
+	movl state_h1(RSTATE), b;
+	movl state_h2(RSTATE), c;
+	movl state_h3(RSTATE), d;
+	movl state_h4(RSTATE), e;
+	movl state_h5(RSTATE), f;
+	movl state_h6(RSTATE), g;
+	movl state_h7(RSTATE), h;
+
+.align 16
+.Loop:
+	/* Load data part1. */
+	LOAD_W_XMM_1();
+
+	leaq -1(RNBLKS), RNBLKS;
+
+	/* Transform 0-3 + Load data part2. */
+	R1(a, b, c, d, e, f, g, h, 0, 0, IW); LOAD_W_XMM_2();
+	R1(d, a, b, c, h, e, f, g, 1, 1, IW);
+	R1(c, d, a, b, g, h, e, f, 2, 2, IW);
+	R1(b, c, d, a, f, g, h, e, 3, 3, IW); LOAD_W_XMM_3();
+
+	/* Transform 4-7 + Precalc 12-14. */
+	R1(a, b, c, d, e, f, g, h, 4, 0, IW);
+	R1(d, a, b, c, h, e, f, g, 5, 1, IW);
+	R1(c, d, a, b, g, h, e, f, 6, 2, IW); SCHED_W_0(12, W0, W1, W2, W3, W4, W5);
+	R1(b, c, d, a, f, g, h, e, 7, 3, IW); SCHED_W_1(12, W0, W1, W2, W3, W4, W5);
+
+	/* Transform 8-11 + Precalc 12-17. */
+	R1(a, b, c, d, e, f, g, h, 8, 0, IW); SCHED_W_2(12, W0, W1, W2, W3, W4, W5);
+	R1(d, a, b, c, h, e, f, g, 9, 1, IW); SCHED_W_0(15, W1, W2, W3, W4, W5, W0);
+	R1(c, d, a, b, g, h, e, f, 10, 2, IW); SCHED_W_1(15, W1, W2, W3, W4, W5, W0);
+	R1(b, c, d, a, f, g, h, e, 11, 3, IW); SCHED_W_2(15, W1, W2, W3, W4, W5, W0);
+
+	/* Transform 12-14 + Precalc 18-20 */
+	R1(a, b, c, d, e, f, g, h, 12, 0, XW); SCHED_W_0(18, W2, W3, W4, W5, W0, W1);
+	R1(d, a, b, c, h, e, f, g, 13, 1, XW); SCHED_W_1(18, W2, W3, W4, W5, W0, W1);
+	R1(c, d, a, b, g, h, e, f, 14, 2, XW); SCHED_W_2(18, W2, W3, W4, W5, W0, W1);
+
+	/* Transform 15-17 + Precalc 21-23 */
+	R1(b, c, d, a, f, g, h, e, 15, 0, XW); SCHED_W_0(21, W3, W4, W5, W0, W1, W2);
+	R2(a, b, c, d, e, f, g, h, 16, 1, XW); SCHED_W_1(21, W3, W4, W5, W0, W1, W2);
+	R2(d, a, b, c, h, e, f, g, 17, 2, XW); SCHED_W_2(21, W3, W4, W5, W0, W1, W2);
+
+	/* Transform 18-20 + Precalc 24-26 */
+	R2(c, d, a, b, g, h, e, f, 18, 0, XW); SCHED_W_0(24, W4, W5, W0, W1, W2, W3);
+	R2(b, c, d, a, f, g, h, e, 19, 1, XW); SCHED_W_1(24, W4, W5, W0, W1, W2, W3);
+	R2(a, b, c, d, e, f, g, h, 20, 2, XW); SCHED_W_2(24, W4, W5, W0, W1, W2, W3);
+
+	/* Transform 21-23 + Precalc 27-29 */
+	R2(d, a, b, c, h, e, f, g, 21, 0, XW); SCHED_W_0(27, W5, W0, W1, W2, W3, W4);
+	R2(c, d, a, b, g, h, e, f, 22, 1, XW); SCHED_W_1(27, W5, W0, W1, W2, W3, W4);
+	R2(b, c, d, a, f, g, h, e, 23, 2, XW); SCHED_W_2(27, W5, W0, W1, W2, W3, W4);
+
+	/* Transform 24-26 + Precalc 30-32 */
+	R2(a, b, c, d, e, f, g, h, 24, 0, XW); SCHED_W_0(30, W0, W1, W2, W3, W4, W5);
+	R2(d, a, b, c, h, e, f, g, 25, 1, XW); SCHED_W_1(30, W0, W1, W2, W3, W4, W5);
+	R2(c, d, a, b, g, h, e, f, 26, 2, XW); SCHED_W_2(30, W0, W1, W2, W3, W4, W5);
+
+	/* Transform 27-29 + Precalc 33-35 */
+	R2(b, c, d, a, f, g, h, e, 27, 0, XW); SCHED_W_0(33, W1, W2, W3, W4, W5, W0);
+	R2(a, b, c, d, e, f, g, h, 28, 1, XW); SCHED_W_1(33, W1, W2, W3, W4, W5, W0);
+	R2(d, a, b, c, h, e, f, g, 29, 2, XW); SCHED_W_2(33, W1, W2, W3, W4, W5, W0);
+
+	/* Transform 30-32 + Precalc 36-38 */
+	R2(c, d, a, b, g, h, e, f, 30, 0, XW); SCHED_W_0(36, W2, W3, W4, W5, W0, W1);
+	R2(b, c, d, a, f, g, h, e, 31, 1, XW); SCHED_W_1(36, W2, W3, W4, W5, W0, W1);
+	R2(a, b, c, d, e, f, g, h, 32, 2, XW); SCHED_W_2(36, W2, W3, W4, W5, W0, W1);
+
+	/* Transform 33-35 + Precalc 39-41 */
+	R2(d, a, b, c, h, e, f, g, 33, 0, XW); SCHED_W_0(39, W3, W4, W5, W0, W1, W2);
+	R2(c, d, a, b, g, h, e, f, 34, 1, XW); SCHED_W_1(39, W3, W4, W5, W0, W1, W2);
+	R2(b, c, d, a, f, g, h, e, 35, 2, XW); SCHED_W_2(39, W3, W4, W5, W0, W1, W2);
+
+	/* Transform 36-38 + Precalc 42-44 */
+	R2(a, b, c, d, e, f, g, h, 36, 0, XW); SCHED_W_0(42, W4, W5, W0, W1, W2, W3);
+	R2(d, a, b, c, h, e, f, g, 37, 1, XW); SCHED_W_1(42, W4, W5, W0, W1, W2, W3);
+	R2(c, d, a, b, g, h, e, f, 38, 2, XW); SCHED_W_2(42, W4, W5, W0, W1, W2, W3);
+
+	/* Transform 39-41 + Precalc 45-47 */
+	R2(b, c, d, a, f, g, h, e, 39, 0, XW); SCHED_W_0(45, W5, W0, W1, W2, W3, W4);
+	R2(a, b, c, d, e, f, g, h, 40, 1, XW); SCHED_W_1(45, W5, W0, W1, W2, W3, W4);
+	R2(d, a, b, c, h, e, f, g, 41, 2, XW); SCHED_W_2(45, W5, W0, W1, W2, W3, W4);
+
+	/* Transform 42-44 + Precalc 48-50 */
+	R2(c, d, a, b, g, h, e, f, 42, 0, XW); SCHED_W_0(48, W0, W1, W2, W3, W4, W5);
+	R2(b, c, d, a, f, g, h, e, 43, 1, XW); SCHED_W_1(48, W0, W1, W2, W3, W4, W5);
+	R2(a, b, c, d, e, f, g, h, 44, 2, XW); SCHED_W_2(48, W0, W1, W2, W3, W4, W5);
+
+	/* Transform 45-47 + Precalc 51-53 */
+	R2(d, a, b, c, h, e, f, g, 45, 0, XW); SCHED_W_0(51, W1, W2, W3, W4, W5, W0);
+	R2(c, d, a, b, g, h, e, f, 46, 1, XW); SCHED_W_1(51, W1, W2, W3, W4, W5, W0);
+	R2(b, c, d, a, f, g, h, e, 47, 2, XW); SCHED_W_2(51, W1, W2, W3, W4, W5, W0);
+
+	/* Transform 48-50 + Precalc 54-56 */
+	R2(a, b, c, d, e, f, g, h, 48, 0, XW); SCHED_W_0(54, W2, W3, W4, W5, W0, W1);
+	R2(d, a, b, c, h, e, f, g, 49, 1, XW); SCHED_W_1(54, W2, W3, W4, W5, W0, W1);
+	R2(c, d, a, b, g, h, e, f, 50, 2, XW); SCHED_W_2(54, W2, W3, W4, W5, W0, W1);
+
+	/* Transform 51-53 + Precalc 57-59 */
+	R2(b, c, d, a, f, g, h, e, 51, 0, XW); SCHED_W_0(57, W3, W4, W5, W0, W1, W2);
+	R2(a, b, c, d, e, f, g, h, 52, 1, XW); SCHED_W_1(57, W3, W4, W5, W0, W1, W2);
+	R2(d, a, b, c, h, e, f, g, 53, 2, XW); SCHED_W_2(57, W3, W4, W5, W0, W1, W2);
+
+	/* Transform 54-56 + Precalc 60-62 */
+	R2(c, d, a, b, g, h, e, f, 54, 0, XW); SCHED_W_0(60, W4, W5, W0, W1, W2, W3);
+	R2(b, c, d, a, f, g, h, e, 55, 1, XW); SCHED_W_1(60, W4, W5, W0, W1, W2, W3);
+	R2(a, b, c, d, e, f, g, h, 56, 2, XW); SCHED_W_2(60, W4, W5, W0, W1, W2, W3);
+
+	/* Transform 57-59 + Precalc 63 */
+	R2(d, a, b, c, h, e, f, g, 57, 0, XW); SCHED_W_0(63, W5, W0, W1, W2, W3, W4);
+	R2(c, d, a, b, g, h, e, f, 58, 1, XW);
+	R2(b, c, d, a, f, g, h, e, 59, 2, XW); SCHED_W_1(63, W5, W0, W1, W2, W3, W4);
+
+	/* Transform 60-62 + Precalc 63 */
+	R2(a, b, c, d, e, f, g, h, 60, 0, XW);
+	R2(d, a, b, c, h, e, f, g, 61, 1, XW); SCHED_W_2(63, W5, W0, W1, W2, W3, W4);
+	R2(c, d, a, b, g, h, e, f, 62, 2, XW);
+
+	/* Transform 63 */
+	R2(b, c, d, a, f, g, h, e, 63, 0, XW);
+
+	/* Update the chaining variables. */
+	xorl state_h0(RSTATE), a;
+	xorl state_h1(RSTATE), b;
+	xorl state_h2(RSTATE), c;
+	xorl state_h3(RSTATE), d;
+	movl a, state_h0(RSTATE);
+	movl b, state_h1(RSTATE);
+	movl c, state_h2(RSTATE);
+	movl d, state_h3(RSTATE);
+	xorl state_h4(RSTATE), e;
+	xorl state_h5(RSTATE), f;
+	xorl state_h6(RSTATE), g;
+	xorl state_h7(RSTATE), h;
+	movl e, state_h4(RSTATE);
+	movl f, state_h5(RSTATE);
+	movl g, state_h6(RSTATE);
+	movl h, state_h7(RSTATE);
+
+	cmpq $0, RNBLKS;
+	jne .Loop;
+
+	vzeroall;
+
+	movq (STACK_REG_SAVE + 0 * 8)(%rsp), %rbx;
+	movq (STACK_REG_SAVE + 1 * 8)(%rsp), %r15;
+	movq (STACK_REG_SAVE + 2 * 8)(%rsp), %r14;
+	movq (STACK_REG_SAVE + 3 * 8)(%rsp), %r13;
+	movq (STACK_REG_SAVE + 4 * 8)(%rsp), %r12;
+
+	vmovdqa %xmm0, IW_W1_ADDR(0, 0);
+	vmovdqa %xmm0, IW_W1W2_ADDR(0, 0);
+	vmovdqa %xmm0, IW_W1_ADDR(4, 0);
+	vmovdqa %xmm0, IW_W1W2_ADDR(4, 0);
+	vmovdqa %xmm0, IW_W1_ADDR(8, 0);
+	vmovdqa %xmm0, IW_W1W2_ADDR(8, 0);
+
+	movq %rbp, %rsp;
+	popq %rbp;
+	ret;
+SYM_FUNC_END(sm3_transform_avx)
diff --git a/arch/x86/crypto/sm3_avx_glue.c b/arch/x86/crypto/sm3_avx_glue.c
new file mode 100644
index 000000000000..661b6f22ffcd
--- /dev/null
+++ b/arch/x86/crypto/sm3_avx_glue.c
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SM3 Secure Hash Algorithm, AVX assembler accelerated.
+ * specified in: https://datatracker.ietf.org/doc/html/draft-sca-cfrg-sm3-02
+ *
+ * Copyright (C) 2021 Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
+ */
+
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <crypto/internal/hash.h>
+#include <crypto/internal/simd.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <crypto/sm3.h>
+#include <crypto/sm3_base.h>
+#include <asm/simd.h>
+
+asmlinkage void sm3_transform_avx(struct sm3_state *state,
+			const u8 *data, int nblocks);
+
+static int sm3_avx_update(struct shash_desc *desc, const u8 *data,
+			 unsigned int len)
+{
+	struct sm3_state *sctx = shash_desc_ctx(desc);
+
+	if (!crypto_simd_usable() ||
+			(sctx->count % SM3_BLOCK_SIZE) + len < SM3_BLOCK_SIZE) {
+		sm3_update(sctx, data, len);
+		return 0;
+	}
+
+	/*
+	 * Make sure struct sm3_state begins directly with the SM3
+	 * 256-bit internal state, as this is what the asm functions expect.
+	 */
+	BUILD_BUG_ON(offsetof(struct sm3_state, state) != 0);
+
+	kernel_fpu_begin();
+	sm3_base_do_update(desc, data, len, sm3_transform_avx);
+	kernel_fpu_end();
+
+	return 0;
+}
+
+static int sm3_avx_finup(struct shash_desc *desc, const u8 *data,
+		      unsigned int len, u8 *out)
+{
+	if (!crypto_simd_usable()) {
+		struct sm3_state *sctx = shash_desc_ctx(desc);
+
+		if (len)
+			sm3_update(sctx, data, len);
+
+		sm3_final(sctx, out);
+		return 0;
+	}
+
+	kernel_fpu_begin();
+	if (len)
+		sm3_base_do_update(desc, data, len, sm3_transform_avx);
+	sm3_base_do_finalize(desc, sm3_transform_avx);
+	kernel_fpu_end();
+
+	return sm3_base_finish(desc, out);
+}
+
+static int sm3_avx_final(struct shash_desc *desc, u8 *out)
+{
+	if (!crypto_simd_usable()) {
+		sm3_final(shash_desc_ctx(desc), out);
+		return 0;
+	}
+
+	kernel_fpu_begin();
+	sm3_base_do_finalize(desc, sm3_transform_avx);
+	kernel_fpu_end();
+
+	return sm3_base_finish(desc, out);
+}
+
+static struct shash_alg sm3_avx_alg = {
+	.digestsize	=	SM3_DIGEST_SIZE,
+	.init		=	sm3_base_init,
+	.update		=	sm3_avx_update,
+	.final		=	sm3_avx_final,
+	.finup		=	sm3_avx_finup,
+	.descsize	=	sizeof(struct sm3_state),
+	.base		=	{
+		.cra_name	=	"sm3",
+		.cra_driver_name =	"sm3-avx",
+		.cra_priority	=	300,
+		.cra_blocksize	=	SM3_BLOCK_SIZE,
+		.cra_module	=	THIS_MODULE,
+	}
+};
+
+static int __init sm3_avx_mod_init(void)
+{
+	const char *feature_name;
+
+	if (!boot_cpu_has(X86_FEATURE_AVX)) {
+		pr_info("AVX instruction are not detected.\n");
+		return -ENODEV;
+	}
+
+	if (!boot_cpu_has(X86_FEATURE_BMI2)) {
+		pr_info("BMI2 instruction are not detected.\n");
+		return -ENODEV;
+	}
+
+	if (!cpu_has_xfeatures(XFEATURE_MASK_SSE | XFEATURE_MASK_YMM,
+				&feature_name)) {
+		pr_info("CPU feature '%s' is not supported.\n", feature_name);
+		return -ENODEV;
+	}
+
+	return crypto_register_shash(&sm3_avx_alg);
+}
+
+static void __exit sm3_avx_mod_exit(void)
+{
+	crypto_unregister_shash(&sm3_avx_alg);
+}
+
+module_init(sm3_avx_mod_init);
+module_exit(sm3_avx_mod_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Tianjia Zhang <tianjia.zhang at linux.alibaba.com>");
+MODULE_DESCRIPTION("SM3 Secure Hash Algorithm, AVX assembler accelerated");
+MODULE_ALIAS_CRYPTO("sm3");
+MODULE_ALIAS_CRYPTO("sm3-avx");
diff --git a/crypto/Kconfig b/crypto/Kconfig
index c236fd0e214e..4f36a5ecd5ba 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -1008,6 +1008,19 @@ config CRYPTO_SM3
 	  http://www.oscca.gov.cn/UpFile/20101222141857786.pdf
 	  https://datatracker.ietf.org/doc/html/draft-shen-sm3-hash
 
+config CRYPTO_SM3_AVX_X86_64
+	tristate "SM3 digest algorithm (x86_64/AVX)"
+	depends on X86 && 64BIT
+	select CRYPTO_HASH
+	select CRYPTO_LIB_SM3
+	help
+	  SM3 secure hash function as defined by OSCCA GM/T 0004-2012 SM3).
+	  It is part of the Chinese Commercial Cryptography suite. This is
+	  SM3 optimized implementation using Advanced Vector Extensions (AVX)
+	  when available.
+
+	  If unsure, say N.
+
 config CRYPTO_STREEBOG
 	tristate "Streebog Hash Function"
 	select CRYPTO_HASH
-- 
2.34.1



From alexandru.elisei at arm.com  Fri Jan  7 04:10:05 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Fri, 7 Jan 2022 12:10:05 +0000
Subject: [PATCH kvmtool 9/9] arm64: Add support for
 KVM_ARM_VCPU_PMU_V3_SET_PMU
In-Reply-To: <87h7ajva2o.wl-maz@kernel.org>
References: <20211115165705.195736-1-alexandru.elisei@arm.com>
 <20211115165705.195736-10-alexandru.elisei@arm.com>
 <87h7ajva2o.wl-maz@kernel.org>
Message-ID: <YdgtnQPAsy1hSOWj@monolith.localdoman>

Hi Marc,

On Tue, Jan 04, 2022 at 02:39:59PM +0000, Marc Zyngier wrote:
> On Mon, 15 Nov 2021 16:57:05 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is
> > used to assign a physical PMU to the events that KVM creates when emulating
> > the PMU for that VCPU. This is useful on heterogeneous systems, when there
> > is more than one hardware PMU present.
> > 
> > The assumption that is made in the implementation is that the user will
> > pin the kvmtool process on a set of CPUs that share the same PMU. This
> > allows kvmtool to set the same PMU for all VCPUs from the main thread,
> > instead of in the individual VCPU threads.
> 
> May I suggest a slightly different use model? Ideally, you'd be able
> to run the vcpu threads on the CPUs matching the PMU affinity, and
> leave all the other threads to roam on other CPUs.

Right now, the only way for userspace to make kvmtool run on a particular
set of CPUs in a heterogeneous configuration is to use taskset, which means
the entire kvmtool process ends up being pinned on a subset of CPUs which
have the same PMU. I would like to keep this approach, as it's simple and
straightforward to implement in kvmtool, and it's easy to change in the
future if there's an incentive to do so.

It's also not clear to me how your suggestion would work. Add a command
line argument to pin all the VCPUs to the specified cpumask?

> 
> With your implementation, the whole of kvmtool gets stuck to a given
> CPU type, which can be problematic.

Do you have a specific use case in mind? Or is it more like a general
concern regarding, for example, the virtio-blk-io or virtio-net-* threads
competing with the VCPU threads if the VM is doing lots of I/O?

Thanks,
Alex


From mhiramat at kernel.org  Fri Jan  7 04:20:46 2022
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Fri, 7 Jan 2022 21:20:46 +0900
Subject: [PATCH v2 2/2] arm64: kprobes: add support for KPROBES_ON_FTRACE
In-Reply-To: <CAAgTQPXi_cmi27upcLHgen3PotOtcu64oAxjYp559g6fYgkCvQ@mail.gmail.com>
References: <1635858706-27320-1-git-send-email-jianhua.ljh@gmail.com>
 <1635858706-27320-2-git-send-email-jianhua.ljh@gmail.com>
 <20211217164019.7d5d9848f350fef4f709c62f@kernel.org>
 <CAAgTQPXi_cmi27upcLHgen3PotOtcu64oAxjYp559g6fYgkCvQ@mail.gmail.com>
Message-ID: <20220107212046.13e55368664b31c2b41b7e94@kernel.org>

On Fri, 7 Jan 2022 01:34:16 +0800
Jianhua Liu <jianhua.ljh at gmail.com> wrote:

> On Fri, Dec 17, 2021 at 3:40 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> >
> > Hi,
> >
> > On Tue,  2 Nov 2021 21:11:46 +0800
> > Janet Liu <jianhua.ljh at gmail.com> wrote:
> >
> > > From: Janet Liu <janet.liu at unisoc.com>
> > >
> > > This patch allow kprobes on ftrace call sites. This optimization
> > > avoids use of a trap with regular kprobes.
> > >
> > > This depends on HAVE_DYNAMIC_FTRACE_WITH_REGS which depends on
> > > "patchable-function-entry" options which is only implemented with newer
> > > toolchains.
> > >
> > > Signed-off-by: Janet Liu <janet.liu at unisoc.com>
> > > ---
> > >  arch/arm64/Kconfig                 |  1 +
> > >  arch/arm64/kernel/probes/Makefile  |  1 +
> > >  arch/arm64/kernel/probes/ftrace.c  | 73 ++++++++++++++++++++++++++++++
> > >  arch/arm64/kernel/probes/kprobes.c | 27 +++++++++++
> > >  4 files changed, 102 insertions(+)
> > >  create mode 100644 arch/arm64/kernel/probes/ftrace.c
> > >
> > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > index 339130712093..f59005608976 100644
> > > --- a/arch/arm64/Kconfig
> > > +++ b/arch/arm64/Kconfig
> > > @@ -200,6 +200,7 @@ config ARM64
> > >       select HAVE_SYSCALL_TRACEPOINTS
> > >       select HAVE_KPROBES
> > >       select HAVE_OPTPROBES
> > > +     select HAVE_KPROBES_ON_FTRACE
> > >       select HAVE_KRETPROBES
> > >       select HAVE_GENERIC_VDSO
> > >       select IOMMU_DMA if IOMMU_SUPPORT
> > > diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> > > index c77c92ac95fd..d9b204f4795a 100644
> > > --- a/arch/arm64/kernel/probes/Makefile
> > > +++ b/arch/arm64/kernel/probes/Makefile
> > > @@ -3,5 +3,6 @@ obj-$(CONFIG_KPROBES)         += kprobes.o decode-insn.o      \
> > >                                  kprobes_trampoline.o         \
> > >                                  simulate-insn.o
> > >  obj-$(CONFIG_OPTPROBES)      += opt.o opt_head.o
> > > +obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
> > >  obj-$(CONFIG_UPROBES)                += uprobes.o decode-insn.o      \
> > >                                  simulate-insn.o
> > > diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
> > > new file mode 100644
> > > index 000000000000..46ea92eb552f
> > > --- /dev/null
> > > +++ b/arch/arm64/kernel/probes/ftrace.c
> > > @@ -0,0 +1,73 @@
> > > +// SPDX-License-Identifier: GPL-2.0-only
> > > +//
> > > +// Dynamic Ftrace based Kprobes Optimization
> > > +//
> > > +// Copyright (C) 2021, Unisoc Inc.
> > > +// Author: Janet Liu <janet.liu at unisoc.com>
> > > +#include <linux/kprobes.h>
> > > +#include <linux/ptrace.h>
> > > +#include <linux/hardirq.h>
> > > +#include <linux/preempt.h>
> > > +#include <linux/ftrace.h>
> > > +
> > > +
> > > +/* Ftrace callback handler for kprobes*/
> > > +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > > +                        struct ftrace_ops *ops, struct ftrace_regs *fregs)
> > > +{
> > > +     struct kprobe *p;
> > > +     struct kprobe_ctlblk *kcb;
> > > +     struct pt_regs *regs = ftrace_get_regs(fregs);
> > > +     int bit;
> > > +
> > > +     bit = ftrace_test_recursion_trylock(ip, parent_ip);
> > > +     if (bit < 0)
> > > +             return;
> > > +
> > > +     preempt_disable_notrace();
> >
> > This already has been done in ftrace side.
> 
> Hi Masami,
> 
> Got it by reading code, will fix this.
> 
> >
> > > +     p = get_kprobe((kprobe_opcode_t *)ip);
> > > +     if (unlikely(!p) || kprobe_disabled(p))
> > > +             goto end;
> > > +
> > > +     kcb = get_kprobe_ctlblk();
> > > +     if (kprobe_running()) {
> > > +             kprobes_inc_nmissed_count(p);
> > > +     } else {
> > > +             unsigned long orig_ip = instruction_pointer(regs);
> > > +
> > > +             instruction_pointer_set(regs, ip);
> >
> > The 'ip' is the address of the 'bl' instruction, which must be
> > p->addr + AARCH64_INSN_SIZE * 2. But this is a bit strange.
> >
> > On aarch64, if the user probe callback is called from breakpoint handler,
> > regs->pc == kp->addr. But in this case, it is not the same.
> >
> > So, what about this?
> >
> >  instruction_pointer_set(regs, ip - AARCH64_INSN_SIZE);
> >
> 
> I got what you said.
> 
> But p->addr is changed when KPROBES_ON_FTRACE enable.
> I implemented kprobe_lookup_name for arm64 to do the change in this patch.

Hmm, that is no good, because printk("%pS\n", p->addr) does not show
what the user set by p->symbol_name. This may confuse user.
Moreover, if user doesn't set symbol_name but addr directly (this
happens when you use 'perf probe' command, which will pass the address
from '_text', not the function entry.

> because kernel/kprobe.c:check_ftrace_location check,
> if p->addr != ftrace_addr, don't kprobe on ftrace entry.
> so p->addr is equal to ftrace addr(the second nop), is equal to 'ip'.
> here should be instruction_pointer_set(regs, ip);

Hmm, OK. this is a special case for the arm64 (and maybe other
architectures except for x86). Let's fix the check_ftrace_location().
We already know that 2 instructions at the beginning of function will
be used for ftrace on arm64. Thus arm64 version of check_ftrace_location()
will check the given address + 1 is ftrace location or not.

> 
> > > +
> > > +             __this_cpu_write(current_kprobe, p);
> > > +             kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> > > +             if (!p->pre_handler || !p->pre_handler(p, regs)) {
> > > +                     /*
> > > +                      *Emulate singlestep (and also recover regs->pc)
> > > +                      *as if there is a nop
> > > +                      */
> > > +                     instruction_pointer_set(regs,
> > > +                                     (unsigned long)p->addr + MCOUNT_INSN_SIZE);
> >
> > And then, this will be
> >
> >                         instruction_pointer_set(regs,
> >                                         (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
> >
> > So basically, kprobes on ftrace will skips 2 NOP instructions (the compiler installed
> > 2 nops) and call post handler. This means we have a virtual big NOP instruction there.
> >
> Ditto, skip two nop instructions should
> instruction_pointer_set(regs,
>                         (unsigned long)p->addr + AARCH64_INSN_SIZE);
> 
> 
> > > +                     if (unlikely(p->post_handler)) {
> > > +                             kcb->kprobe_status = KPROBE_HIT_SSDONE;
> > > +                             p->post_handler(p, regs, 0);
> > > +                     }
> > > +                     instruction_pointer_set(regs, orig_ip);
> > > +             }
> > > +
> > > +             /*
> > > +              * If pre_handler returns !0,it changes regs->pc. We have to
> > > +              * skip emulating post_handler.
> > > +              */
> > > +             __this_cpu_write(current_kprobe, NULL);
> > > +     }
> > > +end:
> > > +     preempt_enable_notrace();
> > > +     ftrace_test_recursion_unlock(bit);
> > > +}
> > > +NOKPROBE_SYMBOL(kprobe_ftrace_handler);
> > > +
> > > +int arch_prepare_kprobe_ftrace(struct kprobe *p)
> > > +{
> > > +     p->ainsn.api.insn = NULL;
> > > +     p->ainsn.api.restore = 0;
> > > +     return 0;
> > > +}
> > > diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> > > index 6dbcc89f6662..3d371d3e4dfa 100644
> > > --- a/arch/arm64/kernel/probes/kprobes.c
> > > +++ b/arch/arm64/kernel/probes/kprobes.c
> > > @@ -417,6 +417,33 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
> > >       return 0;
> > >  }
> > >
> > > +kprobe_opcode_t __kprobes *kprobe_lookup_name(const char *name, unsigned int offset)
> > > +{
> > > +     kprobe_opcode_t *addr;
> > > +
> > > +     addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
> > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > +     if (addr && !offset) {
> > > +             unsigned long faddr;
> > > +
> > > +             faddr = ftrace_location_range((unsigned long)addr,
> > > +                                           (unsigned long)addr + 8);
> >
> > this '8' must be (AARCH64_INSN_SIZE * 2). And here you may need to add
> > a comment why search the 2 instructions. (it is because arm64 uses
> > -fpatchable-function-entry=2.)
> >
> Got it , will fix it.
> > > +             if (faddr)
> > > +                     addr = (kprobe_opcode_t *)faddr;
> > > +     }
> This change the p->addr to ftrace_addr.

Ah, OK. Please forgot above. What we have to do is to change the
check_ftrace_location(), not this conversion.

Thank you,

> 
> > > +#endif
> > > +     return addr;
> > > +}
> > > +
> > > +bool __kprobes arch_kprobe_on_func_entry(unsigned long offset)
> > > +{
> > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > +     return offset <= 8;
> >
> > Ditto.
> Got it, will add comment.
> 
> Thanks
> 
> Jianhua
> >
> > > +#else
> > > +     return !offset;
> > > +#endif
> > > +}
> > > +
> > >  int __init arch_init_kprobes(void)
> > >  {
> > >       register_kernel_break_hook(&kprobes_break_hook);
> > > --
> > > 2.25.1
> > >
> >
> > Thank you,
> >
> >
> > --
> > Masami Hiramatsu <mhiramat at kernel.org>


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From krzysztof.kozlowski at canonical.com  Fri Jan  7 04:47:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 7 Jan 2022 13:47:03 +0100
Subject: [PATCH 0/7] arm/arm64: dts: Remove unused num-viewport from pcie
 node
In-Reply-To: <d3cb7b8439ee3d06@bloch.sibelius.xs4all.nl>
References: <20211229160245.1338-1-jszhang@kernel.org>
 <d3cb7b8439ee3d06@bloch.sibelius.xs4all.nl>
Message-ID: <99115cc4-32f6-d217-68be-33256a6993a8@canonical.com>

On 29/12/2021 17:50, Mark Kettenis wrote:
>> From: Jisheng Zhang <jszhang at kernel.org>
>> Date: Thu, 30 Dec 2021 00:02:38 +0800
>>
>> After commit 281f1f99cf3a("PCI: dwc: Detect number of iATU windows"),
>> the number of iATU windows is detected at runtime, what's more,
>> the 'num-viewport' property parsing has been removed, so remove the
>> unused num-viewport from pcie node(s).
>>
>> It's too late for linux-5.17-rc1, I will rebase and send out v2 if
>> necessary when 5.17-rc1 is released.
> 
> Please no.  This only makes the device trees unnecessarily
> incompatible with older kernels

Anyone who is running a new DTB with older kernel is doomed anyway, not
only because of this change but hundreds of other similar cleanups, e.g.
making DTS conforming to dtschema. Are you sure there are such use cases
of using new DTB with old kernel? I cannot imagine making a stable
product with such scenario...

> and other OSes that do rely on the
> "num-viewport" property.

Right. We should have move the DTS out of the kernel when it was still
small. :)

> It really doesn't hurt to keep this property
> even if future Linux kernels no longer look at it.

For Exynos PCIe, the property is still required by bindings, so
definitely it cannot be removed from DTS. I did not check the other
bindings.

Best regards,
Krzysztof


From thunder.leizhen at huawei.com  Fri Jan  7 05:09:26 2022
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Fri, 7 Jan 2022 21:09:26 +0800
Subject: [PATCH v18 02/17] x86/setup: Move xen_pv_domain() check and
 insert_resource() to setup_arch()
In-Reply-To: <7e7c8d93-e745-2bfd-b93d-aecb3b70bf33@huawei.com>
References: <20211222130820.1754-1-thunder.leizhen@huawei.com>
 <20211222130820.1754-3-thunder.leizhen@huawei.com> <YcSxLodOnxXHx0sV@zn.tnic>
 <d6226aa2-f1f2-24cc-c9d2-9762bd615686@huawei.com>
 <5d8aed79-b20f-2575-3c3f-8945d8cbac3f@huawei.com>
 <7e7c8d93-e745-2bfd-b93d-aecb3b70bf33@huawei.com>
Message-ID: <681a2403-1e1c-1b06-54d0-ca92a7f07e71@huawei.com>



On 2022/1/7 16:13, Leizhen (ThunderTown) wrote:
> 
> 
> On 2021/12/25 9:53, Leizhen (ThunderTown) wrote:
>>
>>
>> On 2021/12/24 14:36, Leizhen (ThunderTown) wrote:
>>>
>>>
>>> On 2021/12/24 1:26, Borislav Petkov wrote:
>>>> On Wed, Dec 22, 2021 at 09:08:05PM +0800, Zhen Lei wrote:
>>>>> From: Chen Zhou <chenzhou10 at huawei.com>
>>>>>
>>>>> We will make the functions reserve_crashkernel() as generic, the
>>>>> xen_pv_domain() check in reserve_crashkernel() is relevant only to
>>>>> x86,
>>>>
>>>> Why is that so? Is Xen-PV x86-only?
>>>>
>>>>> the same as insert_resource() in reserve_crashkernel[_low]().
>>>>
>>>> Why?
>>>>
>>>> Looking at
>>>>
>>>>   0212f9159694 ("x86: Add Crash kernel low reservation")
>>>>
>>>> it *surprisingly* explains why that resources thing is being added:
>>>>
>>>>     We need to add another range in /proc/iomem like "Crash kernel low",
>>>>     so kexec-tools could find that info and append to kdump kernel
>>>>     command line.
>>>>
>>>> Then,
>>>>
>>>>   157752d84f5d ("kexec: use Crash kernel for Crash kernel low")
>>>>
>>>> renamed it because, as it states, kexec-tools was taught to handle
>>>> multiple resources of the same name.
>>>>
>>>> So why does kexec-tools on arm *not* need those iomem resources? How
>>>> does it parse the ranges there? Questions over questions...
> 
> Hi Borislav:
>   The reason why insert_resource() cannot be used in reserve_crashkernel[_low]()
> on arm64 is clear. The parent resource node of crashk[_low]_res is added by
> request_resource() in request_standard_resources(), so that it will be conflicted.
> All request_resource() in request_standard_resources() should be changed to
> insert_resource(), to make insert_resource() can be used in reserve_crashkernel[_low]().
> 
>   I found commit e25e6e7593ca ("kdump, x86: Process multiple Crash kernel in /proc/iomem")
> in kexec-tools. I'm trying to port it to arm64, or make it generic.

Chen Zhou's done it before. But the "Crash kernel (low)" can really be eliminated. Chen
Zhou just used it to distinguish whether the crashkernel memory range is crashkernel load
range or not. We can use get_crash_kernel_load_range() to get and check the load range.


> 
>   Thanks.
> 
>>
>> It's a good question worth figuring out. I'm going to dig into this.
>> I admire your rigorous style and sharp vision.
>>
> 
> 

-- 
Regards,
  Zhen Lei


From broonie at kernel.org  Fri Jan  7 05:10:55 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 7 Jan 2022 13:10:55 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YdgrjWVxRGRtnf5b@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com>
Message-ID: <Ydg733vPQqwhCwtV@sirena.org.uk>

On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:

> Regarding (1), I don't remember whether we decided to do it this way
> because it was more complicated to handle it in the kernel (like the 4
> more patches in this series) or because we wanted to leave the option to
> the dynamic loader. It would be good to clarify this and we may have a
> small window, as Jeremy said, where changing the ABI won't cause
> problems (well, hopefully, there's still a risk).

My understanding is that it was basically just a "let's defer everything
to userspace" thing.  It means that userspace is responsible for turning
on BTI and is therefore responsible for any workarounds which are needed
for problematic binaries, it's the absolute minimum the kernel can be
responsible for.  This all predates my involvement though.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220107/9cd013da/attachment.sig>

From mhocko at suse.com  Fri Jan  7 05:11:29 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 14:11:29 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-7-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
Message-ID: <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz>

On Tue 04-01-22 13:22:25, Yu Zhao wrote:
[...]
> +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
> +{
> +	struct mem_cgroup *memcg;
> +	bool success = false;
> +	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
> +
> +	VM_BUG_ON(!current_is_kswapd());
> +
> +	current->reclaim_state->mm_walk = &pgdat->mm_walk;
> +
> +	memcg = mem_cgroup_iter(NULL, NULL, NULL);
> +	do {
> +		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
> +
> +		if (age_lruvec(lruvec, sc, min_ttl))
> +			success = true;
> +
> +		cond_resched();
> +	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
> +
> +	if (!success && mutex_trylock(&oom_lock)) {
> +		struct oom_control oc = {
> +			.gfp_mask = sc->gfp_mask,
> +			.order = sc->order,
> +		};
> +
> +		if (!oom_reaping_in_progress())
> +			out_of_memory(&oc);
> +
> +		mutex_unlock(&oom_lock);
> +	}

Why do you need to trigger oom killer from this path? Why cannot you
rely on the page allocator to do that like we do now?
-- 
Michal Hocko
SUSE Labs


From mark.rutland at arm.com  Fri Jan  7 05:19:27 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 13:19:27 +0000
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <20220107085536.214501-1-heying24@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
Message-ID: <Ydg939btY/bzEAe4@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 03:55:36AM -0500, He Ying wrote:
> Our product has been updating its kernel from 4.4 to 5.10 recently and
> found a performance issue. We do a bussiness test called ARP test, which
> tests the latency for a ping-pong packets traffic with a certain payload.
> The result is as following.
> 
>  - 4.4 kernel: avg = ~20s
>  - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s

Have you tested with a recent mainline kernel, e.g. v5.15?

Is this test publicly available, and can you say which hardrware (e.g. which
CPU implementation) you're testing with?

> I have been just learning arm64 pseudo-NMI code and have a question,
> why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?

The code in question is all patched via alternatives, and when
CONFIG_ARM64_PSEUDO_NMI is not selected, the code was expected to only have the
overhead of the regular DAIF manipulation.

> I wonder if this brings some performance regression.
> 
> First, I make this patch and then do the test again. Here's the result.
> 
>  - 5.10 kernel with this patch not applied: avg = ~40s
>  - 5.10 kernel with this patch applied: avg = ~23s
> 
> Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
> set. It seems the pseudo-NMI feature actually brings some overhead to
> performance event if CONFIG_ARM64_PSEUDO_NMI is not set.

I'm surprised the overhead is so significant; as above this is all patched in
and so the overhead when this is disabled is expected to be *extremely* small.

For example, wjen CONFIG_ARM64_PSEUDO_NMI, in arch_local_irq_enable():

* The portion under the system_has_prio_mask_debugging() test will be removed
  entirely by the compiler, as this internally checks
  IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI).

* The assembly will be left as a write to DAIFClr. The only additional cost
  should be that of generating GIC_PRIO_IRQON into a register.

* The pmr_sync() will be removed entirely by the compiler as is defined
  conditionally dependent on CONFIG_ARM64_PSEUDO_NMI.

I can't spot an obvious issue with that or ther other cases. In the common case
those add no new instructions, and in the worst case they only add NOPs.

> Furthermore, I find the feature also brings some overhead to vmlinux size.
> I build 5.10 kernel with this patch applied or not while
> CONFIG_ARM64_PSEUDO_NMI is not set.
> 
>  - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
>  - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
> 
> That means arm64 pseudo-NMI feature may bring ~200KB overhead to
> vmlinux size.

I suspect that's just the (unused) alternatives, and we could improve that by
passing the config into the alternative blocks.

> Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
> and performance even if config is not set. To avoid it, add macro control
> all around the related code.
> 
> Signed-off-by: He Ying <heying24 at huawei.com>
> ---
>  arch/arm64/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++--
>  arch/arm64/kernel/entry.S         |  4 ++++
>  2 files changed, 40 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
> index b57b9b1e4344..82f771b41cf5 100644
> --- a/arch/arm64/include/asm/irqflags.h
> +++ b/arch/arm64/include/asm/irqflags.h
> @@ -26,6 +26,7 @@
>   */
>  static inline void arch_local_irq_enable(void)
>  {
> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>  	if (system_has_prio_mask_debugging()) {
>  		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
>  
> @@ -41,10 +42,18 @@ static inline void arch_local_irq_enable(void)
>  		: "memory");
>  
>  	pmr_sync();
> +#else
> +	asm volatile(
> +		"msr	daifclr, #3		// arch_local_irq_enable"
> +		:
> +		:
> +		: "memory");
> +#endif

I'm happy to rework this to improve matters, but I am very much not happy with
duplicating the logic for the !PSEUDO_NMI case. Adding more ifdeffery and
copies of that is not acceptable.

Instead, can you please try changing the alternative to also take the config,
e.g. here have:

|       asm volatile(ALTERNATIVE(
|               "msr    daifclr, #3             // arch_local_irq_enable",
|               __msr_s(SYS_ICC_PMR_EL1, "%0"),
|               ARM64_HAS_IRQ_PRIO_MASKING,
|               CONFIG_ARM64_PSEUDO_NMI)
|               :   
|               : "r" ((unsigned long) GIC_PRIO_IRQON)
|               : "memory");

... and see if that makes a significant difference?

Likewise for the other casees.

>  #endif /* __ASM_IRQFLAGS_H */
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 2f69ae43941d..ffc32d3d909a 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -300,6 +300,7 @@ alternative_else_nop_endif
>  	str	w21, [sp, #S_SYSCALLNO]
>  	.endif
>  
> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>  	/* Save pmr */
>  alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>  	mrs_s	x20, SYS_ICC_PMR_EL1
> @@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>  	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
>  	msr_s	SYS_ICC_PMR_EL1, x20
>  alternative_else_nop_endif
> +#endif
>  
>  	/* Re-enable tag checking (TCO set on exception entry) */
>  #ifdef CONFIG_ARM64_MTE
> @@ -330,6 +332,7 @@ alternative_else_nop_endif
>  	disable_daif
>  	.endif
>  
> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>  	/* Restore pmr */
>  alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>  	ldr	x20, [sp, #S_PMR_SAVE]
> @@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>  	dsb	sy				// Ensure priority change is seen by redistributor
>  .L__skip_pmr_sync\@:
>  alternative_else_nop_endif
> +#endif

For these two I think the ifdeffery is fine, but I'm surprised this has a
measureable impact as the alternatives should be initialized to NOPS (and never
modified).

Thanks,
Mark.


From linux at armlinux.org.uk  Fri Jan  7 05:40:06 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 7 Jan 2022 13:40:06 +0000
Subject: [PATCH CFT net-next 0/6] net: stmmac/xpcs: modernise PCS support
In-Reply-To: <20211217055729.GA14835@linux.intel.com>
References: <Ybs7DNDkBrf73jDi@shell.armlinux.org.uk>
 <20211217055729.GA14835@linux.intel.com>
Message-ID: <YdhCts9ZPMyzO8oX@shell.armlinux.org.uk>

On Fri, Dec 17, 2021 at 01:57:29PM +0800, Wong Vee Khee wrote:
> On Thu, Dec 16, 2021 at 01:11:40PM +0000, Russell King (Oracle) wrote:
> > Hi,
> > 
> > This series updates xpcs and stmmac for the recent changes to phylink
> > to better support split PCS and to get rid of private MAC validation
> > functions.
> > 
> > This series is slightly more involved than other conversions as stmmac
> > has already had optional proper split PCS support.
> > 
> > The patches:
> > 
> > 1) Provide a function to query the xpcs for the interface modes that
> >    are supported.
> > 
> > 2) Populates the MAC capabilities and switches stmmac_validate() to use
> >    phylink_get_linkmodes(). We do not use phylink_generic_validate() yet
> >    as (a) we do not always have the supported interfaces populated, and
> >    (b) the existing code does not restrict based on interface. There
> >    should be no functional effect from this patch.
> > 
> > 3) Populates phylink's supported interfaces from the xpcs when the xpcs
> >    is configured by firmware and also the firmware configured interface
> >    mode. Note: this will restrict stmmac to only supporting these
> >    interfaces modes - stmmac maintainers need to verify that this
> >    behaviour is acceptable.
> > 
> > 4) stmmac_validate() tail-calls xpcs_validate(), but we don't need it to
> >    now that PCS have their own validation method. Convert stmmac and
> >    xpcs to use this method instead.
> > 
> > 5) xpcs sets the poll field of phylink_pcs to true, meaning xpcs
> >    requires its status to be polled. There is no need to also set the
> >    phylink_config.pcs_poll. Remove this.
> > 
> > 6) Switch to phylink_generic_validate(). This is probably the most
> >    contravertial change in this patch set as this will cause the MAC to
> >    restrict link modes based on the interface mode. From an inspection
> >    of the xpcs driver, this should be safe, as XPCS only further
> >    restricts the link modes to a subset of these (whether that is
> >    correct or not is not an issue I am addressing here.) For
> >    implementations that do not use xpcs, this is a more open question
> >    and needs feedback from stmmac maintainers.
> > 
> > Please review and test this series. Thanks!
> > 
> 
> Tested this patch series on my Intel Elkhart Lake setup with Marvell
> 88E1510 PHY. 
> 
> Everything works perfectly!

Can I take that as a tested-by please?

It would be good to get some feedback from other stmmac users, since I
believe stmmac is used in multiple different configurations.

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From alexander.stein at ew.tq-group.com  Fri Jan  7 05:43:02 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 07 Jan 2022 14:43:02 +0100
Subject: (EXT) RE: [PATCH v2 0/3] i.MX8MP: more USB3 glue layer feature
 support
In-Reply-To: <VI1PR04MB43337694F243F8D1B1F6DBCE897D9@VI1PR04MB4333.eurprd04.prod.outlook.com>
References: <20211216160541.544974-1-alexander.stein@ew.tq-group.com>
 <VI1PR04MB43337694F243F8D1B1F6DBCE897D9@VI1PR04MB4333.eurprd04.prod.outlook.com>
Message-ID: <4835974.GXAFRqVoOG@steina-w>

Hi,

Am Mittwoch, 22. Dezember 2021, 04:18:57 CET schrieb Jun Li:
> > -----Original Message-----
> > From: Alexander Stein <alexander.stein at ew.tq-group.com>
> > Sent: Friday, December 17, 2021 12:06 AM
> > To: Kishon Vijay Abraham I <kishon at ti.com>; Vinod Koul <vkoul at kernel.org>;
> > Rob Herring <robh+dt at kernel.org>; Shawn Guo <shawnguo at kernel.org>; Sascha
> > Hauer <s.hauer at pengutronix.de>; Fabio Estevam <festevam at gmail.com>
> > Cc: Alexander Stein <alexander.stein at ew.tq-group.com>; dl-linux-imx
> > <linux-imx at nxp.com>; linux-phy at lists.infradead.org;
> > devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> > Subject: [PATCH v2 0/3] i.MX8MP: more USB3 glue layer feature support
> > 
> > This patchset aims to support flags for e.g. over-current active low or
> > port permanantly attached which are provided in the USB3 glue layer.
> > 
> > There is already a glue layer driver dwc3-imx8mp, but unfortunately this
> > driver does not use the glue area at all, it only handles wakeup-support
> > which is done in the HSIO BLK_CTRL area (0x32f10100), accordingly the
> > driver only uses the hsio clock.
> > 
> > The driver which actually uses the USB3 glue area is phy-fsl-imx8mq-usb.
> > As the name indicates PHY is configured in the corresponding registers,
> > which are part of the USB3 glue layer.
> > 
> > This make is it unclear for me which driver should handle the required
> > features above.
> > dwc3-imx8mp, the glue layer driver, does not touch the glue area at all,
> > but the HSIO BLK_CTRL area.
> > phy-fsl-imx8mq-usb only touches the PHY registers in the glue layer.
> > Neither does map the USB3 control register from the glue layer.
> > 
> > Thanks for any feedback and best regards, Alexander
> 
> Which driver handle what function is decided by the driver *function*,
> not where the actual HW logic is located, iMX8MP do have a "glue" layer
> in SoC HW, some part is for phy config, and some part is for controller,
> so we need put the part of phy config into the phy driver, the changes
> you are adding is for controller so should be put in dwc3-imx8mp.c from
> my point view.

Thanks for that feedback. This makes things clearer to me.
Yes, dwc3-imx8mp.c seems the right place for that. I'll do that.

Best regards,
Alexander





From vee.khee.wong at linux.intel.com  Fri Jan  7 05:47:17 2022
From: vee.khee.wong at linux.intel.com (Wong Vee Khee)
Date: Fri, 7 Jan 2022 21:47:17 +0800
Subject: [PATCH CFT net-next 0/6] net: stmmac/xpcs: modernise PCS support
In-Reply-To: <YdhCts9ZPMyzO8oX@shell.armlinux.org.uk>
References: <Ybs7DNDkBrf73jDi@shell.armlinux.org.uk>
 <20211217055729.GA14835@linux.intel.com>
 <YdhCts9ZPMyzO8oX@shell.armlinux.org.uk>
Message-ID: <20220107134717.GA10144@linux.intel.com>

On Fri, Jan 07, 2022 at 01:40:06PM +0000, Russell King (Oracle) wrote:
> On Fri, Dec 17, 2021 at 01:57:29PM +0800, Wong Vee Khee wrote:
> > On Thu, Dec 16, 2021 at 01:11:40PM +0000, Russell King (Oracle) wrote:
> > > Hi,
> > > 
> > > This series updates xpcs and stmmac for the recent changes to phylink
> > > to better support split PCS and to get rid of private MAC validation
> > > functions.
> > > 
> > > This series is slightly more involved than other conversions as stmmac
> > > has already had optional proper split PCS support.
> > > 
> > > The patches:
> > > 
> > > 1) Provide a function to query the xpcs for the interface modes that
> > >    are supported.
> > > 
> > > 2) Populates the MAC capabilities and switches stmmac_validate() to use
> > >    phylink_get_linkmodes(). We do not use phylink_generic_validate() yet
> > >    as (a) we do not always have the supported interfaces populated, and
> > >    (b) the existing code does not restrict based on interface. There
> > >    should be no functional effect from this patch.
> > > 
> > > 3) Populates phylink's supported interfaces from the xpcs when the xpcs
> > >    is configured by firmware and also the firmware configured interface
> > >    mode. Note: this will restrict stmmac to only supporting these
> > >    interfaces modes - stmmac maintainers need to verify that this
> > >    behaviour is acceptable.
> > > 
> > > 4) stmmac_validate() tail-calls xpcs_validate(), but we don't need it to
> > >    now that PCS have their own validation method. Convert stmmac and
> > >    xpcs to use this method instead.
> > > 
> > > 5) xpcs sets the poll field of phylink_pcs to true, meaning xpcs
> > >    requires its status to be polled. There is no need to also set the
> > >    phylink_config.pcs_poll. Remove this.
> > > 
> > > 6) Switch to phylink_generic_validate(). This is probably the most
> > >    contravertial change in this patch set as this will cause the MAC to
> > >    restrict link modes based on the interface mode. From an inspection
> > >    of the xpcs driver, this should be safe, as XPCS only further
> > >    restricts the link modes to a subset of these (whether that is
> > >    correct or not is not an issue I am addressing here.) For
> > >    implementations that do not use xpcs, this is a more open question
> > >    and needs feedback from stmmac maintainers.
> > > 
> > > Please review and test this series. Thanks!
> > > 
> > 
> > Tested this patch series on my Intel Elkhart Lake setup with Marvell
> > 88E1510 PHY. 
> > 
> > Everything works perfectly!
> 
> Can I take that as a tested-by please?
> 

Sure.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL

> It would be good to get some feedback from other stmmac users, since I
> believe stmmac is used in multiple different configurations.
> 
> Thanks!
> 
> -- 
> RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
> FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From lkp at intel.com  Fri Jan  7 05:47:47 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 07 Jan 2022 21:47:47 +0800
Subject: [soc:for-next] BUILD SUCCESS b6b2e59680e75666a65c0095aeb77500bdda7db9
Message-ID: <61d84483.F/tKvxuAB1WbhXKO%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: b6b2e59680e75666a65c0095aeb77500bdda7db9  ARM: Document merges

elapsed time: 911m

configs tested: 142
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20220107
powerpc              randconfig-c003-20220107
arm                       imx_v6_v7_defconfig
arm                       omap2plus_defconfig
arm                            lart_defconfig
sh                        sh7763rdp_defconfig
sh                           se7343_defconfig
sh                     sh7710voipgw_defconfig
sh                           se7721_defconfig
sh                            shmin_defconfig
arc                          axs101_defconfig
powerpc                     taishan_defconfig
sh                        edosk7705_defconfig
powerpc                 mpc834x_itx_defconfig
sparc                       sparc64_defconfig
powerpc                        warp_defconfig
xtensa                  cadence_csp_defconfig
sh                          r7780mp_defconfig
mips                      loongson3_defconfig
ia64                      gensparse_defconfig
openrisc                    or1ksim_defconfig
m68k                        mvme147_defconfig
sh                          lboxre2_defconfig
sh                      rts7751r2d1_defconfig
xtensa                       common_defconfig
powerpc                      chrp32_defconfig
powerpc                      mgcoge_defconfig
mips                           jazz_defconfig
arm                           viper_defconfig
arc                         haps_hs_defconfig
mips                         mpc30x_defconfig
xtensa                    smp_lx200_defconfig
sparc64                          alldefconfig
arm                           h5000_defconfig
arm                          badge4_defconfig
sh                        dreamcast_defconfig
sh                          polaris_defconfig
m68k                       m5208evb_defconfig
m68k                          sun3x_defconfig
sh                            migor_defconfig
mips                         cobalt_defconfig
arm                  randconfig-c002-20220107
arm                  randconfig-c002-20220106
ia64                             allyesconfig
ia64                             allmodconfig
ia64                                defconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
s390                                defconfig
parisc                           allyesconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20220107
x86_64               randconfig-a001-20220107
x86_64               randconfig-a004-20220107
x86_64               randconfig-a006-20220107
x86_64               randconfig-a002-20220107
x86_64               randconfig-a003-20220107
i386                 randconfig-a003-20220107
i386                 randconfig-a005-20220107
i386                 randconfig-a004-20220107
i386                 randconfig-a006-20220107
i386                 randconfig-a002-20220107
i386                 randconfig-a001-20220107
x86_64               randconfig-a012-20220106
x86_64               randconfig-a015-20220106
x86_64               randconfig-a014-20220106
x86_64               randconfig-a013-20220106
x86_64               randconfig-a011-20220106
x86_64               randconfig-a016-20220106
s390                 randconfig-r044-20220106
riscv                randconfig-r042-20220106
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
mips                 randconfig-c004-20220107
arm                  randconfig-c002-20220107
i386                 randconfig-c001-20220107
riscv                randconfig-c006-20220107
powerpc              randconfig-c003-20220107
x86_64               randconfig-c007-20220107
powerpc                      ppc44x_defconfig
mips                        qi_lb60_defconfig
arm                          collie_defconfig
powerpc                          allyesconfig
arm                         s5pv210_defconfig
arm                         palmz72_defconfig
powerpc                 xes_mpc85xx_defconfig
mips                      bmips_stb_defconfig
x86_64               randconfig-a012-20220107
x86_64               randconfig-a015-20220107
x86_64               randconfig-a014-20220107
x86_64               randconfig-a013-20220107
x86_64               randconfig-a011-20220107
x86_64               randconfig-a016-20220107
i386                 randconfig-a012-20220107
i386                 randconfig-a016-20220107
i386                 randconfig-a014-20220107
i386                 randconfig-a015-20220107
i386                 randconfig-a011-20220107
i386                 randconfig-a013-20220107
hexagon              randconfig-r041-20220107
hexagon              randconfig-r045-20220107
riscv                randconfig-r042-20220107

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mark.rutland at arm.com  Fri Jan  7 05:49:43 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 13:49:43 +0000
Subject: [boot-wrapper PATCH v2 2/9] Add standard headers
In-Reply-To: <20211222181607.1203191-3-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-3-andre.przywara@arm.com>
Message-ID: <YdhE99enrMBNysxI@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:00PM +0000, Andre Przywara wrote:
> So far we were relying on some standard C headers to be provided by the
> toolchain. This applies for instance to stddef.h and stdint.h.
> As a "bare-metal" application, we should not rely on external headers,
> or even on a toolchain providing them in the first place.
> 
> Define our own version of stddef.h and stdint.h, containing just the
> types that we actually need.

Even a freestanding compiler implementation is required to provide these
headers, and using the compiler versions would avoid unexpected mismatches
(e.g. for builtins). So I don't think the justification as written makes sense.

Is this because the next patch removes the stdinc paths, and so we don't get
the compiler's implementation of these headers?

Thanks,
Mark.

> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/aarch32/include/stdint.h | 19 +++++++++++++++++++
>  arch/aarch64/include/stdint.h | 19 +++++++++++++++++++
>  include/stddef.h              | 15 +++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 arch/aarch32/include/stdint.h
>  create mode 100644 arch/aarch64/include/stdint.h
>  create mode 100644 include/stddef.h
> 
> diff --git a/arch/aarch32/include/stdint.h b/arch/aarch32/include/stdint.h
> new file mode 100644
> index 0000000..77546f0
> --- /dev/null
> +++ b/arch/aarch32/include/stdint.h
> @@ -0,0 +1,19 @@
> +/*
> + * arch/aarch32/include/stdint.h
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef STDINT_H__
> +#define STDINT_H__
> +
> +typedef unsigned char		uint8_t;
> +typedef unsigned short int	uint16_t;
> +typedef unsigned int		uint32_t;
> +typedef unsigned long long int	uint64_t;
> +
> +typedef unsigned int		uintptr_t;
> +
> +#endif
> diff --git a/arch/aarch64/include/stdint.h b/arch/aarch64/include/stdint.h
> new file mode 100644
> index 0000000..92c2603
> --- /dev/null
> +++ b/arch/aarch64/include/stdint.h
> @@ -0,0 +1,19 @@
> +/*
> + * arch/aarch64/include/stdint.h
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef STDINT_H__
> +#define STDINT_H__
> +
> +typedef unsigned char		uint8_t;
> +typedef unsigned short int	uint16_t;
> +typedef unsigned int		uint32_t;
> +typedef unsigned long int	uint64_t;
> +
> +typedef unsigned long int	uintptr_t;
> +
> +#endif
> diff --git a/include/stddef.h b/include/stddef.h
> new file mode 100644
> index 0000000..3208b10
> --- /dev/null
> +++ b/include/stddef.h
> @@ -0,0 +1,15 @@
> +/*
> + * include/stddef.h - standard data type definitions
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef STDDEF_H__
> +#define STDDEF_H__
> +
> +typedef unsigned long int	size_t;
> +typedef signed long int		ssize_t;
> +
> +#endif
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 05:49:54 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 13:49:54 +0000
Subject: [boot-wrapper PATCH v2 1/9] Makefile: Avoid .got section creation
In-Reply-To: <20211222181607.1203191-2-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-2-andre.przywara@arm.com>
Message-ID: <YdhFAvJoo0vt6CCT@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:15:59PM +0000, Andre Przywara wrote:
> At the moment we build the boot-wrapper with the default toolchain
> settings, which has issues if that is a toolchain targeted to Linux
> userland, for instance. Since boot-wrapper is rather simple, we get away
> with this, *mostly*, but there is at least one case where this breaks:
> Many distributions enable PIE builds by default when building GCC, so by
> just calling "gcc" we build the .o files for PIE (although we don't link
> them accordingly, since we use "ld" directly).
> When we moved the PSCI code from assembly to C, we also introduced
> global variables, which a PIE enabled GCC will put into a .got section
> (global offset table), to be able to easily relocate them at runtime
> (if needed). This section happens to be outside of the memory region
> we reserve, so can (and will be) overwritten by Linux at some point.
> Doing PSCI calls afterwards does not end well then. "memtest=1" is one
> way to trigger this.
> 
> To avoid the (in our case pointless) creation of the GOT, we specify
> -fno-pic and -fno-pie, to override any potential toolchain default.
> 
> This fixes boot-wrapper builds on many distro compilers, for instance
> as provided by Ubuntu and Arch Linux.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Thanks; applied.

Mark.

> ---
>  Makefile.am | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Makefile.am b/Makefile.am
> index d0a68df..3e970a3 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -126,6 +126,7 @@ CPPFLAGS	+= $(INITRD_FLAGS)
>  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
>  CFLAGS		+= -Wall -fomit-frame-pointer
>  CFLAGS		+= -ffunction-sections -fdata-sections
> +CFLAGS		+= -fno-pic -fno-pie
>  LDFLAGS		+= --gc-sections
>  
>  OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> -- 
> 2.25.1
> 


From alexander.stein at ew.tq-group.com  Fri Jan  7 05:50:55 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 07 Jan 2022 14:50:55 +0100
Subject: (EXT) Re: [PATCH v2 1/3] dt-bindings: phy: imx8mq-usb-phy: Add
 imx8mp specific flags
In-Reply-To: <YcIICIKjbgEn0I+P@robh.at.kernel.org>
References: <20211216160541.544974-1-alexander.stein@ew.tq-group.com>
 <20211216160541.544974-2-alexander.stein@ew.tq-group.com>
 <YcIICIKjbgEn0I+P@robh.at.kernel.org>
Message-ID: <2245006.irdbgypaU6@steina-w>

Hello,

thanks for the review.

Am Dienstag, 21. Dezember 2021, 17:59:52 CET schrieb Rob Herring:
> On Thu, Dec 16, 2021 at 05:05:39PM +0100, Alexander Stein wrote:
> > This adds bindings for features only available on imx8mp. They allow
> > setting polarity of PWR and OC as well as disabling port power control.
> > Also permanently atteched can be annotated as well.
> > 
> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > Adding properties specific to one compatible globally and disabling them
> > on
> > other compatibles is the way to go?
> > 
> > Are there any best practices on the usage of '-' and/or '_' in property
> > names?
> Yes, don't use '_'.

Alright, got it.

> >  .../bindings/phy/fsl,imx8mq-usb-phy.yaml      | 52 ++++++++++++++++++-
> >  1 file changed, 51 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
> > b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml index
> > 2936f3510a6a..1d28b7d1c413 100644
> > --- a/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
> > +++ b/Documentation/devicetree/bindings/phy/fsl,imx8mq-usb-phy.yaml
> > 
> > @@ -16,7 +16,8 @@ properties:
> >        - fsl,imx8mp-usb-phy
> >    
> >    reg:
> > -    maxItems: 1
> > +    minItems: 1
> > +    maxItems: 2
> > 
> >    "#phy-cells":
> >      const: 0
> > 
> > @@ -32,6 +33,28 @@ properties:
> >      description:
> >        A phandle to the regulator for USB VBUS.
> > 
> > +  fsl,permanently-attached:
> > +    type: boolean
> > +    description:
> > +      Indicates if the device atached to a downstream port is
> > +      permanently attached.
> 
> Wouldn't just describing the downstream device be enough to indicate
> this? Though that is in the host controller rather than the phy.

You mean describing the downstream hub in device tree? I guess you are 
thinking about Documentation/devicetree/bindings/usb/usb-device.yaml, no?
I'll try using this.

This flag (and the others below) are used to set some specific flag in the 
host controller (not the PHY, see Li Jun's response). But I have to admit I do 
not know what they actually do. The description is pretty much everything 
written in the reference manual.

> > +
> > +  fsl,disable-port-power-control:
> > +    type: boolean
> > +    description:
> > +      Indicates whether the host controller implementation includes port
> > +      power control. Defines Bit 3 in capability register (HCCPARAMS).
> > +
> > +  fsl,over-current-active-low:
> > +    type: boolean
> > +    description:
> > +      Over current signal polarity is active low.
> > +
> > +  fsl,power-active-low:
> > +    type: boolean
> > +    description:
> > +      Power pad (PWR) polarity is active low.
> > +
> > 
> >  required:
> >    - compatible
> >    - reg
> > 
> > @@ -39,6 +62,33 @@ required:
> >    - clocks
> >    - clock-names
> > 
> > +if:
> > +  properties:
> > +    compatible:
> > +      contains:
> > +        enum:
> > +          - fsl,imx8mp-usb-phy
> > +
> > +then:
> > +  properties:
> > +    reg:
> > +      minItems: 2
> > +      maxItems: 2
> > +      items:
> > +        - description: PHY register base address
> > +        - description: Glue layer base address
> 
> Move 'items' to the top level and then here you only need 'minItems: 2'.
> 
> > +
> > +else:
> > +  properties:
> > +    reg:
> > +      maxItems: 1
> > +      items:
> > +        - description: PHY register base address
> 
> And just 'maxItems' here.

Thanks for the hints on how to write bindings, still fiddling with it.

Best regards,
Alexander





From mark.rutland at arm.com  Fri Jan  7 05:53:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 13:53:50 +0000
Subject: [boot-wrapper PATCH v2 3/9] Makefile: Tell compiler to generate
 bare-metal code
In-Reply-To: <20211222181607.1203191-4-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-4-andre.przywara@arm.com>
Message-ID: <YdhF7kluP5vwzDf4@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:01PM +0000, Andre Przywara wrote:
> Our GCC invocation does not provide many parameters, which lets the
> toolchain fill in its own default setup.
> In case of a native build or when using a full-featured cross-compiler,
> this probably means Linux userland, which is not what we want for a
> bare-metal application like boot-wrapper.
> 
> Tell the compiler to forget about those standard settings, and only use
> what we explicitly ask for. In particular that means to not use toolchain
> provided libraries and headers, since they might pull in more code than
> we want, and might not run well in the boot-wrapper environment.
> 
> This also enables optimisation, since it produces much better code and
> tends to avoid problems due to missing inlining, for instance.

I'd appreciate if we could add some explanation for these (just in the commit
message is fine), as e.g. it's not clear to me why -fno-toplevel-reorder is
necessary.

Thanks,
Mark.

> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Makefile.am | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 3e970a3..d9ad6d1 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -124,9 +124,14 @@ CHOSEN_NODE	:= chosen {						\
>  
>  CPPFLAGS	+= $(INITRD_FLAGS)
>  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
> -CFLAGS		+= -Wall -fomit-frame-pointer
> +CFLAGS		+= -Wall -Wstrict-prototypes -fomit-frame-pointer
> +CFLAGS		+= -ffreestanding -nostdinc -nostdlib
> +CFLAGS		+= -fno-common -fno-strict-aliasing -fno-stack-protector
> +CFLAGS		+= -fno-toplevel-reorder
> +CFLAGS		+= -fno-unwind-tables -fno-asynchronous-unwind-tables
>  CFLAGS		+= -ffunction-sections -fdata-sections
>  CFLAGS		+= -fno-pic -fno-pie
> +CFLAGS		+= -Os
>  LDFLAGS		+= --gc-sections
>  
>  OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 05:59:49 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 13:59:49 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <20211222181607.1203191-10-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
Message-ID: <YdhHVbOvkL+pOOyN@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:07PM +0000, Andre Przywara wrote:
> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> the blob first, then re-compile it with our nodes and properties added.
> 
> In our input DTB the proper phandle references have already been lost,
> all we see in the DTB is phandle properties in the target node, and some
> numbers in the clocks and gpios properties:
> ===========
> 	clk24mhz {
> 		compatible = "fixed-clock";
> 		#clock-cells = <0x00>;
> 		clock-frequency = <0x16e3600>;
> 		clock-output-names = "v2m:clk24mhz";
> ->		phandle = <0x05>;
> 	};
> 	...
> 	serial at 90000 {
> 		compatible = "arm,pl011", "arm,primecell";
> 		reg = <0x90000 0x1000>;
> 		interrupts = <0x05>;
> ->		clocks = <0x05 0x05>;
> 		clock-names = "uartclk", "apb_pclk";
> 	};
> ===========
> dtc warns that those numbers might be wrong:
> =========
> <stdin>:177.6-27: Warning (clocks_property):
>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
>    clocks: cell 0 is not a phandle reference
> ....
> =========
> The proper solution would be to use references (&v2m_clk24mhz) instead,
> as there are in the source .dts file, but we don't have that information
> anymore, and cannot easily recover it.
> 
> To avoid the lengthy list of warnings, just drop those checks from the
> dtc compilation run. This disables more checks than we want or need, but
> we somewhat trust in the original DTB to be sane, so that should be
> fine.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Thanks; applied.

Mark.

> ---
>  Makefile.am | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 3d8128f..430b4a9 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
>  
>  fdt.dtb: $(KERNEL_DTB) Makefile
> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
>  
>  # The filesystem archive might not exist if INITRD is not being used
>  .PHONY: all clean $(FILESYSTEM)
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:01:37 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:01:37 +0000
Subject: [boot-wrapper PATCH v2 6/9] configure: Use earlycon instead of
 earlyprintk
In-Reply-To: <20211222181607.1203191-7-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-7-andre.przywara@arm.com>
Message-ID: <YdhHwXr0pp9d+nRn@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:04PM +0000, Andre Przywara wrote:
> The arm64 Linux kernel dropped support for the "earlyprintk" command line
> parameter a long time ago[1], instead it uses the earlycon parameter
> now.
> 
> Replace earlyprintk with earlycon on the default command line, to see
> early kernel output.
> 
> Ideally we would just say "earlycon" (without specifying an MMIO
> address), but this relies on the stdout-path property in the /chosen
> node, which the model DTs do not carry.

Can we send a Linux patch to add that?

Mark.

> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8ef0ed95ee04
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  configure.ac | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 2b295de..9e3b722 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -99,7 +99,7 @@ AC_SUBST([FILESYSTEM], [$USE_INITRD])
>  AM_CONDITIONAL([INITRD], [test "x$USE_INITRD" != "x"])
>  
>  AS_IF([test "x$X_IMAGE" = "x"],[C_CONSOLE="ttyAMA0"],[C_CONSOLE="hvc0"])
> -C_CMDLINE="console=$C_CONSOLE earlyprintk=pl011,0x1c090000"
> +C_CMDLINE="console=$C_CONSOLE earlycon=pl011,0x1c090000"
>  AC_ARG_WITH([cmdline],
>  	AS_HELP_STRING([--with-cmdline], [set a command line for the kernel]),
>  	[C_CMDLINE=$withval])
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:12:55 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:12:55 +0000
Subject: [boot-wrapper PATCH v2 4/9] configure: Make PSCI the default
 boot method
In-Reply-To: <20211222181607.1203191-5-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-5-andre.przywara@arm.com>
Message-ID: <YdhKZ6ZVo91iu3Rx@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:02PM +0000, Andre Przywara wrote:
> When the boot-wrapper was originally conceived, PSCI was a rather new
> feature, so support in contemporary kernels wasn't guaranteed. The
> boot-wrapper consequently defaulted to not using PSCI.
> 
> Fortunately the times have changed, and most people expect PSCI these
> days, so let's enable PSCI by default.
> 
> We keep the --enable-psci/--disable-psci configure switch, so it can be
> still turned off if needed.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

I had previosusly held off making this change because I wanted to do something
a bit more elaborate, but as this is generally a nice-to-have, and it's still
possible to change things later, I'll apply this now.

Mark.

> ---
>  configure.ac | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 6914eb4..852fd9a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -82,8 +82,8 @@ AS_IF([test "x$X_IMAGE" != "x"],
>  
>  # Allow a user to pass --enable-psci
>  AC_ARG_ENABLE([psci],
> -	AS_HELP_STRING([--enable-psci], [enable the psci boot method]),
> -	[USE_PSCI=$enableval])
> +	AS_HELP_STRING([--disable-psci], [disable the psci boot method]),
> +	[USE_PSCI=$enableval], [USE_PSCI="yes"])
>  AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"])
>  AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no])
>  
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:13:29 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:13:29 +0000
Subject: [boot-wrapper PATCH v2 5/9] configure: Fix default DTB
In-Reply-To: <20211222181607.1203191-6-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-6-andre.przywara@arm.com>
Message-ID: <YdhKiRQKk9xuhJqC@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:03PM +0000, Andre Przywara wrote:
> The DTS files for Arm Ltd. boards and the fastmodel have long been moved
> into the arm/ subdirectory of the arm64 kernel tree's DT folder.
> 
> Adjust the default path to make this build out of the box.
> 
> Also change the default DTB to the more modern FVP RevC model on the
> way.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Thanks; applied.

Mark.

> ---
>  configure.ac | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/configure.ac b/configure.ac
> index 852fd9a..2b295de 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -33,7 +33,7 @@ AC_ARG_WITH([kernel-dir],
>  AS_IF([test "x$KERNEL_ES" = x32],
>  	[KERN_IMAGE=$KERN_DIR/arch/arm/boot/zImage],
>  	[KERN_IMAGE=$KERN_DIR/arch/arm64/boot/Image])
> -KERN_DTB=$KERN_DIR/arch/arm64/boot/dts/rtsm_ve-aemv8a.dtb
> +KERN_DTB=$KERN_DIR/arch/arm64/boot/dts/arm/fvp-base-revc.dtb
>  
>  # Allow the user to override the default DTB
>  AC_ARG_WITH([dtb],
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:14:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:14:57 +0000
Subject: [boot-wrapper PATCH v2 6/9] configure: Use earlycon instead of
 earlyprintk
In-Reply-To: <YdhHwXr0pp9d+nRn@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-7-andre.przywara@arm.com>
 <YdhHwXr0pp9d+nRn@FVFF77S0Q05N>
Message-ID: <YdhK4YhQu3MsQnir@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 02:01:37PM +0000, Mark Rutland wrote:
> On Wed, Dec 22, 2021 at 06:16:04PM +0000, Andre Przywara wrote:
> > The arm64 Linux kernel dropped support for the "earlyprintk" command line
> > parameter a long time ago[1], instead it uses the earlycon parameter
> > now.
> > 
> > Replace earlyprintk with earlycon on the default command line, to see
> > early kernel output.
> > 
> > Ideally we would just say "earlycon" (without specifying an MMIO
> > address), but this relies on the stdout-path property in the /chosen
> > node, which the model DTs do not carry.
> 
> Can we send a Linux patch to add that?
> 
> Mark.

For clarity, I'm going to apply this patch regardless; the above just seems
like a nice-to-have.

Mark.

> 
> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8ef0ed95ee04
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  configure.ac | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/configure.ac b/configure.ac
> > index 2b295de..9e3b722 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -99,7 +99,7 @@ AC_SUBST([FILESYSTEM], [$USE_INITRD])
> >  AM_CONDITIONAL([INITRD], [test "x$USE_INITRD" != "x"])
> >  
> >  AS_IF([test "x$X_IMAGE" = "x"],[C_CONSOLE="ttyAMA0"],[C_CONSOLE="hvc0"])
> > -C_CMDLINE="console=$C_CONSOLE earlyprintk=pl011,0x1c090000"
> > +C_CMDLINE="console=$C_CONSOLE earlycon=pl011,0x1c090000"
> >  AC_ARG_WITH([cmdline],
> >  	AS_HELP_STRING([--with-cmdline], [set a command line for the kernel]),
> >  	[C_CMDLINE=$withval])
> > -- 
> > 2.25.1
> > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mark.rutland at arm.com  Fri Jan  7 06:15:16 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:15:16 +0000
Subject: [boot-wrapper PATCH v2 7/9] pointer auth: Document CPU feature
 bit mask
In-Reply-To: <20211222181607.1203191-8-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-8-andre.przywara@arm.com>
Message-ID: <YdhK9Lkg2kL/zhbV@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:05PM +0000, Andre Przywara wrote:
> When checking for the pointer authentication feature, we actually look
> for *four* different CPUID feature sets.
> Add a comment to make it more obvious that the 0xff is not a typo.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Thanks; applied.

Mark.

> ---
>  arch/aarch64/boot.S | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index bfbb6ec..27ba449 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -38,7 +38,8 @@ ASM_FUNC(_start)
>  
>  	/* Enable pointer authentication if present */
>  	mrs	x1, id_aa64isar1_el1
> -	ldr	x2, =(((0xff) << 24) | (0xff << 4))
> +	/* We check for APA+API and GPA+GPI */
> +	ldr	x2, =((0xff << 24) | (0xff << 4))
>  	and	x1, x1, x2
>  	cbz	x1, 1f
>  
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:19:05 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:19:05 +0000
Subject: [boot-wrapper PATCH v2 8/9] configure: Autodetect GICv3
In-Reply-To: <20211222181607.1203191-9-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-9-andre.przywara@arm.com>
Message-ID: <YdhL2drubqQpq5fl@FVFF77S0Q05N>

On Wed, Dec 22, 2021 at 06:16:06PM +0000, Andre Przywara wrote:
> Currently the user has to specify the GIC architecture version (v2 or
> v3) on the ./configure command line, even though this is actually
> redundant information, since the DTB can carry only one GIC type.
> 
> Unconditionally query for the two GIC compatible strings in the provided
> DTB, then choose the GIC type automatically depending on which string is
> found.
> 
> This saves the user from specifying the GIC type on the configure
> command line, and avoids errors when the wrong type was accidentally
> named.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Makefile.am  | 23 +++++++++--------------
>  configure.ac |  8 --------
>  2 files changed, 9 insertions(+), 22 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index d9ad6d1..3d8128f 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -63,19 +63,14 @@ PSCI_NODE	:=
>  CPU_NODES	:=
>  endif
>  
> -if GICV3
> -GIC_DIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3')
> -GIC_RDIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3')
> -DEFINES		+= -DGIC_DIST_BASE=$(GIC_DIST_BASE)
> -DEFINES		+= -DGIC_RDIST_BASE=$(GIC_RDIST_BASE)
> -COMMON_OBJ	+= gic-v3.o
> -else
> -GIC_DIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic')
> -GIC_CPU_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic')
> -DEFINES		+= -DGIC_CPU_BASE=$(GIC_CPU_BASE)
> -DEFINES		+= -DGIC_DIST_BASE=$(GIC_DIST_BASE)
> -COMMON_OBJ	+= gic.o
> -endif
> +GICV3_DIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,gic-v3' 2> /dev/null)
> +GIC_RDIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,gic-v3' 2> /dev/null)
> +GICV2_DIST_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,cortex-a15-gic' 2> /dev/null)
> +GIC_CPU_BASE	:= $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 1 'arm,cortex-a15-gic' 2> /dev/null)
> +DEFINES		+= $(if $(GICV3_DIST_BASE), -DGIC_DIST_BASE=$(GICV3_DIST_BASE), -DGIC_DIST_BASE=$(GICV2_DIST_BASE))
> +DEFINES		+= $(if $(GIC_RDIST_BASE), -DGIC_RDIST_BASE=$(GIC_RDIST_BASE), )
> +DEFINES		+= $(if $(GIC_CPU_BASE), -DGIC_CPU_BASE=$(GIC_CPU_BASE), )
> +GIC_OBJ		:= $(if $(GICV3_DIST_BASE), gic-v3.o, gic.o)

Hmm... can we organise this such that if we don't find either GICv2 or GICv3 we
produce a build-time error? Currently this'll silently go with GICv2.

Other than that nit, this is a nice quality-of-life improvement!

Thanks,
Mark.

>  
>  if KERNEL_32
>  MBOX_OFFSET	:= 0x7ff8
> @@ -134,7 +129,7 @@ CFLAGS		+= -fno-pic -fno-pie
>  CFLAGS		+= -Os
>  LDFLAGS		+= --gc-sections
>  
> -OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> +OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ)) $(addprefix $(COMMON_SRC),$(GIC_OBJ))
>  
>  # Don't lookup all prerequisites in $(top_srcdir), only the source files. When
>  # building outside the source tree $(ARCH_SRC) needs to be created.
> diff --git a/configure.ac b/configure.ac
> index 9e3b722..ed3e094 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -111,13 +111,6 @@ AC_ARG_WITH([xen-cmdline],
>  	[X_CMDLINE=$withval])
>  AC_SUBST([XEN_CMDLINE], [$X_CMDLINE])
>  
> -# Allow a user to pass --enable-gicv3
> -AC_ARG_ENABLE([gicv3],
> -	AS_HELP_STRING([--enable-gicv3], [enable GICv3 instead of GICv2]),
> -	[USE_GICV3=$enableval])
> -AM_CONDITIONAL([GICV3], [test "x$USE_GICV3" = "xyes"])
> -AS_IF([test "x$USE_GICV3" = "xyes"], [], [USE_GICV3=no])
> -
>  # Ensure that we have all the needed programs
>  AC_PROG_CC
>  AC_PROG_CPP
> @@ -144,7 +137,6 @@ echo "  Device tree blob:                  ${KERN_DTB}"
>  echo "  Linux kernel command line:         ${CMDLINE}"
>  echo "  Embedded initrd:                   ${FILESYSTEM:-NONE}"
>  echo "  Use PSCI?                          ${USE_PSCI}"
> -echo "  Use GICv3?                         ${USE_GICV3}"
>  echo "  Boot-wrapper execution state:      AArch${BOOTWRAPPER_ES}"
>  echo "  Kernel execution state:            AArch${KERNEL_ES}"
>  echo "  Xen image                          ${XEN_IMAGE:-NONE}"
> -- 
> 2.25.1
> 


From mark.rutland at arm.com  Fri Jan  7 06:25:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 14:25:51 +0000
Subject: [boot-wrapper PATCH v2 0/9] Various (build system) fixes
In-Reply-To: <20211222181607.1203191-1-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
Message-ID: <YdhNb3+5ktk0QzrR@FVFF77S0Q05N>

Hi Andre,

On Wed, Dec 22, 2021 at 06:15:58PM +0000, Andre Przywara wrote:
> This series combines various smaller fixes to boot-wrapper, mostly
> build system related, and some convenience fixes.
> Patches 1-3 fix problems with distribution (cross-)compilers, since they
> tend to make too many assumptions about compiling userland programs. 
> Patches 4-8 have been on the list before[1]. Patch 9 is a new fix to
> silence dtc when it's recompiling the DTB.
> 
> See the respective patch subjects below for a summary.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2021-May/656310.html
> 
> Andre Przywara (9):
>   Makefile: Avoid .got section creation
>   Add standard headers
>   Makefile: Tell compiler to generate bare-metal code
>   configure: Make PSCI the default boot method
>   configure: Fix default DTB
>   configure: Use earlycon instead of earlyprintk
>   pointer auth: Document CPU feature bit mask
>   configure: Autodetect GICv3
>   avoid dtc warnings on re-compiling DTB

Thanks for this!

Of these, I have applied:

    Makefile: Avoid .got section creation
    configure: Make PSCI the default boot method
    configure: Fix default DTB
    configure: Use earlycon instead of earlyprintk
    pointer auth: Document CPU feature bit mask
    avoid dtc warnings on re-compiling DTB

... and have pushed that out.

I have not applied:

    Add standard headers
    Makefile: Tell compiler to generate bare-metal code
    configure: Autodetect GICv3

... since for the first two I have some questions/concerns, and for the GICv3
patch I'd like to make that a bit more robust if possible.

Thanks,
Mark.

> 
>  Makefile.am                   | 33 +++++++++++++++++----------------
>  arch/aarch32/include/stdint.h | 19 +++++++++++++++++++
>  arch/aarch64/boot.S           |  3 ++-
>  arch/aarch64/include/stdint.h | 19 +++++++++++++++++++
>  configure.ac                  | 16 ++++------------
>  include/stddef.h              | 15 +++++++++++++++
>  6 files changed, 76 insertions(+), 29 deletions(-)
>  create mode 100644 arch/aarch32/include/stdint.h
>  create mode 100644 arch/aarch64/include/stdint.h
>  create mode 100644 include/stddef.h
> 
> -- 
> 2.25.1
> 


From s-anna at ti.com  Fri Jan  7 06:26:34 2022
From: s-anna at ti.com (Suman Anna)
Date: Fri, 7 Jan 2022 08:26:34 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <20220107031905.2406176-1-robh@kernel.org>
References: <20220107031905.2406176-1-robh@kernel.org>
Message-ID: <cf75f1ee-8424-b6b2-f873-beea4676a29f@ti.com>

Hi Rob,

On 1/6/22 9:19 PM, Rob Herring wrote:
> 'interrupt-parent' is never required as it can be in a parent node or a
> parent node itself can be an interrupt provider. Where exactly it lives is
> outside the scope of a binding schema.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
>  7 files changed, 15 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> index 9ad470e01953..b085450b527f 100644
> --- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> +++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> @@ -43,7 +43,6 @@ required:
>    - gpio-controller
>    - interrupt-controller
>    - "#interrupt-cells"
> -  - interrupt-parent
>  
>  additionalProperties: false
>  
> diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> index e864d798168d..d433e496ec6e 100644
> --- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> +++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> @@ -175,15 +175,6 @@ required:
>    - ti,mbox-num-fifos
>  
>  allOf:
> -  - if:
> -      properties:
> -        compatible:
> -          enum:
> -            - ti,am654-mailbox
> -    then:
> -      required:
> -        - interrupt-parent
> -

There are multiple interrupt controllers on TI K3 devices, and we need this
property to be defined _specifically_ to point to the relevant interrupt router
parent node.

While what you state in general is true, I cannot have a node not define this on
K3 devices, and end up using the wrong interrupt parent (GIC
interrupt-controller). That's why the conditional compatible check.

regards
Suman

>    - if:
>        properties:
>          compatible:
> diff --git a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> index 499c62c04daa..5dce62a7eff2 100644
> --- a/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> +++ b/Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
> @@ -221,7 +221,6 @@ required:
>    - '#gpio-cells'
>    - interrupt-controller
>    - '#interrupt-cells'
> -  - interrupt-parent
>    - interrupts
>    - AVDD-supply
>    - DBVDD1-supply
> diff --git a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> index 437502c5ca96..3ce9f9a16baf 100644
> --- a/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> +++ b/Documentation/devicetree/bindings/net/lantiq,etop-xway.yaml
> @@ -46,7 +46,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - interrupt-parent
>    - interrupts
>    - interrupt-names
>    - lantiq,tx-burst-length
> diff --git a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> index 7bc074a42369..5bc1a21ca579 100644
> --- a/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> +++ b/Documentation/devicetree/bindings/net/lantiq,xrx200-net.yaml
> @@ -38,7 +38,6 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - interrupt-parent
>    - interrupts
>    - interrupt-names
>    - "#address-cells"
> diff --git a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> index 2b9d1d6fc661..72c78f4ec269 100644
> --- a/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/sifive,fu740-pcie.yaml
> @@ -61,7 +61,6 @@ required:
>    - num-lanes
>    - interrupts
>    - interrupt-names
> -  - interrupt-parent
>    - interrupt-map-mask
>    - interrupt-map
>    - clock-names
> diff --git a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> index a2bbc0eb7220..32f4641085bc 100644
> --- a/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> +++ b/Documentation/devicetree/bindings/pci/xilinx-versal-cpm.yaml
> @@ -55,7 +55,6 @@ required:
>    - reg-names
>    - "#interrupt-cells"
>    - interrupts
> -  - interrupt-parent
>    - interrupt-map
>    - interrupt-map-mask
>    - bus-range
> 



From andre.przywara at arm.com  Fri Jan  7 06:31:28 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 7 Jan 2022 14:31:28 +0000
Subject: [boot-wrapper PATCH v2 2/9] Add standard headers
In-Reply-To: <YdhE99enrMBNysxI@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-3-andre.przywara@arm.com>
 <YdhE99enrMBNysxI@FVFF77S0Q05N>
Message-ID: <20220107143128.53eb87b2@donnerap.cambridge.arm.com>

On Fri, 7 Jan 2022 13:49:43 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> On Wed, Dec 22, 2021 at 06:16:00PM +0000, Andre Przywara wrote:
> > So far we were relying on some standard C headers to be provided by the
> > toolchain. This applies for instance to stddef.h and stdint.h.
> > As a "bare-metal" application, we should not rely on external headers,
> > or even on a toolchain providing them in the first place.
> > 
> > Define our own version of stddef.h and stdint.h, containing just the
> > types that we actually need.  
> 
> Even a freestanding compiler implementation is required to provide these
> headers, and using the compiler versions would avoid unexpected mismatches
> (e.g. for builtins). So I don't think the justification as written makes sense.
> 
> Is this because the next patch removes the stdinc paths, and so we don't get
> the compiler's implementation of these headers?

Yes, exactly. I don't like repeating those either, and understand that
even a minimal compiler carries these headers, *somewhere*, but I couldn't
find an easy way of including them without being compiler/build specific.

I can try harder, and would be happy if someone points out the real
solution to this.

For the sake of solving this problem I figured that those particular
definitions are actually somewhat generic (for all practical purposes), so
it was the least involved solution to the real problem, which is to ditch
the *other* compiler headers and libraries, as done in patch 3/9.

Cheers,
Andre

> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  arch/aarch32/include/stdint.h | 19 +++++++++++++++++++
> >  arch/aarch64/include/stdint.h | 19 +++++++++++++++++++
> >  include/stddef.h              | 15 +++++++++++++++
> >  3 files changed, 53 insertions(+)
> >  create mode 100644 arch/aarch32/include/stdint.h
> >  create mode 100644 arch/aarch64/include/stdint.h
> >  create mode 100644 include/stddef.h
> > 
> > diff --git a/arch/aarch32/include/stdint.h b/arch/aarch32/include/stdint.h
> > new file mode 100644
> > index 0000000..77546f0
> > --- /dev/null
> > +++ b/arch/aarch32/include/stdint.h
> > @@ -0,0 +1,19 @@
> > +/*
> > + * arch/aarch32/include/stdint.h
> > + *
> > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > + *
> > + * Use of this source code is governed by a BSD-style license that can be
> > + * found in the LICENSE.txt file.
> > + */
> > +#ifndef STDINT_H__
> > +#define STDINT_H__
> > +
> > +typedef unsigned char		uint8_t;
> > +typedef unsigned short int	uint16_t;
> > +typedef unsigned int		uint32_t;
> > +typedef unsigned long long int	uint64_t;
> > +
> > +typedef unsigned int		uintptr_t;
> > +
> > +#endif
> > diff --git a/arch/aarch64/include/stdint.h b/arch/aarch64/include/stdint.h
> > new file mode 100644
> > index 0000000..92c2603
> > --- /dev/null
> > +++ b/arch/aarch64/include/stdint.h
> > @@ -0,0 +1,19 @@
> > +/*
> > + * arch/aarch64/include/stdint.h
> > + *
> > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > + *
> > + * Use of this source code is governed by a BSD-style license that can be
> > + * found in the LICENSE.txt file.
> > + */
> > +#ifndef STDINT_H__
> > +#define STDINT_H__
> > +
> > +typedef unsigned char		uint8_t;
> > +typedef unsigned short int	uint16_t;
> > +typedef unsigned int		uint32_t;
> > +typedef unsigned long int	uint64_t;
> > +
> > +typedef unsigned long int	uintptr_t;
> > +
> > +#endif
> > diff --git a/include/stddef.h b/include/stddef.h
> > new file mode 100644
> > index 0000000..3208b10
> > --- /dev/null
> > +++ b/include/stddef.h
> > @@ -0,0 +1,15 @@
> > +/*
> > + * include/stddef.h - standard data type definitions
> > + *
> > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > + *
> > + * Use of this source code is governed by a BSD-style license that can be
> > + * found in the LICENSE.txt file.
> > + */
> > +#ifndef STDDEF_H__
> > +#define STDDEF_H__
> > +
> > +typedef unsigned long int	size_t;
> > +typedef signed long int		ssize_t;
> > +
> > +#endif
> > -- 
> > 2.25.1
> >   



From broonie at kernel.org  Fri Jan  7 06:33:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 07 Jan 2022 14:33:19 +0000
Subject: [PATCH] spi: spi-meson-spifc: Add missing pm_runtime_disable() in
 meson_spifc_probe
In-Reply-To: <20220107075424.7774-1-linmq006@gmail.com>
References: <20220107075424.7774-1-linmq006@gmail.com>
Message-ID: <164156599935.2077509.18070348001401229585.b4-ty@kernel.org>

On Fri, 7 Jan 2022 07:54:24 +0000, Miaoqian Lin wrote:
> If the probe fails, we should use pm_runtime_disable() to balance
> pm_runtime_enable().
> Add missing pm_runtime_disable() for meson_spifc_probe.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: spi-meson-spifc: Add missing pm_runtime_disable() in meson_spifc_probe
      commit: 69c1b87516e327a60b39f96b778fe683259408bf

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Fri Jan  7 06:33:21 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 07 Jan 2022 14:33:21 +0000
Subject: [PATCH] spi: atmel: Fix typo
In-Reply-To: <20220107024631.396862-1-qhjin.dev@gmail.com>
References: <20220107024631.396862-1-qhjin.dev@gmail.com>
Message-ID: <164156600175.2077509.8473980991619848547.b4-ty@kernel.org>

On Fri, 7 Jan 2022 10:46:31 +0800, Qinghua Jin wrote:
> Change 'actualy' to 'actually'
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: atmel: Fix typo
      commit: c8c9cb6d9fbeace1c5509f4bb2f3c32095cda0d0

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:33:26 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:33:26 +0100
Subject: [PATCH v21 8/8] soc: mediatek: SVS: add mt8192 SVS GPU driver
In-Reply-To: <20220107095200.4389-9-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-9-roger.lu@mediatek.com>
Message-ID: <2c0e89c6-6e9c-9d12-703f-d71e22023e7a@collabora.com>

Il 07/01/22 10:52, Roger Lu ha scritto:
> mt8192 SVS GPU uses 2-line (high/low bank) HW architecture to provide
> bank voltages. High bank helps update higher frequency's voltage
> and low bank helps update lower frequency's voltage.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> ---
>   drivers/soc/mediatek/mtk-svs.c | 469 ++++++++++++++++++++++++++++++++-
>   1 file changed, 464 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> index 93cdaecadd6d..bec6524ab33a 100644
> --- a/drivers/soc/mediatek/mtk-svs.c
> +++ b/drivers/soc/mediatek/mtk-svs.c

..snip..

> @@ -639,9 +706,11 @@ static int svs_status_debug_show(struct seq_file *m, void *v)
>   
>   	ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
>   	if (ret)
> -		seq_printf(m, "%s: temperature ignore\n", svsb->name);
> +		seq_printf(m, "%s: temperature ignore, turn_pt = %u\n",
> +			   svsb->name, svsb->turn_pt);
>   	else
> -		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
> +		seq_printf(m, "%s: temperature = %d, turn_pt = %u\n",
> +			   svsb->name, tzone_temp, svsb->turn_pt);
>   
>   	for (i = 0; i < svsb->opp_count; i++) {
>   		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
> @@ -784,6 +853,181 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
>   	return DIV_ROUND_UP(vx, 100);
>   }
>   
> +static void svs_get_bank_volts_v3(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +	u32 i, j, *vop, vop74, vop30, mask7_0 = GENMASK(7, 0);
> +	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;

mask7_0, bits8, reg_bytes are constants, and it's not right to declare constants
as variables like you're doing here.

Please replace all usages of `mask7_0` with either a definition or with the call
to the GENMASK macro;
also, replace all usages of `bits8` with a definition, or just 8;
finally, either make `reg_bytes` a `const u8` or a definition.


In my opinion, a #define would be preferred, since the exact same comments on
the exact same values also apply to function svs_set_bank_freq_pct_v3().

After that fix, you'll get my R-b.

I feel like v22 will be golden :)

Regards,
- Angelo

> +	u32 middle_index = (svsb->opp_count / 2);
> +	u32 opp_start = 0, opp_stop = 0, turn_pt = svsb->turn_pt;
> +
> +	if (svsb->phase == SVSB_PHASE_MON &&
> +	    svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
> +		return;
> +
> +	vop74 = svs_readl_relaxed(svsp, VOP74);
> +	vop30 = svs_readl_relaxed(svsp, VOP30);
> +
> +	/* Target is to set svsb->volt[] by algorithm */
> +	if (turn_pt < middle_index) {
> +		if (svsb->type == SVSB_HIGH) {
> +			/* volt[0] ~ volt[turn_pt - 1] */
> +			for (i = 0; i < turn_pt; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				vop = (shift_byte < reg_bytes) ? &vop30 :
> +								 &vop74;
> +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> +				shift_byte++;
> +			}
> +		} else if (svsb->type == SVSB_LOW) {
> +			/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
> +			j = svsb->opp_count - 7;
> +			svsb->volt[turn_pt] = vop30 & mask7_0;
> +			shift_byte++;
> +			for (i = j; i < svsb->opp_count; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				vop = (shift_byte < reg_bytes) ? &vop30 :
> +								 &vop74;
> +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> +				shift_byte++;
> +			}
> +
> +			/* volt[turn_pt + 1] ~ volt[j - 1] by interpolate */
> +			for (i = turn_pt + 1; i < j; i++)
> +				svsb->volt[i] =
> +					interpolate(svsb->freq_pct[turn_pt],
> +						    svsb->freq_pct[j],
> +						    svsb->volt[turn_pt],
> +						    svsb->volt[j],
> +						    svsb->freq_pct[i]);
> +		}
> +	} else {
> +		if (svsb->type == SVSB_HIGH) {
> +			/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
> +			j = turn_pt - 7;
> +			svsb->volt[0] = vop30 & mask7_0;
> +			shift_byte++;
> +			for (i = j; i < turn_pt; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				vop = (shift_byte < reg_bytes) ? &vop30 :
> +								 &vop74;
> +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> +				shift_byte++;
> +			}
> +
> +			/* volt[1] ~ volt[j - 1] by interpolate */
> +			for (i = 1; i < j; i++)
> +				svsb->volt[i] =
> +					interpolate(svsb->freq_pct[0],
> +						    svsb->freq_pct[j],
> +						    svsb->volt[0],
> +						    svsb->volt[j],
> +						    svsb->freq_pct[i]);
> +		} else if (svsb->type == SVSB_LOW) {
> +			/* volt[turn_pt] ~ volt[opp_count - 1] */
> +			for (i = turn_pt; i < svsb->opp_count; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				vop = (shift_byte < reg_bytes) ? &vop30 :
> +								 &vop74;
> +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> +				shift_byte++;
> +			}
> +		}
> +	}
> +
> +	if (svsb->type == SVSB_HIGH) {
> +		opp_start = 0;
> +		opp_stop = svsb->turn_pt;
> +	} else if (svsb->type == SVSB_LOW) {
> +		opp_start = svsb->turn_pt;
> +		opp_stop = svsb->opp_count;
> +	}
> +
> +	for (i = opp_start; i < opp_stop; i++)
> +		if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT)
> +			svsb->volt[i] -= svsb->dvt_fixed;
> +}
> +
> +static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +	u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0;
> +	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;
> +	u32 middle_index = (svsb->opp_count / 2);
> +	u32 turn_pt = middle_index;
> +
> +	for (i = 0; i < svsb->opp_count; i++) {
> +		if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) {
> +			svsb->turn_pt = i;
> +			break;
> +		}
> +	}
> +
> +	turn_pt = svsb->turn_pt;
> +
> +	/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
> +	if (turn_pt < middle_index) {
> +		if (svsb->type == SVSB_HIGH) {
> +			/* Edge case for preventing freq_pct30 from being 0 */
> +			if (turn_pt == 0)
> +				freq_pct30 = svsb->freq_pct[0];
> +
> +			/* freq_pct[0] ~ freq_pct[turn_pt - 1] */
> +			for (i = 0; i < turn_pt; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				freq_pct = (shift_byte < reg_bytes) ?
> +					   &freq_pct30 : &freq_pct74;
> +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> +				shift_byte++;
> +			}
> +		} else if (svsb->type == SVSB_LOW) {
> +			/*
> +			 * freq_pct[turn_pt] +
> +			 * freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
> +			 */
> +			freq_pct30 = svsb->freq_pct[turn_pt];
> +			shift_byte++;
> +			j = svsb->opp_count - 7;
> +			for (i = j; i < svsb->opp_count; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				freq_pct = (shift_byte < reg_bytes) ?
> +					   &freq_pct30 : &freq_pct74;
> +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> +				shift_byte++;
> +			}
> +		}
> +	} else {
> +		if (svsb->type == SVSB_HIGH) {
> +			/*
> +			 * freq_pct[0] +
> +			 * freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
> +			 */
> +			freq_pct30 = svsb->freq_pct[0];
> +			shift_byte++;
> +			j = turn_pt - 7;
> +			for (i = j; i < turn_pt; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				freq_pct = (shift_byte < reg_bytes) ?
> +					   &freq_pct30 : &freq_pct74;
> +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> +				shift_byte++;
> +			}
> +		} else if (svsb->type == SVSB_LOW) {
> +			/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
> +			for (i = turn_pt; i < svsb->opp_count; i++) {
> +				b_sft = bits8 * (shift_byte % reg_bytes);
> +				freq_pct = (shift_byte < reg_bytes) ?
> +					   &freq_pct30 : &freq_pct74;
> +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> +				shift_byte++;
> +			}
> +		}
> +	}
> +
> +	svs_writel_relaxed(svsp, freq_pct74, FREQPCT74);
> +	svs_writel_relaxed(svsp, freq_pct30, FREQPCT30);
> +}
> +
>   static void svs_get_bank_volts_v2(struct svs_platform *svsp)
>   {
>   	struct svs_bank *svsb = svsp->pbank;




From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:33:41 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:33:41 +0100
Subject: [PATCH v21 2/8] arm64: dts: mt8183: add svs device information
In-Reply-To: <20220107095200.4389-3-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-3-roger.lu@mediatek.com>
Message-ID: <1d0afef1-47b2-4b36-9616-27d1df9ac113@collabora.com>

Il 07/01/22 10:51, Roger Lu ha scritto:
> Add compitable/reg/irq/clock/efuse setting in svs node.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:33:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:33:49 +0100
Subject: [PATCH v21 7/8] arm64: dts: mt8192: add svs device information
In-Reply-To: <20220107095200.4389-8-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-8-roger.lu@mediatek.com>
Message-ID: <010f9b6a-d6bf-b27a-cb2d-c5fd181c3ac7@collabora.com>

Il 07/01/22 10:51, Roger Lu ha scritto:
> Add compitable/reg/irq/clock/efuse/reset setting in svs node.

Typo: compitable => compatible
.. also, you're not only adding the svs node, but also efuse: please add that
information in the commit description.

> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>

This patch seems to not apply on top of the current linux-next, can you please
rebase it? That would resolve issues with this series and would be picked sooner.

Apart from that...

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   arch/arm64/boot/dts/mediatek/mt8192.dtsi | 39 ++++++++++++++++++++++++
>   1 file changed, 39 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> index c7c7d4e017ae..c111e26489dd 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> @@ -9,6 +9,8 @@
>   #include <dt-bindings/interrupt-controller/arm-gic.h>
>   #include <dt-bindings/interrupt-controller/irq.h>
>   #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
> +#include <dt-bindings/reset/ti-syscon.h>
> +
>   
>   / {
>   	compatible = "mediatek,mt8192";
> @@ -268,6 +270,14 @@
>   			compatible = "mediatek,mt8192-infracfg", "syscon";
>   			reg = <0 0x10001000 0 0x1000>;
>   			#clock-cells = <1>;
> +
> +			infracfg_rst: reset-controller {
> +				compatible = "mediatek,infra-reset", "ti,syscon-reset";
> +				#reset-cells = <1>;
> +				ti,reset-bits = <
> +					0x150 5 0x154 5 0 0     (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* 0: svs */
> +				>;
> +			};
>   		};
>   
>   		pericfg: syscon at 10003000 {
> @@ -362,6 +372,20 @@
>   			status = "disabled";
>   		};
>   
> +		svs: svs at 1100b000 {
> +			compatible = "mediatek,mt8192-svs";
> +			reg = <0 0x1100b000 0 0x1000>;
> +			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
> +			clocks = <&infracfg CLK_INFRA_THERM>;
> +			clock-names = "main";
> +			nvmem-cells = <&svs_calibration>,
> +				      <&lvts_e_data1>;
> +			nvmem-cell-names = "svs-calibration-data",
> +					   "t-calibration-data";
> +			resets = <&infracfg_rst 0>;
> +			reset-names = "svs_rst";
> +		};
> +
>   		spi1: spi at 11010000 {
>   			compatible = "mediatek,mt8192-spi",
>   				     "mediatek,mt6765-spi";
> @@ -479,6 +503,21 @@
>   			#clock-cells = <1>;
>   		};
>   
> +		efuse: efuse at 11c10000 {
> +			compatible = "mediatek,efuse";
> +			reg = <0 0x11c10000 0 0x1000>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			lvts_e_data1: data1 at 1c0 {
> +				reg = <0x1c0 0x58>;
> +			};
> +
> +			svs_calibration: calib at 580 {
> +				reg = <0x580 0x68>;
> +			};
> +		};
> +
>   		i2c3: i2c3 at 11cb0000 {
>   			compatible = "mediatek,mt8192-i2c";
>   			reg = <0 0x11cb0000 0 0x1000>,
> 


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:33:56 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:33:56 +0100
Subject: [PATCH v21 3/8] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <20220107095200.4389-4-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-4-roger.lu@mediatek.com>
Message-ID: <63d8884d-d02d-53f9-8524-4a074ca5bfea@collabora.com>

Il 07/01/22 10:51, Roger Lu ha scritto:
> The Smart Voltage Scaling(SVS) engine is a piece of hardware
> which calculates suitable SVS bank voltages to OPP voltage table.
> Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
> when receiving OPP_EVENT_ADJUST_VOLTAGE.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> ---
>   drivers/soc/mediatek/Kconfig   |   10 +
>   drivers/soc/mediatek/Makefile  |    1 +
>   drivers/soc/mediatek/mtk-svs.c | 1446 ++++++++++++++++++++++++++++++++
>   3 files changed, 1457 insertions(+)
>   create mode 100644 drivers/soc/mediatek/mtk-svs.c
> 
> diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
> index fdd8bc08569e..3c3eedea35f7 100644
> --- a/drivers/soc/mediatek/Kconfig
> +++ b/drivers/soc/mediatek/Kconfig
> @@ -73,4 +73,14 @@ config MTK_MMSYS
>   	  Say yes here to add support for the MediaTek Multimedia
>   	  Subsystem (MMSYS).
>   
> +config MTK_SVS
> +	tristate "MediaTek Smart Voltage Scaling(SVS)"
> +	depends on MTK_EFUSE && NVMEM
> +	help
> +	  The Smart Voltage Scaling(SVS) engine is a piece of hardware
> +	  which has several controllers(banks) for calculating suitable
> +	  voltage to different power domains(CPU/GPU/CCI) according to
> +	  chip process corner, temperatures and other factors. Then DVFS
> +	  driver could apply SVS bank voltage to PMIC/Buck.
> +
>   endmenu
> diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
> index 90270f8114ed..0e9e703c931a 100644
> --- a/drivers/soc/mediatek/Makefile
> +++ b/drivers/soc/mediatek/Makefile
> @@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
>   obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
>   obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
> +obj-$(CONFIG_MTK_SVS) += mtk-svs.o
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> new file mode 100644
> index 000000000000..fc7e2ee44a92
> --- /dev/null
> +++ b/drivers/soc/mediatek/mtk-svs.c
> @@ -0,0 +1,1446 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + */
> +
> +#include <linux/bits.h>
> +#include <linux/clk.h>
> +#include <linux/completion.h>
> +#include <linux/device.h>
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/kernel.h>
> +#include <linux/kthread.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/nvmem-consumer.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_platform.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_opp.h>
> +#include <linux/pm_qos.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/spinlock.h>
> +
> +/* svs bank 1-line sw id */
> +#define SVSB_CPU_LITTLE			BIT(0)
> +#define SVSB_CPU_BIG			BIT(1)
> +#define SVSB_CCI			BIT(2)
> +#define SVSB_GPU			BIT(3)
> +
> +/* svs bank mode support */
> +#define SVSB_MODE_ALL_DISABLE		0
> +#define SVSB_MODE_INIT01		BIT(1)
> +#define SVSB_MODE_INIT02		BIT(2)
> +
> +/* svs bank volt flags */
> +#define SVSB_INIT01_PD_REQ		BIT(0)
> +#define SVSB_INIT01_VOLT_IGNORE		BIT(1)
> +#define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
> +
> +/* svs bank common setting */
> +#define MAX_OPP_ENTRIES			16
> +#define SVSB_DC_SIGNED_BIT		BIT(15)
> +#define SVSB_DET_CLK_EN			BIT(31)
> +#define SVSB_DET_MAX			0xffff
> +#define SVSB_DET_WINDOW			0xa28
> +#define SVSB_DTHI			0x1
> +#define SVSB_DTLO			0xfe
> +#define SVSB_EN_INIT01			0x1
> +#define SVSB_EN_INIT02			0x5
> +#define SVSB_EN_MASK			0x7
> +#define SVSB_EN_OFF			0x0
> +#define SVSB_INTEN_INIT0x		0x00005f01
> +#define SVSB_INTSTS_CLEAN		0x00ffffff
> +#define SVSB_INTSTS_COMPLETE		0x1
> +#define SVSB_RUNCONFIG_DEFAULT		0x80000000
> +
> +static DEFINE_SPINLOCK(svs_lock);

snip....


> +
> +struct svs_platform_data {
> +	char *name;
> +	struct svs_bank *banks;
> +	bool (*efuse_parsing)(struct svs_platform *svsp);
> +	unsigned long irqflags;
> +	const u32 *regs;
> +	u32 bank_max;
> +	int (*probe)(struct svs_platform *svsp);
> +};
> +

Please move the definition of struct svs_platform_data at the beginning of
the file for increased readability.

With that done,

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:34:03 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:34:03 +0100
Subject: [PATCH v21 4/8] soc: mediatek: SVS: add monitor mode
In-Reply-To: <20220107095200.4389-5-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-5-roger.lu@mediatek.com>
Message-ID: <e118df40-da6b-88f6-fbff-15befb3405d5@collabora.com>

Il 07/01/22 10:51, Roger Lu ha scritto:
> SVS monitor mode is based on different thermal temperature
> to provide suitable SVS bank voltages.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> ---
>   drivers/soc/mediatek/mtk-svs.c | 253 ++++++++++++++++++++++++++++++++-
>   1 file changed, 247 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> index fc7e2ee44a92..042c6e8e9069 100644
> --- a/drivers/soc/mediatek/mtk-svs.c
> +++ b/drivers/soc/mediatek/mtk-svs.c
> @@ -25,6 +25,7 @@
>   #include <linux/regulator/consumer.h>
>   #include <linux/slab.h>
>   #include <linux/spinlock.h>
> +#include <linux/thermal.h>
>   
>   /* svs bank 1-line sw id */
>   #define SVSB_CPU_LITTLE			BIT(0)
> @@ -36,6 +37,7 @@
>   #define SVSB_MODE_ALL_DISABLE		0
>   #define SVSB_MODE_INIT01		BIT(1)
>   #define SVSB_MODE_INIT02		BIT(2)
> +#define SVSB_MODE_MON			BIT(3)
>   
>   /* svs bank volt flags */
>   #define SVSB_INIT01_PD_REQ		BIT(0)
> @@ -53,11 +55,16 @@
>   #define SVSB_EN_INIT01			0x1
>   #define SVSB_EN_INIT02			0x5
>   #define SVSB_EN_MASK			0x7
> +#define SVSB_EN_MON			0x2
>   #define SVSB_EN_OFF			0x0
>   #define SVSB_INTEN_INIT0x		0x00005f01
> +#define SVSB_INTEN_MONVOPEN		0x00ff0000
>   #define SVSB_INTSTS_CLEAN		0x00ffffff
>   #define SVSB_INTSTS_COMPLETE		0x1
> +#define SVSB_INTSTS_MONVOP		0x00ff0000
>   #define SVSB_RUNCONFIG_DEFAULT		0x80000000
> +#define SVSB_TEMP_LOWER_BOUND		0xb2
> +#define SVSB_TEMP_UPPER_BOUND		0x64
>   
>   static DEFINE_SPINLOCK(svs_lock);
>   
> @@ -66,6 +73,7 @@ static DEFINE_SPINLOCK(svs_lock);
>    * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
>    * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
>    * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
> + * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
>    * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
>    *
>    * Each svs bank has its own independent phase and we enable each svs bank by
> @@ -73,12 +81,13 @@ static DEFINE_SPINLOCK(svs_lock);
>    * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
>    *
>    * svs bank general phase-enabled order:
> - * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02
> + * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
>    */
>   enum svsb_phase {
>   	SVSB_PHASE_ERROR = 0,
>   	SVSB_PHASE_INIT01,
>   	SVSB_PHASE_INIT02,
> +	SVSB_PHASE_MON,
>   	SVSB_PHASE_MAX,
>   };
>   
> @@ -209,9 +218,11 @@ static const u32 svs_regs_v2[] = {
>    * @probe: svs platform probe function pointer
>    * @irqflags: svs platform irq settings flags
>    * @efuse_max: total number of svs efuse
> + * @tefuse_max: total number of thermal efuse
>    * @regs: svs platform registers map
>    * @bank_max: total number of svs banks
>    * @efuse: svs efuse data received from NVMEM framework
> + * @tefuse: thermal efuse data received from NVMEM framework
>    */
>   struct svs_platform {
>   	char *name;
> @@ -224,9 +235,11 @@ struct svs_platform {
>   	int (*probe)(struct svs_platform *svsp);
>   	unsigned long irqflags;
>   	size_t efuse_max;
> +	size_t tefuse_max;
>   	const u32 *regs;
>   	u32 bank_max;
>   	u32 *efuse;
> +	u32 *tefuse;
>   };
>   
>   /**
> @@ -241,6 +254,7 @@ struct svs_platform {
>    * @get_volts: function pointer to get bank voltages
>    * @name: bank name
>    * @buck_name: regulator name
> + * @tzone_name: thermal zone name
>    * @suspended: suspend flag of this bank
>    * @phase: bank current phase
>    * @volt_od: bank voltage overdrive
> @@ -270,6 +284,13 @@ struct svs_platform {
>    * @sw_id: bank software identification
>    * @cpu_id: cpu core id for SVS CPU bank use only
>    * @ctl0: TS-x selection
> + * @temp: bank temperature
> + * @tzone_htemp: thermal zone high temperature threshold
> + * @tzone_htemp_voffset: thermal zone high temperature voltage offset
> + * @tzone_ltemp: thermal zone low temperature threshold
> + * @tzone_ltemp_voffset: thermal zone low temperature voltage offset
> + * @bts: svs efuse data
> + * @mts: svs efuse data
>    * @bdes: svs efuse data
>    * @mdes: svs efuse data
>    * @mtdes: svs efuse data
> @@ -292,6 +313,7 @@ struct svs_bank {
>   	void (*get_volts)(struct svs_platform *svsp);
>   	char *name;
>   	char *buck_name;
> +	char *tzone_name;
>   	bool suspended;
>   	enum svsb_phase phase;
>   	s32 volt_od;
> @@ -321,6 +343,13 @@ struct svs_bank {
>   	u32 sw_id;
>   	u32 cpu_id;
>   	u32 ctl0;
> +	u32 temp;
> +	u32 tzone_htemp;
> +	u32 tzone_htemp_voffset;
> +	u32 tzone_ltemp;
> +	u32 tzone_ltemp_voffset;
> +	u32 bts;
> +	u32 mts;
>   	u32 bdes;
>   	u32 mdes;
>   	u32 mtdes;
> @@ -361,10 +390,21 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
>   	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
>   }
>   

I'm sorry for the double review, but this went unnoticed in the previous one.

> +static int svs_get_zone_temperature(const char *tzone_name, int *tzone_temp)
> +{
> +	struct thermal_zone_device *tzd;
> +
> +	tzd = thermal_zone_get_zone_by_name(tzone_name);

This call is expensive, as it's iterating through the (possibly) entire
thermal_tz_list (drivers/thermal/thermal_core.c) so, for performance purposes,
noting that you're using this in svs_adjust_pm_opp_volts(), it's not a good idea
to call it at every ISR.

I would instead propose to get a pointer to the thermal_zone at driver probe
time and cache that in struct svs_bank: this function would also be removed
as the only thing that you'd need to do then would be just one call...

[read forward...]

> +	if (IS_ERR(tzd))
> +		return PTR_ERR(tzd);
> +
> +	return thermal_zone_get_temp(tzd, tzone_temp);
> +}
> +
>   static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
>   {
> -	int ret = -EPERM;
> -	u32 i, svsb_volt, opp_volt;
> +	int ret = -EPERM, tzone_temp = 0;
> +	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
>   
>   	mutex_lock(&svsb->lock);
>   
> @@ -378,6 +418,22 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool force_update)
>   		goto unlock_mutex;
>   	}
>   
> +	/* Get thermal effect */
> +	if (svsb->phase == SVSB_PHASE_MON) {
> +		ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);

... so you can simply call ...


	ret = thermal_zone_get_temp(svsb->tzd, tzone_temp);


...without any need for any helper.

> +		if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
> +			    svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
> +			dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n",
> +				svsb->tzone_name, ret, svsb->temp);
> +			svsb->phase = SVSB_PHASE_ERROR;
> +		}
> +
> +		if (tzone_temp >= svsb->tzone_htemp)
> +			temp_voffset += svsb->tzone_htemp_voffset;
> +		else if (tzone_temp <= svsb->tzone_ltemp)
> +			temp_voffset += svsb->tzone_ltemp_voffset;
> +	}
> +
>   	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
>   	for (i = 0; i < svsb->opp_count; i++) {
>   		switch (svsb->phase) {

Apart from that, the commit looks good. Looking forward to review the new version!

Regards,
- Angelo


From angelogioacchino.delregno at collabora.com  Fri Jan  7 06:34:56 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 7 Jan 2022 15:34:56 +0100
Subject: [PATCH v21 5/8] soc: mediatek: SVS: add debug commands
In-Reply-To: <20220107095200.4389-6-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-6-roger.lu@mediatek.com>
Message-ID: <47bcbffc-42f6-335e-dfab-990e0ab5f103@collabora.com>

Il 07/01/22 10:51, Roger Lu ha scritto:
> The purpose of SVS is to help find the suitable voltages
> for DVFS. Therefore, if SVS bank voltages are concerned
> to be wrong, we can adjust SVS bank voltages by this patch.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> ---
>   drivers/soc/mediatek/mtk-svs.c | 321 ++++++++++++++++++++++++++++++++-
>   1 file changed, 318 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> index 042c6e8e9069..93cdaecadd6d 100644
> --- a/drivers/soc/mediatek/mtk-svs.c
> +++ b/drivers/soc/mediatek/mtk-svs.c

..snip..

> @@ -605,6 +896,16 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
>   	}
>   }
>   
> +static inline void svs_save_bank_register_data(struct svs_platform *svsp,
> +					       enum svsb_phase phase)
> +{
> +	struct svs_bank *svsb = svsp->pbank;
> +	enum svs_reg_index rg_i;
> +

I think that it'd be a good idea to add an `enable` parameter, so that we
don't always do a register dump; after all, this is a debugging feature and
it's going to be completely irrelevant to the user, so keeping this disabled
by default would ensure to get no performance degradation (even if small)
unless really wanted.

So, in this case, here we'd have

	if (!svsp->debug_enabled)
		return;

> +	for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++)
> +		svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i);
> +}
> +

Of course, this implies adding a new debugfs entry to enable/disable the debugging.
Everything else looks good :)

>   static inline void svs_error_isr_handler(struct svs_platform *svsp)
>   {
>   	struct svs_bank *svsb = svsp->pbank;
> @@ -619,6 +920,8 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
>   		svs_readl_relaxed(svsp, SMSTATE1));
>   	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
>   
> +	svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR);
> +
>   	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
>   	svsb->phase = SVSB_PHASE_ERROR;
>   
> @@ -635,6 +938,8 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
>   		 svs_readl_relaxed(svsp, VDESIGN30),
>   		 svs_readl_relaxed(svsp, DCVALUES));
>   
> +	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01);
> +
>   	svsb->phase = SVSB_PHASE_INIT01;
>   	svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
>   				GENMASK(15, 0)) + 1;
> @@ -662,6 +967,8 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp)
>   		 svs_readl_relaxed(svsp, VOP30),
>   		 svs_readl_relaxed(svsp, DCVALUES));
>   
> +	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02);
> +
>   	svsb->phase = SVSB_PHASE_INIT02;
>   	svsb->get_volts(svsp);
>   
> @@ -673,6 +980,8 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
>   {
>   	struct svs_bank *svsb = svsp->pbank;
>   
> +	svs_save_bank_register_data(svsp, SVSB_PHASE_MON);
> +
>   	svsb->phase = SVSB_PHASE_MON;
>   	svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
>   	svsb->get_volts(svsp);
> @@ -1658,6 +1967,12 @@ static int svs_probe(struct platform_device *pdev)
>   		goto svs_probe_iounmap;
>   	}
>   
> +	ret = svs_create_debug_cmds(svsp);
> +	if (ret) {
> +		dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret);
> +		goto svs_probe_iounmap;
> +	}
> +
>   	return 0;
>   
>   svs_probe_iounmap:
> 



From maz at kernel.org  Fri Jan  7 06:35:20 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 07 Jan 2022 14:35:20 +0000
Subject: [PATCH v3 3/4] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU
 attribute
In-Reply-To: <YdgfFa9y1CUkVC5k@monolith.localdoman>
References: <20211213152309.158462-1-alexandru.elisei@arm.com>
 <20211213152309.158462-4-alexandru.elisei@arm.com>
 <8735mvjrq8.wl-maz@kernel.org>
 <YdbYY/EZrTTPKOCp@monolith.localdoman>
 <8735m0vifv.wl-maz@kernel.org>
 <YdgfFa9y1CUkVC5k@monolith.localdoman>
Message-ID: <87zgo7txzr.wl-maz@kernel.org>

On Fri, 07 Jan 2022 11:08:05 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Thu, Jan 06, 2022 at 06:16:04PM +0000, Marc Zyngier wrote:
> > On Thu, 06 Jan 2022 11:54:11 +0000,
> > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > 
> > > 2. What's to stop userspace to change the PMU after at least one VCPU has
> > > run? That can be easily observed by the guest when reading PMCEIDx_EL0.
> > 
> > That's a good point. We need something here. It is a bit odd as to do
> > that, you need to fully enable a PMU on one CPU, but not on the other,
> > then run the first while changing stuff on the other. Something along
> > those lines (untested):
> > 
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 4bf28905d438..4f53520e84fd 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -139,6 +139,7 @@ struct kvm_arch {
> >  
> >  	/* Memory Tagging Extension enabled for the guest */
> >  	bool mte_enabled;
> > +	bool ran_once;
> >  };
> >  
> >  struct kvm_vcpu_fault_info {
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 83297fa97243..3045d7f609df 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -606,6 +606,10 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
> >  
> >  	vcpu->arch.has_run_once = true;
> >  
> > +	mutex_lock(&kvm->lock);
> > +	kvm->arch.ran_once = true;
> > +	mutex_unlock(&kvm->lock);
> > +
> >  	kvm_arm_vcpu_init_debug(vcpu);
> >  
> >  	if (likely(irqchip_in_kernel(kvm))) {
> > diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
> > index dfc0430d6418..95100c541244 100644
> > --- a/arch/arm64/kvm/pmu-emul.c
> > +++ b/arch/arm64/kvm/pmu-emul.c
> > @@ -959,8 +959,9 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
> >  		arm_pmu = entry->arm_pmu;
> >  		if (arm_pmu->pmu.type == pmu_id) {
> >  			/* Can't change PMU if filters are already in place */
> > -			if (kvm->arch.arm_pmu != arm_pmu &&
> > -			    kvm->arch.pmu_filter) {
> > +			if ((kvm->arch.arm_pmu != arm_pmu &&
> > +			     kvm->arch.pmu_filter) ||
> > +			    kvm->arch.ran_once) {
> >  				ret = -EBUSY;
> >  				break;
> >  			}
> > @@ -1040,6 +1041,11 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
> >  
> >  		mutex_lock(&vcpu->kvm->lock);
> >  
> > +		if (vcpu->kvm->arch.ran_once) {
> > +			mutex_unlock(&vcpu->kvm->lock);
> > +			return -EBUSY;
> > +		}
> > +
> >  		if (!vcpu->kvm->arch.pmu_filter) {
> >  			vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
> >  			if (!vcpu->kvm->arch.pmu_filter) {
> > 
> > which should prevent both PMU or filters to be changed once a single
> > vcpu as run.
> > 
> > Thoughts?
> 
> Haven't tested it either, but it looks good to me. If you agree, I can pick
> the diff, turn it into a patch and send it for the next iteration of this
> series as a fix for the PMU events filter, while keeping your authorship.

Of course, please help yourself! :-)

	M.

-- 
Without deviation from the norm, progress is not possible.


From andre.przywara at arm.com  Fri Jan  7 06:38:11 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 7 Jan 2022 14:38:11 +0000
Subject: [boot-wrapper PATCH v2 3/9] Makefile: Tell compiler to generate
 bare-metal code
In-Reply-To: <YdhF7kluP5vwzDf4@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-4-andre.przywara@arm.com>
 <YdhF7kluP5vwzDf4@FVFF77S0Q05N>
Message-ID: <20220107143811.3d193704@donnerap.cambridge.arm.com>

On Fri, 7 Jan 2022 13:53:50 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> On Wed, Dec 22, 2021 at 06:16:01PM +0000, Andre Przywara wrote:
> > Our GCC invocation does not provide many parameters, which lets the
> > toolchain fill in its own default setup.
> > In case of a native build or when using a full-featured cross-compiler,
> > this probably means Linux userland, which is not what we want for a
> > bare-metal application like boot-wrapper.
> > 
> > Tell the compiler to forget about those standard settings, and only use
> > what we explicitly ask for. In particular that means to not use toolchain
> > provided libraries and headers, since they might pull in more code than
> > we want, and might not run well in the boot-wrapper environment.
> > 
> > This also enables optimisation, since it produces much better code and
> > tends to avoid problems due to missing inlining, for instance.  
> 
> I'd appreciate if we could add some explanation for these (just in the commit
> message is fine), as e.g. it's not clear to me why -fno-toplevel-reorder is
> necessary.

Yeah, I was expecting some discussion about this. I went over most options
from the manpage a while ago (for some unrelated baremetal code project),
and decided for each option whether it would make sense or not. TBH I
don't remember every detail from that, but I can certainly just drop the
less critical options from that list.
And I would be happy to add some rationale for each of them, but wonder
what the best place would be? I'd rather do this in a file than in a
commit message, would you prefer comments in Makefile.am, or in README or
a separate file, with a pointer from Makefile.am. Or in a commit message
anyway?

Cheers,
Andre

> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  Makefile.am | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Makefile.am b/Makefile.am
> > index 3e970a3..d9ad6d1 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -124,9 +124,14 @@ CHOSEN_NODE	:= chosen {						\
> >  
> >  CPPFLAGS	+= $(INITRD_FLAGS)
> >  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
> > -CFLAGS		+= -Wall -fomit-frame-pointer
> > +CFLAGS		+= -Wall -Wstrict-prototypes -fomit-frame-pointer
> > +CFLAGS		+= -ffreestanding -nostdinc -nostdlib
> > +CFLAGS		+= -fno-common -fno-strict-aliasing -fno-stack-protector
> > +CFLAGS		+= -fno-toplevel-reorder
> > +CFLAGS		+= -fno-unwind-tables -fno-asynchronous-unwind-tables
> >  CFLAGS		+= -ffunction-sections -fdata-sections
> >  CFLAGS		+= -fno-pic -fno-pie
> > +CFLAGS		+= -Os
> >  LDFLAGS		+= --gc-sections
> >  
> >  OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> > -- 
> > 2.25.1
> >   



From mhocko at suse.com  Fri Jan  7 06:44:50 2022
From: mhocko at suse.com (Michal Hocko)
Date: Fri, 7 Jan 2022 15:44:50 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-7-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
Message-ID: <YdhR4vWdWksBALtM@dhcp22.suse.cz>

On Tue 04-01-22 13:22:25, Yu Zhao wrote:
[...]
> +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> +{
> +	static const struct mm_walk_ops mm_walk_ops = {
> +		.test_walk = should_skip_vma,
> +		.p4d_entry = walk_pud_range,
> +	};
> +
> +	int err;
> +#ifdef CONFIG_MEMCG
> +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> +#endif
> +
> +	walk->next_addr = FIRST_USER_ADDRESS;
> +
> +	do {
> +		unsigned long start = walk->next_addr;
> +		unsigned long end = mm->highest_vm_end;
> +
> +		err = -EBUSY;
> +
> +		rcu_read_lock();
> +#ifdef CONFIG_MEMCG
> +		if (memcg && atomic_read(&memcg->moving_account))
> +			goto contended;
> +#endif
> +		if (!mmap_read_trylock(mm))
> +			goto contended;

Have you evaluated the behavior under mmap_sem contention? I mean what
would be an effect of some mms being excluded from the walk? This path
is called from direct reclaim and we do allocate with exclusive mmap_sem
IIRC and the trylock can fail in a presence of pending writer if I am
not mistaken so even the read lock holder (e.g. an allocation from the #PF)
can bypass the walk.

Or is this considered statistically insignificant thus a theoretical
problem?
-- 
Michal Hocko
SUSE Labs


From andre.przywara at arm.com  Fri Jan  7 06:47:09 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 7 Jan 2022 14:47:09 +0000
Subject: [boot-wrapper PATCH v2 6/9] configure: Use earlycon instead of
 earlyprintk
In-Reply-To: <YdhHwXr0pp9d+nRn@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-7-andre.przywara@arm.com>
 <YdhHwXr0pp9d+nRn@FVFF77S0Q05N>
Message-ID: <20220107144709.5cd21ab5@donnerap.cambridge.arm.com>

On Fri, 7 Jan 2022 14:01:37 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> On Wed, Dec 22, 2021 at 06:16:04PM +0000, Andre Przywara wrote:
> > The arm64 Linux kernel dropped support for the "earlyprintk" command line
> > parameter a long time ago[1], instead it uses the earlycon parameter
> > now.
> > 
> > Replace earlyprintk with earlycon on the default command line, to see
> > early kernel output.
> > 
> > Ideally we would just say "earlycon" (without specifying an MMIO
> > address), but this relies on the stdout-path property in the /chosen
> > node, which the model DTs do not carry.  
> 
> Can we send a Linux patch to add that?

There is already:
http://lists.infradead.org/pipermail/linux-arm-kernel/2021-September/685791.html

But I think it got stuck somewhere.

Cheers,
Andre

> > [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=8ef0ed95ee04
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  configure.ac | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/configure.ac b/configure.ac
> > index 2b295de..9e3b722 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -99,7 +99,7 @@ AC_SUBST([FILESYSTEM], [$USE_INITRD])
> >  AM_CONDITIONAL([INITRD], [test "x$USE_INITRD" != "x"])
> >  
> >  AS_IF([test "x$X_IMAGE" = "x"],[C_CONSOLE="ttyAMA0"],[C_CONSOLE="hvc0"])
> > -C_CMDLINE="console=$C_CONSOLE earlyprintk=pl011,0x1c090000"
> > +C_CMDLINE="console=$C_CONSOLE earlycon=pl011,0x1c090000"
> >  AC_ARG_WITH([cmdline],
> >  	AS_HELP_STRING([--with-cmdline], [set a command line for the kernel]),
> >  	[C_CMDLINE=$withval])
> > -- 
> > 2.25.1
> >   



From narmstrong at baylibre.com  Fri Jan  7 06:55:09 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:09 +0100
Subject: [PATCH 0/6] drm/meson: add support for MIPI DSI Display
Message-ID: <20220107145515.613009-1-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
glue on the same Amlogic SoCs.

This adds support for the glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

The DW-MIPI-DSI transceiver + D-PHY are clocked by the GP0 PLL, and the ENCL encoder + VIU
pixel reader by the VCLK2 clock using the HDMI PLL.

The DW-MIPI-DSI transceiver gets this pixel stream as input clocked with the VCLK2 clock.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

This patchset is based on an earlier attempt at [1] for the AXG SoCs, but:
- the AXG has a single clock source for both transceiver + pixel, which makes it an
  exception instead of a rule, it's simpler to add support for G12A then add AXG on it
- previous glue code was a single monolitic code mixing encoders & bridges, this version
  is aligned on the previous cleanup done on HDMI & CVBS bridges architecture at [2]
- since the only output of AXG is DSI, AXG VPU support is post-poned until we implement
  single-clock DSI support specific case on top of this.

[1] https://lore.kernel.org/r/20200907081825.1654-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20211020123947.2585572-1-narmstrong at baylibre.com

Neil Armstrong (6):
  dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
  dt-bindings: display: meson-vpu: add third DPI output port
  drm/meson: venc: add ENCL encoder setup for MIPI-DSI output
  drm/meson: vclk: add DSI clock config
  drm/meson: add DSI encoder
  drm/meson: add support for MIPI-DSI transceiver

 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++
 .../bindings/display/amlogic,meson-vpu.yaml   |   5 +
 drivers/gpu/drm/meson/Kconfig                 |   7 +
 drivers/gpu/drm/meson/Makefile                |   3 +-
 drivers/gpu/drm/meson/meson_drv.c             |   7 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c     | 383 ++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h     | 115 ++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.c     | 159 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h     |  12 +
 drivers/gpu/drm/meson/meson_vclk.c            |  47 +++
 drivers/gpu/drm/meson/meson_vclk.h            |   1 +
 drivers/gpu/drm/meson/meson_venc.c            | 230 ++++++++++-
 drivers/gpu/drm/meson/meson_venc.h            |   6 +
 drivers/gpu/drm/meson/meson_vpp.h             |   2 +
 14 files changed, 1092 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:10 +0100
Subject: [PATCH 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-2-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
on the same Amlogic SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
new file mode 100644
index 000000000000..f3070783d606
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
@@ -0,0 +1,118 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+description: |
+  The Amlogic Meson Synopsys Designware Integration is composed of
+  - A Synopsys DesignWare MIPI DSI Host Controller IP
+  - A TOP control block controlling the Clocks & Resets of the IP
+
+allOf:
+  - $ref: dsi-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-g12a-dw-mipi-dsi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pclk
+      - const: px_clk
+      - const: meas_clk
+
+  resets:
+    minItems: 1
+
+  reset-names:
+    items:
+      - const: top
+
+  phys:
+    minItems: 1
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/$defs/port-base
+        unevaluatedProperties: false
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+  - ports
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    dsi at 7000 {
+          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+          reg = <0x6000 0x400>;
+          resets = <&reset_top>;
+          reset-names = "top";
+          clocks = <&clk_pclk>, <&clk_px>;
+          clock-names = "pclk", "px_clk";
+          phys = <&mipi_dphy>;
+          phy-names = "dphy";
+
+          ports {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              /* VPU VENC Input */
+              mipi_dsi_venc_port: port at 0 {
+                  reg = <0>;
+
+                  mipi_dsi_in: endpoint {
+                       remote-endpoint = <&dpi_out>;
+                  };
+              };
+
+              /* DSI Output */
+              mipi_dsi_panel_port: port at 1 {
+                  reg = <1>;
+
+                  mipi_out_panel: endpoint {
+                      remote-endpoint = <&mipi_in_panel>;
+                  };
+              };
+          };
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:13 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:13 +0100
Subject: [PATCH 4/6] drm/meson: vclk: add DSI clock config
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-5-narmstrong@baylibre.com>

The DSI path used the ENCL pixel encoder, thus this adds a clock
config using the HDMI PLL in order to feed the ENCL encoder via the
VCLK2 path and the CTS_ENCL clock output.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_vclk.c | 47 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_vclk.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 2a82119eb58e..5e4d982be1c8 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -55,6 +55,8 @@
 #define VCLK2_DIV_MASK		0xff
 #define VCLK2_DIV_EN		BIT(16)
 #define VCLK2_DIV_RESET		BIT(17)
+#define CTS_ENCL_SEL_MASK	(0xf << 12)
+#define CTS_ENCL_SEL_SHIFT	12
 #define CTS_VDAC_SEL_MASK	(0xf << 28)
 #define CTS_VDAC_SEL_SHIFT	28
 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
@@ -83,6 +85,7 @@
 #define VCLK_DIV12_EN		BIT(4)
 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
 #define CTS_ENCI_EN		BIT(0)
+#define CTS_ENCL_EN		BIT(3)
 #define CTS_ENCP_EN		BIT(2)
 #define CTS_VDAC_EN		BIT(4)
 #define HDMI_TX_PIXEL_EN	BIT(5)
@@ -1024,6 +1027,47 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
 }
 
+static void meson_dsi_clock_config(struct meson_drm *priv, unsigned int freq)
+{
+	meson_hdmi_pll_generic_set(priv, freq * 10);
+
+	/* Setup vid_pll divider value /5 */
+	meson_vid_pll_set(priv, VID_PLL_DIV_5);
+
+	/* Disable VCLK2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
+
+	/* Setup the VCLK2 divider value /2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_MASK, 2 - 1);
+
+	/* select vid_pll for vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
+			   VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
+
+	/* enable vclk2 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
+
+	/* select vclk2_div1 for encl */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
+			   CTS_ENCL_SEL_MASK, (8 << CTS_ENCL_SEL_SHIFT));
+
+	/* release vclk2_div_reset and enable vclk2_div */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_EN | VCLK2_DIV_RESET,
+			   VCLK2_DIV_EN);
+
+	/* enable vclk2_div1 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_DIV1_EN, VCLK2_DIV1_EN);
+
+	/* reset vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, 0);
+
+	/* enable encl_clk */
+	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, CTS_ENCL_EN, CTS_ENCL_EN);
+
+	usleep_range(10000, 11000);
+}
+
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		      unsigned int phy_freq, unsigned int vclk_freq,
 		      unsigned int venc_freq, unsigned int dac_freq,
@@ -1050,6 +1094,9 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		meson_vclk_set(priv, phy_freq, 0, 0, 0,
 			       VID_PLL_DIV_5, 2, 1, 1, false, false);
 		return;
+	} else if (target == MESON_VCLK_TARGET_DSI) {
+		meson_dsi_clock_config(priv, phy_freq);
+		return;
 	}
 
 	hdmi_tx_div = vclk_freq / dac_freq;
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 60617aaf18dd..1152b3af8d2e 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -17,6 +17,7 @@ enum {
 	MESON_VCLK_TARGET_CVBS = 0,
 	MESON_VCLK_TARGET_HDMI = 1,
 	MESON_VCLK_TARGET_DMT = 2,
+	MESON_VCLK_TARGET_DSI = 3,
 };
 
 /* 27MHz is the CVBS Pixel Clock */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:11 +0100
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI output port
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-3-narmstrong@baylibre.com>

Add third port corresponding to the ENCL DPI encoder used to connect
to DSI or LVDS transceivers.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
index 851cb0781217..525a01a38568 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
@@ -92,6 +92,11 @@ properties:
     description:
       A port node pointing to the HDMI-TX port node.
 
+  port at 2:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the DPI port node (e.g. DSI or LVDS transceiver).
+
   "#address-cells":
     const: 1
 
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:14 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:14 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-6-narmstrong@baylibre.com>

This adds an encoder bridge designed to drive a MIPI-DSI display
by using the ENCL encoder through the internal MIPI DSI transceiver
connected to the output of the ENCL pixel encoder.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Makefile            |   2 +-
 drivers/gpu/drm/meson/meson_drv.c         |   7 +
 drivers/gpu/drm/meson/meson_encoder_dsi.c | 159 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
 4 files changed, 179 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 3afa31bdc950..833e18c20603 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -2,7 +2,7 @@
 meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
 meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
 meson-drm-y += meson_rdma.o meson_osd_afbcd.o
-meson-drm-y += meson_encoder_hdmi.o
+meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 80f1d439841a..ff278a2b9e6e 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -33,6 +33,7 @@
 #include "meson_registers.h"
 #include "meson_encoder_cvbs.h"
 #include "meson_encoder_hdmi.h"
+#include "meson_encoder_dsi.h"
 #include "meson_viu.h"
 #include "meson_vpp.h"
 #include "meson_rdma.h"
@@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	if (ret)
 		goto free_drm;
 
+	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		ret = meson_encoder_dsi_init(priv);
+		if (ret)
+			goto free_drm;
+	}
+
 	ret = meson_plane_create(priv);
 	if (ret)
 		goto free_drm;
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
new file mode 100644
index 000000000000..90347821cf96
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+
+#include "meson_drv.h"
+#include "meson_encoder_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+#include "meson_vclk.h"
+
+struct meson_encoder_dsi {
+	struct drm_encoder encoder;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct meson_drm *priv;
+};
+
+#define bridge_to_meson_encoder_dsi(x) \
+	container_of(x, struct meson_encoder_dsi, bridge)
+
+static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
+				 &encoder_dsi->bridge, flags);
+}
+
+static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
+
+	meson_venc_mipi_dsi_mode_set(priv, mode);
+	meson_encl_load_gamma(priv);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
+}
+
+static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+}
+
+static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
+					     struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi =
+					bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = meson_encoder_dsi->priv;
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+}
+
+static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
+	.attach	= meson_encoder_dsi_attach,
+	/*
+	 * TOFIX: remove when dw-mipi-dsi moves out of mode_set
+	 * We should get rid of mode_set, but until dw-mipi-dsi uses it
+	 * we need to setup the pixel clock before the following
+	 * bridge tries to setup the HW.
+	 */
+	.mode_set = meson_encoder_dsi_mode_set,
+	.atomic_enable = meson_encoder_dsi_atomic_enable,
+	.atomic_disable	= meson_encoder_dsi_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+int meson_encoder_dsi_init(struct meson_drm *priv)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi;
+	struct device_node *remote;
+	int ret;
+
+	meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
+	if (!meson_encoder_dsi)
+		return -ENOMEM;
+
+	/* DSI Transceiver Bridge */
+	remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
+	if (!remote) {
+		dev_err(priv->dev, "DSI transceiver device is disabled");
+		return 0;
+	}
+
+	meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
+	if (!meson_encoder_dsi->next_bridge) {
+		dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
+		return -EPROBE_DEFER;
+	}
+
+	/* DSI Encoder Bridge */
+	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
+	meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
+	meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&meson_encoder_dsi->bridge);
+
+	meson_encoder_dsi->priv = priv;
+
+	/* Encoder */
+	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
+		return ret;
+	}
+
+	meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
+
+	/* Attach DSI Encoder Bridge to Encoder */
+	ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
+	if (ret) {
+		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * We should have now in place:
+	 * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
+	 */
+
+	dev_dbg(priv->dev, "DSI encoder initialized\n");
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
new file mode 100644
index 000000000000..0f4b641eb633
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+
+#ifndef __MESON_ENCODER_DSI_H
+#define __MESON_ENCODER_DSI_H
+
+int meson_encoder_dsi_init(struct meson_drm *priv);
+
+#endif /* __MESON_ENCODER_DSI_H */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:12 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-4-narmstrong@baylibre.com>

This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
Amlogic AXG SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_venc.c | 230 ++++++++++++++++++++++++++++-
 drivers/gpu/drm/meson/meson_venc.h |   6 +
 drivers/gpu/drm/meson/meson_vpp.h  |   2 +
 3 files changed, 236 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 3c55ed003359..b430dc06aa34 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/iopoll.h>
 
 #include <drm/drm_modes.h>
 
@@ -1557,6 +1558,224 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 }
 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
 
+static unsigned short meson_encl_gamma_table[256] = {
+	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
+	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
+	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
+	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
+	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
+	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
+	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
+	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
+	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
+	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
+	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
+	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
+	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
+	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
+};
+
+#define GAMMA_VCOM_POL    7     /* RW */
+#define GAMMA_RVS_OUT     6     /* RW */
+#define ADR_RDY           5     /* Read Only */
+#define WR_RDY            4     /* Read Only */
+#define RD_RDY            3     /* Read Only */
+#define GAMMA_TR          2     /* RW */
+#define GAMMA_SET         1     /* RW */
+#define GAMMA_EN          0     /* RW */
+
+#define H_RD              12
+#define H_AUTO_INC        11
+#define H_SEL_R           10
+#define H_SEL_G           9
+#define H_SEL_B           8
+#define HADR_MSB          7            /* 7:0 */
+#define HADR              0            /* 7:0 */
+
+#define GAMMA_RETRY       1000
+
+static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
+				       u32 rgb_mask)
+{
+	int i, ret;
+	u32 reg;
+
+	writel_bits_relaxed(BIT(GAMMA_EN), 0,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+
+	ret = readl_relaxed_poll_timeout(priv->io_base +
+						_REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & BIT(ADR_RDY), 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(BIT(H_AUTO_INC) |
+		       BIT(rgb_mask) |
+		       (0 << HADR),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+
+	for (i = 0; i < 256; i++) {
+		ret = readl_relaxed_poll_timeout(priv->io_base +
+							_REG(L_GAMMA_CNTL_PORT),
+						 reg, reg & BIT(WR_RDY),
+						 10, 10000);
+		if (ret)
+			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
+
+		writel_relaxed(data[i],
+			       priv->io_base + _REG(L_GAMMA_DATA_PORT));
+	}
+
+	ret = readl_relaxed_poll_timeout(priv->io_base +
+						_REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & BIT(ADR_RDY), 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(BIT(H_AUTO_INC) |
+		       BIT(rgb_mask) |
+		       (0x23 << HADR),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+}
+
+void meson_encl_load_gamma(struct meson_drm *priv)
+{
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_R);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_G);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, H_SEL_B);
+
+	writel_bits_relaxed(BIT(GAMMA_EN), BIT(GAMMA_EN),
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+}
+
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode)
+{
+	unsigned int max_pxcnt;
+	unsigned int max_lncnt;
+	unsigned int havon_begin;
+	unsigned int havon_end;
+	unsigned int vavon_bline;
+	unsigned int vavon_eline;
+	unsigned int hso_begin;
+	unsigned int hso_end;
+	unsigned int vso_begin;
+	unsigned int vso_end;
+	unsigned int vso_bline;
+	unsigned int vso_eline;
+
+	max_pxcnt = mode->htotal - 1;
+	max_lncnt = mode->vtotal - 1;
+	havon_begin = mode->htotal - mode->hsync_start;
+	havon_end = havon_begin + mode->hdisplay - 1;
+	vavon_bline = mode->vtotal - mode->vsync_start;
+	vavon_eline = vavon_bline + mode->vdisplay - 1;
+	hso_begin = 0;
+	hso_end = mode->hsync_end - mode->hsync_start;
+	vso_begin = 0;
+	vso_end = 0;
+	vso_bline = 0;
+	vso_eline = mode->vsync_end - mode->vsync_start;
+
+	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
+	writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
+	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
+	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
+	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
+
+	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
+	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
+	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
+	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
+	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
+	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
+	writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
+
+	/* default black pattern */
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
+	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
+	writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
+
+	/* Hsync signal for TTL */
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
+	} else {
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
+	}
+	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
+
+	/* Vsync signal for TTL */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	} else {
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	}
+
+	/* DE signal */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
+
+	/* Hsync signal */
+	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
+	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
+	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
+
+	/* Vsync signal */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
+	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
+	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
+
+	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
+	writel_relaxed(BIT(4) | BIT(5),
+		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
+
+	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
+}
+EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
+
 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
 			       struct meson_cvbs_enci_mode *mode)
 {
@@ -1747,8 +1966,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
 
 void meson_venc_enable_vsync(struct meson_drm *priv)
 {
-	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
-		       priv->io_base + _REG(VENC_INTCTRL));
+	switch (priv->venc.current_mode) {
+	case MESON_VENC_MODE_MIPI_DSI:
+		writel_relaxed(0x200,
+			       priv->io_base + _REG(VENC_INTCTRL));
+		break;
+	default:
+		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+	}
 	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
 }
 
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index 9138255ffc9e..0f59adb1c6db 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -21,6 +21,7 @@ enum {
 	MESON_VENC_MODE_CVBS_PAL,
 	MESON_VENC_MODE_CVBS_NTSC,
 	MESON_VENC_MODE_HDMI,
+	MESON_VENC_MODE_MIPI_DSI,
 };
 
 struct meson_cvbs_enci_mode {
@@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
 	unsigned int analog_sync_adj;
 };
 
+/* LCD Encoder gamma setup */
+void meson_encl_load_gamma(struct meson_drm *priv);
+
 /* HDMI Clock parameters */
 enum drm_mode_status
 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
@@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 			      unsigned int ycrcb_map,
 			      bool yuv420_mode,
 			      const struct drm_display_mode *mode);
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode);
 unsigned int meson_venci_get_field(struct meson_drm *priv);
 
 void meson_venc_enable_vsync(struct meson_drm *priv);
diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
index afc9553ed8d3..b790042a1650 100644
--- a/drivers/gpu/drm/meson/meson_vpp.h
+++ b/drivers/gpu/drm/meson/meson_vpp.h
@@ -12,6 +12,8 @@
 struct drm_rect;
 struct meson_drm;
 
+/* Mux VIU/VPP to ENCL */
+#define MESON_VIU_VPP_MUX_ENCL	0x0
 /* Mux VIU/VPP to ENCI */
 #define MESON_VIU_VPP_MUX_ENCI	0x5
 /* Mux VIU/VPP to ENCP */
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 06:55:15 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 15:55:15 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220107145515.613009-1-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
Message-ID: <20220107145515.613009-7-narmstrong@baylibre.com>

The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
Glue on other Amlogic SoCs.

This adds support for the Glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Kconfig             |   7 +
 drivers/gpu/drm/meson/Makefile            |   1 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 383 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 115 +++++++
 4 files changed, 506 insertions(+)
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h

diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 6c70fc3214af..71a1364b51e1 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
 	default y if DRM_MESON
 	select DRM_DW_HDMI
 	imply DRM_DW_HDMI_I2S_AUDIO
+
+config DRM_MESON_DW_MIPI_DSI
+	tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
+	depends on DRM_MESON
+	default y if DRM_MESON
+	select DRM_DW_MIPI_DSI
+	select GENERIC_PHY_MIPI_DPHY
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 833e18c20603..43071bdbd4b9 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
+obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
new file mode 100644
index 000000000000..75af3eec1b74
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/reset.h>
+#include <linux/phy/phy.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+
+#include "meson_drv.h"
+#include "meson_dw_mipi_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+
+#define DRIVER_NAME "meson-dw-mipi-dsi"
+#define DRIVER_DESC "Amlogic Meson MIPI-DSI DRM driver"
+
+/*  MIPI DSI/VENC Color Format Definitions */
+#define MIPI_DSI_VENC_COLOR_30B   0x0
+#define MIPI_DSI_VENC_COLOR_24B   0x1
+#define MIPI_DSI_VENC_COLOR_18B   0x2
+#define MIPI_DSI_VENC_COLOR_16B   0x3
+
+#define COLOR_16BIT_CFG_1         0x0
+#define COLOR_16BIT_CFG_2         0x1
+#define COLOR_16BIT_CFG_3         0x2
+#define COLOR_18BIT_CFG_1         0x3
+#define COLOR_18BIT_CFG_2         0x4
+#define COLOR_24BIT               0x5
+#define COLOR_20BIT_LOOSE         0x6
+#define COLOR_24_BIT_YCBCR        0x7
+#define COLOR_16BIT_YCBCR         0x8
+#define COLOR_30BIT               0x9
+#define COLOR_36BIT               0xa
+#define COLOR_12BIT               0xb
+#define COLOR_RGB_111             0xc
+#define COLOR_RGB_332             0xd
+#define COLOR_RGB_444             0xe
+
+/*  MIPI DSI Relative REGISTERs Definitions */
+/* For MIPI_DSI_TOP_CNTL */
+#define BIT_DPI_COLOR_MODE        20
+#define BIT_IN_COLOR_MODE         16
+#define BIT_CHROMA_SUBSAMPLE      14
+#define BIT_COMP2_SEL             12
+#define BIT_COMP1_SEL             10
+#define BIT_COMP0_SEL              8
+#define BIT_DE_POL                 6
+#define BIT_HSYNC_POL              5
+#define BIT_VSYNC_POL              4
+#define BIT_DPICOLORM              3
+#define BIT_DPISHUTDN              2
+#define BIT_EDPITE_INTR_PULSE      1
+#define BIT_ERR_INTR_PULSE         0
+
+struct meson_dw_mipi_dsi {
+	struct meson_drm *priv;
+	struct device *dev;
+	void __iomem *base;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+	struct dw_mipi_dsi *dmd;
+	struct dw_mipi_dsi_plat_data pdata;
+	struct mipi_dsi_device *dsi_device;
+	const struct drm_display_mode *mode;
+	struct clk *px_clk;
+};
+
+#define encoder_to_meson_dw_mipi_dsi(x) \
+	container_of(x, struct meson_dw_mipi_dsi, encoder)
+
+static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
+{
+	writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
+		       mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+	writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+
+	writel_bits_relaxed(0x3, 0x3, mipi_dsi->base + MIPI_DSI_TOP_CLK_CNTL);
+
+	writel_relaxed(0, mipi_dsi->base + MIPI_DSI_TOP_MEM_PD);
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	unsigned int dpi_data_format, venc_data_width;
+	int ret;
+
+	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+	if (ret) {
+		pr_err("Failed to set DSI PLL rate %lu\n",
+		       mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+
+		return ret;
+	}
+
+	switch (mipi_dsi->dsi_device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		dpi_data_format = COLOR_24BIT;
+		venc_data_width = MIPI_DSI_VENC_COLOR_24B;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		dpi_data_format = COLOR_18BIT_CFG_2;
+		venc_data_width = MIPI_DSI_VENC_COLOR_18B;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		return -EINVAL;
+	};
+
+	/* Configure color format for DPI register */
+	writel_relaxed((dpi_data_format  << BIT_DPI_COLOR_MODE)  |
+		       (venc_data_width  << BIT_IN_COLOR_MODE) |
+			0 << BIT_COMP0_SEL |
+			1 << BIT_COMP1_SEL |
+			2 << BIT_COMP2_SEL |
+			(mipi_dsi->mode->flags & DRM_MODE_FLAG_NHSYNC ? 0 : BIT(BIT_HSYNC_POL)) |
+			(mipi_dsi->mode->flags & DRM_MODE_FLAG_NVSYNC ? 0 : BIT(BIT_VSYNC_POL)),
+			mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	phy_power_on(mipi_dsi->phy);
+
+	return 0;
+}
+
+static void dw_mipi_dsi_phy_power_off(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	phy_power_off(mipi_dsi->phy);
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			  unsigned long mode_flags, u32 lanes, u32 format,
+			  unsigned int *lane_mbps)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	int bpp;
+
+	mipi_dsi->mode = mode;
+
+	bpp = mipi_dsi_pixel_format_to_bpp(mipi_dsi->dsi_device->format);
+
+	phy_mipi_dphy_get_default_config(mode->clock * 1000,
+					 bpp, mipi_dsi->dsi_device->lanes,
+					 &mipi_dsi->phy_opts.mipi_dphy);
+
+	phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
+
+	*lane_mbps = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate / 1000000;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			   struct dw_mipi_dsi_dphy_timing *timing)
+{
+	/* TOFIX handle other cases */
+
+	timing->clk_lp2hs = 37;
+	timing->clk_hs2lp = 135;
+	timing->data_lp2hs = 50;
+	timing->data_hs2lp = 3;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_get_esc_clk_rate(void *priv_data, unsigned int *esc_clk_rate)
+{
+	*esc_clk_rate = 4; /* Mhz */
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops meson_dw_mipi_dsi_phy_ops = {
+	.init = dw_mipi_dsi_phy_init,
+	.power_off = dw_mipi_dsi_phy_power_off,
+	.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+	.get_timing = dw_mipi_dsi_phy_get_timing,
+	.get_esc_clk_rate = dw_mipi_dsi_get_esc_clk_rate,
+};
+
+static int meson_dw_mipi_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
+	struct drm_device *drm = data;
+	struct meson_drm *priv = drm->dev_private;
+
+	/* Check before if we are supposed to have a sub-device... */
+	if (!mipi_dsi->dsi_device) {
+		dw_mipi_dsi_remove(mipi_dsi->dmd);
+		return -EPROBE_DEFER;
+	}
+
+	mipi_dsi->priv = priv;
+
+	meson_dw_mipi_dsi_hw_init(mipi_dsi);
+
+	return 0;
+}
+
+static const struct component_ops meson_dw_mipi_dsi_ops = {
+	.bind	= meson_dw_mipi_dsi_bind,
+};
+
+static int meson_dw_mipi_dsi_host_attach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	mipi_dsi->dsi_device = device;
+
+	switch (device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		DRM_DEV_ERROR(mipi_dsi->dev, "invalid pixel format %d\n", device->format);
+		return -EINVAL;
+	};
+
+	phy_init(mipi_dsi->phy);
+
+	return 0;
+}
+
+static int meson_dw_mipi_dsi_host_detach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (device == mipi_dsi->dsi_device)
+		mipi_dsi->dsi_device = NULL;
+	else
+		return -EINVAL;
+
+	phy_exit(mipi_dsi->phy);
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_host_ops meson_dw_mipi_dsi_host_ops = {
+	.attach = meson_dw_mipi_dsi_host_attach,
+	.detach = meson_dw_mipi_dsi_host_detach,
+};
+
+static int meson_dw_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi;
+	struct reset_control *top_rst;
+	struct resource *res;
+	int ret;
+
+	mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+	if (!mipi_dsi)
+		return -ENOMEM;
+
+	mipi_dsi->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mipi_dsi->base))
+		return PTR_ERR(mipi_dsi->base);
+
+	mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
+	if (IS_ERR(mipi_dsi->phy)) {
+		ret = PTR_ERR(mipi_dsi->phy);
+		dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
+		return ret;
+	}
+
+	mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
+	if (IS_ERR(mipi_dsi->px_clk)) {
+		dev_err(&pdev->dev, "Unable to get PLL clk\n");
+		return PTR_ERR(mipi_dsi->px_clk);
+	}
+
+	/*
+	 * We use a TOP reset signal because the APB reset signal
+	 * is handled by the TOP control registers.
+	 */
+	top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
+	if (IS_ERR(top_rst)) {
+		ret = PTR_ERR(top_rst);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
+
+		return ret;
+	}
+
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to prepare/enable PX clock\n");
+		return ret;
+	}
+
+	reset_control_assert(top_rst);
+	usleep_range(10, 20);
+	reset_control_deassert(top_rst);
+
+	/* MIPI DSI Controller */
+
+	mipi_dsi->pdata.base = mipi_dsi->base;
+	mipi_dsi->pdata.max_data_lanes = 4;
+	mipi_dsi->pdata.phy_ops = &meson_dw_mipi_dsi_phy_ops;
+	mipi_dsi->pdata.host_ops = &meson_dw_mipi_dsi_host_ops;
+	mipi_dsi->pdata.priv_data = mipi_dsi;
+	platform_set_drvdata(pdev, mipi_dsi);
+
+	mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
+	if (IS_ERR(mipi_dsi->dmd)) {
+		ret = PTR_ERR(mipi_dsi->dmd);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to probe dw_mipi_dsi: %d\n", ret);
+		goto err_clkdisable;
+	}
+
+	return component_add(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+err_clkdisable:
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return ret;
+}
+
+static int meson_dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+	dw_mipi_dsi_remove(mipi_dsi->dmd);
+
+	component_del(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return 0;
+}
+
+static const struct of_device_id meson_dw_mipi_dsi_of_table[] = {
+	{ .compatible = "amlogic,meson-g12a-dw-mipi-dsi", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_dw_mipi_dsi_of_table);
+
+static struct platform_driver meson_dw_mipi_dsi_platform_driver = {
+	.probe		= meson_dw_mipi_dsi_probe,
+	.remove		= meson_dw_mipi_dsi_remove,
+	.driver		= {
+		.name		= DRIVER_NAME,
+		.of_match_table	= meson_dw_mipi_dsi_of_table,
+	},
+};
+module_platform_driver(meson_dw_mipi_dsi_platform_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
new file mode 100644
index 000000000000..4075a132e005
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_DW_MIPI_DSI_H
+#define __MESON_DW_MIPI_DSI_H
+
+/* Top-level registers */
+/* [31: 3]    Reserved.     Default 0.
+ *     [2] RW dpi_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_dpi block.   0=Release reset.
+ *     [1] RW intr_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_intr block.  0=Release reset.
+ *     [0] RW dwc_rst_n:  Default 1.
+ *		1=Assert SW reset on IP core.   0=Release reset.
+ */
+#define MIPI_DSI_TOP_SW_RESET                      0x3c0
+/* [31: 5] Reserved.   Default 0.
+ *     [4] RW manual_edpihalt: Default 0.
+ *		1=Manual suspend VencL; 0=do not suspend VencL.
+ *     [3] RW auto_edpihalt_en: Default 0.
+ *		1=Enable IP's edpihalt signal to suspend VencL;
+ *		0=IP's edpihalt signal does not affect VencL.
+ *     [2] RW clock_freerun: Apply to auto-clock gate only. Default 0.
+ *		0=Default, use auto-clock gating to save power;
+ *		1=use free-run clock, disable auto-clock gating, for debug mode.
+ *     [1] RW enable_pixclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable pixclk.      Default 0.
+ *     [0] RW enable_sysclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable sysclk.      Default 0.
+ */
+#define MIPI_DSI_TOP_CLK_CNTL                      0x3c4
+/* [31:24]    Reserved. Default 0.
+ * [23:20] RW dpi_color_mode: Define DPI pixel format. Default 0.
+ *		0=16-bit RGB565 config 1;
+ *		1=16-bit RGB565 config 2;
+ *		2=16-bit RGB565 config 3;
+ *		3=18-bit RGB666 config 1;
+ *		4=18-bit RGB666 config 2;
+ *		5=24-bit RGB888;
+ *		6=20-bit YCbCr 4:2:2;
+ *		7=24-bit YCbCr 4:2:2;
+ *		8=16-bit YCbCr 4:2:2;
+ *		9=30-bit RGB;
+ *		10=36-bit RGB;
+ *		11=12-bit YCbCr 4:2:0.
+ *    [19] Reserved. Default 0.
+ * [18:16] RW in_color_mode:  Define VENC data width. Default 0.
+ *		0=30-bit pixel;
+ *		1=24-bit pixel;
+ *		2=18-bit pixel, RGB666;
+ *		3=16-bit pixel, RGB565.
+ * [15:14] RW chroma_subsample: Define method of chroma subsampling. Default 0.
+ *		Applicable to YUV422 or YUV420 only.
+ *		0=Use even pixel's chroma;
+ *		1=Use odd pixel's chroma;
+ *		2=Use averaged value between even and odd pair.
+ * [13:12] RW comp2_sel:  Select which component to be Cr or B: Default 2.
+ *		0=comp0; 1=comp1; 2=comp2.
+ * [11:10] RW comp1_sel:  Select which component to be Cb or G: Default 1.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *  [9: 8] RW comp0_sel:  Select which component to be Y  or R: Default 0.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *     [7]    Reserved. Default 0.
+ *     [6] RW de_pol:  Default 0.
+ *		If DE input is active low, set to 1 to invert to active high.
+ *     [5] RW hsync_pol: Default 0.
+ *		If HS input is active low, set to 1 to invert to active high.
+ *     [4] RW vsync_pol: Default 0.
+ *		If VS input is active low, set to 1 to invert to active high.
+ *     [3] RW dpicolorm: Signal to IP.   Default 0.
+ *     [2] RW dpishutdn: Signal to IP.   Default 0.
+ *     [1]    Reserved.  Default 0.
+ *     [0]    Reserved.  Default 0.
+ */
+#define MIPI_DSI_TOP_CNTL                          0x3c8
+#define MIPI_DSI_TOP_SUSPEND_CNTL                  0x3cc
+#define MIPI_DSI_TOP_SUSPEND_LINE                  0x3d0
+#define MIPI_DSI_TOP_SUSPEND_PIX                   0x3d4
+#define MIPI_DSI_TOP_MEAS_CNTL                     0x3d8
+/* [0] R  stat_edpihalt:  edpihalt signal from IP.    Default 0. */
+#define MIPI_DSI_TOP_STAT                          0x3dc
+#define MIPI_DSI_TOP_MEAS_STAT_TE0                 0x3e0
+#define MIPI_DSI_TOP_MEAS_STAT_TE1                 0x3e4
+#define MIPI_DSI_TOP_MEAS_STAT_VS0                 0x3e8
+#define MIPI_DSI_TOP_MEAS_STAT_VS1                 0x3ec
+/* [31:16] RW intr_stat/clr. Default 0.
+ *		For each bit, read as this interrupt level status,
+ *		write 1 to clear.
+ * [31:22] Reserved
+ * [   21] stat/clr of eof interrupt
+ * [   21] vde_fall interrupt
+ * [   19] stat/clr of de_rise interrupt
+ * [   18] stat/clr of vs_fall interrupt
+ * [   17] stat/clr of vs_rise interrupt
+ * [   16] stat/clr of dwc_edpite interrupt
+ * [15: 0] RW intr_enable. Default 0.
+ *		For each bit, 1=enable this interrupt, 0=disable.
+ *	[15: 6] Reserved
+ *	[    5] eof interrupt
+ *	[    4] de_fall interrupt
+ *	[    3] de_rise interrupt
+ *	[    2] vs_fall interrupt
+ *	[    1] vs_rise interrupt
+ *	[    0] dwc_edpite interrupt
+ */
+#define MIPI_DSI_TOP_INTR_CNTL_STAT                0x3f0
+// 31: 2    Reserved.   Default 0.
+//  1: 0 RW mem_pd.     Default 3.
+#define MIPI_DSI_TOP_MEM_PD                        0x3f4
+
+#endif /* __MESON_DW_MIPI_DSI_H */
-- 
2.25.1



From rostedt at goodmis.org  Fri Jan  7 06:56:38 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Fri, 7 Jan 2022 09:56:38 -0500
Subject: [PATCHv6 4/5] tracing: Add register read/write tracing support
In-Reply-To: <df9b5a82-5f00-f3ec-14cf-0b212be2a7a7@quicinc.com>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
 <20220106131824.073fbe5c@gandalf.local.home>
 <df9b5a82-5f00-f3ec-14cf-0b212be2a7a7@quicinc.com>
Message-ID: <20220107095638.7d81c1b9@gandalf.local.home>

On Fri, 7 Jan 2022 10:40:05 +0530
Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:

> Hi Steve,
> 
> On 1/6/2022 11:48 PM, Steven Rostedt wrote:
> > This should not be in the kernel/trace directory. It should be in the  
> 
> Hmm these are called from low level generic io header file 
> (include/asm-generic/) where
> we wouldn't have any Kconfig to control this feature flexibly and as we 
> can have this as
> a generic feature selectable by other architectures, wouldn't this be 
> suited in kernel/trace?

Isn't there a place for generic rwmmio code?

> I thought you were ok with the folder structure in the initial versions 
> of the series?

Sorry, I missed the C file in kernel/trace. The files in kernel/trace tend
to be specific for the internals of tracing. This C file is more to hold
helper functions for mmio, which to me should be someplace for mmio code.
Perhaps in mm/ ?

-- Steve


From narmstrong at baylibre.com  Fri Jan  7 07:05:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:12 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <20220107150512.614423-1-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
Message-ID: <20220107150512.614423-3-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY used to communicate with DSI
panels.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/phy/amlogic/Kconfig                   |  12 ++
 drivers/phy/amlogic/Makefile                  |   1 +
 .../amlogic/phy-meson-g12a-mipi-dphy-analog.c | 177 ++++++++++++++++++
 3 files changed, 190 insertions(+)
 create mode 100644 drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c

diff --git a/drivers/phy/amlogic/Kconfig b/drivers/phy/amlogic/Kconfig
index db5d0cd757e3..ac898a102bcc 100644
--- a/drivers/phy/amlogic/Kconfig
+++ b/drivers/phy/amlogic/Kconfig
@@ -49,6 +49,18 @@ config PHY_MESON_G12A_USB3_PCIE
 	  in Meson G12A SoCs.
 	  If unsure, say N.
 
+config PHY_MESON_G12A_MIPI_DPHY_ANALOG
+	tristate "Meson G12A MIPI Analog DPHY driver"
+	default ARCH_MESON
+	depends on OF && (ARCH_MESON || COMPILE_TEST)
+	select GENERIC_PHY
+	select REGMAP_MMIO
+	select GENERIC_PHY_MIPI_DPHY
+	help
+	  Enable this to support the Meson MIPI Analog DPHY found in Meson G12A
+	  SoCs.
+	  If unsure, say N.
+
 config PHY_MESON_AXG_PCIE
 	tristate "Meson AXG PCIE PHY driver"
 	default ARCH_MESON
diff --git a/drivers/phy/amlogic/Makefile b/drivers/phy/amlogic/Makefile
index 8fa07fbd0d92..2eada0a683ca 100644
--- a/drivers/phy/amlogic/Makefile
+++ b/drivers/phy/amlogic/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_PHY_MESON8B_USB2)			+= phy-meson8b-usb2.o
 obj-$(CONFIG_PHY_MESON_GXL_USB2)		+= phy-meson-gxl-usb2.o
 obj-$(CONFIG_PHY_MESON_G12A_USB2)		+= phy-meson-g12a-usb2.o
 obj-$(CONFIG_PHY_MESON_G12A_USB3_PCIE)		+= phy-meson-g12a-usb3-pcie.o
+obj-$(CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG)	+= phy-meson-g12a-mipi-dphy-analog.o
 obj-$(CONFIG_PHY_MESON_AXG_PCIE)		+= phy-meson-axg-pcie.o
 obj-$(CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG)	+= phy-meson-axg-mipi-pcie-analog.o
 obj-$(CONFIG_PHY_MESON_AXG_MIPI_DPHY)		+= phy-meson-axg-mipi-dphy.o
diff --git a/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
new file mode 100644
index 000000000000..6e9d416c0552
--- /dev/null
+++ b/drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Meson G12A MIPI DSI Analog PHY
+ *
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/phy/phy.h>
+
+#define HHI_MIPI_CNTL0 0x00
+#define		HHI_MIPI_CNTL0_DIF_REF_CTL1	GENMASK(31, 16)
+#define		HHI_MIPI_CNTL0_DIF_REF_CTL0	GENMASK(15, 0)
+
+#define HHI_MIPI_CNTL1 0x04
+#define		HHI_MIPI_CNTL1_BANDGAP		BIT(16)
+#define		HHI_MIPI_CNTL2_DIF_REF_CTL2	GENMASK(15, 0)
+
+#define HHI_MIPI_CNTL2 0x08
+#define		HHI_MIPI_CNTL2_DIF_TX_CTL1	GENMASK(31, 16)
+#define		HHI_MIPI_CNTL2_CH_EN		GENMASK(15, 11)
+#define		HHI_MIPI_CNTL2_DIF_TX_CTL0	GENMASK(10, 0)
+
+#define DSI_LANE_0				BIT(4)
+#define DSI_LANE_1				BIT(3)
+#define DSI_LANE_CLK				BIT(2)
+#define DSI_LANE_2				BIT(1)
+#define DSI_LANE_3				BIT(0)
+
+struct phy_g12a_mipi_dphy_analog_priv {
+	struct phy *phy;
+	struct regmap *regmap;
+	struct phy_configure_opts_mipi_dphy config;
+};
+
+static int phy_g12a_mipi_dphy_analog_configure(struct phy *phy,
+					       union phy_configure_opts *opts)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+	int ret;
+
+	ret = phy_mipi_dphy_config_validate(&opts->mipi_dphy);
+	if (ret)
+		return ret;
+
+	memcpy(&priv->config, opts, sizeof(priv->config));
+
+	return 0;
+}
+
+static int phy_g12a_mipi_dphy_analog_power_on(struct phy *phy)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+	unsigned int reg;
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL0,
+		     FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL0, 0x8) |
+		     FIELD_PREP(HHI_MIPI_CNTL0_DIF_REF_CTL1, 0xa487));
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL1,
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_REF_CTL2, 0x2e) |
+		     HHI_MIPI_CNTL1_BANDGAP);
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL2,
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_TX_CTL0, 0x459) |
+		     FIELD_PREP(HHI_MIPI_CNTL2_DIF_TX_CTL1, 0x2680));
+
+	reg = DSI_LANE_CLK;
+	switch (priv->config.lanes) {
+	case 4:
+		reg |= DSI_LANE_3;
+		fallthrough;
+	case 3:
+		reg |= DSI_LANE_2;
+		fallthrough;
+	case 2:
+		reg |= DSI_LANE_1;
+		fallthrough;
+	case 1:
+		reg |= DSI_LANE_0;
+		break;
+	default:
+		reg = 0;
+	}
+
+	regmap_update_bits(priv->regmap, HHI_MIPI_CNTL2,
+			   HHI_MIPI_CNTL2_CH_EN,
+			   FIELD_PREP(HHI_MIPI_CNTL2_CH_EN, reg));
+
+	return 0;
+}
+
+static int phy_g12a_mipi_dphy_analog_power_off(struct phy *phy)
+{
+	struct phy_g12a_mipi_dphy_analog_priv *priv = phy_get_drvdata(phy);
+
+	regmap_write(priv->regmap, HHI_MIPI_CNTL0, 0);
+	regmap_write(priv->regmap, HHI_MIPI_CNTL1, 0);
+	regmap_write(priv->regmap, HHI_MIPI_CNTL2, 0);
+
+	return 0;
+}
+
+static const struct phy_ops phy_g12a_mipi_dphy_analog_ops = {
+	.configure = phy_g12a_mipi_dphy_analog_configure,
+	.power_on = phy_g12a_mipi_dphy_analog_power_on,
+	.power_off = phy_g12a_mipi_dphy_analog_power_off,
+	.owner = THIS_MODULE,
+};
+
+static int phy_g12a_mipi_dphy_analog_probe(struct platform_device *pdev)
+{
+	struct phy_provider *phy;
+	struct device *dev = &pdev->dev;
+	struct phy_g12a_mipi_dphy_analog_priv *priv;
+	struct device_node *np = dev->of_node;
+	struct regmap *map;
+	int ret;
+
+	priv = devm_kmalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	/* Get the hhi system controller node */
+	map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+	if (IS_ERR(map)) {
+		dev_err(dev,
+			"failed to get HHI regmap\n");
+		return PTR_ERR(map);
+	}
+
+	priv->regmap = map;
+
+	priv->phy = devm_phy_create(dev, np, &phy_g12a_mipi_dphy_analog_ops);
+	if (IS_ERR(priv->phy)) {
+		ret = PTR_ERR(priv->phy);
+		if (ret != -EPROBE_DEFER)
+			dev_err(dev, "failed to create PHY\n");
+		return ret;
+	}
+
+	phy_set_drvdata(priv->phy, priv);
+	dev_set_drvdata(dev, priv);
+
+	phy = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy);
+}
+
+static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
+	{
+		.compatible = "amlogic,g12a-mipi-dphy-analog",
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, phy_g12a_mipi_dphy_analog_of_match);
+
+static struct platform_driver phy_g12a_mipi_dphy_analog_driver = {
+	.probe = phy_g12a_mipi_dphy_analog_probe,
+	.driver = {
+		.name = "phy-meson-g12a-mipi-dphy-analog",
+		.of_match_table = phy_g12a_mipi_dphy_analog_of_match,
+	},
+};
+module_platform_driver(phy_g12a_mipi_dphy_analog_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION("Meson G12A MIPI Analog D-PHY driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 07:05:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:11 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI D-PHY
 bindings
In-Reply-To: <20220107150512.614423-1-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
Message-ID: <20220107150512.614423-2-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY to communicate with DSI
panels, this adds the bindings.

This Analog D-PHY works with a separate Digital MIPI D-PHY.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 .../phy/amlogic,g12a-mipi-dphy-analog.yaml    | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml

diff --git a/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml b/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
new file mode 100644
index 000000000000..7aa0c05d6ce4
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/amlogic,g12a-mipi-dphy-analog.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic G12A MIPI analog PHY
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+properties:
+  compatible:
+    const: amlogic,g12a-mipi-dphy-analog
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    phy at 0 {
+          compatible = "amlogic,g12a-mipi-dphy-analog";
+          reg = <0x0 0xc>;
+          #phy-cells = <0>;
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan  7 07:05:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri,  7 Jan 2022 16:05:10 +0100
Subject: [PATCH v3 0/2] phy: amlogic: Add support for the G12A Analog MIPI
 D-PHY
Message-ID: <20220107150512.614423-1-narmstrong@baylibre.com>

The Amlogic G12A SoCs embeds an Analog MIPI D-PHY to communicate with DSI
panels, this adds the bindings.
    
This Analog D-PHY works with a separate Digital MIPI D-PHY.

This serie adds the Bindings and the PHY driver.

Changes from v2 at [2]:
- Bindings example fix

Changes from v1 at [1]:
- Bindings fixes

[1] https://lore.kernel.org/r/20201123145157.300456-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20210210080736.771803-1-narmstrong at baylibre.com

Neil Armstrong (2):
  dt-bindings: phy: add Amlogic G12A Analog MIPI D-PHY bindings
  phy: amlogic: Add G12A Analog MIPI D-PHY driver

 .../phy/amlogic,g12a-mipi-dphy-analog.yaml    |  35 ++++
 drivers/phy/amlogic/Kconfig                   |  12 ++
 drivers/phy/amlogic/Makefile                  |   1 +
 .../amlogic/phy-meson-g12a-mipi-dphy-analog.c | 177 ++++++++++++++++++
 4 files changed, 225 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/amlogic,g12a-mipi-dphy-analog.yaml
 create mode 100644 drivers/phy/amlogic/phy-meson-g12a-mipi-dphy-analog.c

-- 
2.25.1



From james.clark at arm.com  Fri Jan  7 07:10:45 2022
From: james.clark at arm.com (James Clark)
Date: Fri, 7 Jan 2022 15:10:45 +0000
Subject: [PATCH 2/3] coresight: Fail to open with return stacks if they
 are unavailable
In-Reply-To: <b61ef2e3-e573-4867-af5d-fd5fabece4b1@arm.com>
References: <20211208160907.749482-1-james.clark@arm.com>
 <20211208160907.749482-2-james.clark@arm.com>
 <b52ef2f3-9e30-59a6-2aea-e46c93915868@arm.com>
 <b61ef2e3-e573-4867-af5d-fd5fabece4b1@arm.com>
Message-ID: <70b562dc-adcd-da34-3811-ff872bc7cab8@arm.com>



On 09/12/2021 11:13, James Clark wrote:
> 
> 
> On 09/12/2021 11:00, Suzuki K Poulose wrote:
>> On 08/12/2021 16:09, James Clark wrote:
>>> Maintain consistency with the other options by failing to open when they
>>> aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
>>> added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
>>> requested but not supported by hardware.
>>>
>>> The consequence of not doing this is that the user may not be
>>> aware that they are not enabling the feature as it is silently disabled.
>>>
>>> Signed-off-by: James Clark <james.clark at arm.com>
>>> ---
>>> ? drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
>>> ? 1 file changed, 9 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> index d2bafb50c66a..0a9bb943a5e5 100644
>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>> @@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>>> ????? }
>>> ? ????? /* return stack - enable if selected and supported */
>>> -??? if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
>>> -??????? /* bit[12], Return stack enable bit */
>>> -??????? config->cfg |= BIT(12);
>>> -
>>> +??? if (attr->config & BIT(ETM_OPT_RETSTK)) {
>>> +??????? if (!drvdata->retstack) {
>>> +??????????? ret = -EINVAL;
>>> +??????????? goto out;
>>> +??????? } else {
>>> +??????????? /* bit[12], Return stack enable bit */
>>> +??????????? config->cfg |= BIT(12);
>>> +??????? }
>>
>> nit: While at this, please could you change the hard coded value
>> to ETM4_CFG_BIT_RETSTK ?
>>
> I started changing them all because I had trouble searching for bits by name but then
> I thought it would snowball into a bigger change so I undid it.
> 
> I think I'll just go and do it now if it's an issue here.

Hi Suzuki,

I started on this and I think the only worthwhile change is to make them all consistent
with sysreg.h. As in have xxx_SHIFT and xxx_MASK style definitions like:

  #define TRCCONFIGR_INSTP0_SHIFT		1
  #define TRCCONFIGR_INSTPO_MASK		GENMASK(1,0)

This has been done for SPE and some of the new ETM stuff. If that sounds right to you
I will go and do it as a followup patch to this one. It is quite a bit change so I can
see maybe we don't want to do it? (Personally I would vote to do it)

James

> 
>> Otherwise, looks good to me
>>
>> Suzuki


From robh at kernel.org  Fri Jan  7 07:20:05 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 7 Jan 2022 09:20:05 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <cf75f1ee-8424-b6b2-f873-beea4676a29f@ti.com>
References: <20220107031905.2406176-1-robh@kernel.org>
 <cf75f1ee-8424-b6b2-f873-beea4676a29f@ti.com>
Message-ID: <CAL_JsqL3PGqmzA0wW37G7TXhbRVgByznk==Q8GhA0_OFBKAycQ@mail.gmail.com>

On Fri, Jan 7, 2022 at 8:27 AM Suman Anna <s-anna at ti.com> wrote:
>
> Hi Rob,
>
> On 1/6/22 9:19 PM, Rob Herring wrote:
> > 'interrupt-parent' is never required as it can be in a parent node or a
> > parent node itself can be an interrupt provider. Where exactly it lives is
> > outside the scope of a binding schema.
> >
> > Signed-off-by: Rob Herring <robh at kernel.org>
> > ---
> >  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
> >  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
> >  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
> >  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
> >  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
> >  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
> >  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
> >  7 files changed, 15 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> > index 9ad470e01953..b085450b527f 100644
> > --- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> > +++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> > @@ -43,7 +43,6 @@ required:
> >    - gpio-controller
> >    - interrupt-controller
> >    - "#interrupt-cells"
> > -  - interrupt-parent
> >
> >  additionalProperties: false
> >
> > diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> > index e864d798168d..d433e496ec6e 100644
> > --- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> > +++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> > @@ -175,15 +175,6 @@ required:
> >    - ti,mbox-num-fifos
> >
> >  allOf:
> > -  - if:
> > -      properties:
> > -        compatible:
> > -          enum:
> > -            - ti,am654-mailbox
> > -    then:
> > -      required:
> > -        - interrupt-parent
> > -
>
> There are multiple interrupt controllers on TI K3 devices, and we need this
> property to be defined _specifically_ to point to the relevant interrupt router
> parent node.
>
> While what you state in general is true, I cannot have a node not define this on
> K3 devices, and end up using the wrong interrupt parent (GIC
> interrupt-controller). That's why the conditional compatible check.

But you could.

The parent node can have a default interrupt-parent and child nodes
can override that. It doesn't matter which one is the default though
typically you would want the one used the most to be the default.
Looking at your dts files, it looks like you all did the opposite. The
only way that wouldn't work is if the parent node is if the parent
node has its own 'interrupts' or you are just abusing
'interrupt-parent' where the standard parsing doesn't work.

You are also free to use 'interrupts-extended' anywhere 'interrupts'
is used and then interrupt-parent being present is an error. How you
structure all this is outside the scope of binding schemas which only
need to define how many interrupts and what are they. Ensuring parents
and cell sizes are correct is mostly done by dtc.

Rob


From quic_schowdhu at quicinc.com  Fri Jan  7 07:27:50 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Fri, 7 Jan 2022 20:57:50 +0530
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data Capture
 and Compare unit(DCC)
In-Reply-To: <YdeC456prDBG7tBA@ripper>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <YbzvD+FFHuDWzCtZ@yoga> <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
 <YdeC456prDBG7tBA@ripper>
Message-ID: <77a2ef02-384d-ce67-ae84-02c385eccd60@quicinc.com>


On 1/7/2022 5:31 AM, Bjorn Andersson wrote:
> On Wed 05 Jan 23:57 PST 2022, Souradeep Chowdhury wrote:
>
>> On 12/18/2021 1:41 AM, Bjorn Andersson wrote:
>>> On Tue 10 Aug 12:54 CDT 2021, Souradeep Chowdhury wrote:
>>>
>>>> The DCC is a DMA Engine designed to capture and store data
>>>> during system crash or software triggers.The DCC operates
>>> Please include a space after '.'
>> Ack
>>>> based on user inputs via the sysfs interface.The user gives
>>>> addresses as inputs and these addresses are stored in the
>>>> form of linkedlists.In case of a system crash or a manual
>>> I think the user configures the DCC hardware with "a sequence of
>>> operations to be performed as DCC is triggered".
>>>
>>> Afaict the sequence is stored just as a sequence of operations in SRAM,
>>> there's no linked list involved - except in your intermediate
>>> implementation.
>> The user just enters the addresses as input whereas the sequence of
>> operations takes
>>
>> place as per configuration code inside the driver. The end result is storage
>> of these
>>
>> addresses inside the DCC SRAM. The DCC hardware will capture the value at
>> these
>>
>> addresses on a crash or manual trigger by the user.
>>
>>>> software trigger by the user through the sysfs interface,
>>>> the dcc captures and stores the values at these addresses.
>>>> This patch contains the driver which has all the methods
>>>> pertaining to the sysfs interface, auxiliary functions to
>>>> support all the four fundamental operations of dcc namely
>>>> read, write, first read then write and loop.The probe method
>>> "first read then write" is called "read/modify/write"
>> Ack
>>>> here instantiates all the resources necessary for dcc to
>>>> operate mainly the dedicated dcc sram where it stores the
>>>> values.The DCC driver can be used for debugging purposes
>>>> without going for a reboot since it can perform manual
>>>> triggers.
>>>>
>>>> Also added the documentation for sysfs entries
>>>> and explained the functionalities of each sysfs file that
>>>> has been created for dcc.
>>>>
>>>> The following is the justification of using sysfs interface
>>>> over the other alternatives like ioctls
>>>>
>>>> i) As can be seen from the sysfs attribute descriptions,
>>>> most of it does basic hardware manipulations like dcc_enable,
>>>> dcc_disable, config reset etc. As a result sysfs is preferred
>>>> over ioctl as we just need to enter a 0 or 1.
>>>>
>>> As I mentioned in our chat, using sysfs allows us to operate the
>>> interface using the shell without additional tools.
>>>
>>> But I don't think that it's easy to implement enable/disable/reset using
>>> sysfs is a strong argument. The difficult part of this ABI is the
>>> operations to manipulate the sequence of operations, so that's what you
>>> need to have a solid plan for.
>> The sysfs interface is being used to get the addresses values entered by the
>> user
>>
>> and to also go for manual triggers. The sequence of operations are kept as a
>> part of
>>
>> fixed driver code which is called when the user enters the data.
>>
> But does the hardware really just operate on "addresses values entered
> by the user". Given the various types of operations: read, write,
> read-modify-write and loop I get the feeling that the hardware
> "executes" a series of actions.
>
> I'm don't think the proposed sysfs interface best exposes this to the
> user and I don't think that "it's easy to implement enable/disable
> attributes in sysfs" is reason enough to go with that approach.

So the sysfs interface here has been introduced keeping in mind how the 
DCC_SRAM needs to be

programmed for the dcc hardware to work. We are maintaining a list here 
based on the address

entry. The 4 cases for the type of addresses are as follows-:

i) READ ADDRESSES

user enters something like "echo <addr> <len> > config"

DCC driver stores the <addr> along with the length information in the 
DCC_SRAM.

ii) WRITE ADDRESSES

User enters something like "echo <addr> <write_val> 1? > config_write"

DCC stores the <addr> first in sram followed by <write_val>.

For the above 2 type of addresses there won't be much difference if we 
use IOCTL.

However, for the next 2 type of addresses

iii) LOOP ADDRESSES

user has to enter something like below

echo 9 > loop
echo 0x01741010 1 > config
echo 0x01741014 1 > config
echo 1 > loop

The DCC SRAM will be programmed precisely like the above entries where 
the loop count will be stored first

followed by loop addresses and then again a "echo 1 > loop " marks the 
end of loop addresses.

in DCC_SRAM.

iv) READ_WRITE ADDRESSES

User has to enter something like below

echo <addr> > /sys/bus/platform/devices/../config

echo <mask> <val> > /sys/bus/platform/devices/../rd_mod_wr

Here first the? <addr> is stored in DCC_SRAM followed by <mask> and then 
the <val>.

The above representation to the user space is consistent with the dcc 
hardware in terms of

the way the sequence of values are programmed in the DCC SRAM . Moving 
to IOCTL will

only change the way the READ_WRITE address is represented although user 
will have to enter

multiple parameters at once, let me know if we still need to go for the 
same.


>>>> ii) Existing similar debug hardwares are there for which drivers
>>>> have been written using sysfs interface.One such example is the
>>>> coresight-etm-trace driver.
>>> Afaict the etm interface has operations to enable and disable, I don't
>>> see anything that's similar to the interface for defining the sequence
>>> of operations.
>> Here I have just drawn analogy with an existing sysfs interface. The
>> argument for
>>
>> using sysfs instead of other interfaces can be as folllows
>>
>> 1)
>>
>> Debugfs interface is used by drivers to expose debugging information additional to
>> the function they do. But the sole usage of this driver depends on the configuration
>> exported through the attributes and therefore it is an ABI as suggested by Mani.
>>
>> 2)
>>
>> Debugfs is disabled in production so this will not give the user facility to use DCC.
>>
>> 3)
>>
>> As you mentioned sysfs can be used with the shell without any additional tools.
>>
>> 4)
>>
>> Alternatives like NETLINK has also been suggested although in this case by using
>> NETLINK we won't be able to exploit most it's features like duplex connection,
>> asychrony and bulk data transfers. We are not showing any stats here to the user
>> as such and also sysfs is considered to be a bit more reliable.
>>
> I'm not sure why netlink would preferred for this; to me sysfs is much
> preferred as it allows us to use DCC from scripts etc without having to
> bundle additional binaries. If we can't express the configuration
> appropriately in a sysfs (debugfs would be the same) interface, I think
> an ioctl interface on /dev/dcc would be a reasonable alternative.
>
>> Please let me your thoughts regarding this.
>>
>>>> A closer analog can also be the watchdog
>>>> subsystems though it is ioctls based.
>>>>
>>> I don't think this adds value to the argument for using a sysfs based
>>> interface.
>> Ack
>>>> Signed-off-by: Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>> ---
>>>>    Documentation/ABI/testing/sysfs-driver-dcc |  114 ++
>>>>    drivers/soc/qcom/Kconfig                   |    8 +
>>>>    drivers/soc/qcom/Makefile                  |    1 +
>>>>    drivers/soc/qcom/dcc.c                     | 1549 ++++++++++++++++++++++++++++
>>>>    4 files changed, 1672 insertions(+)
>>>>    create mode 100644 Documentation/ABI/testing/sysfs-driver-dcc
>>>>    create mode 100644 drivers/soc/qcom/dcc.c
>>>>
>>>> diff --git a/Documentation/ABI/testing/sysfs-driver-dcc b/Documentation/ABI/testing/sysfs-driver-dcc
> [..]
>>>> +What:           /sys/bus/platform/devices/.../rd_mod_wr
>>>> +Date:           March 2021
>>>> +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>> +Description:
>>>> +		This file is used to read the value of the register
>>>> +		and then write the value given as an argument to the
>>>> +		register address in config.
>>> It's not clear from this description how to use this operation. E.g. is
>>> it appended to the same list of operations? When will this operation
>>> happen?
>>>
>>> Looking at the implementation I believe that "config", "config_write",
>>> "loop" and "rd_mod_wr" all appends operations to the same list.
>>>
>>> I think it would be much better to configure this with a single file
>>> that can either be written to '>' or appended to '>>' and you would feed
>>> it a sequence of the operations to be performed.
>>>
>>> That said, I'm afraid that might no longer be a sysfs attribute.
>>>
>>> Something like:
>>>     # echo 'r 0x80000010 0x10' > config
>>>     # echo 'w 0x80000000 0xff' >> config
>>>     # echo 'rmw 0x80000000 0xf 0xa' >> config
>>>     # echo 'l 0x80000010 10' >> config
>>>
>>> and:
>>>     # cat config
>>>     r 0x80000010 0x10
>>>     w 0x80000000 0xff
>>>     rmw 0x80000000 0xf 0xa
>>>     l 0x80000010 10
>>>
>>> (Or read/write/modify/loop as keywords...)
>>>
>>>
>>> reset could be done by just: echo '' > config
>>>
>>> This would make it quite similar to several of the files in the tracing
>>> framework.
>> Currently this is being implemented as follows
>>
>> Step 1
>>
>> echo 0x80000000 > /sys/bus/platform/devices/../config
>>
>> Step 2
>>
>> echo 0xF 0xA > /sys/bus/platform/devices/../rd_mod_wr
>>
>> So the particular address is tagged as rd_mod_wr type and therefore
>>
>> while the value at the address 0x80000000 is captured, 0xA is also
>>
>> written to it's last 4 bits. Will be updating this in the documentation
>>
>> along with details for loop and config_write as well.
>>
> But can you help me confirm what is actually written in SRAM when you
> run these two steps?
Explained as above.
>
>>>> +		The address argument should
>>>> +		be given of the form <mask> <value>.For debugging
>>>> +		purposes sometimes we need to first read from a register
>>>> +		and then set some values to the register.
>>>> +		Example:
>>>> +		echo 0x80000000 > /sys/bus/platform/devices/.../config
>>>> +		(Set the address in config file)
>>>> +		echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
>>>> +		(Provide the mask and the value to write)
>>>> +
>>>> +What:           /sys/bus/platform/devices/.../ready
>>>> +Date:           March 2021
>>>> +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>> +Description:
>>>> +		This file is used to check the status of the dcc
>>>> +		hardware if it's ready to take the inputs.
>>> When will this read "false"?
>> This will give false if the DCC hardware is not in an operational state.
>>
>> Will update accordingly.
>>
>>>> +		Example:
>>>> +		cat /sys/bus/platform/devices/.../ready
>>>> +
>>>> +What:		/sys/bus/platform/devices/.../curr_list
>>>> +Date:		February 2021
>>>> +Contact:	Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>> +Description:
>>>> +		This attribute is used to enter the linklist to be
>>> I think it would be more appropriate to use the verb "select" here and
>>> afaict it's a "list" as the "linked" part only relates to your
>>> implementation).
>>>
>>> But that said, I don't like this ABI. I think it would be cleaner if you
>>> had specific attributes for each of the lists. That way it would be
>>> clear that you have N lists and they can be configured and enabled
>>> independently, and there's no possible race conditions.
>> So we do have attributes for independent lists in this case. The user is
>> given the option
>>
>> to configure multiple lists at one go. For example I can do
>>
>> echo 1 > curr_list
>>
>> echo 0x18000010 1 > config
>> echo 0x18000024 1 > config
>>
>> Then followed by
>>
>> echo 2 > curr_list
>>
>> echo 0x18010038 6 > config
>> echo 0x18020010 1 > config
>>
>> We will get the output in terms of two separate list of registers values.
>>
> I understand that this will define two lists of operations and that we
> will get 2 and 7 registers dumped, respectively. Perhaps unlikely, but
> what happens if you try to do these two operations concurrently?
>
>
> What I'm suggesting here is that if you have N contexts, you should have
> N interfaces to modify each one independently - simply because that's
> generally a very good thing.

Not sure if there will ever be a concurrency issue in this case. This is 
just about programming the DCC SRAM

from the user entries sequentially. The curr_list number is nothing but 
some register writes done in the dcc

so that the dcc_hardware knows the beginning and end of a particular 
list and can dump the captured data

according. Even if an user chooses multiple curr_list entries, it will 
be programmed sequentially in DCC_SRAM.

>
>>>> +		used while appending addresses.The range of values
>>>> +		for this can be from 0 to 3.This feature is given in
>>>> +		order to use certain linkedlist for certain debugging
>>>> +		purposes.
>>>> +		Example:
>>>> +		echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
>>>> +
> [..]
>>>> diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
> [..]
>>>> +static int dcc_valid_list(struct dcc_drvdata *drvdata, int curr_list)
>>>> +{
>>>> +	u32 lock_reg;
>>>> +
>>>> +	if (list_empty(&drvdata->cfg_head[curr_list]))
>>>> +		return -EINVAL;
>>>> +
>>>> +	if (drvdata->enable[curr_list]) {
>>>> +		dev_err(drvdata->dev, "List %d is already enabled\n",
>>>> +				curr_list);
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	lock_reg = dcc_readl(drvdata, DCC_LL_LOCK(curr_list));
>>> Under what circumstances would this differ from
>>> drvdata->enable[curr_list}?
>> So locking the list is done on the register as soon as the user enters the
>> curr_list entry whereas
>>
>> the list is marked as enabled only on successfully programming the SRAM
>> contents. So a list can
>>
>> be locked and not marked enabled in certain cases. The first is used so that
>> the user doesn't
>>
>> mistakenly enter the same curr_list twice whereas the later is used to mark
>> that the list has been
>>
>> successfully configured.
>>
> So this will mark the list as "actively in use, but disabled"? Why is
> this kept in the hardware? When is this not the same as the list of
> operations for that list being non-empty?

So this is in accordance with the dcc hardware configuration 
requirement. We have to lock the list first and

after that proceed with the subsequent writes . As per the driver code below

 ?????????????? /* 1. Take ownership of the list */
 ??????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));

 ??????????????? /* 2. Program linked-list in the SRAM */
 ??????????????? ram_cfg_base = drvdata->ram_cfg;
 ??????????????? ret = __dcc_ll_cfg(drvdata, list);
 ??????????????? if (ret) {
 ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
 ??????????????????????? goto err;
 ??????????????? }

 ??????????????? /* 3. program DCC_RAM_CFG reg */
 ??????????????? dcc_writel(drvdata, ram_cfg_base +
 ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
 ??????????????? dcc_writel(drvdata, drvdata->ram_start +
 ??????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
 ??????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));

 ??????????????? /* 4. Clears interrupt status register */
 ??????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
 ??????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
 ??????????????????????????????????????? DCC_LL_INT_STATUS(list));

In case of any errors we again unlock the list before exiting.

>
>>>> +	if (lock_reg & 0x1) {
>>>> +		dev_err(drvdata->dev, "List %d is already locked\n",
>>>> +				curr_list);
>>>> +		return -EINVAL;
>>>> +	}
>>>> +
>>>> +	dev_err(drvdata->dev, "DCC list passed %d\n", curr_list);
>>> This is noise, please drop it.
>> Ack
>>>> +	return 0;
>>>> +}
>>>> +
>>>> +static bool is_dcc_enabled(struct dcc_drvdata *drvdata)
>>>> +{
>>>> +	bool dcc_enable = false;
>>>> +	int list;
>>>> +
>>>> +	for (list = 0; list < DCC_MAX_LINK_LIST; list++) {
>>>> +		if (drvdata->enable[list]) {
>>> 			return true;
>>>
>>>> +			dcc_enable = true;
>>>> +			break;
>>>> +		}
>>>> +	}
>>>> +
>>> 	return false;
>>>
>>>> +	return dcc_enable;
>>>> +}
>>>> +
>>>> +static int dcc_enable(struct dcc_drvdata *drvdata)
>>>> +{
>>>> +	int ret = 0;
>>>> +	int list;
>>>> +	u32 ram_cfg_base;
>>>> +
>>>> +	mutex_lock(&drvdata->mutex);
>>>> +
>>>> +	if (!is_dcc_enabled(drvdata)) {
>>>> +		memset_io(drvdata->ram_base,
>>>> +			0xDE, drvdata->ram_size);
>>> No need to wrap this line, and please use lowercase hex digits.
>> Ack
>>>> +	}
>>>> +
>>>> +	for (list = 0; list < drvdata->nr_link_list; list++) {
>>>> +
>>> Please drop the empty line.
>> Ack
>>>> +		if (dcc_valid_list(drvdata, list))
>>>> +			continue;
>>>> +
>>>> +		/* 1. Take ownership of the list */
>>>> +		dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
>>> Can we have a define for BIT(0)? Is it really about ownership or just
>>> that we "enable" it?
>>>
>>> If ownership, who's the other contenders for the ownership?
>> This is done to mark that the user has already entered the curr_list and
>> therefore
>>
>> cannot enter it again.
>>
> What does "entered" mean here? Do you mean that the list of operations
> that the driver kept track of has been flushed out to SRAM and we're not
> not allowed to modify it?
>
> What does this actually mean? Why is this done in the hardware and not
> simply with a bool in the driver?
That is correct. As explained above this is as per dcc hardware 
configuration requirement.
>
>>>> +
>>>> +		/* 2. Program linked-list in the SRAM */
>>>> +		ram_cfg_base = drvdata->ram_cfg;
>>>> +		ret = __dcc_ll_cfg(drvdata, list);
>>>> +		if (ret) {
>>>> +			dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
>>>> +			goto err;
>>>> +		}
>>>> +
>>>> +		/* 3. program DCC_RAM_CFG reg */
>>>> +		dcc_writel(drvdata, ram_cfg_base +
>>>> +			drvdata->ram_offset/4, DCC_LL_BASE(list));
>>>> +		dcc_writel(drvdata, drvdata->ram_start +
>>>> +			drvdata->ram_offset/4, DCC_FD_BASE(list));
>>>> +		dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
>>>> +
>>>> +		/* 4. Clears interrupt status register */
>>>> +		dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
>>>> +		dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
>>>> +					DCC_LL_INT_STATUS(list));
>>>> +
>>>> +		drvdata->enable[list] = true;
>>>> +
>>>> +		/* 5. Configure trigger */
>>>> +		dcc_writel(drvdata, BIT(9), DCC_LL_CFG(list));
>>>> +	}
>>>> +
>>>> +err:
>>>> +	mutex_unlock(&drvdata->mutex);
>>>> +	return ret;
>>>> +}
>>>> +
>>>> +static void dcc_disable(struct dcc_drvdata *drvdata)
>>>> +{
>>>> +	int curr_list;
>>>> +
>>>> +	mutex_lock(&drvdata->mutex);
>>>> +
>>>> +	for (curr_list = 0; curr_list < drvdata->nr_link_list; curr_list++) {
>>>> +		if (!drvdata->enable[curr_list])
>>>> +			continue;
>>>> +		dcc_writel(drvdata, 0, DCC_LL_CFG(curr_list));
>>>> +		dcc_writel(drvdata, 0, DCC_LL_BASE(curr_list));
>>>> +		dcc_writel(drvdata, 0, DCC_FD_BASE(curr_list));
>>>> +		dcc_writel(drvdata, 0, DCC_LL_LOCK(curr_list));
>>>> +		drvdata->enable[curr_list] = false;
>>>> +	}
>>>> +	memset_io(drvdata->ram_base, 0, drvdata->ram_size);
>>> Is there any reason why DCC is filled with 0xde during initialization
>>> but 0 when disabled?
>> Yes this poison value is required to distinguish between bus hang on
>> register accesses
>>
>> and a zero value for the registers. In case of the former dcc returns zero
>> value on registers
>>
>> which causes ambiguity.
>>
> That explains why you poison ram_base with 0xde during dcc_enable(). But
> why do you overwrite it with 0s in dcc_disable()?
>
> You should be able to either just leave it as it will be poisoned again
> next time dcc_enable() is called, or if you want to ensure things are
> cleared you should be able to poison it with the same poison - to
> distinguish it from a bunch of read 0s?
Ack
>
> Regards,
> Bjorn


From quic_schowdhu at quicinc.com  Fri Jan  7 07:43:16 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Fri, 7 Jan 2022 21:13:16 +0530
Subject: [PATCH V6 0/7] Add driver support for Data Capture and Compare
 Engine(DCC) for SM8150,SC7280,SC7180,SDM845
In-Reply-To: <YdeDtlmPRQx3FU9i@ripper>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <396edd95-4f38-6830-99da-11e73d62a0cf@linaro.org>
 <705c280b-bced-476d-8e21-1a5afbf3d2f3@quicinc.com> <YdeDtlmPRQx3FU9i@ripper>
Message-ID: <84d36c7f-d75e-61f9-7670-c651cc50d083@quicinc.com>


On 1/7/2022 5:35 AM, Bjorn Andersson wrote:
> On Thu 06 Jan 07:20 PST 2022, Souradeep Chowdhury wrote:
>
>> On 12/16/2021 9:18 PM, Thara Gopinath wrote:
>>>
>>> On 8/10/21 1:54 PM, Souradeep Chowdhury wrote:
>>>> DCC(Data Capture and Compare) is a DMA engine designed for debugging
>>>> purposes.In case of a system
>>>> crash or manual software triggers by the user the DCC hardware
>>>> stores the value at the register
>>>> addresses which can be used for debugging purposes.The DCC driver
>>>> provides the user with sysfs
>>>> interface to configure the register addresses.The options that the
>>>> DCC hardware provides include
>>>> reading from registers,writing to registers,first reading and then
>>>> writing to registers and looping
>>>> through the values of the same register.
>>>>
>>>> In certain cases a register write needs to be executed for accessing
>>>> the rest of the registers,
>>>> also the user might want to record the changing values of a register
>>>> with time for which he has the
>>>> option to use the loop feature.
>>> Hello Souradeep,
>>>
>>> First of all, I think this is very a useful feature to have. I have some
>>> generic design related queries/comments on driver and the interface
>>> exposed to the user space. Also, I do not understand the h/w well here,
>>> so feel free to correct me if I am wrong.
>>>
>>> 1. Linked list looks like a very internal feature to the h/w. It really
>>> is not an info that user should be aware of. I tried reading the code a
>>> bit. IUC, every time a s/w trigger is issued the configs in all the
>>> enabled linked lists are executed. The final ram dump that you get from
>>> /dev/dcc_sram is a dump of contents from all the enabled list? Is this
>>> understanding correct ? And we are talking of at-most 4 linked list?
>>> If yes, I think it might be better to have a folder per linked list with
>>> config, config_write etc. Also if possible it will be better to dump the
>>> results to a file in the specific folder instead of reading from
>>> /dev/dcc_sram.
>>> If no, there is no real need for user to know the linked list, right?
>>> Choosing of linked list can be done by kernel driver in this case with
>>> no input needed from user.
>>>
>>> 2. Now to the sysfs interface itself, I know lot of thought has gone
>>> into sysfs vs debugfs considerations. But, have you considered using
>>> netlink interface instead of sysfs. Netlink interface is used for
>>> asynchronous communication between kernel and user space. In case of
>>> DCC, the communication appears to be asynchronous, where in user asks
>>> the kernel to capture some info and kernel can indicate back to user
>>> when the info is captured. Also the entire mess surrounding echoing addr
>>> / value / offset repeatedly into a sysfs entry can be avoided using
>>> netlink interface.
>>>
>> Hello Thara,
>>
>> Thanks for your review comments. Following are some points from my end
>>
>>
>> 1) Each linked list represent a particular block of memory in DCC_SRAM which
>> is preserved for that particular list. That is why offset calculation is
>> done on the driver based on the linked list chosen by the user.
>>
>>  ??? This choice needs to be made by the user since the number for the linked
>> list chosen is specific to the registers used to debug a particular
>> component.? Also we are giving the user flexibility to configure multiple
>>
>>  ??? linked lists at one go so that even if we don't have a separate folder
>> for it , the dumps are collected as a separate list of registers. Also there
>> are certain curr_list values which may be supported by the dcc
>>
>>  ??? hardware but may not be accessible to the user and so the choice cannot
>> be made arbitrarily from the driver.
>>
> But in the end, as you write out the SRAM content, is there really any
> linked lists? Afaict it's just a sequence of operations/commands. The
> linked list part seems to be your data structure of choice to keep track
> of these operations in the driver before flushing them out.

That is correct, the linked list defined in the driver is for storing 
the addresses sequentially in DCC_SRAM and is just an internal

data structure of the driver. However, there is also a "list" from DCC 
hardware perspective. The following driver code shows how

a list is initiated with the beginning and end sram offset so that DCC 
hardware can treat it as a separate list of addresses and dump

the values separately.

 ????????????? /* 1. Take ownership of the list */
 ??????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));

 ??????????????? /* 2. Program linked-list in the SRAM */
 ??????????????? ram_cfg_base = drvdata->ram_cfg;
 ??????????????? ret = __dcc_ll_cfg(drvdata, list);
 ??????????????? if (ret) {
 ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
 ??????????????????????? goto err;
 ??????????????? }

 ??????????????? /* 3. program DCC_RAM_CFG reg */
 ??????????????? dcc_writel(drvdata, ram_cfg_base +
 ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
 ??????????????? dcc_writel(drvdata, drvdata->ram_start +
 ??????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
 ??????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));

 ??????????????? /* 4. Clears interrupt status register */
 ??????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
 ??????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
 ??????????????????????????????????????? DCC_LL_INT_STATUS(list));

 ??????????????? drvdata->enable[list] = true;

So when user enters multiple lists, the DCC hardware will process it as 
separate group of register values.

>
> Regards,
> Bjorn
>
>> 2) From opensource, I can see that Netlink has been used in most of the
>> cases where we need to notify stats to the user by taking the advantage of
>> asynchronous communication. In this case, that requirement is not
>>
>>  ? ? there since it is mostly one way communication from user to kernel. Also
>> since this is used for debugging purposes perhaps sysfs adds more
>> reliability than Netlink. In case of Netlink we have the additional
>>
>>  ???? overhead of dealing with socket calls. Let me know otherwise.
>>
>>
>> Thanks,
>>
>> Souradeep
>>
>>
>>
>>
>>


From pbonzini at redhat.com  Fri Jan  7 07:43:19 2022
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Fri, 7 Jan 2022 16:43:19 +0100
Subject: [GIT PULL] KVM/arm64 updates for 5.17
In-Reply-To: <20220107114548.4069893-1-maz@kernel.org>
References: <20220107114548.4069893-1-maz@kernel.org>
Message-ID: <896a998b-17b6-7f50-8f23-b14ff8f44333@redhat.com>

On 1/7/22 12:45, Marc Zyngier wrote:
> Hi Paolo,
> 
> Here's the bulk of the KVM/arm64 updates for 5.17. No real new feature
> this time around, but a bunch of changes that will make the merging of
> upcoming features easier (pKVM is reaching a point where it will
> finally be usable, and NV isn't too far off... fingers crossed). This
> comes with the usual set of bug fixes and cleanups all over the shop.
> 
> We also have a sizeable chunks of selftest updates which probably
> account for half of the changes.

Pulled, thanks!

Paolo



From benjamin.gaignard at collabora.com  Fri Jan  7 07:54:53 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Fri,  7 Jan 2022 16:54:53 +0100
Subject: [PATCH v5 0/2] media: HEVC: RPS clean up
Message-ID: <20220107155455.604536-1-benjamin.gaignard@collabora.com>

This series aims to clean up Reference Picture Set usage and flags.

Long term flag was named with RPS prefix while it is not used for RPS
but for mark long term references in DBP. Remane it and remove the two
other useless RPS flags.

Clarify documentation about RPS lists content and make sure that Hantro
driver use them correctly (i.e without look up in DBP).

version 5:
- rework commit message as suggested by Ezequiel
- improve V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE documentation
  with reference to HEVC ITU spec.
- add review-by tags from Jernej and Ezequiel

version 4:
- check flags with & and not ==
- remove the 2 last patches which becomes useless since VPU ctrl-blk
  driver introduction.

version 3:
- rebased on top of v5.16-rc1

version 2:
- change DPB field name from rps to flags


Benjamin Gaignard (2):
  media: hevc: Remove RPS named flags
  media: hevc: Embedded indexes in RPS

 .../media/v4l/ext-ctrls-codec.rst             | 16 +++++------
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 27 +++++--------------
 .../staging/media/sunxi/cedrus/cedrus_h265.c  |  2 +-
 include/media/hevc-ctrls.h                    |  6 ++---
 4 files changed, 18 insertions(+), 33 deletions(-)

-- 
2.30.2



From benjamin.gaignard at collabora.com  Fri Jan  7 07:54:54 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Fri,  7 Jan 2022 16:54:54 +0100
Subject: [PATCH v5 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <20220107155455.604536-1-benjamin.gaignard@collabora.com>
References: <20220107155455.604536-1-benjamin.gaignard@collabora.com>
Message-ID: <20220107155455.604536-2-benjamin.gaignard@collabora.com>

Marking a picture as long-term reference is valid for DPB but not for RPS.
Change flag name to match with it description in HEVC spec chapiter
"8.3.2 Decoding process for reference picture set".

PocStCurrBefore, PocStCurrAfter, PocLtCurr lists could be built by the kernel
from the DPB entries struct v4l2_hevc_dpb_entry, using the information in the
rps field. This way RPS flags becomes useless and are removed.

This patch break staging HEVC API because it introduce a new flag,
change a field name in v4l2_hevc_dpb_entry structure and remove
V4L2_HEVC_DPB_ENTRY_RPS_* flags.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
---
version 5:
- rework commit message as suggested by Ezequiel
- improve V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE documentation
  with reference to HEVC ITU spec.
- add review-by tags from Jernej and Ezequiel

version 4:
- check flags with & and not ==

 .../userspace-api/media/v4l/ext-ctrls-codec.rst        | 10 +++++-----
 drivers/staging/media/hantro/hantro_g2_hevc_dec.c      |  2 +-
 drivers/staging/media/sunxi/cedrus/cedrus_h265.c       |  2 +-
 include/media/hevc-ctrls.h                             |  6 ++----
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index e141f0e4eec9..5d1fc2d33dc7 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3166,11 +3166,11 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
 	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
 	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
     * - __u8
-      - ``rps``
-      - The reference set for the reference frame
-        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
-        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
-        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+      - ``flags``
+      - Long term flag for the reference frame
+        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE). The flag is set like
+        describe in ITU HEVC specification chapiter "8.3.2 Decoding
+        process for reference picture set".
     * - __u8
       - ``field_pic``
       - Whether the reference is a field picture or a frame.
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 99d8ea7543da..14e0e6414100 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -433,7 +433,7 @@ static int set_ref(struct hantro_ctx *ctx)
 		chroma_addr = luma_addr + cr_offset;
 		mv_addr = luma_addr + mv_offset;
 
-		if (dpb[i].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[i].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
 
 		hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr);
diff --git a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
index 8829a7bab07e..8ab2d9c6f048 100644
--- a/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
+++ b/drivers/staging/media/sunxi/cedrus/cedrus_h265.c
@@ -169,7 +169,7 @@ static void cedrus_h265_ref_pic_list_write(struct cedrus_dev *dev,
 		unsigned int index = list[i];
 		u8 value = list[i];
 
-		if (dpb[index].rps == V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
+		if (dpb[index].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
 			value |= VE_DEC_H265_SRAM_REF_PIC_LIST_LT_REF;
 
 		/* Each SRAM word gathers up to 4 references. */
diff --git a/include/media/hevc-ctrls.h b/include/media/hevc-ctrls.h
index ef63bc205756..01ccda48d8c5 100644
--- a/include/media/hevc-ctrls.h
+++ b/include/media/hevc-ctrls.h
@@ -127,15 +127,13 @@ struct v4l2_ctrl_hevc_pps {
 	__u64	flags;
 };
 
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE	0x01
-#define V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER	0x02
-#define V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR		0x03
+#define V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE	0x01
 
 #define V4L2_HEVC_DPB_ENTRIES_NUM_MAX		16
 
 struct v4l2_hevc_dpb_entry {
 	__u64	timestamp;
-	__u8	rps;
+	__u8	flags;
 	__u8	field_pic;
 	__u16	pic_order_cnt[2];
 	__u8	padding[2];
-- 
2.30.2



From benjamin.gaignard at collabora.com  Fri Jan  7 07:54:55 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Fri,  7 Jan 2022 16:54:55 +0100
Subject: [PATCH v5 2/2] media: hevc: Embedded indexes in RPS
In-Reply-To: <20220107155455.604536-1-benjamin.gaignard@collabora.com>
References: <20220107155455.604536-1-benjamin.gaignard@collabora.com>
Message-ID: <20220107155455.604536-3-benjamin.gaignard@collabora.com>

Reference Picture Set lists provide indexes of short and long term
reference in DBP array.
Fix Hantro to not do a look up in DBP entries.
Make documentation more clear about it.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
---
version 5:
- add review-by tag from Ezequiel

 .../media/v4l/ext-ctrls-codec.rst             |  6 ++---
 .../staging/media/hantro/hantro_g2_hevc_dec.c | 25 +++++--------------
 2 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
index 5d1fc2d33dc7..f730707cd1cf 100644
--- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -3383,15 +3383,15 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
     * - __u8
       - ``poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrBefore as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term before references in DPB array.
     * - __u8
       - ``poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocStCurrAfter as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the short term after references in DPB array.
     * - __u8
       - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]``
       - PocLtCurr as described in section 8.3.2 "Decoding process for reference
-        picture set.
+        picture set": provides the index of the long term references in DPB array.
     * - __u64
       - ``flags``
       - See :ref:`Decode Parameters Flags <hevc_decode_params_flags>`
diff --git a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
index 14e0e6414100..c524af41baf5 100644
--- a/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
+++ b/drivers/staging/media/hantro/hantro_g2_hevc_dec.c
@@ -255,24 +255,11 @@ static void set_params(struct hantro_ctx *ctx)
 	hantro_reg_write(vpu, &g2_apf_threshold, 8);
 }
 
-static int find_ref_pic_index(const struct v4l2_hevc_dpb_entry *dpb, int pic_order_cnt)
-{
-	int i;
-
-	for (i = 0; i < V4L2_HEVC_DPB_ENTRIES_NUM_MAX; i++) {
-		if (dpb[i].pic_order_cnt[0] == pic_order_cnt)
-			return i;
-	}
-
-	return 0x0;
-}
-
 static void set_ref_pic_list(struct hantro_ctx *ctx)
 {
 	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
 	struct hantro_dev *vpu = ctx->dev;
 	const struct v4l2_ctrl_hevc_decode_params *decode_params = ctrls->decode_params;
-	const struct v4l2_hevc_dpb_entry *dpb = decode_params->dpb;
 	u32 list0[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	u32 list1[V4L2_HEVC_DPB_ENTRIES_NUM_MAX] = {};
 	static const struct hantro_reg ref_pic_regs0[] = {
@@ -316,11 +303,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 	/* List 0 contains: short term before, short term after and long term */
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list0[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list0[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list0); i++)
-		list0[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list0[j++] = decode_params->poc_lt_curr[i];
 
 	/* Fill the list, copying over and over */
 	i = 0;
@@ -329,11 +316,11 @@ static void set_ref_pic_list(struct hantro_ctx *ctx)
 
 	j = 0;
 	for (i = 0; i < decode_params->num_poc_st_curr_after && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_after[i]);
+		list1[j++] = decode_params->poc_st_curr_after[i];
 	for (i = 0; i < decode_params->num_poc_st_curr_before && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_st_curr_before[i]);
+		list1[j++] = decode_params->poc_st_curr_before[i];
 	for (i = 0; i < decode_params->num_poc_lt_curr && j < ARRAY_SIZE(list1); i++)
-		list1[j++] = find_ref_pic_index(dpb, decode_params->poc_lt_curr[i]);
+		list1[j++] = decode_params->poc_lt_curr[i];
 
 	i = 0;
 	while (j < ARRAY_SIZE(list1))
-- 
2.30.2



From bjorn.andersson at linaro.org  Fri Jan  7 07:57:11 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Fri, 7 Jan 2022 07:57:11 -0800
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data
 Capture and Compare unit(DCC)
In-Reply-To: <77a2ef02-384d-ce67-ae84-02c385eccd60@quicinc.com>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <YbzvD+FFHuDWzCtZ@yoga>
 <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
 <YdeC456prDBG7tBA@ripper>
 <77a2ef02-384d-ce67-ae84-02c385eccd60@quicinc.com>
Message-ID: <Ydhi1/SH5ySDLNfI@ripper>

On Fri 07 Jan 07:27 PST 2022, Souradeep Chowdhury wrote:

> 
> On 1/7/2022 5:31 AM, Bjorn Andersson wrote:
> > On Wed 05 Jan 23:57 PST 2022, Souradeep Chowdhury wrote:
> > 
> > > On 12/18/2021 1:41 AM, Bjorn Andersson wrote:
> > > > On Tue 10 Aug 12:54 CDT 2021, Souradeep Chowdhury wrote:
> > > > 
> > > > > The DCC is a DMA Engine designed to capture and store data
> > > > > during system crash or software triggers.The DCC operates
> > > > Please include a space after '.'
> > > Ack
> > > > > based on user inputs via the sysfs interface.The user gives
> > > > > addresses as inputs and these addresses are stored in the
> > > > > form of linkedlists.In case of a system crash or a manual
> > > > I think the user configures the DCC hardware with "a sequence of
> > > > operations to be performed as DCC is triggered".
> > > > 
> > > > Afaict the sequence is stored just as a sequence of operations in SRAM,
> > > > there's no linked list involved - except in your intermediate
> > > > implementation.
> > > The user just enters the addresses as input whereas the sequence of
> > > operations takes
> > > 
> > > place as per configuration code inside the driver. The end result is storage
> > > of these
> > > 
> > > addresses inside the DCC SRAM. The DCC hardware will capture the value at
> > > these
> > > 
> > > addresses on a crash or manual trigger by the user.
> > > 
> > > > > software trigger by the user through the sysfs interface,
> > > > > the dcc captures and stores the values at these addresses.
> > > > > This patch contains the driver which has all the methods
> > > > > pertaining to the sysfs interface, auxiliary functions to
> > > > > support all the four fundamental operations of dcc namely
> > > > > read, write, first read then write and loop.The probe method
> > > > "first read then write" is called "read/modify/write"
> > > Ack
> > > > > here instantiates all the resources necessary for dcc to
> > > > > operate mainly the dedicated dcc sram where it stores the
> > > > > values.The DCC driver can be used for debugging purposes
> > > > > without going for a reboot since it can perform manual
> > > > > triggers.
> > > > > 
> > > > > Also added the documentation for sysfs entries
> > > > > and explained the functionalities of each sysfs file that
> > > > > has been created for dcc.
> > > > > 
> > > > > The following is the justification of using sysfs interface
> > > > > over the other alternatives like ioctls
> > > > > 
> > > > > i) As can be seen from the sysfs attribute descriptions,
> > > > > most of it does basic hardware manipulations like dcc_enable,
> > > > > dcc_disable, config reset etc. As a result sysfs is preferred
> > > > > over ioctl as we just need to enter a 0 or 1.
> > > > > 
> > > > As I mentioned in our chat, using sysfs allows us to operate the
> > > > interface using the shell without additional tools.
> > > > 
> > > > But I don't think that it's easy to implement enable/disable/reset using
> > > > sysfs is a strong argument. The difficult part of this ABI is the
> > > > operations to manipulate the sequence of operations, so that's what you
> > > > need to have a solid plan for.
> > > The sysfs interface is being used to get the addresses values entered by the
> > > user
> > > 
> > > and to also go for manual triggers. The sequence of operations are kept as a
> > > part of
> > > 
> > > fixed driver code which is called when the user enters the data.
> > > 
> > But does the hardware really just operate on "addresses values entered
> > by the user". Given the various types of operations: read, write,
> > read-modify-write and loop I get the feeling that the hardware
> > "executes" a series of actions.
> > 
> > I'm don't think the proposed sysfs interface best exposes this to the
> > user and I don't think that "it's easy to implement enable/disable
> > attributes in sysfs" is reason enough to go with that approach.
> 
> So the sysfs interface here has been introduced keeping in mind how the
> DCC_SRAM needs to be
> 
> programmed for the dcc hardware to work. We are maintaining a list here
> based on the address
> 
> entry. The 4 cases for the type of addresses are as follows-:
> 
> i) READ ADDRESSES
> 
> user enters something like "echo <addr> <len> > config"
> 
> DCC driver stores the <addr> along with the length information in the
> DCC_SRAM.
> 
> ii) WRITE ADDRESSES
> 
> User enters something like "echo <addr> <write_val> 1? > config_write"
> 
> DCC stores the <addr> first in sram followed by <write_val>.
> 
> For the above 2 type of addresses there won't be much difference if we use
> IOCTL.
> 
> However, for the next 2 type of addresses
> 
> iii) LOOP ADDRESSES
> 
> user has to enter something like below
> 
> echo 9 > loop
> echo 0x01741010 1 > config
> echo 0x01741014 1 > config
> echo 1 > loop
> 
> The DCC SRAM will be programmed precisely like the above entries where the
> loop count will be stored first
> 
> followed by loop addresses and then again a "echo 1 > loop " marks the end
> of loop addresses.
> 
> in DCC_SRAM.
> 
> iv) READ_WRITE ADDRESSES
> 
> User has to enter something like below
> 
> echo <addr> > /sys/bus/platform/devices/../config
> 
> echo <mask> <val> > /sys/bus/platform/devices/../rd_mod_wr
> 
> Here first the? <addr> is stored in DCC_SRAM followed by <mask> and then the
> <val>.
> 
> The above representation to the user space is consistent with the dcc
> hardware in terms of
> 
> the way the sequence of values are programmed in the DCC SRAM . Moving to
> IOCTL will
> 
> only change the way the READ_WRITE address is represented although user will
> have to enter
> 
> multiple parameters at once, let me know if we still need to go for the
> same.
> 

So if I understand correctly, my concern is that if I would like to
perform something like (in pseudo code):

readl(X)
write(1, Y)
readl(Z) 5 times

then I will do this as:

echo X > config
echo Y 1 > config_write
echo 5 > loop
echo Z > config
echo 1 > loop

And the DCC driver will then write this to SRAM as something like:

read X
write Y, 1
loop 5
read Z
loop


In other words, my mind and the DCC has the same representation of this
sequence of operations, but I have to shuffle the information into 4
different sysfs attributes to get there.

The design guideline for sysfs is that each attribute should hold one
value per attribute, but in your model the attributes are tangled and
writing things to them depends on what has been written in that or other
attributes previously.

I simply don't think that's a good ABI.

[..]
> > > > > +		The address argument should
> > > > > +		be given of the form <mask> <value>.For debugging
> > > > > +		purposes sometimes we need to first read from a register
> > > > > +		and then set some values to the register.
> > > > > +		Example:
> > > > > +		echo 0x80000000 > /sys/bus/platform/devices/.../config
> > > > > +		(Set the address in config file)
> > > > > +		echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
> > > > > +		(Provide the mask and the value to write)
> > > > > +
> > > > > +What:           /sys/bus/platform/devices/.../ready
> > > > > +Date:           March 2021
> > > > > +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > > > +Description:
> > > > > +		This file is used to check the status of the dcc
> > > > > +		hardware if it's ready to take the inputs.
> > > > When will this read "false"?
> > > This will give false if the DCC hardware is not in an operational state.
> > > 
> > > Will update accordingly.
> > > 
> > > > > +		Example:
> > > > > +		cat /sys/bus/platform/devices/.../ready
> > > > > +
> > > > > +What:		/sys/bus/platform/devices/.../curr_list
> > > > > +Date:		February 2021
> > > > > +Contact:	Souradeep Chowdhury<schowdhu at codeaurora.org>
> > > > > +Description:
> > > > > +		This attribute is used to enter the linklist to be
> > > > I think it would be more appropriate to use the verb "select" here and
> > > > afaict it's a "list" as the "linked" part only relates to your
> > > > implementation).
> > > > 
> > > > But that said, I don't like this ABI. I think it would be cleaner if you
> > > > had specific attributes for each of the lists. That way it would be
> > > > clear that you have N lists and they can be configured and enabled
> > > > independently, and there's no possible race conditions.
> > > So we do have attributes for independent lists in this case. The user is
> > > given the option
> > > 
> > > to configure multiple lists at one go. For example I can do
> > > 
> > > echo 1 > curr_list
> > > 
> > > echo 0x18000010 1 > config
> > > echo 0x18000024 1 > config
> > > 
> > > Then followed by
> > > 
> > > echo 2 > curr_list
> > > 
> > > echo 0x18010038 6 > config
> > > echo 0x18020010 1 > config
> > > 
> > > We will get the output in terms of two separate list of registers values.
> > > 
> > I understand that this will define two lists of operations and that we
> > will get 2 and 7 registers dumped, respectively. Perhaps unlikely, but
> > what happens if you try to do these two operations concurrently?
> > 
> > 
> > What I'm suggesting here is that if you have N contexts, you should have
> > N interfaces to modify each one independently - simply because that's
> > generally a very good thing.
> 
> Not sure if there will ever be a concurrency issue in this case.
> This is just about programming the DCC SRAM from the user entries
> sequentially.

So you've decided that two such sequences must not happen at the same
time. (I know it's unlikely, but there's nothing preventing me from
running the two snippets of echos concurrently and the outcome will be
unexpected)

> The curr_list number is nothing but some register writes
> done in the dcc so that the dcc_hardware knows the beginning and end
> of a particular list and can dump the captured data according. Even if
> an user chooses multiple curr_list entries, it will be programmed
> sequentially in DCC_SRAM.
> 

So there's no separation between the lists in the hardware?

Looking at the driver I get a sense that we have N lists that can be
configured independently and will be run "independently" upon a trigger.

If this isn't the case, what's the purpose of the multiple lists?

> > 
> > > > > +		used while appending addresses.The range of values
> > > > > +		for this can be from 0 to 3.This feature is given in
> > > > > +		order to use certain linkedlist for certain debugging
> > > > > +		purposes.
> > > > > +		Example:
> > > > > +		echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
> > > > > +
> > [..]
> > > > > diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
> > [..]
> > > > > +static int dcc_valid_list(struct dcc_drvdata *drvdata, int curr_list)
> > > > > +{
> > > > > +	u32 lock_reg;
> > > > > +
> > > > > +	if (list_empty(&drvdata->cfg_head[curr_list]))
> > > > > +		return -EINVAL;
> > > > > +
> > > > > +	if (drvdata->enable[curr_list]) {
> > > > > +		dev_err(drvdata->dev, "List %d is already enabled\n",
> > > > > +				curr_list);
> > > > > +		return -EINVAL;
> > > > > +	}
> > > > > +
> > > > > +	lock_reg = dcc_readl(drvdata, DCC_LL_LOCK(curr_list));
> > > > Under what circumstances would this differ from
> > > > drvdata->enable[curr_list}?
> > > So locking the list is done on the register as soon as the user enters the
> > > curr_list entry whereas
> > > 
> > > the list is marked as enabled only on successfully programming the SRAM
> > > contents. So a list can
> > > 
> > > be locked and not marked enabled in certain cases. The first is used so that
> > > the user doesn't
> > > 
> > > mistakenly enter the same curr_list twice whereas the later is used to mark
> > > that the list has been
> > > 
> > > successfully configured.
> > > 
> > So this will mark the list as "actively in use, but disabled"? Why is
> > this kept in the hardware? When is this not the same as the list of
> > operations for that list being non-empty?
> 
> So this is in accordance with the dcc hardware configuration
> requirement. We have to lock the list first and after that proceed
> with the subsequent writes.

But what does this mean? What happens when I lock a list?

Afacit we have a "lock" bit and an "enable" bit. So in what circumstance
does the hardware care about a list being locked? Wouldn't it be
sufficient to just have the enable bit?

> As per the driver code below
> 
> ?????????????? /* 1. Take ownership of the list */
> ??????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
> 
> ??????????????? /* 2. Program linked-list in the SRAM */
> ??????????????? ram_cfg_base = drvdata->ram_cfg;
> ??????????????? ret = __dcc_ll_cfg(drvdata, list);
> ??????????????? if (ret) {
> ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
> ??????????????????????? goto err;
> ??????????????? }
> 
> ??????????????? /* 3. program DCC_RAM_CFG reg */
> ??????????????? dcc_writel(drvdata, ram_cfg_base +
> ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
> ??????????????? dcc_writel(drvdata, drvdata->ram_start +
> ??????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
> ??????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
> 
> ??????????????? /* 4. Clears interrupt status register */
> ??????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
> ??????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
> ??????????????????????????????????????? DCC_LL_INT_STATUS(list));
> 
> In case of any errors we again unlock the list before exiting.
> 

So it needs to be locked while SRAM contains a valid sequence of
operations?

Or does it need to be locked while we write to SRAM? If so, why is that?

Regards,
Bjorn


From andre.przywara at arm.com  Fri Jan  7 08:00:54 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  7 Jan 2022 16:00:54 +0000
Subject: [PATCH 0/2] arm64: booting.rst: Clarify EL2 and cover v8-R64
Message-ID: <20220107160056.322141-1-andre.przywara@arm.com>

Hi,

clarify the wording of the ARM64 boot protocol requirements, to both
cater for the introduction of secure EL2 in Armv8.4, but also for the
addition of the Armv8-R64 architecture branch.
There is an ARM ARM supplement for v8-R64[1], and also a free model[2].

On top of those clarifications, there are at least two other issues to
consider for v8-R64 on Linux, I wonder if those should be documented
somewhere, although I doubt that booting.rst is the right place:
- Linux clears the NS/NSTable bit in the PTEs. In non-secure world those
  bits are ignored, but when in secure world this means "secure PA".
  That luckily matches the design here (secure-only), but we should avoid
  re-purposing those bits in the future (which would be technically
  possible when running only non-secure).
- The GIC needs to be implemented using a "single Security state" for
  the Linux GIC driver to work. The model mentioned above defaults to
  a security aware GIC, so needs to be told off using the command line.
  I wonder if this is should be explicitly mentioned somewhere, to avoid
  disappointment by implementors later.

I'd be grateful for any hint whether to state those things and where to
put them.

Cheers,
Andre

[1] https://developer.arm.com/documentation/ddi0600/latest/
[2] https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms/arm-ecosystem-models

Andre Przywara (2):
  arm64: booting.rst: Clarify on requiring non-secure EL2
  arm64: booting.rst: Cover Armv8-R64

 Documentation/arm64/booting.rst | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

-- 
2.25.1



From andre.przywara at arm.com  Fri Jan  7 08:00:55 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  7 Jan 2022 16:00:55 +0000
Subject: [PATCH 1/2] arm64: booting.rst: Clarify on requiring non-secure EL2
In-Reply-To: <20220107160056.322141-1-andre.przywara@arm.com>
References: <20220107160056.322141-1-andre.przywara@arm.com>
Message-ID: <20220107160056.322141-2-andre.przywara@arm.com>

The ARMv8.4 architecture revision introduced the EL2 exception level
to the secure world. Clarify the existing wording to make sure that
Linux relies on being executed in the non-secure state.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 Documentation/arm64/booting.rst | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
index 52d060caf8bb..07cb34ed4200 100644
--- a/Documentation/arm64/booting.rst
+++ b/Documentation/arm64/booting.rst
@@ -10,9 +10,9 @@ This document is based on the ARM booting document by Russell King and
 is relevant to all public releases of the AArch64 Linux kernel.
 
 The AArch64 exception model is made up of a number of exception levels
-(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
-counterpart.  EL2 is the hypervisor level and exists only in non-secure
-mode. EL3 is the highest priority level and exists only in secure mode.
+(EL0 - EL3), with EL0, EL1 and EL2 having a secure and a non-secure
+counterpart.  EL2 is the hypervisor level, EL3 is the highest priority
+level and exists only in secure mode. Both are architecturally optional.
 
 For the purposes of this document, we will use the term `boot loader`
 simply to define all software that executes on the CPU(s) before control
@@ -167,8 +167,8 @@ Before jumping into the kernel, the following conditions must be met:
 
   All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
   IRQ and FIQ).
-  The CPU must be in either EL2 (RECOMMENDED in order to have access to
-  the virtualisation extensions) or non-secure EL1.
+  The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
+  to have access  to the virtualisation extensions), or in EL1.
 
 - Caches, MMUs
 
-- 
2.25.1



From andre.przywara at arm.com  Fri Jan  7 08:00:56 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri,  7 Jan 2022 16:00:56 +0000
Subject: [PATCH 2/2] arm64: booting.rst: Cover Armv8-R64
In-Reply-To: <20220107160056.322141-1-andre.przywara@arm.com>
References: <20220107160056.322141-1-andre.przywara@arm.com>
Message-ID: <20220107160056.322141-3-andre.przywara@arm.com>

There is a new revision of the ARMv8-R architecture [1], which
optionally introduces kernel compatibility - by introducing an MMU
into EL1 and EL0.
Linux can run on such an implementation, if it is entered in EL1 and
VMSA is both implemented and enabled for that exception level.

Clarify our kernel boot protocol to make this an officially supported
mode of operation, but also limit the expectations about running in
secure state (which is the only security state in v8-R).

Also we heavily rely on the Virtual Memory System Architecture (VMSA),
make this explicit in the text, as this allows to cover v8-R64 as well.

[1] https://developer.arm.com/documentation/ddi0600/latest/

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
 Documentation/arm64/booting.rst | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
index 07cb34ed4200..99fab4d7e7ad 100644
--- a/Documentation/arm64/booting.rst
+++ b/Documentation/arm64/booting.rst
@@ -167,8 +167,13 @@ Before jumping into the kernel, the following conditions must be met:
 
   All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
   IRQ and FIQ).
-  The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
-  to have access  to the virtualisation extensions), or in EL1.
+  If the CPU supports two security states, Linux must be entered in
+  non-secure state, either in EL2 (RECOMMENDED in order to have access
+  to the virtualisation extensions) or in EL1.
+  If the CPU only supports a single security state, Linux can be run even
+  when this single state is "secure".
+  The exception level the kernel is entered in must support the VMSA
+  memory model.
 
 - Caches, MMUs
 
-- 
2.25.1



From benjamin.gaignard at collabora.com  Fri Jan  7 08:02:41 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Fri, 7 Jan 2022 17:02:41 +0100
Subject: [PATCH v4 1/2] media: hevc: Remove RPS named flags
In-Reply-To: <YdWOecbZHO+Skbnn@eze-laptop>
References: <20220104073842.1791639-1-benjamin.gaignard@collabora.com>
 <20220104073842.1791639-2-benjamin.gaignard@collabora.com>
 <YdWOecbZHO+Skbnn@eze-laptop>
Message-ID: <a8b2640b-35e3-7e4c-c1ac-4d8651470d2b@collabora.com>


Le 05/01/2022 ? 13:26, Ezequiel Garcia a ?crit?:
> Hi Benjamin,
>
> On Tue, Jan 04, 2022 at 08:38:41AM +0100, Benjamin Gaignard wrote:
>> Marking a picture as long-term reference is valid for DPB but not for RPS.
>> Change flag name to match with it description in HEVC spec chapiter
>> "8.3.2 Decoding process for reference picture set".
>> Remove the other unused RPS flags.
>>
> A change like this, which is affecting a kernel interface and has impact
> on userspace and drivers, requires a lot more attention in the commit description.
>
> If I understand correctly, this change is related to how HEVC was first
> introduced and how the DPB was originally represented in V4L2.
>
> Originally, a DPB entry struct v4l2_hevc_dpb_entry had an rps field
> which can be:
>
>    V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE
>    V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER
>    V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR
>
> Perhaps this idea followed libva, where a VAPictureHEVC has flags field
> which can be:
>
>    VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE,
>    VA_PICTURE_HEVC_RPS_ST_CURR_AFTER,
>    VA_PICTURE_HEVC_RPS_LT_CURR,
>    VA_PICTURE_HEVC_LONG_TERM_REFERENCE
>
> In this representation, the sets PocStCurrBefore, PocStCurrAfter,
> PocLtCurr are implicit, and must be built by the kernel from the DPB
> entries struct v4l2_hevc_dpb_entry, using the information in the rps field.
>
> Last year, we changed this with your commit:
>
> commit d395a78db9eabd12633b39e05c80e803543b6590
> Author: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> Date:   Thu Jun 3 13:49:57 2021 +0200
>
>      media: hevc: Add decode params control
>
> Which added the control v4l2_ctrl_hevc_decode_params, which includes
> the sets PocStCurrBefore, PocStCurrAfter, PocLtCurr explicitly and therefore
> moved the responsability of creating and maintaining the sets to userspace.
>
> This effectively made the rps field in the struct v4l2_hevc_dpb_entry
> useless. The longterm flag is still needed though for a DPB entry.
>
> With this in mind, you could even say this commit is doing actually two
> things:
>
> 1. Removes the unused rps field.
> 2. Adds a flag field, for the longterm DPB entry boolean.
>
> Do you think a single byte of flags will be OK for a DPB entry?
> I think so, but I'd love yours/others input here.

In ITU HEVC spec it is said that:
"When a picture is referred to as being marked as "used for reference",
this collectively refers to the picture being marked as "used
  for
short-term reference" or "used for long-term reference" (but not both)."

So I believe that a single if enough for DPB entry.

>
> If the above is more or less accurate then, and provided you
> submit a new version with a more detailed commit description:

I will follow your suggestions and improve it in v5

>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
>
> Also, a small question:
>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
>> ---
>> version 4:
>> - check flags with & and not ==
>>
>>   Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst | 8 +++-----
>>   drivers/staging/media/hantro/hantro_g2_hevc_dec.c         | 2 +-
>>   drivers/staging/media/sunxi/cedrus/cedrus_h265.c          | 2 +-
>>   include/media/hevc-ctrls.h                                | 6 ++----
>>   4 files changed, 7 insertions(+), 11 deletions(-)
>>
>> diff --git a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> index e141f0e4eec9..38da33e61c3d 100644
>> --- a/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> +++ b/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
>> @@ -3166,11 +3166,9 @@ enum v4l2_mpeg_video_hevc_size_of_length_field -
>>   	:c:func:`v4l2_timeval_to_ns()` function to convert the struct
>>   	:c:type:`timeval` in struct :c:type:`v4l2_buffer` to a __u64.
>>       * - __u8
>> -      - ``rps``
>> -      - The reference set for the reference frame
>> -        (V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_BEFORE,
>> -        V4L2_HEVC_DPB_ENTRY_RPS_ST_CURR_AFTER or
>> -        V4L2_HEVC_DPB_ENTRY_RPS_LT_CURR)
>> +      - ``flags``
>> +      - Long term flag for the reference frame
>> +        (V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
> Is this longterm flag associated in any way to a syntax element
> or an HEVC process? If so, please document that.

done in v5.

Thanks for your review.

Benjamin

>
> Thanks,
> Ezequiel


From bjorn.andersson at linaro.org  Fri Jan  7 08:03:41 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Fri, 7 Jan 2022 08:03:41 -0800
Subject: [PATCH V6 0/7] Add driver support for Data Capture and Compare
 Engine(DCC) for SM8150,SC7280,SC7180,SDM845
In-Reply-To: <84d36c7f-d75e-61f9-7670-c651cc50d083@quicinc.com>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <396edd95-4f38-6830-99da-11e73d62a0cf@linaro.org>
 <705c280b-bced-476d-8e21-1a5afbf3d2f3@quicinc.com>
 <YdeDtlmPRQx3FU9i@ripper>
 <84d36c7f-d75e-61f9-7670-c651cc50d083@quicinc.com>
Message-ID: <YdhkXRxUQGRRZEsx@ripper>

On Fri 07 Jan 07:43 PST 2022, Souradeep Chowdhury wrote:

> 
> On 1/7/2022 5:35 AM, Bjorn Andersson wrote:
> > On Thu 06 Jan 07:20 PST 2022, Souradeep Chowdhury wrote:
> > 
> > > On 12/16/2021 9:18 PM, Thara Gopinath wrote:
> > > > 
> > > > On 8/10/21 1:54 PM, Souradeep Chowdhury wrote:
> > > > > DCC(Data Capture and Compare) is a DMA engine designed for debugging
> > > > > purposes.In case of a system
> > > > > crash or manual software triggers by the user the DCC hardware
> > > > > stores the value at the register
> > > > > addresses which can be used for debugging purposes.The DCC driver
> > > > > provides the user with sysfs
> > > > > interface to configure the register addresses.The options that the
> > > > > DCC hardware provides include
> > > > > reading from registers,writing to registers,first reading and then
> > > > > writing to registers and looping
> > > > > through the values of the same register.
> > > > > 
> > > > > In certain cases a register write needs to be executed for accessing
> > > > > the rest of the registers,
> > > > > also the user might want to record the changing values of a register
> > > > > with time for which he has the
> > > > > option to use the loop feature.
> > > > Hello Souradeep,
> > > > 
> > > > First of all, I think this is very a useful feature to have. I have some
> > > > generic design related queries/comments on driver and the interface
> > > > exposed to the user space. Also, I do not understand the h/w well here,
> > > > so feel free to correct me if I am wrong.
> > > > 
> > > > 1. Linked list looks like a very internal feature to the h/w. It really
> > > > is not an info that user should be aware of. I tried reading the code a
> > > > bit. IUC, every time a s/w trigger is issued the configs in all the
> > > > enabled linked lists are executed. The final ram dump that you get from
> > > > /dev/dcc_sram is a dump of contents from all the enabled list? Is this
> > > > understanding correct ? And we are talking of at-most 4 linked list?
> > > > If yes, I think it might be better to have a folder per linked list with
> > > > config, config_write etc. Also if possible it will be better to dump the
> > > > results to a file in the specific folder instead of reading from
> > > > /dev/dcc_sram.
> > > > If no, there is no real need for user to know the linked list, right?
> > > > Choosing of linked list can be done by kernel driver in this case with
> > > > no input needed from user.
> > > > 
> > > > 2. Now to the sysfs interface itself, I know lot of thought has gone
> > > > into sysfs vs debugfs considerations. But, have you considered using
> > > > netlink interface instead of sysfs. Netlink interface is used for
> > > > asynchronous communication between kernel and user space. In case of
> > > > DCC, the communication appears to be asynchronous, where in user asks
> > > > the kernel to capture some info and kernel can indicate back to user
> > > > when the info is captured. Also the entire mess surrounding echoing addr
> > > > / value / offset repeatedly into a sysfs entry can be avoided using
> > > > netlink interface.
> > > > 
> > > Hello Thara,
> > > 
> > > Thanks for your review comments. Following are some points from my end
> > > 
> > > 
> > > 1) Each linked list represent a particular block of memory in DCC_SRAM which
> > > is preserved for that particular list. That is why offset calculation is
> > > done on the driver based on the linked list chosen by the user.
> > > 
> > >  ??? This choice needs to be made by the user since the number for the linked
> > > list chosen is specific to the registers used to debug a particular
> > > component.? Also we are giving the user flexibility to configure multiple
> > > 
> > >  ??? linked lists at one go so that even if we don't have a separate folder
> > > for it , the dumps are collected as a separate list of registers. Also there
> > > are certain curr_list values which may be supported by the dcc
> > > 
> > >  ??? hardware but may not be accessible to the user and so the choice cannot
> > > be made arbitrarily from the driver.
> > > 
> > But in the end, as you write out the SRAM content, is there really any
> > linked lists? Afaict it's just a sequence of operations/commands. The
> > linked list part seems to be your data structure of choice to keep track
> > of these operations in the driver before flushing them out.
> 
> That is correct, the linked list defined in the driver is for storing the
> addresses sequentially in DCC_SRAM and is just an internal
> data structure of the driver. However, there is also a "list" from DCC
> hardware perspective. The following driver code shows how
> a list is initiated with the beginning and end sram offset so that DCC
> hardware can treat it as a separate list of addresses and dump
> the values separately.
> 

Makes sense. But I think you should use "list" (or "sequence") and not
"linked list" in the API/documentation then.

> ????????????? /* 1. Take ownership of the list */
> ??????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
> 
> ??????????????? /* 2. Program linked-list in the SRAM */
> ??????????????? ram_cfg_base = drvdata->ram_cfg;
> ??????????????? ret = __dcc_ll_cfg(drvdata, list);
> ??????????????? if (ret) {
> ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
> ??????????????????????? goto err;
> ??????????????? }
> 
> ??????????????? /* 3. program DCC_RAM_CFG reg */
> ??????????????? dcc_writel(drvdata, ram_cfg_base +
> ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
> ??????????????? dcc_writel(drvdata, drvdata->ram_start +
> ??????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
> ??????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
> 
> ??????????????? /* 4. Clears interrupt status register */
> ??????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
> ??????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
> ??????????????????????????????????????? DCC_LL_INT_STATUS(list));
> 
> ??????????????? drvdata->enable[list] = true;
> 
> So when user enters multiple lists, the DCC hardware will process it as
> separate group of register values.
> 

But as the DCC supports reading, writing, looping and rmw I don't think
it's correct to say that a list is a "group of register values". It's a
"sequence (or list) of operations".

Regards,
Bjorn

> > 
> > Regards,
> > Bjorn
> > 
> > > 2) From opensource, I can see that Netlink has been used in most of the
> > > cases where we need to notify stats to the user by taking the advantage of
> > > asynchronous communication. In this case, that requirement is not
> > > 
> > >  ? ? there since it is mostly one way communication from user to kernel. Also
> > > since this is used for debugging purposes perhaps sysfs adds more
> > > reliability than Netlink. In case of Netlink we have the additional
> > > 
> > >  ???? overhead of dealing with socket calls. Let me know otherwise.
> > > 
> > > 
> > > Thanks,
> > > 
> > > Souradeep
> > > 
> > > 
> > > 
> > > 
> > > 


From mark.rutland at arm.com  Fri Jan  7 08:20:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 16:20:52 +0000
Subject: [PATCH 1/2] arm64: booting.rst: Clarify on requiring non-secure
 EL2
In-Reply-To: <20220107160056.322141-2-andre.przywara@arm.com>
References: <20220107160056.322141-1-andre.przywara@arm.com>
 <20220107160056.322141-2-andre.przywara@arm.com>
Message-ID: <YdhoZPfjuI9vxSe3@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 04:00:55PM +0000, Andre Przywara wrote:
> The ARMv8.4 architecture revision introduced the EL2 exception level
> to the secure world. Clarify the existing wording to make sure that
> Linux relies on being executed in the non-secure state.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Documentation/arm64/booting.rst | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
> index 52d060caf8bb..07cb34ed4200 100644
> --- a/Documentation/arm64/booting.rst
> +++ b/Documentation/arm64/booting.rst
> @@ -10,9 +10,9 @@ This document is based on the ARM booting document by Russell King and
>  is relevant to all public releases of the AArch64 Linux kernel.
>  
>  The AArch64 exception model is made up of a number of exception levels
> -(EL0 - EL3), with EL0 and EL1 having a secure and a non-secure
> -counterpart.  EL2 is the hypervisor level and exists only in non-secure
> -mode. EL3 is the highest priority level and exists only in secure mode.
> +(EL0 - EL3), with EL0, EL1 and EL2 having a secure and a non-secure
> +counterpart.  EL2 is the hypervisor level, EL3 is the highest priority
> +level and exists only in secure mode. Both are architecturally optional.
>  
>  For the purposes of this document, we will use the term `boot loader`
>  simply to define all software that executes on the CPU(s) before control
> @@ -167,8 +167,8 @@ Before jumping into the kernel, the following conditions must be met:
>  
>    All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
>    IRQ and FIQ).
> -  The CPU must be in either EL2 (RECOMMENDED in order to have access to
> -  the virtualisation extensions) or non-secure EL1.
> +  The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
> +  to have access  to the virtualisation extensions), or in EL1.
                   ^^

Nit: double space

It might be clearer to explicitly say "non-secure EL2" and "non-secure EL1"
here, but either way this looks good to me, so with the whitespace fixed:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Thanks,
Mark.


From mark.rutland at arm.com  Fri Jan  7 08:27:43 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 7 Jan 2022 16:27:43 +0000
Subject: [PATCH 2/2] arm64: booting.rst: Cover Armv8-R64
In-Reply-To: <20220107160056.322141-3-andre.przywara@arm.com>
References: <20220107160056.322141-1-andre.przywara@arm.com>
 <20220107160056.322141-3-andre.przywara@arm.com>
Message-ID: <Ydhp/yMxdLHT7B01@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 04:00:56PM +0000, Andre Przywara wrote:
> There is a new revision of the ARMv8-R architecture [1], which
> optionally introduces kernel compatibility - by introducing an MMU
> into EL1 and EL0.
> Linux can run on such an implementation, if it is entered in EL1 and
> VMSA is both implemented and enabled for that exception level.
> 
> Clarify our kernel boot protocol to make this an officially supported
> mode of operation, but also limit the expectations about running in
> secure state (which is the only security state in v8-R).
> 
> Also we heavily rely on the Virtual Memory System Architecture (VMSA),
> make this explicit in the text, as this allows to cover v8-R64 as well.
> 
> [1] https://developer.arm.com/documentation/ddi0600/latest/
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Documentation/arm64/booting.rst | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/arm64/booting.rst b/Documentation/arm64/booting.rst
> index 07cb34ed4200..99fab4d7e7ad 100644
> --- a/Documentation/arm64/booting.rst
> +++ b/Documentation/arm64/booting.rst
> @@ -167,8 +167,13 @@ Before jumping into the kernel, the following conditions must be met:
>  
>    All forms of interrupts must be masked in PSTATE.DAIF (Debug, SError,
>    IRQ and FIQ).
> -  The CPU must be in non-secure state, either in EL2 (RECOMMENDED in order
> -  to have access  to the virtualisation extensions), or in EL1.
> +  If the CPU supports two security states, Linux must be entered in
> +  non-secure state, either in EL2 (RECOMMENDED in order to have access
> +  to the virtualisation extensions) or in EL1.
> +  If the CPU only supports a single security state, Linux can be run even
> +  when this single state is "secure".

Hmm... we've never supported running on the secure side so far, so are we
certain that everything actually works in such configs?

I know that some control fields (e.g. for filtering debug/tracing and so on)
differ across S/NS, and IIRC there's a bunch of GIC configuration that could
differ (but I could be mistaken).

Is there anything we need to have initialized differently by firmware?

Thanks,
Mark.

> +  The exception level the kernel is entered in must support the VMSA
> +  memory model.
>  
>  - Caches, MMUs
>  
> -- 
> 2.25.1
> 


From s-anna at ti.com  Fri Jan  7 08:29:30 2022
From: s-anna at ti.com (Suman Anna)
Date: Fri, 7 Jan 2022 10:29:30 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <CAL_JsqL3PGqmzA0wW37G7TXhbRVgByznk==Q8GhA0_OFBKAycQ@mail.gmail.com>
References: <20220107031905.2406176-1-robh@kernel.org>
 <cf75f1ee-8424-b6b2-f873-beea4676a29f@ti.com>
 <CAL_JsqL3PGqmzA0wW37G7TXhbRVgByznk==Q8GhA0_OFBKAycQ@mail.gmail.com>
Message-ID: <8902cefa-e2d7-1bcc-aae2-f272be53d675@ti.com>

Hi Rob,

On 1/7/22 9:20 AM, Rob Herring wrote:
> On Fri, Jan 7, 2022 at 8:27 AM Suman Anna <s-anna at ti.com> wrote:
>>
>> Hi Rob,
>>
>> On 1/6/22 9:19 PM, Rob Herring wrote:
>>> 'interrupt-parent' is never required as it can be in a parent node or a
>>> parent node itself can be an interrupt provider. Where exactly it lives is
>>> outside the scope of a binding schema.
>>>
>>> Signed-off-by: Rob Herring <robh at kernel.org>
>>> ---
>>>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
>>>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
>>>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
>>>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
>>>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
>>>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
>>>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
>>>  7 files changed, 15 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
>>> index 9ad470e01953..b085450b527f 100644
>>> --- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
>>> +++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
>>> @@ -43,7 +43,6 @@ required:
>>>    - gpio-controller
>>>    - interrupt-controller
>>>    - "#interrupt-cells"
>>> -  - interrupt-parent
>>>
>>>  additionalProperties: false
>>>
>>> diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
>>> index e864d798168d..d433e496ec6e 100644
>>> --- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
>>> +++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
>>> @@ -175,15 +175,6 @@ required:
>>>    - ti,mbox-num-fifos
>>>
>>>  allOf:
>>> -  - if:
>>> -      properties:
>>> -        compatible:
>>> -          enum:
>>> -            - ti,am654-mailbox
>>> -    then:
>>> -      required:
>>> -        - interrupt-parent
>>> -
>>
>> There are multiple interrupt controllers on TI K3 devices, and we need this
>> property to be defined _specifically_ to point to the relevant interrupt router
>> parent node.
>>
>> While what you state in general is true, I cannot have a node not define this on
>> K3 devices, and end up using the wrong interrupt parent (GIC
>> interrupt-controller). That's why the conditional compatible check.
> 
> But you could.
> 
> The parent node can have a default interrupt-parent and child nodes
> can override that. It doesn't matter which one is the default though
> typically you would want the one used the most to be the default.
> Looking at your dts files, it looks like you all did the opposite. 

Hmm, I am not sure I understood your last comment. Can you point out the
specific usage?

All our K3 dts files have the interrupt-parent = <&gic500> defined at the
root-node, which is the default ARM GIC.

Let us know if we need to fix something in our dts files.

The
> only way that wouldn't work is if the parent node is if the parent
> node has its own 'interrupts' or you are just abusing
> 'interrupt-parent' where the standard parsing doesn't work.

All our K3 gic500 nodes does have an 'interrupts' property.

> 
> You are also free to use 'interrupts-extended' anywhere 'interrupts'
> is used and then interrupt-parent being present is an error. 

Yes, this is understood. The OMAP Mailbox binding is reused between multiple SoC
families, some of which do not use an Interrupt Router in between.

So, whats the best way to enforce this in the specific schema? I have used the
common 'interrupts' property that applies to all SoCs, and enforced the
conditional 'interrupt-parent' only on relevant compatibles.

regards
Suman

How you
> structure all this is outside the scope of binding schemas which only
> need to define how many interrupts and what are they. Ensuring parents
> and cell sizes are correct is mostly done by dtc.
> 
> Rob
> 



From seanjc at google.com  Fri Jan  7 08:31:33 2022
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 7 Jan 2022 16:31:33 +0000
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <CAD=HUj5v37wZ9NuNC4QBDvCGO2SyNG2KAiTc9Jxfg=R7neCuTw@mail.gmail.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
 <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
 <YdcpIQgMZJrqswKU@google.com>
 <CAD=HUj5v37wZ9NuNC4QBDvCGO2SyNG2KAiTc9Jxfg=R7neCuTw@mail.gmail.com>
Message-ID: <Ydhq5aHW+JFo15UF@google.com>

On Fri, Jan 07, 2022, David Stevens wrote:
> > > These are the type of pages which KVM is currently rejecting. Is this
> > > something that KVM can support?
> >
> > I'm not opposed to it.  My complaint is that this series is incomplete in that it
> > allows mapping the memory into the guest, but doesn't support accessing the memory
> > from KVM itself.  That means for things to work properly, KVM is relying on the
> > guest to use the memory in a limited capacity, e.g. isn't using the memory as
> > general purpose RAM.  That's not problematic for your use case, because presumably
> > the memory is used only by the vGPU, but as is KVM can't enforce that behavior in
> > any way.
> >
> > The really gross part is that failures are not strictly punted to userspace;
> > the resulting error varies significantly depending on how the guest "illegally"
> > uses the memory.
> >
> > My first choice would be to get the amdgpu driver "fixed", but that's likely an
> > unreasonable request since it sounds like the non-KVM behavior is working as intended.
> >
> > One thought would be to require userspace to opt-in to mapping this type of memory
> > by introducing a new memslot flag that explicitly states that the memslot cannot
> > be accessed directly by KVM, i.e. can only be mapped into the guest.  That way,
> > KVM has an explicit ABI with respect to how it handles this type of memory, even
> > though the semantics of exactly what will happen if userspace/guest violates the
> > ABI are not well-defined.  And internally, KVM would also have a clear touchpoint
> > where it deliberately allows mapping such memslots, as opposed to the more implicit
> > behavior of bypassing ensure_pfn_ref().
> 
> Is it well defined when KVM needs to directly access a memslot?

Not really, there's certainly no established rule.

> At least for x86, it looks like most of the use cases are related to nested
> virtualization, except for the call in emulator_cmpxchg_emulated.

The emulator_cmpxchg_emulated() will hopefully go away in the nearish future[*].
Paravirt features that communicate between guest and host via memory is the other
case that often maps a pfn into KVM.

> Without being able to specifically state what should be avoided, a flag like
> that would be difficult for userspace to use.

Yeah :-(  I was thinking KVM could state the flag would be safe to use if and only
if userspace could guarantee that the guest would use the memory for some "special"
use case, but hadn't actually thought about how to word things.

The best thing to do is probably to wait for for kvm_vcpu_map() to be eliminated,
as described in the changelogs for commits:

  357a18ad230f ("KVM: Kill kvm_map_gfn() / kvm_unmap_gfn() and gfn_to_pfn_cache")
  7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status")

Once that is done, everything in KVM will either access guest memory through the
userspace hva, or via a mechanism that is tied into the mmu_notifier, at which
point accessing non-refcounted struct pages is safe and just needs to worry about
not corrupting _refcount.


From seanjc at google.com  Fri Jan  7 08:46:56 2022
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 7 Jan 2022 16:46:56 +0000
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <Ydhq5aHW+JFo15UF@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
 <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
 <YdcpIQgMZJrqswKU@google.com>
 <CAD=HUj5v37wZ9NuNC4QBDvCGO2SyNG2KAiTc9Jxfg=R7neCuTw@mail.gmail.com>
 <Ydhq5aHW+JFo15UF@google.com>
Message-ID: <YdhugJ6h76JLHTjT@google.com>

On Fri, Jan 07, 2022, Sean Christopherson wrote:
> On Fri, Jan 07, 2022, David Stevens wrote:
> > > > These are the type of pages which KVM is currently rejecting. Is this
> > > > something that KVM can support?
> > >
> > > I'm not opposed to it.  My complaint is that this series is incomplete in that it
> > > allows mapping the memory into the guest, but doesn't support accessing the memory
> > > from KVM itself.  That means for things to work properly, KVM is relying on the
> > > guest to use the memory in a limited capacity, e.g. isn't using the memory as
> > > general purpose RAM.  That's not problematic for your use case, because presumably
> > > the memory is used only by the vGPU, but as is KVM can't enforce that behavior in
> > > any way.
> > >
> > > The really gross part is that failures are not strictly punted to userspace;
> > > the resulting error varies significantly depending on how the guest "illegally"
> > > uses the memory.
> > >
> > > My first choice would be to get the amdgpu driver "fixed", but that's likely an
> > > unreasonable request since it sounds like the non-KVM behavior is working as intended.
> > >
> > > One thought would be to require userspace to opt-in to mapping this type of memory
> > > by introducing a new memslot flag that explicitly states that the memslot cannot
> > > be accessed directly by KVM, i.e. can only be mapped into the guest.  That way,
> > > KVM has an explicit ABI with respect to how it handles this type of memory, even
> > > though the semantics of exactly what will happen if userspace/guest violates the
> > > ABI are not well-defined.  And internally, KVM would also have a clear touchpoint
> > > where it deliberately allows mapping such memslots, as opposed to the more implicit
> > > behavior of bypassing ensure_pfn_ref().
> > 
> > Is it well defined when KVM needs to directly access a memslot?
> 
> Not really, there's certainly no established rule.
> 
> > At least for x86, it looks like most of the use cases are related to nested
> > virtualization, except for the call in emulator_cmpxchg_emulated.
> 
> The emulator_cmpxchg_emulated() will hopefully go away in the nearish future[*].

Forgot the link...

https://lore.kernel.org/all/YcG32Ytj0zUAW%2FB2 at hirez.programming.kicks-ass.net/

> Paravirt features that communicate between guest and host via memory is the other
> case that often maps a pfn into KVM.
> 
> > Without being able to specifically state what should be avoided, a flag like
> > that would be difficult for userspace to use.
> 
> Yeah :-(  I was thinking KVM could state the flag would be safe to use if and only
> if userspace could guarantee that the guest would use the memory for some "special"
> use case, but hadn't actually thought about how to word things.
> 
> The best thing to do is probably to wait for for kvm_vcpu_map() to be eliminated,
> as described in the changelogs for commits:
> 
>   357a18ad230f ("KVM: Kill kvm_map_gfn() / kvm_unmap_gfn() and gfn_to_pfn_cache")
>   7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status")
> 
> Once that is done, everything in KVM will either access guest memory through the
> userspace hva, or via a mechanism that is tied into the mmu_notifier, at which
> point accessing non-refcounted struct pages is safe and just needs to worry about
> not corrupting _refcount.


From robh at kernel.org  Fri Jan  7 09:03:25 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 7 Jan 2022 11:03:25 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <8902cefa-e2d7-1bcc-aae2-f272be53d675@ti.com>
References: <20220107031905.2406176-1-robh@kernel.org>
 <cf75f1ee-8424-b6b2-f873-beea4676a29f@ti.com>
 <CAL_JsqL3PGqmzA0wW37G7TXhbRVgByznk==Q8GhA0_OFBKAycQ@mail.gmail.com>
 <8902cefa-e2d7-1bcc-aae2-f272be53d675@ti.com>
Message-ID: <CAL_JsqKScenYRO4QERfdB-e8-70Va1tMBbSTXbAoUp+AVTk8Pw@mail.gmail.com>

On Fri, Jan 7, 2022 at 10:29 AM Suman Anna <s-anna at ti.com> wrote:
>
> Hi Rob,
>
> On 1/7/22 9:20 AM, Rob Herring wrote:
> > On Fri, Jan 7, 2022 at 8:27 AM Suman Anna <s-anna at ti.com> wrote:
> >>
> >> Hi Rob,
> >>
> >> On 1/6/22 9:19 PM, Rob Herring wrote:
> >>> 'interrupt-parent' is never required as it can be in a parent node or a
> >>> parent node itself can be an interrupt provider. Where exactly it lives is
> >>> outside the scope of a binding schema.
> >>>
> >>> Signed-off-by: Rob Herring <robh at kernel.org>
> >>> ---
> >>>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
> >>>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
> >>>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
> >>>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
> >>>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
> >>>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
> >>>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
> >>>  7 files changed, 15 deletions(-)
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> >>> index 9ad470e01953..b085450b527f 100644
> >>> --- a/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> >>> +++ b/Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml
> >>> @@ -43,7 +43,6 @@ required:
> >>>    - gpio-controller
> >>>    - interrupt-controller
> >>>    - "#interrupt-cells"
> >>> -  - interrupt-parent
> >>>
> >>>  additionalProperties: false
> >>>
> >>> diff --git a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> >>> index e864d798168d..d433e496ec6e 100644
> >>> --- a/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> >>> +++ b/Documentation/devicetree/bindings/mailbox/ti,omap-mailbox.yaml
> >>> @@ -175,15 +175,6 @@ required:
> >>>    - ti,mbox-num-fifos
> >>>
> >>>  allOf:
> >>> -  - if:
> >>> -      properties:
> >>> -        compatible:
> >>> -          enum:
> >>> -            - ti,am654-mailbox
> >>> -    then:
> >>> -      required:
> >>> -        - interrupt-parent
> >>> -
> >>
> >> There are multiple interrupt controllers on TI K3 devices, and we need this
> >> property to be defined _specifically_ to point to the relevant interrupt router
> >> parent node.
> >>
> >> While what you state in general is true, I cannot have a node not define this on
> >> K3 devices, and end up using the wrong interrupt parent (GIC
> >> interrupt-controller). That's why the conditional compatible check.
> >
> > But you could.
> >
> > The parent node can have a default interrupt-parent and child nodes
> > can override that. It doesn't matter which one is the default though
> > typically you would want the one used the most to be the default.
> > Looking at your dts files, it looks like you all did the opposite.
>
> Hmm, I am not sure I understood your last comment. Can you point out the
> specific usage?

Perhaps an example. These are all equivalent:

parent {
  child1 {
    interrupt-parent = <&intc1>;
    interrupts = <1>;
  };
  child2 {
    interrupt-parent = <&intc2>;
    interrupts = <2>;
 };
};

parent {
  interrupt-parent = <&intc1>; // Or in the parent's parent...
  child1 {
    interrupts = <1>;
  };
  child2 {
    interrupt-parent = <&intc2>;
    interrupts = <2>;
  };
};

parent {
  interrupt-parent = <&intc2>;
  child1 {
    interrupt-parent = <&intc1>;
    interrupts = <1>;
  };
  child2 {
    interrupts = <2>;
  };
};

You could structure main_navss and child nodes in any of these 3 ways.

>
> All our K3 dts files have the interrupt-parent = <&gic500> defined at the
> root-node, which is the default ARM GIC.
>
> Let us know if we need to fix something in our dts files.

No! I'm just saying there are multiple correct ways to write the dts files.

> The
> > only way that wouldn't work is if the parent node is if the parent
> > node has its own 'interrupts' or you are just abusing
> > 'interrupt-parent' where the standard parsing doesn't work.
>
> All our K3 gic500 nodes does have an 'interrupts' property.

I said the parent node, not the 'interrupt-parent'. In this case, the
parent is 'main_navss: bus at 30800000'. It doesn't have 'interrupts' in
your case, so only the 2nd case is a possibility.

> > You are also free to use 'interrupts-extended' anywhere 'interrupts'
> > is used and then interrupt-parent being present is an error.
>
> Yes, this is understood. The OMAP Mailbox binding is reused between multiple SoC
> families, some of which do not use an Interrupt Router in between.
>
> So, whats the best way to enforce this in the specific schema? I have used the
> common 'interrupts' property that applies to all SoCs, and enforced the
> conditional 'interrupt-parent' only on relevant compatibles.

You can't. There is no way a schema can ensure you connect the right
interrupt controller just as it can't ensure you used the right
interrupt number and flags or used the right addresses. Well, you
could technically, but then at that point we could just generate the
dts from the schema.

Rob


From jose.exposito89 at gmail.com  Fri Jan  7 09:26:01 2022
From: jose.exposito89 at gmail.com (=?iso-8859-1?Q?Jos=E9_Exp=F3sito?=)
Date: Fri, 7 Jan 2022 18:26:01 +0100
Subject: [PATCH v3 2/6] drm/plane: Fix typo in format_mod_supported
 documentation
In-Reply-To: <3DdB6YPUQr4O063yNreefZcIm6p5Z6HORoVVbk5RTMmjz8qvnxMse42hLvfDmA323KG-TWLc_JUFZEEEIkoINXQuAzjLVe2jRRM01tQgYOU=@emersion.fr>
References: <20211226112503.31771-1-jose.exposito89@gmail.com>
 <20211226112503.31771-3-jose.exposito89@gmail.com>
 <3DdB6YPUQr4O063yNreefZcIm6p5Z6HORoVVbk5RTMmjz8qvnxMse42hLvfDmA323KG-TWLc_JUFZEEEIkoINXQuAzjLVe2jRRM01tQgYOU=@emersion.fr>
Message-ID: <20220107172601.GA122757@elementary>

Hi Simon,

On Wed, Jan 05, 2022 at 11:54:43PM +0000, Simon Ser wrote:
> Pushed patches 1 & 2 to drm-misc-next. Thanks for your contribution!

Thanks a lot for the review and for applying the changes, appreciate it.

Is there something that needs to improve in the other 4 patches?
Or just waiting on maintainers input?

Thanks,
Jos? Exp?sito


From contact at emersion.fr  Fri Jan  7 09:29:29 2022
From: contact at emersion.fr (Simon Ser)
Date: Fri, 07 Jan 2022 17:29:29 +0000
Subject: [PATCH v3 2/6] drm/plane: Fix typo in format_mod_supported
 documentation
In-Reply-To: <20220107172601.GA122757@elementary>
References: <20211226112503.31771-1-jose.exposito89@gmail.com>
 <20211226112503.31771-3-jose.exposito89@gmail.com>
 <3DdB6YPUQr4O063yNreefZcIm6p5Z6HORoVVbk5RTMmjz8qvnxMse42hLvfDmA323KG-TWLc_JUFZEEEIkoINXQuAzjLVe2jRRM01tQgYOU=@emersion.fr>
 <20220107172601.GA122757@elementary>
Message-ID: <zTX9uSmiLpHhH2VG6QBEkyfzqLTLylulwnf54f-fsx7Qp-ePGWW9gJJm-whTbo35o0TKd_hzV_f5Ir977j0A_sMeXCXZ8nofLNV6Q9Rzwwc=@emersion.fr>

On Friday, January 7th, 2022 at 18:26, Jos? Exp?sito <jose.exposito89 at gmail.com> wrote:

> Is there something that needs to improve in the other 4 patches?
> Or just waiting on maintainers input?

Yeah, these patches look good to me. Feel free to add my R-b.

Maintainers for these drivers still need to review/ack/apply them.


From marcel at ziswiler.com  Fri Jan  7 10:03:02 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:02 +0100
Subject: [PATCH v1 02/14] dt-bindings: gpio: fix gpio-hog example
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-3-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Even if this is no yaml yet at least fix the example to be compliant to
later schema as e.g. found in gpio-pca95xx.yaml, fairchild,74hc595.yaml
and gpio/fsl-imx-gpio.yaml.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 Documentation/devicetree/bindings/gpio/gpio.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index a8895d339bfe..5663e71b751f 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -213,7 +213,7 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
 		gpio-controller;
 		#gpio-cells = <2>;
 
-		line_b {
+		line_b-hog {
 			gpio-hog;
 			gpios = <6 0>;
 			output-low;
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:01 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:01 +0100
Subject: [PATCH v1 01/14] arm64: dts: imx8mm: fix strange hex notation
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-2-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Fix strange hex notation with mixed lower-case and upper-case letters.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6af3353..c68a5e456025 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -279,7 +279,7 @@
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
-#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53c 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53C 0x4 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
@@ -486,7 +486,7 @@
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                0x1D8 0x440 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
-#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4Fc 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4FC 0x4 0x2
 #define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                 0x1D8 0x440 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
@@ -494,7 +494,7 @@
 #define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
 #define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX                                  0x1DC 0x444 0x000 0x4 0x0
-#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4Fc 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4FC 0x4 0x3
 #define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:03 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:03 +0100
Subject: [PATCH v1 03/14] arm64: defconfig: rebuild default configuration
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-4-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Run "make defconfig; make savedefconfig" to rebuild defconfig.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 135 +++++++++++++----------------------
 1 file changed, 50 insertions(+), 85 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cc5d3ba166b1..79e4bf9f4c2c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,17 +3,14 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
+CONFIG_BPF_JIT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
 CONFIG_BLK_CGROUP=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_HUGETLB=y
@@ -66,7 +63,6 @@ CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
 CONFIG_SCHED_SMT=y
 CONFIG_NUMA=y
-CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_KEXEC_FILE=y
 CONFIG_CRASH_DUMP=y
@@ -84,7 +80,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
@@ -97,19 +92,9 @@ CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
 CONFIG_ARM_SCMI_CPUFREQ=y
 CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_QORIQ_CPUFREQ=y
-CONFIG_ARM_SCMI_PROTOCOL=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_INTEL_STRATIX10_SERVICE=y
-CONFIG_INTEL_STRATIX10_RSU=m
-CONFIG_QCOM_SCM=y
-CONFIG_EFI_CAPSULE_LOADER=y
-CONFIG_IMX_SCU=y
-CONFIG_IMX_SCU_PD=y
 CONFIG_ACPI=y
 CONFIG_ACPI_APEI=y
 CONFIG_ACPI_APEI_GHES=y
-CONFIG_ACPI_APEI_PCIEAER=y
 CONFIG_ACPI_APEI_MEMORY_FAILURE=y
 CONFIG_ACPI_APEI_EINJ=y
 CONFIG_VIRTUALIZATION=y
@@ -182,14 +167,12 @@ CONFIG_NET_ACT_GATE=m
 CONFIG_QRTR=m
 CONFIG_QRTR_SMD=m
 CONFIG_QRTR_TUN=m
-CONFIG_BPF_JIT=y
 CONFIG_CAN=m
+CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
-CONFIG_CAN_FLEXCAN=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
-# CONFIG_BT_HS is not set
 # CONFIG_BT_LE is not set
 CONFIG_BT_LEDS=y
 # CONFIG_BT_DEBUGFS is not set
@@ -228,7 +211,6 @@ CONFIG_PCIE_ROCKCHIP_HOST=m
 CONFIG_PCIE_BRCMSTB=m
 CONFIG_PCI_IMX6=y
 CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
@@ -236,6 +218,11 @@ CONFIG_PCIE_KIRIN=y
 CONFIG_PCIE_HISI_STB=y
 CONFIG_PCIE_TEGRA194_HOST=m
 CONFIG_PCIE_VISCONTI_HOST=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
+CONFIG_PCIE_CADENCE_PLAT_HOST=y
+CONFIG_PCIE_CADENCE_PLAT_EP=y
+CONFIG_PCI_J721E_HOST=y
+CONFIG_PCI_J721E_EP=y
 CONFIG_PCI_ENDPOINT=y
 CONFIG_PCI_ENDPOINT_CONFIGFS=y
 CONFIG_PCI_EPF_TEST=m
@@ -243,8 +230,15 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_HISILICON_LPC=y
-CONFIG_FSL_MC_BUS=y
 CONFIG_TEGRA_ACONNECT=m
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_INTEL_STRATIX10_SERVICE=y
+CONFIG_INTEL_STRATIX10_RSU=m
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -261,11 +255,10 @@ CONFIG_MTD_SST25L=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_DENALI_DT=y
 CONFIG_MTD_NAND_MARVELL=y
+CONFIG_MTD_NAND_BRCMNAND=m
 CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_MTK_DEVAPC=m
-CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -315,6 +308,7 @@ CONFIG_NET_XGENE=y
 CONFIG_ATL1C=m
 CONFIG_BCMGENET=m
 CONFIG_BNX2X=m
+CONFIG_SYSTEMPORT=m
 CONFIG_MACB=y
 CONFIG_THUNDER_NIC_PF=y
 CONFIG_FEC=y
@@ -351,13 +345,11 @@ CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
 CONFIG_TI_K3_AM65_CPSW_NUSS=y
 CONFIG_QCOM_IPA=m
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MESON_GXL_PHY=m
 CONFIG_AQUANTIA_PHY=y
 CONFIG_BCM54140_PHY=m
 CONFIG_MARVELL_PHY=m
 CONFIG_MARVELL_10G_PHY=m
-CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_MICROSEMI_PHY=y
 CONFIG_AT803X_PHY=y
@@ -365,6 +357,8 @@ CONFIG_REALTEK_PHY=y
 CONFIG_ROCKCHIP_PHY=y
 CONFIG_DP83867_PHY=y
 CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
@@ -406,6 +400,8 @@ CONFIG_SERIO_AMBAKMI=y
 CONFIG_LEGACY_PTY_COUNT=16
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_RUNTIME_UARTS=16
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_BCM2835AUX=y
@@ -472,6 +468,7 @@ CONFIG_SPI=y
 CONFIG_SPI_ARMADA_3700=y
 CONFIG_SPI_BCM2835=m
 CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_SPI_DESIGNWARE=m
 CONFIG_SPI_DW_DMA=y
 CONFIG_SPI_DW_MMIO=m
@@ -507,22 +504,7 @@ CONFIG_PINCTRL_IMX8QM=y
 CONFIG_PINCTRL_IMX8QXP=y
 CONFIG_PINCTRL_IMX8DXL=y
 CONFIG_PINCTRL_IMX8ULP=y
-CONFIG_PINCTRL_MSM=y
-CONFIG_PINCTRL_IPQ8074=y
-CONFIG_PINCTRL_IPQ6018=y
-CONFIG_PINCTRL_MSM8916=y
-CONFIG_PINCTRL_MSM8994=y
-CONFIG_PINCTRL_MSM8996=y
-CONFIG_PINCTRL_MSM8998=y
-CONFIG_PINCTRL_QCS404=y
-CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
-CONFIG_PINCTRL_SC7180=y
-CONFIG_PINCTRL_SC7280=y
-CONFIG_PINCTRL_SDM845=y
-CONFIG_PINCTRL_SM8150=y
-CONFIG_PINCTRL_SM8250=y
-CONFIG_PINCTRL_SM8350=y
 CONFIG_PINCTRL_LPASS_LPI=m
 CONFIG_GPIO_ALTERA=m
 CONFIG_GPIO_DAVINCI=y
@@ -543,9 +525,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
-CONFIG_POWER_AVS=y
-CONFIG_QCOM_CPR=y
-CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_QCOM_PON=m
 CONFIG_POWER_RESET_XGENE=y
@@ -553,10 +532,10 @@ CONFIG_POWER_RESET_SYSCON=y
 CONFIG_SYSCON_REBOOT_MODE=y
 CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_BQ27XXX=y
-CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_BQ25890=m
 CONFIG_CHARGER_BQ25980=m
+CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
 CONFIG_SENSORS_LM90=m
@@ -568,10 +547,10 @@ CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
-CONFIG_QORIQ_THERMAL=m
-CONFIG_SUN8I_THERMAL=y
 CONFIG_IMX_SC_THERMAL=m
 CONFIG_IMX8MM_THERMAL=m
+CONFIG_QORIQ_THERMAL=m
+CONFIG_SUN8I_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=m
 CONFIG_RCAR_THERMAL=y
 CONFIG_RCAR_GEN3_THERMAL=y
@@ -580,8 +559,8 @@ CONFIG_BCM2711_THERMAL=m
 CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
-CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_TEGRA_SOCTHERM=m
+CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_QCOM_TSENS=y
 CONFIG_QCOM_SPMI_TEMP_ALARM=m
 CONFIG_QCOM_LMH=m
@@ -590,7 +569,6 @@ CONFIG_WATCHDOG=y
 CONFIG_SL28CPLD_WATCHDOG=m
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_ARM_SBSA_WATCHDOG=y
-CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=m
@@ -599,9 +577,11 @@ CONFIG_IMX_SC_WDT=m
 CONFIG_QCOM_WDT=m
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
+CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
+CONFIG_BCM7038_WDT=m
 CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_I2C=y
@@ -651,13 +631,12 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 CONFIG_MEDIA_SDR_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_PLATFORM_SUPPORT=y
 # CONFIG_DVB_NET is not set
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
@@ -674,7 +653,6 @@ CONFIG_VIDEO_RCAR_DRIF=m
 CONFIG_VIDEO_IMX219=m
 CONFIG_VIDEO_OV5640=m
 CONFIG_VIDEO_OV5645=m
-CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_MALI_DISPLAY=m
@@ -701,24 +679,23 @@ CONFIG_DRM_SUN8I_DW_HDMI=m
 CONFIG_DRM_SUN8I_MIXER=m
 CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
+CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
-CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
-CONFIG_DRM_DISPLAY_CONNECTOR=m
 CONFIG_DRM_LONTIUM_LT8912B=m
-CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_LONTIUM_LT9611=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_PARADE_PS8640=m
 CONFIG_DRM_SII902X=m
 CONFIG_DRM_SIMPLE_BRIDGE=m
 CONFIG_DRM_THINE_THC63LVD1024=m
 CONFIG_DRM_TI_SN65DSI86=m
-CONFIG_DRM_LONTIUM_LT9611UXC=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@@ -749,15 +726,14 @@ CONFIG_SND_HDA_TEGRA=m
 CONFIG_SND_HDA_CODEC_HDMI=m
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
-CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_FSL_ASRC=m
 CONFIG_SND_SOC_FSL_MICFIL=m
 CONFIG_SND_SOC_FSL_EASRC=m
 CONFIG_SND_IMX_SOC=m
 CONFIG_SND_SOC_IMX_SGTL5000=m
 CONFIG_SND_SOC_IMX_SPDIF=m
-CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_SOC_FSL_ASOC_CARD=m
+CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_MESON_AXG_SOUND_CARD=m
 CONFIG_SND_MESON_GX_SOUND_CARD=m
 CONFIG_SND_SOC_QCOM=m
@@ -811,13 +787,12 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_HID_MULTITOUCH=m
 CONFIG_I2C_HID_ACPI=m
 CONFIG_I2C_HID_OF=m
-CONFIG_USB_CONN_GPIO=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=m
 CONFIG_USB_XHCI_PCI_RENESAS=m
 CONFIG_USB_XHCI_TEGRA=y
+CONFIG_USB_BRCMSTB=m
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_EXYNOS=y
 CONFIG_USB_EHCI_HCD_PLATFORM=y
@@ -862,8 +837,8 @@ CONFIG_TYPEC=m
 CONFIG_TYPEC_TCPM=m
 CONFIG_TYPEC_TCPCI=m
 CONFIG_TYPEC_FUSB302=m
-CONFIG_TYPEC_HD3SS3220=m
 CONFIG_TYPEC_TPS6598X=m
+CONFIG_TYPEC_HD3SS3220=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_ARMMMCI=y
@@ -961,7 +936,6 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
-CONFIG_MFD_CROS_EC_DEV=y
 CONFIG_STAGING=y
 CONFIG_STAGING_MEDIA=y
 CONFIG_VIDEO_HANTRO=m
@@ -971,15 +945,14 @@ CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_CHARDEV=m
-CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_SCPI=y
 CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_FSL_SAI=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_COMMON_CLK_PWM=y
 CONFIG_COMMON_CLK_VC5=y
-CONFIG_COMMON_CLK_ZYNQMP=y
 CONFIG_COMMON_CLK_BD718XX=m
 CONFIG_CLK_RASPBERRYPI=m
 CONFIG_CLK_IMX8MM=y
@@ -995,8 +968,8 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y
 CONFIG_QCOM_CLK_APCC_MSM8996=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
-CONFIG_IPQ_GCC_8074=y
 CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
 CONFIG_MSM_GCC_8916=y
 CONFIG_MSM_GCC_8994=y
 CONFIG_MSM_MMCC_8996=y
@@ -1005,16 +978,13 @@ CONFIG_QCS_GCC_404=y
 CONFIG_SC_GCC_7180=y
 CONFIG_SC_GCC_7280=y
 CONFIG_SDM_CAMCC_845=m
-CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_VIDEOCC_845=y
 CONFIG_SDM_DISPCC_845=y
-CONFIG_SM_GCC_8150=y
-CONFIG_SM_GCC_8250=y
+CONFIG_SM_DISPCC_8250=y
 CONFIG_SM_GCC_8350=y
 CONFIG_SM_GPUCC_8150=y
 CONFIG_SM_GPUCC_8250=y
-CONFIG_SM_DISPCC_8250=y
 CONFIG_QCOM_HFPLL=y
 CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
@@ -1048,9 +1018,11 @@ CONFIG_RASPBERRYPI_POWER=y
 CONFIG_FSL_DPAA=y
 CONFIG_FSL_MC_DPIO=y
 CONFIG_FSL_RCPM=y
+CONFIG_MTK_DEVAPC=m
 CONFIG_MTK_PMIC_WRAP=y
 CONFIG_QCOM_AOSS_QMP=y
 CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_RMTFS_MEM=m
 CONFIG_QCOM_RPMH=y
@@ -1061,24 +1033,21 @@ CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
 CONFIG_QCOM_SMSM=y
 CONFIG_QCOM_SOCINFO=m
-CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_APR=m
-CONFIG_ARCH_R8A774A1=y
-CONFIG_ARCH_R8A774B1=y
-CONFIG_ARCH_R8A774C0=y
-CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77990=y
 CONFIG_ARCH_R8A77950=y
 CONFIG_ARCH_R8A77951=y
+CONFIG_ARCH_R8A77965=y
 CONFIG_ARCH_R8A77960=y
 CONFIG_ARCH_R8A77961=y
-CONFIG_ARCH_R8A77965=y
-CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A77980=y
-CONFIG_ARCH_R8A77990=y
-CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A779A0=y
 CONFIG_ARCH_R9A07G044=y
+CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1157,13 +1126,13 @@ CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_ARM_SMMU_V3_PMU=m
 CONFIG_FSL_IMX8_DDR_PMU=m
-CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
+CONFIG_HISI_PMU=y
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_IMX_OCOTP_SCU=y
-CONFIG_QCOM_QFPROM=y
 CONFIG_MTK_EFUSE=y
+CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_UNIPHIER_EFUSE=y
@@ -1177,11 +1146,9 @@ CONFIG_FPGA_REGION=m
 CONFIG_OF_FPGA_REGION=m
 CONFIG_TEE=y
 CONFIG_OPTEE=y
-CONFIG_SLIMBUS=m
+CONFIG_MUX_MMIO=y
 CONFIG_SLIM_QCOM_CTRL=m
 CONFIG_SLIM_QCOM_NGD_CTRL=m
-CONFIG_MUX_MMIO=y
-CONFIG_INTERCONNECT=y
 CONFIG_INTERCONNECT_IMX=m
 CONFIG_INTERCONNECT_IMX8MM=m
 CONFIG_INTERCONNECT_IMX8MN=m
@@ -1209,7 +1176,6 @@ CONFIG_OVERLAY_FS=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
 CONFIG_SQUASHFS=y
 CONFIG_NFS_FS=y
@@ -1241,6 +1207,5 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_PREEMPT is not set
 # CONFIG_FTRACE is not set
 CONFIG_MEMTEST=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:05 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:05 +0100
Subject: [PATCH v1 05/14] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-6-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids firmware load error and sysfs fallback reported as follows:

[    0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
 for imx/sdma/sdma-imx7d.bin failed with error -2
[    0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
 fallback for: imx/sdma/sdma-imx7d.bin

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3c8106c5776a..a18785a827dc 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -915,7 +915,7 @@ CONFIG_DMADEVICES=y
 CONFIG_DMA_BCM2835=y
 CONFIG_DMA_SUN6I=m
 CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:06 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:06 +0100
Subject: [PATCH v1 06/14] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-7-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Realtek Gigabit Ethernet driver as a module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index a18785a827dc..86d39d8456c1 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -338,6 +338,7 @@ CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
 CONFIG_QCOM_EMAC=m
 CONFIG_RMNET=m
+CONFIG_R8169=m
 CONFIG_SH_ETH=y
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:07 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:07 +0100
Subject: [PATCH v1 07/14] arm64: defconfig: build ads1015 adc driver as a
 module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-8-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Texas Instruments ADS1015 ADC IIO driver as a module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 86d39d8456c1..1d0fe0bd0059 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1071,6 +1071,7 @@ CONFIG_QCOM_SPMI_VADC=m
 CONFIG_QCOM_SPMI_ADC5=m
 CONFIG_ROCKCHIP_SARADC=m
 CONFIG_RZG2L_ADC=m
+CONFIG_TI_ADS1015=m
 CONFIG_IIO_CROS_EC_SENSORS_CORE=m
 CONFIG_IIO_CROS_EC_SENSORS=m
 CONFIG_IIO_ST_LSM6DSX=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:08 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:08 +0100
Subject: [PATCH v1 08/14] arm64: defconfig: build lm75 temperature sensor
 driver as a module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-9-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Maxim Integrated LM75 temperature sensor driver as a module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 1d0fe0bd0059..b4fd61fda35d 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -541,6 +541,7 @@ CONFIG_CHARGER_BQ25980=m
 CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
+CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_PWM_FAN=m
 CONFIG_SENSORS_RASPBERRYPI_HWMON=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:09 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:09 +0100
Subject: [PATCH v1 09/14] arm64: defconfig: build mcp251xfd can as a module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-10-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Microchip MCP251XFD CAN (CONFIG_CAN_MCP251XFD) as a module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b4fd61fda35d..870404a1957d 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -173,6 +173,7 @@ CONFIG_CAN=m
 CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
+CONFIG_CAN_MCP251XFD=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
 # CONFIG_BT_LE is not set
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:10 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:10 +0100
Subject: [PATCH v1 10/14] arm64: defconfig: build sdio mwifiex as a module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-11-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build NXP (formerly Marvell) SDIO MWIFIEX (CONFIG_MWIFIEX_SDIO) as a
module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 870404a1957d..cb99bd97e736 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -380,6 +380,7 @@ CONFIG_ATH10K_SNOC=m
 CONFIG_WCN36XX=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
 CONFIG_MWIFIEX_PCIE=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:04 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:04 +0100
Subject: [PATCH v1 04/14] arm64: defconfig: enable bpf/cgroup firewalling
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-5-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids the following systemd warning:

[    2.618538] systemd[1]: system-getty.slice: unit configures an IP
 firewall, but the local system does not support BPF/cgroup firewalling.
[    2.630916] systemd[1]: (This warning is only shown for the first
 unit using IP firewalling.)

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 79e4bf9f4c2c..3c8106c5776a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_BPF_JIT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -18,6 +19,7 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:11 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:11 +0100
Subject: [PATCH v1 11/14] arm64: defconfig: build nxp bluetooth as modules
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-12-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build NXP (formerly Marvell) SDIO as well as UART based Bluetooth
(CONFIG_BT_HCIUART_MRVL, CONFIG_BT_MRVL and CONFIG_BT_MRVL_SDIO) as
modules.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cb99bd97e736..fe4da2a167ff 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -184,6 +184,9 @@ CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_LL=y
 CONFIG_BT_HCIUART_BCM=y
 CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
 CONFIG_BT_QCOMSMD=m
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:12 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:12 +0100
Subject: [PATCH v1 12/14] arm64: defconfig: build nuvoton nau8822 as module
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-13-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Nuvoton NAU8822 sound SoC driver as a module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index fe4da2a167ff..c6140cdd461c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -789,6 +789,7 @@ CONFIG_SND_SOC_WM8960=m
 CONFIG_SND_SOC_WM8962=m
 CONFIG_SND_SOC_WM8978=m
 CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_NAU8822=m
 CONFIG_SND_SOC_LPASS_WSA_MACRO=m
 CONFIG_SND_SOC_LPASS_VA_MACRO=m
 CONFIG_SND_SIMPLE_CARD=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:00 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:00 +0100
Subject: [PATCH v1 00/14] arm64: prepare and add verdin imx8m mini support
Message-ID: <20220107180314.1816515-1-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>


Fix strange hex notation and gpio-hog example, rebuild default
configuration, enable various relevant configuration options mainly to
be built as modules, add toradex,verdin-imx8mm et al. to dt-bindings and
finally add initial support for verdin imx8m mini.


Marcel Ziswiler (14):
  arm64: dts: imx8mm: fix strange hex notation
  dt-bindings: gpio: fix gpio-hog example
  arm64: defconfig: rebuild default configuration
  arm64: defconfig: enable bpf/cgroup firewalling
  arm64: defconfig: build imx-sdma as a module
  arm64: defconfig: build r8169 as a module
  arm64: defconfig: build ads1015 adc driver as a module
  arm64: defconfig: build lm75 temperature sensor driver as a module
  arm64: defconfig: build mcp251xfd can as a module
  arm64: defconfig: build sdio mwifiex as a module
  arm64: defconfig: build nxp bluetooth as modules
  arm64: defconfig: build nuvoton nau8822 as module
  dt-bindings: arm: fsl: add toradex,verdin-imx8mm et al.
  arm64: dts: freescale: add initial support for verdin imx8m mini

 .../devicetree/bindings/arm/fsl.yaml          |   21 +
 .../devicetree/bindings/gpio/gpio.txt         |    2 +-
 arch/arm64/boot/dts/freescale/Makefile        |    4 +
 .../arm64/boot/dts/freescale/imx8mm-pinfunc.h |    6 +-
 .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  143 ++
 .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
 .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
 .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
 .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
 .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
 .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1277 +++++++++++++++++
 arch/arm64/configs/defconfig                  |  148 +-
 14 files changed, 1820 insertions(+), 90 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi

-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:14 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:14 +0100
Subject: [PATCH v1 14/14] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-15-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This patch adds the device tree to support Toradex Verdin iMX8M Mini a
computer on module which can be used on different carrier boards.

The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
Wi-Fi module.

Anything that is not self-contained on the module is disabled by
default.

The device tree for the Dahlia includes the module's device tree and
enables the supported peripherals of the carrier board.

The device tree for the Verdin Development Board includes the module's
device tree as well as the Dahlia one as it is a superset and supports
almost all peripherals available.

So far there is no display functionality supported at all but basic
console UART, USB host, eMMC and Ethernet and PCIe functionality work
fine.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

 arch/arm64/boot/dts/freescale/Makefile        |    4 +
 .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  143 ++
 .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
 .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
 .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
 .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
 .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
 .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1277 +++++++++++++++++
 10 files changed, 1733 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 6d8f0a532587..04380f2e44a2 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -63,6 +63,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2pro.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
new file mode 100644
index 000000000000..b5bf025c74a2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-wm8904";
+		simple-audio-card,routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"IN2L", "Line In Jack",
+			"IN2R", "Line In Jack",
+			"Headphone Jack", "MICBIAS",
+			"IN1L", "Headphone Jack";
+		simple-audio-card,widgets =
+			"Microphone", "Headphone Jack",
+			"Headphone", "Headphone Jack",
+			"Line", "Line In Jack";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&wm8904_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+	status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+	status = "okay";
+};
+
+&fec1 {
+	status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+	status = "okay";
+};
+
+&hwmon_temp {
+	vs-supply = <&reg_1p8v>;
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	status = "okay";
+
+	/* Audio Codec */
+	wm8904_1a: codec at 1a {
+		compatible = "wlf,wm8904";
+		AVDD-supply = <&reg_3p3v>;
+		clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+		clock-names = "mclk";
+		CPVDD-supply = <&reg_3p3v>;
+		DBVDD-supply = <&reg_3p3v>;
+		DCVDD-supply = <&reg_3p3v>;
+		MICVDD-supply = <&reg_3p3v>;
+		reg = <0x1a>;
+		#sound-dai-cells = <0>;
+	};
+};
+
+/* Verdin PCIE_1 */
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	status = "okay";
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+	status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
new file mode 100644
index 000000000000..f35d22dc546b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-nau8822";
+		simple-audio-card,routing =
+			"Headphones", "LHP",
+			"Headphones", "RHP",
+			"Speaker", "LSPK",
+			"Speaker", "RSPK",
+			"Line Out", "AUXOUT1",
+			"Line Out", "AUXOUT2",
+			"LAUX", "Line In",
+			"RAUX", "Line In",
+			"LMICP", "Mic In",
+			"RMICP", "Mic In";
+		simple-audio-card,widgets =
+			"Headphones", "Headphones",
+			"Line Out", "Line Out",
+			"Speaker", "Speaker",
+			"Microphone", "Mic In",
+			"Line", "Line In";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&nau8822_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+&gpio_expander_21 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	/* Audio Codec */
+	nau8822_1a: codec at 1a {
+		compatible = "nuvoton,nau8822";
+		reg = <0x1a>;
+	};
+};
+
+/* Verdin UART_1, connector X50 through RS485 transceiver */
+&uart2 {
+	linux,rs485-enabled-at-boot-time;
+	rs485-rts-active-low;
+	rs485-rx-during-tx;
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+	max-frequency = <100000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
new file mode 100644
index 000000000000..d64ff378a152
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dahlia",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
new file mode 100644
index 000000000000..6ae71ecac8de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dev",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
new file mode 100644
index 000000000000..9aff9dde1a02
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "SODIMM_162",
+			  "SODIMM_164",
+			  "SODIMM_166",
+			  "SODIMM_168",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "SODIMM_156",
+			  "SODIMM_160",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "SODIMM_148",
+			  "SODIMM_152",
+			  "SODIMM_154",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "SODIMM_150",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
+
+&usdhc3 {
+	bus-width = <4>;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
new file mode 100644
index 000000000000..d424c475cba1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dahlia",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
new file mode 100644
index 000000000000..ef952021832e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dev",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
new file mode 100644
index 000000000000..c400770c1df5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	reg_wifi_en: regulator-wifi-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "PDn_AW-CM276NF";
+		startup-delay-us = <2000>;
+	};
+};
+
+/* On-module Wi-Fi */
+&usdhc3 {
+	bus-width = <4>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_wifi_ctrl>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_wifi_ctrl>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_wifi_ctrl>;
+	vmmc-supply = <&reg_wifi_en>;
+	wifi-host;
+	status = "okay";
+};
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
new file mode 100644
index 000000000000..23eb695a5266
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -0,0 +1,1277 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mm.dtsi"
+
+/ {
+	chosen {
+		bootargs = "console=ttymxc0,115200 earlycon";
+		stdout-path = &uart1;
+	};
+
+	aliases {
+		rtc0 = &rtc_i2c;
+		rtc1 = &snvs_rtc;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 45 63 88 119 158 203 255>;
+		default-brightness-level = <4>;
+		/* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+		enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+		power-supply = <&reg_3p3v>;
+		/* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+		pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+		status = "disabled";
+	};
+
+	/* Fixed clock dedicated to SPI CAN controller */
+	clk20m: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <20000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		wakeup {
+			debounce-interval = <10>;
+			/* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+			gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+			label = "Wake-Up";
+			linux,code = <KEY_WAKEUP>;
+			wakeup-source;
+		};
+	};
+
+	/* Carrier Board Supplies */
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-name = "+V1.8_SW";
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SW";
+	};
+
+	reg_5p0v: regulator-5p0v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "+V5_SW";
+	};
+
+	/* Non PMIC On-module Supplies */
+	reg_ethphy: regulator-ethphy {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+		off-on-delay = <500000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_eth>;
+		regulator-boot-on;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_ETH";
+		startup-delay-us = <200000>;
+	};
+
+	reg_usb_otg1_vbus: regulator-usb-otg1 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_1_EN (SODIMM 155) */
+		gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb1_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg1_vbus";
+	};
+
+	reg_usb_otg2_vbus: regulator-usb-otg2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_2_EN (SODIMM 185) */
+		gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb2_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg2_vbus";
+	};
+
+	reg_usdhc2_vmmc: regulator-usdhc2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin SD_1_PWR_EN (SODIMM 76) */
+		gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+		off-on-delay = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SD";
+		startup-delay-us = <2000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* Use the kernel configuration settings instead */
+		/delete-node/ linux,cma;
+
+		rpmsg_reserved: rpmsg at b8000000 {
+			no-map;
+			reg = <0 0xb8000000 0 0x400000>;
+		};
+	};
+};
+
+&A53_0 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_1 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_2 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_3 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&ddrc {
+	operating-points-v2 = <&ddrc_opp_table>;
+
+	ddrc_opp_table: opp-table {
+		compatible = "operating-points-v2";
+
+		opp-25M {
+			opp-hz = /bits/ 64 <25000000>;
+		};
+
+		opp-100M {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+
+		opp-750M {
+			opp-hz = /bits/ 64 <750000000>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+};
+
+/* Verdin CAN_1 and CAN_2 (On-module) */
+&ecspi3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>,
+		   <&gpio1 5 GPIO_ACTIVE_LOW>;
+	spi-num-chipselects = <2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi3>;
+	status = "okay";
+
+	can1: can at 0 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 6 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can1_int>;
+		reg = <0>;
+		spi-max-frequency = <8500000>;
+	};
+
+	can2: can at 1 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 7 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can2_int>;
+		reg = <1>;
+		spi-max-frequency = <8500000>;
+		/* Not assembled on regular SKUs */
+		status = "disabled";
+	};
+};
+
+/* Verdin ETH_1 (On-module PHY) */
+&fec1 {
+	fsl,magic-packet;
+	phy-handle = <&ethphy0>;
+	phy-mode = "rgmii-id";
+	phy-supply = <&reg_ethphy>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_fec1>;
+	pinctrl-1 = <&pinctrl_fec1_sleep>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy at 7 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+			micrel,led-mode = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexspi0>;
+#if 0
+	flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <80000000>;
+	};
+#endif
+};
+
+&gpio1 {
+	gpio-line-names = "SODIMM_216",
+			  "SODIMM_19",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_220",
+			  "SODIMM_222",
+			  "",
+			  "SODIMM_218",
+			  "SODIMM_155",
+			  "SODIMM_157",
+			  "SODIMM_185",
+			  "SODIMM_187";
+};
+
+&gpio2 {
+	gpio-line-names = "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_84",
+			  "SODIMM_78",
+			  "SODIMM_74",
+			  "SODIMM_80",
+			  "SODIMM_82",
+			  "SODIMM_70",
+			  "SODIMM_72";
+};
+
+&gpio5 {
+	gpio-line-names = "SODIMM_131",
+			  "",
+			  "SODIMM_91",
+			  "SODIMM_16",
+			  "SODIMM_15",
+			  "SODIMM_208",
+			  "SODIMM_137",
+			  "SODIMM_139",
+			  "SODIMM_141",
+			  "SODIMM_143",
+			  "SODIMM_196",
+			  "SODIMM_200",
+			  "SODIMM_198",
+			  "SODIMM_202",
+			  "",
+			  "",
+			  "SODIMM_55",
+			  "SODIMM_53",
+			  "SODIMM_95",
+			  "SODIMM_93",
+			  "SODIMM_14",
+			  "SODIMM_12",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_210",
+			  "SODIMM_212",
+			  "SODIMM_151",
+			  "SODIMM_153";
+
+	ctrl_sleep_moci-hog {
+		gpio-hog;
+		/* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+		gpios = <1 GPIO_ACTIVE_HIGH>;
+		line-name = "CTRL_SLEEP_MOCI#";
+		output-high;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+	};
+};
+
+/* On-module I2C */
+&i2c1 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+
+	pca9450: pmic at 25 {
+		compatible = "nxp,pca9450a";
+		interrupt-parent = <&gpio1>;
+		/* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pmic>;
+		reg = <0x25>;
+		sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			reg_vdd_soc: BUCK1 {
+				nxp,dvs-run-voltage = <850000>;
+				nxp,dvs-standby-voltage = <800000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <850000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+VDD_SOC";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_arm: BUCK2 {
+				nxp,dvs-run-voltage = <950000>;
+				nxp,dvs-standby-voltage = <850000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_ARM";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_dram: BUCK3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_GPU_VPU_DDR";
+			};
+
+			reg_vdd_3v3: BUCK4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <3300000>;
+				regulator-name = "+V3.3";
+			};
+
+			reg_vdd_1v8: BUCK5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "PWR_1V8_MOCI";
+			};
+
+			reg_nvcc_dram: BUCK6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1100000>;
+				regulator-min-microvolt = <1100000>;
+				regulator-name = "+VDD_DDR";
+			};
+
+			reg_nvcc_snvs: LDO1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8_SNVS";
+			};
+
+			reg_vdd_snvs: LDO2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+V0.8_SNVS";
+			};
+
+			reg_vdda: LDO3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8A";
+			};
+
+			reg_vdd_phy: LDO4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <900000>;
+				regulator-name = "+V0.9_MIPI";
+			};
+
+			reg_nvcc_sd: LDO5 {
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V3.3_1.8_SD";
+			};
+		};
+	};
+
+	rtc_i2c: rtc at 32 {
+		compatible = "epson,rx8130";
+		reg = <0x32>;
+	};
+
+	adc at 49 {
+		compatible = "ti,ads1015";
+		reg = <0x49>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Verdin I2C_1 (ADC_4 - ADC_3) */
+		channel at 0 {
+			reg = <0>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_4 - ADC_1) */
+		channel at 1 {
+			reg = <1>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_3 - ADC_1) */
+		channel at 2 {
+			reg = <2>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_2 - ADC_1) */
+		channel at 3 {
+			reg = <3>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_4 */
+		channel at 4 {
+			reg = <4>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_3 */
+		channel at 5 {
+			reg = <5>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_2 */
+		channel at 6 {
+			reg = <6>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_1 */
+		channel at 7 {
+			reg = <7>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+	};
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+	clock-frequency = <10000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "disabled";
+};
+
+/* Verdin I2C_3_HDMI N/A */
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	pinctrl-1 = <&pinctrl_i2c4_gpio>;
+	scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+	gpio_expander_21: gpio-expander at 21 {
+		compatible = "nxp,pcal6416";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x21>;
+		status = "disabled";
+		vcc-supply = <&reg_3p3v>;
+	};
+
+	lvds_ti_sn65dsi83: bridge at 2c {
+		compatible = "ti,sn65dsi83";
+		/* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		enable-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+		reg = <0x2c>;
+		status = "disabled";
+	};
+
+	/* Current measurement into module VCC */
+	hwmon: hwmon at 40 {
+		compatible = "ti,ina219";
+		reg = <0x40>;
+		shunt-resistor = <10000>;
+		status = "disabled";
+	};
+
+	hdmi_lontium_lt8912: hdmi at 48 {
+		compatible = "lontium,lt8912b";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+		reg = <0x48>;
+		/* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+		status = "disabled";
+	};
+
+	atmel_mxt_ts: touch at 4a {
+		compatible = "atmel,maxtouch";
+		/* Verdin GPIO_9_DSI */
+		/* (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused) */
+		interrupt-parent = <&gpio3>;
+		interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+		reg = <0x4a>;
+		/* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
+
+	/* Temperature sensor on carrier board */
+	hwmon_temp: sensor at 4f {
+		compatible = "ti,tmp75c";
+		reg = <0x4f>;
+		status = "disabled";
+	};
+
+	/* EEPROM on display adapter (MIPI DSI Display Adapter) */
+	eeprom_display_adapter: eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+		status = "disabled";
+	};
+
+	/* EEPROM on carrier board */
+	eeprom_carrier_board: eeprom at 57 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x57>;
+		status = "disabled";
+	};
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_1>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_2>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_3>;
+	#pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	#sound-dai-cells = <0>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <24576000>;
+	assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+};
+
+&snvs_pwrkey {
+	status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux console */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_4 */
+/*
+ * Resource allocated to M4 by default, must not be accessed from Cortex-A35 or you get an OOPS
+ */
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&usbmisc1 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+&usbmisc2 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	adp-disable;
+	dr_mode = "otg";
+	hnp-disable;
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	srp-disable;
+	vbus-supply = <&reg_usb_otg1_vbus>;
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	dr_mode = "host";
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	vbus-supply = <&reg_usb_otg2_vbus>;
+};
+
+&usbphynop1 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+&usbphynop2 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+	bus-width = <8>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	pm-ignore-notify;
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	bus-width = <4>;
+	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+&wdog1 {
+	fsl,ext-reset-output;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+		    <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+		    <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+		    <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+		    <&pinctrl_pmic_tpm_ena>;
+
+	pinctrl_can1_int: can1intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6		0x1c4>;	/* CAN_1_SPI_INT#_1.8V */
+	};
+
+	pinctrl_can2_int: can2intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7		0x1c4>;	/* CAN_2_SPI_INT#_1.8V */
+	};
+
+	pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1		0x1c4>;	/* SODIMM 256 */
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK		0x4>,	/* SODIMM 196 */
+			<MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI		0x4>,	/* SODIMM 200 */
+			<MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO		0x1c4>,	/* SODIMM 198 */
+			<MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13		0x1c4>;	/* SODIMM 202 */
+	};
+
+	pinctrl_ecspi3: ecspi3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK		0x4>,	/* CAN_SPI_SCK_1.8V */
+			<MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI		0x4>,	/* CAN_SPI_MOSI_1.8V */
+			<MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO		0x1c4>,	/* CAN_SPI_MISO_1.8V */
+			<MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25		0x1c4>,	/* CAN_1_SPI_CS_1.8V# */
+			<MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5		0x1c4>;	/* CAN_2_SPI_CS#_1.8V */
+	};
+
+	pinctrl_fec1: fec1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x1c4>;
+	};
+
+	pinctrl_fec1_sleep: fec1-sleepgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_GPIO1_IO23		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22		0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x184>;
+	};
+
+	pinctrl_flexspi0: flexspi0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK		0x1c2>,	/* SODIMM 52 */
+			<MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B		0x82>,	/* SODIMM 54 */
+			<MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B		0x82>,	/* SODIMM 64 */
+			<MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS		0x82>,	/* SODIMM 66 */
+			<MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0		0x82>,	/* SODIMM 56 */
+			<MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1		0x82>,	/* SODIMM 58 */
+			<MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2		0x82>,	/* SODIMM 60 */
+			<MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3		0x82>;	/* SODIMM 62 */
+	};
+
+	pinctrl_gpio1: gpio1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4		0x184>;	/* SODIMM 206 */
+	};
+
+	pinctrl_gpio2: gpio2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5		0x1c4>;	/* SODIMM 208 */
+	};
+
+	pinctrl_gpio3: gpio3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26		0x184>;	/* SODIMM 210 */
+	};
+
+	pinctrl_gpio4: gpio4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27		0x184>;	/* SODIMM 212 */
+	};
+
+	pinctrl_gpio5: gpio5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0		0x184>;	/* SODIMM 216 */
+	};
+
+	pinctrl_gpio6: gpio6grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11		0x184>;	/* SODIMM 218 */
+	};
+
+	pinctrl_gpio7: gpio7grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x184>;	/* SODIMM 220 */
+	};
+
+	pinctrl_gpio8: gpio8grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x184>;	/* SODIMM 222 */
+	};
+
+	/* Verdin GPIO_9_DSI (pulled-up as active-low) */
+	pinctrl_gpio_9_dsi: gpio9dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15		0x1c4>;	/* SODIMM 17 */
+	};
+
+	/* Verdin GPIO_10_DSI */
+	pinctrl_gpio_10_dsi: gpio10dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3		0x1c4>;	/* SODIMM 21 */
+	};
+
+	pinctrl_gpio_hog1: gpiohog1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20		0x1c4>,	/* SODIMM 88 */
+			<MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1		0x1c4>,	/* SODIMM 90 */
+			<MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2		0x1c4>,	/* SODIMM 92 */
+			<MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3		0x1c4>,	/* SODIMM 94 */
+			<MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4		0x1c4>,	/* SODIMM 96 */
+			<MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5		0x1c4>,	/* SODIMM 100 */
+			<MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0		0x1c4>,	/* SODIMM 102 */
+			<MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11		0x1c4>,	/* SODIMM 104 */
+			<MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12		0x1c4>,	/* SODIMM 106 */
+			<MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13		0x1c4>,	/* SODIMM 108 */
+			<MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14		0x1c4>,	/* SODIMM 112 */
+			<MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15		0x1c4>,	/* SODIMM 114 */
+			<MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16		0x1c4>,	/* SODIMM 116 */
+			<MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18		0x1c4>,	/* SODIMM 118 */
+			<MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10		0x1c4>;	/* SODIMM 120 */
+	};
+
+	pinctrl_gpio_hog2: gpiohog2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2		0x1c4>;	/* SODIMM 91 */
+	};
+
+	pinctrl_gpio_hog3: gpiohog3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13		0x1c4>,	/* SODIMM 157 */
+			<MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15		0x1c4>;	/* SODIMM 187 */
+	};
+
+	pinctrl_gpio_keys: gpiokeysgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28		0x1c4>;	/* SODIMM 252 */
+	};
+
+	/* On-module I2C */
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	pinctrl_i2c1_gpio: i2c1gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14		0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15		0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	/* Verdin I2C_4_CSI */
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL			0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA			0x400001c6>;	/* SODIMM 53 */
+	};
+
+	pinctrl_i2c2_gpio: i2c2gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16		0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17		0x400001c6>;	/* SODIMM 53 */
+	};
+
+	/* Verdin I2C_2_DSI */
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL			0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400001c6>;	/* SODIMM 93 */
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18		0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19		0x400001c6>;	/* SODIMM 93 */
+	};
+
+	/* Verdin I2C_1 */
+	pinctrl_i2c4: i2c4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c6>;	/* SODIMM 12 */
+	};
+
+	pinctrl_i2c4_gpio: i2c4gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20		0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21		0x400001c6>;	/* SODIMM 12 */
+	};
+
+	/* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+	pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23		0x184>;	/* SODIMM 42 */
+	};
+
+	/* Verdin I2S_2_D_OUT shared with SAI5 */
+	pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24		0x184>;	/* SODIMM 46 */
+	};
+
+	pinctrl_pcie0: pcie0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19		0x6>,	/* SODIMM 244 */
+			/* PMIC_EN_PCIe_CLK, unused */
+			<MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19		0x6>;
+	};
+
+	pinctrl_pmic: pmicirqgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x41>;	/* PMIC_INT# */
+	};
+
+	/* Verdin PWM_3_DSI shared with GPIO1_IO1 */
+	pinctrl_pwm_1: pwm1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT		0x6>;	/* SODIMM 19 */
+	};
+
+	pinctrl_pwm_2: pwm2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT			0x6>;	/* SODIMM 15 */
+	};
+
+	pinctrl_pwm_3: pwm3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT			0x6>;	/* SODIMM 16 */
+	};
+
+	/* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM1_OUT */
+	pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsihpdgpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1		0x184>;	/* SODIMM 19 */
+	};
+
+	pinctrl_reg_eth: regethgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_WP_GPIO2_IO20			0x184>;	/* PMIC_EN_ETH */
+	};
+
+	pinctrl_reg_usb1_en: regusb1engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12		0x184>;	/* SODIMM 155 */
+	};
+
+	pinctrl_reg_usb2_en: regusb2engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14		0x184>;	/* SODIMM 185 */
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC		0xd6>,	/* SODIMM 32 */
+			<MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK		0xd6>,	/* SODIMM 30 */
+			<MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK		0xd6>,	/* SODIMM 38 */
+			<MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0		0xd6>,	/* SODIMM 36 */
+			<MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0		0xd6>;	/* SODIMM 34 */
+	};
+
+	pinctrl_sai5: sai5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0		0xd6>,	/* SODIMM 48 */
+			<MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC		0xd6>,	/* SODIMM 44 */
+			<MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK		0xd6>,	/* SODIMM 42 */
+			<MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0		0xd6>;	/* SODIMM 46 */
+	};
+
+	/* control signal for optional ATTPM20P or SE050 */
+	pinctrl_pmic_tpm_ena: pmictpmenagrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19		0x1c4>;	/* PMIC_TPM_ENA */
+	};
+
+	pinctrl_tsp: tspgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6		0x140>,	/* SODIMM 148 */
+			<MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7		0x140>,	/* SODIMM 152 */
+			<MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8		0x140>,	/* SODIMM 154 */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x140>,	/* SODIMM 179 */
+			<MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17		0x140>;	/* SODIMM 150 */
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x1c4>,	/* SODIMM 149 */
+			<MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x1c4>;	/* SODIMM 147 */
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x1c4>,	/* SODIMM 129 */
+			<MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x1c4>,	/* SODIMM 131 */
+			<MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x1c4>,	/* SODIMM 133 */
+			<MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x1c4>;	/* SODIMM 135 */
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX		0x1c4>,	/* SODIMM 137 */
+			<MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX		0x1c4>,	/* SODIMM 139 */
+			<MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B	0x1c4>,	/* SODIMM 141 */
+			<MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B	0x1c4>;	/* SODIMM 143 */
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX		0x1c4>,	/* SODIMM 151 */
+			<MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX		0x1c4>;	/* SODIMM 153 */
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x190>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d0>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x190>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x194>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d4>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x194>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x196>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d6>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x196>;
+	};
+
+	pinctrl_usdhc2_cd: usdhc2cdgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x1c4>;	/* SODIMM 84 */
+	};
+
+	pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5		0x184>;	/* SODIMM 76 */
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x190>,	/* SODIMM 78 */
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d0>,	/* SODIMM 74 */
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0>,	/* SODIMM 80 */
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0>,	/* SODIMM 82 */
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0>,	/* SODIMM 70 */
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0>,	/* SODIMM 72 */
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x194>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x196>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	/* On-module Wi-Fi/BT or type specific SDHC interface */
+	/* (e.g. on X52 extension slot of Verdin Development Board) */
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x190>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d0>;
+	};
+
+	pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x194>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d4>;
+	};
+
+	pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x196>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d6>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6>;	/* PMIC_WDI */
+	};
+
+	pinctrl_wifi_ctrl: wifictrlgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16		0x1c4>,	/* WIFI_WKUP_BT */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x1c4>,	/* WIFI_W_WKUP_HOST */
+			<MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20		0x1c4>;	/* WIFI_WKUP_WLAN */
+	};
+
+	pinctrl_wifi_i2s: bti2sgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK		0xd6>,	/* WIFI_TX_BCLK */
+			<MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0		0xd6>,	/* WIFI_TX_DATA0 */
+			<MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC		0xd6>,	/* WIFI_TX_SYNC */
+			<MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0		0xd6>;	/* WIFI_RX_DATA0 */
+	};
+
+	pinctrl_wifi_pwr_en: wifipwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25		0x184>;	/* PMIC_EN_WIFI */
+	};
+};
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan  7 10:03:13 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri,  7 Jan 2022 19:03:13 +0100
Subject: [PATCH v1 13/14] dt-bindings: arm: fsl: add toradex,
 verdin-imx8mm et al.
In-Reply-To: <20220107180314.1816515-1-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
Message-ID: <20220107180314.1816515-14-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Add toradex,verdin-imx8mm for our new Verdin iMX8M Mini modules, its
nonwifi and wifi variants and the carrier boards (both Dahlia and the
Verdin Development Board) they may be mated in.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
---

 .../devicetree/bindings/arm/fsl.yaml          | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 97f6eebad76a..9ed61591c6aa 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -770,6 +770,9 @@ properties:
               - gw,imx8mm-gw7901          # i.MX8MM Gateworks Board
               - gw,imx8mm-gw7902          # i.MX8MM Gateworks Board
               - kontron,imx8mm-n801x-som  # i.MX8MM Kontron SL (N801X) SOM
+              - toradex,verdin-imx8mm     # Colibri iMX8M Mini Modules
+              - toradex,verdin-imx8mm-nonwifi  # Colibri iMX8M Mini Modules without Wi-Fi / BT
+              - toradex,verdin-imx8mm-wifi  # Colibri iMX8M Mini Wi-Fi / BT Modules
               - variscite,var-som-mx8mm   # i.MX8MM Variscite VAR-SOM-MX8MM module
           - const: fsl,imx8mm
 
@@ -787,6 +790,24 @@ properties:
           - const: kontron,imx8mm-n801x-som
           - const: fsl,imx8mm
 
+      - description: Toradex Boards with Verdin iMX8M Mini Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-nonwifi-dahlia # Verdin iMX8M Mini Module on Dahlia
+              - toradex,verdin-imx8mm-nonwifi-dev    # Verdin iMX8M Mini Module on Verdin Development Board
+          - const: toradex,verdin-imx8mm-nonwifi     # Colibri iMX8M Mini Module without Wi-Fi / BT
+          - const: toradex,verdin-imx8mm             # Colibri iMX8M Mini Module
+          - const: fsl,imx8mm
+
+      - description: Toradex Boards with Verdin iMX8M Mini Wi-Fi / BT Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-wifi-dahlia # Verdin iMX8M Mini Wi-Fi / BT Module on Dahlia
+              - toradex,verdin-imx8mm-wifi-dev    # Verdin iMX8M Mini Wi-Fi / BT M. on Verdin Development B.
+          - const: toradex,verdin-imx8mm-wifi     # Colibri iMX8M Mini Wi-Fi / BT Module
+          - const: toradex,verdin-imx8mm          # Colibri iMX8M Mini Module
+          - const: fsl,imx8mm
+
       - description: Variscite VAR-SOM-MX8MM based boards
         items:
           - const: variscite,var-som-mx8mm-symphony
-- 
2.33.1



From helgaas at kernel.org  Fri Jan  7 10:15:12 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 12:15:12 -0600
Subject: [PATCH 03/15] PCI: mvebu: Check that PCI bridge specified in DT
 has function number zero
In-Reply-To: <20211125124605.25915-4-pali@kernel.org>
Message-ID: <20220107181512.GA390598@bhelgaas>

On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Roh?r wrote:
> Driver cannot handle PCI bridges at non-zero function address. So add
> appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> function to zero.

Why can the driver not handle bridges at non-zero function addresses?
The PCI spec allows that, doesn't it?  Is this a hardware limitation?

> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Cc: stable at vger.kernel.org
> ---
>  drivers/pci/controller/pci-mvebu.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 6197f7e7c317..08274132cdfb 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  	port->devfn = of_pci_get_devfn(child);
>  	if (port->devfn < 0)
>  		goto skip;
> +	if (PCI_FUNC(port->devfn) != 0) {
> +		dev_err(dev, "%s: invalid function number, must be zero\n",
> +			port->name);
> +		goto skip;
> +	}
>  
>  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
>  				 &port->mem_target, &port->mem_attr);
> -- 
> 2.20.1
> 


From pali at kernel.org  Fri Jan  7 10:18:19 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 19:18:19 +0100
Subject: [PATCH 03/15] PCI: mvebu: Check that PCI bridge specified in DT
 has function number zero
In-Reply-To: <20220107181512.GA390598@bhelgaas>
References: <20211125124605.25915-4-pali@kernel.org>
 <20220107181512.GA390598@bhelgaas>
Message-ID: <20220107181819.yiya3mxhtfsnubg4@pali>

On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Roh?r wrote:
> > Driver cannot handle PCI bridges at non-zero function address. So add
> > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > function to zero.
> 
> Why can the driver not handle bridges at non-zero function addresses?
> The PCI spec allows that, doesn't it?  Is this a hardware limitation?

It is software / kernel limitation.

Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
this driver can emulate only single function PCI-to-PCI bridge device.

> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 6197f7e7c317..08274132cdfb 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> >  	port->devfn = of_pci_get_devfn(child);
> >  	if (port->devfn < 0)
> >  		goto skip;
> > +	if (PCI_FUNC(port->devfn) != 0) {
> > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > +			port->name);
> > +		goto skip;
> > +	}
> >  
> >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> >  				 &port->mem_target, &port->mem_attr);
> > -- 
> > 2.20.1
> > 


From jose.exposito89 at gmail.com  Fri Jan  7 10:24:51 2022
From: jose.exposito89 at gmail.com (=?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?=)
Date: Fri,  7 Jan 2022 19:24:51 +0100
Subject: [PATCH RESEND v2] clk: mediatek: Fix memory leaks on probe
Message-ID: <20220107182451.139456-1-jose.exposito89@gmail.com>

Handle the error branches to free memory where required.

Addresses-Coverity-ID: 1491825 ("Resource leak")
Signed-off-by: Jos? Exp?sito <jose.exposito89 at gmail.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

---

v2: Add Reviewed-by tag
---
 drivers/clk/mediatek/clk-mt8192.c | 36 +++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
index cbc7c6dbe0f4..79ddb3cc0b98 100644
--- a/drivers/clk/mediatek/clk-mt8192.c
+++ b/drivers/clk/mediatek/clk-mt8192.c
@@ -1236,9 +1236,17 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
 
 	r = mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data);
 	if (r)
-		return r;
+		goto free_clk_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_clk_data;
+
+	return r;
 
-	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+free_clk_data:
+	mtk_free_clk_data(clk_data);
+	return r;
 }
 
 static int clk_mt8192_peri_probe(struct platform_device *pdev)
@@ -1253,9 +1261,17 @@ static int clk_mt8192_peri_probe(struct platform_device *pdev)
 
 	r = mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks), clk_data);
 	if (r)
-		return r;
+		goto free_clk_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_clk_data;
 
-	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	return r;
+
+free_clk_data:
+	mtk_free_clk_data(clk_data);
+	return r;
 }
 
 static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
@@ -1271,9 +1287,17 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
 	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
 	if (r)
-		return r;
+		goto free_clk_data;
 
-	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto free_clk_data;
+
+	return r;
+
+free_clk_data:
+	mtk_free_clk_data(clk_data);
+	return r;
 }
 
 static const struct of_device_id of_match_clk_mt8192[] = {
-- 
2.25.1



From nathan at kernel.org  Fri Jan  7 10:33:03 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 11:33:03 -0700
Subject: [PATCH] clk: visconti: Remove pointless NULL check in
 visconti_pll_add_lookup()
Message-ID: <20220107183303.2337676-1-nathan@kernel.org>

Clang warns:

drivers/clk/visconti/pll.c:292:20: warning: address of array 'ctx->clk_data.hws' will always evaluate to 'true' [-Wpointer-bool-conversion]
        if (ctx->clk_data.hws && id)
            ~~~~~~~~~~~~~~^~~ ~~
1 warning generated.

This array cannot be NULL if ctx is not NULL, which is allocated in
visconti_init_pll(), so just remove the check, which matches other clk
drivers.

Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and reset driver")
Link: https://github.com/ClangBuiltLinux/linux/issues/1564
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 drivers/clk/visconti/pll.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
index 3b6e88bb73d5..a2398bc6c6e4 100644
--- a/drivers/clk/visconti/pll.c
+++ b/drivers/clk/visconti/pll.c
@@ -289,7 +289,7 @@ static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx,
 				    struct clk_hw *hw_clk,
 				    unsigned int id)
 {
-	if (ctx->clk_data.hws && id)
+	if (id)
 		ctx->clk_data.hws[id] = hw_clk;
 }
 

base-commit: 70faf946ad975c64efb2eb809f9139f304a494b0
-- 
2.34.1



From lkp at intel.com  Fri Jan  7 10:36:58 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 8 Jan 2022 02:36:58 +0800
Subject: [arm:cex7 128/187] drivers/net/dsa/mt7530.c:3060:44: error: 'struct
 mt7530_priv' has no member named 'pcs_ops'
Message-ID: <202201080235.iGcVDS38-lkp@intel.com>

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git cex7
head:   c0fd07781c7d7d3a273892450c656e1eede8d221
commit: 53b8fb9411f006389a222c44fc1c08295ddfae2b [128/187] net: dsa: mt7530: partially convert to phylink_pcs  *EXPERIMENTAL*
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220108/202201080235.iGcVDS38-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git remote add arm git://git.armlinux.org.uk/~rmk/linux-arm.git
        git fetch --no-tags arm cex7
        git checkout 53b8fb9411f006389a222c44fc1c08295ddfae2b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/net/dsa/mt7530.c:3026:25: error: initialization of 'int (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' from incompatible pointer type 'void (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' [-Werror=incompatible-pointer-types]
    3026 |         .pcs_validate = mt753x_pcs_validate,
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3026:25: note: (near initialization for 'mt7530_pcs_ops.pcs_validate')
   drivers/net/dsa/mt7530.c:3033:25: error: initialization of 'int (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' from incompatible pointer type 'void (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' [-Werror=incompatible-pointer-types]
    3033 |         .pcs_validate = mt753x_pcs_validate,
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3033:25: note: (near initialization for 'mt7531_pcs_ops.pcs_validate')
   drivers/net/dsa/mt7530.c: In function 'mt753x_setup':
>> drivers/net/dsa/mt7530.c:3060:44: error: 'struct mt7530_priv' has no member named 'pcs_ops'
    3060 |                 priv->pcs[i].pcs.ops = priv->pcs_ops;
         |                                            ^~
   cc1: some warnings being treated as errors


vim +3060 drivers/net/dsa/mt7530.c

  3039	
  3040	static int
  3041	mt753x_setup(struct dsa_switch *ds)
  3042	{
  3043		struct mt7530_priv *priv = ds->priv;
  3044		int ret = priv->info->sw_setup(ds);
  3045		int i;
  3046	
  3047		if (ret)
  3048			return ret;
  3049	
  3050		ret = mt7530_setup_irq(priv);
  3051		if (ret)
  3052			return ret;
  3053	
  3054		ret = mt7530_setup_mdio(priv);
  3055		if (ret && priv->irq)
  3056			mt7530_free_irq_common(priv);
  3057	
  3058		/* Initialise the PCS devices */
  3059		for (i = 0; i < priv->ds->num_ports; i++) {
> 3060			priv->pcs[i].pcs.ops = priv->pcs_ops;
  3061			priv->pcs[i].priv = priv;
  3062			priv->pcs[i].port = i;
  3063		}
  3064	
  3065		return ret;
  3066	}
  3067	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From yuzhao at google.com  Fri Jan  7 10:45:40 2022
From: yuzhao at google.com (Yu Zhao)
Date: Fri, 7 Jan 2022 11:45:40 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>
Message-ID: <YdiKVJlClB3h1Kmg@google.com>

On Fri, Jan 07, 2022 at 10:38:18AM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:30:00, Yu Zhao wrote:
> [...]
> > Hi Andrew, Linus,
> > 
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> 
> I am still not done with the review and have seen at least few problems
> that would need to be addressed.
> 
> But more fundamentally I believe there are really some important
> questions to be answered. First and foremost this is a major addition
> to the memory reclaim and there should be a wider consensus that we
> really want to go that way. The patchset doesn't have a single ack nor
> reviewed-by AFAICS. I haven't seen a lot of discussion since v2
> (http://lkml.kernel.org/r/20210413065633.2782273-1-yuzhao at google.com)
> nor do I see any clarification on how concerns raised there have been
> addressed or at least how they are planned to be addressed.
> 
> Johannes has made some excellent points
> http://lkml.kernel.org/r/YHcpzZYD2fQyWvEQ at cmpxchg.org. Let me quote
> for reference part of it I find the most important:
> : Realistically, I think incremental changes are unavoidable to get this
> : merged upstream.
> : 
> : Not just in the sense that they need to be smaller changes, but also
> : in the sense that they need to replace old code. It would be
> : impossible to maintain both, focus development and testing resources,
> : and provide a reasonably stable experience with both systems tugging
> : at a complicated shared code base.
> : 
> : On the other hand, the existing code also has billions of hours of
> : production testing and tuning. We can't throw this all out overnight -
> : it needs to be surgical and the broader consequences of each step need
> : to be well understood.
> : 
> : We also have millions of servers relying on being able to do upgrades
> : for drivers and fixes in other subsystems that we can't put on hold
> : until we stabilized a new reclaim implementation from scratch.
> 
> Fully agreed on all points here.
> 
> I do appreciate there is a lot of work behind this patchset and I
> also do understand it has gained a considerable amount of testing as
> well. Your numbers are impressive but my experience tells me that it is
> equally important to understand the worst case behavior and there is not
> really much mentioned about those in changelogs.
> 
> We also shouldn't ignore costs the code is adding. One of them would be
> a further page flags depletion. We have been hitting problems on that
> front for years and many features had to be reworked to bypass a lack of
> space in page->flags.
> 
> I will be looking more into the code (especially the memcg side of it)
> but I really believe that a consensus on above Johannes' points need to
> be found first before this work can move forward.

Thanks for the summary. I appreciate your time and I agree your
assessment is fair.

So I've acknowledged your concerns, and you've acknowledged my numbers
(the performance improvements) are impressive.

Now we are in agreement, cheers.

Next, I argue that the benefits of this patchset outweigh its risks,
because, drawing from my past experience,
1. There have been many larger and/or riskier patchsets taken; I'll
   assemble a list if you disagree. And this patchset is fully guarded
   by #ifdef; Linus has also assessed on this point.
2. There have been none that came with the testing/benchmarking
   coverage as this one did. Please point me to some if I'm mistaken,
   and I'll gladly match them.

The numbers might not materialize in the real world; the code is not
perfect; and many other risks... But all the top eight open source
memory hogs were covered, which is unprecedented; memcached and fio
showed significant improvements and it only takes a few commands to
see for yourselves.

Regarding the acks and the reviewed-bys, I certainly can ask people
who have reaped the benefits of this patchset to do them, if it's
required. But I see less fun in that. I prefer to provide empirical
evidence and convince people who are on the other side of the aisle.


From helgaas at kernel.org  Fri Jan  7 10:45:48 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 12:45:48 -0600
Subject: [PATCH 04/15] PCI: mvebu: Handle invalid size of read config
 request
In-Reply-To: <20211125124605.25915-5-pali@kernel.org>
Message-ID: <20220107184548.GA390934@bhelgaas>

On Thu, Nov 25, 2021 at 01:45:54PM +0100, Pali Roh?r wrote:
> Function mvebu_pcie_hw_rd_conf() does not handle invalid size. So correctly
> set read value to all-ones and return appropriate error return value
> PCIBIOS_BAD_REGISTER_NUMBER like in mvebu_pcie_hw_wr_conf() function.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Cc: stable at vger.kernel.org

Is there a bug that this fixes?  If not, I would drop the stable tag
(as I see Lorenzo already did, thanks!).

> ---
>  drivers/pci/controller/pci-mvebu.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 08274132cdfb..19c6ee298442 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -261,6 +261,9 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
>  	case 4:
>  		*val = readl_relaxed(conf_data);
>  		break;
> +	default:
> +		*val = 0xffffffff;
> +		return PCIBIOS_BAD_REGISTER_NUMBER;

Might be the right thing to do, but there are many config accessors
that do not set *val to ~0 before returning
PCIBIOS_BAD_REGISTER_NUMBER:

  pci_bus_read_config_byte (and word, dword)  # PCI_OP_READ(), *val unchanged
  pci_generic_config_read                     # *val = 32-bit value
  pci_user_read_config_byte (...)             # PCI_USER_READ_CONFIG(), *val unchanged
  sh7786_pcie_read                            # *val unchanged
  dw_pcie_read                                # *val = 0
  mobiveil_pcie_read                          # *val = 0
  faraday_raw_pci_read_config                 # *val = 32-bit value
  ixp4xx_pci_read_config                      # *val unchanged
  orion5x_pci_hw_rd_conf                      # *val = 32-bit value
  orion_pcie_rd_conf                          # *val = 32-bit value
  bonito64_pcibios_read                       # *val = 32-bit value
  loongson_pcibios_read                       # *val = 32-bit value
  msc_pcibios_read                            # *val = 32-bit value
  ar724x_pci_read                             # *val unchanged
  bcm1480_pcibios_read                        # *val = 32-bit value
  _altera_pcie_cfg_read                       # *val = 32-bit value
  rockchip_pcie_rd_own_conf                   # *val = 0
  rockchip_pcie_rd_other_conf                 # *val = 0
  pci_bridge_emul_conf_read                   # may depend on op?

There are more, but I got tired of looking.  I actually didn't see any
that set *val to ~0.

I think the check in PCI_OP_READ() means that most accessors will
never see an invalid "size".

>  	}
>  
>  	return PCIBIOS_SUCCESSFUL;
> -- 
> 2.20.1
> 


From maz at kernel.org  Fri Jan  7 10:53:50 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 07 Jan 2022 18:53:50 +0000
Subject: [PATCH 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220107115053.k5d2uv7yrftrpcez@pali>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-11-pali@kernel.org>
 <87bl0ovq7f.wl-maz@kernel.org>
 <20220106154447.aie6taiuvav5wu6y@pali>
 <878rvsvoyo.wl-maz@kernel.org>
 <20220106162047.vqykmygs75eimfgy@pali>
 <877dbcvngf.wl-maz@kernel.org> <20220106182044.3ff0828c@thinkpad>
 <874k6gvkhz.wl-maz@kernel.org>
 <20220107115053.k5d2uv7yrftrpcez@pali>
Message-ID: <87wnjbtm0x.wl-maz@kernel.org>

On Fri, 07 Jan 2022 11:50:53 +0000,
Pali Roh?r <pali at kernel.org> wrote:
> 
> On Thursday 06 January 2022 17:31:36 Marc Zyngier wrote:
> > On Thu, 06 Jan 2022 17:20:44 +0000,
> > Marek Beh?n <kabel at kernel.org> wrote:
> > > 
> > > On Thu, 06 Jan 2022 16:27:44 +0000
> > > Marc Zyngier <maz at kernel.org> wrote:
> > > > You are completely missing my point. I'm talking about data
> > > > structures, you're talking about interrupts. You have this:
> > > > 
> > > > struct mvebu_pcie_port {
> > > >        // Tons of stuff
> > > >        struct irq_chip intx_chip;
> > > > };
> > > > 
> > > > What I want you to do is:
> > > > 
> > > > struct mvebu_pcie_port {
> > > >        // Tons of stuff
> > > > };
> > > > 
> > > > static struct irq_chip intx_chip = {
> > > > 	.name		= "INTx",
> > > > 	.irq_mask	= mvebu_pcie_intx_irq_mask,
> > > > 	.irq_unmask	= mvebu_pcie_intx_irq_unmask;
> > > > };
> > > > 
> > > > That's it. No more, no less.
> > > > 
> > > > 	M.
> > > > 
> > > 
> > > Hmm, but struct irq_chip contains a dynamic member,
> > >   struct device *parent_device;
> > > Isn't that used? Or are you planning to kill it?
> > 
> > Indeed, and I am definitely planning to kill it. This is the wrong
> > place for this stuff, and I want it gone. There are thankfully very
> > few users of this misfeature.
> 
> Ok, so what about this change?
> 
> @@ -1458,7 +1617,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  		mvebu_writel(port, cmd, PCIE_CMD_OFF);
>  
>  		/* Mask all interrupt sources. */
> -		mvebu_writel(port, 0, PCIE_MASK_OFF);
> +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
> +
> +		/* Clear all interrupt causes. */
> +		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
> +
> +		/* Remove IRQ domains. */
> +		if (port->intx_irq_domain)
> +			irq_domain_remove(port->intx_irq_domain);
> +
> +		if (irq > 0)
> +			irq_set_chained_handler_and_data(irq, NULL, NULL);

You really want this to be done *before* you remove the domain, as
there still could be interrupts in flight at this point.

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Fri Jan  7 11:01:11 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 07 Jan 2022 13:01:11 -0600
Subject: [PATCH v21 1/8] dt-bindings: soc: mediatek: add mtk svs
 dt-bindings
In-Reply-To: <20220107095200.4389-2-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-2-roger.lu@mediatek.com>
Message-ID: <1641582071.084026.3702048.nullmailer@robh.at.kernel.org>

On Fri, 07 Jan 2022 17:51:53 +0800, Roger Lu wrote:
> Document the binding for enabling mtk svs on MediaTek SoC.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
>  .../bindings/soc/mediatek/mtk-svs.yaml        | 84 +++++++++++++++++++
>  1 file changed, 84 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml: properties:nvmem-cells: {'minItems': 1, 'maxItems': 2, 'description': 'Phandle to the calibration data provided by a nvmem device.', 'items': [{'description': 'SVS efuse for SVS controller'}, {'description': 'Thermal efuse for SVS controller'}]} should not be valid under {'required': ['maxItems']}
	hint: "maxItems" is not needed with an "items" list
	from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml: ignoring, error in schema: properties: nvmem-cells
Documentation/devicetree/bindings/soc/mediatek/mtk-svs.example.dt.yaml:0:0: /example-0/soc/svs at 1100b000: failed to match any schema with compatible: ['mediatek,mt8183-svs']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1576508

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh+dt at kernel.org  Fri Jan  7 11:04:37 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 7 Jan 2022 13:04:37 -0600
Subject: [PATCH v8 2/4] dt-bindings: arm: cpus: Add cortex-a78 compatible
In-Reply-To: <20220107115345.9075-3-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
 <20220107115345.9075-3-tinghan.shen@mediatek.com>
Message-ID: <CAL_JsqKctALMWbNytCP7TGKEcCaoOVpm4eHQ3PUHDy2AKrwfmg@mail.gmail.com>

On Fri, Jan 7, 2022 at 5:54 AM Tinghan Shen <tinghan.shen at mediatek.com> wrote:
>
> Add ARM cpu type cortex-a78.
>
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  Documentation/devicetree/bindings/arm/cpus.yaml | 1 +
>  1 file changed, 1 insertion(+)

I already have a patch for this pending for 5.17.

Rob


From lkp at intel.com  Fri Jan  7 11:07:29 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 8 Jan 2022 03:07:29 +0800
Subject: [arm:net-queue 128/174] drivers/net/dsa/mt7530.c:3060:32: error: no
 member named 'pcs_ops' in 'struct mt7530_priv'
Message-ID: <202201080355.pMKHutjh-lkp@intel.com>

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git net-queue
head:   9ceab2608ffe3f543e1118044bc86bc6ccb93255
commit: 0ecdf3ab2ae1d35480614337758d8db5060885cf [128/174] net: dsa: mt7530: partially convert to phylink_pcs  *EXPERIMENTAL*
config: i386-randconfig-a005-20220106 (https://download.01.org/0day-ci/archive/20220108/202201080355.pMKHutjh-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git remote add arm git://git.armlinux.org.uk/~rmk/linux-arm.git
        git fetch --no-tags arm net-queue
        git checkout 0ecdf3ab2ae1d35480614337758d8db5060885cf
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/net/dsa/mt7530.c:3026:18: error: incompatible function pointer types initializing 'int (*)(struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' with an expression of type 'void (struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' [-Werror,-Wincompatible-function-pointer-types]
           .pcs_validate = mt753x_pcs_validate,
                           ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3033:18: error: incompatible function pointer types initializing 'int (*)(struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' with an expression of type 'void (struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' [-Werror,-Wincompatible-function-pointer-types]
           .pcs_validate = mt753x_pcs_validate,
                           ^~~~~~~~~~~~~~~~~~~
>> drivers/net/dsa/mt7530.c:3060:32: error: no member named 'pcs_ops' in 'struct mt7530_priv'
                   priv->pcs[i].pcs.ops = priv->pcs_ops;
                                          ~~~~  ^
   3 errors generated.


vim +3060 drivers/net/dsa/mt7530.c

  3039	
  3040	static int
  3041	mt753x_setup(struct dsa_switch *ds)
  3042	{
  3043		struct mt7530_priv *priv = ds->priv;
  3044		int ret = priv->info->sw_setup(ds);
  3045		int i;
  3046	
  3047		if (ret)
  3048			return ret;
  3049	
  3050		ret = mt7530_setup_irq(priv);
  3051		if (ret)
  3052			return ret;
  3053	
  3054		ret = mt7530_setup_mdio(priv);
  3055		if (ret && priv->irq)
  3056			mt7530_free_irq_common(priv);
  3057	
  3058		/* Initialise the PCS devices */
  3059		for (i = 0; i < priv->ds->num_ports; i++) {
> 3060			priv->pcs[i].pcs.ops = priv->pcs_ops;
  3061			priv->pcs[i].priv = priv;
  3062			priv->pcs[i].port = i;
  3063		}
  3064	
  3065		return ret;
  3066	}
  3067	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From linux at armlinux.org.uk  Fri Jan  7 11:15:26 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Fri, 7 Jan 2022 19:15:26 +0000
Subject: [PATCH 04/15] PCI: mvebu: Handle invalid size of read config
 request
In-Reply-To: <20220107184548.GA390934@bhelgaas>
References: <20211125124605.25915-5-pali@kernel.org>
 <20220107184548.GA390934@bhelgaas>
Message-ID: <YdiRTjGGWelHZ9rA@shell.armlinux.org.uk>

On Fri, Jan 07, 2022 at 12:45:48PM -0600, Bjorn Helgaas wrote:
> On Thu, Nov 25, 2021 at 01:45:54PM +0100, Pali Roh?r wrote:
> > Function mvebu_pcie_hw_rd_conf() does not handle invalid size. So correctly
> > set read value to all-ones and return appropriate error return value
> > PCIBIOS_BAD_REGISTER_NUMBER like in mvebu_pcie_hw_wr_conf() function.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > Cc: stable at vger.kernel.org
> 
> Is there a bug that this fixes?  If not, I would drop the stable tag
> (as I see Lorenzo already did, thanks!).
> 
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 08274132cdfb..19c6ee298442 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -261,6 +261,9 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> >  	case 4:
> >  		*val = readl_relaxed(conf_data);
> >  		break;
> > +	default:
> > +		*val = 0xffffffff;
> > +		return PCIBIOS_BAD_REGISTER_NUMBER;
> 
> Might be the right thing to do, but there are many config accessors
> that do not set *val to ~0 before returning
> PCIBIOS_BAD_REGISTER_NUMBER:

I think a better question would be - how can this function be called
with a size that isn't 1, 2 or 4? I suppose if someone were to add
another PCI_OP_READ/PCI_OP_WRITE. However... they really need to audit
every implementation if they do that.

The generic implementation does this:

        if (size == 1)
                *val = readb(addr);
        else if (size == 2)
                *val = readw(addr);
        else
                *val = readl(addr);

and therefore completely ignores the size if it isn't 1 or 2. So I
don't think this is something that needs fixing.

If we're going to fix this in drivers, shouldn't we fix the generic
implementation too?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mark.kettenis at xs4all.nl  Fri Jan  7 11:39:53 2022
From: mark.kettenis at xs4all.nl (Mark Kettenis)
Date: Fri, 7 Jan 2022 20:39:53 +0100 (CET)
Subject: [PATCH 0/7] arm/arm64: dts: Remove unused num-viewport from pcie
 node
In-Reply-To: <99115cc4-32f6-d217-68be-33256a6993a8@canonical.com> (message
 from Krzysztof Kozlowski on Fri, 7 Jan 2022 13:47:03 +0100)
References: <20211229160245.1338-1-jszhang@kernel.org>
 <d3cb7b8439ee3d06@bloch.sibelius.xs4all.nl>
 <99115cc4-32f6-d217-68be-33256a6993a8@canonical.com>
Message-ID: <d3cb933f371ab5b5@bloch.sibelius.xs4all.nl>

> Date: Fri, 7 Jan 2022 13:47:03 +0100
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> 
> On 29/12/2021 17:50, Mark Kettenis wrote:
> >> From: Jisheng Zhang <jszhang at kernel.org>
> >> Date: Thu, 30 Dec 2021 00:02:38 +0800
> >>
> >> After commit 281f1f99cf3a("PCI: dwc: Detect number of iATU windows"),
> >> the number of iATU windows is detected at runtime, what's more,
> >> the 'num-viewport' property parsing has been removed, so remove the
> >> unused num-viewport from pcie node(s).
> >>
> >> It's too late for linux-5.17-rc1, I will rebase and send out v2 if
> >> necessary when 5.17-rc1 is released.
> > 
> > Please no.  This only makes the device trees unnecessarily
> > incompatible with older kernels
> 
> Anyone who is running a new DTB with older kernel is doomed anyway, not
> only because of this change but hundreds of other similar cleanups, e.g.
> making DTS conforming to dtschema. Are you sure there are such use cases
> of using new DTB with old kernel? I cannot imagine making a stable
> product with such scenario...

Well, many of those changes just affect the node names, which aren't
part of the ABI.  And adding missing properties or compatibles doesn't
break things either.  But yes, we keep seeing diffs to "cleanup"
bindings and device trees, especially in the context of converting
them to dtschema.  And that's just wrong.  If old device trees don't
pass validation, the default assumption should be that the schema is
wrong; not the other way around.

> > and other OSes that do rely on the
> > "num-viewport" property.
> 
> Right. We should have move the DTS out of the kernel when it was still
> small. :)

I don't think the number/size of DTs really matters.  But yes, moving
them to a separate repository would certainly make it more obvious
that they should not be tied to a particular kernel version and that
they are shared with other projects such as U-Boot and other OSes.

> > It really doesn't hurt to keep this property
> > even if future Linux kernels no longer look at it.
> 
> For Exynos PCIe, the property is still required by bindings, so
> definitely it cannot be removed from DTS. I did not check the other
> bindings.
> 
> Best regards,
> Krzysztof

Cheers,

Mark


From nathan at kernel.org  Fri Jan  7 11:43:30 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:30 -0700
Subject: [PATCH RFC 4.9 0/5] Fix booting arm64 big endian with QEMU 5.0.0+
Message-ID: <20220107194335.3090066-1-nathan@kernel.org>

Hello everyone,

After upgrading the version of QEMU used in our CI from 4.2.0 to 6.2.0,
I noticed that our 4.9 arm64 big endian builds stopped booting properly.
This is not something that is clang specific, I could reproduce it with
GCC 8.3.0 (the rootfs is at [1]).

$ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- distclean defconfig

$ scripts/config -e CPU_BIG_ENDIAN

$ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig Image.gz

$ qemu-system-aarch64 \
    -initrd rootfs.cpio \
    -append 'console=ttyAMA0 earlycon' \
    -cpu max \
    -machine virt,gic-version=max \
    -machine virtualization=true \
    -display none \
    -kernel arch/arm64/boot/Image.gz \
    -m 512m \
    -nodefaults \
    -serial mon:stdio
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 4.9.296 (nathan at archlinux-ax161) (gcc version 8.3.0 (Debian 8.3.0-2) ) #1 SMP PREEMPT Fri Jan 7 19:10:49 UTC 2022
...
[    0.773924] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[    0.773924]
[    0.776016] CPU: 0 PID: 1 Comm: init Not tainted 4.9.296 #1
[    0.776149] Hardware name: linux,dummy-virt (DT)
[    0.776375] Call trace:
[    0.777063] [<ffff000008088ba0>] dump_backtrace+0x0/0x1b0
[    0.777293] [<ffff000008088d64>] show_stack+0x14/0x20
[    0.777420] [<ffff0000088c2d18>] dump_stack+0x98/0xb8
[    0.777555] [<ffff0000088c0ee8>] panic+0x11c/0x278
[    0.777684] [<ffff0000080c4d20>] do_exit+0x940/0x970
[    0.777816] [<ffff0000080c4db8>] do_group_exit+0x38/0xa0
[    0.777974] [<ffff0000080cf698>] get_signal+0xb8/0x678
[    0.778111] [<ffff000008087ca8>] do_signal+0xd8/0x9b0
[    0.778248] [<ffff0000080888dc>] do_notify_resume+0x8c/0xa8
[    0.778392] [<ffff000008082ff4>] work_pending+0x8/0x10
[    0.778790] Kernel Offset: disabled
[    0.778891] Memory Limit: none
[    0.779241] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

I ended up bisecting QEMU down to cd3f80aba0 ("target/arm: Enable
ARMv8.1-VHE in -cpu max") [2], which did not seem obviously broken. I
noticed that our 4.14 builds were fine so I ended up doing a reverse
bisect down to commit ec347012bbec ("arm64: sysreg: Move to use
definitions for all the SCTLR bits"). Getting that change to apply
cleanly involved applying the three other arm64 patches in this series
and making it build properly required the BUILD_BUG_ON header split
(including bug.h might have been sufficient but I did not want to risk
any further breakage). I searched through mainline to see if there were
any fixes commits that I missed and I did not find any.

I am not sure if this series would be acceptable in 4.9, hence the RFC
tag. If not, I am happy to just spin down our boot tests of arm64 big
endian on 4.9, which is not a super valuable target, but I figured I
would send the series and let others decide!

[1]: https://github.com/ClangBuiltLinux/boot-utils/tree/6cfa15992d375dfb874ca0677abdaebfba4f74e6/images/arm64be
[2]: https://gitlab.com/qemu-project/qemu/-/commit/cd3f80aba0c559a6291f7c3e686422b15381f6b7

Cheers,
Nathan

Ian Abbott (1):
  bug: split BUILD_BUG stuff out into <linux/build_bug.h>

James Morse (1):
  arm64: sysreg: Move to use definitions for all the SCTLR bits

Mark Rutland (2):
  arm64: reduce el2_setup branching
  arm64: move !VHE work to end of el2_setup

Stefan Traby (1):
  arm64: Remove a redundancy in sysreg.h

 arch/arm64/include/asm/sysreg.h | 69 +++++++++++++++++++++++++--
 arch/arm64/kernel/head.S        | 49 ++++++++-----------
 arch/arm64/mm/proc.S            | 24 +---------
 include/linux/bug.h             | 72 +---------------------------
 include/linux/build_bug.h       | 84 +++++++++++++++++++++++++++++++++
 5 files changed, 170 insertions(+), 128 deletions(-)
 create mode 100644 include/linux/build_bug.h


base-commit: 710bf39c7aec32641ea63f6593db1df8c3e4a4d7
-- 
2.34.1



From nathan at kernel.org  Fri Jan  7 11:43:31 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:31 -0700
Subject: [PATCH RFC 4.9 1/5] bug: split BUILD_BUG stuff out into
 <linux/build_bug.h>
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <20220107194335.3090066-2-nathan@kernel.org>

From: Ian Abbott <abbotti at mev.co.uk>

commit bc6245e5efd70c41eaf9334b1b5e646745cb0fb3 upstream.

Including <linux/bug.h> pulls in a lot of bloat from <asm/bug.h> and
<asm-generic/bug.h> that is not needed to call the BUILD_BUG() family of
macros.  Split them out into their own header, <linux/build_bug.h>.

Also correct some checkpatch.pl errors for the BUILD_BUG_ON_ZERO() and
BUILD_BUG_ON_NULL() macros by adding parentheses around the bitfield
widths that begin with a minus sign.

Link: http://lkml.kernel.org/r/20170525120316.24473-6-abbotti at mev.co.uk
Signed-off-by: Ian Abbott <abbotti at mev.co.uk>
Acked-by: Michal Nazarewicz <mina86 at mina86.com>
Acked-by: Kees Cook <keescook at chromium.org>
Cc: Steven Rostedt <rostedt at goodmis.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Jakub Kicinski <jakub.kicinski at netronome.com>
Cc: Rasmus Villemoes <linux at rasmusvillemoes.dk>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
[nathan: Just take this patch, not the checkpatch.pl patches before it]
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 include/linux/bug.h       | 72 +--------------------------------
 include/linux/build_bug.h | 84 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 85 insertions(+), 71 deletions(-)
 create mode 100644 include/linux/build_bug.h

diff --git a/include/linux/bug.h b/include/linux/bug.h
index 0faae96302bd..eafb6213e582 100644
--- a/include/linux/bug.h
+++ b/include/linux/bug.h
@@ -3,6 +3,7 @@
 
 #include <asm/bug.h>
 #include <linux/compiler.h>
+#include <linux/build_bug.h>
 
 enum bug_trap_type {
 	BUG_TRAP_TYPE_NONE = 0,
@@ -13,80 +14,9 @@ enum bug_trap_type {
 struct pt_regs;
 
 #ifdef __CHECKER__
-#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
-#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
-#define BUILD_BUG_ON_ZERO(e) (0)
-#define BUILD_BUG_ON_NULL(e) ((void*)0)
-#define BUILD_BUG_ON_INVALID(e) (0)
-#define BUILD_BUG_ON_MSG(cond, msg) (0)
-#define BUILD_BUG_ON(condition) (0)
-#define BUILD_BUG() (0)
 #define MAYBE_BUILD_BUG_ON(cond) (0)
 #else /* __CHECKER__ */
 
-/* Force a compilation error if a constant expression is not a power of 2 */
-#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)	\
-	BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
-#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
-	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
-
-/* Force a compilation error if condition is true, but also produce a
-   result (of value 0 and type size_t), so the expression can be used
-   e.g. in a structure initializer (or where-ever else comma expressions
-   aren't permitted). */
-#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
-#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
-
-/*
- * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
- * expression but avoids the generation of any code, even if that expression
- * has side-effects.
- */
-#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
-
-/**
- * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
- *		      error message.
- * @condition: the condition which the compiler should know is false.
- *
- * See BUILD_BUG_ON for description.
- */
-#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
-
-/**
- * BUILD_BUG_ON - break compile if a condition is true.
- * @condition: the condition which the compiler should know is false.
- *
- * If you have some code which relies on certain constants being equal, or
- * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
- * detect if someone changes it.
- *
- * The implementation uses gcc's reluctance to create a negative array, but gcc
- * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
- * inline functions).  Luckily, in 4.3 they added the "error" function
- * attribute just for this type of case.  Thus, we use a negative sized array
- * (should always create an error on gcc versions older than 4.4) and then call
- * an undefined function with the error attribute (should always create an
- * error on gcc 4.3 and later).  If for some reason, neither creates a
- * compile-time error, we'll still have a link-time error, which is harder to
- * track down.
- */
-#ifndef __OPTIMIZE__
-#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
-#else
-#define BUILD_BUG_ON(condition) \
-	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
-#endif
-
-/**
- * BUILD_BUG - break compile if used.
- *
- * If you have some code that you expect the compiler to eliminate at
- * build time, you should use BUILD_BUG to detect if it is
- * unexpectedly used.
- */
-#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
-
 #define MAYBE_BUILD_BUG_ON(cond)			\
 	do {						\
 		if (__builtin_constant_p((cond)))       \
diff --git a/include/linux/build_bug.h b/include/linux/build_bug.h
new file mode 100644
index 000000000000..b7d22d60008a
--- /dev/null
+++ b/include/linux/build_bug.h
@@ -0,0 +1,84 @@
+#ifndef _LINUX_BUILD_BUG_H
+#define _LINUX_BUILD_BUG_H
+
+#include <linux/compiler.h>
+
+#ifdef __CHECKER__
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n) (0)
+#define BUILD_BUG_ON_ZERO(e) (0)
+#define BUILD_BUG_ON_NULL(e) ((void *)0)
+#define BUILD_BUG_ON_INVALID(e) (0)
+#define BUILD_BUG_ON_MSG(cond, msg) (0)
+#define BUILD_BUG_ON(condition) (0)
+#define BUILD_BUG() (0)
+#else /* __CHECKER__ */
+
+/* Force a compilation error if a constant expression is not a power of 2 */
+#define __BUILD_BUG_ON_NOT_POWER_OF_2(n)	\
+	BUILD_BUG_ON(((n) & ((n) - 1)) != 0)
+#define BUILD_BUG_ON_NOT_POWER_OF_2(n)			\
+	BUILD_BUG_ON((n) == 0 || (((n) & ((n) - 1)) != 0))
+
+/*
+ * Force a compilation error if condition is true, but also produce a
+ * result (of value 0 and type size_t), so the expression can be used
+ * e.g. in a structure initializer (or where-ever else comma expressions
+ * aren't permitted).
+ */
+#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:(-!!(e)); }))
+#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:(-!!(e)); }))
+
+/*
+ * BUILD_BUG_ON_INVALID() permits the compiler to check the validity of the
+ * expression but avoids the generation of any code, even if that expression
+ * has side-effects.
+ */
+#define BUILD_BUG_ON_INVALID(e) ((void)(sizeof((__force long)(e))))
+
+/**
+ * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied
+ *		      error message.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * See BUILD_BUG_ON for description.
+ */
+#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
+
+/**
+ * BUILD_BUG_ON - break compile if a condition is true.
+ * @condition: the condition which the compiler should know is false.
+ *
+ * If you have some code which relies on certain constants being equal, or
+ * some other compile-time-evaluated condition, you should use BUILD_BUG_ON to
+ * detect if someone changes it.
+ *
+ * The implementation uses gcc's reluctance to create a negative array, but gcc
+ * (as of 4.4) only emits that error for obvious cases (e.g. not arguments to
+ * inline functions).  Luckily, in 4.3 they added the "error" function
+ * attribute just for this type of case.  Thus, we use a negative sized array
+ * (should always create an error on gcc versions older than 4.4) and then call
+ * an undefined function with the error attribute (should always create an
+ * error on gcc 4.3 and later).  If for some reason, neither creates a
+ * compile-time error, we'll still have a link-time error, which is harder to
+ * track down.
+ */
+#ifndef __OPTIMIZE__
+#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+#else
+#define BUILD_BUG_ON(condition) \
+	BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)
+#endif
+
+/**
+ * BUILD_BUG - break compile if used.
+ *
+ * If you have some code that you expect the compiler to eliminate at
+ * build time, you should use BUILD_BUG to detect if it is
+ * unexpectedly used.
+ */
+#define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
+
+#endif	/* __CHECKER__ */
+
+#endif	/* _LINUX_BUILD_BUG_H */
-- 
2.34.1



From nathan at kernel.org  Fri Jan  7 11:43:32 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:32 -0700
Subject: [PATCH RFC 4.9 2/5] arm64: Remove a redundancy in sysreg.h
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <20220107194335.3090066-3-nathan@kernel.org>

From: Stefan Traby <stefan at hello-penguin.com>

commit d38338e396ee0571b3502962fd2fbaec4d2d9a8f upstream.

This is really trivial; there is a dup (1 << 16) in the code

Acked-by: Will Deacon <will.deacon at arm.com>
Signed-off-by: Stefan Traby <stefan at hello-penguin.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 arch/arm64/include/asm/sysreg.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 88bbe364b6ae..7a9f0a71f441 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -95,8 +95,8 @@
 #define SCTLR_ELx_M	1
 
 #define SCTLR_EL2_RES1	((1 << 4)  | (1 << 5)  | (1 << 11) | (1 << 16) | \
-			 (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23) | \
-			 (1 << 28) | (1 << 29))
+			 (1 << 18) | (1 << 22) | (1 << 23) | (1 << 28) | \
+			 (1 << 29))
 
 #define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
 			 SCTLR_ELx_SA | SCTLR_ELx_I)
-- 
2.34.1



From nathan at kernel.org  Fri Jan  7 11:43:33 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:33 -0700
Subject: [PATCH RFC 4.9 3/5] arm64: reduce el2_setup branching
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <20220107194335.3090066-4-nathan@kernel.org>

From: Mark Rutland <mark.rutland at arm.com>

commit 3ad47d055aa88d9f4189253f5b5c485f4c4626b2 upstream.

The early el2_setup code is a little convoluted, with two branches where
one would do. This makes the code more painful to read than is
necessary.

We can remove a branch and simplify the logic by moving the early return
in the booted-at-EL1 case earlier in the function. This separates it
from all the setup logic that only makes sense for EL2.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 arch/arm64/kernel/head.S | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 387542383662..b15abc6ae4af 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -489,13 +489,8 @@ ENTRY(el2_setup)
 	msr	SPsel, #1			// We want to use SP_EL{1,2}
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
-	b.ne	1f
-	mrs	x0, sctlr_el2
-CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
-CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
-	msr	sctlr_el2, x0
-	b	2f
-1:	mrs	x0, sctlr_el1
+	b.eq	1f
+	mrs	x0, sctlr_el1
 CPU_BE(	orr	x0, x0, #(3 << 24)	)	// Set the EE and E0E bits for EL1
 CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
 	msr	sctlr_el1, x0
@@ -503,7 +498,11 @@ CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
 	isb
 	ret
 
-2:
+1:	mrs	x0, sctlr_el2
+CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
+CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
+	msr	sctlr_el2, x0
+
 #ifdef CONFIG_ARM64_VHE
 	/*
 	 * Check for VHE being present. For the rest of the EL2 setup,
-- 
2.34.1



From nathan at kernel.org  Fri Jan  7 11:43:34 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:34 -0700
Subject: [PATCH RFC 4.9 4/5] arm64: move !VHE work to end of el2_setup
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <20220107194335.3090066-5-nathan@kernel.org>

From: Mark Rutland <mark.rutland at arm.com>

commit d61c97a7773d0848b4bf5c4697855c7ce117362c upstream.

We only need to initialise sctlr_el1 if we're installing an EL2 stub, so
we may as well defer this until we're doing so. Similarly, we can defer
intialising CPTR_EL2 until then, as we do not access any trapped
functionality as part of el2_setup.

This patch modified el2_setup accordingly, allowing us to remove a
branch and simplify the code flow.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 arch/arm64/kernel/head.S | 37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b15abc6ae4af..c067b13e93cc 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -553,26 +553,6 @@ set_hcr:
 	msr	vpidr_el2, x0
 	msr	vmpidr_el2, x1
 
-	/*
-	 * When VHE is not in use, early init of EL2 and EL1 needs to be
-	 * done here.
-	 * When VHE _is_ in use, EL1 will not be used in the host and
-	 * requires no configuration, and all non-hyp-specific EL2 setup
-	 * will be done via the _EL1 system register aliases in __cpu_setup.
-	 */
-	cbnz	x2, 1f
-
-	/* sctlr_el1 */
-	mov	x0, #0x0800			// Set/clear RES{1,0} bits
-CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
-CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
-	msr	sctlr_el1, x0
-
-	/* Coprocessor traps. */
-	mov	x0, #0x33ff
-	msr	cptr_el2, x0			// Disable copro. traps to EL2
-1:
-
 #ifdef CONFIG_COMPAT
 	msr	hstr_el2, xzr			// Disable CP15 traps to EL2
 #endif
@@ -598,6 +578,23 @@ CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
 	ret
 
 install_el2_stub:
+	/*
+	 * When VHE is not in use, early init of EL2 and EL1 needs to be
+	 * done here.
+	 * When VHE _is_ in use, EL1 will not be used in the host and
+	 * requires no configuration, and all non-hyp-specific EL2 setup
+	 * will be done via the _EL1 system register aliases in __cpu_setup.
+	 */
+	/* sctlr_el1 */
+	mov	x0, #0x0800			// Set/clear RES{1,0} bits
+CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
+CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
+	msr	sctlr_el1, x0
+
+	/* Coprocessor traps. */
+	mov	x0, #0x33ff
+	msr	cptr_el2, x0			// Disable copro. traps to EL2
+
 	/* Hypervisor stub */
 	adrp	x0, __hyp_stub_vectors
 	add	x0, x0, #:lo12:__hyp_stub_vectors
-- 
2.34.1



From nathan at kernel.org  Fri Jan  7 11:43:35 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri,  7 Jan 2022 12:43:35 -0700
Subject: [PATCH RFC 4.9 5/5] arm64: sysreg: Move to use definitions for all
 the SCTLR bits
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <20220107194335.3090066-6-nathan@kernel.org>

From: James Morse <james.morse at arm.com>

[ Upstream commit 7a00d68ebe5f07cb1db17e7fedfd031f0d87e8bb ]

__cpu_setup() configures SCTLR_EL1 using some hard coded hex masks,
and el2_setup() duplicates some this when setting RES1 bits.

Lets make this the same as KVM's hyp_init, which uses named bits.

First, we add definitions for all the SCTLR_EL{1,2} bits, the RES{1,0}
bits, and those we want to set or clear.

Add a build_bug checks to ensures all bits are either set or clear.
This means we don't need to preserve endian-ness configuration
generated elsewhere.

Finally, move the head.S and proc.S users of these hard-coded masks
over to the macro versions.

Signed-off-by: James Morse <james.morse at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
---
 arch/arm64/include/asm/sysreg.h | 65 ++++++++++++++++++++++++++++++++-
 arch/arm64/kernel/head.S        | 13 ++-----
 arch/arm64/mm/proc.S            | 24 +-----------
 3 files changed, 67 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7a9f0a71f441..ae1b31d02784 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -20,6 +20,7 @@
 #ifndef __ASM_SYSREG_H
 #define __ASM_SYSREG_H
 
+#include <asm/compiler.h>
 #include <linux/stringify.h>
 
 #include <asm/opcodes.h>
@@ -88,25 +89,81 @@
 
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_EE    (1 << 25)
+#define SCTLR_ELx_WXN	(1 << 19)
 #define SCTLR_ELx_I	(1 << 12)
 #define SCTLR_ELx_SA	(1 << 3)
 #define SCTLR_ELx_C	(1 << 2)
 #define SCTLR_ELx_A	(1 << 1)
 #define SCTLR_ELx_M	1
 
+#define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
+			 SCTLR_ELx_SA | SCTLR_ELx_I)
+
+/* SCTLR_EL2 specific flags. */
 #define SCTLR_EL2_RES1	((1 << 4)  | (1 << 5)  | (1 << 11) | (1 << 16) | \
 			 (1 << 18) | (1 << 22) | (1 << 23) | (1 << 28) | \
 			 (1 << 29))
+#define SCTLR_EL2_RES0	((1 << 6)  | (1 << 7)  | (1 << 8)  | (1 << 9)  | \
+			 (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \
+			 (1 << 17) | (1 << 20) | (1 << 21) | (1 << 24) | \
+			 (1 << 26) | (1 << 27) | (1 << 30) | (1 << 31))
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define ENDIAN_SET_EL2		SCTLR_ELx_EE
+#define ENDIAN_CLEAR_EL2	0
+#else
+#define ENDIAN_SET_EL2		0
+#define ENDIAN_CLEAR_EL2	SCTLR_ELx_EE
+#endif
+
+/* SCTLR_EL2 value used for the hyp-stub */
+#define SCTLR_EL2_SET	(ENDIAN_SET_EL2   | SCTLR_EL2_RES1)
+#define SCTLR_EL2_CLEAR	(SCTLR_ELx_M      | SCTLR_ELx_A    | SCTLR_ELx_C   | \
+			 SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
+			 ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
+
+/* Check all the bits are accounted for */
+#define SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != ~0)
 
-#define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
-			 SCTLR_ELx_SA | SCTLR_ELx_I)
 
 /* SCTLR_EL1 specific flags. */
 #define SCTLR_EL1_UCI		(1 << 26)
+#define SCTLR_EL1_E0E		(1 << 24)
 #define SCTLR_EL1_SPAN		(1 << 23)
+#define SCTLR_EL1_NTWE		(1 << 18)
+#define SCTLR_EL1_NTWI		(1 << 16)
 #define SCTLR_EL1_UCT		(1 << 15)
+#define SCTLR_EL1_DZE		(1 << 14)
+#define SCTLR_EL1_UMA		(1 << 9)
 #define SCTLR_EL1_SED		(1 << 8)
+#define SCTLR_EL1_ITD		(1 << 7)
 #define SCTLR_EL1_CP15BEN	(1 << 5)
+#define SCTLR_EL1_SA0		(1 << 4)
+
+#define SCTLR_EL1_RES1	((1 << 11) | (1 << 20) | (1 << 22) | (1 << 28) | \
+			 (1 << 29))
+#define SCTLR_EL1_RES0  ((1 << 6)  | (1 << 10) | (1 << 13) | (1 << 17) | \
+			 (1 << 21) | (1 << 27) | (1 << 30) | (1 << 31))
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define ENDIAN_SET_EL1		(SCTLR_EL1_E0E | SCTLR_ELx_EE)
+#define ENDIAN_CLEAR_EL1	0
+#else
+#define ENDIAN_SET_EL1		0
+#define ENDIAN_CLEAR_EL1	(SCTLR_EL1_E0E | SCTLR_ELx_EE)
+#endif
+
+#define SCTLR_EL1_SET	(SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   |\
+			 SCTLR_EL1_SA0  | SCTLR_EL1_SED  | SCTLR_ELx_I    |\
+			 SCTLR_EL1_DZE  | SCTLR_EL1_UCT  | SCTLR_EL1_NTWI |\
+			 SCTLR_EL1_NTWE | SCTLR_EL1_SPAN | ENDIAN_SET_EL1 |\
+			 SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
+#define SCTLR_EL1_CLEAR	(SCTLR_ELx_A   | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD    |\
+			 SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
+			 SCTLR_EL1_RES0)
+
+/* Check all the bits are accounted for */
+#define SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != ~0)
 
 /* id_aa64isar0 */
 #define ID_AA64ISAR0_RDM_SHIFT		28
@@ -244,6 +301,7 @@
 
 #else
 
+#include <linux/build_bug.h>
 #include <linux/types.h>
 
 asm(
@@ -300,6 +358,9 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
 {
 	u32 val;
 
+	SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS;
+	SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS;
+
 	val = read_sysreg(sctlr_el1);
 	val &= ~clear;
 	val |= set;
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index c067b13e93cc..04f81675b6b3 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -490,17 +490,13 @@ ENTRY(el2_setup)
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
 	b.eq	1f
-	mrs	x0, sctlr_el1
-CPU_BE(	orr	x0, x0, #(3 << 24)	)	// Set the EE and E0E bits for EL1
-CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
+	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
 	msr	sctlr_el1, x0
 	mov	w0, #BOOT_CPU_MODE_EL1		// This cpu booted in EL1
 	isb
 	ret
 
-1:	mrs	x0, sctlr_el2
-CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
-CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
+1:	mov_q	x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
 	msr	sctlr_el2, x0
 
 #ifdef CONFIG_ARM64_VHE
@@ -585,10 +581,7 @@ install_el2_stub:
 	 * requires no configuration, and all non-hyp-specific EL2 setup
 	 * will be done via the _EL1 system register aliases in __cpu_setup.
 	 */
-	/* sctlr_el1 */
-	mov	x0, #0x0800			// Set/clear RES{1,0} bits
-CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
-CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
+	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
 	msr	sctlr_el1, x0
 
 	/* Coprocessor traps. */
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 1b91b8c8999b..266211a0ecd6 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -413,11 +413,7 @@ ENTRY(__cpu_setup)
 	/*
 	 * Prepare SCTLR
 	 */
-	adr	x5, crval
-	ldp	w5, w6, [x5]
-	mrs	x0, sctlr_el1
-	bic	x0, x0, x5			// clear bits
-	orr	x0, x0, x6			// set bits
+	mov_q	x0, SCTLR_EL1_SET
 	/*
 	 * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
 	 * both user and kernel.
@@ -453,21 +449,3 @@ ENTRY(__cpu_setup)
 	msr	tcr_el1, x10
 	ret					// return to head.S
 ENDPROC(__cpu_setup)
-
-	/*
-	 * We set the desired value explicitly, including those of the
-	 * reserved bits. The values of bits EE & E0E were set early in
-	 * el2_setup, which are left untouched below.
-	 *
-	 *                 n n            T
-	 *       U E      WT T UD     US IHBS
-	 *       CE0      XWHW CZ     ME TEEA S
-	 * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
-	 * 0011 0... 1101 ..0. ..0. 10.. .0.. .... < hardware reserved
-	 * .... .1.. .... 01.1 11.1 ..01 0.01 1101 < software settings
-	 */
-	.type	crval, #object
-crval:
-	.word	0xfcffffff			// clear
-	.word	0x34d5d91d			// set
-	.popsection
-- 
2.34.1



From trix at redhat.com  Fri Jan  7 12:49:39 2022
From: trix at redhat.com (trix at redhat.com)
Date: Fri,  7 Jan 2022 12:49:39 -0800
Subject: [PATCH] clk: visconti: fix array's data insert check
Message-ID: <20220107204939.3939151-1-trix@redhat.com>

From: Tom Rix <trix at redhat.com>

Clang build fails with
pll.c:292:20: error: address of array 'ctx->clk_data.hws' will
  always evaluate to 'true'
        if (ctx->clk_data.hws && id)
            ~~~~~~~~~~~~~~^~~ ~~

This check protects inserting into the clk_data.hws array.
clk_data is allocated a trailing element of the ctx struct.
If the ctx is ok, the ctx->clk_data.hws will be ok.

Change to checking if 'id' falls outside of the array
bounds.

Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and reset driver")
Signed-off-by: Tom Rix <trix at redhat.com>
---
 drivers/clk/visconti/pll.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c
index 3b6e88bb73d5b..7f2e1016536ab 100644
--- a/drivers/clk/visconti/pll.c
+++ b/drivers/clk/visconti/pll.c
@@ -289,7 +289,7 @@ static void visconti_pll_add_lookup(struct visconti_pll_provider *ctx,
 				    struct clk_hw *hw_clk,
 				    unsigned int id)
 {
-	if (ctx->clk_data.hws && id)
+	if (id < ctx->clk_data.num)
 		ctx->clk_data.hws[id] = hw_clk;
 }
 
-- 
2.26.3



From helgaas at kernel.org  Fri Jan  7 13:09:02 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 15:09:02 -0600
Subject: [PATCH 03/15] PCI: mvebu: Check that PCI bridge specified in DT
 has function number zero
In-Reply-To: <20220107181819.yiya3mxhtfsnubg4@pali>
Message-ID: <20220107210902.GA403155@bhelgaas>

On Fri, Jan 07, 2022 at 07:18:19PM +0100, Pali Roh?r wrote:
> On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> > On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Roh?r wrote:
> > > Driver cannot handle PCI bridges at non-zero function address. So add
> > > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > > function to zero.
> > 
> > Why can the driver not handle bridges at non-zero function addresses?
> > The PCI spec allows that, doesn't it?  Is this a hardware limitation?
> 
> It is software / kernel limitation.
> 
> Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
> this driver can emulate only single function PCI-to-PCI bridge device.

That's weird.  Why does pci-bridge-emul.c care about the function
number?  Or maybe you're saying that pci-mvebu.c isn't smart enough to
build an emulated bridge at a non-zero function?  Or, since this is
emulated, maybe there's just no *reason* to ever use a non-zero
function?

It would really be nice to have the commit log and maybe even a
comment allude to what's going on here .  Otherwise this check sort of
dangles without having an obvious reason for existence.

Does this issue also affect pci-aardvark.c (which looks like the only
other user of pci_bridge_emul_init())?

> > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > Cc: stable at vger.kernel.org
> > > ---
> > >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> > >  1 file changed, 5 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > index 6197f7e7c317..08274132cdfb 100644
> > > --- a/drivers/pci/controller/pci-mvebu.c
> > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> > >  	port->devfn = of_pci_get_devfn(child);
> > >  	if (port->devfn < 0)
> > >  		goto skip;
> > > +	if (PCI_FUNC(port->devfn) != 0) {
> > > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > > +			port->name);
> > > +		goto skip;
> > > +	}
> > >  
> > >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> > >  				 &port->mem_target, &port->mem_attr);
> > > -- 
> > > 2.20.1
> > > 


From yuzhao at google.com  Fri Jan  7 13:12:45 2022
From: yuzhao at google.com (Yu Zhao)
Date: Fri, 7 Jan 2022 14:12:45 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydf9RXPch5ddg/WC@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcTkrl84Xzg2dSz@dhcp22.suse.cz> <Ydde2F4Oi0wKx//y@google.com>
 <Ydf9RXPch5ddg/WC@dhcp22.suse.cz>
Message-ID: <Ydisze9ZR/QBtjpX@google.com>

On Fri, Jan 07, 2022 at 09:43:49AM +0100, Michal Hocko wrote:
> On Thu 06-01-22 14:27:52, Yu Zhao wrote:
> > On Thu, Jan 06, 2022 at 05:06:42PM +0100, Michal Hocko wrote:
> [...]
> > > > diff --git a/include/linux/oom.h b/include/linux/oom.h
> > > > index 2db9a1432511..9c7a4fae0661 100644
> > > > --- a/include/linux/oom.h
> > > > +++ b/include/linux/oom.h
> > > > @@ -57,6 +57,22 @@ struct oom_control {
> > > >  extern struct mutex oom_lock;
> > > >  extern struct mutex oom_adj_mutex;
> > > >  
> > > > +#ifdef CONFIG_MMU
> > > > +extern struct task_struct *oom_reaper_list;
> > > > +extern struct wait_queue_head oom_reaper_wait;
> > > > +
> > > > +static inline bool oom_reaping_in_progress(void)
> > > > +{
> > > > +	/* a racy check can be used to reduce the chance of overkilling */
> > > > +	return READ_ONCE(oom_reaper_list) || !waitqueue_active(&oom_reaper_wait);
> > > > +}
> > > > +#else
> > > > +static inline bool oom_reaping_in_progress(void)
> > > > +{
> > > > +	return false;
> > > > +}
> > > > +#endif
> > > 
> > > I do not like this. These are internal oom reaper's and no code should
> > > really make any decisions based on that. oom_reaping_in_progress is not
> > > telling much anyway.
> > 
> > There is a perfectly legitimate reason for this.
> > 
> > If there is already a oom kill victim and the oom reaper is making
> > progress, the system may still be under memory pressure until the oom
> > reaping is done. The page reclaim has two choices in this transient
> > state: kill more processes or keep reclaiming (a few more) hot pages.
> > 
> > The first choice, AKA overkilling, is generally a bad one. The oom
> > reaper is single threaded and it can't go faster with additional
> > victims. Additional processes are sacrificed for nothing -- this is
> > an overcorrection of a system that tries to strike a balance between
> > the tendencies to release memory pressure and to improve memory
> > utilization.
> > 
> > > This is a global queue for oom reaper that can
> > > contain oom victims from different oom scopes (e.g. global OOM, memcg
> > > OOM or memory policy OOM).
> > 
> > True, but this is a wrong reason to make the conclusion below. Oom
> > kill scopes do NOT matter; only the pool the freed memory goes into
> > does. And there is only one global pool free pages.
> > 
> > > Your lru_gen_age_node uses this to decide whether to trigger
> > > out_of_memory and that is clearly wrong for the above reasons.
> > 
> > I hope my explanation above is clear enough. There is nothing wrong
> > with the purpose and the usage of oom_reaping_in_progress(), and it
> > has been well tested in the Arch Linux Zen kernel.
> 
> I disagree. An ongoing oom kill in one domain (say memcg A) shouldn't be
> any base for any decisions in reclaim in other domain (say memcg B or
> even a global reclaim). Those are fundamentally different conditions.

I agree for the memcg A oom and memcg B reclaim case, because memory
freed from A doesn't go to B.

I still think for the memcg A and the global reclaim case, memory
freed from A can be considered when deciding whether to make more
kills during global reclaim.

But this is something really minor, and I'll go with your suggestion,
i.e., getting rid of oom_reaping_in_progress().

> > Without it, overkills can be easily reproduced by the following simple
> > script. That is additional oom kills happen to processes other than
> > "tail".
> > 
> >   # enable zram
> >   while true;
> >   do
> >       tail /dev/zero
> >   done
> 
> I would be interested to hear more (care to send oom reports?).

I agree with what said below. I think those additional ooms might have
been from different oom domains. I plan to leave this for now and go
with your suggestion as mentioned above.

> > > out_of_memory is designed to skip over any action if there is an oom
> > > victim pending from the oom domain (have a look at oom_evaluate_task).
> > 
> > Where exactly? Point me to the code please.
> > 
> > I don't see such a logic inside out_of_memory() or
> > oom_evaluate_task(). Currently the only thing that could remotely
> > prevent overkills is oom_lock. But it's inadequate.
> 
> OK, let me try to exaplain. The protocol is rather convoluted. Once the
> oom killer is invoked it choses a victim to kill. oom_evaluate_task will
> evaluate _all_ tasks from the oom respective domain (select_bad_process
> which distinguishes memcg vs global oom kill and oom_cpuset_eligible for
> the cpuset domains). If there is any pre-existing oom victim
> (tsk_is_oom_victim) then the scan is aborted and the oom killer bails
> out. OOM victim stops being considered as relevant once the oom reaper
> manages to release its address space (or give up on the mmap_sem
> contention) and sets MMF_OOM_SKIP flag for the mm.
> 
> That being said the out_of_memory automatically backs off and relies on
> the oom reaper to process its queue.
> 
> Does it make more clear for you now?

Yes, you are right, thanks.

> > This is the entire pipeline:
> > low on memory -> out_of_memory() -> oom_reaper() -> free memory
> > 
> > To avoid overkills, we need to consider the later half of it too.
> > oom_reaping_in_progress() is exactly for this purpose.
> > 
> > > > +static bool age_lruvec(struct lruvec *lruvec, struct scan_control *sc,
> > > > +		       unsigned long min_ttl)
> > > > +{
> > > > +	bool need_aging;
> > > > +	long nr_to_scan;
> > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > +	int swappiness = get_swappiness(memcg);
> > > > +	DEFINE_MAX_SEQ(lruvec);
> > > > +	DEFINE_MIN_SEQ(lruvec);
> > > > +
> > > > +	if (mem_cgroup_below_min(memcg))
> > > > +		return false;
> > > 
> > > mem_cgroup_below_min requires effective values to be calculated for the
> > > reclaimed hierarchy. Have a look at mem_cgroup_calculate_protection
> > 
> > I always keep that in mind, and age_lruvec() is called *after*
> > mem_cgroup_calculate_protection():
> 
> >   balance_pgdat()
> >     memcgs_need_aging = 0
> >     do {
> >       lru_gen_age_node()
> >         if (!memcgs_need_aging) {
> >             memcgs_need_aging = 1
> >             return
> >         }
> >         age_lruvec()
> > 
> >       shrink_node_memcgs()
> >         mem_cgroup_calculate_protection()
> >         lru_gen_shrink_lruvec()
> >           if ...
> >             memcgs_need_aging = 0
> >     } while ...
> 
> Uff, this is really subtle. I really think you should be following the
> existing pattern when the effective values are calculated right in the
> same context as they are evaluated.

Consider it done.


From helgaas at kernel.org  Fri Jan  7 13:27:36 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 15:27:36 -0600
Subject: [PATCH 3/3] PCI: aardvark: Implement emulated root PCI bridge
In-Reply-To: <20180629092231.32207-4-thomas.petazzoni@bootlin.com>
Message-ID: <20220107212736.GA404447@bhelgaas>

On Fri, Jun 29, 2018 at 11:22:31AM +0200, Thomas Petazzoni wrote:

> +static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
> +{
> +	struct pci_sw_bridge *bridge = &pcie->bridge;

> +	/* Support interrupt A for MSI feature */
> +	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;

Only 3.5 years later, IIUC, this is the value you get when you read
PCI_INTERRUPT_PIN, so I think this should be PCI_INTERRUPT_INTA, not
PCIE_CORE_INT_A_ASSERT_ENABLE.

Readers expect to get the values defined in the PCI spec, i.e.,

  PCI_INTERRUPT_UNKNOWN
  PCI_INTERRUPT_INTA
  PCI_INTERRUPT_INTB
  PCI_INTERRUPT_INTC
  PCI_INTERRUPT_INTD

Bjorn


From helgaas at kernel.org  Fri Jan  7 13:32:16 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 15:32:16 -0600
Subject: [PATCH 05/15] PCI: mvebu: Disallow mapping interrupts on
 emulated bridges
In-Reply-To: <20211125124605.25915-6-pali@kernel.org>
Message-ID: <20220107213216.GA403555@bhelgaas>

On Thu, Nov 25, 2021 at 01:45:55PM +0100, Pali Roh?r wrote:
> Interrupt support on mvebu emulated bridges is not implemented yet.

Is this mvebu-specific, or is aardvar also affected?

> So properly indicate return value to callers that they cannot request
> interrupts from emulated bridge.

Pet peeve: descriptions that say "do this *properly*".  As though the
previous authors were just ignorant or intentionally did something
*improperly* :)

> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Cc: stable at vger.kernel.org
> ---
>  drivers/pci/controller/pci-mvebu.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 19c6ee298442..a3df352d440e 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -705,6 +705,15 @@ static struct pci_ops mvebu_pcie_ops = {
>  	.write = mvebu_pcie_wr_conf,
>  };
>  
> +static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> +{
> +	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> +	if (dev->bus->number == 0)
> +		return 0; /* Proper return code 0 == NO_IRQ */
> +
> +	return of_irq_parse_and_map_pci(dev, slot, pin);

Is this something that could be done with a .read_base() op, e.g.,
make PCI_INTERRUPT_PIN contain zero (PCI_INTERRUPT_UNKNOWN)?

> +}
> +
>  static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
>  						 const struct resource *res,
>  						 resource_size_t start,
> @@ -1119,6 +1128,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
>  	bridge->sysdata = pcie;
>  	bridge->ops = &mvebu_pcie_ops;
>  	bridge->align_resource = mvebu_pcie_align_resource;
> +	bridge->map_irq = mvebu_pcie_map_irq;

I assume this means INTx doesn't work for some devices?  Which ones?
I guess anything on the root bus?  But INTx for devices *below* these
emulated Root Ports *does* work?

>  	return pci_host_probe(bridge);
>  }
> -- 
> 2.20.1
> 


From helgaas at kernel.org  Fri Jan  7 13:55:04 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 15:55:04 -0600
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20211125124605.25915-9-pali@kernel.org>
Message-ID: <20220107215504.GA406217@bhelgaas>

On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> Properly propagate failure from mvebu_pcie_add_windows() function back to
> the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> On error set base value higher than limit value which indicates that
> address range is disabled. 

Does the spec say that if software programs something invalid,
hardware should proactively set the base and limit registers to
disable the window?

I'm not sure I've seen hardware that does this, and it seems ... maybe
a little aggressive.

What happens if software writes the base and limit in the wrong order,
so the window is invalid after the first write but valid after the
second?  That actually sounds like it could be a sensible strategy to
prevent a partially-configured window from being active.

Bjorn


From chase.conklin at arm.com  Fri Jan  7 13:54:01 2022
From: chase.conklin at arm.com (Chase Conklin)
Date: Fri,  7 Jan 2022 15:54:01 -0600
Subject: [PATCH v5 08/69] KVM: arm64: nv: Reset VCPU to EL2 registers if
 VCPU nested virt is set
In-Reply-To: <20211129200150.351436-9-maz@kernel.org>
References: <20211129200150.351436-9-maz@kernel.org>
Message-ID: <20220107215401.61828-1-chase.conklin@arm.com>

Hi Marc,

On Mon Nov 29 15:00:49 EST 2021, Marc Zyngier <maz at kernel.org> wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
>
> Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
> feature is enabled on the VCPU.
>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> [maz: rework register reset not to use empty data structures]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/reset.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 426bd7fbc3fd..38a7182819fb 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -27,6 +27,7 @@
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/virt.h>
>  
>  /* Maximum phys_shift supported for any VM on this host */
> @@ -38,6 +39,9 @@ static u32 kvm_ipa_limit;
>  #define VCPU_RESET_PSTATE_EL1	(PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
>  				 PSR_F_BIT | PSR_D_BIT)
>  
> +#define VCPU_RESET_PSTATE_EL2	(PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> +				 PSR_F_BIT | PSR_D_BIT)
> +
>  #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
>  				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
>  
> @@ -176,8 +180,8 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
>  	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
>  		return false;
>  
> -	/* MTE is incompatible with AArch32 */
> -	if (kvm_has_mte(vcpu->kvm) && is32bit)
> +	/* MTE and NV are incompatible with AArch32 */
> +	if ((kvm_has_mte(vcpu->kvm) || nested_virt_in_use(vcpu)) && is32bit)
>  		return false;

Should something similar be done for SVE? I see from the ID register emulation
that SVE is hidden from the guest but there isn't anything in
kvm_vcpu_enable_sve() that checks if NV is in use. That means it's possible to
have both nested_virt_in_use(vcpu) and vcpu_has_sve(vcpu) be true
simultaneously. If that happens, the FPSIMD fixup can get confused

	/*
	 * Don't handle SVE traps for non-SVE vcpus here. This
	 * includes NV guests for the time being.
	 */
	if (!sve_guest && (esr_ec != ESR_ELx_EC_FP_ASIMD ||
			   guest_hyp_fpsimd_traps_enabled(vcpu)))
		return false;

and incorrectly restore the wrong context instead of forwarding a FPSIMD trap to
the guest hypervisor.

Thanks,
Chase

>  	/* Check that the vcpus are either all 32bit or all 64bit */
> @@ -255,6 +259,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  	default:
>  		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
>  			pstate = VCPU_RESET_PSTATE_SVC;
> +		} else if (nested_virt_in_use(vcpu)) {
> +			pstate = VCPU_RESET_PSTATE_EL2;
>  		} else {
>  			pstate = VCPU_RESET_PSTATE_EL1;
>  		}
> -- 
> 2.30.2



From martin.blumenstingl at googlemail.com  Fri Jan  7 13:56:52 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:56:52 +0100
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4 Reset
 Controller
In-Reply-To: <20220107023931.13251-2-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-2-zelong.dong@amlogic.com>
Message-ID: <CAFBinCDrfpjCDu4Atwx9n0KAafDyCQnBSd5fNFV5NgM1xgU-NA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Add new compatible for Amlogic's Meson-S4 Reset Controller
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 13:57:05 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:57:05 +0100
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-3-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-3-zelong.dong@amlogic.com>
Message-ID: <CAFBinCCmTwPcmuMAFP-rgu_v5NR0Z3B5bp-WTEvnaf+UMY5MRA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Add DT bindings for the Meson-S4 SoC Reset Controller include file.
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From martin.blumenstingl at googlemail.com  Fri Jan  7 13:58:23 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 22:58:23 +0100
Subject: [PATCH 3/3] reset: reset-meson: add support for the Meson-S4 SoC
 Reset Controller
In-Reply-To: <20220107023931.13251-4-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-4-zelong.dong@amlogic.com>
Message-ID: <CAFBinCAP66AHM4252BwJ2FMLtyw2RzUsoitahpK0jNdgZaJLXg@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:40 AM Zelong Dong <zelong.dong at amlogic.com> wrote:
>
> Compared to the A1 SoCs the number of RESET registers is different
> and the offset for the level registers is the same. Add a new
> compatible string and struct meson_reset_param to add support for the
> reset controller on the S4 SoC.
>
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From pali at kernel.org  Fri Jan  7 13:58:46 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 22:58:46 +0100
Subject: [PATCH 03/15] PCI: mvebu: Check that PCI bridge specified in DT
 has function number zero
In-Reply-To: <20220107210902.GA403155@bhelgaas>
References: <20220107181819.yiya3mxhtfsnubg4@pali>
 <20220107210902.GA403155@bhelgaas>
Message-ID: <20220107215846.i5n4gx56deqfs3y4@pali>

On Friday 07 January 2022 15:09:02 Bjorn Helgaas wrote:
> On Fri, Jan 07, 2022 at 07:18:19PM +0100, Pali Roh?r wrote:
> > On Friday 07 January 2022 12:15:12 Bjorn Helgaas wrote:
> > > On Thu, Nov 25, 2021 at 01:45:53PM +0100, Pali Roh?r wrote:
> > > > Driver cannot handle PCI bridges at non-zero function address. So add
> > > > appropriate check. Currently all in-tree kernel DTS files set PCI bridge
> > > > function to zero.
> > > 
> > > Why can the driver not handle bridges at non-zero function addresses?
> > > The PCI spec allows that, doesn't it?  Is this a hardware limitation?
> > 
> > It is software / kernel limitation.
> > 
> > Because this bridge is virtual, emulated by pci-bridge-emul.c driver and
> > this driver can emulate only single function PCI-to-PCI bridge device.
> 
> That's weird.  Why does pci-bridge-emul.c care about the function
> number?

pci-bridge-emul.c emulates whole PCI config space and multifunction PCI
device needs to have Multi-Function Device bit set. Which
pci-bridge-emul.c does not do as it "emulates" only singe-function
device. Also some extended PCIe registers needs to be aligned for
multifunction device. And for simplification nothing from this is
implemented in that pci-bridge-emul.c driver. Basically single function
device is easily to emulate than multi function device. And for
simplicity of driver it is just better to do not implement more stuff
if it is not required.

> Or maybe you're saying that pci-mvebu.c isn't smart enough to
> build an emulated bridge at a non-zero function?  Or, since this is
> emulated, maybe there's just no *reason* to ever use a non-zero
> function?

These PCIe root ports are basically on different PCI domains, every root
port with its subtree has its own configuration, including own access
to config space of subdevices. And I do not think that there is a reason
to try putting root port (as emulated pci-to-pci bridge) on non-zero
function and putting separate root ports into "one" multifunction
device.

Technically it could be possible to implement it and also properly, as
it is just emulation of PCI device. But why? Just big complication
without any benefit. At least I do not see benefit.

> It would really be nice to have the commit log and maybe even a
> comment allude to what's going on here .  Otherwise this check sort of
> dangles without having an obvious reason for existence.
> 
> Does this issue also affect pci-aardvark.c (which looks like the only
> other user of pci_bridge_emul_init())?

Theoretically yes. But pci-aardvark is single-root-port hardware and
therefore it is single-function device. And emulated device is
registered by pci-aardvark driver, not by DT. Because it is
single-root-port HW there is no DT node for root port like for any other
single-root-port PCIe controllers. So practically no.

> > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > Cc: stable at vger.kernel.org
> > > > ---
> > > >  drivers/pci/controller/pci-mvebu.c | 5 +++++
> > > >  1 file changed, 5 insertions(+)
> > > > 
> > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > index 6197f7e7c317..08274132cdfb 100644
> > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > @@ -864,6 +864,11 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> > > >  	port->devfn = of_pci_get_devfn(child);
> > > >  	if (port->devfn < 0)
> > > >  		goto skip;
> > > > +	if (PCI_FUNC(port->devfn) != 0) {
> > > > +		dev_err(dev, "%s: invalid function number, must be zero\n",
> > > > +			port->name);
> > > > +		goto skip;
> > > > +	}
> > > >  
> > > >  	ret = mvebu_get_tgt_attr(dev->of_node, port->devfn, IORESOURCE_MEM,
> > > >  				 &port->mem_target, &port->mem_attr);
> > > > -- 
> > > > 2.20.1
> > > > 


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:09:13 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:09:13 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <20220107150512.614423-3-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-3-narmstrong@baylibre.com>
Message-ID: <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 4:06 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +#define HHI_MIPI_CNTL2 0x08
> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL1      GENMASK(31, 16)
> +#define                HHI_MIPI_CNTL2_CH_EN            GENMASK(15, 11)
> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL0      GENMASK(10, 0)
> +
> +#define DSI_LANE_0                             BIT(4)
> +#define DSI_LANE_1                             BIT(3)
> +#define DSI_LANE_CLK                           BIT(2)
> +#define DSI_LANE_2                             BIT(1)
> +#define DSI_LANE_3                             BIT(0)
At first I thought that these should be named
HHI_MIPI_CNTL2_DSI_LANE_0 (and similar).
But then I understood that they aren't bits directly in HHI_MIPI_CNTL2
but they belong to HHI_MIPI_CNTL2_CH_EN.
Have you considered naming them for example
HHI_MIPI_CNTL2_CH_EN_DSI_LANE_0 to make this more clear?

[...]
> +       if (IS_ERR(map)) {
> +               dev_err(dev,
> +                       "failed to get HHI regmap\n");
> +               return PTR_ERR(map);
I suggest using:
  return dev_err_probe(dev, PTR_ERR(map), "failed to get HHI regmap\n");
to simplify the code

[...]
> +       if (IS_ERR(priv->phy)) {
> +               ret = PTR_ERR(priv->phy);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(dev, "failed to create PHY\n");
> +               return ret;
and similar here:
  return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n");

[...]
> +static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
> +       {
> +               .compatible = "amlogic,g12a-mipi-dphy-analog",
> +       },
> +       { },
In the past I was suggested to use:
  { /* sentinel */ }
meaning: no trailing comma here so nobody can add entries after the
sentinel by accident.
I suggest doing the same here if you re-spin this series.


Thank you!
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:13:42 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:13:42 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <20220107150512.614423-2-narmstrong@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
Message-ID: <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +required:
> +  - compatible
> +  - reg
> +  - "#phy-cells"
I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
the datasheet.
I'm no expert on this and I'm just asking in case you have missed one of these:
Can you confirm that these belong to some other IP?


Best regards,
Martin


From pali at kernel.org  Fri Jan  7 14:13:48 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 23:13:48 +0100
Subject: [PATCH 05/15] PCI: mvebu: Disallow mapping interrupts on
 emulated bridges
In-Reply-To: <20220107213216.GA403555@bhelgaas>
References: <20211125124605.25915-6-pali@kernel.org>
 <20220107213216.GA403555@bhelgaas>
Message-ID: <20220107221348.5s4ehqhxunmoacbm@pali>

On Friday 07 January 2022 15:32:16 Bjorn Helgaas wrote:
> On Thu, Nov 25, 2021 at 01:45:55PM +0100, Pali Roh?r wrote:
> > Interrupt support on mvebu emulated bridges is not implemented yet.
> 
> Is this mvebu-specific, or is aardvar also affected?

This is pci-mvebu.c driver specific, it does not implement emulation of
neither INTx, nor MSI interrupts for emulated pci bridge (root port). As
we know this HW does not have compliant pci root port, it needs to be
emulated in driver, and emulation for interrupts is missing. (it means
that also AER interrupt is missing).

And pci-aardvark.c driver has same issue and similar patch is required
for pci-aardvark.c too. Marek should take care of it. But for
pci-aardvark we already have implementation which emulates INTx
interrupts and it is waiting for review on the list:
https://lore.kernel.org/linux-pci/20211208061851.31867-1-kabel at kernel.org/

> > So properly indicate return value to callers that they cannot request
> > interrupts from emulated bridge.
> 
> Pet peeve: descriptions that say "do this *properly*".  As though the
> previous authors were just ignorant or intentionally did something
> *improperly* :)
> 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > Cc: stable at vger.kernel.org
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 19c6ee298442..a3df352d440e 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -705,6 +705,15 @@ static struct pci_ops mvebu_pcie_ops = {
> >  	.write = mvebu_pcie_wr_conf,
> >  };
> >  
> > +static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > +{
> > +	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> > +	if (dev->bus->number == 0)
> > +		return 0; /* Proper return code 0 == NO_IRQ */
> > +
> > +	return of_irq_parse_and_map_pci(dev, slot, pin);
> 
> Is this something that could be done with a .read_base() op, e.g.,
> make PCI_INTERRUPT_PIN contain zero (PCI_INTERRUPT_UNKNOWN)?

I'm not sure... maybe. I choose this style as after I implement
emulation of INTx interrupts it allows me just to replace "return 0;" by
"return my_mapping_function_for_root_port(...);". Similarly like it is
in pending pci-aardvark.c patch:
https://lore.kernel.org/linux-pci/20211208061851.31867-15-kabel at kernel.org/

> > +}
> > +
> >  static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
> >  						 const struct resource *res,
> >  						 resource_size_t start,
> > @@ -1119,6 +1128,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
> >  	bridge->sysdata = pcie;
> >  	bridge->ops = &mvebu_pcie_ops;
> >  	bridge->align_resource = mvebu_pcie_align_resource;
> > +	bridge->map_irq = mvebu_pcie_map_irq;
> 
> I assume this means INTx doesn't work for some devices?  Which ones?
> I guess anything on the root bus?  But INTx for devices *below* these
> emulated Root Ports *does* work?

Exactly. All devices except emulated root ports (which are on bus 0)
have working MSI, MSI-X and INTx interrupts.

> >  	return pci_host_probe(bridge);
> >  }
> > -- 
> > 2.20.1
> > 


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:14:41 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:14:41 +0100
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI output
 port
In-Reply-To: <20220107145515.613009-3-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-3-narmstrong@baylibre.com>
Message-ID: <CAFBinCArnZ8XtaBtWa0smmPTc-sHvAdD7_-3iTywxUJ08-uyMw@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:56 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Add third port corresponding to the ENCL DPI encoder used to connect
> to DSI or LVDS transceivers.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>


From pali at kernel.org  Fri Jan  7 14:28:26 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 7 Jan 2022 23:28:26 +0100
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220107215504.GA406217@bhelgaas>
References: <20211125124605.25915-9-pali@kernel.org>
 <20220107215504.GA406217@bhelgaas>
Message-ID: <20220107222826.cv2bzywwayjwzy3c@pali>

On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > Properly propagate failure from mvebu_pcie_add_windows() function back to
> > the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> > PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> > On error set base value higher than limit value which indicates that
> > address range is disabled. 
> 
> Does the spec say that if software programs something invalid,
> hardware should proactively set the base and limit registers to
> disable the window?

No. But this patch address something totally different. Software can do
fully valid operation, e.g. try to set forwarding memory window as large
as possible. But because this driver "emulates" pci bridge by calling
software/kernel function (mvebu_pcie_add_windows), some operations which
in real HW cannot happen, are possible in software.

For example there are limitations in sizes of forwarding memory windows,
because it is done by mvebu-mbus driver, which is responsible for
configuring mapping and forwarding of PCIe I/O and MEM windows. And due
to Marvell HW, there are restrictions which are not in PCIe HW.

Currently if such error happens, obviously kernel is not able to set
PCIe windows and it just print warnings to dmesg. Trying to access these
windows would result in the worst case in crashes.

With this change when mvebu_pcie_add_windows() function fails then into
emulated config space is put information that particular forwarding
window is disabled. I think that it is better to indicate it in config
space what is the current "reality" of hardware configuration. If window
is disabled in real-HW (meaning in mvebu-mbus driver) then show it also
in emulated config space of pci bridge.

Do you have better idea what should emulated pci bridge do, if software
try to set fully valid configuration of forwarding window, but it is not
possible to achieve it (even compliant PCI bridge must be able to do
it)?

> I'm not sure I've seen hardware that does this, and it seems ... maybe
> a little aggressive.
> 
> What happens if software writes the base and limit in the wrong order,
> so the window is invalid after the first write but valid after the
> second?  That actually sounds like it could be a sensible strategy to
> prevent a partially-configured window from being active.
> 
> Bjorn

Invalid window (limit < base) means that window is disabled. And
pci-mvebu.c in its callbacks from pci-bridge-emul.c should correctly
handle it and propagates information about disablement to mvebu-mbus
driver.

After window is valid again (limit > base) then pci-mvebu.c call
mvebu-mbus to setup new mapping.


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:33:14 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:33:14 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220107145515.613009-4-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-4-narmstrong@baylibre.com>
Message-ID: <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>

 Hi Neil,

On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
> Amlogic AXG SoCs.
Should this be "AXG and newer SoCs" or is this really AXG specific?

[...]
> +#define GAMMA_VCOM_POL    7     /* RW */
> +#define GAMMA_RVS_OUT     6     /* RW */
> +#define ADR_RDY           5     /* Read Only */
> +#define WR_RDY            4     /* Read Only */
> +#define RD_RDY            3     /* Read Only */
> +#define GAMMA_TR          2     /* RW */
> +#define GAMMA_SET         1     /* RW */
> +#define GAMMA_EN          0     /* RW */
> +
> +#define H_RD              12
> +#define H_AUTO_INC        11
> +#define H_SEL_R           10
> +#define H_SEL_G           9
> +#define H_SEL_B           8
I think all values above can be wrapped in the BIT() macro, then you
don't need that below.

> +#define HADR_MSB          7            /* 7:0 */
> +#define HADR              0            /* 7:0 */
Here GENMASK(7, 0) can be used for HADR

Also I think prefixing all macros above with their register name
(L_GAMMA_CNTL_PORT_ or L_GAMMA_ADDR_PORT_) will make the code easier
to read.

[...]
> +       writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
The public S905 datasheet calls 0x8000 ENCL_PX_LN_CNT_SHADOW_EN

> +       writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
According to the public S905 datasheet this is:
- BIT(3): ENCL_VIDEO_MODE_ADV_VFIFO_EN
- BIT(4): ENCL_VIDEO_MODE_ADV_GAIN_HDTV
- BIT(10): ENCL_SEL_GAMMA_RGB_IN

> +       writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
I don't know the exact name but the 32-bit vendor kernel sources have
a comment [0] saying that 0x1000 is "bypass filter"
But maybe we can simply call it ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER

[...]
> +       writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
The public S905 datasheet says:
- BIT(0): USE RGB data from VIU, furthermore a comment in the 3.10
kernel sources make this more clear: bit[0] 1:RGB, 0:YUV
- BIT(1): CFG_VIDEO_RGBIN_ZBLK

> +       /* default black pattern */
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
> +       writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
same as above: ENCL_VIDEO_MODE_ADV_VFIFO_EN

> +
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
> +       writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
note to self: L_RGB_COEFF_ADDR seems to contain some "magic" value,
there's no further info in the 3.10 kernel sources or datasheet

> +       writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
According to the public S905 datasheet BIT(10) is DITH10_EN (10-bits
Dithering to 8 Bits Enable).
I am not sure if this would belong to the selected video mode/bit depth.
I'll let other reviewers decide if this is relevant or not because I don't know.

[...]
> +       writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
> +       writel_relaxed(BIT(4) | BIT(5),
> +                      priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
the public S905 datasheet states:
- BIT(4): STV1_SEL (STV1 is frame Signal)
- BIT(5): STV2_SEL (STV2 is frame Signal)
This doesn't seem helpful to me though, but maybe you can still create
preprocessor macros for this (for consistency)?

[...]
> +       switch (priv->venc.current_mode) {
> +       case MESON_VENC_MODE_MIPI_DSI:
> +               writel_relaxed(0x200,
> +                              priv->io_base + _REG(VENC_INTCTRL));
the public S905 datasheet documents this as:
- BIT(9): ENCP_LNRST_INT_EN (Progressive encoder filed change interrupt enable)
Please add a preprocessor macro to make it consistent with
VENC_INTCTRL_ENCI_LNRST_INT_EN which already exists and is used below.


Best regards,
Martin


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:35:16 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:35:16 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220107145515.613009-6-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-6-narmstrong@baylibre.com>
Message-ID: <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>

Hi Neil,

On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:

[...]
> +       writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
see my comment on patch #3 from this series for BIT(3)


Best regards,
Martin


From james.quinlan at broadcom.com  Fri Jan  7 14:36:55 2022
From: james.quinlan at broadcom.com (Jim Quinlan)
Date: Fri, 7 Jan 2022 17:36:55 -0500
Subject: [PATCH v1 0/4] PCI: brcmstb: Augment driver for MIPs SOCs
In-Reply-To: <20220105104202.GD7009@alpha.franken.de>
References: <20211209204726.6676-1-jim2101024@gmail.com>
 <20220105104202.GD7009@alpha.franken.de>
Message-ID: <CA+-6iNyjDvuTFo9usprg9OX9a-vsieoh2z2-KAfaxAAZ2cw_Og@mail.gmail.com>

On Wed, Jan 5, 2022 at 5:42 AM Thomas Bogendoerfer
<tsbogend at alpha.franken.de> wrote:
>
> On Thu, Dec 09, 2021 at 03:47:21PM -0500, Jim Quinlan wrote:
> > With this patchset, the Broadcom STB PCIe controller driver
> > supports Arm, Arm64, and now MIPs.
> >
> > Jim Quinlan (4):
> >   dt-bindings: PCI: Add compatible string for Brcmstb 74[23]5 MIPs SOCs
> >   MIPS: bmips: Add support PCIe controller device nodes
> >   MIPS: bmips: Remove obsolete DMA mapping support
> >   PCI: brcmstb: Augment driver for MIPs SOCs
> >
> >  .../bindings/pci/brcm,stb-pcie.yaml           |   2 +
> >  arch/mips/Kconfig                             |   1 -
> >  arch/mips/bmips/dma.c                         | 106 +-----------------
> >  arch/mips/boot/dts/brcm/bcm7425.dtsi          |  30 +++++
> >  arch/mips/boot/dts/brcm/bcm7435.dtsi          |  30 +++++
> >  arch/mips/boot/dts/brcm/bcm97425svmb.dts      |   9 ++
> >  arch/mips/boot/dts/brcm/bcm97435svmb.dts      |   9 ++
> >  drivers/pci/controller/Kconfig                |   2 +-
> >  drivers/pci/controller/pcie-brcmstb.c         |  82 +++++++++++++-
> >  9 files changed, 161 insertions(+), 110 deletions(-)
>
> if nobody objects I'd like to add this series to mips-next.
Hi Thomas,

I have another pullreq in progress [1] that may possibly be accepted
soon.  I have tested that
these two pullreqs do not conflict or cause compiler errors regardless
of their merge order.

Regards,
Jim Quinlan
Broadcom STB

[1] [PATCH v10 0/7] PCI: brcmstb: root port turns on sub-device power


[PATCH v10 0/7] PCI: brcmstb: root port turns on sub-device power

>
> Thomas.
>
> --
> Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
> good idea.                                                [ RFC1925, 2.3 ]


From martin.blumenstingl at googlemail.com  Fri Jan  7 14:49:15 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Fri, 7 Jan 2022 23:49:15 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220107145515.613009-7-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-7-narmstrong@baylibre.com>
Message-ID: <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>

Hi Neil,

some high-level comments from me below.

On Fri, Jan 7, 2022 at 3:58 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
[...]
> +/*  MIPI DSI Relative REGISTERs Definitions */
> +/* For MIPI_DSI_TOP_CNTL */
> +#define BIT_DPI_COLOR_MODE        20
> +#define BIT_IN_COLOR_MODE         16
> +#define BIT_CHROMA_SUBSAMPLE      14
> +#define BIT_COMP2_SEL             12
> +#define BIT_COMP1_SEL             10
> +#define BIT_COMP0_SEL              8
> +#define BIT_DE_POL                 6
> +#define BIT_HSYNC_POL              5
> +#define BIT_VSYNC_POL              4
> +#define BIT_DPICOLORM              3
> +#define BIT_DPISHUTDN              2
> +#define BIT_EDPITE_INTR_PULSE      1
> +#define BIT_ERR_INTR_PULSE         0
Why not use BIT() and GENMASK() for these and prefixing them with
MIPI_DSI_TOP_CNTL_?
That would make them consistent with other parts of the meson sub-driver.

[...]
> +static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
> +{
> +       writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
> +                      mipi_dsi->base + MIPI_DSI_TOP_CNTL);
please use the macros from above

> +       writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> +       writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);

[...]
> +       phy_power_on(mipi_dsi->phy);
Please propagate the error code here.
Also shouldn't this go to a new dw_mipi_dsi_phy_power_on() as the PHY
driver uses the updated settings from phy_configure only in it's
.power_on callback?

[...]
> +       phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
please propagate the error code here as the PHY driver has some
explicit code to return an error in it's .phy_configure callback

[...]
> +       phy_init(mipi_dsi->phy);
please propagate the error code here

[...]
> +       phy_exit(mipi_dsi->phy);
please propagate the error code here

[...]
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
other parts of the meson DRM driver have been converted to use
devm_platform_ioremap_resource()
I suggest updating this as well to simplify the code here

[...]
> +       mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
> +       if (IS_ERR(mipi_dsi->phy)) {
> +               ret = PTR_ERR(mipi_dsi->phy);
> +               dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
> +               return ret;
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->phy, "failed to
get mipi dphy\n");

[...]
> +       mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
> +       if (IS_ERR(mipi_dsi->px_clk)) {
> +               dev_err(&pdev->dev, "Unable to get PLL clk\n");
> +               return PTR_ERR(mipi_dsi->px_clk);
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->px_clk, "Unable
to get PLL clk\n");
Also should it say s/PLL clk/px clock/?

[...]
> +       top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
> +       if (IS_ERR(top_rst)) {
> +               ret = PTR_ERR(top_rst);
> +
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
> +
> +               return ret;
you can simplify this with:
  return dev_err_probe(&pdev->dev, PTR_ERR(top_rst, "Unable to get
reset control\n");

[...]
> +       mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
> +       if (IS_ERR(mipi_dsi->dmd)) {
> +               ret = PTR_ERR(mipi_dsi->dmd);
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&pdev->dev,
> +                               "Failed to probe dw_mipi_dsi: %d\n", ret);
you can simplify this with:
  dev_err_probe(&pdev->dev, ret, "Failed to probe dw_mipi_dsi\n");


Best regards,
Martin


From helgaas at kernel.org  Fri Jan  7 15:01:55 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 17:01:55 -0600
Subject: [PATCH 05/15] PCI: mvebu: Disallow mapping interrupts on
 emulated bridges
In-Reply-To: <20220107221348.5s4ehqhxunmoacbm@pali>
Message-ID: <20220107230155.GA425110@bhelgaas>

On Fri, Jan 07, 2022 at 11:13:48PM +0100, Pali Roh?r wrote:
> On Friday 07 January 2022 15:32:16 Bjorn Helgaas wrote:
> > On Thu, Nov 25, 2021 at 01:45:55PM +0100, Pali Roh?r wrote:
> > > Interrupt support on mvebu emulated bridges is not implemented yet.
> > 
> > Is this mvebu-specific, or is aardvar also affected?
> 
> This is pci-mvebu.c driver specific, it does not implement emulation of
> neither INTx, nor MSI interrupts for emulated pci bridge (root port). As
> we know this HW does not have compliant pci root port, it needs to be
> emulated in driver, and emulation for interrupts is missing. (it means
> that also AER interrupt is missing).
> 
> And pci-aardvark.c driver has same issue and similar patch is required
> for pci-aardvark.c too. Marek should take care of it. But for
> pci-aardvark we already have implementation which emulates INTx
> interrupts and it is waiting for review on the list:
> https://lore.kernel.org/linux-pci/20211208061851.31867-1-kabel at kernel.org/
> 
> > > So properly indicate return value to callers that they cannot request
> > > interrupts from emulated bridge.
> > 
> > Pet peeve: descriptions that say "do this *properly*".  As though the
> > previous authors were just ignorant or intentionally did something
> > *improperly* :)
> > 
> > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > Cc: stable at vger.kernel.org
> > > ---
> > >  drivers/pci/controller/pci-mvebu.c | 10 ++++++++++
> > >  1 file changed, 10 insertions(+)
> > > 
> > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > index 19c6ee298442..a3df352d440e 100644
> > > --- a/drivers/pci/controller/pci-mvebu.c
> > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > @@ -705,6 +705,15 @@ static struct pci_ops mvebu_pcie_ops = {
> > >  	.write = mvebu_pcie_wr_conf,
> > >  };
> > >  
> > > +static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > > +{
> > > +	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> > > +	if (dev->bus->number == 0)
> > > +		return 0; /* Proper return code 0 == NO_IRQ */
> > > +
> > > +	return of_irq_parse_and_map_pci(dev, slot, pin);
> > 
> > Is this something that could be done with a .read_base() op, e.g.,
> > make PCI_INTERRUPT_PIN contain zero (PCI_INTERRUPT_UNKNOWN)?
> 
> I'm not sure... maybe. I choose this style as after I implement
> emulation of INTx interrupts it allows me just to replace "return 0;" by
> "return my_mapping_function_for_root_port(...);". 

OK, so even after you implement INTx for the emulated Root Ports, the
default of_irq_parse_and_map_pci() is insufficient, and you will
require an mvebu .map_irq() function.  That's reasonable.

"PCI_INTERRUPT_PIN == 0" is the way software learns that a device
doesn't use INTx, of course, and I suppose PCI_INTERRUPT_PIN already
reads as zero, since mvebu_pci_bridge_emul_init() doesn't set
bridge->conf.intpin, and I assume the default value would be zero?

Bjorn


From pali at kernel.org  Fri Jan  7 15:11:55 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 8 Jan 2022 00:11:55 +0100
Subject: [PATCH 05/15] PCI: mvebu: Disallow mapping interrupts on
 emulated bridges
In-Reply-To: <20220107230155.GA425110@bhelgaas>
References: <20220107221348.5s4ehqhxunmoacbm@pali>
 <20220107230155.GA425110@bhelgaas>
Message-ID: <20220107231155.juv4skvyqunuilgk@pali>

On Friday 07 January 2022 17:01:55 Bjorn Helgaas wrote:
> On Fri, Jan 07, 2022 at 11:13:48PM +0100, Pali Roh?r wrote:
> > On Friday 07 January 2022 15:32:16 Bjorn Helgaas wrote:
> > > On Thu, Nov 25, 2021 at 01:45:55PM +0100, Pali Roh?r wrote:
> > > > Interrupt support on mvebu emulated bridges is not implemented yet.
> > > 
> > > Is this mvebu-specific, or is aardvar also affected?
> > 
> > This is pci-mvebu.c driver specific, it does not implement emulation of
> > neither INTx, nor MSI interrupts for emulated pci bridge (root port). As
> > we know this HW does not have compliant pci root port, it needs to be
> > emulated in driver, and emulation for interrupts is missing. (it means
> > that also AER interrupt is missing).
> > 
> > And pci-aardvark.c driver has same issue and similar patch is required
> > for pci-aardvark.c too. Marek should take care of it. But for
> > pci-aardvark we already have implementation which emulates INTx
> > interrupts and it is waiting for review on the list:
> > https://lore.kernel.org/linux-pci/20211208061851.31867-1-kabel at kernel.org/
> > 
> > > > So properly indicate return value to callers that they cannot request
> > > > interrupts from emulated bridge.
> > > 
> > > Pet peeve: descriptions that say "do this *properly*".  As though the
> > > previous authors were just ignorant or intentionally did something
> > > *improperly* :)
> > > 
> > > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > > Cc: stable at vger.kernel.org
> > > > ---
> > > >  drivers/pci/controller/pci-mvebu.c | 10 ++++++++++
> > > >  1 file changed, 10 insertions(+)
> > > > 
> > > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > > index 19c6ee298442..a3df352d440e 100644
> > > > --- a/drivers/pci/controller/pci-mvebu.c
> > > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > > @@ -705,6 +705,15 @@ static struct pci_ops mvebu_pcie_ops = {
> > > >  	.write = mvebu_pcie_wr_conf,
> > > >  };
> > > >  
> > > > +static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> > > > +{
> > > > +	/* Interrupt support on mvebu emulated bridges is not implemented yet */
> > > > +	if (dev->bus->number == 0)
> > > > +		return 0; /* Proper return code 0 == NO_IRQ */
> > > > +
> > > > +	return of_irq_parse_and_map_pci(dev, slot, pin);
> > > 
> > > Is this something that could be done with a .read_base() op, e.g.,
> > > make PCI_INTERRUPT_PIN contain zero (PCI_INTERRUPT_UNKNOWN)?
> > 
> > I'm not sure... maybe. I choose this style as after I implement
> > emulation of INTx interrupts it allows me just to replace "return 0;" by
> > "return my_mapping_function_for_root_port(...);". 
> 
> OK, so even after you implement INTx for the emulated Root Ports, the
> default of_irq_parse_and_map_pci() is insufficient, and you will
> require an mvebu .map_irq() function.  That's reasonable.
> 
> "PCI_INTERRUPT_PIN == 0" is the way software learns that a device
> doesn't use INTx, of course, and I suppose PCI_INTERRUPT_PIN already
> reads as zero, since mvebu_pci_bridge_emul_init() doesn't set
> bridge->conf.intpin, and I assume the default value would be zero?
> 
> Bjorn

Yes, looks like that zeros are in emulated config space for fields not
explicitly initialized. Which is the pci-mvebu.c case.

But now I'm looking at pci-aardvark.c driver and it sets
PCI_INTERRUPT_PIN register to A:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/pci-aardvark.c?h=v5.16-rc8#n953
And that comment "/* Support interrupt A for MSI feature */" must be
total nonsense as INTA for sure is not required for MSI... Plus we know
that pci-aardvark.c driver does not implement for pci bridge neither
INTx nor MSI... Ach... seems that this code is here since beginning and
needs to be fixed...


From helgaas at kernel.org  Fri Jan  7 15:16:17 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 17:16:17 -0600
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220107222826.cv2bzywwayjwzy3c@pali>
Message-ID: <20220107231617.GA425878@bhelgaas>

On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > Properly propagate failure from mvebu_pcie_add_windows() function back to
> > > the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> > > PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> > > On error set base value higher than limit value which indicates that
> > > address range is disabled. 
> > 
> > Does the spec say that if software programs something invalid,
> > hardware should proactively set the base and limit registers to
> > disable the window?
> 
> No. But this patch address something totally different. Software can do
> fully valid operation, e.g. try to set forwarding memory window as large
> as possible. But because this driver "emulates" pci bridge by calling
> software/kernel function (mvebu_pcie_add_windows), some operations which
> in real HW cannot happen, are possible in software.
> 
> For example there are limitations in sizes of forwarding memory windows,
> because it is done by mvebu-mbus driver, which is responsible for
> configuring mapping and forwarding of PCIe I/O and MEM windows. And due
> to Marvell HW, there are restrictions which are not in PCIe HW.
> 
> Currently if such error happens, obviously kernel is not able to set
> PCIe windows and it just print warnings to dmesg. Trying to access these
> windows would result in the worst case in crashes.
> 
> With this change when mvebu_pcie_add_windows() function fails then into
> emulated config space is put information that particular forwarding
> window is disabled. I think that it is better to indicate it in config
> space what is the current "reality" of hardware configuration. If window
> is disabled in real-HW (meaning in mvebu-mbus driver) then show it also
> in emulated config space of pci bridge.
> 
> Do you have better idea what should emulated pci bridge do, if software
> try to set fully valid configuration of forwarding window, but it is not
> possible to achieve it (even compliant PCI bridge must be able to do
> it)?

On an ACPI system, the host bridge window sizes are constrained by the
host bridge _CRS method.  I assume there's a similar constraint in DT.

Is the fact that mvebu_pcie_add_windows() can fail a symptom of a DT
that describes more available space than mvebu-bus can map?

> > I'm not sure I've seen hardware that does this, and it seems ... maybe
> > a little aggressive.
> > 
> > What happens if software writes the base and limit in the wrong order,
> > so the window is invalid after the first write but valid after the
> > second?  That actually sounds like it could be a sensible strategy to
> > prevent a partially-configured window from being active.
> 
> Invalid window (limit < base) means that window is disabled. And
> pci-mvebu.c in its callbacks from pci-bridge-emul.c should correctly
> handle it and propagates information about disablement to mvebu-mbus
> driver.
> 
> After window is valid again (limit > base) then pci-mvebu.c call
> mvebu-mbus to setup new mapping.

Not sure I'm understanding the code correctly.  Here's the sort of
thing I'm worried about, but maybe this is actually impossible:

Let's say software writes (0x00, 0xff) to the I/O (base, limit), which
describes the [io 0x0000-0xffff] window.  If mvebu-mbus can't handle
that, it looks like you set the (base, limit) to (0xf0, 0x0f), which
would describe [io 0xf000-0x0fff], which is invalid.

The software writes 0x40 to the limit, so now we have (0xf0, 0x40), or
[io 0xf000-0x40ff].  That's still invalid, but software thinks the
0x00 it wrote to the base is still there.

Bjorn


From helgaas at kernel.org  Fri Jan  7 15:17:34 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 7 Jan 2022 17:17:34 -0600
Subject: [PATCH 3/3] PCI: aardvark: Implement emulated root PCI bridge
In-Reply-To: <20220107212736.GA404447@bhelgaas>
Message-ID: <20220107231734.GA426583@bhelgaas>

[+cc Pali; sorry, I meant to cc you on this but forgot]

On Fri, Jan 07, 2022 at 03:27:38PM -0600, Bjorn Helgaas wrote:
> On Fri, Jun 29, 2018 at 11:22:31AM +0200, Thomas Petazzoni wrote:
> 
> > +static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
> > +{
> > +	struct pci_sw_bridge *bridge = &pcie->bridge;
> 
> > +	/* Support interrupt A for MSI feature */
> > +	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
> 
> Only 3.5 years later, IIUC, this is the value you get when you read
> PCI_INTERRUPT_PIN, so I think this should be PCI_INTERRUPT_INTA, not
> PCIE_CORE_INT_A_ASSERT_ENABLE.
> 
> Readers expect to get the values defined in the PCI spec, i.e.,
> 
>   PCI_INTERRUPT_UNKNOWN
>   PCI_INTERRUPT_INTA
>   PCI_INTERRUPT_INTB
>   PCI_INTERRUPT_INTC
>   PCI_INTERRUPT_INTD
> 
> Bjorn


From keescook at chromium.org  Fri Jan  7 15:27:46 2022
From: keescook at chromium.org (Kees Cook)
Date: Fri,  7 Jan 2022 15:27:46 -0800
Subject: [PATCH] arm64: atomics: Dereference matching size
Message-ID: <20220107232746.1540130-1-keescook@chromium.org>

When building with -Warray-bounds (which is desired to be enabled
globally), the following warning is generated:

In file included from ./arch/arm64/include/asm/lse.h:16,
                 from ./arch/arm64/include/asm/cmpxchg.h:14,
                 from ./arch/arm64/include/asm/atomic.h:16,
                 from ./include/linux/atomic.h:7,
                 from ./include/asm-generic/bitops/atomic.h:5,
                 from ./arch/arm64/include/asm/bitops.h:25,
                 from ./include/linux/bitops.h:33,
                 from ./include/linux/kernel.h:22,
                 from kernel/printk/printk.c:22:
./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
  247 |         asm volatile(                                                   \
      |         ^~~
./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
  266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
      | ^~~~~~~~~~~~~~
kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
 3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
      |                 ^~~~~~~~~~~~~~~~~~~~

This is due to the compiler seeing an unsigned long * cast against
something (atomic_t) that is int sized. Replace the cast with the
matching size cast. This results in no change in binary output.

Cc: Will Deacon <will at kernel.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Boqun Feng <boqun.feng at gmail.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Kees Cook <keescook at chromium.org>
---
 arch/arm64/include/asm/atomic_lse.h | 2 +-
 arch/arm64/include/asm/cmpxchg.h    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index d955ade5df7c..5d460f6b7675 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -249,7 +249,7 @@ __lse__cmpxchg_case_##name##sz(volatile void *ptr,			\
 	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
 	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
 	"	mov	%" #w "[ret], %" #w "[tmp]"			\
-	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
+	: [ret] "+r" (x0), [v] "+Q" (*(u##sz *)ptr),			\
 	  [tmp] "=&r" (tmp)						\
 	: [old] "r" (x1), [new] "r" (x2)				\
 	: cl);								\
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index f9bef42c1411..497acf134d99 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -243,7 +243,7 @@ static inline void __cmpwait_case_##sz(volatile void *ptr,		\
 	"	cbnz	%" #w "[tmp], 1f\n"				\
 	"	wfe\n"							\
 	"1:"								\
-	: [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr)		\
+	: [tmp] "=&r" (tmp), [v] "+Q" (*(u##sz *)ptr)			\
 	: [val] "r" (val));						\
 }
 
-- 
2.30.2



From keescook at chromium.org  Fri Jan  7 15:34:18 2022
From: keescook at chromium.org (Kees Cook)
Date: Fri, 7 Jan 2022 15:34:18 -0800
Subject: [PATCH v6] sun4i-emac.c: add dma support
In-Reply-To: <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
References: <20211228164817.1297c1c9@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
Message-ID: <202201071532.57A08030@keescook>

On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee at foxmail.com wrote:
> From: Conley Lee <conleylee at foxmail.com>
>
> Thanks for your review. Here is the new version for this patch.
>
> This patch adds support for the emac rx dma present on sun4i. The emac
> is able to move packets from rx fifo to RAM by using dma.
>
> Change since v4.
>   - rename sbk field to skb
>   - rename alloc_emac_dma_req to emac_alloc_dma_req
>   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
>     sleeping
>   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
>   - fix some code style issues
>
> Change since v5.
>   - fix some code style issue
>
> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 200 ++++++++++++++++++++
>  1 file changed, 200 insertions(+)

This is causing build failures:

$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
$ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                           ~^
      |                                                            |                                      |                                                            unsigned int
      |                                                           %llx
  923 |                     regs->start, resource_size(regs));
      |                     ~~~~~~~~~~~
      |                         |
      |                         resource_size_t {aka long long unsigned int}
drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
  922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
      |                                                                      ~^
      |                                                                       |
      |                                                                       unsigned int
      |                                                                      %llu
  923 |                     regs->start, resource_size(regs));
      |                                  ~~~~~~~~~~~~~~~~~~~
      |                                  |
      |                                  resource_size_t {aka long long unsigned int}


--
Kees Cook


From yuzhao at google.com  Fri Jan  7 15:36:11 2022
From: yuzhao at google.com (Yu Zhao)
Date: Fri, 7 Jan 2022 16:36:11 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz>
Message-ID: <YdjOazilBEkdUT7x@google.com>

On Fri, Jan 07, 2022 at 02:11:29PM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> [...]
> > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
> > +{
> > +	struct mem_cgroup *memcg;
> > +	bool success = false;
> > +	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
> > +
> > +	VM_BUG_ON(!current_is_kswapd());
> > +
> > +	current->reclaim_state->mm_walk = &pgdat->mm_walk;
> > +
> > +	memcg = mem_cgroup_iter(NULL, NULL, NULL);
> > +	do {
> > +		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
> > +
> > +		if (age_lruvec(lruvec, sc, min_ttl))
> > +			success = true;
> > +
> > +		cond_resched();
> > +	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
> > +
> > +	if (!success && mutex_trylock(&oom_lock)) {
> > +		struct oom_control oc = {
> > +			.gfp_mask = sc->gfp_mask,
> > +			.order = sc->order,
> > +		};
> > +
> > +		if (!oom_reaping_in_progress())
> > +			out_of_memory(&oc);
> > +
> > +		mutex_unlock(&oom_lock);
> > +	}
> 
> Why do you need to trigger oom killer from this path? Why cannot you
> rely on the page allocator to do that like we do now?

This is per desktop users' (repeated) requests. The can't tolerate
thrashing as servers do because of UI lags; and they usually don't
have fancy tools like oomd.

Related discussions I saw:
https://github.com/zen-kernel/zen-kernel/issues/218
https://lore.kernel.org/lkml/20101028191523.GA14972 at google.com/
https://lore.kernel.org/lkml/20211213051521.21f02dd2 at mail.inbox.lv/
https://lore.kernel.org/lkml/54C2C89C.8080002 at gmail.com/
https://lore.kernel.org/lkml/d9802b6a-949b-b327-c4a6-3dbca485ec20 at gmx.com/

>From patch 8:
  Personal computers
  ------------------
  :Thrashing prevention: Write ``N`` to
   ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
   ``N`` milliseconds from getting evicted. The OOM killer is invoked if
   this working set can't be kept in memory. Based on the average human
   detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
   lags due to thrashing. Larger values like ``N=3000`` make lags less
   noticeable at the cost of more OOM kills.


From rananta at google.com  Fri Jan  7 15:43:08 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Fri, 7 Jan 2022 15:43:08 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
Message-ID: <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> Hi Raghu,
>
> On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > Capture the start of the KVM VM, which is basically the
> > start of any vCPU run. This state of the VM is helpful
> > in the upcoming patches to prevent user-space from
> > configuring certain VM features after the VM has started
> > running.
> >
> > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > ---
> >  include/linux/kvm_host.h | 3 +++
> >  virt/kvm/kvm_main.c      | 9 +++++++++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > index c310648cc8f1..d0bd8f7a026c 100644
> > --- a/include/linux/kvm_host.h
> > +++ b/include/linux/kvm_host.h
> > @@ -623,6 +623,7 @@ struct kvm {
> >         struct notifier_block pm_notifier;
> >  #endif
> >         char stats_id[KVM_STATS_NAME_SIZE];
> > +       bool vm_started;
>
> Since KVM_RUN on any vCPUs doesn't necessarily mean that the VM
> started yet, the name might be a bit misleading IMHO.  I would
> think 'has_run_once' or 'ran_once' might be more clear (?).
>
I always struggle with the names; but if you feel that 'ran_once'
makes more sense for a reader, I can change it.
>
> >  };
> >
> >  #define kvm_err(fmt, ...) \
> > @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> >         }
> >  }
> >
> > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> > +
> >  extern bool kvm_rebooting;
> >
> >  extern unsigned int halt_poll_ns;
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 72c4e6b39389..962b91ac2064 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
> >         int r;
> >         struct kvm_fpu *fpu = NULL;
> >         struct kvm_sregs *kvm_sregs = NULL;
> > +       struct kvm *kvm = vcpu->kvm;
> >
> >         if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
> >                 return -EIO;
> > @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
> >                         if (oldpid)
> >                                 synchronize_rcu();
> >                         put_pid(oldpid);
> > +
> > +                       /*
> > +                        * Since we land here even on the first vCPU run,
> > +                        * we can mark that the VM has started running.
> > +                        */
>
> It might be nicer to add a comment why the code below gets kvm->lock.
>
I've been going back and forth on this one. Initially I considered
simply going with atomic_t, but the patch 4/11 (KVM: arm64: Setup a
framework for hypercall bitmap firmware registers)
kvm_arm_set_fw_reg_bmap()'s implementation felt like we need a lock to
have the whole 'is the register busy?' operation atomic. But, that's
just one of the applications.
> Anyway, the patch generally looks good to me, and thank you
> for making this change (it works for my purpose as well).
>
> Reviewed-by: Reiji Watanabe <reijiw at google.com>
>
Glad that it's helping you as well and thanks for the review.

Regards,
Raghavendra

> Thanks,
> Reiji
>
>
> > +                       mutex_lock(&kvm->lock);
> > +                       kvm->vm_started = true;
> > +                       mutex_unlock(&kvm->lock);
> >                 }
> >                 r = kvm_arch_vcpu_ioctl_run(vcpu);
> >                 trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >


From pali at kernel.org  Fri Jan  7 15:46:58 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 8 Jan 2022 00:46:58 +0100
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220107231617.GA425878@bhelgaas>
References: <20220107222826.cv2bzywwayjwzy3c@pali>
 <20220107231617.GA425878@bhelgaas>
Message-ID: <20220107234658.oav7oofcbwa7o6sz@pali>

On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > Properly propagate failure from mvebu_pcie_add_windows() function back to
> > > > the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> > > > PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> > > > On error set base value higher than limit value which indicates that
> > > > address range is disabled. 
> > > 
> > > Does the spec say that if software programs something invalid,
> > > hardware should proactively set the base and limit registers to
> > > disable the window?
> > 
> > No. But this patch address something totally different. Software can do
> > fully valid operation, e.g. try to set forwarding memory window as large
> > as possible. But because this driver "emulates" pci bridge by calling
> > software/kernel function (mvebu_pcie_add_windows), some operations which
> > in real HW cannot happen, are possible in software.
> > 
> > For example there are limitations in sizes of forwarding memory windows,
> > because it is done by mvebu-mbus driver, which is responsible for
> > configuring mapping and forwarding of PCIe I/O and MEM windows. And due
> > to Marvell HW, there are restrictions which are not in PCIe HW.
> > 
> > Currently if such error happens, obviously kernel is not able to set
> > PCIe windows and it just print warnings to dmesg. Trying to access these
> > windows would result in the worst case in crashes.
> > 
> > With this change when mvebu_pcie_add_windows() function fails then into
> > emulated config space is put information that particular forwarding
> > window is disabled. I think that it is better to indicate it in config
> > space what is the current "reality" of hardware configuration. If window
> > is disabled in real-HW (meaning in mvebu-mbus driver) then show it also
> > in emulated config space of pci bridge.
> > 
> > Do you have better idea what should emulated pci bridge do, if software
> > try to set fully valid configuration of forwarding window, but it is not
> > possible to achieve it (even compliant PCI bridge must be able to do
> > it)?
> 
> On an ACPI system, the host bridge window sizes are constrained by the
> host bridge _CRS method.  I assume there's a similar constraint in DT.
> 
> Is the fact that mvebu_pcie_add_windows() can fail a symptom of a DT
> that describes more available space than mvebu-bus can map?

Memory maps for mvebu are more complicated. There is no explicit size in
DT ranges property as it is dynamically allocated by mvebu-mbus:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47

On some Armada platform (I think it is AXP) there is lot of SerDeses
with PCIe functionality (I think six or seven?) but "shared memory pool"
which mvebu-mbus allocates to consumers is not big enough to allow e.g.
256 MB + 64 kB for every PCIe port.

There is upper limit of mvebu memory slots in HW and each slot has size
restrictions. So mvebu-mbus has to deal with splitting requested
PCIe window to more mvebu memory slots... So even if there is available
memory for assigning then there does not have to be a free slot.

Due to nature of plugable PCIe expansion cards, you are basically free
to put any PCIe card which you like into any PCIe slot. So it would be
up to the user to choose combination of such cards which pass all those
mvebu windows and slots restrictions... Otherwise kernel just say that
cannot satisfy card's BAR assignment because it is not possible to set
forwarding windows correctly.

Moreover it is possible to bind / unbind pci mvebu device dynamically at
runtime (also by rmmod), so whole resource allocation in mvebu-bus is
dynamic even during system runtime. So theoretically user can unbind one
driver to free some memory and then can bind another (which needs more
memory).

I think that this pci-mvebu driver and HW is very unusual in both
resource assignment and supported features and requirements from SW.

> > > I'm not sure I've seen hardware that does this, and it seems ... maybe
> > > a little aggressive.
> > > 
> > > What happens if software writes the base and limit in the wrong order,
> > > so the window is invalid after the first write but valid after the
> > > second?  That actually sounds like it could be a sensible strategy to
> > > prevent a partially-configured window from being active.
> > 
> > Invalid window (limit < base) means that window is disabled. And
> > pci-mvebu.c in its callbacks from pci-bridge-emul.c should correctly
> > handle it and propagates information about disablement to mvebu-mbus
> > driver.
> > 
> > After window is valid again (limit > base) then pci-mvebu.c call
> > mvebu-mbus to setup new mapping.
> 
> Not sure I'm understanding the code correctly.  Here's the sort of
> thing I'm worried about, but maybe this is actually impossible:
> 
> Let's say software writes (0x00, 0xff) to the I/O (base, limit), which
> describes the [io 0x0000-0xffff] window.  If mvebu-mbus can't handle
> that, it looks like you set the (base, limit) to (0xf0, 0x0f), which
> would describe [io 0xf000-0x0fff], which is invalid.
> 
> The software writes 0x40 to the limit, so now we have (0xf0, 0x40), or
> [io 0xf000-0x40ff].  That's still invalid, but software thinks the
> 0x00 it wrote to the base is still there.
> 
> Bjorn

I see. In this situation it does not work correctly.

But is not kernel itself "privileged" to setup forwarding windows?
Because currently kernel does not do it and therefore do we need to care
for it?

Or do you have idea how to handle this kind of situation? Or how to
handle these kinds of errors?


From gascoar at gmail.com  Fri Jan  7 15:46:18 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Fri,  7 Jan 2022 20:46:18 -0300
Subject: [PATCH 0/2] staging: vc04_services: cleanup macros
 BM2835_MMAL_VERSION and BM2835_MMAL_MODULE_NAME
Message-ID: <20220107234620.49900-1-gascoar@gmail.com>

These two patches cleanup the macros BM2835_MMAL_VERSION and
BM2835_MMAL_MODULE_NAME.

Gaston Gonzalez (2):
  staging: vc04_services: remove unneeded MODULE_VERSION() usage
  staging: vc04_services: use KBUILD_MODNAME instead of own module name
    definition

 .../vc04_services/bcm2835-camera/bcm2835-camera.c      | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

-- 
2.34.1



From gascoar at gmail.com  Fri Jan  7 15:46:20 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Fri,  7 Jan 2022 20:46:20 -0300
Subject: [PATCH 1/2] staging: vc04_services: remove unneeded MODULE_VERSION()
 usage
In-Reply-To: <20220107234620.49900-1-gascoar@gmail.com>
References: <20220107234620.49900-1-gascoar@gmail.com>
Message-ID: <20220107234620.49900-2-gascoar@gmail.com>

MODULE_VERSION() is useless for in-tree drivers given that only the kernel
version matters. Hence, remove it.

While at it, one realignment was made to improve readability.

Suggested by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 .../staging/vc04_services/bcm2835-camera/bcm2835-camera.c   | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 253d755e547f..35ac0fda6e14 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -33,7 +33,6 @@
 #include "mmal-parameters.h"
 #include "bcm2835-camera.h"
 
-#define BM2835_MMAL_VERSION "0.0.2"
 #define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
 #define MIN_WIDTH 32
 #define MIN_HEIGHT 32
@@ -1954,9 +1953,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 			goto unreg_dev;
 		}
 
-		v4l2_info(&dev->v4l2_dev,
-			  "Broadcom 2835 MMAL video capture ver %s loaded.\n",
-			  BM2835_MMAL_VERSION);
+		v4l2_info(&dev->v4l2_dev, "Broadcom 2835 MMAL video capture loaded.\n");
 
 		gdev[camera] = dev;
 	}
@@ -2008,5 +2005,4 @@ module_platform_driver(bcm2835_camera_driver)
 MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture");
 MODULE_AUTHOR("Vincent Sanders");
 MODULE_LICENSE("GPL");
-MODULE_VERSION(BM2835_MMAL_VERSION);
 MODULE_ALIAS("platform:bcm2835-camera");
-- 
2.34.1



From gascoar at gmail.com  Fri Jan  7 15:46:22 2022
From: gascoar at gmail.com (Gaston Gonzalez)
Date: Fri,  7 Jan 2022 20:46:22 -0300
Subject: [PATCH 2/2] staging: vc04_services: use KBUILD_MODNAME instead of own
 module name definition
In-Reply-To: <20220107234620.49900-1-gascoar@gmail.com>
References: <20220107234620.49900-1-gascoar@gmail.com>
Message-ID: <20220107234620.49900-3-gascoar@gmail.com>

Remove own module name definition and use KBUILD_MODNAME instead, which
is the standard way of getting the module name.

While at it, one realignment was made to improve readability.

Suggested-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Gaston Gonzalez <gascoar at gmail.com>
---
 drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
index 35ac0fda6e14..88b1878854e0 100644
--- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
+++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
@@ -33,7 +33,6 @@
 #include "mmal-parameters.h"
 #include "bcm2835-camera.h"
 
-#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
 #define MIN_WIDTH 32
 #define MIN_HEIGHT 32
 #define MIN_BUFFER_SIZE (80 * 1024)
@@ -1893,8 +1892,7 @@ static int bcm2835_mmal_probe(struct platform_device *pdev)
 		dev->capture.fmt = &formats[3]; /* JPEG */
 
 		/* v4l device registration */
-		dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev,
-						       BM2835_MMAL_MODULE_NAME,
+		dev->camera_num = v4l2_device_set_name(&dev->v4l2_dev, KBUILD_MODNAME,
 						       &camera_instance);
 		ret = v4l2_device_register(NULL, &dev->v4l2_dev);
 		if (ret) {
-- 
2.34.1



From briannorris at chromium.org  Fri Jan  7 15:53:10 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:10 -0800
Subject: [PATCH 00/10] rk3399: Clean up and enable DDR DVFS
Message-ID: <20220107235320.965497-1-briannorris@chromium.org>

This series covers 2 primary tasks:

1) Resubmit prior work:

[RESEND PATCH v5 3/4] arm64: dts: rockchip: Enable dmc and dfi nodes on gru.
https://lore.kernel.org/lkml/20210308233858.24741-2-daniel.lezcano at linaro.org/
[RESEND PATCH v5 2/4] arm64: dts: rk3399: Add dfi and dmc nodes.
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/

This series was partially merged a while back, but the remaining 2
patches were blocked mostly on stylistic grounds (alpha/numerical
ordering).

2) Integrate many updates, bugfixes, and clarifications that were done
by Rockchip and Google engineers when first launching this platform.
Many of these were not integrated in the earlier series (e.g., the OPPs
changed before production; earlier patchsets used pre-production
numbers).

Along the way, it seemed worthwhile to convert the binding docs to a
schema. Among other reasons, it actually helped catch several errors and
omissions in translation between downstream device trees and the version
that actually landed upstream.

See the patches for further details.

Regards,
Brian


Brian Norris (8):
  dt-bindings: devfreq: rk3399_dmc: Convert to YAML
  dt-bindings: devfreq: rk3399_dmc: Deprecate unused/redundant
    properties
  dt-bindings: devfreq: rk3399_dmc: Fix Hz units
  dt-bindings: devfreq: rk3399_dmc: Add more disable-freq properties
  PM / devfreq: rk3399_dmc: Drop undocumented ondemand DT props
  PM / devfreq: rk3399_dmc: Drop excess timing properties
  PM / devfreq: rk3399_dmc: Use bitfield macro definitions for ODT_PD
  PM / devfreq: rk3399_dmc: Support new disable-freq properties

Lin Huang (2):
  arm64: dts: rk3399: Add dfi and dmc nodes
  arm64: dts: rockchip: Enable dmc and dfi nodes on gru

 .../bindings/devfreq/rk3399_dmc.txt           | 212 -----------
 .../bindings/devfreq/rk3399_dmc.yaml          | 339 ++++++++++++++++++
 .../dts/rockchip/rk3399-gru-chromebook.dtsi   |   7 +
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi |  12 +
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi  |  28 ++
 .../boot/dts/rockchip/rk3399-op1-opp.dtsi     |  25 ++
 arch/arm64/boot/dts/rockchip/rk3399.dtsi      |  19 +
 drivers/devfreq/rk3399_dmc.c                  | 230 +++++-------
 8 files changed, 525 insertions(+), 347 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml

-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:11 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:11 -0800
Subject: [PATCH 01/10] dt-bindings: devfreq: rk3399_dmc: Convert to YAML
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>

I want to add, deprecate, and bugfix some properties, as well as add the
first users. This is easier with a proper schema.

The transformation is mostly straightforward, plus a few notable tweaks:

 * Renamed rockchip,dram_speed_bin to rockchip,ddr3_speed_bin. The
   driver code and the example matched, but the description was
   different. I went with the implementation.

 * Drop upthreshold and downdifferential properties from the example.
   These were undocumented (so, wouldn't pass validation), but were
   representing software properties (governor tweaks). I drop them from
   the driver in subsequent patches.

 * Rename clock from pclk_ddr_mon to dmc_clk. The driver, DT example,
   and all downstream users matched -- the binding definition was the
   exception. Anyway, "dmc_clk" is a more appropriately generic name.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 .../bindings/devfreq/rk3399_dmc.txt           | 212 -------------
 .../bindings/devfreq/rk3399_dmc.yaml          | 297 ++++++++++++++++++
 2 files changed, 297 insertions(+), 212 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
deleted file mode 100644
index 58fc8a6cebc7..000000000000
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
+++ /dev/null
@@ -1,212 +0,0 @@
-* Rockchip rk3399 DMC (Dynamic Memory Controller) device
-
-Required properties:
-- compatible:		 Must be "rockchip,rk3399-dmc".
-- devfreq-events:	 Node to get DDR loading, Refer to
-			 Documentation/devicetree/bindings/devfreq/event/
-			 rockchip-dfi.txt
-- clocks:		 Phandles for clock specified in "clock-names" property
-- clock-names :		 The name of clock used by the DFI, must be
-			 "pclk_ddr_mon";
-- operating-points-v2:	 Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml
-			 for details.
-- center-supply:	 DMC supply node.
-- status:		 Marks the node enabled/disabled.
-- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
-			 files".
-
-Optional properties:
-- interrupts:		 The CPU interrupt number. The interrupt specifier
-			 format depends on the interrupt controller.
-			 It should be a DCF interrupt. When DDR DVFS finishes
-			 a DCF interrupt is triggered.
-- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
-			 files".
-
-Following properties relate to DDR timing:
-
-- rockchip,dram_speed_bin :	  Value reference include/dt-bindings/clock/rk3399-ddr.h,
-				  it selects the DDR3 cl-trp-trcd type. It must be
-				  set according to "Speed Bin" in DDR3 datasheet,
-				  DO NOT use a smaller "Speed Bin" than specified
-				  for the DDR3 being used.
-
-- rockchip,pd_idle :		  Configure the PD_IDLE value. Defines the
-				  power-down idle period in which memories are
-				  placed into power-down mode if bus is idle
-				  for PD_IDLE DFI clock cycles.
-
-- rockchip,sr_idle :		  Configure the SR_IDLE value. Defines the
-				  self-refresh idle period in which memories are
-				  placed into self-refresh mode if bus is idle
-				  for SR_IDLE * 1024 DFI clock cycles (DFI
-				  clocks freq is half of DRAM clock), default
-				  value is "0".
-
-- rockchip,sr_mc_gate_idle :	  Defines the memory self-refresh and controller
-				  clock gating idle period. Memories are placed
-				  into self-refresh mode and memory controller
-				  clock arg gating started if bus is idle for
-				  sr_mc_gate_idle*1024 DFI clock cycles.
-
-- rockchip,srpd_lite_idle :	  Defines the self-refresh power down idle
-				  period in which memories are placed into
-				  self-refresh power down mode if bus is idle
-				  for srpd_lite_idle * 1024 DFI clock cycles.
-				  This parameter is for LPDDR4 only.
-
-- rockchip,standby_idle :	  Defines the standby idle period in which
-				  memories are placed into self-refresh mode.
-				  The controller, pi, PHY and DRAM clock will
-				  be gated if bus is idle for standby_idle * DFI
-				  clock cycles.
-
-- rockchip,dram_dll_dis_freq :	  Defines the DDR3 DLL bypass frequency in MHz.
-				  When DDR frequency is less than DRAM_DLL_DISB_FREQ,
-				  DDR3 DLL will be bypassed. Note: if DLL was bypassed,
-				  the odt will also stop working.
-
-- rockchip,phy_dll_dis_freq :	  Defines the PHY dll bypass frequency in
-				  MHz (Mega Hz). When DDR frequency is less than
-				  DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
-				  Note: PHY DLL and PHY ODT are independent.
-
-- rockchip,ddr3_odt_dis_freq :	  When the DRAM type is DDR3, this parameter defines
-				  the ODT disable frequency in MHz (Mega Hz).
-				  when the DDR frequency is  less then ddr3_odt_dis_freq,
-				  the ODT on the DRAM side and controller side are
-				  both disabled.
-
-- rockchip,ddr3_drv :		  When the DRAM type is DDR3, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 40.
-
-- rockchip,ddr3_odt :		  When the DRAM type is DDR3, this parameter defines
-				  the DRAM side ODT strength in ohms. Default value
-				  is 120.
-
-- rockchip,phy_ddr3_ca_drv :	  When the DRAM type is DDR3, this parameter defines
-				  the phy side CA line (incluing command line,
-				  address line and clock line) driver strength.
-				  Default value is 40.
-
-- rockchip,phy_ddr3_dq_drv :	  When the DRAM type is DDR3, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 40.
-
-- rockchip,phy_ddr3_odt : 	  When the DRAM type is DDR3, this parameter defines
-				  the PHY side ODT strength. Default value is 240.
-
-- rockchip,lpddr3_odt_dis_freq : When the DRAM type is LPDDR3, this parameter defines
-				  then ODT disable frequency in MHz (Mega Hz).
-				  When DDR frequency is less then ddr3_odt_dis_freq,
-				  the ODT on the DRAM side and controller side are
-				  both disabled.
-
-- rockchip,lpddr3_drv :		  When the DRAM type is LPDDR3, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 34.
-
-- rockchip,lpddr3_odt :		  When the DRAM type is LPDDR3, this parameter defines
-				  the DRAM side ODT strength in ohms. Default value
-				  is 240.
-
-- rockchip,phy_lpddr3_ca_drv :	  When the DRAM type is LPDDR3, this parameter defines
-				  the PHY side CA line (including command line,
-				  address line and clock line) driver strength.
-				  Default value is 40.
-
-- rockchip,phy_lpddr3_dq_drv :	  When the DRAM type is LPDDR3, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 40.
-
-- rockchip,phy_lpddr3_odt : 	  When dram type is LPDDR3, this parameter define
-				  the phy side odt strength, default value is 240.
-
-- rockchip,lpddr4_odt_dis_freq : When the DRAM type is LPDDR4, this parameter
-				  defines the ODT disable frequency in
-				  MHz (Mega Hz). When the DDR frequency is less then
-				  ddr3_odt_dis_freq, the ODT on the DRAM side and
-				  controller side are both disabled.
-
-- rockchip,lpddr4_drv :		  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 60.
-
-- rockchip,lpddr4_dq_odt : 	  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side ODT on DQS/DQ line strength in ohms.
-				  Default value is 40.
-
-- rockchip,lpddr4_ca_odt :	  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side ODT on CA line strength in ohms.
-				  Default value is 40.
-
-- rockchip,phy_lpddr4_ca_drv :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side CA line (including command address
-				  line) driver strength. Default value is 40.
-
-- rockchip,phy_lpddr4_ck_cs_drv : When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side clock line and CS line driver
-				  strength. Default value is 80.
-
-- rockchip,phy_lpddr4_dq_drv :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 80.
-
-- rockchip,phy_lpddr4_odt :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side ODT strength. Default value is 60.
-
-Example:
-	dmc_opp_table: dmc_opp_table {
-		compatible = "operating-points-v2";
-
-		opp00 {
-			opp-hz = /bits/ 64 <300000000>;
-			opp-microvolt = <900000>;
-		};
-		opp01 {
-			opp-hz = /bits/ 64 <666000000>;
-			opp-microvolt = <900000>;
-		};
-	};
-
-	dmc: dmc {
-		compatible = "rockchip,rk3399-dmc";
-		devfreq-events = <&dfi>;
-		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru SCLK_DDRC>;
-		clock-names = "dmc_clk";
-		operating-points-v2 = <&dmc_opp_table>;
-		center-supply = <&ppvar_centerlogic>;
-		upthreshold = <15>;
-		downdifferential = <10>;
-		rockchip,ddr3_speed_bin = <21>;
-		rockchip,pd_idle = <0x40>;
-		rockchip,sr_idle = <0x2>;
-		rockchip,sr_mc_gate_idle = <0x3>;
-		rockchip,srpd_lite_idle	= <0x4>;
-		rockchip,standby_idle = <0x2000>;
-		rockchip,dram_dll_dis_freq = <300>;
-		rockchip,phy_dll_dis_freq = <125>;
-		rockchip,auto_pd_dis_freq = <666>;
-		rockchip,ddr3_odt_dis_freq = <333>;
-		rockchip,ddr3_drv = <40>;
-		rockchip,ddr3_odt = <120>;
-		rockchip,phy_ddr3_ca_drv = <40>;
-		rockchip,phy_ddr3_dq_drv = <40>;
-		rockchip,phy_ddr3_odt = <240>;
-		rockchip,lpddr3_odt_dis_freq = <333>;
-		rockchip,lpddr3_drv = <34>;
-		rockchip,lpddr3_odt = <240>;
-		rockchip,phy_lpddr3_ca_drv = <40>;
-		rockchip,phy_lpddr3_dq_drv = <40>;
-		rockchip,phy_lpddr3_odt = <240>;
-		rockchip,lpddr4_odt_dis_freq = <333>;
-		rockchip,lpddr4_drv = <60>;
-		rockchip,lpddr4_dq_odt = <40>;
-		rockchip,lpddr4_ca_odt = <40>;
-		rockchip,phy_lpddr4_ca_drv = <40>;
-		rockchip,phy_lpddr4_ck_cs_drv = <80>;
-		rockchip,phy_lpddr4_dq_drv = <80>;
-		rockchip,phy_lpddr4_odt = <60>;
-	};
diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
new file mode 100644
index 000000000000..f12f34d93378
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -0,0 +1,297 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# %YAML 1.2
+---
+$id: http://devicetree.org/schemas/devfreq/rk3399_dmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip rk3399 DMC (Dynamic Memory Controller) device
+
+maintainers:
+  - Brian Norris <briannorris at chromium.org>
+
+required:
+  - compatible
+  - devfreq-events
+  - clocks
+  - clock-names
+  - operating-points-v2
+  - center-supply
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3399-dmc
+
+  devfreq-events:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    description:
+      Node to get DDR loading. Refer to
+      Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt.
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+    - const: dmc_clk
+
+  operating-points-v2:
+    description:
+      Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml for details.
+
+  center-supply:
+    description:
+      DMC regulator supply.
+
+  rockchip,pmu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Phandle to the syscon managing the "PMU general register files".
+
+  interrupts:
+    maxItems: 1
+    description:
+      The CPU interrupt number. The interrupt specifier format depends on the
+      interrupt controller. It should be a DCF interrupt. When DDR DVFS
+      finishes a DCF interrupt is triggered.
+
+  rockchip,ddr3_speed_bin:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
+      DDR3 cl-trp-trcd type. It must be set according to "Speed Bin" in DDR3
+      datasheet; DO NOT use a smaller "Speed Bin" than specified for the DDR3
+      being used.
+
+  rockchip,pd_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Configure the PD_IDLE value. Defines the power-down idle period in which
+      memories are placed into power-down mode if bus is idle for PD_IDLE DFI
+      clock cycles.
+
+  rockchip,sr_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Configure the SR_IDLE value. Defines the self-refresh idle period in
+      which memories are placed into self-refresh mode if bus is idle for
+      SR_IDLE * 1024 DFI clock cycles (DFI clocks freq is half of DRAM clock),
+      default value is "0".
+
+  rockchip,sr_mc_gate_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the memory self-refresh and controller clock gating idle period.
+      Memories are placed into self-refresh mode and memory controller clock
+      arg gating started if bus is idle for sr_mc_gate_idle*1024 DFI clock
+      cycles.
+
+  rockchip,srpd_lite_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the self-refresh power down idle period in which memories are
+      placed into self-refresh power down mode if bus is idle for
+      srpd_lite_idle * 1024 DFI clock cycles. This parameter is for LPDDR4
+      only.
+
+  rockchip,standby_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the standby idle period in which memories are placed into
+      self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
+      if bus is idle for standby_idle * DFI clock cycles.
+
+  rockchip,dram_dll_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
+      than DRAM_DLL_DISB_FREQ, DDR3 DLL will be bypassed.
+      Note: if DLL was bypassed, the odt will also stop working.
+
+  rockchip,phy_dll_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
+      is less than DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
+      Note: PHY DLL and PHY ODT are independent.
+
+  rockchip,auto_pd_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the auto PD disable frequency in MHz.
+
+  rockchip,ddr3_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the ODT disable
+      frequency in MHz (Mega Hz). When the DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,ddr3_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 40.
+
+  rockchip,ddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the DRAM side ODT
+      strength in ohms. Default value is 120.
+
+  rockchip,phy_ddr3_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the phy side CA line
+      (incluing command line, address line and clock line) drive strength.
+      Default value is 40.
+
+  rockchip,phy_ddr3_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 40.
+
+  rockchip,phy_ddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the PHY side ODT
+      strength. Default value is 240.
+
+  rockchip,lpddr3_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines then ODT disable
+      frequency in MHz (Mega Hz). When DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,lpddr3_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 34.
+
+  rockchip,lpddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
+      strength in ohms. Default value is 240.
+
+  rockchip,phy_lpddr3_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
+      (including command line, address line and clock line) drive strength.
+      Default value is 40.
+
+  rockchip,phy_lpddr3_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 40.
+
+  rockchip,phy_lpddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When dram type is LPDDR3, this parameter define the phy side odt
+      strength, default value is 240.
+
+  rockchip,lpddr4_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the ODT disable
+      frequency in MHz (Mega Hz). When the DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,lpddr4_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 60.
+
+  rockchip,lpddr4_dq_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
+      DQS/DQ line strength in ohms. Default value is 40.
+
+  rockchip,lpddr4_ca_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
+      CA line strength in ohms. Default value is 40.
+
+  rockchip,phy_lpddr4_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
+      (including command address line) drive strength. Default value is 40.
+
+  rockchip,phy_lpddr4_ck_cs_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side clock
+      line and CS line drive strength. Default value is 80.
+
+  rockchip,phy_lpddr4_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 80.
+
+  rockchip,phy_lpddr4_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
+      strength. Default value is 60.
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3399-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    dmc: dmc {
+      compatible = "rockchip,rk3399-dmc";
+      devfreq-events = <&dfi>;
+      rockchip,pmu = <&pmu>;
+      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru SCLK_DDRC>;
+      clock-names = "dmc_clk";
+      operating-points-v2 = <&dmc_opp_table>;
+      center-supply = <&ppvar_centerlogic>;
+      rockchip,ddr3_speed_bin = <21>;
+      rockchip,pd_idle = <0x40>;
+      rockchip,sr_idle = <0x2>;
+      rockchip,sr_mc_gate_idle = <0x3>;
+      rockchip,srpd_lite_idle = <0x4>;
+      rockchip,standby_idle = <0x2000>;
+      rockchip,dram_dll_dis_freq = <300>;
+      rockchip,phy_dll_dis_freq = <125>;
+      rockchip,auto_pd_dis_freq = <666>;
+      rockchip,ddr3_odt_dis_freq = <333>;
+      rockchip,ddr3_drv = <40>;
+      rockchip,ddr3_odt = <120>;
+      rockchip,phy_ddr3_ca_drv = <40>;
+      rockchip,phy_ddr3_dq_drv = <40>;
+      rockchip,phy_ddr3_odt = <240>;
+      rockchip,lpddr3_odt_dis_freq = <333>;
+      rockchip,lpddr3_drv = <34>;
+      rockchip,lpddr3_odt = <240>;
+      rockchip,phy_lpddr3_ca_drv = <40>;
+      rockchip,phy_lpddr3_dq_drv = <40>;
+      rockchip,phy_lpddr3_odt = <240>;
+      rockchip,lpddr4_odt_dis_freq = <333>;
+      rockchip,lpddr4_drv = <60>;
+      rockchip,lpddr4_dq_odt = <40>;
+      rockchip,lpddr4_ca_odt = <40>;
+      rockchip,phy_lpddr4_ca_drv = <40>;
+      rockchip,phy_lpddr4_ck_cs_drv = <80>;
+      rockchip,phy_lpddr4_dq_drv = <80>;
+      rockchip,phy_lpddr4_odt = <60>;
+    };
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:12 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:12 -0800
Subject: [PATCH 02/10] dt-bindings: devfreq: rk3399_dmc: Deprecate
 unused/redundant properties
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>

These DRAM configuration properties are all handled in ARM Trusted
Firmware (and have been since the early days of this SoC), and there are
no in-tree users of the DMC binding yet. It's better to just defer to
firmware instead of maintaining this large list of properties.

There's also some confusion about units: many of these are specified in
MHz, but the downstream users and driver code are treating them as Hz, I
believe. Rather than straighten all that out, I just drop them.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 .../bindings/devfreq/rk3399_dmc.yaml          | 42 +++++++++----------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index f12f34d93378..6bb411dddb7b 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -58,6 +58,7 @@ properties:
       finishes a DCF interrupt is triggered.
 
   rockchip,ddr3_speed_bin:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
@@ -104,6 +105,7 @@ properties:
       if bus is idle for standby_idle * DFI clock cycles.
 
   rockchip,dram_dll_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
@@ -111,6 +113,7 @@ properties:
       Note: if DLL was bypassed, the odt will also stop working.
 
   rockchip,phy_dll_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
@@ -118,6 +121,7 @@ properties:
       Note: PHY DLL and PHY ODT are independent.
 
   rockchip,auto_pd_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Defines the auto PD disable frequency in MHz.
@@ -131,18 +135,21 @@ properties:
       disabled.
 
   rockchip,ddr3_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the DRAM side drive
       strength in ohms. Default value is 40.
 
   rockchip,ddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the DRAM side ODT
       strength in ohms. Default value is 120.
 
   rockchip,phy_ddr3_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the phy side CA line
@@ -150,12 +157,14 @@ properties:
       Default value is 40.
 
   rockchip,phy_ddr3_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 40.
 
   rockchip,phy_ddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the PHY side ODT
@@ -170,18 +179,21 @@ properties:
       disabled.
 
   rockchip,lpddr3_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
       strength in ohms. Default value is 34.
 
   rockchip,lpddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
       strength in ohms. Default value is 240.
 
   rockchip,phy_lpddr3_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
@@ -189,12 +201,14 @@ properties:
       Default value is 40.
 
   rockchip,phy_lpddr3_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 40.
 
   rockchip,phy_lpddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When dram type is LPDDR3, this parameter define the phy side odt
@@ -209,42 +223,49 @@ properties:
       disabled.
 
   rockchip,lpddr4_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
       strength in ohms. Default value is 60.
 
   rockchip,lpddr4_dq_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
       DQS/DQ line strength in ohms. Default value is 40.
 
   rockchip,lpddr4_ca_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
       CA line strength in ohms. Default value is 40.
 
   rockchip,phy_lpddr4_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
       (including command address line) drive strength. Default value is 40.
 
   rockchip,phy_lpddr4_ck_cs_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side clock
       line and CS line drive strength. Default value is 80.
 
   rockchip,phy_lpddr4_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 80.
 
   rockchip,phy_lpddr4_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
@@ -265,33 +286,12 @@ examples:
       clock-names = "dmc_clk";
       operating-points-v2 = <&dmc_opp_table>;
       center-supply = <&ppvar_centerlogic>;
-      rockchip,ddr3_speed_bin = <21>;
       rockchip,pd_idle = <0x40>;
       rockchip,sr_idle = <0x2>;
       rockchip,sr_mc_gate_idle = <0x3>;
       rockchip,srpd_lite_idle = <0x4>;
       rockchip,standby_idle = <0x2000>;
-      rockchip,dram_dll_dis_freq = <300>;
-      rockchip,phy_dll_dis_freq = <125>;
-      rockchip,auto_pd_dis_freq = <666>;
       rockchip,ddr3_odt_dis_freq = <333>;
-      rockchip,ddr3_drv = <40>;
-      rockchip,ddr3_odt = <120>;
-      rockchip,phy_ddr3_ca_drv = <40>;
-      rockchip,phy_ddr3_dq_drv = <40>;
-      rockchip,phy_ddr3_odt = <240>;
       rockchip,lpddr3_odt_dis_freq = <333>;
-      rockchip,lpddr3_drv = <34>;
-      rockchip,lpddr3_odt = <240>;
-      rockchip,phy_lpddr3_ca_drv = <40>;
-      rockchip,phy_lpddr3_dq_drv = <40>;
-      rockchip,phy_lpddr3_odt = <240>;
       rockchip,lpddr4_odt_dis_freq = <333>;
-      rockchip,lpddr4_drv = <60>;
-      rockchip,lpddr4_dq_odt = <40>;
-      rockchip,lpddr4_ca_odt = <40>;
-      rockchip,phy_lpddr4_ca_drv = <40>;
-      rockchip,phy_lpddr4_ck_cs_drv = <80>;
-      rockchip,phy_lpddr4_dq_drv = <80>;
-      rockchip,phy_lpddr4_odt = <60>;
     };
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:13 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:13 -0800
Subject: [PATCH 03/10] dt-bindings: devfreq: rk3399_dmc: Fix Hz units
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.3.I9341269171c114d0e04e41d48037fd32816e2d8c@changeid>

The driver and all downstream device trees [1] are using Hz units, but
the document claims MHz. DRAM frequency for these systems can't possibly
exceed 2^32-1 Hz, so the choice of unit doesn't really matter than much.

Rather than add unnecessary risk in getting the units wrong, let's just
go with the unofficial convention and make the docs match reality.

A sub-1MHz frequency is extremely unlikely, so include a minimum in the
schema, to help catch anybody who might have believed this was MHz.

[1] And notably, also those trying to upstream them:
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 .../bindings/devfreq/rk3399_dmc.yaml          | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index 6bb411dddb7b..2c871c57fd97 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -128,11 +128,11 @@ properties:
 
   rockchip,ddr3_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is DDR3, this parameter defines the ODT disable
-      frequency in MHz (Mega Hz). When the DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
+      the ODT on the DRAM side and controller side are both disabled.
 
   rockchip,ddr3_drv:
     deprecated: true
@@ -172,11 +172,11 @@ properties:
 
   rockchip,lpddr3_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is LPDDR3, this parameter defines then ODT disable
-      frequency in MHz (Mega Hz). When DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When DDR frequency is less then ddr3_odt_dis_freq, the
+      ODT on the DRAM side and controller side are both disabled.
 
   rockchip,lpddr3_drv:
     deprecated: true
@@ -216,11 +216,11 @@ properties:
 
   rockchip,lpddr4_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is LPDDR4, this parameter defines the ODT disable
-      frequency in MHz (Mega Hz). When the DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
+      the ODT on the DRAM side and controller side are both disabled.
 
   rockchip,lpddr4_drv:
     deprecated: true
@@ -291,7 +291,7 @@ examples:
       rockchip,sr_mc_gate_idle = <0x3>;
       rockchip,srpd_lite_idle = <0x4>;
       rockchip,standby_idle = <0x2000>;
-      rockchip,ddr3_odt_dis_freq = <333>;
-      rockchip,lpddr3_odt_dis_freq = <333>;
-      rockchip,lpddr4_odt_dis_freq = <333>;
+      rockchip,ddr3_odt_dis_freq = <333000000>;
+      rockchip,lpddr3_odt_dis_freq = <333000000>;
+      rockchip,lpddr4_odt_dis_freq = <333000000>;
     };
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:14 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:14 -0800
Subject: [PATCH 04/10] dt-bindings: devfreq: rk3399_dmc: Add more disable-freq
 properties
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.4.I382d4de737198ea52deb118c9bdc4d93d76e009e@changeid>

DDR DVFS tuning has found that several power-saving features don't have
good tradeoffs at higher frequencies -- at higher frequencies, we'll see
glitches or other errors. Provide tuning controls so these can be
disabled at higher OPPs, and left active only at the lower ones.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 .../bindings/devfreq/rk3399_dmc.yaml          | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index 2c871c57fd97..357d07c5a3df 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -271,6 +271,43 @@ properties:
       When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
       strength. Default value is 60.
 
+  rockchip,pd_idle_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the power-down idle disable frequency in Hz. When the DDR
+      frequency is greater than pd_idle_dis_freq, power-down idle is disabled.
+      See also rockchip,pd_idle.
+
+  rockchip,sr_idle_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the self-refresh idle disable frequency in Hz. When the DDR
+      frequency is greater than sr_idle_dis_freq, self-refresh idle is
+      disabled. See also rockchip,sr_idle.
+
+  rockchip,sr_mc_gate_idle_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the self-refresh and memory-controller clock gating disable
+      frequency in Hz. When the DDR frequency is greater than
+      sr_mc_gate_idle_dis_freq, the clock will not be gated when idle. See also
+      rockchip,sr_mc_gate_idle.
+
+  rockchip,srpd_lite_idle_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the self-refresh power down idle disable frequency in Hz. When
+      the DDR frequency is greater than srpd_lite_idle_dis_freq, memory will
+      not be placed into self-refresh power down mode when idle. See also
+      rockchip,srpd_lite_idle.
+
+  rockchip,standby_idle_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the standby idle disable frequency in Hz. When the DDR frequency
+      is greater than standby_idle_dis_freq, standby idle is disabled. See also
+      rockchip,standby_idle.
+
 additionalProperties: false
 
 examples:
@@ -294,4 +331,9 @@ examples:
       rockchip,ddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr4_odt_dis_freq = <333000000>;
+      rockchip,pd_idle_dis_freq = <1000000000>;
+      rockchip,sr_idle_dis_freq = <1000000000>;
+      rockchip,sr_mc_gate_idle_dis_freq = <1000000000>;
+      rockchip,srpd_lite_idle_dis_freq = <0>;
+      rockchip,standby_idle_dis_freq = <928000000>;
     };
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:15 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:15 -0800
Subject: [PATCH 05/10] PM / devfreq: rk3399_dmc: Drop undocumented ondemand DT
 props
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.5.I4bd77eb751d5bfce8346bfed576bcacb28e4550f@changeid>

These properties are:

* undocumented
* directly representing software properties, not hardware properties
* unused (no in-tree users, yet; this IP block has so far only been used
  in downstream kernels)

Let's just stick the values that downstream users have been using
directly in the driver and call it a day.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 drivers/devfreq/rk3399_dmc.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 293857ebfd75..e982862f6ac2 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -430,10 +430,8 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 		goto err_edev;
 	}
 
-	of_property_read_u32(np, "upthreshold",
-			     &data->ondemand_data.upthreshold);
-	of_property_read_u32(np, "downdifferential",
-			     &data->ondemand_data.downdifferential);
+	data->ondemand_data.upthreshold = 25;
+	data->ondemand_data.downdifferential = 15;
 
 	data->rate = clk_get_rate(data->dmc_clk);
 
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:16 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:16 -0800
Subject: [PATCH 06/10] PM / devfreq: rk3399_dmc: Drop excess timing properties
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.6.Ia0f7d6168a71ba4a4fd0519972a8dfd4c681fc25@changeid>

All of these properties are initialized by ARM Trusted Firmware, and
have been since the early days of this chip. It's redundant (and
possibly wrong) to do this here now. What's more, there seems to be some
confusion about the units and some of the definitions of this timing
struct: the DT docs say MHz for many of these, but downstream users were
in Hz (and therefore, the ATF interface was Hz). Also, the in-driver
usage for some of these (e.g., for comparing to target frequency) were
in Hz too. So doubly wrong.

We can avoid thinking about who got the right units by dropping the
unnecessary code and properties. They are marked deprecated in the
binding schema.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 drivers/devfreq/rk3399_dmc.c | 144 +++++++----------------------------
 1 file changed, 29 insertions(+), 115 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index e982862f6ac2..8f447217303f 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -23,38 +23,6 @@
 #include <soc/rockchip/rk3399_grf.h>
 #include <soc/rockchip/rockchip_sip.h>
 
-struct dram_timing {
-	unsigned int ddr3_speed_bin;
-	unsigned int pd_idle;
-	unsigned int sr_idle;
-	unsigned int sr_mc_gate_idle;
-	unsigned int srpd_lite_idle;
-	unsigned int standby_idle;
-	unsigned int auto_pd_dis_freq;
-	unsigned int dram_dll_dis_freq;
-	unsigned int phy_dll_dis_freq;
-	unsigned int ddr3_odt_dis_freq;
-	unsigned int ddr3_drv;
-	unsigned int ddr3_odt;
-	unsigned int phy_ddr3_ca_drv;
-	unsigned int phy_ddr3_dq_drv;
-	unsigned int phy_ddr3_odt;
-	unsigned int lpddr3_odt_dis_freq;
-	unsigned int lpddr3_drv;
-	unsigned int lpddr3_odt;
-	unsigned int phy_lpddr3_ca_drv;
-	unsigned int phy_lpddr3_dq_drv;
-	unsigned int phy_lpddr3_odt;
-	unsigned int lpddr4_odt_dis_freq;
-	unsigned int lpddr4_drv;
-	unsigned int lpddr4_dq_odt;
-	unsigned int lpddr4_ca_odt;
-	unsigned int phy_lpddr4_ca_drv;
-	unsigned int phy_lpddr4_ck_cs_drv;
-	unsigned int phy_lpddr4_dq_drv;
-	unsigned int phy_lpddr4_odt;
-};
-
 struct rk3399_dmcfreq {
 	struct device *dev;
 	struct devfreq *devfreq;
@@ -62,13 +30,21 @@ struct rk3399_dmcfreq {
 	struct clk *dmc_clk;
 	struct devfreq_event_dev *edev;
 	struct mutex lock;
-	struct dram_timing timing;
 	struct regulator *vdd_center;
 	struct regmap *regmap_pmu;
 	unsigned long rate, target_rate;
 	unsigned long volt, target_volt;
 	unsigned int odt_dis_freq;
 	int odt_pd_arg0, odt_pd_arg1;
+
+	unsigned int pd_idle;
+	unsigned int sr_idle;
+	unsigned int sr_mc_gate_idle;
+	unsigned int srpd_lite_idle;
+	unsigned int standby_idle;
+	unsigned int ddr3_odt_dis_freq;
+	unsigned int lpddr3_odt_dis_freq;
+	unsigned int lpddr4_odt_dis_freq;
 };
 
 static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -238,69 +214,27 @@ static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,
 			 rk3399_dmcfreq_resume);
 
-static int of_get_ddr_timings(struct dram_timing *timing,
-			      struct device_node *np)
+static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
+				   struct device_node *np)
 {
 	int ret = 0;
 
-	ret = of_property_read_u32(np, "rockchip,ddr3_speed_bin",
-				   &timing->ddr3_speed_bin);
 	ret |= of_property_read_u32(np, "rockchip,pd_idle",
-				    &timing->pd_idle);
+				    &data->pd_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_idle",
-				    &timing->sr_idle);
+				    &data->sr_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle",
-				    &timing->sr_mc_gate_idle);
+				    &data->sr_mc_gate_idle);
 	ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle",
-				    &timing->srpd_lite_idle);
+				    &data->srpd_lite_idle);
 	ret |= of_property_read_u32(np, "rockchip,standby_idle",
-				    &timing->standby_idle);
-	ret |= of_property_read_u32(np, "rockchip,auto_pd_dis_freq",
-				    &timing->auto_pd_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,dram_dll_dis_freq",
-				    &timing->dram_dll_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,phy_dll_dis_freq",
-				    &timing->phy_dll_dis_freq);
+				    &data->standby_idle);
 	ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",
-				    &timing->ddr3_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,ddr3_drv",
-				    &timing->ddr3_drv);
-	ret |= of_property_read_u32(np, "rockchip,ddr3_odt",
-				    &timing->ddr3_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_ca_drv",
-				    &timing->phy_ddr3_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_dq_drv",
-				    &timing->phy_ddr3_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_odt",
-				    &timing->phy_ddr3_odt);
+				    &data->ddr3_odt_dis_freq);
 	ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",
-				    &timing->lpddr3_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,lpddr3_drv",
-				    &timing->lpddr3_drv);
-	ret |= of_property_read_u32(np, "rockchip,lpddr3_odt",
-				    &timing->lpddr3_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_ca_drv",
-				    &timing->phy_lpddr3_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_dq_drv",
-				    &timing->phy_lpddr3_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_odt",
-				    &timing->phy_lpddr3_odt);
+				    &data->lpddr3_odt_dis_freq);
 	ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",
-				    &timing->lpddr4_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_drv",
-				    &timing->lpddr4_drv);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_dq_odt",
-				    &timing->lpddr4_dq_odt);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_ca_odt",
-				    &timing->lpddr4_ca_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ca_drv",
-				    &timing->phy_lpddr4_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ck_cs_drv",
-				    &timing->phy_lpddr4_ck_cs_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_dq_drv",
-				    &timing->phy_lpddr4_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_odt",
-				    &timing->phy_lpddr4_odt);
+				    &data->lpddr4_odt_dis_freq);
 
 	return ret;
 }
@@ -311,8 +245,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct rk3399_dmcfreq *data;
-	int ret, index, size;
-	uint32_t *timing;
+	int ret;
 	struct dev_pm_opp *opp;
 	u32 ddr_type;
 	u32 val;
@@ -343,26 +276,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/*
-	 * Get dram timing and pass it to arm trust firmware,
-	 * the dram driver in arm trust firmware will get these
-	 * timing and to do dram initial.
-	 */
-	if (!of_get_ddr_timings(&data->timing, np)) {
-		timing = &data->timing.ddr3_speed_bin;
-		size = sizeof(struct dram_timing) / 4;
-		for (index = 0; index < size; index++) {
-			arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, *timing++, index,
-				      ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM,
-				      0, 0, 0, 0, &res);
-			if (res.a0) {
-				dev_err(dev, "Failed to set dram param: %ld\n",
-					res.a0);
-				ret = -EINVAL;
-				goto err_edev;
-			}
-		}
-	}
+	rk3399_dmcfreq_of_props(data, np);
 
 	node = of_parse_phandle(np, "rockchip,pmu", 0);
 	if (!node)
@@ -381,13 +295,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 
 	switch (ddr_type) {
 	case RK3399_PMUGRF_DDRTYPE_DDR3:
-		data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
+		data->odt_dis_freq = data->ddr3_odt_dis_freq;
 		break;
 	case RK3399_PMUGRF_DDRTYPE_LPDDR3:
-		data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
+		data->odt_dis_freq = data->lpddr3_odt_dis_freq;
 		break;
 	case RK3399_PMUGRF_DDRTYPE_LPDDR4:
-		data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
+		data->odt_dis_freq = data->lpddr4_odt_dis_freq;
 		break;
 	default:
 		ret = -EINVAL;
@@ -414,11 +328,11 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	 * arg2:
 	 *     bit[0]     : odt enable
 	 */
-	data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
-			    ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
-			    ((data->timing.standby_idle & 0xffff) << 16);
-	data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
-			    ((data->timing.srpd_lite_idle & 0xfff) << 16);
+	data->odt_pd_arg0 = (data->sr_idle & 0xff) |
+			    ((data->sr_mc_gate_idle & 0xff) << 8) |
+			    ((data->standby_idle & 0xffff) << 16);
+	data->odt_pd_arg1 = (data->pd_idle & 0xfff) |
+			    ((data->srpd_lite_idle & 0xfff) << 16);
 
 	/*
 	 * We add a devfreq driver to our parent since it has a device tree node
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:17 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:17 -0800
Subject: [PATCH 07/10] PM / devfreq: rk3399_dmc: Use bitfield macro
 definitions for ODT_PD
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.7.I0f36da588afd01d0dc9ce5866240efa34bd91e21@changeid>

We're going to add new usages, and it's cleaner to work with macros
instead of comments and magic numbers.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 drivers/devfreq/rk3399_dmc.c | 43 ++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 8f447217303f..c4efbc15cbb1 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/devfreq.h>
@@ -23,6 +24,15 @@
 #include <soc/rockchip/rk3399_grf.h>
 #include <soc/rockchip/rockchip_sip.h>
 
+#define RK3399_SET_ODT_PD_0_SR_IDLE			GENMASK(7, 0)
+#define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE		GENMASK(15, 8)
+#define RK3399_SET_ODT_PD_0_STANDBY_IDLE		GENMASK(31, 16)
+
+#define RK3399_SET_ODT_PD_1_PD_IDLE			GENMASK(11, 0)
+#define RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE		GENMASK(27, 16)
+
+#define RK3399_SET_ODT_PD_2_ODT_ENABLE			BIT(0)
+
 struct rk3399_dmcfreq {
 	struct device *dev;
 	struct devfreq *devfreq;
@@ -55,7 +65,6 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	unsigned long old_clk_rate = dmcfreq->rate;
 	unsigned long target_volt, target_rate;
 	struct arm_smccc_res res;
-	bool odt_enable = false;
 	int err;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
@@ -72,8 +81,10 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	mutex_lock(&dmcfreq->lock);
 
 	if (dmcfreq->regmap_pmu) {
+		unsigned int odt_pd_arg2 = 0;
+
 		if (target_rate >= dmcfreq->odt_dis_freq)
-			odt_enable = true;
+			odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;
 
 		/*
 		 * This makes a SMC call to the TF-A to set the DDR PD
@@ -83,7 +94,7 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
 			      dmcfreq->odt_pd_arg1,
 			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
-			      odt_enable, 0, 0, 0, &res);
+			      odt_pd_arg2, 0, 0, 0, &res);
 	}
 
 	/*
@@ -316,23 +327,17 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	/*
 	 * In TF-A there is a platform SIP call to set the PD (power-down)
 	 * timings and to enable or disable the ODT (on-die termination).
-	 * This call needs three arguments as follows:
-	 *
-	 * arg0:
-	 *     bit[0-7]   : sr_idle
-	 *     bit[8-15]  : sr_mc_gate_idle
-	 *     bit[16-31] : standby idle
-	 * arg1:
-	 *     bit[0-11]  : pd_idle
-	 *     bit[16-27] : srpd_lite_idle
-	 * arg2:
-	 *     bit[0]     : odt enable
 	 */
-	data->odt_pd_arg0 = (data->sr_idle & 0xff) |
-			    ((data->sr_mc_gate_idle & 0xff) << 8) |
-			    ((data->standby_idle & 0xffff) << 16);
-	data->odt_pd_arg1 = (data->pd_idle & 0xfff) |
-			    ((data->srpd_lite_idle & 0xfff) << 16);
+	data->odt_pd_arg0 =
+		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_IDLE, data->sr_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE,
+			   data->sr_mc_gate_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_0_STANDBY_IDLE,
+			   data->standby_idle);
+	data->odt_pd_arg1 =
+		FIELD_PREP(RK3399_SET_ODT_PD_1_PD_IDLE, data->pd_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE,
+			   data->srpd_lite_idle);
 
 	/*
 	 * We add a devfreq driver to our parent since it has a device tree node
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:18 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:18 -0800
Subject: [PATCH 08/10] PM / devfreq: rk3399_dmc: Support new disable-freq
 properties
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.8.I08d654522b8a1ae92ecb8d2e2a74511f778f61e5@changeid>

Implement the newly-defined properties to allow disabling certain
power-saving-at-idle features at higher frequencies.

This is a rewritten version of work by Lin Huang <hl at rock-chips.com>.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 drivers/devfreq/rk3399_dmc.c | 51 +++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index c4efbc15cbb1..58a4970918be 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -55,6 +55,12 @@ struct rk3399_dmcfreq {
 	unsigned int ddr3_odt_dis_freq;
 	unsigned int lpddr3_odt_dis_freq;
 	unsigned int lpddr4_odt_dis_freq;
+
+	unsigned int pd_idle_dis_freq;
+	unsigned int sr_idle_dis_freq;
+	unsigned int sr_mc_gate_idle_dis_freq;
+	unsigned int srpd_lite_idle_dis_freq;
+	unsigned int standby_idle_dis_freq;
 };
 
 static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -81,8 +87,25 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	mutex_lock(&dmcfreq->lock);
 
 	if (dmcfreq->regmap_pmu) {
+		unsigned int odt_pd_arg0 = dmcfreq->odt_pd_arg0;
+		unsigned int odt_pd_arg1 = dmcfreq->odt_pd_arg1;
 		unsigned int odt_pd_arg2 = 0;
 
+		if (target_rate >= dmcfreq->sr_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE;
+
+		if (target_rate >= dmcfreq->sr_mc_gate_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE;
+
+		if (target_rate >= dmcfreq->standby_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_STANDBY_IDLE;
+
+		if (target_rate >= dmcfreq->pd_idle_dis_freq)
+			odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_PD_IDLE;
+
+		if (target_rate >= dmcfreq->srpd_lite_idle_dis_freq)
+			odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE;
+
 		if (target_rate >= dmcfreq->odt_dis_freq)
 			odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;
 
@@ -91,10 +114,9 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 		 * (power-down) timings and to enable or disable the
 		 * ODT (on-die termination) resistors.
 		 */
-		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
-			      dmcfreq->odt_pd_arg1,
-			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
-			      odt_pd_arg2, 0, 0, 0, &res);
+		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, odt_pd_arg0, odt_pd_arg1,
+			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, odt_pd_arg2,
+			      0, 0, 0, &res);
 	}
 
 	/*
@@ -230,6 +252,16 @@ static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
 {
 	int ret = 0;
 
+	/*
+	 * These are all optional, and serve as minimum bounds. Give them large
+	 * (i.e., never "disabled") values if the DT doesn't specify one.
+	 */
+	data->pd_idle_dis_freq =
+		data->sr_idle_dis_freq =
+		data->sr_mc_gate_idle_dis_freq =
+		data->srpd_lite_idle_dis_freq =
+		data->standby_idle_dis_freq = UINT_MAX;
+
 	ret |= of_property_read_u32(np, "rockchip,pd_idle",
 				    &data->pd_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_idle",
@@ -247,6 +279,17 @@ static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
 	ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",
 				    &data->lpddr4_odt_dis_freq);
 
+	ret |= of_property_read_u32(np, "rockchip,pd_idle_dis_freq",
+				    &data->pd_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,sr_idle_dis_freq",
+				    &data->sr_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle_dis_freq",
+				    &data->sr_mc_gate_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle_dis_freq",
+				    &data->srpd_lite_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,standby_idle_dis_freq",
+				    &data->standby_idle_dis_freq);
+
 	return ret;
 }
 
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:19 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:19 -0800
Subject: [PATCH 09/10] arm64: dts: rk3399: Add dfi and dmc nodes
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.9.Ie97993621975c5463d7928a8646f3737c9f2921d@changeid>

From: Lin Huang <hl at rock-chips.com>

These are required to support DDR DVFS on RK3399 platforms.

Signed-off-by: Lin Huang <hl at rock-chips.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Ga?l PORTAY <gael.portay at collabora.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Signed-off-by: Brian Norris <briannorris at chromium.org>
---
This is based on a v5 posting from various authors:
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/
Much of that series was already merged, so I start over with the
numbering.

Change since Daniel's posting: reordered by unit address, per existing
style

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index d3cdf6f42a30..86e2d87e008a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1295,6 +1295,25 @@ pwm3: pwm at ff420030 {
 		status = "disabled";
 	};
 
+	dfi: dfi at ff630000 {
+		reg = <0x00 0xff630000 0x00 0x4000>;
+		compatible = "rockchip,rk3399-dfi";
+		rockchip,pmu = <&pmugrf>;
+		interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru PCLK_DDR_MON>;
+		clock-names = "pclk_ddr_mon";
+		status = "disabled";
+	};
+
+	dmc: dmc {
+		compatible = "rockchip,rk3399-dmc";
+		rockchip,pmu = <&pmugrf>;
+		devfreq-events = <&dfi>;
+		clocks = <&cru SCLK_DDRC>;
+		clock-names = "dmc_clk";
+		status = "disabled";
+	};
+
 	vpu: video-codec at ff650000 {
 		compatible = "rockchip,rk3399-vpu";
 		reg = <0x0 0xff650000 0x0 0x800>;
-- 
2.34.1.575.g55b058a8bb-goog



From briannorris at chromium.org  Fri Jan  7 15:53:20 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri,  7 Jan 2022 15:53:20 -0800
Subject: [PATCH 10/10] arm64: dts: rockchip: Enable dmc and dfi nodes on gru
In-Reply-To: <20220107235320.965497-1-briannorris@chromium.org>
References: <20220107235320.965497-1-briannorris@chromium.org>
Message-ID: <20220107155215.10.I3a5c7f21ecd8221b42c2dbcd618386bce7b3e9a6@changeid>

From: Lin Huang <hl at rock-chips.com>

Enable the DMC (Dynamic Memory Controller) and the DFI (DDR PHY
Interface) nodes on gru boards so we can support DDR DVFS.

Signed-off-by: Lin Huang <hl at rock-chips.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Ga?l PORTAY <gael.portay at collabora.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Signed-off-by: Brian Norris <briannorris at chromium.org>
---
This was part of a previous series, at:
https://lore.kernel.org/r/20210308233858.24741-3-daniel.lezcano at linaro.org
I've picked up a bunch of changes and fixes, so I've restarted the patch
series numbering.

Updates since the old series:

 * reordered alphabetically by phandle name, per style
 * drop a ton of deprecated/unused properties
 * add required center-supply for scarlet
 * add new *_idle_dis_freq properties
 * drop the lowest (200 MHz) OPP; this was never stabilized for
   production
 * bump the voltage (0.9V -> 0.925V) for the highest OPP on Chromebook
   models; later (tablet) models were more stable, with a fixed DDR
   regulator
 * bump odt_dis_freq to 666 MHz; early versions used 333 MHz, but
   stabilization efforts landed on 666 MHz for production

 .../dts/rockchip/rk3399-gru-chromebook.dtsi   |  7 +++++
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 12 ++++++++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi  | 28 +++++++++++++++++++
 .../boot/dts/rockchip/rk3399-op1-opp.dtsi     | 25 +++++++++++++++++
 4 files changed, 72 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
index 9b2c679f5eca..46292fdceecb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
@@ -234,6 +234,13 @@ &cdn_dp {
 	extcon = <&usbc_extcon0>, <&usbc_extcon1>;
 };
 
+&dmc {
+	center-supply = <&ppvar_centerlogic>;
+	rockchip,pd_idle_dis_freq = <800000000>;
+	rockchip,sr_idle_dis_freq = <800000000>;
+	rockchip,sr_mc_gate_idle_dis_freq = <800000000>;
+};
+
 &edp {
 	status = "okay";
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
index a9817b3d7edc..913d845eb51a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
@@ -391,6 +391,18 @@ &cru {
 		<400000000>;
 };
 
+/* The center supply is fixed to .9V on scarlet */
+&dmc {
+	center-supply = <&pp900_s0>;
+};
+
+/* We don't need .925 V for 928 MHz on scarlet */
+&dmc_opp_table {
+	opp03 {
+		opp-microvolt = <900000>;
+	};
+};
+
 &gpio0 {
 	gpio-line-names = /* GPIO0 A 0-7 */
 			  "CLK_32K_AP",
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 45a5ae5d2027..58b8d332f924 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -373,6 +373,34 @@ &cru {
 		<200000000>;
 };
 
+&dfi {
+	status = "okay";
+};
+
+&dmc {
+	status = "okay";
+	rockchip,pd_idle = <0x40>;
+	rockchip,sr_idle = <0x2>;
+	rockchip,sr_mc_gate_idle = <0x3>;
+	rockchip,srpd_lite_idle	= <0x4>;
+	rockchip,standby_idle = <0x2000>;
+	rockchip,ddr3_odt_dis_freq = <666000000>;
+	rockchip,lpddr3_odt_dis_freq = <666000000>;
+	rockchip,lpddr4_odt_dis_freq = <666000000>;
+
+	rockchip,pd_idle_dis_freq = <1000000000>;
+	rockchip,sr_idle_dis_freq = <1000000000>;
+	rockchip,sr_mc_gate_idle_dis_freq = <1000000000>;
+	rockchip,srpd_lite_idle_dis_freq = <0>;
+	rockchip,standby_idle_dis_freq = <928000000>;
+};
+
+&dmc_opp_table {
+	opp03 {
+		opp-suspend;
+	};
+};
+
 &emmc_phy {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
index 2180e0f75003..6e29e74f6fc6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
@@ -110,6 +110,27 @@ opp05 {
 			opp-microvolt = <1075000>;
 		};
 	};
+
+	dmc_opp_table: dmc_opp_table {
+		compatible = "operating-points-v2";
+
+		opp00 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <900000>;
+		};
+		opp01 {
+			opp-hz = /bits/ 64 <666000000>;
+			opp-microvolt = <900000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <900000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <928000000>;
+			opp-microvolt = <925000>;
+		};
+	};
 };
 
 &cpu_l0 {
@@ -136,6 +157,10 @@ &cpu_b1 {
 	operating-points-v2 = <&cluster1_opp>;
 };
 
+&dmc {
+	operating-points-v2 = <&dmc_opp_table>;
+};
+
 &gpu {
 	operating-points-v2 = <&gpu_opp_table>;
 };
-- 
2.34.1.575.g55b058a8bb-goog



From jmattson at google.com  Fri Jan  7 16:04:49 2022
From: jmattson at google.com (Jim Mattson)
Date: Fri, 7 Jan 2022 16:04:49 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
Message-ID: <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Hi Raghu,
> >
> > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > Capture the start of the KVM VM, which is basically the
> > > start of any vCPU run. This state of the VM is helpful
> > > in the upcoming patches to prevent user-space from
> > > configuring certain VM features after the VM has started
> > > running.

What about live migration, where the VM has already technically been
started before the first call to KVM_RUN?


From bot at kernelci.org  Fri Jan  7 16:06:45 2022
From: bot at kernelci.org (kernelci.org bot)
Date: Fri, 07 Jan 2022 16:06:45 -0800 (PST)
Subject: arm64/for-kernelci build: 2 builds: 0 failed,
 2 passed (v5.16-rc8-90-g492ba2240491)
Message-ID: <61d8d595.1c69fb81.a136a.04f3@mx.google.com>

arm64/for-kernelci build: 2 builds: 0 failed, 2 passed (v5.16-rc8-90-g492ba2240491)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.16-rc8-90-g492ba2240491/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.16-rc8-90-g492ba2240491
Git Commit: 492ba2240491514402656b601ce8d0d547920273
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-10) ? PASS, 0 errors, 0 warnings, 0 section mismatches

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From sboyd at kernel.org  Fri Jan  7 16:08:10 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 07 Jan 2022 16:08:10 -0800
Subject: [PATCH] clk: visconti: Remove pointless NULL check in
 visconti_pll_add_lookup()
In-Reply-To: <20220107183303.2337676-1-nathan@kernel.org>
References: <20220107183303.2337676-1-nathan@kernel.org>
Message-ID: <20220108000811.B8373C36AE5@smtp.kernel.org>

Quoting Nathan Chancellor (2022-01-07 10:33:03)
> Clang warns:
> 
> drivers/clk/visconti/pll.c:292:20: warning: address of array 'ctx->clk_data.hws' will always evaluate to 'true' [-Wpointer-bool-conversion]
>         if (ctx->clk_data.hws && id)
>             ~~~~~~~~~~~~~~^~~ ~~
> 1 warning generated.
> 
> This array cannot be NULL if ctx is not NULL, which is allocated in
> visconti_init_pll(), so just remove the check, which matches other clk
> drivers.
> 
> Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and reset driver")
> Link: https://github.com/ClangBuiltLinux/linux/issues/1564
> Reported-by: kernel test robot <lkp at intel.com>
> Signed-off-by: Nathan Chancellor <nathan at kernel.org>
> ---

Applied to clk-next


From yuzhao at google.com  Fri Jan  7 16:19:28 2022
From: yuzhao at google.com (Yu Zhao)
Date: Fri, 7 Jan 2022 17:19:28 -0700
Subject: [PATCH v6 5/9] mm: multigenerational lru: mm_struct list
In-Reply-To: <YdgChw4vNb43XsU/@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-6-yuzhao@google.com>
 <YdgChw4vNb43XsU/@dhcp22.suse.cz>
Message-ID: <YdjYkFmtMdrYg736@google.com>

On Fri, Jan 07, 2022 at 10:06:15AM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:24, Yu Zhao wrote:
> > To exploit spatial locality, the aging prefers to walk page tables to
> > search for young PTEs. And this patch paves the way for that.
> > 
> > An mm_struct list is maintained for each memcg, and an mm_struct
> > follows its owner task to the new memcg when this task is migrated.
> 
> How does this work actually for the memcg reclaim? I can see you
> lru_gen_migrate_mm on the task migration. My concern is, though, that
> such a task leaves all the memory behind in the previous memcg (in
> cgroup v2, in v1 you can opt in for charge migration). If you move the
> mm to a new memcg then you age it somewhere where the memory is not
> really consumed.

There are two options to gather the accessed bit: page table walks and
rmap walks. Page table walks sweep dense hotspots that are NOT
misplaced in terms of reclaim scope (lruvec); rmap walks cover what
page table walks miss, e.g., misplaced dense hotspots or sparse ones.

Dense hotspots are stored in Bloom filters for each lruvec.

If an mm leaves everything in the old memcg, page table walks in the
new memcg reclaim path basically ignore this mm after the first scan,
because everything is misplaced.

In the old memcg reclaim path, page table walks won't see this mm
at all. But rmap walks will catch everything later in the eviction
path, i.e., lru_gen_look_around(). This function is less efficient
compared with page table walks because, for each rmap walk of a
non-shared page, it only can gather the accessed bit from 64 PTEs at
most. But it's still a lot faster than the original rmap, which only
gathers the accessed bit from a single PTE, for each walk of a
non-shared page.


From sboyd at kernel.org  Fri Jan  7 16:48:08 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 07 Jan 2022 16:48:08 -0800
Subject: [PATCH 4/8] ARM: at91: PM: add cpu idle support for sama7g5
In-Reply-To: <20211216141338.35144-5-claudiu.beznea@microchip.com>
References: <20211216141338.35144-1-claudiu.beznea@microchip.com>
 <20211216141338.35144-5-claudiu.beznea@microchip.com>
Message-ID: <20220108004810.3DC10C36AEB@smtp.kernel.org>

Quoting Claudiu Beznea (2021-12-16 06:13:34)
> Add CPU idle support for SAMA7G5. Support will make use of PMC_CPU_RATIO
> register to divide the CPU clock by 16 before switching it to idle and
> use automatic self-refresh option of DDR controller.
> 
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From seanjc at google.com  Fri Jan  7 17:06:03 2022
From: seanjc at google.com (Sean Christopherson)
Date: Sat, 8 Jan 2022 01:06:03 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <20220104194918.373612-2-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
Message-ID: <Ydjje8qBOP3zDOZi@google.com>

On Tue, Jan 04, 2022, Raghavendra Rao Ananta wrote:
> Capture the start of the KVM VM, which is basically the

Please wrap at ~75 chars.

> start of any vCPU run. This state of the VM is helpful
> in the upcoming patches to prevent user-space from
> configuring certain VM features after the VM has started
> running.

Please provide context of how the flag will be used.  I glanced at the future
patches, and knowing very little about arm, I was unable to glean useful info
about exactly who is being prevented from doing what.

> 
> Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> ---
>  include/linux/kvm_host.h | 3 +++
>  virt/kvm/kvm_main.c      | 9 +++++++++
>  2 files changed, 12 insertions(+)
> 
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index c310648cc8f1..d0bd8f7a026c 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -623,6 +623,7 @@ struct kvm {
>  	struct notifier_block pm_notifier;
>  #endif
>  	char stats_id[KVM_STATS_NAME_SIZE];
> +	bool vm_started;
>  };
>  
>  #define kvm_err(fmt, ...) \
> @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
>  	}
>  }
>  
> +#define kvm_vm_has_started(kvm) (kvm->vm_started)

Needs parantheses around (kvm), but why bother with a macro?  This is the same
header that defines struct kvm.

> +
>  extern bool kvm_rebooting;
>  
>  extern unsigned int halt_poll_ns;
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 72c4e6b39389..962b91ac2064 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
>  	int r;
>  	struct kvm_fpu *fpu = NULL;
>  	struct kvm_sregs *kvm_sregs = NULL;
> +	struct kvm *kvm = vcpu->kvm;

If you're going to bother grabbing kvm, replace the instances below that also do
vcpu->kvm.

>  
>  	if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
>  		return -EIO;
> @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
>  			if (oldpid)
>  				synchronize_rcu();
>  			put_pid(oldpid);
> +
> +			/*
> +			 * Since we land here even on the first vCPU run,
> +			 * we can mark that the VM has started running.

Please avoid "we", "us", etc..

"vm_started" is also ambiguous.  If we end up with a flag, then I would prefer a
much more literal name, a la created_vcpus, e.g. ran_vcpus or something.

> +			 */
> +			mutex_lock(&kvm->lock);

This adds unnecessary lock contention when running vCPUs.  The naive solution
would be:
			if (!kvm->vm_started) {
				...
			}

> +			kvm->vm_started = true;
> +			mutex_unlock(&kvm->lock);

Lastly, why is this in generic KVM?

>  		}
>  		r = kvm_arch_vcpu_ioctl_run(vcpu);
>  		trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From sboyd at kernel.org  Fri Jan  7 17:25:14 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 07 Jan 2022 17:25:14 -0800
Subject: [PATCH v2 2/9] clk: mstar: msc313 cpupll clk driver
In-Reply-To: <20220102165730.50190-3-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
 <20220102165730.50190-3-romain.perier@gmail.com>
Message-ID: <20220108012515.D1213C36AEB@smtp.kernel.org>

Quoting Romain Perier (2022-01-02 08:57:23)
> diff --git a/drivers/clk/mstar/Kconfig b/drivers/clk/mstar/Kconfig
> index de37e1bce2d2..a44ca2b180ff 100644
> --- a/drivers/clk/mstar/Kconfig
> +++ b/drivers/clk/mstar/Kconfig
> @@ -7,3 +7,10 @@ config MSTAR_MSC313_MPLL
>         help
>           Support for the MPLL PLL and dividers block present on
>           MStar/Sigmastar SoCs.
> +
> +config MSTAR_MSC313_CPUPLL

Can this file be sorted on Kconfig name?

> +       bool "MStar CPUPLL driver"
> +       depends on ARCH_MSTARV7 || COMPILE_TEST
> +       default ARCH_MSTARV7
> +       help
> +         Support for the CPU PLL present on MStar/Sigmastar SoCs.
> diff --git a/drivers/clk/mstar/Makefile b/drivers/clk/mstar/Makefile
> index f8dcd25ede1d..9f05b73a0619 100644
> --- a/drivers/clk/mstar/Makefile
> +++ b/drivers/clk/mstar/Makefile
> @@ -4,3 +4,4 @@
>  #
>  
>  obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
> +obj-$(CONFIG_MSTAR_MSC313_CPUPLL) += clk-msc313-cpupll.o
> diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c
> new file mode 100644
> index 000000000000..2229b16475eb
> --- /dev/null
> +++ b/drivers/clk/mstar/clk-msc313-cpupll.c
> @@ -0,0 +1,227 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Daniel Palmer <daniel at thingy.jp>
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>

Is this include used? Please drop unused includes.

> +#include <linux/of_address.h>
> +#include <linux/module.h>

It isn't a module though.

> +#include <linux/kernel.h>

Preferably sort includes alphabetically too.

> +
> +/*
> + * This IP is not documented outside of the messy vendor driver.
> + * Below is what we think the registers look like based on looking at
> + * the vendor code and poking at the hardware:
> + *
> + * 0x140 -- LPF low. Seems to store one half of the clock transition
> + * 0x144 /
> + * 0x148 -- LPF high. Seems to store one half of the clock transition
> + * 0x14c /
> + * 0x150 -- vendor code says "toggle lpf enable"
> + * 0x154 -- mu?
> + * 0x15c -- lpf_update_count?
> + * 0x160 -- vendor code says "switch to LPF". Clock source config? Register bank?
> + * 0x164 -- vendor code says "from low to high" which seems to mean transition from LPF low to
> + * LPF high.
> + * 0x174 -- Seems to be the PLL lock status bit
> + * 0x180 -- Seems to be the current frequency, this might need to be populated by software?
> + * 0x184 /  The vendor driver uses these to set the initial value of LPF low
> + *
> + * Frequency seems to be calculated like this:
> + * (parent clock (432mhz) / register_magic_value) * 16 * 524288
> + * Only the lower 24 bits of the resulting value will be used. In addition, the
> + * PLL doesn't seem to be able to lock on frequencies lower than 220 MHz, as
> + * divisor 0xfb586f (220 MHz) works but 0xfb7fff locks up.
> + *
> + * Vendor values:
> + * frequency - register value
> + *
> + * 400000000  - 0x0067AE14
> + * 600000000  - 0x00451EB8,
> + * 800000000  - 0x0033D70A,
> + * 1000000000 - 0x002978d4,
> + */
> +
> +#define REG_LPF_LOW_L          0x140
> +#define REG_LPF_LOW_H          0x144
> +#define REG_LPF_HIGH_BOTTOM    0x148
> +#define REG_LPF_HIGH_TOP       0x14c
> +#define REG_LPF_TOGGLE         0x150
> +#define REG_LPF_MYSTERYTWO     0x154
> +#define REG_LPF_UPDATE_COUNT   0x15c
> +#define REG_LPF_MYSTERYONE     0x160
> +#define REG_LPF_TRANSITIONCTRL 0x164
> +#define REG_LPF_LOCK           0x174
> +#define REG_CURRENT            0x180
> +
> +#define MULTIPLIER_1           16
> +#define MULTIPLIER_2           524288
> +#define MULTIPLIER             (MULTIPLIER_1 * MULTIPLIER_2)
> +
> +struct msc313_cpupll {
> +       void __iomem *base;
> +       struct clk_hw clk_hw;
> +};
> +
> +#define to_cpupll(_hw) container_of(_hw, struct msc313_cpupll, clk_hw)
> +
> +static u32 msc313_cpupll_reg_read32(struct msc313_cpupll *cpupll, unsigned int reg)
> +{
> +       u32 value;
> +
> +       value = ioread16(cpupll->base + reg + 4) << 16;
> +       value |= ioread16(cpupll->base + reg);
> +
> +       return value;
> +}
> +
> +static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
> +{
> +       u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
> +
> +       iowrite16(l, cpupll->base + reg);

We don't usually see 16-bit accesses but if that's what the hardware
wants then OK.

> +       iowrite16(h, cpupll->base + reg + 4);
> +}
> +
> +static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
> +{
> +       msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
> +
> +       iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
> +       iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
> +       iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
> +       iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
> +
> +       iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
> +       iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
> +
> +       while (!(ioread16(cpupll->base + REG_LPF_LOCK)))
> +               cpu_relax();

Any timeout? Can this use the io read timeout APIs?

> +
> +       iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
> +
> +       msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L, regvalue);
> +}
> +
> +static unsigned long msc313_cpupll_frequencyforreg(u32 reg, unsigned long parent_rate)
> +{
> +       unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
> +       unsigned long long scaled;
> +
> +       if (prescaled == 0 || reg == 0)
> +               return 0;
> +       scaled = DIV_ROUND_DOWN_ULL(prescaled, reg);
> +
> +       return scaled;

Just

	return DIV_ROUND_DOWN_ULL(...);

> +}
> +
> +static u32 msc313_cpupll_regforfrequecy(unsigned long rate, unsigned long parent_rate)
> +{
> +       unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
> +       unsigned long long scaled;
> +       u32 reg;
> +
> +       if (prescaled == 0 || rate == 0)
> +               return 0;
> +
> +       scaled = DIV_ROUND_UP_ULL(prescaled, rate);
> +       reg = scaled;
> +
> +       return reg;

Just

	return DIV_ROUND_UP_ULL(...);

> +}
> +
> +static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
> +{
> +       struct msc313_cpupll *cpupll = to_cpupll(hw);
> +
> +       return msc313_cpupll_frequencyforreg(msc313_cpupll_reg_read32(cpupll, REG_LPF_LOW_L),
> +                                            parent_rate);
> +}
> +
> +static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
> +                                    unsigned long *parent_rate)
> +{
> +       u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
> +       long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
> +
> +       /*
> +        * This is my poor attempt at making sure the resulting
> +        * rate doesn't overshoot the requested rate.

If you want better bounds you can use determine_rate and then look at
the min/max constraints to make sure you don't overshoot. But otherwise
round_rate implementation is up to the provider to figure out what
should happen, i.e. overshooting could be OK if the provider intends for
it.

> +        */
> +       for (; rounded >= rate && reg > 0; reg--)
> +               rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
> +
> +       return rounded;
> +}
> +
> +static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
> +{
> +       struct msc313_cpupll *cpupll = to_cpupll(hw);
> +       u32 reg = msc313_cpupll_regforfrequecy(rate, parent_rate);
> +
> +       msc313_cpupll_setfreq(cpupll, reg);
> +
> +       return 0;
> +}
> +
> +static const struct clk_ops msc313_cpupll_ops = {
> +       .recalc_rate    = msc313_cpupll_recalc_rate,
> +       .round_rate     = msc313_cpupll_round_rate,
> +       .set_rate       = msc313_cpupll_set_rate,
> +};
> +
> +static const struct of_device_id msc313_cpupll_of_match[] = {
> +       {
> +               .compatible = "mstar,msc313-cpupll",
> +       },
> +       {}

This can and should be less lines

	{ .compatible = "mstar,msc313-cpupll", },
	{}

> +};
> +
> +static const struct clk_parent_data cpupll_parent = {
> +       .index  = 0,
> +};
> +
> +static int msc313_cpupll_probe(struct platform_device *pdev)
> +{
> +       struct clk_init_data clk_init = {};
> +       struct device *dev = &pdev->dev;
> +       struct msc313_cpupll *cpupll;
> +       int ret;
> +
> +       cpupll = devm_kzalloc(&pdev->dev, sizeof(*cpupll), GFP_KERNEL);
> +       if (!cpupll)
> +               return -ENOMEM;
> +
> +       cpupll->base = devm_platform_ioremap_resource(pdev, 0);
> +       if (IS_ERR(cpupll->base))
> +               return PTR_ERR(cpupll->base);
> +
> +       /* LPF might not contain the current frequency so fix that up */
> +       msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L,
> +                                 msc313_cpupll_reg_read32(cpupll, REG_CURRENT));
> +
> +       clk_init.name = dev_name(dev);
> +       clk_init.ops = &msc313_cpupll_ops;
> +       clk_init.flags = CLK_IS_CRITICAL;

Why is it critical? Can we have a comment? The clk ops don't have enable
or disable so it seems like the flag won't do anything.

> +       clk_init.parent_data = &cpupll_parent;
> +       clk_init.num_parents = 1;
> +       cpupll->clk_hw.init = &clk_init;
> +
> +       ret = devm_clk_hw_register(dev, &cpupll->clk_hw);
> +       if (ret)
> +               return ret;
> +
> +       return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, &cpupll->clk_hw);
> +}
> +
> +static struct platform_driver msc313_cpupll_driver = {
> +       .driver = {
> +               .name = "mstar-msc313-cpupll",
> +               .of_match_table = msc313_cpupll_of_match,
> +       },
> +       .probe = msc313_cpupll_probe,
> +};
> +builtin_platform_driver(msc313_cpupll_driver);


From sboyd at kernel.org  Fri Jan  7 17:26:48 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 07 Jan 2022 17:26:48 -0800
Subject: [RFC PATCH 1/4] clk: mxs: imx28: Reparent gpmi clk to ref_gpmi
In-Reply-To: <20211217155512.1877408-2-dario.binacchi@amarulasolutions.com>
References: <20211217155512.1877408-1-dario.binacchi@amarulasolutions.com>
 <20211217155512.1877408-2-dario.binacchi@amarulasolutions.com>
Message-ID: <20220108012649.4E050C36AEB@smtp.kernel.org>

Quoting Dario Binacchi (2021-12-17 07:55:09)
> From: Michael Trimarchi <michael at amarulasolutions.com>
> 
> ref_gpmi is connected that is sourced from pll0. This allow
> to get nand clk frequency to handle edo mode 5,4,3
> 
> Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
> ---
> 
>  drivers/clk/mxs/clk-imx28.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c
> index 62146ea4d5b8..9e0b9f8e5885 100644
> --- a/drivers/clk/mxs/clk-imx28.c
> +++ b/drivers/clk/mxs/clk-imx28.c
> @@ -243,6 +243,9 @@ static void __init mx28_clocks_init(struct device_node *np)
>  
>         clk_register_clkdev(clks[enet_out], NULL, "enet_out");
>  
> +       /* GPMI set parent to ref_gpmi instead of osc */
> +       clk_set_parent(clks[gpmi_sel], clks[ref_gpmi]);

Please check the return value and print a warning or something if it
fails. Also, can it be done through assigned-clock-parents instead?

> +
>         for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
>                 clk_prepare_enable(clks[clks_init_on[i]]);
>  }


From sboyd at kernel.org  Fri Jan  7 17:27:38 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 07 Jan 2022 17:27:38 -0800
Subject: [PATCH v2] clk: imx: Add imx8dxl clk driver
In-Reply-To: <1639747533-9778-1-git-send-email-abel.vesa@nxp.com>
References: <1639747533-9778-1-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220108012739.8091EC36AEB@smtp.kernel.org>

Quoting Abel Vesa (2021-12-17 05:25:33)
> From: Jacky Bai <ping.bai at nxp.com>
> 
> Add files for imx8dxl clk driver which is based on imx8qxp clock driver.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From cki-project at redhat.com  Fri Jan  7 17:42:45 2022
From: cki-project at redhat.com (CKI Project)
Date: Sat, 08 Jan 2022 01:42:45 -0000
Subject: =?utf-8?b?4pyF?= PASS: Test report for kernel 5.16.0-rc8 (arm-next,
 492ba224)
Message-ID: <cki.CDRKTA19NIFFSWQQ62JW@redhat.com>



Check out this report and any autotriaged failures in our web dashboard:
    https://datawarehouse.cki-project.org/kcidb/checkouts/28411

Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: 492ba2240491 - Merge remote-tracking branch 'arm64/for-next/core' into for-kernelci

The results of these automated tests are provided below.

    Overall result: PASSED
             Merge: OK
           Compile: OK
             Tests: OK
    Targeted tests: NO

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2022/01/07/443601544

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? xfstests - ext4
       ??? xfstests - xfs
       ??? IPMI driver test
       ??? IPMItool loop stress test
       ??? selinux-policy: serge-testsuite
       ??? Storage blktests - blk
       ??? Storage block - filesystem fio test
       ??? Storage block - queue scheduler test
       ??? storage: software RAID testing
       ??? Storage: swraid mdadm raid_module test
       ??? stress: stress-ng - interrupt
       ??? stress: stress-ng - cpu
       ??? stress: stress-ng - cpu-cache
       ??? stress: stress-ng - memory
       ? ??? Podman system test - as root
       ? ??? Podman system test - as user
       ? ??? xfstests - btrfs
       ? ??? Storage blktests - nvme-tcp
       ? ??? Storage block - storage fio numa
       ? ??? lvm cache test
       ? ??? stress: stress-ng - os

    Host 2:
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP - cve
       ? LTP - sched
       ? LTP - syscalls
       ? LTP - can
       ? LTP - commands
       ? LTP - containers
       ? LTP - dio
       ? LTP - fs
       ? LTP - fsx
       ? LTP - math
       ? LTP - hugetlb
       ? LTP - mm
       ? LTP - nptl
       ? LTP - pty
       ? LTP - ipc
       ? LTP - tracing
       ? LTP: openposix test suite
       ? CIFS Connectathon
       ? POSIX pjd-fstest suites
       ? NFS Connectathon
       ? Loopdev Sanity
       ? jvm - jcstress tests
       ? Memory: fork_mem
       ? Memory function: memfd_create
       ? AMTU (Abstract Machine Test Utility)
       ? Networking bridge: sanity
       ? Ethernet drivers sanity
       ? Networking socket: fuzz
       ? Networking route: pmtu
       ? Networking route_func - local
       ? Networking route_func - forward
       ? Networking TCP: keepalive test
       ? Networking UDP: socket
       ? Networking cki netfilter test
       ? Networking tunnel: geneve basic test
       ? Networking tunnel: gre basic
       ? L2TP basic test
       ? Networking tunnel: vxlan basic
       ? Networking ipsec: basic netns - transport
       ? Networking ipsec: basic netns - tunnel
       ? Libkcapi AF_ALG test
       ? pciutils: update pci ids test
       ? ALSA PCM loopback test
       ? ALSA Control (mixer) Userspace Element test
       ? storage: dm/common
       ? lvm snapper test
       ? storage: SCSI VPD
       ? trace: ftrace/tracer
       ? ? i2c: i2cdetect sanity
       ? ? Firmware test suite
       ? ? Memory function: kaslr
       ? ? Networking: igmp conformance test
       ? ? audit: audit testsuite test

    Host 3:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ? ??? Storage blktests - nvmeof-mp

    Host 4:
       ? Boot test
       ? Reboot test
       ? ? Storage blktests - nvmeof-mp

    Host 5:
       ? Boot test
       ? Reboot test
       ? Networking bridge: sanity - mlx5
       ? Ethernet drivers sanity - mlx5

    Host 6:
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP - cve
       ? LTP - sched
       ? LTP - syscalls
       ? LTP - can
       ? LTP - commands
       ? LTP - containers
       ? LTP - dio
       ? LTP - fs
       ? LTP - fsx
       ? LTP - math
       ? LTP - hugetlb
       ? LTP - mm
       ? LTP - nptl
       ? LTP - pty
       ? LTP - ipc
       ? LTP - tracing
       ? LTP: openposix test suite
       ? CIFS Connectathon
       ? POSIX pjd-fstest suites
       ? NFS Connectathon
       ? Loopdev Sanity
       ? jvm - jcstress tests
       ? Memory: fork_mem
       ? Memory function: memfd_create
       ? AMTU (Abstract Machine Test Utility)
       ? Networking bridge: sanity
       ? Ethernet drivers sanity
       ? Networking socket: fuzz
       ? Networking route: pmtu
       ? Networking route_func - local
       ? Networking route_func - forward
       ? Networking TCP: keepalive test
       ? Networking UDP: socket
       ? Networking cki netfilter test
       ? Networking tunnel: geneve basic test
       ? Networking tunnel: gre basic
       ? L2TP basic test
       ? Networking tunnel: vxlan basic
       ? Networking ipsec: basic netns - transport
       ? Networking ipsec: basic netns - tunnel
       ? Libkcapi AF_ALG test
       ? pciutils: update pci ids test
       ? ALSA PCM loopback test
       ? ALSA Control (mixer) Userspace Element test
       ? storage: dm/common
       ? lvm snapper test
       ? storage: SCSI VPD
       ? trace: ftrace/tracer
       ? ? i2c: i2cdetect sanity
       ? ? Firmware test suite
       ? ? Memory function: kaslr
       ? ? Networking: igmp conformance test
       ? ? audit: audit testsuite test

    Host 7:
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? IPMI driver test
       ? IPMItool loop stress test
       ? selinux-policy: serge-testsuite
       ? Storage blktests - blk
       ? Storage block - filesystem fio test
       ? Storage block - queue scheduler test
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? stress: stress-ng - interrupt
       ? stress: stress-ng - cpu
       ? stress: stress-ng - cpu-cache
       ? stress: stress-ng - memory
       ? ? Podman system test - as root
       ? ? Podman system test - as user
       ? ? xfstests - btrfs
       ? ? Storage blktests - nvme-tcp
       ? ? Storage block - storage fio numa
       ? ? lvm cache test
       ? ? stress: stress-ng - os

    Host 8:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ? ??? Storage blktests - srp

    Host 9:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? Networking bridge: sanity - mlx5
       ??? Ethernet drivers sanity - mlx5

    Host 10:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ? ??? Storage blktests - srp

    Host 11:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ??? xfstests - ext4
       ??? xfstests - xfs
       ??? IPMI driver test
       ??? IPMItool loop stress test
       ??? selinux-policy: serge-testsuite
       ??? Storage blktests - blk
       ??? Storage block - filesystem fio test
       ??? Storage block - queue scheduler test
       ??? storage: software RAID testing
       ??? Storage: swraid mdadm raid_module test
       ??? stress: stress-ng - interrupt
       ??? stress: stress-ng - cpu
       ??? stress: stress-ng - cpu-cache
       ??? stress: stress-ng - memory
       ? ??? Podman system test - as root
       ? ??? Podman system test - as user
       ? ??? xfstests - btrfs
       ? ??? Storage blktests - nvme-tcp
       ? ??? Storage block - storage fio numa
       ? ??? lvm cache test
       ? ??? stress: stress-ng - os

    Host 12:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ??? Boot test
       ??? Reboot test
       ? ??? Storage blktests - nvmeof-mp

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.
Targeted tests
--------------
Test runs for patches always include a set of base tests, plus some
tests chosen based on the file paths modified by the patch. The latter
are called "targeted tests". If no targeted tests are run, that means
no patch-specific tests are available. Please, consider contributing a
targeted test for related patches to increase test coverage. See
https://docs.engineering.redhat.com/x/_wEZB for more details.



From kuba at kernel.org  Fri Jan  7 18:34:41 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 7 Jan 2022 18:34:41 -0800
Subject: [PATCH v6] sun4i-emac.c: add dma support
In-Reply-To: <202201071532.57A08030@keescook>
References: <20211228164817.1297c1c9@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <tencent_DE05ADA53D5B084D4605BE6CB11E49EF7408@qq.com>
 <202201071532.57A08030@keescook>
Message-ID: <20220107183441.484b0de5@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Fri, 7 Jan 2022 15:34:18 -0800 Kees Cook wrote:
> On Wed, Dec 29, 2021 at 09:43:51AM +0800, conleylee at foxmail.com wrote:
> > From: Conley Lee <conleylee at foxmail.com>
> >
> > Thanks for your review. Here is the new version for this patch.
> >
> > This patch adds support for the emac rx dma present on sun4i. The emac
> > is able to move packets from rx fifo to RAM by using dma.
> >
> > Change since v4.
> >   - rename sbk field to skb
> >   - rename alloc_emac_dma_req to emac_alloc_dma_req
> >   - using kzalloc(..., GPF_ATOMIC) in interrupt context to avoid
> >     sleeping
> >   - retry by using emac_inblk_32bit when emac_dma_inblk_32bit fails
> >   - fix some code style issues
> >
> > Change since v5.
> >   - fix some code style issue
> >
> > Signed-off-by: Conley Lee <conleylee at foxmail.com>
>
> This is causing build failures:
> 
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 allmodconfig
> $ make CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 -j... -k -s
> drivers/net/ethernet/allwinner/sun4i-emac.c: In function 'emac_configure_dma':
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:60: error: format '%x' expects argument of type 'unsigned int', but argument 3 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                           ~^
>       |                                                            |                                      |                                                            unsigned int
>       |                                                           %llx
>   923 |                     regs->start, resource_size(regs));
>       |                     ~~~~~~~~~~~
>       |                         |
>       |                         resource_size_t {aka long long unsigned int}
> drivers/net/ethernet/allwinner/sun4i-emac.c:922:71: error: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'resource_size_t' {aka 'long long unsigned int'} [-Werror=format=]
>   922 |         netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
>       |                                                                      ~^
>       |                                                                       |
>       |                                                                       unsigned int
>       |                                                                      %llu
>   923 |                     regs->start, resource_size(regs));
>       |                                  ~~~~~~~~~~~~~~~~~~~
>       |                                  |
>       |                                  resource_size_t {aka long long unsigned int}
> 

Ugh, I saw this and somehow it didn't enter my brain that it's new.
%pa right? Let me test that and send a fix before we close net-next..


From lkp at intel.com  Fri Jan  7 18:53:53 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 8 Jan 2022 10:53:53 +0800
Subject: [arm:cex7 171/187] drivers/net/dsa/mt7530.c:3005:25: error:
 initialization of 'int (*)(struct phylink_pcs *, unsigned int,  long
 unsigned int *, const struct phylink_link_state *)' from incompatible
 pointer type 'void (*)(struct phylink_pcs *, long unsigned int *, const
 str...
Message-ID: <202201081004.KlKoEQZg-lkp@intel.com>

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git cex7
head:   c0fd07781c7d7d3a273892450c656e1eede8d221
commit: 708ac1dafaf0600cc8361fb9e3f03a8d331dbb2b [171/187] net: phylink: pass mode into pcs_validate()
config: arc-allyesconfig (https://download.01.org/0day-ci/archive/20220108/202201081004.KlKoEQZg-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git remote add arm git://git.armlinux.org.uk/~rmk/linux-arm.git
        git fetch --no-tags arm cex7
        git checkout 708ac1dafaf0600cc8361fb9e3f03a8d331dbb2b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/net/dsa/mt7530.c:3005:25: error: initialization of 'int (*)(struct phylink_pcs *, unsigned int,  long unsigned int *, const struct phylink_link_state *)' from incompatible pointer type 'void (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' [-Werror=incompatible-pointer-types]
    3005 |         .pcs_validate = mt753x_pcs_validate,
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3005:25: note: (near initialization for 'mt7530_pcs_ops.pcs_validate')
   drivers/net/dsa/mt7530.c:3012:25: error: initialization of 'int (*)(struct phylink_pcs *, unsigned int,  long unsigned int *, const struct phylink_link_state *)' from incompatible pointer type 'void (*)(struct phylink_pcs *, long unsigned int *, const struct phylink_link_state *)' [-Werror=incompatible-pointer-types]
    3012 |         .pcs_validate = mt753x_pcs_validate,
         |                         ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3012:25: note: (near initialization for 'mt7531_pcs_ops.pcs_validate')
   drivers/net/dsa/mt7530.c: In function 'mt753x_setup':
   drivers/net/dsa/mt7530.c:3039:44: error: 'struct mt7530_priv' has no member named 'pcs_ops'
    3039 |                 priv->pcs[i].pcs.ops = priv->pcs_ops;
         |                                            ^~
   cc1: some warnings being treated as errors


vim +3005 drivers/net/dsa/mt7530.c

c288575f7810a51 Landen Chao           2020-09-11  3003  
53b8fb9411f0063 Russell King (Oracle  2021-11-21  3004) static const struct phylink_pcs_ops mt7530_pcs_ops = {
53b8fb9411f0063 Russell King (Oracle  2021-11-21 @3005) 	.pcs_validate = mt753x_pcs_validate,
53b8fb9411f0063 Russell King (Oracle  2021-11-21  3006) 	.pcs_get_state = mt7530_pcs_get_state,
53b8fb9411f0063 Russell King (Oracle  2021-11-21  3007) 	.pcs_config = mt753x_pcs_config,
53b8fb9411f0063 Russell King (Oracle  2021-11-21  3008) 	.pcs_an_restart = mt7530_pcs_an_restart,
53b8fb9411f0063 Russell King (Oracle  2021-11-21  3009) };
88bdef8be9f649c Landen Chao           2020-09-11  3010  

:::::: The code at line 3005 was first introduced by commit
:::::: 53b8fb9411f006389a222c44fc1c08295ddfae2b net: dsa: mt7530: partially convert to phylink_pcs  *EXPERIMENTAL*

:::::: TO: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
:::::: CC: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From kuba at kernel.org  Fri Jan  7 19:22:01 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 7 Jan 2022 19:22:01 -0800
Subject: [PATCH v2 0/3] ARM: ox810se: Add Ethernet support
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <20220107192201.56136f10@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Tue,  4 Jan 2022 15:56:43 +0100 Neil Armstrong wrote:
> This adds support for the Synopsys DWMAC controller found in the
> OX820SE SoC, by using almost the same glue code as the OX820.
> 
> Patch 1 & 2 are for net branch, patch 3 will be queued to arm-soc.
> 
> Changes since v1:
> - correctly update value read from register
> - add proper tag on patch 3 for arm-soc tree

Waiting for Rob's ack, I just noticed you haven't CCed him directly.
Adding his address now, but not sure if that's enough...


From marcan at marcan.st  Fri Jan  7 21:13:49 2022
From: marcan at marcan.st (Hector Martin)
Date: Sat, 8 Jan 2022 14:13:49 +0900
Subject: [GIT PULL] Apple SoC MAINTAINERS updates for 5.17
Message-ID: <24ae6871-3e67-5c7f-2060-28048db439a2@marcan.st>

Hi SoC folks,

Please merge this trivial MAINTAINERS change for 5.17.

This commit was waiting on the watchdog driver to be merged, but I only
just now realized that it silently did. Sorry for the last-minute pull.
If this can't make it into the 5.17 merge window, it can be added as a
fix later instead.

The branch is based on asahi-soc-dt-5.17-v2 to avoid a merge conflict
with other changes that happened there.

-Hector

The following changes since commit 301f651614c3396d711a8cc3f92f6fb95b12f5c5:

  dt-bindings: mailbox: apple,mailbox: Add power-domains property
(2021-12-15 20:20:38 +0900)

are available in the Git repository at:

  https://github.com/AsahiLinux/linux.git tags/asahi-soc-maintainers-5.17

for you to fetch changes up to 6dc701ee9fabfc929cae2d7acc957bf38e4c3264:

  MAINTAINERS: Add Apple watchdog to ARM/APPLE MACHINE SUPPORT
(2022-01-08 14:10:03 +0900)

----------------------------------------------------------------
Apple SoC MAINTAINERS updates for 5.17.

Adds the watchdog driver MAINTAINERS changes. The driver itself is
already merged.

This branch is based on asahi-soc-dt-5.17-v2 to avoid a merge conflict.

----------------------------------------------------------------
Sven Peter (1):
      MAINTAINERS: Add Apple watchdog to ARM/APPLE MACHINE SUPPORT

 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)



From quic_saipraka at quicinc.com  Fri Jan  7 21:34:16 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 8 Jan 2022 11:04:16 +0530
Subject: [PATCHv6 4/5] tracing: Add register read/write tracing support
In-Reply-To: <20220107095638.7d81c1b9@gandalf.local.home>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
 <20220106131824.073fbe5c@gandalf.local.home>
 <df9b5a82-5f00-f3ec-14cf-0b212be2a7a7@quicinc.com>
 <20220107095638.7d81c1b9@gandalf.local.home>
Message-ID: <b36d92de-ae0b-243d-f2de-e12fe730f6c4@quicinc.com>

Hi,

On 1/7/2022 8:26 PM, Steven Rostedt wrote:
> On Fri, 7 Jan 2022 10:40:05 +0530
> Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
>
>> Hi Steve,
>>
>> On 1/6/2022 11:48 PM, Steven Rostedt wrote:
>>> This should not be in the kernel/trace directory. It should be in the
>> Hmm these are called from low level generic io header file
>> (include/asm-generic/) where
>> we wouldn't have any Kconfig to control this feature flexibly and as we
>> can have this as
>> a generic feature selectable by other architectures, wouldn't this be
>> suited in kernel/trace?
> Isn't there a place for generic rwmmio code?

I am thinking of moving it to lib/ similar to an interface of 
logic_iomem.c which
Arnd had initially suggested to look at.

>> I thought you were ok with the folder structure in the initial versions
>> of the series?
> Sorry, I missed the C file in kernel/trace. The files in kernel/trace tend
> to be specific for the internals of tracing. This C file is more to hold
> helper functions for mmio, which to me should be someplace for mmio code.
> Perhaps in mm/ ?
>

Oh ok, mm would not be the right fit as it is memory management and this 
is about
memory mapped IO, let me try and move it to lib/ as done for logic_iomem.c

Thanks,
Sai


From reijiw at google.com  Fri Jan  7 21:40:14 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Fri, 7 Jan 2022 21:40:14 -0800
Subject: [RFC PATCH v3 03/11] KVM: Introduce KVM_CAP_ARM_HVC_FW_REG_BMAP
In-Reply-To: <20220104194918.373612-4-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-4-rananta@google.com>
Message-ID: <CAAeT=FxCCD+H1z8+gfyBZNeibfAUqUenZZe56Vj_3fCghJjy=Q@mail.gmail.com>

Hi Raghu,

On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> Introduce the KVM ARM64 capability, KVM_CAP_ARM_HVC_FW_REG_BMAP,
> to indicate the support for psuedo-firmware bitmap extension.
> Each of these registers holds a feature-set exposed to the guest
> in the form of a bitmap. If supported, a simple 'read' of the
> capability should return the number of psuedo-firmware registers
> supported. User-space can utilize this to discover the registers.
> It can further explore or modify the features using the classical
> GET/SET_ONE_REG interface.
>
> Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> ---
>  Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
>  include/uapi/linux/kvm.h       |  1 +
>  2 files changed, 22 insertions(+)
>
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index aeeb071c7688..646176537f2c 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -6925,6 +6925,27 @@ indicated by the fd to the VM this is called on.
>  This is intended to support intra-host migration of VMs between userspace VMMs,
>  upgrading the VMM process without interrupting the guest.
>
> +7.30 KVM_CAP_ARM_HVC_FW_REG_BMAP

IMHO, instead of including its format of the register in the name,
including its purpose/function in the name might be better.
e.g. KVM_CAP_ARM_HVC_FEATURE_REG ?
(Feature fields don't necessarily have to be in a bitmap format
 if they don't fit well although I'm not sure if we have such fields.)

> +--------------------------------
> +
> +:Architectures: arm64
> +:Parameters: None
> +:Returns: Number of psuedo-firmware registers supported

Looking at patch-4, the return value of this would be the number of
pseudo-firmware *bitmap* registers supported.
BTW, "4.68 KVM_SET_ONE_REG" in the doc uses the word "arm64 firmware
pseudo-registers".  It would be nicer to use the same term.

> +
> +This capability indicates that KVM for arm64 supports the psuedo-firmware
> +register bitmap extension. Each of these registers represent the features
> +supported by a particular type in the form of a bitmap. By default, these
> +registers are set with the upper limit of the features that are supported.
> +
> +The registers can be accessed via the standard SET_ONE_REG and KVM_GET_ONE_REG
> +interfaces. The user-space is expected to read the number of these registers
> +available by reading KVM_CAP_ARM_HVC_FW_REG_BMAP, read the current bitmap
> +configuration via GET_ONE_REG for each register, and then write back the
> +desired bitmap of features that it wishes the guest to see via SET_ONE_REG.
> +
> +Note that KVM doesn't allow the user-space to modify these registers after
> +the VM (any of the vCPUs) has started running.

Since even if KVM_RUN fails, and the VM hasn't started yet,
it will get immutable. So, "after any of the vCPUs run KVM_RUN."
might be more clear ?

Thanks,
Reiji



> +
>  8. Other capabilities.
>  ======================
>
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 1daa45268de2..209b43dbbc3c 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -1131,6 +1131,7 @@ struct kvm_ppc_resize_hpt {
>  #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
>  #define KVM_CAP_ARM_MTE 205
>  #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
> +#define KVM_CAP_ARM_HVC_FW_REG_BMAP 207
>
>  #ifdef KVM_CAP_IRQ_ROUTING
>
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From lkp at intel.com  Fri Jan  7 22:07:17 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 8 Jan 2022 14:07:17 +0800
Subject: [arm:net-queue 171/174] drivers/net/dsa/mt7530.c:3005:18: error:
 incompatible function pointer types initializing 'int (*)(struct phylink_pcs
 *, unsigned int, unsigned long *, const struct phylink_link_state *)' with
 an expression of type 'void (struct phylink_pcs *, unsigned lo...
Message-ID: <202201081440.qAwUArEv-lkp@intel.com>

tree:   git://git.armlinux.org.uk/~rmk/linux-arm.git net-queue
head:   9ceab2608ffe3f543e1118044bc86bc6ccb93255
commit: a5d401c6c8d1f84dcfa1a267166ad8ce85cda26f [171/174] net: phylink: pass mode into pcs_validate()
config: i386-randconfig-a005-20220106 (https://download.01.org/0day-ci/archive/20220108/202201081440.qAwUArEv-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project ca7ffe09dc6e525109e3cd570cc5182ce568be13)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        git remote add arm git://git.armlinux.org.uk/~rmk/linux-arm.git
        git fetch --no-tags arm net-queue
        git checkout a5d401c6c8d1f84dcfa1a267166ad8ce85cda26f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/net/dsa/mt7530.c:3005:18: error: incompatible function pointer types initializing 'int (*)(struct phylink_pcs *, unsigned int, unsigned long *, const struct phylink_link_state *)' with an expression of type 'void (struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' [-Werror,-Wincompatible-function-pointer-types]
           .pcs_validate = mt753x_pcs_validate,
                           ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3012:18: error: incompatible function pointer types initializing 'int (*)(struct phylink_pcs *, unsigned int, unsigned long *, const struct phylink_link_state *)' with an expression of type 'void (struct phylink_pcs *, unsigned long *, const struct phylink_link_state *)' [-Werror,-Wincompatible-function-pointer-types]
           .pcs_validate = mt753x_pcs_validate,
                           ^~~~~~~~~~~~~~~~~~~
   drivers/net/dsa/mt7530.c:3039:32: error: no member named 'pcs_ops' in 'struct mt7530_priv'
                   priv->pcs[i].pcs.ops = priv->pcs_ops;
                                          ~~~~  ^
   3 errors generated.


vim +3005 drivers/net/dsa/mt7530.c

c288575f7810a5 Landen Chao           2020-09-11  3003  
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21  3004) static const struct phylink_pcs_ops mt7530_pcs_ops = {
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21 @3005) 	.pcs_validate = mt753x_pcs_validate,
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21  3006) 	.pcs_get_state = mt7530_pcs_get_state,
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21  3007) 	.pcs_config = mt753x_pcs_config,
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21  3008) 	.pcs_an_restart = mt7530_pcs_an_restart,
0ecdf3ab2ae1d3 Russell King (Oracle  2021-11-21  3009) };
88bdef8be9f649 Landen Chao           2020-09-11  3010  

:::::: The code at line 3005 was first introduced by commit
:::::: 0ecdf3ab2ae1d35480614337758d8db5060885cf net: dsa: mt7530: partially convert to phylink_pcs  *EXPERIMENTAL*

:::::: TO: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
:::::: CC: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From qianggui.song at amlogic.com  Sat Jan  8 00:42:14 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:14 +0800
Subject: [PATCH 0/4] irqchip/meson-gpio: Add support for Meson-S4 SoC
Message-ID: <20220108084218.31877-1-qianggui.song@amlogic.com>

This patchset add support for GPIO interrupt controller of Meson-S4 SoC
Which has somethings different with current other meson chips. To
support the new chips, current gpio irqchip driver need to rework as
below:
1. support more than 8 gpio irq line.
2. add a set trigger type callback function.

With above work, add support for S4 gpio irqchip

Qianggui Song (4):
  dt-bindings: interrupt-controller: New binding for Meson-S4 SoCs
  irqchip/meson-gpio: support more than 8 channels gpio irq line
  irqchip/meson-gpio: add select trigger type callback
  irqchip/meson-gpio: Add support for meson s4 SoCs

 .../amlogic,meson-gpio-intc.txt               |  1 +
 drivers/irqchip/irq-meson-gpio.c              | 97 ++++++++++++++++---
 2 files changed, 86 insertions(+), 12 deletions(-)

-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:15 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:15 +0800
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-2-qianggui.song@amlogic.com>

Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 23b18b92c558..9300736bf1ed 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -18,6 +18,7 @@ Required properties:
     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
+    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
 - reg : Specifies base physical address and size of the registers.
 - interrupt-controller : Identifies the node as an interrupt controller.
 - #interrupt-cells : Specifies the number of cells needed to encode an
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:16 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:16 +0800
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio irq
 line
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-3-qianggui.song@amlogic.com>

Current meson gpio irqchip driver only support 8 channels for gpio irq
line, later chips may have more then 8 channels, so need to modify code
to support more.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index d90ff0b92480..6a7b4fb13452 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -16,7 +16,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#define NUM_CHANNEL 8
 #define MAX_INPUT_MUX 256
 
 #define REG_EDGE_POL	0x00
@@ -60,6 +59,7 @@ struct irq_ctl_ops {
 
 struct meson_gpio_irq_params {
 	unsigned int nr_hwirq;
+	unsigned int channel_num;
 	bool support_edge_both;
 	unsigned int edge_both_offset;
 	unsigned int edge_single_offset;
@@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
+	.channel_num = 8,					\
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
@@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 8,				\
 	.pol_low_offset = 0,					\
 	.pin_sel_mask = 0x7f,					\
+	.channel_num = 8,					\
 
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
@@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 struct meson_gpio_irq_controller {
 	const struct meson_gpio_irq_params *params;
 	void __iomem *base;
-	u32 channel_irqs[NUM_CHANNEL];
-	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
+	u32 *channel_irqs;
+	unsigned long *channel_map;
+	u8 channel_num;
 	spinlock_t lock;
 };
 
@@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
-	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
-	if (idx >= NUM_CHANNEL) {
+	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
+	if (idx >= ctl->channel_num) {
 		spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
@@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
 
 	ctl->params = match->data;
 
+	ctl->channel_num = ctl->params->channel_num;
+	ctl->channel_irqs = kcalloc(ctl->channel_num,
+				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
+	if (!ctl->channel_irqs)
+		return -ENOMEM;
+
+	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
+	if (!ctl->channel_map) {
+		kfree(ctl->channel_irqs);
+		return -ENOMEM;
+	}
+
 	ret = of_property_read_variable_u32_array(node,
 						  "amlogic,channel-interrupts",
 						  ctl->channel_irqs,
-						  NUM_CHANNEL,
-						  NUM_CHANNEL);
+						  ctl->channel_num,
+						  ctl->channel_num);
 	if (ret < 0) {
-		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
+		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
 		return ret;
 	}
 
@@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
 	}
 
 	pr_info("%d to %d gpio interrupt mux initialized\n",
-		ctl->params->nr_hwirq, NUM_CHANNEL);
+		ctl->params->nr_hwirq, ctl->channel_num);
 
 	return 0;
 
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:17 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:17 +0800
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-4-qianggui.song@amlogic.com>

Due to some chips may use different registers and offset, provide
a set trigger type call back.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 6a7b4fb13452..98419428fcbd 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -55,6 +55,8 @@ struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
 				 unsigned int channel, unsigned long hwirq);
 	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
+	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
+					  unsigned int idx, u32 val);
 };
 
 struct meson_gpio_irq_params {
@@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
 	struct irq_ctl_ops ops;
 };
 
-#define INIT_MESON_COMMON(irqs, init, sel)			\
+#define INIT_MESON_COMMON(irqs, init, sel, type)		\
 	.nr_hwirq = irqs,					\
 	.ops = {						\
 		.gpio_irq_init = init,				\
 		.gpio_irq_sel_pin = sel,			\
+		.gpio_irq_sel_type = type,			\
 	},
 
 #define INIT_MESON8_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
-			  meson8_gpio_irq_sel_pin)		\
+			  meson8_gpio_irq_sel_pin, NULL)	\
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
@@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
-			  meson_a1_gpio_irq_sel_pin)		\
+			  meson_a1_gpio_irq_sel_pin, NULL)	\
 	.support_edge_both = true,				\
 	.edge_both_offset = 16,					\
 	.edge_single_offset = 8,				\
@@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
 	 */
 	type &= IRQ_TYPE_SENSE_MASK;
 
+	/* Some controllers may have different calculation method*/
+	if (params->ops.gpio_irq_sel_type)
+		return params->ops.gpio_irq_sel_type(ctl, idx, type);
+
 	/*
 	 * New controller support EDGE_BOTH trigger. This setting takes
 	 * precedence over the other edge/polarity settings
-- 
2.34.1



From qianggui.song at amlogic.com  Sat Jan  8 00:42:18 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Sat, 8 Jan 2022 16:42:18 +0800
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220108084218.31877-1-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
Message-ID: <20220108084218.31877-5-qianggui.song@amlogic.com>

The meson s4 SoCs support 12 gpio irq lines compared with previous
serial chips and have something different, details are as below.

IRQ Number:
- 80:68 13 pins on bank Z
- 67:48 20 pins on bank X
- 47:36 12 pins on bank H
- 35:24 12 pins on bank D
- 23:22 2  pins on bank E
- 21:14 8  pins on bank C
- 13:0  13 pins on bank B

- PADCTRL_GPIO_IRQ_CTRL0
  bit[31]:    enable/disable the whole irq lines
  bit[12-23]: single edge trigger
  bit[0-11]:  poll trigger

- PADCTRL_GPIO_IRQ_CTRL[X]
- bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
- bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
  where X = 1-6

- PADCTRL_GPIO_IRQ_CTRL[7]
  bit[0-11]: both edge trigger

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index 98419428fcbd..c5d20a866c37 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -42,6 +42,11 @@
 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
 
+/* use for s4 chips */
+#define REG_EDGE_POL_S4	0x1c
+#define REG_EDGE_POL_MASK_S4(x)				\
+	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
+
 struct meson_gpio_irq_controller;
 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				    unsigned int channel, unsigned long hwirq);
@@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				      unsigned int channel,
 				      unsigned long hwirq);
 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
+static unsigned int
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, u32 val);
 
 struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
@@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
 	.pin_sel_mask = 0x7f,					\
 	.channel_num = 8,					\
 
+#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
+	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
+			  meson_a1_gpio_irq_sel_pin,            \
+			  meson_s4_gpio_irq_sel_type)           \
+	.support_edge_both = true,				\
+	.edge_both_offset = 0,					\
+	.edge_single_offset = 12,				\
+	.pol_low_offset = 0,					\
+	.pin_sel_mask = 0xff,					\
+	.channel_num = 12,					\
+
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
 };
@@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
 	INIT_MESON_A1_COMMON_DATA(62)
 };
 
+static const struct meson_gpio_irq_params s4_params = {
+	INIT_MESON_S4_COMMON_DATA(82)
+};
+
 static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
 	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
+	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
 	{ }
 };
 
@@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
 }
 
+static unsigned int
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, unsigned int type)
+{
+	unsigned int val = 0;
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);
+
+	if (type == IRQ_TYPE_EDGE_BOTH) {
+		val |= BIT(ctl->params->edge_both_offset + (idx));
+		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
+					   BIT(ctl->params->edge_both_offset + (idx)), val);
+		return 0;
+	}
+
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->pol_low_offset + (idx));
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->edge_single_offset  + (idx));
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
+				   REG_EDGE_POL_MASK_S4(idx), val);
+
+	return 0;
+};
+
 static int
 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 			       unsigned long  hwirq,
-- 
2.34.1



From linmq006 at gmail.com  Sat Jan  8 00:53:36 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Sat,  8 Jan 2022 08:53:36 +0000
Subject: [PATCH] dmaengine: stm32-dmamux: Fix PM disable depth imbalance in
 stm32_dmamux_probe
Message-ID: <20220108085336.11992-1-linmq006@gmail.com>

The pm_runtime_enable will increase power disable depth.
If the probe fails, we should use pm_runtime_disable() to balance
pm_runtime_enable().

Fixes: 4f3ceca254e0 ("dmaengine: stm32-dmamux: Add PM Runtime support")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/dma/stm32-dmamux.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
index a42164389ebc..d5d55732adba 100644
--- a/drivers/dma/stm32-dmamux.c
+++ b/drivers/dma/stm32-dmamux.c
@@ -292,10 +292,12 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
 	ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
 				     &stm32_dmamux->dmarouter);
 	if (ret)
-		goto err_clk;
+		goto pm_disable;
 
 	return 0;
 
+pm_disable:
+	pm_runtime_disable(&pdev->dev);
 err_clk:
 	clk_disable_unprepare(stm32_dmamux->clk);
 
-- 
2.17.1



From ardb at kernel.org  Sat Jan  8 01:31:13 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 8 Jan 2022 10:31:13 +0100
Subject: [PATCH] arm64: atomics: Dereference matching size
In-Reply-To: <20220107232746.1540130-1-keescook@chromium.org>
References: <20220107232746.1540130-1-keescook@chromium.org>
Message-ID: <CAMj1kXFOqUuSUG=9g0Dd+m3yUfbtf7JG=CR2VP6i6AGXPPAa8Q@mail.gmail.com>

On Sat, 8 Jan 2022 at 00:28, Kees Cook <keescook at chromium.org> wrote:
>
> When building with -Warray-bounds (which is desired to be enabled
> globally), the following warning is generated:
>
> In file included from ./arch/arm64/include/asm/lse.h:16,
>                  from ./arch/arm64/include/asm/cmpxchg.h:14,
>                  from ./arch/arm64/include/asm/atomic.h:16,
>                  from ./include/linux/atomic.h:7,
>                  from ./include/asm-generic/bitops/atomic.h:5,
>                  from ./arch/arm64/include/asm/bitops.h:25,
>                  from ./include/linux/bitops.h:33,
>                  from ./include/linux/kernel.h:22,
>                  from kernel/printk/printk.c:22:
> ./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
>   247 |         asm volatile(                                                   \
>       |         ^~~
> ./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
>   266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
>       | ^~~~~~~~~~~~~~
> kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
>  3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
>       |                 ^~~~~~~~~~~~~~~~~~~~
>
> This is due to the compiler seeing an unsigned long * cast against
> something (atomic_t) that is int sized. Replace the cast with the
> matching size cast. This results in no change in binary output.
>
> Cc: Will Deacon <will at kernel.org>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Boqun Feng <boqun.feng at gmail.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Kees Cook <keescook at chromium.org>

Acked-by: Ard Biesheuvel <ardb at kernel.org>

> ---
>  arch/arm64/include/asm/atomic_lse.h | 2 +-
>  arch/arm64/include/asm/cmpxchg.h    | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
> index d955ade5df7c..5d460f6b7675 100644
> --- a/arch/arm64/include/asm/atomic_lse.h
> +++ b/arch/arm64/include/asm/atomic_lse.h
> @@ -249,7 +249,7 @@ __lse__cmpxchg_case_##name##sz(volatile void *ptr,                  \
>         "       mov     %" #w "[tmp], %" #w "[old]\n"                   \
>         "       cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"    \
>         "       mov     %" #w "[ret], %" #w "[tmp]"                     \
> -       : [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),            \
> +       : [ret] "+r" (x0), [v] "+Q" (*(u##sz *)ptr),                    \
>           [tmp] "=&r" (tmp)                                             \
>         : [old] "r" (x1), [new] "r" (x2)                                \
>         : cl);                                                          \
> diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
> index f9bef42c1411..497acf134d99 100644
> --- a/arch/arm64/include/asm/cmpxchg.h
> +++ b/arch/arm64/include/asm/cmpxchg.h
> @@ -243,7 +243,7 @@ static inline void __cmpwait_case_##sz(volatile void *ptr,          \
>         "       cbnz    %" #w "[tmp], 1f\n"                             \
>         "       wfe\n"                                                  \
>         "1:"                                                            \
> -       : [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr)           \
> +       : [tmp] "=&r" (tmp), [v] "+Q" (*(u##sz *)ptr)                   \
>         : [val] "r" (val));                                             \
>  }
>
> --
> 2.30.2
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From kewei.xu at mediatek.com  Sat Jan  8 01:54:16 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 8 Jan 2022 17:54:16 +0800
Subject: [PATCH 0/2] add i2c support for mt8186
Message-ID: <20220108095418.16602-1-kewei.xu@mediatek.com>

Kewei Xu (2):
  dt-bindings: i2c: update bindings for MT8186 SoC
  i2c: mediatek: Add i2c compatible for Mediatek MT8186

 .../devicetree/bindings/i2c/i2c-mt65xx.txt         |  1 +
 drivers/i2c/busses/i2c-mt65xx.c                    | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

--
2.18.0



From kewei.xu at mediatek.com  Sat Jan  8 01:54:17 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 8 Jan 2022 17:54:17 +0800
Subject: [PATCH 1/2] dt-bindings: i2c: update bindings for MT8186 SoC
In-Reply-To: <20220108095418.16602-1-kewei.xu@mediatek.com>
References: <20220108095418.16602-1-kewei.xu@mediatek.com>
Message-ID: <20220108095418.16602-2-kewei.xu@mediatek.com>

Add a DT binding documentation for the MT8186 soc.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216ae7084..88f74a3c81ec 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -14,6 +14,7 @@ Required properties:
       "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629
       "mediatek,mt8173-i2c": for MediaTek MT8173
       "mediatek,mt8183-i2c": for MediaTek MT8183
+      "mediatek,mt8186-i2c": for MediaTek MT8186
       "mediatek,mt8192-i2c": for MediaTek MT8192
       "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195
       "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
-- 
2.25.1



From kewei.xu at mediatek.com  Sat Jan  8 01:54:18 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Sat, 8 Jan 2022 17:54:18 +0800
Subject: [PATCH 2/2] i2c: mediatek: Add i2c compatible for Mediatek MT8186
In-Reply-To: <20220108095418.16602-1-kewei.xu@mediatek.com>
References: <20220108095418.16602-1-kewei.xu@mediatek.com>
Message-ID: <20220108095418.16602-3-kewei.xu@mediatek.com>

Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
MT8186 doesn't need handshake signal witch apdma.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9ea427f53083..aa4d21838e14 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -397,6 +397,19 @@ static const struct mtk_i2c_compatible mt8183_compat = {
 	.max_dma_support = 33,
 };
 
+static const struct mtk_i2c_compatible mt8186_compat = {
+	.regs = mt_i2c_regs_v2,
+	.pmic_i2c = 0,
+	.dcm = 0,
+	.auto_restart = 1,
+	.aux_len_reg = 1,
+	.timing_adjust = 1,
+	.dma_sync = 0,
+	.ltiming_adjust = 1,
+	.apdma_sync = 0,
+	.max_dma_support = 36,
+};
+
 static const struct mtk_i2c_compatible mt8192_compat = {
 	.quirks = &mt8183_i2c_quirks,
 	.regs = mt_i2c_regs_v2,
@@ -418,6 +431,7 @@ static const struct of_device_id mtk_i2c_of_match[] = {
 	{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
 	{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
 	{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
+	{ .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat },
 	{ .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
 	{}
 };
-- 
2.25.1



From maz at kernel.org  Sat Jan  8 02:37:52 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 10:37:52 +0000
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <20220108084218.31877-3-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-3-qianggui.song@amlogic.com>
Message-ID: <87tueetsvz.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:16 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..6a7b4fb13452 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int channel_num;

For consistency, please name this nr_channels.

>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.channel_num = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.channel_num = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;
> +	u8 channel_num;

Same thing. Though this is completely superfluous, see below.

>  	spinlock_t lock;
>  };
>  
> @@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  	spin_lock_irqsave(&ctl->lock, flags);
>  
>  	/* Find a free channel */
> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
> -	if (idx >= NUM_CHANNEL) {
> +	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
> +	if (idx >= ctl->channel_num) {
>  		spin_unlock_irqrestore(&ctl->lock, flags);
>  		pr_err("No channel available\n");
>  		return -ENOSPC;
> @@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>  
>  	ctl->params = match->data;
>  
> +	ctl->channel_num = ctl->params->channel_num;

Since you already have a pointer to params, why do you need to
duplicate this information?

> +	ctl->channel_irqs = kcalloc(ctl->channel_num,
> +				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
> +	if (!ctl->channel_irqs)
> +		return -ENOMEM;
> +
> +	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
> +	if (!ctl->channel_map) {
> +		kfree(ctl->channel_irqs);
> +		return -ENOMEM;
> +	}
> +
>  	ret = of_property_read_variable_u32_array(node,
>  						  "amlogic,channel-interrupts",
>  						  ctl->channel_irqs,
> -						  NUM_CHANNEL,
> -						  NUM_CHANNEL);
> +						  ctl->channel_num,
> +						  ctl->channel_num);
>  	if (ret < 0) {
> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
> +		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
>  		return ret;

You are now leaking the bitmap and channel_map allocations.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sat Jan  8 02:44:59 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 10:44:59 +0000
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220108084218.31877-4-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-4-qianggui.song@amlogic.com>
Message-ID: <87sftytsk4.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:17 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Due to some chips may use different registers and offset, provide
> a set trigger type call back.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index 6a7b4fb13452..98419428fcbd 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>  				 unsigned int channel, unsigned long hwirq);
>  	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
> +	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
> +					  unsigned int idx, u32 val);
>  };
>  
>  struct meson_gpio_irq_params {
> @@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
>  	struct irq_ctl_ops ops;
>  };
>  
> -#define INIT_MESON_COMMON(irqs, init, sel)			\
> +#define INIT_MESON_COMMON(irqs, init, sel, type)		\
>  	.nr_hwirq = irqs,					\
>  	.ops = {						\
>  		.gpio_irq_init = init,				\
>  		.gpio_irq_sel_pin = sel,			\
> +		.gpio_irq_sel_type = type,			\
>  	},
>  
>  #define INIT_MESON8_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
> -			  meson8_gpio_irq_sel_pin)		\
> +			  meson8_gpio_irq_sel_pin, NULL)	\
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> @@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> -			  meson_a1_gpio_irq_sel_pin)		\
> +			  meson_a1_gpio_irq_sel_pin, NULL)	\
>  	.support_edge_both = true,				\
>  	.edge_both_offset = 16,					\
>  	.edge_single_offset = 8,				\
> @@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>  	 */
>  	type &= IRQ_TYPE_SENSE_MASK;
>  
> +	/* Some controllers may have different calculation method*/
> +	if (params->ops.gpio_irq_sel_type)
> +		return params->ops.gpio_irq_sel_type(ctl, idx, type);
> +

No. If you are going to indirect these things, indirect them for all
implementations and keep the code clean.

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Sat Jan  8 03:06:42 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 11:06:42 +0000
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220108084218.31877-5-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
Message-ID: <87r19itrjx.wl-maz@kernel.org>

On Sat, 08 Jan 2022 08:42:18 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> The meson s4 SoCs support 12 gpio irq lines compared with previous
> serial chips and have something different, details are as below.
> 
> IRQ Number:
> - 80:68 13 pins on bank Z
> - 67:48 20 pins on bank X
> - 47:36 12 pins on bank H
> - 35:24 12 pins on bank D
> - 23:22 2  pins on bank E
> - 21:14 8  pins on bank C
> - 13:0  13 pins on bank B
> 
> - PADCTRL_GPIO_IRQ_CTRL0
>   bit[31]:    enable/disable the whole irq lines

s/the whole/all the/

>   bit[12-23]: single edge trigger
>   bit[0-11]:  poll trigger
> 
> - PADCTRL_GPIO_IRQ_CTRL[X]
> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2

choose?

> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
>   where X = 1-6
> 
> - PADCTRL_GPIO_IRQ_CTRL[7]
>   bit[0-11]: both edge trigger

This information would fit better in the code than in the commit
message.

> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
>  1 file changed, 51 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index 98419428fcbd..c5d20a866c37 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -42,6 +42,11 @@
>  #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
>  #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
>  
> +/* use for s4 chips */

s/use/Used/

> +#define REG_EDGE_POL_S4	0x1c
> +#define REG_EDGE_POL_MASK_S4(x)				\
> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })

Why on Earth should this macro handle multiple types?

> +
>  struct meson_gpio_irq_controller;
>  static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>  				    unsigned int channel, unsigned long hwirq);
> @@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>  				      unsigned int channel,
>  				      unsigned long hwirq);
>  static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
> +static unsigned int
> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
> +			   unsigned int idx, u32 val);
>  
>  struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
> @@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
>  	.pin_sel_mask = 0x7f,					\
>  	.channel_num = 8,					\
>  
> +#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
> +	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
> +			  meson_a1_gpio_irq_sel_pin,            \
> +			  meson_s4_gpio_irq_sel_type)           \
> +	.support_edge_both = true,				\
> +	.edge_both_offset = 0,					\
> +	.edge_single_offset = 12,				\
> +	.pol_low_offset = 0,					\
> +	.pin_sel_mask = 0xff,					\
> +	.channel_num = 12,					\
> +
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
>  };
> @@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
>  	INIT_MESON_A1_COMMON_DATA(62)
>  };
>  
> +static const struct meson_gpio_irq_params s4_params = {
> +	INIT_MESON_S4_COMMON_DATA(82)
> +};
> +
>  static const struct of_device_id meson_irq_gpio_matches[] = {
>  	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
>  	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
> @@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
>  	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
>  	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
> +	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
>  	{ }
>  };
>  
> @@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
>  	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
>  }
>  
> +static unsigned int
> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
> +			   unsigned int idx, unsigned int type)

An 'unsigned int' return type, directly returned by a caller that
has 'int' as its return type. What could possibly go wrong?

> +{
> +	unsigned int val = 0;
> +
> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);

Drop the 0 + as well as the useless bracketing all over this function.

> +
> +	if (type == IRQ_TYPE_EDGE_BOTH) {
> +		val |= BIT(ctl->params->edge_both_offset + (idx));
> +		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
> +					   BIT(ctl->params->edge_both_offset + (idx)), val);
> +		return 0;
> +	}
> +
> +	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
> +		val |= BIT(ctl->params->pol_low_offset + (idx));
> +
> +	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
> +		val |= BIT(ctl->params->edge_single_offset  + (idx));
> +
> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
> +				   REG_EDGE_POL_MASK_S4(idx), val);
> +
> +	return 0;
> +};
> +
>  static int
>  meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  			       unsigned long  hwirq,

	M.

-- 
Without deviation from the norm, progress is not possible.


From daniel at 0x0f.com  Sat Jan  8 03:49:49 2022
From: daniel at 0x0f.com (Daniel Palmer)
Date: Sat, 8 Jan 2022 20:49:49 +0900
Subject: [PATCH v2 2/9] clk: mstar: msc313 cpupll clk driver
In-Reply-To: <20220108012515.D1213C36AEB@smtp.kernel.org>
References: <20220102165730.50190-1-romain.perier@gmail.com>
 <20220102165730.50190-3-romain.perier@gmail.com>
 <20220108012515.D1213C36AEB@smtp.kernel.org>
Message-ID: <CAFr9PX=PvqTtueB9Mi_hZWaUvwfQWhm9Z2D+VtiJcnjzZSxH9w@mail.gmail.com>

Hi Stephen,

Thank you for looking at this for us.

On Sat, 8 Jan 2022 at 10:25, Stephen Boyd <sboyd at kernel.org> wrote:

> > +static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
> > +{
> > +       u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
> > +
> > +       iowrite16(l, cpupll->base + reg);
>
> We don't usually see 16-bit accesses but if that's what the hardware
> wants then OK.

This hardware is weird and most of the registers are like this where
they are 32bit spaced but only 16 bits are used in each.
32bit registers are split across 2 16 bit registers spaced 32bits
apart. Writing the two parts has to be in the right order to get the
right result.

> > +       iowrite16(h, cpupll->base + reg + 4);
> > +}
> > +
> > +static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
> > +{
> > +       msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
> > +
> > +       iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
> > +       iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
> > +       iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
> > +       iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
> > +
> > +       iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
> > +       iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
> > +
> > +       while (!(ioread16(cpupll->base + REG_LPF_LOCK)))
> > +               cpu_relax();
>
> Any timeout? Can this use the io read timeout APIs?

Good point. I never saw a situation where the lock didn't happen but I
think Willy did when he was poking at it.
I guess if it doesn't lock we should timeout, warn that something
isn't working and return an error.

> > +static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
> > +                                    unsigned long *parent_rate)
> > +{
> > +       u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
> > +       long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
> > +
> > +       /*
> > +        * This is my poor attempt at making sure the resulting
> > +        * rate doesn't overshoot the requested rate.
>
> If you want better bounds you can use determine_rate and then look at
> the min/max constraints to make sure you don't overshoot. But otherwise
> round_rate implementation is up to the provider to figure out what
> should happen, i.e. overshooting could be OK if the provider intends for
> it.

This clock is basically only used by cpufreq-dt. I'm not sure what it
would do with determine_rate. I'll take a look.
The main thing I wanted to do here was make sure the resulting clock
wasn't higher than what we have in the opp table and end up with the
CPU locking up.

> > +       clk_init.name = dev_name(dev);
> > +       clk_init.ops = &msc313_cpupll_ops;
> > +       clk_init.flags = CLK_IS_CRITICAL;
>
> Why is it critical? Can we have a comment? The clk ops don't have enable
> or disable so it seems like the flag won't do anything.

This clock is critical in the sense that once the DDR memory is setup
by the bootloader you must not turn it off even if you switch the CPU
to the other clock source. If you disable it the system locks up.
I think it can be dropped as does nothing without enable or disable
like you wrote.

Cheers,

Daniel


From maz at kernel.org  Sat Jan  8 04:51:23 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 12:51:23 +0000
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <20220107085536.214501-1-heying24@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
Message-ID: <87pmp2tmpg.wl-maz@kernel.org>

On Fri, 07 Jan 2022 08:55:36 +0000,
He Ying <heying24 at huawei.com> wrote:
> 
> Our product has been updating its kernel from 4.4 to 5.10 recently and
> found a performance issue. We do a bussiness test called ARP test, which
> tests the latency for a ping-pong packets traffic with a certain payload.
> The result is as following.
> 
>  - 4.4 kernel: avg = ~20s
>  - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s
> 
> I have been just learning arm64 pseudo-NMI code and have a question,
> why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
> I wonder if this brings some performance regression.
> 
> First, I make this patch and then do the test again. Here's the result.
> 
>  - 5.10 kernel with this patch not applied: avg = ~40s
>  - 5.10 kernel with this patch applied: avg = ~23s
> 
> Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
> set. It seems the pseudo-NMI feature actually brings some overhead to
> performance event if CONFIG_ARM64_PSEUDO_NMI is not set.
> 
> Furthermore, I find the feature also brings some overhead to vmlinux size.
> I build 5.10 kernel with this patch applied or not while
> CONFIG_ARM64_PSEUDO_NMI is not set.
> 
>  - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
>  - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
> 
> That means arm64 pseudo-NMI feature may bring ~200KB overhead to
> vmlinux size.
> 
> Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
> and performance even if config is not set. To avoid it, add macro control
> all around the related code.

This obviously attracted my attention, and I took this patch for a
ride on 5.16-rc8 on a machine that doesn't support GICv3 NMIs to make
sure that any extra code would only result in pure overhead.

There was no measurable difference with this patch applied or not,
with CONFIG_ARM64_PSEUDO_NMI selected or not for the workloads I tried
(I/O heavy virtual machines, hackbench).

Mark already asked a number of questions (test case, implementation,
test on a modern kernel). Please provide as many detail as you
possibly can, because such a regression really isn't expected, and
doesn't show up on the systems I have at hand. Some profiling numbers
could also be interesting, in case this is a result of a particular
resource being thrashed (TLB, cache...).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From chun-jie.chen at mediatek.com  Sat Jan  8 05:19:51 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sat, 8 Jan 2022 21:19:51 +0800
Subject: [v1 0/2] Mediatek MT8186 power domain support
Message-ID: <20220108131953.16744-1-chun-jie.chen@mediatek.com>

This patch series adds power domain support for MT8186.
It depends on [1]"Mediatek MT8195 power domain support"
and based on 5.16-rc6.

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=580579

Chun-Jie Chen (2):
  dt-bindings: power: Add MT8186 power domains
  soc: mediatek: pm-domains: Add support for mt8186

 .../power/mediatek,power-controller.yaml      |   1 +
 drivers/soc/mediatek/mt8186-pm-domains.h      | 344 ++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c         |   5 +
 include/dt-bindings/power/mt8186-power.h      |  32 ++
 include/linux/soc/mediatek/infracfg.h         |  48 +++
 5 files changed, 430 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8186-pm-domains.h
 create mode 100644 include/dt-bindings/power/mt8186-power.h

--
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan  8 05:19:52 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sat, 8 Jan 2022 21:19:52 +0800
Subject: [v1 1/2] dt-bindings: power: Add MT8186 power domains
In-Reply-To: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
References: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
Message-ID: <20220108131953.16744-2-chun-jie.chen@mediatek.com>

Add power domains dt-bindings for MT8186.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 .../power/mediatek,power-controller.yaml      |  1 +
 include/dt-bindings/power/mt8186-power.h      | 32 +++++++++++++++++++
 2 files changed, 33 insertions(+)
 create mode 100644 include/dt-bindings/power/mt8186-power.h

diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
index d6ebd77d28a7..135c6f722091 100644
--- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
@@ -26,6 +26,7 @@ properties:
       - mediatek,mt8167-power-controller
       - mediatek,mt8173-power-controller
       - mediatek,mt8183-power-controller
+      - mediatek,mt8186-power-controller
       - mediatek,mt8192-power-controller
       - mediatek,mt8195-power-controller
 
diff --git a/include/dt-bindings/power/mt8186-power.h b/include/dt-bindings/power/mt8186-power.h
new file mode 100644
index 000000000000..ca8ea2d24801
--- /dev/null
+++ b/include/dt-bindings/power/mt8186-power.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT8186_POWER_H
+#define _DT_BINDINGS_POWER_MT8186_POWER_H
+
+#define MT8186_POWER_DOMAIN_MFG0			0
+#define MT8186_POWER_DOMAIN_MFG1			1
+#define MT8186_POWER_DOMAIN_MFG2			2
+#define MT8186_POWER_DOMAIN_MFG3			3
+#define MT8186_POWER_DOMAIN_SSUSB			4
+#define MT8186_POWER_DOMAIN_SSUSB_P1			5
+#define MT8186_POWER_DOMAIN_DIS				6
+#define MT8186_POWER_DOMAIN_IMG				7
+#define MT8186_POWER_DOMAIN_IMG2			8
+#define MT8186_POWER_DOMAIN_IPE				9
+#define MT8186_POWER_DOMAIN_CAM				10
+#define MT8186_POWER_DOMAIN_CAM_RAWA			11
+#define MT8186_POWER_DOMAIN_CAM_RAWB			12
+#define MT8186_POWER_DOMAIN_VENC			13
+#define MT8186_POWER_DOMAIN_VDEC			14
+#define MT8186_POWER_DOMAIN_WPE				15
+#define MT8186_POWER_DOMAIN_CONN_ON			16
+#define MT8186_POWER_DOMAIN_CSIRX_TOP			17
+#define MT8186_POWER_DOMAIN_ADSP_AO			18
+#define MT8186_POWER_DOMAIN_ADSP_INFRA			19
+#define MT8186_POWER_DOMAIN_ADSP_TOP			20
+
+#endif /* _DT_BINDINGS_POWER_MT8186_POWER_H */
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan  8 05:19:53 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sat, 8 Jan 2022 21:19:53 +0800
Subject: [v1 2/2] soc: mediatek: pm-domains: Add support for mt8186
In-Reply-To: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
References: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
Message-ID: <20220108131953.16744-3-chun-jie.chen@mediatek.com>

Add power domain control data in mt8186.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/soc/mediatek/mt8186-pm-domains.h | 344 +++++++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c    |   5 +
 include/linux/soc/mediatek/infracfg.h    |  48 ++++
 3 files changed, 397 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8186-pm-domains.h

diff --git a/drivers/soc/mediatek/mt8186-pm-domains.h b/drivers/soc/mediatek/mt8186-pm-domains.h
new file mode 100644
index 000000000000..bf2dd0cdc3a8
--- /dev/null
+++ b/drivers/soc/mediatek/mt8186-pm-domains.h
@@ -0,0 +1,344 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef __SOC_MEDIATEK_MT8186_PM_DOMAINS_H
+#define __SOC_MEDIATEK_MT8186_PM_DOMAINS_H
+
+#include "mtk-pm-domains.h"
+#include <dt-bindings/power/mt8186-power.h>
+
+/*
+ * MT8186 power domain support
+ */
+
+static const struct scpsys_domain_data scpsys_domain_data_mt8186[] = {
+	[MT8186_POWER_DOMAIN_MFG0] = {
+		.name = "mfg0",
+		.sta_mask = BIT(2),
+		.ctl_offs = 0x308,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
+	},
+	[MT8186_POWER_DOMAIN_MFG1] = {
+		.name = "mfg1",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x30c,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP2,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_MFG1_STEP3,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_MFG2] = {
+		.name = "mfg2",
+		.sta_mask = BIT(4),
+		.ctl_offs = 0x310,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_MFG3] = {
+		.name = "mfg3",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x314,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_SSUSB] = {
+		.name = "ssusb",
+		.sta_mask = BIT(20),
+		.ctl_offs = 0x9F0,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8186_POWER_DOMAIN_SSUSB_P1] = {
+		.name = "ssusb_p1",
+		.sta_mask = BIT(19),
+		.ctl_offs = 0x9F4,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8186_POWER_DOMAIN_DIS] = {
+		.name = "dis",
+		.sta_mask = BIT(21),
+		.ctl_offs = 0x354,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_DIS_STEP2,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+		},
+	},
+	[MT8186_POWER_DOMAIN_IMG] = {
+		.name = "img",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x334,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_IMG2] = {
+		.name = "img2",
+		.sta_mask = BIT(14),
+		.ctl_offs = 0x338,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_IPE] = {
+		.name = "ipe",
+		.sta_mask = BIT(15),
+		.ctl_offs = 0x33C,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_CAM] = {
+		.name = "cam",
+		.sta_mask = BIT(23),
+		.ctl_offs = 0x35C,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_CAM_RAWA] = {
+		.name = "cam_rawa",
+		.sta_mask = BIT(24),
+		.ctl_offs = 0x360,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_CAM_RAWB] = {
+		.name = "cam_rawb",
+		.sta_mask = BIT(25),
+		.ctl_offs = 0x364,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_VENC] = {
+		.name = "venc",
+		.sta_mask = BIT(18),
+		.ctl_offs = 0x348,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_VDEC] = {
+		.name = "vdec",
+		.sta_mask = BIT(16),
+		.ctl_offs = 0x340,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_WPE] = {
+		.name = "wpe",
+		.sta_mask = BIT(0),
+		.ctl_offs = 0x3F8,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1,
+				MT8186_TOP_AXI_PROT_EN_2_SET,
+				MT8186_TOP_AXI_PROT_EN_2_CLR,
+				MT8186_TOP_AXI_PROT_EN_2_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2,
+				MT8186_TOP_AXI_PROT_EN_2_SET,
+				MT8186_TOP_AXI_PROT_EN_2_CLR,
+				MT8186_TOP_AXI_PROT_EN_2_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_CONN_ON] = {
+		.name = "conn_on",
+		.sta_mask = BIT(1),
+		.ctl_offs = 0x304,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1,
+				MT8186_TOP_AXI_PROT_EN_1_SET,
+				MT8186_TOP_AXI_PROT_EN_1_CLR,
+				MT8186_TOP_AXI_PROT_EN_1_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4,
+				MT8186_TOP_AXI_PROT_EN_SET,
+				MT8186_TOP_AXI_PROT_EN_CLR,
+				MT8186_TOP_AXI_PROT_EN_STA),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8186_POWER_DOMAIN_CSIRX_TOP] = {
+		.name = "csirx_top",
+		.sta_mask = BIT(6),
+		.ctl_offs = 0x318,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_ADSP_AO] = {
+		.name = "adsp_ao",
+		.sta_mask = BIT(17),
+		.ctl_offs = 0x9FC,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_ADSP_INFRA] = {
+		.name = "adsp_infra",
+		.sta_mask = BIT(10),
+		.ctl_offs = 0x9F8,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8186_POWER_DOMAIN_ADSP_TOP] = {
+		.name = "adsp_top",
+		.sta_mask = BIT(31),
+		.ctl_offs = 0x3E4,
+		.pwr_sta_offs = 0x16C,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = BIT(8),
+		.sram_pdn_ack_bits = BIT(12),
+		.bp_infracfg = {
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1,
+				MT8186_TOP_AXI_PROT_EN_3_SET,
+				MT8186_TOP_AXI_PROT_EN_3_CLR,
+				MT8186_TOP_AXI_PROT_EN_3_STA),
+			BUS_PROT_WR_IGN(MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2,
+				MT8186_TOP_AXI_PROT_EN_3_SET,
+				MT8186_TOP_AXI_PROT_EN_3_CLR,
+				MT8186_TOP_AXI_PROT_EN_3_STA),
+		},
+		.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+};
+
+static const struct scpsys_soc_data mt8186_scpsys_data = {
+	.domains_data = scpsys_domain_data_mt8186,
+	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8186),
+};
+
+#endif /* __SOC_MEDIATEK_MT8186_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index 61973a306e97..5ced254b082b 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -19,6 +19,7 @@
 #include "mt8167-pm-domains.h"
 #include "mt8173-pm-domains.h"
 #include "mt8183-pm-domains.h"
+#include "mt8186-pm-domains.h"
 #include "mt8192-pm-domains.h"
 #include "mt8195-pm-domains.h"
 
@@ -566,6 +567,10 @@ static const struct of_device_id scpsys_of_match[] = {
 		.compatible = "mediatek,mt8183-power-controller",
 		.data = &mt8183_scpsys_data,
 	},
+	{
+		.compatible = "mediatek,mt8186-power-controller",
+		.data = &mt8186_scpsys_data,
+	},
 	{
 		.compatible = "mediatek,mt8192-power-controller",
 		.data = &mt8192_scpsys_data,
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index d858e0bab7a2..8a1c2040a28e 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -140,6 +140,54 @@
 #define MT8192_TOP_AXI_PROT_EN_MM_2_MDP_2ND		BIT(13)
 #define MT8192_TOP_AXI_PROT_EN_VDNR_CAM			BIT(21)
 
+#define MT8186_TOP_AXI_PROT_EN_SET			(0x2A0)
+#define MT8186_TOP_AXI_PROT_EN_CLR			(0x2A4)
+#define MT8186_TOP_AXI_PROT_EN_STA			(0x228)
+#define MT8186_TOP_AXI_PROT_EN_1_SET			(0x2A8)
+#define MT8186_TOP_AXI_PROT_EN_1_CLR			(0x2AC)
+#define MT8186_TOP_AXI_PROT_EN_1_STA			(0x258)
+#define MT8186_TOP_AXI_PROT_EN_2_SET			(0x2B0)
+#define MT8186_TOP_AXI_PROT_EN_2_CLR			(0x2B4)
+#define MT8186_TOP_AXI_PROT_EN_2_STA			(0x26C)
+#define MT8186_TOP_AXI_PROT_EN_3_SET			(0x2B8)
+#define MT8186_TOP_AXI_PROT_EN_3_CLR			(0x2BC)
+#define MT8186_TOP_AXI_PROT_EN_3_STA			(0x2C8)
+
+/* MFG1 */
+#define MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP1		(GENMASK(28, 27))
+#define MT8186_TOP_AXI_PROT_EN_MFG1_STEP2		(GENMASK(22, 21))
+#define MT8186_TOP_AXI_PROT_EN_MFG1_STEP3		(BIT(25))
+#define MT8186_TOP_AXI_PROT_EN_1_MFG1_STEP4		(BIT(29))
+/* DIS */
+#define MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1		(GENMASK(12, 11))
+#define MT8186_TOP_AXI_PROT_EN_DIS_STEP2		(GENMASK(2, 1) | GENMASK(11, 10))
+/* IMG */
+#define MT8186_TOP_AXI_PROT_EN_1_IMG_STEP1		(BIT(23))
+#define MT8186_TOP_AXI_PROT_EN_1_IMG_STEP2		(BIT(15))
+/* IPE */
+#define MT8186_TOP_AXI_PROT_EN_1_IPE_STEP1		(BIT(24))
+#define MT8186_TOP_AXI_PROT_EN_1_IPE_STEP2		(BIT(16))
+/* CAM */
+#define MT8186_TOP_AXI_PROT_EN_1_CAM_STEP1		(GENMASK(22, 21))
+#define MT8186_TOP_AXI_PROT_EN_1_CAM_STEP2		(GENMASK(14, 13))
+/* VENC */
+#define MT8186_TOP_AXI_PROT_EN_1_VENC_STEP1		(BIT(31))
+#define MT8186_TOP_AXI_PROT_EN_1_VENC_STEP2		(BIT(19))
+/* VDEC */
+#define MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP1		(BIT(30))
+#define MT8186_TOP_AXI_PROT_EN_1_VDEC_STEP2		(BIT(17))
+/* WPE */
+#define MT8186_TOP_AXI_PROT_EN_2_WPE_STEP1		(BIT(17))
+#define MT8186_TOP_AXI_PROT_EN_2_WPE_STEP2		(BIT(16))
+/* CONN_ON */
+#define MT8186_TOP_AXI_PROT_EN_1_CONN_ON_STEP1		(BIT(18))
+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP2		(BIT(14))
+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP3		(BIT(13))
+#define MT8186_TOP_AXI_PROT_EN_CONN_ON_STEP4		(BIT(16))
+/* ADSP_TOP */
+#define MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP1		(GENMASK(12, 11))
+#define MT8186_TOP_AXI_PROT_EN_3_ADSP_TOP_STEP2		(GENMASK(1, 0))
+
 #define MT8183_TOP_AXI_PROT_EN_STA1			0x228
 #define MT8183_TOP_AXI_PROT_EN_STA1_1			0x258
 #define MT8183_TOP_AXI_PROT_EN_SET			0x2a0
-- 
2.18.0



From maz at kernel.org  Sat Jan  8 05:27:17 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 08 Jan 2022 13:27:17 +0000
Subject: [PATCH kvmtool 9/9] arm64: Add support for
 KVM_ARM_VCPU_PMU_V3_SET_PMU
In-Reply-To: <YdgtnQPAsy1hSOWj@monolith.localdoman>
References: <20211115165705.195736-1-alexandru.elisei@arm.com>
 <20211115165705.195736-10-alexandru.elisei@arm.com>
 <87h7ajva2o.wl-maz@kernel.org>
 <YdgtnQPAsy1hSOWj@monolith.localdoman>
Message-ID: <87o84mtl1m.wl-maz@kernel.org>

On Fri, 07 Jan 2022 12:10:05 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Tue, Jan 04, 2022 at 02:39:59PM +0000, Marc Zyngier wrote:
> > On Mon, 15 Nov 2021 16:57:05 +0000,
> > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > 
> > > The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is
> > > used to assign a physical PMU to the events that KVM creates when emulating
> > > the PMU for that VCPU. This is useful on heterogeneous systems, when there
> > > is more than one hardware PMU present.
> > > 
> > > The assumption that is made in the implementation is that the user will
> > > pin the kvmtool process on a set of CPUs that share the same PMU. This
> > > allows kvmtool to set the same PMU for all VCPUs from the main thread,
> > > instead of in the individual VCPU threads.
> > 
> > May I suggest a slightly different use model? Ideally, you'd be able
> > to run the vcpu threads on the CPUs matching the PMU affinity, and
> > leave all the other threads to roam on other CPUs.
> 
> Right now, the only way for userspace to make kvmtool run on a particular
> set of CPUs in a heterogeneous configuration is to use taskset, which means
> the entire kvmtool process ends up being pinned on a subset of CPUs which
> have the same PMU. I would like to keep this approach, as it's simple and
> straightforward to implement in kvmtool, and it's easy to change in the
> future if there's an incentive to do so.
> 
> It's also not clear to me how your suggestion would work. Add a command
> line argument to pin all the VCPUs to the specified cpumask?
> 
> > 
> > With your implementation, the whole of kvmtool gets stuck to a given
> > CPU type, which can be problematic.
> 
> Do you have a specific use case in mind? Or is it more like a general
> concern regarding, for example, the virtio-blk-io or virtio-net-* threads
> competing with the VCPU threads if the VM is doing lots of I/O?

Exactly that. The real requirement is that the vcpu thread affinities
are that of the PMU, but not that of any other thread. Maybe that's
just another parameter, independent of the PMU setup. Something like:

	lkvm run ... --vcpu-affinity $(< /sys/devices/armv8_pmuv3_0/cpus)

for example.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From trix at redhat.com  Sat Jan  8 07:50:03 2022
From: trix at redhat.com (trix at redhat.com)
Date: Sat,  8 Jan 2022 07:50:03 -0800
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix error checking in
 mtk_mac_config()
Message-ID: <20220108155003.3991055-1-trix@redhat.com>

From: Tom Rix <trix at redhat.com>

Clang static analysis reports this problem
mtk_eth_soc.c:394:7: warning: Branch condition evaluates
  to a garbage value
                if (err)
                    ^~~

err is not initialized and only conditionally set.
Check err consistently with the rest of mtk_mac_config(),
after even possible setting.

Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
Signed-off-by: Tom Rix <trix at redhat.com>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index b67b4323cff08..a27e548488584 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -385,14 +385,16 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 		       0 : mac->id;
 
 		/* Setup SGMIISYS with the determined property */
-		if (state->interface != PHY_INTERFACE_MODE_SGMII)
+		if (state->interface != PHY_INTERFACE_MODE_SGMII) {
 			err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
 							 state);
-		else if (phylink_autoneg_inband(mode))
+			if (err)
+				goto init_err;
+		} else if (phylink_autoneg_inband(mode)) {
 			err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
-
-		if (err)
-			goto init_err;
+			if (err)
+				goto init_err;
+		}
 
 		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
 				   SYSCFG0_SGMII_MASK, val);
-- 
2.26.3



From alexandru.elisei at arm.com  Sat Jan  8 08:03:36 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Sat, 8 Jan 2022 16:03:36 +0000
Subject: [PATCH kvmtool 9/9] arm64: Add support for
 KVM_ARM_VCPU_PMU_V3_SET_PMU
In-Reply-To: <87o84mtl1m.wl-maz@kernel.org>
References: <20211115165705.195736-1-alexandru.elisei@arm.com>
 <20211115165705.195736-10-alexandru.elisei@arm.com>
 <87h7ajva2o.wl-maz@kernel.org>
 <YdgtnQPAsy1hSOWj@monolith.localdoman>
 <87o84mtl1m.wl-maz@kernel.org>
Message-ID: <Ydm12K8O/9SNO3ht@monolith.localdoman>

Hi Marc,

On Sat, Jan 08, 2022 at 01:27:17PM +0000, Marc Zyngier wrote:
> On Fri, 07 Jan 2022 12:10:05 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > Hi Marc,
> > 
> > On Tue, Jan 04, 2022 at 02:39:59PM +0000, Marc Zyngier wrote:
> > > On Mon, 15 Nov 2021 16:57:05 +0000,
> > > Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > > > 
> > > > The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is
> > > > used to assign a physical PMU to the events that KVM creates when emulating
> > > > the PMU for that VCPU. This is useful on heterogeneous systems, when there
> > > > is more than one hardware PMU present.
> > > > 
> > > > The assumption that is made in the implementation is that the user will
> > > > pin the kvmtool process on a set of CPUs that share the same PMU. This
> > > > allows kvmtool to set the same PMU for all VCPUs from the main thread,
> > > > instead of in the individual VCPU threads.
> > > 
> > > May I suggest a slightly different use model? Ideally, you'd be able
> > > to run the vcpu threads on the CPUs matching the PMU affinity, and
> > > leave all the other threads to roam on other CPUs.
> > 
> > Right now, the only way for userspace to make kvmtool run on a particular
> > set of CPUs in a heterogeneous configuration is to use taskset, which means
> > the entire kvmtool process ends up being pinned on a subset of CPUs which
> > have the same PMU. I would like to keep this approach, as it's simple and
> > straightforward to implement in kvmtool, and it's easy to change in the
> > future if there's an incentive to do so.
> > 
> > It's also not clear to me how your suggestion would work. Add a command
> > line argument to pin all the VCPUs to the specified cpumask?
> > 
> > > 
> > > With your implementation, the whole of kvmtool gets stuck to a given
> > > CPU type, which can be problematic.
> > 
> > Do you have a specific use case in mind? Or is it more like a general
> > concern regarding, for example, the virtio-blk-io or virtio-net-* threads
> > competing with the VCPU threads if the VM is doing lots of I/O?
> 
> Exactly that. The real requirement is that the vcpu thread affinities
> are that of the PMU, but not that of any other thread. Maybe that's
> just another parameter, independent of the PMU setup. Something like:
> 
> 	lkvm run ... --vcpu-affinity $(< /sys/devices/armv8_pmuv3_0/cpus)
> 
> for example.

That should be easy (famous last words?) to implement as a separate patch
on top of this series, I'll give that a go in the next iteration.

Thanks for the suggestion.

Alex


From luto at kernel.org  Sat Jan  8 08:43:52 2022
From: luto at kernel.org (Andy Lutomirski)
Date: Sat,  8 Jan 2022 08:43:52 -0800
Subject: [PATCH 07/23] membarrier: Rewrite sync_core_before_usermode() and
 improve documentation
In-Reply-To: <cover.1641659630.git.luto@kernel.org>
References: <cover.1641659630.git.luto@kernel.org>
Message-ID: <d2f76c148fa039d2dea404c03e5fcd2f3dbf3750.1641659630.git.luto@kernel.org>

The old sync_core_before_usermode() comments suggested that a
non-icache-syncing return-to-usermode instruction is x86-specific and that
all other architectures automatically notice cross-modified code on return
to userspace.

This is misleading.  The incantation needed to modify code from one
CPU and execute it on another CPU is highly architecture dependent.
On x86, according to the SDM, one must modify the code, issue SFENCE
if the modification was WC or nontemporal, and then issue a "serializing
instruction" on the CPU that will execute the code.  membarrier() can do
the latter.

On arm, arm64 and powerpc, one must flush the icache and then flush the
pipeline on the target CPU, although the CPU manuals don't necessarily use
this language.

So let's drop any pretense that we can have a generic way to define or
implement membarrier's SYNC_CORE operation and instead require all
architectures to define the helper and supply their own documentation as to
how to use it.  This means x86, arm64, and powerpc for now.  Let's also
rename the function from sync_core_before_usermode() to
membarrier_sync_core_before_usermode() because the precise flushing details
may very well be specific to membarrier, and even the concept of
"sync_core" in the kernel is mostly an x86-ism.

(It may well be the case that, on real x86 processors, synchronizing the
 icache (which requires no action at all) and "flushing the pipeline" is
 sufficient, but trying to use this language would be confusing at best.
 LFENCE does something awfully like "flushing the pipeline", but the SDM
 does not permit LFENCE as an alternative to a "serializing instruction"
 for this purpose.)

Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: linuxppc-dev at lists.ozlabs.org
Cc: Nicholas Piggin <npiggin at gmail.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Cc: Nicholas Piggin <npiggin at gmail.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: x86 at kernel.org
Cc: stable at vger.kernel.org
Acked-by: Will Deacon <will at kernel.org> # for arm64
Fixes: 70216e18e519 ("membarrier: Provide core serializing command, *_SYNC_CORE")
Signed-off-by: Andy Lutomirski <luto at kernel.org>
---
 .../membarrier-sync-core/arch-support.txt     | 69 ++++++-------------
 arch/arm/include/asm/membarrier.h             | 21 ++++++
 arch/arm64/include/asm/membarrier.h           | 19 +++++
 arch/powerpc/include/asm/membarrier.h         | 10 +++
 arch/x86/Kconfig                              |  1 -
 arch/x86/include/asm/membarrier.h             | 25 +++++++
 arch/x86/include/asm/sync_core.h              | 20 ------
 arch/x86/kernel/alternative.c                 |  2 +-
 arch/x86/kernel/cpu/mce/core.c                |  2 +-
 arch/x86/mm/tlb.c                             |  3 +-
 drivers/misc/sgi-gru/grufault.c               |  2 +-
 drivers/misc/sgi-gru/gruhandles.c             |  2 +-
 drivers/misc/sgi-gru/grukservices.c           |  2 +-
 include/linux/sched/mm.h                      |  1 -
 include/linux/sync_core.h                     | 21 ------
 init/Kconfig                                  |  3 -
 kernel/sched/membarrier.c                     | 14 +++-
 17 files changed, 115 insertions(+), 102 deletions(-)
 create mode 100644 arch/arm/include/asm/membarrier.h
 create mode 100644 arch/arm64/include/asm/membarrier.h
 create mode 100644 arch/x86/include/asm/membarrier.h
 delete mode 100644 include/linux/sync_core.h

diff --git a/Documentation/features/sched/membarrier-sync-core/arch-support.txt b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
index 883d33b265d6..4009b26bf5c3 100644
--- a/Documentation/features/sched/membarrier-sync-core/arch-support.txt
+++ b/Documentation/features/sched/membarrier-sync-core/arch-support.txt
@@ -5,51 +5,26 @@
 #
 # Architecture requirements
 #
-# * arm/arm64/powerpc
 #
-# Rely on implicit context synchronization as a result of exception return
-# when returning from IPI handler, and when returning to user-space.
-#
-# * x86
-#
-# x86-32 uses IRET as return from interrupt, which takes care of the IPI.
-# However, it uses both IRET and SYSEXIT to go back to user-space. The IRET
-# instruction is core serializing, but not SYSEXIT.
-#
-# x86-64 uses IRET as return from interrupt, which takes care of the IPI.
-# However, it can return to user-space through either SYSRETL (compat code),
-# SYSRETQ, or IRET.
-#
-# Given that neither SYSRET{L,Q}, nor SYSEXIT, are core serializing, we rely
-# instead on write_cr3() performed by switch_mm() to provide core serialization
-# after changing the current mm, and deal with the special case of kthread ->
-# uthread (temporarily keeping current mm into active_mm) by issuing a
-# sync_core_before_usermode() in that specific case.
-#
-    -----------------------
-    |         arch |status|
-    -----------------------
-    |       alpha: | TODO |
-    |         arc: | TODO |
-    |         arm: |  ok  |
-    |       arm64: |  ok  |
-    |        csky: | TODO |
-    |       h8300: | TODO |
-    |     hexagon: | TODO |
-    |        ia64: | TODO |
-    |        m68k: | TODO |
-    |  microblaze: | TODO |
-    |        mips: | TODO |
-    |       nds32: | TODO |
-    |       nios2: | TODO |
-    |    openrisc: | TODO |
-    |      parisc: | TODO |
-    |     powerpc: |  ok  |
-    |       riscv: | TODO |
-    |        s390: | TODO |
-    |          sh: | TODO |
-    |       sparc: | TODO |
-    |          um: | TODO |
-    |         x86: |  ok  |
-    |      xtensa: | TODO |
-    -----------------------
+# An architecture that wants to support
+# MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE needs to define precisely what it
+# is supposed to do and implement membarrier_sync_core_before_usermode() to
+# make it do that.  Then it can select ARCH_HAS_MEMBARRIER_SYNC_CORE via
+# Kconfig and document what SYNC_CORE does on that architecture in this
+# list.
+#
+# On x86, a program can safely modify code, issue
+# MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, and then execute that code, via
+# the modified address or an alias, from any thread in the calling process.
+#
+# On arm and arm64, a program can modify code, flush the icache as needed,
+# and issue MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE to force a "context
+# synchronizing event", aka pipeline flush on all CPUs that might run the
+# calling process.  Then the program can execute the modified code as long
+# as it is executed from an address consistent with the icache flush and
+# the CPU's cache type.  On arm, cacheflush(2) can be used for the icache
+# flushing operation.
+#
+# On powerpc, a program can use MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE
+# similarly to arm64.  It would be nice if the powerpc maintainers could
+# add a more clear explanantion.
diff --git a/arch/arm/include/asm/membarrier.h b/arch/arm/include/asm/membarrier.h
new file mode 100644
index 000000000000..c162a0758657
--- /dev/null
+++ b/arch/arm/include/asm/membarrier.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM_MEMBARRIER_H
+#define _ASM_ARM_MEMBARRIER_H
+
+#include <asm/barrier.h>
+
+/*
+ * On arm, anyone trying to use membarrier() to handle JIT code is required
+ * to first flush the icache (most likely by using cacheflush(2) and then
+ * do SYNC_CORE.  All that's needed after the icache flush is to execute a
+ * "context synchronization event".
+ *
+ * Returning to user mode is a context synchronization event, so no
+ * specific action by the kernel is needed other than ensuring that the
+ * kernel is entered.
+ */
+static inline void membarrier_sync_core_before_usermode(void)
+{
+}
+
+#endif /* _ASM_ARM_MEMBARRIER_H */
diff --git a/arch/arm64/include/asm/membarrier.h b/arch/arm64/include/asm/membarrier.h
new file mode 100644
index 000000000000..db8e0ea57253
--- /dev/null
+++ b/arch/arm64/include/asm/membarrier.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARM64_MEMBARRIER_H
+#define _ASM_ARM64_MEMBARRIER_H
+
+#include <asm/barrier.h>
+
+/*
+ * On arm64, anyone trying to use membarrier() to handle JIT code is
+ * required to first flush the icache and then do SYNC_CORE.  All that's
+ * needed after the icache flush is to execute a "context synchronization
+ * event".  Right now, ERET does this, and we are guaranteed to ERET before
+ * any user code runs.  If Linux ever programs the CPU to make ERET stop
+ * being a context synchronizing event, then this will need to be adjusted.
+ */
+static inline void membarrier_sync_core_before_usermode(void)
+{
+}
+
+#endif /* _ASM_ARM64_MEMBARRIER_H */
diff --git a/arch/powerpc/include/asm/membarrier.h b/arch/powerpc/include/asm/membarrier.h
index b90766e95bd1..466abe6fdcea 100644
--- a/arch/powerpc/include/asm/membarrier.h
+++ b/arch/powerpc/include/asm/membarrier.h
@@ -1,4 +1,14 @@
 #ifndef _ASM_POWERPC_MEMBARRIER_H
 #define _ASM_POWERPC_MEMBARRIER_H
 
+#include <asm/barrier.h>
+
+/*
+ * The RFI family of instructions are context synchronising, and
+ * that is how we return to userspace, so nothing is required here.
+ */
+static inline void membarrier_sync_core_before_usermode(void)
+{
+}
+
 #endif /* _ASM_POWERPC_MEMBARRIER_H */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index d9830e7e1060..5060c38bf560 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -90,7 +90,6 @@ config X86
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
-	select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
 	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_UBSAN_SANITIZE_ALL
 	select ARCH_HAS_DEBUG_WX
diff --git a/arch/x86/include/asm/membarrier.h b/arch/x86/include/asm/membarrier.h
new file mode 100644
index 000000000000..9b72a1b49359
--- /dev/null
+++ b/arch/x86/include/asm/membarrier.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_X86_MEMBARRIER_H
+#define _ASM_X86_MEMBARRIER_H
+
+#include <asm/sync_core.h>
+
+/*
+ * Ensure that the CPU notices any instruction changes before the next time
+ * it returns to usermode.
+ */
+static inline void membarrier_sync_core_before_usermode(void)
+{
+	/* With PTI, we unconditionally serialize before running user code. */
+	if (static_cpu_has(X86_FEATURE_PTI))
+		return;
+
+	/*
+	 * Even if we're in an interrupt, we might reschedule before returning,
+	 * in which case we could switch to a different thread in the same mm
+	 * and return using SYSRET or SYSEXIT.  Instead of trying to keep
+	 * track of our need to sync the core, just sync right away.
+	 */
+	sync_core();
+}
+
+#endif /* _ASM_X86_MEMBARRIER_H */
diff --git a/arch/x86/include/asm/sync_core.h b/arch/x86/include/asm/sync_core.h
index ab7382f92aff..bfe4ac4e6be2 100644
--- a/arch/x86/include/asm/sync_core.h
+++ b/arch/x86/include/asm/sync_core.h
@@ -88,24 +88,4 @@ static inline void sync_core(void)
 	iret_to_self();
 }
 
-/*
- * Ensure that a core serializing instruction is issued before returning
- * to user-mode. x86 implements return to user-space through sysexit,
- * sysrel, and sysretq, which are not core serializing.
- */
-static inline void sync_core_before_usermode(void)
-{
-	/* With PTI, we unconditionally serialize before running user code. */
-	if (static_cpu_has(X86_FEATURE_PTI))
-		return;
-
-	/*
-	 * Even if we're in an interrupt, we might reschedule before returning,
-	 * in which case we could switch to a different thread in the same mm
-	 * and return using SYSRET or SYSEXIT.  Instead of trying to keep
-	 * track of our need to sync the core, just sync right away.
-	 */
-	sync_core();
-}
-
 #endif /* _ASM_X86_SYNC_CORE_H */
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index e9da3dc71254..b47cd22b2eb1 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -17,7 +17,7 @@
 #include <linux/kprobes.h>
 #include <linux/mmu_context.h>
 #include <linux/bsearch.h>
-#include <linux/sync_core.h>
+#include <asm/sync_core.h>
 #include <asm/text-patching.h>
 #include <asm/alternative.h>
 #include <asm/sections.h>
diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
index 193204aee880..a2529e09f620 100644
--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -41,12 +41,12 @@
 #include <linux/irq_work.h>
 #include <linux/export.h>
 #include <linux/set_memory.h>
-#include <linux/sync_core.h>
 #include <linux/task_work.h>
 #include <linux/hardirq.h>
 
 #include <asm/intel-family.h>
 #include <asm/processor.h>
+#include <asm/sync_core.h>
 #include <asm/traps.h>
 #include <asm/tlbflush.h>
 #include <asm/mce.h>
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 1ae15172885e..74b7a615bc15 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -12,6 +12,7 @@
 #include <linux/sched/mm.h>
 
 #include <asm/tlbflush.h>
+#include <asm/membarrier.h>
 #include <asm/mmu_context.h>
 #include <asm/nospec-branch.h>
 #include <asm/cache.h>
@@ -491,7 +492,7 @@ static void sync_core_if_membarrier_enabled(struct mm_struct *next)
 #ifdef CONFIG_MEMBARRIER
 	if (unlikely(atomic_read(&next->membarrier_state) &
 		     MEMBARRIER_STATE_PRIVATE_EXPEDITED_SYNC_CORE))
-		sync_core_before_usermode();
+		membarrier_sync_core_before_usermode();
 #endif
 }
 
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index d7ef61e602ed..462c667bd6c4 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -20,8 +20,8 @@
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/security.h>
-#include <linux/sync_core.h>
 #include <linux/prefetch.h>
+#include <asm/sync_core.h>
 #include "gru.h"
 #include "grutables.h"
 #include "grulib.h"
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
index 1d75d5e540bc..c8cba1c1b00f 100644
--- a/drivers/misc/sgi-gru/gruhandles.c
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -16,7 +16,7 @@
 #define GRU_OPERATION_TIMEOUT	(((cycles_t) local_cpu_data->itc_freq)*10)
 #define CLKS2NSEC(c)		((c) *1000000000 / local_cpu_data->itc_freq)
 #else
-#include <linux/sync_core.h>
+#include <asm/sync_core.h>
 #include <asm/tsc.h>
 #define GRU_OPERATION_TIMEOUT	((cycles_t) tsc_khz*10*1000)
 #define CLKS2NSEC(c)		((c) * 1000000 / tsc_khz)
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 0ea923fe6371..ce03ff3f7c3a 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -16,10 +16,10 @@
 #include <linux/miscdevice.h>
 #include <linux/proc_fs.h>
 #include <linux/interrupt.h>
-#include <linux/sync_core.h>
 #include <linux/uaccess.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <asm/sync_core.h>
 #include <asm/io_apic.h>
 #include "gru.h"
 #include "grulib.h"
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index e8919995d8dd..e107f292fc42 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -7,7 +7,6 @@
 #include <linux/sched.h>
 #include <linux/mm_types.h>
 #include <linux/gfp.h>
-#include <linux/sync_core.h>
 
 /*
  * Routines for handling mm_structs
diff --git a/include/linux/sync_core.h b/include/linux/sync_core.h
deleted file mode 100644
index 013da4b8b327..000000000000
--- a/include/linux/sync_core.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _LINUX_SYNC_CORE_H
-#define _LINUX_SYNC_CORE_H
-
-#ifdef CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
-#include <asm/sync_core.h>
-#else
-/*
- * This is a dummy sync_core_before_usermode() implementation that can be used
- * on all architectures which return to user-space through core serializing
- * instructions.
- * If your architecture returns to user-space through non-core-serializing
- * instructions, you need to write your own functions.
- */
-static inline void sync_core_before_usermode(void)
-{
-}
-#endif
-
-#endif /* _LINUX_SYNC_CORE_H */
-
diff --git a/init/Kconfig b/init/Kconfig
index 11f8a845f259..bbaf93f9438b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -2364,9 +2364,6 @@ source "kernel/Kconfig.locks"
 config ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	bool
 
-config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
-	bool
-
 # It may be useful for an architecture to override the definitions of the
 # SYSCALL_DEFINE() and __SYSCALL_DEFINEx() macros in <linux/syscalls.h>
 # and the COMPAT_ variants in <linux/compat.h>, in particular to use a
diff --git a/kernel/sched/membarrier.c b/kernel/sched/membarrier.c
index 327830f89c37..eb73eeaedc7d 100644
--- a/kernel/sched/membarrier.c
+++ b/kernel/sched/membarrier.c
@@ -5,6 +5,14 @@
  * membarrier system call
  */
 #include "sched.h"
+#ifdef CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE
+#include <asm/membarrier.h>
+#else
+static inline void membarrier_sync_core_before_usermode(void)
+{
+	compiletime_assert(0, "architecture does not implement membarrier_sync_core_before_usermode");
+}
+#endif
 
 /*
  * The basic principle behind the regular memory barrier mode of
@@ -231,12 +239,12 @@ static void ipi_sync_core(void *info)
 	 * the big comment at the top of this file.
 	 *
 	 * A sync_core() would provide this guarantee, but
-	 * sync_core_before_usermode() might end up being deferred until
-	 * after membarrier()'s smp_mb().
+	 * membarrier_sync_core_before_usermode() might end up being deferred
+	 * until after membarrier()'s smp_mb().
 	 */
 	smp_mb();	/* IPIs should be serializing but paranoid. */
 
-	sync_core_before_usermode();
+	membarrier_sync_core_before_usermode();
 }
 
 static void ipi_rseq(void *info)
-- 
2.33.1



From jose.exposito89 at gmail.com  Sat Jan  8 08:52:30 2022
From: jose.exposito89 at gmail.com (=?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?=)
Date: Sat,  8 Jan 2022 17:52:30 +0100
Subject: [PATCH v2] drm/imx: Fix memory leak in imx_pd_connector_get_modes
Message-ID: <20220108165230.44610-1-jose.exposito89@gmail.com>

Avoid leaking the display mode variable if of_get_drm_display_mode
fails.

Fixes: 76ecd9c9fb24 ("drm/imx: parallel-display: check return code from of_get_drm_display_mode()")
Addresses-Coverity-ID: 1443943 ("Resource leak")
Signed-off-by: Jos? Exp?sito <jose.exposito89 at gmail.com>

---

v2: Improve commit message
---
 drivers/gpu/drm/imx/parallel-display.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index a8aba0141ce7..3bf8e0a4803a 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -75,8 +75,10 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
 		ret = of_get_drm_display_mode(np, &imxpd->mode,
 					      &imxpd->bus_flags,
 					      OF_USE_NATIVE_MODE);
-		if (ret)
+		if (ret) {
+			drm_mode_destroy(connector->dev, mode);
 			return ret;
+		}
 
 		drm_mode_copy(mode, &imxpd->mode);
 		mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-- 
2.25.1



From olof at lixom.net  Sat Jan  8 12:20:11 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 12:20:11 -0800
Subject: [GIT PULL] SoC: Fixes for 5.16, part 4
Message-ID: <20220108202011.GA1760@lx2k>

Hi Linus,

The following changes since commit fc74e0a40e4f9fd0468e34045b0c45bba11dcbb2:

  Linux 5.16-rc7 (2021-12-26 13:17:17 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.16-4

for you to fetch changes up to 8922bb6526ac4b20bd8de7f47d6e77808670f6c4:

  Merge tag 'socfpga_fix_for_v5.16_part_3' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux into arm/fixes (2022-01-05 16:18:50 -0800)

----------------------------------------------------------------
SoC; Fixes for 5.16, part 4

A few more fixes have come in, nothing overly severe but would be good
to get in by final release:

 - More specific compatible fields on the qspi controller for socfpga,
 to enable quirks in the driver.
 - A runtime PM fix for Renesas to fix mismatched reference counts on
 errors.

----------------------------------------------------------------
Dinh Nguyen (2):
      dt-bindings: spi: cadence-quadspi: document "intel,socfpga-qspi"
      ARM: dts: socfpga: change qspi to "intel,socfpga-qspi"

Heiner Kallweit (1):
      reset: renesas: Fix Runtime PM usage

Olof Johansson (2):
      Merge tag 'reset-fixes-for-v5.16-2' of git://git.pengutronix.de/pza/linux into arm/fixes
      Merge tag 'socfpga_fix_for_v5.16_part_3' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux into arm/fixes

 Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml | 1 +
 arch/arm/boot/dts/socfpga.dtsi                           | 2 +-
 arch/arm/boot/dts/socfpga_arria10.dtsi                   | 2 +-
 arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi        | 2 +-
 arch/arm64/boot/dts/intel/socfpga_agilex.dtsi            | 2 +-
 drivers/reset/reset-rzg2l-usbphy-ctrl.c                  | 7 ++++++-
 6 files changed, 11 insertions(+), 5 deletions(-)


From olof at lixom.net  Sat Jan  8 12:24:10 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 12:24:10 -0800
Subject: [GIT PULL] firmware: arm_scmi: Updates for v5.17
In-Reply-To: <20220107113740.f4zlz25largdjcfd@bogus>
References: <20211222141342.56395-1-sudeep.holla@arm.com>
 <20220107113740.f4zlz25largdjcfd@bogus>
Message-ID: <20220108202410.GA1057@lx2k>

On Fri, Jan 07, 2022 at 11:37:40AM +0000, Sudeep Holla wrote:
> 
> Hi again,
> 
> On Wed, Dec 22, 2021 at 02:13:42PM +0000, Sudeep Holla wrote:
> > Hi ARM SoC Team,
> >
> > Please pull !
> >
> 
> I am aware I sent this pull request just around the same time Arnd finalised
> the initial set. I have seen emails suggesting that Olof might be planning
> to merge additional PR, so it would be great if this gets included in
> that cut. All the changes are in -next since 21st December, so there should
> be no surprises.
> 
> Thanks again and sorry for nagging.

Yeah, no worries -- I'd been letting pull requests sitting for a while over the
holidays. I've merged this into our late branch now.


Thanks,

-Olof


From andrey.zhizhikin at leica-geosystems.com  Sat Jan  8 12:48:03 2022
From: andrey.zhizhikin at leica-geosystems.com (ZHIZHIKIN Andrey)
Date: Sat, 8 Jan 2022 20:48:03 +0000
Subject: [PATCH v3 2/2] arm64: dts: imx8m: define proper status for caam jr
In-Reply-To: <b5e37dc573f9cefc83f73f1113a632a29ba9a833.camel@pengutronix.de>
References: <20211111164601.13135-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-1-andrey.zhizhikin@leica-geosystems.com>
 <20211207230206.14637-3-andrey.zhizhikin@leica-geosystems.com>
 <aa84249b7e099cf23b49016433b22ae541c0a41d.camel@pengutronix.de>
 <AM6PR06MB469100A5D7A069AF84A83EEFA64C9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <30312d09effae6b78309723a7261f85915b8d5b8.camel@pengutronix.de>
 <AM6PR06MB46919E01996D1F1DE326306DA64D9@AM6PR06MB4691.eurprd06.prod.outlook.com>
 <b5e37dc573f9cefc83f73f1113a632a29ba9a833.camel@pengutronix.de>
Message-ID: <AM6PR06MB4691D4FCA4D82284E70A9F53A64E9@AM6PR06MB4691.eurprd06.prod.outlook.com>

Hello Rouven,

> -----Original Message-----
> From: Rouven Czerwinski <r.czerwinski at pengutronix.de>
> Sent: Friday, January 7, 2022 12:56 PM

[snip]

> 
> Yes, upstream TF-A does not implement the NXP specific SIPs to
> communicate with the ROM code to do further image authentication.
> Thats also the reason why all JRs are released to normal world, there
> is no possible HAB use after TF-A has started.
> 
> > I've been following the build documentation in U-Boot, where the downstream
> > TF-A is listed as build prequisites [2] without any mentioning of upstream,
> > hence I received a readout that matched the BootROM "1-to-1".
> 
> Yes, since the downstream TF-A is required to authenticate further
> images.
> 
> Aside from this the bootrom HAB interface on i.MX8MQ was broken in
> interesting ways, I had to implement parsing of the HAB status SRAM
> area by hand within barebox.
> 
> > I believe that if the information from NXP regarding JR0 reservation for
> > HAB is correct (and I have no reasons to doubt it), then upstream TF-A
> > should be adapted in order for HAB feature to work, and in that case this
> > patch brings correct HW state description as seeing from Linux.
> 
> JR0 for HAB in S-World makes sense to me, otherwise the bootrom will
> probably refuse to work with the JR.
> 
> > And in contrary, if the upstream TF-A is not adjusted to include HAB
> > support - then applying this patch would effectively just "remove" one
> > JR device, still keeping 2 additional available nodes for HW crypto
> > operations in Kernel, with added benefit that both upstream and
> > downstream TF-A can be used during the boot without seeing issues later
> > in the Kernel.
> 
> Even with the downstream TF-A there is no reason to keep JR0 asigned to
> the secure world, unless you are running OP-TEE. JR0 assignement for
> HAB shouldn't be required after the bootloader has run, unless you want
> to HAB authenticate images from a running Linux kernel.

Then this probably should be communicated in U-Boot as there is a
patchset proposed in U-Boot, and one of the patches in that series [1]
disabled JR0 as well. Once merged - the JR0 is not going to be available
for Linux, regardless of the fact that TF-A would set DIDs to 0x1.

> 
> The reason NXP hardcodes the configuration downstream is of course to
> support HAB & OP-TEE, but this is still not a reason to hardcode this
> assignement into the kernel device tree. They probably also hardcode it
> in their downstream kernel versions.

Actually, I've checked the downstream NXP Kernel version, and none of
the Job Ring nodes (including JR0) are disabled there.

> 
> I can understand that it seems easier to hardcode this in the kernel,
> but as I said before, if you are running OP-TEE you need to adjust the
> DT anyway since nodes need to be added and you might as well adjust the
> jobring configuration than.

My first version of this patch has been targeting dynamic register
readout to check if DID is set for either S or NS Worlds, but that was
rejected due to unreliable readout in HW. Hence this attempt to
statically disable node was made.

Please note, that there are combinations out there which do have HAB,
TF-A but no OP-TEE. In that case patching DT is not an option, and
would cause the probing error at boot.

Frankly speaking, I'm not sure how to proceed with this further...

Clearly, there is an issue that JR devices are not available in certain
combination of SW entities that are setting different permissions on JR:
upstream TF-A does not do any reservation but does not support HAB (and
this is aligned with current DT nodes description); downstream TF-A does
perform reservation and support HAB, but does not release JR0 to NS-World
causing error on the boot at JR probing. Since those 2 combinations are
orthogonal - the only solution that I see (including the patch proposed
in U-Boot ML) is to reserve the JR0 for all combinations, loosing it in
Linux but covering both TF-A (HAB and non-HAB) at the same time.

If you have any other suggestions here - I'm fully opened to receive those!

> 
> Kind regards,
> Rouven
> 
> 

Regards,
Andrey

Link: [1]: https://lore.kernel.org/u-boot/20211207074129.10955-3-gaurav.jain at nxp.com/

From stefan.wahren at i2se.com  Sat Jan  8 13:04:06 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat, 8 Jan 2022 22:04:06 +0100
Subject: [PATCH] ARM: dts: gpio-ranges property is now required
In-Reply-To: <20220104170247.956760-1-linus.walleij@linaro.org>
References: <20220104170247.956760-1-linus.walleij@linaro.org>
Message-ID: <07f6beef-8824-e995-577e-3c705ed7d40f@i2se.com>

Hi Olof,

Am 04.01.22 um 18:02 schrieb Linus Walleij:
> From: Phil Elwell <phil at raspberrypi.com>
>
> Since [1], added in 5.7, the absence of a gpio-ranges property has
> prevented GPIOs from being restored to inputs when released.
> Add those properties for BCM283x and BCM2711 devices.
>
> [1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
>     pin-ranges")
>
> Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
> Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
> Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
> Reported-by: Florian Fainelli <f.fainelli at gmail.com>
> Reported-by: Jan Kiszka <jan.kiszka at web.de>
> Signed-off-by: Phil Elwell <phil at raspberrypi.com>
> Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Hi SoC maintainers, please apply this directly for fixes, the
> missing patch is wreacking havoc in the RPi world.

this patch has been send to soc at kernel.org in order to fix a regression
[1] caused by "pinctrl: bcm2835: Change init order for gpio hog". Would
be great to get it into 5.16

[1] -
https://lore.kernel.org/all/ec60b52b-7a59-266d-9608-11c0da9053a6 at i2se.com/




From pr-tracker-bot at kernel.org  Sat Jan  8 13:11:55 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sat, 08 Jan 2022 21:11:55 +0000
Subject: [GIT PULL] SoC: Fixes for 5.16, part 4
In-Reply-To: <20220108202011.GA1760@lx2k>
References: <20220108202011.GA1760@lx2k>
Message-ID: <164167631534.4399.1770958189507443875.pr-tracker-bot@kernel.org>

The pull request you sent on Sat, 8 Jan 2022 12:20:11 -0800:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.16-4

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/4634129ad9fdc89d10b597fc6f8f4336fb61e105

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From olof at lixom.net  Sat Jan  8 13:18:43 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 13:18:43 -0800
Subject: [PATCH] ARM: dts: gpio-ranges property is now required
In-Reply-To: <07f6beef-8824-e995-577e-3c705ed7d40f@i2se.com>
References: <20220104170247.956760-1-linus.walleij@linaro.org>
 <07f6beef-8824-e995-577e-3c705ed7d40f@i2se.com>
Message-ID: <CAOesGMjQavd+2eupBE40BfhBwVq4_K493Kn0uzsCi9DoPHB19A@mail.gmail.com>

On Sat, Jan 8, 2022 at 1:04 PM Stefan Wahren <stefan.wahren at i2se.com> wrote:
>
> Hi Olof,
>
> Am 04.01.22 um 18:02 schrieb Linus Walleij:
> > From: Phil Elwell <phil at raspberrypi.com>
> >
> > Since [1], added in 5.7, the absence of a gpio-ranges property has
> > prevented GPIOs from being restored to inputs when released.
> > Add those properties for BCM283x and BCM2711 devices.
> >
> > [1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
> >     pin-ranges")
> >
> > Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
> > Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
> > Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
> > Reported-by: Florian Fainelli <f.fainelli at gmail.com>
> > Reported-by: Jan Kiszka <jan.kiszka at web.de>
> > Signed-off-by: Phil Elwell <phil at raspberrypi.com>
> > Acked-by: Florian Fainelli <f.fainelli at gmail.com>
> > Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> > Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
> > Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> > ---
> > Hi SoC maintainers, please apply this directly for fixes, the
> > missing patch is wreacking havoc in the RPi world.
>
> this patch has been send to soc at kernel.org in order to fix a regression
> [1] caused by "pinctrl: bcm2835: Change init order for gpio hog". Would
> be great to get it into 5.16
>
> [1] -
> https://lore.kernel.org/all/ec60b52b-7a59-266d-9608-11c0da9053a6 at i2se.com/

Yeah, my bad -- I only scanned for pull requests and missed this
patch. I'll send it up. Linus just merged the pull request I sent so
I'll do an incremental one.

-Olof


From olof at lixom.net  Sat Jan  8 13:26:21 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 13:26:21 -0800
Subject: [GIT PULL] amlogic fixes for v5.17-rc
In-Reply-To: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
References: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
Message-ID: <YdoBffKeAvtOeRSe@lx2k>

On Mon, Jan 03, 2022 at 04:13:44PM +0100, Neil Armstrong wrote:
> Hi,
> 
> Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
> the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
> applied by greg in the tty branch for 5.17.
> 
> I know it's early for 5.17-rc1, but at least it's in the pipe.
> 
> I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
> if necessary I can rebase on v5.16-rcX.

Hi Neil,

It looks like this branch is based on our arm/dt branch? Please don't base your
topics on our branches, it'll be awkward if we ever need to rebuild them (it's
happened a few times, but we try very hard to avoid it).

In this case, you should have based your contents on top of your latest dt
branch (if it would have had conflicts), not ours.

Mind rebuilding and send a new pull request?

Thanks,


-Olof



From olof at lixom.net  Sat Jan  8 13:58:40 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 13:58:40 -0800
Subject: [GIT PULL] Apple SoC MAINTAINERS updates for 5.17
In-Reply-To: <24ae6871-3e67-5c7f-2060-28048db439a2@marcan.st>
References: <24ae6871-3e67-5c7f-2060-28048db439a2@marcan.st>
Message-ID: <YdoJEMjEr5jKwLf7@lx2k>

On Sat, Jan 08, 2022 at 02:13:49PM +0900, Hector Martin wrote:
> Hi SoC folks,
> 
> Please merge this trivial MAINTAINERS change for 5.17.
> 
> This commit was waiting on the watchdog driver to be merged, but I only
> just now realized that it silently did. Sorry for the last-minute pull.
> If this can't make it into the 5.17 merge window, it can be added as a
> fix later instead.
> 
> The branch is based on asahi-soc-dt-5.17-v2 to avoid a merge conflict
> with other changes that happened there.

Hi,

I've merged a bunch of outstanding pull requests into an arm/late branch, but
I'm holding on to this one for a bit, we'll merge it once the main branches
have gone in, since it contains a bunch of that contents. Since it's just
a MAINTAINERS update it's fine to merge late, no need to soak in -next.


-Olof


From henrik at grimler.se  Sat Jan  8 13:57:33 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat,  8 Jan 2022 22:57:33 +0100
Subject: [RFC PATCH 1/1] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
In-Reply-To: <20220108215733.705865-1-henrik@grimler.se>
References: <20220108215733.705865-1-henrik@grimler.se>
Message-ID: <20220108215733.705865-2-henrik@grimler.se>

On Exynos5 the call is simply ignored by most variants of the
trustzone firmware.  However, on some devices it instead causes the
device to hang, so let's avoid the call for the SoCs where it should
not be needed.

To see that the call is ignored, we can look into sboot/tzsw.  On most
of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
the secure monitor calls is quite easy to recognise, the SMC number is
compared to known ones, and if equal it branches to the relevant
function.  In assembly this looks something like:

;-- handle_smc:
0x00000514      650070e3       cmn r0, 0x65
0x00000518      0a00000a       beq loc.smc_cmd_reg
0x0000051c      010070e3       cmn r0, 1
0x00000520      6c00000a       beq loc.smc_cmd_init
0x00000524      020070e3       cmn r0, 2
0x00000528      6b00000a       beq loc.smc_cmd_info
0x0000052c      030070e3       cmn r0, 3
0x00000530      6e00000a       beq loc.smc_cmd_sleep
0x00000534      060070e3       cmn r0, 6
0x00000538      ae00000a       beq loc.smc_cmd_save_state
0x0000053c      070070e3       cmn r0, 7
0x00000540      b400000a       beq loc.smc_cmd_standby
0x00000544      2b01001a       bne loc.smc_return_minus1

where above example is from exynos5420-arndale-octa.  As can be seen
the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
annotations are taken from github.com/hsnaves/exynos5410-firmware,
where a large part of the exynos5410 trustzone firmware has been
reverse-engineered.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
 	/*
 	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
 	 * because Exynos3250 removes WFE in secure mode.
+	 *
+	 * On Exynos5 devices the call is ignored by trustzone firmware.
 	 */
-	if (soc_is_exynos3250())
+	if (!soc_is_exynos4210() && !soc_is_exynos4412())
 		return 0;
 
 	/*
-- 
2.34.1



From henrik at grimler.se  Sat Jan  8 13:57:32 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat,  8 Jan 2022 22:57:32 +0100
Subject: [RFC PATCH 0/1] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
Message-ID: <20220108215733.705865-1-henrik@grimler.se>

I am trying to add support in mainline for a tablet based on Exynos
5420 (Samsung Galaxy Tab S).  For this tablet, CCI has to be disabled,
and with that the device then hangs during

  exynos_smc(SMC_CMD_CPU1BOOT, cpu, 0, 0),

which is run in the cpu_boot secure-firmware function.  If the call is
skipped, then four out of eight CPUs are brought up, which is the same
as on exynos5420-arndale-octa [1] which also has disabled CCI.

Based on Samsung's kernel sources, it seems like the SMC_CMD_CPU1BOOT
call is only needed on Exynos4 and Exynos5250 devices [2], on other
SoC models the call is skipped.  To test if the call seem to do
anything, I booted exynos5422-odroid-xu4 with disabled CCI and with or
without the SMC_CMD_CPU1BOOT call.  The result in both cases were the
same: the first four CPUs were brought up.

To further investigate if the SMC_CMD_CPU1BOOT call is handled we need
to dig into the trustzone firmware.  The trustzone firmware used in
exynos5410-odroid-xu has been to a large part reverse engineered [3],
and by comparing with sboot/tzsw in mainline devices it can be seen
that similar trustzone firmware is used in several.  Out of those, the
SMC_CMD_CPU1BOOT call seem to be only handled in Exynos4 devices.

Here's a table summarising the findings for the mainline devices that
have a secure-firmware node (Exynos3 devices omitted).  An extra 4212
device has been included to get a datapoint for that SoC as well.

.----------------------.--------------.--------------.--------------.
| Device (exynos-)     | Similar tzsw | CPU1BOOT SMC | sboot/tzsw   |
|                      |   to 5410?   |   handled?   |   source     |
.----------------------.--------------.--------------.--------------.
  4212 galaxy tab 3    | yes          | yes          | T310XXSBQB2
  4412-i9300           | yes          | yes          | I9300XXUGPE1
  4412-i9305           | yes          | yes          | I9305XXUFPB1
  4412-itop-elite      | not checked  |              |
  4412-n710x           | not checked  |              |
  4412-odroid{x,x2,u3} | yes          | yes          | wiki.odroid.com/_media/en/boot.tar.gz
  4412-origen          | no           | don't know   | Linaro's origen hwpack 20130130
  4412-p4note-n8010    | not checked  |              |
  4412-trats2          | not checked  |              |
  5410-odroidxu        | yes          | no           | github.com/hsnaves/exynos5410-firmware
  5410-smdk5410        | not checked  |              |
  5420-arndale-octa    | yes          | no           | Linaro's arndale-octa hwpack 20140323
  5422-odroid-xu{3,4}  | yes          | no           | Hardkernel's u-boot 2020.01 branch

"Similar tzsw" above means that the secure monitor calls seem to be
handled in the same way as for exynos5410-odroid-xu, in a quite
easy-to-spot function (see patch for what it looks like).

For the tablet I am actually interested in, the trustzone firmware
looks very different, and I have not been able to locate where/how the
secure monitor calls are handled.

Nevertheless, since the call seem to only be handled in trustzone
firmware for Exynos4, and since exynos5422-odroid-xu4 behaves the same
with or without this secure monitor call, I *think* it should be safe
to only run it on the devices where we know that it is handled.

[1] https://krzk.eu/#/builders/32
[2] https://github.com/LineageOS/android_kernel_samsung_exynos5420/blob/cm-14.1/arch/arm/mach-exynos/platsmp.c#L225-L229
[3] https://github.com/hsnaves/exynos5410-firmware

Henrik Grimler (1):
  ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4

 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)


base-commit: 3e4d9032d1a223488456f82d05cfe5519962f344
prerequisite-patch-id: f0f30752eb24b3515eee0a8d7bcf043e2cb084ad
-- 
2.34.1



From mirq-linux at rere.qmqm.pl  Sat Jan  8 15:56:51 2022
From: mirq-linux at rere.qmqm.pl (=?iso-8859-2?Q?Micha=B3_Miros=B3aw?=)
Date: Sun, 9 Jan 2022 00:56:51 +0100
Subject: [PATCH v2 3/5] drm/dp: Move DisplayPort helpers into separate
 helper module
In-Reply-To: <87pmpy3za7.fsf@intel.com>
References: <20211215104318.18866-1-tzimmermann@suse.de>
 <20211215104318.18866-4-tzimmermann@suse.de>
 <87pmpy3za7.fsf@intel.com>
Message-ID: <Ydokw2y6w9JlCsgR@qmqm.qmqm.pl>

On Wed, Dec 15, 2021 at 01:04:00PM +0200, Jani Nikula wrote:
> On Wed, 15 Dec 2021, Thomas Zimmermann <tzimmermann at suse.de> wrote:
> > 	* move DP helper code into dp/ (Jani)
> 
> I suggested adding the subdirectory, but I'm going to bikeshed the name,
> which I didn't suggest.
> 
> $ find drivers/gpu/drm -mindepth 1 -maxdepth 1 -type d | wc -l
> 68

Maybe the hardware-specific drivers could be moved up to drivers/gpu/
instead? That would make it obvious what code is generic and what is not.

Best Regards
Micha? Miros?aw


From yong.wu at mediatek.com  Sat Jan  8 18:46:49 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Sun, 9 Jan 2022 10:46:49 +0800
Subject: [PATCH v3 26/33] iommu/mediatek: Add mtk_iommu_bank_data structure
In-Reply-To: <5ac9dd6b-43cd-0f76-eb34-906ab84196c1@collabora.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-27-yong.wu@mediatek.com>
 <5ac9dd6b-43cd-0f76-eb34-906ab84196c1@collabora.com>
Message-ID: <214831c674c23d6733d372b5970d8c6754d55b1d.camel@mediatek.com>

Hi AngeloGioacchino,

Thanks very much for reviewing whole the patchset.

On Tue, 2022-01-04 at 16:53 +0100, AngeloGioacchino Del Regno wrote:
> Il 23/09/21 13:58, Yong Wu ha scritto:
> > Prepare for supporting multi-banks for the IOMMU HW, No functional
> > change.
> > 
> > Add a new structure(mtk_iommu_bank_data) for each a bank. Each a
> > bank have
> > the independent HW base/IRQ/tlb-range ops, and each a bank has its
> > special
> > iommu-domain(independent pgtable), thus, also move the domain
> > information
> > into it.
> > 
> > In previous SoC, we have only one bank which could be treated as
> > bank0(
> > bankid always is 0 for the previous SoC).
> > 
> > After adding this structure, the tlb operations and irq could use
> > bank_data as parameter.
> > 
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---

[...]
  
> > -struct mtk_iommu_data {
> > +struct mtk_iommu_bank_data {
> >   	void __iomem			*base;
> >   	int				irq;
> > +	unsigned int			id;
> > +	struct device			*pdev;
> 
> `pdev` may be a bit misleading, as it's conventionally read as
> "platform device"
> and not as the intended "parent device"... perhaps calling it
> parent_dev would be
> more appropriate.

will rename it. Thanks.

> 
> > +	struct mtk_iommu_data		*pdata;   /* parent data */
> 
> Same here, pdata -> parent_data

Will fix.

> 
> > +	spinlock_t			tlb_lock; /* lock for tlb range
> > flush */
> > +	struct mtk_iommu_domain		*m4u_dom; /* Each bank has
> > a domain */
> > +};
> > +
> > +struct mtk_iommu_data {
> > +	union {
> > +		struct { /* only for gen1 */
> > +			void __iomem		*base;
> > +			int			irq;
> > +			struct mtk_iommu_domain	*m4u_dom;
> > +		};
> > +
> > +		/* only for gen2 that support multi-banks */
> > +		struct mtk_iommu_bank_data	bank[MTK_IOMMU_BANK_MAX];
> > +	};
> 
> Sorry, but I really don't like this union... please, update
> mtk_iommu_v1 to always
> use bank[0] or, more appropriately, dynamically allocate the bank
> array with a
> devm_kzalloc call (as to not waste memory on platforms with less
> available banks).
> 
> In that case, you would have...
> 
> >   	struct device			*dev;
> >   	struct clk			*bclk;
> >   	phys_addr_t			protect_base; /* protect memory
> > base */
> >   	struct mtk_iommu_suspend_reg	reg;
> > -	struct mtk_iommu_domain		*m4u_dom;
> >   	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
> >   	bool                            enable_4GB;
> > -	spinlock_t			tlb_lock; /* lock for tlb range
> > flush */
> 
> 	struct mtk_iommu_bank_data	*banks;
> 	u8				num_banks;
> 
> ... where `num_banks` gets copied from the same in
> mtk_iommu_plat_data, defined
> for each SoC, and where `banks` is dynamically allocated in
> mtk_iommu.c and
> mtk_iommu_v1.c's probe() callback.

Thanks for this idea. I will try this to see if the code will be too
complicate after changing this. If it is, I will use bank[0] always in
mtk_iommu_v1, this looks simpler.

> 
> >   
> >   	struct iommu_device		iommu;
> >   	const struct mtk_iommu_plat_data *plat_data;
> > 
> 
> 

From yong.wu at mediatek.com  Sat Jan  8 18:47:24 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Sun, 9 Jan 2022 10:47:24 +0800
Subject: [PATCH v3 13/33] iommu/mediatek: Remove the power status
 checking in tlb flush all
In-Reply-To: <1cb7458d-a012-2e84-82bd-7e4f30ed9162@collabora.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-14-yong.wu@mediatek.com>
 <1cb7458d-a012-2e84-82bd-7e4f30ed9162@collabora.com>
Message-ID: <c5062c4636e67924af8fbf9a66565e2f89dddce5.camel@mediatek.com>

On Tue, 2022-01-04 at 16:55 +0100, AngeloGioacchino Del Regno wrote:
> Il 23/09/21 13:58, Yong Wu ha scritto:
> > To simplify the code, Remove the power status checking in the
> > tlb_flush_all, remove this:
> >     if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > 	    continue;
> > 
> > After this patch, the mtk_iommu_tlb_flush_all will be called from
> > a) isr
> > b) pm runtime resume callback
> > c) tlb flush range fail case
> > d) iommu_create_device_direct_mappings
> >     -> iommu_flush_iotlb_all
> > In first three cases, the power and clock always are enabled; d) is
> > direct
> > mapping, the tlb flush is unnecessay since we already have
> > tlb_flush_all
> > in the pm_runtime_resume callback. When the iommu's power status is
> > changed to active, the tlb always is clean.
> > 
> > In addition, there still are 2 reasons that don't add PM status
> > checking
> > in the tlb flush all:
> > a) Write tlb flush all register also is ok even though the HW has
> > no
> > power and clocks. Write ignore.
> 
> Do you mean that the register write seemingly succeeds but the
> hardware discards it?
> Please, reword the `a` sentence to be clearer.

Yes. This is the "Write ignore" I tried to explain.

By the way, the tlb operation patches were moved to this patchset[1]
from Dafna. Would you help take a look at that one? I will send the
next mt8195 version based on that patchset.

[1] 
https://lore.kernel.org/linux-mediatek/20211208120744.2415-1-dafna.hirschfeld at collabora.com/

Thanks.

> 
> > b) pm_runtime_get_if_in_use(m4udev) is 0 when the tlb_flush_all
> > is called frm pm_runtime_resume cb. From this point, we can not add
> > this code above in this tlb_flush_all.
> > 
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >   drivers/iommu/mtk_iommu.c | 20 +++++++-------------
> >   1 file changed, 7 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index e9e94944ed91..4a33b6c6b1db 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -204,10 +204,14 @@ static struct mtk_iommu_domain
> > *to_mtk_domain(struct iommu_domain *dom)
> >   	return container_of(dom, struct mtk_iommu_domain, domain);
> >   }
> >   
> > -static void mtk_iommu_tlb_do_flush_all(struct mtk_iommu_data
> > *data)
> > +static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
> >   {
> >   	unsigned long flags;
> >   
> > +	/*
> > +	 * No need get power status since the HW PM status nearly is
> > active
> > +	 * when entering here.
> 
> Please reword this comment to explain the entire situation.
> 
> > +	 */
> >   	spin_lock_irqsave(&data->tlb_lock, flags);
> >   	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> >   		       data->base + data->plat_data->inv_sel_reg);
> > @@ -216,16 +220,6 @@ static void mtk_iommu_tlb_do_flush_all(struct
> > mtk_iommu_data *data)
> >   	spin_unlock_irqrestore(&data->tlb_lock, flags);
> >   }
> >   
> > -static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
> > -{
> > -	if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > -		return;
> > -
> > -	mtk_iommu_tlb_do_flush_all(data);
> > -
> > -	pm_runtime_put(data->dev);
> > -}
> > -
> >   static void mtk_iommu_tlb_flush_range_sync(unsigned long iova,
> > size_t size,
> >   					   struct mtk_iommu_data *data)
> >   {
> > @@ -263,7 +257,7 @@ static void
> > mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
> >   		if (ret) {
> >   			dev_warn(data->dev,
> >   				 "Partial TLB flush timed out, falling
> > back to full flush\n");
> > -			mtk_iommu_tlb_do_flush_all(data);
> > +			mtk_iommu_tlb_flush_all(data);
> >   		}
> >   
> >   		if (has_pm)
> > @@ -993,7 +987,7 @@ static int __maybe_unused
> > mtk_iommu_runtime_resume(struct device *dev)
> >   	 *
> >   	 * Thus, Make sure the tlb always is clean after each PM
> > resume.
> >   	 */
> > -	mtk_iommu_tlb_do_flush_all(data);
> > +	mtk_iommu_tlb_flush_all(data);
> >   
> >   	/*
> >   	 * Uppon first resume, only enable the clk and return, since
> > the values of the
> > 
> 
> 

From yong.wu at mediatek.com  Sat Jan  8 18:47:46 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Sun, 9 Jan 2022 10:47:46 +0800
Subject: [PATCH v3 22/33] iommu/mediatek: Add PCIe support
In-Reply-To: <3b5e7072-0935-4383-27a1-dd8d623cc608@collabora.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-23-yong.wu@mediatek.com>
 <3b5e7072-0935-4383-27a1-dd8d623cc608@collabora.com>
Message-ID: <694747210c8da8ae4fc282cd90152e5c81945da5.camel@mediatek.com>

On Tue, 2022-01-04 at 16:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 23/09/21 13:58, Yong Wu ha scritto:
> > Currently the code for of_iommu_configure_dev_id is like this:
> > 
> > static int of_iommu_configure_dev_id(struct device_node *master_np,
> >                                       struct device *dev,
> >                                       const u32 *id)
> > {
> >         struct of_phandle_args iommu_spec = { .args_count = 1 };
> > 
> >         err = of_map_id(master_np, *id, "iommu-map",
> >                         "iommu-map-mask", &iommu_spec.np,
> >                         iommu_spec.args);
> > ...
> > }
> > 
> > It supports only one id output. BUT our PCIe HW has two ID(one is
> > for
> > writing, the other is for reading). I'm not sure if we should
> > change
> > of_map_id to support output MAX_PHANDLE_ARGS.
> > 
> > Here add the solution in ourselve drivers. If it's pcie case,
> > enable one
> > more bit.
> > 
> > Not all infra iommu support PCIe, thus add a PCIe support flag
> > here.
> > 
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >   drivers/iommu/mtk_iommu.c | 21 ++++++++++++++++++++-
> >   1 file changed, 20 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 37d6dfb4feab..3f1fd8036345 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -20,6 +20,7 @@
> >   #include <linux/of_address.h>
> >   #include <linux/of_irq.h>
> >   #include <linux/of_platform.h>
> > +#include <linux/pci.h>
> >   #include <linux/platform_device.h>
> >   #include <linux/pm_runtime.h>
> >   #include <linux/regmap.h>
> > @@ -132,6 +133,7 @@
> >   #define MTK_IOMMU_TYPE_MM		(0x0 << 13)
> >   #define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
> >   #define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
> > +#define IFA_IOMMU_PCIe_SUPPORT		BIT(15)
> 
> This definition looks like "breaking" the naming convention that's
> used in this
> driver... what about MTK_INFRA_IOMMU_PCIE_SUPPORT?

OK for me. I noticed the "PCIE" should called to "PCIe", thus renamed
this.

> 
> >   
> >   #define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) &
> > (_x)))
> >   
> > @@ -401,8 +403,11 @@ static int mtk_iommu_config(struct
> > mtk_iommu_data *data, struct device *dev,
> >   				larb_mmu->mmu &=
> > ~MTK_SMI_MMU_EN(portid);
> >   		} else if (MTK_IOMMU_IS_TYPE(data->plat_data,
> > MTK_IOMMU_TYPE_INFRA)) {
> >   			peri_mmuen_msk = BIT(portid);
> > -			peri_mmuen = enable ? peri_mmuen_msk : 0;
> > +			/* PCIdev has only one output id, enable the
> > next writing bit for PCIe */
> > +			if (dev_is_pci(dev))
> > +				peri_mmuen_msk |= BIT(portid + 1);
> >   
> > +			peri_mmuen = enable ? peri_mmuen_msk : 0;
> >   			ret = regmap_update_bits(data->pericfg,
> > PERICFG_IOMMU_1,
> >   						 peri_mmuen_msk,
> > peri_mmuen);
> >   			if (ret)
> > @@ -977,6 +982,15 @@ static int mtk_iommu_probe(struct
> > platform_device *pdev)
> >   		ret = component_master_add_with_match(dev,
> > &mtk_iommu_com_ops, match);
> >   		if (ret)
> >   			goto out_bus_set_null;
> > +	} else if (MTK_IOMMU_IS_TYPE(data->plat_data,
> > MTK_IOMMU_TYPE_INFRA) &&
> > +		   MTK_IOMMU_HAS_FLAG(data->plat_data,
> > IFA_IOMMU_PCIe_SUPPORT)) {
> > +		#ifdef CONFIG_PCI
> 
> Please fix the indentation of this ifdef (do not indent).

Thanks. Will fix this.

> 
> > +		if (!iommu_present(&pci_bus_type)) {
> > +			ret = bus_set_iommu(&pci_bus_type,
> > &mtk_iommu_ops);
> > +			if (ret) /* PCIe fail don't affect
> > platform_bus. */
> > +				goto out_list_del;
> > +		}
> > +		#endif
> >   	}
> >   	return ret;
> >   
> > @@ -1007,6 +1021,11 @@ static int mtk_iommu_remove(struct
> > platform_device *pdev)
> >   	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
> >   		device_link_remove(data->smicomm_dev, &pdev->dev);
> >   		component_master_del(&pdev->dev, &mtk_iommu_com_ops);
> > +	} else if (MTK_IOMMU_IS_TYPE(data->plat_data,
> > MTK_IOMMU_TYPE_INFRA) &&
> > +		   MTK_IOMMU_HAS_FLAG(data->plat_data,
> > IFA_IOMMU_PCIe_SUPPORT)) {
> > +		#ifdef CONFIG_PCI
> 
> ditto.
> 
> > +		bus_set_iommu(&pci_bus_type, NULL);
> > +		#endif
> >   	}
> >   	pm_runtime_disable(&pdev->dev);
> >   	devm_free_irq(&pdev->dev, data->irq, data);
> > 
> 
> 

From yong.wu at mediatek.com  Sat Jan  8 18:48:27 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Sun, 9 Jan 2022 10:48:27 +0800
Subject: [PATCH v3 09/33] iommu/mediatek: Remove for_each_m4u in
 tlb_sync_all
In-Reply-To: <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-10-yong.wu@mediatek.com>
 <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>
Message-ID: <22faee018a36a49e4a507b69d087432c8cd689ec.camel@mediatek.com>

On Tue, 2022-01-04 at 16:55 +0100, AngeloGioacchino Del Regno wrote:
> Il 23/09/21 13:58, Yong Wu ha scritto:
> > The tlb_sync_all is called from these three functions:
> > a) flush_iotlb_all: it will be called for each a iommu HW.
> > b) tlb_flush_range_sync: it already has for_each_m4u.
> > c) in irq: When IOMMU HW translation fault, Only need flush itself.
> > 
> > Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
> > 
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >   drivers/iommu/mtk_iommu.c | 18 +++++++-----------
> >   1 file changed, 7 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> > index 6f4f6624e3ac..0b4c30baa864 100644
> > --- a/drivers/iommu/mtk_iommu.c
> > +++ b/drivers/iommu/mtk_iommu.c
> > @@ -206,19 +206,15 @@ static struct mtk_iommu_domain
> > *to_mtk_domain(struct iommu_domain *dom)
> >   
> >   static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
> >   {
> > -	struct list_head *head = data->hw_list;
> > -
> > -	for_each_m4u(data, head) {
> > -		if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > -			continue;
> > +	if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > +		return;
> >   
> > -		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> > -			       data->base + data->plat_data-
> > >inv_sel_reg);
> > -		writel_relaxed(F_ALL_INVLD, data->base +
> > REG_MMU_INVALIDATE);
> > -		wmb(); /* Make sure the tlb flush all done */
> > +	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> > +		       data->base + data->plat_data->inv_sel_reg);
> > +	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
> > +	wmb(); /* Make sure the tlb flush all done */
> 
> There aren't a lot of writes here - not anymore, since you are no
> longer doing
> this for_each_m4u()...
> ...so, please change writel_relaxed() to writel() calls, allowing you
> to also
> remove the write barrier at the end (since in the non relaxed
> version, order is already ensured).

In the "writel", the "__iowmb()" runs before "write_relaxed". Then how
to guarantee the last register was wrote into the HW. Here the flush
all don't have sync(waiting it complete)

> 
> >   
> > -		pm_runtime_put(data->dev);
> > -	}
> > +	pm_runtime_put(data->dev);
> >   }
> >   
> >   static void mtk_iommu_tlb_flush_range_sync(unsigned long iova,
> > size_t size,
> > 

From olof at lixom.net  Sat Jan  8 23:25:40 2022
From: olof at lixom.net (Olof Johansson)
Date: Sat, 8 Jan 2022 23:25:40 -0800
Subject: [GIT PULL] SoC: One more fix for 5.16
Message-ID: <YdqN9GxRTQYVA/f4@lx2k>


Hi Linus,


The following changes since commit 8922bb6526ac4b20bd8de7f47d6e77808670f6c4:

  Merge tag 'socfpga_fix_for_v5.16_part_3' of git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux into arm/fixes (2022-01-05 16:18:50 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.16-5

for you to fetch changes up to c8013355ead68dce152cf426686f8a5f80d88b40:

  ARM: dts: gpio-ranges property is now required (2022-01-08 13:28:28 -0800)

----------------------------------------------------------------
SoC: One more fix for 5.16

I had missed one patch when I sent up what I thought was the last batch
of fixes for this release. This one fixes issues on the Raspberry Pi
platforms due to gpio init changes this release, so hopefully we can get
it merged before final release is cut.

----------------------------------------------------------------
Phil Elwell (1):
      ARM: dts: gpio-ranges property is now required

 arch/arm/boot/dts/bcm2711.dtsi | 2 ++
 arch/arm/boot/dts/bcm283x.dtsi | 2 ++
 2 files changed, 4 insertions(+)


From conleylee at foxmail.com  Sun Jan  9 01:17:55 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Sun,  9 Jan 2022 17:17:55 +0800
Subject: [PATCH v1] sun4i-emac.c: enable emac tx dma
In-Reply-To: <YdLhQjUTobcLq73j@Red>
References: <YdLhQjUTobcLq73j@Red>
Message-ID: <tencent_E4BA4D6105A46CCC1E8AEF48057EA5FE5B08@qq.com>

From: conley <conleylee at foxmail.com>

Hello
I am reading the R40 user manual and trying to create a new path to enable
emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
I try to enable emac tx dma channel by the follow steps:
1. enable tx dma mode
2. set packet lengths
2. move data from skb to tx fifo by using dma in xmit function.
3. start transfer from tx fifo to phy in dma tx done callback

But it doesn't work. emac tx interrupt and dma finished interrupt are
raised, but no packets are transmitted (I test it by tcpdump).
Do you know how to configure the emac tx dma correctly? Thanks ~

Signed-off-by: conley <conleylee at foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 324 +++++++++++++-------
 drivers/net/ethernet/allwinner/sun4i-emac.h |  14 +
 2 files changed, 221 insertions(+), 117 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 964227e342ee..fcd7848f64a0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -80,6 +80,7 @@ struct emac_board_info {
 	u16			tx_fifo_stat;
 
 	int			emacrx_completed_flag;
+	int 			emactx_completed_flag;
 
 	struct device_node	*phy_node;
 	unsigned int		link;
@@ -88,15 +89,20 @@ struct emac_board_info {
 
 	phy_interface_t		phy_interface;
 	struct dma_chan	*rx_chan;
+	struct dma_chan	*tx_chan;
 	phys_addr_t emac_rx_fifo;
+	phys_addr_t emac_tx_fifo;
 };
 
 struct emac_dma_req {
 	struct emac_board_info *db;
-	struct dma_async_tx_descriptor *desc;
+	struct dma_chan *chan;
 	struct sk_buff *skb;
-	dma_addr_t rxbuf;
+	void* buf;
+	dma_addr_t mapped_buf;
 	int count;
+	enum dma_data_direction dir;
+	int channel; // for tx
 };
 
 static void emac_update_speed(struct net_device *dev)
@@ -218,8 +224,9 @@ static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
 
 static struct emac_dma_req *
 emac_alloc_dma_req(struct emac_board_info *db,
-		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
-		   dma_addr_t rxbuf, int count)
+		struct dma_chan* chan,
+		struct sk_buff *skb, void* buf,
+		dma_addr_t mapped_buf, int count, int channel)
 {
 	struct emac_dma_req *req;
 
@@ -228,9 +235,10 @@ emac_alloc_dma_req(struct emac_board_info *db,
 		return NULL;
 
 	req->db = db;
-	req->desc = desc;
+	req->chan = chan;
 	req->skb = skb;
-	req->rxbuf = rxbuf;
+	req->buf = buf;
+	req->mapped_buf = mapped_buf;
 	req->count = count;
 	return req;
 }
@@ -240,22 +248,22 @@ static void emac_free_dma_req(struct emac_dma_req *req)
 	kfree(req);
 }
 
-static void emac_dma_done_callback(void *arg)
+static void emac_dma_rx_done_callback(void *arg)
 {
 	struct emac_dma_req *req = arg;
 	struct emac_board_info *db = req->db;
 	struct sk_buff *skb = req->skb;
-	struct net_device *dev = db->ndev;
+	struct net_device *ndev = db->ndev;
 	int rxlen = req->count;
 	u32 reg_val;
 
-	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, rxlen, DMA_FROM_DEVICE);
 
-	skb->protocol = eth_type_trans(skb, dev);
+	skb->protocol = eth_type_trans(skb, ndev);
 	netif_rx(skb);
-	dev->stats.rx_bytes += rxlen;
+	ndev->stats.rx_bytes += rxlen;
 	/* Pass to upper layer */
-	dev->stats.rx_packets++;
+	ndev->stats.rx_packets++;
 
 	/* re enable cpu receive */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
@@ -264,48 +272,92 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
 	emac_free_dma_req(req);
 }
 
-static int emac_dma_inblk_32bit(struct emac_board_info *db,
-		struct sk_buff *skb, void *rdptr, int count)
+
+static void emac_transfer_to_phy(struct emac_board_info* db, int channel)
+{
+	u32 reg = channel == 0 ? EMAC_TX_CTL0_REG : EMAC_TX_CTL1_REG;
+	writel(readl(db->membase + reg) | 1, db->membase + reg);
+	netif_trans_update(db->ndev);
+}
+
+
+static void emac_dma_tx_done_callback(void* arg)
+{
+	struct emac_dma_req *req = arg;
+	struct emac_board_info *db = req->db;
+	struct sk_buff *skb = req->skb;
+
+	emac_transfer_to_phy(db, req->channel);
+	dev_consume_skb_any(skb);
+
+	db->emactx_completed_flag = 1;
+	dev_info(db->dev, "emac xmit with dma done: channel = %d, len = %d\n", req->channel, req->count);
+	
+	emac_free_dma_req(req);
+}
+
+static int emac_dma_submit_request(
+		struct emac_board_info *db,
+		struct sk_buff *skb, void *buf,
+		int count, enum dma_transfer_direction dir,
+		int channel)
 {
+	int ret = 0;
 	struct dma_async_tx_descriptor *desc;
 	dma_cookie_t cookie;
-	dma_addr_t rxbuf;
+	dma_addr_t mapped_buf;
+	enum dma_data_direction data_dir;
+	struct dma_chan *chan;
 	struct emac_dma_req *req;
-	int ret = 0;
+	dma_async_tx_callback callback;
+	
+	if (dir == DMA_DEV_TO_MEM){
+		data_dir = DMA_FROM_DEVICE;
+		chan = db->rx_chan;
+		callback = emac_dma_rx_done_callback;
+	}else if (dir == DMA_MEM_TO_DEV){
+		data_dir = DMA_TO_DEVICE;
+		chan = db->tx_chan;
+		callback = emac_dma_tx_done_callback;
+	}else{
+		dev_err(db->dev, "emac dma transfer direction must be"
+				"DMA_FROM_DEVICE or DMA_TO_DEVICE\n");
+		return -EINVAL;
+	}
 
-	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
-	ret = dma_mapping_error(db->dev, rxbuf);
-	if (ret) {
-		dev_err(db->dev, "dma mapping error.\n");
+	mapped_buf = dma_map_single(db->dev, buf, count, data_dir);
+	ret = dma_mapping_error(db->dev, mapped_buf);
+	if (ret){
+		dev_err(db->dev, "dma mapping error\n");
 		return ret;
+	}	
+	
+	req = emac_alloc_dma_req(db, chan, skb, buf, mapped_buf, count, channel);
+	if (!req) {
+		dev_err(db->dev, "alloc emac dma req error.\n");
+		ret = -ENOMEM;
+		goto alloc_req_err;
 	}
 
-	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
-					   DMA_DEV_TO_MEM,
-					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	desc = dmaengine_prep_slave_single(chan, mapped_buf, count, dir,
+						DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
 	if (!desc) {
 		dev_err(db->dev, "prepare slave single failed\n");
 		ret = -ENOMEM;
 		goto prepare_err;
 	}
 
-	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
-	if (!req) {
-		dev_err(db->dev, "alloc emac dma req error.\n");
-		ret = -ENOMEM;
-		goto alloc_req_err;
-	}
-
 	desc->callback_param = req;
-	desc->callback = emac_dma_done_callback;
-
+	desc->callback = callback;
+	
 	cookie = dmaengine_submit(desc);
 	ret = dma_submit_error(cookie);
 	if (ret) {
@@ -313,20 +365,31 @@ static int emac_dma_inblk_32bit(struct emac_board_info *db,
 		goto submit_err;
 	}
 
-	dma_async_issue_pending(db->rx_chan);
+	dma_async_issue_pending(chan);
 	return ret;
 
 submit_err:
-	emac_free_dma_req(req);
-
-alloc_req_err:
 	dmaengine_desc_free(desc);
 
 prepare_err:
-	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
+	dma_unmap_single(db->dev, req->mapped_buf, req->count, req->dir);
+
+alloc_req_err:
+	emac_free_dma_req(req);
 	return ret;
 }
 
+static int emac_dma_inblk_32bit(struct emac_board_info *db,
+		struct sk_buff *skb, void *rdptr, int count)
+{
+	return emac_dma_submit_request(db, skb, rdptr, count, DMA_DEV_TO_MEM, -1);
+}
+
+static int emac_dma_outblk_32bit(struct emac_board_info *db, struct sk_buff *skb, int channel)
+{
+	return emac_dma_submit_request(db, skb, skb->data, skb->len, DMA_MEM_TO_DEV, channel);
+}
+
 /* ethtool ops */
 static void emac_get_drvinfo(struct net_device *dev,
 			      struct ethtool_drvinfo *info)
@@ -506,7 +569,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -535,6 +598,13 @@ static void emac_timeout(struct net_device *dev, unsigned int txqueue)
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+static void emac_set_packet_len(struct emac_board_info* db, int channel, int len)
+{
+	u32 reg = channel == 0 ? EMAC_TX_PL0_REG : EMAC_TX_PL1_REG;
+	/* set TX len */
+	writel(len, db->membase + reg);
+}
+
 /* Hardware start transmission.
  * Send a packet to media from the upper layer.
  */
@@ -543,9 +613,11 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct emac_board_info *db = netdev_priv(dev);
 	unsigned long channel;
 	unsigned long flags;
+	u32 reg_val;
+	int len = skb->len;
 
 	channel = db->tx_fifo_stat & 3;
-	if (channel == 3)
+	if (channel == 3 || !db->emactx_completed_flag)
 		return NETDEV_TX_BUSY;
 
 	channel = (channel == 1 ? 1 : 0);
@@ -553,32 +625,27 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&db->lock, flags);
 
 	writel(channel, db->membase + EMAC_TX_INS_REG);
+	
+	emac_set_packet_len(db, channel, len);
+
+	if (db->tx_chan){
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val | EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_dma_outblk_32bit(db, skb, channel);
+		db->emactx_completed_flag = 0;
+		dev_info(db->dev, "xmit with dma: channel = %lu, len = %d\n", channel, len);
+	}else{
+		reg_val = readl(db->membase + EMAC_TX_MODE_REG);
+		writel(reg_val & ~EMAC_TX_MODE_DMA_EN, db->membase + EMAC_TX_MODE_REG);
+		emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG, skb->data, len);
+
+		emac_transfer_to_phy(db, channel);
+		/* free this SKB */
+		dev_consume_skb_any(skb);
+	}
 
-	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
-			skb->data, skb->len);
-	dev->stats.tx_bytes += skb->len;
-
+	dev->stats.tx_bytes += len;
 	db->tx_fifo_stat |= 1 << channel;
-	/* TX control: First packet immediately send, second packet queue */
-	if (channel == 0) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
-		       db->membase + EMAC_TX_CTL0_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	} else if (channel == 1) {
-		/* set TX len */
-		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
-		/* start translate from fifo to phy */
-		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
-		       db->membase + EMAC_TX_CTL1_REG);
-
-		/* save the time stamp */
-		netif_trans_update(dev);
-	}
 
 	if ((db->tx_fifo_stat & 3) == 3) {
 		/* Second packet */
@@ -587,9 +654,6 @@ static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_unlock_irqrestore(&db->lock, flags);
 
-	/* free this SKB */
-	dev_consume_skb_any(skb);
-
 	return NETDEV_TX_OK;
 }
 
@@ -637,7 +701,7 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +733,7 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -753,14 +817,14 @@ static void emac_rx(struct net_device *dev)
 }
 
 static irqreturn_t emac_interrupt(int irq, void *dev_id)
-{
+{	
 	struct net_device *dev = dev_id;
 	struct emac_board_info *db = netdev_priv(dev);
 	int int_status;
 	unsigned int reg_val;
 
 	/* A real interrupt coming */
-
+	
 	spin_lock(&db->lock);
 
 	/* Disable all interrupts */
@@ -776,27 +840,29 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
 
 	/* Received the coming packet */
-	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
+	if ((int_status & EMAC_INT_STA_RX_COMPLETE) && (db->emacrx_completed_flag == 1)) {
 		/* carrier lost */
 		db->emacrx_completed_flag = 0;
 		emac_rx(dev);
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE){
+		dev_info(db->dev, "emac tx interrupt, int_status = 0x%x\n", int_status);
 		emac_tx_done(dev, db, int_status);
+	}
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
@@ -904,56 +970,75 @@ static const struct net_device_ops emac_netdev_ops = {
 #endif
 };
 
-static int emac_configure_dma(struct emac_board_info *db)
+static int emac_configure_dma_channel(
+				struct device *dev,
+				const char *name,
+				phys_addr_t const fifo,
+				struct dma_chan **chan)
+{
+	int ret = 0;
+	struct dma_slave_config conf = {
+		.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
+		.dst_maxburst = 4,
+		.src_maxburst = 4,
+		.device_fc = false
+	};
+
+	if (!strcmp(name, "rx")){
+		conf.direction = DMA_DEV_TO_MEM;
+		conf.src_addr = fifo;
+	} else if (!strcmp(name, "tx")) {
+		conf.direction = DMA_MEM_TO_DEV;
+		conf.dst_addr = fifo;
+	} else {
+		dev_err(dev, "emac dma channel must be rx or tx\n");
+		return -EINVAL;
+	}
+
+	*chan = dma_request_chan(dev, name);
+	ret = IS_ERR(*chan);
+	if (ret){
+		dev_err(dev, "request dma channel %s failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		*chan = NULL;
+		return ret;
+	}
+
+	ret = dmaengine_slave_config(*chan, &conf);
+	if (ret) {
+		dev_err(dev, "config %s dma slave failed, ret = %d."
+				" dma %s channel is disabled\n", name, ret, name);
+		dma_release_channel(*chan);
+		*chan = NULL;
+	}
+
+	return ret;
+}
+
+static void emac_configure_dma(struct emac_board_info *db)
 {
 	struct platform_device *pdev = db->pdev;
-	struct net_device *ndev = db->ndev;
-	struct dma_slave_config conf = {};
+	struct device* dev = db->dev;
 	struct resource *regs;
-	int err = 0;
+
+	db->rx_chan = NULL;
+	db->tx_chan = NULL;
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!regs) {
-		netdev_err(ndev, "get io resource from device failed.\n");
-		err = -ENOMEM;
-		goto out_clear_chan;
+		dev_err(dev, "get io resource from device failed.\n");
+		return;
 	}
 
-	netdev_info(ndev, "get io resource from device: 0x%x, size = %u\n",
+	dev_info(dev, "get io resource from device: 0x%x, size = %u\n",
 		    regs->start, resource_size(regs));
-	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
-
-	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
-	if (IS_ERR(db->rx_chan)) {
-		netdev_err(ndev,
-			   "failed to request dma channel. dma is disabled\n");
-		err = PTR_ERR(db->rx_chan);
-		goto out_clear_chan;
-	}
-
-	conf.direction = DMA_DEV_TO_MEM;
-	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
-	conf.src_addr = db->emac_rx_fifo;
-	conf.dst_maxburst = 4;
-	conf.src_maxburst = 4;
-	conf.device_fc = false;
-
-	err = dmaengine_slave_config(db->rx_chan, &conf);
-	if (err) {
-		netdev_err(ndev, "config dma slave failed\n");
-		err = -EINVAL;
-		goto out_slave_configure_err;
-	}
 
-	return err;
-
-out_slave_configure_err:
-	dma_release_channel(db->rx_chan);
+	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
+	db->emac_tx_fifo = regs->start + EMAC_TX_IO_DATA_REG;
 
-out_clear_chan:
-	db->rx_chan = NULL;
-	return err;
+	emac_configure_dma_channel(dev, "rx", db->emac_rx_fifo, &db->rx_chan);
+	emac_configure_dma_channel(dev, "tx", db->emac_tx_fifo, &db->tx_chan);
 }
 
 /* Search EMAC board, allocate space and register it
@@ -998,8 +1083,7 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
-	if (emac_configure_dma(db))
-		netdev_info(ndev, "configure dma failed. disable dma.\n");
+	emac_configure_dma(db);
 
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
@@ -1038,6 +1122,7 @@ static int emac_probe(struct platform_device *pdev)
 	}
 
 	db->emacrx_completed_flag = 1;
+	db->emactx_completed_flag = 1;
 	emac_powerup(ndev);
 	emac_reset(db);
 
@@ -1088,6 +1173,11 @@ static int emac_remove(struct platform_device *pdev)
 		dma_release_channel(db->rx_chan);
 	}
 
+	if (db->tx_chan){
+		dmaengine_terminate_all(db->tx_chan);
+		dma_release_channel(db->tx_chan);
+	}
+
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..14914110d9b0 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -61,7 +61,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
-- 
2.31.1



From mkl at pengutronix.de  Sun Jan  9 03:35:04 2022
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sun,  9 Jan 2022 12:35:04 +0100
Subject: [PATCH] arm64: vdso: fix "no previous prototype" warning
Message-ID: <20220109113504.1921017-1-mkl@pengutronix.de>

If compiling the arm64 kernel with W=1 the following warning is produced:

| arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
|     9 | int __kernel_clock_gettime(clockid_t clock,
|       |     ^~~~~~~~~~~~~~~~~~~~~~
| arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
|    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
|       |     ^~~~~~~~~~~~~~~~~~~~~
| arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
|    21 | int __kernel_clock_getres(clockid_t clock_id,
|       |     ^~~~~~~~~~~~~~~~~~~~~

This patch adds the missing prototype to fix the warning and make
compilation with "CONFIG_WERROR=y" possible.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Vincenzo Frascino <vincenzo.frascino at arm.com>
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
---
 arch/arm64/kernel/vdso/vgettimeofday.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
index 4236cf34d7d9..cc37674b9d35 100644
--- a/arch/arm64/kernel/vdso/vgettimeofday.c
+++ b/arch/arm64/kernel/vdso/vgettimeofday.c
@@ -6,18 +6,27 @@
  *
  */
 
+int __kernel_clock_gettime(clockid_t clock,
+			   struct __kernel_timespec *ts);
+
 int __kernel_clock_gettime(clockid_t clock,
 			   struct __kernel_timespec *ts)
 {
 	return __cvdso_clock_gettime(clock, ts);
 }
 
+int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
+			  struct timezone *tz);
+
 int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
 			  struct timezone *tz)
 {
 	return __cvdso_gettimeofday(tv, tz);
 }
 
+int __kernel_clock_getres(clockid_t clock_id,
+			  struct __kernel_timespec *res);
+
 int __kernel_clock_getres(clockid_t clock_id,
 			  struct __kernel_timespec *res)
 {
-- 
2.34.1




From alistair at alistair23.me  Sun Jan  9 03:41:18 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:41:18 +1000
Subject: [PATCH 0/2] watchdog: imx_wdt2: Enable ping on suspend support
Message-ID: <20220109114120.386013-1-alistair@alistair23.me>

When running Linux on the reMarkable2 tablet the device reboots two
minutes after suspend. This is because we don't go into low power
mode so the watchdog timer is still running and triggers a reboot.

This series adds optional support for ping on suspend for the
i.MX watchdog timer and then enables it for the reMarkable2 tablet.

Alistair Francis (2):
  watchdog: imx2_wdg: Alow ping on suspend
  ARM: dts: imx7d: remarkable2: set ping-during-suspend for watchdog

 .../bindings/watchdog/fsl-imx-wdt.yaml        |  7 ++++++
 arch/arm/boot/dts/imx7d-remarkable2.dts       |  1 +
 drivers/watchdog/imx2_wdt.c                   | 22 +++++++++++++------
 3 files changed, 23 insertions(+), 7 deletions(-)

-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:41:19 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:41:19 +1000
Subject: [PATCH 1/2] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <20220109114120.386013-1-alistair@alistair23.me>
References: <20220109114120.386013-1-alistair@alistair23.me>
Message-ID: <20220109114120.386013-2-alistair@alistair23.me>

The i.MX watchdog cannot be disabled by softwrae once it has been
enabled. This means that it can't be stopped before suspend.

For systems that enter low power mode this is fine, as the watchdog will
be automatically stopped by hardwrae in low power mode. Not all i.MX
platforms support low power mode in the mainline kernel. For example the
i.MX7D does not enter low power mode and so will be rebooted 2 minutes
after entering freeze or mem sleep states.

This patch introduces a device tree property "fsl,ping-during-suspend"
that can be used to enable ping on suspend support for these systems.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 .../bindings/watchdog/fsl-imx-wdt.yaml        |  7 ++++++
 drivers/watchdog/imx2_wdt.c                   | 22 +++++++++++++------
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
index fb7695515be1..b8660a3c456c 100644
--- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
@@ -55,6 +55,13 @@ properties:
       If present, the watchdog device is configured to assert its
       external reset (WDOG_B) instead of issuing a software reset.
 
+  fsl,ping-during-suspend:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: |
+      If present, the kernel will ping the watchdog during suspend.
+      This should be used on platforms that don't enter low power mode
+      during suspend.
+
 required:
   - compatible
   - interrupts
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 51bfb796898b..9a5fdb3173a8 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -66,6 +66,7 @@ struct imx2_wdt_device {
 	struct watchdog_device wdog;
 	bool ext_reset;
 	bool clk_is_on;
+	bool no_ping;
 };
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -312,12 +313,14 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
 
 	wdev->ext_reset = of_property_read_bool(dev->of_node,
 						"fsl,ext-reset-output");
+	wdev->no_ping = !of_property_read_bool(dev->of_node, "fsl,ping-during-suspend");
 	platform_set_drvdata(pdev, wdog);
 	watchdog_set_drvdata(wdog, wdev);
 	watchdog_set_nowayout(wdog, nowayout);
 	watchdog_set_restart_priority(wdog, 128);
 	watchdog_init_timeout(wdog, timeout, dev);
-	watchdog_stop_ping_on_suspend(wdog);
+	if (wdev->no_ping)
+		watchdog_stop_ping_on_suspend(wdog);
 
 	if (imx2_wdt_is_running(wdev)) {
 		imx2_wdt_set_timeout(wdog, wdog->timeout);
@@ -366,9 +369,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
 		imx2_wdt_ping(wdog);
 	}
 
-	clk_disable_unprepare(wdev->clk);
+	if (wdev->no_ping) {
+		clk_disable_unprepare(wdev->clk);
 
-	wdev->clk_is_on = false;
+		wdev->clk_is_on = false;
+	}
 
 	return 0;
 }
@@ -380,11 +385,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
 	int ret;
 
-	ret = clk_prepare_enable(wdev->clk);
-	if (ret)
-		return ret;
+	if (wdev->no_ping) {
+		ret = clk_prepare_enable(wdev->clk);
 
-	wdev->clk_is_on = true;
+		if (ret)
+			return ret;
+
+		wdev->clk_is_on = true;
+	}
 
 	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
 		/*
-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:41:20 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:41:20 +1000
Subject: [PATCH 2/2] ARM: dts: imx7d: remarkable2: set ping-during-suspend for
 watchdog
In-Reply-To: <20220109114120.386013-1-alistair@alistair23.me>
References: <20220109114120.386013-1-alistair@alistair23.me>
Message-ID: <20220109114120.386013-3-alistair@alistair23.me>

Set ping-during-suspend for the reMarkable watchdog timer to avoid the
device rebooting when asleep.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/boot/dts/imx7d-remarkable2.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/imx7d-remarkable2.dts b/arch/arm/boot/dts/imx7d-remarkable2.dts
index 89cbf13097a4..99a453108af7 100644
--- a/arch/arm/boot/dts/imx7d-remarkable2.dts
+++ b/arch/arm/boot/dts/imx7d-remarkable2.dts
@@ -115,6 +115,7 @@ &wdog1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_wdog>;
 	fsl,ext-reset-output;
+	fsl,ping-during-suspend;
 };
 
 &iomuxc {
-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:53:27 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:53:27 +1000
Subject: [PATCH v5 0/4] Add support for the Cypress cyttsp5
Message-ID: <20220109115331.388633-1-alistair@alistair23.me>

This patch series builds on top of [1] and adds support for the cyttsp5
touchscreen controller for the reMarkable 2.

I first tried to add an I2C HID device. Although the cyttsp5 has some HID
looking aspects it is not HID compatible. Just in trying to probe the device
I found:
 - The HID descriptor has extra padding
 - The HID descriptor sets the high bytes of the descriptor length
 - The HID descriptor has extra unrecognised tags
 - The HID reset command doesn't appear to work

I don't think there is a way to use the I2C HID framework with the cyttsp5.
For anyone interested you can see the work here [2]. In that branch though I
can only obtain a HID descriptor, nothing else works without more core
changes.

So instead I rebased the series from [1]. Converted to the new yaml DTS
documentation, added regulator support and fixed a x/y miscalculation bug.

1: https://lwn.net/ml/linux-kernel/20180703094309.18514-1-mylene.josserand at bootlin.com/
2: https://github.com/alistair23/linux/commits/rM2-mainline-cyttsp5-hid

v5:
 - Address review comments from v4

Alistair Francis (2):
  ARM: imx_v6_v7_defconfig: Enable the cyttsp5 touchscreen
  ARM: dts: imx7d-remarkable2: Enable the cyttsp5

Myl?ne Josserand (2):
  Input: Add driver for Cypress Generation 5 touchscreen
  dt-bindings: input: Add Cypress TT2100 touchscreen controller

 .../input/touchscreen/cypress,tt21000.yaml    |  92 ++
 arch/arm/boot/dts/imx7d-remarkable2.dts       |  89 ++
 arch/arm/configs/imx_v6_v7_defconfig          |   1 +
 drivers/input/touchscreen/Kconfig             |  16 +
 drivers/input/touchscreen/Makefile            |   1 +
 drivers/input/touchscreen/cyttsp5.c           | 902 ++++++++++++++++++
 6 files changed, 1101 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
 create mode 100644 drivers/input/touchscreen/cyttsp5.c

-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:53:28 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:53:28 +1000
Subject: [PATCH v5 1/4] Input: Add driver for Cypress Generation 5 touchscreen
In-Reply-To: <20220109115331.388633-1-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
Message-ID: <20220109115331.388633-2-alistair@alistair23.me>

From: Myl?ne Josserand <mylene.josserand at bootlin.com>

This is the basic driver for the Cypress TrueTouch Gen5 touchscreen
controllers. This driver supports only the I2C bus but it uses regmap
so SPI support could be added later.
The touchscreen can retrieve some defined zone that are handled as
buttons (according to the hardware). That is why it handles
button and multitouch events.

Reviewed-by: Maxime Ripard <maxime.ripard at bootlin.com>
Signed-off-by: Myl?ne Josserand <mylene.josserand at bootlin.com>
Signed-off-by: Alistair Francis <alistair at alistair23.me>
Tested-by: Andreas Kemnade <andreas at kemnade.info> # Kobo Clara HD
---
 drivers/input/touchscreen/Kconfig   |  16 +
 drivers/input/touchscreen/Makefile  |   1 +
 drivers/input/touchscreen/cyttsp5.c | 902 ++++++++++++++++++++++++++++
 3 files changed, 919 insertions(+)
 create mode 100644 drivers/input/touchscreen/cyttsp5.c

diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2f6adfb7b938..eb4e1b156683 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -284,6 +284,22 @@ config TOUCHSCREEN_CYTTSP4_SPI
 	  To compile this driver as a module, choose M here: the
 	  module will be called cyttsp4_spi.
 
+config TOUCHSCREEN_CYTTSP5
+	tristate "Cypress TrueTouch Gen5 Touchscreen Driver"
+	depends on I2C
+	select REGMAP_I2C
+	select CRC_ITU_T
+	help
+	  Driver for Parade TrueTouch Standard Product Generation 5
+	  touchscreen controllers. I2C bus interface support only.
+
+	  Say Y here if you have a Cypress Gen5 touchscreen.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cyttsp5.
+
 config TOUCHSCREEN_DA9034
 	tristate "Touchscreen support for Dialog Semiconductor DA9034"
 	depends on PMIC_DA903X
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index 39a8127cf6a5..0ea5c47f7fd9 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI)	+= cyttsp_spi.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_CORE)	+= cyttsp4_core.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_I2C)	+= cyttsp4_i2c.o cyttsp_i2c_common.o
 obj-$(CONFIG_TOUCHSCREEN_CYTTSP4_SPI)	+= cyttsp4_spi.o
+obj-$(CONFIG_TOUCHSCREEN_CYTTSP5)	+= cyttsp5.o
 obj-$(CONFIG_TOUCHSCREEN_DA9034)	+= da9034-ts.o
 obj-$(CONFIG_TOUCHSCREEN_DA9052)	+= da9052_tsi.o
 obj-$(CONFIG_TOUCHSCREEN_DYNAPRO)	+= dynapro.o
diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c
new file mode 100644
index 000000000000..3ac45108090c
--- /dev/null
+++ b/drivers/input/touchscreen/cyttsp5.c
@@ -0,0 +1,902 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Parade TrueTouch(TM) Standard Product V5 Module.
+ *
+ * Copyright (C) 2015 Parade Technologies
+ * Copyright (C) 2012-2015 Cypress Semiconductor
+ * Copyright (C) 2018 Bootlin
+ *
+ * Authors: Myl?ne Josserand <mylene.josserand at bootlin.com>
+ *                Alistair Francis <alistair at alistair23.me>
+ */
+
+#include <linux/crc-itu-t.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <asm/unaligned.h>
+
+#define CYTTSP5_NAME				"cyttsp5"
+#define CY_I2C_DATA_SIZE			(2 * 256)
+#define HID_VERSION				0x0100
+#define CY_MAX_INPUT				512
+#define CYTTSP5_PREALLOCATED_CMD_BUFFER	32
+#define CY_BITS_PER_BTN			1
+#define CY_NUM_BTN_EVENT_ID			GENMASK(CY_BITS_PER_BTN, 0)
+
+#define MAX_AREA				255
+#define HID_OUTPUT_BL_SOP			0x1
+#define HID_OUTPUT_BL_EOP			0x17
+#define HID_OUTPUT_BL_LAUNCH_APP		0x3B
+#define HID_OUTPUT_BL_LAUNCH_APP_SIZE		11
+#define HID_OUTPUT_GET_SYSINFO			0x2
+#define HID_OUTPUT_GET_SYSINFO_SIZE		5
+#define HID_OUTPUT_MAX_CMD_SIZE		12
+
+#define HID_DESC_REG				0x1
+#define HID_INPUT_REG				0x3
+#define HID_OUTPUT_REG				0x4
+
+#define REPORT_ID_TOUCH			0x1
+#define REPORT_ID_BTN				0x3
+#define REPORT_SIZE_5				5
+#define REPORT_SIZE_8				8
+#define REPORT_SIZE_16				16
+
+/* Touch reports offsets */
+/* Header offsets */
+#define TOUCH_REPORT_DESC_HDR_CONTACTCOUNT	16
+/* Record offsets */
+#define TOUCH_REPORT_DESC_CONTACTID		8
+#define TOUCH_REPORT_DESC_X			16
+#define TOUCH_REPORT_DESC_Y			32
+#define TOUCH_REPORT_DESC_P			48
+#define TOUCH_REPORT_DESC_MAJ			56
+#define TOUCH_REPORT_DESC_MIN			64
+
+/* HID */
+#define HID_TOUCH_REPORT_ID			0x1
+#define HID_BTN_REPORT_ID			0x3
+#define HID_APP_RESPONSE_REPORT_ID		0x1F
+#define HID_APP_OUTPUT_REPORT_ID		0x2F
+#define HID_BL_RESPONSE_REPORT_ID		0x30
+#define HID_BL_OUTPUT_REPORT_ID		0x40
+
+#define HID_OUTPUT_RESPONSE_REPORT_OFFSET	2
+#define HID_OUTPUT_RESPONSE_CMD_OFFSET		4
+#define HID_OUTPUT_RESPONSE_CMD_MASK		GENMASK(6, 0)
+
+#define HID_SYSINFO_SENSING_OFFSET		33
+#define HID_SYSINFO_BTN_OFFSET			48
+#define HID_SYSINFO_BTN_MASK			GENMASK(7, 0)
+#define HID_SYSINFO_MAX_BTN			8
+
+#define CY_HID_OUTPUT_TIMEOUT_MS			200
+#define CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS	3000
+#define CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS	4000
+
+/* maximum number of concurrent tracks */
+#define TOUCH_REPORT_SIZE			10
+#define TOUCH_INPUT_HEADER_SIZE		7
+#define BTN_REPORT_SIZE			9
+#define BTN_INPUT_HEADER_SIZE			5
+
+#define MAX_CY_TCH_T_IDS	32
+
+/* All usage pages for Touch Report */
+#define TOUCH_REPORT_USAGE_PG_X		0x00010030
+#define TOUCH_REPORT_USAGE_PG_Y		0x00010031
+#define TOUCH_REPORT_USAGE_PG_P		0x000D0030
+#define TOUCH_REPORT_USAGE_PG_CONTACTID	0x000D0051
+#define TOUCH_REPORT_USAGE_PG_CONTACTCOUNT	0x000D0054
+#define TOUCH_REPORT_USAGE_PG_MAJ		0xFF010062
+#define TOUCH_REPORT_USAGE_PG_MIN		0xFF010063
+#define TOUCH_COL_USAGE_PG			0x000D0022
+
+/* System Information interface definitions */
+struct cyttsp5_sensing_conf_data_dev {
+	u8 electrodes_x;
+	u8 electrodes_y;
+	__le16 len_x;
+	__le16 len_y;
+	__le16 res_x;
+	__le16 res_y;
+	__le16 max_z;
+	u8 origin_x;
+	u8 origin_y;
+	u8 btn;
+	u8 scan_mode;
+	u8 max_num_of_tch_per_refresh_cycle;
+} __packed;
+
+struct cyttsp5_sensing_conf_data {
+	u16 res_x;
+	u16 res_y;
+	u16 max_z;
+	u16 len_x;
+	u16 len_y;
+	u8 origin_x;
+	u8 origin_y;
+	u8 max_tch;
+};
+
+enum cyttsp5_tch_abs {	/* for ordering within the extracted touch data array */
+	CY_TCH_X,	/* X */
+	CY_TCH_Y,	/* Y */
+	CY_TCH_P,	/* P (Z) */
+	CY_TCH_T,	/* TOUCH ID */
+	CY_TCH_MAJ,	/* TOUCH_MAJOR */
+	CY_TCH_MIN,	/* TOUCH_MINOR */
+	CY_TCH_NUM_ABS
+};
+
+struct cyttsp5_tch_abs_params {
+	size_t ofs;	/* abs byte offset */
+	size_t size;	/* size in bits */
+	size_t min;	/* min value */
+	size_t max;	/* max value */
+	size_t bofs;	/* bit offset */
+};
+
+struct cyttsp5_touch {
+	int abs[CY_TCH_NUM_ABS];
+};
+
+struct cyttsp5_sysinfo {
+	struct cyttsp5_sensing_conf_data sensing_conf_data;
+	int num_btns;
+	struct cyttsp5_tch_abs_params tch_hdr;
+	struct cyttsp5_tch_abs_params tch_abs[CY_TCH_NUM_ABS];
+	u32 key_code[HID_SYSINFO_MAX_BTN];
+};
+
+struct cyttsp5_hid_desc {
+	__le16 hid_desc_len;
+	u8 packet_id;
+	u8 reserved_byte;
+	__le16 bcd_version;
+	__le16 report_desc_len;
+	__le16 report_desc_register;
+	__le16 input_register;
+	__le16 max_input_len;
+	__le16 output_register;
+	__le16 max_output_len;
+	__le16 command_register;
+	__le16 data_register;
+	__le16 vendor_id;
+	__le16 product_id;
+	__le16 version_id;
+	u8 reserved[4];
+} __packed;
+
+struct cyttsp5 {
+	struct device *dev;
+	struct completion cmd_done;
+	struct cyttsp5_sysinfo sysinfo;
+	struct cyttsp5_hid_desc hid_desc;
+	u8 cmd_buf[CYTTSP5_PREALLOCATED_CMD_BUFFER];
+	u8 input_buf[CY_MAX_INPUT];
+	u8 response_buf[CY_MAX_INPUT];
+	struct gpio_desc *reset_gpio;
+	struct input_dev *input;
+	char phys[NAME_MAX];
+	int num_prv_rec;
+	struct regmap *regmap;
+	struct touchscreen_properties prop;
+	struct regulator *vdd;
+};
+
+/*
+ * For what is understood in the datasheet, the register does not
+ * matter. For consistency, use the Input Register address
+ * but it does mean anything to the device. The important data
+ * to send is the I2C address
+ */
+static int cyttsp5_read(struct cyttsp5 *ts, u8 *buf, u32 max)
+{
+	int error;
+	u32 size;
+	u8 temp[2];
+
+	/* Read the frame to retrieve the size */
+	error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, temp, sizeof(temp));
+	if (error)
+		return error;
+
+	size = get_unaligned_le16(temp);
+	if (!size || size == 2)
+		return 0;
+
+	if (size > max)
+		return -EINVAL;
+
+	/* Get the real value */
+	return regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, size);
+}
+
+static int cyttsp5_write(struct cyttsp5 *ts, unsigned int reg, u8 *data,
+			 size_t size)
+{
+	u8 cmd[HID_OUTPUT_MAX_CMD_SIZE];
+
+	if (size + 1 > HID_OUTPUT_MAX_CMD_SIZE)
+		return -E2BIG;
+
+	/* High bytes of register address needed as first byte of cmd */
+	cmd[0] = (reg >> 8) & 0xFF ;
+
+	/* Copy the rest of the data */
+	if (data)
+		memcpy(&cmd[1], data, size);
+
+	/*
+	 * The hardware wants to receive a frame with the address register
+	 * contained in the first two bytes. As the regmap_write function
+	 * add the register adresse in the frame, we use the low byte as
+	 * first frame byte for the address register and the first
+	 * data byte is the high register + left of the cmd to send
+	 */
+	return regmap_bulk_write(ts->regmap, reg & 0xFF, cmd, size + 1);
+}
+
+static void cyttsp5_get_touch_axis(int *axis, int size, int max, u8 *xy_data,
+				   int bofs)
+{
+	int nbyte;
+
+	for (nbyte = 0, *axis = 0; nbyte < size; nbyte++)
+		*axis += ((xy_data[nbyte] >> bofs) << (nbyte * 8));
+
+	*axis &= max - 1;
+}
+
+static void cyttsp5_get_touch_record(struct cyttsp5 *ts,
+				     struct cyttsp5_touch *touch, u8 *xy_data)
+{
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	enum cyttsp5_tch_abs abs;
+
+	for (abs = CY_TCH_X; abs < CY_TCH_NUM_ABS; abs++)
+		cyttsp5_get_touch_axis(&touch->abs[abs],
+				       si->tch_abs[abs].size,
+				       si->tch_abs[abs].max,
+				       xy_data + si->tch_abs[abs].ofs,
+				       si->tch_abs[abs].bofs);
+}
+
+static void cyttsp5_get_mt_touches(struct cyttsp5 *ts,
+				   struct cyttsp5_touch *tch, int num_cur_tch)
+{
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	int i, t = 0, offset = 0;
+	DECLARE_BITMAP(ids, MAX_CY_TCH_T_IDS);
+	u8 *tch_addr;
+	int tmp;
+
+	bitmap_zero(ids, MAX_CY_TCH_T_IDS);
+	memset(tch->abs, 0, sizeof(tch->abs));
+
+	switch (ts->input_buf[2]) {
+	case HID_TOUCH_REPORT_ID:
+		offset = TOUCH_INPUT_HEADER_SIZE;
+		break;
+	case HID_BTN_REPORT_ID:
+		offset = BTN_INPUT_HEADER_SIZE;
+		break;
+	}
+
+	for (i = 0; i < num_cur_tch; i++) {
+		tch_addr = ts->input_buf + offset + (i * TOUCH_REPORT_SIZE);
+		cyttsp5_get_touch_record(ts, tch, tch_addr);
+
+		/* Convert MAJOR/MINOR from mm to resolution */
+		tmp = tch->abs[CY_TCH_MAJ] * 100 * si->sensing_conf_data.res_x;
+		tch->abs[CY_TCH_MAJ] = tmp / si->sensing_conf_data.len_x;
+		tmp = tch->abs[CY_TCH_MIN] * 100 * si->sensing_conf_data.res_x;
+		tch->abs[CY_TCH_MIN] = tmp / si->sensing_conf_data.len_x;
+
+		t = tch->abs[CY_TCH_T];
+		input_mt_slot(ts->input, t);
+		input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true);
+		__set_bit(t, ids);
+
+		/* position and pressure fields */
+		touchscreen_report_pos(ts->input, &ts->prop,
+				       tch->abs[CY_TCH_X], tch->abs[CY_TCH_Y],
+				       true);
+		input_report_abs(ts->input, ABS_MT_PRESSURE,
+				 tch->abs[CY_TCH_P]);
+
+		/* Get the extended touch fields */
+		input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,
+				 tch->abs[CY_TCH_MAJ]);
+		input_report_abs(ts->input, ABS_MT_TOUCH_MINOR,
+				 tch->abs[CY_TCH_MIN]);
+	}
+
+	ts->num_prv_rec = num_cur_tch;
+}
+
+static int cyttsp5_mt_attention(struct device *dev)
+{
+	struct cyttsp5 *ts = dev_get_drvdata(dev);
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	int max_tch = si->sensing_conf_data.max_tch;
+	struct cyttsp5_touch tch;
+	u8 num_cur_tch;
+
+	cyttsp5_get_touch_axis((int *) &num_cur_tch, si->tch_hdr.size,
+			       si->tch_hdr.max,
+			       ts->input_buf + 3 + si->tch_hdr.ofs,
+			       si->tch_hdr.bofs);
+
+	if (num_cur_tch > max_tch) {
+		dev_err(dev, "Num touch err detected (n=%d)\n", num_cur_tch);
+		num_cur_tch = max_tch;
+	}
+
+	if (num_cur_tch == 0 && ts->num_prv_rec == 0)
+		return 0;
+
+	/* extract xy_data for all currently reported touches */
+	if (num_cur_tch)
+		cyttsp5_get_mt_touches(ts, &tch, num_cur_tch);
+
+	input_mt_sync_frame(ts->input);
+	input_sync(ts->input);
+
+	return 0;
+}
+
+static int cyttsp5_setup_input_device(struct device *dev)
+{
+	struct cyttsp5 *ts = dev_get_drvdata(dev);
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	int max_x, max_y, max_p;
+	int max_x_tmp, max_y_tmp;
+	int error;
+
+	max_x_tmp = si->sensing_conf_data.res_x;
+	max_y_tmp = si->sensing_conf_data.res_y;
+	max_x = max_x_tmp - 1;
+	max_y = max_y_tmp - 1;
+	max_p = si->sensing_conf_data.max_z;
+
+	input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
+	input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
+	input_set_abs_params(ts->input, ABS_MT_PRESSURE, 0, max_p, 0, 0);
+
+	input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, MAX_AREA, 0, 0);
+	input_set_abs_params(ts->input, ABS_MT_TOUCH_MINOR, 0, MAX_AREA, 0, 0);
+
+	error = input_mt_init_slots(ts->input, si->tch_abs[CY_TCH_T].max,
+		INPUT_MT_DROP_UNUSED | INPUT_MT_DIRECT);
+	if (error < 0)
+		return error;
+
+	error = input_register_device(ts->input);
+	if (error < 0)
+		dev_err(dev, "Error, failed register input device r=%d\n", error);
+
+	return error;
+}
+
+static int cyttsp5_parse_dt_key_code(struct device *dev)
+{
+	struct cyttsp5 *ts = dev_get_drvdata(dev);
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+
+	if (!si->num_btns)
+		return 0;
+
+	/* Initialize the button to RESERVED */
+	memset32(si->key_code, KEY_RESERVED,  si->num_btns);
+
+	return device_property_read_u32_array(dev, "linux,keycodes",
+				   si->key_code, si->num_btns);
+}
+
+static int cyttsp5_btn_attention(struct device *dev)
+{
+	struct cyttsp5 *ts = dev_get_drvdata(dev);
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	int cur_btn, offset = 0;
+	int cur_btn_state;
+
+	switch (ts->input_buf[2]) {
+	case HID_TOUCH_REPORT_ID:
+		offset = TOUCH_INPUT_HEADER_SIZE;
+		break;
+	case HID_BTN_REPORT_ID:
+		offset = BTN_INPUT_HEADER_SIZE;
+		break;
+	}
+
+	if (ts->input_buf[2] != HID_BTN_REPORT_ID || !si->num_btns)
+		return 0;
+
+	/* extract button press/release touch information */
+	for (cur_btn = 0; cur_btn < si->num_btns; cur_btn++) {
+		/* Get current button state */
+		cur_btn_state = (ts->input_buf[offset] >> (cur_btn * CY_BITS_PER_BTN))
+			& CY_NUM_BTN_EVENT_ID;
+
+		input_report_key(ts->input, si->key_code[cur_btn],
+				 cur_btn_state);
+		input_sync(ts->input);
+	}
+
+	return 0;
+}
+
+static int cyttsp5_validate_cmd_response(struct cyttsp5 *ts, u8 code)
+{
+	u16 size, crc;
+	u8 status, report_id;
+	int command_code;
+
+	size = get_unaligned_le16(&ts->response_buf[0]);
+
+	if (!size)
+		return 0;
+
+	report_id = ts->response_buf[HID_OUTPUT_RESPONSE_REPORT_OFFSET];
+
+	switch (report_id) {
+	case HID_BL_RESPONSE_REPORT_ID: {
+		if (ts->response_buf[4] != HID_OUTPUT_BL_SOP) {
+			dev_err(ts->dev, "HID output response, wrong SOP\n");
+			return -EPROTO;
+		}
+
+		if (ts->response_buf[size - 1] != HID_OUTPUT_BL_EOP) {
+			dev_err(ts->dev, "HID output response, wrong EOP\n");
+			return -EPROTO;
+		}
+
+		crc = crc_itu_t(0xFFFF, &ts->response_buf[4], size - 7);
+		if (get_unaligned_le16(&ts->response_buf[size - 3]) != crc) {
+			dev_err(ts->dev, "HID output response, wrong CRC 0x%X\n",
+				crc);
+			return -EPROTO;
+		}
+
+		status = ts->response_buf[5];
+		if (status) {
+			dev_err(ts->dev, "HID output response, ERROR:%d\n",
+				status);
+			return -EPROTO;
+		}
+		break;
+	}
+	case HID_APP_RESPONSE_REPORT_ID: {
+		command_code = ts->response_buf[HID_OUTPUT_RESPONSE_CMD_OFFSET]
+			& HID_OUTPUT_RESPONSE_CMD_MASK;
+		if (command_code != code) {
+			dev_err(ts->dev,
+				"HID output response, wrong command_code:%X\n",
+				command_code);
+			return -EPROTO;
+		}
+		break;
+	}
+	}
+
+	return 0;
+}
+
+static void cyttsp5_si_get_btn_data(struct cyttsp5 *ts)
+{
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+	unsigned int btns = ts->response_buf[HID_SYSINFO_BTN_OFFSET]
+		& HID_SYSINFO_BTN_MASK;
+
+	si->num_btns = hweight8(btns);
+}
+
+static int cyttsp5_get_sysinfo_regs(struct cyttsp5 *ts)
+{
+	struct cyttsp5_sensing_conf_data *scd = &ts->sysinfo.sensing_conf_data;
+	struct cyttsp5_sensing_conf_data_dev *scd_dev =
+		(struct cyttsp5_sensing_conf_data_dev *)
+		&ts->response_buf[HID_SYSINFO_SENSING_OFFSET];
+
+	cyttsp5_si_get_btn_data(ts);
+
+	scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle;
+	scd->res_x = get_unaligned_le16(&scd_dev->res_x);
+	scd->res_y = get_unaligned_le16(&scd_dev->res_y);
+	scd->max_z = get_unaligned_le16(&scd_dev->max_z);
+	scd->len_x = get_unaligned_le16(&scd_dev->len_x);
+	scd->len_y = get_unaligned_le16(&scd_dev->len_y);
+
+	return 0;
+}
+
+static int cyttsp5_hid_output_get_sysinfo(struct cyttsp5 *ts)
+{
+	int rc;
+	u8 cmd[HID_OUTPUT_GET_SYSINFO_SIZE];
+
+	/* HI bytes of Output register address */
+	put_unaligned_le16(HID_OUTPUT_GET_SYSINFO_SIZE, cmd);
+	cmd[2] = HID_APP_OUTPUT_REPORT_ID;
+	cmd[3] = 0x0; /* Reserved */
+	cmd[4] = HID_OUTPUT_GET_SYSINFO;
+
+	rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
+			   HID_OUTPUT_GET_SYSINFO_SIZE);
+	if (rc) {
+		dev_err(ts->dev, "Failed to write command %d", rc);
+		return rc;
+	}
+
+	rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+						msecs_to_jiffies(CY_HID_OUTPUT_GET_SYSINFO_TIMEOUT_MS));
+	if (rc <= 0) {
+		dev_err(ts->dev, "HID output cmd execution timed out\n");
+		rc = -ETIMEDOUT;
+		return rc;
+	}
+
+	rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_GET_SYSINFO);
+	if (rc) {
+		dev_err(ts->dev, "Validation of the response failed\n");
+		return rc;
+	}
+
+	return cyttsp5_get_sysinfo_regs(ts);
+}
+
+static int cyttsp5_hid_output_bl_launch_app(struct cyttsp5 *ts)
+{
+	int rc;
+	u8 cmd[HID_OUTPUT_BL_LAUNCH_APP];
+	u16 crc;
+
+	put_unaligned_le16(HID_OUTPUT_BL_LAUNCH_APP_SIZE, cmd);
+	cmd[2] = HID_BL_OUTPUT_REPORT_ID;
+	cmd[3] = 0x0; /* Reserved */
+	cmd[4] = HID_OUTPUT_BL_SOP;
+	cmd[5] = HID_OUTPUT_BL_LAUNCH_APP;
+	put_unaligned_le16(0x00, &cmd[6]);
+	crc = crc_itu_t(0xFFFF, &cmd[4], 4);
+	put_unaligned_le16(crc, &cmd[8]);
+	cmd[10] = HID_OUTPUT_BL_EOP;
+
+	rc = cyttsp5_write(ts, HID_OUTPUT_REG, cmd,
+			   HID_OUTPUT_BL_LAUNCH_APP_SIZE);
+	if (rc) {
+		dev_err(ts->dev, "Failed to write command %d", rc);
+		return rc;
+	}
+
+	rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+						msecs_to_jiffies(CY_HID_OUTPUT_TIMEOUT_MS));
+	if (rc <= 0) {
+		dev_err(ts->dev, "HID output cmd execution timed out\n");
+		rc = -ETIMEDOUT;
+		return rc;
+	}
+
+	rc = cyttsp5_validate_cmd_response(ts, HID_OUTPUT_BL_LAUNCH_APP);
+	if (rc) {
+		dev_err(ts->dev, "Validation of the response failed\n");
+		return rc;
+	}
+
+	return 0;
+}
+
+static int cyttsp5_get_hid_descriptor(struct cyttsp5 *ts,
+				      struct cyttsp5_hid_desc *desc)
+{
+	struct device *dev = ts->dev;
+	__le16 hid_desc_register = HID_DESC_REG;
+	int rc;
+	u8 cmd[2];
+
+	/* Set HID descriptor register */
+	memcpy(cmd, &hid_desc_register, sizeof(hid_desc_register));
+
+	rc = cyttsp5_write(ts, HID_DESC_REG, NULL, 0);
+	if (rc) {
+		dev_err(dev, "Failed to get HID descriptor, rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = wait_for_completion_interruptible_timeout(&ts->cmd_done,
+						msecs_to_jiffies(CY_HID_GET_HID_DESCRIPTOR_TIMEOUT_MS));
+	if (rc <= 0) {
+		dev_err(ts->dev, "HID get descriptor timed out\n");
+		rc = -ETIMEDOUT;
+		return rc;
+	}
+
+	memcpy(desc, ts->response_buf, sizeof(*desc));
+
+	/* Check HID descriptor length and version */
+	if (le16_to_cpu(desc->hid_desc_len) != sizeof(*desc) ||
+	    le16_to_cpu(desc->bcd_version) != HID_VERSION) {
+		dev_err(dev, "Unsupported HID version\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int fill_tch_abs(struct cyttsp5_tch_abs_params *tch_abs, int report_size,
+			int offset)
+{
+	tch_abs->ofs = offset / 8;
+	tch_abs->size = report_size / 8;
+	if (report_size % 8)
+		tch_abs->size += 1;
+	tch_abs->min = 0;
+	tch_abs->max = 1 << report_size;
+	tch_abs->bofs = offset - (tch_abs->ofs << 3);
+
+	return 0;
+}
+
+static irqreturn_t cyttsp5_handle_irq(int irq, void *handle)
+{
+	struct cyttsp5 *ts = handle;
+	int report_id;
+	int size;
+	int error;
+
+	error = cyttsp5_read(ts, ts->input_buf, CY_MAX_INPUT);
+	if (error)
+		return IRQ_HANDLED;
+
+	size = get_unaligned_le16(&ts->input_buf[0]);
+	if (size == 0) {
+		/* reset */
+		report_id = 0;
+		size = 2;
+	} else {
+		report_id = ts->input_buf[2];
+	}
+
+	switch (report_id) {
+	case HID_TOUCH_REPORT_ID:
+		cyttsp5_mt_attention(ts->dev);
+		break;
+	case HID_BTN_REPORT_ID:
+		cyttsp5_btn_attention(ts->dev);
+		break;
+	default:
+		/* It is not an input but a command response */
+		memcpy(ts->response_buf, ts->input_buf, size);
+		complete(&ts->cmd_done);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int cyttsp5_deassert_int(struct cyttsp5 *ts)
+{
+	u16 size;
+	u8 buf[2];
+	int error;
+
+	error = regmap_bulk_read(ts->regmap, HID_INPUT_REG, buf, sizeof(buf));
+	if (error < 0)
+		return error;
+
+	size = get_unaligned_le16(&buf[0]);
+	if (size == 2 || size == 0)
+		return 0;
+
+	return -EINVAL;
+}
+
+static int cyttsp5_fill_all_touch(struct cyttsp5 *ts)
+{
+	struct cyttsp5_sysinfo *si = &ts->sysinfo;
+
+	fill_tch_abs(&si->tch_abs[CY_TCH_X], REPORT_SIZE_16,
+		     TOUCH_REPORT_DESC_X);
+	fill_tch_abs(&si->tch_abs[CY_TCH_Y], REPORT_SIZE_16,
+		     TOUCH_REPORT_DESC_Y);
+	fill_tch_abs(&si->tch_abs[CY_TCH_P], REPORT_SIZE_8,
+		     TOUCH_REPORT_DESC_P);
+	fill_tch_abs(&si->tch_abs[CY_TCH_T], REPORT_SIZE_5,
+		     TOUCH_REPORT_DESC_CONTACTID);
+	fill_tch_abs(&si->tch_hdr, REPORT_SIZE_5,
+		     TOUCH_REPORT_DESC_HDR_CONTACTCOUNT);
+	fill_tch_abs(&si->tch_abs[CY_TCH_MAJ], REPORT_SIZE_8,
+		     TOUCH_REPORT_DESC_MAJ);
+	fill_tch_abs(&si->tch_abs[CY_TCH_MIN], REPORT_SIZE_8,
+		     TOUCH_REPORT_DESC_MIN);
+
+	return 0;
+}
+
+static int cyttsp5_startup(struct cyttsp5 *ts)
+{
+	int error;
+
+	error = cyttsp5_deassert_int(ts);
+	if (error) {
+		dev_err(ts->dev, "Error on deassert int r=%d\n", error);
+		return -ENODEV;
+	}
+
+	/*
+	 * Launch the application as the device starts in bootloader mode
+	 * because of a power-on-reset
+	 */
+	error = cyttsp5_hid_output_bl_launch_app(ts);
+	if (error < 0) {
+		dev_err(ts->dev, "Error on launch app r=%d\n", error);
+		return error;
+	}
+
+	error = cyttsp5_get_hid_descriptor(ts, &ts->hid_desc);
+	if (error < 0) {
+		dev_err(ts->dev, "Error on getting HID descriptor r=%d\n", error);
+		return error;
+	}
+
+	error = cyttsp5_fill_all_touch(ts);
+	if (error < 0) {
+		dev_err(ts->dev, "Error on report descriptor r=%d\n", error);
+		return error;
+	}
+
+	error = cyttsp5_hid_output_get_sysinfo(ts);
+	if (error) {
+		dev_err(ts->dev, "Error on getting sysinfo r=%d\n", error);
+		return error;
+	}
+
+	return error;
+}
+
+static void cyttsp5_cleanup(void *data)
+{
+	struct cyttsp5 *ts = data;
+
+	regulator_disable(ts->vdd);
+}
+
+static int cyttsp5_probe(struct device *dev, struct regmap *regmap, int irq,
+			 const char *name)
+{
+	struct cyttsp5 *ts;
+	struct cyttsp5_sysinfo *si;
+	int error, i;
+
+	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
+	if (!ts)
+		return -ENOMEM;
+
+	/* Initialize device info */
+	ts->regmap = regmap;
+	ts->dev = dev;
+	si = &ts->sysinfo;
+	dev_set_drvdata(dev, ts);
+
+	init_completion(&ts->cmd_done);
+
+	/* Power up the device */
+	ts->vdd = devm_regulator_get(dev, "vdd");
+	if (IS_ERR(ts->vdd)) {
+		error = PTR_ERR(ts->vdd);
+		return error;
+	}
+
+	error = devm_add_action_or_reset(dev, cyttsp5_cleanup, ts);
+	if (error) {
+		return error;
+	}
+
+	error = regulator_enable(ts->vdd);
+	if (error) {
+		return error;
+	}
+
+	ts->input = devm_input_allocate_device(dev);
+	if (!ts->input) {
+		dev_err(dev, "Error, failed to allocate input device\n");
+		return -ENODEV;
+	}
+
+	ts->input->name = "cyttsp5";
+	scnprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev));
+	ts->input->phys = ts->phys;
+	input_set_drvdata(ts->input, ts);
+
+	/* Reset the gpio to be in a reset state */
+	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ts->reset_gpio)) {
+		error = PTR_ERR(ts->reset_gpio);
+		dev_err(dev, "Failed to request reset gpio, error %d\n", error);
+		return error;
+	}
+	gpiod_set_value(ts->reset_gpio, 0);
+
+	/* Need a delay to have device up */
+	msleep(20);
+
+	error = devm_request_threaded_irq(dev, irq, NULL, cyttsp5_handle_irq,
+				       IRQF_ONESHOT, name, ts);
+	if (error) {
+		dev_err(dev, "unable to request IRQ\n");
+		return error;
+	}
+
+	error = cyttsp5_startup(ts);
+	if (error) {
+		dev_err(ts->dev, "Fail initial startup r=%d\n", error);
+		return error;
+	}
+
+	error = cyttsp5_parse_dt_key_code(dev);
+	if (error < 0) {
+		dev_err(ts->dev, "Error while parsing dts %d\n", error);
+		return error;
+	}
+
+	touchscreen_parse_properties(ts->input, true, &ts->prop);
+
+	__set_bit(EV_KEY, ts->input->evbit);
+	for (i = 0; i < si->num_btns; i++)
+		__set_bit(si->key_code[i], ts->input->keybit);
+
+	return cyttsp5_setup_input_device(dev);
+}
+
+static int cyttsp5_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct regmap *regmap;
+	static const struct regmap_config config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+	};
+
+	regmap = devm_regmap_init_i2c(client, &config);
+	if (IS_ERR(regmap)) {
+		dev_err(&client->dev, "regmap allocation failed: %ld\n",
+			PTR_ERR(regmap));
+		return PTR_ERR(regmap);
+	}
+
+	return cyttsp5_probe(&client->dev, regmap, client->irq, client->name);
+}
+
+static const struct of_device_id cyttsp5_of_match[] = {
+	{ .compatible = "cypress,tt21000", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
+
+static const struct i2c_device_id cyttsp5_i2c_id[] = {
+	{ CYTTSP5_NAME, 0, },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, cyttsp5_i2c_id);
+
+static struct i2c_driver cyttsp5_i2c_driver = {
+	.driver = {
+		.name = CYTTSP5_NAME,
+		.of_match_table = cyttsp5_of_match,
+	},
+	.probe = cyttsp5_i2c_probe,
+	.id_table = cyttsp5_i2c_id,
+};
+module_i2c_driver(cyttsp5_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Touchscreen driver for Cypress TrueTouch Gen 5 Product");
+MODULE_AUTHOR("Myl?ne Josserand <mylene.josserand at bootlin.com>");
-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:53:29 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:53:29 +1000
Subject: [PATCH v5 2/4] dt-bindings: input: Add Cypress TT2100 touchscreen
 controller
In-Reply-To: <20220109115331.388633-1-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
Message-ID: <20220109115331.388633-3-alistair@alistair23.me>

From: Myl?ne Josserand <mylene.josserand at free-electrons.com>

Add the Cypress TrueTouch Generation 5 touchscreen device tree bindings
documentation. It can use I2C or SPI bus.
This touchscreen can handle some defined zone that are designed and
sent as button. To be able to customize the keycode sent, the
"linux,code" property in a "button" sub-node can be used.

Signed-off-by: Myl?ne Josserand <mylene.josserand at free-electrons.com>
Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 .../input/touchscreen/cypress,tt21000.yaml    | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml

diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
new file mode 100644
index 000000000000..acd2d9389f8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/cypress,tt21000.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cypress TT2100 touchscreen controller
+
+description: The Cypress TT2100 series (also known as "CYTTSP5" after
+  the marketing name Cypress TrueTouch Standard Product series 5).
+
+maintainers:
+  - Alistair Francis <alistair at alistair23.me>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    const: cypress,tt21000
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  vdd-supply:
+    description: Regulator for voltage.
+
+  reset-gpios:
+    maxItems: 1
+
+  linux,code:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: EV_ABS specific event code generated by the axis.
+
+patternProperties:
+  "^button-[0-9]+$":
+    type: object
+    properties:
+      linux,code:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: Keycode to emit
+
+    required:
+      - linux,code
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - vdd-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/input/linux-event-codes.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        touchscreen at 24 {
+            compatible = "cypress,tt21000";
+            reg = <0x24>;
+            pinctrl-names = "default";
+            pinctrl-0 = <&tp_reset_ds203>;
+            interrupt-parent = <&pio>;
+            interrupts = <1 5 IRQ_TYPE_LEVEL_LOW>;
+            reset-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>;
+            vdd-supply = <&reg_touch>;
+
+            button-0 {
+                linux,code = <KEY_HOMEPAGE>;
+            };
+
+            button-1 {
+                linux,code = <KEY_MENU>;
+            };
+
+            button-2 {
+                linux,code = <KEY_BACK>;
+            };
+        };
+    };
+...
-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:53:30 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:53:30 +1000
Subject: [PATCH v5 3/4] ARM: imx_v6_v7_defconfig: Enable the cyttsp5
 touchscreen
In-Reply-To: <20220109115331.388633-1-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
Message-ID: <20220109115331.388633-4-alistair@alistair23.me>

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/configs/imx_v6_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 1fbb8e45e604..5326bf4b4c43 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -167,6 +167,7 @@ CONFIG_TOUCHSCREEN_ADS7846=y
 CONFIG_TOUCHSCREEN_AD7879=y
 CONFIG_TOUCHSCREEN_AD7879_I2C=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_CYTTSP5=y
 CONFIG_TOUCHSCREEN_DA9052=y
 CONFIG_TOUCHSCREEN_EGALAX=y
 CONFIG_TOUCHSCREEN_GOODIX=y
-- 
2.31.1



From alistair at alistair23.me  Sun Jan  9 03:53:31 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Sun,  9 Jan 2022 21:53:31 +1000
Subject: [PATCH v5 4/4] ARM: dts: imx7d-remarkable2: Enable the cyttsp5
In-Reply-To: <20220109115331.388633-1-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
Message-ID: <20220109115331.388633-5-alistair@alistair23.me>

Add support for the cyttsp5 touchscreen controller for the reMarkable 2.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/boot/dts/imx7d-remarkable2.dts | 89 +++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-remarkable2.dts b/arch/arm/boot/dts/imx7d-remarkable2.dts
index 89cbf13097a4..f12d6805b214 100644
--- a/arch/arm/boot/dts/imx7d-remarkable2.dts
+++ b/arch/arm/boot/dts/imx7d-remarkable2.dts
@@ -8,6 +8,7 @@
 /dts-v1/;
 
 #include "imx7d.dtsi"
+#include <dt-bindings/input/linux-event-codes.h>
 
 / {
 	model = "reMarkable 2.0";
@@ -34,6 +35,18 @@ reg_brcm: regulator-brcm {
 		startup-delay-us = <150>;
 	};
 
+	reg_touch: regulator-touch {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD_3V3_TOUCH";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&pinctrl_touch_reg>;
+		pinctrl-1 = <&pinctrl_touch_reg>;
+		gpio = <&gpio1 11 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
 	wifi_pwrseq: wifi_pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		pinctrl-names = "default";
@@ -51,6 +64,59 @@ &clks {
 	assigned-clock-rates = <0>, <32768>;
 };
 
+&i2c3 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	status = "okay";
+
+	tsc at 24 {
+		compatible = "cypress,tt21000";
+		reg = <0x24>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_touch>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <14 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
+		vdd-supply = <&reg_touch>;
+		touchscreen-size-x = <880>;
+		touchscreen-size-y = <1280>;
+
+		button-0 {
+			linux,code = <KEY_HOMEPAGE>;
+		};
+
+		button-1 {
+			linux,code = <KEY_MENU>;
+		};
+
+		button-2 {
+			linux,code = <KEY_BACK>;
+		};
+
+		button-3 {
+			linux,code = <KEY_SEARCH>;
+		};
+
+		button-4 {
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+
+		button-5 {
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		button-6 {
+			linux,code = <KEY_CAMERA>;
+		};
+
+		button-7 {
+			linux,code = <KEY_POWER>;
+		};
+	};
+};
+
 &snvs_pwrkey {
 	status = "okay";
 };
@@ -125,6 +191,29 @@ MX7D_PAD_SAI1_TX_BCLK__GPIO6_IO13	0x14
 		>;
 	};
 
+	pinctrl_touch: touchgrp {
+		fsl,pins = <
+			/* CYTTSP interrupt */
+			MX7D_PAD_GPIO1_IO14__GPIO1_IO14		0x54
+			/* CYTTSP reset */
+			MX7D_PAD_GPIO1_IO13__GPIO1_IO13		0x04
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX7D_PAD_I2C3_SDA__I2C3_SDA		0x4000007f
+			MX7D_PAD_I2C3_SCL__I2C3_SCL		0x4000007f
+		>;
+	};
+
+	pinctrl_touch_reg: touchreggrp {
+		fsl,pins = <
+			/* TOUCH_PWR_EN */
+			MX7D_PAD_GPIO1_IO11__GPIO1_IO11		0x14
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-- 
2.31.1



From alistair23 at gmail.com  Sun Jan  9 04:00:45 2022
From: alistair23 at gmail.com (Alistair Francis)
Date: Sun, 9 Jan 2022 22:00:45 +1000
Subject: [PATCH v4 0/4] Add support for the Cypress cyttsp5
In-Reply-To: <37291fe7-7028-cd9e-7fde-01d13f85f0d9@sholland.org>
References: <20211222124603.326920-1-alistair@alistair23.me>
 <37291fe7-7028-cd9e-7fde-01d13f85f0d9@sholland.org>
Message-ID: <CAKmqyKOpO-PemwbQN-PL+miZjV1aq2zzipwMqwVXMJvH=10=Tw@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:49 PM Samuel Holland <samuel at sholland.org> wrote:
>
> Hello!
>
> On 12/22/21 6:45 AM, Alistair Francis wrote:
> > This patch series builds on top of [1] and adds support for the cyttsp5
> > touchscreen controller for the reMarkable 2.
> >
> > I first tried to add an I2C HID device. Although the cyttsp5 has some HID
> > looking aspects it is not HID compatible. Just in trying to probe the device
> > I found:
> >  - The HID descriptor has extra padding
> >  - The HID descriptor sets the high bytes of the descriptor length
> >  - The HID descriptor has extra unrecognised tags
> >  - The HID reset command doesn't appear to work
> >
> > I don't think there is a way to use the I2C HID framework with the cyttsp5.
> > For anyone interested you can see the work here [2]. In that branch though I
> > can only obtain a HID descriptor, nothing else works without more core
> > changes.
> >
> > So instead I rebased the series from [1]. Converted to the new yaml DTS
> > documentation, added regulator support and fixed a x/y miscalculation bug.
>
> I am working on the PineNote, which also uses a cyttsp5 touchscreen. I attempted

Hey! That's great! PineNote support would be awesome

> to use the driver from this series, but I could not get it to work. I found that
> the cyttsp5_sensing_conf_data was filled with all zeroes, so every touch failed
> the max_tch check. I noticed that cmd_done was being completed by empty
> responses (which explains why the response buffer was zeroes), but I got stuck
> after that.

Hmm... That's annoying. This series now works with the rM2 and a kobo
device, so I don't understand why it wouldn't work on the PineNote.

I just sent a v5 (sorry, I forgot to CC you) that has some code
cleanups, but I don't expect it to fix the issues you are seeing.

>
> So I looked back at the thread you linked below, and tried to implement the
> workarounds described there, and those above, plus some others, and I was able
> to get the touchscreen working with i2c_hid. Here are the changes I made to i2c_hid:
> https://github.com/smaeul/linux/commit/a1e07425a6c4
>
> In summary:
>  - Perform a 2-byte dummy read before reading the HID descriptor.
>    This is required to clear the two-byte empty message.
>  - Split command/response into multiple I2C transactions.
>    This is probably some sort of timing issue.
>    Without these first two, HID descriptor reads return "02 00".
>  - Chop 2 bytes out of the HID descriptor, as per the thread below.
>  - Similarly, chop 3 bytes out of the report descriptor.
>  - Skip the reset command, as above. Otherwise, the touchscreen
>    sends a different, short, unusable (partial?) report descriptor.

Cool! I'm impressed you got this working!

>
> I reused the the existing i2c_hid_of_goodix driver to handle toggling the reset
> line, which is required. That existing binding is almost identical to the one in
> this series. Here's the glue I added:
> https://github.com/smaeul/linux/commit/65d9250d3899
>
> And here is the result, from dmesg and debugfs:
> https://gist.github.com/smaeul/60b4b0f784bfff8bb8ce3ee3b4483be9
>
> So far, the quirks only appear to affect probing the device. The touchscreen
> works normally after that.

If the PineNote and eInk setups are different (they probably are if
this series isn't working for you) then there might be other changes
as well.

>
> What do you think of this approach? It certainly seems cleaner than parsing the
> HID reports/responses by hand. But I don't know if all of the quirks are
> acceptable for i2c_hid.

I'll leave that for an I2C HID maintainer to answer.

>
> One additional quirk that I haven't handled yet is the missing min/max for ABS_*
> axes in the report descriptor. This prevents libinput from working, but other
> evdev users appear to work fine. The driver in this series appears to get that
> information from some vendor-specific command, and I am not sure where to hook
> that up.

We will need that won't we? So then i2c_hid would have to implement
that as well?

Alistair

>
> Regards,
> Samuel
>
> > 1: https://lwn.net/ml/linux-kernel/20180703094309.18514-1-mylene.josserand at bootlin.com/
> > 2: https://github.com/alistair23/linux/commits/rM2-mainline-cyttsp5-hid
> >
> > Alistair Francis (2):
> >   ARM: imx_v6_v7_defconfig: Enable the cyttsp5 touchscreen
> >   ARM: dts: imx7d-remarkable2: Enable the cyttsp5
> >
> > Myl?ne Josserand (2):
> >   Input: Add driver for Cypress Generation 5 touchscreen
> >   dt-bindings: input: Add Cypress TT2100 touchscreen controller
> >
> >  .../input/touchscreen/cypress,tt21000.yaml    |  92 ++
> >  arch/arm/boot/dts/imx7d-remarkable2.dts       |  89 ++
> >  arch/arm/configs/imx_v6_v7_defconfig          |   1 +
> >  drivers/input/touchscreen/Kconfig             |  14 +
> >  drivers/input/touchscreen/Makefile            |   1 +
> >  drivers/input/touchscreen/cyttsp5.c           | 922 ++++++++++++++++++
> >  6 files changed, 1119 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> >  create mode 100644 drivers/input/touchscreen/cyttsp5.c
> >
>


From lkp at intel.com  Sun Jan  9 04:16:27 2022
From: lkp at intel.com (kernel test robot)
Date: Sun, 09 Jan 2022 20:16:27 +0800
Subject: [soc:arm/late] BUILD SUCCESS 6b6db66fb373b0f19ca7798500244d256ec0ab44
Message-ID: <61dad21b.A/lHzQ8ciAq8cfpj%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/late
branch HEAD: 6b6db66fb373b0f19ca7798500244d256ec0ab44  Merge tag 'soc-fsl-next-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/leo/linux into arm/late

elapsed time: 728m

configs tested: 141
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                            zeus_defconfig
nios2                         10m50_defconfig
mips                         db1xxx_defconfig
m68k                        m5272c3_defconfig
riscv                            allmodconfig
mips                            ar7_defconfig
powerpc                     taishan_defconfig
powerpc                        warp_defconfig
sh                        dreamcast_defconfig
m68k                             alldefconfig
powerpc                 mpc8540_ads_defconfig
um                                  defconfig
um                             i386_defconfig
powerpc                      ppc6xx_defconfig
m68k                            mac_defconfig
sh                            migor_defconfig
nds32                            alldefconfig
arc                          axs101_defconfig
arc                     nsimosci_hs_defconfig
openrisc                  or1klitex_defconfig
sh                            hp6xx_defconfig
arm                        multi_v7_defconfig
powerpc                     tqm8541_defconfig
i386                             alldefconfig
alpha                               defconfig
powerpc                mpc7448_hpc2_defconfig
m68k                        stmark2_defconfig
sh                           sh2007_defconfig
sh                           se7619_defconfig
arm                        oxnas_v6_defconfig
sh                      rts7751r2d1_defconfig
m68k                       m5475evb_defconfig
arm                            mps2_defconfig
sh                                  defconfig
nios2                            alldefconfig
powerpc                      bamboo_defconfig
powerpc                 mpc85xx_cds_defconfig
sh                          kfr2r09_defconfig
sh                     sh7710voipgw_defconfig
m68k                                defconfig
arm                         lpc18xx_defconfig
sh                          landisk_defconfig
arm                            qcom_defconfig
arm                          exynos_defconfig
powerpc                      makalu_defconfig
sh                           se7780_defconfig
powerpc                 mpc834x_itx_defconfig
powerpc                      cm5200_defconfig
x86_64                           alldefconfig
sh                        sh7757lcr_defconfig
powerpc                      chrp32_defconfig
m68k                            q40_defconfig
sh                         ecovec24_defconfig
sh                          rsk7264_defconfig
mips                         bigsur_defconfig
arm                  randconfig-c002-20220109
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20220109
x86_64               randconfig-a001-20220109
x86_64               randconfig-a004-20220109
x86_64               randconfig-a006-20220109
x86_64               randconfig-a003-20220109
x86_64               randconfig-a002-20220109
i386                 randconfig-a003-20220109
i386                 randconfig-a005-20220109
i386                 randconfig-a006-20220109
i386                 randconfig-a004-20220109
i386                 randconfig-a001-20220109
i386                 randconfig-a002-20220109
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
arm                  randconfig-c002-20220109
mips                 randconfig-c004-20220109
i386                 randconfig-c001-20220109
riscv                randconfig-c006-20220109
powerpc              randconfig-c003-20220109
x86_64               randconfig-c007-20220109
powerpc                     ppa8548_defconfig
mips                      maltaaprp_defconfig
powerpc                          allyesconfig
powerpc                     ksi8560_defconfig
x86_64               randconfig-a015-20220109
x86_64               randconfig-a012-20220109
x86_64               randconfig-a014-20220109
x86_64               randconfig-a013-20220109
x86_64               randconfig-a011-20220109
x86_64               randconfig-a016-20220109
i386                 randconfig-a012-20220109
i386                 randconfig-a016-20220109
i386                 randconfig-a015-20220109
i386                 randconfig-a014-20220109
i386                 randconfig-a011-20220109
i386                 randconfig-a013-20220109
hexagon              randconfig-r041-20220109
riscv                randconfig-r042-20220109
hexagon              randconfig-r045-20220109

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan  9 04:17:00 2022
From: lkp at intel.com (kernel test robot)
Date: Sun, 09 Jan 2022 20:17:00 +0800
Subject: [soc:for-next] BUILD SUCCESS e333f3fec06a8c04be658706e6bb1c7c40df1357
Message-ID: <61dad23c.FSzDP1Kj9dA0U2uX%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: e333f3fec06a8c04be658706e6bb1c7c40df1357  ARM: Document merges

elapsed time: 727m

configs tested: 141
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                            zeus_defconfig
nios2                         10m50_defconfig
mips                         db1xxx_defconfig
m68k                        m5272c3_defconfig
riscv                            allmodconfig
mips                            ar7_defconfig
powerpc                     taishan_defconfig
powerpc                        warp_defconfig
sh                        dreamcast_defconfig
m68k                             alldefconfig
powerpc                 mpc8540_ads_defconfig
um                                  defconfig
um                             i386_defconfig
powerpc                      ppc6xx_defconfig
m68k                            mac_defconfig
sh                            migor_defconfig
nds32                            alldefconfig
arc                          axs101_defconfig
arc                     nsimosci_hs_defconfig
openrisc                  or1klitex_defconfig
sh                            hp6xx_defconfig
arm                        multi_v7_defconfig
powerpc                     tqm8541_defconfig
i386                             alldefconfig
alpha                               defconfig
powerpc                mpc7448_hpc2_defconfig
m68k                        stmark2_defconfig
sh                           sh2007_defconfig
sh                           se7619_defconfig
arm                        oxnas_v6_defconfig
sh                      rts7751r2d1_defconfig
m68k                       m5475evb_defconfig
arm                            mps2_defconfig
sh                                  defconfig
nios2                            alldefconfig
powerpc                      bamboo_defconfig
powerpc                 mpc85xx_cds_defconfig
sh                          kfr2r09_defconfig
sh                     sh7710voipgw_defconfig
m68k                                defconfig
arm                         lpc18xx_defconfig
sh                          landisk_defconfig
arm                            qcom_defconfig
arm                          exynos_defconfig
powerpc                      makalu_defconfig
sh                           se7780_defconfig
powerpc                 mpc834x_itx_defconfig
powerpc                      cm5200_defconfig
x86_64                           alldefconfig
sh                        sh7757lcr_defconfig
powerpc                      chrp32_defconfig
m68k                            q40_defconfig
sh                         ecovec24_defconfig
sh                          rsk7264_defconfig
mips                         bigsur_defconfig
arm                  randconfig-c002-20220109
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20220109
x86_64               randconfig-a001-20220109
x86_64               randconfig-a004-20220109
x86_64               randconfig-a006-20220109
x86_64               randconfig-a003-20220109
x86_64               randconfig-a002-20220109
i386                 randconfig-a003-20220109
i386                 randconfig-a005-20220109
i386                 randconfig-a006-20220109
i386                 randconfig-a004-20220109
i386                 randconfig-a001-20220109
i386                 randconfig-a002-20220109
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
arm                  randconfig-c002-20220109
mips                 randconfig-c004-20220109
i386                 randconfig-c001-20220109
riscv                randconfig-c006-20220109
powerpc              randconfig-c003-20220109
x86_64               randconfig-c007-20220109
powerpc                     ppa8548_defconfig
mips                      maltaaprp_defconfig
powerpc                          allyesconfig
powerpc                     ksi8560_defconfig
x86_64               randconfig-a015-20220109
x86_64               randconfig-a012-20220109
x86_64               randconfig-a014-20220109
x86_64               randconfig-a013-20220109
x86_64               randconfig-a011-20220109
x86_64               randconfig-a016-20220109
i386                 randconfig-a012-20220109
i386                 randconfig-a016-20220109
i386                 randconfig-a015-20220109
i386                 randconfig-a014-20220109
i386                 randconfig-a011-20220109
i386                 randconfig-a013-20220109
hexagon              randconfig-r041-20220109
riscv                randconfig-r042-20220109
hexagon              randconfig-r045-20220109

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan  9 04:16:43 2022
From: lkp at intel.com (kernel test robot)
Date: Sun, 09 Jan 2022 20:16:43 +0800
Subject: [soc:arm/fixes] BUILD SUCCESS c8013355ead68dce152cf426686f8a5f80d88b40
Message-ID: <61dad22b.vFp+QUs2eiG9GAR4%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/fixes
branch HEAD: c8013355ead68dce152cf426686f8a5f80d88b40  ARM: dts: gpio-ranges property is now required

elapsed time: 728m

configs tested: 142
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
arm                            zeus_defconfig
nios2                         10m50_defconfig
mips                         db1xxx_defconfig
m68k                        m5272c3_defconfig
riscv                            allmodconfig
mips                            ar7_defconfig
powerpc                     taishan_defconfig
powerpc                        warp_defconfig
sh                        dreamcast_defconfig
m68k                             alldefconfig
powerpc                 mpc8540_ads_defconfig
um                                  defconfig
um                             i386_defconfig
powerpc                      ppc6xx_defconfig
m68k                            mac_defconfig
sh                            migor_defconfig
nds32                            alldefconfig
arc                          axs101_defconfig
arc                     nsimosci_hs_defconfig
openrisc                  or1klitex_defconfig
sh                            hp6xx_defconfig
arm                        multi_v7_defconfig
powerpc                     tqm8541_defconfig
i386                             alldefconfig
alpha                               defconfig
powerpc                mpc7448_hpc2_defconfig
m68k                        stmark2_defconfig
sh                           sh2007_defconfig
sh                           se7619_defconfig
arm                        oxnas_v6_defconfig
sh                      rts7751r2d1_defconfig
m68k                       m5475evb_defconfig
arm                            mps2_defconfig
sh                                  defconfig
nios2                            alldefconfig
powerpc                      bamboo_defconfig
powerpc                 mpc85xx_cds_defconfig
sh                          kfr2r09_defconfig
sh                     sh7710voipgw_defconfig
m68k                                defconfig
arm                         lpc18xx_defconfig
sh                          landisk_defconfig
arm                            qcom_defconfig
arm                          exynos_defconfig
powerpc                      makalu_defconfig
sh                           se7780_defconfig
powerpc                 mpc834x_itx_defconfig
powerpc                      cm5200_defconfig
x86_64                           alldefconfig
sh                        sh7757lcr_defconfig
powerpc                      chrp32_defconfig
m68k                            q40_defconfig
sh                         ecovec24_defconfig
sh                          rsk7264_defconfig
mips                         bigsur_defconfig
arm                  randconfig-c002-20220109
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a005-20220109
x86_64               randconfig-a001-20220109
x86_64               randconfig-a004-20220109
x86_64               randconfig-a006-20220109
x86_64               randconfig-a003-20220109
x86_64               randconfig-a002-20220109
i386                 randconfig-a003-20220109
i386                 randconfig-a005-20220109
i386                 randconfig-a006-20220109
i386                 randconfig-a004-20220109
i386                 randconfig-a001-20220109
i386                 randconfig-a002-20220109
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
arm                  randconfig-c002-20220109
mips                 randconfig-c004-20220109
i386                 randconfig-c001-20220109
riscv                randconfig-c006-20220109
powerpc              randconfig-c003-20220109
x86_64               randconfig-c007-20220109
powerpc                     ppa8548_defconfig
mips                      maltaaprp_defconfig
powerpc                          allyesconfig
powerpc                     ksi8560_defconfig
x86_64               randconfig-a015-20220109
x86_64               randconfig-a012-20220109
x86_64               randconfig-a014-20220109
x86_64               randconfig-a013-20220109
x86_64               randconfig-a011-20220109
x86_64               randconfig-a016-20220109
i386                 randconfig-a012-20220109
i386                 randconfig-a016-20220109
i386                 randconfig-a015-20220109
i386                 randconfig-a014-20220109
i386                 randconfig-a011-20220109
i386                 randconfig-a013-20220109
hexagon              randconfig-r041-20220109
riscv                randconfig-r042-20220109
hexagon              randconfig-r045-20220109
s390                 randconfig-r044-20220109

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From gregkh at linuxfoundation.org  Sun Jan  9 04:58:19 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Sun, 9 Jan 2022 13:58:19 +0100
Subject: [PATCH RFC 4.9 0/5] Fix booting arm64 big endian with QEMU 5.0.0+
In-Reply-To: <20220107194335.3090066-1-nathan@kernel.org>
References: <20220107194335.3090066-1-nathan@kernel.org>
Message-ID: <Ydrb604dRBdB9xmq@kroah.com>

On Fri, Jan 07, 2022 at 12:43:30PM -0700, Nathan Chancellor wrote:
> Hello everyone,
> 
> After upgrading the version of QEMU used in our CI from 4.2.0 to 6.2.0,
> I noticed that our 4.9 arm64 big endian builds stopped booting properly.
> This is not something that is clang specific, I could reproduce it with
> GCC 8.3.0 (the rootfs is at [1]).
> 
> $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- distclean defconfig
> 
> $ scripts/config -e CPU_BIG_ENDIAN
> 
> $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig Image.gz
> 
> $ qemu-system-aarch64 \
>     -initrd rootfs.cpio \
>     -append 'console=ttyAMA0 earlycon' \
>     -cpu max \
>     -machine virt,gic-version=max \
>     -machine virtualization=true \
>     -display none \
>     -kernel arch/arm64/boot/Image.gz \
>     -m 512m \
>     -nodefaults \
>     -serial mon:stdio
> [    0.000000] Booting Linux on physical CPU 0x0
> [    0.000000] Linux version 4.9.296 (nathan at archlinux-ax161) (gcc version 8.3.0 (Debian 8.3.0-2) ) #1 SMP PREEMPT Fri Jan 7 19:10:49 UTC 2022
> ...
> [    0.773924] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> [    0.773924]
> [    0.776016] CPU: 0 PID: 1 Comm: init Not tainted 4.9.296 #1
> [    0.776149] Hardware name: linux,dummy-virt (DT)
> [    0.776375] Call trace:
> [    0.777063] [<ffff000008088ba0>] dump_backtrace+0x0/0x1b0
> [    0.777293] [<ffff000008088d64>] show_stack+0x14/0x20
> [    0.777420] [<ffff0000088c2d18>] dump_stack+0x98/0xb8
> [    0.777555] [<ffff0000088c0ee8>] panic+0x11c/0x278
> [    0.777684] [<ffff0000080c4d20>] do_exit+0x940/0x970
> [    0.777816] [<ffff0000080c4db8>] do_group_exit+0x38/0xa0
> [    0.777974] [<ffff0000080cf698>] get_signal+0xb8/0x678
> [    0.778111] [<ffff000008087ca8>] do_signal+0xd8/0x9b0
> [    0.778248] [<ffff0000080888dc>] do_notify_resume+0x8c/0xa8
> [    0.778392] [<ffff000008082ff4>] work_pending+0x8/0x10
> [    0.778790] Kernel Offset: disabled
> [    0.778891] Memory Limit: none
> [    0.779241] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
> 
> I ended up bisecting QEMU down to cd3f80aba0 ("target/arm: Enable
> ARMv8.1-VHE in -cpu max") [2], which did not seem obviously broken. I
> noticed that our 4.14 builds were fine so I ended up doing a reverse
> bisect down to commit ec347012bbec ("arm64: sysreg: Move to use
> definitions for all the SCTLR bits"). Getting that change to apply
> cleanly involved applying the three other arm64 patches in this series
> and making it build properly required the BUILD_BUG_ON header split
> (including bug.h might have been sufficient but I did not want to risk
> any further breakage). I searched through mainline to see if there were
> any fixes commits that I missed and I did not find any.
> 
> I am not sure if this series would be acceptable in 4.9, hence the RFC
> tag. If not, I am happy to just spin down our boot tests of arm64 big
> endian on 4.9, which is not a super valuable target, but I figured I
> would send the series and let others decide!
> 
> [1]: https://github.com/ClangBuiltLinux/boot-utils/tree/6cfa15992d375dfb874ca0677abdaebfba4f74e6/images/arm64be
> [2]: https://gitlab.com/qemu-project/qemu/-/commit/cd3f80aba0c559a6291f7c3e686422b15381f6b7

Seems sane, having build coverage for 4.9 for the next year is always
good to keep going.  I'll queue these up now, thanks!

greg k-h


From gregkh at linuxfoundation.org  Sun Jan  9 05:07:38 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 09 Jan 2022 14:07:38 +0100
Subject: Patch "arm64: move !VHE work to end of el2_setup" has been added to
 the 4.9-stable tree
In-Reply-To: <20220107194335.3090066-5-nathan@kernel.org>
Message-ID: <1641733658197117@kroah.com>


This is a note to let you know that I've just added the patch titled

    arm64: move !VHE work to end of el2_setup

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-move-vhe-work-to-end-of-el2_setup.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Sun Jan  9 01:56:51 PM CET 2022
From: Nathan Chancellor <nathan at kernel.org>
Date: Fri,  7 Jan 2022 12:43:34 -0700
Subject: arm64: move !VHE work to end of el2_setup
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>, Sasha Levin <sashal at kernel.org>, Catalin Marinas <catalin.marinas at arm.com>, Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>, Marc Zyngier <maz at kernel.org>, Nick Desaulniers <ndesaulniers at google.com>, linux-arm-kernel at lists.infradead.org, stable at vger.kernel.org, llvm at lists.linux.dev
Message-ID: <20220107194335.3090066-5-nathan at kernel.org>

From: Mark Rutland <mark.rutland at arm.com>

commit d61c97a7773d0848b4bf5c4697855c7ce117362c upstream.

We only need to initialise sctlr_el1 if we're installing an EL2 stub, so
we may as well defer this until we're doing so. Similarly, we can defer
intialising CPTR_EL2 until then, as we do not access any trapped
functionality as part of el2_setup.

This patch modified el2_setup accordingly, allowing us to remove a
branch and simplify the code flow.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm64/kernel/head.S |   37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -553,26 +553,6 @@ set_hcr:
 	msr	vpidr_el2, x0
 	msr	vmpidr_el2, x1
 
-	/*
-	 * When VHE is not in use, early init of EL2 and EL1 needs to be
-	 * done here.
-	 * When VHE _is_ in use, EL1 will not be used in the host and
-	 * requires no configuration, and all non-hyp-specific EL2 setup
-	 * will be done via the _EL1 system register aliases in __cpu_setup.
-	 */
-	cbnz	x2, 1f
-
-	/* sctlr_el1 */
-	mov	x0, #0x0800			// Set/clear RES{1,0} bits
-CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
-CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
-	msr	sctlr_el1, x0
-
-	/* Coprocessor traps. */
-	mov	x0, #0x33ff
-	msr	cptr_el2, x0			// Disable copro. traps to EL2
-1:
-
 #ifdef CONFIG_COMPAT
 	msr	hstr_el2, xzr			// Disable CP15 traps to EL2
 #endif
@@ -598,6 +578,23 @@ CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// C
 	ret
 
 install_el2_stub:
+	/*
+	 * When VHE is not in use, early init of EL2 and EL1 needs to be
+	 * done here.
+	 * When VHE _is_ in use, EL1 will not be used in the host and
+	 * requires no configuration, and all non-hyp-specific EL2 setup
+	 * will be done via the _EL1 system register aliases in __cpu_setup.
+	 */
+	/* sctlr_el1 */
+	mov	x0, #0x0800			// Set/clear RES{1,0} bits
+CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
+CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
+	msr	sctlr_el1, x0
+
+	/* Coprocessor traps. */
+	mov	x0, #0x33ff
+	msr	cptr_el2, x0			// Disable copro. traps to EL2
+
 	/* Hypervisor stub */
 	adrp	x0, __hyp_stub_vectors
 	add	x0, x0, #:lo12:__hyp_stub_vectors


Patches currently in stable-queue which might be from nathan at kernel.org are

queue-4.9/arm64-sysreg-move-to-use-definitions-for-all-the-sctlr-bits.patch
queue-4.9/bug-split-build_bug-stuff-out-into-linux-build_bug.h.patch
queue-4.9/arm64-move-vhe-work-to-end-of-el2_setup.patch
queue-4.9/arm64-remove-a-redundancy-in-sysreg.h.patch
queue-4.9/arm64-reduce-el2_setup-branching.patch


From gregkh at linuxfoundation.org  Sun Jan  9 05:07:38 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 09 Jan 2022 14:07:38 +0100
Subject: Patch "arm64: reduce el2_setup branching" has been added to the
 4.9-stable tree
In-Reply-To: <20220107194335.3090066-4-nathan@kernel.org>
Message-ID: <1641733658226222@kroah.com>


This is a note to let you know that I've just added the patch titled

    arm64: reduce el2_setup branching

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-reduce-el2_setup-branching.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Sun Jan  9 01:56:51 PM CET 2022
From: Nathan Chancellor <nathan at kernel.org>
Date: Fri,  7 Jan 2022 12:43:33 -0700
Subject: arm64: reduce el2_setup branching
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>, Sasha Levin <sashal at kernel.org>, Catalin Marinas <catalin.marinas at arm.com>, Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>, Marc Zyngier <maz at kernel.org>, Nick Desaulniers <ndesaulniers at google.com>, linux-arm-kernel at lists.infradead.org, stable at vger.kernel.org, llvm at lists.linux.dev
Message-ID: <20220107194335.3090066-4-nathan at kernel.org>

From: Mark Rutland <mark.rutland at arm.com>

commit 3ad47d055aa88d9f4189253f5b5c485f4c4626b2 upstream.

The early el2_setup code is a little convoluted, with two branches where
one would do. This makes the code more painful to read than is
necessary.

We can remove a branch and simplify the logic by moving the early return
in the booted-at-EL1 case earlier in the function. This separates it
from all the setup logic that only makes sense for EL2.

Acked-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm64/kernel/head.S |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -489,13 +489,8 @@ ENTRY(el2_setup)
 	msr	SPsel, #1			// We want to use SP_EL{1,2}
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
-	b.ne	1f
-	mrs	x0, sctlr_el2
-CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
-CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
-	msr	sctlr_el2, x0
-	b	2f
-1:	mrs	x0, sctlr_el1
+	b.eq	1f
+	mrs	x0, sctlr_el1
 CPU_BE(	orr	x0, x0, #(3 << 24)	)	// Set the EE and E0E bits for EL1
 CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
 	msr	sctlr_el1, x0
@@ -503,7 +498,11 @@ CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clea
 	isb
 	ret
 
-2:
+1:	mrs	x0, sctlr_el2
+CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
+CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
+	msr	sctlr_el2, x0
+
 #ifdef CONFIG_ARM64_VHE
 	/*
 	 * Check for VHE being present. For the rest of the EL2 setup,


Patches currently in stable-queue which might be from nathan at kernel.org are

queue-4.9/arm64-sysreg-move-to-use-definitions-for-all-the-sctlr-bits.patch
queue-4.9/bug-split-build_bug-stuff-out-into-linux-build_bug.h.patch
queue-4.9/arm64-move-vhe-work-to-end-of-el2_setup.patch
queue-4.9/arm64-remove-a-redundancy-in-sysreg.h.patch
queue-4.9/arm64-reduce-el2_setup-branching.patch


From gregkh at linuxfoundation.org  Sun Jan  9 05:07:39 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 09 Jan 2022 14:07:39 +0100
Subject: Patch "arm64: Remove a redundancy in sysreg.h" has been added to the
 4.9-stable tree
In-Reply-To: <20220107194335.3090066-3-nathan@kernel.org>
Message-ID: <164173365975245@kroah.com>


This is a note to let you know that I've just added the patch titled

    arm64: Remove a redundancy in sysreg.h

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-remove-a-redundancy-in-sysreg.h.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Sun Jan  9 01:56:51 PM CET 2022
From: Nathan Chancellor <nathan at kernel.org>
Date: Fri,  7 Jan 2022 12:43:32 -0700
Subject: arm64: Remove a redundancy in sysreg.h
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>, Sasha Levin <sashal at kernel.org>, Catalin Marinas <catalin.marinas at arm.com>, Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>, Marc Zyngier <maz at kernel.org>, Nick Desaulniers <ndesaulniers at google.com>, linux-arm-kernel at lists.infradead.org, stable at vger.kernel.org, llvm at lists.linux.dev
Message-ID: <20220107194335.3090066-3-nathan at kernel.org>

From: Stefan Traby <stefan at hello-penguin.com>

commit d38338e396ee0571b3502962fd2fbaec4d2d9a8f upstream.

This is really trivial; there is a dup (1 << 16) in the code

Acked-by: Will Deacon <will.deacon at arm.com>
Signed-off-by: Stefan Traby <stefan at hello-penguin.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm64/include/asm/sysreg.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -95,8 +95,8 @@
 #define SCTLR_ELx_M	1
 
 #define SCTLR_EL2_RES1	((1 << 4)  | (1 << 5)  | (1 << 11) | (1 << 16) | \
-			 (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23) | \
-			 (1 << 28) | (1 << 29))
+			 (1 << 18) | (1 << 22) | (1 << 23) | (1 << 28) | \
+			 (1 << 29))
 
 #define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
 			 SCTLR_ELx_SA | SCTLR_ELx_I)


Patches currently in stable-queue which might be from nathan at kernel.org are

queue-4.9/arm64-sysreg-move-to-use-definitions-for-all-the-sctlr-bits.patch
queue-4.9/bug-split-build_bug-stuff-out-into-linux-build_bug.h.patch
queue-4.9/arm64-move-vhe-work-to-end-of-el2_setup.patch
queue-4.9/arm64-remove-a-redundancy-in-sysreg.h.patch
queue-4.9/arm64-reduce-el2_setup-branching.patch


From gregkh at linuxfoundation.org  Sun Jan  9 05:07:39 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 09 Jan 2022 14:07:39 +0100
Subject: Patch "arm64: sysreg: Move to use definitions for all the SCTLR bits"
 has been added to the 4.9-stable tree
In-Reply-To: <20220107194335.3090066-6-nathan@kernel.org>
Message-ID: <164173365977248@kroah.com>


This is a note to let you know that I've just added the patch titled

    arm64: sysreg: Move to use definitions for all the SCTLR bits

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-sysreg-move-to-use-definitions-for-all-the-sctlr-bits.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Sun Jan  9 01:56:51 PM CET 2022
From: Nathan Chancellor <nathan at kernel.org>
Date: Fri,  7 Jan 2022 12:43:35 -0700
Subject: arm64: sysreg: Move to use definitions for all the SCTLR bits
To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>, Sasha Levin <sashal at kernel.org>, Catalin Marinas <catalin.marinas at arm.com>, Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>, Marc Zyngier <maz at kernel.org>, Nick Desaulniers <ndesaulniers at google.com>, linux-arm-kernel at lists.infradead.org, stable at vger.kernel.org, llvm at lists.linux.dev
Message-ID: <20220107194335.3090066-6-nathan at kernel.org>

From: James Morse <james.morse at arm.com>

commit 7a00d68ebe5f07cb1db17e7fedfd031f0d87e8bb upstream.

__cpu_setup() configures SCTLR_EL1 using some hard coded hex masks,
and el2_setup() duplicates some this when setting RES1 bits.

Lets make this the same as KVM's hyp_init, which uses named bits.

First, we add definitions for all the SCTLR_EL{1,2} bits, the RES{1,0}
bits, and those we want to set or clear.

Add a build_bug checks to ensures all bits are either set or clear.
This means we don't need to preserve endian-ness configuration
generated elsewhere.

Finally, move the head.S and proc.S users of these hard-coded masks
over to the macro versions.

Signed-off-by: James Morse <james.morse at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Nathan Chancellor <nathan at kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm64/include/asm/sysreg.h |   65 ++++++++++++++++++++++++++++++++++++++--
 arch/arm64/kernel/head.S        |   13 +-------
 arch/arm64/mm/proc.S            |   24 --------------
 3 files changed, 67 insertions(+), 35 deletions(-)

--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -20,6 +20,7 @@
 #ifndef __ASM_SYSREG_H
 #define __ASM_SYSREG_H
 
+#include <asm/compiler.h>
 #include <linux/stringify.h>
 
 #include <asm/opcodes.h>
@@ -88,25 +89,81 @@
 
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_EE    (1 << 25)
+#define SCTLR_ELx_WXN	(1 << 19)
 #define SCTLR_ELx_I	(1 << 12)
 #define SCTLR_ELx_SA	(1 << 3)
 #define SCTLR_ELx_C	(1 << 2)
 #define SCTLR_ELx_A	(1 << 1)
 #define SCTLR_ELx_M	1
 
+#define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
+			 SCTLR_ELx_SA | SCTLR_ELx_I)
+
+/* SCTLR_EL2 specific flags. */
 #define SCTLR_EL2_RES1	((1 << 4)  | (1 << 5)  | (1 << 11) | (1 << 16) | \
 			 (1 << 18) | (1 << 22) | (1 << 23) | (1 << 28) | \
 			 (1 << 29))
+#define SCTLR_EL2_RES0	((1 << 6)  | (1 << 7)  | (1 << 8)  | (1 << 9)  | \
+			 (1 << 10) | (1 << 13) | (1 << 14) | (1 << 15) | \
+			 (1 << 17) | (1 << 20) | (1 << 21) | (1 << 24) | \
+			 (1 << 26) | (1 << 27) | (1 << 30) | (1 << 31))
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define ENDIAN_SET_EL2		SCTLR_ELx_EE
+#define ENDIAN_CLEAR_EL2	0
+#else
+#define ENDIAN_SET_EL2		0
+#define ENDIAN_CLEAR_EL2	SCTLR_ELx_EE
+#endif
+
+/* SCTLR_EL2 value used for the hyp-stub */
+#define SCTLR_EL2_SET	(ENDIAN_SET_EL2   | SCTLR_EL2_RES1)
+#define SCTLR_EL2_CLEAR	(SCTLR_ELx_M      | SCTLR_ELx_A    | SCTLR_ELx_C   | \
+			 SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
+			 ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
+
+/* Check all the bits are accounted for */
+#define SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != ~0)
 
-#define SCTLR_ELx_FLAGS	(SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
-			 SCTLR_ELx_SA | SCTLR_ELx_I)
 
 /* SCTLR_EL1 specific flags. */
 #define SCTLR_EL1_UCI		(1 << 26)
+#define SCTLR_EL1_E0E		(1 << 24)
 #define SCTLR_EL1_SPAN		(1 << 23)
+#define SCTLR_EL1_NTWE		(1 << 18)
+#define SCTLR_EL1_NTWI		(1 << 16)
 #define SCTLR_EL1_UCT		(1 << 15)
+#define SCTLR_EL1_DZE		(1 << 14)
+#define SCTLR_EL1_UMA		(1 << 9)
 #define SCTLR_EL1_SED		(1 << 8)
+#define SCTLR_EL1_ITD		(1 << 7)
 #define SCTLR_EL1_CP15BEN	(1 << 5)
+#define SCTLR_EL1_SA0		(1 << 4)
+
+#define SCTLR_EL1_RES1	((1 << 11) | (1 << 20) | (1 << 22) | (1 << 28) | \
+			 (1 << 29))
+#define SCTLR_EL1_RES0  ((1 << 6)  | (1 << 10) | (1 << 13) | (1 << 17) | \
+			 (1 << 21) | (1 << 27) | (1 << 30) | (1 << 31))
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define ENDIAN_SET_EL1		(SCTLR_EL1_E0E | SCTLR_ELx_EE)
+#define ENDIAN_CLEAR_EL1	0
+#else
+#define ENDIAN_SET_EL1		0
+#define ENDIAN_CLEAR_EL1	(SCTLR_EL1_E0E | SCTLR_ELx_EE)
+#endif
+
+#define SCTLR_EL1_SET	(SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   |\
+			 SCTLR_EL1_SA0  | SCTLR_EL1_SED  | SCTLR_ELx_I    |\
+			 SCTLR_EL1_DZE  | SCTLR_EL1_UCT  | SCTLR_EL1_NTWI |\
+			 SCTLR_EL1_NTWE | SCTLR_EL1_SPAN | ENDIAN_SET_EL1 |\
+			 SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
+#define SCTLR_EL1_CLEAR	(SCTLR_ELx_A   | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD    |\
+			 SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
+			 SCTLR_EL1_RES0)
+
+/* Check all the bits are accounted for */
+#define SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS	BUILD_BUG_ON((SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != ~0)
 
 /* id_aa64isar0 */
 #define ID_AA64ISAR0_RDM_SHIFT		28
@@ -244,6 +301,7 @@
 
 #else
 
+#include <linux/build_bug.h>
 #include <linux/types.h>
 
 asm(
@@ -300,6 +358,9 @@ static inline void config_sctlr_el1(u32
 {
 	u32 val;
 
+	SCTLR_EL2_BUILD_BUG_ON_MISSING_BITS;
+	SCTLR_EL1_BUILD_BUG_ON_MISSING_BITS;
+
 	val = read_sysreg(sctlr_el1);
 	val &= ~clear;
 	val |= set;
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -490,17 +490,13 @@ ENTRY(el2_setup)
 	mrs	x0, CurrentEL
 	cmp	x0, #CurrentEL_EL2
 	b.eq	1f
-	mrs	x0, sctlr_el1
-CPU_BE(	orr	x0, x0, #(3 << 24)	)	// Set the EE and E0E bits for EL1
-CPU_LE(	bic	x0, x0, #(3 << 24)	)	// Clear the EE and E0E bits for EL1
+	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
 	msr	sctlr_el1, x0
 	mov	w0, #BOOT_CPU_MODE_EL1		// This cpu booted in EL1
 	isb
 	ret
 
-1:	mrs	x0, sctlr_el2
-CPU_BE(	orr	x0, x0, #(1 << 25)	)	// Set the EE bit for EL2
-CPU_LE(	bic	x0, x0, #(1 << 25)	)	// Clear the EE bit for EL2
+1:	mov_q	x0, (SCTLR_EL2_RES1 | ENDIAN_SET_EL2)
 	msr	sctlr_el2, x0
 
 #ifdef CONFIG_ARM64_VHE
@@ -585,10 +581,7 @@ install_el2_stub:
 	 * requires no configuration, and all non-hyp-specific EL2 setup
 	 * will be done via the _EL1 system register aliases in __cpu_setup.
 	 */
-	/* sctlr_el1 */
-	mov	x0, #0x0800			// Set/clear RES{1,0} bits
-CPU_BE(	movk	x0, #0x33d0, lsl #16	)	// Set EE and E0E on BE systems
-CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
+	mov_q	x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
 	msr	sctlr_el1, x0
 
 	/* Coprocessor traps. */
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -413,11 +413,7 @@ ENTRY(__cpu_setup)
 	/*
 	 * Prepare SCTLR
 	 */
-	adr	x5, crval
-	ldp	w5, w6, [x5]
-	mrs	x0, sctlr_el1
-	bic	x0, x0, x5			// clear bits
-	orr	x0, x0, x6			// set bits
+	mov_q	x0, SCTLR_EL1_SET
 	/*
 	 * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for
 	 * both user and kernel.
@@ -453,21 +449,3 @@ ENTRY(__cpu_setup)
 	msr	tcr_el1, x10
 	ret					// return to head.S
 ENDPROC(__cpu_setup)
-
-	/*
-	 * We set the desired value explicitly, including those of the
-	 * reserved bits. The values of bits EE & E0E were set early in
-	 * el2_setup, which are left untouched below.
-	 *
-	 *                 n n            T
-	 *       U E      WT T UD     US IHBS
-	 *       CE0      XWHW CZ     ME TEEA S
-	 * .... .IEE .... NEAI TE.I ..AD DEN0 ACAM
-	 * 0011 0... 1101 ..0. ..0. 10.. .0.. .... < hardware reserved
-	 * .... .1.. .... 01.1 11.1 ..01 0.01 1101 < software settings
-	 */
-	.type	crval, #object
-crval:
-	.word	0xfcffffff			// clear
-	.word	0x34d5d91d			// set
-	.popsection


Patches currently in stable-queue which might be from nathan at kernel.org are

queue-4.9/arm64-sysreg-move-to-use-definitions-for-all-the-sctlr-bits.patch
queue-4.9/bug-split-build_bug-stuff-out-into-linux-build_bug.h.patch
queue-4.9/arm64-move-vhe-work-to-end-of-el2_setup.patch
queue-4.9/arm64-remove-a-redundancy-in-sysreg.h.patch
queue-4.9/arm64-reduce-el2_setup-branching.patch


From christophe.jaillet at wanadoo.fr  Sun Jan  9 05:20:35 2022
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun,  9 Jan 2022 14:20:35 +0100
Subject: [PATCH v2] fsi: Aspeed: Fix a potential double free
Message-ID: <3b5c9b693749a956b525c54bed0eeac9f958b8e8.1641734402.git.christophe.jaillet@wanadoo.fr>

A struct device can never be devm_alloc()'ed.
Here, it is embedded in "struct fsi_master", and "struct fsi_master" is
embedded in "struct fsi_master_aspeed".

Since "struct device" is embedded, the data structure embedding it must be
released with the release function, as is already done here.

So use kzalloc() instead of devm_kzalloc() when allocating "aspeed".
This prevent a potential double free().

Fixes: 606397d67f41 ("fsi: Add ast2600 master driver")
Suggested-by: Greg KH <gregkh at linuxfoundation.org>
Suggested-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
v2: Keep the release function which is correct
    s/devm_kzalloc()/kzalloc()/ instead
---
 drivers/fsi/fsi-master-aspeed.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 8606e55c1721..ae6319818b14 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -542,7 +542,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 		return rc;
 	}
 
-	aspeed = devm_kzalloc(&pdev->dev, sizeof(*aspeed), GFP_KERNEL);
+	aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL);
 	if (!aspeed)
 		return -ENOMEM;
 
-- 
2.32.0



From stano.jakubek at gmail.com  Sun Jan  9 05:23:11 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 14:23:11 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add Huawei
Message-ID: <20220109132311.GA2827@standask-GA-A55M-S2HP>

Add vendor prefix for Huawei (https://www.huawei.com/en/)

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a13d6a19c2b4..18ffa2d7379f 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -515,6 +515,8 @@ patternProperties:
     description: HannStar Display Co.
   "^holtek,.*":
     description: Holtek Semiconductor, Inc.
+  "^huawei,.*":
+    description: Huawei Technologies Co., Ltd.
   "^hugsun,.*":
     description: Shenzhen Hugsun Technology Co. Ltd.
   "^hwacom,.*":
-- 
2.25.1



From guoheyi at linux.alibaba.com  Sun Jan  9 05:26:13 2022
From: guoheyi at linux.alibaba.com (Heyi Guo)
Date: Sun,  9 Jan 2022 21:26:13 +0800
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
Message-ID: <20220109132613.122912-1-guoheyi@linux.alibaba.com>

The memory will be freed by the caller if transfer timeout occurs,
then it would trigger kernel panic if the peer device responds with
something after timeout and triggers the interrupt handler of aspeed
i2c driver.

Set the msgs pointer to NULL to avoid invalid memory reference after
timeout to fix this potential kernel panic.

Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>

-------

Cc: Brendan Higgins <brendanhiggins at google.com>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Joel Stanley <joel at jms.id.au>
Cc: Andrew Jeffery <andrew at aj.id.au>
Cc: Philipp Zabel <p.zabel at pengutronix.de>
Cc: linux-i2c at vger.kernel.org
Cc: openbmc at lists.ozlabs.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-aspeed at lists.ozlabs.org
---
 drivers/i2c/busses/i2c-aspeed.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
index 67e8b97c0c950..3ab0396168680 100644
--- a/drivers/i2c/busses/i2c-aspeed.c
+++ b/drivers/i2c/busses/i2c-aspeed.c
@@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
 		spin_lock_irqsave(&bus->lock, flags);
 		if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
 			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
+		/*
+		 * All the buffers may be freed after returning to caller, so
+		 * set msgs to NULL to avoid memory reference after freeing.
+		 */
+		bus->msgs = NULL;
 		spin_unlock_irqrestore(&bus->lock, flags);
 
 		return -ETIMEDOUT;
-- 
2.17.1



From stano.jakubek at gmail.com  Sun Jan  9 05:44:31 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 14:44:31 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add 8devices
Message-ID: <20220109134431.GA4560@standask-GA-A55M-S2HP>

Add vendor prefix for 8devices (https://www.8devices.com/)

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a13d6a19c2b4..d9a0c29971a6 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -25,6 +25,8 @@ patternProperties:
   # Keep list in alphabetical order.
   "^70mai,.*":
     description: 70mai Co., Ltd.
+  "^8dev,.*":
+    description: 8devices, UAB
   "^abb,.*":
     description: ABB
   "^abilis,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Sun Jan  9 05:53:12 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 14:53:12 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add Wingtech
Message-ID: <20220109135312.GA4900@standask-GA-A55M-S2HP>

Add vendor prefix for Wingtech (http://www.wingtech.com/en)

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a13d6a19c2b4..419c565ba01c 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1332,6 +1332,8 @@ patternProperties:
     description: Wiligear, Ltd.
   "^winbond,.*":
     description: Winbond Electronics corp.
+  "^wingtech,.*":
+    description: Wingtech Technology Co., Ltd.
   "^winlink,.*":
     description: WinLink Co., Ltd
   "^winstar,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Sun Jan  9 06:37:21 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 15:37:21 +0100
Subject: [PATCH] dt-bindings: serial: Convert rda,8810pl-uart to YAML
Message-ID: <20220109143721.GA7707@standask-GA-A55M-S2HP>

Convert RDA Micro UART bindings to DT schema format.

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 .../bindings/serial/rda,8810pl-uart.txt       | 17 -------
 .../bindings/serial/rda,8810pl-uart.yaml      | 46 +++++++++++++++++++
 MAINTAINERS                                   |  2 +-
 3 files changed, 47 insertions(+), 18 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
 create mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml

diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
deleted file mode 100644
index a08df97a69e6..000000000000
--- a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-RDA Micro UART
-
-Required properties:
-- compatible :  "rda,8810pl-uart" for RDA8810PL SoCs.
-- reg        :  Offset and length of the register set for the device.
-- interrupts :  Should contain UART interrupt.
-- clocks     :  Phandle to the input clock.
-
-
-Example:
-
-		uart2: serial at 20a90000 {
-			compatible = "rda,8810pl-uart";
-			reg = <0x20a90000 0x1000>;
-			interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&uart_clk>;
-		};
diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
new file mode 100644
index 000000000000..74b1e368bb84
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/rda,8810pl-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RDA Micro UART Interface
+
+maintainers:
+  - Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
+
+allOf:
+  - $ref: serial.yaml#
+
+properties:
+  compatible:
+    const: rda,8810pl-uart
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+  #include <dt-bindings/interrupt-controller/irq.h>
+
+  uart3: serial at 20a90000 {
+    compatible = "rda,8810pl-uart";
+    reg = <0x20a90000 0x1000>;
+    interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+    clocks = <&uart_clk>;
+  };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 44d79a8b62c6..c7434954c19f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2502,7 +2502,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/arm/rda.yaml
 F:	Documentation/devicetree/bindings/gpio/gpio-rda.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/rda,8810pl-intc.txt
-F:	Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
+F:	Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
 F:	Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt
 F:	arch/arm/boot/dts/rda8810pl-*
 F:	drivers/clocksource/timer-rda.c
-- 
2.25.1



From stano.jakubek at gmail.com  Sun Jan  9 07:21:15 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 16:21:15 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add F(x)tec
Message-ID: <20220109152115.GA9102@standask-GA-A55M-S2HP>

Add vendor prefix for F(x)tec (https://www.fxtec.com/)

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a13d6a19c2b4..0a6821f2d1e1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -441,6 +441,8 @@ patternProperties:
     description: Freescale Semiconductor
   "^fujitsu,.*":
     description: Fujitsu Ltd.
+  "^fxtec,.*":
+    description: FX Technology Ltd.
   "^gardena,.*":
     description: GARDENA GmbH
   "^gateworks,.*":
-- 
2.25.1



From christianshewitt at gmail.com  Sun Jan  9 07:27:25 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sun, 9 Jan 2022 19:27:25 +0400
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220108084218.31877-2-qianggui.song@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-2-qianggui.song@amlogic.com>
Message-ID: <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>


> On 8 Jan 2022, at 12:42 pm, Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
> .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
> 1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> index 23b18b92c558..9300736bf1ed 100644
> --- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
> @@ -18,6 +18,7 @@ Required properties:
>     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
>     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
>     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
> +    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)

^ should be "amlogic,meson-s4-gpio-intc? ?

Christian

> - reg : Specifies base physical address and size of the registers.
> - interrupt-controller : Identifies the node as an interrupt controller.
> - #interrupt-cells : Specifies the number of cells needed to encode an
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 



From stano.jakubek at gmail.com  Sun Jan  9 07:33:07 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 16:33:07 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add Thundercomm
Message-ID: <20220109153307.GA9842@standask-GA-A55M-S2HP>

Add vendor prefix for Thundercomm (https://www.thundercomm.com/)

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a13d6a19c2b4..f79c30183e7e 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1205,6 +1205,8 @@ patternProperties:
     description: THine Electronics, Inc.
   "^thingyjp,.*":
     description: thingy.jp
+  "^thundercomm,.*":
+    description: Thundercomm Technology Co., Ltd.
   "^ti,.*":
     description: Texas Instruments
   "^tianma,.*":
-- 
2.25.1



From robh at kernel.org  Sun Jan  9 08:33:11 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 09 Jan 2022 10:33:11 -0600
Subject: [PATCH 01/10] dt-bindings: devfreq: rk3399_dmc: Convert to YAML
In-Reply-To: <20220107155215.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>
References: <20220107235320.965497-1-briannorris@chromium.org>
 <20220107155215.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>
Message-ID: <1641745991.444665.3263067.nullmailer@robh.at.kernel.org>

On Fri, 07 Jan 2022 15:53:11 -0800, Brian Norris wrote:
> I want to add, deprecate, and bugfix some properties, as well as add the
> first users. This is easier with a proper schema.
> 
> The transformation is mostly straightforward, plus a few notable tweaks:
> 
>  * Renamed rockchip,dram_speed_bin to rockchip,ddr3_speed_bin. The
>    driver code and the example matched, but the description was
>    different. I went with the implementation.
> 
>  * Drop upthreshold and downdifferential properties from the example.
>    These were undocumented (so, wouldn't pass validation), but were
>    representing software properties (governor tweaks). I drop them from
>    the driver in subsequent patches.
> 
>  * Rename clock from pclk_ddr_mon to dmc_clk. The driver, DT example,
>    and all downstream users matched -- the binding definition was the
>    exception. Anyway, "dmc_clk" is a more appropriately generic name.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
> 
>  .../bindings/devfreq/rk3399_dmc.txt           | 212 -------------
>  .../bindings/devfreq/rk3399_dmc.yaml          | 297 ++++++++++++++++++
>  2 files changed, 297 insertions(+), 212 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
>  create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:
./Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml:37:5: [warning] wrong indentation: expected 6 but found 4 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1577007

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Sun Jan  9 08:33:11 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 09 Jan 2022 10:33:11 -0600
Subject: [PATCH] dt-bindings: serial: Convert rda,8810pl-uart to YAML
In-Reply-To: <20220109143721.GA7707@standask-GA-A55M-S2HP>
References: <20220109143721.GA7707@standask-GA-A55M-S2HP>
Message-ID: <1641745991.464215.3263070.nullmailer@robh.at.kernel.org>

On Sun, 09 Jan 2022 15:37:21 +0100, Stanislav Jakubek wrote:
> Convert RDA Micro UART bindings to DT schema format.
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
>  .../bindings/serial/rda,8810pl-uart.txt       | 17 -------
>  .../bindings/serial/rda,8810pl-uart.yaml      | 46 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 47 insertions(+), 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:
./Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml:40:3: [error] syntax error: expected <block end>, but found '?' (syntax)

dtschema/dtc warnings/errors:
make[1]: *** Deleting file 'Documentation/devicetree/bindings/serial/rda,8810pl-uart.example.dts'
Traceback (most recent call last):
  File "/usr/local/bin/dt-extract-example", line 46, in <module>
    binding = yaml.load(open(args.yamlfile, encoding='utf-8').read())
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/main.py", line 434, in load
    return constructor.get_single_data()
  File "/usr/local/lib/python3.8/dist-packages/ruamel/yaml/constructor.py", line 119, in get_single_data
    node = self.composer.get_single_node()
  File "_ruamel_yaml.pyx", line 706, in _ruamel_yaml.CParser.get_single_node
  File "_ruamel_yaml.pyx", line 724, in _ruamel_yaml.CParser._compose_document
  File "_ruamel_yaml.pyx", line 775, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 889, in _ruamel_yaml.CParser._compose_mapping_node
  File "_ruamel_yaml.pyx", line 773, in _ruamel_yaml.CParser._compose_node
  File "_ruamel_yaml.pyx", line 852, in _ruamel_yaml.CParser._compose_sequence_node
  File "_ruamel_yaml.pyx", line 904, in _ruamel_yaml.CParser._parse_next_event
ruamel.yaml.parser.ParserError: while parsing a block collection
  in "<unicode string>", line 37, column 3
did not find expected '-' indicator
  in "<unicode string>", line 40, column 3
make[1]: *** [Documentation/devicetree/bindings/Makefile:25: Documentation/devicetree/bindings/serial/rda,8810pl-uart.example.dts] Error 1
make[1]: *** Waiting for unfinished jobs....
Traceback (most recent call last):
  File "/usr/bin/yamllint", line 11, in <module>
    load_entry_point('yamllint==1.20.0', 'console_scripts', 'yamllint')()
  File "/usr/lib/python3/dist-packages/yamllint/cli.py", line 184, in run
    prob_level = show_problems(problems, file, args_format=args.format,
  File "/usr/lib/python3/dist-packages/yamllint/cli.py", line 91, in show_problems
    for problem in problems:
  File "/usr/lib/python3/dist-packages/yamllint/linter.py", line 200, in _run
    for problem in get_cosmetic_problems(buffer, conf, filepath):
  File "/usr/lib/python3/dist-packages/yamllint/linter.py", line 137, in get_cosmetic_problems
    for problem in rule.check(rule_conf,
  File "/usr/lib/python3/dist-packages/yamllint/rules/indentation.py", line 570, in check
    for problem in _check(conf, token, prev, next, nextnext, context):
  File "/usr/lib/python3/dist-packages/yamllint/rules/indentation.py", line 336, in _check
    'wrong indentation: expected %d but found %d' %
TypeError: %d format: a number is required, not NoneType
./Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml:  while parsing a block collection
  in "<unicode string>", line 37, column 3
did not find expected '-' indicator
  in "<unicode string>", line 40, column 3
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml: ignoring, error parsing file
make: *** [Makefile:1413: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1577445

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From stano.jakubek at gmail.com  Sun Jan  9 09:03:21 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Sun, 9 Jan 2022 18:03:21 +0100
Subject: [PATCH v2] dt-bindings: serial: Convert rda,8810pl-uart to YAML
Message-ID: <20220109170321.GA12989@standask-GA-A55M-S2HP>

Convert RDA Micro UART bindings to DT schema format.

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Fix indentation in example

 .../bindings/serial/rda,8810pl-uart.txt       | 17 -------
 .../bindings/serial/rda,8810pl-uart.yaml      | 46 +++++++++++++++++++
 MAINTAINERS                                   |  2 +-
 3 files changed, 47 insertions(+), 18 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
 create mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml

diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
deleted file mode 100644
index a08df97a69e6..000000000000
--- a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-RDA Micro UART
-
-Required properties:
-- compatible :  "rda,8810pl-uart" for RDA8810PL SoCs.
-- reg        :  Offset and length of the register set for the device.
-- interrupts :  Should contain UART interrupt.
-- clocks     :  Phandle to the input clock.
-
-
-Example:
-
-		uart2: serial at 20a90000 {
-			compatible = "rda,8810pl-uart";
-			reg = <0x20a90000 0x1000>;
-			interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&uart_clk>;
-		};
diff --git a/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
new file mode 100644
index 000000000000..5f4ed8221270
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/serial/rda,8810pl-uart.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RDA Micro UART Interface
+
+maintainers:
+  - Manivannan Sadhasivam <manivannan.sadhasivam at linaro.org>
+
+allOf:
+  - $ref: serial.yaml#
+
+properties:
+  compatible:
+    const: rda,8810pl-uart
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    uart3: serial at 20a90000 {
+      compatible = "rda,8810pl-uart";
+      reg = <0x20a90000 0x1000>;
+      interrupts = <11 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&uart_clk>;
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 44d79a8b62c6..c7434954c19f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2502,7 +2502,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/arm/rda.yaml
 F:	Documentation/devicetree/bindings/gpio/gpio-rda.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/rda,8810pl-intc.txt
-F:	Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
+F:	Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
 F:	Documentation/devicetree/bindings/timer/rda,8810pl-timer.txt
 F:	arch/arm/boot/dts/rda8810pl-*
 F:	drivers/clocksource/timer-rda.c
-- 
2.25.1



From wuhanluop at 163.com  Sun Jan  9 09:02:39 2022
From: wuhanluop at 163.com (Peng Luo)
Date: Mon, 10 Jan 2022 01:02:39 +0800
Subject: [PATCH] crypto: testmgr - fix some wrong vectors of aes-ccm
Message-ID: <20220109170239.4322-1-wuhanluop@163.com>

Some vectors of aes-ccm are wrong.
This patch has been tested with kernel 4.9 and openssl1.1.1k.

Signed-off-by: Peng Luo <wuhanluop at 163.com>
---
 crypto/testmgr.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index a253d66ba1c1..ff171fe53979 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -19865,8 +19865,8 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
 			  "\xd0\xd1\x3d\x1a\xa3\x6d\xe4\x0a"
 			  "\x86\xb0\x87\x6b\x62\x33\x8c\x34"
 			  "\xce\xab\x57\xcc\x79\x0b\xe0\x6f"
-			  "\x5c\x3e\x48\x1f\x6c\x46\xf7\x51"
-			  "\x8b\x84\x83\x2a\xc1\x05\xb8\xc5",
+			  "\xCF\xE9\xF9\x21\x3C\x1A\xCE\x67"
+			  "\x62\x7B\x36\x3A\xEA\x19\xAC\x58",
 		.clen	= 48,
 		.novrfy	= 1,
 	}, {
@@ -19952,8 +19952,8 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
 			  "\xc6\x0e\x6e\xe5\xd6\x98\xa6\x37"
 			  "\x8c\x26\x33\xc6\xb2\xa2\x17\xfa"
 			  "\x64\x19\xc0\x30\xd7\xfc\x14\x6b"
-			  "\xe3\x33\xc2\x04\xb0\x37\xbe\x3f"
-			  "\xa9\xb4\x2d\x68\x03\xa3\x44\xef",
+			  "\x08\x5A\x20\x4A\xB0\x2C\xF9\x49"
+			  "\x10\x1C\x9C\x85\x8C\x12\xE0\x3A",
 		.clen	= 48,
 		.novrfy	= 1,
 	}, {
@@ -19983,7 +19983,7 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
 			  "\x3e\xaf\x70\x5e\xb2\x4d\xea\x39"
 			  "\x89\xd4\x75\x7a\x63\xb1\xda\x93",
 		.plen	= 32,
-		.ctext	= "\x48\x01\x5e\x02\x24\x04\x66\x47"
+		.ctext	= "\x14\x01\x5e\x02\x24\x04\x66\x47"
 			  "\xa1\xea\x6f\xaf\xe8\xfc\xfb\xdd"
 			  "\xa5\xa9\x87\x8d\x84\xee\x2e\x77"
 			  "\xbb\x86\xb9\xf5\x5c\x6c\xff\xf6"
-- 
2.17.1



From jolsa at redhat.com  Sun Jan  9 10:30:38 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Sun, 9 Jan 2022 19:30:38 +0100
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <20220105061351.120843-49-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
Message-ID: <Ydspzl2aWpufl/yR@krava>

On Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers wrote:
> A common problem is confusing CPU map indices with the CPU, by wrapping
> the CPU with a struct then this is avoided. This approach is similar to
> atomic_t.
> 
> Suggested-by: John Garry <john.garry at huawei.com>
> Signed-off-by: Ian Rogers <irogers at google.com>

SNIP

>  tools/perf/util/stat.h                        |   2 +-
>  tools/perf/util/svghelper.c                   |   6 +-
>  tools/perf/util/synthetic-events.c            |  12 +-
>  tools/perf/util/synthetic-events.h            |   3 +-
>  tools/perf/util/util.h                        |   5 +-
>  59 files changed, 408 insertions(+), 347 deletions(-)

that's massive ;-) did it find any mis-use of the index/value?

how about the same for threads?

> diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
> index 71a31ed738c9..581f9ffb4237 100644
> --- a/tools/lib/perf/include/internal/cpumap.h
> +++ b/tools/lib/perf/include/internal/cpumap.h
> @@ -4,6 +4,11 @@
>  
>  #include <linux/refcount.h>
>  
> +/** A wrapper around a CPU to avoid confusion with the perf_cpu_map's map's indices. */
> +struct perf_cpu {
> +	int cpu;
> +};

should we use 'int val' or 'int v' instead, so we don't have cpu.cpu ?

jirka

SNIP



From jolsa at redhat.com  Sun Jan  9 10:30:45 2022
From: jolsa at redhat.com (Jiri Olsa)
Date: Sun, 9 Jan 2022 19:30:45 +0100
Subject: [PATCH v4 26/48] perf evsel: Derive CPUs and threads in
 alloc_counts
In-Reply-To: <20220105061351.120843-27-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-27-irogers@google.com>
Message-ID: <Ydsp1d58t/gp/GHd@krava>

On Tue, Jan 04, 2022 at 10:13:29PM -0800, Ian Rogers wrote:

SNIP

> diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
> index 7ff36bf6d644..3e275e9c60d1 100644
> --- a/tools/perf/util/counts.h
> +++ b/tools/perf/util/counts.h
> @@ -40,7 +40,7 @@ void perf_counts__delete(struct perf_counts *counts);
>  void perf_counts__reset(struct perf_counts *counts);
>  
>  void evsel__reset_counts(struct evsel *evsel);
> -int evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads);
> +int evsel__alloc_counts(struct evsel *evsel);
>  void evsel__free_counts(struct evsel *evsel);
>  
>  #endif /* __PERF_COUNTS_H */
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 656c30b988ce..6c9af21776e6 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -1578,7 +1578,7 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale)
>  	if (FD(evsel, cpu, thread) < 0)
>  		return -EINVAL;
>  
> -	if (evsel->counts == NULL && evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
> +	if (evsel->counts == NULL && evsel__alloc_counts(evsel) < 0)

ugh, nice.. good that it's used only from test code ;-)

btw I noticed evsel__read_on_cpu_scaled is not used at all

jirka

>  		return -ENOMEM;
>  
>  	if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0)
> diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
> index c69b221f5e3e..995cb5003133 100644
> --- a/tools/perf/util/stat.c
> +++ b/tools/perf/util/stat.c
> @@ -152,11 +152,13 @@ static void evsel__free_stat_priv(struct evsel *evsel)
>  	zfree(&evsel->stats);
>  }
>  
> -static int evsel__alloc_prev_raw_counts(struct evsel *evsel, int ncpus, int nthreads)
> +static int evsel__alloc_prev_raw_counts(struct evsel *evsel)
>  {
> +	int cpu_map_nr = evsel__nr_cpus(evsel);
> +	int nthreads = perf_thread_map__nr(evsel->core.threads);
>  	struct perf_counts *counts;
>  
> -	counts = perf_counts__new(ncpus, nthreads);
> +	counts = perf_counts__new(cpu_map_nr, nthreads);
>  	if (counts)
>  		evsel->prev_raw_counts = counts;
>  
> @@ -177,12 +179,9 @@ static void evsel__reset_prev_raw_counts(struct evsel *evsel)
>  
>  static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
>  {
> -	int ncpus = evsel__nr_cpus(evsel);
> -	int nthreads = perf_thread_map__nr(evsel->core.threads);
> -
>  	if (evsel__alloc_stat_priv(evsel) < 0 ||
> -	    evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
> -	    (alloc_raw && evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
> +	    evsel__alloc_counts(evsel) < 0 ||
> +	    (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0))
>  		return -ENOMEM;
>  
>  	return 0;
> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 



From mr.bossman075 at gmail.com  Sun Jan  9 11:07:42 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 9 Jan 2022 14:07:42 -0500
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220105235157.8ED80C36AEB@smtp.kernel.org>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
Message-ID: <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>


>> +static const char * const pll_ref_sels[] = {"osc", "dummy", };
>> +static const char * const per_sels[] = {"ipg_pdof", "osc", };
>> +static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
>> +static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
>> +static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
>> +static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
>> +static const char *const pre_periph_sels[] = {
>> +       "pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
>> +static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
>> +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
>> +static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
>> +static const char *const lcdif_sels[] = {
>> +       "pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
>> +       "pll2_pfd1_594m", "pll3_pfd1_664_62m", };
>> +static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
>> +static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
> 
> Any chance this can use clk_parent_data instead of string names for
> parents?
> 
>> +
>> +static struct clk_hw **hws;
>> +static struct clk_hw_onecell_data *clk_hw_data;
>> +
>> +static void __init imxrt_clocks_common_init(void __iomem *base)
> 
> Drop __init and preferably inline this to the callsite.
> 
>> +{
>> +       /* Anatop clocks */
>> +       hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
>> +
>> +       hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
>> +               base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
>> +               base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
>> +               base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +       hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
>> +               base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
>> +
>> +       hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
>> +               "pll1_arm_ref_sel", base + 0x0, 0x7f);
>> +       hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
>> +               "pll2_sys_ref_sel", base + 0x30, 0x1);
>> +       hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
>> +               "pll3_usb_otg_ref_sel", base + 0x10, 0x1);
>> +       hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
>> +               "pll5_video_ref_sel", base + 0xa0, 0x7f);
>> +
>> +       /* PLL bypass out */
>> +       hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", base + 0x0, 16, 1,
>> +               pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", base + 0x30, 16, 1,
>> +               pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", base + 0x10, 16, 1,
>> +               pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
>> +       hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", base + 0xa0, 16, 1,
>> +               pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
>> +
>> +       hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
>> +               "pll5_video", base + 0xa0, 19, 2);
>> +       hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
>> +               "video_post_div_sel", base + 0x170, 30, 2);
>> +
>> +       hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
>> +
>> +       hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", base + 0x100, 0);
>> +       hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", base + 0x100, 1);
>> +       hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", base + 0x100, 2);
>> +       hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", base + 0xf0, 1);
>> +       hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", base + 0xf0, 3);
>> +}
>> +
>> +static int imxrt1050_clocks_probe(struct platform_device *pdev)
>> +{
>> +       void __iomem *ccm_base;
>> +       void __iomem *pll_base;
>> +       struct device *dev = &pdev->dev;
>> +       struct device_node *np = dev->of_node;
>> +       struct device_node *anp;
>> +       int ret;
>> +
>> +       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
>> +                                         IMXRT1050_CLK_END), GFP_KERNEL);
>> +       if (WARN_ON(!clk_hw_data))
>> +               return -ENOMEM;
>> +
>> +       clk_hw_data->num = IMXRT1050_CLK_END;
>> +       hws = clk_hw_data->hws;
>> +
>> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> 
> Use clk_parent_data instead and reference the binding name with .fw_name

Hi Stephen, sorry to bother you again.
I'm wondering if adding `clk_parent_data` is necessary as it seems like 
it wold be a big change and the other IMX boards haven't implemented 
this yet would it be okay if I don't do this, or if it is necessary 
could you link to a patch set to change it.



From pr-tracker-bot at kernel.org  Sun Jan  9 11:25:57 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sun, 09 Jan 2022 19:25:57 +0000
Subject: [GIT PULL] SoC: One more fix for 5.16
In-Reply-To: <YdqN9GxRTQYVA/f4@lx2k>
References: <YdqN9GxRTQYVA/f4@lx2k>
Message-ID: <164175635732.32020.17846257667340116617.pr-tracker-bot@kernel.org>

The pull request you sent on Sat, 8 Jan 2022 23:25:40 -0800:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-fixes-5.16-5

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/95350123bb5568a7d95e3789225144bd1a154274

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From linux at roeck-us.net  Sun Jan  9 12:05:26 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Sun, 9 Jan 2022 12:05:26 -0800
Subject: [PATCH v2] fsi: Aspeed: Fix a potential double free
In-Reply-To: <3b5c9b693749a956b525c54bed0eeac9f958b8e8.1641734402.git.christophe.jaillet@wanadoo.fr>
References: <3b5c9b693749a956b525c54bed0eeac9f958b8e8.1641734402.git.christophe.jaillet@wanadoo.fr>
Message-ID: <5ecd3555-092c-e11d-deb4-98da7c0e3e01@roeck-us.net>

On 1/9/22 5:20 AM, Christophe JAILLET wrote:
> A struct device can never be devm_alloc()'ed.
> Here, it is embedded in "struct fsi_master", and "struct fsi_master" is
> embedded in "struct fsi_master_aspeed".
> 
> Since "struct device" is embedded, the data structure embedding it must be
> released with the release function, as is already done here.
> 
> So use kzalloc() instead of devm_kzalloc() when allocating "aspeed".
> This prevent a potential double free().
> 
> Fixes: 606397d67f41 ("fsi: Add ast2600 master driver")
> Suggested-by: Greg KH <gregkh at linuxfoundation.org>
> Suggested-by: Guenter Roeck <linux at roeck-us.net>
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> v2: Keep the release function which is correct
>      s/devm_kzalloc()/kzalloc()/ instead
> ---
>   drivers/fsi/fsi-master-aspeed.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
> index 8606e55c1721..ae6319818b14 100644
> --- a/drivers/fsi/fsi-master-aspeed.c
> +++ b/drivers/fsi/fsi-master-aspeed.c
> @@ -542,7 +542,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
>   		return rc;
>   	}
>   
> -	aspeed = devm_kzalloc(&pdev->dev, sizeof(*aspeed), GFP_KERNEL);
> +	aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL);

Unfortunately it isn't that easy. error handling in the probe function must take this
into account and free the memory. Looking at that exposes another bug: The
failure in opb_readl() should not result in a direct return but disable and
unprepare the clock.

Guenter


From clabbe.montjoie at gmail.com  Sun Jan  9 12:45:01 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Sun, 9 Jan 2022 21:45:01 +0100
Subject: [PATCH v1] sun4i-emac.c: enable emac tx dma
In-Reply-To: <tencent_E4BA4D6105A46CCC1E8AEF48057EA5FE5B08@qq.com>
References: <YdLhQjUTobcLq73j@Red>
 <tencent_E4BA4D6105A46CCC1E8AEF48057EA5FE5B08@qq.com>
Message-ID: <YdtJTQJJ4aEUcp/D@Red>

Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee at foxmail.com a ?crit :
> From: conley <conleylee at foxmail.com>
> 
> Hello
> I am reading the R40 user manual and trying to create a new path to enable
> emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> I try to enable emac tx dma channel by the follow steps:
> 1. enable tx dma mode
> 2. set packet lengths
> 2. move data from skb to tx fifo by using dma in xmit function.
> 3. start transfer from tx fifo to phy in dma tx done callback
> 
> But it doesn't work. emac tx interrupt and dma finished interrupt are
> raised, but no packets are transmitted (I test it by tcpdump).
> Do you know how to configure the emac tx dma correctly? Thanks ~
> 

Hello

Here are my thoughts to help you:
- Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
- If it was a patch, "v1" is not necessary
- Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
- I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
- Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
- Knowing also the board (and so PHY, modes etc...) could help
- I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
- For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).

Anyway, I will try to test your patch on my a10 board

Regards


From christophe.jaillet at wanadoo.fr  Sun Jan  9 13:56:10 2022
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sun,  9 Jan 2022 22:56:10 +0100
Subject: [PATCH v3] fsi: Aspeed: Fix a potential double free
Message-ID: <2c123f8b0a40dc1a061fae982169fe030b4f47e6.1641765339.git.christophe.jaillet@wanadoo.fr>

A struct device can never be devm_alloc()'ed.
Here, it is embedded in "struct fsi_master", and "struct fsi_master" is
embedded in "struct fsi_master_aspeed".

Since "struct device" is embedded, the data structure embedding it must be
released with the release function, as is already done here.

So use kzalloc() instead of devm_kzalloc() when allocating "aspeed" and
update all error handling branches accordingly.

This prevent a potential double free().

This also fix another issue if opb_readl() fails. Instead of a direct
return, it now jumps in the error handling path.

Fixes: 606397d67f41 ("fsi: Add ast2600 master driver")
Suggested-by: Greg KH <gregkh at linuxfoundation.org>
Suggested-by: Guenter Roeck <linux at roeck-us.net>
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
v2: Keep the release function which is correct
    s/devm_kzalloc()/kzalloc()/ instead

v3: Update the error handling path to free "aspeed" [Guenter Roeck]
    Fix another issue when opb_readl() fails [Guenter Roeck]

I hope that fixing both issues in the same patch is ok. It makes no sense
to me not to update the goto to the correct label if opb_readl() fails.
---
 drivers/fsi/fsi-master-aspeed.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index 8606e55c1721..0bed2fab8055 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -542,25 +542,28 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 		return rc;
 	}
 
-	aspeed = devm_kzalloc(&pdev->dev, sizeof(*aspeed), GFP_KERNEL);
+	aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL);
 	if (!aspeed)
 		return -ENOMEM;
 
 	aspeed->dev = &pdev->dev;
 
 	aspeed->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(aspeed->base))
-		return PTR_ERR(aspeed->base);
+	if (IS_ERR(aspeed->base)) {
+		rc = PTR_ERR(aspeed->base);
+		goto err_free_aspeed;
+	}
 
 	aspeed->clk = devm_clk_get(aspeed->dev, NULL);
 	if (IS_ERR(aspeed->clk)) {
 		dev_err(aspeed->dev, "couldn't get clock\n");
-		return PTR_ERR(aspeed->clk);
+		rc = PTR_ERR(aspeed->clk);
+		goto err_free_aspeed;
 	}
 	rc = clk_prepare_enable(aspeed->clk);
 	if (rc) {
 		dev_err(aspeed->dev, "couldn't enable clock\n");
-		return rc;
+		goto err_free_aspeed;
 	}
 
 	rc = setup_cfam_reset(aspeed);
@@ -595,7 +598,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 	rc = opb_readl(aspeed, ctrl_base + FSI_MVER, &raw);
 	if (rc) {
 		dev_err(&pdev->dev, "failed to read hub version\n");
-		return rc;
+		goto err_release;
 	}
 
 	reg = be32_to_cpu(raw);
@@ -634,6 +637,8 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 
 err_release:
 	clk_disable_unprepare(aspeed->clk);
+err_free_aspeed:
+	kfree(aspeed);
 	return rc;
 }
 
-- 
2.32.0



From kuba at kernel.org  Sun Jan  9 16:43:33 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Sun, 9 Jan 2022 16:43:33 -0800
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix error checking in
 mtk_mac_config()
In-Reply-To: <20220108155003.3991055-1-trix@redhat.com>
References: <20220108155003.3991055-1-trix@redhat.com>
Message-ID: <20220109164333.61dc2e89@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Sat,  8 Jan 2022 07:50:03 -0800 trix at redhat.com wrote:
> From: Tom Rix <trix at redhat.com>
> 
> Clang static analysis reports this problem
> mtk_eth_soc.c:394:7: warning: Branch condition evaluates
>   to a garbage value
>                 if (err)
>                     ^~~
> 
> err is not initialized and only conditionally set.
> Check err consistently with the rest of mtk_mac_config(),
> after even possible setting.
> 
> Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
> Signed-off-by: Tom Rix <trix at redhat.com>
> ---
>  drivers/net/ethernet/mediatek/mtk_eth_soc.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> index b67b4323cff08..a27e548488584 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
> @@ -385,14 +385,16 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
>  		       0 : mac->id;
>  
>  		/* Setup SGMIISYS with the determined property */
> -		if (state->interface != PHY_INTERFACE_MODE_SGMII)
> +		if (state->interface != PHY_INTERFACE_MODE_SGMII) {
>  			err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
>  							 state);
> -		else if (phylink_autoneg_inband(mode))
> +			if (err)
> +				goto init_err;
> +		} else if (phylink_autoneg_inband(mode)) {
>  			err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
> -
> -		if (err)
> -			goto init_err;
> +			if (err)
> +				goto init_err;
> +		}
>  
>  		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
>  				   SYSCFG0_SGMII_MASK, val);

Why not init err to 0 before the if or add an else err = 0; branch?


From robh at kernel.org  Sun Jan  9 16:56:30 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 9 Jan 2022 18:56:30 -0600
Subject: [PATCH v7 01/10] dt-bindings: vendor-prefixes: Add Sunplus
In-Reply-To: <2e74a1339a5ea54d92fdc4d1998a2b169e23b82b.1640154492.git.qinjian@cqplus1.com>
References: <cover.1640154492.git.qinjian@cqplus1.com>
 <2e74a1339a5ea54d92fdc4d1998a2b169e23b82b.1640154492.git.qinjian@cqplus1.com>
Message-ID: <YduEPlMoAR9KXoaa@robh.at.kernel.org>

On Wed, Dec 22, 2021 at 03:05:57PM +0800, Qin Jian wrote:
> Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)
> 
> Acked-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Qin Jian <qinjian at cqplus1.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)

As this one is a dependency for other series, applied for 5.17.

Rob


From chun-jie.chen at mediatek.com  Sun Jan  9 16:58:59 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 08:58:59 +0800
Subject: [v2 0/3] Integrate vppsys with mtk-mmsys in MT8195
Message-ID: <20220110005902.27148-1-chun-jie.chen@mediatek.com>

This patch series is based on 5.16-rc6.

change since v1:
- remove vppsys in clock document
- unregister clock when fail to add clock provider

Chun-Jie Chen (3):
  clk: mediatek: Add error handle when fail to register clock provider
  dt-bindings: ARM: Mediatek: Remove vppsys in MT8195 clock document
  clk: mediatek: Integrate vppsys with mtk-mmsys in MT8195

 .../arm/mediatek/mediatek,mt8195-clock.yaml   | 16 -------
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c  |  5 ++-
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c  |  5 ++-
 drivers/clk/mediatek/clk-mt8195-topckgen.c    |  5 ++-
 drivers/clk/mediatek/clk-mt8195-vdo0.c        |  5 ++-
 drivers/clk/mediatek/clk-mt8195-vdo1.c        |  5 ++-
 drivers/clk/mediatek/clk-mt8195-vpp0.c        | 42 ++++++++++++-------
 drivers/clk/mediatek/clk-mt8195-vpp1.c        | 42 ++++++++++++-------
 drivers/clk/mediatek/clk-mtk.c                | 14 ++++++-
 drivers/clk/mediatek/clk-mtk.h                |  1 +
 10 files changed, 89 insertions(+), 51 deletions(-)

--
2.18.0



From chun-jie.chen at mediatek.com  Sun Jan  9 16:59:00 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 08:59:00 +0800
Subject: [v2 1/3] clk: mediatek: Add error handle when fail to register clock
 provider
In-Reply-To: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110005902.27148-2-chun-jie.chen@mediatek.com>

Need to deference registered clocks when fail to
regisiter clock provider.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c |  5 ++++-
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c |  5 +++--
 drivers/clk/mediatek/clk-mt8195-topckgen.c   |  5 ++++-
 drivers/clk/mediatek/clk-mt8195-vdo0.c       |  5 ++++-
 drivers/clk/mediatek/clk-mt8195-vdo1.c       |  5 ++++-
 drivers/clk/mediatek/clk-mtk.c               | 14 +++++++++++++-
 drivers/clk/mediatek/clk-mtk.h               |  1 +
 7 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
index 6156ceeed71e..be0a716e24d2 100644
--- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
+++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
@@ -126,10 +126,13 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_apmixed_data;
+		goto unregister_clk;
 
 	return r;
 
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
 free_apmixed_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
index f1c84186346e..bc5fc84e48dd 100644
--- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
+++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
@@ -68,11 +68,12 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
 	mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_apusys_pll_data;
+		goto unregister_clk;
 
 	return r;
 
-free_apusys_pll_data:
+unregister_clk:
+	mtk_clk_unregister(clk_data);
 	mtk_free_clk_data(clk_data);
 	return r;
 }
diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
index 3e2aba9c40bb..02a1801dfe86 100644
--- a/drivers/clk/mediatek/clk-mt8195-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
@@ -1254,10 +1254,13 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
 	if (r)
-		goto free_top_data;
+		goto unregister_clk;
 
 	return r;
 
+unregister_clk:
+	mtk_clk_unregister(top_clk_data);
+
 free_top_data:
 	mtk_free_clk_data(top_clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
index f7ff7618c714..b7ceb6c7a33f 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
@@ -105,10 +105,13 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_vdo0_data;
+		goto unregister_clk;
 
 	return r;
 
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
 free_vdo0_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
index 03df8eae8838..cca90c2632a1 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
@@ -122,10 +122,13 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_vdo1_data;
+		goto unregister_clk;
 
 	return r;
 
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
 free_vdo1_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 8d5791b3f460..ee4de1094458 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -303,6 +303,15 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 	}
 }
 
+void mtk_clk_unregister(struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	for (i = 0; i < clk_data->clk_num; i++)
+		clk_unregister(clk_data->clks[i]);
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister);
+
 int mtk_clk_simple_probe(struct platform_device *pdev)
 {
 	const struct mtk_clk_desc *mcd;
@@ -324,10 +333,13 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_data;
+		goto unregister_clk;
 
 	return r;
 
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
 free_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 0ff289d93452..4c0958f66f51 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -200,6 +200,7 @@ struct mtk_clk_divider {
 void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			int num, void __iomem *base, spinlock_t *lock,
 				struct clk_onecell_data *clk_data);
+void mtk_clk_unregister(struct clk_onecell_data *clk_data);
 
 struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
 void mtk_free_clk_data(struct clk_onecell_data *clk_data);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sun Jan  9 16:59:01 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 08:59:01 +0800
Subject: [v2 2/3] dt-bindings: ARM: Mediatek: Remove vppsys in MT8195 clock
 document
In-Reply-To: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110005902.27148-3-chun-jie.chen@mediatek.com>

vppsys0 and vppsys1 sub-system are both integrated with mmsys driver,
should be describe in mediatek,mmsys.yaml

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 .../arm/mediatek/mediatek,mt8195-clock.yaml      | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
index 17fcbb45d121..d62d60181147 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
@@ -28,11 +28,9 @@ properties:
           - mediatek,mt8195-imp_iic_wrap_s
           - mediatek,mt8195-imp_iic_wrap_w
           - mediatek,mt8195-mfgcfg
-          - mediatek,mt8195-vppsys0
           - mediatek,mt8195-wpesys
           - mediatek,mt8195-wpesys_vpp0
           - mediatek,mt8195-wpesys_vpp1
-          - mediatek,mt8195-vppsys1
           - mediatek,mt8195-imgsys
           - mediatek,mt8195-imgsys1_dip_top
           - mediatek,mt8195-imgsys1_dip_nr
@@ -92,13 +90,6 @@ examples:
         #clock-cells = <1>;
     };
 
-  - |
-    vppsys0: clock-controller at 14000000 {
-        compatible = "mediatek,mt8195-vppsys0";
-        reg = <0x14000000 0x1000>;
-        #clock-cells = <1>;
-    };
-
   - |
     wpesys: clock-controller at 14e00000 {
         compatible = "mediatek,mt8195-wpesys";
@@ -120,13 +111,6 @@ examples:
         #clock-cells = <1>;
     };
 
-  - |
-    vppsys1: clock-controller at 14f00000 {
-        compatible = "mediatek,mt8195-vppsys1";
-        reg = <0x14f00000 0x1000>;
-        #clock-cells = <1>;
-    };
-
   - |
     imgsys: clock-controller at 15000000 {
         compatible = "mediatek,mt8195-imgsys";
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sun Jan  9 16:59:02 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 08:59:02 +0800
Subject: [v2 3/3] clk: mediatek: Integrate vppsys with mtk-mmsys in MT8195
In-Reply-To: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110005902.27148-4-chun-jie.chen@mediatek.com>

Integrate vpp0 and vpp1 with mtk-mmsys driver which
will populate device by platform_device_register_data
to start vppsys clock driver.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8195-vpp0.c | 42 +++++++++++++++++---------
 drivers/clk/mediatek/clk-mt8195-vpp1.c | 42 +++++++++++++++++---------
 2 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8195-vpp0.c b/drivers/clk/mediatek/clk-mt8195-vpp0.c
index c3241466a8d0..68c375bfce8b 100644
--- a/drivers/clk/mediatek/clk-mt8195-vpp0.c
+++ b/drivers/clk/mediatek/clk-mt8195-vpp0.c
@@ -86,25 +86,39 @@ static const struct mtk_gate vpp0_clks[] = {
 	GATE_VPP0_2(CLK_VPP0_WARP1_MDP_DL_ASYNC, "vpp0_warp1_mdp_dl_async", "top_wpe_vpp", 3),
 };
 
-static const struct mtk_clk_desc vpp0_desc = {
-	.clks = vpp0_clks,
-	.num_clks = ARRAY_SIZE(vpp0_clks),
-};
+static int clk_mt8195_vpp0_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data;
+	int r;
 
-static const struct of_device_id of_match_clk_mt8195_vpp0[] = {
-	{
-		.compatible = "mediatek,mt8195-vppsys0",
-		.data = &vpp0_desc,
-	}, {
-		/* sentinel */
-	}
-};
+	clk_data = mtk_alloc_clk_data(CLK_VPP0_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	r = mtk_clk_register_gates(node, vpp0_clks, ARRAY_SIZE(vpp0_clks), clk_data);
+	if (r)
+		goto free_vpp0_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
+free_vpp0_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
 
 static struct platform_driver clk_mt8195_vpp0_drv = {
-	.probe = mtk_clk_simple_probe,
+	.probe = clk_mt8195_vpp0_probe,
 	.driver = {
 		.name = "clk-mt8195-vpp0",
-		.of_match_table = of_match_clk_mt8195_vpp0,
 	},
 };
 builtin_platform_driver(clk_mt8195_vpp0_drv);
diff --git a/drivers/clk/mediatek/clk-mt8195-vpp1.c b/drivers/clk/mediatek/clk-mt8195-vpp1.c
index ce0b9a40a179..237077c60f54 100644
--- a/drivers/clk/mediatek/clk-mt8195-vpp1.c
+++ b/drivers/clk/mediatek/clk-mt8195-vpp1.c
@@ -84,25 +84,39 @@ static const struct mtk_gate vpp1_clks[] = {
 	GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_26M, "vpp1_vpp_split_26m", "clk26m", 26),
 };
 
-static const struct mtk_clk_desc vpp1_desc = {
-	.clks = vpp1_clks,
-	.num_clks = ARRAY_SIZE(vpp1_clks),
-};
+static int clk_mt8195_vpp1_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data;
+	int r;
 
-static const struct of_device_id of_match_clk_mt8195_vpp1[] = {
-	{
-		.compatible = "mediatek,mt8195-vppsys1",
-		.data = &vpp1_desc,
-	}, {
-		/* sentinel */
-	}
-};
+	clk_data = mtk_alloc_clk_data(CLK_VPP1_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	r = mtk_clk_register_gates(node, vpp1_clks, ARRAY_SIZE(vpp1_clks), clk_data);
+	if (r)
+		goto free_vpp1_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
+free_vpp1_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
 
 static struct platform_driver clk_mt8195_vpp1_drv = {
-	.probe = mtk_clk_simple_probe,
+	.probe = clk_mt8195_vpp1_probe,
 	.driver = {
 		.name = "clk-mt8195-vpp1",
-		.of_match_table = of_match_clk_mt8195_vpp1,
 	},
 };
 builtin_platform_driver(clk_mt8195_vpp1_drv);
-- 
2.18.0



From cgel.zte at gmail.com  Sun Jan  9 17:27:30 2022
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Mon, 10 Jan 2022 01:27:30 +0000
Subject: [PATCH] drivers/pinctrl: remove redundant ret variable
Message-ID: <20220110012730.643927-1-chi.minghao@zte.com.cn>

From: Minghao Chi <chi.minghao at zte.com.cn>

Return value from pxa2xx_pinctrl_init() directly instead
of taking this in another redundant variable.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Minghao Chi <chi.minghao at zte.com.cn>
Signed-off-by: CGEL ZTE <cgel.zte at gmail.com>
---
 drivers/pinctrl/pxa/pinctrl-pxa27x.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pxa/pinctrl-pxa27x.c b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
index 48ccfb50b23e..ff9302e4803a 100644
--- a/drivers/pinctrl/pxa/pinctrl-pxa27x.c
+++ b/drivers/pinctrl/pxa/pinctrl-pxa27x.c
@@ -504,7 +504,7 @@ static const struct pxa_desc_pin pxa27x_pins[] = {
 
 static int pxa27x_pinctrl_probe(struct platform_device *pdev)
 {
-	int ret, i;
+	int i;
 	void __iomem *base_af[8];
 	void __iomem *base_dir[4];
 	void __iomem *base_sleep[4];
@@ -532,9 +532,8 @@ static int pxa27x_pinctrl_probe(struct platform_device *pdev)
 	for (i = 0; i < ARRAY_SIZE(base_sleep); i++)
 		base_sleep[i] = base_sleep[0] + sizeof(base_af[0]) * i;
 
-	ret = pxa2xx_pinctrl_init(pdev, pxa27x_pins, ARRAY_SIZE(pxa27x_pins),
+	return pxa2xx_pinctrl_init(pdev, pxa27x_pins, ARRAY_SIZE(pxa27x_pins),
 				  base_af, base_dir, base_sleep);
-	return ret;
 }
 
 static const struct of_device_id pxa27x_pinctrl_match[] = {
-- 
2.25.1



From kabel at kernel.org  Sun Jan  9 17:49:55 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:49:55 +0100
Subject: [PATCH v2 00/23] PCI: aardvark controller fixes BATCH 4
Message-ID: <20220110015018.26359-1-kabel@kernel.org>

Hello Lorenzo, Bjorn and Marc,

this is v2 of fourth batch of fixes for the Aardvark PCIe controller
driver.

Stuff is converted to new interrupt APIs and recommendations from Marc.
Marc, could you look at these and acknowledge or comment?

This series mainly fixes and adds support for stuff around interrupts:
the most important thing is fixing MSI support.

The series is rebased on helgaas/next.

Marek

Changes since v1:
- added patches converting irq_chip and msi_domain_info structures into
  static driver structures, instead of creating them dynamically, as
  suggested by Marc
- added some small patches that should be easy to review
  - conversion to use constants from linux/pci.h instead of ad-hoc
    constants int patch 1
  - use dev_fwnode(dev) instead of of_node_to_fwnode(dev->of_node) in
    patch 8
  - fix of a comment in patch 22

Marek Beh?n (6):
  PCI: aardvark: Make MSI irq_chip structures static driver structures
  PCI: aardvark: Make msi_domain_info structure a static driver
    structure
  PCI: aardvark: Use dev_fwnode() instead of
    of_node_to_fwnode(dev->of_node)
  PCI: aardvark: Drop __maybe_unused from advk_pcie_disable_phy()
  PCI: aardvark: Update comment about link going down after link-up
  PCI: aardvark: Make main irq_chip structure a static driver structure

Pali Roh?r (17):
  PCI: aardvark: Replace custom PCIE_CORE_INT_* macros with
    PCI_INTERRUPT_*
  PCI: aardvark: Fix reading MSI interrupt number
  PCI: aardvark: Fix support for MSI interrupts
  PCI: aardvark: Rewrite IRQ code to chained IRQ handler
  PCI: aardvark: Check return value of generic_handle_domain_irq() when
    processing INTx IRQ
  PCI: aardvark: Refactor unmasking summary MSI interrupt
  PCI: aardvark: Add support for masking MSI interrupts
  PCI: aardvark: Fix setting MSI address
  PCI: aardvark: Enable MSI-X support
  PCI: aardvark: Add support for ERR interrupt on emulated bridge
  PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
  PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE and
    PCI_EXP_RTSTA_PME on emulated bridge
  PCI: aardvark: Add support for PME interrupts
  PCI: aardvark: Fix support for PME requester on emulated bridge
  PCI: aardvark: Use separate INTA interrupt for emulated root bridge
  PCI: aardvark: Remove irq_mask_ack callback for INTx interrupts
  PCI: aardvark: Don't mask irq when mapping

 drivers/pci/controller/pci-aardvark.c | 415 +++++++++++++++++---------
 1 file changed, 281 insertions(+), 134 deletions(-)

-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:49:56 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:49:56 +0100
Subject: [PATCH v2 01/23] PCI: aardvark: Replace custom PCIE_CORE_INT_* macros
 with PCI_INTERRUPT_*
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-2-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Header file linux/pci.h defines enum pci_interrupt_pin with corresponding
PCI_INTERRUPT_* values.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index ec0df426863d..62baddd2ca95 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -39,10 +39,6 @@
 #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN			BIT(6)
 #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHCK			BIT(7)
 #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV			BIT(8)
-#define     PCIE_CORE_INT_A_ASSERT_ENABLE			1
-#define     PCIE_CORE_INT_B_ASSERT_ENABLE			2
-#define     PCIE_CORE_INT_C_ASSERT_ENABLE			3
-#define     PCIE_CORE_INT_D_ASSERT_ENABLE			4
 /* PIO registers base address and register offsets */
 #define PIO_BASE_ADDR				0x4000
 #define PIO_CTRL				(PIO_BASE_ADDR + 0x0)
@@ -968,7 +964,7 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
 	bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64);
 
 	/* Support interrupt A for MSI feature */
-	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
+	bridge->conf.intpin = PCI_INTERRUPT_INTA;
 
 	/* Aardvark HW provides PCIe Capability structure in version 2 */
 	bridge->pcie_conf.cap = cpu_to_le16(2);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:49:58 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:49:58 +0100
Subject: [PATCH v2 03/23] PCI: aardvark: Fix support for MSI interrupts
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-4-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Aardvark hardware supports Multi-MSI and MSI_FLAG_MULTI_PCI_MSI is already
set for the MSI chip. But when allocating MSI interrupt numbers for
Multi-MSI, the numbers need to be properly aligned, otherwise endpoint
devices send MSI interrupt with incorrect numbers.

Fix this issue by using function bitmap_find_free_region() instead of
bitmap_find_next_zero_area().

To ensure that aligned MSI interrupt numbers are used by endpoint devices,
we cannot use Linux virtual irq numbers (as they are random and not
properly aligned). Instead we need to use the aligned hwirq numbers.

This change fixes receiving MSI interrupts on Armada 3720 boards and
allows using NVMe disks which use Multi-MSI feature with 3 interrupts.

Without this NVMe disks freeze booting as linux nvme-core.c is waiting
60s for an interrupt.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index fd95ad64c887..346d38835539 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1189,7 +1189,7 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,
 
 	msg->address_lo = lower_32_bits(msi_msg);
 	msg->address_hi = upper_32_bits(msi_msg);
-	msg->data = data->irq;
+	msg->data = data->hwirq;
 }
 
 static int advk_msi_set_affinity(struct irq_data *irq_data,
@@ -1206,15 +1206,11 @@ static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 	int hwirq, i;
 
 	mutex_lock(&pcie->msi_used_lock);
-	hwirq = bitmap_find_next_zero_area(pcie->msi_used, MSI_IRQ_NUM,
-					   0, nr_irqs, 0);
-	if (hwirq >= MSI_IRQ_NUM) {
-		mutex_unlock(&pcie->msi_used_lock);
-		return -ENOSPC;
-	}
-
-	bitmap_set(pcie->msi_used, hwirq, nr_irqs);
+	hwirq = bitmap_find_free_region(pcie->msi_used, MSI_IRQ_NUM,
+					order_base_2(nr_irqs));
 	mutex_unlock(&pcie->msi_used_lock);
+	if (hwirq < 0)
+		return -ENOSPC;
 
 	for (i = 0; i < nr_irqs; i++)
 		irq_domain_set_info(domain, virq + i, hwirq + i,
@@ -1232,7 +1228,7 @@ static void advk_msi_irq_domain_free(struct irq_domain *domain,
 	struct advk_pcie *pcie = domain->host_data;
 
 	mutex_lock(&pcie->msi_used_lock);
-	bitmap_clear(pcie->msi_used, d->hwirq, nr_irqs);
+	bitmap_release_region(pcie->msi_used, d->hwirq, order_base_2(nr_irqs));
 	mutex_unlock(&pcie->msi_used_lock);
 }
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:49:57 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:49:57 +0100
Subject: [PATCH v2 02/23] PCI: aardvark: Fix reading MSI interrupt number
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-3-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

In advk_pcie_handle_msi() the authors expect that when bit i in the W1C
register PCIE_MSI_STATUS_REG is cleared, the PCIE_MSI_PAYLOAD_REG is
updated to contain the MSI number corresponding to index i.

Experiments show that this is not so, and instead PCIE_MSI_PAYLOAD_REG
always contains the number of the last received MSI, overall.

Do not read PCIE_MSI_PAYLOAD_REG register for determining MSI interrupt
number. Since Aardvark already forbids more than 32 interrupts and uses
own allocated hwirq numbers, the msi_idx already corresponds to the
received MSI number.

Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 62baddd2ca95..fd95ad64c887 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1393,7 +1393,6 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 {
 	u32 msi_val, msi_mask, msi_status, msi_idx;
-	u16 msi_data;
 
 	msi_mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
 	msi_val = advk_readl(pcie, PCIE_MSI_STATUS_REG);
@@ -1403,13 +1402,9 @@ static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 		if (!(BIT(msi_idx) & msi_status))
 			continue;
 
-		/*
-		 * msi_idx contains bits [4:0] of the msi_data and msi_data
-		 * contains 16bit MSI interrupt number
-		 */
 		advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG);
-		msi_data = advk_readl(pcie, PCIE_MSI_PAYLOAD_REG) & PCIE_MSI_DATA_MASK;
-		generic_handle_irq(msi_data);
+		if (generic_handle_domain_irq(pcie->msi_inner_domain, msi_idx) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unexpected MSI 0x%02x\n", msi_idx);
 	}
 
 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING,
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:49:59 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:49:59 +0100
Subject: [PATCH v2 04/23] PCI: aardvark: Rewrite IRQ code to chained IRQ
 handler
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-5-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Rewrite the code to use irq_set_chained_handler_and_data() handler with
chained_irq_enter() and chained_irq_exit() processing instead of using
devm_request_irq().

advk_pcie_irq_handler() reads IRQ status bits and calls other functions
based on which bits are set. These functions then read its own IRQ status
bits and calls other aardvark functions based on these bits. Finally
generic_handle_domain_irq() with translated linux IRQ numbers are called.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 48 +++++++++++++++------------
 1 file changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 346d38835539..315147f2812f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -269,6 +269,7 @@ struct advk_pcie {
 		u32 actions;
 	} wins[OB_WIN_COUNT];
 	u8 wins_count;
+	int irq;
 	struct irq_domain *irq_domain;
 	struct irq_chip irq_chip;
 	raw_spinlock_t irq_lock;
@@ -1437,21 +1438,26 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	}
 }
 
-static irqreturn_t advk_pcie_irq_handler(int irq, void *arg)
+static void advk_pcie_irq_handler(struct irq_desc *desc)
 {
-	struct advk_pcie *pcie = arg;
-	u32 status;
+	struct advk_pcie *pcie = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	u32 val, mask, status;
 
-	status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
-	if (!(status & PCIE_IRQ_CORE_INT))
-		return IRQ_NONE;
+	chained_irq_enter(chip, desc);
 
-	advk_pcie_handle_int(pcie);
+	val = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
+	mask = advk_readl(pcie, HOST_CTRL_INT_MASK_REG);
+	status = val & ((~mask) & PCIE_IRQ_ALL_MASK);
 
-	/* Clear interrupt */
-	advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
+	if (status & PCIE_IRQ_CORE_INT) {
+		advk_pcie_handle_int(pcie);
 
-	return IRQ_HANDLED;
+		/* Clear interrupt */
+		advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
+	}
+
+	chained_irq_exit(chip, desc);
 }
 
 static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie)
@@ -1518,7 +1524,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
 	struct advk_pcie *pcie;
 	struct pci_host_bridge *bridge;
 	struct resource_entry *entry;
-	int ret, irq;
+	int ret;
 
 	bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie));
 	if (!bridge)
@@ -1604,17 +1610,9 @@ static int advk_pcie_probe(struct platform_device *pdev)
 	if (IS_ERR(pcie->base))
 		return PTR_ERR(pcie->base);
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	ret = devm_request_irq(dev, irq, advk_pcie_irq_handler,
-			       IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie",
-			       pcie);
-	if (ret) {
-		dev_err(dev, "Failed to register interrupt\n");
-		return ret;
-	}
+	pcie->irq = platform_get_irq(pdev, 0);
+	if (pcie->irq < 0)
+		return pcie->irq;
 
 	pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node,
 						       "reset-gpios", 0,
@@ -1663,11 +1661,14 @@ static int advk_pcie_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	irq_set_chained_handler_and_data(pcie->irq, advk_pcie_irq_handler, pcie);
+
 	bridge->sysdata = pcie;
 	bridge->ops = &advk_pcie_ops;
 
 	ret = pci_host_probe(bridge);
 	if (ret < 0) {
+		irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 		advk_pcie_remove_msi_irq_domain(pcie);
 		advk_pcie_remove_irq_domain(pcie);
 		return ret;
@@ -1715,6 +1716,9 @@ static int advk_pcie_remove(struct platform_device *pdev)
 	advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
 	advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
 
+	/* Remove IRQ handler */
+	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
+
 	/* Remove IRQ domains */
 	advk_pcie_remove_msi_irq_domain(pcie);
 	advk_pcie_remove_irq_domain(pcie);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:00 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:00 +0100
Subject: [PATCH v2 05/23] PCI: aardvark: Check return value of
 generic_handle_domain_irq() when processing INTx IRQ
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-6-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

It is possible that we receive spurious INTx interrupt. Check for the
return value of generic_handle_domain_irq() when processing INTx IRQ.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 315147f2812f..252033a46e1e 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1434,7 +1434,9 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 		advk_writel(pcie, PCIE_ISR1_INTX_ASSERT(i),
 			    PCIE_ISR1_REG);
 
-		generic_handle_domain_irq(pcie->irq_domain, i);
+		if (generic_handle_domain_irq(pcie->irq_domain, i) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unexpected INT%c IRQ\n",
+					    (char)i + 'A');
 	}
 }
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:01 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:01 +0100
Subject: [PATCH v2 06/23] PCI: aardvark: Make MSI irq_chip structures static
 driver structures
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-7-kabel@kernel.org>

Marc Zyngier says [1] that we should use struct irq_chip as a global
static struct in the driver. Even though the structure currently
contains a dynamic member (parent_device), Marc says [2] that he plans
to kill it and make the structure completely static.

Convert Aardvark's priv->msi_bottom_irq_chip and priv->msi_irq_chip to
static driver structure.

[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz at kernel.org/
[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz at kernel.org/

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 252033a46e1e..441100bacb68 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -275,8 +275,6 @@ struct advk_pcie {
 	raw_spinlock_t irq_lock;
 	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
-	struct irq_chip msi_bottom_irq_chip;
-	struct irq_chip msi_irq_chip;
 	struct msi_domain_info msi_domain_info;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
 	struct mutex msi_used_lock;
@@ -1199,6 +1197,12 @@ static int advk_msi_set_affinity(struct irq_data *irq_data,
 	return -EINVAL;
 }
 
+static struct irq_chip advk_msi_bottom_irq_chip = {
+	.name			= "MSI",
+	.irq_compose_msi_msg	= advk_msi_irq_compose_msi_msg,
+	.irq_set_affinity	= advk_msi_set_affinity,
+};
+
 static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 				     unsigned int virq,
 				     unsigned int nr_irqs, void *args)
@@ -1215,7 +1219,7 @@ static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
 
 	for (i = 0; i < nr_irqs; i++)
 		irq_domain_set_info(domain, virq + i, hwirq + i,
-				    &pcie->msi_bottom_irq_chip,
+				    &advk_msi_bottom_irq_chip,
 				    domain->host_data, handle_simple_irq,
 				    NULL, NULL);
 
@@ -1285,29 +1289,23 @@ static const struct irq_domain_ops advk_pcie_irq_domain_ops = {
 	.xlate = irq_domain_xlate_onecell,
 };
 
+static struct irq_chip advk_msi_irq_chip = {
+	.name = "advk-MSI",
+};
+
 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 {
 	struct device *dev = &pcie->pdev->dev;
 	struct device_node *node = dev->of_node;
-	struct irq_chip *bottom_ic, *msi_ic;
 	struct msi_domain_info *msi_di;
 	phys_addr_t msi_msg_phys;
 
 	mutex_init(&pcie->msi_used_lock);
 
-	bottom_ic = &pcie->msi_bottom_irq_chip;
-
-	bottom_ic->name = "MSI";
-	bottom_ic->irq_compose_msi_msg = advk_msi_irq_compose_msi_msg;
-	bottom_ic->irq_set_affinity = advk_msi_set_affinity;
-
-	msi_ic = &pcie->msi_irq_chip;
-	msi_ic->name = "advk-MSI";
-
 	msi_di = &pcie->msi_domain_info;
 	msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
 		MSI_FLAG_MULTI_PCI_MSI;
-	msi_di->chip = msi_ic;
+	msi_di->chip = &advk_msi_irq_chip;
 
 	msi_msg_phys = virt_to_phys(&pcie->msi_msg);
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:02 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:02 +0100
Subject: [PATCH v2 07/23] PCI: aardvark: Make msi_domain_info structure a
 static driver structure
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-8-kabel@kernel.org>

Make Aardvark's msi_domain_info structure into a private driver structure.
Domain info is same for every potential instatination of a controller.

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 441100bacb68..5ab107f65c6c 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -275,7 +275,6 @@ struct advk_pcie {
 	raw_spinlock_t irq_lock;
 	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
-	struct msi_domain_info msi_domain_info;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
 	struct mutex msi_used_lock;
 	u16 msi_msg;
@@ -1293,20 +1292,20 @@ static struct irq_chip advk_msi_irq_chip = {
 	.name = "advk-MSI",
 };
 
+static struct msi_domain_info advk_msi_domain_info = {
+	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+		  MSI_FLAG_MULTI_PCI_MSI,
+	.chip	= &advk_msi_irq_chip,
+};
+
 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 {
 	struct device *dev = &pcie->pdev->dev;
 	struct device_node *node = dev->of_node;
-	struct msi_domain_info *msi_di;
 	phys_addr_t msi_msg_phys;
 
 	mutex_init(&pcie->msi_used_lock);
 
-	msi_di = &pcie->msi_domain_info;
-	msi_di->flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		MSI_FLAG_MULTI_PCI_MSI;
-	msi_di->chip = &advk_msi_irq_chip;
-
 	msi_msg_phys = virt_to_phys(&pcie->msi_msg);
 
 	advk_writel(pcie, lower_32_bits(msi_msg_phys),
@@ -1322,7 +1321,8 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 
 	pcie->msi_domain =
 		pci_msi_create_irq_domain(of_node_to_fwnode(node),
-					  msi_di, pcie->msi_inner_domain);
+					  &advk_msi_domain_info,
+					  pcie->msi_inner_domain);
 	if (!pcie->msi_domain) {
 		irq_domain_remove(pcie->msi_inner_domain);
 		return -ENOMEM;
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:03 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:03 +0100
Subject: [PATCH v2 08/23] PCI: aardvark: Use dev_fwnode() instead of
 of_node_to_fwnode(dev->of_node)
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-9-kabel@kernel.org>

Use simple
  dev_fwnode(dev)
instead of
  struct device_node *node = dev->of_node;
  of_node_to_fwnode(node)
especially since the node variable is not used elsewhere in the function.

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 5ab107f65c6c..3f7515814167 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1301,7 +1301,6 @@ static struct msi_domain_info advk_msi_domain_info = {
 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 {
 	struct device *dev = &pcie->pdev->dev;
-	struct device_node *node = dev->of_node;
 	phys_addr_t msi_msg_phys;
 
 	mutex_init(&pcie->msi_used_lock);
@@ -1320,7 +1319,7 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 		return -ENOMEM;
 
 	pcie->msi_domain =
-		pci_msi_create_irq_domain(of_node_to_fwnode(node),
+		pci_msi_create_irq_domain(dev_fwnode(dev),
 					  &advk_msi_domain_info,
 					  pcie->msi_inner_domain);
 	if (!pcie->msi_domain) {
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:04 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:04 +0100
Subject: [PATCH v2 09/23] PCI: aardvark: Refactor unmasking summary MSI
 interrupt
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-10-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Refactor the masking of ISR0/1 Sources and unmasking of summary MSI interrupt
so that it corresponds to the comments:
- first mask all ISR0/1
- then unmask all MSIs
- then unmask summary MSI interrupt

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 3f7515814167..9d2462f076c1 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -572,15 +572,17 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
 
 	/* Disable All ISR0/1 Sources */
-	reg = PCIE_ISR0_ALL_MASK;
-	reg &= ~PCIE_ISR0_MSI_INT_PENDING;
-	advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
-
+	advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG);
 	advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
 
 	/* Unmask all MSIs */
 	advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
 
+	/* Unmask summary MSI interrupt */
+	reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+	reg &= ~PCIE_ISR0_MSI_INT_PENDING;
+	advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
+
 	/* Enable summary interrupt for GIC SPI source */
 	reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
 	advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:06 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:06 +0100
Subject: [PATCH v2 11/23] PCI: aardvark: Fix setting MSI address
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-12-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

MSI address for receiving MSI interrupts needs to be correctly set before
enabling processing of MSI interrupts.

Move code for setting PCIE_MSI_ADDR_LOW_REG and PCIE_MSI_ADDR_HIGH_REG
from advk_pcie_init_msi_irq_domain() to advk_pcie_setup_hw(), before
enabling PCIE_CORE_CTRL2_MSI_ENABLE.

After this we can remove the now unused member msi_msg, which was used
only for MSI doorbell address. MSI address can be any address which cannot
be used to DMA to. So change it to the address of the main struct advk_pcie.

Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver")
Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
Cc: stable at vger.kernel.org # f21a8b1b6837 ("PCI: aardvark: Move to MSI handling using generic MSI support")
---
 drivers/pci/controller/pci-aardvark.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 51fedbcb41fb..79102704d82f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -278,7 +278,6 @@ struct advk_pcie {
 	raw_spinlock_t msi_irq_lock;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
 	struct mutex msi_used_lock;
-	u16 msi_msg;
 	int link_gen;
 	struct pci_bridge_emul bridge;
 	struct gpio_desc *reset_gpio;
@@ -473,6 +472,7 @@ static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num)
 
 static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 {
+	phys_addr_t msi_addr;
 	u32 reg;
 	int i;
 
@@ -561,6 +561,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	reg |= LANE_COUNT_1;
 	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
 
+	/* Set MSI address */
+	msi_addr = virt_to_phys(pcie);
+	advk_writel(pcie, lower_32_bits(msi_addr), PCIE_MSI_ADDR_LOW_REG);
+	advk_writel(pcie, upper_32_bits(msi_addr), PCIE_MSI_ADDR_HIGH_REG);
+
 	/* Enable MSI */
 	reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
 	reg |= PCIE_CORE_CTRL2_MSI_ENABLE;
@@ -1184,10 +1189,10 @@ static void advk_msi_irq_compose_msi_msg(struct irq_data *data,
 					 struct msi_msg *msg)
 {
 	struct advk_pcie *pcie = irq_data_get_irq_chip_data(data);
-	phys_addr_t msi_msg = virt_to_phys(&pcie->msi_msg);
+	phys_addr_t msi_addr = virt_to_phys(pcie);
 
-	msg->address_lo = lower_32_bits(msi_msg);
-	msg->address_hi = upper_32_bits(msi_msg);
+	msg->address_lo = lower_32_bits(msi_addr);
+	msg->address_hi = upper_32_bits(msi_addr);
 	msg->data = data->hwirq;
 }
 
@@ -1346,18 +1351,10 @@ static struct msi_domain_info advk_msi_domain_info = {
 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 {
 	struct device *dev = &pcie->pdev->dev;
-	phys_addr_t msi_msg_phys;
 
 	raw_spin_lock_init(&pcie->msi_irq_lock);
 	mutex_init(&pcie->msi_used_lock);
 
-	msi_msg_phys = virt_to_phys(&pcie->msi_msg);
-
-	advk_writel(pcie, lower_32_bits(msi_msg_phys),
-		    PCIE_MSI_ADDR_LOW_REG);
-	advk_writel(pcie, upper_32_bits(msi_msg_phys),
-		    PCIE_MSI_ADDR_HIGH_REG);
-
 	pcie->msi_inner_domain =
 		irq_domain_add_linear(NULL, MSI_IRQ_NUM,
 				      &advk_msi_domain_ops, pcie);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:05 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:05 +0100
Subject: [PATCH v2 10/23] PCI: aardvark: Add support for masking MSI interrupts
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-11-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

We should not unmask MSIs at setup, but only when kernel asks for them
to be unmasked.

At setup, mask all MSIs, and implement IRQ chip callbacks for masking
and unmasking particular MSIs.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 54 ++++++++++++++++++++++++---
 1 file changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 9d2462f076c1..51fedbcb41fb 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -275,6 +275,7 @@ struct advk_pcie {
 	raw_spinlock_t irq_lock;
 	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
+	raw_spinlock_t msi_irq_lock;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
 	struct mutex msi_used_lock;
 	u16 msi_msg;
@@ -571,12 +572,10 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
 	advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
 
-	/* Disable All ISR0/1 Sources */
+	/* Disable All ISR0/1 and MSI Sources */
 	advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG);
 	advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG);
-
-	/* Unmask all MSIs */
-	advk_writel(pcie, ~(u32)PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
+	advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG);
 
 	/* Unmask summary MSI interrupt */
 	reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
@@ -1198,10 +1197,52 @@ static int advk_msi_set_affinity(struct irq_data *irq_data,
 	return -EINVAL;
 }
 
+static void advk_msi_irq_mask(struct irq_data *d)
+{
+	struct advk_pcie *pcie = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 mask;
+
+	raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
+	mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
+	mask |= BIT(hwirq);
+	advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
+	raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
+}
+
+static void advk_msi_irq_unmask(struct irq_data *d)
+{
+	struct advk_pcie *pcie = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 mask;
+
+	raw_spin_lock_irqsave(&pcie->msi_irq_lock, flags);
+	mask = advk_readl(pcie, PCIE_MSI_MASK_REG);
+	mask &= ~BIT(hwirq);
+	advk_writel(pcie, mask, PCIE_MSI_MASK_REG);
+	raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
+}
+
+static void advk_msi_top_irq_mask(struct irq_data *d)
+{
+	pci_msi_mask_irq(d);
+	irq_chip_mask_parent(d);
+}
+
+static void advk_msi_top_irq_unmask(struct irq_data *d)
+{
+	pci_msi_unmask_irq(d);
+	irq_chip_unmask_parent(d);
+}
+
 static struct irq_chip advk_msi_bottom_irq_chip = {
 	.name			= "MSI",
 	.irq_compose_msi_msg	= advk_msi_irq_compose_msi_msg,
 	.irq_set_affinity	= advk_msi_set_affinity,
+	.irq_mask		= advk_msi_irq_mask,
+	.irq_unmask		= advk_msi_irq_unmask,
 };
 
 static int advk_msi_irq_domain_alloc(struct irq_domain *domain,
@@ -1291,7 +1332,9 @@ static const struct irq_domain_ops advk_pcie_irq_domain_ops = {
 };
 
 static struct irq_chip advk_msi_irq_chip = {
-	.name = "advk-MSI",
+	.name		= "advk-MSI",
+	.irq_mask	= advk_msi_top_irq_mask,
+	.irq_unmask	= advk_msi_top_irq_unmask,
 };
 
 static struct msi_domain_info advk_msi_domain_info = {
@@ -1305,6 +1348,7 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 	struct device *dev = &pcie->pdev->dev;
 	phys_addr_t msi_msg_phys;
 
+	raw_spin_lock_init(&pcie->msi_irq_lock);
 	mutex_init(&pcie->msi_used_lock);
 
 	msi_msg_phys = virt_to_phys(&pcie->msi_msg);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:07 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:07 +0100
Subject: [PATCH v2 12/23] PCI: aardvark: Enable MSI-X support
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-13-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

According to PCI 3.0 specification, sending both MSI and MSI-X interrupts
is done by DWORD memory write operation to doorbell message address. The
write operation for MSI has zero upper 16 bits and the MSI interrupt number
in the lower 16 bits, while the write operation for MSI-X contains a 32-bit
value from MSI-X table.

Since the driver only uses interrupt numbers from range 0..31, the upper
16 bits of the DWORD memory write operation to doorbell message address
are zero even for MSI-X interrupts. Thus we can enable MSI-X interrupts.

Testing proves that kernel can correctly receive MSI-X interrupts from PCIe
cards which supports both MSI and MSI-X interrupts.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 79102704d82f..a892f22510da 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1344,7 +1344,7 @@ static struct irq_chip advk_msi_irq_chip = {
 
 static struct msi_domain_info advk_msi_domain_info = {
 	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_MULTI_PCI_MSI,
+		  MSI_FLAG_MULTI_PCI_MSI | MSI_FLAG_PCI_MSIX,
 	.chip	= &advk_msi_irq_chip,
 };
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:08 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:08 +0100
Subject: [PATCH v2 13/23] PCI: aardvark: Add support for ERR interrupt on
 emulated bridge
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-14-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

ERR interrupt is triggered when corresponding bit is unmasked in both ISR0
and PCI_EXP_DEVCTL registers. Unmasking ERR bits in PCI_EXP_DEVCTL register
is not enough. This means that currently the ERR interrupt is never
triggered.

Unmask ERR bits in ISR0 register at driver probe time. ERR interrupt is not
triggered until ERR bits are unmasked also in PCI_EXP_DEVCTL register,
which is done by AER driver. So it is safe to unconditionally unmask all
ERR bits in aardvark probe.

Aardvark HW sets PCI_ERR_ROOT_AER_IRQ to zero and when corresponding bits
in ISR0 and PCI_EXP_DEVCTL are enabled, the HW triggers a generic interrupt
on GIC. Chain this interrupt to PCIe interrupt 0 with
generic_handle_domain_irq() to allow processing of ERR interrupts.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 35 ++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index a892f22510da..6fc6c3199954 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -99,6 +99,10 @@
 #define PCIE_MSG_PM_PME_MASK			BIT(7)
 #define PCIE_ISR0_MASK_REG			(CONTROL_BASE_ADDR + 0x44)
 #define     PCIE_ISR0_MSI_INT_PENDING		BIT(24)
+#define     PCIE_ISR0_CORR_ERR			BIT(11)
+#define     PCIE_ISR0_NFAT_ERR			BIT(12)
+#define     PCIE_ISR0_FAT_ERR			BIT(13)
+#define     PCIE_ISR0_ERR_MASK			GENMASK(13, 11)
 #define     PCIE_ISR0_INTX_ASSERT(val)		BIT(16 + (val))
 #define     PCIE_ISR0_INTX_DEASSERT(val)	BIT(20 + (val))
 #define     PCIE_ISR0_ALL_MASK			GENMASK(31, 0)
@@ -783,11 +787,15 @@ advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge,
 	case PCI_INTERRUPT_LINE: {
 		/*
 		 * From the whole 32bit register we support reading from HW only
-		 * one bit: PCI_BRIDGE_CTL_BUS_RESET.
+		 * two bits: PCI_BRIDGE_CTL_BUS_RESET and PCI_BRIDGE_CTL_SERR.
 		 * Other bits are retrieved only from emulated config buffer.
 		 */
 		__le32 *cfgspace = (__le32 *)&bridge->conf;
 		u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]);
+		if (advk_readl(pcie, PCIE_ISR0_MASK_REG) & PCIE_ISR0_ERR_MASK)
+			val &= ~(PCI_BRIDGE_CTL_SERR << 16);
+		else
+			val |= PCI_BRIDGE_CTL_SERR << 16;
 		if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN)
 			val |= PCI_BRIDGE_CTL_BUS_RESET << 16;
 		else
@@ -817,6 +825,19 @@ advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 		break;
 
 	case PCI_INTERRUPT_LINE:
+		/*
+		 * According to Figure 6-3: Pseudo Logic Diagram for Error
+		 * Message Controls in PCIe base specification, SERR# Enable bit
+		 * in Bridge Control register enable receiving of ERR_* messages
+		 */
+		if (mask & (PCI_BRIDGE_CTL_SERR << 16)) {
+			u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+			if (new & (PCI_BRIDGE_CTL_SERR << 16))
+				val &= ~PCIE_ISR0_ERR_MASK;
+			else
+				val |= PCIE_ISR0_ERR_MASK;
+			advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
+		}
 		if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) {
 			u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG);
 			if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16))
@@ -1462,6 +1483,18 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
 	isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
 
+	/* Process ERR interrupt */
+	if (isr0_status & PCIE_ISR0_ERR_MASK) {
+		advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG);
+
+		/*
+		 * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use
+		 * PCIe interrupt 0
+		 */
+		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
+	}
+
 	/* Process MSI interrupts */
 	if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
 		advk_pcie_handle_msi(pcie);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:09 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:09 +0100
Subject: [PATCH v2 14/23] PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on
 emulated bridge
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-15-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

The emulated bridge returns incorrect value for PCI_EXP_RTSTA register
during readout in advk_pci_bridge_emul_pcie_conf_read() function: the
correct bit is BIT(16), but we are setting BIT(23), because the code
does
  *value = (isr0 & PCIE_MSG_PM_PME_MASK) << 16
where
  PCIE_MSG_PM_PME_MASK
is
  BIT(7).

The code should probably have been something like
  *value = (!!(isr0 & PCIE_MSG_PM_PME_MASK)) << 16,
but we are better of using an if() and using the proper macro for this
bit.

Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space")
Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 6fc6c3199954..8706a5f58eb5 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -876,7 +876,9 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 	case PCI_EXP_RTSTA: {
 		u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG);
 		u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG);
-		*value = (isr0 & PCIE_MSG_PM_PME_MASK) << 16 | (msglog >> 16);
+		*value = msglog >> 16;
+		if (isr0 & PCIE_MSG_PM_PME_MASK)
+			*value |= PCI_EXP_RTSTA_PME;
 		return PCI_BRIDGE_EMUL_HANDLED;
 	}
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:10 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:10 +0100
Subject: [PATCH v2 15/23] PCI: aardvark: Optimize writing PCI_EXP_RTCTL_PMEIE
 and PCI_EXP_RTSTA_PME on emulated bridge
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-16-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

To optimize advk_pci_bridge_emul_pcie_conf_write() code, touch
PCIE_ISR0_REG and PCIE_ISR0_MASK_REG registers only when it is really
needed, when processing PCI_EXP_RTCTL_PMEIE and PCI_EXP_RTSTA_PME bits.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 8706a5f58eb5..e7b9ca31c79c 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -934,19 +934,21 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 			advk_pcie_wait_for_retrain(pcie);
 		break;
 
-	case PCI_EXP_RTCTL: {
+	case PCI_EXP_RTCTL:
 		/* Only mask/unmask PME interrupt */
-		u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG) &
-			~PCIE_MSG_PM_PME_MASK;
-		if ((new & PCI_EXP_RTCTL_PMEIE) == 0)
-			val |= PCIE_MSG_PM_PME_MASK;
-		advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
+		if (mask & PCI_EXP_RTCTL_PMEIE) {
+			u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+			if (new & PCI_EXP_RTCTL_PMEIE)
+				val &= ~PCIE_MSG_PM_PME_MASK;
+			else
+				val |= PCIE_MSG_PM_PME_MASK;
+			advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
+		}
 		break;
-	}
 
 	case PCI_EXP_RTSTA:
-		new = (new & PCI_EXP_RTSTA_PME) >> 9;
-		advk_writel(pcie, new, PCIE_ISR0_REG);
+		if (new & PCI_EXP_RTSTA_PME)
+			advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG);
 		break;
 
 	case PCI_EXP_DEVCTL:
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:11 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:11 +0100
Subject: [PATCH v2 16/23] PCI: aardvark: Add support for PME interrupts
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-17-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Currently enabling PCI_EXP_RTSTA_PME bit in PCI_EXP_RTCTL register does
nothing. This is because PCIe PME driver expects to receive PCIe interrupt
defined in PCI_EXP_FLAGS_IRQ register, but aardvark hardware does not
trigger PCIe INTx/MSI interrupt for PME event, rather it triggers custom
aardvark interrupt which this driver is not processing yet.

Fix this issue by handling PME interrupt in advk_pcie_handle_int() and
chaining it to PCIe interrupt 0 with generic_handle_domain_irq() (since
aardvark sets PCI_EXP_FLAGS_IRQ to zero). With this change PCIe PME driver
finally starts receiving PME interrupt.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index e7b9ca31c79c..3f2d570bfbb5 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1487,6 +1487,18 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
 	isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
 
+	/* Process PME interrupt */
+	if (isr0_status & PCIE_MSG_PM_PME_MASK) {
+		/*
+		 * Do not clear PME interrupt bit in ISR0, it is cleared by IRQ
+		 * receiver by writing to the PCI_EXP_RTSTA register of emulated
+		 * root bridge. Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ,
+		 * so use PCIe interrupt 0.
+		 */
+		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
+	}
+
 	/* Process ERR interrupt */
 	if (isr0_status & PCIE_ISR0_ERR_MASK) {
 		advk_writel(pcie, PCIE_ISR0_ERR_MASK, PCIE_ISR0_REG);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:12 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:12 +0100
Subject: [PATCH v2 17/23] PCI: aardvark: Fix support for PME requester on
 emulated bridge
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-18-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Enable aardvark PME interrupt unconditionally by unmasking it and read PME
requester ID to emulated bridge config space immediately after receiving
interrupt.

PME requester ID is stored in the PCIE_MSG_LOG_REG register, which contains
the last inbound message. So when new inbound message is received by HW
(including non-PM), the content in PCIE_MSG_LOG_REG register is replaced by
a new value.

PCIe specification mandates that subsequent PMEs are kept pending until the
PME Status Register bit is cleared by software by writing a 1b.

Support for masking/unmasking PME interrupt on emulated bridge via
PCI_EXP_RTCTL_PMEIE bit is now implemented only in emulated bridge config
space, to ensure that we do not miss any aardvark PME interrupt.

Reading of PCI_EXP_RTCAP and PCI_EXP_RTSTA registers is simplified as final
value is now always stored into emulated bridge config space by the
interrupt handler, so there is no need to implement support for these
registers in read_pcie callback.

Clearing of W1C bit PCI_EXP_RTSTA_PME is now also simplified as it is done
by pci-bridge-emul.c code for emulated bridge config space. So there is no
need to implement support for clearing this bit in write_pcie callback.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 91 +++++++++++++++------------
 1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 3f2d570bfbb5..730ff1ffc952 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -591,6 +591,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
 	reg &= ~PCIE_ISR0_MSI_INT_PENDING;
 	advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
 
+	/* Unmask PME interrupt for processing of PME requester */
+	reg = advk_readl(pcie, PCIE_ISR0_MASK_REG);
+	reg &= ~PCIE_MSG_PM_PME_MASK;
+	advk_writel(pcie, reg, PCIE_ISR0_MASK_REG);
+
 	/* Enable summary interrupt for GIC SPI source */
 	reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK);
 	advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG);
@@ -865,22 +870,11 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 		*value = PCI_EXP_SLTSTA_PDS << 16;
 		return PCI_BRIDGE_EMUL_HANDLED;
 
-	case PCI_EXP_RTCTL: {
-		u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
-		*value = (val & PCIE_MSG_PM_PME_MASK) ? 0 : PCI_EXP_RTCTL_PMEIE;
-		*value |= le16_to_cpu(bridge->pcie_conf.rootctl) & PCI_EXP_RTCTL_CRSSVE;
-		*value |= PCI_EXP_RTCAP_CRSVIS << 16;
-		return PCI_BRIDGE_EMUL_HANDLED;
-	}
-
-	case PCI_EXP_RTSTA: {
-		u32 isr0 = advk_readl(pcie, PCIE_ISR0_REG);
-		u32 msglog = advk_readl(pcie, PCIE_MSG_LOG_REG);
-		*value = msglog >> 16;
-		if (isr0 & PCIE_MSG_PM_PME_MASK)
-			*value |= PCI_EXP_RTSTA_PME;
-		return PCI_BRIDGE_EMUL_HANDLED;
-	}
+	/*
+	 * PCI_EXP_RTCTL and PCI_EXP_RTSTA are also supported, but do not need
+	 * to be handled here, because their values are stored in emulated
+	 * config space buffer, and we read them from there when needed.
+	 */
 
 	case PCI_EXP_LNKCAP: {
 		u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
@@ -934,22 +928,19 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 			advk_pcie_wait_for_retrain(pcie);
 		break;
 
-	case PCI_EXP_RTCTL:
-		/* Only mask/unmask PME interrupt */
-		if (mask & PCI_EXP_RTCTL_PMEIE) {
-			u32 val = advk_readl(pcie, PCIE_ISR0_MASK_REG);
-			if (new & PCI_EXP_RTCTL_PMEIE)
-				val &= ~PCIE_MSG_PM_PME_MASK;
-			else
-				val |= PCIE_MSG_PM_PME_MASK;
-			advk_writel(pcie, val, PCIE_ISR0_MASK_REG);
-		}
+	case PCI_EXP_RTCTL: {
+		u16 rootctl = le16_to_cpu(bridge->pcie_conf.rootctl);
+		/* Only emulation of PMEIE and CRSSVE bits is provided */
+		rootctl &= PCI_EXP_RTCTL_PMEIE | PCI_EXP_RTCTL_CRSSVE;
+		bridge->pcie_conf.rootctl = cpu_to_le16(rootctl);
 		break;
+	}
 
-	case PCI_EXP_RTSTA:
-		if (new & PCI_EXP_RTSTA_PME)
-			advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG);
-		break;
+	/*
+	 * PCI_EXP_RTSTA is also supported, but does not need to be handled
+	 * here, because its value is stored in emulated config space buffer,
+	 * and we write it there when needed.
+	 */
 
 	case PCI_EXP_DEVCTL:
 	case PCI_EXP_DEVCTL2:
@@ -1452,6 +1443,32 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 	irq_domain_remove(pcie->irq_domain);
 }
 
+static void advk_pcie_handle_pme(struct advk_pcie *pcie)
+{
+	u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16;
+
+	advk_writel(pcie, PCIE_MSG_PM_PME_MASK, PCIE_ISR0_REG);
+
+	/*
+	 * PCIE_MSG_LOG_REG contains the last inbound message, so store
+	 * the requester ID only when PME was not asserted yet.
+	 * Also do not trigger PME interrupt when PME is still asserted.
+	 */
+	if (!(le32_to_cpu(pcie->bridge.pcie_conf.rootsta) & PCI_EXP_RTSTA_PME)) {
+		pcie->bridge.pcie_conf.rootsta = cpu_to_le32(requester | PCI_EXP_RTSTA_PME);
+
+		/*
+		 * Trigger PME interrupt only if PMEIE bit in Root Control is set.
+		 * Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ, so use PCIe interrupt 0.
+		 */
+		if (!(le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & PCI_EXP_RTCTL_PMEIE))
+			return;
+
+		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+			dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
+	}
+}
+
 static void advk_pcie_handle_msi(struct advk_pcie *pcie)
 {
 	u32 msi_val, msi_mask, msi_status, msi_idx;
@@ -1487,17 +1504,9 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 	isr1_mask = advk_readl(pcie, PCIE_ISR1_MASK_REG);
 	isr1_status = isr1_val & ((~isr1_mask) & PCIE_ISR1_ALL_MASK);
 
-	/* Process PME interrupt */
-	if (isr0_status & PCIE_MSG_PM_PME_MASK) {
-		/*
-		 * Do not clear PME interrupt bit in ISR0, it is cleared by IRQ
-		 * receiver by writing to the PCI_EXP_RTSTA register of emulated
-		 * root bridge. Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ,
-		 * so use PCIe interrupt 0.
-		 */
-		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
-			dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
-	}
+	/* Process PME interrupt as the first one to do not miss PME requester id */
+	if (isr0_status & PCIE_MSG_PM_PME_MASK)
+		advk_pcie_handle_pme(pcie);
 
 	/* Process ERR interrupt */
 	if (isr0_status & PCIE_ISR0_ERR_MASK) {
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:14 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:14 +0100
Subject: [PATCH v2 19/23] PCI: aardvark: Remove irq_mask_ack callback for INTx
 interrupts
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-20-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Callback for irq_mask_ack is the same as for irq_mask. As there is no
special handling for irq_ack, there is no need to define irq_mask_ack too.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index ca519cadcdfe..a41e3e206478 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1422,7 +1422,6 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
 	}
 
 	irq_chip->irq_mask = advk_pcie_irq_mask;
-	irq_chip->irq_mask_ack = advk_pcie_irq_mask;
 	irq_chip->irq_unmask = advk_pcie_irq_unmask;
 
 	pcie->irq_domain =
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:13 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:13 +0100
Subject: [PATCH v2 18/23] PCI: aardvark: Use separate INTA interrupt for
 emulated root bridge
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-19-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

Emulated root bridge currently provides only one Legacy INTA interrupt
which is used for reporting PCIe PME and ERR events and handled by kernel
PCIe PME and AER drivers.

Aardvark HW reports these PME and ERR events separately, so there is no
need to mix real INTA interrupt and emulated INTA interrupt for PCIe PME
and AER drivers.

Register a new advk-RP (as in Root Port) irq chip and a new irq domain
for emulated root bridge and use this new separate irq domain for
providing INTA interrupt from emulated root bridge for PME and ERR events.

The real INTA interrupt from real devices is now separate.

A custom map_irq callback function on PCI host bridge structure is used to
allocate IRQ mapping for emulated root bridge from new irq domain. Original
callback of_irq_parse_and_map_pci() is used for all other devices as before.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 69 ++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 730ff1ffc952..ca519cadcdfe 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -274,6 +274,7 @@ struct advk_pcie {
 	} wins[OB_WIN_COUNT];
 	u8 wins_count;
 	int irq;
+	struct irq_domain *rp_irq_domain;
 	struct irq_domain *irq_domain;
 	struct irq_chip irq_chip;
 	raw_spinlock_t irq_lock;
@@ -1443,6 +1444,44 @@ static void advk_pcie_remove_irq_domain(struct advk_pcie *pcie)
 	irq_domain_remove(pcie->irq_domain);
 }
 
+static struct irq_chip advk_rp_irq_chip = {
+	.name = "advk-RP",
+};
+
+static int advk_pcie_rp_irq_map(struct irq_domain *h,
+				unsigned int virq, irq_hw_number_t hwirq)
+{
+	struct advk_pcie *pcie = h->host_data;
+
+	irq_set_chip_and_handler(virq, &advk_rp_irq_chip, handle_simple_irq);
+	irq_set_chip_data(virq, pcie);
+
+	return 0;
+}
+
+static const struct irq_domain_ops advk_pcie_rp_irq_domain_ops = {
+	.map = advk_pcie_rp_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int advk_pcie_init_rp_irq_domain(struct advk_pcie *pcie)
+{
+	pcie->rp_irq_domain = irq_domain_add_linear(NULL, 1,
+						    &advk_pcie_rp_irq_domain_ops,
+						    pcie);
+	if (!pcie->rp_irq_domain) {
+		dev_err(&pcie->pdev->dev, "Failed to add Root Port IRQ domain\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void advk_pcie_remove_rp_irq_domain(struct advk_pcie *pcie)
+{
+	irq_domain_remove(pcie->rp_irq_domain);
+}
+
 static void advk_pcie_handle_pme(struct advk_pcie *pcie)
 {
 	u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16;
@@ -1464,7 +1503,7 @@ static void advk_pcie_handle_pme(struct advk_pcie *pcie)
 		if (!(le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & PCI_EXP_RTCTL_PMEIE))
 			return;
 
-		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+		if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL)
 			dev_err_ratelimited(&pcie->pdev->dev, "unhandled PME IRQ\n");
 	}
 }
@@ -1516,7 +1555,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
 		 * Aardvark HW returns zero for PCI_ERR_ROOT_AER_IRQ, so use
 		 * PCIe interrupt 0
 		 */
-		if (generic_handle_domain_irq(pcie->irq_domain, 0) == -EINVAL)
+		if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL)
 			dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n");
 	}
 
@@ -1560,6 +1599,21 @@ static void advk_pcie_irq_handler(struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
+static int advk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct advk_pcie *pcie = dev->bus->sysdata;
+
+	/*
+	 * Emulated root bridge has its own emulated irq chip and irq domain.
+	 * Argument pin is the INTx pin (1=INTA, 2=INTB, 3=INTC, 4=INTD) and
+	 * hwirq for irq_create_mapping() is indexed from zero.
+	 */
+	if (pci_is_root_bus(dev->bus))
+		return irq_create_mapping(pcie->rp_irq_domain, pin - 1);
+	else
+		return of_irq_parse_and_map_pci(dev, slot, pin);
+}
+
 static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie)
 {
 	phy_power_off(pcie->phy);
@@ -1761,14 +1815,24 @@ static int advk_pcie_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = advk_pcie_init_rp_irq_domain(pcie);
+	if (ret) {
+		dev_err(dev, "Failed to initialize irq\n");
+		advk_pcie_remove_msi_irq_domain(pcie);
+		advk_pcie_remove_irq_domain(pcie);
+		return ret;
+	}
+
 	irq_set_chained_handler_and_data(pcie->irq, advk_pcie_irq_handler, pcie);
 
 	bridge->sysdata = pcie;
 	bridge->ops = &advk_pcie_ops;
+	bridge->map_irq = advk_pcie_map_irq;
 
 	ret = pci_host_probe(bridge);
 	if (ret < 0) {
 		irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
+		advk_pcie_remove_rp_irq_domain(pcie);
 		advk_pcie_remove_msi_irq_domain(pcie);
 		advk_pcie_remove_irq_domain(pcie);
 		return ret;
@@ -1820,6 +1884,7 @@ static int advk_pcie_remove(struct platform_device *pdev)
 	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 
 	/* Remove IRQ domains */
+	advk_pcie_remove_rp_irq_domain(pcie);
 	advk_pcie_remove_msi_irq_domain(pcie);
 	advk_pcie_remove_irq_domain(pcie);
 
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:15 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:15 +0100
Subject: [PATCH v2 20/23] PCI: aardvark: Don't mask irq when mapping
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-21-kabel@kernel.org>

From: Pali Roh?r <pali at kernel.org>

By default, all Legacy INTx interrupts are masked, so there is no need to
mask this interrupt during irq_map callback.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index a41e3e206478..0e3dcd584f7e 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1339,7 +1339,6 @@ static int advk_pcie_irq_map(struct irq_domain *h,
 {
 	struct advk_pcie *pcie = h->host_data;
 
-	advk_pcie_irq_mask(irq_get_irq_data(virq));
 	irq_set_status_flags(virq, IRQ_LEVEL);
 	irq_set_chip_and_handler(virq, &pcie->irq_chip,
 				 handle_level_irq);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:16 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:16 +0100
Subject: [PATCH v2 21/23] PCI: aardvark: Drop __maybe_unused from
 advk_pcie_disable_phy()
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-22-kabel@kernel.org>

This function is now always used in driver remove method, drop the
__maybe_unused attribute.

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 0e3dcd584f7e..360e2e3b3aa6 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1612,7 +1612,7 @@ static int advk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 		return of_irq_parse_and_map_pci(dev, slot, pin);
 }
 
-static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie)
+static void advk_pcie_disable_phy(struct advk_pcie *pcie)
 {
 	phy_power_off(pcie->phy);
 	phy_exit(pcie->phy);
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:17 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:17 +0100
Subject: [PATCH v2 22/23] PCI: aardvark: Update comment about link going down
 after link-up
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-23-kabel@kernel.org>

Update the comment about what happens when link goes down after we have
checked for link-up. If a PIO request is done while link-down, we have
a serious problem.

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 360e2e3b3aa6..2c5cc929b94f 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -1007,8 +1007,12 @@ static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus,
 		return false;
 
 	/*
-	 * If the link goes down after we check for link-up, nothing bad
-	 * happens but the config access times out.
+	 * If the link goes down after we check for link-up, we have a problem:
+	 * if a PIO request is executed while link-down, the whole controller
+	 * gets stuck in a non-functional state, and even after link comes up
+	 * again, PIO requests won't work anymore, and a reset of the whole PCIe
+	 * controller is needed. Therefore we need to prevent sending PIO
+	 * requests while the link is down.
 	 */
 	if (!pci_is_root_bus(bus) && !advk_pcie_link_up(pcie))
 		return false;
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 17:50:18 2022
From: kabel at kernel.org (=?UTF-8?q?Marek=20Beh=C3=BAn?=)
Date: Mon, 10 Jan 2022 02:50:18 +0100
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a static
 driver structure
In-Reply-To: <20220110015018.26359-1-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
Message-ID: <20220110015018.26359-24-kabel@kernel.org>

Marc Zyngier says [1] that we should use struct irq_chip as a global
static struct in the driver. Even though the structure currently
contains a dynamic member (parent_device), Marc says [2] that he plans
to kill it and make the structure completely static.

We have already converted others irq_chip structures in this driver in
this way, but we omitted this one because the .name member is
dynamically created from device's name, and the name is displayed in
sysfs, so changing it would break sysfs ABI.

The rationale for changing the name (to "advk-INT") in spite of sysfs
ABI, and thus allowing to convert to a static structure, is that after
the other changes we made in this series, the IRQ chip is basically
something different: it no logner generates ERR and PME interrupts (they
are generated by emulated bridge's rp_irq_chip).

[1] https://lore.kernel.org/linux-pci/877dbcvngf.wl-maz at kernel.org/
[2] https://lore.kernel.org/linux-pci/874k6gvkhz.wl-maz at kernel.org/

Signed-off-by: Marek Beh?n <kabel at kernel.org>
---
 drivers/pci/controller/pci-aardvark.c | 25 +++++++------------------
 1 file changed, 7 insertions(+), 18 deletions(-)

diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 2c5cc929b94f..087a0b22d573 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -276,7 +276,6 @@ struct advk_pcie {
 	int irq;
 	struct irq_domain *rp_irq_domain;
 	struct irq_domain *irq_domain;
-	struct irq_chip irq_chip;
 	raw_spinlock_t irq_lock;
 	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
@@ -1338,14 +1337,19 @@ static void advk_pcie_irq_unmask(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&pcie->irq_lock, flags);
 }
 
+static struct irq_chip advk_irq_chip = {
+	.name		= "advk-INT",
+	.irq_mask	= advk_pcie_irq_mask,
+	.irq_unmask	= advk_pcie_irq_unmask,
+};
+
 static int advk_pcie_irq_map(struct irq_domain *h,
 			     unsigned int virq, irq_hw_number_t hwirq)
 {
 	struct advk_pcie *pcie = h->host_data;
 
 	irq_set_status_flags(virq, IRQ_LEVEL);
-	irq_set_chip_and_handler(virq, &pcie->irq_chip,
-				 handle_level_irq);
+	irq_set_chip_and_handler(virq, &advk_irq_chip, handle_level_irq);
 	irq_set_chip_data(virq, pcie);
 
 	return 0;
@@ -1404,7 +1408,6 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
 	struct device *dev = &pcie->pdev->dev;
 	struct device_node *node = dev->of_node;
 	struct device_node *pcie_intc_node;
-	struct irq_chip *irq_chip;
 	int ret = 0;
 
 	raw_spin_lock_init(&pcie->irq_lock);
@@ -1415,28 +1418,14 @@ static int advk_pcie_init_irq_domain(struct advk_pcie *pcie)
 		return -ENODEV;
 	}
 
-	irq_chip = &pcie->irq_chip;
-
-	irq_chip->name = devm_kasprintf(dev, GFP_KERNEL, "%s-irq",
-					dev_name(dev));
-	if (!irq_chip->name) {
-		ret = -ENOMEM;
-		goto out_put_node;
-	}
-
-	irq_chip->irq_mask = advk_pcie_irq_mask;
-	irq_chip->irq_unmask = advk_pcie_irq_unmask;
-
 	pcie->irq_domain =
 		irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
 				      &advk_pcie_irq_domain_ops, pcie);
 	if (!pcie->irq_domain) {
 		dev_err(dev, "Failed to get a INTx IRQ domain\n");
 		ret = -ENOMEM;
-		goto out_put_node;
 	}
 
-out_put_node:
 	of_node_put(pcie_intc_node);
 	return ret;
 }
-- 
2.34.1



From kabel at kernel.org  Sun Jan  9 18:21:27 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Mon, 10 Jan 2022 03:21:27 +0100
Subject: [PATCH 3/3] PCI: aardvark: Implement emulated root PCI bridge
In-Reply-To: <20220107212736.GA404447@bhelgaas>
References: <20180629092231.32207-4-thomas.petazzoni@bootlin.com>
 <20220107212736.GA404447@bhelgaas>
Message-ID: <20220110032127.4ea60dc9@thinkpad>

On Fri, 7 Jan 2022 15:27:36 -0600
Bjorn Helgaas <helgaas at kernel.org> wrote:

> On Fri, Jun 29, 2018 at 11:22:31AM +0200, Thomas Petazzoni wrote:
> 
> > +static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
> > +{
> > +	struct pci_sw_bridge *bridge = &pcie->bridge;  
> 
> > +	/* Support interrupt A for MSI feature */
> > +	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;  
> 
> Only 3.5 years later, IIUC, this is the value you get when you read
> PCI_INTERRUPT_PIN, so I think this should be PCI_INTERRUPT_INTA, not
> PCIE_CORE_INT_A_ASSERT_ENABLE.
> 
> Readers expect to get the values defined in the PCI spec, i.e.,
> 
>   PCI_INTERRUPT_UNKNOWN
>   PCI_INTERRUPT_INTA
>   PCI_INTERRUPT_INTB
>   PCI_INTERRUPT_INTC
>   PCI_INTERRUPT_INTD

Hello Bjorn,

now sent v2 of batch 4 of fixes for pci-aardvark, where this is fixed
in the first patch.
  https://lore.kernel.org/linux-pci/20220110015018.26359-1-kabel at kernel.org/
Could you find time to review the series? :-)

Marek


From heying24 at huawei.com  Sun Jan  9 19:00:43 2022
From: heying24 at huawei.com (He Ying)
Date: Mon, 10 Jan 2022 11:00:43 +0800
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <Ydg939btY/bzEAe4@FVFF77S0Q05N>
References: <20220107085536.214501-1-heying24@huawei.com>
 <Ydg939btY/bzEAe4@FVFF77S0Q05N>
Message-ID: <bd82d240-34d7-4df9-650b-c039555f05e3@huawei.com>

Hi Mark,

I'm just back from the weekend and sorry for the delayed reply.


? 2022/1/7 21:19, Mark Rutland ??:
> On Fri, Jan 07, 2022 at 03:55:36AM -0500, He Ying wrote:
>> Our product has been updating its kernel from 4.4 to 5.10 recently and
>> found a performance issue. We do a bussiness test called ARP test, which
>> tests the latency for a ping-pong packets traffic with a certain payload.
>> The result is as following.
>>
>>   - 4.4 kernel: avg = ~20s
>>   - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s
> Have you tested with a recent mainline kernel, e.g. v5.15?

Actuallly no, that's because this test is only available for the product 
environment and

we don't have an available 5.15 kernel for it yet.

>
> Is this test publicly available, and can you say which hardrware (e.g. which
> CPU implementation) you're testing with?

Actually no. The test is only available for our product environment now. 
We are testing

with hisilicon 1213 (4 ARM Cortex-A72 cores).

>
>> I have been just learning arm64 pseudo-NMI code and have a question,
>> why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
> The code in question is all patched via alternatives, and when
> CONFIG_ARM64_PSEUDO_NMI is not selected, the code was expected to only have the
> overhead of the regular DAIF manipulation.
I don't understand alernatives very well and I'll apreciate it if you 
can explain it a bit more.
>
>> I wonder if this brings some performance regression.
>>
>> First, I make this patch and then do the test again. Here's the result.
>>
>>   - 5.10 kernel with this patch not applied: avg = ~40s
>>   - 5.10 kernel with this patch applied: avg = ~23s
>>
>> Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
>> set. It seems the pseudo-NMI feature actually brings some overhead to
>> performance event if CONFIG_ARM64_PSEUDO_NMI is not set.
> I'm surprised the overhead is so significant; as above this is all patched in
> and so the overhead when this is disabled is expected to be *extremely* small.
>
> For example, wjen CONFIG_ARM64_PSEUDO_NMI, in arch_local_irq_enable():
>
> * The portion under the system_has_prio_mask_debugging() test will be removed
>    entirely by the compiler, as this internally checks
>    IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI).
>
> * The assembly will be left as a write to DAIFClr. The only additional cost
>    should be that of generating GIC_PRIO_IRQON into a register.
>
> * The pmr_sync() will be removed entirely by the compiler as is defined
>    conditionally dependent on CONFIG_ARM64_PSEUDO_NMI.
>
> I can't spot an obvious issue with that or ther other cases. In the common case
> those add no new instructions, and in the worst case they only add NOPs.

Thanks for your detailed explaination! Actually I can't understand the 
result exactly.

I build two 5.10 kernel images with this patch applied or not and 
objdump them. Indeed,

the disassembles of 'arch_local_irq_restore' are the same. Do you have 
any ideas how

we can find the root cause why this patch improves the performance so much?


However, the test result is trustworthy because we do it many times and 
the result is

always repeatable.

>
>> Furthermore, I find the feature also brings some overhead to vmlinux size.
>> I build 5.10 kernel with this patch applied or not while
>> CONFIG_ARM64_PSEUDO_NMI is not set.
>>
>>   - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
>>   - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
>>
>> That means arm64 pseudo-NMI feature may bring ~200KB overhead to
>> vmlinux size.
> I suspect that's just the (unused) alternatives, and we could improve that by
> passing the config into the alternative blocks.

Do you mean the sections generated by the alternatives? I don't understand

alernatives very well and I'll apreciate it if you can explain it a bit 
more.

>
>> Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
>> and performance even if config is not set. To avoid it, add macro control
>> all around the related code.
>>
>> Signed-off-by: He Ying <heying24 at huawei.com>
>> ---
>>   arch/arm64/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++--
>>   arch/arm64/kernel/entry.S         |  4 ++++
>>   2 files changed, 40 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
>> index b57b9b1e4344..82f771b41cf5 100644
>> --- a/arch/arm64/include/asm/irqflags.h
>> +++ b/arch/arm64/include/asm/irqflags.h
>> @@ -26,6 +26,7 @@
>>    */
>>   static inline void arch_local_irq_enable(void)
>>   {
>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>   	if (system_has_prio_mask_debugging()) {
>>   		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
>>   
>> @@ -41,10 +42,18 @@ static inline void arch_local_irq_enable(void)
>>   		: "memory");
>>   
>>   	pmr_sync();
>> +#else
>> +	asm volatile(
>> +		"msr	daifclr, #3		// arch_local_irq_enable"
>> +		:
>> +		:
>> +		: "memory");
>> +#endif
> I'm happy to rework this to improve matters, but I am very much not happy with
> duplicating the logic for the !PSEUDO_NMI case. Adding more ifdeffery and
> copies of that is not acceptable.
I agree. Adding these ifdeffery is a bit ugly. Let's see if there are 
some better ways.
>
> Instead, can you please try changing the alternative to also take the config,
> e.g. here have:
>
> |       asm volatile(ALTERNATIVE(
> |               "msr    daifclr, #3             // arch_local_irq_enable",
> |               __msr_s(SYS_ICC_PMR_EL1, "%0"),
> |               ARM64_HAS_IRQ_PRIO_MASKING,
> |               CONFIG_ARM64_PSEUDO_NMI)
> |               :
> |               : "r" ((unsigned long) GIC_PRIO_IRQON)
> |               : "memory");
>
> ... and see if that makes a significant difference?
>
> Likewise for the other casees.

OK, I'll try it. But I have some questions. Here's the comment of 
ALERNATIVE:

/*
 ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature));
 ?*
 ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature, CONFIG_FOO));
 ?* N.B. If CONFIG_FOO is specified, but not selected, the whole block
 ?*????? will be omitted, including oldinstr.
 ?*/

If CONFIG_FOO is not selected, the whole block will be omitted including 
oldinstr.

But we still want the oldinstr in this situation. Do I misunderstand 
something?

>
>>   #endif /* __ASM_IRQFLAGS_H */
>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>> index 2f69ae43941d..ffc32d3d909a 100644
>> --- a/arch/arm64/kernel/entry.S
>> +++ b/arch/arm64/kernel/entry.S
>> @@ -300,6 +300,7 @@ alternative_else_nop_endif
>>   	str	w21, [sp, #S_SYSCALLNO]
>>   	.endif
>>   
>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>   	/* Save pmr */
>>   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>   	mrs_s	x20, SYS_ICC_PMR_EL1
>> @@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>   	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
>>   	msr_s	SYS_ICC_PMR_EL1, x20
>>   alternative_else_nop_endif
>> +#endif
>>   
>>   	/* Re-enable tag checking (TCO set on exception entry) */
>>   #ifdef CONFIG_ARM64_MTE
>> @@ -330,6 +332,7 @@ alternative_else_nop_endif
>>   	disable_daif
>>   	.endif
>>   
>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>   	/* Restore pmr */
>>   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>   	ldr	x20, [sp, #S_PMR_SAVE]
>> @@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>   	dsb	sy				// Ensure priority change is seen by redistributor
>>   .L__skip_pmr_sync\@:
>>   alternative_else_nop_endif
>> +#endif
> For these two I think the ifdeffery is fine, but I'm surprised this has a
> measureable impact as the alternatives should be initialized to NOPS (and never
> modified).

Yes, these NOPs may bring some overhead. But I can't say how much these 
NOPs contribute to

the result of test.

>
> Thanks,
> Mark.
> .


From heying24 at huawei.com  Sun Jan  9 19:20:39 2022
From: heying24 at huawei.com (He Ying)
Date: Mon, 10 Jan 2022 11:20:39 +0800
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <87pmp2tmpg.wl-maz@kernel.org>
References: <20220107085536.214501-1-heying24@huawei.com>
 <87pmp2tmpg.wl-maz@kernel.org>
Message-ID: <a010e8dd-428b-c295-b2db-020d8cc698c5@huawei.com>

Hi Marc,

I'm just back from the weekend and sorry for the delayed reply.


? 2022/1/8 20:51, Marc Zyngier ??:
> On Fri, 07 Jan 2022 08:55:36 +0000,
> He Ying <heying24 at huawei.com> wrote:
>> Our product has been updating its kernel from 4.4 to 5.10 recently and
>> found a performance issue. We do a bussiness test called ARP test, which
>> tests the latency for a ping-pong packets traffic with a certain payload.
>> The result is as following.
>>
>>   - 4.4 kernel: avg = ~20s
>>   - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s
>>
>> I have been just learning arm64 pseudo-NMI code and have a question,
>> why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
>> I wonder if this brings some performance regression.
>>
>> First, I make this patch and then do the test again. Here's the result.
>>
>>   - 5.10 kernel with this patch not applied: avg = ~40s
>>   - 5.10 kernel with this patch applied: avg = ~23s
>>
>> Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
>> set. It seems the pseudo-NMI feature actually brings some overhead to
>> performance event if CONFIG_ARM64_PSEUDO_NMI is not set.
>>
>> Furthermore, I find the feature also brings some overhead to vmlinux size.
>> I build 5.10 kernel with this patch applied or not while
>> CONFIG_ARM64_PSEUDO_NMI is not set.
>>
>>   - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
>>   - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
>>
>> That means arm64 pseudo-NMI feature may bring ~200KB overhead to
>> vmlinux size.
>>
>> Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
>> and performance even if config is not set. To avoid it, add macro control
>> all around the related code.
> This obviously attracted my attention, and I took this patch for a
> ride on 5.16-rc8 on a machine that doesn't support GICv3 NMIs to make
> sure that any extra code would only result in pure overhead.
>
> There was no measurable difference with this patch applied or not,
> with CONFIG_ARM64_PSEUDO_NMI selected or not for the workloads I tried
> (I/O heavy virtual machines, hackbench).
Our test is some kind of network test.
>
> Mark already asked a number of questions (test case, implementation,
> test on a modern kernel). Please provide as many detail as you
> possibly can, because such a regression really isn't expected, and
> doesn't show up on the systems I have at hand. Some profiling numbers
> could also be interesting, in case this is a result of a particular
> resource being thrashed (TLB, cache...).

I replied to Mark a few moments ago and provided as many details as I can.

You mentioned TLB and cache could be thrashed. How can we check this?

By using perf tools?

>
> Thanks,
>
> 	M.
>


From liang.yang at amlogic.com  Sun Jan  9 19:28:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 10 Jan 2022 11:28:46 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <1jfsq1z22l.fsf@starbuckisacylon.baylibre.com>
 <151ded4b-a28b-dac9-31e1-5b817cd9dc44@amlogic.com>
 <e4942f0e-3670-fb52-5cfa-b131a037320a@baylibre.com>
Message-ID: <5fd77688-922c-d8f4-1a09-41967fa52f89@amlogic.com>

Hi,

On 2022/1/7 17:57, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 07/01/2022 05:04, Liang Yang wrote:
>> Hi Jerome,
>>
>> On 2022/1/6 16:16, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>>
>>> On Thu 06 Jan 2022 at 11:25, Liang Yang <liang.yang at amlogic.com> wrote:
>>>
>>>> Because EMMC and NAND have the same control clock register, so we
>>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>>
>>>>  ????sd_emmc_c_clkc: mmc at 7000 {
>>>>  ??????? compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>>>  ??????? reg = <0x0 0x7000 0x0 0x800>;
>>>>  ????};
>>>>
>>>>  ????nand-controller at 7800 {
>>>>  ??????? ......
>>>>
>>>>  ??????? clocks = <&clkc CLKID_SD_EMMC_C>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>>>  ??????????? <&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>>>  ??????? clock-names = "core", "device", "rx", "tx";
>>>>  ??????? amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>>
>>>>  ??????? ......
>>>>  ????}
>>>>
>>>> but in fact, above implementation is rejected. so now registering
>>>> a nand_divider.
>>>
>>> Can you give a bit of context ? a link to the discussion rejecting this
>>>
>> Maybe I mistake the meaning of [jianxin.pan at amlogic.com], so i need him to clarify it.
>>> As far as remember, things were getting done for A1 and stopped before
>>> clock part was finished. I'm saying the change is wrong, just that a
>>> discussion is needed before a decision is made.
>>>
>> ok.
>> previous discussion in this link:
>> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
>> it never go on since v6.
> 
> Looking at the serie I don't see any major blockers, if you're willing to take ownership
> of this patchset and send a v6 with all issues/comments addressed, it would be easier than
> restarting the whole design discussion
> 
> Neil


Hi Neil, thanks for your advice.
After talking with [jianxin.pan], form this link 
<https://lkml.org/lkml/2019/1/8/441>, it already moves futher and on v9, 
so we decide to continue to work hard on it.

> 
>>
>>>>
>>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>  ? drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>>  ? 1 file changed, 49 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>>> index ac3be92872d0..4472363059c2 100644
>>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>>> @@ -2,7 +2,7 @@
>>>>  ? /*
>>>>  ?? * Amlogic Meson Nand Flash Controller Driver
>>>>  ?? *
>>>> - * Copyright (c) 2018 Amlogic, inc.
>>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>>  ?? * Author: Liang Yang <liang.yang at amlogic.com>
>>>>  ?? */
>>>>  ? @@ -10,6 +10,7 @@
>>>>  ? #include <linux/dma-mapping.h>
>>>>  ? #include <linux/interrupt.h>
>>>>  ? #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>  ? #include <linux/mtd/rawnand.h>
>>>>  ? #include <linux/mtd/mtd.h>
>>>>  ? #include <linux/mfd/syscon.h>
>>>> @@ -55,6 +56,7 @@
>>>>  ? #define NFC_REG_VER??????? 0x38
>>>>  ? ? #define NFC_RB_IRQ_EN??????? BIT(21)
>>>> +#define NFC_CMD_FIFO_RESET??? BIT(31)
>>>>  ? ? #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)??? \
>>>>  ????? (??????????????????????????????? \
>>>> @@ -104,6 +106,9 @@
>>>>  ? ? #define PER_INFO_BYTE??????? 8
>>>>  ? +#define CLK_DIV_SHIFT??????? 0
>>>> +#define CLK_DIV_WIDTH??????? 6
>>>> +
>>>>  ? struct meson_nfc_nand_chip {
>>>>  ????? struct list_head node;
>>>>  ????? struct nand_chip nand;
>>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>>  ????? struct nand_controller controller;
>>>>  ????? struct clk *core_clk;
>>>>  ????? struct clk *device_clk;
>>>> -??? struct clk *phase_tx;
>>>> -??? struct clk *phase_rx;
>>>
>>> I would have been nice to explain why these clock are no longer
>>> required, in the change description maybe ?
>>
>> i got the reply from our vlsi members that rx and tx doesn't make sense to meson NFC timing. so previous commit about this should be wrong.
>>>
>>>> +??? struct clk *nand_clk;
>>>> +??? struct clk_divider nand_divider;
>>>>  ? ????? unsigned long clk_rate;
>>>>  ????? u32 bus_timing;
>>>>  ? ????? struct device *dev;
>>>>  ????? void __iomem *reg_base;
>>>> -??? struct regmap *reg_clk;
>>>> +??? void __iomem *reg_clk;
>>>>  ????? struct completion completion;
>>>>  ????? struct list_head chips;
>>>>  ????? const struct meson_nfc_data *data;
>>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>>  ????? cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>>  ????????? | nfc->param.chip_select | nfc->timing.tbers_max;
>>>>  ????? writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>> -
>>>> +??? meson_nfc_drain_cmd(nfc);
>>>
>>> is this clock related ?
>> ok, i will split it in another patch.
>>>
>>>>  ????? ret = wait_for_completion_timeout(&nfc->completion,
>>>>  ??????????????????????? msecs_to_jiffies(timeout_ms));
>>>>  ????? if (ret == 0)
>>>>  ????????? ret = -1;
>>>>  ? +??? /* reset command fifo to avoid lock */
>>>> +??? writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>
>>> Again, not seem to be clock related - does not belong in this patch
>> ok, i will split it in another patch.
>>>
>>>>  ????? return ret;
>>>>  ? }
>>>>  ? @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
>>>>  ? static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ? {
>>>>  ????? int ret;
>>>> +??? struct clk_init_data init = {0};
>>>> +??? const char *fix_div2_pll_name[1];
>>>>  ? -??? /* request core clock */
>>>
>>> Why is the comment bothering you ?
>>>
>>>>  ????? nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>>  ????? if (IS_ERR(nfc->core_clk)) {
>>>>  ????????? dev_err(nfc->dev, "failed to get core clock\n");
>>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ????????? return PTR_ERR(nfc->device_clk);
>>>>  ????? }
>>>>  ? -??? nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>>> -??? if (IS_ERR(nfc->phase_tx)) {
>>>> -??????? dev_err(nfc->dev, "failed to get TX clk\n");
>>>> -??????? return PTR_ERR(nfc->phase_tx);
>>>> -??? }
>>>> -
>>>> -??? nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>>> -??? if (IS_ERR(nfc->phase_rx)) {
>>>> -??????? dev_err(nfc->dev, "failed to get RX clk\n");
>>>> -??????? return PTR_ERR(nfc->phase_rx);
>>>> -??? }
>>>> +??? init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>>> +??? init.ops = &clk_divider_ops;
>>>> +??? fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>>
>>> You should be using "fw_name" so CCF looks a DT directly, instead of this
>> ok
>>>
>>>> +??? init.parent_names = fix_div2_pll_name;
>>>> +??? init.num_parents = 1;
>>>> +??? nfc->nand_divider.reg = nfc->reg_clk;
>>>> +??? nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>>> +??? nfc->nand_divider.width = CLK_DIV_WIDTH;
>>>> +??? nfc->nand_divider.hw.init = &init;
>>>> +??? nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>>> +????????????????? CLK_DIVIDER_ROUND_CLOSEST |
>>>> +??????????????????????? CLK_DIVIDER_ALLOW_ZERO;
>>>> +
>>>> +??? nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>>> +??? if (IS_ERR(nfc->nand_clk))
>>>> +??????? return PTR_ERR(nfc->nand_clk);
>>>>  ? ????? /* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>>> -??? regmap_update_bits(nfc->reg_clk,
>>>> -?????????????? 0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>>> +??? writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>>  ? ????? ret = clk_prepare_enable(nfc->core_clk);
>>>>  ????? if (ret) {
>>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ????????? goto err_device_clk;
>>>>  ????? }
>>>>  ? -??? ret = clk_prepare_enable(nfc->phase_tx);
>>>> +??? ret = clk_prepare_enable(nfc->nand_clk);
>>>>  ????? if (ret) {
>>>> -??????? dev_err(nfc->dev, "failed to enable TX clock\n");
>>>> -??????? goto err_phase_tx;
>>>> -??? }
>>>> -
>>>> -??? ret = clk_prepare_enable(nfc->phase_rx);
>>>> -??? if (ret) {
>>>> -??????? dev_err(nfc->dev, "failed to enable RX clock\n");
>>>> -??????? goto err_phase_rx;
>>>> +??????? dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>>> +??????? goto err_nand_clk;
>>>>  ????? }
>>>>  ? ????? ret = clk_set_rate(nfc->device_clk, 24000000);
>>>>  ????? if (ret)
>>>> -??????? goto err_disable_rx;
>>>> +??????? goto err_disable_clk;
>>>>  ? ????? return 0;
>>>>  ? -err_disable_rx:
>>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>>> -err_phase_rx:
>>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>>> -err_phase_tx:
>>>> +err_disable_clk:
>>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>>> +err_nand_clk:
>>>>  ????? clk_disable_unprepare(nfc->device_clk);
>>>>  ? err_device_clk:
>>>>  ????? clk_disable_unprepare(nfc->core_clk);
>>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>  ? ? static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>>  ? {
>>>> -??? clk_disable_unprepare(nfc->phase_rx);
>>>> -??? clk_disable_unprepare(nfc->phase_tx);
>>>> +??? clk_disable_unprepare(nfc->nand_clk);
>>>>  ????? clk_disable_unprepare(nfc->device_clk);
>>>>  ????? clk_disable_unprepare(nfc->core_clk);
>>>>  ? }
>>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>  ????? struct device *dev = &pdev->dev;
>>>>  ????? struct meson_nfc *nfc;
>>>>  ????? struct resource *res;
>>>> +??? u32 ext_clk_reg;
>>>>  ????? int ret, irq;
>>>>  ? ????? nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>  ????? if (IS_ERR(nfc->reg_base))
>>>>  ????????? return PTR_ERR(nfc->reg_base);
>>>>  ? -??? nfc->reg_clk =
>>>> -??????? syscon_regmap_lookup_by_phandle(dev->of_node,
>>>> -??????????????????????? "amlogic,mmc-syscon");
>>>> +??? ret = of_property_read_u32(pdev->dev.of_node,
>>>> +?????????????????? "sd_emmc_c_clkc",
>>>> +?????????????????? &ext_clk_reg);
>>>> +??? if (ret) {
>>>> +??????? dev_err(dev, "failed to get NAND external clock register\n");
>>>> +??????? return ret;
>>>> +??? }
>>>> +
>>>> +??? nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>
>>> That's how you should get a register region.
>>> If you want an example of a device claiming several region on amlogic,
>>> have a look at the pinctrl driver.
>> ok
>>>
>>>>  ????? if (IS_ERR(nfc->reg_clk)) {
>>>>  ????????? dev_err(dev, "Failed to lookup clock base\n");
>>>>  ????????? return PTR_ERR(nfc->reg_clk);
>>>
>>> .
> 
> .


From liang.yang at amlogic.com  Sun Jan  9 19:32:52 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 10 Jan 2022 11:32:52 +0800
Subject: [PATCH] mtd: rawnand: meson: fix the clock after discarding
 sd_emmc_c_clkc
In-Reply-To: <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>
References: <20220106032504.23310-1-liang.yang@amlogic.com>
 <20220106090832.42225c49@xps13>
 <9c7b1d77-cff1-b40c-6d02-f67ca8b9b683@amlogic.com>
 <1jh7agou4i.fsf@starbuckisacylon.baylibre.com>
Message-ID: <b3e5cec5-9eed-a2cd-ee0b-7e49672cc9f6@amlogic.com>

Hello Jerome,

On 2022/1/7 15:54, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Fri 07 Jan 2022 at 10:40, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Hi Miquel,
>>
>> Meson NFC clock depends on the implementation of sd_emmc_c_clkc, but i
>> don't find the commit in
>> linux mainline. then the information i got from [jianxin.pan at amlogic.com]
>> is the rejection of
>> serial patches. I just look into the corresponding emails in link:
>>
>> https://lore.kernel.org/all/86789d73-5a6c-7729-ecd1-dcd342b2fcde at amlogic.com/
>> it seems the patch never go on since V6, so [jianxin.pan at amlogic.com],
>> could you help to clear it?
>> let us address the discussion in another email from
>> [jbrunet at baylibre.com].
> 
> That V6 was "rejected" because some comments from thre V5 were still not
> addressed.
> 
em, we decide to continue to work on sd_emmc_c_clkc and it already has a 
longer trip, see this link <https://lkml.org/lkml/2019/1/8/441>. thanks.

>>
>> On 2022/1/6 16:08, Miquel Raynal wrote:
>>> [ EXTERNAL EMAIL ]
>>> Hi Liang,
>>> liang.yang at amlogic.com wrote on Thu, 6 Jan 2022 11:25:04 +0800:
>>>
>>>> Because EMMC and NAND have the same control clock register, so we
>>>> implement a 'sd_emmc_c_clkc'. Previously DTS is defined as below:
>>>>
>>>> 	sd_emmc_c_clkc: mmc at 7000 {
>>>> 		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
>>>> 		reg = <0x0 0x7000 0x0 0x800>;
>>>> 	};
>>>>
>>>> 	nand-controller at 7800 {
>>>> 		......
>>>>
>>>> 		clocks = <&clkc CLKID_SD_EMMC_C>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
>>>> 			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
>>>> 		clock-names = "core", "device", "rx", "tx";
>>>> 		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
>>>>
>>>> 		......
>>>> 	}
>>>>
>>>> but in fact, above implementation is rejected. so now registering
>>>> a nand_divider.
>>> What is rejected?
>>> Why is it rejected?
>>> What is nand_divider?
>> i simplify our clock framework below, so nand divider is SD_EMMC_CLOCK[5:0]
>> here.
>> 			   -----          -----		    -----
>> 	   the other------|	\        |     |	   |	 |
>>           		  | mux	| -----  |  N  | ----------| NFC/|
>> 	   FCLK_DIV2------|     |        |     |	   | EMMC|
>> 			   -----/         ----- 	    -----
>> 		    SD_EMMC_CLOCK[7:6] SD_EMMC_CLOCK[5:0]
>>>
>>>>
>>>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
>>> Change Ids are not expected in the upstream kernel.
>>> But if you fix something you should have a Fixes:.
>>>
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>    drivers/mtd/nand/raw/meson_nand.c | 88 +++++++++++++++++--------------
>>>>    1 file changed, 49 insertions(+), 39 deletions(-)
>>>>
>>>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>>>> index ac3be92872d0..4472363059c2 100644
>>>> --- a/drivers/mtd/nand/raw/meson_nand.c
>>>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>>>> @@ -2,7 +2,7 @@
>>>>    /*
>>>>     * Amlogic Meson Nand Flash Controller Driver
>>>>     *
>>>> - * Copyright (c) 2018 Amlogic, inc.
>>>> + * Copyright (c) 2018-2021 Amlogic, inc.
>>>>     * Author: Liang Yang <liang.yang at amlogic.com>
>>>>     */
>>>>    @@ -10,6 +10,7 @@
>>>>    #include <linux/dma-mapping.h>
>>>>    #include <linux/interrupt.h>
>>>>    #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/mtd/rawnand.h>
>>>>    #include <linux/mtd/mtd.h>
>>>>    #include <linux/mfd/syscon.h>
>>>> @@ -55,6 +56,7 @@
>>>>    #define NFC_REG_VER		0x38
>>>>      #define NFC_RB_IRQ_EN		BIT(21)
>>>> +#define NFC_CMD_FIFO_RESET	BIT(31)
>>>>      #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)
>>>> \
>>>>    	(								\
>>>> @@ -104,6 +106,9 @@
>>>>      #define PER_INFO_BYTE		8
>>>>    +#define CLK_DIV_SHIFT		0
>>>> +#define CLK_DIV_WIDTH		6
>>>> +
>>>>    struct meson_nfc_nand_chip {
>>>>    	struct list_head node;
>>>>    	struct nand_chip nand;
>>>> @@ -151,15 +156,15 @@ struct meson_nfc {
>>>>    	struct nand_controller controller;
>>>>    	struct clk *core_clk;
>>>>    	struct clk *device_clk;
>>>> -	struct clk *phase_tx;
>>>> -	struct clk *phase_rx;
>>>> +	struct clk *nand_clk;
>>>> +	struct clk_divider nand_divider;
>>>>      	unsigned long clk_rate;
>>>>    	u32 bus_timing;
>>>>      	struct device *dev;
>>>>    	void __iomem *reg_base;
>>>> -	struct regmap *reg_clk;
>>>> +	void __iomem *reg_clk;
>>>>    	struct completion completion;
>>>>    	struct list_head chips;
>>>>    	const struct meson_nfc_data *data;
>>>> @@ -406,12 +411,14 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
>>>>    	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
>>>>    		| nfc->param.chip_select | nfc->timing.tbers_max;
>>>>    	writel(cmd, nfc->reg_base + NFC_REG_CMD);
>>>> -
>>>> +	meson_nfc_drain_cmd(nfc);
>>>>    	ret = wait_for_completion_timeout(&nfc->completion,
>>>>    					  msecs_to_jiffies(timeout_ms));
>>>>    	if (ret == 0)
>>>>    		ret = -1;
>>>>    +	/* reset command fifo to avoid lock */
>>>> +	writel(NFC_CMD_FIFO_RESET, nfc->reg_base + NFC_REG_CMD);
>>>>    	return ret;
>>>>    }
>>>>    @@ -988,8 +995,9 @@ static const struct mtd_ooblayout_ops
>>>> meson_ooblayout_ops = {
>>>>    static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    {
>>>>    	int ret;
>>>> +	struct clk_init_data init = {0};
>>>> +	const char *fix_div2_pll_name[1];
>>>>    -	/* request core clock */
>>>>    	nfc->core_clk = devm_clk_get(nfc->dev, "core");
>>>>    	if (IS_ERR(nfc->core_clk)) {
>>>>    		dev_err(nfc->dev, "failed to get core clock\n");
>>>> @@ -1002,21 +1010,25 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    		return PTR_ERR(nfc->device_clk);
>>>>    	}
>>>>    -	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
>>>> -	if (IS_ERR(nfc->phase_tx)) {
>>>> -		dev_err(nfc->dev, "failed to get TX clk\n");
>>>> -		return PTR_ERR(nfc->phase_tx);
>>>> -	}
>>>> -
>>>> -	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
>>>> -	if (IS_ERR(nfc->phase_rx)) {
>>>> -		dev_err(nfc->dev, "failed to get RX clk\n");
>>>> -		return PTR_ERR(nfc->phase_rx);
>>>> -	}
>>>> +	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
>>>> +	init.ops = &clk_divider_ops;
>>>> +	fix_div2_pll_name[0] = __clk_get_name(nfc->device_clk);
>>>> +	init.parent_names = fix_div2_pll_name;
>>>> +	init.num_parents = 1;
>>>> +	nfc->nand_divider.reg = nfc->reg_clk;
>>>> +	nfc->nand_divider.shift = CLK_DIV_SHIFT;
>>>> +	nfc->nand_divider.width = CLK_DIV_WIDTH;
>>>> +	nfc->nand_divider.hw.init = &init;
>>>> +	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
>>>> +				  CLK_DIVIDER_ROUND_CLOSEST |
>>>> +          			  CLK_DIVIDER_ALLOW_ZERO;
>>>> +
>>>> +	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
>>>> +	if (IS_ERR(nfc->nand_clk))
>>>> +		return PTR_ERR(nfc->nand_clk);
>>>>      	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
>>>> -	regmap_update_bits(nfc->reg_clk,
>>>> -			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
>>>> +	writel(CLK_SELECT_NAND | readl(nfc->reg_clk), nfc->reg_clk);
>>>>      	ret = clk_prepare_enable(nfc->core_clk);
>>>>    	if (ret) {
>>>> @@ -1030,29 +1042,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>    		goto err_device_clk;
>>>>    	}
>>>>    -	ret = clk_prepare_enable(nfc->phase_tx);
>>>> +	ret = clk_prepare_enable(nfc->nand_clk);
>>>>    	if (ret) {
>>>> -		dev_err(nfc->dev, "failed to enable TX clock\n");
>>>> -		goto err_phase_tx;
>>>> -	}
>>>> -
>>>> -	ret = clk_prepare_enable(nfc->phase_rx);
>>>> -	if (ret) {
>>>> -		dev_err(nfc->dev, "failed to enable RX clock\n");
>>>> -		goto err_phase_rx;
>>>> +		dev_err(nfc->dev, "pre enable NFC divider fail\n");
>>>> +		goto err_nand_clk;
>>>>    	}
>>>>      	ret = clk_set_rate(nfc->device_clk, 24000000);
>>>>    	if (ret)
>>>> -		goto err_disable_rx;
>>>> +		goto err_disable_clk;
>>>>      	return 0;
>>>>    -err_disable_rx:
>>>> -	clk_disable_unprepare(nfc->phase_rx);
>>>> -err_phase_rx:
>>>> -	clk_disable_unprepare(nfc->phase_tx);
>>>> -err_phase_tx:
>>>> +err_disable_clk:
>>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>> +err_nand_clk:
>>>>    	clk_disable_unprepare(nfc->device_clk);
>>>>    err_device_clk:
>>>>    	clk_disable_unprepare(nfc->core_clk);
>>>> @@ -1061,8 +1065,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
>>>>      static void meson_nfc_disable_clk(struct meson_nfc *nfc)
>>>>    {
>>>> -	clk_disable_unprepare(nfc->phase_rx);
>>>> -	clk_disable_unprepare(nfc->phase_tx);
>>>> +	clk_disable_unprepare(nfc->nand_clk);
>>>>    	clk_disable_unprepare(nfc->device_clk);
>>>>    	clk_disable_unprepare(nfc->core_clk);
>>>>    }
>>>> @@ -1375,6 +1378,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>    	struct device *dev = &pdev->dev;
>>>>    	struct meson_nfc *nfc;
>>>>    	struct resource *res;
>>>> +	u32 ext_clk_reg;
>>>>    	int ret, irq;
>>>>      	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
>>>> @@ -1396,9 +1400,15 @@ static int meson_nfc_probe(struct platform_device *pdev)
>>>>    	if (IS_ERR(nfc->reg_base))
>>>>    		return PTR_ERR(nfc->reg_base);
>>>>    -	nfc->reg_clk =
>>>> -		syscon_regmap_lookup_by_phandle(dev->of_node,
>>>> -						"amlogic,mmc-syscon");
>>>> +	ret = of_property_read_u32(pdev->dev.of_node,
>>>> +				   "sd_emmc_c_clkc",
>>>> +				   &ext_clk_reg);
>>>> +	if (ret) {
>>>> +		dev_err(dev, "failed to get NAND external clock register\n");
>>>> +		return ret;
>>>> +	}
>>>> +
>>>> +	nfc->reg_clk = devm_ioremap(&pdev->dev, ext_clk_reg, sizeof(int));
>>>>    	if (IS_ERR(nfc->reg_clk)) {
>>>>    		dev_err(dev, "Failed to lookup clock base\n");
>>>>    		return PTR_ERR(nfc->reg_clk);
>>>
>>> Thanks,
>>> Miqu?l
>>> .
> 
> .


From yuzhao at google.com  Sun Jan  9 19:58:02 2022
From: yuzhao at google.com (Yu Zhao)
Date: Sun, 9 Jan 2022 20:58:02 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
Message-ID: <Yduuyrk/AZG717Hs@google.com>

On Fri, Jan 07, 2022 at 10:00:31AM +0100, Michal Hocko wrote:
> On Fri 07-01-22 09:55:09, Michal Hocko wrote:
> [...]
> > > In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
> > > reclaimer; and direct reclaimers rarely come here, i.e., only when
> > > kswapd can't keep up in terms of the aging, which is similar to the
> > > condition where the inactive list is empty for the active/inactive
> > > lru.
> > 
> > Well, this is not a strong argument to be honest. Kswapd being stuck
> > and the majority of the reclaim being done in the direct reclaim
> > context is a situation I have seen many many times.
> 
> Also do not forget that memcg reclaim is effectivelly only direct
> reclaim. Not that the memcg reclaim indicates a global memory shortage
> but it can add up and race with the global reclaim as well.

I don't dispute any of the above, and I probably don't like this code
more than you do.

But let's not forget the purposes of PF_MEMALLOC, besides preventing
recursive reclaims, include letting reclaim dip into reserves so that
it can make more free memory. So I think it's acceptable if the
following conditions are met:
1. The allocation size is small.
2. The number of allocations is bounded.
3. Its failure doesn't stall reclaim.
And it'd be nice if
4. The allocation happens rarely, e.g., slow path only.

The code in question meets all of them.

1. This allocation is 160 bytes.
2. It's bounded by the number of page table walkers which, in the
   worst, is same as the number of mm_struct's.
3. Most importantly, its failure doesn't stall the aging. The aging
   will fallback to the rmap-based function lru_gen_look_around().
   But this function only gathers the accessed bit from at most 64
   PTEs, meaning it's less efficient (retains ~80% performance gains).
4. This allocation is rare, i.e., only when the aging is required,
   which is similar to the low inactive case for the active/inactive
   lru.

The bottom line is I can try various optimizations, e.g., preallocate
a few buffers for a limited number of page walkers and if this number
has been reached, fallback to the rmap-based function. But I have yet
to see evidence that calls for additional complexity.


From hnagalla at ti.com  Sun Jan  9 20:06:48 2022
From: hnagalla at ti.com (Hari Nagalla)
Date: Sun, 9 Jan 2022 22:06:48 -0600
Subject: [PATCH 0/2] TI K3 M4F support on AM64x SoC
Message-ID: <20220110040650.18186-1-hnagalla@ti.com>

Hi All,

The following series introduces K3 M4F remoteproc driver support for AM64x 
SoC family. The AM64X SoCs has a ARM Cortex M4F core in MCU voltage
domain. For safety oriented applications, this core is operated
independently with out any IPC to other cores on the SoC. However,
for non safety applications, some customers use it as a remote processor
and so linux remote proc support is extended to the M4F core.

See AM64x Technical Reference Manual (SPRUIM2C ? SEPTEMBER 2021)
for further details: https://www.ti.com/lit/pdf/SPRUIM2

Regards
Hari

Hari Nagalla (2):
  dt-bindings: remoteproc: k3-m4f: Add bindings for K3 AM64x SoCs
  remoteproc: k4-m4: Add a remoteproc driver for M4F subsystem

 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 121 +++
 drivers/remoteproc/Kconfig                    |  13 +
 drivers/remoteproc/Makefile                   |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c      | 899 ++++++++++++++++++
 4 files changed, 1034 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

-- 
2.17.1



From hnagalla at ti.com  Sun Jan  9 20:06:49 2022
From: hnagalla at ti.com (Hari Nagalla)
Date: Sun, 9 Jan 2022 22:06:49 -0600
Subject: [PATCH 1/2] dt-bindings: remoteproc: k3-m4f: Add bindings for K3
 AM64x SoCs
In-Reply-To: <20220110040650.18186-1-hnagalla@ti.com>
References: <20220110040650.18186-1-hnagalla@ti.com>
Message-ID: <20220110040650.18186-2-hnagalla@ti.com>

K3 AM64x SoC has a Cortex M4F subsystem in the MCU volatge domain.
The remote processor's life cycle management and IPC mechanisms are
similar across the R5F and M4F cores from remote processor driver
point of view. However, there are subtle differences in image loading
and starting the M4F subsystems.

The YAML binding document provides the various node properties to be
configured by the consumers of the M4F subsystem.

Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
 .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 121 ++++++++++++++++++
 1 file changed, 121 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml

diff --git a/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
new file mode 100644
index 000000000000..8db9a3f6256e
--- /dev/null
+++ b/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
@@ -0,0 +1,121 @@
+# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/remoteproc/ti,k3-m4f-rproc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TI K3 M4F processor subsystems
+
+maintainers:
+  - Hari Nagalla <hnagalla at ti.com>
+
+description: |
+  Some K3 family SoCs have  Arm Cortex M4F cores. AM64x is a SoC in K3
+  family with a M4F core. Typically safety oriented applications may use
+  the M4F core in isolation with out an IPC. Where as some Industrial and
+  home automation applications, may use the M4F core as a remote processor
+  with IPC communications.
+
+properties:
+  $nodename:
+    pattern: "^m4fss(@.*)?"
+
+  compatible:
+    enum:
+      - ti,am64-m4fss
+
+  power-domains:
+    description: |
+      Should contain a phandle to a PM domain provider node and an args
+      specifier containing the M4FSS device id value.
+    maxItems: 1
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  reg:
+    items:
+      - description: Address and Size of the IRAM internal memory region
+      - description: Address and Size of the DRAM internal memory region
+
+  reg-names:
+    items:
+      - const: iram
+      - const: dram
+
+  resets:
+    description: |
+      Should contain the phandle to the reset controller node managing the
+      local resets for this device, and a reset specifier.
+    maxItems: 1
+
+  firmware-name:
+    description: |
+      Should contain the name of the default firmware image
+      file located on the firmware search path
+
+  mboxes:
+    description: |
+      OMAP Mailbox specifier denoting the sub-mailbox, to be used for
+      communication with the remote processor. This property should match
+      with the sub-mailbox node used in the firmware image.
+    maxItems: 1
+
+  memory-region:
+    description: |
+      phandle to the reserved memory nodes to be associated with the
+      remoteproc device. There should be at least two reserved memory nodes
+      defined. The reserved memory nodes should be carveout nodes, and
+      should be defined with a "no-map" property as per the bindings in
+      Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+    minItems: 2
+    maxItems: 8
+#    items:
+#      - description: region used for dynamic DMA allocations like vrings and
+#                         vring buffers
+#      - description: region reserved for firmware image sections
+    additionalItems: true
+
+    unevaluatedProperties: false
+
+
+required:
+  - compatible
+  - power-domains
+  - "#address-cells"
+  - "#size-cells"
+  - reg
+  - reg-names
+  - ti,sci
+  - ti,sci-dev-id
+  - ti,sci-proc-ids
+  - resets
+  - firmware-name
+
+additionalProperties: false
+
+examples:
+  - |
+    cbass_main:  bus at f4000 {
+      #address-cells = <2>;
+      #size-cells = <2>;
+      mcu_m4fss: m4fss at 5000000 {
+        compatible = "ti,am64-m4fss";
+        reg = <0x00 0x5000000 0x00 0x30000>,
+              <0x00 0x5040000 0x00 0x10000>;
+        reg-names = "iram", "dram";
+        ti,sci = <&dmsc>;
+        ti,sci-dev-id = <9>;
+        ti,sci-proc-ids = <0x18 0xff>;
+        resets = <&k3_reset 9 1>;
+        firmware-name = "am64-mcu-m4f0_0-fw";
+        mboxes = <&mailbox0_cluster6 &mbox_m4_0>;
+        memory-region = <&mcu_m4fss_dma_memory_region>,
+                        <&mcu_m4fss_memory_region>;
+      };
+    };
+
+...
-- 
2.17.1



From hnagalla at ti.com  Sun Jan  9 20:06:50 2022
From: hnagalla at ti.com (Hari Nagalla)
Date: Sun, 9 Jan 2022 22:06:50 -0600
Subject: [PATCH 2/2] remoteproc: k4-m4: Add a remoteproc driver for M4F
 subsystem
In-Reply-To: <20220110040650.18186-1-hnagalla@ti.com>
References: <20220110040650.18186-1-hnagalla@ti.com>
Message-ID: <20220110040650.18186-3-hnagalla@ti.com>

The AM64x SoC of TI K3 family has a Cortex  M4F core in the MCU
domain. This core is typically used for safety applications in a stand
alone mode. However, some application (non safety related) may want to
use the M4F core as a generic remote processor with IPC to the host
processor. The M4F core has internal IRAM and DRAM memories and are
exposed to the system bus for code and data loading.

A remoteproc driver is added to support this subsystem to be able to
load and boot M4F core. Loading includes to M4F internal memories and
to any predefined external code/data memory. The carveouts for external
contiguous memory is defined in the M4F device node and should match
with the external memory declarations in the M4F image binary. The M4F
subsystem has two resets. One reset is for the entire subsystem i.e
including the internal memories and ther other, a local reset is only
for the M4F processing core. For loading the image remoteoproc driver
first releases the subsystem reset, loads the firmware image and then
releases the local reset to let the M4F processing core to run.

Signed-off-by: Hari Nagalla <hnagalla at ti.com>
---
 drivers/remoteproc/Kconfig               |  13 +
 drivers/remoteproc/Makefile              |   1 +
 drivers/remoteproc/ti_k3_m4_remoteproc.c | 899 +++++++++++++++++++++++
 3 files changed, 913 insertions(+)
 create mode 100644 drivers/remoteproc/ti_k3_m4_remoteproc.c

diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig
index 3ddd426fc969..059490822b6f 100644
--- a/drivers/remoteproc/Kconfig
+++ b/drivers/remoteproc/Kconfig
@@ -348,6 +348,19 @@ config TI_K3_R5_REMOTEPROC
 	  It's safe to say N here if you're not interested in utilizing
 	  a slave processor.
 
+config TI_K3_M4_REMOTEPROC
+	tristate "TI K3 M4 remoteproc support"
+	depends on ARCH_K3
+	select MAILBOX
+	select OMAP2PLUS_MBOX
+	help
+	  Say m here to support TI's M4 remote processor subsystems
+	  on various TI K3 family of SoCs through the remote processor
+	  framework.
+
+	  It's safe to say N here if you're not interested in utilizing
+	  a slave processor.
+
 endif # REMOTEPROC
 
 endmenu
diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile
index 5478c7cb9e07..449948f2e466 100644
--- a/drivers/remoteproc/Makefile
+++ b/drivers/remoteproc/Makefile
@@ -38,3 +38,4 @@ obj-$(CONFIG_ST_SLIM_REMOTEPROC)	+= st_slim_rproc.o
 obj-$(CONFIG_STM32_RPROC)		+= stm32_rproc.o
 obj-$(CONFIG_TI_K3_DSP_REMOTEPROC)	+= ti_k3_dsp_remoteproc.o
 obj-$(CONFIG_TI_K3_R5_REMOTEPROC)	+= ti_k3_r5_remoteproc.o
+obj-$(CONFIG_TI_K3_M4_REMOTEPROC)	+= ti_k3_m4_remoteproc.o
diff --git a/drivers/remoteproc/ti_k3_m4_remoteproc.c b/drivers/remoteproc/ti_k3_m4_remoteproc.c
new file mode 100644
index 000000000000..d8fb419bb269
--- /dev/null
+++ b/drivers/remoteproc/ti_k3_m4_remoteproc.c
@@ -0,0 +1,899 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * TI K3 Cortex-M4 Remote Processor(s) driver
+ *
+ * Copyright (C) 2021 Texas Instruments Incorporated - https://www.ti.com/
+ *	Hari Nagalla <hnagalla at ti.com>
+ */
+
+#include <linux/io.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/omap-mailbox.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include "omap_remoteproc.h"
+#include "remoteproc_internal.h"
+#include "ti_sci_proc.h"
+
+#define KEYSTONE_RPROC_LOCAL_ADDRESS_MASK	(SZ_16M - 1)
+
+/**
+ * struct k3_m4_mem - internal memory structure
+ * @cpu_addr: MPU virtual address of the memory region
+ * @bus_addr: Bus address used to access the memory region
+ * @dev_addr: Device address of the memory region from DSP view
+ * @size: Size of the memory region
+ */
+struct k3_m4_mem {
+	void __iomem *cpu_addr;
+	phys_addr_t bus_addr;
+	u32 dev_addr;
+	size_t size;
+};
+
+/**
+ * struct k3_m4_mem_data - memory definitions for a DSP
+ * @name: name for this memory entry
+ * @dev_addr: device address for the memory entry
+ */
+struct k3_m4_mem_data {
+	const char *name;
+	const u32 dev_addr;
+};
+
+/**
+ * struct k3_m4_dev_data - device data structure for a DSP
+ * @mems: pointer to memory definitions for a DSP
+ * @num_mems: number of memory regions in @mems
+ * @boot_align_addr: boot vector address alignment granularity
+ * @uses_lreset: flag to denote the need for local reset management
+ */
+struct k3_m4_dev_data {
+	const struct k3_m4_mem_data *mems;
+	u32 num_mems;
+	u32 boot_align_addr;
+	bool uses_lreset;
+};
+
+/**
+ * struct k3_m4_rproc - k3 M4 remote processor driver structure
+ * @dev: cached device pointer
+ * @rproc: remoteproc device handle
+ * @mem: internal memory regions data
+ * @num_mems: number of internal memory regions
+ * @rmem: reserved memory regions data
+ * @num_rmems: number of reserved memory regions
+ * @reset: reset control handle
+ * @data: pointer to M4-specific device data
+ * @tsp: TI-SCI processor control handle
+ * @ti_sci: TI-SCI handle
+ * @ti_sci_id: TI-SCI device identifier
+ * @mbox: mailbox channel handle
+ * @client: mailbox client to request the mailbox channel
+ * @ipc_only: flag to indicate IPC-only mode
+ */
+struct k3_m4_rproc {
+	struct device *dev;
+	struct rproc *rproc;
+	struct k3_m4_mem *mem;
+	int num_mems;
+	struct k3_m4_mem *rmem;
+	int num_rmems;
+	struct reset_control *reset;
+	const struct k3_m4_dev_data *data;
+	struct ti_sci_proc *tsp;
+	const struct ti_sci_handle *ti_sci;
+	u32 ti_sci_id;
+	struct mbox_chan *mbox;
+	struct mbox_client client;
+	bool ipc_only;
+};
+
+/**
+ * k3_m4_rproc_mbox_callback() - inbound mailbox message handler
+ * @client: mailbox client pointer used for requesting the mailbox channel
+ * @data: mailbox payload
+ *
+ * This handler is invoked by the OMAP mailbox driver whenever a mailbox
+ * message is received. Usually, the mailbox payload simply contains
+ * the index of the virtqueue that is kicked by the remote processor,
+ * and we let remoteproc core handle it.
+ *
+ * In addition to virtqueue indices, we also have some out-of-band values
+ * that indicate different events. Those values are deliberately very
+ * large so they don't coincide with virtqueue indices.
+ */
+static void k3_m4_rproc_mbox_callback(struct mbox_client *client, void *data)
+{
+	struct k3_m4_rproc *kproc = container_of(client, struct k3_m4_rproc,
+						  client);
+	struct device *dev = kproc->rproc->dev.parent;
+	const char *name = kproc->rproc->name;
+	u32 msg = omap_mbox_message(data);
+
+	dev_dbg(dev, "mbox msg: 0x%x\n", msg);
+
+	switch (msg) {
+	case RP_MBOX_CRASH:
+		/*
+		 * remoteproc detected an exception, but error recovery is not
+		 * supported. So, just log this for now
+		 */
+		dev_err(dev, "K3 M4 rproc %s crashed\n", name);
+		break;
+	case RP_MBOX_ECHO_REPLY:
+		dev_info(dev, "received echo reply from %s\n", name);
+		break;
+	default:
+		/* silently handle all other valid messages */
+		if (msg >= RP_MBOX_READY && msg < RP_MBOX_END_MSG)
+			return;
+		if (msg > kproc->rproc->max_notifyid) {
+			dev_dbg(dev, "dropping unknown message 0x%x", msg);
+			return;
+		}
+		/* msg contains the index of the triggered vring */
+		if (rproc_vq_interrupt(kproc->rproc, msg) == IRQ_NONE)
+			dev_dbg(dev, "no message was found in vqid %d\n", msg);
+	}
+}
+
+/*
+ * Kick the remote processor to notify about pending unprocessed messages.
+ * The vqid usage is not used and is inconsequential, as the kick is performed
+ * through a simulated GPIO (a bit in an IPC interrupt-triggering register),
+ * the remote processor is expected to process both its Tx and Rx virtqueues.
+ */
+static void k3_m4_rproc_kick(struct rproc *rproc, int vqid)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = rproc->dev.parent;
+	mbox_msg_t msg = (mbox_msg_t)vqid;
+	int ret;
+
+	/* send the index of the triggered virtqueue in the mailbox payload */
+	ret = mbox_send_message(kproc->mbox, (void *)msg);
+	if (ret < 0)
+		dev_err(dev, "failed to send mailbox message, status = %d\n",
+			ret);
+}
+
+/* Put the M4 processor into reset */
+static int k3_m4_rproc_reset(struct k3_m4_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	int ret;
+
+	ret = reset_control_assert(kproc->reset);
+	if (ret) {
+		dev_err(dev, "local-reset assert failed, ret = %d\n", ret);
+		return ret;
+	}
+
+	if (kproc->data->uses_lreset)
+		return ret;
+
+	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "module-reset assert failed, ret = %d\n", ret);
+		if (reset_control_deassert(kproc->reset))
+			dev_warn(dev, "local-reset deassert back failed\n");
+	}
+
+	return ret;
+}
+
+/* Release the M4 processor from reset */
+static int k3_m4_rproc_release(struct k3_m4_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	int ret;
+
+	if (kproc->data->uses_lreset)
+		goto lreset;
+
+	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "module-reset deassert failed, ret = %d\n", ret);
+		return ret;
+	}
+
+	dev_info(dev, "released m4 reset\n");
+
+lreset:
+	ret = reset_control_deassert(kproc->reset);
+	if (ret) {
+		dev_err(dev, "local-reset deassert failed, ret = %d\n", ret);
+		if (kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+							  kproc->ti_sci_id))
+			dev_warn(dev, "module-reset assert back failed\n");
+	}
+
+	return ret;
+}
+
+static int k3_m4_rproc_request_mbox(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct mbox_client *client = &kproc->client;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	client->dev = dev;
+	client->tx_done = NULL;
+	client->rx_callback = k3_m4_rproc_mbox_callback;
+	client->tx_block = false;
+	client->knows_txdone = false;
+
+	kproc->mbox = mbox_request_channel(client, 0);
+	if (IS_ERR(kproc->mbox)) {
+		ret = -EBUSY;
+		dev_err(dev, "mbox_request_channel failed: %ld\n",
+			PTR_ERR(kproc->mbox));
+		return ret;
+	}
+
+	/*
+	 * Ping the remote processor, this is only for sanity-sake for now;
+	 * there is no functional effect whatsoever.
+	 *
+	 * Note that the reply will _not_ arrive immediately: this message
+	 * will wait in the mailbox fifo until the remote processor is booted.
+	 */
+	ret = mbox_send_message(kproc->mbox, (void *)RP_MBOX_ECHO_REQUEST);
+	if (ret < 0) {
+		dev_err(dev, "mbox_send_message failed: %d\n", ret);
+		mbox_free_channel(kproc->mbox);
+		return ret;
+	}
+
+	return 0;
+}
+
+/*
+ * The M4F cores have a local reset that affects only the CPU, and a
+ * generic module reset that powers on the device and allows the M4 internal
+ * memories to be accessed while the local reset is asserted. This function is
+ * used to release the global reset on M4F to allow loading into the M4F
+ * internal RAMs. The .prepare() ops is invoked by remoteproc core before any
+ * firmware loading, and is followed by the .start() ops after loading to
+ * actually let the M4F core run.
+ */
+static int k3_m4_rproc_prepare(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	/* IPC-only mode does not require the core to be released from reset */
+	if (kproc->ipc_only)
+		return 0;
+
+	ret = kproc->ti_sci->ops.dev_ops.get_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret)
+		dev_err(dev, "module-reset deassert failed, cannot enable internal RAM loading, ret = %d\n",
+			ret);
+
+	return ret;
+}
+
+/*
+ * This function implements the .unprepare() ops and performs the complimentary
+ * operations to that of the .prepare() ops. The function is used to assert the
+ * global reset on applicable M4F cores. This completes the second portion of
+ * powering down the M4F cores. The cores themselves are only halted in the
+ * .stop() callback through the local reset, and the .unprepare() ops is invoked
+ * by the remoteproc core after the remoteproc is stopped to balance the global
+ * reset.
+ */
+static int k3_m4_rproc_unprepare(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	/* do not put back the cores into reset in IPC-only mode */
+	if (kproc->ipc_only)
+		return 0;
+
+	ret = kproc->ti_sci->ops.dev_ops.put_device(kproc->ti_sci,
+						    kproc->ti_sci_id);
+	if (ret)
+		dev_err(dev, "module-reset assert failed, ret = %d\n", ret);
+
+	return ret;
+}
+
+/*
+ * Power up the M4F remote processor.
+ *
+ * This function will be invoked only after the firmware for this rproc
+ * was loaded, parsed successfully, and all of its resource requirements
+ * were met.
+ */
+static int k3_m4_rproc_start(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	u32 boot_addr;
+	int ret;
+
+	if (kproc->ipc_only) {
+		dev_err(dev, "%s cannot be invoked in IPC-only mode\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	ret = k3_m4_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	boot_addr = rproc->bootaddr;
+	ret = k3_m4_rproc_release(kproc);
+	if (ret)
+		goto put_mbox;
+
+	return 0;
+
+put_mbox:
+	mbox_free_channel(kproc->mbox);
+	return ret;
+}
+
+/*
+ * Stop the M4 remote processor.
+ *
+ * This function puts the M4 processor into reset, and finishes processing
+ * of any pending messages.
+ */
+static int k3_m4_rproc_stop(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	if (kproc->ipc_only) {
+		dev_err(dev, "%s cannot be invoked in IPC-only mode\n",
+			__func__);
+		return -EINVAL;
+	}
+
+	mbox_free_channel(kproc->mbox);
+
+	k3_m4_rproc_reset(kproc);
+
+	return 0;
+}
+
+/*
+ * Attach to a running M4 remote processor (IPC-only mode)
+ *
+ * This rproc attach callback only needs to request the mailbox, the remote
+ * processor is already booted, so there is no need to issue any TI-SCI
+ * commands to boot the M4 core.
+ */
+static int k3_m4_rproc_attach(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+	int ret;
+
+	if (!kproc->ipc_only || rproc->state != RPROC_DETACHED) {
+		dev_err(dev, "M4 is expected to be in IPC-only mode and RPROC_DETACHED state\n");
+		return -EINVAL;
+	}
+
+	ret = k3_m4_rproc_request_mbox(rproc);
+	if (ret)
+		return ret;
+
+	dev_err(dev, "M4 initialized in IPC-only mode\n");
+	return 0;
+}
+
+/*
+ * Detach from a running M4 remote processor (IPC-only mode)
+ *
+ * This rproc detach callback performs the opposite operation to attach callback
+ * and only needs to release the mailbox, the M4 core is not stopped and will
+ * be left to continue to run its booted firmware.
+ */
+static int k3_m4_rproc_detach(struct rproc *rproc)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	if (!kproc->ipc_only || rproc->state != RPROC_ATTACHED) {
+		dev_err(dev, "M4 is expected to be in IPC-only mode and RPROC_ATTACHED state\n");
+		return -EINVAL;
+	}
+
+	mbox_free_channel(kproc->mbox);
+	dev_err(dev, "M4 deinitialized in IPC-only mode\n");
+	return 0;
+}
+
+/*
+ * This function implements the .get_loaded_rsc_table() callback and is used
+ * to provide the resource table for a booted M4 in IPC-only mode. The K3 M4
+ * firmwares follow a design-by-contract approach and are expected to have the
+ * resource table at the base of the DDR region reserved for firmware usage.
+ * This provides flexibility for the remote processor to be booted by different
+ * bootloaders that may or may not have the ability to publish the resource table
+ * address and size through a DT property.
+ */
+static struct resource_table *k3_m4_get_loaded_rsc_table(struct rproc *rproc,
+							 size_t *rsc_table_sz)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	struct device *dev = kproc->dev;
+
+	if (!kproc->rmem[0].cpu_addr) {
+		dev_err(dev, "memory-region #1 does not exist, loaded rsc table can't be found");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/*
+	 * NOTE: The resource table size is currently hard-coded to a maximum
+	 * of 256 bytes. The most common resource table usage for K3 firmwares
+	 * is to only have the vdev resource entry and an optional trace entry.
+	 * The exact size could be computed based on resource table address, but
+	 * the hard-coded value suffices to support the IPC-only mode.
+	 */
+	*rsc_table_sz = 256;
+	return (struct resource_table *)kproc->rmem[0].cpu_addr;
+}
+
+/*
+ * Custom function to translate a M4 device address (internal RAMs only) to a
+ * kernel virtual address.  The M4s can access their RAMs at either an internal
+ * address visible only from a M4, or at the SoC-level bus address. Both these
+ * addresses need to be looked through for translation. The translated addresses
+ * can be used either by the remoteproc core for loading (when using kernel
+ * remoteproc loader), or by any rpmsg bus drivers.
+ */
+static void *k3_m4_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
+{
+	struct k3_m4_rproc *kproc = rproc->priv;
+	void __iomem *va = NULL;
+	phys_addr_t bus_addr;
+	u32 dev_addr, offset;
+	size_t size;
+	int i;
+
+	if (len == 0)
+		return NULL;
+
+	for (i = 0; i < kproc->num_mems; i++) {
+		bus_addr = kproc->mem[i].bus_addr;
+		dev_addr = kproc->mem[i].dev_addr;
+		size = kproc->mem[i].size;
+
+		if (da < KEYSTONE_RPROC_LOCAL_ADDRESS_MASK) {
+			/* handle M4-view addresses */
+			if (da >= dev_addr &&
+			    ((da + len) <= (dev_addr + size))) {
+				offset = da - dev_addr;
+				va = kproc->mem[i].cpu_addr + offset;
+				return (__force void *)va;
+			}
+		} else {
+			/* handle SoC-view addresses */
+			if (da >= bus_addr &&
+			    (da + len) <= (bus_addr + size)) {
+				offset = da - bus_addr;
+				va = kproc->mem[i].cpu_addr + offset;
+				return (__force void *)va;
+			}
+		}
+	}
+
+	/* handle static DDR reserved memory regions */
+	for (i = 0; i < kproc->num_rmems; i++) {
+		dev_addr = kproc->rmem[i].dev_addr;
+		size = kproc->rmem[i].size;
+
+		if (da >= dev_addr && ((da + len) <= (dev_addr + size))) {
+			offset = da - dev_addr;
+			va = kproc->rmem[i].cpu_addr + offset;
+			return (__force void *)va;
+		}
+	}
+
+	return NULL;
+}
+
+static const struct rproc_ops k3_m4_rproc_ops = {
+	.start		= k3_m4_rproc_start,
+	.stop		= k3_m4_rproc_stop,
+	.attach		= k3_m4_rproc_attach,
+	.detach		= k3_m4_rproc_detach,
+	.kick		= k3_m4_rproc_kick,
+	.da_to_va	= k3_m4_rproc_da_to_va,
+	.get_loaded_rsc_table = k3_m4_get_loaded_rsc_table,
+};
+
+static int k3_m4_rproc_of_get_memories(struct platform_device *pdev,
+				       struct k3_m4_rproc *kproc)
+{
+	const struct k3_m4_dev_data *data = kproc->data;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int num_mems = 0;
+	int i;
+
+	num_mems = kproc->data->num_mems;
+	kproc->mem = devm_kcalloc(kproc->dev, num_mems,
+				  sizeof(*kproc->mem), GFP_KERNEL);
+	if (!kproc->mem)
+		return -ENOMEM;
+
+	for (i = 0; i < num_mems; i++) {
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						   data->mems[i].name);
+		if (!res) {
+			dev_err(dev, "found no memory resource for %s\n",
+				data->mems[i].name);
+			return -EINVAL;
+		}
+		if (!devm_request_mem_region(dev, res->start,
+					     resource_size(res),
+					     dev_name(dev))) {
+			dev_err(dev, "could not request %s region for resource\n",
+				data->mems[i].name);
+			return -EBUSY;
+		}
+
+		kproc->mem[i].cpu_addr = devm_ioremap_wc(dev, res->start,
+							 resource_size(res));
+		if (!kproc->mem[i].cpu_addr) {
+			dev_err(dev, "failed to map %s memory\n",
+				data->mems[i].name);
+			return -ENOMEM;
+		}
+		kproc->mem[i].bus_addr = res->start;
+		kproc->mem[i].dev_addr = data->mems[i].dev_addr;
+		kproc->mem[i].size = resource_size(res);
+
+		dev_dbg(dev, "memory %8s: bus addr %pa size 0x%zx va %pK da 0x%x\n",
+			data->mems[i].name, &kproc->mem[i].bus_addr,
+			kproc->mem[i].size, kproc->mem[i].cpu_addr,
+			kproc->mem[i].dev_addr);
+	}
+	kproc->num_mems = num_mems;
+
+	return 0;
+}
+
+static int k3_m4_reserved_mem_init(struct k3_m4_rproc *kproc)
+{
+	struct device *dev = kproc->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *rmem_np;
+	struct reserved_mem *rmem;
+	int num_rmems;
+	int ret, i;
+
+	num_rmems = of_property_count_elems_of_size(np, "memory-region",
+						    sizeof(phandle));
+	if (num_rmems <= 0) {
+		dev_err(dev, "device does not reserved memory regions, ret = %d\n",
+			num_rmems);
+		return -EINVAL;
+	}
+	if (num_rmems < 2) {
+		dev_err(dev, "device needs at least two memory regions to be defined, num = %d\n",
+			num_rmems);
+		return -EINVAL;
+	}
+
+	/* use reserved memory region 0 for vring DMA allocations */
+	ret = of_reserved_mem_device_init_by_idx(dev, np, 0);
+	if (ret) {
+		dev_err(dev, "device cannot initialize DMA pool, ret = %d\n",
+			ret);
+		return ret;
+	}
+
+	num_rmems--;
+	kproc->rmem = kcalloc(num_rmems, sizeof(*kproc->rmem), GFP_KERNEL);
+	if (!kproc->rmem) {
+		ret = -ENOMEM;
+		goto release_rmem;
+	}
+
+	/* use remaining reserved memory regions for static carveouts */
+	for (i = 0; i < num_rmems; i++) {
+		rmem_np = of_parse_phandle(np, "memory-region", i + 1);
+		if (!rmem_np) {
+			ret = -EINVAL;
+			goto unmap_rmem;
+		}
+
+		rmem = of_reserved_mem_lookup(rmem_np);
+		if (!rmem) {
+			of_node_put(rmem_np);
+			ret = -EINVAL;
+			goto unmap_rmem;
+		}
+		of_node_put(rmem_np);
+
+		kproc->rmem[i].bus_addr = rmem->base;
+		/* 64-bit address regions currently not supported */
+		kproc->rmem[i].dev_addr = (u32)rmem->base;
+		kproc->rmem[i].size = rmem->size;
+		kproc->rmem[i].cpu_addr = ioremap_wc(rmem->base, rmem->size);
+		if (!kproc->rmem[i].cpu_addr) {
+			dev_err(dev, "failed to map reserved memory#%d at %pa of size %pa\n",
+				i + 1, &rmem->base, &rmem->size);
+			ret = -ENOMEM;
+			goto unmap_rmem;
+		}
+
+		dev_dbg(dev, "reserved memory%d: bus addr %pa size 0x%zx va %pK da 0x%x\n",
+			i + 1, &kproc->rmem[i].bus_addr,
+			kproc->rmem[i].size, kproc->rmem[i].cpu_addr,
+			kproc->rmem[i].dev_addr);
+	}
+	kproc->num_rmems = num_rmems;
+
+	return 0;
+
+unmap_rmem:
+	for (i--; i >= 0; i--)
+		iounmap(kproc->rmem[i].cpu_addr);
+	kfree(kproc->rmem);
+release_rmem:
+	of_reserved_mem_device_release(kproc->dev);
+	return ret;
+}
+
+static void k3_m4_reserved_mem_exit(struct k3_m4_rproc *kproc)
+{
+	int i;
+
+	for (i = 0; i < kproc->num_rmems; i++)
+		iounmap(kproc->rmem[i].cpu_addr);
+	kfree(kproc->rmem);
+
+	of_reserved_mem_device_release(kproc->dev);
+}
+
+static struct ti_sci_proc *k3_m4_rproc_of_get_tsp(struct device *dev,
+						  const struct ti_sci_handle *sci)
+{
+	struct ti_sci_proc *tsp;
+	u32 temp[2];
+	int ret;
+
+	ret = of_property_read_u32_array(dev->of_node, "ti,sci-proc-ids",
+					 temp, 2);
+	if (ret < 0)
+		return ERR_PTR(ret);
+
+	tsp = kzalloc(sizeof(*tsp), GFP_KERNEL);
+	if (!tsp)
+		return ERR_PTR(-ENOMEM);
+
+	tsp->dev = dev;
+	tsp->sci = sci;
+	tsp->ops = &sci->ops.proc_ops;
+	tsp->proc_id = temp[0];
+	tsp->host_id = temp[1];
+
+	return tsp;
+}
+
+static int k3_m4_rproc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	const struct k3_m4_dev_data *data;
+	struct k3_m4_rproc *kproc;
+	struct rproc *rproc;
+	const char *fw_name;
+	bool r_state = false;
+	bool p_state = false;
+	int ret = 0;
+	int ret1;
+
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
+	ret = rproc_of_parse_firmware(dev, 0, &fw_name);
+	if (ret) {
+		dev_err(dev, "failed to parse firmware-name property, ret = %d\n",
+			ret);
+		return ret;
+	}
+
+	rproc = rproc_alloc(dev, dev_name(dev), &k3_m4_rproc_ops, fw_name,
+			    sizeof(*kproc));
+	if (!rproc)
+		return -ENOMEM;
+
+	rproc->has_iommu = false;
+	rproc->recovery_disabled = true;
+	if (data->uses_lreset) {
+		rproc->ops->prepare = k3_m4_rproc_prepare;
+		rproc->ops->unprepare = k3_m4_rproc_unprepare;
+	}
+	kproc = rproc->priv;
+	kproc->rproc = rproc;
+	kproc->dev = dev;
+	kproc->data = data;
+
+	kproc->ti_sci = ti_sci_get_by_phandle(np, "ti,sci");
+	if (IS_ERR(kproc->ti_sci)) {
+		ret = PTR_ERR(kproc->ti_sci);
+		if (ret != -EPROBE_DEFER) {
+			dev_err(dev, "failed to get ti-sci handle, ret = %d\n",
+				ret);
+		}
+		kproc->ti_sci = NULL;
+		goto free_rproc;
+	}
+
+	ret = of_property_read_u32(np, "ti,sci-dev-id", &kproc->ti_sci_id);
+	if (ret) {
+		dev_err(dev, "missing 'ti,sci-dev-id' property\n");
+		goto put_sci;
+	}
+
+	kproc->reset = devm_reset_control_get_exclusive(dev, NULL);
+	if (IS_ERR(kproc->reset)) {
+		ret = PTR_ERR(kproc->reset);
+		dev_err(dev, "failed to get reset, status = %d\n", ret);
+		goto put_sci;
+	}
+
+	kproc->tsp = k3_m4_rproc_of_get_tsp(dev, kproc->ti_sci);
+	if (IS_ERR(kproc->tsp)) {
+		dev_err(dev, "failed to construct ti-sci proc control, ret = %d\n",
+			ret);
+		ret = PTR_ERR(kproc->tsp);
+		goto put_sci;
+	}
+
+	ret = ti_sci_proc_request(kproc->tsp);
+	if (ret < 0) {
+		dev_err(dev, "ti_sci_proc_request failed, ret = %d\n", ret);
+		goto free_tsp;
+	}
+
+	ret = k3_m4_rproc_of_get_memories(pdev, kproc);
+	if (ret)
+		goto release_tsp;
+
+	ret = k3_m4_reserved_mem_init(kproc);
+	if (ret) {
+		dev_err(dev, "reserved memory init failed, ret = %d\n", ret);
+		goto release_tsp;
+	}
+
+	ret = kproc->ti_sci->ops.dev_ops.is_on(kproc->ti_sci, kproc->ti_sci_id,
+					       &r_state, &p_state);
+	if (ret) {
+		dev_err(dev, "failed to get initial state, mode cannot be determined, ret = %d\n",
+			ret);
+		goto release_mem;
+	}
+
+	/* configure devices for either remoteproc or IPC-only mode */
+	if (p_state) {
+		dev_err(dev, "configured M4 for IPC-only mode\n");
+		rproc->state = RPROC_DETACHED;
+		kproc->ipc_only = true;
+	} else {
+		dev_err(dev, "configured M4 for remoteproc mode\n");
+		/*
+		 * ensure the M4 local reset is asserted to ensure the core
+		 * doesn't execute bogus code in .prepare() when the module
+		 * reset is released.
+		 */
+		if (data->uses_lreset) {
+			ret = reset_control_status(kproc->reset);
+			if (ret < 0) {
+				dev_err(dev, "failed to get reset status, status = %d\n",
+					ret);
+				goto release_mem;
+			} else if (ret == 0) {
+				dev_warn(dev, "local reset is deasserted for device\n");
+				k3_m4_rproc_reset(kproc);
+			}
+		}
+	}
+
+	ret = rproc_add(rproc);
+	if (ret) {
+		dev_err(dev, "failed to add register device with remoteproc core, status = %d\n",
+			ret);
+		goto release_mem;
+	}
+
+	platform_set_drvdata(pdev, kproc);
+
+	return 0;
+
+release_mem:
+	k3_m4_reserved_mem_exit(kproc);
+release_tsp:
+	ret1 = ti_sci_proc_release(kproc->tsp);
+	if (ret1)
+		dev_err(dev, "failed to release proc, ret = %d\n", ret1);
+free_tsp:
+	kfree(kproc->tsp);
+put_sci:
+	ret1 = ti_sci_put_handle(kproc->ti_sci);
+	if (ret1)
+		dev_err(dev, "failed to put ti_sci handle, ret = %d\n", ret1);
+free_rproc:
+	rproc_free(rproc);
+	return ret;
+}
+
+static int k3_m4_rproc_remove(struct platform_device *pdev)
+{
+	struct k3_m4_rproc *kproc = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	rproc_del(kproc->rproc);
+
+	ret = ti_sci_proc_release(kproc->tsp);
+	if (ret)
+		dev_err(dev, "failed to release proc, ret = %d\n", ret);
+
+	kfree(kproc->tsp);
+
+	ret = ti_sci_put_handle(kproc->ti_sci);
+	if (ret)
+		dev_err(dev, "failed to put ti_sci handle, ret = %d\n", ret);
+
+	k3_m4_reserved_mem_exit(kproc);
+	rproc_free(kproc->rproc);
+
+	return 0;
+}
+
+static const struct k3_m4_mem_data am64_m4_mems[] = {
+	{ .name = "iram", .dev_addr = 0x0 },
+	{ .name = "dram", .dev_addr = 0x30000 },
+};
+
+static const struct k3_m4_dev_data am64_m4_data = {
+	.mems = am64_m4_mems,
+	.num_mems = ARRAY_SIZE(am64_m4_mems),
+	.boot_align_addr = SZ_1K,
+	.uses_lreset = true,
+};
+
+static const struct of_device_id k3_m4_of_match[] = {
+	{ .compatible = "ti,am64-m4fss", .data = &am64_m4_data, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, k3_m4_of_match);
+
+static struct platform_driver k3_m4_rproc_driver = {
+	.probe	= k3_m4_rproc_probe,
+	.remove	= k3_m4_rproc_remove,
+	.driver	= {
+		.name = "k3-m4-rproc",
+		.of_match_table = k3_m4_of_match,
+	},
+};
+
+module_platform_driver(k3_m4_rproc_driver);
+
+MODULE_AUTHOR("Hari Nagalla <hnagalla at ti.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI K3 M4 Remoteproc driver");
-- 
2.17.1



From yuzhao at google.com  Sun Jan  9 20:47:57 2022
From: yuzhao at google.com (Yu Zhao)
Date: Sun, 9 Jan 2022 21:47:57 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdhR4vWdWksBALtM@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz>
Message-ID: <Ydu6fXg2FmrseQOn@google.com>

On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> [...]
> > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > +{
> > +	static const struct mm_walk_ops mm_walk_ops = {
> > +		.test_walk = should_skip_vma,
> > +		.p4d_entry = walk_pud_range,
> > +	};
> > +
> > +	int err;
> > +#ifdef CONFIG_MEMCG
> > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > +#endif
> > +
> > +	walk->next_addr = FIRST_USER_ADDRESS;
> > +
> > +	do {
> > +		unsigned long start = walk->next_addr;
> > +		unsigned long end = mm->highest_vm_end;
> > +
> > +		err = -EBUSY;
> > +
> > +		rcu_read_lock();
> > +#ifdef CONFIG_MEMCG
> > +		if (memcg && atomic_read(&memcg->moving_account))
> > +			goto contended;
> > +#endif
> > +		if (!mmap_read_trylock(mm))
> > +			goto contended;
> 
> Have you evaluated the behavior under mmap_sem contention? I mean what
> would be an effect of some mms being excluded from the walk? This path
> is called from direct reclaim and we do allocate with exclusive mmap_sem
> IIRC and the trylock can fail in a presence of pending writer if I am
> not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> can bypass the walk.

You are right. Here it must be a trylock; otherwise it can deadlock.

I think there might be a misunderstanding: the aging doesn't
exclusively rely on page table walks to gather the accessed bit. It
prefers page table walks but it can also fallback to the rmap-based
function, i.e., lru_gen_look_around(), which only gathers the accessed
bit from at most 64 PTEs and therefore is less efficient. But it still
retains about 80% of the performance gains.

> Or is this considered statistically insignificant thus a theoretical
> problem?

Yes. People who work on the maple tree and SPF at Google expressed the
same concern during the design review meeting (all stakeholders on the
mailing list were also invited). So we had a counter to monitor the
contention in previous versions, i.e., MM_LOCK_CONTENTION in v4 here:
https://lore.kernel.org/lkml/20210818063107.2696454-8-yuzhao at google.com/

And we also combined this patchset with the SPF patchset to see if the
latter makes any difference. Our conclusion was the contention is
statistically insignificant to the performance under memory pressure.

This can be explained by how often we create a new generation. (We
only walk page tables when we create a new generation. And it's
similar to the low inactive condition for the active/inactive lru.)

Usually we only do so every few seconds. We'd run into problems with
other parts of the kernel, e.g., lru lock contention, i/o congestion,
etc. if we create more than a few generation every second.


From leilk.liu at mediatek.com  Sun Jan  9 21:37:44 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 10 Jan 2022 13:37:44 +0800
Subject: [PATCH 2/2] dt-bindings: spi: Add compatible for Mediatek MT8186
In-Reply-To: <20220110053744.30323-1-leilk.liu@mediatek.com>
References: <20220110053744.30323-1-leilk.liu@mediatek.com>
Message-ID: <20220110053744.30323-2-leilk.liu@mediatek.com>

This commit adds dt-binding documentation of spi bus for Mediatek MT8186 SoC
Platform.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
index cfa36977eea1..83f02528b802 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -26,6 +26,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt6779-spi
+              - mediatek,mt8186-spi
               - mediatek,mt8192-spi
               - mediatek,mt8195-spi
           - const: mediatek,mt6765-spi
-- 
2.25.1



From leilk.liu at mediatek.com  Sun Jan  9 21:37:43 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 10 Jan 2022 13:37:43 +0800
Subject: [PATCH 1/2] dt-bindings: spi: Convert spi-mt65xx & spi-slave-mt27xx
 to json-schema
Message-ID: <20220110053744.30323-1-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Master & Slave controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 96 +++++++++++++++++++
 .../spi/mediatek,spi-slave-mt27xx.yaml        | 69 +++++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
 .../bindings/spi/spi-slave-mt27xx.txt         | 33 -------
 4 files changed, 165 insertions(+), 101 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
new file mode 100644
index 000000000000..cfa36977eea1
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Bus controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: /spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt7629-spi
+          - const: mediatek,mt7622-spi
+      - items:
+          - enum:
+              - mediatek,mt8516-spi
+          - const: mediatek,mt2712-spi
+      - items:
+          - enum:
+              - mediatek,mt6779-spi
+              - mediatek,mt8192-spi
+              - mediatek,mt8195-spi
+          - const: mediatek,mt6765-spi
+      - const: mediatek,mt2701-spi
+      - const: mediatek,mt6589-spi
+      - const: mediatek,mt6893-spi
+      - const: mediatek,mt8135-spi
+      - const: mediatek,mt8173-spi
+      - const: mediatek,mt8183-spi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the parent clock
+      - description: clock used for the muxes clock
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: parent-clk
+      - const: sel-clk
+      - const: spi-clk
+
+  mediatek,pad-select:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    maxItems: 4
+    items:
+      enum: [0, 1, 2, 3]
+    description:
+      specify which pins group(ck/mi/mo/cs) spi controller used.
+      This is an array.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 1100a000 {
+      compatible = "mediatek,mt8173-spi";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      reg = <0x1100a000 0x1000>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+               <&topckgen CLK_TOP_SPI_SEL>,
+               <&pericfg CLK_PERI_SPI0>;
+      clock-names = "parent-clk", "sel-clk", "spi-clk";
+      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
+      mediatek,pad-select = <1>, <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
new file mode 100644
index 000000000000..783b16c52928
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Slave controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: /spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - const: mediatek,mt2712-spi-slave
+      - const: mediatek,mt8195-spi-slave
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: spi
+
+  assigned-clocks:
+    maxItems: 1
+    description: |
+      The mux clock for the given platform.
+
+  assigned-clock-parents:
+    maxItems: 1
+    description: |
+      The parent of mux clock for the given platform.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2712-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 10013000 {
+      compatible = "mediatek,mt2712-spi-slave";
+      reg = <0x10013000 0x100>;
+      interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&infracfg CLK_INFRA_AO_SPI1>;
+      clock-names = "spi";
+      assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
deleted file mode 100644
index 2a24969159cc..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Binding for MTK SPI controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2701-spi: for mt2701 platforms
-    - mediatek,mt2712-spi: for mt2712 platforms
-    - mediatek,mt6589-spi: for mt6589 platforms
-    - mediatek,mt6765-spi: for mt6765 platforms
-    - mediatek,mt7622-spi: for mt7622 platforms
-    - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
-    - mediatek,mt8135-spi: for mt8135 platforms
-    - mediatek,mt8173-spi: for mt8173 platforms
-    - mediatek,mt8183-spi: for mt8183 platforms
-    - mediatek,mt6893-spi: for mt6893 platforms
-    - "mediatek,mt8192-spi", "mediatek,mt6765-spi": for mt8192 platforms
-    - "mediatek,mt8195-spi", "mediatek,mt6765-spi": for mt8195 platforms
-    - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
-    - "mediatek,mt6779-spi", "mediatek,mt6765-spi": for mt6779 platforms
-
-- #address-cells: should be 1.
-
-- #size-cells: should be 0.
-
-- reg: Address and length of the register set for the device
-
-- interrupts: Should contain spi interrupt
-
-- clocks: phandles to input clocks.
-  The first should be one of the following. It's PLL.
-   -  <&clk26m>: specify parent clock 26MHZ.
-   -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
-				      It's the default one.
-   -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
-  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
-
-- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
-  muxes clock, and "spi-clk" for the clock gate.
-
-Optional properties:
--cs-gpios: see spi-bus.txt.
-
-- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
-  controller used. This is an array, the element value should be 0~3,
-  only required for MT8173.
-    0: specify GPIO69,70,71,72 for spi pins.
-    1: specify GPIO102,103,104,105 for spi pins.
-    2: specify GPIO128,129,130,131 for spi pins.
-    3: specify GPIO5,6,7,8 for spi pins.
-
-Example:
-
-- SoC Specific Portion:
-spi: spi at 1100a000 {
-	compatible = "mediatek,mt8173-spi";
-	#address-cells = <1>;
-	#size-cells = <0>;
-	reg = <0 0x1100a000 0 0x1000>;
-	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
-		 <&topckgen CLK_TOP_SPI_SEL>,
-		 <&pericfg CLK_PERI_SPI0>;
-	clock-names = "parent-clk", "sel-clk", "spi-clk";
-	cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
-	mediatek,pad-select = <1>, <0>;
-};
diff --git a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt b/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
deleted file mode 100644
index 9192724540fd..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Binding for MTK SPI Slave controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2712-spi-slave: for mt2712 platforms
-    - mediatek,mt8195-spi-slave: for mt8195 platforms
-- reg: Address and length of the register set for the device.
-- interrupts: Should contain spi interrupt.
-- clocks: phandles to input clocks.
-  It's clock gate, and should be <&infracfg CLK_INFRA_AO_SPI1>.
-- clock-names: should be "spi" for the clock gate.
-
-Optional properties:
-- assigned-clocks: it's mux clock, should be <&topckgen CLK_TOP_SPISLV_SEL>.
-- assigned-clock-parents: parent of mux clock.
-  It's PLL, and should be one of the following.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D2>: specify parent clock 312MHZ.
-				       It's the default one.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D4>: specify parent clock 156MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-
-Example:
-- SoC Specific Portion:
-spis1: spi at 10013000 {
-	compatible = "mediatek,mt2712-spi-slave";
-	reg = <0 0x10013000 0 0x100>;
-	interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&infracfg CLK_INFRA_AO_SPI1>;
-	clock-names = "spi";
-	assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
-	assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
-};
-- 
2.25.1



From reijiw at google.com  Sun Jan  9 21:40:41 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Sun,  9 Jan 2022 21:40:41 -0800
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
Message-ID: <20220110054042.1079932-1-reijiw@google.com>

vcpu_allowed_register_width() checks if all the VCPUs are either
all 32bit or all 64bit.  Since the checking is done even for vCPUs
that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
the non-initialized vCPUs are erroneously treated as 64bit vCPU,
which causes the function to incorrectly detect a mixed-width VM.

Fix vcpu_allowed_register_width() to skip the check for vCPUs that
are not initialized yet.

Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/kvm/reset.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 426bd7fbc3fd..ef78bbc7566a 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 	if (kvm_has_mte(vcpu->kvm) && is32bit)
 		return false;
 
+	/*
+	 * Make sure vcpu->arch.target setting is visible from others so
+	 * that the width consistency checking between two vCPUs is done
+	 * by at least one of them at KVM_ARM_VCPU_INIT.
+	 */
+	smp_mb();
+
 	/* Check that the vcpus are either all 32bit or all 64bit */
 	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
+		/* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
+		if (tmp->arch.target == -1)
+			continue;
+
 		if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit)
 			return false;
 	}

base-commit: df0cc57e057f18e44dac8e6c18aba47ab53202f9
-- 
2.34.1.575.g55b058a8bb-goog



From reijiw at google.com  Sun Jan  9 21:40:42 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Sun,  9 Jan 2022 21:40:42 -0800
Subject: [PATCH 2/2] KVM: arm64: selftests: Introduce vcpu_width_config
In-Reply-To: <20220110054042.1079932-1-reijiw@google.com>
References: <20220110054042.1079932-1-reijiw@google.com>
Message-ID: <20220110054042.1079932-2-reijiw@google.com>

Introduce a test for aarch64 that ensures non-mixed-width vCPUs
(all 64bit vCPUs or all 32bit vcPUs) can be configured, and
mixed-width vCPUs cannot be configured.

Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/aarch64/vcpu_width_config.c | 125 ++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/vcpu_width_config.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 3cb5ac5da087..8795a83cc382 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -3,6 +3,7 @@
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
 /aarch64/psci_cpu_on_test
+/aarch64/vcpu_width_config
 /aarch64/vgic_init
 /s390x/memop
 /s390x/resets
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 17342b575e85..259e01d0735a 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -95,6 +95,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
 TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test
+TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
 TEST_GEN_PROGS_aarch64 += demand_paging_test
 TEST_GEN_PROGS_aarch64 += dirty_log_test
diff --git a/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c b/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
new file mode 100644
index 000000000000..cd238e068236
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.
+ *
+ * Copyright (c) 2022 Google LLC.
+ *
+ * This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs
+ * or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be
+ * configured.
+ */
+
+#define _GNU_SOURCE
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+
+/*
+ * Add a vCPU, run KVM_ARM_VCPU_INIT with @init1, and then
+ * add another vCPU, and run KVM_ARM_VCPU_INIT with @init2.
+ */
+int add_init_2vcpus(struct kvm_vcpu_init *init1,
+			 struct kvm_vcpu_init *init2)
+{
+	struct kvm_vm *vm;
+	int ret;
+
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+
+	vm_vcpu_add(vm, 0);
+	ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
+	if (ret)
+		goto free_exit;
+
+	vm_vcpu_add(vm, 1);
+	ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
+
+free_exit:
+	kvm_vm_free(vm);
+	return ret;
+}
+
+/*
+ * Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init1,
+ * and run KVM_ARM_VCPU_INIT for another vCPU with @init2.
+ */
+int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init1,
+				struct kvm_vcpu_init *init2)
+{
+	struct kvm_vm *vm;
+	int ret;
+
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+
+	vm_vcpu_add(vm, 0);
+	vm_vcpu_add(vm, 1);
+
+	ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
+	if (ret)
+		goto free_exit;
+
+	ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
+
+free_exit:
+	kvm_vm_free(vm);
+	return ret;
+}
+
+/*
+ * Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
+ * configured, and two mixed-witgh vCPUs cannot be configured.
+ * Each of those three cases, configure vCPUs in two different orders.
+ * The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
+ * KVM_ARM_VCPU_INIT for them.
+ * The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
+ * and then run those commands for another vCPU.
+ */
+int main(void)
+{
+	struct kvm_vcpu_init init1, init2;
+	struct kvm_vm *vm;
+	int ret;
+
+	if (kvm_check_cap(KVM_CAP_ARM_EL1_32BIT) <= 0) {
+		print_skip("KVM_CAP_ARM_EL1_32BIT is not supported");
+		exit(KSFT_SKIP);
+	}
+
+	/* Get the preferred target type and copy that to init2 */
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+	vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init1);
+	kvm_vm_free(vm);
+	memcpy(&init2, &init1, sizeof(init2));
+
+	/* Test with 64bit vCPUs */
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
+
+	/* Test with 32bit vCPUs */
+	init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	init2.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
+
+	/* Test with mixed-width vCPUs  */
+	init1.features[0] = 0;
+	init2.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret != 0,
+		    "Configuring mixed-width vCPUs worked unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret != 0,
+		    "Configuring mixed-width vCPUs worked unexpectedly");
+
+	return 0;
+}
-- 
2.34.1.575.g55b058a8bb-goog



From irogers at google.com  Sun Jan  9 21:45:19 2022
From: irogers at google.com (Ian Rogers)
Date: Sun, 9 Jan 2022 21:45:19 -0800
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <Ydspzl2aWpufl/yR@krava>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
 <Ydspzl2aWpufl/yR@krava>
Message-ID: <CAP-5=fUQsd21cxFiXBi2pCh9rakMReiNWxbrKn+1CesCamrtdg@mail.gmail.com>

On Sun, Jan 9, 2022 at 10:30 AM Jiri Olsa <jolsa at redhat.com> wrote:
>
> On Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers wrote:
> > A common problem is confusing CPU map indices with the CPU, by wrapping
> > the CPU with a struct then this is avoided. This approach is similar to
> > atomic_t.
> >
> > Suggested-by: John Garry <john.garry at huawei.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>
>
> SNIP
>
> >  tools/perf/util/stat.h                        |   2 +-
> >  tools/perf/util/svghelper.c                   |   6 +-
> >  tools/perf/util/synthetic-events.c            |  12 +-
> >  tools/perf/util/synthetic-events.h            |   3 +-
> >  tools/perf/util/util.h                        |   5 +-
> >  59 files changed, 408 insertions(+), 347 deletions(-)
>
> that's massive ;-) did it find any mis-use of the index/value?

It did. The fixes precede this patch so that we can have the fixes
without the large rename.

> how about the same for threads?

Agreed, but the patch set was already big enough.

> > diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
> > index 71a31ed738c9..581f9ffb4237 100644
> > --- a/tools/lib/perf/include/internal/cpumap.h
> > +++ b/tools/lib/perf/include/internal/cpumap.h
> > @@ -4,6 +4,11 @@
> >
> >  #include <linux/refcount.h>
> >
> > +/** A wrapper around a CPU to avoid confusion with the perf_cpu_map's map's indices. */
> > +struct perf_cpu {
> > +     int cpu;
> > +};
>
> should we use 'int val' or 'int v' instead, so we don't have cpu.cpu ?

I can rename it if you have a preference.

Thanks,
Ian

> jirka
>
> SNIP
>


From irogers at google.com  Sun Jan  9 21:49:48 2022
From: irogers at google.com (Ian Rogers)
Date: Sun, 9 Jan 2022 21:49:48 -0800
Subject: [PATCH v4 26/48] perf evsel: Derive CPUs and threads in
 alloc_counts
In-Reply-To: <Ydsp1d58t/gp/GHd@krava>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-27-irogers@google.com>
 <Ydsp1d58t/gp/GHd@krava>
Message-ID: <CAP-5=fU77-qjcooX5B7qmimUoyNp-nXKNtnGQE9F6TH8Qsx+4A@mail.gmail.com>

On Sun, Jan 9, 2022 at 10:30 AM Jiri Olsa <jolsa at redhat.com> wrote:
>
> On Tue, Jan 04, 2022 at 10:13:29PM -0800, Ian Rogers wrote:
>
> SNIP
>
> > diff --git a/tools/perf/util/counts.h b/tools/perf/util/counts.h
> > index 7ff36bf6d644..3e275e9c60d1 100644
> > --- a/tools/perf/util/counts.h
> > +++ b/tools/perf/util/counts.h
> > @@ -40,7 +40,7 @@ void perf_counts__delete(struct perf_counts *counts);
> >  void perf_counts__reset(struct perf_counts *counts);
> >
> >  void evsel__reset_counts(struct evsel *evsel);
> > -int evsel__alloc_counts(struct evsel *evsel, int ncpus, int nthreads);
> > +int evsel__alloc_counts(struct evsel *evsel);
> >  void evsel__free_counts(struct evsel *evsel);
> >
> >  #endif /* __PERF_COUNTS_H */
> > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> > index 656c30b988ce..6c9af21776e6 100644
> > --- a/tools/perf/util/evsel.c
> > +++ b/tools/perf/util/evsel.c
> > @@ -1578,7 +1578,7 @@ int __evsel__read_on_cpu(struct evsel *evsel, int cpu, int thread, bool scale)
> >       if (FD(evsel, cpu, thread) < 0)
> >               return -EINVAL;
> >
> > -     if (evsel->counts == NULL && evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
> > +     if (evsel->counts == NULL && evsel__alloc_counts(evsel) < 0)
>
> ugh, nice.. good that it's used only from test code ;-)
>
> btw I noticed evsel__read_on_cpu_scaled is not used at all

I'd noticed that too, but wanted to stay away from making the patch
set larger.  You end up removing the argument to
__evsel__read_on_cpu, etc. Definitely worth cleaning up, but maybe we
can do it later.

Thanks,
Ian

> jirka
>
> >               return -ENOMEM;
> >
> >       if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) <= 0)
> > diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
> > index c69b221f5e3e..995cb5003133 100644
> > --- a/tools/perf/util/stat.c
> > +++ b/tools/perf/util/stat.c
> > @@ -152,11 +152,13 @@ static void evsel__free_stat_priv(struct evsel *evsel)
> >       zfree(&evsel->stats);
> >  }
> >
> > -static int evsel__alloc_prev_raw_counts(struct evsel *evsel, int ncpus, int nthreads)
> > +static int evsel__alloc_prev_raw_counts(struct evsel *evsel)
> >  {
> > +     int cpu_map_nr = evsel__nr_cpus(evsel);
> > +     int nthreads = perf_thread_map__nr(evsel->core.threads);
> >       struct perf_counts *counts;
> >
> > -     counts = perf_counts__new(ncpus, nthreads);
> > +     counts = perf_counts__new(cpu_map_nr, nthreads);
> >       if (counts)
> >               evsel->prev_raw_counts = counts;
> >
> > @@ -177,12 +179,9 @@ static void evsel__reset_prev_raw_counts(struct evsel *evsel)
> >
> >  static int evsel__alloc_stats(struct evsel *evsel, bool alloc_raw)
> >  {
> > -     int ncpus = evsel__nr_cpus(evsel);
> > -     int nthreads = perf_thread_map__nr(evsel->core.threads);
> > -
> >       if (evsel__alloc_stat_priv(evsel) < 0 ||
> > -         evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
> > -         (alloc_raw && evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
> > +         evsel__alloc_counts(evsel) < 0 ||
> > +         (alloc_raw && evsel__alloc_prev_raw_counts(evsel) < 0))
> >               return -ENOMEM;
> >
> >       return 0;
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
>


From reijiw at google.com  Sun Jan  9 22:28:49 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Sun, 9 Jan 2022 22:28:49 -0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <20220104194918.373612-5-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
Message-ID: <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>

Hi Raghu,

On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> KVM regularly introduces new hypercall services to the guests without
> any consent from the Virtual Machine Manager (VMM). This means, the
> guests can observe hypercall services in and out as they migrate
> across various host kernel versions. This could be a major problem
> if the guest discovered a hypercall, started using it, and after
> getting migrated to an older kernel realizes that it's no longer
> available. Depending on how the guest handles the change, there's
> a potential chance that the guest would just panic.
>
> As a result, there's a need for the VMM to elect the services that
> it wishes the guest to discover. VMM can elect these services based
> on the kernels spread across its (migration) fleet. To remedy this,
> extend the existing firmware psuedo-registers, such as
> KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.
>
> These firmware registers are categorized based on the service call
> owners, and unlike the existing firmware psuedo-registers, they hold
> the features supported in the form of a bitmap.
>
> The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
> this extension, which returns the number of psuedo-firmware
> registers supported. During the VM initialization, the registers
> holds an upper-limit of the features supported by the corresponding
> registers. It's expected that the VMMs discover the features
> provided by each register via GET_ONE_REG, and writeback the
> desired values using SET_ONE_REG. KVM allows this modification
> only until the VM has started.
>
> Older VMMs can simply ignore the capability and the hypercall services
> will be exposed unconditionally to the guests, thus ensuring backward
> compatibility.
>
> In this patch, the framework adds the register only for ARM's standard
> secure services (owner value 4). Currently, this includes support only
> for ARM True Random Number Generator (TRNG) service, with bit-0 of the
> register representing mandatory features of v1.0. Other services are
> momentarily added in the upcoming patches.
>
> Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |  12 ++++
>  arch/arm64/include/uapi/asm/kvm.h |   4 ++
>  arch/arm64/kvm/arm.c              |   4 ++
>  arch/arm64/kvm/hypercalls.c       | 103 +++++++++++++++++++++++++++++-
>  arch/arm64/kvm/trng.c             |   8 +--
>  include/kvm/arm_hypercalls.h      |   6 ++
>  6 files changed, 129 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2a5f7f38006f..a32cded0371b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -102,6 +102,15 @@ struct kvm_s2_mmu {
>  struct kvm_arch_memory_slot {
>  };
>
> +/**
> + * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
> + *
> + * @hvc_std_bmap: Bitmap of standard secure service calls
> + */
> +struct kvm_hvc_desc {
> +       u64 hvc_std_bmap;
> +};
> +
>  struct kvm_arch {
>         struct kvm_s2_mmu mmu;
>
> @@ -137,6 +146,9 @@ struct kvm_arch {
>
>         /* Memory Tagging Extension enabled for the guest */
>         bool mte_enabled;
> +
> +       /* Hypercall firmware register' descriptor */
> +       struct kvm_hvc_desc hvc_desc;
>  };
>
>  struct kvm_vcpu_fault_info {
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index b3edde68bc3e..0d6f29c58456 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -281,6 +281,10 @@ struct kvm_arm_copy_mte_tags {
>  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
>  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
>
> +#define KVM_REG_ARM_STD_BMAP                   KVM_REG_ARM_FW_REG(3)
> +#define KVM_REG_ARM_STD_BIT_TRNG_V1_0          BIT(0)
> +#define KVM_REG_ARM_STD_BMAP_BIT_MAX           0       /* Last valid bit */
> +
>  /* SVE registers */
>  #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
>
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e4727dc771bf..56fe81565235 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>         kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
>
>         set_default_spectre(kvm);
> +       kvm_arm_init_hypercalls(kvm);
>
>         return ret;
>  out_free_stage2_pgd:
> @@ -283,6 +284,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>         case KVM_CAP_ARM_PTRAUTH_GENERIC:
>                 r = system_has_full_ptr_auth();
>                 break;
> +       case KVM_CAP_ARM_HVC_FW_REG_BMAP:
> +               r = kvm_arm_num_fw_bmap_regs();
> +               break;

Looking at the discussion for the v2 series,

 https://lore.kernel.org/kvmarm/20211130101958.fcdqthphyhxzvzla at gator.home/

I assume that the number of the pseudo-firmware bitmap registers
will be used to clear pseudo firmware bitmap registers that
userspace doesn't know.
I'm wondering how userspace can identify which pseudo-firmware
registers that KVM_GET_REG_LIST provides are the pseudo-firmware
bitmap registers that it doesn't know.
For instance, suppose pseudo-firmware registers that KVM_GET_REG_LIST
provides are KVM_REG_ARM_FW_REG(0) to KVM_REG_ARM_FW_REG(9), userspace
doesn't knows KVM_REG_ARM_FW_REG(6) to KVM_REG_ARM_FW_REG(9), and
KVM_CAP_ARM_HVC_FW_REG_BMAP returns 5, how can userspace identify
remaining two bitmap registers from those 4 (fw-reg #6 to #9)
firmware registers ?


>         default:
>                 r = 0;
>         }
> diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> index 3c2fcf31ad3d..06243e4670eb 100644
> --- a/arch/arm64/kvm/hypercalls.c
> +++ b/arch/arm64/kvm/hypercalls.c
> @@ -58,6 +58,29 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
>         val[3] = lower_32_bits(cycles);
>  }
>
> +static bool kvm_arm_fw_reg_feat_enabled(u64 reg_bmap, u64 feat_bit)
> +{
> +       return reg_bmap & feat_bit;
> +}
> +
> +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
> +{
> +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> +
> +       switch (func_id) {
> +       case ARM_SMCCC_TRNG_VERSION:
> +       case ARM_SMCCC_TRNG_FEATURES:
> +       case ARM_SMCCC_TRNG_GET_UUID:
> +       case ARM_SMCCC_TRNG_RND32:
> +       case ARM_SMCCC_TRNG_RND64:
> +               return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
> +                                               KVM_REG_ARM_STD_BIT_TRNG_V1_0);
> +       default:
> +               /* By default, allow the services that aren't listed here */
> +               return true;
> +       }
> +}

kvm_hvc_call_supported() could return true even for @func_id that
kvm_hvc_call_handler() returns -EINVAL for.  Is this behavior what
you really want ?
If so, IMHO the function name might be a bit mis-leading.
"kvm_hvc_call_disabled" (and flip the return value)
might be closer to what it does(?).


> +
>  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
>  {
>         u32 func_id = smccc_get_function(vcpu);
> @@ -65,6 +88,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
>         u32 feature;
>         gpa_t gpa;
>
> +       if (!kvm_hvc_call_supported(vcpu, func_id))
> +               goto out;
> +
>         switch (func_id) {
>         case ARM_SMCCC_VERSION_FUNC_ID:
>                 val[0] = ARM_SMCCC_VERSION_1_1;
> @@ -143,6 +169,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
>                 return kvm_psci_call(vcpu);
>         }
>
> +out:
>         smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
>         return 1;
>  }
> @@ -153,9 +180,25 @@ static const u64 kvm_arm_fw_reg_ids[] = {
>         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
>  };
>
> +static const u64 kvm_arm_fw_reg_bmap_ids[] = {
> +       KVM_REG_ARM_STD_BMAP,
> +};
> +
> +void kvm_arm_init_hypercalls(struct kvm *kvm)
> +{
> +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> +
> +       hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
> +}
> +
> +int kvm_arm_num_fw_bmap_regs(void)
> +{
> +       return ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids);
> +}
> +
>  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
>  {
> -       return ARRAY_SIZE(kvm_arm_fw_reg_ids);
> +       return ARRAY_SIZE(kvm_arm_fw_reg_ids) + kvm_arm_num_fw_bmap_regs();
>  }
>
>  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> @@ -167,6 +210,11 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
>                         return -EFAULT;
>         }
>
> +       for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids); i++) {
> +               if (put_user(kvm_arm_fw_reg_bmap_ids[i], uindices++))
> +                       return -EFAULT;
> +       }
> +
>         return 0;
>  }
>
> @@ -211,9 +259,20 @@ static int get_kernel_wa_level(u64 regid)
>         return -EINVAL;
>  }
>
> +static void
> +kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
> +{
> +       struct kvm *kvm = vcpu->kvm;
> +
> +       mutex_lock(&kvm->lock);
> +       *val = fw_reg_bmap;
> +       mutex_unlock(&kvm->lock);

Why does it need to hold the lock ? (Wouldn't READ_ONCE be enough ?)


> +}
> +
>  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>  {
>         void __user *uaddr = (void __user *)(long)reg->addr;
> +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
>         u64 val;
>
>         switch (reg->id) {
> @@ -224,6 +283,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
>                 val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
>                 break;
> +       case KVM_REG_ARM_STD_BMAP:
> +               kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
> +               break;
>         default:
>                 return -ENOENT;
>         }
> @@ -234,6 +296,43 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>         return 0;
>  }
>
> +static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
> +{
> +       int ret = 0;
> +       struct kvm *kvm = vcpu->kvm;
> +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> +       u64 *fw_reg_bmap, fw_reg_features;
> +
> +       switch (reg_id) {
> +       case KVM_REG_ARM_STD_BMAP:
> +               fw_reg_bmap = &hvc_desc->hvc_std_bmap;
> +               fw_reg_features = ARM_SMCCC_STD_FEATURES;
> +               break;
> +       default:
> +               return -ENOENT;
> +       }
> +
> +       /* Check for unsupported bit */
> +       if (val & ~fw_reg_features)
> +               return -EINVAL;
> +
> +       mutex_lock(&kvm->lock);
> +
> +       /*
> +        * If the VM (any vCPU) has already started running, return success
> +        * if there's no change in the value. Else, return -EBUSY.
> +        */
> +       if (kvm_vm_has_started(kvm)) {
> +               ret = *fw_reg_bmap != val ? -EBUSY : 0;
> +               goto out;
> +       }
> +
> +       *fw_reg_bmap = val;
> +out:
> +       mutex_unlock(&kvm->lock);
> +       return ret;
> +}
> +
>  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>  {
>         void __user *uaddr = (void __user *)(long)reg->addr;
> @@ -310,6 +409,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
>                         return -EINVAL;
>
>                 return 0;
> +       case KVM_REG_ARM_STD_BMAP:
> +               return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
>         default:
>                 return -ENOENT;
>         }
> diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c
> index 99bdd7103c9c..23f912514b06 100644
> --- a/arch/arm64/kvm/trng.c
> +++ b/arch/arm64/kvm/trng.c
> @@ -60,14 +60,8 @@ int kvm_trng_call(struct kvm_vcpu *vcpu)
>                 val = ARM_SMCCC_TRNG_VERSION_1_0;
>                 break;
>         case ARM_SMCCC_TRNG_FEATURES:
> -               switch (smccc_get_arg1(vcpu)) {
> -               case ARM_SMCCC_TRNG_VERSION:
> -               case ARM_SMCCC_TRNG_FEATURES:
> -               case ARM_SMCCC_TRNG_GET_UUID:
> -               case ARM_SMCCC_TRNG_RND32:
> -               case ARM_SMCCC_TRNG_RND64:
> +               if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu)))
>                         val = TRNG_SUCCESS;

kvm_hvc_call_supported() returns true for any values that are
not explicitly listed in kvm_hvc_call_supported() (i.e. it returns
true even for @func_id that are not any of ARM_SMCCC_TRNG_*).
So, I don't think it can simply use the current kvm_hvc_call_supported.

Thanks,
Reiji

> -               }
>                 break;
>         case ARM_SMCCC_TRNG_GET_UUID:
>                 smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]),
> diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
> index 5d38628a8d04..8fe68d8d6d96 100644
> --- a/include/kvm/arm_hypercalls.h
> +++ b/include/kvm/arm_hypercalls.h
> @@ -6,6 +6,9 @@
>
>  #include <asm/kvm_emulate.h>
>
> +#define ARM_SMCCC_STD_FEATURES \
> +       GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
> +
>  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
>
>  static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
> @@ -42,9 +45,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
>
>  struct kvm_one_reg;
>
> +void kvm_arm_init_hypercalls(struct kvm *kvm);
> +int kvm_arm_num_fw_bmap_regs(void);
>  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
>  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
>  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
>  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id);
>
>  #endif
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From neal_liu at aspeedtech.com  Sun Jan  9 22:29:14 2022
From: neal_liu at aspeedtech.com (Neal Liu)
Date: Mon, 10 Jan 2022 06:29:14 +0000
Subject: [PATCH v3 2/4] usb: aspeed-vhub: fix remote wakeup failure in
 iKVM use case
In-Reply-To: <HK0PR06MB3202796B4DDF471856149B1480429@HK0PR06MB3202.apcprd06.prod.outlook.com>
References: <20211208100545.1441397-1-neal_liu@aspeedtech.com>
 <20211208100545.1441397-3-neal_liu@aspeedtech.com>
 <391323f136e49387797d43e89b6e42cd95d916c2.camel@kernel.crashing.org>
 <HK0PR06MB320271524E51BDFA922F070780709@HK0PR06MB3202.apcprd06.prod.outlook.com>
 <0888eb83c8b2bd53d4c3e2355019052d0ab40db6.camel@kernel.crashing.org>
 <HK0PR06MB3202051E7C15E84006DF55C0807B9@HK0PR06MB3202.apcprd06.prod.outlook.com>
 <HK0PR06MB3202796B4DDF471856149B1480429@HK0PR06MB3202.apcprd06.prod.outlook.com>
Message-ID: <HK0PR06MB320263FDED955EA4B6E0557480509@HK0PR06MB3202.apcprd06.prod.outlook.com>

> -----Original Message-----
> From: Neal Liu
> Sent: Monday, December 27, 2021 10:07 AM
> To: Benjamin Herrenschmidt <benh at kernel.crashing.org>; Felipe Balbi
> <balbi at kernel.org>; Greg Kroah-Hartman <gregkh at linuxfoundation.org>; Joel
> Stanley <joel at jms.id.au>; Andrew Jeffery <andrew at aj.id.au>; Cai Huoqing
> <caihuoqing at baidu.com>; Tao Ren <rentao.bupt at gmail.com>; Julia Lawall
> <julia.lawall at inria.fr>; kernel test robot <lkp at intel.com>; Sasha Levin
> <sashal at kernel.org>; linux-usb at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-aspeed at lists.ozlabs.org
> Cc: BMC-SW <BMC-SW at aspeedtech.com>
> Subject: RE: [PATCH v3 2/4] usb: aspeed-vhub: fix remote wakeup failure in
> iKVM use case
> 
> > -----Original Message-----
> > From: Neal Liu
> > Sent: Monday, December 20, 2021 10:23 AM
> > To: Benjamin Herrenschmidt <benh at kernel.crashing.org>; Felipe Balbi
> > <balbi at kernel.org>; Greg Kroah-Hartman <gregkh at linuxfoundation.org>;
> > Joel Stanley <joel at jms.id.au>; Andrew Jeffery <andrew at aj.id.au>; Cai
> > Huoqing <caihuoqing at baidu.com>; Tao Ren <rentao.bupt at gmail.com>; Julia
> > Lawall <julia.lawall at inria.fr>; kernel test robot <lkp at intel.com>;
> > Sasha Levin <sashal at kernel.org>; linux-usb at vger.kernel.org;
> > linux-kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > linux-aspeed at lists.ozlabs.org
> > Cc: BMC-SW <BMC-SW at aspeedtech.com>
> > Subject: RE: [PATCH v3 2/4] usb: aspeed-vhub: fix remote wakeup
> > failure in iKVM use case
> >
> > > -----Original Message-----
> > > From: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> > > Sent: Tuesday, December 14, 2021 10:36 AM
> > > To: Neal Liu <neal_liu at aspeedtech.com>; Felipe Balbi
> > > <balbi at kernel.org>; Greg Kroah-Hartman <gregkh at linuxfoundation.org>;
> > > Joel Stanley <joel at jms.id.au>; Andrew Jeffery <andrew at aj.id.au>; Cai
> > > Huoqing <caihuoqing at baidu.com>; Tao Ren <rentao.bupt at gmail.com>;
> > > Julia Lawall <julia.lawall at inria.fr>; kernel test robot
> > > <lkp at intel.com>; Sasha Levin <sashal at kernel.org>;
> > > linux-usb at vger.kernel.org; linux-kernel at vger.kernel.org;
> > > linux-arm-kernel at lists.infradead.org;
> > > linux-aspeed at lists.ozlabs.org
> > > Cc: BMC-SW <BMC-SW at aspeedtech.com>
> > > Subject: Re: [PATCH v3 2/4] usb: aspeed-vhub: fix remote wakeup
> > > failure in iKVM use case
> > >
> > > On Thu, 2021-12-09 at 02:37 +0000, Neal Liu wrote:
> > > > I'm confused. Signaling Wakeup when wakeup_en is set if it has any
> > > > ep activities is not exactly what you said?
> > > >
> > > > wakeup_en is set only if host allows this device have wakeup
> > > > capability and bus being suspended.
> > > >
> > > > Normal ep activities would not write the MMIO because wakeup_en is
> > > > not set.
> > >
> > > Hrm... I didn't think wakeup_en was limited to the bus being
> > > suspended, but maybe I misremember, it's been a while.
> > >
> > > Cheers,
> > > Ben.
> > >
> >
> > wakeup_en is only set in the case of host set
> USB_DEVICE_REMOTE_WAKEUP
> > feature to vhub devices.
> > I think this behavior only occurs during host is going to suspend, and
> > set this feature to any device which can wakeup itself before sleep.
> > Thanks
> >
> > -Neal
> >
> Would you like to test it if you have some free time.
> Please feel free for any feedback.
> 
> -Neal

Gentle ping for this patch.
Thanks


From qinjian at cqplus1.com  Sun Jan  9 22:37:01 2022
From: qinjian at cqplus1.com (=?utf-8?B?cWluamlhblvopoPlgaVd?=)
Date: Mon, 10 Jan 2022 06:37:01 +0000
Subject: [PATCH v7 06/10] clk: Add Sunplus SP7021 clock driver
In-Reply-To: <20220108004112.2AB34C36AE9@smtp.kernel.org>
References: <cover.1640154492.git.qinjian@cqplus1.com>
 <7f8302e2c1d02141dd69d2524eaa857d6494fdc7.1640154492.git.qinjian@cqplus1.com>
 <20220106004249.90484C36AEB@smtp.kernel.org>
 <51a2cbddc978400086271fc735493566@cqplus1.com>
 <20220108004112.2AB34C36AE9@smtp.kernel.org>
Message-ID: <739d561357814c31a530b327480e1212@cqplus1.com>

> > > > +
> > > > +CLK_OF_DECLARE_DRIVER(sp_clkc, "sunplus,sp7021-clkc", sp_clk_setup);
> > >
> > > Why CLK_OF_DECLARE_DRIVER? There should be a comment but better would be
> > > to make a platform driver instead. If the platform driver can't be used,
> > > we need to know what other device driver is probing based on this clkc
> > > compatible string.
> >
> > Dear Stephen,
> >
> > Sorry, I don't understand your comment.
> > Did you mean, like below:
> >
> > static int sp7021_clk_probe(struct platform_device *pdev)
> > {
> >         ......
> >         sp_clk_data->num = CLK_MAX;
> >         return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
> > }
> >
> > static const struct of_device_id sp7021_clk_dt_ids[] = {
> >         { .compatible = "sunplus,sp7021-clkc", },
> >         { }
> > };
> > MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);
> >
> > static struct platform_driver sp7021_clk_driver = {
> >         .probe  = sp7021_clk_probe,
> >         .driver = {
> >                 .name = "sp7021-clk",
> >                 .of_match_table = sp7021_clk_dt_ids,
> >         },
> > };
> > builtin_platform_driver(sp7021_clk_driver);
> >
> >
> > But, It's doesn't work.
> 
> Why doesn't it work?
> 
> > Most other clk drivers used CLK_OF_DECLARE_DRIVER or CLK_OF_DECLARE.
> > I just take these as the reference and it's working.
> 
> CLK_OF_DECLARE is for clks that need to be registered so the main
> irqchip and/or clocksource/clockevent can operate properly.
> CLK_OF_DECLARE_DRIVER is for the case that there's another driver that
> will attach to the device node that has the compatible string.

After some trace, I found:
In our dts, 'clkc' node defined @ clocks:
	clocks {
		...
		clkc: clock-controller at 9c000000 {
			#clock-cells = <1>;
			compatible = "sunplus,sp7021-clkc";
			reg = <0x9c000000 0x280>; // G0:CLKEN ~ G4:PLL
			clocks = <&extclk>, <&clkc PLL_SYS>;
			clock-names = "extclk", "pllsys";
		};
	};
	soc {
		...
	}
In this case, clk driver write as platform driver not work (sp7021_clk_probe not called)
But, CLK_OF_DECLARE and CLK_OF_DECLARE_DRIVER both worked (called from clk_of_init)

Then, I move the 'clkc' mode from 'clocks' to 'soc':
	clocks {
		...
	};
	soc {
		...
		clkc: clock-controller at 9c000000 {
			#clock-cells = <1>;
			compatible = "sunplus,sp7021-clkc";
			reg = <0x9c000000 0x280>; // G0:CLKEN ~ G4:PLL
			clocks = <&extclk>, <&clkc PLL_SYS>;
			clock-names = "extclk", "pllsys";
		};
	}
In this case, clk driver write as platform driver worked (called from platform_probe)
CLK_OF_DECLARE and CLK_OF_DECLARE_DRIVER also both worked. (still called from clk_of_init, more early than platform_probe)

It looks like CLK_OF_DECLARE/CLK_OF_DECLARE_DRIVER is better than platform driver.
Why you prefer platform driver?



From anshuman.khandual at arm.com  Sun Jan  9 22:41:36 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 10 Jan 2022 12:11:36 +0530
Subject: [PATCH] mm: Generalize ARCH_HAS_FILTER_PGPROT
Message-ID: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>

ARCH_HAS_FILTER_PGPROT config has duplicate definitions on platforms that
subscribe it. Instead make it a generic config option which can be selected
on applicable platforms when required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: x86 at kernel.org
Cc: linux-mm at kvack.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.16

 arch/arm64/Kconfig | 4 +---
 arch/x86/Kconfig   | 3 ---
 mm/Kconfig         | 3 +++
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..652fe8d12f4a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -23,6 +23,7 @@ config ARM64
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_GIGANTIC_PAGE
@@ -1178,9 +1179,6 @@ config HW_PERF_EVENTS
 	def_bool y
 	depends on ARM_PMU
 
-config ARCH_HAS_FILTER_PGPROT
-	def_bool y
-
 # Supported by clang >= 7.0
 config CC_HAVE_SHADOW_CALL_STACK
 	def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c2ccb85f2ef..d9594e05fddb 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -328,9 +328,6 @@ config GENERIC_CALIBRATE_DELAY
 config ARCH_HAS_CPU_RELAX
 	def_bool y
 
-config ARCH_HAS_FILTER_PGPROT
-	def_bool y
-
 config HAVE_SETUP_PER_CPU_AREA
 	def_bool y
 
diff --git a/mm/Kconfig b/mm/Kconfig
index 356f4f2c779e..dbf9daa4a29b 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -766,6 +766,9 @@ config IDLE_PAGE_TRACKING
 config ARCH_HAS_CACHE_LINE_SIZE
 	bool
 
+config ARCH_HAS_FILTER_PGPROT
+	bool
+
 config ARCH_HAS_PTE_DEVMAP
 	bool
 
-- 
2.20.1



From conleylee at foxmail.com  Sun Jan  9 23:23:07 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Mon, 10 Jan 2022 15:23:07 +0800
Subject: [PATCH 0/2] sun4i-emac: replace magic number with marcos
Message-ID: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>

From: conley <conleylee at foxmail.com>

- sun4i-emac.h: add register related marcos
- sun4i-emac.c: replace magic number with marco

*** BLURB HERE ***

conley (2):
  sun4i-emac.h: add register related marcos
  sun4i-emac.c: replace magic number with macro

 drivers/net/ethernet/allwinner/sun4i-emac.c | 26 ++++++++++-----------
 drivers/net/ethernet/allwinner/sun4i-emac.h | 18 ++++++++++++++
 2 files changed, 31 insertions(+), 13 deletions(-)

-- 
2.31.1



From conleylee at foxmail.com  Sun Jan  9 23:23:09 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Mon, 10 Jan 2022 15:23:09 +0800
Subject: [PATCH 2/2] sun4i-emac.c: replace magic number with macro
In-Reply-To: <20220110072309.2259523-1-conleylee@foxmail.com>
References: <20220110072309.2259523-1-conleylee@foxmail.com>
Message-ID: <tencent_DEA0AF54608BBD29ADC09D0DCA83E85DA205@qq.com>

From: conley <conleylee at foxmail.com>

Signed-off-by: conley <conleylee at foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 26 ++++++++++-----------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 849de4564709..cf9d8e9a4d9f 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -106,9 +106,9 @@ static void emac_update_speed(struct net_device *dev)
 
 	/* set EMAC SPEED, depend on PHY  */
 	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
-	reg_val &= ~(0x1 << 8);
+	reg_val &= ~EMAC_MAC_SUPP_100M;
 	if (db->speed == SPEED_100)
-		reg_val |= 1 << 8;
+		reg_val |= EMAC_MAC_SUPP_100M;
 	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
 }
 
@@ -264,7 +264,7 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
@@ -429,7 +429,7 @@ static unsigned int emac_powerup(struct net_device *ndev)
 	/* initial EMAC */
 	/* flush RX FIFO */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
-	reg_val |= 0x8;
+	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
 	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
 	udelay(1);
 
@@ -441,8 +441,8 @@ static unsigned int emac_powerup(struct net_device *ndev)
 
 	/* set MII clock */
 	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
-	reg_val &= (~(0xf << 2));
-	reg_val |= (0xD << 2);
+	reg_val &=~ EMAC_MAC_MCFG_MII_CLKD_MASK;
+	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
 	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
 
 	/* clear RX counter */
@@ -506,7 +506,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -637,7 +637,7 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +669,7 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -783,20 +783,20 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE)
 		emac_tx_done(dev, db, int_status);
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
-- 
2.31.1



From conleylee at foxmail.com  Sun Jan  9 23:23:08 2022
From: conleylee at foxmail.com (conleylee at foxmail.com)
Date: Mon, 10 Jan 2022 15:23:08 +0800
Subject: [PATCH 1/2] sun4i-emac.h: add register related marcos
In-Reply-To: <20220110072309.2259523-1-conleylee@foxmail.com>
References: <20220110072309.2259523-1-conleylee@foxmail.com>
Message-ID: <tencent_DA3D18DE830ADA4AA7B6AA9B3E0AF4D9DE09@qq.com>

From: conley <conleylee at foxmail.com>

Signed-off-by: conley <conleylee at foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..90bd9ad77607 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -38,6 +38,7 @@
 #define EMAC_RX_CTL_REG		(0x3c)
 #define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
 #define EMAC_RX_CTL_DMA_EN		(1 << 2)
+#define EMAC_RX_CTL_FLUSH_FIFO		(1 << 3)
 #define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
 #define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
 #define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
@@ -61,7 +62,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
@@ -87,8 +102,11 @@
 #define EMAC_MAC_CLRT_RM		(0x0f)
 #define EMAC_MAC_MAXF_REG	(0x70)
 #define EMAC_MAC_SUPP_REG	(0x74)
+#define EMAC_MAC_SUPP_100M	(0x1 << 8)
 #define EMAC_MAC_TEST_REG	(0x78)
 #define EMAC_MAC_MCFG_REG	(0x7c)
+#define EMAC_MAC_MCFG_MII_CLKD_MASK	(0xff << 2)
+#define EMAC_MAC_MCFG_MII_CLKD_72	(0x0d << 2)
 #define EMAC_MAC_A0_REG		(0x98)
 #define EMAC_MAC_A1_REG		(0x9c)
 #define EMAC_MAC_A2_REG		(0xa0)
-- 
2.31.1



From linmq006 at gmail.com  Sun Jan  9 23:31:00 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Mon, 10 Jan 2022 07:31:00 +0000
Subject: [PATCH] coresight: syscfg: Fix memleak on registration failure in
 cscfg_create_device
Message-ID: <20220110073100.15497-1-linmq006@gmail.com>

device_register() calls device_initialize(),
according to doc of device_initialize:

    Use put_device() to give up your reference instead of freeing
    * @dev directly once you have called this function.

To prevent potential memleak, use put_device() instead call kfree
directly.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 43054568430f..007fa1c761a7 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -764,7 +764,7 @@ struct device *cscfg_device(void)
 /* Must have a release function or the kernel will complain on module unload */
 static void cscfg_dev_release(struct device *dev)
 {
-	kfree(cscfg_mgr);
+	put_device(dev);
 	cscfg_mgr = NULL;
 }
 
-- 
2.17.1



From guodong.liu at mediatek.com  Sun Jan  9 23:31:10 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Mon, 10 Jan 2022 15:31:10 +0800
Subject: [PATCH v1 1/2] dt-bindings: pinctrl: mt8186: add pinctrl file and
 binding document
Message-ID: <20220110073111.31306-1-guodong.liu@mediatek.com>

1. This patch adds pinctrl file for mt8186.
2. This patch adds mt8186 compatible node in binding document.

Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
---
 .../bindings/pinctrl/pinctrl-mt8186.yaml      |  303 +++++
 include/dt-bindings/pinctrl/mt8186-pinfunc.h  | 1174 +++++++++++++++++
 2 files changed, 1477 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
 create mode 100644 include/dt-bindings/pinctrl/mt8186-pinfunc.h

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
new file mode 100644
index 000000000000..0a1154faca29
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
@@ -0,0 +1,303 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/pinctrl-mt8186.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8186 Pin Controller
+
+maintainers:
+  - Sean Wang <sean.wang at mediatek.com>
+
+description: |
+  The Mediatek's Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt8186-pinctrl
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO binding is used,
+      the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+    const: 2
+
+  gpio-ranges:
+    description: gpio valid number range.
+    maxItems: 1
+
+  reg:
+    description: |
+      Physical address base for gpio base registers. There are 8 GPIO
+      physical address base in mt8186.
+    maxItems: 8
+
+  reg-names:
+    description: |
+      Gpio base register names.
+    maxItems: 8
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupts:
+    description: The interrupt outputs to sysirq.
+    maxItems: 1
+
+  mediatek,rsel_resistance_in_si_unit:
+    type: boolean
+    description: |
+      Identifying i2c pins pull up/down type which is RSEL. It can support
+      RSEL define or si unit value(ohm) to set different resistance.
+
+# PIN CONFIGURATION NODES
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      '^pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and
+          input schmitt.
+          An example of using macro:
+          pincontroller {
+            /* GPIO0 set as multifunction GPIO0 */
+            gpio-pins {
+              pins {
+                pinmux = <PINMUX_GPIO0__FUNC_GPIO0>;
+              }
+            };
+            /* GPIO128 set as multifunction SDA0 */
+            i2c0-pins {
+              pins {
+                pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+              }
+            };
+          };
+        $ref: "pinmux-node.yaml"
+
+        properties:
+          pinmux:
+            description: |
+              Integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in dt-bindings/pinctrl/<soc>-pinfunc.h
+              directly.
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+          bias-pull-down:
+            description: |
+              For pull down type is normal, it don't need add RSEL & R1R0 define
+              and resistance value.
+              For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
+              set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+              "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" &
+              "MTK_PUPD_SET_R1R0_11" define in mt8186.
+              For pull down type is RSEL, it can add RSEL define & resistance
+              value(ohm) to set different resistance by identifying property
+              "mediatek,rsel_resistance_in_si_unit".
+              It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
+              & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011"
+              & "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101"
+              & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
+              define in mt8186. It can also support resistance value(ohm)
+              "75000" & "5000" in mt8186.
+              oneOf:
+                - enum: [100, 101, 102, 103]
+                - description: mt8186 pull down PUPD/R0/R1 type define value.
+                - enum: [200, 201, 202, 203, 204, 205, 206, 207]
+                - description: mt8186 pull down RSEL type define value.
+                - enum: [75000, 5000]
+                - description: mt8186 pull down RSEL type si unit value(ohm).
+
+              An example of using RSEL define:
+              pincontroller {
+                i2c0_pin {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-down = <MTK_PULL_SET_RSEL_001>;
+                  }
+                };
+              };
+              An example of using si unit resistance value(ohm):
+              &pio {
+                mediatek,rsel_resistance_in_si_unit;
+              }
+              pincontroller {
+                i2c0_pin {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-down = <75000>;
+                  }
+                };
+              };
+
+          bias-pull-up:
+            description: |
+              For pull up type is normal, it don't need add RSEL & R1R0 define
+              and resistance value.
+              For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
+              set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+              "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" &
+              "MTK_PUPD_SET_R1R0_11" define in mt8186.
+              For pull up type is RSEL, it can add RSEL define & resistance
+              value(ohm) to set different resistance by identifying property
+              "mediatek,rsel_resistance_in_si_unit".
+              It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
+              & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011"
+              & "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101"
+              & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
+              define in mt8186. It can also support resistance value(ohm)
+              "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" &
+              "75000" in mt8186.
+              oneOf:
+                - enum: [100, 101, 102, 103]
+                - description: mt8186 pull up PUPD/R0/R1 type define value.
+                - enum: [200, 201, 202, 203, 204, 205, 206, 207]
+                - description: mt8186 pull up RSEL type define value.
+                - enum: [1000, 1500, 2000, 3000, 4000, 5000, 10000, 75000]
+                - description: mt8186 pull up RSEL type si unit value(ohm).
+              An example of using RSEL define:
+              pincontroller {
+                i2c0-pins {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-up = <MTK_PULL_SET_RSEL_001>;
+                  }
+                };
+              };
+              An example of using si unit resistance value(ohm):
+              &pio {
+                mediatek,rsel_resistance_in_si_unit;
+              }
+              pincontroller {
+                i2c0-pins {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-up = <1000>;
+                  }
+                };
+              };
+
+          bias-disable: true
+
+          output-high: true
+
+          output-low: true
+
+          input-enable: true
+
+          input-disable: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+        required:
+          - pinmux
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - '#interrupt-cells'
+  - gpio-controller
+  - '#gpio-cells'
+  - gpio-ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/mt8186-pinfunc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pio: pinctrl at 10005000 {
+      compatible = "mediatek,mt8186-pinctrl";
+      reg = <0x10005000 0x1000>,
+            <0x10002000 0x0200>,
+            <0x10002200 0x0200>,
+            <0x10002400 0x0200>,
+            <0x10002600 0x0200>,
+            <0x10002A00 0x0200>,
+            <0x10002c00 0x0200>,
+            <0x1000b000 0x1000>;
+      reg-names = "iocfg0", "iocfg_bm", "iocfg_bl",
+                  "iocfg_br", "iocfg_lm", "iocfg_rb",
+                  "iocfg_tl", "eint";
+      gpio-controller;
+      #gpio-cells = <2>;
+      gpio-ranges = <&pio 0 0 185>;
+      interrupt-controller;
+      interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
+      #interrupt-cells = <2>;
+
+      pio-pins {
+        pins {
+          pinmux = <PINMUX_GPIO0__FUNC_GPIO0>;
+          output-low;
+        };
+      };
+
+      spi0-pins {
+        pins-spi {
+          pinmux = <PINMUX_GPIO0__FUNC_SPI0_CLK_B>,
+                   <PINMUX_GPIO1__FUNC_SPI0_CSB_B>,
+                   <PINMUX_GPIO2__FUNC_SPI0_MO_B>;
+          bias-disable;
+        };
+        pins-spi-mi {
+          pinmux = <PINMUX_GPIO3__FUNC_SPI0_MI_B>;
+          bias-pull-down;
+        };
+      };
+
+      i2c0-pins {
+        pins {
+          pinmux = <PINMUX_GPIO127__FUNC_SCL0>,
+                   <PINMUX_GPIO128__FUNC_SDA0>;
+          bias-disable;
+          mediatek,drive-strength-adv = <7>;
+        };
+      };
+    };
diff --git a/include/dt-bindings/pinctrl/mt8186-pinfunc.h b/include/dt-bindings/pinctrl/mt8186-pinfunc.h
new file mode 100644
index 000000000000..f58983d11bca
--- /dev/null
+++ b/include/dt-bindings/pinctrl/mt8186-pinfunc.h
@@ -0,0 +1,1174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Guodong Liu <Guodong.Liu at mediatek.com>
+ *
+ */
+
+#ifndef __MT8168_PINFUNC_H
+#define __MT8168_PINFUNC_H
+
+#include "mt65xx.h"
+
+#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
+#define PINMUX_GPIO0__FUNC_I2S0_MCK (MTK_PIN_NO(0) | 1)
+#define PINMUX_GPIO0__FUNC_SPI0_CLK_B (MTK_PIN_NO(0) | 2)
+#define PINMUX_GPIO0__FUNC_I2S2_MCK (MTK_PIN_NO(0) | 3)
+#define PINMUX_GPIO0__FUNC_CMFLASH0 (MTK_PIN_NO(0) | 4)
+#define PINMUX_GPIO0__FUNC_SCP_SPI0_CK (MTK_PIN_NO(0) | 5)
+#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 6)
+#define PINMUX_GPIO0__FUNC_DBG_MON_A0 (MTK_PIN_NO(0) | 7)
+
+#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
+#define PINMUX_GPIO1__FUNC_I2S0_BCK (MTK_PIN_NO(1) | 1)
+#define PINMUX_GPIO1__FUNC_SPI0_CSB_B (MTK_PIN_NO(1) | 2)
+#define PINMUX_GPIO1__FUNC_I2S2_BCK (MTK_PIN_NO(1) | 3)
+#define PINMUX_GPIO1__FUNC_CMFLASH1 (MTK_PIN_NO(1) | 4)
+#define PINMUX_GPIO1__FUNC_SCP_SPI0_CS (MTK_PIN_NO(1) | 5)
+#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 6)
+
+#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
+#define PINMUX_GPIO2__FUNC_I2S0_LRCK (MTK_PIN_NO(2) | 1)
+#define PINMUX_GPIO2__FUNC_SPI0_MO_B (MTK_PIN_NO(2) | 2)
+#define PINMUX_GPIO2__FUNC_I2S2_LRCK (MTK_PIN_NO(2) | 3)
+#define PINMUX_GPIO2__FUNC_CMFLASH2 (MTK_PIN_NO(2) | 4)
+#define PINMUX_GPIO2__FUNC_SCP_SPI0_MO (MTK_PIN_NO(2) | 5)
+#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 6)
+
+#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
+#define PINMUX_GPIO3__FUNC_I2S0_DI (MTK_PIN_NO(3) | 1)
+#define PINMUX_GPIO3__FUNC_SPI0_MI_B (MTK_PIN_NO(3) | 2)
+#define PINMUX_GPIO3__FUNC_I2S2_DI (MTK_PIN_NO(3) | 3)
+#define PINMUX_GPIO3__FUNC_SRCLKENAI1 (MTK_PIN_NO(3) | 4)
+#define PINMUX_GPIO3__FUNC_SCP_SPI0_MI (MTK_PIN_NO(3) | 5)
+#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 6)
+
+#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
+#define PINMUX_GPIO4__FUNC_I2S3_DO (MTK_PIN_NO(4) | 1)
+#define PINMUX_GPIO4__FUNC_I2S1_DO (MTK_PIN_NO(4) | 3)
+#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6)
+
+#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
+#define PINMUX_GPIO5__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(5) | 1)
+#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6)
+
+#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
+#define PINMUX_GPIO6__FUNC_I2S3_MCK (MTK_PIN_NO(6) | 1)
+#define PINMUX_GPIO6__FUNC_SPI1_CLK_B (MTK_PIN_NO(6) | 2)
+#define PINMUX_GPIO6__FUNC_I2S1_MCK (MTK_PIN_NO(6) | 3)
+#define PINMUX_GPIO6__FUNC_DPI_DATA22 (MTK_PIN_NO(6) | 4)
+#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6)
+
+#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
+#define PINMUX_GPIO7__FUNC_I2S3_BCK (MTK_PIN_NO(7) | 1)
+#define PINMUX_GPIO7__FUNC_SPI1_CSB_B (MTK_PIN_NO(7) | 2)
+#define PINMUX_GPIO7__FUNC_I2S1_BCK (MTK_PIN_NO(7) | 3)
+#define PINMUX_GPIO7__FUNC_DPI_DATA23 (MTK_PIN_NO(7) | 4)
+#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6)
+
+#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
+#define PINMUX_GPIO8__FUNC_I2S3_LRCK (MTK_PIN_NO(8) | 1)
+#define PINMUX_GPIO8__FUNC_SPI1_MO_B (MTK_PIN_NO(8) | 2)
+#define PINMUX_GPIO8__FUNC_I2S1_LRCK (MTK_PIN_NO(8) | 3)
+#define PINMUX_GPIO8__FUNC_CONN_UART0_RXD (MTK_PIN_NO(8) | 4)
+#define PINMUX_GPIO8__FUNC_SSPM_URXD_AO (MTK_PIN_NO(8) | 5)
+#define PINMUX_GPIO8__FUNC_ADSP_UART_RX (MTK_PIN_NO(8) | 6)
+#define PINMUX_GPIO8__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(8) | 7)
+
+#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
+#define PINMUX_GPIO9__FUNC_I2S3_DO (MTK_PIN_NO(9) | 1)
+#define PINMUX_GPIO9__FUNC_SPI1_MI_B (MTK_PIN_NO(9) | 2)
+#define PINMUX_GPIO9__FUNC_I2S1_DO (MTK_PIN_NO(9) | 3)
+#define PINMUX_GPIO9__FUNC_CONN_UART0_TXD (MTK_PIN_NO(9) | 4)
+#define PINMUX_GPIO9__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(9) | 5)
+#define PINMUX_GPIO9__FUNC_ADSP_UART_TX (MTK_PIN_NO(9) | 6)
+#define PINMUX_GPIO9__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(9) | 7)
+
+#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
+#define PINMUX_GPIO10__FUNC_I2S0_MCK (MTK_PIN_NO(10) | 1)
+#define PINMUX_GPIO10__FUNC_SPI4_CLK_A (MTK_PIN_NO(10) | 2)
+#define PINMUX_GPIO10__FUNC_I2S2_MCK (MTK_PIN_NO(10) | 3)
+#define PINMUX_GPIO10__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(10) | 4)
+#define PINMUX_GPIO10__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(10) | 5)
+#define PINMUX_GPIO10__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(10) | 6)
+#define PINMUX_GPIO10__FUNC_CONN_MCU_TDI (MTK_PIN_NO(10) | 7)
+
+#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
+#define PINMUX_GPIO11__FUNC_I2S0_BCK (MTK_PIN_NO(11) | 1)
+#define PINMUX_GPIO11__FUNC_SPI4_CSB_A (MTK_PIN_NO(11) | 2)
+#define PINMUX_GPIO11__FUNC_I2S2_BCK (MTK_PIN_NO(11) | 3)
+#define PINMUX_GPIO11__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(11) | 4)
+#define PINMUX_GPIO11__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(11) | 5)
+#define PINMUX_GPIO11__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(11) | 6)
+#define PINMUX_GPIO11__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(11) | 7)
+
+#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
+#define PINMUX_GPIO12__FUNC_I2S0_LRCK (MTK_PIN_NO(12) | 1)
+#define PINMUX_GPIO12__FUNC_SPI4_MO_A (MTK_PIN_NO(12) | 2)
+#define PINMUX_GPIO12__FUNC_I2S2_LRCK (MTK_PIN_NO(12) | 3)
+#define PINMUX_GPIO12__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(12) | 4)
+#define PINMUX_GPIO12__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(12) | 5)
+#define PINMUX_GPIO12__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(12) | 6)
+#define PINMUX_GPIO12__FUNC_CONN_MCU_TCK (MTK_PIN_NO(12) | 7)
+
+#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
+#define PINMUX_GPIO13__FUNC_I2S0_DI (MTK_PIN_NO(13) | 1)
+#define PINMUX_GPIO13__FUNC_SPI4_MI_A (MTK_PIN_NO(13) | 2)
+#define PINMUX_GPIO13__FUNC_I2S2_DI (MTK_PIN_NO(13) | 3)
+#define PINMUX_GPIO13__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(13) | 4)
+#define PINMUX_GPIO13__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(13) | 5)
+#define PINMUX_GPIO13__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(13) | 6)
+#define PINMUX_GPIO13__FUNC_CONN_MCU_TDO (MTK_PIN_NO(13) | 7)
+
+#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
+#define PINMUX_GPIO14__FUNC_CLKM0 (MTK_PIN_NO(14) | 3)
+#define PINMUX_GPIO14__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(14) | 4)
+#define PINMUX_GPIO14__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(14) | 5)
+#define PINMUX_GPIO14__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(14) | 6)
+#define PINMUX_GPIO14__FUNC_CONN_MCU_TMS (MTK_PIN_NO(14) | 7)
+
+#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
+#define PINMUX_GPIO15__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(15) | 1)
+#define PINMUX_GPIO15__FUNC_SRCLKENAI1 (MTK_PIN_NO(15) | 2)
+#define PINMUX_GPIO15__FUNC_CLKM1 (MTK_PIN_NO(15) | 3)
+#define PINMUX_GPIO15__FUNC_PWM0 (MTK_PIN_NO(15) | 4)
+
+#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
+#define PINMUX_GPIO16__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(16) | 1)
+#define PINMUX_GPIO16__FUNC_SRCLKENAI0 (MTK_PIN_NO(16) | 2)
+#define PINMUX_GPIO16__FUNC_CLKM2 (MTK_PIN_NO(16) | 3)
+#define PINMUX_GPIO16__FUNC_PWM1 (MTK_PIN_NO(16) | 4)
+
+#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
+#define PINMUX_GPIO17__FUNC_CLKM3 (MTK_PIN_NO(17) | 3)
+#define PINMUX_GPIO17__FUNC_PWM2 (MTK_PIN_NO(17) | 4)
+#define PINMUX_GPIO17__FUNC_DBG_MON_A32 (MTK_PIN_NO(17) | 7)
+
+#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
+#define PINMUX_GPIO18__FUNC_CMVREF0 (MTK_PIN_NO(18) | 2)
+#define PINMUX_GPIO18__FUNC_SPI2_CLK_B (MTK_PIN_NO(18) | 6)
+#define PINMUX_GPIO18__FUNC_DBG_MON_A26 (MTK_PIN_NO(18) | 7)
+
+#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
+#define PINMUX_GPIO19__FUNC_CMVREF1 (MTK_PIN_NO(19) | 2)
+#define PINMUX_GPIO19__FUNC_ANT_SEL3 (MTK_PIN_NO(19) | 5)
+#define PINMUX_GPIO19__FUNC_SPI2_CSB_B (MTK_PIN_NO(19) | 6)
+#define PINMUX_GPIO19__FUNC_DBG_MON_A2 (MTK_PIN_NO(19) | 7)
+
+#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
+#define PINMUX_GPIO20__FUNC_CMVREF2 (MTK_PIN_NO(20) | 2)
+#define PINMUX_GPIO20__FUNC_ANT_SEL4 (MTK_PIN_NO(20) | 5)
+#define PINMUX_GPIO20__FUNC_SPI2_MO_B (MTK_PIN_NO(20) | 6)
+#define PINMUX_GPIO20__FUNC_DBG_MON_A3 (MTK_PIN_NO(20) | 7)
+
+#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
+#define PINMUX_GPIO21__FUNC_I2S0_MCK (MTK_PIN_NO(21) | 1)
+#define PINMUX_GPIO21__FUNC_I2S1_MCK (MTK_PIN_NO(21) | 2)
+#define PINMUX_GPIO21__FUNC_I2S3_MCK (MTK_PIN_NO(21) | 3)
+#define PINMUX_GPIO21__FUNC_ANT_SEL5 (MTK_PIN_NO(21) | 5)
+#define PINMUX_GPIO21__FUNC_SPI2_MI_B (MTK_PIN_NO(21) | 6)
+#define PINMUX_GPIO21__FUNC_DBG_MON_A4 (MTK_PIN_NO(21) | 7)
+
+#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
+#define PINMUX_GPIO22__FUNC_I2S0_BCK (MTK_PIN_NO(22) | 1)
+#define PINMUX_GPIO22__FUNC_I2S1_BCK (MTK_PIN_NO(22) | 2)
+#define PINMUX_GPIO22__FUNC_I2S3_BCK (MTK_PIN_NO(22) | 3)
+#define PINMUX_GPIO22__FUNC_TDM_RX_LRCK (MTK_PIN_NO(22) | 4)
+#define PINMUX_GPIO22__FUNC_ANT_SEL6 (MTK_PIN_NO(22) | 5)
+#define PINMUX_GPIO22__FUNC_DBG_MON_A5 (MTK_PIN_NO(22) | 7)
+
+#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
+#define PINMUX_GPIO23__FUNC_I2S0_LRCK (MTK_PIN_NO(23) | 1)
+#define PINMUX_GPIO23__FUNC_I2S1_LRCK (MTK_PIN_NO(23) | 2)
+#define PINMUX_GPIO23__FUNC_I2S3_LRCK (MTK_PIN_NO(23) | 3)
+#define PINMUX_GPIO23__FUNC_TDM_RX_BCK (MTK_PIN_NO(23) | 4)
+#define PINMUX_GPIO23__FUNC_ANT_SEL7 (MTK_PIN_NO(23) | 5)
+#define PINMUX_GPIO23__FUNC_DBG_MON_A6 (MTK_PIN_NO(23) | 7)
+
+#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
+#define PINMUX_GPIO24__FUNC_I2S0_DI (MTK_PIN_NO(24) | 1)
+#define PINMUX_GPIO24__FUNC_I2S1_DO (MTK_PIN_NO(24) | 2)
+#define PINMUX_GPIO24__FUNC_I2S3_DO (MTK_PIN_NO(24) | 3)
+#define PINMUX_GPIO24__FUNC_TDM_RX_MCK (MTK_PIN_NO(24) | 4)
+#define PINMUX_GPIO24__FUNC_DBG_MON_A7 (MTK_PIN_NO(24) | 7)
+
+#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
+#define PINMUX_GPIO25__FUNC_I2S2_MCK (MTK_PIN_NO(25) | 1)
+#define PINMUX_GPIO25__FUNC_PCM_CLK (MTK_PIN_NO(25) | 2)
+#define PINMUX_GPIO25__FUNC_SPI4_CLK_B (MTK_PIN_NO(25) | 3)
+#define PINMUX_GPIO25__FUNC_TDM_RX_DATA0 (MTK_PIN_NO(25) | 4)
+#define PINMUX_GPIO25__FUNC_DBG_MON_A8 (MTK_PIN_NO(25) | 7)
+
+#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
+#define PINMUX_GPIO26__FUNC_I2S2_BCK (MTK_PIN_NO(26) | 1)
+#define PINMUX_GPIO26__FUNC_PCM_SYNC (MTK_PIN_NO(26) | 2)
+#define PINMUX_GPIO26__FUNC_SPI4_CSB_B (MTK_PIN_NO(26) | 3)
+#define PINMUX_GPIO26__FUNC_TDM_RX_DATA1 (MTK_PIN_NO(26) | 4)
+#define PINMUX_GPIO26__FUNC_DBG_MON_A9 (MTK_PIN_NO(26) | 7)
+
+#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
+#define PINMUX_GPIO27__FUNC_I2S2_LRCK (MTK_PIN_NO(27) | 1)
+#define PINMUX_GPIO27__FUNC_PCM_DI (MTK_PIN_NO(27) | 2)
+#define PINMUX_GPIO27__FUNC_SPI4_MO_B (MTK_PIN_NO(27) | 3)
+#define PINMUX_GPIO27__FUNC_TDM_RX_DATA2 (MTK_PIN_NO(27) | 4)
+#define PINMUX_GPIO27__FUNC_DBG_MON_A10 (MTK_PIN_NO(27) | 7)
+
+#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
+#define PINMUX_GPIO28__FUNC_I2S2_DI (MTK_PIN_NO(28) | 1)
+#define PINMUX_GPIO28__FUNC_PCM_DO (MTK_PIN_NO(28) | 2)
+#define PINMUX_GPIO28__FUNC_SPI4_MI_B (MTK_PIN_NO(28) | 3)
+#define PINMUX_GPIO28__FUNC_TDM_RX_DATA3 (MTK_PIN_NO(28) | 4)
+
+#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
+#define PINMUX_GPIO29__FUNC_ANT_SEL0 (MTK_PIN_NO(29) | 1)
+#define PINMUX_GPIO29__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(29) | 2)
+
+#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
+#define PINMUX_GPIO30__FUNC_ANT_SEL1 (MTK_PIN_NO(30) | 1)
+
+#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
+#define PINMUX_GPIO31__FUNC_ANT_SEL2 (MTK_PIN_NO(31) | 1)
+#define PINMUX_GPIO31__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(31) | 2)
+#define PINMUX_GPIO31__FUNC_SRCLKENAI1 (MTK_PIN_NO(31) | 3)
+
+#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
+#define PINMUX_GPIO32__FUNC_URXD0 (MTK_PIN_NO(32) | 1)
+#define PINMUX_GPIO32__FUNC_UTXD0 (MTK_PIN_NO(32) | 2)
+#define PINMUX_GPIO32__FUNC_ADSP_UART_RX (MTK_PIN_NO(32) | 3)
+#define PINMUX_GPIO32__FUNC_TP_URXD1_AO (MTK_PIN_NO(32) | 4)
+
+#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
+#define PINMUX_GPIO33__FUNC_UTXD0 (MTK_PIN_NO(33) | 1)
+#define PINMUX_GPIO33__FUNC_URXD0 (MTK_PIN_NO(33) | 2)
+#define PINMUX_GPIO33__FUNC_ADSP_UART_TX (MTK_PIN_NO(33) | 3)
+#define PINMUX_GPIO33__FUNC_TP_UTXD1_AO (MTK_PIN_NO(33) | 4)
+
+#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
+#define PINMUX_GPIO34__FUNC_URXD1 (MTK_PIN_NO(34) | 1)
+#define PINMUX_GPIO34__FUNC_TP_URXD2_AO (MTK_PIN_NO(34) | 2)
+#define PINMUX_GPIO34__FUNC_SSPM_URXD_AO (MTK_PIN_NO(34) | 3)
+#define PINMUX_GPIO34__FUNC_ADSP_UART_RX (MTK_PIN_NO(34) | 4)
+#define PINMUX_GPIO34__FUNC_CONN_UART0_RXD (MTK_PIN_NO(34) | 5)
+
+#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
+#define PINMUX_GPIO35__FUNC_UTXD1 (MTK_PIN_NO(35) | 1)
+#define PINMUX_GPIO35__FUNC_TP_UTXD2_AO (MTK_PIN_NO(35) | 2)
+#define PINMUX_GPIO35__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(35) | 3)
+#define PINMUX_GPIO35__FUNC_ADSP_UART_TX (MTK_PIN_NO(35) | 4)
+#define PINMUX_GPIO35__FUNC_CONN_UART0_TXD (MTK_PIN_NO(35) | 5)
+#define PINMUX_GPIO35__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(35) | 6)
+
+#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
+#define PINMUX_GPIO36__FUNC_SPI0_CLK_A (MTK_PIN_NO(36) | 1)
+#define PINMUX_GPIO36__FUNC_CLKM0 (MTK_PIN_NO(36) | 2)
+#define PINMUX_GPIO36__FUNC_SCP_SPI0_CK (MTK_PIN_NO(36) | 4)
+#define PINMUX_GPIO36__FUNC_SPINOR_CK (MTK_PIN_NO(36) | 5)
+#define PINMUX_GPIO36__FUNC_DBG_MON_A11 (MTK_PIN_NO(36) | 7)
+
+#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
+#define PINMUX_GPIO37__FUNC_SPI0_CSB_A (MTK_PIN_NO(37) | 1)
+#define PINMUX_GPIO37__FUNC_CLKM1 (MTK_PIN_NO(37) | 2)
+#define PINMUX_GPIO37__FUNC_PWM0 (MTK_PIN_NO(37) | 3)
+#define PINMUX_GPIO37__FUNC_SCP_SPI0_CS (MTK_PIN_NO(37) | 4)
+#define PINMUX_GPIO37__FUNC_SPINOR_CS (MTK_PIN_NO(37) | 5)
+#define PINMUX_GPIO37__FUNC_DBG_MON_A12 (MTK_PIN_NO(37) | 7)
+
+#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
+#define PINMUX_GPIO38__FUNC_SPI0_MO_A (MTK_PIN_NO(38) | 1)
+#define PINMUX_GPIO38__FUNC_CLKM2 (MTK_PIN_NO(38) | 2)
+#define PINMUX_GPIO38__FUNC_PWM1 (MTK_PIN_NO(38) | 3)
+#define PINMUX_GPIO38__FUNC_SCP_SPI0_MO (MTK_PIN_NO(38) | 4)
+#define PINMUX_GPIO38__FUNC_SPINOR_IO0 (MTK_PIN_NO(38) | 5)
+#define PINMUX_GPIO38__FUNC_DBG_MON_A13 (MTK_PIN_NO(38) | 7)
+
+#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
+#define PINMUX_GPIO39__FUNC_SPI0_MI_A (MTK_PIN_NO(39) | 1)
+#define PINMUX_GPIO39__FUNC_CLKM3 (MTK_PIN_NO(39) | 2)
+#define PINMUX_GPIO39__FUNC_PWM2 (MTK_PIN_NO(39) | 3)
+#define PINMUX_GPIO39__FUNC_SCP_SPI0_MI (MTK_PIN_NO(39) | 4)
+#define PINMUX_GPIO39__FUNC_SPINOR_IO1 (MTK_PIN_NO(39) | 5)
+#define PINMUX_GPIO39__FUNC_DBG_MON_A14 (MTK_PIN_NO(39) | 7)
+
+#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
+#define PINMUX_GPIO40__FUNC_SPI1_CLK_A (MTK_PIN_NO(40) | 1)
+#define PINMUX_GPIO40__FUNC_SCP_SPI1_CK (MTK_PIN_NO(40) | 2)
+#define PINMUX_GPIO40__FUNC_UCTS0 (MTK_PIN_NO(40) | 4)
+#define PINMUX_GPIO40__FUNC_SPINOR_IO2 (MTK_PIN_NO(40) | 5)
+#define PINMUX_GPIO40__FUNC_TP_UCTS1_AO (MTK_PIN_NO(40) | 6)
+#define PINMUX_GPIO40__FUNC_DBG_MON_A15 (MTK_PIN_NO(40) | 7)
+
+#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
+#define PINMUX_GPIO41__FUNC_SPI1_CSB_A (MTK_PIN_NO(41) | 1)
+#define PINMUX_GPIO41__FUNC_SCP_SPI1_CS (MTK_PIN_NO(41) | 2)
+#define PINMUX_GPIO41__FUNC_PWM0 (MTK_PIN_NO(41) | 3)
+#define PINMUX_GPIO41__FUNC_URTS0 (MTK_PIN_NO(41) | 4)
+#define PINMUX_GPIO41__FUNC_SPINOR_IO3 (MTK_PIN_NO(41) | 5)
+#define PINMUX_GPIO41__FUNC_TP_URTS1_AO (MTK_PIN_NO(41) | 6)
+#define PINMUX_GPIO41__FUNC_DBG_MON_A16 (MTK_PIN_NO(41) | 7)
+
+#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
+#define PINMUX_GPIO42__FUNC_SPI1_MO_A (MTK_PIN_NO(42) | 1)
+#define PINMUX_GPIO42__FUNC_SCP_SPI1_MO (MTK_PIN_NO(42) | 2)
+#define PINMUX_GPIO42__FUNC_PWM1 (MTK_PIN_NO(42) | 3)
+#define PINMUX_GPIO42__FUNC_UCTS1 (MTK_PIN_NO(42) | 4)
+#define PINMUX_GPIO42__FUNC_TP_UCTS2_AO (MTK_PIN_NO(42) | 6)
+#define PINMUX_GPIO42__FUNC_DBG_MON_A17 (MTK_PIN_NO(42) | 7)
+
+#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
+#define PINMUX_GPIO43__FUNC_SPI1_MI_A (MTK_PIN_NO(43) | 1)
+#define PINMUX_GPIO43__FUNC_SCP_SPI1_MI (MTK_PIN_NO(43) | 2)
+#define PINMUX_GPIO43__FUNC_PWM2 (MTK_PIN_NO(43) | 3)
+#define PINMUX_GPIO43__FUNC_URTS1 (MTK_PIN_NO(43) | 4)
+#define PINMUX_GPIO43__FUNC_TP_URTS2_AO (MTK_PIN_NO(43) | 6)
+#define PINMUX_GPIO43__FUNC_DBG_MON_A18 (MTK_PIN_NO(43) | 7)
+
+#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
+#define PINMUX_GPIO44__FUNC_SPI2_CLK_A (MTK_PIN_NO(44) | 1)
+#define PINMUX_GPIO44__FUNC_SCP_SPI0_CK (MTK_PIN_NO(44) | 2)
+#define PINMUX_GPIO44__FUNC_DBG_MON_A19 (MTK_PIN_NO(44) | 7)
+
+#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
+#define PINMUX_GPIO45__FUNC_SPI2_CSB_A (MTK_PIN_NO(45) | 1)
+#define PINMUX_GPIO45__FUNC_SCP_SPI0_CS (MTK_PIN_NO(45) | 2)
+#define PINMUX_GPIO45__FUNC_DBG_MON_A20 (MTK_PIN_NO(45) | 7)
+
+#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
+#define PINMUX_GPIO46__FUNC_SPI2_MO_A (MTK_PIN_NO(46) | 1)
+#define PINMUX_GPIO46__FUNC_SCP_SPI0_MO (MTK_PIN_NO(46) | 2)
+#define PINMUX_GPIO46__FUNC_DBG_MON_A21 (MTK_PIN_NO(46) | 7)
+
+#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
+#define PINMUX_GPIO47__FUNC_SPI2_MI_A (MTK_PIN_NO(47) | 1)
+#define PINMUX_GPIO47__FUNC_SCP_SPI0_MI (MTK_PIN_NO(47) | 2)
+#define PINMUX_GPIO47__FUNC_DBG_MON_A22 (MTK_PIN_NO(47) | 7)
+
+#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
+#define PINMUX_GPIO48__FUNC_SPI3_CLK (MTK_PIN_NO(48) | 1)
+#define PINMUX_GPIO48__FUNC_TP_URXD1_AO (MTK_PIN_NO(48) | 2)
+#define PINMUX_GPIO48__FUNC_TP_URXD2_AO (MTK_PIN_NO(48) | 3)
+#define PINMUX_GPIO48__FUNC_URXD1 (MTK_PIN_NO(48) | 4)
+#define PINMUX_GPIO48__FUNC_I2S2_MCK (MTK_PIN_NO(48) | 5)
+#define PINMUX_GPIO48__FUNC_SCP_SPI0_CK (MTK_PIN_NO(48) | 6)
+
+#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
+#define PINMUX_GPIO49__FUNC_SPI3_CSB (MTK_PIN_NO(49) | 1)
+#define PINMUX_GPIO49__FUNC_TP_UTXD1_AO (MTK_PIN_NO(49) | 2)
+#define PINMUX_GPIO49__FUNC_TP_UTXD2_AO (MTK_PIN_NO(49) | 3)
+#define PINMUX_GPIO49__FUNC_UTXD1 (MTK_PIN_NO(49) | 4)
+#define PINMUX_GPIO49__FUNC_I2S2_BCK (MTK_PIN_NO(49) | 5)
+#define PINMUX_GPIO49__FUNC_SCP_SPI0_CS (MTK_PIN_NO(49) | 6)
+
+#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0)
+#define PINMUX_GPIO50__FUNC_SPI3_MO (MTK_PIN_NO(50) | 1)
+#define PINMUX_GPIO50__FUNC_I2S2_LRCK (MTK_PIN_NO(50) | 5)
+#define PINMUX_GPIO50__FUNC_SCP_SPI0_MO (MTK_PIN_NO(50) | 6)
+
+#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0)
+#define PINMUX_GPIO51__FUNC_SPI3_MI (MTK_PIN_NO(51) | 1)
+#define PINMUX_GPIO51__FUNC_I2S2_DI (MTK_PIN_NO(51) | 5)
+#define PINMUX_GPIO51__FUNC_SCP_SPI0_MI (MTK_PIN_NO(51) | 6)
+
+#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0)
+#define PINMUX_GPIO52__FUNC_SPI5_CLK (MTK_PIN_NO(52) | 1)
+#define PINMUX_GPIO52__FUNC_I2S2_MCK (MTK_PIN_NO(52) | 2)
+#define PINMUX_GPIO52__FUNC_I2S1_MCK (MTK_PIN_NO(52) | 3)
+#define PINMUX_GPIO52__FUNC_SCP_SPI1_CK (MTK_PIN_NO(52) | 4)
+#define PINMUX_GPIO52__FUNC_LVTS_26M (MTK_PIN_NO(52) | 5)
+#define PINMUX_GPIO52__FUNC_DFD_TCK_XI (MTK_PIN_NO(52) | 6)
+#define PINMUX_GPIO52__FUNC_DBG_MON_B30 (MTK_PIN_NO(52) | 7)
+
+#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
+#define PINMUX_GPIO53__FUNC_SPI5_CSB (MTK_PIN_NO(53) | 1)
+#define PINMUX_GPIO53__FUNC_I2S2_BCK (MTK_PIN_NO(53) | 2)
+#define PINMUX_GPIO53__FUNC_I2S1_BCK (MTK_PIN_NO(53) | 3)
+#define PINMUX_GPIO53__FUNC_SCP_SPI1_CS (MTK_PIN_NO(53) | 4)
+#define PINMUX_GPIO53__FUNC_LVTS_FOUT (MTK_PIN_NO(53) | 5)
+#define PINMUX_GPIO53__FUNC_DFD_TDI (MTK_PIN_NO(53) | 6)
+#define PINMUX_GPIO53__FUNC_DBG_MON_B31 (MTK_PIN_NO(53) | 7)
+
+#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
+#define PINMUX_GPIO54__FUNC_SPI5_MO (MTK_PIN_NO(54) | 1)
+#define PINMUX_GPIO54__FUNC_I2S2_LRCK (MTK_PIN_NO(54) | 2)
+#define PINMUX_GPIO54__FUNC_I2S1_LRCK (MTK_PIN_NO(54) | 3)
+#define PINMUX_GPIO54__FUNC_SCP_SPI1_MO (MTK_PIN_NO(54) | 4)
+#define PINMUX_GPIO54__FUNC_LVTS_SCK (MTK_PIN_NO(54) | 5)
+#define PINMUX_GPIO54__FUNC_DFD_TDO (MTK_PIN_NO(54) | 6)
+#define PINMUX_GPIO54__FUNC_DBG_MON_A1 (MTK_PIN_NO(54) | 7)
+
+#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
+#define PINMUX_GPIO55__FUNC_SPI5_MI (MTK_PIN_NO(55) | 1)
+#define PINMUX_GPIO55__FUNC_I2S2_DI (MTK_PIN_NO(55) | 2)
+#define PINMUX_GPIO55__FUNC_I2S1_DO (MTK_PIN_NO(55) | 3)
+#define PINMUX_GPIO55__FUNC_SCP_SPI1_MI (MTK_PIN_NO(55) | 4)
+#define PINMUX_GPIO55__FUNC_LVTS_SDO (MTK_PIN_NO(55) | 5)
+#define PINMUX_GPIO55__FUNC_DFD_TMS (MTK_PIN_NO(55) | 6)
+#define PINMUX_GPIO55__FUNC_DBG_MON_B32 (MTK_PIN_NO(55) | 7)
+
+#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
+#define PINMUX_GPIO56__FUNC_I2S1_DO (MTK_PIN_NO(56) | 1)
+#define PINMUX_GPIO56__FUNC_I2S3_DO (MTK_PIN_NO(56) | 2)
+#define PINMUX_GPIO56__FUNC_DBG_MON_A23 (MTK_PIN_NO(56) | 7)
+
+#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
+#define PINMUX_GPIO57__FUNC_I2S1_BCK (MTK_PIN_NO(57) | 1)
+#define PINMUX_GPIO57__FUNC_I2S3_BCK (MTK_PIN_NO(57) | 2)
+#define PINMUX_GPIO57__FUNC_DBG_MON_A24 (MTK_PIN_NO(57) | 7)
+
+#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
+#define PINMUX_GPIO58__FUNC_I2S1_LRCK (MTK_PIN_NO(58) | 1)
+#define PINMUX_GPIO58__FUNC_I2S3_LRCK (MTK_PIN_NO(58) | 2)
+#define PINMUX_GPIO58__FUNC_DBG_MON_A25 (MTK_PIN_NO(58) | 7)
+
+#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0)
+#define PINMUX_GPIO59__FUNC_I2S1_MCK (MTK_PIN_NO(59) | 1)
+#define PINMUX_GPIO59__FUNC_I2S3_MCK (MTK_PIN_NO(59) | 2)
+#define PINMUX_GPIO59__FUNC_DBG_MON_A27 (MTK_PIN_NO(59) | 7)
+
+#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
+#define PINMUX_GPIO60__FUNC_TDM_RX_LRCK (MTK_PIN_NO(60) | 1)
+#define PINMUX_GPIO60__FUNC_ANT_SEL3 (MTK_PIN_NO(60) | 2)
+#define PINMUX_GPIO60__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(60) | 5)
+
+#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
+#define PINMUX_GPIO61__FUNC_TDM_RX_BCK (MTK_PIN_NO(61) | 1)
+#define PINMUX_GPIO61__FUNC_ANT_SEL4 (MTK_PIN_NO(61) | 2)
+#define PINMUX_GPIO61__FUNC_SPINOR_CK (MTK_PIN_NO(61) | 4)
+#define PINMUX_GPIO61__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(61) | 5)
+
+#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
+#define PINMUX_GPIO62__FUNC_TDM_RX_MCK (MTK_PIN_NO(62) | 1)
+#define PINMUX_GPIO62__FUNC_ANT_SEL5 (MTK_PIN_NO(62) | 2)
+#define PINMUX_GPIO62__FUNC_SPINOR_CS (MTK_PIN_NO(62) | 4)
+#define PINMUX_GPIO62__FUNC_CONN_MCU_TDI (MTK_PIN_NO(62) | 5)
+
+#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
+#define PINMUX_GPIO63__FUNC_TDM_RX_DATA0 (MTK_PIN_NO(63) | 1)
+#define PINMUX_GPIO63__FUNC_ANT_SEL6 (MTK_PIN_NO(63) | 2)
+#define PINMUX_GPIO63__FUNC_SPINOR_IO0 (MTK_PIN_NO(63) | 4)
+#define PINMUX_GPIO63__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(63) | 5)
+
+#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
+#define PINMUX_GPIO64__FUNC_TDM_RX_DATA1 (MTK_PIN_NO(64) | 1)
+#define PINMUX_GPIO64__FUNC_ANT_SEL7 (MTK_PIN_NO(64) | 2)
+#define PINMUX_GPIO64__FUNC_PWM0 (MTK_PIN_NO(64) | 3)
+#define PINMUX_GPIO64__FUNC_SPINOR_IO1 (MTK_PIN_NO(64) | 4)
+#define PINMUX_GPIO64__FUNC_CONN_MCU_TCK (MTK_PIN_NO(64) | 5)
+
+#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
+#define PINMUX_GPIO65__FUNC_TDM_RX_DATA2 (MTK_PIN_NO(65) | 1)
+#define PINMUX_GPIO65__FUNC_UCTS0 (MTK_PIN_NO(65) | 2)
+#define PINMUX_GPIO65__FUNC_PWM1 (MTK_PIN_NO(65) | 3)
+#define PINMUX_GPIO65__FUNC_SPINOR_IO2 (MTK_PIN_NO(65) | 4)
+#define PINMUX_GPIO65__FUNC_CONN_MCU_TDO (MTK_PIN_NO(65) | 5)
+#define PINMUX_GPIO65__FUNC_TP_UCTS1_AO (MTK_PIN_NO(65) | 6)
+#define PINMUX_GPIO65__FUNC_TP_UCTS2_AO (MTK_PIN_NO(65) | 7)
+
+#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
+#define PINMUX_GPIO66__FUNC_TDM_RX_DATA3 (MTK_PIN_NO(66) | 1)
+#define PINMUX_GPIO66__FUNC_URTS0 (MTK_PIN_NO(66) | 2)
+#define PINMUX_GPIO66__FUNC_PWM2 (MTK_PIN_NO(66) | 3)
+#define PINMUX_GPIO66__FUNC_SPINOR_IO3 (MTK_PIN_NO(66) | 4)
+#define PINMUX_GPIO66__FUNC_CONN_MCU_TMS (MTK_PIN_NO(66) | 5)
+#define PINMUX_GPIO66__FUNC_TP_URTS1_AO (MTK_PIN_NO(66) | 6)
+#define PINMUX_GPIO66__FUNC_TP_URTS2_AO (MTK_PIN_NO(66) | 7)
+
+#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
+#define PINMUX_GPIO67__FUNC_MSDC0_DSL (MTK_PIN_NO(67) | 1)
+
+#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
+#define PINMUX_GPIO68__FUNC_MSDC0_CLK (MTK_PIN_NO(68) | 1)
+
+#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
+#define PINMUX_GPIO69__FUNC_MSDC0_CMD (MTK_PIN_NO(69) | 1)
+
+#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
+#define PINMUX_GPIO70__FUNC_MSDC0_RSTB (MTK_PIN_NO(70) | 1)
+
+#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
+#define PINMUX_GPIO71__FUNC_MSDC0_DAT0 (MTK_PIN_NO(71) | 1)
+
+#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
+#define PINMUX_GPIO72__FUNC_MSDC0_DAT1 (MTK_PIN_NO(72) | 1)
+
+#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
+#define PINMUX_GPIO73__FUNC_MSDC0_DAT2 (MTK_PIN_NO(73) | 1)
+
+#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
+#define PINMUX_GPIO74__FUNC_MSDC0_DAT3 (MTK_PIN_NO(74) | 1)
+
+#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
+#define PINMUX_GPIO75__FUNC_MSDC0_DAT4 (MTK_PIN_NO(75) | 1)
+
+#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
+#define PINMUX_GPIO76__FUNC_MSDC0_DAT5 (MTK_PIN_NO(76) | 1)
+
+#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
+#define PINMUX_GPIO77__FUNC_MSDC0_DAT6 (MTK_PIN_NO(77) | 1)
+
+#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
+#define PINMUX_GPIO78__FUNC_MSDC0_DAT7 (MTK_PIN_NO(78) | 1)
+
+#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
+#define PINMUX_GPIO79__FUNC_KPCOL0 (MTK_PIN_NO(79) | 1)
+
+#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
+#define PINMUX_GPIO80__FUNC_KPCOL1 (MTK_PIN_NO(80) | 1)
+#define PINMUX_GPIO80__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(80) | 2)
+#define PINMUX_GPIO80__FUNC_PWM0 (MTK_PIN_NO(80) | 3)
+#define PINMUX_GPIO80__FUNC_CLKM0 (MTK_PIN_NO(80) | 4)
+
+#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
+#define PINMUX_GPIO81__FUNC_KPROW0 (MTK_PIN_NO(81) | 1)
+#define PINMUX_GPIO81__FUNC_PWM1 (MTK_PIN_NO(81) | 3)
+#define PINMUX_GPIO81__FUNC_CLKM1 (MTK_PIN_NO(81) | 4)
+
+#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
+#define PINMUX_GPIO82__FUNC_KPROW1 (MTK_PIN_NO(82) | 1)
+#define PINMUX_GPIO82__FUNC_PWM2 (MTK_PIN_NO(82) | 3)
+#define PINMUX_GPIO82__FUNC_CLKM2 (MTK_PIN_NO(82) | 4)
+
+#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
+#define PINMUX_GPIO83__FUNC_AP_GOOD (MTK_PIN_NO(83) | 1)
+#define PINMUX_GPIO83__FUNC_GPS_PPS (MTK_PIN_NO(83) | 2)
+#define PINMUX_GPIO83__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(83) | 4)
+#define PINMUX_GPIO83__FUNC_DBG_MON_A28 (MTK_PIN_NO(83) | 7)
+
+#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
+#define PINMUX_GPIO84__FUNC_MSDC1_CLK (MTK_PIN_NO(84) | 1)
+#define PINMUX_GPIO84__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(84) | 2)
+#define PINMUX_GPIO84__FUNC_UDI_TCK (MTK_PIN_NO(84) | 4)
+#define PINMUX_GPIO84__FUNC_CONN_DSP_JCK (MTK_PIN_NO(84) | 5)
+#define PINMUX_GPIO84__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(84) | 6)
+#define PINMUX_GPIO84__FUNC_DFD_TCK_XI (MTK_PIN_NO(84) | 7)
+
+#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0)
+#define PINMUX_GPIO85__FUNC_MSDC1_CMD (MTK_PIN_NO(85) | 1)
+#define PINMUX_GPIO85__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(85) | 2)
+#define PINMUX_GPIO85__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(85) | 3)
+#define PINMUX_GPIO85__FUNC_UDI_TMS (MTK_PIN_NO(85) | 4)
+#define PINMUX_GPIO85__FUNC_CONN_DSP_JMS (MTK_PIN_NO(85) | 5)
+#define PINMUX_GPIO85__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(85) | 6)
+#define PINMUX_GPIO85__FUNC_DFD_TMS (MTK_PIN_NO(85) | 7)
+
+#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0)
+#define PINMUX_GPIO86__FUNC_MSDC1_DAT0 (MTK_PIN_NO(86) | 1)
+#define PINMUX_GPIO86__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(86) | 2)
+#define PINMUX_GPIO86__FUNC_UDI_TDI (MTK_PIN_NO(86) | 4)
+#define PINMUX_GPIO86__FUNC_CONN_DSP_JDI (MTK_PIN_NO(86) | 5)
+#define PINMUX_GPIO86__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(86) | 6)
+#define PINMUX_GPIO86__FUNC_DFD_TDI (MTK_PIN_NO(86) | 7)
+
+#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0)
+#define PINMUX_GPIO87__FUNC_MSDC1_DAT1 (MTK_PIN_NO(87) | 1)
+#define PINMUX_GPIO87__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(87) | 2)
+#define PINMUX_GPIO87__FUNC_UDI_TDO (MTK_PIN_NO(87) | 4)
+#define PINMUX_GPIO87__FUNC_CONN_DSP_JDO (MTK_PIN_NO(87) | 5)
+#define PINMUX_GPIO87__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(87) | 6)
+#define PINMUX_GPIO87__FUNC_DFD_TDO (MTK_PIN_NO(87) | 7)
+
+#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0)
+#define PINMUX_GPIO88__FUNC_MSDC1_DAT2 (MTK_PIN_NO(88) | 1)
+#define PINMUX_GPIO88__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(88) | 2)
+#define PINMUX_GPIO88__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(88) | 3)
+#define PINMUX_GPIO88__FUNC_UDI_NTRST (MTK_PIN_NO(88) | 4)
+#define PINMUX_GPIO88__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(88) | 5)
+#define PINMUX_GPIO88__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(88) | 6)
+
+#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0)
+#define PINMUX_GPIO89__FUNC_MSDC1_DAT3 (MTK_PIN_NO(89) | 1)
+#define PINMUX_GPIO89__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(89) | 5)
+
+#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0)
+#define PINMUX_GPIO90__FUNC_IDDIG_P0 (MTK_PIN_NO(90) | 1)
+#define PINMUX_GPIO90__FUNC_PGD_HV_HSC_PWR4 (MTK_PIN_NO(90) | 4)
+#define PINMUX_GPIO90__FUNC_GDU_SUM_TROOP2_2 (MTK_PIN_NO(90) | 5)
+
+#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0)
+#define PINMUX_GPIO91__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(91) | 1)
+#define PINMUX_GPIO91__FUNC_PGD_HV_HSC_PWR5 (MTK_PIN_NO(91) | 4)
+#define PINMUX_GPIO91__FUNC_GDU_TROOPS_DET0 (MTK_PIN_NO(91) | 5)
+
+#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0)
+#define PINMUX_GPIO92__FUNC_VBUS_VALID_P0 (MTK_PIN_NO(92) | 1)
+#define PINMUX_GPIO92__FUNC_PGD_DA_EFUSE_RDY (MTK_PIN_NO(92) | 4)
+#define PINMUX_GPIO92__FUNC_GDU_TROOPS_DET1 (MTK_PIN_NO(92) | 5)
+
+#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0)
+#define PINMUX_GPIO93__FUNC_IDDIG_P1 (MTK_PIN_NO(93) | 1)
+#define PINMUX_GPIO93__FUNC_PWM0 (MTK_PIN_NO(93) | 2)
+#define PINMUX_GPIO93__FUNC_CLKM0 (MTK_PIN_NO(93) | 3)
+#define PINMUX_GPIO93__FUNC_PGD_DA_EFUSE_RDY_PRE (MTK_PIN_NO(93) | 4)
+#define PINMUX_GPIO93__FUNC_GDU_TROOPS_DET2 (MTK_PIN_NO(93) | 5)
+
+#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0)
+#define PINMUX_GPIO94__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(94) | 1)
+#define PINMUX_GPIO94__FUNC_PWM1 (MTK_PIN_NO(94) | 2)
+#define PINMUX_GPIO94__FUNC_CLKM1 (MTK_PIN_NO(94) | 3)
+#define PINMUX_GPIO94__FUNC_PGD_DA_PWRGD_RESET (MTK_PIN_NO(94) | 4)
+
+#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
+#define PINMUX_GPIO95__FUNC_VBUS_VALID_P1 (MTK_PIN_NO(95) | 1)
+#define PINMUX_GPIO95__FUNC_PWM2 (MTK_PIN_NO(95) | 2)
+#define PINMUX_GPIO95__FUNC_CLKM2 (MTK_PIN_NO(95) | 3)
+#define PINMUX_GPIO95__FUNC_PGD_DA_PWRGD_ENB (MTK_PIN_NO(95) | 4)
+
+#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
+#define PINMUX_GPIO96__FUNC_DSI_TE (MTK_PIN_NO(96) | 1)
+#define PINMUX_GPIO96__FUNC_DBG_MON_A29 (MTK_PIN_NO(96) | 7)
+
+#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
+#define PINMUX_GPIO97__FUNC_DISP_PWM (MTK_PIN_NO(97) | 1)
+#define PINMUX_GPIO97__FUNC_DBG_MON_A30 (MTK_PIN_NO(97) | 7)
+
+#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
+#define PINMUX_GPIO98__FUNC_LCM_RST (MTK_PIN_NO(98) | 1)
+
+#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
+#define PINMUX_GPIO99__FUNC_DPI_PCLK (MTK_PIN_NO(99) | 1)
+#define PINMUX_GPIO99__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(99) | 2)
+#define PINMUX_GPIO99__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(99) | 3)
+#define PINMUX_GPIO99__FUNC_ANT_SEL0 (MTK_PIN_NO(99) | 5)
+#define PINMUX_GPIO99__FUNC_TP_GPIO0_AO (MTK_PIN_NO(99) | 6)
+#define PINMUX_GPIO99__FUNC_PGD_LV_LSC_PWR0 (MTK_PIN_NO(99) | 7)
+
+#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
+#define PINMUX_GPIO100__FUNC_DPI_VSYNC (MTK_PIN_NO(100) | 1)
+#define PINMUX_GPIO100__FUNC_KPCOL2 (MTK_PIN_NO(100) | 2)
+#define PINMUX_GPIO100__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(100) | 3)
+#define PINMUX_GPIO100__FUNC_ANT_SEL1 (MTK_PIN_NO(100) | 5)
+#define PINMUX_GPIO100__FUNC_TP_GPIO1_AO (MTK_PIN_NO(100) | 6)
+#define PINMUX_GPIO100__FUNC_PGD_LV_LSC_PWR1 (MTK_PIN_NO(100) | 7)
+
+#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
+#define PINMUX_GPIO101__FUNC_DPI_HSYNC (MTK_PIN_NO(101) | 1)
+#define PINMUX_GPIO101__FUNC_KPROW2 (MTK_PIN_NO(101) | 2)
+#define PINMUX_GPIO101__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(101) | 3)
+#define PINMUX_GPIO101__FUNC_ANT_SEL2 (MTK_PIN_NO(101) | 5)
+#define PINMUX_GPIO101__FUNC_TP_GPIO2_AO (MTK_PIN_NO(101) | 6)
+#define PINMUX_GPIO101__FUNC_PGD_LV_LSC_PWR2 (MTK_PIN_NO(101) | 7)
+
+#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
+#define PINMUX_GPIO102__FUNC_DPI_DE (MTK_PIN_NO(102) | 1)
+#define PINMUX_GPIO102__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(102) | 3)
+#define PINMUX_GPIO102__FUNC_ANT_SEL3 (MTK_PIN_NO(102) | 5)
+#define PINMUX_GPIO102__FUNC_TP_GPIO3_AO (MTK_PIN_NO(102) | 6)
+#define PINMUX_GPIO102__FUNC_PGD_LV_LSC_PWR3 (MTK_PIN_NO(102) | 7)
+
+#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
+#define PINMUX_GPIO103__FUNC_DPI_DATA0 (MTK_PIN_NO(103) | 1)
+#define PINMUX_GPIO103__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(103) | 3)
+#define PINMUX_GPIO103__FUNC_CLKM0 (MTK_PIN_NO(103) | 4)
+#define PINMUX_GPIO103__FUNC_ANT_SEL4 (MTK_PIN_NO(103) | 5)
+#define PINMUX_GPIO103__FUNC_TP_GPIO4_AO (MTK_PIN_NO(103) | 6)
+#define PINMUX_GPIO103__FUNC_PGD_LV_LSC_PWR4 (MTK_PIN_NO(103) | 7)
+
+#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
+#define PINMUX_GPIO104__FUNC_DPI_DATA1 (MTK_PIN_NO(104) | 1)
+#define PINMUX_GPIO104__FUNC_GPS_PPS (MTK_PIN_NO(104) | 2)
+#define PINMUX_GPIO104__FUNC_UCTS2 (MTK_PIN_NO(104) | 3)
+#define PINMUX_GPIO104__FUNC_CLKM1 (MTK_PIN_NO(104) | 4)
+#define PINMUX_GPIO104__FUNC_ANT_SEL5 (MTK_PIN_NO(104) | 5)
+#define PINMUX_GPIO104__FUNC_TP_GPIO5_AO (MTK_PIN_NO(104) | 6)
+#define PINMUX_GPIO104__FUNC_PGD_LV_LSC_PWR5 (MTK_PIN_NO(104) | 7)
+
+#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
+#define PINMUX_GPIO105__FUNC_DPI_DATA2 (MTK_PIN_NO(105) | 1)
+#define PINMUX_GPIO105__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(105) | 2)
+#define PINMUX_GPIO105__FUNC_URTS2 (MTK_PIN_NO(105) | 3)
+#define PINMUX_GPIO105__FUNC_CLKM2 (MTK_PIN_NO(105) | 4)
+#define PINMUX_GPIO105__FUNC_ANT_SEL6 (MTK_PIN_NO(105) | 5)
+#define PINMUX_GPIO105__FUNC_TP_GPIO6_AO (MTK_PIN_NO(105) | 6)
+#define PINMUX_GPIO105__FUNC_PGD_LV_HSC_PWR0 (MTK_PIN_NO(105) | 7)
+
+#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
+#define PINMUX_GPIO106__FUNC_DPI_DATA3 (MTK_PIN_NO(106) | 1)
+#define PINMUX_GPIO106__FUNC_TP_UTXD1_AO (MTK_PIN_NO(106) | 2)
+#define PINMUX_GPIO106__FUNC_UTXD2 (MTK_PIN_NO(106) | 3)
+#define PINMUX_GPIO106__FUNC_PWM0 (MTK_PIN_NO(106) | 4)
+#define PINMUX_GPIO106__FUNC_ANT_SEL7 (MTK_PIN_NO(106) | 5)
+#define PINMUX_GPIO106__FUNC_TP_GPIO7_AO (MTK_PIN_NO(106) | 6)
+#define PINMUX_GPIO106__FUNC_PGD_LV_HSC_PWR1 (MTK_PIN_NO(106) | 7)
+
+#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
+#define PINMUX_GPIO107__FUNC_DPI_DATA4 (MTK_PIN_NO(107) | 1)
+#define PINMUX_GPIO107__FUNC_TP_URXD1_AO (MTK_PIN_NO(107) | 2)
+#define PINMUX_GPIO107__FUNC_URXD2 (MTK_PIN_NO(107) | 3)
+#define PINMUX_GPIO107__FUNC_PWM1 (MTK_PIN_NO(107) | 4)
+#define PINMUX_GPIO107__FUNC_GDU_SUM_TROOP0_0 (MTK_PIN_NO(107) | 6)
+#define PINMUX_GPIO107__FUNC_PGD_LV_HSC_PWR2 (MTK_PIN_NO(107) | 7)
+
+#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
+#define PINMUX_GPIO108__FUNC_DPI_DATA5 (MTK_PIN_NO(108) | 1)
+#define PINMUX_GPIO108__FUNC_TP_UCTS1_AO (MTK_PIN_NO(108) | 2)
+#define PINMUX_GPIO108__FUNC_UCTS0 (MTK_PIN_NO(108) | 3)
+#define PINMUX_GPIO108__FUNC_PWM2 (MTK_PIN_NO(108) | 4)
+#define PINMUX_GPIO108__FUNC_GDU_SUM_TROOP0_1 (MTK_PIN_NO(108) | 6)
+#define PINMUX_GPIO108__FUNC_PGD_LV_HSC_PWR3 (MTK_PIN_NO(108) | 7)
+
+#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
+#define PINMUX_GPIO109__FUNC_DPI_DATA6 (MTK_PIN_NO(109) | 1)
+#define PINMUX_GPIO109__FUNC_TP_URTS1_AO (MTK_PIN_NO(109) | 2)
+#define PINMUX_GPIO109__FUNC_URTS0 (MTK_PIN_NO(109) | 3)
+#define PINMUX_GPIO109__FUNC_I2S0_DI (MTK_PIN_NO(109) | 4)
+#define PINMUX_GPIO109__FUNC_I2S2_DI (MTK_PIN_NO(109) | 5)
+#define PINMUX_GPIO109__FUNC_GDU_SUM_TROOP0_2 (MTK_PIN_NO(109) | 6)
+#define PINMUX_GPIO109__FUNC_PGD_LV_HSC_PWR4 (MTK_PIN_NO(109) | 7)
+
+#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
+#define PINMUX_GPIO110__FUNC_DPI_DATA7 (MTK_PIN_NO(110) | 1)
+#define PINMUX_GPIO110__FUNC_TP_UCTS2_AO (MTK_PIN_NO(110) | 2)
+#define PINMUX_GPIO110__FUNC_UCTS1 (MTK_PIN_NO(110) | 3)
+#define PINMUX_GPIO110__FUNC_I2S3_BCK (MTK_PIN_NO(110) | 4)
+#define PINMUX_GPIO110__FUNC_I2S1_BCK (MTK_PIN_NO(110) | 5)
+#define PINMUX_GPIO110__FUNC_GDU_SUM_TROOP1_0 (MTK_PIN_NO(110) | 6)
+#define PINMUX_GPIO110__FUNC_PGD_LV_HSC_PWR5 (MTK_PIN_NO(110) | 7)
+
+#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
+#define PINMUX_GPIO111__FUNC_DPI_DATA8 (MTK_PIN_NO(111) | 1)
+#define PINMUX_GPIO111__FUNC_TP_URTS2_AO (MTK_PIN_NO(111) | 2)
+#define PINMUX_GPIO111__FUNC_URTS1 (MTK_PIN_NO(111) | 3)
+#define PINMUX_GPIO111__FUNC_I2S3_MCK (MTK_PIN_NO(111) | 4)
+#define PINMUX_GPIO111__FUNC_I2S1_MCK (MTK_PIN_NO(111) | 5)
+#define PINMUX_GPIO111__FUNC_GDU_SUM_TROOP1_1 (MTK_PIN_NO(111) | 6)
+#define PINMUX_GPIO111__FUNC_PGD_HV_HSC_PWR0 (MTK_PIN_NO(111) | 7)
+
+#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
+#define PINMUX_GPIO112__FUNC_DPI_DATA9 (MTK_PIN_NO(112) | 1)
+#define PINMUX_GPIO112__FUNC_TP_URXD2_AO (MTK_PIN_NO(112) | 2)
+#define PINMUX_GPIO112__FUNC_URXD1 (MTK_PIN_NO(112) | 3)
+#define PINMUX_GPIO112__FUNC_I2S3_LRCK (MTK_PIN_NO(112) | 4)
+#define PINMUX_GPIO112__FUNC_I2S1_LRCK (MTK_PIN_NO(112) | 5)
+#define PINMUX_GPIO112__FUNC_GDU_SUM_TROOP1_2 (MTK_PIN_NO(112) | 6)
+#define PINMUX_GPIO112__FUNC_PGD_HV_HSC_PWR1 (MTK_PIN_NO(112) | 7)
+
+#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
+#define PINMUX_GPIO113__FUNC_DPI_DATA10 (MTK_PIN_NO(113) | 1)
+#define PINMUX_GPIO113__FUNC_TP_UTXD2_AO (MTK_PIN_NO(113) | 2)
+#define PINMUX_GPIO113__FUNC_UTXD1 (MTK_PIN_NO(113) | 3)
+#define PINMUX_GPIO113__FUNC_I2S3_DO (MTK_PIN_NO(113) | 4)
+#define PINMUX_GPIO113__FUNC_I2S1_DO (MTK_PIN_NO(113) | 5)
+#define PINMUX_GPIO113__FUNC_GDU_SUM_TROOP2_0 (MTK_PIN_NO(113) | 6)
+#define PINMUX_GPIO113__FUNC_PGD_HV_HSC_PWR2 (MTK_PIN_NO(113) | 7)
+
+#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
+#define PINMUX_GPIO114__FUNC_DPI_DATA11 (MTK_PIN_NO(114) | 1)
+#define PINMUX_GPIO114__FUNC_GDU_SUM_TROOP2_1 (MTK_PIN_NO(114) | 6)
+#define PINMUX_GPIO114__FUNC_PGD_HV_HSC_PWR3 (MTK_PIN_NO(114) | 7)
+
+#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
+#define PINMUX_GPIO115__FUNC_PCM_CLK (MTK_PIN_NO(115) | 1)
+#define PINMUX_GPIO115__FUNC_I2S0_BCK (MTK_PIN_NO(115) | 2)
+#define PINMUX_GPIO115__FUNC_I2S2_BCK (MTK_PIN_NO(115) | 3)
+
+#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
+#define PINMUX_GPIO116__FUNC_PCM_SYNC (MTK_PIN_NO(116) | 1)
+#define PINMUX_GPIO116__FUNC_I2S0_LRCK (MTK_PIN_NO(116) | 2)
+#define PINMUX_GPIO116__FUNC_I2S2_LRCK (MTK_PIN_NO(116) | 3)
+
+#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
+#define PINMUX_GPIO117__FUNC_PCM_DI (MTK_PIN_NO(117) | 1)
+#define PINMUX_GPIO117__FUNC_I2S0_DI (MTK_PIN_NO(117) | 2)
+#define PINMUX_GPIO117__FUNC_I2S2_DI (MTK_PIN_NO(117) | 3)
+
+#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
+#define PINMUX_GPIO118__FUNC_PCM_DO (MTK_PIN_NO(118) | 1)
+#define PINMUX_GPIO118__FUNC_I2S0_MCK (MTK_PIN_NO(118) | 2)
+#define PINMUX_GPIO118__FUNC_I2S2_MCK (MTK_PIN_NO(118) | 3)
+#define PINMUX_GPIO118__FUNC_I2S3_DO (MTK_PIN_NO(118) | 4)
+#define PINMUX_GPIO118__FUNC_I2S1_DO (MTK_PIN_NO(118) | 5)
+
+#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
+#define PINMUX_GPIO119__FUNC_JTMS_SEL1 (MTK_PIN_NO(119) | 1)
+#define PINMUX_GPIO119__FUNC_UDI_TMS (MTK_PIN_NO(119) | 2)
+#define PINMUX_GPIO119__FUNC_DFD_TMS (MTK_PIN_NO(119) | 3)
+#define PINMUX_GPIO119__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(119) | 4)
+#define PINMUX_GPIO119__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(119) | 5)
+#define PINMUX_GPIO119__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(119) | 6)
+
+#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
+#define PINMUX_GPIO120__FUNC_JTCK_SEL1 (MTK_PIN_NO(120) | 1)
+#define PINMUX_GPIO120__FUNC_UDI_TCK (MTK_PIN_NO(120) | 2)
+#define PINMUX_GPIO120__FUNC_DFD_TCK_XI (MTK_PIN_NO(120) | 3)
+#define PINMUX_GPIO120__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(120) | 4)
+#define PINMUX_GPIO120__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(120) | 5)
+#define PINMUX_GPIO120__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(120) | 6)
+
+#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
+#define PINMUX_GPIO121__FUNC_JTDI_SEL1 (MTK_PIN_NO(121) | 1)
+#define PINMUX_GPIO121__FUNC_UDI_TDI (MTK_PIN_NO(121) | 2)
+#define PINMUX_GPIO121__FUNC_DFD_TDI (MTK_PIN_NO(121) | 3)
+#define PINMUX_GPIO121__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(121) | 4)
+#define PINMUX_GPIO121__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(121) | 5)
+#define PINMUX_GPIO121__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(121) | 6)
+
+#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
+#define PINMUX_GPIO122__FUNC_JTDO_SEL1 (MTK_PIN_NO(122) | 1)
+#define PINMUX_GPIO122__FUNC_UDI_TDO (MTK_PIN_NO(122) | 2)
+#define PINMUX_GPIO122__FUNC_DFD_TDO (MTK_PIN_NO(122) | 3)
+#define PINMUX_GPIO122__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(122) | 4)
+#define PINMUX_GPIO122__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(122) | 5)
+#define PINMUX_GPIO122__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(122) | 6)
+
+#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
+#define PINMUX_GPIO123__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(123) | 1)
+#define PINMUX_GPIO123__FUNC_UDI_NTRST (MTK_PIN_NO(123) | 2)
+#define PINMUX_GPIO123__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(123) | 4)
+#define PINMUX_GPIO123__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(123) | 5)
+#define PINMUX_GPIO123__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(123) | 6)
+
+#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
+#define PINMUX_GPIO124__FUNC_CMMCLK0 (MTK_PIN_NO(124) | 1)
+#define PINMUX_GPIO124__FUNC_CLKM0 (MTK_PIN_NO(124) | 2)
+#define PINMUX_GPIO124__FUNC_PWM0 (MTK_PIN_NO(124) | 3)
+
+#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
+#define PINMUX_GPIO125__FUNC_CMMCLK1 (MTK_PIN_NO(125) | 1)
+#define PINMUX_GPIO125__FUNC_CLKM1 (MTK_PIN_NO(125) | 2)
+#define PINMUX_GPIO125__FUNC_PWM1 (MTK_PIN_NO(125) | 3)
+#define PINMUX_GPIO125__FUNC_DBG_MON_B0 (MTK_PIN_NO(125) | 7)
+
+#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
+#define PINMUX_GPIO126__FUNC_CMMCLK2 (MTK_PIN_NO(126) | 1)
+#define PINMUX_GPIO126__FUNC_CLKM2 (MTK_PIN_NO(126) | 2)
+#define PINMUX_GPIO126__FUNC_PWM2 (MTK_PIN_NO(126) | 3)
+#define PINMUX_GPIO126__FUNC_DBG_MON_B1 (MTK_PIN_NO(126) | 7)
+
+#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0)
+#define PINMUX_GPIO127__FUNC_SCL0 (MTK_PIN_NO(127) | 1)
+#define PINMUX_GPIO127__FUNC_SCP_SCL0 (MTK_PIN_NO(127) | 4)
+#define PINMUX_GPIO127__FUNC_SCP_SCL1 (MTK_PIN_NO(127) | 5)
+
+#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0)
+#define PINMUX_GPIO128__FUNC_SDA0 (MTK_PIN_NO(128) | 1)
+#define PINMUX_GPIO128__FUNC_SCP_SDA0 (MTK_PIN_NO(128) | 4)
+#define PINMUX_GPIO128__FUNC_SCP_SDA1 (MTK_PIN_NO(128) | 5)
+
+#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0)
+#define PINMUX_GPIO129__FUNC_SCL1 (MTK_PIN_NO(129) | 1)
+#define PINMUX_GPIO129__FUNC_SCP_SCL0 (MTK_PIN_NO(129) | 4)
+#define PINMUX_GPIO129__FUNC_SCP_SCL1 (MTK_PIN_NO(129) | 5)
+#define PINMUX_GPIO129__FUNC_DBG_MON_B4 (MTK_PIN_NO(129) | 7)
+
+#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0)
+#define PINMUX_GPIO130__FUNC_SDA1 (MTK_PIN_NO(130) | 1)
+#define PINMUX_GPIO130__FUNC_SCP_SDA0 (MTK_PIN_NO(130) | 4)
+#define PINMUX_GPIO130__FUNC_SCP_SDA1 (MTK_PIN_NO(130) | 5)
+#define PINMUX_GPIO130__FUNC_DBG_MON_B5 (MTK_PIN_NO(130) | 7)
+
+#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0)
+#define PINMUX_GPIO131__FUNC_SCL2 (MTK_PIN_NO(131) | 1)
+#define PINMUX_GPIO131__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(131) | 2)
+#define PINMUX_GPIO131__FUNC_CONN_UART0_TXD (MTK_PIN_NO(131) | 3)
+#define PINMUX_GPIO131__FUNC_SCP_SCL0 (MTK_PIN_NO(131) | 4)
+#define PINMUX_GPIO131__FUNC_SCP_SCL1 (MTK_PIN_NO(131) | 5)
+#define PINMUX_GPIO131__FUNC_DBG_MON_B6 (MTK_PIN_NO(131) | 7)
+
+#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0)
+#define PINMUX_GPIO132__FUNC_SDA2 (MTK_PIN_NO(132) | 1)
+#define PINMUX_GPIO132__FUNC_SSPM_URXD_AO (MTK_PIN_NO(132) | 2)
+#define PINMUX_GPIO132__FUNC_CONN_UART0_RXD (MTK_PIN_NO(132) | 3)
+#define PINMUX_GPIO132__FUNC_SCP_SDA0 (MTK_PIN_NO(132) | 4)
+#define PINMUX_GPIO132__FUNC_SCP_SDA1 (MTK_PIN_NO(132) | 5)
+#define PINMUX_GPIO132__FUNC_DBG_MON_B7 (MTK_PIN_NO(132) | 7)
+
+#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0)
+#define PINMUX_GPIO133__FUNC_SCL3 (MTK_PIN_NO(133) | 1)
+#define PINMUX_GPIO133__FUNC_SCP_SCL0 (MTK_PIN_NO(133) | 4)
+#define PINMUX_GPIO133__FUNC_SCP_SCL1 (MTK_PIN_NO(133) | 5)
+#define PINMUX_GPIO133__FUNC_DBG_MON_B8 (MTK_PIN_NO(133) | 7)
+
+#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0)
+#define PINMUX_GPIO134__FUNC_SDA3 (MTK_PIN_NO(134) | 1)
+#define PINMUX_GPIO134__FUNC_GPS_PPS (MTK_PIN_NO(134) | 3)
+#define PINMUX_GPIO134__FUNC_SCP_SDA0 (MTK_PIN_NO(134) | 4)
+#define PINMUX_GPIO134__FUNC_SCP_SDA1 (MTK_PIN_NO(134) | 5)
+#define PINMUX_GPIO134__FUNC_DBG_MON_B9 (MTK_PIN_NO(134) | 7)
+
+#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0)
+#define PINMUX_GPIO135__FUNC_SCL4 (MTK_PIN_NO(135) | 1)
+#define PINMUX_GPIO135__FUNC_TP_UTXD1_AO (MTK_PIN_NO(135) | 2)
+#define PINMUX_GPIO135__FUNC_UTXD1 (MTK_PIN_NO(135) | 3)
+#define PINMUX_GPIO135__FUNC_SCP_SCL0 (MTK_PIN_NO(135) | 4)
+#define PINMUX_GPIO135__FUNC_SCP_SCL1 (MTK_PIN_NO(135) | 5)
+#define PINMUX_GPIO135__FUNC_DBG_MON_B10 (MTK_PIN_NO(135) | 7)
+
+#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0)
+#define PINMUX_GPIO136__FUNC_SDA4 (MTK_PIN_NO(136) | 1)
+#define PINMUX_GPIO136__FUNC_TP_URXD1_AO (MTK_PIN_NO(136) | 2)
+#define PINMUX_GPIO136__FUNC_URXD1 (MTK_PIN_NO(136) | 3)
+#define PINMUX_GPIO136__FUNC_SCP_SDA0 (MTK_PIN_NO(136) | 4)
+#define PINMUX_GPIO136__FUNC_SCP_SDA1 (MTK_PIN_NO(136) | 5)
+#define PINMUX_GPIO136__FUNC_DBG_MON_B11 (MTK_PIN_NO(136) | 7)
+
+#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0)
+#define PINMUX_GPIO137__FUNC_SCL5 (MTK_PIN_NO(137) | 1)
+#define PINMUX_GPIO137__FUNC_UTXD2 (MTK_PIN_NO(137) | 2)
+#define PINMUX_GPIO137__FUNC_UCTS1 (MTK_PIN_NO(137) | 3)
+#define PINMUX_GPIO137__FUNC_SCP_SCL0 (MTK_PIN_NO(137) | 4)
+#define PINMUX_GPIO137__FUNC_SCP_SCL1 (MTK_PIN_NO(137) | 5)
+
+#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0)
+#define PINMUX_GPIO138__FUNC_SDA5 (MTK_PIN_NO(138) | 1)
+#define PINMUX_GPIO138__FUNC_URXD2 (MTK_PIN_NO(138) | 2)
+#define PINMUX_GPIO138__FUNC_URTS1 (MTK_PIN_NO(138) | 3)
+#define PINMUX_GPIO138__FUNC_SCP_SDA0 (MTK_PIN_NO(138) | 4)
+#define PINMUX_GPIO138__FUNC_SCP_SDA1 (MTK_PIN_NO(138) | 5)
+
+#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0)
+#define PINMUX_GPIO139__FUNC_SCL6 (MTK_PIN_NO(139) | 1)
+#define PINMUX_GPIO139__FUNC_UTXD1 (MTK_PIN_NO(139) | 2)
+#define PINMUX_GPIO139__FUNC_TP_UTXD1_AO (MTK_PIN_NO(139) | 3)
+#define PINMUX_GPIO139__FUNC_SCP_SCL0 (MTK_PIN_NO(139) | 4)
+#define PINMUX_GPIO139__FUNC_SCP_SCL1 (MTK_PIN_NO(139) | 5)
+#define PINMUX_GPIO139__FUNC_DBG_MON_B12 (MTK_PIN_NO(139) | 7)
+
+#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0)
+#define PINMUX_GPIO140__FUNC_SDA6 (MTK_PIN_NO(140) | 1)
+#define PINMUX_GPIO140__FUNC_URXD1 (MTK_PIN_NO(140) | 2)
+#define PINMUX_GPIO140__FUNC_TP_URXD1_AO (MTK_PIN_NO(140) | 3)
+#define PINMUX_GPIO140__FUNC_SCP_SDA0 (MTK_PIN_NO(140) | 4)
+#define PINMUX_GPIO140__FUNC_SCP_SDA1 (MTK_PIN_NO(140) | 5)
+#define PINMUX_GPIO140__FUNC_DBG_MON_B13 (MTK_PIN_NO(140) | 7)
+
+#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0)
+#define PINMUX_GPIO141__FUNC_SCL7 (MTK_PIN_NO(141) | 1)
+#define PINMUX_GPIO141__FUNC_URTS0 (MTK_PIN_NO(141) | 2)
+#define PINMUX_GPIO141__FUNC_TP_URTS1_AO (MTK_PIN_NO(141) | 3)
+#define PINMUX_GPIO141__FUNC_SCP_SCL0 (MTK_PIN_NO(141) | 4)
+#define PINMUX_GPIO141__FUNC_SCP_SCL1 (MTK_PIN_NO(141) | 5)
+#define PINMUX_GPIO141__FUNC_UDI_TCK (MTK_PIN_NO(141) | 6)
+#define PINMUX_GPIO141__FUNC_DBG_MON_B14 (MTK_PIN_NO(141) | 7)
+
+#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0)
+#define PINMUX_GPIO142__FUNC_SDA7 (MTK_PIN_NO(142) | 1)
+#define PINMUX_GPIO142__FUNC_UCTS0 (MTK_PIN_NO(142) | 2)
+#define PINMUX_GPIO142__FUNC_TP_UCTS1_AO (MTK_PIN_NO(142) | 3)
+#define PINMUX_GPIO142__FUNC_SCP_SDA0 (MTK_PIN_NO(142) | 4)
+#define PINMUX_GPIO142__FUNC_SCP_SDA1 (MTK_PIN_NO(142) | 5)
+
+#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0)
+#define PINMUX_GPIO143__FUNC_SCL8 (MTK_PIN_NO(143) | 1)
+#define PINMUX_GPIO143__FUNC_SCP_SCL0 (MTK_PIN_NO(143) | 4)
+#define PINMUX_GPIO143__FUNC_SCP_SCL1 (MTK_PIN_NO(143) | 5)
+#define PINMUX_GPIO143__FUNC_DBG_MON_B16 (MTK_PIN_NO(143) | 7)
+
+#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0)
+#define PINMUX_GPIO144__FUNC_SDA8 (MTK_PIN_NO(144) | 1)
+#define PINMUX_GPIO144__FUNC_SCP_SDA0 (MTK_PIN_NO(144) | 4)
+#define PINMUX_GPIO144__FUNC_SCP_SDA1 (MTK_PIN_NO(144) | 5)
+#define PINMUX_GPIO144__FUNC_DBG_MON_B17 (MTK_PIN_NO(144) | 7)
+
+#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0)
+#define PINMUX_GPIO145__FUNC_SCL9 (MTK_PIN_NO(145) | 1)
+#define PINMUX_GPIO145__FUNC_CMVREF1 (MTK_PIN_NO(145) | 2)
+#define PINMUX_GPIO145__FUNC_GPS_PPS (MTK_PIN_NO(145) | 3)
+#define PINMUX_GPIO145__FUNC_SCP_SCL0 (MTK_PIN_NO(145) | 4)
+#define PINMUX_GPIO145__FUNC_SCP_SCL1 (MTK_PIN_NO(145) | 5)
+#define PINMUX_GPIO145__FUNC_DBG_MON_B18 (MTK_PIN_NO(145) | 7)
+
+#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0)
+#define PINMUX_GPIO146__FUNC_SDA9 (MTK_PIN_NO(146) | 1)
+#define PINMUX_GPIO146__FUNC_CMVREF0 (MTK_PIN_NO(146) | 2)
+#define PINMUX_GPIO146__FUNC_SCP_SDA0 (MTK_PIN_NO(146) | 4)
+#define PINMUX_GPIO146__FUNC_SCP_SDA1 (MTK_PIN_NO(146) | 5)
+#define PINMUX_GPIO146__FUNC_DBG_MON_B19 (MTK_PIN_NO(146) | 7)
+
+#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0)
+#define PINMUX_GPIO147__FUNC_CMFLASH0 (MTK_PIN_NO(147) | 1)
+#define PINMUX_GPIO147__FUNC_LVTS_SDI (MTK_PIN_NO(147) | 2)
+#define PINMUX_GPIO147__FUNC_DPI_DATA12 (MTK_PIN_NO(147) | 3)
+#define PINMUX_GPIO147__FUNC_TP_GPIO0_AO (MTK_PIN_NO(147) | 4)
+#define PINMUX_GPIO147__FUNC_ANT_SEL3 (MTK_PIN_NO(147) | 5)
+#define PINMUX_GPIO147__FUNC_DFD_TCK_XI (MTK_PIN_NO(147) | 6)
+#define PINMUX_GPIO147__FUNC_DBG_MON_B20 (MTK_PIN_NO(147) | 7)
+
+#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0)
+#define PINMUX_GPIO148__FUNC_CMFLASH1 (MTK_PIN_NO(148) | 1)
+#define PINMUX_GPIO148__FUNC_LVTS_SCF (MTK_PIN_NO(148) | 2)
+#define PINMUX_GPIO148__FUNC_DPI_DATA13 (MTK_PIN_NO(148) | 3)
+#define PINMUX_GPIO148__FUNC_TP_GPIO1_AO (MTK_PIN_NO(148) | 4)
+#define PINMUX_GPIO148__FUNC_ANT_SEL4 (MTK_PIN_NO(148) | 5)
+#define PINMUX_GPIO148__FUNC_DFD_TMS (MTK_PIN_NO(148) | 6)
+#define PINMUX_GPIO148__FUNC_DBG_MON_B21 (MTK_PIN_NO(148) | 7)
+
+#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0)
+#define PINMUX_GPIO149__FUNC_CMFLASH2 (MTK_PIN_NO(149) | 1)
+#define PINMUX_GPIO149__FUNC_CLKM0 (MTK_PIN_NO(149) | 2)
+#define PINMUX_GPIO149__FUNC_DPI_DATA14 (MTK_PIN_NO(149) | 3)
+#define PINMUX_GPIO149__FUNC_TP_GPIO2_AO (MTK_PIN_NO(149) | 4)
+#define PINMUX_GPIO149__FUNC_ANT_SEL5 (MTK_PIN_NO(149) | 5)
+#define PINMUX_GPIO149__FUNC_DFD_TDI (MTK_PIN_NO(149) | 6)
+#define PINMUX_GPIO149__FUNC_DBG_MON_B22 (MTK_PIN_NO(149) | 7)
+
+#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0)
+#define PINMUX_GPIO150__FUNC_CLKM1 (MTK_PIN_NO(150) | 2)
+#define PINMUX_GPIO150__FUNC_DPI_DATA15 (MTK_PIN_NO(150) | 3)
+#define PINMUX_GPIO150__FUNC_TP_GPIO3_AO (MTK_PIN_NO(150) | 4)
+#define PINMUX_GPIO150__FUNC_ANT_SEL6 (MTK_PIN_NO(150) | 5)
+#define PINMUX_GPIO150__FUNC_DFD_TDO (MTK_PIN_NO(150) | 6)
+#define PINMUX_GPIO150__FUNC_DBG_MON_B23 (MTK_PIN_NO(150) | 7)
+
+#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0)
+#define PINMUX_GPIO151__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(151) | 1)
+#define PINMUX_GPIO151__FUNC_CLKM2 (MTK_PIN_NO(151) | 2)
+#define PINMUX_GPIO151__FUNC_DPI_DATA16 (MTK_PIN_NO(151) | 3)
+#define PINMUX_GPIO151__FUNC_TP_GPIO4_AO (MTK_PIN_NO(151) | 4)
+#define PINMUX_GPIO151__FUNC_ANT_SEL7 (MTK_PIN_NO(151) | 5)
+#define PINMUX_GPIO151__FUNC_UDI_TMS (MTK_PIN_NO(151) | 6)
+#define PINMUX_GPIO151__FUNC_DBG_MON_B24 (MTK_PIN_NO(151) | 7)
+
+#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0)
+#define PINMUX_GPIO152__FUNC_CLKM3 (MTK_PIN_NO(152) | 2)
+#define PINMUX_GPIO152__FUNC_DPI_DATA17 (MTK_PIN_NO(152) | 3)
+#define PINMUX_GPIO152__FUNC_TP_GPIO5_AO (MTK_PIN_NO(152) | 4)
+
+#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0)
+#define PINMUX_GPIO153__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(153) | 1)
+#define PINMUX_GPIO153__FUNC_DPI_DATA18 (MTK_PIN_NO(153) | 3)
+#define PINMUX_GPIO153__FUNC_TP_GPIO6_AO (MTK_PIN_NO(153) | 4)
+#define PINMUX_GPIO153__FUNC_UDI_TDI (MTK_PIN_NO(153) | 6)
+#define PINMUX_GPIO153__FUNC_DBG_MON_B26 (MTK_PIN_NO(153) | 7)
+
+#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0)
+#define PINMUX_GPIO154__FUNC_PWM0 (MTK_PIN_NO(154) | 1)
+#define PINMUX_GPIO154__FUNC_CMVREF2 (MTK_PIN_NO(154) | 2)
+#define PINMUX_GPIO154__FUNC_DPI_DATA19 (MTK_PIN_NO(154) | 3)
+#define PINMUX_GPIO154__FUNC_TP_GPIO7_AO (MTK_PIN_NO(154) | 4)
+#define PINMUX_GPIO154__FUNC_UDI_TDO (MTK_PIN_NO(154) | 6)
+#define PINMUX_GPIO154__FUNC_DBG_MON_B27 (MTK_PIN_NO(154) | 7)
+
+#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0)
+#define PINMUX_GPIO155__FUNC_PWM1 (MTK_PIN_NO(155) | 1)
+#define PINMUX_GPIO155__FUNC_CMVREF1 (MTK_PIN_NO(155) | 2)
+#define PINMUX_GPIO155__FUNC_DPI_DATA20 (MTK_PIN_NO(155) | 3)
+#define PINMUX_GPIO155__FUNC_UDI_NTRST (MTK_PIN_NO(155) | 6)
+#define PINMUX_GPIO155__FUNC_DBG_MON_B28 (MTK_PIN_NO(155) | 7)
+
+#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0)
+#define PINMUX_GPIO156__FUNC_PWM2 (MTK_PIN_NO(156) | 1)
+#define PINMUX_GPIO156__FUNC_CMVREF0 (MTK_PIN_NO(156) | 2)
+#define PINMUX_GPIO156__FUNC_DPI_DATA21 (MTK_PIN_NO(156) | 3)
+
+#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0)
+#define PINMUX_GPIO157__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(157) | 1)
+
+#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0)
+#define PINMUX_GPIO158__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(158) | 1)
+
+#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0)
+#define PINMUX_GPIO159__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(159) | 1)
+#define PINMUX_GPIO159__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(159) | 2)
+
+#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0)
+#define PINMUX_GPIO160__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(160) | 1)
+#define PINMUX_GPIO160__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(160) | 2)
+
+#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0)
+#define PINMUX_GPIO161__FUNC_SRCLKENA0 (MTK_PIN_NO(161) | 1)
+
+#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0)
+#define PINMUX_GPIO162__FUNC_SRCLKENA1 (MTK_PIN_NO(162) | 1)
+#define PINMUX_GPIO162__FUNC_DBG_MON_A31 (MTK_PIN_NO(162) | 7)
+
+#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0)
+#define PINMUX_GPIO163__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(163) | 1)
+#define PINMUX_GPIO163__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(163) | 2)
+
+#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0)
+#define PINMUX_GPIO164__FUNC_RTC32K_CK (MTK_PIN_NO(164) | 1)
+
+#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0)
+#define PINMUX_GPIO165__FUNC_WATCHDOG (MTK_PIN_NO(165) | 1)
+
+#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0)
+#define PINMUX_GPIO166__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(166) | 1)
+#define PINMUX_GPIO166__FUNC_AUD_CLK_MISO (MTK_PIN_NO(166) | 2)
+#define PINMUX_GPIO166__FUNC_I2S1_MCK (MTK_PIN_NO(166) | 3)
+
+#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0)
+#define PINMUX_GPIO167__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(167) | 1)
+#define PINMUX_GPIO167__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(167) | 2)
+#define PINMUX_GPIO167__FUNC_I2S1_BCK (MTK_PIN_NO(167) | 3)
+
+#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0)
+#define PINMUX_GPIO168__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(168) | 1)
+#define PINMUX_GPIO168__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(168) | 2)
+#define PINMUX_GPIO168__FUNC_I2S1_LRCK (MTK_PIN_NO(168) | 3)
+
+#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0)
+#define PINMUX_GPIO169__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(169) | 1)
+#define PINMUX_GPIO169__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(169) | 2)
+#define PINMUX_GPIO169__FUNC_I2S1_DO (MTK_PIN_NO(169) | 3)
+
+#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0)
+#define PINMUX_GPIO170__FUNC_AUD_CLK_MISO (MTK_PIN_NO(170) | 1)
+#define PINMUX_GPIO170__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(170) | 2)
+#define PINMUX_GPIO170__FUNC_I2S2_MCK (MTK_PIN_NO(170) | 3)
+
+#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0)
+#define PINMUX_GPIO171__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(171) | 1)
+#define PINMUX_GPIO171__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(171) | 2)
+#define PINMUX_GPIO171__FUNC_I2S2_BCK (MTK_PIN_NO(171) | 3)
+
+#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0)
+#define PINMUX_GPIO172__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(172) | 1)
+#define PINMUX_GPIO172__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(172) | 2)
+#define PINMUX_GPIO172__FUNC_I2S2_LRCK (MTK_PIN_NO(172) | 3)
+#define PINMUX_GPIO172__FUNC_VOW_DAT_MISO (MTK_PIN_NO(172) | 4)
+
+#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0)
+#define PINMUX_GPIO173__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(173) | 1)
+#define PINMUX_GPIO173__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(173) | 2)
+#define PINMUX_GPIO173__FUNC_I2S2_DI (MTK_PIN_NO(173) | 3)
+#define PINMUX_GPIO173__FUNC_VOW_CLK_MISO (MTK_PIN_NO(173) | 4)
+
+#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0)
+#define PINMUX_GPIO174__FUNC_CONN_TOP_CLK (MTK_PIN_NO(174) | 1)
+#define PINMUX_GPIO174__FUNC_AUXIF_CLK (MTK_PIN_NO(174) | 2)
+#define PINMUX_GPIO174__FUNC_DFD_TCK_XI (MTK_PIN_NO(174) | 3)
+#define PINMUX_GPIO174__FUNC_DBG_MON_B3 (MTK_PIN_NO(174) | 7)
+
+#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0)
+#define PINMUX_GPIO175__FUNC_CONN_TOP_DATA (MTK_PIN_NO(175) | 1)
+#define PINMUX_GPIO175__FUNC_AUXIF_ST (MTK_PIN_NO(175) | 2)
+#define PINMUX_GPIO175__FUNC_DFD_TMS (MTK_PIN_NO(175) | 3)
+#define PINMUX_GPIO175__FUNC_DBG_MON_B15 (MTK_PIN_NO(175) | 7)
+
+#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0)
+#define PINMUX_GPIO176__FUNC_CONN_BT_CLK (MTK_PIN_NO(176) | 1)
+#define PINMUX_GPIO176__FUNC_DFD_TDI (MTK_PIN_NO(176) | 3)
+#define PINMUX_GPIO176__FUNC_DBG_MON_B2 (MTK_PIN_NO(176) | 7)
+
+#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0)
+#define PINMUX_GPIO177__FUNC_CONN_BT_DATA (MTK_PIN_NO(177) | 1)
+#define PINMUX_GPIO177__FUNC_DFD_TDO (MTK_PIN_NO(177) | 3)
+
+#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0)
+#define PINMUX_GPIO178__FUNC_CONN_HRST_B (MTK_PIN_NO(178) | 1)
+#define PINMUX_GPIO178__FUNC_UDI_TMS (MTK_PIN_NO(178) | 3)
+#define PINMUX_GPIO178__FUNC_DBG_MON_B25 (MTK_PIN_NO(178) | 7)
+
+#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0)
+#define PINMUX_GPIO179__FUNC_CONN_WB_PTA (MTK_PIN_NO(179) | 1)
+#define PINMUX_GPIO179__FUNC_UDI_TCK (MTK_PIN_NO(179) | 3)
+#define PINMUX_GPIO179__FUNC_DBG_MON_B29 (MTK_PIN_NO(179) | 7)
+
+#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0)
+#define PINMUX_GPIO180__FUNC_CONN_WF_CTRL0 (MTK_PIN_NO(180) | 1)
+#define PINMUX_GPIO180__FUNC_UDI_TDI (MTK_PIN_NO(180) | 3)
+
+#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0)
+#define PINMUX_GPIO181__FUNC_CONN_WF_CTRL1 (MTK_PIN_NO(181) | 1)
+#define PINMUX_GPIO181__FUNC_UDI_TDO (MTK_PIN_NO(181) | 3)
+
+#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0)
+#define PINMUX_GPIO182__FUNC_CONN_WF_CTRL2 (MTK_PIN_NO(182) | 1)
+#define PINMUX_GPIO182__FUNC_UDI_NTRST (MTK_PIN_NO(182) | 3)
+
+#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0)
+#define PINMUX_GPIO183__FUNC_SPMI_SCL (MTK_PIN_NO(183) | 1)
+
+#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0)
+#define PINMUX_GPIO184__FUNC_SPMI_SDA (MTK_PIN_NO(184) | 1)
+
+#endif /* __MT8168-PINFUNC_H */
-- 
2.25.1



From conleylee at foxmail.com  Sun Jan  9 23:47:02 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Mon, 10 Jan 2022 15:47:02 +0800
Subject: [PATCH v1] sun4i-emac.c: enable emac tx dma
In-Reply-To: <YdtJTQJJ4aEUcp/D@Red>
References: <YdLhQjUTobcLq73j@Red>
 <tencent_E4BA4D6105A46CCC1E8AEF48057EA5FE5B08@qq.com>
 <YdtJTQJJ4aEUcp/D@Red>
Message-ID: <tencent_15A7824636308FBA779482A8D296ADB0A607@qq.com>

On 01/09/22 at 09:45??, Corentin Labbe wrote:
> Date: Sun, 9 Jan 2022 21:45:01 +0100
> From: Corentin Labbe <clabbe.montjoie at gmail.com>
> To: conleylee at foxmail.com
> Cc: davem at davemloft.net, mripard at kernel.org, wens at csie.org,
>  jernej.skrabec at gmail.com, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-sunxi at lists.linux.dev,
>  linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v1] sun4i-emac.c: enable emac tx dma
> 
> Le Sun, Jan 09, 2022 at 05:17:55PM +0800, conleylee at foxmail.com a ?crit :
> > From: conley <conleylee at foxmail.com>
> > 
> > Hello
> > I am reading the R40 user manual and trying to create a new path to enable
> > emac tx dma channel. According to the figure 8-21(TX Operation Diagram),
> > I try to enable emac tx dma channel by the follow steps:
> > 1. enable tx dma mode
> > 2. set packet lengths
> > 2. move data from skb to tx fifo by using dma in xmit function.
> > 3. start transfer from tx fifo to phy in dma tx done callback
> > 
> > But it doesn't work. emac tx interrupt and dma finished interrupt are
> > raised, but no packets are transmitted (I test it by tcpdump).
> > Do you know how to configure the emac tx dma correctly? Thanks ~
> > 
> 
> Hello
> 
> Here are my thoughts to help you:
> - Your email is not a real patch, but an ask for help, so you should not use [ PATCH ] in the subject.
> - If it was a patch, "v1" is not necessary
> - Your patch below is doing too many unrelated different things, it is hard to see the DMA TX enable part
> - I think you could first send a preliminary patch which adds all EMAC_INT_CTL_TX_xxx which are already used by the driver (to reduce the diff)
> - Without the DTB change, it is hard to see the whole picture, did you correctly use the right dma number for an easy example.
> - Knowing also the board (and so PHY, modes etc...) could help
> - I think your priority should not to add TX, but to fix reported problems to your initial patch (build warnings/error https://marc.info/?l=linux-arm-kernel&m=164159846213585&w=2) since your work on TX will need to be applied after this.
> - For the previous point, always build test with at least 2 different 32/64 arch. And if possible a total different arch (like x86_64).
> 
> Anyway, I will try to test your patch on my a10 board
> 
> Regards
Thanks a lot for your help ~ I will submit an patch which add all
register related. By the way, the build warnings problems have been fixed
by Jakub Kicinski <kuba at kernel.org>.


From tony at atomide.com  Sun Jan  9 23:55:38 2022
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 10 Jan 2022 09:55:38 +0200
Subject: [GIT PULL] Fixes for omaps
Message-ID: <pull-1641801310-149268@atomide.com>

From: "Tony Lindgren" <tony at atomide.com>

The following changes since commit fa55b7dcdc43c1aa1ba12bca9d2dd4318c2a0dbf:

  Linux 5.16-rc1 (2021-11-14 13:56:52 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap tags/omap-for-v5.17/fixes-for-merge-window-signed

for you to fetch changes up to 31aa7056bbec0259e2ec91db7d3571f66b14f93f:

  ARM: dts: Don't use legacy clock defines for dra7 clkctrl (2021-12-22 08:28:19 +0200)

----------------------------------------------------------------
Fixes for omaps

A series of fixes for omap variants for minor issues, and a fix for a timer
regression for some omap3 beagleboard versions.

The timer fix needs to patch both the dts and the timer code because
otherwise the timer quirk handling for old dtbs will prevent the dts fix
from working.

The other changes are for issues found by automated analysis, a macasp
typo fix, and two cosmetic fixes for clocks.

----------------------------------------------------------------
Jayesh Choudhary (1):
      ARM: dts: am335x-wega: Fix typo in mcasp property rx-num-evt

Tony Lindgren (3):
      ARM: dts: Fix timer regression for beagleboard revision c
      clk: ti: Move dra7 clock devices out of the legacy section
      ARM: dts: Don't use legacy clock defines for dra7 clkctrl

Wan Jiabing (1):
      ARM: OMAP2+: hwmod: Add of_node_put() before break

Ye Guojin (1):
      ARM: OMAP2+: adjust the location of put_device() call in omapdss_init_of

 .../devicetree/bindings/arm/omap/omap.txt          |  3 ++
 arch/arm/boot/dts/Makefile                         |  1 +
 arch/arm/boot/dts/am335x-wega.dtsi                 |  2 +-
 arch/arm/boot/dts/dra7.dtsi                        | 20 ++++-----
 arch/arm/boot/dts/omap3-beagle-ab4.dts             | 47 ++++++++++++++++++++++
 arch/arm/boot/dts/omap3-beagle.dts                 | 33 ---------------
 arch/arm/mach-omap2/display.c                      |  2 +-
 arch/arm/mach-omap2/omap_hwmod.c                   |  4 +-
 drivers/clocksource/timer-ti-dm-systimer.c         |  2 +-
 include/dt-bindings/clock/dra7.h                   | 14 +++----
 10 files changed, 74 insertions(+), 54 deletions(-)
 create mode 100644 arch/arm/boot/dts/omap3-beagle-ab4.dts


From yu.tu at amlogic.com  Mon Jan 10 00:26:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:09 +0800
Subject: [PATCH 1/2] dt-bindings: serial: meson: Drop compatible = amlogic,
 meson-gx-uart.
Message-ID: <20220110082616.13474-1-yu.tu@amlogic.com>

Deprecated, don't use anymore because compatible =
amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
and G12A which have different revisions of the UART IP.
So it's split into GXBB, GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:

base-commit: 99a507a8ea28542ec196e2dd80096708e2482735
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:10 +0800
Subject: [PATCH] tty: serial: meson: Change request_irq to devm_request_irq
 and move devm_request_irq to meson_uart_probe()
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-2-yu.tu@amlogic.com>

Because an interrupt error occurs when the user opens /dev/ttyAML* but
don't close it, and then opens the same port again. This problem is
encountered in actual projects.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e41f20cba3..0dd3f5b35768 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -135,8 +135,6 @@ static void meson_uart_shutdown(struct uart_port *port)
 	unsigned long flags;
 	u32 val;
 
-	free_irq(port->irq, port);
-
 	spin_lock_irqsave(&port->lock, flags);
 
 	val = readl(port->membase + AML_UART_CONTROL);
@@ -284,7 +282,6 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret;
 
 	meson_uart_reset(port);
 
@@ -298,10 +295,7 @@ static int meson_uart_startup(struct uart_port *port)
 	val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
 	writel(val, port->membase + AML_UART_MISC);
 
-	ret = request_irq(port->irq, meson_uart_interrupt, 0,
-			  port->name, port);
-
-	return ret;
+	return 0;
 }
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
@@ -908,6 +902,14 @@ static int meson_uart_probe(struct platform_device *pdev)
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
+	ret = devm_request_irq(&pdev->dev, port->irq, meson_uart_interrupt,
+			       0, dev_name(&pdev->dev), port);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to request uart irq: %d\n",
+			ret);
+		return ret;
+	}
+
 	/* reset port before registering (and possibly registering console) */
 	meson_uart_reset(port);
 

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
prerequisite-patch-id: 7af8c81b4c2163240725e96625b1487c280f4f30
prerequisite-patch-id: 8791f6362b14e7c4ff4f85cce550f06abeb1af7a
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:11 +0800
Subject: [PATCH] tty: serial: meson: Make the bit24 and bit [26,
 27] of the UART_REG5 register writable
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-3-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7c3f30cea68e..b0551750dff8 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);

base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: 4e4d909acabcb7533da20e2207207be73454a88c
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:12 +0800
Subject: [PATCH] tty: serial: meson: meson_uart_shutdown omit clear
 AML_UART_TX_EN bit
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-4-yu.tu@amlogic.com>

This change is an improvement. The meson_uart_shutdown function
should have the opposite operation to the meson_uart_startup
function, but the meson_uart_shutdown of AML_UART_TX_EN is logically
missing.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 9b07e3534969..c17109d6d441 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -140,7 +140,7 @@ static void meson_uart_shutdown(struct uart_port *port)
 	spin_lock_irqsave(&port->lock, flags);
 
 	val = readl(port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_RX_EN;
+	val &= ~(AML_UART_RX_EN | AML_UART_TX_EN);
 	val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
prerequisite-patch-id: a44e5da7009d9b815eb87395cbd7d14e7d953a09
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:13 +0800
Subject: [PATCH] tty: serial: meson: Request the register region in
 meson_uart_probe()
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-5-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe and will make
it easier to integrate the common clock code which will require the
registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index c9a37602ffd0..99efe62a1507 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -397,24 +397,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -728,6 +715,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -749,10 +740,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)

base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:26:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:26:14 +0800
Subject: [PATCH 1/2] tty: serial: meson: The UART baud rate calculation is
 described using the common clock code.
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <20220110082616.13474-6-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);

base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
-- 
2.33.1



From clabbe.montjoie at gmail.com  Mon Jan 10 00:32:24 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 10 Jan 2022 09:32:24 +0100
Subject: [PATCH 0/2] sun4i-emac: replace magic number with marcos
In-Reply-To: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
Message-ID: <YdvvGAzD7KQlxBZo@Red>

Le Mon, Jan 10, 2022 at 03:23:07PM +0800, conleylee at foxmail.com a ?crit :
> From: conley <conleylee at foxmail.com>
> 
> - sun4i-emac.h: add register related marcos
> - sun4i-emac.c: replace magic number with marco
> 
> *** BLURB HERE ***
> 
> conley (2):
>   sun4i-emac.h: add register related marcos
>   sun4i-emac.c: replace magic number with macro
> 
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 26 ++++++++++-----------
>  drivers/net/ethernet/allwinner/sun4i-emac.h | 18 ++++++++++++++
>  2 files changed, 31 insertions(+), 13 deletions(-)
> 

Hello

The from should be your real name.
You miss commit message.
The subject should be "net: allwinner: xxxx" or "net: ethernet: sun4i-emac: xxxx"
You did a typo marcos/macros
If you add a changelog, either put it in cover letter or below "---" in patch along git stats (changelog should not be part of commit message).

I think both patch should be merged.

Regards


From yunfei.dong at mediatek.com  Mon Jan 10 00:34:27 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:27 +0800
Subject: [PATCH v4, 00/15] media: mtk-vcodec: support for MT8192 decoder
Message-ID: <20220110083442.32604-1-yunfei.dong@mediatek.com>

This series adds support for mt8192 h264/vp8/vp9 decoder drivers. Firstly, refactor
power/clock/interrupt interfaces for mt8192 is lat and core architecture.

Secondly, add new functions to get frame buffer size and resolution according
to decoder capability from scp side. Then add callback function to get/put
capture buffer in order to enable lat and core decoder in parallel. 

Then add to support MT21C compressed mode and fix v4l2-compliance fail.

Next, extract H264 request api driver to let mt8183 and mt8192 use the same
code, and adds mt8192 frame based h264 driver for stateless decoder.

Lastly, add vp8 and vp9 stateless decoder drivers.

Patches 1 to refactor power/clock/interrupt interface.
Patches 2~4 get frame buffer size and resolution according to decoder capability.
Patches 5~6 enable lat and core decode in parallel.
Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail.
patch 11 record capture queue format type.
Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder.
Patch 14~15 add vp8 and vp9 stateless decoder drivers.
----
Dependents on "Support multi hardware decode using of_platform_populate"[1].

This patches are the second part used to add mt8192 h264 decoder. And the base part is [1].

[1]https://patchwork.linuxtv.org/project/linux-media/cover/20211215061552.8523-1-yunfei.dong at mediatek.com/
---
changes compared with v3:
- remove enum mtk_chip for patch 2.
- add vp8 stateless decoder drivers for patch 14.
- add vp9 stateless decoder drivers for patch 15.
changes compared with v2:
- add new patch 11 to record capture queue format type.
- separate patch 4 according to tzung-bi's suggestion.
- re-write commit message for patch 5 according to tzung-bi's suggestion.
changes compared with v1:
- rewrite commit message for patch 12.
- rewrite cover-letter message.
---
Yunfei Dong (15):
  media: mtk-vcodec: Add vdec enable/disable hardware helpers
  media: mtk-vcodec: Using firmware type to separate different firmware
    architecture
  media: mtk-vcodec: get capture queue buffer size from scp
  media: mtk-vcodec: Read max resolution from dec_capability
  media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer
    buffered
  media: mtk-vcodec: Refactor get and put capture buffer flow
  media: mtk-vcodec: Refactor supported vdec formats and framesizes
  media: mtk-vcodec: Add format to support MT21C
  media: mtk-vcodec: disable vp8 4K capability
  media: mtk-vcodec: Fix v4l2-compliance fail
  media: mtk-vcodec: record capture queue format type
  media: mtk-vcodec: Extract H264 common code
  media: mtk-vcodec: Add h264 decoder driver for mt8192
  media: mtk-vcodec: Add vp8 decoder driver for mt8192
  media: mtk-vcodec: Add vp9 decoder driver for mt8192

 drivers/media/platform/mtk-vcodec/Makefile    |    4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   49 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |    5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  168 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |    6 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   14 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  284 ++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   40 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |    5 -
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |    6 +
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |    1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    |  311 +++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    |  254 ++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  416 +---
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  |  605 +++++
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         |  445 ++++
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 2066 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   36 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    3 +
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |   37 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      |    2 +
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |   54 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   15 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |    2 +-
 include/linux/remoteproc/mtk_scp.h            |    2 +
 25 files changed, 4248 insertions(+), 582 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:28 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:28 +0800
Subject: [PATCH v4,
 01/15] media: mtk-vcodec: Add vdec enable/disable hardware helpers
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-2-yunfei.dong@mediatek.com>

Lock, power and clock are highly coupled operations. Adds vdec
enable/disable hardware helpers and uses them.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 168 +++++++++++-------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |   6 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  20 +--
 .../platform/mtk-vcodec/vdec_msg_queue.c      |   2 +
 5 files changed, 117 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index d44894fa2f6e..fc3e272d2059 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -195,9 +195,6 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
-		if (ret < 0)
-			goto err_load_fw;
 		/*
 		 * Does nothing if firmware was already loaded.
 		 */
@@ -254,8 +251,6 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_dec_release(ctx);
 
-	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index b9f5ef979c69..c2ed79bce686 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -80,74 +80,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return -EINVAL;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int ret, i;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		enable_irq(subdev_dev->dec_irq);
-	} else {
-		pm = &vdec_dev->pm;
-		enable_irq(vdec_dev->dec_irq);
-	}
-
 	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
@@ -169,31 +126,120 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int i;
 
+	dec_clk = &pm->vdec_clk;
+	mtk_smi_larb_put(pm->larbvdec);
+	for (i = dec_clk->clk_num - 1; i >= 0; i--)
+		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+}
+
+static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+ {
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
 	if (vdec_dev->vdec_pdata->is_subdev_supported) {
 		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
+		if (subdev_dev)
+			enable_irq(subdev_dev->dec_irq);
+		else
+			mtk_v4l2_err("Failed to get hw dev\n");
+	} else {
+		enable_irq(vdec_dev->dec_irq);
+	}
+}
+
+static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			disable_irq(subdev_dev->dec_irq);
+		else
 			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		disable_irq(subdev_dev->dec_irq);
 	} else {
-		pm = &vdec_dev->pm;
 		disable_irq(vdec_dev->dec_irq);
 	}
+}
 
-	dec_clk = &pm->vdec_clk;
-	mtk_smi_larb_put(pm->larbvdec);
-	for (i = dec_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return NULL;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			return &subdev_dev->pm;
+
+		mtk_v4l2_err("Failed to get hw dev\n");
+		return NULL;
+	}
+
+	return &vdec_dev->pm;
+}
+
+static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_pw_on(pm);
+		mtk_vcodec_dec_clock_on(pm);
+	}
+}
+
+static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
+	int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_clock_off(pm);
+		mtk_vcodec_dec_pw_off(pm);
+	}
+}
+
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
+
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+		hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
+	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
+
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+		hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_off(ctx->dev, MTK_VDEC_LAT0);
+
+	mutex_unlock(&ctx->dev->dec_mutex[hw_idx]);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_disable_hardware);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index c4121df9764f..b420739b373d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -12,9 +12,7 @@
 int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 05a5b240e906..c93dd0ea3537 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -38,11 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -70,15 +68,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 	if (!ctx->drv_handle)
 		return -EIO;
 
-	mtk_vdec_lock(ctx);
-
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
-
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -103,11 +97,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return;
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	ctx->drv_handle = NULL;
 }
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index 576e08200a10..900d04fd4e66 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -212,11 +212,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
 		return;
 
 	ctx = lat_buf->ctx;
+	mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
 	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
 
 	lat_buf->core_decode(lat_buf);
 
 	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
 	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
 
 	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:37 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:37 +0800
Subject: [PATCH v4, 10/15] media: mtk-vcodec: Fix v4l2-compliance fail
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-11-yunfei.dong@mediatek.com>

Need to use default pic info when get pic info fail.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 34ee4a0092ff..75210eb829d0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -478,11 +478,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ctx->picinfo.pic_w = pix_mp->width;
 		ctx->picinfo.pic_h = pix_mp->height;
 
+		/*
+		 * If get pic info fail, need to use the default pic info params, or
+		 * v4l2-compliance will fail
+		 */
 		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
 		if (ret) {
 			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
 				     ctx->id);
-			return -EINVAL;
 		}
 
 		ctx->last_decoded_picinfo = ctx->picinfo;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:36 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:36 +0800
Subject: [PATCH v4, 09/15] media: mtk-vcodec: disable vp8 4K capability
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-10-yunfei.dong@mediatek.com>

For vp8 not support 4K, need to disable it.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 519f2b9d9b5b..34ee4a0092ff 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -532,7 +532,8 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
 		if (!(ctx->dev->dec_capability &
-				VCODEC_CAPABILITY_4K_DISABLED)) {
+				VCODEC_CAPABILITY_4K_DISABLED) &&
+				fsize->pixel_format != V4L2_PIX_FMT_VP8_FRAME) {
 			mtk_v4l2_debug(3, "4K is enabled");
 			fsize->stepwise.max_width =
 					VCODEC_DEC_4K_CODED_WIDTH;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:29 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:29 +0800
Subject: [PATCH v4,
 02/15] media: mtk-vcodec: Using firmware type to separate different
 firmware architecture
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-3-yunfei.dong@mediatek.com>

MT8173 platform use vpu firmware, mt8183/mt8192 will use scp
firmware instead, using chip name is not reasonable to separate
different firmware architecture. Using firmware type is much better.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c   |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c  |  2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h  | 13 -------------
 .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  5 -----
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c   |  6 ++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h   |  1 +
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c     |  4 ++--
 drivers/media/platform/mtk-vcodec/venc_vpu_if.c     |  2 +-
 8 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 04ca43c77e5f..7966c132be8f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -613,7 +613,6 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
-	.chip = MTK_MT8173,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23d997ac114d..5aebf88f997b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -343,7 +343,6 @@ static struct vb2_ops mtk_vdec_request_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
-	.chip = MTK_MT8183,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
@@ -362,7 +361,6 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 
 /* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
-	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 3fc747cea5c9..45d9e1be7063 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -335,13 +335,6 @@ struct mtk_vcodec_ctx {
 	struct vdec_msg_queue msg_queue;
 };
 
-enum mtk_chip {
-	MTK_MT8173,
-	MTK_MT8183,
-	MTK_MT8192,
-	MTK_MT8195,
-};
-
 /**
  * struct mtk_vdec_hw_arch - Used to separate different hardware architecture
  */
@@ -367,7 +360,6 @@ enum mtk_vdec_hw_arch {
  * @vdec_framesizes: supported video decoder frame sizes
  * @num_framesizes: count of video decoder frame sizes
  *
- * @chip: chip this decoder is compatible with
  * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
@@ -390,7 +382,6 @@ struct mtk_vcodec_dec_pdata {
 	const struct mtk_codec_framesizes *vdec_framesizes;
 	const int num_framesizes;
 
-	enum mtk_chip chip;
 	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
@@ -400,8 +391,6 @@ struct mtk_vcodec_dec_pdata {
 /**
  * struct mtk_vcodec_enc_pdata - compatible data for each IC
  *
- * @chip: chip this encoder is compatible with
- *
  * @uses_ext: whether the encoder uses the extended firmware messaging format
  * @min_bitrate: minimum supported encoding bitrate
  * @max_bitrate: maximum supported encoding bitrate
@@ -412,8 +401,6 @@ struct mtk_vcodec_dec_pdata {
  * @core_id: stand for h264 or vp8 encode index
  */
 struct mtk_vcodec_enc_pdata {
-	enum mtk_chip chip;
-
 	bool uses_ext;
 	unsigned long min_bitrate;
 	unsigned long max_bitrate;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..3ac6969c54c0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -378,7 +378,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 }
 
 static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
 	.output_formats = mtk_video_formats_output,
@@ -389,7 +388,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_vp8,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_vp8),
 	.output_formats = mtk_video_formats_output,
@@ -400,7 +398,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
-	.chip = MTK_MT8183,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -412,7 +409,6 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
-	.chip = MTK_MT8192,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -424,7 +420,6 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
-	.chip = MTK_MT8195,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
index 94b39ae5c2e1..556e54aadac9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
@@ -65,3 +65,9 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
 	return fw->ops->ipi_send(fw, id, buf, len, wait);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_send);
+
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
+{
+	return fw->type;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
index 539bb626772c..acd355961e3a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
@@ -39,5 +39,6 @@ int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
 			       const char *name, void *priv);
 int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
 			   void *buf, unsigned int len, unsigned int wait);
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
 
 #endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index c84fac52fe26..21f6d9c5a371 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -33,8 +33,8 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	 */
 	vpu->inst_id = 0xdeadbeef;
 
-	/* Firmware version field does not exist on MT8173. */
-	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
+	/* VPU firmware does not contain a version field. */
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index e7899d8a3e4e..d3570c4c177d 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -18,7 +18,7 @@ static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
 					     msg->vpu_inst_addr);
 
 	/* Firmware version field value is unspecified on MT8173. */
-	if (vpu->ctx->dev->venc_pdata->chip == MTK_MT8173)
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:42 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:42 +0800
Subject: [PATCH v4, 15/15] media: mtk-vcodec: support stateless VP9 decoding
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-16-yunfei.dong@mediatek.com>

Add support for VP9 decoding using the stateless API, as supported by MT8192.
And the drivers is lat and core architecture.

Signed-off-by: George Sun <george.sun at mediatek.com>
Co-developed-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |    1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   26 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |    1 +
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 2066 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |    4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    1 +
 6 files changed, 2096 insertions(+), 3 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index b457daf2d196..93e7a343b5b0 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
+		vdec/vdec_vp9_req_lat_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
 		vdec/vdec_h264_req_multi_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 019055a0807d..03c1c873361a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -91,13 +91,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
 		},
 		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
-	}
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS,
+			},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP9_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[4];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
+static struct mtk_video_fmt mtk_video_formats[5];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[3];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -368,6 +383,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
 	case V4L2_PIX_FMT_VP8_FRAME:
+	case V4L2_PIX_FMT_VP9_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -416,6 +432,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP9_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP9_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 63ca6458929b..24bfbd1a6b3a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -358,6 +358,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
+	MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
new file mode 100644
index 000000000000..ca93bdc77165
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
@@ -0,0 +1,2066 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: George Sun <george.sun at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* reset_frame_context defined in VP9 spec */
+#define VP9_RESET_FRAME_CONTEXT_NONE0 0
+#define VP9_RESET_FRAME_CONTEXT_NONE1 1
+#define VP9_RESET_FRAME_CONTEXT_SPEC 2
+#define VP9_RESET_FRAME_CONTEXT_ALL 3
+
+#define VP9_TILE_BUF_SIZE 4096
+#define VP9_PROB_BUF_SIZE 2560
+#define VP9_COUNTS_BUF_SIZE 16384
+
+#define FOR_EACH_COEF_PROBS_BAND(t, i, j, k) \
+	for (t = 0; t < 4; t++) \
+		for (i = 0; i < 2; i++) \
+			for (j = 0; j < 2; j++) \
+				for (k = 0; k < 6; k++)
+
+#define HDR_FLAG(x) (!!((hdr)->flags & V4L2_VP9_FRAME_FLAG_##x))
+#define LF_FLAG(x) (!!((lf)->flags & V4L2_VP9_LOOP_FILTER_FLAG_##x))
+#define SEG_FLAG(x) (!!((seg)->flags & V4L2_VP9_SEGMENTATION_FLAG_##x))
+
+/**
+ * struct vdec_vp9_slice_frame_ctx - vp9 prob tables footprint
+ */
+struct vdec_vp9_slice_frame_ctx {
+	struct {
+		__u8 probs[6][3];
+		__u8 padding[2];
+	} coef_probs[4][2][2][6];
+
+	__u8 y_mode_prob[4][16];
+	__u8 switch_interp_prob[4][16];
+	__u8 seg[32];  /* ignore */
+	__u8 comp_inter_prob[16];
+	__u8 comp_ref_prob[16];
+	__u8 single_ref_prob[5][2];
+	__u8 single_ref_prob_padding[6];
+
+	__u8 joint[3];
+	__u8 joint_padding[13];
+	struct {
+		__u8 sign;
+		__u8 classes[10];
+		__u8 padding[5];
+	} sign_classes[2];
+	struct {
+		__u8 class0[1];
+		__u8 bits[10];
+		__u8 padding[5];
+	} class0_bits[2];
+	struct {
+		__u8 class0_fp[2][3];
+		__u8 fp[3];
+		__u8 class0_hp;
+		__u8 hp;
+		__u8 padding[5];
+	} class0_fp_hp[2];
+
+	__u8 uv_mode_prob[10][16];
+	__u8 uv_mode_prob_padding[2][16];
+
+	__u8 partition_prob[16][4];
+
+	__u8 inter_mode_probs[7][4];
+	__u8 skip_probs[4];
+
+	__u8 tx_p8x8[2][4];
+	__u8 tx_p16x16[2][4];
+	__u8 tx_p32x32[2][4];
+	__u8 intra_inter_prob[8];
+};
+
+/**
+ * struct vdec_vp9_slice_frame_counts - vp9 counts tables footprint
+ */
+struct vdec_vp9_slice_frame_counts {
+	union {
+		struct {
+			__u32 band_0[3];
+			__u32 padding0[1];
+			__u32 band_1_5[5][6];
+			__u32 padding1[2];
+		} eob_branch[4][2][2];
+		__u32 eob_branch_space[256 * 4];
+	};
+
+	struct {
+		__u32 band_0[3][4];
+		__u32 band_1_5[5][6][4];
+	} coef_probs[4][2][2];
+
+	__u32 intra_inter[4][2];
+	__u32 comp_inter[5][2];
+	__u32 comp_inter_padding[2];
+	__u32 comp_ref[5][2];
+	__u32 comp_ref_padding[2];
+	__u32 single_ref[5][2][2];
+	__u32 inter_mode[7][4];
+	__u32 y_mode[4][12];
+	__u32 uv_mode[10][10];
+	__u32 partition[16][4];
+	__u32 switchable_interp[4][4];
+
+	__u32 tx_p8x8[2][2];
+	__u32 tx_p16x16[2][4];
+	__u32 tx_p32x32[2][4];
+
+	__u32 skip[3][4];
+
+	__u32 joint[4];
+
+	struct {
+		__u32 sign[2];
+		__u32 class0[2];
+		__u32 classes[12];
+		__u32 bits[10][2];
+		__u32 padding[4];
+		__u32 class0_fp[2][4];
+		__u32 fp[4];
+		__u32 class0_hp[2];
+		__u32 hp[2];
+	} mvcomp[2];
+
+	__u32 reserved[126][4];
+};
+
+/**
+ * struct vdec_vp9_slice_uncompressed_header - vp9 uncompressed header syntax
+ *                                             used for decoding
+ */
+struct vdec_vp9_slice_uncompressed_header {
+	__u8 profile;
+	__u8 last_frame_type;
+	__u8 frame_type;
+
+	__u8 last_show_frame;
+	__u8 show_frame;
+	__u8 error_resilient_mode;
+
+	__u8 bit_depth;
+	__u8 padding0[1];
+	__u16 last_frame_width;
+	__u16 last_frame_height;
+	__u16 frame_width;
+	__u16 frame_height;
+
+	__u8 intra_only;
+	__u8 reset_frame_context;
+	__u8 ref_frame_sign_bias[4];
+	__u8 allow_high_precision_mv;
+	__u8 interpolation_filter;
+
+	__u8 refresh_frame_context;
+	__u8 frame_parallel_decoding_mode;
+	__u8 frame_context_idx;
+
+	/* loop_filter_params */
+	__u8 loop_filter_level;
+	__u8 loop_filter_sharpness;
+	__u8 loop_filter_delta_enabled;
+	__s8 loop_filter_ref_deltas[4];
+	__s8 loop_filter_mode_deltas[2];
+
+	/* quantization_params */
+	__u8 base_q_idx;
+	__s8 delta_q_y_dc;
+	__s8 delta_q_uv_dc;
+	__s8 delta_q_uv_ac;
+
+	/* segmentation_params */
+	__u8 segmentation_enabled;
+	__u8 segmentation_update_map;
+	__u8 segmentation_tree_probs[7];
+	__u8 padding1[1];
+	__u8 segmentation_temporal_udpate;
+	__u8 segmentation_pred_prob[3];
+	__u8 segmentation_update_data;
+	__u8 segmentation_abs_or_delta_update;
+	__u8 feature_enabled[8];
+	__s16 feature_value[8][4];
+
+	/* tile_info */
+	__u8 tile_cols_log2;
+	__u8 tile_rows_log2;
+	__u8 padding2[2];
+
+	__u16 uncompressed_header_size;
+	__u16 header_size_in_bytes;
+
+	/* LAT OUT, CORE IN */
+	__u32 dequant[8][4];
+};
+
+/**
+ * struct vdec_vp9_slice_compressed_header - vp9 compressed header syntax
+ *                                           used for decoding.
+ */
+struct vdec_vp9_slice_compressed_header {
+	__u8 tx_mode;
+	__u8 ref_mode;
+	__u8 comp_fixed_ref;
+	__u8 comp_var_ref[2];
+	__u8 padding[3];
+};
+
+/**
+ * struct vdec_vp9_slice_tiles - vp9 tile syntax
+ */
+struct vdec_vp9_slice_tiles {
+	__u32 size[4][64];
+	__u32 mi_rows[4];
+	__u32 mi_cols[64];
+	__u8 actual_rows;
+	__u8 padding[7];
+};
+
+/**
+ * struct vdec_vp9_slice_reference - vp9 reference frame information
+ */
+struct vdec_vp9_slice_reference {
+	__u16 frame_width;
+	__u16 frame_height;
+	__u8 bit_depth;
+	__u8 subsampling_x;
+	__u8 subsampling_y;
+	__u8 padding;
+};
+
+/**
+ * struct vdec_vp9_slice_frame - vp9 syntax used for decoding
+ */
+struct vdec_vp9_slice_frame {
+	struct vdec_vp9_slice_uncompressed_header uh;
+	struct vdec_vp9_slice_compressed_header ch;
+	struct vdec_vp9_slice_tiles tiles;
+	struct vdec_vp9_slice_reference ref[3];
+};
+
+/**
+ * struct vdec_vp9_slice_init_vsi - VSI used to initialize instance
+ */
+struct vdec_vp9_slice_init_vsi {
+	unsigned int architecture;
+	unsigned int reserved;
+	uint64_t core_vsi;
+	/* default frame context's position in MicroP */
+	uint64_t default_frame_ctx;
+};
+
+/**
+ * struct vdec_vp9_slice_mem - memory address and size
+ */
+struct vdec_vp9_slice_mem {
+	union {
+		uint64_t buf;
+		dma_addr_t dma_addr;
+	};
+	union {
+		size_t size;
+		dma_addr_t dma_addr_end;
+		uint64_t padding;
+	};
+};
+
+/**
+ * struct vdec_vp9_slice_bs - input buffer for decoding
+ */
+struct vdec_vp9_slice_bs {
+	struct vdec_vp9_slice_mem buf;
+	struct vdec_vp9_slice_mem frame;
+};
+
+/**
+ * struct vdec_vp9_slice_fb - frame buffer for decoding
+ */
+struct vdec_vp9_slice_fb {
+	struct vdec_vp9_slice_mem y;
+	struct vdec_vp9_slice_mem c;
+};
+
+/**
+ * struct vdec_vp9_slice_state - decoding state
+ */
+struct vdec_vp9_slice_state {
+	int err;
+	unsigned int full;
+	unsigned int timeout;
+	unsigned int perf;
+
+	unsigned int crc[12];
+};
+
+/*
+ * struct vdec_vp9_slice_vsi - exchange decoding information
+ *                             between Main CPU and MicroP
+ * @bs          : input buffer
+ * @fb          : output buffer
+ * @ref         : 3 reference buffers
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @ube         : general buffer
+ * @trans       : trans buffer position in general buffer
+ * @err_map     : error buffer
+ * @row_info    : row info buffer
+ * @frame       : decoding syntax
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_vsi {
+	/* used in LAT stage */
+	struct vdec_vp9_slice_bs bs;
+	/* used in Core stage */
+	struct vdec_vp9_slice_fb fb;
+	struct vdec_vp9_slice_fb ref[3];
+
+	struct vdec_vp9_slice_mem mv[2];
+	struct vdec_vp9_slice_mem seg[2];
+	struct vdec_vp9_slice_mem tile;
+	struct vdec_vp9_slice_mem prob;
+	struct vdec_vp9_slice_mem counts;
+
+	/* LAT stage's output, Core stage's input */
+	struct vdec_vp9_slice_mem ube;
+	struct vdec_vp9_slice_mem trans;
+	struct vdec_vp9_slice_mem err_map;
+	struct vdec_vp9_slice_mem row_info;
+
+	/* decoding parameters */
+	struct vdec_vp9_slice_frame frame;
+
+	struct vdec_vp9_slice_state state;
+};
+
+/*
+ * struct vdec_vp9_slice_pfc - per-frame context that contains a local vsi.
+ *                             pass it from lat to core
+ * @vsi         : local vsi. copy to/from remote vsi before/after decoding
+ * @ref_idx     : reference buffer index
+ * @seq         : picture sequence
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_pfc {
+	struct vdec_vp9_slice_vsi vsi;
+
+	u64 ref_idx[3];
+
+	int seq;
+
+	/* LAT/Core CRC */
+	struct vdec_vp9_slice_state state[2];
+};
+
+/*
+ * enum vdec_vp9_slice_resolution_level
+ */
+enum vdec_vp9_slice_resolution_level {
+	VP9_RES_NONE,
+	VP9_RES_FHD,
+	VP9_RES_4K,
+	VP9_RES_8K,
+};
+
+/*
+ * struct vdec_vp9_slice_ref - picture's width & height should kept
+ *                             for later decoding as reference picture
+ */
+struct vdec_vp9_slice_ref {
+	unsigned int width;
+	unsigned int height;
+};
+
+/*
+ * struct vdec_vp9_slice_instance - represent one vp9 instance
+ * @ctx         : pointer to codec's context
+ * @vpu         : VPU instance
+ * @seq         : global picture sequence
+ * @level       : level of current resolution
+ * @width       : width of last picture
+ * @height      : height of last picture
+ * @frame_type  : frame_type of last picture
+ * @irq         : irq to Main CPU or MicroP
+ * @show_frame  : show_frame of last picture
+ * @dpb         : picture information (width/height) for reference
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @frame_ctx   : 4 frame context according to VP9 Spec
+ * @dirty       : state of each frame context
+ * @init_vsi    : vsi used for initialized VP9 instance
+ * @vsi         : vsi used for decoding/flush ...
+ * @core_vsi    : vsi used for Core stage
+ */
+struct vdec_vp9_slice_instance {
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+
+	int seq;
+
+	enum vdec_vp9_slice_resolution_level level;
+
+	/* for resolution change and get_pic_info */
+	unsigned int width;
+	unsigned int height;
+
+	/* for last_frame_type */
+	unsigned int frame_type;
+	unsigned int irq;
+
+	unsigned int show_frame;
+
+	/* maintain vp9 reference frame state */
+	struct vdec_vp9_slice_ref dpb[VB2_MAX_FRAME];
+
+	/*
+	 * normal working buffers
+	 * mv[0]/seg[0]/tile/prob/counts is used for LAT
+	 * mv[1]/seg[1] is used for CORE
+	 */
+	struct mtk_vcodec_mem mv[2];
+	struct mtk_vcodec_mem seg[2];
+	struct mtk_vcodec_mem tile;
+	struct mtk_vcodec_mem prob;
+	struct mtk_vcodec_mem counts;
+
+	/* 4 prob tables */
+	struct vdec_vp9_slice_frame_ctx frame_ctx[4];
+	unsigned char dirty[4];
+
+	/* MicroP vsi */
+	union {
+		struct vdec_vp9_slice_init_vsi *init_vsi;
+		struct vdec_vp9_slice_vsi *vsi;
+	};
+	struct vdec_vp9_slice_vsi *core_vsi;
+};
+
+/*
+ * (2, (0, (1, 3)))
+ * max level = 2
+ */
+static const signed char vdec_vp9_slice_inter_mode_tree[6] = {
+	-2, 2, 0, 4, -1, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_intra_mode_tree[18] = {
+	0, 2, -9, 4, -1, 6, 8, 12, -2, 10, -4, -5, -3, 14, -8, 16, -6, -7
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_partition_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 1 */
+static const signed char vdec_vp9_slice_switchable_interp_tree[4] = {
+	0, 2, -1, -2
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_joint_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_mv_class_tree[20] = {
+	0, 2, -1, 4, 6, 8, -2, -3, 10, 12,
+	-4, -5, -6, 14, 16, 18, -7, -8, -9, -10
+};
+
+/* max level = 0 */
+static const signed char vdec_vp9_slice_mv_class0_tree[2] = {
+	0, -1
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_fp_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/*
+ * all VP9 instances could share this default frame context.
+ */
+static struct vdec_vp9_slice_frame_ctx *vdec_vp9_slice_default_frame_ctx;
+static DEFINE_MUTEX(vdec_vp9_slice_frame_ctx_lock);
+
+static int vdec_vp9_slice_core_decode(
+	struct vdec_lat_buf *lat_buf);
+
+static int vdec_vp9_slice_init_default_frame_ctx(
+	struct vdec_vp9_slice_instance *instance)
+{
+	struct vdec_vp9_slice_frame_ctx *remote_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret = 0;
+
+	ctx = instance->ctx;
+	vsi = instance->vpu.vsi;
+	if (!ctx || !vsi) {
+		mtk_vcodec_err(instance, "invalid ctx or vsi 0x%px 0x%px\n",
+			ctx, vsi);
+		return -EINVAL;
+	}
+
+	remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+		(u32)vsi->default_frame_ctx);
+	if (!remote_frame_ctx) {
+		mtk_vcodec_err(instance, "failed to map default frame ctx\n");
+		return -EINVAL;
+	}
+
+	mtk_vcodec_debug(instance, "map default frame ctx to 0x%px\n",
+		remote_frame_ctx);
+
+	mutex_lock(&vdec_vp9_slice_frame_ctx_lock);
+
+	if (vdec_vp9_slice_default_frame_ctx)
+		goto out;
+
+	frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_KERNEL);
+	if (!frame_ctx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy_fromio(frame_ctx, remote_frame_ctx, sizeof(*frame_ctx));
+	vdec_vp9_slice_default_frame_ctx = frame_ctx;
+
+out:
+	mutex_unlock(&vdec_vp9_slice_frame_ctx_lock);
+
+	return ret;
+}
+
+static int vdec_vp9_slice_alloc_working_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi *vsi)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	enum vdec_vp9_slice_resolution_level level;
+	/* super blocks */
+	unsigned int max_sb_w;
+	unsigned int max_sb_h;
+	unsigned int max_w;
+	unsigned int max_h;
+	unsigned int w;
+	unsigned int h;
+	size_t size;
+	int ret;
+	int i;
+
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+
+	if (w > VCODEC_DEC_4K_CODED_WIDTH ||
+		h > VCODEC_DEC_4K_CODED_HEIGHT) {
+		/* 8K? */
+		return -EINVAL;
+	} else if (w > MTK_VDEC_MAX_W || h > MTK_VDEC_MAX_H) {
+		/* 4K */
+		level = VP9_RES_4K;
+		max_w = VCODEC_DEC_4K_CODED_WIDTH;
+		max_h = VCODEC_DEC_4K_CODED_HEIGHT;
+	} else {
+		/* FHD */
+		level = VP9_RES_FHD;
+		max_w = MTK_VDEC_MAX_W;
+		max_h = MTK_VDEC_MAX_H;
+	}
+
+	if (level == instance->level)
+		return 0;
+
+	mtk_vcodec_debug(instance,
+		"resolution level changed, from %u to %u, %ux%u",
+		instance->level, level, w, h);
+
+	max_sb_w = DIV_ROUND_UP(max_w, 64);
+	max_sb_h = DIV_ROUND_UP(max_h, 64);
+	ret = -ENOMEM;
+
+	/*
+	 * Lat-flush must wait core idle, otherwise core will
+	 * use released buffers
+	 */
+
+	size = (max_sb_w * max_sb_h + 2) * 576;
+	for (i = 0; i < 2; i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+		instance->mv[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->mv[i]))
+			goto err;
+	}
+
+	size = (max_sb_w * max_sb_h * 32) + 256;
+	for (i = 0; i < 2; i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+		instance->seg[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->seg[i]))
+			goto err;
+	}
+
+	if (!instance->tile.va) {
+		instance->tile.size = VP9_TILE_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->tile))
+			goto err;
+	}
+
+	if (!instance->prob.va) {
+		instance->prob.size = VP9_PROB_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->prob))
+			goto err;
+	}
+
+	if (!instance->counts.va) {
+		instance->counts.size = VP9_COUNTS_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->counts))
+			goto err;
+	}
+
+	instance->level = level;
+	return 0;
+
+err:
+	instance->level = VP9_RES_NONE;
+	return ret;
+}
+
+static void vdec_vp9_slice_free_working_buffer(
+	struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(instance->mv); i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+	}
+	for (i = 0; i < ARRAY_SIZE(instance->seg); i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+	}
+	if (instance->tile.va)
+		mtk_vcodec_mem_free(ctx, &instance->tile);
+	if (instance->prob.va)
+		mtk_vcodec_mem_free(ctx, &instance->prob);
+	if (instance->counts.va)
+		mtk_vcodec_mem_free(ctx, &instance->counts);
+
+	instance->level = VP9_RES_NONE;
+}
+
+static void vdec_vp9_slice_vsi_from_remote(
+	struct vdec_vp9_slice_vsi *vsi,
+	struct vdec_vp9_slice_vsi *remote_vsi,
+	int skip)
+{
+	struct vdec_vp9_slice_frame *rf;
+	struct vdec_vp9_slice_frame *f;
+
+	/*
+	 * compressed header
+	 * dequant
+	 * buffer position
+	 * decode state
+	 */
+	if (!skip) {
+		rf = &remote_vsi->frame;
+		f = &vsi->frame;
+		memcpy_fromio(&f->ch, &rf->ch, sizeof(f->ch));
+		memcpy_fromio(&f->uh.dequant, &rf->uh.dequant,
+			sizeof(f->uh.dequant));
+		memcpy_fromio(&vsi->trans, &remote_vsi->trans,
+			sizeof(vsi->trans));
+	}
+
+	memcpy_fromio(&vsi->state, &remote_vsi->state, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_vsi_to_remote(
+	struct vdec_vp9_slice_vsi *vsi,
+	struct vdec_vp9_slice_vsi *remote_vsi)
+{
+	memcpy_toio(remote_vsi, vsi, sizeof(*vsi));
+}
+
+static int vdec_vp9_slice_tile_offset(int idx,
+	int mi_num, int tile_log2)
+{
+	int sbs = (mi_num + 7) >> 3;
+	int offset = ((idx * sbs) >> tile_log2) << 3;
+	return offset < mi_num ? offset : mi_num;
+}
+
+static int vdec_vp9_slice_setup_lat_from_src_buf(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx);
+	if (!src)
+		return -EINVAL;
+
+	dst = &lat_buf->ts_info;
+	v4l2_m2m_buf_copy_metadata(src, dst, true);
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_hdr(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_uncompressed_header *uh,
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int i;
+
+	uh->profile = hdr->profile;
+	uh->last_frame_type = instance->frame_type;
+	uh->frame_type = !HDR_FLAG(KEY_FRAME);
+	uh->last_show_frame = instance->show_frame;
+	uh->show_frame = HDR_FLAG(SHOW_FRAME);
+	uh->error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	uh->bit_depth = hdr->bit_depth;
+	uh->last_frame_width = instance->width;
+	uh->last_frame_height = instance->height;
+	uh->frame_width = hdr->frame_width_minus_1 + 1;
+	uh->frame_height = hdr->frame_height_minus_1 + 1;
+	uh->intra_only = HDR_FLAG(INTRA_ONLY);
+	/* map v4l2 enum to values defined in VP9 spec for firmware */
+	switch (hdr->reset_frame_context) {
+	case V4L2_VP9_RESET_FRAME_CTX_NONE:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_SPEC:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_SPEC;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_ALL:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_ALL;
+		break;
+	default:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	}
+	/*
+	 * ref_frame_sign_bias specifies the intended direction
+	 * of the motion vector in time for each reference frame.
+	 * - INTRA_FRAME = 0,
+	 * - LAST_FRAME = 1,
+	 * - GOLDEN_FRAME = 2,
+	 * - ALTREF_FRAME = 3,
+	 * ref_frame_sign_biases[INTRA_FRAME] is always 0
+	 * and VDA only passes another 3 directions
+	 */
+	uh->ref_frame_sign_bias[0] = 0;
+	for (i = 0; i < 3; i++)
+		uh->ref_frame_sign_bias[i + 1] =
+			!!(hdr->ref_frame_sign_biases & (1 << i));
+	uh->allow_high_precision_mv = HDR_FLAG(ALLOW_HIGH_PREC_MV);
+	uh->interpolation_filter = hdr->interpolation_filter;
+	uh->refresh_frame_context = HDR_FLAG(REFRESH_FRAME_CTX);
+	uh->frame_parallel_decoding_mode = HDR_FLAG(PARALLEL_DEC_MODE);
+	uh->frame_context_idx = hdr->frame_context_idx;
+
+	/* tile info */
+	uh->tile_cols_log2 = hdr->tile_cols_log2;
+	uh->tile_rows_log2 = hdr->tile_rows_log2;
+
+	uh->uncompressed_header_size = hdr->uncompressed_header_size;
+	uh->header_size_in_bytes = hdr->compressed_header_size;
+}
+
+static void vdec_vp9_slice_setup_frame_ctx(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_uncompressed_header *uh,
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int error_resilient_mode;
+	int reset_frame_context;
+	int key_frame;
+	int intra_only;
+	int i;
+
+	key_frame = HDR_FLAG(KEY_FRAME);
+	intra_only = HDR_FLAG(INTRA_ONLY);
+	error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	reset_frame_context = uh->reset_frame_context;
+
+	/*
+	 * according to "6.2 Uncompressed header syntax" in
+	 * "VP9 Bitstream & Decoding Process Specification",
+	 * reset @frame_context_idx when (FrameIsIntra || error_resilient_mode)
+	 */
+	if (key_frame || intra_only || error_resilient_mode) {
+		/*
+		 * @reset_frame_context specifies
+		 * whether the frame context should be
+		 * reset to default values:
+		 * 0 or 1 means do not reset any frame context
+		 * 2 resets just the context specified in the frame header
+		 * 3 resets all contexts
+		 */
+		if (key_frame || error_resilient_mode ||
+			reset_frame_context == 3) {
+			/* use default table */
+			for (i = 0; i < 4; i++)
+				instance->dirty[i] = 0;
+		} else if (reset_frame_context == 2) {
+			instance->dirty[uh->frame_context_idx] = 0;
+		} else {
+			;
+		}
+		uh->frame_context_idx = 0;
+	}
+}
+
+static void vdec_vp9_slice_setup_loop_filter(
+	struct vdec_vp9_slice_uncompressed_header *uh,
+	struct v4l2_vp9_loop_filter *lf)
+{
+	int i;
+
+	uh->loop_filter_level = lf->level;
+	uh->loop_filter_sharpness = lf->sharpness;
+	uh->loop_filter_delta_enabled = LF_FLAG(DELTA_ENABLED);
+	for (i = 0; i < 4; i++)
+		uh->loop_filter_ref_deltas[i] = lf->ref_deltas[i];
+	for (i = 0; i < 2; i++)
+		uh->loop_filter_mode_deltas[i] = lf->mode_deltas[i];
+}
+
+static void vdec_vp9_slice_setup_quantization(
+	struct vdec_vp9_slice_uncompressed_header *uh,
+	struct v4l2_vp9_quantization *quant)
+{
+	uh->base_q_idx = quant->base_q_idx;
+	uh->delta_q_y_dc = quant->delta_q_y_dc;
+	uh->delta_q_uv_dc = quant->delta_q_uv_dc;
+	uh->delta_q_uv_ac = quant->delta_q_uv_ac;
+}
+
+static void vdec_vp9_slice_setup_segmentation(
+	struct vdec_vp9_slice_uncompressed_header *uh,
+	struct v4l2_vp9_segmentation *seg)
+{
+	int i;
+	int j;
+
+	uh->segmentation_enabled = SEG_FLAG(ENABLED);
+	uh->segmentation_update_map = SEG_FLAG(UPDATE_MAP);
+	for (i = 0; i < 7; i++)
+		uh->segmentation_tree_probs[i] = seg->tree_probs[i];
+	uh->segmentation_temporal_udpate = SEG_FLAG(TEMPORAL_UPDATE);
+	for (i = 0; i < 3; i++)
+		uh->segmentation_pred_prob[i] = seg->pred_probs[i];
+	uh->segmentation_update_data = SEG_FLAG(UPDATE_DATA);
+	uh->segmentation_abs_or_delta_update = SEG_FLAG(ABS_OR_DELTA_UPDATE);
+	for (i = 0; i < 8; i++) {
+		uh->feature_enabled[i] = seg->feature_enabled[i];
+		for (j = 0; j < 4; j++)
+			uh->feature_value[i][j] = seg->feature_data[i][j];
+	}
+}
+
+static int vdec_vp9_slice_setup_tile(struct vdec_vp9_slice_vsi *vsi,
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_rows;
+	unsigned int mi_cols;
+	struct vdec_vp9_slice_tiles *tiles;
+	int offset;
+	int start;
+	int end;
+	int i;
+
+	rows_log2 = hdr->tile_rows_log2;
+	cols_log2 = hdr->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+	tiles = &vsi->frame.tiles;
+	tiles->actual_rows = 0;
+
+	if (rows > 4 || cols > 64)
+		return -EINVAL;
+
+	/* setup mi rows/cols information */
+	mi_rows = (hdr->frame_height_minus_1 + 1 + 7) >> 3;
+	mi_cols = (hdr->frame_width_minus_1 + 1 + 7) >> 3;
+
+	for (i = 0; i < rows; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_rows, rows_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_rows, rows_log2);
+		offset = end - start;
+		tiles->mi_rows[i] = (offset + 7) >> 3;
+		if (tiles->mi_rows[i])
+			tiles->actual_rows++;
+	}
+
+	for (i = 0; i < cols; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_cols, cols_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_cols, cols_log2);
+		offset = end - start;
+		tiles->mi_cols[i] = (offset + 7) >> 3;
+	}
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_state(struct vdec_vp9_slice_vsi *vsi)
+{
+	memset(&vsi->state, 0, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_setup_ref_idx(
+	struct vdec_vp9_slice_pfc *pfc,
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int i;
+
+	for (i = 0; i < 3; i++)
+		pfc->ref_idx[i] = hdr->refs[i];
+}
+
+static int vdec_vp9_slice_setup_pfc(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_pfc *pfc)
+{
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	struct v4l2_ctrl *hdr_ctrl;
+	struct vdec_vp9_slice_vsi *vsi;
+	int ret;
+
+	/* frame header */
+	hdr_ctrl = v4l2_ctrl_find(&instance->ctx->ctrl_hdl,
+		V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS);
+	if (!hdr_ctrl || !hdr_ctrl->p_cur.p)
+		return -EINVAL;
+	hdr = hdr_ctrl->p_cur.p;
+
+	vsi = &pfc->vsi;
+	uh = &vsi->frame.uh;
+
+	/* setup vsi information */
+	vdec_vp9_slice_setup_hdr(instance, uh, hdr);
+	vdec_vp9_slice_setup_frame_ctx(instance, uh, hdr);
+	vdec_vp9_slice_setup_loop_filter(uh, &hdr->lf);
+	vdec_vp9_slice_setup_quantization(uh, &hdr->quant);
+	vdec_vp9_slice_setup_segmentation(uh, &hdr->seg);
+	ret = vdec_vp9_slice_setup_tile(vsi, hdr);
+	if (ret)
+		return ret;
+	vdec_vp9_slice_setup_state(vsi);
+
+	/* core stage needs buffer index to get ref y/c ... */
+	vdec_vp9_slice_setup_ref_idx(pfc, hdr);
+
+	pfc->seq = instance->seq;
+	instance->seq++;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi *vsi,
+	struct mtk_vcodec_mem *bs,
+	struct vdec_lat_buf *lat_buf)
+{
+	int i;
+
+	vsi->bs.buf.dma_addr = bs->dma_addr;
+	vsi->bs.buf.size = bs->size;
+	vsi->bs.frame.dma_addr = bs->dma_addr;
+	vsi->bs.frame.size = bs->size;
+
+	for (i = 0; i < 2; i++) {
+		vsi->mv[i].dma_addr = instance->mv[i].dma_addr;
+		vsi->mv[i].size = instance->mv[i].size;
+	}
+	for (i = 0; i < 2; i++) {
+		vsi->seg[i].dma_addr = instance->seg[i].dma_addr;
+		vsi->seg[i].size = instance->seg[i].size;
+	}
+	vsi->tile.dma_addr = instance->tile.dma_addr;
+	vsi->tile.size = instance->tile.size;
+	vsi->prob.dma_addr = instance->prob.dma_addr;
+	vsi->prob.size = instance->prob.size;
+	vsi->counts.dma_addr = instance->counts.dma_addr;
+	vsi->counts.size = instance->counts.size;
+
+	vsi->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	vsi->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
+	vsi->trans.dma_addr = lat_buf->ctx->msg_queue.wdma_wptr_addr;
+	/* used to store trans end */
+	vsi->trans.dma_addr_end = lat_buf->ctx->msg_queue.wdma_rptr_addr;
+	vsi->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
+	vsi->err_map.size = lat_buf->wdma_err_addr.size;
+
+	vsi->row_info.buf = 0;
+	vsi->row_info.size = 0;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_prob_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+
+	mtk_vcodec_debug(instance, "ctx dirty %u idx %d\n",
+		instance->dirty[uh->frame_context_idx], uh->frame_context_idx);
+
+	if (instance->dirty[uh->frame_context_idx])
+		frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	else
+		frame_ctx = vdec_vp9_slice_default_frame_ctx;
+	memcpy(instance->prob.va, frame_ctx, sizeof(*frame_ctx));
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_seg_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi *vsi,
+	struct mtk_vcodec_mem *buf)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	/* reset segment buffer */
+	uh = &vsi->frame.uh;
+	if (uh->frame_type == 0 ||
+		uh->intra_only ||
+		uh->error_resilient_mode ||
+		uh->frame_width != instance->width ||
+		uh->frame_height != instance->height) {
+		mtk_vcodec_debug(instance, "reset seg\n");
+		memset(buf->va, 0, buf->size);
+	}
+}
+
+/*
+ * parse tiles according to `6.4 Decode tiles syntax`
+ * in "vp9-bitstream-specification"
+ *
+ * frame contains uncompress header, compressed header and several tiles.
+ * this function parses tiles' position and size, stores them to tile buffer
+ * for decoding.
+ */
+static int vdec_vp9_slice_setup_tile_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi * vsi,
+	struct mtk_vcodec_mem *bs)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_row;
+	unsigned int mi_col;
+	unsigned int offset;
+	unsigned int pa;
+	unsigned int size;
+	struct vdec_vp9_slice_tiles *tiles;
+	unsigned char *pos;
+	unsigned char *end;
+	unsigned char *va;
+	unsigned int *tb;
+	int i;
+	int j;
+
+	uh = &vsi->frame.uh;
+	rows_log2 = uh->tile_rows_log2;
+	cols_log2 = uh->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+
+	if (rows > 4 || cols > 64) {
+		mtk_vcodec_err(instance, "tile_rows %u tile_cols %u\n",
+			rows, cols);
+		return -EINVAL;
+	}
+
+	offset = uh->uncompressed_header_size +
+		uh->header_size_in_bytes;
+	if (bs->size <= offset) {
+		mtk_vcodec_err(instance, "bs size %zu tile offset %u\n",
+			bs->size, offset);
+		return -EINVAL;
+	}
+
+	tiles = &vsi->frame.tiles;
+	/* setup tile buffer */
+
+	va = (unsigned char *)bs->va;
+	pos = va + offset;
+	end = va + bs->size;
+	/* truncated */
+	pa = (unsigned int)bs->dma_addr + offset;
+	tb = instance->tile.va;
+	for (i = 0; i < rows; i++) {
+		for (j = 0; j < cols; j++) {
+			if (i == rows - 1 &&
+				j == cols - 1) {
+				size = (unsigned int)(end - pos);
+			} else {
+				if (end - pos < 4) {
+					mtk_vcodec_err(instance,
+						"tile %px %px\n", end, pos);
+					return -EINVAL;
+				}
+				size = (pos[0] << 24) | (pos[1] << 16) |
+					(pos[2] << 8) | pos[3];
+				pos += 4;
+				pa += 4;
+				offset += 4;
+				if (end - pos < size) {
+					mtk_vcodec_err(instance,
+						"tile %px %px %u\n",
+						end, pos, size);
+					return -EINVAL;
+				}
+			}
+			tiles->size[i][j] = size;
+			if (tiles->mi_rows[i]) {
+				*tb++ = (size << 3) + ((offset << 3) & 0x7f);
+				*tb++ = pa &~0xf;
+				*tb++ = (pa << 3) & 0x7f;
+				mi_row = (tiles->mi_rows[i] - 1) & 0x1ff;
+				mi_col = (tiles->mi_cols[j] - 1) & 0x3f;
+				*tb++ = (mi_row << 6) + mi_col;
+			}
+			pos += size;
+			pa += size;
+			offset += size;
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat(
+	struct vdec_vp9_slice_instance *instance,
+	struct mtk_vcodec_mem *bs,
+	struct vdec_lat_buf *lat_buf,
+	struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	ret = vdec_vp9_slice_setup_lat_from_src_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_pfc(instance, pfc);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_alloc_working_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_lat_buffer(instance, vsi, bs, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]);
+
+	/* setup prob/tile buffers for LAT */
+
+	ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	return ret;
+}
+
+/* implement merge prob process defined in 8.4.1 */
+static unsigned char vdec_vp9_slice_merge_prob(unsigned char pre,
+	unsigned int ct0,
+	unsigned int ct1,
+	unsigned int cs,
+	unsigned int uf)
+{
+	unsigned int den;
+	unsigned int prob;
+	unsigned int count;
+	unsigned int factor;
+
+	/*
+	 * The variable den representing the total times
+	 * this boolean has been decoded is set equal to ct0 + ct1.
+	 */
+	den = ct0 + ct1;
+	if (!den)
+		return pre;  /* => count = 0 => factor = 0 */
+	/*
+	 * The variable prob estimating the probability that
+	 * the boolean is decoded as a 0 is set equal to
+	 * (den == 0) ? 128 : Clip3(1, 255, (ct0 * 256 + (den >> 1)) / den).
+	 */
+	prob = ((ct0 << 8) + (den >> 1)) / den;
+	prob = prob < 1 ? 1 : (prob > 255 ? 255 : prob);
+	/* The variable count is set equal to Min(ct0 + ct1, countSat) */
+	count = den < cs ? den : cs;
+	/*
+	 * The variable factor is set equal to
+	 * maxUpdateFactor * count / countSat.
+	 */
+	factor = uf * count / cs;
+	/*
+	 * The return variable outProb is set equal to
+	 * Round2(preProb * (256 - factor) + prob * factor, 8).
+	 */
+	return pre + (((prob - pre) * factor + 128) >> 8);
+}
+
+static inline unsigned char vdec_vp9_slice_adapt_prob(
+	unsigned char pre,
+	unsigned int ct0,
+	unsigned int ct1)
+{
+	return vdec_vp9_slice_merge_prob(pre, ct0, ct1, 20, 128);
+}
+
+/* implement merge probs process defined in 8.4.2 */
+static unsigned int vdec_vp9_slice_merge_probs(
+	const signed char *tree,
+	int location,
+	unsigned char *pre_probs,
+	unsigned int *counts,
+	unsigned char *probs,
+	unsigned int cs,
+	unsigned int uf)
+{
+	int left = tree[location];
+	int right = tree[location + 1];
+	unsigned int left_count;
+	unsigned int right_count;
+
+	if (left <= 0)
+		left_count = counts[-left];
+	else
+		left_count = vdec_vp9_slice_merge_probs(tree, left,
+			pre_probs, counts, probs, cs, uf);
+
+	if (right <= 0)
+		right_count = counts[-right];
+	else
+		right_count = vdec_vp9_slice_merge_probs(tree, right,
+			pre_probs, counts, probs, cs, uf);
+
+	/* merge left and right */
+	probs[location >> 1] =
+		vdec_vp9_slice_merge_prob(pre_probs[location >> 1],
+			left_count, right_count, cs, uf);
+	return left_count + right_count;
+}
+
+static inline void vdec_vp9_slice_adapt_probs(
+	const signed char *tree,
+	unsigned char *pre_probs,
+	unsigned int *counts,
+	unsigned char *probs)
+{
+	vdec_vp9_slice_merge_probs(tree, 0, pre_probs, counts, probs, 20, 128);
+}
+
+/* 8.4 Probability adaptation process */
+static void vdec_vp9_slice_adapt_table(
+	struct vdec_vp9_slice_vsi *vsi,
+	struct vdec_vp9_slice_frame_ctx *ctx,
+	struct vdec_vp9_slice_frame_ctx *pre_ctx,
+	struct vdec_vp9_slice_frame_counts *counts)
+{
+	unsigned char *pp;
+	unsigned char *p;
+	unsigned int *c;
+	unsigned int *e;
+	unsigned int uf;
+	int t, i, j, k, l;
+
+	uf = 128;
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only ||
+		vsi->frame.uh.last_frame_type)
+		uf = 112;
+
+	p = (unsigned char *)&ctx->coef_probs;
+	pp = (unsigned char *)&pre_ctx->coef_probs;
+	c = (unsigned int *)&counts->coef_probs;
+	e = (unsigned int *)&counts->eob_branch;
+
+	/* 8.4.3 Coefficient probability adaption process */
+	FOR_EACH_COEF_PROBS_BAND(t, i, j, k) {
+		for (l = 0; l < (k == 0 ? 3 : 6); l++) {
+			p[0] = vdec_vp9_slice_merge_prob(pp[0],
+				c[3], e[0] - c[3], 24, uf);
+			p[1] = vdec_vp9_slice_merge_prob(pp[1],
+				c[0], c[1] + c[2], 24, uf);
+			p[2] = vdec_vp9_slice_merge_prob(pp[2],
+				c[1], c[2], 24, uf);
+			p += 3;
+			pp += 3;
+			c += 4;
+			e++;
+		}
+		if (k == 0) {
+			/* 3*3 unused values and 2 bytes padding */
+			p += 11;
+			pp += 11;
+			e++;
+		} else {
+			/* extra 2 bytes could make 4 bytes align (3*6+2) */
+			p += 2;
+			pp += 2;
+			/* 5*6=30, extra 2 int */
+			if (k == 5)
+				e += 2;
+		}
+	}
+
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only)
+		return;
+
+	/* 8.4.4 Non coefficient probability adaption process */
+
+	for (i = 0; i < 4; i++) {
+		ctx->intra_inter_prob[i] = vdec_vp9_slice_adapt_prob(
+			pre_ctx->intra_inter_prob[i],
+			counts->intra_inter[i][0],
+			counts->intra_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_inter_prob[i] = vdec_vp9_slice_adapt_prob(
+			pre_ctx->comp_inter_prob[i],
+			counts->comp_inter[i][0],
+			counts->comp_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_ref_prob[i] = vdec_vp9_slice_adapt_prob(
+			pre_ctx->comp_ref_prob[i],
+			counts->comp_ref[i][0],
+			counts->comp_ref[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		for (j = 0; j < 2; j++) {
+			ctx->single_ref_prob[i][j] =
+				vdec_vp9_slice_adapt_prob(
+					pre_ctx->single_ref_prob[i][j],
+					counts->single_ref[i][j][0],
+					counts->single_ref[i][j][1]);
+		}
+	}
+
+	for (i = 0; i < 7; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_inter_mode_tree,
+			&pre_ctx->inter_mode_probs[i][0],
+			&counts->inter_mode[i][0],
+			&ctx->inter_mode_probs[i][0]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+			&pre_ctx->y_mode_prob[i][0],
+			&counts->y_mode[i][0],
+			&ctx->y_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 10; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+			&pre_ctx->uv_mode_prob[i][0],
+			&counts->uv_mode[i][0],
+			&ctx->uv_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 16; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_partition_tree,
+			&pre_ctx->partition_prob[i][0],
+			&counts->partition[i][0],
+			&ctx->partition_prob[i][0]);
+	}
+
+	if (vsi->frame.uh.interpolation_filter == 4) {
+		for (i = 0; i < 4; i++) {
+			vdec_vp9_slice_adapt_probs(
+				vdec_vp9_slice_switchable_interp_tree,
+				&pre_ctx->switch_interp_prob[i][0],
+				&counts->switchable_interp[i][0],
+				&ctx->switch_interp_prob[i][0]);
+		}
+	}
+
+	if (vsi->frame.ch.tx_mode == 4) {
+		for (i = 0; i < 2; i++) {
+			ctx->tx_p8x8[i][0] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p8x8[i][0],
+				counts->tx_p8x8[i][0],
+				counts->tx_p8x8[i][1]);
+			ctx->tx_p16x16[i][0] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p16x16[i][0],
+				counts->tx_p16x16[i][0],
+				counts->tx_p16x16[i][1] +
+				counts->tx_p16x16[i][2]);
+			ctx->tx_p16x16[i][1] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p16x16[i][1],
+				counts->tx_p16x16[i][1],
+				counts->tx_p16x16[i][2]);
+			ctx->tx_p32x32[i][0] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p32x32[i][0],
+				counts->tx_p32x32[i][0],
+				counts->tx_p32x32[i][1] +
+				counts->tx_p32x32[i][2] +
+				counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][1] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p32x32[i][1],
+				counts->tx_p32x32[i][1],
+				counts->tx_p32x32[i][2] +
+				counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][2] = vdec_vp9_slice_adapt_prob(
+				pre_ctx->tx_p32x32[i][2],
+				counts->tx_p32x32[i][2],
+				counts->tx_p32x32[i][3]);
+		}
+	}
+
+	for (i = 0; i < 3; i++) {
+		ctx->skip_probs[i] = vdec_vp9_slice_adapt_prob(
+			pre_ctx->skip_probs[i],
+			counts->skip[i][0],
+			counts->skip[i][1]);
+	}
+
+	vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_joint_tree,
+		&pre_ctx->joint[0],
+		&counts->joint[0],
+		&ctx->joint[0]);
+
+	for (i = 0; i < 2; i++) {
+		ctx->sign_classes[i].sign = vdec_vp9_slice_adapt_prob(
+			pre_ctx->sign_classes[i].sign,
+			counts->mvcomp[i].sign[0],
+			counts->mvcomp[i].sign[1]);
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class_tree,
+			&pre_ctx->sign_classes[i].classes[0],
+			&counts->mvcomp[i].classes[0],
+			&ctx->sign_classes[i].classes[0]);
+
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class0_tree,
+			pre_ctx->class0_bits[i].class0,
+			counts->mvcomp[i].class0,
+			ctx->class0_bits[i].class0);
+		for (j = 0; j < 10; j++) {
+			ctx->class0_bits[i].bits[j] =
+				vdec_vp9_slice_adapt_prob(
+					pre_ctx->class0_bits[i].bits[j],
+					counts->mvcomp[i].bits[j][0],
+					counts->mvcomp[i].bits[j][1]);
+		}
+
+		for (j = 0; j < 2; ++j) {
+			vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+				pre_ctx->class0_fp_hp[i].class0_fp[j],
+				counts->mvcomp[i].class0_fp[j],
+				ctx->class0_fp_hp[i].class0_fp[j]);
+		}
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+			pre_ctx->class0_fp_hp[i].fp,
+			counts->mvcomp[i].fp,
+			ctx->class0_fp_hp[i].fp);
+		if (vsi->frame.uh.allow_high_precision_mv) {
+			ctx->class0_fp_hp[i].class0_hp =
+				vdec_vp9_slice_adapt_prob(
+					pre_ctx->class0_fp_hp[i].class0_hp,
+					counts->mvcomp[i].class0_hp[0],
+					counts->mvcomp[i].class0_hp[1]);
+			ctx->class0_fp_hp[i].hp =
+				vdec_vp9_slice_adapt_prob(
+					pre_ctx->class0_fp_hp[i].hp,
+					counts->mvcomp[i].hp[0],
+					counts->mvcomp[i].hp[1]);
+		}
+	}
+}
+
+static int vdec_vp9_slice_update_prob(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *pre_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_frame_counts *counts;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+	pre_frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	frame_ctx = (struct vdec_vp9_slice_frame_ctx *)instance->prob.va;
+	counts = (struct vdec_vp9_slice_frame_counts *)instance->counts.va;
+
+	if (!uh->refresh_frame_context)
+		return 0;
+
+	if (!uh->frame_parallel_decoding_mode) {
+		/* uh->error_resilient_mode must be 0 */
+		vdec_vp9_slice_adapt_table(vsi,
+			frame_ctx,
+			/* use default frame ctx? */
+			instance->dirty[uh->frame_context_idx] ?
+				pre_frame_ctx :
+				vdec_vp9_slice_default_frame_ctx,
+			counts);
+	}
+
+	memcpy(pre_frame_ctx, frame_ctx, sizeof(*frame_ctx));
+	instance->dirty[uh->frame_context_idx] = 1;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_update_lat(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_lat_buf *lat_buf,
+	struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance,
+		"Frame %u LAT CRC 0x%08x\n", pfc->seq, vsi->state.crc[0]);
+
+	/* buffer full, need to re-decode */
+	if (vsi->state.full) {
+		/* buffer not enough */
+		if (vsi->trans.dma_addr_end - vsi->trans.dma_addr ==
+			vsi->ube.size)
+			return -ENOMEM;
+		return -EAGAIN;
+	}
+
+	vdec_vp9_slice_update_prob(instance, vsi);
+
+	instance->width = vsi->frame.uh.frame_width;
+	instance->height = vsi->frame.uh.frame_height;
+	instance->frame_type = vsi->frame.uh.frame_type;
+	instance->show_frame = vsi->frame.uh.show_frame;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_to_dst_buf(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	dst = v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx);
+	if (!dst)
+		return -EINVAL;
+
+	src = &lat_buf->ts_info;
+	dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
+	dst->timecode = src->timecode;
+	dst->field = src->field;
+	dst->flags = src->flags;
+	dst->vb2_buf.copied_timestamp = src->vb2_buf.copied_timestamp;
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_buffer(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_vp9_slice_pfc *pfc,
+	struct vdec_vp9_slice_vsi *vsi,
+	struct vdec_fb *fb,
+	struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_buffer *vb;
+	struct vb2_queue *vq;
+	struct vdec_vp9_slice_reference *ref;
+	int plane;
+	int size;
+	int idx;
+	int w;
+	int h;
+	int i;
+
+	plane = instance->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+	size = ALIGN(w, 64) * ALIGN(h, 64);
+
+	/* frame buffer */
+	vsi->fb.y.dma_addr = fb->base_y.dma_addr;
+	if (plane == 1)
+		vsi->fb.c.dma_addr = fb->base_y.dma_addr + size;
+	else
+		vsi->fb.c.dma_addr = fb->base_c.dma_addr;
+
+	/* reference buffers */
+	vq = v4l2_m2m_get_vq(instance->ctx->m2m_ctx,
+		V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	if (!vq)
+		return -EINVAL;
+
+	/* get current output buffer */
+	vb = &v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx)->vb2_buf;
+	if (!vb)
+		return -EINVAL;
+
+	/* update internal buffer's width/height */
+	for (i = 0; i < vq->num_buffers; i++) {
+		if (vb == vq->bufs[i]) {
+			instance->dpb[i].width = w;
+			instance->dpb[i].height = h;
+			break;
+		}
+	}
+
+	/*
+	 * get buffer's width/height from instance
+	 * get buffer address from vb2buf
+	 */
+	for (i = 0; i < 3; i++) {
+		ref = &vsi->frame.ref[i];
+		idx = vb2_find_timestamp(vq, pfc->ref_idx[i], 0);
+		if (idx < 0) {
+			ref->frame_width = w;
+			ref->frame_height = h;
+			memset(&vsi->ref[i], 0, sizeof(vsi->ref[i]));
+		} else {
+			ref->frame_width = instance->dpb[idx].width;
+			ref->frame_height = instance->dpb[idx].height;
+			vb = vq->bufs[idx];
+			vsi->ref[i].y.dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 0);
+			if (plane == 1)
+				vsi->ref[i].c.dma_addr =
+					vsi->ref[i].y.dma_addr + size;
+			else
+				vsi->ref[i].c.dma_addr =
+					vb2_dma_contig_plane_dma_addr(vb, 1);
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_fb *fb,
+	struct vdec_lat_buf *lat_buf,
+	struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	vdec_vp9_slice_setup_state(vsi);
+
+	ret = vdec_vp9_slice_setup_core_to_dst_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_core_buffer(instance, pfc, vsi,
+		fb, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[1]);
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static int vdec_vp9_slice_update_core(
+	struct vdec_vp9_slice_instance *instance,
+	struct vdec_lat_buf *lat_buf,
+	struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[1], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n",
+		pfc->seq,
+		vsi->state.crc[0], vsi->state.crc[1],
+		vsi->state.crc[2], vsi->state.crc[3]);
+	mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n",
+		pfc->seq,
+		vsi->state.crc[4], vsi->state.crc[5],
+		vsi->state.crc[6], vsi->state.crc[7]);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret;
+
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+	if (!instance)
+		return -ENOMEM;
+
+	instance->ctx = ctx;
+	instance->vpu.id = SCP_IPI_VDEC_LAT;
+	instance->vpu.core_id = SCP_IPI_VDEC_CORE;
+	instance->vpu.ctx = ctx;
+	instance->vpu.codec_type = ctx->current_codec;
+
+	ret = vpu_dec_init(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "failed to init vpu dec, ret %d\n",
+			ret);
+		goto error_vpu_init;
+	}
+
+	/* init vsi and global flags */
+
+	vsi = instance->vpu.vsi;
+	if (!vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+	instance->init_vsi = vsi;
+	instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+		(u32)vsi->core_vsi);
+	if (!instance->core_vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 core vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+
+	instance->irq = 1;
+
+	mtk_vcodec_debug(instance, "vsi 0x%px core_vsi 0x%llx 0x%px\n",
+		vsi, vsi->core_vsi, instance->core_vsi);
+
+	ret = vdec_vp9_slice_init_default_frame_ctx(instance);
+	if (ret)
+		goto error_default_frame_ctx;
+
+	ctx->drv_handle = instance;
+
+	return 0;
+
+error_default_frame_ctx:
+error_vsi:
+	vpu_dec_deinit(&instance->vpu);
+error_vpu_init:
+	kfree(instance);
+	return ret;
+}
+
+static void vdec_vp9_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	if (!instance)
+		return;
+
+	mtk_vcodec_debug(instance, "h_vdec 0x%px\n", h_vdec);
+
+	vpu_dec_deinit(&instance->vpu);
+	vdec_vp9_slice_free_working_buffer(instance);
+	vdec_msg_queue_deinit(&instance->ctx->msg_queue, instance->ctx);
+	kfree(instance);
+}
+
+static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs,
+	struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	mtk_vcodec_debug(instance, "flush ...\n");
+
+	vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue);
+	return vpu_dec_reset(&instance->vpu);
+}
+
+static void vdec_vp9_slice_get_pic_info(
+	struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	unsigned int data[3];
+
+	mtk_vcodec_debug(instance, "w %u h %u\n",
+		ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&instance->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = instance->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = instance->vpu.fb_sz[1];
+}
+
+static void vdec_vp9_slice_get_dpb_size(
+	struct vdec_vp9_slice_instance *instance,
+	unsigned int *dpb_sz)
+{
+	/* refer VP9 specification */
+	*dpb_sz = 9;
+}
+
+static void vdec_vp9_slice_get_crop_info(
+	struct vdec_vp9_slice_instance *instance,
+	struct v4l2_rect *cr)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = ctx->picinfo.pic_w;
+	cr->height = ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(instance, "l=%d, t=%d, w=%d, h=%d\n",
+		cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_vp9_slice_get_param(void *h_vdec,
+	enum vdec_get_param_type type, void *out)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp9_slice_get_pic_info(instance);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		vdec_vp9_slice_get_dpb_size(instance, out);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp9_slice_get_crop_info(instance, out);
+		break;
+	default:
+		mtk_vcodec_err(instance, "invalid get parameter type=%d\n",
+			type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_lat_decode(void *h_vdec,
+	struct mtk_vcodec_mem *bs,
+	struct vdec_fb *fb,
+	bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct vdec_vp9_slice_vsi *vsi;
+	struct mtk_vcodec_ctx *ctx;
+	int ret;
+
+	if (!instance || !instance->ctx)
+		return -EINVAL;
+	ctx = instance->ctx;
+
+	/* init msgQ for the first time */
+	if (vdec_msg_queue_init(&ctx->msg_queue, ctx,
+		vdec_vp9_slice_core_decode, sizeof(*pfc))) {
+		mtk_vcodec_err(instance,
+			"Failed to init VP9 msg queue\n");
+		return -ENOMEM;
+	}
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vdec_vp9_slice_flush(h_vdec, bs, fb, res_chg);
+
+	lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(instance, "Failed to get VP9 lat buf\n");
+		return -EBUSY;
+	}
+	pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+	if (!pfc)
+		return -EINVAL;
+	vsi = &pfc->vsi;
+
+	ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance,
+			"Failed to setup VP9 lat ret %d\n", ret);
+		return ret;
+	}
+	vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi);
+
+	ret = vpu_dec_start(&instance->vpu, 0, 0);
+	if (ret) {
+		mtk_vcodec_err(instance,
+			"Failed to dec VP9 ret %d\n", ret);
+		return ret;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx,
+			MTK_INST_IRQ_RECEIVED,
+			WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance,
+				"VP9 decode timeout %d\n", ret);
+			writel(1, &instance->vsi->state.timeout);
+		}
+		vpu_dec_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0);
+	ret = vdec_vp9_slice_update_lat(instance, lat_buf, pfc);
+
+	/* LAT trans full, no more UBE or decode timeout */
+	if (ret) {
+		mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret);
+		return ret;
+	}
+
+	mtk_vcodec_debug(instance, "lat dma 1 0x%llx 0x%llx\n",
+		pfc->vsi.trans.dma_addr, pfc->vsi.trans.dma_addr_end);
+
+	vdec_msg_queue_update_ube_wptr(&ctx->msg_queue,
+		vsi->trans.dma_addr_end  + ctx->msg_queue.wdma_addr.dma_addr);
+	vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_core_decode(
+	struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct mtk_vcodec_ctx *ctx = NULL;
+	struct vdec_fb *fb = NULL;
+	int ret = -EINVAL;
+
+	if (!lat_buf)
+		goto err;
+
+	pfc = lat_buf->private_data;
+	ctx = lat_buf->ctx;
+	if (!pfc || !ctx)
+		goto err;
+
+	instance = ctx->drv_handle;
+	if (!instance)
+		goto err;
+
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	if (!fb) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	ret = vdec_vp9_slice_setup_core(instance, fb, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_setup_core\n");
+		goto err;
+	}
+	vdec_vp9_slice_vsi_to_remote(&pfc->vsi, instance->core_vsi);
+
+	ret = vpu_dec_core(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "vpu_dec_core\n");
+		goto err;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx,
+			MTK_INST_IRQ_RECEIVED,
+			WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance, "VP9 core timeout\n");
+			writel(1, &instance->core_vsi->state.timeout);
+		}
+		vpu_dec_core_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(&pfc->vsi, instance->core_vsi, 1);
+	ret = vdec_vp9_slice_update_core(instance, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_update_core\n");
+		goto err;
+	}
+
+	pfc->vsi.trans.dma_addr_end += ctx->msg_queue.wdma_addr.dma_addr;
+	mtk_vcodec_debug(instance, "core dma_addr_end 0x%llx\n",
+		pfc->vsi.trans.dma_addr_end);
+	vdec_msg_queue_update_ube_rptr(&ctx->msg_queue,
+		pfc->vsi.trans.dma_addr_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 0);
+
+	return 0;
+
+err:
+	if (ctx) {
+		/* always update read pointer */
+		vdec_msg_queue_update_ube_rptr(&ctx->msg_queue,
+			pfc->vsi.trans.dma_addr_end);
+
+		if (fb)
+			ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 1);
+	}
+	return ret;
+}
+
+const struct vdec_common_if vdec_vp9_slice_lat_if = {
+	.init		= vdec_vp9_slice_init,
+	.decode		= vdec_vp9_slice_lat_decode,
+	.get_param	= vdec_vp9_slice_get_param,
+	.deinit		= vdec_vp9_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 9db9a57da2c1..2d3a45781359 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -44,6 +44,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_vp9_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP9_FRAME:
+		ctx->dec_if = &vdec_vp9_slice_lat_if;
+		ctx->hw_id = MTK_VDEC_LAT0;
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index e3adf8f36342..e383a04db7b8 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -60,6 +60,7 @@ extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
+extern const struct vdec_common_if vdec_vp9_slice_lat_if;
 
 /**
  * vdec_if_init() - initialize decode driver
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:38 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:38 +0800
Subject: [PATCH v4, 11/15] media: mtk-vcodec: record capture queue format type
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-12-yunfei.dong@mediatek.com>

Capture queue format type is difference for different platform,
need to calculate capture buffer size according to capture queue
format type in scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 75210eb829d0..4533cb44551d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -468,6 +468,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 			}
 			ctx->state = MTK_STATE_INIT;
 		}
+	} else {
+		ctx->capture_fourcc = fmt->fourcc;
 	}
 
 	/*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 12a2baaf9e81..4981760226b5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -277,6 +277,7 @@ struct vdec_pic_info {
  *		     to be used with encoder and stateful decoder.
  * @is_flushing: set to true if flushing is in progress.
  * @current_codec: current set input codec, in V4L2 pixel format
+ * @capture_fourcc: capture queue type in V4L2 pixel format
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -324,6 +325,7 @@ struct mtk_vcodec_ctx {
 	bool is_flushing;
 
 	u32 current_codec;
+	u32 capture_fourcc;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:30 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:30 +0800
Subject: [PATCH v4,
 03/15] media: mtk-vcodec: get capture queue buffer size from scp
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-4-yunfei.dong@mediatek.com>

Different capture buffer format has different buffer size, need to get
real buffer size according to buffer type from scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 37 ++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 50 +++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   | 15 ++++++
 3 files changed, 102 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5daca8d52ebb..363d928be29f 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -20,6 +20,7 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_RESET = 0xA004,
 	AP_IPIMSG_DEC_CORE = 0xA005,
 	AP_IPIMSG_DEC_CORE_END = 0xA006,
+	AP_IPIMSG_DEC_GET_PARAM = 0xA007,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
@@ -28,6 +29,7 @@ enum vdec_ipi_msgid {
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
 	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
 	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
+	VPU_IPIMSG_DEC_GET_PARAM_ACK = 0xB007,
 };
 
 /**
@@ -114,4 +116,39 @@ struct vdec_vpu_ipi_init_ack {
 	uint32_t inst_id;
 };
 
+/**
+ * struct vdec_ap_ipi_get_param - for AP_IPIMSG_DEC_GET_PARAM
+ * @msg_id	: AP_IPIMSG_DEC_GET_PARAM
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @data	: picture information
+ * @param_type	: get param type
+ * @codec_type	: Codec fourcc
+ */
+struct vdec_ap_ipi_get_param {
+	uint32_t msg_id;
+	uint32_t inst_id;
+	uint32_t data[4];
+	uint32_t param_type;
+	uint32_t codec_type;
+};
+
+
+/**
+ * struct vdec_vpu_ipi_get_param_ack - for VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @msg_id	: VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @status	: VPU exeuction result
+ * @ap_inst_addr	: AP vcodec_vpu_inst instance address
+ * @data     : picture information from SCP.
+ * @param_type	: get param type
+ * @reserved : reserved param
+ */
+struct vdec_vpu_ipi_get_param_ack {
+	uint32_t msg_id;
+	int32_t status;
+	uint64_t ap_inst_addr;
+	uint32_t data[4];
+	uint32_t param_type;
+	uint32_t reserved;
+};
+
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 21f6d9c5a371..816fd6a5556a 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -6,6 +6,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
+#include "vdec_drv_if.h"
 #include "vdec_ipi_msg.h"
 #include "vdec_vpu_if.h"
 #include "mtk_vcodec_fw.h"
@@ -54,6 +55,27 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	}
 }
 
+static void handle_get_param_msg_ack(
+	const struct vdec_vpu_ipi_get_param_ack *msg)
+{
+	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
+					(unsigned long)msg->ap_inst_addr;
+
+	mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr);
+
+	/* param_type is enum vdec_get_param_type */
+	switch(msg->param_type) {
+	case GET_PARAM_PIC_INFO:
+		vpu->fb_sz[0] = msg->data[0];
+		vpu->fb_sz[1] = msg->data[1];
+		break;
+	default:
+		mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type);
+		vpu->failure = 1;
+		break;
+	}
+}
+
 /*
  * vpu_dec_ipi_handler - Handler for VPU ipi message.
  *
@@ -89,6 +111,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
+		case VPU_IPIMSG_DEC_GET_PARAM_ACK:
+			handle_get_param_msg_ack(data);
+			break;
 		default:
 			mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id);
 			break;
@@ -217,6 +242,31 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+	unsigned int len, unsigned int param_type)
+{
+	struct vdec_ap_ipi_get_param msg;
+	int err;
+
+	mtk_vcodec_debug_enter(vpu);
+
+	if (len > ARRAY_SIZE(msg.data)) {
+		mtk_vcodec_err(vpu, "invalid len = %d\n", len);
+		return -EINVAL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_id = AP_IPIMSG_DEC_GET_PARAM;
+	msg.inst_id = vpu->inst_id;
+	memcpy(msg.data, data, sizeof(unsigned int) * len);
+	msg.param_type = param_type;
+	msg.codec_type = vpu->codec_type;
+
+	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
+	mtk_vcodec_debug(vpu, "- ret=%d", err);
+	return err;
+}
+
 int vpu_dec_core(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 4cb3c7f5a3ad..963f8d4877b7 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -28,6 +28,8 @@ struct mtk_vcodec_ctx;
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
  * @codec_type     : use codec type to separate different codecs
+ * @capture_type    : used capture type to separate different capture format
+ * @fb_sz  : frame buffer size of each plane
  */
 struct vdec_vpu_inst {
 	int id;
@@ -42,6 +44,8 @@ struct vdec_vpu_inst {
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
 	unsigned int codec_type;
+	unsigned int capture_type;
+	unsigned int fb_sz[2];
 };
 
 /**
@@ -104,4 +108,15 @@ int vpu_dec_core(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_get_param - get param from scp
+ *
+ * @vpu : instance for vdec_vpu_inst
+ * @data: meta data to pass bitstream info to VPU decoder
+ * @len : meta data length
+ * @param_type : get param type
+ */
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+	unsigned int len, unsigned int param_type);
+
 #endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:39 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:39 +0800
Subject: [PATCH v4, 12/15] media: mtk-vcodec: Extract H264 common code
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-13-yunfei.dong@mediatek.com>

Mt8192 can use some of common code with mt8183. Moves them to
a new file in order to reuse.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 311 ++++++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 254 +++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 400 +-----------------
 4 files changed, 589 insertions(+), 377 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 359619653a0e..3f41d748eee5 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
+		vdec/vdec_h264_req_common.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
new file mode 100644
index 000000000000..c8113ca251f5
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
@@ -0,0 +1,311 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include "vdec_h264_req_common.h"
+
+/* get used parameters for sps/pps */
+#define GET_MTK_VDEC_FLAG(cond, flag) \
+	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
+#define GET_MTK_VDEC_PARAM(param) \
+	{ dst_param->param = src_param->param; }
+
+/*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
+{
+	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
+}
+
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+	struct slice_api_h264_decode_param *decode_params,
+	struct mtk_h264_dpb_info *h264_dpb_info)
+{
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	int index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
+		const struct slice_h264_dpb_entry *dpb;
+		int vb2_index;
+
+		dpb = &decode_params->dpb[index];
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
+			h264_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+
+		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
+		if (vb2_index < 0) {
+			dev_err(&ctx->dev->plat_dev->dev,
+				"Reference invalid: dpb_index(%d) reference_ts(%lld)",
+				index, dpb->reference_ts);
+			continue;
+		}
+
+		/* 1 for short term reference, 2 for long term reference */
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			h264_dpb_info[index].reference_flag = 1;
+		else
+			h264_dpb_info[index].reference_flag = 2;
+
+		vb = vq->bufs[vb2_index];
+		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
+		h264_dpb_info[index].field = vb2_v4l2->field;
+
+		h264_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			h264_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			h264_dpb_info[index].c_dma_addr =
+				h264_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+}
+
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+	const struct v4l2_ctrl_h264_sps *src_param)
+{
+	GET_MTK_VDEC_PARAM(chroma_format_idc);
+	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
+	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
+	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
+	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
+	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
+	GET_MTK_VDEC_PARAM(max_num_ref_frames);
+	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
+	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
+
+	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
+		V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
+	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
+		V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
+		V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
+		V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
+		V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
+		V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+}
+
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+	const struct v4l2_ctrl_h264_pps *src_param)
+{
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
+	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
+	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
+	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
+	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
+
+	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
+		V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	GET_MTK_VDEC_FLAG(pic_order_present_flag,
+		V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	GET_MTK_VDEC_FLAG(weighted_pred_flag,
+		V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
+		V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
+		V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
+		V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
+		V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
+		V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+}
+
+void mtk_vdec_h264_copy_slice_hd_params(
+	struct mtk_h264_slice_hd_param *dst_param,
+	const struct v4l2_ctrl_h264_slice_params *src_param,
+	const struct v4l2_ctrl_h264_decode_params *dec_param)
+{
+	int temp;
+
+	GET_MTK_VDEC_PARAM(first_mb_in_slice);
+	GET_MTK_VDEC_PARAM(slice_type);
+	GET_MTK_VDEC_PARAM(cabac_init_idc);
+	GET_MTK_VDEC_PARAM(slice_qp_delta);
+	GET_MTK_VDEC_PARAM(disable_deblocking_filter_idc);
+	GET_MTK_VDEC_PARAM(slice_alpha_c0_offset_div2);
+	GET_MTK_VDEC_PARAM(slice_beta_offset_div2);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_active_minus1);
+
+	dst_param->frame_num = dec_param->frame_num;
+	dst_param->pic_order_cnt_lsb = dec_param->pic_order_cnt_lsb;
+
+	dst_param->delta_pic_order_cnt_bottom =
+		dec_param->delta_pic_order_cnt_bottom;
+	dst_param->delta_pic_order_cnt0 =
+		dec_param->delta_pic_order_cnt0;
+	dst_param->delta_pic_order_cnt1 =
+		dec_param->delta_pic_order_cnt1;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
+	dst_param->field_pic_flag = temp ? 1 : 0;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD;
+	dst_param->bottom_field_flag = temp ? 1 : 0;
+
+	GET_MTK_VDEC_FLAG(direct_spatial_mv_pred_flag,
+		V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
+}
+
+void mtk_vdec_h264_copy_scaling_matrix(
+	struct slice_api_h264_scaling_matrix *dst_matrix,
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
+{
+	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
+	       sizeof(dst_matrix->scaling_list_4x4));
+
+	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
+	       sizeof(dst_matrix->scaling_list_8x8));
+}
+
+void mtk_vdec_h264_copy_decode_params(
+	struct slice_api_h264_decode_param *dst_params,
+	const struct v4l2_ctrl_h264_decode_params *src_params,
+	const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
+		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
+		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
+
+		dst_entry->reference_ts = src_entry->reference_ts;
+		dst_entry->frame_num = src_entry->frame_num;
+		dst_entry->pic_num = src_entry->pic_num;
+		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
+		dst_entry->bottom_field_order_cnt =
+			src_entry->bottom_field_order_cnt;
+		dst_entry->flags = src_entry->flags;
+	}
+
+	/* num_slices is a leftover from the old H.264 support and is ignored
+	 * by the firmware.
+	 */
+	dst_params->num_slices = 0;
+	dst_params->nal_ref_idc = src_params->nal_ref_idc;
+	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
+	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
+	dst_params->flags = src_params->flags;
+}
+
+static bool mtk_vdec_h264_dpb_entry_match(
+	const struct v4l2_h264_dpb_entry *a,
+	const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+/*
+ * Move DPB entries of dec_param that refer to a frame already existing in dpb
+ * into the already existing slot in dpb, and move other entries into new slots.
+ *
+ * This function is an adaptation of the similarly-named function in
+ * hantro_h264.c.
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+	struct v4l2_h264_dpb_entry *dpb)
+{
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	/* Disable all entries by default, and mark the ones in use. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			set_bit(i, in_use);
+		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+	}
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries were already used.
+		 */
+		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &dpb[j];
+			if (!mtk_vdec_h264_dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			/* Don't reiterate on this one. */
+			clear_bit(j, in_use);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(dec_param->dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
+			return;
+
+		cdpb = &dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+unsigned int mtk_vdec_h264_get_mv_buf_size(
+	unsigned int width, unsigned int height)
+{
+	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
+
+	return HW_MB_STORE_SZ * unit_size;
+}
+
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz)
+{
+	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
+		return 3;
+
+	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
+	    data[3] == 1)
+		return 4;
+
+	return -1;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
new file mode 100644
index 000000000000..0d32fe6a0d29
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_H264_REQ_COMMON_H_
+#define _VDEC_H264_REQ_COMMON_H_
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_drv.h"
+
+#define NAL_NON_IDR_SLICE			0x01
+#define NAL_IDR_SLICE				0x05
+#define NAL_TYPE(value)				((value) & 0x1F)
+
+#define BUF_PREDICTION_SZ			(64 * 4096)
+#define MB_UNIT_LEN				16
+
+/* motion vector size (bytes) for every macro block */
+#define HW_MB_STORE_SZ				64
+
+#define H264_MAX_MV_NUM				32
+
+/**
+ * struct mtk_h264_dpb_info  - h264 dpb information
+ * @y_dma_addr: Y bitstream physical address
+ * @c_dma_addr: CbCr bitstream physical address
+ * @reference_flag: reference picture flag (short/long term reference picture)
+ * @field: field picture flag
+ */
+struct mtk_h264_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int field;
+};
+
+/**
+ * struct mtk_h264_sps_param  - parameters for sps
+ */
+struct mtk_h264_sps_param {
+	unsigned char chroma_format_idc;
+	unsigned char bit_depth_luma_minus8;
+	unsigned char bit_depth_chroma_minus8;
+	unsigned char log2_max_frame_num_minus4;
+	unsigned char pic_order_cnt_type;
+	unsigned char log2_max_pic_order_cnt_lsb_minus4;
+	unsigned char max_num_ref_frames;
+	unsigned char separate_colour_plane_flag;
+	unsigned short pic_width_in_mbs_minus1;
+	unsigned short pic_height_in_map_units_minus1;
+	unsigned int max_frame_nums;
+	unsigned char qpprime_y_zero_transform_bypass_flag;
+	unsigned char delta_pic_order_always_zero_flag;
+	unsigned char frame_mbs_only_flag;
+	unsigned char mb_adaptive_frame_field_flag;
+	unsigned char direct_8x8_inference_flag;
+	unsigned char reserved[3];
+};
+
+/**
+ * struct mtk_h264_pps_param  - parameters for pps
+ */
+struct mtk_h264_pps_param {
+	unsigned char num_ref_idx_l0_default_active_minus1;
+	unsigned char num_ref_idx_l1_default_active_minus1;
+	unsigned char weighted_bipred_idc;
+	char pic_init_qp_minus26;
+	char chroma_qp_index_offset;
+	char second_chroma_qp_index_offset;
+	unsigned char entropy_coding_mode_flag;
+	unsigned char pic_order_present_flag;
+	unsigned char deblocking_filter_control_present_flag;
+	unsigned char constrained_intra_pred_flag;
+	unsigned char weighted_pred_flag;
+	unsigned char redundant_pic_cnt_present_flag;
+	unsigned char transform_8x8_mode_flag;
+	unsigned char scaling_matrix_present_flag;
+	unsigned char reserved[2];
+};
+
+/**
+ * struct mtk_h264_slice_hd_param  - parameters for slice header
+ */
+struct mtk_h264_slice_hd_param {
+	unsigned int first_mb_in_slice;
+	unsigned int field_pic_flag;
+	unsigned int slice_type;
+	unsigned int frame_num;
+	int pic_order_cnt_lsb;
+	int delta_pic_order_cnt_bottom;
+	unsigned int bottom_field_flag;
+	unsigned int direct_spatial_mv_pred_flag;
+	int delta_pic_order_cnt0;
+	int delta_pic_order_cnt1;
+	unsigned int cabac_init_idc;
+	int slice_qp_delta;
+	unsigned int disable_deblocking_filter_idc;
+	int slice_alpha_c0_offset_div2;
+	int slice_beta_offset_div2;
+	unsigned int num_ref_idx_l0_active_minus1;
+	unsigned int num_ref_idx_l1_active_minus1;
+	unsigned int reserved;
+};
+
+struct slice_api_h264_scaling_matrix {
+	unsigned char scaling_list_4x4[6][16];
+	unsigned char scaling_list_8x8[6][64];
+};
+
+struct slice_h264_dpb_entry {
+	unsigned long long reference_ts;
+	unsigned short frame_num;
+	unsigned short pic_num;
+	/* Note that field is indicated by v4l2_buffer.field */
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+/**
+ * struct slice_api_h264_decode_param - parameters for decode.
+ */
+struct slice_api_h264_decode_param {
+	struct slice_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
+	unsigned short num_slices;
+	unsigned short nal_ref_idc;
+	unsigned char ref_pic_list_p0[32];
+	unsigned char ref_pic_list_b0[32];
+	unsigned char ref_pic_list_b1[32];
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+};
+
+/**
+ * struct h264_fb - h264 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct h264_fb {
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	int32_t poc;
+	uint32_t reserved;
+};
+
+/**
+ * mtk_vdec_h264_fixup_ref_list - fixup unused reference to 0x20.
+ * @ref_list: reference picture list
+ * @num_valid: used reference number
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid);
+
+/**
+ * mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @id: CID control ID
+ */
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id);
+
+/**
+ * mtk_vdec_h264_fill_dpb_info - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @decode_params: slice decode params
+ * @h264_dpb_info: dpb buffer information
+ */
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+	struct slice_api_h264_decode_param *decode_params,
+	struct mtk_h264_dpb_info *h264_dpb_info);
+
+/**
+ * mtk_vdec_h264_copy_sps_params - get sps params.
+ * @dst_params: sps params for hw decoder
+ * @src_params: sps params from user driver
+ */
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+	const struct v4l2_ctrl_h264_sps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_pps_params - get pps params.
+ * @dst_params: pps params for hw decoder
+ * @src_params: pps params from user driver
+ */
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+	const struct v4l2_ctrl_h264_pps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_slice_hd_params - get slice header params.
+ * @dst_params: slice params for hw decoder
+ * @src_params: slice params from user driver
+ * @dec_param: decode params from user driver
+ */
+void mtk_vdec_h264_copy_slice_hd_params(
+	struct mtk_h264_slice_hd_param *dst_param,
+	const struct v4l2_ctrl_h264_slice_params *src_param,
+	const struct v4l2_ctrl_h264_decode_params *dec_param);
+
+/**
+ * mtk_vdec_h264_copy_scaling_matrix - get each CID contrl address.
+ * @dst_matrix: scaling list params for hw decoder
+ * @src_matrix: scaling list params from user driver
+ */
+void mtk_vdec_h264_copy_scaling_matrix(
+	struct slice_api_h264_scaling_matrix *dst_matrix,
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix);
+
+/**
+ * mtk_vdec_h264_copy_decode_params - get decode params.
+ * @dst_params: dst params for hw decoder
+ * @src_params: decode params from user driver
+ * @dpb: dpb information
+ */
+void mtk_vdec_h264_copy_decode_params(
+	struct slice_api_h264_decode_param *dst_params,
+	const struct v4l2_ctrl_h264_decode_params *src_params,
+	const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);
+
+
+/**
+ * mtk_vdec_h264_update_dpb - updata dpb list.
+ * @dec_param: v4l2 control decode params
+ * @dpb: dpb entry informaton
+ */
+void mtk_vdec_h264_update_dpb(
+	const struct v4l2_ctrl_h264_decode_params *dec_param,
+	struct v4l2_h264_dpb_entry *dpb);
+
+/**
+ * mtk_vdec_h264_find_start_code - find h264 start code using sofeware.
+ * @data: input buffer address
+ * @data_sz: input buffer size
+ */
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz);
+
+/**
+ * mtk_vdec_h264_get_mv_buf_size - get mv buffer size.
+ * @width: picture width
+ * @height: picture height
+ */
+unsigned int mtk_vdec_h264_get_mv_buf_size(
+	unsigned int width, unsigned int height);
+
+#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index d00219a7587c..ee28686639c9 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -12,109 +12,7 @@
 #include "../vdec_drv_base.h"
 #include "../vdec_drv_if.h"
 #include "../vdec_vpu_if.h"
-
-#define BUF_PREDICTION_SZ			(64 * 4096)
-#define MB_UNIT_LEN				16
-
-/* get used parameters for sps/pps */
-#define GET_MTK_VDEC_FLAG(cond, flag) \
-	{ dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
-#define GET_MTK_VDEC_PARAM(param) \
-	{ dst_param->param = src_param->param; }
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ				64
-
-#define H264_MAX_FB_NUM				17
-#define H264_MAX_MV_NUM				32
-#define HDR_PARSING_BUF_SZ			1024
-
-/**
- * struct mtk_h264_dpb_info  - h264 dpb information
- * @y_dma_addr: Y bitstream physical address
- * @c_dma_addr: CbCr bitstream physical address
- * @reference_flag: reference picture flag (short/long term reference picture)
- * @field: field picture flag
- */
-struct mtk_h264_dpb_info {
-	dma_addr_t y_dma_addr;
-	dma_addr_t c_dma_addr;
-	int reference_flag;
-	int field;
-};
-
-/*
- * struct mtk_h264_sps_param  - parameters for sps
- */
-struct mtk_h264_sps_param {
-	unsigned char chroma_format_idc;
-	unsigned char bit_depth_luma_minus8;
-	unsigned char bit_depth_chroma_minus8;
-	unsigned char log2_max_frame_num_minus4;
-	unsigned char pic_order_cnt_type;
-	unsigned char log2_max_pic_order_cnt_lsb_minus4;
-	unsigned char max_num_ref_frames;
-	unsigned char separate_colour_plane_flag;
-	unsigned short pic_width_in_mbs_minus1;
-	unsigned short pic_height_in_map_units_minus1;
-	unsigned int max_frame_nums;
-	unsigned char qpprime_y_zero_transform_bypass_flag;
-	unsigned char delta_pic_order_always_zero_flag;
-	unsigned char frame_mbs_only_flag;
-	unsigned char mb_adaptive_frame_field_flag;
-	unsigned char direct_8x8_inference_flag;
-	unsigned char reserved[3];
-};
-
-/*
- * struct mtk_h264_pps_param  - parameters for pps
- */
-struct mtk_h264_pps_param {
-	unsigned char num_ref_idx_l0_default_active_minus1;
-	unsigned char num_ref_idx_l1_default_active_minus1;
-	unsigned char weighted_bipred_idc;
-	char pic_init_qp_minus26;
-	char chroma_qp_index_offset;
-	char second_chroma_qp_index_offset;
-	unsigned char entropy_coding_mode_flag;
-	unsigned char pic_order_present_flag;
-	unsigned char deblocking_filter_control_present_flag;
-	unsigned char constrained_intra_pred_flag;
-	unsigned char weighted_pred_flag;
-	unsigned char redundant_pic_cnt_present_flag;
-	unsigned char transform_8x8_mode_flag;
-	unsigned char scaling_matrix_present_flag;
-	unsigned char reserved[2];
-};
-
-struct slice_api_h264_scaling_matrix {
-	unsigned char scaling_list_4x4[6][16];
-	unsigned char scaling_list_8x8[6][64];
-};
-
-struct slice_h264_dpb_entry {
-	unsigned long long reference_ts;
-	unsigned short frame_num;
-	unsigned short pic_num;
-	/* Note that field is indicated by v4l2_buffer.field */
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
-};
-
-/*
- * struct slice_api_h264_decode_param - parameters for decode.
- */
-struct slice_api_h264_decode_param {
-	struct slice_h264_dpb_entry dpb[16];
-	unsigned short num_slices;
-	unsigned short nal_ref_idc;
-	unsigned char ref_pic_list_p0[32];
-	unsigned char ref_pic_list_b0[32];
-	unsigned char ref_pic_list_b1[32];
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
-};
+#include "vdec_h264_req_common.h"
 
 /*
  * struct mtk_h264_dec_slice_param  - parameters for decode current frame
@@ -127,22 +25,6 @@ struct mtk_h264_dec_slice_param {
 	struct mtk_h264_dpb_info h264_dpb_info[16];
 };
 
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va  : virtual address of struct vdec_fb
- * @y_fb_dma    : dma address of Y frame buffer (luma)
- * @c_fb_dma    : dma address of C frame buffer (chroma)
- * @poc         : picture order count of frame buffer
- * @reserved    : for 8 bytes alignment
- */
-struct h264_fb {
-	u64 vdec_fb_va;
-	u64 y_fb_dma;
-	u64 c_fb_dma;
-	s32 poc;
-	u32 reserved;
-};
-
 /**
  * struct vdec_h264_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
@@ -212,265 +94,35 @@ struct vdec_h264_slice_inst {
 	struct v4l2_h264_dpb_entry dpb[16];
 };
 
-static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
-{
-	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
-
-	return ctrl->p_cur.p;
-}
-
-static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
-			      struct mtk_h264_dec_slice_param *slice_param)
-{
-	struct vb2_queue *vq;
-	struct vb2_buffer *vb;
-	struct vb2_v4l2_buffer *vb2_v4l2;
-	u64 index;
-
-	vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-
-	for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
-		const struct slice_h264_dpb_entry *dpb;
-		int vb2_index;
-
-		dpb = &slice_param->decode_params.dpb[index];
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
-			slice_param->h264_dpb_info[index].reference_flag = 0;
-			continue;
-		}
-
-		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
-		if (vb2_index < 0) {
-			mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
-				       index, dpb->reference_ts);
-			continue;
-		}
-		/* 1 for short term reference, 2 for long term reference */
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
-			slice_param->h264_dpb_info[index].reference_flag = 1;
-		else
-			slice_param->h264_dpb_info[index].reference_flag = 2;
-
-		vb = vq->bufs[vb2_index];
-		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-		slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
-
-		slice_param->h264_dpb_info[index].y_dma_addr =
-			vb2_dma_contig_plane_dma_addr(vb, 0);
-		if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-			slice_param->h264_dpb_info[index].c_dma_addr =
-				vb2_dma_contig_plane_dma_addr(vb, 1);
-		}
-	}
-}
-
-static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
-				    const struct v4l2_ctrl_h264_sps *src_param)
-{
-	GET_MTK_VDEC_PARAM(chroma_format_idc);
-	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
-	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
-	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
-	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
-	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
-	GET_MTK_VDEC_PARAM(max_num_ref_frames);
-	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
-	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
-
-	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
-			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
-	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
-			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
-	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
-			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
-	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
-			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
-	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
-			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
-	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
-			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-}
-
-static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
-				    const struct v4l2_ctrl_h264_pps *src_param)
-{
-	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
-	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
-	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
-	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
-	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
-	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
-
-	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
-			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
-	GET_MTK_VDEC_FLAG(pic_order_present_flag,
-			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
-	GET_MTK_VDEC_FLAG(weighted_pred_flag,
-			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
-	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
-			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
-	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
-			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
-	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
-			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
-	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
-			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
-	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
-			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-}
-
-static void
-get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
-			const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
-{
-	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
-	       sizeof(dst_matrix->scaling_list_4x4));
-
-	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
-	       sizeof(dst_matrix->scaling_list_8x8));
-}
-
-static void
-get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
-			   const struct v4l2_ctrl_h264_decode_params *src_params,
-			   const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
-		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
-		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
-
-		dst_entry->reference_ts = src_entry->reference_ts;
-		dst_entry->frame_num = src_entry->frame_num;
-		dst_entry->pic_num = src_entry->pic_num;
-		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
-		dst_entry->bottom_field_order_cnt =
-			src_entry->bottom_field_order_cnt;
-		dst_entry->flags = src_entry->flags;
-	}
-
-	/*
-	 * num_slices is a leftover from the old H.264 support and is ignored
-	 * by the firmware.
-	 */
-	dst_params->num_slices = 0;
-	dst_params->nal_ref_idc = src_params->nal_ref_idc;
-	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
-	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
-	dst_params->flags = src_params->flags;
-}
-
-static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
-			    const struct v4l2_h264_dpb_entry *b)
-{
-	return a->top_field_order_cnt == b->top_field_order_cnt &&
-	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
-}
-
-/*
- * Move DPB entries of dec_param that refer to a frame already existing in dpb
- * into the already existing slot in dpb, and move other entries into new slots.
- *
- * This function is an adaptation of the similarly-named function in
- * hantro_h264.c.
- */
-static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
-		       struct v4l2_h264_dpb_entry *dpb)
-{
-	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	unsigned int i, j;
-
-	/* Disable all entries by default, and mark the ones in use. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
-			set_bit(i, in_use);
-		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
-	}
-
-	/* Try to match new DPB entries with existing ones by their POCs. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-
-		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-			continue;
-
-		/*
-		 * To cut off some comparisons, iterate only on target DPB
-		 * entries were already used.
-		 */
-		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
-			struct v4l2_h264_dpb_entry *cdpb;
-
-			cdpb = &dpb[j];
-			if (!dpb_entry_match(cdpb, ndpb))
-				continue;
-
-			*cdpb = *ndpb;
-			set_bit(j, used);
-			/* Don't reiterate on this one. */
-			clear_bit(j, in_use);
-			break;
-		}
-
-		if (j == ARRAY_SIZE(dec_param->dpb))
-			set_bit(i, new);
-	}
-
-	/* For entries that could not be matched, use remaining free slots. */
-	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-		struct v4l2_h264_dpb_entry *cdpb;
-
-		/*
-		 * Both arrays are of the same sizes, so there is no way
-		 * we can end up with no space in target array, unless
-		 * something is buggy.
-		 */
-		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
-		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
-			return;
-
-		cdpb = &dpb[j];
-		*cdpb = *ndpb;
-		set_bit(j, used);
-	}
-}
-
-/*
- * The firmware expects unused reflist entries to have the value 0x20.
- */
-static void fixup_ref_list(u8 *ref_list, size_t num_valid)
-{
-	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
-}
-
 static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 {
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	const struct v4l2_ctrl_h264_sps *sps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_SPS);
 	const struct v4l2_ctrl_h264_pps *pps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
 	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_SCALING_MATRIX);
 	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
 	struct v4l2_h264_reflist_builder reflist_builder;
 	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
 	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
 	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
 
-	update_dpb(dec_params, inst->dpb);
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
 
-	get_h264_sps_parameters(&slice_param->sps, sps);
-	get_h264_pps_parameters(&slice_param->pps, pps);
-	get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
-	get_h264_decode_parameters(&slice_param->decode_params, dec_params,
-				   inst->dpb);
-	get_h264_dpb_list(inst, slice_param);
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix,
+		scaling_matrix);
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params,
+		dec_params, inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+		slice_param->h264_dpb_info);
 
 	/* Build the reference lists */
 	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
@@ -478,21 +130,14 @@ static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
 	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
 	/* Adapt the built lists to the firmware's expectations */
-	fixup_ref_list(p0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
 
 	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
 	       sizeof(inst->vsi_ctx.h264_slice_params));
 }
 
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
-	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
-
-	return HW_MB_STORE_SZ * unit_size;
-}
-
 static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
 {
 	int err;
@@ -525,7 +170,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
 	int i;
 	int err;
 	struct mtk_vcodec_mem *mem = NULL;
-	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
 
 	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
 	for (i = 0; i < H264_MAX_MV_NUM; i++) {
@@ -674,7 +319,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+		V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
 	struct mtk_video_dec_buf *src_buf_info;
 	struct mtk_video_dec_buf *dst_buf_info;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:32 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:32 +0800
Subject: [PATCH v4,
 05/15] media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set
 capture buffer buffered
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-6-yunfei.dong@mediatek.com>

lat thread: output queue      \
                               -> lat hardware -> lat trans buffer
            lat trans buffer  /

core thread: capture queue     \
                                ->core hardware -> capture queue
             lat trans buffer  /

Lat and core work in different thread, setting capture buffer buffered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 5aebf88f997b..23a154c4e321 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -314,6 +314,9 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 
+	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
+		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
 	src_vq->requires_requests = true;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:35 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:35 +0800
Subject: [PATCH v4, 08/15] media: mtk-vcodec: Add format to support MT21C
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-9-yunfei.dong@mediatek.com>

Needs to use mediatek compressed mode for mt8192 decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c   | 7 ++++++-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h         | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 01bb96f3b30e..21895fbed4c5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,7 +81,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_video_fmt mtk_video_formats[3];
 static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
 
 static struct mtk_video_fmt default_out_format;
@@ -361,6 +361,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 		num_framesizes++;
 		break;
 	case V4L2_PIX_FMT_MM21:
+	case V4L2_PIX_FMT_MT21C:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
 		mtk_video_formats[count_formats].num_planes = 2;
@@ -387,6 +388,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
 		cap_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx);
+		cap_format_count++;
+	}
 	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cdc0a53eee4e..12a2baaf9e81 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,6 +353,7 @@ enum mtk_vdec_hw_arch {
  */
 enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:31 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:31 +0800
Subject: [PATCH v4,
 04/15] media: mtk-vcodec: Read max resolution from dec_capability
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-5-yunfei.dong@mediatek.com>

Supported max resolution for different platforms are not the same: 2K
or 4K, getting it according to dec_capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 31 +++++++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +++
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 130ecef2e766..65a224d788bf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -152,13 +152,15 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
 	q_data->field = V4L2_FIELD_NONE;
+	ctx->max_width = MTK_VDEC_MAX_W;
+	ctx->max_height = MTK_VDEC_MAX_H;
 
 	v4l_bound_align_image(&q_data->coded_width,
 				MTK_VDEC_MIN_W,
-				MTK_VDEC_MAX_W, 4,
+				ctx->max_width, 4,
 				&q_data->coded_height,
 				MTK_VDEC_MIN_H,
-				MTK_VDEC_MAX_H, 5, 6);
+				ctx->max_height, 5, 6);
 
 	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
 	q_data->bytesperline[0] = q_data->coded_width;
@@ -217,17 +219,17 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
 	}
 }
 
-static int vidioc_try_fmt(struct v4l2_format *f,
-			  const struct mtk_video_fmt *fmt)
+static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx,
+	struct v4l2_format *f, const struct mtk_video_fmt *fmt)
 {
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
 
 	pix_fmt_mp->field = V4L2_FIELD_NONE;
 
 	pix_fmt_mp->width =
-		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
+		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width);
 	pix_fmt_mp->height =
-		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
+		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height);
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		pix_fmt_mp->num_planes = 1;
@@ -245,16 +247,16 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 		tmp_h = pix_fmt_mp->height;
 		v4l_bound_align_image(&pix_fmt_mp->width,
 					MTK_VDEC_MIN_W,
-					MTK_VDEC_MAX_W, 6,
+					ctx->max_width, 6,
 					&pix_fmt_mp->height,
 					MTK_VDEC_MIN_H,
-					MTK_VDEC_MAX_H, 6, 9);
+					ctx->max_height, 6, 9);
 
 		if (pix_fmt_mp->width < tmp_w &&
-			(pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W)
+			(pix_fmt_mp->width + 64) <= ctx->max_width)
 			pix_fmt_mp->width += 64;
 		if (pix_fmt_mp->height < tmp_h &&
-			(pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H)
+			(pix_fmt_mp->height + 64) <= ctx->max_height)
 			pix_fmt_mp->height += 64;
 
 		mtk_v4l2_debug(0,
@@ -294,7 +296,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
@@ -317,7 +319,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 		return -EINVAL;
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -445,7 +447,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		return -EINVAL;
 
 	q_data->fmt = fmt;
-	vidioc_try_fmt(f, q_data->fmt);
+	vidioc_try_fmt(ctx, f, q_data->fmt);
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
 		q_data->coded_width = pix_mp->width;
@@ -545,6 +547,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 				fsize->stepwise.min_height,
 				fsize->stepwise.max_height,
 				fsize->stepwise.step_height);
+
+		ctx->max_width = fsize->stepwise.max_width;
+		ctx->max_height = fsize->stepwise.max_height;
 		return 0;
 	}
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 45d9e1be7063..199f5f0b9152 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -287,6 +287,8 @@ struct vdec_pic_info {
  *	  mtk_video_dec_buf.
  * @hw_id: hardware index used to identify different hardware.
  *
+ * @max_width: hardware supported max width
+ * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
@@ -332,6 +334,8 @@ struct mtk_vcodec_ctx {
 	struct mutex lock;
 	int hw_id;
 
+	unsigned int max_width;
+	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:33 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:33 +0800
Subject: [PATCH v4,
 06/15] media: mtk-vcodec: Refactor get and put capture buffer flow
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-7-yunfei.dong@mediatek.com>

For lat and core decode in parallel, need to get capture buffer
when core start to decode and put put capture buffer to display
list when core decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 123 ++++++++++++------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  16 ++-
 3 files changed, 104 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23a154c4e321..f3036c3f223b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -108,37 +108,89 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 
 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
 
-static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
-					       struct vdec_fb *fb)
+static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
+					   struct mtk_vcodec_mem *bs, int error)
 {
-	struct mtk_video_dec_buf *vdec_frame_buf =
-		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
-	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
-	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	struct mtk_video_dec_buf *out_buf;
+	struct vb2_v4l2_buffer *vb;
 
-	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
-	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		unsigned int cap_c_size =
-			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+	if (!bs) {
+		mtk_v4l2_err("Free bitstream buffer fail.");
+		return;
+	}
+	out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	vb = &out_buf->m2m_buf.vb;
+
+	mtk_v4l2_debug(2,
+		"Free bitsteam buffer id = %d to done_list",
+		vb->vb2_buf.index);
+
+	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+	if (error) {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		if (error == -EIO)
+			out_buf->error = true;
+	} else {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+	}
+}
 
-		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx,
+					   struct vdec_fb *fb, int error)
+{
+	struct mtk_video_dec_buf *vdec_frame_buf;
+	struct vb2_v4l2_buffer *vb;
+	unsigned int cap_y_size, cap_c_size;
+
+	if (!fb) {
+		mtk_v4l2_err("Free frame buffer fail.");
+		return;
 	}
+	vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf,
+				      frame_buffer);
+	vb = &vdec_frame_buf->m2m_buf.vb;
+
+	cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+
+	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+
+	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+
+	mtk_v4l2_debug(2,
+		"Free frame buffer id = %d to done_list",
+		vb->vb2_buf.index);
+	if (error)
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+	else
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
 }
 
-static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
-					   struct vb2_v4l2_buffer *vb2_v4l2)
+static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
 {
-	struct mtk_video_dec_buf *framebuf =
-		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
-	struct vdec_fb *pfb = &framebuf->frame_buffer;
-	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+	struct mtk_video_dec_buf *framebuf;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vb2_buffer *dst_buf;
+	struct vdec_fb *pfb;
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2) {
+		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
+		return NULL;
+	}
 
-	pfb->base_y.va = NULL;
+	dst_buf = &vb2_v4l2->vb2_buf;
+	framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	pfb = &framebuf->frame_buffer;
+	pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
 	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
 	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
 
 	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		pfb->base_c.va = NULL;
+		pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
 		pfb->base_c.dma_addr =
 			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
 		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
@@ -162,12 +214,11 @@ static void mtk_vdec_worker(struct work_struct *work)
 	struct mtk_vcodec_ctx *ctx =
 		container_of(work, struct mtk_vcodec_ctx, decode_work);
 	struct mtk_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
+	struct vb2_v4l2_buffer *vb2_v4l2_src;
 	struct vb2_buffer *vb2_src;
 	struct mtk_vcodec_mem *bs_src;
 	struct mtk_video_dec_buf *dec_buf_src;
 	struct media_request *src_buf_req;
-	struct vdec_fb *dst_buf;
 	bool res_chg = false;
 	int ret;
 
@@ -178,13 +229,6 @@ static void mtk_vdec_worker(struct work_struct *work)
 		return;
 	}
 
-	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	if (!vb2_v4l2_dst) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
-		return;
-	}
-
 	vb2_src = &vb2_v4l2_src->vb2_buf;
 	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
 				   m2m_buf.vb);
@@ -193,9 +237,15 @@ static void mtk_vdec_worker(struct work_struct *work)
 	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
 		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
 
-	bs_src->va = NULL;
+	bs_src->va = vb2_plane_vaddr(vb2_src, 0);
 	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
 	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
+	if (!bs_src->va) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id,
+			vb2_src->index);
+		return;
+	}
 
 	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
 		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
@@ -206,9 +256,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 	else
 		mtk_v4l2_err("vb2 buffer media request is NULL");
 
-	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
-	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
-	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+	ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
 	if (ret) {
 		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
 			     ctx->id, vb2_src->index, bs_src->size,
@@ -220,12 +268,9 @@ static void mtk_vdec_worker(struct work_struct *work)
 		}
 	}
 
-	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
-
-	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
-					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
+	mtk_vdec_stateless_out_to_done(ctx, bs_src, ret);
 	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
 static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
@@ -358,6 +403,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = false,
 	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
@@ -376,6 +423,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = true,
 	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 199f5f0b9152..009f9124a57d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,7 +353,8 @@ enum mtk_vdec_hw_arch {
  * @ctrls_setup: init vcodec dec ctrls
  * @worker: worker to start a decode job
  * @flush_decoder: function that flushes the decoder
- *
+ * @get_cap_buffer: get capture buffer from capture queue
+ * @cap_to_disp: put capture buffer to disp list
  * @vdec_vb2_ops: struct vb2_ops
  *
  * @vdec_formats: supported video decoder formats
@@ -375,6 +376,8 @@ struct mtk_vcodec_dec_pdata {
 	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
 	void (*worker)(struct work_struct *work);
 	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
+	struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
+	void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, struct vdec_fb *fb, int error);
 
 	struct vb2_ops *vdec_vb2_ops;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 43542de11e9c..d00219a7587c 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -670,32 +670,42 @@ static void vdec_h264_slice_deinit(void *h_vdec)
 }
 
 static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
-				  struct vdec_fb *fb, bool *res_chg)
+				  struct vdec_fb *unused, bool *res_chg)
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
 		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	struct mtk_video_dec_buf *dst_buf_info;
+	struct vdec_fb *fb;
 	u32 data[2];
 	u64 y_fb_dma;
 	u64 c_fb_dma;
 	int err;
 
+	inst->num_nalu++;
 	/* bs NULL means flush decoder */
 	if (!bs)
 		return vpu_dec_reset(vpu);
 
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
 	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
 	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
 
 	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
-			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+			 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
 
 	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
 	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
 	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
 	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
 
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+		&dst_buf_info->m2m_buf.vb, true);
 	get_vdec_decode_parameters(inst);
 	data[0] = bs->size;
 	/*
@@ -734,6 +744,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
 	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
+
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, 0);
 	return 0;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:34 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:34 +0800
Subject: [PATCH v4,
 07/15] media: mtk-vcodec: Refactor supported vdec formats and
 framesizes
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-8-yunfei.dong@mediatek.com>

Supported output and capture format types for mt8192 are different
with mt8183. Needs to get format types according to decoder capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   8 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 117 +++++++++++++-----
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  13 +-
 4 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 65a224d788bf..519f2b9d9b5b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -26,7 +26,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	const struct mtk_video_fmt *fmt;
 	unsigned int k;
 
-	for (k = 0; k < dec_pdata->num_formats; k++) {
+	for (k = 0; k < *dec_pdata->num_formats; k++) {
 		fmt = &dec_pdata->vdec_formats[k];
 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
 			return fmt;
@@ -525,7 +525,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	for (i = 0; i < dec_pdata->num_framesizes; ++i) {
+	for (i = 0; i < *dec_pdata->num_framesizes; ++i) {
 		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
 			continue;
 
@@ -564,7 +564,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 	const struct mtk_video_fmt *fmt;
 	int i, j = 0;
 
-	for (i = 0; i < dec_pdata->num_formats; i++) {
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
 		if (output_queue &&
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
 			continue;
@@ -577,7 +577,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		++j;
 	}
 
-	if (i == dec_pdata->num_formats)
+	if (i == *dec_pdata->num_formats)
 		return -EINVAL;
 
 	fmt = &dec_pdata->vdec_formats[i];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 7966c132be8f..3f33beb9c551 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -37,7 +37,9 @@ static const struct mtk_video_fmt mtk_video_formats[] = {
 	},
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+static const unsigned int num_supported_formats =
+	ARRAY_SIZE(mtk_video_formats);
+
 #define DEFAULT_OUT_FMT_IDX 0
 #define DEFAULT_CAP_FMT_IDX 3
 
@@ -59,7 +61,8 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 	},
 };
 
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+static const unsigned int num_supported_framesize =
+	ARRAY_SIZE(mtk_vdec_framesizes);
 
 /*
  * This function tries to clean all display buffers, the buffers will return
@@ -235,7 +238,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
 	unsigned int k;
 
 	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (k = 0; k < NUM_FORMATS; k++) {
+	for (k = 0; k < num_supported_formats; k++) {
 		fmt = &mtk_video_formats[k];
 		if (fmt->fourcc == pixelformat) {
 			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
@@ -617,11 +620,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
+	.num_formats = &num_supported_formats,
 	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
 	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_supported_framesize,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index f3036c3f223b..01bb96f3b30e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,33 +81,23 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static const struct mtk_video_fmt mtk_video_formats[] = {
-	{
-		.fourcc = V4L2_PIX_FMT_H264_SLICE,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_MM21,
-		.type = MTK_FMT_FRAME,
-		.num_planes = 2,
-	},
+static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+
+static struct mtk_video_fmt default_out_format;
+static struct mtk_video_fmt default_cap_format;
+static unsigned int num_formats = 0;
+static unsigned int num_framesizes = 0;
+
+static struct v4l2_frmsize_stepwise stepwise_fhd = {
+	.min_width = MTK_VDEC_MIN_W,
+	.max_width = MTK_VDEC_MAX_W,
+	.step_width = 16,
+	.min_height = MTK_VDEC_MIN_H,
+	.max_height = MTK_VDEC_MAX_H,
+	.step_height = 16
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX    0
-#define DEFAULT_CAP_FMT_IDX    1
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_H264_SLICE,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
 static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
 					   struct mtk_vcodec_mem *bs, int error)
 {
@@ -352,6 +342,63 @@ const struct media_device_ops mtk_vcodec_media_ops = {
 	.req_queue	= v4l2_m2m_request_queue,
 };
 
+static void mtk_vcodec_add_formats(unsigned int fourcc,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata;
+	int count_formats = *pdata->num_formats;
+	int count_framesizes = *pdata->num_framesizes;
+
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264_SLICE:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
+		mtk_video_formats[count_formats].num_planes = 1;
+
+		mtk_vdec_framesizes[count_framesizes].fourcc = fourcc;
+		mtk_vdec_framesizes[count_framesizes].stepwise = stepwise_fhd;
+		num_framesizes++;
+		break;
+	case V4L2_PIX_FMT_MM21:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
+		mtk_video_formats[count_formats].num_planes = 2;
+		break;
+	default:
+		mtk_v4l2_err("Can not add unsupported format type");
+		return;
+	}
+
+	num_formats++;
+	mtk_v4l2_debug(3, "num_formats: %d num_frames:%d dec_capability: 0x%x",
+		*(pdata->num_formats), *(pdata->num_framesizes),
+		ctx->dev->dec_capability);
+}
+
+static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
+{
+	int cap_format_count = 0, out_format_count = 0;
+
+	if (num_formats && num_framesizes)
+		return;
+
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
+		cap_format_count++;
+	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
+		out_format_count++;
+	}
+
+	if (cap_format_count)
+		default_cap_format = mtk_video_formats[cap_format_count - 1];
+	if (out_format_count)
+		default_out_format =
+			mtk_video_formats[cap_format_count + out_format_count - 1];
+}
+
 static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct vb2_queue *src_vq;
@@ -361,6 +408,10 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 
 	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
 		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+	else
+		ctx->dev->dec_capability |=
+			MTK_VDEC_FORMAT_H264_SLICE | MTK_VDEC_FORMAT_MM21;
+	mtk_vcodec_get_supported_formats(ctx);
 
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
@@ -395,11 +446,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
@@ -415,11 +466,11 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 009f9124a57d..cdc0a53eee4e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -347,6 +347,15 @@ enum mtk_vdec_hw_arch {
 	MTK_VDEC_LAT_SINGLE_CORE,
 };
 
+/**
+ * struct mtk_vdec_format_types - Structure used to get supported
+ *		  format types according to decoder capability
+ */
+enum mtk_vdec_format_types {
+	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -382,12 +391,12 @@ struct mtk_vcodec_dec_pdata {
 	struct vb2_ops *vdec_vb2_ops;
 
 	const struct mtk_video_fmt *vdec_formats;
-	const int num_formats;
+	const int *num_formats;
 	const struct mtk_video_fmt *default_out_fmt;
 	const struct mtk_video_fmt *default_cap_fmt;
 
 	const struct mtk_codec_framesizes *vdec_framesizes;
-	const int num_framesizes;
+	const int *num_framesizes;
 
 	enum mtk_vdec_hw_arch hw_arch;
 
-- 
2.25.1



From krzk at kernel.org  Mon Jan 10 00:39:33 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 09:39:33 +0100
Subject: [PATCH v1 03/14] arm64: defconfig: rebuild default configuration
In-Reply-To: <20220107180314.1816515-4-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-4-marcel@ziswiler.com>
Message-ID: <c0d9b876-ea21-2706-4330-5878ad1cdedd@kernel.org>

On 07/01/2022 19:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Run "make defconfig; make savedefconfig" to rebuild defconfig.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  arch/arm64/configs/defconfig | 135 +++++++++++++----------------------
>  1 file changed, 50 insertions(+), 85 deletions(-)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index cc5d3ba166b1..79e4bf9f4c2c 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -3,17 +3,14 @@ CONFIG_POSIX_MQUEUE=y
>  CONFIG_AUDIT=y
>  CONFIG_NO_HZ_IDLE=y
>  CONFIG_HIGH_RES_TIMERS=y
> -CONFIG_PREEMPT=y
> +CONFIG_BPF_JIT=y
>  CONFIG_IRQ_TIME_ACCOUNTING=y
>  CONFIG_BSD_PROCESS_ACCT=y
>  CONFIG_BSD_PROCESS_ACCT_V3=y
> -CONFIG_TASK_XACCT=y
> -CONFIG_TASK_IO_ACCOUNTING=y
>  CONFIG_IKCONFIG=y
>  CONFIG_IKCONFIG_PROC=y
>  CONFIG_NUMA_BALANCING=y
>  CONFIG_MEMCG=y
> -CONFIG_MEMCG_SWAP=y
>  CONFIG_BLK_CGROUP=y
>  CONFIG_CGROUP_PIDS=y
>  CONFIG_CGROUP_HUGETLB=y
> @@ -66,7 +63,6 @@ CONFIG_ARM64_VA_BITS_48=y
>  CONFIG_SCHED_MC=y
>  CONFIG_SCHED_SMT=y
>  CONFIG_NUMA=y
> -CONFIG_SECCOMP=y
>  CONFIG_KEXEC=y
>  CONFIG_KEXEC_FILE=y
>  CONFIG_CRASH_DUMP=y
> @@ -84,7 +80,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
>  CONFIG_CPU_FREQ_GOV_USERSPACE=y
>  CONFIG_CPU_FREQ_GOV_ONDEMAND=y
>  CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
> -CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
>  CONFIG_CPUFREQ_DT=y
>  CONFIG_ACPI_CPPC_CPUFREQ=m
>  CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
> @@ -97,19 +92,9 @@ CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
>  CONFIG_ARM_SCMI_CPUFREQ=y
>  CONFIG_ARM_TEGRA186_CPUFREQ=y
>  CONFIG_QORIQ_CPUFREQ=y
> -CONFIG_ARM_SCMI_PROTOCOL=y
> -CONFIG_ARM_SCPI_PROTOCOL=y
> -CONFIG_RASPBERRYPI_FIRMWARE=y
> -CONFIG_INTEL_STRATIX10_SERVICE=y
> -CONFIG_INTEL_STRATIX10_RSU=m
> -CONFIG_QCOM_SCM=y
> -CONFIG_EFI_CAPSULE_LOADER=y
> -CONFIG_IMX_SCU=y
> -CONFIG_IMX_SCU_PD=y
>  CONFIG_ACPI=y
>  CONFIG_ACPI_APEI=y
>  CONFIG_ACPI_APEI_GHES=y
> -CONFIG_ACPI_APEI_PCIEAER=y
>  CONFIG_ACPI_APEI_MEMORY_FAILURE=y
>  CONFIG_ACPI_APEI_EINJ=y
>  CONFIG_VIRTUALIZATION=y
> @@ -182,14 +167,12 @@ CONFIG_NET_ACT_GATE=m
>  CONFIG_QRTR=m
>  CONFIG_QRTR_SMD=m
>  CONFIG_QRTR_TUN=m
> -CONFIG_BPF_JIT=y
>  CONFIG_CAN=m
> +CONFIG_CAN_FLEXCAN=m
>  CONFIG_CAN_RCAR=m
>  CONFIG_CAN_RCAR_CANFD=m
> -CONFIG_CAN_FLEXCAN=m
>  CONFIG_BT=m
>  CONFIG_BT_HIDP=m
> -# CONFIG_BT_HS is not set
>  # CONFIG_BT_LE is not set
>  CONFIG_BT_LEDS=y
>  # CONFIG_BT_DEBUGFS is not set
> @@ -228,7 +211,6 @@ CONFIG_PCIE_ROCKCHIP_HOST=m
>  CONFIG_PCIE_BRCMSTB=m
>  CONFIG_PCI_IMX6=y
>  CONFIG_PCI_LAYERSCAPE=y
> -CONFIG_PCIE_LAYERSCAPE_GEN4=y
>  CONFIG_PCI_HISI=y
>  CONFIG_PCIE_QCOM=y
>  CONFIG_PCIE_ARMADA_8K=y
> @@ -236,6 +218,11 @@ CONFIG_PCIE_KIRIN=y
>  CONFIG_PCIE_HISI_STB=y
>  CONFIG_PCIE_TEGRA194_HOST=m
>  CONFIG_PCIE_VISCONTI_HOST=y
> +CONFIG_PCIE_LAYERSCAPE_GEN4=y
> +CONFIG_PCIE_CADENCE_PLAT_HOST=y
> +CONFIG_PCIE_CADENCE_PLAT_EP=y
> +CONFIG_PCI_J721E_HOST=y
> +CONFIG_PCI_J721E_EP=y
>  CONFIG_PCI_ENDPOINT=y
>  CONFIG_PCI_ENDPOINT_CONFIGFS=y
>  CONFIG_PCI_EPF_TEST=m
> @@ -243,8 +230,15 @@ CONFIG_DEVTMPFS=y
>  CONFIG_DEVTMPFS_MOUNT=y
>  CONFIG_FW_LOADER_USER_HELPER=y
>  CONFIG_HISILICON_LPC=y
> -CONFIG_FSL_MC_BUS=y
>  CONFIG_TEGRA_ACONNECT=m
> +CONFIG_ARM_SCMI_PROTOCOL=y
> +CONFIG_ARM_SCPI_PROTOCOL=y
> +CONFIG_RASPBERRYPI_FIRMWARE=y
> +CONFIG_INTEL_STRATIX10_SERVICE=y
> +CONFIG_INTEL_STRATIX10_RSU=m
> +CONFIG_EFI_CAPSULE_LOADER=y
> +CONFIG_IMX_SCU=y
> +CONFIG_IMX_SCU_PD=y
>  CONFIG_GNSS=m
>  CONFIG_GNSS_MTK_SERIAL=m
>  CONFIG_MTD=y
> @@ -261,11 +255,10 @@ CONFIG_MTD_SST25L=y
>  CONFIG_MTD_RAW_NAND=y
>  CONFIG_MTD_NAND_DENALI_DT=y
>  CONFIG_MTD_NAND_MARVELL=y
> +CONFIG_MTD_NAND_BRCMNAND=m
>  CONFIG_MTD_NAND_FSL_IFC=y
>  CONFIG_MTD_NAND_QCOM=y
>  CONFIG_MTD_SPI_NOR=y
> -CONFIG_MTK_DEVAPC=m
> -CONFIG_SPI_CADENCE_QUADSPI=y
>  CONFIG_BLK_DEV_LOOP=y
>  CONFIG_BLK_DEV_NBD=m
>  CONFIG_VIRTIO_BLK=y
> @@ -315,6 +308,7 @@ CONFIG_NET_XGENE=y
>  CONFIG_ATL1C=m
>  CONFIG_BCMGENET=m
>  CONFIG_BNX2X=m
> +CONFIG_SYSTEMPORT=m
>  CONFIG_MACB=y
>  CONFIG_THUNDER_NIC_PF=y
>  CONFIG_FEC=y
> @@ -351,13 +345,11 @@ CONFIG_SNI_NETSEC=y
>  CONFIG_STMMAC_ETH=m
>  CONFIG_TI_K3_AM65_CPSW_NUSS=y
>  CONFIG_QCOM_IPA=m
> -CONFIG_MDIO_BUS_MUX_MMIOREG=y
> -CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
> +CONFIG_MESON_GXL_PHY=m
>  CONFIG_AQUANTIA_PHY=y
>  CONFIG_BCM54140_PHY=m
>  CONFIG_MARVELL_PHY=m
>  CONFIG_MARVELL_10G_PHY=m
> -CONFIG_MESON_GXL_PHY=m
>  CONFIG_MICREL_PHY=y
>  CONFIG_MICROSEMI_PHY=y
>  CONFIG_AT803X_PHY=y
> @@ -365,6 +357,8 @@ CONFIG_REALTEK_PHY=y
>  CONFIG_ROCKCHIP_PHY=y
>  CONFIG_DP83867_PHY=y
>  CONFIG_VITESSE_PHY=y
> +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
> +CONFIG_MDIO_BUS_MUX_MMIOREG=y
>  CONFIG_USB_PEGASUS=m
>  CONFIG_USB_RTL8150=m
>  CONFIG_USB_RTL8152=m
> @@ -406,6 +400,8 @@ CONFIG_SERIO_AMBAKMI=y
>  CONFIG_LEGACY_PTY_COUNT=16
>  CONFIG_SERIAL_8250=y
>  CONFIG_SERIAL_8250_CONSOLE=y
> +CONFIG_SERIAL_8250_NR_UARTS=16
> +CONFIG_SERIAL_8250_RUNTIME_UARTS=16
>  CONFIG_SERIAL_8250_EXTENDED=y
>  CONFIG_SERIAL_8250_SHARE_IRQ=y
>  CONFIG_SERIAL_8250_BCM2835AUX=y
> @@ -472,6 +468,7 @@ CONFIG_SPI=y
>  CONFIG_SPI_ARMADA_3700=y
>  CONFIG_SPI_BCM2835=m
>  CONFIG_SPI_BCM2835AUX=m
> +CONFIG_SPI_CADENCE_QUADSPI=y
>  CONFIG_SPI_DESIGNWARE=m
>  CONFIG_SPI_DW_DMA=y
>  CONFIG_SPI_DW_MMIO=m
> @@ -507,22 +504,7 @@ CONFIG_PINCTRL_IMX8QM=y
>  CONFIG_PINCTRL_IMX8QXP=y
>  CONFIG_PINCTRL_IMX8DXL=y
>  CONFIG_PINCTRL_IMX8ULP=y
> -CONFIG_PINCTRL_MSM=y
> -CONFIG_PINCTRL_IPQ8074=y
> -CONFIG_PINCTRL_IPQ6018=y
> -CONFIG_PINCTRL_MSM8916=y
> -CONFIG_PINCTRL_MSM8994=y
> -CONFIG_PINCTRL_MSM8996=y
> -CONFIG_PINCTRL_MSM8998=y
> -CONFIG_PINCTRL_QCS404=y
> -CONFIG_PINCTRL_QDF2XXX=y
>  CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
> -CONFIG_PINCTRL_SC7180=y
> -CONFIG_PINCTRL_SC7280=y
> -CONFIG_PINCTRL_SDM845=y
> -CONFIG_PINCTRL_SM8150=y
> -CONFIG_PINCTRL_SM8250=y
> -CONFIG_PINCTRL_SM8350=y
>  CONFIG_PINCTRL_LPASS_LPI=m
>  CONFIG_GPIO_ALTERA=m
>  CONFIG_GPIO_DAVINCI=y
> @@ -543,9 +525,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
>  CONFIG_GPIO_BD9571MWV=m
>  CONFIG_GPIO_MAX77620=y
>  CONFIG_GPIO_SL28CPLD=m
> -CONFIG_POWER_AVS=y
> -CONFIG_QCOM_CPR=y
> -CONFIG_ROCKCHIP_IODOMAIN=y
>  CONFIG_POWER_RESET_MSM=y
>  CONFIG_POWER_RESET_QCOM_PON=m
>  CONFIG_POWER_RESET_XGENE=y
> @@ -553,10 +532,10 @@ CONFIG_POWER_RESET_SYSCON=y
>  CONFIG_SYSCON_REBOOT_MODE=y
>  CONFIG_BATTERY_SBS=m
>  CONFIG_BATTERY_BQ27XXX=y
> -CONFIG_SENSORS_ARM_SCMI=y
>  CONFIG_BATTERY_MAX17042=m
>  CONFIG_CHARGER_BQ25890=m
>  CONFIG_CHARGER_BQ25980=m
> +CONFIG_SENSORS_ARM_SCMI=y
>  CONFIG_SENSORS_ARM_SCPI=y
>  CONFIG_SENSORS_JC42=m
>  CONFIG_SENSORS_LM90=m
> @@ -568,10 +547,10 @@ CONFIG_SENSORS_INA3221=m
>  CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
>  CONFIG_CPU_THERMAL=y
>  CONFIG_THERMAL_EMULATION=y
> -CONFIG_QORIQ_THERMAL=m
> -CONFIG_SUN8I_THERMAL=y
>  CONFIG_IMX_SC_THERMAL=m
>  CONFIG_IMX8MM_THERMAL=m
> +CONFIG_QORIQ_THERMAL=m
> +CONFIG_SUN8I_THERMAL=y
>  CONFIG_ROCKCHIP_THERMAL=m
>  CONFIG_RCAR_THERMAL=y
>  CONFIG_RCAR_GEN3_THERMAL=y
> @@ -580,8 +559,8 @@ CONFIG_BCM2711_THERMAL=m
>  CONFIG_BCM2835_THERMAL=m
>  CONFIG_BRCMSTB_THERMAL=m
>  CONFIG_EXYNOS_THERMAL=y
> -CONFIG_TEGRA_BPMP_THERMAL=m
>  CONFIG_TEGRA_SOCTHERM=m
> +CONFIG_TEGRA_BPMP_THERMAL=m
>  CONFIG_QCOM_TSENS=y
>  CONFIG_QCOM_SPMI_TEMP_ALARM=m
>  CONFIG_QCOM_LMH=m
> @@ -590,7 +569,6 @@ CONFIG_WATCHDOG=y
>  CONFIG_SL28CPLD_WATCHDOG=m
>  CONFIG_ARM_SP805_WATCHDOG=y
>  CONFIG_ARM_SBSA_WATCHDOG=y
> -CONFIG_ARM_SMC_WATCHDOG=y
>  CONFIG_S3C2410_WATCHDOG=y
>  CONFIG_DW_WATCHDOG=y
>  CONFIG_SUNXI_WATCHDOG=m
> @@ -599,9 +577,11 @@ CONFIG_IMX_SC_WDT=m
>  CONFIG_QCOM_WDT=m
>  CONFIG_MESON_GXBB_WATCHDOG=m
>  CONFIG_MESON_WATCHDOG=m
> +CONFIG_ARM_SMC_WATCHDOG=y
>  CONFIG_RENESAS_WDT=y
>  CONFIG_UNIPHIER_WATCHDOG=y
>  CONFIG_BCM2835_WDT=y
> +CONFIG_BCM7038_WDT=m
>  CONFIG_MFD_ALTERA_SYSMGR=y
>  CONFIG_MFD_BD9571MWV=y
>  CONFIG_MFD_AXP20X_I2C=y
> @@ -651,13 +631,12 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
>  CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
>  CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
>  CONFIG_MEDIA_SDR_SUPPORT=y
> -CONFIG_MEDIA_CONTROLLER=y
> -CONFIG_VIDEO_V4L2_SUBDEV_API=y
>  CONFIG_MEDIA_PLATFORM_SUPPORT=y
>  # CONFIG_DVB_NET is not set
>  CONFIG_MEDIA_USB_SUPPORT=y
>  CONFIG_USB_VIDEO_CLASS=m
>  CONFIG_V4L_PLATFORM_DRIVERS=y
> +CONFIG_VIDEO_QCOM_CAMSS=m
>  CONFIG_VIDEO_RCAR_CSI2=m
>  CONFIG_VIDEO_RCAR_VIN=m
>  CONFIG_VIDEO_SUN6I_CSI=m
> @@ -674,7 +653,6 @@ CONFIG_VIDEO_RCAR_DRIF=m
>  CONFIG_VIDEO_IMX219=m
>  CONFIG_VIDEO_OV5640=m
>  CONFIG_VIDEO_OV5645=m
> -CONFIG_VIDEO_QCOM_CAMSS=m
>  CONFIG_DRM=m
>  CONFIG_DRM_I2C_NXP_TDA998X=m
>  CONFIG_DRM_MALI_DISPLAY=m
> @@ -701,24 +679,23 @@ CONFIG_DRM_SUN8I_DW_HDMI=m
>  CONFIG_DRM_SUN8I_MIXER=m
>  CONFIG_DRM_MSM=m
>  CONFIG_DRM_TEGRA=m
> +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
>  CONFIG_DRM_PANEL_LVDS=m
>  CONFIG_DRM_PANEL_SIMPLE=m
>  CONFIG_DRM_PANEL_EDP=m
> -CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
>  CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
>  CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
>  CONFIG_DRM_PANEL_SITRONIX_ST7703=m
>  CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
> -CONFIG_DRM_DISPLAY_CONNECTOR=m
>  CONFIG_DRM_LONTIUM_LT8912B=m
> -CONFIG_DRM_NWL_MIPI_DSI=m
>  CONFIG_DRM_LONTIUM_LT9611=m
> +CONFIG_DRM_LONTIUM_LT9611UXC=m
> +CONFIG_DRM_NWL_MIPI_DSI=m
>  CONFIG_DRM_PARADE_PS8640=m
>  CONFIG_DRM_SII902X=m
>  CONFIG_DRM_SIMPLE_BRIDGE=m
>  CONFIG_DRM_THINE_THC63LVD1024=m
>  CONFIG_DRM_TI_SN65DSI86=m
> -CONFIG_DRM_LONTIUM_LT9611UXC=m
>  CONFIG_DRM_I2C_ADV7511=m
>  CONFIG_DRM_I2C_ADV7511_AUDIO=y
>  CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
> @@ -749,15 +726,14 @@ CONFIG_SND_HDA_TEGRA=m
>  CONFIG_SND_HDA_CODEC_HDMI=m
>  CONFIG_SND_SOC=y
>  CONFIG_SND_BCM2835_SOC_I2S=m
> -CONFIG_SND_SOC_FSL_SAI=m
>  CONFIG_SND_SOC_FSL_ASRC=m
>  CONFIG_SND_SOC_FSL_MICFIL=m
>  CONFIG_SND_SOC_FSL_EASRC=m
>  CONFIG_SND_IMX_SOC=m
>  CONFIG_SND_SOC_IMX_SGTL5000=m
>  CONFIG_SND_SOC_IMX_SPDIF=m
> -CONFIG_SND_SOC_IMX_AUDMIX=m
>  CONFIG_SND_SOC_FSL_ASOC_CARD=m
> +CONFIG_SND_SOC_IMX_AUDMIX=m
>  CONFIG_SND_MESON_AXG_SOUND_CARD=m
>  CONFIG_SND_MESON_GX_SOUND_CARD=m
>  CONFIG_SND_SOC_QCOM=m
> @@ -811,13 +787,12 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
>  CONFIG_HID_MULTITOUCH=m
>  CONFIG_I2C_HID_ACPI=m
>  CONFIG_I2C_HID_OF=m
> -CONFIG_USB_CONN_GPIO=m
>  CONFIG_USB=y
>  CONFIG_USB_OTG=y
>  CONFIG_USB_XHCI_HCD=y
> -CONFIG_USB_XHCI_PCI=m
>  CONFIG_USB_XHCI_PCI_RENESAS=m
>  CONFIG_USB_XHCI_TEGRA=y
> +CONFIG_USB_BRCMSTB=m
>  CONFIG_USB_EHCI_HCD=y
>  CONFIG_USB_EHCI_EXYNOS=y
>  CONFIG_USB_EHCI_HCD_PLATFORM=y
> @@ -862,8 +837,8 @@ CONFIG_TYPEC=m
>  CONFIG_TYPEC_TCPM=m
>  CONFIG_TYPEC_TCPCI=m
>  CONFIG_TYPEC_FUSB302=m
> -CONFIG_TYPEC_HD3SS3220=m
>  CONFIG_TYPEC_TPS6598X=m
> +CONFIG_TYPEC_HD3SS3220=m
>  CONFIG_MMC=y
>  CONFIG_MMC_BLOCK_MINORS=32
>  CONFIG_MMC_ARMMMCI=y
> @@ -961,7 +936,6 @@ CONFIG_VIRTIO_BALLOON=y
>  CONFIG_VIRTIO_MMIO=y
>  CONFIG_XEN_GNTDEV=y
>  CONFIG_XEN_GRANT_DEV_ALLOC=y
> -CONFIG_MFD_CROS_EC_DEV=y
>  CONFIG_STAGING=y
>  CONFIG_STAGING_MEDIA=y
>  CONFIG_VIDEO_HANTRO=m
> @@ -971,15 +945,14 @@ CONFIG_CROS_EC=y
>  CONFIG_CROS_EC_I2C=y
>  CONFIG_CROS_EC_SPI=y
>  CONFIG_CROS_EC_CHARDEV=m
> -CONFIG_COMMON_CLK_SCMI=y
>  CONFIG_COMMON_CLK_RK808=y
> +CONFIG_COMMON_CLK_SCMI=y
>  CONFIG_COMMON_CLK_SCPI=y
>  CONFIG_COMMON_CLK_CS2000_CP=y
>  CONFIG_COMMON_CLK_FSL_SAI=y
>  CONFIG_COMMON_CLK_S2MPS11=y
>  CONFIG_COMMON_CLK_PWM=y
>  CONFIG_COMMON_CLK_VC5=y
> -CONFIG_COMMON_CLK_ZYNQMP=y
>  CONFIG_COMMON_CLK_BD718XX=m
>  CONFIG_CLK_RASPBERRYPI=m
>  CONFIG_CLK_IMX8MM=y
> @@ -995,8 +968,8 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y
>  CONFIG_QCOM_CLK_APCC_MSM8996=y
>  CONFIG_QCOM_CLK_SMD_RPM=y
>  CONFIG_QCOM_CLK_RPMH=y
> -CONFIG_IPQ_GCC_8074=y
>  CONFIG_IPQ_GCC_6018=y
> +CONFIG_IPQ_GCC_8074=y
>  CONFIG_MSM_GCC_8916=y
>  CONFIG_MSM_GCC_8994=y
>  CONFIG_MSM_MMCC_8996=y
> @@ -1005,16 +978,13 @@ CONFIG_QCS_GCC_404=y
>  CONFIG_SC_GCC_7180=y
>  CONFIG_SC_GCC_7280=y
>  CONFIG_SDM_CAMCC_845=m
> -CONFIG_SDM_GCC_845=y
>  CONFIG_SDM_GPUCC_845=y
>  CONFIG_SDM_VIDEOCC_845=y
>  CONFIG_SDM_DISPCC_845=y
> -CONFIG_SM_GCC_8150=y
> -CONFIG_SM_GCC_8250=y
> +CONFIG_SM_DISPCC_8250=y
>  CONFIG_SM_GCC_8350=y
>  CONFIG_SM_GPUCC_8150=y
>  CONFIG_SM_GPUCC_8250=y
> -CONFIG_SM_DISPCC_8250=y
>  CONFIG_QCOM_HFPLL=y
>  CONFIG_CLK_GFM_LPASS_SM8250=m
>  CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
> @@ -1048,9 +1018,11 @@ CONFIG_RASPBERRYPI_POWER=y
>  CONFIG_FSL_DPAA=y
>  CONFIG_FSL_MC_DPIO=y
>  CONFIG_FSL_RCPM=y
> +CONFIG_MTK_DEVAPC=m
>  CONFIG_MTK_PMIC_WRAP=y
>  CONFIG_QCOM_AOSS_QMP=y
>  CONFIG_QCOM_COMMAND_DB=y
> +CONFIG_QCOM_CPR=y
>  CONFIG_QCOM_GENI_SE=y
>  CONFIG_QCOM_RMTFS_MEM=m
>  CONFIG_QCOM_RPMH=y
> @@ -1061,24 +1033,21 @@ CONFIG_QCOM_SMD_RPM=y
>  CONFIG_QCOM_SMP2P=y
>  CONFIG_QCOM_SMSM=y
>  CONFIG_QCOM_SOCINFO=m
> -CONFIG_QCOM_WCNSS_CTRL=m
>  CONFIG_QCOM_STATS=m
> +CONFIG_QCOM_WCNSS_CTRL=m
>  CONFIG_QCOM_APR=m
> -CONFIG_ARCH_R8A774A1=y
> -CONFIG_ARCH_R8A774B1=y
> -CONFIG_ARCH_R8A774C0=y
> -CONFIG_ARCH_R8A774E1=y
> +CONFIG_ARCH_R8A77995=y
> +CONFIG_ARCH_R8A77990=y
>  CONFIG_ARCH_R8A77950=y
>  CONFIG_ARCH_R8A77951=y
> +CONFIG_ARCH_R8A77965=y
>  CONFIG_ARCH_R8A77960=y
>  CONFIG_ARCH_R8A77961=y
> -CONFIG_ARCH_R8A77965=y
> -CONFIG_ARCH_R8A77970=y
>  CONFIG_ARCH_R8A77980=y
> -CONFIG_ARCH_R8A77990=y
> -CONFIG_ARCH_R8A77995=y
> +CONFIG_ARCH_R8A77970=y
>  CONFIG_ARCH_R8A779A0=y
>  CONFIG_ARCH_R9A07G044=y
> +CONFIG_ROCKCHIP_IODOMAIN=y
>  CONFIG_ROCKCHIP_PM_DOMAINS=y
>  CONFIG_ARCH_TEGRA_132_SOC=y
>  CONFIG_ARCH_TEGRA_210_SOC=y
> @@ -1157,13 +1126,13 @@ CONFIG_PHY_UNIPHIER_USB3=y
>  CONFIG_PHY_TEGRA_XUSB=y
>  CONFIG_ARM_SMMU_V3_PMU=m
>  CONFIG_FSL_IMX8_DDR_PMU=m
> -CONFIG_HISI_PMU=y
>  CONFIG_QCOM_L2_PMU=y
>  CONFIG_QCOM_L3_PMU=y
> +CONFIG_HISI_PMU=y
>  CONFIG_NVMEM_IMX_OCOTP=y
>  CONFIG_NVMEM_IMX_OCOTP_SCU=y
> -CONFIG_QCOM_QFPROM=y
>  CONFIG_MTK_EFUSE=y
> +CONFIG_QCOM_QFPROM=y
>  CONFIG_ROCKCHIP_EFUSE=y
>  CONFIG_NVMEM_SUNXI_SID=y
>  CONFIG_UNIPHIER_EFUSE=y
> @@ -1177,11 +1146,9 @@ CONFIG_FPGA_REGION=m
>  CONFIG_OF_FPGA_REGION=m
>  CONFIG_TEE=y
>  CONFIG_OPTEE=y
> -CONFIG_SLIMBUS=m

NAK, blind savedefconfig is undesirable because it later might cause
dropping of configs (see DEBUGFS case). We discussed it from time to time...

Basically you should never remove user-selectable options from defconfig.

> +CONFIG_MUX_MMIO=y
>  CONFIG_SLIM_QCOM_CTRL=m
>  CONFIG_SLIM_QCOM_NGD_CTRL=m
> -CONFIG_MUX_MMIO=y
> -CONFIG_INTERCONNECT=y

Same.

>  CONFIG_INTERCONNECT_IMX=m
>  CONFIG_INTERCONNECT_IMX8MM=m
>  CONFIG_INTERCONNECT_IMX8MN=m
> @@ -1209,7 +1176,6 @@ CONFIG_OVERLAY_FS=m
>  CONFIG_VFAT_FS=y
>  CONFIG_TMPFS_POSIX_ACL=y
>  CONFIG_HUGETLBFS=y
> -CONFIG_CONFIGFS_FS=y

The same.

There might be more of such. Don't run savedefconfig blindly.

>  CONFIG_EFIVAR_FS=y
>  CONFIG_SQUASHFS=y
>  CONFIG_NFS_FS=y
> @@ -1241,6 +1207,5 @@ CONFIG_MAGIC_SYSRQ=y
>  CONFIG_DEBUG_FS=y
>  CONFIG_DEBUG_KERNEL=y
>  # CONFIG_SCHED_DEBUG is not set
> -# CONFIG_DEBUG_PREEMPT is not set
>  # CONFIG_FTRACE is not set
>  CONFIG_MEMTEST=y
> 


Best regards,
Krzysztof


From krzk at kernel.org  Mon Jan 10 00:40:42 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 09:40:42 +0100
Subject: [PATCH v1 06/14] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220107180314.1816515-7-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-7-marcel@ziswiler.com>
Message-ID: <c3962f91-7183-dd12-f645-629acd0cf076@kernel.org>

On 07/01/2022 19:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Build Realtek Gigabit Ethernet driver as a module.

Why?

We see what the patch does easily, so no really need of explaining it.
What is needed here is to explain why do you do it? What board needs it?

> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index a18785a827dc..86d39d8456c1 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -338,6 +338,7 @@ CONFIG_MLX5_CORE=m
>  CONFIG_MLX5_CORE_EN=y
>  CONFIG_QCOM_EMAC=m
>  CONFIG_RMNET=m
> +CONFIG_R8169=m
>  CONFIG_SH_ETH=y
>  CONFIG_RAVB=y
>  CONFIG_SMC91X=y
> 


Best regards,
Krzysztof


From krzk at kernel.org  Mon Jan 10 00:41:13 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 09:41:13 +0100
Subject: [PATCH v1 07/14] arm64: defconfig: build ads1015 adc driver as a
 module
In-Reply-To: <20220107180314.1816515-8-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-8-marcel@ziswiler.com>
Message-ID: <7b46e580-269c-bbf5-1319-47f91e2e89fa@kernel.org>

On 07/01/2022 19:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Build Texas Instruments ADS1015 ADC IIO driver as a module.

This should be probably squashed with several others of such changes
because probably the answer to "why" is the same.

Anyway: why?

> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 86d39d8456c1..1d0fe0bd0059 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -1071,6 +1071,7 @@ CONFIG_QCOM_SPMI_VADC=m
>  CONFIG_QCOM_SPMI_ADC5=m
>  CONFIG_ROCKCHIP_SARADC=m
>  CONFIG_RZG2L_ADC=m
> +CONFIG_TI_ADS1015=m
>  CONFIG_IIO_CROS_EC_SENSORS_CORE=m
>  CONFIG_IIO_CROS_EC_SENSORS=m
>  CONFIG_IIO_ST_LSM6DSX=m
> 


Best regards,
Krzysztof


From krzk at kernel.org  Mon Jan 10 00:41:25 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 09:41:25 +0100
Subject: [PATCH v1 08/14] arm64: defconfig: build lm75 temperature sensor
 driver as a module
In-Reply-To: <20220107180314.1816515-9-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-9-marcel@ziswiler.com>
Message-ID: <e6575bd5-ba9f-546f-ce82-162f19c14cad@kernel.org>

On 07/01/2022 19:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Build Maxim Integrated LM75 temperature sensor driver as a module.

Why?

> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 


Best regards,
Krzysztof


From yunfei.dong at mediatek.com  Mon Jan 10 00:34:41 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:41 +0800
Subject: [PATCH v4, 14/15] media: mtk-vcodec: support stateless VP8 decoding
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-15-yunfei.dong@mediatek.com>

Add support for VP8 decoding using the stateless API, as supported by MT8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  24 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         | 445 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 6 files changed, 474 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 22edb1c86598..b457daf2d196 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
+		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 21895fbed4c5..019055a0807d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -76,13 +76,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
 		},
 		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP8_FRAME,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
 	}
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[3];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+static struct mtk_video_fmt mtk_video_formats[4];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -352,6 +367,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
+	case V4L2_PIX_FMT_VP8_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -396,6 +412,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP8_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 4981760226b5..63ca6458929b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -357,6 +357,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
new file mode 100644
index 000000000000..0b0013c2f9ed
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/slab.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <uapi/linux/v4l2-controls.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* Decoding picture buffer size (3 reference frames plus current frame) */
+#define VP8_DPB_SIZE			4
+
+/* HW working buffer size (bytes) */
+#define VP8_SEG_ID_SZ		(256 * 1024)
+#define VP8_PP_WRAPY_SZ		(64 * 1024)
+#define VP8_PP_WRAPC_SZ		(64 * 1024)
+#define VP8_VLD_PRED_SZ		(64 * 1024)
+
+/**
+ * struct vdec_vp8_slice_info - decode misc information
+ * @vld_wrapper_dma   : vld wrapper dma address
+ * @seg_id_buf_dma    : seg id dma address
+ * @wrap_y_dma        : wrap y dma address
+ * @wrap_c_dma        : wrap y dma address
+ * @cur_y_fb_dma      : current plane Y frame buffer dma address
+ * @cur_c_fb_dma      : current plane C frame buffer dma address
+ * @bs_dma            : bitstream dma address
+ * @bs_sz             : bitstream size
+ * @resolution_changed: resolution change flag 1 - changed,  0 - not change
+ * @frame_header_type : current frame header type
+ * @wait_key_frame    : wait key frame coming
+ * @crc               : used to check whether hardware's status is right
+ * @timeout           : decode timeout: 1 timeout, 0 no timeount
+ * @reserved:         : reserved, currently unused
+ */
+struct vdec_vp8_slice_info {
+	uint64_t vld_wrapper_dma;
+	uint64_t seg_id_buf_dma;
+	uint64_t wrap_y_dma;
+	uint64_t wrap_c_dma;
+	uint64_t cur_y_fb_dma;
+	uint64_t cur_c_fb_dma;
+	uint64_t bs_dma;
+	uint32_t bs_sz;
+	uint32_t resolution_changed;
+	uint32_t frame_header_type;
+	uint32_t crc[8];
+	uint32_t reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_dpb_info  - vp8 reference information
+ * @y_dma_addr    : Y bitstream physical address
+ * @c_dma_addr    : CbCr bitstream physical address
+ * @reference_flag: reference picture flag
+ * @reserved      : 64bit align
+ */
+struct vdec_vp8_slice_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_vsi - VPU shared information
+ * @dec          : decoding information
+ * @pic          : picture information
+ * @vp8_dpb_info : reference buffer information
+ */
+struct vdec_vp8_slice_vsi {
+	struct vdec_vp8_slice_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_vp8_slice_dpb_info vp8_dpb_info[3];
+};
+
+/**
+ * struct vdec_vp8_slice_inst - VP8 decoder instance
+ * @seg_id_buf     : seg buffer
+ * @wrap_y_buf     : wrapper y buffer
+ * @wrap_c_buf     : wrapper c buffer
+ * @vld_wrapper_buf: vld wrapper buffer
+ * @ctx            : V4L2 context
+ * @vpu            : VPU instance for decoder
+ * @vsi            : VPU share information
+ */
+struct vdec_vp8_slice_inst {
+	struct mtk_vcodec_mem seg_id_buf;
+	struct mtk_vcodec_mem wrap_y_buf;
+	struct mtk_vcodec_mem wrap_c_buf;
+	struct mtk_vcodec_mem vld_wrapper_buf;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+	struct vdec_vp8_slice_vsi *vsi;
+};
+
+static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+static void vdec_vp8_slice_get_crop_info(struct vdec_vp8_slice_inst *inst,
+	struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->vsi->pic.pic_w;
+	cr->height = inst->vsi->pic.pic_h;
+	mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+
+	inst->vsi->pic.pic_w = ctx->picinfo.pic_w;
+	inst->vsi->pic.pic_h = ctx->picinfo.pic_h;
+	inst->vsi->pic.buf_w = ctx->picinfo.buf_w;
+	inst->vsi->pic.buf_h = ctx->picinfo.buf_h;
+	inst->vsi->pic.fb_sz[0] = ctx->picinfo.fb_sz[0];
+	inst->vsi->pic.fb_sz[1] = ctx->picinfo.fb_sz[1];
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+		ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+		ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]);
+}
+
+static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	int err;
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	mem->size = VP8_SEG_ID_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "Cannot allocate working buffer");
+		return err;
+	}
+	inst->vsi->dec.seg_id_buf_dma = (uint64_t)mem->dma_addr;
+
+	mem = &inst->wrap_y_buf;
+	mem->size = VP8_PP_WRAPY_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP Y buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_y_dma = (uint64_t)mem->dma_addr;
+
+	mem = &inst->wrap_c_buf;
+	mem->size = VP8_PP_WRAPC_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP C buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_c_dma = (uint64_t)mem->dma_addr;
+
+	mem = &inst->vld_wrapper_buf;
+	mem->size = VP8_VLD_PRED_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate vld wrapper buffer");
+		return err;
+	}
+	inst->vsi->dec.vld_wrapper_dma = (uint64_t)mem->dma_addr;
+
+	return 0;
+}
+
+static void vdec_vp8_slice_free_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.seg_id_buf_dma = 0;
+
+	mem = &inst->wrap_y_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_y_dma = 0;
+
+	mem = &inst->wrap_c_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_c_dma = 0;
+
+	mem = &inst->vld_wrapper_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.vld_wrapper_dma= 0;
+}
+
+static u64 vdec_vp8_slice_get_ref_by_ts(
+	const struct v4l2_ctrl_vp8_frame *frame_header,
+	int index)
+{
+	switch (index) {
+	case 0:
+		return frame_header->last_frame_ts;
+	case 1:
+		return frame_header->golden_frame_ts;
+	case 2:
+		return frame_header->alt_frame_ts;
+	default:
+		break;
+	}
+
+	return -1;
+}
+
+static void vdec_vp8_slice_get_decode_parameters(
+	struct vdec_vp8_slice_inst *inst)
+{
+	const struct v4l2_ctrl_vp8_frame *frame_header =
+		vdec_vp8_slice_get_ctrl_ptr(inst->ctx,
+			V4L2_CTRL_TYPE_VP8_FRAME);
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	u64 referenct_ts;
+	int index, vb2_index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	for (index = 0; index < 3; index++) {
+		referenct_ts = vdec_vp8_slice_get_ref_by_ts(frame_header, index);
+		vb2_index = vb2_find_timestamp(vq, referenct_ts, 0);
+		if (vb2_index < 0) {
+			if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header))
+				mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)",
+					index, referenct_ts);
+			inst->vsi->vp8_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+		inst->vsi->vp8_dpb_info[index].reference_flag = 1;
+
+		vb = vq->bufs[vb2_index];
+		inst->vsi->vp8_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				inst->vsi->vp8_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+
+	inst->vsi->dec.frame_header_type = frame_header->flags >> 1;
+}
+
+static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp8_slice_inst *inst;
+	int err;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	inst->vsi = inst->vpu.vsi;
+	err = vdec_vp8_slice_alloc_working_buf(inst);
+	if (err)
+		goto error_deinit;
+
+	mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n",
+		(int)sizeof(struct v4l2_ctrl_vp8_frame),
+		(int)sizeof(struct vdec_vp8_slice_vsi));
+	mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p",
+		inst, inst->vpu.codec_type, inst->vpu.vsi);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_deinit:
+	vpu_dec_deinit(&inst->vpu);
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+	struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
+	unsigned int data;
+	uint64_t y_fb_dma, c_fb_dma;
+	int err, timeout;
+
+	/* Resolution changes are never initiated by us */
+	*res_chg = false;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vpu_dec_reset(vpu);
+
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma = y_fb_dma +
+			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	inst->vsi->dec.bs_dma = (unsigned long)bs->dma_addr;
+	inst->vsi->dec.bs_sz = bs->size;
+	inst->vsi->dec.cur_y_fb_dma = y_fb_dma;
+	inst->vsi->dec.cur_c_fb_dma = c_fb_dma;
+
+	mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%lx) y/c(0x%llx 0x%llx)",
+		inst->ctx->decoded_frame_cnt,
+		bs->size, (unsigned long)bs->dma_addr,
+		y_fb_dma, c_fb_dma);
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+			&dst_buf_info->m2m_buf.vb, true);
+
+	vdec_vp8_slice_get_decode_parameters(inst);
+	err = vpu_dec_start(vpu, &data, 1);
+	if (err) {
+		mtk_vcodec_debug(inst, "vp8 dec start err!");
+		goto error;
+	}
+
+	if (inst->vsi->dec.resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution_changed -");
+		*res_chg = true;
+		return 0;
+	}
+
+	/* wait decode done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(
+			inst->ctx, MTK_INST_IRQ_RECEIVED,
+			50, MTK_VDEC_CORE);
+
+	err = vpu_dec_end(vpu);
+	if (err || timeout)
+		mtk_vcodec_debug(inst, "vp8 dec error timeout:%d err: %d pic_%d",
+			timeout, err, inst->ctx->decoded_frame_cnt);
+
+	mtk_vcodec_debug(inst, "y_crc: 0x%x 0x%x 0x%x 0x%x",
+		inst->vsi->dec.crc[0],
+		inst->vsi->dec.crc[1],
+		inst->vsi->dec.crc[2],
+		inst->vsi->dec.crc[3]);
+
+	mtk_vcodec_debug(inst, "c_crc: 0x%x 0x%x 0x%x 0x%x",
+			inst->vsi->dec.crc[4],
+			inst->vsi->dec.crc[5],
+			inst->vsi->dec.crc[6],
+			inst->vsi->dec.crc[7]);
+	inst->ctx->decoded_frame_cnt++;
+
+error:
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, !!err);
+	return err;
+}
+
+static int vdec_vp8_slice_get_param(void *h_vdec,
+	enum vdec_get_param_type type, void *out)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp8_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp8_slice_get_crop_info(inst, out);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*((unsigned int *)out) = VP8_DPB_SIZE;
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void vdec_vp8_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_vp8_slice_free_working_buf(inst);
+	kfree(inst);
+}
+
+const struct vdec_common_if vdec_vp8_slice_if = {
+	.init		= vdec_vp8_slice_init,
+	.decode		= vdec_vp8_slice_decode,
+	.get_param	= vdec_vp8_slice_get_param,
+	.deinit		= vdec_vp8_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c17a7815e1bb..9db9a57da2c1 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -32,6 +32,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_h264_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP8_FRAME:
+		ctx->dec_if = &vdec_vp8_slice_if;
+		ctx->hw_id = MTK_VDEC_CORE;
+		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
 		ctx->hw_id = MTK_VDEC_CORE;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index 6ce848e74167..e3adf8f36342 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -58,6 +58,7 @@ extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
 extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
+extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
 /**
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 10 00:34:40 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 10 Jan 2022 16:34:40 +0800
Subject: [PATCH v4,
 13/15] media: mtk-vcodec: support stateless H.264 decoding for mt8192
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <20220110083442.32604-14-yunfei.dong@mediatek.com>

Adds h264 lat and core architecture driver for mt8192, and the decode mode is frame
based for stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 605 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 include/linux/remoteproc/mtk_scp.h            |   2 +
 5 files changed, 616 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 3f41d748eee5..22edb1c86598 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
+		vdec/vdec_h264_req_multi_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
new file mode 100644
index 000000000000..b53c05507d75
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -0,0 +1,605 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+#include "vdec_h264_req_common.h"
+
+/**
+ * enum vdec_h264_core_dec_err_type  - core decode error type
+ * @TRANS_BUFFER_FULL : trans buffer is full
+ * @SLICE_HEADER_FULL : slice header buffer is full
+ */
+enum vdec_h264_core_dec_err_type {
+	TRANS_BUFFER_FULL = 1,
+	SLICE_HEADER_FULL,
+};
+
+/**
+ * struct vdec_h264_slice_lat_dec_param  - parameters for decode current frame
+ * @sps : h264 sps syntax parameters
+ * @pps : h264 pps syntax parameters
+ * @slice_header: h264 slice header syntax parameters
+ * @scaling_matrix : h264 scaling list parameters
+ * @decode_params : decoder parameters of each frame used for hardware decode
+ * @h264_dpb_info : dpb reference list
+ */
+struct vdec_h264_slice_lat_dec_param {
+	struct mtk_h264_sps_param sps;
+	struct mtk_h264_pps_param pps;
+	struct mtk_h264_slice_hd_param slice_header;
+	struct slice_api_h264_scaling_matrix scaling_matrix;
+	struct slice_api_h264_decode_param decode_params;
+	struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+/**
+ * struct vdec_h264_slice_info - decode information
+ * @nal_info    : nal info of current picture
+ * @timeout     : Decode timeout: 1 timeout, 0 no timeount
+ * @bs_buf_size : bitstream size
+ * @bs_buf_addr : bitstream buffer dma address
+ * @y_fb_dma    : Y frame buffer dma address
+ * @c_fb_dma    : C frame buffer dma address
+ * @vdec_fb_va  : VDEC frame buffer struct virtual address
+ * @crc         : Used to check whether hardware's status is right
+ */
+struct vdec_h264_slice_info {
+	uint16_t nal_info;
+	uint16_t timeout;
+	uint32_t bs_buf_size;
+	uint64_t bs_buf_addr;
+	uint64_t y_fb_dma;
+	uint64_t c_fb_dma;
+	uint64_t vdec_fb_va;
+	uint32_t crc[8];
+};
+
+/**
+ * struct vdec_h264_slice_vsi - shared memory for decode information exchange
+ *        between VPU and Host. The memory is allocated by VPU then mapping to
+ *        Host in vdec_h264_slice_init() and freed in vdec_h264_slice_deinit()
+ *        by VPU. AP-W/R : AP is writer/reader on this item. VPU-W/R: VPU is
+ *        write/reader on this item.
+ * @wdma_err_addr       : wdma error dma address
+ * @wdma_start_addr     : wdma start dma address
+ * @wdma_end_addr       : wdma end dma address
+ * @slice_bc_start_addr : slice bc start dma address
+ * @slice_bc_end_addr   : slice bc end dma address
+ * @row_info_start_addr : row info start dma address
+ * @row_info_end_addr   : row info end dma address
+ * @trans_start         : trans start dma address
+ * @trans_end           : trans end dma address
+ * @wdma_end_addr_offset: wdma end address offset
+ * @mv_buf_dma          : HW working motion vector buffer
+ *                        dma address (AP-W, VPU-R)
+ * @dec                 : decode information (AP-R, VPU-W)
+ * @h264_slice_params   : decode parameters for hw used
+ */
+struct vdec_h264_slice_vsi {
+	/* LAT dec addr */
+	uint64_t wdma_err_addr;
+	uint64_t wdma_start_addr;
+	uint64_t wdma_end_addr;
+	uint64_t slice_bc_start_addr;
+	uint64_t slice_bc_end_addr;
+	uint64_t row_info_start_addr;
+	uint64_t row_info_end_addr;
+	uint64_t trans_start;
+	uint64_t trans_end;
+	uint64_t wdma_end_addr_offset;
+
+	uint64_t mv_buf_dma[H264_MAX_MV_NUM];
+	struct vdec_h264_slice_info dec;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+};
+
+/**
+ * struct vdec_h264_slice_share_info - shared information used to exchange
+ *                                     message between lat and core
+ * @sps	              : sequence header information from user space
+ * @dec_params        : decoder params from user space
+ * @h264_slice_params : decoder params used for hardware
+ * @trans_start       : trans start dma address
+ * @trans_end         : trans end dma address
+ * @nal_info          : nal info of current picture
+ */
+struct vdec_h264_slice_share_info {
+	struct v4l2_ctrl_h264_sps sps;
+	struct v4l2_ctrl_h264_decode_params dec_params;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+	uint64_t trans_start;
+	uint64_t trans_end;
+	uint16_t nal_info;
+};
+
+/**
+ * struct vdec_h264_slice_inst - h264 decoder instance
+ * @slice_dec_num        : how many picture be decoded
+ * @ctx                 : point to mtk_vcodec_ctx
+ * @pred_buf            : HW working predication buffer
+ * @mv_buf              : HW working motion vector buffer
+ * @vpu                 : VPU instance
+ * @vsi                 : vsi used for lat
+ * @vsi_core            : vsi used for core
+ *
+ * @resolution_changed  : resolution changed
+ * @realloc_mv_buf      : reallocate mv buffer
+ * @cap_num_planes      : number of capture queue plane
+ *
+ * @dpb : decoded picture buffer used to store reference buffer information
+ */
+struct vdec_h264_slice_inst {
+	unsigned int slice_dec_num;
+	struct mtk_vcodec_ctx *ctx;
+	struct mtk_vcodec_mem pred_buf;
+	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
+	struct vdec_vpu_inst vpu;
+	struct vdec_h264_slice_vsi *vsi;
+	struct vdec_h264_slice_vsi *vsi_core;
+
+	unsigned int resolution_changed;
+	unsigned int realloc_mv_buf;
+	unsigned int cap_num_planes;
+
+	struct v4l2_h264_dpb_entry dpb[16];
+};
+
+static void vdec_h264_slice_fill_decode_parameters(
+	struct vdec_h264_slice_inst *inst,
+	struct vdec_h264_slice_share_info *share_info)
+{
+	struct vdec_h264_slice_lat_dec_param *slice_param =
+		&inst->vsi->h264_slice_params;
+	const struct v4l2_ctrl_h264_decode_params *dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	const struct v4l2_ctrl_h264_sps *sps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_SPS);
+	const struct v4l2_ctrl_h264_pps *pps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+			V4L2_CID_STATELESS_H264_PPS);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps,sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(
+		&slice_param->scaling_matrix, src_matrix);
+
+	memcpy(&share_info->sps, sps, sizeof(*sps));
+	memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params));
+}
+
+static void vdec_h264_slice_fill_decode_reflist(
+	struct vdec_h264_slice_inst *inst,
+	struct vdec_h264_slice_lat_dec_param *slice_param,
+	struct vdec_h264_slice_share_info *share_info)
+{
+	struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
+	struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params,
+		inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+		slice_param->h264_dpb_info);
+
+	mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt);
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
+				       inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+
+	/* Adapt the built lists to the firmware's expectations */
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+}
+
+static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+	struct vdec_pic_info *pic)
+{
+	int i;
+	int err;
+	struct mtk_vcodec_mem *mem;
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(
+		pic->buf_w, pic->buf_h);
+
+	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+		mem->size = buf_sz;
+		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+		if (err) {
+			mtk_vcodec_err(inst, "failed to allocate mv buf");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst)
+{
+	int i;
+	struct mtk_vcodec_mem *mem;
+
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+	}
+}
+
+static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+	inst->cap_num_planes =
+		ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
+		ctx->picinfo.fb_sz[1]);
+
+	if ((ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w) ||
+		(ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h)) {
+		inst->resolution_changed = true;
+		if ((ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w) ||
+			(ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h))
+			inst->realloc_mv_buf = true;
+
+		mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
+			inst->resolution_changed,
+			inst->realloc_mv_buf,
+			ctx->last_decoded_picinfo.pic_w,
+			ctx->last_decoded_picinfo.pic_h,
+			ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+	}
+}
+
+static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
+	struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->ctx->picinfo.pic_w;
+	cr->height = inst->ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_h264_slice_inst *inst;
+	int err, vsi_size;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), 64);
+	inst->vsi = inst->vpu.vsi;
+	inst->vsi_core =
+		(struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+	inst->resolution_changed = true;
+	inst->realloc_mv_buf = true;
+
+	mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n",
+		(int)sizeof(struct mtk_h264_sps_param),
+		(int)sizeof(struct mtk_h264_pps_param),
+		(int)sizeof(struct vdec_h264_slice_lat_dec_param),
+		(int)sizeof(struct mtk_h264_dpb_info),
+		vsi_size);
+	mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x",
+		inst, inst->vpu.codec_type);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static void vdec_h264_slice_deinit(void *h_vdec)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_h264_slice_free_mv_buf(inst);
+	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
+
+	kfree(inst);
+}
+
+static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_fb *fb;
+	uint64_t vdec_fb_va;
+	uint64_t y_fb_dma, c_fb_dma;
+	int err, timeout, i;
+	struct vdec_vpu_inst *vpu;
+	struct mtk_vcodec_ctx *ctx = lat_buf->ctx;
+	struct vdec_h264_slice_inst *inst = ctx->drv_handle;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
+	struct mtk_vcodec_mem *mem;
+
+	mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode");
+	memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params,
+		sizeof(share_info->h264_slice_params));
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	vpu = &inst->vpu;
+	vdec_fb_va = (unsigned long)fb;
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma =
+			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+		c_fb_dma);
+
+	inst->vsi_core->dec.y_fb_dma = y_fb_dma;
+	inst->vsi_core->dec.c_fb_dma = c_fb_dma;
+	inst->vsi_core->dec.vdec_fb_va = vdec_fb_va;
+	inst->vsi_core->dec.nal_info = share_info->nal_info;
+	inst->vsi_core->wdma_start_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi_core->wdma_end_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+	inst->vsi_core->trans_start = share_info->trans_start;
+	inst->vsi_core->trans_end = share_info->trans_end;
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi_core->mv_buf_dma[i] = mem->dma_addr;
+	}
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	vb2_v4l2->vb2_buf.timestamp = lat_buf->ts_info.vb2_buf.timestamp;
+	vb2_v4l2->timecode = lat_buf->ts_info.timecode;
+	vb2_v4l2->field = lat_buf->ts_info.field;
+	vb2_v4l2->flags = lat_buf->ts_info.flags;
+	vb2_v4l2->vb2_buf.copied_timestamp =
+		lat_buf->ts_info.vb2_buf.copied_timestamp;
+
+	vdec_h264_slice_fill_decode_reflist(inst,
+		&inst->vsi_core->h264_slice_params, share_info);
+
+	err = vpu_dec_core(vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "core decode err=%d", err);
+		goto vdec_dec_end;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(
+		inst->ctx, MTK_INST_IRQ_RECEIVED,
+		WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+	if (timeout)
+		mtk_vcodec_err(inst, "core decode timeout: pic_%d",
+			ctx->decoded_frame_cnt);
+	inst->vsi_core->dec.timeout = !!timeout;
+
+	vpu_dec_core_end(vpu);
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+		ctx->decoded_frame_cnt,
+		inst->vsi_core->dec.crc[0],	inst->vsi_core->dec.crc[1],
+		inst->vsi_core->dec.crc[2],	inst->vsi_core->dec.crc[3],
+		inst->vsi_core->dec.crc[4],	inst->vsi_core->dec.crc[5],
+		inst->vsi_core->dec.crc[6],	inst->vsi_core->dec.crc[7]);
+
+vdec_dec_end:
+	vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue,
+		share_info->trans_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, !!err);
+	mtk_vcodec_debug(inst, "core decode done err=%d", err);
+	ctx->decoded_frame_cnt++;
+	return 0;
+}
+
+static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+	struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	int nal_start_idx, err, timeout = 0, i;
+	unsigned int data[2];
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_h264_slice_share_info *share_info;
+	unsigned char *buf;
+	struct mtk_vcodec_mem *mem;
+
+	if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
+		vdec_h264_slice_core_decode, sizeof(*share_info)))
+		return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs) {
+		vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue);
+		return vpu_dec_reset(vpu);
+	}
+
+	lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(inst, "failed to get lat buffer");
+		return -EINVAL;
+	}
+	share_info = lat_buf->private_data;
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	buf = (unsigned char *)bs->va;
+	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
+	if (nal_start_idx < 0) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	inst->vsi->dec.nal_info = buf[nal_start_idx];
+	inst->vsi->dec.bs_buf_addr = (uint64_t)bs->dma_addr;
+	inst->vsi->dec.bs_buf_size = bs->size;
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+		&lat_buf->ts_info, true);
+
+	vdec_h264_slice_fill_decode_parameters(inst, share_info);
+	*res_chg = inst->resolution_changed;
+	if (inst->resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->realloc_mv_buf) {
+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		inst->resolution_changed = false;
+	}
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi->mv_buf_dma[i] = mem->dma_addr;
+	}
+	inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+
+	inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr;
+	inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx)err:0x%llx",
+		inst->vsi->wdma_start_addr,
+		inst->vsi->wdma_end_addr,
+		inst->vsi->wdma_err_addr);
+
+	mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))",
+		inst->vsi->slice_bc_start_addr,
+		inst->vsi->slice_bc_end_addr,
+		inst->vsi->trans_start,
+		inst->vsi->trans_end);
+	err = vpu_dec_start(vpu, data, 2);
+	if (err) {
+		mtk_vcodec_debug(inst, "lat decode err: %d", err);
+		goto err_free_fb_out;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(
+		inst->ctx, MTK_INST_IRQ_RECEIVED,
+		WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+	inst->vsi->dec.timeout = !!timeout;
+
+	err = vpu_dec_end(vpu);
+	if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
+		share_info->trans_end);
+
+	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		sizeof(share_info->h264_slice_params));
+	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	inst->slice_dec_num++;
+
+err_free_fb_out:
+	mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);
+	return err;
+}
+
+static int vdec_h264_slice_get_param(void *h_vdec,
+	enum vdec_get_param_type type, void *out)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_h264_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*(unsigned int *)out = 6;
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_h264_slice_get_crop_info(inst, out);
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+const struct vdec_common_if vdec_h264_slice_lat_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c93dd0ea3537..c17a7815e1bb 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -20,7 +20,13 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
-		ctx->dec_if = &vdec_h264_slice_if;
+		if (ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) {
+			ctx->dec_if = &vdec_h264_slice_if;
+			ctx->hw_id = MTK_VDEC_CORE;
+		} else {
+			ctx->dec_if = &vdec_h264_slice_lat_if;
+			ctx->hw_id = MTK_VDEC_LAT0;
+		}
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index d467e8af4a84..6ce848e74167 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -56,6 +56,7 @@ struct vdec_fb_node {
 
 extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
+extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
diff --git a/include/linux/remoteproc/mtk_scp.h b/include/linux/remoteproc/mtk_scp.h
index b47416f7aeb8..a32ffd736e7b 100644
--- a/include/linux/remoteproc/mtk_scp.h
+++ b/include/linux/remoteproc/mtk_scp.h
@@ -41,6 +41,8 @@ enum scp_ipi_id {
 	SCP_IPI_ISP_FRAME,
 	SCP_IPI_FD_CMD,
 	SCP_IPI_CROS_HOST_CMD,
+	SCP_IPI_VDEC_LAT,
+	SPC_IPI_VDEC_CORE,
 	SCP_IPI_NS_SERVICE = 0xFF,
 	SCP_IPI_MAX = 0x100,
 };
-- 
2.25.1



From nancy.lin at mediatek.com  Mon Jan 10 00:46:24 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:24 +0800
Subject: [PATCH v11 01/22] dt-bindings: mediatek: add vdosys1 RDMA definition
 for mt8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-2-nancy.lin@mediatek.com>

Add vdosys1 RDMA definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 .../arm/mediatek/mediatek,mdp-rdma.yaml       | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
new file mode 100644
index 000000000000..d70b81ec1914
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mdp-rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MDP RDMA
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  The mediatek MDP RDMA stands for Read Direct Memory Access.
+  It provides real time data to the back-end panel driver, such as DSI,
+  DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-vdo1-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,gce-client-reg:
+    description:
+      The register of display function block to be set by gce. There are 4 arguments,
+      such as gce node, subsys id, offset and register size. The subsys id that is
+      mapping to the register of display function blocks is defined in the gce header
+      include/include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    vdo1_rdma0: vdo1_rdma at 1c104000 {
+        compatible = "mediatek,mt8195-vdo1-rdma";
+        reg = <0 0x1c104000 0 0x1000>;
+        interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+        mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x4000 0x1000>;
+    };
+
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:27 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:27 +0800
Subject: [PATCH v11 04/22] dt-bindings: reset: mt8195: add vdosys1 reset
 control bit
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-5-nancy.lin@mediatek.com>

Add vdosys1 reset control bit for MT8195 platform.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 include/dt-bindings/reset/mt8195-resets.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/mt8195-resets.h b/include/dt-bindings/reset/mt8195-resets.h
index a26bccc8b957..aab8d74496a6 100644
--- a/include/dt-bindings/reset/mt8195-resets.h
+++ b/include/dt-bindings/reset/mt8195-resets.h
@@ -26,4 +26,16 @@
 
 #define MT8195_TOPRGU_SW_RST_NUM               16
 
+/* VDOSYS1 */
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC          25
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC          26
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC          27
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC          28
+#define MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC          29
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC     51
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC     52
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC     53
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC     54
+#define MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC      55
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8195 */
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:30 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:30 +0800
Subject: [PATCH v11 07/22] soc: mediatek: add cmdq support of mtk-mmsys config
 API for mt8195 vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-8-nancy.lin@mediatek.com>

Add cmdq support for mtk-mmsys config API.
The mmsys config register settings need to take effect with the other
HW settings(like OVL_ADAPTOR...) at the same vblanking time.

If we use CPU to write the mmsys reg, we can't guarantee all the
settings can be written in the same vblanking time.
Cmdq is used for this purpose. We prepare all the related HW settings
in one cmdq packet. The first command in the packet is "wait stream done",
and then following with all the HW settings. After the cmdq packet is
flush to GCE HW. The GCE waits for the "stream done event" to coming
and then starts flushing all the HW settings. This can guarantee all
the settings flush in the same vblanking.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mmsys.c       | 29 ++++++++++++++++++++------
 include/linux/soc/mediatek/mtk-mmsys.h |  6 +++++-
 2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 725a99fcbc6d..1b0024ee47a9 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -88,6 +88,7 @@ struct mtk_mmsys {
 	const struct mtk_mmsys_driver_data *data;
 	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
 	struct reset_controller_dev rcdev;
+	struct cmdq_client_reg cmdq_base;
 };
 
 void mtk_mmsys_ddp_connect(struct device *dev,
@@ -180,7 +181,7 @@ static const struct reset_control_ops mtk_mmsys_reset_ops = {
 };
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val)
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
 	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
@@ -188,7 +189,6 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 	u32 mask;
 	u32 offset;
 	int i;
-	u32 tmp;
 
 	if (!mmsys->data->num_configs)
 		return;
@@ -204,10 +204,20 @@ void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
 	mask = mmsys_config[i].mask;
 	reg_val = val << mmsys_config[i].shift;
 
-	tmp = readl(mmsys->regs + offset);
-
-	tmp = (tmp & ~mask) | reg_val;
-	writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (cmdq_pkt && mmsys->cmdq_base.size) {
+		cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
+				    mmsys->cmdq_base.offset + offset, reg_val,
+				    mask);
+	} else {
+#endif
+		u32 tmp = readl(mmsys->regs + offset);
+
+		tmp = (tmp & ~mask) | reg_val;
+		writel(tmp, mmsys->regs + offset);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	}
+#endif
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
 
@@ -243,6 +253,13 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	}
 
 	mmsys->data = of_device_get_match_data(&pdev->dev);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
+	if (ret)
+		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
+#endif
+
 	platform_set_drvdata(pdev, mmsys);
 
 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index b2d2310d7e7a..3e998bfb795a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -6,6 +6,10 @@
 #ifndef __MTK_MMSYS_H
 #define __MTK_MMSYS_H
 
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox/mtk-cmdq-mailbox.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
 enum mtk_ddp_comp_id;
 struct device;
 
@@ -78,6 +82,6 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id next);
 
 void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
-			  u32 id, u32 val);
+			  u32 id, u32 val, struct cmdq_pkt *cmdq_pkt);
 
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:25 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:25 +0800
Subject: [PATCH v11 02/22] dt-bindings: mediatek: add vdosys1 MERGE property
 for mt8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-3-nancy.lin@mediatek.com>

MT8195 vdosys1 merge1 to merge4 have HW mute function.
Add MERGE additional mute property description.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Acked-By: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml  | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 28be8ffeb429..f5b1e632bcd5 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -61,6 +61,10 @@ properties:
       command to SMI to speed up the data rate.
     type: boolean
 
+  mediatek,merge-mute:
+    description: Support mute function. Mute the content of merge output.
+    type: boolean
+
   mediatek,gce-client-reg:
     description:
       The register of client driver can be configured by gce with 4 arguments
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:28 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:28 +0800
Subject: [PATCH v11 05/22] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-6-nancy.lin@mediatek.com>

Add mt8195 vdosys1 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 136 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  10 ++
 include/linux/soc/mediatek/mtk-mmsys.h |   2 +
 3 files changed, 148 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index e04cabdfa2dc..65da65754d6e 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -165,6 +165,70 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		BIT(17)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(BIT(17) | BIT(16))
 
+#define MT8195_VDO1_VPP_MERGE0_P0_SEL_IN			0xf04
+#define MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0			1
+
+#define MT8195_VDO1_VPP_MERGE0_P1_SEL_IN			0xf08
+#define MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1			1
+
+#define MT8195_VDO1_DISP_DPI1_SEL_IN				0xf10
+#define MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT			0
+
+#define MT8195_VDO1_DISP_DP_INTF0_SEL_IN			0xf14
+#define MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT		0
+
+#define MT8195_VDO1_MERGE4_SOUT_SEL				0xf18
+#define MT8195_MERGE4_SOUT_TO_DPI1_SEL					2
+#define MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL				3
+
+#define MT8195_VDO1_MIXER_IN1_SEL_IN				0xf24
+#define MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT			1
+
+#define MT8195_VDO1_MIXER_IN2_SEL_IN				0xf28
+#define MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT			1
+
+#define MT8195_VDO1_MIXER_IN3_SEL_IN				0xf2c
+#define MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT			1
+
+#define MT8195_VDO1_MIXER_IN4_SEL_IN				0xf30
+#define MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT			1
+
+#define MT8195_VDO1_MIXER_OUT_SOUT_SEL				0xf34
+#define MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL				1
+
+#define MT8195_VDO1_VPP_MERGE1_P0_SEL_IN			0xf3c
+#define MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2			1
+
+#define MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL			0xf40
+#define MT8195_SOUT_TO_MIXER_IN1_SEL					1
+
+#define MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL			0xf44
+#define MT8195_SOUT_TO_MIXER_IN2_SEL					1
+
+#define MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL			0xf48
+#define MT8195_SOUT_TO_MIXER_IN3_SEL					1
+
+#define MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL			0xf4c
+#define MT8195_SOUT_TO_MIXER_IN4_SEL					1
+
+#define MT8195_VDO1_MERGE4_ASYNC_SEL_IN				0xf50
+#define MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT			1
+
+#define MT8195_VDO1_MIXER_IN1_SOUT_SEL				0xf58
+#define MT8195_MIXER_IN1_SOUT_TO_DISP_MIXER				0
+
+#define MT8195_VDO1_MIXER_IN2_SOUT_SEL				0xf5c
+#define MT8195_MIXER_IN2_SOUT_TO_DISP_MIXER				0
+
+#define MT8195_VDO1_MIXER_IN3_SOUT_SEL				0xf60
+#define MT8195_MIXER_IN3_SOUT_TO_DISP_MIXER				0
+
+#define MT8195_VDO1_MIXER_IN4_SOUT_SEL				0xf64
+#define MT8195_MIXER_IN4_SOUT_TO_DISP_MIXER				0
+
+#define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
+#define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER			0
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -214,6 +278,78 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
 		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
 		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P0_SEL_IN_FROM_MDP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE0_P1_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE0_P1_SEL_IN_FROM_MDP_RDMA1
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_VPP_MERGE1_P0_SEL_IN, GENMASK(0, 0),
+		MT8195_VPP_MERGE1_P0_SEL_IN_FROM_MDP_RDMA2
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE0_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN1_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE1_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN2_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE2_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN3_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE3_ASYNC_SOUT_SEL, GENMASK(1, 0),
+		MT8195_SOUT_TO_MIXER_IN4_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_OUT_SOUT_SEL, GENMASK(0, 0),
+		MT8195_MIXER_SOUT_TO_MERGE4_ASYNC_SEL
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN1_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN1_SEL_IN_FROM_MERGE0_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN2_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN2_SEL_IN_FROM_MERGE1_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN3_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN3_SEL_IN_FROM_MERGE2_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_IN4_SEL_IN, GENMASK(0, 0),
+		MT8195_MIXER_IN4_SEL_IN_FROM_MERGE3_ASYNC_SOUT
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MIXER_SOUT_SEL_IN, GENMASK(2, 0),
+		MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER
+	}, {
+		DDP_COMPONENT_OVL_ADAPTOR, DDP_COMPONENT_MERGE5,
+		MT8195_VDO1_MERGE4_ASYNC_SEL_IN, GENMASK(2, 0),
+		MT8195_MERGE4_ASYNC_SEL_IN_FROM_MIXER_OUT_SOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_DISP_DPI1_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DPI1_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DPI1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DPI1_SEL
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_DISP_DP_INTF0_SEL_IN, GENMASK(1, 0),
+		MT8195_DISP_DP_INTF0_SEL_IN_FROM_VPP_MERGE4_MOUT
+	}, {
+		DDP_COMPONENT_MERGE5, DDP_COMPONENT_DP_INTF1,
+		MT8195_VDO1_MERGE4_SOUT_SEL, GENMASK(1, 0),
+		MT8195_MERGE4_SOUT_TO_DP_INTF0_SEL
 	}
 };
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 4c9263e3d09e..416a97d7fd83 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -69,6 +69,12 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.clk_driver = "clk-mt8195-vdo1",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.clk_driver = "clk-mt8365-mm",
 	.routes = mt8365_mmsys_routing_table,
@@ -257,6 +263,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8195-vdosys0",
 		.data = &mt8195_vdosys0_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys1",
+		.data = &mt8195_vdosys1_driver_data,
+	},
 	{
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 64c77c4a6c56..eaf7f7345519 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -18,6 +18,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
 	DDP_COMPONENT_DP_INTF0,
+	DDP_COMPONENT_DP_INTF1,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
 	DDP_COMPONENT_DSC0,
@@ -39,6 +40,7 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_OVL_2L0,
 	DDP_COMPONENT_OVL_2L1,
 	DDP_COMPONENT_OVL_2L2,
+	DDP_COMPONENT_OVL_ADAPTOR,
 	DDP_COMPONENT_OVL1,
 	DDP_COMPONENT_POSTMASK0,
 	DDP_COMPONENT_PWM0,
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:31 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:31 +0800
Subject: [PATCH v11 08/22] soc: mediatek: mmsys: modify reset controller for
 MT8195 vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-9-nancy.lin@mediatek.com>

MT8195 vdosys1 has more than 32 reset bits and a different reset base
than other chips. Modify mmsys for support 64 bit and different reset
base.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h |  1 +
 drivers/soc/mediatek/mtk-mmsys.c    | 21 ++++++++++++++++-----
 drivers/soc/mediatek/mtk-mmsys.h    |  2 ++
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 11ba79e3275e..628098260f61 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -229,6 +229,7 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER			0
 
+#define MT8195_VDO1_SW0_RST_B		0x1d0
 #define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
 #define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
 #define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 1b0024ee47a9..3f85171c980e 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -19,6 +19,8 @@
 #include "mt8195-mmsys.h"
 #include "mt8365-mmsys.h"
 
+#define MMSYS_SW_RESET_PER_REG 32
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.clk_driver = "clk-mt2701-mm",
 	.routes = mmsys_default_routing_table,
@@ -49,12 +51,16 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
 	.clk_driver = "clk-mt8173-mm",
 	.routes = mmsys_default_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_default_routing_table),
+	.sw_reset_start = MMSYS_SW0_RST_B,
+	.num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.clk_driver = "clk-mt8183-mm",
 	.routes = mmsys_mt8183_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
+	.sw_reset_start = MMSYS_SW0_RST_B,
+	.num_resets = 32,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -75,6 +81,8 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
 	.config = mmsys_mt8195_config_table,
 	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
+	.sw_reset_start = MT8195_VDO1_SW0_RST_B,
+	.num_resets = 64,
 };
 
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
@@ -133,18 +141,22 @@ static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned l
 {
 	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
 	unsigned long flags;
+	u32 offset;
 	u32 reg;
 
+	offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
+	id = id % MMSYS_SW_RESET_PER_REG;
+
 	spin_lock_irqsave(&mmsys->lock, flags);
 
-	reg = readl_relaxed(mmsys->regs + MMSYS_SW0_RST_B);
+	reg = readl_relaxed(mmsys->regs + mmsys->data->sw_reset_start + offset);
 
 	if (assert)
 		reg &= ~BIT(id);
 	else
 		reg |= BIT(id);
 
-	writel_relaxed(reg, mmsys->regs + MMSYS_SW0_RST_B);
+	writel_relaxed(reg, mmsys->regs + mmsys->data->sw_reset_start + offset);
 
 	spin_unlock_irqrestore(&mmsys->lock, flags);
 
@@ -240,10 +252,11 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	mmsys->data = of_device_get_match_data(&pdev->dev);
 	spin_lock_init(&mmsys->lock);
 
 	mmsys->rcdev.owner = THIS_MODULE;
-	mmsys->rcdev.nr_resets = 32;
+	mmsys->rcdev.nr_resets = mmsys->data->num_resets;
 	mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
 	mmsys->rcdev.of_node = pdev->dev.of_node;
 	ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
@@ -252,8 +265,6 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	mmsys->data = of_device_get_match_data(&pdev->dev);
-
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
 	if (ret)
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 2694021435d2..4842102cd451 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -102,6 +102,8 @@ struct mtk_mmsys_driver_data {
 	const unsigned int num_routes;
 	const struct mtk_mmsys_config *config;
 	const unsigned int num_configs;
+	u32 sw_reset_start;
+	u32 num_resets;
 };
 
 /*
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:23 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:23 +0800
Subject: [PATCH v11 00/22] Add MediaTek SoC DRM (vdosys1) support for mt8195
Message-ID: <20220110084645.31191-1-nancy.lin@mediatek.com>

The hardware path of vdosys1 with DPTx output need to go through by several modules, such as, OVL_ADAPTOR and MERGE.

Add DRM and these modules support by the patches below:

Changes in v11:
- remove ethdr vblank spin lock
- refine ovl_adaptor print message

Changes in v10:
- refine ethdr reset control using devm_reset_control_array_get_optional_exclusive
- fix ovl_adaptor mtk_ovl_adaptor_clk_enable error handle issue

Changes in v9:
- rebase on kernel-5.16-rc1
- rebase on vdosys0 series v13. (ref [5])
- fix ovl_adaptor sub driver is brought up unintentionally
- fix clang build test fail- duplicate ethdr/mdp_rdma init_module/cleanup_module symbol issue 

Changes in v8:
- separate merge async reset to new patch.
- separate drm ovl_adaptor sub driver to new patch.
- fix reviewer comment in v7.

Changes in v7:
- rebase on vdosys0 series v12 (ref[5])
- add dma description in ethdr binding document.
- refine vdosys1 bit definition of mmsys routing table.
- separate merge modification into 3 pathces.
- separate mutex modification into 2 patches.
- add plane color coding for mdp_rdma csc.
- move mdp_rdma pm control to ovl_adaptor.
- fix reviewer comment in v6.

Changes in v6:
- rebase on kernel-5.15-rc1.
- change mbox label to gce0 for dts node of vdosys1.
- modify mmsys reset num for mt8195.
- rebase on vdosys0 series v10. (ref [5])
- use drm to bring up ovl_adaptor driver.
- move drm iommu/mutex check from kms init to drm bind.
- modify rdma binding doc location. (Documentation/devicetree/bindings/arm/)
- modify for reviewer's comment in v5.

Changes in v5:
- add mmsys reset controller reference.

Changes in v4:
- use merge common driver for merge1~4.
- refine ovl_adaptor rdma driver.
- use ovl_adaptor ddp_comp function instead of ethdr.
- modify for reviewer's comment in v3.

Changes in v3:
- modify for reviewer's comment in v2.
- add vdosys1 2 pixels align limit.
- add mixer odd offset support.

Changes in v2:
- Merge PSEUDO_OVL and ETHDR into one DRM component.
- Add mmsys config API for vdosys1 hardware setting.
- Add mmsys reset control using linux reset framework.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

This series are based on the following patch:
[1] arm64: dts: Add Mediatek SoC MT8195 and evaluation board dts and Makefile
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210601075350.31515-2-seiya.wang at mediatek.com/
[2] arm64: dts: mt8195: add IOMMU and smi nodes
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[3] [01/24] dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210630023504.18177-2-yong.wu at mediatek.com/
[4] Add gce support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=537069
[5] Add MediaTek SoC DRM (vdosys0) support for mt8195
    https://patchwork.kernel.org/project/linux-mediatek/list/?series=587313
[6] [v8,1/2] dt-bindings: reset: mt8195: add toprgu reset-controller header file
    https://patchwork.kernel.org/project/linux-mediatek/patch/20210806023606.16867-2-Christine.Zhu at mediatek.com/

Nancy.Lin (22):
  dt-bindings: mediatek: add vdosys1 RDMA definition for mt8195
  dt-bindings: mediatek: add vdosys1 MERGE property for mt8195
  dt-bindings: mediatek: add ethdr definition for mt8195
  dt-bindings: reset: mt8195: add vdosys1 reset control bit
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
  soc: mediatek: add mtk-mmsys config API for mt8195 vdosys1
  soc: mediatek: add cmdq support of mtk-mmsys config API for mt8195
    vdosys1
  soc: mediatek: mmsys: modify reset controller for MT8195 vdosys1
  soc: mediatek: change the mutex defines and the mutex_mod type
  soc: mediatek: add mtk-mutex support for mt8195 vdosys1
  drm/mediatek: add display MDP RDMA support for MT8195
  drm/mediatek: add display merge advance config API for MT8195
  drm/mediatek: add display merge start/stop API for cmdq support
  drm/mediatek: add display merge mute/unmute support for MT8195
  drm/mediatek: add display merge async reset control
  drm/mediatek: add ETHDR support for MT8195
  drm/mediatek: add mediatek-drm plane color encoding info
  drm/mediatek: add ovl_adaptor support for MT8195
  drm/mediatek: modify mediatek-drm for mt8195 multi mmsys support
  drm/mediatek: add drm ovl_adaptor sub driver for MT8195
  drm/mediatek: add mediatek-drm of vdosys1 support for MT8195
  arm64: dts: mt8195: add display node for vdosys1

 .../arm/mediatek/mediatek,mdp-rdma.yaml       |  77 ++++
 .../display/mediatek/mediatek,ethdr.yaml      | 147 ++++++
 .../display/mediatek/mediatek,merge.yaml      |   4 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 222 +++++++++
 drivers/gpu/drm/mediatek/Makefile             |   5 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  28 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     |  89 +++-
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       |  38 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h       |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  30 +-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        | 343 ++++++++++----
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |  13 +-
 drivers/gpu/drm/mediatek/mtk_drm_plane.c      |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.h      |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c          | 376 +++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h          |  25 +
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c       | 315 +++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h       |  20 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 199 ++++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  80 +++-
 drivers/soc/mediatek/mtk-mmsys.h              |  12 +
 drivers/soc/mediatek/mtk-mutex.c              | 296 +++++++-----
 include/dt-bindings/reset/mt8195-resets.h     |  12 +
 include/linux/soc/mediatek/mtk-mmsys.h        |  22 +
 26 files changed, 2552 insertions(+), 243 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mdp-rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:29 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:29 +0800
Subject: [PATCH v11 06/22] soc: mediatek: add mtk-mmsys config API for mt8195
 vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-7-nancy.lin@mediatek.com>

Add mmsys config API. The config API is used for config mmsys reg.
Some mmsys regs need to be setting according to the HW engine binding
to the mmsys simultaneously.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 62 ++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 34 ++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       | 10 +++++
 include/linux/soc/mediatek/mtk-mmsys.h | 16 +++++++
 4 files changed, 122 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index 65da65754d6e..11ba79e3275e 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -229,6 +229,21 @@
 #define MT8195_VDO1_MIXER_SOUT_SEL_IN				0xf68
 #define MT8195_MIXER_SOUT_SEL_IN_FROM_DISP_MIXER			0
 
+#define MT8195_VDO1_MERGE0_ASYNC_CFG_WD	0xe30
+#define MT8195_VDO1_MERGE1_ASYNC_CFG_WD	0xe40
+#define MT8195_VDO1_MERGE2_ASYNC_CFG_WD	0xe50
+#define MT8195_VDO1_MERGE3_ASYNC_CFG_WD	0xe60
+#define MT8195_VDO1_HDRBE_ASYNC_CFG_WD	0xe70
+#define MT8195_VDO1_HDR_TOP_CFG		0xd00
+#define MT8195_VDO1_MIXER_IN1_ALPHA	0xd30
+#define MT8195_VDO1_MIXER_IN2_ALPHA	0xd34
+#define MT8195_VDO1_MIXER_IN3_ALPHA	0xd38
+#define MT8195_VDO1_MIXER_IN4_ALPHA	0xd3c
+#define MT8195_VDO1_MIXER_IN1_PAD	0xd40
+#define MT8195_VDO1_MIXER_IN2_PAD	0xd44
+#define MT8195_VDO1_MIXER_IN3_PAD	0xd48
+#define MT8195_VDO1_MIXER_IN4_PAD	0xd4c
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -353,4 +368,51 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	}
 };
 
+/*
+ * mtk_mmsys_config table is used for config mmsys reg in runtime.
+ * MMSYS_CONFIG_MERGE_ASYNC_WIDTH: config merge async width
+ * MMSYS_CONFIG_MERGE_ASYNC_HEIGHT: config merge async height
+ * MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH: config hdr_be async width
+ * MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT: config hdr_be async height
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_ODD: config mixer odd channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN: config mixer even channel 9bit alpha value
+ * MMSYS_CONFIG_MIXER_IN_CH_SWAP: config mixer input RGB channel swap
+ * MMSYS_CONFIG_HDR_ALPHA_SEL: config alpha source
+ * MMSYS_CONFIG_MIXER_IN_MODE: config mixer pad mode(bypass/even extend mode)
+ * MMSYS_CONFIG_MIXER_IN_BIWIDTH: config mixer pad width. formula: width / 2 - 1
+ */
+static const struct mtk_mmsys_config mmsys_mt8195_config_table[] = {
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 0, MT8195_VDO1_MERGE0_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 1, MT8195_VDO1_MERGE1_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 2, MT8195_VDO1_MERGE2_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MERGE_ASYNC_WIDTH, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_MERGE_ASYNC_HEIGHT, 3, MT8195_VDO1_MERGE3_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(13, 0), 0},
+	{ MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0, MT8195_VDO1_HDRBE_ASYNC_CFG_WD, GENMASK(29, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 1, MT8195_VDO1_MIXER_IN1_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 2, MT8195_VDO1_MIXER_IN2_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 3, MT8195_VDO1_MIXER_IN3_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(8, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, 4, MT8195_VDO1_MIXER_IN4_ALPHA, GENMASK(24, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(4, 4), 4},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 1, MT8195_VDO1_HDR_TOP_CFG, GENMASK(20, 20), 20},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 2, MT8195_VDO1_HDR_TOP_CFG, GENMASK(21, 21), 21},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 3, MT8195_VDO1_HDR_TOP_CFG, GENMASK(22, 22), 22},
+	{ MMSYS_CONFIG_HDR_ALPHA_SEL, 4, MT8195_VDO1_HDR_TOP_CFG, GENMASK(23, 23), 23},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_MODE, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(1, 0), 0},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 1, MT8195_VDO1_MIXER_IN1_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 2, MT8195_VDO1_MIXER_IN2_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 3, MT8195_VDO1_MIXER_IN3_PAD, GENMASK(31, 16), 16},
+	{ MMSYS_CONFIG_MIXER_IN_BIWIDTH, 4, MT8195_VDO1_MIXER_IN4_PAD, GENMASK(31, 16), 16},
+};
+
 #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 416a97d7fd83..725a99fcbc6d 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -73,6 +73,8 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 	.clk_driver = "clk-mt8195-vdo1",
 	.routes = mmsys_mt8195_routing_table,
 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+	.config = mmsys_mt8195_config_table,
+	.num_configs = ARRAY_SIZE(mmsys_mt8195_config_table),
 };
 
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
@@ -177,6 +179,38 @@ static const struct reset_control_ops mtk_mmsys_reset_ops = {
 	.reset = mtk_mmsys_reset,
 };
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const struct mtk_mmsys_config *mmsys_config = mmsys->data->config;
+	u32 reg_val;
+	u32 mask;
+	u32 offset;
+	int i;
+	u32 tmp;
+
+	if (!mmsys->data->num_configs)
+		return;
+
+	for (i = 0; i < mmsys->data->num_configs; i++)
+		if (config == mmsys_config[i].config && id == mmsys_config[i].id)
+			break;
+
+	if (i == mmsys->data->num_configs)
+		return;
+
+	offset = mmsys_config[i].addr;
+	mask = mmsys_config[i].mask;
+	reg_val = val << mmsys_config[i].shift;
+
+	tmp = readl(mmsys->regs + offset);
+
+	tmp = (tmp & ~mask) | reg_val;
+	writel(tmp, mmsys->regs + offset);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_config);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index 8b0ed05117ea..2694021435d2 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -88,10 +88,20 @@ struct mtk_mmsys_routes {
 	u32 val;
 };
 
+struct mtk_mmsys_config {
+	enum mtk_mmsys_config_type config;
+	u32 id;
+	u32 addr;
+	u32 mask;
+	u32 shift;
+};
+
 struct mtk_mmsys_driver_data {
 	const char *clk_driver;
 	const struct mtk_mmsys_routes *routes;
 	const unsigned int num_routes;
+	const struct mtk_mmsys_config *config;
+	const unsigned int num_configs;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index eaf7f7345519..b2d2310d7e7a 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -56,6 +56,19 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_ID_MAX,
 };
 
+enum mtk_mmsys_config_type {
+	MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+	MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH,
+	MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT,
+	MMSYS_CONFIG_HDR_ALPHA_SEL,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_ODD,
+	MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN,
+	MMSYS_CONFIG_MIXER_IN_CH_SWAP,
+	MMSYS_CONFIG_MIXER_IN_MODE,
+	MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+};
+
 void mtk_mmsys_ddp_connect(struct device *dev,
 			   enum mtk_ddp_comp_id cur,
 			   enum mtk_ddp_comp_id next);
@@ -64,4 +77,7 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 			      enum mtk_ddp_comp_id cur,
 			      enum mtk_ddp_comp_id next);
 
+void mtk_mmsys_ddp_config(struct device *dev, enum mtk_mmsys_config_type config,
+			  u32 id, u32 val);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:26 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:26 +0800
Subject: [PATCH v11 03/22] dt-bindings: mediatek: add ethdr definition for
 mt8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-4-nancy.lin@mediatek.com>

Add vdosys1 ETHDR definition.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,ethdr.yaml      | 147 ++++++++++++++++++
 1 file changed, 147 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
new file mode 100644
index 000000000000..131eed5eeeb7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ethdr.yaml
@@ -0,0 +1,147 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ethdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Ethdr Device Tree Bindings
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  ETHDR is designed for HDR video and graphics conversion in the external display path.
+  It handles multiple HDR input types and performs tone mapping, color space/color
+  format conversion, and then combine different layers, output the required HDR or
+  SDR signal to the subsequent display path. This engine is composed of two video
+  frontends, two graphic frontends, one video backend and a mixer. ETHDR has two
+  DMA function blocks, DS and ADL. These two function blocks read the pre-programmed
+  registers from DRAM and set them to HW in the v-blanking period.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-disp-ethdr
+  reg:
+    maxItems: 7
+  reg-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+  interrupts:
+    minItems: 1
+  iommus:
+    description: The compatible property is DMA function blocks.
+      Should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for
+      details.
+    minItems: 1
+    maxItems: 2
+  clocks:
+    items:
+      - description: mixer clock
+      - description: video frontend 0 clock
+      - description: video frontend 1 clock
+      - description: graphic frontend 0 clock
+      - description: graphic frontend 1 clock
+      - description: video backend clock
+      - description: autodownload and menuload clock
+      - description: video frontend 0 async clock
+      - description: video frontend 1 async clock
+      - description: graphic frontend 0 async clock
+      - description: graphic frontend 1 async clock
+      - description: video backend async clock
+      - description: ethdr top clock
+  clock-names:
+    items:
+      - const: mixer
+      - const: vdo_fe0
+      - const: vdo_fe1
+      - const: gfx_fe0
+      - const: gfx_fe1
+      - const: vdo_be
+      - const: adl_ds
+      - const: vdo_fe0_async
+      - const: vdo_fe1_async
+      - const: gfx_fe0_async
+      - const: gfx_fe1_async
+      - const: vdo_be_async
+      - const: ethdr_top
+  power-domains:
+    maxItems: 1
+  resets:
+    maxItems: 5
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: The register of display function block to be set by gce.
+      There are 4 arguments in this property, gce node, subsys id, offset and
+      register size. The subsys id is defined in the gce header of each chips
+      include/include/dt-bindings/gce/<chip>-gce.h, mapping to the register of
+      display function block.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+
+    disp_ethdr at 1c114000 {
+            compatible = "mediatek,mt8195-disp-ethdr";
+            reg = <0 0x1c114000 0 0x1000>,
+                  <0 0x1c115000 0 0x1000>,
+                  <0 0x1c117000 0 0x1000>,
+                  <0 0x1c119000 0 0x1000>,
+                  <0 0x1c11A000 0 0x1000>,
+                  <0 0x1c11B000 0 0x1000>,
+                  <0 0x1c11C000 0 0x1000>;
+            reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                        "vdo_be", "adl_ds";
+            mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x4000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0x5000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0x7000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0x9000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0xA000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0xB000 0x1000>,
+                                      <&gce0 SUBSYS_1c11XXXX 0xC000 0x1000>;
+            clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+                     <&vdosys1 CLK_VDO1_26M_SLOW>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+                     <&topckgen CLK_TOP_ETHDR_SEL>;
+            clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+                          "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+                          "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+                          "ethdr_top";
+            power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+            iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+                     <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+            interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+            resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+                     <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
+    };
+
+...
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:32 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:32 +0800
Subject: [PATCH v11 09/22] soc: mediatek: change the mutex defines and the
 mutex_mod type
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-10-nancy.lin@mediatek.com>

This is a preparation for adding support for mt8195 vdosys1 mutex.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements,
so change it to support multi-bit control.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 242 +++++++++++++++----------------
 1 file changed, 121 insertions(+), 121 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 36502b27fe20..ff2f74668e8a 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -29,113 +29,113 @@
 
 #define INT_MUTEX				BIT(1)
 
-#define MT8167_MUTEX_MOD_DISP_PWM		1
-#define MT8167_MUTEX_MOD_DISP_OVL0		6
-#define MT8167_MUTEX_MOD_DISP_OVL1		7
-#define MT8167_MUTEX_MOD_DISP_RDMA0		8
-#define MT8167_MUTEX_MOD_DISP_RDMA1		9
-#define MT8167_MUTEX_MOD_DISP_WDMA0		10
-#define MT8167_MUTEX_MOD_DISP_CCORR		11
-#define MT8167_MUTEX_MOD_DISP_COLOR		12
-#define MT8167_MUTEX_MOD_DISP_AAL		13
-#define MT8167_MUTEX_MOD_DISP_GAMMA		14
-#define MT8167_MUTEX_MOD_DISP_DITHER		15
-#define MT8167_MUTEX_MOD_DISP_UFOE		16
-
-#define MT8192_MUTEX_MOD_DISP_OVL0		0
-#define MT8192_MUTEX_MOD_DISP_OVL0_2L		1
-#define MT8192_MUTEX_MOD_DISP_RDMA0		2
-#define MT8192_MUTEX_MOD_DISP_COLOR0		4
-#define MT8192_MUTEX_MOD_DISP_CCORR0		5
-#define MT8192_MUTEX_MOD_DISP_AAL0		6
-#define MT8192_MUTEX_MOD_DISP_GAMMA0		7
-#define MT8192_MUTEX_MOD_DISP_POSTMASK0		8
-#define MT8192_MUTEX_MOD_DISP_DITHER0		9
-#define MT8192_MUTEX_MOD_DISP_OVL2_2L		16
-#define MT8192_MUTEX_MOD_DISP_RDMA4		17
-
-#define MT8183_MUTEX_MOD_DISP_RDMA0		0
-#define MT8183_MUTEX_MOD_DISP_RDMA1		1
-#define MT8183_MUTEX_MOD_DISP_OVL0		9
-#define MT8183_MUTEX_MOD_DISP_OVL0_2L		10
-#define MT8183_MUTEX_MOD_DISP_OVL1_2L		11
-#define MT8183_MUTEX_MOD_DISP_WDMA0		12
-#define MT8183_MUTEX_MOD_DISP_COLOR0		13
-#define MT8183_MUTEX_MOD_DISP_CCORR0		14
-#define MT8183_MUTEX_MOD_DISP_AAL0		15
-#define MT8183_MUTEX_MOD_DISP_GAMMA0		16
-#define MT8183_MUTEX_MOD_DISP_DITHER0		17
-
-#define MT8173_MUTEX_MOD_DISP_OVL0		11
-#define MT8173_MUTEX_MOD_DISP_OVL1		12
-#define MT8173_MUTEX_MOD_DISP_RDMA0		13
-#define MT8173_MUTEX_MOD_DISP_RDMA1		14
-#define MT8173_MUTEX_MOD_DISP_RDMA2		15
-#define MT8173_MUTEX_MOD_DISP_WDMA0		16
-#define MT8173_MUTEX_MOD_DISP_WDMA1		17
-#define MT8173_MUTEX_MOD_DISP_COLOR0		18
-#define MT8173_MUTEX_MOD_DISP_COLOR1		19
-#define MT8173_MUTEX_MOD_DISP_AAL		20
-#define MT8173_MUTEX_MOD_DISP_GAMMA		21
-#define MT8173_MUTEX_MOD_DISP_UFOE		22
-#define MT8173_MUTEX_MOD_DISP_PWM0		23
-#define MT8173_MUTEX_MOD_DISP_PWM1		24
-#define MT8173_MUTEX_MOD_DISP_OD		25
-
-#define MT8195_MUTEX_MOD_DISP_OVL0		0
-#define MT8195_MUTEX_MOD_DISP_WDMA0		1
-#define MT8195_MUTEX_MOD_DISP_RDMA0		2
-#define MT8195_MUTEX_MOD_DISP_COLOR0		3
-#define MT8195_MUTEX_MOD_DISP_CCORR0		4
-#define MT8195_MUTEX_MOD_DISP_AAL0		5
-#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
-#define MT8195_MUTEX_MOD_DISP_DITHER0		7
-#define MT8195_MUTEX_MOD_DISP_DSI0		8
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
-#define MT8195_MUTEX_MOD_DISP_OVL1		10
-#define MT8195_MUTEX_MOD_DISP_WDMA1		11
-#define MT8195_MUTEX_MOD_DISP_RDMA1		12
-#define MT8195_MUTEX_MOD_DISP_COLOR1		13
-#define MT8195_MUTEX_MOD_DISP_CCORR1		14
-#define MT8195_MUTEX_MOD_DISP_AAL1		15
-#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
-#define MT8195_MUTEX_MOD_DISP_DITHER1		17
-#define MT8195_MUTEX_MOD_DISP_DSI1		18
-#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
-#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
-#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
-#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
-#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
-#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
-#define MT8195_MUTEX_MOD_DISP_PWM0		27
-#define MT8195_MUTEX_MOD_DISP_PWM1		28
-
-#define MT2712_MUTEX_MOD_DISP_PWM2		10
-#define MT2712_MUTEX_MOD_DISP_OVL0		11
-#define MT2712_MUTEX_MOD_DISP_OVL1		12
-#define MT2712_MUTEX_MOD_DISP_RDMA0		13
-#define MT2712_MUTEX_MOD_DISP_RDMA1		14
-#define MT2712_MUTEX_MOD_DISP_RDMA2		15
-#define MT2712_MUTEX_MOD_DISP_WDMA0		16
-#define MT2712_MUTEX_MOD_DISP_WDMA1		17
-#define MT2712_MUTEX_MOD_DISP_COLOR0		18
-#define MT2712_MUTEX_MOD_DISP_COLOR1		19
-#define MT2712_MUTEX_MOD_DISP_AAL0		20
-#define MT2712_MUTEX_MOD_DISP_UFOE		22
-#define MT2712_MUTEX_MOD_DISP_PWM0		23
-#define MT2712_MUTEX_MOD_DISP_PWM1		24
-#define MT2712_MUTEX_MOD_DISP_OD0		25
-#define MT2712_MUTEX_MOD2_DISP_AAL1		33
-#define MT2712_MUTEX_MOD2_DISP_OD1		34
-
-#define MT2701_MUTEX_MOD_DISP_OVL		3
-#define MT2701_MUTEX_MOD_DISP_WDMA		6
-#define MT2701_MUTEX_MOD_DISP_COLOR		7
-#define MT2701_MUTEX_MOD_DISP_BLS		9
-#define MT2701_MUTEX_MOD_DISP_RDMA0		10
-#define MT2701_MUTEX_MOD_DISP_RDMA1		12
+#define MT8167_MUTEX_MOD_DISP_PWM		BIT(1)
+#define MT8167_MUTEX_MOD_DISP_OVL0		BIT(6)
+#define MT8167_MUTEX_MOD_DISP_OVL1		BIT(7)
+#define MT8167_MUTEX_MOD_DISP_RDMA0		BIT(8)
+#define MT8167_MUTEX_MOD_DISP_RDMA1		BIT(9)
+#define MT8167_MUTEX_MOD_DISP_WDMA0		BIT(10)
+#define MT8167_MUTEX_MOD_DISP_CCORR		BIT(11)
+#define MT8167_MUTEX_MOD_DISP_COLOR		BIT(12)
+#define MT8167_MUTEX_MOD_DISP_AAL		BIT(13)
+#define MT8167_MUTEX_MOD_DISP_GAMMA		BIT(14)
+#define MT8167_MUTEX_MOD_DISP_DITHER		BIT(15)
+#define MT8167_MUTEX_MOD_DISP_UFOE		BIT(16)
+
+#define MT8192_MUTEX_MOD_DISP_OVL0		BIT(0)
+#define MT8192_MUTEX_MOD_DISP_OVL0_2L		BIT(1)
+#define MT8192_MUTEX_MOD_DISP_RDMA0		BIT(2)
+#define MT8192_MUTEX_MOD_DISP_COLOR0		BIT(4)
+#define MT8192_MUTEX_MOD_DISP_CCORR0		BIT(5)
+#define MT8192_MUTEX_MOD_DISP_AAL0		BIT(6)
+#define MT8192_MUTEX_MOD_DISP_GAMMA0		BIT(7)
+#define MT8192_MUTEX_MOD_DISP_POSTMASK0		BIT(8)
+#define MT8192_MUTEX_MOD_DISP_DITHER0		BIT(9)
+#define MT8192_MUTEX_MOD_DISP_OVL2_2L		BIT(16)
+#define MT8192_MUTEX_MOD_DISP_RDMA4		BIT(17)
+
+#define MT8183_MUTEX_MOD_DISP_RDMA0		BIT(0)
+#define MT8183_MUTEX_MOD_DISP_RDMA1		BIT(1)
+#define MT8183_MUTEX_MOD_DISP_OVL0		BIT(9)
+#define MT8183_MUTEX_MOD_DISP_OVL0_2L		BIT(10)
+#define MT8183_MUTEX_MOD_DISP_OVL1_2L		BIT(11)
+#define MT8183_MUTEX_MOD_DISP_WDMA0		BIT(12)
+#define MT8183_MUTEX_MOD_DISP_COLOR0		BIT(13)
+#define MT8183_MUTEX_MOD_DISP_CCORR0		BIT(14)
+#define MT8183_MUTEX_MOD_DISP_AAL0		BIT(15)
+#define MT8183_MUTEX_MOD_DISP_GAMMA0		BIT(16)
+#define MT8183_MUTEX_MOD_DISP_DITHER0		BIT(17)
+
+#define MT8173_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT8173_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT8173_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT8173_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT8173_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT8173_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT8173_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT8173_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT8173_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT8173_MUTEX_MOD_DISP_AAL		BIT(20)
+#define MT8173_MUTEX_MOD_DISP_GAMMA		BIT(21)
+#define MT8173_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT8173_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT8173_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT8173_MUTEX_MOD_DISP_OD		BIT(25)
+
+#define MT8195_MUTEX_MOD_DISP_OVL0		BIT(0)
+#define MT8195_MUTEX_MOD_DISP_WDMA0		BIT(1)
+#define MT8195_MUTEX_MOD_DISP_RDMA0		BIT(2)
+#define MT8195_MUTEX_MOD_DISP_COLOR0		BIT(3)
+#define MT8195_MUTEX_MOD_DISP_CCORR0		BIT(4)
+#define MT8195_MUTEX_MOD_DISP_AAL0		BIT(5)
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		BIT(6)
+#define MT8195_MUTEX_MOD_DISP_DITHER0		BIT(7)
+#define MT8195_MUTEX_MOD_DISP_DSI0		BIT(8)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	BIT(9)
+#define MT8195_MUTEX_MOD_DISP_OVL1		BIT(10)
+#define MT8195_MUTEX_MOD_DISP_WDMA1		BIT(11)
+#define MT8195_MUTEX_MOD_DISP_RDMA1		BIT(12)
+#define MT8195_MUTEX_MOD_DISP_COLOR1		BIT(13)
+#define MT8195_MUTEX_MOD_DISP_CCORR1		BIT(14)
+#define MT8195_MUTEX_MOD_DISP_AAL1		BIT(15)
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		BIT(16)
+#define MT8195_MUTEX_MOD_DISP_DITHER1		BIT(17)
+#define MT8195_MUTEX_MOD_DISP_DSI1		BIT(18)
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	BIT(19)
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		BIT(20)
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		BIT(21)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	BIT(22)
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	BIT(23)
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	BIT(24)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	BIT(25)
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	BIT(26)
+#define MT8195_MUTEX_MOD_DISP_PWM0		BIT(27)
+#define MT8195_MUTEX_MOD_DISP_PWM1		BIT(28)
+
+#define MT2712_MUTEX_MOD_DISP_PWM2		BIT(10)
+#define MT2712_MUTEX_MOD_DISP_OVL0		BIT(11)
+#define MT2712_MUTEX_MOD_DISP_OVL1		BIT(12)
+#define MT2712_MUTEX_MOD_DISP_RDMA0		BIT(13)
+#define MT2712_MUTEX_MOD_DISP_RDMA1		BIT(14)
+#define MT2712_MUTEX_MOD_DISP_RDMA2		BIT(15)
+#define MT2712_MUTEX_MOD_DISP_WDMA0		BIT(16)
+#define MT2712_MUTEX_MOD_DISP_WDMA1		BIT(17)
+#define MT2712_MUTEX_MOD_DISP_COLOR0		BIT(18)
+#define MT2712_MUTEX_MOD_DISP_COLOR1		BIT(19)
+#define MT2712_MUTEX_MOD_DISP_AAL0		BIT(20)
+#define MT2712_MUTEX_MOD_DISP_UFOE		BIT(22)
+#define MT2712_MUTEX_MOD_DISP_PWM0		BIT(23)
+#define MT2712_MUTEX_MOD_DISP_PWM1		BIT(24)
+#define MT2712_MUTEX_MOD_DISP_OD0		BIT(25)
+#define MT2712_MUTEX_MOD2_DISP_AAL1		BIT(33)
+#define MT2712_MUTEX_MOD2_DISP_OD1		BIT(34)
+
+#define MT2701_MUTEX_MOD_DISP_OVL		BIT(3)
+#define MT2701_MUTEX_MOD_DISP_WDMA		BIT(6)
+#define MT2701_MUTEX_MOD_DISP_COLOR		BIT(7)
+#define MT2701_MUTEX_MOD_DISP_BLS		BIT(9)
+#define MT2701_MUTEX_MOD_DISP_RDMA0		BIT(10)
+#define MT2701_MUTEX_MOD_DISP_RDMA1		BIT(12)
 
 #define MT2712_MUTEX_SOF_SINGLE_MODE		0
 #define MT2712_MUTEX_SOF_DSI0			1
@@ -183,7 +183,7 @@ enum mtk_mutex_sof_id {
 };
 
 struct mtk_mutex_data {
-	const unsigned int *mutex_mod;
+	const unsigned long *mutex_mod;
 	const unsigned int *mutex_sof;
 	const unsigned int mutex_mod_reg;
 	const unsigned int mutex_sof_reg;
@@ -198,7 +198,7 @@ struct mtk_mutex_ctx {
 	const struct mtk_mutex_data	*data;
 };
 
-static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_BLS] = MT2701_MUTEX_MOD_DISP_BLS,
 	[DDP_COMPONENT_COLOR0] = MT2701_MUTEX_MOD_DISP_COLOR,
 	[DDP_COMPONENT_OVL0] = MT2701_MUTEX_MOD_DISP_OVL,
@@ -207,7 +207,7 @@ static const unsigned int mt2701_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT2701_MUTEX_MOD_DISP_WDMA,
 };
 
-static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT2712_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_AAL1] = MT2712_MUTEX_MOD2_DISP_AAL1,
 	[DDP_COMPONENT_COLOR0] = MT2712_MUTEX_MOD_DISP_COLOR0,
@@ -227,7 +227,7 @@ static const unsigned int mt2712_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT2712_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8167_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_CCORR] = MT8167_MUTEX_MOD_DISP_CCORR,
 	[DDP_COMPONENT_COLOR0] = MT8167_MUTEX_MOD_DISP_COLOR,
@@ -242,7 +242,7 @@ static const unsigned int mt8167_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8167_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8173_MUTEX_MOD_DISP_AAL,
 	[DDP_COMPONENT_COLOR0] = MT8173_MUTEX_MOD_DISP_COLOR0,
 	[DDP_COMPONENT_COLOR1] = MT8173_MUTEX_MOD_DISP_COLOR1,
@@ -260,7 +260,7 @@ static const unsigned int mt8173_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA1] = MT8173_MUTEX_MOD_DISP_WDMA1,
 };
 
-static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8183_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8183_MUTEX_MOD_DISP_CCORR0,
 	[DDP_COMPONENT_COLOR0] = MT8183_MUTEX_MOD_DISP_COLOR0,
@@ -274,7 +274,7 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
-static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
 	[DDP_COMPONENT_COLOR0] = MT8192_MUTEX_MOD_DISP_COLOR0,
@@ -288,7 +288,7 @@ static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
 };
 
-static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+static const unsigned long mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
 	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
 	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
@@ -467,16 +467,16 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 		sof_id = MUTEX_SOF_DP_INTF0;
 		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << mtx->data->mutex_mod[id];
+			reg |= mtx->data->mutex_mod[id];
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg |= 1 << (mtx->data->mutex_mod[id] - 32);
+			reg |= (mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		return;
@@ -512,16 +512,16 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 						  mutex->id));
 		break;
 	default:
-		if (mtx->data->mutex_mod[id] < 32) {
+		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
 						    mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << mtx->data->mutex_mod[id]);
+			reg &= ~(mtx->data->mutex_mod[id]);
 			writel_relaxed(reg, mtx->regs + offset);
 		} else {
 			offset = DISP_REG_MUTEX_MOD2(mutex->id);
 			reg = readl_relaxed(mtx->regs + offset);
-			reg &= ~(1 << (mtx->data->mutex_mod[id] - 32));
+			reg &= ~(mtx->data->mutex_mod[id] >> 32);
 			writel_relaxed(reg, mtx->regs + offset);
 		}
 		break;
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:34 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:34 +0800
Subject: [PATCH v11 11/22] drm/mediatek: add display MDP RDMA support for
 MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-12-nancy.lin@mediatek.com>

Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/Makefile       |   3 +-
 drivers/gpu/drm/mediatek/mtk_disp_drv.h |   7 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |   1 +
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c | 315 ++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h |  20 ++
 6 files changed, 346 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_mdp_rdma.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index a38e88e82d12..6e604a933ed0 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -13,7 +13,8 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_drm_gem.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
-		  mtk_dpi.o
+		  mtk_dpi.o \
+		  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
 
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index a33b13fe2b6e..b3a372cab0bd 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -8,6 +8,7 @@
 
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include "mtk_drm_plane.h"
+#include "mtk_mdp_rdma.h"
 
 int mtk_aal_clk_enable(struct device *dev);
 void mtk_aal_clk_disable(struct device *dev);
@@ -106,4 +107,10 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_mdp_rdma_clk_enable(struct device *dev);
+void mtk_mdp_rdma_clk_disable(struct device *dev);
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt);
 #endif
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 274a5bb10851..fa41306422df 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_dpi_driver,
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
+	&mtk_mdp_rdma_driver,
 };
 
 static int __init mtk_drm_init(void)
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index a58cebd01d35..64a1f66df26a 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -55,5 +55,6 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_mdp_rdma_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
new file mode 100644
index 000000000000..eecfa98ff52e
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_drv.h"
+#include "mtk_mdp_rdma.h"
+
+#define MDP_RDMA_EN			0x000
+#define FLD_ROT_ENABLE				BIT(0)
+#define MDP_RDMA_RESET			0x008
+#define MDP_RDMA_CON			0x020
+#define FLD_OUTPUT_10B				BIT(5)
+#define FLD_SIMPLE_MODE				BIT(4)
+#define MDP_RDMA_GMCIF_CON		0x028
+#define FLD_COMMAND_DIV				BIT(0)
+#define FLD_EXT_PREULTRA_EN			BIT(3)
+#define FLD_RD_REQ_TYPE				GENMASK(7, 4)
+#define VAL_RD_REQ_TYPE_BURST_8_ACCESS		7
+#define FLD_ULTRA_EN				GENMASK(13, 12)
+#define VAL_ULTRA_EN_ENABLE			1
+#define FLD_PRE_ULTRA_EN			GENMASK(17, 16)
+#define VAL_PRE_ULTRA_EN_ENABLE			1
+#define FLD_EXT_ULTRA_EN			BIT(18)
+#define MDP_RDMA_SRC_CON		0x030
+#define FLD_OUTPUT_ARGB				BIT(25)
+#define FLD_BIT_NUMBER				GENMASK(19, 18)
+#define FLD_SWAP				BIT(14)
+#define FLD_UNIFORM_CONFIG			BIT(17)
+#define RDMA_INPUT_10BIT			BIT(18)
+#define FLD_SRC_FORMAT				GENMASK(3, 0)
+#define MDP_RDMA_COMP_CON		0x038
+#define FLD_AFBC_EN				BIT(22)
+#define FLD_AFBC_YUV_TRANSFORM			BIT(21)
+#define FLD_UFBDC_EN				BIT(12)
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE	0x060
+#define FLD_MF_BKGD_WB				GENMASK(22, 0)
+#define MDP_RDMA_MF_SRC_SIZE		0x070
+#define FLD_MF_SRC_H				GENMASK(30, 16)
+#define FLD_MF_SRC_W				GENMASK(14, 0)
+#define MDP_RDMA_MF_CLIP_SIZE		0x078
+#define FLD_MF_CLIP_H				GENMASK(30, 16)
+#define FLD_MF_CLIP_W				GENMASK(14, 0)
+#define MDP_RDMA_SRC_OFFSET_0		0x118
+#define FLD_SRC_OFFSET_0			GENMASK(31, 0)
+#define MDP_RDMA_TRANSFORM_0		0x200
+#define FLD_INT_MATRIX_SEL			GENMASK(27, 23)
+#define FLD_TRANS_EN				BIT(16)
+#define MDP_RDMA_SRC_BASE_0		0xf00
+#define FLD_SRC_BASE_0				GENMASK(31, 0)
+
+#define RDMA_CSC_FULL709_TO_RGB			5
+#define RDMA_CSC_BT601_TO_RGB			6
+
+enum rdma_format {
+	RDMA_INPUT_FORMAT_RGB565 = 0,
+	RDMA_INPUT_FORMAT_RGB888 = 1,
+	RDMA_INPUT_FORMAT_RGBA8888 = 2,
+	RDMA_INPUT_FORMAT_ARGB8888 = 3,
+	RDMA_INPUT_FORMAT_UYVY = 4,
+	RDMA_INPUT_FORMAT_YUY2 = 5,
+	RDMA_INPUT_FORMAT_Y8 = 7,
+	RDMA_INPUT_FORMAT_YV12 = 8,
+	RDMA_INPUT_FORMAT_UYVY_3PL = 9,
+	RDMA_INPUT_FORMAT_NV12 = 12,
+	RDMA_INPUT_FORMAT_UYVY_2PL = 13,
+	RDMA_INPUT_FORMAT_Y410 = 14
+};
+
+struct mtk_mdp_rdma {
+	void __iomem		*regs;
+	struct clk		*clk;
+	struct cmdq_client_reg	cmdq_reg;
+};
+
+static unsigned int rdma_fmt_convert(unsigned int fmt)
+{
+	switch (fmt) {
+	default:
+	case DRM_FORMAT_RGB565:
+		return RDMA_INPUT_FORMAT_RGB565;
+	case DRM_FORMAT_BGR565:
+		return RDMA_INPUT_FORMAT_RGB565 | FLD_SWAP;
+	case DRM_FORMAT_RGB888:
+		return RDMA_INPUT_FORMAT_RGB888;
+	case DRM_FORMAT_BGR888:
+		return RDMA_INPUT_FORMAT_RGB888 | FLD_SWAP;
+	case DRM_FORMAT_RGBX8888:
+	case DRM_FORMAT_RGBA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888;
+	case DRM_FORMAT_BGRX8888:
+	case DRM_FORMAT_BGRA8888:
+		return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP;
+	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_ARGB8888:
+		return RDMA_INPUT_FORMAT_RGBA8888;
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ABGR8888:
+		return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP;
+	case DRM_FORMAT_ABGR2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_ARGB2101010:
+		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_RGBA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_BGRA1010102:
+		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_10BIT;
+	case DRM_FORMAT_UYVY:
+		return RDMA_INPUT_FORMAT_UYVY;
+	case DRM_FORMAT_YUYV:
+		return RDMA_INPUT_FORMAT_YUY2;
+	}
+}
+
+static unsigned int rdma_color_convert(unsigned int color_encoding)
+{
+	switch (color_encoding) {
+	default:
+	case DRM_COLOR_YCBCR_BT709:
+		return RDMA_CSC_FULL709_TO_RGB;
+	case DRM_COLOR_YCBCR_BT601:
+		return RDMA_CSC_BT601_TO_RGB;
+	}
+}
+
+static void mtk_mdp_rdma_fifo_config(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_EXT_ULTRA_EN | VAL_PRE_ULTRA_EN_ENABLE << 16 |
+			   VAL_ULTRA_EN_ENABLE << 12 | VAL_RD_REQ_TYPE_BURST_8_ACCESS << 4 |
+			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_GMCIF_CON, FLD_EXT_ULTRA_EN |
+			   FLD_PRE_ULTRA_EN | FLD_ULTRA_EN | FLD_RD_REQ_TYPE |
+			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV);
+}
+
+void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_ROT_ENABLE, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);
+}
+
+void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg,
+			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);
+	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);
+	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);
+}
+
+void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,
+			 struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);
+	const struct drm_format_info *fmt_info = drm_format_info(cfg->fmt);
+	bool csc_enable = fmt_info->is_yuv ? true : false;
+	unsigned int src_pitch_y = cfg->pitch;
+	unsigned int offset_y = 0;
+
+	mtk_mdp_rdma_fifo_config(dev, cmdq_pkt);
+
+	mtk_ddp_write_mask(cmdq_pkt, FLD_UNIFORM_CONFIG, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_CON, FLD_UNIFORM_CONFIG);
+	mtk_ddp_write_mask(cmdq_pkt, rdma_fmt_convert(cfg->fmt), &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_CON, FLD_SWAP | FLD_SRC_FORMAT | FLD_BIT_NUMBER);
+
+	if (!csc_enable && fmt_info->has_alpha)
+		mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_ARGB, &priv->cmdq_reg,
+				   priv->regs, MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
+	else
+		mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+				   MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);
+
+	mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);
+
+	mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, FLD_MF_BKGD_WB);
+
+	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON,
+			   FLD_AFBC_YUV_TRANSFORM | FLD_UFBDC_EN | FLD_AFBC_EN);
+	mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_10B, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_CON, FLD_OUTPUT_10B);
+	mtk_ddp_write_mask(cmdq_pkt, FLD_SIMPLE_MODE, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_CON, FLD_SIMPLE_MODE);
+	if (csc_enable)
+		mtk_ddp_write_mask(cmdq_pkt, rdma_color_convert(cfg->color_encoding) << 23,
+				   &priv->cmdq_reg, priv->regs, MDP_RDMA_TRANSFORM_0,
+				   FLD_INT_MATRIX_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, csc_enable << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_TRANSFORM_0, FLD_TRANS_EN);
+
+	offset_y  = cfg->x_left * fmt_info->cpp[0] + cfg->y_top * src_pitch_y;
+
+	mtk_ddp_write_mask(cmdq_pkt, offset_y, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_SRC_OFFSET_0, FLD_SRC_OFFSET_0);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_W);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_H);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_W);
+	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,
+			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_H);
+}
+
+int mtk_mdp_rdma_clk_enable(struct device *dev)
+{
+	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
+
+	clk_prepare_enable(rdma->clk);
+	return 0;
+}
+
+void mtk_mdp_rdma_clk_disable(struct device *dev)
+{
+	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(rdma->clk);
+}
+
+static int mtk_mdp_rdma_bind(struct device *dev, struct device *master,
+			     void *data)
+{
+	return 0;
+}
+
+static void mtk_mdp_rdma_unbind(struct device *dev, struct device *master,
+				void *data)
+{
+}
+
+static const struct component_ops mtk_mdp_rdma_component_ops = {
+	.bind	= mtk_mdp_rdma_bind,
+	.unbind = mtk_mdp_rdma_unbind,
+};
+
+static int mtk_mdp_rdma_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_mdp_rdma *priv;
+	int ret = 0;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap rdma\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get rdma clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+	platform_set_drvdata(pdev, priv);
+
+	pm_runtime_enable(dev);
+
+	ret = component_add(dev, &mtk_mdp_rdma_component_ops);
+	if (ret != 0) {
+		pm_runtime_disable(dev);
+		dev_err(dev, "Failed to add component: %d\n", ret);
+	}
+	return ret;
+}
+
+static int mtk_mdp_rdma_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_mdp_rdma_component_ops);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-vdo1-rdma", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match);
+
+struct platform_driver mtk_mdp_rdma_driver = {
+	.probe = mtk_mdp_rdma_probe,
+	.remove = mtk_mdp_rdma_remove,
+	.driver = {
+		.name = "mediatek-mdp-rdma",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_mdp_rdma_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
new file mode 100644
index 000000000000..9943ee3aac31
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_MDP_RDMA_H__
+#define __MTK_MDP_RDMA_H__
+
+struct mtk_mdp_rdma_cfg {
+	unsigned int	pitch;
+	unsigned int	addr0;
+	unsigned int	width;
+	unsigned int	height;
+	unsigned int	x_left;
+	unsigned int	y_top;
+	int		fmt;
+	int		color_encoding;
+};
+
+#endif // __MTK_MDP_RDMA_H__
-- 
2.18.0



From krzk at kernel.org  Mon Jan 10 00:47:37 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 09:47:37 +0100
Subject: [PATCH v1 14/14] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <20220107180314.1816515-15-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-15-marcel@ziswiler.com>
Message-ID: <c80ac4a7-d401-00c3-c6c2-61bc9a600590@kernel.org>

On 07/01/2022 19:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> This patch adds the device tree to support Toradex Verdin iMX8M Mini a
> computer on module which can be used on different carrier boards.
> 
> The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
> Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
> 1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
> RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
> Wi-Fi module.
> 
> Anything that is not self-contained on the module is disabled by
> default.
> 
> The device tree for the Dahlia includes the module's device tree and
> enables the supported peripherals of the carrier board.
> 
> The device tree for the Verdin Development Board includes the module's
> device tree as well as the Dahlia one as it is a superset and supports
> almost all peripherals available.
> 
> So far there is no display functionality supported at all but basic
> console UART, USB host, eMMC and Ethernet and PCIe functionality work
> fine.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
>  arch/arm64/boot/dts/freescale/Makefile        |    4 +
>  .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  143 ++
>  .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
>  .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
>  .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
>  .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
>  .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
>  .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
>  .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
>  .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1277 +++++++++++++++++
>  10 files changed, 1733 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
> 

(...)

> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
> new file mode 100644
> index 000000000000..23eb695a5266
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
> @@ -0,0 +1,1277 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> +/*
> + * Copyright 2022 Toradex
> + */
> +
> +#include "dt-bindings/pwm/pwm.h"
> +#include "imx8mm.dtsi"
> +
> +/ {
> +	chosen {
> +		bootargs = "console=ttymxc0,115200 earlycon";

earlycon is a debug tool, so should not be part of mainline DTS by
default. Entire bootargs property looks actually not needed.

> +		stdout-path = &uart1;
> +	};
> +

(...)

> +/* Verdin ETH_1 (On-module PHY) */
> +&fec1 {
> +	fsl,magic-packet;
> +	phy-handle = <&ethphy0>;
> +	phy-mode = "rgmii-id";
> +	phy-supply = <&reg_ethphy>;
> +	pinctrl-names = "default", "sleep";
> +	pinctrl-0 = <&pinctrl_fec1>;
> +	pinctrl-1 = <&pinctrl_fec1_sleep>;
> +
> +	mdio {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		ethphy0: ethernet-phy at 7 {
> +			compatible = "ethernet-phy-ieee802.3-c22";
> +			interrupt-parent = <&gpio1>;
> +			interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
> +			micrel,led-mode = <0>;
> +			reg = <7>;
> +		};
> +	};
> +};
> +
> +/* Verdin QSPI_1 */
> +&flexspi {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_flexspi0>;
> +#if 0

Please drop it or explain with a comment why we need dead code in Linux
kernel.

> +	flash at 0 {
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		compatible = "jedec,spi-nor";
> +		reg = <0>;
> +		spi-max-frequency = <80000000>;
> +	};
> +#endif
> +};
> +


Best regards,
Krzysztof


From guodong.liu at mediatek.com  Mon Jan 10 00:48:40 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Mon, 10 Jan 2022 16:48:40 +0800
Subject: [PATCH v1 1/2] dt-bindings: iio: adc: Add compatible for Mediatek
 MT8186
Message-ID: <20220110084841.575-1-guodong.liu@mediatek.com>

This commit adds dt-binding documentation of auxadc for Mediatek MT8186 SoC
Platform.

Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
---
 .../devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml      | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
index b939f9652e3a..65581ad4b816 100644
--- a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
@@ -34,6 +34,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8183-auxadc
+              - mediatek,mt8186-auxadc
               - mediatek,mt8195-auxadc
               - mediatek,mt8516-auxadc
           - const: mediatek,mt8173-auxadc
-- 
2.25.1



From yu.tu at amlogic.com  Mon Jan 10 00:54:39 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:54:39 +0800
Subject: [PATCH 1/2] dt-bindings: serial: meson: Drop compatible =
 amlogic,meson-gx-uart.
In-Reply-To: <20220110082616.13474-1-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
Message-ID: <f16843d4-c3c7-9b24-e262-3ca5472e07a7@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Deprecated, don't use anymore because compatible =
> amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
> and G12A which have different revisions of the UART IP.
> So it's split into GXBB, GXL and G12A.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> index 72e8868db3e0..ad9f1f4537a0 100644
> --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> @@ -28,7 +28,10 @@ properties:
>                 - amlogic,meson6-uart
>                 - amlogic,meson8-uart
>                 - amlogic,meson8b-uart
> -              - amlogic,meson-gx-uart
> +              - amlogic,meson-gx-uart # deprecated, use revision specific property below
> +              - amlogic,meson-gxbb-uart
> +              - amlogic,meson-gxl-uart
> +              - amlogic,meson-g12a-uart
>                 - amlogic,meson-s4-uart
>             - const: amlogic,meson-ao-uart
>         - description: Everything-Else power domain UART controller
> @@ -36,7 +39,10 @@ properties:
>             - amlogic,meson6-uart
>             - amlogic,meson8-uart
>             - amlogic,meson8b-uart
> -          - amlogic,meson-gx-uart
> +          - amlogic,meson-gx-uart # deprecated, use revision specific property below
> +          - amlogic,meson-gxbb-uart
> +          - amlogic,meson-gxl-uart
> +          - amlogic,meson-g12a-uart
>             - amlogic,meson-s4-uart
>   
>     reg:
> 
> base-commit: 99a507a8ea28542ec196e2dd80096708e2482735


From yu.tu at amlogic.com  Mon Jan 10 00:54:57 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:54:57 +0800
Subject: [PATCH] tty: serial: meson: Change request_irq to
 devm_request_irq and move devm_request_irq to meson_uart_probe()
In-Reply-To: <20220110082616.13474-2-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-2-yu.tu@amlogic.com>
Message-ID: <79e4a4d1-eefd-9fa2-d365-192f28f4c9c8@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Because an interrupt error occurs when the user opens /dev/ttyAML* but
> don't close it, and then opens the same port again. This problem is
> encountered in actual projects.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 16 +++++++++-------
>   1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 45e41f20cba3..0dd3f5b35768 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -135,8 +135,6 @@ static void meson_uart_shutdown(struct uart_port *port)
>   	unsigned long flags;
>   	u32 val;
>   
> -	free_irq(port->irq, port);
> -
>   	spin_lock_irqsave(&port->lock, flags);
>   
>   	val = readl(port->membase + AML_UART_CONTROL);
> @@ -284,7 +282,6 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret;
>   
>   	meson_uart_reset(port);
>   
> @@ -298,10 +295,7 @@ static int meson_uart_startup(struct uart_port *port)
>   	val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
>   	writel(val, port->membase + AML_UART_MISC);
>   
> -	ret = request_irq(port->irq, meson_uart_interrupt, 0,
> -			  port->name, port);
> -
> -	return ret;
> +	return 0;
>   }
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
> @@ -908,6 +902,14 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	meson_ports[pdev->id] = port;
>   	platform_set_drvdata(pdev, port);
>   
> +	ret = devm_request_irq(&pdev->dev, port->irq, meson_uart_interrupt,
> +			       0, dev_name(&pdev->dev), port);
> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to request uart irq: %d\n",
> +			ret);
> +		return ret;
> +	}
> +
>   	/* reset port before registering (and possibly registering console) */
>   	meson_uart_reset(port);
>   
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
> prerequisite-patch-id: 7af8c81b4c2163240725e96625b1487c280f4f30
> prerequisite-patch-id: 8791f6362b14e7c4ff4f85cce550f06abeb1af7a


From yu.tu at amlogic.com  Mon Jan 10 00:55:05 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:05 +0800
Subject: [PATCH] tty: serial: meson: Make the bit24 and bit [26, 27] of the
 UART_REG5 register writable
In-Reply-To: <20220110082616.13474-3-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-3-yu.tu@amlogic.com>
Message-ID: <b553aea7-cb78-830a-4a4c-51d2ee2a1850@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> The UART_REG5 register defaults to 0. The console port is set in
> ROMCODE. But other UART ports default to 0, so make bit24 and
> bit[26,27] writable so that the UART can choose a more
> appropriate clock.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7c3f30cea68e..b0551750dff8 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>   							CLK_SET_RATE_NO_REPARENT,
>   							port->membase + AML_UART_REG5,
>   							26, 2,
> -							CLK_DIVIDER_READ_ONLY,
> +							CLK_DIVIDER_ROUND_CLOSEST,
>   							xtal_div_table, NULL);
>   		if (IS_ERR(hw))
>   			return PTR_ERR(hw);
> @@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>   					CLK_SET_RATE_PARENT,
>   					port->membase + AML_UART_REG5,
>   					24, 0x1,
> -					CLK_MUX_READ_ONLY,
> +					CLK_MUX_ROUND_CLOSEST,
>   					NULL, NULL);
>   	if (IS_ERR(hw))
>   		return PTR_ERR(hw);
> 
> base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
> prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: 4e4d909acabcb7533da20e2207207be73454a88c


From yu.tu at amlogic.com  Mon Jan 10 00:55:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:14 +0800
Subject: [PATCH] tty: serial: meson: meson_uart_shutdown omit clear
 AML_UART_TX_EN bit
In-Reply-To: <20220110082616.13474-4-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-4-yu.tu@amlogic.com>
Message-ID: <f16770c3-fc9c-3353-8b5c-5f3029cda240@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> This change is an improvement. The meson_uart_shutdown function
> should have the opposite operation to the meson_uart_startup
> function, but the meson_uart_shutdown of AML_UART_TX_EN is logically
> missing.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 9b07e3534969..c17109d6d441 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -140,7 +140,7 @@ static void meson_uart_shutdown(struct uart_port *port)
>   	spin_lock_irqsave(&port->lock, flags);
>   
>   	val = readl(port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_RX_EN;
> +	val &= ~(AML_UART_RX_EN | AML_UART_TX_EN);
>   	val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f
> prerequisite-patch-id: af9e3acc8f6ff7602d3a68a57c008e5ec362b353
> prerequisite-patch-id: a44e5da7009d9b815eb87395cbd7d14e7d953a09


From yu.tu at amlogic.com  Mon Jan 10 00:55:21 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:21 +0800
Subject: [PATCH] tty: serial: meson: Request the register region in
 meson_uart_probe()
In-Reply-To: <20220110082616.13474-5-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-5-yu.tu@amlogic.com>
Message-ID: <936e828c-15e0-5223-7daa-94b2fafc2602@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> This simplifies resetting the UART controller during probe and will make
> it easier to integrate the common clock code which will require the
> registers at probe time as well.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>   1 file changed, 6 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index c9a37602ffd0..99efe62a1507 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -397,24 +397,11 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	devm_iounmap(port->dev, port->membase);
> -	port->membase = NULL;
> -	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
> +	/* nothing to do */
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> -	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
> -				     dev_name(port->dev))) {
> -		dev_err(port->dev, "Memory region busy\n");
> -		return -EBUSY;
> -	}
> -
> -	port->membase = devm_ioremap(port->dev, port->mapbase,
> -					     port->mapsize);
> -	if (!port->membase)
> -		return -ENOMEM;
> -
>   	return 0;
>   }
>   
> @@ -728,6 +715,10 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	if (!port)
>   		return -ENOMEM;
>   
> +	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
> +	if (IS_ERR(port->membase))
> +		return PTR_ERR(port->membase);
> +
>   	ret = meson_uart_probe_clocks(pdev, port);
>   	if (ret)
>   		return ret;
> @@ -749,10 +740,7 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	platform_set_drvdata(pdev, port);
>   
>   	/* reset port before registering (and possibly registering console) */
> -	if (meson_uart_request_port(port) >= 0) {
> -		meson_uart_reset(port);
> -		meson_uart_release_port(port);
> -	}
> +	meson_uart_reset(port);
>   
>   	ret = uart_add_one_port(&meson_uart_driver, port);
>   	if (ret)
> 
> base-commit: b3a9e3b9622ae10064826dccb4f7a52bd88c7407
> prerequisite-patch-id: 97a514f3447511cb204179ce03ae99dc1d5902d9


From yu.tu at amlogic.com  Mon Jan 10 00:55:33 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:33 +0800
Subject: [PATCH 1/2] tty: serial: meson: The UART baud rate calculation is
 described using the common clock code.
In-Reply-To: <20220110082616.13474-6-yu.tu@amlogic.com>
References: <20220110082616.13474-1-yu.tu@amlogic.com>
 <20220110082616.13474-6-yu.tu@amlogic.com>
Message-ID: <84c9dc1e-c514-cd34-60c6-7973ade7883d@amlogic.com>

Hi All,
	I'm really sorry for sending the wrong specified file. Please ignore 
the email. I will resend V4.

On 2022/1/10 16:26, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>   1 file changed, 163 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>   #include <linux/console.h>
>   #include <linux/delay.h>
>   #include <linux/init.h>
> @@ -65,9 +66,7 @@
>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>   
>   /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>   #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>   
>   #define AML_UART_PORT_NUM		12
>   #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>   #define AML_UART_POLL_USEC		5
>   #define AML_UART_TIMEOUT_USEC		10000
>   
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>   static struct uart_driver meson_uart_driver;
>   
>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret = 0;
> +	int ret;
>   
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>   
> +	val = readl(port->membase + AML_UART_CONTROL);
>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
>   	u32 val;
>   
>   	while (!meson_uart_tx_empty(port))
>   		cpu_relax();
>   
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>   	val |= AML_UART_BAUD_USE;
>   	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>   }
>   
>   static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})
> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },
> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>   {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>   
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>   
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>   	}
>   
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>   	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}
>   
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>   
>   	return 0;
>   }
>   
>   static int meson_uart_probe(struct platform_device *pdev)
>   {
> +	struct meson_uart_data *private_data;
>   	struct resource *res_mem;
>   	struct uart_port *port;
>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>   		return -EBUSY;
>   	}
>   
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>   		return -ENOMEM;
>   
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
> +
> +	port = &private_data->port;
> +
>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>   	if (IS_ERR(port->membase))
>   		return PTR_ERR(port->membase);
>   
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>   	port->iotype = UPIO_MEM;
>   	port->mapbase = res_mem->start;
>   	port->mapsize = resource_size(res_mem);
> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	port->x_char = 0;
>   	port->ops = &meson_uart_ops;
>   	port->fifosize = fifosize;
> +	port->private_data = private_data;
>   
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>   	meson_ports[pdev->id] = port;
>   	platform_set_drvdata(pdev, port);
>   
> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>   }
>   
>   static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB, GXL and G12A which have different revisions
> +	 * of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>   	{ /* sentinel */ },
>   };
>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 
> base-commit: 93a770b7e16772530196674ffc79bb13fa927dc6
> prerequisite-patch-id: 95191c926509964c8e9bf4128b8bbad8a277b84a
> prerequisite-patch-id: a2e4756ff85f0df0efe111d7e2cb51b8e26e226f


From yu.tu at amlogic.com  Mon Jan 10 00:55:59 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:55:59 +0800
Subject: [PATCH V4 0/5] the UART driver compatible with
Message-ID: <20220110085604.18042-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
  tty: serial: meson: Request the register region in meson_uart_probe()
  tty: serial: meson: The UART baud rate calculation is described using
    the common clock code.
  tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
    register writable
  tty: serial: meson: Added S4 SOC compatibility.

V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.

Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/

 .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
 drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
 2 files changed, 177 insertions(+), 77 deletions(-)

-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:00 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:00 +0800
Subject: [PATCH V4 1/5] dt-bindings: serial: meson: Drop
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-2-yu.tu@amlogic.com>

Deprecated, don't use anymore because compatible =
amlogic,meson-gx-uart. Don't differentiate between GXBB, GXL
and G12A which have different revisions of the UART IP.
So it's split into GXBB, GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:01 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:01 +0800
Subject: [PATCH V4 2/5] tty: serial: meson: Request the register
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-3-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe and
will make it easier to integrate the common clock code which
will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From guodong.liu at mediatek.com  Mon Jan 10 00:48:41 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Mon, 10 Jan 2022 16:48:41 +0800
Subject: [PATCH v1 2/2] iio: adc: mt8186: Add compatible node for mt8186
In-Reply-To: <20220110084841.575-1-guodong.liu@mediatek.com>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
Message-ID: <20220110084841.575-2-guodong.liu@mediatek.com>

This commit adds mt8186 compatible node.

Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
---
 drivers/iio/adc/mt6577_auxadc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
index d4fccd52ef08..fb08d761589a 100644
--- a/drivers/iio/adc/mt6577_auxadc.c
+++ b/drivers/iio/adc/mt6577_auxadc.c
@@ -46,6 +46,11 @@ struct mt6577_auxadc_device {
 	const struct mtk_auxadc_compatible *dev_comp;
 };
 
+static const struct mtk_auxadc_compatible mt8186_compat = {
+	.sample_data_cali = false,
+	.check_global_idle = false,
+};
+
 static const struct mtk_auxadc_compatible mt8173_compat = {
 	.sample_data_cali = false,
 	.check_global_idle = true,
@@ -334,6 +339,7 @@ static const struct of_device_id mt6577_auxadc_of_match[] = {
 	{ .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat},
 	{ .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat},
 	{ .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat},
+	{ .compatible = "mediatek,mt8186-auxadc", .data = &mt8186_compat},
 	{ .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat},
 	{ }
 };
-- 
2.25.1



From yu.tu at amlogic.com  Mon Jan 10 00:56:02 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:02 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From nancy.lin at mediatek.com  Mon Jan 10 00:46:44 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:44 +0800
Subject: [PATCH v11 21/22] drm/mediatek: add mediatek-drm of vdosys1 support
 for MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-22-nancy.lin@mediatek.com>

Add driver data of mt8195 vdosys1 to mediatek-drm.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 36430f956b4f..e851c56f00b1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -190,6 +190,14 @@ static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
 	DDP_COMPONENT_DP_INTF0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
+	DDP_COMPONENT_OVL_ADAPTOR,
+	DDP_COMPONENT_MERGE5,
+	DDP_COMPONENT_DP_INTF1,
+};
+
+static const int mt8195_vdosys1_mtk_cmdq_mbox[] = {-1, 0, -1};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -254,6 +262,14 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.mmsys_dev_num = 2,
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
+	.ext_path = mt8195_mtk_ddp_ext,
+	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
+	.mmsys_id = 1,
+	.mmsys_dev_num = 2,
+	.mbox_index = mt8195_vdosys1_mtk_cmdq_mbox,
+};
+
 static const struct of_device_id mtk_drm_of_ids[] = {
 	{ .compatible = "mediatek,mt2701-mmsys",
 	  .data = &mt2701_mmsys_driver_data},
@@ -271,6 +287,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8192_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8195-vdosys0",
 	  .data = &mt8195_vdosys0_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys1",
+	  .data = &mt8195_vdosys1_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0



From yu.tu at amlogic.com  Mon Jan 10 00:56:03 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:03 +0800
Subject: [PATCH V4 4/5] tty: serial: meson: Make the bit24 and
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 1004fd0b0c9e..fd128878e91a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From nancy.lin at mediatek.com  Mon Jan 10 00:46:33 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:33 +0800
Subject: [PATCH v11 10/22] soc: mediatek: add mtk-mutex support for mt8195
 vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-11-nancy.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys1.
The vdosys1 path component contains ovl_adaptor, merge5,
and dp_intf1. Ovl_adaptor is composed of several sub-elements.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 54 ++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index ff2f74668e8a..7767fedbd14f 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -112,6 +112,35 @@
 #define MT8195_MUTEX_MOD_DISP_PWM0		BIT(27)
 #define MT8195_MUTEX_MOD_DISP_PWM1		BIT(28)
 
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA0	BIT(0)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA1	BIT(1)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA2	BIT(2)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA3	BIT(3)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA4	BIT(4)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA5	BIT(5)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA6	BIT(6)
+#define MT8195_MUTEX_MOD_DISP1_MDP_RDMA7	BIT(7)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE0	BIT(8)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE1	BIT(9)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE2	BIT(10)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE3	BIT(11)
+#define MT8195_MUTEX_MOD_DISP1_VPP_MERGE4	BIT(12)
+#define MT8195_MUTEX_MOD_DISP1_VPP2_DL_RELAY	BIT(13)
+#define MT8195_MUTEX_MOD_DISP1_VPP3_DL_RELAY	BIT(14)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_DSC_DL_ASYNC	BIT(15)
+#define MT8195_MUTEX_MOD_DISP1_VDO0_MERGE_DL_ASYNC	BIT(16)
+#define MT8195_MUTEX_MOD_DISP1_VDO1_OUT_DL_RELAY	BIT(17)
+#define MT8195_MUTEX_MOD_DISP1_DISP_MIXER	BIT(18)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0	BIT(19)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1	BIT(20)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0	BIT(21)
+#define MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1	BIT(22)
+#define MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0	BIT(23)
+#define MT8195_MUTEX_MOD_DISP1_HDR_MLOAD	BIT(24)
+#define MT8195_MUTEX_MOD_DISP1_DPI0		BIT(25)
+#define MT8195_MUTEX_MOD_DISP1_DPI1		BIT(26)
+#define MT8195_MUTEX_MOD_DISP1_DP_INTF0		BIT(27)
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		BIT(10)
 #define MT2712_MUTEX_MOD_DISP_OVL0		BIT(11)
 #define MT2712_MUTEX_MOD_DISP_OVL1		BIT(12)
@@ -302,6 +331,27 @@ static const unsigned long mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
 	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
 	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+	[DDP_COMPONENT_OVL_ADAPTOR] = MT8195_MUTEX_MOD_DISP1_MDP_RDMA0 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA1 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA2 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA3 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA4 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA5 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA6 |
+				      MT8195_MUTEX_MOD_DISP1_MDP_RDMA7 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE0 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE1 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE2 |
+				      MT8195_MUTEX_MOD_DISP1_VPP_MERGE3 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_GFX_FE1 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_VDO_BE0 |
+				      MT8195_MUTEX_MOD_DISP1_HDR_MLOAD |
+				      MT8195_MUTEX_MOD_DISP1_DISP_MIXER,
+	[DDP_COMPONENT_MERGE5] = MT8195_MUTEX_MOD_DISP1_VPP_MERGE4,
+	[DDP_COMPONENT_DP_INTF1] = MT8195_MUTEX_MOD_DISP1_DP_INTF0,
 };
 
 static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
@@ -466,6 +516,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DP_INTF0:
 		sof_id = MUTEX_SOF_DP_INTF0;
 		break;
+	case DDP_COMPONENT_DP_INTF1:
+		sof_id = MUTEX_SOF_DP_INTF1;
+		break;
 	default:
 		if (mtx->data->mutex_mod[id] <= BIT(31)) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -506,6 +559,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
 	case DDP_COMPONENT_DP_INTF0:
+	case DDP_COMPONENT_DP_INTF1:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:40 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:40 +0800
Subject: [PATCH v11 17/22] drm/mediatek: add mediatek-drm plane color encoding
 info
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-18-nancy.lin@mediatek.com>

Add plane color encoding information for color space conversion.
It's a preparation for adding support for mt8195 ovl_adaptor mdp_rdma
csc control.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 1 +
 drivers/gpu/drm/mediatek/mtk_drm_plane.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index 734a1fb052df..81bd5d6e8df5 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -137,6 +137,7 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state,
 	mtk_plane_state->pending.width = drm_rect_width(&new_state->dst);
 	mtk_plane_state->pending.height = drm_rect_height(&new_state->dst);
 	mtk_plane_state->pending.rotation = new_state->rotation;
+	mtk_plane_state->pending.color_encoding = new_state->color_encoding;
 }
 
 static void mtk_plane_atomic_async_update(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.h b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
index d454bece9535..2d5ec66e3df1 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.h
@@ -24,6 +24,7 @@ struct mtk_plane_pending_state {
 	bool				dirty;
 	bool				async_dirty;
 	bool				async_config;
+	enum drm_color_encoding		color_encoding;
 };
 
 struct mtk_plane_state {
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:35 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:35 +0800
Subject: [PATCH v11 12/22] drm/mediatek: add display merge advance config API
 for MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-13-nancy.lin@mediatek.com>

Add merge new advance config API. The original merge API is
mtk_ddp_comp_funcs function prototype. The API interface parameters
cannot be modified, so add a new config API for extension. This is
the preparation for ovl_adaptor merge control.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  3 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 52 ++++++++++++++++++++---
 2 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index b3a372cab0bd..c2de53a5892e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -63,6 +63,9 @@ void mtk_merge_config(struct device *dev, unsigned int width,
 		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
 void mtk_merge_start(struct device *dev);
 void mtk_merge_stop(struct device *dev);
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w,
+			      unsigned int h, unsigned int vrefresh, unsigned int bpc,
+			      struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 45face638153..40da0555416d 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -17,6 +17,7 @@
 #define DISP_REG_MERGE_CTRL		0x000
 #define MERGE_EN				1
 #define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_1		0x014
 #define DISP_REG_MERGE_CFG_4		0x020
 #define DISP_REG_MERGE_CFG_10		0x038
 /* no swap */
@@ -25,9 +26,12 @@
 #define DISP_REG_MERGE_CFG_12		0x040
 #define CFG_10_10_1PI_2PO_BUF_MODE		6
 #define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define CFG_11_10_1PI_2PO_MERGE			18
 #define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
 #define DISP_REG_MERGE_CFG_24		0x070
 #define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_26		0x078
+#define DISP_REG_MERGE_CFG_27		0x07c
 #define DISP_REG_MERGE_CFG_36		0x0a0
 #define ULTRA_EN				BIT(0)
 #define PREULTRA_EN				BIT(4)
@@ -98,12 +102,19 @@ static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
 void mtk_merge_config(struct device *dev, unsigned int w,
 		      unsigned int h, unsigned int vrefresh,
 		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_merge_advance_config(dev, w, 0, h, vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w,
+			      unsigned int h, unsigned int vrefresh, unsigned int bpc,
+			      struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
 
-	if (!h || !w) {
-		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+	if (!h || !l_w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, l_w, h);
 		return;
 	}
 
@@ -112,14 +123,41 @@ void mtk_merge_config(struct device *dev, unsigned int w,
 		mode = CFG_10_10_2PI_2PO_BUF_MODE;
 	}
 
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	if (r_w)
+		mode = CFG_11_10_1PI_2PO_MERGE;
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_0);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_1);
+	mtk_ddp_write(cmdq_pkt, h << 16 | (l_w + r_w), &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_4);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+	/*
+	 * DISP_REG_MERGE_CFG_24 is merge SRAM0 w/h
+	 * DISP_REG_MERGE_CFG_25 is merge SRAM1 w/h.
+	 * If r_w > 0, the merge is in merge mode (input0 and input1 merge together),
+	 * the input0 goes to SRAM0, and input1 goes to SRAM1.
+	 * If r_w = 0, the merge is in buffer mode, the input goes through SRAM0 and
+	 * then to SRAM1. Both SRAM0 and SRAM1 are set to the same size.
+	 */
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CFG_24);
-	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
-		      DISP_REG_MERGE_CFG_25);
+	if (r_w)
+		mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_CFG_25);
+	else
+		mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_CFG_25);
+
+	/*
+	 * DISP_REG_MERGE_CFG_26 and DISP_REG_MERGE_CFG_27 is only used in LR merge.
+	 * Only take effect when the merge is setting to merge mode.
+	 */
+	mtk_ddp_write(cmdq_pkt, h << 16 | l_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_26);
+	mtk_ddp_write(cmdq_pkt, h << 16 | r_w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_27);
+
 	mtk_ddp_write_mask(cmdq_pkt, SWAP_MODE, &priv->cmdq_reg, priv->regs,
 			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
 	mtk_ddp_write_mask(cmdq_pkt, mode, &priv->cmdq_reg, priv->regs,
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:37 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:37 +0800
Subject: [PATCH v11 14/22] drm/mediatek: add display merge mute/unmute support
 for MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-15-nancy.lin@mediatek.com>

Add merge mute/unmute setting for MT8195.
MT8195 Vdosys1 merge1~merge4 support HW mute function.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index c0d9b43b2a66..9dca145cfb71 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -58,12 +58,15 @@
 #define FLD_PREULTRA_TH_LOW			GENMASK(15, 0)
 #define FLD_PREULTRA_TH_HIGH			GENMASK(31, 16)
 
+#define DISP_REG_MERGE_MUTE_0		0xf00
+
 struct mtk_disp_merge {
 	void __iomem			*regs;
 	struct clk			*clk;
 	struct clk			*async_clk;
 	struct cmdq_client_reg		cmdq_reg;
 	bool				fifo_en;
+	bool				mute_support;
 };
 
 void mtk_merge_start(struct device *dev)
@@ -82,6 +85,10 @@ void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+	if (priv->mute_support)
+		mtk_ddp_write(cmdq_pkt, 0x0, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_MUTE_0);
+
 	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CTRL);
 }
@@ -90,6 +97,10 @@ void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
+	if (priv->mute_support)
+		mtk_ddp_write(cmdq_pkt, 0x1, &priv->cmdq_reg, priv->regs,
+			      DISP_REG_MERGE_MUTE_0);
+
 	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
 		      DISP_REG_MERGE_CTRL);
 }
@@ -264,6 +275,8 @@ static int mtk_disp_merge_probe(struct platform_device *pdev)
 	priv->fifo_en = of_property_read_bool(dev->of_node,
 					      "mediatek,merge-fifo-en");
 
+	priv->mute_support = of_property_read_bool(dev->of_node,
+						   "mediatek,merge-mute");
 	platform_set_drvdata(pdev, priv);
 
 	ret = component_add(dev, &mtk_disp_merge_component_ops);
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:42 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:42 +0800
Subject: [PATCH v11 19/22] drm/mediatek: modify mediatek-drm for mt8195 multi
 mmsys support
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-20-nancy.lin@mediatek.com>

MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support.
The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers,
only one drm driver register as the drm device.
Each drm driver binds its own component. The last bind drm driver
allocates and registers the drm device to drm core.
Each crtc path is created with the corresponding drm driver data.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c |  24 +-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.h |   3 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  | 300 ++++++++++++++++++------
 drivers/gpu/drm/mediatek/mtk_drm_drv.h  |  10 +-
 4 files changed, 246 insertions(+), 91 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index d661edf7e0fe..fe2871aca859 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -847,21 +847,28 @@ static int mtk_drm_crtc_init_comp_planes(struct drm_device *drm_dev,
 }
 
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
-			const enum mtk_ddp_comp_id *path, unsigned int path_len)
+			const enum mtk_ddp_comp_id *path, unsigned int path_len,
+			int priv_data_index)
 {
 	struct mtk_drm_private *priv = drm_dev->dev_private;
 	struct device *dev = drm_dev->dev;
 	struct mtk_drm_crtc *mtk_crtc;
 	unsigned int num_comp_planes = 0;
-	int pipe = priv->num_pipes;
 	int ret;
 	int i;
 	bool has_ctm = false;
 	uint gamma_lut_size = 0;
+	struct drm_crtc *tmp;
+	int crtc_i = 0;
 
 	if (!path)
 		return 0;
 
+	priv = priv->all_drm_private[priv_data_index];
+
+	drm_for_each_crtc(tmp, drm_dev)
+		crtc_i++;
+
 	for (i = 0; i < path_len; i++) {
 		enum mtk_ddp_comp_id comp_id = path[i];
 		struct device_node *node;
@@ -873,7 +880,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		if (!node) {
 			dev_info(dev,
 				 "Not creating crtc %d because component %d is disabled or missing\n",
-				 pipe, comp_id);
+				 crtc_i, comp_id);
 			return 0;
 		}
 
@@ -926,29 +933,28 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
 		ret = mtk_drm_crtc_init_comp_planes(drm_dev, mtk_crtc, i,
-						    pipe);
+						    crtc_i);
 		if (ret)
 			return ret;
 	}
 
-	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, pipe);
+	ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, crtc_i);
 	if (ret < 0)
 		return ret;
 
 	if (gamma_lut_size)
 		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
 	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
-	priv->num_pipes++;
 	mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	i = (priv->data->mbox_index) ? priv->data->mbox_index[drm_crtc_index(&mtk_crtc->base)] : 0;
 	mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
 	mtk_crtc->cmdq_client.client.tx_block = false;
 	mtk_crtc->cmdq_client.client.knows_txdone = true;
 	mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
 	mtk_crtc->cmdq_client.chan =
-			mbox_request_channel(&mtk_crtc->cmdq_client.client,
-					     drm_crtc_index(&mtk_crtc->base));
+			mbox_request_channel(&mtk_crtc->cmdq_client.client, i);
 	if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
 		dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
 			drm_crtc_index(&mtk_crtc->base));
@@ -958,7 +964,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	if (mtk_crtc->cmdq_client.chan) {
 		ret = of_property_read_u32_index(priv->mutex_node,
 						 "mediatek,gce-events",
-						 drm_crtc_index(&mtk_crtc->base),
+						 i,
 						 &mtk_crtc->cmdq_event);
 		if (ret) {
 			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
index cb9a36c48d4f..a57eb12d7c05 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.h
@@ -17,7 +17,8 @@
 void mtk_drm_crtc_commit(struct drm_crtc *crtc);
 int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			const enum mtk_ddp_comp_id *path,
-			unsigned int path_len);
+			unsigned int path_len,
+			int priv_data_index);
 int mtk_drm_crtc_plane_check(struct drm_crtc *crtc, struct drm_plane *plane,
 			     struct mtk_plane_state *state);
 void mtk_drm_crtc_async_update(struct drm_crtc *crtc, struct drm_plane *plane,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 390cda4bae57..a05703843af2 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -196,6 +196,7 @@ static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.ext_path = mt2701_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt2701_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
@@ -204,6 +205,7 @@ static const struct mtk_mmsys_driver_data mt7623_mmsys_driver_data = {
 	.ext_path = mt7623_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt7623_mtk_ddp_ext),
 	.shadow_register = true,
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
@@ -213,11 +215,13 @@ static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt2712_mtk_ddp_ext),
 	.third_path = mt2712_mtk_ddp_third,
 	.third_len = ARRAY_SIZE(mt2712_mtk_ddp_third),
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
 	.main_path = mt8167_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8167_mtk_ddp_main),
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
@@ -225,6 +229,7 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8173_mtk_ddp_main),
 	.ext_path = mt8173_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8173_mtk_ddp_ext),
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
@@ -232,6 +237,7 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8183_mtk_ddp_main),
 	.ext_path = mt8183_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -239,32 +245,116 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
 	.ext_path = mt8192_mtk_ddp_ext,
 	.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
+	.mmsys_dev_num = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
 	.main_path = mt8195_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+	.mmsys_dev_num = 2,
 };
 
+static const struct of_device_id mtk_drm_of_ids[] = {
+	{ .compatible = "mediatek,mt2701-mmsys",
+	  .data = &mt2701_mmsys_driver_data},
+	{ .compatible = "mediatek,mt7623-mmsys",
+	  .data = &mt7623_mmsys_driver_data},
+	{ .compatible = "mediatek,mt2712-mmsys",
+	  .data = &mt2712_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8167-mmsys",
+	  .data = &mt8167_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8173-mmsys",
+	  .data = &mt8173_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8183-mmsys",
+	  .data = &mt8183_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8192-mmsys",
+	  .data = &mt8192_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
+
+static int mtk_drm_match(struct device *dev, void *data)
+{
+	if (!strncmp(dev_name(dev), "mediatek-drm", sizeof("mediatek-drm") - 1))
+		return true;
+	return false;
+}
+
+static bool mtk_drm_get_all_drm_priv(struct device *dev)
+{
+	struct mtk_drm_private *drm_priv = dev_get_drvdata(dev);
+	struct mtk_drm_private *all_drm_priv[MAX_CRTC];
+	struct device_node *phandle = dev->parent->of_node;
+	const struct of_device_id *of_id;
+	struct device_node *node;
+	struct device *drm_dev;
+	int cnt = 0;
+	int i, j;
+
+	for_each_child_of_node(phandle->parent, node) {
+		struct platform_device *pdev;
+
+		of_id = of_match_node(mtk_drm_of_ids, node);
+		if (!of_id)
+			continue;
+
+		pdev = of_find_device_by_node(node);
+		if (!pdev)
+			continue;
+
+		drm_dev = device_find_child(&pdev->dev, NULL, mtk_drm_match);
+		if (!drm_dev || !dev_get_drvdata(drm_dev))
+			continue;
+
+		all_drm_priv[cnt] = dev_get_drvdata(drm_dev);
+		if (all_drm_priv[cnt] && all_drm_priv[cnt]->mtk_drm_bound)
+			cnt++;
+	}
+
+	if (drm_priv->data->mmsys_dev_num == cnt) {
+		for (i = 0; i < cnt; i++)
+			for (j = 0; j < cnt; j++)
+				all_drm_priv[j]->all_drm_private[i] = all_drm_priv[i];
+
+		return true;
+	}
+
+	return false;
+}
+
+static bool mtk_drm_find_mmsys_comp(struct mtk_drm_private *private, int comp_id)
+{
+	const struct mtk_mmsys_driver_data *drv_data = private->data;
+	int i;
+
+	if (drv_data->main_path)
+		for (i = 0; i < drv_data->main_len; i++)
+			if (drv_data->main_path[i] == comp_id)
+				return true;
+
+	if (drv_data->ext_path)
+		for (i = 0; i < drv_data->ext_len; i++)
+			if (drv_data->ext_path[i] == comp_id)
+				return true;
+
+	if (drv_data->third_path)
+		for (i = 0; i < drv_data->third_len; i++)
+			if (drv_data->third_path[i] == comp_id)
+				return true;
+
+	return false;
+}
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
+	struct mtk_drm_private *priv_n;
 	struct platform_device *pdev;
-	struct device_node *np;
+	struct device_node *np = NULL;
 	struct device *dma_dev;
-	int ret;
-
-	if (!iommu_present(&platform_bus_type))
-		return -EPROBE_DEFER;
-
-	pdev = of_find_device_by_node(private->mutex_node);
-	if (!pdev) {
-		dev_err(drm->dev, "Waiting for disp-mutex device %pOF\n",
-			private->mutex_node);
-		of_node_put(private->mutex_node);
-		return -EPROBE_DEFER;
-	}
-	private->mutex_dev = &pdev->dev;
+	int ret, i, j;
 
 	ret = drmm_mode_config_init(drm);
 	if (ret)
@@ -283,33 +373,61 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	drm->mode_config.funcs = &mtk_drm_mode_config_funcs;
 	drm->mode_config.helper_private = &mtk_drm_mode_config_helpers;
 
-	ret = component_bind_all(drm->dev, drm);
-	if (ret)
-		goto put_mutex_dev;
+	for (i = 0; i < private->data->mmsys_dev_num; i++) {
+		drm->dev_private = private->all_drm_private[i];
+		ret = component_bind_all(private->all_drm_private[i]->dev, drm);
+		if (ret)
+			goto put_mutex_dev;
+	}
 
 	/*
-	 * We currently support two fixed data streams, each optional,
-	 * and each statically assigned to a crtc:
-	 * OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
+	 * 1. We currently support two fixed data streams, each optional,
+	 *    and each statically assigned to a crtc:
+	 *    OVL0 -> COLOR0 -> AAL -> OD -> RDMA0 -> UFOE -> DSI0 ...
+	 * 2. For multi mmsys architecture, crtc path data are located in
+	 *    different drm private data structures. Loop through crtc index to
+	 *    create crtc from the main path and then ext_path and finally the
+	 *    third path.
+	 * 3. Use OVL device for all DMA memory allocations
 	 */
-	ret = mtk_drm_crtc_create(drm, private->data->main_path,
-				  private->data->main_len);
-	if (ret < 0)
-		goto err_component_unbind;
-	/* ... and OVL1 -> COLOR1 -> GAMMA -> RDMA1 -> DPI0. */
-	ret = mtk_drm_crtc_create(drm, private->data->ext_path,
-				  private->data->ext_len);
-	if (ret < 0)
-		goto err_component_unbind;
-
-	ret = mtk_drm_crtc_create(drm, private->data->third_path,
-				  private->data->third_len);
-	if (ret < 0)
-		goto err_component_unbind;
+	for (i = 0; i < MAX_CRTC; i++) {
+		for (j = 0; j < private->data->mmsys_dev_num; j++) {
+			priv_n = private->all_drm_private[j];
+
+			if (i == 0 && priv_n->data->main_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
+							  priv_n->data->main_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->main_path[0]];
+
+				continue;
+			} else if (i == 1 && priv_n->data->ext_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->ext_path,
+							  priv_n->data->ext_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->ext_path[0]];
+
+				continue;
+			} else if (i == 2 && priv_n->data->third_len) {
+				ret = mtk_drm_crtc_create(drm, priv_n->data->third_path,
+							  priv_n->data->third_len, j);
+				if (ret)
+					goto err_component_unbind;
+
+				if (!np)
+					np = priv_n->comp_node[priv_n->data->third_path[0]];
+
+				continue;
+			}
+		}
+	}
 
-	/* Use OVL device for all DMA memory allocations */
-	np = private->comp_node[private->data->main_path[0]] ?:
-	     private->comp_node[private->data->ext_path[0]];
 	pdev = of_find_device_by_node(np);
 	if (!pdev) {
 		ret = -ENODEV;
@@ -318,7 +436,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	}
 
 	dma_dev = &pdev->dev;
-	private->dma_dev = dma_dev;
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->dma_dev = dma_dev;
 
 	/*
 	 * Configure the DMA segment size to make sure we get contiguous IOVA
@@ -340,9 +459,12 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 	return 0;
 
 err_component_unbind:
-	component_unbind_all(drm->dev, drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		component_unbind_all(private->all_drm_private[i]->dev, drm);
 put_mutex_dev:
-	put_device(private->mutex_dev);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		put_device(private->all_drm_private[i]->mutex_dev);
+
 	return ret;
 }
 
@@ -395,15 +517,36 @@ static int compare_of(struct device *dev, void *data)
 static int mtk_drm_bind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
+	struct platform_device *pdev;
 	struct drm_device *drm;
-	int ret;
+	int ret, i;
+
+	if (!iommu_present(&platform_bus_type))
+		return -EPROBE_DEFER;
+
+	pdev = of_find_device_by_node(private->mutex_node);
+	if (!pdev) {
+		dev_err(dev, "Waiting for disp-mutex device %pOF\n",
+			private->mutex_node);
+		of_node_put(private->mutex_node);
+		return -EPROBE_DEFER;
+	}
+
+	private->mutex_dev = &pdev->dev;
+	private->mtk_drm_bound = true;
+	private->dev = dev;
+
+	if (!mtk_drm_get_all_drm_priv(dev))
+		return 0;
 
 	drm = drm_dev_alloc(&mtk_drm_driver, dev);
 	if (IS_ERR(drm))
 		return PTR_ERR(drm);
 
+	private->drm_master = true;
 	drm->dev_private = private;
-	private->drm = drm;
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->drm = drm;
 
 	ret = mtk_drm_kms_init(drm);
 	if (ret < 0)
@@ -428,10 +571,14 @@ static void mtk_drm_unbind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
 
-	drm_dev_unregister(private->drm);
-	mtk_drm_kms_deinit(private->drm);
-	drm_dev_put(private->drm);
-	private->num_pipes = 0;
+	/* for multi mmsys dev, unregister drm dev in mmsys master */
+	if (private->drm_master) {
+		drm_dev_unregister(private->drm);
+		mtk_drm_kms_deinit(private->drm);
+		drm_dev_put(private->drm);
+	}
+	private->mtk_drm_bound = false;
+	private->drm_master = false;
 	private->drm = NULL;
 }
 
@@ -546,54 +693,40 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	{ }
 };
 
-static const struct of_device_id mtk_drm_of_ids[] = {
-	{ .compatible = "mediatek,mt2701-mmsys",
-	  .data = &mt2701_mmsys_driver_data},
-	{ .compatible = "mediatek,mt7623-mmsys",
-	  .data = &mt7623_mmsys_driver_data},
-	{ .compatible = "mediatek,mt2712-mmsys",
-	  .data = &mt2712_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8167-mmsys",
-	  .data = &mt8167_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8173-mmsys",
-	  .data = &mt8173_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8183-mmsys",
-	  .data = &mt8183_mmsys_driver_data},
-	{ .compatible = "mediatek,mt8192-mmsys",
-	  .data = &mt8192_mmsys_driver_data},
-	{.compatible = "mediatek,mt8195-vdosys0",
-	  .data = &mt8195_vdosys0_driver_data},
-	{ }
-};
-MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-
 static int mtk_drm_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *phandle = dev->parent->of_node;
 	const struct of_device_id *of_id;
+	const struct mtk_mmsys_driver_data *drv_data;
 	struct mtk_drm_private *private;
 	struct device_node *node;
 	struct component_match *match = NULL;
 	int ret;
 	int i;
 
+	of_id = of_match_node(mtk_drm_of_ids, phandle);
+	if (!of_id)
+		return -ENODEV;
+
+	drv_data = of_id->data;
 	private = devm_kzalloc(dev, sizeof(*private), GFP_KERNEL);
 	if (!private)
 		return -ENOMEM;
 
+	private->all_drm_private = devm_kmalloc_array(dev, drv_data->mmsys_dev_num,
+						      sizeof(*private->all_drm_private),
+						      GFP_KERNEL);
+	if (!private->all_drm_private)
+		return -ENOMEM;
+
+	private->data = drv_data;
 	private->mmsys_dev = dev->parent;
 	if (!private->mmsys_dev) {
 		dev_err(dev, "Failed to get MMSYS device\n");
 		return -ENODEV;
 	}
 
-	of_id = of_match_node(mtk_drm_of_ids, phandle);
-	if (!of_id)
-		return -ENODEV;
-
-	private->data = of_id->data;
-
 	/* Iterate over sibling DISP function blocks */
 	for_each_child_of_node(phandle->parent, node) {
 		const struct of_device_id *of_id;
@@ -613,7 +746,13 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		comp_type = (enum mtk_ddp_comp_type)of_id->data;
 
 		if (comp_type == MTK_DISP_MUTEX) {
-			private->mutex_node = of_node_get(node);
+			int id;
+
+			id = of_alias_get_id(node, "mutex");
+			if (id < 0 || id == drv_data->mmsys_id) {
+				private->mutex_node = of_node_get(node);
+				dev_dbg(dev, "get mutex for mmsys %d", drv_data->mmsys_id);
+			}
 			continue;
 		}
 
@@ -624,6 +763,9 @@ static int mtk_drm_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (!mtk_drm_find_mmsys_comp(private, comp_id))
+			continue;
+
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
@@ -701,9 +843,10 @@ static int mtk_drm_sys_suspend(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
 	struct drm_device *drm = private->drm;
-	int ret;
+	int ret = 0;
 
-	ret = drm_mode_config_helper_suspend(drm);
+	if (private->drm_master)
+		ret = drm_mode_config_helper_suspend(drm);
 
 	return ret;
 }
@@ -712,9 +855,10 @@ static int mtk_drm_sys_resume(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
 	struct drm_device *drm = private->drm;
-	int ret;
+	int ret = 0;
 
-	ret = drm_mode_config_helper_resume(drm);
+	if (private->drm_master)
+		ret = drm_mode_config_helper_resume(drm);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index d27561e5e274..c9bcd69168dc 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -29,14 +29,17 @@ struct mtk_mmsys_driver_data {
 	unsigned int third_len;
 
 	bool shadow_register;
+	unsigned int mmsys_id;
+	unsigned int mmsys_dev_num;
+	const int *mbox_index;
 };
 
 struct mtk_drm_private {
 	struct drm_device *drm;
 	struct device *dma_dev;
-
-	unsigned int num_pipes;
-
+	bool mtk_drm_bound;
+	bool drm_master;
+	struct device *dev;
 	struct device_node *mutex_node;
 	struct device *mutex_dev;
 	struct device *mmsys_dev;
@@ -44,6 +47,7 @@ struct mtk_drm_private {
 	struct mtk_ddp_comp ddp_comp[DDP_COMPONENT_ID_MAX];
 	const struct mtk_mmsys_driver_data *data;
 	struct drm_atomic_state *suspend_state;
+	struct mtk_drm_private **all_drm_private;
 };
 
 extern struct platform_driver mtk_disp_aal_driver;
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:43 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:43 +0800
Subject: [PATCH v11 20/22] drm/mediatek: add drm ovl_adaptor sub driver for
 MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-21-nancy.lin@mediatek.com>

Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if
the component exists in the path.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 16 ++++----
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ++++++++++++---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 41 +++++++++++++++------
 4 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index fe2871aca859..62529a954b62 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -877,15 +877,13 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		node = priv->comp_node[comp_id];
 		comp = &priv->ddp_comp[comp_id];
 
-		if (!node) {
-			dev_info(dev,
-				 "Not creating crtc %d because component %d is disabled or missing\n",
-				 crtc_i, comp_id);
-			return 0;
-		}
-
-		if (!comp->dev) {
-			dev_err(dev, "Component %pOF not initialized\n", node);
+		/* Not all drm components have a DTS device node, such as ovl_adaptor,
+		 * which is the drm bring up sub driver
+		 */
+		if (!node && !comp->dev) {
+			dev_err(dev,
+				"Not creating crtc %d because component %d is disabled, missing or not initialized\n",
+				crtc_i, comp_id);
 			return -ENODEV;
 		}
 	}
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 26d197da41c0..ce40bab9c56b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -385,6 +385,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe = {
 	.start = mtk_ufoe_start,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
+	.clk_enable = mtk_ovl_adaptor_clk_enable,
+	.clk_disable = mtk_ovl_adaptor_clk_disable,
+	.config = mtk_ovl_adaptor_config,
+	.start = mtk_ovl_adaptor_start,
+	.stop = mtk_ovl_adaptor_stop,
+	.layer_nr = mtk_ovl_adaptor_layer_nr,
+	.layer_config = mtk_ovl_adaptor_layer_config,
+	.enable_vblank = mtk_ovl_adaptor_enable_vblank,
+	.disable_vblank = mtk_ovl_adaptor_disable_vblank,
+};
+
 static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_AAL] = "aal",
 	[MTK_DISP_BLS] = "bls",
@@ -398,6 +410,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
 	[MTK_DISP_OVL_2L] = "ovl-2l",
+	[MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
 	[MTK_DISP_POSTMASK] = "postmask",
 	[MTK_DISP_PWM] = "pwm",
 	[MTK_DISP_RDMA] = "rdma",
@@ -443,6 +456,7 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_OVL_2L0]		= { MTK_DISP_OVL_2L,	0, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L1]		= { MTK_DISP_OVL_2L,	1, &ddp_ovl },
 	[DDP_COMPONENT_OVL_2L2]		= { MTK_DISP_OVL_2L,    2, &ddp_ovl },
+	[DDP_COMPONENT_OVL_ADAPTOR]	= { MTK_DISP_OVL_ADAPTOR,	0, &ddp_ovl_adaptor },
 	[DDP_COMPONENT_POSTMASK0]	= { MTK_DISP_POSTMASK,	0, &ddp_postmask },
 	[DDP_COMPONENT_PWM0]		= { MTK_DISP_PWM,	0, NULL },
 	[DDP_COMPONENT_PWM1]		= { MTK_DISP_PWM,	1, NULL },
@@ -548,12 +562,17 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 
 	comp->id = comp_id;
 	comp->funcs = mtk_ddp_matches[comp_id].funcs;
-	comp_pdev = of_find_device_by_node(node);
-	if (!comp_pdev) {
-		DRM_INFO("Waiting for device %s\n", node->full_name);
-		return -EPROBE_DEFER;
+	/* Not all drm components have a DTS device node, such as ovl_adaptor,
+	 * which is the drm bring up sub driver
+	 */
+	if (node) {
+		comp_pdev = of_find_device_by_node(node);
+		if (!comp_pdev) {
+			DRM_INFO("Waiting for device %s\n", node->full_name);
+			return -EPROBE_DEFER;
+		}
+		comp->dev = &comp_pdev->dev;
 	}
-	comp->dev = &comp_pdev->dev;
 
 	/* Only DMA capable components need the LARB property */
 	if (type == MTK_DISP_OVL ||
@@ -573,6 +592,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
+	    type == MTK_DISP_OVL_ADAPTOR ||
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 221e2e3a3c8d..5e1404dc20c4 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
 	MTK_DISP_OVL_2L,
+	MTK_DISP_OVL_ADAPTOR,
 	MTK_DISP_POSTMASK,
 	MTK_DISP_PWM,
 	MTK_DISP_RDMA,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index a05703843af2..36430f956b4f 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -351,9 +351,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
 	struct mtk_drm_private *priv_n;
-	struct platform_device *pdev;
-	struct device_node *np = NULL;
-	struct device *dma_dev;
+	struct device *dma_dev = NULL;
 	int ret, i, j;
 
 	ret = drmm_mode_config_init(drm);
@@ -400,8 +398,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 				if (ret)
 					goto err_component_unbind;
 
-				if (!np)
-					np = priv_n->comp_node[priv_n->data->main_path[0]];
+				if (!dma_dev)
+					dma_dev = priv_n->ddp_comp[priv_n->data->main_path[0]].dev;
 
 				continue;
 			} else if (i == 1 && priv_n->data->ext_len) {
@@ -410,8 +408,8 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 				if (ret)
 					goto err_component_unbind;
 
-				if (!np)
-					np = priv_n->comp_node[priv_n->data->ext_path[0]];
+				if (!dma_dev)
+					dma_dev = priv_n->ddp_comp[priv_n->data->ext_path[0]].dev;
 
 				continue;
 			} else if (i == 2 && priv_n->data->third_len) {
@@ -420,22 +418,20 @@ static int mtk_drm_kms_init(struct drm_device *drm)
 				if (ret)
 					goto err_component_unbind;
 
-				if (!np)
-					np = priv_n->comp_node[priv_n->data->third_path[0]];
+				if (!dma_dev)
+					dma_dev = priv_n->ddp_comp[priv_n->data->third_path[0]].dev;
 
 				continue;
 			}
 		}
 	}
 
-	pdev = of_find_device_by_node(np);
-	if (!pdev) {
+	if (!dma_dev) {
 		ret = -ENODEV;
 		dev_err(drm->dev, "Need at least one OVL device\n");
 		goto err_component_unbind;
 	}
 
-	dma_dev = &pdev->dev;
 	for (i = 0; i < private->data->mmsys_dev_num; i++)
 		private->all_drm_private[i]->dma_dev = dma_dev;
 
@@ -514,6 +510,11 @@ static int compare_of(struct device *dev, void *data)
 	return dev->of_node == data;
 }
 
+static int compare_dev(struct device *dev, void *data)
+{
+	return dev == (struct device *)data;
+}
+
 static int mtk_drm_bind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
@@ -702,6 +703,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 	struct mtk_drm_private *private;
 	struct device_node *node;
 	struct component_match *match = NULL;
+	struct platform_device *ovl_adaptor;
 	int ret;
 	int i;
 
@@ -727,6 +729,19 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	/* Bringup ovl_adaptor */
+	if (mtk_drm_find_mmsys_comp(private, DDP_COMPONENT_OVL_ADAPTOR)) {
+		ovl_adaptor = platform_device_register_data(dev, "mediatek-disp-ovl-adaptor",
+							    PLATFORM_DEVID_AUTO,
+							    (void *)private->mmsys_dev,
+							    sizeof(*private->mmsys_dev));
+		private->ddp_comp[DDP_COMPONENT_OVL_ADAPTOR].dev = &ovl_adaptor->dev;
+		private->comp_node[DDP_COMPONENT_OVL_ADAPTOR] = ovl_adaptor->dev.of_node;
+		mtk_ddp_comp_init(NULL, &private->ddp_comp[DDP_COMPONENT_OVL_ADAPTOR],
+				  DDP_COMPONENT_OVL_ADAPTOR);
+		component_match_add(dev, &match, compare_dev, &ovl_adaptor->dev);
+	}
+
 	/* Iterate over sibling DISP function blocks */
 	for_each_child_of_node(phandle->parent, node) {
 		const struct of_device_id *of_id;
@@ -780,6 +795,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
+		    comp_type == MTK_DISP_OVL_ADAPTOR ||
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DPI ||
 		    comp_type == MTK_DSI) {
@@ -882,6 +898,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
 	&mtk_disp_merge_driver,
+	&mtk_disp_ovl_adaptor_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:38 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:38 +0800
Subject: [PATCH v11 15/22] drm/mediatek: add display merge async reset control
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-16-nancy.lin@mediatek.com>

Add merge async reset control in mtk_merge_stop. Async hw doesn't do self
reset on each sof signal(start of frame), so need to reset the async to
clear the hw status for the next merge start.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: CK Hu <ck.hu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 9dca145cfb71..177473fa8160 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -8,6 +8,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_drm_ddp_comp.h"
@@ -79,6 +80,9 @@ void mtk_merge_stop(struct device *dev)
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
 	mtk_merge_stop_cmdq(dev, NULL);
+
+	if (priv->async_clk)
+		device_reset_optional(dev);
 }
 
 void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:36 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:36 +0800
Subject: [PATCH v11 13/22] drm/mediatek: add display merge start/stop API for
 cmdq support
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-14-nancy.lin@mediatek.com>

Add merge start/stop API for cmdq support. The ovl_adaptor merges
are configured with each drm plane update. Need to enable/disable
merge with cmdq making sure all the settings taken effect in the
same vblank.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h   |  2 ++
 drivers/gpu/drm/mediatek/mtk_disp_merge.c | 20 +++++++++++++++++---
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index c2de53a5892e..224a710bb537 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -66,6 +66,8 @@ void mtk_merge_stop(struct device *dev);
 void mtk_merge_advance_config(struct device *dev, unsigned int l_w, unsigned int r_w,
 			      unsigned int h, unsigned int vrefresh, unsigned int bpc,
 			      struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt);
 
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
index 40da0555416d..c0d9b43b2a66 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_merge.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -67,17 +67,31 @@ struct mtk_disp_merge {
 };
 
 void mtk_merge_start(struct device *dev)
+{
+	mtk_merge_start_cmdq(dev, NULL);
+}
+
+void mtk_merge_stop(struct device *dev)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+	mtk_merge_stop_cmdq(dev, NULL);
 }
 
-void mtk_merge_stop(struct device *dev)
+void mtk_merge_start_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop_cmdq(struct device *dev, struct cmdq_pkt *cmdq_pkt)
 {
 	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
 
-	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CTRL);
 }
 
 static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:45 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:45 +0800
Subject: [PATCH v11 22/22] arm64: dts: mt8195: add display node for vdosys1
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-23-nancy.lin@mediatek.com>

Add display node for vdosys1.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 222 +++++++++++++++++++++++
 1 file changed, 222 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index e136761345db..a69a7b57e070 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/power/mt8195-power.h>
+#include <dt-bindings/reset/mt8195-resets.h>
 
 / {
 	compatible = "mediatek,mt8195";
@@ -20,6 +21,22 @@
 	aliases {
 		gce0 = &gce0;
 		gce1 = &gce1;
+		ethdr0 = &ethdr0;
+		mutex0 = &mutex;
+		mutex1 = &mutex1;
+		merge1 = &merge1;
+		merge2 = &merge2;
+		merge3 = &merge3;
+		merge4 = &merge4;
+		merge5 = &merge5;
+		vdo1_rdma0 = &vdo1_rdma0;
+		vdo1_rdma1 = &vdo1_rdma1;
+		vdo1_rdma2 = &vdo1_rdma2;
+		vdo1_rdma3 = &vdo1_rdma3;
+		vdo1_rdma4 = &vdo1_rdma4;
+		vdo1_rdma5 = &vdo1_rdma5;
+		vdo1_rdma6 = &vdo1_rdma6;
+		vdo1_rdma7 = &vdo1_rdma7;
 	};
 
 	clocks {
@@ -1235,7 +1252,212 @@
 		vdosys1: syscon at 1c100000 {
 			compatible = "mediatek,mt8195-vdosys1", "syscon";
 			reg = <0 0x1c100000 0 0x1000>;
+			mboxes = <&gce0 1 CMDQ_THR_PRIO_4>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x0000 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
+		};
+
+		mutex1: disp_mutex0 at 1c101000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c101000 0 0x1000>;
+			reg-names = "vdo1_mutex";
+			interrupts = <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
+			clock-names = "vdo1_mutex";
+			mediatek,gce-events = <CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0>;
+		};
+
+		vdo1_rdma0: vdo1_rdma at 1c104000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c104000 0 0x1000>;
+			interrupts = <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x4000 0x1000>;
+		};
+
+		vdo1_rdma1: vdo1_rdma at 1c105000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c105000 0 0x1000>;
+			interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA1>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x5000 0x1000>;
+		};
+
+		vdo1_rdma2: vdo1_rdma at 1c106000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c106000 0 0x1000>;
+			interrupts = <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA2>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x6000 0x1000>;
+		};
+
+		vdo1_rdma3: vdo1_rdma at 1c107000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c107000 0 0x1000>;
+			interrupts = <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA3>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x7000 0x1000>;
+		};
+
+		vdo1_rdma4: vdo1_rdma at 1c108000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c108000 0 0x1000>;
+			interrupts = <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA4>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x8000 0x1000>;
+		};
+
+		vdo1_rdma5: vdo1_rdma at 1c109000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c109000 0 0x1000>;
+			interrupts = <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA5>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA5>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x9000 0x1000>;
+		};
+
+		vdo1_rdma6: vdo1_rdma at 1c10a000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10a000 0 0x1000>;
+			interrupts = <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA6>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA6>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xa000 0x1000>;
+		};
+
+		vdo1_rdma7: vdo1_rdma at 1c10b000 {
+			compatible = "mediatek,mt8195-vdo1-rdma";
+			reg = <0 0x1c10b000 0 0x1000>;
+			interrupts = <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_MDP_RDMA7>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA7>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xb000 0x1000>;
+		};
+
+		merge1: disp_vpp_merge at 1c10c000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10c000 0 0x1000>;
+			interrupts = <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE0>,
+				 <&vdosys1 CLK_VDO1_MERGE0_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xc000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE0_DL_ASYNC>;
+		};
+
+		merge2: disp_vpp_merge at 1c10d000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10d000 0 0x1000>;
+			interrupts = <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE1>,
+				 <&vdosys1 CLK_VDO1_MERGE1_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xd000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE1_DL_ASYNC>;
+		};
+
+		merge3: disp_vpp_merge at 1c10e000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10e000 0 0x1000>;
+			interrupts = <GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE2>,
+				 <&vdosys1 CLK_VDO1_MERGE2_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xe000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE2_DL_ASYNC>;
+		};
+
+		merge4: disp_vpp_merge at 1c10f000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c10f000 0 0x1000>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE3>,
+				 <&vdosys1 CLK_VDO1_MERGE3_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xf000 0x1000>;
+			mediatek,merge-mute = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE3_DL_ASYNC>;
+		};
+
+		merge5: disp_vpp_merge at 1c110000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c110000 0 0x1000>;
+			interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+				 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+			clock-names = "merge","merge_async";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x0000 0x1000>;
+			mediatek,merge-fifo-en = <1>;
+			resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+		};
+
+		ethdr0: disp_ethdr at 1c114000 {
+			compatible = "mediatek,mt8195-disp-ethdr";
+			reg = <0 0x1c114000 0 0x1000>,
+			      <0 0x1c115000 0 0x1000>,
+			      <0 0x1c117000 0 0x1000>,
+			      <0 0x1c119000 0 0x1000>,
+			      <0 0x1c11A000 0 0x1000>,
+			      <0 0x1c11B000 0 0x1000>,
+			      <0 0x1c11C000 0 0x1000>;
+			reg-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				    "vdo_be", "adl_ds";
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c11XXXX 0x4000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0x5000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0x7000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0x9000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0xA000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0xB000 0x1000>,
+						  <&gce0 SUBSYS_1c11XXXX 0xC000 0x1000>;
+			clocks = <&vdosys1 CLK_VDO1_DISP_MIXER>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE>,
+				 <&vdosys1 CLK_VDO1_26M_SLOW>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 CLK_VDO1_HDR_VDO_BE_DL_ASYNC>,
+				 <&topckgen CLK_TOP_ETHDR>;
+			clock-names = "mixer", "vdo_fe0", "vdo_fe1", "gfx_fe0", "gfx_fe1",
+				      "vdo_be", "adl_ds", "vdo_fe0_async", "vdo_fe1_async",
+				      "gfx_fe0_async", "gfx_fe1_async","vdo_be_async",
+				      "ethdr_top";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L3_HDR_DS>,
+				 <&iommu_vpp M4U_PORT_L3_HDR_ADL>;
+			interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>; /* disp mixer */
+			resets = <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE0_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_GFX_FE1_DL_ASYNC>,
+				 <&vdosys1 MT8195_VDOSYS1_SW1_RST_B_HDR_VDO_BE_DL_ASYNC>;
 		};
 	};
 
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:39 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:39 +0800
Subject: [PATCH v11 16/22] drm/mediatek: add ETHDR support for MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-17-nancy.lin@mediatek.com>

ETHDR is a part of ovl_adaptor.
ETHDR is designed for HDR video and graphics conversion in the external
display path. It handles multiple HDR input types and performs tone
mapping, color space/color format conversion, and then combine
different layers, output the required HDR or SDR signal to the
subsequent display path.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/Makefile      |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h |   1 +
 drivers/gpu/drm/mediatek/mtk_ethdr.c   | 376 +++++++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_ethdr.h   |  25 ++
 5 files changed, 404 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.c
 create mode 100644 drivers/gpu/drm/mediatek/mtk_ethdr.h

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 6e604a933ed0..fb158a1e7f06 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -14,6 +14,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_drm_plane.o \
 		  mtk_dsi.o \
 		  mtk_dpi.o \
+		  mtk_ethdr.o \
 		  mtk_mdp_rdma.o
 
 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index fa41306422df..390cda4bae57 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -743,6 +743,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_dpi_driver,
 	&mtk_drm_platform_driver,
 	&mtk_dsi_driver,
+	&mtk_ethdr_driver,
 	&mtk_mdp_rdma_driver,
 };
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 64a1f66df26a..3fb85776b8b3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -55,6 +55,7 @@ extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
+extern struct platform_driver mtk_ethdr_driver;
 extern struct platform_driver mtk_mdp_rdma_driver;
 
 #endif /* MTK_DRM_DRV_H */
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.c b/drivers/gpu/drm/mediatek/mtk_ethdr.c
new file mode 100644
index 000000000000..d36a0a5c3d9e
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MIX_INTEN			0x4
+#define MIX_FME_CPL_INTEN			BIT(1)
+#define MIX_INTSTA			0x8
+#define MIX_EN				0xc
+#define MIX_RST				0x14
+#define MIX_ROI_SIZE			0x18
+#define MIX_DATAPATH_CON		0x1c
+#define OUTPUT_NO_RND				BIT(3)
+#define SOURCE_RGB_SEL				BIT(7)
+#define BACKGROUND_RELAY			(4 << 9)
+#define MIX_ROI_BGCLR			0x20
+#define BGCLR_BLACK				0xff000000
+#define MIX_SRC_CON			0x24
+#define MIX_SRC_L0_EN				BIT(0)
+#define MIX_L_SRC_CON(n)		(0x28 + 0x18 * (n))
+#define NON_PREMULTI_SOURCE			(2 << 12)
+#define MIX_L_SRC_SIZE(n)		(0x30 + 0x18 * (n))
+#define MIX_L_SRC_OFFSET(n)		(0x34 + 0x18 * (n))
+#define MIX_FUNC_DCM0			0x120
+#define MIX_FUNC_DCM1			0x124
+#define MIX_FUNC_DCM_ENABLE			0xffffffff
+
+#define HDR_VDO_FE_0804_HDR_DM_FE	0x804
+#define HDR_VDO_FE_0804_BYPASS_ALL		0xfd
+#define HDR_GFX_FE_0204_GFX_HDR_FE	0x204
+#define HDR_GFX_FE_0204_BYPASS_ALL		0xfd
+#define HDR_VDO_BE_0204_VDO_DM_BE	0x204
+#define HDR_VDO_BE_0204_BYPASS_ALL		0x7e
+
+#define MIXER_INX_MODE_BYPASS			0
+#define MIXER_INX_MODE_EVEN_EXTEND		1
+#define DEFAULT_9BIT_ALPHA			0x100
+#define	MIXER_ALPHA_AEN				BIT(8)
+#define	MIXER_ALPHA				0xff
+#define ETHDR_CLK_NUM				13
+
+enum mtk_ethdr_comp_id {
+	ETHDR_MIXER,
+	ETHDR_VDO_FE0,
+	ETHDR_VDO_FE1,
+	ETHDR_GFX_FE0,
+	ETHDR_GFX_FE1,
+	ETHDR_VDO_BE,
+	ETHDR_ADL_DS,
+	ETHDR_ID_MAX
+};
+
+struct mtk_ethdr_comp {
+	struct device		*dev;
+	void __iomem		*regs;
+	struct cmdq_client_reg	cmdq_base;
+};
+
+struct mtk_ethdr {
+	struct mtk_ethdr_comp	ethdr_comp[ETHDR_ID_MAX];
+	struct clk_bulk_data	ethdr_clk[ETHDR_CLK_NUM];
+	struct device		*mmsys_dev;
+	void			(*vblank_cb)(void *data);
+	void			*vblank_cb_data;
+	int			irq;
+	struct reset_control	*reset_ctl;
+};
+
+static const char * const ethdr_clk_str[] = {
+	"ethdr_top",
+	"mixer",
+	"vdo_fe0",
+	"vdo_fe1",
+	"gfx_fe0",
+	"gfx_fe1",
+	"vdo_be",
+	"adl_ds",
+	"vdo_fe0_async",
+	"vdo_fe1_async",
+	"gfx_fe0_async",
+	"gfx_fe1_async",
+	"vdo_be_async",
+};
+
+void mtk_ethdr_enable_vblank(struct device *dev,
+			     void (*vblank_cb)(void *),
+			     void *vblank_cb_data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	priv->vblank_cb = vblank_cb;
+	priv->vblank_cb_data = vblank_cb_data;
+
+	writel(MIX_FME_CPL_INTEN, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+void mtk_ethdr_disable_vblank(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	priv->vblank_cb = NULL;
+	priv->vblank_cb_data = NULL;
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTEN);
+}
+
+static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id)
+{
+	struct mtk_ethdr *priv = dev_id;
+
+	writel(0x0, priv->ethdr_comp[ETHDR_MIXER].regs + MIX_INTSTA);
+
+	if (!priv->vblank_cb)
+		return IRQ_NONE;
+
+	priv->vblank_cb(priv->vblank_cb_data);
+
+	return IRQ_HANDLED;
+}
+
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+	struct mtk_plane_pending_state *pending = &state->pending;
+	unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
+	unsigned int align_width = ALIGN_DOWN(pending->width, 2);
+	unsigned int alpha_con = 0;
+
+	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
+
+	if (idx >= 4)
+		return;
+
+	if (!pending->enable) {
+		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+				     idx + 1, MIXER_INX_MODE_BYPASS, cmdq_pkt);
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+				     idx + 1, 0, cmdq_pkt);
+		return;
+	}
+
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_MODE,
+			     idx + 1, pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
+			     MIXER_INX_MODE_BYPASS, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_BIWIDTH,
+			     idx + 1, align_width / 2 - 1, cmdq_pkt);
+
+	if (state->base.fb && state->base.fb->format->has_alpha) {
+		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 0, cmdq_pkt);
+	} else {
+		mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_ALPHA_SEL,
+				     idx + 1, 1, cmdq_pkt);
+	}
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_ODD, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_ALPHA_EVEN, idx + 1,
+			     DEFAULT_9BIT_ALPHA, cmdq_pkt);
+
+	mtk_ddp_write(cmdq_pkt, pending->height << 16 | align_width, &mixer->cmdq_base,
+		      mixer->regs, MIX_L_SRC_SIZE(idx));
+	mtk_ddp_write(cmdq_pkt, offset, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_OFFSET(idx));
+	mtk_ddp_write_mask(cmdq_pkt, alpha_con, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_CON(idx),
+			   0x1ff);
+	mtk_ddp_write_mask(cmdq_pkt, BIT(idx), &mixer->cmdq_base, mixer->regs, MIX_SRC_CON,
+			   BIT(idx));
+}
+
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *vdo_fe0 = &priv->ethdr_comp[ETHDR_VDO_FE0];
+	struct mtk_ethdr_comp *vdo_fe1 = &priv->ethdr_comp[ETHDR_VDO_FE1];
+	struct mtk_ethdr_comp *gfx_fe0 = &priv->ethdr_comp[ETHDR_GFX_FE0];
+	struct mtk_ethdr_comp *gfx_fe1 = &priv->ethdr_comp[ETHDR_GFX_FE1];
+	struct mtk_ethdr_comp *vdo_be = &priv->ethdr_comp[ETHDR_VDO_BE];
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	dev_dbg(dev, "%s-w:%d, h:%d\n", __func__, w, h);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe0->cmdq_base,
+		      vdo_fe0->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_FE_0804_BYPASS_ALL, &vdo_fe1->cmdq_base,
+		      vdo_fe1->regs, HDR_VDO_FE_0804_HDR_DM_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe0->cmdq_base,
+		      gfx_fe0->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_GFX_FE_0204_BYPASS_ALL, &gfx_fe1->cmdq_base,
+		      gfx_fe1->regs, HDR_GFX_FE_0204_GFX_HDR_FE);
+
+	mtk_ddp_write(cmdq_pkt, HDR_VDO_BE_0204_BYPASS_ALL, &vdo_be->cmdq_base,
+		      vdo_be->regs, HDR_VDO_BE_0204_VDO_DM_BE);
+
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM0);
+	mtk_ddp_write(cmdq_pkt, MIX_FUNC_DCM_ENABLE, &mixer->cmdq_base, mixer->regs, MIX_FUNC_DCM1);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &mixer->cmdq_base, mixer->regs, MIX_ROI_SIZE);
+	mtk_ddp_write(cmdq_pkt, BGCLR_BLACK, &mixer->cmdq_base, mixer->regs, MIX_ROI_BGCLR);
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(0));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(1));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(2));
+	mtk_ddp_write(cmdq_pkt, NON_PREMULTI_SOURCE, &mixer->cmdq_base, mixer->regs,
+		      MIX_L_SRC_CON(3));
+	mtk_ddp_write(cmdq_pkt, 0x0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(0));
+	mtk_ddp_write(cmdq_pkt, OUTPUT_NO_RND | SOURCE_RGB_SEL | BACKGROUND_RELAY,
+		      &mixer->cmdq_base, mixer->regs, MIX_DATAPATH_CON);
+	mtk_ddp_write_mask(cmdq_pkt, MIX_SRC_L0_EN, &mixer->cmdq_base, mixer->regs,
+			   MIX_SRC_CON, MIX_SRC_L0_EN);
+
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_WIDTH, 0,
+			     w / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_HDR_BE_ASYNC_HEIGHT, 0,
+			     h, cmdq_pkt);
+	mtk_mmsys_ddp_config(priv->mmsys_dev, MMSYS_CONFIG_MIXER_IN_CH_SWAP, 4, 0, cmdq_pkt);
+}
+
+void mtk_ethdr_start(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	writel(1, mixer->regs + MIX_EN);
+}
+
+void mtk_ethdr_stop(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+	struct mtk_ethdr_comp *mixer = &priv->ethdr_comp[ETHDR_MIXER];
+
+	writel(0, mixer->regs + MIX_EN);
+	writel(1, mixer->regs + MIX_RST);
+	reset_control_reset(priv->reset_ctl);
+	writel(0, mixer->regs + MIX_RST);
+}
+
+int mtk_ethdr_clk_enable(struct device *dev)
+{
+	int ret;
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	ret = clk_bulk_prepare_enable(ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		dev_err(dev,
+			"ethdr_clk prepare enable failed\n");
+	return ret;
+}
+
+void mtk_ethdr_clk_disable(struct device *dev)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	clk_bulk_disable_unprepare(ETHDR_CLK_NUM, priv->ethdr_clk);
+}
+
+static int mtk_ethdr_bind(struct device *dev, struct device *master,
+			  void *data)
+{
+	struct mtk_ethdr *priv = dev_get_drvdata(dev);
+
+	priv->mmsys_dev = data;
+	return 0;
+}
+
+static void mtk_ethdr_unbind(struct device *dev, struct device *master, void *data)
+{
+}
+
+static const struct component_ops mtk_ethdr_component_ops = {
+	.bind	= mtk_ethdr_bind,
+	.unbind = mtk_ethdr_unbind,
+};
+
+static int mtk_ethdr_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_ethdr *priv;
+	int ret;
+	int i;
+
+	dev_info(dev, "%s+\n", __func__);
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	for (i = 0; i < ETHDR_ID_MAX; i++) {
+		priv->ethdr_comp[i].dev = dev;
+		priv->ethdr_comp[i].regs = of_iomap(dev->of_node, i);
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+		ret = cmdq_dev_get_client_reg(dev,
+					      &priv->ethdr_comp[i].cmdq_base, i);
+		if (ret)
+			dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+		dev_dbg(dev, "[DRM]regs:0x%x, node:%d\n", priv->ethdr_comp[i].regs, i);
+	}
+
+	for (i = 0; i < ETHDR_CLK_NUM; i++)
+		priv->ethdr_clk[i].id = ethdr_clk_str[i];
+	ret = devm_clk_bulk_get_optional(dev, ETHDR_CLK_NUM, priv->ethdr_clk);
+	if (ret)
+		return ret;
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (priv->irq < 0)
+		priv->irq = 0;
+
+	if (priv->irq) {
+		ret = devm_request_irq(dev, priv->irq, mtk_ethdr_irq_handler,
+				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
+		if (ret < 0) {
+			dev_err(dev, "Failed to request irq %d: %d\n", priv->irq, ret);
+			return ret;
+		}
+	}
+
+	priv->reset_ctl = devm_reset_control_array_get_optional_exclusive(dev);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_ethdr_component_ops);
+	if (ret)
+		dev_notice(dev, "Failed to add component: %d\n", ret);
+
+	dev_info(dev, "%s-\n", __func__);
+	return ret;
+}
+
+static int mtk_ethdr_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_ethdr_component_ops);
+	return 0;
+}
+
+static const struct of_device_id mtk_ethdr_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-ethdr"},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_ethdr_driver_dt_match);
+
+struct platform_driver mtk_ethdr_driver = {
+	.probe		= mtk_ethdr_probe,
+	.remove		= mtk_ethdr_remove,
+	.driver		= {
+		.name	= "mediatek-disp-ethdr",
+		.owner	= THIS_MODULE,
+		.of_match_table = mtk_ethdr_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_ethdr.h b/drivers/gpu/drm/mediatek/mtk_ethdr.h
new file mode 100644
index 000000000000..84eb9bf2ede0
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_ethdr.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef __MTK_ETHDR_H__
+#define __MTK_ETHDR_H__
+
+#include <drm/mediatek_drm.h>
+
+void mtk_ethdr_start(struct device *dev);
+void mtk_ethdr_stop(struct device *dev);
+int mtk_ethdr_clk_enable(struct device *dev);
+void mtk_ethdr_clk_disable(struct device *dev);
+void mtk_ethdr_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_layer_config(struct device *dev, unsigned int idx,
+			    struct mtk_plane_state *state,
+			    struct cmdq_pkt *cmdq_pkt);
+void mtk_ethdr_enable_vblank(struct device *dev, void (*vblank_cb)(void *),
+			     void *vblank_cb_data);
+void mtk_ethdr_disable_vblank(struct device *dev);
+#endif
+
-- 
2.18.0



From nancy.lin at mediatek.com  Mon Jan 10 00:46:41 2022
From: nancy.lin at mediatek.com (Nancy.Lin)
Date: Mon, 10 Jan 2022 16:46:41 +0800
Subject: [PATCH v11 18/22] drm/mediatek: add ovl_adaptor support for MT8195
In-Reply-To: <20220110084645.31191-1-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
Message-ID: <20220110084645.31191-19-nancy.lin@mediatek.com>

Add ovl_adaptor driver for MT8195.
Ovl_adaptor is an encapsulated module and designed for simplified
DRM control flow. This module is composed of 8 RDMAs, 4 MERGEs and
an ETHDR. Two RDMAs merge into one layer, so this module support 4
layers.

Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |  16 +
 .../gpu/drm/mediatek/mtk_disp_ovl_adaptor.c   | 436 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 4 files changed, 454 insertions(+)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index fb158a1e7f06..3abd27d7c91d 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -6,6 +6,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_gamma.o \
 		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
+		  mtk_disp_ovl_adaptor.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
 		  mtk_drm_ddp_comp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 224a710bb537..cd9827402626 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -112,6 +112,22 @@ void mtk_rdma_enable_vblank(struct device *dev,
 			    void *vblank_cb_data);
 void mtk_rdma_disable_vblank(struct device *dev);
 
+int mtk_ovl_adaptor_clk_enable(struct device *dev);
+void mtk_ovl_adaptor_clk_disable(struct device *dev);
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+			    unsigned int h, unsigned int vrefresh,
+			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt);
+void mtk_ovl_adaptor_enable_vblank(struct device *dev,
+				   void (*vblank_cb)(void *),
+				   void *vblank_cb_data);
+void mtk_ovl_adaptor_disable_vblank(struct device *dev);
+void mtk_ovl_adaptor_start(struct device *dev);
+void mtk_ovl_adaptor_stop(struct device *dev);
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev);
+
 int mtk_mdp_rdma_clk_enable(struct device *dev);
 void mtk_mdp_rdma_clk_disable(struct device *dev);
 void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
new file mode 100644
index 000000000000..2b91be1cf0f9
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <drm/drm_fourcc.h>
+#include <drm/drm_of.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_ethdr.h"
+
+#define MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH 1920
+#define MTK_OVL_ADAPTOR_LAYER_NUM 4
+
+enum mtk_ovl_adaptor_comp_type {
+	OVL_ADAPTOR_TYPE_RDMA = 0,
+	OVL_ADAPTOR_TYPE_MERGE,
+	OVL_ADAPTOR_TYPE_ETHDR,
+	OVL_ADAPTOR_TYPE_NUM,
+};
+
+enum mtk_ovl_adaptor_comp_id {
+	OVL_ADAPTOR_MDP_RDMA0,
+	OVL_ADAPTOR_MDP_RDMA1,
+	OVL_ADAPTOR_MDP_RDMA2,
+	OVL_ADAPTOR_MDP_RDMA3,
+	OVL_ADAPTOR_MDP_RDMA4,
+	OVL_ADAPTOR_MDP_RDMA5,
+	OVL_ADAPTOR_MDP_RDMA6,
+	OVL_ADAPTOR_MDP_RDMA7,
+	OVL_ADAPTOR_MERGE0,
+	OVL_ADAPTOR_MERGE1,
+	OVL_ADAPTOR_MERGE2,
+	OVL_ADAPTOR_MERGE3,
+	OVL_ADAPTOR_ETHDR0,
+	OVL_ADAPTOR_ID_MAX
+};
+
+struct ovl_adaptor_comp_match {
+	enum mtk_ovl_adaptor_comp_type type;
+	int alias_id;
+};
+
+struct mtk_disp_ovl_adaptor {
+	struct device *ovl_adaptor_comp[OVL_ADAPTOR_ID_MAX];
+	struct device *mmsys_dev;
+};
+
+static const char * const private_comp_stem[OVL_ADAPTOR_TYPE_NUM] = {
+	[OVL_ADAPTOR_TYPE_RDMA]		= "vdo1_rdma",
+	[OVL_ADAPTOR_TYPE_MERGE]	= "merge",
+	[OVL_ADAPTOR_TYPE_ETHDR]	= "ethdr",
+};
+
+static const struct ovl_adaptor_comp_match comp_matches[OVL_ADAPTOR_ID_MAX] = {
+	[OVL_ADAPTOR_MDP_RDMA0]	= { OVL_ADAPTOR_TYPE_RDMA, 0 },
+	[OVL_ADAPTOR_MDP_RDMA1]	= { OVL_ADAPTOR_TYPE_RDMA, 1 },
+	[OVL_ADAPTOR_MDP_RDMA2]	= { OVL_ADAPTOR_TYPE_RDMA, 2 },
+	[OVL_ADAPTOR_MDP_RDMA3]	= { OVL_ADAPTOR_TYPE_RDMA, 3 },
+	[OVL_ADAPTOR_MDP_RDMA4]	= { OVL_ADAPTOR_TYPE_RDMA, 4 },
+	[OVL_ADAPTOR_MDP_RDMA5]	= { OVL_ADAPTOR_TYPE_RDMA, 5 },
+	[OVL_ADAPTOR_MDP_RDMA6]	= { OVL_ADAPTOR_TYPE_RDMA, 6 },
+	[OVL_ADAPTOR_MDP_RDMA7]	= { OVL_ADAPTOR_TYPE_RDMA, 7 },
+	[OVL_ADAPTOR_MERGE0]	= { OVL_ADAPTOR_TYPE_MERGE, 1 },
+	[OVL_ADAPTOR_MERGE1]	= { OVL_ADAPTOR_TYPE_MERGE, 2 },
+	[OVL_ADAPTOR_MERGE2]	= { OVL_ADAPTOR_TYPE_MERGE, 3 },
+	[OVL_ADAPTOR_MERGE3]	= { OVL_ADAPTOR_TYPE_MERGE, 4 },
+	[OVL_ADAPTOR_ETHDR0]	= { OVL_ADAPTOR_TYPE_ETHDR, 0 },
+};
+
+void mtk_ovl_adaptor_layer_config(struct device *dev, unsigned int idx,
+				  struct mtk_plane_state *state,
+				  struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct mtk_plane_pending_state *pending = &state->pending;
+	struct mtk_mdp_rdma_cfg rdma_config = {0};
+	struct device *rdma_l;
+	struct device *rdma_r;
+	struct device *merge;
+	struct device *ethdr;
+	const struct drm_format_info *fmt_info = drm_format_info(pending->format);
+	bool use_dual_pipe = false;
+	unsigned int align_width;
+	unsigned int l_w = 0;
+	unsigned int r_w = 0;
+
+	dev_dbg(dev, "%s+ idx:%d, enable:%d, fmt:0x%x\n", __func__, idx,
+		pending->enable, pending->format);
+	dev_dbg(dev, "addr 0x%lx, fb w:%d, {%d,%d,%d,%d}\n",
+		pending->addr, (pending->pitch / fmt_info->cpp[0]),
+		pending->x, pending->y, pending->width, pending->height);
+
+	rdma_l = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx];
+	rdma_r = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MDP_RDMA0 + 2 * idx + 1];
+	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
+	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
+
+	if (!pending->enable) {
+		mtk_merge_stop_cmdq(merge, cmdq_pkt);
+		mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
+		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
+		mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
+		return;
+	}
+
+	/* ETHDR is in 1T2P domain, width needs to be 2 pixels align */
+	align_width = ALIGN_DOWN(pending->width, 2);
+
+	if (align_width > MTK_OVL_ADAPTOR_RDMA_MAX_WIDTH)
+		use_dual_pipe = true;
+
+	if (use_dual_pipe) {
+		l_w = (align_width / 2) + ((pending->width / 2) % 2);
+		r_w = align_width - l_w;
+	} else {
+		l_w = align_width;
+	}
+	mtk_merge_advance_config(merge, l_w, r_w, pending->height, 0, 0, cmdq_pkt);
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_WIDTH,
+			     idx, align_width / 2, cmdq_pkt);
+	mtk_mmsys_ddp_config(ovl_adaptor->mmsys_dev, MMSYS_CONFIG_MERGE_ASYNC_HEIGHT,
+			     idx, pending->height, cmdq_pkt);
+
+	rdma_config.width = l_w;
+	rdma_config.height = pending->height;
+	rdma_config.addr0 = pending->addr;
+	rdma_config.pitch = pending->pitch;
+	rdma_config.fmt = pending->format;
+	rdma_config.color_encoding = pending->color_encoding;
+	mtk_mdp_rdma_config(rdma_l, &rdma_config, cmdq_pkt);
+
+	if (use_dual_pipe) {
+		rdma_config.x_left = l_w;
+		rdma_config.width = r_w;
+		mtk_mdp_rdma_config(rdma_r, &rdma_config, cmdq_pkt);
+	}
+
+	mtk_merge_start_cmdq(merge, cmdq_pkt);
+
+	mtk_mdp_rdma_start(rdma_l, cmdq_pkt);
+	if (use_dual_pipe)
+		mtk_mdp_rdma_start(rdma_r, cmdq_pkt);
+	else
+		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
+
+	mtk_ethdr_layer_config(ethdr, idx, state, cmdq_pkt);
+}
+
+void mtk_ovl_adaptor_config(struct device *dev, unsigned int w,
+			    unsigned int h, unsigned int vrefresh,
+			    unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_config(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0], w, h,
+			 vrefresh, bpc, cmdq_pkt);
+}
+
+void mtk_ovl_adaptor_start(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_start(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+void mtk_ovl_adaptor_stop(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_stop(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+int mtk_ovl_adaptor_clk_enable(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct device *comp;
+	int ret;
+	int i;
+
+	for (i = 0; i < OVL_ADAPTOR_MERGE0; i++) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+		ret = pm_runtime_get_sync(comp);
+		if (ret) {
+			dev_err(dev, "Failed to enable power domain %d, err %d\n", i, ret);
+			goto pwr_err;
+		}
+	}
+
+	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+
+		if (i < OVL_ADAPTOR_MERGE0)
+			ret = mtk_mdp_rdma_clk_enable(comp);
+		else if (i < OVL_ADAPTOR_ETHDR0)
+			ret = mtk_merge_clk_enable(comp);
+		else
+			ret = mtk_ethdr_clk_enable(comp);
+		if (ret) {
+			dev_err(dev, "Failed to enable clock %d, err %d\n", i, ret);
+			goto clk_err;
+		}
+	}
+
+	return ret;
+
+clk_err:
+	while (--i >= 0) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+		if (i < OVL_ADAPTOR_MERGE0)
+			mtk_mdp_rdma_clk_disable(comp);
+		else if (i < OVL_ADAPTOR_ETHDR0)
+			mtk_merge_clk_disable(comp);
+		else
+			mtk_ethdr_clk_disable(comp);
+	}
+	i = OVL_ADAPTOR_MERGE0;
+
+pwr_err:
+	while (--i >= 0)
+		pm_runtime_put(ovl_adaptor->ovl_adaptor_comp[i]);
+
+	return ret;
+}
+
+void mtk_ovl_adaptor_clk_disable(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+	struct device *comp;
+	int i;
+
+	for (i = 0; i < OVL_ADAPTOR_ID_MAX; i++) {
+		comp = ovl_adaptor->ovl_adaptor_comp[i];
+
+		if (i < OVL_ADAPTOR_MERGE0) {
+			mtk_mdp_rdma_clk_disable(comp);
+			pm_runtime_put(comp);
+		} else if (i < OVL_ADAPTOR_ETHDR0) {
+			mtk_merge_clk_disable(comp);
+		} else {
+			mtk_ethdr_clk_disable(comp);
+		}
+	}
+}
+
+unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev)
+{
+	return MTK_OVL_ADAPTOR_LAYER_NUM;
+}
+
+void mtk_ovl_adaptor_enable_vblank(struct device *dev, void (*vblank_cb)(void *),
+				   void *vblank_cb_data)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_enable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0],
+				vblank_cb, vblank_cb_data);
+}
+
+void mtk_ovl_adaptor_disable_vblank(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev);
+
+	mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]);
+}
+
+static int ovl_adaptor_comp_get_id(struct device *dev, struct device_node *node,
+				   enum mtk_ovl_adaptor_comp_type type)
+{
+	int alias_id = of_alias_get_id(node, private_comp_stem[type]);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(comp_matches); i++)
+		if (comp_matches[i].type == type &&
+		    comp_matches[i].alias_id == alias_id)
+			return i;
+
+	dev_warn(dev, "Failed to get id. type: %d, alias: %d\n", type, alias_id);
+	return -EINVAL;
+}
+
+static const struct of_device_id mtk_ovl_adaptor_comp_dt_ids[] = {
+	{
+		.compatible = "mediatek,mt8195-vdo1-rdma",
+		.data = (void *)OVL_ADAPTOR_TYPE_RDMA,
+	}, {
+		.compatible = "mediatek,mt8195-disp-merge",
+		.data = (void *)OVL_ADAPTOR_TYPE_MERGE,
+	}, {
+		.compatible = "mediatek,mt8195-disp-ethdr",
+		.data = (void *)OVL_ADAPTOR_TYPE_ETHDR,
+	},
+	{},
+};
+
+static int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static int ovl_adaptor_comp_init(struct device *dev, struct component_match **match)
+{
+	struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
+	struct device_node *node, *parent;
+	struct platform_device *comp_pdev;
+
+	parent = dev->parent->parent->of_node->parent;
+
+	for_each_child_of_node(parent, node) {
+		const struct of_device_id *of_id;
+		enum mtk_ovl_adaptor_comp_type type;
+		int id;
+
+		of_id = of_match_node(mtk_ovl_adaptor_comp_dt_ids, node);
+		if (!of_id)
+			continue;
+
+		if (!of_device_is_available(node)) {
+			dev_dbg(dev, "Skipping disabled component %pOF\n",
+				node);
+			continue;
+		}
+
+		type = (enum mtk_ovl_adaptor_comp_type)of_id->data;
+		id = ovl_adaptor_comp_get_id(dev, node, type);
+		if (id < 0) {
+			dev_warn(dev, "Skipping unknown component %pOF\n",
+				 node);
+			continue;
+		}
+
+		comp_pdev = of_find_device_by_node(node);
+		if (!comp_pdev)
+			return -EPROBE_DEFER;
+
+		priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
+
+		drm_of_component_match_add(dev, match, compare_of, node);
+		dev_dbg(dev, "Adding component match for %pOF\n", node);
+	}
+
+	return 0;
+}
+
+static int mtk_disp_ovl_adaptor_comp_bind(struct device *dev, struct device *master,
+					  void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_ovl_adaptor_comp_unbind(struct device *dev, struct device *master,
+					     void *data)
+{
+}
+
+static const struct component_ops mtk_disp_ovl_adaptor_comp_ops = {
+	.bind	= mtk_disp_ovl_adaptor_comp_bind,
+	.unbind = mtk_disp_ovl_adaptor_comp_unbind,
+};
+
+static int mtk_disp_ovl_adaptor_master_bind(struct device *dev)
+{
+	struct mtk_disp_ovl_adaptor *priv = dev_get_drvdata(dev);
+
+	component_bind_all(dev, priv->mmsys_dev);
+	return 0;
+}
+
+static void mtk_disp_ovl_adaptor_master_unbind(struct device *dev)
+{
+}
+
+static const struct component_master_ops mtk_disp_ovl_adaptor_master_ops = {
+	.bind		= mtk_disp_ovl_adaptor_master_bind,
+	.unbind		= mtk_disp_ovl_adaptor_master_unbind,
+};
+
+static int mtk_disp_ovl_adaptor_probe(struct platform_device *pdev)
+{
+	struct mtk_disp_ovl_adaptor *priv;
+	struct device *dev = &pdev->dev;
+	struct component_match *match = NULL;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = ovl_adaptor_comp_init(dev, &match);
+	if (ret < 0)
+		return ret;
+
+	priv->mmsys_dev = pdev->dev.platform_data;
+
+	component_master_add_with_match(dev, &mtk_disp_ovl_adaptor_master_ops, match);
+
+	pm_runtime_enable(dev);
+
+	ret = component_add(dev, &mtk_disp_ovl_adaptor_comp_ops);
+	if (ret != 0) {
+		pm_runtime_disable(dev);
+		dev_err(dev, "Failed to add component: %d\n", ret);
+	}
+
+	return ret;
+}
+
+static int mtk_disp_ovl_adaptor_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &mtk_disp_ovl_adaptor_master_ops);
+	pm_runtime_disable(&pdev->dev);
+	return 0;
+}
+
+struct platform_driver mtk_disp_ovl_adaptor_driver = {
+	.probe		= mtk_disp_ovl_adaptor_probe,
+	.remove		= mtk_disp_ovl_adaptor_remove,
+	.driver		= {
+		.name	= "mediatek-disp-ovl-adaptor",
+		.owner	= THIS_MODULE,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 3fb85776b8b3..d27561e5e274 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -51,6 +51,7 @@ extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
 extern struct platform_driver mtk_disp_merge_driver;
+extern struct platform_driver mtk_disp_ovl_adaptor_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0



From yu.tu at amlogic.com  Mon Jan 10 00:56:04 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 16:56:04 +0800
Subject: [PATCH V4 5/5] tty: serial: meson: Added S4 SOC compatibility.
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <20220110085604.18042-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index fd128878e91a..d6aa04cc31ba 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -863,6 +863,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-g12a-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	/*
 	 * deprecated, don't use anymore because it doesn't differentiate
 	 * between GXBB, GXL and G12A which have different revisions
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan 10 01:16:03 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 10:16:03 +0100
Subject: [PATCH v3 09/33] iommu/mediatek: Remove for_each_m4u in
 tlb_sync_all
In-Reply-To: <22faee018a36a49e4a507b69d087432c8cd689ec.camel@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-10-yong.wu@mediatek.com>
 <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>
 <22faee018a36a49e4a507b69d087432c8cd689ec.camel@mediatek.com>
Message-ID: <85987e9a-dfb0-c241-1dde-43c050a78b51@collabora.com>

Il 09/01/22 03:48, Yong Wu ha scritto:
> On Tue, 2022-01-04 at 16:55 +0100, AngeloGioacchino Del Regno wrote:
>> Il 23/09/21 13:58, Yong Wu ha scritto:
>>> The tlb_sync_all is called from these three functions:
>>> a) flush_iotlb_all: it will be called for each a iommu HW.
>>> b) tlb_flush_range_sync: it already has for_each_m4u.
>>> c) in irq: When IOMMU HW translation fault, Only need flush itself.
>>>
>>> Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
>>>
>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>> ---
>>>    drivers/iommu/mtk_iommu.c | 18 +++++++-----------
>>>    1 file changed, 7 insertions(+), 11 deletions(-)
>>>
>>> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
>>> index 6f4f6624e3ac..0b4c30baa864 100644
>>> --- a/drivers/iommu/mtk_iommu.c
>>> +++ b/drivers/iommu/mtk_iommu.c
>>> @@ -206,19 +206,15 @@ static struct mtk_iommu_domain
>>> *to_mtk_domain(struct iommu_domain *dom)
>>>    
>>>    static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
>>>    {
>>> -	struct list_head *head = data->hw_list;
>>> -
>>> -	for_each_m4u(data, head) {
>>> -		if (pm_runtime_get_if_in_use(data->dev) <= 0)
>>> -			continue;
>>> +	if (pm_runtime_get_if_in_use(data->dev) <= 0)
>>> +		return;
>>>    
>>> -		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>>> -			       data->base + data->plat_data-
>>>> inv_sel_reg);
>>> -		writel_relaxed(F_ALL_INVLD, data->base +
>>> REG_MMU_INVALIDATE);
>>> -		wmb(); /* Make sure the tlb flush all done */
>>> +	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>>> +		       data->base + data->plat_data->inv_sel_reg);
>>> +	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
>>> +	wmb(); /* Make sure the tlb flush all done */
>>
>> There aren't a lot of writes here - not anymore, since you are no
>> longer doing
>> this for_each_m4u()...
>> ...so, please change writel_relaxed() to writel() calls, allowing you
>> to also
>> remove the write barrier at the end (since in the non relaxed
>> version, order is already ensured).
> 
> In the "writel", the "__iowmb()" runs before "write_relaxed". Then how
> to guarantee the last register was wrote into the HW. Here the flush
> all don't have sync(waiting it complete)
> 

That's right, I'm sorry for the invalid proposal.

Though, there's something else to mention here... if writing
(F_INVLD_EN1 | F_INVLD_EN0) to inv_sel_reg is *required* to happen before
writing F_ALL_INVLD to REG_MMU_INVALIDATE (which I think is exactly the
case here), then, in order to ensure write ordering, you should still use
writel() instead of the relaxed accessor; after which, since (as you mentioned)
there is no sync readback loop, you can keep that wmb() at the end.

>>
>>>    
>>> -		pm_runtime_put(data->dev);
>>> -	}
>>> +	pm_runtime_put(data->dev);
>>>    }
>>>    
>>>    static void mtk_iommu_tlb_flush_range_sync(unsigned long iova,
>>> size_t size,
>>>
> 




From pali at kernel.org  Mon Jan 10 01:17:29 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 10 Jan 2022 10:17:29 +0100
Subject: [PATCH 3/3] PCI: aardvark: Implement emulated root PCI bridge
In-Reply-To: <20220107231734.GA426583@bhelgaas>
References: <20220107212736.GA404447@bhelgaas>
 <20220107231734.GA426583@bhelgaas>
Message-ID: <20220110091729.owxno5ck3bihlrzj@pali>

On Friday 07 January 2022 17:17:34 Bjorn Helgaas wrote:
> [+cc Pali; sorry, I meant to cc you on this but forgot]
> 
> On Fri, Jan 07, 2022 at 03:27:38PM -0600, Bjorn Helgaas wrote:
> > On Fri, Jun 29, 2018 at 11:22:31AM +0200, Thomas Petazzoni wrote:
> > 
> > > +static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
> > > +{
> > > +	struct pci_sw_bridge *bridge = &pcie->bridge;
> > 
> > > +	/* Support interrupt A for MSI feature */
> > > +	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
> > 
> > Only 3.5 years later, IIUC, this is the value you get when you read
> > PCI_INTERRUPT_PIN, so I think this should be PCI_INTERRUPT_INTA, not
> > PCIE_CORE_INT_A_ASSERT_ENABLE.
> > 
> > Readers expect to get the values defined in the PCI spec, i.e.,
> > 
> >   PCI_INTERRUPT_UNKNOWN
> >   PCI_INTERRUPT_INTA
> >   PCI_INTERRUPT_INTB
> >   PCI_INTERRUPT_INTC
> >   PCI_INTERRUPT_INTD
> > 
> > Bjorn

Yes! We have a prepared patch for it and Marek now sent it:
https://lore.kernel.org/linux-pci/20220110015018.26359-2-kabel at kernel.org/


From krzysztof.kozlowski at canonical.com  Mon Jan 10 01:21:24 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 10:21:24 +0100
Subject: [PATCH 0/7] arm/arm64: dts: Remove unused num-viewport from pcie
 node
In-Reply-To: <d3cb933f371ab5b5@bloch.sibelius.xs4all.nl>
References: <20211229160245.1338-1-jszhang@kernel.org>
 <d3cb7b8439ee3d06@bloch.sibelius.xs4all.nl>
 <99115cc4-32f6-d217-68be-33256a6993a8@canonical.com>
 <d3cb933f371ab5b5@bloch.sibelius.xs4all.nl>
Message-ID: <2ee68b52-bb73-e013-d722-0c033391b704@canonical.com>

On 07/01/2022 20:39, Mark Kettenis wrote:
>> Date: Fri, 7 Jan 2022 13:47:03 +0100
>> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>
>> On 29/12/2021 17:50, Mark Kettenis wrote:
>>>> From: Jisheng Zhang <jszhang at kernel.org>
>>>> Date: Thu, 30 Dec 2021 00:02:38 +0800
>>>>
>>>> After commit 281f1f99cf3a("PCI: dwc: Detect number of iATU windows"),
>>>> the number of iATU windows is detected at runtime, what's more,
>>>> the 'num-viewport' property parsing has been removed, so remove the
>>>> unused num-viewport from pcie node(s).
>>>>
>>>> It's too late for linux-5.17-rc1, I will rebase and send out v2 if
>>>> necessary when 5.17-rc1 is released.
>>>
>>> Please no.  This only makes the device trees unnecessarily
>>> incompatible with older kernels
>>
>> Anyone who is running a new DTB with older kernel is doomed anyway, not
>> only because of this change but hundreds of other similar cleanups, e.g.
>> making DTS conforming to dtschema. Are you sure there are such use cases
>> of using new DTB with old kernel? I cannot imagine making a stable
>> product with such scenario...
> 
> Well, many of those changes just affect the node names, which aren't
> part of the ABI.  And adding missing properties or compatibles doesn't
> break things either.  But yes, we keep seeing diffs to "cleanup"
> bindings and device trees, especially in the context of converting
> them to dtschema.  And that's just wrong.  If old device trees don't
> pass validation, the default assumption should be that the schema is
> wrong; not the other way around.

I cannot get how you reached a conclusion that old device tree could be
good, but old bindings would be bad... Both were developed without
consistency, sometimes without proper review. Simply both can be wrong
and now we fix them - the bindings by converting to stricter schema and
DTS files by aligning them with new schema.

There was never a contract between us and users that OLD kernel will
work with NEW DTB. The only contract we made was the other way around -
NEW kernel will work with OLD DTB.

I understand that it is useful to have new DTB working with old kernel.
I consider it as a "nice to have" feature but:
1. Still there are no real users of such pattern (new DTB with old
kernel), around Linux kernel. If they are - I am repaeting - their Linux
project is already broken.

2. If Linux drivers or other projects depend on node names and anything
not being part of bindings (the ABI), they are broken by design. They
should either be fixed or accept that might get broken anytime soon
because they do not use bindings but undocumented parts (which are not ABI).

3. "Nice to have" should not stop us in improving out codebase and
making it easier to maintain for us. We do not make these "dtschema
align" changes for pure fun, but to make everything easier for us in the
longterm. The dtschema checks I was running (and converting to dtschema)
already found errors in DTS. These are real bugs which are fixed by this
stricter dtschema.

Best regards,
Krzysztof


From narmstrong at baylibre.com  Mon Jan 10 01:23:50 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:23:50 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc
In-Reply-To: <YdoBffKeAvtOeRSe@lx2k>
References: <7e40328b-6645-4343-3050-73dcfb2cefcb@baylibre.com>
 <YdoBffKeAvtOeRSe@lx2k>
Message-ID: <df36156e-eb2e-21e0-e5f2-28666409547a@baylibre.com>

Hi,

On 08/01/2022 22:26, Olof Johansson wrote:
> On Mon, Jan 03, 2022 at 04:13:44PM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
>> the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
>> applied by greg in the tty branch for 5.17.
>>
>> I know it's early for 5.17-rc1, but at least it's in the pipe.
>>
>> I based the changes on your dt-5.17 tag pushed to linus for 5.17-rc1,
>> if necessary I can rebase on v5.16-rcX.
> 
> Hi Neil,
> 
> It looks like this branch is based on our arm/dt branch? Please don't base your
> topics on our branches, it'll be awkward if we ever need to rebuild them (it's
> happened a few times, but we try very hard to avoid it).


Sure, no worries, I tried but I was wrong

> 
> In this case, you should have based your contents on top of your latest dt
> branch (if it would have had conflicts), not ours.

Noted for next time

> 
> Mind rebuilding and send a new pull request?

Sure, rebasing right now on proper 5.17-rc DT tag

> 
> Thanks,
> 
> 
> -Olof
> 

Thanks,
Neil


From narmstrong at baylibre.com  Mon Jan 10 01:25:00 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:25:00 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
 <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
Message-ID: <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>

On 07/01/2022 23:13, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +required:
>> +  - compatible
>> +  - reg
>> +  - "#phy-cells"
> I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
> the datasheet.
> I'm no expert on this and I'm just asking in case you have missed one of these:
> Can you confirm that these belong to some other IP?

Indeed the name is misleading, both go to the DSI Transceiver IP (dw-mipi-dsi)

Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:27:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:27:56 +0100
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <20220110085604.18042-1-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
Message-ID: <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>

Hi,

On 10/01/2022 09:55, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate
> clock makes it easier for the UART driver to be compatible
> with the baud rate requirements of the UART IP on different
> meson chips. Add Meson S4 SoC compatible.
> 
> Yu Tu (5):
>   dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>   tty: serial: meson: Request the register region in meson_uart_probe()
>   tty: serial: meson: The UART baud rate calculation is described using
>     the common clock code.
>   tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>     register writable
>   tty: serial: meson: Added S4 SOC compatibility.

Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
[PATCH V4 0/5] the UART driver compatible with
[PATCH V4 1/5] dt-bindings: serial: meson: Drop
[PATCH V4 2/5] tty: serial: meson: Request the register
...
Only the last one is OK.


> 
> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
> discussed in the email
> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
> the DTS before it can be deleted
> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
> in the email.
> 
> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
> 
>  .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
>  drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
>  2 files changed, 177 insertions(+), 77 deletions(-)
> 



From maz at kernel.org  Mon Jan 10 01:28:39 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 10 Jan 2022 09:28:39 +0000
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a
 static driver structure
In-Reply-To: <20220110015018.26359-24-kabel@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
 <20220110015018.26359-24-kabel@kernel.org>
Message-ID: <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>

On 2022-01-10 01:50, Marek Beh?n wrote:
> Marc Zyngier says [1] that we should use struct irq_chip as a global
> static struct in the driver. Even though the structure currently
> contains a dynamic member (parent_device), Marc says [2] that he plans
> to kill it and make the structure completely static.
> 
> We have already converted others irq_chip structures in this driver in
> this way, but we omitted this one because the .name member is
> dynamically created from device's name, and the name is displayed in
> sysfs, so changing it would break sysfs ABI.
> 
> The rationale for changing the name (to "advk-INT") in spite of sysfs
> ABI, and thus allowing to convert to a static structure, is that after
> the other changes we made in this series, the IRQ chip is basically
> something different: it no logner generates ERR and PME interrupts 
> (they
> are generated by emulated bridge's rp_irq_chip).

There is no 'is spite of the ABI'. If you don't understand why
we don't break the ABI, you have an even bigger problem.

So NAK to this patch, now and forever. Any change to the structure to
make it read-only must allow the preservation of the existing names
when they are generated by the driver.

         M.
-- 
Jazz is not dead. It just smells funny...


From yu.tu at amlogic.com  Mon Jan 10 01:35:51 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 17:35:51 +0800
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
Message-ID: <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>

Hi Neil,
	Thank you very much for your reply.

On 2022/1/10 17:27, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 10/01/2022 09:55, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate
>> clock makes it easier for the UART driver to be compatible
>> with the baud rate requirements of the UART IP on different
>> meson chips. Add Meson S4 SoC compatible.
>>
>> Yu Tu (5):
>>    dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>>    tty: serial: meson: Request the register region in meson_uart_probe()
>>    tty: serial: meson: The UART baud rate calculation is described using
>>      the common clock code.
>>    tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>>      register writable
>>    tty: serial: meson: Added S4 SOC compatibility.
> 
> Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
> [PATCH V4 0/5] the UART driver compatible with
> [PATCH V4 1/5] dt-bindings: serial: meson: Drop
> [PATCH V4 2/5] tty: serial: meson: Request the register
> ...
> Only the last one is OK.
> 
I saw the subject was a little long, I changed it manually, do I need to 
regenerate and send?
> 
>>
>> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
>> discussed in the email
>> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
>> the DTS before it can be deleted
>> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
>> in the email.
>>
>> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
>>
>>   .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
>>   drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
>>   2 files changed, 177 insertions(+), 77 deletions(-)
>>
> 


From m.szyprowski at samsung.com  Mon Jan 10 01:36:13 2022
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 10 Jan 2022 10:36:13 +0100
Subject: [RFT PATCH] ARM: suspend: switch to swapper_pg_dir before using
 the vmap'ed stack
In-Reply-To: <20220106192645.3913934-1-ardb@kernel.org>
References: <CGME20220106192701eucas1p23a3cfa225cef560be6b85a101263d26f@eucas1p2.samsung.com>
 <20220106192645.3913934-1-ardb@kernel.org>
Message-ID: <5fdf1098-fba8-9cba-b9ca-49fa4296dc89@samsung.com>

Hi Ard,

On 06.01.2022 20:26, Ard Biesheuvel wrote:
> The resume from suspend code switches to the ID map so it can enable the
> MMU. On !LPAE configurations, the ID map carries its own copy of the
> kernel VA range, but this is not kept in sync with swapper_pg_dir, and
> so it may lack the mapping of the kernel mode stack if CONFIG_VMAP_STACK
> is enabled.
>
> So let's switch to swapper_pg_dir right after re-enabling the MMU on
> such configurations. This avoids a crash on resume observed on various
> platforms [0].
>
> [0] https://protect2.fireeye.com/v1/url?k=efa2c314-b039fa16-efa3485b-0cc47a31381a-5dcf992b5d854429&q=1&e=1dac5900-a7aa-40ed-a2f0-9af17ae05bfe&u=https%3A%2F%2Flore.kernel.org%2Flinux-arm-kernel%2F20211122092816.2865873-8-ardb%40kernel.org%2F
>
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> Cc: Jon Hunter <jonathanh at nvidia.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

This fixes the suspend/resume issue observed on ARM 32bit Exynos based 
boards. Thanks!

Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>

Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>

> ---
> Please test with the Kconfig patch [9177/1] reverted.
>
>   arch/arm/kernel/sleep.S | 7 +++++++
>   1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
> index b062b3738bc6..6217ef90feb0 100644
> --- a/arch/arm/kernel/sleep.S
> +++ b/arch/arm/kernel/sleep.S
> @@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
>   ENDPROC(cpu_resume_mmu)
>   	.popsection
>   cpu_resume_after_mmu:
> +#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
> +	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
> +	@ as the ID map does not cover the vmalloc region.
> +	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
> +	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
> +	isb
> +#endif
>   	bl	cpu_init		@ restore the und/abt/irq banked regs
>   	mov	r0, #0			@ return zero on success
>   	ldmfd	sp!, {r4 - r11, pc}

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From narmstrong at baylibre.com  Mon Jan 10 01:38:49 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:38:49 +0100
Subject: [GIT PULL] amlogic fixes for v5.17-rc v2
Message-ID: <746a7f25-1c96-9d27-3a08-e86b2af608ef@baylibre.com>

Hi,

Here's a couple of DT fixes for v5.17-rc1, they fix the UART compatibles of
the ARMv7 Amlogic SoCs and by the way keep earlycon working after [1] has been
applied by greg in the tty branch for 5.17.

Now based on my previous arm DT tag touching these files, sorry for v1.

Neil

[1] https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=ad234e2bac274a43c9fa540bde8cd9f0c627b71f

The following changes since commit 72ccc373b064ae3ac0c5b5f2306069b60ca118df:

  ARM: dts: meson8b: ec100: Fix the pwm regulator supply properties (2021-07-26 10:05:36 +0200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git tags/amlogic-fixes-v5.17-rc-v2

for you to fetch changes up to 3375aa77135f6aeb1107ed839a2050a4118444bc:

  ARM: dts: meson8b: Fix the UART device-tree schema validation (2022-01-10 10:32:51 +0100)

----------------------------------------------------------------
Amlogic fixes for v5.17-rc
- meson6/meson8/meson8b UART compatible fixup to notably fix earlycon

----------------------------------------------------------------
Martin Blumenstingl (3):
      ARM: dts: meson: Fix the UART compatible strings
      ARM: dts: meson8: Fix the UART device-tree schema validation
      ARM: dts: meson8b: Fix the UART device-tree schema validation

 arch/arm/boot/dts/meson.dtsi   |  8 ++++----
 arch/arm/boot/dts/meson8.dtsi  | 24 ++++++++++++------------
 arch/arm/boot/dts/meson8b.dtsi | 24 ++++++++++++------------
 3 files changed, 28 insertions(+), 28 deletions(-)


From narmstrong at baylibre.com  Mon Jan 10 01:43:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:43:02 +0100
Subject: [PATCH V4 0/5] the UART driver compatible with
In-Reply-To: <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <1f4b9288-c7ff-c895-425c-187d058642b9@baylibre.com>
 <a19771e6-d1d4-d1ef-9819-21e2147aad16@amlogic.com>
Message-ID: <d14fdcd5-99c2-6aa0-085e-5355ecc0febf@baylibre.com>

On 10/01/2022 10:35, Yu Tu wrote:
> Hi Neil,
> ????Thank you very much for your reply.
> 
> On 2022/1/10 17:27, Neil Armstrong wrote:
>> [ EXTERNAL EMAIL ]
>>
>> Hi,
>>
>> On 10/01/2022 09:55, Yu Tu wrote:
>>> Using the common Clock code to describe the UART baud rate
>>> clock makes it easier for the UART driver to be compatible
>>> with the baud rate requirements of the UART IP on different
>>> meson chips. Add Meson S4 SoC compatible.
>>>
>>> Yu Tu (5):
>>> ?? dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart.
>>> ?? tty: serial: meson: Request the register region in meson_uart_probe()
>>> ?? tty: serial: meson: The UART baud rate calculation is described using
>>> ???? the common clock code.
>>> ?? tty: serial: meson: Make the bit24 and bit [26,27] of the UART_REG5
>>> ???? register writable
>>> ?? tty: serial: meson: Added S4 SOC compatibility.
>>
>> Weird, the subjects are fine in the cover letter but are all truncated in the email thread:
>> [PATCH V4 0/5] the UART driver compatible with
>> [PATCH V4 1/5] dt-bindings: serial: meson: Drop
>> [PATCH V4 2/5] tty: serial: meson: Request the register
>> ...
>> Only the last one is OK.
>>
> I saw the subject was a little long, I changed it manually, do I need to regenerate and send?

yes please, the mail subject will be the commit title so it must be short but descriptive enough.

"dt-bindings: serial: meson: Drop" is too short.

"dt-bindings: serial: meson: Drop compatible = amlogic,meson-gx-uart" is ok but formulation is wrong,
and remove special characters like "=", "[", "]"...

The best title could be :
"dt-bindings: serial: meson: Drop legacy amlogic,meson-gx-uart compatible"

If the subject it too long, reduce it and enhance the commit message with the details.

Neil

>>
>>>
>>> V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
>>> discussed in the email
>>> V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
>>> the DTS before it can be deleted
>>> V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
>>> in the email.
>>>
>>> Link:https://lore.kernel.org/linux-amlogic/20211230102110.3861-4-yu.tu at amlogic.com/
>>>
>>> ? .../bindings/serial/amlogic,meson-uart.yaml?? |? 10 +-
>>> ? drivers/tty/serial/meson_uart.c?????????????? | 244 ++++++++++++------
>>> ? 2 files changed, 177 insertions(+), 77 deletions(-)
>>>
>>



From narmstrong at baylibre.com  Mon Jan 10 01:45:58 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:45:58 +0100
Subject: [PATCH 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-4-narmstrong@baylibre.com>
 <CAFBinCA-df8Sedqh8Arh_BsMCHYv6-Kb3owrkFBd=W_EY2qxSA@mail.gmail.com>
Message-ID: <6f62eeaa-1feb-274a-e1e8-377c582c428f@baylibre.com>

On 07/01/2022 23:33, Martin Blumenstingl wrote:
>  Hi Neil,
> 
> On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
>> Amlogic AXG SoCs> Should this be "AXG and newer SoCs" or is this really AXG specific?

Yup should be, thanks for noting

> 
> [...]
>> +#define GAMMA_VCOM_POL    7     /* RW */
>> +#define GAMMA_RVS_OUT     6     /* RW */
>> +#define ADR_RDY           5     /* Read Only */
>> +#define WR_RDY            4     /* Read Only */
>> +#define RD_RDY            3     /* Read Only */
>> +#define GAMMA_TR          2     /* RW */
>> +#define GAMMA_SET         1     /* RW */
>> +#define GAMMA_EN          0     /* RW */
>> +
>> +#define H_RD              12
>> +#define H_AUTO_INC        11
>> +#define H_SEL_R           10
>> +#define H_SEL_G           9
>> +#define H_SEL_B           8
> I think all values above can be wrapped in the BIT() macro, then you
> don't need that below.

yep

> 
>> +#define HADR_MSB          7            /* 7:0 */
>> +#define HADR              0            /* 7:0 */
> Here GENMASK(7, 0) can be used for HADR
> 
> Also I think prefixing all macros above with their register name
> (L_GAMMA_CNTL_PORT_ or L_GAMMA_ADDR_PORT_) will make the code easier
> to read.
> 
> [...]
>> +       writel_relaxed(0x8000, priv->io_base + _REG(ENCL_VIDEO_MODE));
> The public S905 datasheet calls 0x8000 ENCL_PX_LN_CNT_SHADOW_EN

Thanks for searching !

> 
>> +       writel_relaxed(0x0418, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> According to the public S905 datasheet this is:
> - BIT(3): ENCL_VIDEO_MODE_ADV_VFIFO_EN
> - BIT(4): ENCL_VIDEO_MODE_ADV_GAIN_HDTV
> - BIT(10): ENCL_SEL_GAMMA_RGB_IN
> 
>> +       writel_relaxed(0x1000, priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
> I don't know the exact name but the 32-bit vendor kernel sources have
> a comment [0] saying that 0x1000 is "bypass filter"
> But maybe we can simply call it ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER

Yep

> 
> [...]
>> +       writel_relaxed(3, priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
> The public S905 datasheet says:
> - BIT(0): USE RGB data from VIU, furthermore a comment in the 3.10
> kernel sources make this more clear: bit[0] 1:RGB, 0:YUV
> - BIT(1): CFG_VIDEO_RGBIN_ZBLK
> 
>> +       /* default black pattern */
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
>> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
>> +       writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
>> +       writel_bits_relaxed(BIT(3), 0, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> same as above: ENCL_VIDEO_MODE_ADV_VFIFO_EN
> 
>> +
>> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
>> +
>> +       writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
>> +       writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR));
> note to self: L_RGB_COEFF_ADDR seems to contain some "magic" value,
> there's no further info in the 3.10 kernel sources or datasheet
> 
>> +       writel_relaxed(0x400, priv->io_base + _REG(L_DITH_CNTL_ADDR));
> According to the public S905 datasheet BIT(10) is DITH10_EN (10-bits
> Dithering to 8 Bits Enable).
> I am not sure if this would belong to the selected video mode/bit depth.
> I'll let other reviewers decide if this is relevant or not because I don't know.


it would probably for pre-GXL when the pipeline was 8bit, would probably need to add
a comment if someone wants to us DPI/LVDS on pre-GXL.

> 
> [...]
>> +       writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
>> +       writel_relaxed(BIT(4) | BIT(5),
>> +                      priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
> the public S905 datasheet states:
> - BIT(4): STV1_SEL (STV1 is frame Signal)
> - BIT(5): STV2_SEL (STV2 is frame Signal)
> This doesn't seem helpful to me though, but maybe you can still create
> preprocessor macros for this (for consistency)?

yep

> 
> [...]
>> +       switch (priv->venc.current_mode) {
>> +       case MESON_VENC_MODE_MIPI_DSI:
>> +               writel_relaxed(0x200,
>> +                              priv->io_base + _REG(VENC_INTCTRL));
> the public S905 datasheet documents this as:
> - BIT(9): ENCP_LNRST_INT_EN (Progressive encoder filed change interrupt enable)
> Please add a preprocessor macro to make it consistent with
> VENC_INTCTRL_ENCI_LNRST_INT_EN which already exists and is used below.

Yep

Thanks for the review :-)

Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:46:16 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:46:16 +0100
Subject: [PATCH 5/6] drm/meson: add DSI encoder
In-Reply-To: <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-6-narmstrong@baylibre.com>
 <CAFBinCCR4zftkvJWgX4T068BRsjVp9YhRbzgdBOR+tuMcGSZ3w@mail.gmail.com>
Message-ID: <b0200846-0346-a65b-ed98-c0c778040cd9@baylibre.com>

On 07/01/2022 23:35, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 3:57 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> 
> [...]
>> +       writel_bits_relaxed(BIT(3), BIT(3), priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> see my comment on patch #3 from this series for BIT(3)
> 

Yep, thanks,

Neil

> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Mon Jan 10 01:51:49 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 10:51:49 +0100
Subject: [PATCH 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-7-narmstrong@baylibre.com>
 <CAFBinCB3+dSjQFRp5CBpGk5Qi8zoxRDRaobuCtXzU6VtM8+ryQ@mail.gmail.com>
Message-ID: <508ea2d7-aee3-9409-023c-638b09d733b0@baylibre.com>

On 07/01/2022 23:49, Martin Blumenstingl wrote:
> Hi Neil,
> 
> some high-level comments from me below.
> 
> On Fri, Jan 7, 2022 at 3:58 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +/*  MIPI DSI Relative REGISTERs Definitions */
>> +/* For MIPI_DSI_TOP_CNTL */
>> +#define BIT_DPI_COLOR_MODE        20
>> +#define BIT_IN_COLOR_MODE         16
>> +#define BIT_CHROMA_SUBSAMPLE      14
>> +#define BIT_COMP2_SEL             12
>> +#define BIT_COMP1_SEL             10
>> +#define BIT_COMP0_SEL              8
>> +#define BIT_DE_POL                 6
>> +#define BIT_HSYNC_POL              5
>> +#define BIT_VSYNC_POL              4
>> +#define BIT_DPICOLORM              3
>> +#define BIT_DPISHUTDN              2
>> +#define BIT_EDPITE_INTR_PULSE      1
>> +#define BIT_ERR_INTR_PULSE         0
> Why not use BIT() and GENMASK() for these and prefixing them with
> MIPI_DSI_TOP_CNTL_?
> That would make them consistent with other parts of the meson sub-driver.

Yeah it was a lousy copy-paste from vendor driver, and I was lazy, but I'll fix this.

> 
> [...]
>> +static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
>> +{
>> +       writel_relaxed((1 << 4) | (1 << 5) | (0 << 6),
>> +                      mipi_dsi->base + MIPI_DSI_TOP_CNTL);
> please use the macros from above
> 
>> +       writel_bits_relaxed(0xf, 0xf, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
>> +       writel_bits_relaxed(0xf, 0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
> 
> [...]
>> +       phy_power_on(mipi_dsi->phy);
> Please propagate the error code here.
> Also shouldn't this go to a new dw_mipi_dsi_phy_power_on() as the PHY
> driver uses the updated settings from phy_configure only in it's
> .power_on callback?

Good point, let me check that.

> 
> [...]
>> +       phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
> please propagate the error code here as the PHY driver has some
> explicit code to return an error in it's .phy_configure callback
> 
> [...]
>> +       phy_init(mipi_dsi->phy);
> please propagate the error code here
> 
> [...]
>> +       phy_exit(mipi_dsi->phy);
> please propagate the error code here

ok for the 3

> 
> [...]
>> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> +       mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
> other parts of the meson DRM driver have been converted to use
> devm_platform_ioremap_resource()
> I suggest updating this as well to simplify the code here

Yep, again lazyness

> 
> [...]
>> +       mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
>> +       if (IS_ERR(mipi_dsi->phy)) {
>> +               ret = PTR_ERR(mipi_dsi->phy);
>> +               dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
>> +               return ret;
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->phy, "failed to
> get mipi dphy\n");
> 
> [...]
>> +       mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
>> +       if (IS_ERR(mipi_dsi->px_clk)) {
>> +               dev_err(&pdev->dev, "Unable to get PLL clk\n");
>> +               return PTR_ERR(mipi_dsi->px_clk);
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(mipi_dsi->px_clk, "Unable
> to get PLL clk\n");
> Also should it say s/PLL clk/px clock/?
> 
> [...]
>> +       top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
>> +       if (IS_ERR(top_rst)) {
>> +               ret = PTR_ERR(top_rst);
>> +
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
>> +
>> +               return ret;
> you can simplify this with:
>   return dev_err_probe(&pdev->dev, PTR_ERR(top_rst, "Unable to get
> reset control\n");
> 
> [...]
>> +       mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
>> +       if (IS_ERR(mipi_dsi->dmd)) {
>> +               ret = PTR_ERR(mipi_dsi->dmd);
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&pdev->dev,
>> +                               "Failed to probe dw_mipi_dsi: %d\n", ret);
> you can simplify this with:
>   dev_err_probe(&pdev->dev, ret, "Failed to probe dw_mipi_dsi\n");
>

Again 4 lazyness effects, will fix !

Thanks,
Neil


> 
> Best regards,
> Martin
> 



From Jonathan.Cameron at Huawei.com  Mon Jan 10 01:55:43 2022
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 10 Jan 2022 09:55:43 +0000
Subject: [PATCH] dt-bindings: vendor-prefixes: add Huawei
In-Reply-To: <20220109132311.GA2827@standask-GA-A55M-S2HP>
References: <20220109132311.GA2827@standask-GA-A55M-S2HP>
Message-ID: <20220110095543.00001ac0@Huawei.com>

On Sun, 9 Jan 2022 14:23:11 +0100
Stanislav Jakubek <stano.jakubek at gmail.com> wrote:

> Add vendor prefix for Huawei (https://www.huawei.com/en/)

Patch description should say why...  Is there an existing binding
using a huawei vendor prefix?

Thanks,

Jonathan


> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index a13d6a19c2b4..18ffa2d7379f 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -515,6 +515,8 @@ patternProperties:
>      description: HannStar Display Co.
>    "^holtek,.*":
>      description: Holtek Semiconductor, Inc.
> +  "^huawei,.*":
> +    description: Huawei Technologies Co., Ltd.
>    "^hugsun,.*":
>      description: Shenzhen Hugsun Technology Co. Ltd.
>    "^hwacom,.*":



From angelogioacchino.delregno at collabora.com  Mon Jan 10 02:01:13 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 11:01:13 +0100
Subject: [PATCH v1 1/2] dt-bindings: iio: adc: Add compatible for Mediatek
 MT8186
In-Reply-To: <20220110084841.575-1-guodong.liu@mediatek.com>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
Message-ID: <02a18741-2015-73d2-9a5c-a28c1b15894f@collabora.com>

Il 10/01/22 09:48, Guodong Liu ha scritto:
> This commit adds dt-binding documentation of auxadc for Mediatek MT8186 SoC
> Platform.
> 
> Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   .../devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml      | 1 +
>   1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
> index b939f9652e3a..65581ad4b816 100644
> --- a/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
> @@ -34,6 +34,7 @@ properties:
>         - items:
>             - enum:
>                 - mediatek,mt8183-auxadc
> +              - mediatek,mt8186-auxadc
>                 - mediatek,mt8195-auxadc
>                 - mediatek,mt8516-auxadc
>             - const: mediatek,mt8173-auxadc
> 


From angelogioacchino.delregno at collabora.com  Mon Jan 10 02:01:28 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 11:01:28 +0100
Subject: [PATCH v1 2/2] iio: adc: mt8186: Add compatible node for mt8186
In-Reply-To: <20220110084841.575-2-guodong.liu@mediatek.com>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
 <20220110084841.575-2-guodong.liu@mediatek.com>
Message-ID: <292950d7-d057-4e66-5d0d-a5144f50f2ce@collabora.com>

Il 10/01/22 09:48, Guodong Liu ha scritto:
> This commit adds mt8186 compatible node.
> 
> Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/iio/adc/mt6577_auxadc.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
> index d4fccd52ef08..fb08d761589a 100644
> --- a/drivers/iio/adc/mt6577_auxadc.c
> +++ b/drivers/iio/adc/mt6577_auxadc.c
> @@ -46,6 +46,11 @@ struct mt6577_auxadc_device {
>   	const struct mtk_auxadc_compatible *dev_comp;
>   };
>   
> +static const struct mtk_auxadc_compatible mt8186_compat = {
> +	.sample_data_cali = false,
> +	.check_global_idle = false,
> +};
> +
>   static const struct mtk_auxadc_compatible mt8173_compat = {
>   	.sample_data_cali = false,
>   	.check_global_idle = true,
> @@ -334,6 +339,7 @@ static const struct of_device_id mt6577_auxadc_of_match[] = {
>   	{ .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat},
>   	{ .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat},
>   	{ .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat},
> +	{ .compatible = "mediatek,mt8186-auxadc", .data = &mt8186_compat},
>   	{ .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat},
>   	{ }
>   };
> 


From angelogioacchino.delregno at collabora.com  Mon Jan 10 02:09:04 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 11:09:04 +0100
Subject: [PATCH v1 2/2] pinctrl: add pinctrl driver on mt8186
In-Reply-To: <20220110073111.31306-2-guodong.liu@mediatek.com>
References: <20220110073111.31306-1-guodong.liu@mediatek.com>
 <20220110073111.31306-2-guodong.liu@mediatek.com>
Message-ID: <c7d7fbe3-1fe2-8765-5577-b4b06cebe9b6@collabora.com>

Il 10/01/22 08:31, Guodong Liu ha scritto:
> This commit includes pinctrl driver for mt8186.
> 
> Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
> ---
>   drivers/pinctrl/mediatek/Kconfig              |    6 +
>   drivers/pinctrl/mediatek/Makefile             |    1 +
>   drivers/pinctrl/mediatek/pinctrl-mt8186.c     | 1313 ++++++++++
>   drivers/pinctrl/mediatek/pinctrl-mtk-mt8186.h | 2186 +++++++++++++++++
>   4 files changed, 3506 insertions(+)
>   create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8186.c
>   create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8186.h
> 
> diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
> index 66db4ac5d169..2cb5963cef4c 100644
> --- a/drivers/pinctrl/mediatek/Kconfig
> +++ b/drivers/pinctrl/mediatek/Kconfig
> @@ -147,6 +147,12 @@ config PINCTRL_MT8183
>   	default ARM64 && ARCH_MEDIATEK
>   	select PINCTRL_MTK_PARIS
>   
> +config PINCTRL_MT8186
> +	bool "Mediatek MT8186 pin control"
> +	depends on OF
> +	depends on ARM64 || COMPILE_TEST

Like the other MTK pinctrl drivers, please add:
	default ARM64 && ARCH_MEDIATEK


With that fixed,

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> +	select PINCTRL_MTK_PARIS
> +
>   config PINCTRL_MT8192
>   	bool "Mediatek MT8192 pin control"
>   	depends on OF
> diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
> index 1e3931d924e7..29018d6ad0de 100644
> --- a/drivers/pinctrl/mediatek/Makefile
> +++ b/drivers/pinctrl/mediatek/Makefile
> @@ -21,6 +21,7 @@ obj-$(CONFIG_PINCTRL_MT7986)	+= pinctrl-mt7986.o
>   obj-$(CONFIG_PINCTRL_MT8167)	+= pinctrl-mt8167.o
>   obj-$(CONFIG_PINCTRL_MT8173)	+= pinctrl-mt8173.o
>   obj-$(CONFIG_PINCTRL_MT8183)	+= pinctrl-mt8183.o
> +obj-$(CONFIG_PINCTRL_MT8186)	+= pinctrl-mt8186.o
>   obj-$(CONFIG_PINCTRL_MT8192)	+= pinctrl-mt8192.o
>   obj-$(CONFIG_PINCTRL_MT8195)    += pinctrl-mt8195.o
>   obj-$(CONFIG_PINCTRL_MT8365)	+= pinctrl-mt8365.o
> diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8186.c b/drivers/pinctrl/mediatek/pinctrl-mt8186.c
> new file mode 100644
> index 000000000000..1e550b15b9d4
> --- /dev/null
> +++ b/drivers/pinctrl/mediatek/pinctrl-mt8186.c
> @@ -0,0 +1,1313 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*



From kabel at kernel.org  Mon Jan 10 02:23:01 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Mon, 10 Jan 2022 11:23:01 +0100
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a
 static driver structure
In-Reply-To: <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
 <20220110015018.26359-24-kabel@kernel.org>
 <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
Message-ID: <20220110112301.7e13c716@thinkpad>

On Mon, 10 Jan 2022 09:28:39 +0000
Marc Zyngier <maz at kernel.org> wrote:

> On 2022-01-10 01:50, Marek Beh?n wrote:
> > Marc Zyngier says [1] that we should use struct irq_chip as a global
> > static struct in the driver. Even though the structure currently
> > contains a dynamic member (parent_device), Marc says [2] that he plans
> > to kill it and make the structure completely static.
> > 
> > We have already converted others irq_chip structures in this driver in
> > this way, but we omitted this one because the .name member is
> > dynamically created from device's name, and the name is displayed in
> > sysfs, so changing it would break sysfs ABI.
> > 
> > The rationale for changing the name (to "advk-INT") in spite of sysfs
> > ABI, and thus allowing to convert to a static structure, is that after
> > the other changes we made in this series, the IRQ chip is basically
> > something different: it no logner generates ERR and PME interrupts 
> > (they
> > are generated by emulated bridge's rp_irq_chip).  
> 
> There is no 'is spite of the ABI'. If you don't understand why
> we don't break the ABI, you have an even bigger problem.
> 
> So NAK to this patch, now and forever. Any change to the structure to
> make it read-only must allow the preservation of the existing names
> when they are generated by the driver.

Dear Marc,

That's why I put it as a last patch here :)

I have the questions

1) the first is that this driver has only ever been used on Armada 37xx,
   where there has always been only one PCIe controller, and it's name
   always was d0070000.pcie, so the irq_chip was always called
   d0070000.pcie-irq.
   So we could theoretically infer from config options if we are
   building for Armada 37xx: if ARM64 and ARMADA_37XX_CLK config options
   are enabled, make the name d0070000.pcie-irq, otherwise advk-INT ?

2) I tried to look for the name d0070000.pcie-irq in /proc and /sysfs,
   but couldn't find it there (not in /proc/interrupts nor anywhere
   else). It is possible that I omitted something, or that with other
   PCIe card it will show up when corresponding driver is loaded.
   But theoretically, if I could prove that until now this never
   appeared anywhere in sysfs for some reason, then we could change it,
   right? Becuase that way it isn't sysfs ABI change.

Thanks.

Marek


From rppt at kernel.org  Mon Jan 10 02:27:19 2022
From: rppt at kernel.org (Mike Rapoport)
Date: Mon, 10 Jan 2022 12:27:19 +0200
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <20220104202227.2903605-9-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
Message-ID: <YdwKB3SfF7hkB9Xv@kernel.org>

Hi,

On Tue, Jan 04, 2022 at 01:22:27PM -0700, Yu Zhao wrote:
> Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> 
> Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention.
> Compared with the size-based approach, e.g., [1], this time-based
> approach has the following advantages:
> 1) It's easier to configure because it's agnostic to applications and
>    memory sizes.
> 2) It's more reliable because it's directly wired to the OOM killer.
> 
> Add /sys/kernel/debug/lru_gen for working set estimation and proactive
> reclaim. Compared with the page table-based approach and the PFN-based
> approach, e.g., mm/damon/[vp]addr.c, this lruvec-based approach has
> the following advantages:
> 1) It offers better choices because it's aware of memcgs, NUMA nodes,
>    shared mappings and unmapped page cache.
> 2) It's more scalable because it's O(nr_hot_evictable_pages), whereas
>    the PFN-based approach is O(nr_total_pages).
> 
> Add /sys/kernel/debug/lru_gen_full for debugging.
> 
> [1] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/
> 
> Signed-off-by: Yu Zhao <yuzhao at google.com>
> Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> ---
>  Documentation/vm/index.rst        |   1 +
>  Documentation/vm/multigen_lru.rst |  62 +++++

The description of user visible interfaces should go to
Documentation/admin-guide/mm

Documentation/vm/multigen_lru.rst should have contained design description
and the implementation details and it would be great to actually have such
document.

>  include/linux/nodemask.h          |   1 +
>  mm/vmscan.c                       | 415 ++++++++++++++++++++++++++++++
>  4 files changed, 479 insertions(+)
>  create mode 100644 Documentation/vm/multigen_lru.rst
> 
> diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
> index 6f5ffef4b716..f25e755b4ff4 100644
> --- a/Documentation/vm/index.rst
> +++ b/Documentation/vm/index.rst
> @@ -38,3 +38,4 @@ algorithms.  If you are looking for advice on simply allocating memory, see the
>     unevictable-lru
>     z3fold
>     zsmalloc
> +   multigen_lru
> diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
> new file mode 100644
> index 000000000000..6f9e0181348b
> --- /dev/null
> +++ b/Documentation/vm/multigen_lru.rst
> @@ -0,0 +1,62 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +=====================
> +Multigenerational LRU
> +=====================
> +
> +Quick start
> +===========
> +Runtime configurations
> +----------------------
> +:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
> + feature wasn't enabled by default.

Required for what? This sentence seem to lack context. Maybe add an
overview what is Multigenerational LRU so that users will have an idea what
these knobs control.

> +
> +Recipes
> +=======

Some more context here will be also helpful.

> +Personal computers
> +------------------
> +:Thrashing prevention: Write ``N`` to
> + ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
> + ``N`` milliseconds from getting evicted. The OOM killer is invoked if
> + this working set can't be kept in memory. Based on the average human
> + detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
> + lags due to thrashing. Larger values like ``N=3000`` make lags less
> + noticeable at the cost of more OOM kills.
> +
> +Data centers
> +------------
> +:Debugfs interface: ``/sys/kernel/debug/lru_gen`` has the following
> + format:
> + ::
> +
> +   memcg  memcg_id  memcg_path
> +     node  node_id
> +       min_gen  birth_time  anon_size  file_size
> +       ...
> +       max_gen  birth_time  anon_size  file_size
> +
> + ``min_gen`` is the oldest generation number and ``max_gen`` is the
> + youngest generation number. ``birth_time`` is in milliseconds.
> + ``anon_size`` and ``file_size`` are in pages.

And what does oldest and youngest generations mean from the user
perspective?

> +
> + This file also accepts commands in the following subsections.
> + Multiple command lines are supported, so does concatenation with
> + delimiters ``,`` and ``;``.
> +
> + ``/sys/kernel/debug/lru_gen_full`` contains additional stats for
> + debugging.
> +
> +:Working set estimation: Write ``+ memcg_id node_id max_gen
> + [can_swap [full_scan]]`` to ``/sys/kernel/debug/lru_gen`` to trigger
> + the aging. It scans PTEs for accessed pages and promotes them to the
> + youngest generation ``max_gen``. Then it creates a new generation
> + ``max_gen+1``. Set ``can_swap`` to 1 to scan for accessed anon pages
> + when swap is off. Set ``full_scan`` to 0 to reduce the overhead as
> + well as the coverage when scanning PTEs.
> +
> +:Proactive reclaim: Write ``- memcg_id node_id min_gen [swappiness
> + [nr_to_reclaim]]`` to ``/sys/kernel/debug/lru_gen`` to trigger the
> + eviction. It evicts generations less than or equal to ``min_gen``.
> + ``min_gen`` should be less than ``max_gen-1`` as ``max_gen`` and
> + ``max_gen-1`` aren't fully aged and therefore can't be evicted. Use
> + ``nr_to_reclaim`` to limit the number of pages to evict.

...

-- 
Sincerely yours,
Mike.


From mark.rutland at arm.com  Mon Jan 10 02:27:59 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 10 Jan 2022 10:27:59 +0000
Subject: [PATCH] arm64: atomics: Dereference matching size
In-Reply-To: <20220107232746.1540130-1-keescook@chromium.org>
References: <20220107232746.1540130-1-keescook@chromium.org>
Message-ID: <YdwKLwvDRfc59c8U@FVFF77S0Q05N>

Hi Kees,

On Fri, Jan 07, 2022 at 03:27:46PM -0800, Kees Cook wrote:
> When building with -Warray-bounds (which is desired to be enabled
> globally), the following warning is generated:
> 
> In file included from ./arch/arm64/include/asm/lse.h:16,
>                  from ./arch/arm64/include/asm/cmpxchg.h:14,
>                  from ./arch/arm64/include/asm/atomic.h:16,
>                  from ./include/linux/atomic.h:7,
>                  from ./include/asm-generic/bitops/atomic.h:5,
>                  from ./arch/arm64/include/asm/bitops.h:25,
>                  from ./include/linux/bitops.h:33,
>                  from ./include/linux/kernel.h:22,
>                  from kernel/printk/printk.c:22:
> ./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
>   247 |         asm volatile(                                                   \
>       |         ^~~
> ./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
>   266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
>       | ^~~~~~~~~~~~~~
> kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
>  3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
>       |                 ^~~~~~~~~~~~~~~~~~~~
> 
> This is due to the compiler seeing an unsigned long * cast against
> something (atomic_t) that is int sized. Replace the cast with the
> matching size cast. This results in no change in binary output.

Just to check, I assume both GCC and Clang are happy with this applied?

I recall that (historically at least) clang would warn about size mismatches
for inline assembly and would sometimes require more care. I don't see anythign
for which that would matter, but I just want to check.

> Cc: Will Deacon <will at kernel.org>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Boqun Feng <boqun.feng at gmail.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Kees Cook <keescook at chromium.org>
> ---
>  arch/arm64/include/asm/atomic_lse.h | 2 +-
>  arch/arm64/include/asm/cmpxchg.h    | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
> index d955ade5df7c..5d460f6b7675 100644
> --- a/arch/arm64/include/asm/atomic_lse.h
> +++ b/arch/arm64/include/asm/atomic_lse.h
> @@ -249,7 +249,7 @@ __lse__cmpxchg_case_##name##sz(volatile void *ptr,			\
>  	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
>  	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
>  	"	mov	%" #w "[ret], %" #w "[tmp]"			\
> -	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
> +	: [ret] "+r" (x0), [v] "+Q" (*(u##sz *)ptr),			\
>  	  [tmp] "=&r" (tmp)						\
>  	: [old] "r" (x1), [new] "r" (x2)				\
>  	: cl);								\

It might be worth nothing that __ll_sc__cmpxchg_case_##name##sz already uses
the same constraint:

	[v] "+Q" (*(u##sz *)ptr

... since that explains why we only need to update the LSE form and not the
LL/SC form, and indicates that this is unlikely to be problematic.

Either way:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Thanks,
Mark.

> diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
> index f9bef42c1411..497acf134d99 100644
> --- a/arch/arm64/include/asm/cmpxchg.h
> +++ b/arch/arm64/include/asm/cmpxchg.h
> @@ -243,7 +243,7 @@ static inline void __cmpwait_case_##sz(volatile void *ptr,		\
>  	"	cbnz	%" #w "[tmp], 1f\n"				\
>  	"	wfe\n"							\
>  	"1:"								\
> -	: [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr)		\
> +	: [tmp] "=&r" (tmp), [v] "+Q" (*(u##sz *)ptr)			\
>  	: [val] "r" (val));						\
>  }
>  
> -- 
> 2.30.2
> 


From tony at atomide.com  Mon Jan 10 02:30:54 2022
From: tony at atomide.com (Tony Lindgren)
Date: Mon, 10 Jan 2022 12:30:54 +0200
Subject: [PATCH] dt-bindings: clock: Add binding for TI clksel
In-Reply-To: <CAL_JsqLek5SOypZhTxpLK13x2HEYbLbYYotLGOfM-JTb=QE-Eg@mail.gmail.com>
References: <20211217113640.59840-1-tony@atomide.com>
 <YcIZNfTn37uNbj0F@robh.at.kernel.org>
 <YcLElm04V47kP0Z9@atomide.com>
 <CAL_JsqLek5SOypZhTxpLK13x2HEYbLbYYotLGOfM-JTb=QE-Eg@mail.gmail.com>
Message-ID: <YdwK3haVDCxyIioo@atomide.com>

* Rob Herring <robh at kernel.org> [220104 22:06]:
> On Wed, Dec 22, 2021 at 12:24 AM Tony Lindgren <tony at atomide.com> wrote:
> >
> > Hi,
> >
> > * Rob Herring <robh at kernel.org> [211221 18:13]:
> > > On Fri, Dec 17, 2021 at 01:36:40PM +0200, Tony Lindgren wrote:
> > > > +additionalProperties: true
> > >
> > > Like what properties?
> > >
> > > true is only used for common, incomplete schemas referenced by device
> > > schemas.
> >
> > There is a collection of the current component clock child nodes for each
> > clksel instance. I got warnings with "additionalProperties: false", but
> > maybe the child clock nodes need to be somehow specified in the binding?
> 
> If everything else is a child node, then you can do:
> 
> additionalProperties:
>   type: object

OK thanks will do, the additional properties are always child nodes.

Regards,

Tony


From Conor.Dooley at microchip.com  Mon Jan 10 02:32:45 2022
From: Conor.Dooley at microchip.com (Conor.Dooley at microchip.com)
Date: Mon, 10 Jan 2022 10:32:45 +0000
Subject: [PATCH v2 0/1] soc: add polarfire soc system controller
In-Reply-To: <20211220144413.6798-1-conor.dooley@microchip.com>
References: <20211220144413.6798-1-conor.dooley@microchip.com>
Message-ID: <6924ec40-d253-0370-9e51-49552855f56d@microchip.com>

On 20/12/2021 14:44, conor.dooley at microchip.com wrote:
> From: Conor Dooley <conor.dooley at microchip.com>
> 
> Changes since v1:
> - system controller is now an mfd
> - parentage is now used to get the device node on the system controller
> - mpfs_sys_controller_get() now updates the reference count
> - "polarfire-soc" in compat string changed to "mpfs"
> 
> Depends on [0] to change the compat string in the dt-binding.
> 
Hey Arnd, if you could take a look at this it'd be great
> @Arnd Bergmann:
> I sent the first version of this patch in November & you (along with
> requesting referencing counting) wanted me to check if the driver was
> bound to the specific device [1]. I have taken another look at this
> driver now and I am still none the wiser as to how I should do this.
> 
> As I said in the previous thread, I checked other drivers but was not
> able to find any examples of of_find_device_by_node() where the binding
> of the driver was checked. If you could point me towards an example
> that would be great.
> 
> Thanks,
> Conor.
> 
> For some extra context, the device tree entry for this driver will look
> like:
> 
> syscontroller: syscontroller {
> 	compatible = "microchip,mpfs-sys-controller", "simple-mfd";
> 	mboxes = <&mbox 0>;
> 
> 	hwrandom: hwrandom {
> 		compatible = "microchip,mpfs-rng";
> 	};
> 
> 	sysserv: sysserv {
> 		compatible = "microchip,mpfs-generic-service";
> 	};
> };
> 
> and the mpfs_sys_controller_get() function is called in, for example,
> the mpfs-rng driver:
> 
> node_pointer = of_get_parent(dev->of_node);
> if (!node_pointer) {
> 	dev_err(&pdev->dev,
> 		"Failed to find mpfs system controller node\n");
> 	return -ENODEV;
> }
> 
> rng_priv->sys_controller =  mpfs_sys_controller_get(&pdev->dev, node_pointer);
> 
> [0] https://lore.kernel.org/linux-riscv/CAMuHMdWTjrAiHosU0cGyJYkK=9JzNgHb=tjHXPdYxTWmkVzeYQ at mail.gmail.com/T/
> [1] https://lore.kernel.org/linux-riscv/CAK8P3a1m_LhOg5JGMqPz6sohJa2hPZ3GN-jQDPxigZ5DaqAGxQ at mail.gmail.com/
> 
> Conor Dooley (1):
>    soc: add polarfire soc system controller
> 
>   drivers/soc/Kconfig                         |   1 +
>   drivers/soc/Makefile                        |   1 +
>   drivers/soc/microchip/Kconfig               |  10 ++
>   drivers/soc/microchip/Makefile              |   1 +
>   drivers/soc/microchip/mpfs-sys-controller.c | 169 ++++++++++++++++++++
>   include/soc/microchip/mpfs.h                |   3 +-
>   6 files changed, 184 insertions(+), 1 deletion(-)
>   create mode 100644 drivers/soc/microchip/Kconfig
>   create mode 100644 drivers/soc/microchip/Makefile
>   create mode 100644 drivers/soc/microchip/mpfs-sys-controller.c
> 


From lee.jones at linaro.org  Mon Jan 10 02:33:23 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Jan 2022 10:33:23 +0000
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <20220107031905.2406176-1-robh@kernel.org>
References: <20220107031905.2406176-1-robh@kernel.org>
Message-ID: <YdwLc2ZTERBoXgxR@google.com>

On Thu, 06 Jan 2022, Rob Herring wrote:

> 'interrupt-parent' is never required as it can be in a parent node or a
> parent node itself can be an interrupt provider. Where exactly it lives is
> outside the scope of a binding schema.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -

Acked-by: Lee Jones <lee.jones at linaro.org>

>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
>  7 files changed, 15 deletions(-)

-- 
Lee Jones [???]
Principal Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From alain.volmat at foss.st.com  Mon Jan 10 02:37:39 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Mon, 10 Jan 2022 11:37:39 +0100
Subject: [PATCH] media: stm32: dcmi: create a dma scatterlist based on DMA
 max_sg_burst value
Message-ID: <20220110103739.118426-1-alain.volmat@foss.st.com>

Prior to submitting a transfer to the DMA, the client should first check
the capabilities of the DMA channel in term of maximum of each segment.
This is given by the max_sg_burst value reported by dma_get_slave_caps API.
Based on that, if the transfer is larger than what can be handled by the
DMA channel, we split the transfer into several scatterlist elements.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/media/platform/stm32/stm32-dcmi.c | 47 ++++++++++++++++++-----
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index e1b17c05229c..ee170e999a88 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -113,7 +113,7 @@ struct dcmi_framesize {
 struct dcmi_buf {
 	struct vb2_v4l2_buffer	vb;
 	bool			prepared;
-	dma_addr_t		paddr;
+	struct sg_table		sgt;
 	size_t			size;
 	struct list_head	list;
 };
@@ -157,6 +157,7 @@ struct stm32_dcmi {
 	enum state			state;
 	struct dma_chan			*dma_chan;
 	dma_cookie_t			dma_cookie;
+	u32				dma_max_burst;
 	u32				misr;
 	int				errors_count;
 	int				overrun_count;
@@ -326,13 +327,11 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi,
 	mutex_lock(&dcmi->dma_lock);
 
 	/* Prepare a DMA transaction */
-	desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr,
-					   buf->size,
+	desc = dmaengine_prep_slave_sg(dcmi->dma_chan, buf->sgt.sgl, buf->sgt.nents,
 					   DMA_DEV_TO_MEM,
 					   DMA_PREP_INTERRUPT);
 	if (!desc) {
-		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n",
-			__func__, &buf->paddr, buf->size);
+		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_sg failed\n", __func__);
 		mutex_unlock(&dcmi->dma_lock);
 		return -EINVAL;
 	}
@@ -524,6 +523,10 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb);
 	unsigned long size;
+	unsigned int num_sgs = 1;
+	dma_addr_t dma_buf;
+	struct scatterlist *sg;
+	int i, ret;
 
 	size = dcmi->fmt.fmt.pix.sizeimage;
 
@@ -537,15 +540,33 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
 
 	if (!buf->prepared) {
 		/* Get memory addresses */
-		buf->paddr =
-			vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
 		buf->size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-		buf->prepared = true;
+		if (buf->size > dcmi->dma_max_burst)
+			num_sgs = DIV_ROUND_UP(buf->size, dcmi->dma_max_burst);
 
-		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
+		ret = sg_alloc_table(&buf->sgt, num_sgs, GFP_ATOMIC);
+		if (ret) {
+			dev_err(dcmi->dev, "sg table alloc failed\n");
+			return ret;
+		}
+
+		dma_buf = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
 
 		dev_dbg(dcmi->dev, "buffer[%d] phy=%pad size=%zu\n",
-			vb->index, &buf->paddr, buf->size);
+			vb->index, &dma_buf, buf->size);
+
+		for_each_sg(buf->sgt.sgl, sg, num_sgs, i) {
+			size_t bytes = min_t(size_t, size, dcmi->dma_max_burst);
+
+			sg_dma_address(sg) = dma_buf;
+			sg_dma_len(sg) = bytes;
+			dma_buf += bytes;
+			size -= bytes;
+		}
+
+		buf->prepared = true;
+
+		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
 	}
 
 	return 0;
@@ -1866,6 +1887,7 @@ static int dcmi_probe(struct platform_device *pdev)
 	struct stm32_dcmi *dcmi;
 	struct vb2_queue *q;
 	struct dma_chan *chan;
+	struct dma_slave_caps caps;
 	struct clk *mclk;
 	int irq;
 	int ret = 0;
@@ -1953,6 +1975,11 @@ static int dcmi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dcmi->dma_max_burst = UINT_MAX;
+	ret = dma_get_slave_caps(chan, &caps);
+	if (!ret && caps.max_sg_burst)
+		dcmi->dma_max_burst = caps.max_sg_burst	* DMA_SLAVE_BUSWIDTH_4_BYTES;
+
 	spin_lock_init(&dcmi->irqlock);
 	mutex_init(&dcmi->lock);
 	mutex_init(&dcmi->dma_lock);
-- 
2.25.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:09 +0800
Subject: [PATCH V5 0/5] The UART driver compatible with
Message-ID: <20220110104214.25321-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  dt-bindings: serial: meson: Drop legacy compatible.
  tty: serial: meson: Move request the register region.
  tty: serial: meson: Using the common clock code describe.
  tty: serial: meson: Make some bit of the REG5 register writable.
  tty: serial: meson: Added S4 SOC compatibility.

V4 -> V5: Change error format.
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email

Link:https://lore.kernel.org/linux-amlogic/20220110085604.18042-1-yu.tu at amlogic.com/

 .../bindings/serial/amlogic,meson-uart.yaml   |  10 +-
 drivers/tty/serial/meson_uart.c               | 244 ++++++++++++------
 2 files changed, 177 insertions(+), 77 deletions(-)

-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:10 +0800
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-2-yu.tu@amlogic.com>

Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
compatible. Don't differentiate between GXBB, GXL and G12A which
have different revisions of the UART IP. So it's split into
GXBB,GXL and G12A.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index 72e8868db3e0..ad9f1f4537a0 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -28,7 +28,10 @@ properties:
               - amlogic,meson6-uart
               - amlogic,meson8-uart
               - amlogic,meson8b-uart
-              - amlogic,meson-gx-uart
+              - amlogic,meson-gx-uart # deprecated, use revision specific property below
+              - amlogic,meson-gxbb-uart
+              - amlogic,meson-gxl-uart
+              - amlogic,meson-g12a-uart
               - amlogic,meson-s4-uart
           - const: amlogic,meson-ao-uart
       - description: Everything-Else power domain UART controller
@@ -36,7 +39,10 @@ properties:
           - amlogic,meson6-uart
           - amlogic,meson8-uart
           - amlogic,meson8b-uart
-          - amlogic,meson-gx-uart
+          - amlogic,meson-gx-uart # deprecated, use revision specific property below
+          - amlogic,meson-gxbb-uart
+          - amlogic,meson-gxl-uart
+          - amlogic,meson-g12a-uart
           - amlogic,meson-s4-uart
 
   reg:
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:11 +0800
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register region.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-3-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe
and will make it easier to integrate the common clock code
which will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:12 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:12 +0800
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
 1 file changed, 163 insertions(+), 61 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..1004fd0b0c9e 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,13 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct uart_port	port;
+	struct clk		*pclk;
+	struct clk		*baud_clk;
+	bool			use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
 static int meson_uart_startup(struct uart_port *port)
 {
 	u32 val;
-	int ret = 0;
+	int ret;
 
-	val = readl(port->membase + AML_UART_CONTROL);
-	val |= AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
-	val &= ~AML_UART_CLEAR_ERR;
-	writel(val, port->membase + AML_UART_CONTROL);
+	meson_uart_reset(port);
 
+	val = readl(port->membase + AML_UART_CONTROL);
 	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
 	writel(val, port->membase + AML_UART_CONTROL);
 
@@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
+	clk_disable_unprepare(private_data->pclk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->pclk);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret) {
+		clk_disable_unprepare(private_data->pclk);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
+#define CLK_NAME(name) \
+({\
+	char clk_name[32];\
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
+	clk_name;\
+})
+
+static struct clk_div_table xtal_div_table[] = {
+	{ 0, 3  },
+	{ 1, 1  },
+	{ 2, 2  },
+	{ 3, 2  },
+};
+
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk = NULL;
-	int ret;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
+	private_data->pclk = devm_clk_get(port->dev, "pclk");
+	if (IS_ERR(private_data->pclk))
+		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
+				     "Failed to get the 'pclk' clock\n");
 
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
 	}
 
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
-
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
-{
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
-
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
-
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							CLK_NAME(xtal_div),
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       CLK_NAME(clk81_div4),
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					CLK_NAME(use_xtal),
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	hw = devm_clk_hw_register_divider(port->dev,
+					  CLK_NAME(baud_div),
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
@@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
 		return -EBUSY;
 	}
 
-	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
-	if (!port)
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
 		return -ENOMEM;
 
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
+
+	port = &private_data->port;
+
 	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
-
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
 	port->mapsize = resource_size(res_mem);
@@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
 
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
 
@@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxbb-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gxl-uart",
+		.data = (void *)true,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-uart",
+		.data = (void *)true,
+	},
+	/*
+	 * deprecated, don't use anymore because it doesn't differentiate
+	 * between GXBB, GXL and G12A which have different revisions
+	 * of the UART IP.
+	 */
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)false,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:13 +0800
Subject: [PATCH V5 4/5] tty: serial: meson: Make some bit of the REG5 register
 writable.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 1004fd0b0c9e..fd128878e91a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -693,7 +693,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -719,7 +719,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 10 02:42:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 10 Jan 2022 18:42:14 +0800
Subject: [PATCH V5 5/5] tty: serial: meson: Added S4 SOC compatibility.
In-Reply-To: <20220110104214.25321-1-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
Message-ID: <20220110104214.25321-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index fd128878e91a..d6aa04cc31ba 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -863,6 +863,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-g12a-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	/*
 	 * deprecated, don't use anymore because it doesn't differentiate
 	 * between GXBB, GXL and G12A which have different revisions
-- 
2.33.1



From alexandru.elisei at arm.com  Mon Jan 10 02:48:41 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 10 Jan 2022 10:48:41 +0000
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
In-Reply-To: <20220110054042.1079932-1-reijiw@google.com>
References: <20220110054042.1079932-1-reijiw@google.com>
Message-ID: <YdwPCcZWD8Uc1eej@monolith.localdoman>

Hi Reiji,

On Sun, Jan 09, 2022 at 09:40:41PM -0800, Reiji Watanabe wrote:
> vcpu_allowed_register_width() checks if all the VCPUs are either
> all 32bit or all 64bit.  Since the checking is done even for vCPUs
> that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
> the non-initialized vCPUs are erroneously treated as 64bit vCPU,
> which causes the function to incorrectly detect a mixed-width VM.
> 
> Fix vcpu_allowed_register_width() to skip the check for vCPUs that
> are not initialized yet.
> 
> Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/kvm/reset.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 426bd7fbc3fd..ef78bbc7566a 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
>  	if (kvm_has_mte(vcpu->kvm) && is32bit)
>  		return false;
>  
> +	/*
> +	 * Make sure vcpu->arch.target setting is visible from others so
> +	 * that the width consistency checking between two vCPUs is done
> +	 * by at least one of them at KVM_ARM_VCPU_INIT.
> +	 */
> +	smp_mb();

>From ARM DDI 0487G.a, page B2-146 ("Data Memory Barrier (DMB)"):

"The DMB instruction is a memory barrier instruction that ensures the relative
order of memory accesses before the barrier with memory accesses after the
barrier."

I'm going to assume from the comment that you are referring to completion of
memory accesses ("Make sure [..] is visible from others"). Please correct me if
I am wrong. In this case, DMB ensures ordering of memory accesses with regards
to writes and reads, not *completion*.  Have a look at
tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus for
the classic message passing example as an example of memory ordering.
Message passing and other patterns are also explained in ARM DDI 0487G.a, page
K11-8363.

I'm not saying that your approach is incorrect, but the commit message should
explain what memory accesses are being ordered relative to each other and why.

Thanks,
Alex

> +
>  	/* Check that the vcpus are either all 32bit or all 64bit */
>  	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> +		/* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> +		if (tmp->arch.target == -1)
> +			continue;
> +
>  		if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit)
>  			return false;
>  	}
> 
> base-commit: df0cc57e057f18e44dac8e6c18aba47ab53202f9
> -- 
> 2.34.1.575.g55b058a8bb-goog
> 


From german.gomez at arm.com  Mon Jan 10 02:48:57 2022
From: german.gomez at arm.com (German Gomez)
Date: Mon, 10 Jan 2022 10:48:57 +0000
Subject: [PATCH v5 6/6] perf arm64: inject missing frames if perf-record
 used "--call-graph=fp"
In-Reply-To: <YcGfQr43ChIgtacC@krava>
References: <20211217154521.80603-1-german.gomez@arm.com>
 <20211217154521.80603-7-german.gomez@arm.com> <YcGfQr43ChIgtacC@krava>
Message-ID: <866deed3-9f01-7b68-9b01-9c9f02fbdfac@arm.com>

Hi Jiri,

On 21/12/2021 09:32, Jiri Olsa wrote:
> On Fri, Dec 17, 2021 at 03:45:20PM +0000, German Gomez wrote:
>
> SNIP
>
>> +}
>> +
>> +u64 get_leaf_frame_caller_aarch64(struct perf_sample *sample, struct thread *thread, int usr_idx)
>> +{
>> +	int ret;
>> +	struct entries entries = {};
>> +	struct regs_dump old_regs = sample->user_regs;
>> +
>> +	if (!get_leaf_frame_caller_enabled(sample))
>> +		return 0;
>> +
>> +	/*
>> +	 * If PC and SP are not recorded, get the value of PC from the stack
>> +	 * and set its mask. SP is not used when doing the unwinding but it
>> +	 * still needs to be set to prevent failures.
>> +	 */
>> +
>> +	if (!(sample->user_regs.mask & SMPL_REG_MASK(PERF_REG_ARM64_PC))) {
>> +		sample->user_regs.cache_mask |= SMPL_REG_MASK(PERF_REG_ARM64_PC);
>> +		sample->user_regs.cache_regs[PERF_REG_ARM64_PC] = sample->callchain->ips[usr_idx+1];
>> +	}
>> +
>> +	if (!(sample->user_regs.mask & SMPL_REG_MASK(PERF_REG_ARM64_SP))) {
>> +		sample->user_regs.cache_mask |= SMPL_REG_MASK(PERF_REG_ARM64_SP);
>> +		sample->user_regs.cache_regs[PERF_REG_ARM64_SP] = 0;
>> +	}
>> +
>> +	ret = unwind__get_entries(add_entry, &entries, thread, sample, 2);
> just curious, did you try this with both unwinders libunwind/libdw?

Yes I did,

This is the program I was using:

? int a = 0;

? void leaf() {
??? for (int i = 0; i < 10000000; i++)
????? a *= a;
? }

? void parent() {
??? leaf();
? }

? int main() {
??? parent();
? }

? ... compiled with "gcc -O0 -fno-omit-frame-pointer -fno-inline program.c"

>
> any chance you could add arm specific test for this?

I don't see a reason not to. I'll make a note for a separate patch.

>
> otherwise it looks good to me
>
> Acked-by: Jiri Olsa <jolsa at kernel.org>

Thanks for the review,
German


From nsaenzju at redhat.com  Mon Jan 10 02:50:44 2022
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Mon, 10 Jan 2022 11:50:44 +0100
Subject: [PATCH v4 2/2] Documentation: core-api: entry: Add comments about
 nesting
In-Reply-To: <20220110105044.94423-1-nsaenzju@redhat.com>
References: <20220110105044.94423-1-nsaenzju@redhat.com>
Message-ID: <20220110105044.94423-2-nsaenzju@redhat.com>

The topic of nesting and reentrancy in the context of early entry code
hasn't been addressed so far. So do it.

Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>

---

Changes since v3:
 - Introduce Paul's rewording suggestions

 Documentation/core-api/entry.rst | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/Documentation/core-api/entry.rst b/Documentation/core-api/entry.rst
index c6f8e22c88fe..e12f22ab33c7 100644
--- a/Documentation/core-api/entry.rst
+++ b/Documentation/core-api/entry.rst
@@ -105,6 +105,8 @@ has to do extra work between the various steps. In such cases it has to
 ensure that enter_from_user_mode() is called first on entry and
 exit_to_user_mode() is called last on exit.
 
+Do not nest syscalls. Nested systcalls will cause RCU and/or context tracking
+to print a warning.
 
 KVM
 ---
@@ -121,6 +123,8 @@ Task work handling is done separately for guest at the boundary of the
 vcpu_run() loop via xfer_to_guest_mode_handle_work() which is a subset of
 the work handled on return to user space.
 
+Do not nest KVM entry/exit transitions because doing so is nonsensical.
+
 Interrupts and regular exceptions
 ---------------------------------
 
@@ -180,6 +184,16 @@ before it handles soft interrupts, whose handlers must run in BH context rather
 than irq-disabled context. In addition, irqentry_exit() might schedule, which
 also requires that HARDIRQ_OFFSET has been removed from the preemption count.
 
+Even though interrupt handlers are expected to run with local interrupts
+disabled, interrupt nesting is common from an entry/exit perspective. For
+example, softirq handling happens within an irqentry_{enter,exit}() block with
+local interrupts enabled. Also, although uncommon, nothing prevents an
+interrupt handler from re-enabling interrupts.
+
+Interrupt entry/exit code doesn't strictly need to handle reentrancy, since it
+runs with local interrupts disabled. But NMIs can happen anytime, and a lot of
+the entry code is shared between the two.
+
 NMI and NMI-like exceptions
 ---------------------------
 
@@ -259,3 +273,7 @@ and for e.g. a debug exception it can look like this:
 
 There is no combined irqentry_nmi_if_kernel() function available as the
 above cannot be handled in an exception-agnostic way.
+
+NMIs can happen in any context. For example, an NMI-like exception triggered
+while handling an NMI. So NMI entry code has to be reentrant and state updates
+need to handle nesting.
-- 
2.34.1



From nsaenzju at redhat.com  Mon Jan 10 02:50:43 2022
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Mon, 10 Jan 2022 11:50:43 +0100
Subject: [PATCH v4 1/2] Documentation: Fill the gaps about entry/noinstr
 constraints
Message-ID: <20220110105044.94423-1-nsaenzju@redhat.com>

From: Thomas Gleixner <tglx at linutronix.de>

The entry/exit handling for exceptions, interrupts, syscalls and KVM is
not really documented except for some comments.

Fill the gaps.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de
Co-developed-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Paul E. McKenney <paulmck at kernel.org>

----

Changes since v3:
 - s/nointr/noinstr/

Changes since v2:
 - No big content changes, just style corrections, so it should be
   pretty clean at this stage. In the light of this, I kept Mark's
   Reviewed-by.
 - Paul's style and paragraph re-writes
 - Randy's style comments
 - Add links to transition type sections

 Documentation/core-api/entry.rst | 261 +++++++++++++++++++++++++++++++
 Documentation/core-api/index.rst |   8 +
 2 files changed, 269 insertions(+)
 create mode 100644 Documentation/core-api/entry.rst

diff --git a/Documentation/core-api/entry.rst b/Documentation/core-api/entry.rst
new file mode 100644
index 000000000000..c6f8e22c88fe
--- /dev/null
+++ b/Documentation/core-api/entry.rst
@@ -0,0 +1,261 @@
+Entry/exit handling for exceptions, interrupts, syscalls and KVM
+================================================================
+
+All transitions between execution domains require state updates which are
+subject to strict ordering constraints. State updates are required for the
+following:
+
+  * Lockdep
+  * RCU / Context tracking
+  * Preemption counter
+  * Tracing
+  * Time accounting
+
+The update order depends on the transition type and is explained below in
+the transition type sections: `Syscalls`_, `KVM`_, `Interrupts and regular
+exceptions`_, `NMI and NMI-like exceptions`_.
+
+Non-instrumentable code - noinstr
+---------------------------------
+
+Most instrumentation facilities depend on RCU, so intrumentation is prohibited
+for entry code before RCU starts watching and exit code after RCU stops
+watching. In addition, many architectures must save and restore register state,
+which means that (for example) a breakpoint in the breakpoint entry code would
+overwrite the debug registers of the initial breakpoint.
+
+Such code must be marked with the 'noinstr' attribute, placing that code into a
+special section inaccessible to instrumentation and debug facilities. Some
+functions are partially instrumentable, which is handled by marking them
+noinstr and using instrumentation_begin() and instrumentation_end() to flag the
+instrumentable ranges of code:
+
+.. code-block:: c
+
+  noinstr void entry(void)
+  {
+  	handle_entry();     // <-- must be 'noinstr' or '__always_inline'
+	...
+
+	instrumentation_begin();
+	handle_context();   // <-- instrumentable code
+	instrumentation_end();
+
+	...
+	handle_exit();      // <-- must be 'noinstr' or '__always_inline'
+  }
+
+This allows verification of the 'noinstr' restrictions via objtool on
+supported architectures.
+
+Invoking non-instrumentable functions from instrumentable context has no
+restrictions and is useful to protect e.g. state switching which would
+cause malfunction if instrumented.
+
+All non-instrumentable entry/exit code sections before and after the RCU
+state transitions must run with interrupts disabled.
+
+Syscalls
+--------
+
+Syscall-entry code starts in assembly code and calls out into low-level C code
+after establishing low-level architecture-specific state and stack frames. This
+low-level C code must not be instrumented. A typical syscall handling function
+invoked from low-level assembly code looks like this:
+
+.. code-block:: c
+
+  noinstr void syscall(struct pt_regs *regs, int nr)
+  {
+	arch_syscall_enter(regs);
+	nr = syscall_enter_from_user_mode(regs, nr);
+
+	instrumentation_begin();
+	if (!invoke_syscall(regs, nr) && nr != -1)
+	 	result_reg(regs) = __sys_ni_syscall(regs);
+	instrumentation_end();
+
+	syscall_exit_to_user_mode(regs);
+  }
+
+syscall_enter_from_user_mode() first invokes enter_from_user_mode() which
+establishes state in the following order:
+
+  * Lockdep
+  * RCU / Context tracking
+  * Tracing
+
+and then invokes the various entry work functions like ptrace, seccomp, audit,
+syscall tracing, etc. After all that is done, the instrumentable invoke_syscall
+function can be invoked. The instrumentable code section then ends, after which
+syscall_exit_to_user_mode() is invoked.
+
+syscall_exit_to_user_mode() handles all work which needs to be done before
+returning to user space like tracing, audit, signals, task work etc. After
+that it invokes exit_to_user_mode() which again handles the state
+transition in the reverse order:
+
+  * Tracing
+  * RCU / Context tracking
+  * Lockdep
+
+syscall_enter_from_user_mode() and syscall_exit_to_user_mode() are also
+available as fine grained subfunctions in cases where the architecture code
+has to do extra work between the various steps. In such cases it has to
+ensure that enter_from_user_mode() is called first on entry and
+exit_to_user_mode() is called last on exit.
+
+
+KVM
+---
+
+Entering or exiting guest mode is very similar to syscalls. From the host
+kernel point of view the CPU goes off into user space when entering the
+guest and returns to the kernel on exit.
+
+kvm_guest_enter_irqoff() is a KVM-specific variant of exit_to_user_mode()
+and kvm_guest_exit_irqoff() is the KVM variant of enter_from_user_mode().
+The state operations have the same ordering.
+
+Task work handling is done separately for guest at the boundary of the
+vcpu_run() loop via xfer_to_guest_mode_handle_work() which is a subset of
+the work handled on return to user space.
+
+Interrupts and regular exceptions
+---------------------------------
+
+Interrupts entry and exit handling is slightly more complex than syscalls
+and KVM transitions.
+
+If an interrupt is raised while the CPU executes in user space, the entry
+and exit handling is exactly the same as for syscalls.
+
+If the interrupt is raised while the CPU executes in kernel space the entry and
+exit handling is slightly different. RCU state is only updated when the
+interrupt is raised in the context of the CPU's idle task. Otherwise, RCU will
+already be watching. Lockdep and tracing have to be updated unconditionally.
+
+irqentry_enter() and irqentry_exit() provide the implementation for this.
+
+The architecture-specific part looks similar to syscall handling:
+
+.. code-block:: c
+
+  noinstr void interrupt(struct pt_regs *regs, int nr)
+  {
+	arch_interrupt_enter(regs);
+	state = irqentry_enter(regs);
+
+	instrumentation_begin();
+
+	irq_enter_rcu();
+	invoke_irq_handler(regs, nr);
+	irq_exit_rcu();
+
+	instrumentation_end();
+
+	irqentry_exit(regs, state);
+  }
+
+Note that the invocation of the actual interrupt handler is within a
+irq_enter_rcu() and irq_exit_rcu() pair.
+
+irq_enter_rcu() updates the preemption count which makes in_hardirq()
+return true, handles NOHZ tick state and interrupt time accounting. This
+means that up to the point where irq_enter_rcu() is invoked in_hardirq()
+returns false.
+
+irq_exit_rcu() handles interrupt time accounting, undoes the preemption
+count update and eventually handles soft interrupts and NOHZ tick state.
+
+In theory, the preemption count could be updated in irqentry_enter(). In
+practice, deferring this update to irq_enter_rcu() allows the preemption-count
+code to be traced, while also maintaining symmetry with irq_exit_rcu() and
+irqentry_exit(), which are described in the next paragraph. The only downside
+is that the early entry code up to irq_enter_rcu() must be aware that the
+preemption count has not yet been updated with the HARDIRQ_OFFSET state.
+
+Note that irq_exit_rcu() must remove HARDIRQ_OFFSET from the preemption count
+before it handles soft interrupts, whose handlers must run in BH context rather
+than irq-disabled context. In addition, irqentry_exit() might schedule, which
+also requires that HARDIRQ_OFFSET has been removed from the preemption count.
+
+NMI and NMI-like exceptions
+---------------------------
+
+NMIs and NMI-like exceptions (machine checks, double faults, debug
+interrupts, etc.) can hit any context and must be extra careful with
+the state.
+
+State changes for debug exceptions and machine-check exceptions depend on
+whether these exceptions happened in user-space (breakpoints or watchpoints) or
+in kernel mode (code patching). From user-space, they are treated like
+interrupts, while from kernel mode they are treated like NMIs.
+
+NMIs and other NMI-like exceptions handle state transitions without
+distinguishing between user-mode and kernel-mode origin.
+
+The state update on entry is handled in irqentry_nmi_enter() which updates
+state in the following order:
+
+  * Preemption counter
+  * Lockdep
+  * RCU / Context tracking
+  * Tracing
+
+The exit counterpart irqentry_nmi_exit() does the reverse operation in the
+reverse order.
+
+Note that the update of the preemption counter has to be the first
+operation on enter and the last operation on exit. The reason is that both
+lockdep and RCU rely on in_nmi() returning true in this case. The
+preemption count modification in the NMI entry/exit case must not be
+traced.
+
+Architecture-specific code looks like this:
+
+.. code-block:: c
+
+  noinstr void nmi(struct pt_regs *regs)
+  {
+	arch_nmi_enter(regs);
+	state = irqentry_nmi_enter(regs);
+
+	instrumentation_begin();
+	nmi_handler(regs);
+	instrumentation_end();
+
+	irqentry_nmi_exit(regs);
+  }
+
+and for e.g. a debug exception it can look like this:
+
+.. code-block:: c
+
+  noinstr void debug(struct pt_regs *regs)
+  {
+	arch_nmi_enter(regs);
+
+	debug_regs = save_debug_regs();
+
+	if (user_mode(regs)) {
+		state = irqentry_enter(regs);
+
+		instrumentation_begin();
+		user_mode_debug_handler(regs, debug_regs);
+		instrumentation_end();
+
+		irqentry_exit(regs, state);
+  	} else {
+  		state = irqentry_nmi_enter(regs);
+
+		instrumentation_begin();
+		kernel_mode_debug_handler(regs, debug_regs);
+		instrumentation_end();
+
+		irqentry_nmi_exit(regs, state);
+	}
+  }
+
+There is no combined irqentry_nmi_if_kernel() function available as the
+above cannot be handled in an exception-agnostic way.
diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst
index 5de2c7a4b1b3..972d46a5ddf6 100644
--- a/Documentation/core-api/index.rst
+++ b/Documentation/core-api/index.rst
@@ -44,6 +44,14 @@ Library functionality that is used throughout the kernel.
    timekeeping
    errseq
 
+Low level entry and exit
+========================
+
+.. toctree::
+   :maxdepth: 1
+
+   entry
+
 Concurrency primitives
 ======================
 
-- 
2.34.1



From catalin.marinas at arm.com  Mon Jan 10 02:52:19 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 10 Jan 2022 10:52:19 +0000
Subject: [PATCH] mm: Generalize ARCH_HAS_FILTER_PGPROT
In-Reply-To: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>
References: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YdwP40C8Zu8s2Az0@arm.com>

On Mon, Jan 10, 2022 at 12:11:36PM +0530, Anshuman Khandual wrote:
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 5c2ccb85f2ef..d9594e05fddb 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -328,9 +328,6 @@ config GENERIC_CALIBRATE_DELAY
>  config ARCH_HAS_CPU_RELAX
>  	def_bool y
>  
> -config ARCH_HAS_FILTER_PGPROT
> -	def_bool y

Aren't you missing a select for x86?

-- 
Catalin


From pali at kernel.org  Mon Jan 10 02:53:24 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Mon, 10 Jan 2022 11:53:24 +0100
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a
 static driver structure
In-Reply-To: <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
 <20220110015018.26359-24-kabel@kernel.org>
 <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
Message-ID: <20220110105324.jud6bzdtmoiuvyas@pali>

On Monday 10 January 2022 09:28:39 Marc Zyngier wrote:
> On 2022-01-10 01:50, Marek Beh?n wrote:
> > Marc Zyngier says [1] that we should use struct irq_chip as a global
> > static struct in the driver. Even though the structure currently
> > contains a dynamic member (parent_device), Marc says [2] that he plans
> > to kill it and make the structure completely static.
> > 
> > We have already converted others irq_chip structures in this driver in
> > this way, but we omitted this one because the .name member is
> > dynamically created from device's name, and the name is displayed in
> > sysfs, so changing it would break sysfs ABI.
> > 
> > The rationale for changing the name (to "advk-INT") in spite of sysfs
> > ABI, and thus allowing to convert to a static structure, is that after
> > the other changes we made in this series, the IRQ chip is basically
> > something different: it no logner generates ERR and PME interrupts (they
> > are generated by emulated bridge's rp_irq_chip).
> 
> There is no 'is spite of the ABI'. If you don't understand why
> we don't break the ABI, you have an even bigger problem.
> 
> So NAK to this patch, now and forever. Any change to the structure to
> make it read-only must allow the preservation of the existing names
> when they are generated by the driver.

Marc, you already presented that you do not like Armada 3720 platform
and that you do not care about it.

But please do not slowdown development for this platform.

Arguments about ABIs, breaking it and similar are not relevant here as
this current kernel implementation is broken. And has to be replaced by
a working one. We are doing on it for more than year.

It really does not make sense to try doing some backward compatibility
with something which is broken by design and does not work. It just take
lot of time without any value.

We really need to more forward and fix driver as in current state is
PCIe on Armada 3720 unusable.


From mhocko at suse.com  Mon Jan 10 02:54:42 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 11:54:42 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydu6fXg2FmrseQOn@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz> <Ydu6fXg2FmrseQOn@google.com>
Message-ID: <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz>

On Sun 09-01-22 21:47:57, Yu Zhao wrote:
> On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > [...]
> > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > +{
> > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > +		.test_walk = should_skip_vma,
> > > +		.p4d_entry = walk_pud_range,
> > > +	};
> > > +
> > > +	int err;
> > > +#ifdef CONFIG_MEMCG
> > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > +#endif
> > > +
> > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > +
> > > +	do {
> > > +		unsigned long start = walk->next_addr;
> > > +		unsigned long end = mm->highest_vm_end;
> > > +
> > > +		err = -EBUSY;
> > > +
> > > +		rcu_read_lock();
> > > +#ifdef CONFIG_MEMCG
> > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > +			goto contended;
> > > +#endif
> > > +		if (!mmap_read_trylock(mm))
> > > +			goto contended;
> > 
> > Have you evaluated the behavior under mmap_sem contention? I mean what
> > would be an effect of some mms being excluded from the walk? This path
> > is called from direct reclaim and we do allocate with exclusive mmap_sem
> > IIRC and the trylock can fail in a presence of pending writer if I am
> > not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> > can bypass the walk.
> 
> You are right. Here it must be a trylock; otherwise it can deadlock.

Yeah, this is clear.

> I think there might be a misunderstanding: the aging doesn't
> exclusively rely on page table walks to gather the accessed bit. It
> prefers page table walks but it can also fallback to the rmap-based
> function, i.e., lru_gen_look_around(), which only gathers the accessed
> bit from at most 64 PTEs and therefore is less efficient. But it still
> retains about 80% of the performance gains.

I have to say that I really have hard time to understand the runtime
behavior depending on that interaction. How does the reclaim behave when
the virtual scan is enabled, partially enabled and almost completely
disabled due to different constrains? I do not see any such an
evaluation described in changelogs and I consider this to be a rather
important information to judge the overall behavior.
 
> > Or is this considered statistically insignificant thus a theoretical
> > problem?
> 
> Yes. People who work on the maple tree and SPF at Google expressed the
> same concern during the design review meeting (all stakeholders on the
> mailing list were also invited). So we had a counter to monitor the
> contention in previous versions, i.e., MM_LOCK_CONTENTION in v4 here:
> https://lore.kernel.org/lkml/20210818063107.2696454-8-yuzhao at google.com/
> 
> And we also combined this patchset with the SPF patchset to see if the
> latter makes any difference. Our conclusion was the contention is
> statistically insignificant to the performance under memory pressure.
> 
> This can be explained by how often we create a new generation. (We
> only walk page tables when we create a new generation. And it's
> similar to the low inactive condition for the active/inactive lru.)
> 
> Usually we only do so every few seconds. We'd run into problems with
> other parts of the kernel, e.g., lru lock contention, i/o congestion,
> etc. if we create more than a few generation every second.

This would be a very good information to have in changelogs. Ideally
with some numbers and analysis.

-- 
Michal Hocko
SUSE Labs


From ardb at kernel.org  Mon Jan 10 02:55:48 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 10 Jan 2022 11:55:48 +0100
Subject: [RFT PATCH] ARM: suspend: switch to swapper_pg_dir before using
 the vmap'ed stack
In-Reply-To: <5fdf1098-fba8-9cba-b9ca-49fa4296dc89@samsung.com>
References: <CGME20220106192701eucas1p23a3cfa225cef560be6b85a101263d26f@eucas1p2.samsung.com>
 <20220106192645.3913934-1-ardb@kernel.org>
 <5fdf1098-fba8-9cba-b9ca-49fa4296dc89@samsung.com>
Message-ID: <CAMj1kXEtdHYT_xJMkmL_SSWCvofgrvWHVMciEoXU0y9_ZWAdsw@mail.gmail.com>

On Mon, 10 Jan 2022 at 10:36, Marek Szyprowski <m.szyprowski at samsung.com> wrote:
>
> Hi Ard,
>
> On 06.01.2022 20:26, Ard Biesheuvel wrote:
> > The resume from suspend code switches to the ID map so it can enable the
> > MMU. On !LPAE configurations, the ID map carries its own copy of the
> > kernel VA range, but this is not kept in sync with swapper_pg_dir, and
> > so it may lack the mapping of the kernel mode stack if CONFIG_VMAP_STACK
> > is enabled.
> >
> > So let's switch to swapper_pg_dir right after re-enabling the MMU on
> > such configurations. This avoids a crash on resume observed on various
> > platforms [0].
> >
> > [0] https://protect2.fireeye.com/v1/url?k=efa2c314-b039fa16-efa3485b-0cc47a31381a-5dcf992b5d854429&q=1&e=1dac5900-a7aa-40ed-a2f0-9af17ae05bfe&u=https%3A%2F%2Flore.kernel.org%2Flinux-arm-kernel%2F20211122092816.2865873-8-ardb%40kernel.org%2F
> >
> > Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> > Cc: Geert Uytterhoeven <geert at linux-m68k.org>
> > Cc: Jon Hunter <jonathanh at nvidia.com>
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
>
> This fixes the suspend/resume issue observed on ARM 32bit Exynos based
> boards. Thanks!
>
> Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
>
> Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
>

Thanks Marek.


From yong.wu at mediatek.com  Mon Jan 10 02:59:42 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 10 Jan 2022 18:59:42 +0800
Subject: [PATCH v3 09/33] iommu/mediatek: Remove for_each_m4u in
 tlb_sync_all
In-Reply-To: <85987e9a-dfb0-c241-1dde-43c050a78b51@collabora.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-10-yong.wu@mediatek.com>
 <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>
 <22faee018a36a49e4a507b69d087432c8cd689ec.camel@mediatek.com>
 <85987e9a-dfb0-c241-1dde-43c050a78b51@collabora.com>
Message-ID: <83400d36640fc6256972041c882d080ce9aa5fdd.camel@mediatek.com>

On Mon, 2022-01-10 at 10:16 +0100, AngeloGioacchino Del Regno wrote:
> Il 09/01/22 03:48, Yong Wu ha scritto:
> > On Tue, 2022-01-04 at 16:55 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Il 23/09/21 13:58, Yong Wu ha scritto:
> > > > The tlb_sync_all is called from these three functions:
> > > > a) flush_iotlb_all: it will be called for each a iommu HW.
> > > > b) tlb_flush_range_sync: it already has for_each_m4u.
> > > > c) in irq: When IOMMU HW translation fault, Only need flush
> > > > itself.
> > > > 
> > > > Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
> > > > 
> > > > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > > > ---
> > > >    drivers/iommu/mtk_iommu.c | 18 +++++++-----------
> > > >    1 file changed, 7 insertions(+), 11 deletions(-)
> > > > 
> > > > diff --git a/drivers/iommu/mtk_iommu.c
> > > > b/drivers/iommu/mtk_iommu.c
> > > > index 6f4f6624e3ac..0b4c30baa864 100644
> > > > --- a/drivers/iommu/mtk_iommu.c
> > > > +++ b/drivers/iommu/mtk_iommu.c
> > > > @@ -206,19 +206,15 @@ static struct mtk_iommu_domain
> > > > *to_mtk_domain(struct iommu_domain *dom)
> > > >    
> > > >    static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data
> > > > *data)
> > > >    {
> > > > -	struct list_head *head = data->hw_list;
> > > > -
> > > > -	for_each_m4u(data, head) {
> > > > -		if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > > > -			continue;
> > > > +	if (pm_runtime_get_if_in_use(data->dev) <= 0)
> > > > +		return;
> > > >    
> > > > -		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> > > > -			       data->base + data->plat_data-
> > > > > inv_sel_reg);
> > > > 
> > > > -		writel_relaxed(F_ALL_INVLD, data->base +
> > > > REG_MMU_INVALIDATE);
> > > > -		wmb(); /* Make sure the tlb flush all done */
> > > > +	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
> > > > +		       data->base + data->plat_data-
> > > > >inv_sel_reg);
> > > > +	writel_relaxed(F_ALL_INVLD, data->base +
> > > > REG_MMU_INVALIDATE);
> > > > +	wmb(); /* Make sure the tlb flush all done */
> > > 
> > > There aren't a lot of writes here - not anymore, since you are no
> > > longer doing
> > > this for_each_m4u()...
> > > ...so, please change writel_relaxed() to writel() calls, allowing
> > > you
> > > to also
> > > remove the write barrier at the end (since in the non relaxed
> > > version, order is already ensured).
> > 
> > In the "writel", the "__iowmb()" runs before "write_relaxed". Then
> > how
> > to guarantee the last register was wrote into the HW. Here the
> > flush
> > all don't have sync(waiting it complete)
> > 
> 
> That's right, I'm sorry for the invalid proposal.
> 
> Though, there's something else to mention here... if writing
> (F_INVLD_EN1 | F_INVLD_EN0) to inv_sel_reg is *required* to happen
> before
> writing F_ALL_INVLD to REG_MMU_INVALIDATE (which I think is exactly
> the
> case here), then, in order to ensure write ordering, you should still
> use
> writel() instead of the relaxed accessor; after which, since (as you
> mentioned)
> there is no sync readback loop, you can keep that wmb() at the end.

The writel_relaxed also makes sure the order. I did try this:


https://patchwork.kernel.org/project/linux-mediatek/patch/1570627143-29441-3-git-send-email-yong.wu at mediatek.com/

> 
> > > 
> > > >    
> > > > -		pm_runtime_put(data->dev);
> > > > -	}
> > > > +	pm_runtime_put(data->dev);
> > > >    }
> > > >    
> > > >    static void mtk_iommu_tlb_flush_range_sync(unsigned long
> > > > iova,
> > > > size_t size,
> > > > 
> 
> 

From suzuki.poulose at arm.com  Mon Jan 10 03:03:05 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 10 Jan 2022 11:03:05 +0000
Subject: [PATCH V2 5/7] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <1641517808-5735-6-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-6-git-send-email-anshuman.khandual@arm.com>
Message-ID: <0ce7622a-0c61-ea80-6c53-0388a8b620fe@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2064142 might fail to write
> into certain system registers after the TRBE has been disabled. Under some
> conditions after TRBE has been disabled, writes into certain TRBE registers
> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
> ignored and not be effected.
> 
> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
> just after the trace collection has stopped and before performing a system
> register write to one of the affected registers. This just updates the TRBE
> driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   arch/arm64/Kconfig                           |  2 +-
>   drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>   drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
>   3 files changed, 39 insertions(+), 25 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index f1651cb71ef3..b6d62672bf7d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -780,7 +780,7 @@ config ARM64_ERRATUM_2224489
>   
>   config ARM64_ERRATUM_2064142
>   	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
> -	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
> +	depends on CORESIGHT_TRBE
>   	default y
>   	help
>   	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 276862c07e32..850e9fca6847 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -91,10 +91,12 @@ struct trbe_buf {
>    */
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
> +#define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
> +	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>   }
>   
> +static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
> +{
> +	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -174,30 +181,42 @@ static int trbe_alloc_node(struct perf_event *event)
>   	return cpu_to_node(event->cpu);
>   }
>   
> -static void trbe_drain_buffer(void)
> +static inline void trbe_drain_buffer(void)
>   {
>   	tsb_csync();
>   	dsb(nsh);
>   }
>   
> -static void trbe_drain_and_disable_local(void)
> +static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
>   {
>   	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>   
> -	trbe_drain_buffer();
> -
>   	/*
>   	 * Disable the TRBE without clearing LIMITPTR which
>   	 * might be required for fetching the buffer limits.
>   	 */
>   	trblimitr &= ~TRBLIMITR_ENABLE;
>   	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
> +
> +	/*
> +	 * Errata affected TRBE implementation will need TSB CSYNC and
> +	 * DSB in order to prevent subsequent writes into certain TRBE
> +	 * system registers from being ignored and not effected.
> +	 */

minor nit: This comment could be moved to the definition of the
function "trbe_needs_drain_after_disable()" to make more sense.
The name is implicit here indicating, why we are doing a drain.

Either ways:

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>



From m.szyprowski at samsung.com  Mon Jan 10 03:08:40 2022
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 10 Jan 2022 12:08:40 +0100
Subject: [RFC PATCH 1/1] ARM: exynos: only do SMC_CMD_CPU1BOOT call on
 Exynos4
In-Reply-To: <20220108215733.705865-2-henrik@grimler.se>
References: <20220108215733.705865-1-henrik@grimler.se>
 <CGME20220108215952eucas1p1bb9bc56c7f8ac7117b5e5576635460d5@eucas1p1.samsung.com>
 <20220108215733.705865-2-henrik@grimler.se>
Message-ID: <2202f06f-e901-44bb-b6dc-7225dd093e1b@samsung.com>

On 08.01.2022 22:57, Henrik Grimler wrote:
> On Exynos5 the call is simply ignored by most variants of the
> trustzone firmware.  However, on some devices it instead causes the
> device to hang, so let's avoid the call for the SoCs where it should
> not be needed.
>
> To see that the call is ignored, we can look into sboot/tzsw.  On most
> of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
> the secure monitor calls is quite easy to recognise, the SMC number is
> compared to known ones, and if equal it branches to the relevant
> function.  In assembly this looks something like:
>
> ;-- handle_smc:
> 0x00000514      650070e3       cmn r0, 0x65
> 0x00000518      0a00000a       beq loc.smc_cmd_reg
> 0x0000051c      010070e3       cmn r0, 1
> 0x00000520      6c00000a       beq loc.smc_cmd_init
> 0x00000524      020070e3       cmn r0, 2
> 0x00000528      6b00000a       beq loc.smc_cmd_info
> 0x0000052c      030070e3       cmn r0, 3
> 0x00000530      6e00000a       beq loc.smc_cmd_sleep
> 0x00000534      060070e3       cmn r0, 6
> 0x00000538      ae00000a       beq loc.smc_cmd_save_state
> 0x0000053c      070070e3       cmn r0, 7
> 0x00000540      b400000a       beq loc.smc_cmd_standby
> 0x00000544      2b01001a       bne loc.smc_return_minus1
>
> where above example is from exynos5420-arndale-octa.  As can be seen
> the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
> annotations are taken from github.com/hsnaves/exynos5410-firmware,
> where a large part of the exynos5410 trustzone firmware has been
> reverse-engineered.
>
> Signed-off-by: Henrik Grimler <henrik at grimler.se>

Works fine on all ARM 32bit Exynos-based boards I have for tests.

Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>

> ---
>   arch/arm/mach-exynos/firmware.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
> index 2eaf2dbb8e81..2da5b60b59e2 100644
> --- a/arch/arm/mach-exynos/firmware.c
> +++ b/arch/arm/mach-exynos/firmware.c
> @@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
>   	/*
>   	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
>   	 * because Exynos3250 removes WFE in secure mode.
> +	 *
> +	 * On Exynos5 devices the call is ignored by trustzone firmware.
>   	 */
> -	if (soc_is_exynos3250())
> +	if (!soc_is_exynos4210() && !soc_is_exynos4412())
>   		return 0;
>   
>   	/*

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From mark.rutland at arm.com  Mon Jan 10 03:26:29 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 10 Jan 2022 11:26:29 +0000
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <bd82d240-34d7-4df9-650b-c039555f05e3@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
 <Ydg939btY/bzEAe4@FVFF77S0Q05N>
 <bd82d240-34d7-4df9-650b-c039555f05e3@huawei.com>
Message-ID: <YdwX5RTVbw8veM98@FVFF77S0Q05N>

On Mon, Jan 10, 2022 at 11:00:43AM +0800, He Ying wrote:
> Hi Mark,
> 
> I'm just back from the weekend and sorry for the delayed reply.
> 
> 
> ? 2022/1/7 21:19, Mark Rutland ??:
> > On Fri, Jan 07, 2022 at 03:55:36AM -0500, He Ying wrote:
> > > Our product has been updating its kernel from 4.4 to 5.10 recently and
> > > found a performance issue. We do a bussiness test called ARP test, which
> > > tests the latency for a ping-pong packets traffic with a certain payload.
> > > The result is as following.
> > > 
> > >   - 4.4 kernel: avg = ~20s
> > >   - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s
> > Have you tested with a recent mainline kernel, e.g. v5.15?
> 
> Actuallly no, that's because this test is only available for the product
> environment and
> 
> we don't have an available 5.15 kernel for it yet.

Ok; do you see anything comparable with any tests available to upstream
developers? e.g. hackbench or `perf bench sched` ?

> > Is this test publicly available, and can you say which hardrware (e.g. which
> > CPU implementation) you're testing with?
> 
> Actually no. The test is only available for our product environment now. We
> are testing
> 
> with hisilicon 1213 (4 ARM Cortex-A72 cores).

Thanks for the CPU info; there are a number of other Cortex-A72 platforms out
there, so it might be possible to reproduce the behaviour elsewhere.

> > > I have been just learning arm64 pseudo-NMI code and have a question,
> > > why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
> > The code in question is all patched via alternatives, and when
> > CONFIG_ARM64_PSEUDO_NMI is not selected, the code was expected to only have the
> > overhead of the regular DAIF manipulation.
> I don't understand alernatives very well and I'll apreciate it if you can
> explain it a bit more.

Code using alternatives is patched at runtime, so for:

	ALTERNATIVE(x, y, cap)

... the `x` instructions will be inline in the code, and the `y` instructions
will be placed in a separate linker section. If the `cap` capability is
detected, the `y` instructions will be copied over the `x` instructions.

So for:

| asm volatile(ALTERNATIVE(
|         "msr    daifclr, #3             // arch_local_irq_enable",
|         __msr_s(SYS_ICC_PMR_EL1, "%0"),
|         ARM64_HAS_IRQ_PRIO_MASKING)
|         :
|         : "r" ((unsigned long) GIC_PRIO_IRQON)
|         : "memory");

... where ARM64_HAS_IRQ_PRIO_MASKING is not detected, the inline instructions
will be:

| msr    daifclr, #3             // arch_local_irq_enable 

A separate linker section will contain:
... and a separate linker section will contain:

| __msr_s(SYS_ICC_PMR_EL1, "%0"

... and some metadata will be recorded in a `struct alt_instr`, which will be
unused and will take some space, but should have no runtime overhead -- the
runtime cost should only be the `msr daifclr, #3` instruction.

> > > I wonder if this brings some performance regression.
> > > 
> > > First, I make this patch and then do the test again. Here's the result.
> > > 
> > >   - 5.10 kernel with this patch not applied: avg = ~40s
> > >   - 5.10 kernel with this patch applied: avg = ~23s
> > > 
> > > Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
> > > set. It seems the pseudo-NMI feature actually brings some overhead to
> > > performance event if CONFIG_ARM64_PSEUDO_NMI is not set.
> > I'm surprised the overhead is so significant; as above this is all patched in
> > and so the overhead when this is disabled is expected to be *extremely* small.
> > 
> > For example, wjen CONFIG_ARM64_PSEUDO_NMI, in arch_local_irq_enable():
> > 
> > * The portion under the system_has_prio_mask_debugging() test will be removed
> >    entirely by the compiler, as this internally checks
> >    IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI).
> > 
> > * The assembly will be left as a write to DAIFClr. The only additional cost
> >    should be that of generating GIC_PRIO_IRQON into a register.
> > 
> > * The pmr_sync() will be removed entirely by the compiler as is defined
> >    conditionally dependent on CONFIG_ARM64_PSEUDO_NMI.
> > 
> > I can't spot an obvious issue with that or ther other cases. In the common case
> > those add no new instructions, and in the worst case they only add NOPs.
> 
> Thanks for your detailed explaination! Actually I can't understand the
> result exactly.
> 
> I build two 5.10 kernel images with this patch applied or not and objdump
> them. Indeed, the disassembles of 'arch_local_irq_restore' are the same. Do
> you have any ideas how we can find the root cause why this patch improves the
> performance so much?
> 
> However, the test result is trustworthy because we do it many times and the
> result is always repeatable.

Due to the large numbers, I suspect this must be due to a specific fast-path,
and it's possible that this is due to secondary factors (e.g. alignment of
code) rather than the pseudo-NMK code itself.

We need to narrow down *where* time is being spent. Since it appears that this
is related to the local IRQ state management, it isn't likely that we can
determine that reliably with the PMU. Given that, I think the first step is to
reproduce the result elsewhere, for which we will need some plublicly available
test-case.

> > > Furthermore, I find the feature also brings some overhead to vmlinux size.
> > > I build 5.10 kernel with this patch applied or not while
> > > CONFIG_ARM64_PSEUDO_NMI is not set.
> > > 
> > >   - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
> > >   - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
> > > 
> > > That means arm64 pseudo-NMI feature may bring ~200KB overhead to
> > > vmlinux size.
> > I suspect that's just the (unused) alternatives, and we could improve that by
> > passing the config into the alternative blocks.
> 
> Do you mean the sections generated by the alternatives? I don't understand
> alernatives very well and I'll apreciate it if you can explain it a bit
> more.

Yes; I meant the sections generated to hold the alternatives code and the
alternatives metadata.


> > > Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
> > > and performance even if config is not set. To avoid it, add macro control
> > > all around the related code.
> > > 
> > > Signed-off-by: He Ying <heying24 at huawei.com>
> > > ---
> > >   arch/arm64/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++--
> > >   arch/arm64/kernel/entry.S         |  4 ++++
> > >   2 files changed, 40 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
> > > index b57b9b1e4344..82f771b41cf5 100644
> > > --- a/arch/arm64/include/asm/irqflags.h
> > > +++ b/arch/arm64/include/asm/irqflags.h
> > > @@ -26,6 +26,7 @@
> > >    */
> > >   static inline void arch_local_irq_enable(void)
> > >   {
> > > +#ifdef CONFIG_ARM64_PSEUDO_NMI
> > >   	if (system_has_prio_mask_debugging()) {
> > >   		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
> > > @@ -41,10 +42,18 @@ static inline void arch_local_irq_enable(void)
> > >   		: "memory");
> > >   	pmr_sync();
> > > +#else
> > > +	asm volatile(
> > > +		"msr	daifclr, #3		// arch_local_irq_enable"
> > > +		:
> > > +		:
> > > +		: "memory");
> > > +#endif
> > I'm happy to rework this to improve matters, but I am very much not happy with
> > duplicating the logic for the !PSEUDO_NMI case. Adding more ifdeffery and
> > copies of that is not acceptable.
> I agree. Adding these ifdeffery is a bit ugly. Let's see if there are some
> better ways.
> > 
> > Instead, can you please try changing the alternative to also take the config,
> > e.g. here have:
> > 
> > |       asm volatile(ALTERNATIVE(
> > |               "msr    daifclr, #3             // arch_local_irq_enable",
> > |               __msr_s(SYS_ICC_PMR_EL1, "%0"),
> > |               ARM64_HAS_IRQ_PRIO_MASKING,
> > |               CONFIG_ARM64_PSEUDO_NMI)
> > |               :
> > |               : "r" ((unsigned long) GIC_PRIO_IRQON)
> > |               : "memory");
> > 
> > ... and see if that makes a significant difference?
> > 
> > Likewise for the other casees.
> 
> OK, I'll try it. But I have some questions. Here's the comment of
> ALERNATIVE:
> 
> /*
> ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature));
> ?*
> ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature, CONFIG_FOO));
> ?* N.B. If CONFIG_FOO is specified, but not selected, the whole block
> ?*????? will be omitted, including oldinstr.
> ?*/
> 
> If CONFIG_FOO is not selected, the whole block will be omitted including
> oldinstr.
> 
> But we still want the oldinstr in this situation. Do I misunderstand
> something?

Sorry; you are right, and my suggestion was broken.

I'll need to have a think about this; we might be able to rework this to use a
static key instead, but IIRC last time I tried there were issues with that
approach. I have some (old) work-in-progress patches at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/daif-rework

I suspect I won't have time to renew that in the near future, but an approach
like that might be worthwhile.

Thanks,
Mark.


From conleylee at foxmail.com  Mon Jan 10 03:35:49 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Mon, 10 Jan 2022 19:35:49 +0800
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with macro
In-Reply-To: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
Message-ID: <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>

This patch remove magic numbers in sun4i-emac.c and replace with macros
defined in sun4i-emac.h

Change since v1
---------------
- reformat
- merge commits
- add commit message

Signed-off-by: Conley Lee <conleylee at foxmail.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
 drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 849de4564709..98fd98feb439 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -106,9 +106,9 @@ static void emac_update_speed(struct net_device *dev)
 
 	/* set EMAC SPEED, depend on PHY  */
 	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
-	reg_val &= ~(0x1 << 8);
+	reg_val &= ~EMAC_MAC_SUPP_100M;
 	if (db->speed == SPEED_100)
-		reg_val |= 1 << 8;
+		reg_val |= EMAC_MAC_SUPP_100M;
 	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
 }
 
@@ -264,7 +264,7 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
@@ -429,7 +429,7 @@ static unsigned int emac_powerup(struct net_device *ndev)
 	/* initial EMAC */
 	/* flush RX FIFO */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
-	reg_val |= 0x8;
+	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
 	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
 	udelay(1);
 
@@ -441,8 +441,8 @@ static unsigned int emac_powerup(struct net_device *ndev)
 
 	/* set MII clock */
 	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
-	reg_val &= (~(0xf << 2));
-	reg_val |= (0xD << 2);
+	reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK;
+	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
 	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
 
 	/* clear RX counter */
@@ -506,7 +506,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |=
+				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
+				 EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +671,9 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |=
+				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
+				 EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -783,20 +787,20 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE)
 		emac_tx_done(dev, db, int_status);
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..90bd9ad77607 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -38,6 +38,7 @@
 #define EMAC_RX_CTL_REG		(0x3c)
 #define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
 #define EMAC_RX_CTL_DMA_EN		(1 << 2)
+#define EMAC_RX_CTL_FLUSH_FIFO		(1 << 3)
 #define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
 #define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
 #define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
@@ -61,7 +62,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
@@ -87,8 +102,11 @@
 #define EMAC_MAC_CLRT_RM		(0x0f)
 #define EMAC_MAC_MAXF_REG	(0x70)
 #define EMAC_MAC_SUPP_REG	(0x74)
+#define EMAC_MAC_SUPP_100M	(0x1 << 8)
 #define EMAC_MAC_TEST_REG	(0x78)
 #define EMAC_MAC_MCFG_REG	(0x7c)
+#define EMAC_MAC_MCFG_MII_CLKD_MASK	(0xff << 2)
+#define EMAC_MAC_MCFG_MII_CLKD_72	(0x0d << 2)
 #define EMAC_MAC_A0_REG		(0x98)
 #define EMAC_MAC_A1_REG		(0x9c)
 #define EMAC_MAC_A2_REG		(0xa0)
-- 
2.31.1



From alexandru.elisei at arm.com  Mon Jan 10 03:40:26 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 10 Jan 2022 11:40:26 +0000
Subject: [RFC PATCH v5 19/38] KVM: arm64: Do not run a VCPU on a CPU
 without SPE
In-Reply-To: <20211117153842.302159-20-alexandru.elisei@arm.com>
References: <20211117153842.302159-1-alexandru.elisei@arm.com>
 <20211117153842.302159-20-alexandru.elisei@arm.com>
Message-ID: <YdwbKtLCXfZnKXb9@monolith.localdoman>

Hello,

This patch will be dropped in the next iteration, and instead I'll
implement the same approach that PMU emulation emulation uses, which is
currently being worked on [1].

Prospective reviewers can safely ignore this patch.

[1] https://lore.kernel.org/linux-arm-kernel/20211213152309.158462-1-alexandru.elisei at arm.com

Thanks,
Alex

On Wed, Nov 17, 2021 at 03:38:23PM +0000, Alexandru Elisei wrote:
> The kernel allows heterogeneous systems where FEAT_SPE is not present on
> all CPUs. This presents a challenge for KVM, as it will have to touch the
> SPE registers when emulating SPE for a guest, and those accesses will cause
> an undefined exception if SPE is not present on the CPU.
> 
> Avoid this situation by keeping a cpumask of CPUs that the VCPU is
> allowed run on, which for SPE is the reunion of all CPUs that support
> SPE, and refuse to run the VCPU on a CPU which is not part of the
> cpumask.
> 
> Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |  3 +++
>  arch/arm64/kvm/arm.c              | 15 +++++++++++++++
>  arch/arm64/kvm/spe.c              |  2 ++
>  3 files changed, 20 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 8b3faed48914..96ce98f6135d 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -405,6 +405,9 @@ struct kvm_vcpu_arch {
>  		u64 last_steal;
>  		gpa_t base;
>  	} steal;
> +
> +	cpumask_var_t supported_cpus;
> +	bool cpu_not_supported;
>  };
>  
>  /* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index b2997b919be2..8a7c01d1df58 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -351,6 +351,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
>  
>  	vcpu->arch.mmu_page_cache.gfp_zero = __GFP_ZERO;
>  
> +	if (!zalloc_cpumask_var(&vcpu->arch.supported_cpus, GFP_KERNEL))
> +		return -ENOMEM;
> +
>  	/* Set up the timer */
>  	kvm_timer_vcpu_init(vcpu);
>  
> @@ -378,6 +381,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
>  	if (vcpu->arch.has_run_once && unlikely(!irqchip_in_kernel(vcpu->kvm)))
>  		static_branch_dec(&userspace_irqchip_in_use);
>  
> +	free_cpumask_var(vcpu->arch.supported_cpus);
>  	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
>  	kvm_timer_vcpu_terminate(vcpu);
>  	kvm_pmu_vcpu_destroy(vcpu);
> @@ -456,6 +460,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>  	if (vcpu_has_ptrauth(vcpu))
>  		vcpu_ptrauth_disable(vcpu);
>  	kvm_arch_vcpu_load_debug_state_flags(vcpu);
> +
> +	if (!cpumask_empty(vcpu->arch.supported_cpus) &&
> +	    !cpumask_test_cpu(smp_processor_id(), vcpu->arch.supported_cpus))
> +		vcpu->arch.cpu_not_supported = true;
>  }
>  
>  void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
> @@ -893,6 +901,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
>  		 */
>  		preempt_disable();
>  
> +		if (unlikely(vcpu->arch.cpu_not_supported)) {
> +			vcpu->arch.cpu_not_supported = false;
> +			ret = -ENOEXEC;
> +			preempt_enable();
> +			continue;
> +		}
> +
>  		kvm_pmu_flush_hwstate(vcpu);
>  
>  		local_irq_disable();
> diff --git a/arch/arm64/kvm/spe.c b/arch/arm64/kvm/spe.c
> index 7c6f94358cc1..f3863728bab6 100644
> --- a/arch/arm64/kvm/spe.c
> +++ b/arch/arm64/kvm/spe.c
> @@ -40,5 +40,7 @@ int kvm_spe_vcpu_enable_spe(struct kvm_vcpu *vcpu)
>  	if (vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT))
>  		return -EINVAL;
>  
> +	cpumask_copy(vcpu->arch.supported_cpus, &supported_cpus);
> +
>  	return 0;
>  }
> -- 
> 2.33.1
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:40:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:40:18 +0100
Subject: [PATCH v3 09/33] iommu/mediatek: Remove for_each_m4u in
 tlb_sync_all
In-Reply-To: <83400d36640fc6256972041c882d080ce9aa5fdd.camel@mediatek.com>
References: <20210923115840.17813-1-yong.wu@mediatek.com>
 <20210923115840.17813-10-yong.wu@mediatek.com>
 <bfa33e94-c2e5-5dab-c9af-b674e1669daa@collabora.com>
 <22faee018a36a49e4a507b69d087432c8cd689ec.camel@mediatek.com>
 <85987e9a-dfb0-c241-1dde-43c050a78b51@collabora.com>
 <83400d36640fc6256972041c882d080ce9aa5fdd.camel@mediatek.com>
Message-ID: <114af71c-58d0-982f-d362-19184a55fb85@collabora.com>

Il 10/01/22 11:59, Yong Wu ha scritto:
> On Mon, 2022-01-10 at 10:16 +0100, AngeloGioacchino Del Regno wrote:
>> Il 09/01/22 03:48, Yong Wu ha scritto:
>>> On Tue, 2022-01-04 at 16:55 +0100, AngeloGioacchino Del Regno
>>> wrote:
>>>> Il 23/09/21 13:58, Yong Wu ha scritto:
>>>>> The tlb_sync_all is called from these three functions:
>>>>> a) flush_iotlb_all: it will be called for each a iommu HW.
>>>>> b) tlb_flush_range_sync: it already has for_each_m4u.
>>>>> c) in irq: When IOMMU HW translation fault, Only need flush
>>>>> itself.
>>>>>
>>>>> Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
>>>>>
>>>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>>>> ---
>>>>>     drivers/iommu/mtk_iommu.c | 18 +++++++-----------
>>>>>     1 file changed, 7 insertions(+), 11 deletions(-)
>>>>>
>>>>> diff --git a/drivers/iommu/mtk_iommu.c
>>>>> b/drivers/iommu/mtk_iommu.c
>>>>> index 6f4f6624e3ac..0b4c30baa864 100644
>>>>> --- a/drivers/iommu/mtk_iommu.c
>>>>> +++ b/drivers/iommu/mtk_iommu.c
>>>>> @@ -206,19 +206,15 @@ static struct mtk_iommu_domain
>>>>> *to_mtk_domain(struct iommu_domain *dom)
>>>>>     
>>>>>     static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data
>>>>> *data)
>>>>>     {
>>>>> -	struct list_head *head = data->hw_list;
>>>>> -
>>>>> -	for_each_m4u(data, head) {
>>>>> -		if (pm_runtime_get_if_in_use(data->dev) <= 0)
>>>>> -			continue;
>>>>> +	if (pm_runtime_get_if_in_use(data->dev) <= 0)
>>>>> +		return;
>>>>>     
>>>>> -		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>>>>> -			       data->base + data->plat_data-
>>>>>> inv_sel_reg);
>>>>>
>>>>> -		writel_relaxed(F_ALL_INVLD, data->base +
>>>>> REG_MMU_INVALIDATE);
>>>>> -		wmb(); /* Make sure the tlb flush all done */
>>>>> +	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
>>>>> +		       data->base + data->plat_data-
>>>>>> inv_sel_reg);
>>>>> +	writel_relaxed(F_ALL_INVLD, data->base +
>>>>> REG_MMU_INVALIDATE);
>>>>> +	wmb(); /* Make sure the tlb flush all done */
>>>>
>>>> There aren't a lot of writes here - not anymore, since you are no
>>>> longer doing
>>>> this for_each_m4u()...
>>>> ...so, please change writel_relaxed() to writel() calls, allowing
>>>> you
>>>> to also
>>>> remove the write barrier at the end (since in the non relaxed
>>>> version, order is already ensured).
>>>
>>> In the "writel", the "__iowmb()" runs before "write_relaxed". Then
>>> how
>>> to guarantee the last register was wrote into the HW. Here the
>>> flush
>>> all don't have sync(waiting it complete)
>>>
>>
>> That's right, I'm sorry for the invalid proposal.
>>
>> Though, there's something else to mention here... if writing
>> (F_INVLD_EN1 | F_INVLD_EN0) to inv_sel_reg is *required* to happen
>> before
>> writing F_ALL_INVLD to REG_MMU_INVALIDATE (which I think is exactly
>> the
>> case here), then, in order to ensure write ordering, you should still
>> use
>> writel() instead of the relaxed accessor; after which, since (as you
>> mentioned)
>> there is no sync readback loop, you can keep that wmb() at the end.
> 
> The writel_relaxed also makes sure the order. I did try this:
> 
> 
> https://patchwork.kernel.org/project/linux-mediatek/patch/1570627143-29441-3-git-send-email-yong.wu at mediatek.com/
> 

Ok, that's fair. Means that this patch is fine as it is.
I'll release by R-b on Dafna's patch, as suggested.

Thank you,
- Angelo


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:42:38 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:42:38 +0100
Subject: [PATCH v2 1/5] iommu/mediatek: Remove for_each_m4u in tlb_sync_all
In-Reply-To: <20211208120744.2415-2-dafna.hirschfeld@collabora.com>
References: <20211208120744.2415-1-dafna.hirschfeld@collabora.com>
 <20211208120744.2415-2-dafna.hirschfeld@collabora.com>
Message-ID: <41c17006-af5d-19ec-210e-f6f12542eb75@collabora.com>

Il 08/12/21 13:07, Dafna Hirschfeld ha scritto:
> From: Yong Wu <yong.wu at mediatek.com>
> 
> The tlb_sync_all is called from these three functions:
> a) flush_iotlb_all: it will be called for each a iommu HW.
> b) tlb_flush_range_sync: it already has for_each_m4u.
> c) in irq: When IOMMU HW translation fault, Only need flush itself.
> 
> Thus, No need for_each_m4u in this tlb_sync_all. Remove it.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From anshuman.khandual at arm.com  Mon Jan 10 03:43:07 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 10 Jan 2022 17:13:07 +0530
Subject: [PATCH] mm: Generalize ARCH_HAS_FILTER_PGPROT
In-Reply-To: <YdwP40C8Zu8s2Az0@arm.com>
References: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>
 <YdwP40C8Zu8s2Az0@arm.com>
Message-ID: <de9ce5d0-04f0-74c5-a65c-814acedb5d46@arm.com>



On 1/10/22 4:22 PM, Catalin Marinas wrote:
> On Mon, Jan 10, 2022 at 12:11:36PM +0530, Anshuman Khandual wrote:
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index 5c2ccb85f2ef..d9594e05fddb 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -328,9 +328,6 @@ config GENERIC_CALIBRATE_DELAY
>>  config ARCH_HAS_CPU_RELAX
>>  	def_bool y
>>  
>> -config ARCH_HAS_FILTER_PGPROT
>> -	def_bool y
> 
> Aren't you missing a select for x86?
> 

It already gets unconditionally selected in arch/x86/Kconfig.


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:43:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:43:18 +0100
Subject: [PATCH v2 2/5] iommu/mediatek: Always check runtime PM status in
 tlb flush range callback
In-Reply-To: <20211208120744.2415-3-dafna.hirschfeld@collabora.com>
References: <20211208120744.2415-1-dafna.hirschfeld@collabora.com>
 <20211208120744.2415-3-dafna.hirschfeld@collabora.com>
Message-ID: <f91157b6-886c-2d69-451e-6ddeb52f95d7@collabora.com>

Il 08/12/21 13:07, Dafna Hirschfeld ha scritto:
> From: Sebastian Reichel <sebastian.reichel at collabora.com>
> 
> In case of v4l2_reqbufs() it is possible, that a TLB flush is done
> without runtime PM being enabled. In that case the "Partial TLB flush
> timed out, falling back to full flush" warning is printed.
> 
> Commit c0b57581b73b ("iommu/mediatek: Add power-domain operation")
> introduced has_pm as optimization to avoid checking runtime PM
> when there is no power domain attached. But without the PM domain
> there is still the device driver's runtime PM suspend handler, which
> disables the clock. Thus flushing should also be avoided when there
> is no PM domain involved.
> 
> Signed-off-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From arnd at arndb.de  Mon Jan 10 03:43:07 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 10 Jan 2022 12:43:07 +0100
Subject: [PATCH V2 01/17] kconfig: Add SYSVIPC_COMPAT for all architectures
In-Reply-To: <20211228143958.3409187-2-guoren@kernel.org>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-2-guoren@kernel.org>
Message-ID: <CAK8P3a0E+2=BnKienWp_VuT2g=YcEfP81SJmgbrLWZbdhRXXrA@mail.gmail.com>

On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> The existing per-arch definitions are pretty much historic cruft.
> Move SYSVIPC_COMPAT into init/Kconfig.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Christoph Hellwig <hch at infradead.org>

Acked-by: Arnd Bergmann <arnd at arndb.de>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:43:46 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:43:46 +0100
Subject: [PATCH v2 3/5] iommu/mediatek: Remove the power status checking
 in tlb flush all
In-Reply-To: <20211208120744.2415-4-dafna.hirschfeld@collabora.com>
References: <20211208120744.2415-1-dafna.hirschfeld@collabora.com>
 <20211208120744.2415-4-dafna.hirschfeld@collabora.com>
Message-ID: <10ca4eae-2959-a697-6818-308e04f88e14@collabora.com>

Il 08/12/21 13:07, Dafna Hirschfeld ha scritto:
> From: Yong Wu <yong.wu at mediatek.com>
> 
> To simplify the code, Remove the power status checking in the
> tlb_flush_all, remove this:
>     if (pm_runtime_get_if_in_use(data->dev) <= 0)
> 	    continue;
> 
> The mtk_iommu_tlb_flush_all is called from
> a) isr
> b) tlb flush range fail case
> c) iommu_create_device_direct_mappings
> 
> In first two cases, the power and clock are always enabled.
> In the third case tlb flush is unnecessary because in a later patch
> in the series a full flush from the pm_runtime_resume callback is added.
> 
> In addition, writing the tlb control register when the iommu is not resumed
> is ok and the write is ignored.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> [refactor commit log]
> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:44:14 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:44:14 +0100
Subject: [PATCH v2 4/5] iommu/mediatek: Add tlb_lock in tlb_flush_all
In-Reply-To: <20211208120744.2415-5-dafna.hirschfeld@collabora.com>
References: <20211208120744.2415-1-dafna.hirschfeld@collabora.com>
 <20211208120744.2415-5-dafna.hirschfeld@collabora.com>
Message-ID: <283e584d-ab72-a3cb-f97e-71eeb16f7834@collabora.com>

Il 08/12/21 13:07, Dafna Hirschfeld ha scritto:
> From: Yong Wu <yong.wu at mediatek.com>
> 
> The tlb_flush_all touches the registers controlling tlb operations.
> Protect it with the tlb_lock spinlock.
> This also require the range_sync func to release that spinlock before
> calling tlb_flush_all.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> [refactor commit log]
> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 03:44:32 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 12:44:32 +0100
Subject: [PATCH v2 5/5] iommu/mediatek: Always tlb_flush_all when each PM
 resume
In-Reply-To: <20211208120744.2415-6-dafna.hirschfeld@collabora.com>
References: <20211208120744.2415-1-dafna.hirschfeld@collabora.com>
 <20211208120744.2415-6-dafna.hirschfeld@collabora.com>
Message-ID: <02719a0f-9725-abc5-f5c4-acbb4bfac08d@collabora.com>

Il 08/12/21 13:07, Dafna Hirschfeld ha scritto:
> From: Yong Wu <yong.wu at mediatek.com>
> 
> Prepare for 2 HWs that sharing pgtable in different power-domains.
> 
> When there are 2 M4U HWs, it may has problem in the flush_range in which
> we get the pm_status via the m4u dev, BUT that function don't reflect the
> real power-domain status of the HW since there may be other HW also use
> that power-domain.
> 
> DAM allocation is often done while the allocating device is runtime
> suspended. In such a case the iommu will also be suspended and partial
> flushing of the tlb will not be executed.
> Therefore, we add a tlb_flush_all in the pm_runtime_resume to make
> sure the tlb is always clean.
> 
> In other case, the iommu's power should be active via device
> link with smi.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> [move the call to mtk_iommu_tlb_flush_all to the bottom of resume cb, improve doc/log]
> Signed-off-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From arnd at arndb.de  Mon Jan 10 03:44:26 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 10 Jan 2022 12:44:26 +0100
Subject: [PATCH V2 02/17] fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
In-Reply-To: <20211228143958.3409187-3-guoren@kernel.org>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-3-guoren@kernel.org>
Message-ID: <CAK8P3a3RALe7ihmhZ-5jucrH_0CZm3VyPaVfT-nC-96=1pKTcQ@mail.gmail.com>

On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> RISC-V doesn't neeed compat_stat, so using __ARCH_WANT_COMPAT_STAT
> to exclude unnecessary SYSCALL functions.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From jirislaby at kernel.org  Mon Jan 10 03:58:19 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Mon, 10 Jan 2022 12:58:19 +0100
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <20220110104214.25321-3-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
Message-ID: <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>

Hi,

On 10. 01. 22, 11:42, Yu Tu wrote:
> This simplifies resetting the UART controller during probe
> and will make it easier to integrate the common clock code
> which will require the registers at probe time as well.

And you are *also* switching devm_request_mem_region+devm_ioremap into 
devm_ioremap_resource without even noting it here. It should've been 
done in a separate patch.

And no, do not resend a new version in the next few days. Having v5 in 
20 days is a bit too much. Give maintainers and reviewers some more 
space to express themselves.
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>   1 file changed, 6 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 45e00d928253..7570958d010c 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	devm_iounmap(port->dev, port->membase);
> -	port->membase = NULL;
> -	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
> +	/* nothing to do */
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> -	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
> -				     dev_name(port->dev))) {
> -		dev_err(port->dev, "Memory region busy\n");
> -		return -EBUSY;
> -	}
> -
> -	port->membase = devm_ioremap(port->dev, port->mapbase,
> -					     port->mapsize);
> -	if (!port->membase)
> -		return -ENOMEM;
> -
>   	return 0;
>   }
>   
> @@ -733,6 +720,10 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	if (!port)
>   		return -ENOMEM;
>   
> +	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
> +	if (IS_ERR(port->membase))
> +		return PTR_ERR(port->membase);
> +
>   	ret = meson_uart_probe_clocks(pdev, port);
>   	if (ret)
>   		return ret;
> @@ -754,10 +745,7 @@ static int meson_uart_probe(struct platform_device *pdev)
>   	platform_set_drvdata(pdev, port);
>   
>   	/* reset port before registering (and possibly registering console) */
> -	if (meson_uart_request_port(port) >= 0) {
> -		meson_uart_reset(port);
> -		meson_uart_release_port(port);
> -	}
> +	meson_uart_reset(port);
>   
>   	ret = uart_add_one_port(&meson_uart_driver, port);
>   	if (ret)

thanks,
-- 
js
suse labs


From anshuman.khandual at arm.com  Mon Jan 10 03:59:42 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 10 Jan 2022 17:29:42 +0530
Subject: [PATCH V2 5/7] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <0ce7622a-0c61-ea80-6c53-0388a8b620fe@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-6-git-send-email-anshuman.khandual@arm.com>
 <0ce7622a-0c61-ea80-6c53-0388a8b620fe@arm.com>
Message-ID: <3d549672-5e03-9f36-1331-49ff4dcb3edd@arm.com>



On 1/10/22 4:33 PM, Suzuki K Poulose wrote:
> On 07/01/2022 01:10, Anshuman Khandual wrote:
>> TRBE implementations affected by Arm erratum #2064142 might fail to write
>> into certain system registers after the TRBE has been disabled. Under some
>> conditions after TRBE has been disabled, writes into certain TRBE registers
>> TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
>> ignored and not be effected.
>>
>> Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
>> just after the trace collection has stopped and before performing a system
>> register write to one of the affected registers. This just updates the TRBE
>> driver as required.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>> ? arch/arm64/Kconfig?????????????????????????? |? 2 +-
>> ? drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
>> ? drivers/hwtracing/coresight/coresight-trbe.h |? 8 ---
>> ? 3 files changed, 39 insertions(+), 25 deletions(-)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index f1651cb71ef3..b6d62672bf7d 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -780,7 +780,7 @@ config ARM64_ERRATUM_2224489
>> ? ? config ARM64_ERRATUM_2064142
>> ????? bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
>> -??? depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
>> +??? depends on CORESIGHT_TRBE
>> ????? default y
>> ????? help
>> ??????? This option adds the workaround for ARM Cortex-A510 erratum 2064142.
>> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
>> index 276862c07e32..850e9fca6847 100644
>> --- a/drivers/hwtracing/coresight/coresight-trbe.c
>> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
>> @@ -91,10 +91,12 @@ struct trbe_buf {
>> ?? */
>> ? #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE??? 0
>> ? #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE??? 1
>> +#define TRBE_NEEDS_DRAIN_AFTER_DISABLE??????? 2
>> ? ? static int trbe_errata_cpucaps[] = {
>> ????? [TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>> ????? [TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>> +??? [TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
>> ????? -1,??????? /* Sentinel, must be the last entry */
>> ? };
>> ? @@ -167,6 +169,11 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
>> ????? return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
>> ? }
>> ? +static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
>> +{
>> +??? return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
>> +}
>> +
>> ? static int trbe_alloc_node(struct perf_event *event)
>> ? {
>> ????? if (event->cpu == -1)
>> @@ -174,30 +181,42 @@ static int trbe_alloc_node(struct perf_event *event)
>> ????? return cpu_to_node(event->cpu);
>> ? }
>> ? -static void trbe_drain_buffer(void)
>> +static inline void trbe_drain_buffer(void)
>> ? {
>> ????? tsb_csync();
>> ????? dsb(nsh);
>> ? }
>> ? -static void trbe_drain_and_disable_local(void)
>> +static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
>> ? {
>> ????? u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
>> ? -??? trbe_drain_buffer();
>> -
>> ????? /*
>> ?????? * Disable the TRBE without clearing LIMITPTR which
>> ?????? * might be required for fetching the buffer limits.
>> ?????? */
>> ????? trblimitr &= ~TRBLIMITR_ENABLE;
>> ????? write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
>> +
>> +??? /*
>> +???? * Errata affected TRBE implementation will need TSB CSYNC and
>> +???? * DSB in order to prevent subsequent writes into certain TRBE
>> +???? * system registers from being ignored and not effected.
>> +???? */
> 
> minor nit: This comment could be moved to the definition of the
> function "trbe_needs_drain_after_disable()" to make more sense.
> The name is implicit here indicating, why we are doing a drain.

Sure, will move the comment just before the function definition.

> 
> Either ways:
> 
> Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
> 


From suzuki.poulose at arm.com  Mon Jan 10 04:03:28 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 10 Jan 2022 12:03:28 +0000
Subject: [PATCH V2 6/7] coresight: trbe: Work around the invalid
 prohibited states
In-Reply-To: <1641517808-5735-7-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-7-git-send-email-anshuman.khandual@arm.com>
Message-ID: <c0f062ea-6c05-0ff1-297e-1ed8a5ed8666@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #2038923 might get TRBE into
> an inconsistent view on whether trace is prohibited within the CPU. As a
> result, the trace buffer or trace buffer state might be corrupted. This
> happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
> followed by just a single context synchronization event before execution
> changes from a context, in which trace is prohibited to one where it isn't,
> or vice versa. In these mentioned conditions, the view of whether trace is
> prohibited is inconsistent between parts of the CPU, and the trace buffer
> or the trace buffer state might be corrupted.
> 
> Work around this problem in the TRBE driver by preventing an inconsistent
> view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
> immediately following a change to TRBLIMITR_EL1.E with at least one ISB
> instruction before an ERET, or two ISB instructions if no ERET is to take
> place. This just updates the TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   arch/arm64/Kconfig                           |  2 +-
>   drivers/hwtracing/coresight/coresight-trbe.c | 48 +++++++++++++++-----
>   2 files changed, 37 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index b6d62672bf7d..209e481acf0d 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -798,7 +798,7 @@ config ARM64_ERRATUM_2064142
>   
>   config ARM64_ERRATUM_2038923
>   	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
> -	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
> +	depends on CORESIGHT_TRBE
>   	default y
>   	help
>   	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index 850e9fca6847..c4cc529749f8 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -92,11 +92,13 @@ struct trbe_buf {
>   #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
>   #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
> +#define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>   	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
> +	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -174,6 +176,11 @@ static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
>   	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
>   }
>   
> +static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudata)
> +{
> +	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -187,6 +194,28 @@ static inline void trbe_drain_buffer(void)
>   	dsb(nsh);
>   }
>   
> +static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
> +{
> +	/*
> +	 * Enable the TRBE without clearing LIMITPTR which
> +	 * might be required for fetching the buffer limits.
> +	 */
> +	trblimitr |= TRBLIMITR_ENABLE;
> +	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
> +
> +	/* Synchronize the TRBE enable event */
> +	isb();
> +
> +	/*
> +	 * Errata affected TRBE implementation will need an additional
> +	 * context synchronization in order to prevent an inconsistent
> +	 * TRBE prohibited region view on the CPU which could possibly
> +	 * corrupt the TRBE buffer or the TRBE state.
> +	 */
> +	if (trbe_needs_ctxt_sync_after_enable(cpudata))
> +		isb();
> +}

Similar to the previous patch, we may move the comment to the function
where it is defined.

Either ways:

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From suzuki.poulose at arm.com  Mon Jan 10 04:04:07 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 10 Jan 2022 12:04:07 +0000
Subject: [PATCH V2 7/7] coresight: trbe: Work around the trace data
 corruption
In-Reply-To: <1641517808-5735-8-git-send-email-anshuman.khandual@arm.com>
References: <1641517808-5735-1-git-send-email-anshuman.khandual@arm.com>
 <1641517808-5735-8-git-send-email-anshuman.khandual@arm.com>
Message-ID: <db01e88d-1f5c-92fb-d32e-aafe48bd41e7@arm.com>

On 07/01/2022 01:10, Anshuman Khandual wrote:
> TRBE implementations affected by Arm erratum #1902691 might corrupt trace
> data or deadlock, when it's being written into the memory. Workaround this
> problem in the driver, by preventing TRBE initialization on affected cpus.
> The firmware must have disabled the access to TRBE for the kernel on such
> implementations. This will cover the kernel for any firmware that doesn't
> do this already. This just updates the TRBE driver as required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>   arch/arm64/Kconfig                           |  2 +-
>   drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
>   2 files changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 209e481acf0d..8a2245c3e857 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -821,7 +821,7 @@ config ARM64_ERRATUM_2038923
>   
>   config ARM64_ERRATUM_1902691
>   	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
> -	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
> +	depends on CORESIGHT_TRBE
>   	default y
>   	help
>   	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
> diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
> index c4cc529749f8..d2f1c68e589c 100644
> --- a/drivers/hwtracing/coresight/coresight-trbe.c
> +++ b/drivers/hwtracing/coresight/coresight-trbe.c
> @@ -93,12 +93,14 @@ struct trbe_buf {
>   #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
>   #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
>   #define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
> +#define TRBE_IS_BROKEN				4
>   
>   static int trbe_errata_cpucaps[] = {
>   	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
>   	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
>   	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
>   	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
> +	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
>   	-1,		/* Sentinel, must be the last entry */
>   };
>   
> @@ -181,6 +183,11 @@ static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudat
>   	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
>   }
>   
> +static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
> +{
> +	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
> +}
> +
>   static int trbe_alloc_node(struct perf_event *event)
>   {
>   	if (event->cpu == -1)
> @@ -1288,6 +1295,11 @@ static void arm_trbe_probe_cpu(void *info)
>   	 */
>   	trbe_check_errata(cpudata);
>   
> +	if (trbe_is_broken(cpudata)) {
> +		pr_err("Disabling TRBE on cpu%d due to erratum\n", cpu);
> +		goto cpu_clear;
> +	}
> +
>   	/*
>   	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
>   	 * we must always program the TBRPTR_EL1, 256bytes from a page


Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>



From jirislaby at kernel.org  Mon Jan 10 04:11:50 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Mon, 10 Jan 2022 13:11:50 +0100
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <20220110104214.25321-4-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-4-yu.tu@amlogic.com>
Message-ID: <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>

Hi,

"Subject: Using the common clock code describe."

Please reformulate that ^^^ -- I cannot make any sense of it. And avoid 
adding a period to the subject. PLease see others' commit logs.

On 10. 01. 22, 11:42, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.



> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>   1 file changed, 163 insertions(+), 61 deletions(-)
> 
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>    */
>   
>   #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>   #include <linux/console.h>
>   #include <linux/delay.h>
>   #include <linux/init.h>
> @@ -65,9 +66,7 @@
>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>   
>   /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>   #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>   
>   #define AML_UART_PORT_NUM		12
>   #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>   #define AML_UART_POLL_USEC		5
>   #define AML_UART_TIMEOUT_USEC		10000
>   
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>   static struct uart_driver meson_uart_driver;
>   
>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>   static int meson_uart_startup(struct uart_port *port)
>   {
>   	u32 val;
> -	int ret = 0;
> +	int ret;
>   
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);

Why is this OK? We didn't use to reset it.

And why is this not done in a separate patch?


> +	val = readl(port->membase + AML_UART_CONTROL);
>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>   	writel(val, port->membase + AML_UART_CONTROL);
>   
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>   
>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
>   	u32 val;
>   
>   	while (!meson_uart_tx_empty(port))
>   		cpu_relax();
>   
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>   	val |= AML_UART_BAUD_USE;
>   	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>   }
>   
>   static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>   
>   static void meson_uart_release_port(struct uart_port *port)
>   {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>   }
>   
>   static int meson_uart_request_port(struct uart_port *port)
>   {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>   	return 0;
>   }
>   
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})

This is cryptic and duplicates the variable on the stack. Why not expand 
the macro and delete it then?

> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },

An extra space here and there:

> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>   {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>   
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>   
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>   	}
>   
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>   	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}
>   
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>   
>   	return 0;
>   }



-- 
js
suse labs


From stano.jakubek at gmail.com  Mon Jan 10 04:13:07 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Mon, 10 Jan 2022 13:13:07 +0100
Subject: [PATCH] dt-bindings: vendor-prefixes: add Huawei
In-Reply-To: <20220110095543.00001ac0@Huawei.com>
References: <20220109132311.GA2827@standask-GA-A55M-S2HP>
 <20220110095543.00001ac0@Huawei.com>
Message-ID: <20220110121307.GA1894@standask-GA-A55M-S2HP>

On Mon, Jan 10, 2022 at 09:55:43AM +0000, Jonathan Cameron wrote:
> On Sun, 9 Jan 2022 14:23:11 +0100
> Stanislav Jakubek <stano.jakubek at gmail.com> wrote:
> 
> > Add vendor prefix for Huawei (https://www.huawei.com/en/)
> 
> Patch description should say why...  Is there an existing binding
> using a huawei vendor prefix?

Not sure about bindings, but there are device trees using the huawei 
vendor prefix. I'm aware of at least these two:
/arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
/arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts

Similar situation with the other vendor prefix patches I've sent yesterday.

Should I send a v2 with an updated patch description for this and
the other patches?

Thanks,

Stanislav

> 
> Thanks,
> 
> Jonathan
> 
> 
> > 
> > Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> > ---
> >  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > index a13d6a19c2b4..18ffa2d7379f 100644
> > --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> > @@ -515,6 +515,8 @@ patternProperties:
> >      description: HannStar Display Co.
> >    "^holtek,.*":
> >      description: Holtek Semiconductor, Inc.
> > +  "^huawei,.*":
> > +    description: Huawei Technologies Co., Ltd.
> >    "^hugsun,.*":
> >      description: Shenzhen Hugsun Technology Co. Ltd.
> >    "^hwacom,.*":
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:27:03 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:27:03 +0800
Subject: [PATCH 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <87tueetsvz.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-3-qianggui.song@amlogic.com>
 <87tueetsvz.wl-maz@kernel.org>
Message-ID: <3235dfc6-413c-7582-8204-2ac8ad0952d4@amlogic.com>



On 1/8/22 6:37 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:16 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Current meson gpio irqchip driver only support 8 channels for gpio irq
>> line, later chips may have more then 8 channels, so need to modify code
>> to support more.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>>   1 file changed, 24 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index d90ff0b92480..6a7b4fb13452 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -16,7 +16,6 @@
>>   #include <linux/of.h>
>>   #include <linux/of_address.h>
>>   
>> -#define NUM_CHANNEL 8
>>   #define MAX_INPUT_MUX 256
>>   
>>   #define REG_EDGE_POL	0x00
>> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>>   
>>   struct meson_gpio_irq_params {
>>   	unsigned int nr_hwirq;
>> +	unsigned int channel_num;
> 
> For consistency, please name this nr_channels.
Okay
> 
>>   	bool support_edge_both;
>>   	unsigned int edge_both_offset;
>>   	unsigned int edge_single_offset;
>> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>>   	.edge_single_offset = 0,				\
>>   	.pol_low_offset = 16,					\
>>   	.pin_sel_mask = 0xff,					\
>> +	.channel_num = 8,					\
>>   
>>   #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
>> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>>   	.edge_single_offset = 8,				\
>>   	.pol_low_offset = 0,					\
>>   	.pin_sel_mask = 0x7f,					\
>> +	.channel_num = 8,					\
>>   
>>   static const struct meson_gpio_irq_params meson8_params = {
>>   	INIT_MESON8_COMMON_DATA(134)
>> @@ -136,8 +138,9 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>>   struct meson_gpio_irq_controller {
>>   	const struct meson_gpio_irq_params *params;
>>   	void __iomem *base;
>> -	u32 channel_irqs[NUM_CHANNEL];
>> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
>> +	u32 *channel_irqs;
>> +	unsigned long *channel_map;
>> +	u8 channel_num;
> 
> Same thing. Though this is completely superfluous, see below.
I will remove this variable
> 
>>   	spinlock_t lock;
>>   };
>>   
>> @@ -207,8 +210,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>>   	spin_lock_irqsave(&ctl->lock, flags);
>>   
>>   	/* Find a free channel */
>> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
>> -	if (idx >= NUM_CHANNEL) {
>> +	idx = find_first_zero_bit(ctl->channel_map, ctl->channel_num);
>> +	if (idx >= ctl->channel_num) {
>>   		spin_unlock_irqrestore(&ctl->lock, flags);
>>   		pr_err("No channel available\n");
>>   		return -ENOSPC;
>> @@ -447,13 +450,25 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>>   
>>   	ctl->params = match->data;
>>   
>> +	ctl->channel_num = ctl->params->channel_num;
> 
> Since you already have a pointer to params, why do you need to
> duplicate this information?
will remove it next patch
> 
>> +	ctl->channel_irqs = kcalloc(ctl->channel_num,
>> +				    sizeof(*ctl->channel_irqs), GFP_KERNEL);
>> +	if (!ctl->channel_irqs)
>> +		return -ENOMEM;
>> +
>> +	ctl->channel_map = bitmap_zalloc(ctl->params->channel_num, GFP_KERNEL);
>> +	if (!ctl->channel_map) {
>> +		kfree(ctl->channel_irqs);
>> +		return -ENOMEM;
>> +	}
>> +
>>   	ret = of_property_read_variable_u32_array(node,
>>   						  "amlogic,channel-interrupts",
>>   						  ctl->channel_irqs,
>> -						  NUM_CHANNEL,
>> -						  NUM_CHANNEL);
>> +						  ctl->channel_num,
>> +						  ctl->channel_num);
>>   	if (ret < 0) {
>> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
>> +		pr_err("can't get %d channel interrupts\n", ctl->channel_num);
>>   		return ret;
> 
> You are now leaking the bitmap and channel_map allocations.
will fix it next patch
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:28:00 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:28:00 +0800
Subject: [PATCH 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <87sftytsk4.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-4-qianggui.song@amlogic.com>
 <87sftytsk4.wl-maz@kernel.org>
Message-ID: <0525de06-03b0-2321-5131-eb2710e5935c@amlogic.com>



On 1/8/22 6:44 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:17 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Due to some chips may use different registers and offset, provide
>> a set trigger type call back.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 13 ++++++++++---
>>   1 file changed, 10 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index 6a7b4fb13452..98419428fcbd 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>>   	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>>   				 unsigned int channel, unsigned long hwirq);
>>   	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
>> +	unsigned int (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
>> +					  unsigned int idx, u32 val);
>>   };
>>   
>>   struct meson_gpio_irq_params {
>> @@ -68,16 +70,17 @@ struct meson_gpio_irq_params {
>>   	struct irq_ctl_ops ops;
>>   };
>>   
>> -#define INIT_MESON_COMMON(irqs, init, sel)			\
>> +#define INIT_MESON_COMMON(irqs, init, sel, type)		\
>>   	.nr_hwirq = irqs,					\
>>   	.ops = {						\
>>   		.gpio_irq_init = init,				\
>>   		.gpio_irq_sel_pin = sel,			\
>> +		.gpio_irq_sel_type = type,			\
>>   	},
>>   
>>   #define INIT_MESON8_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_gpio_irq_init_dummy,	\
>> -			  meson8_gpio_irq_sel_pin)		\
>> +			  meson8_gpio_irq_sel_pin, NULL)	\
>>   	.edge_single_offset = 0,				\
>>   	.pol_low_offset = 16,					\
>>   	.pin_sel_mask = 0xff,					\
>> @@ -85,7 +88,7 @@ struct meson_gpio_irq_params {
>>   
>>   #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>>   	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
>> -			  meson_a1_gpio_irq_sel_pin)		\
>> +			  meson_a1_gpio_irq_sel_pin, NULL)	\
>>   	.support_edge_both = true,				\
>>   	.edge_both_offset = 16,					\
>>   	.edge_single_offset = 8,				\
>> @@ -279,6 +282,10 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>>   	 */
>>   	type &= IRQ_TYPE_SENSE_MASK;
>>   
>> +	/* Some controllers may have different calculation method*/
>> +	if (params->ops.gpio_irq_sel_type)
>> +		return params->ops.gpio_irq_sel_type(ctl, idx, type);
>> +
> 
> No. If you are going to indirect these things, indirect them for all
> implementations and keep the code clean.
Okay, I' ll try to implement a new macro
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:32:23 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:32:23 +0800
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <87r19itrjx.wl-maz@kernel.org>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
 <87r19itrjx.wl-maz@kernel.org>
Message-ID: <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>



On 1/8/22 7:06 PM, Marc Zyngier wrote:
> 
> On Sat, 08 Jan 2022 08:42:18 +0000,
> Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> The meson s4 SoCs support 12 gpio irq lines compared with previous
>> serial chips and have something different, details are as below.
>>
>> IRQ Number:
>> - 80:68 13 pins on bank Z
>> - 67:48 20 pins on bank X
>> - 47:36 12 pins on bank H
>> - 35:24 12 pins on bank D
>> - 23:22 2  pins on bank E
>> - 21:14 8  pins on bank C
>> - 13:0  13 pins on bank B
>>
>> - PADCTRL_GPIO_IRQ_CTRL0
>>    bit[31]:    enable/disable the whole irq lines
> 
> s/the whole/all the/
Okay
> 
>>    bit[12-23]: single edge trigger
>>    bit[0-11]:  poll trigger
>>
>> - PADCTRL_GPIO_IRQ_CTRL[X]
>> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
> 
> choose?
yes it is choose
> 
>> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
>>    where X = 1-6
>>
>> - PADCTRL_GPIO_IRQ_CTRL[7]
>>    bit[0-11]: both edge trigger
> 
> This information would fit better in the code than in the commit
> message.
> 
will copy this to code.
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>>   drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
>>   1 file changed, 51 insertions(+)
>>
>> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
>> index 98419428fcbd..c5d20a866c37 100644
>> --- a/drivers/irqchip/irq-meson-gpio.c
>> +++ b/drivers/irqchip/irq-meson-gpio.c
>> @@ -42,6 +42,11 @@
>>   #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
>>   #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
>>   
>> +/* use for s4 chips */
> 
> s/use/Used/
okay
> 
>> +#define REG_EDGE_POL_S4	0x1c
>> +#define REG_EDGE_POL_MASK_S4(x)				\
>> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
> 
> Why on Earth should this macro handle multiple types?
If I use  #define REG_EDGE_POL_MASK_S4(x) (BIT(x) | BIT(12 + (x)), when
run git format-patch -1 --stdout | ./script/checkpath.pl --strict -,
will get a message
CHECK: Macro argument reuse 'x' - possible side-effects?

> 
>> +
>>   struct meson_gpio_irq_controller;
>>   static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>>   				    unsigned int channel, unsigned long hwirq);
>> @@ -50,6 +55,9 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
>>   				      unsigned int channel,
>>   				      unsigned long hwirq);
>>   static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
>> +static unsigned int
>> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
>> +			   unsigned int idx, u32 val);
>>   
>>   struct irq_ctl_ops {
>>   	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>> @@ -96,6 +104,17 @@ struct meson_gpio_irq_params {
>>   	.pin_sel_mask = 0x7f,					\
>>   	.channel_num = 8,					\
>>   
>> +#define INIT_MESON_S4_COMMON_DATA(irqs)                         \
>> +	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,         \
>> +			  meson_a1_gpio_irq_sel_pin,            \
>> +			  meson_s4_gpio_irq_sel_type)           \
>> +	.support_edge_both = true,				\
>> +	.edge_both_offset = 0,					\
>> +	.edge_single_offset = 12,				\
>> +	.pol_low_offset = 0,					\
>> +	.pin_sel_mask = 0xff,					\
>> +	.channel_num = 12,					\
>> +
>>   static const struct meson_gpio_irq_params meson8_params = {
>>   	INIT_MESON8_COMMON_DATA(134)
>>   };
>> @@ -126,6 +145,10 @@ static const struct meson_gpio_irq_params a1_params = {
>>   	INIT_MESON_A1_COMMON_DATA(62)
>>   };
>>   
>> +static const struct meson_gpio_irq_params s4_params = {
>> +	INIT_MESON_S4_COMMON_DATA(82)
>> +};
>> +
>>   static const struct of_device_id meson_irq_gpio_matches[] = {
>>   	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
>>   	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
>> @@ -135,6 +158,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>>   	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
>>   	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
>>   	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
>> +	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
>>   	{ }
>>   };
>>   
>> @@ -202,6 +226,33 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
>>   	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
>>   }
>>   
>> +static unsigned int
>> +meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
>> +			   unsigned int idx, unsigned int type)
> 
> An 'unsigned int' return type, directly returned by a caller that
> has 'int' as its return type. What could possibly go wrong?

will modify this next patch
> 
>> +{
>> +	unsigned int val = 0;
>> +
>> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(0 + (idx)), 0);
> 
> Drop the 0 + as well as the useless bracketing all over this function.
> 
Okay
>> +
>> +	if (type == IRQ_TYPE_EDGE_BOTH) {
>> +		val |= BIT(ctl->params->edge_both_offset + (idx));
>> +		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
>> +					   BIT(ctl->params->edge_both_offset + (idx)), val);
>> +		return 0;
>> +	}
>> +
>> +	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
>> +		val |= BIT(ctl->params->pol_low_offset + (idx));
>> +
>> +	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
>> +		val |= BIT(ctl->params->edge_single_offset  + (idx));
>> +
>> +	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
>> +				   REG_EDGE_POL_MASK_S4(idx), val);
>> +
>> +	return 0;
>> +};
>> +
>>   static int
>>   meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>>   			       unsigned long  hwirq,
> 
> 	M.
> 


From Qianggui.Song at amlogic.com  Mon Jan 10 04:33:01 2022
From: Qianggui.Song at amlogic.com (qianggui.song)
Date: Mon, 10 Jan 2022 20:33:01 +0800
Subject: [PATCH 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-2-qianggui.song@amlogic.com>
 <A4441A27-7B49-4A9A-83FD-05144A63E705@gmail.com>
Message-ID: <50bc5a03-5c1f-10dc-b3c3-bdf78e435577@amlogic.com>



On 1/9/22 11:27 PM, Christian Hewitt wrote:
> 
> 
>> On 8 Jan 2022, at 12:42 pm, Qianggui Song <qianggui.song at amlogic.com> wrote:
>>
>> Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs
>>
>> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
>> ---
>> .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> index 23b18b92c558..9300736bf1ed 100644
>> --- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> +++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
>> @@ -18,6 +18,7 @@ Required properties:
>>      "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
>>      "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
>>      "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
>> +    "amlogic,meson-a1-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
> 
> ^ should be "amlogic,meson-s4-gpio-intc? ?
Yes, thanks for pointing out
> 
> Christian
> 
>> - reg : Specifies base physical address and size of the registers.
>> - interrupt-controller : Identifies the node as an interrupt controller.
>> - #interrupt-cells : Specifies the number of cells needed to encode an
>> -- 
>> 2.34.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
> 
> .
> 


From narmstrong at baylibre.com  Mon Jan 10 05:01:30 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 10 Jan 2022 14:01:30 +0100
Subject: [PATCH v3 2/2] phy: amlogic: Add G12A Analog MIPI D-PHY driver
In-Reply-To: <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-3-narmstrong@baylibre.com>
 <CAFBinCC9J_w9JM-TmrXp7SXT27V7Ze37wrxHZZQ1==N4y2-0dg@mail.gmail.com>
Message-ID: <3f7f1c95-8a16-cb74-3a99-3f67404424db@baylibre.com>

Hi,

On 07/01/2022 23:09, Martin Blumenstingl wrote:
> Hi Neil,
> 
> On Fri, Jan 7, 2022 at 4:06 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> [...]
>> +#define HHI_MIPI_CNTL2 0x08
>> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL1      GENMASK(31, 16)
>> +#define                HHI_MIPI_CNTL2_CH_EN            GENMASK(15, 11)
>> +#define                HHI_MIPI_CNTL2_DIF_TX_CTL0      GENMASK(10, 0)
>> +
>> +#define DSI_LANE_0                             BIT(4)
>> +#define DSI_LANE_1                             BIT(3)
>> +#define DSI_LANE_CLK                           BIT(2)
>> +#define DSI_LANE_2                             BIT(1)
>> +#define DSI_LANE_3                             BIT(0)
> At first I thought that these should be named
> HHI_MIPI_CNTL2_DSI_LANE_0 (and similar).
> But then I understood that they aren't bits directly in HHI_MIPI_CNTL2
> but they belong to HHI_MIPI_CNTL2_CH_EN.
> Have you considered naming them for example
> HHI_MIPI_CNTL2_CH_EN_DSI_LANE_0 to make this more clear?
> 
> [...]
>> +       if (IS_ERR(map)) {
>> +               dev_err(dev,
>> +                       "failed to get HHI regmap\n");
>> +               return PTR_ERR(map);
> I suggest using:
>   return dev_err_probe(dev, PTR_ERR(map), "failed to get HHI regmap\n");
> to simplify the code
> 
> [...]
>> +       if (IS_ERR(priv->phy)) {
>> +               ret = PTR_ERR(priv->phy);
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(dev, "failed to create PHY\n");
>> +               return ret;
> and similar here:
>   return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n");
> 
> [...]
>> +static const struct of_device_id phy_g12a_mipi_dphy_analog_of_match[] = {
>> +       {
>> +               .compatible = "amlogic,g12a-mipi-dphy-analog",
>> +       },
>> +       { },
> In the past I was suggested to use:
>   { /* sentinel */ }
> meaning: no trailing comma here so nobody can add entries after the
> sentinel by accident.
> I suggest doing the same here if you re-spin this series.

Yep, will do the changes,

Thanks,
Neil

> 
> 
> Thank you!
> Martin
> 



From leon at kernel.org  Mon Jan 10 05:05:20 2022
From: leon at kernel.org (Leon Romanovsky)
Date: Mon, 10 Jan 2022 15:05:20 +0200
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
Message-ID: <YdwvEKiKd0JKpG9T@unreal>

On Mon, Jan 10, 2022 at 07:35:49PM +0800, Conley Lee wrote:
> This patch remove magic numbers in sun4i-emac.c and replace with macros
> defined in sun4i-emac.h
> 
> Change since v1
> ---------------
> - reformat
> - merge commits
> - add commit message

This changelog should be placed after "---" below your SOB.

Thanks

> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
>  drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
>  2 files changed, 35 insertions(+), 13 deletions(-)


From andrew at lunn.ch  Mon Jan 10 05:31:28 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 10 Jan 2022 14:31:28 +0100
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
Message-ID: <Ydw1MOcmS6fZ6J8d@lunn.ch>

> @@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
>  		if (!rxcount) {
>  			db->emacrx_completed_flag = 1;
>  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -			reg_val |= (0xf << 0) | (0x01 << 8);
> +			reg_val |=
> +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> +				 EMAC_INT_CTL_RX_EN);

Putting the first value on the next line is a bit odd. This would be
preferred:

+			reg_val |= (EMAC_INT_CTL_TX_EN |
+                                   EMAC_INT_CTL_TX_ABRT_EN |
+				    EMAC_INT_CTL_RX_EN);

I also have to wonder why two | have become three? (0x01 << 8) is
clearly a single value. (0xf << 0) should either be a single macro, or
4 macros since 0xf is four bits. Without looking into the details, i
cannot say this is wrong, but it does look strange.

       Andrew


From arnd at arndb.de  Mon Jan 10 05:35:19 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 10 Jan 2022 14:35:19 +0100
Subject: [PATCH V2 03/17] asm-generic: fcntl: compat: Remove duplicate
 definitions
In-Reply-To: <20211228143958.3409187-4-guoren@kernel.org>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-4-guoren@kernel.org>
Message-ID: <CAK8P3a2zn9M6X09WsjJ9HYiS9WnO_YPCvJLSBk+HaH+yZHQqfA@mail.gmail.com>

On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
> arch/*/include/asm/compat.h.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

Unfortunately, this one does not look correct to me:

> @@ -116,7 +116,7 @@
>  #define F_GETSIG       11      /* for sockets. */
>  #endif
>
> -#ifndef CONFIG_64BIT
> +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
>  #ifndef F_GETLK64
>  #define F_GETLK64      12      /*  using 'struct flock64' */
>  #define F_SETLK64      13

The problem here is that include/uapi/ headers cannot contain checks for
CONFIG_* symbols because those may have different meanings in user space
compared to kernel.

This is a preexisting problem in the header, but I think the change
makes it worse.

With the current behavior, user space will always see the definitions,
unless it happens to have its own definition for CONFIG_64BIT already.
On 64-bit parisc, this has the effect of defining the macros to the
same values as F_SETOWN/F_SETSIG/F_GETSIG, which is potentially
harmful. On MIPS, it uses values that are different from the 32-bit numbers
but are otherwise unused. Everywhere else, we get the definition from
the 32-bit architecture in user space, which will do nothing in the kernel.

The correct check for a uapi header would be to test for
__BITS_PER_LONG==32. We should probably do that here, but
this won't help you move the definitions, and it is a user-visible change
as the incorrect definition will no longer be visible. [Adding Jeff and Bruce
(the flock mainainers) to Cc for additional feedback on this]

For your series, I would suggest just moving the macro definitions to
include/linux/compat.h along with the 'struct compat_flock64'
definition, and leaving the duplicate one in the uapi header unchanged
until we have decided on a solution.

        Arnd


From trix at redhat.com  Mon Jan 10 05:43:00 2022
From: trix at redhat.com (Tom Rix)
Date: Mon, 10 Jan 2022 05:43:00 -0800
Subject: [PATCH] net: ethernet: mtk_eth_soc: fix error checking in
 mtk_mac_config()
In-Reply-To: <20220109164333.61dc2e89@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220108155003.3991055-1-trix@redhat.com>
 <20220109164333.61dc2e89@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <f3025d42-6ff0-8880-c0e6-3ee45a8556f7@redhat.com>


On 1/9/22 4:43 PM, Jakub Kicinski wrote:
> On Sat,  8 Jan 2022 07:50:03 -0800 trix at redhat.com wrote:
>> From: Tom Rix <trix at redhat.com>
>>
>> Clang static analysis reports this problem
>> mtk_eth_soc.c:394:7: warning: Branch condition evaluates
>>    to a garbage value
>>                  if (err)
>>                      ^~~
>>
>> err is not initialized and only conditionally set.
>> Check err consistently with the rest of mtk_mac_config(),
>> after even possible setting.
>>
>> Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
>> Signed-off-by: Tom Rix <trix at redhat.com>
>> ---
>>   drivers/net/ethernet/mediatek/mtk_eth_soc.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>> index b67b4323cff08..a27e548488584 100644
>> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
>> @@ -385,14 +385,16 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
>>   		       0 : mac->id;
>>   
>>   		/* Setup SGMIISYS with the determined property */
>> -		if (state->interface != PHY_INTERFACE_MODE_SGMII)
>> +		if (state->interface != PHY_INTERFACE_MODE_SGMII) {
>>   			err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
>>   							 state);
>> -		else if (phylink_autoneg_inband(mode))
>> +			if (err)
>> +				goto init_err;
>> +		} else if (phylink_autoneg_inband(mode)) {
>>   			err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
>> -
>> -		if (err)
>> -			goto init_err;
>> +			if (err)
>> +				goto init_err;
>> +		}
>>   
>>   		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
>>   				   SYSCFG0_SGMII_MASK, val);
> Why not init err to 0 before the if or add an else err = 0; branch?

This is the way I would have preferred to do it but the function's 
existing error handling does it this way.

I'll respin the patch.

Tom


>



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:00 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:00 +0800
Subject: [v1 00/16] Mediatek MT8186 clock support
Message-ID: <20220110134416.5191-1-chun-jie.chen@mediatek.com>

this patch series is based on 5.16-rc6 and depends on
[1]"Integrate vppsys with mtk-mmsys in MT8195".

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=603955

Chun-Jie Chen (16):
  dt-bindings: ARM: Mediatek: Add new document bindings of MT8186 clock
  clk: mediatek: Add dt-bindings of MT8186 clocks
  clk: mediatek: Add MT8186 mcusys clock support
  clk: mediatek: Add MT8186 topckgen clock support
  clk: mediatek: Add MT8186 infrastructure clock support
  clk: mediatek: Add MT8186 apmixedsys clock support
  clk: mediatek: Add MT8186 imp i2c wrapper clock support
  clk: mediatek: Add MT8186 mfgsys clock support
  clk: mediatek: Add MT8186 mmsys clock support
  clk: mediatek: Add MT8186 wpesys clock support
  clk: mediatek: Add MT8186 imgsys clock support
  clk: mediatek: Add MT8186 vdecsys clock support
  clk: mediatek: Add MT8186 vencsys clock support
  clk: mediatek: Add MT8186 camsys clock support
  clk: mediatek: Add MT8186 mdpsys clock support
  clk: mediatek: Add MT8186 ipesys clock support

 .../arm/mediatek/mediatek,mt8186-clock.yaml   | 133 ++++
 .../mediatek/mediatek,mt8186-sys-clock.yaml   |  74 ++
 drivers/clk/mediatek/Kconfig                  |   8 +
 drivers/clk/mediatek/Makefile                 |   5 +
 drivers/clk/mediatek/clk-mt8186-apmixedsys.c  | 114 +++
 drivers/clk/mediatek/clk-mt8186-cam.c         |  89 +++
 drivers/clk/mediatek/clk-mt8186-img.c         |  67 ++
 .../clk/mediatek/clk-mt8186-imp_iic_wrap.c    |  66 ++
 drivers/clk/mediatek/clk-mt8186-infra_ao.c    | 215 +++++
 drivers/clk/mediatek/clk-mt8186-ipe.c         |  54 ++
 drivers/clk/mediatek/clk-mt8186-mcu.c         |  86 ++
 drivers/clk/mediatek/clk-mt8186-mdp.c         |  79 ++
 drivers/clk/mediatek/clk-mt8186-mfg.c         |  47 ++
 drivers/clk/mediatek/clk-mt8186-mm.c          |  97 +++
 drivers/clk/mediatek/clk-mt8186-topckgen.c    | 737 ++++++++++++++++++
 drivers/clk/mediatek/clk-mt8186-vdec.c        |  87 +++
 drivers/clk/mediatek/clk-mt8186-venc.c        |  50 ++
 drivers/clk/mediatek/clk-mt8186-wpe.c         |  50 ++
 include/dt-bindings/clock/mt8186-clk.h        | 445 +++++++++++
 19 files changed, 2503 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
 create mode 100644 drivers/clk/mediatek/clk-mt8186-apmixedsys.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-cam.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-img.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-imp_iic_wrap.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-infra_ao.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-ipe.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mcu.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mdp.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mfg.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mm.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-topckgen.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-vdec.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-venc.c
 create mode 100644 drivers/clk/mediatek/clk-mt8186-wpe.c
 create mode 100644 include/dt-bindings/clock/mt8186-clk.h

-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:01 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:01 +0800
Subject: [v1 01/16] dt-bindings: ARM: Mediatek: Add new document bindings of
 MT8186 clock
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-2-chun-jie.chen@mediatek.com>

This patch adds the new binding documentation for system clock
and functional clock on Mediatek MT8186.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 .../arm/mediatek/mediatek,mt8186-clock.yaml   | 133 ++++++++++++++++++
 .../mediatek/mediatek,mt8186-sys-clock.yaml   |  74 ++++++++++
 2 files changed, 207 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
 create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
new file mode 100644
index 000000000000..fc39101bc9b0
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
@@ -0,0 +1,133 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Functional Clock Controller for MT8186
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+description:
+  The clock architecture in Mediatek like below
+  PLLs -->
+          dividers -->
+                      muxes
+                           -->
+                              clock gate
+
+  The devices provide clock gate control in different IP blocks.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8186-imp_iic_wrap
+          - mediatek,mt8186-mfgsys
+          - mediatek,mt8186-wpesys
+          - mediatek,mt8186-imgsys1
+          - mediatek,mt8186-imgsys2
+          - mediatek,mt8186-vdecsys
+          - mediatek,mt8186-vencsys
+          - mediatek,mt8186-camsys
+          - mediatek,mt8186-camsys_rawa
+          - mediatek,mt8186-camsys_rawb
+          - mediatek,mt8186-mdpsys
+          - mediatek,mt8186-ipesys
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    imp_iic_wrap: clock-controller at 11017000 {
+        compatible = "mediatek,mt8186-imp_iic_wrap";
+        reg = <0x11017000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    mfgsys: clock-controller at 13000000 {
+        compatible = "mediatek,mt8186-mfgsys";
+        reg = <0x13000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    wpesys: clock-controller at 14020000 {
+        compatible = "mediatek,mt8186-wpesys";
+        reg = <0x14020000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys1: clock-controller at 15020000 {
+        compatible = "mediatek,mt8186-imgsys1";
+        reg = <0x15020000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    imgsys2: clock-controller at 15820000 {
+        compatible = "mediatek,mt8186-imgsys2";
+        reg = <0x15820000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vdecsys: clock-controller at 1602f000 {
+        compatible = "mediatek,mt8186-vdecsys";
+        reg = <0x1602f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    vencsys: clock-controller at 17000000 {
+        compatible = "mediatek,mt8186-vencsys";
+        reg = <0x17000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys: clock-controller at 1a000000 {
+        compatible = "mediatek,mt8186-camsys";
+        reg = <0x1a000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawa: clock-controller at 1a04f000 {
+        compatible = "mediatek,mt8186-camsys_rawa";
+        reg = <0x1a04f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    camsys_rawb: clock-controller at 1a06f000 {
+        compatible = "mediatek,mt8186-camsys_rawb";
+        reg = <0x1a06f000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    mdpsys: clock-controller at 1b000000 {
+        compatible = "mediatek,mt8186-mdpsys";
+        reg = <0x1b000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    ipesys: clock-controller at 1c000000 {
+        compatible = "mediatek,mt8186-ipesys";
+        reg = <0x1c000000 0x1000>;
+        #clock-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
new file mode 100644
index 000000000000..11473971a165
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-sys-clock.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek System Clock Controller for MT8186
+
+maintainers:
+  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+description:
+  The clock architecture in Mediatek like below
+  PLLs -->
+          dividers -->
+                      muxes
+                           -->
+                              clock gate
+
+  The apmixedsys provides most of PLLs which generated from SoC 26m.
+  The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
+  The infracfg_ao provides clock gate in peripheral and infrastructure IP blocks.
+  The mcusys provides mux control to select the clock source in AP MCU.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt8186-mcusys
+          - mediatek,mt8186-topckgen
+          - mediatek,mt8186-infracfg_ao
+          - mediatek,mt8186-apmixedsys
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    mcusys: syscon at c53a000 {
+        compatible = "mediatek,mt8186-mcusys", "syscon";
+        reg = <0xc53a000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    topckgen: syscon at 10000000 {
+        compatible = "mediatek,mt8186-topckgen", "syscon";
+        reg = <0x10000000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    infracfg_ao: syscon at 10001000 {
+        compatible = "mediatek,mt8186-infracfg_ao", "syscon";
+        reg = <0x10001000 0x1000>;
+        #clock-cells = <1>;
+    };
+
+  - |
+    apmixedsys: syscon at 1000c000 {
+        compatible = "mediatek,mt8186-apmixedsys", "syscon";
+        reg = <0x1000c000 0x1000>;
+        #clock-cells = <1>;
+    };
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:03 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:03 +0800
Subject: [v1 03/16] clk: mediatek: Add MT8186 mcusys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-4-chun-jie.chen@mediatek.com>

Add MT8186 mcusys clock controller which provides muxes
to select the clock source of APMCU.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig          |  8 +++
 drivers/clk/mediatek/Makefile         |  1 +
 drivers/clk/mediatek/clk-mt8186-mcu.c | 86 +++++++++++++++++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mcu.c

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 3ce6fb04d8ff..7218165b6a44 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -495,6 +495,14 @@ config COMMON_CLK_MT8183_VENCSYS
 	help
 	  This driver supports MediaTek MT8183 vencsys clocks.
 
+config COMMON_CLK_MT8186
+	bool "Clock driver for MediaTek MT8186"
+	depends on ARM64 || COMPILE_TEST
+	select COMMON_CLK_MEDIATEK
+	default ARCH_MEDIATEK
+	help
+	  This driver supports MediaTek MT8186 clocks.
+
 config COMMON_CLK_MT8192
 	bool "Clock driver for MediaTek MT8192"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index dc96038a0155..0ae3828f69fb 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
 obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
+obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-mcu.c b/drivers/clk/mediatek/clk-mt8186-mcu.c
new file mode 100644
index 000000000000..293176633f65
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-mcu.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static DEFINE_SPINLOCK(mt8186_clk_lock);
+
+static const char * const mcu_armpll_ll_parents[] = {
+	"clk26m",
+	"armpll_ll",
+	"mainpll",
+	"univpll_d2"
+};
+
+static const char * const mcu_armpll_bl_parents[] = {
+	"clk26m",
+	"armpll_bl",
+	"mainpll",
+	"univpll_d2"
+};
+
+static const char * const mcu_armpll_bus_parents[] = {
+	"clk26m",
+	"ccipll",
+	"mainpll",
+	"univpll_d2"
+};
+
+static struct mtk_composite mcu_muxes[] = {
+	/* CPU_PLLDIV_CFG0 */
+	MUX(CLK_MCU_ARMPLL_LL_SEL, "mcu_armpll_ll_sel", mcu_armpll_ll_parents, 0x2A0, 9, 2),
+	/* CPU_PLLDIV_CFG1 */
+	MUX(CLK_MCU_ARMPLL_BL_SEL, "mcu_armpll_bl_sel", mcu_armpll_bl_parents, 0x2A4, 9, 2),
+	/* BUS_PLLDIV_CFG */
+	MUX(CLK_MCU_ARMPLL_BUS_SEL, "mcu_armpll_bus_sel", mcu_armpll_bus_parents, 0x2E0, 9, 2),
+};
+
+static const struct of_device_id of_match_clk_mt8186_mcu[] = {
+	{ .compatible = "mediatek,mt8186-mcusys", },
+	{}
+};
+
+static int clk_mt8186_mcu_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
+				    &mt8186_clk_lock, clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8186_mcu_drv = {
+	.probe = clk_mt8186_mcu_probe,
+	.driver = {
+		.name = "clk-mt8186-mcu",
+		.of_match_table = of_match_clk_mt8186_mcu,
+	},
+};
+builtin_platform_driver(clk_mt8186_mcu_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:04 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:04 +0800
Subject: [v1 04/16] clk: mediatek: Add MT8186 topckgen clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-5-chun-jie.chen@mediatek.com>

Add MT8186 topckgen clock controller which provides muxes, dividers
to handle variety clock selection in other IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile              |   2 +-
 drivers/clk/mediatek/clk-mt8186-topckgen.c | 737 +++++++++++++++++++++
 2 files changed, 738 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-topckgen.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 0ae3828f69fb..a5166f0860bd 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -67,7 +67,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
 obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o
+obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-topckgen.c b/drivers/clk/mediatek/clk-mt8186-topckgen.c
new file mode 100644
index 000000000000..096178bed8de
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-topckgen.c
@@ -0,0 +1,737 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-mtk.h"
+#include "clk-mux.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static DEFINE_SPINLOCK(mt8186_clk_lock);
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+	FIXED_CLK(CLK_TOP_ULPOSC1, "ulposc1", NULL, 250000000),
+	FIXED_CLK(CLK_TOP_466M_FMEM, "hd_466m_fmem_ck", NULL, 466000000),
+	FIXED_CLK(CLK_TOP_MPLL, "mpll", NULL, 208000000),
+};
+
+static const struct mtk_fixed_factor top_divs[] = {
+	FACTOR(CLK_TOP_MAINPLL_D2, "mainpll_d2", "mainpll", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D2_D2, "mainpll_d2_d2", "mainpll_d2", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D2_D4, "mainpll_d2_d4", "mainpll_d2", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D2_D16, "mainpll_d2_d16", "mainpll_d2", 1, 16),
+	FACTOR(CLK_TOP_MAINPLL_D3, "mainpll_d3", "mainpll", 1, 3),
+	FACTOR(CLK_TOP_MAINPLL_D3_D2, "mainpll_d3_d2", "mainpll_d3", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D3_D4, "mainpll_d3_d4", "mainpll_d3", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D5, "mainpll_d5", "mainpll", 1, 5),
+	FACTOR(CLK_TOP_MAINPLL_D5_D2, "mainpll_d5_d2", "mainpll_d5", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D5_D4, "mainpll_d5_d4", "mainpll_d5", 1, 4),
+	FACTOR(CLK_TOP_MAINPLL_D7, "mainpll_d7", "mainpll", 1, 7),
+	FACTOR(CLK_TOP_MAINPLL_D7_D2, "mainpll_d7_d2", "mainpll_d7", 1, 2),
+	FACTOR(CLK_TOP_MAINPLL_D7_D4, "mainpll_d7_d4", "mainpll_d7", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL, "univpll", "univ2pll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D2_D2, "univpll_d2_d2", "univpll_d2", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D2_D4, "univpll_d2_d4", "univpll_d2", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3),
+	FACTOR(CLK_TOP_UNIVPLL_D3_D2, "univpll_d3_d2", "univpll_d3", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D3_D4, "univpll_d3_d4", "univpll_d3", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D3_D8, "univpll_d3_d8", "univpll_d3", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_D3_D32, "univpll_d3_d32", "univpll_d3", 1, 32),
+	FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5),
+	FACTOR(CLK_TOP_UNIVPLL_D5_D2, "univpll_d5_d2", "univpll_d5", 1, 2),
+	FACTOR(CLK_TOP_UNIVPLL_D5_D4, "univpll_d5_d4", "univpll_d5", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll", 1, 7),
+	FACTOR(CLK_TOP_UNIVPLL_192M, "univpll_192m", "univ2pll", 1, 13),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D4, "univpll_192m_d4", "univpll_192m", 1, 4),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D8, "univpll_192m_d8", "univpll_192m", 1, 8),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D16, "univpll_192m_d16", "univpll_192m", 1, 16),
+	FACTOR(CLK_TOP_UNIVPLL_192M_D32, "univpll_192m_d32", "univpll_192m", 1, 32),
+	FACTOR(CLK_TOP_APLL1_D2, "apll1_d2", "apll1", 1, 2),
+	FACTOR(CLK_TOP_APLL1_D4, "apll1_d4", "apll1", 1, 4),
+	FACTOR(CLK_TOP_APLL1_D8, "apll1_d8", "apll1", 1, 8),
+	FACTOR(CLK_TOP_APLL2_D2, "apll2_d2", "apll2", 1, 2),
+	FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
+	FACTOR(CLK_TOP_APLL2_D8, "apll2_d8", "apll2", 1, 8),
+	FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2),
+	FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4),
+	FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll", 1, 8),
+	FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll", 1, 16),
+	FACTOR(CLK_TOP_TVDPLL_D32, "tvdpll_d32", "tvdpll", 1, 32),
+	FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC1_D2, "ulposc1_d2", "ulposc1", 1, 2),
+	FACTOR(CLK_TOP_ULPOSC1_D4, "ulposc1_d4", "ulposc1", 1, 4),
+	FACTOR(CLK_TOP_ULPOSC1_D8, "ulposc1_d8", "ulposc1", 1, 8),
+	FACTOR(CLK_TOP_ULPOSC1_D10, "ulposc1_d10", "ulposc1", 1, 10),
+	FACTOR(CLK_TOP_ULPOSC1_D16, "ulposc1_d16", "ulposc1", 1, 16),
+	FACTOR(CLK_TOP_ULPOSC1_D32, "ulposc1_d32", "ulposc1", 1, 32),
+	FACTOR(CLK_TOP_ADSPPLL_D2, "adsppll_d2", "adsppll", 1, 2),
+	FACTOR(CLK_TOP_ADSPPLL_D4, "adsppll_d4", "adsppll", 1, 4),
+	FACTOR(CLK_TOP_ADSPPLL_D8, "adsppll_d8", "adsppll", 1, 8),
+	FACTOR(CLK_TOP_NNAPLL_D2, "nnapll_d2", "nnapll", 1, 2),
+	FACTOR(CLK_TOP_NNAPLL_D4, "nnapll_d4", "nnapll", 1, 4),
+	FACTOR(CLK_TOP_NNAPLL_D8, "nnapll_d8", "nnapll", 1, 8),
+	FACTOR(CLK_TOP_NNA2PLL_D2, "nna2pll_d2", "nna2pll", 1, 2),
+	FACTOR(CLK_TOP_NNA2PLL_D4, "nna2pll_d4", "nna2pll", 1, 4),
+	FACTOR(CLK_TOP_NNA2PLL_D8, "nna2pll_d8", "nna2pll", 1, 8),
+	FACTOR(CLK_TOP_F_BIST2FPC, "f_bist2fpc_ck", "univpll_d3_d2", 1, 1),
+};
+
+static const char * const axi_parents[] = {
+	"clk26m",
+	"mainpll_d7",
+	"mainpll_d2_d4",
+	"univpll_d7"
+};
+
+static const char * const scp_parents[] = {
+	"clk26m",
+	"mainpll_d2_d4",
+	"mainpll_d5",
+	"mainpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3"
+};
+
+static const char * const mfg_parents[] = {
+	"clk26m",
+	"mfgpll",
+	"mainpll_d3",
+	"mainpll_d5"
+};
+
+static const char * const camtg_parents[] = {
+	"clk26m",
+	"univpll_192m_d8",
+	"univpll_d3_d8",
+	"univpll_192m_d4",
+	"univpll_d3_d32",
+	"univpll_192m_d16",
+	"univpll_192m_d32"
+};
+
+static const char * const uart_parents[] = {
+	"clk26m",
+	"univpll_d3_d8"
+};
+
+static const char * const spi_parents[] = {
+	"clk26m",
+	"mainpll_d5_d4",
+	"mainpll_d3_d4",
+	"mainpll_d5_d2",
+	"mainpll_d2_d4",
+	"mainpll_d7",
+	"mainpll_d3_d2",
+	"mainpll_d5"
+};
+
+static const char * const msdc5hclk_parents[] = {
+	"clk26m",
+	"mainpll_d2_d2",
+	"mainpll_d7",
+	"mainpll_d3_d2"
+};
+
+static const char * const msdc50_0_parents[] = {
+	"clk26m",
+	"msdcpll",
+	"univpll_d3",
+	"msdcpll_d2",
+	"mainpll_d7",
+	"mainpll_d3_d2",
+	"univpll_d2_d2"
+};
+
+static const char * const msdc30_1_parents[] = {
+	"clk26m",
+	"msdcpll_d2",
+	"univpll_d3_d2",
+	"mainpll_d3_d2",
+	"mainpll_d7"
+};
+
+static const char * const audio_parents[] = {
+	"clk26m",
+	"mainpll_d5_d4",
+	"mainpll_d7_d4",
+	"mainpll_d2_d16"
+};
+
+static const char * const aud_intbus_parents[] = {
+	"clk26m",
+	"mainpll_d2_d4",
+	"mainpll_d7_d2"
+};
+
+static const char * const aud_1_parents[] = {
+	"clk26m",
+	"apll1"
+};
+
+static const char * const aud_2_parents[] = {
+	"clk26m",
+	"apll2"
+};
+
+static const char * const aud_engen1_parents[] = {
+	"clk26m",
+	"apll1_d2",
+	"apll1_d4",
+	"apll1_d8"
+};
+
+static const char * const aud_engen2_parents[] = {
+	"clk26m",
+	"apll2_d2",
+	"apll2_d4",
+	"apll2_d8"
+};
+
+static const char * const disp_pwm_parents[] = {
+	"clk26m",
+	"univpll_d5_d2",
+	"univpll_d3_d4",
+	"ulposc1_d2",
+	"ulposc1_d8"
+};
+
+static const char * const sspm_parents[] = {
+	"clk26m",
+	"mainpll_d2_d2",
+	"mainpll_d3_d2",
+	"mainpll_d5",
+	"mainpll_d3"
+};
+
+static const char * const dxcc_parents[] = {
+	"clk26m",
+	"mainpll_d2_d2",
+	"mainpll_d2_d4"
+};
+
+static const char * const usb_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"univpll_d5_d2"
+};
+
+static const char * const srck_parents[] = {
+	"clk32k",
+	"clk26m",
+	"ulposc1_d10"
+};
+
+static const char * const spm_parents[] = {
+	"clk32k",
+	"ulposc1_d10",
+	"clk26m",
+	"mainpll_d7_d2"
+};
+
+static const char * const i2c_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"univpll_d3_d4",
+	"univpll_d5_d2"
+};
+
+static const char * const pwm_parents[] = {
+	"clk26m",
+	"univpll_d3_d8",
+	"univpll_d3_d4",
+	"univpll_d2_d4"
+};
+
+static const char * const seninf_parents[] = {
+	"clk26m",
+	"univpll_d2_d4",
+	"univpll_d2_d2",
+	"univpll_d3_d2"
+};
+
+static const char * const aes_msdcfde_parents[] = {
+	"clk26m",
+	"univpll_d3",
+	"mainpll_d3",
+	"univpll_d2_d2",
+	"mainpll_d2_d2",
+	"mainpll_d2_d4"
+};
+
+static const char * const pwrap_ulposc_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"ulposc1_d4",
+	"ulposc1_d8",
+	"ulposc1_d10",
+	"ulposc1_d16",
+	"ulposc1_d32"
+};
+
+static const char * const camtm_parents[] = {
+	"clk26m",
+	"univpll_d2_d4",
+	"univpll_d3_d2"
+};
+
+static const char * const venc_parents[] = {
+	"clk26m",
+	"mmpll",
+	"mainpll_d2_d2",
+	"mainpll_d2",
+	"univpll_d3",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"mmpll"
+};
+
+static const char * const isp_parents[] = {
+	"clk26m",
+	"mainpll_d2",
+	"mainpll_d2_d2",
+	"univpll_d3",
+	"mainpll_d3",
+	"mmpll",
+	"univpll_d5",
+	"univpll_d2_d2",
+	"mmpll_d2"
+};
+
+static const char * const dpmaif_parents[] = {
+	"clk26m",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"mainpll_d2_d2",
+	"univpll_d3_d2"
+};
+
+static const char * const vdec_parents[] = {
+	"clk26m",
+	"mainpll_d3",
+	"mainpll_d2_d2",
+	"univpll_d5",
+	"mainpll_d2",
+	"univpll_d3",
+	"univpll_d2_d2"
+};
+
+static const char * const disp_parents[] = {
+	"clk26m",
+	"univpll_d3_d2",
+	"mainpll_d5",
+	"univpll_d5",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3",
+	"mainpll_d2",
+	"mmpll"
+};
+
+static const char * const mdp_parents[] = {
+	"clk26m",
+	"mainpll_d5",
+	"univpll_d5",
+	"mainpll_d2_d2",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3",
+	"mainpll_d2",
+	"mmpll"
+};
+
+static const char * const audio_h_parents[] = {
+	"clk26m",
+	"univpll_d7",
+	"apll1",
+	"apll2"
+};
+
+static const char * const ufs_parents[] = {
+	"clk26m",
+	"mainpll_d7",
+	"univpll_d2_d4",
+	"mainpll_d2_d4"
+};
+
+static const char * const aes_fde_parents[] = {
+	"clk26m",
+	"univpll_d3",
+	"mainpll_d2_d2",
+	"univpll_d5"
+};
+
+static const char * const audiodsp_parents[] = {
+	"clk26m",
+	"ulposc1_d10",
+	"adsppll",
+	"adsppll_d2",
+	"adsppll_d4",
+	"adsppll_d8"
+};
+
+static const char * const dvfsrc_parents[] = {
+	"clk26m",
+	"ulposc1_d10",
+};
+
+static const char * const dsi_occ_parents[] = {
+	"clk26m",
+	"univpll_d3_d2",
+	"mpll",
+	"mainpll_d5"
+};
+
+static const char * const spmi_mst_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"ulposc1_d4",
+	"ulposc1_d8",
+	"ulposc1_d10",
+	"ulposc1_d16",
+	"ulposc1_d32"
+};
+
+static const char * const spinor_parents[] = {
+	"clk26m",
+	"clk13m",
+	"mainpll_d7_d4",
+	"univpll_d3_d8",
+	"univpll_d5_d4",
+	"mainpll_d7_d2"
+};
+
+static const char * const nna_parents[] = {
+	"clk26m",
+	"univpll_d3_d8",
+	"mainpll_d2_d4",
+	"univpll_d3_d2",
+	"mainpll_d2_d2",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3",
+	"mmpll",
+	"mainpll_d2",
+	"univpll_d2",
+	"nnapll_d2",
+	"nnapll_d4",
+	"nnapll_d8",
+	"nnapll",
+	"nna2pll"
+};
+
+static const char * const nna2_parents[] = {
+	"clk26m",
+	"univpll_d3_d8",
+	"mainpll_d2_d4",
+	"univpll_d3_d2",
+	"mainpll_d2_d2",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3",
+	"mmpll",
+	"mainpll_d2",
+	"univpll_d2",
+	"nna2pll_d2",
+	"nna2pll_d4",
+	"nna2pll_d8",
+	"nnapll",
+	"nna2pll"
+};
+
+static const char * const ssusb_parents[] = {
+	"clk26m",
+	"univpll_d5_d4",
+	"univpll_d5_d2"
+};
+
+static const char * const wpe_parents[] = {
+	"clk26m",
+	"univpll_d3_d2",
+	"mainpll_d5",
+	"univpll_d5",
+	"univpll_d2_d2",
+	"mainpll_d3",
+	"univpll_d3",
+	"mainpll_d2",
+	"mmpll"
+};
+
+static const char * const dpi_parents[] = {
+	"clk26m",
+	"tvdpll",
+	"tvdpll_d2",
+	"tvdpll_d4",
+	"tvdpll_d8",
+	"tvdpll_d16",
+	"tvdpll_d32"
+};
+
+static const char * const u3_occ_250m_parents[] = {
+	"clk26m",
+	"univpll_d5"
+};
+
+static const char * const u3_occ_500m_parents[] = {
+	"clk26m",
+	"nna2pll_d2"
+};
+
+static const char * const adsp_bus_parents[] = {
+	"clk26m",
+	"ulposc1_d2",
+	"mainpll_d5",
+	"mainpll_d2_d2",
+	"mainpll_d3",
+	"mainpll_d2",
+	"univpll_d3"
+};
+
+static const char * const apll_mck_parents[] = {
+	"top_aud_1",
+	"top_aud_2"
+};
+
+static const struct mtk_mux top_mtk_muxes[] = {
+	/*
+	 * CLK_CFG_0
+	 * top_axi is bus clock, should not be closed by Linux.
+	 * top_scp is main clock in always-on co-processor.
+	 */
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI, "top_axi", axi_parents,
+				   0x0040, 0x0044, 0x0048, 0, 2, 7, 0x0004, 0,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SCP, "top_scp", scp_parents,
+				   0x0040, 0x0044, 0x0048, 8, 3, 15, 0x0004, 1,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG, "top_mfg",
+		mfg_parents, 0x0040, 0x0044, 0x0048, 16, 2, 23, 0x0004, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG, "top_camtg",
+		camtg_parents, 0x0040, 0x0044, 0x0048, 24, 3, 31, 0x0004, 3),
+	/* CLK_CFG_1 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG1, "top_camtg1",
+		camtg_parents, 0x0050, 0x0054, 0x0058, 0, 3, 7, 0x0004, 4),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG2, "top_camtg2",
+		camtg_parents, 0x0050, 0x0054, 0x0058, 8, 3, 15, 0x0004, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG3, "top_camtg3",
+		camtg_parents, 0x0050, 0x0054, 0x0058, 16, 3, 23, 0x0004, 6),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG4, "top_camtg4",
+		camtg_parents, 0x0050, 0x0054, 0x0058, 24, 3, 31, 0x0004, 7),
+	/* CLK_CFG_2 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG5, "top_camtg5",
+		camtg_parents, 0x0060, 0x0064, 0x0068, 0, 3, 7, 0x0004, 8),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG6, "top_camtg6",
+		camtg_parents, 0x0060, 0x0064, 0x0068, 8, 3, 15, 0x0004, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UART, "top_uart",
+		uart_parents, 0x0060, 0x0064, 0x0068, 16, 1, 23, 0x0004, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI, "top_spi",
+		spi_parents, 0x0060, 0x0064, 0x0068, 24, 3, 31, 0x0004, 11),
+	/* CLK_CFG_3 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_HCLK, "top_msdc5hclk",
+		msdc5hclk_parents, 0x0070, 0x0074, 0x0078, 0, 2, 7, 0x0004, 12),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0, "top_msdc50_0",
+		msdc50_0_parents, 0x0070, 0x0074, 0x0078, 8, 3, 15, 0x0004, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1, "top_msdc30_1",
+		msdc30_1_parents, 0x0070, 0x0074, 0x0078, 16, 3, 23, 0x0004, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO, "top_audio",
+		audio_parents, 0x0070, 0x0074, 0x0078, 24, 2, 31, 0x0004, 15),
+	/* CLK_CFG_4 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_INTBUS, "top_aud_intbus",
+		aud_intbus_parents, 0x0080, 0x0084, 0x0088, 0, 2, 7, 0x0004, 16),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_1, "top_aud_1",
+		aud_1_parents, 0x0080, 0x0084, 0x0088, 8, 1, 15, 0x0004, 17),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_2, "top_aud_2",
+		aud_2_parents, 0x0080, 0x0084, 0x0088, 16, 1, 23, 0x0004, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN1, "top_aud_engen1",
+		aud_engen1_parents, 0x0080, 0x0084, 0x0088, 24, 2, 31, 0x0004, 19),
+	/*
+	 * CLK_CFG_5
+	 * top_sspm is main clock in always-on co-processor, should not be closed
+	 * in Linux.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_ENGEN2, "top_aud_engen2",
+		aud_engen2_parents, 0x0090, 0x0094, 0x0098, 0, 2, 7, 0x0004, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM, "top_disp_pwm",
+		disp_pwm_parents, 0x0090, 0x0094, 0x0098, 8, 3, 15, 0x0004, 21),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SSPM, "top_sspm", sspm_parents,
+				   0x0090, 0x0094, 0x0098, 16, 3, 23, 0x0004, 22,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DXCC, "top_dxcc",
+		dxcc_parents, 0x0090, 0x0094, 0x0098, 24, 2, 31, 0x0004, 23),
+	/*
+	 * CLK_CFG_6
+	 * top_spm and top_srck are main clocks in always-on co-processor.
+	 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_TOP, "top_usb",
+		usb_parents, 0x00a0, 0x00a4, 0x00a8, 0, 2, 7, 0x0004, 24),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SRCK, "top_srck", srck_parents,
+				   0x00a0, 0x00a4, 0x00a8, 8, 2, 15, 0x0004, 25,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SPM, "top_spm", spm_parents,
+				   0x00a0, 0x00a4, 0x00a8, 16, 2, 23, 0x0004, 26,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C, "top_i2c",
+		i2c_parents, 0x00a0, 0x00a4, 0x00a8, 24, 2, 31, 0x0004, 27),
+	/* CLK_CFG_7 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM, "top_pwm",
+		pwm_parents, 0x00b0, 0x00b4, 0x00b8, 0, 2, 7, 0x0004, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF, "top_seninf",
+		seninf_parents, 0x00b0, 0x00b4, 0x00b8, 8, 2, 15, 0x0004, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF1, "top_seninf1",
+		seninf_parents, 0x00b0, 0x00b4, 0x00b8, 16, 2, 23, 0x0004, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF2, "top_seninf2",
+		seninf_parents, 0x00b0, 0x00b4, 0x00b8, 24, 2, 31, 0x0008, 0),
+	/* CLK_CFG_8 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SENINF3, "top_seninf3",
+		seninf_parents, 0x00c0, 0x00c4, 0x00c8, 0, 2, 7, 0x0008, 1),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_MSDCFDE, "top_aes_msdcfde",
+		aes_msdcfde_parents, 0x00c0, 0x00c4, 0x00c8, 8, 3, 15, 0x0008, 2),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_PWRAP_ULPOSC, "top_pwrap_ulposc",
+		pwrap_ulposc_parents, 0x00c0, 0x00c4, 0x00c8, 16, 3, 23, 0x0008, 3),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTM, "top_camtm",
+		camtm_parents, 0x00c0, 0x00c4, 0x00c8, 24, 2, 31, 0x0008, 4),
+	/* CLK_CFG_9 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_VENC, "top_venc",
+		venc_parents, 0x00d0, 0x00d4, 0x00d8, 0, 3, 7, 0x0008, 5),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_CAM, "top_cam",
+		isp_parents, 0x00d0, 0x00d4, 0x00d8, 8, 4, 15, 0x0008, 6),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_IMG1, "top_img1",
+		isp_parents, 0x00d0, 0x00d4, 0x00d8, 16, 4, 23, 0x0008, 7),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_IPE, "top_ipe",
+		isp_parents, 0x00d0, 0x00d4, 0x00d8, 24, 4, 31, 0x0008, 8),
+	/* CLK_CFG_10 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DPMAIF, "top_dpmaif",
+		dpmaif_parents, 0x00e0, 0x00e4, 0x00e8, 0, 3, 7, 0x0008, 9),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC, "top_vdec",
+		vdec_parents, 0x00e0, 0x00e4, 0x00e8, 8, 3, 15, 0x0008, 10),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP, "top_disp",
+		disp_parents, 0x00e0, 0x00e4, 0x00e8, 16, 4, 23, 0x0008, 11),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_MDP, "top_mdp",
+		mdp_parents, 0x00e0, 0x00e4, 0x00e8, 24, 4, 31, 0x0008, 12),
+	/* CLK_CFG_11 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_H, "top_audio_h",
+		audio_h_parents, 0x00ec, 0x00f0, 0x00f4, 0, 2, 7, 0x0008, 13),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_UFS, "top_ufs",
+		ufs_parents, 0x00ec, 0x00f0, 0x00f4, 8, 2, 15, 0x0008, 14),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AES_FDE, "top_aes_fde",
+		aes_fde_parents, 0x00ec, 0x00f0, 0x00f4, 16, 2, 23, 0x0008, 15),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIODSP, "top_audiodsp",
+		audiodsp_parents, 0x00ec, 0x00f0, 0x00f4, 24, 3, 31, 0x0008, 16),
+	/*
+	 * CLK_CFG_12
+	 * dvfsrc is for internal DVFS usage, should not be closed in Linux.
+	 */
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DVFSRC, "top_dvfsrc", dvfsrc_parents,
+				   0x0100, 0x0104, 0x0108, 0, 1, 7, 0x0008, 17,
+				   CLK_IS_CRITICAL),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DSI_OCC, "top_dsi_occ",
+		dsi_occ_parents, 0x0100, 0x0104, 0x0108, 8, 2, 15, 0x0008, 18),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPMI_MST, "top_spmi_mst",
+		spmi_mst_parents, 0x0100, 0x0104, 0x0108, 16, 3, 23, 0x0008, 19),
+	/* CLK_CFG_13 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINOR, "top_spinor",
+		spinor_parents, 0x0110, 0x0114, 0x0118, 0, 3, 6, 0x0008, 20),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA, "top_nna",
+		nna_parents, 0x0110, 0x0114, 0x0118, 7, 4, 14, 0x0008, 21),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA1, "top_nna1",
+		nna_parents, 0x0110, 0x0114, 0x0118, 15, 4, 22, 0x0008, 22),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_NNA2, "top_nna2",
+		nna2_parents, 0x0110, 0x0114, 0x0118, 23, 4, 30, 0x0008, 23),
+	/* CLK_CFG_14 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI, "top_ssusb_xhci",
+		ssusb_parents, 0x0120, 0x0124, 0x0128, 0, 2, 5, 0x0008, 24),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_TOP_1P, "top_ssusb_1p",
+		ssusb_parents, 0x0120, 0x0124, 0x0128, 6, 2, 11, 0x0008, 25),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_SSUSB_XHCI_1P, "top_ssusb_xhci_1p",
+		ssusb_parents, 0x0120, 0x0124, 0x0128, 12, 2, 17, 0x0008, 26),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_WPE, "top_wpe",
+		wpe_parents, 0x0120, 0x0124, 0x0128, 18, 4, 25, 0x0008, 27),
+	/* CLK_CFG_15 */
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi",
+		dpi_parents, 0x0180, 0x0184, 0x0188, 0, 3, 6, 0x0008, 28),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U3_OCC_250M, "top_u3_occ_250m",
+		u3_occ_250m_parents, 0x0180, 0x0184, 0x0188, 7, 1, 11, 0x0008, 29),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_U3_OCC_500M, "top_u3_occ_500m",
+		u3_occ_500m_parents, 0x0180, 0x0184, 0x0188, 12, 1, 16, 0x0008, 30),
+	MUX_GATE_CLR_SET_UPD(CLK_TOP_ADSP_BUS, "top_adsp_bus",
+		adsp_bus_parents, 0x0180, 0x0184, 0x0188, 17, 3, 23, 0x0008, 31),
+};
+
+static struct mtk_composite top_muxes[] = {
+	/* CLK_AUDDIV_0 */
+	MUX(CLK_TOP_APLL_I2S0_MCK_SEL, "apll_i2s0_mck_sel", apll_mck_parents, 0x0320, 16, 1),
+	MUX(CLK_TOP_APLL_I2S1_MCK_SEL, "apll_i2s1_mck_sel", apll_mck_parents, 0x0320, 17, 1),
+	MUX(CLK_TOP_APLL_I2S2_MCK_SEL, "apll_i2s2_mck_sel", apll_mck_parents, 0x0320, 18, 1),
+	MUX(CLK_TOP_APLL_I2S4_MCK_SEL, "apll_i2s4_mck_sel", apll_mck_parents, 0x0320, 19, 1),
+	MUX(CLK_TOP_APLL_TDMOUT_MCK_SEL, "apll_tdmout_mck_sel", apll_mck_parents,
+		0x0320, 20, 1),
+};
+
+static const struct mtk_composite top_adj_divs[] = {
+	DIV_GATE(CLK_TOP_APLL12_CK_DIV0, "apll12_div0", "apll_i2s0_mck_sel",
+			0x0320, 0, 0x0328, 8, 0),
+	DIV_GATE(CLK_TOP_APLL12_CK_DIV1, "apll12_div1", "apll_i2s1_mck_sel",
+			0x0320, 1, 0x0328, 8, 8),
+	DIV_GATE(CLK_TOP_APLL12_CK_DIV2, "apll12_div2", "apll_i2s2_mck_sel",
+			0x0320, 2, 0x0328, 8, 16),
+	DIV_GATE(CLK_TOP_APLL12_CK_DIV4, "apll12_div4", "apll_i2s4_mck_sel",
+			0x0320, 3, 0x0328, 8, 24),
+	DIV_GATE(CLK_TOP_APLL12_CK_DIV_TDMOUT_M, "apll12_div_tdmout_m", "apll_tdmout_mck_sel",
+			0x0320, 4, 0x0334, 8, 0),
+};
+
+static const struct of_device_id of_match_clk_mt8186_topck[] = {
+	{ .compatible = "mediatek,mt8186-topckgen", },
+	{}
+};
+
+static int clk_mt8186_topck_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+				    clk_data);
+	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
+	mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
+			       &mt8186_clk_lock, clk_data);
+
+	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+				    &mt8186_clk_lock, clk_data);
+	mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+				    &mt8186_clk_lock, clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8186_topck_drv = {
+	.probe = clk_mt8186_topck_probe,
+	.driver = {
+		.name = "clk-mt8186-topck",
+		.of_match_table = of_match_clk_mt8186_topck,
+	},
+};
+builtin_platform_driver(clk_mt8186_topck_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:05 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:05 +0800
Subject: [v1 05/16] clk: mediatek: Add MT8186 infrastructure clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-6-chun-jie.chen@mediatek.com>

Add MT8186 infrastructure clock controller which provides
clock gate control for basic IP like pwm, uart, spi and so on.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile              |   2 +-
 drivers/clk/mediatek/clk-mt8186-infra_ao.c | 215 +++++++++++++++++++++
 2 files changed, 216 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-infra_ao.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index a5166f0860bd..54957094843e 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -67,7 +67,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
 obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o
+obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-infra_ao.c b/drivers/clk/mediatek/clk-mt8186-infra_ao.c
new file mode 100644
index 000000000000..cd2bc99bc9bf
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-infra_ao.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs infra_ao0_cg_regs = {
+	.set_ofs = 0x80,
+	.clr_ofs = 0x84,
+	.sta_ofs = 0x90,
+};
+
+static const struct mtk_gate_regs infra_ao1_cg_regs = {
+	.set_ofs = 0x88,
+	.clr_ofs = 0x8c,
+	.sta_ofs = 0x94,
+};
+
+static const struct mtk_gate_regs infra_ao2_cg_regs = {
+	.set_ofs = 0xa4,
+	.clr_ofs = 0xa8,
+	.sta_ofs = 0xac,
+};
+
+static const struct mtk_gate_regs infra_ao3_cg_regs = {
+	.set_ofs = 0xc0,
+	.clr_ofs = 0xc4,
+	.sta_ofs = 0xc8,
+};
+
+#define GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, _flag)	\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao0_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO0(_id, _name, _parent, _shift)			\
+	GATE_INFRA_AO0_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, _flag)	\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao1_cg_regs, _shift,	\
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO1(_id, _name, _parent, _shift)			\
+	GATE_INFRA_AO1_FLAGS(_id, _name, _parent, _shift, 0)
+
+#define GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, _flag)	\
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao2_cg_regs, _shift, \
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO2(_id, _name, _parent, _shift)			\
+	GATE_INFRA_AO2_FLAGS(_id, _name, _parent, _shift, 0)
+
+ #define GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, _flag)        \
+	GATE_MTK_FLAGS(_id, _name, _parent, &infra_ao3_cg_regs, _shift, \
+		&mtk_clk_gate_ops_setclr, _flag)
+
+#define GATE_INFRA_AO3(_id, _name, _parent, _shift)			\
+	GATE_INFRA_AO3_FLAGS(_id, _name, _parent, _shift, 0)
+
+static const struct mtk_gate infra_ao_clks[] = {
+	/* INFRA_AO0 */
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_TMR, "infra_ao_pmic_tmr", "top_pwrap_ulposc", 0),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_AP, "infra_ao_pmic_ap", "top_pwrap_ulposc", 1),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_MD, "infra_ao_pmic_md", "top_pwrap_ulposc", 2),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PMIC_CONN, "infra_ao_pmic_conn", "top_pwrap_ulposc", 3),
+	/* infra_ao_scp_core are main clock in always-on co-processor. */
+	GATE_INFRA_AO0_FLAGS(CLK_INFRA_AO_SCP_CORE,
+			     "infra_ao_scp_core", "top_scp", 4, CLK_IS_CRITICAL),
+	/* infra_ao_sej is main clock is for secure engine with JTAG support */
+	GATE_INFRA_AO0_FLAGS(CLK_INFRA_AO_SEJ,
+			     "infra_ao_sej", "top_axi", 5, CLK_IS_CRITICAL),
+	GATE_INFRA_AO0(CLK_INFRA_AO_APXGPT, "infra_ao_apxgpt", "top_axi", 6),
+	GATE_INFRA_AO0(CLK_INFRA_AO_ICUSB, "infra_ao_icusb", "top_axi", 8),
+	GATE_INFRA_AO0(CLK_INFRA_AO_GCE, "infra_ao_gce", "top_axi", 9),
+	GATE_INFRA_AO0(CLK_INFRA_AO_THERM, "infra_ao_therm", "top_axi", 10),
+	GATE_INFRA_AO0(CLK_INFRA_AO_I2C_AP, "infra_ao_i2c_ap", "top_i2c", 11),
+	GATE_INFRA_AO0(CLK_INFRA_AO_I2C_CCU, "infra_ao_i2c_ccu", "top_i2c", 12),
+	GATE_INFRA_AO0(CLK_INFRA_AO_I2C_SSPM, "infra_ao_i2c_sspm", "top_i2c", 13),
+	GATE_INFRA_AO0(CLK_INFRA_AO_I2C_RSV, "infra_ao_i2c_rsv", "top_i2c", 14),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM_HCLK, "infra_ao_pwm_hclk", "top_axi", 15),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM1, "infra_ao_pwm1", "top_pwm", 16),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM2, "infra_ao_pwm2", "top_pwm", 17),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM3, "infra_ao_pwm3", "top_pwm", 18),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM4, "infra_ao_pwm4", "top_pwm", 19),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM5, "infra_ao_pwm5", "top_pwm", 20),
+	GATE_INFRA_AO0(CLK_INFRA_AO_PWM, "infra_ao_pwm", "top_pwm", 21),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART0, "infra_ao_uart0", "top_uart", 22),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART1, "infra_ao_uart1", "top_uart", 23),
+	GATE_INFRA_AO0(CLK_INFRA_AO_UART2, "infra_ao_uart2", "top_uart", 24),
+	GATE_INFRA_AO0(CLK_INFRA_AO_GCE_26M, "infra_ao_gce_26m", "clk26m", 27),
+	GATE_INFRA_AO0(CLK_INFRA_AO_CQ_DMA_FPC, "infra_ao_dma", "top_axi", 28),
+	GATE_INFRA_AO0(CLK_INFRA_AO_BTIF, "infra_ao_btif", "top_axi", 31),
+	/* INFRA_AO1 */
+	GATE_INFRA_AO1(CLK_INFRA_AO_SPI0, "infra_ao_spi0", "top_spi", 1),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC0, "infra_ao_msdc0", "top_msdc5hclk", 2),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDCFDE, "infra_ao_msdcfde", "top_aes_msdcfde", 3),
+	GATE_INFRA_AO1(CLK_INFRA_AO_MSDC1, "infra_ao_msdc1", "top_axi", 4),
+	/* infra_ao_dvfsrc is for internal DVFS usage, should not be handled by Linux */
+	GATE_INFRA_AO1_FLAGS(CLK_INFRA_AO_DVFSRC,
+			     "infra_ao_dvfsrc", "top_dvfsrc", 7, CLK_IS_CRITICAL),
+	GATE_INFRA_AO1(CLK_INFRA_AO_GCPU, "infra_ao_gcpu", "top_axi", 8),
+	GATE_INFRA_AO1(CLK_INFRA_AO_TRNG, "infra_ao_trng", "top_axi", 9),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AUXADC, "infra_ao_auxadc", "clk26m", 10),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CPUM, "infra_ao_cpum", "top_axi", 11),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CCIF1_AP, "infra_ao_ccif1_ap", "top_axi", 12),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CCIF1_MD, "infra_ao_ccif1_md", "top_axi", 13),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AUXADC_MD, "infra_ao_auxadc_md", "clk26m", 14),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AP_DMA, "infra_ao_ap_dma", "top_axi", 18),
+	GATE_INFRA_AO1(CLK_INFRA_AO_XIU, "infra_ao_xiu", "top_axi", 19),
+	/* infra_ao_device_apc is for device access permission control module */
+	GATE_INFRA_AO1_FLAGS(CLK_INFRA_AO_DEVICE_APC,
+			     "infra_ao_dapc", "top_axi", 20, CLK_IS_CRITICAL),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CCIF_AP, "infra_ao_ccif_ap", "top_axi", 23),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DEBUGTOP, "infra_ao_debugtop", "top_axi", 24),
+	GATE_INFRA_AO1(CLK_INFRA_AO_AUDIO, "infra_ao_audio", "top_axi", 25),
+	GATE_INFRA_AO1(CLK_INFRA_AO_CCIF_MD, "infra_ao_ccif_md", "top_axi", 26),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DXCC_SEC_CORE, "infra_ao_secore", "top_dxcc", 27),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DXCC_AO, "infra_ao_dxcc_ao", "top_dxcc", 28),
+	GATE_INFRA_AO1(CLK_INFRA_AO_IMP_IIC, "infra_ao_imp_iic", "top_axi", 29),
+	GATE_INFRA_AO1(CLK_INFRA_AO_DRAMC_F26M, "infra_ao_dramc26", "clk26m", 31),
+	/* INFRA_AO2 */
+	GATE_INFRA_AO2(CLK_INFRA_AO_RG_PWM_FBCLK6, "infra_ao_pwm_fbclk6", "clk26m", 0),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_HCLK, "infra_ao_ssusb_hclk", "top_axi", 1),
+	GATE_INFRA_AO2(CLK_INFRA_AO_DISP_PWM, "infra_ao_disp_pwm", "top_disp_pwm", 2),
+	GATE_INFRA_AO2(CLK_INFRA_AO_CLDMA_BCLK, "infra_ao_cldmabclk", "top_axi", 3),
+	GATE_INFRA_AO2(CLK_INFRA_AO_AUDIO_26M_BCLK, "infra_ao_audio26m", "clk26m", 4),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_P1_HCLK, "infra_ao_ssusb_p1_hclk", "top_axi", 5),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI1, "infra_ao_spi1", "top_spi", 6),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C4, "infra_ao_i2c4", "top_i2c", 7),
+	GATE_INFRA_AO2(CLK_INFRA_AO_MODEM_TEMP_SHARE, "infra_ao_mdtemp", "clk26m", 8),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI2, "infra_ao_spi2", "top_spi", 9),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI3, "infra_ao_spi3", "top_spi", 10),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_REF, "infra_ao_ssusb_ref", "clk26m", 11),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_XHCI, "infra_ao_ssusb_xhci", "top_ssusb_xhci", 12),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_P1_REF, "infra_ao_ssusb_p1_ref", "clk26m", 13),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_P1_XHCI,
+		       "infra_ao_ssusb_p1_xhci", "top_ssusb_xhci_1p", 14),
+	/* infra_ao_sspm is main clock in co-processor, should not be closed in Linux. */
+	GATE_INFRA_AO2_FLAGS(CLK_INFRA_AO_SSPM, "infra_ao_sspm", "top_sspm", 15, CLK_IS_CRITICAL),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SSUSB_TOP_P1_SYS,
+		       "infra_ao_ssusb_p1_sys", "top_ssusb_1p", 16),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C5, "infra_ao_i2c5", "top_i2c", 18),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C5_ARBITER, "infra_ao_i2c5a", "top_i2c", 19),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C5_IMM, "infra_ao_i2c5_imm", "top_i2c", 20),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C1_ARBITER, "infra_ao_i2c1a", "top_i2c", 21),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C1_IMM, "infra_ao_i2c1_imm", "top_i2c", 22),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C2_ARBITER, "infra_ao_i2c2a", "top_i2c", 23),
+	GATE_INFRA_AO2(CLK_INFRA_AO_I2C2_IMM, "infra_ao_i2c2_imm", "top_i2c", 24),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI4, "infra_ao_spi4", "top_spi", 25),
+	GATE_INFRA_AO2(CLK_INFRA_AO_SPI5, "infra_ao_spi5", "top_spi", 26),
+	GATE_INFRA_AO2(CLK_INFRA_AO_CQ_DMA, "infra_ao_cq_dma", "top_axi", 27),
+	GATE_INFRA_AO2(CLK_INFRA_AO_BIST2FPC, "infra_ao_bist2fpc", "f_bist2fpc_ck", 28),
+	/* INFRA_AO3 */
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC0_SELF, "infra_ao_msdc0sf", "top_msdc50_0", 0),
+	GATE_INFRA_AO3(CLK_INFRA_AO_SPINOR, "infra_ao_spinor", "top_spinor", 1),
+	/*
+	 * infra_ao_sspm_26m/infra_ao_sspm_32k are main clocks in co-processor,
+	 * should not be closed in Linux.
+	 */
+	GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_SSPM_26M_SELF, "infra_ao_sspm_26m", "clk26m", 3,
+			     CLK_IS_CRITICAL),
+	GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_SSPM_32K_SELF, "infra_ao_sspm_32k", "clk32k", 4,
+			     CLK_IS_CRITICAL),
+	GATE_INFRA_AO3(CLK_INFRA_AO_I2C6, "infra_ao_i2c6", "top_i2c", 6),
+	GATE_INFRA_AO3(CLK_INFRA_AO_AP_MSDC0, "infra_ao_ap_msdc0", "top_axi", 7),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MD_MSDC0, "infra_ao_md_msdc0", "top_axi", 8),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC0_SRC, "infra_ao_msdc0_clk", "top_msdc50_0", 9),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MSDC1_SRC, "infra_ao_msdc1_clk", "top_msdc30_1", 10),
+	/* infra_ao_sej_f13m is main clock is for secure engine with JTAG support */
+	GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_SEJ_F13M,
+			     "infra_ao_sej_f13m", "clk26m", 15, CLK_IS_CRITICAL),
+	/* infra_ao_aes_top0_bclk is for secure encryption */
+	GATE_INFRA_AO3_FLAGS(CLK_INFRA_AO_AES_TOP0_BCLK,
+			     "infra_ao_aes_top0_bclk", "top_axi", 16, CLK_IS_CRITICAL),
+	GATE_INFRA_AO3(CLK_INFRA_AO_MCU_PM_BCLK, "infra_ao_mcu_pm_bclk", "top_axi", 17),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF2_AP, "infra_ao_ccif2_ap", "top_axi", 18),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF2_MD, "infra_ao_ccif2_md", "top_axi", 19),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF3_AP, "infra_ao_ccif3_ap", "top_axi", 20),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF3_MD, "infra_ao_ccif3_md", "top_axi", 21),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FADSP_26M, "infra_ao_fadsp_26m", "clk26m", 22),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FADSP_32K, "infra_ao_fadsp_32k", "clk32k", 23),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF4_AP, "infra_ao_ccif4_ap", "top_axi", 24),
+	GATE_INFRA_AO3(CLK_INFRA_AO_CCIF4_MD, "infra_ao_ccif4_md", "top_axi", 25),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FADSP, "infra_ao_fadsp", "top_audiodsp", 27),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FLASHIF_133M, "infra_ao_flashif_133m", "top_axi", 28),
+	GATE_INFRA_AO3(CLK_INFRA_AO_FLASHIF_66M, "infra_ao_flashif_66m", "top_axi", 29),
+};
+
+static const struct mtk_clk_desc infra_ao_desc = {
+	.clks = infra_ao_clks,
+	.num_clks = ARRAY_SIZE(infra_ao_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_infra_ao[] = {
+	{
+		.compatible = "mediatek,mt8186-infracfg_ao",
+		.data = &infra_ao_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_infra_ao_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-infra-ao",
+		.of_match_table = of_match_clk_mt8186_infra_ao,
+	},
+};
+builtin_platform_driver(clk_mt8186_infra_ao_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:06 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:06 +0800
Subject: [v1 06/16] clk: mediatek: Add MT8186 apmixedsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-7-chun-jie.chen@mediatek.com>

Add MT8186 apmixedsys clock controller which provides Plls
generated from SoC.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile                |   3 +-
 drivers/clk/mediatek/clk-mt8186-apmixedsys.c | 114 +++++++++++++++++++
 2 files changed, 116 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-apmixedsys.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 54957094843e..b139acdff591 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -67,7 +67,8 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
 obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
-obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o
+obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
+				   clk-mt8186-apmixedsys.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-apmixedsys.c b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c
new file mode 100644
index 000000000000..50bb04e9953d
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#define MT8186_PLL_FMAX		(3800UL * MHZ)
+#define MT8186_PLL_FMIN		(1500UL * MHZ)
+#define MT8186_INTEGER_BITS	(8)
+
+#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags,		\
+	    _rst_bar_mask, _pcwbits, _pd_reg, _pd_shift,		\
+	    _tuner_reg, _tuner_en_reg, _tuner_en_bit,			\
+	    _pcw_reg) {							\
+		.id = _id,						\
+		.name = _name,						\
+		.reg = _reg,						\
+		.pwr_reg = _pwr_reg,					\
+		.en_mask = _en_mask,					\
+		.flags = _flags,					\
+		.rst_bar_mask = _rst_bar_mask,				\
+		.fmax = MT8186_PLL_FMAX,				\
+		.fmin = MT8186_PLL_FMIN,				\
+		.pcwbits = _pcwbits,					\
+		.pcwibits = MT8186_INTEGER_BITS,			\
+		.pd_reg = _pd_reg,					\
+		.pd_shift = _pd_shift,					\
+		.tuner_reg = _tuner_reg,				\
+		.tuner_en_reg = _tuner_en_reg,				\
+		.tuner_en_bit = _tuner_en_bit,				\
+		.pcw_reg = _pcw_reg,					\
+		.pcw_shift = 0,						\
+		.pcw_chg_reg = 0,					\
+		.en_reg = 0,						\
+		.pll_en_bit = 0,					\
+	}
+
+static const struct mtk_pll_data plls[] = {
+	/*
+	 * armpll_ll/armpll_bl/ccipll are main clock source of AP MCU,
+	 * should not be closed in Linux world.
+	 */
+	PLL(CLK_APMIXED_ARMPLL_LL, "armpll_ll", 0x0204, 0x0210, 0,
+	    PLL_AO, 0, 22, 0x0208, 24, 0, 0, 0, 0x0208),
+	PLL(CLK_APMIXED_ARMPLL_BL, "armpll_bl", 0x0214, 0x0220, 0,
+	    PLL_AO, 0, 22, 0x0218, 24, 0, 0, 0, 0x0218),
+	PLL(CLK_APMIXED_CCIPLL, "ccipll", 0x0224, 0x0230, 0,
+	    PLL_AO, 0, 22, 0x0228, 24, 0, 0, 0, 0x0228),
+	PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0244, 0x0250, 0xff000000,
+	    HAVE_RST_BAR, BIT(23), 22, 0x0248, 24, 0, 0, 0, 0x0248),
+	PLL(CLK_APMIXED_UNIV2PLL, "univ2pll", 0x0324, 0x0330, 0xff000000,
+	    HAVE_RST_BAR, BIT(23), 22, 0x0328, 24, 0, 0, 0, 0x0328),
+	PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x038C, 0x0398, 0,
+	    0, 0, 22, 0x0390, 24, 0, 0, 0, 0x0390),
+	PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0254, 0x0260, 0,
+	    0, 0, 22, 0x0258, 24, 0, 0, 0, 0x0258),
+	PLL(CLK_APMIXED_NNAPLL, "nnapll", 0x035C, 0x0368, 0,
+	    0, 0, 22, 0x0360, 24, 0, 0, 0, 0x0360),
+	PLL(CLK_APMIXED_NNA2PLL, "nna2pll", 0x036C, 0x0378, 0,
+	    0, 0, 22, 0x0370, 24, 0, 0, 0, 0x0370),
+	PLL(CLK_APMIXED_ADSPPLL, "adsppll", 0x0304, 0x0310, 0,
+	    0, 0, 22, 0x0308, 24, 0, 0, 0, 0x0308),
+	PLL(CLK_APMIXED_MFGPLL, "mfgpll", 0x0314, 0x0320, 0,
+	    0, 0, 22, 0x0318, 24, 0, 0, 0, 0x0318),
+	PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0264, 0x0270, 0,
+	    0, 0, 22, 0x0268, 24, 0, 0, 0, 0x0268),
+	PLL(CLK_APMIXED_APLL1, "apll1", 0x0334, 0x0344, 0,
+	    0, 0, 32, 0x0338, 24, 0x0040, 0x000C, 0, 0x033C),
+	PLL(CLK_APMIXED_APLL2, "apll2", 0x0348, 0x0358, 0,
+	    0, 0, 32, 0x034C, 24, 0x0044, 0x000C, 5, 0x0350),
+};
+
+static const struct of_device_id of_match_clk_mt8186_apmixed[] = {
+	{ .compatible = "mediatek,mt8186-apmixedsys", },
+	{}
+};
+
+static int clk_mt8186_apmixed_probe(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data;
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+static struct platform_driver clk_mt8186_apmixed_drv = {
+	.probe = clk_mt8186_apmixed_probe,
+	.driver = {
+		.name = "clk-mt8186-apmixed",
+		.of_match_table = of_match_clk_mt8186_apmixed,
+	},
+};
+builtin_platform_driver(clk_mt8186_apmixed_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:09 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:09 +0800
Subject: [v1 09/16] clk: mediatek: Add MT8186 mmsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-10-chun-jie.chen@mediatek.com>

Add MT8186 mmsys clock controller which provides clock gate
control in video system. This is integrated with mtk-mmsys
driver which will populate device by platform_device_register_data
to start mmsys clock driver.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile        |  2 +-
 drivers/clk/mediatek/clk-mt8186-mm.c | 97 ++++++++++++++++++++++++++++
 2 files changed, 98 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mm.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 9477b5694c32..b34d89e757cb 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -69,7 +69,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
-				   clk-mt8186-mfg.o
+				   clk-mt8186-mfg.o clk-mt8186-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-mm.c b/drivers/clk/mediatek/clk-mt8186-mm.c
new file mode 100644
index 000000000000..1c1a9ae1d0c2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-mm.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs mm0_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mm1_cg_regs = {
+	.set_ofs = 0x1a4,
+	.clr_ofs = 0x1a8,
+	.sta_ofs = 0x1a0,
+};
+
+#define GATE_MM0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mm0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MM1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mm1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mm_clks[] = {
+	/* MM0 */
+	GATE_MM0(CLK_MM_DISP_MUTEX0, "mm_disp_mutex0", "top_disp", 0),
+	GATE_MM0(CLK_MM_APB_MM_BUS, "mm_apb_mm_bus", "top_disp", 1),
+	GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "top_disp", 2),
+	GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "top_disp", 3),
+	GATE_MM0(CLK_MM_DISP_OVL0_2L, "mm_disp_ovl0_2l", "top_disp", 4),
+	GATE_MM0(CLK_MM_DISP_WDMA0, "mm_disp_wdma0", "top_disp", 5),
+	GATE_MM0(CLK_MM_DISP_RSZ0, "mm_disp_rsz0", "top_disp", 7),
+	GATE_MM0(CLK_MM_DISP_AAL0, "mm_disp_aal0", "top_disp", 8),
+	GATE_MM0(CLK_MM_DISP_CCORR0, "mm_disp_ccorr0", "top_disp", 9),
+	GATE_MM0(CLK_MM_DISP_COLOR0, "mm_disp_color0", "top_disp", 10),
+	GATE_MM0(CLK_MM_SMI_INFRA, "mm_smi_infra", "top_disp", 11),
+	GATE_MM0(CLK_MM_DISP_DSC_WRAP0, "mm_disp_dsc_wrap0", "top_disp", 12),
+	GATE_MM0(CLK_MM_DISP_GAMMA0, "mm_disp_gamma0", "top_disp", 13),
+	GATE_MM0(CLK_MM_DISP_POSTMASK0, "mm_disp_postmask0", "top_disp", 14),
+	GATE_MM0(CLK_MM_DISP_DITHER0, "mm_disp_dither0", "top_disp", 16),
+	GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "top_disp", 17),
+	GATE_MM0(CLK_MM_DSI0, "mm_dsi0", "top_disp", 19),
+	GATE_MM0(CLK_MM_DISP_FAKE_ENG0, "mm_disp_fake_eng0", "top_disp", 20),
+	GATE_MM0(CLK_MM_DISP_FAKE_ENG1, "mm_disp_fake_eng1", "top_disp", 21),
+	GATE_MM0(CLK_MM_SMI_GALS, "mm_smi_gals", "top_disp", 22),
+	GATE_MM0(CLK_MM_SMI_IOMMU, "mm_smi_iommu", "top_disp", 24),
+	GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "top_disp", 25),
+	GATE_MM0(CLK_MM_DISP_DPI, "mm_disp_dpi", "top_disp", 26),
+	/* MM1 */
+	GATE_MM1(CLK_MM_DSI0_DSI_CK_DOMAIN, "mm_dsi0_dsi_domain", "top_disp", 0),
+	GATE_MM1(CLK_MM_DISP_26M, "mm_disp_26m_ck", "top_disp", 10),
+};
+
+static int clk_mt8186_mm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data;
+	int r;
+
+	clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
+	if (!clk_data)
+		return -ENOMEM;
+
+	r = mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks), clk_data);
+	if (r)
+		goto free_mm_data;
+
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_clk;
+
+	return r;
+
+unregister_clk:
+	mtk_clk_unregister(clk_data);
+
+free_mm_data:
+	mtk_free_clk_data(clk_data);
+	return r;
+}
+
+
+static struct platform_driver clk_mt8186_mm_drv = {
+	.probe = clk_mt8186_mm_probe,
+	.driver = {
+		.name = "clk-mt8186-mm",
+	},
+};
+builtin_platform_driver(clk_mt8186_mm_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:07 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:07 +0800
Subject: [v1 07/16] clk: mediatek: Add MT8186 imp i2c wrapper clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-8-chun-jie.chen@mediatek.com>

Add MT8186 imp i2c wrapper clock controllers which provide clock gate
control in i2c IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile                 |  2 +-
 .../clk/mediatek/clk-mt8186-imp_iic_wrap.c    | 66 +++++++++++++++++++
 2 files changed, 67 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-imp_iic_wrap.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index b139acdff591..8f8240e4d8d0 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -68,7 +68,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
-				   clk-mt8186-apmixedsys.o
+				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8186-imp_iic_wrap.c
new file mode 100644
index 000000000000..18aee488df69
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-imp_iic_wrap.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs imp_iic_wrap_cg_regs = {
+	.set_ofs = 0xe08,
+	.clr_ofs = 0xe04,
+	.sta_ofs = 0xe00,
+};
+
+#define GATE_IMP_IIC_WRAP(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &imp_iic_wrap_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate imp_iic_wrap_clks[] = {
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C0,
+		"imp_iic_wrap_ap_clock_i2c0", "infra_ao_i2c_ap", 0),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C1,
+		"imp_iic_wrap_ap_clock_i2c1", "infra_ao_i2c_ap", 1),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C2,
+		"imp_iic_wrap_ap_clock_i2c2", "infra_ao_i2c_ap", 2),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C3,
+		"imp_iic_wrap_ap_clock_i2c3", "infra_ao_i2c_ap", 3),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C4,
+		"imp_iic_wrap_ap_clock_i2c4", "infra_ao_i2c_ap", 4),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C5,
+		"imp_iic_wrap_ap_clock_i2c5", "infra_ao_i2c_ap", 5),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C6,
+		"imp_iic_wrap_ap_clock_i2c6", "infra_ao_i2c_ap", 6),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C7,
+		"imp_iic_wrap_ap_clock_i2c7", "infra_ao_i2c_ap", 7),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C8,
+		"imp_iic_wrap_ap_clock_i2c8", "infra_ao_i2c_ap", 8),
+	GATE_IMP_IIC_WRAP(CLK_IMP_IIC_WRAP_AP_CLOCK_I2C9,
+		"imp_iic_wrap_ap_clock_i2c9", "infra_ao_i2c_ap", 9),
+};
+
+static const struct mtk_clk_desc imp_iic_wrap_desc = {
+	.clks = imp_iic_wrap_clks,
+	.num_clks = ARRAY_SIZE(imp_iic_wrap_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_imp_iic_wrap[] = {
+	{
+		.compatible = "mediatek,mt8186-imp_iic_wrap",
+		.data = &imp_iic_wrap_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_imp_iic_wrap_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-imp_iic_wrap",
+		.of_match_table = of_match_clk_mt8186_imp_iic_wrap,
+	},
+};
+builtin_platform_driver(clk_mt8186_imp_iic_wrap_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:14 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:14 +0800
Subject: [v1 14/16] clk: mediatek: Add MT8186 camsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-15-chun-jie.chen@mediatek.com>

Add MT8186 camsys clock controllers which provide clock gate
control for camera IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  3 +-
 drivers/clk/mediatek/clk-mt8186-cam.c | 89 +++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-cam.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index c5d5a10734d0..9190e17602eb 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -70,7 +70,8 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
 				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
-				   clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o
+				   clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o \
+				   clk-mt8186-cam.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-cam.c b/drivers/clk/mediatek/clk-mt8186-cam.c
new file mode 100644
index 000000000000..5552fe5d428f
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-cam.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs cam_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_CAM(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &cam_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate cam_clks[] = {
+	GATE_CAM(CLK_CAM_LARB13, "cam_larb13", "top_cam", 0),
+	GATE_CAM(CLK_CAM_DFP_VAD, "cam_dfp_vad", "top_cam", 1),
+	GATE_CAM(CLK_CAM_LARB14, "cam_larb14", "top_cam", 2),
+	GATE_CAM(CLK_CAM, "cam", "top_cam", 6),
+	GATE_CAM(CLK_CAMTG, "camtg", "top_cam", 7),
+	GATE_CAM(CLK_CAM_SENINF, "cam_seninf", "top_cam", 8),
+	GATE_CAM(CLK_CAMSV1, "camsv1", "top_cam", 10),
+	GATE_CAM(CLK_CAMSV2, "camsv2", "top_cam", 11),
+	GATE_CAM(CLK_CAMSV3, "camsv3", "top_cam", 12),
+	GATE_CAM(CLK_CAM_CCU0, "cam_ccu0", "top_cam", 13),
+	GATE_CAM(CLK_CAM_CCU1, "cam_ccu1", "top_cam", 14),
+	GATE_CAM(CLK_CAM_MRAW0, "cam_mraw0", "top_cam", 15),
+	GATE_CAM(CLK_CAM_FAKE_ENG, "cam_fake_eng", "top_cam", 17),
+	GATE_CAM(CLK_CAM_CCU_GALS, "cam_ccu_gals", "top_cam", 18),
+	GATE_CAM(CLK_CAM2MM_GALS, "cam2mm_gals", "top_cam", 19),
+};
+
+static const struct mtk_gate cam_rawa_clks[] = {
+	GATE_CAM(CLK_CAM_RAWA_LARBX_RAWA, "cam_rawa_larbx_rawa", "top_cam", 0),
+	GATE_CAM(CLK_CAM_RAWA, "cam_rawa", "top_cam", 1),
+	GATE_CAM(CLK_CAM_RAWA_CAMTG_RAWA, "cam_rawa_camtg_rawa", "top_cam", 2),
+};
+
+static const struct mtk_gate cam_rawb_clks[] = {
+	GATE_CAM(CLK_CAM_RAWB_LARBX_RAWB, "cam_rawb_larbx_rawb", "top_cam", 0),
+	GATE_CAM(CLK_CAM_RAWB, "cam_rawb", "top_cam", 1),
+	GATE_CAM(CLK_CAM_RAWB_CAMTG_RAWB, "cam_rawb_camtg_rawb", "top_cam", 2),
+};
+
+static const struct mtk_clk_desc cam_desc = {
+	.clks = cam_clks,
+	.num_clks = ARRAY_SIZE(cam_clks),
+};
+
+static const struct mtk_clk_desc cam_rawa_desc = {
+	.clks = cam_rawa_clks,
+	.num_clks = ARRAY_SIZE(cam_rawa_clks),
+};
+
+static const struct mtk_clk_desc cam_rawb_desc = {
+	.clks = cam_rawb_clks,
+	.num_clks = ARRAY_SIZE(cam_rawb_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_cam[] = {
+	{
+		.compatible = "mediatek,mt8186-camsys",
+		.data = &cam_desc,
+	}, {
+		.compatible = "mediatek,mt8186-camsys_rawa",
+		.data = &cam_rawa_desc,
+	}, {
+		.compatible = "mediatek,mt8186-camsys_rawb",
+		.data = &cam_rawb_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_cam_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-cam",
+		.of_match_table = of_match_clk_mt8186_cam,
+	},
+};
+builtin_platform_driver(clk_mt8186_cam_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:13 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:13 +0800
Subject: [v1 13/16] clk: mediatek: Add MT8186 vencsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-14-chun-jie.chen@mediatek.com>

Add MT8186 vencsys clock controller which provide clock gate
control for video encoder.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |  2 +-
 drivers/clk/mediatek/clk-mt8186-venc.c | 50 ++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-venc.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index e29e6a661115..c5d5a10734d0 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -70,7 +70,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
 				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
-				   clk-mt8186-img.o clk-mt8186-vdec.o
+				   clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-venc.c b/drivers/clk/mediatek/clk-mt8186-venc.c
new file mode 100644
index 000000000000..4cd69f9ebf76
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-venc.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs venc_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_VENC(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &venc_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate venc_clks[] = {
+	GATE_VENC(CLK_VENC_CKE0_LARB, "venc_cke0_larb", "top_venc", 0),
+	GATE_VENC(CLK_VENC_CKE1_VENC, "venc_cke1_venc", "top_venc", 4),
+	GATE_VENC(CLK_VENC_CKE2_JPGENC, "venc_cke2_jpgenc", "top_venc", 8),
+	GATE_VENC(CLK_VENC_CKE5_GALS, "venc_cke5_gals", "top_venc", 28),
+};
+
+static const struct mtk_clk_desc venc_desc = {
+	.clks = venc_clks,
+	.num_clks = ARRAY_SIZE(venc_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_venc[] = {
+	{
+		.compatible = "mediatek,mt8186-vencsys",
+		.data = &venc_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_venc_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-venc",
+		.of_match_table = of_match_clk_mt8186_venc,
+	},
+};
+builtin_platform_driver(clk_mt8186_venc_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:08 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:08 +0800
Subject: [v1 08/16] clk: mediatek: Add MT8186 mfgsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-9-chun-jie.chen@mediatek.com>

Add MT8186 mfg clock controller which provides clock gate
control for GPU.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  3 +-
 drivers/clk/mediatek/clk-mt8186-mfg.c | 47 +++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mfg.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 8f8240e4d8d0..9477b5694c32 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -68,7 +68,8 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
-				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o
+				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
+				   clk-mt8186-mfg.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-mfg.c b/drivers/clk/mediatek/clk-mt8186-mfg.c
new file mode 100644
index 000000000000..63417a040a7e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-mfg.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs mfg_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_MFG(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mfg_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mfg_clks[] = {
+	GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "top_mfg", 0),
+};
+
+static const struct mtk_clk_desc mfg_desc = {
+	.clks = mfg_clks,
+	.num_clks = ARRAY_SIZE(mfg_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_mfg[] = {
+	{
+		.compatible = "mediatek,mt8186-mfgsys",
+		.data = &mfg_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_mfg_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-mfg",
+		.of_match_table = of_match_clk_mt8186_mfg,
+	},
+};
+builtin_platform_driver(clk_mt8186_mfg_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:02 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:02 +0800
Subject: [v1 02/16] clk: mediatek: Add dt-bindings of MT8186 clocks
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-3-chun-jie.chen@mediatek.com>

Add MT8186 clock dt-bindings, includes topckgen, apmixedsys,
infracfg_ao, mcusys and subsystem clocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 include/dt-bindings/clock/mt8186-clk.h | 445 +++++++++++++++++++++++++
 1 file changed, 445 insertions(+)
 create mode 100644 include/dt-bindings/clock/mt8186-clk.h

diff --git a/include/dt-bindings/clock/mt8186-clk.h b/include/dt-bindings/clock/mt8186-clk.h
new file mode 100644
index 000000000000..6a291750cea4
--- /dev/null
+++ b/include/dt-bindings/clock/mt8186-clk.h
@@ -0,0 +1,445 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8186_H
+#define _DT_BINDINGS_CLK_MT8186_H
+
+/* MCUSYS */
+
+#define CLK_MCU_ARMPLL_LL_SEL		0
+#define CLK_MCU_ARMPLL_BL_SEL		1
+#define CLK_MCU_ARMPLL_BUS_SEL		2
+#define CLK_MCU_NR_CLK			3
+
+/* TOPCKGEN */
+
+#define CLK_TOP_AXI			0
+#define CLK_TOP_SCP			1
+#define CLK_TOP_MFG			2
+#define CLK_TOP_CAMTG			3
+#define CLK_TOP_CAMTG1			4
+#define CLK_TOP_CAMTG2			5
+#define CLK_TOP_CAMTG3			6
+#define CLK_TOP_CAMTG4			7
+#define CLK_TOP_CAMTG5			8
+#define CLK_TOP_CAMTG6			9
+#define CLK_TOP_UART			10
+#define CLK_TOP_SPI			11
+#define CLK_TOP_MSDC50_0_HCLK		12
+#define CLK_TOP_MSDC50_0		13
+#define CLK_TOP_MSDC30_1		14
+#define CLK_TOP_AUDIO			15
+#define CLK_TOP_AUD_INTBUS		16
+#define CLK_TOP_AUD_1			17
+#define CLK_TOP_AUD_2			18
+#define CLK_TOP_AUD_ENGEN1		19
+#define CLK_TOP_AUD_ENGEN2		20
+#define CLK_TOP_DISP_PWM		21
+#define CLK_TOP_SSPM			22
+#define CLK_TOP_DXCC			23
+#define CLK_TOP_USB_TOP			24
+#define CLK_TOP_SRCK			25
+#define CLK_TOP_SPM			26
+#define CLK_TOP_I2C			27
+#define CLK_TOP_PWM			28
+#define CLK_TOP_SENINF			29
+#define CLK_TOP_SENINF1			30
+#define CLK_TOP_SENINF2			31
+#define CLK_TOP_SENINF3			32
+#define CLK_TOP_AES_MSDCFDE		33
+#define CLK_TOP_PWRAP_ULPOSC		34
+#define CLK_TOP_CAMTM			35
+#define CLK_TOP_VENC			36
+#define CLK_TOP_CAM			37
+#define CLK_TOP_IMG1			38
+#define CLK_TOP_IPE			39
+#define CLK_TOP_DPMAIF			40
+#define CLK_TOP_VDEC			41
+#define CLK_TOP_DISP			42
+#define CLK_TOP_MDP			43
+#define CLK_TOP_AUDIO_H			44
+#define CLK_TOP_UFS			45
+#define CLK_TOP_AES_FDE			46
+#define CLK_TOP_AUDIODSP		47
+#define CLK_TOP_DVFSRC			48
+#define CLK_TOP_DSI_OCC			49
+#define CLK_TOP_SPMI_MST		50
+#define CLK_TOP_SPINOR			51
+#define CLK_TOP_NNA			52
+#define CLK_TOP_NNA1			53
+#define CLK_TOP_NNA2			54
+#define CLK_TOP_SSUSB_XHCI		55
+#define CLK_TOP_SSUSB_TOP_1P		56
+#define CLK_TOP_SSUSB_XHCI_1P		57
+#define CLK_TOP_WPE			58
+#define CLK_TOP_DPI			59
+#define CLK_TOP_U3_OCC_250M		60
+#define CLK_TOP_U3_OCC_500M		61
+#define CLK_TOP_ADSP_BUS		62
+#define CLK_TOP_APLL_I2S0_MCK_SEL	63
+#define CLK_TOP_APLL_I2S1_MCK_SEL	64
+#define CLK_TOP_APLL_I2S2_MCK_SEL	65
+#define CLK_TOP_APLL_I2S4_MCK_SEL	66
+#define CLK_TOP_APLL_TDMOUT_MCK_SEL	67
+#define CLK_TOP_MAINPLL_D2		68
+#define CLK_TOP_MAINPLL_D2_D2		69
+#define CLK_TOP_MAINPLL_D2_D4		70
+#define CLK_TOP_MAINPLL_D2_D16		71
+#define CLK_TOP_MAINPLL_D3		72
+#define CLK_TOP_MAINPLL_D3_D2		73
+#define CLK_TOP_MAINPLL_D3_D4		74
+#define CLK_TOP_MAINPLL_D5		75
+#define CLK_TOP_MAINPLL_D5_D2		76
+#define CLK_TOP_MAINPLL_D5_D4		77
+#define CLK_TOP_MAINPLL_D7		78
+#define CLK_TOP_MAINPLL_D7_D2		79
+#define CLK_TOP_MAINPLL_D7_D4		80
+#define CLK_TOP_UNIVPLL			81
+#define CLK_TOP_UNIVPLL_D2		82
+#define CLK_TOP_UNIVPLL_D2_D2		83
+#define CLK_TOP_UNIVPLL_D2_D4		84
+#define CLK_TOP_UNIVPLL_D3		85
+#define CLK_TOP_UNIVPLL_D3_D2		86
+#define CLK_TOP_UNIVPLL_D3_D4		87
+#define CLK_TOP_UNIVPLL_D3_D8		88
+#define CLK_TOP_UNIVPLL_D3_D32		89
+#define CLK_TOP_UNIVPLL_D5		90
+#define CLK_TOP_UNIVPLL_D5_D2		91
+#define CLK_TOP_UNIVPLL_D5_D4		92
+#define CLK_TOP_UNIVPLL_D7		93
+#define CLK_TOP_UNIVPLL_192M		94
+#define CLK_TOP_UNIVPLL_192M_D4		95
+#define CLK_TOP_UNIVPLL_192M_D8		96
+#define CLK_TOP_UNIVPLL_192M_D16	97
+#define CLK_TOP_UNIVPLL_192M_D32	98
+#define CLK_TOP_APLL1_D2		99
+#define CLK_TOP_APLL1_D4		100
+#define CLK_TOP_APLL1_D8		101
+#define CLK_TOP_APLL2_D2		102
+#define CLK_TOP_APLL2_D4		103
+#define CLK_TOP_APLL2_D8		104
+#define CLK_TOP_MMPLL_D2		105
+#define CLK_TOP_TVDPLL_D2		106
+#define CLK_TOP_TVDPLL_D4		107
+#define CLK_TOP_TVDPLL_D8		108
+#define CLK_TOP_TVDPLL_D16		109
+#define CLK_TOP_TVDPLL_D32		110
+#define CLK_TOP_MSDCPLL_D2		111
+#define CLK_TOP_ULPOSC1			112
+#define CLK_TOP_ULPOSC1_D2		113
+#define CLK_TOP_ULPOSC1_D4		114
+#define CLK_TOP_ULPOSC1_D8		115
+#define CLK_TOP_ULPOSC1_D10		116
+#define CLK_TOP_ULPOSC1_D16		117
+#define CLK_TOP_ULPOSC1_D32		118
+#define CLK_TOP_ADSPPLL_D2		119
+#define CLK_TOP_ADSPPLL_D4		120
+#define CLK_TOP_ADSPPLL_D8		121
+#define CLK_TOP_NNAPLL_D2		122
+#define CLK_TOP_NNAPLL_D4		123
+#define CLK_TOP_NNAPLL_D8		124
+#define CLK_TOP_NNA2PLL_D2		125
+#define CLK_TOP_NNA2PLL_D4		126
+#define CLK_TOP_NNA2PLL_D8		127
+#define CLK_TOP_F_BIST2FPC		128
+#define CLK_TOP_466M_FMEM		129
+#define CLK_TOP_MPLL			130
+#define CLK_TOP_APLL12_CK_DIV0		131
+#define CLK_TOP_APLL12_CK_DIV1		132
+#define CLK_TOP_APLL12_CK_DIV2		133
+#define CLK_TOP_APLL12_CK_DIV4		134
+#define CLK_TOP_APLL12_CK_DIV_TDMOUT_M	135
+#define CLK_TOP_NR_CLK			136
+
+/* INFRACFG_AO */
+
+#define CLK_INFRA_AO_PMIC_TMR		0
+#define CLK_INFRA_AO_PMIC_AP		1
+#define CLK_INFRA_AO_PMIC_MD		2
+#define CLK_INFRA_AO_PMIC_CONN		3
+#define CLK_INFRA_AO_SCP_CORE		4
+#define CLK_INFRA_AO_SEJ		5
+#define CLK_INFRA_AO_APXGPT		6
+#define CLK_INFRA_AO_ICUSB		7
+#define CLK_INFRA_AO_GCE		8
+#define CLK_INFRA_AO_THERM		9
+#define CLK_INFRA_AO_I2C_AP		10
+#define CLK_INFRA_AO_I2C_CCU		11
+#define CLK_INFRA_AO_I2C_SSPM		12
+#define CLK_INFRA_AO_I2C_RSV		13
+#define CLK_INFRA_AO_PWM_HCLK		14
+#define CLK_INFRA_AO_PWM1		15
+#define CLK_INFRA_AO_PWM2		16
+#define CLK_INFRA_AO_PWM3		17
+#define CLK_INFRA_AO_PWM4		18
+#define CLK_INFRA_AO_PWM5		19
+#define CLK_INFRA_AO_PWM		20
+#define CLK_INFRA_AO_UART0		21
+#define CLK_INFRA_AO_UART1		22
+#define CLK_INFRA_AO_UART2		23
+#define CLK_INFRA_AO_GCE_26M		24
+#define CLK_INFRA_AO_CQ_DMA_FPC		25
+#define CLK_INFRA_AO_BTIF		26
+#define CLK_INFRA_AO_SPI0		27
+#define CLK_INFRA_AO_MSDC0		28
+#define CLK_INFRA_AO_MSDCFDE		29
+#define CLK_INFRA_AO_MSDC1		30
+#define CLK_INFRA_AO_DVFSRC		31
+#define CLK_INFRA_AO_GCPU		32
+#define CLK_INFRA_AO_TRNG		33
+#define CLK_INFRA_AO_AUXADC		34
+#define CLK_INFRA_AO_CPUM		35
+#define CLK_INFRA_AO_CCIF1_AP		36
+#define CLK_INFRA_AO_CCIF1_MD		37
+#define CLK_INFRA_AO_AUXADC_MD		38
+#define CLK_INFRA_AO_AP_DMA		39
+#define CLK_INFRA_AO_XIU		40
+#define CLK_INFRA_AO_DEVICE_APC		41
+#define CLK_INFRA_AO_CCIF_AP		42
+#define CLK_INFRA_AO_DEBUGTOP		43
+#define CLK_INFRA_AO_AUDIO		44
+#define CLK_INFRA_AO_CCIF_MD		45
+#define CLK_INFRA_AO_DXCC_SEC_CORE	46
+#define CLK_INFRA_AO_DXCC_AO		47
+#define CLK_INFRA_AO_IMP_IIC		48
+#define CLK_INFRA_AO_DRAMC_F26M		49
+#define CLK_INFRA_AO_RG_PWM_FBCLK6	50
+#define CLK_INFRA_AO_SSUSB_TOP_HCLK	51
+#define CLK_INFRA_AO_DISP_PWM		52
+#define CLK_INFRA_AO_CLDMA_BCLK		53
+#define CLK_INFRA_AO_AUDIO_26M_BCLK	54
+#define CLK_INFRA_AO_SSUSB_TOP_P1_HCLK	55
+#define CLK_INFRA_AO_SPI1		56
+#define CLK_INFRA_AO_I2C4		57
+#define CLK_INFRA_AO_MODEM_TEMP_SHARE	58
+#define CLK_INFRA_AO_SPI2		59
+#define CLK_INFRA_AO_SPI3		60
+#define CLK_INFRA_AO_SSUSB_TOP_REF	61
+#define CLK_INFRA_AO_SSUSB_TOP_XHCI	62
+#define CLK_INFRA_AO_SSUSB_TOP_P1_REF	63
+#define CLK_INFRA_AO_SSUSB_TOP_P1_XHCI	64
+#define CLK_INFRA_AO_SSPM		65
+#define CLK_INFRA_AO_SSUSB_TOP_P1_SYS	66
+#define CLK_INFRA_AO_I2C5		67
+#define CLK_INFRA_AO_I2C5_ARBITER	68
+#define CLK_INFRA_AO_I2C5_IMM		69
+#define CLK_INFRA_AO_I2C1_ARBITER	70
+#define CLK_INFRA_AO_I2C1_IMM		71
+#define CLK_INFRA_AO_I2C2_ARBITER	72
+#define CLK_INFRA_AO_I2C2_IMM		73
+#define CLK_INFRA_AO_SPI4		74
+#define CLK_INFRA_AO_SPI5		75
+#define CLK_INFRA_AO_CQ_DMA		76
+#define CLK_INFRA_AO_BIST2FPC		77
+#define CLK_INFRA_AO_MSDC0_SELF		78
+#define CLK_INFRA_AO_SPINOR		79
+#define CLK_INFRA_AO_SSPM_26M_SELF	80
+#define CLK_INFRA_AO_SSPM_32K_SELF	81
+#define CLK_INFRA_AO_I2C6		82
+#define CLK_INFRA_AO_AP_MSDC0		83
+#define CLK_INFRA_AO_MD_MSDC0		84
+#define CLK_INFRA_AO_MSDC0_SRC		85
+#define CLK_INFRA_AO_MSDC1_SRC		86
+#define CLK_INFRA_AO_SEJ_F13M		87
+#define CLK_INFRA_AO_AES_TOP0_BCLK	88
+#define CLK_INFRA_AO_MCU_PM_BCLK	89
+#define CLK_INFRA_AO_CCIF2_AP		90
+#define CLK_INFRA_AO_CCIF2_MD		91
+#define CLK_INFRA_AO_CCIF3_AP		92
+#define CLK_INFRA_AO_CCIF3_MD		93
+#define CLK_INFRA_AO_FADSP_26M		94
+#define CLK_INFRA_AO_FADSP_32K		95
+#define CLK_INFRA_AO_CCIF4_AP		96
+#define CLK_INFRA_AO_CCIF4_MD		97
+#define CLK_INFRA_AO_FADSP		98
+#define CLK_INFRA_AO_FLASHIF_133M	99
+#define CLK_INFRA_AO_FLASHIF_66M	100
+#define CLK_INFRA_AO_NR_CLK		101
+
+/* APMIXEDSYS */
+
+#define CLK_APMIXED_ARMPLL_LL		0
+#define CLK_APMIXED_ARMPLL_BL		1
+#define CLK_APMIXED_CCIPLL		2
+#define CLK_APMIXED_MAINPLL		3
+#define CLK_APMIXED_UNIV2PLL		4
+#define CLK_APMIXED_MSDCPLL		5
+#define CLK_APMIXED_MMPLL		6
+#define CLK_APMIXED_NNAPLL		7
+#define CLK_APMIXED_NNA2PLL		8
+#define CLK_APMIXED_ADSPPLL		9
+#define CLK_APMIXED_MFGPLL		10
+#define CLK_APMIXED_TVDPLL		11
+#define CLK_APMIXED_APLL1		12
+#define CLK_APMIXED_APLL2		13
+#define CLK_APMIXED_NR_CLK		14
+
+/* IMP_IIC_WRAP */
+
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C0	0
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C1	1
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C2	2
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C3	3
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C4	4
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C5	5
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C6	6
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C7	7
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C8	8
+#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C9	9
+#define CLK_IMP_IIC_WRAP_NR_CLK		10
+
+/* MFGCFG */
+
+#define CLK_MFG_BG3D			0
+#define CLK_MFG_NR_CLK			1
+
+/* MMSYS */
+
+#define CLK_MM_DISP_MUTEX0		0
+#define CLK_MM_APB_MM_BUS		1
+#define CLK_MM_DISP_OVL0		2
+#define CLK_MM_DISP_RDMA0		3
+#define CLK_MM_DISP_OVL0_2L		4
+#define CLK_MM_DISP_WDMA0		5
+#define CLK_MM_DISP_RSZ0		6
+#define CLK_MM_DISP_AAL0		7
+#define CLK_MM_DISP_CCORR0		8
+#define CLK_MM_DISP_COLOR0		9
+#define CLK_MM_SMI_INFRA		10
+#define CLK_MM_DISP_DSC_WRAP0		11
+#define CLK_MM_DISP_GAMMA0		12
+#define CLK_MM_DISP_POSTMASK0		13
+#define CLK_MM_DISP_DITHER0		14
+#define CLK_MM_SMI_COMMON		15
+#define CLK_MM_DSI0			16
+#define CLK_MM_DISP_FAKE_ENG0		17
+#define CLK_MM_DISP_FAKE_ENG1		18
+#define CLK_MM_SMI_GALS			19
+#define CLK_MM_SMI_IOMMU		20
+#define CLK_MM_DISP_RDMA1		21
+#define CLK_MM_DISP_DPI			22
+#define CLK_MM_DSI0_DSI_CK_DOMAIN	23
+#define CLK_MM_DISP_26M			24
+#define CLK_MM_NR_CLK			25
+
+/* WPESYS */
+
+#define CLK_WPE_CK_EN			0
+#define CLK_WPE_SMI_LARB8_CK_EN		1
+#define CLK_WPE_SYS_EVENT_TX_CK_EN	2
+#define CLK_WPE_SMI_LARB8_PCLK_EN	3
+#define CLK_WPE_NR_CLK			4
+
+/* IMGSYS1 */
+
+#define CLK_IMG1_LARB9_IMG1		0
+#define CLK_IMG1_LARB10_IMG1		1
+#define CLK_IMG1_DIP			2
+#define CLK_IMG1_GALS_IMG1		3
+#define CLK_IMG1_NR_CLK			4
+
+/* IMGSYS2 */
+
+#define CLK_IMG2_LARB9_IMG2		0
+#define CLK_IMG2_LARB10_IMG2		1
+#define CLK_IMG2_MFB			2
+#define CLK_IMG2_WPE			3
+#define CLK_IMG2_MSS			4
+#define CLK_IMG2_GALS_IMG2		5
+#define CLK_IMG2_NR_CLK			6
+
+/* VDECSYS */
+
+#define CLK_VDEC_LARB1_CKEN		0
+#define CLK_VDEC_LAT_CKEN		1
+#define CLK_VDEC_LAT_ACTIVE		2
+#define CLK_VDEC_LAT_CKEN_ENG		3
+#define CLK_VDEC_MINI_MDP_CKEN_CFG_RG	4
+#define CLK_VDEC_CKEN			5
+#define CLK_VDEC_ACTIVE			6
+#define CLK_VDEC_CKEN_ENG		7
+#define CLK_VDEC_NR_CLK			8
+
+/* VENCSYS */
+
+#define CLK_VENC_CKE0_LARB		0
+#define CLK_VENC_CKE1_VENC		1
+#define CLK_VENC_CKE2_JPGENC		2
+#define CLK_VENC_CKE5_GALS		3
+#define CLK_VENC_NR_CLK			4
+
+/* CAMSYS */
+
+#define CLK_CAM_LARB13			0
+#define CLK_CAM_DFP_VAD			1
+#define CLK_CAM_LARB14			2
+#define CLK_CAM				3
+#define CLK_CAMTG			4
+#define CLK_CAM_SENINF			5
+#define CLK_CAMSV1			6
+#define CLK_CAMSV2			7
+#define CLK_CAMSV3			8
+#define CLK_CAM_CCU0			9
+#define CLK_CAM_CCU1			10
+#define CLK_CAM_MRAW0			11
+#define CLK_CAM_FAKE_ENG		12
+#define CLK_CAM_CCU_GALS		13
+#define CLK_CAM2MM_GALS			14
+#define CLK_CAM_NR_CLK			15
+
+/* CAMSYS_RAWA */
+
+#define CLK_CAM_RAWA_LARBX_RAWA		0
+#define CLK_CAM_RAWA			1
+#define CLK_CAM_RAWA_CAMTG_RAWA		2
+#define CLK_CAM_RAWA_NR_CLK		3
+
+/* CAMSYS_RAWB */
+
+#define CLK_CAM_RAWB_LARBX_RAWB		0
+#define CLK_CAM_RAWB			1
+#define CLK_CAM_RAWB_CAMTG_RAWB		2
+#define CLK_CAM_RAWB_NR_CLK		3
+
+/* MDPSYS */
+
+#define CLK_MDP_RDMA0			0
+#define CLK_MDP_TDSHP0			1
+#define CLK_MDP_IMG_DL_ASYNC0		2
+#define CLK_MDP_IMG_DL_ASYNC1		3
+#define CLK_MDP_DISP_RDMA		4
+#define CLK_MDP_HMS			5
+#define CLK_MDP_SMI0			6
+#define CLK_MDP_APB_BUS			7
+#define CLK_MDP_WROT0			8
+#define CLK_MDP_RSZ0			9
+#define CLK_MDP_HDR0			10
+#define CLK_MDP_MUTEX0			11
+#define CLK_MDP_WROT1			12
+#define CLK_MDP_RSZ1			13
+#define CLK_MDP_FAKE_ENG0		14
+#define CLK_MDP_AAL0			15
+#define CLK_MDP_DISP_WDMA		16
+#define CLK_MDP_COLOR			17
+#define CLK_MDP_IMG_DL_ASYNC2		18
+#define CLK_MDP_IMG_DL_RELAY0_ASYNC0	19
+#define CLK_MDP_IMG_DL_RELAY1_ASYNC1	20
+#define CLK_MDP_IMG_DL_RELAY2_ASYNC2	21
+#define CLK_MDP_NR_CLK			22
+
+/* IPESYS */
+
+#define CLK_IPE_LARB19			0
+#define CLK_IPE_LARB20			1
+#define CLK_IPE_SMI_SUBCOM		2
+#define CLK_IPE_FD			3
+#define CLK_IPE_FE			4
+#define CLK_IPE_RSC			5
+#define CLK_IPE_DPE			6
+#define CLK_IPE_GALS_IPE		7
+#define CLK_IPE_NR_CLK			8
+
+#endif /* _DT_BINDINGS_CLK_MT8186_H */
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:12 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:12 +0800
Subject: [v1 12/16] clk: mediatek: Add MT8186 vdecsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-13-chun-jie.chen@mediatek.com>

Add MT8186 vdec clock controller which provide clock gate
control for video decoder.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile          |  2 +-
 drivers/clk/mediatek/clk-mt8186-vdec.c | 87 ++++++++++++++++++++++++++
 2 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-vdec.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 9f89e36d9ddf..e29e6a661115 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -70,7 +70,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
 				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
-				   clk-mt8186-img.o
+				   clk-mt8186-img.o clk-mt8186-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-vdec.c b/drivers/clk/mediatek/clk-mt8186-vdec.c
new file mode 100644
index 000000000000..f0aa2c491a32
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-vdec.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "clk-mtk.h"
+#include "clk-gate.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+
+static const struct mtk_gate_regs vdec0_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x4,
+	.sta_ofs = 0x0,
+};
+
+static const struct mtk_gate_regs vdec1_cg_regs = {
+	.set_ofs = 0x190,
+	.clr_ofs = 0x190,
+	.sta_ofs = 0x190,
+};
+
+static const struct mtk_gate_regs vdec2_cg_regs = {
+	.set_ofs = 0x200,
+	.clr_ofs = 0x204,
+	.sta_ofs = 0x200,
+};
+
+static const struct mtk_gate_regs vdec3_cg_regs = {
+	.set_ofs = 0x8,
+	.clr_ofs = 0xc,
+	.sta_ofs = 0x8,
+};
+
+#define GATE_VDEC0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec0_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC1(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+#define GATE_VDEC2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec2_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+#define GATE_VDEC3(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &vdec3_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
+
+static const struct mtk_gate vdec_clks[] = {
+	/* VDEC0 */
+	GATE_VDEC0(CLK_VDEC_CKEN, "vdec_cken", "top_vdec", 0),
+	GATE_VDEC0(CLK_VDEC_ACTIVE, "vdec_active", "top_vdec", 4),
+	GATE_VDEC0(CLK_VDEC_CKEN_ENG, "vdec_cken_eng", "top_vdec", 8),
+	/* VDEC1 */
+	GATE_VDEC1(CLK_VDEC_MINI_MDP_CKEN_CFG_RG, "vdec_mini_mdp_cken_cfg_rg", "top_vdec", 0),
+	/* VDEC2 */
+	GATE_VDEC2(CLK_VDEC_LAT_CKEN, "vdec_lat_cken", "top_vdec", 0),
+	GATE_VDEC2(CLK_VDEC_LAT_ACTIVE, "vdec_lat_active", "top_vdec", 4),
+	GATE_VDEC2(CLK_VDEC_LAT_CKEN_ENG, "vdec_lat_cken_eng", "top_vdec", 8),
+	/* VDEC3 */
+	GATE_VDEC3(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "top_vdec", 0),
+};
+
+static const struct mtk_clk_desc vdec_desc = {
+	.clks = vdec_clks,
+	.num_clks = ARRAY_SIZE(vdec_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_vdec[] = {
+	{
+		.compatible = "mediatek,mt8186-vdecsys",
+		.data = &vdec_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_vdec_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-vdec",
+		.of_match_table = of_match_clk_mt8186_vdec,
+	},
+};
+builtin_platform_driver(clk_mt8186_vdec_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:10 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:10 +0800
Subject: [v1 10/16] clk: mediatek: Add MT8186 wpesys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-11-chun-jie.chen@mediatek.com>

Add MT8186 wpesys clock controllers which provide clock gate
control in Wrapping Engine.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8186-wpe.c | 50 +++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-wpe.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index b34d89e757cb..380ab37ea151 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -69,7 +69,7 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
-				   clk-mt8186-mfg.o clk-mt8186-mm.o
+				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-wpe.c b/drivers/clk/mediatek/clk-mt8186-wpe.c
new file mode 100644
index 000000000000..677c78571ecc
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-wpe.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs wpe_cg_regs = {
+	.set_ofs = 0x0,
+	.clr_ofs = 0x0,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_WPE(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &wpe_cg_regs, _shift, &mtk_clk_gate_ops_no_setclr_inv)
+
+static const struct mtk_gate wpe_clks[] = {
+	GATE_WPE(CLK_WPE_CK_EN, "wpe", "top_wpe", 17),
+	GATE_WPE(CLK_WPE_SMI_LARB8_CK_EN, "wpe_smi_larb8", "top_wpe", 19),
+	GATE_WPE(CLK_WPE_SYS_EVENT_TX_CK_EN, "wpe_sys_event_tx", "top_wpe", 20),
+	GATE_WPE(CLK_WPE_SMI_LARB8_PCLK_EN, "wpe_smi_larb8_p_en", "top_wpe", 25),
+};
+
+static const struct mtk_clk_desc wpe_desc = {
+	.clks = wpe_clks,
+	.num_clks = ARRAY_SIZE(wpe_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_wpe[] = {
+	{
+		.compatible = "mediatek,mt8186-wpesys",
+		.data = &wpe_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_wpe_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-wpe",
+		.of_match_table = of_match_clk_mt8186_wpe,
+	},
+};
+builtin_platform_driver(clk_mt8186_wpe_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:16 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:16 +0800
Subject: [v1 16/16] clk: mediatek: Add MT8186 ipesys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-17-chun-jie.chen@mediatek.com>

Add MT8186 ipesys clock controller which provides clock gate
control for Image Process Engine.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8186-ipe.c | 54 +++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-ipe.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 7320df02356c..f370eb661c71 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -71,7 +71,7 @@ obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
 				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
 				   clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o \
-				   clk-mt8186-cam.o clk-mt8186-mdp.o
+				   clk-mt8186-cam.o clk-mt8186-mdp.o clk-mt8186-ipe.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-ipe.c b/drivers/clk/mediatek/clk-mt8186-ipe.c
new file mode 100644
index 000000000000..3e9160309a15
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-ipe.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs ipe_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_IPE(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &ipe_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate ipe_clks[] = {
+	GATE_IPE(CLK_IPE_LARB19, "ipe_larb19", "top_ipe", 0),
+	GATE_IPE(CLK_IPE_LARB20, "ipe_larb20", "top_ipe", 1),
+	GATE_IPE(CLK_IPE_SMI_SUBCOM, "ipe_smi_subcom", "top_ipe", 2),
+	GATE_IPE(CLK_IPE_FD, "ipe_fd", "top_ipe", 3),
+	GATE_IPE(CLK_IPE_FE, "ipe_fe", "top_ipe", 4),
+	GATE_IPE(CLK_IPE_RSC, "ipe_rsc", "top_ipe", 5),
+	GATE_IPE(CLK_IPE_DPE, "ipe_dpe", "top_ipe", 6),
+	GATE_IPE(CLK_IPE_GALS_IPE, "ipe_gals_ipe", "top_img1", 8),
+};
+
+static const struct mtk_clk_desc ipe_desc = {
+	.clks = ipe_clks,
+	.num_clks = ARRAY_SIZE(ipe_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_ipe[] = {
+	{
+		.compatible = "mediatek,mt8186-ipesys",
+		.data = &ipe_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_ipe_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-ipe",
+		.of_match_table = of_match_clk_mt8186_ipe,
+	},
+};
+builtin_platform_driver(clk_mt8186_ipe_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:11 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:11 +0800
Subject: [v1 11/16] clk: mediatek: Add MT8186 imgsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-12-chun-jie.chen@mediatek.com>

Add MT8186 imgsys clock controllers which provide clock gate
control for image IP blocks.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  3 +-
 drivers/clk/mediatek/clk-mt8186-img.c | 67 +++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-img.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 380ab37ea151..9f89e36d9ddf 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -69,7 +69,8 @@ obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
 obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
 obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
-				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o
+				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
+				   clk-mt8186-img.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-img.c b/drivers/clk/mediatek/clk-mt8186-img.c
new file mode 100644
index 000000000000..d84f137867a2
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-img.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs img_cg_regs = {
+	.set_ofs = 0x4,
+	.clr_ofs = 0x8,
+	.sta_ofs = 0x0,
+};
+
+#define GATE_IMG(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate img1_clks[] = {
+	GATE_IMG(CLK_IMG1_LARB9_IMG1, "img1_larb9_img1", "top_img1", 0),
+	GATE_IMG(CLK_IMG1_LARB10_IMG1, "img1_larb10_img1", "top_img1", 1),
+	GATE_IMG(CLK_IMG1_DIP, "img1_dip", "top_img1", 2),
+	GATE_IMG(CLK_IMG1_GALS_IMG1, "img1_gals_img1", "top_img1", 12),
+};
+
+static const struct mtk_gate img2_clks[] = {
+	GATE_IMG(CLK_IMG2_LARB9_IMG2, "img2_larb9_img2", "top_img1", 0),
+	GATE_IMG(CLK_IMG2_LARB10_IMG2, "img2_larb10_img2", "top_img1", 1),
+	GATE_IMG(CLK_IMG2_MFB, "img2_mfb", "top_img1", 6),
+	GATE_IMG(CLK_IMG2_WPE, "img2_wpe", "top_img1", 7),
+	GATE_IMG(CLK_IMG2_MSS, "img2_mss", "top_img1", 8),
+	GATE_IMG(CLK_IMG2_GALS_IMG2, "img2_gals_img2", "top_img1", 12),
+};
+
+static const struct mtk_clk_desc img1_desc = {
+	.clks = img1_clks,
+	.num_clks = ARRAY_SIZE(img1_clks),
+};
+
+static const struct mtk_clk_desc img2_desc = {
+	.clks = img2_clks,
+	.num_clks = ARRAY_SIZE(img2_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_img[] = {
+	{
+		.compatible = "mediatek,mt8186-imgsys1",
+		.data = &img1_desc,
+	}, {
+		.compatible = "mediatek,mt8186-imgsys2",
+		.data = &img2_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_img_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-img",
+		.of_match_table = of_match_clk_mt8186_img,
+	},
+};
+builtin_platform_driver(clk_mt8186_img_drv);
-- 
2.18.0



From chun-jie.chen at mediatek.com  Mon Jan 10 05:44:15 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Mon, 10 Jan 2022 21:44:15 +0800
Subject: [v1 15/16] clk: mediatek: Add MT8186 mdpsys clock support
In-Reply-To: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
Message-ID: <20220110134416.5191-16-chun-jie.chen@mediatek.com>

Add MT8186 mdpsys clock controller which provides clock gate
control in Multimedia Data Path.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
---
 drivers/clk/mediatek/Makefile         |  2 +-
 drivers/clk/mediatek/clk-mt8186-mdp.c | 79 +++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mediatek/clk-mt8186-mdp.c

diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
index 9190e17602eb..7320df02356c 100644
--- a/drivers/clk/mediatek/Makefile
+++ b/drivers/clk/mediatek/Makefile
@@ -71,7 +71,7 @@ obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt
 				   clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
 				   clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
 				   clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o \
-				   clk-mt8186-cam.o
+				   clk-mt8186-cam.o clk-mt8186-mdp.o
 obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
 obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
 obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
diff --git a/drivers/clk/mediatek/clk-mt8186-mdp.c b/drivers/clk/mediatek/clk-mt8186-mdp.c
new file mode 100644
index 000000000000..62f2f23c284b
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt8186-mdp.c
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (c) 2022 MediaTek Inc.
+// Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+
+#include "clk-gate.h"
+#include "clk-mtk.h"
+
+#include <dt-bindings/clock/mt8186-clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+static const struct mtk_gate_regs mdp0_cg_regs = {
+	.set_ofs = 0x104,
+	.clr_ofs = 0x108,
+	.sta_ofs = 0x100,
+};
+
+static const struct mtk_gate_regs mdp2_cg_regs = {
+	.set_ofs = 0x124,
+	.clr_ofs = 0x128,
+	.sta_ofs = 0x120,
+};
+
+#define GATE_MDP0(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mdp0_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+#define GATE_MDP2(_id, _name, _parent, _shift)			\
+	GATE_MTK(_id, _name, _parent, &mdp2_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
+
+static const struct mtk_gate mdp_clks[] = {
+	/* MDP0 */
+	GATE_MDP0(CLK_MDP_RDMA0, "mdp_rdma0", "top_mdp", 0),
+	GATE_MDP0(CLK_MDP_TDSHP0, "mdp_tdshp0", "top_mdp", 1),
+	GATE_MDP0(CLK_MDP_IMG_DL_ASYNC0, "mdp_img_dl_async0", "top_mdp", 2),
+	GATE_MDP0(CLK_MDP_IMG_DL_ASYNC1, "mdp_img_dl_async1", "top_mdp", 3),
+	GATE_MDP0(CLK_MDP_DISP_RDMA, "mdp_disp_rdma", "top_mdp", 4),
+	GATE_MDP0(CLK_MDP_HMS, "mdp_hms", "top_mdp", 5),
+	GATE_MDP0(CLK_MDP_SMI0, "mdp_smi0", "top_mdp", 6),
+	GATE_MDP0(CLK_MDP_APB_BUS, "mdp_apb_bus", "top_mdp", 7),
+	GATE_MDP0(CLK_MDP_WROT0, "mdp_wrot0", "top_mdp", 8),
+	GATE_MDP0(CLK_MDP_RSZ0, "mdp_rsz0", "top_mdp", 9),
+	GATE_MDP0(CLK_MDP_HDR0, "mdp_hdr0", "top_mdp", 10),
+	GATE_MDP0(CLK_MDP_MUTEX0, "mdp_mutex0", "top_mdp", 11),
+	GATE_MDP0(CLK_MDP_WROT1, "mdp_wrot1", "top_mdp", 12),
+	GATE_MDP0(CLK_MDP_RSZ1, "mdp_rsz1", "top_mdp", 13),
+	GATE_MDP0(CLK_MDP_FAKE_ENG0, "mdp_fake_eng0", "top_mdp", 14),
+	GATE_MDP0(CLK_MDP_AAL0, "mdp_aal0", "top_mdp", 15),
+	GATE_MDP0(CLK_MDP_DISP_WDMA, "mdp_disp_wdma", "top_mdp", 16),
+	GATE_MDP0(CLK_MDP_COLOR, "mdp_color", "top_mdp", 17),
+	GATE_MDP0(CLK_MDP_IMG_DL_ASYNC2, "mdp_img_dl_async2", "top_mdp", 18),
+	/* MDP2 */
+	GATE_MDP2(CLK_MDP_IMG_DL_RELAY0_ASYNC0, "mdp_img_dl_rel0_as0", "top_mdp", 0),
+	GATE_MDP2(CLK_MDP_IMG_DL_RELAY1_ASYNC1, "mdp_img_dl_rel1_as1", "top_mdp", 8),
+	GATE_MDP2(CLK_MDP_IMG_DL_RELAY2_ASYNC2, "mdp_img_dl_rel2_as2", "top_mdp", 24),
+};
+
+static const struct mtk_clk_desc mdp_desc = {
+	.clks = mdp_clks,
+	.num_clks = ARRAY_SIZE(mdp_clks),
+};
+
+static const struct of_device_id of_match_clk_mt8186_mdp[] = {
+	{
+		.compatible = "mediatek,mt8186-mdpsys",
+		.data = &mdp_desc,
+	}, {
+		/* sentinel */
+	}
+};
+
+static struct platform_driver clk_mt8186_mdp_drv = {
+	.probe = mtk_clk_simple_probe,
+	.driver = {
+		.name = "clk-mt8186-mdp",
+		.of_match_table = of_match_clk_mt8186_mdp,
+	},
+};
+builtin_platform_driver(clk_mt8186_mdp_drv);
-- 
2.18.0



From clabbe.montjoie at gmail.com  Mon Jan 10 05:56:35 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Mon, 10 Jan 2022 14:56:35 +0100
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
Message-ID: <Ydw7EzPvwArW/siQ@Red>

Le Mon, Jan 10, 2022 at 07:35:49PM +0800, Conley Lee a ?crit :
> This patch remove magic numbers in sun4i-emac.c and replace with macros
> defined in sun4i-emac.h
> 
> Change since v1
> ---------------
> - reformat
> - merge commits
> - add commit message
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
>  drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
>  2 files changed, 35 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
> index 849de4564709..98fd98feb439 100644
> --- a/drivers/net/ethernet/allwinner/sun4i-emac.c
> +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
> @@ -106,9 +106,9 @@ static void emac_update_speed(struct net_device *dev)
>  
>  	/* set EMAC SPEED, depend on PHY  */
>  	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
> -	reg_val &= ~(0x1 << 8);
> +	reg_val &= ~EMAC_MAC_SUPP_100M;
>  	if (db->speed == SPEED_100)
> -		reg_val |= 1 << 8;
> +		reg_val |= EMAC_MAC_SUPP_100M;
>  	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
>  }
>  
> @@ -264,7 +264,7 @@ static void emac_dma_done_callback(void *arg)
>  
>  	/* re enable interrupt */
>  	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -	reg_val |= (0x01 << 8);
> +	reg_val |= EMAC_INT_CTL_RX_EN;
>  	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  
>  	db->emacrx_completed_flag = 1;
> @@ -429,7 +429,7 @@ static unsigned int emac_powerup(struct net_device *ndev)
>  	/* initial EMAC */
>  	/* flush RX FIFO */
>  	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
> -	reg_val |= 0x8;
> +	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
>  	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
>  	udelay(1);
>  
> @@ -441,8 +441,8 @@ static unsigned int emac_powerup(struct net_device *ndev)
>  
>  	/* set MII clock */
>  	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
> -	reg_val &= (~(0xf << 2));
> -	reg_val |= (0xD << 2);
> +	reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK;
> +	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
>  	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
>  
>  	/* clear RX counter */
> @@ -506,7 +506,7 @@ static void emac_init_device(struct net_device *dev)
>  
>  	/* enable RX/TX0/RX Hlevel interrup */
>  	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -	reg_val |= (0xf << 0) | (0x01 << 8);
> +	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
>  	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  
>  	spin_unlock_irqrestore(&db->lock, flags);
> @@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
>  		if (!rxcount) {
>  			db->emacrx_completed_flag = 1;
>  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -			reg_val |= (0xf << 0) | (0x01 << 8);
> +			reg_val |=
> +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> +				 EMAC_INT_CTL_RX_EN);
>  			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  
>  			/* had one stuck? */
> @@ -669,7 +671,9 @@ static void emac_rx(struct net_device *dev)
>  			writel(reg_val | EMAC_CTL_RX_EN,
>  			       db->membase + EMAC_CTL_REG);
>  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -			reg_val |= (0xf << 0) | (0x01 << 8);
> +			reg_val |=
> +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> +				 EMAC_INT_CTL_RX_EN);
>  			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  
>  			db->emacrx_completed_flag = 1;
> @@ -783,20 +787,20 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
>  	}
>  
>  	/* Transmit Interrupt check */
> -	if (int_status & (0x01 | 0x02))
> +	if (int_status & EMAC_INT_STA_TX_COMPLETE)
>  		emac_tx_done(dev, db, int_status);
>  
> -	if (int_status & (0x04 | 0x08))
> +	if (int_status & EMAC_INT_STA_TX_ABRT)
>  		netdev_info(dev, " ab : %x\n", int_status);
>  
>  	/* Re-enable interrupt mask */
>  	if (db->emacrx_completed_flag == 1) {
>  		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -		reg_val |= (0xf << 0) | (0x01 << 8);
> +		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
>  		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  	} else {
>  		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> -		reg_val |= (0xf << 0);
> +		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
>  		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
>  	}
>  
> diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
> index 38c72d9ec600..90bd9ad77607 100644
> --- a/drivers/net/ethernet/allwinner/sun4i-emac.h
> +++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
> @@ -38,6 +38,7 @@
>  #define EMAC_RX_CTL_REG		(0x3c)
>  #define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
>  #define EMAC_RX_CTL_DMA_EN		(1 << 2)
> +#define EMAC_RX_CTL_FLUSH_FIFO		(1 << 3)
>  #define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
>  #define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
>  #define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
> @@ -61,7 +62,21 @@
>  #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
>  #define EMAC_RX_FBC_REG		(0x50)
>  #define EMAC_INT_CTL_REG	(0x54)
> +#define EMAC_INT_CTL_RX_EN	(1 << 8)
> +#define EMAC_INT_CTL_TX0_EN	(1)
> +#define EMAC_INT_CTL_TX1_EN	(1 << 1)
> +#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
> +#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
> +#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
> +#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
>  #define EMAC_INT_STA_REG	(0x58)
> +#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
> +#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
> +#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
> +#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
> +#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
> +#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
> +#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)

Hello

As proposed by checkpatch, I thing there are several place (like all EMAC_INT_STA) where you could use BIT(x) instead of (0xX << x)

Regards


From angelogioacchino.delregno at collabora.com  Mon Jan 10 06:28:24 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 15:28:24 +0100
Subject: [v2 1/3] clk: mediatek: Add error handle when fail to register
 clock provider
In-Reply-To: <20220110005902.27148-2-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
 <20220110005902.27148-2-chun-jie.chen@mediatek.com>
Message-ID: <b3d59493-7819-94e4-343e-d0514ab9f72b@collabora.com>

Il 10/01/22 01:59, Chun-Jie Chen ha scritto:
> Need to deference registered clocks when fail to
> regisiter clock provider.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From arnd at arndb.de  Mon Jan 10 06:28:40 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 10 Jan 2022 15:28:40 +0100
Subject: [PATCH V2 11/17] riscv: compat: Add elf.h implementation
In-Reply-To: <20211228143958.3409187-12-guoren@kernel.org>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-12-guoren@kernel.org>
Message-ID: <CAK8P3a0H2Nq=bFdzWGzzGuFWP85JA7=Td6_rb8GqOF3bYCRJBw@mail.gmail.com>

On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Implement necessary type and macro for compat elf. See the code
> comment for detail.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

This looks mostly correct,

> +/*
> + * FIXME: not sure SET_PERSONALITY for compat process is right!
> + */
> +#define SET_PERSONALITY(ex)                                               \
> +do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)                         \
> +               set_thread_flag(TIF_32BIT);                                \
> +       else                                                               \
> +               clear_thread_flag(TIF_32BIT);                              \
> +       set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
> +} while (0)

This means the personality after exec is always set to PER_LINUX, not
PER_LINUX32, which I think is wrong: you want the PER_LINUX32
setting to stick, just like the upper bits do in the default implementation.

What the other ones do is:

| arch/parisc/include/asm/elf.h-
set_personality((current->personality & ~PER_MASK) | PER_LINUX); \

This looks like the same problem you introduce here: always forcing PER_LINUX
instead of PER_LINUX32 makes it impossible to use PER_LINUX32.

| arch/alpha/include/asm/elf.h:#define SET_PERSONALITY(EX)
                           \
| arch/alpha/include/asm/elf.h-   set_personality(((EX).e_flags &
EF_ALPHA_32BIT)         \
| arch/alpha/include/asm/elf.h-      ? PER_LINUX_32BIT : PER_LINUX)
| arch/csky/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)
| arch/nds32/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)

These look even worse: instead of forcing the lower bits to
PER_LINUX/PER_LINUX32 and
leaving the upper bits untouched, these also clear the upper bits
unconditionally.

| arch/arm64/include/asm/elf.h:#define SET_PERSONALITY(ex)
                                   \
| arch/arm64/include/asm/elf.h-   current->personality &=
~READ_IMPLIES_EXEC;                     \
| arch/x86/um/asm/elf.h:#define SET_PERSONALITY(ex) do {} while(0)
| arch/x86/include/asm/elf.h:#define set_personality_64bit()      do {
} while (0)
| arch/x86/kernel/process_64.c:static void __set_personality_ia32(void)
|         current->personality |= force_personality32;

Inconsistent: does not enforce PER_LINUX/PER_LINUX32 as the default
implementation
does, but just leaves the value untouched (other than (re)setting
READ_IMPLIES_EXEC).
I think this is harmless otherwise, as we generally ignore the lower
bits, except for the
bit of code that checks for PER_LINUX32 in override_architecture() to mangle the
output of sys_newuname() or in /proc/cpuinfo.

| arch/s390/include/asm/elf.h-    if
(personality(current->personality) != PER_LINUX32)   \
| arch/s390/include/asm/elf.h-            set_personality(PER_LINUX |
                   \
| arch/s390/include/asm/elf.h-
(current->personality & ~PER_MASK));    \
| arch/powerpc/include/asm/elf.h- if
(personality(current->personality) != PER_LINUX32)   \
| arch/powerpc/include/asm/elf.h-         set_personality(PER_LINUX |
                   \
| arch/powerpc/include/asm/elf.h-
(current->personality & (~PER_MASK)));  \
| arch/sparc/include/asm/elf_64.h-        if
(personality(current->personality) != PER_LINUX32)   \
| arch/sparc/include/asm/elf_64.h-
set_personality(PER_LINUX |             \
| arch/sparc/include/asm/elf_64.h-
(current->personality & (~PER_MASK)));  \

This is probably the behavior you want to copy.

      Arnd


From angelogioacchino.delregno at collabora.com  Mon Jan 10 06:36:34 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 15:36:34 +0100
Subject: [v2 3/3] clk: mediatek: Integrate vppsys with mtk-mmsys in MT8195
In-Reply-To: <20220110005902.27148-4-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
 <20220110005902.27148-4-chun-jie.chen@mediatek.com>
Message-ID: <e5ca60a0-4fee-0d6b-0714-77dc51f5a7cf@collabora.com>

Il 10/01/22 01:59, Chun-Jie Chen ha scritto:
> Integrate vpp0 and vpp1 with mtk-mmsys driver which
> will populate device by platform_device_register_data
> to start vppsys clock driver.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Hello Chun-Jie,

I agree with this series and I would be happy to give you my R-b, but
this patch will make these clocks to *never* probe in in the targeted
kernel version.

You forgot to mention that this patch will break vpp0/vpp1 clocks entirely
unless applied on top of patch series [1].

Please, either mention that said series is *required* for this one to work
as expected, or move series [1], patches 6 and 7 to this series instead;
since the MDP3 driver will need quite a while to get merged, I would suggest
to move the patches here, as to get something "complete" to merge.

[1]: https://patchwork.kernel.org/project/linux-mediatek/list/?series=568283

> ---
>   drivers/clk/mediatek/clk-mt8195-vpp0.c | 42 +++++++++++++++++---------
>   drivers/clk/mediatek/clk-mt8195-vpp1.c | 42 +++++++++++++++++---------
>   2 files changed, 56 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8195-vpp0.c b/drivers/clk/mediatek/clk-mt8195-vpp0.c
> index c3241466a8d0..68c375bfce8b 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vpp0.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vpp0.c
> @@ -86,25 +86,39 @@ static const struct mtk_gate vpp0_clks[] = {
>   	GATE_VPP0_2(CLK_VPP0_WARP1_MDP_DL_ASYNC, "vpp0_warp1_mdp_dl_async", "top_wpe_vpp", 3),
>   };
>   
> -static const struct mtk_clk_desc vpp0_desc = {
> -	.clks = vpp0_clks,
> -	.num_clks = ARRAY_SIZE(vpp0_clks),
> -};
> +static int clk_mt8195_vpp0_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->parent->of_node;
> +	struct clk_onecell_data *clk_data;
> +	int r;
>   
> -static const struct of_device_id of_match_clk_mt8195_vpp0[] = {
> -	{
> -		.compatible = "mediatek,mt8195-vppsys0",
> -		.data = &vpp0_desc,
> -	}, {
> -		/* sentinel */
> -	}
> -};
> +	clk_data = mtk_alloc_clk_data(CLK_VPP0_NR_CLK);
> +	if (!clk_data)
> +		return -ENOMEM;
> +
> +	r = mtk_clk_register_gates(node, vpp0_clks, ARRAY_SIZE(vpp0_clks), clk_data);
> +	if (r)
> +		goto free_vpp0_data;
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		goto unregister_clk;
> +
> +	return r;
> +
> +unregister_clk:
> +	mtk_clk_unregister(clk_data);
> +
> +free_vpp0_data:
> +	mtk_free_clk_data(clk_data);
> +	return r;
> +}
>   
>   static struct platform_driver clk_mt8195_vpp0_drv = {
> -	.probe = mtk_clk_simple_probe,
> +	.probe = clk_mt8195_vpp0_probe,
>   	.driver = {
>   		.name = "clk-mt8195-vpp0",
> -		.of_match_table = of_match_clk_mt8195_vpp0,
>   	},
>   };
>   builtin_platform_driver(clk_mt8195_vpp0_drv);
> diff --git a/drivers/clk/mediatek/clk-mt8195-vpp1.c b/drivers/clk/mediatek/clk-mt8195-vpp1.c
> index ce0b9a40a179..237077c60f54 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vpp1.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vpp1.c
> @@ -84,25 +84,39 @@ static const struct mtk_gate vpp1_clks[] = {
>   	GATE_VPP1_1(CLK_VPP1_VPP_SPLIT_26M, "vpp1_vpp_split_26m", "clk26m", 26),
>   };
>   
> -static const struct mtk_clk_desc vpp1_desc = {
> -	.clks = vpp1_clks,
> -	.num_clks = ARRAY_SIZE(vpp1_clks),
> -};
> +static int clk_mt8195_vpp1_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->parent->of_node;
> +	struct clk_onecell_data *clk_data;
> +	int r;
>   
> -static const struct of_device_id of_match_clk_mt8195_vpp1[] = {
> -	{
> -		.compatible = "mediatek,mt8195-vppsys1",
> -		.data = &vpp1_desc,
> -	}, {
> -		/* sentinel */
> -	}
> -};
> +	clk_data = mtk_alloc_clk_data(CLK_VPP1_NR_CLK);
> +	if (!clk_data)
> +		return -ENOMEM;
> +
> +	r = mtk_clk_register_gates(node, vpp1_clks, ARRAY_SIZE(vpp1_clks), clk_data);
> +	if (r)
> +		goto free_vpp1_data;
> +
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		goto unregister_clk;
> +
> +	return r;
> +
> +unregister_clk:
> +	mtk_clk_unregister(clk_data);
> +
> +free_vpp1_data:
> +	mtk_free_clk_data(clk_data);
> +	return r;
> +}
>   
>   static struct platform_driver clk_mt8195_vpp1_drv = {
> -	.probe = mtk_clk_simple_probe,
> +	.probe = clk_mt8195_vpp1_probe,
>   	.driver = {
>   		.name = "clk-mt8195-vpp1",
> -		.of_match_table = of_match_clk_mt8195_vpp1,
>   	},
>   };
>   builtin_platform_driver(clk_mt8195_vpp1_drv);
> 


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


From mhocko at suse.com  Mon Jan 10 06:37:28 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 15:37:28 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yduuyrk/AZG717Hs@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
 <Yduuyrk/AZG717Hs@google.com>
Message-ID: <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>

On Sun 09-01-22 20:58:02, Yu Zhao wrote:
> On Fri, Jan 07, 2022 at 10:00:31AM +0100, Michal Hocko wrote:
> > On Fri 07-01-22 09:55:09, Michal Hocko wrote:
> > [...]
> > > > In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
> > > > reclaimer; and direct reclaimers rarely come here, i.e., only when
> > > > kswapd can't keep up in terms of the aging, which is similar to the
> > > > condition where the inactive list is empty for the active/inactive
> > > > lru.
> > > 
> > > Well, this is not a strong argument to be honest. Kswapd being stuck
> > > and the majority of the reclaim being done in the direct reclaim
> > > context is a situation I have seen many many times.
> > 
> > Also do not forget that memcg reclaim is effectivelly only direct
> > reclaim. Not that the memcg reclaim indicates a global memory shortage
> > but it can add up and race with the global reclaim as well.
> 
> I don't dispute any of the above, and I probably don't like this code
> more than you do.
> 
> But let's not forget the purposes of PF_MEMALLOC, besides preventing
> recursive reclaims, include letting reclaim dip into reserves so that
> it can make more free memory. So I think it's acceptable if the
> following conditions are met:
> 1. The allocation size is small.
> 2. The number of allocations is bounded.
> 3. Its failure doesn't stall reclaim.
> And it'd be nice if
> 4. The allocation happens rarely, e.g., slow path only.

I would add 
  0. The allocation should be done only if absolutely _necessary_.

Please keep in mind that whatever you allocate from that context will be
consuming a very precious memory reserves which are shared with other
components of the system. Even worse these can go all the way to
depleting memory completely where other things can fall apart.

> The code in question meets all of them.
> 
> 1. This allocation is 160 bytes.
> 2. It's bounded by the number of page table walkers which, in the
>    worst, is same as the number of mm_struct's.
> 3. Most importantly, its failure doesn't stall the aging. The aging
>    will fallback to the rmap-based function lru_gen_look_around().
>    But this function only gathers the accessed bit from at most 64
>    PTEs, meaning it's less efficient (retains ~80% performance gains).
> 4. This allocation is rare, i.e., only when the aging is required,
>    which is similar to the low inactive case for the active/inactive
>    lru.

I think this fallback behavior deserves much more detailed explanation
in changelogs.

> The bottom line is I can try various optimizations, e.g., preallocate
> a few buffers for a limited number of page walkers and if this number
> has been reached, fallback to the rmap-based function. But I have yet
> to see evidence that calls for additional complexity.

I would disagree here. This is not an optimization. You should be
avoiding allocations from the memory reclaim because any allocation just
add a runtime behavior complexity and potential corner cases.
-- 
Michal Hocko
SUSE Labs


From conleylee at foxmail.com  Mon Jan 10 06:40:38 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Mon, 10 Jan 2022 22:40:38 +0800
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <Ydw1MOcmS6fZ6J8d@lunn.ch>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
 <Ydw1MOcmS6fZ6J8d@lunn.ch>
Message-ID: <tencent_0C9377D282B45298ADD426820211360E8F07@qq.com>

On 01/10/22 at 02:31??, Andrew Lunn wrote:
> Date: Mon, 10 Jan 2022 14:31:28 +0100
> From: Andrew Lunn <andrew at lunn.ch>
> To: Conley Lee <conleylee at foxmail.com>
> Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
>  wens at csie.org, clabbe.montjoie at gmail.com, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v2] net: ethernet: sun4i-emac: replace magic number
>  with macro
> 
> > @@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
> >  		if (!rxcount) {
> >  			db->emacrx_completed_flag = 1;
> >  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -			reg_val |= (0xf << 0) | (0x01 << 8);
> > +			reg_val |=
> > +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> > +				 EMAC_INT_CTL_RX_EN);
> 
> Putting the first value on the next line is a bit odd. This would be
> preferred:
> 
> +			reg_val |= (EMAC_INT_CTL_TX_EN |
> +                                   EMAC_INT_CTL_TX_ABRT_EN |
> +				    EMAC_INT_CTL_RX_EN);
> 
> I also have to wonder why two | have become three? (0x01 << 8) is
> clearly a single value. (0xf << 0) should either be a single macro, or
> 4 macros since 0xf is four bits. Without looking into the details, i
> cannot say this is wrong, but it does look strange.
> 
>        Andrew
> 
Thanks for your suggestion. The (0xf << 0) mask enable tx finish and tx abort
interrupts at hardware level. And the reason this mask has 4 bits is that
sun4i emac has 2 tx channels. I reduce it into two macros EMAC_INT_CTL_TX_EN 
and EMAC_INT_CTL_TX_ABRT_EN, this may be more readable, since we always
enable both tx channels in the driver.


From conleylee at foxmail.com  Mon Jan 10 06:42:02 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Mon, 10 Jan 2022 22:42:02 +0800
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <YdwvEKiKd0JKpG9T@unreal>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
 <YdwvEKiKd0JKpG9T@unreal>
Message-ID: <tencent_6DDF530ADA4A09B6D49B4E0A8CD9F23D7809@qq.com>

On 01/10/22 at 03:05??, Leon Romanovsky wrote:
> Date: Mon, 10 Jan 2022 15:05:20 +0200
> From: Leon Romanovsky <leon at kernel.org>
> To: Conley Lee <conleylee at foxmail.com>
> Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
>  wens at csie.org, clabbe.montjoie at gmail.com, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v2] net: ethernet: sun4i-emac: replace magic number
>  with macro
> 
> On Mon, Jan 10, 2022 at 07:35:49PM +0800, Conley Lee wrote:
> > This patch remove magic numbers in sun4i-emac.c and replace with macros
> > defined in sun4i-emac.h
> > 
> > Change since v1
> > ---------------
> > - reformat
> > - merge commits
> > - add commit message
> 
> This changelog should be placed after "---" below your SOB.
> 
> Thanks
> 
> > 
> > Signed-off-by: Conley Lee <conleylee at foxmail.com>
> > ---
> >  drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
> >  drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
> >  2 files changed, 35 insertions(+), 13 deletions(-)
I will reformat it and submit again, thanks ~


From maz at kernel.org  Mon Jan 10 06:44:17 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 10 Jan 2022 14:44:17 +0000
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a
 static driver structure
In-Reply-To: <20220110105324.jud6bzdtmoiuvyas@pali>
References: <20220110015018.26359-1-kabel@kernel.org>
 <20220110015018.26359-24-kabel@kernel.org>
 <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
 <20220110105324.jud6bzdtmoiuvyas@pali>
Message-ID: <87mtk3tzum.wl-maz@kernel.org>

On Mon, 10 Jan 2022 10:53:24 +0000,
Pali Roh?r <pali at kernel.org> wrote:
> 
> On Monday 10 January 2022 09:28:39 Marc Zyngier wrote:
> > On 2022-01-10 01:50, Marek Beh?n wrote:
> > > Marc Zyngier says [1] that we should use struct irq_chip as a global
> > > static struct in the driver. Even though the structure currently
> > > contains a dynamic member (parent_device), Marc says [2] that he plans
> > > to kill it and make the structure completely static.
> > > 
> > > We have already converted others irq_chip structures in this driver in
> > > this way, but we omitted this one because the .name member is
> > > dynamically created from device's name, and the name is displayed in
> > > sysfs, so changing it would break sysfs ABI.
> > > 
> > > The rationale for changing the name (to "advk-INT") in spite of sysfs
> > > ABI, and thus allowing to convert to a static structure, is that after
> > > the other changes we made in this series, the IRQ chip is basically
> > > something different: it no logner generates ERR and PME interrupts (they
> > > are generated by emulated bridge's rp_irq_chip).
> > 
> > There is no 'is spite of the ABI'. If you don't understand why
> > we don't break the ABI, you have an even bigger problem.
> > 
> > So NAK to this patch, now and forever. Any change to the structure to
> > make it read-only must allow the preservation of the existing names
> > when they are generated by the driver.
> 
> Marc, you already presented that you do not like Armada 3720 platform
> and that you do not care about it.

What I like or not is irrelevant here. What I ask for is that
userspace ABIs are not broken.

> But please do not slowdown development for this platform.

That's quite an accusation.

> Arguments about ABIs, breaking it and similar are not relevant here as
> this current kernel implementation is broken. And has to be replaced by
> a working one. We are doing on it for more than year.
>
> It really does not make sense to try doing some backward compatibility
> with something which is broken by design and does not work. It just take
> lot of time without any value.
> 
> We really need to more forward and fix driver as in current state is
> PCIe on Armada 3720 unusable.

This patch doesn't fix anything. It has the potential to break
userspace, and I'm not having any of it. You may not care about
backward compatibility, but this is thankfully *not* your pet
playground.

You can claim that I am doing a bad job. In which case, feel free to
submit a patch removing me from the MAINTAINER file, and we can have
that discussion.

In the meantime, I will continue to oppose these kind of patches that
pretend to 'fix' things without adding any value.

	M.

-- 
Without deviation from the norm, progress is not possible.


From jbrunet at baylibre.com  Mon Jan 10 06:29:45 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 10 Jan 2022 15:29:45 +0100
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>


On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:

Title is bad (like several other patches in this series) - Please fix it

> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>  1 file changed, 163 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..1004fd0b0c9e 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,13 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct uart_port	port;
> +	struct clk		*pclk;
> +	struct clk		*baud_clk;
> +	bool			use_xtal_clk;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>  static int meson_uart_startup(struct uart_port *port)
>  {
>  	u32 val;
> -	int ret = 0;
> +	int ret;
>  
> -	val = readl(port->membase + AML_UART_CONTROL);
> -	val |= AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> -	val &= ~AML_UART_CLEAR_ERR;
> -	writel(val, port->membase + AML_UART_CONTROL);
> +	meson_uart_reset(port);
>  
> +	val = readl(port->membase + AML_UART_CONTROL);
>  	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>  	writel(val, port->membase + AML_UART_CONTROL);
>  
> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
> +	clk_disable_unprepare(private_data->pclk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->pclk);
> +	if (ret)
> +		return ret;

In the previous version of the series, you already been asked to the
enable of pclk in the probe. Optimization should not be mixed with this
series

Please make sure all comments are addressed before re-posting

> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret) {
> +		clk_disable_unprepare(private_data->pclk);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
>  
> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> +#define CLK_NAME(name) \
> +({\
> +	char clk_name[32];\
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
> +	clk_name;\
> +})

1) This result in some ugly code being inlined
2) You return a pointer a local variable which is not gurantee to exist
anymore  outside of this ...

Please do this simply in the related function.

> +
> +static struct clk_div_table xtal_div_table[] = {
> +	{ 0, 3  },
> +	{ 1, 1  },
> +	{ 2, 2  },
> +	{ 3, 2  },
> +};
> +
> +static int meson_uart_probe_clocks(struct uart_port *port)
>  {
> -	struct clk *clk = NULL;
> -	int ret;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};
>  
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
> +	if (IS_ERR(private_data->pclk))
> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
> +				     "Failed to get the 'pclk' clock\n");
>  
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
>  	}
>  
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> -
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> -{
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> -
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> -
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							CLK_NAME(xtal_div),
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       CLK_NAME(clk81_div4),
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}

Contradiction with previous series.
In the previous series we could clearly see that gxbb did not have the
/4 divider. It did not have bits 26 and 27 either.

Now gxbb get the /4 divider. It operated correctly without it so far, so
this is rather suspicious. Could you please comment on this ?

>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					CLK_NAME(use_xtal),
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  CLK_NAME(baud_div),
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");

I have already commented on the use of this function in the previous
version.

Please make sure all comments are addressed before re-posting

>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem;
>  	struct uart_port *port;
>  	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>  		return -EBUSY;
>  	}
>  
> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
> -	if (!port)
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
>  		return -ENOMEM;
>  
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
> +
> +	port = &private_data->port;
> +
>  	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> -
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
>  	port->mapsize = resource_size(res_mem);
> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = fifosize;
> +	port->private_data = private_data;

port has private_data
private_data has port

Is it really necessary to have both ... looks to me that port in
private_data is overkill

>  
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
>  
> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxbb-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gxl-uart",
> +		.data = (void *)true,
> +	},
> +	{
> +		.compatible = "amlogic,meson-g12a-uart",
> +		.data = (void *)true,
> +	},
> +	/*
> +	 * deprecated, don't use anymore because it doesn't differentiate
> +	 * between GXBB, GXL and G12A which have different revisions
> +	 * of the UART IP.
> +	 */
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)false,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From hakavlad at inbox.lv  Mon Jan 10 06:49:32 2022
From: hakavlad at inbox.lv (Alexey Avramov)
Date: Mon, 10 Jan 2022 23:49:32 +0900
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220110234932.6eb6c356@mail.inbox.lv>

Note that with vm.swappiness=0, the vm.watermark_scale_factor value does
not affect the swap possibility: MGLRU ignores sc->file_is_tiny.

With the classic 2-gen LRU swapping goes well at swappiness=0 and
high vm.watermark_scale_factor, which is expected according to the
documentation:
"At 0, the kernel will not initiate swap until the amount of free and
file-backed pages is less than the high watermark in a zone." [1]

With vm.swappiness=0, no swap occurs with any vm.watermark_scale_factor
value with MGLRU.

I used to see in practice (with MGLRU v3) the impossibility of swapping 
when vm.swappiness=0 and vm.watermark_scale_factor=1000.

At a minimum, this will require updating the documentation for
vm.swappiness.

BTW, why MGLRU doesn't use something like sc->file_is_tiny?

[1] https://github.com/torvalds/linux/blob/v5.16/Documentation/admin-guide/sysctl/vm.rst#swappiness


From maz at kernel.org  Mon Jan 10 06:54:36 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 10 Jan 2022 14:54:36 +0000
Subject: [PATCH 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>
References: <20220108084218.31877-1-qianggui.song@amlogic.com>
 <20220108084218.31877-5-qianggui.song@amlogic.com>
 <87r19itrjx.wl-maz@kernel.org>
 <835a3f28-ec6a-9cd2-d574-5ef87b630fb3@amlogic.com>
Message-ID: <87lezntzdf.wl-maz@kernel.org>

On Mon, 10 Jan 2022 12:32:23 +0000,
qianggui.song <Qianggui.Song at amlogic.com> wrote:
> 
> 
> 
> On 1/8/22 7:06 PM, Marc Zyngier wrote:
> > 
> > On Sat, 08 Jan 2022 08:42:18 +0000,
> > Qianggui Song <qianggui.song at amlogic.com> wrote:
> >> 
> >> The meson s4 SoCs support 12 gpio irq lines compared with previous
> >> serial chips and have something different, details are as below.
> >> 
> >> IRQ Number:
> >> - 80:68 13 pins on bank Z
> >> - 67:48 20 pins on bank X
> >> - 47:36 12 pins on bank H
> >> - 35:24 12 pins on bank D
> >> - 23:22 2  pins on bank E
> >> - 21:14 8  pins on bank C
> >> - 13:0  13 pins on bank B
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL0
> >>    bit[31]:    enable/disable the whole irq lines
> > 
> > s/the whole/all the/
> Okay
> > 
> >>    bit[12-23]: single edge trigger
> >>    bit[0-11]:  poll trigger
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL[X]
> >> - bit[0-16]: 7 bits to chooge gpio source for irq line 2*[X] - 2
> > 
> > choose?
> yes it is choose
> > 
> >> - bit[16-22]:7 bits to chooge gpio source for irq line 2*[X] - 1
> >>    where X = 1-6
> >> 
> >> - PADCTRL_GPIO_IRQ_CTRL[7]
> >>    bit[0-11]: both edge trigger
> > 
> > This information would fit better in the code than in the commit
> > message.
> > 
> will copy this to code.
> >> 
> >> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> >> ---
> >>   drivers/irqchip/irq-meson-gpio.c | 51 ++++++++++++++++++++++++++++++++
> >>   1 file changed, 51 insertions(+)
> >> 
> >> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> >> index 98419428fcbd..c5d20a866c37 100644
> >> --- a/drivers/irqchip/irq-meson-gpio.c
> >> +++ b/drivers/irqchip/irq-meson-gpio.c
> >> @@ -42,6 +42,11 @@
> >>   #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
> >>   #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
> >>   +/* use for s4 chips */
> > 
> > s/use/Used/
> okay
> > 
> >> +#define REG_EDGE_POL_S4	0x1c
> >> +#define REG_EDGE_POL_MASK_S4(x)				\
> >> +	({typeof(x) _x = (x); BIT(_x) | BIT(12 + (_x)); })
> > 
> > Why on Earth should this macro handle multiple types?
> If I use  #define REG_EDGE_POL_MASK_S4(x) (BIT(x) | BIT(12 + (x)), when
> run git format-patch -1 --stdout | ./script/checkpath.pl --strict -,
> will get a message
> CHECK: Macro argument reuse 'x' - possible side-effects?

Well, either expand the macro directly in the code (after all, there
is only one use for it) or make this a C function instead of a macro.

	M.

-- 
Without deviation from the norm, progress is not possible.


From mhocko at suse.com  Mon Jan 10 07:01:13 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 16:01:13 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdcU4P+XWkbDUUoO@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz>
Message-ID: <YdxKORU9OWCv114O@dhcp22.suse.cz>

On Thu 06-01-22 17:12:18, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > +{
> > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);

One thing I have overlooked completely. You cannot really use GFP_KERNEL
allocation here because the reclaim context can be constrained (e.g.
GFP_NOFS). This allocation will not do any reclaim as it is PF_MEMALLOC
but I suspect that the lockdep will complain anyway.

Also kvmalloc is not really great here. a) vmalloc path is never
executed for small objects and b) we do not really want to make a
dependency between vmalloc and the reclaim (by vmalloc -> reclaim ->
vmalloc).

Even if we rule out vmalloc and look at kmalloc alone. Is this really
safe? I do not see any recursion prevention in the SL.B code. Maybe this
just happens to work but the dependency should be really documented so
that future SL.B changes won't break the whole scheme. 
-- 
Michal Hocko
SUSE Labs


From krzysztof.kozlowski at canonical.com  Mon Jan 10 07:10:59 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 16:10:59 +0100
Subject: [PATCH 2/2] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <CAPLW+4miCOwFR11gdaU1nMQZdk8zVcWOcSK=Wjd3AaCagGLyug@mail.gmail.com>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
 <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
 <CAPLW+4miCOwFR11gdaU1nMQZdk8zVcWOcSK=Wjd3AaCagGLyug@mail.gmail.com>
Message-ID: <372040ab-6ada-62e9-727f-6daeba8e73f8@canonical.com>

On 03/01/2022 15:41, Sam Protsenko wrote:
> On Sun, 2 Jan 2022 at 17:58, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
>> controller bindings to DT schema format
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 220 ++++++++++++++++++
>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ----------
>>  MAINTAINERS                                   |   2 +-
>>  3 files changed, 221 insertions(+), 123 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>>
>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> new file mode 100644
>> index 000000000000..195bfafe05fd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> @@ -0,0 +1,220 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung S3C/S5P/Exynos SoC SPI controller
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description:
>> +  All the SPI controller nodes should be represented in the aliases node using
>> +  the following format 'spi{n}' where n is a unique number for the alias.
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - enum:
>> +          - samsung,s3c2443-spi
> 
> Maybe add the list of supported platforms for each compatible (in a
> comment on the same line), like it was done in .txt binding?
> 
> Other than that:
> 

Sure.


Best regards,
Krzysztof


From kabel at kernel.org  Mon Jan 10 07:19:27 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Mon, 10 Jan 2022 16:19:27 +0100
Subject: [PATCH v2 23/23] PCI: aardvark: Make main irq_chip structure a
 static driver structure
In-Reply-To: <87mtk3tzum.wl-maz@kernel.org>
References: <20220110015018.26359-1-kabel@kernel.org>
 <20220110015018.26359-24-kabel@kernel.org>
 <bf65af53fe1a4e6b814b124b59ad3aa9@kernel.org>
 <20220110105324.jud6bzdtmoiuvyas@pali>
 <87mtk3tzum.wl-maz@kernel.org>
Message-ID: <20220110161927.64362d52@thinkpad>

On Mon, 10 Jan 2022 14:44:17 +0000
Marc Zyngier <maz at kernel.org> wrote:

> On Mon, 10 Jan 2022 10:53:24 +0000,
> Pali Roh?r <pali at kernel.org> wrote:
> > 
> > On Monday 10 January 2022 09:28:39 Marc Zyngier wrote:  
> > > On 2022-01-10 01:50, Marek Beh?n wrote:  
> > > > Marc Zyngier says [1] that we should use struct irq_chip as a global
> > > > static struct in the driver. Even though the structure currently
> > > > contains a dynamic member (parent_device), Marc says [2] that he plans
> > > > to kill it and make the structure completely static.
> > > > 
> > > > We have already converted others irq_chip structures in this driver in
> > > > this way, but we omitted this one because the .name member is
> > > > dynamically created from device's name, and the name is displayed in
> > > > sysfs, so changing it would break sysfs ABI.
> > > > 
> > > > The rationale for changing the name (to "advk-INT") in spite of sysfs
> > > > ABI, and thus allowing to convert to a static structure, is that after
> > > > the other changes we made in this series, the IRQ chip is basically
> > > > something different: it no logner generates ERR and PME interrupts (they
> > > > are generated by emulated bridge's rp_irq_chip).  
> > > 
> > > There is no 'is spite of the ABI'. If you don't understand why
> > > we don't break the ABI, you have an even bigger problem.
> > > 
> > > So NAK to this patch, now and forever. Any change to the structure to
> > > make it read-only must allow the preservation of the existing names
> > > when they are generated by the driver.  
> > 
> > Marc, you already presented that you do not like Armada 3720 platform
> > and that you do not care about it.  
> 
> What I like or not is irrelevant here. What I ask for is that
> userspace ABIs are not broken.
> 
> > But please do not slowdown development for this platform.  
> 
> That's quite an accusation.
> 
> > Arguments about ABIs, breaking it and similar are not relevant here as
> > this current kernel implementation is broken. And has to be replaced by
> > a working one. We are doing on it for more than year.
> >
> > It really does not make sense to try doing some backward compatibility
> > with something which is broken by design and does not work. It just take
> > lot of time without any value.
> > 
> > We really need to more forward and fix driver as in current state is
> > PCIe on Armada 3720 unusable.  
> 
> This patch doesn't fix anything. It has the potential to break
> userspace, and I'm not having any of it. You may not care about
> backward compatibility, but this is thankfully *not* your pet
> playground.
> 
> You can claim that I am doing a bad job. In which case, feel free to
> submit a patch removing me from the MAINTAINER file, and we can have
> that discussion.
> 
> In the meantime, I will continue to oppose these kind of patches that
> pretend to 'fix' things without adding any value.
> 
> 	M.

Dear Marc,

that is why I put this patch as last patch of this series, so that it
could be potentially dropped.

I mostly agree with your points, Pali does not. Pali, let's not sabotage
ourselves with needless arguments. Marc, Pali means well, but sometimes
when he has different opinion, he can get quite argumentative. Let's
ignore this patch for now.

Marc, what do you think about the other patches? Did you have time to
look at them?

Thanks.

Marek


From mhocko at suse.com  Mon Jan 10 07:21:53 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 16:21:53 +0100
Subject: [PATCH v6 5/9] mm: multigenerational lru: mm_struct list
In-Reply-To: <YdjYkFmtMdrYg736@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-6-yuzhao@google.com>
 <YdgChw4vNb43XsU/@dhcp22.suse.cz> <YdjYkFmtMdrYg736@google.com>
Message-ID: <YdxPEdsfl771Z7IX@dhcp22.suse.cz>

On Fri 07-01-22 17:19:28, Yu Zhao wrote:
> On Fri, Jan 07, 2022 at 10:06:15AM +0100, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:24, Yu Zhao wrote:
> > > To exploit spatial locality, the aging prefers to walk page tables to
> > > search for young PTEs. And this patch paves the way for that.
> > > 
> > > An mm_struct list is maintained for each memcg, and an mm_struct
> > > follows its owner task to the new memcg when this task is migrated.
> > 
> > How does this work actually for the memcg reclaim? I can see you
> > lru_gen_migrate_mm on the task migration. My concern is, though, that
> > such a task leaves all the memory behind in the previous memcg (in
> > cgroup v2, in v1 you can opt in for charge migration). If you move the
> > mm to a new memcg then you age it somewhere where the memory is not
> > really consumed.
> 
> There are two options to gather the accessed bit: page table walks and
> rmap walks. Page table walks sweep dense hotspots that are NOT
> misplaced in terms of reclaim scope (lruvec); rmap walks cover what
> page table walks miss, e.g., misplaced dense hotspots or sparse ones.
> 
> Dense hotspots are stored in Bloom filters for each lruvec.
> 
> If an mm leaves everything in the old memcg, page table walks in the
> new memcg reclaim path basically ignore this mm after the first scan,
> because everything is misplaced.

OK, so do I get it right that pages mapped from a different memcg than
the reclaimed one are considered effectivelly non-present from the the
reclaim logic POV? This would be worth mentioning in the migration
callback because it is not really that straightforward to put those two
together.
 
> In the old memcg reclaim path, page table walks won't see this mm
> at all. But rmap walks will catch everything later in the eviction
> path, i.e., lru_gen_look_around(). This function is less efficient
> compared with page table walks because, for each rmap walk of a
> non-shared page, it only can gather the accessed bit from 64 PTEs at
> most. But it's still a lot faster than the original rmap, which only
> gathers the accessed bit from a single PTE, for each walk of a
> non-shared page.

Again, something that should be really documented.
-- 
Michal Hocko
SUSE Labs


From jagan at amarulasolutions.com  Mon Jan 10 07:27:13 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Mon, 10 Jan 2022 20:57:13 +0530
Subject: [PATCH 1/2] arm64: dts: exynos: Link DSI panel at port@1 for TM2 board
Message-ID: <20220110152714.58220-1-jagan@amarulasolutions.com>

TM2 board DSI pipeline has input from MIC and output to
s6e3ha2 panel.

The existing pipeline has child nodes of ports, panel and
MIC is remote-endpoint reference of port at 0 of ports.?

Adding panel as another child node to DSI is unconventional
as pipeline has ports child. However it can be true if MIC
is added inside port node like this.

dsi {
	compatible = "samsung,exynos5433-mipi-dsi";
	#address-cells = <1>;
	#size-cells = <0>;

	port {
		dsi_to_mic: endpoint {
			remote-endpoint = <&mic_to_dsi>;
		};
	};

	panel at 0 {
		compatible = "samsung,s6e3hf2";
                reg = <0>;
                vdd3-supply = <&ldo27_reg>;
                vci-supply = <&ldo28_reg>;
                reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
                enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
	};
};

The above pipeline is proper but it requires the DSI input MIC
pipeline to update.

This patch is trying to add panel at port at 1 so-that the entire
pipeline before to panel output is untouched.

Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index aca01709fd29..e13210c8d7e0 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -53,6 +53,16 @@ &cmu_disp {
 };
 
 &dsi {
+	ports {
+		port at 1 {
+			reg = <1>;
+
+			dsi_out_panel: endpoint {
+				remote-endpoint = <&dsi_in_panel>;
+			};
+		};
+	};
+
 	panel at 0 {
 		compatible = "samsung,s6e3ha2";
 		reg = <0>;
@@ -60,6 +70,12 @@ panel at 0 {
 		vci-supply = <&ldo28_reg>;
 		reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
 		enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+
+		port {
+			dsi_in_panel: endpoint {
+				remote-endpoint = <&dsi_out_panel>;
+			};
+		};
 	};
 };
 
-- 
2.25.1



From jagan at amarulasolutions.com  Mon Jan 10 07:27:14 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Mon, 10 Jan 2022 20:57:14 +0530
Subject: [PATCH 2/2] arm64: dts: exynos: Link DSI panel at port@1 for TM2E
 board
In-Reply-To: <20220110152714.58220-1-jagan@amarulasolutions.com>
References: <20220110152714.58220-1-jagan@amarulasolutions.com>
Message-ID: <20220110152714.58220-2-jagan@amarulasolutions.com>

TM2E board DSI pipeline has input from MIC and output to
s6e3ha2 panel.

The existing pipeline has child nodes of ports, panel and
MIC is remote-endpoint reference of port at 0 of ports.?

Adding panel as another child node to DSI is unconventional
as pipeline has ports child. However it can be true if MIC
is added inside port node like this.

dsi {
	compatible = "samsung,exynos5433-mipi-dsi";
	#address-cells = <1>;
	#size-cells = <0>;

	port {
		dsi_to_mic: endpoint {
			remote-endpoint = <&mic_to_dsi>;
		};
	};

	panel at 0 {
		compatible = "samsung,s6e3hf2";
                reg = <0>;
                vdd3-supply = <&ldo27_reg>;
                vci-supply = <&ldo28_reg>;
                reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
                enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
	};
};

The above pipeline is proper but it requires the DSI input MIC
pipeline to update.

This patch is trying to add panel at port at 1 so-that the entire
pipeline before to panel output is untouched.

Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
---
 arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
index 22d26460f3dd..09418fe30353 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -51,6 +51,16 @@ &cmu_disp {
 };
 
 &dsi {
+	ports {
+		port at 1 {
+			reg = <1>;
+
+			dsi_out_panel: endpoint {
+				remote-endpoint = <&dsi_in_panel>;
+			};
+		};
+	};
+
 	panel at 0 {
 		compatible = "samsung,s6e3hf2";
 		reg = <0>;
@@ -58,6 +68,12 @@ panel at 0 {
 		vci-supply = <&ldo28_reg>;
 		reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
 		enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
+
+		port {
+			dsi_in_panel: endpoint {
+				remote-endpoint = <&dsi_out_panel>;
+			};
+		};
 	};
 };
 
-- 
2.25.1



From mhocko at suse.com  Mon Jan 10 07:35:46 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 16:35:46 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdjOazilBEkdUT7x@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz> <YdjOazilBEkdUT7x@google.com>
Message-ID: <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>

On Fri 07-01-22 16:36:11, Yu Zhao wrote:
> On Fri, Jan 07, 2022 at 02:11:29PM +0100, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > [...]
> > > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
> > > +{
> > > +	struct mem_cgroup *memcg;
> > > +	bool success = false;
> > > +	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
> > > +
> > > +	VM_BUG_ON(!current_is_kswapd());
> > > +
> > > +	current->reclaim_state->mm_walk = &pgdat->mm_walk;
> > > +
> > > +	memcg = mem_cgroup_iter(NULL, NULL, NULL);
> > > +	do {
> > > +		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
> > > +
> > > +		if (age_lruvec(lruvec, sc, min_ttl))
> > > +			success = true;
> > > +
> > > +		cond_resched();
> > > +	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
> > > +
> > > +	if (!success && mutex_trylock(&oom_lock)) {
> > > +		struct oom_control oc = {
> > > +			.gfp_mask = sc->gfp_mask,
> > > +			.order = sc->order,
> > > +		};
> > > +
> > > +		if (!oom_reaping_in_progress())
> > > +			out_of_memory(&oc);
> > > +
> > > +		mutex_unlock(&oom_lock);
> > > +	}
> > 
> > Why do you need to trigger oom killer from this path? Why cannot you
> > rely on the page allocator to do that like we do now?
> 
> This is per desktop users' (repeated) requests. The can't tolerate
> thrashing as servers do because of UI lags; and they usually don't
> have fancy tools like oomd.
> 
> Related discussions I saw:
> https://github.com/zen-kernel/zen-kernel/issues/218
> https://lore.kernel.org/lkml/20101028191523.GA14972 at google.com/
> https://lore.kernel.org/lkml/20211213051521.21f02dd2 at mail.inbox.lv/
> https://lore.kernel.org/lkml/54C2C89C.8080002 at gmail.com/
> https://lore.kernel.org/lkml/d9802b6a-949b-b327-c4a6-3dbca485ec20 at gmx.com/

I do not really see any arguments why an userspace based trashing
detection cannot be used for those. Could you clarify?

Also my question was pointing to why out_of_memory is called from the
reclaim rather than the allocator (memcg charging path). It is the
caller of the reclaim to control different reclaim strategies and tell
when all the hopes are lost and the oom killer should be invoked. This
allows for a different policies at the allocator level and this change
will break that AFAICS. E.g. what if the underlying allocation context
is __GFP_NORETRY?
 
> >From patch 8:
>   Personal computers
>   ------------------
>   :Thrashing prevention: Write ``N`` to
>    ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
>    ``N`` milliseconds from getting evicted. The OOM killer is invoked if
>    this working set can't be kept in memory. Based on the average human
>    detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
>    lags due to thrashing. Larger values like ``N=3000`` make lags less
>    noticeable at the cost of more OOM kills.

This is a very good example of something that should be a self contained
patch with its own justification. TBH it is really not all that clear to
me that we want to provide any user visible knob to control OOM behavior
based on a time based QoS.

-- 
Michal Hocko
SUSE Labs


From lee.jones at linaro.org  Mon Jan 10 07:38:12 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 10 Jan 2022 15:38:12 +0000
Subject: [PATCH v2 2/2] mfd: atmel-flexcom: use resume_noirq
In-Reply-To: <20211028135138.3481166-3-claudiu.beznea@microchip.com>
References: <20211028135138.3481166-1-claudiu.beznea@microchip.com>
 <20211028135138.3481166-3-claudiu.beznea@microchip.com>
Message-ID: <YdxS5NaIWLviZUc0@google.com>

On Thu, 28 Oct 2021, Claudiu Beznea wrote:

> Flexcom IP embeds 3 other IPs: usart, i2c, spi and selects the operation
> mode (usart, i2c, spi) via mode register (FLEX_MR). On i2c bus there might
> be connected critical devices (like PMIC) which on suspend/resume should
> be suspended/resumed at the end/beginning. i2c uses
> .suspend_noirq/.resume_noirq for this kind of purposes. Align flexcom
> to use .resume_noirq as it should be resumed before the embedded IPs.
> Otherwise the embedded devices might behave badly.
> 
> Fixes: 7fdec11015c3 ("atmel_flexcom: Support resuming after a chip reset")
> Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
> Tested-by: Codrin Ciubotariu <codrin.ciubotariu at microchip.com>
> Acked-by: Nicolas Ferre <nicolas.ferre at microchip.com>
> ---
>  drivers/mfd/atmel-flexcom.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c
> index 962f66dc8813..559eb4d352b6 100644
> --- a/drivers/mfd/atmel-flexcom.c
> +++ b/drivers/mfd/atmel-flexcom.c
> @@ -87,7 +87,7 @@ static const struct of_device_id atmel_flexcom_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match);
>  
> -static int __maybe_unused atmel_flexcom_resume(struct device *dev)
> +static int __maybe_unused atmel_flexcom_resume_noirq(struct device *dev)
>  {
>  	struct atmel_flexcom *ddata = dev_get_drvdata(dev);
>  	int err;
> @@ -105,8 +105,9 @@ static int __maybe_unused atmel_flexcom_resume(struct device *dev)
>  	return 0;
>  }
>  
> -static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL,
> -			 atmel_flexcom_resume);
> +static const struct dev_pm_ops atmel_flexcom_pm_ops = {
> +	.resume_noirq = atmel_flexcom_resume_noirq,

Doesn't this mean you can remove __maybe_unused?

> +};
>  
>  static struct platform_driver atmel_flexcom_driver = {
>  	.probe	= atmel_flexcom_probe,

-- 
Lee Jones [???]
Principal Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From mhocko at suse.com  Mon Jan 10 07:39:51 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 16:39:51 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdiKVJlClB3h1Kmg@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>
 <YdiKVJlClB3h1Kmg@google.com>
Message-ID: <YdxTR4+FL08XyFuO@dhcp22.suse.cz>

On Fri 07-01-22 11:45:40, Yu Zhao wrote:
[...]
> Next, I argue that the benefits of this patchset outweigh its risks,
> because, drawing from my past experience,
> 1. There have been many larger and/or riskier patchsets taken; I'll
>    assemble a list if you disagree.

No question about that. Changes in the reclaim path are paved with
failures and reverts and fine tuning on top of existing fine tuning.
The difference from your patchset is that they tend to be much much
smaller and go incremental and therefore easier to review.

>    And this patchset is fully guarded
>    by #ifdef; Linus has also assessed on this point.

I appreciate you made the new behavior an opt-in and therefore existing
workloads are less likely to regress. I do not think ifdefs help
all that much, though, because a) realistically the config will
likely be enabled for most distribution kernels and b) the parallel
reclaim implementation adds a maintenance overhead regardless of those
ifdef. The later point is especially worrying because the memory reclaim
is a complex and hard to review beast already. Any future changes would
need to consider both reclaim algorithms of course.

Hence I argue we really need a wider consensus this is the right
direction we want to pursue.

> 2. There have been none that came with the testing/benchmarking
>    coverage as this one did. Please point me to some if I'm mistaken,
>    and I'll gladly match them.

I do appreciate your numbers but you should realize that this is an area
that is really hard to get any conclusive testing for. We keep learning
about fallouts on workloads we haven't really anticipated or where the
runtime effects happen to disagree with our intuition. So while those
numbers are nice there are other important aspects to consider like the
maintenance cost for example.

> The numbers might not materialize in the real world; the code is not
> perfect; and many other risks... But all the top eight open source
> memory hogs were covered, which is unprecedented; memcached and fio
> showed significant improvements and it only takes a few commands to
> see for yourselves.
> 
> Regarding the acks and the reviewed-bys, I certainly can ask people
> who have reaped the benefits of this patchset to do them, if it's
> required. But I see less fun in that. I prefer to provide empirical
> evidence and convince people who are on the other side of the aisle.

I like to hear from users who benefit from your work and that certainly
gives more credit to it. But it will be the MM community to maintain the
code and address future issues.

We do not have a dedicated maintainer for the memory reclaim but
certainly there are people who have helped shaping the existing code and
have learned a lot from the past issues - like Johannes, Rik, Mel just
to name few. If I were you I would be really looking into finding an
agreement with them. I myself can help you with memcg and oom side of
the things (we already have discussions about those).

Thanks!
-- 
Michal Hocko
SUSE Labs


From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:15 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:15 +0100
Subject: [v1 16/16] clk: mediatek: Add MT8186 ipesys clock support
In-Reply-To: <20220110134416.5191-17-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-17-chun-jie.chen@mediatek.com>
Message-ID: <ac78fbe2-cb96-5426-8281-3730f2114214@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 ipesys clock controller which provides clock gate
> control for Image Process Engine.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:19 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:19 +0100
Subject: [v1 14/16] clk: mediatek: Add MT8186 camsys clock support
In-Reply-To: <20220110134416.5191-15-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-15-chun-jie.chen@mediatek.com>
Message-ID: <271644d2-e2e6-977f-c7da-173f072a3ce8@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 camsys clock controllers which provide clock gate
> control for camera IP blocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:24 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:24 +0100
Subject: [v1 15/16] clk: mediatek: Add MT8186 mdpsys clock support
In-Reply-To: <20220110134416.5191-16-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-16-chun-jie.chen@mediatek.com>
Message-ID: <da97ff55-afb4-4912-5346-76c7426a64d9@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 mdpsys clock controller which provides clock gate
> control in Multimedia Data Path.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:30 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:30 +0100
Subject: [v1 13/16] clk: mediatek: Add MT8186 vencsys clock support
In-Reply-To: <20220110134416.5191-14-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-14-chun-jie.chen@mediatek.com>
Message-ID: <159e2406-4f1b-9ade-8daa-51d8eb055394@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 vencsys clock controller which provide clock gate
> control for video encoder.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:37 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:37 +0100
Subject: [v1 12/16] clk: mediatek: Add MT8186 vdecsys clock support
In-Reply-To: <20220110134416.5191-13-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-13-chun-jie.chen@mediatek.com>
Message-ID: <1d2d5aed-1b4d-2800-85ff-d9a0887d3263@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 vdec clock controller which provide clock gate
> control for video decoder.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:49:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:49:44 +0100
Subject: [v1 11/16] clk: mediatek: Add MT8186 imgsys clock support
In-Reply-To: <20220110134416.5191-12-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-12-chun-jie.chen@mediatek.com>
Message-ID: <81447fb8-eedc-d51f-a697-a631cadb8aaa@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 imgsys clock controllers which provide clock gate
> control for image IP blocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:00 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:00 +0100
Subject: [v1 10/16] clk: mediatek: Add MT8186 wpesys clock support
In-Reply-To: <20220110134416.5191-11-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-11-chun-jie.chen@mediatek.com>
Message-ID: <26f4a15b-423c-ebc4-b50a-038cfb4b42fb@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 wpesys clock controllers which provide clock gate
> control in Wrapping Engine.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:11 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:11 +0100
Subject: [v1 09/16] clk: mediatek: Add MT8186 mmsys clock support
In-Reply-To: <20220110134416.5191-10-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-10-chun-jie.chen@mediatek.com>
Message-ID: <503854db-055a-0f17-ae4e-7ca259f5d655@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 mmsys clock controller which provides clock gate
> control in video system. This is integrated with mtk-mmsys
> driver which will populate device by platform_device_register_data
> to start mmsys clock driver.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:19 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:19 +0100
Subject: [v1 08/16] clk: mediatek: Add MT8186 mfgsys clock support
In-Reply-To: <20220110134416.5191-9-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-9-chun-jie.chen@mediatek.com>
Message-ID: <7781382e-023d-89d2-50a2-37b9711889fe@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 mfg clock controller which provides clock gate
> control for GPU.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:29 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:29 +0100
Subject: [v1 07/16] clk: mediatek: Add MT8186 imp i2c wrapper clock support
In-Reply-To: <20220110134416.5191-8-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-8-chun-jie.chen@mediatek.com>
Message-ID: <9233bc50-b377-c16d-2d03-a71770de0973@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 imp i2c wrapper clock controllers which provide clock gate
> control in i2c IP blocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:38 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:38 +0100
Subject: [v1 06/16] clk: mediatek: Add MT8186 apmixedsys clock support
In-Reply-To: <20220110134416.5191-7-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-7-chun-jie.chen@mediatek.com>
Message-ID: <9f15a4ea-9a45-9c8c-92c8-401144bab929@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 apmixedsys clock controller which provides Plls
> generated from SoC.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:49 +0100
Subject: [v1 05/16] clk: mediatek: Add MT8186 infrastructure clock support
In-Reply-To: <20220110134416.5191-6-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-6-chun-jie.chen@mediatek.com>
Message-ID: <993b0a1b-c78f-2a50-a9e8-fc4ba639b25c@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 infrastructure clock controller which provides
> clock gate control for basic IP like pwm, uart, spi and so on.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:50:57 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:50:57 +0100
Subject: [v1 04/16] clk: mediatek: Add MT8186 topckgen clock support
In-Reply-To: <20220110134416.5191-5-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-5-chun-jie.chen@mediatek.com>
Message-ID: <2e0762b9-aea3-dda2-8d55-b9a2232d676f@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 topckgen clock controller which provides muxes, dividers
> to handle variety clock selection in other IP blocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:51:02 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:51:02 +0100
Subject: [v1 03/16] clk: mediatek: Add MT8186 mcusys clock support
In-Reply-To: <20220110134416.5191-4-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-4-chun-jie.chen@mediatek.com>
Message-ID: <9f60fb73-0983-8c7f-f96b-ea625f644ea7@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 mcusys clock controller which provides muxes
> to select the clock source of APMCU.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From krzysztof.kozlowski at canonical.com  Mon Jan 10 07:52:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 10 Jan 2022 16:52:02 +0100
Subject: [PATCH 2/2] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <YdR6BsyVaBnnFz7x@robh.at.kernel.org>
References: <20220102155807.42758-1-krzysztof.kozlowski@canonical.com>
 <20220102155807.42758-2-krzysztof.kozlowski@canonical.com>
 <YdR6BsyVaBnnFz7x@robh.at.kernel.org>
Message-ID: <4c92afa7-53e2-0243-e6b5-3e594cc6b2ca@canonical.com>

On 04/01/2022 17:47, Rob Herring wrote:
> On Sun, Jan 02, 2022 at 04:58:07PM +0100, Krzysztof Kozlowski wrote:
>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
>> controller bindings to DT schema format
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 220 ++++++++++++++++++
>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ----------
>>  MAINTAINERS                                   |   2 +-
>>  3 files changed, 221 insertions(+), 123 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>>
>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> new file mode 100644
>> index 000000000000..195bfafe05fd
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> @@ -0,0 +1,220 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung S3C/S5P/Exynos SoC SPI controller
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description:
>> +  All the SPI controller nodes should be represented in the aliases node using
>> +  the following format 'spi{n}' where n is a unique number for the alias.
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - enum:
>> +          - samsung,s3c2443-spi
>> +          - samsung,s3c6410-spi
>> +          - samsung,s5pv210-spi
>> +          - samsung,exynos5433-spi
>> +      - const: samsung,exynos7-spi
>> +        deprecated: true
>> +
>> +  clocks:
>> +    minItems: 2
>> +    maxItems: 3
>> +
>> +  clock-names:
>> +    minItems: 2
>> +    maxItems: 3
>> +
>> +  cs-gpios: true
>> +
>> +  dmas:
>> +    minItems: 2
>> +    maxItems: 2
>> +
>> +  dma-names:
>> +    items:
>> +      - const: tx
>> +      - const: rx
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  no-cs-readback:
>> +    description:
>> +      The CS line is disconnected, therefore the device should not operate
>> +      based on CS signalling.
>> +    type: boolean
>> +
>> +  num-cs:
>> +    minimum: 1
>> +    maximum: 4
>> +    default: 1
>> +
>> +  samsung,spi-src-clk:
>> +    description:
>> +      If the spi controller includes a internal clock mux to select the clock
>> +      source for the spi bus clock, this property can be used to indicate the
>> +      clock to be used for driving the spi bus clock. If not specified, the
>> +      clock number 0 is used as default.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    default: 0
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +patternProperties:
>> +  "^.*@[0-9a-f]+$":
>> +    type: object
>> +
>> +    allOf:
>> +      - $ref: spi-peripheral-props.yaml
>> +
>> +    properties:
>> +      controller-data:
>> +        type: object
>> +        additionalProperties: false
>> +
>> +        properties:
>> +          samsung,spi-feedback-delay:
> 
> All this has to go in it's own schema which then needs to be added to 
> spi-peripheral-props.yaml.

OK

> 
>> +            description: |
>> +              The sampling phase shift to be applied on the miso line (to account
>> +              for any lag in the miso line). Valid values:
>> +               - 0: No phase shift.
>> +               - 1: 90 degree phase shift sampling.
>> +               - 2: 180 degree phase shift sampling.
>> +               - 3: 270 degree phase shift sampling.
>> +            $ref: /schemas/types.yaml#/definitions/uint32
>> +            enum: [0, 1, 2, 3]
>> +
>> +        required:
>> +          - samsung,spi-feedback-delay
>> +
>> +    required:
>> +      - controller-data
> 
> Not really great that this is required and there's not some default that 
> works.

I can make it optional with new kernel. I'll send a follow up patch for
this.

> 
>> +
>> +    unevaluatedProperties: false
>> +
>> +required:
>> +  - compatible
>> +  - clocks
>> +  - clock-names
>> +  - dmas
>> +  - dma-names
>> +  - interrupts
>> +  - reg
>> +
>> +allOf:
>> +  - $ref: spi-controller.yaml#
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: samsung,exynos5433-spi
>> +    then:
>> +      properties:
>> +        clocks:
>> +          minItems: 3
>> +          maxItems: 3
>> +        clock-names:
>> +          items:
>> +            - const: spi
>> +            - enum:
>> +                - spi_busclk0
>> +                - spi_busclk1
>> +                - spi_busclk2
>> +                - spi_busclk3
>> +            - const: spi_ioclk
>> +    else:
>> +      properties:
>> +        clocks:
>> +          minItems: 2
>> +          maxItems: 2
>> +        clock-names:
>> +          items:
>> +            - const: spi
>> +            - enum:
>> +                - spi_busclk0
>> +                - spi_busclk1
>> +                - spi_busclk2
>> +                - spi_busclk3
>> +
>> +unevaluatedProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/exynos5433.h>
>> +    #include <dt-bindings/clock/samsung,s2mps11.h>
>> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
>> +    #include <dt-bindings/gpio/gpio.h>
>> +
>> +    spi at 14d30000 {
>> +        compatible = "samsung,exynos5433-spi";
>> +        reg = <0x14d30000 0x100>;
>> +        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
>> +        dmas = <&pdma0 11>, <&pdma0 10>;
>> +        dma-names = "tx", "rx";
>> +        #address-cells = <1>;
>> +        #size-cells = <0>;
>> +        clocks = <&cmu_peric CLK_PCLK_SPI1>,
>> +                 <&cmu_peric CLK_SCLK_SPI1>,
>> +                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
>> +        clock-names = "spi",
>> +                      "spi_busclk0",
>> +                      "spi_ioclk";
>> +        samsung,spi-src-clk = <0>;
>> +        pinctrl-names = "default";
>> +        pinctrl-0 = <&spi1_bus>;
>> +        num-cs = <1>;
>> +
>> +        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
>> +        status = "okay";
> 
> Don't need 'status' in examples.

Sure

> 
>> +        audio-codec at 0 {
>> +            compatible = "wlf,wm5110";
>> +            reg = <0x0>;
>> +            spi-max-frequency = <20000000>;
>> +            interrupt-parent = <&gpa0>;
>> +            interrupts = <4 IRQ_TYPE_NONE>;
>> +            clocks = <&pmu_system_controller 0>,
>> +                     <&s2mps13_osc S2MPS11_CLK_BT>;
>> +            clock-names = "mclk1", "mclk2";
>> +
>> +            gpio-controller;
>> +            #gpio-cells = <2>;
>> +            interrupt-controller;
>> +            #interrupt-cells = <2>;
>> +
>> +            wlf,micd-detect-debounce = <300>;
>> +            wlf,micd-bias-start-time = <0x1>;
>> +            wlf,micd-rate = <0x7>;
>> +            wlf,micd-dbtime = <0x2>;
>> +            wlf,micd-force-micbias;
>> +            wlf,micd-configs = <0x0 1 0>;
>> +            wlf,hpdet-channel = <1>;
>> +            wlf,gpsw = <0x1>;
>> +            wlf,inmode = <2 0 2 0>;
>> +
>> +            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
>> +            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
>> +
>> +            /* core supplies */
>> +            AVDD-supply = <&ldo18_reg>;
>> +            DBVDD1-supply = <&ldo18_reg>;
>> +            CPVDD-supply = <&ldo18_reg>;
>> +            DBVDD2-supply = <&ldo18_reg>;
>> +            DBVDD3-supply = <&ldo18_reg>;
>> +            SPKVDDL-supply = <&ldo18_reg>;
>> +            SPKVDDR-supply = <&ldo18_reg>;
>> +
>> +            controller-data {
> 
> The schema didn't get checked since spi-peripheral-props.yaml isn't 
> yet in my tree, but I'd expect this to be a warning. If not its schema 
> needs to be a bit stricter. The schema for "wlf,wm5110" will need to 
> reference spi-peripheral-props.yaml. (Actually, all SPI peripheral 
> device schemas will need a reference in theory, but really we only care 
> for devices used with controllers with extra properties). 

I did not see any warnings. I'll modify the wm5110.


Best regards,
Krzysztof


From angelogioacchino.delregno at collabora.com  Mon Jan 10 07:52:30 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 10 Jan 2022 16:52:30 +0100
Subject: [v1 02/16] clk: mediatek: Add dt-bindings of MT8186 clocks
In-Reply-To: <20220110134416.5191-3-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-3-chun-jie.chen@mediatek.com>
Message-ID: <1254b48a-8aca-b791-a352-3aad9135d0b0@collabora.com>

Il 10/01/22 14:44, Chun-Jie Chen ha scritto:
> Add MT8186 clock dt-bindings, includes topckgen, apmixedsys,
> infracfg_ao, mcusys and subsystem clocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>

Hello Chun-Jie,

I think that this patch should be squashed with patch 01/16, as this
is dt-bindings as much as the yaml that you're introducing.

Regards,
- Angelo


From christophe.leroy at csgroup.eu  Mon Jan 10 07:56:19 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Mon, 10 Jan 2022 15:56:19 +0000
Subject: [PATCH V2 03/17] asm-generic: fcntl: compat: Remove duplicate
 definitions
In-Reply-To: <20211228143958.3409187-4-guoren@kernel.org>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-4-guoren@kernel.org>
Message-ID: <d64c8b66-c5bc-81a1-55c6-a0b44cafb19a@csgroup.eu>



Le 28/12/2021 ? 15:39, guoren at kernel.org a ?crit?:
> From: Guo Ren <guoren at linux.alibaba.com>
> 
> Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
> arch/*/include/asm/compat.h.
> 
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>
> ---
>   arch/arm64/include/asm/compat.h   | 4 ----
>   arch/powerpc/include/asm/compat.h | 4 ----
>   arch/s390/include/asm/compat.h    | 4 ----
>   arch/sparc/include/asm/compat.h   | 4 ----
>   arch/x86/include/asm/compat.h     | 4 ----
>   include/uapi/asm-generic/fcntl.h  | 2 +-
>   6 files changed, 1 insertion(+), 21 deletions(-)
> 

...

> diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
> index ecd0f5bdfc1d..5bc1e51d73b1 100644
> --- a/include/uapi/asm-generic/fcntl.h
> +++ b/include/uapi/asm-generic/fcntl.h
> @@ -116,7 +116,7 @@
>   #define F_GETSIG	11	/* for sockets. */
>   #endif
>   
> -#ifndef CONFIG_64BIT
> +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
>   #ifndef F_GETLK64
>   #define F_GETLK64	12	/*  using 'struct flock64' */
>   #define F_SETLK64	13

There seems to be a problem with this change:

error: /linux/include/uapi/asm-generic/fcntl.h: leak CONFIG_COMPAT to 
user-space
make[3]: *** [/linux/scripts/Makefile.headersinst:63: 
usr/include/asm-generic/fcntl.h] Error 1
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [/linux/Makefile:1283: headers] Error 2
make[1]: *** [Makefile:219: __sub-make] Error 2
make[2]: Leaving directory '/output'
make[1]: Leaving directory '/linux'
make: *** [Makefile:157: khdr] Error 2
make: Leaving directory '/linux/tools/testing/selftests'
## Selftest build completed rc = 2
## Found 2 binaries
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Error build failed rc 2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Error: Process completed with exit code 2.

From vbabka at suse.cz  Mon Jan 10 08:01:07 2022
From: vbabka at suse.cz (Vlastimil Babka)
Date: Mon, 10 Jan 2022 17:01:07 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdxKORU9OWCv114O@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <YdxKORU9OWCv114O@dhcp22.suse.cz>
Message-ID: <8edfd643-888b-fbe6-97c0-21f900767c27@suse.cz>

On 1/10/22 16:01, Michal Hocko wrote:
> On Thu 06-01-22 17:12:18, Michal Hocko wrote:
>> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
>> > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
>> > +{
>> > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
>> > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> 
> One thing I have overlooked completely. You cannot really use GFP_KERNEL
> allocation here because the reclaim context can be constrained (e.g.
> GFP_NOFS). This allocation will not do any reclaim as it is PF_MEMALLOC
> but I suspect that the lockdep will complain anyway.
> 
> Also kvmalloc is not really great here. a) vmalloc path is never
> executed for small objects and b) we do not really want to make a
> dependency between vmalloc and the reclaim (by vmalloc -> reclaim ->
> vmalloc).
> 
> Even if we rule out vmalloc and look at kmalloc alone. Is this really
> safe? I do not see any recursion prevention in the SL.B code. Maybe this
> just happens to work but the dependency should be really documented so
> that future SL.B changes won't break the whole scheme. 

Slab implementations drop all locks before calling into page allocator (thus
possibly reclaim) so slab itself should be fine and I don't expect it to
change. But we could eventually reach the page allocator recursively again,
that's true and not great.


From amelie.delaunay at foss.st.com  Mon Jan 10 08:11:00 2022
From: amelie.delaunay at foss.st.com (Amelie DELAUNAY)
Date: Mon, 10 Jan 2022 17:11:00 +0100
Subject: [Linux-stm32] [PATCH] dmaengine: stm32-dmamux: Fix PM disable
 depth imbalance in stm32_dmamux_probe
In-Reply-To: <20220108085336.11992-1-linmq006@gmail.com>
References: <20220108085336.11992-1-linmq006@gmail.com>
Message-ID: <37a66156-a616-058d-b3c0-6d2ca22a12ed@foss.st.com>

On 1/8/22 9:53 AM, Miaoqian Lin wrote:
> The pm_runtime_enable will increase power disable depth.
> If the probe fails, we should use pm_runtime_disable() to balance
> pm_runtime_enable().
> 
> Fixes: 4f3ceca254e0 ("dmaengine: stm32-dmamux: Add PM Runtime support")
> Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>

Thanks for your patch,

Reviewed-by: Amelie Delaunay <amelie.delaunay at foss.st.com>

> ---
>   drivers/dma/stm32-dmamux.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/dma/stm32-dmamux.c b/drivers/dma/stm32-dmamux.c
> index a42164389ebc..d5d55732adba 100644
> --- a/drivers/dma/stm32-dmamux.c
> +++ b/drivers/dma/stm32-dmamux.c
> @@ -292,10 +292,12 @@ static int stm32_dmamux_probe(struct platform_device *pdev)
>   	ret = of_dma_router_register(node, stm32_dmamux_route_allocate,
>   				     &stm32_dmamux->dmarouter);
>   	if (ret)
> -		goto err_clk;
> +		goto pm_disable;
>   
>   	return 0;
>   
> +pm_disable:
> +	pm_runtime_disable(&pdev->dev);
>   err_clk:
>   	clk_disable_unprepare(stm32_dmamux->clk);
>   
> 


From robh+dt at kernel.org  Mon Jan 10 08:18:02 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 10:18:02 -0600
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <20220110104214.25321-2-yu.tu@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-2-yu.tu@amlogic.com>
Message-ID: <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>

On Mon, Jan 10, 2022 at 4:42 AM Yu Tu <yu.tu at amlogic.com> wrote:
>
> Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
> compatible. Don't differentiate between GXBB, GXL and G12A which
> have different revisions of the UART IP. So it's split into
> GXBB,GXL and G12A.

You are breaking compatibility. If your dts is updated to use the new
compatible, then a kernel without the change will not work anymore. It
worked before without understanding the changes you are making. It
should continue to. A compatible value like this would accomplish what
you want:

"amlogic,meson-gxbb-uart", "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"

A new kernel will match on "amlogic,meson-gxbb-uart" or
"amlogic,meson-gx-uart" depending if the dtb is updated or not. An old
kernel will continue to match on "amlogic,meson-gx-uart".

If you are going to go breaking things, the power domain distinction
in the compatible is odd...


Rob


From mhocko at suse.com  Mon Jan 10 08:25:15 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 17:25:15 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <8edfd643-888b-fbe6-97c0-21f900767c27@suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <YdxKORU9OWCv114O@dhcp22.suse.cz>
 <8edfd643-888b-fbe6-97c0-21f900767c27@suse.cz>
Message-ID: <Ydxd6zHs2uR5mNnn@dhcp22.suse.cz>

On Mon 10-01-22 17:01:07, Vlastimil Babka wrote:
> On 1/10/22 16:01, Michal Hocko wrote:
> > On Thu 06-01-22 17:12:18, Michal Hocko wrote:
> >> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> >> > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> >> > +{
> >> > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> >> > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> > 
> > One thing I have overlooked completely. You cannot really use GFP_KERNEL
> > allocation here because the reclaim context can be constrained (e.g.
> > GFP_NOFS). This allocation will not do any reclaim as it is PF_MEMALLOC
> > but I suspect that the lockdep will complain anyway.
> > 
> > Also kvmalloc is not really great here. a) vmalloc path is never
> > executed for small objects and b) we do not really want to make a
> > dependency between vmalloc and the reclaim (by vmalloc -> reclaim ->
> > vmalloc).
> > 
> > Even if we rule out vmalloc and look at kmalloc alone. Is this really
> > safe? I do not see any recursion prevention in the SL.B code. Maybe this
> > just happens to work but the dependency should be really documented so
> > that future SL.B changes won't break the whole scheme. 
> 
> Slab implementations drop all locks before calling into page allocator (thus
> possibly reclaim) so slab itself should be fine and I don't expect it to
> change. But we could eventually reach the page allocator recursively again,
> that's true and not great.

Thanks for double checking. If recursion is really intended and
something SL.B allocators should support then this is definitely worth
documenting so that a subtle change won't break in the future. 

-- 
Michal Hocko
SUSE Labs


From hch at infradead.org  Mon Jan 10 08:30:16 2022
From: hch at infradead.org (Christoph Hellwig)
Date: Mon, 10 Jan 2022 08:30:16 -0800
Subject: [PATCH V2 03/17] asm-generic: fcntl: compat: Remove duplicate
 definitions
In-Reply-To: <CAK8P3a2zn9M6X09WsjJ9HYiS9WnO_YPCvJLSBk+HaH+yZHQqfA@mail.gmail.com>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-4-guoren@kernel.org>
 <CAK8P3a2zn9M6X09WsjJ9HYiS9WnO_YPCvJLSBk+HaH+yZHQqfA@mail.gmail.com>
Message-ID: <YdxfGMDJh2ZVq8jc@infradead.org>

On Mon, Jan 10, 2022 at 02:35:19PM +0100, Arnd Bergmann wrote:
> > +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> >  #ifndef F_GETLK64
> >  #define F_GETLK64      12      /*  using 'struct flock64' */
> >  #define F_SETLK64      13
> 
> The problem here is that include/uapi/ headers cannot contain checks for
> CONFIG_* symbols because those may have different meanings in user space
> compared to kernel.
> 
> This is a preexisting problem in the header, but I think the change
> makes it worse.

FYI, this is what I did in my old branch, which also sidesteps the
duplicate value problem on parisc. The rebase is untested so far,
but I can spend some cycles on finishing it:

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/fcntl-asm-generic-cleanup


From robh at kernel.org  Mon Jan 10 08:48:59 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 10:48:59 -0600
Subject: [PATCH 1/2] dt-bindings: remoteproc: k3-m4f: Add bindings for K3
 AM64x SoCs
In-Reply-To: <20220110040650.18186-2-hnagalla@ti.com>
References: <20220110040650.18186-1-hnagalla@ti.com>
 <20220110040650.18186-2-hnagalla@ti.com>
Message-ID: <1641833339.676351.1067450.nullmailer@robh.at.kernel.org>

On Sun, 09 Jan 2022 22:06:49 -0600, Hari Nagalla wrote:
> K3 AM64x SoC has a Cortex M4F subsystem in the MCU volatge domain.
> The remote processor's life cycle management and IPC mechanisms are
> similar across the R5F and M4F cores from remote processor driver
> point of view. However, there are subtle differences in image loading
> and starting the M4F subsystems.
> 
> The YAML binding document provides the various node properties to be
> configured by the consumers of the M4F subsystem.
> 
> Signed-off-by: Hari Nagalla <hnagalla at ti.com>
> ---
>  .../bindings/remoteproc/ti,k3-m4f-rproc.yaml  | 121 ++++++++++++++++++
>  1 file changed, 121 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml: properties:memory-region: 'anyOf' conditional failed, one must be fixed:
	'minItems' is not one of ['maxItems', 'description', 'deprecated']
		hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
	'additionalItems' is not one of ['maxItems', 'description', 'deprecated']
		hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
	'unevaluatedProperties' is not one of ['maxItems', 'description', 'deprecated']
		hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
	Additional properties are not allowed ('unevaluatedProperties' was unexpected)
		hint: Arrays must be described with a combination of minItems/maxItems/items
	'minItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref']
	'maxItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref']
	'additionalItems' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref']
	'unevaluatedProperties' is not one of ['description', 'deprecated', 'const', 'enum', 'minimum', 'maximum', 'multipleOf', 'default', '$ref']
	1 was expected
		hint: Only "maxItems" is required for a single entry if there are no constraints defined for the values.
	hint: cell array properties must define how many entries and what the entries are when there is more than one entry.
	from schema $id: http://devicetree.org/meta-schemas/core.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.yaml: ignoring, error in schema: properties: memory-region
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.example.dts:19.31-36.11: Warning (unit_address_vs_reg): /example-0/bus at f4000: node has a unit name, but no reg or ranges property
Documentation/devicetree/bindings/remoteproc/ti,k3-m4f-rproc.example.dt.yaml:0:0: /example-0/bus at f4000/m4fss at 5000000: failed to match any schema with compatible: ['ti,am64-m4fss']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1577759

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Jan 10 08:48:59 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 10:48:59 -0600
Subject: [PATCH 1/2] dt-bindings: spi: Convert spi-mt65xx &
 spi-slave-mt27xx to json-schema
In-Reply-To: <20220110053744.30323-1-leilk.liu@mediatek.com>
References: <20220110053744.30323-1-leilk.liu@mediatek.com>
Message-ID: <1641833339.690847.1067453.nullmailer@robh.at.kernel.org>

On Mon, 10 Jan 2022 13:37:43 +0800, Leilk Liu wrote:
> Convert Mediatek ARM SOC's SPI Master & Slave controller binding
> to json-schema format.
> 
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
>  .../bindings/spi/mediatek,spi-mt65xx.yaml     | 96 +++++++++++++++++++
>  .../spi/mediatek,spi-slave-mt27xx.yaml        | 69 +++++++++++++
>  .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
>  .../bindings/spi/spi-slave-mt27xx.txt         | 33 -------
>  4 files changed, 165 insertions(+), 101 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
>  create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml: properties:compatible:oneOf: [{'const': 'mediatek,mt2712-spi-slave'}, {'const': 'mediatek,mt8195-spi-slave'}] should not be valid under {'items': {'propertyNames': {'const': 'const'}, 'required': ['const']}}
	hint: Use 'enum' rather than 'oneOf' + 'const' entries
	from schema $id: http://devicetree.org/meta-schemas/keywords.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml: ignoring, error in schema: properties: compatible: oneOf
Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.example.dt.yaml:0:0: /example-0/spi at 10013000: failed to match any schema with compatible: ['mediatek,mt2712-spi-slave']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1577767

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From foxhoundsk.tw at gmail.com  Mon Jan 10 08:51:14 2022
From: foxhoundsk.tw at gmail.com (Huichun Feng)
Date: Tue, 11 Jan 2022 00:51:14 +0800
Subject: Does clocksource arch_sys_counter synchronize across CPUs?
Message-ID: <CAFbkdV3KOGA863+TV9_uVWnmg75v-60R3qT0r-+LgQiyHM6BtA@mail.gmail.com>

Hi list,

AFAIK, one of the clocksource in arm64 (armv8.3, Rpi4) --
arch_sys_counter, uses a per-core register CNTVCT as the accessor.

And comes to consistency of CNTVCT's, after searching some of the
related manuals [0-2], I didn't find statements saying that it is
synchronize across CPUs. However, I've found a recent patch [3] says
that CNTVCT is synchronized in armv8.6.

So, does CNTVCT synchronize across CPUs in armv8.3?

thanks.
Huichun

[0] https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
[1] https://developer.arm.com/documentation/den0024/a/ARMv8-Registers/System-registers
[2] https://developer.arm.com/documentation/102379/0000/The-processor-timers?lang=en
[3] https://www.spinics.net/lists/arm-kernel/msg934605.html


From mhocko at suse.com  Mon Jan 10 08:57:39 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 10 Jan 2022 17:57:39 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <20220104202227.2903605-7-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
Message-ID: <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz>

On Tue 04-01-22 13:22:25, Yu Zhao wrote:
[...]
> +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> +{
> +	static const struct mm_walk_ops mm_walk_ops = {
> +		.test_walk = should_skip_vma,
> +		.p4d_entry = walk_pud_range,
> +	};
> +
> +	int err;
> +#ifdef CONFIG_MEMCG
> +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> +#endif
> +
> +	walk->next_addr = FIRST_USER_ADDRESS;
> +
> +	do {
> +		unsigned long start = walk->next_addr;
> +		unsigned long end = mm->highest_vm_end;
> +
> +		err = -EBUSY;
> +
> +		rcu_read_lock();
> +#ifdef CONFIG_MEMCG
> +		if (memcg && atomic_read(&memcg->moving_account))
> +			goto contended;
> +#endif

Why do you need to check for moving_account?
-- 
Michal Hocko
SUSE Labs


From john.garry at huawei.com  Mon Jan 10 09:00:27 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 17:00:27 +0000
Subject: [PATCH v4 01/48] libperf: Add comments to perf_cpu_map.
In-Reply-To: <20220105061351.120843-2-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-2-irogers@google.com>
Message-ID: <aea97c61-b684-3322-05a2-f55a7877e1b9@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
> A particular observed problem is confusing the index with the CPU value,
> documentation should hopefully reduce this type of problem.
> 
> Reviewed-by: James Clark<james.clark at arm.com>
> Signed-off-by: Ian Rogers<irogers at google.com>

Reviewed-by: John Garry <john.garry at huawei.com>


From linux at roeck-us.net  Mon Jan 10 09:01:48 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 10 Jan 2022 09:01:48 -0800
Subject: [PATCH v3] fsi: Aspeed: Fix a potential double free
In-Reply-To: <2c123f8b0a40dc1a061fae982169fe030b4f47e6.1641765339.git.christophe.jaillet@wanadoo.fr>
References: <2c123f8b0a40dc1a061fae982169fe030b4f47e6.1641765339.git.christophe.jaillet@wanadoo.fr>
Message-ID: <3c4ff68f-3686-bcc6-c370-0732860b4d80@roeck-us.net>

On 1/9/22 1:56 PM, Christophe JAILLET wrote:
> A struct device can never be devm_alloc()'ed.
> Here, it is embedded in "struct fsi_master", and "struct fsi_master" is
> embedded in "struct fsi_master_aspeed".
> 
> Since "struct device" is embedded, the data structure embedding it must be
> released with the release function, as is already done here.
> 
> So use kzalloc() instead of devm_kzalloc() when allocating "aspeed" and
> update all error handling branches accordingly.
> 
> This prevent a potential double free().
> 
> This also fix another issue if opb_readl() fails. Instead of a direct
> return, it now jumps in the error handling path.
> 
> Fixes: 606397d67f41 ("fsi: Add ast2600 master driver")
> Suggested-by: Greg KH <gregkh at linuxfoundation.org>
> Suggested-by: Guenter Roeck <linux at roeck-us.net>
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
> v2: Keep the release function which is correct
>      s/devm_kzalloc()/kzalloc()/ instead
> 
> v3: Update the error handling path to free "aspeed" [Guenter Roeck]
>      Fix another issue when opb_readl() fails [Guenter Roeck]
> 
> I hope that fixing both issues in the same patch is ok. It makes no sense
> to me not to update the goto to the correct label if opb_readl() fails.
> ---
>   drivers/fsi/fsi-master-aspeed.c | 17 +++++++++++------
>   1 file changed, 11 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
> index 8606e55c1721..0bed2fab8055 100644
> --- a/drivers/fsi/fsi-master-aspeed.c
> +++ b/drivers/fsi/fsi-master-aspeed.c
> @@ -542,25 +542,28 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
>   		return rc;
>   	}
>   
> -	aspeed = devm_kzalloc(&pdev->dev, sizeof(*aspeed), GFP_KERNEL);
> +	aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL);
>   	if (!aspeed)
>   		return -ENOMEM;
>   
>   	aspeed->dev = &pdev->dev;
>   
>   	aspeed->base = devm_platform_ioremap_resource(pdev, 0);
> -	if (IS_ERR(aspeed->base))
> -		return PTR_ERR(aspeed->base);
> +	if (IS_ERR(aspeed->base)) {
> +		rc = PTR_ERR(aspeed->base);
> +		goto err_free_aspeed;
> +	}
>   
>   	aspeed->clk = devm_clk_get(aspeed->dev, NULL);
>   	if (IS_ERR(aspeed->clk)) {
>   		dev_err(aspeed->dev, "couldn't get clock\n");
> -		return PTR_ERR(aspeed->clk);
> +		rc = PTR_ERR(aspeed->clk);
> +		goto err_free_aspeed;
>   	}
>   	rc = clk_prepare_enable(aspeed->clk);
>   	if (rc) {
>   		dev_err(aspeed->dev, "couldn't enable clock\n");
> -		return rc;
> +		goto err_free_aspeed;
>   	}
>   
>   	rc = setup_cfam_reset(aspeed);
> @@ -595,7 +598,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
>   	rc = opb_readl(aspeed, ctrl_base + FSI_MVER, &raw);
>   	if (rc) {
>   		dev_err(&pdev->dev, "failed to read hub version\n");
> -		return rc;
> +		goto err_release;
>   	}
>   
>   	reg = be32_to_cpu(raw);
> @@ -634,6 +637,8 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
>   
>   err_release:
>   	clk_disable_unprepare(aspeed->clk);
> +err_free_aspeed:
> +	kfree(aspeed);
>   	return rc;
>   }
>   
> 



From helgaas at kernel.org  Mon Jan 10 09:07:04 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 10 Jan 2022 11:07:04 -0600
Subject: [PATCH v2 01/23] PCI: aardvark: Replace custom PCIE_CORE_INT_*
 macros with PCI_INTERRUPT_*
In-Reply-To: <20220110015018.26359-2-kabel@kernel.org>
Message-ID: <20220110170704.GA60160@bhelgaas>

On Mon, Jan 10, 2022 at 02:49:56AM +0100, Marek Beh?n wrote:
> From: Pali Roh?r <pali at kernel.org>
> 
> Header file linux/pci.h defines enum pci_interrupt_pin with corresponding
> PCI_INTERRUPT_* values.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Signed-off-by: Marek Beh?n <kabel at kernel.org>

Reviewed-by: Bjorn Helgaas <bhelgaas at google.com>

Thanks!

> ---
>  drivers/pci/controller/pci-aardvark.c | 6 +-----
>  1 file changed, 1 insertion(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> index ec0df426863d..62baddd2ca95 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -39,10 +39,6 @@
>  #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN			BIT(6)
>  #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHCK			BIT(7)
>  #define     PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV			BIT(8)
> -#define     PCIE_CORE_INT_A_ASSERT_ENABLE			1
> -#define     PCIE_CORE_INT_B_ASSERT_ENABLE			2
> -#define     PCIE_CORE_INT_C_ASSERT_ENABLE			3
> -#define     PCIE_CORE_INT_D_ASSERT_ENABLE			4
>  /* PIO registers base address and register offsets */
>  #define PIO_BASE_ADDR				0x4000
>  #define PIO_CTRL				(PIO_BASE_ADDR + 0x0)
> @@ -968,7 +964,7 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
>  	bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64);
>  
>  	/* Support interrupt A for MSI feature */
> -	bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE;
> +	bridge->conf.intpin = PCI_INTERRUPT_INTA;
>  
>  	/* Aardvark HW provides PCIe Capability structure in version 2 */
>  	bridge->pcie_conf.cap = cpu_to_le16(2);
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From miles.chen at mediatek.com  Mon Jan 10 09:09:58 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 11 Jan 2022 01:09:58 +0800
Subject: [PATCH 2/3] clk: mediatek: clk-mt8192: drop CLK_OF_DECLARE_DRIVER
In-Reply-To: <20220110171000.24316-1-miles.chen@mediatek.com>
References: <20220110171000.24316-1-miles.chen@mediatek.com>
Message-ID: <20220110171000.24316-3-miles.chen@mediatek.com>

clk-mt8192.c uses CLK_OF_DECLARE_DRIVER and it does not work for
kernel modules.

To support clk-mt8192 moudle build, move the
clk_mt8192_top_init_early() logic to clk_mt8192_top_probe()
and drop clk_mt8192_top_init_early() and CLK_OF_DECLARE_DRIVER.

Cc: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Cc: Chen-Yu Tsai <wenst at chromium.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mt8192.c | 21 +++++----------------
 1 file changed, 5 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
index cbc7c6dbe0f4..552fae4f0fd5 100644
--- a/drivers/clk/mediatek/clk-mt8192.c
+++ b/drivers/clk/mediatek/clk-mt8192.c
@@ -1179,31 +1179,20 @@ static const struct mtk_pll_data plls[] = {
 
 static struct clk_onecell_data *top_clk_data;
 
-static void clk_mt8192_top_init_early(struct device_node *node)
+static int clk_mt8192_top_probe(struct platform_device *pdev)
 {
+	struct device_node *node = pdev->dev.of_node;
+	int r;
+	void __iomem *base;
 	int i;
 
 	top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
 	if (!top_clk_data)
-		return;
+		return -ENOMEM;
 
 	for (i = 0; i < CLK_TOP_NR_CLK; i++)
 		top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
 
-	mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs), top_clk_data);
-
-	of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
-}
-
-CLK_OF_DECLARE_DRIVER(mt8192_topckgen, "mediatek,mt8192-topckgen",
-		      clk_mt8192_top_init_early);
-
-static int clk_mt8192_top_probe(struct platform_device *pdev)
-{
-	struct device_node *node = pdev->dev.of_node;
-	int r;
-	void __iomem *base;
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
-- 
2.18.0



From miles.chen at mediatek.com  Mon Jan 10 09:09:56 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 11 Jan 2022 01:09:56 +0800
Subject: clk: mediatek: support COMMON_CLK_MT8192 module build
Message-ID: <20220110171000.24316-1-miles.chen@mediatek.com>

This patch set supports COMMON_CLK_MT8192 module build.
Boot-up tested with builtin and module build:

load test:
clk_mt8192_venc 16384 0 - Live 0xffff800008ff7000
clk_mt8192_vdec 16384 0 - Live 0xffff800008fef000
clk_mt8192_scp_adsp 16384 0 - Live 0xffff800008fe7000
clk_mt8192_msdc 16384 0 - Live 0xffff800008fdf000
clk_mt8192_mm 16384 0 - Live 0xffff800008fda000
clk_mt8192_mfg 16384 0 - Live 0xffff800008fd5000
clk_mt8192_mdp 16384 0 - Live 0xffff800008fd0000
clk_mt8192_ipe 16384 0 - Live 0xffff800008fcb000
clk_mt8192_imp_iic_wrap 16384 0 - Live 0xffff800008fc6000
clk_mt8192_img 16384 0 - Live 0xffff800008fc1000
clk_mt8192_cam 16384 0 - Live 0xffff800008fbc000
clk_mt8192_aud 16384 0 - Live 0xffff800008fb7000
clk_mt8192 40960 0 [permanent], Live 0xffff800008fa8000     





From miles.chen at mediatek.com  Mon Jan 10 09:09:57 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 11 Jan 2022 01:09:57 +0800
Subject: [PATCH 1/3] clk: mediatek: export mtk_clk_simple_probe
In-Reply-To: <20220110171000.24316-1-miles.chen@mediatek.com>
References: <20220110171000.24316-1-miles.chen@mediatek.com>
Message-ID: <20220110171000.24316-2-miles.chen@mediatek.com>

Export mtk_clk_simple_probe() to support mt8192 module build.

Cc: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Cc: Chen-Yu Tsai <wenst at chromium.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 8d5791b3f460..807dea08d7de 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -332,5 +332,6 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 	mtk_free_clk_data(clk_data);
 	return r;
 }
+EXPORT_SYMBOL_GPL(mtk_clk_simple_probe);
 
 MODULE_LICENSE("GPL");
-- 
2.18.0



From john.garry at huawei.com  Mon Jan 10 09:10:04 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 17:10:04 +0000
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <20220105061351.120843-3-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
Message-ID: <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
>   
> +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> +				       void *data)
> +{
> +	if (idx < 0 || idx > map->nr)
> +		return cpu_map__empty_aggr_cpu_id();
> +
> +	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> +}
> +


This is later deleted in the series. Can the series be reworked so that 
we don't add stuff and then later delete it? One reason for that 
approach is that we don't spend time reviewing something which will be 
deleted, especially in such a big series...

If it really makes sense to do it this way then fine.

Thanks,
John


From miles.chen at mediatek.com  Mon Jan 10 09:09:59 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 11 Jan 2022 01:09:59 +0800
Subject: [PATCH 3/3] clk: mediatek: support COMMON_CLK_MT8192 module build
In-Reply-To: <20220110171000.24316-1-miles.chen@mediatek.com>
References: <20220110171000.24316-1-miles.chen@mediatek.com>
Message-ID: <20220110171000.24316-4-miles.chen@mediatek.com>

To support COMMON_CLK_MT8192* module build,
add MODULE_LICENSE and include module.h.

Cc: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Cc: Chen-Yu Tsai <wenst at chromium.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/Kconfig                  | 26 +++++++++----------
 drivers/clk/mediatek/clk-mt8192-aud.c         |  4 ++-
 drivers/clk/mediatek/clk-mt8192-cam.c         |  4 ++-
 drivers/clk/mediatek/clk-mt8192-img.c         |  4 ++-
 .../clk/mediatek/clk-mt8192-imp_iic_wrap.c    |  4 ++-
 drivers/clk/mediatek/clk-mt8192-ipe.c         |  4 ++-
 drivers/clk/mediatek/clk-mt8192-mdp.c         |  4 ++-
 drivers/clk/mediatek/clk-mt8192-mfg.c         |  4 ++-
 drivers/clk/mediatek/clk-mt8192-mm.c          |  4 ++-
 drivers/clk/mediatek/clk-mt8192-msdc.c        |  4 ++-
 drivers/clk/mediatek/clk-mt8192-scp_adsp.c    |  4 ++-
 drivers/clk/mediatek/clk-mt8192-vdec.c        |  4 ++-
 drivers/clk/mediatek/clk-mt8192-venc.c        |  4 ++-
 drivers/clk/mediatek/clk-mt8192.c             |  2 ++
 14 files changed, 51 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig
index 3ce6fb04d8ff..b2205caf673f 100644
--- a/drivers/clk/mediatek/Kconfig
+++ b/drivers/clk/mediatek/Kconfig
@@ -496,7 +496,7 @@ config COMMON_CLK_MT8183_VENCSYS
 	  This driver supports MediaTek MT8183 vencsys clocks.
 
 config COMMON_CLK_MT8192
-	bool "Clock driver for MediaTek MT8192"
+	tristate "Clock driver for MediaTek MT8192"
 	depends on ARM64 || COMPILE_TEST
 	select COMMON_CLK_MEDIATEK
 	default ARM64
@@ -504,73 +504,73 @@ config COMMON_CLK_MT8192
 	  This driver supports MediaTek MT8192 basic clocks.
 
 config COMMON_CLK_MT8192_AUDSYS
-	bool "Clock driver for MediaTek MT8192 audsys"
+	tristate "Clock driver for MediaTek MT8192 audsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 audsys clocks.
 
 config COMMON_CLK_MT8192_CAMSYS
-	bool "Clock driver for MediaTek MT8192 camsys"
+	tristate "Clock driver for MediaTek MT8192 camsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 camsys and camsys_raw clocks.
 
 config COMMON_CLK_MT8192_IMGSYS
-	bool "Clock driver for MediaTek MT8192 imgsys"
+	tristate "Clock driver for MediaTek MT8192 imgsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 imgsys and imgsys2 clocks.
 
 config COMMON_CLK_MT8192_IMP_IIC_WRAP
-	bool "Clock driver for MediaTek MT8192 imp_iic_wrap"
+	tristate "Clock driver for MediaTek MT8192 imp_iic_wrap"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 imp_iic_wrap clocks.
 
 config COMMON_CLK_MT8192_IPESYS
-	bool "Clock driver for MediaTek MT8192 ipesys"
+	tristate "Clock driver for MediaTek MT8192 ipesys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 ipesys clocks.
 
 config COMMON_CLK_MT8192_MDPSYS
-	bool "Clock driver for MediaTek MT8192 mdpsys"
+	tristate "Clock driver for MediaTek MT8192 mdpsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 mdpsys clocks.
 
 config COMMON_CLK_MT8192_MFGCFG
-	bool "Clock driver for MediaTek MT8192 mfgcfg"
+	tristate "Clock driver for MediaTek MT8192 mfgcfg"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 mfgcfg clocks.
 
 config COMMON_CLK_MT8192_MMSYS
-	bool "Clock driver for MediaTek MT8192 mmsys"
+	tristate "Clock driver for MediaTek MT8192 mmsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 mmsys clocks.
 
 config COMMON_CLK_MT8192_MSDC
-	bool "Clock driver for MediaTek MT8192 msdc"
+	tristate "Clock driver for MediaTek MT8192 msdc"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 msdc and msdc_top clocks.
 
 config COMMON_CLK_MT8192_SCP_ADSP
-	bool "Clock driver for MediaTek MT8192 scp_adsp"
+	tristate "Clock driver for MediaTek MT8192 scp_adsp"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 scp_adsp clocks.
 
 config COMMON_CLK_MT8192_VDECSYS
-	bool "Clock driver for MediaTek MT8192 vdecsys"
+	tristate "Clock driver for MediaTek MT8192 vdecsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 vdecsys and vdecsys_soc clocks.
 
 config COMMON_CLK_MT8192_VENCSYS
-	bool "Clock driver for MediaTek MT8192 vencsys"
+	tristate "Clock driver for MediaTek MT8192 vencsys"
 	depends on COMMON_CLK_MT8192
 	help
 	  This driver supports MediaTek MT8192 vencsys clocks.
diff --git a/drivers/clk/mediatek/clk-mt8192-aud.c b/drivers/clk/mediatek/clk-mt8192-aud.c
index f28d56628045..ea512fa3d4b9 100644
--- a/drivers/clk/mediatek/clk-mt8192-aud.c
+++ b/drivers/clk/mediatek/clk-mt8192-aud.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 
@@ -115,4 +116,5 @@ static struct platform_driver clk_mt8192_aud_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_aud_drv);
+module_platform_driver(clk_mt8192_aud_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-cam.c b/drivers/clk/mediatek/clk-mt8192-cam.c
index fc74cd80b4b0..04a0de364408 100644
--- a/drivers/clk/mediatek/clk-mt8192-cam.c
+++ b/drivers/clk/mediatek/clk-mt8192-cam.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -104,4 +105,5 @@ static struct platform_driver clk_mt8192_cam_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_cam_drv);
+module_platform_driver(clk_mt8192_cam_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-img.c b/drivers/clk/mediatek/clk-mt8192-img.c
index 7ce3abe42577..54713a5f3dfc 100644
--- a/drivers/clk/mediatek/clk-mt8192-img.c
+++ b/drivers/clk/mediatek/clk-mt8192-img.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -67,4 +68,5 @@ static struct platform_driver clk_mt8192_img_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_img_drv);
+module_platform_driver(clk_mt8192_img_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c
index 700356ac6a58..94fdb3c1a963 100644
--- a/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c
+++ b/drivers/clk/mediatek/clk-mt8192-imp_iic_wrap.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -116,4 +117,5 @@ static struct platform_driver clk_mt8192_imp_iic_wrap_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_imp_iic_wrap_drv);
+module_platform_driver(clk_mt8192_imp_iic_wrap_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-ipe.c b/drivers/clk/mediatek/clk-mt8192-ipe.c
index 730d91b64b3f..7f8a7a60e2bd 100644
--- a/drivers/clk/mediatek/clk-mt8192-ipe.c
+++ b/drivers/clk/mediatek/clk-mt8192-ipe.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -54,4 +55,5 @@ static struct platform_driver clk_mt8192_ipe_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_ipe_drv);
+module_platform_driver(clk_mt8192_ipe_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-mdp.c b/drivers/clk/mediatek/clk-mt8192-mdp.c
index 93c87ae2f332..9eab7337fabe 100644
--- a/drivers/clk/mediatek/clk-mt8192-mdp.c
+++ b/drivers/clk/mediatek/clk-mt8192-mdp.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -79,4 +80,5 @@ static struct platform_driver clk_mt8192_mdp_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_mdp_drv);
+module_platform_driver(clk_mt8192_mdp_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-mfg.c b/drivers/clk/mediatek/clk-mt8192-mfg.c
index 3bbc7469f0e4..8b44f0779a8c 100644
--- a/drivers/clk/mediatek/clk-mt8192-mfg.c
+++ b/drivers/clk/mediatek/clk-mt8192-mfg.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -47,4 +48,5 @@ static struct platform_driver clk_mt8192_mfg_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_mfg_drv);
+module_platform_driver(clk_mt8192_mfg_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-mm.c b/drivers/clk/mediatek/clk-mt8192-mm.c
index 4a0b4c4bc06a..506beb5a410d 100644
--- a/drivers/clk/mediatek/clk-mt8192-mm.c
+++ b/drivers/clk/mediatek/clk-mt8192-mm.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/platform_device.h>
 
 #include "clk-mtk.h"
@@ -105,4 +106,5 @@ static struct platform_driver clk_mt8192_mm_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_mm_drv);
+module_platform_driver(clk_mt8192_mm_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-msdc.c b/drivers/clk/mediatek/clk-mt8192-msdc.c
index 87c3b79b79cf..a467885abbf8 100644
--- a/drivers/clk/mediatek/clk-mt8192-msdc.c
+++ b/drivers/clk/mediatek/clk-mt8192-msdc.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -82,4 +83,5 @@ static struct platform_driver clk_mt8192_msdc_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_msdc_drv);
+module_platform_driver(clk_mt8192_msdc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-scp_adsp.c b/drivers/clk/mediatek/clk-mt8192-scp_adsp.c
index 58725d79dd13..87fbd0131aed 100644
--- a/drivers/clk/mediatek/clk-mt8192-scp_adsp.c
+++ b/drivers/clk/mediatek/clk-mt8192-scp_adsp.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -47,4 +48,5 @@ static struct platform_driver clk_mt8192_scp_adsp_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_scp_adsp_drv);
+module_platform_driver(clk_mt8192_scp_adsp_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-vdec.c b/drivers/clk/mediatek/clk-mt8192-vdec.c
index b1d95cfbf22a..4d223ecca2c8 100644
--- a/drivers/clk/mediatek/clk-mt8192-vdec.c
+++ b/drivers/clk/mediatek/clk-mt8192-vdec.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -91,4 +92,5 @@ static struct platform_driver clk_mt8192_vdec_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_vdec_drv);
+module_platform_driver(clk_mt8192_vdec_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192-venc.c b/drivers/clk/mediatek/clk-mt8192-venc.c
index c0d867bff09e..0e8092802771 100644
--- a/drivers/clk/mediatek/clk-mt8192-venc.c
+++ b/drivers/clk/mediatek/clk-mt8192-venc.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include <linux/clk-provider.h>
+#include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
@@ -50,4 +51,5 @@ static struct platform_driver clk_mt8192_venc_drv = {
 	},
 };
 
-builtin_platform_driver(clk_mt8192_venc_drv);
+module_platform_driver(clk_mt8192_venc_drv);
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
index 552fae4f0fd5..a221834db347 100644
--- a/drivers/clk/mediatek/clk-mt8192.c
+++ b/drivers/clk/mediatek/clk-mt8192.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
@@ -1313,3 +1314,4 @@ static int __init clk_mt8192_init(void)
 }
 
 arch_initcall(clk_mt8192_init);
+MODULE_LICENSE("GPL");
-- 
2.18.0



From robh at kernel.org  Mon Jan 10 09:16:49 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 11:16:49 -0600
Subject: [PATCH 01/10] dt-bindings: devfreq: rk3399_dmc: Convert to YAML
In-Reply-To: <20220107155215.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>
References: <20220107235320.965497-1-briannorris@chromium.org>
 <20220107155215.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>
Message-ID: <YdxqATskHY3BMWSZ@robh.at.kernel.org>

On Fri, Jan 07, 2022 at 03:53:11PM -0800, Brian Norris wrote:
> I want to add, deprecate, and bugfix some properties, as well as add the
> first users. This is easier with a proper schema.
> 
> The transformation is mostly straightforward, plus a few notable tweaks:
> 
>  * Renamed rockchip,dram_speed_bin to rockchip,ddr3_speed_bin. The
>    driver code and the example matched, but the description was
>    different. I went with the implementation.
> 
>  * Drop upthreshold and downdifferential properties from the example.
>    These were undocumented (so, wouldn't pass validation), but were
>    representing software properties (governor tweaks). I drop them from
>    the driver in subsequent patches.
> 
>  * Rename clock from pclk_ddr_mon to dmc_clk. The driver, DT example,
>    and all downstream users matched -- the binding definition was the
>    exception. Anyway, "dmc_clk" is a more appropriately generic name.

generic is not really better, but okay.

> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
> 
>  .../bindings/devfreq/rk3399_dmc.txt           | 212 -------------
>  .../bindings/devfreq/rk3399_dmc.yaml          | 297 ++++++++++++++++++
>  2 files changed, 297 insertions(+), 212 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
>  create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> 
> diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
> deleted file mode 100644
> index 58fc8a6cebc7..000000000000
> --- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
> +++ /dev/null
> @@ -1,212 +0,0 @@
> -* Rockchip rk3399 DMC (Dynamic Memory Controller) device
> -
> -Required properties:
> -- compatible:		 Must be "rockchip,rk3399-dmc".
> -- devfreq-events:	 Node to get DDR loading, Refer to
> -			 Documentation/devicetree/bindings/devfreq/event/
> -			 rockchip-dfi.txt
> -- clocks:		 Phandles for clock specified in "clock-names" property
> -- clock-names :		 The name of clock used by the DFI, must be
> -			 "pclk_ddr_mon";
> -- operating-points-v2:	 Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml
> -			 for details.
> -- center-supply:	 DMC supply node.
> -- status:		 Marks the node enabled/disabled.
> -- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
> -			 files".
> -
> -Optional properties:
> -- interrupts:		 The CPU interrupt number. The interrupt specifier
> -			 format depends on the interrupt controller.
> -			 It should be a DCF interrupt. When DDR DVFS finishes
> -			 a DCF interrupt is triggered.
> -- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
> -			 files".
> -
> -Following properties relate to DDR timing:
> -
> -- rockchip,dram_speed_bin :	  Value reference include/dt-bindings/clock/rk3399-ddr.h,
> -				  it selects the DDR3 cl-trp-trcd type. It must be
> -				  set according to "Speed Bin" in DDR3 datasheet,
> -				  DO NOT use a smaller "Speed Bin" than specified
> -				  for the DDR3 being used.
> -
> -- rockchip,pd_idle :		  Configure the PD_IDLE value. Defines the
> -				  power-down idle period in which memories are
> -				  placed into power-down mode if bus is idle
> -				  for PD_IDLE DFI clock cycles.
> -
> -- rockchip,sr_idle :		  Configure the SR_IDLE value. Defines the
> -				  self-refresh idle period in which memories are
> -				  placed into self-refresh mode if bus is idle
> -				  for SR_IDLE * 1024 DFI clock cycles (DFI
> -				  clocks freq is half of DRAM clock), default
> -				  value is "0".
> -
> -- rockchip,sr_mc_gate_idle :	  Defines the memory self-refresh and controller
> -				  clock gating idle period. Memories are placed
> -				  into self-refresh mode and memory controller
> -				  clock arg gating started if bus is idle for
> -				  sr_mc_gate_idle*1024 DFI clock cycles.
> -
> -- rockchip,srpd_lite_idle :	  Defines the self-refresh power down idle
> -				  period in which memories are placed into
> -				  self-refresh power down mode if bus is idle
> -				  for srpd_lite_idle * 1024 DFI clock cycles.
> -				  This parameter is for LPDDR4 only.
> -
> -- rockchip,standby_idle :	  Defines the standby idle period in which
> -				  memories are placed into self-refresh mode.
> -				  The controller, pi, PHY and DRAM clock will
> -				  be gated if bus is idle for standby_idle * DFI
> -				  clock cycles.
> -
> -- rockchip,dram_dll_dis_freq :	  Defines the DDR3 DLL bypass frequency in MHz.
> -				  When DDR frequency is less than DRAM_DLL_DISB_FREQ,
> -				  DDR3 DLL will be bypassed. Note: if DLL was bypassed,
> -				  the odt will also stop working.
> -
> -- rockchip,phy_dll_dis_freq :	  Defines the PHY dll bypass frequency in
> -				  MHz (Mega Hz). When DDR frequency is less than
> -				  DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
> -				  Note: PHY DLL and PHY ODT are independent.
> -
> -- rockchip,ddr3_odt_dis_freq :	  When the DRAM type is DDR3, this parameter defines
> -				  the ODT disable frequency in MHz (Mega Hz).
> -				  when the DDR frequency is  less then ddr3_odt_dis_freq,
> -				  the ODT on the DRAM side and controller side are
> -				  both disabled.
> -
> -- rockchip,ddr3_drv :		  When the DRAM type is DDR3, this parameter defines
> -				  the DRAM side driver strength in ohms. Default
> -				  value is 40.
> -
> -- rockchip,ddr3_odt :		  When the DRAM type is DDR3, this parameter defines
> -				  the DRAM side ODT strength in ohms. Default value
> -				  is 120.
> -
> -- rockchip,phy_ddr3_ca_drv :	  When the DRAM type is DDR3, this parameter defines
> -				  the phy side CA line (incluing command line,
> -				  address line and clock line) driver strength.
> -				  Default value is 40.
> -
> -- rockchip,phy_ddr3_dq_drv :	  When the DRAM type is DDR3, this parameter defines
> -				  the PHY side DQ line (including DQS/DQ/DM line)
> -				  driver strength. Default value is 40.
> -
> -- rockchip,phy_ddr3_odt : 	  When the DRAM type is DDR3, this parameter defines
> -				  the PHY side ODT strength. Default value is 240.
> -
> -- rockchip,lpddr3_odt_dis_freq : When the DRAM type is LPDDR3, this parameter defines
> -				  then ODT disable frequency in MHz (Mega Hz).
> -				  When DDR frequency is less then ddr3_odt_dis_freq,
> -				  the ODT on the DRAM side and controller side are
> -				  both disabled.
> -
> -- rockchip,lpddr3_drv :		  When the DRAM type is LPDDR3, this parameter defines
> -				  the DRAM side driver strength in ohms. Default
> -				  value is 34.
> -
> -- rockchip,lpddr3_odt :		  When the DRAM type is LPDDR3, this parameter defines
> -				  the DRAM side ODT strength in ohms. Default value
> -				  is 240.
> -
> -- rockchip,phy_lpddr3_ca_drv :	  When the DRAM type is LPDDR3, this parameter defines
> -				  the PHY side CA line (including command line,
> -				  address line and clock line) driver strength.
> -				  Default value is 40.
> -
> -- rockchip,phy_lpddr3_dq_drv :	  When the DRAM type is LPDDR3, this parameter defines
> -				  the PHY side DQ line (including DQS/DQ/DM line)
> -				  driver strength. Default value is 40.
> -
> -- rockchip,phy_lpddr3_odt : 	  When dram type is LPDDR3, this parameter define
> -				  the phy side odt strength, default value is 240.
> -
> -- rockchip,lpddr4_odt_dis_freq : When the DRAM type is LPDDR4, this parameter
> -				  defines the ODT disable frequency in
> -				  MHz (Mega Hz). When the DDR frequency is less then
> -				  ddr3_odt_dis_freq, the ODT on the DRAM side and
> -				  controller side are both disabled.
> -
> -- rockchip,lpddr4_drv :		  When the DRAM type is LPDDR4, this parameter defines
> -				  the DRAM side driver strength in ohms. Default
> -				  value is 60.
> -
> -- rockchip,lpddr4_dq_odt : 	  When the DRAM type is LPDDR4, this parameter defines
> -				  the DRAM side ODT on DQS/DQ line strength in ohms.
> -				  Default value is 40.
> -
> -- rockchip,lpddr4_ca_odt :	  When the DRAM type is LPDDR4, this parameter defines
> -				  the DRAM side ODT on CA line strength in ohms.
> -				  Default value is 40.
> -
> -- rockchip,phy_lpddr4_ca_drv :	  When the DRAM type is LPDDR4, this parameter defines
> -				  the PHY side CA line (including command address
> -				  line) driver strength. Default value is 40.
> -
> -- rockchip,phy_lpddr4_ck_cs_drv : When the DRAM type is LPDDR4, this parameter defines
> -				  the PHY side clock line and CS line driver
> -				  strength. Default value is 80.
> -
> -- rockchip,phy_lpddr4_dq_drv :	  When the DRAM type is LPDDR4, this parameter defines
> -				  the PHY side DQ line (including DQS/DQ/DM line)
> -				  driver strength. Default value is 80.
> -
> -- rockchip,phy_lpddr4_odt :	  When the DRAM type is LPDDR4, this parameter defines
> -				  the PHY side ODT strength. Default value is 60.
> -
> -Example:
> -	dmc_opp_table: dmc_opp_table {
> -		compatible = "operating-points-v2";
> -
> -		opp00 {
> -			opp-hz = /bits/ 64 <300000000>;
> -			opp-microvolt = <900000>;
> -		};
> -		opp01 {
> -			opp-hz = /bits/ 64 <666000000>;
> -			opp-microvolt = <900000>;
> -		};
> -	};
> -
> -	dmc: dmc {
> -		compatible = "rockchip,rk3399-dmc";
> -		devfreq-events = <&dfi>;
> -		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> -		clocks = <&cru SCLK_DDRC>;
> -		clock-names = "dmc_clk";
> -		operating-points-v2 = <&dmc_opp_table>;
> -		center-supply = <&ppvar_centerlogic>;
> -		upthreshold = <15>;
> -		downdifferential = <10>;
> -		rockchip,ddr3_speed_bin = <21>;
> -		rockchip,pd_idle = <0x40>;
> -		rockchip,sr_idle = <0x2>;
> -		rockchip,sr_mc_gate_idle = <0x3>;
> -		rockchip,srpd_lite_idle	= <0x4>;
> -		rockchip,standby_idle = <0x2000>;
> -		rockchip,dram_dll_dis_freq = <300>;
> -		rockchip,phy_dll_dis_freq = <125>;
> -		rockchip,auto_pd_dis_freq = <666>;
> -		rockchip,ddr3_odt_dis_freq = <333>;
> -		rockchip,ddr3_drv = <40>;
> -		rockchip,ddr3_odt = <120>;
> -		rockchip,phy_ddr3_ca_drv = <40>;
> -		rockchip,phy_ddr3_dq_drv = <40>;
> -		rockchip,phy_ddr3_odt = <240>;
> -		rockchip,lpddr3_odt_dis_freq = <333>;
> -		rockchip,lpddr3_drv = <34>;
> -		rockchip,lpddr3_odt = <240>;
> -		rockchip,phy_lpddr3_ca_drv = <40>;
> -		rockchip,phy_lpddr3_dq_drv = <40>;
> -		rockchip,phy_lpddr3_odt = <240>;
> -		rockchip,lpddr4_odt_dis_freq = <333>;
> -		rockchip,lpddr4_drv = <60>;
> -		rockchip,lpddr4_dq_odt = <40>;
> -		rockchip,lpddr4_ca_odt = <40>;
> -		rockchip,phy_lpddr4_ca_drv = <40>;
> -		rockchip,phy_lpddr4_ck_cs_drv = <80>;
> -		rockchip,phy_lpddr4_dq_drv = <80>;
> -		rockchip,phy_lpddr4_odt = <60>;
> -	};
> diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> new file mode 100644
> index 000000000000..f12f34d93378
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> @@ -0,0 +1,297 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +# %YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/devfreq/rk3399_dmc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Rockchip rk3399 DMC (Dynamic Memory Controller) device
> +
> +maintainers:
> +  - Brian Norris <briannorris at chromium.org>
> +
> +required:

'required' normally goes after properties.

> +  - compatible
> +  - devfreq-events
> +  - clocks
> +  - clock-names
> +  - operating-points-v2
> +  - center-supply
> +
> +properties:
> +  compatible:
> +    enum:
> +      - rockchip,rk3399-dmc
> +
> +  devfreq-events:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    description:
> +      Node to get DDR loading. Refer to
> +      Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt.
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    items:
> +    - const: dmc_clk
> +
> +  operating-points-v2:
> +    description:
> +      Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml for details.

Drop generic, free form references. Just 'true' is fine here.

> +
> +  center-supply:
> +    description:
> +      DMC regulator supply.
> +
> +  rockchip,pmu:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1

'phandle' is already a single item. Drop.

> +    description:
> +      Phandle to the syscon managing the "PMU general register files".
> +
> +  interrupts:
> +    maxItems: 1
> +    description:
> +      The CPU interrupt number. The interrupt specifier format depends on the
> +      interrupt controller. It should be a DCF interrupt. When DDR DVFS
> +      finishes a DCF interrupt is triggered.

You can drop 'The interrupt specifier format depends on the interrupt 
controller'.

> +
> +  rockchip,ddr3_speed_bin:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
> +      DDR3 cl-trp-trcd type. It must be set according to "Speed Bin" in DDR3
> +      datasheet; DO NOT use a smaller "Speed Bin" than specified for the DDR3
> +      being used.
> +
> +  rockchip,pd_idle:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Configure the PD_IDLE value. Defines the power-down idle period in which
> +      memories are placed into power-down mode if bus is idle for PD_IDLE DFI
> +      clock cycles.
> +
> +  rockchip,sr_idle:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Configure the SR_IDLE value. Defines the self-refresh idle period in
> +      which memories are placed into self-refresh mode if bus is idle for
> +      SR_IDLE * 1024 DFI clock cycles (DFI clocks freq is half of DRAM clock),
> +      default value is "0".
> +
> +  rockchip,sr_mc_gate_idle:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the memory self-refresh and controller clock gating idle period.
> +      Memories are placed into self-refresh mode and memory controller clock
> +      arg gating started if bus is idle for sr_mc_gate_idle*1024 DFI clock
> +      cycles.
> +
> +  rockchip,srpd_lite_idle:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the self-refresh power down idle period in which memories are
> +      placed into self-refresh power down mode if bus is idle for
> +      srpd_lite_idle * 1024 DFI clock cycles. This parameter is for LPDDR4
> +      only.
> +
> +  rockchip,standby_idle:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the standby idle period in which memories are placed into
> +      self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
> +      if bus is idle for standby_idle * DFI clock cycles.
> +
> +  rockchip,dram_dll_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
> +      than DRAM_DLL_DISB_FREQ, DDR3 DLL will be bypassed.
> +      Note: if DLL was bypassed, the odt will also stop working.
> +
> +  rockchip,phy_dll_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: |
> +      Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
> +      is less than DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
> +      Note: PHY DLL and PHY ODT are independent.
> +
> +  rockchip,auto_pd_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the auto PD disable frequency in MHz.
> +
> +  rockchip,ddr3_odt_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the ODT disable
> +      frequency in MHz (Mega Hz). When the DDR frequency is less then
> +      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
> +      disabled.
> +
> +  rockchip,ddr3_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the DRAM side drive
> +      strength in ohms. Default value is 40.
> +
> +  rockchip,ddr3_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the DRAM side ODT
> +      strength in ohms. Default value is 120.
> +
> +  rockchip,phy_ddr3_ca_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the phy side CA line
> +      (incluing command line, address line and clock line) drive strength.
> +      Default value is 40.
> +
> +  rockchip,phy_ddr3_dq_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the PHY side DQ line
> +      (including DQS/DQ/DM line) drive strength. Default value is 40.
> +
> +  rockchip,phy_ddr3_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is DDR3, this parameter defines the PHY side ODT
> +      strength. Default value is 240.
> +
> +  rockchip,lpddr3_odt_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR3, this parameter defines then ODT disable
> +      frequency in MHz (Mega Hz). When DDR frequency is less then
> +      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
> +      disabled.
> +
> +  rockchip,lpddr3_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
> +      strength in ohms. Default value is 34.
> +
> +  rockchip,lpddr3_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
> +      strength in ohms. Default value is 240.
> +
> +  rockchip,phy_lpddr3_ca_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
> +      (including command line, address line and clock line) drive strength.
> +      Default value is 40.
> +
> +  rockchip,phy_lpddr3_dq_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
> +      (including DQS/DQ/DM line) drive strength. Default value is 40.
> +
> +  rockchip,phy_lpddr3_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When dram type is LPDDR3, this parameter define the phy side odt
> +      strength, default value is 240.
> +
> +  rockchip,lpddr4_odt_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the ODT disable
> +      frequency in MHz (Mega Hz). When the DDR frequency is less then
> +      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
> +      disabled.
> +
> +  rockchip,lpddr4_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
> +      strength in ohms. Default value is 60.
> +
> +  rockchip,lpddr4_dq_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
> +      DQS/DQ line strength in ohms. Default value is 40.
> +
> +  rockchip,lpddr4_ca_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
> +      CA line strength in ohms. Default value is 40.
> +
> +  rockchip,phy_lpddr4_ca_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
> +      (including command address line) drive strength. Default value is 40.
> +
> +  rockchip,phy_lpddr4_ck_cs_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the PHY side clock
> +      line and CS line drive strength. Default value is 80.
> +
> +  rockchip,phy_lpddr4_dq_drv:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
> +      (including DQS/DQ/DM line) drive strength. Default value is 80.
> +
> +  rockchip,phy_lpddr4_odt:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
> +      strength. Default value is 60.
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/rk3399-cru.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    dmc: dmc {

memory-controller {

> +      compatible = "rockchip,rk3399-dmc";
> +      devfreq-events = <&dfi>;
> +      rockchip,pmu = <&pmu>;
> +      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
> +      clocks = <&cru SCLK_DDRC>;
> +      clock-names = "dmc_clk";
> +      operating-points-v2 = <&dmc_opp_table>;
> +      center-supply = <&ppvar_centerlogic>;
> +      rockchip,ddr3_speed_bin = <21>;
> +      rockchip,pd_idle = <0x40>;
> +      rockchip,sr_idle = <0x2>;
> +      rockchip,sr_mc_gate_idle = <0x3>;
> +      rockchip,srpd_lite_idle = <0x4>;
> +      rockchip,standby_idle = <0x2000>;
> +      rockchip,dram_dll_dis_freq = <300>;
> +      rockchip,phy_dll_dis_freq = <125>;
> +      rockchip,auto_pd_dis_freq = <666>;
> +      rockchip,ddr3_odt_dis_freq = <333>;
> +      rockchip,ddr3_drv = <40>;
> +      rockchip,ddr3_odt = <120>;
> +      rockchip,phy_ddr3_ca_drv = <40>;
> +      rockchip,phy_ddr3_dq_drv = <40>;
> +      rockchip,phy_ddr3_odt = <240>;
> +      rockchip,lpddr3_odt_dis_freq = <333>;
> +      rockchip,lpddr3_drv = <34>;
> +      rockchip,lpddr3_odt = <240>;
> +      rockchip,phy_lpddr3_ca_drv = <40>;
> +      rockchip,phy_lpddr3_dq_drv = <40>;
> +      rockchip,phy_lpddr3_odt = <240>;
> +      rockchip,lpddr4_odt_dis_freq = <333>;
> +      rockchip,lpddr4_drv = <60>;
> +      rockchip,lpddr4_dq_odt = <40>;
> +      rockchip,lpddr4_ca_odt = <40>;
> +      rockchip,phy_lpddr4_ca_drv = <40>;
> +      rockchip,phy_lpddr4_ck_cs_drv = <80>;
> +      rockchip,phy_lpddr4_dq_drv = <80>;
> +      rockchip,phy_lpddr4_odt = <60>;
> +    };
> -- 
> 2.34.1.575.g55b058a8bb-goog
> 
> 


From kuba at kernel.org  Mon Jan 10 09:28:36 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 10 Jan 2022 09:28:36 -0800
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <Ydw7EzPvwArW/siQ@Red>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
 <Ydw7EzPvwArW/siQ@Red>
Message-ID: <20220110092836.113dbae1@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Mon, 10 Jan 2022 14:56:35 +0100 Corentin Labbe wrote:
> > @@ -61,7 +62,21 @@
> >  #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
> >  #define EMAC_RX_FBC_REG		(0x50)
> >  #define EMAC_INT_CTL_REG	(0x54)
> > +#define EMAC_INT_CTL_RX_EN	(1 << 8)
> > +#define EMAC_INT_CTL_TX0_EN	(1)
> > +#define EMAC_INT_CTL_TX1_EN	(1 << 1)
> > +#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
> > +#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
> > +#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
> > +#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
> >  #define EMAC_INT_STA_REG	(0x58)
> > +#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
> > +#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
> > +#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
> > +#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
> > +#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
> > +#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
> > +#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)  
> 
> As proposed by checkpatch, I thing there are several place (like all
> EMAC_INT_STA) where you could use BIT(x) instead of (0xX << x)

That's not a hard requirement, if the driver already uses the shift you
can leave your code as is, some upstream developers actually prefer to
avoid the BIT() macro.


From maz at kernel.org  Mon Jan 10 09:30:55 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 10 Jan 2022 17:30:55 +0000
Subject: Does clocksource arch_sys_counter synchronize across CPUs?
In-Reply-To: <CAFbkdV3KOGA863+TV9_uVWnmg75v-60R3qT0r-+LgQiyHM6BtA@mail.gmail.com>
References: <CAFbkdV3KOGA863+TV9_uVWnmg75v-60R3qT0r-+LgQiyHM6BtA@mail.gmail.com>
Message-ID: <87fspvts4w.wl-maz@kernel.org>

On Mon, 10 Jan 2022 16:51:14 +0000,
Huichun Feng <foxhoundsk.tw at gmail.com> wrote:
> 
> Hi list,
> 
> AFAIK, one of the clocksource in arm64 (armv8.3, Rpi4) --

RPI4 is ARMv8.0 (not that it matters here).

> arch_sys_counter, uses a per-core register CNTVCT as the accessor.
> 
> And comes to consistency of CNTVCT's, after searching some of the
> related manuals [0-2], I didn't find statements saying that it is
> synchronize across CPUs. However, I've found a recent patch [3] says
> that CNTVCT is synchronized in armv8.6.
> 
> So, does CNTVCT synchronize across CPUs in armv8.3?

CNTVCT_EL0 is guaranteed to be identical across CPUs as long as
CNTVOFF_EL2 is identical across CPUs. That's because all the CPUs
source their counters from the same source (see the architecture spec
in section D11 for the details).

The patch you mention makes use of the *self-synchronisation* feature
of the CNTVCTSS_EL0 instruction. which guarantees that the instruction
won't be reordered wrt to other instructions in the stream, avoiding
the use of an ISB instruction. Nothing to do with cross-CPU
synchronisation, which has always been guaranteed (there are broken
system integrations though).

	M.

-- 
Without deviation from the norm, progress is not possible.


From robh at kernel.org  Mon Jan 10 09:36:02 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 11:36:02 -0600
Subject: [PATCH 2/3] dt-bindings: reset: add bindings for the Meson-S4
 SoC Reset Controller
In-Reply-To: <20220107023931.13251-3-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-3-zelong.dong@amlogic.com>
Message-ID: <YdxugtL5PsrwsT6D@robh.at.kernel.org>

On Fri, 07 Jan 2022 10:39:30 +0800, Zelong Dong wrote:
> Add DT bindings for the Meson-S4 SoC Reset Controller include file.
> 
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
> ---
>  .../reset/amlogic,meson-s4-reset.h            | 125 ++++++++++++++++++
>  1 file changed, 125 insertions(+)
>  create mode 100644 include/dt-bindings/reset/amlogic,meson-s4-reset.h
> 


Please add Acked-by/Reviewed-by tags when posting new versions. However,
there's no need to repost patches *only* to add the tags. The upstream
maintainer will do that for acks received on the version they apply.

If a tag was not added on purpose, please state why and what changed.



From irogers at google.com  Mon Jan 10 09:36:49 2022
From: irogers at google.com (Ian Rogers)
Date: Mon, 10 Jan 2022 09:36:49 -0800
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
Message-ID: <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>

On Mon, Jan 10, 2022 at 9:10 AM John Garry <john.garry at huawei.com> wrote:
>
> On 05/01/2022 06:13, Ian Rogers wrote:
> >
> > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > +                                    void *data)
> > +{
> > +     if (idx < 0 || idx > map->nr)
> > +             return cpu_map__empty_aggr_cpu_id();
> > +
> > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
>
>
> This is later deleted in the series. Can the series be reworked so that
> we don't add stuff and then later delete it? One reason for that
> approach is that we don't spend time reviewing something which will be
> deleted, especially in such a big series...

Hi John,

I think you are asking to squash:
https://lore.kernel.org/lkml/20220105061351.120843-8-irogers at google.com/
into this change. There are other  similar related changes that may
also be squashed. The changes are trying to introduce a new API and
then add changes to switch over to using it. This is with a view to
making bisection easier, have each change only do 1 thing and so on. I
believe the format of the patches is house style, but it is fine to
squash changes together too. Having sent patches to Arnaldo and having
had them split I'm reluctant to do a v5 with them squashed without him
expressing a preference.

Thanks,
Ian

> If it really makes sense to do it this way then fine.
>
> Thanks,
> John


From ebiggers at kernel.org  Mon Jan 10 09:48:22 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 10 Jan 2022 09:48:22 -0800
Subject: [PATCH] crypto: testmgr - fix some wrong vectors of aes-ccm
In-Reply-To: <20220109170239.4322-1-wuhanluop@163.com>
References: <20220109170239.4322-1-wuhanluop@163.com>
Message-ID: <YdxxZmmlWp+RQeGC@sol.localdomain>

On Mon, Jan 10, 2022 at 01:02:39AM +0800, Peng Luo wrote:
> Some vectors of aes-ccm are wrong.
> This patch has been tested with kernel 4.9 and openssl1.1.1k.
> 
> Signed-off-by: Peng Luo <wuhanluop at 163.com>
> ---
>  crypto/testmgr.h | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index a253d66ba1c1..ff171fe53979 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -19865,8 +19865,8 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
>  			  "\xd0\xd1\x3d\x1a\xa3\x6d\xe4\x0a"
>  			  "\x86\xb0\x87\x6b\x62\x33\x8c\x34"
>  			  "\xce\xab\x57\xcc\x79\x0b\xe0\x6f"
> -			  "\x5c\x3e\x48\x1f\x6c\x46\xf7\x51"
> -			  "\x8b\x84\x83\x2a\xc1\x05\xb8\xc5",
> +			  "\xCF\xE9\xF9\x21\x3C\x1A\xCE\x67"
> +			  "\x62\x7B\x36\x3A\xEA\x19\xAC\x58",
>  		.clen	= 48,
>  		.novrfy	= 1,
>  	}, {
> @@ -19952,8 +19952,8 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
>  			  "\xc6\x0e\x6e\xe5\xd6\x98\xa6\x37"
>  			  "\x8c\x26\x33\xc6\xb2\xa2\x17\xfa"
>  			  "\x64\x19\xc0\x30\xd7\xfc\x14\x6b"
> -			  "\xe3\x33\xc2\x04\xb0\x37\xbe\x3f"
> -			  "\xa9\xb4\x2d\x68\x03\xa3\x44\xef",
> +			  "\x08\x5A\x20\x4A\xB0\x2C\xF9\x49"
> +			  "\x10\x1C\x9C\x85\x8C\x12\xE0\x3A",
>  		.clen	= 48,
>  		.novrfy	= 1,
>  	}, {
> @@ -19983,7 +19983,7 @@ static const struct aead_testvec aes_ccm_tv_template[] = {
>  			  "\x3e\xaf\x70\x5e\xb2\x4d\xea\x39"
>  			  "\x89\xd4\x75\x7a\x63\xb1\xda\x93",
>  		.plen	= 32,
> -		.ctext	= "\x48\x01\x5e\x02\x24\x04\x66\x47"
> +		.ctext	= "\x14\x01\x5e\x02\x24\x04\x66\x47"
>  			  "\xa1\xea\x6f\xaf\xe8\xfc\xfb\xdd"
>  			  "\xa5\xa9\x87\x8d\x84\xee\x2e\x77"
>  			  "\xbb\x86\xb9\xf5\x5c\x6c\xff\xf6"

This patch causes a self-test failure:

	[   22.354527] alg: aead: ccm_base(ctr-aes-aesni,cbcmac(aes-aesni)) decryption unexpectedly succeeded on test vector 16; expected_error"
	[   22.355843] ------------[ cut here ]------------
	[   22.356306] alg: self-tests for ccm_base(ctr-aes-aesni,cbcmac(aes-aesni)) (ccm(aes)) failed (rc=-22)

Please be more specific about what is wrong.  Also, please test with the latest
upstream kernel, not v4.9 which is over 5 years old.

- Eric


From john.garry at huawei.com  Mon Jan 10 09:51:33 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 17:51:33 +0000
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
 <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
Message-ID: <b2377d2c-e061-fccd-c31d-589cba3ab1b6@huawei.com>

On 10/01/2022 17:36, Ian Rogers wrote:
> I think you are asking to squash:
> https://lore.kernel.org/lkml/20220105061351.120843-8-irogers at google.com/
> into this change. 

That's the general idea.

 > There are other similar related changes that may
 > also be squashed. The changes are trying to introduce a new API and
 > then add changes to switch over to using it. This is with a view to
 > making bisection easier, have each change only do 1 thing and so on. I
 > believe the format of the patches is house style, but it is fine to
 > squash changes together too. Having sent patches to Arnaldo and having
 > had them split I'm reluctant to do a v5 with them squashed without him
 > expressing a preference.
 >

I don't feel so strongly. But I do think that ability to review should 
take preference to providing simple bisections.

Anyway, I'll stop talking and actually have a look.

Cheers,
John


From paulmck at kernel.org  Mon Jan 10 10:01:26 2022
From: paulmck at kernel.org (Paul E. McKenney)
Date: Mon, 10 Jan 2022 10:01:26 -0800
Subject: [PATCH v4 2/2] Documentation: core-api: entry: Add comments
 about nesting
In-Reply-To: <20220110105044.94423-2-nsaenzju@redhat.com>
References: <20220110105044.94423-1-nsaenzju@redhat.com>
 <20220110105044.94423-2-nsaenzju@redhat.com>
Message-ID: <20220110180126.GF947480@paulmck-ThinkPad-P17-Gen-1>

On Mon, Jan 10, 2022 at 11:50:44AM +0100, Nicolas Saenz Julienne wrote:
> The topic of nesting and reentrancy in the context of early entry code
> hasn't been addressed so far. So do it.
> 
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>

Reviewed-by: Paul E. McKenney <paulmck at kernel.org>

> ---
> 
> Changes since v3:
>  - Introduce Paul's rewording suggestions
> 
>  Documentation/core-api/entry.rst | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/Documentation/core-api/entry.rst b/Documentation/core-api/entry.rst
> index c6f8e22c88fe..e12f22ab33c7 100644
> --- a/Documentation/core-api/entry.rst
> +++ b/Documentation/core-api/entry.rst
> @@ -105,6 +105,8 @@ has to do extra work between the various steps. In such cases it has to
>  ensure that enter_from_user_mode() is called first on entry and
>  exit_to_user_mode() is called last on exit.
>  
> +Do not nest syscalls. Nested systcalls will cause RCU and/or context tracking
> +to print a warning.
>  
>  KVM
>  ---
> @@ -121,6 +123,8 @@ Task work handling is done separately for guest at the boundary of the
>  vcpu_run() loop via xfer_to_guest_mode_handle_work() which is a subset of
>  the work handled on return to user space.
>  
> +Do not nest KVM entry/exit transitions because doing so is nonsensical.
> +
>  Interrupts and regular exceptions
>  ---------------------------------
>  
> @@ -180,6 +184,16 @@ before it handles soft interrupts, whose handlers must run in BH context rather
>  than irq-disabled context. In addition, irqentry_exit() might schedule, which
>  also requires that HARDIRQ_OFFSET has been removed from the preemption count.
>  
> +Even though interrupt handlers are expected to run with local interrupts
> +disabled, interrupt nesting is common from an entry/exit perspective. For
> +example, softirq handling happens within an irqentry_{enter,exit}() block with
> +local interrupts enabled. Also, although uncommon, nothing prevents an
> +interrupt handler from re-enabling interrupts.
> +
> +Interrupt entry/exit code doesn't strictly need to handle reentrancy, since it
> +runs with local interrupts disabled. But NMIs can happen anytime, and a lot of
> +the entry code is shared between the two.
> +
>  NMI and NMI-like exceptions
>  ---------------------------
>  
> @@ -259,3 +273,7 @@ and for e.g. a debug exception it can look like this:
>  
>  There is no combined irqentry_nmi_if_kernel() function available as the
>  above cannot be handled in an exception-agnostic way.
> +
> +NMIs can happen in any context. For example, an NMI-like exception triggered
> +while handling an NMI. So NMI entry code has to be reentrant and state updates
> +need to handle nesting.
> -- 
> 2.34.1
> 


From alyssa.rosenzweig at collabora.com  Mon Jan 10 10:13:30 2022
From: alyssa.rosenzweig at collabora.com (Alyssa Rosenzweig)
Date: Mon, 10 Jan 2022 13:13:30 -0500
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
Message-ID: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>

Set a mysterious chicken bit in the MT8192 clock driver (!) to get the
Mali GPU on MT8192 to work. This workaround is from the downstream Mali
driver shipped in ChromeOS. The change there is unsuitable for mainline
but good as a reference for the hardware behaviour:

https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5

That links to an internal Google issue tracker which I assume has more
information on the bug. I would appreciate if someone from Google or
MediaTek could explain what this change actually does and why it's
necessary on MT8192.

At any rate, this register logically belongs to the MT8192 "infra" clock
device, so it makes sense to set it there too. This avoids adding any
platform-specific hacks to the 3D driver, either mainline (Panfrost) or
legacy (kbase).

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Cc: Nick Fan <Nick.Fan at mediatek.com>
Cc: Nicolas Boichat <drinkcat at chromium.org>
---
 drivers/clk/mediatek/clk-mt8192.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
index cbc7c6dbe0f4..e3673494d08d 100644
--- a/drivers/clk/mediatek/clk-mt8192.c
+++ b/drivers/clk/mediatek/clk-mt8192.c
@@ -1179,6 +1179,10 @@ static const struct mtk_pll_data plls[] = {
 
 static struct clk_onecell_data *top_clk_data;
 
+/* Control registers in the infra block used to set a chicken bit */
+#define INFRA_CTRL 0x290
+#define INFRA_CTRL_DISABLE_MFG2ACP BIT(9)
+
 static void clk_mt8192_top_init_early(struct device_node *node)
 {
 	int i;
@@ -1224,6 +1228,29 @@ static int clk_mt8192_top_probe(struct platform_device *pdev)
 	return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
 }
 
+/*
+ * Disable ACP on the infra clock. Setting this quirk is required for 3D to
+ * work correctly. Without this quirk, any work queued to the Mali GPU faults,
+ * for example raising a Data Invalid Fault. This suggests the GPU is failing
+ * to read back the contents of shared CPU/GPU memory correctly, perhaps due to
+ * a MT8192 platform integration issue breaking memory or caches.
+ *
+ * Relevant downstream change:
+ * https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5
+ */
+static int clk_mt8192_infra_disable_mfg2acp(struct platform_device *pdev)
+{
+	void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
+	void __iomem *infra_ctrl = base + INFRA_CTRL;
+
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	writel(readl(infra_ctrl) | INFRA_CTRL_DISABLE_MFG2ACP, infra_ctrl);
+
+	return 0;
+}
+
 static int clk_mt8192_infra_probe(struct platform_device *pdev)
 {
 	struct clk_onecell_data *clk_data;
@@ -1238,6 +1265,10 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
 	if (r)
 		return r;
 
+	r = clk_mt8192_infra_disable_mfg2acp(pdev);
+	if (r)
+		return r;
+
 	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 }
 
-- 
2.30.2



From wells.lu at sunplus.com  Mon Jan 10 10:17:09 2022
From: wells.lu at sunplus.com (=?utf-8?B?V2VsbHMgTHUg5ZGC6Iqz6aiw?=)
Date: Mon, 10 Jan 2022 18:17:09 +0000
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com> 
Message-ID: <0f6a382cd66d4d5d84201da0a29145a3@sphcmbx02.sunplus.com.tw>

Hi Andy,

Could you please answer my questions in previous mail?
I need your answers to proceed submission.

Sorry, I am not sure if my previous mail is lost or you are busy.


Best regards,

Wells Lu

Smart Computing Program
Home Entertainment Business Unit
Sunplus Technology Co., Ltd.
19, Innovation 1st Road,
Science-based Industrial Park
Hsin-Chu, Taiwan 300
TEL?886-3-5786005 ext. 2580


> 
> Hi Andy,
> 
> Thanks a lot for your review.
> 
> 
> Please see my answers below:
> 
> 
> > >
> > > Add driver for Sunplus SP7021 SoC.
> >
> > Thanks for an update, my comments below.
> >
> > ...
> >
> > > +config PINCTRL_SPPCTL
> > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> >
> > Why bool and not tristate?
> 
> Pinctrl driver is selected by many drivers in SP7021 platform.
> We never build it as a module, but build-in to kernel.
> So we use "bool".
> 
> Should we set it to tristate?
> 
> 
> >
> > > +       depends on SOC_SP7021
> > > +       depends on OF && HAS_IOMEM
> >
> > ...
> >
> > > +#include <linux/of.h>
> > > +#include <linux/of_device.h>
> >
> > > +#include <linux/pinctrl/pinconf.h>
> > > +#include <linux/pinctrl/pinconf-generic.h> #include
> > > +<linux/pinctrl/pinmux.h>
> >
> > Can you move this group...
> >
> > > +#include <linux/platform_device.h>
> > > +#include <linux/seq_file.h>
> > > +#include <linux/slab.h>
> >
> > ...to be somewhere here?
> 
> Yes, I'll move it next patch.
> 
> 
> > > +#include <dt-bindings/pinctrl/sppctl-sp7021.h>
> >
> > ...
> >
> > > +/* inline functions */
> >
> > Useless.
> 
> I'll remove all this kind of comments next patch.
> 
> 
> > ...
> >
> > > +       mask = GENMASK(bit_sz - 1, 0) << (bit_off + SPPCTL_GROUP_PINMUX_MASK_SHIFT);
> > > +       reg = mask | (val << bit_off);
> >
> > Now you may do one step forward:
> >
> >        mask = GENMASK(bit_sz - 1, 0) << SPPCTL_GROUP_PINMUX_MASK_SHIFT;
> >        reg = (val | mask) << bit_off;
> 
> I'll revise these statements as code you've shared.
> 
> 
> > ...
> >
> > > +static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset,
> > > +                                   enum mux_first_reg first, enum
> > > +mux_master_reg master) {
> > > +       struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
> > > +       u32 reg_off, bit_off, reg;
> > > +       int val;
> > > +
> > > +       /* FIRST register */
> > > +       if (first != mux_f_keep) {
> > > +               /*
> > > +                * Refer to descriptions of function sppctl_first_get()
> > > +                * for usage of FIRST registers.
> > > +                */
> > > +               reg_off = (offset / 32) * 4;
> > > +               bit_off = offset % 32;
> > > +
> > > +               reg = sppctl_first_readl(spp_gchip, reg_off);
> > > +               val = (reg & BIT(bit_off)) ? 1 : 0;
> >
> > > +               if (first != val) {
> >
> > first is enum, val is int, are you sure it's good to compare like this?
> 
> No, it is always not good to compare different type of things.
> I'll modify code as shown below:
> 
> 	enum mux_first_reg val;
> 		:
> 		:
> 	val = (reg & BIT(bit_off)) ? mux_f_gpio : mux_f_mux;
> 
> 
> > > +                       if (first == mux_f_gpio)
> > > +                               reg |= BIT(bit_off);
> > > +                       else
> > > +                               reg &= ~BIT(bit_off);
> >
> >
> > Since you operate against enums it's better to use switch-case.
> 
> I'll modify code as shown below:
> 
> 			if (first != val)
> 				switch (first) {
> 				case mux_f_gpio:
> 					reg |= BIT(bit_off);
> 					sppctl_first_writel(spp_gchip, reg, reg_off);
> 					break;
> 
> 				case mux_f_mux:
> 					reg &= ~BIT(bit_off);
> 					sppctl_first_writel(spp_gchip, reg, reg_off);
> 					break;
> 
> 				case mux_f_keep:
> 					break;
> 				}
> 
> 
> > > +                       sppctl_first_writel(spp_gchip, reg, reg_off);
> > > +               }
> > > +       }
> > > +
> > > +       /* MASTER register */
> > > +       if (master != mux_m_keep) {
> > > +               /*
> > > +                * Refer to descriptions of function sppctl_master_get()
> > > +                * for usage of MASTER registers.
> > > +                */
> > > +               reg_off = (offset / 16) * 4;
> > > +               bit_off = offset % 16;
> > > +
> > > +               reg = BIT(bit_off) << SPPCTL_MASTER_MASK_SHIFT;
> > > +               if (master == mux_m_gpio)
> > > +                       reg |= BIT(bit_off);
> > > +               sppctl_gpio_master_writel(spp_gchip, reg, reg_off);
> > > +       }
> > > +}
> >
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
> >
> > Perhaps a macro with definitive name?
> 
> I'll define two new macros:
> 
> #define SPPCTL_MOON_REG_MASK_SHIFT		16
> #define SPPCTL_SET_MOON_REG_BIT(bit)		(BIT(bit + SPPCTL_MOON_REG_MASK_SHIFT) |
> BIT(bit))
> #define SPPCTL_CLR_MOON_REG_BIT(bit)		BIT(bit + SPPCTL_MOON_REG_MASK_SHIFT)
> 
> And modify code as shown below:
> 
> 
> 			reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> 
> 
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
> > > +       if (val)
> > > +               reg |= BIT(bit_off);
> >
> > You can use it even here:
> >
> > if (val)
> >   reg = MY_MACRO(bit_off)
> > else
> >   reg = BIT(...) // perhaps another macro
> 
> I'll modify code as shown below:
> 
> 	if (val)
> 		reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> 	else
> 		reg = SPPCTL_CLR_MOON_REG_BIT(bit_off);
> 
> 
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
> >
> > Ditto.
> 
> I'll modify code as shown below:
> 
> 			reg = SPPCTL_CLR_MOON_REG_BIT(bit_off);
> 
> 
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) | BIT(bit_off);
> >
> > Ditto.
> 
> I'll modify code as shown shown below:
> 
> 			reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> 
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
> > > +       if (val)
> > > +               reg |= BIT(bit_off);
> >
> > Ditto.
> 
> I'll modify code as shown below:
> 
> 	if (val)
> 		reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> 	else
> 		reg = SPPCTL_CLR_MOON_REG_BIT(bit_off);
> 
> 
> > ...
> >
> > > +       reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT);
> > > +       if (val)
> > > +               reg |= BIT(bit_off);
> >
> > Ditto.
> 
> I'll modify code as shown in above case.
> 
> 
> > And looking into repetition, you may even have a helper which does
> > this conditional
> >
> > static inline u32 sppctl_...()
> > {
> >   ...
> >   return reg;
> > }
> 
> I'll add an inline function as shown below:
> 
> static inline u32 sppctl_prep_moon_reg(u32 bit_off, int val) {
> 	if (val)
> 		return SPPCTL_SET_MOON_REG_BIT(bit_off);
> 	else
> 		return SPPCTL_CLR_MOON_REG_BIT(bit_off); }
> 
> And replace all "if (val) ... " with the inline function.
> 
> 
> > ...
> >
> > > +       int ret = 0;
> >
> > Redundant variable, return directly.
> 
> I'll remove the redundant variable.
> 
> 
> > > +       switch (param) {
> > > +       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
> > > +               /*
> > > +                * Upper 16-bit word is mask. Lower 16-bit word is value.
> > > +                * Refer to descriptions of function sppctl_master_get().
> > > +                */
> > > +               reg_off = (offset / 16) * 4;
> > > +               bit_off = offset % 16;
> > > +               reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) |
> > > + BIT(bit_off);
> >
> > As I commented above use helper function which takes offset as input
> > and returns you reg and reg_off.
> 
> I'll modify code as shown below:
> 
> 		reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> 
> Sorry, I don't understand your meaning "returns you reg and reg_off".
> The helper macro will return reg but not reg_off, right?
> 
> 
> > > +               sppctl_gpio_od_writel(spp_gchip, reg, reg_off);
> > > +               break;
> > > +
> > > +       case PIN_CONFIG_INPUT_ENABLE:
> > > +               break;
> > > +
> > > +       case PIN_CONFIG_OUTPUT:
> > > +               ret = sppctl_gpio_direction_output(chip, offset, 0);
> > > +               break;
> > > +
> > > +       case PIN_CONFIG_PERSIST_STATE:
> > > +               ret = -ENOTSUPP;
> > > +               break;
> > > +
> > > +       default:
> > > +               ret = -EINVAL;
> > > +               break;
> > > +       }
> > > +
> > > +       return ret;
> > > +}
> >
> > ...
> >
> > > +       if (!of_find_property(pdev->dev.of_node, "gpio-controller", NULL))
> > > +               return dev_err_probe(&pdev->dev, -EINVAL, "Not a
> > > + gpio-controller!\n");
> >
> > Why do you need this check for?
> 
> By referring to other pinctrl driver, we check if property "gpio-controller" exists?
> Will core help us check this?
> Is this redundant?
> 
> 
> > ...
> >
> > > +       gchip->can_sleep        = 0;
> >
> > Besides that it's already cleared, the type here is boolean.
> 
> I'll remove the unnecessary assignment as the whole structure is initialized to 0.
> Should I also remove the assignment:
> 
> 		gchip->base 		= 0;
> 
> 
> > ...
> >
> > > +/* pinconf operations */
> >
> > Any value of this comment?
> 
> I'll remove it.
> 
> 
> > > +static int sppctl_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
> > > +                                unsigned long *config) {
> > > +       struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
> > > +       unsigned int param = pinconf_to_config_param(*config);
> >
> > > +       unsigned int arg = 0;
> >
> > Move assignment to where it actually makes sense.
> 
> I'll move it as shown below:
> 
> 		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
> 			if (!sppctl_gpio_output_od_get(&pctl->spp_gchip->chip, pin))
> 				return -EINVAL;
> 			arg = 0;
> 			break;
> 
> 
> > > +       switch (param) {
> > > +       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
> > > +               if (!sppctl_gpio_output_od_get(&pctl->spp_gchip->chip, pin))
> > > +                       return -EINVAL;
> > > +               break;
> > > +
> > > +       case PIN_CONFIG_OUTPUT:
> > > +               if (!sppctl_first_get(&pctl->spp_gchip->chip, pin))
> > > +                       return -EINVAL;
> > > +               if (!sppctl_master_get(&pctl->spp_gchip->chip, pin))
> > > +                       return -EINVAL;
> > > +               if (sppctl_gpio_get_direction(&pctl->spp_gchip->chip, pin))
> > > +                       return -EINVAL;
> > > +               arg = sppctl_gpio_get(&pctl->spp_gchip->chip, pin);
> > > +               break;
> > > +
> > > +       default:
> > > +               return -EOPNOTSUPP;
> > > +       }
> > > +       *config = pinconf_to_config_packed(param, arg);
> > > +
> > > +       return 0;
> > > +}
> >
> > ...
> >
> > > +       switch (f->type) {
> > > +       case pinmux_type_fpmx:  /* fully-pinmux */
> >
> > Why do you need these comments?
> > Shouldn't you rather to kernel doc your enum entries?
> 
> I'll remove the comments.
> Could you please tell me where I should write and put my kernel doc?
> Is there any examples I can refer to?
> 
> 
> > > +               *num_groups = sppctl_pmux_list_sz;
> > > +               *groups = sppctl_pmux_list_s;
> > > +               break;
> > > +
> > > +       case pinmux_type_grp:   /* group-pinmux */
> > > +               if (!f->grps)
> > > +                       break;
> > > +
> > > +               *num_groups = f->gnum;
> > > +               for (i = 0; i < pctl->unq_grps_sz; i++)
> > > +                       if (pctl->g2fp_maps[i].f_idx == selector)
> > > +                               break;
> > > +               *groups = &pctl->unq_grps[i];
> > > +               break;
> >
> > > +       }
> >
> > > +/** sppctl_fully_pinmux_conv - Convert GPIO# to fully-pinmux
> > > +control-field setting
> > > + *
> > > + * Each fully-pinmux function can be mapped to any of GPIO 8 ~ 71
> > > +by
> > > + * settings its control-field. Refer to following table:
> > > + *
> > > + * control-field |  GPIO
> > > + * --------------+--------
> > > + *        0      |  No map
> > > + *        1      |    8
> > > + *        2      |    9
> > > + *        3      |   10
> > > + *        :      |    :
> > > + *       65      |   71
> > > + */
> > > +static inline int sppctl_fully_pinmux_conv(unsigned int offset) {
> > > +       return (offset < 8) ? 0 : offset - 7; }
> >
> > ...
> >
> > > +static const struct pinmux_ops sppctl_pinmux_ops = {
> > > +       .get_functions_count = sppctl_get_functions_count,
> > > +       .get_function_name   = sppctl_get_function_name,
> > > +       .get_function_groups = sppctl_get_function_groups,
> > > +       .set_mux             = sppctl_set_mux,
> > > +       .gpio_request_enable = sppctl_gpio_request_enable,
> >
> > > +       .strict              = true
> >
> > + Comma.
> 
> I'll add a comma right after 'true'.
> 
> 
> > > +};
> >
> > ...
> >
> > > +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev,
> > > +struct device_node
> > *np_config,
> > > +                                struct pinctrl_map **map, unsigned
> > > +int *num_maps) {
> > > +       struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
> > > +       int nmG = of_property_count_strings(np_config, "groups");
> > > +       const struct sppctl_func *f = NULL;
> > > +       u8 pin_num, pin_type, pin_func;
> > > +       struct device_node *parent;
> > > +       unsigned long *configs;
> > > +       struct property *prop;
> > > +       const char *s_f, *s_g;
> > > +
> > > +       const __be32 *list;
> > > +       u32 dt_pin, dt_fun;
> > > +       int i, size = 0;
> > > +
> > > +       list = of_get_property(np_config, "sunplus,pins", &size);
> > > +
> > > +       if (nmG <= 0)
> > > +               nmG = 0;
> > > +
> > > +       parent = of_get_parent(np_config);
> > > +       *num_maps = size / sizeof(*list);
> > > +
> > > +       /*
> > > +        * Process property:
> > > +        *     sunplus,pins = < u32 u32 u32 ... >;
> > > +        *
> > > +        * Each 32-bit integer defines a individual pin in which:
> > > +        *
> > > +        *   Bit 32~24: defines GPIO pin number. Its range is 0 ~ 98.
> > > +        *   Bit 23~16: defines types: (1) fully-pinmux pins
> > > +        *                             (2) IO processor pins
> > > +        *                             (3) digital GPIO pins
> > > +        *   Bit 15~8:  defines pins of peripherals (which are defined in
> > > +        *              'include/dt-binging/pinctrl/sppctl.h').
> > > +        *   Bit 7~0:   defines types or initial-state of digital GPIO pins.
> > > +        */
> > > +       for (i = 0; i < (*num_maps); i++) {
> > > +               dt_pin = be32_to_cpu(list[i]);
> > > +               pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
> > > +
> > > +               /* Check if out of range? */
> > > +               if (pin_num >= sppctl_pins_all_sz) {
> > > +                       dev_err(pctldev->dev, "Invalid pin property
> > > + at index %d
> > (0x%08x)\n",
> > > +                               i, dt_pin);
> > > +                       return -EINVAL;
> > > +               }
> > > +       }
> > > +
> > > +       *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
> > > +       for (i = 0; i < (*num_maps); i++) {
> > > +               dt_pin = be32_to_cpu(list[i]);
> > > +               pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
> > > +               pin_type = FIELD_GET(GENMASK(23, 16), dt_pin);
> > > +               pin_func = FIELD_GET(GENMASK(15, 8), dt_pin);
> > > +               (*map)[i].name = parent->name;
> > > +
> > > +               if (pin_type == SPPCTL_PCTL_G_GPIO) {
> > > +                       /* A digital GPIO pin */
> > > +                       (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
> > > +                       (*map)[i].data.configs.num_configs = 1;
> > > +                       (*map)[i].data.configs.group_or_pin =
> > > + pin_get_name(pctldev,
> > pin_num);
> > > +                       configs = kmalloc(sizeof(*configs), GFP_KERNEL);
> > > +                       *configs = FIELD_GET(GENMASK(7, 0), dt_pin);
> > > +                       (*map)[i].data.configs.configs = configs;
> > > +
> > > +                       dev_dbg(pctldev->dev, "%s: GPIO (%s)\n",
> > > +                               (*map)[i].data.configs.group_or_pin,
> > > +                               (*configs & (SPPCTL_PCTL_L_OUT | SPPCTL_PCTL_L_OU1)) ?
> > > +                               "OUT" : "IN");
> > > +               } else if (pin_type == SPPCTL_PCTL_G_IOPP) {
> > > +                       /* A IO Processor (IOP) pin */
> > > +                       (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
> > > +                       (*map)[i].data.configs.num_configs = 1;
> > > +                       (*map)[i].data.configs.group_or_pin =
> > > + pin_get_name(pctldev,
> > pin_num);
> > > +                       configs = kmalloc(sizeof(*configs), GFP_KERNEL);
> > > +                       *configs = SPPCTL_IOP_CONFIGS;
> > > +                       (*map)[i].data.configs.configs = configs;
> > > +
> > > +                       dev_dbg(pctldev->dev, "%s: IOP\n",
> > > +                               (*map)[i].data.configs.group_or_pin);
> > > +               } else {
> > > +                       /* A fully-pinmux pin */
> > > +                       (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
> > > +                       (*map)[i].data.mux.function =
> sppctl_list_funcs[pin_func].name;
> > > +                       (*map)[i].data.mux.group =
> > > + pin_get_name(pctldev, pin_num);
> > > +
> > > +                       dev_dbg(pctldev->dev, "%s: %s\n", (*map)[i].data.mux.group,
> > > +                               (*map)[i].data.mux.function);
> > > +               }
> > > +       }
> > > +
> > > +       /*
> > > +        * Process properties:
> > > +        *     function = "xxx";
> > > +        *     groups = "yyy";
> > > +        */
> > > +       if (nmG > 0 && of_property_read_string(np_config, "function", &s_f) == 0)
> {
> > > +               of_property_for_each_string(np_config, "groups", prop, s_g) {
> > > +                       (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
> > > +                       (*map)[*num_maps].data.mux.function = s_f;
> > > +                       (*map)[*num_maps].data.mux.group = s_g;
> > > +                       (*num_maps)++;
> > > +
> > > +                       dev_dbg(pctldev->dev, "%s: %s\n", s_f, s_g);
> > > +               }
> > > +       }
> > > +
> > > +       /*
> > > +        * Process property:
> > > +        *     sunplus,zero_func = < u32 u32 u32 ...>
> > > +        */
> > > +       list = of_get_property(np_config, "sunplus,zero_func", &size);
> > > +       if (list) {
> > > +               for (i = 0; i < (size / sizeof(*list)); i++) {
> > > +                       dt_fun = be32_to_cpu(list[i]);
> > > +                       if (dt_fun >= sppctl_list_funcs_sz) {
> > > +                               dev_err(pctldev->dev, "Zero-func %d out of range!\n",
> > > +                                       dt_fun);
> > > +                               continue;
> > > +                       }
> > > +
> > > +                       f = &sppctl_list_funcs[dt_fun];
> > > +                       switch (f->type) {
> > > +                       case pinmux_type_fpmx:
> > > +                               sppctl_func_set(pctl, dt_fun, 0);
> > > +                               dev_dbg(pctldev->dev, "%s: No map\n", f->name);
> > > +                               break;
> > > +
> > > +                       case pinmux_type_grp:
> > > +                               sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, 0);
> > > +                               dev_dbg(pctldev->dev, "%s: No map\n", f->name);
> > > +                               break;
> > > +
> > > +                       default:
> > > +                               dev_err(pctldev->dev, "Wrong zero-group: %d (%s)\n",
> > > +                                       dt_fun, f->name);
> > > +                               break;
> > > +                       }
> > > +               }
> > > +       }
> > > +
> > > +       of_node_put(parent);
> > > +       dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps);
> > > +       return 0;
> > > +}
> >
> > ...
> >
> > > +       sppctl->g2fp_maps = devm_kcalloc(&pdev->dev, sppctl->unq_grps_sz + 1,
> > > +                                        sizeof(*sppctl->g2fp_maps), GFP_KERNEL);
> > > +       if (!sppctl->g2fp_maps)
> > > +               return -ENOMEM;
> >
> > > +       /*
> > > +        * Check only product of n and size of the second devm_kcalloc()
> > > +        * because its size is the largest of the two.
> > > +        */
> > > +       if (unlikely(check_mul_overflow(sppctl->unq_grps_sz + 1,
> > > +                                       sizeof(*sppctl->g2fp_maps), &prod)))
> > > +               return -EINVAL;
> >
> > What the point to check it after? What the point to use it with
> > kcalloc()? Please, do your homework, i.e. read the code which implements that.
> 
> I'll remove the "if (unlikely(check_mul_overflow()...) return -EINVAL" statement next
> patch.
> 
> I think I mis-understood your previous comment.
> I thought I was asked to add check_mul_overflow() function for devm_kcalloc(...).
> Sorry for strange codes.
> 
> I should study devm_kcalloc() furthermore. Now I know devm_kcalloc(...) does
> multiplication overflow check for us. That's why we need to devm_kzalloc() with
> devm_kcalloc().
> 
> One question left in my mind is, in this case, even we have 10,000 pins, we will never
> get overflow. It looks not so necessary.
> 
> 
> > ...
> >
> > > +       struct device_node *np = of_node_get(pdev->dev.of_node);
> >
> > What's the role of of_node_get()?
> 
> I'll remove the unused codes.
> I think it was used to check if OF node exists.
> 
> 
> > ...
> >
> > > +       /* Initialize pctl_desc */
> >
> > Useless. Drop all useless comments like this from the code.
> 
> I'll remove all this kind of comments.
> 
> 
> > ...
> >
> > > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech.");
> >
> > Is it useful?
> 
> I think yes. It tells users that Pinctrl driver has probed successfully.
> If no this message, users don't know if Pinctrl driver has probed
> successfully or not. For example, because that dts node of pinctrl is
> "disabled" or Pinctrl driver is even not enabled.
> 
> Can I keep this?
> 
> 
> > ...
> >
> > > +#ifndef __SPPCTL_H__
> > > +#define __SPPCTL_H__
> > > +
> > > +#include <linux/bits.h>
> > > +#include <linux/gpio/driver.h>
> >
> > > +#include <linux/kernel.h>
> > > +#include <linux/pinctrl/pinctrl.h>
> > > +#include <linux/spinlock.h>
> >
> > types.h is missed.
> 
> I'll add the header file next patch.
> 
> 
> > ...
> >
> > > +/** enum mux_first_reg - define modes of FIRST register accesses
> >
> > Fix the multi-line comment style. You mentioned you fixed, but seems not (not in
> all places).
> 
> I'll fix it.
> 
> Sorry for my mistake.
> I modified multi-line comments for all.
> Later, I added more comments. But I
> forgot to switch back from network mode.
> 
> 
> > > + *    - mux_f_mux:  Select the pin to a fully-pinmux pin
> > > + *    - mux_f_gpio: Select the pin to a GPIO or IOP pin
> > > + *    - mux_f_keep: Don't change (keep intact)
> > > + */
> > > +enum mux_first_reg {
> > > +       mux_f_mux = 0,          /* select fully-pinmux       */
> > > +       mux_f_gpio = 1,         /* select GPIO or IOP pinmux */
> > > +       mux_f_keep = 2,         /* keep no change            */
> > > +};
> >
> >
> > > +struct sppctl_gpio_chip {
> > > +       void __iomem *gpioxt_base;      /* MASTER, OE, OUT, IN, I_INV, O_INV, OD */
> > > +       void __iomem *first_base;       /* GPIO_FIRST                            */
> > > +
> > > +       struct gpio_chip chip;
> > > +       spinlock_t lock;                /* lock for accessing OE register        */
> > > +};
> >
> > Why is this in the header?
> 
> Do you mean I need to move this "struct sppctl_gpio_chip { ... }" declaration
> to c file because it is only used by the c file?
> 
> 
> > ...
> >
> > > +/* SP7021 Pin Controller Driver.
> > > + * Copyright (C) Sunplus Tech / Tibbo Tech.
> > > + */
> >
> > Multi-line comments.
> 
> I'll fix it.
> Sorry for mistake. I overlooked the file header.
> 
> 
> > I stopped here, please read my comments for previous versions and here and try your
> best.
> 
> I read all your comments many times.
> I'll do my best to address all comments.
> Sorry for mis-understand some comments.
> 
> 
> Your previous comments:
> > > > > +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct
> device_node *np_config,
> > > > > +                                struct pinctrl_map **map, unsigned
> > > > > +int *num_maps) {
> > > >
> > > > Looking into this rather quite big function why you can't use what pin control
> core provides?
> > >
> > > No, we cannot use functions pin-control core provides.
> > > Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
> > > We have more explanation there.
> >
> > Fine, can you reuse some library functions, etc? Please, consider refactoring to
> make it more readable.
> 
> Could you please share me your idea about "refactoring"?
> Or could you give me some hints?
> I think many times, but have no idea about refactoring.
> 
> 
> > --
> > With Best Regards,
> > Andy Shevchenko

From pr-tracker-bot at kernel.org  Mon Jan 10 10:27:55 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:27:55 +0000
Subject: [GIT PULL] arm64 updates for 5.17
In-Reply-To: <20220106185501.1480075-1-catalin.marinas@arm.com>
References: <20220106185501.1480075-1-catalin.marinas@arm.com>
Message-ID: <164183927535.9673.16814182667735611453.pr-tracker-bot@kernel.org>

The pull request you sent on Thu,  6 Jan 2022 18:55:01 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-upstream

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9b9e211360044c12d7738973c944d6f300134881

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Mon Jan 10 10:28:03 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:28:03 +0000
Subject: [GIT PULL 5/5] SoC: Add support for StarFive JH7100 RISC-V SoC
In-Reply-To: <CAK8P3a1DkNq+SxXdvFnQMkH7BaNQ-=ug_XjAAD8_jw3-eX-wnQ@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <CAK8P3a1DkNq+SxXdvFnQMkH7BaNQ-=ug_XjAAD8_jw3-eX-wnQ@mail.gmail.com>
Message-ID: <164183928307.9673.8260950414473469873.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 23 Dec 2021 22:37:45 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/newsoc-5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/bb4ed26e7e837ca3034d4105491436d54c430038

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Mon Jan 10 10:28:02 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:28:02 +0000
Subject: [GIT PULL 3/5] ARM: SoC driver updates for v5.17
In-Reply-To: <CAK8P3a2WjTojdOwr-k6HHQuBXMHU-2wRC3rQacQx8SL6W2cK-g@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <CAK8P3a2WjTojdOwr-k6HHQuBXMHU-2wRC3rQacQx8SL6W2cK-g@mail.gmail.com>
Message-ID: <164183928284.9673.17371954660531165425.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 23 Dec 2021 22:34:17 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/drivers-5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e85195d5bf8979f6db3f12cf8f1294887bf6b037

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Mon Jan 10 10:28:02 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:28:02 +0000
Subject: [GIT PULL 1/5] ARM: SoC updates for v5.17
In-Reply-To: <CAK8P3a2u88x0USAVHe6YeNCbLV6pvOPytHs4Bo4ma1avsq+ojA@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <CAK8P3a2u88x0USAVHe6YeNCbLV6pvOPytHs4Bo4ma1avsq+ojA@mail.gmail.com>
Message-ID: <164183928261.9673.8780484435703411702.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 23 Dec 2021 22:32:44 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/1135ec008ef3745cd1cee5bc543cfe48427c22a9

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Mon Jan 10 10:28:02 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:28:02 +0000
Subject: [GIT PULL 2/5] ARM: defconfig updates for 5.17
In-Reply-To: <CAK8P3a3cvBGO9e=34S9o0ConOTHJ_rLsRcGa0J0k0-PGChmJwA@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <CAK8P3a3cvBGO9e=34S9o0ConOTHJ_rLsRcGa0J0k0-PGChmJwA@mail.gmail.com>
Message-ID: <164183928273.9673.11458523125742457099.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 23 Dec 2021 22:33:26 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/defconfig-5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/0dca3c5e017ab81ebe21eb9096f657c45a6b17a4

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From pr-tracker-bot at kernel.org  Mon Jan 10 10:28:02 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Mon, 10 Jan 2022 18:28:02 +0000
Subject: [GIT PULL 4/5] ARM: SoC devicetree changes for v5.17
In-Reply-To: <CAK8P3a23RO3B4be2x_gZV5sYy2JiAgPMFMO5QE8wQ9gLEa8ZVw@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <CAK8P3a23RO3B4be2x_gZV5sYy2JiAgPMFMO5QE8wQ9gLEa8ZVw@mail.gmail.com>
Message-ID: <164183928295.9673.11763370272529520512.pr-tracker-bot@kernel.org>

The pull request you sent on Thu, 23 Dec 2021 22:35:11 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/dt-5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/aca48b2dd1e70bb1be23bf5eb2fa50da9f6c2579

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From lkp at intel.com  Mon Jan 10 10:29:00 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 02:29:00 +0800
Subject: [xilinx-xlnx:master 156/279] drivers/usb/dwc3/dwc3-xilinx.c:509:6:
 warning: no previous prototype for 'dwc3_xilinx_wakeup_capable'
Message-ID: <202201110205.SGifrSgE-lkp@intel.com>

Hi Piyush,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   2f2b644138b37e22206a72377828c457f3f4d590
commit: 6e383f53627b34b9aa1f149720de25f55b199d37 [156/279] usb: dwc3: Added remote wake-up in xilinx glue driver
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20220111/202201110205.SGifrSgE-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/6e383f53627b34b9aa1f149720de25f55b199d37
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 6e383f53627b34b9aa1f149720de25f55b199d37
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/usb/dwc3/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/usb/dwc3/dwc3-xilinx.c:509:6: warning: no previous prototype for 'dwc3_xilinx_wakeup_capable' [-Wmissing-prototypes]
     509 | void dwc3_xilinx_wakeup_capable(struct device *dev, bool wakeup)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~


vim +/dwc3_xilinx_wakeup_capable +509 drivers/usb/dwc3/dwc3-xilinx.c

   507	
   508	/* xilinx feature support functions */
 > 509	void dwc3_xilinx_wakeup_capable(struct device *dev, bool wakeup)
   510	{
   511		struct device_node *node = of_node_get(dev->parent->of_node);
   512	
   513		/* check for valid parent node */
   514		while (node) {
   515			if (of_device_is_compatible(node, "xlnx,zynqmp-dwc3") ||
   516			    of_device_is_compatible(node, "xlnx,versal-dwc3"))
   517				break;
   518	
   519			/* get the next parent node */
   520			node = of_get_next_parent(node);
   521		}
   522	
   523		if (node) {
   524			struct platform_device *pdev_parent;
   525			struct dwc3_xlnx *priv_data;
   526	
   527			pdev_parent = of_find_device_by_node(node);
   528			priv_data = platform_get_drvdata(pdev_parent);
   529	
   530			/* Set wakeup capable as true or false */
   531			priv_data->wakeup_capable = wakeup;
   532	
   533			/* Allow D3 state if wakeup capable only */
   534			priv_data->enable_d3_suspend = wakeup;
   535		}
   536	}
   537	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From olof at lixom.net  Mon Jan 10 10:32:52 2022
From: olof at lixom.net (Olof Johansson)
Date: Mon, 10 Jan 2022 10:32:52 -0800
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <CAK8P3a3sBADt4Cu=LGbjHQpQ32O-BtFk1aQFwhL8Ar=M_gj6Xw@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
 <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
 <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>
 <CAK8P3a3sBADt4Cu=LGbjHQpQ32O-BtFk1aQFwhL8Ar=M_gj6Xw@mail.gmail.com>
Message-ID: <CAOesGMjArmB1J7KasjHZRTNXoZvtUXkTOQAyg5yd29qC8PeS9g@mail.gmail.com>

On Tue, Jan 4, 2022 at 5:40 PM Arnd Bergmann <arnd at kernel.org> wrote:
>
> On Tue, Jan 4, 2022 at 7:40 PM Olof Johansson <olof at lixom.net> wrote:
> > On Tue, Jan 4, 2022 at 1:58 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> > > On 12/24/21 9:11 AM, Florian Fainelli wrote:
> > > >
> > > > Should I resend or fix something in those? Thanks!
> > >
> > >
> > > Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
> > > Thanks and happy new year.
> >
> > I'm about to make a pass of merges, likely tomorrow -- I had to get my
> > Honeycomb working again since it hosts all the trees and mailboxes for
> > me.
> >
> > No need to resend at this time.
>
> It's possible that I had accidentally merged them in the end but tagged
> the branch without those merge commits, so have a look if it's in there.

Yeah, it looks like there were a few merges not part of the pull
request (Linus just merged them, so these showed up in
regen-contents). I'll fold them into arm/late.

arm/defconfig
        broadcom/defconfig [sign: Y Arnd Bergmann <arnd at arndb.de>]
                https://github.com/Broadcom/stblinux
tags/arm-soc/for-5.17/defconfig
        broadcom/defconfig64 [sign: Y Arnd Bergmann <arnd at arndb.de>]
                https://github.com/Broadcom/stblinux
tags/arm-soc/for-5.17/defconfig-arm64
        qcom/defconfig [sign: N ]

git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux
tags/qcom-arm64-defconfig-for-5.17
        patch
                ARM: multi_v7_defconfig: Enable drivers for
DragonBoard 410c [sign: N ]


-Olof


From lkp at intel.com  Mon Jan 10 10:39:17 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 02:39:17 +0800
Subject: [v1 03/16] clk: mediatek: Add MT8186 mcusys clock support
In-Reply-To: <20220110134416.5191-4-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-4-chun-jie.chen@mediatek.com>
Message-ID: <202201110231.DNu9pn4H-lkp@intel.com>

Hi Chun-Jie,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next v5.16 next-20220110]
[cannot apply to mbgg-mediatek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: nios2-allyesconfig (https://download.01.org/0day-ci/archive/20220111/202201110231.DNu9pn4H-lkp at intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/d28b64e80990fd336192ccdd31676120bf4e2696
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
        git checkout d28b64e80990fd336192ccdd31676120bf4e2696
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/mediatek/clk-mt8186-mcu.c: In function 'clk_mt8186_mcu_probe':
>> drivers/clk/mediatek/clk-mt8186-mcu.c:74:9: error: implicit declaration of function 'mtk_clk_unregister'; did you mean 'devm_clk_unregister'? [-Werror=implicit-function-declaration]
      74 |         mtk_clk_unregister(clk_data);
         |         ^~~~~~~~~~~~~~~~~~
         |         devm_clk_unregister
   cc1: some warnings being treated as errors


vim +74 drivers/clk/mediatek/clk-mt8186-mcu.c

    48	
    49	static int clk_mt8186_mcu_probe(struct platform_device *pdev)
    50	{
    51		struct clk_onecell_data *clk_data;
    52		struct device_node *node = pdev->dev.of_node;
    53		int r;
    54		void __iomem *base;
    55	
    56		base = devm_platform_ioremap_resource(pdev, 0);
    57		if (IS_ERR(base))
    58			return PTR_ERR(base);
    59	
    60		clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
    61		if (!clk_data)
    62			return -ENOMEM;
    63	
    64		mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
    65					    &mt8186_clk_lock, clk_data);
    66	
    67		r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
    68		if (r)
    69			goto unregister_clk;
    70	
    71		return r;
    72	
    73	unregister_clk:
  > 74		mtk_clk_unregister(clk_data);
    75		mtk_free_clk_data(clk_data);
    76		return r;
    77	}
    78	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andy.shevchenko at gmail.com  Mon Jan 10 10:41:37 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Mon, 10 Jan 2022 20:41:37 +0200
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
Message-ID: <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>

On Tue, Dec 28, 2021 at 5:38 PM Wells Lu ??? <wells.lu at sunplus.com> wrote:

...

> > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> >
> > Why bool and not tristate?
>
> Pinctrl driver is selected by many drivers in SP7021 platform.
> We never build it as a module, but build-in to kernel.
> So we use "bool".
>
> Should we set it to tristate?

You still haven't answered "why", so I can't tell you.

...

> > > +               /*
> > > +                * Upper 16-bit word is mask. Lower 16-bit word is value.
> > > +                * Refer to descriptions of function sppctl_master_get().
> > > +                */
> > > +               reg_off = (offset / 16) * 4;
> > > +               bit_off = offset % 16;
> > > +               reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) |
> > > + BIT(bit_off);
> >
> > As I commented above use helper function which takes offset as input and returns you reg
> > and reg_off.
>
> I'll modify code as shown below:
>
>                 reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
>
> Sorry, I don't understand your meaning "returns you reg and reg_off".
> The helper macro will return reg but not reg_off, right?

Something like (fix types accordingly to your needs):

static inline u32 sppctl_get_reg_and_offset(unsigned int offset, u32 *roff)
{
              u32 boff = offset % 16;
              *roff = (offset / 16) * 4;

               return  MY_COOL_MACRO(boff); // BIT(boff +
SPPCTL_GPIO_MASK_SHIFT) | BIT(boff)
}

    reg = sppctl_get_reg_and_offset(offset, &reg_off);

...

> > > +       if (!of_find_property(pdev->dev.of_node, "gpio-controller", NULL))
> > > +               return dev_err_probe(&pdev->dev, -EINVAL, "Not a
> > > + gpio-controller!\n");
> >
> > Why do you need this check for?
>
> By referring to other pinctrl driver, we check if property "gpio-controller" exists?
> Will core help us check this?
> Is this redundant?

You should answer this question, not me.

...

> Should I also remove the assignment:
>
>                 gchip->base             = 0;

Actually this is a good catch. Why do you use 0 as a base? In the new
code we are supposed to have -1 to be assigned.

...

> > > +       case pinmux_type_fpmx:  /* fully-pinmux */
> >
> > Why do you need these comments?
> > Shouldn't you rather to kernel doc your enum entries?
>
> I'll remove the comments.
> Could you please tell me where I should write and put my kernel doc?
> Is there any examples I can refer to?

In the enum definition you do something like this (and read documentation):

/**
 * enum ...
 * @pinmux_type_fpmx: fully pin muxing
 * @pinmux_type_grp: group pin muxing
 * ...
 */

...

> > > +       if (unlikely(check_mul_overflow(sppctl->unq_grps_sz + 1,
> > > +                                       sizeof(*sppctl->g2fp_maps), &prod)))
> > > +               return -EINVAL;
> >
> > What the point to check it after? What the point to use it with kcalloc()? Please, do your
> > homework, i.e. read the code which implements that.
>
> I'll remove the "if (unlikely(check_mul_overflow()...) return -EINVAL" statement next patch.
>
> I think I mis-understood your previous comment.
> I thought I was asked to add check_mul_overflow() function for devm_kcalloc(...).
> Sorry for strange codes.

There were basically two iterative comments, i.e.
first one suggested adding a check, but second one suggested switching
to kcalloc() API.

> I should study devm_kcalloc() furthermore. Now I know devm_kcalloc(...) does
> multiplication overflow check for us. That's why we need to devm_kzalloc() with
> devm_kcalloc().
>
> One question left in my mind is, in this case, even we have 10,000 pins,
> we will never get overflow. It looks not so necessary.

But it's not your issue, the kcalloc() does it for you for the good sake.

...

> > > +       struct device_node *np = of_node_get(pdev->dev.of_node);
> >
> > What's the role of of_node_get()?
>
> I'll remove the unused codes.
> I think it was used to check if OF node exists.

And if it doesn't, what is the difference?

You are the author of this code, please be prepared to explain every line in it.

...

> > > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo Tech.");
> >
> > Is it useful?
>
> I think yes. It tells users that Pinctrl driver has probed successfully.
> If no this message, users don't know if Pinctrl driver has probed
> successfully or not. For example, because that dts node of pinctrl is
> "disabled" or Pinctrl driver is even not enabled.
>
> Can I keep this?

You can, but I think it's not needed.
Users may easily get this from other sources. Why do you need to have
such noise in the valuable resource, i.e. kernel message buffer?

...

> > > + *    - mux_f_mux:  Select the pin to a fully-pinmux pin
> > > + *    - mux_f_gpio: Select the pin to a GPIO or IOP pin
> > > + *    - mux_f_keep: Don't change (keep intact)

> > > +       mux_f_mux = 0,          /* select fully-pinmux       */
> > > +       mux_f_gpio = 1,         /* select GPIO or IOP pinmux */
> > > +       mux_f_keep = 2,         /* keep no change            */

These comments are replaced by the kernel doc above, no need to keep them.

...

> > Why is this in the header?
>
> Do you mean I need to move this "struct sppctl_gpio_chip { ... }" declaration
> to c file because it is only used by the c file?

Yes.

...

> Your previous comments:
> > > > > +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config,
> > > > > +                                struct pinctrl_map **map, unsigned
> > > > > +int *num_maps) {
> > > >
> > > > Looking into this rather quite big function why you can't use what pin control core provides?
> > >
> > > No, we cannot use functions pin-control core provides.
> > > Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
> > > We have more explanation there.
> >
> > Fine, can you reuse some library functions, etc? Please, consider refactoring to make it more readable.
>
> Could you please share me your idea about "refactoring"?
> Or could you give me some hints?
> I think many times, but have no idea about refactoring.

Just split it to a few logical parts so that code can be easier to read.

-- 
With Best Regards,
Andy Shevchenko


From john.garry at huawei.com  Mon Jan 10 10:43:08 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 18:43:08 +0000
Subject: [PATCH v4 03/48] perf stat: Correct aggregation CPU map
In-Reply-To: <20220105061351.120843-4-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-4-irogers@google.com>
Message-ID: <1ae917ec-4d32-4ee7-0948-f91eb3bf35fb@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
> Switch the perf_cpu_map in aggr_update_shadow from
> the evlist to the counter's cpu map, so the index is appropriate. This
> addresses a problem where uncore counts, with a cpumap like:
> $ cat /sys/devices/uncore_imc_0/cpumask
> 0,18
> Don't aggregate counts in CPUs based on the index of those values in the
> cpumap (0 and 1) but on the actual CPU (0 and 18). Thereby correcting
> metric calculations in per-socket mode for counters without a full
> cpumask.
> 
> On a SkylakeX with a tweaked DRAM_BW_Use metric, to remove unnecessary
> scaling, this gives:
> 
> Before:
> $ /perf stat --per-socket -M DRAM_BW_Use -I 1000
>       1.001102293 S0        1              27.01 MiB  uncore_imc/cas_count_write/ #   103.00 DRAM_BW_Use
>       1.001102293 S0        1              30.22 MiB  uncore_imc/cas_count_read/
>       1.001102293 S0        1      1,001,102,293 ns   duration_time
>       1.001102293 S1        1              20.10 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
>       1.001102293 S1        1              32.74 MiB  uncore_imc/cas_count_read/
>       1.001102293 S1        0      <not counted> ns   duration_time
>       2.003517973 S0        1              83.04 MiB  uncore_imc/cas_count_write/ #   920.00 DRAM_BW_Use
>       2.003517973 S0        1             145.95 MiB  uncore_imc/cas_count_read/
>       2.003517973 S0        1      1,002,415,680 ns   duration_time
>       2.003517973 S1        1             302.45 MiB  uncore_imc/cas_count_write/ #     0.00 DRAM_BW_Use
>       2.003517973 S1        1             290.99 MiB  uncore_imc/cas_count_read/
>       2.003517973 S1        0      <not counted> ns   duration_time
> 
> After:
> $ perf stat --per-socket -M DRAM_BW_Use -I 1000
>       1.001080840 S0        1              24.96 MiB  uncore_imc/cas_count_write/ #    54.00 DRAM_BW_Use
>       1.001080840 S0        1              33.64 MiB  uncore_imc/cas_count_read/
>       1.001080840 S0        1      1,001,080,840 ns   duration_time
>       1.001080840 S1        1              42.43 MiB  uncore_imc/cas_count_write/ #    84.00 DRAM_BW_Use
>       1.001080840 S1        1              47.05 MiB  uncore_imc/cas_count_read/
>       1.001080840 S1        0      <not counted> ns   duration_time
> 
> Signed-off-by: Ian Rogers<irogers at google.com>

Tested-by: John Garry <john.garry at huawei.com>


From andy.shevchenko at gmail.com  Mon Jan 10 10:42:55 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Mon, 10 Jan 2022 20:42:55 +0200
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <0f6a382cd66d4d5d84201da0a29145a3@sphcmbx02.sunplus.com.tw>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <0f6a382cd66d4d5d84201da0a29145a3@sphcmbx02.sunplus.com.tw>
Message-ID: <CAHp75VftFc8DNnrKp0dGsPvyzTrp+1z0_JP79Dzv5i0HMtsoUA@mail.gmail.com>

On Mon, Jan 10, 2022 at 8:16 PM Wells Lu ??? <wells.lu at sunplus.com> wrote:
>
> Hi Andy,
>
> Could you please answer my questions in previous mail?
> I need your answers to proceed submission.
>
> Sorry, I am not sure if my previous mail is lost or you are busy.

Please, do not top-post! Also remove unrelated context, make your
message small enough and neat.

I have answered your questions.

-- 
With Best Regards,
Andy Shevchenko


From john.garry at huawei.com  Mon Jan 10 10:50:54 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 18:50:54 +0000
Subject: [PATCH v4 04/48] perf stat: Switch aggregation to use for_each
 loop
In-Reply-To: <20220105061351.120843-5-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-5-irogers@google.com>
Message-ID: <0e26524c-9f4c-b351-2498-0a56bc86b4ee@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
> +	cpus = evsel__cpus(evsel);
> +	perf_cpu_map__for_each_cpu(cpu, idx, cpus) {

It seems a common pattern to evaluate cpus and use in 
perf_cpu_map__for_each_cpu() - is it possible to make a macro to accept 
evsel and create cpus, like perf_evsel__for_each_cpu()?

> +		if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpus, idx),
> +						 id))
> +			return cpu;
>   	}
>   	return 0;



From acme at kernel.org  Mon Jan 10 10:52:11 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 15:52:11 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
 <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
Message-ID: <YdyAWxprUpsySNqo@kernel.org>

Em Mon, Jan 10, 2022 at 09:36:49AM -0800, Ian Rogers escreveu:
> On Mon, Jan 10, 2022 at 9:10 AM John Garry <john.garry at huawei.com> wrote:
> >
> > On 05/01/2022 06:13, Ian Rogers wrote:
> > >
> > > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > > +                                    void *data)
> > > +{
> > > +     if (idx < 0 || idx > map->nr)
> > > +             return cpu_map__empty_aggr_cpu_id();
> > > +
> > > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > > +}
> > > +
> >
> >
> > This is later deleted in the series. Can the series be reworked so that
> > we don't add stuff and then later delete it? One reason for that
> > approach is that we don't spend time reviewing something which will be
> > deleted, especially in such a big series...
> 
> Hi John,
> 
> I think you are asking to squash:
> https://lore.kernel.org/lkml/20220105061351.120843-8-irogers at google.com/
> into this change. There are other  similar related changes that may
> also be squashed. The changes are trying to introduce a new API and
> then add changes to switch over to using it. This is with a view to
> making bisection easier, have each change only do 1 thing and so on. I
> believe the format of the patches is house style, but it is fine to
> squash changes together too. Having sent patches to Arnaldo and having
> had them split I'm reluctant to do a v5 with them squashed without him
> expressing a preference.

Right, sometimes this is needed, I'm getting the patchkit now to test
build it in my containers and will go patch by patch reviewing.

- Arnaldo
 
> Thanks,
> Ian
> 
> > If it really makes sense to do it this way then fine.
> >
> > Thanks,
> > John

-- 

- Arnaldo


From acme at kernel.org  Mon Jan 10 10:53:45 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 15:53:45 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <YdyAWxprUpsySNqo@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
 <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
 <YdyAWxprUpsySNqo@kernel.org>
Message-ID: <YdyAuTeFjF8n8lyv@kernel.org>

Em Mon, Jan 10, 2022 at 03:52:11PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 09:36:49AM -0800, Ian Rogers escreveu:
> > On Mon, Jan 10, 2022 at 9:10 AM John Garry <john.garry at huawei.com> wrote:
> > >
> > > On 05/01/2022 06:13, Ian Rogers wrote:
> > > >
> > > > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > > > +                                    void *data)
> > > > +{
> > > > +     if (idx < 0 || idx > map->nr)
> > > > +             return cpu_map__empty_aggr_cpu_id();
> > > > +
> > > > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > > > +}
> > > > +
> > >
> > >
> > > This is later deleted in the series. Can the series be reworked so that
> > > we don't add stuff and then later delete it? One reason for that
> > > approach is that we don't spend time reviewing something which will be
> > > deleted, especially in such a big series...
> > 
> > Hi John,
> > 
> > I think you are asking to squash:
> > https://lore.kernel.org/lkml/20220105061351.120843-8-irogers at google.com/
> > into this change. There are other  similar related changes that may
> > also be squashed. The changes are trying to introduce a new API and
> > then add changes to switch over to using it. This is with a view to
> > making bisection easier, have each change only do 1 thing and so on. I
> > believe the format of the patches is house style, but it is fine to
> > squash changes together too. Having sent patches to Arnaldo and having
> > had them split I'm reluctant to do a v5 with them squashed without him
> > expressing a preference.
> 
> Right, sometimes this is needed, I'm getting the patchkit now to test
> build it in my containers and will go patch by patch reviewing.

Good start:

?[acme at toolbox perf]$ b4 am -ctsl --cc-trailers CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA at mail.gmail.com
Looking up https://lore.kernel.org/r/CAP-5%3DfWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA%40mail.gmail.com
Grabbing thread from lore.kernel.org/all/CAP-5%3DfWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA%40mail.gmail.com/t.mbox.gz
Checking for newer revisions on https://lore.kernel.org/all/
Analyzing 58 messages in the thread
Checking attestation on all messages, may take a moment...
---
  ? [PATCH v4 1/48] libperf: Add comments to perf_cpu_map.
    + Reviewed-by: John Garry <john.garry at huawei.com>
    + Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
    + Link: https://lore.kernel.org/r/20220105061351.120843-2-irogers at google.com
<BIG SNIP>
Cover: ./v4_20220104_irogers_refactor_perf_cpumap.cover
 Link: https://lore.kernel.org/r/20220105061351.120843-1-irogers at google.com
 Base: applies clean to current tree
       git checkout -b v4_20220104_irogers_google_com HEAD
       git am ./v4_20220104_irogers_refactor_perf_cpumap.mbx

:-)

- Arnaldo


From f.fainelli at gmail.com  Mon Jan 10 10:56:42 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 10 Jan 2022 10:56:42 -0800
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <CAOesGMjArmB1J7KasjHZRTNXoZvtUXkTOQAyg5yd29qC8PeS9g@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
 <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
 <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>
 <CAK8P3a3sBADt4Cu=LGbjHQpQ32O-BtFk1aQFwhL8Ar=M_gj6Xw@mail.gmail.com>
 <CAOesGMjArmB1J7KasjHZRTNXoZvtUXkTOQAyg5yd29qC8PeS9g@mail.gmail.com>
Message-ID: <3d57e988-68e7-a1e4-5ad5-697ed82b9b08@gmail.com>

On 1/10/22 10:32 AM, Olof Johansson wrote:
> On Tue, Jan 4, 2022 at 5:40 PM Arnd Bergmann <arnd at kernel.org> wrote:
>>
>> On Tue, Jan 4, 2022 at 7:40 PM Olof Johansson <olof at lixom.net> wrote:
>>> On Tue, Jan 4, 2022 at 1:58 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
>>>> On 12/24/21 9:11 AM, Florian Fainelli wrote:
>>>>>
>>>>> Should I resend or fix something in those? Thanks!
>>>>
>>>>
>>>> Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
>>>> Thanks and happy new year.
>>>
>>> I'm about to make a pass of merges, likely tomorrow -- I had to get my
>>> Honeycomb working again since it hosts all the trees and mailboxes for
>>> me.
>>>
>>> No need to resend at this time.
>>
>> It's possible that I had accidentally merged them in the end but tagged
>> the branch without those merge commits, so have a look if it's in there.
> 
> Yeah, it looks like there were a few merges not part of the pull
> request (Linus just merged them, so these showed up in
> regen-contents). I'll fold them into arm/late.

Thanks!
-- 
Florian


From acme at kernel.org  Mon Jan 10 10:56:55 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 15:56:55 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <YdyAuTeFjF8n8lyv@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <57ab982e-ecc1-3f49-c580-0a251e29698b@huawei.com>
 <CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA@mail.gmail.com>
 <YdyAWxprUpsySNqo@kernel.org> <YdyAuTeFjF8n8lyv@kernel.org>
Message-ID: <YdyBd7FHnyQaDwgu@kernel.org>

Em Mon, Jan 10, 2022 at 03:53:45PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 03:52:11PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 10, 2022 at 09:36:49AM -0800, Ian Rogers escreveu:
> > > On Mon, Jan 10, 2022 at 9:10 AM John Garry <john.garry at huawei.com> wrote:
> > > >
> > > > On 05/01/2022 06:13, Ian Rogers wrote:
> > > > >
> > > > > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > > > > +                                    void *data)
> > > > > +{
> > > > > +     if (idx < 0 || idx > map->nr)
> > > > > +             return cpu_map__empty_aggr_cpu_id();
> > > > > +
> > > > > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > > > > +}
> > > > > +
> > > >
> > > >
> > > > This is later deleted in the series. Can the series be reworked so that
> > > > we don't add stuff and then later delete it? One reason for that
> > > > approach is that we don't spend time reviewing something which will be
> > > > deleted, especially in such a big series...
> > > 
> > > Hi John,
> > > 
> > > I think you are asking to squash:
> > > https://lore.kernel.org/lkml/20220105061351.120843-8-irogers at google.com/
> > > into this change. There are other  similar related changes that may
> > > also be squashed. The changes are trying to introduce a new API and
> > > then add changes to switch over to using it. This is with a view to
> > > making bisection easier, have each change only do 1 thing and so on. I
> > > believe the format of the patches is house style, but it is fine to
> > > squash changes together too. Having sent patches to Arnaldo and having
> > > had them split I'm reluctant to do a v5 with them squashed without him
> > > expressing a preference.
> > 
> > Right, sometimes this is needed, I'm getting the patchkit now to test
> > build it in my containers and will go patch by patch reviewing.
> 
> Good start:
> 
> ?[acme at toolbox perf]$ b4 am -ctsl --cc-trailers CAP-5=fWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA at mail.gmail.com
> Looking up https://lore.kernel.org/r/CAP-5%3DfWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA%40mail.gmail.com
> Grabbing thread from lore.kernel.org/all/CAP-5%3DfWT_19OfZTTjvLUcChV4nDwqc5Zq4VE93Gak6OO4NORsA%40mail.gmail.com/t.mbox.gz
> Checking for newer revisions on https://lore.kernel.org/all/
> Analyzing 58 messages in the thread
> Checking attestation on all messages, may take a moment...
> ---
>   ? [PATCH v4 1/48] libperf: Add comments to perf_cpu_map.
>     + Reviewed-by: John Garry <john.garry at huawei.com>
>     + Signed-off-by: Arnaldo Carvalho de Melo <acme at redhat.com>
>     + Link: https://lore.kernel.org/r/20220105061351.120843-2-irogers at google.com
> <BIG SNIP>
> Cover: ./v4_20220104_irogers_refactor_perf_cpumap.cover
>  Link: https://lore.kernel.org/r/20220105061351.120843-1-irogers at google.com
>  Base: applies clean to current tree
>        git checkout -b v4_20220104_irogers_google_com HEAD
>        git am ./v4_20220104_irogers_refactor_perf_cpumap.mbx
> 

oops:

  CC      /tmp/build/perf/util/unwind-libunwind-local.o
util/bpf_counter_cgroup.c: In function ?bperf_load_program?:
util/bpf_counter_cgroup.c:51:26: error: incompatible types when initializing type ?int? using type ?struct perf_cpu?
   51 |         int total_cpus = cpu__max_cpu();
      |                          ^~~~~~~~~~~~
util/bpf_counter_cgroup.c:127:74: error: invalid operands to binary + (have ?int? and ?struct perf_cpu?)
  127 |                                 __u32 idx = evsel->core.idx * total_cpus +
      |                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
      |                                                             |
      |                                                             int
  128 |                                         evlist->core.all_cpus->map[cpu];
      |                                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                                                   |
      |                                                                   struct perf_cpu
util/bpf_counter_cgroup.c: In function ?bperf_cgrp__sync_counters?:
util/bpf_counter_cgroup.c:215:23: error: incompatible types when assigning to type ?int? from type ?struct perf_cpu?
  215 |                 cpu = evlist->core.all_cpus->map[i];
      |                       ^~~~~~
util/bpf_counter_cgroup.c: In function ?bperf_cgrp__read?:
util/bpf_counter_cgroup.c:248:26: error: incompatible types when initializing type ?int? using type ?struct perf_cpu?
  248 |         int total_cpus = cpu__max_cpu();
      |                          ^~~~~~~~~~~~
util/bpf_counter_cgroup.c:275:31: error: incompatible types when assigning to type ?int? from type ?struct perf_cpu?
  275 |                         cpu = evlist->core.all_cpus->map[i];
      |                               ^~~~~~
make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:97: /tmp/build/perf/util/bpf_counter_cgroup.o] Error 1
make[4]: *** Waiting for unfinished jobs....
util/bpf_counter.c: In function ?bperf__load?:
util/bpf_counter.c:543:31: error: incompatible types when assigning to type ?__u32? {aka ?unsigned int?} from type ?struct perf_cpu?
  543 |                         key = evsel->core.cpus->map[i];
      |                               ^~~~~
util/bpf_counter.c: In function ?bperf_sync_counters?:
util/bpf_counter.c:587:23: error: incompatible types when assigning to type ?int? from type ?struct perf_cpu?
  587 |                 cpu = all_cpu_map->map[i];
      |                       ^~~~~~~~~~~
util/bpf_counter.c: In function ?bperf__read?:
util/bpf_counter.c:608:29: error: incompatible types when initializing type ?__u32? {aka ?unsigned int?} using type ?struct perf_cpu?
  608 |         __u32 num_cpu_bpf = cpu__max_cpu();
      |                             ^~~~~~~~~~~~
In file included from /var/home/acme/git/perf/tools/perf/util/cpumap.h:8,
                 from /var/home/acme/git/perf/tools/perf/util/env.h:7,
                 from util/cgroup.h:8,
                 from util/bpf_counter.c:22:
/var/home/acme/git/perf/tools/lib/perf/include/perf/cpumap.h:25:33: error: incompatible types when assigning to type ?__u32? {aka ?unsigned int?} from type ?struct perf_cpu?
   25 |         for ((idx) = 0, (cpu) = perf_cpu_map__cpu(cpus, idx);   \
      |                                 ^~~~~~~~~~~~~~~~~
util/bpf_counter.c:626:25: note: in expansion of macro ?perf_cpu_map__for_each_cpu?
  626 |                         perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
/var/home/acme/git/perf/tools/lib/perf/include/perf/cpumap.h:26:20: error: comparison of integer expressions of different signedness: ?__u32? {aka ?unsigned int?} and ?int? [-Werror=sign-compare]
   26 |              (idx) < perf_cpu_map__nr(cpus);                    \
      |                    ^
util/bpf_counter.c:626:25: note: in expansion of macro ?perf_cpu_map__for_each_cpu?
  626 |                         perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
/var/home/acme/git/perf/tools/lib/perf/include/perf/cpumap.h:27:31: error: incompatible types when assigning to type ?__u32? {aka ?unsigned int?} from type ?struct perf_cpu?
   27 |              (idx)++, (cpu) = perf_cpu_map__cpu(cpus, idx))
      |                               ^~~~~~~~~~~~~~~~~
util/bpf_counter.c:626:25: note: in expansion of macro ?perf_cpu_map__for_each_cpu?
  626 |                         perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
util/bpf_counter.c:633:31: error: incompatible types when assigning to type ?__u32? {aka ?unsigned int?} from type ?struct perf_cpu?
  633 |                         cpu = evsel->core.cpus->map[i];
      |                               ^~~~~
util/bpf_counter.c:611:21: error: unused variable ?num_cpu? [-Werror=unused-variable]
  611 |         __u32 i, j, num_cpu;
      |                     ^~~~~~~
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_counter.o] Error 1
util/bpf_ftrace.c: In function ?perf_ftrace__latency_prepare_bpf?:
util/bpf_ftrace.c:66:31: error: implicit declaration of function ?cpu_map__cpu?; did you mean ?cpu__max_cpu?? [-Werror=implicit-function-declaration]
   66 |                         cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
      |                               ^~~~~~~~~~~~
      |                               cpu__max_cpu
util/bpf_ftrace.c: In function ?perf_ftrace__latency_read_bpf?:
util/bpf_ftrace.c:125:21: error: incompatible types when initializing type ?int? using type ?struct perf_cpu?
  125 |         int ncpus = cpu__max_cpu();
      |                     ^~~~~~~~~~~~
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_ftrace.o] Error 1
  LD      /tmp/build/perf/util/intel-pt-decoder/perf-in.o
  LD      /tmp/build/perf/util/scripting-engines/perf-in.o
make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [Makefile.perf:240: sub-make] Error 2
make: *** [Makefile:113: install-bin] Error 2
make: Leaving directory '/var/home/acme/git/perf/tools/perf'

 Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':

   279,675,447,200      cycles:u
   348,898,435,627      instructions:u            #    1.25  insn per cycle

       4.978587957 seconds time elapsed

      68.698979000 seconds user
      12.541229000 seconds sys


?[acme at toolbox perf]$

This is building with:

$ make BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin


In general for such refactorings its important to run:

make -C tools/perf build-test


But there is no entry there with BUILD_BPF_SKEL=1, will fix that now and
try to fix this in the patchkit as well.

- Arnaldo


From mathieu.poirier at linaro.org  Mon Jan 10 10:58:50 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 10 Jan 2022 11:58:50 -0700
Subject: [PATCH v2 0/6] coresight: syscfg: Extend configfs for config load
In-Reply-To: <20211130220100.25888-1-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
Message-ID: <20220110185850.GA771798@p14s>

Good morning Mike,

On Tue, Nov 30, 2021 at 10:00:54PM +0000, Mike Leach wrote:
> This set extends the configfs support to allow loading and unloading of
> configurations as binary files via configfs.
> 
> Additional attributes - load, unload and last_load_status are provided to
> implement the load functionality.
> 
> Routines to generate binary configuration files are supplied in
> ./samples/coresight.
> 
> Example generator and reader applications are provided.
> 
> Additional Makefile.host supplied to build the generator and reader
> applications on the host system separate from a cross compiled kernel.
> 
> Documentation is updated to describe feature usage.
> 
> Applies and tested on latest coresight/next that includes the
> previous coresight configuration dynamic load patchset.
> 

I have started to review this set.

Thanks,
Mathieu

> Changes since v1:
> 1) Rebased to coresight/next - 5.16-rc1 with previous coresight config
> set applied.
> 2) Makefile.host fixed to default to all target.
> 
> Mike Leach (6):
>   coresight: configfs: Add in functionality for load via configfs
>   coresight: configfs: Add in binary attributes to load files
>   coresight: configfs: Modify config files to allow userspace use
>   coresight: samples: Add an example config writer for configfs load
>   coresight: samples: Add coresight file reader sample program
>   Documentation: coresight: docs for config load via configfs
> 
>  .../trace/coresight/coresight-config.rst      | 151 +++++-
>  drivers/hwtracing/coresight/Makefile          |   2 +-
>  .../coresight/coresight-config-file.c         | 472 ++++++++++++++++++
>  .../coresight/coresight-config-file.h         | 158 ++++++
>  .../hwtracing/coresight/coresight-config.h    |  38 ++
>  .../coresight/coresight-syscfg-configfs.c     | 148 +++++-
>  .../coresight/coresight-syscfg-configfs.h     |   8 +
>  .../hwtracing/coresight/coresight-syscfg.c    |  36 ++
>  .../hwtracing/coresight/coresight-syscfg.h    |   2 +
>  samples/coresight/Makefile                    |  23 +
>  samples/coresight/Makefile.host               |  47 ++
>  samples/coresight/coresight-cfg-bufw.c        | 302 +++++++++++
>  samples/coresight/coresight-cfg-bufw.h        |  24 +
>  samples/coresight/coresight-cfg-file-read.c   | 191 +++++++
>  samples/coresight/coresight-cfg-filegen.c     |  89 ++++
>  15 files changed, 1677 insertions(+), 14 deletions(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.h
>  create mode 100644 samples/coresight/Makefile.host
>  create mode 100644 samples/coresight/coresight-cfg-bufw.c
>  create mode 100644 samples/coresight/coresight-cfg-bufw.h
>  create mode 100644 samples/coresight/coresight-cfg-file-read.c
>  create mode 100644 samples/coresight/coresight-cfg-filegen.c
> 
> -- 
> 2.17.1
> 


From acme at kernel.org  Mon Jan 10 11:02:49 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:02:49 -0300
Subject: [PATCH v4 17/48] perf cpumap: Remove cpu_map__cpu, use libperf
 function.
In-Reply-To: <20220105061351.120843-18-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-18-irogers@google.com>
Message-ID: <YdyC2VdqizF6prb4@kernel.org>

Em Tue, Jan 04, 2022 at 10:13:20PM -0800, Ian Rogers escreveu:
> Switch the remaining few users of cpu_map__cpu to perf_cpu_map__cpu and
> remove the function.
> 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>

util/bpf_ftrace.c: In function ?perf_ftrace__latency_prepare_bpf?:
util/bpf_ftrace.c:66:31: error: implicit declaration of function ?cpu_map__cpu?; did you mean ?cpu_map__has?? [-Werror=implicit-function-declaration]
   66 |                         cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
      |                               ^~~~~~~~~~~~
      |                               cpu_map__has
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_ftrace.o] Error 1
make[4]: *** Waiting for unfinished jobs....
  LD      /tmp/build/perf/ui/browsers/perf-in.o
  LD      /tmp/build/perf/ui/perf-in.o
  LD      /tmp/build/perf/util/scripting-engines/perf-in.o
make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [Makefile.perf:240: sub-make] Error 2
make: *** [Makefile:113: install-bin] Error 2
make: Leaving directory '/var/home/acme/git/perf/tools/perf'

 Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':

   163,635,422,196      cycles:u                                                    
   213,602,262,800      instructions:u            #    1.31  insn per cycle         

       3.804738555 seconds time elapsed

      40.622581000 seconds user
       6.589980000 seconds sys


?[acme at toolbox perf]$ git log --oneline -1
dfe103e757aeff79 (HEAD) perf cpumap: Remove cpu_map__cpu, use libperf function.

This is the first breakage, trying to fix now.

> ---
>  tools/perf/builtin-ftrace.c | 2 +-
>  tools/perf/util/cpumap.c    | 9 ++-------
>  tools/perf/util/cpumap.h    | 1 -
>  3 files changed, 3 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c
> index 2b54e2ddc80a..f16c39a37a52 100644
> --- a/tools/perf/builtin-ftrace.c
> +++ b/tools/perf/builtin-ftrace.c
> @@ -281,7 +281,7 @@ static int set_tracing_cpumask(struct perf_cpu_map *cpumap)
>  	int ret;
>  	int last_cpu;
>  
> -	last_cpu = cpu_map__cpu(cpumap, cpumap->nr - 1);
> +	last_cpu = perf_cpu_map__cpu(cpumap, cpumap->nr - 1);
>  	mask_size = last_cpu / 4 + 2; /* one more byte for EOS */
>  	mask_size += last_cpu / 32; /* ',' is needed for every 32th cpus */
>  
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index e0d7f1da5858..32f9fc2dd389 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -485,11 +485,6 @@ bool cpu_map__has(struct perf_cpu_map *cpus, int cpu)
>  	return perf_cpu_map__idx(cpus, cpu) != -1;
>  }
>  
> -int cpu_map__cpu(struct perf_cpu_map *cpus, int idx)
> -{
> -	return cpus->map[idx];
> -}
> -
>  size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size)
>  {
>  	int i, cpu, start = -1;
> @@ -547,7 +542,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
>  	int i, cpu;
>  	char *ptr = buf;
>  	unsigned char *bitmap;
> -	int last_cpu = cpu_map__cpu(map, map->nr - 1);
> +	int last_cpu = perf_cpu_map__cpu(map, map->nr - 1);
>  
>  	if (buf == NULL)
>  		return 0;
> @@ -559,7 +554,7 @@ size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size)
>  	}
>  
>  	for (i = 0; i < map->nr; i++) {
> -		cpu = cpu_map__cpu(map, i);
> +		cpu = perf_cpu_map__cpu(map, i);
>  		bitmap[cpu / 8] |= 1 << (cpu % 8);
>  	}
>  
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index a053bf31a3f0..87545bcd461d 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -80,7 +80,6 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
>  		       struct aggr_cpu_id (*f)(int cpu, void *data),
>  		       void *data);
>  
> -int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
>  bool cpu_map__has(struct perf_cpu_map *cpus, int cpu);
>  
>  bool aggr_cpu_id__equal(const struct aggr_cpu_id *a, const struct aggr_cpu_id *b);
> -- 
> 2.34.1.448.ga2b2bfdf31-goog

-- 

- Arnaldo


From acme at kernel.org  Mon Jan 10 11:04:08 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:04:08 -0300
Subject: [PATCH v4 17/48] perf cpumap: Remove cpu_map__cpu, use libperf
 function.
In-Reply-To: <YdyC2VdqizF6prb4@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-18-irogers@google.com>
 <YdyC2VdqizF6prb4@kernel.org>
Message-ID: <YdyDKAZY+m0rRW2H@kernel.org>

Em Mon, Jan 10, 2022 at 04:02:49PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 04, 2022 at 10:13:20PM -0800, Ian Rogers escreveu:
> > Switch the remaining few users of cpu_map__cpu to perf_cpu_map__cpu and
> > remove the function.
> > 
> > Reviewed-by: James Clark <james.clark at arm.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>
> 
> util/bpf_ftrace.c: In function ?perf_ftrace__latency_prepare_bpf?:
> util/bpf_ftrace.c:66:31: error: implicit declaration of function ?cpu_map__cpu?; did you mean ?cpu_map__has?? [-Werror=implicit-function-declaration]
>    66 |                         cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
>       |                               ^~~~~~~~~~~~
>       |                               cpu_map__has
> cc1: all warnings being treated as errors
> make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_ftrace.o] Error 1
> make[4]: *** Waiting for unfinished jobs....
>   LD      /tmp/build/perf/ui/browsers/perf-in.o
>   LD      /tmp/build/perf/ui/perf-in.o
>   LD      /tmp/build/perf/util/scripting-engines/perf-in.o
> make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
> make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
> make[2]: *** Waiting for unfinished jobs....
> make[1]: *** [Makefile.perf:240: sub-make] Error 2
> make: *** [Makefile:113: install-bin] Error 2
> make: Leaving directory '/var/home/acme/git/perf/tools/perf'
> 
>  Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':
> 
>    163,635,422,196      cycles:u                                                    
>    213,602,262,800      instructions:u            #    1.31  insn per cycle         
> 
>        3.804738555 seconds time elapsed
> 
>       40.622581000 seconds user
>        6.589980000 seconds sys
> 
> 
> ?[acme at toolbox perf]$ git log --oneline -1
> dfe103e757aeff79 (HEAD) perf cpumap: Remove cpu_map__cpu, use libperf function.
> 
> This is the first breakage, trying to fix now.

?[acme at toolbox perf]$ find tools/perf/ -name "*.c" | xargs grep -w cpu_map__cpu
tools/perf/util/bpf_ftrace.c:			cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
?[acme at toolbox perf]$

Only this one remaining, so just moving to perf_cpu_map__cpu() like done
elsewhere in this patch.

- Arnaldo


From john.garry at huawei.com  Mon Jan 10 11:04:34 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 19:04:34 +0000
Subject: [PATCH v4 05/48] perf stat: Switch to cpu version of cpu_map__get
In-Reply-To: <20220105061351.120843-6-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-6-irogers@google.com>
Message-ID: <64d64526-7d3e-0c31-f43e-f03810f72ac2@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
> Avoid bugs where the wrong index is passed with the cpu_map.

nit: Don't you mean possible bugs?

> 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>


From acme at kernel.org  Mon Jan 10 11:06:26 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:06:26 -0300
Subject: [PATCH v4 17/48] perf cpumap: Remove cpu_map__cpu, use libperf
 function.
In-Reply-To: <YdyDKAZY+m0rRW2H@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-18-irogers@google.com>
 <YdyC2VdqizF6prb4@kernel.org> <YdyDKAZY+m0rRW2H@kernel.org>
Message-ID: <YdyDsm6fzC+E2C0b@kernel.org>

Em Mon, Jan 10, 2022 at 04:04:08PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 04:02:49PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Tue, Jan 04, 2022 at 10:13:20PM -0800, Ian Rogers escreveu:
> > > Switch the remaining few users of cpu_map__cpu to perf_cpu_map__cpu and
> > > remove the function.
> > > 
> > > Reviewed-by: James Clark <james.clark at arm.com>
> > > Signed-off-by: Ian Rogers <irogers at google.com>
> > 
> > util/bpf_ftrace.c: In function ?perf_ftrace__latency_prepare_bpf?:
> > util/bpf_ftrace.c:66:31: error: implicit declaration of function ?cpu_map__cpu?; did you mean ?cpu_map__has?? [-Werror=implicit-function-declaration]
> >    66 |                         cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
> >       |                               ^~~~~~~~~~~~
> >       |                               cpu_map__has
> > cc1: all warnings being treated as errors
> > make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_ftrace.o] Error 1
> > make[4]: *** Waiting for unfinished jobs....
> >   LD      /tmp/build/perf/ui/browsers/perf-in.o
> >   LD      /tmp/build/perf/ui/perf-in.o
> >   LD      /tmp/build/perf/util/scripting-engines/perf-in.o
> > make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
> > make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
> > make[2]: *** Waiting for unfinished jobs....
> > make[1]: *** [Makefile.perf:240: sub-make] Error 2
> > make: *** [Makefile:113: install-bin] Error 2
> > make: Leaving directory '/var/home/acme/git/perf/tools/perf'
> > 
> >  Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':
> > 
> >    163,635,422,196      cycles:u                                                    
> >    213,602,262,800      instructions:u            #    1.31  insn per cycle         
> > 
> >        3.804738555 seconds time elapsed
> > 
> >       40.622581000 seconds user
> >        6.589980000 seconds sys
> > 
> > 
> > ?[acme at toolbox perf]$ git log --oneline -1
> > dfe103e757aeff79 (HEAD) perf cpumap: Remove cpu_map__cpu, use libperf function.
> > 
> > This is the first breakage, trying to fix now.
> 
> ?[acme at toolbox perf]$ find tools/perf/ -name "*.c" | xargs grep -w cpu_map__cpu
> tools/perf/util/bpf_ftrace.c:			cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
> ?[acme at toolbox perf]$
> 
> Only this one remaining, so just moving to perf_cpu_map__cpu() like done
> elsewhere in this patch.
> 

?[acme at toolbox perf]$ git diff
diff --git a/tools/perf/util/bpf_ftrace.c b/tools/perf/util/bpf_ftrace.c
index f00a2de6778ccb97..28dc4c60c7884818 100644
--- a/tools/perf/util/bpf_ftrace.c
+++ b/tools/perf/util/bpf_ftrace.c
@@ -63,7 +63,7 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace *ftrace)
                fd = bpf_map__fd(skel->maps.cpu_filter);

                for (i = 0; i < ncpus; i++) {
-                       cpu = cpu_map__cpu(ftrace->evlist->core.cpus, i);
+                       cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i);
                        bpf_map_update_elem(fd, &cpu, &val, BPF_ANY);
                }
        }
?[acme at toolbox perf]$


From robh at kernel.org  Mon Jan 10 11:06:39 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 13:06:39 -0600
Subject: [PATCH 1/8] of: base: add of_parse_phandle_with_optional_args()
In-Reply-To: <20211228142549.1275412-2-michael@walle.cc>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-2-michael@walle.cc>
Message-ID: <YdyDv1/WbNi3CMbu@robh.at.kernel.org>

On Tue, Dec 28, 2021 at 03:25:42PM +0100, Michael Walle wrote:
> Add a new variant of the of_parse_phandle_with_args() which treats the
> cells name as optional. If it's missing, it is assumed that the phandle
> has no arguments.
> 
> Up until now, a nvmem node didn't have any arguments, so all the device
> trees haven't any '#*-cells' property. But there is a need for an
> additional argument for the phandle, for which we need a '#*-cells'
> property. Therefore, we need to support nvmem nodes with and without
> this property.
> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
>  drivers/of/base.c  | 23 +++++++++++++++++++++++
>  include/linux/of.h | 12 ++++++++++++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index 5b907600f5b0..fb28bb26276e 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -1543,6 +1543,29 @@ int of_parse_phandle_with_args(const struct device_node *np, const char *list_na
>  }
>  EXPORT_SYMBOL(of_parse_phandle_with_args);
>  
> +/**
> + * of_parse_phandle_with_optional_args() - Find a node pointed by phandle in a list
> + *
> + * Same as of_parse_phandle_args() except that if the cells_name property is
> + * not found, cell_count of 0 is assumed.
> + *
> + * This is used to useful, if you have a phandle which didn't have arguments
> + * before and thus doesn't have a '#*-cells' property but is now migrated to
> + * having arguments while retaining backwards compatibility.
> + */
> +int of_parse_phandle_with_optional_args(const struct device_node *np,
> +					const char *list_name,
> +					const char *cells_name, int index,
> +					struct of_phandle_args *out_args)
> +{
> +	if (index < 0)
> +		return -EINVAL;

I'm not sure why we didn't do this from the start, but just make index 
unsigned and then this check is not needed.

> +
> +	return __of_parse_phandle_with_args(np, list_name, cells_name,
> +					    0, index, out_args);
> +}
> +EXPORT_SYMBOL(of_parse_phandle_with_optional_args);


With the above, just make this static inline. Bonus points if you want 
to do the same changes on the other variants.

Rob


From acme at kernel.org  Mon Jan 10 11:10:46 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:10:46 -0300
Subject: [PATCH v4 44/48] perf bpf: Rename cpu to cpu_map_idx
In-Reply-To: <20220105061351.120843-45-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-45-irogers@google.com>
Message-ID: <YdyEtsLxsZM09y8O@kernel.org>

Em Tue, Jan 04, 2022 at 10:13:47PM -0800, Ian Rogers escreveu:
> Synchronize the caller in evsel with the called function.
> Shorten 3 lines of code in bperf_read by using
> perf_cpu_map__for_each_cpu.
> This code is frequently using variables named cpu as cpu map indices,
> which doesn't matter as all CPUs are in the CPU map. It is strange in
> some cases the cpumap is used at all.

  CC      /tmp/build/perf/builtin-stat.o
  INSTALL trace_plugins
  CC      /tmp/build/perf/util/evlist.o
  CC      /tmp/build/perf/util/evsel.o
  CC      /tmp/build/perf/util/header.o
  CC      /tmp/build/perf/util/bpf_counter.o
  CC      /tmp/build/perf/util/bpf_counter_cgroup.o
  CC      /tmp/build/perf/util/bpf_ftrace.o
In file included from util/cpumap.h:8,
                 from util/bpf_counter.c:23:
util/bpf_counter.c: In function ?bperf__read?:
/var/home/acme/git/perf/tools/lib/perf/include/perf/cpumap.h:27:20: error: comparison of integer expressions of different signedness: ?__u32? {aka ?unsigned int?} and ?int? [-Werror=sign-compare]
   27 |              (idx) < perf_cpu_map__nr(cpus);                    \
      |                    ^
util/bpf_counter.c:626:25: note: in expansion of macro ?perf_cpu_map__for_each_cpu?
  626 |                         perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
util/bpf_counter.c:611:21: error: unused variable ?num_cpu? [-Werror=unused-variable]
  611 |         __u32 i, j, num_cpu;
      |                     ^~~~~~~
cc1: all warnings being treated as errors
make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_counter.o] Error 1
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
make[1]: *** [Makefile.perf:240: sub-make] Error 2
make: *** [Makefile:113: install-bin] Error 2
make: Leaving directory '/var/home/acme/git/perf/tools/perf'

 Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':

    15,589,752,360      cycles:u
    28,227,862,710      instructions:u            #    1.81  insn per cycle

       1.996638375 seconds time elapsed

       3.567457000 seconds user
       0.934840000 seconds sys


?[acme at toolbox perf]$ git log --oneline -1
0083ba4c6a931fd0 (HEAD) perf bpf: Rename cpu to cpu_map_idx
?[acme at toolbox perf]$

Trying to fix...
 
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/util/bpf_counter.c | 16 +++++++---------
>  tools/perf/util/bpf_counter.h |  4 ++--
>  2 files changed, 9 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
> index c17d4a43ce06..ae5bd87ff020 100644
> --- a/tools/perf/util/bpf_counter.c
> +++ b/tools/perf/util/bpf_counter.c
> @@ -265,7 +265,7 @@ static int bpf_program_profiler__read(struct evsel *evsel)
>  	return 0;
>  }
>  
> -static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu,
> +static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu_map_idx,
>  					    int fd)
>  {
>  	struct bpf_prog_profiler_bpf *skel;
> @@ -277,7 +277,7 @@ static int bpf_program_profiler__install_pe(struct evsel *evsel, int cpu,
>  		assert(skel != NULL);
>  
>  		ret = bpf_map_update_elem(bpf_map__fd(skel->maps.events),
> -					  &cpu, &fd, BPF_ANY);
> +					  &cpu_map_idx, &fd, BPF_ANY);
>  		if (ret)
>  			return ret;
>  	}
> @@ -566,12 +566,12 @@ static int bperf__load(struct evsel *evsel, struct target *target)
>  	return err;
>  }
>  
> -static int bperf__install_pe(struct evsel *evsel, int cpu, int fd)
> +static int bperf__install_pe(struct evsel *evsel, int cpu_map_idx, int fd)
>  {
>  	struct bperf_leader_bpf *skel = evsel->leader_skel;
>  
>  	return bpf_map_update_elem(bpf_map__fd(skel->maps.events),
> -				   &cpu, &fd, BPF_ANY);
> +				   &cpu_map_idx, &fd, BPF_ANY);
>  }
>  
>  /*
> @@ -623,9 +623,7 @@ static int bperf__read(struct evsel *evsel)
>  		case BPERF_FILTER_GLOBAL:
>  			assert(i == 0);
>  
> -			num_cpu = all_cpu_map->nr;
> -			for (j = 0; j < num_cpu; j++) {
> -				cpu = all_cpu_map->map[j];
> +			perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
>  				perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
>  				perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
>  				perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
> @@ -757,11 +755,11 @@ static inline bool bpf_counter_skip(struct evsel *evsel)
>  		evsel->follower_skel == NULL;
>  }
>  
> -int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd)
> +int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd)
>  {
>  	if (bpf_counter_skip(evsel))
>  		return 0;
> -	return evsel->bpf_counter_ops->install_pe(evsel, cpu, fd);
> +	return evsel->bpf_counter_ops->install_pe(evsel, cpu_map_idx, fd);
>  }
>  
>  int bpf_counter__load(struct evsel *evsel, struct target *target)
> diff --git a/tools/perf/util/bpf_counter.h b/tools/perf/util/bpf_counter.h
> index 65ebaa6694fb..4dbf26408b69 100644
> --- a/tools/perf/util/bpf_counter.h
> +++ b/tools/perf/util/bpf_counter.h
> @@ -16,7 +16,7 @@ typedef int (*bpf_counter_evsel_op)(struct evsel *evsel);
>  typedef int (*bpf_counter_evsel_target_op)(struct evsel *evsel,
>  					   struct target *target);
>  typedef int (*bpf_counter_evsel_install_pe_op)(struct evsel *evsel,
> -					       int cpu,
> +					       int cpu_map_idx,
>  					       int fd);
>  
>  struct bpf_counter_ops {
> @@ -40,7 +40,7 @@ int bpf_counter__enable(struct evsel *evsel);
>  int bpf_counter__disable(struct evsel *evsel);
>  int bpf_counter__read(struct evsel *evsel);
>  void bpf_counter__destroy(struct evsel *evsel);
> -int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd);
> +int bpf_counter__install_pe(struct evsel *evsel, int cpu_map_idx, int fd);
>  
>  #else /* HAVE_BPF_SKEL */
>  
> -- 
> 2.34.1.448.ga2b2bfdf31-goog

-- 

- Arnaldo


From henrik at grimler.se  Mon Jan 10 11:16:11 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Mon, 10 Jan 2022 20:16:11 +0100
Subject: [RFC PATCH 1/1] ARM: exynos: only do SMC_CMD_CPU1BOOT call on
 Exynos4
In-Reply-To: <2202f06f-e901-44bb-b6dc-7225dd093e1b@samsung.com>
References: <20220108215733.705865-1-henrik@grimler.se>
 <CGME20220108215952eucas1p1bb9bc56c7f8ac7117b5e5576635460d5@eucas1p1.samsung.com>
 <20220108215733.705865-2-henrik@grimler.se>
 <2202f06f-e901-44bb-b6dc-7225dd093e1b@samsung.com>
Message-ID: <YdyF4cvS2GRxKPVn@localhost>

Hi Marek,

> Works fine on all ARM 32bit Exynos-based boards I have for tests.
> 
> Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>

Thanks for testing!  Would you mind telling me which Exynos boards you
have in your test-setup?

Best regards,
Henrik Grimler


From john.garry at huawei.com  Mon Jan 10 11:17:52 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 10 Jan 2022 19:17:52 +0000
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <20220105061351.120843-3-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
Message-ID: <9ee9f3ca-bfeb-7258-f7dd-2485c26ef372@huawei.com>

On 05/01/2022 06:13, Ian Rogers wrote:
> +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> +				       void *data)
> +{
> +	if (idx < 0 || idx > map->nr)

Incidentally should this be >= map->nr?

> +		return cpu_map__empty_aggr_cpu_id();
> +
> +	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> +}
> +



From acme at kernel.org  Mon Jan 10 11:26:26 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:26:26 -0300
Subject: [PATCH v4 44/48] perf bpf: Rename cpu to cpu_map_idx
In-Reply-To: <YdyEtsLxsZM09y8O@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-45-irogers@google.com>
 <YdyEtsLxsZM09y8O@kernel.org>
Message-ID: <YdyIYhSN0wLhlOh0@kernel.org>

Em Mon, Jan 10, 2022 at 04:10:46PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 04, 2022 at 10:13:47PM -0800, Ian Rogers escreveu:
> > Synchronize the caller in evsel with the called function.
> > Shorten 3 lines of code in bperf_read by using
> > perf_cpu_map__for_each_cpu.
> > This code is frequently using variables named cpu as cpu map indices,
> > which doesn't matter as all CPUs are in the CPU map. It is strange in
> > some cases the cpumap is used at all.
> 
>   CC      /tmp/build/perf/builtin-stat.o
>   INSTALL trace_plugins
>   CC      /tmp/build/perf/util/evlist.o
>   CC      /tmp/build/perf/util/evsel.o
>   CC      /tmp/build/perf/util/header.o
>   CC      /tmp/build/perf/util/bpf_counter.o
>   CC      /tmp/build/perf/util/bpf_counter_cgroup.o
>   CC      /tmp/build/perf/util/bpf_ftrace.o
> In file included from util/cpumap.h:8,
>                  from util/bpf_counter.c:23:
> util/bpf_counter.c: In function ?bperf__read?:
> /var/home/acme/git/perf/tools/lib/perf/include/perf/cpumap.h:27:20: error: comparison of integer expressions of different signedness: ?__u32? {aka ?unsigned int?} and ?int? [-Werror=sign-compare]
>    27 |              (idx) < perf_cpu_map__nr(cpus);                    \
>       |                    ^
> util/bpf_counter.c:626:25: note: in expansion of macro ?perf_cpu_map__for_each_cpu?
>   626 |                         perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
>       |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~
> util/bpf_counter.c:611:21: error: unused variable ?num_cpu? [-Werror=unused-variable]
>   611 |         __u32 i, j, num_cpu;
>       |                     ^~~~~~~
> cc1: all warnings being treated as errors
> make[4]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:96: /tmp/build/perf/util/bpf_counter.o] Error 1
> make[4]: *** Waiting for unfinished jobs....
> make[3]: *** [/var/home/acme/git/perf/tools/build/Makefile.build:139: util] Error 2
> make[2]: *** [Makefile.perf:665: /tmp/build/perf/perf-in.o] Error 2
> make[1]: *** [Makefile.perf:240: sub-make] Error 2
> make: *** [Makefile:113: install-bin] Error 2
> make: Leaving directory '/var/home/acme/git/perf/tools/perf'
> 
>  Performance counter stats for 'make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin':
> 
>     15,589,752,360      cycles:u
>     28,227,862,710      instructions:u            #    1.81  insn per cycle
> 
>        1.996638375 seconds time elapsed
> 
>        3.567457000 seconds user
>        0.934840000 seconds sys
> 
> 
> ?[acme at toolbox perf]$ git log --oneline -1
> 0083ba4c6a931fd0 (HEAD) perf bpf: Rename cpu to cpu_map_idx
> ?[acme at toolbox perf]$
> 
> Trying to fix...

Would be better to have the "Shorten 3 lines of code in bperf_read by
using perf_cpu_map__for_each_cpu." in a separate patch, try to do this
next time.

Below cures the two issues.

- Arnaldo


    Committer notes:

    Found when building with BUILD_BPF_SKEL=1:

    Remove unused 'num_cpu' variable in bperf__read().

    Make 'j' an 'int' as it is used in perf_cpu_map__for_each_cpu() to compare against an 'int'


diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
index ae5bd87ff02033c2..80d1a3a31052fe55 100644
--- a/tools/perf/util/bpf_counter.c
+++ b/tools/perf/util/bpf_counter.c
@@ -608,7 +608,8 @@ static int bperf__read(struct evsel *evsel)
 	__u32 num_cpu_bpf = cpu__max_cpu();
 	struct bpf_perf_event_value values[num_cpu_bpf];
 	int reading_map_fd, err = 0;
-	__u32 i, j, num_cpu;
+	__u32 i;
+	int j;
 
 	bperf_sync_counters(evsel);
 	reading_map_fd = bpf_map__fd(skel->maps.accum_readings);


From song at kernel.org  Mon Jan 10 11:30:34 2022
From: song at kernel.org (Song Liu)
Date: Mon, 10 Jan 2022 11:30:34 -0800
Subject: [PATCH v1 04/14] arm64: defconfig: enable bpf/cgroup firewalling
In-Reply-To: <20220107180314.1816515-5-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-5-marcel@ziswiler.com>
Message-ID: <CAPhsuW6sewYKBbCh+EcY-6PcwQV_+4-Pm1bmgXcZepzoAH=Z6g@mail.gmail.com>

On Fri, Jan 7, 2022 at 10:06 AM Marcel Ziswiler <marcel at ziswiler.com> wrote:
>
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>
> This avoids the following systemd warning:
>
> [    2.618538] systemd[1]: system-getty.slice: unit configures an IP
>  firewall, but the local system does not support BPF/cgroup firewalling.
> [    2.630916] systemd[1]: (This warning is only shown for the first
>  unit using IP firewalling.)
>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Acked-by: Song Liu <songliubraving at fb.com>


From robh at kernel.org  Mon Jan 10 11:42:58 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 13:42:58 -0600
Subject: [PATCH 2/4] dt-bindings: power: supply: maxim,max14577: convert
 to dtschema
In-Reply-To: <20211229141524.34174-3-krzysztof.kozlowski@canonical.com>
References: <20211229141524.34174-1-krzysztof.kozlowski@canonical.com>
 <20211229141524.34174-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyMQiRRooFgjfyo@robh.at.kernel.org>

On Wed, 29 Dec 2021 15:15:22 +0100, Krzysztof Kozlowski wrote:
> Convert the Charger bindings of Maxim MAX14577/MAX77836 MUIC to DT
> schema format.  The existing bindings were defined in
> ../bindings/mfd/max14577.txt.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/power/supply/maxim,max14577.yaml | 84 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Mon Jan 10 11:44:08 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 13:44:08 -0600
Subject: [PATCH 4/4] dt-bindings: mfd: maxim, max14577: convert to dtschema
In-Reply-To: <20211229141524.34174-5-krzysztof.kozlowski@canonical.com>
References: <20211229141524.34174-1-krzysztof.kozlowski@canonical.com>
 <20211229141524.34174-5-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyMiHcyKNHipYCE@robh.at.kernel.org>

On Wed, Dec 29, 2021 at 03:15:24PM +0100, Krzysztof Kozlowski wrote:
> Convert the MFD part of Maxim MAX14577/MAX77836 MUIC to DT schema
> format.  The example DTS was copied from existing DTS
> (exynos3250-rinato.dts), so keep the license as GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/mfd/max14577.txt      | 147 -------------
>  .../bindings/mfd/maxim,max14577.yaml          | 195 ++++++++++++++++++
>  MAINTAINERS                                   |   2 +-
>  3 files changed, 196 insertions(+), 148 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt
>  create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
> 
> diff --git a/Documentation/devicetree/bindings/mfd/max14577.txt b/Documentation/devicetree/bindings/mfd/max14577.txt
> deleted file mode 100644
> index be11943a0560..000000000000
> --- a/Documentation/devicetree/bindings/mfd/max14577.txt
> +++ /dev/null
> @@ -1,147 +0,0 @@
> -Maxim MAX14577/77836 Multi-Function Device
> -
> -MAX14577 is a Multi-Function Device with Micro-USB Interface Circuit, Li+
> -Battery Charger and SFOUT LDO output for powering USB devices. It is
> -interfaced to host controller using I2C.
> -
> -MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
> -For the description of Fuel Gauge low SOC alert interrupt see:
> -../power/supply/max17040_battery.txt
> -
> -
> -Required properties:
> -- compatible : Must be "maxim,max14577" or "maxim,max77836".
> -- reg : I2C slave address for the max14577 chip (0x25 for max14577/max77836)
> -- interrupts : IRQ line for the chip.
> -
> -
> -Required nodes:
> - - charger :
> -	Node for configuring the charger driver.
> -	Required properties:
> -		- compatible : "maxim,max14577-charger"
> -			or "maxim,max77836-charger"
> -		- maxim,fast-charge-uamp : Current in uA for Fast Charge;
> -			Valid values:
> -			- for max14577: 90000 - 950000;
> -			- for max77836: 45000 - 475000;
> -		- maxim,eoc-uamp : Current in uA for End-Of-Charge mode;
> -			Valid values:
> -			- for max14577: 50000 - 200000;
> -			- for max77836: 5000 - 100000;
> -		- maxim,ovp-uvolt : OverVoltage Protection Threshold in uV;
> -			In an overvoltage condition, INT asserts and charging
> -			stops. Valid values:
> -			- 6000000, 6500000, 7000000, 7500000;
> -		- maxim,constant-uvolt : Battery Constant Voltage in uV;
> -			Valid values:
> -			- 4000000 - 4280000 (step by 20000);
> -			- 4350000;
> -
> -
> -Optional nodes:
> -- max14577-muic/max77836-muic :
> -	Node used only by extcon consumers.
> -	Required properties:
> -		- compatible : "maxim,max14577-muic" or "maxim,max77836-muic"
> -
> -- regulators :
> -	Required properties:
> -		- compatible : "maxim,max14577-regulator"
> -			or "maxim,max77836-regulator"
> -
> -	May contain a sub-node per regulator from the list below. Each
> -	sub-node should contain the constraints and initialization information
> -	for that regulator. See regulator.txt for a description of standard
> -	properties for these sub-nodes.
> -
> -	List of valid regulator names:
> -	- for max14577: CHARGER, SAFEOUT.
> -	- for max77836: CHARGER, SAFEOUT, LDO1, LDO2.
> -
> -	The SAFEOUT is a fixed voltage regulator so there is no need to specify
> -	voltages for it.
> -
> -
> -Example:
> -
> -#include <dt-bindings/interrupt-controller/irq.h>
> -
> -max14577 at 25 {
> -	compatible = "maxim,max14577";
> -	reg = <0x25>;
> -	interrupt-parent = <&gpx1>;
> -	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
> -
> -	muic: max14577-muic {
> -		compatible = "maxim,max14577-muic";
> -	};
> -
> -	regulators {
> -		compatible = "maxim,max14577-regulator";
> -
> -		SAFEOUT {
> -			regulator-name = "SAFEOUT";
> -		};
> -		CHARGER {
> -			regulator-name = "CHARGER";
> -			regulator-min-microamp = <90000>;
> -			regulator-max-microamp = <950000>;
> -			regulator-boot-on;
> -		};
> -	};
> -
> -	charger {
> -		compatible = "maxim,max14577-charger";
> -
> -		maxim,constant-uvolt = <4350000>;
> -		maxim,fast-charge-uamp = <450000>;
> -		maxim,eoc-uamp = <50000>;
> -		maxim,ovp-uvolt = <6500000>;
> -	};
> -};
> -
> -
> -max77836 at 25 {
> -	compatible = "maxim,max77836";
> -	reg = <0x25>;
> -	interrupt-parent = <&gpx1>;
> -	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
> -
> -	muic: max77836-muic {
> -		compatible = "maxim,max77836-muic";
> -	};
> -
> -	regulators {
> -		compatible = "maxim,max77836-regulator";
> -
> -		SAFEOUT {
> -			regulator-name = "SAFEOUT";
> -		};
> -		CHARGER {
> -			regulator-name = "CHARGER";
> -			regulator-min-microamp = <90000>;
> -			regulator-max-microamp = <950000>;
> -			regulator-boot-on;
> -		};
> -		LDO1 {
> -			regulator-name = "LDO1";
> -			regulator-min-microvolt = <2700000>;
> -			regulator-max-microvolt = <2700000>;
> -		};
> -		LDO2 {
> -			regulator-name = "LDO2";
> -			regulator-min-microvolt = <800000>;
> -			regulator-max-microvolt = <3950000>;
> -		};
> -	};
> -
> -	charger {
> -		compatible = "maxim,max77836-charger";
> -
> -		maxim,constant-uvolt = <4350000>;
> -		maxim,fast-charge-uamp = <225000>;
> -		maxim,eoc-uamp = <7500>;
> -		maxim,ovp-uvolt = <6500000>;
> -	};
> -};
> diff --git a/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
> new file mode 100644
> index 000000000000..512fd671595c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
> @@ -0,0 +1,195 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/maxim,max14577.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
> +  Integrated Circuit (MUIC).
> +
> +  The Maxim MAX14577 is a MicroUSB and Companion Power Management IC which
> +  includes voltage safeout regulators, charger and MicroUSB management IC.
> +
> +  The Maxim MAX77836 is a MicroUSB and Companion Power Management IC which
> +  includes voltage safeout and LDO regulators, charger, fuel-gauge and MicroUSB
> +  management IC.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - maxim,max14577
> +      - maxim,max77836
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +  wakeup-source: true
> +
> +  charger:
> +    $ref: ../power/supply/maxim,max14577.yaml

/schemas/power/...

With those fixed,

Reviewed-by: Rob Herring <robh at kernel.org>

> +
> +  extcon:
> +    type: object
> +    properties:
> +      compatible:
> +        enum:
> +          - maxim,max14577-muic
> +          - maxim,max77836-muic
> +
> +    required:
> +      - compatible
> +
> +  regulators:
> +    $ref: ../regulator/maxim,max14577.yaml
> +
> +required:
> +  - compatible
> +  - interrupts
> +  - reg
> +  - charger
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: maxim,max14577
> +    then:
> +      properties:
> +        charger:
> +          properties:
> +            compatible:
> +              const: maxim,max14577-charger
> +        extcon:
> +          properties:
> +            compatible:
> +              const: maxim,max14577-muic
> +        regulator:
> +          properties:
> +            compatible:
> +              const: maxim,max14577-regulator
> +    else:
> +      properties:
> +        charger:
> +          properties:
> +            compatible:
> +              const: maxim,max77836-charger
> +        extcon:
> +          properties:
> +            compatible:
> +              const: maxim,max77836-muic
> +        regulator:
> +          properties:
> +            compatible:
> +              const: maxim,max77836-regulator
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        pmic at 25 {
> +            compatible = "maxim,max14577";
> +            reg = <0x25>;
> +            interrupt-parent = <&gpx1>;
> +            interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
> +
> +            extcon {
> +                compatible = "maxim,max14577-muic";
> +            };
> +
> +            regulators {
> +                compatible = "maxim,max14577-regulator";
> +
> +                SAFEOUT {
> +                    regulator-name = "SAFEOUT";
> +                };
> +
> +                CHARGER {
> +                    regulator-name = "CHARGER";
> +                    regulator-min-microamp = <90000>;
> +                    regulator-max-microamp = <950000>;
> +                    regulator-boot-on;
> +                };
> +            };
> +
> +            charger {
> +                compatible = "maxim,max14577-charger";
> +
> +                maxim,constant-uvolt = <4350000>;
> +                maxim,fast-charge-uamp = <450000>;
> +                maxim,eoc-uamp = <50000>;
> +                maxim,ovp-uvolt = <6500000>;
> +            };
> +        };
> +    };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        pmic at 25 {
> +            compatible = "maxim,max77836";
> +            interrupt-parent = <&gpx1>;
> +            interrupts = <5 IRQ_TYPE_NONE>;
> +            reg = <0x25>;
> +            wakeup-source;
> +
> +            extcon {
> +                compatible = "maxim,max77836-muic";
> +            };
> +
> +            regulators {
> +                compatible = "maxim,max77836-regulator";
> +
> +                SAFEOUT {
> +                  regulator-name = "SAFEOUT";
> +                };
> +
> +                CHARGER {
> +                  regulator-name = "CHARGER";
> +                  regulator-min-microamp = <45000>;
> +                  regulator-max-microamp = <475000>;
> +                  regulator-boot-on;
> +                };
> +
> +                LDO1 {
> +                  regulator-name = "MOT_2.7V";
> +                  regulator-min-microvolt = <1100000>;
> +                  regulator-max-microvolt = <2700000>;
> +                };
> +
> +                LDO2 {
> +                  regulator-name = "UNUSED_LDO2";
> +                  regulator-min-microvolt = <800000>;
> +                  regulator-max-microvolt = <3950000>;
> +                };
> +            };
> +
> +            charger {
> +                compatible = "maxim,max77836-charger";
> +
> +                maxim,constant-uvolt = <4350000>;
> +                maxim,fast-charge-uamp = <225000>;
> +                maxim,eoc-uamp = <7500>;
> +                maxim,ovp-uvolt = <6500000>;
> +            };
> +        };
> +    };
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 13e21c229c5d..af392bd04874 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11692,11 +11692,11 @@ M:	Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>  M:	Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
>  L:	linux-kernel at vger.kernel.org
>  S:	Supported
> +F:	Documentation/devicetree/bindings/*/maxim,max14577.yaml
>  F:	Documentation/devicetree/bindings/*/maxim,max77686.yaml
>  F:	Documentation/devicetree/bindings/*/maxim,max77693.yaml
>  F:	Documentation/devicetree/bindings/*/maxim,max77843.yaml
>  F:	Documentation/devicetree/bindings/clock/maxim,max77686.txt
> -F:	Documentation/devicetree/bindings/mfd/max14577.txt
>  F:	drivers/*/*max77843.c
>  F:	drivers/*/max14577*.c
>  F:	drivers/*/max77686*.c
> -- 
> 2.32.0
> 
> 


From acme at kernel.org  Mon Jan 10 11:50:45 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 16:50:45 -0300
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <20220105061351.120843-49-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
Message-ID: <YdyOFd8JJHbm1W+m@kernel.org>

Em Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers escreveu:
> A common problem is confusing CPU map indices with the CPU, by wrapping
> the CPU with a struct then this is avoided. This approach is similar to
> atomic_t.

This one needed this to build with BUILD_BPF_SKEL=1, please check, I'll
soon push this to tmp.perf/perf_cpu so that you can take a look and test
it.

- Arnaldo

diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
index 80d1a3a31052fe55..328479df5e16a638 100644
--- a/tools/perf/util/bpf_counter.c
+++ b/tools/perf/util/bpf_counter.c
@@ -540,7 +540,7 @@ static int bperf__load(struct evsel *evsel, struct target *target)
 		    filter_type == BPERF_FILTER_TGID)
 			key = evsel->core.threads->map[i].pid;
 		else if (filter_type == BPERF_FILTER_CPU)
-			key = evsel->core.cpus->map[i];
+			key = evsel->core.cpus->map[i].cpu;
 		else
 			break;
 
@@ -584,7 +584,7 @@ static int bperf_sync_counters(struct evsel *evsel)
 
 	num_cpu = all_cpu_map->nr;
 	for (i = 0; i < num_cpu; i++) {
-		cpu = all_cpu_map->map[i];
+		cpu = all_cpu_map->map[i].cpu;
 		bperf_trigger_reading(evsel->bperf_leader_prog_fd, cpu);
 	}
 	return 0;
@@ -605,7 +605,7 @@ static int bperf__disable(struct evsel *evsel)
 static int bperf__read(struct evsel *evsel)
 {
 	struct bperf_follower_bpf *skel = evsel->follower_skel;
-	__u32 num_cpu_bpf = cpu__max_cpu();
+	__u32 num_cpu_bpf = cpu__max_cpu().cpu;
 	struct bpf_perf_event_value values[num_cpu_bpf];
 	int reading_map_fd, err = 0;
 	__u32 i;
@@ -615,6 +615,7 @@ static int bperf__read(struct evsel *evsel)
 	reading_map_fd = bpf_map__fd(skel->maps.accum_readings);
 
 	for (i = 0; i < bpf_map__max_entries(skel->maps.accum_readings); i++) {
+		struct perf_cpu entry;
 		__u32 cpu;
 
 		err = bpf_map_lookup_elem(reading_map_fd, &i, values);
@@ -624,14 +625,15 @@ static int bperf__read(struct evsel *evsel)
 		case BPERF_FILTER_GLOBAL:
 			assert(i == 0);
 
-			perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
+			perf_cpu_map__for_each_cpu(entry, j, all_cpu_map) {
+				cpu = entry.cpu;
 				perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
 				perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
 				perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
 			}
 			break;
 		case BPERF_FILTER_CPU:
-			cpu = evsel->core.cpus->map[i];
+			cpu = evsel->core.cpus->map[i].cpu;
 			perf_counts(evsel->counts, i, 0)->val = values[cpu].counter;
 			perf_counts(evsel->counts, i, 0)->ena = values[cpu].enabled;
 			perf_counts(evsel->counts, i, 0)->run = values[cpu].running;
diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
index cbc6c2bca488f6bf..631e34a0b66ff084 100644
--- a/tools/perf/util/bpf_counter_cgroup.c
+++ b/tools/perf/util/bpf_counter_cgroup.c
@@ -48,7 +48,7 @@ static int bperf_load_program(struct evlist *evlist)
 	struct cgroup *cgrp, *leader_cgrp;
 	__u32 i, cpu;
 	__u32 nr_cpus = evlist->core.all_cpus->nr;
-	int total_cpus = cpu__max_cpu();
+	int total_cpus = cpu__max_cpu().cpu;
 	int map_size, map_fd;
 	int prog_fd, err;
 
@@ -125,7 +125,7 @@ static int bperf_load_program(struct evlist *evlist)
 			for (cpu = 0; cpu < nr_cpus; cpu++) {
 				int fd = FD(evsel, cpu);
 				__u32 idx = evsel->core.idx * total_cpus +
-					evlist->core.all_cpus->map[cpu];
+					evlist->core.all_cpus->map[cpu].cpu;
 
 				err = bpf_map_update_elem(map_fd, &idx, &fd,
 							  BPF_ANY);
@@ -212,7 +212,7 @@ static int bperf_cgrp__sync_counters(struct evlist *evlist)
 	int prog_fd = bpf_program__fd(skel->progs.trigger_read);
 
 	for (i = 0; i < nr_cpus; i++) {
-		cpu = evlist->core.all_cpus->map[i];
+		cpu = evlist->core.all_cpus->map[i].cpu;
 		bperf_trigger_reading(prog_fd, cpu);
 	}
 
@@ -245,7 +245,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
 {
 	struct evlist *evlist = evsel->evlist;
 	int i, cpu, nr_cpus = evlist->core.all_cpus->nr;
-	int total_cpus = cpu__max_cpu();
+	int total_cpus = cpu__max_cpu().cpu;
 	struct perf_counts_values *counts;
 	struct bpf_perf_event_value *values;
 	int reading_map_fd, err = 0;
@@ -272,7 +272,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
 		}
 
 		for (i = 0; i < nr_cpus; i++) {
-			cpu = evlist->core.all_cpus->map[i];
+			cpu = evlist->core.all_cpus->map[i].cpu;
 
 			counts = perf_counts(evsel->counts, i, 0);
 			counts->val = values[cpu].counter;
diff --git a/tools/perf/util/bpf_ftrace.c b/tools/perf/util/bpf_ftrace.c
index 28dc4c60c7884818..d756cc66eef32ae8 100644
--- a/tools/perf/util/bpf_ftrace.c
+++ b/tools/perf/util/bpf_ftrace.c
@@ -63,7 +63,7 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace *ftrace)
 		fd = bpf_map__fd(skel->maps.cpu_filter);
 
 		for (i = 0; i < ncpus; i++) {
-			cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i);
+			cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i).cpu;
 			bpf_map_update_elem(fd, &cpu, &val, BPF_ANY);
 		}
 	}
@@ -122,7 +122,7 @@ int perf_ftrace__latency_read_bpf(struct perf_ftrace *ftrace __maybe_unused,
 	int i, fd, err;
 	u32 idx;
 	u64 *hist;
-	int ncpus = cpu__max_cpu();
+	int ncpus = cpu__max_cpu().cpu;
 
 	fd = bpf_map__fd(skel->maps.latency);
 


From sboyd at kernel.org  Mon Jan 10 12:12:00 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 10 Jan 2022 12:12:00 -0800
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
 <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
Message-ID: <20220110201201.C1E37C36AE9@smtp.kernel.org>

Quoting Jesse Taube (2022-01-09 11:07:42)
> >> +
> >> +       clk_hw_data->num = IMXRT1050_CLK_END;
> >> +       hws = clk_hw_data->hws;
> >> +
> >> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> > 
> > Use clk_parent_data instead and reference the binding name with .fw_name
> 
> Hi Stephen, sorry to bother you again.
> I'm wondering if adding `clk_parent_data` is necessary as it seems like 
> it wold be a big change and the other IMX boards haven't implemented 
> this yet would it be okay if I don't do this, or if it is necessary 
> could you link to a patch set to change it.
> 

Is it a big change because the imx_clk_hw*() APIs aren't prepared for
non-string parents? Can you make some clk_parent_data based APIs and
migrate things over gradually? This is really a question for i.MX folks
to see if anyone is working on moving away from the string names.


From acme at kernel.org  Mon Jan 10 12:17:25 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 17:17:25 -0300
Subject: [PATCH v4 00/48] Refactor perf cpumap
In-Reply-To: <20220105061351.120843-1-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
Message-ID: <YdyUVSHs/OLZ9Ntm@kernel.org>

Em Tue, Jan 04, 2022 at 10:13:03PM -0800, Ian Rogers escreveu:
> Perf cpu map has various functions where a cpumap and index are passed
> in order to load the cpu. A problem with this is that the wrong index
> may be passed for the cpumap, causing problems like aggregation on the
> wrong CPU:
> https://lore.kernel.org/lkml/20211204023409.969668-1-irogers at google.com/
> 
> This patch set refactors the cpu map API, reducing it and explicitly
> passing the cpu (rather than the pair) to functions that need
> it. Comments are added at the same time. Changes modify the same
> file/function more than once as refactoring and fixes are broken apart
> for the sake of bisection.
> 
> v2. Incorproates fixes suggested Jiri Olsa, rewrites the evlist CPU
>     iterator in part in a way suggested by Riccardo Mancini. The new
>     fixes start at patch 23. The final change was suggested by John
>     Garry to make the CPUs have their own struct wrapper.
> 
> v3. Incorporates fixes suggested by Namhyung Kim.
> 
> v4. Rebases and incorporates fixes suggested by Jiri Olsa.

Did fixes in places where BUILD_BPF_SKEL=1 was failing, now, at the end
of the series:

?[acme at toolbox perf]$ git log --oneline -1 ; time make -C tools/perf build-test
462aafa8fcbdc78f (HEAD -> perf/core) perf cpumap: Give CPUs their own type
make: Entering directory '/var/home/acme/git/perf/tools/perf'
- tarpkg: ./tests/perf-targz-src-pkg .
                 make_static: cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 -j32  DESTDIR=/tmp/tmp.lFrqVcqiRY
              make_with_gtk2: cd . && make GTK2=1 -j32  DESTDIR=/tmp/tmp.KvHmTqUGmD
- /var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP: cd . && make FEATURE_DUMP_COPY=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP  feature-dump
cd . && make FEATURE_DUMP_COPY=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP feature-dump
            make_no_libelf_O: cd . && make NO_LIBELF=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.xz3LYy7WpA DESTDIR=/tmp/tmp.zVjIMpvQMM
      make_no_libbpf_DEBUG_O: cd . && make NO_LIBBPF=1 DEBUG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.0gxAOSjb1j DESTDIR=/tmp/tmp.kYTk1WjWWz
          make_no_libaudit_O: cd . && make NO_LIBAUDIT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.6hArTG9Dth DESTDIR=/tmp/tmp.hCNdYeDRCr
         make_no_backtrace_O: cd . && make NO_BACKTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.VtoPI58z3t DESTDIR=/tmp/tmp.SYyBBMSHSL
         make_no_libcrypto_O: cd . && make NO_LIBCRYPTO=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.SO1qtxJwvE DESTDIR=/tmp/tmp.AqrPw1oZfx
       make_with_clangllvm_O: cd . && make LIBCLANGLLVM=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.G9KVEaDv2B DESTDIR=/tmp/tmp.6CSqj0wPqJ
       make_with_coresight_O: cd . && make CORESIGHT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.PnVTJNHy1E DESTDIR=/tmp/tmp.k7Arerg778
         make_no_libpython_O: cd . && make NO_LIBPYTHON=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.cKjvFagVL3 DESTDIR=/tmp/tmp.aCaD0hbP3O
               make_no_sdt_O: cd . && make NO_SDT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.EKoWnoZtl4 DESTDIR=/tmp/tmp.1gGYetcptB
       make_libbpf_dynamic_O: cd . && make LIBBPF_DYNAMIC=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.Nked5O10EK DESTDIR=/tmp/tmp.eo6YAEOfZO
              make_minimal_O: cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1 NO_LIBCAP=1 NO_SYSCALL_TABLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.Z6dSqYBXfU DESTDIR=/tmp/tmp.Y4iRu634of
 make_install_prefix_slash_O: cd . && make install prefix=/tmp/krava/ FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.BgipDyNu70 DESTDIR=/tmp/tmp.pOwrdDYBqf
     make_util_pmu_bison_o_O: cd . && make util/pmu-bison.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.XeO82Ajmv6 DESTDIR=/tmp/tmp.dxQKNNBM6W
              make_install_O: cd . && make install FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.KuCyqzLwnA DESTDIR=/tmp/tmp.KYvqoiOKzW
       make_install_prefix_O: cd . && make install prefix=/tmp/krava FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.rJNNPELdri DESTDIR=/tmp/tmp.g52i9CcmnU
          make_install_bin_O: cd . && make install-bin FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.i118vbQuo0 DESTDIR=/tmp/tmp.90tKcjOWD8
               make_perf_o_O: cd . && make perf.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.kEZMTvh3wf DESTDIR=/tmp/tmp.JYvQLdkPsp
             make_no_slang_O: cd . && make NO_SLANG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.WDNGH0DpdW DESTDIR=/tmp/tmp.Zfa804wClJ
                make_no_ui_O: cd . && make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.P4nTBNqkP4 DESTDIR=/tmp/tmp.iCLqOyrh4o
              make_no_newt_O: cd . && make NO_NEWT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.EdjjHoqODV DESTDIR=/tmp/tmp.jKfYRizWtm
         make_with_libpfm4_O: cd . && make LIBPFM4=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.r3hPAOgfId DESTDIR=/tmp/tmp.GvMmEZUc2B
          make_no_demangle_O: cd . && make NO_DEMANGLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.wG9f40LzG3 DESTDIR=/tmp/tmp.i76sPjSg1m
         make_no_libunwind_O: cd . && make NO_LIBUNWIND=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.SmFfmmB9KQ DESTDIR=/tmp/tmp.9tjMdCWMxG
            make_no_libbpf_O: cd . && make NO_LIBBPF=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.7jH21oP9n7 DESTDIR=/tmp/tmp.taUqTgY37S
       make_no_syscall_tbl_O: cd . && make NO_SYSCALL_TABLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.L2v7vi1AQl DESTDIR=/tmp/tmp.wHEA4jEpw9
           make_no_libnuma_O: cd . && make NO_LIBNUMA=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.9N5pQYuRbO DESTDIR=/tmp/tmp.B0Yptb7xP6
           make_util_map_o_O: cd . && make util/map.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.B8oe4jnWwB DESTDIR=/tmp/tmp.m0APlsli14
      make_with_babeltrace_O: cd . && make LIBBABELTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.3G1kLTJLJx DESTDIR=/tmp/tmp.ahuDENSMsz
                make_debug_O: cd . && make DEBUG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.KpsvOj0KHD DESTDIR=/tmp/tmp.f2Yv9Lrorg
           make_no_libperl_O: cd . && make NO_LIBPERL=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.7tIufwAi4O DESTDIR=/tmp/tmp.vcBv7UYjuw
         make_no_libbionic_O: cd . && make NO_LIBBIONIC=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.HCJA7xCDxq DESTDIR=/tmp/tmp.us5CDSPqyO
                 make_pure_O: cd . && make FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.eg2wCpydvg DESTDIR=/tmp/tmp.MmD1xESO2A
                  make_doc_O: cd . && make doc FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.TqkyGrzRut DESTDIR=/tmp/tmp.ap34IVxoM9
           make_no_scripts_O: cd . && make NO_LIBPYTHON=1 NO_LIBPERL=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.pRWHKzpPhv DESTDIR=/tmp/tmp.dUNhAp2rLt
            make_clean_all_O: cd . && make clean all FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.YnzNLLk9ID DESTDIR=/tmp/tmp.7kXr5obkmA
make_no_libdw_dwarf_unwind_O: cd . && make NO_LIBDW_DWARF_UNWIND=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.GzZCxuYLwR DESTDIR=/tmp/tmp.n3YS9a9DcU
                 make_help_O: cd . && make help FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.t7QwWVHsod DESTDIR=/tmp/tmp.NG5uSWCZzi
          make_no_auxtrace_O: cd . && make NO_AUXTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.wiDZkJzs8R DESTDIR=/tmp/tmp.ITtPlX0usX
              make_no_gtk2_O: cd . && make NO_GTK2=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.xd1x5QIckJ DESTDIR=/tmp/tmp.f6KzsHHkZH
                 make_tags_O: cd . && make tags FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.e8oSaBuFUb DESTDIR=/tmp/tmp.4czd6ovlSB
OK
make: Leaving directory '/var/home/acme/git/perf/tools/perf'

real	4m29.388s
user	59m6.060s
sys	12m19.581s
?[acme at toolbox perf]$

alias m='perf stat -e cycles:u,instructions:u make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin && git status && perf test python'

So 'perf test python' is done after every build, no problems with that
as well.

I'm now making it go thru the container builds.

- Arnaldo




From acme at kernel.org  Mon Jan 10 12:40:11 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 17:40:11 -0300
Subject: [PATCH v4 00/48] Refactor perf cpumap
In-Reply-To: <YdyUVSHs/OLZ9Ntm@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <YdyUVSHs/OLZ9Ntm@kernel.org>
Message-ID: <YdyZq4dHjhJrxOHb@kernel.org>

Em Mon, Jan 10, 2022 at 05:17:25PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 04, 2022 at 10:13:03PM -0800, Ian Rogers escreveu:
> > Perf cpu map has various functions where a cpumap and index are passed
> > in order to load the cpu. A problem with this is that the wrong index
> > may be passed for the cpumap, causing problems like aggregation on the
> > wrong CPU:
> > https://lore.kernel.org/lkml/20211204023409.969668-1-irogers at google.com/
> > 
> > This patch set refactors the cpu map API, reducing it and explicitly
> > passing the cpu (rather than the pair) to functions that need
> > it. Comments are added at the same time. Changes modify the same
> > file/function more than once as refactoring and fixes are broken apart
> > for the sake of bisection.
> > 
> > v2. Incorproates fixes suggested Jiri Olsa, rewrites the evlist CPU
> >     iterator in part in a way suggested by Riccardo Mancini. The new
> >     fixes start at patch 23. The final change was suggested by John
> >     Garry to make the CPUs have their own struct wrapper.
> > 
> > v3. Incorporates fixes suggested by Namhyung Kim.
> > 
> > v4. Rebases and incorporates fixes suggested by Jiri Olsa.
> 
> Did fixes in places where BUILD_BPF_SKEL=1 was failing, now, at the end
> of the series:
> 
> ?[acme at toolbox perf]$ git log --oneline -1 ; time make -C tools/perf build-test
> 462aafa8fcbdc78f (HEAD -> perf/core) perf cpumap: Give CPUs their own type
> make: Entering directory '/var/home/acme/git/perf/tools/perf'
> - tarpkg: ./tests/perf-targz-src-pkg .
>                  make_static: cd . && make LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX32=1 NO_JVMTI=1 -j32  DESTDIR=/tmp/tmp.lFrqVcqiRY
>               make_with_gtk2: cd . && make GTK2=1 -j32  DESTDIR=/tmp/tmp.KvHmTqUGmD
> - /var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP: cd . && make FEATURE_DUMP_COPY=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP  feature-dump
> cd . && make FEATURE_DUMP_COPY=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP feature-dump
>             make_no_libelf_O: cd . && make NO_LIBELF=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.xz3LYy7WpA DESTDIR=/tmp/tmp.zVjIMpvQMM
>       make_no_libbpf_DEBUG_O: cd . && make NO_LIBBPF=1 DEBUG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.0gxAOSjb1j DESTDIR=/tmp/tmp.kYTk1WjWWz
>           make_no_libaudit_O: cd . && make NO_LIBAUDIT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.6hArTG9Dth DESTDIR=/tmp/tmp.hCNdYeDRCr
>          make_no_backtrace_O: cd . && make NO_BACKTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.VtoPI58z3t DESTDIR=/tmp/tmp.SYyBBMSHSL
>          make_no_libcrypto_O: cd . && make NO_LIBCRYPTO=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.SO1qtxJwvE DESTDIR=/tmp/tmp.AqrPw1oZfx
>        make_with_clangllvm_O: cd . && make LIBCLANGLLVM=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.G9KVEaDv2B DESTDIR=/tmp/tmp.6CSqj0wPqJ
>        make_with_coresight_O: cd . && make CORESIGHT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.PnVTJNHy1E DESTDIR=/tmp/tmp.k7Arerg778
>          make_no_libpython_O: cd . && make NO_LIBPYTHON=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.cKjvFagVL3 DESTDIR=/tmp/tmp.aCaD0hbP3O
>                make_no_sdt_O: cd . && make NO_SDT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.EKoWnoZtl4 DESTDIR=/tmp/tmp.1gGYetcptB
>        make_libbpf_dynamic_O: cd . && make LIBBPF_DYNAMIC=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.Nked5O10EK DESTDIR=/tmp/tmp.eo6YAEOfZO
>               make_minimal_O: cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1 NO_LIBCAP=1 NO_SYSCALL_TABLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.Z6dSqYBXfU DESTDIR=/tmp/tmp.Y4iRu634of
>  make_install_prefix_slash_O: cd . && make install prefix=/tmp/krava/ FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.BgipDyNu70 DESTDIR=/tmp/tmp.pOwrdDYBqf
>      make_util_pmu_bison_o_O: cd . && make util/pmu-bison.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.XeO82Ajmv6 DESTDIR=/tmp/tmp.dxQKNNBM6W
>               make_install_O: cd . && make install FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.KuCyqzLwnA DESTDIR=/tmp/tmp.KYvqoiOKzW
>        make_install_prefix_O: cd . && make install prefix=/tmp/krava FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.rJNNPELdri DESTDIR=/tmp/tmp.g52i9CcmnU
>           make_install_bin_O: cd . && make install-bin FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.i118vbQuo0 DESTDIR=/tmp/tmp.90tKcjOWD8
>                make_perf_o_O: cd . && make perf.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.kEZMTvh3wf DESTDIR=/tmp/tmp.JYvQLdkPsp
>              make_no_slang_O: cd . && make NO_SLANG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.WDNGH0DpdW DESTDIR=/tmp/tmp.Zfa804wClJ
>                 make_no_ui_O: cd . && make NO_NEWT=1 NO_SLANG=1 NO_GTK2=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.P4nTBNqkP4 DESTDIR=/tmp/tmp.iCLqOyrh4o
>               make_no_newt_O: cd . && make NO_NEWT=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.EdjjHoqODV DESTDIR=/tmp/tmp.jKfYRizWtm
>          make_with_libpfm4_O: cd . && make LIBPFM4=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.r3hPAOgfId DESTDIR=/tmp/tmp.GvMmEZUc2B
>           make_no_demangle_O: cd . && make NO_DEMANGLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.wG9f40LzG3 DESTDIR=/tmp/tmp.i76sPjSg1m
>          make_no_libunwind_O: cd . && make NO_LIBUNWIND=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.SmFfmmB9KQ DESTDIR=/tmp/tmp.9tjMdCWMxG
>             make_no_libbpf_O: cd . && make NO_LIBBPF=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.7jH21oP9n7 DESTDIR=/tmp/tmp.taUqTgY37S
>        make_no_syscall_tbl_O: cd . && make NO_SYSCALL_TABLE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.L2v7vi1AQl DESTDIR=/tmp/tmp.wHEA4jEpw9
>            make_no_libnuma_O: cd . && make NO_LIBNUMA=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.9N5pQYuRbO DESTDIR=/tmp/tmp.B0Yptb7xP6
>            make_util_map_o_O: cd . && make util/map.o FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.B8oe4jnWwB DESTDIR=/tmp/tmp.m0APlsli14
>       make_with_babeltrace_O: cd . && make LIBBABELTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.3G1kLTJLJx DESTDIR=/tmp/tmp.ahuDENSMsz
>                 make_debug_O: cd . && make DEBUG=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.KpsvOj0KHD DESTDIR=/tmp/tmp.f2Yv9Lrorg
>            make_no_libperl_O: cd . && make NO_LIBPERL=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.7tIufwAi4O DESTDIR=/tmp/tmp.vcBv7UYjuw
>          make_no_libbionic_O: cd . && make NO_LIBBIONIC=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.HCJA7xCDxq DESTDIR=/tmp/tmp.us5CDSPqyO
>                  make_pure_O: cd . && make FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.eg2wCpydvg DESTDIR=/tmp/tmp.MmD1xESO2A
>                   make_doc_O: cd . && make doc FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.TqkyGrzRut DESTDIR=/tmp/tmp.ap34IVxoM9
>            make_no_scripts_O: cd . && make NO_LIBPYTHON=1 NO_LIBPERL=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.pRWHKzpPhv DESTDIR=/tmp/tmp.dUNhAp2rLt
>             make_clean_all_O: cd . && make clean all FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.YnzNLLk9ID DESTDIR=/tmp/tmp.7kXr5obkmA
> make_no_libdw_dwarf_unwind_O: cd . && make NO_LIBDW_DWARF_UNWIND=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.GzZCxuYLwR DESTDIR=/tmp/tmp.n3YS9a9DcU
>                  make_help_O: cd . && make help FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.t7QwWVHsod DESTDIR=/tmp/tmp.NG5uSWCZzi
>           make_no_auxtrace_O: cd . && make NO_AUXTRACE=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.wiDZkJzs8R DESTDIR=/tmp/tmp.ITtPlX0usX
>               make_no_gtk2_O: cd . && make NO_GTK2=1 FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.xd1x5QIckJ DESTDIR=/tmp/tmp.f6KzsHHkZH
>                  make_tags_O: cd . && make tags FEATURES_DUMP=/var/home/acme/git/perf/tools/perf/BUILD_TEST_FEATURE_DUMP -j32 O=/tmp/tmp.e8oSaBuFUb DESTDIR=/tmp/tmp.4czd6ovlSB
> OK
> make: Leaving directory '/var/home/acme/git/perf/tools/perf'
> 
> real	4m29.388s
> user	59m6.060s
> sys	12m19.581s
> ?[acme at toolbox perf]$
> 
> alias m='perf stat -e cycles:u,instructions:u make -k BUILD_BPF_SKEL=1 CORESIGHT=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin && git status && perf test python'
> 
> So 'perf test python' is done after every build, no problems with that
> as well.
> 
> I'm now making it go thru the container builds.

Not a good start, checking:

[perfbuilder at five ~]$ time dm
   1    50.25 almalinux:8                   : FAIL clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   2    54.14 alpine:3.4                    : FAIL clang version 3.8.0 (tags/RELEASE_380/final)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   3    39.78 alpine:3.5                    : FAIL clang version 3.8.1 (tags/RELEASE_381/final)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   4    82.52 alpine:3.6                    : FAIL clang version 4.0.0 (tags/RELEASE_400/final)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   5   113.61 alpine:3.7                    : FAIL gcc version 6.4.0 (Alpine 6.4.0)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   6   119.02 alpine:3.8                    : FAIL gcc version 6.4.0 (Alpine 6.4.0)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   7    64.55 alpine:3.9                    : FAIL gcc version 8.3.0 (Alpine 8.3.0)
    builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
    static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
                                  ^
    1 error generated.
   8: alpine:3.10


From robh at kernel.org  Mon Jan 10 12:40:19 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 14:40:19 -0600
Subject: [PATCH v7] dt-bindings: soc: grf: add naneng combo phy register
 compatible
In-Reply-To: <20211231082249.5075-1-jbx6244@gmail.com>
References: <20211230084815.28110-2-yifeng.zhao@rock-chips.com>
 <20211231082249.5075-1-jbx6244@gmail.com>
Message-ID: <YdyZs7dDFPCWfJd9@robh.at.kernel.org>

On Fri, 31 Dec 2021 09:22:49 +0100, Johan Jonker wrote:
> Add Naneng combo phy register compatible.
> 
> Signed-off-by: Johan Jonker <jbx6244 at gmail.com>
> ---
>  Documentation/devicetree/bindings/soc/rockchip/grf.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From acme at kernel.org  Mon Jan 10 12:42:35 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 17:42:35 -0300
Subject: [PATCH v4 00/48] Refactor perf cpumap
In-Reply-To: <YdyZq4dHjhJrxOHb@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <YdyUVSHs/OLZ9Ntm@kernel.org> <YdyZq4dHjhJrxOHb@kernel.org>
Message-ID: <YdyaOw5Yz8jmEfOw@kernel.org>

Em Mon, Jan 10, 2022 at 05:40:12PM -0300, Arnaldo Carvalho de Melo escreveu:
> > I'm now making it go thru the container builds.
> 
> Not a good start, checking:
> 
> [perfbuilder at five ~]$ time dm
>    1    50.25 almalinux:8                   : FAIL clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)

                                   ^
Interesting, it builds with gcc, not with clang:

+ make PYTHON=python3 ARCH= CROSS_COMPILE= EXTRA_CFLAGS= -C tools/perf O=/tmp/build/perf CC=clang

And it really isn't used anywhere in builtin-stat.c, will remove it
after figuring out when it stops being used.

- Arnaldo

>     1 error generated.
>    2    54.14 alpine:3.4                    : FAIL clang version 3.8.0 (tags/RELEASE_380/final)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    3    39.78 alpine:3.5                    : FAIL clang version 3.8.1 (tags/RELEASE_381/final)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    4    82.52 alpine:3.6                    : FAIL clang version 4.0.0 (tags/RELEASE_400/final)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    5   113.61 alpine:3.7                    : FAIL gcc version 6.4.0 (Alpine 6.4.0)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    6   119.02 alpine:3.8                    : FAIL gcc version 6.4.0 (Alpine 6.4.0)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    7    64.55 alpine:3.9                    : FAIL gcc version 8.3.0 (Alpine 8.3.0)
>     builtin-stat.c:1499:31: error: unused function 'perf_env__get_cpu' [-Werror,-Wunused-function]
>     static inline struct perf_cpu perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
>                                   ^
>     1 error generated.
>    8: alpine:3.10

-- 

- Arnaldo


From robh at kernel.org  Mon Jan 10 12:43:55 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 14:43:55 -0600
Subject: [PATCH 24/24] dt-bindings: pinctrl: samsung: convert to dtschema
In-Reply-To: <20211231162309.257587-7-krzysztof.kozlowski@canonical.com>
References: <20211231161930.256733-1-krzysztof.kozlowski@canonical.com>
 <20211231162309.257587-7-krzysztof.kozlowski@canonical.com>
Message-ID: <Ydyai46oaXI5+ixU@robh.at.kernel.org>

On Fri, 31 Dec 2021 17:23:09 +0100, Krzysztof Kozlowski wrote:
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) pin
> controller bindings to DT schema format.  Parts of description and DTS
> example was copied from existing sources, so keep the license as
> GPL-2.0-only.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../pinctrl/samsung,pinctrl-gpio-bank.yaml    |  52 +++
>  .../pinctrl/samsung,pinctrl-pins-cfg.yaml     |  81 ++++
>  .../samsung,pinctrl-wakeup-interrupt.yaml     |  76 ++++
>  .../bindings/pinctrl/samsung,pinctrl.yaml     | 381 +++++++++++++++++
>  .../bindings/pinctrl/samsung-pinctrl.txt      | 383 ------------------
>  MAINTAINERS                                   |   2 +-
>  6 files changed, 591 insertions(+), 384 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From acme at kernel.org  Mon Jan 10 12:46:52 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 17:46:52 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <20211230072030.302559-8-irogers@google.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
Message-ID: <YdybPJKjqx6zb28/@kernel.org>

Em Wed, Dec 29, 2021 at 11:19:48PM -0800, Ian Rogers escreveu:
> Avoid error prone cpu_map + idx variant. Remove now unused functions.

At this point we need to remove the now unused perf_env__get_cpu(), and
then deal with the fallout in the following patches that needlessly
modify this unused function.

Doing that now.

- Arnaldo

?[acme at toolbox perf]$ git diff
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 6b985abaa2d22c58..40cb3518f27e2309 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -1477,22 +1477,6 @@ static void perf_stat__exit_aggr_mode(void)
        stat_config.cpus_aggr_map = NULL;
 }

-static inline int perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
-{
-       struct perf_env *env = data;
-       int cpu;
-
-       if (idx > map->nr)
-               return -1;
-
-       cpu = map->map[idx];
-
-       if (cpu >= env->nr_cpus_avail)
-               return -1;
-
-       return cpu;
-}
-
 static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
 {
        struct perf_env *env = data;
 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/builtin-stat.c | 28 ++++------------------------
>  tools/perf/util/cpumap.c  | 12 ++++++------
>  tools/perf/util/cpumap.h  |  2 +-
>  3 files changed, 11 insertions(+), 31 deletions(-)
> 
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 9791ae9b1a53..6b985abaa2d2 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -1504,11 +1504,6 @@ static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
>  	return id;
>  }
>  
> -static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
> -{
> -	return perf_env__get_socket_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> -}
> -
>  static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
>  {
>  	struct perf_env *env = data;
> @@ -1527,11 +1522,6 @@ static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
>  	return id;
>  }
>  
> -static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
> -{
> -	return perf_env__get_die_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> -}
> -
>  static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
>  {
>  	struct perf_env *env = data;
> @@ -1551,11 +1541,6 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
>  	return id;
>  }
>  
> -static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
> -{
> -	return perf_env__get_core_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> -}
> -
>  static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
>  {
>  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> @@ -1564,33 +1549,28 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
>  	return id;
>  }
>  
> -static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
> -{
> -	return perf_env__get_node_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> -}
> -
>  static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
>  				      struct cpu_aggr_map **sockp)
>  {
> -	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
> +	return cpu_map__build_map(cpus, sockp, perf_env__get_socket_aggr_by_cpu, env);
>  }
>  
>  static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
>  				   struct cpu_aggr_map **diep)
>  {
> -	return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
> +	return cpu_map__build_map(cpus, diep, perf_env__get_die_aggr_by_cpu, env);
>  }
>  
>  static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
>  				    struct cpu_aggr_map **corep)
>  {
> -	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
> +	return cpu_map__build_map(cpus, corep, perf_env__get_core_aggr_by_cpu, env);
>  }
>  
>  static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
>  				    struct cpu_aggr_map **nodep)
>  {
> -	return cpu_map__build_map(cpus, nodep, perf_env__get_node, env);
> +	return cpu_map__build_map(cpus, nodep, perf_env__get_node_aggr_by_cpu, env);
>  }
>  
>  static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 49fba2c53822..feaf34b25efc 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -163,7 +163,7 @@ static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
>  }
>  
>  int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> -		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
> +		       struct aggr_cpu_id (*f)(int cpu, void *data),
>  		       void *data)
>  {
>  	int nr = cpus->nr;
> @@ -178,7 +178,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
>  	c->nr = 0;
>  
>  	for (cpu = 0; cpu < nr; cpu++) {
> -		s1 = f(cpus, cpu, data);
> +		s1 = f(cpu, data);
>  		for (s2 = 0; s2 < c->nr; s2++) {
>  			if (cpu_map__compare_aggr_cpu_id(s1, c->map[s2]))
>  				break;
> @@ -290,22 +290,22 @@ struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *da
>  
>  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
>  {
> -	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL);
> +	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket_aggr_by_cpu, NULL);
>  }
>  
>  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep)
>  {
> -	return cpu_map__build_map(cpus, diep, cpu_map__get_die, NULL);
> +	return cpu_map__build_map(cpus, diep, cpu_map__get_die_aggr_by_cpu, NULL);
>  }
>  
>  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep)
>  {
> -	return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL);
> +	return cpu_map__build_map(cpus, corep, cpu_map__get_core_aggr_by_cpu, NULL);
>  }
>  
>  int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **numap)
>  {
> -	return cpu_map__build_map(cpus, numap, cpu_map__get_node, NULL);
> +	return cpu_map__build_map(cpus, numap, cpu_map__get_node_aggr_by_cpu, NULL);
>  }
>  
>  /* setup simple routines to easily access node numbers given a cpu number */
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index c62d67704425..9648816c4255 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -63,7 +63,7 @@ int cpu__max_present_cpu(void);
>  int cpu__get_node(int cpu);
>  
>  int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> -		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
> +		       struct aggr_cpu_id (*f)(int cpu, void *data),
>  		       void *data);
>  
>  int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
> -- 
> 2.34.1.448.ga2b2bfdf31-goog

-- 

- Arnaldo


From robh at kernel.org  Mon Jan 10 12:53:52 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 14:53:52 -0600
Subject: [PATCH RFC 2/4] dt-bindings: arm: bcm2835: Add Raspberry Pi Zero
 2 W
In-Reply-To: <1641068812-5851-3-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
 <1641068812-5851-3-git-send-email-stefan.wahren@i2se.com>
Message-ID: <Ydyc4IwORMPNep4z@robh.at.kernel.org>

On Sat, 01 Jan 2022 21:26:50 +0100, Stefan Wahren wrote:
> Add the Raspberry Pi Zero 2 W to DT schema.
> 
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>  Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From acme at kernel.org  Mon Jan 10 13:03:04 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 18:03:04 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <YdybPJKjqx6zb28/@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org>
Message-ID: <YdyfCN1/JWJtJHTO@kernel.org>

Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Dec 29, 2021 at 11:19:48PM -0800, Ian Rogers escreveu:
> > Avoid error prone cpu_map + idx variant. Remove now unused functions.
> 
> At this point we need to remove the now unused perf_env__get_cpu(), and
> then deal with the fallout in the following patches that needlessly
> modify this unused function.
> 
> Doing that now.

Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
build containers, a better start now:

[perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
[perfbuilder at five ~]$ time dm
   1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
   2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
   3: alpine:3.5


- Arnaldo
 
> ?[acme at toolbox perf]$ git diff
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 6b985abaa2d22c58..40cb3518f27e2309 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -1477,22 +1477,6 @@ static void perf_stat__exit_aggr_mode(void)
>         stat_config.cpus_aggr_map = NULL;
>  }
> 
> -static inline int perf_env__get_cpu(void *data, struct perf_cpu_map *map, int idx)
> -{
> -       struct perf_env *env = data;
> -       int cpu;
> -
> -       if (idx > map->nr)
> -               return -1;
> -
> -       cpu = map->map[idx];
> -
> -       if (cpu >= env->nr_cpus_avail)
> -               return -1;
> -
> -       return cpu;
> -}
> -
>  static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
>  {
>         struct perf_env *env = data;
>  
> > Reviewed-by: James Clark <james.clark at arm.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/builtin-stat.c | 28 ++++------------------------
> >  tools/perf/util/cpumap.c  | 12 ++++++------
> >  tools/perf/util/cpumap.h  |  2 +-
> >  3 files changed, 11 insertions(+), 31 deletions(-)
> > 
> > diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> > index 9791ae9b1a53..6b985abaa2d2 100644
> > --- a/tools/perf/builtin-stat.c
> > +++ b/tools/perf/builtin-stat.c
> > @@ -1504,11 +1504,6 @@ static struct aggr_cpu_id perf_env__get_socket_aggr_by_cpu(int cpu, void *data)
> >  	return id;
> >  }
> >  
> > -static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx, void *data)
> > -{
> > -	return perf_env__get_socket_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> > -}
> > -
> >  static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
> >  {
> >  	struct perf_env *env = data;
> > @@ -1527,11 +1522,6 @@ static struct aggr_cpu_id perf_env__get_die_aggr_by_cpu(int cpu, void *data)
> >  	return id;
> >  }
> >  
> > -static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, void *data)
> > -{
> > -	return perf_env__get_die_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> > -}
> > -
> >  static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
> >  {
> >  	struct perf_env *env = data;
> > @@ -1551,11 +1541,6 @@ static struct aggr_cpu_id perf_env__get_core_aggr_by_cpu(int cpu, void *data)
> >  	return id;
> >  }
> >  
> > -static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx, void *data)
> > -{
> > -	return perf_env__get_core_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> > -}
> > -
> >  static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
> >  {
> >  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > @@ -1564,33 +1549,28 @@ static struct aggr_cpu_id perf_env__get_node_aggr_by_cpu(int cpu, void *data)
> >  	return id;
> >  }
> >  
> > -static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx, void *data)
> > -{
> > -	return perf_env__get_node_aggr_by_cpu(perf_env__get_cpu(data, map, idx), data);
> > -}
> > -
> >  static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
> >  				      struct cpu_aggr_map **sockp)
> >  {
> > -	return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
> > +	return cpu_map__build_map(cpus, sockp, perf_env__get_socket_aggr_by_cpu, env);
> >  }
> >  
> >  static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
> >  				   struct cpu_aggr_map **diep)
> >  {
> > -	return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
> > +	return cpu_map__build_map(cpus, diep, perf_env__get_die_aggr_by_cpu, env);
> >  }
> >  
> >  static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
> >  				    struct cpu_aggr_map **corep)
> >  {
> > -	return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
> > +	return cpu_map__build_map(cpus, corep, perf_env__get_core_aggr_by_cpu, env);
> >  }
> >  
> >  static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
> >  				    struct cpu_aggr_map **nodep)
> >  {
> > -	return cpu_map__build_map(cpus, nodep, perf_env__get_node, env);
> > +	return cpu_map__build_map(cpus, nodep, perf_env__get_node_aggr_by_cpu, env);
> >  }
> >  
> >  static struct aggr_cpu_id perf_stat__get_socket_file(struct perf_stat_config *config __maybe_unused,
> > diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> > index 49fba2c53822..feaf34b25efc 100644
> > --- a/tools/perf/util/cpumap.c
> > +++ b/tools/perf/util/cpumap.c
> > @@ -163,7 +163,7 @@ static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
> >  }
> >  
> >  int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> > -		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
> > +		       struct aggr_cpu_id (*f)(int cpu, void *data),
> >  		       void *data)
> >  {
> >  	int nr = cpus->nr;
> > @@ -178,7 +178,7 @@ int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> >  	c->nr = 0;
> >  
> >  	for (cpu = 0; cpu < nr; cpu++) {
> > -		s1 = f(cpus, cpu, data);
> > +		s1 = f(cpu, data);
> >  		for (s2 = 0; s2 < c->nr; s2++) {
> >  			if (cpu_map__compare_aggr_cpu_id(s1, c->map[s2]))
> >  				break;
> > @@ -290,22 +290,22 @@ struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *da
> >  
> >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
> >  {
> > -	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket, NULL);
> > +	return cpu_map__build_map(cpus, sockp, cpu_map__get_socket_aggr_by_cpu, NULL);
> >  }
> >  
> >  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep)
> >  {
> > -	return cpu_map__build_map(cpus, diep, cpu_map__get_die, NULL);
> > +	return cpu_map__build_map(cpus, diep, cpu_map__get_die_aggr_by_cpu, NULL);
> >  }
> >  
> >  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep)
> >  {
> > -	return cpu_map__build_map(cpus, corep, cpu_map__get_core, NULL);
> > +	return cpu_map__build_map(cpus, corep, cpu_map__get_core_aggr_by_cpu, NULL);
> >  }
> >  
> >  int cpu_map__build_node_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **numap)
> >  {
> > -	return cpu_map__build_map(cpus, numap, cpu_map__get_node, NULL);
> > +	return cpu_map__build_map(cpus, numap, cpu_map__get_node_aggr_by_cpu, NULL);
> >  }
> >  
> >  /* setup simple routines to easily access node numbers given a cpu number */
> > diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> > index c62d67704425..9648816c4255 100644
> > --- a/tools/perf/util/cpumap.h
> > +++ b/tools/perf/util/cpumap.h
> > @@ -63,7 +63,7 @@ int cpu__max_present_cpu(void);
> >  int cpu__get_node(int cpu);
> >  
> >  int cpu_map__build_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **res,
> > -		       struct aggr_cpu_id (*f)(struct perf_cpu_map *map, int cpu, void *data),
> > +		       struct aggr_cpu_id (*f)(int cpu, void *data),
> >  		       void *data);
> >  
> >  int cpu_map__cpu(struct perf_cpu_map *cpus, int idx);
> > -- 
> > 2.34.1.448.ga2b2bfdf31-goog
> 
> -- 
> 
> - Arnaldo

-- 

- Arnaldo


From fllinden at amazon.com  Mon Jan 10 13:08:06 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Mon, 10 Jan 2022 21:08:06 +0000
Subject: [PATCH 0/3] usable memory range fixes (arm64/fdt/efi)
Message-ID: <20220110210809.3528-1-fllinden@amazon.com>

b261dba2fdb2 ("arm64: kdump: Remove custom linux,usable-memory-range handling")
moved capping memory ranges using the FDT-specified linux,usable-memory-range
to the FDT code. This property is used to specify the memory range that
a crash kernel runs in.

While this correctly filters any memory ranges that come from the DT,
this breaks crash kernels on arm64 EFI systems. In these cases, DT is used
for the usable-memory-range property, but the actual memory ranges
come from EFI. Since the call to filter them was moved to the FDT
code, which runs before the EFI init code, the EFI ranges are not
filtered anymore, leading to the crash kernel using memory that
it shouldn't.

This set fixes the the issue by having the EFI code cap its
memory ranges too, and defining a common interface for both the
DT and EFI code to use.

These changes stick to the "firmware code should cap its own memory ranges"
idea, using a common memblock interface. An alternative would be to
use an FDT-specific interface as before, called from arm64_memblock_init,
but having things a little more generalized seemed like a good idea.

This is only a functional change on architectures that have both
DT and EFI, and a usable-memory-range property (which is just arm64).
On any other architecture, usable_size will not be set, leading to a
memblock_cap_memory_range call with 0 size, which is a no-op.

Frank van der Linden (3):
  memblock: define functions to set the usable memory range
  of: fdt: use memblock usable range interface
  efi: enforce usable memory range after reserving regions

 drivers/firmware/efi/efi-init.c |  7 +++++++
 drivers/of/fdt.c                |  3 ++-
 include/linux/memblock.h        |  2 ++
 mm/memblock.c                   | 37 +++++++++++++++++++++++++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)

-- 
2.32.0



From fllinden at amazon.com  Mon Jan 10 13:08:07 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Mon, 10 Jan 2022 21:08:07 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory range
In-Reply-To: <20220110210809.3528-1-fllinden@amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
Message-ID: <20220110210809.3528-2-fllinden@amazon.com>

Some architectures might limit the usable memory range based
on a firmware property, like "linux,usable-memory-range"
for ARM crash kernels. This limit needs to be enforced after
firmware memory map processing has been done, which might be
e.g. FDT or EFI, or both.

Define an interface for it that is firmware type agnostic.

Signed-off-by: Frank van der Linden <fllinden at amazon.com>
---
 include/linux/memblock.h |  2 ++
 mm/memblock.c            | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 34de69b3b8ba..6128efa50d33 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
 phys_addr_t memblock_start_of_DRAM(void);
 phys_addr_t memblock_end_of_DRAM(void);
 void memblock_enforce_memory_limit(phys_addr_t memory_limit);
+void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
+void memblock_enforce_usable_range(void);
 void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
 void memblock_mem_limit_remove_map(phys_addr_t limit);
 bool memblock_is_memory(phys_addr_t addr);
diff --git a/mm/memblock.c b/mm/memblock.c
index 5096500b2647..cb961965f3ad 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -101,6 +101,7 @@ unsigned long max_low_pfn;
 unsigned long min_low_pfn;
 unsigned long max_pfn;
 unsigned long long max_possible_pfn;
+phys_addr_t usable_start, usable_size;
 
 static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
 static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock;
@@ -1715,6 +1716,42 @@ void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
 			base + size, PHYS_ADDR_MAX);
 }
 
+/**
+ * memblock_set_usable_range - set usable memory range
+ * @base: physical address that is the start of the range
+ * @size: size of the range.
+ *
+ * Used when a firmware property limits the range of usable
+ * memory, like for the linux,usable-memory-range property
+ * used by ARM crash kernels.
+ */
+void __init memblock_set_usable_range(phys_addr_t base, phys_addr_t size)
+{
+	usable_start = base;
+	usable_size = size;
+}
+
+/**
+ * memblock_enforce_usable_range - cap memory ranges to usable range
+ *
+ * Some architectures call this during boot after firmware memory ranges
+ * have been scanned, to make sure they fall within the usable range
+ * set by memblock_set_usable_range.
+ *
+ * This may be called more than once if there are multiple firmware sources
+ * for memory ranges.
+ *
+ * Avoid "no memory registered" warning - the warning itself is
+ * useful, but we know this can be called with no registered
+ * memory (e.g. when the synthetic DT for the crash kernel has
+ * been parsed on EFI arm64 systems).
+ */
+void __init memblock_enforce_usable_range(void)
+{
+	if (memblock_memory->total_size)
+		memblock_cap_memory_range(usable_start, usable_size);
+}
+
 void __init memblock_mem_limit_remove_map(phys_addr_t limit)
 {
 	phys_addr_t max_addr;
-- 
2.32.0



From fllinden at amazon.com  Mon Jan 10 13:08:09 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Mon, 10 Jan 2022 21:08:09 +0000
Subject: [PATCH 3/3] efi: enforce usable memory range after reserving regions
In-Reply-To: <20220110210809.3528-1-fllinden@amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
Message-ID: <20220110210809.3528-4-fllinden@amazon.com>

The usable memory range may be restricted through parameters that
did not come from EFI, like the FDT "linux,usable-memory-range"
property.

Enforce this range after the EFI memory map regions have been
processed.

Signed-off-by: Frank van der Linden <fllinden at amazon.com>
---
 drivers/firmware/efi/efi-init.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index b19ce1a83f91..280e9178c7df 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -204,6 +204,13 @@ static __init void reserve_regions(void)
 				memblock_reserve(paddr, size);
 		}
 	}
+
+	/*
+	 * Done, filter !nomap memory we just added so that the
+	 * usable range is enforced. This is normally only set
+	 * for crash kernels on some architectures.
+	 */
+	memblock_enforce_usable_range();
 }
 
 void __init efi_init(void)
-- 
2.32.0



From fllinden at amazon.com  Mon Jan 10 13:08:08 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Mon, 10 Jan 2022 21:08:08 +0000
Subject: [PATCH 2/3] of: fdt: use memblock usable range interface
In-Reply-To: <20220110210809.3528-1-fllinden@amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
Message-ID: <20220110210809.3528-3-fllinden@amazon.com>

Use the memblock usable range interface to set and enforce the
usable memory range (if any).

Signed-off-by: Frank van der Linden <fllinden at amazon.com>
---
 drivers/of/fdt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 4546572af24b..b3c2a4124518 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1279,7 +1279,8 @@ void __init early_init_dt_scan_nodes(void)
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 
 	/* Handle linux,usable-memory-range property */
-	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
+	memblock_set_usable_range(cap_mem_addr, cap_mem_size);
+	memblock_enforce_usable_range();
 }
 
 bool __init early_init_dt_scan(void *params)
-- 
2.32.0



From lkp at intel.com  Mon Jan 10 13:13:59 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 05:13:59 +0800
Subject: [v1 04/16] clk: mediatek: Add MT8186 topckgen clock support
In-Reply-To: <20220110134416.5191-5-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-5-chun-jie.chen@mediatek.com>
Message-ID: <202201110556.oB2sYNXm-lkp@intel.com>

Hi Chun-Jie,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next v5.16 next-20220110]
[cannot apply to mbgg-mediatek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: nios2-allyesconfig (https://download.01.org/0day-ci/archive/20220111/202201110556.oB2sYNXm-lkp at intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/265a72ef3e3b41a62f280049219cf4efe1d79171
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
        git checkout 265a72ef3e3b41a62f280049219cf4efe1d79171
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/mediatek/clk-mt8186-topckgen.c: In function 'clk_mt8186_topck_probe':
>> drivers/clk/mediatek/clk-mt8186-topckgen.c:725:9: error: implicit declaration of function 'mtk_clk_unregister'; did you mean 'devm_clk_unregister'? [-Werror=implicit-function-declaration]
     725 |         mtk_clk_unregister(clk_data);
         |         ^~~~~~~~~~~~~~~~~~
         |         devm_clk_unregister
   cc1: some warnings being treated as errors


vim +725 drivers/clk/mediatek/clk-mt8186-topckgen.c

   691	
   692	static int clk_mt8186_topck_probe(struct platform_device *pdev)
   693	{
   694		struct clk_onecell_data *clk_data;
   695		struct device_node *node = pdev->dev.of_node;
   696		int r;
   697		void __iomem *base;
   698	
   699		base = devm_platform_ioremap_resource(pdev, 0);
   700		if (IS_ERR(base))
   701			return PTR_ERR(base);
   702	
   703		clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
   704		if (!clk_data)
   705			return -ENOMEM;
   706	
   707		mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
   708					    clk_data);
   709		mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
   710		mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
   711				       &mt8186_clk_lock, clk_data);
   712	
   713		mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
   714					    &mt8186_clk_lock, clk_data);
   715		mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
   716					    &mt8186_clk_lock, clk_data);
   717	
   718		r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
   719		if (r)
   720			goto unregister_clk;
   721	
   722		return r;
   723	
   724	unregister_clk:
 > 725		mtk_clk_unregister(clk_data);
   726		mtk_free_clk_data(clk_data);
   727		return r;
   728	}
   729	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From acme at kernel.org  Mon Jan 10 13:23:09 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 18:23:09 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <YdyfCN1/JWJtJHTO@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
Message-ID: <Ydyjvcma/wMTPwbn@kernel.org>

Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Dec 29, 2021 at 11:19:48PM -0800, Ian Rogers escreveu:
> > > Avoid error prone cpu_map + idx variant. Remove now unused functions.
> > 
> > At this point we need to remove the now unused perf_env__get_cpu(), and
> > then deal with the fallout in the following patches that needlessly
> > modify this unused function.
> > 
> > Doing that now.
> 
> Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> build containers, a better start now:
> 
> [perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
> [perfbuilder at five ~]$ time dm
>    1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
>    2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
>    3: alpine:3.5
> 

So far so good:

[perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
[perfbuilder at five ~]$ time dm
   1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
   2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
   3    54.98 alpine:3.5                    : Ok   gcc (Alpine 6.2.1) 6.2.1 20160822 , clang version 3.8.1 (tags/RELEASE_381/final)
   4    57.69 alpine:3.6                    : Ok   gcc (Alpine 6.3.0) 6.3.0 , clang version 4.0.0 (tags/RELEASE_400/final)
   5    63.62 alpine:3.7                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0)
   6    64.52 alpine:3.8                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
   7    66.54 alpine:3.9                    : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1)
   8    91.91 alpine:3.10                   : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0)
   9   104.93 alpine:3.11                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0)
  10   107.97 alpine:3.12                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c)
  11   115.98 alpine:3.13                   : Ok   gcc (Alpine 10.2.1_pre1) 10.2.1 20201203 , Alpine clang version 10.0.1
  12   101.73 alpine:3.14                   : Ok   gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424 , Alpine clang version 11.1.0
  13   103.35 alpine:3.15                   : Ok   gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027 , Alpine clang version 12.0.1
  14   104.43 alpine:edge                   : Ok   gcc (Alpine 11.2.1_git20211128) 11.2.1 20211128 , Alpine clang version 12.0.1
  15    51.06 alt:p8                        : Ok   x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1) , clang version 3.8.0 (tags/RELEASE_380/final)

Building with:

build_perf_gcc() {
	set -o xtrace
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" -C tools/perf O=/tmp/build/perf || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" NO_LIBELF=1 -C tools/perf O=/tmp/build/perf || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" NO_LIBBPF=1 -C tools/perf O=/tmp/build/perf || exit 1
	if [ -d /usr/include/traceevent/ ] ; then
		make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" LIBTRACEEVENT_DYNAMIC=1 -C tools/perf O=/tmp/build/perf || exit 1
	fi
	set +o xtrace
}

build_perf_clang() {
	set -o xtrace

	if [ ! $NO_BUILD_BPF_SKEL ] ; then
		rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
		make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" BUILD_BPF_SKEL=1 -C tools/perf O=/tmp/build/perf || exit 1
	fi

	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" -C tools/perf O=/tmp/build/perf CC=clang || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" NO_LIBELF=1 -C tools/perf O=/tmp/build/perf CC=clang || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" NO_LIBBPF=1 -C tools/perf O=/tmp/build/perf CC=clang || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" LIBCLANGLLVM=1 -C tools/perf O=/tmp/build/perf CC=clang || exit 1
	rm -rf /tmp/build/perf ; mkdir /tmp/build/perf
	make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" LIBCLANGLLVM=1 -C tools/perf O=/tmp/build/perf || exit 1
	if [ -d /usr/include/traceevent/ ] ; then
		make $EXTRA_MAKE_ARGS ARCH=$ARCH CROSS_COMPILE=$CROSS_COMPILE EXTRA_CFLAGS="$EXTRA_CFLAGS" LIBTRACEEVENT_DYNAMIC=1 -C tools/perf O=/tmp/build/perf || exit 1
	fi
	set +o xtrace
}


From acme at kernel.org  Mon Jan 10 13:34:46 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 18:34:46 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <Ydyjvcma/wMTPwbn@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
 <Ydyjvcma/wMTPwbn@kernel.org>
Message-ID: <Ydymdm/PoB0hQVUT@kernel.org>

Em Mon, Jan 10, 2022 at 06:23:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > At this point we need to remove the now unused perf_env__get_cpu(), and
> > > then deal with the fallout in the following patches that needlessly
> > > modify this unused function.
> > > 
> > > Doing that now.
> > 
> > Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> > build containers, a better start now:

> So far so good:

perf test ok, just that one that is failing, but before this series as
well:

 89: perf all metricgroups test                                      : FAILED!

[acme at quaco perf]$ uname -a
Linux quaco 5.15.7-200.fc35.x86_64 #1 SMP Wed Dec 8 19:00:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[acme at quaco perf]$ git log --oneline -1
16ed0580fb4d64bd (HEAD -> perf/core, seventh/perf/core, five/perf/core, acme.korg/tmp.perf/perf_cpu) perf cpumap: Give CPUs their own type
[acme at quaco perf]$ perf -v
perf version 5.16.g16ed0580fb4d
[acme at quaco perf]$ sudo su -
[sudo] password for acme:
[root at quaco ~]# perf -vv
perf version 5.16.g16ed0580fb4d
                 dwarf: [ on  ]  # HAVE_DWARF_SUPPORT
    dwarf_getlocations: [ on  ]  # HAVE_DWARF_GETLOCATIONS_SUPPORT
                 glibc: [ on  ]  # HAVE_GLIBC_SUPPORT
         syscall_table: [ on  ]  # HAVE_SYSCALL_TABLE_SUPPORT
                libbfd: [ on  ]  # HAVE_LIBBFD_SUPPORT
                libelf: [ on  ]  # HAVE_LIBELF_SUPPORT
               libnuma: [ on  ]  # HAVE_LIBNUMA_SUPPORT
numa_num_possible_cpus: [ on  ]  # HAVE_LIBNUMA_SUPPORT
               libperl: [ on  ]  # HAVE_LIBPERL_SUPPORT
             libpython: [ on  ]  # HAVE_LIBPYTHON_SUPPORT
              libslang: [ on  ]  # HAVE_SLANG_SUPPORT
             libcrypto: [ on  ]  # HAVE_LIBCRYPTO_SUPPORT
             libunwind: [ on  ]  # HAVE_LIBUNWIND_SUPPORT
    libdw-dwarf-unwind: [ on  ]  # HAVE_DWARF_SUPPORT
                  zlib: [ on  ]  # HAVE_ZLIB_SUPPORT
                  lzma: [ on  ]  # HAVE_LZMA_SUPPORT
             get_cpuid: [ on  ]  # HAVE_AUXTRACE_SUPPORT
                   bpf: [ on  ]  # HAVE_LIBBPF_SUPPORT
                   aio: [ on  ]  # HAVE_AIO_SUPPORT
                  zstd: [ on  ]  # HAVE_ZSTD_SUPPORT
               libpfm4: [ OFF ]  # HAVE_LIBPFM
[root at quaco ~]# perf test
  1: vmlinux symtab matches kallsyms                                 : Ok
  2: Detect openat syscall event                                     : Ok
  3: Detect openat syscall event on all cpus                         : Ok
  4: Read samples using the mmap interface                           : Ok
  5: Test data source output                                         : Ok
  6: Parse event definition strings                                  : Ok
  7: Simple expression parser                                        : Ok
  8: PERF_RECORD_* events & perf_sample fields                       : Ok
  9: Parse perf pmu format                                           : Ok
 10: PMU events                                                      :
 10.1: PMU event table sanity                                        : Ok
 10.2: PMU event map aliases                                         : Ok
 10.3: Parsing of PMU event table metrics                            : Ok
 10.4: Parsing of PMU event table metrics with fake PMUs             : Ok
 11: DSO data read                                                   : Ok
 12: DSO data cache                                                  : Ok
 13: DSO data reopen                                                 : Ok
 14: Roundtrip evsel->name                                           : Ok
 15: Parse sched tracepoints fields                                  : Ok
 16: syscalls:sys_enter_openat event fields                          : Ok
 17: Setup struct perf_event_attr                                    : Ok
 18: Match and link multiple hists                                   : Ok
 19: 'import perf' in python                                         : Ok
 20: Breakpoint overflow signal handler                              : Ok
 21: Breakpoint overflow sampling                                    : Ok
 22: Breakpoint accounting                                           : Ok
 23: Watchpoint                                                      :
 23.1: Read Only Watchpoint                                          : Skip (missing hardware support)
 23.2: Write Only Watchpoint                                         : Ok
 23.3: Read / Write Watchpoint                                       : Ok
 23.4: Modify Watchpoint                                             : Ok
 24: Number of exit events of a simple workload                      : Ok
 25: Software clock events period values                             : Ok
 26: Object code reading                                             : Ok
 27: Sample parsing                                                  : Ok
 28: Use a dummy software event to keep tracking                     : Ok
 29: Parse with no sample_id_all bit set                             : Ok
 30: Filter hist entries                                             : Ok
 31: Lookup mmap thread                                              : Ok
 32: Share thread maps                                               : Ok
 33: Sort output of hist entries                                     : Ok
 34: Cumulate child hist entries                                     : Ok
 35: Track with sched_switch                                         : Ok
 36: Filter fds with revents mask in a fdarray                       : Ok
 37: Add fd to a fdarray, making it autogrow                         : Ok
 38: kmod_path__parse                                                : Ok
 39: Thread map                                                      : Ok
 40: LLVM search and compile                                         :
 40.1: Basic BPF llvm compile                                        : Ok
 40.2: kbuild searching                                              : Ok
 40.3: Compile source for BPF prologue generation                    : Ok
 40.4: Compile source for BPF relocation                             : Ok
 41: Session topology                                                : Ok
 42: BPF filter                                                      :
 42.1: Basic BPF filtering                                           : Ok
 42.2: BPF pinning                                                   : Ok
 42.3: BPF prologue generation                                       : Ok
 43: Synthesize thread map                                           : Ok
 44: Remove thread map                                               : Ok
 45: Synthesize cpu map                                              : Ok
 46: Synthesize stat config                                          : Ok
 47: Synthesize stat                                                 : Ok
 48: Synthesize stat round                                           : Ok
 49: Synthesize attr update                                          : Ok
 50: Event times                                                     : Ok
 51: Read backward ring buffer                                       : Ok
 52: Print cpu map                                                   : Ok
 53: Merge cpu map                                                   : Ok
 54: Probe SDT events                                                : Ok
 55: is_printable_array                                              : Ok
 56: Print bitmap                                                    : Ok
 57: perf hooks                                                      : Ok
 58: builtin clang support                                           :
 58.1: builtin clang compile C source to IR                          : Skip (not compiled in)
 58.2: builtin clang compile C source to ELF object                  : Skip (not compiled in)
 59: unit_number__scnprintf                                          : Ok
 60: mem2node                                                        : Ok
 61: time utils                                                      : Ok
 62: Test jit_write_elf                                              : Ok
 63: Test libpfm4 support                                            :
 63.1: test of individual --pfm-events                               : Skip (not compiled in)
 63.2: test groups of --pfm-events                                   : Skip (not compiled in)
 64: Test api io                                                     : Ok
 65: maps__merge_in                                                  : Ok
 66: Demangle Java                                                   : Ok
 67: Demangle OCaml                                                  : Ok
 68: Parse and process metrics                                       : Ok
 69: PE file support                                                 : Ok
 70: Event expansion for cgroups                                     : Ok
 71: Convert perf time to TSC                                        : Ok
 72: dlfilter C API                                                  : Ok
 73: Sigtrap                                                         : Ok
 74: x86 rdpmc                                                       : Ok
 75: Test dwarf unwind                                               : Ok
 76: x86 instruction decoder - new instructions                      : Ok
 77: Intel PT packet decoder                                         : Ok
 78: x86 bp modify                                                   : Ok
 79: x86 Sample parsing                                              : Ok
 80: build id cache operations                                       : Ok
 81: daemon operations                                               : Ok
 82: perf pipe recording and injection test                          : Ok
 83: Add vfs_getname probe to get syscall args filenames             : Ok
 84: probe libc's inet_pton & backtrace it with ping                 : Ok
 85: Use vfs_getname probe to get syscall args filenames             : Ok
 86: Zstd perf.data compression/decompression                        : Ok
 87: perf stat csv summary test                                      : Ok
 88: perf stat metrics (shadow stat) test                            : Ok
 89: perf all metricgroups test                                      : FAILED!
 90: perf all metrics test                                           : Ok
 91: perf all PMU test                                               : Ok
 92: perf stat --bpf-counters test                                   : Ok
 93: Check Arm CoreSight trace data recording and synthesized samples: Skip
 94: Check Arm SPE trace data recording and synthesized samples      : Skip
 95: Check open filename arg using perf trace + vfs_getname          : Ok
[root at quaco ~]#

And the containers are ok so far:

[perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
[perfbuilder at five ~]$ time dm
   1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
   2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
   3    54.98 alpine:3.5                    : Ok   gcc (Alpine 6.2.1) 6.2.1 20160822 , clang version 3.8.1 (tags/RELEASE_381/final)
   4    57.69 alpine:3.6                    : Ok   gcc (Alpine 6.3.0) 6.3.0 , clang version 4.0.0 (tags/RELEASE_400/final)
   5    63.62 alpine:3.7                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0)
   6    64.52 alpine:3.8                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
   7    66.54 alpine:3.9                    : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1)
   8    91.91 alpine:3.10                   : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0)
   9   104.93 alpine:3.11                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0)
  10   107.97 alpine:3.12                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c)
  11   115.98 alpine:3.13                   : Ok   gcc (Alpine 10.2.1_pre1) 10.2.1 20201203 , Alpine clang version 10.0.1
  12   101.73 alpine:3.14                   : Ok   gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424 , Alpine clang version 11.1.0
  13   103.35 alpine:3.15                   : Ok   gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027 , Alpine clang version 12.0.1
  14   104.43 alpine:edge                   : Ok   gcc (Alpine 11.2.1_git20211128) 11.2.1 20211128 , Alpine clang version 12.0.1
  15    51.06 alt:p8                        : Ok   x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1) , clang version 3.8.0 (tags/RELEASE_380/final)
  16    75.95 alt:p9                        : Ok   x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1) , clang version 10.0.0
  17    75.26 alt:p10                       : Ok   x86_64-alt-linux-gcc (GCC) 10.3.1 20210703 (ALT Sisyphus 10.3.1-alt2) , clang version 11.0.1
  18    74.85 alt:sisyphus                  : Ok   x86_64-alt-linux-gcc (GCC) 11.2.1 20210911 (ALT Sisyphus 11.2.1-alt1) , ALT Linux Team clang version 12.0.1
  19    52.87 amazonlinux:1                 : Ok   gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) , clang version 3.6.2 (tags/RELEASE_362/final)
  20    85.98 amazonlinux:2                 : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13) , clang version 11.1.0 (Amazon Linux 2 11.1.0-1.amzn2.0.2)
  21    79.77 archlinux:base                : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
  22    83.56 centos:8                      : Ok   gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1) , clang version 11.0.1 (Red Hat 11.0.1-1.module_el8.4.0+966+2995ef20)
  23    98.02 centos:stream                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-3) , clang version 12.0.1 (Red Hat 12.0.1-2.module_el8.6.0+937+1cafe22c)
  24    27.67 clearlinux:latest             : Ok   gcc (Clear Linux OS for Intel Architecture) 11.2.1 20211228 releases/gcc-11.2.0-618-g3b2b18144c , clang version 11.1.0
  25    65.92 debian:9                      : Ok   gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 , clang version 3.8.1-24 (tags/RELEASE_381/final)
  26    62.20 debian:10                     : Ok   gcc (Debian 8.3.0-6) 8.3.0 , clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)
  27: debian:11



From pcc at google.com  Mon Jan 10 13:43:45 2022
From: pcc at google.com (Peter Collingbourne)
Date: Mon, 10 Jan 2022 13:43:45 -0800
Subject: [PATCH v4 4/7] uaccess-buffer: add CONFIG_GENERIC_ENTRY support
In-Reply-To: <875yrncbud.ffs@tglx>
References: <20211209221545.2333249-1-pcc@google.com>
 <20211209221545.2333249-5-pcc@google.com> <87a6h7webt.ffs@tglx>
 <CAMn1gO4Qcp+t+UhUg4X6KCGbx7_Sm+w8t1_zugPMweuKSZrv7w@mail.gmail.com>
 <87a6h0lmxm.ffs@tglx>
 <CAMn1gO7iaaXEgAt3kQVRSN3ueY7MPt0yww40ADAmUZLOb0ZwZg@mail.gmail.com>
 <875yrncbud.ffs@tglx>
Message-ID: <CAMn1gO7QmQZq-kXeqkCREMJnRsWzYLZphbG_B59aOhb-+O2wZQ@mail.gmail.com>

On Fri, Dec 17, 2021 at 10:42 AM Thomas Gleixner <tglx at linutronix.de> wrote:
>
> Peter,
>
> On Thu, Dec 16 2021 at 16:09, Peter Collingbourne wrote:
> > userspace program sets addr to 0. Furthermore, a userspace program
> > setting addr to 0 would not automatically cause the pending signals to
> > be delivered (because simply storing a value to memory from userspace
> > will not necessarily trigger a kernel entry), and signals could
> > therefore be left blocked for longer than expected (at least until the
> > next kernel entry).
>
> Groan, so what you are trying to prevent is:
>
>    *ptr = addr;
>
> --> interrupt
>        signal raised
>
>     signal delivery
>
>     signal handler
>       syscall()   <- Logs this syscall
>       sigreturn;
>
>    syscall() <- Is not logged
>
> I must have missed that detail in these novel sized comments all over
> the place.
>
> Yes, I can see how that pre/post muck solves this, but TBH while it is
> admittedly a smart hack it's also a horrible hack.
>
> There are a two aspects which I really dislike:
>
>   - It's yet another ad hoc 'solution' to scratch 'my particular itch'
>
>   - It's adding a horrorshow in the syscall hotpath. We have already
>     enough gunk there. No need to add more.
>
> The problem you are trying to solve is to instrument user accesses of
> the kernel, which is special purpose tracing, right?
>
> May I ask why this is not solvable via tracepoints?
>
>   DECLARE_EVENT_CLASS(uaccess_class,....);
>   DECLARE_EVENT(uaccess_class, uaccess_read,...);
>   DECLARE_EVENT(uaccess_class, uaccess_write,...);
>
>     trace_uaccess_read(from, n);
>
>     trace_uaccess_write(to, n);
>
> Tracepoints have filters, tooling, libraries etc. Zero code except for
> the tracepoints themself. They are disabled by default with a static
> key, which means very close to 0 overhead.
>
> Aside of that such tracepoints can be used for other purposes as well
> and are therefore not bound to 'my particular itch'.
>
> There are obviously some questions to solve versus filtering, but even
> with a stupid tid based filter, it's easy enough to filter out the stuff
> you're interested in. E.g. to filter out the signal scenario above all
> you need is to enable two more tracepoints:
>
>    signal:signal_deliver
>    syscalls:sys_enter_rt_sigreturn
>
> and when analyzing the event stream you can just skip the noise between
> signal:signal_deliver and syscalls:sys_enter_rt_sigreturn trace entries.

I'm afraid that it won't always work. This is because the control flow
can leave a signal handler without going through sigreturn (e.g. when
throwing an exception through the signal handler in C++, or via
longjmp).

But aside from that, there seem to be more fundamental problems with
using tracepoints for this. Let me start by saying that the uaccess
monitoring needs to be synchronous. This is because we need to read
the sanitizer metadata (e.g. memory tags for HWASan) for the memory
accessed by the syscall at the time that the syscall takes place,
before the syscall wrapper function returns. If we read it later, the
memory accessed by the syscall may have been deallocated or
reallocated, so we may end up producing a false positive
use-after-free (if deallocated) or buffer-overflow (if reallocated)
report.

As far as I can tell, there are four main ways that a userspace
program can access tracepoint events:

1) /sys/kernel/debug/tracing/trace_pipe
2) perf_event_open()
3) BPF
4) SIGTRAP on perf events

Let me go over each of them in turn. I don't think any of them will
work, but let me know if you think I made a mistake.

1) The event monitoring via trace_pipe appears to be a mechanism that
is global to the system, so it isn't suitable for an environment where
multiple processes may have sanitizers enabled.

2) This seems to be closest to being feasible, but it looks like there
are a few issues. From reading the perf_event_open man page, the way I
imagined it could work is that we sample the events uaccess_read,
uaccess_write, signal_deliver and sys_enter_rt_sigreturn to a ring
buffer. Then in the syscall wrapper we read the buffer and filter out
the events as you proposed. We do, however, need to be careful to
avoid memory corruption with this approach -- suppose that a signal
comes in while the syscall wrapper is part way through reading the
ring buffer. The syscalls performed by the signal handler may cause
the kernel to overwrite the part of the ring buffer that the syscall
wrapper is currently reading. I think something like this may work to
avoid the overwriting:

// thread local variables:
perf_event_mmap_page *page; // initialized at thread startup
bool in_syscall = false;

long syscall(...) {
  if (in_syscall) {
    // just do the syscall without logging to avoid reentrancy issues
    raw_syscall(...);
  }
  in_syscall = true;
  old_data_head = page->data_head;
  page->data_tail = old_data_head;
  raw_syscall(...);
  new_data_head = page->data_head;
  // read events between old_data_head and new_data_head
  in_syscall = false;
}

With this scheme we end up dropping events from signal handlers in
rare cases. This may be acceptable because the whole scheme is
best-effort anyway. However, if we abnormally return from the syscall
wrapper (exception or longjmp from signal handler), we will be stuck
in the state where logging is disabled, which seems more problematic.

For this to work we will need access to the arguments to the
uaccess_read and uaccess_write events. I couldn't find anything
suitable in the man page, but it does offer this tantalizing snippet:

              PERF_SAMPLE_RAW
                     Records additional data, if applicable.  Usually
returned by tracepoint events.

Maybe the arguments can be accessed via this record? Reading through
the kernel code it looks like *something* is copied in response to
this flag being set, but it is not very clear what. A comment in the
include/uapi/linux/perf_event.h header seems to indicate, however,
that even if the arguments are accessible this way, that isn't part of
the ABI:

         *      #
         *      # The RAW record below is opaque data wrt the ABI
         *      #
         *      # That is, the ABI doesn't make any promises wrt to
         *      # the stability of its content, it may vary depending
         *      # on event, hardware, kernel version and phase of
         *      # the moon.
         *      #
         *      # In other words, PERF_SAMPLE_RAW contents are not an ABI.
         *      #
         *
         *      { u32                   size;
         *        char                  data[size];}&& PERF_SAMPLE_RAW

This would make PERF_SAMPLE_RAW unsuitable for use in sanitizers
because they are generally expected not to break with new kernel
versions.

Another issue is that we need to be able to read the id file from
tracefs in order to issue the perf_event_open() syscall, but there
isn't necessarily a guarantee that tracefs will always be available
given that we will want to use this from almost every process on the
system including init and sandboxed processes. It also looks like the
whole "events" tree of tracefs is restricted to root on at least some
Android devices. There may be other privileges issues that I haven't
run into yet.

3) Installing BPF programs requires additional privileges. As
explained below, this makes it unsuitable for use with sanitizers.

4) I explained why I don't think it will work in the cover letter of
my most recent patch series:

- Tracing would need to be synchronous in order to produce useful
  stack traces. For example this could be achieved using the new SIGTRAP
  on perf events mechanism. However, this would require logging each
  access to the stack (in the form of a sigcontext) and this is more
  likely to overflow the stack due to being much larger than a uaccess
  buffer entry as well as being unbounded, in contrast to the bounded
  buffer size passed to prctl(). An approach based on signal handlers is
  also likely to fall foul of the asynchronous signal issues mentioned
  previously, together with needing sigreturn to be handled specially
  (because it copies a sigcontext from userspace) otherwise we could
  never return from the signal handler. Furthermore, arguments to the
  trace events are not available to SIGTRAP. (This on its own wouldn't
  be insurmountable though -- we could add the arguments as fields
  to siginfo.)

> There are other fancies like BPF which can be used for filtering and
> filling a map with entries.
>
> The only downside is that system configuration restricts access and
> requires certain priviledges. But is that a real problem for the purpose
> at hand, sanitizers and validation tools?
>
> I don't think it is, but you surely can provide more information here.

I'm afraid that it is a problem. We frequently deploy sanitizers in
production-like environments, which means that processes may not only
be running as non-root but may also be sandboxed. For example, a
typical HWASan deployment on an Android device will have HWASan
enabled in almost every process, including untrusted application
processes and sandboxed processes used for parsing untrusted data (and
which are particularly security sensitive).

Furthermore, we plan to use uaccess logging with the ARM Memory
Tagging Extension, which is intended to be deployed to end-user
devices. While opening holes in the sandbox for HWASan may be possible
in some cases (though inadvisable because sanitizers are meant to be
transparent to the program as much as possible, and we don't control
every sandbox used by every Android app), we shouldn't open holes in
the sandbox on end-user devices even if we were able to get every app
with a sandbox to do so as this would increase the risk to end users
(whereas the entire goal of deploying this is to *reduce* the risk).

Peter


From robh at kernel.org  Mon Jan 10 13:54:20 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 15:54:20 -0600
Subject: [PATCH 3/8] dt-bindings: clock: samsung: convert Exynos5433 to
 dtschema
In-Reply-To: <20220102115356.75796-3-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-3-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyrDKivO+Jj/Ae/@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:51 +0100, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5433 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5433-clock.txt       | 507 -----------------
>  .../clock/samsung,exynos5433-clock.yaml       | 524 ++++++++++++++++++
>  2 files changed, 524 insertions(+), 507 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5433-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
> 

Applied, thanks!


From robh at kernel.org  Mon Jan 10 13:54:29 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 15:54:29 -0600
Subject: [PATCH 4/8] dt-bindings: clock: samsung: convert Exynos7 to
 dtschema
In-Reply-To: <20220102115356.75796-4-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyrFYwgViOaEX5h@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:52 +0100, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos7 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos7-clock.txt          | 108 -------
>  .../bindings/clock/samsung,exynos7-clock.yaml | 269 ++++++++++++++++++
>  2 files changed, 269 insertions(+), 108 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos7-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
> 

Applied, thanks!


From robh at kernel.org  Mon Jan 10 13:54:39 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 15:54:39 -0600
Subject: [PATCH 5/8] dt-bindings: clock: samsung: extend Exynos7 bindings
 with UFS
In-Reply-To: <20220102115356.75796-5-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-5-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyrH3WspngOp6ag@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:53 +0100, Krzysztof Kozlowski wrote:
> The UFS for Exynos7 SoC clock controller requires additional input
> clocks for the FSYS1 clock controller.  Update the bindings to reflect
> this, at least in theory.  In practice, these input clocks are ignored,
> so it is rather adjusting of bindings to existing DTS, without affecting
> any real users.  I understand that is not how it should be done,
> though...
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/clock/samsung,exynos7-clock.yaml   | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Mon Jan 10 13:55:02 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 15:55:02 -0600
Subject: [PATCH 6/8] dt-bindings: clock: samsung: convert Exynos5260 to
 dtschema
In-Reply-To: <20220102115356.75796-6-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-6-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyrNv79Eepm31ty@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:54 +0100, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5260 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5260-clock.txt       | 190 ---------
>  .../clock/samsung,exynos5260-clock.yaml       | 382 ++++++++++++++++++
>  2 files changed, 382 insertions(+), 190 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5260-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
> 

Applied, thanks!


From yuzhao at google.com  Mon Jan 10 14:04:54 2022
From: yuzhao at google.com (Yu Zhao)
Date: Mon, 10 Jan 2022 15:04:54 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdxTR4+FL08XyFuO@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>
 <YdiKVJlClB3h1Kmg@google.com> <YdxTR4+FL08XyFuO@dhcp22.suse.cz>
Message-ID: <YdythmxHpSksJiXs@google.com>

On Mon, Jan 10, 2022 at 04:39:51PM +0100, Michal Hocko wrote:
> On Fri 07-01-22 11:45:40, Yu Zhao wrote:
> [...]
> > Next, I argue that the benefits of this patchset outweigh its risks,
> > because, drawing from my past experience,
> > 1. There have been many larger and/or riskier patchsets taken; I'll
> >    assemble a list if you disagree.
> 
> No question about that. Changes in the reclaim path are paved with
> failures and reverts and fine tuning on top of existing fine tuning.
> The difference from your patchset is that they tend to be much much
> smaller and go incremental and therefore easier to review.

No argument here.

> >    And this patchset is fully guarded
> >    by #ifdef; Linus has also assessed on this point.
> 
> I appreciate you made the new behavior an opt-in and therefore existing
> workloads are less likely to regress. I do not think ifdefs help
> all that much, though, because a) realistically the config will
> likely be enabled for most distribution kernels

There is also a runtime kill switch.

> b) the parallel
> reclaim implementation adds a maintenance overhead regardless of those
> ifdef. The later point is especially worrying because the memory reclaim
> is a complex and hard to review beast already. Any future changes would
> need to consider both reclaim algorithms of course.

A perfectly legitimate concern.

If this patchset is taken:
1. There will be refactoring that makes the long-term maintenance as
   affordable as possible, i.e., similar to the SL.B model, but can
   also make runtime switch.
2. There will also be optimizations for mmu notifier (KVM), THP, etc.
3. Most importantly, Google will be committing more resource on this.
   And that's why we need to hear a decision -- our resource planning
   depends on it.

> Hence I argue we really need a wider consensus this is the right
> direction we want to pursue.

We've been doing our best to get this consensus -- we invited all
the stakeholders to meetings a long time ago -- but unfortunately we
couldn't move the needle.

I agree consensus is important. But, IMO, progress is even more
important. And personally, I'd rather try something wrong than do
nothing.

> > 2. There have been none that came with the testing/benchmarking
> >    coverage as this one did. Please point me to some if I'm mistaken,
> >    and I'll gladly match them.
> 
> I do appreciate your numbers but you should realize that this is an area
> that is really hard to get any conclusive testing for.

Fully agreed. That's why we started a new initiative, and we hope more
people will following these practices:
1. All results in this area should be reported with at least standard
   deviations, or preferably confidence intervals.
2. Real applications should be benchmarked (with synthetic load
   generator), not just synthetic benchmarks (not real applications).
3. A wide range of devices should be covered, i.e., servers, desktops,
   laptops and phones.

I'm very confident to say our benchmark reports were hold to the
highest standards. We have worked with MariaDB (company), EnterpriseDB
(Postgres), Redis (company), etc. on these reports. They have copies
of these reports (PDF version):
https://linux-mm.googlesource.com/benchmarks/

We welcome any expert in those applications to examine our reports,
and we'll be happy to run any other benchmarks or same benchmarks with
different configurations that anybody thinks it's important and we've
missed.

> We keep learning
> about fallouts on workloads we haven't really anticipated or where the
> runtime effects happen to disagree with our intuition. So while those
> numbers are nice there are other important aspects to consider like the
> maintenance cost for example.

I assume we agree this is not an easy decision. Can I also assume we
agree that this decision should be make within a reasonable time frame?

> > The numbers might not materialize in the real world; the code is not
> > perfect; and many other risks... But all the top eight open source
> > memory hogs were covered, which is unprecedented; memcached and fio
> > showed significant improvements and it only takes a few commands to
> > see for yourselves.
> > 
> > Regarding the acks and the reviewed-bys, I certainly can ask people
> > who have reaped the benefits of this patchset to do them, if it's
> > required. But I see less fun in that. I prefer to provide empirical
> > evidence and convince people who are on the other side of the aisle.
> 
> I like to hear from users who benefit from your work and that certainly
> gives more credit to it. But it will be the MM community to maintain the
> code and address future issues.

I'll ask downstream kernel maintainers (from different distros) that
have taken this patchset to ACK.

I'll ask credible testers who are professionals, researchers,
contributors to other subsystems to provide Test-by's. There are many
other individual testers I may not be able to acknowledge their
efforts, e.g., my coworker just sent this to me:

   Using that v5 for some time and confirm that difference under heavy
   load and memory pressure is significant."
https://www.phoronix.com/forums/forum/software/general-linux-open-source/1301258-mglru-is-a-very-enticing-enhancement-for-linux-in-2022#post1301275

I'll leave the reviews in your capable hands. As I said, I prefer to
convince people with empirical evidence.

> We do not have a dedicated maintainer for the memory reclaim but
> certainly there are people who have helped shaping the existing code and
> have learned a lot from the past issues - like Johannes, Rik, Mel just
> to name few. If I were you I would be really looking into finding an
> agreement with them. I myself can help you with memcg and oom side of
> the things (we already have discussions about those).

Unfortunately people have different priorities. As I said, we tried
to get all the stakeholders in the same (conference) room so that we
can make some good progress. But we failed.

Rest assured, we'll keep trying. But please understand we need to do
cost control and therefore we can't keep investing in this effort
forever. So I think it's not unreasonable, after I've addressed all
pending comments, to ask for some clear instructions from the
leadership:
    Yes
    No
    Or something specific

Thanks!


From robh at kernel.org  Mon Jan 10 14:11:18 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 16:11:18 -0600
Subject: [PATCH 7/8] dt-bindings: clock: samsung: convert Exynos5410 to
 dtschema
In-Reply-To: <20220102115356.75796-7-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-7-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyvBtQhApv1LhwK@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:55 +0100, Krzysztof Kozlowski wrote:
> Convert Samsung Exynos5410 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/exynos5410-clock.txt       | 50 --------------
>  .../clock/samsung,exynos5410-clock.yaml       | 66 +++++++++++++++++++
>  MAINTAINERS                                   |  1 -
>  3 files changed, 66 insertions(+), 51 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/exynos5410-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
> 

Applied, thanks!


From robh at kernel.org  Mon Jan 10 14:11:27 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 16:11:27 -0600
Subject: [PATCH 8/8] dt-bindings: clock: samsung: convert S5Pv210 to
 dtschema
In-Reply-To: <20220102115356.75796-8-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-8-krzysztof.kozlowski@canonical.com>
Message-ID: <YdyvD/yfB6Wm+Xua@robh.at.kernel.org>

On Sun, 02 Jan 2022 12:53:56 +0100, Krzysztof Kozlowski wrote:
> Convert Samsung S5Pv210 SoC clock controller bindings to DT schema
> format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/clock/samsung,s5pv210-clock.txt  | 77 ------------------
>  .../bindings/clock/samsung,s5pv210-clock.yaml | 79 +++++++++++++++++++
>  MAINTAINERS                                   |  1 -
>  3 files changed, 79 insertions(+), 78 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.txt
>  create mode 100644 Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
> 

Applied, thanks!


From robh at kernel.org  Mon Jan 10 14:11:57 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 10 Jan 2022 16:11:57 -0600
Subject: [PATCH v2 1/9] dt-bindings: clk: mstar msc313 cpupll binding
 description
In-Reply-To: <20220102165730.50190-2-romain.perier@gmail.com>
References: <20220102165730.50190-1-romain.perier@gmail.com>
 <20220102165730.50190-2-romain.perier@gmail.com>
Message-ID: <YdyvLSbjrPPg80Pa@robh.at.kernel.org>

On Sun, 02 Jan 2022 17:57:22 +0100, Romain Perier wrote:
> From: Daniel Palmer <daniel at 0x0f.com>
> 
> Add a binding description for the MStar/SigmaStar CPU PLL block.
> 
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> ---
>  .../bindings/clock/mstar,msc313-cpupll.yaml   | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From m.szyprowski at samsung.com  Mon Jan 10 14:15:55 2022
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 10 Jan 2022 23:15:55 +0100
Subject: [RFC PATCH 1/1] ARM: exynos: only do SMC_CMD_CPU1BOOT call on
 Exynos4
In-Reply-To: <YdyF4cvS2GRxKPVn@localhost>
References: <20220108215733.705865-1-henrik@grimler.se>
 <CGME20220108215952eucas1p1bb9bc56c7f8ac7117b5e5576635460d5@eucas1p1.samsung.com>
 <20220108215733.705865-2-henrik@grimler.se>
 <2202f06f-e901-44bb-b6dc-7225dd093e1b@samsung.com>
 <YdyF4cvS2GRxKPVn@localhost>
Message-ID: <cab52568-d70e-d062-e526-fa61cab7c9c3@samsung.com>


On 10.01.2022 20:16, Henrik Grimler wrote:
> Hi Marek,
>> Works fine on all ARM 32bit Exynos-based boards I have for tests.
>>
>> Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Thanks for testing!  Would you mind telling me which Exynos boards you
> have in your test-setup?

Sure:

Exynos3250: Rinato
Exynos4210: Trats
Exynos4412: Trats2, Odroid X2/U3
Exynos5250: Snow Chromebook, Arndale5250
Exynos5410: Odroid XU
Exynos5420: Pit Chromebook
Exynos5422: Odroud Xu3/Xu3-lite/Xu4/HC1
Exynos5800: Pi Chromebook


Best regards

-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From martin.blumenstingl at googlemail.com  Mon Jan 10 14:18:33 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 10 Jan 2022 23:18:33 +0100
Subject: [PATCH v3 1/2] dt-bindings: phy: add Amlogic G12A Analog MIPI
 D-PHY bindings
In-Reply-To: <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>
References: <20220107150512.614423-1-narmstrong@baylibre.com>
 <20220107150512.614423-2-narmstrong@baylibre.com>
 <CAFBinCDRx6VaaAubr6VRLnX=G4Ez8cGg-=6e-9GWrH8FwwBs-g@mail.gmail.com>
 <fad140b9-2940-a24a-ba70-9849bacf617d@baylibre.com>
Message-ID: <CAFBinCC7wfPjLGVe87E0H7WYXwrFw0e0k_2epF1dDaWKkSvRyQ@mail.gmail.com>

Hi Neil,

On Mon, Jan 10, 2022 at 10:25 AM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> On 07/01/2022 23:13, Martin Blumenstingl wrote:
> > Hi Neil,
> >
> > On Fri, Jan 7, 2022 at 4:05 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> > [...]
> >> +required:
> >> +  - compatible
> >> +  - reg
> >> +  - "#phy-cells"
> > I also found a "MIPI DSI PHY clock" and "MIPI DSI PHY interrupt" in
> > the datasheet.
> > I'm no expert on this and I'm just asking in case you have missed one of these:
> > Can you confirm that these belong to some other IP?
>
> Indeed the name is misleading, both go to the DSI Transceiver IP (dw-mipi-dsi)
Thank you for clarifying this!

I just found an old comment from Rob on v2 of this series: [0]
He mentions:
"If this is a child of something else, then put a $ref to this schema
and the example in the parent schema."

To be honest: I completely forgot about that comment until now.
If I had remembered it (and assuming that his comment is still valid)
then I would have had to NACK my own
Documentation/devicetree/bindings/phy/amlogic,meson8-hdmi-tx-phy.yaml
For today it's already late so I'll look into this more tomorrow.


Best regards,
Martin


[0] https://lore.kernel.org/all/20210210165118.GA2311581 at robh.at.kernel.org/


From m.szyprowski at samsung.com  Mon Jan 10 14:20:49 2022
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Mon, 10 Jan 2022 23:20:49 +0100
Subject: [RFT][PATCH 1/3] ARM: dts: exynos: fix UART3 pins configuration
 in Exynos5250
In-Reply-To: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
References: <CGME20211230195340eucas1p1ebbcf10a6b4fb15fca9b7757af5e1702@eucas1p1.samsung.com>
 <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
Message-ID: <a0b84be2-55b5-64e7-d39a-c3cd3f46d443@samsung.com>

On 30.12.2021 20:53, Krzysztof Kozlowski wrote:
> The gpa1-4 pin was put twice in UART3 pin configuration of Exynos5250,
> instead of proper pin gpa1-5.
>
> Fixes: f8bfe2b050f3 ("ARM: dts: add pin state information in client nodes for Exynos5 platforms")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Well, the uart3_data node is not referenced anywhere, so this change is 
not really relevant to any board, but for the completeness, feel free to 
add:

Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>


> ---
>   arch/arm/boot/dts/exynos5250-pinctrl.dtsi | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> index d31a68672bfa..d7d756614edd 100644
> --- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
> @@ -260,7 +260,7 @@ i2c3_hs_bus: i2c3-hs-bus {
>   	};
>   
>   	uart3_data: uart3-data {
> -		samsung,pins = "gpa1-4", "gpa1-4";
> +		samsung,pins = "gpa1-4", "gpa1-5";
>   		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>   		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>   		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From irogers at google.com  Mon Jan 10 14:22:34 2022
From: irogers at google.com (Ian Rogers)
Date: Mon, 10 Jan 2022 14:22:34 -0800
Subject: [PATCH v4 04/48] perf stat: Switch aggregation to use for_each
 loop
In-Reply-To: <0e26524c-9f4c-b351-2498-0a56bc86b4ee@huawei.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-5-irogers@google.com>
 <0e26524c-9f4c-b351-2498-0a56bc86b4ee@huawei.com>
Message-ID: <CAP-5=fWU+JBpqpE0ujGfs5TmnY9mv5CWNdMc=X_zKe79GTvPfw@mail.gmail.com>

On Mon, Jan 10, 2022 at 10:51 AM John Garry <john.garry at huawei.com> wrote:
>
> On 05/01/2022 06:13, Ian Rogers wrote:
> > +     cpus = evsel__cpus(evsel);
> > +     perf_cpu_map__for_each_cpu(cpu, idx, cpus) {
>
> It seems a common pattern to evaluate cpus and use in
> perf_cpu_map__for_each_cpu() - is it possible to make a macro to accept
> evsel and create cpus, like perf_evsel__for_each_cpu()?

It's possible, I'm not sure it is saving much and it is common to also
want to iterate the cpumap of the evlist.

Thanks,
Ian

> > +             if (cpu_map__compare_aggr_cpu_id(config->aggr_get_id(config, cpus, idx),
> > +                                              id))
> > +                     return cpu;
> >       }
> >       return 0;
>


From irogers at google.com  Mon Jan 10 14:29:58 2022
From: irogers at google.com (Ian Rogers)
Date: Mon, 10 Jan 2022 14:29:58 -0800
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <Ydymdm/PoB0hQVUT@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
 <Ydyjvcma/wMTPwbn@kernel.org> <Ydymdm/PoB0hQVUT@kernel.org>
Message-ID: <CAP-5=fVAa3JVbdzNZg0LrVfw__9U9Q8PkHcro+TJiFVyvTho+A@mail.gmail.com>

On Mon, Jan 10, 2022 at 1:34 PM Arnaldo Carvalho de Melo
<acme at kernel.org> wrote:
>
> Em Mon, Jan 10, 2022 at 06:23:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > At this point we need to remove the now unused perf_env__get_cpu(), and
> > > > then deal with the fallout in the following patches that needlessly
> > > > modify this unused function.
> > > >
> > > > Doing that now.
> > >
> > > Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> > > build containers, a better start now:
>
> > So far so good:
>
> perf test ok, just that one that is failing, but before this series as
> well:
>
>  89: perf all metricgroups test                                      : FAILED!

Could you add the verbose output? I suspect it is fixed by this:
https://lore.kernel.org/lkml/20211223183948.3423989-1-irogers at google.com/

Thanks,
Ian

> [acme at quaco perf]$ uname -a
> Linux quaco 5.15.7-200.fc35.x86_64 #1 SMP Wed Dec 8 19:00:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
> [acme at quaco perf]$ git log --oneline -1
> 16ed0580fb4d64bd (HEAD -> perf/core, seventh/perf/core, five/perf/core, acme.korg/tmp.perf/perf_cpu) perf cpumap: Give CPUs their own type
> [acme at quaco perf]$ perf -v
> perf version 5.16.g16ed0580fb4d
> [acme at quaco perf]$ sudo su -
> [sudo] password for acme:
> [root at quaco ~]# perf -vv
> perf version 5.16.g16ed0580fb4d
>                  dwarf: [ on  ]  # HAVE_DWARF_SUPPORT
>     dwarf_getlocations: [ on  ]  # HAVE_DWARF_GETLOCATIONS_SUPPORT
>                  glibc: [ on  ]  # HAVE_GLIBC_SUPPORT
>          syscall_table: [ on  ]  # HAVE_SYSCALL_TABLE_SUPPORT
>                 libbfd: [ on  ]  # HAVE_LIBBFD_SUPPORT
>                 libelf: [ on  ]  # HAVE_LIBELF_SUPPORT
>                libnuma: [ on  ]  # HAVE_LIBNUMA_SUPPORT
> numa_num_possible_cpus: [ on  ]  # HAVE_LIBNUMA_SUPPORT
>                libperl: [ on  ]  # HAVE_LIBPERL_SUPPORT
>              libpython: [ on  ]  # HAVE_LIBPYTHON_SUPPORT
>               libslang: [ on  ]  # HAVE_SLANG_SUPPORT
>              libcrypto: [ on  ]  # HAVE_LIBCRYPTO_SUPPORT
>              libunwind: [ on  ]  # HAVE_LIBUNWIND_SUPPORT
>     libdw-dwarf-unwind: [ on  ]  # HAVE_DWARF_SUPPORT
>                   zlib: [ on  ]  # HAVE_ZLIB_SUPPORT
>                   lzma: [ on  ]  # HAVE_LZMA_SUPPORT
>              get_cpuid: [ on  ]  # HAVE_AUXTRACE_SUPPORT
>                    bpf: [ on  ]  # HAVE_LIBBPF_SUPPORT
>                    aio: [ on  ]  # HAVE_AIO_SUPPORT
>                   zstd: [ on  ]  # HAVE_ZSTD_SUPPORT
>                libpfm4: [ OFF ]  # HAVE_LIBPFM
> [root at quaco ~]# perf test
>   1: vmlinux symtab matches kallsyms                                 : Ok
>   2: Detect openat syscall event                                     : Ok
>   3: Detect openat syscall event on all cpus                         : Ok
>   4: Read samples using the mmap interface                           : Ok
>   5: Test data source output                                         : Ok
>   6: Parse event definition strings                                  : Ok
>   7: Simple expression parser                                        : Ok
>   8: PERF_RECORD_* events & perf_sample fields                       : Ok
>   9: Parse perf pmu format                                           : Ok
>  10: PMU events                                                      :
>  10.1: PMU event table sanity                                        : Ok
>  10.2: PMU event map aliases                                         : Ok
>  10.3: Parsing of PMU event table metrics                            : Ok
>  10.4: Parsing of PMU event table metrics with fake PMUs             : Ok
>  11: DSO data read                                                   : Ok
>  12: DSO data cache                                                  : Ok
>  13: DSO data reopen                                                 : Ok
>  14: Roundtrip evsel->name                                           : Ok
>  15: Parse sched tracepoints fields                                  : Ok
>  16: syscalls:sys_enter_openat event fields                          : Ok
>  17: Setup struct perf_event_attr                                    : Ok
>  18: Match and link multiple hists                                   : Ok
>  19: 'import perf' in python                                         : Ok
>  20: Breakpoint overflow signal handler                              : Ok
>  21: Breakpoint overflow sampling                                    : Ok
>  22: Breakpoint accounting                                           : Ok
>  23: Watchpoint                                                      :
>  23.1: Read Only Watchpoint                                          : Skip (missing hardware support)
>  23.2: Write Only Watchpoint                                         : Ok
>  23.3: Read / Write Watchpoint                                       : Ok
>  23.4: Modify Watchpoint                                             : Ok
>  24: Number of exit events of a simple workload                      : Ok
>  25: Software clock events period values                             : Ok
>  26: Object code reading                                             : Ok
>  27: Sample parsing                                                  : Ok
>  28: Use a dummy software event to keep tracking                     : Ok
>  29: Parse with no sample_id_all bit set                             : Ok
>  30: Filter hist entries                                             : Ok
>  31: Lookup mmap thread                                              : Ok
>  32: Share thread maps                                               : Ok
>  33: Sort output of hist entries                                     : Ok
>  34: Cumulate child hist entries                                     : Ok
>  35: Track with sched_switch                                         : Ok
>  36: Filter fds with revents mask in a fdarray                       : Ok
>  37: Add fd to a fdarray, making it autogrow                         : Ok
>  38: kmod_path__parse                                                : Ok
>  39: Thread map                                                      : Ok
>  40: LLVM search and compile                                         :
>  40.1: Basic BPF llvm compile                                        : Ok
>  40.2: kbuild searching                                              : Ok
>  40.3: Compile source for BPF prologue generation                    : Ok
>  40.4: Compile source for BPF relocation                             : Ok
>  41: Session topology                                                : Ok
>  42: BPF filter                                                      :
>  42.1: Basic BPF filtering                                           : Ok
>  42.2: BPF pinning                                                   : Ok
>  42.3: BPF prologue generation                                       : Ok
>  43: Synthesize thread map                                           : Ok
>  44: Remove thread map                                               : Ok
>  45: Synthesize cpu map                                              : Ok
>  46: Synthesize stat config                                          : Ok
>  47: Synthesize stat                                                 : Ok
>  48: Synthesize stat round                                           : Ok
>  49: Synthesize attr update                                          : Ok
>  50: Event times                                                     : Ok
>  51: Read backward ring buffer                                       : Ok
>  52: Print cpu map                                                   : Ok
>  53: Merge cpu map                                                   : Ok
>  54: Probe SDT events                                                : Ok
>  55: is_printable_array                                              : Ok
>  56: Print bitmap                                                    : Ok
>  57: perf hooks                                                      : Ok
>  58: builtin clang support                                           :
>  58.1: builtin clang compile C source to IR                          : Skip (not compiled in)
>  58.2: builtin clang compile C source to ELF object                  : Skip (not compiled in)
>  59: unit_number__scnprintf                                          : Ok
>  60: mem2node                                                        : Ok
>  61: time utils                                                      : Ok
>  62: Test jit_write_elf                                              : Ok
>  63: Test libpfm4 support                                            :
>  63.1: test of individual --pfm-events                               : Skip (not compiled in)
>  63.2: test groups of --pfm-events                                   : Skip (not compiled in)
>  64: Test api io                                                     : Ok
>  65: maps__merge_in                                                  : Ok
>  66: Demangle Java                                                   : Ok
>  67: Demangle OCaml                                                  : Ok
>  68: Parse and process metrics                                       : Ok
>  69: PE file support                                                 : Ok
>  70: Event expansion for cgroups                                     : Ok
>  71: Convert perf time to TSC                                        : Ok
>  72: dlfilter C API                                                  : Ok
>  73: Sigtrap                                                         : Ok
>  74: x86 rdpmc                                                       : Ok
>  75: Test dwarf unwind                                               : Ok
>  76: x86 instruction decoder - new instructions                      : Ok
>  77: Intel PT packet decoder                                         : Ok
>  78: x86 bp modify                                                   : Ok
>  79: x86 Sample parsing                                              : Ok
>  80: build id cache operations                                       : Ok
>  81: daemon operations                                               : Ok
>  82: perf pipe recording and injection test                          : Ok
>  83: Add vfs_getname probe to get syscall args filenames             : Ok
>  84: probe libc's inet_pton & backtrace it with ping                 : Ok
>  85: Use vfs_getname probe to get syscall args filenames             : Ok
>  86: Zstd perf.data compression/decompression                        : Ok
>  87: perf stat csv summary test                                      : Ok
>  88: perf stat metrics (shadow stat) test                            : Ok
>  89: perf all metricgroups test                                      : FAILED!
>  90: perf all metrics test                                           : Ok
>  91: perf all PMU test                                               : Ok
>  92: perf stat --bpf-counters test                                   : Ok
>  93: Check Arm CoreSight trace data recording and synthesized samples: Skip
>  94: Check Arm SPE trace data recording and synthesized samples      : Skip
>  95: Check open filename arg using perf trace + vfs_getname          : Ok
> [root at quaco ~]#
>
> And the containers are ok so far:
>
> [perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
> [perfbuilder at five ~]$ time dm
>    1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
>    2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
>    3    54.98 alpine:3.5                    : Ok   gcc (Alpine 6.2.1) 6.2.1 20160822 , clang version 3.8.1 (tags/RELEASE_381/final)
>    4    57.69 alpine:3.6                    : Ok   gcc (Alpine 6.3.0) 6.3.0 , clang version 4.0.0 (tags/RELEASE_400/final)
>    5    63.62 alpine:3.7                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0)
>    6    64.52 alpine:3.8                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
>    7    66.54 alpine:3.9                    : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1)
>    8    91.91 alpine:3.10                   : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0)
>    9   104.93 alpine:3.11                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0)
>   10   107.97 alpine:3.12                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c)
>   11   115.98 alpine:3.13                   : Ok   gcc (Alpine 10.2.1_pre1) 10.2.1 20201203 , Alpine clang version 10.0.1
>   12   101.73 alpine:3.14                   : Ok   gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424 , Alpine clang version 11.1.0
>   13   103.35 alpine:3.15                   : Ok   gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027 , Alpine clang version 12.0.1
>   14   104.43 alpine:edge                   : Ok   gcc (Alpine 11.2.1_git20211128) 11.2.1 20211128 , Alpine clang version 12.0.1
>   15    51.06 alt:p8                        : Ok   x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1) , clang version 3.8.0 (tags/RELEASE_380/final)
>   16    75.95 alt:p9                        : Ok   x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1) , clang version 10.0.0
>   17    75.26 alt:p10                       : Ok   x86_64-alt-linux-gcc (GCC) 10.3.1 20210703 (ALT Sisyphus 10.3.1-alt2) , clang version 11.0.1
>   18    74.85 alt:sisyphus                  : Ok   x86_64-alt-linux-gcc (GCC) 11.2.1 20210911 (ALT Sisyphus 11.2.1-alt1) , ALT Linux Team clang version 12.0.1
>   19    52.87 amazonlinux:1                 : Ok   gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) , clang version 3.6.2 (tags/RELEASE_362/final)
>   20    85.98 amazonlinux:2                 : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13) , clang version 11.1.0 (Amazon Linux 2 11.1.0-1.amzn2.0.2)
>   21    79.77 archlinux:base                : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
>   22    83.56 centos:8                      : Ok   gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1) , clang version 11.0.1 (Red Hat 11.0.1-1.module_el8.4.0+966+2995ef20)
>   23    98.02 centos:stream                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-3) , clang version 12.0.1 (Red Hat 12.0.1-2.module_el8.6.0+937+1cafe22c)
>   24    27.67 clearlinux:latest             : Ok   gcc (Clear Linux OS for Intel Architecture) 11.2.1 20211228 releases/gcc-11.2.0-618-g3b2b18144c , clang version 11.1.0
>   25    65.92 debian:9                      : Ok   gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 , clang version 3.8.1-24 (tags/RELEASE_381/final)
>   26    62.20 debian:10                     : Ok   gcc (Debian 8.3.0-6) 8.3.0 , clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)
>   27: debian:11
>


From jsbarnes at google.com  Mon Jan 10 14:46:08 2022
From: jsbarnes at google.com (Jesse Barnes)
Date: Mon, 10 Jan 2022 14:46:08 -0800
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdythmxHpSksJiXs@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
 <YdgKClGAuHlkzVbQ@dhcp22.suse.cz> <YdiKVJlClB3h1Kmg@google.com>
 <YdxTR4+FL08XyFuO@dhcp22.suse.cz> <YdythmxHpSksJiXs@google.com>
Message-ID: <CAJmaN=n=kn9-gC8if5wp8Gfj7uN+QVrX0ex=9JPXC7rPvGf1Qg@mail.gmail.com>

> > > 2. There have been none that came with the testing/benchmarking
> > >    coverage as this one did. Please point me to some if I'm mistaken,
> > >    and I'll gladly match them.
> >
> > I do appreciate your numbers but you should realize that this is an area
> > that is really hard to get any conclusive testing for.
>
> Fully agreed. That's why we started a new initiative, and we hope more
> people will following these practices:
> 1. All results in this area should be reported with at least standard
>    deviations, or preferably confidence intervals.
> 2. Real applications should be benchmarked (with synthetic load
>    generator), not just synthetic benchmarks (not real applications).
> 3. A wide range of devices should be covered, i.e., servers, desktops,
>    laptops and phones.
>
> I'm very confident to say our benchmark reports were hold to the
> highest standards. We have worked with MariaDB (company), EnterpriseDB
> (Postgres), Redis (company), etc. on these reports. They have copies
> of these reports (PDF version):
> https://linux-mm.googlesource.com/benchmarks/
>
> We welcome any expert in those applications to examine our reports,
> and we'll be happy to run any other benchmarks or same benchmarks with
> different configurations that anybody thinks it's important and we've
> missed.

I really think this gets at the heart of the issue with mm
development, and is one of the reasons it's been extra frustrating to
not have an MM conf for the past couple of years; I think sorting out
how we measure & proceed on changes would be easier done f2f.  E.g.
concluding with a consensus that if something doesn't regress on X, Y,
and Z, and has reasonably maintainable and readable code, we should
merge it and try it out.

But since f2f isn't an option until 2052 at the earliest...

I understand the desire for an "incremental approach that gets us from
A->B".  In the abstract it sounds great.  However, with a change like
this one, I think it's highly likely that such a path would be
littered with regressions both large and small, and would probably be
more difficult to reason about than the relatively clean design of
MGLRU.  On top of that, I don't think we'll get the kind of user
feedback we need for something like this *without* merging it.  Yu has
done a tremendous job collecting data here (and the results are really
incredible), but I think we can all agree that without extensive
testing in the field with all sorts of weird codes, we're not going to
find the problematic behaviors we're concerned about.

So unless we want to eschew big mm changes entirely (we shouldn't!
look at net or scheduling for how important big rewrites are to
progress), I think we should be open to experimenting with new stuff.
We can always revert if things get too unwieldy.

None of this is to say that there may not be lots more comments on the
code or potential fixes/changes to incorporate before merging; I'm
mainly arguing about the mindset we should have to changes like this,
not all the stuff the community is already really good at (i.e.
testing and reviewing code on a nuts & bolts level).

Thanks,
Jesse


From abel.vesa at nxp.com  Mon Jan 10 14:48:10 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 11 Jan 2022 00:48:10 +0200
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050
 clock driver
In-Reply-To: <20220110201201.C1E37C36AE9@smtp.kernel.org>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
 <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
 <20220110201201.C1E37C36AE9@smtp.kernel.org>
Message-ID: <Ydy3qvT5w6IWnR7s@abelvesa>

On 22-01-10 12:12:00, Stephen Boyd wrote:
> Quoting Jesse Taube (2022-01-09 11:07:42)
> > >> +
> > >> +       clk_hw_data->num = IMXRT1050_CLK_END;
> > >> +       hws = clk_hw_data->hws;
> > >> +
> > >> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> > > 
> > > Use clk_parent_data instead and reference the binding name with .fw_name
> > 
> > Hi Stephen, sorry to bother you again.
> > I'm wondering if adding `clk_parent_data` is necessary as it seems like 
> > it wold be a big change and the other IMX boards haven't implemented 
> > this yet would it be okay if I don't do this, or if it is necessary 
> > could you link to a patch set to change it.
> > 
> 
> Is it a big change because the imx_clk_hw*() APIs aren't prepared for
> non-string parents? Can you make some clk_parent_data based APIs and
> migrate things over gradually? This is really a question for i.MX folks
> to see if anyone is working on moving away from the string names.

I'm currently looking into it. I would suggest we take this patch as is
and I'll switch it later on to clk_parent_data.



From rananta at google.com  Mon Jan 10 15:07:13 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 10 Jan 2022 15:07:13 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
Message-ID: <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>

On Fri, Jan 7, 2022 at 4:05 PM Jim Mattson <jmattson at google.com> wrote:
>
> On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > Hi Reiji,
> >
> > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > >
> > > Hi Raghu,
> > >
> > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > <rananta at google.com> wrote:
> > > >
> > > > Capture the start of the KVM VM, which is basically the
> > > > start of any vCPU run. This state of the VM is helpful
> > > > in the upcoming patches to prevent user-space from
> > > > configuring certain VM features after the VM has started
> > > > running.
>
> What about live migration, where the VM has already technically been
> started before the first call to KVM_RUN?

My understanding is that a new 'struct kvm' is created on the target
machine and this flag should be reset, which would allow the VMM to
restore the firmware registers. However, we would be running KVM_RUN
for the first time on the target machine, thus setting the flag.
So, you are right; It's more of a resume operation from the guest's
point of view. I guess the name of the variable is what's confusing
here.

Thanks,
Raghavendra


From rananta at google.com  Mon Jan 10 15:23:46 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 10 Jan 2022 15:23:46 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <Ydjje8qBOP3zDOZi@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
Message-ID: <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>

On Fri, Jan 7, 2022 at 5:06 PM Sean Christopherson <seanjc at google.com> wrote:
>
> On Tue, Jan 04, 2022, Raghavendra Rao Ananta wrote:
> > Capture the start of the KVM VM, which is basically the
>
> Please wrap at ~75 chars.
>
> > start of any vCPU run. This state of the VM is helpful
> > in the upcoming patches to prevent user-space from
> > configuring certain VM features after the VM has started
> > running.
>
> Please provide context of how the flag will be used.  I glanced at the future
> patches, and knowing very little about arm, I was unable to glean useful info
> about exactly who is being prevented from doing what.
>
> >
> > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > ---
> >  include/linux/kvm_host.h | 3 +++
> >  virt/kvm/kvm_main.c      | 9 +++++++++
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > index c310648cc8f1..d0bd8f7a026c 100644
> > --- a/include/linux/kvm_host.h
> > +++ b/include/linux/kvm_host.h
> > @@ -623,6 +623,7 @@ struct kvm {
> >       struct notifier_block pm_notifier;
> >  #endif
> >       char stats_id[KVM_STATS_NAME_SIZE];
> > +     bool vm_started;
> >  };
> >
> >  #define kvm_err(fmt, ...) \
> > @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> >       }
> >  }
> >
> > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
>
> Needs parantheses around (kvm), but why bother with a macro?  This is the same
> header that defines struct kvm.
>
No specific reason for creating a macro as such. I can remove it if it
feels noisy.
> > +
> >  extern bool kvm_rebooting;
> >
> >  extern unsigned int halt_poll_ns;
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 72c4e6b39389..962b91ac2064 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
> >       int r;
> >       struct kvm_fpu *fpu = NULL;
> >       struct kvm_sregs *kvm_sregs = NULL;
> > +     struct kvm *kvm = vcpu->kvm;
>
> If you're going to bother grabbing kvm, replace the instances below that also do
> vcpu->kvm.
>
> >
> >       if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
> >               return -EIO;
> > @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
> >                       if (oldpid)
> >                               synchronize_rcu();
> >                       put_pid(oldpid);
> > +
> > +                     /*
> > +                      * Since we land here even on the first vCPU run,
> > +                      * we can mark that the VM has started running.
>
> Please avoid "we", "us", etc..
>
> "vm_started" is also ambiguous.  If we end up with a flag, then I would prefer a
> much more literal name, a la created_vcpus, e.g. ran_vcpus or something.
>
> > +                      */
> > +                     mutex_lock(&kvm->lock);
>
> This adds unnecessary lock contention when running vCPUs.  The naive solution
> would be:
>                         if (!kvm->vm_started) {
>                                 ...
>                         }
>
Not sure if I understood the solution..

> > +                     kvm->vm_started = true;
> > +                     mutex_unlock(&kvm->lock);
>
> Lastly, why is this in generic KVM?
>
The v1 of the series originally had it in the arm specific code.
However, I was suggested to move it to the generic code since the book
keeping is not arch specific and could be helpful to others too [1].

Thanks for the review. I'll add your other comments as well.

Regards,
Raghavendra

[1]: https://lore.kernel.org/kvmarm/YYMKphExkqttn2w0 at google.com/

> >               }
> >               r = kvm_arch_vcpu_ioctl_run(vcpu);
> >               trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm at lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From joel at jms.id.au  Mon Jan 10 15:29:30 2022
From: joel at jms.id.au (Joel Stanley)
Date: Mon, 10 Jan 2022 23:29:30 +0000
Subject: [PATCH 3/3] ARM: aspeed: Add secure boot controller support
In-Reply-To: <20211117035106.321454-4-joel@jms.id.au>
References: <20211117035106.321454-1-joel@jms.id.au>
 <20211117035106.321454-4-joel@jms.id.au>
Message-ID: <CACPK8XcSPiOoJZ4jyJySvCiW+EXxSVsxiEcK2eOZjGY9b1vrjA@mail.gmail.com>

Hi Arnd,

On Wed, 17 Nov 2021 at 03:51, Joel Stanley <joel at jms.id.au> wrote:
>
> This reads out the status of the secure boot controller and exposes it
> in sysfs.
>
> An example on a AST2600A3 QEMU model:
>
>  # grep . /sys/bus/soc/devices/soc0/*
>  /sys/bus/soc/devices/soc0/abr_image:0
>  /sys/bus/soc/devices/soc0/family:AST2600
>  /sys/bus/soc/devices/soc0/low_security_key:0
>  /sys/bus/soc/devices/soc0/machine:Rainier 2U
>  /sys/bus/soc/devices/soc0/otp_protected:0
>  /sys/bus/soc/devices/soc0/revision:A3
>  /sys/bus/soc/devices/soc0/secure_boot:1
>  /sys/bus/soc/devices/soc0/serial_number:888844441234abcd
>  /sys/bus/soc/devices/soc0/soc_id:05030303
>  /sys/bus/soc/devices/soc0/uart_boot:1

Quoting from your response to my pull request:

> - I actually want to avoid custom attributes on soc device instances as much
>   as possible. I have not looked in detail at what you add here, but the
>   number of custom attributes means we should discuss this properly.

Can you explain the reasoning here?

I am a bit surprised given we have this nice feature in struct
soc_device_attribute:

struct soc_device_attribute {
...
        const struct attribute_group *custom_attr_group;
};

Cheers,

Joel


>
> On boot the state of the system according to the secure boot controller
> will be printed:
>
>  [    0.037634] AST2600 secure boot enabled
>
> or
>
>  [    0.037935] AST2600 secure boot disabled
>
> Signed-off-by: Joel Stanley <joel at jms.id.au>
> Reviewed-by: Ryan Chen <ryan_chen at aspeedtech.com>
> ---
>  drivers/soc/aspeed/aspeed-socinfo.c | 73 +++++++++++++++++++++++++++++
>  1 file changed, 73 insertions(+)
>
> diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c
> index 1ca140356a08..6faf2c199c90 100644
> --- a/drivers/soc/aspeed/aspeed-socinfo.c
> +++ b/drivers/soc/aspeed/aspeed-socinfo.c
> @@ -9,6 +9,8 @@
>  #include <linux/slab.h>
>  #include <linux/sys_soc.h>
>
> +static u32 security_status;
> +
>  static struct {
>         const char *name;
>         const u32 id;
> @@ -74,6 +76,54 @@ static const char *siliconid_to_rev(u32 siliconid)
>         return "??";
>  }
>
> +#define SEC_STATUS             0x14
> +#define ABR_IMAGE_SOURCE       BIT(13)
> +#define OTP_PROTECTED          BIT(8)
> +#define LOW_SEC_KEY            BIT(7)
> +#define SECURE_BOOT            BIT(6)
> +#define UART_BOOT              BIT(5)
> +
> +static ssize_t abr_image_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       return sprintf(buf, "%d\n", !!(security_status & ABR_IMAGE_SOURCE));
> +}
> +static DEVICE_ATTR_RO(abr_image);
> +
> +static ssize_t low_security_key_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       return sprintf(buf, "%d\n", !!(security_status & LOW_SEC_KEY));
> +}
> +static DEVICE_ATTR_RO(low_security_key);
> +
> +static ssize_t otp_protected_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       return sprintf(buf, "%d\n", !!(security_status & OTP_PROTECTED));
> +}
> +static DEVICE_ATTR_RO(otp_protected);
> +
> +static ssize_t secure_boot_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       return sprintf(buf, "%d\n", !!(security_status & SECURE_BOOT));
> +}
> +static DEVICE_ATTR_RO(secure_boot);
> +
> +static ssize_t uart_boot_show(struct device *dev, struct device_attribute *attr, char *buf)
> +{
> +       /* Invert the bit, as 1 is boot from SPI/eMMC */
> +       return sprintf(buf, "%d\n", !(security_status & UART_BOOT));
> +}
> +static DEVICE_ATTR_RO(uart_boot);
> +
> +static struct attribute *aspeed_attrs[] = {
> +       &dev_attr_abr_image.attr,
> +       &dev_attr_low_security_key.attr,
> +       &dev_attr_otp_protected.attr,
> +       &dev_attr_secure_boot.attr,
> +       &dev_attr_uart_boot.attr,
> +       NULL,
> +};
> +ATTRIBUTE_GROUPS(aspeed);
> +
>  static int __init aspeed_socinfo_init(void)
>  {
>         struct soc_device_attribute *attrs;
> @@ -81,6 +131,7 @@ static int __init aspeed_socinfo_init(void)
>         struct device_node *np;
>         void __iomem *reg;
>         bool has_chipid = false;
> +       bool has_sbe = false;
>         u32 siliconid;
>         u32 chipid[2];
>         const char *machine = NULL;
> @@ -109,6 +160,20 @@ static int __init aspeed_socinfo_init(void)
>         }
>         of_node_put(np);
>
> +       /* AST2600 only */
> +       np = of_find_compatible_node(NULL, NULL, "aspeed,ast2600-sbc");
> +       if (of_device_is_available(np)) {
> +               void *base = of_iomap(np, 0);
> +               if (!base) {
> +                       of_node_put(np);
> +                       return -ENODEV;
> +               }
> +               security_status = readl(base + SEC_STATUS);
> +               has_sbe = true;
> +               iounmap(base);
> +               of_node_put(np);
> +       }
> +
>         attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
>         if (!attrs)
>                 return -ENODEV;
> @@ -135,6 +200,9 @@ static int __init aspeed_socinfo_init(void)
>                 attrs->serial_number = kasprintf(GFP_KERNEL, "%08x%08x",
>                                                  chipid[1], chipid[0]);
>
> +       if (has_sbe)
> +               attrs->custom_attr_group = aspeed_groups[0];
> +
>         soc_dev = soc_device_register(attrs);
>         if (IS_ERR(soc_dev)) {
>                 kfree(attrs->soc_id);
> @@ -148,6 +216,11 @@ static int __init aspeed_socinfo_init(void)
>                         attrs->revision,
>                         attrs->soc_id);
>
> +       if (has_sbe) {
> +               pr_info("AST2600 secure boot %s\n",
> +                       (security_status & SECURE_BOOT) ? "enabled" : "disabled");
> +       }
> +
>         return 0;
>  }
>  early_initcall(aspeed_socinfo_init);
> --
> 2.33.0
>


From rananta at google.com  Mon Jan 10 15:40:35 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 10 Jan 2022 15:40:35 -0800
Subject: [RFC PATCH v3 03/11] KVM: Introduce KVM_CAP_ARM_HVC_FW_REG_BMAP
In-Reply-To: <CAAeT=FxCCD+H1z8+gfyBZNeibfAUqUenZZe56Vj_3fCghJjy=Q@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-4-rananta@google.com>
 <CAAeT=FxCCD+H1z8+gfyBZNeibfAUqUenZZe56Vj_3fCghJjy=Q@mail.gmail.com>
Message-ID: <CAJHc60yY9qH5_r09Tz2fhWr+tT+i7RnKhchBuEePCKnos52kwA@mail.gmail.com>

On Fri, Jan 7, 2022 at 9:40 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> Hi Raghu,
>
> On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > Introduce the KVM ARM64 capability, KVM_CAP_ARM_HVC_FW_REG_BMAP,
> > to indicate the support for psuedo-firmware bitmap extension.
> > Each of these registers holds a feature-set exposed to the guest
> > in the form of a bitmap. If supported, a simple 'read' of the
> > capability should return the number of psuedo-firmware registers
> > supported. User-space can utilize this to discover the registers.
> > It can further explore or modify the features using the classical
> > GET/SET_ONE_REG interface.
> >
> > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > ---
> >  Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
> >  include/uapi/linux/kvm.h       |  1 +
> >  2 files changed, 22 insertions(+)
> >
> > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > index aeeb071c7688..646176537f2c 100644
> > --- a/Documentation/virt/kvm/api.rst
> > +++ b/Documentation/virt/kvm/api.rst
> > @@ -6925,6 +6925,27 @@ indicated by the fd to the VM this is called on.
> >  This is intended to support intra-host migration of VMs between userspace VMMs,
> >  upgrading the VMM process without interrupting the guest.
> >
> > +7.30 KVM_CAP_ARM_HVC_FW_REG_BMAP
>
> IMHO, instead of including its format of the register in the name,
> including its purpose/function in the name might be better.
> e.g. KVM_CAP_ARM_HVC_FEATURE_REG ?
> (Feature fields don't necessarily have to be in a bitmap format
>  if they don't fit well although I'm not sure if we have such fields.)
>
Well we do have registers, KVM_REG_ARM_PSCI_VERSION for instance,
that's not covered by this CAP. But sure, I can explicitly add
'FEATURES' to the name. I also wanted to explicitly convey that we are
covering the *bitmapped* firmware registers here. But not sure if
appending 'BMAP' might give an impression that the CAP itself is
bitmapped.
Do you think KVM_CAP_ARM_HVC_BMAP_FEAT_REG is better?

> > +
> > +:Architectures: arm64
> > +:Parameters: None
> > +:Returns: Number of psuedo-firmware registers supported
>
> Looking at patch-4, the return value of this would be the number of
> pseudo-firmware *bitmap* registers supported.
> BTW, "4.68 KVM_SET_ONE_REG" in the doc uses the word "arm64 firmware
> pseudo-registers".  It would be nicer to use the same term.
>
Nice catch. I'll fix it here in apr.rst.
> > +
> > +This capability indicates that KVM for arm64 supports the psuedo-firmware
> > +register bitmap extension. Each of these registers represent the features
> > +supported by a particular type in the form of a bitmap. By default, these
> > +registers are set with the upper limit of the features that are supported.
> > +
> > +The registers can be accessed via the standard SET_ONE_REG and KVM_GET_ONE_REG
> > +interfaces. The user-space is expected to read the number of these registers
> > +available by reading KVM_CAP_ARM_HVC_FW_REG_BMAP, read the current bitmap
> > +configuration via GET_ONE_REG for each register, and then write back the
> > +desired bitmap of features that it wishes the guest to see via SET_ONE_REG.
> > +
> > +Note that KVM doesn't allow the user-space to modify these registers after
> > +the VM (any of the vCPUs) has started running.
>
> Since even if KVM_RUN fails, and the VM hasn't started yet,
> it will get immutable. So, "after any of the vCPUs run KVM_RUN."
> might be more clear ?
>
Sure, that's probably more clear. I'll fix it.

Regards,
Raghavendra

> Thanks,
> Reiji
>
>
>
> > +
> >  8. Other capabilities.
> >  ======================
> >
> > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> > index 1daa45268de2..209b43dbbc3c 100644
> > --- a/include/uapi/linux/kvm.h
> > +++ b/include/uapi/linux/kvm.h
> > @@ -1131,6 +1131,7 @@ struct kvm_ppc_resize_hpt {
> >  #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
> >  #define KVM_CAP_ARM_MTE 205
> >  #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
> > +#define KVM_CAP_ARM_HVC_FW_REG_BMAP 207
> >
> >  #ifdef KVM_CAP_IRQ_ROUTING
> >
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >


From stevensd at chromium.org  Mon Jan 10 15:47:47 2022
From: stevensd at chromium.org (David Stevens)
Date: Tue, 11 Jan 2022 08:47:47 +0900
Subject: [PATCH v5 4/4] KVM: mmu: remove over-aggressive warnings
In-Reply-To: <Ydhq5aHW+JFo15UF@google.com>
References: <20211129034317.2964790-1-stevensd@google.com>
 <20211129034317.2964790-5-stevensd@google.com>
 <Yc4G23rrSxS59br5@google.com>
 <CAD=HUj5Q6rW8UyxAXUa3o93T0LBqGQb7ScPj07kvuM3txHMMrQ@mail.gmail.com>
 <YdXrURHO/R82puD4@google.com> <YdXvUaBUvaRPsv6m@google.com>
 <CAD=HUj736L5oxkzeL2JoPV8g1S6Rugy_TquW=PRt73YmFzP6Jw@mail.gmail.com>
 <YdcpIQgMZJrqswKU@google.com>
 <CAD=HUj5v37wZ9NuNC4QBDvCGO2SyNG2KAiTc9Jxfg=R7neCuTw@mail.gmail.com>
 <Ydhq5aHW+JFo15UF@google.com>
Message-ID: <CAD=HUj62nanThBtAo2bnEh=xXp+AU0XmJeOCLb2cRkRW03pJbw@mail.gmail.com>

> The best thing to do is probably to wait for for kvm_vcpu_map() to be eliminated,
> as described in the changelogs for commits:
>
>   357a18ad230f ("KVM: Kill kvm_map_gfn() / kvm_unmap_gfn() and gfn_to_pfn_cache")
>   7e2175ebd695 ("KVM: x86: Fix recording of guest steal time / preempted status")
>
> Once that is done, everything in KVM will either access guest memory through the
> userspace hva, or via a mechanism that is tied into the mmu_notifier, at which
> point accessing non-refcounted struct pages is safe and just needs to worry about
> not corrupting _refcount.

That does sound like the best approach. I'll put this patch series on
hold until that work is done.


From jmattson at google.com  Mon Jan 10 15:57:00 2022
From: jmattson at google.com (Jim Mattson)
Date: Mon, 10 Jan 2022 15:57:00 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
Message-ID: <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>

On Mon, Jan 10, 2022 at 3:07 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> On Fri, Jan 7, 2022 at 4:05 PM Jim Mattson <jmattson at google.com> wrote:
> >
> > On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > Hi Reiji,
> > >
> > > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > > >
> > > > Hi Raghu,
> > > >
> > > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > > <rananta at google.com> wrote:
> > > > >
> > > > > Capture the start of the KVM VM, which is basically the
> > > > > start of any vCPU run. This state of the VM is helpful
> > > > > in the upcoming patches to prevent user-space from
> > > > > configuring certain VM features after the VM has started
> > > > > running.
> >
> > What about live migration, where the VM has already technically been
> > started before the first call to KVM_RUN?
>
> My understanding is that a new 'struct kvm' is created on the target
> machine and this flag should be reset, which would allow the VMM to
> restore the firmware registers. However, we would be running KVM_RUN
> for the first time on the target machine, thus setting the flag.
> So, you are right; It's more of a resume operation from the guest's
> point of view. I guess the name of the variable is what's confusing
> here.

I was actually thinking that live migration gives userspace an easy
way to circumvent your restriction. You said, "This state of the VM is
helpful in the upcoming patches to prevent user-space from configuring
certain VM features after the VM has started running." However, if you
don't ensure that these VM features are configured the same way on the
target machine as they were on the source machine, you have not
actually accomplished your stated goal.

> Thanks,
> Raghavendra


From laurent.pinchart at ideasonboard.com  Mon Jan 10 15:58:04 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 11 Jan 2022 01:58:04 +0200
Subject: [PATCH v1 01/14] arm64: dts: imx8mm: fix strange hex notation
In-Reply-To: <20220107180314.1816515-2-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-2-marcel@ziswiler.com>
Message-ID: <YdzIDNa0gHqbLChi@pendragon.ideasonboard.com>

Hi Marcel,

Thank you for the patch.

On Fri, Jan 07, 2022 at 07:03:01PM +0100, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Fix strange hex notation with mixed lower-case and upper-case letters.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> ---
> 
>  arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> index a003e6af3353..c68a5e456025 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> @@ -279,7 +279,7 @@
>  #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
>  #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
>  #define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
> -#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53c 0x4 0x0
> +#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53C 0x4 0x0
>  #define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
>  #define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
>  #define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
> @@ -486,7 +486,7 @@
>  #define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
>  #define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                0x1D8 0x440 0x000 0x1 0x0
>  #define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
> -#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4Fc 0x4 0x2
> +#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4FC 0x4 0x2
>  #define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                 0x1D8 0x440 0x000 0x4 0x0
>  #define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
>  #define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
> @@ -494,7 +494,7 @@
>  #define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
>  #define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
>  #define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX                                  0x1DC 0x444 0x000 0x4 0x0
> -#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4Fc 0x4 0x3
> +#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4FC 0x4 0x3
>  #define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
>  #define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
>  #define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0

-- 
Regards,

Laurent Pinchart


From khilman at baylibre.com  Mon Jan 10 15:59:03 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 10 Jan 2022 15:59:03 -0800
Subject: [v6 0/5] Mediatek MT8195 power domain support
In-Reply-To: <20211116025045.5401-1-chun-jie.chen@mediatek.com>
References: <20211116025045.5401-1-chun-jie.chen@mediatek.com>
Message-ID: <7h5yqruoqg.fsf@baylibre.com>

Chun-Jie Chen <chun-jie.chen at mediatek.com> writes:

> This patch series adds power domain support for MT8195
> and is based on 5.16-rc1.

Reviewed-by: Kevin Hilman <khilman at baylibre.com>



From tharvey at gateworks.com  Mon Jan 10 16:00:21 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Mon, 10 Jan 2022 16:00:21 -0800
Subject: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt overlays for
 serial modes
In-Reply-To: <20211214213630.14819-1-tharvey@gateworks.com>
References: <20211214213630.14819-1-tharvey@gateworks.com>
Message-ID: <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>

On Tue, Dec 14, 2021 at 1:36 PM Tim Harvey <tharvey at gateworks.com> wrote:
>
> The imx8mm-venice-gw73xx-0x som+baseboard combination has a multi-protocol
> RS-232/RS-485/RS-422 transceiver to an off-board connector which
> can be configured in a number of ways via UART and GPIO configuration.
>
> The default configuration per the imx8mm-venice-gw73xx-0x dts is for
> UART2 TX/RX and UART4 TX/RX to be available as RS-232:
>  J15.1 UART2 TX out
>  J15.2 UART2 RX in
>  J15.3 UART4 TX out
>  J15.4 UART4 RX in
>  J15.5 GND
>
> Add dt overlays to allow additional the modes of operation:
>
> rs232-rts (UART2 RS-232 with RTS/CTS hardware flow control)
>  J15.1 TX out
>  J15.2 RX in
>  J15.3 RTS out
>  J15.4 CTS in
>  J15.5 GND
>
> rs485 (UART2 RS-485 half duplex)
>  J15.1 TXRX-
>  J15.2 N/C
>  J15.3 TXRX+
>  J15.4 N/C
>  J15.5 GND
>
> rs422 (UART2 RS-422 full duplex)
>  J15.1 TX-
>  J15.2 RX+
>  J15.3 TX+
>  J15.4 RX-
>  J15.5 GND
>
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |  3 +
>  .../imx8mm-venice-gw73xx-0x-rs232-rts.dts     | 53 ++++++++++++++++
>  .../imx8mm-venice-gw73xx-0x-rs422.dts         | 61 +++++++++++++++++++
>  .../imx8mm-venice-gw73xx-0x-rs485.dts         | 61 +++++++++++++++++++
>  4 files changed, 178 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
>
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index a14a6173b765..5ec8d59347b6 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
> +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
> +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
>  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
> new file mode 100644
> index 000000000000..c184cf4aea4e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021 Gateworks Corporation
> + *
> + * GW73xx RS232 with RTS/CTS hardware flow control:
> + *  - GPIO4_0 rs485_en needs to be driven low (in-active)
> + *  - UART4_TX becomes RTS
> + *  - UART4_RX becomes CTS
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +
> +#include "imx8mm-pinfunc.h"
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +       compatible = "gw,imx8mm-gw73xx-0x";
> +};
> +
> +&gpio4 {
> +       rs485_en {
> +               gpio-hog;
> +               gpios = <0 GPIO_ACTIVE_HIGH>;
> +               output-low;
> +               line-name = "rs485_en";
> +       };
> +};
> +
> +&uart2 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_uart2>;
> +       rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
> +       cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
> +       uart-has-rtscts;
> +       status = "okay";
> +};
> +
> +&uart4 {
> +       status = "disabled";
> +};
> +
> +&iomuxc {
> +       pinctrl_uart2: uart2grp {
> +               fsl,pins = <
> +                       MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
> +                       MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
> +                       MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29       0x140
> +                       MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28       0x140
> +               >;
> +       };
> +};
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
> new file mode 100644
> index 000000000000..3e6404340d52
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021 Gateworks Corporation
> + *
> + * GW73xx RS422 (RS485 full duplex):
> + *  - GPIO1_0 rs485_term selects on-chip termination
> + *  - GPIO4_0 rs485_en needs to be driven high (active)
> + *  - GPIO4_2 rs485_hd needs to be driven low (in-active)
> + *  - UART4_TX is DE for RS485 transmitter
> + *  - RS485_EN needs to be pulled high
> + *  - RS485_HALF needs to be low
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +
> +#include "imx8mm-pinfunc.h"
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +       compatible = "gw,imx8mm-gw73xx-0x";
> +};
> +
> +&gpio4 {
> +       rs485_en {
> +               gpio-hog;
> +               gpios = <0 GPIO_ACTIVE_HIGH>;
> +               output-high;
> +               line-name = "rs485_en";
> +       };
> +
> +       rs485_hd {
> +               gpio-hog;
> +               gpios = <2 GPIO_ACTIVE_HIGH>;
> +               output-low;
> +               line-name = "rs485_hd";
> +       };
> +};
> +
> +&uart2 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_uart2>;
> +       rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
> +       linux,rs485-enabled-at-boot-time;
> +       status = "okay";
> +};
> +
> +&uart4 {
> +       status = "disabled";
> +};
> +
> +&iomuxc {
> +       pinctrl_uart2: uart2grp {
> +               fsl,pins = <
> +                       MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
> +                       MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
> +                       MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29       0x140
> +               >;
> +       };
> +};
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> new file mode 100644
> index 000000000000..97f19c15c3d0
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021 Gateworks Corporation
> + *
> + * GW73xx RS485 HD:
> + *  - GPIO1_0 rs485_term selects on-chip termination
> + *  - GPIO4_0 rs485_en needs to be driven high (active)
> + *  - GPIO4_2 rs485_hd needs to be driven high (active)
> + *  - UART4_TX is DE for RS485 transmitter
> + *  - RS485_EN needs to be pulled high
> + *  - RS485_HALF needs to be pulled high
> + */
> +
> +#include <dt-bindings/gpio/gpio.h>
> +
> +#include "imx8mm-pinfunc.h"
> +
> +/dts-v1/;
> +/plugin/;
> +
> +&{/} {
> +       compatible = "gw,imx8mm-gw73xx-0x";
> +};
> +
> +&gpio4 {
> +       rs485_en {
> +               gpio-hog;
> +               gpios = <0 GPIO_ACTIVE_HIGH>;
> +               output-high;
> +               line-name = "rs485_en";
> +       };
> +
> +       rs485_hd {
> +               gpio-hog;
> +               gpios = <2 GPIO_ACTIVE_HIGH>;
> +               output-high;
> +               line-name = "rs485_hd";
> +       };
> +};
> +
> +&uart2 {
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_uart2>;
> +       rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
> +       linux,rs485-enabled-at-boot-time;
> +       status = "okay";
> +};
> +
> +&uart4 {
> +       status = "disabled";
> +};
> +
> +&iomuxc {
> +       pinctrl_uart2: uast2grp {
> +               fsl,pins = <
> +                       MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
> +                       MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
> +                       MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29       0x140
> +               >;
> +       };
> +};
> --
> 2.17.1
>

gentle ping.

I'm mostly interested to see if my approach to dt fragments here and
the naming of the files makes sense to others.

This patch causes the kernel to build dtbo files for:
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dtbo
arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dtbo

The intention is that these files are used by boot firmware (U-Boot)
to adjust the dtb before passing it to the kernel.

Best regards,

Tim


From reijiw at google.com  Mon Jan 10 16:03:41 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 10 Jan 2022 16:03:41 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
Message-ID: <CAAeT=FwfjUiaWAJHCEqTCyu9PRr+JEKx1v0P-CJ=2-yGBvaGbA@mail.gmail.com>

On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Hi Raghu,
> >
> > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > Capture the start of the KVM VM, which is basically the
> > > start of any vCPU run. This state of the VM is helpful
> > > in the upcoming patches to prevent user-space from
> > > configuring certain VM features after the VM has started
> > > running.
> > >
> > > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > > ---
> > >  include/linux/kvm_host.h | 3 +++
> > >  virt/kvm/kvm_main.c      | 9 +++++++++
> > >  2 files changed, 12 insertions(+)
> > >
> > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > > index c310648cc8f1..d0bd8f7a026c 100644
> > > --- a/include/linux/kvm_host.h
> > > +++ b/include/linux/kvm_host.h
> > > @@ -623,6 +623,7 @@ struct kvm {
> > >         struct notifier_block pm_notifier;
> > >  #endif
> > >         char stats_id[KVM_STATS_NAME_SIZE];
> > > +       bool vm_started;
> >
> > Since KVM_RUN on any vCPUs doesn't necessarily mean that the VM
> > started yet, the name might be a bit misleading IMHO.  I would
> > think 'has_run_once' or 'ran_once' might be more clear (?).
> >
> I always struggle with the names; but if you feel that 'ran_once'
> makes more sense for a reader, I can change it.

I would prefer 'ran_once'.


> > >  };
> > >
> > >  #define kvm_err(fmt, ...) \
> > > @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> > >         }
> > >  }
> > >
> > > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> > > +
> > >  extern bool kvm_rebooting;
> > >
> > >  extern unsigned int halt_poll_ns;
> > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > > index 72c4e6b39389..962b91ac2064 100644
> > > --- a/virt/kvm/kvm_main.c
> > > +++ b/virt/kvm/kvm_main.c
> > > @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
> > >         int r;
> > >         struct kvm_fpu *fpu = NULL;
> > >         struct kvm_sregs *kvm_sregs = NULL;
> > > +       struct kvm *kvm = vcpu->kvm;
> > >
> > >         if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
> > >                 return -EIO;
> > > @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
> > >                         if (oldpid)
> > >                                 synchronize_rcu();
> > >                         put_pid(oldpid);
> > > +
> > > +                       /*
> > > +                        * Since we land here even on the first vCPU run,
> > > +                        * we can mark that the VM has started running.
> > > +                        */
> >
> > It might be nicer to add a comment why the code below gets kvm->lock.
> >
> I've been going back and forth on this one. Initially I considered
> simply going with atomic_t, but the patch 4/11 (KVM: arm64: Setup a
> framework for hypercall bitmap firmware registers)
> kvm_arm_set_fw_reg_bmap()'s implementation felt like we need a lock to
> have the whole 'is the register busy?' operation atomic. But, that's
> just one of the applications.

I understand why you need the code to get the lock here with the
current implementation.
But, since the code just set the one field (vm_started) with the lock,
I thought the intention of getting the lock might not be so obvious.
(But, maybe clear enough looking at the code in the patch-4)

Thanks,
Reiji


> > Anyway, the patch generally looks good to me, and thank you
> > for making this change (it works for my purpose as well).
> >
> > Reviewed-by: Reiji Watanabe <reijiw at google.com>
> >
> Glad that it's helping you as well and thanks for the review.
>
> Regards,
> Raghavendra
>
> > Thanks,
> > Reiji
> >
> >
> > > +                       mutex_lock(&kvm->lock);
> > > +                       kvm->vm_started = true;
> > > +                       mutex_unlock(&kvm->lock);
> > >                 }
> > >                 r = kvm_arch_vcpu_ioctl_run(vcpu);
> > >                 trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> > > --
> > > 2.34.1.448.ga2b2bfdf31-goog
> > >


From lkp at intel.com  Mon Jan 10 16:06:03 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 08:06:03 +0800
Subject: [v1 06/16] clk: mediatek: Add MT8186 apmixedsys clock support
In-Reply-To: <20220110134416.5191-7-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-7-chun-jie.chen@mediatek.com>
Message-ID: <202201110701.jdDbg8yY-lkp@intel.com>

Hi Chun-Jie,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on clk/clk-next]
[also build test ERROR on robh/for-next v5.16 next-20220110]
[cannot apply to mbgg-mediatek/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: nios2-allyesconfig (https://download.01.org/0day-ci/archive/20220111/202201110701.jdDbg8yY-lkp at intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/2b9fcab7333544a52a4e5fd9e42764e1f1e7a7b1
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Chun-Jie-Chen/dt-bindings-ARM-Mediatek-Add-new-document-bindings-of-MT8186-clock/20220110-224451
        git checkout 2b9fcab7333544a52a4e5fd9e42764e1f1e7a7b1
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/mediatek/clk-mt8186-apmixedsys.c: In function 'clk_mt8186_apmixed_probe':
>> drivers/clk/mediatek/clk-mt8186-apmixedsys.c:102:9: error: implicit declaration of function 'mtk_clk_unregister'; did you mean 'devm_clk_unregister'? [-Werror=implicit-function-declaration]
     102 |         mtk_clk_unregister(clk_data);
         |         ^~~~~~~~~~~~~~~~~~
         |         devm_clk_unregister
   cc1: some warnings being treated as errors


vim +102 drivers/clk/mediatek/clk-mt8186-apmixedsys.c

    82	
    83	static int clk_mt8186_apmixed_probe(struct platform_device *pdev)
    84	{
    85		struct clk_onecell_data *clk_data;
    86		struct device_node *node = pdev->dev.of_node;
    87		int r;
    88	
    89		clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
    90		if (!clk_data)
    91			return -ENOMEM;
    92	
    93		mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
    94	
    95		r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
    96		if (r)
    97			goto unregister_clk;
    98	
    99		return r;
   100	
   101	unregister_clk:
 > 102		mtk_clk_unregister(clk_data);
   103		mtk_free_clk_data(clk_data);
   104		return r;
   105	}
   106	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mr.bossman075 at gmail.com  Mon Jan 10 16:18:58 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Mon, 10 Jan 2022 19:18:58 -0500
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <Ydy3qvT5w6IWnR7s@abelvesa>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
 <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
 <20220110201201.C1E37C36AE9@smtp.kernel.org> <Ydy3qvT5w6IWnR7s@abelvesa>
Message-ID: <baa991a5-31d8-80fb-faf0-b443626030d4@gmail.com>



On 1/10/22 17:48, Abel Vesa wrote:
> On 22-01-10 12:12:00, Stephen Boyd wrote:
>> Quoting Jesse Taube (2022-01-09 11:07:42)
>>>>> +
>>>>> +       clk_hw_data->num = IMXRT1050_CLK_END;
>>>>> +       hws = clk_hw_data->hws;
>>>>> +
>>>>> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
>>>>
>>>> Use clk_parent_data instead and reference the binding name with .fw_name
>>>
>>> Hi Stephen, sorry to bother you again.
>>> I'm wondering if adding `clk_parent_data` is necessary as it seems like
>>> it wold be a big change and the other IMX boards haven't implemented
>>> this yet would it be okay if I don't do this, or if it is necessary
>>> could you link to a patch set to change it.
>>>
>>
>> Is it a big change because the imx_clk_hw*() APIs aren't prepared for
>> non-string parents? Can you make some clk_parent_data based APIs and
>> migrate things over gradually? This is really a question for i.MX folks
>> to see if anyone is working on moving away from the string names.
> 
> I'm currently looking into it. I would suggest we take this patch as is
> and I'll switch it later on to clk_parent_data.
Thanks so much that would be great!

Should I sent the other changes requested I have them ready? Or should i 
wait.

Best regards
	Jesse Taube


From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:05 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:05 +0000
Subject: [PATCH v2 04/13] media: s5p-mfc: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-5-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
---
v1->v2
* Included RB tag
---
 drivers/media/platform/s5p-mfc/s5p_mfc.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index f6732f031e96..761341934925 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -1268,7 +1268,6 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 {
 	struct s5p_mfc_dev *dev;
 	struct video_device *vfd;
-	struct resource *res;
 	int ret;
 
 	pr_debug("%s++\n", __func__);
@@ -1294,12 +1293,10 @@ static int s5p_mfc_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->regs_base))
 		return PTR_ERR(dev->regs_base);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to get irq resource\n");
-		return -ENOENT;
-	}
-	dev->irq = res->start;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		return ret;
+	dev->irq = ret;
 	ret = devm_request_irq(&pdev->dev, dev->irq, s5p_mfc_irq,
 					0, pdev->name, dev);
 	if (ret) {
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:06 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:06 +0000
Subject: [PATCH v2 05/13] media: stm32-dma2d: Use platform_get_irq() to get
 the interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-6-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/stm32/dma2d/dma2d.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/stm32/dma2d/dma2d.c b/drivers/media/platform/stm32/dma2d/dma2d.c
index 17af90d86898..9706aa41b5d2 100644
--- a/drivers/media/platform/stm32/dma2d/dma2d.c
+++ b/drivers/media/platform/stm32/dma2d/dma2d.c
@@ -633,14 +633,11 @@ static int dma2d_probe(struct platform_device *pdev)
 		goto put_clk_gate;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to find IRQ\n");
-		ret = -ENXIO;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto unprep_clk_gate;
-	}
 
-	dev->irq = res->start;
+	dev->irq = ret;
 
 	ret = devm_request_irq(&pdev->dev, dev->irq, dma2d_isr,
 			       0, pdev->name, dev);
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:08 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:08 +0000
Subject: [PATCH v2 07/13] media: exynos-gsc: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-8-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/exynos-gsc/gsc-core.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c
index cfd6ae70b8d8..e3559b047092 100644
--- a/drivers/media/platform/exynos-gsc/gsc-core.c
+++ b/drivers/media/platform/exynos-gsc/gsc-core.c
@@ -1106,9 +1106,9 @@ MODULE_DEVICE_TABLE(of, exynos_gsc_match);
 static int gsc_probe(struct platform_device *pdev)
 {
 	struct gsc_dev *gsc;
-	struct resource *res;
 	struct device *dev = &pdev->dev;
 	const struct gsc_driverdata *drv_data = of_device_get_match_data(dev);
+	int irq;
 	int ret;
 	int i;
 
@@ -1141,11 +1141,9 @@ static int gsc_probe(struct platform_device *pdev)
 	if (IS_ERR(gsc->regs))
 		return PTR_ERR(gsc->regs);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev, "failed to get IRQ resource\n");
-		return -ENXIO;
-	}
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	for (i = 0; i < gsc->num_clocks; i++) {
 		gsc->clock[i] = devm_clk_get(dev, drv_data->clk_names[i]);
@@ -1167,8 +1165,8 @@ static int gsc_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = devm_request_irq(dev, res->start, gsc_irq_handler,
-				0, pdev->name, gsc);
+	ret = devm_request_irq(dev, irq, gsc_irq_handler,
+			       0, pdev->name, gsc);
 	if (ret) {
 		dev_err(dev, "failed to install irq (%d)\n", ret);
 		goto err_clk;
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:10 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:10 +0000
Subject: [PATCH v2 09/13] media: mtk-vcodec: Drop unnecessary call to
 platform_get_resource()
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-10-prabhakar.mahadev-lad.rj@bp.renesas.com>

mtk_vcodec_probe() calls platform_get_resource(pdev, IORESOURCE_IRQ, ..)
to check if IRQ resource exists and later calls platform_get_irq(pdev, ..)
to get the actual IRQ.

This patch drops an unnecessary call to platform_get_resource() and
checks the return value of platform_get_irq(pdev, ..) to check if the
IRQ line is valid.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c    | 11 ++++-------
 .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c    | 10 +++-------
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 40c39e1e596b..1509c2a4de84 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -200,7 +200,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_dec;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int i, ret;
@@ -244,14 +243,12 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto err_res;
-	}
 
-	dev->dec_irq = platform_get_irq(pdev, 0);
+	dev->dec_irq = ret;
+
 	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
 	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
 			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index aeaecb8d416e..86e70d826754 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -236,7 +236,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_enc;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
@@ -280,14 +279,11 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_res;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto err_res;
-	}
 
-	dev->enc_irq = platform_get_irq(pdev, 0);
+	dev->enc_irq = ret;
 	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
 	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
 			       mtk_vcodec_enc_irq_handler,
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:11 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:11 +0000
Subject: [PATCH v2 10/13] media: exynos4-is: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-11-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/exynos4-is/fimc-core.c | 11 +++++------
 drivers/media/platform/exynos4-is/fimc-lite.c | 11 +++++------
 2 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c
index bfdee771cef9..91cc8d58a663 100644
--- a/drivers/media/platform/exynos4-is/fimc-core.c
+++ b/drivers/media/platform/exynos4-is/fimc-core.c
@@ -926,6 +926,7 @@ static int fimc_probe(struct platform_device *pdev)
 	struct fimc_dev *fimc;
 	struct resource *res;
 	int ret = 0;
+	int irq;
 
 	fimc = devm_kzalloc(dev, sizeof(*fimc), GFP_KERNEL);
 	if (!fimc)
@@ -965,11 +966,9 @@ static int fimc_probe(struct platform_device *pdev)
 	if (IS_ERR(fimc->regs))
 		return PTR_ERR(fimc->regs);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(dev, "Failed to get IRQ resource\n");
-		return -ENXIO;
-	}
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	ret = fimc_clk_get(fimc);
 	if (ret)
@@ -986,7 +985,7 @@ static int fimc_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
-	ret = devm_request_irq(dev, res->start, fimc_irq_handler,
+	ret = devm_request_irq(dev, irq, fimc_irq_handler,
 			       0, dev_name(dev), fimc);
 	if (ret < 0) {
 		dev_err(dev, "failed to install irq (%d)\n", ret);
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index aaa3af0493ce..9b7cc9564cf1 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -1454,6 +1454,7 @@ static int fimc_lite_probe(struct platform_device *pdev)
 	struct fimc_lite *fimc;
 	struct resource *res;
 	int ret;
+	int irq;
 
 	if (!dev->of_node)
 		return -ENODEV;
@@ -1485,17 +1486,15 @@ static int fimc_lite_probe(struct platform_device *pdev)
 	if (IS_ERR(fimc->regs))
 		return PTR_ERR(fimc->regs);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(dev, "Failed to get IRQ resource\n");
-		return -ENXIO;
-	}
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	ret = fimc_lite_clk_get(fimc);
 	if (ret)
 		return ret;
 
-	ret = devm_request_irq(dev, res->start, flite_irq_handler,
+	ret = devm_request_irq(dev, irq, flite_irq_handler,
 			       0, dev_name(dev), fimc);
 	if (ret) {
 		dev_err(dev, "Failed to install irq (%d)\n", ret);
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:12 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:12 +0000
Subject: [PATCH v2 11/13] media: s5p-g2d: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-12-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/s5p-g2d/g2d.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
index fa0bb31bd2b9..dd8864779a7c 100644
--- a/drivers/media/platform/s5p-g2d/g2d.c
+++ b/drivers/media/platform/s5p-g2d/g2d.c
@@ -623,7 +623,6 @@ static int g2d_probe(struct platform_device *pdev)
 {
 	struct g2d_dev *dev;
 	struct video_device *vfd;
-	struct resource *res;
 	const struct of_device_id *of_id;
 	int ret = 0;
 
@@ -664,14 +663,11 @@ static int g2d_probe(struct platform_device *pdev)
 		goto put_clk_gate;
 	}
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "failed to find IRQ\n");
-		ret = -ENXIO;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto unprep_clk_gate;
-	}
 
-	dev->irq = res->start;
+	dev->irq = ret;
 
 	ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
 						0, pdev->name, dev);
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:13 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:13 +0000
Subject: [PATCH v2 12/13] media: mtk-vpu: Drop unnecessary call to
 platform_get_resource()
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-13-prabhakar.mahadev-lad.rj@bp.renesas.com>

mtk_vpu_probe() calls platform_get_resource(pdev, IORESOURCE_IRQ, ..)
to check if IRQ resource exists and later calls
platform_get_irq(pdev, ..) to get the actual IRQ.

This patch drops an unnecessary call to platform_get_resource() and
checks the return value of platform_get_irq(pdev, ..) to make sure the
IRQ line is valid.

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/mtk-vpu/mtk_vpu.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/mtk-vpu/mtk_vpu.c b/drivers/media/platform/mtk-vpu/mtk_vpu.c
index 7bd715fc844d..47b684b92f81 100644
--- a/drivers/media/platform/mtk-vpu/mtk_vpu.c
+++ b/drivers/media/platform/mtk-vpu/mtk_vpu.c
@@ -810,7 +810,6 @@ static int mtk_vpu_probe(struct platform_device *pdev)
 {
 	struct mtk_vpu *vpu;
 	struct device *dev;
-	struct resource *res;
 	int ret = 0;
 
 	dev_dbg(&pdev->dev, "initialization\n");
@@ -908,13 +907,10 @@ static int mtk_vpu_probe(struct platform_device *pdev)
 	init_waitqueue_head(&vpu->run.wq);
 	init_waitqueue_head(&vpu->ack_wq);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(dev, "get IRQ resource failed.\n");
-		ret = -ENXIO;
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
 		goto free_p_mem;
-	}
-	vpu->reg.irq = platform_get_irq(pdev, 0);
+	vpu->reg.irq = ret;
 	ret = devm_request_irq(dev, vpu->reg.irq, vpu_irq_handler, 0,
 			       pdev->name, vpu);
 	if (ret) {
-- 
2.17.1



From prabhakar.mahadev-lad.rj at bp.renesas.com  Mon Jan 10 16:23:14 2022
From: prabhakar.mahadev-lad.rj at bp.renesas.com (Lad Prabhakar)
Date: Tue, 11 Jan 2022 00:23:14 +0000
Subject: [PATCH v2 13/13] media: coda: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <20220111002314.15213-14-prabhakar.mahadev-lad.rj@bp.renesas.com>

platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
allocation of IRQ resources in DT core code, this causes an issue
when using hierarchical interrupt domains using "interrupts" property
in the node as this bypasses the hierarchical setup and messes up the
irq chaining.

In preparation for removal of static setup of IRQ resource from DT core
code use platform_get_irq().

Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
---
v1->v2
* No change.
---
 drivers/media/platform/coda/imx-vdoa.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c
index 00643f37b3e6..c70871bae193 100644
--- a/drivers/media/platform/coda/imx-vdoa.c
+++ b/drivers/media/platform/coda/imx-vdoa.c
@@ -284,7 +284,6 @@ EXPORT_SYMBOL(vdoa_context_configure);
 static int vdoa_probe(struct platform_device *pdev)
 {
 	struct vdoa_data *vdoa;
-	struct resource *res;
 	int ret;
 
 	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
@@ -309,10 +308,10 @@ static int vdoa_probe(struct platform_device *pdev)
 	if (IS_ERR(vdoa->regs))
 		return PTR_ERR(vdoa->regs);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res)
-		return -EINVAL;
-	ret = devm_request_threaded_irq(&pdev->dev, res->start, NULL,
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		return ret;
+	ret = devm_request_threaded_irq(&pdev->dev, ret, NULL,
 					vdoa_irq_handler, IRQF_ONESHOT,
 					"vdoa", vdoa);
 	if (ret < 0) {
-- 
2.17.1



From nobuhiro1.iwamatsu at toshiba.co.jp  Mon Jan 10 16:38:29 2022
From: nobuhiro1.iwamatsu at toshiba.co.jp (nobuhiro1.iwamatsu at toshiba.co.jp)
Date: Tue, 11 Jan 2022 00:38:29 +0000
Subject: [PATCH] clk: visconti: Remove pointless NULL check in
 visconti_pll_add_lookup()
In-Reply-To: <20220107183303.2337676-1-nathan@kernel.org>
References: <20220107183303.2337676-1-nathan@kernel.org>
Message-ID: <TYAPR01MB6252818ED275BCE2035C52E292519@TYAPR01MB6252.jpnprd01.prod.outlook.com>

Hi Nathan,

Thanks for your patch.

> -----Original Message-----
> From: Nathan Chancellor <nathan at kernel.org>
> Sent: Saturday, January 8, 2022 3:33 AM
> To: Michael Turquette <mturquette at baylibre.com>; Stephen Boyd
> <sboyd at kernel.org>; iwamatsu nobuhiro(?? ?? ????????)
> <nobuhiro1.iwamatsu at toshiba.co.jp>
> Cc: Nick Desaulniers <ndesaulniers at google.com>; linux-clk at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> llvm at lists.linux.dev; Nathan Chancellor <nathan at kernel.org>; kernel test
> robot <lkp at intel.com>
> Subject: [PATCH] clk: visconti: Remove pointless NULL check in
> visconti_pll_add_lookup()
> 
> Clang warns:
> 
> drivers/clk/visconti/pll.c:292:20: warning: address of array 'ctx->clk_data.hws'
> will always evaluate to 'true' [-Wpointer-bool-conversion]
>         if (ctx->clk_data.hws && id)
>             ~~~~~~~~~~~~~~^~~ ~~
> 1 warning generated.
> 
> This array cannot be NULL if ctx is not NULL, which is allocated in
> visconti_init_pll(), so just remove the check, which matches other clk drivers.
> 
> Fixes: b4cbe606dc36 ("clk: visconti: Add support common clock driver and
> reset driver")
> Link: https://github.com/ClangBuiltLinux/linux/issues/1564
> Reported-by: kernel test robot <lkp at intel.com>
> Signed-off-by: Nathan Chancellor <nathan at kernel.org>
> ---
>  drivers/clk/visconti/pll.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>

Best regards,
  Nobuhiro




From acme at kernel.org  Mon Jan 10 16:41:12 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 21:41:12 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <CAP-5=fVAa3JVbdzNZg0LrVfw__9U9Q8PkHcro+TJiFVyvTho+A@mail.gmail.com>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
 <Ydyjvcma/wMTPwbn@kernel.org> <Ydymdm/PoB0hQVUT@kernel.org>
 <CAP-5=fVAa3JVbdzNZg0LrVfw__9U9Q8PkHcro+TJiFVyvTho+A@mail.gmail.com>
Message-ID: <YdzSKOWJRC0dRnSn@kernel.org>

Em Mon, Jan 10, 2022 at 02:29:58PM -0800, Ian Rogers escreveu:
> On Mon, Jan 10, 2022 at 1:34 PM Arnaldo Carvalho de Melo
> <acme at kernel.org> wrote:
> >
> > Em Mon, Jan 10, 2022 at 06:23:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > At this point we need to remove the now unused perf_env__get_cpu(), and
> > > > > then deal with the fallout in the following patches that needlessly
> > > > > modify this unused function.
> > > > >
> > > > > Doing that now.
> > > >
> > > > Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> > > > build containers, a better start now:
> >
> > > So far so good:
> >
> > perf test ok, just that one that is failing, but before this series as
> > well:
> >
> >  89: perf all metricgroups test                                      : FAILED!
> 
> Could you add the verbose output? I suspect it is fixed by this:
> https://lore.kernel.org/lkml/20211223183948.3423989-1-irogers at google.com/

I'll try it.

BTW, here are the final tests, problems with arm 32 and 64-bit, I'll go thru
them tomorrow, to fix in the cset the problem appears, so that we keep it
bisectable, else you can get what I have in tmp.perf/perf_cpu, fix it and
tomorrow I'll retest.

  27    85.67 debian:11                     : Ok   gcc (Debian 10.2.1-6) 10.2.1 20210110 , Debian clang version 11.0.1-2
  28    98.65 debian:experimental           : Ok   gcc (Debian 11.2.0-13) 11.2.0 , Debian clang version 13.0.0-9+b2
  29     8.69 debian:experimental-x-arm64   : FAIL gcc version 11.2.0 (Debian 11.2.0-9)
    arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
    arch/arm64/util/pmu.c:18:35: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
       18 |                 if (pmu->cpus->nr != cpu__max_cpu())
          |                     ~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~
          |                              |       |
          |                              int     struct perf_cpu
    make[5]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: util] Error 2
    make[4]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arm64] Error 2
    make[3]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arch] Error 2
  30    19.15 debian:experimental-x-mips    : Ok   mips-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110
  31    21.25 debian:experimental-x-mips64  : Ok   mips64-linux-gnuabi64-gcc (Debian 10.2.1-6) 10.2.1 20210110
  32    22.45 debian:experimental-x-mipsel  : Ok   mipsel-linux-gnu-gcc (Debian 11.2.0-9) 11.2.0
  33    21.86 fedora:22                     : Ok   gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) , clang version 3.5.0 (tags/RELEASE_350/final)
  34    55.88 fedora:23                     : Ok   gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) , clang version 3.7.0 (tags/RELEASE_370/final)
  35    67.12 fedora:24                     : Ok   gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) , clang version 3.8.1 (tags/RELEASE_381/final)
  36    17.53 fedora:24-x-ARC-uClibc        : Ok   arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710
  37    68.11 fedora:25                     : Ok   gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) , clang version 3.9.1 (tags/RELEASE_391/final)
  38    80.15 fedora:26                     : Ok   gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2) , clang version 4.0.1 (tags/RELEASE_401/final)
  39    80.54 fedora:27                     : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6) , clang version 5.0.2 (tags/RELEASE_502/final)
  40    91.48 fedora:28                     : Ok   gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2) , clang version 6.0.1 (tags/RELEASE_601/final)
  41    96.71 fedora:29                     : Ok   gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2) , clang version 7.0.1 (Fedora 7.0.1-6.fc29)
  42   100.71 fedora:30                     : Ok   gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) , clang version 8.0.0 (Fedora 8.0.0-3.fc30)
  43    94.09 fedora:31                     : Ok   gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) , clang version 9.0.1 (Fedora 9.0.1-4.fc31)
  44    87.49 fedora:32                     : Ok   gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) , clang version 10.0.1 (Fedora 10.0.1-3.fc32)
  45    85.99 fedora:33                     : Ok   gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) , clang version 11.0.0 (Fedora 11.0.0-3.fc33)
  46    88.89 fedora:34                     : Ok   gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) , clang version 12.0.1 (Fedora 12.0.1-1.fc34)
  47    19.84 fedora:34-x-ARC-glibc         : Ok   arc-linux-gcc (ARC HS GNU/Linux glibc toolchain 2019.03-rc1) 8.3.1 20190225
  48    17.93 fedora:34-x-ARC-uClibc        : Ok   arc-linux-gcc (ARCv2 ISA Linux uClibc toolchain 2019.03-rc1) 8.3.1 20190225
  49    91.33 fedora:35                     : Ok   gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7) , clang version 13.0.0 (Fedora 13.0.0-3.fc35)
  50    99.83 fedora:rawhide                : Ok   gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7) , clang version 13.0.0 (Fedora 13.0.0-5.fc36)
  51    79.16 gentoo-stage3:latest          : Ok   gcc (Gentoo 11.2.0 p1) 11.2.0 , clang version 13.0.0
  52    68.81 mageia:6                      : Ok   gcc (Mageia 5.5.0-1.mga6) 5.5.0 , clang version 3.9.1 (tags/RELEASE_391/final)
  53    38.50 mageia:7                      : FAIL clang version 8.0.0 (Mageia 8.0.0-1.mga7)
          yychar = yylex (&yylval, &yylloc, scanner);
                   ^
    #define yylex           parse_events_lex
                            ^
    1 error generated.
    make[3]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: util] Error 2
  54    89.20 manjaro:base                  : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
  55     6.18 openmandriva:cooker           : FAIL gcc version 11.2.0 20210728 (OpenMandriva) (GCC)
    In file included from builtin-bench.c:22:
    bench/bench.h:66:19: error: conflicting types for 'pthread_attr_setaffinity_np'; have 'int(pthread_attr_t *, size_t,  cpu_set_t *)' {aka 'int(pthread_attr_t *, long unsigned int,  cpu_set_t *)'}
       66 | static inline int pthread_attr_setaffinity_np(pthread_attr_t *attr __maybe_unused,
          |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
    In file included from bench/bench.h:64,
                     from builtin-bench.c:22:
    /usr/include/pthread.h:394:12: note: previous declaration of 'pthread_attr_setaffinity_np' with type 'int(pthread_attr_t *, size_t,  const cpu_set_t *)' {aka 'int(pthread_attr_t *, long unsigned int,  const cpu_set_t *)'}
      394 | extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
          |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
    ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
    ld: warning: -r and --icf may not be used together, disabling --icf
    ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
    ld: warning: -r and --icf may not be used together, disabling --icf
    ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
    ld: warning: -r and --icf may not be used together, disabling --icf
  56   100.50 opensuse:15.0                 : Ok   gcc (SUSE Linux) 7.4.1 20190905 [gcc-7-branch revision 275407] , clang version 5.0.1 (tags/RELEASE_501/final 312548)
  57   107.92 opensuse:15.1                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 7.0.1 (tags/RELEASE_701/final 349238)
  58   102.71 opensuse:15.2                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 9.0.1
  59   113.86 opensuse:15.3                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 11.0.1
  60   114.75 opensuse:15.4                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 11.0.1
  61   129.42 opensuse:tumbleweed           : Ok   gcc (SUSE Linux) 11.2.1 20211124 [revision 7510c23c1ec53aa4a62705f0384079661342ff7b] , clang version 13.0.0
  62    94.32 oraclelinux:8                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4.0.1) , clang version 12.0.1 (Red Hat 12.0.1-4.0.1.module+el8.5.0+20428+2b4ecd47)
  63    94.81 rockylinux:8                  : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module+el8.5.0+715+58f51d49)
  64    71.11 ubuntu:16.04                  : Ok   gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609 , clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
  65     6.89 ubuntu:16.04-x-arm            : FAIL gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)
    arch/arm/util/cs-etm.c: In function 'cs_etm_set_option':
    arch/arm/util/cs-etm.c:206:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
      for (i = 0; i < cpu__max_cpu(); i++) {
                    ^
    arch/arm/util/cs-etm.c:207:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
       if (!perf_cpu_map__has(event_cpus, i) ||
                                          ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c:208:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
           !perf_cpu_map__has(online_cpus, i))
                                           ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c: In function 'cs_etm_info_priv_size':
    arch/arm/util/cs-etm.c:525:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
       for (i = 0; i < cpu__max_cpu(); i++) {
                     ^
    arch/arm/util/cs-etm.c:526:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (!perf_cpu_map__has(event_cpus, i) ||
                                           ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c:527:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
            !perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c:539:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
       for (i = 0; i < cpu__max_cpu(); i++) {
                     ^
    arch/arm/util/cs-etm.c:540:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (!perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c: In function 'cs_etm_info_fill':
    arch/arm/util/cs-etm.c:725:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (perf_cpu_map__has(event_cpus, i) &&
                                          ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c:726:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
            !perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    arch/arm/util/cs-etm.c:746:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
      for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
                    ^
    arch/arm/util/cs-etm.c:747:34: error: incompatible type for argument 2 of 'perf_cpu_map__has'
       if (perf_cpu_map__has(cpu_map, i))
                                      ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
    make[5]: *** [util] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm' failed
    make[4]: *** [arm] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
    make[3]: *** [arch] Error 2
  66     6.99 ubuntu:16.04-x-arm64          : FAIL gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)
    arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
    arch/arm64/util/pmu.c:18:21: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
       if (pmu->cpus->nr != cpu__max_cpu())
                         ^
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
    make[5]: *** [util] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm64' failed
    make[4]: *** [arm64] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
    make[3]: *** [arch] Error 2
  67    18.54 ubuntu:16.04-x-powerpc        : Ok   powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
  68    19.04 ubuntu:16.04-x-powerpc64      : Ok   powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
  69    18.93 ubuntu:16.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
  70    19.04 ubuntu:16.04-x-s390           : Ok   s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
  71    76.32 ubuntu:18.04                  : Ok   gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 , clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
  72     7.49 ubuntu:18.04-x-arm            : FAIL gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)
    arch/arm/util/cs-etm.c: In function 'cs_etm_set_option':
    arch/arm/util/cs-etm.c:206:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
      for (i = 0; i < cpu__max_cpu(); i++) {
                    ^ ~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:207:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
       if (!perf_cpu_map__has(event_cpus, i) ||
                                          ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:208:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
           !perf_cpu_map__has(online_cpus, i))
                                           ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c: In function 'cs_etm_info_priv_size':
    arch/arm/util/cs-etm.c:525:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
       for (i = 0; i < cpu__max_cpu(); i++) {
                     ^ ~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:526:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (!perf_cpu_map__has(event_cpus, i) ||
                                           ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:527:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
            !perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:539:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
       for (i = 0; i < cpu__max_cpu(); i++) {
                     ^ ~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:540:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (!perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c: In function 'cs_etm_info_fill':
    arch/arm/util/cs-etm.c:725:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
        if (perf_cpu_map__has(event_cpus, i) &&
                                          ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:726:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
            !perf_cpu_map__has(online_cpus, i))
                                            ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:746:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
      for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
                    ^ ~~~~~~~~~~~~~~
    arch/arm/util/cs-etm.c:747:34: error: incompatible type for argument 2 of 'perf_cpu_map__has'
       if (perf_cpu_map__has(cpu_map, i))
                                      ^
    In file included from arch/arm/util/../../../util/cpumap.h:8:0,
                     from arch/arm/util/cs-etm.c:22:
    /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
     LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
                      ^~~~~~~~~~~~~~~~~
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
    make[5]: *** [util] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm' failed
    make[4]: *** [arm] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
    make[3]: *** [arch] Error 2
  73     7.49 ubuntu:18.04-x-arm64          : FAIL gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)
    arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
    arch/arm64/util/pmu.c:18:21: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
       if (pmu->cpus->nr != cpu__max_cpu())
           ~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
    make[5]: *** [util] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm64' failed
    make[4]: *** [arm64] Error 2
    /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
    make[3]: *** [arch] Error 2
  74    16.73 ubuntu:18.04-x-m68k           : Ok   m68k-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  75    19.94 ubuntu:18.04-x-powerpc        : Ok   powerpc-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  76    21.35 ubuntu:18.04-x-powerpc64      : Ok   powerpc64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  77    21.55 ubuntu:18.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  78    96.72 ubuntu:18.04-x-riscv64        : Ok   riscv64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  79    18.24 ubuntu:18.04-x-s390           : Ok   s390x-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  80    19.54 ubuntu:18.04-x-sh4            : Ok   sh4-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  81    18.34 ubuntu:18.04-x-sparc64        : Ok   sparc64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
  82    73.64 ubuntu:20.04                  : FAIL clang version 10.0.0-4ubuntu1

  83    22.06 ubuntu:20.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
  84    73.74 ubuntu:20.10                  : Ok   gcc (Ubuntu 10.3.0-1ubuntu1~20.10) 10.3.0 , Ubuntu clang version 11.0.0-2
  85    83.78 ubuntu:21.04                  : Ok   gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0 , Ubuntu clang version 12.0.0-3ubuntu1~21.04.2
  86    86.88 ubuntu:21.10                  : Ok   gcc (Ubuntu 11.2.0-7ubuntu2) 11.2.0 , Ubuntu clang version 13.0.0-2
  87   105.27 ubuntu:22.04                  : Ok   gcc (Ubuntu 11.2.0-13ubuntu1) 11.2.0 , Ubuntu clang version 13.0.0-9
BUILD_TARBALL_HEAD=16ed0580fb4d64bd59771ae7559dc307f04a0473
88 5613.66

real	95m27.836s
user	1m24.038s
sys	0m50.044s
[perfbuilder at five ~]$

 
> Thanks,
> Ian
> 
> > [acme at quaco perf]$ uname -a
> > Linux quaco 5.15.7-200.fc35.x86_64 #1 SMP Wed Dec 8 19:00:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
> > [acme at quaco perf]$ git log --oneline -1
> > 16ed0580fb4d64bd (HEAD -> perf/core, seventh/perf/core, five/perf/core, acme.korg/tmp.perf/perf_cpu) perf cpumap: Give CPUs their own type
> > [acme at quaco perf]$ perf -v
> > perf version 5.16.g16ed0580fb4d
> > [acme at quaco perf]$ sudo su -
> > [sudo] password for acme:
> > [root at quaco ~]# perf -vv
> > perf version 5.16.g16ed0580fb4d
> >                  dwarf: [ on  ]  # HAVE_DWARF_SUPPORT
> >     dwarf_getlocations: [ on  ]  # HAVE_DWARF_GETLOCATIONS_SUPPORT
> >                  glibc: [ on  ]  # HAVE_GLIBC_SUPPORT
> >          syscall_table: [ on  ]  # HAVE_SYSCALL_TABLE_SUPPORT
> >                 libbfd: [ on  ]  # HAVE_LIBBFD_SUPPORT
> >                 libelf: [ on  ]  # HAVE_LIBELF_SUPPORT
> >                libnuma: [ on  ]  # HAVE_LIBNUMA_SUPPORT
> > numa_num_possible_cpus: [ on  ]  # HAVE_LIBNUMA_SUPPORT
> >                libperl: [ on  ]  # HAVE_LIBPERL_SUPPORT
> >              libpython: [ on  ]  # HAVE_LIBPYTHON_SUPPORT
> >               libslang: [ on  ]  # HAVE_SLANG_SUPPORT
> >              libcrypto: [ on  ]  # HAVE_LIBCRYPTO_SUPPORT
> >              libunwind: [ on  ]  # HAVE_LIBUNWIND_SUPPORT
> >     libdw-dwarf-unwind: [ on  ]  # HAVE_DWARF_SUPPORT
> >                   zlib: [ on  ]  # HAVE_ZLIB_SUPPORT
> >                   lzma: [ on  ]  # HAVE_LZMA_SUPPORT
> >              get_cpuid: [ on  ]  # HAVE_AUXTRACE_SUPPORT
> >                    bpf: [ on  ]  # HAVE_LIBBPF_SUPPORT
> >                    aio: [ on  ]  # HAVE_AIO_SUPPORT
> >                   zstd: [ on  ]  # HAVE_ZSTD_SUPPORT
> >                libpfm4: [ OFF ]  # HAVE_LIBPFM
> > [root at quaco ~]# perf test
> >   1: vmlinux symtab matches kallsyms                                 : Ok
> >   2: Detect openat syscall event                                     : Ok
> >   3: Detect openat syscall event on all cpus                         : Ok
> >   4: Read samples using the mmap interface                           : Ok
> >   5: Test data source output                                         : Ok
> >   6: Parse event definition strings                                  : Ok
> >   7: Simple expression parser                                        : Ok
> >   8: PERF_RECORD_* events & perf_sample fields                       : Ok
> >   9: Parse perf pmu format                                           : Ok
> >  10: PMU events                                                      :
> >  10.1: PMU event table sanity                                        : Ok
> >  10.2: PMU event map aliases                                         : Ok
> >  10.3: Parsing of PMU event table metrics                            : Ok
> >  10.4: Parsing of PMU event table metrics with fake PMUs             : Ok
> >  11: DSO data read                                                   : Ok
> >  12: DSO data cache                                                  : Ok
> >  13: DSO data reopen                                                 : Ok
> >  14: Roundtrip evsel->name                                           : Ok
> >  15: Parse sched tracepoints fields                                  : Ok
> >  16: syscalls:sys_enter_openat event fields                          : Ok
> >  17: Setup struct perf_event_attr                                    : Ok
> >  18: Match and link multiple hists                                   : Ok
> >  19: 'import perf' in python                                         : Ok
> >  20: Breakpoint overflow signal handler                              : Ok
> >  21: Breakpoint overflow sampling                                    : Ok
> >  22: Breakpoint accounting                                           : Ok
> >  23: Watchpoint                                                      :
> >  23.1: Read Only Watchpoint                                          : Skip (missing hardware support)
> >  23.2: Write Only Watchpoint                                         : Ok
> >  23.3: Read / Write Watchpoint                                       : Ok
> >  23.4: Modify Watchpoint                                             : Ok
> >  24: Number of exit events of a simple workload                      : Ok
> >  25: Software clock events period values                             : Ok
> >  26: Object code reading                                             : Ok
> >  27: Sample parsing                                                  : Ok
> >  28: Use a dummy software event to keep tracking                     : Ok
> >  29: Parse with no sample_id_all bit set                             : Ok
> >  30: Filter hist entries                                             : Ok
> >  31: Lookup mmap thread                                              : Ok
> >  32: Share thread maps                                               : Ok
> >  33: Sort output of hist entries                                     : Ok
> >  34: Cumulate child hist entries                                     : Ok
> >  35: Track with sched_switch                                         : Ok
> >  36: Filter fds with revents mask in a fdarray                       : Ok
> >  37: Add fd to a fdarray, making it autogrow                         : Ok
> >  38: kmod_path__parse                                                : Ok
> >  39: Thread map                                                      : Ok
> >  40: LLVM search and compile                                         :
> >  40.1: Basic BPF llvm compile                                        : Ok
> >  40.2: kbuild searching                                              : Ok
> >  40.3: Compile source for BPF prologue generation                    : Ok
> >  40.4: Compile source for BPF relocation                             : Ok
> >  41: Session topology                                                : Ok
> >  42: BPF filter                                                      :
> >  42.1: Basic BPF filtering                                           : Ok
> >  42.2: BPF pinning                                                   : Ok
> >  42.3: BPF prologue generation                                       : Ok
> >  43: Synthesize thread map                                           : Ok
> >  44: Remove thread map                                               : Ok
> >  45: Synthesize cpu map                                              : Ok
> >  46: Synthesize stat config                                          : Ok
> >  47: Synthesize stat                                                 : Ok
> >  48: Synthesize stat round                                           : Ok
> >  49: Synthesize attr update                                          : Ok
> >  50: Event times                                                     : Ok
> >  51: Read backward ring buffer                                       : Ok
> >  52: Print cpu map                                                   : Ok
> >  53: Merge cpu map                                                   : Ok
> >  54: Probe SDT events                                                : Ok
> >  55: is_printable_array                                              : Ok
> >  56: Print bitmap                                                    : Ok
> >  57: perf hooks                                                      : Ok
> >  58: builtin clang support                                           :
> >  58.1: builtin clang compile C source to IR                          : Skip (not compiled in)
> >  58.2: builtin clang compile C source to ELF object                  : Skip (not compiled in)
> >  59: unit_number__scnprintf                                          : Ok
> >  60: mem2node                                                        : Ok
> >  61: time utils                                                      : Ok
> >  62: Test jit_write_elf                                              : Ok
> >  63: Test libpfm4 support                                            :
> >  63.1: test of individual --pfm-events                               : Skip (not compiled in)
> >  63.2: test groups of --pfm-events                                   : Skip (not compiled in)
> >  64: Test api io                                                     : Ok
> >  65: maps__merge_in                                                  : Ok
> >  66: Demangle Java                                                   : Ok
> >  67: Demangle OCaml                                                  : Ok
> >  68: Parse and process metrics                                       : Ok
> >  69: PE file support                                                 : Ok
> >  70: Event expansion for cgroups                                     : Ok
> >  71: Convert perf time to TSC                                        : Ok
> >  72: dlfilter C API                                                  : Ok
> >  73: Sigtrap                                                         : Ok
> >  74: x86 rdpmc                                                       : Ok
> >  75: Test dwarf unwind                                               : Ok
> >  76: x86 instruction decoder - new instructions                      : Ok
> >  77: Intel PT packet decoder                                         : Ok
> >  78: x86 bp modify                                                   : Ok
> >  79: x86 Sample parsing                                              : Ok
> >  80: build id cache operations                                       : Ok
> >  81: daemon operations                                               : Ok
> >  82: perf pipe recording and injection test                          : Ok
> >  83: Add vfs_getname probe to get syscall args filenames             : Ok
> >  84: probe libc's inet_pton & backtrace it with ping                 : Ok
> >  85: Use vfs_getname probe to get syscall args filenames             : Ok
> >  86: Zstd perf.data compression/decompression                        : Ok
> >  87: perf stat csv summary test                                      : Ok
> >  88: perf stat metrics (shadow stat) test                            : Ok
> >  89: perf all metricgroups test                                      : FAILED!
> >  90: perf all metrics test                                           : Ok
> >  91: perf all PMU test                                               : Ok
> >  92: perf stat --bpf-counters test                                   : Ok
> >  93: Check Arm CoreSight trace data recording and synthesized samples: Skip
> >  94: Check Arm SPE trace data recording and synthesized samples      : Skip
> >  95: Check open filename arg using perf trace + vfs_getname          : Ok
> > [root at quaco ~]#
> >
> > And the containers are ok so far:
> >
> > [perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
> > [perfbuilder at five ~]$ time dm
> >    1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
> >    2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
> >    3    54.98 alpine:3.5                    : Ok   gcc (Alpine 6.2.1) 6.2.1 20160822 , clang version 3.8.1 (tags/RELEASE_381/final)
> >    4    57.69 alpine:3.6                    : Ok   gcc (Alpine 6.3.0) 6.3.0 , clang version 4.0.0 (tags/RELEASE_400/final)
> >    5    63.62 alpine:3.7                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0)
> >    6    64.52 alpine:3.8                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
> >    7    66.54 alpine:3.9                    : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1)
> >    8    91.91 alpine:3.10                   : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0)
> >    9   104.93 alpine:3.11                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0)
> >   10   107.97 alpine:3.12                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c)
> >   11   115.98 alpine:3.13                   : Ok   gcc (Alpine 10.2.1_pre1) 10.2.1 20201203 , Alpine clang version 10.0.1
> >   12   101.73 alpine:3.14                   : Ok   gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424 , Alpine clang version 11.1.0
> >   13   103.35 alpine:3.15                   : Ok   gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027 , Alpine clang version 12.0.1
> >   14   104.43 alpine:edge                   : Ok   gcc (Alpine 11.2.1_git20211128) 11.2.1 20211128 , Alpine clang version 12.0.1
> >   15    51.06 alt:p8                        : Ok   x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1) , clang version 3.8.0 (tags/RELEASE_380/final)
> >   16    75.95 alt:p9                        : Ok   x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1) , clang version 10.0.0
> >   17    75.26 alt:p10                       : Ok   x86_64-alt-linux-gcc (GCC) 10.3.1 20210703 (ALT Sisyphus 10.3.1-alt2) , clang version 11.0.1
> >   18    74.85 alt:sisyphus                  : Ok   x86_64-alt-linux-gcc (GCC) 11.2.1 20210911 (ALT Sisyphus 11.2.1-alt1) , ALT Linux Team clang version 12.0.1
> >   19    52.87 amazonlinux:1                 : Ok   gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) , clang version 3.6.2 (tags/RELEASE_362/final)
> >   20    85.98 amazonlinux:2                 : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13) , clang version 11.1.0 (Amazon Linux 2 11.1.0-1.amzn2.0.2)
> >   21    79.77 archlinux:base                : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
> >   22    83.56 centos:8                      : Ok   gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1) , clang version 11.0.1 (Red Hat 11.0.1-1.module_el8.4.0+966+2995ef20)
> >   23    98.02 centos:stream                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-3) , clang version 12.0.1 (Red Hat 12.0.1-2.module_el8.6.0+937+1cafe22c)
> >   24    27.67 clearlinux:latest             : Ok   gcc (Clear Linux OS for Intel Architecture) 11.2.1 20211228 releases/gcc-11.2.0-618-g3b2b18144c , clang version 11.1.0
> >   25    65.92 debian:9                      : Ok   gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 , clang version 3.8.1-24 (tags/RELEASE_381/final)
> >   26    62.20 debian:10                     : Ok   gcc (Debian 8.3.0-6) 8.3.0 , clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)
> >   27: debian:11
> >

-- 

- Arnaldo


From acme at kernel.org  Mon Jan 10 16:50:50 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Mon, 10 Jan 2022 21:50:50 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <YdzSKOWJRC0dRnSn@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
 <Ydyjvcma/wMTPwbn@kernel.org> <Ydymdm/PoB0hQVUT@kernel.org>
 <CAP-5=fVAa3JVbdzNZg0LrVfw__9U9Q8PkHcro+TJiFVyvTho+A@mail.gmail.com>
 <YdzSKOWJRC0dRnSn@kernel.org>
Message-ID: <YdzUah2LGrPDuKyR@kernel.org>

Em Mon, Jan 10, 2022 at 09:41:12PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 02:29:58PM -0800, Ian Rogers escreveu:
> > On Mon, Jan 10, 2022 at 1:34 PM Arnaldo Carvalho de Melo
> > <acme at kernel.org> wrote:
> > >
> > > Em Mon, Jan 10, 2022 at 06:23:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > > At this point we need to remove the now unused perf_env__get_cpu(), and
> > > > > > then deal with the fallout in the following patches that needlessly
> > > > > > modify this unused function.
> > > > > >
> > > > > > Doing that now.
> > > > >
> > > > > Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> > > > > build containers, a better start now:
> > >
> > > > So far so good:
> > >
> > > perf test ok, just that one that is failing, but before this series as
> > > well:
> > >
> > >  89: perf all metricgroups test                                      : FAILED!
> > 
> > Could you add the verbose output? I suspect it is fixed by this:
> > https://lore.kernel.org/lkml/20211223183948.3423989-1-irogers at google.com/
> 
> I'll try it.

Yeah, stops failing, will review and apply tomorrow.

 80: build id cache operations                                       : Ok
 81: daemon operations                                               : Ok
 82: perf pipe recording and injection test                          : Ok
 83: Add vfs_getname probe to get syscall args filenames             : Ok
 84: probe libc's inet_pton & backtrace it with ping                 : Ok
 85: Use vfs_getname probe to get syscall args filenames             : Ok
 86: Zstd perf.data compression/decompression                        : Ok
 87: perf stat csv summary test                                      : Ok
 88: perf stat metrics (shadow stat) test                            : Ok
 89: perf all metricgroups test                                      : Ok
 90: perf all metrics test                                           : Ok
 91: perf all PMU test                                               : Ok
 92: perf stat --bpf-counters test                                   : Ok
 93: Check Arm CoreSight trace data recording and synthesized samples: Skip
 94: Check Arm SPE trace data recording and synthesized samples      : Skip
 95: Check open filename arg using perf trace + vfs_getname          : Ok
[root at quaco ~]#


 
> BTW, here are the final tests, problems with arm 32 and 64-bit, I'll go thru
> them tomorrow, to fix in the cset the problem appears, so that we keep it
> bisectable, else you can get what I have in tmp.perf/perf_cpu, fix it and
> tomorrow I'll retest.
> 
>   27    85.67 debian:11                     : Ok   gcc (Debian 10.2.1-6) 10.2.1 20210110 , Debian clang version 11.0.1-2
>   28    98.65 debian:experimental           : Ok   gcc (Debian 11.2.0-13) 11.2.0 , Debian clang version 13.0.0-9+b2
>   29     8.69 debian:experimental-x-arm64   : FAIL gcc version 11.2.0 (Debian 11.2.0-9)
>     arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
>     arch/arm64/util/pmu.c:18:35: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
>        18 |                 if (pmu->cpus->nr != cpu__max_cpu())
>           |                     ~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~
>           |                              |       |
>           |                              int     struct perf_cpu
>     make[5]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: util] Error 2
>     make[4]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arm64] Error 2
>     make[3]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arch] Error 2
>   30    19.15 debian:experimental-x-mips    : Ok   mips-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110
>   31    21.25 debian:experimental-x-mips64  : Ok   mips64-linux-gnuabi64-gcc (Debian 10.2.1-6) 10.2.1 20210110
>   32    22.45 debian:experimental-x-mipsel  : Ok   mipsel-linux-gnu-gcc (Debian 11.2.0-9) 11.2.0
>   33    21.86 fedora:22                     : Ok   gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) , clang version 3.5.0 (tags/RELEASE_350/final)
>   34    55.88 fedora:23                     : Ok   gcc (GCC) 5.3.1 20160406 (Red Hat 5.3.1-6) , clang version 3.7.0 (tags/RELEASE_370/final)
>   35    67.12 fedora:24                     : Ok   gcc (GCC) 6.3.1 20161221 (Red Hat 6.3.1-1) , clang version 3.8.1 (tags/RELEASE_381/final)
>   36    17.53 fedora:24-x-ARC-uClibc        : Ok   arc-linux-gcc (ARCompact ISA Linux uClibc toolchain 2017.09-rc2) 7.1.1 20170710
>   37    68.11 fedora:25                     : Ok   gcc (GCC) 6.4.1 20170727 (Red Hat 6.4.1-1) , clang version 3.9.1 (tags/RELEASE_391/final)
>   38    80.15 fedora:26                     : Ok   gcc (GCC) 7.3.1 20180130 (Red Hat 7.3.1-2) , clang version 4.0.1 (tags/RELEASE_401/final)
>   39    80.54 fedora:27                     : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-6) , clang version 5.0.2 (tags/RELEASE_502/final)
>   40    91.48 fedora:28                     : Ok   gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2) , clang version 6.0.1 (tags/RELEASE_601/final)
>   41    96.71 fedora:29                     : Ok   gcc (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2) , clang version 7.0.1 (Fedora 7.0.1-6.fc29)
>   42   100.71 fedora:30                     : Ok   gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) , clang version 8.0.0 (Fedora 8.0.0-3.fc30)
>   43    94.09 fedora:31                     : Ok   gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2) , clang version 9.0.1 (Fedora 9.0.1-4.fc31)
>   44    87.49 fedora:32                     : Ok   gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) , clang version 10.0.1 (Fedora 10.0.1-3.fc32)
>   45    85.99 fedora:33                     : Ok   gcc (GCC) 10.3.1 20210422 (Red Hat 10.3.1-1) , clang version 11.0.0 (Fedora 11.0.0-3.fc33)
>   46    88.89 fedora:34                     : Ok   gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1) , clang version 12.0.1 (Fedora 12.0.1-1.fc34)
>   47    19.84 fedora:34-x-ARC-glibc         : Ok   arc-linux-gcc (ARC HS GNU/Linux glibc toolchain 2019.03-rc1) 8.3.1 20190225
>   48    17.93 fedora:34-x-ARC-uClibc        : Ok   arc-linux-gcc (ARCv2 ISA Linux uClibc toolchain 2019.03-rc1) 8.3.1 20190225
>   49    91.33 fedora:35                     : Ok   gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7) , clang version 13.0.0 (Fedora 13.0.0-3.fc35)
>   50    99.83 fedora:rawhide                : Ok   gcc (GCC) 11.2.1 20211203 (Red Hat 11.2.1-7) , clang version 13.0.0 (Fedora 13.0.0-5.fc36)
>   51    79.16 gentoo-stage3:latest          : Ok   gcc (Gentoo 11.2.0 p1) 11.2.0 , clang version 13.0.0
>   52    68.81 mageia:6                      : Ok   gcc (Mageia 5.5.0-1.mga6) 5.5.0 , clang version 3.9.1 (tags/RELEASE_391/final)
>   53    38.50 mageia:7                      : FAIL clang version 8.0.0 (Mageia 8.0.0-1.mga7)
>           yychar = yylex (&yylval, &yylloc, scanner);
>                    ^
>     #define yylex           parse_events_lex
>                             ^
>     1 error generated.
>     make[3]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: util] Error 2
>   54    89.20 manjaro:base                  : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
>   55     6.18 openmandriva:cooker           : FAIL gcc version 11.2.0 20210728 (OpenMandriva) (GCC)
>     In file included from builtin-bench.c:22:
>     bench/bench.h:66:19: error: conflicting types for 'pthread_attr_setaffinity_np'; have 'int(pthread_attr_t *, size_t,  cpu_set_t *)' {aka 'int(pthread_attr_t *, long unsigned int,  cpu_set_t *)'}
>        66 | static inline int pthread_attr_setaffinity_np(pthread_attr_t *attr __maybe_unused,
>           |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>     In file included from bench/bench.h:64,
>                      from builtin-bench.c:22:
>     /usr/include/pthread.h:394:12: note: previous declaration of 'pthread_attr_setaffinity_np' with type 'int(pthread_attr_t *, size_t,  const cpu_set_t *)' {aka 'int(pthread_attr_t *, long unsigned int,  const cpu_set_t *)'}
>       394 | extern int pthread_attr_setaffinity_np (pthread_attr_t *__attr,
>           |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
>     ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
>     ld: warning: -r and --icf may not be used together, disabling --icf
>     ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
>     ld: warning: -r and --icf may not be used together, disabling --icf
>     ld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
>     ld: warning: -r and --icf may not be used together, disabling --icf
>   56   100.50 opensuse:15.0                 : Ok   gcc (SUSE Linux) 7.4.1 20190905 [gcc-7-branch revision 275407] , clang version 5.0.1 (tags/RELEASE_501/final 312548)
>   57   107.92 opensuse:15.1                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 7.0.1 (tags/RELEASE_701/final 349238)
>   58   102.71 opensuse:15.2                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 9.0.1
>   59   113.86 opensuse:15.3                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 11.0.1
>   60   114.75 opensuse:15.4                 : Ok   gcc (SUSE Linux) 7.5.0 , clang version 11.0.1
>   61   129.42 opensuse:tumbleweed           : Ok   gcc (SUSE Linux) 11.2.1 20211124 [revision 7510c23c1ec53aa4a62705f0384079661342ff7b] , clang version 13.0.0
>   62    94.32 oraclelinux:8                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4.0.1) , clang version 12.0.1 (Red Hat 12.0.1-4.0.1.module+el8.5.0+20428+2b4ecd47)
>   63    94.81 rockylinux:8                  : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module+el8.5.0+715+58f51d49)
>   64    71.11 ubuntu:16.04                  : Ok   gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609 , clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final)
>   65     6.89 ubuntu:16.04-x-arm            : FAIL gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)
>     arch/arm/util/cs-etm.c: In function 'cs_etm_set_option':
>     arch/arm/util/cs-etm.c:206:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>       for (i = 0; i < cpu__max_cpu(); i++) {
>                     ^
>     arch/arm/util/cs-etm.c:207:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>        if (!perf_cpu_map__has(event_cpus, i) ||
>                                           ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c:208:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>            !perf_cpu_map__has(online_cpus, i))
>                                            ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c: In function 'cs_etm_info_priv_size':
>     arch/arm/util/cs-etm.c:525:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>        for (i = 0; i < cpu__max_cpu(); i++) {
>                      ^
>     arch/arm/util/cs-etm.c:526:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (!perf_cpu_map__has(event_cpus, i) ||
>                                            ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c:527:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>             !perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c:539:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>        for (i = 0; i < cpu__max_cpu(); i++) {
>                      ^
>     arch/arm/util/cs-etm.c:540:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (!perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c: In function 'cs_etm_info_fill':
>     arch/arm/util/cs-etm.c:725:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (perf_cpu_map__has(event_cpus, i) &&
>                                           ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c:726:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>             !perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     arch/arm/util/cs-etm.c:746:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>       for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
>                     ^
>     arch/arm/util/cs-etm.c:747:34: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>        if (perf_cpu_map__has(cpu_map, i))
>                                       ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
>     make[5]: *** [util] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm' failed
>     make[4]: *** [arm] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
>     make[3]: *** [arch] Error 2
>   66     6.99 ubuntu:16.04-x-arm64          : FAIL gcc version 5.4.0 20160609 (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9)
>     arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
>     arch/arm64/util/pmu.c:18:21: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
>        if (pmu->cpus->nr != cpu__max_cpu())
>                          ^
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
>     make[5]: *** [util] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm64' failed
>     make[4]: *** [arm64] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
>     make[3]: *** [arch] Error 2
>   67    18.54 ubuntu:16.04-x-powerpc        : Ok   powerpc-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
>   68    19.04 ubuntu:16.04-x-powerpc64      : Ok   powerpc64-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
>   69    18.93 ubuntu:16.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
>   70    19.04 ubuntu:16.04-x-s390           : Ok   s390x-linux-gnu-gcc (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
>   71    76.32 ubuntu:18.04                  : Ok   gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0 , clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
>   72     7.49 ubuntu:18.04-x-arm            : FAIL gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)
>     arch/arm/util/cs-etm.c: In function 'cs_etm_set_option':
>     arch/arm/util/cs-etm.c:206:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>       for (i = 0; i < cpu__max_cpu(); i++) {
>                     ^ ~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:207:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>        if (!perf_cpu_map__has(event_cpus, i) ||
>                                           ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:208:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>            !perf_cpu_map__has(online_cpus, i))
>                                            ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c: In function 'cs_etm_info_priv_size':
>     arch/arm/util/cs-etm.c:525:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>        for (i = 0; i < cpu__max_cpu(); i++) {
>                      ^ ~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:526:39: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (!perf_cpu_map__has(event_cpus, i) ||
>                                            ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:527:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>             !perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:539:17: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>        for (i = 0; i < cpu__max_cpu(); i++) {
>                      ^ ~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:540:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (!perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c: In function 'cs_etm_info_fill':
>     arch/arm/util/cs-etm.c:725:38: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>         if (perf_cpu_map__has(event_cpus, i) &&
>                                           ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:726:40: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>             !perf_cpu_map__has(online_cpus, i))
>                                             ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:746:16: error: invalid operands to binary < (have 'int' and 'struct perf_cpu')
>       for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
>                     ^ ~~~~~~~~~~~~~~
>     arch/arm/util/cs-etm.c:747:34: error: incompatible type for argument 2 of 'perf_cpu_map__has'
>        if (perf_cpu_map__has(cpu_map, i))
>                                       ^
>     In file included from arch/arm/util/../../../util/cpumap.h:8:0,
>                      from arch/arm/util/cs-etm.c:22:
>     /git/perf-5.16.0/tools/lib/perf/include/perf/cpumap.h:22:18: note: expected 'struct perf_cpu' but argument is of type 'int'
>      LIBPERF_API bool perf_cpu_map__has(const struct perf_cpu_map *map, struct perf_cpu cpu);
>                       ^~~~~~~~~~~~~~~~~
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
>     make[5]: *** [util] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm' failed
>     make[4]: *** [arm] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
>     make[3]: *** [arch] Error 2
>   73     7.49 ubuntu:18.04-x-arm64          : FAIL gcc version 7.5.0 (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04)
>     arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
>     arch/arm64/util/pmu.c:18:21: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
>        if (pmu->cpus->nr != cpu__max_cpu())
>            ~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'util' failed
>     make[5]: *** [util] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arm64' failed
>     make[4]: *** [arm64] Error 2
>     /git/perf-5.16.0/tools/build/Makefile.build:139: recipe for target 'arch' failed
>     make[3]: *** [arch] Error 2
>   74    16.73 ubuntu:18.04-x-m68k           : Ok   m68k-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   75    19.94 ubuntu:18.04-x-powerpc        : Ok   powerpc-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   76    21.35 ubuntu:18.04-x-powerpc64      : Ok   powerpc64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   77    21.55 ubuntu:18.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   78    96.72 ubuntu:18.04-x-riscv64        : Ok   riscv64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   79    18.24 ubuntu:18.04-x-s390           : Ok   s390x-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   80    19.54 ubuntu:18.04-x-sh4            : Ok   sh4-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   81    18.34 ubuntu:18.04-x-sparc64        : Ok   sparc64-linux-gnu-gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
>   82    73.64 ubuntu:20.04                  : FAIL clang version 10.0.0-4ubuntu1
> 
>   83    22.06 ubuntu:20.04-x-powerpc64el    : Ok   powerpc64le-linux-gnu-gcc (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
>   84    73.74 ubuntu:20.10                  : Ok   gcc (Ubuntu 10.3.0-1ubuntu1~20.10) 10.3.0 , Ubuntu clang version 11.0.0-2
>   85    83.78 ubuntu:21.04                  : Ok   gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0 , Ubuntu clang version 12.0.0-3ubuntu1~21.04.2
>   86    86.88 ubuntu:21.10                  : Ok   gcc (Ubuntu 11.2.0-7ubuntu2) 11.2.0 , Ubuntu clang version 13.0.0-2
>   87   105.27 ubuntu:22.04                  : Ok   gcc (Ubuntu 11.2.0-13ubuntu1) 11.2.0 , Ubuntu clang version 13.0.0-9
> BUILD_TARBALL_HEAD=16ed0580fb4d64bd59771ae7559dc307f04a0473
> 88 5613.66
> 
> real	95m27.836s
> user	1m24.038s
> sys	0m50.044s
> [perfbuilder at five ~]$
> 
>  
> > Thanks,
> > Ian
> > 
> > > [acme at quaco perf]$ uname -a
> > > Linux quaco 5.15.7-200.fc35.x86_64 #1 SMP Wed Dec 8 19:00:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
> > > [acme at quaco perf]$ git log --oneline -1
> > > 16ed0580fb4d64bd (HEAD -> perf/core, seventh/perf/core, five/perf/core, acme.korg/tmp.perf/perf_cpu) perf cpumap: Give CPUs their own type
> > > [acme at quaco perf]$ perf -v
> > > perf version 5.16.g16ed0580fb4d
> > > [acme at quaco perf]$ sudo su -
> > > [sudo] password for acme:
> > > [root at quaco ~]# perf -vv
> > > perf version 5.16.g16ed0580fb4d
> > >                  dwarf: [ on  ]  # HAVE_DWARF_SUPPORT
> > >     dwarf_getlocations: [ on  ]  # HAVE_DWARF_GETLOCATIONS_SUPPORT
> > >                  glibc: [ on  ]  # HAVE_GLIBC_SUPPORT
> > >          syscall_table: [ on  ]  # HAVE_SYSCALL_TABLE_SUPPORT
> > >                 libbfd: [ on  ]  # HAVE_LIBBFD_SUPPORT
> > >                 libelf: [ on  ]  # HAVE_LIBELF_SUPPORT
> > >                libnuma: [ on  ]  # HAVE_LIBNUMA_SUPPORT
> > > numa_num_possible_cpus: [ on  ]  # HAVE_LIBNUMA_SUPPORT
> > >                libperl: [ on  ]  # HAVE_LIBPERL_SUPPORT
> > >              libpython: [ on  ]  # HAVE_LIBPYTHON_SUPPORT
> > >               libslang: [ on  ]  # HAVE_SLANG_SUPPORT
> > >              libcrypto: [ on  ]  # HAVE_LIBCRYPTO_SUPPORT
> > >              libunwind: [ on  ]  # HAVE_LIBUNWIND_SUPPORT
> > >     libdw-dwarf-unwind: [ on  ]  # HAVE_DWARF_SUPPORT
> > >                   zlib: [ on  ]  # HAVE_ZLIB_SUPPORT
> > >                   lzma: [ on  ]  # HAVE_LZMA_SUPPORT
> > >              get_cpuid: [ on  ]  # HAVE_AUXTRACE_SUPPORT
> > >                    bpf: [ on  ]  # HAVE_LIBBPF_SUPPORT
> > >                    aio: [ on  ]  # HAVE_AIO_SUPPORT
> > >                   zstd: [ on  ]  # HAVE_ZSTD_SUPPORT
> > >                libpfm4: [ OFF ]  # HAVE_LIBPFM
> > > [root at quaco ~]# perf test
> > >   1: vmlinux symtab matches kallsyms                                 : Ok
> > >   2: Detect openat syscall event                                     : Ok
> > >   3: Detect openat syscall event on all cpus                         : Ok
> > >   4: Read samples using the mmap interface                           : Ok
> > >   5: Test data source output                                         : Ok
> > >   6: Parse event definition strings                                  : Ok
> > >   7: Simple expression parser                                        : Ok
> > >   8: PERF_RECORD_* events & perf_sample fields                       : Ok
> > >   9: Parse perf pmu format                                           : Ok
> > >  10: PMU events                                                      :
> > >  10.1: PMU event table sanity                                        : Ok
> > >  10.2: PMU event map aliases                                         : Ok
> > >  10.3: Parsing of PMU event table metrics                            : Ok
> > >  10.4: Parsing of PMU event table metrics with fake PMUs             : Ok
> > >  11: DSO data read                                                   : Ok
> > >  12: DSO data cache                                                  : Ok
> > >  13: DSO data reopen                                                 : Ok
> > >  14: Roundtrip evsel->name                                           : Ok
> > >  15: Parse sched tracepoints fields                                  : Ok
> > >  16: syscalls:sys_enter_openat event fields                          : Ok
> > >  17: Setup struct perf_event_attr                                    : Ok
> > >  18: Match and link multiple hists                                   : Ok
> > >  19: 'import perf' in python                                         : Ok
> > >  20: Breakpoint overflow signal handler                              : Ok
> > >  21: Breakpoint overflow sampling                                    : Ok
> > >  22: Breakpoint accounting                                           : Ok
> > >  23: Watchpoint                                                      :
> > >  23.1: Read Only Watchpoint                                          : Skip (missing hardware support)
> > >  23.2: Write Only Watchpoint                                         : Ok
> > >  23.3: Read / Write Watchpoint                                       : Ok
> > >  23.4: Modify Watchpoint                                             : Ok
> > >  24: Number of exit events of a simple workload                      : Ok
> > >  25: Software clock events period values                             : Ok
> > >  26: Object code reading                                             : Ok
> > >  27: Sample parsing                                                  : Ok
> > >  28: Use a dummy software event to keep tracking                     : Ok
> > >  29: Parse with no sample_id_all bit set                             : Ok
> > >  30: Filter hist entries                                             : Ok
> > >  31: Lookup mmap thread                                              : Ok
> > >  32: Share thread maps                                               : Ok
> > >  33: Sort output of hist entries                                     : Ok
> > >  34: Cumulate child hist entries                                     : Ok
> > >  35: Track with sched_switch                                         : Ok
> > >  36: Filter fds with revents mask in a fdarray                       : Ok
> > >  37: Add fd to a fdarray, making it autogrow                         : Ok
> > >  38: kmod_path__parse                                                : Ok
> > >  39: Thread map                                                      : Ok
> > >  40: LLVM search and compile                                         :
> > >  40.1: Basic BPF llvm compile                                        : Ok
> > >  40.2: kbuild searching                                              : Ok
> > >  40.3: Compile source for BPF prologue generation                    : Ok
> > >  40.4: Compile source for BPF relocation                             : Ok
> > >  41: Session topology                                                : Ok
> > >  42: BPF filter                                                      :
> > >  42.1: Basic BPF filtering                                           : Ok
> > >  42.2: BPF pinning                                                   : Ok
> > >  42.3: BPF prologue generation                                       : Ok
> > >  43: Synthesize thread map                                           : Ok
> > >  44: Remove thread map                                               : Ok
> > >  45: Synthesize cpu map                                              : Ok
> > >  46: Synthesize stat config                                          : Ok
> > >  47: Synthesize stat                                                 : Ok
> > >  48: Synthesize stat round                                           : Ok
> > >  49: Synthesize attr update                                          : Ok
> > >  50: Event times                                                     : Ok
> > >  51: Read backward ring buffer                                       : Ok
> > >  52: Print cpu map                                                   : Ok
> > >  53: Merge cpu map                                                   : Ok
> > >  54: Probe SDT events                                                : Ok
> > >  55: is_printable_array                                              : Ok
> > >  56: Print bitmap                                                    : Ok
> > >  57: perf hooks                                                      : Ok
> > >  58: builtin clang support                                           :
> > >  58.1: builtin clang compile C source to IR                          : Skip (not compiled in)
> > >  58.2: builtin clang compile C source to ELF object                  : Skip (not compiled in)
> > >  59: unit_number__scnprintf                                          : Ok
> > >  60: mem2node                                                        : Ok
> > >  61: time utils                                                      : Ok
> > >  62: Test jit_write_elf                                              : Ok
> > >  63: Test libpfm4 support                                            :
> > >  63.1: test of individual --pfm-events                               : Skip (not compiled in)
> > >  63.2: test groups of --pfm-events                                   : Skip (not compiled in)
> > >  64: Test api io                                                     : Ok
> > >  65: maps__merge_in                                                  : Ok
> > >  66: Demangle Java                                                   : Ok
> > >  67: Demangle OCaml                                                  : Ok
> > >  68: Parse and process metrics                                       : Ok
> > >  69: PE file support                                                 : Ok
> > >  70: Event expansion for cgroups                                     : Ok
> > >  71: Convert perf time to TSC                                        : Ok
> > >  72: dlfilter C API                                                  : Ok
> > >  73: Sigtrap                                                         : Ok
> > >  74: x86 rdpmc                                                       : Ok
> > >  75: Test dwarf unwind                                               : Ok
> > >  76: x86 instruction decoder - new instructions                      : Ok
> > >  77: Intel PT packet decoder                                         : Ok
> > >  78: x86 bp modify                                                   : Ok
> > >  79: x86 Sample parsing                                              : Ok
> > >  80: build id cache operations                                       : Ok
> > >  81: daemon operations                                               : Ok
> > >  82: perf pipe recording and injection test                          : Ok
> > >  83: Add vfs_getname probe to get syscall args filenames             : Ok
> > >  84: probe libc's inet_pton & backtrace it with ping                 : Ok
> > >  85: Use vfs_getname probe to get syscall args filenames             : Ok
> > >  86: Zstd perf.data compression/decompression                        : Ok
> > >  87: perf stat csv summary test                                      : Ok
> > >  88: perf stat metrics (shadow stat) test                            : Ok
> > >  89: perf all metricgroups test                                      : FAILED!
> > >  90: perf all metrics test                                           : Ok
> > >  91: perf all PMU test                                               : Ok
> > >  92: perf stat --bpf-counters test                                   : Ok
> > >  93: Check Arm CoreSight trace data recording and synthesized samples: Skip
> > >  94: Check Arm SPE trace data recording and synthesized samples      : Skip
> > >  95: Check open filename arg using perf trace + vfs_getname          : Ok
> > > [root at quaco ~]#
> > >
> > > And the containers are ok so far:
> > >
> > > [perfbuilder at five ~]$ export BUILD_TARBALL=http://192.168.100.2/perf/perf-5.16.0.tar.xz
> > > [perfbuilder at five ~]$ time dm
> > >    1    95.61 almalinux:8                   : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-4) , clang version 12.0.1 (Red Hat 12.0.1-4.module_el8.5.0+1025+93159d6c)
> > >    2    56.18 alpine:3.4                    : Ok   gcc (Alpine 5.3.0) 5.3.0 , clang version 3.8.0 (tags/RELEASE_380/final)
> > >    3    54.98 alpine:3.5                    : Ok   gcc (Alpine 6.2.1) 6.2.1 20160822 , clang version 3.8.1 (tags/RELEASE_381/final)
> > >    4    57.69 alpine:3.6                    : Ok   gcc (Alpine 6.3.0) 6.3.0 , clang version 4.0.0 (tags/RELEASE_400/final)
> > >    5    63.62 alpine:3.7                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0)
> > >    6    64.52 alpine:3.8                    : Ok   gcc (Alpine 6.4.0) 6.4.0 , Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1)
> > >    7    66.54 alpine:3.9                    : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1)
> > >    8    91.91 alpine:3.10                   : Ok   gcc (Alpine 8.3.0) 8.3.0 , Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0)
> > >    9   104.93 alpine:3.11                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0)
> > >   10   107.97 alpine:3.12                   : Ok   gcc (Alpine 9.3.0) 9.3.0 , Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c)
> > >   11   115.98 alpine:3.13                   : Ok   gcc (Alpine 10.2.1_pre1) 10.2.1 20201203 , Alpine clang version 10.0.1
> > >   12   101.73 alpine:3.14                   : Ok   gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424 , Alpine clang version 11.1.0
> > >   13   103.35 alpine:3.15                   : Ok   gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027 , Alpine clang version 12.0.1
> > >   14   104.43 alpine:edge                   : Ok   gcc (Alpine 11.2.1_git20211128) 11.2.1 20211128 , Alpine clang version 12.0.1
> > >   15    51.06 alt:p8                        : Ok   x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1) , clang version 3.8.0 (tags/RELEASE_380/final)
> > >   16    75.95 alt:p9                        : Ok   x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1) , clang version 10.0.0
> > >   17    75.26 alt:p10                       : Ok   x86_64-alt-linux-gcc (GCC) 10.3.1 20210703 (ALT Sisyphus 10.3.1-alt2) , clang version 11.0.1
> > >   18    74.85 alt:sisyphus                  : Ok   x86_64-alt-linux-gcc (GCC) 11.2.1 20210911 (ALT Sisyphus 11.2.1-alt1) , ALT Linux Team clang version 12.0.1
> > >   19    52.87 amazonlinux:1                 : Ok   gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2) , clang version 3.6.2 (tags/RELEASE_362/final)
> > >   20    85.98 amazonlinux:2                 : Ok   gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13) , clang version 11.1.0 (Amazon Linux 2 11.1.0-1.amzn2.0.2)
> > >   21    79.77 archlinux:base                : Ok   gcc (GCC) 11.1.0 , clang version 13.0.0
> > >   22    83.56 centos:8                      : Ok   gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1) , clang version 11.0.1 (Red Hat 11.0.1-1.module_el8.4.0+966+2995ef20)
> > >   23    98.02 centos:stream                 : Ok   gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-3) , clang version 12.0.1 (Red Hat 12.0.1-2.module_el8.6.0+937+1cafe22c)
> > >   24    27.67 clearlinux:latest             : Ok   gcc (Clear Linux OS for Intel Architecture) 11.2.1 20211228 releases/gcc-11.2.0-618-g3b2b18144c , clang version 11.1.0
> > >   25    65.92 debian:9                      : Ok   gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516 , clang version 3.8.1-24 (tags/RELEASE_381/final)
> > >   26    62.20 debian:10                     : Ok   gcc (Debian 8.3.0-6) 8.3.0 , clang version 7.0.1-8+deb10u2 (tags/RELEASE_701/final)
> > >   27: debian:11
> > >
> 
> -- 
> 
> - Arnaldo

-- 

- Arnaldo


From rananta at google.com  Mon Jan 10 16:50:54 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 10 Jan 2022 16:50:54 -0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
 <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>
Message-ID: <CAJHc60ywYgAPfG11Ljkj3qzLoUn9mZPKnPH0P-HYS-pfs+A__g@mail.gmail.com>

On Sun, Jan 9, 2022 at 10:29 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> Hi Raghu,
>
> On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > KVM regularly introduces new hypercall services to the guests without
> > any consent from the Virtual Machine Manager (VMM). This means, the
> > guests can observe hypercall services in and out as they migrate
> > across various host kernel versions. This could be a major problem
> > if the guest discovered a hypercall, started using it, and after
> > getting migrated to an older kernel realizes that it's no longer
> > available. Depending on how the guest handles the change, there's
> > a potential chance that the guest would just panic.
> >
> > As a result, there's a need for the VMM to elect the services that
> > it wishes the guest to discover. VMM can elect these services based
> > on the kernels spread across its (migration) fleet. To remedy this,
> > extend the existing firmware psuedo-registers, such as
> > KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.
> >
> > These firmware registers are categorized based on the service call
> > owners, and unlike the existing firmware psuedo-registers, they hold
> > the features supported in the form of a bitmap.
> >
> > The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
> > this extension, which returns the number of psuedo-firmware
> > registers supported. During the VM initialization, the registers
> > holds an upper-limit of the features supported by the corresponding
> > registers. It's expected that the VMMs discover the features
> > provided by each register via GET_ONE_REG, and writeback the
> > desired values using SET_ONE_REG. KVM allows this modification
> > only until the VM has started.
> >
> > Older VMMs can simply ignore the capability and the hypercall services
> > will be exposed unconditionally to the guests, thus ensuring backward
> > compatibility.
> >
> > In this patch, the framework adds the register only for ARM's standard
> > secure services (owner value 4). Currently, this includes support only
> > for ARM True Random Number Generator (TRNG) service, with bit-0 of the
> > register representing mandatory features of v1.0. Other services are
> > momentarily added in the upcoming patches.
> >
> > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h |  12 ++++
> >  arch/arm64/include/uapi/asm/kvm.h |   4 ++
> >  arch/arm64/kvm/arm.c              |   4 ++
> >  arch/arm64/kvm/hypercalls.c       | 103 +++++++++++++++++++++++++++++-
> >  arch/arm64/kvm/trng.c             |   8 +--
> >  include/kvm/arm_hypercalls.h      |   6 ++
> >  6 files changed, 129 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 2a5f7f38006f..a32cded0371b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -102,6 +102,15 @@ struct kvm_s2_mmu {
> >  struct kvm_arch_memory_slot {
> >  };
> >
> > +/**
> > + * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
> > + *
> > + * @hvc_std_bmap: Bitmap of standard secure service calls
> > + */
> > +struct kvm_hvc_desc {
> > +       u64 hvc_std_bmap;
> > +};
> > +
> >  struct kvm_arch {
> >         struct kvm_s2_mmu mmu;
> >
> > @@ -137,6 +146,9 @@ struct kvm_arch {
> >
> >         /* Memory Tagging Extension enabled for the guest */
> >         bool mte_enabled;
> > +
> > +       /* Hypercall firmware register' descriptor */
> > +       struct kvm_hvc_desc hvc_desc;
> >  };
> >
> >  struct kvm_vcpu_fault_info {
> > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > index b3edde68bc3e..0d6f29c58456 100644
> > --- a/arch/arm64/include/uapi/asm/kvm.h
> > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > @@ -281,6 +281,10 @@ struct kvm_arm_copy_mte_tags {
> >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
> >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
> >
> > +#define KVM_REG_ARM_STD_BMAP                   KVM_REG_ARM_FW_REG(3)
> > +#define KVM_REG_ARM_STD_BIT_TRNG_V1_0          BIT(0)
> > +#define KVM_REG_ARM_STD_BMAP_BIT_MAX           0       /* Last valid bit */
> > +
> >  /* SVE registers */
> >  #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
> >
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index e4727dc771bf..56fe81565235 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> >         kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
> >
> >         set_default_spectre(kvm);
> > +       kvm_arm_init_hypercalls(kvm);
> >
> >         return ret;
> >  out_free_stage2_pgd:
> > @@ -283,6 +284,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> >         case KVM_CAP_ARM_PTRAUTH_GENERIC:
> >                 r = system_has_full_ptr_auth();
> >                 break;
> > +       case KVM_CAP_ARM_HVC_FW_REG_BMAP:
> > +               r = kvm_arm_num_fw_bmap_regs();
> > +               break;
>
> Looking at the discussion for the v2 series,
>
>  https://lore.kernel.org/kvmarm/20211130101958.fcdqthphyhxzvzla at gator.home/
>
> I assume that the number of the pseudo-firmware bitmap registers
> will be used to clear pseudo firmware bitmap registers that
> userspace doesn't know.
> I'm wondering how userspace can identify which pseudo-firmware
> registers that KVM_GET_REG_LIST provides are the pseudo-firmware
> bitmap registers that it doesn't know.
> For instance, suppose pseudo-firmware registers that KVM_GET_REG_LIST
> provides are KVM_REG_ARM_FW_REG(0) to KVM_REG_ARM_FW_REG(9), userspace
> doesn't knows KVM_REG_ARM_FW_REG(6) to KVM_REG_ARM_FW_REG(9), and
> KVM_CAP_ARM_HVC_FW_REG_BMAP returns 5, how can userspace identify
> remaining two bitmap registers from those 4 (fw-reg #6 to #9)
> firmware registers ?
>
In v3, we leave the decision upto the userspace. If the userspace
encounters a register that it's unaware, it can choose either to clear
it or let it get exposed to the guest as is (see the code snipped
shared by Andrew in the link).
Trying to understand the question better- are you asking how would
userspace distinguish between bitmap and regular fw registers with
intermixed sequence numbers?
If yes, do you foresee a reason why they 'unaware' registers needed to
be treated differently?
>
> >         default:
> >                 r = 0;
> >         }
> > diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> > index 3c2fcf31ad3d..06243e4670eb 100644
> > --- a/arch/arm64/kvm/hypercalls.c
> > +++ b/arch/arm64/kvm/hypercalls.c
> > @@ -58,6 +58,29 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
> >         val[3] = lower_32_bits(cycles);
> >  }
> >
> > +static bool kvm_arm_fw_reg_feat_enabled(u64 reg_bmap, u64 feat_bit)
> > +{
> > +       return reg_bmap & feat_bit;
> > +}
> > +
> > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
> > +{
> > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> > +
> > +       switch (func_id) {
> > +       case ARM_SMCCC_TRNG_VERSION:
> > +       case ARM_SMCCC_TRNG_FEATURES:
> > +       case ARM_SMCCC_TRNG_GET_UUID:
> > +       case ARM_SMCCC_TRNG_RND32:
> > +       case ARM_SMCCC_TRNG_RND64:
> > +               return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
> > +                                               KVM_REG_ARM_STD_BIT_TRNG_V1_0);
> > +       default:
> > +               /* By default, allow the services that aren't listed here */
> > +               return true;
> > +       }
> > +}
>
> kvm_hvc_call_supported() could return true even for @func_id that
> kvm_hvc_call_handler() returns -EINVAL for.  Is this behavior what
> you really want ?
Yes. My idea was to let kvm_hvc_call_supported() check for the
support, while kvm_hvc_call_handler() does the real processing of the
call.

> If so, IMHO the function name might be a bit mis-leading.
> "kvm_hvc_call_disabled" (and flip the return value)
> might be closer to what it does(?).
>
Sorry, I'm unclear how flipping is helping. Wouldn't we return 'false'
if we don't have a case for the func_id, indicating it's NOT disabled,
but kvm_hvc_call_handler() can still return SMCCC_RET_NOT_SUPPORTED?
>
> > +
> >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> >  {
> >         u32 func_id = smccc_get_function(vcpu);
> > @@ -65,6 +88,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> >         u32 feature;
> >         gpa_t gpa;
> >
> > +       if (!kvm_hvc_call_supported(vcpu, func_id))
> > +               goto out;
> > +
> >         switch (func_id) {
> >         case ARM_SMCCC_VERSION_FUNC_ID:
> >                 val[0] = ARM_SMCCC_VERSION_1_1;
> > @@ -143,6 +169,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> >                 return kvm_psci_call(vcpu);
> >         }
> >
> > +out:
> >         smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
> >         return 1;
> >  }
> > @@ -153,9 +180,25 @@ static const u64 kvm_arm_fw_reg_ids[] = {
> >         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
> >  };
> >
> > +static const u64 kvm_arm_fw_reg_bmap_ids[] = {
> > +       KVM_REG_ARM_STD_BMAP,
> > +};
> > +
> > +void kvm_arm_init_hypercalls(struct kvm *kvm)
> > +{
> > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > +
> > +       hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
> > +}
> > +
> > +int kvm_arm_num_fw_bmap_regs(void)
> > +{
> > +       return ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids);
> > +}
> > +
> >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
> >  {
> > -       return ARRAY_SIZE(kvm_arm_fw_reg_ids);
> > +       return ARRAY_SIZE(kvm_arm_fw_reg_ids) + kvm_arm_num_fw_bmap_regs();
> >  }
> >
> >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> > @@ -167,6 +210,11 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> >                         return -EFAULT;
> >         }
> >
> > +       for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids); i++) {
> > +               if (put_user(kvm_arm_fw_reg_bmap_ids[i], uindices++))
> > +                       return -EFAULT;
> > +       }
> > +
> >         return 0;
> >  }
> >
> > @@ -211,9 +259,20 @@ static int get_kernel_wa_level(u64 regid)
> >         return -EINVAL;
> >  }
> >
> > +static void
> > +kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
> > +{
> > +       struct kvm *kvm = vcpu->kvm;
> > +
> > +       mutex_lock(&kvm->lock);
> > +       *val = fw_reg_bmap;
> > +       mutex_unlock(&kvm->lock);
>
> Why does it need to hold the lock ? (Wouldn't READ_ONCE be enough ?)
>
I don't have much experience with READ_ONCE at this point, but do you
think this read can be protected again the read/write in
kvm_arm_set_fw_reg_bmap()?
>
> > +}
> > +
> >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> >  {
> >         void __user *uaddr = (void __user *)(long)reg->addr;
> > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> >         u64 val;
> >
> >         switch (reg->id) {
> > @@ -224,6 +283,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> >         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
> >                 val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
> >                 break;
> > +       case KVM_REG_ARM_STD_BMAP:
> > +               kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
> > +               break;
> >         default:
> >                 return -ENOENT;
> >         }
> > @@ -234,6 +296,43 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> >         return 0;
> >  }
> >
> > +static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
> > +{
> > +       int ret = 0;
> > +       struct kvm *kvm = vcpu->kvm;
> > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > +       u64 *fw_reg_bmap, fw_reg_features;
> > +
> > +       switch (reg_id) {
> > +       case KVM_REG_ARM_STD_BMAP:
> > +               fw_reg_bmap = &hvc_desc->hvc_std_bmap;
> > +               fw_reg_features = ARM_SMCCC_STD_FEATURES;
> > +               break;
> > +       default:
> > +               return -ENOENT;
> > +       }
> > +
> > +       /* Check for unsupported bit */
> > +       if (val & ~fw_reg_features)
> > +               return -EINVAL;
> > +
> > +       mutex_lock(&kvm->lock);
> > +
> > +       /*
> > +        * If the VM (any vCPU) has already started running, return success
> > +        * if there's no change in the value. Else, return -EBUSY.
> > +        */
> > +       if (kvm_vm_has_started(kvm)) {
> > +               ret = *fw_reg_bmap != val ? -EBUSY : 0;
> > +               goto out;
> > +       }
> > +
> > +       *fw_reg_bmap = val;
> > +out:
> > +       mutex_unlock(&kvm->lock);
> > +       return ret;
> > +}
> > +
> >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> >  {
> >         void __user *uaddr = (void __user *)(long)reg->addr;
> > @@ -310,6 +409,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> >                         return -EINVAL;
> >
> >                 return 0;
> > +       case KVM_REG_ARM_STD_BMAP:
> > +               return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
> >         default:
> >                 return -ENOENT;
> >         }
> > diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c
> > index 99bdd7103c9c..23f912514b06 100644
> > --- a/arch/arm64/kvm/trng.c
> > +++ b/arch/arm64/kvm/trng.c
> > @@ -60,14 +60,8 @@ int kvm_trng_call(struct kvm_vcpu *vcpu)
> >                 val = ARM_SMCCC_TRNG_VERSION_1_0;
> >                 break;
> >         case ARM_SMCCC_TRNG_FEATURES:
> > -               switch (smccc_get_arg1(vcpu)) {
> > -               case ARM_SMCCC_TRNG_VERSION:
> > -               case ARM_SMCCC_TRNG_FEATURES:
> > -               case ARM_SMCCC_TRNG_GET_UUID:
> > -               case ARM_SMCCC_TRNG_RND32:
> > -               case ARM_SMCCC_TRNG_RND64:
> > +               if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu)))
> >                         val = TRNG_SUCCESS;
>
> kvm_hvc_call_supported() returns true for any values that are
> not explicitly listed in kvm_hvc_call_supported() (i.e. it returns
> true even for @func_id that are not any of ARM_SMCCC_TRNG_*).
> So, I don't think it can simply use the current kvm_hvc_call_supported.
>
You are right. Probably I should leave the case statements as is (or
think of some better way).

Thanks for the review and suggestions.

Regards,
Raghavendra
> Thanks,
> Reiji
>
> > -               }
> >                 break;
> >         case ARM_SMCCC_TRNG_GET_UUID:
> >                 smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]),
> > diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
> > index 5d38628a8d04..8fe68d8d6d96 100644
> > --- a/include/kvm/arm_hypercalls.h
> > +++ b/include/kvm/arm_hypercalls.h
> > @@ -6,6 +6,9 @@
> >
> >  #include <asm/kvm_emulate.h>
> >
> > +#define ARM_SMCCC_STD_FEATURES \
> > +       GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
> > +
> >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
> >
> >  static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
> > @@ -42,9 +45,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
> >
> >  struct kvm_one_reg;
> >
> > +void kvm_arm_init_hypercalls(struct kvm *kvm);
> > +int kvm_arm_num_fw_bmap_regs(void);
> >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
> >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
> >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id);
> >
> >  #endif
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >


From yuzhao at google.com  Mon Jan 10 17:18:55 2022
From: yuzhao at google.com (Yu Zhao)
Date: Mon, 10 Jan 2022 18:18:55 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz> <YdjOazilBEkdUT7x@google.com>
 <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>
Message-ID: <Ydza/zXKY9ATRoh6@google.com>

On Mon, Jan 10, 2022 at 04:35:46PM +0100, Michal Hocko wrote:
> On Fri 07-01-22 16:36:11, Yu Zhao wrote:
> > On Fri, Jan 07, 2022 at 02:11:29PM +0100, Michal Hocko wrote:
> > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > [...]
> > > > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
> > > > +{
> > > > +	struct mem_cgroup *memcg;
> > > > +	bool success = false;
> > > > +	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
> > > > +
> > > > +	VM_BUG_ON(!current_is_kswapd());
> > > > +
> > > > +	current->reclaim_state->mm_walk = &pgdat->mm_walk;
> > > > +
> > > > +	memcg = mem_cgroup_iter(NULL, NULL, NULL);
> > > > +	do {
> > > > +		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
> > > > +
> > > > +		if (age_lruvec(lruvec, sc, min_ttl))
> > > > +			success = true;
> > > > +
> > > > +		cond_resched();
> > > > +	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
> > > > +
> > > > +	if (!success && mutex_trylock(&oom_lock)) {
> > > > +		struct oom_control oc = {
> > > > +			.gfp_mask = sc->gfp_mask,
> > > > +			.order = sc->order,
> > > > +		};
> > > > +
> > > > +		if (!oom_reaping_in_progress())
> > > > +			out_of_memory(&oc);
> > > > +
> > > > +		mutex_unlock(&oom_lock);
> > > > +	}
> > > 
> > > Why do you need to trigger oom killer from this path? Why cannot you
> > > rely on the page allocator to do that like we do now?
> > 
> > This is per desktop users' (repeated) requests. The can't tolerate
> > thrashing as servers do because of UI lags; and they usually don't
> > have fancy tools like oomd.
> > 
> > Related discussions I saw:
> > https://github.com/zen-kernel/zen-kernel/issues/218
> > https://lore.kernel.org/lkml/20101028191523.GA14972 at google.com/
> > https://lore.kernel.org/lkml/20211213051521.21f02dd2 at mail.inbox.lv/
> > https://lore.kernel.org/lkml/54C2C89C.8080002 at gmail.com/
> > https://lore.kernel.org/lkml/d9802b6a-949b-b327-c4a6-3dbca485ec20 at gmx.com/
> 
> I do not really see any arguments why an userspace based trashing
> detection cannot be used for those. Could you clarify?

It definitely can be done. But who is going to do it for every distro
and all individual users? AFAIK, not a single distro provides such a
solution for desktop/laptop/phone users.

And also there is the theoretical question how reliable a userspace
solution can be. What if this usespace solution itself gets stuck in
the direct reclaim path. I'm sure if nobody has done some search to
prove or debunk it.

In addition, what exactly PSI values should be used on different
models of consumer electronics? Nobody knows. We have a team working
on this and we haven't figured it out for all our Chromebook models.

As Andrew said, "a blunt instrument like this would be useful".
https://lore.kernel.org/lkml/20211202135824.33d2421bf5116801cfa2040d at linux-foundation.org/

I'd like to have less code in kernel too, but I've learned never to
walk over users. If I remove this and they come after me asking why,
I'd have a hard time convincing them.

> Also my question was pointing to why out_of_memory is called from the
> reclaim rather than the allocator (memcg charging path). It is the
> caller of the reclaim to control different reclaim strategies and tell
> when all the hopes are lost and the oom killer should be invoked. This
> allows for a different policies at the allocator level and this change
> will break that AFAICS. E.g. what if the underlying allocation context
> is __GFP_NORETRY?

This is called in kswapd only, and by default (min_ttl=0) it doesn't
do anything. So __GFP_NORETRY doesn't apply. The question would be
more along the lines of long-term ABI support.

And I'll add the following comments, if you think we can keep this
logic:
   OOM kill if every generation from all memcgs is younger than min_ttl.
   Another theoretical possibility is all memcgs are either below min or
   ineligible at priority 0, but this isn't the main goal.

(Please read my reply at the bottom to decide whether we should keep
 it or not. Thanks.)

> > >From patch 8:
> >   Personal computers
> >   ------------------
> >   :Thrashing prevention: Write ``N`` to
> >    ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
> >    ``N`` milliseconds from getting evicted. The OOM killer is invoked if
> >    this working set can't be kept in memory. Based on the average human
> >    detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
> >    lags due to thrashing. Larger values like ``N=3000`` make lags less
> >    noticeable at the cost of more OOM kills.
> 
> This is a very good example of something that should be a self contained
> patch with its own justification.

Consider it done.

> TBH it is really not all that clear to
> me that we want to provide any user visible knob to control OOM behavior
> based on a time based QoS.

Agreed, and it didn't exist until v4, i.e., after I was demanded to
provide it for several times.

For example:
https://github.com/zen-kernel/zen-kernel/issues/223

And another example:
   Your Multigenerational LRU patchset is pretty complex and
   effective, but does not eliminate thrashing condition fully on an
   old PCs with slow HDD.

   I'm kindly asking you to cooperate with hakavlad if it's possible
   and maybe re-implement parts of le9 patch in your patchset wherever
   acceptable, as they are quite similar in the core concept.

This is excerpt of an email from iam at valdikss.org.ru, and he has
posted demo videos in this discussion:
https://lore.kernel.org/lkml/2dc51fc8-f14e-17ed-a8c6-0ec70423bf54 at valdikss.org.ru/


From axe.yang at mediatek.com  Mon Jan 10 17:40:44 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Tue, 11 Jan 2022 09:40:44 +0800
Subject: [PATCH v2 1/3] dt-bindings: mmc: add cap-sdio-async-irq flag
In-Reply-To: <20220111014046.5864-1-axe.yang@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
Message-ID: <20220111014046.5864-2-axe.yang@mediatek.com>

Asynchronous interrupt is a mechanism that allow SDIO devices alarm
interrupt when host stop providing clock to card. Add a DT flag to
enable this feature if it is supported by SDIO card.

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index 513f3c8758aa..16fb06f88471 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -165,6 +165,11 @@ properties:
     description:
       eMMC hardware reset is supported
 
+  cap-sdio-async-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO async interrupt is supported.
+
   cap-sdio-irq:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.25.1



From axe.yang at mediatek.com  Mon Jan 10 17:40:45 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Tue, 11 Jan 2022 09:40:45 +0800
Subject: [PATCH v2 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20220111014046.5864-1-axe.yang@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
Message-ID: <20220111014046.5864-3-axe.yang@mediatek.com>

If cap-sdio-async-irq flag is set in host dts node, parse EAI
information from SDIO CCCR interrupt externsion segment. If async
interrupt is supported by SDIO card then send command to card to
enable it and set enable_async_irq flag in sdio_cccr structure to 1.
The parse flow is implemented in sdio_read_cccr().

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
 include/linux/mmc/card.h |  3 ++-
 include/linux/mmc/host.h |  1 +
 include/linux/mmc/sdio.h |  5 +++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf140f4ec864..a972241548b4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -410,6 +410,8 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "no-mmc-hs400"))
 		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
 				 MMC_CAP2_HS400_ES);
+	if (device_property_read_bool(dev, "cap-sdio-async-irq"))
+		host->caps2 |= MMC_CAP2_SDIO_ASYNC_IRQ;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 41164748723d..771fb5d18585 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
 			if (data & SDIO_DRIVE_SDTD)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ) {
+				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
+						       &data);
+				if (ret)
+					goto out;
+
+				if (data & SDIO_INTERRUPT_EXT_SAI) {
+					data |= SDIO_INTERRUPT_EXT_EAI;
+					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+							       data, NULL);
+					if (ret)
+						goto out;
+
+					card->cccr.enable_async_irq = 1;
+				}
+			}
 		}
 
 		/* if no uhs mode ensure we check for high speed */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 37f975875102..4df9182bc0e6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,8 @@ struct sdio_cccr {
 				wide_bus:1,
 				high_power:1,
 				high_speed:1,
-				disable_cd:1;
+				disable_cd:1,
+				enable_async_irq:1;
 };
 
 struct sdio_cis {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7afb57cab00b..502a5418264c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -402,6 +402,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SDIO_ASYNC_IRQ	(1 << 29)	/* SDIO host supports asynchronous interrupt */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 2a05d1ac4f0e..1ef400f28642 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -159,6 +159,11 @@
 #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT	0x16
+#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
-- 
2.25.1



From axe.yang at mediatek.com  Mon Jan 10 17:40:43 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Tue, 11 Jan 2022 09:40:43 +0800
Subject: [PATCH v2 0/3]mmc: mediatek: add support for SDIO async irq 
Message-ID: <20220111014046.5864-1-axe.yang@mediatek.com>

Change in v2:
- change flag name from 'cap-sdio-async-int' to 'cap-sdio-async-irq'
- change corresponding macro names from xxx_INT to xxx_IRQ
- resort new member in msdc_host structure
- refine function msdc_request_dat1_eint_irq()
- rename msdc_{suspend,resume} function names, add suffix '_noirq'
- add MMC_CAP2_NO_SDIO judgement before parse eint related pin setting

Axe Yang (3):
  dt-bindings: mmc: add cap-sdio-async-irq flag
  mmc: core: Add support for SDIO async interrupt
  mmc: mediatek: add support for SDIO eint irq

 .../bindings/mmc/mmc-controller.yaml          |   5 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/sdio.c                       |  17 +++
 drivers/mmc/host/mtk-sd.c                     | 124 ++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +-
 include/linux/mmc/host.h                      |   1 +
 include/linux/mmc/sdio.h                      |   5 +
 7 files changed, 148 insertions(+), 9 deletions(-)

-- 
2.18.0



From axe.yang at mediatek.com  Mon Jan 10 17:40:46 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Tue, 11 Jan 2022 09:40:46 +0800
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <20220111014046.5864-1-axe.yang@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
Message-ID: <20220111014046.5864-4-axe.yang@mediatek.com>

Add support for eint irq when MSDC is used as an SDIO host. This
feature requires SDIO device support async irq function. With this
feature,SDIO host can be awakened by SDIO card in suspend state,
without additional pin.

MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
resume, switch GPIO function back to DAT1 mode then turn on clock.

Some device tree property should be added or modified in msdc node
to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
are mandatory. And cap-sdio-async-irq flag is necessary since this
feature depends on asynchronous interrupt:
        &mmcX {
                ...
                pinctrl-names = "default", "state_uhs", "state_eint",
                                "state_dat1";
                ...
                pinctrl-2 = <&mmc2_pins_eint>;
                pinctrl-3 = <&mmc2_pins_dat1>;
                ...
                cap-sdio-async-irq;
                ...
        };

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 124 +++++++++++++++++++++++++++++++++++---
 1 file changed, 116 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 65037e1d7723..d78e05c89c29 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2015 MediaTek Inc.
+ * Copyright (c) 2014-2022 MediaTek Inc.
  * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
  */
 
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -440,8 +441,12 @@ struct msdc_host {
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
+	struct pinctrl_state *pins_eint;
+	struct pinctrl_state *pins_dat1;
 	struct delayed_work req_timeout;
 	int irq;		/* host interrupt */
+	int eint_irq;		/* device interrupt */
+	int sdio_irq_cnt;	/* irq enable cnt */
 	struct reset_control *reset;
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -465,6 +470,7 @@ struct msdc_host {
 	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
+	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 	struct msdc_tune_para def_tune_para; /* default tune setting */
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
@@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	__msdc_enable_sdio_irq(host, enb);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (enb)
-		pm_runtime_get_noresume(host->dev);
-	else
-		pm_runtime_put_noidle(host->dev);
+	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
+		if (enb)
+			pm_runtime_get_noresume(host->dev);
+		else
+			pm_runtime_put_noidle(host->dev);
+	}
 }
 
 static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
@@ -2461,6 +2469,49 @@ static const struct mmc_host_ops mt_msdc_ops = {
 	.hw_reset = msdc_hw_reset,
 };
 
+static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
+{
+	unsigned long flags;
+	struct msdc_host *host = (struct msdc_host *)dev_id;
+	struct mmc_host *mmc = mmc_from_priv(host);
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (likely(host->sdio_irq_cnt > 0)) {
+		disable_irq_nosync(host->eint_irq);
+		disable_irq_wake(host->eint_irq);
+		host->sdio_irq_cnt--;
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	sdio_signal_irq(mmc);
+
+	return IRQ_HANDLED;
+}
+
+static int msdc_request_dat1_eint_irq(struct msdc_host *host)
+{
+	struct gpio_desc *desc;
+	int irq, ret;
+
+	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	ret = gpiod_to_irq(desc);
+	if (ret < 0)
+		return ret;
+
+	irq = ret;
+	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					"sdio-eint", host);
+
+	if (!ret)
+		host->eint_irq = irq;
+
+	return ret;
+}
+
 static const struct cqhci_host_ops msdc_cmdq_ops = {
 	.enable         = msdc_cqe_enable,
 	.disable        = msdc_cqe_disable,
@@ -2631,6 +2682,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO)) {
+		/* Support for SDIO eint irq */
+		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+		if (IS_ERR(host->pins_eint)) {
+			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
+		} else {
+			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
+			if (IS_ERR(host->pins_dat1)) {
+				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
+						    "Cannot find pinctrl dat1!\n");
+				goto host_free;
+			}
+
+			host->sdio_eint_ready = true;
+		}
+	}
+
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
@@ -2722,6 +2790,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto release;
 
+	if (host->sdio_eint_ready) {
+		ret = msdc_request_dat1_eint_irq(host);
+		if (ret) {
+			dev_err(host->dev, "Failed to register data1 eint irq!\n");
+			goto release;
+		}
+
+		pinctrl_select_state(host->pinctrl, host->pins_dat1);
+	}
+
 	pm_runtime_set_active(host->dev);
 	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(host->dev);
@@ -2841,16 +2919,31 @@ static void msdc_restore_reg(struct msdc_host *host)
 
 static int __maybe_unused msdc_runtime_suspend(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 
 	msdc_save_reg(host);
+
+	if (host->sdio_eint_ready) {
+		disable_irq(host->irq);
+		pinctrl_select_state(host->pinctrl, host->pins_eint);
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt == 0) {
+			enable_irq(host->eint_irq);
+			enable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt++;
+		}
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 	msdc_gate_clock(host);
 	return 0;
 }
 
 static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
@@ -2860,10 +2953,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 		return ret;
 
 	msdc_restore_reg(host);
+
+	if (host->sdio_eint_ready) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt > 0) {
+			disable_irq_nosync(host->eint_irq);
+			disable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt--;
+			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		} else {
+			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+		enable_irq(host->irq);
+	}
 	return 0;
 }
 
-static int __maybe_unused msdc_suspend(struct device *dev)
+static int __maybe_unused msdc_suspend_noirq(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret;
@@ -2877,13 +2985,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int __maybe_unused msdc_resume(struct device *dev)
+static int __maybe_unused msdc_resume_noirq(struct device *dev)
 {
 	return pm_runtime_force_resume(dev);
 }
 
 static const struct dev_pm_ops msdc_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-- 
2.25.1



From torvalds at linux-foundation.org  Mon Jan 10 17:41:58 2022
From: torvalds at linux-foundation.org (Linus Torvalds)
Date: Mon, 10 Jan 2022 17:41:58 -0800
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <CAJmaN=n=kn9-gC8if5wp8Gfj7uN+QVrX0ex=9JPXC7rPvGf1Qg@mail.gmail.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
 <YdgKClGAuHlkzVbQ@dhcp22.suse.cz> <YdiKVJlClB3h1Kmg@google.com>
 <YdxTR4+FL08XyFuO@dhcp22.suse.cz> <YdythmxHpSksJiXs@google.com>
 <CAJmaN=n=kn9-gC8if5wp8Gfj7uN+QVrX0ex=9JPXC7rPvGf1Qg@mail.gmail.com>
Message-ID: <CAHk-=whAOM+xQm9vMe33qf8X1LX2QQZ7RBgKe_KH2C3LB=6Jdw@mail.gmail.com>

On Mon, Jan 10, 2022 at 2:46 PM Jesse Barnes <jsbarnes at google.com> wrote:
>
> So unless we want to eschew big mm changes entirely (we shouldn't!
> look at net or scheduling for how important big rewrites are to
> progress), I think we should be open to experimenting with new stuff.

So I personally think this is worth going with, partly simply due to
the reported improvements that have been measured.

But also to a large extent because the whole notion of doing
multi-generational LRU isn't exactly some wackadoodle crazy thing. We
already do active vs inactive, the whole multi-generational thing just
doesn't seem to be so "far out".

 But yes, numbers talk, and I get the feeling that we just need to try
it. Maybe not 5.17, but..

           Linus


From leilk.liu at mediatek.com  Mon Jan 10 17:48:49 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 11 Jan 2022 09:48:49 +0800
Subject: [PATCH 1/2] dt-bindings: spi: Convert spi-mt65xx &
 spi-slave-mt27xx to json-schema
In-Reply-To: <1641833339.690847.1067453.nullmailer@robh.at.kernel.org>
References: <20220110053744.30323-1-leilk.liu@mediatek.com>
 <1641833339.690847.1067453.nullmailer@robh.at.kernel.org>
Message-ID: <f9ee59dab63c33001b196e56fd55aa890948ddcd.camel@mediatek.com>

On Mon, 2022-01-10 at 10:48 -0600, Rob Herring wrote:
> On Mon, 10 Jan 2022 13:37:43 +0800, Leilk Liu wrote:
> > Convert Mediatek ARM SOC's SPI Master & Slave controller binding
> > to json-schema format.
> > 
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> > ---
> >  .../bindings/spi/mediatek,spi-mt65xx.yaml     | 96
> > +++++++++++++++++++
> >  .../spi/mediatek,spi-slave-mt27xx.yaml        | 69 +++++++++++++
> >  .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
> >  .../bindings/spi/spi-slave-mt27xx.txt         | 33 -------
> >  4 files changed, 165 insertions(+), 101 deletions(-)
> >  create mode 100644
> > Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
> >  create mode 100644
> > Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> > mt27xx.yaml
> >  delete mode 100644 Documentation/devicetree/bindings/spi/spi-
> > mt65xx.txt
> >  delete mode 100644 Documentation/devicetree/bindings/spi/spi-
> > slave-mt27xx.txt
> > 
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-
> review/Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> mt27xx.yaml: properties:compatible:oneOf: [{'const':
> 'mediatek,mt2712-spi-slave'}, {'const': 'mediatek,mt8195-spi-slave'}] 
> should not be valid under {'items': {'propertyNames': {'const':
> 'const'}, 'required': ['const']}}
> 	hint: Use 'enum' rather than 'oneOf' + 'const' entries
> 	from schema $id: 
> http://devicetree.org/meta-schemas/keywords.yaml#
> /builds/robherring/linux-dt-
> review/Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> mt27xx.yaml: ignoring, error in schema: properties: compatible: oneOf
> Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> mt27xx.example.dt.yaml:0:0: /example-0/spi at 10013000: failed to match
> any schema with compatible: ['mediatek,mt2712-spi-slave']
> 
> doc reference errors (make refcheckdocs):
> 
> See https://patchwork.ozlabs.org/patch/1577767
> 
> This check can fail if there are any dependencies. The base for a
> patch
> series is generally the most recent rc1.
> 
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up
> to
> date:
> 
> pip3 install dtschema --upgrade
> 
> Please check and re-submit.

OK, I'll re-send it, thanks

> 

From guoren at kernel.org  Mon Jan 10 18:42:51 2022
From: guoren at kernel.org (Guo Ren)
Date: Tue, 11 Jan 2022 10:42:51 +0800
Subject: [PATCH V2 11/17] riscv: compat: Add elf.h implementation
In-Reply-To: <CAK8P3a0H2Nq=bFdzWGzzGuFWP85JA7=Td6_rb8GqOF3bYCRJBw@mail.gmail.com>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-12-guoren@kernel.org>
 <CAK8P3a0H2Nq=bFdzWGzzGuFWP85JA7=Td6_rb8GqOF3bYCRJBw@mail.gmail.com>
Message-ID: <CAJF2gTQCJ2W2wgdTVpdCoD0ycTkRd1jvfweknjq=t+PrW8QjKg@mail.gmail.com>

On Mon, Jan 10, 2022 at 10:29 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > Implement necessary type and macro for compat elf. See the code
> > comment for detail.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Cc: Arnd Bergmann <arnd at arndb.de>
>
> This looks mostly correct,
>
> > +/*
> > + * FIXME: not sure SET_PERSONALITY for compat process is right!
> > + */
> > +#define SET_PERSONALITY(ex)                                               \
> > +do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)                         \
> > +               set_thread_flag(TIF_32BIT);                                \
> > +       else                                                               \
> > +               clear_thread_flag(TIF_32BIT);                              \
> > +       set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
> > +} while (0)
>
> This means the personality after exec is always set to PER_LINUX, not
> PER_LINUX32, which I think is wrong: you want the PER_LINUX32
> setting to stick, just like the upper bits do in the default implementation.
>
> What the other ones do is:
>
> | arch/parisc/include/asm/elf.h-
> set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
>
> This looks like the same problem you introduce here: always forcing PER_LINUX
> instead of PER_LINUX32 makes it impossible to use PER_LINUX32.
>
> | arch/alpha/include/asm/elf.h:#define SET_PERSONALITY(EX)
>                            \
> | arch/alpha/include/asm/elf.h-   set_personality(((EX).e_flags &
> EF_ALPHA_32BIT)         \
> | arch/alpha/include/asm/elf.h-      ? PER_LINUX_32BIT : PER_LINUX)
> | arch/csky/include/asm/elf.h:#define SET_PERSONALITY(ex)
> set_personality(PER_LINUX)
> | arch/nds32/include/asm/elf.h:#define SET_PERSONALITY(ex)
> set_personality(PER_LINUX)
>
> These look even worse: instead of forcing the lower bits to
> PER_LINUX/PER_LINUX32 and
> leaving the upper bits untouched, these also clear the upper bits
> unconditionally.
>
> | arch/arm64/include/asm/elf.h:#define SET_PERSONALITY(ex)
>                                    \
> | arch/arm64/include/asm/elf.h-   current->personality &=
> ~READ_IMPLIES_EXEC;                     \
> | arch/x86/um/asm/elf.h:#define SET_PERSONALITY(ex) do {} while(0)
> | arch/x86/include/asm/elf.h:#define set_personality_64bit()      do {
> } while (0)
> | arch/x86/kernel/process_64.c:static void __set_personality_ia32(void)
> |         current->personality |= force_personality32;
>
> Inconsistent: does not enforce PER_LINUX/PER_LINUX32 as the default
> implementation
> does, but just leaves the value untouched (other than (re)setting
> READ_IMPLIES_EXEC).
> I think this is harmless otherwise, as we generally ignore the lower
> bits, except for the
> bit of code that checks for PER_LINUX32 in override_architecture() to mangle the
> output of sys_newuname() or in /proc/cpuinfo.
>
> | arch/s390/include/asm/elf.h-    if
> (personality(current->personality) != PER_LINUX32)   \
> | arch/s390/include/asm/elf.h-            set_personality(PER_LINUX |
>                    \
> | arch/s390/include/asm/elf.h-
> (current->personality & ~PER_MASK));    \
> | arch/powerpc/include/asm/elf.h- if
> (personality(current->personality) != PER_LINUX32)   \
> | arch/powerpc/include/asm/elf.h-         set_personality(PER_LINUX |
>                    \
> | arch/powerpc/include/asm/elf.h-
> (current->personality & (~PER_MASK)));  \
> | arch/sparc/include/asm/elf_64.h-        if
> (personality(current->personality) != PER_LINUX32)   \
> | arch/sparc/include/asm/elf_64.h-
> set_personality(PER_LINUX |             \
> | arch/sparc/include/asm/elf_64.h-
> (current->personality & (~PER_MASK)));  \
>
> This is probably the behavior you want to copy.
Thank you very much for your detailed explanation. Here is my modification.

+#define SET_PERSONALITY(ex)                                    \
+do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)              \
+               set_thread_flag(TIF_32BIT);                     \
+       else                                                    \
+               clear_thread_flag(TIF_32BIT);                   \
+       if (personality(current->personality) != PER_LINUX32)   \
+               set_personality(PER_LINUX |                     \
+                       (current->personality & (~PER_MASK)));  \
+} while (0)

>
>       Arnd




--
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From guoren at kernel.org  Mon Jan 10 18:43:53 2022
From: guoren at kernel.org (Guo Ren)
Date: Tue, 11 Jan 2022 10:43:53 +0800
Subject: [PATCH V2 03/17] asm-generic: fcntl: compat: Remove duplicate
 definitions
In-Reply-To: <CAK8P3a2zn9M6X09WsjJ9HYiS9WnO_YPCvJLSBk+HaH+yZHQqfA@mail.gmail.com>
References: <20211228143958.3409187-1-guoren@kernel.org>
 <20211228143958.3409187-4-guoren@kernel.org>
 <CAK8P3a2zn9M6X09WsjJ9HYiS9WnO_YPCvJLSBk+HaH+yZHQqfA@mail.gmail.com>
Message-ID: <CAJF2gTTzUV1teCh0Avw7rTsrd=50atKGCdpQsVyEeUus1TeGjA@mail.gmail.com>

On Mon, Jan 10, 2022 at 9:35 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Tue, Dec 28, 2021 at 3:39 PM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
> > arch/*/include/asm/compat.h.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Cc: Arnd Bergmann <arnd at arndb.de>
>
> Unfortunately, this one does not look correct to me:
>
> > @@ -116,7 +116,7 @@
> >  #define F_GETSIG       11      /* for sockets. */
> >  #endif
> >
> > -#ifndef CONFIG_64BIT
> > +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
> >  #ifndef F_GETLK64
> >  #define F_GETLK64      12      /*  using 'struct flock64' */
> >  #define F_SETLK64      13
>
> The problem here is that include/uapi/ headers cannot contain checks for
> CONFIG_* symbols because those may have different meanings in user space
> compared to kernel.
>
> This is a preexisting problem in the header, but I think the change
> makes it worse.
>
> With the current behavior, user space will always see the definitions,
> unless it happens to have its own definition for CONFIG_64BIT already.
> On 64-bit parisc, this has the effect of defining the macros to the
> same values as F_SETOWN/F_SETSIG/F_GETSIG, which is potentially
> harmful. On MIPS, it uses values that are different from the 32-bit numbers
> but are otherwise unused. Everywhere else, we get the definition from
> the 32-bit architecture in user space, which will do nothing in the kernel.
>
> The correct check for a uapi header would be to test for
> __BITS_PER_LONG==32. We should probably do that here, but
> this won't help you move the definitions, and it is a user-visible change
> as the incorrect definition will no longer be visible. [Adding Jeff and Bruce
> (the flock mainainers) to Cc for additional feedback on this]
>
> For your series, I would suggest just moving the macro definitions to
> include/linux/compat.h along with the 'struct compat_flock64'
> definition, and leaving the duplicate one in the uapi header unchanged
> until we have decided on a solution.
Okay.

>
>         Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From marex at denx.de  Mon Jan 10 18:48:02 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 11 Jan 2022 03:48:02 +0100
Subject: [PATCH] ARM: dts: stm32: Add CM4 reserved memory,
 rproc and IPCC on DHCOR SoM
Message-ID: <20220111024802.112583-1-marex@denx.de>

Add reserved memory nodes for CortexM4 on the STM32MP1 DHCOR SoM, enable
rproc to control the CM4 and IPCC mailbox to interact with it.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 56 ++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
index 44ecc47085871..6336c3ca0f0e2 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi
@@ -19,6 +19,48 @@ memory at c0000000 {
 		device_type = "memory";
 		reg = <0xc0000000 0x40000000>;
 	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		mcuram2: mcuram2 at 10000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10000000 0x40000>;
+			no-map;
+		};
+
+		vdev0vring0: vdev0vring0 at 10040000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10040000 0x1000>;
+			no-map;
+		};
+
+		vdev0vring1: vdev0vring1 at 10041000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10041000 0x1000>;
+			no-map;
+		};
+
+		vdev0buffer: vdev0buffer at 10042000 {
+			compatible = "shared-dma-pool";
+			reg = <0x10042000 0x4000>;
+			no-map;
+		};
+
+		mcuram: mcuram at 30000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x30000000 0x40000>;
+			no-map;
+		};
+
+		retram: retram at 38000000 {
+			compatible = "shared-dma-pool";
+			reg = <0x38000000 0x10000>;
+			no-map;
+		};
+	};
 };
 
 &crc1 {
@@ -179,11 +221,25 @@ eeprom at 53 {
 	};
 };
 
+&ipcc {
+	status = "okay";
+};
+
 &iwdg2 {
 	timeout-sec = <32>;
 	status = "okay";
 };
 
+&m4_rproc {
+	memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+			<&vdev0vring1>, <&vdev0buffer>;
+	mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+	mbox-names = "vq0", "vq1", "shutdown";
+	interrupt-parent = <&exti>;
+	interrupts = <68 1>;
+	status = "okay";
+};
+
 &pwr_regulators {
 	vdd-supply = <&vdd>;
 	vdd_3v3_usbfs-supply = <&vdd_usb>;
-- 
2.34.1



From yu.tu at amlogic.com  Mon Jan 10 18:48:41 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 10:48:41 +0800
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
 <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
Message-ID: <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>

Hi Jiri ,
	Thank you very much for your reply.

On 2022/1/10 19:58, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> On 10. 01. 22, 11:42, Yu Tu wrote:
>> This simplifies resetting the UART controller during probe
>> and will make it easier to integrate the common clock code
>> which will require the registers at probe time as well.
> 
> And you are *also* switching devm_request_mem_region+devm_ioremap into 
> devm_ioremap_resource without even noting it here. It should've been 
> done in a separate patch.
> 
I can change it as you suggest?
The switching devm_request_mem_region+devm_ioremap into
devm_ioremap_resource in a separate patch.

> And no, do not resend a new version in the next few days. Having v5 in 
> 20 days is a bit too much. Give maintainers and reviewers some more 
> space to express themselves.
I am so sorry if PATCH is sent too frequently, which has disturbed you.
How often should I send it? Or under what circumstances can I send the 
next version?

>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>> ? drivers/tty/serial/meson_uart.c | 24 ++++++------------------
>> ? 1 file changed, 6 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c 
>> b/drivers/tty/serial/meson_uart.c
>> index 45e00d928253..7570958d010c 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct 
>> uart_port *port,
>> ? static void meson_uart_release_port(struct uart_port *port)
>> ? {
>> -??? devm_iounmap(port->dev, port->membase);
>> -??? port->membase = NULL;
>> -??? devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
>> +??? /* nothing to do */
>> ? }
>> ? static int meson_uart_request_port(struct uart_port *port)
>> ? {
>> -??? if (!devm_request_mem_region(port->dev, port->mapbase, 
>> port->mapsize,
>> -???????????????????? dev_name(port->dev))) {
>> -??????? dev_err(port->dev, "Memory region busy\n");
>> -??????? return -EBUSY;
>> -??? }
>> -
>> -??? port->membase = devm_ioremap(port->dev, port->mapbase,
>> -???????????????????????? port->mapsize);
>> -??? if (!port->membase)
>> -??????? return -ENOMEM;
>> -
>> ????? return 0;
>> ? }
>> @@ -733,6 +720,10 @@ static int meson_uart_probe(struct 
>> platform_device *pdev)
>> ????? if (!port)
>> ????????? return -ENOMEM;
>> +??? port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>> +??? if (IS_ERR(port->membase))
>> +??????? return PTR_ERR(port->membase);
>> +
>> ????? ret = meson_uart_probe_clocks(pdev, port);
>> ????? if (ret)
>> ????????? return ret;
>> @@ -754,10 +745,7 @@ static int meson_uart_probe(struct 
>> platform_device *pdev)
>> ????? platform_set_drvdata(pdev, port);
>> ????? /* reset port before registering (and possibly registering 
>> console) */
>> -??? if (meson_uart_request_port(port) >= 0) {
>> -??????? meson_uart_reset(port);
>> -??????? meson_uart_release_port(port);
>> -??? }
>> +??? meson_uart_reset(port);
>> ????? ret = uart_add_one_port(&meson_uart_driver, port);
>> ????? if (ret)
> 
> thanks,


From conleylee at foxmail.com  Mon Jan 10 19:05:53 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Tue, 11 Jan 2022 11:05:53 +0800
Subject: [PATCH v3] net: ethernet: sun4i-emac: replace magic number with macro
In-Reply-To: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
Message-ID: <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>

This patch remove magic numbers in sun4i-emac.c and replace with macros
defined in sun4i-emac.h

Signed-off-by: Conley Lee <conleylee at foxmail.com>
---
Change since v2.
- fix some code style issues

Change since v1.
- reformat
- merge commits
- add commit message

---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
 drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
 2 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 849de4564709..74635a6fa8ca 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -106,9 +106,9 @@ static void emac_update_speed(struct net_device *dev)
 
 	/* set EMAC SPEED, depend on PHY  */
 	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
-	reg_val &= ~(0x1 << 8);
+	reg_val &= ~EMAC_MAC_SUPP_100M;
 	if (db->speed == SPEED_100)
-		reg_val |= 1 << 8;
+		reg_val |= EMAC_MAC_SUPP_100M;
 	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
 }
 
@@ -264,7 +264,7 @@ static void emac_dma_done_callback(void *arg)
 
 	/* re enable interrupt */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0x01 << 8);
+	reg_val |= EMAC_INT_CTL_RX_EN;
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	db->emacrx_completed_flag = 1;
@@ -429,7 +429,7 @@ static unsigned int emac_powerup(struct net_device *ndev)
 	/* initial EMAC */
 	/* flush RX FIFO */
 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
-	reg_val |= 0x8;
+	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
 	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
 	udelay(1);
 
@@ -441,8 +441,8 @@ static unsigned int emac_powerup(struct net_device *ndev)
 
 	/* set MII clock */
 	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
-	reg_val &= (~(0xf << 2));
-	reg_val |= (0xD << 2);
+	reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK;
+	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
 	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
 
 	/* clear RX counter */
@@ -506,7 +506,7 @@ static void emac_init_device(struct net_device *dev)
 
 	/* enable RX/TX0/RX Hlevel interrup */
 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-	reg_val |= (0xf << 0) | (0x01 << 8);
+	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 	spin_unlock_irqrestore(&db->lock, flags);
@@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
 		if (!rxcount) {
 			db->emacrx_completed_flag = 1;
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN |
+					EMAC_INT_CTL_TX_ABRT_EN |
+					EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			/* had one stuck? */
@@ -669,7 +671,9 @@ static void emac_rx(struct net_device *dev)
 			writel(reg_val | EMAC_CTL_RX_EN,
 			       db->membase + EMAC_CTL_REG);
 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-			reg_val |= (0xf << 0) | (0x01 << 8);
+			reg_val |= (EMAC_INT_CTL_TX_EN |
+					EMAC_INT_CTL_TX_ABRT_EN |
+					EMAC_INT_CTL_RX_EN);
 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 
 			db->emacrx_completed_flag = 1;
@@ -783,20 +787,20 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
 	}
 
 	/* Transmit Interrupt check */
-	if (int_status & (0x01 | 0x02))
+	if (int_status & EMAC_INT_STA_TX_COMPLETE)
 		emac_tx_done(dev, db, int_status);
 
-	if (int_status & (0x04 | 0x08))
+	if (int_status & EMAC_INT_STA_TX_ABRT)
 		netdev_info(dev, " ab : %x\n", int_status);
 
 	/* Re-enable interrupt mask */
 	if (db->emacrx_completed_flag == 1) {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0) | (0x01 << 8);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	} else {
 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
-		reg_val |= (0xf << 0);
+		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
 	}
 
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
index 38c72d9ec600..90bd9ad77607 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.h
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
@@ -38,6 +38,7 @@
 #define EMAC_RX_CTL_REG		(0x3c)
 #define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
 #define EMAC_RX_CTL_DMA_EN		(1 << 2)
+#define EMAC_RX_CTL_FLUSH_FIFO		(1 << 3)
 #define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
 #define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
 #define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
@@ -61,7 +62,21 @@
 #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
 #define EMAC_RX_FBC_REG		(0x50)
 #define EMAC_INT_CTL_REG	(0x54)
+#define EMAC_INT_CTL_RX_EN	(1 << 8)
+#define EMAC_INT_CTL_TX0_EN	(1)
+#define EMAC_INT_CTL_TX1_EN	(1 << 1)
+#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
+#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
+#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
+#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
 #define EMAC_INT_STA_REG	(0x58)
+#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
+#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
+#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
+#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
+#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
+#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
+#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
 #define EMAC_MAC_CTL0_REG	(0x5c)
 #define EMAC_MAC_CTL0_RX_FLOW_CTL_EN	(1 << 2)
 #define EMAC_MAC_CTL0_TX_FLOW_CTL_EN	(1 << 3)
@@ -87,8 +102,11 @@
 #define EMAC_MAC_CLRT_RM		(0x0f)
 #define EMAC_MAC_MAXF_REG	(0x70)
 #define EMAC_MAC_SUPP_REG	(0x74)
+#define EMAC_MAC_SUPP_100M	(0x1 << 8)
 #define EMAC_MAC_TEST_REG	(0x78)
 #define EMAC_MAC_MCFG_REG	(0x7c)
+#define EMAC_MAC_MCFG_MII_CLKD_MASK	(0xff << 2)
+#define EMAC_MAC_MCFG_MII_CLKD_72	(0x0d << 2)
 #define EMAC_MAC_A0_REG		(0x98)
 #define EMAC_MAC_A1_REG		(0x9c)
 #define EMAC_MAC_A2_REG		(0xa0)
-- 
2.31.1



From yu.tu at amlogic.com  Mon Jan 10 19:13:52 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 11:13:52 +0800
Subject: [PATCH V5 3/5] tty: serial: meson: Using the common clock code
 describe.
In-Reply-To: <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-4-yu.tu@amlogic.com>
 <327f985f-bbf1-00ba-d203-cc9d5bbd955c@kernel.org>
Message-ID: <2710be28-3e01-081d-a726-b37b7c053f96@amlogic.com>

Hi Jiri,
	Thank you very much for your reply.

On 2022/1/10 20:11, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi,
> 
> "Subject: Using the common clock code describe."
> 
> Please reformulate that ^^^ -- I cannot make any sense of it. And avoid 
> adding a period to the subject. PLease see others' commit logs.
> 
I will correct this in the next version.

> On 10. 01. 22, 11:42, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> 
> 
> 
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>> ? drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>> ? 1 file changed, 163 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c 
>> b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..1004fd0b0c9e 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>> ?? */
>> ? #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> ? #include <linux/console.h>
>> ? #include <linux/delay.h>
>> ? #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>> ? #define AML_UART_RECV_IRQ(c)??????? ((c) & 0xff)
>> ? /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK??????? 0x7fffff
>> ? #define AML_UART_BAUD_USE??????? BIT(23)
>> -#define AML_UART_BAUD_XTAL??????? BIT(24)
>> ? #define AML_UART_PORT_NUM??????? 12
>> ? #define AML_UART_PORT_OFFSET??????? 6
>> @@ -76,6 +75,13 @@
>> ? #define AML_UART_POLL_USEC??????? 5
>> ? #define AML_UART_TIMEOUT_USEC??????? 10000
>> +struct meson_uart_data {
>> +??? struct uart_port??? port;
>> +??? struct clk??????? *pclk;
>> +??? struct clk??????? *baud_clk;
>> +??? bool??????????? use_xtal_clk;
>> +};
>> +
>> ? static struct uart_driver meson_uart_driver;
>> ? static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port 
>> *port)
>> ? static int meson_uart_startup(struct uart_port *port)
>> ? {
>> ????? u32 val;
>> -??? int ret = 0;
>> +??? int ret;
>> -??? val = readl(port->membase + AML_UART_CONTROL);
>> -??? val |= AML_UART_CLEAR_ERR;
>> -??? writel(val, port->membase + AML_UART_CONTROL);
>> -??? val &= ~AML_UART_CLEAR_ERR;
>> -??? writel(val, port->membase + AML_UART_CONTROL);
>> +??? meson_uart_reset(port);
> 
> Why is this OK? We didn't use to reset it.
This change simply optimizes the code. Because the meson_uart_reset 
function has implemented the control logic.
> 
> And why is this not done in a separate patch?
I will consider merging with the previous patch as a patch.
> 
> 
>> +??? val = readl(port->membase + AML_UART_CONTROL);
>> ????? val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>> ????? writel(val, port->membase + AML_UART_CONTROL);
>> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port 
>> *port)
>> ? static void meson_uart_change_speed(struct uart_port *port, unsigned 
>> long baud)
>> ? {
>> +??? struct meson_uart_data *private_data = port->private_data;
>> ????? u32 val;
>> ????? while (!meson_uart_tx_empty(port))
>> ????????? cpu_relax();
>> -??? if (port->uartclk == 24000000) {
>> -??????? val = ((port->uartclk / 3) / baud) - 1;
>> -??????? val |= AML_UART_BAUD_XTAL;
>> -??? } else {
>> -??????? val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -??? }
>> +??? val = readl(port->membase + AML_UART_REG5);
>> ????? val |= AML_UART_BAUD_USE;
>> ????? writel(val, port->membase + AML_UART_REG5);
>> +
>> +??? clk_set_rate(private_data->baud_clk, baud);
>> ? }
>> ? static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct 
>> uart_port *port,
>> ? static void meson_uart_release_port(struct uart_port *port)
>> ? {
>> -??? /* nothing to do */
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +
>> +??? clk_disable_unprepare(private_data->baud_clk);
>> +??? clk_disable_unprepare(private_data->pclk);
>> ? }
>> ? static int meson_uart_request_port(struct uart_port *port)
>> ? {
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +??? int ret;
>> +
>> +??? ret = clk_prepare_enable(private_data->pclk);
>> +??? if (ret)
>> +??????? return ret;
>> +
>> +??? ret = clk_prepare_enable(private_data->baud_clk);
>> +??? if (ret) {
>> +??????? clk_disable_unprepare(private_data->pclk);
>> +??????? return ret;
>> +??? }
>> +
>> ????? return 0;
>> ? }
>> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>> ????? .cons??????? = MESON_SERIAL_CONSOLE,
>> ? };
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -???????????????????????? const char *id)
>> +#define CLK_NAME(name) \
>> +({\
>> +??? char clk_name[32];\
>> +??? snprintf(clk_name, sizeof(clk_name), "%s#%s", 
>> dev_name(port->dev), #name);\
>> +??? clk_name;\
>> +})
> 
> This is cryptic and duplicates the variable on the stack. Why not expand 
> the macro and delete it then?
> 
I've overdone it. I'll move it to the meson_uart_probe_clocks function 
as you suggested and delete it.
>> +
>> +static struct clk_div_table xtal_div_table[] = {
>> +??? { 0, 3? },
> 
> An extra space here and there:
> 
>> +??? { 1, 1? },
>> +??? { 2, 2? },
>> +??? { 3, 2? },
>> +};
>> +
Sorry, stupid mistake. I will correct.

>> +static int meson_uart_probe_clocks(struct uart_port *port)
>> ? {
>> -??? struct clk *clk = NULL;
>> -??? int ret;
>> +??? struct meson_uart_data *private_data = port->private_data;
>> +??? struct clk *clk_baud, *clk_xtal;
>> +??? struct clk_hw *hw;
>> +??? struct clk_parent_data use_xtal_mux_parents[2] = {
>> +??????? { .index = -1, },
>> +??????? { .index = -1, },
>> +??? };
>> -??? clk = devm_clk_get(dev, id);
>> -??? if (IS_ERR(clk))
>> -??????? return clk;
>> +??? private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +??? if (IS_ERR(private_data->pclk))
>> +??????? return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +???????????????????? "Failed to get the 'pclk' clock\n");
>> -??? ret = clk_prepare_enable(clk);
>> -??? if (ret) {
>> -??????? dev_err(dev, "couldn't enable clk\n");
>> -??????? return ERR_PTR(ret);
>> +??? clk_baud = devm_clk_get(port->dev, "baud");
>> +??? if (IS_ERR(clk_baud)) {
>> +??????? dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +??????? return PTR_ERR(clk_baud);
>> ????? }
>> -??? devm_add_action_or_reset(dev,
>> -??????????? (void(*)(void *))clk_disable_unprepare,
>> -??????????? clk);
>> -
>> -??? return clk;
>> -}
>> -
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -?????????????????? struct uart_port *port)
>> -{
>> -??? struct clk *clk_xtal = NULL;
>> -??? struct clk *clk_pclk = NULL;
>> -??? struct clk *clk_baud = NULL;
>> -
>> -??? clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -??? if (IS_ERR(clk_pclk))
>> -??????? return PTR_ERR(clk_pclk);
>> -
>> -??? clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +??? clk_xtal = devm_clk_get(port->dev, "xtal");
>> ????? if (IS_ERR(clk_xtal))
>> -??????? return PTR_ERR(clk_xtal);
>> -
>> -??? clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -??? if (IS_ERR(clk_baud))
>> -??????? return PTR_ERR(clk_baud);
>> +??????? return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +???????????????????? "Failed to get the 'xtal' clock\n");
>> +
>> +??? if (private_data->use_xtal_clk) {
>> +??????? hw = devm_clk_hw_register_divider_table(port->dev,
>> +??????????????????????????? CLK_NAME(xtal_div),
>> +??????????????????????????? __clk_get_name(clk_baud),
>> +??????????????????????????? CLK_SET_RATE_NO_REPARENT,
>> +??????????????????????????? port->membase + AML_UART_REG5,
>> +??????????????????????????? 26, 2,
>> +??????????????????????????? CLK_DIVIDER_READ_ONLY,
>> +??????????????????????????? xtal_div_table, NULL);
>> +??????? if (IS_ERR(hw))
>> +??????????? return PTR_ERR(hw);
>> +
>> +??????? use_xtal_mux_parents[1].hw = hw;
>> +??? } else {
>> +??????? hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +?????????????????????????????? CLK_NAME(clk81_div4),
>> +?????????????????????????????? __clk_get_name(clk_baud),
>> +?????????????????????????????? CLK_SET_RATE_NO_REPARENT,
>> +?????????????????????????????? 1, 4);
>> +??????? if (IS_ERR(hw))
>> +??????????? return PTR_ERR(hw);
>> +
>> +??????? use_xtal_mux_parents[0].hw = hw;
>> +??? }
>> -??? port->uartclk = clk_get_rate(clk_baud);
>> +??? hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +??????????????????? CLK_NAME(use_xtal),
>> +??????????????????? ARRAY_SIZE(use_xtal_mux_parents),
>> +??????????????????? NULL, NULL,
>> +??????????????????? use_xtal_mux_parents,
>> +??????????????????? CLK_SET_RATE_PARENT,
>> +??????????????????? port->membase + AML_UART_REG5,
>> +??????????????????? 24, 0x1,
>> +??????????????????? CLK_MUX_READ_ONLY,
>> +??????????????????? NULL, NULL);
>> +??? if (IS_ERR(hw))
>> +??????? return PTR_ERR(hw);
>> +
>> +??? port->uartclk = clk_hw_get_rate(hw);
>> +
>> +??? hw = devm_clk_hw_register_divider(port->dev,
>> +????????????????????? CLK_NAME(baud_div),
>> +????????????????????? clk_hw_get_name(hw),
>> +????????????????????? CLK_SET_RATE_PARENT,
>> +????????????????????? port->membase + AML_UART_REG5,
>> +????????????????????? 0, 23,
>> +????????????????????? CLK_DIVIDER_ROUND_CLOSEST,
>> +????????????????????? NULL);
>> +??? if (IS_ERR(hw))
>> +??????? return PTR_ERR(hw);
>> +
>> +??? private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>> ????? return 0;
>> ? }
> 
> 
> 


From conleylee at foxmail.com  Mon Jan 10 19:19:52 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Tue, 11 Jan 2022 11:19:52 +0800
Subject: [PATCH v2] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <Ydw7EzPvwArW/siQ@Red>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_AEEE0573A5455BBE4D5C05226C6C1E3AEF08@qq.com>
 <Ydw7EzPvwArW/siQ@Red>
Message-ID: <tencent_1A43F59DA700A4F4602BBA89B3C096CDC405@qq.com>

On 01/10/22 at 02:56??, Corentin Labbe wrote:
> Date: Mon, 10 Jan 2022 14:56:35 +0100
> From: Corentin Labbe <clabbe.montjoie at gmail.com>
> To: Conley Lee <conleylee at foxmail.com>
> Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
>  wens at csie.org, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v2] net: ethernet: sun4i-emac: replace magic number
>  with macro
> 
> Le Mon, Jan 10, 2022 at 07:35:49PM +0800, Conley Lee a ?crit :
> > This patch remove magic numbers in sun4i-emac.c and replace with macros
> > defined in sun4i-emac.h
> > 
> > Change since v1
> > ---------------
> > - reformat
> > - merge commits
> > - add commit message
> > 
> > Signed-off-by: Conley Lee <conleylee at foxmail.com>
> > ---
> >  drivers/net/ethernet/allwinner/sun4i-emac.c | 30 ++++++++++++---------
> >  drivers/net/ethernet/allwinner/sun4i-emac.h | 18 +++++++++++++
> >  2 files changed, 35 insertions(+), 13 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
> > index 849de4564709..98fd98feb439 100644
> > --- a/drivers/net/ethernet/allwinner/sun4i-emac.c
> > +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
> > @@ -106,9 +106,9 @@ static void emac_update_speed(struct net_device *dev)
> >  
> >  	/* set EMAC SPEED, depend on PHY  */
> >  	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
> > -	reg_val &= ~(0x1 << 8);
> > +	reg_val &= ~EMAC_MAC_SUPP_100M;
> >  	if (db->speed == SPEED_100)
> > -		reg_val |= 1 << 8;
> > +		reg_val |= EMAC_MAC_SUPP_100M;
> >  	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
> >  }
> >  
> > @@ -264,7 +264,7 @@ static void emac_dma_done_callback(void *arg)
> >  
> >  	/* re enable interrupt */
> >  	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -	reg_val |= (0x01 << 8);
> > +	reg_val |= EMAC_INT_CTL_RX_EN;
> >  	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  
> >  	db->emacrx_completed_flag = 1;
> > @@ -429,7 +429,7 @@ static unsigned int emac_powerup(struct net_device *ndev)
> >  	/* initial EMAC */
> >  	/* flush RX FIFO */
> >  	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
> > -	reg_val |= 0x8;
> > +	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
> >  	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
> >  	udelay(1);
> >  
> > @@ -441,8 +441,8 @@ static unsigned int emac_powerup(struct net_device *ndev)
> >  
> >  	/* set MII clock */
> >  	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
> > -	reg_val &= (~(0xf << 2));
> > -	reg_val |= (0xD << 2);
> > +	reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK;
> > +	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
> >  	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
> >  
> >  	/* clear RX counter */
> > @@ -506,7 +506,7 @@ static void emac_init_device(struct net_device *dev)
> >  
> >  	/* enable RX/TX0/RX Hlevel interrup */
> >  	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -	reg_val |= (0xf << 0) | (0x01 << 8);
> > +	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
> >  	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  
> >  	spin_unlock_irqrestore(&db->lock, flags);
> > @@ -637,7 +637,9 @@ static void emac_rx(struct net_device *dev)
> >  		if (!rxcount) {
> >  			db->emacrx_completed_flag = 1;
> >  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -			reg_val |= (0xf << 0) | (0x01 << 8);
> > +			reg_val |=
> > +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> > +				 EMAC_INT_CTL_RX_EN);
> >  			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  
> >  			/* had one stuck? */
> > @@ -669,7 +671,9 @@ static void emac_rx(struct net_device *dev)
> >  			writel(reg_val | EMAC_CTL_RX_EN,
> >  			       db->membase + EMAC_CTL_REG);
> >  			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -			reg_val |= (0xf << 0) | (0x01 << 8);
> > +			reg_val |=
> > +				(EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN |
> > +				 EMAC_INT_CTL_RX_EN);
> >  			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  
> >  			db->emacrx_completed_flag = 1;
> > @@ -783,20 +787,20 @@ static irqreturn_t emac_interrupt(int irq, void *dev_id)
> >  	}
> >  
> >  	/* Transmit Interrupt check */
> > -	if (int_status & (0x01 | 0x02))
> > +	if (int_status & EMAC_INT_STA_TX_COMPLETE)
> >  		emac_tx_done(dev, db, int_status);
> >  
> > -	if (int_status & (0x04 | 0x08))
> > +	if (int_status & EMAC_INT_STA_TX_ABRT)
> >  		netdev_info(dev, " ab : %x\n", int_status);
> >  
> >  	/* Re-enable interrupt mask */
> >  	if (db->emacrx_completed_flag == 1) {
> >  		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -		reg_val |= (0xf << 0) | (0x01 << 8);
> > +		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
> >  		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  	} else {
> >  		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
> > -		reg_val |= (0xf << 0);
> > +		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
> >  		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
> >  	}
> >  
> > diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.h b/drivers/net/ethernet/allwinner/sun4i-emac.h
> > index 38c72d9ec600..90bd9ad77607 100644
> > --- a/drivers/net/ethernet/allwinner/sun4i-emac.h
> > +++ b/drivers/net/ethernet/allwinner/sun4i-emac.h
> > @@ -38,6 +38,7 @@
> >  #define EMAC_RX_CTL_REG		(0x3c)
> >  #define EMAC_RX_CTL_AUTO_DRQ_EN		(1 << 1)
> >  #define EMAC_RX_CTL_DMA_EN		(1 << 2)
> > +#define EMAC_RX_CTL_FLUSH_FIFO		(1 << 3)
> >  #define EMAC_RX_CTL_PASS_ALL_EN		(1 << 4)
> >  #define EMAC_RX_CTL_PASS_CTL_EN		(1 << 5)
> >  #define EMAC_RX_CTL_PASS_CRC_ERR_EN	(1 << 6)
> > @@ -61,7 +62,21 @@
> >  #define EMAC_RX_IO_DATA_STATUS_OK	(1 << 7)
> >  #define EMAC_RX_FBC_REG		(0x50)
> >  #define EMAC_INT_CTL_REG	(0x54)
> > +#define EMAC_INT_CTL_RX_EN	(1 << 8)
> > +#define EMAC_INT_CTL_TX0_EN	(1)
> > +#define EMAC_INT_CTL_TX1_EN	(1 << 1)
> > +#define EMAC_INT_CTL_TX_EN	(EMAC_INT_CTL_TX0_EN | EMAC_INT_CTL_TX1_EN)
> > +#define EMAC_INT_CTL_TX0_ABRT_EN	(0x1 << 2)
> > +#define EMAC_INT_CTL_TX1_ABRT_EN	(0x1 << 3)
> > +#define EMAC_INT_CTL_TX_ABRT_EN	(EMAC_INT_CTL_TX0_ABRT_EN | EMAC_INT_CTL_TX1_ABRT_EN)
> >  #define EMAC_INT_STA_REG	(0x58)
> > +#define EMAC_INT_STA_TX0_COMPLETE	(0x1)
> > +#define EMAC_INT_STA_TX1_COMPLETE	(0x1 << 1)
> > +#define EMAC_INT_STA_TX_COMPLETE	(EMAC_INT_STA_TX0_COMPLETE | EMAC_INT_STA_TX1_COMPLETE)
> > +#define EMAC_INT_STA_TX0_ABRT	(0x1 << 2)
> > +#define EMAC_INT_STA_TX1_ABRT	(0x1 << 3)
> > +#define EMAC_INT_STA_TX_ABRT	(EMAC_INT_STA_TX0_ABRT | EMAC_INT_STA_TX1_ABRT)
> > +#define EMAC_INT_STA_RX_COMPLETE	(0x1 << 8)
> 
> Hello
> 
> As proposed by checkpatch, I thing there are several place (like all EMAC_INT_STA) where you could use BIT(x) instead of (0xX << x)
> 
> Regards
Hi ~ 
Thanks for your suggestion. But I think it might be better to keep the code style consistent,
so I didn't change it in the new version of this patch.


From peng.fan at oss.nxp.com  Mon Jan 10 19:21:47 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:21:47 +0800
Subject: [PATCH] firmware: imx: add get resource owner api
Message-ID: <20220111032147.342012-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add resource owner management API, this API could be used to check
whether M4 is under control of Linux.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/firmware/imx/rm.c           | 45 +++++++++++++++++++++++++++++
 include/linux/firmware/imx/svc/rm.h |  5 ++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/firmware/imx/rm.c b/drivers/firmware/imx/rm.c
index a12db6ff323b..3c3605f98123 100644
--- a/drivers/firmware/imx/rm.c
+++ b/drivers/firmware/imx/rm.c
@@ -43,3 +43,48 @@ bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
 	return hdr->func;
 }
 EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
+
+/*
+ * This function get @resource partition number
+ *
+ * @param[in]     ipc         IPC handle
+ * @param[in]     resource    resource the control is associated with
+ * @param[out]    pt          pointer to return the partition number
+ *
+ * @return Returns 0 for success and < 0 for errors.
+ */
+struct imx_sc_msg_rm_get_resource_owner {
+	struct imx_sc_rpc_msg hdr;
+	union {
+		struct {
+			u16 resource;
+		} req;
+		struct {
+			u8 val;
+		} resp;
+	} data;
+} __packed __aligned(4);
+
+int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
+{
+	struct imx_sc_msg_rm_get_resource_owner msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_RM;
+	hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER;
+	hdr->size = 2;
+
+	msg.data.req.resource = resource;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return ret;
+
+	if (pt)
+		*pt = msg.data.resp.val;
+
+	return 0;
+}
+EXPORT_SYMBOL(imx_sc_rm_get_resource_owner);
diff --git a/include/linux/firmware/imx/svc/rm.h b/include/linux/firmware/imx/svc/rm.h
index 456b6a59d29b..ff481b23ea36 100644
--- a/include/linux/firmware/imx/svc/rm.h
+++ b/include/linux/firmware/imx/svc/rm.h
@@ -59,11 +59,16 @@ enum imx_sc_rm_func {
 
 #if IS_ENABLED(CONFIG_IMX_SCU)
 bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
+int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt);
 #else
 static inline bool
 imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
 {
 	return true;
 }
+static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
+{
+	return -ENOTSUPP;
+}
 #endif
 #endif
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:22 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:22 +0800
Subject: [PATCH V2] remoteproc: imx_rproc: use imx specific hook for
 find_loaded_rsc_table
Message-ID: <20220111033333.403448-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

If there is a resource table device tree node, use the address as
the resource table address, otherwise use the address(where
.resource_table section loaded) inside the Cortex-M elf file.

And there is an update in NXP SDK that Resource Domain Control(RDC)
enabled to protect TCM, linux not able to write the TCM space when
updating resource table status and cause kernel dump. So use the address
from device tree could avoid kernel dump.

Note: NXP M4 SDK not check resource table update, so it does not matter
use whether resource table address specified in elf file or in device
tree. But to reflect the fact that if people specific resource table
address in device tree, it means people are aware and going to use it,
not the address specified in elf file.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V2:
 Update commit message

 drivers/remoteproc/imx_rproc.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 7a096f1891e6..0bd24c937a73 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -499,6 +499,17 @@ static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc
 	return (struct resource_table *)priv->rsc_table;
 }
 
+static struct resource_table *
+imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
+{
+	struct imx_rproc *priv = rproc->priv;
+
+	if (priv->rsc_table)
+		return (struct resource_table *)priv->rsc_table;
+
+	return rproc_elf_find_loaded_rsc_table(rproc, fw);
+}
+
 static const struct rproc_ops imx_rproc_ops = {
 	.prepare	= imx_rproc_prepare,
 	.attach		= imx_rproc_attach,
@@ -508,7 +519,7 @@ static const struct rproc_ops imx_rproc_ops = {
 	.da_to_va       = imx_rproc_da_to_va,
 	.load		= rproc_elf_load_segments,
 	.parse_fw	= imx_rproc_parse_fw,
-	.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
+	.find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
 	.get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
 	.sanity_check	= rproc_elf_sanity_check,
 	.get_boot_addr	= rproc_elf_get_boot_addr,
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:23 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:23 +0800
Subject: [PATCH] remoteproc: imx_rproc: validate resource table
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-2-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Currently NXP use one device tree to support all NXP released Cortex-M
demos. There is one simple demo that not need to communicate with
Linux, thus it will not update the resource table. So there maybe
garbage data in it. In such case, Linux should directly ignore it.

It is hard to decide what data is garbage data, NXP released SDK use
ver(1), reserved(0) in a valid resource table. But in case others
use different value, so here use 0xff as a max value for ver and num.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 0bd24c937a73..75fde16f80a4 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -490,11 +490,19 @@ static int imx_rproc_attach(struct rproc *rproc)
 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
 {
 	struct imx_rproc *priv = rproc->priv;
+	struct resource_table *table;
 
 	/* The resource table has already been mapped in imx_rproc_addr_init */
 	if (!priv->rsc_table)
 		return NULL;
 
+	table = priv->rsc_table;
+	/* Gabage data check */
+	if (table->ver >= 0xff || table->num >= 0xff || table->reserved[0] || table->reserved[1]) {
+		dev_err(priv->dev, "Ignore invalid rsc table\n");
+		return NULL;
+	}
+
 	*table_sz = SZ_1K;
 	return (struct resource_table *)priv->rsc_table;
 }
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:24 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:24 +0800
Subject: [PATCH 0/9] remoteproc: imx_rproc: support i.MX8QXP/QM and self
 recovery
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-3-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

This patchset is to add i.MX8QM/QXP support.

i.MX8QM/QXP general purpose M4 core has self recovery capability if M4
is configured not in the same hardware partition. patch 3 is to support
self recovery case, when doing self recovery, only do detach and attach,
not using stop/start.

This patchset depends on: https://lkml.org/lkml/2022/1/10/1577

Peng Fan (9):
  dt-bindings: remoteproc: imx_rproc: support i.MX8QXP
  dt-bindings: remoteproc: imx_rproc: support i.MX8QM
  remoteproc: support self recovery after rproc crash
  remoteproc: imx_rproc: ignore create mem entry for resource table
  remoteproc: imx_rproc: make clk optional
  remoteproc: imx_rproc: support attaching to i.MX8QXP M4
  remoteproc: imx_rproc: support kicking Mcore from Linux for i.MX8QXP
  remoteproc: imx_rproc: support i.MX8QM
  remoteproc: imx_rproc: request mbox channel later

 .../bindings/remoteproc/fsl,imx-rproc.yaml    |  14 +
 drivers/remoteproc/imx_rproc.c                | 245 +++++++++++++++++-
 drivers/remoteproc/remoteproc_core.c          |  66 +++--
 include/linux/remoteproc.h                    |   2 +
 4 files changed, 296 insertions(+), 31 deletions(-)

-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:25 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:25 +0800
Subject: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QXP
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-4-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX8QXP compatible

Add a new property rsrc-id for SoC which supports SCFW. This rsrc-id
is used to check whether remote process is under control of Linux or
not.

To i.MX8QM/QXP, when M4 is in the same hardware partition with Cortex-A
cores, need power up M4 through SCFW, then M4 could start. So introduce
power-domains property

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml  | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index fc16d903353e..ed1bcb3046a9 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -19,6 +19,7 @@ properties:
       - fsl,imx8mm-cm4
       - fsl,imx8mn-cm7
       - fsl,imx8mp-cm7
+      - fsl,imx8qxp-cm4
       - fsl,imx8ulp-cm33
       - fsl,imx7d-cm4
       - fsl,imx7ulp-cm4
@@ -59,6 +60,15 @@ properties:
       Indicate whether need to load the default firmware and start the remote
       processor automatically.
 
+  power-domains:
+    maxItems: 8
+
+  rsrc-id:
+    description:
+      This property is to specify the resource id of the remote processor in SoC
+      which supports SCFW
+    maxItems: 1
+
 required:
   - compatible
 
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:26 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:26 +0800
Subject: [PATCH 2/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QM
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-5-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add i.MX8QM compatible

There are two general purpose M4, so add reg property to indicate the
id.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml         | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
index ed1bcb3046a9..cd9dcb63b176 100644
--- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
@@ -20,6 +20,7 @@ properties:
       - fsl,imx8mn-cm7
       - fsl,imx8mp-cm7
       - fsl,imx8qxp-cm4
+      - fsl,imx8qm-cm4
       - fsl,imx8ulp-cm33
       - fsl,imx7d-cm4
       - fsl,imx7ulp-cm4
@@ -63,6 +64,9 @@ properties:
   power-domains:
     maxItems: 8
 
+  reg:
+    maxItems: 1
+
   rsrc-id:
     description:
       This property is to specify the resource id of the remote processor in SoC
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:27 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:27 +0800
Subject: [PATCH 3/9] remoteproc: support self recovery after rproc crash
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-6-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Current logic only support main processor to stop/start the remote
processor after rproc crash. However to SoC, such as i.MX8QM/QXP, the
remote processor could do self recovery after crash and trigger watchdog
reboot. It does not need main processor to load image, stop/start M4
core.

This patch add a new flag to indicate whether the SoC has self recovery
capability. And introduce two functions: rproc_self_recovery,
rproc_assisted_recovery for the two cases. Assisted recovery is as
before, let main processor to help recovery, while self recovery is
recover itself withou help. To self recovery, we only do detach and
attach.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/remoteproc_core.c | 66 ++++++++++++++++++++--------
 include/linux/remoteproc.h           |  2 +
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 69f51acf235e..4bd5544dab8f 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1887,6 +1887,49 @@ static int __rproc_detach(struct rproc *rproc)
 	return 0;
 }
 
+static int rproc_self_recovery(struct rproc *rproc)
+{
+	int ret;
+
+	mutex_unlock(&rproc->lock);
+	ret = rproc_detach(rproc);
+	mutex_lock(&rproc->lock);
+	if (ret)
+		return ret;
+
+	if (atomic_inc_return(&rproc->power) > 1)
+		return 0;
+	return rproc_attach(rproc);
+}
+
+static int rproc_assisted_recovery(struct rproc *rproc)
+{
+	const struct firmware *firmware_p;
+	struct device *dev = &rproc->dev;
+	int ret;
+
+	ret = rproc_stop(rproc, true);
+	if (ret)
+		return ret;
+
+	/* generate coredump */
+	rproc->ops->coredump(rproc);
+
+	/* load firmware */
+	ret = request_firmware(&firmware_p, rproc->firmware, dev);
+	if (ret < 0) {
+		dev_err(dev, "request_firmware failed: %d\n", ret);
+		return ret;
+	}
+
+	/* boot the remote processor up again */
+	ret = rproc_start(rproc, firmware_p);
+
+	release_firmware(firmware_p);
+
+	return ret;
+}
+
 /**
  * rproc_trigger_recovery() - recover a remoteproc
  * @rproc: the remote processor
@@ -1901,7 +1944,6 @@ static int __rproc_detach(struct rproc *rproc)
  */
 int rproc_trigger_recovery(struct rproc *rproc)
 {
-	const struct firmware *firmware_p;
 	struct device *dev = &rproc->dev;
 	int ret;
 
@@ -1915,24 +1957,10 @@ int rproc_trigger_recovery(struct rproc *rproc)
 
 	dev_err(dev, "recovering %s\n", rproc->name);
 
-	ret = rproc_stop(rproc, true);
-	if (ret)
-		goto unlock_mutex;
-
-	/* generate coredump */
-	rproc->ops->coredump(rproc);
-
-	/* load firmware */
-	ret = request_firmware(&firmware_p, rproc->firmware, dev);
-	if (ret < 0) {
-		dev_err(dev, "request_firmware failed: %d\n", ret);
-		goto unlock_mutex;
-	}
-
-	/* boot the remote processor up again */
-	ret = rproc_start(rproc, firmware_p);
-
-	release_firmware(firmware_p);
+	if (rproc->self_recovery)
+		ret = rproc_self_recovery(rproc);
+	else
+		ret = rproc_assisted_recovery(rproc);
 
 unlock_mutex:
 	mutex_unlock(&rproc->lock);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index e0600e1e5c17..b32ef46f8aa4 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -529,6 +529,7 @@ struct rproc_dump_segment {
  * @elf_machine: firmware ELF machine
  * @cdev: character device of the rproc
  * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release
+ * @self_recovery: flag to indicate if remoteproc support self recovery
  */
 struct rproc {
 	struct list_head node;
@@ -568,6 +569,7 @@ struct rproc {
 	u16 elf_machine;
 	struct cdev cdev;
 	bool cdev_put_on_release;
+	bool self_recovery;
 };
 
 /**
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:28 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:28 +0800
Subject: [PATCH 4/9] remoteproc: imx_rproc: ignore create mem entry for
 resource table
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-7-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

resource table will not be used for memory allocation, no need to create
rproc mem entry.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 75fde16f80a4..7b2578177ea8 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -423,6 +423,9 @@ static int imx_rproc_prepare(struct rproc *rproc)
 		if (!strcmp(it.node->name, "vdev0buffer"))
 			continue;
 
+		if (!strncmp(it.node->name, "rsc-table", strlen("rsc-table")))
+			continue;
+
 		rmem = of_reserved_mem_lookup(it.node);
 		if (!rmem) {
 			dev_err(priv->dev, "unable to acquire memory-region\n");
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:29 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:29 +0800
Subject: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-8-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

To i.MX8QXP/QM/ULP and i.MX7ULP, Mcore maybe out of control of Linux.
And in such case, no need clk, so make clk optional with has_clk.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 7b2578177ea8..0e99a3ca6fbc 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -89,6 +89,7 @@ struct imx_rproc {
 	struct work_struct		rproc_work;
 	struct workqueue_struct		*workqueue;
 	void __iomem			*rsc_table;
+	bool				has_clk;
 };
 
 static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
@@ -724,6 +725,9 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
 	if (dcfg->method == IMX_RPROC_NONE)
 		return 0;
 
+	if (!priv->has_clk)
+		return 0;
+
 	priv->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(priv->clk)) {
 		dev_err(dev, "Failed to get clock\n");
@@ -768,6 +772,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
 	priv->rproc = rproc;
 	priv->dcfg = dcfg;
 	priv->dev = dev;
+	priv->has_clk = true;
 
 	dev_set_drvdata(dev, rproc);
 	priv->workqueue = create_workqueue(dev_name(dev));
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:30 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:30 +0800
Subject: [PATCH 6/9] remoteproc: imx_rproc: support attaching to i.MX8QXP M4
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-9-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

When M4 is kicked by SCFW, M4 runs in its own hardware partition, Linux
could only do IPC with M4, it could not start, stop, update image.

When M4 crash reboot, it could notify Linux, so Linux could prepare to
reattach to M4 after M4 recovery.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 96 ++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 0e99a3ca6fbc..5f04aea2f6a1 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -6,6 +6,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/firmware/imx/sci.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mailbox_client.h>
@@ -59,6 +60,8 @@
 #define IMX_SIP_RPROC_STARTED		0x01
 #define IMX_SIP_RPROC_STOP		0x02
 
+#define	IMX_SC_IRQ_GROUP_REBOOTED	5
+
 /**
  * struct imx_rproc_mem - slim internal memory structure
  * @cpu_addr: MPU virtual address of the memory region
@@ -90,6 +93,23 @@ struct imx_rproc {
 	struct workqueue_struct		*workqueue;
 	void __iomem			*rsc_table;
 	bool				has_clk;
+	struct imx_sc_ipc		*ipc_handle;
+	struct notifier_block		proc_nb;
+	u32				rproc_pt;
+	u32				rsrc;
+};
+
+static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
+	/* dev addr , sys addr  , size	    , flags */
+	{ 0x08000000, 0x08000000, 0x10000000, 0},
+	/* TCML/U */
+	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
+	/* OCRAM(Low 96KB) */
+	{ 0x21000000, 0x00100000, 0x00018000, 0},
+	/* OCRAM */
+	{ 0x21100000, 0x00100000, 0x00040000, 0},
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0 },
 };
 
 static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
@@ -236,6 +256,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
 	.method		= IMX_RPROC_NONE,
 };
 
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
+	.att		= imx_rproc_att_imx8qxp,
+	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
+	.method		= IMX_RPROC_SCU_API,
+};
+
 static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
 	.att		= imx_rproc_att_imx7ulp,
 	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
@@ -491,6 +517,11 @@ static int imx_rproc_attach(struct rproc *rproc)
 	return 0;
 }
 
+static int imx_rproc_detach(struct rproc *rproc)
+{
+	return 0;
+}
+
 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
 {
 	struct imx_rproc *priv = rproc->priv;
@@ -525,6 +556,7 @@ imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *
 static const struct rproc_ops imx_rproc_ops = {
 	.prepare	= imx_rproc_prepare,
 	.attach		= imx_rproc_attach,
+	.detach		= imx_rproc_detach,
 	.start		= imx_rproc_start,
 	.stop		= imx_rproc_stop,
 	.kick		= imx_rproc_kick,
@@ -671,6 +703,22 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
 	mbox_free_channel(priv->rx_ch);
 }
 
+static int imx_rproc_partition_notify(struct notifier_block *nb,
+				      unsigned long event, void *group)
+{
+	struct imx_rproc *priv = container_of(nb, struct imx_rproc, proc_nb);
+
+	/* Ignore other irqs */
+	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
+		return 0;
+
+	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
+
+	pr_info("Patition%d reset!\n", priv->rproc_pt);
+
+	return 0;
+}
+
 static int imx_rproc_detect_mode(struct imx_rproc *priv)
 {
 	struct regmap_config config = { .name = "imx-rproc" };
@@ -680,6 +728,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
 	struct arm_smccc_res res;
 	int ret;
 	u32 val;
+	u8 pt;
 
 	switch (dcfg->method) {
 	case IMX_RPROC_NONE:
@@ -690,6 +739,52 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
 		if (res.a0)
 			priv->rproc->state = RPROC_DETACHED;
 		return 0;
+	case IMX_RPROC_SCU_API:
+		ret = imx_scu_get_handle(&priv->ipc_handle);
+		if (ret)
+			return ret;
+		ret = of_property_read_u32(dev->of_node, "rsrc-id", &priv->rsrc);
+		if (ret) {
+			dev_err(dev, "no rsrc-id\n");
+			return ret;
+		}
+
+		/*
+		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
+		 * and Linux could only do IPC with Mcore and nothing else.
+		 */
+		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
+
+			priv->has_clk = false;
+			priv->rproc->self_recovery = true;
+			priv->rproc->state = RPROC_DETACHED;
+
+			/* Get partition id and enable irq in SCFW */
+			ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc, &pt);
+			if (ret) {
+				dev_err(dev, "not able to get resource owner\n");
+				return ret;
+			}
+
+			priv->rproc_pt = pt;
+			priv->proc_nb.notifier_call = imx_rproc_partition_notify;
+
+			ret = imx_scu_irq_register_notifier(&priv->proc_nb);
+			if (ret) {
+				dev_warn(dev, "register scu notifier failed.\n");
+				return ret;
+			}
+
+			ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED,
+						       BIT(priv->rproc_pt), true);
+			if (ret) {
+				imx_scu_irq_unregister_notifier(&priv->proc_nb);
+				dev_warn(dev, "Enable irq failed.\n");
+				return ret;
+			}
+		}
+
+		return 0;
 	default:
 		break;
 	}
@@ -847,6 +942,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
 	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
 	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
 	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
+	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
 	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
 	{},
 };
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:31 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:31 +0800
Subject: [PATCH 7/9] remoteproc: imx_rproc: support kicking Mcore from Linux
 for i.MX8QXP
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-10-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

When M4 is in the same hardware partition with Cortex-A, it
could be start/stop by Linux.

Added power domain to make sure M4 could run, it requires several power
domains to work. Make clk always optional for i.MX8QXP, because
SCFW handles it when power up M4 core.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 64 +++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 5f04aea2f6a1..09d2a06e5ed6 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -16,6 +16,7 @@
 #include <linux/of_reserved_mem.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/regmap.h>
 #include <linux/remoteproc.h>
 #include <linux/workqueue.h>
@@ -97,6 +98,9 @@ struct imx_rproc {
 	struct notifier_block		proc_nb;
 	u32				rproc_pt;
 	u32				rsrc;
+	int                             num_pd;
+	struct device                   **pd_dev;
+	struct device_link              **pd_dev_link;
 };
 
 static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
@@ -305,6 +309,9 @@ static int imx_rproc_start(struct rproc *rproc)
 		arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
 		ret = res.a0;
 		break;
+	case IMX_RPROC_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -334,6 +341,9 @@ static int imx_rproc_stop(struct rproc *rproc)
 		if (res.a1)
 			dev_info(dev, "Not in wfi, force stopped\n");
 		break;
+	case IMX_RPROC_SCU_API:
+		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
+		break;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -719,6 +729,56 @@ static int imx_rproc_partition_notify(struct notifier_block *nb,
 	return 0;
 }
 
+static int imx_rproc_attach_pd(struct imx_rproc *priv)
+{
+	struct device *dev = priv->dev;
+	int ret, i;
+
+	priv->num_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
+						  "#power-domain-cells");
+	if (priv->num_pd < 0)
+		return priv->num_pd;
+
+	if (!priv->num_pd)
+		return 0;
+
+	priv->pd_dev = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev), GFP_KERNEL);
+	if (!priv->pd_dev)
+		return -ENOMEM;
+
+	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev_link),
+					       GFP_KERNEL);
+
+	if (!priv->pd_dev_link)
+		return -ENOMEM;
+
+	for (i = 0; i < priv->num_pd; i++) {
+		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
+		if (IS_ERR(priv->pd_dev[i])) {
+			ret = PTR_ERR(priv->pd_dev[i]);
+			goto detach_pd;
+		}
+
+		priv->pd_dev_link[i] = device_link_add(dev, priv->pd_dev[i], DL_FLAG_STATELESS |
+						       DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+		if (!priv->pd_dev_link[i]) {
+			dev_pm_domain_detach(priv->pd_dev[i], false);
+			ret = -EINVAL;
+			goto detach_pd;
+		}
+	}
+
+	return 0;
+
+detach_pd:
+	while (--i >= 0) {
+		device_link_del(priv->pd_dev_link[i]);
+		dev_pm_domain_detach(priv->pd_dev[i], false);
+	}
+
+	return ret;
+}
+
 static int imx_rproc_detect_mode(struct imx_rproc *priv)
 {
 	struct regmap_config config = { .name = "imx-rproc" };
@@ -749,13 +809,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
 			return ret;
 		}
 
+		priv->has_clk = false;
 		/*
 		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
 		 * and Linux could only do IPC with Mcore and nothing else.
 		 */
 		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
 
-			priv->has_clk = false;
 			priv->rproc->self_recovery = true;
 			priv->rproc->state = RPROC_DETACHED;
 
@@ -782,6 +842,8 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
 				dev_warn(dev, "Enable irq failed.\n");
 				return ret;
 			}
+		} else {
+			return imx_rproc_attach_pd(priv);
 		}
 
 		return 0;
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:32 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:32 +0800
Subject: [PATCH 8/9] remoteproc: imx_rproc: support i.MX8QM
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-11-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Most logic are same as i.MX8QXP, but i.MX8QM has two general purpose
M4 cores:
 Use the lower 16 bits specifying core, higher 16 bits for flags.
 The 2nd core has different start address from SCFW view

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 55 +++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 09d2a06e5ed6..7bc274fbce9f 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -77,8 +77,11 @@ struct imx_rproc_mem {
 
 /* att flags */
 /* M4 own area. Can be mapped at probe */
-#define ATT_OWN		BIT(1)
-#define ATT_IOMEM	BIT(2)
+#define ATT_OWN         BIT(31)
+#define ATT_IOMEM       BIT(30)
+/* I = [0:7] */
+#define ATT_CORE_MASK   0xffff
+#define ATT_CORE(I)     BIT((I))
 
 struct imx_rproc {
 	struct device			*dev;
@@ -98,11 +101,25 @@ struct imx_rproc {
 	struct notifier_block		proc_nb;
 	u32				rproc_pt;
 	u32				rsrc;
+	u32				reg;
 	int                             num_pd;
 	struct device                   **pd_dev;
 	struct device_link              **pd_dev_link;
 };
 
+static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
+	/* dev addr , sys addr  , size      , flags */
+	{ 0x08000000, 0x08000000, 0x10000000, 0},
+	/* TCML */
+	{ 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_CORE(0)},
+	{ 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_CORE(1)},
+	/* TCMU */
+	{ 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_CORE(0)},
+	{ 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_CORE(1)},
+	/* DDR (Data) */
+	{ 0x80000000, 0x80000000, 0x60000000, 0 },
+};
+
 static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
 	/* dev addr , sys addr  , size	    , flags */
 	{ 0x08000000, 0x08000000, 0x10000000, 0},
@@ -260,6 +277,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
 	.method		= IMX_RPROC_NONE,
 };
 
+static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
+	.att            = imx_rproc_att_imx8qm,
+	.att_size       = ARRAY_SIZE(imx_rproc_att_imx8qm),
+	.method         = IMX_RPROC_SCU_API,
+};
+
 static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
 	.att		= imx_rproc_att_imx8qxp,
 	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
@@ -310,7 +333,10 @@ static int imx_rproc_start(struct rproc *rproc)
 		ret = res.a0;
 		break;
 	case IMX_RPROC_SCU_API:
-		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);
+		if (priv->reg)
+			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x38fe0000);
+		else
+			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -342,7 +368,10 @@ static int imx_rproc_stop(struct rproc *rproc)
 			dev_info(dev, "Not in wfi, force stopped\n");
 		break;
 	case IMX_RPROC_SCU_API:
-		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
+		if (priv->reg)
+			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x38fe0000);
+		else
+			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -364,6 +393,11 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
 	for (i = 0; i < dcfg->att_size; i++) {
 		const struct imx_rproc_att *att = &dcfg->att[i];
 
+		if (att->flags & ATT_CORE_MASK) {
+			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
+				continue;
+		}
+
 		if (da >= att->da && da + len < att->da + att->size) {
 			unsigned int offset = da - att->da;
 
@@ -594,6 +628,11 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
 		if (!(att->flags & ATT_OWN))
 			continue;
 
+		if (att->flags & ATT_CORE_MASK) {
+			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
+				continue;
+		}
+
 		if (b >= IMX_RPROC_MEM_MAX)
 			break;
 
@@ -809,6 +848,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
 			return ret;
 		}
 
+		priv->reg = of_get_cpu_hwid(dev->of_node, 0);
+		if (priv->reg == ~0U)
+			priv->reg = 0;
+
+		if (priv->reg > 1)
+			return -EINVAL;
+
 		priv->has_clk = false;
 		/*
 		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
@@ -1005,6 +1051,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
 	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
 	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
 	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
+	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
 	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
 	{},
 };
-- 
2.25.1



From peng.fan at oss.nxp.com  Mon Jan 10 19:33:33 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 11:33:33 +0800
Subject: [PATCH 9/9] remoteproc: imx_rproc: request mbox channel later
In-Reply-To: <20220111033333.403448-1-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
Message-ID: <20220111033333.403448-12-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

It is possible that when remote processor crash, the communication
channel will be broken with garbage value in mailbox, such as
when Linux is issuing a message through mailbox, remote processor
crashes, we need free & rebuild the mailbox channels to make sure
no garbage value in mailbox channels.

So move the request/free to start/stop for managing remote procesosr in
Linux, move to attach/detach for remote processor is out of control of
Linux.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 drivers/remoteproc/imx_rproc.c | 30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 7bc274fbce9f..079be82a334c 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -83,6 +83,9 @@ struct imx_rproc_mem {
 #define ATT_CORE_MASK   0xffff
 #define ATT_CORE(I)     BIT((I))
 
+static int imx_rproc_xtr_mbox_init(struct rproc *rproc);
+static void imx_rproc_free_mbox(struct rproc *rproc);
+
 struct imx_rproc {
 	struct device			*dev;
 	struct regmap			*regmap;
@@ -323,6 +326,10 @@ static int imx_rproc_start(struct rproc *rproc)
 	struct arm_smccc_res res;
 	int ret;
 
+	ret = imx_rproc_xtr_mbox_init(rproc);
+	if (ret)
+		return ret;
+
 	switch (dcfg->method) {
 	case IMX_RPROC_MMIO:
 		ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
@@ -379,6 +386,8 @@ static int imx_rproc_stop(struct rproc *rproc)
 
 	if (ret)
 		dev_err(dev, "Failed to stop remote core\n");
+	else
+		imx_rproc_free_mbox(rproc);
 
 	return ret;
 }
@@ -558,11 +567,12 @@ static void imx_rproc_kick(struct rproc *rproc, int vqid)
 
 static int imx_rproc_attach(struct rproc *rproc)
 {
-	return 0;
+	return imx_rproc_xtr_mbox_init(rproc);
 }
 
 static int imx_rproc_detach(struct rproc *rproc)
 {
+	imx_rproc_free_mbox(rproc);
 	return 0;
 }
 
@@ -716,6 +726,9 @@ static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
 	struct mbox_client *cl;
 	int ret;
 
+	if (priv->tx_ch && priv->rx_ch)
+		return 0;
+
 	if (!of_get_property(dev->of_node, "mbox-names", NULL))
 		return 0;
 
@@ -750,6 +763,8 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
 
 	mbox_free_channel(priv->tx_ch);
 	mbox_free_channel(priv->rx_ch);
+	priv->tx_ch = NULL;
+	priv->rx_ch = NULL;
 }
 
 static int imx_rproc_partition_notify(struct notifier_block *nb,
@@ -985,23 +1000,19 @@ static int imx_rproc_probe(struct platform_device *pdev)
 		goto err_put_rproc;
 	}
 
-	ret = imx_rproc_xtr_mbox_init(rproc);
-	if (ret)
-		goto err_put_wkq;
-
 	ret = imx_rproc_addr_init(priv, pdev);
 	if (ret) {
 		dev_err(dev, "failed on imx_rproc_addr_init\n");
-		goto err_put_mbox;
+		goto err_put_wkq;
 	}
 
 	ret = imx_rproc_detect_mode(priv);
 	if (ret)
-		goto err_put_mbox;
+		goto err_put_wkq;
 
 	ret = imx_rproc_clk_enable(priv);
 	if (ret)
-		goto err_put_mbox;
+		goto err_put_wkq;
 
 	INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
 
@@ -1018,8 +1029,6 @@ static int imx_rproc_probe(struct platform_device *pdev)
 
 err_put_clk:
 	clk_disable_unprepare(priv->clk);
-err_put_mbox:
-	imx_rproc_free_mbox(rproc);
 err_put_wkq:
 	destroy_workqueue(priv->workqueue);
 err_put_rproc:
@@ -1035,7 +1044,6 @@ static int imx_rproc_remove(struct platform_device *pdev)
 
 	clk_disable_unprepare(priv->clk);
 	rproc_del(rproc);
-	imx_rproc_free_mbox(rproc);
 	destroy_workqueue(priv->workqueue);
 	rproc_free(rproc);
 
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:38:59 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:08:59 +0530
Subject: [PATCH V3 0/7] coresight: trbe: Workaround Cortex-A510 erratas
Message-ID: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>

	This series adds three different workarounds in the TRBE driver for
Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
part number definition in the platform. This series applies on 5.16.

Relevant errata documents can be found here.

https://developer.arm.com/documentation/SDEN2397239/900
https://developer.arm.com/documentation/SDEN2397589/900

Changes in V3:

- Moved the comment inside trbe_needs_drain_after_disable()
- Moved the comment inside trbe_needs_ctxt_sync_after_enable()

Changes in V2:

https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/

Accommodated most review comments from the previous version.

- Split all patches into CPU errata definition, detection and TRBE workarounds
- s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
- s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
- s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
- s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
- Updated Kconfig help message for config ARM64_ERRATUM_1902691
- Updated error message for trbe_is_broken() detection
- Added new trblimitr parameter to set_trbe_enabled(), improving performance
- Added COMPILE_TEST dependency in the errata, until TRBE part is available

Changes in V1:

https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (7):
  arm64: Add Cortex-A510 CPU part definition
  arm64: errata: Add detection for TRBE ignored system register writes
  arm64: errata: Add detection for TRBE invalid prohibited states
  arm64: errata: Add detection for TRBE trace data corruption
  coresight: trbe: Work around the ignored system register writes
  coresight: trbe: Work around the invalid prohibited states
  coresight: trbe: Work around the trace data corruption

 Documentation/arm64/silicon-errata.rst       |   6 +
 arch/arm64/Kconfig                           |  59 ++++++++++
 arch/arm64/include/asm/cputype.h             |   2 +
 arch/arm64/kernel/cpu_errata.c               |  27 +++++
 arch/arm64/tools/cpucaps                     |   3 +
 drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-trbe.h |   8 --
 7 files changed, 183 insertions(+), 36 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:00 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:00 +0530
Subject: [PATCH V3 1/7] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.25.1



From peng.fan at nxp.com  Mon Jan 10 19:39:11 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 11 Jan 2022 03:39:11 +0000
Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
In-Reply-To: <20211214120737.1611955-1-peng.fan@oss.nxp.com>
References: <20211214120737.1611955-1-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB94177F777E854B92C665303488519@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> This patchset includes several update of i.MX sysctr and tpm driver.

Ping..

Thanks,
Peng.

> 
> Peng Fan (5):
>   clocksource/drivers/imx-sysctr: drop IRQF_IRQPOLL
>   clocksource/drivers/imx-tpm: drop IRQF_IRQPOLL
>   clocksource/drivers/imx-tpm: mark two variable with __ro_after_init
>   clocksource/drivers/imx-tpm: add CLOCK_EVT_FEAT_DYNIRQ
>   clocksource/drivers/imx-tpm: update name of clkevt
> 
>  drivers/clocksource/timer-imx-sysctr.c |  2 +-
>  drivers/clocksource/timer-imx-tpm.c    | 10 +++++-----
>  2 files changed, 6 insertions(+), 6 deletions(-)
> 
> --
> 2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:01 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:01 +0530
Subject: [PATCH V3 2/7] arm64: errata: Add detection for TRBE ignored system
 register writes
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-3-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected. This adds a new errata ARM64_ERRATUM_2064142
in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..c9b30e6c2b6c 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -52,6 +52,8 @@ stable kernels.
 | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..e27ccfe9fa9c 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2064142
+	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
+
+	  Affected Cortex-A510 core might fail to write into system registers after the
+	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
+	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
+	  and TRBTRG_EL1 will be ignored and will not be effected.
+
+	  Work around this in the driver by executing TSB CSYNC and DSB after collection
+	  is stopped and before performing a system register write to one of the affected
+	  registers.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..cbb7d5a9aee7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2064142
+	{
+		.desc = "ARM erratum 2064142",
+		.capability = ARM64_WORKAROUND_2064142,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..fca3cb329e1d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2064142
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:02 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:02 +0530
Subject: [PATCH V3 3/7] arm64: errata: Add detection for TRBE invalid
 prohibited states
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-4-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted. This adds a new errata
ARM64_ERRATUM_2038923 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 23 +++++++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 35 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index c9b30e6c2b6c..e0ef3e9a4b8b 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e27ccfe9fa9c..188eae6ef28d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2038923
+	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
+
+	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
+	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
+	  might be corrupted. This happens after TRBE buffer has been enabled by setting
+	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
+	  execution changes from a context, in which trace is prohibited to one where it
+	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
+	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
+	  the trace buffer state might be corrupted.
+
+	  Work around this in the driver by preventing an inconsistent view of whether the
+	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
+	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
+	  two ISB instructions if no ERET is to take place.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cbb7d5a9aee7..60b0c1f1d912 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_2038923
+	{
+		.desc = "ARM erratum 2038923",
+		.capability = ARM64_WORKAROUND_2038923,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
+#endif
 	{
 	}
 };
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index fca3cb329e1d..45a06d36d080 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -56,6 +56,7 @@ WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
+WORKAROUND_2038923
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:03 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:03 +0530
Subject: [PATCH V3 4/7] arm64: errata: Add detection for TRBE trace data
 corruption
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-5-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. So effectively
TRBE is broken and hence cannot be used to capture trace data. This adds
a new errata ARM64_ERRATUM_1902691 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index e0ef3e9a4b8b..50018f60c4d4 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -56,6 +56,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #1902691        | ARM64_ERRATUM_1902691       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 188eae6ef28d..f1651cb71ef3 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -819,6 +819,24 @@ config ARM64_ERRATUM_2038923
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_1902691
+	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
+
+	  Affected Cortex-A510 core might cause trace data corruption, when being written
+	  into the memory. Effectively TRBE is broken and hence cannot be used to capture
+	  trace data.
+
+	  Work around this problem in the driver by just preventing TRBE initialization on
+	  affected cpus. The firmware must have disabled the access to TRBE for the kernel
+	  on such implementations. This will cover the kernel for any firmware that doesn't
+	  do this already.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 60b0c1f1d912..a3336dfb5a8a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		/* Cortex-A510 r0p0 - r0p2 */
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1902691
+	{
+		.desc = "ARM erratum 1902691",
+		.capability = ARM64_WORKAROUND_1902691,
+
+		/* Cortex-A510 r0p0 - r0p1 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 45a06d36d080..e7719e8f18de 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -57,6 +57,7 @@ WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
 WORKAROUND_2038923
+WORKAROUND_1902691
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:04 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:04 +0530
Subject: [PATCH V3 5/7] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-6-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected.

Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
just after the trace collection has stopped and before performing a system
register write to one of the affected registers. This just updates the TRBE
driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
 drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f1651cb71ef3..b6d62672bf7d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -780,7 +780,7 @@ config ARM64_ERRATUM_2224489
 
 config ARM64_ERRATUM_2064142
 	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 276862c07e32..4ef944971d8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -91,10 +91,12 @@ struct trbe_buf {
  */
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
+#define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
+	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -167,6 +169,16 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
 }
 
+static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
+{
+	/*
+	 * Errata affected TRBE implementation will need TSB CSYNC and
+	 * DSB in order to prevent subsequent writes into certain TRBE
+	 * system registers from being ignored and not effected.
+	 */
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -174,30 +186,37 @@ static int trbe_alloc_node(struct perf_event *event)
 	return cpu_to_node(event->cpu);
 }
 
-static void trbe_drain_buffer(void)
+static inline void trbe_drain_buffer(void)
 {
 	tsb_csync();
 	dsb(nsh);
 }
 
-static void trbe_drain_and_disable_local(void)
+static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
-	trbe_drain_buffer();
-
 	/*
 	 * Disable the TRBE without clearing LIMITPTR which
 	 * might be required for fetching the buffer limits.
 	 */
 	trblimitr &= ~TRBLIMITR_ENABLE;
 	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	if (trbe_needs_drain_after_disable(cpudata))
+		trbe_drain_buffer();
 	isb();
 }
 
-static void trbe_reset_local(void)
+static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
 {
-	trbe_drain_and_disable_local();
+	trbe_drain_buffer();
+	set_trbe_disabled(cpudata);
+}
+
+static void trbe_reset_local(struct trbe_cpudata *cpudata)
+{
+	trbe_drain_and_disable_local(cpudata);
 	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
 	write_sysreg_s(0, SYS_TRBPTR_EL1);
 	write_sysreg_s(0, SYS_TRBBASER_EL1);
@@ -234,7 +253,7 @@ static void trbe_stop_and_truncate_event(struct perf_output_handle *handle)
 	 * at event_stop(). So disable the TRBE here and leave
 	 * the update_buffer() to return a 0 size.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	perf_aux_output_end(handle, 0);
 	*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
@@ -579,8 +598,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	WARN_ON(buf->trbe_hw_base < buf->trbe_base);
 	WARN_ON(buf->trbe_write < buf->trbe_hw_base);
 	WARN_ON(buf->trbe_write >= buf->trbe_limit);
-	set_trbe_disabled();
-	isb();
+	set_trbe_disabled(buf->cpudata);
 	clr_trbe_status();
 	set_trbe_base_pointer(buf->trbe_hw_base);
 	set_trbe_write_pointer(buf->trbe_write);
@@ -775,7 +793,7 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
 	 * the TRBE here will ensure that no IRQ could be generated when the perf
 	 * handle gets freed in etm_event_stop().
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 
 	/* Check if there is a pending interrupt and handle it here */
 	status = read_sysreg_s(SYS_TRBSR_EL1);
@@ -986,7 +1004,7 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 	if (cpudata->mode != CS_MODE_PERF)
 		return -EINVAL;
 
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 	buf->cpudata = NULL;
 	cpudata->buf = NULL;
 	cpudata->mode = CS_MODE_DISABLED;
@@ -1028,7 +1046,7 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
 		 * is able to detect this with a disconnected handle
 		 * (handle->event = NULL).
 		 */
-		trbe_drain_and_disable_local();
+		trbe_drain_and_disable_local(buf->cpudata);
 		*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
 		return -EINVAL;
 	}
@@ -1062,6 +1080,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 {
 	struct perf_output_handle **handle_ptr = dev;
 	struct perf_output_handle *handle = *handle_ptr;
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
 	enum trbe_fault_action act;
 	u64 status;
 	bool truncated = false;
@@ -1082,7 +1101,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 	 * Ensure the trace is visible to the CPUs and
 	 * any external aborts have been resolved.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	clr_trbe_irq();
 	isb();
 
@@ -1167,8 +1186,9 @@ static const struct attribute_group *arm_trbe_groups[] = {
 static void arm_trbe_enable_cpu(void *info)
 {
 	struct trbe_drvdata *drvdata = info;
+	struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
 
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
 }
 
@@ -1276,7 +1296,7 @@ static void arm_trbe_remove_coresight_cpu(void *info)
 	struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
 
 	disable_percpu_irq(drvdata->irq);
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	if (trbe_csdev) {
 		coresight_unregister(trbe_csdev);
 		cpudata->drvdata = NULL;
@@ -1349,8 +1369,10 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 	struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
 
 	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
+		struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+
 		disable_percpu_irq(drvdata->irq);
-		trbe_reset_local();
+		trbe_reset_local(cpudata);
 	}
 	return 0;
 }
diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h
index abf3e36082f0..30e4d7db4f8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.h
+++ b/drivers/hwtracing/coresight/coresight-trbe.h
@@ -91,14 +91,6 @@ static inline bool is_trbe_running(u64 trbsr)
 #define TRBE_FILL_MODE_WRAP		1
 #define TRBE_FILL_MODE_CIRCULAR_BUFFER	3
 
-static inline void set_trbe_disabled(void)
-{
-	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
-
-	trblimitr &= ~TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-}
-
 static inline bool get_trbe_flag_update(u64 trbidr)
 {
 	return trbidr & TRBIDR_FLAG;
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:05 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:05 +0530
Subject: [PATCH V3 6/7] coresight: trbe: Work around the invalid prohibited
 states
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-7-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted.

Work around this problem in the TRBE driver by preventing an inconsistent
view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
immediately following a change to TRBLIMITR_EL1.E with at least one ISB
instruction before an ERET, or two ISB instructions if no ERET is to take
place. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 48 +++++++++++++++-----
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b6d62672bf7d..209e481acf0d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -798,7 +798,7 @@ config ARM64_ERRATUM_2064142
 
 config ARM64_ERRATUM_2038923
 	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 4ef944971d8e..6254ba598df2 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -92,11 +92,13 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
+#define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
+	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -179,6 +181,17 @@ static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
 }
 
+static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudata)
+{
+	/*
+	 * Errata affected TRBE implementation will need an additional
+	 * context synchronization in order to prevent an inconsistent
+	 * TRBE prohibited region view on the CPU which could possibly
+	 * corrupt the TRBE buffer or the TRBE state.
+	 */
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -192,6 +205,22 @@ static inline void trbe_drain_buffer(void)
 	dsb(nsh);
 }
 
+static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
+{
+	/*
+	 * Enable the TRBE without clearing LIMITPTR which
+	 * might be required for fetching the buffer limits.
+	 */
+	trblimitr |= TRBLIMITR_ENABLE;
+	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/* Synchronize the TRBE enable event */
+	isb();
+
+	if (trbe_needs_ctxt_sync_after_enable(cpudata))
+		isb();
+}
+
 static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
@@ -555,9 +584,10 @@ static void clr_trbe_status(void)
 	write_sysreg_s(trbsr, SYS_TRBSR_EL1);
 }
 
-static void set_trbe_limit_pointer_enabled(unsigned long addr)
+static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	unsigned long addr = buf->trbe_limit;
 
 	WARN_ON(!IS_ALIGNED(addr, (1UL << TRBLIMITR_LIMIT_SHIFT)));
 	WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
@@ -585,12 +615,7 @@ static void set_trbe_limit_pointer_enabled(unsigned long addr)
 	trblimitr |= (TRBE_TRIG_MODE_IGNORE & TRBLIMITR_TRIG_MODE_MASK) <<
 		      TRBLIMITR_TRIG_MODE_SHIFT;
 	trblimitr |= (addr & PAGE_MASK);
-
-	trblimitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-
-	/* Synchronize the TRBE enable event */
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static void trbe_enable_hw(struct trbe_buf *buf)
@@ -608,7 +633,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	 * till now before enabling the TRBE.
 	 */
 	isb();
-	set_trbe_limit_pointer_enabled(buf->trbe_limit);
+	set_trbe_limit_pointer_enabled(buf);
 }
 
 static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *handle,
@@ -1013,16 +1038,15 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 
 static void trbe_handle_spurious(struct perf_output_handle *handle)
 {
-	u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
+	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
 	/*
 	 * If the IRQ was spurious, simply re-enable the TRBE
 	 * back without modifying the buffer parameters to
 	 * retain the trace collected so far.
 	 */
-	limitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static int trbe_handle_overflow(struct perf_output_handle *handle)
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 10 19:39:06 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 11 Jan 2022 09:09:06 +0530
Subject: [PATCH V3 7/7] coresight: trbe: Work around the trace data corruption
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641872346-3270-8-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. Workaround this
problem in the driver, by preventing TRBE initialization on affected cpus.
The firmware must have disabled the access to TRBE for the kernel on such
implementations. This will cover the kernel for any firmware that doesn't
do this already. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 209e481acf0d..8a2245c3e857 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -821,7 +821,7 @@ config ARM64_ERRATUM_2038923
 
 config ARM64_ERRATUM_1902691
 	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 6254ba598df2..75b608bc400b 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -93,12 +93,14 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 #define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
+#define TRBE_IS_BROKEN				4
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
+	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -192,6 +194,11 @@ static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudat
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
 }
 
+static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -1288,6 +1295,11 @@ static void arm_trbe_probe_cpu(void *info)
 	 */
 	trbe_check_errata(cpudata);
 
+	if (trbe_is_broken(cpudata)) {
+		pr_err("Disabling TRBE on cpu%d due to erratum\n", cpu);
+		goto cpu_clear;
+	}
+
 	/*
 	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
 	 * we must always program the TBRPTR_EL1, 256bytes from a page
-- 
2.25.1



From reijiw at google.com  Mon Jan 10 20:33:48 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 10 Jan 2022 20:33:48 -0800
Subject: [RFC PATCH v3 03/11] KVM: Introduce KVM_CAP_ARM_HVC_FW_REG_BMAP
In-Reply-To: <CAJHc60yY9qH5_r09Tz2fhWr+tT+i7RnKhchBuEePCKnos52kwA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-4-rananta@google.com>
 <CAAeT=FxCCD+H1z8+gfyBZNeibfAUqUenZZe56Vj_3fCghJjy=Q@mail.gmail.com>
 <CAJHc60yY9qH5_r09Tz2fhWr+tT+i7RnKhchBuEePCKnos52kwA@mail.gmail.com>
Message-ID: <CAAeT=FyJcUKP4ZGuMQh-AFExj9X=cXKUf0RueqqqhRwUHL2+sw@mail.gmail.com>

On Mon, Jan 10, 2022 at 3:40 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> On Fri, Jan 7, 2022 at 9:40 PM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Hi Raghu,
> >
> > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > Introduce the KVM ARM64 capability, KVM_CAP_ARM_HVC_FW_REG_BMAP,
> > > to indicate the support for psuedo-firmware bitmap extension.
> > > Each of these registers holds a feature-set exposed to the guest
> > > in the form of a bitmap. If supported, a simple 'read' of the
> > > capability should return the number of psuedo-firmware registers
> > > supported. User-space can utilize this to discover the registers.
> > > It can further explore or modify the features using the classical
> > > GET/SET_ONE_REG interface.
> > >
> > > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > > ---
> > >  Documentation/virt/kvm/api.rst | 21 +++++++++++++++++++++
> > >  include/uapi/linux/kvm.h       |  1 +
> > >  2 files changed, 22 insertions(+)
> > >
> > > diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> > > index aeeb071c7688..646176537f2c 100644
> > > --- a/Documentation/virt/kvm/api.rst
> > > +++ b/Documentation/virt/kvm/api.rst
> > > @@ -6925,6 +6925,27 @@ indicated by the fd to the VM this is called on.
> > >  This is intended to support intra-host migration of VMs between userspace VMMs,
> > >  upgrading the VMM process without interrupting the guest.
> > >
> > > +7.30 KVM_CAP_ARM_HVC_FW_REG_BMAP
> >
> > IMHO, instead of including its format of the register in the name,
> > including its purpose/function in the name might be better.
> > e.g. KVM_CAP_ARM_HVC_FEATURE_REG ?
> > (Feature fields don't necessarily have to be in a bitmap format
> >  if they don't fit well although I'm not sure if we have such fields.)
> >
> Well we do have registers, KVM_REG_ARM_PSCI_VERSION for instance,
> that's not covered by this CAP. But sure, I can explicitly add
> 'FEATURES' to the name. I also wanted to explicitly convey that we are
> covering the *bitmapped* firmware registers here. But not sure if
> appending 'BMAP' might give an impression that the CAP itself is
> bitmapped.
> Do you think KVM_CAP_ARM_HVC_BMAP_FEAT_REG is better?

Thank you for the explanation! That sounds better to me.

Regards,
Reiji


> > > +
> > > +:Architectures: arm64
> > > +:Parameters: None
> > > +:Returns: Number of psuedo-firmware registers supported
> >
> > Looking at patch-4, the return value of this would be the number of
> > pseudo-firmware *bitmap* registers supported.
> > BTW, "4.68 KVM_SET_ONE_REG" in the doc uses the word "arm64 firmware
> > pseudo-registers".  It would be nicer to use the same term.
> >
> Nice catch. I'll fix it here in apr.rst.
> > > +
> > > +This capability indicates that KVM for arm64 supports the psuedo-firmware
> > > +register bitmap extension. Each of these registers represent the features
> > > +supported by a particular type in the form of a bitmap. By default, these
> > > +registers are set with the upper limit of the features that are supported.
> > > +
> > > +The registers can be accessed via the standard SET_ONE_REG and KVM_GET_ONE_REG
> > > +interfaces. The user-space is expected to read the number of these registers
> > > +available by reading KVM_CAP_ARM_HVC_FW_REG_BMAP, read the current bitmap
> > > +configuration via GET_ONE_REG for each register, and then write back the
> > > +desired bitmap of features that it wishes the guest to see via SET_ONE_REG.
> > > +
> > > +Note that KVM doesn't allow the user-space to modify these registers after
> > > +the VM (any of the vCPUs) has started running.
> >
> > Since even if KVM_RUN fails, and the VM hasn't started yet,
> > it will get immutable. So, "after any of the vCPUs run KVM_RUN."
> > might be more clear ?
> >
> Sure, that's probably more clear. I'll fix it.
>
> Regards,
> Raghavendra
>
> > Thanks,
> > Reiji
> >
> >
> >
> > > +
> > >  8. Other capabilities.
> > >  ======================
> > >
> > > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> > > index 1daa45268de2..209b43dbbc3c 100644
> > > --- a/include/uapi/linux/kvm.h
> > > +++ b/include/uapi/linux/kvm.h
> > > @@ -1131,6 +1131,7 @@ struct kvm_ppc_resize_hpt {
> > >  #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
> > >  #define KVM_CAP_ARM_MTE 205
> > >  #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
> > > +#define KVM_CAP_ARM_HVC_FW_REG_BMAP 207
> > >
> > >  #ifdef KVM_CAP_IRQ_ROUTING
> > >
> > > --
> > > 2.34.1.448.ga2b2bfdf31-goog
> > >


From peng.fan at oss.nxp.com  Mon Jan 10 22:20:13 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Tue, 11 Jan 2022 14:20:13 +0800
Subject: [PATCH] arm64: dts: imx8: add mu5/6 node
Message-ID: <20220111062013.1027517-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Add mu5/6 for i.MX8QXP/QM, these two mu will be used for
communicating with general purpose Cortex-M4 cores.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi  | 16 ++++++++++++++++
 .../arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi |  8 ++++++++
 .../boot/dts/freescale/imx8qxp-ss-lsio.dtsi      |  8 ++++++++
 3 files changed, 32 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
index ee4e585a9c39..6446e6df7a9a 100644
--- a/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -141,6 +141,22 @@ lsio_mu4: mailbox at 5d1f0000 {
 		status = "disabled";
 	};
 
+	lsio_mu5: mailbox at 5d200000 {
+		reg = <0x5d200000 0x10000>;
+		interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_MU_5A>;
+		status = "disabled";
+	};
+
+	lsio_mu6: mailbox at 5d210000 {
+		reg = <0x5d210000 0x10000>;
+		interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_MU_6A>;
+		status = "disabled";
+	};
+
 	lsio_mu13: mailbox at 5d280000 {
 		reg = <0x5d280000 0x10000>;
 		interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
index 30896610c654..669aa14ce9f7 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-lsio.dtsi
@@ -56,6 +56,14 @@ &lsio_mu4 {
 	compatible = "fsl,imx8-mu-scu", "fsl,imx8qm-mu", "fsl,imx6sx-mu";
 };
 
+&lsio_mu5 {
+	compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
+};
+
+&lsio_mu6 {
+	compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
+};
+
 &lsio_mu13 {
 	compatible = "fsl,imx8qm-mu", "fsl,imx6sx-mu";
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
index 11395479ffc0..8e2152c6eb88 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-lsio.dtsi
@@ -56,6 +56,14 @@ &lsio_mu4 {
 	compatible = "fsl,imx8-mu-scu", "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
 };
 
+&lsio_mu5 {
+	compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
+};
+
+&lsio_mu6 {
+	compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
+};
+
 &lsio_mu13 {
 	compatible = "fsl,imx8qxp-mu", "fsl,imx6sx-mu";
 };
-- 
2.25.1



From yong.wu at mediatek.com  Mon Jan 10 22:39:02 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:39:02 +0800
Subject: [PATCH v2 4/6] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-5-yong.wu@mediatek.com>

The successful return value for clk_bulk_prepare_enable is 0, rather than
"< 0". Fix this.

Fixes: 0e14917c57f9 ("memory: mtk-smi: Use clk_bulk clock ops")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/mtk-smi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b883dcc0bbfa..e7b1a22b12ea 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -480,7 +480,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 	int ret;
 
 	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	/* Configure the basic setting for this larb */
-- 
2.18.0



From yong.wu at mediatek.com  Mon Jan 10 22:38:58 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:38:58 +0800
Subject: [PATCH v2 0/6] MT8186 SMI SUPPORT
Message-ID: <20220111063904.7583-1-yong.wu@mediatek.com>

This patchset adds mt8186 smi support, mainly adds a sleep control function.

Change note:
v2: a) Add two patches for the "make dtbs_check" warning.
    b) Seperate the "sleep control" into two functions.
       And add a "TODO" comment while sleep control fails.

v1: https://lore.kernel.org/linux-mediatek/20211203064027.14993-1-yong.wu at mediatek.com/
    Base on v5.16-rc1.

Yong Wu (6):
  dt-bindings: memory: mtk-smi: Fix larb-id dtbs_check warning
  dt-bindings: memory: mtk-smi: Fix the larb clock/clock-names dtbs
    warning
  dt-bindings: memory: mediatek: Add mt8186 support
  memory: mtk-smi: Fix the return value for clk_bulk_prepare_enable
  memory: mtk-smi: Add sleep ctrl function
  memory: mtk-smi: mt8186: Add smi support

 .../mediatek,smi-common.yaml                  |  4 +-
 .../memory-controllers/mediatek,smi-larb.yaml | 10 ++--
 drivers/memory/mtk-smi.c                      | 50 ++++++++++++++++++-
 3 files changed, 57 insertions(+), 7 deletions(-)

-- 
2.18.0




From yong.wu at mediatek.com  Mon Jan 10 22:39:01 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:39:01 +0800
Subject: [PATCH v2 3/6] dt-bindings: memory: mediatek: Add mt8186 support
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-4-yong.wu@mediatek.com>

Add mt8186 smi support in the bindings.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 .../bindings/memory-controllers/mediatek,smi-common.yaml      | 4 +++-
 .../bindings/memory-controllers/mediatek,smi-larb.yaml        | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 3a82b0b27fa0..fbe5077408d8 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ description: |
   MediaTek SMI have two generations of HW architecture, here is the list
   which generation the SoCs use:
   generation 1: mt2701 and mt7623.
-  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8192 and mt8195.
+  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195.
 
   There's slight differences between the two SMI, for generation 2, the
   register which control the iommu port is at each larb's register base. But
@@ -35,6 +35,7 @@ properties:
           - mediatek,mt8167-smi-common
           - mediatek,mt8173-smi-common
           - mediatek,mt8183-smi-common
+          - mediatek,mt8186-smi-common
           - mediatek,mt8192-smi-common
           - mediatek,mt8195-smi-common-vdo
           - mediatek,mt8195-smi-common-vpp
@@ -127,6 +128,7 @@ allOf:
           enum:
             - mediatek,mt6779-smi-common
             - mediatek,mt8183-smi-common
+            - mediatek,mt8186-smi-common
             - mediatek,mt8192-smi-common
             - mediatek,mt8195-smi-common-vdo
             - mediatek,mt8195-smi-common-vpp
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index 884c0c74e5e4..7da157cb1db6 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -23,6 +23,7 @@ properties:
           - mediatek,mt8167-smi-larb
           - mediatek,mt8173-smi-larb
           - mediatek,mt8183-smi-larb
+          - mediatek,mt8186-smi-larb
           - mediatek,mt8192-smi-larb
           - mediatek,mt8195-smi-larb
 
@@ -75,6 +76,7 @@ allOf:
         compatible:
           enum:
             - mediatek,mt8183-smi-larb
+            - mediatek,mt8186-smi-larb
             - mediatek,mt8195-smi-larb
 
     then:
@@ -108,6 +110,7 @@ allOf:
               - mediatek,mt2701-smi-larb
               - mediatek,mt2712-smi-larb
               - mediatek,mt6779-smi-larb
+              - mediatek,mt8186-smi-larb
               - mediatek,mt8192-smi-larb
               - mediatek,mt8195-smi-larb
 
-- 
2.18.0



From peng.fan at nxp.com  Mon Jan 10 22:44:40 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 11 Jan 2022 06:44:40 +0000
Subject: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QXP
In-Reply-To: <20220111033333.403448-4-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-4-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB9417B64FFCA45C6ABA034CD588519@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QXP

+Rob

> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add i.MX8QXP compatible
> 
> Add a new property rsrc-id for SoC which supports SCFW. This rsrc-id is used
> to check whether remote process is under control of Linux or not.
> 
> To i.MX8QM/QXP, when M4 is in the same hardware partition with Cortex-A
> cores, need power up M4 through SCFW, then M4 could start. So introduce
> power-domains property
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml  | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git
> a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> index fc16d903353e..ed1bcb3046a9 100644
> --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> @@ -19,6 +19,7 @@ properties:
>        - fsl,imx8mm-cm4
>        - fsl,imx8mn-cm7
>        - fsl,imx8mp-cm7
> +      - fsl,imx8qxp-cm4
>        - fsl,imx8ulp-cm33
>        - fsl,imx7d-cm4
>        - fsl,imx7ulp-cm4
> @@ -59,6 +60,15 @@ properties:
>        Indicate whether need to load the default firmware and start the
> remote
>        processor automatically.
> 
> +  power-domains:
> +    maxItems: 8
> +
> +  rsrc-id:
> +    description:
> +      This property is to specify the resource id of the remote processor in
> SoC
> +      which supports SCFW
> +    maxItems: 1
> +
>  required:
>    - compatible
> 
> --
> 2.25.1



From yong.wu at mediatek.com  Mon Jan 10 22:38:59 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:38:59 +0800
Subject: [PATCH v2 1/6] dt-bindings: memory: mtk-smi: Fix larb-id dtbs_check
 warning
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-2-yong.wu@mediatek.com>

Mute the warning from "make dtbs_check":

larb at 14016000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
larb at 15001000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
larb at 16010000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml

Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../bindings/memory-controllers/mediatek,smi-larb.yaml           | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index eaeff1ada7f8..80907e357892 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -108,7 +108,6 @@ allOf:
               - mediatek,mt2701-smi-larb
               - mediatek,mt2712-smi-larb
               - mediatek,mt6779-smi-larb
-              - mediatek,mt8167-smi-larb
               - mediatek,mt8192-smi-larb
               - mediatek,mt8195-smi-larb
 
-- 
2.18.0



From yong.wu at mediatek.com  Mon Jan 10 22:39:03 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:39:03 +0800
Subject: [PATCH v2 5/6] memory: mtk-smi: Add sleep ctrl function
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-6-yong.wu@mediatek.com>

Sleep control means that when the larb goes to sleep, we should wait a bit
until all the current commands are finished. Thus, when the larb runtime
suspends, we need to enable this function to wait until all the existed
commands are finished. When the larb resumes, just disable this function.
This function only improves the safety of bus. Add a new flag for this
function. Prepare for mt8186.

Signed-off-by: Anan Sun <anan.sun at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/memory/mtk-smi.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index e7b1a22b12ea..d8552f4caba4 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -32,6 +33,10 @@
 #define SMI_DUMMY			0x444
 
 /* SMI LARB */
+#define SMI_LARB_SLP_CON                0xc
+#define SLP_PROT_EN                     BIT(0)
+#define SLP_PROT_RDY                    BIT(16)
+
 #define SMI_LARB_CMD_THRT_CON		0x24
 #define SMI_LARB_THRT_RD_NU_LMT_MSK	GENMASK(7, 4)
 #define SMI_LARB_THRT_RD_NU_LMT		(5 << 4)
@@ -81,6 +86,7 @@
 
 #define MTK_SMI_FLAG_THRT_UPDATE	BIT(0)
 #define MTK_SMI_FLAG_SW_FLAG		BIT(1)
+#define MTK_SMI_FLAG_SLEEP_CTL		BIT(2)
 #define MTK_SMI_CAPS(flags, _x)		(!!((flags) & (_x)))
 
 struct mtk_smi_reg_pair {
@@ -371,6 +377,26 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{}
 };
 
+static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
+{
+	int ret;
+	u32 tmp;
+
+	writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON);
+	ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON,
+					tmp, !!(tmp & SLP_PROT_RDY), 10, 1000);
+	if (ret) {
+		/* TODO: Reset this larb if it fails here. */
+		dev_warn(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp);
+	}
+	return ret;
+}
+
+static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb)
+{
+	writel_relaxed(0, larb->base + SMI_LARB_SLP_CON);
+}
+
 static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
 {
 	struct platform_device *smi_com_pdev;
@@ -483,6 +509,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
+		mtk_smi_larb_sleep_ctrl_disable(larb);
+
 	/* Configure the basic setting for this larb */
 	larb_gen->config_port(dev);
 
@@ -492,9 +521,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
 {
 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+	int ret = 0;
+
+	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
+		ret = mtk_smi_larb_sleep_ctrl_enable(larb);
 
 	clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
-	return 0;
+	return ret;
 }
 
 static const struct dev_pm_ops smi_larb_pm_ops = {
-- 
2.18.0



From yong.wu at mediatek.com  Mon Jan 10 22:39:04 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:39:04 +0800
Subject: [PATCH v2 6/6] memory: mtk-smi: mt8186: Add smi support
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-7-yong.wu@mediatek.com>

Add mt8186 SMI support.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/memory/mtk-smi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index d8552f4caba4..424a16de516e 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -355,6 +355,11 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
 				      /* IPU0 | IPU1 | CCU */
 };
 
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
+	.config_port                = mtk_smi_larb_config_port_gen2_general,
+	.flags_general	            = MTK_SMI_FLAG_SLEEP_CTL,
+};
+
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
 };
@@ -372,6 +377,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
 	{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
 	{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
+	{.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
 	{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
 	{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
 	{}
@@ -577,6 +583,12 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
 		    F_MMU1_LARB(7),
 };
 
+static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = {
+	.type     = MTK_SMI_GEN2,
+	.has_gals = true,
+	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7),
+};
+
 static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
 	.type     = MTK_SMI_GEN2,
 	.has_gals = true,
@@ -611,6 +623,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
 	{.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
 	{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
 	{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
+	{.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
 	{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
 	{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
 	{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
-- 
2.18.0



From yong.wu at mediatek.com  Mon Jan 10 22:39:00 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 11 Jan 2022 14:39:00 +0800
Subject: [PATCH v2 2/6] dt-bindings: memory: mtk-smi: Fix the larb
 clock/clock-names dtbs warning
In-Reply-To: <20220111063904.7583-1-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
Message-ID: <20220111063904.7583-3-yong.wu@mediatek.com>

Mute the warning from "make dtbs_check":

larb at 14017000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
	...

larb at 16010000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml

larb at 17010000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml

If a platform's larb supports gals, there will be some larbs have one
more "gals" clock while the others still only need "apb"/"smi" clocks,
then the minItems for clock and clock-names are 2.

Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../bindings/memory-controllers/mediatek,smi-larb.yaml      | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index 80907e357892..884c0c74e5e4 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -80,10 +80,10 @@ allOf:
     then:
       properties:
         clock:
-          items:
-            minItems: 3
-            maxItems: 3
+          minItems: 2
+          maxItems: 3
         clock-names:
+          minItems: 2
           items:
             - const: apb
             - const: smi
-- 
2.18.0



From peng.fan at nxp.com  Mon Jan 10 22:45:00 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 11 Jan 2022 06:45:00 +0000
Subject: [PATCH 2/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QM
In-Reply-To: <20220111033333.403448-5-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-5-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB941738987CD958741E42E34B88519@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 2/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QM

+Rob

> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add i.MX8QM compatible
> 
> There are two general purpose M4, so add reg property to indicate the id.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml         | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git
> a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> index ed1bcb3046a9..cd9dcb63b176 100644
> --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> @@ -20,6 +20,7 @@ properties:
>        - fsl,imx8mn-cm7
>        - fsl,imx8mp-cm7
>        - fsl,imx8qxp-cm4
> +      - fsl,imx8qm-cm4
>        - fsl,imx8ulp-cm33
>        - fsl,imx7d-cm4
>        - fsl,imx7ulp-cm4
> @@ -63,6 +64,9 @@ properties:
>    power-domains:
>      maxItems: 8
> 
> +  reg:
> +    maxItems: 1
> +
>    rsrc-id:
>      description:
>        This property is to specify the resource id of the remote processor in
> SoC
> --
> 2.25.1



From yu.tu at amlogic.com  Mon Jan 10 23:04:14 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 15:04:14 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
Message-ID: <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>

Hi Jerome,
	Thank you very much for your reply.

On 2022/1/10 22:29, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
> 
> Title is bad (like several other patches in this series) - Please fix it
> Ok.
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>   1 file changed, 163 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..1004fd0b0c9e 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,13 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct uart_port	port;
>> +	struct clk		*pclk;
>> +	struct clk		*baud_clk;
>> +	bool			use_xtal_clk;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>   static int meson_uart_startup(struct uart_port *port)
>>   {
>>   	u32 val;
>> -	int ret = 0;
>> +	int ret;
>>   
>> -	val = readl(port->membase + AML_UART_CONTROL);
>> -	val |= AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> -	val &= ~AML_UART_CLEAR_ERR;
>> -	writel(val, port->membase + AML_UART_CONTROL);
>> +	meson_uart_reset(port);
>>   
>> +	val = readl(port->membase + AML_UART_CONTROL);
>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>   	writel(val, port->membase + AML_UART_CONTROL);
>>   
>> @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>> +	clk_disable_unprepare(private_data->pclk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->pclk);
>> +	if (ret)
>> +		return ret;
> 
> In the previous version of the series, you already been asked to the
> enable of pclk in the probe. Optimization should not be mixed with this
> series
> 
> Please make sure all comments are addressed before re-posting
> 
I'm sorry. I misunderstood you earlier. I'm going to move into the probe 
function.
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret) {
>> +		clk_disable_unprepare(private_data->pclk);
>> +		return ret;
>> +	}
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> +#define CLK_NAME(name) \
>> +({\
>> +	char clk_name[32];\
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>> +	clk_name;\
>> +})
> 
> 1) This result in some ugly code being inlined
> 2) You return a pointer a local variable which is not gurantee to exist
> anymore  outside of this ...
> 
> Please do this simply in the related function.
I've overdone it. I'll move it to the meson_uart_probe_clocks function 
as you suggested.
> 
>> +
>> +static struct clk_div_table xtal_div_table[] = {
>> +	{ 0, 3  },
>> +	{ 1, 1  },
>> +	{ 2, 2  },
>> +	{ 3, 2  },
>> +};
>> +
>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>   {
>> -	struct clk *clk = NULL;
>> -	int ret;
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	struct clk_hw *hw;
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
>>   
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>> +	if (IS_ERR(private_data->pclk))
>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>>   
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud)) {
>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +		return PTR_ERR(clk_baud);
>>   	}
>>   
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> -
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> -{
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> -
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> -
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> -
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	if (private_data->use_xtal_clk) {
>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>> +							CLK_NAME(xtal_div),
>> +							__clk_get_name(clk_baud),
>> +							CLK_SET_RATE_NO_REPARENT,
>> +							port->membase + AML_UART_REG5,
>> +							26, 2,
>> +							CLK_DIVIDER_READ_ONLY,
>> +							xtal_div_table, NULL);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[1].hw = hw;
>> +	} else {
>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +						       CLK_NAME(clk81_div4),
>> +						       __clk_get_name(clk_baud),
>> +						       CLK_SET_RATE_NO_REPARENT,
>> +						       1, 4);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[0].hw = hw;
>> +	}
> 
> Contradiction with previous series.
> In the previous series we could clearly see that gxbb did not have the
> /4 divider. It did not have bits 26 and 27 either.
> 
> Now gxbb get the /4 divider. It operated correctly without it so far, so
> this is rather suspicious. Could you please comment on this ?
> 
As Martin and I discussed earlier.
meson6 and meson8b SoC.There are not have bits 26 and 27 either.
CLK81 is recommended for this part of SOC.

GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
UART_EE_A_REG5[26]:
- 0x0: divide the input clock by 3 (meaning: this internally works
with an 8MHz clock)
- 0x1: use the input clock directly without further division (meaning:
this internally work with an 24MHz clock)
8MHz is recommended for this part of SOC. Their UART IP configuration is 
the same.

G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
UART_EE_A_REG5[27]:
- 0x0: use the clock as configured in UART_EE_A_REG5[26]
- 0x1: divide the input clock by 2 (meaning: this internally works
with an 12MHz clock)
12MHz is recommended for this part of SOC.

NOTE:
1. clk81 /4 divider.
There is a 4 divider inside, this is what the internal SOC designer told 
me. But they forgot to document it. So it makes people feel suspicious.

2.The UART_EE_A_REG5 default value is 0,except for the console port(set 
in romcode).All the baud rate clocks supported by UART can work, but 
different chip usage scenarios suggest using that clock to reduce jitter.

In summary, I would like to know your suggestions, including how to 
change compatible.
Thank you so much!

  >>
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +					CLK_NAME(use_xtal),
>> +					ARRAY_SIZE(use_xtal_mux_parents),
>> +					NULL, NULL,
>> +					use_xtal_mux_parents,
>> +					CLK_SET_RATE_PARENT,
>> +					port->membase + AML_UART_REG5,
>> +					24, 0x1,
>> +					CLK_MUX_READ_ONLY,
>> +					NULL, NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	port->uartclk = clk_hw_get_rate(hw);
>> +
>> +	hw = devm_clk_hw_register_divider(port->dev,
>> +					  CLK_NAME(baud_div),
>> +					  clk_hw_get_name(hw),
>> +					  CLK_SET_RATE_PARENT,
>> +					  port->membase + AML_UART_REG5,
>> +					  0, 23,
>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>> +					  NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
> 
> I have already commented on the use of this function in the previous
> version.
> 
> Please make sure all comments are addressed before re-posting
> 
I'm sorry. I misunderstood you earlier. I will be changed to
"private_data->baud_clk = hw->clk;".What do you think?
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem;
>>   	struct uart_port *port;
>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   		return -EBUSY;
>>   	}
>>   
>> -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
>> -	if (!port)
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>>   		return -ENOMEM;
>>   
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->use_xtal_clk = true;
>> +
>> +	port = &private_data->port;
>> +
>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> -
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>>   	port->mapsize = resource_size(res_mem);
>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = fifosize;
>> +	port->private_data = private_data;
> 
> port has private_data
> private_data has port
> 
> Is it really necessary to have both ... looks to me that port in
> private_data is overkill
> 
It's very thoughtful of you. I'll delete it as you suggested.
>>   
>> +	ret = meson_uart_probe_clocks(port);
>> +	if (ret)
>> +		return ret;
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>>   
>> @@ -766,10 +839,39 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxbb-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxl-uart",
>> +		.data = (void *)true,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-g12a-uart",
>> +		.data = (void *)true,
>> +	},
>> +	/*
>> +	 * deprecated, don't use anymore because it doesn't differentiate
>> +	 * between GXBB, GXL and G12A which have different revisions
>> +	 * of the UART IP.
>> +	 */
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)false,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From allen-kh.cheng at mediatek.com  Mon Jan 10 23:10:11 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 11 Jan 2022 15:10:11 +0800
Subject: [PATCH] firmware: mediatek: add adsp ipc protocol interface
Message-ID: <20220111071011.5964-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 ++
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 137 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++++
 6 files changed, 215 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..b45f16cec063
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *dsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	dsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(dsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "Wrong mbox chan %d \n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *dsp_ipc;
+	struct mtk_adsp_chan *dsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
+	if (!dsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		dsp_chan = &dsp_ipc->chans[i];
+		cl = &dsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		dsp_chan->ipc = dsp_ipc;
+		dsp_chan->idx = i;
+		dsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(dsp_chan->ch)) {
+			ret = PTR_ERR(dsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	dsp_ipc->dev = dev;
+	dev_set_drvdata(dev, dsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out:
+	kfree(chan_name);
+	for (j = 0; j < i; j++) {
+		dsp_chan = &dsp_ipc->chans[j];
+		mbox_free_channel(dsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *dsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *dsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		dsp_chan = &dsp_ipc->chans[i];
+		mbox_free_channel(dsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..08e3c7d3b405
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From yu.tu at amlogic.com  Mon Jan 10 23:18:13 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 11 Jan 2022 15:18:13 +0800
Subject: [PATCH V5 1/5] dt-bindings: serial: meson: Drop legacy compatible.
In-Reply-To: <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-2-yu.tu@amlogic.com>
 <CAL_JsqKFLnfc5eaUHeo6EkbS0kkpA94rh=Zuda9V9aCragdVxw@mail.gmail.com>
Message-ID: <fbca8027-f7f0-7822-5252-0be586a66496@amlogic.com>

Hi Rob,
	Thank you very much for your reply.

On 2022/1/11 0:18, Rob Herring wrote:
> [ EXTERNAL EMAIL ]
> 
> On Mon, Jan 10, 2022 at 4:42 AM Yu Tu <yu.tu at amlogic.com> wrote:
>>
>> Deprecated, don't use anymore because legacy amlogic,meson-gx-uart
>> compatible. Don't differentiate between GXBB, GXL and G12A which
>> have different revisions of the UART IP. So it's split into
>> GXBB,GXL and G12A.
> 
> You are breaking compatibility. If your dts is updated to use the new
> compatible, then a kernel without the change will not work anymore. It
> worked before without understanding the changes you are making. It
> should continue to. A compatible value like this would accomplish what
> you want:
> 
> "amlogic,meson-gxbb-uart", "amlogic,meson-gx-uart", "amlogic,meson-ao-uart"
> 
> A new kernel will match on "amlogic,meson-gxbb-uart" or
> "amlogic,meson-gx-uart" depending if the dtb is updated or not. An old
> kernel will continue to match on "amlogic,meson-gx-uart".
> 
> If you are going to go breaking things, the power domain distinction
> in the compatible is odd...
> 
I will not blindly delete this "amlogic, meson-gx-uart" compatible as 
you suggest, just make a comment until all DTS changes are finished.
> 
> Rob
> 


From alexander.stein at ew.tq-group.com  Mon Jan 10 23:20:01 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 11 Jan 2022 08:20:01 +0100
Subject: (EXT) Re: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt
 overlays for serial modes
In-Reply-To: <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
Message-ID: <2226437.ElGaqSPkdT@steina-w>

Am Dienstag, 11. Januar 2022, 01:00:21 CET schrieb Tim Harvey:
> [SNIP]
> > diff --git a/arch/arm64/boot/dts/freescale/Makefile
> > b/arch/arm64/boot/dts/freescale/Makefile index a14a6173b765..5ec8d59347b6
> > 100644
> > --- a/arch/arm64/boot/dts/freescale/Makefile
> > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > @@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
> > 
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
> > 
> > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
> > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
> > 
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
> >  dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
> > 
> [SNIP]
> I'm mostly interested to see if my approach to dt fragments here and
> the naming of the files makes sense to others.
> 
> This patch causes the kernel to build dtbo files for:
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dtbo
> arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dtbo
> 
> The intention is that these files are used by boot firmware (U-Boot)
> to adjust the dtb before passing it to the kernel.

Hi Tim,

do these dtbo actually work? I'm wondering because I was trying to useoverlays 
myself and noticed that the had to be compiled with -@ for u-boot to be able 
to apply them. Apparently there are 2 possibilities:
* Set "DTC_FLAGS_[dtb] := -@" yourself
See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
commit/?id=e426d63e752bdbe7d5ba2d872319dde9ab844a07

* Use dedicated overlay target
See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
commit/?id=15d16d6dadf6947ac7f9a686c615995c5a426ce2

You use neither of them. IIRC just naming the target file .dtbo will not apply 
symbols (-Q) during dtc call. Can you verify using 'V=1'
Also I'm wondering which way is the best to go.

Best regards,
Alexander





From lkp at intel.com  Mon Jan 10 23:21:21 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 15:21:21 +0800
Subject: [soc:for-next] BUILD SUCCESS 317a42bd9204fe5b76b0d57863f4994a89da3a98
Message-ID: <61dd2ff1.CoAy9EsC/hSd9kv1%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next
branch HEAD: 317a42bd9204fe5b76b0d57863f4994a89da3a98  ARM: Document merges

elapsed time: 723m

configs tested: 86
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm                              allyesconfig
arm                              allmodconfig
arm64                               defconfig
arm64                            allyesconfig
i386                          randconfig-c001
mips                 randconfig-c004-20220111
sh                         microdev_defconfig
arm                          iop32x_defconfig
arm                        clps711x_defconfig
powerpc                      arches_defconfig
mips                       bmips_be_defconfig
m68k                       bvme6000_defconfig
sh                   rts7751r2dplus_defconfig
riscv                            allyesconfig
arm                  randconfig-c002-20220111
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
nios2                            allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
xtensa                           allyesconfig
h8300                            allyesconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64                        randconfig-a006
x86_64                        randconfig-a004
x86_64                        randconfig-a002
i386                          randconfig-a012
i386                          randconfig-a014
i386                          randconfig-a016
riscv                randconfig-r042-20220111
arc                  randconfig-r043-20220111
s390                 randconfig-r044-20220111
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
um                             i386_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
arm                  randconfig-c002-20220111
x86_64                        randconfig-c007
riscv                randconfig-c006-20220111
powerpc              randconfig-c003-20220111
i386                          randconfig-c001
s390                 randconfig-c005-20220111
mips                 randconfig-c004-20220111
powerpc                     akebono_defconfig
powerpc                     kilauea_defconfig
powerpc                          g5_defconfig
i386                          randconfig-a002
i386                          randconfig-a006
i386                          randconfig-a004
x86_64                        randconfig-a012
x86_64                        randconfig-a014
x86_64                        randconfig-a016

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Mon Jan 10 23:20:57 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 11 Jan 2022 15:20:57 +0800
Subject: [soc:arm/late] BUILD SUCCESS 035434f0dd0dc659e3ef215fc504c1faa995fff8
Message-ID: <61dd2fd9.DebvpoF0B2cHbOpi%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git arm/late
branch HEAD: 035434f0dd0dc659e3ef215fc504c1faa995fff8  Merge tag 'amlogic-fixes-v5.17-rc-v2' of https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux into arm/late

elapsed time: 724m

configs tested: 121
configs skipped: 4

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                          randconfig-c001
mips                 randconfig-c004-20220111
powerpc                     tqm8541_defconfig
nios2                            allyesconfig
powerpc                      ppc40x_defconfig
m68k                        stmark2_defconfig
sh                           se7721_defconfig
mips                      fuloong2e_defconfig
csky                             alldefconfig
powerpc                       ppc64_defconfig
powerpc                     taishan_defconfig
sh                           se7780_defconfig
um                             i386_defconfig
h8300                               defconfig
xtensa                  nommu_kc705_defconfig
parisc                generic-64bit_defconfig
arc                    vdk_hs38_smp_defconfig
arm                        multi_v7_defconfig
sh                         microdev_defconfig
arm                          iop32x_defconfig
powerpc                    adder875_defconfig
parisc                           alldefconfig
arm                           viper_defconfig
mips                 decstation_r4k_defconfig
arm                        clps711x_defconfig
powerpc                      arches_defconfig
mips                       bmips_be_defconfig
arm                            zeus_defconfig
sh                           se7722_defconfig
ia64                        generic_defconfig
mips                         mpc30x_defconfig
arc                          axs103_defconfig
sh                          urquell_defconfig
arm                            hisi_defconfig
sh                             shx3_defconfig
m68k                       bvme6000_defconfig
sh                   rts7751r2dplus_defconfig
riscv                            allyesconfig
arm                  randconfig-c002-20220111
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                             allmodconfig
m68k                                defconfig
m68k                             allyesconfig
nds32                               defconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64                        randconfig-a006
x86_64                        randconfig-a004
x86_64                        randconfig-a002
i386                          randconfig-a012
i386                          randconfig-a014
i386                          randconfig-a016
riscv                randconfig-r042-20220111
arc                  randconfig-r043-20220111
s390                 randconfig-r044-20220111
riscv                    nommu_k210_defconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
arm                  randconfig-c002-20220111
x86_64                        randconfig-c007
riscv                randconfig-c006-20220111
powerpc              randconfig-c003-20220111
i386                          randconfig-c001
s390                 randconfig-c005-20220111
mips                 randconfig-c004-20220111
arm                     am200epdkit_defconfig
arm                          imote2_defconfig
powerpc                     akebono_defconfig
powerpc                     kilauea_defconfig
powerpc                          g5_defconfig
powerpc                     kmeter1_defconfig
powerpc                     tqm5200_defconfig
arm                  colibri_pxa300_defconfig
mips                           ip22_defconfig
i386                          randconfig-a002
i386                          randconfig-a006
i386                          randconfig-a004
x86_64                        randconfig-a012
x86_64                        randconfig-a014
x86_64                        randconfig-a016
x86_64                        randconfig-a005
x86_64                        randconfig-a003
x86_64                        randconfig-a001

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From reijiw at google.com  Mon Jan 10 23:37:57 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 10 Jan 2022 23:37:57 -0800
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
In-Reply-To: <YdwPCcZWD8Uc1eej@monolith.localdoman>
References: <20220110054042.1079932-1-reijiw@google.com>
 <YdwPCcZWD8Uc1eej@monolith.localdoman>
Message-ID: <CAAeT=Fz1KPbpmcSbukBuGWMJH=V_oXAJoaDHAen_Gy9Qswo_1Q@mail.gmail.com>

Hi Alex,

On Mon, Jan 10, 2022 at 2:48 AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Hi Reiji,
>
> On Sun, Jan 09, 2022 at 09:40:41PM -0800, Reiji Watanabe wrote:
> > vcpu_allowed_register_width() checks if all the VCPUs are either
> > all 32bit or all 64bit.  Since the checking is done even for vCPUs
> > that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
> > the non-initialized vCPUs are erroneously treated as 64bit vCPU,
> > which causes the function to incorrectly detect a mixed-width VM.
> >
> > Fix vcpu_allowed_register_width() to skip the check for vCPUs that
> > are not initialized yet.
> >
> > Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/kvm/reset.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > index 426bd7fbc3fd..ef78bbc7566a 100644
> > --- a/arch/arm64/kvm/reset.c
> > +++ b/arch/arm64/kvm/reset.c
> > @@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> >       if (kvm_has_mte(vcpu->kvm) && is32bit)
> >               return false;
> >
> > +     /*
> > +      * Make sure vcpu->arch.target setting is visible from others so
> > +      * that the width consistency checking between two vCPUs is done
> > +      * by at least one of them at KVM_ARM_VCPU_INIT.
> > +      */
> > +     smp_mb();
>
> From ARM DDI 0487G.a, page B2-146 ("Data Memory Barrier (DMB)"):
>
> "The DMB instruction is a memory barrier instruction that ensures the relative
> order of memory accesses before the barrier with memory accesses after the
> barrier."
>
> I'm going to assume from the comment that you are referring to completion of
> memory accesses ("Make sure [..] is visible from others"). Please correct me if
> I am wrong. In this case, DMB ensures ordering of memory accesses with regards
> to writes and reads, not *completion*.  Have a look at
> tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus for
> the classic message passing example as an example of memory ordering.
> Message passing and other patterns are also explained in ARM DDI 0487G.a, page
> K11-8363.
>
> I'm not saying that your approach is incorrect, but the commit message should
> explain what memory accesses are being ordered relative to each other and why.

Thank you so much for the review.
What I meant with the comment was:
---
  DMB is used to make sure that writing @vcpu->arch.target, which is done
  by kvm_vcpu_set_target() before getting here, is visible to other PEs
  before the following kvm_for_each_vcpu iteration reads the other vCPUs'
  target field.
---
Did the comment become more clear ?? (Or do I use DMB incorrectly ?)

> > +
> >       /* Check that the vcpus are either all 32bit or all 64bit */
> >       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> > +             /* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> > +             if (tmp->arch.target == -1)
> > +                     continue;

I just noticed DMB(ishld) is needed here to assure ordering between
reading tmp->arch.target and reading vcpu->arch.features for this fix.
Similarly, kvm_vcpu_set_target() needs DMB(ishst) to assure ordering
between writing vcpu->arch.features and writing vcpu->arch.target...
I am going to fix them in the v2 series.

Thanks,
Reiji

> > +
> >               if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit)
> >                       return false;
> >       }
> >
> > base-commit: df0cc57e057f18e44dac8e6c18aba47ab53202f9
> > --
> > 2.34.1.575.g55b058a8bb-goog
> >


From allen-kh.cheng at mediatek.com  Mon Jan 10 23:40:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 11 Jan 2022 15:40:23 +0800
Subject: [PATCH v11 0/2] This patches provide ADSP IPC support for MT8195
Message-ID: <20220111074025.22633-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between
processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox
registers to kick dsp.

Two mailboxes used to send notification or short message between processors with
dsp

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error

Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 176 ++++++++++++++++++
 4 files changed, 237 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 10 23:40:24 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 11 Jan 2022 15:40:24 +0800
Subject: [PATCH v11 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220111074025.22633-1-allen-kh.cheng@mediatek.com>
References: <20220111074025.22633-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220111074025.22633-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 10 23:40:25 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 11 Jan 2022 15:40:25 +0800
Subject: [PATCH v11 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220111074025.22633-1-allen-kh.cheng@mediatek.com>
References: <20220111074025.22633-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220111074025.22633-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 176 +++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..b8174f155f8d
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return &mbox->chans[sp->args[0]];
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear DSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear DSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



From jakub.daroch at betterbiz.pl  Mon Jan 10 23:45:52 2022
From: jakub.daroch at betterbiz.pl (Jakub Daroch)
Date: Tue, 11 Jan 2022 07:45:52 GMT
Subject: Wycena paneli fotowoltaicznych
Message-ID: <20220111024500-0.1.o.1038.0.kqlml8ak9i@betterbiz.pl>

Dzie? dobry,

dostrzegam mo?liwo?? wsp??pracy z Pa?stwa firm?.

?wiadczymy kompleksow? obs?ug? inwestycji w fotowoltaik?, kt?ra obni?a koszty energii elektrycznej nawet o 90%.

Czy s? Pa?stwo zainteresowani weryfikacj? wst?pnych propozycji?


Pozdrawiam,
Jakub Daroch


From guoheyi at linux.alibaba.com  Mon Jan 10 23:52:25 2022
From: guoheyi at linux.alibaba.com (Heyi Guo)
Date: Tue, 11 Jan 2022 15:52:25 +0800
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
In-Reply-To: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
References: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
Message-ID: <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>

Hi all,

Any comments?

Thanks,

Heyi

? 2022/1/9 ??9:26, Heyi Guo ??:
> The memory will be freed by the caller if transfer timeout occurs,
> then it would trigger kernel panic if the peer device responds with
> something after timeout and triggers the interrupt handler of aspeed
> i2c driver.
>
> Set the msgs pointer to NULL to avoid invalid memory reference after
> timeout to fix this potential kernel panic.
>
> Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>
>
> -------
>
> Cc: Brendan Higgins <brendanhiggins at google.com>
> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> Cc: Joel Stanley <joel at jms.id.au>
> Cc: Andrew Jeffery <andrew at aj.id.au>
> Cc: Philipp Zabel <p.zabel at pengutronix.de>
> Cc: linux-i2c at vger.kernel.org
> Cc: openbmc at lists.ozlabs.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-aspeed at lists.ozlabs.org
> ---
>   drivers/i2c/busses/i2c-aspeed.c | 5 +++++
>   1 file changed, 5 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> index 67e8b97c0c950..3ab0396168680 100644
> --- a/drivers/i2c/busses/i2c-aspeed.c
> +++ b/drivers/i2c/busses/i2c-aspeed.c
> @@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>   		spin_lock_irqsave(&bus->lock, flags);
>   		if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
>   			bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> +		/*
> +		 * All the buffers may be freed after returning to caller, so
> +		 * set msgs to NULL to avoid memory reference after freeing.
> +		 */
> +		bus->msgs = NULL;
>   		spin_unlock_irqrestore(&bus->lock, flags);
>   
>   		return -ETIMEDOUT;


From tudor.ambarus at microchip.com  Tue Jan 11 00:09:33 2022
From: tudor.ambarus at microchip.com (Tudor Ambarus)
Date: Tue, 11 Jan 2022 10:09:33 +0200
Subject: [PATCH] ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
Message-ID: <20220111080933.800414-1-tudor.ambarus@microchip.com>

PMERRLOC resource size has been shrunk to 0x100, which resulted in
HSMC_ERRLOCx register being truncated to offset x = 21, causing
error correction to fail if more than 22 bit errors where 24 or
32 bit error correction was supported.

Fixes: d9c41bf30cf8 ("ARM: dts: at91: Declare EBI/NAND controllers")
Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
---
 arch/arm/boot/dts/sama5d2.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 801969c113d6..de88eb484718 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -413,7 +413,7 @@ hsmc: hsmc at f8014000 {
 				pmecc: ecc-engine at f8014070 {
 					compatible = "atmel,sama5d2-pmecc";
 					reg = <0xf8014070 0x490>,
-					      <0xf8014500 0x100>;
+					      <0xf8014500 0x200>;
 				};
 			};
 
-- 
2.25.1



From aneesh.kumar at linux.ibm.com  Tue Jan 11 00:16:24 2022
From: aneesh.kumar at linux.ibm.com (Aneesh Kumar K.V)
Date: Tue, 11 Jan 2022 13:46:24 +0530
Subject: [PATCH v6 4/9] mm: multigenerational lru: groundwork
In-Reply-To: <20220104202227.2903605-5-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-5-yuzhao@google.com>
Message-ID: <878rvm661z.fsf@linux.ibm.com>

Yu Zhao <yuzhao at google.com> writes:

.....

 +
> +/*
> + * Evictable pages are divided into multiple generations. The youngest and the
> + * oldest generation numbers, max_seq and min_seq, are monotonically increasing.
> + * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
> + * offset within MAX_NR_GENS, gen, indexes the lru list of the corresponding
> + * generation. The gen counter in folio->flags stores gen+1 while a page is on
> + * lrugen->lists[]. Otherwise, it stores 0.
> + *
> + * A page is added to the youngest generation on faulting. The aging needs to
> + * check the accessed bit at least twice before handing this page over to the
> + * eviction. The first check takes care of the accessed bit set on the initial
> + * fault; the second check makes sure this page hasn't been used since then.
> + * This process, AKA second chance, requires a minimum of two generations,
> + * hence MIN_NR_GENS. And to be compatible with the active/inactive lru, these
> + * two generations are mapped to the active; the rest of generations, if they
> + * exist, are mapped to the inactive. PG_active is always cleared while a page
> + * is on lrugen->lists[] so that demotion, which happens consequently when the
> + * aging creates a new generation, needs not to worry about it.
> + */

Where do we clear PG_active in the code? Is this the reason we endup
with

  void deactivate_page(struct page *page)
  {
 -	if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) {
 +	if (PageLRU(page) && !PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) {




> +#define MIN_NR_GENS		2U
> +#define MAX_NR_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
> +
> +struct lru_gen_struct {
> +	/* the aging increments the youngest generation number */
> +	unsigned long max_seq;
> +	/* the eviction increments the oldest generation numbers */
> +	unsigned long min_seq[ANON_AND_FILE];
> +	/* the birth time of each generation in jiffies */
> +	unsigned long timestamps[MAX_NR_GENS];
> +	/* the multigenerational lru lists */
> +	struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
> +	/* the sizes of the above lists */
> +	unsigned long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
> +	/* whether the multigenerational lru is enabled */
> +	bool enabled;
> +};
> +

....

>  static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx, int nid,
> diff --git a/mm/swap.c b/mm/swap.c
> index e8c9dc6d0377..d7dde3b7d4b5 100644
> --- a/mm/swap.c
> +++ b/mm/swap.c
> @@ -462,6 +462,11 @@ void folio_add_lru(struct folio *folio)
>  	VM_BUG_ON_FOLIO(folio_test_active(folio) && folio_test_unevictable(folio), folio);
>  	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
>  
> +	/* see the comment in lru_gen_add_folio() */
> +	if (lru_gen_enabled() && !folio_test_unevictable(folio) &&
> +	    task_in_lru_fault() && !(current->flags & PF_MEMALLOC))
> +		folio_set_active(folio);
> +


Can you explain this better? What is the significance of marking the
folio active here. Do we need to differentiate parallel page faults (across
different vmas) w.r.t task_in_lru_fault()?


>  	folio_get(folio);
>  	local_lock(&lru_pvecs.lock);
>  	pvec = this_cpu_ptr(&lru_pvecs.lru_add);
> @@ -563,7 +568,7 @@ static void lru_deactivate_file_fn(struct page *page, struct lruvec *lruvec)
>  


From jiasheng at iscas.ac.cn  Tue Jan 11 00:16:47 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Tue, 11 Jan 2022 16:16:47 +0800
Subject: [PATCH] tty: serial: samsung_tty: Check null pointer after calling
 of_match_node
Message-ID: <20220111081647.637752-1-jiasheng@iscas.ac.cn>

If there is no suitable node, of_match_node() will return NULL pointer.
Therefore it should be better to check it in order to avoid the
dereference of NULL pointer.
And the only caller s3c24xx_serial_probe() has already checked the
return value of the s3c24xx_get_driver_data().
So the new check can be dealed with.

Fixes: 55ed51fff224 ("{tty: serial, nand: onenand}: samsung: rename to fix build warning")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
 drivers/tty/serial/samsung_tty.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c
index e2f49863e9c2..efbf9a7d5e92 100644
--- a/drivers/tty/serial/samsung_tty.c
+++ b/drivers/tty/serial/samsung_tty.c
@@ -2185,6 +2185,9 @@ s3c24xx_get_driver_data(struct platform_device *pdev)
 		const struct of_device_id *match;
 
 		match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
+		if (!match)
+			return NULL;
+
 		return (struct s3c24xx_serial_drv_data *)match->data;
 	}
 #endif
-- 
2.25.1



From suniel.spartan at gmail.com  Tue Jan 11 00:22:34 2022
From: suniel.spartan at gmail.com (Suniel Mahesh)
Date: Tue, 11 Jan 2022 13:52:34 +0530
Subject: [PATCH 0/4] media: rockchip: rga: PX30 support and YUV2YUV fix
Message-ID: <9e7aa8de-30cf-e3e0-4c5f-e4b989ea8b48@gmail.com>

Hi Paul/All,

I have added this patch series onto linux-next and testing RGA on PX30.

Log Snippet:
root at px30-engicam-px30-core-ctouch2:/# dmesg | grep rga
rockchip-rga ff480000.rga: HW Version: 0x04.00
rockchip-rga ff480000.rga: Registered rockchip-rga as /dev/video0

How do I test this ? In the email you mentioned:

I tested it with a standalone utility setting V4L2_PIX_FMT_YUV420 on 
both output and capture. The issue should be pretty easy to reproduce.

Can you please share more information/any procedure on how to test.

Thanks and Regards
Suniel Mahesh


From miles.chen at mediatek.com  Tue Jan 11 00:21:27 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 11 Jan 2022 16:21:27 +0800
Subject: [PATCH 1/1] thermal: mtk_thermal: fix kernel-doc warnings
Message-ID: <20220111082129.13459-1-miles.chen@mediatek.com>

Fix kernel-doc warnings:
drivers/thermal/mtk_thermal.c:562: warning: expecting prototype for raw_to_mcelsius(). Prototype was for raw_to_mcelsius_v1() instead

Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/thermal/mtk_thermal.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c
index ede94eadddda..0df369edfb7a 100644
--- a/drivers/thermal/mtk_thermal.c
+++ b/drivers/thermal/mtk_thermal.c
@@ -550,7 +550,7 @@ static const struct mtk_thermal_data mt8183_thermal_data = {
 };
 
 /**
- * raw_to_mcelsius - convert a raw ADC value to mcelsius
+ * raw_to_mcelsius_v1 - convert a raw ADC value to mcelsius v1
  * @mt:	The thermal controller
  * @sensno:	sensor number
  * @raw:	raw ADC value
@@ -573,6 +573,15 @@ static int raw_to_mcelsius_v1(struct mtk_thermal *mt, int sensno, s32 raw)
 	return mt->degc_cali * 500 - tmp;
 }
 
+/**
+ * raw_to_mcelsius_v2 - convert a raw ADC value to mcelsius v2
+ * @mt:	The thermal controller
+ * @sensno:	sensor number
+ * @raw:	raw ADC value
+ *
+ * This converts the raw ADC value to mcelsius using the SoC specific
+ * calibration constants
+ */
 static int raw_to_mcelsius_v2(struct mtk_thermal *mt, int sensno, s32 raw)
 {
 	s32 format_1;
-- 
2.18.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 00:24:37 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 09:24:37 +0100
Subject: [PATCH] tty: serial: samsung_tty: Check null pointer after
 calling of_match_node
In-Reply-To: <20220111081647.637752-1-jiasheng@iscas.ac.cn>
References: <20220111081647.637752-1-jiasheng@iscas.ac.cn>
Message-ID: <21f01245-9bcf-95fc-7781-a8da02029783@canonical.com>

On 11/01/2022 09:16, Jiasheng Jiang wrote:
> If there is no suitable node, of_match_node() will return NULL pointer.

NAK.

This is not possible. All drivers have such pattern and it was
discouraged to add empty/dead NULL checks.

If you think returning NULL is possible, please explain/document it.

> Therefore it should be better to check it in order to avoid the
> dereference of NULL pointer.
> And the only caller s3c24xx_serial_probe() has already checked the
> return value of the s3c24xx_get_driver_data().
> So the new check can be dealed with.
> 



Best regards,
Krzysztof


From maxime at cerno.tech  Tue Jan 11 00:24:54 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 11 Jan 2022 09:24:54 +0100
Subject: (subset) [PATCH] ARM: dts: nanopi-neo-air: Add eMMC and bluetooth
In-Reply-To: <20220104193719.87091-1-mike.rudenko@gmail.com>
References: <20220104193719.87091-1-mike.rudenko@gmail.com>
Message-ID: <164188927517.774115.5653853938961736601.b4-ty@cerno.tech>

On Tue, 4 Jan 2022 22:37:18 +0300, Mikhail Rudenko wrote:
> Enable the bluetooth part of AP6212 chip (connected to UART3) and the
> onboard eMMC (connected to MMC2) for the NanoPi NEO Air board.
> 
> 

Applied to local tree (sunxi/dt-for-5.18).

Thanks!
Maxime


From hch at lst.de  Tue Jan 11 00:35:10 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:10 +0100
Subject: consolidate the compat fcntl definitions
Message-ID: <20220111083515.502308-1-hch@lst.de>

Hi all,

currenty the compat fcnt definitions are duplicate for all compat
architectures, and the native fcntl64 definitions aren't even usable
from userspace due to a bogus CONFIG_64BIT ifdef.  This series tries
to sort out all that.

Diffstat:
 arch/arm64/include/asm/compat.h        |   20 --------------------
 arch/mips/include/asm/compat.h         |   23 ++---------------------
 arch/mips/include/uapi/asm/fcntl.h     |   28 +++-------------------------
 arch/parisc/include/asm/compat.h       |   16 ----------------
 arch/powerpc/include/asm/compat.h      |   20 --------------------
 arch/s390/include/asm/compat.h         |   20 --------------------
 arch/sparc/include/asm/compat.h        |   22 +---------------------
 arch/x86/include/asm/compat.h          |   24 +++---------------------
 include/linux/compat.h                 |   31 +++++++++++++++++++++++++++++++
 include/uapi/asm-generic/fcntl.h       |   21 +++++++--------------
 tools/include/uapi/asm-generic/fcntl.h |   21 +++++++--------------
 11 files changed, 54 insertions(+), 192 deletions(-)


From hch at lst.de  Tue Jan 11 00:35:11 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:11 +0100
Subject: [PATCH 1/5] uapi: remove the unused HAVE_ARCH_STRUCT_FLOCK64 define
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <20220111083515.502308-2-hch@lst.de>

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 include/uapi/asm-generic/fcntl.h       | 2 --
 tools/include/uapi/asm-generic/fcntl.h | 2 --
 2 files changed, 4 deletions(-)

diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index ecd0f5bdfc1d6..caa482e3b01af 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -207,7 +207,6 @@ struct flock {
 };
 #endif
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK64
 #ifndef __ARCH_FLOCK64_PAD
 #define __ARCH_FLOCK64_PAD
 #endif
@@ -220,6 +219,5 @@ struct flock64 {
 	__kernel_pid_t  l_pid;
 	__ARCH_FLOCK64_PAD
 };
-#endif
 
 #endif /* _ASM_GENERIC_FCNTL_H */
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index ac190958c9814..4a49d33ca4d55 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -202,7 +202,6 @@ struct flock {
 };
 #endif
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK64
 #ifndef __ARCH_FLOCK64_PAD
 #define __ARCH_FLOCK64_PAD
 #endif
@@ -215,6 +214,5 @@ struct flock64 {
 	__kernel_pid_t  l_pid;
 	__ARCH_FLOCK64_PAD
 };
-#endif
 
 #endif /* _ASM_GENERIC_FCNTL_H */
-- 
2.30.2



From andrzej.hajda at intel.com  Tue Jan 11 00:35:11 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 11 Jan 2022 09:35:11 +0100
Subject: [PATCH 1/2] arm64: dts: exynos: Link DSI panel at port@1 for TM2
 board
In-Reply-To: <20220110152714.58220-1-jagan@amarulasolutions.com>
References: <20220110152714.58220-1-jagan@amarulasolutions.com>
Message-ID: <9912c743-8acb-c59a-760a-a9b79ed48784@intel.com>

+CC: dri-devel

On 10.01.2022 16:27, Jagan Teki wrote:
> TM2 board DSI pipeline has input from MIC and output to
> s6e3ha2 panel.
>
> The existing pipeline has child nodes of ports, panel and
> MIC is remote-endpoint reference of port at 0 of ports.
>
> Adding panel as another child node to DSI is unconventional
> as pipeline has ports child. However it can be true if MIC
> is added inside port node like this.
>
> dsi {
> 	compatible = "samsung,exynos5433-mipi-dsi";
> 	#address-cells = <1>;
> 	#size-cells = <0>;
>
> 	port {
> 		dsi_to_mic: endpoint {
> 			remote-endpoint = <&mic_to_dsi>;
> 		};
> 	};
>
> 	panel at 0 {
> 		compatible = "samsung,s6e3hf2";
>                  reg = <0>;
>                  vdd3-supply = <&ldo27_reg>;
>                  vci-supply = <&ldo28_reg>;
>                  reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
>                  enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> 	};
> };
>
> The above pipeline is proper but it requires the DSI input MIC
> pipeline to update.
>
> This patch is trying to add panel at port at 1 so-that the entire
> pipeline before to panel output is untouched.
>
> Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> ---
>   arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> index aca01709fd29..e13210c8d7e0 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> @@ -53,6 +53,16 @@ &cmu_disp {
>   };
>   
>   &dsi {
> +	ports {
> +		port at 1 {
> +			reg = <1>;
> +
> +			dsi_out_panel: endpoint {
> +				remote-endpoint = <&dsi_in_panel>;
> +			};
> +		};
> +	};
> +
>   	panel at 0 {
>   		compatible = "samsung,s6e3ha2";
>   		reg = <0>;
> @@ -60,6 +70,12 @@ panel at 0 {
>   		vci-supply = <&ldo28_reg>;
>   		reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
>   		enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> +
> +		port {
> +			dsi_in_panel: endpoint {
> +				remote-endpoint = <&dsi_out_panel>;
> +			};
> +		};


As I already wrote in Exynos thread, DSI host has already parent-child 
relation with the panel - DSI host knows well who is connected to it. 
Adding another links between them is redundant and has no value added.

I have already answered in Exynos thread[1] how could you deal with the 
issue, you have.

[1]: 
https://lore.kernel.org/dri-devel/e541c52b-9751-933b-5eac-783dd0ed9056 at intel.com/


Regards

Andrzej


>   	};
>   };
>   


From hch at lst.de  Tue Jan 11 00:35:12 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:12 +0100
Subject: [PATCH 2/5] uapi: simplify __ARCH_FLOCK{,64}_PAD a little
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <20220111083515.502308-3-hch@lst.de>

Don't bother to define the symbols empty, just don't use them.  That
makes the intent a little more clear.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 include/uapi/asm-generic/fcntl.h       | 12 ++++--------
 tools/include/uapi/asm-generic/fcntl.h | 12 ++++--------
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index caa482e3b01af..c53897ca5d402 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -193,22 +193,16 @@ struct f_owner_ex {
 #define F_LINUX_SPECIFIC_BASE	1024
 
 #ifndef HAVE_ARCH_STRUCT_FLOCK
-#ifndef __ARCH_FLOCK_PAD
-#define __ARCH_FLOCK_PAD
-#endif
-
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
 	__kernel_pid_t	l_pid;
+#ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
-};
 #endif
-
-#ifndef __ARCH_FLOCK64_PAD
-#define __ARCH_FLOCK64_PAD
+};
 #endif
 
 struct flock64 {
@@ -217,7 +211,9 @@ struct flock64 {
 	__kernel_loff_t l_start;
 	__kernel_loff_t l_len;
 	__kernel_pid_t  l_pid;
+#ifdef __ARCH_FLOCK64_PAD
 	__ARCH_FLOCK64_PAD
+#endif
 };
 
 #endif /* _ASM_GENERIC_FCNTL_H */
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index 4a49d33ca4d55..82054502b9748 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -188,22 +188,16 @@ struct f_owner_ex {
 #define F_LINUX_SPECIFIC_BASE	1024
 
 #ifndef HAVE_ARCH_STRUCT_FLOCK
-#ifndef __ARCH_FLOCK_PAD
-#define __ARCH_FLOCK_PAD
-#endif
-
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
 	__kernel_pid_t	l_pid;
+#ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
-};
 #endif
-
-#ifndef __ARCH_FLOCK64_PAD
-#define __ARCH_FLOCK64_PAD
+};
 #endif
 
 struct flock64 {
@@ -212,7 +206,9 @@ struct flock64 {
 	__kernel_loff_t l_start;
 	__kernel_loff_t l_len;
 	__kernel_pid_t  l_pid;
+#ifdef __ARCH_FLOCK64_PAD
 	__ARCH_FLOCK64_PAD
+#endif
 };
 
 #endif /* _ASM_GENERIC_FCNTL_H */
-- 
2.30.2



From hch at lst.de  Tue Jan 11 00:35:13 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:13 +0100
Subject: [PATCH 3/5] uapi: merge the 32-bit mips struct flock into the generic
 one
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <20220111083515.502308-4-hch@lst.de>

Add a new __ARCH_FLOCK_EXTRA_SYSID macro following the style of
__ARCH_FLOCK_PAD to avoid having a separate definition just for one
architecture.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/mips/include/uapi/asm/fcntl.h     | 26 +++-----------------------
 include/uapi/asm-generic/fcntl.h       |  5 +++--
 tools/include/uapi/asm-generic/fcntl.h |  5 +++--
 3 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 42e13dead5431..9e44ac810db94 100644
--- a/arch/mips/include/uapi/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
@@ -50,30 +50,10 @@
 #define F_SETLKW64	35
 #endif
 
-/*
- * The flavours of struct flock.  "struct flock" is the ABI compliant
- * variant.  Finally struct flock64 is the LFS variant of struct flock.	 As
- * a historic accident and inconsistence with the ABI definition it doesn't
- * contain all the same fields as struct flock.
- */
-
 #if _MIPS_SIM != _MIPS_SIM_ABI64
-
-#include <linux/types.h>
-
-struct flock {
-	short	l_type;
-	short	l_whence;
-	__kernel_off_t	l_start;
-	__kernel_off_t	l_len;
-	long	l_sysid;
-	__kernel_pid_t l_pid;
-	long	pad[4];
-};
-
-#define HAVE_ARCH_STRUCT_FLOCK
-
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+#define __ARCH_FLOCK_EXTRA_SYSID	long l_sysid;
+#define __ARCH_FLOCK_PAD		long pad[4];
+#endif
 
 #include <asm-generic/fcntl.h>
 
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index c53897ca5d402..98f4ff165b776 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -192,18 +192,19 @@ struct f_owner_ex {
 
 #define F_LINUX_SPECIFIC_BASE	1024
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
+#ifdef __ARCH_FLOCK_EXTRA_SYSID
+	__ARCH_FLOCK_EXTRA_SYSID
+#endif
 	__kernel_pid_t	l_pid;
 #ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
 #endif
 };
-#endif
 
 struct flock64 {
 	short  l_type;
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index 82054502b9748..bf961a71802e0 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -187,18 +187,19 @@ struct f_owner_ex {
 
 #define F_LINUX_SPECIFIC_BASE	1024
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
+#ifdef __ARCH_FLOCK_EXTRA_SYSID
+	__ARCH_FLOCK_EXTRA_SYSID
+#endif
 	__kernel_pid_t	l_pid;
 #ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
 #endif
 };
-#endif
 
 struct flock64 {
 	short  l_type;
-- 
2.30.2



From hch at lst.de  Tue Jan 11 00:35:14 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:14 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <20220111083515.502308-5-hch@lst.de>

The fcntl F_GETLK64/F_SETLK64/F_SETLKW64 are only implemented for the
32-bit syscall APIs, but we also need them for compat handling on 64-bit
builds.  Redefining them is error prone (as shown by the example that
parisc gets it wrong currently), so we should use the same defines for
both case.  In theory we could try to hide them from userspace, but
given that only MIPS actually gets that right, while the asm-generic
version used by most architectures relies on a Kconfig symbol that can't
be relied on to be set properly by userspace is a clear indicator to not
bother.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/arm64/include/asm/compat.h        | 4 ----
 arch/mips/include/asm/compat.h         | 4 ----
 arch/mips/include/uapi/asm/fcntl.h     | 2 --
 arch/powerpc/include/asm/compat.h      | 4 ----
 arch/s390/include/asm/compat.h         | 4 ----
 arch/sparc/include/asm/compat.h        | 4 ----
 arch/x86/include/asm/compat.h          | 4 ----
 include/uapi/asm-generic/fcntl.h       | 2 --
 tools/include/uapi/asm-generic/fcntl.h | 2 --
 9 files changed, 30 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eaa6ca062d89b..2763287654081 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -73,10 +73,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index bbb3bc5a42fd8..6a350c1f70d7e 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -65,10 +65,6 @@ struct compat_flock {
 	s32		pad[4];
 };
 
-#define F_GETLK64	33
-#define F_SETLK64	34
-#define F_SETLKW64	35
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 9e44ac810db94..1769fc50d35f0 100644
--- a/arch/mips/include/uapi/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
@@ -44,11 +44,9 @@
 #define F_SETOWN	24	/*  for sockets. */
 #define F_GETOWN	23	/*  for sockets. */
 
-#ifndef __mips64
 #define F_GETLK64	33	/*  using 'struct flock64' */
 #define F_SETLK64	34
 #define F_SETLKW64	35
-#endif
 
 #if _MIPS_SIM != _MIPS_SIM_ABI64
 #define __ARCH_FLOCK_EXTRA_SYSID	long l_sysid;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 7afc96fb6524b..83d8f70779cbc 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -52,10 +52,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index cdc7ae72529d8..0f14b3188b1bb 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -110,10 +110,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64       12
-#define F_SETLK64       13
-#define F_SETLKW64      14    
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index bd949fcf9d63b..108078751bb5a 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -84,10 +84,6 @@ struct compat_flock {
 	short		__unused;
 };
 
-#define F_GETLK64	12
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7516e4199b3c6..8d19a212f4f26 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -58,10 +58,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 /*
  * IA32 uses 4 byte alignment for 64 bit quantities,
  * so we need to pack this structure.
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 98f4ff165b776..43d7c44031be0 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -116,13 +116,11 @@
 #define F_GETSIG	11	/* for sockets. */
 #endif
 
-#ifndef CONFIG_64BIT
 #ifndef F_GETLK64
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 #endif
-#endif
 
 #ifndef F_SETOWN_EX
 #define F_SETOWN_EX	15
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index bf961a71802e0..6e16722026f39 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -115,13 +115,11 @@
 #define F_GETSIG	11	/* for sockets. */
 #endif
 
-#ifndef CONFIG_64BIT
 #ifndef F_GETLK64
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 #endif
-#endif
 
 #ifndef F_SETOWN_EX
 #define F_SETOWN_EX	15
-- 
2.30.2



From hch at lst.de  Tue Jan 11 00:35:15 2022
From: hch at lst.de (Christoph Hellwig)
Date: Tue, 11 Jan 2022 09:35:15 +0100
Subject: [PATCH 5/5] compat: consolidate the compat_flock{,64} definition
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <20220111083515.502308-6-hch@lst.de>

Provide a single common definition for the compat_flock and
compat_flock64 structures using the same tricks as for the native
variants.  Another extra define is added for the packing required on
x86.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/arm64/include/asm/compat.h   | 16 ----------------
 arch/mips/include/asm/compat.h    | 19 ++-----------------
 arch/parisc/include/asm/compat.h  | 16 ----------------
 arch/powerpc/include/asm/compat.h | 16 ----------------
 arch/s390/include/asm/compat.h    | 16 ----------------
 arch/sparc/include/asm/compat.h   | 18 +-----------------
 arch/x86/include/asm/compat.h     | 20 +++-----------------
 include/linux/compat.h            | 31 +++++++++++++++++++++++++++++++
 8 files changed, 37 insertions(+), 115 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 2763287654081..e0faec1984a1c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -65,22 +65,6 @@ struct compat_stat {
 	compat_ulong_t	__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 6a350c1f70d7e..6d6e5a451f4d9 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -55,23 +55,8 @@ struct compat_stat {
 	s32		st_pad4[14];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	s32		l_sysid;
-	compat_pid_t	l_pid;
-	s32		pad[4];
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
+#define __ARCH_COMPAT_FLOCK_EXTRA_SYSID		s32 l_sysid;
+#define __ARCH_COMPAT_FLOCK_PAD			s32 pad[4];
 
 struct compat_statfs {
 	int		f_type;
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c04f5a637c390..a1e4534d80509 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -53,22 +53,6 @@ struct compat_stat {
 	u32			st_spare4[3];
 };
 
-struct compat_flock {
-	short			l_type;
-	short			l_whence;
-	compat_off_t		l_start;
-	compat_off_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_flock64 {
-	short			l_type;
-	short			l_whence;
-	compat_loff_t		l_start;
-	compat_loff_t		l_len;
-	compat_pid_t		l_pid;
-};
-
 struct compat_statfs {
 	s32		f_type;
 	s32		f_bsize;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 83d8f70779cbc..5ef3c7c83c343 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -44,22 +44,6 @@ struct compat_stat {
 	u32		__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 0f14b3188b1bb..07f04d37068b6 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -102,22 +102,6 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	u32		f_type;
 	u32		f_bsize;
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index 108078751bb5a..d78fb44942e0f 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -75,23 +75,7 @@ struct compat_stat64 {
 	unsigned int	__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-	short		__unused;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-	short		__unused;
-};
+#define __ARCH_COMPAT_FLOCK_PAD		short __unused;
 
 struct compat_statfs {
 	int		f_type;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 8d19a212f4f26..de794d8958663 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -50,25 +50,11 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 /*
- * IA32 uses 4 byte alignment for 64 bit quantities,
- * so we need to pack this structure.
+ * IA32 uses 4 byte alignment for 64 bit quantities, so we need to pack the
+ * compat flock64 structure.
  */
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-} __attribute__((packed));
+#define __ARCH_NEED_COMPAT_FLOCK64_PACKED
 
 struct compat_statfs {
 	int		f_type;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1c758b0e03598..a0481fe6c5d51 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -258,6 +258,37 @@ struct compat_rlimit {
 	compat_ulong_t	rlim_max;
 };
 
+#ifdef __ARCH_NEED_COMPAT_FLOCK64_PACKED
+#define __ARCH_COMPAT_FLOCK64_PACK	__attribute__((packed))
+#else
+#define __ARCH_COMPAT_FLOCK64_PACK
+#endif
+
+struct compat_flock {
+	short			l_type;
+	short			l_whence;
+	compat_off_t		l_start;
+	compat_off_t		l_len;
+#ifdef __ARCH_COMPAT_FLOCK_EXTRA_SYSID
+	__ARCH_COMPAT_FLOCK_EXTRA_SYSID
+#endif
+	compat_pid_t		l_pid;
+#ifdef __ARCH_COMPAT_FLOCK_PAD
+	__ARCH_COMPAT_FLOCK_PAD
+#endif
+};
+
+struct compat_flock64 {
+	short		l_type;
+	short		l_whence;
+	compat_loff_t	l_start;
+	compat_loff_t	l_len;
+	compat_pid_t	l_pid;
+#ifdef __ARCH_COMPAT_FLOCK64_PAD
+	__ARCH_COMPAT_FLOCK64_PAD
+#endif
+} __ARCH_COMPAT_FLOCK64_PACK;
+
 struct compat_rusage {
 	struct old_timeval32 ru_utime;
 	struct old_timeval32 ru_stime;
-- 
2.30.2



From yuzhao at google.com  Tue Jan 11 00:41:22 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 11 Jan 2022 01:41:22 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YdSuSHa/Vjl6bPkg@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com>
Message-ID: <Yd1Css8+jsspeZHh@google.com>

On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > TLDR
> > ====
> > The current page reclaim is too expensive in terms of CPU usage and it
> > often makes poor choices about what to evict. This patchset offers an
> > alternative solution that is performant, versatile and
> > straightforward.
> 
> <snipped>
> 
> > Summery
> > =======
> > The facts are:
> > 1. The independent lab results and the real-world applications
> >    indicate substantial improvements; there are no known regressions.
> > 2. Thrashing prevention, working set estimation and proactive reclaim
> >    work out of the box; there are no equivalent solutions.
> > 3. There is a lot of new code; nobody has demonstrated smaller changes
> >    with similar effects.
> > 
> > Our options, accordingly, are:
> > 1. Given the amount of evidence, the reported improvements will likely
> >    materialize for a wide range of workloads.
> > 2. Gauging the interest from the past discussions [14][15][16], the
> >    new features will likely be put to use for both personal computers
> >    and data centers.
> > 3. Based on Google's track record, the new code will likely be well
> >    maintained in the long term. It'd be more difficult if not
> >    impossible to achieve similar effects on top of the existing
> >    design.
> 
> Hi Andrew, Linus,
> 
> Can you please take a look at this patchset and let me know if it's
> 5.17 material?
> 
> My goal is to get it merged asap so that users can reap the benefits
> and I can push the sequels. Please examine the data provided -- I
> think the unprecedented coverage and the magnitude of the improvements
> warrant a green light.

Downstream kernel maintainers who have been carrying MGLRU for more than
3 versions, can you please provide your Acked-by tags?

Having this patchset in the mainline will make your job easier :)

   Alexandre - the XanMod Kernel maintainer
               https://xanmod.org
   
   Brian     - the Chrome OS kernel memory maintainer
               https://www.chromium.org
   
   Jan       - the Arch Linux Zen kernel maintainer
               https://archlinux.org
   
   Steven    - the Liquorix kernel maintainer
               https://liquorix.net
   
   Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
               https://chromium.googlesource.com/chromiumos/third_party/kernel

Also my gratitude to those who have helped test MGLRU:

   Daniel - researcher at Michigan Tech
            benchmarked memcached
   
   Holger - who has been testing/patching/contributing to various
            subsystems since ~2008
   
   Shuang - researcher at University of Rochester
            benchmarked fio and provided a report
   
   Sofia  - EDI https://www.edi.works
            benchmarked the top eight memory hogs and provided reports

Can you please provide your Tested-by tags? This will ensure the credit
for your contributions.

Thanks!


From tzimmermann at suse.de  Tue Jan 11 00:52:24 2022
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue, 11 Jan 2022 09:52:24 +0100
Subject: [PATCH v3 00/10] drm: Make drivers to honour the nomodeset
 parameter
In-Reply-To: <20211222082831.196562-1-javierm@redhat.com>
References: <20211222082831.196562-1-javierm@redhat.com>
Message-ID: <1a5bd538-063b-c2cf-bb3e-96a6fdb0da0f@suse.de>

Hi

patches 6 to 10 are

Acked-by: Thomas Zimmermann <tzimmermann at suse.de>

Best regards
Thomas

Am 22.12.21 um 09:28 schrieb Javier Martinez Canillas:
> The nomodeset kernel command line parameter is used to prevent the KMS/DRM
> drivers to be registered/probed. But only a few drivers implement support
> for this and most DRM drivers just ignore it.
> 
> This patch series is a v3 to make DRM drivers to honour nomodeset. It is
> posted as separate patches to make easier for drivers maintainers to ack
> or pick them independently at their own pace.
> 
> The drm_module_{pci,platform}_driver() helper macros are added, which are
> just wrappers around module_{pci,platform}_driver() but adding a check for
> drm_firmware_drivers_only() and returning -ENODEV if that is true.
> 
> PCI and platform DRM drivers are then modified in the following patches to
> make use of those macros.
> 
> Only KMS drivers will be ported to use these new macros, and only for PCI
> and platform DRM drivers. A follow-up series might do the same for drivers
> that are rendering-only and for USB/SPI/I2C devices, but it will need more
> discussion to agree whether that's desirable or not.
> 
> Not all drivers were posted in v3 to avoid flooding the list with too many
> patches. I'm only including the patches adding the macros and some patches
> as an example of their usage.
> 
> I've built tested with 'make allmodconfig && make M=drivers/gpu/drm' but I
> don't have hardware to test the drivers, so review/testing is appreciated.
> 
> Best regards,
> Javier
> 
> Changes in v3:
> - Include Thomas Zimmermann's patches in the series and rebase on top.
> - Add collected Acked-by tags from v2.
> 
> Changes in v2:
> - Add drm_module_{pci,platform}_driver() macros and put the check there
>    (Thomas Zimmermann).
> - Use the drm_module_*_driver() macros if possible (Thomas Zimmermann).
> - Leave the DRM drivers that don't set the DRIVER_MODESET driver feature
>    (Lucas Stach).
> - Leave USB/SPI/I2C drivers and only include PCI and platform ones
>    (Noralf Tr?nnes).
> - Add collected Reviewed-by tags
> 
> Javier Martinez Canillas (5):
>    drm: Provide platform module-init macro
>    drm/imx/dcss: Replace module initialization with DRM helpers
>    drm/komeda: Replace module initialization with DRM helpers
>    drm/arm/hdlcd: Replace module initialization with DRM helpers
>    drm/malidp: Replace module initialization with DRM helpers
> 
> Thomas Zimmermann (5):
>    drm: Provide PCI module-init macros
>    drm/ast: Replace module-init boiler-plate code with DRM helpers
>    drm/bochs: Replace module-init boiler-plate code with DRM helpers
>    drm/cirrus: Replace module-init boiler-plate code with DRM helpers
>    drm/hisilicon/hibmc: Replace module initialization with DRM helpers
> 
>   Documentation/gpu/drm-internals.rst           |   6 +
>   .../gpu/drm/arm/display/komeda/komeda_drv.c   |   3 +-
>   drivers/gpu/drm/arm/hdlcd_drv.c               |   3 +-
>   drivers/gpu/drm/arm/malidp_drv.c              |   3 +-
>   drivers/gpu/drm/ast/ast_drv.c                 |  18 +--
>   .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   3 +-
>   drivers/gpu/drm/imx/dcss/dcss-drv.c           |   3 +-
>   drivers/gpu/drm/tiny/bochs.c                  |  20 +--
>   drivers/gpu/drm/tiny/cirrus.c                 |  17 +--
>   include/drm/drm_module.h                      | 125 ++++++++++++++++++
>   10 files changed, 147 insertions(+), 54 deletions(-)
>   create mode 100644 include/drm/drm_module.h
> 

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Ivo Totev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/1be8c7fd/attachment-0001.sig>

From heying24 at huawei.com  Tue Jan 11 00:52:32 2022
From: heying24 at huawei.com (He Ying)
Date: Tue, 11 Jan 2022 16:52:32 +0800
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <YdwX5RTVbw8veM98@FVFF77S0Q05N>
References: <20220107085536.214501-1-heying24@huawei.com>
 <Ydg939btY/bzEAe4@FVFF77S0Q05N>
 <bd82d240-34d7-4df9-650b-c039555f05e3@huawei.com>
 <YdwX5RTVbw8veM98@FVFF77S0Q05N>
Message-ID: <168f7e83-e815-f10e-3a43-8529aab77f1e@huawei.com>

Hi Mark,

? 2022/1/10 19:26, Mark Rutland ??:
> On Mon, Jan 10, 2022 at 11:00:43AM +0800, He Ying wrote:
>> Hi Mark,
>>
>> I'm just back from the weekend and sorry for the delayed reply.
>>
>>
>> ? 2022/1/7 21:19, Mark Rutland ??:
>>> On Fri, Jan 07, 2022 at 03:55:36AM -0500, He Ying wrote:
>>>> Our product has been updating its kernel from 4.4 to 5.10 recently and
>>>> found a performance issue. We do a bussiness test called ARP test, which
>>>> tests the latency for a ping-pong packets traffic with a certain payload.
>>>> The result is as following.
>>>>
>>>>    - 4.4 kernel: avg = ~20s
>>>>    - 5.10 kernel (CONFIG_ARM64_PSEUDO_NMI is not set): avg = ~40s
>>> Have you tested with a recent mainline kernel, e.g. v5.15?
>> Actuallly no, that's because this test is only available for the product
>> environment and
>>
>> we don't have an available 5.15 kernel for it yet.
> Ok; do you see anything comparable with any tests available to upstream
> developers? e.g. hackbench or `perf bench sched` ?

I'm not sure. The test is some kind of network test. And I don't know which

bench test is comparable.

>
>>> Is this test publicly available, and can you say which hardrware (e.g. which
>>> CPU implementation) you're testing with?
>> Actually no. The test is only available for our product environment now. We
>> are testing
>>
>> with hisilicon 1213 (4 ARM Cortex-A72 cores).
> Thanks for the CPU info; there are a number of other Cortex-A72 platforms out
> there, so it might be possible to reproduce the behaviour elsewhere.

I asked our collegues how they did the test. Actually it's a private 
test and

difficult to be reproduced elsewhere. But I got another important 
information.

See below.

>
>>>> I have been just learning arm64 pseudo-NMI code and have a question,
>>>> why is the related code not wrapped by CONFIG_ARM64_PSEUDO_NMI?
>>> The code in question is all patched via alternatives, and when
>>> CONFIG_ARM64_PSEUDO_NMI is not selected, the code was expected to only have the
>>> overhead of the regular DAIF manipulation.
>> I don't understand alernatives very well and I'll apreciate it if you can
>> explain it a bit more.
> Code using alternatives is patched at runtime, so for:
>
> 	ALTERNATIVE(x, y, cap)
>
> ... the `x` instructions will be inline in the code, and the `y` instructions
> will be placed in a separate linker section. If the `cap` capability is
> detected, the `y` instructions will be copied over the `x` instructions.
>
> So for:
>
> | asm volatile(ALTERNATIVE(
> |         "msr    daifclr, #3             // arch_local_irq_enable",
> |         __msr_s(SYS_ICC_PMR_EL1, "%0"),
> |         ARM64_HAS_IRQ_PRIO_MASKING)
> |         :
> |         : "r" ((unsigned long) GIC_PRIO_IRQON)
> |         : "memory");
>
> ... where ARM64_HAS_IRQ_PRIO_MASKING is not detected, the inline instructions
> will be:
>
> | msr    daifclr, #3             // arch_local_irq_enable
>
> A separate linker section will contain:
> ... and a separate linker section will contain:
>
> | __msr_s(SYS_ICC_PMR_EL1, "%0"
>
> ... and some metadata will be recorded in a `struct alt_instr`, which will be
> unused and will take some space, but should have no runtime overhead -- the
> runtime cost should only be the `msr daifclr, #3` instruction.

Thank you very much for the detailed explanation. I think I understand 
it better.

I agree that these ALERNATIVEs might only bring some additional space but no

runtime overhead.

>
>>>> I wonder if this brings some performance regression.
>>>>
>>>> First, I make this patch and then do the test again. Here's the result.
>>>>
>>>>    - 5.10 kernel with this patch not applied: avg = ~40s
>>>>    - 5.10 kernel with this patch applied: avg = ~23s
>>>>
>>>> Amazing! Note that all kernel is built with CONFIG_ARM64_PSEUDO_NMI not
>>>> set. It seems the pseudo-NMI feature actually brings some overhead to
>>>> performance event if CONFIG_ARM64_PSEUDO_NMI is not set.
>>> I'm surprised the overhead is so significant; as above this is all patched in
>>> and so the overhead when this is disabled is expected to be *extremely* small.
>>>
>>> For example, wjen CONFIG_ARM64_PSEUDO_NMI, in arch_local_irq_enable():
>>>
>>> * The portion under the system_has_prio_mask_debugging() test will be removed
>>>     entirely by the compiler, as this internally checks
>>>     IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI).
>>>
>>> * The assembly will be left as a write to DAIFClr. The only additional cost
>>>     should be that of generating GIC_PRIO_IRQON into a register.
>>>
>>> * The pmr_sync() will be removed entirely by the compiler as is defined
>>>     conditionally dependent on CONFIG_ARM64_PSEUDO_NMI.
>>>
>>> I can't spot an obvious issue with that or ther other cases. In the common case
>>> those add no new instructions, and in the worst case they only add NOPs.
>> Thanks for your detailed explaination! Actually I can't understand the
>> result exactly.
>>
>> I build two 5.10 kernel images with this patch applied or not and objdump
>> them. Indeed, the disassembles of 'arch_local_irq_restore' are the same. Do
>> you have any ideas how we can find the root cause why this patch improves the
>> performance so much?
>>
>> However, the test result is trustworthy because we do it many times and the
>> result is always repeatable.
> Due to the large numbers, I suspect this must be due to a specific fast-path,
> and it's possible that this is due to secondary factors (e.g. alignment of
> code) rather than the pseudo-NMK code itself.
>
> We need to narrow down *where* time is being spent. Since it appears that this
> is related to the local IRQ state management, it isn't likely that we can
> determine that reliably with the PMU. Given that, I think the first step is to
> reproduce the result elsewhere, for which we will need some plublicly available
> test-case.

As said before, I asked our collegues how they did the ARP test. In one 
word,

a very small performance regression may bring the big change to the test 
result.

I feel very sorry for missing this important information. So, this patch may

improve the performance a little and then lead to the big change to the

test result.

>
>>>> Furthermore, I find the feature also brings some overhead to vmlinux size.
>>>> I build 5.10 kernel with this patch applied or not while
>>>> CONFIG_ARM64_PSEUDO_NMI is not set.
>>>>
>>>>    - 5.10 kernel with this patch not applied: vmlinux size is 384060600 Bytes.
>>>>    - 5.10 kernel with this patch applied: vmlinux size is 383842936 Bytes.
>>>>
>>>> That means arm64 pseudo-NMI feature may bring ~200KB overhead to
>>>> vmlinux size.
>>> I suspect that's just the (unused) alternatives, and we could improve that by
>>> passing the config into the alternative blocks.
>> Do you mean the sections generated by the alternatives? I don't understand
>> alernatives very well and I'll apreciate it if you can explain it a bit
>> more.
> Yes; I meant the sections generated to hold the alternatives code and the
> alternatives metadata.
I got it. Thanks.
>
>
>>>> Above all, arm64 pseudo-NMI feature brings some overhead to vmlinux size
>>>> and performance even if config is not set. To avoid it, add macro control
>>>> all around the related code.
>>>>
>>>> Signed-off-by: He Ying <heying24 at huawei.com>
>>>> ---
>>>>    arch/arm64/include/asm/irqflags.h | 38 +++++++++++++++++++++++++++++--
>>>>    arch/arm64/kernel/entry.S         |  4 ++++
>>>>    2 files changed, 40 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/include/asm/irqflags.h b/arch/arm64/include/asm/irqflags.h
>>>> index b57b9b1e4344..82f771b41cf5 100644
>>>> --- a/arch/arm64/include/asm/irqflags.h
>>>> +++ b/arch/arm64/include/asm/irqflags.h
>>>> @@ -26,6 +26,7 @@
>>>>     */
>>>>    static inline void arch_local_irq_enable(void)
>>>>    {
>>>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>>>    	if (system_has_prio_mask_debugging()) {
>>>>    		u32 pmr = read_sysreg_s(SYS_ICC_PMR_EL1);
>>>> @@ -41,10 +42,18 @@ static inline void arch_local_irq_enable(void)
>>>>    		: "memory");
>>>>    	pmr_sync();
>>>> +#else
>>>> +	asm volatile(
>>>> +		"msr	daifclr, #3		// arch_local_irq_enable"
>>>> +		:
>>>> +		:
>>>> +		: "memory");
>>>> +#endif
>>> I'm happy to rework this to improve matters, but I am very much not happy with
>>> duplicating the logic for the !PSEUDO_NMI case. Adding more ifdeffery and
>>> copies of that is not acceptable.
>> I agree. Adding these ifdeffery is a bit ugly. Let's see if there are some
>> better ways.
>>> Instead, can you please try changing the alternative to also take the config,
>>> e.g. here have:
>>>
>>> |       asm volatile(ALTERNATIVE(
>>> |               "msr    daifclr, #3             // arch_local_irq_enable",
>>> |               __msr_s(SYS_ICC_PMR_EL1, "%0"),
>>> |               ARM64_HAS_IRQ_PRIO_MASKING,
>>> |               CONFIG_ARM64_PSEUDO_NMI)
>>> |               :
>>> |               : "r" ((unsigned long) GIC_PRIO_IRQON)
>>> |               : "memory");
>>>
>>> ... and see if that makes a significant difference?
>>>
>>> Likewise for the other casees.
>> OK, I'll try it. But I have some questions. Here's the comment of
>> ALERNATIVE:
>>
>> /*
>>  ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature));
>>  ?*
>>  ?* Usage: asm(ALTERNATIVE(oldinstr, newinstr, feature, CONFIG_FOO));
>>  ?* N.B. If CONFIG_FOO is specified, but not selected, the whole block
>>  ?*????? will be omitted, including oldinstr.
>>  ?*/
>>
>> If CONFIG_FOO is not selected, the whole block will be omitted including
>> oldinstr.
>>
>> But we still want the oldinstr in this situation. Do I misunderstand
>> something?
> Sorry; you are right, and my suggestion was broken.
>
> I'll need to have a think about this; we might be able to rework this to use a
> static key instead, but IIRC last time I tried there were issues with that
> approach. I have some (old) work-in-progress patches at:
>
>    https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/daif-rework
>
> I suspect I won't have time to renew that in the near future, but an approach
> like that might be worthwhile.

OK, I see. What do you think if I send a v2 patch that only adds 
ifdeffery to

arch/arm64/kernel/entry.S and leave the rework to ALERNATIVE behind?

I think these modifications can save some NOPs definitely.

>
> Thanks,
> Mark.
> .


From mhocko at suse.com  Tue Jan 11 01:00:32 2022
From: mhocko at suse.com (Michal Hocko)
Date: Tue, 11 Jan 2022 10:00:32 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydza/zXKY9ATRoh6@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz> <YdjOazilBEkdUT7x@google.com>
 <YdxSUuDc3OC4pe+f@dhcp22.suse.cz> <Ydza/zXKY9ATRoh6@google.com>
Message-ID: <Yd1HMDqiySwVxbF7@dhcp22.suse.cz>

On Mon 10-01-22 18:18:55, Yu Zhao wrote:
> On Mon, Jan 10, 2022 at 04:35:46PM +0100, Michal Hocko wrote:
> > On Fri 07-01-22 16:36:11, Yu Zhao wrote:
> > > On Fri, Jan 07, 2022 at 02:11:29PM +0100, Michal Hocko wrote:
> > > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > [...]
> > > > > +static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
> > > > > +{
> > > > > +	struct mem_cgroup *memcg;
> > > > > +	bool success = false;
> > > > > +	unsigned long min_ttl = READ_ONCE(lru_gen_min_ttl);
> > > > > +
> > > > > +	VM_BUG_ON(!current_is_kswapd());
> > > > > +
> > > > > +	current->reclaim_state->mm_walk = &pgdat->mm_walk;
> > > > > +
> > > > > +	memcg = mem_cgroup_iter(NULL, NULL, NULL);
> > > > > +	do {
> > > > > +		struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
> > > > > +
> > > > > +		if (age_lruvec(lruvec, sc, min_ttl))
> > > > > +			success = true;
> > > > > +
> > > > > +		cond_resched();
> > > > > +	} while ((memcg = mem_cgroup_iter(NULL, memcg, NULL)));
> > > > > +
> > > > > +	if (!success && mutex_trylock(&oom_lock)) {
> > > > > +		struct oom_control oc = {
> > > > > +			.gfp_mask = sc->gfp_mask,
> > > > > +			.order = sc->order,
> > > > > +		};
> > > > > +
> > > > > +		if (!oom_reaping_in_progress())
> > > > > +			out_of_memory(&oc);
> > > > > +
> > > > > +		mutex_unlock(&oom_lock);
> > > > > +	}
> > > > 
> > > > Why do you need to trigger oom killer from this path? Why cannot you
> > > > rely on the page allocator to do that like we do now?
> > > 
> > > This is per desktop users' (repeated) requests. The can't tolerate
> > > thrashing as servers do because of UI lags; and they usually don't
> > > have fancy tools like oomd.
> > > 
> > > Related discussions I saw:
> > > https://github.com/zen-kernel/zen-kernel/issues/218
> > > https://lore.kernel.org/lkml/20101028191523.GA14972 at google.com/
> > > https://lore.kernel.org/lkml/20211213051521.21f02dd2 at mail.inbox.lv/
> > > https://lore.kernel.org/lkml/54C2C89C.8080002 at gmail.com/
> > > https://lore.kernel.org/lkml/d9802b6a-949b-b327-c4a6-3dbca485ec20 at gmx.com/
> > 
> > I do not really see any arguments why an userspace based trashing
> > detection cannot be used for those. Could you clarify?
> 
> It definitely can be done. But who is going to do it for every distro
> and all individual users? AFAIK, not a single distro provides such a
> solution for desktop/laptop/phone users.

If existing interfaces provides sufficient information to make those
calls then I would definitely prefer a userspace solution.

> And also there is the theoretical question how reliable a userspace
> solution can be. What if this usespace solution itself gets stuck in
> the direct reclaim path. I'm sure if nobody has done some search to
> prove or debunk it.

I have to confess I haven't checked oomd or other solutions but with a
sufficient care (all the code mlocked in + no allocations done while
collecting data) I believe this should be achieveable.

> In addition, what exactly PSI values should be used on different
> models of consumer electronics? Nobody knows. We have a team working
> on this and we haven't figured it out for all our Chromebook models.

I believe this is a matter of tuning for a specific deployment. We do
not have only psi but also refault counters that can be used.

> As Andrew said, "a blunt instrument like this would be useful".
> https://lore.kernel.org/lkml/20211202135824.33d2421bf5116801cfa2040d at linux-foundation.org/
> 
> I'd like to have less code in kernel too, but I've learned never to
> walk over users. If I remove this and they come after me asking why,
> I'd have a hard time convincing them.
> 
> > Also my question was pointing to why out_of_memory is called from the
> > reclaim rather than the allocator (memcg charging path). It is the
> > caller of the reclaim to control different reclaim strategies and tell
> > when all the hopes are lost and the oom killer should be invoked. This
> > allows for a different policies at the allocator level and this change
> > will break that AFAICS. E.g. what if the underlying allocation context
> > is __GFP_NORETRY?
> 
> This is called in kswapd only, and by default (min_ttl=0) it doesn't
> do anything. So __GFP_NORETRY doesn't apply.

My bad. I must have got lost when traversing the code but I can see you
are enforcing that by a VM_BUG_ON. So the limited scope reclaim is not a
problem indeed.

> The question would be
> more along the lines of long-term ABI support.
> 
> And I'll add the following comments, if you think we can keep this
> logic:
>    OOM kill if every generation from all memcgs is younger than min_ttl.
>    Another theoretical possibility is all memcgs are either below min or
>    ineligible at priority 0, but this isn't the main goal.
> 
> (Please read my reply at the bottom to decide whether we should keep
>  it or not. Thanks.)
> 
> > > >From patch 8:
> > >   Personal computers
> > >   ------------------
> > >   :Thrashing prevention: Write ``N`` to
> > >    ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
> > >    ``N`` milliseconds from getting evicted. The OOM killer is invoked if
> > >    this working set can't be kept in memory. Based on the average human
> > >    detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
> > >    lags due to thrashing. Larger values like ``N=3000`` make lags less
> > >    noticeable at the cost of more OOM kills.
> > 
> > This is a very good example of something that should be a self contained
> > patch with its own justification.
> 
> Consider it done.
> 
> > TBH it is really not all that clear to
> > me that we want to provide any user visible knob to control OOM behavior
> > based on a time based QoS.
> 
> Agreed, and it didn't exist until v4, i.e., after I was demanded to
> provide it for several times.
> 
> For example:
> https://github.com/zen-kernel/zen-kernel/issues/223
> 
> And another example:
>    Your Multigenerational LRU patchset is pretty complex and
>    effective, but does not eliminate thrashing condition fully on an
>    old PCs with slow HDD.
> 
>    I'm kindly asking you to cooperate with hakavlad if it's possible
>    and maybe re-implement parts of le9 patch in your patchset wherever
>    acceptable, as they are quite similar in the core concept.
> 
> This is excerpt of an email from iam at valdikss.org.ru, and he has
> posted demo videos in this discussion:
> https://lore.kernel.org/lkml/2dc51fc8-f14e-17ed-a8c6-0ec70423bf54 at valdikss.org.ru/

That is all an interesting feedback but we should be really craful about
ABI constrains and future maintainability of the knob. I still stand
behind my statement that kernel should implement such features only if
it is clear that we cannot really implement a similar logic in the
userspace.

-- 
Michal Hocko
SUSE Labs


From holger at applied-asynchrony.com  Tue Jan 11 00:53:36 2022
From: holger at applied-asynchrony.com (=?UTF-8?Q?Holger_Hoffst=c3=a4tte?=)
Date: Tue, 11 Jan 2022 09:53:36 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <ca3a7d27-150d-ed06-c8f8-0c74c4f00667@applied-asynchrony.com>

On 2022-01-11 09:41, Yu Zhao wrote:
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
>> On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
>>> TLDR
>>> ====
>>> The current page reclaim is too expensive in terms of CPU usage and it
>>> often makes poor choices about what to evict. This patchset offers an
>>> alternative solution that is performant, versatile and
>>> straightforward.
>>
>> <snipped>
>>
>>> Summery
>>> =======
>>> The facts are:
>>> 1. The independent lab results and the real-world applications
>>>     indicate substantial improvements; there are no known regressions.
>>> 2. Thrashing prevention, working set estimation and proactive reclaim
>>>     work out of the box; there are no equivalent solutions.
>>> 3. There is a lot of new code; nobody has demonstrated smaller changes
>>>     with similar effects.
>>>
>>> Our options, accordingly, are:
>>> 1. Given the amount of evidence, the reported improvements will likely
>>>     materialize for a wide range of workloads.
>>> 2. Gauging the interest from the past discussions [14][15][16], the
>>>     new features will likely be put to use for both personal computers
>>>     and data centers.
>>> 3. Based on Google's track record, the new code will likely be well
>>>     maintained in the long term. It'd be more difficult if not
>>>     impossible to achieve similar effects on top of the existing
>>>     design.
>>
>> Hi Andrew, Linus,
>>
>> Can you please take a look at this patchset and let me know if it's
>> 5.17 material?
>>
>> My goal is to get it merged asap so that users can reap the benefits
>> and I can push the sequels. Please examine the data provided -- I
>> think the unprecedented coverage and the magnitude of the improvements
>> warrant a green light.
> 
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
> 
> Having this patchset in the mainline will make your job easier :)
> 
>     Alexandre - the XanMod Kernel maintainer
>                 https://xanmod.org
>     
>     Brian     - the Chrome OS kernel memory maintainer
>                 https://www.chromium.org
>     
>     Jan       - the Arch Linux Zen kernel maintainer
>                 https://archlinux.org
>     
>     Steven    - the Liquorix kernel maintainer
>                 https://liquorix.net
>     
>     Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                 https://chromium.googlesource.com/chromiumos/third_party/kernel
> 
> Also my gratitude to those who have helped test MGLRU:
> 
>     Daniel - researcher at Michigan Tech
>              benchmarked memcached
>     
>     Holger - who has been testing/patching/contributing to various
>              subsystems since ~2008
>     
>     Shuang - researcher at University of Rochester
>              benchmarked fio and provided a report
>     
>     Sofia  - EDI https://www.edi.works
>              benchmarked the top eight memory hogs and provided reports
> 
> Can you please provide your Tested-by tags? This will ensure the credit
> for your contributions.
> 
> Thanks!
> 

Have been pounding on this "in production" on several different machines
(server, desktop, laptop) and 5.15.x without any issues, so:

Tested-by: Holger Hoffst?tte <holger at applied-asynchrony.com>

Looking forward to seeing this in mainline!

cheers,
Holger


From angelogioacchino.delregno at collabora.com  Tue Jan 11 01:10:54 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 10:10:54 +0100
Subject: [PATCH v2 4/6] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <20220111063904.7583-5-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-5-yong.wu@mediatek.com>
Message-ID: <00efa277-6475-4f20-f045-443a0706e9e2@collabora.com>

Il 11/01/22 07:39, Yong Wu ha scritto:
> The successful return value for clk_bulk_prepare_enable is 0, rather than
> "< 0". Fix this.
> 

Hello! Thanks for this commit!
However, there are a few comments...

This description is a bit confusing, please reword it, something like...

"Function clk_bulk_prepare_enable() returns 0 for success or a negative
number for error. Fix this code style issue."

In any case, you're not fixing any bad logic issue here, as the function
will never return anything > 0.

What you're fixing is a common pattern usage issue, so the Fixes tag can be
removed since it's not really useful to schedule this commit for backport
over older stable versions.


After the requested changes:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> Fixes: 0e14917c57f9 ("memory: mtk-smi: Use clk_bulk clock ops")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/memory/mtk-smi.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> index b883dcc0bbfa..e7b1a22b12ea 100644
> --- a/drivers/memory/mtk-smi.c
> +++ b/drivers/memory/mtk-smi.c
> @@ -480,7 +480,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
>   	int ret;
>   
>   	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
> -	if (ret < 0)
> +	if (ret)
>   		return ret;
>   
>   	/* Configure the basic setting for this larb */
> 



From angelogioacchino.delregno at collabora.com  Tue Jan 11 01:14:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 10:14:23 +0100
Subject: [PATCH v2 5/6] memory: mtk-smi: Add sleep ctrl function
In-Reply-To: <20220111063904.7583-6-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-6-yong.wu@mediatek.com>
Message-ID: <e3815197-8963-99a6-e83d-b801de1725f3@collabora.com>

Il 11/01/22 07:39, Yong Wu ha scritto:
> Sleep control means that when the larb goes to sleep, we should wait a bit
> until all the current commands are finished. Thus, when the larb runtime
> suspends, we need to enable this function to wait until all the existed
> commands are finished. When the larb resumes, just disable this function.
> This function only improves the safety of bus. Add a new flag for this
> function. Prepare for mt8186.
> 
> Signed-off-by: Anan Sun <anan.sun at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From ada at thorsis.com  Tue Jan 11 01:14:12 2022
From: ada at thorsis.com (Alexander Dahl)
Date: Tue, 11 Jan 2022 10:14:12 +0100
Subject: [PATCH] ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
In-Reply-To: <20220111080933.800414-1-tudor.ambarus@microchip.com>
References: <20220111080933.800414-1-tudor.ambarus@microchip.com>
Message-ID: <Yd1KZC+dg5GHruju@ada.ifak-system.com>

Hello,

Am Tue, Jan 11, 2022 at 10:09:33AM +0200 schrieb Tudor Ambarus:
> PMERRLOC resource size has been shrunk to 0x100, 

What do mean with "has been shrunk"? It was introduced like this for
sama5d2, sama5d3, and sama5d4 in the first place with d9c41bf30cf8c.

FWIW, I had a look in the sama5d2, sama5d3 and sama5d4 series
datasheets, and it seems sama5d2 differs from the two others here.

> which resulted in
> HSMC_ERRLOCx register being truncated to offset x = 21, causing
> error correction to fail if more than 22 bit errors where 24 or
> 32 bit error correction was supported.
> 
> Fixes: d9c41bf30cf8 ("ARM: dts: at91: Declare EBI/NAND controllers")

This landed in 4.13. Is this fix needed for stable then? That would be
4.14, 4.19, 5.4, 5.10, and 5.15, right? Or is this covered by the
fixes tag already?

Greets
Alex

> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---
>  arch/arm/boot/dts/sama5d2.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
> index 801969c113d6..de88eb484718 100644
> --- a/arch/arm/boot/dts/sama5d2.dtsi
> +++ b/arch/arm/boot/dts/sama5d2.dtsi
> @@ -413,7 +413,7 @@ hsmc: hsmc at f8014000 {
>  				pmecc: ecc-engine at f8014070 {
>  					compatible = "atmel,sama5d2-pmecc";
>  					reg = <0xf8014070 0x490>,
> -					      <0xf8014500 0x100>;
> +					      <0xf8014500 0x200>;
>  				};
>  			};
>  
> -- 
> 2.25.1
> 


From hverkuil-cisco at xs4all.nl  Tue Jan 11 01:16:37 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 11 Jan 2022 10:16:37 +0100
Subject: [PATCH v3] media: meson: vdec: Fix a NULL pointer dereference in
 amvdec_add_ts()
In-Reply-To: <20211215033535.40422-1-zhou1615@umn.edu>
References: <20211214144613.35fec82a@coco.lan>
 <20211215033535.40422-1-zhou1615@umn.edu>
Message-ID: <368bc1b7-ff86-beaa-6749-afbe5960eaeb@xs4all.nl>

Zhou Qingyang, this is exactly the patch Neil wrote, except you just stuck your
name on it. Not nice.

Neil, can you post your patch with your own Signed-off-by, then I'll take that one.

Regards,

	Hans

On 15/12/2021 04:35, Zhou Qingyang wrote:
> In amvdec_add_ts(), there is a dereference of kzalloc(), which could lead
> to a NULL pointer dereference on failure of kzalloc().
> 
> Fix this bug by adding a NULL check of new_ts.
> 
> This bug was found by a static analyzer[1].
> 
> Builds with CONFIG_VIDEO_MESON_VDEC=m show no new warnings,
> and our static analyzer no longer warns about this code.
> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> ---
> 
> [1] The analysis employs differential checking to identify inconsistent
> security operations (e.g., checks or kfrees) between two code paths and
> confirms that the inconsistent operations are not recovered in the 
> current function or the callers, so they constitute bugs.
> 
> Note that, as a bug found by static analysis, it can be a false
> positive or hard to trigger. Multiple researchers have cross-reviewed
> the bug.
> 
> Changes in v3:
>   -  Change the description of patch
>   -  Turn the return type from 'void' to 'int'
>   -  Check the return value in the caller 'esparser_queue()'
> 
> Changes in v2:
>   -  Delete dev_err() message
> 
>  drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>  3 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..095100a50da8 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	if (!ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
> +
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index b9125c295d1d..06fd66539797 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
> +
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index 88137d15aa3a..4bf3e61d081b 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags: the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 flags);
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  
>  /**



From hverkuil at xs4all.nl  Tue Jan 11 01:21:59 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 11 Jan 2022 10:21:59 +0100
Subject: [PATCH v2] media: meson: vdec: potential dereference of null
 pointer
In-Reply-To: <20211210015620.2143555-1-jiasheng@iscas.ac.cn>
References: <20211210015620.2143555-1-jiasheng@iscas.ac.cn>
Message-ID: <03dbdbe8-ea08-ef62-c09d-67b3baab6401@xs4all.nl>

On 10/12/2021 02:56, Jiasheng Jiang wrote:
> The return value of kzalloc() needs to be checked.
> To avoid use of null pointer in case of the failure of alloc.

Same issue as with Zhou's patch: this is almost identical to Neil's patch,
but without any mention of his name.

I very much prefer it if Neil just posts his patch so I can pick that up.

Regards,

	Hans

> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---
> Changelog:
> 
> v1 -> v2
> 
> *Change 1. Change the return type of amvdec_add_ts from void to int.
> *Change 2. Return -ENOMEN if alloc fail and return 0 if not.
> *Change 3. Modify the caller to deal with the error.
> ---
>  drivers/staging/media/meson/vdec/esparser.c     | 6 +++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 5 ++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 2 +-
>  3 files changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..7e78288cc551 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,9 +328,13 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
> +	if (ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
>  
>  	vbuf->flags = 0;
>  	vbuf->field = V4L2_FIELD_NONE;
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index 7f07a9175815..972a1d1a12a5 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,15 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +244,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index cfaed52ab526..1bcb697290de 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -55,7 +55,7 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  



From LW at KARO-electronics.de  Tue Jan 11 01:26:09 2022
From: LW at KARO-electronics.de (Lothar =?UTF-8?B?V2HDn21hbm4=?=)
Date: Tue, 11 Jan 2022 10:26:09 +0100
Subject: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt overlays
 for serial modes
In-Reply-To: <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
Message-ID: <20220111102609.1f52b923@ipc1.ka-ro>

Hi,

On Mon, 10 Jan 2022 16:00:21 -0800 Tim Harvey wrote:
> On Tue, Dec 14, 2021 at 1:36 PM Tim Harvey <tharvey at gateworks.com> wrote:
> >
[...]
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> > new file mode 100644
> > index 000000000000..97f19c15c3d0
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> > @@ -0,0 +1,61 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Copyright 2021 Gateworks Corporation
> > + *
> > + * GW73xx RS485 HD:
> > + *  - GPIO1_0 rs485_term selects on-chip termination
> > + *  - GPIO4_0 rs485_en needs to be driven high (active)
> > + *  - GPIO4_2 rs485_hd needs to be driven high (active)
> > + *  - UART4_TX is DE for RS485 transmitter
> > + *  - RS485_EN needs to be pulled high
> > + *  - RS485_HALF needs to be pulled high
> > + */
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +
> > +#include "imx8mm-pinfunc.h"
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +&{/} {
> > +       compatible = "gw,imx8mm-gw73xx-0x";
> > +};
> > +
> > +&gpio4 {
> > +       rs485_en {
> > +               gpio-hog;
> > +               gpios = <0 GPIO_ACTIVE_HIGH>;
> > +               output-high;
> > +               line-name = "rs485_en";
> > +       };
> > +
> > +       rs485_hd {
> > +               gpio-hog;
> > +               gpios = <2 GPIO_ACTIVE_HIGH>;
> > +               output-high;
> > +               line-name = "rs485_hd";
> > +       };
> > +};
> > +
> > +&uart2 {
> > +       pinctrl-names = "default";
> > +       pinctrl-0 = <&pinctrl_uart2>;
> > +       rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
> > +       linux,rs485-enabled-at-boot-time;
> > +       status = "okay";
> > +};
> > +
> > +&uart4 {
> > +       status = "disabled";
> > +};
> > +
> > +&iomuxc {
> > +       pinctrl_uart2: uast2grp {
>
s/uast/uart/


Lothar Wa?mann

-- 
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________


From javier at dowhile0.org  Tue Jan 11 01:26:42 2022
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Tue, 11 Jan 2022 10:26:42 +0100
Subject: [PATCH RESEND v4 v5 4/4] drm/vc4: Notify the firmware when DRM is
 in charge
In-Reply-To: <20211215095117.176435-5-maxime@cerno.tech>
References: <20211215095117.176435-1-maxime@cerno.tech>
 <20211215095117.176435-5-maxime@cerno.tech>
Message-ID: <CABxcv=mseT4o71HYKETiezZ2FDFvvf=Aw+jpuOE98dVWdvwLzw@mail.gmail.com>

Hello Maxime,

On Wed, Dec 15, 2021 at 10:51 AM Maxime Ripard <maxime at cerno.tech> wrote:
>
> Once the call to drm_fb_helper_remove_conflicting_framebuffers() has
> been made, simplefb has been unregistered and the KMS driver is entirely
> in charge of the display.
>
> Thus, we can notify the firmware it can free whatever resource it was
> using to maintain simplefb functional.
>
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---

Patch looks good to me.

Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>

Best regards,
Javier


From jagan at amarulasolutions.com  Tue Jan 11 01:33:19 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Tue, 11 Jan 2022 15:03:19 +0530
Subject: [PATCH 1/2] arm64: dts: exynos: Link DSI panel at port@1 for TM2
 board
In-Reply-To: <9912c743-8acb-c59a-760a-a9b79ed48784@intel.com>
References: <20220110152714.58220-1-jagan@amarulasolutions.com>
 <9912c743-8acb-c59a-760a-a9b79ed48784@intel.com>
Message-ID: <CAMty3ZDF8jjoOx_qHsFAVKGDPqrOaiwSFkCikrHZQLRd-OV0pQ@mail.gmail.com>

Hi Andrzej,

On Tue, Jan 11, 2022 at 2:05 PM Andrzej Hajda <andrzej.hajda at intel.com> wrote:
>
> +CC: dri-devel
>
> On 10.01.2022 16:27, Jagan Teki wrote:
> > TM2 board DSI pipeline has input from MIC and output to
> > s6e3ha2 panel.
> >
> > The existing pipeline has child nodes of ports, panel and
> > MIC is remote-endpoint reference of port at 0 of ports.
> >
> > Adding panel as another child node to DSI is unconventional
> > as pipeline has ports child. However it can be true if MIC
> > is added inside port node like this.
> >
> > dsi {
> >       compatible = "samsung,exynos5433-mipi-dsi";
> >       #address-cells = <1>;
> >       #size-cells = <0>;
> >
> >       port {
> >               dsi_to_mic: endpoint {
> >                       remote-endpoint = <&mic_to_dsi>;
> >               };
> >       };
> >
> >       panel at 0 {
> >               compatible = "samsung,s6e3hf2";
> >                  reg = <0>;
> >                  vdd3-supply = <&ldo27_reg>;
> >                  vci-supply = <&ldo28_reg>;
> >                  reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
> >                  enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> >       };
> > };
> >
> > The above pipeline is proper but it requires the DSI input MIC
> > pipeline to update.
> >
> > This patch is trying to add panel at port at 1 so-that the entire
> > pipeline before to panel output is untouched.
> >
> > Reported-by: Marek Szyprowski <m.szyprowski at samsung.com>
> > Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> > ---
> >   arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 16 ++++++++++++++++
> >   1 file changed, 16 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> > index aca01709fd29..e13210c8d7e0 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> > +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
> > @@ -53,6 +53,16 @@ &cmu_disp {
> >   };
> >
> >   &dsi {
> > +     ports {
> > +             port at 1 {
> > +                     reg = <1>;
> > +
> > +                     dsi_out_panel: endpoint {
> > +                             remote-endpoint = <&dsi_in_panel>;
> > +                     };
> > +             };
> > +     };
> > +
> >       panel at 0 {
> >               compatible = "samsung,s6e3ha2";
> >               reg = <0>;
> > @@ -60,6 +70,12 @@ panel at 0 {
> >               vci-supply = <&ldo28_reg>;
> >               reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
> >               enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> > +
> > +             port {
> > +                     dsi_in_panel: endpoint {
> > +                             remote-endpoint = <&dsi_out_panel>;
> > +                     };
> > +             };
>
>
> As I already wrote in Exynos thread, DSI host has already parent-child
> relation with the panel - DSI host knows well who is connected to it.
> Adding another links between them is redundant and has no value added.
>
> I have already answered in Exynos thread[1] how could you deal with the
> issue, you have.
>
> [1]:
> https://lore.kernel.org/dri-devel/e541c52b-9751-933b-5eac-783dd0ed9056 at intel.com/

I have commented on this thread for better understanding. Please have
a look and respond.

Thanks,
Jagan.


From Tudor.Ambarus at microchip.com  Tue Jan 11 01:36:10 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Tue, 11 Jan 2022 09:36:10 +0000
Subject: [PATCH] ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
In-Reply-To: <Yd1KZC+dg5GHruju@ada.ifak-system.com>
References: <20220111080933.800414-1-tudor.ambarus@microchip.com>
 <Yd1KZC+dg5GHruju@ada.ifak-system.com>
Message-ID: <1b302157-c30f-4aa5-c798-d1bb7990258e@microchip.com>

On 1/11/22 11:14 AM, Alexander Dahl wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> Hello,

Hi!

> 
> Am Tue, Jan 11, 2022 at 10:09:33AM +0200 schrieb Tudor Ambarus:
>> PMERRLOC resource size has been shrunk to 0x100,
> 
> What do mean with "has been shrunk"? It was introduced like this for
> sama5d2, sama5d3, and sama5d4 in the first place with d9c41bf30cf8c.

I meant has been shrunk until now.
I will reword this for better clarity, maybe s/"has been shrunk"/"was set".

> 
> FWIW, I had a look in the sama5d2, sama5d3 and sama5d4 series
> datasheets, and it seems sama5d2 differs from the two others here.

Indeed, this patch is for sama5d2 only. sama5d3 and sama5d4 PMERRLOC
registers fit in the 0x100 size, there's no need to update them.

> 
>> which resulted in
>> HSMC_ERRLOCx register being truncated to offset x = 21, causing
>> error correction to fail if more than 22 bit errors where 24 or
>> 32 bit error correction was supported.
>>
>> Fixes: d9c41bf30cf8 ("ARM: dts: at91: Declare EBI/NAND controllers")
> 
> This landed in 4.13. Is this fix needed for stable then? That would be
> 4.14, 4.19, 5.4, 5.10, and 5.15, right? Or is this covered by the
> fixes tag already?

Maybe indirectly. But best would be to add the following line according to
https://www.kernel.org/doc/html/latest/process/stable-kernel-rules.html

Cc: <stable at vger.kernel.org> # 4.14.x
Will add it. Cheers,
ta

From angelogioacchino.delregno at collabora.com  Tue Jan 11 01:37:57 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 10:37:57 +0100
Subject: [PATCH v11 4/4] soc: mediatek: mutex: add functions that operate
 registers by CMDQ
In-Reply-To: <20220104091712.25670-5-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
 <20220104091712.25670-5-moudy.ho@mediatek.com>
Message-ID: <a78a4654-2442-e4b1-8e81-2a6d399407ec@collabora.com>

Il 04/01/22 10:17, Moudy Ho ha scritto:
> Considering that some functions have timing requirements
> in specific situation, this patch adds several interface that
> operate registers by CMDQ.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From tzimmermann at suse.de  Tue Jan 11 01:38:36 2022
From: tzimmermann at suse.de (Thomas Zimmermann)
Date: Tue, 11 Jan 2022 10:38:36 +0100
Subject: [PATCH RESEND v4 v5 4/4] drm/vc4: Notify the firmware when DRM is
 in charge
In-Reply-To: <20211215095117.176435-5-maxime@cerno.tech>
References: <20211215095117.176435-1-maxime@cerno.tech>
 <20211215095117.176435-5-maxime@cerno.tech>
Message-ID: <1a42431d-59bc-53e0-199b-815c96f97a29@suse.de>

Hi

Am 15.12.21 um 10:51 schrieb Maxime Ripard:
> Once the call to drm_fb_helper_remove_conflicting_framebuffers() has
> been made, simplefb has been unregistered and the KMS driver is entirely
> in charge of the display.
> 
> Thus, we can notify the firmware it can free whatever resource it was
> using to maintain simplefb functional.
> 
> Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> ---
>   drivers/gpu/drm/vc4/vc4_drv.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 86c61ee120b7..a03053c8e22c 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -37,6 +37,8 @@
>   #include <drm/drm_fb_helper.h>
>   #include <drm/drm_vblank.h>
>   
> +#include <soc/bcm2835/raspberrypi-firmware.h>
> +
>   #include "uapi/drm/vc4_drm.h"
>   
>   #include "vc4_drv.h"
> @@ -215,6 +217,7 @@ static void vc4_match_add_drivers(struct device *dev,
>   static int vc4_drm_bind(struct device *dev)
>   {
>   	struct platform_device *pdev = to_platform_device(dev);
> +	struct rpi_firmware *firmware = NULL;
>   	struct drm_device *drm;
>   	struct vc4_dev *vc4;
>   	struct device_node *node;
> @@ -251,10 +254,29 @@ static int vc4_drm_bind(struct device *dev)
>   	if (ret)
>   		return ret;
>   
> +	node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware");
> +	if (node) {
> +		firmware = rpi_firmware_get(node);
> +		of_node_put(node);
> +
> +		if (!firmware)
> +			return -EPROBE_DEFER;
> +	}
> +

The code is

Acked-by: Thomas Zimmermann <tzimmermann at suse.de>

Just for my understanding:

You retrieve the firmware before killing simpledrm simply to keep the 
display on if it fails, right?

What's the possible error that would justify a retry (via EPROBE_DEFER)?

Best regards
Thomas

>   	ret = drm_aperture_remove_framebuffers(false, &vc4_drm_driver);
>   	if (ret)
>   		return ret;
>   
> +	if (firmware) {
> +		ret = rpi_firmware_property(firmware,
> +					    RPI_FIRMWARE_NOTIFY_DISPLAY_DONE,
> +					    NULL, 0);
> +		if (ret)
> +			drm_warn(drm, "Couldn't stop firmware display driver: %d\n", ret);
> +
> +		rpi_firmware_put(firmware);
> +	}
> +
>   	ret = component_bind_all(dev, drm);
>   	if (ret)
>   		return ret;

-- 
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 N?rnberg, Germany
(HRB 36809, AG N?rnberg)
Gesch?ftsf?hrer: Ivo Totev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/b59d9a1d/attachment.sig>

From angelogioacchino.delregno at collabora.com  Tue Jan 11 01:38:39 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 10:38:39 +0100
Subject: [PATCH v11 1/4] soc: mediatek: mmsys: add CMDQ write register
 function
In-Reply-To: <20220104091712.25670-2-moudy.ho@mediatek.com>
References: <20220104091712.25670-1-moudy.ho@mediatek.com>
 <20220104091712.25670-2-moudy.ho@mediatek.com>
Message-ID: <39e4ab28-be15-f06c-e444-5f84cf08aa52@collabora.com>

Il 04/01/22 10:17, Moudy Ho ha scritto:
> Adding the interface of writing MMSYS register via CMDQ,
> users do not need to parse related dts information.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>






From clabbe.montjoie at gmail.com  Tue Jan 11 01:47:12 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 11 Jan 2022 10:47:12 +0100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
Message-ID: <Yd1SIHUNdLIvKhzz@Red>

Hello

I work on adding crypto/engine support to my crypto driver sun4i-ss.
Selftests are passed but when doing iperf over ipsec I hit a spinlock recursion BUG.

This bug happen also against my sun8i-ce driver.
But this bug happen only on ARM (SoCs H3) and not on arm64 (SoCs H6, a64 tested) for it.

This is the full trace:
iperf 3.10.1
Linux buildroot 5.15.13-00003-g14f78eca130d #199 SMP Fri Jan 7 08:35:20 CET 2022 armv7l
Control connection MSS 1386
Time: Fri, 07 Jan 2022 08:52:27 GMT
Connecting to host ipsec.lava.local, port 5201
      Cookie: ylt5ilt5n4jnw72qu2lik5njq63rfalkshz6
      TCP MSS: 1386 (default)
[  5] local 192.168.1.204 port 33828 connected to 192.168.1.40 port 5201
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks, omitting 0 seconds, 10 second test, tos 0
[   44.412526] BUG: spinlock recursion on CPU#0, 1c15000.crypto-/111
[   44.418674]  lock: 0xc3f40268, .magic: dead4ead, .owner: 1c15000.crypto-/111, .owner_cpu: 0
[   44.427040] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
[   44.435647] Hardware name: Allwinner sun8i Family
[   44.440354] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
[   44.448110] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
[   44.455685] [<c0857fc4>] (dump_stack_lvl) from [<c016c5dc>] (do_raw_spin_lock+0x11c/0x120)
[   44.463953] [<c016c5dc>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
[   44.471961] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
[   44.479451] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
[   44.488156] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
[   44.497636] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
[   44.506944] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
[   44.515645] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
[   44.523391] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
[   44.532527] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
[   44.543394] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
[   44.553306] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
[   44.562182] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
[   44.570359] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
[   44.578016] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
[   44.585848] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
[   44.593162] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
[   44.600824] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
[   44.609007] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
[   44.616491] Exception stack(0xc1b79e38 to 0xc1b79e80)
[   44.621541] 9e20:                                                       c1c13c00 c0de5100
[   44.629712] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
[   44.637883] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
[   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
[   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
[   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
[   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
[   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
[   44.688600] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
[   44.697045] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
[   44.704793] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
[   44.712017] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
[   44.717066] 9fa0:                                     00000000 00000000 00000000 00000000
[   44.725237] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   44.733406] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.11   sec  1.11 MBytes  8.39 Mbits/sec    1   1.35 KBytes       
[  5]   1.11-2.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[   46.438402] sched: RT throttling activated
[   46.438402] sched: RT throttling activated
[  5]   2.00-3.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   3.00-4.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   4.00-5.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   5.00-6.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   6.00-7.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   7.00-8.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[  5]   8.00-9.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
[   65.398401] rcu: INFO: rcu_sched self-detected stall on CPU
[   65.403987] rcu: 	0-....: (2068 ticks this GP) idle=afd/1/0x40000004 softirq=3056/3057 fqs=1050 
[   65.412774] 	(t=2102 jiffies g=1437 q=434)
[   65.416873] NMI backtrace for cpu 0
[   65.420361] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
[   65.428965] Hardware name: Allwinner sun8i Family
[   65.433669] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
[   65.441424] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
[   65.448998] [<c0857fc4>] (dump_stack_lvl) from [<c042dc1c>] (nmi_cpu_backtrace+0xdc/0x110)
[   65.457267] [<c042dc1c>] (nmi_cpu_backtrace) from [<c042dd58>] (nmi_trigger_cpumask_backtrace+0x108/0x168)
[   65.466918] [<c042dd58>] (nmi_trigger_cpumask_backtrace) from [<c0856bf8>] (rcu_dump_cpu_stacks+0x128/0x15c)
[   65.476745] [<c0856bf8>] (rcu_dump_cpu_stacks) from [<c0188224>] (rcu_sched_clock_irq+0x798/0x950)
[   65.485707] [<c0188224>] (rcu_sched_clock_irq) from [<c0193608>] (update_process_times+0x9c/0xd0)
[   65.494581] [<c0193608>] (update_process_times) from [<c01a5b14>] (tick_sched_timer+0x7c/0xf0)
[   65.503197] [<c01a5b14>] (tick_sched_timer) from [<c0193e3c>] (__hrtimer_run_queues+0x15c/0x218)
[   65.511984] [<c0193e3c>] (__hrtimer_run_queues) from [<c0194efc>] (hrtimer_interrupt+0x124/0x2b0)
[   65.520857] [<c0194efc>] (hrtimer_interrupt) from [<c06a552c>] (arch_timer_handler_phys+0x28/0x30)
[   65.529820] [<c06a552c>] (arch_timer_handler_phys) from [<c017a654>] (handle_percpu_devid_irq+0x78/0x13c)
[   65.539388] [<c017a654>] (handle_percpu_devid_irq) from [<c01742fc>] (handle_domain_irq+0x5c/0x78)
[   65.548352] [<c01742fc>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
[   65.556533] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
[   65.564017] Exception stack(0xc1b79a30 to 0xc1b79a78)
[   65.569067] 9a20:                                     00000000 00000000 000003dc 000003da
[   65.577238] 9a40: c3f40268 ffffe000 00000000 c1b78000 00000002 00000000 c3f40268 c0de5100
[   65.585408] 9a60: c0b496d0 c1b79a80 c016c5b0 c016c538 80000113 ffffffff
[   65.592015] [<c0100afc>] (__irq_svc) from [<c016c538>] (do_raw_spin_lock+0x78/0x120)
[   65.599759] [<c016c538>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
[   65.607765] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
[   65.615255] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
[   65.623960] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
[   65.633440] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
[   65.642747] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
[   65.651447] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
[   65.659193] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
[   65.668329] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
[   65.679196] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
[   65.689108] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
[   65.697982] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
[   65.706159] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
[   65.713816] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
[   65.721647] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
[   65.728960] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
[   65.736620] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
[   65.744799] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
[   65.752281] Exception stack(0xc1b79e38 to 0xc1b79e80)
[   65.757329] 9e20:                                                       c1c13c00 c0de5100
[   65.765500] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
[   65.773671] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
[   65.781837] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
[   65.789929] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
[   65.798196] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
[   65.806552] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
[   65.815686] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
[   65.824384] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
[   65.832827] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
[   65.840574] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
[   65.847799] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
[   65.852847] 9fa0:                                     00000000 00000000 00000000 00000000
[   65.861017] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   65.869186] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
[  128.458402] rcu: INFO: rcu_sched self-detected stall on CPU
[  128.463984] rcu: 	0-....: (8328 ticks this GP) idle=afd/1/0x40000004 softirq=3056/3057 fqs=3872 
[  128.472769] 	(t=8408 jiffies g=1437 q=435)
[  128.476867] NMI backtrace for cpu 0
[  128.480354] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
[  128.488958] Hardware name: Allwinner sun8i Family
[  128.493660] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
[  128.501413] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
[  128.508985] [<c0857fc4>] (dump_stack_lvl) from [<c042dc1c>] (nmi_cpu_backtrace+0xdc/0x110)
[  128.517252] [<c042dc1c>] (nmi_cpu_backtrace) from [<c042dd58>] (nmi_trigger_cpumask_backtrace+0x108/0x168)
[  128.526904] [<c042dd58>] (nmi_trigger_cpumask_backtrace) from [<c0856bf8>] (rcu_dump_cpu_stacks+0x128/0x15c)
[  128.536730] [<c0856bf8>] (rcu_dump_cpu_stacks) from [<c0188224>] (rcu_sched_clock_irq+0x798/0x950)
[  128.545691] [<c0188224>] (rcu_sched_clock_irq) from [<c0193608>] (update_process_times+0x9c/0xd0)
[  128.554564] [<c0193608>] (update_process_times) from [<c01a5b14>] (tick_sched_timer+0x7c/0xf0)
[  128.563179] [<c01a5b14>] (tick_sched_timer) from [<c0193e3c>] (__hrtimer_run_queues+0x15c/0x218)
[  128.571966] [<c0193e3c>] (__hrtimer_run_queues) from [<c0194efc>] (hrtimer_interrupt+0x124/0x2b0)
[  128.580838] [<c0194efc>] (hrtimer_interrupt) from [<c06a552c>] (arch_timer_handler_phys+0x28/0x30)
[  128.589800] [<c06a552c>] (arch_timer_handler_phys) from [<c017a654>] (handle_percpu_devid_irq+0x78/0x13c)
[  128.599369] [<c017a654>] (handle_percpu_devid_irq) from [<c01742fc>] (handle_domain_irq+0x5c/0x78)
[  128.608332] [<c01742fc>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
[  128.616514] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
[  128.623997] Exception stack(0xc1b79a30 to 0xc1b79a78)
[  128.629047] 9a20:                                     00000000 00000000 000003dc 000003da
[  128.637218] 9a40: c3f40268 ffffe000 00000000 c1b78000 00000002 00000000 c3f40268 c0de5100
[  128.645388] 9a60: c0b496d0 c1b79a80 c016c5b0 c016c538 80000113 ffffffff
[  128.651995] [<c0100afc>] (__irq_svc) from [<c016c538>] (do_raw_spin_lock+0x78/0x120)
[  128.659738] [<c016c538>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
[  128.667744] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
[  128.675233] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
[  128.683936] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
[  128.693408] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
[  128.702716] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
[  128.711417] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
[  128.719163] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
[  128.728299] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
[  128.739165] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
[  128.749077] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
[  128.757951] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
[  128.766129] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
[  128.773786] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
[  128.781617] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
[  128.788930] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
[  128.796589] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
[  128.804768] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
[  128.812250] Exception stack(0xc1b79e38 to 0xc1b79e80)
[  128.817298] 9e20:                                                       c1c13c00 c0de5100
[  128.825469] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
[  128.833640] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
[  128.841806] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
[  128.849898] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
[  128.858163] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
[  128.866518] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
[  128.875651] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
[  128.884349] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
[  128.892790] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
[  128.900537] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
[  128.907760] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
[  128.912809] 9fa0:                                     00000000 00000000 00000000 00000000
[  128.920978] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[  128.929147] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000

None on my drivers are using spinlock so the only one which remains is crypto/engine one (queue_lock)

I have started to bisect this, but this lead to unrelated commits. (I tried twice with different starting point)

Known broken version are
5.13 5.14 5.15.13 next-20220105 5.10
I randomly hit also "NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!".
On 5.6 and 5.7 I got: NOHZ: local_softirq_pending 08

Working version are 5.4.170 and 5.5

The normal iperf performance is at least 30Mbit/s, when bug is present, iperf never end.
But When the bug is present with "NOHZ: local_softirq_pending 08", iperf give 1Mbit/s.

I started also to test other crypto driver which use the crypto/crypto_engine
On my sun8i-ss, no kernel trace are given, but iperf performance decrease is present.
I also tested omap-aes and it seems un-impacted.

Any help to debug that is welcome.
Thanks in advance

Regards



From drjones at redhat.com  Tue Jan 11 01:47:22 2022
From: drjones at redhat.com (Andrew Jones)
Date: Tue, 11 Jan 2022 10:47:22 +0100
Subject: [PATCH 2/2] KVM: arm64: selftests: Introduce vcpu_width_config
In-Reply-To: <20220110054042.1079932-2-reijiw@google.com>
References: <20220110054042.1079932-1-reijiw@google.com>
 <20220110054042.1079932-2-reijiw@google.com>
Message-ID: <20220111094722.cvj2zjtsh64jjg4i@gator>

On Sun, Jan 09, 2022 at 09:40:42PM -0800, Reiji Watanabe wrote:
> Introduce a test for aarch64 that ensures non-mixed-width vCPUs
> (all 64bit vCPUs or all 32bit vcPUs) can be configured, and
> mixed-width vCPUs cannot be configured.
> 
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  tools/testing/selftests/kvm/.gitignore        |   1 +
>  tools/testing/selftests/kvm/Makefile          |   1 +
>  .../selftests/kvm/aarch64/vcpu_width_config.c | 125 ++++++++++++++++++
>  3 files changed, 127 insertions(+)
>  create mode 100644 tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
>

 
Reviewed-by: Andrew Jones <drjones at redhat.com>



From maxime at cerno.tech  Tue Jan 11 01:50:26 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 11 Jan 2022 10:50:26 +0100
Subject: (subset) [PATCH] drm/sun4i: dw-hdmi: Fix missing put_device()
 call in sun8i_hdmi_phy_get
In-Reply-To: <20220107083633.20843-1-linmq006@gmail.com>
References: <20220107083633.20843-1-linmq006@gmail.com>
Message-ID: <164189462190.787936.7018811034548071748.b4-ty@cerno.tech>

On Fri, 7 Jan 2022 08:36:32 +0000, Miaoqian Lin wrote:
> The reference taken by 'of_find_device_by_node()' must be released when
> not needed anymore.
> Add the corresponding 'put_device()' in the error handling path.
> 
> 

Applied to drm/drm-misc (drm-misc-fixes).

Thanks!
Maxime


From David.Laight at ACULAB.COM  Tue Jan 11 01:52:17 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Tue, 11 Jan 2022 09:52:17 +0000
Subject: [PATCH 5/5] compat: consolidate the compat_flock{,64} definition
In-Reply-To: <20220111083515.502308-6-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-6-hch@lst.de>
Message-ID: <f69d570127db4f78a6b30e1775a020c4@AcuMS.aculab.com>

From: Christoph Hellwig
> Sent: 11 January 2022 08:35
> 
> Provide a single common definition for the compat_flock and
> compat_flock64 structures using the same tricks as for the native
> variants.  Another extra define is added for the packing required on
> x86.
> 
...
>  /*
> - * IA32 uses 4 byte alignment for 64 bit quantities,
> - * so we need to pack this structure.
> + * IA32 uses 4 byte alignment for 64 bit quantities, so we need to pack the
> + * compat flock64 structure.
>   */
...
> +#define __ARCH_NEED_COMPAT_FLOCK64_PACKED

Maybe:
#define __ARCH_COMPAT_FLOCK64_ATTR (packed),(aligned(4)

...
Delete this bit:
> +#ifdef __ARCH_NEED_COMPAT_FLOCK64_PACKED
> +#define __ARCH_COMPAT_FLOCK64_PACK	__attribute__((packed))
> +#else
> +#define __ARCH_COMPAT_FLOCK64_PACK
> +#endif
...
> +struct compat_flock64 {
> +	short		l_type;
> +	short		l_whence;
> +	compat_loff_t	l_start;
> +	compat_loff_t	l_len;
> +	compat_pid_t	l_pid;
> +#ifdef __ARCH_COMPAT_FLOCK64_PAD
> +	__ARCH_COMPAT_FLOCK64_PAD
> +#endif
> +} __ARCH_COMPAT_FLOCK64_PACK;

then:
#ifdef __ARCH_COMPAT_FLOCK64_ATTR
} __attribute__(__ARCH_COMPAT_FLOCK64_ATTR);
#else
};
#endif

Makes it a bit more like the xxx_PAD bits.
Although the trailing ; does cause a bit of grief.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From krzysztof.kozlowski at canonical.com  Tue Jan 11 02:13:34 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 11:13:34 +0100
Subject: [PATCH v2 0/4] spi: dt-bindings: samsung: convert to dtschema
Message-ID: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v1
================
1. Patch 2: describe devices matching compatible, correct issues pointed out by
   Rob, add reviewed-by tag.
2. New patches 3 and 4.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  ARM: dts: exynos: split dmas into array of phandles in Exynos5250
  spi: dt-bindings: samsung: convert to dtschema
  spi: dt-bindings: samsung: allow controller-data to be optional
  spi: s3c64xx: allow controller-data to be optional

 .../spi/samsung,spi-peripheral-props.yaml     |  36 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 195 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 -----------
 MAINTAINERS                                   |   2 +-
 arch/arm/boot/dts/exynos5250.dtsi             |   9 +-
 drivers/spi/spi-s3c64xx.c                     |  14 +-
 7 files changed, 242 insertions(+), 137 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 02:13:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 11:13:35 +0100
Subject: [PATCH v2 1/4] ARM: dts: exynos: split dmas into array of phandles in
 Exynos5250
In-Reply-To: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111101338.58630-2-krzysztof.kozlowski@canonical.com>

"dmas" property should be rather an array of phandles, as dtschema
points.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..102bb57bf704 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
 			status = "disabled";
 			reg = <0x12d20000 0x100>;
 			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 5
-				&pdma0 4>;
+			dmas = <&pdma0 5>, <&pdma0 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
 			status = "disabled";
 			reg = <0x12d30000 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma1 5
-				&pdma1 4>;
+			dmas = <&pdma1 5>, <&pdma1 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
 			status = "disabled";
 			reg = <0x12d40000 0x100>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 7
-				&pdma0 6>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 02:13:37 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 11:13:37 +0100
Subject: [PATCH v2 3/4] spi: dt-bindings: samsung: allow controller-data to be
 optional
In-Reply-To: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111101338.58630-4-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI bindings requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/spi/samsung,spi-peripheral-props.yaml  | 1 +
 Documentation/devicetree/bindings/spi/samsung,spi.yaml         | 3 ---
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
index aa5a1f48494b..cadc8a5f061f 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -28,6 +28,7 @@ properties:
            - 3: 270 degree phase shift sampling.
         $ref: /schemas/types.yaml#/definitions/uint32
         enum: [0, 1, 2, 3]
+        default: 0
 
     required:
       - samsung,spi-feedback-delay
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
index da4533feb946..322558818a43 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -75,9 +75,6 @@ patternProperties:
     allOf:
       - $ref: spi-peripheral-props.yaml
 
-    required:
-      - controller-data
-
     unevaluatedProperties: false
 
 required:
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 02:13:38 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 11:13:38 +0100
Subject: [PATCH v2 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111101338.58630-5-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI driver requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/spi/spi-s3c64xx.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..769d958a2f86 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
 		return ERR_PTR(-EINVAL);
 	}
 
-	data_np = of_get_child_by_name(slave_np, "controller-data");
-	if (!data_np) {
-		dev_err(&spi->dev, "child node 'controller-data' not found\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		of_node_put(data_np);
+	if (!cs)
 		return ERR_PTR(-ENOMEM);
+
+	data_np = of_get_child_by_name(slave_np, "controller-data");
+	if (!data_np) {
+		dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");
+		return cs;
 	}
 
 	of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 02:13:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 11:13:36 +0100
Subject: [PATCH v2 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111101338.58630-3-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 198 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 -----------
 MAINTAINERS                                   |   2 +-
 5 files changed, 235 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..aa5a1f48494b
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  See spi-peripheral-props.yaml for more info.
+
+properties:
+  controller-data:
+    type: object
+    additionalProperties: false
+
+    properties:
+      samsung,spi-feedback-delay:
+        description: |
+          The sampling phase shift to be applied on the miso line (to account
+          for any lag in the miso line). Valid values:
+           - 0: No phase shift.
+           - 1: 90 degree phase shift sampling.
+           - 2: 180 degree phase shift sampling.
+           - 3: 270 degree phase shift sampling.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2, 3]
+
+    required:
+      - samsung,spi-feedback-delay
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..da4533feb946
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi # for S5PV210 and S5PC110
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+patternProperties:
+  "^.*@[0-9a-f]+$":
+    type: object
+    allOf:
+      - $ref: spi-peripheral-props.yaml
+
+    required:
+      - controller-data
+
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..df885eeb144f 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -85,5 +85,6 @@ properties:
 # The controller specific properties go here.
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
+  - $ref: samsung,spi-peripheral-props.yaml#
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..1f951bc877f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17054,7 +17054,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From catalin.marinas at arm.com  Tue Jan 11 02:19:22 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 11 Jan 2022 10:19:22 +0000
Subject: [PATCH] mm: Generalize ARCH_HAS_FILTER_PGPROT
In-Reply-To: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>
References: <1641796896-16960-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Yd1Zqqy8rkLJM2u7@arm.com>

On Mon, Jan 10, 2022 at 12:11:36PM +0530, Anshuman Khandual wrote:
> ARCH_HAS_FILTER_PGPROT config has duplicate definitions on platforms that
> subscribe it. Instead make it a generic config option which can be selected
> on applicable platforms when required.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: "H. Peter Anvin" <hpa at zytor.com>
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: x86 at kernel.org
> Cc: linux-mm at kvack.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>

Assuming this goes in via the mm tree, for arm64:

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From javier at dowhile0.org  Tue Jan 11 02:21:25 2022
From: javier at dowhile0.org (Javier Martinez Canillas)
Date: Tue, 11 Jan 2022 11:21:25 +0100
Subject: [PATCH v2 3/5] drm/dp: Move DisplayPort helpers into separate
 helper module
In-Reply-To: <2165cfb8-c9c6-1aca-b492-587a8e07eb9f@suse.de>
References: <20211215104318.18866-1-tzimmermann@suse.de>
 <20211215104318.18866-4-tzimmermann@suse.de>
 <87pmpy3za7.fsf@intel.com> <2165cfb8-c9c6-1aca-b492-587a8e07eb9f@suse.de>
Message-ID: <CABxcv=nnyfULvog9z=nMduDK0iT1ZwkxYhdKs3xW88St6C00pw@mail.gmail.com>

On Wed, Dec 15, 2021 at 12:12 PM Thomas Zimmermann <tzimmermann at suse.de> wrote:
>
> Hi
>
> Am 15.12.21 um 12:04 schrieb Jani Nikula:
> > On Wed, 15 Dec 2021, Thomas Zimmermann <tzimmermann at suse.de> wrote:
> >>      * move DP helper code into dp/ (Jani)
> >
> > I suggested adding the subdirectory, but I'm going to bikeshed the name,
> > which I didn't suggest.
> >
> > $ find drivers/gpu/drm -mindepth 1 -maxdepth 1 -type d | wc -l
> > 68
> >
> > Assuming we move more of the drm modules to subdirectories, how are they
> > going to stand out from drivers?
> >
> > I suggested drm_dp, which I understand results in tautology, but hey,
> > all the filenames under drm/ also have drm_*.[ch]. And I find that very
> > useful for git greps and other code archeology. With just the dp name,
> > you'd have to know and list all the drm subdirectories when looking up
> > stuff that's part of drm but not drivers.
>
> I think we have enough filename prefixes already. drm/drm_dp/drm_dp_ is
> just ridiculous.
>

Maybe what can be done is to just add a drivers/gpu/drm/core
subdirectory that would contain all the DRM core code ?

Then the dp helpers could be moved to drivers/gpu/drm/core/dp/drm_dp.c
for example. This would also make easy to differentiate the drm
modules from the drivers with just:

$ find drivers/gpu/drm -mindepth 1 -maxdepth 1 -type d -not -name core

Best regards,
Javier


From hakavlad at inbox.lv  Tue Jan 11 02:24:51 2022
From: hakavlad at inbox.lv (Alexey Avramov)
Date: Tue, 11 Jan 2022 19:24:51 +0900
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <20220111192451.1a853019@mail.inbox.lv>

In some of my benchmarks MGLRU really gave unrivaled performance.
I assume the adoption of MGLRU into the kernel would save billions of
dollars and greatly reduce carbon dioxide emissions.

However, there are also cases where MGLRU loses.
There are cases where MGLRU does not achieve the performance that the
classic LRU gives (at least I got such results when testing MGLRU before[1],
but I did not report them here).

As a Linux user, I would like to see both variants of LRU in the kernel, so
that it is possible to switch to the suitable variant when needed: none of
the LRU variants allowed me to squeeze the maximum for all cases.

I hope to test MGLRU v6 later and show you some of its weaknesses and
anomalies with specific logs and benchmarks. 

[1] I didn't have enough time and energy to decipher the results at that time:
    https://github.com/hakavlad/cache-tests/tree/main/mg-LRU-v3_vs_classic-LRU
    (but you can try to guess what it all means)



From rppt at kernel.org  Tue Jan 11 02:31:58 2022
From: rppt at kernel.org (Mike Rapoport)
Date: Tue, 11 Jan 2022 12:31:58 +0200
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <20220110210809.3528-2-fllinden@amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com>
Message-ID: <Yd1cnquQFZoNE7FP@kernel.org>

On Mon, Jan 10, 2022 at 09:08:07PM +0000, Frank van der Linden wrote:
> Some architectures might limit the usable memory range based
> on a firmware property, like "linux,usable-memory-range"
> for ARM crash kernels. This limit needs to be enforced after
> firmware memory map processing has been done, which might be
> e.g. FDT or EFI, or both.
> 
> Define an interface for it that is firmware type agnostic.
> 
> Signed-off-by: Frank van der Linden <fllinden at amazon.com>
> ---
>  include/linux/memblock.h |  2 ++
>  mm/memblock.c            | 37 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 34de69b3b8ba..6128efa50d33 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
>  phys_addr_t memblock_start_of_DRAM(void);
>  phys_addr_t memblock_end_of_DRAM(void);
>  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> +void memblock_enforce_usable_range(void);
>  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
>  void memblock_mem_limit_remove_map(phys_addr_t limit);

We already have 3 very similar interfaces that deal with memory capping.
Now you suggest to add fourth that will "generically" solve a single use
case of DT, EFI and kdump interaction on arm64.

Looks like a workaround for a fundamental issue of incompatibility between
DT and EFI wrt memory registration.

>  bool memblock_is_memory(phys_addr_t addr);
> diff --git a/mm/memblock.c b/mm/memblock.c
> index 5096500b2647..cb961965f3ad 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -101,6 +101,7 @@ unsigned long max_low_pfn;
>  unsigned long min_low_pfn;
>  unsigned long max_pfn;
>  unsigned long long max_possible_pfn;
> +phys_addr_t usable_start, usable_size;
>
>  static struct memblock_region memblock_memory_init_regions[INIT_MEMBLOCK_REGIONS] __initdata_memblock;
>  static struct memblock_region memblock_reserved_init_regions[INIT_MEMBLOCK_RESERVED_REGIONS] __initdata_memblock;
> @@ -1715,6 +1716,42 @@ void __init memblock_cap_memory_range(phys_addr_t base, phys_addr_t size)
>  			base + size, PHYS_ADDR_MAX);
>  }
>  
> +/**
> + * memblock_set_usable_range - set usable memory range
> + * @base: physical address that is the start of the range
> + * @size: size of the range.
> + *
> + * Used when a firmware property limits the range of usable
> + * memory, like for the linux,usable-memory-range property
> + * used by ARM crash kernels.
> + */
> +void __init memblock_set_usable_range(phys_addr_t base, phys_addr_t size)
> +{
> +	usable_start = base;
> +	usable_size = size;
> +}
> +
> +/**
> + * memblock_enforce_usable_range - cap memory ranges to usable range
> + *
> + * Some architectures call this during boot after firmware memory ranges
> + * have been scanned, to make sure they fall within the usable range
> + * set by memblock_set_usable_range.
> + *
> + * This may be called more than once if there are multiple firmware sources
> + * for memory ranges.
> + *
> + * Avoid "no memory registered" warning - the warning itself is
> + * useful, but we know this can be called with no registered
> + * memory (e.g. when the synthetic DT for the crash kernel has
> + * been parsed on EFI arm64 systems).
> + */
> +void __init memblock_enforce_usable_range(void)
> +{
> +	if (memblock_memory->total_size)
> +		memblock_cap_memory_range(usable_start, usable_size);
> +}
> +
>  void __init memblock_mem_limit_remove_map(phys_addr_t limit)
>  {
>  	phys_addr_t max_addr;
> -- 
> 2.32.0
> 

-- 
Sincerely yours,
Mike.


From maxime at cerno.tech  Tue Jan 11 02:35:42 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 11 Jan 2022 11:35:42 +0100
Subject: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20 support
In-Reply-To: <tencent_13C536D91764B05D794CBCF3156C963E6C0A@qq.com>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <tencent_13C536D91764B05D794CBCF3156C963E6C0A@qq.com>
Message-ID: <20220111103542.f7ilg2ugqklpztr5@houat>

Hi,

On Wed, Jan 05, 2022 at 10:45:50AM +0800, conleylee at foxmail.com wrote:
> From: conley <conleylee at foxmail.com>

This should be your full name in the author and signed-off-by

> ARM dts: sun7i: Add Marsboard A20 board
> 
> This patch add support for Marsboard A20 board.
> 
> The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
> card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
> USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.
> 
> Change since v1.
>   - Spearate biddings and dts as two patches.
>   - use SPDX tag

And the changelog should be after the --- below

> Signed-off-by: conley <conleylee at foxmail.com>
> ---
>  arch/arm/boot/dts/Makefile                |   1 +
>  arch/arm/boot/dts/sun7i-a20-marsboard.dts | 183 ++++++++++++++++++++++
>  2 files changed, 184 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sun7i-a20-marsboard.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..4628a2617313 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
>  	sun7i-a20-icnova-swac.dtb \
>  	sun7i-a20-lamobo-r1.dtb \
>  	sun7i-a20-linutronix-testbox-v2.dtb \
> +	sun7i-a20-marsboard.dtb \
>  	sun7i-a20-m3.dtb \
>  	sun7i-a20-mk808c.dtb \
>  	sun7i-a20-olimex-som-evb.dtb \
> diff --git a/arch/arm/boot/dts/sun7i-a20-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> new file mode 100644
> index 000000000000..7ab6aa30fee6
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: LGPL-2.1+

The license for DT files is usually a dual-license with GPL and MIT,
which would be:

SPDX-License-Identifier: (GPL-2.0+ OR MIT)

You can't link to a DT, so GPL and LGPL should be equivalent here, and
MIT is useful for other projects (like the *BSD) that reuse the DT.

> +/*
> + * Copyright 2021 Conley Lee
> + * Conley Lee <conleylee at foxmail.com>
> + */
> +
> +/dts-v1/;
> +#include "sun7i-a20.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> +	model = "HAOYU Electronics Marsboard A20";
> +	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";

Is there multiple boards called marsboard?

If not, then the compatible should be haoyu,marsboard.

The file name should be sun7i-a20-haoyu-marsboard too.

> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +};
> +
> +&ahci {
> +	target-supply = <&reg_ahci_5v>;
> +	status = "okay";
> +};
> +
> +&codec {
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&de {
> +	status = "okay";
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&gmac_mii_pins {
> +	pins = "PA0", "PA1", "PA2",
> +	"PA3", "PA4", "PA5", "PA6",
> +	"PA7", "PA8", "PA9", "PA10",
> +	"PA11", "PA12", "PA13", "PA14",
> +	"PA15", "PA16", "PA17";
> +};

Why do you need that node?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/58ec1f62/attachment-0001.sig>

From luca at lucaceresoli.net  Tue Jan 11 02:35:48 2022
From: luca at lucaceresoli.net (Luca Ceresoli)
Date: Tue, 11 Jan 2022 11:35:48 +0100
Subject: [PATCH 1/2] PCI: dra7xx: Fix link removal on probe error
In-Reply-To: <59a23c89-0810-eb28-acd9-7051ac34d438@lucaceresoli.net>
References: <20211214221450.589884-1-luca@lucaceresoli.net>
 <CAL_Jsq+GQTcx1EGKHug2ZcDZufrKM-4k6PB0vQeTCTG42MHzvA@mail.gmail.com>
 <59a23c89-0810-eb28-acd9-7051ac34d438@lucaceresoli.net>
Message-ID: <4579940c-27dc-733e-4022-ebea4671c839@lucaceresoli.net>

Hi Rob,

On 16/12/21 10:08, Luca Ceresoli wrote:
> Hi Rob,
> 
> thanks for the quick feedback!
> 
> On 14/12/21 23:42, Rob Herring wrote:
>> On Tue, Dec 14, 2021 at 4:15 PM Luca Ceresoli <luca at lucaceresoli.net> wrote:
>>>
>>> If a devm_phy_get() calls fails with phy_count==N (N > 0), then N links
>>> have already been added by device_link_add() and won't be deleted by
>>> device_link_del() because the code calls 'return' and not 'goto err_link'.
>>>
>>> Fix in a very simple way by doing all the devm_phy_get() calls before all
>>> the device_link_add() calls.
>>>
>>> Fixes: 7a4db656a635 ("PCI: dra7xx: Create functional dependency between PCIe and PHY")
>>> Signed-off-by: Luca Ceresoli <luca at lucaceresoli.net>
>>> ---
>>>  drivers/pci/controller/dwc/pci-dra7xx.c | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
>>> index f7f1490e7beb..2ccc53869e13 100644
>>> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
>>> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
>>> @@ -757,7 +757,9 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
>>>                 phy[i] = devm_phy_get(dev, name);
>>>                 if (IS_ERR(phy[i]))
>>>                         return PTR_ERR(phy[i]);
>>> +       }
>>>
>>> +       for (i = 0; i < phy_count; i++) {
>>>                 link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
>>
>> I think this should happen automatically now with fw_devlink being
>> enabled by default. Can you try?
> 
> Do you mean removal should be done automatically? I think they are not
> due to the DL_FLAG_STATELESS flag.

I would love to have feedback because, as said, I think my patch is
correct, but if I'm wrong (which might well be) I have to drop patch 1
and rewrite patch 2 in a slightly more complex form.

About your request to try: I only have hardware with phy_count==1, and
anyway I cannot access it at the moment. :(

Regards.
-- 
Luca


From aneesh.kumar at linux.ibm.com  Tue Jan 11 02:37:57 2022
From: aneesh.kumar at linux.ibm.com (Aneesh Kumar K.V)
Date: Tue, 11 Jan 2022 16:07:57 +0530
Subject: [PATCH v6 7/9] mm: multigenerational lru: eviction
In-Reply-To: <20220104202227.2903605-8-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-8-yuzhao@google.com>
Message-ID: <87czkyzhfe.fsf@linux.ibm.com>

...

 +static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
> +			  int *type_scanned, struct list_head *list)
> +{
> +	int i;
> +	int type;
> +	int scanned;
> +	int tier = -1;
> +	DEFINE_MIN_SEQ(lruvec);
> +
> +	VM_BUG_ON(!seq_is_valid(lruvec));
> +
> +	/*
> +	 * Try to make the obvious choice first. When anon and file are both
> +	 * available from the same generation, interpret swappiness 1 as file
> +	 * first and 200 as anon first.
> +	 */
> +	if (!swappiness)
> +		type = 1;
> +	else if (min_seq[0] < min_seq[1])
> +		type = 0;
> +	else if (swappiness == 1)
> +		type = 1;
> +	else if (swappiness == 200)
> +		type = 0;
> +	else
> +		type = get_type_to_scan(lruvec, swappiness, &tier);
> +

Wondering wether it will make it simpler to use
#define ANON 0
#define FILE 1

and then
	else if (min_seq[ANON] < min_seq[FILE])
		type = ANON;

The usage of 0/1 across code do confuse

-aneesh


From mhocko at suse.com  Tue Jan 11 02:40:55 2022
From: mhocko at suse.com (Michal Hocko)
Date: Tue, 11 Jan 2022 11:40:55 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <CAJmaN=n=kn9-gC8if5wp8Gfj7uN+QVrX0ex=9JPXC7rPvGf1Qg@mail.gmail.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <YdgKClGAuHlkzVbQ@dhcp22.suse.cz>
 <YdiKVJlClB3h1Kmg@google.com> <YdxTR4+FL08XyFuO@dhcp22.suse.cz>
 <YdythmxHpSksJiXs@google.com>
 <CAJmaN=n=kn9-gC8if5wp8Gfj7uN+QVrX0ex=9JPXC7rPvGf1Qg@mail.gmail.com>
Message-ID: <Yd1et2VFOX4xxgly@dhcp22.suse.cz>

On Mon 10-01-22 14:46:08, Jesse Barnes wrote:
> > > > 2. There have been none that came with the testing/benchmarking
> > > >    coverage as this one did. Please point me to some if I'm mistaken,
> > > >    and I'll gladly match them.
> > >
> > > I do appreciate your numbers but you should realize that this is an area
> > > that is really hard to get any conclusive testing for.
> >
> > Fully agreed. That's why we started a new initiative, and we hope more
> > people will following these practices:
> > 1. All results in this area should be reported with at least standard
> >    deviations, or preferably confidence intervals.
> > 2. Real applications should be benchmarked (with synthetic load
> >    generator), not just synthetic benchmarks (not real applications).
> > 3. A wide range of devices should be covered, i.e., servers, desktops,
> >    laptops and phones.
> >
> > I'm very confident to say our benchmark reports were hold to the
> > highest standards. We have worked with MariaDB (company), EnterpriseDB
> > (Postgres), Redis (company), etc. on these reports. They have copies
> > of these reports (PDF version):
> > https://linux-mm.googlesource.com/benchmarks/
> >
> > We welcome any expert in those applications to examine our reports,
> > and we'll be happy to run any other benchmarks or same benchmarks with
> > different configurations that anybody thinks it's important and we've
> > missed.
> 
> I really think this gets at the heart of the issue with mm
> development, and is one of the reasons it's been extra frustrating to
> not have an MM conf for the past couple of years; I think sorting out
> how we measure & proceed on changes would be easier done f2f.  E.g.
> concluding with a consensus that if something doesn't regress on X, Y,
> and Z, and has reasonably maintainable and readable code, we should
> merge it and try it out.

I am fully with you on that! I hope we can have LSFMM this year finally.

> But since f2f isn't an option until 2052 at the earliest...

Let's be more optimistic than that ;)

> I understand the desire for an "incremental approach that gets us from
> A->B".  In the abstract it sounds great.  However, with a change like
> this one, I think it's highly likely that such a path would be
> littered with regressions both large and small, and would probably be
> more difficult to reason about than the relatively clean design of
> MGLRU.

There are certainly things that do not make much sense to split up of
course. On the other hand the patchset is making a lot of decisions and
assumptions that are neither documented in the code nor in the
changelog. From my past experience these are really problematic from a
long term maintenance POV. We are struggling with those already because
changelog tend to be much more coarse in the past yet the code stays
with us and we have been really "great" at not touching many of those
because "something might break". This results in the complexity grow and
further maintenance burden.

> On top of that, I don't think we'll get the kind of user
> feedback we need for something like this *without* merging it.  Yu has
> done a tremendous job collecting data here (and the results are really
> incredible), but I think we can all agree that without extensive
> testing in the field with all sorts of weird codes, we're not going to
> find the problematic behaviors we're concerned about.

This is understood.

> So unless we want to eschew big mm changes entirely (we shouldn't!
> look at net or scheduling for how important big rewrites are to
> progress), I think we should be open to experimenting with new stuff.
> We can always revert if things get too unwieldy.

As long as the patchset doesn't include new user visible interfaces
which have proven to be really hard to revert.

> None of this is to say that there may not be lots more comments on the
> code or potential fixes/changes to incorporate before merging; I'm
> mainly arguing about the mindset we should have to changes like this,
> not all the stuff the community is already really good at (i.e.
> testing and reviewing code on a nuts & bolts level).

>From my reading of this and previous discussions I have gathered that
there was no opposition just for the sake of it. There have been very
specific questions regarding the implementation and/or future plans to
address issues expressed in the past.

So far I have only managed to check the memcg and oom integration
finding some issues there. All of them should be fixable reasonably
easily but it also points that a deep dive into this is really
necessary.

I have also raised questions about future maintainability of the
resulting code. As you could have noticed the review power in the MM
community is lacking behind and we tend to have more code producers than
reviewers and maintainers.
Not to mention other things like page flags depletion which is something
we have been struggling for quite some time already.

All that being said there is a lot of work for such a large change to be
merged.
-- 
Michal Hocko
SUSE Labs


From joel at jms.id.au  Tue Jan 11 02:51:22 2022
From: joel at jms.id.au (Joel Stanley)
Date: Tue, 11 Jan 2022 10:51:22 +0000
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
In-Reply-To: <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>
References: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
 <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>
Message-ID: <CACPK8XcYp9iAD3fjBQCax41C-1UpA+1AQW3epyEooYzNLt7R5g@mail.gmail.com>

On Tue, 11 Jan 2022 at 07:52, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
>
> Hi all,
>
> Any comments?
>
> Thanks,
>
> Heyi
>
> ? 2022/1/9 ??9:26, Heyi Guo ??:
> > The memory will be freed by the caller if transfer timeout occurs,
> > then it would trigger kernel panic if the peer device responds with
> > something after timeout and triggers the interrupt handler of aspeed
> > i2c driver.
> >
> > Set the msgs pointer to NULL to avoid invalid memory reference after
> > timeout to fix this potential kernel panic.

Thanks for the patch. How did you discover this issue? Do you have a
test I can run to reproduce the crash?

Can you provide a Fixes tag?

Do other i2c master drivers do this? I took a quick look at the meson
driver and it doesn't appear to clear it's pointer to msgs.

> >
> > Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>
> >
> > -------
> >
> > Cc: Brendan Higgins <brendanhiggins at google.com>
> > Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> > Cc: Joel Stanley <joel at jms.id.au>
> > Cc: Andrew Jeffery <andrew at aj.id.au>
> > Cc: Philipp Zabel <p.zabel at pengutronix.de>
> > Cc: linux-i2c at vger.kernel.org
> > Cc: openbmc at lists.ozlabs.org
> > Cc: linux-arm-kernel at lists.infradead.org
> > Cc: linux-aspeed at lists.ozlabs.org
> > ---
> >   drivers/i2c/busses/i2c-aspeed.c | 5 +++++
> >   1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> > index 67e8b97c0c950..3ab0396168680 100644
> > --- a/drivers/i2c/busses/i2c-aspeed.c
> > +++ b/drivers/i2c/busses/i2c-aspeed.c
> > @@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
> >               spin_lock_irqsave(&bus->lock, flags);
> >               if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
> >                       bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> > +             /*
> > +              * All the buffers may be freed after returning to caller, so
> > +              * set msgs to NULL to avoid memory reference after freeing.
> > +              */
> > +             bus->msgs = NULL;
> >               spin_unlock_irqrestore(&bus->lock, flags);
> >
> >               return -ETIMEDOUT;


From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:32 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:32 +0100
Subject: [PATCH v9 15/15] arm64: dts: mediatek: Get rid of mediatek, larb
 for MM nodes
In-Reply-To: <20211112105509.12010-16-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-16-yong.wu@mediatek.com>
Message-ID: <231368ef-2619-9556-68fd-45c11e8f7290@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> After adding device_link between the IOMMU consumer and smi,
> the mediatek,larb is unnecessary now.
> 
> CC: Matthias Brugger <matthias.bgg at gmail.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:33 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:33 +0100
Subject: [PATCH v9 13/15] memory: mtk-smi: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20211112105509.12010-14-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-14-yong.wu@mediatek.com>
Message-ID: <d1a6af37-a51a-e31a-aace-d43227ac5e19@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> After adding device_link between the iommu consumer and smi-larb,
> the pm_runtime_get(_sync) of smi-larb and smi-common will be called
> automatically. we can get rid of mtk_smi_larb_get/put.
> 
> CC: Matthias Brugger <matthias.bgg at gmail.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>
> Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:40 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:40 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <20211112105509.12010-13-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
Message-ID: <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> After this patchset, mtk_vcodec_release_enc_pm has only one line.
> then remove that function, use pm_runtime_disable instead.
> 
> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
> rename it from the _pm to _clk.
> 
> No functional change.
> 
> CC: Tiffany Lin <tiffany.lin at mediatek.com>
> CC: Irui Wang <irui.wang at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:41 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:41 +0100
Subject: [PATCH v9 11/15] media: mtk-vcodec: dec: Remove
 mtk_vcodec_release_dec_pm
In-Reply-To: <20211112105509.12010-12-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-12-yong.wu@mediatek.com>
Message-ID: <0a9e348b-fac5-c93b-b4c4-1d834c96c195@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> After this patchset, mtk_vcodec_release_dec_pm has only one line.
> then remove that function. Use pm_runtime_disable directly instead.
> 
> For symmetry, move the pm_runtime_enable out from
> mtk_vcodec_init_dec_pm, then mtk_vcodec_init_dec_pm only operate for
> the clocks, rename it from the _pm to _clk.
> 
> No functional change.
> 
> CC: Tiffany Lin <tiffany.lin at mediatek.com>
> CC: Yunfei Dong <yunfei.dong at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:42 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:42 +0100
Subject: [PATCH v9 10/15] media: mtk-vcodec: Get rid of
 mtk_smi_larb_get/put
In-Reply-To: <20211112105509.12010-11-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-11-yong.wu@mediatek.com>
Message-ID: <4803854b-99b6-278c-f76a-f66e59307871@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the vcodec device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
> 
> CC: Tiffany Lin <tiffany.lin at mediatek.com>
> CC: Irui Wang <irui.wang at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>
> Acked-by: Tiffany Lin <tiffany.lin at mediatek.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:42 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:42 +0100
Subject: [PATCH v9 09/15] drm/mediatek: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20211112105509.12010-10-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-10-yong.wu@mediatek.com>
Message-ID: <c7e626f5-5ef9-83de-8b48-fb0252125811@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the drm device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
> 
> CC: CK Hu <ck.hu at mediatek.com>
> CC: Philipp Zabel <p.zabel at pengutronix.de>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>
> Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:43 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:43 +0100
Subject: [PATCH v9 08/15] drm/mediatek: Add pm runtime support for ovl and
 rdma
In-Reply-To: <20211112105509.12010-9-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-9-yong.wu@mediatek.com>
Message-ID: <ae5c8350-75c1-b90e-3bad-78c19154d7bd@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> From: Yongqiang Niu <yongqiang.niu at mediatek.com>
> 
> Prepare for smi cleaning up "mediatek,larb".
> 
> Display use the dispsys device to call pm_rumtime_get_sync before.
> This patch add pm_runtime_xx with ovl and rdma device whose nodes has
> "iommus" property, then display could help pm_runtime_get for smi via
> ovl or rdma device.
> 
> CC: CK Hu <ck.hu at mediatek.com>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> (Yong: Use pm_runtime_resume_and_get instead of pm_runtime_get_sync)
> Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:44 +0100
Subject: [PATCH v9 07/15] media: mtk-mdp: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20211112105509.12010-8-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-8-yong.wu@mediatek.com>
Message-ID: <16f77e36-fffe-d2d3-2c7c-6412a038238c@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> MediaTek IOMMU has already added the device_link between the consumer
> and smi-larb device. If the mdp device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
> 
> CC: Minghsiu Tsai <minghsiu.tsai at mediatek.com>
> CC: Houlong Wei <houlong.wei at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>
> Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:44 +0100
Subject: [PATCH v9 06/15] media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20211112105509.12010-7-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-7-yong.wu@mediatek.com>
Message-ID: <1003e60d-fa75-d518-943d-72ff88d6b132@collabora.com>

Il 12/11/21 11:55, Yong Wu ha scritto:
> MediaTek IOMMU has already added device_link between the consumer
> and smi-larb device. If the jpg device call the pm_runtime_get_sync,
> the smi-larb's pm_runtime_get_sync also be called automatically.
> 
> After removing the larb_get operations, then mtk_jpeg_clk_init is
> also unnecessary. Remove it too.
> 
> CC: Rick Chang <rick.chang at mediatek.com>
> CC: Xia Jiang <xia.jiang at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Evan Green <evgreen at chromium.org>
> Acked-by: Rick Chang <rick.chang at mediatek.com>
> Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:47 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:47 +0100
Subject: [PATCH v9 05/15] iommu/mediatek: Add device_link between the
 consumer and the larb devices
In-Reply-To: <20211112105509.12010-6-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-6-yong.wu@mediatek.com>
Message-ID: <cb4054ae-4646-ee61-162f-96112ef6dbcf@collabora.com>

Il 12/11/21 11:54, Yong Wu ha scritto:
> MediaTek IOMMU-SMI diagram is like below. all the consumer connect with
> smi-larb, then connect with smi-common.
> 
>          M4U
>           |
>      smi-common
>           |
>    -------------
>    |         |    ...
>    |         |
> larb1     larb2
>    |         |
> vdec       venc
> 
> When the consumer works, it should enable the smi-larb's power which
> also need enable the smi-common's power firstly.
> 
> Thus, First of all, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
> 
> This patch adds device_link between the consumer and the larbs.
> 
> When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
> pm_runtime_xx to keep the original status of clocks. It can avoid two
> issues:
> 1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
> all the clocks are enabled before entering kernel, but the clocks for
> display HW(always in larb0) will be gated after clk_enable and clk_disable
> called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
> operation happened before display driver probe. At that time, the display
> HW will be abnormal.
> 
> 2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
> pm_runtime_xx to avoid the deadlock.
> 
> Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
> device_link_removed should be added explicitly.
> 
> Meanwhile, Currently we don't have a device connect with 2 larbs at the
> same time. Disallow this case, print the error log.
> 
> [1] https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel at mhfsdcap03/
> [2] https://lore.kernel.org/patchwork/patch/1086569/
> 
> Suggested-by: Tomasz Figa <tfiga at chromium.org>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:48 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:48 +0100
Subject: [PATCH v9 04/15] iommu/mediatek: Add probe_defer for smi-larb
In-Reply-To: <20211112105509.12010-5-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-5-yong.wu@mediatek.com>
Message-ID: <eaf59017-49d2-6579-a106-44bd2a21e5af@collabora.com>

Il 12/11/21 11:54, Yong Wu ha scritto:
> Prepare for adding device_link.
> 
> The iommu consumer should use device_link to connect with the
> smi-larb(supplier). then the smi-larb should run before the iommu
> consumer. Here we delay the iommu driver until the smi driver is ready,
> then all the iommu consumers always are after the smi driver.
> 
> When there is no this patch, if some consumer drivers run before
> smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
> device_link_add, then device_links_driver_bound will use WARN_ON
> to complain that the link_status of supplier is not right.
> 
> device_is_bound may be more elegant here. but it is not allowed to
> EXPORT from https://lore.kernel.org/patchwork/patch/1334670/.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:49 +0100
Subject: [PATCH v9 03/15] iommu/mediatek: Return ENODEV if the device is
 NULL
In-Reply-To: <20211112105509.12010-4-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-4-yong.wu@mediatek.com>
Message-ID: <a6a8bb2b-8538-a27c-8e6b-21eb33ecfacd@collabora.com>

Il 12/11/21 11:54, Yong Wu ha scritto:
> The platform device is created at:
> of_platform_default_populate_init:  arch_initcall_sync
>    ->of_platform_populate
>          ->of_platform_device_create_pdata
> 
> When entering our probe, all the devices should be already created.
> if it is null, means NODEV. Currently we don't get the fail case.
> It's a minor fix, no need add fixes tags.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:52 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:52 +0100
Subject: [PATCH v9 01/15] dt-binding: mediatek: Get rid of mediatek, larb
 for multimedia HW
In-Reply-To: <20211112105509.12010-2-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-2-yong.wu@mediatek.com>
Message-ID: <1020e4cf-99d4-0912-eca7-620e44a6d3f0@collabora.com>

Il 12/11/21 11:54, Yong Wu ha scritto:
> After adding device_link between the consumer with the smi-larbs,
> if the consumer call its owner pm_runtime_get(_sync), the
> pm_runtime_get(_sync) of smi-larb and smi-common will be called
> automatically. Thus, the consumer don't need this property.
> 
> And IOMMU also know which larb this consumer connects with from
> iommu id in the "iommus=" property.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Reviewed-by: Evan Green <evgreen at chromium.org>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Tue Jan 11 02:57:51 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 11:57:51 +0100
Subject: [PATCH v9 02/15] iommu/mediatek-v1: Free the existed fwspec if
 the master dev already has
In-Reply-To: <20211112105509.12010-3-yong.wu@mediatek.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-3-yong.wu@mediatek.com>
Message-ID: <db984e48-a0fc-0802-0ce6-69d542c08771@collabora.com>

Il 12/11/21 11:54, Yong Wu ha scritto:
> When the iommu master device enters of_iommu_xlate, the ops may be
> NULL(iommu dev is defered), then it will initialize the fwspec here:
> 
> [<c0c9c5bc>] (dev_iommu_fwspec_set) from [<c06bda80>]
> (iommu_fwspec_init+0xbc/0xd4)
> [<c06bd9c4>] (iommu_fwspec_init) from [<c06c0db4>]
> (of_iommu_xlate+0x7c/0x12c)
> [<c06c0d38>] (of_iommu_xlate) from [<c06c10e8>]
> (of_iommu_configure+0x144/0x1e8)
> 
> BUT the mtk_iommu_v1.c only supports arm32, the probing flow still is a bit
> weird. We always expect create the fwspec internally. otherwise it will
> enter here and return fail.
> 
> static int mtk_iommu_create_mapping(struct device *dev,
> 				    struct of_phandle_args *args)
> {
>          ...
> 	if (!fwspec) {
> 	        ....
> 	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {
>                  >>>>>>>>>>Enter here. return fail.<<<<<<<<<<<<
> 		return -EINVAL;
> 	}
> 	...
> }
> 
> Thus, Free the existed fwspec if the master device already has fwspec.
> 
> This issue is reported at:
> https://lore.kernel.org/linux-mediatek/trinity-7d9ebdc9-4849-4d93-bfb5-429dcb4ee449-1626253158870 at 3c-app-gmx-bs01/
> 
> Reported-by: Frank Wunderlich <frank-w at public-files.de>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From joel at jms.id.au  Tue Jan 11 02:59:28 2022
From: joel at jms.id.au (Joel Stanley)
Date: Tue, 11 Jan 2022 10:59:28 +0000
Subject: [PATCH] ARM: dts: aspeed: Add ASRock ROMED8HM3 BMC
In-Reply-To: <20220105101719.7093-1-zev@bewilderbeest.net>
References: <20220105101719.7093-1-zev@bewilderbeest.net>
Message-ID: <CACPK8XeHyoo0D1vQm=L8m284kC5n-O+FEMp1HN+ROWJfx7qjhQ@mail.gmail.com>

On Wed, 5 Jan 2022 at 23:10, Zev Weiss <zev at bewilderbeest.net> wrote:
>
> This is a half-width, single-socket Epyc server board with an AST2500
> BMC.  This device tree is sufficient for basic OpenBMC functionality,
> but we'll need to add a few more devices (as driver support becomes
> available) before it's fully usable.
>
> Signed-off-by: Zev Weiss <zev at bewilderbeest.net>

Reviewed-by: Joel Stanley <joel at jms.id.au>

Have you considered using the openbmc gpio naming scheme for the
gpio-line-names?


> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  .../boot/dts/aspeed-bmc-asrock-romed8hm3.dts  | 259 ++++++++++++++++++
>  2 files changed, 260 insertions(+)
>  create mode 100644 arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
>
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..4008d2143b44 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1481,6 +1481,7 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
>         aspeed-bmc-arm-centriq2400-rep.dtb \
>         aspeed-bmc-arm-stardragon4800-rep2.dtb \
>         aspeed-bmc-asrock-e3c246d4i.dtb \
> +       aspeed-bmc-asrock-romed8hm3.dtb \
>         aspeed-bmc-bytedance-g220a.dtb \
>         aspeed-bmc-facebook-cloudripper.dtb \
>         aspeed-bmc-facebook-cmm.dtb \
> diff --git a/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
> new file mode 100644
> index 000000000000..e71ccfd1df63
> --- /dev/null
> +++ b/arch/arm/boot/dts/aspeed-bmc-asrock-romed8hm3.dts
> @@ -0,0 +1,259 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/dts-v1/;
> +
> +#include "aspeed-g5.dtsi"
> +#include <dt-bindings/gpio/aspeed-gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/{
> +       model = "ASRock ROMED8HM3 BMC v1.00";
> +       compatible = "asrock,romed8hm3-bmc", "aspeed,ast2500";
> +
> +       aliases {
> +               serial4 = &uart5;
> +       };
> +
> +       chosen {
> +               stdout-path = &uart5;
> +               bootargs = "console=tty0 console=ttyS4,115200 earlycon";
> +       };
> +
> +       memory at 80000000 {
> +               reg = <0x80000000 0x20000000>;
> +       };
> +
> +       leds {
> +               compatible = "gpio-leds";
> +
> +               heartbeat {
> +                       gpios = <&gpio ASPEED_GPIO(H, 6) GPIO_ACTIVE_LOW>;
> +                       linux,default-trigger = "timer";
> +               };
> +
> +               system-fault {
> +                       gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
> +                       panic-indicator;
> +               };
> +       };
> +
> +       iio-hwmon {
> +               compatible = "iio-hwmon";
> +               io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
> +                       <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
> +                       <&adc 8>, <&adc 9>, <&adc 10>, <&adc 11>,
> +                       <&adc 12>, <&adc 13>, <&adc 14>, <&adc 15>;
> +       };
> +};
> +
> +&fmc {
> +       status = "okay";
> +       flash at 0 {
> +               status = "okay";
> +               m25p,fast-read;
> +               label = "bmc";
> +               spi-max-frequency = <100000000>; /* 100 MHz */
> +#include "openbmc-flash-layout-64.dtsi"
> +       };
> +};
> +
> +&uart5 {
> +       status = "okay";
> +};
> +
> +&vuart {
> +       status = "okay";
> +       aspeed,lpc-io-reg = <0x2f8>;
> +       aspeed,lpc-interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&mac0 {
> +       status = "okay";
> +
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_rgmii1_default &pinctrl_mdio1_default>;
> +};
> +
> +&i2c0 {
> +       status = "okay";
> +
> +       /* inlet temp sensor */
> +       w83773g at 4c {
> +               compatible = "nuvoton,w83773g";
> +               reg = <0x4c>;
> +       };
> +};
> +
> +&i2c1 {
> +       status = "okay";
> +};
> +
> +&i2c2 {
> +       status = "okay";
> +
> +       /* IPB temp sensor */
> +       w83773g at 4c {
> +               compatible = "nuvoton,w83773g";
> +               reg = <0x4c>;
> +       };
> +
> +       /* IPB PMIC */
> +       lm25066 at 40 {
> +               compatible = "lm25066";
> +               reg = <0x40>;
> +       };
> +
> +       /* 12VSB PMIC */
> +       lm25066 at 41 {
> +               compatible = "lm25066";
> +               reg = <0x41>;
> +       };
> +};
> +
> +&i2c4 {
> +       status = "okay";
> +};
> +
> +&i2c5 {
> +       status = "okay";
> +};
> +
> +&i2c6 {
> +       status = "okay";
> +};
> +
> +&i2c7 {
> +       status = "okay";
> +
> +       /* Baseboard FRU eeprom */
> +       eeprom at 50 {
> +               compatible = "st,24c128", "atmel,24c128";
> +               reg = <0x50>;
> +               pagesize = <16>;
> +       };
> +};
> +
> +&i2c8 {
> +       status = "okay";
> +};
> +
> +&i2c9 {
> +       status = "okay";
> +};
> +
> +&video {
> +       status = "okay";
> +};
> +
> +&vhub {
> +       status = "okay";
> +};
> +
> +&lpc_ctrl {
> +       status = "okay";
> +};
> +
> +&lpc_snoop {
> +       status = "okay";
> +       snoop-ports = <0x80>;
> +};
> +
> +&kcs3 {
> +       status = "okay";
> +       aspeed,lpc-io-reg = <0xca2>;
> +};
> +
> +&pwm_tacho {
> +       status = "okay";
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_pwm3_default
> +               &pinctrl_pwm4_default
> +               &pinctrl_pwm5_default
> +               &pinctrl_pwm6_default>;
> +
> +       fan at 3 {
> +               reg = <0x03>;
> +               aspeed,fan-tach-ch = /bits/ 8 <0x03 0x0b>;
> +       };
> +
> +       fan at 4 {
> +               reg = <0x04>;
> +               aspeed,fan-tach-ch = /bits/ 8 <0x04 0x0c>;
> +       };
> +
> +       fan at 5 {
> +               reg = <0x05>;
> +               aspeed,fan-tach-ch = /bits/ 8 <0x05 0x0d>;
> +       };
> +
> +       fan at 6 {
> +               reg = <0x06>;
> +               aspeed,fan-tach-ch = /bits/ 8 <0x06 0x0e>;
> +       };
> +};
> +
> +&gpio {
> +       status = "okay";
> +       gpio-line-names =
> +               /*  A */ "LOCATORLED_STATUS_N", "BMC_MAC2_INTB", "NMI_BTN_N", "BMC_NMI",
> +                       "", "", "", "",
> +               /*  B */ "DDR_MEM_TEMP", "", "", "", "", "", "", "",
> +               /*  C */ "", "", "", "", "PCIE_HP_SEL_N", "PCIE_SATA_SEL_N", "LOCATORBTN", "",
> +               /*  D */ "BMC_PSIN", "BMC_PSOUT", "BMC_RESETCON", "RESETCON",
> +                       "", "", "", "PSU_FAN_FAIL_N",
> +               /*  E */ "", "", "", "", "", "", "", "",
> +               /*  F */ "NIC_PWR_GOOD", "PRSNTB0", "PRSNTB1", "PRSNTB2",
> +                       "PRSNTB3", "", "3VSB_PCIE1_PG", "12V_PCIE1_PG",
> +               /*  G */ "HWM_BAT_EN", "CHASSIS_ID0", "CHASSIS_ID1", "CHASSIS_ID2",
> +                       "BMC_ALERT1_N_R", "BMC_ALERT2_N_R", "BMC_ALERT3_N", "BMC_ALERT4_N",
> +               /*  H */ "X24_C1_PRSNT", "X24_C2_PRSNT", "X24_C3_PRSNT", "FM_MEM_THERM_EVENT_BMC_R_N",
> +                       "FACMODE", "BMC_RTCRST", "BMC_HB_LED_N", "BMC_CASEOPEN",
> +               /*  I */ "", "", "", "", "", "", "", "",
> +               /*  J */ "BMC_READY", "BMC_PCH_BIOS_CS_N", "", "P0_MA_DDR_QS_CS_N",
> +                       "", "", "", "",
> +               /*  K */ "", "", "", "", "", "", "", "",
> +               /*  L */ "", "", "", "", "", "", "", "",
> +               /*  M */ "", "", "MEZZ_PWRBRK_N", "OCP_HP_RST_EN",
> +                       "MAIN_PWR_EN_G", "BMC_MAIN_EN", "AUX_PWR_EN_G", "BMC_AUX_EN",
> +               /*  N */ "", "", "", "", "", "", "", "",
> +               /*  O */ "", "", "", "", "", "", "", "",
> +               /*  P */ "", "", "", "", "", "", "", "",
> +               /*  Q */ "", "", "", "",
> +                       "BMC_SMB_PRESENT_1_N", "BMC_SMB_PRESENT_2_N",
> +                       "BMC_SMB_PRESENT_3_N", "BMC_PCIE_WAKE_N",
> +               /*  R */ "", "", "THERMALTRIP_CLEAR_N", "", "", "", "", "",
> +               /*  S */ "", "", "", "", "", "", "", "",
> +               /*  T */ "", "", "", "", "", "", "", "",
> +               /*  U */ "", "", "", "", "", "", "", "",
> +               /*  V */ "", "", "", "", "", "", "", "",
> +               /*  W */ "", "", "", "", "", "", "", "",
> +               /*  X */ "", "", "", "", "", "", "", "",
> +               /*  Y */ "SLP_S3", "SLP_S4_S5", "NODE_ID_1", "NODE_ID_2", "", "", "", "",
> +               /*  Z */ "", "", "SYSTEM_FAULT_LED_N", "FAST_THROTTLE_N",
> +                       "", "", "", "",
> +               /* AA */ "FM_CPU0_IBMC_THERMTRIP_N", "", "PROCHOT_L_G", "",
> +                       "", "", "", "",
> +               /* AB */ "BMC_FORCE_SELFREFRESH", "PWRGD_OUT", "", "IRQ_BMC_PCH_SMI_LPC_N",
> +                       "", "", "", "",
> +               /* AC */ "", "", "", "", "", "", "", "";
> +};
> +
> +&adc {
> +       status = "okay";
> +       pinctrl-names = "default";
> +       pinctrl-0 = <&pinctrl_adc0_default
> +               &pinctrl_adc1_default
> +               &pinctrl_adc2_default
> +               &pinctrl_adc3_default
> +               &pinctrl_adc4_default
> +               &pinctrl_adc5_default
> +               &pinctrl_adc6_default
> +               &pinctrl_adc7_default
> +               &pinctrl_adc8_default
> +               &pinctrl_adc9_default
> +               &pinctrl_adc10_default
> +               &pinctrl_adc11_default
> +               &pinctrl_adc12_default
> +               &pinctrl_adc13_default
> +               &pinctrl_adc14_default
> +               &pinctrl_adc15_default>;
> +};
> --
> 2.34.1
>


From mark.rutland at arm.com  Tue Jan 11 03:05:06 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 11:05:06 +0000
Subject: [PATCH] arm64: Make CONFIG_ARM64_PSEUDO_NMI macro wrap all the
 pseudo-NMI code
In-Reply-To: <168f7e83-e815-f10e-3a43-8529aab77f1e@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
 <Ydg939btY/bzEAe4@FVFF77S0Q05N>
 <bd82d240-34d7-4df9-650b-c039555f05e3@huawei.com>
 <YdwX5RTVbw8veM98@FVFF77S0Q05N>
 <168f7e83-e815-f10e-3a43-8529aab77f1e@huawei.com>
Message-ID: <Yd1kYu8CMlGYeb20@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 04:52:32PM +0800, He Ying wrote:
> ? 2022/1/10 19:26, Mark Rutland ??:
> > On Mon, Jan 10, 2022 at 11:00:43AM +0800, He Ying wrote:
> > > ? 2022/1/7 21:19, Mark Rutland ??:
> > > > On Fri, Jan 07, 2022 at 03:55:36AM -0500, He Ying wrote:
 
> > Due to the large numbers, I suspect this must be due to a specific fast-path,
> > and it's possible that this is due to secondary factors (e.g. alignment of
> > code) rather than the pseudo-NMK code itself.
> > 
> > We need to narrow down *where* time is being spent. Since it appears that this
> > is related to the local IRQ state management, it isn't likely that we can
> > determine that reliably with the PMU. Given that, I think the first step is to
> > reproduce the result elsewhere, for which we will need some plublicly available
> > test-case.
> 
> As said before, I asked our collegues how they did the ARP test. In one word,
> a very small performance regression may bring the big change to the test
> result.
> 
> I feel very sorry for missing this important information. So, this patch may
> improve the performance a little and then lead to the big change to the
> test result.

No problem; thanks for confirming.

[...]

> OK, I see. What do you think if I send a v2 patch that only adds ifdeffery
> to
> 
> arch/arm64/kernel/entry.S and leave the rework to ALERNATIVE behind?

I think that would be reasonable given we do that for other bits in entry.S;
I'd be happy with such a patch.

Thanks,
Mark.


From angelogioacchino.delregno at collabora.com  Tue Jan 11 03:05:56 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 12:05:56 +0100
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <c0279078032bae61e6c1d70be74d1fb8c528083f.camel@mediatek.com>
References: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
 <c0279078032bae61e6c1d70be74d1fb8c528083f.camel@mediatek.com>
Message-ID: <8a87c97e-fd58-bc73-44a6-0055b86cd7ea@collabora.com>

Il 06/01/22 06:22, CK Hu ha scritto:
> Hi, Angelo:
> 
> On Tue, 2022-01-04 at 10:59 +0100, AngeloGioacchino Del Regno wrote:
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
> 
> This patch looks good to me, but please add 'Fixes' tag to note to
> which patch this patch want to fix.
> 
> Regards,
> CK
> 

Hello,
unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM API was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.

Thanks,
- Angelo


From wenst at chromium.org  Tue Jan 11 03:22:37 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:37 +0800
Subject: [PATCH 0/7] pinctrl: mediatek: Fixes and minor improvements
Message-ID: <20220111112244.1483783-1-wenst@chromium.org>

Hi everyone,

Here are some fixes and minor improvements to generic pinconf and the
Mediatek Paris pinctrl driver.

Patch 1 makes the generic pinconf library print out arguments for
PIN_CONFIG_BIAS_PULL_* in debugfs.

Patch 2 fixes bogus readback of PIN_CONFIG_BIAS_DISABLE being always
present.

Patch 3 fixes the type of the "argument" argument in mtk_pinconf_get().
This was erroneously typed as an enum when it should have been u32.

Patch 4 fixes the pingroup config state readback to actually do
readback.

Patch 5 drops an extra newline in the pinconf debugfs output.

Patch 6 cleans up the debugfs output, skipping the custom hardware state
output on the virtual GPIOs, which have no corresponding hardware.

Patch 7 adds support for PIN_CONFIG_DRIVE_STRENGTH_UA (drive-strength-uA)
to the Mediatek Paris pinctrl library. The goal is to replace the vendor
specific "mtk,drive-strength-adv" property with the generic one.

Later on we might want to deprecate "mtk,drive-strength-adv".

Please have a look.


Regards
ChenYu


Chen-Yu Tsai (7):
  pinctrl: pinconf-generic: Print arguments for bias-pull-*
  pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_DISABLE readback
  pinctrl: mediatek: paris: Fix "argument" argument type for
    mtk_pinconf_get()
  pinctrl: mediatek: paris: Fix pingroup pin config state readback
  pinctrl: mediatek: paris: Drop extra newline in
    mtk_pctrl_show_one_pin()
  pinctrl: mediatek: paris: Skip custom extra pin config dump for vrtual
    GPIOs
  pinctrl: mediatek: paris: Support generic PIN_CONFIG_DRIVE_STRENGTH_UA

 drivers/pinctrl/mediatek/pinctrl-paris.c | 106 ++++++++++++++++++++---
 drivers/pinctrl/pinconf-generic.c        |   6 +-
 2 files changed, 98 insertions(+), 14 deletions(-)

-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:38 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:38 +0800
Subject: [PATCH 1/7] pinctrl: pinconf-generic: Print arguments for bias-pull-*
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-2-wenst@chromium.org>

The bias-pull-* properties, or PIN_CONFIG_BIAS_PULL_* pin config
parameters, accept optional arguments in ohms denoting the strength of
the pin bias.

Print these values out in debugfs as well.

Fixes: eec450713e5c ("pinctrl: pinconf-generic: Add flag to print arguments")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/pinconf-generic.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
index f8edcc88ac01..415d1df8f46a 100644
--- a/drivers/pinctrl/pinconf-generic.c
+++ b/drivers/pinctrl/pinconf-generic.c
@@ -30,10 +30,10 @@ static const struct pin_config_item conf_items[] = {
 	PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false),
 	PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false),
 	PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false),
-	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false),
+	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", "ohms", true),
 	PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
-				"input bias pull to pin specific state", NULL, false),
-	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false),
+				"input bias pull to pin specific state", "ohms", true),
+	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", "ohms", true),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false),
 	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false),
 	PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false),
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:39 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:39 +0800
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_DISABLE
 readback
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-3-wenst@chromium.org>

When reading back pin bias settings, if the pin is not in a
bias-disabled state, the function should return -EINVAL.

Fix this in the mediatek-paris pinctrl library so that the read back
state is not littered with bogus a "input bias disabled" combined with
"pull up" or "pull down" states.

Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index f9f9110f2107..1ca598ea7ba7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -97,8 +97,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 			if (err)
 				goto out;
 			if (param == PIN_CONFIG_BIAS_DISABLE) {
-				if (ret == MTK_PUPD_SET_R1R0_00)
-					ret = MTK_DISABLE;
+				if (ret != MTK_PUPD_SET_R1R0_00)
+					err = -EINVAL;
 			} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
 				/* When desire to get pull-up value, return
 				 *  error if current setting is pull-down
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:40 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:40 +0800
Subject: [PATCH 3/7] pinctrl: mediatek: paris: Fix "argument" argument type
 for mtk_pinconf_get()
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-4-wenst@chromium.org>

For mtk_pinconf_get(), the "argument" argument is typically returned by
pinconf_to_config_argument(), which holds the value for a given pinconf
parameter. It certainly should not have the type of "enum pin_config_param",
which describes the type of the pinconf parameter itself.

Change the type to u32, which matches the return type of
pinconf_to_config_argument().

Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 1ca598ea7ba7..d720624d8cd2 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -188,8 +188,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 }
 
 static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
-			   enum pin_config_param param,
-			   enum pin_config_param arg)
+			   enum pin_config_param param, u32 arg)
 {
 	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
 	const struct mtk_pin_desc *desc;
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:41 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:41 +0800
Subject: [PATCH 4/7] pinctrl: mediatek: paris: Fix pingroup pin config state
 readback
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-5-wenst@chromium.org>

mtk_pconf_group_get(), used to read back pingroup pin config state,
simply returns a set of configs saved from a previous invocation of
mtk_pconf_group_set(). This is an unfiltered, unvalidated set passed
in from the pinconf core, which does not match the current hardware
state.

Since the driver library is designed to have a pin per group, pass
through mtk_pconf_group_get() to mtk_pinconf_get(), to read back
the current pin config state of the only pin in the group.

Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index d720624d8cd2..d259f075c62d 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -736,10 +736,10 @@ static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, unsigned group,
 			       unsigned long *config)
 {
 	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
+	struct mtk_pinctrl_group *grp = &hw->groups[group];
 
-	*config = hw->groups[group].config;
-
-	return 0;
+	 /* One pin per group only */
+	return mtk_pinconf_get(pctldev, grp->pin, config);
 }
 
 static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:42 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:42 +0800
Subject: [PATCH 5/7] pinctrl: mediatek: paris: Drop extra newline in
 mtk_pctrl_show_one_pin()
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-6-wenst@chromium.org>

The caller of mtk_pctrl_show_one_pin() is responsible for printing the
full line. mtk_pctrl_show_one_pin(), called through mtk_pctrl_dbg_show(),
should only produce a string containing the extra information the driver
wants included.

Drop the extra newlines.

Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
Fixes: fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index d259f075c62d..1bacabfbc183 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -639,12 +639,10 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 			pullup);
 
 	if (r1 != -1) {
-		len += scnprintf(buf + len, buf_len - len, " (%1d %1d)\n",
+		len += scnprintf(buf + len, buf_len - len, " (%1d %1d)",
 			r1, r0);
 	} else if (rsel != -1) {
-		len += scnprintf(buf + len, buf_len - len, " (%1d)\n", rsel);
-	} else {
-		len += scnprintf(buf + len, buf_len - len, "\n");
+		len += scnprintf(buf + len, buf_len - len, " (%1d)", rsel);
 	}
 
 	return len;
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:43 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:43 +0800
Subject: [PATCH 6/7] pinctrl: mediatek: paris: Skip custom extra pin config
 dump for vrtual GPIOs
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-7-wenst@chromium.org>

Virtual GPIOs do not have any hardware state associated with them. Any
attempt to read back hardware state for these pins result in error
codes.

Skip dumping extra pin config information for these virtual GPIOs.

Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 1bacabfbc183..678c8aa33012 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -585,6 +585,9 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
 	if (gpio >= hw->soc->npins)
 		return -EINVAL;
 
+	if (mtk_is_virt_gpio(hw, gpio))
+		return -EINVAL;
+
 	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
 	pinmux = mtk_pctrl_get_pinmux(hw, gpio);
 	if (pinmux >= hw->soc->nfuncs)
-- 
2.34.1.575.g55b058a8bb-goog



From wenst at chromium.org  Tue Jan 11 03:22:44 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 11 Jan 2022 19:22:44 +0800
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <20220111112244.1483783-8-wenst@chromium.org>

Some of the MediaTek chips that utilize the Paris pinctrl driver library
support a lower drive strength (<= 1mA) than the standard drive strength
settings (2~16 mA) on certain pins. This was previously supported by the
custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
"mediatek,drive-strength-adv" device tree property.

The drive strength values for this hardware are 125, 250, 500, and 1000 mA,
and can be readily described by the existing "drive-strength-microamp",
which then gets parsed by the generic pinconf library into the parameter
PIN_CONFIG_DRIVE_STRENGTH_UA.

Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
custom parameter around for backward compatibility.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---

The indentation in the switch/case blocks is getting somewhat out of
control. I also have some cleanup changes to reverse the logic of the
if/break statements. Not sure if it should be done before or after this
patch though.

---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 84 ++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
index 678c8aa33012..5a94903ae372 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = {
 	"func12", "func13", "func14", "func15",
 };
 
+/*
+ * This section supports converting to/from custom MTK_PIN_CONFIG_DRV_ADV
+ * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs.
+ *
+ * The custom value encodes three hardware bits as follows:
+ *
+ *   |           Bits           |
+ *   | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA)
+ *   ------------------------------------------------
+ *   |    x   |    x   |    0   | disabled, use standard drive strength
+ *   -------------------------------------
+ *   |    0   |    0   |    1   |  125 uA
+ *   |    0   |    1   |    1   |  250 uA
+ *   |    1   |    0   |    1   |  500 uA
+ *   |    1   |    1   |    1   | 1000 uA
+ */
+static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 };
+
+static int mtk_drv_adv_to_uA(int val)
+{
+	/* This should never happen. */
+	if (WARN_ON_ONCE(val < 0 || val > 7))
+		return -EINVAL;
+
+	/* Bit 0 simply enables this hardware part */
+	if (!(val & BIT(0)))
+		return -EINVAL;
+
+	return mtk_drv_adv_uA[(val >> 1)];
+}
+
+static int mtk_drv_uA_to_adv(int val)
+{
+	switch (val) {
+	case 125:
+		return 0x1;
+	case 250:
+		return 0x3;
+	case 500:
+		return 0x5;
+	case 1000:
+		return 0x7;
+	}
+
+	return -EINVAL;
+}
+
 static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
 					  struct pinctrl_gpio_range *range,
 					  unsigned int pin)
@@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
 
 		break;
 	case PIN_CONFIG_DRIVE_STRENGTH:
+		if (hw->soc->adv_drive_get) {
+			err = hw->soc->adv_drive_get(hw, desc, &ret);
+			if (!err) {
+				err = mtk_drv_adv_to_uA(ret);
+				if (err > 0) {
+					/* PIN_CONFIG_DRIVE_STRENGTH_UA used */
+					err = -EINVAL;
+					break;
+				}
+			}
+		}
+
 		if (hw->soc->drive_get)
 			err = hw->soc->drive_get(hw, desc, &ret);
 		else
 			err = -ENOTSUPP;
 		break;
+	case PIN_CONFIG_DRIVE_STRENGTH_UA:
+		if (hw->soc->adv_drive_get) {
+			err = hw->soc->adv_drive_get(hw, desc, &ret);
+			if (err)
+				break;
+			err = mtk_drv_adv_to_uA(ret);
+			if (err < 0)
+				break;
+
+			ret = err;
+			err = 0;
+		} else {
+			err = -ENOTSUPP;
+		}
+		break;
 	case MTK_PIN_CONFIG_TDSEL:
 	case MTK_PIN_CONFIG_RDSEL:
 		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
@@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 		else
 			err = -ENOTSUPP;
 		break;
+	case PIN_CONFIG_DRIVE_STRENGTH_UA:
+		if (hw->soc->adv_drive_set) {
+			err = mtk_drv_uA_to_adv(arg);
+			if (err < 0)
+				break;
+			err = hw->soc->adv_drive_set(hw, desc, err);
+		} else {
+			err = -ENOTSUPP;
+		}
+		break;
 	case MTK_PIN_CONFIG_TDSEL:
 	case MTK_PIN_CONFIG_RDSEL:
 		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
-- 
2.34.1.575.g55b058a8bb-goog



From matthias.schiffer at ew.tq-group.com  Tue Jan 11 03:25:29 2022
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Tue, 11 Jan 2022 12:25:29 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am65: disable optional peripherals by
 default
Message-ID: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>

All peripharals that require pinmuxing or other configuration to work
should be disabled by default. Dependent DTS are adjusted accordingly.

The following nodes are now "disabled" according to dtx_diff and were not
overridden to "okay", as they define no pinctrl:

k3-am654-base-board:
- mcu_i2c0
- mcu_spi0..2
- cal
- main_i2c3
- ehrpwm0..5
- main_uart1..2
- main_spi1..4

k3-am65-iot2050*:
- mci_spi1..2
- cal
- ehrpwm0..5
- main_spi0..4

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---

These changes were not tested on hardware, and I'm not familiar with
any of these boards, so it would be great if someone could check
whether the effective changes listed above are correct, or if some of
these devices (in particular I2C, UART and PWM) are actually connected
and work with the default pinmuxing.

There were also a few devices where I was unsure whether they are optional
or not - for example one of the io2050 disables all the txpru nodes, so
maybe it would make sense to disable these in the SoC DTSI as well? I left
these nodes unchanged for now.

 .../dts/ti/k3-am65-iot2050-common-pg1.dtsi    |   4 -
 .../dts/ti/k3-am65-iot2050-common-pg2.dtsi    |   7 +
 .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 132 +++++-------------
 arch/arm64/boot/dts/ti/k3-am65-main.dtsi      |  52 +++++++
 arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi       |  10 ++
 arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi    |   2 +
 .../ti/k3-am6528-iot2050-basic-common.dtsi    |   6 +-
 .../arm64/boot/dts/ti/k3-am654-base-board.dts | 129 +++--------------
 .../ti/k3-am6548-iot2050-advanced-common.dtsi |   5 +-
 9 files changed, 134 insertions(+), 213 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
index 51f902fa35a7..746f0e89a305 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
@@ -13,10 +13,6 @@ &dss {
 	assigned-clock-parents = <&k3_clks 67 5>;
 };
 
-&serdes0 {
-	status = "disabled";
-};
-
 &sdhci1 {
 	no-1-8-v;
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
index e73458ca6900..b769fe6fc072 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
@@ -35,6 +35,7 @@ &dss {
 &serdes0 {
 	assigned-clocks = <&k3_clks 153 4>, <&serdes0 AM654_SERDES_CMU_REFCLK>;
 	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
+	status = "okay";
 };
 
 &dwc3_0 {
@@ -42,10 +43,16 @@ &dwc3_0 {
 				 <&k3_clks 151 8>;  /* set PIPE3_TXB_CLK to WIZ8B2M4VSB */
 	phys = <&serdes0 PHY_TYPE_USB3 0>;
 	phy-names = "usb3-phy";
+	status = "okay";
 };
 
 &usb0 {
 	maximum-speed = "super-speed";
 	snps,dis-u1-entry-quirk;
 	snps,dis-u2-entry-quirk;
+	status = "okay";
+};
+
+&usb0_phy {
+	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
index 3079eaee01c0..873c123c611e 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -362,15 +362,13 @@ &wkup_uart0 {
 &main_uart1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart1_pins_default>;
-};
-
-&main_uart2 {
-	status = "disabled";
+	status = "okay";
 };
 
 &mcu_uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&arduino_uart_pins_default>;
+	status = "okay";
 };
 
 &main_gpio0 {
@@ -416,12 +414,14 @@ &wkup_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_i2c0_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 };
 
 &mcu_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_i2c0_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 
 	psu: regulator at 60 {
 		compatible = "ti,tps62363";
@@ -481,6 +481,7 @@ &main_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c0_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 
 	rtc: rtc8564 at 51 {
 		compatible = "nxp,pcf8563";
@@ -498,12 +499,14 @@ &main_i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c1_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 };
 
 &main_i2c2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c2_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 };
 
 &main_i2c3 {
@@ -514,6 +517,8 @@ &main_i2c3 {
 	#address-cells = <1>;
 	#size-cells = <0>;
 
+	status = "okay";
+
 	edp-bridge at f {
 		compatible = "toshiba,tc358767";
 		reg = <0x0f>;
@@ -541,13 +546,10 @@ bridge_in: endpoint {
 	};
 };
 
-&mcu_cpsw {
-	status = "disabled";
-};
-
 &ecap0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ecap0_pins_default>;
+	status = "okay";
 };
 
 &sdhci1 {
@@ -555,20 +557,38 @@ &sdhci1 {
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	status = "okay";
+};
+
+&dwc3_0 {
+	status = "okay";
 };
 
+
 &usb0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb0_pins_default>;
 	dr_mode = "host";
 };
 
+&usb0_phy {
+	status = "okay";
+};
+
+&dwc3_1 {
+	status = "okay";
+};
+
 &usb1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&usb1_pins_default>;
 	dr_mode = "host";
 };
 
+&usb1_phy {
+	status = "okay";
+};
+
 &mcu_spi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_spi0_pins_default>;
@@ -576,13 +596,12 @@ &mcu_spi0 {
 	#address-cells = <1>;
 	#size-cells= <0>;
 	ti,pindir-d0-out-d1-in;
-};
-
-&tscadc0 {
-	status = "disabled";
+	status = "okay";
 };
 
 &tscadc1 {
+	status = "okay";
+
 	adc {
 		ti,adc-channels = <0 1 2 3 4 5>;
 	};
@@ -591,6 +610,7 @@ adc {
 &ospi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+	status = "okay";
 
 	flash at 0 {
 		compatible = "jedec,spi-nor";
@@ -611,6 +631,7 @@ flash at 0 {
 &dss {
 	pinctrl-names = "default";
 	pinctrl-0 = <&dss_vout1_pins_default>;
+	status = "okay";
 
 	assigned-clocks = <&k3_clks 67 2>;
 	assigned-clock-parents = <&k3_clks 67 5>;
@@ -628,17 +649,14 @@ dpi_out: endpoint {
 	};
 };
 
-&pcie0_rc {
-	status = "disabled";
-};
-
-&pcie0_ep {
-	status = "disabled";
+&serdes1 {
+	status = "okay";
 };
 
 &pcie1_rc {
 	pinctrl-names = "default";
 	pinctrl-0 = <&minipcie_pins_default>;
+	status = "okay";
 
 	num-lanes = <1>;
 	phys = <&serdes1 PHY_TYPE_PCIE 0>;
@@ -646,20 +664,9 @@ &pcie1_rc {
 	reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>;
 };
 
-&m_can0 {
-	status = "disabled";
-};
-
-&m_can1 {
-	status = "disabled";
-};
-
-&pcie1_ep {
-	status = "disabled";
-};
-
 &mailbox0_cluster0 {
 	interrupts = <436>;
+	status = "okay";
 
 	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
 		ti,mbox-tx = <1 0 0>;
@@ -669,6 +676,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
 
 &mailbox0_cluster1 {
 	interrupts = <432>;
+	status = "okay";
 
 	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
 		ti,mbox-tx = <1 0 0>;
@@ -676,46 +684,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
 	};
 };
 
-&mailbox0_cluster2 {
-	status = "disabled";
-};
-
-&mailbox0_cluster3 {
-	status = "disabled";
-};
-
-&mailbox0_cluster4 {
-	status = "disabled";
-};
-
-&mailbox0_cluster5 {
-	status = "disabled";
-};
-
-&mailbox0_cluster6 {
-	status = "disabled";
-};
-
-&mailbox0_cluster7 {
-	status = "disabled";
-};
-
-&mailbox0_cluster8 {
-	status = "disabled";
-};
-
-&mailbox0_cluster9 {
-	status = "disabled";
-};
-
-&mailbox0_cluster10 {
-	status = "disabled";
-};
-
-&mailbox0_cluster11 {
-	status = "disabled";
-};
-
 &mcu_r5fss0_core0 {
 	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
 			<&mcu_r5fss0_core0_memory_region>;
@@ -727,27 +695,3 @@ &mcu_r5fss0_core1 {
 			<&mcu_r5fss0_core1_memory_region>;
 	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>;
 };
-
-&icssg0_mdio {
-	status = "disabled";
-};
-
-&icssg1_mdio {
-	status = "disabled";
-};
-
-&icssg2_mdio {
-	status = "disabled";
-};
-
-&mcasp0 {
-	status = "disabled";
-};
-
-&mcasp1 {
-	status = "disabled";
-};
-
-&mcasp2 {
-	status = "disabled";
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
index ce8bb4a61011..5aa425d1ba80 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -64,6 +64,7 @@ serdes0: serdes at 900000 {
 		ti,serdes-clk = <&serdes0_clk>;
 		#clock-cells = <1>;
 		mux-controls = <&serdes_mux 0>;
+		status = "disabled";
 	};
 
 	serdes1: serdes at 910000 {
@@ -79,6 +80,7 @@ serdes1: serdes at 910000 {
 		ti,serdes-clk = <&serdes1_clk>;
 		#clock-cells = <1>;
 		mux-controls = <&serdes_mux 1>;
+		status = "disabled";
 	};
 
 	main_uart0: serial at 2800000 {
@@ -88,6 +90,7 @@ main_uart0: serial at 2800000 {
 		clock-frequency = <48000000>;
 		current-speed = <115200>;
 		power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	main_uart1: serial at 2810000 {
@@ -96,6 +99,7 @@ main_uart1: serial at 2810000 {
 		interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
 		clock-frequency = <48000000>;
 		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	main_uart2: serial at 2820000 {
@@ -104,6 +108,7 @@ main_uart2: serial at 2820000 {
 		interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
 		clock-frequency = <48000000>;
 		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	crypto: crypto at 4e00000 {
@@ -152,6 +157,7 @@ main_i2c0: i2c at 2000000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 110 1>;
 		power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	main_i2c1: i2c at 2010000 {
@@ -163,6 +169,7 @@ main_i2c1: i2c at 2010000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 111 1>;
 		power-domains = <&k3_pds 111 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	main_i2c2: i2c at 2020000 {
@@ -174,6 +181,7 @@ main_i2c2: i2c at 2020000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 112 1>;
 		power-domains = <&k3_pds 112 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	main_i2c3: i2c at 2030000 {
@@ -185,6 +193,7 @@ main_i2c3: i2c at 2030000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 113 1>;
 		power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	ecap0: pwm at 3100000 {
@@ -194,6 +203,7 @@ ecap0: pwm at 3100000 {
 		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 39 0>;
 		clock-names = "fck";
+		status = "disabled";
 	};
 
 	main_spi0: spi at 2100000 {
@@ -206,6 +216,7 @@ main_spi0: spi at 2100000 {
 		#size-cells = <0>;
 		dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>;
 		dma-names = "tx0", "rx0";
+		status = "disabled";
 	};
 
 	main_spi1: spi at 2110000 {
@@ -218,6 +229,7 @@ main_spi1: spi at 2110000 {
 		#size-cells = <0>;
 		assigned-clocks = <&k3_clks 137 1>;
 		assigned-clock-rates = <48000000>;
+		status = "disabled";
 	};
 
 	main_spi2: spi at 2120000 {
@@ -228,6 +240,7 @@ main_spi2: spi at 2120000 {
 		power-domains = <&k3_pds 139 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	main_spi3: spi at 2130000 {
@@ -238,6 +251,7 @@ main_spi3: spi at 2130000 {
 		power-domains = <&k3_pds 140 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	main_spi4: spi at 2140000 {
@@ -248,6 +262,7 @@ main_spi4: spi at 2140000 {
 		power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	sdhci0: mmc at 4f80000 {
@@ -272,6 +287,7 @@ sdhci0: mmc at 4f80000 {
 		ti,otap-del-sel-hs400 = <0x0>;
 		ti,trm-icp = <0x8>;
 		dma-coherent;
+		status = "disabled";
 	};
 
 	sdhci1: mmc at 4fa0000 {
@@ -295,6 +311,7 @@ sdhci1: mmc at 4fa0000 {
 		ti,otap-del-sel = <0x2>;
 		ti,trm-icp = <0x8>;
 		dma-coherent;
+		status = "disabled";
 	};
 
 	scm_conf: scm-conf at 100000 {
@@ -361,6 +378,7 @@ dwc3_0: dwc3 at 4000000 {
 		assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
 		assigned-clock-parents = <&k3_clks 151 4>,	/* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
 					 <&k3_clks 151 9>;	/* set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
+		status = "disabled";
 
 		usb0: usb at 10000 {
 			compatible = "snps,dwc3";
@@ -386,6 +404,7 @@ usb0_phy: phy at 4100000 {
 		clocks = <&k3_clks 151 0>, <&k3_clks 151 1>;
 		clock-names = "wkupclk", "refclk";
 		#phy-cells = <0>;
+		status = "disabled";
 	};
 
 	dwc3_1: dwc3 at 4020000 {
@@ -400,6 +419,7 @@ dwc3_1: dwc3 at 4020000 {
 		clocks = <&k3_clks 152 2>;
 		assigned-clocks = <&k3_clks 152 2>;
 		assigned-clock-parents = <&k3_clks 152 4>;	/* set REF_CLK to 20MHz i.e. PER0_PLL/48 */
+		status = "disabled";
 
 		usb1: usb at 10000 {
 			compatible = "snps,dwc3";
@@ -424,6 +444,7 @@ usb1_phy: phy at 4110000 {
 		clocks = <&k3_clks 152 0>, <&k3_clks 152 1>;
 		clock-names = "wkupclk", "refclk";
 		#phy-cells = <0>;
+		status = "disabled";
 	};
 
 	intr_main_gpio: interrupt-controller at a00000 {
@@ -497,6 +518,7 @@ mailbox0_cluster0: mailbox at 31f80000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster1: mailbox at 31f81000 {
@@ -506,6 +528,7 @@ mailbox0_cluster1: mailbox at 31f81000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster2: mailbox at 31f82000 {
@@ -515,6 +538,7 @@ mailbox0_cluster2: mailbox at 31f82000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster3: mailbox at 31f83000 {
@@ -524,6 +548,7 @@ mailbox0_cluster3: mailbox at 31f83000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster4: mailbox at 31f84000 {
@@ -533,6 +558,7 @@ mailbox0_cluster4: mailbox at 31f84000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster5: mailbox at 31f85000 {
@@ -542,6 +568,7 @@ mailbox0_cluster5: mailbox at 31f85000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster6: mailbox at 31f86000 {
@@ -551,6 +578,7 @@ mailbox0_cluster6: mailbox at 31f86000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster7: mailbox at 31f87000 {
@@ -560,6 +588,7 @@ mailbox0_cluster7: mailbox at 31f87000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster8: mailbox at 31f88000 {
@@ -569,6 +598,7 @@ mailbox0_cluster8: mailbox at 31f88000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster9: mailbox at 31f89000 {
@@ -578,6 +608,7 @@ mailbox0_cluster9: mailbox at 31f89000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster10: mailbox at 31f8a000 {
@@ -587,6 +618,7 @@ mailbox0_cluster10: mailbox at 31f8a000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		mailbox0_cluster11: mailbox at 31f8b000 {
@@ -596,6 +628,7 @@ mailbox0_cluster11: mailbox at 31f8b000 {
 			ti,mbox-num-users = <4>;
 			ti,mbox-num-fifos = <16>;
 			interrupt-parent = <&intr_main_navss>;
+			status = "disabled";
 		};
 
 		ringacc: ringacc at 3c000000 {
@@ -703,6 +736,7 @@ pcie0_rc: pcie at 5500000 {
 		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
 		msi-map = <0x0 &gic_its 0x0 0x10000>;
 		device_type = "pci";
+		status = "disabled";
 	};
 
 	pcie0_ep: pcie-ep at 5500000 {
@@ -716,6 +750,7 @@ pcie0_ep: pcie-ep at 5500000 {
 		max-link-speed = <2>;
 		dma-coherent;
 		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
 	};
 
 	pcie1_rc: pcie at 5600000 {
@@ -736,6 +771,7 @@ pcie1_rc: pcie at 5600000 {
 		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
 		msi-map = <0x0 &gic_its 0x10000 0x10000>;
 		device_type = "pci";
+		status = "disabled";
 	};
 
 	pcie1_ep: pcie-ep at 5600000 {
@@ -749,6 +785,7 @@ pcie1_ep: pcie-ep at 5600000 {
 		max-link-speed = <2>;
 		dma-coherent;
 		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
+		status = "disabled";
 	};
 
 	mcasp0: mcasp at 2b00000 {
@@ -766,6 +803,7 @@ mcasp0: mcasp at 2b00000 {
 		clocks = <&k3_clks 104 0>;
 		clock-names = "fck";
 		power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	mcasp1: mcasp at 2b10000 {
@@ -783,6 +821,7 @@ mcasp1: mcasp at 2b10000 {
 		clocks = <&k3_clks 105 0>;
 		clock-names = "fck";
 		power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	mcasp2: mcasp at 2b20000 {
@@ -800,6 +839,7 @@ mcasp2: mcasp at 2b20000 {
 		clocks = <&k3_clks 106 0>;
 		clock-names = "fck";
 		power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	cal: cal at 6f03000 {
@@ -813,6 +853,7 @@ cal: cal at 6f03000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 2 0>;
 		power-domains = <&k3_pds 2 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 
 		ports {
 			#address-cells = <1>;
@@ -857,6 +898,8 @@ dss: dss at 4a00000 {
 
 		dma-coherent;
 
+		status = "disabled";
+
 		dss_ports: ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -870,6 +913,7 @@ ehrpwm0: pwm at 3000000 {
 		power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 0>, <&k3_clks 40 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	ehrpwm1: pwm at 3010000 {
@@ -879,6 +923,7 @@ ehrpwm1: pwm at 3010000 {
 		power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 1>, <&k3_clks 41 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	ehrpwm2: pwm at 3020000 {
@@ -888,6 +933,7 @@ ehrpwm2: pwm at 3020000 {
 		power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 2>, <&k3_clks 42 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	ehrpwm3: pwm at 3030000 {
@@ -897,6 +943,7 @@ ehrpwm3: pwm at 3030000 {
 		power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 3>, <&k3_clks 43 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	ehrpwm4: pwm at 3040000 {
@@ -906,6 +953,7 @@ ehrpwm4: pwm at 3040000 {
 		power-domains = <&k3_pds 44 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 4>, <&k3_clks 44 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	ehrpwm5: pwm at 3050000 {
@@ -915,6 +963,7 @@ ehrpwm5: pwm at 3050000 {
 		power-domains = <&k3_pds 45 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&ehrpwm_tbclk 5>, <&k3_clks 45 0>;
 		clock-names = "tbclk", "fck";
+		status = "disabled";
 	};
 
 	icssg0: icssg at b000000 {
@@ -1055,6 +1104,7 @@ icssg0_mdio: mdio at 32400 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			bus_freq = <1000000>;
+			status = "disabled";
 		};
 	};
 
@@ -1196,6 +1246,7 @@ icssg1_mdio: mdio at 32400 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			bus_freq = <1000000>;
+			status = "disabled";
 		};
 	};
 
@@ -1337,6 +1388,7 @@ icssg2_mdio: mdio at 32400 {
 			#address-cells = <1>;
 			#size-cells = <0>;
 			bus_freq = <1000000>;
+			status = "disabled";
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
index 8d592bf41d6f..50f26e96276f 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
@@ -46,6 +46,7 @@ mcu_i2c0: i2c at 40b00000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 114 1>;
 		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	mcu_spi0: spi at 40300000 {
@@ -56,6 +57,7 @@ mcu_spi0: spi at 40300000 {
 		power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	mcu_spi1: spi at 40310000 {
@@ -66,6 +68,7 @@ mcu_spi1: spi at 40310000 {
 		power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	mcu_spi2: spi at 40320000 {
@@ -76,6 +79,7 @@ mcu_spi2: spi at 40320000 {
 		power-domains = <&k3_pds 144 TI_SCI_PD_EXCLUSIVE>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		status = "disabled";
 	};
 
 	tscadc0: tscadc at 40200000 {
@@ -89,6 +93,7 @@ tscadc0: tscadc at 40200000 {
 		dmas = <&mcu_udmap 0x7100>,
 			<&mcu_udmap 0x7101 >;
 		dma-names = "fifo0", "fifo1";
+		status = "disabled";
 
 		adc {
 			#io-channel-cells = <1>;
@@ -107,6 +112,7 @@ tscadc1: tscadc at 40210000 {
 		dmas = <&mcu_udmap 0x7102>,
 			<&mcu_udmap 0x7103>;
 		dma-names = "fifo0", "fifo1";
+		status = "disabled";
 
 		adc {
 			#io-channel-cells = <1>;
@@ -172,6 +178,7 @@ m_can0: mcan at 40528000 {
 			     <GIC_SPI 545 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		status = "disabled";
 	};
 
 	m_can1: mcan at 40568000 {
@@ -187,6 +194,7 @@ m_can1: mcan at 40568000 {
 			     <GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-names = "int0", "int1";
 		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
+		status = "disabled";
 	};
 
 	fss: fss at 47000000 {
@@ -252,6 +260,8 @@ mcu_cpsw: ethernet at 46000000 {
 			    "tx4", "tx5", "tx6", "tx7",
 			    "rx";
 
+		status = "disabled";
+
 		ethernet-ports {
 			#address-cells = <1>;
 			#size-cells = <0>;
diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
index 9c69d0917f69..8f0c505a16ed 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
@@ -54,6 +54,7 @@ wkup_uart0: serial at 42300000 {
 		clock-frequency = <48000000>;
 		current-speed = <115200>;
 		power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	wkup_i2c0: i2c at 42120000 {
@@ -65,6 +66,7 @@ wkup_i2c0: i2c at 42120000 {
 		clock-names = "fck";
 		clocks = <&k3_clks 115 1>;
 		power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 	};
 
 	intr_wkup_gpio: interrupt-controller at 42200000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
index 4a9bf7d7c07d..29f539cc2392 100644
--- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
@@ -29,11 +29,6 @@ cpu-map {
 	/delete-node/ l2-cache1;
 };
 
-/* eMMC */
-&sdhci0 {
-	status = "disabled";
-};
-
 &main_pmx0 {
 	main_uart0_pins_default: main-uart0-pins-default {
 		pinctrl-single,pins = <
@@ -52,6 +47,7 @@ AM65X_IOPAD(0x0194, PIN_INPUT,  1)  /* (E24) UART0_RIN */
 &main_uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
+	status = "okay";
 };
 
 &mcu_r5fss0 {
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
index 9043f91c9bec..821ee7f2eff0 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -275,12 +275,14 @@ &main_uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_uart0_pins_default>;
 	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
+	status = "okay";
 };
 
 &wkup_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&wkup_i2c0_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 
 	pca9554: gpio at 39 {
 		compatible = "nxp,pca9554";
@@ -300,6 +302,7 @@ &main_i2c0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c0_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 
 	pca9555: gpio at 21 {
 		compatible = "nxp,pca9555";
@@ -313,17 +316,20 @@ &main_i2c1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c1_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 };
 
 &main_i2c2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&main_i2c2_pins_default>;
 	clock-frequency = <400000>;
+	status = "okay";
 };
 
 &ecap0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&ecap0_pins_default>;
+	status = "okay";
 };
 
 &main_spi0 {
@@ -332,6 +338,7 @@ &main_spi0 {
 	#address-cells = <1>;
 	#size-cells= <0>;
 	ti,pindir-d0-out-d1-in;
+	status = "okay";
 
 	flash at 0{
 		compatible = "jedec,spi-nor";
@@ -351,6 +358,7 @@ &sdhci0 {
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	status = "okay";
 };
 
 /*
@@ -364,6 +372,11 @@ &sdhci1 {
 	pinctrl-0 = <&main_mmc1_pins_default>;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
+	status = "okay";
+};
+
+&dwc3_1 {
+	status = "okay";
 };
 
 &usb1 {
@@ -372,60 +385,29 @@ &usb1 {
 	dr_mode = "otg";
 };
 
-&dwc3_0 {
-	status = "disabled";
-};
-
-&usb0_phy {
-	status = "disabled";
+&usb1_phy {
+	status = "okay";
 };
 
 &tscadc0 {
+	status = "okay";
+
 	adc {
 		ti,adc-channels = <0 1 2 3 4 5 6 7>;
 	};
 };
 
 &tscadc1 {
+	status = "okay";
+
 	adc {
 		ti,adc-channels = <0 1 2 3 4 5 6 7>;
 	};
 };
 
-&serdes0 {
-	status = "disabled";
-};
-
-&serdes1 {
-	status = "disabled";
-};
-
-&pcie0_rc {
-	status = "disabled";
-};
-
-&pcie0_ep {
-	status = "disabled";
-};
-
-&pcie1_rc {
-	status = "disabled";
-};
-
-&pcie1_ep {
-	status = "disabled";
-};
-
-&m_can0 {
-	status = "disabled";
-};
-
-&m_can1 {
-	status = "disabled";
-};
-
 &mailbox0_cluster0 {
 	interrupts = <436>;
+	status = "okay";
 
 	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
 		ti,mbox-tx = <1 0 0>;
@@ -435,6 +417,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
 
 &mailbox0_cluster1 {
 	interrupts = <432>;
+	status = "okay";
 
 	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
 		ti,mbox-tx = <1 0 0>;
@@ -442,46 +425,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
 	};
 };
 
-&mailbox0_cluster2 {
-	status = "disabled";
-};
-
-&mailbox0_cluster3 {
-	status = "disabled";
-};
-
-&mailbox0_cluster4 {
-	status = "disabled";
-};
-
-&mailbox0_cluster5 {
-	status = "disabled";
-};
-
-&mailbox0_cluster6 {
-	status = "disabled";
-};
-
-&mailbox0_cluster7 {
-	status = "disabled";
-};
-
-&mailbox0_cluster8 {
-	status = "disabled";
-};
-
-&mailbox0_cluster9 {
-	status = "disabled";
-};
-
-&mailbox0_cluster10 {
-	status = "disabled";
-};
-
-&mailbox0_cluster11 {
-	status = "disabled";
-};
-
 &mcu_r5fss0_core0 {
 	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
 			<&mcu_r5fss0_core0_memory_region>;
@@ -497,6 +440,7 @@ &mcu_r5fss0_core1 {
 &ospi0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+	status = "okay";
 
 	flash at 0{
 		compatible = "jedec,spi-nor";
@@ -517,6 +461,7 @@ flash at 0{
 &mcu_cpsw {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
+	status = "okay";
 };
 
 &davinci_mdio {
@@ -531,31 +476,3 @@ &cpsw_port1 {
 	phy-mode = "rgmii-rxid";
 	phy-handle = <&phy0>;
 };
-
-&mcasp0 {
-	status = "disabled";
-};
-
-&mcasp1 {
-	status = "disabled";
-};
-
-&mcasp2 {
-	status = "disabled";
-};
-
-&dss {
-	status = "disabled";
-};
-
-&icssg0_mdio {
-	status = "disabled";
-};
-
-&icssg1_mdio {
-	status = "disabled";
-};
-
-&icssg2_mdio {
-	status = "disabled";
-};
diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
index d25e8b26187f..731224ec5c36 100644
--- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
@@ -49,8 +49,5 @@ &sdhci0 {
 	non-removable;
 	ti,driver-strength-ohm = <50>;
 	disable-wp;
-};
-
-&main_uart0 {
-	status = "disabled";
+	status = "okay";
 };
-- 
2.25.1



From matthias.schiffer at ew.tq-group.com  Tue Jan 11 03:25:30 2022
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Tue, 11 Jan 2022 12:25:30 +0100
Subject: [PATCH 2/2] arm64: dts: ti: k3-am65*: remove
 #address-cells/#size-cells from flash nodes
In-Reply-To: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>
References: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <6e245e545a2927d2bd4bbc7df9197e6669ccce93.1641900122.git.matthias.schiffer@ew.tq-group.com>

Specifying partitions directly in the flash node is deprecated, a
fixed-partitions node should be used instead. Therefore, it doesn't make
sense to have these properties in the flash nodes.

Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
---
 arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi | 2 --
 arch/arm64/boot/dts/ti/k3-am654-base-board.dts     | 8 ++------
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
index 873c123c611e..7eca697e1ca1 100644
--- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
@@ -623,8 +623,6 @@ flash at 0 {
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <2>;
-		#address-cells = <1>;
-		#size-cells = <1>;
 	};
 };
 
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
index 821ee7f2eff0..9c06da9d6d8f 100644
--- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -340,14 +340,12 @@ &main_spi0 {
 	ti,pindir-d0-out-d1-in;
 	status = "okay";
 
-	flash at 0{
+	flash at 0 {
 		compatible = "jedec,spi-nor";
 		reg = <0x0>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 		spi-max-frequency = <48000000>;
-		#address-cells = <1>;
-		#size-cells= <1>;
 	};
 };
 
@@ -442,7 +440,7 @@ &ospi0 {
 	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
 	status = "okay";
 
-	flash at 0{
+	flash at 0 {
 		compatible = "jedec,spi-nor";
 		reg = <0x0>;
 		spi-tx-bus-width = <8>;
@@ -453,8 +451,6 @@ flash at 0{
 		cdns,tchsh-ns = <60>;
 		cdns,tslch-ns = <60>;
 		cdns,read-delay = <0>;
-		#address-cells = <1>;
-		#size-cells = <1>;
 	};
 };
 
-- 
2.25.1



From mark.rutland at arm.com  Tue Jan 11 03:30:18 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 11:30:18 +0000
Subject: [boot-wrapper PATCH v2 3/9] Makefile: Tell compiler to generate
 bare-metal code
In-Reply-To: <20220107143811.3d193704@donnerap.cambridge.arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-4-andre.przywara@arm.com>
 <YdhF7kluP5vwzDf4@FVFF77S0Q05N>
 <20220107143811.3d193704@donnerap.cambridge.arm.com>
Message-ID: <Yd1qSjmu61hXGZgd@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 02:38:11PM +0000, Andre Przywara wrote:
> On Fri, 7 Jan 2022 13:53:50 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > On Wed, Dec 22, 2021 at 06:16:01PM +0000, Andre Przywara wrote:
> > > Our GCC invocation does not provide many parameters, which lets the
> > > toolchain fill in its own default setup.
> > > In case of a native build or when using a full-featured cross-compiler,
> > > this probably means Linux userland, which is not what we want for a
> > > bare-metal application like boot-wrapper.
> > > 
> > > Tell the compiler to forget about those standard settings, and only use
> > > what we explicitly ask for. In particular that means to not use toolchain
> > > provided libraries and headers, since they might pull in more code than
> > > we want, and might not run well in the boot-wrapper environment.
> > > 
> > > This also enables optimisation, since it produces much better code and
> > > tends to avoid problems due to missing inlining, for instance.  
> > 
> > I'd appreciate if we could add some explanation for these (just in the commit
> > message is fine), as e.g. it's not clear to me why -fno-toplevel-reorder is
> > necessary.
> 
> Yeah, I was expecting some discussion about this. I went over most options
> from the manpage a while ago (for some unrelated baremetal code project),
> and decided for each option whether it would make sense or not. TBH I
> don't remember every detail from that, but I can certainly just drop the
> less critical options from that list.

Yes please.

To be clear, I'm only suggesting dropping a few of these, and I think the
others just needs some explanation.

I'm certain we *should* add:

	-ffreestanding
	-nostdlib

... and I'd be happy to take a patch adding just those as an immediate fix.

I think the folllowing are reasonable but need some explanation:

	-Wstrict-prototypes		// Just to catch accidents
	-fno-stack-protector		// Because we dont have any init/support code
	-fno-strict-aliasing		// Do we rely on type punning today?
	-fno-unwind-tables		// Because we don't consume the result
	-fno-asynchronous-unwind-tables	// Because we don't consume the result

I don't understand why we need:

	-fno-common
	-fno-toplevel-reorder
	-Os

... and I suspect we can drop those unless we have some rationale.

I'm torn over:

	-nostdinc

... as IIUC that's just to catch accidental includes, but necessitates the
prior patch adding copies of some headers. We could arguably leave that as-is
and just be careful.

> And I would be happy to add some rationale for each of them, but wonder
> what the best place would be? I'd rather do this in a file than in a
> commit message, would you prefer comments in Makefile.am, or in README or
> a separate file, with a pointer from Makefile.am. Or in a commit message
> anyway?

I think within the Makefile would be best if you're happy to organise it, e.g.

	# The boot-wrapper is a non-hosted environment and isn't linked
	# with standard libraries.
	CFLAGS += -ffreestanding -nostdlib

	# Avoid the pointless creation og a GOT
	CFLAGS += -fno-pic -fno-pie

... does that work for you?

Thanks,
Mark.

> 
> Cheers,
> Andre
> 
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > >  Makefile.am | 7 ++++++-
> > >  1 file changed, 6 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/Makefile.am b/Makefile.am
> > > index 3e970a3..d9ad6d1 100644
> > > --- a/Makefile.am
> > > +++ b/Makefile.am
> > > @@ -124,9 +124,14 @@ CHOSEN_NODE	:= chosen {						\
> > >  
> > >  CPPFLAGS	+= $(INITRD_FLAGS)
> > >  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
> > > -CFLAGS		+= -Wall -fomit-frame-pointer
> > > +CFLAGS		+= -Wall -Wstrict-prototypes -fomit-frame-pointer
> > > +CFLAGS		+= -ffreestanding -nostdinc -nostdlib
> > > +CFLAGS		+= -fno-common -fno-strict-aliasing -fno-stack-protector
> > > +CFLAGS		+= -fno-toplevel-reorder
> > > +CFLAGS		+= -fno-unwind-tables -fno-asynchronous-unwind-tables
> > >  CFLAGS		+= -ffunction-sections -fdata-sections
> > >  CFLAGS		+= -fno-pic -fno-pie
> > > +CFLAGS		+= -Os
> > >  LDFLAGS		+= --gc-sections
> > >  
> > >  OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> > > -- 
> > > 2.25.1
> > >   
> 


From nsaenzju at redhat.com  Tue Jan 11 03:32:38 2022
From: nsaenzju at redhat.com (Nicolas Saenz Julienne)
Date: Tue, 11 Jan 2022 12:32:38 +0100
Subject: Possible nohz-full/RCU issue in arm64 KVM
In-Reply-To: <YdR4N9QVYOzjowAb@FVFF77S0Q05N>
References: <d80e440375896f75d45e227d40af60ca7ba24ceb.camel@redhat.com>
 <YbyO40zDW/kvUHEE@FVFF77S0Q05N>
 <70f112072d9496d21901946ea82832d3ed3a8cb2.camel@redhat.com>
 <Ybyg1r/Q6EfeuXGV@FVFF77S0Q05N>
 <9ab8107f-ff41-6a9e-57e1-a261bea93aca@redhat.com>
 <YdR4N9QVYOzjowAb@FVFF77S0Q05N>
Message-ID: <399d8805ca09f7d3c905b8c653abf60dd7141574.camel@redhat.com>

Hi Mark,

On Tue, 2022-01-04 at 16:39 +0000, Mark Rutland wrote:
> On Fri, Dec 17, 2021 at 04:54:22PM +0100, Paolo Bonzini wrote:
> > On 12/17/21 15:38, Mark Rutland wrote:
> > > For example kvm_guest_enter_irqoff() calls guest_enter_irq_off() which calls
> > > vtime_account_guest_enter(), but kvm_guest_exit_irqoff() doesn't call
> > > guest_exit_irq_off() and the call to vtime_account_guest_exit() is open-coded
> > > elsewhere. Also, guest_enter_irq_off() conditionally calls
> > > rcu_virt_note_context_switch(), but I can't immediately spot anything on the
> > > exit side that corresponded with that, which looks suspicious.
> > 
> > rcu_note_context_switch() is a point-in-time notification; it's not strictly
> > necessary, but it may improve performance a bit by avoiding unnecessary IPIs
> > from the RCU subsystem.
> > 
> > There's no benefit from doing it when you're back from the guest, because at
> > that point the CPU is just running normal kernel code.
> 
> I see.
> 
> My main issue here was just that it's really difficult to see how the
> entry/exit logic is balanced, and I reckon we can solve that by splitting
> guest_{enter,exit}_irqoff() into helper functions to handle the vtime
> accounting separately from the context tracking, so that arch code can do
> something like:
> 
>   guest_timing_enter_irqoff();
>   
>   guest_eqs_enter_irqoff();
>   < actually run vCPU here >
>   guest_eqs_exit_irqoff();
>   
>   < handle pending IRQs here >
>   
>   guest_timing_exit_irqoff();
> 
> ... which I hope should work for RISC-V too.
> 
> I've had a go, and I've pushed out a WIP to:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/kvm/rcu

Had a look at the patches and they seeem OK to me.

Thanks!

-- 
Nicol?s S?enz



From mark.rutland at arm.com  Tue Jan 11 03:34:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 11:34:53 +0000
Subject: [boot-wrapper PATCH v2 2/9] Add standard headers
In-Reply-To: <20220107143128.53eb87b2@donnerap.cambridge.arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-3-andre.przywara@arm.com>
 <YdhE99enrMBNysxI@FVFF77S0Q05N>
 <20220107143128.53eb87b2@donnerap.cambridge.arm.com>
Message-ID: <Yd1rXXvt3u2mSFf8@FVFF77S0Q05N>

On Fri, Jan 07, 2022 at 02:31:28PM +0000, Andre Przywara wrote:
> On Fri, 7 Jan 2022 13:49:43 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> > On Wed, Dec 22, 2021 at 06:16:00PM +0000, Andre Przywara wrote:
> > > So far we were relying on some standard C headers to be provided by the
> > > toolchain. This applies for instance to stddef.h and stdint.h.
> > > As a "bare-metal" application, we should not rely on external headers,
> > > or even on a toolchain providing them in the first place.
> > > 
> > > Define our own version of stddef.h and stdint.h, containing just the
> > > types that we actually need.  
> > 
> > Even a freestanding compiler implementation is required to provide these
> > headers, and using the compiler versions would avoid unexpected mismatches
> > (e.g. for builtins). So I don't think the justification as written makes sense.
> > 
> > Is this because the next patch removes the stdinc paths, and so we don't get
> > the compiler's implementation of these headers?
> 
> Yes, exactly. I don't like repeating those either, and understand that
> even a minimal compiler carries these headers, *somewhere*, but I couldn't
> find an easy way of including them without being compiler/build specific.
> 
> I can try harder, and would be happy if someone points out the real
> solution to this.
> 
> For the sake of solving this problem I figured that those particular
> definitions are actually somewhat generic (for all practical purposes), so
> it was the least involved solution to the real problem, which is to ditch
> the *other* compiler headers and libraries, as done in patch 3/9.

FWIW, if we do need to use -nostdinc to drop other headers, I'm happy to take
something like this, but I think that should be an atomic change -- we should
add -nostdinc and the headers at the same time, and be explicit in the commit
message as to the rationale.

I'm just torn as to whether we actually need -nostdinc, as IIUC we don't
strictly need to drop that for freestanding code, and IIRC we haven't had any
mistakes so far that stemmed from including headers that weren't suitable for
freestanding code.

So I'm tempted to say keep the standard includes for now.

Thanks,
Mark.

> 
> Cheers,
> Andre
> 
> > > 
> > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > ---
> > >  arch/aarch32/include/stdint.h | 19 +++++++++++++++++++
> > >  arch/aarch64/include/stdint.h | 19 +++++++++++++++++++
> > >  include/stddef.h              | 15 +++++++++++++++
> > >  3 files changed, 53 insertions(+)
> > >  create mode 100644 arch/aarch32/include/stdint.h
> > >  create mode 100644 arch/aarch64/include/stdint.h
> > >  create mode 100644 include/stddef.h
> > > 
> > > diff --git a/arch/aarch32/include/stdint.h b/arch/aarch32/include/stdint.h
> > > new file mode 100644
> > > index 0000000..77546f0
> > > --- /dev/null
> > > +++ b/arch/aarch32/include/stdint.h
> > > @@ -0,0 +1,19 @@
> > > +/*
> > > + * arch/aarch32/include/stdint.h
> > > + *
> > > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > > + *
> > > + * Use of this source code is governed by a BSD-style license that can be
> > > + * found in the LICENSE.txt file.
> > > + */
> > > +#ifndef STDINT_H__
> > > +#define STDINT_H__
> > > +
> > > +typedef unsigned char		uint8_t;
> > > +typedef unsigned short int	uint16_t;
> > > +typedef unsigned int		uint32_t;
> > > +typedef unsigned long long int	uint64_t;
> > > +
> > > +typedef unsigned int		uintptr_t;
> > > +
> > > +#endif
> > > diff --git a/arch/aarch64/include/stdint.h b/arch/aarch64/include/stdint.h
> > > new file mode 100644
> > > index 0000000..92c2603
> > > --- /dev/null
> > > +++ b/arch/aarch64/include/stdint.h
> > > @@ -0,0 +1,19 @@
> > > +/*
> > > + * arch/aarch64/include/stdint.h
> > > + *
> > > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > > + *
> > > + * Use of this source code is governed by a BSD-style license that can be
> > > + * found in the LICENSE.txt file.
> > > + */
> > > +#ifndef STDINT_H__
> > > +#define STDINT_H__
> > > +
> > > +typedef unsigned char		uint8_t;
> > > +typedef unsigned short int	uint16_t;
> > > +typedef unsigned int		uint32_t;
> > > +typedef unsigned long int	uint64_t;
> > > +
> > > +typedef unsigned long int	uintptr_t;
> > > +
> > > +#endif
> > > diff --git a/include/stddef.h b/include/stddef.h
> > > new file mode 100644
> > > index 0000000..3208b10
> > > --- /dev/null
> > > +++ b/include/stddef.h
> > > @@ -0,0 +1,15 @@
> > > +/*
> > > + * include/stddef.h - standard data type definitions
> > > + *
> > > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > > + *
> > > + * Use of this source code is governed by a BSD-style license that can be
> > > + * found in the LICENSE.txt file.
> > > + */
> > > +#ifndef STDDEF_H__
> > > +#define STDDEF_H__
> > > +
> > > +typedef unsigned long int	size_t;
> > > +typedef signed long int		ssize_t;
> > > +
> > > +#endif
> > > -- 
> > > 2.25.1
> > >   
> 


From andriy.shevchenko at linux.intel.com  Tue Jan 11 03:46:47 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Tue, 11 Jan 2022 13:46:47 +0200
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <20220111014046.5864-4-axe.yang@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
Message-ID: <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>

On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:
> Add support for eint irq when MSDC is used as an SDIO host. This

IRQ

> feature requires SDIO device support async irq function. With this

IRQ

> feature,SDIO host can be awakened by SDIO card in suspend state,

feature, SDIO

> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in msdc node

MSDC

> to support SDIO eint irq. Pinctrls named state_dat1 and state_eint

IRQ

> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>         &mmcX {
>                 ...
>                 pinctrl-names = "default", "state_uhs", "state_eint",
>                                 "state_dat1";
>                 ...
>                 pinctrl-2 = <&mmc2_pins_eint>;
>                 pinctrl-3 = <&mmc2_pins_dat1>;
>                 ...
>                 cap-sdio-async-irq;
>                 ...
>         };

...

> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2014-2022 MediaTek Inc.

Shouldn't it be rather like

 * Copyright (c) 2014-2015,2022 MediaTek Inc.

?

...

> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +	unsigned long flags;
> +	struct msdc_host *host = (struct msdc_host *)dev_id;

No casting is needed.

> +	struct mmc_host *mmc = mmc_from_priv(host);

Perhaps reversed xmas tree order

	struct msdc_host *host = dev_id;
	struct mmc_host *mmc = mmc_from_priv(host);
	unsigned long flags;

?

But hey, why do you need flags?

> +	spin_lock_irqsave(&host->lock, flags);
> +	if (likely(host->sdio_irq_cnt > 0)) {
> +		disable_irq_nosync(host->eint_irq);
> +		disable_irq_wake(host->eint_irq);
> +		host->sdio_irq_cnt--;
> +	}
> +	spin_unlock_irqrestore(&host->lock, flags);
> +
> +	sdio_signal_irq(mmc);
> +
> +	return IRQ_HANDLED;
> +}

...

> +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> +{
> +	struct gpio_desc *desc;
> +	int irq, ret;
> +
> +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
> +
> +	ret = gpiod_to_irq(desc);
> +	if (ret < 0)
> +		return ret;
> +
> +	irq = ret;
> +	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +					"sdio-eint", host);

> +

Redundant blank line.

> +	if (!ret)
> +		host->eint_irq = irq;
> +
> +	return ret;

I guess I have already commented on this, i.e. use standard pattern

	if (ret)
		return ret;

	...
	return 0;

> +}

...

> +		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
> +		if (IS_ERR(host->pins_eint)) {

> +			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");

In debug mode of pin control this will bring a duplicate message.

> +		} else {
> +			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
> +			if (IS_ERR(host->pins_dat1)) {
> +				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
> +						    "Cannot find pinctrl dat1!\n");
> +				goto host_free;
> +			}
> +
> +			host->sdio_eint_ready = true;
> +		}
> +	}


-- 
With Best Regards,
Andy Shevchenko




From ross.burton at arm.com  Tue Jan 11 04:00:12 2022
From: ross.burton at arm.com (Ross Burton)
Date: Tue, 11 Jan 2022 12:00:12 +0000
Subject: [PATCH 1/3] arm64: defconfig: drop unused POWER_AVS option
Message-ID: <20220111120014.2154585-1-ross.burton@arm.com>

Commit 785b5bb41b0a ("PM: AVS: Drop the avs directory and the
corresponding Kconfig") moved AVS code to SOC-specific folders, and
removed corresponding Kconfig from drivers/power, leaving original
POWER_AVS config option enabled in some defconfigs.

Remove the options, which have no references in the tree anymore.

Fixes: 785b5bb41b0a ("PM: AVS: Drop the avs directory and the corresponding Kconfig")

Signed-off-by: Ross Burton <ross.burton at arm.com>
---
 arch/arm64/configs/defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..da1e14d54c25 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -544,7 +544,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
-CONFIG_POWER_AVS=y
 CONFIG_QCOM_CPR=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_POWER_RESET_MSM=y
-- 
2.25.1



From ross.burton at arm.com  Tue Jan 11 04:00:13 2022
From: ross.burton at arm.com (Ross Burton)
Date: Tue, 11 Jan 2022 12:00:13 +0000
Subject: [PATCH 2/3] arm64: defconfig: set CONFIG_USB_CONN_GPIO=y
In-Reply-To: <20220111120014.2154585-1-ross.burton@arm.com>
References: <20220111120014.2154585-1-ross.burton@arm.com>
Message-ID: <20220111120014.2154585-2-ross.burton@arm.com>

Since 10a7b37b5b ("arm64: Update default configuration") PHY_TEGRA_XUSB
is set to y. That option needs USB_CONN_GPIO to also be y not m, so
set USB_CONN_GPIO explicitly to y to reflect reality.

Signed-off-by: Ross Burton <ross.burton at arm.com>
---
 arch/arm64/configs/defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index da1e14d54c25..3e8756ec30d0 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -811,7 +811,7 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_HID_MULTITOUCH=m
 CONFIG_I2C_HID_ACPI=m
 CONFIG_I2C_HID_OF=m
-CONFIG_USB_CONN_GPIO=m
+CONFIG_USB_CONN_GPIO=y
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
-- 
2.25.1



From ross.burton at arm.com  Tue Jan 11 04:00:14 2022
From: ross.burton at arm.com (Ross Burton)
Date: Tue, 11 Jan 2022 12:00:14 +0000
Subject: [PATCH 3/3] arm64: defconfig: don't set CONFIG_ACPI_APEI_PCIEAER
In-Reply-To: <20220111120014.2154585-1-ross.burton@arm.com>
References: <20220111120014.2154585-1-ross.burton@arm.com>
Message-ID: <20220111120014.2154585-3-ross.burton@arm.com>

Since 8c8ff55 ("PCI/AER: Don't select CONFIG_PCIEAER by default"), PCIe
Advanced Error Reporting isn't enabled by default.. As this means just
enabling CONFIG_CPI_APEI_PCIEAR does not have an effect, remove it from
the defconfig for clarity.

Signed-off-by: Ross Burton <ross.burton at arm.com>
---
 arch/arm64/configs/defconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3e8756ec30d0..fb457dc38882 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -109,7 +109,6 @@ CONFIG_IMX_SCU_PD=y
 CONFIG_ACPI=y
 CONFIG_ACPI_APEI=y
 CONFIG_ACPI_APEI_GHES=y
-CONFIG_ACPI_APEI_PCIEAER=y
 CONFIG_ACPI_APEI_MEMORY_FAILURE=y
 CONFIG_ACPI_APEI_EINJ=y
 CONFIG_VIRTUALIZATION=y
-- 
2.25.1



From noralf at tronnes.org  Tue Jan 11 04:02:50 2022
From: noralf at tronnes.org (=?UTF-8?Q?Noralf_Tr=c3=b8nnes?=)
Date: Tue, 11 Jan 2022 13:02:50 +0100
Subject: [PATCH v2 1/2] drm/mipi-dbi: Remove dependency on GEM CMA helper
 library
In-Reply-To: <20211106193509.17472-2-tzimmermann@suse.de>
References: <20211106193509.17472-2-tzimmermann@suse.de>
Message-ID: <a9e2d66e-1a85-b61f-ee3b-ca7032e0516f@tronnes.org>

> The MIPI DBI helpers access struct drm_gem_cma_object.vaddr in a
> few places. Replace all instances with the correct generic GEM
> functions. Use drm_gem_fb_vmap() for mapping a framebuffer's GEM
> objects and drm_gem_fb_vunmap() for unmapping them. This removes
> the dependency on CMA helpers within MIPI DBI.
>
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> Reviewed-by: Daniel Vetter <daniel.vetter at ffwll.ch>
> ---
>  drivers/gpu/drm/drm_mipi_dbi.c | 34 +++++++++++++++++++++++++---------
>  1 file changed, 25 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_mipi_dbi.c
b/drivers/gpu/drm/drm_mipi_dbi.c
> index 71b646c4131f..f80fd6c0ccf8 100644
> --- a/drivers/gpu/drm/drm_mipi_dbi.c
> +++ b/drivers/gpu/drm/drm_mipi_dbi.c
> @@ -15,9 +15,10 @@
>  #include <drm/drm_connector.h>
>  #include <drm/drm_damage_helper.h>
>  #include <drm/drm_drv.h>
> -#include <drm/drm_gem_cma_helper.h>
> +#include <drm/drm_file.h>
>  #include <drm/drm_format_helper.h>
>  #include <drm/drm_fourcc.h>
> +#include <drm/drm_gem.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  #include <drm/drm_mipi_dbi.h>
>  #include <drm/drm_modes.h>
> @@ -200,13 +201,19 @@ int mipi_dbi_buf_copy(void *dst, struct
drm_framebuffer *fb,
>  		      struct drm_rect *clip, bool swap)
>  {
>  	struct drm_gem_object *gem = drm_gem_fb_get_obj(fb, 0);
> -	struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem);
> -	void *src = cma_obj->vaddr;
> +	struct dma_buf_map map[DRM_FORMAT_MAX_PLANES];
> +	struct dma_buf_map data[DRM_FORMAT_MAX_PLANES];
> +	void *src;
>  	int ret;
>
>  	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
>  	if (ret)
>  		return ret;
> +	src = data[0].vaddr; /* TODO: Use mapping abstraction properly */

This assignment should be after the _vmap() call. The MIPI DBI drivers
are currently broken because of this.

Noralf.

> +
> +	ret = drm_gem_fb_vmap(fb, map, data);
> +	if (ret)
> +		goto out_drm_gem_fb_end_cpu_access;
>
>  	switch (fb->format->format) {
>  	case DRM_FORMAT_RGB565:
> @@ -221,9 +228,11 @@ int mipi_dbi_buf_copy(void *dst, struct
drm_framebuffer *fb,
>  	default:
>  		drm_err_once(fb->dev, "Format is not supported: %p4cc\n",
>  			     &fb->format->format);
> -		return -EINVAL;
> +		ret = -EINVAL;
>  	}
>
> +	drm_gem_fb_vunmap(fb, map);
> +out_drm_gem_fb_end_cpu_access:
>  	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
>
>  	return ret;
>


From mhocko at suse.com  Tue Jan 11 04:15:50 2022
From: mhocko at suse.com (Michal Hocko)
Date: Tue, 11 Jan 2022 13:15:50 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <1641900108.61dd684cb0e59@mail.inbox.lv>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz> <YdjOazilBEkdUT7x@google.com>
 <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>
 <1641900108.61dd684cb0e59@mail.inbox.lv>
Message-ID: <Yd109jeRllJbjV9o@dhcp22.suse.cz>

On Tue 11-01-22 11:21:48, Alexey Avramov wrote:
> > I do not really see any arguments why an userspace based trashing
> > detection cannot be used for those.
> 
> Firsly,
> because this is the task of the kernel, not the user space.
> Memory is managed by the kernel, not by the user space.
> The absence of such a mechanism in the kernel is a fundamental problem.
> The userspace tools are ugly hacks:
> some of them consume a lot of CPU [1],
> some of them consume a lot of memory [2],
> some of them cannot into process_mrelease() (earlyoom, nohang),
> some of them kill only the whole cgroup (systemd-oomd, oomd) [3]
> and depends on systemd and cgroup_v2 (oomd, systemd-oomd).

Thanks for those links. Read through them and my understanding is that
most of those are very specific to the tool used and nothing really
fundamental because of lack of kernel support.

> One of the biggest challenges for userspace oom-killers is to potentially
> function under intense memory pressure and are prone to getting stuck in
> memory reclaim themselves [4].

This one is more interesting and the truth is that handling the complete
OOM situation from the userspace is really tricky. Especially when with
a more complex oom decision policy. In the past we have discussed
potential ways to implement a oom kill policy be kernel modules or eBPF.
Without anybody following up on that.

But I suspect you are mixing up two things here. One of them is out
of memory situation where no memory can be reclaimed and allocated.

The other is one where the memory can be reclaimed, a progress is made,
but that leads to a trashing when the most of the time is spent on
refaulting a memory reclaimed shortly before.

The first one is addressed by the global oom killer and it tries to
be really conservative as much as possible because this is a very
disruptive operation. But the later one is more complex and a proper
handling really depends on the particular workload to be handled
properly because it is more of a QoS than an emergency action to keep
the system alive.

There are workloads which prefer a temporary trashing over its working
set during a peak memory demand rather than an OOM kill because way too
much work would be thrown away. On the other side workloads that are
latency sensitive can see even the direct reclaim as a runtime visible
problem.

I hope you can imagine there is a really large gap between those
two cases and no simple solution can be applied to the whole
range. Therefore we have PSI and refault stats exported to the userspace
so that a workload specific policy can be implemented there.

If userspace has hard time to use that data and action upon then let's
talk about specifics. For the most steady trashing situations I have
seen the userspace with mlocked memory and the code can make a forward
progress and mediate the situation.

[...]

> [1] https://github.com/facebookincubator/oomd/issues/79
> [2] https://github.com/hakavlad/nohang#memory-and-cpu-usage
> [3] https://github.com/facebookincubator/oomd/issues/125
> [4] https://lore.kernel.org/all/CALvZod7vtDxJZtNhn81V=oE-EPOf=4KZB2Bv6Giz+u3bFFyOLg at mail.gmail.com/
> [5] https://github.com/zen-kernel/zen-kernel/issues/223
> [6] https://raw.githubusercontent.com/hakavlad/cache-tests/main/mg-LRU-v3_vs_classic-LRU/3-firefox-tail-OOM/mg-LRU-1/psi2
> [7] https://lore.kernel.org/linux-mm/20211202150614.22440-1-mgorman at techsingularity.net/
-- 
Michal Hocko
SUSE Labs


From mark.rutland at arm.com  Tue Jan 11 04:23:10 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 12:23:10 +0000
Subject: Possible nohz-full/RCU issue in arm64 KVM
In-Reply-To: <399d8805ca09f7d3c905b8c653abf60dd7141574.camel@redhat.com>
References: <d80e440375896f75d45e227d40af60ca7ba24ceb.camel@redhat.com>
 <YbyO40zDW/kvUHEE@FVFF77S0Q05N>
 <70f112072d9496d21901946ea82832d3ed3a8cb2.camel@redhat.com>
 <Ybyg1r/Q6EfeuXGV@FVFF77S0Q05N>
 <9ab8107f-ff41-6a9e-57e1-a261bea93aca@redhat.com>
 <YdR4N9QVYOzjowAb@FVFF77S0Q05N>
 <399d8805ca09f7d3c905b8c653abf60dd7141574.camel@redhat.com>
Message-ID: <Yd12rvDxyIWzEXWc@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 12:32:38PM +0100, Nicolas Saenz Julienne wrote:
> Hi Mark,
> 
> On Tue, 2022-01-04 at 16:39 +0000, Mark Rutland wrote:
> > On Fri, Dec 17, 2021 at 04:54:22PM +0100, Paolo Bonzini wrote:
> > > On 12/17/21 15:38, Mark Rutland wrote:
> > > > For example kvm_guest_enter_irqoff() calls guest_enter_irq_off() which calls
> > > > vtime_account_guest_enter(), but kvm_guest_exit_irqoff() doesn't call
> > > > guest_exit_irq_off() and the call to vtime_account_guest_exit() is open-coded
> > > > elsewhere. Also, guest_enter_irq_off() conditionally calls
> > > > rcu_virt_note_context_switch(), but I can't immediately spot anything on the
> > > > exit side that corresponded with that, which looks suspicious.
> > > 
> > > rcu_note_context_switch() is a point-in-time notification; it's not strictly
> > > necessary, but it may improve performance a bit by avoiding unnecessary IPIs
> > > from the RCU subsystem.
> > > 
> > > There's no benefit from doing it when you're back from the guest, because at
> > > that point the CPU is just running normal kernel code.
> > 
> > I see.
> > 
> > My main issue here was just that it's really difficult to see how the
> > entry/exit logic is balanced, and I reckon we can solve that by splitting
> > guest_{enter,exit}_irqoff() into helper functions to handle the vtime
> > accounting separately from the context tracking, so that arch code can do
> > something like:
> > 
> >   guest_timing_enter_irqoff();
> >   
> >   guest_eqs_enter_irqoff();
> >   < actually run vCPU here >
> >   guest_eqs_exit_irqoff();
> >   
> >   < handle pending IRQs here >
> >   
> >   guest_timing_exit_irqoff();
> > 
> > ... which I hope should work for RISC-V too.
> > 
> > I've had a go, and I've pushed out a WIP to:
> > 
> >   https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=arm64/kvm/rcu
> 
> Had a look at the patches and they seeem OK to me.
> 
> Thanks!

Cool.

FWIW I have an updated version at:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=kvm/entry-rework

... which is largely the same approach, but the helpers got renamed, the
lockdep/tracing bits got fixed, and I've aligned mips, riscv, and x86 on the
same approach.

Once I get a free hour or so I intend to rebase that atop v5.16 and post that
out. I'll start a new thread with that, and rope in the relevant arch
maintainers (since e.g. I'm not sure what to do for ppc and s390).

Thanks,
Mark.

> 
> -- 
> Nicol?s S?enz
> 


From tudor.ambarus at microchip.com  Tue Jan 11 04:53:10 2022
From: tudor.ambarus at microchip.com (Tudor Ambarus)
Date: Tue, 11 Jan 2022 14:53:10 +0200
Subject: [PATCH] clk: at91: sama7g5: Allow MCK1 to be exported and referenced
 in DT
Message-ID: <20220111125310.902856-1-tudor.ambarus@microchip.com>

MCK1 feeds the External Bus Interface (EBI). EBI's clock rate is used
to translate EBI's timmings to SMC timings, thus we need to handle MCK1
in the EBI driver. Allow MCK1 to be referenced as a PMC_TYPE_CORE clock
from phandle in DT.

Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
---
 drivers/clk/at91/sama7g5.c       | 8 +++++++-
 include/dt-bindings/clock/at91.h | 1 +
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
index 369dfafabbca..e43458673afb 100644
--- a/drivers/clk/at91/sama7g5.c
+++ b/drivers/clk/at91/sama7g5.c
@@ -302,6 +302,7 @@ static const struct {
  * @ep_count:		extra parents count
  * @ep_mux_table:	mux table for extra parents
  * @id:			clock id
+ * @eid:		export index in sama7g5->chws[] array
  * @c:			true if clock is critical and cannot be disabled
  */
 static const struct {
@@ -311,6 +312,7 @@ static const struct {
 	u8 ep_count;
 	u8 ep_mux_table[4];
 	u8 id;
+	u8 eid;
 	u8 c;
 } sama7g5_mckx[] = {
 	{ .n = "mck1",
@@ -319,6 +321,7 @@ static const struct {
 	  .ep_mux_table = { 5, },
 	  .ep_count = 1,
 	  .ep_chg_id = INT_MIN,
+	  .eid = PMC_MCK1,
 	  .c = 1, },
 
 	{ .n = "mck2",
@@ -913,7 +916,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
 	if (IS_ERR(regmap))
 		return;
 
-	sama7g5_pmc = pmc_data_allocate(PMC_CPU + 1,
+	sama7g5_pmc = pmc_data_allocate(PMC_MCK1 + 1,
 					nck(sama7g5_systemck),
 					nck(sama7g5_periphck),
 					nck(sama7g5_gck), 8);
@@ -1027,6 +1030,9 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
 			goto err_free;
 
 		alloc_mem[alloc_mem_size++] = mux_table;
+
+		if (sama7g5_mckx[i].eid)
+			sama7g5_pmc->chws[sama7g5_mckx[i].eid] = hw;
 	}
 
 	hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal");
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 98e1b2ab6403..8498c0cd95fe 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -35,6 +35,7 @@
 #define PMC_AUDIOIOPLL		(PMC_MAIN + 7)
 #define PMC_ETHPLL		(PMC_MAIN + 8)
 #define PMC_CPU			(PMC_MAIN + 9)
+#define PMC_MCK1		(PMC_MAIN + 10)
 
 #ifndef AT91_PMC_MOSCS
 #define AT91_PMC_MOSCS		0		/* MOSCS Flag */
-- 
2.25.1



From maxime at cerno.tech  Tue Jan 11 04:54:56 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 11 Jan 2022 13:54:56 +0100
Subject: [PATCH RESEND v4 v5 0/4] drm/vc4: Use the firmware to stop the
 display pipeline
In-Reply-To: <20211215095117.176435-1-maxime@cerno.tech>
References: <20211215095117.176435-1-maxime@cerno.tech>
Message-ID: <164190568949.817599.3855426533627905672.b4-ty@cerno.tech>

On Wed, 15 Dec 2021 10:51:13 +0100, Maxime Ripard wrote:
> The VC4 driver has had limited support to disable the HDMI controllers and
> pixelvalves at boot if the firmware has enabled them.
> 
> However, this proved to be limited, and a bit unreliable so a new firmware
> command has been introduced some time ago to make it free all its resources and
> disable any display output it might have enabled.
> 
> [...]

Applied to drm/drm-misc (drm-misc-next).

Thanks!
Maxime


From tudor.ambarus at microchip.com  Tue Jan 11 04:56:41 2022
From: tudor.ambarus at microchip.com (Tudor Ambarus)
Date: Tue, 11 Jan 2022 14:56:41 +0200
Subject: [PATCH] ARM: configs: at91: sama7: Enable NAND / SMC
Message-ID: <20220111125641.903624-1-tudor.ambarus@microchip.com>

Enable the Static Memory Controller. Tested with Micron MT29F4G08ABAEAWP
NAND flash. Software error correction is not needed, as the SMC includes
a PMECC error correction hardware module.

Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
---
 arch/arm/configs/sama7_defconfig | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 0368068e04d9..342d9f30d9d2 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -82,6 +82,9 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_MTD=y
 CONFIG_MTD_TESTS=m
 CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+# CONFIG_MTD_NAND_ECC_SW_HAMMING is not set
 CONFIG_MTD_SPI_NOR=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
@@ -174,7 +177,6 @@ CONFIG_DMATEST=y
 CONFIG_STAGING=y
 CONFIG_MICROCHIP_PIT64B=y
 # CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_ATMEL_EBI is not set
 CONFIG_IIO=y
 CONFIG_IIO_SW_TRIGGER=y
 CONFIG_AT91_SAMA5D2_ADC=y
-- 
2.25.1



From maxime at cerno.tech  Tue Jan 11 05:01:44 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Tue, 11 Jan 2022 14:01:44 +0100
Subject: [PATCH RESEND v4 v5 4/4] drm/vc4: Notify the firmware when DRM
 is in charge
In-Reply-To: <1a42431d-59bc-53e0-199b-815c96f97a29@suse.de>
References: <20211215095117.176435-1-maxime@cerno.tech>
 <20211215095117.176435-5-maxime@cerno.tech>
 <1a42431d-59bc-53e0-199b-815c96f97a29@suse.de>
Message-ID: <20220111130144.y2fs74tkpe7ecada@houat>

Hi Thomas,

On Tue, Jan 11, 2022 at 10:38:36AM +0100, Thomas Zimmermann wrote:
> Hi
> 
> Am 15.12.21 um 10:51 schrieb Maxime Ripard:
> > Once the call to drm_fb_helper_remove_conflicting_framebuffers() has
> > been made, simplefb has been unregistered and the KMS driver is entirely
> > in charge of the display.
> > 
> > Thus, we can notify the firmware it can free whatever resource it was
> > using to maintain simplefb functional.
> > 
> > Signed-off-by: Maxime Ripard <maxime at cerno.tech>
> > ---
> >   drivers/gpu/drm/vc4/vc4_drv.c | 22 ++++++++++++++++++++++
> >   1 file changed, 22 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> > index 86c61ee120b7..a03053c8e22c 100644
> > --- a/drivers/gpu/drm/vc4/vc4_drv.c
> > +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> > @@ -37,6 +37,8 @@
> >   #include <drm/drm_fb_helper.h>
> >   #include <drm/drm_vblank.h>
> > +#include <soc/bcm2835/raspberrypi-firmware.h>
> > +
> >   #include "uapi/drm/vc4_drm.h"
> >   #include "vc4_drv.h"
> > @@ -215,6 +217,7 @@ static void vc4_match_add_drivers(struct device *dev,
> >   static int vc4_drm_bind(struct device *dev)
> >   {
> >   	struct platform_device *pdev = to_platform_device(dev);
> > +	struct rpi_firmware *firmware = NULL;
> >   	struct drm_device *drm;
> >   	struct vc4_dev *vc4;
> >   	struct device_node *node;
> > @@ -251,10 +254,29 @@ static int vc4_drm_bind(struct device *dev)
> >   	if (ret)
> >   		return ret;
> > +	node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware");
> > +	if (node) {
> > +		firmware = rpi_firmware_get(node);
> > +		of_node_put(node);
> > +
> > +		if (!firmware)
> > +			return -EPROBE_DEFER;
> > +	}
> > +
> 
> The code is
> 
> Acked-by: Thomas Zimmermann <tzimmermann at suse.de>

Thanks for your review

> Just for my understanding:
> 
> You retrieve the firmware before killing simpledrm simply to keep the
> display on if it fails, right?

Exactly

> What's the possible error that would justify a retry (via EPROBE_DEFER)?

The firmware there is backed by a driver that might not have probed yet,
in which case we just want to retry later on

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/b6c06932/attachment-0001.sig>

From tudor.ambarus at microchip.com  Tue Jan 11 05:05:56 2022
From: tudor.ambarus at microchip.com (Tudor Ambarus)
Date: Tue, 11 Jan 2022 15:05:56 +0200
Subject: [PATCH] ARM: dts: at91: sama7g5: Add NAND support
Message-ID: <20220111130556.905978-1-tudor.ambarus@microchip.com>

Add NAND support. The sama7g5's SMC IP is the same as sama5d2's with
a slightly change: it provides a synchronous clock output (SMC clock)
that is dedicated to FPGA usage. Since this doesn't interfere with the SMC
NAND configuration, thus code will not be added in the current nand driver
to address the FPGA usage, use the sama5d2's compatible and choose not to
introduce dedicated compatibles for sama7g5.
Tested with Micron MT29F4G08ABAEAWP NAND flash.

Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
---
The patch depends on the following patch:
https://lore.kernel.org/linux-clk/20220111125310.902856-1-tudor.ambarus at microchip.com/T/#u

 arch/arm/boot/dts/sama7g5.dtsi | 55 ++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index eddcfbf4d223..7972cb8c2562 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -75,6 +75,45 @@ soc {
 		#size-cells = <1>;
 		ranges;
 
+		nfc_sram: sram at 600000 {
+			compatible = "mmio-sram";
+			no-memory-wc;
+			reg = <0x00600000 0x2400>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x00600000 0x2400>;
+		};
+
+		nfc_io: nfc-io at 10000000 {
+			compatible = "atmel,sama5d3-nfc-io", "syscon";
+			reg = <0x10000000 0x8000000>;
+		};
+
+		ebi: ebi at 40000000 {
+			compatible = "atmel,sama5d3-ebi";
+			#address-cells = <2>;
+			#size-cells = <1>;
+			atmel,smc = <&hsmc>;
+			reg = <0x40000000 0x20000000>;
+			ranges = <0x0 0x0 0x40000000 0x8000000
+				  0x1 0x0 0x48000000 0x8000000
+				  0x2 0x0 0x50000000 0x8000000
+				  0x3 0x0 0x58000000 0x8000000>;
+			clocks = <&pmc PMC_TYPE_CORE PMC_MCK1>;
+			status = "disabled";
+
+			nand_controller: nand-controller {
+				compatible = "atmel,sama5d3-nand-controller";
+				atmel,nfc-sram = <&nfc_sram>;
+				atmel,nfc-io = <&nfc_io>;
+				ecc-engine = <&pmecc>;
+				#address-cells = <2>;
+				#size-cells = <1>;
+				ranges;
+				status = "disabled";
+			};
+		};
+
 		securam: securam at e0000000 {
 			compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram";
 			reg = <0xe0000000 0x4000>;
@@ -181,6 +220,22 @@ tcb1: timer at e0800000 {
 			clock-names = "t0_clk", "t1_clk", "t2_clk", "slow_clk";
 		};
 
+		hsmc: hsmc at e0808000 {
+			compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd";
+			reg = <0xe0808000 0x1000>;
+			interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 21>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges;
+
+			pmecc: ecc-engine at e0808070 {
+				compatible = "atmel,sama5d2-pmecc";
+				reg = <0xe0808070 0x490>,
+				      <0xe0808500 0x200>;
+			};
+		};
+
 		qspi0: spi at e080c000 {
 			compatible = "microchip,sama7g5-ospi";
 			reg = <0xe080c000 0x400>, <0x20000000 0x10000000>;
-- 
2.25.1



From mark.rutland at arm.com  Tue Jan 11 05:06:40 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:40 +0000
Subject: [bootwrapper PATCH 00/13] Cleanups and improvements
Message-ID: <20220111130653.2331827-1-mark.rutland@arm.com>

This series reworks the aarch64 boot-wrapper, moving a fair amount of
initialization code to C. This has a few benefits:

1) This makes the code more legible and easier to maintain.

    Current feature detection and system register configuration is
    written in assembly, requiring runs of *almost* identical blocks of
    assembly to read ID registers and conditionally initialize register
    values. This requires a bunch of labels (which are all named
    numerically), and all the magic numbers are hard coded, so this gets
    pretty painful to read:
    
    |	mrs	x1, id_aa64isar0_el1
    |	ubfx	x1, x1, #24, #4
    |	cbz	x1, 1f
    |
    |	orr	x0, x0, #(1 << 34)		// TME enable
    |
    | 1:
    
    In C, it's much easier to add helpers which use mnemonics, which
    makes the code much easier to read, and avoids the need to manually
    allocate registers, etc:
    
    |	if (mrs_field(ID_AA64ISAR0_EL1, TME))
    |		scr |= SCR_EL3_TME;

    This should make it easier to handle new architectural extensions
    (and/or architecture variants such as ARMv8-R) in future.
    
2) This allows for better diagnostics.

    Currently a mis-configured boot-wrapper is rather unforgiving, and
    provides no indication as to what might have gone wrong. By moving
    initialization to C, we can make use to the UART code to log
    diagnostic information, and we can more easily add additional error
    handling and conditional logic.
    
    This series adds diagnostic information and error handling that can
    be used to identify problems such as the boot-wrapper being launched
    at the wrong exception level:
    
    | Boot-wrapper v0.2
    | Entered at EL2
    | Memory layout:
    | [0000000080000000..0000000080001f90] => boot-wrapper
    | [000000008000fff8..0000000080010000] => mbox
    | [0000000080200000..00000000822af200] => kernel
    | [0000000088000000..0000000088002857] => dtb
    |
    | WARNING: PSCI could not be initialized. Boot may fail

Originally I had planned for this to be a more expansive set of changes,
unifying some early control-flow, fixing some latent bugs, and making
the boot-wrapper dynamically handle being entered at any of EL{3,2,1}
with automated selection of a suitable DT. As the series has already
become pretty long, I'd like to get this preparatory cleanup out of the
way first, and handle those cases with subsequent patches.

If there are no objections in the next few days, I intend to apply these
patches by the end of the week. If people can provide Reviewed-by and
Tested-by tags, I'd be happy to apply this earlier.

I've pushed the series to the `cleanup` branch in the boot-wrapper repo:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git/
  git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

... and it should apply cleanup atop the `master` branch.

Thanks,
Mark.

Mark Rutland (13):
  Document entry requirements
  Add bit-field macros
  aarch64: add system register accessors
  aarch32: add coprocessor accessors
  aarch64: add mov_64 macro
  aarch64: initialize SCTLR_ELx for the boot-wrapper
  Rework common init C code
  Announce boot-wrapper mode / exception level
  aarch64: move the bulk of EL3 initialization to C
  aarch32: move the bulk of Secure PL1 initialization to C
  Announce locations of memory objects
  Rework bootmethod initialization
  Unify start_el3 & start_no_el3

 Makefile.am                       |   6 +-
 arch/aarch32/boot.S               |  33 +++---
 arch/aarch32/include/asm/cpu.h    |  62 ++++++++---
 arch/aarch32/include/asm/gic-v3.h |   6 +-
 arch/aarch32/include/asm/psci.h   |  28 +++++
 arch/aarch32/init.c               |  42 ++++++++
 arch/aarch32/psci.S               |  13 +--
 arch/aarch32/utils.S              |   9 --
 arch/aarch64/boot.S               | 169 +++++++++++++-----------------
 arch/aarch64/common.S             |  10 +-
 arch/aarch64/include/asm/cpu.h    | 102 +++++++++++++++---
 arch/aarch64/include/asm/gic-v3.h |  10 +-
 arch/aarch64/include/asm/psci.h   |  28 +++++
 arch/aarch64/init.c               |  88 ++++++++++++++++
 arch/aarch64/psci.S               |  22 +---
 arch/aarch64/spin.S               |   3 +
 arch/aarch64/utils.S              |   9 --
 common/boot.c                     |   4 -
 common/init.c                     |  60 +++++++++++
 common/platform.c                 |  46 +++++---
 common/psci.c                     |  22 +++-
 include/bits.h                    |  33 ++++++
 include/boot.h                    |   2 +
 include/platform.h                |  20 ++++
 model.lds.S                       |  20 ++--
 25 files changed, 621 insertions(+), 226 deletions(-)
 create mode 100644 arch/aarch32/include/asm/psci.h
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/include/asm/psci.h
 create mode 100644 arch/aarch64/init.c
 create mode 100644 common/init.c
 create mode 100644 include/bits.h
 create mode 100644 include/platform.h

-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:41 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:41 +0000
Subject: [bootwrapper PATCH 01/13] Document entry requirements
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-2-mark.rutland@arm.com>

Currently the boot-wrapper only supports some combinations of exception
levels, with other combinations not being supported.

While we generally expect the boot-wrapper to be entered at the highest
implemented exception level, the AArch32 boot-wrapper has a comment
implying it supports being entered with something else owning EL3. As
this would require such EL3 firmware to always be in sync with the
boot-wrapper's requirements, which change over time, we don't actually
support such a configuration.

Some CPU state (such as CNTFRQ/CNTFRQ_EL0) needs to be initialized at
the highest implemented exception level, but today the boot-wrapper only
does so when entered at EL3 / Secure-PL1. Thus, today the only
completely supported configurations are EL3 / Secure-PL1, and entering
in other configurations is not entirely supported.

The aarch64 `jump_kernel` function always writes to SCTLR_EL2, which is
UNDEFINED at EL1. Hence, the aarch64 boot-wrapper does not support being
entered at EL1.

The aarch32 code assumes that any non-hyp mode is Secure PL1, and
attempt to switch to monitor mode. If entered on a system without the
security extensions, where the highest privileged mode is Non-secure
PL1, this will not work. Hence the aarch32 boot-wrapper does not support
being entered at Non-secure PL1.

Actually supporting all of these configurations requires restructuring
much of the boot-wrapper. For now, document the supported configurations
in each architecture's boot.S, and remove the misleading comment from
arch/aarch32/boot.S. Subsequent patches will improve the support and add
support for additional configurations.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 14 ++++++++++++++
 arch/aarch32/psci.S |  5 -----
 arch/aarch64/boot.S | 13 +++++++++++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 4add338..00c432d 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -16,6 +16,20 @@
 	.arch_extension virt
 
 	.section .init
+
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered in the following modes:
+	 *
+	 * - PL1 / EL3 (Secure) Supervisor mode
+	 *   Entering in this mode is strongly recommended.
+	 *   PL2 must be implemented.
+	 *
+	 * - PL2 / EL2 (Non-secure) Hypervisor mode
+	 *   Entering in this mode is partially supported.
+	 *   PSCI is not supported when entered in this mode.
+	 */
 ASM_FUNC(_start)
 	/* Stack initialisation */
 	cpuid	r0, r1
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index dc7aeb7..e0d2972 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -44,11 +44,6 @@ ASM_FUNC(start_el3)
 	/* pass through */
 
 ASM_FUNC(start_no_el3)
-	/*
-	 * For no-el3, we assume that firmware launched the boot-wrapper in
-	 * non-secure EL2 or EL1. We assume it has its own PSCI implementation
-	 * sitting at EL3, and that this path is only taken by primary CPU.
-	 */
 	cpuid	r0, r1
 	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 27ba449..900b9f8 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -12,6 +12,19 @@
 
 	.section .init
 
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered at the following exception levels:
+	 *
+	 * - EL3 (Secure)
+	 *   Entering at EL3 is strongly recommended.
+	 *   EL2 must be implemented.
+	 *
+	 * - EL2 (Non-secure)
+	 *   Entering at EL2 is partially supported.
+	 *   PSCI is not supported when entered in this exception level.
+	 */
 ASM_FUNC(_start)
 	cpuid	x0, x1
 	bl	find_logical_id
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:43 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:43 +0000
Subject: [bootwrapper PATCH 03/13] aarch64: add system register accessors
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-4-mark.rutland@arm.com>

We open code the use of mrs/msr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/include/asm/cpu.h    | 41 ++++++++++++++++++++++---------
 arch/aarch64/include/asm/gic-v3.h | 10 +++-----
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 63eb1c3..1053414 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -9,10 +9,14 @@
 #ifndef __ASM_AARCH64_CPU_H
 #define __ASM_AARCH64_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
 
+#define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
+
 /*
  * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
  * no WXN.
@@ -29,6 +33,12 @@
 
 #define CPTR_EL3_EZ		(1 << 8)
 
+#define ICC_SRE_EL2		S3_4_C12_C9_5
+#define ICC_SRE_EL3		S3_6_C12_C12_5
+#define ICC_CTLR_EL1		S3_0_C12_C12_4
+#define ICC_CTLR_EL3		S3_6_C12_C12_4
+#define ICC_PMR_EL1		S3_0_C4_C6_0
+
 #define ZCR_EL3			s3_6_c1_c2_0
 #define ZCR_EL3_LEN_MASK	0x1ff
 
@@ -50,20 +60,27 @@
 
 #define sevl()		asm volatile ("sevl\n" : : : "memory")
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define __str(def)	#def
 
-	asm volatile ("mrs	%0, mpidr_el1\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define mrs(reg)							\
+({									\
+	unsigned long __mrs_val;					\
+	asm volatile("mrs %0, " __str(reg) : "=r" (__mrs_val));		\
+	__mrs_val;							\
+})
 
-static inline uint64_t read_id_aa64pfr0(void)
-{
-	uint64_t val;
+#define msr(reg, val)							\
+do {									\
+	unsigned long __msr_val = val;					\
+	asm volatile("msr " __str(reg) ", %0" : : "r" (__msr_val));	\
+} while (0)
+
+#define mrs_field(reg, field) \
+	BITS_EXTRACT(mrs(reg), (reg##_##field))
 
-	asm volatile ("mrs	%0, id_aa64pfr0_el1\n" : "=r" (val));
-	return val;
+static inline unsigned long read_mpidr(void)
+{
+	return mrs(mpidr_el1) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
@@ -73,7 +90,7 @@ static inline void iciallu(void)
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_aa64pfr0() >> 24) & 0xf);
+	return !!mrs_field(ID_AA64PFR0_EL1, GIC);
 }
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
index 5b32380..2447480 100644
--- a/arch/aarch64/include/asm/gic-v3.h
+++ b/arch/aarch64/include/asm/gic-v3.h
@@ -9,20 +9,16 @@
 #ifndef __ASM_AARCH64_GICV3_H
 #define __ASM_AARCH64_GICV3_H
 
-#define ICC_SRE_EL2	"S3_4_C12_C9_5"
-#define ICC_SRE_EL3	"S3_6_C12_C12_5"
-#define ICC_CTLR_EL1	"S3_0_C12_C12_4"
-#define ICC_CTLR_EL3	"S3_6_C12_C12_4"
-#define ICC_PMR_EL1	"S3_0_C4_C6_0"
+#include <asm/cpu.h>
 
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
+	msr(ICC_SRE_EL3, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
+	msr(ICC_CTLR_EL3, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:42 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:42 +0000
Subject: [bootwrapper PATCH 02/13] Add bit-field macros
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-3-mark.rutland@arm.com>

Arm architectural documentation typically defines bit-fields as
`[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
helpful if we could define fields in the same way.

Add helpers so that we can do so, along with helper to extract/insert
bit-field values.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 include/bits.h | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 include/bits.h

diff --git a/include/bits.h b/include/bits.h
new file mode 100644
index 0000000..8824a38
--- /dev/null
+++ b/include/bits.h
@@ -0,0 +1,33 @@
+/*
+ * include/bits.h - helpers for bit-field definitions.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __BITS_H
+#define __BITS_H
+
+#ifdef __ASSEMBLY__
+#define UL(x)	x
+#define ULL(x)	x
+#else
+#define UL(x)	x##UL
+#define ULL(x)	x##ULL
+#endif
+
+#define BITS(msb, lsb) \
+((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
+
+#define BIT(b)	BITS(b, b)
+
+#define BITS_LSB(bits)	(__builtin_ffsll(bits) - 1)
+
+#define BITS_EXTRACT(val, bits) \
+	(((val) & (bits)) >> BITS_LSB(bits))
+
+#define BITS_INSERT(bits, val) \
+	(((val) << BITS_LSB(bits)) & (bits))
+
+#endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:44 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:44 +0000
Subject: [bootwrapper PATCH 04/13] aarch32: add coprocessor accessors
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-5-mark.rutland@arm.com>

We open code the use of mrc/mcr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h    | 45 ++++++++++++++++++++-----------
 arch/aarch32/include/asm/gic-v3.h |  6 +++--
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index 105cae5..d691c7b 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -9,9 +9,13 @@
 #ifndef __ASM_AARCH32_CPU_H
 #define __ASM_AARCH32_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0x00ffffff
 #define MPIDR_INVALID		(-1)
 
+#define ID_PFR1_GIC		BITS(31, 28)
+
 /* Only RES1 bits and CP15 barriers for the kernel */
 #define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
 #define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
@@ -40,32 +44,43 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define MPIDR		"p15, 0, %0, c0, c0, 5"
+#define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
-	asm volatile ("mrc	p15, 0, %0, c0, c0, 5\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define ICC_SRE		"p15, 6, %0, c12, c12, 5"
+#define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
-static inline uint32_t read_id_pfr1(void)
-{
-	uint32_t val;
+#define mrc(reg)						\
+({								\
+	unsigned long __mrc_val;				\
+	asm volatile("mrc " reg : "=r" (__mrc_val));		\
+	__mrc_val;						\
+})
 
-	asm volatile ("mrc	p15, 0, %0, c0, c1, 1\n" : "=r" (val));
-	return val;
+#define mcr(reg, val)						\
+do {								\
+	unsigned long __mcr_val = val;				\
+	asm volatile("mcr " reg : : "r" (__mcr_val));		\
+} while (0)
+
+
+#define mrc_field(reg, field) \
+	BITS_EXTRACT(mrc(reg), (reg##_##field))
+
+static inline unsigned long read_mpidr(void)
+{
+	return mrc(MPIDR) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
 {
-	uint32_t val = 0;
-
-	asm volatile ("mcr	p15, 0, %0, c7, c5, 0" : : "r" (val));
+	mcr(ICIALLU, 0);
 }
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_pfr1() >> 28) & 0xf);
+	return !!mrc_field(ID_PFR1, GIC);
 }
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
index 65f38de..b28136a 100644
--- a/arch/aarch32/include/asm/gic-v3.h
+++ b/arch/aarch32/include/asm/gic-v3.h
@@ -9,14 +9,16 @@
 #ifndef __ASM_AARCH32_GICV3_H
 #define __ASM_AARCH32_GICV3_H
 
+#include <asm/cpu.h>
+
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
+	mcr(ICC_SRE, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
+	mcr(ICC_CTLR, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:45 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:45 +0000
Subject: [bootwrapper PATCH 05/13] aarch64: add mov_64 macro
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-6-mark.rutland@arm.com>

In subsequent patches we'll need to load 64-bit values into GPRs before
the CPU is in a known endianness, where we cannot use literal pools.

In preparation for that, this patch adds a new `mov_64` macro to load a
64-bit value into a GPR using a sequence of MOV and MOVKs, which will
function the same regardless of the CPU's endianness.

At the same time, move the `cpuid` macro to use `mov_64` internally.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/common.S | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
index c7171a9..3279fa9 100644
--- a/arch/aarch64/common.S
+++ b/arch/aarch64/common.S
@@ -9,9 +9,17 @@
 
 #include <cpu.h>
 
+	/* Load a 64-bit value using immediates */
+	.macro	mov_64 dest, val
+	mov	\dest, #(((\val) >>  0) & 0xffff)
+	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
+	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
+	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
+	.endm
+
 	/* Put MPIDR into \dest, clobber \tmp and flags */
 	.macro cpuid dest, tmp
 	mrs	\dest, mpidr_el1
-	ldr	\tmp, =MPIDR_ID_BITS
+	mov_64	\tmp, MPIDR_ID_BITS
 	ands	\dest, \dest, \tmp
 	.endm
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:46 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:46 +0000
Subject: [bootwrapper PATCH 06/13] aarch64: initialize SCTLR_ELx for the
 boot-wrapper
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-7-mark.rutland@arm.com>

The SCTLR_ELx registers contain fields which are UNKNOWN or
IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
defines the endianness of memory accesses (e.g. reads from literal
pools). Due to this, portions of boot-wrapper code are not guaranteed
top work correctly.

Rework the startup code to explicitly initialize SCTLR_ELx for the
exception level the boot-wrapper was entered at. When entered at EL2
it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
which would break the initialization performed in jump_kernel.

As we plan to eventually support the highest implemented EL being any of
EL3/EL2/EL1, code is added to handle all of these exception levels, even
though we do not currently support starting at EL1.

We'll initialize other registers in subsequent patches.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
 arch/aarch64/include/asm/cpu.h | 27 ++++++++++++-
 2 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 900b9f8..45a0367 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -26,26 +26,26 @@
 	 *   PSCI is not supported when entered in this exception level.
 	 */
 ASM_FUNC(_start)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cmp	x0, #MPIDR_INVALID
-	beq	err_invalid_id
-	bl	setup_stack
-
-	/*
-	 * EL3 initialisation
-	 */
 	mrs	x0, CurrentEL
 	cmp	x0, #CURRENTEL_EL3
-	b.eq	1f
+	b.eq	reset_at_el3
+	cmp	x0, #CURRENTEL_EL2
+	b.eq	reset_at_el2
+	cmp	x0, #CURRENTEL_EL1
+	b.eq	reset_at_el1
 
-	mov	w0, #1
-	ldr	x1, =flag_no_el3
-	str	w0, [x1]
+	/* Booting at EL0 is not supported */
+	b	.
 
-	b	start_no_el3
+	/*
+	 * EL3 initialisation
+	 */
+reset_at_el3:
+	mov_64	x0, SCTLR_EL3_RESET
+	msr	sctlr_el3, x0
+	isb
 
-1:	mov	x0, #0x30			// RES1
+	mov	x0, #0x30			// RES1
 	orr	x0, x0, #(1 << 0)		// Non-secure EL1
 	orr	x0, x0, #(1 << 8)		// HVC enable
 
@@ -135,10 +135,54 @@ ASM_FUNC(_start)
 	ldr	x0, =COUNTER_FREQ
 	msr	cntfrq_el0, x0
 
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
 	bl	gic_secure_init
 
 	b	start_el3
 
+	/*
+	 * EL2 initialization
+	 */
+reset_at_el2:
+	// Ensure E2H is not in use
+	mov_64	x0, HCR_EL2_RESET
+	msr	hcr_el2, x0
+	isb
+
+	mov_64	x0, SCTLR_EL2_RESET
+	msr	sctlr_el2, x0
+	isb
+
+	b	reset_no_el3
+
+	/*
+	 * EL1 initialization
+	 */
+reset_at_el1:
+	mov_64	x0, SCTLR_EL1_RESET
+	msr	sctlr_el1, x0
+	isb
+
+	b	reset_no_el3
+
+reset_no_el3:
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
+	mov	w0, #1
+	ldr	x1, =flag_no_el3
+	str	w0, [x1]
+
+	b	start_no_el3
+
 err_invalid_id:
 	b	.
 
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 1053414..f0edd2a 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -14,6 +14,32 @@
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
+#define CURRENTEL_EL2		(2 << 2)
+#define CURRENTEL_EL1		(1 << 2)
+
+/*
+ * RES1 bit definitions definitions as of ARM DDI 0487G.b
+ *
+ * These includes bits which are RES1 in some configurations.
+ */
+#define SCTLR_EL3_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
+				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
+
+#define SCTLR_EL2_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
+				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
+
+#define SCTLR_EL1_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
+				 1 << 11 | 1 << 8 | 1 << 7 | 1 << 4)
+
+#define HCR_EL2_RES1		(1 << 1)
+
+/*
+ * Initial register values required for the boot-wrapper to run out-of-reset.
+ */
+#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
+#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
+#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
+#define HCR_EL2_RESET		HCR_EL2_RES1
 
 #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
 
@@ -43,7 +69,6 @@
 #define ZCR_EL3_LEN_MASK	0x1ff
 
 #define SCTLR_EL1_CP15BEN	(1 << 5)
-#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
 
 #ifdef KERNEL_32
 /* 32-bit kernel decompressor uses CP15 barriers */
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:47 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:47 +0000
Subject: [bootwrapper PATCH 07/13] Rework common init C code
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-8-mark.rutland@arm.com>

In init_platform() we initialize a UART and announce the presence of the
bootwrapper to the world. We do this relatively late in the boot-flow,
and prior to this will silently ignore errors (e.g. in gic_secure_init).

To make it possible to provide improved diagnostics, and to allow us to
move more initialization into C, this patch reworks the init code to
call a C function earlier, where we can announce the presence of the
boot-wrapper and perform other initialization.

In subsequent patches this will be expanded with more CPU
initialization.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am         |  2 +-
 arch/aarch32/boot.S |  5 +++++
 arch/aarch64/boot.S |  4 ++++
 common/boot.c       |  4 ----
 common/init.c       | 24 ++++++++++++++++++++++++
 common/platform.c   | 12 +++++++-----
 include/platform.h  | 17 +++++++++++++++++
 7 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 common/init.c
 create mode 100644 include/platform.h

diff --git a/Makefile.am b/Makefile.am
index f941b07..0651c38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ endif
 PSCI_CPU_OFF	:= 0x84000002
 
 COMMON_SRC	:= common/
-COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o
+COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
 ARCH_OBJ	:= boot.o stack.o utils.o
 
diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 00c432d..ee073ea 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -48,6 +48,9 @@ ASM_FUNC(_start)
 	mov	r0, #1
 	ldr	r1, =flag_no_el3
 	str	r0, [r1]
+
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 _switch_monitor:
@@ -71,6 +74,8 @@ _monitor:
 	ldr	r0, =COUNTER_FREQ
 	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	/* Initialise boot method */
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 45a0367..17b4a75 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -141,6 +141,8 @@ reset_at_el3:
 	b.eq	err_invalid_id
 	bl	setup_stack
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	b	start_el3
@@ -181,6 +183,8 @@ reset_no_el3:
 	ldr	x1, =flag_no_el3
 	str	w0, [x1]
 
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 err_invalid_id:
diff --git a/common/boot.c b/common/boot.c
index c74d34c..29d53a4 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -12,8 +12,6 @@
 extern unsigned long entrypoint;
 extern unsigned long dtb;
 
-void init_platform(void);
-
 void __noreturn jump_kernel(unsigned long address,
 			    unsigned long a0,
 			    unsigned long a1,
@@ -62,8 +60,6 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid)
 {
 	if (cpu == 0) {
-		init_platform();
-
 		*mbox = (unsigned long)&entrypoint;
 		sevl();
 		spin(mbox, invalid, 1);
diff --git a/common/init.c b/common/init.c
new file mode 100644
index 0000000..9c471c9
--- /dev/null
+++ b/common/init.c
@@ -0,0 +1,24 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+static void announce_bootwrapper(void)
+{
+	print_string("Boot-wrapper v0.2\r\n\r\n");
+}
+
+void cpu_init_bootwrapper(void)
+{
+	if (this_cpu_logical_id() == 0) {
+		init_uart();
+		announce_bootwrapper();
+		init_platform();
+	}
+}
diff --git a/common/platform.c b/common/platform.c
index d11f568..47bf547 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -1,5 +1,5 @@
 /*
- * platform.c - code to initialise everything required when first booting.
+ * platform.c - Platform initialization and I/O.
  *
  * Copyright (C) 2015 ARM Limited. All rights reserved.
  *
@@ -7,6 +7,7 @@
  * found in the LICENSE.txt file.
  */
 
+#include <cpu.h>
 #include <stdint.h>
 
 #include <asm/io.h>
@@ -30,7 +31,7 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-static void print_string(const char *str)
+void print_string(const char *str)
 {
 	uint32_t flags;
 
@@ -47,7 +48,7 @@ static void print_string(const char *str)
 	}
 }
 
-void init_platform(void)
+void init_uart(void)
 {
 	/*
 	 * UART initialisation (38400 8N1)
@@ -58,9 +59,10 @@ void init_platform(void)
 	raw_writel(0x70,	PL011(UART_LCR_H));
 	/* Enable the UART, TXen and RXen */
 	raw_writel(0x301,	PL011(UARTCR));
+}
 
-	print_string("Boot-wrapper v0.2\r\n\r\n");
-
+void init_platform(void)
+{
 #ifdef SYSREGS_BASE
 	/*
 	 * CLCD output site MB
diff --git a/include/platform.h b/include/platform.h
new file mode 100644
index 0000000..e5248e1
--- /dev/null
+++ b/include/platform.h
@@ -0,0 +1,17 @@
+/*
+ * include/platform.h - Platform initialization and I/O.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __PLATFORM_H
+#define __PLATFORM_H
+
+void print_string(const char *str);
+void init_uart(void);
+
+void init_platform(void);
+
+#endif /* __PLATFORM_H */
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:48 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:48 +0000
Subject: [bootwrapper PATCH 08/13] Announce boot-wrapper mode / exception level
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-9-mark.rutland@arm.com>

When something goes wrong within the boot-wrapper, it can be very
helpful to know where we started from. Add an arch_announce() function
to log this early in the boot process. More information can be added
here in future.

This is logged ot the serial console as:

| Boot-wrapper v0.2
| Entered at EL3

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |  2 +-
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 30 ++++++++++++++++++++++++++++++
 arch/aarch64/init.c            | 19 +++++++++++++++++++
 common/init.c                  |  6 +++++-
 common/platform.c              | 24 ++++++++++++++----------
 include/platform.h             |  1 +
 7 files changed, 79 insertions(+), 12 deletions(-)
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/init.c

diff --git a/Makefile.am b/Makefile.am
index 0651c38..885a77c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,7 +36,7 @@ PSCI_CPU_OFF	:= 0x84000002
 COMMON_SRC	:= common/
 COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
-ARCH_OBJ	:= boot.o stack.o utils.o
+ARCH_OBJ	:= boot.o stack.o utils.o init.o
 
 if BOOTWRAPPER_32
 CPPFLAGS	+= -DBOOTWRAPPER_32
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index d691c7b..aa72204 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -44,6 +44,15 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
+static inline unsigned long read_cpsr(void)
+{
+	unsigned long cpsr;
+	asm volatile ("mrs      %0, cpsr\n" : "=r" (cpsr));
+	return cpsr;
+}
+
+#define read_cpsr_mode()       (read_cpsr() & PSR_MODE_MASK)
+
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
new file mode 100644
index 0000000..b29ebb4
--- /dev/null
+++ b/arch/aarch32/init.c
@@ -0,0 +1,30 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <platform.h>
+
+#include <asm/cpu.h>
+
+static const char *mode_string(void)
+{
+	switch (read_cpsr_mode()) {
+	case PSR_MON:
+		return "PL1";
+	case PSR_HYP:
+		return "PL2 (Non-secure)";
+	default:
+		return "<UNKNOWN MODE>";
+	}
+}
+
+void announce_arch(void)
+{
+	print_string("Entered at ");
+	print_string(mode_string());
+	print_string("\r\n");
+}
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
new file mode 100644
index 0000000..82816e7
--- /dev/null
+++ b/arch/aarch64/init.c
@@ -0,0 +1,19 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+void announce_arch(void)
+{
+	unsigned char el = mrs(CurrentEl) >> 2;
+
+	print_string("Entered at EL");
+	print_char('0' + el);
+	print_string("\r\n");
+}
diff --git a/common/init.c b/common/init.c
index 9c471c9..2600f73 100644
--- a/common/init.c
+++ b/common/init.c
@@ -11,14 +11,18 @@
 
 static void announce_bootwrapper(void)
 {
-	print_string("Boot-wrapper v0.2\r\n\r\n");
+	print_string("Boot-wrapper v0.2\r\n");
 }
 
+void announce_arch(void);
+
 void cpu_init_bootwrapper(void)
 {
 	if (this_cpu_logical_id() == 0) {
 		init_uart();
 		announce_bootwrapper();
+		announce_arch();
+		print_string("\r\n");
 		init_platform();
 	}
 }
diff --git a/common/platform.c b/common/platform.c
index 47bf547..80d0562 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -31,21 +31,25 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-void print_string(const char *str)
+void print_char(char c)
 {
 	uint32_t flags;
 
-	while (*str) {
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_FIFO_FULL);
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_FIFO_FULL);
+
+	raw_writel(c, PL011(UARTDR));
 
-		raw_writel(*str++, PL011(UARTDR));
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_BUSY);
+}
 
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_BUSY);
-	}
+void print_string(const char *str)
+{
+	while (*str)
+		print_char(*str++);
 }
 
 void init_uart(void)
diff --git a/include/platform.h b/include/platform.h
index e5248e1..237b481 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -9,6 +9,7 @@
 #ifndef __PLATFORM_H
 #define __PLATFORM_H
 
+void print_char(char c);
 void print_string(const char *str);
 void init_uart(void);
 
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:49 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:49 +0000
Subject: [bootwrapper PATCH 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-10-mark.rutland@arm.com>

The majority of state that we initialize at EL3 is necessary for code at
lower ELs to function, but isnt' necessary for the boot-wrapper itself.
Given that, it would be better to write this in C where it can be
written mode clearly, and where it will be possible to add logging/debug
logic.

This patch migrates the AArch64 EL3 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |  2 +-
 arch/aarch64/boot.S            | 92 +---------------------------------
 arch/aarch64/include/asm/cpu.h | 36 ++++++++++++-
 arch/aarch64/init.c            | 69 +++++++++++++++++++++++++
 4 files changed, 107 insertions(+), 92 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 885a77c..a598b95 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,7 +153,7 @@ $(COMMON_SRC):
 %.o: %.S Makefile | $(ARCH_SRC)
 	$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
 
-%.o: %.c Makefile | $(COMMON_SRC)
+%.o: %.c Makefile | $(ARCH_SRC) $(COMMON_SRC)
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
 model.lds: $(LD_SCRIPT) Makefile
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 17b4a75..c0ec518 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -45,96 +45,6 @@ reset_at_el3:
 	msr	sctlr_el3, x0
 	isb
 
-	mov	x0, #0x30			// RES1
-	orr	x0, x0, #(1 << 0)		// Non-secure EL1
-	orr	x0, x0, #(1 << 8)		// HVC enable
-
-	/* Enable pointer authentication if present */
-	mrs	x1, id_aa64isar1_el1
-	/* We check for APA+API and GPA+GPI */
-	ldr	x2, =((0xff << 24) | (0xff << 4))
-	and	x1, x1, x2
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 16)		// AP key enable
-	orr	x0, x0, #(1 << 17)		// AP insn enable
-1:
-	/* Enable TME if present */
-	mrs	x1, id_aa64isar0_el1
-	ubfx	x1, x1, #24, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 34)		// TME enable
-1:
-	/* Enable FGT if present */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #56, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 27)		// FGT enable
-1:
-	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #60, #4
-	cmp	x1, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 28)		// ECV enable
-1:
-	/* Enable MTE if present */
-	mrs	x10, id_aa64pfr1_el1
-	ubfx	x10, x10, #8, #4
-	cmp	x10, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 26)		// ATA enable
-1:
-#ifndef KERNEL_32
-	orr	x0, x0, #(1 << 10)		// 64-bit EL2
-#endif
-	msr	scr_el3, x0
-
-	msr	cptr_el3, xzr			// Disable copro. traps to EL3
-
-	mov	x0, xzr
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #32, #4
-	cbz	x1, 1f
-
-	// Enable SPE for the non-secure world.
-	orr	x0, x0, #(0x3 << 12)
-
-	// Do not trap PMSNEVFR_EL1 if present
-	cmp	x1, #3
-	b.lt	1f
-	orr	x0, x0, #(1 << 36)
-
-1:	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #44, #4
-	cbz	x1, 1f
-
-	// Enable TRBE for the non-secure world.
-	ldr	x1, =(0x3 << 24)
-	orr	x0, x0, x1
-
-1:	msr	mdcr_el3, x0			// Disable traps to EL3
-
-	mrs	x0, id_aa64pfr0_el1
-	ubfx	x0, x0, #32, #4			// SVE present?
-	cbz	x0, 1f				// Skip SVE init if not
-
-	mrs	x0, cptr_el3
-	orr	x0, x0, #CPTR_EL3_EZ		// enable SVE
-	msr	cptr_el3, x0
-	isb
-
-	mov	x0, #ZCR_EL3_LEN_MASK		// SVE: Enable full vector len
-	msr	ZCR_EL3, x0			// for EL2.
-
-1:
-	ldr	x0, =COUNTER_FREQ
-	msr	cntfrq_el0, x0
-
 	cpuid	x0, x1
 	bl	find_logical_id
 	cmp	x0, #MPIDR_INVALID
@@ -143,6 +53,8 @@ reset_at_el3:
 
 	bl	cpu_init_bootwrapper
 
+	bl	cpu_init_el3
+
 	bl	gic_secure_init
 
 	b	start_el3
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index f0edd2a..5afcf78 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -31,7 +31,41 @@
 #define SCTLR_EL1_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
 				 1 << 11 | 1 << 8 | 1 << 7 | 1 << 4)
 
-#define HCR_EL2_RES1		(1 << 1)
+#define ZCR_EL3				s3_6_c1_c2_0
+#define ZCR_EL3_LEN			BITS(3, 1)
+
+#define MDCR_EL3_NSPB_NS_NOTRAP		(UL(3) << 12)
+#define MDCR_EL3_NSTB_NS_NOTRAP		(UL(3) << 24)
+#define MDCR_EL3_ENPMSN			BIT(36)
+
+#define SCR_EL3_RES1			BITS(5, 4)
+#define SCR_EL3_NS			BIT(0)
+#define SCR_EL3_HCE			BIT(8)
+#define SCR_EL3_RW			BIT(10)
+#define SCR_EL3_APK			BIT(16)
+#define SCR_EL3_API			BIT(17)
+#define SCR_EL3_ATA			BIT(26)
+#define SCR_EL3_FGTEN			BIT(27)
+#define SCR_EL3_ECVEN			BIT(28)
+#define SCR_EL3_TME			BIT(34)
+
+#define HCR_EL2_RES1			BIT(1)
+
+#define ID_AA64DFR0_EL1_PMSVER		BITS(35, 32)
+#define ID_AA64DFR0_EL1_TRACEBUFFER	BITS(47, 44)
+
+#define ID_AA64ISAR0_EL1_TME		BITS(27, 24)
+
+#define ID_AA64ISAR1_EL1_APA		BITS(7, 4)
+#define ID_AA64ISAR1_EL1_API		BITS(11, 8)
+#define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
+#define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
+
+#define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
+#define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
+
+#define ID_AA64PFR1_EL1_MTE		BITS(11, 8)
+#define ID_AA64PFR0_EL1_SVE		BITS(35, 32)
 
 /*
  * Initial register values required for the boot-wrapper to run out-of-reset.
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 82816e7..ded9871 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -8,6 +8,7 @@
  */
 #include <cpu.h>
 #include <platform.h>
+#include <stdbool.h>
 
 void announce_arch(void)
 {
@@ -17,3 +18,71 @@ void announce_arch(void)
 	print_char('0' + el);
 	print_string("\r\n");
 }
+
+static inline bool kernel_is_32bit(void)
+{
+#ifdef KERNEL_32
+	return true;
+#else
+	return false;
+#endif
+}
+
+static inline bool cpu_has_pauth(void)
+{
+	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
+				       ID_AA64ISAR1_EL1_API |
+				       ID_AA64ISAR1_EL1_GPA |
+				       ID_AA64ISAR1_EL1_GPI;
+
+	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
+}
+
+void cpu_init_el3(void)
+{
+	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
+	unsigned long mdcr = 0;
+	unsigned long cptr = 0;
+
+	if (cpu_has_pauth())
+		scr |= SCR_EL3_APK | SCR_EL3_API;
+
+	if (mrs_field(ID_AA64ISAR0_EL1, TME))
+		scr |= SCR_EL3_TME;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
+		scr |= SCR_EL3_FGTEN;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
+		scr |= SCR_EL3_ECVEN;
+
+	if (mrs_field(ID_AA64PFR1_EL1, MTE))
+		scr |= SCR_EL3_ATA;
+
+	if (!kernel_is_32bit())
+		scr |= SCR_EL3_RW;
+
+	msr(SCR_EL3, scr);
+
+	msr(CPTR_EL3, cptr);
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER))
+		mdcr |= MDCR_EL3_NSPB_NS_NOTRAP;
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER) >= 3)
+		mdcr |= MDCR_EL3_ENPMSN;
+
+	if (mrs_field(ID_AA64DFR0_EL1, TRACEBUFFER))
+		mdcr |= MDCR_EL3_NSTB_NS_NOTRAP;
+
+	msr(MDCR_EL3, mdcr);
+
+	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
+		cptr |= CPTR_EL3_EZ;
+		msr(CPTR_EL3, cptr);
+		isb();
+		msr(ZCR_EL3, ZCR_EL3_LEN);
+	}
+
+	msr(CNTFRQ_EL0, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:50 +0000
Subject: [bootwrapper PATCH 10/13] aarch32: move the bulk of Secure PL1
 initialization to C
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-11-mark.rutland@arm.com>

The majority of state that we initialize at Secure PL1 is necessary for
code at lower PLs to function, but isnt' necessary for the boot-wrapper
itself.  Given that, it would be better to write this in C where it can
be written mode clearly, and where it will be possible to add
logging/debug logic.

This patch migrates the AArch32 Secure PL1 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S            | 11 +----------
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 12 ++++++++++++
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index ee073ea..820957b 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -63,16 +63,7 @@ _monitor:
 	/* Move the stack to Monitor mode*/
 	mrs	sp, sp_svc
 
-	/* Setup secure registers and devices */
-	mov	r0, #1				@ Non-secure lower level
-	orr	r0, #(1 << 8)			@ HVC enable
-	mcr	p15, 0, r0, c1, c1, 0		@ SCR
-
-	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
-	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
-
-	ldr	r0, =COUNTER_FREQ
-	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
+	bl	cpu_init_secure_pl1
 
 	bl	cpu_init_bootwrapper
 
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index aa72204..c1bce9a 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -30,6 +30,11 @@
 #define PSR_I			(1 << 7)
 #define PSR_A			(1 << 8)
 
+#define SCR_NS			BIT(0)
+#define SCR_HCE			BIT(8)
+
+#define NSACR_CP10		BIT(10)
+#define NSACR_CP11		BIT(11)
 
 #define SPSR_KERNEL		(PSR_A | PSR_I | PSR_F | PSR_HYP)
 
@@ -55,11 +60,15 @@ static inline unsigned long read_cpsr(void)
 
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define SCR		"p15, 0, %0, c1, c1, 0"
+#define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
+#define CNTFRQ		"p15, 0, %0, c14, c0, 0"
+
 #define mrc(reg)						\
 ({								\
 	unsigned long __mrc_val;				\
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
index b29ebb4..5b69dcd 100644
--- a/arch/aarch32/init.c
+++ b/arch/aarch32/init.c
@@ -28,3 +28,15 @@ void announce_arch(void)
 	print_string(mode_string());
 	print_string("\r\n");
 }
+
+void cpu_init_secure_pl1(void)
+{
+	unsigned long scr = SCR_NS | SCR_HCE;
+	unsigned long nsacr = NSACR_CP10 | NSACR_CP11;
+
+	mcr(SCR, scr);
+
+	mcr(NSACR, nsacr);
+
+	mcr(CNTFRQ, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:51 +0000
Subject: [bootwrapper PATCH 11/13] Announce locations of memory objects
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-12-mark.rutland@arm.com>

To make it easier to debug boot failures, log the location of memory
objects at boot time.

This is logged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL3
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 common/init.c      | 27 +++++++++++++++++++++++++++
 common/platform.c  | 14 ++++++++++++++
 include/platform.h |  2 ++
 model.lds.S        | 20 ++++++++++++++------
 4 files changed, 57 insertions(+), 6 deletions(-)

diff --git a/common/init.c b/common/init.c
index 2600f73..fc74b9e 100644
--- a/common/init.c
+++ b/common/init.c
@@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
 	print_string("Boot-wrapper v0.2\r\n");
 }
 
+#define announce_object(object, desc)				\
+do {								\
+	extern char object##__start[];				\
+	extern char object##__end[];				\
+	print_string("[");					\
+	print_ulong_hex((unsigned long)object##__start);	\
+	print_string("..");					\
+	print_ulong_hex((unsigned long)object##__end);		\
+	print_string("] => " desc "\r\n");			\
+} while (0)
+
+static void announce_objects(void)
+{
+	print_string("Memory layout:\r\n");
+	announce_object(text, "boot-wrapper");
+	announce_object(mbox, "mbox");
+	announce_object(kernel, "kernel");
+#ifdef XEN
+	announce_object(xen, "xen");
+#endif
+	announce_object(dtb, "dtb");
+#ifdef USE_INITRD
+	announce_object(filesystem, "initrd");
+#endif
+}
+
 void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
@@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
+		announce_objects();
 		print_string("\r\n");
 		init_platform();
 	}
diff --git a/common/platform.c b/common/platform.c
index 80d0562..5a91349 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -52,6 +52,20 @@ void print_string(const char *str)
 		print_char(*str++);
 }
 
+#define HEX_CHARS_PER_LONG (2 * sizeof(long))
+#define NIBBLES_PER
+
+void print_ulong_hex(unsigned long val)
+{
+	const char hex_chars[16] = "0123456789abcdef";
+	int i;
+
+	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
+		int v = (val >> (4 * i)) & 0xf;
+		print_char(hex_chars[v]);
+	}
+}
+
 void init_uart(void)
 {
 	/*
diff --git a/include/platform.h b/include/platform.h
index 237b481..c88e124 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -11,6 +11,8 @@
 
 void print_char(char c);
 void print_string(const char *str);
+void print_ulong_hex(unsigned long val);
+
 void init_uart(void);
 
 void init_platform(void);
diff --git a/model.lds.S b/model.lds.S
index d4e7e13..dacaa25 100644
--- a/model.lds.S
+++ b/model.lds.S
@@ -35,46 +35,54 @@ SECTIONS
 	 * the boot section's *(.data)
 	 */
 	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
-		kernel = .;
+		kernel__start = .;
 		KERNEL
+		kernel__end = .;
 	}
 
 #ifdef XEN
 	.xen (PHYS_OFFSET + XEN_OFFSET): {
-		xen = .;
+		xen__start = .;
 		XEN
+		xen__end = .;
 	}
 
-	entrypoint = xen;
+	entrypoint = xen__start;
 #else
-	entrypoint = kernel;
+	entrypoint = kernel__start;
 #endif
 
 	.dtb (PHYS_OFFSET + FDT_OFFSET): {
+		dtb__start = .;
 		dtb = .;
 		./fdt.dtb
+		dtb__end = .;
 	}
 
 #ifdef USE_INITRD
 	.filesystem (PHYS_OFFSET + FS_OFFSET): {
-		filesystem = .;
+		filesystem__start = .;
 		FILESYSTEM
-		fs_size = . - filesystem;
+		filesystem__end = .;
 	}
 #endif
 
 	.boot PHYS_OFFSET: {
+		text__start = .;
 		*(.init)
 		*(.text*)
 		*(.data* .rodata* .bss* COMMON)
 		*(.vectors)
 		*(.stack)
 		PROVIDE(etext = .);
+		text__end = .;
 	}
 
 	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
+		mbox__start = .;
 		mbox = .;
 		QUAD(0x0)
+		mbox__end = .;
 	}
 
 	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:52 +0000
Subject: [bootwrapper PATCH 12/13] Rework bootmethod initialization
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-13-mark.rutland@arm.com>

We currently initialize the bootmethod late, in assembly code. This
requires us to maintain the el3/no_el3 distintion late into the boot
process, and means we cannot produce any helpful diagnostic when booted
at an unexpected exception level.

Rework things so that we initialize the bootmethod early, with a warning
when things are wrong. The el3/no_el3 distinction is now irrelevant to
the bootmethod code, and can be removed in subsequent patches.

When a boot-wrapper configured for PSCI is entered at EL2, a warning is
looged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL2
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb
|
| WARNING: PSCI could not be initialized. Boot may fail

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h  |  1 +
 arch/aarch32/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
 arch/aarch32/psci.S             |  8 +-------
 arch/aarch32/utils.S            |  9 ---------
 arch/aarch64/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
 arch/aarch64/psci.S             | 21 ++-------------------
 arch/aarch64/spin.S             |  3 +++
 arch/aarch64/utils.S            |  9 ---------
 common/init.c                   |  7 ++++++-
 common/psci.c                   | 22 +++++++++++++++++++---
 include/boot.h                  |  2 ++
 11 files changed, 90 insertions(+), 48 deletions(-)
 create mode 100644 arch/aarch32/include/asm/psci.h
 create mode 100644 arch/aarch64/include/asm/psci.h

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index c1bce9a..3426075 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -63,6 +63,7 @@ static inline unsigned long read_cpsr(void)
 #define SCR		"p15, 0, %0, c1, c1, 0"
 #define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
+#define MVBAR		"p15, 0, %0, c12, c0, 1"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
diff --git a/arch/aarch32/include/asm/psci.h b/arch/aarch32/include/asm/psci.h
new file mode 100644
index 0000000..50c7c70
--- /dev/null
+++ b/arch/aarch32/include/asm/psci.h
@@ -0,0 +1,28 @@
+/*
+ * arch/aarch64/include/asm/psci.h
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __ASM_AARCH64_PSCI_H
+#define __ASM_AARCH64_PSCI_H
+
+#include <cpu.h>
+#include <stdbool.h>
+
+extern char psci_vectors[];
+
+static inline bool cpu_init_psci_arch(void)
+{
+	if (read_cpsr_mode() != PSR_MON)
+		return false;
+
+	mcr(MVBAR, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+
+#endif
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index e0d2972..cdc36b0 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -15,7 +15,7 @@
 
 	.section .vectors
 	.align 6
-smc_vectors:
+ASM_DATA(psci_vectors)
 	b	err_exception			@ Reset
 	b	err_exception			@ Undef
 	b	handle_smc			@ SMC
@@ -39,11 +39,5 @@ handle_smc:
 	movs	pc, lr
 
 ASM_FUNC(start_el3)
-	ldr	r0, =smc_vectors
-	blx	setup_vector
-	/* pass through */
-
 ASM_FUNC(start_no_el3)
-	cpuid	r0, r1
-	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch32/utils.S b/arch/aarch32/utils.S
index 5809f48..58279aa 100644
--- a/arch/aarch32/utils.S
+++ b/arch/aarch32/utils.S
@@ -35,12 +35,3 @@ ASM_FUNC(find_logical_id)
 	bx	lr
 3:	mov	r0, #MPIDR_INVALID
 	bx	lr
-
-/*
- * Setup EL3 vectors.
- * r0: vector address
- */
-ASM_FUNC(setup_vector)
-	mcr	p15, 0, r0, c12, c0, 1	@ MVBAR
-	isb
-	bx	lr
diff --git a/arch/aarch64/include/asm/psci.h b/arch/aarch64/include/asm/psci.h
new file mode 100644
index 0000000..491e685
--- /dev/null
+++ b/arch/aarch64/include/asm/psci.h
@@ -0,0 +1,28 @@
+/*
+ * arch/aarch64/include/asm/psci.h
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __ASM_AARCH64_PSCI_H
+#define __ASM_AARCH64_PSCI_H
+
+#include <cpu.h>
+#include <stdbool.h>
+
+extern char psci_vectors[];
+
+static inline bool cpu_init_psci_arch(void)
+{
+	if (mrs(CurrentEL) != CURRENTEL_EL3)
+		return false;
+
+	msr(VBAR_EL3, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+
+#endif
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index 8bd224b..d6ca2eb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -19,7 +19,7 @@
 	.section .vectors, "w"
 
 	.align 11
-vector:
+ASM_DATA(psci_vectors)
 	// current EL, SP_EL0
 	ventry	err_exception	// synchronous
 	ventry	err_exception	// IRQ
@@ -80,22 +80,5 @@ smc_exit:
 	eret
 
 ASM_FUNC(start_el3)
-	ldr	x0, =vector
-	bl	setup_vector
-
-	/* only boot the primary cpu (entry 0 in the table) */
-	cpuid	x0, x1
-	bl	find_logical_id
-	b	psci_first_spin
-
-/*
- * This PSCI implementation requires EL3. Without EL3 we'll only boot the
- * primary cpu, all others will be trapped in an infinite loop.
- */
 ASM_FUNC(start_no_el3)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cbz	x0, psci_first_spin
-spin_dead:
-	wfe
-	b	spin_dead
+	b	psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 1ea1c0b..764c532 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -12,6 +12,9 @@
 
 	.text
 
+ASM_FUNC(cpu_init_bootmethod)
+	ret
+
 ASM_FUNC(start_el3)
 ASM_FUNC(start_no_el3)
 	cpuid	x0, x1
diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
index 85c7f8a..32393cc 100644
--- a/arch/aarch64/utils.S
+++ b/arch/aarch64/utils.S
@@ -32,12 +32,3 @@ ASM_FUNC(find_logical_id)
 	ret
 3:	mov	x0, #MPIDR_INVALID
 	ret
-
-/*
- * Setup EL3 vectors
- * x0: vector address
- */
-ASM_FUNC(setup_vector)
-	msr	VBAR_EL3, x0
-	isb
-	ret
diff --git a/common/init.c b/common/init.c
index fc74b9e..3c05ac3 100644
--- a/common/init.c
+++ b/common/init.c
@@ -6,6 +6,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE.txt file.
  */
+#include <boot.h>
 #include <cpu.h>
 #include <platform.h>
 
@@ -44,7 +45,9 @@ void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
 {
-	if (this_cpu_logical_id() == 0) {
+	unsigned int cpu = this_cpu_logical_id();
+
+	if (cpu == 0) {
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
@@ -52,4 +55,6 @@ void cpu_init_bootwrapper(void)
 		print_string("\r\n");
 		init_platform();
 	}
+
+	cpu_init_bootmethod(cpu);
 }
diff --git a/common/psci.c b/common/psci.c
index a0e8700..8af6870 100644
--- a/common/psci.c
+++ b/common/psci.c
@@ -12,8 +12,11 @@
 #include <bakery_lock.h>
 #include <boot.h>
 #include <cpu.h>
+#include <platform.h>
 #include <psci.h>
 
+#include <asm/psci.h>
+
 #ifndef CPU_IDS
 #error "No MPIDRs provided"
 #endif
@@ -78,12 +81,25 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
 	}
 }
 
-void __noreturn psci_first_spin(unsigned int cpu)
+void __noreturn psci_first_spin(void)
 {
-	if (cpu == MPIDR_INVALID)
-		while (1);
+	unsigned int cpu = this_cpu_logical_id();
 
 	first_spin(cpu, branch_table + cpu, PSCI_ADDR_INVALID);
 
 	unreachable();
 }
+
+void cpu_init_bootmethod(unsigned int cpu)
+{
+	if (cpu_init_psci_arch())
+		return;
+
+	if (cpu == 0) {
+		print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
+		return;
+	}
+
+	while (1)
+		wfe();
+}
diff --git a/include/boot.h b/include/boot.h
index d75e013..10968f8 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -16,4 +16,6 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
 void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid_addr);
 
+void cpu_init_bootmethod(unsigned int cpu);
+
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 11 05:06:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 11 Jan 2022 13:06:53 +0000
Subject: [bootwrapper PATCH 13/13] Unify start_el3 & start_no_el3
In-Reply-To: <20220111130653.2331827-1-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
Message-ID: <20220111130653.2331827-14-mark.rutland@arm.com>

Now that the start_el3 and start_no_el3 labels point at the same place,
unify them into a start_bootmethod label and update callers.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 5 ++---
 arch/aarch64/boot.S | 4 ++--
 arch/aarch64/psci.S | 3 +--
 3 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 820957b..4d16c9c 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -51,7 +51,7 @@ ASM_FUNC(_start)
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 _switch_monitor:
 	adr	lr, _monitor
@@ -69,8 +69,7 @@ _monitor:
 
 	bl	gic_secure_init
 
-	/* Initialise boot method */
-	b	start_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index c0ec518..da5fa65 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -57,7 +57,7 @@ reset_at_el3:
 
 	bl	gic_secure_init
 
-	b	start_el3
+	b	start_bootmethod
 
 	/*
 	 * EL2 initialization
@@ -97,7 +97,7 @@ reset_no_el3:
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index d6ca2eb..9709dbb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -79,6 +79,5 @@ smc_exit:
 	ldp	x18, x19, [sp], #16
 	eret
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	b	psci_first_spin
-- 
2.30.2



From boger at wirenboard.com  Tue Jan 11 05:13:02 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 16:13:02 +0300
Subject: [PATCH 1/3] iio: adc: sun4i-gpadc-iio: no temp sensor on R40
In-Reply-To: <20211122124115.00005186@Huawei.com>
References: <20211119191456.510435-1-boger@wirenboard.com>
 <20211119191456.510435-2-boger@wirenboard.com>
 <20211122091132.yjudzei3bdqmnxq6@gilmour>
 <20211122124115.00005186@Huawei.com>
Message-ID: <85db7e8a-2b9a-7e44-ec96-b804201a3491@wirenboard.com>


22.11.2021 15:41, Jonathan Cameron ?????:
> On Mon, 22 Nov 2021 10:11:32 +0100
> Maxime Ripard <maxime at cerno.tech> wrote:
>
>> On Fri, Nov 19, 2021 at 10:14:54PM +0300, Evgeny Boger wrote:
>>> R40 SoC has touchscreen controller also serving as general-purpose ADC.
>>> The hardware is very similar to A31, except that R40 has separate
>>> calibrated thermal sensor IP (handled by sun8i_thermal).
>>>
>>> Despite the temperature sensor in the RTP is never mentioned in
>>> the R40 family user manuals, it appears to be working. However,
>>> it's not very useful as it lacks calibration data and there is another
>>> fully functioning temperature sensor anyway.
>>>
>>> This patch disables the temperature sensor in RTP/GPADC IP on R40.
>>>
>>> The reason for disabling the temperature sensor is that the IP
>>> needs to be switched back and forth between RTP and GPADC modes for
>>> temperature measurements. Not only this introduces delays, but it also
>>> disturbs external circuitry by injecting current into ADC inputs.
>>>
>>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
>> Acked-by: Maxime Ripard <maxime at cerno.tech>
> +Cc linux-iio at vger.kernel.org
>
> I'm fine with this and assuming Lee is happy to pick it up + send
> me an immutable branch in case anything crosses with it this cycle..
>
> Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

Hi Jonathan!

Is there anything else I should do to make this patch series accepted?


> Thanks,
>
> Jonathan
>
>> Maxime
>>



From songmuchun at bytedance.com  Tue Jan 11 05:16:52 2022
From: songmuchun at bytedance.com (Muchun Song)
Date: Tue, 11 Jan 2022 21:16:52 +0800
Subject: [PATCH] arm64: mm: hugetlb: add support for free vmemmap pages of
 HugeTLB
Message-ID: <20220111131652.61947-1-songmuchun@bytedance.com>

The preparation of supporting freeing vmemmap associated with each
HugeTLB page is ready, so we can support this feature for arm64.

Signed-off-by: Muchun Song <songmuchun at bytedance.com>
---
There is already some discussions about this in [1], but there was no
conclusion in the end. I copied the concern proposed by Anshuman to here.

1st concern:
"
  But what happens when a hot remove section's vmemmap area (which is being
  teared down) is nearby another vmemmap area which is either created or
  being destroyed for HugeTLB alloc/free purpose. As you mentioned HugeTLB
  pages inside the hot remove section might be safe. But what about other
  HugeTLB areas whose vmemmap area shares page table entries with vmemmap
  entries for a section being hot removed ? Massive HugeTLB alloc/use/free
  test cycle using memory just adjacent to a memory hotplug area, which is
  always added and removed periodically, should be able to expose this problem.
"
My Answer: As you already know HugeTLB pages inside the hot remove section
is safe. Let's talk your question "what about other HugeTLB areas whose
vmemmap area shares page table entries with vmemmap entries for a section
being hot removed ?", the question is not established. Why? The minimal
granularity size of hotplug memory 128MB (on arm64, 4k base page), so any
HugeTLB smaller than 128MB is within a section, then, there is no share
(PTE) page tables between HugeTLB in this section and ones in other
sections and a HugeTLB could not cross two sections. Any HugeTLB bigger
than 128MB (e.g. 1GB) whose size is an integer multible of a section and
vmemmap area is also an integer multiple of 2MB. At the time memory is
removed, all huge pages either have been migrated away or dissolved. The
vmemmap is stable. So there is no problem in this case as well.

2nd concern:
"
  differently, not sure if ptdump would require any synchronization.

  Dumping an wrong value is probably okay but crashing because a page table
  entry is being freed after ptdump acquired the pointer is bad. On arm64,
  ptdump() is protected against hotremove via [get|put]_online_mems().
"
My Answer: The ptdump should be fine since vmemmap_remap_free() only exchanges
PTEs or split the PMD entry (which means allocating a PTE page table). Both
operations do not free any page tables, so ptdump cannot run into a UAF on
any page tables. The wrost case is just dumping an wrong value.

[1] https://lore.kernel.org/linux-mm/b8cdc9c8-853c-8392-a2fa-4f1a8f02057a at arm.com/T/

 fs/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index 7a2b11c0b803..04cfd5bf5ec9 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -247,7 +247,7 @@ config HUGETLB_PAGE
 
 config HUGETLB_PAGE_FREE_VMEMMAP
 	def_bool HUGETLB_PAGE
-	depends on X86_64
+	depends on X86_64 || ARM64
 	depends on SPARSEMEM_VMEMMAP
 
 config HUGETLB_PAGE_FREE_VMEMMAP_DEFAULT_ON
-- 
2.11.0



From tudor.ambarus at microchip.com  Tue Jan 11 05:23:01 2022
From: tudor.ambarus at microchip.com (Tudor Ambarus)
Date: Tue, 11 Jan 2022 15:23:01 +0200
Subject: [PATCH v2] ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
Message-ID: <20220111132301.906712-1-tudor.ambarus@microchip.com>

PMERRLOC resource size was set to 0x100, which resulted in HSMC_ERRLOCx
register being truncated to offset x = 21, causing error correction to
fail if more than 22 bit errors and if 24 or 32 bit error correction
was supported.

Fixes: d9c41bf30cf8 ("ARM: dts: at91: Declare EBI/NAND controllers")
Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
Cc: <stable at vger.kernel.org> # 4.13.x
---
v2:
- update commit description
- Cc stable at vger.kernel.org

 arch/arm/boot/dts/sama5d2.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
index 09c741e8ecb8..c700c3b19e4c 100644
--- a/arch/arm/boot/dts/sama5d2.dtsi
+++ b/arch/arm/boot/dts/sama5d2.dtsi
@@ -415,7 +415,7 @@ hsmc: hsmc at f8014000 {
 				pmecc: ecc-engine at f8014070 {
 					compatible = "atmel,sama5d2-pmecc";
 					reg = <0xf8014070 0x490>,
-					      <0xf8014500 0x100>;
+					      <0xf8014500 0x200>;
 				};
 			};
 
-- 
2.25.1



From maz at kernel.org  Tue Jan 11 05:30:41 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 11 Jan 2022 13:30:41 +0000
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
In-Reply-To: <CAAeT=Fz1KPbpmcSbukBuGWMJH=V_oXAJoaDHAen_Gy9Qswo_1Q@mail.gmail.com>
References: <20220110054042.1079932-1-reijiw@google.com>
 <YdwPCcZWD8Uc1eej@monolith.localdoman>
 <CAAeT=Fz1KPbpmcSbukBuGWMJH=V_oXAJoaDHAen_Gy9Qswo_1Q@mail.gmail.com>
Message-ID: <875yqqtn5q.wl-maz@kernel.org>

On Tue, 11 Jan 2022 07:37:57 +0000,
Reiji Watanabe <reijiw at google.com> wrote:
> 
> Hi Alex,
> 
> On Mon, Jan 10, 2022 at 2:48 AM Alexandru Elisei
> <alexandru.elisei at arm.com> wrote:
> >
> > Hi Reiji,
> >
> > On Sun, Jan 09, 2022 at 09:40:41PM -0800, Reiji Watanabe wrote:
> > > vcpu_allowed_register_width() checks if all the VCPUs are either
> > > all 32bit or all 64bit.  Since the checking is done even for vCPUs
> > > that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
> > > the non-initialized vCPUs are erroneously treated as 64bit vCPU,
> > > which causes the function to incorrectly detect a mixed-width VM.
> > >
> > > Fix vcpu_allowed_register_width() to skip the check for vCPUs that
> > > are not initialized yet.
> > >
> > > Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
> > > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > > ---
> > >  arch/arm64/kvm/reset.c | 11 +++++++++++
> > >  1 file changed, 11 insertions(+)
> > >
> > > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > > index 426bd7fbc3fd..ef78bbc7566a 100644
> > > --- a/arch/arm64/kvm/reset.c
> > > +++ b/arch/arm64/kvm/reset.c
> > > @@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> > >       if (kvm_has_mte(vcpu->kvm) && is32bit)
> > >               return false;
> > >
> > > +     /*
> > > +      * Make sure vcpu->arch.target setting is visible from others so
> > > +      * that the width consistency checking between two vCPUs is done
> > > +      * by at least one of them at KVM_ARM_VCPU_INIT.
> > > +      */
> > > +     smp_mb();
> >
> > From ARM DDI 0487G.a, page B2-146 ("Data Memory Barrier (DMB)"):
> >
> > "The DMB instruction is a memory barrier instruction that ensures the relative
> > order of memory accesses before the barrier with memory accesses after the
> > barrier."
> >
> > I'm going to assume from the comment that you are referring to completion of
> > memory accesses ("Make sure [..] is visible from others"). Please correct me if
> > I am wrong. In this case, DMB ensures ordering of memory accesses with regards
> > to writes and reads, not *completion*.  Have a look at
> > tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus for
> > the classic message passing example as an example of memory ordering.
> > Message passing and other patterns are also explained in ARM DDI 0487G.a, page
> > K11-8363.
> >
> > I'm not saying that your approach is incorrect, but the commit message should
> > explain what memory accesses are being ordered relative to each other and why.
> 
> Thank you so much for the review.
> What I meant with the comment was:
> ---
>   DMB is used to make sure that writing @vcpu->arch.target, which is done
>   by kvm_vcpu_set_target() before getting here, is visible to other PEs
>   before the following kvm_for_each_vcpu iteration reads the other vCPUs'
>   target field.
> ---
> Did the comment become more clear ?? (Or do I use DMB incorrectly ?)
> 
> > > +
> > >       /* Check that the vcpus are either all 32bit or all 64bit */
> > >       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> > > +             /* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> > > +             if (tmp->arch.target == -1)
> > > +                     continue;
> 
> I just noticed DMB(ishld) is needed here to assure ordering between
> reading tmp->arch.target and reading vcpu->arch.features for this fix.
> Similarly, kvm_vcpu_set_target() needs DMB(ishst) to assure ordering
> between writing vcpu->arch.features and writing vcpu->arch.target...
> I am going to fix them in the v2 series.

Yes, you'd need at least this, and preferably in their smp_rmb/wmb
variants.

However, this looks like a pretty fragile construct, as there are
multiple paths where we can change target (including some error
paths from the run loop).

I'd rather all changes to target and the feature bits happen under the
kvm->lock, and take that lock when checking for consistency in
vcpu_allowed_register_width(), as this isn't a fast path. I wrote the
following, which is obviously incomplete and as usual untested.

Thanks,

	M.

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e4727dc771bf..42f2ab80646c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1061,7 +1061,8 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
 static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 			       const struct kvm_vcpu_init *init)
 {
-	unsigned int i, ret;
+	unsigned int i;
+	int ret = 0;
 	u32 phys_target = kvm_target_cpu();
 
 	if (init->target != phys_target)
@@ -1074,32 +1075,46 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 	if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
 		return -EINVAL;
 
+	/* Hazard against a concurent check of the target in kvm_reset_vcpu() */
+	mutex_lock(&vcpu->kvm->lock);
+
 	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
 	for (i = 0; i < sizeof(init->features) * 8; i++) {
 		bool set = (init->features[i / 32] & (1 << (i % 32)));
 
-		if (set && i >= KVM_VCPU_MAX_FEATURES)
-			return -ENOENT;
+		if (set && i >= KVM_VCPU_MAX_FEATURES) {
+			ret = -ENOENT;
+			break;
+		}
 
 		/*
 		 * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
 		 * use the same feature set.
 		 */
 		if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES &&
-		    test_bit(i, vcpu->arch.features) != set)
-			return -EINVAL;
+		    test_bit(i, vcpu->arch.features) != set) {
+			ret = -EINVAL;
+			break;
+		}
 
 		if (set)
 			set_bit(i, vcpu->arch.features);
 	}
 
-	vcpu->arch.target = phys_target;
+	if (!ret)
+		vcpu->arch.target = phys_target;
+
+	mutex_unlock(&vcpu->kvm->lock);
+	if (ret)
+		return ret;
 
 	/* Now we know what it is, we can reset it. */
 	ret = kvm_reset_vcpu(vcpu);
 	if (ret) {
+		mutex_lock(&vcpu->kvm->lock);
 		vcpu->arch.target = -1;
 		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
+		mutex_unlock(&vcpu->kvm->lock);
 	}
 
 	return ret;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index ef78bbc7566a..fae88a703140 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -180,13 +180,6 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 	if (kvm_has_mte(vcpu->kvm) && is32bit)
 		return false;
 
-	/*
-	 * Make sure vcpu->arch.target setting is visible from others so
-	 * that the width consistency checking between two vCPUs is done
-	 * by at least one of them at KVM_ARM_VCPU_INIT.
-	 */
-	smp_mb();
-
 	/* Check that the vcpus are either all 32bit or all 64bit */
 	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
 		/* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
@@ -222,14 +215,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_reset_state reset_state;
-	int ret;
+	int ret = -EINVAL;
 	bool loaded;
 	u32 pstate;
 
 	mutex_lock(&vcpu->kvm->lock);
-	reset_state = vcpu->arch.reset_state;
-	WRITE_ONCE(vcpu->arch.reset_state.reset, false);
+	if (vcpu_allowed_register_width(vcpu)) {
+		reset_state = vcpu->arch.reset_state;
+		WRITE_ONCE(vcpu->arch.reset_state.reset, false);
+		ret = 0;
+	}
 	mutex_unlock(&vcpu->kvm->lock);
+	if (ret)
+		goto out;
 
 	/* Reset PMU outside of the non-preemptible section */
 	kvm_pmu_vcpu_reset(vcpu);
@@ -257,11 +255,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 		}
 	}
 
-	if (!vcpu_allowed_register_width(vcpu)) {
-		ret = -EINVAL;
-		goto out;
-	}
-
 	switch (vcpu->arch.target) {
 	default:
 		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {

-- 
Without deviation from the norm, progress is not possible.


From ada at thorsis.com  Tue Jan 11 05:34:41 2022
From: ada at thorsis.com (Alexander Dahl)
Date: Tue, 11 Jan 2022 14:34:41 +0100
Subject: [PATCH v2] ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
In-Reply-To: <20220111132301.906712-1-tudor.ambarus@microchip.com>
References: <20220111132301.906712-1-tudor.ambarus@microchip.com>
Message-ID: <2950776.PjgfHZTfyB@ada>

Hei hei,

Am Dienstag, 11. Januar 2022, 14:23:01 CET schrieb Tudor Ambarus:
> PMERRLOC resource size was set to 0x100, which resulted in HSMC_ERRLOCx
> register being truncated to offset x = 21, causing error correction to
> fail if more than 22 bit errors and if 24 or 32 bit error correction
> was supported.
> 
> Fixes: d9c41bf30cf8 ("ARM: dts: at91: Declare EBI/NAND controllers")
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> Cc: <stable at vger.kernel.org> # 4.13.x

Acked-by: Alexander Dahl <ada at thorsis.com>

Greets
Alex

> ---
> v2:
> - update commit description
> - Cc stable at vger.kernel.org
> 
>  arch/arm/boot/dts/sama5d2.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi
> index 09c741e8ecb8..c700c3b19e4c 100644
> --- a/arch/arm/boot/dts/sama5d2.dtsi
> +++ b/arch/arm/boot/dts/sama5d2.dtsi
> @@ -415,7 +415,7 @@ hsmc: hsmc at f8014000 {
>  				pmecc: ecc-engine at f8014070 {
>  					compatible = "atmel,sama5d2-pmecc";
>  					reg = <0xf8014070 0x490>,
> -					      <0xf8014500 0x100>;
> +					      <0xf8014500 0x200>;
>  				};
>  			};





From angelogioacchino.delregno at somainline.org  Tue Jan 11 05:41:41 2022
From: angelogioacchino.delregno at somainline.org (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:41:41 +0100
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <20220111112244.1483783-8-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-8-wenst@chromium.org>
Message-ID: <99ae1a61-7d12-f723-efb7-b26abb3811ef@somainline.org>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> Some of the MediaTek chips that utilize the Paris pinctrl driver library
> support a lower drive strength (<= 1mA) than the standard drive strength
> settings (2~16 mA) on certain pins. This was previously supported by the
> custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
> "mediatek,drive-strength-adv" device tree property.
> 
> The drive strength values for this hardware are 125, 250, 500, and 1000 mA,
> and can be readily described by the existing "drive-strength-microamp",
> which then gets parsed by the generic pinconf library into the parameter
> PIN_CONFIG_DRIVE_STRENGTH_UA.
> 
> Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
> custom parameter around for backward compatibility.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
> 
> The indentation in the switch/case blocks is getting somewhat out of
> control. I also have some cleanup changes to reverse the logic of the
> if/break statements. Not sure if it should be done before or after this
> patch though.

Hello Chen-Yu,

this commit is so nice that:
- My heart says that it's fine as it is, but
- My brain says that it makes a lot more sense if you push the cleanup
changes to reverse that logic before pushing this commit, as to reduce the
count of changed lines (hence, to reduce some noise)...

...so please, can you rebase this commit over the cleanups?

Thanks,
- Angelo

> 
> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 84 ++++++++++++++++++++++++
>   1 file changed, 84 insertions(+)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 678c8aa33012..5a94903ae372 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = {
>   	"func12", "func13", "func14", "func15",
>   };
>   
> +/*
> + * This section supports converting to/from custom MTK_PIN_CONFIG_DRV_ADV
> + * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs.
> + *
> + * The custom value encodes three hardware bits as follows:
> + *
> + *   |           Bits           |
> + *   | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA)
> + *   ------------------------------------------------
> + *   |    x   |    x   |    0   | disabled, use standard drive strength
> + *   -------------------------------------
> + *   |    0   |    0   |    1   |  125 uA
> + *   |    0   |    1   |    1   |  250 uA
> + *   |    1   |    0   |    1   |  500 uA
> + *   |    1   |    1   |    1   | 1000 uA
> + */
> +static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 };
> +
> +static int mtk_drv_adv_to_uA(int val)
> +{
> +	/* This should never happen. */
> +	if (WARN_ON_ONCE(val < 0 || val > 7))
> +		return -EINVAL;
> +
> +	/* Bit 0 simply enables this hardware part */
> +	if (!(val & BIT(0)))
> +		return -EINVAL;
> +
> +	return mtk_drv_adv_uA[(val >> 1)];
> +}
> +
> +static int mtk_drv_uA_to_adv(int val)
> +{
> +	switch (val) {
> +	case 125:
> +		return 0x1;
> +	case 250:
> +		return 0x3;
> +	case 500:
> +		return 0x5;
> +	case 1000:
> +		return 0x7;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>   static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
>   					  struct pinctrl_gpio_range *range,
>   					  unsigned int pin)
> @@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>   
>   		break;
>   	case PIN_CONFIG_DRIVE_STRENGTH:
> +		if (hw->soc->adv_drive_get) {
> +			err = hw->soc->adv_drive_get(hw, desc, &ret);
> +			if (!err) {
> +				err = mtk_drv_adv_to_uA(ret);
> +				if (err > 0) {
> +					/* PIN_CONFIG_DRIVE_STRENGTH_UA used */
> +					err = -EINVAL;
> +					break;
> +				}
> +			}
> +		}
> +
>   		if (hw->soc->drive_get)
>   			err = hw->soc->drive_get(hw, desc, &ret);
>   		else
>   			err = -ENOTSUPP;
>   		break;
> +	case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +		if (hw->soc->adv_drive_get) {
> +			err = hw->soc->adv_drive_get(hw, desc, &ret);
> +			if (err)
> +				break;
> +			err = mtk_drv_adv_to_uA(ret);
> +			if (err < 0)
> +				break;
> +
> +			ret = err;
> +			err = 0;
> +		} else {
> +			err = -ENOTSUPP;
> +		}
> +		break;
>   	case MTK_PIN_CONFIG_TDSEL:
>   	case MTK_PIN_CONFIG_RDSEL:
>   		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> @@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>   		else
>   			err = -ENOTSUPP;
>   		break;
> +	case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +		if (hw->soc->adv_drive_set) {
> +			err = mtk_drv_uA_to_adv(arg);
> +			if (err < 0)
> +				break;
> +			err = hw->soc->adv_drive_set(hw, desc, err);
> +		} else {
> +			err = -ENOTSUPP;
> +		}
> +		break;
>   	case MTK_PIN_CONFIG_TDSEL:
>   	case MTK_PIN_CONFIG_RDSEL:
>   		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> 



From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:41:52 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:41:52 +0100
Subject: [PATCH 6/7] pinctrl: mediatek: paris: Skip custom extra pin
 config dump for vrtual GPIOs
In-Reply-To: <20220111112244.1483783-7-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-7-wenst@chromium.org>
Message-ID: <a8251721-9df2-8bea-11fd-87806d70f444@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> Virtual GPIOs do not have any hardware state associated with them. Any
> attempt to read back hardware state for these pins result in error
> codes.
> 
> Skip dumping extra pin config information for these virtual GPIOs.
> 
> Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Can you please fix the typo in the commit title? "vrtual"->"virtual"

After the typo fix:

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Thank you!

> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 3 +++
>   1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 1bacabfbc183..678c8aa33012 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -585,6 +585,9 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
>   	if (gpio >= hw->soc->npins)
>   		return -EINVAL;
>   
> +	if (mtk_is_virt_gpio(hw, gpio))
> +		return -EINVAL;
> +
>   	desc = (const struct mtk_pin_desc *)&hw->soc->pins[gpio];
>   	pinmux = mtk_pctrl_get_pinmux(hw, gpio);
>   	if (pinmux >= hw->soc->nfuncs)
> 



From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:17 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:17 +0100
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_DISABLE
 readback
In-Reply-To: <20220111112244.1483783-3-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-3-wenst@chromium.org>
Message-ID: <8ca8dd15-30c3-a89e-9a18-c8b8788e0904@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> When reading back pin bias settings, if the pin is not in a
> bias-disabled state, the function should return -EINVAL.
> 
> Fix this in the mediatek-paris pinctrl library so that the read back
> state is not littered with bogus a "input bias disabled" combined with
> "pull up" or "pull down" states.
> 
> Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index f9f9110f2107..1ca598ea7ba7 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -97,8 +97,8 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>   			if (err)
>   				goto out;
>   			if (param == PIN_CONFIG_BIAS_DISABLE) {
> -				if (ret == MTK_PUPD_SET_R1R0_00)
> -					ret = MTK_DISABLE;
> +				if (ret != MTK_PUPD_SET_R1R0_00)
> +					err = -EINVAL;
>   			} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
>   				/* When desire to get pull-up value, return
>   				 *  error if current setting is pull-down
> 


From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:19 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:19 +0100
Subject: [PATCH 5/7] pinctrl: mediatek: paris: Drop extra newline in
 mtk_pctrl_show_one_pin()
In-Reply-To: <20220111112244.1483783-6-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-6-wenst@chromium.org>
Message-ID: <82271a06-d9cb-efd0-57f1-b0bab847f826@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> The caller of mtk_pctrl_show_one_pin() is responsible for printing the
> full line. mtk_pctrl_show_one_pin(), called through mtk_pctrl_dbg_show(),
> should only produce a string containing the extra information the driver
> wants included.
> 
> Drop the extra newlines.
> 
> Fixes: 184d8e13f9b1 ("pinctrl: mediatek: Add support for pin configuration dump via debugfs.")
> Fixes: fb34a9ae383a ("pinctrl: mediatek: support rsel feature")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 6 ++----
>   1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index d259f075c62d..1bacabfbc183 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -639,12 +639,10 @@ ssize_t mtk_pctrl_show_one_pin(struct mtk_pinctrl *hw,
>   			pullup);
>   
>   	if (r1 != -1) {
> -		len += scnprintf(buf + len, buf_len - len, " (%1d %1d)\n",
> +		len += scnprintf(buf + len, buf_len - len, " (%1d %1d)",
>   			r1, r0);

Since you're doing also some nice cleanups, would you mind un-breaking the line
above? That'd be 82 columns, which is fine to have.

In any case:


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

>   	} else if (rsel != -1) {
> -		len += scnprintf(buf + len, buf_len - len, " (%1d)\n", rsel);
> -	} else {
> -		len += scnprintf(buf + len, buf_len - len, "\n");
> +		len += scnprintf(buf + len, buf_len - len, " (%1d)", rsel);
>   	}
>   
>   	return len;
> 


From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:23 +0100
Subject: [PATCH 4/7] pinctrl: mediatek: paris: Fix pingroup pin config
 state readback
In-Reply-To: <20220111112244.1483783-5-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-5-wenst@chromium.org>
Message-ID: <97f46bb0-b446-92da-a83c-751f8b918570@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> mtk_pconf_group_get(), used to read back pingroup pin config state,
> simply returns a set of configs saved from a previous invocation of
> mtk_pconf_group_set(). This is an unfiltered, unvalidated set passed
> in from the pinconf core, which does not match the current hardware
> state.
> 
> Since the driver library is designed to have a pin per group, pass
> through mtk_pconf_group_get() to mtk_pinconf_get(), to read back
> the current pin config state of the only pin in the group.
> 
> Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index d720624d8cd2..d259f075c62d 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -736,10 +736,10 @@ static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, unsigned group,
>   			       unsigned long *config)
>   {
>   	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
> +	struct mtk_pinctrl_group *grp = &hw->groups[group];
>   
> -	*config = hw->groups[group].config;
> -
> -	return 0;
> +	 /* One pin per group only */
> +	return mtk_pinconf_get(pctldev, grp->pin, config);
>   }
>   
>   static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group,
> 


From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:26 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:26 +0100
Subject: [PATCH 3/7] pinctrl: mediatek: paris: Fix "argument" argument
 type for mtk_pinconf_get()
In-Reply-To: <20220111112244.1483783-4-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-4-wenst@chromium.org>
Message-ID: <f6114de8-940b-558f-a231-2c960e113fc3@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> For mtk_pinconf_get(), the "argument" argument is typically returned by
> pinconf_to_config_argument(), which holds the value for a given pinconf
> parameter. It certainly should not have the type of "enum pin_config_param",
> which describes the type of the pinconf parameter itself.
> 
> Change the type to u32, which matches the return type of
> pinconf_to_config_argument().
> 
> Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that implements the vendor dt-bindings")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>



Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/pinctrl/mediatek/pinctrl-paris.c | 3 +--
>   1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 1ca598ea7ba7..d720624d8cd2 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -188,8 +188,7 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>   }
>   
>   static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
> -			   enum pin_config_param param,
> -			   enum pin_config_param arg)
> +			   enum pin_config_param param, u32 arg)
>   {
>   	struct mtk_pinctrl *hw = pinctrl_dev_get_drvdata(pctldev);
>   	const struct mtk_pin_desc *desc;
> 


From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:27 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:27 +0100
Subject: [PATCH 1/7] pinctrl: pinconf-generic: Print arguments for
 bias-pull-*
In-Reply-To: <20220111112244.1483783-2-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-2-wenst@chromium.org>
Message-ID: <2dc957b1-300f-161c-edb6-efacf11942e0@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> The bias-pull-* properties, or PIN_CONFIG_BIAS_PULL_* pin config
> parameters, accept optional arguments in ohms denoting the strength of
> the pin bias.
> 
> Print these values out in debugfs as well.
> 
> Fixes: eec450713e5c ("pinctrl: pinconf-generic: Add flag to print arguments")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Tested on qcom-SC7180 Trogdor, mtk-MT8173 Elm, and others;

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/pinctrl/pinconf-generic.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c
> index f8edcc88ac01..415d1df8f46a 100644
> --- a/drivers/pinctrl/pinconf-generic.c
> +++ b/drivers/pinctrl/pinconf-generic.c
> @@ -30,10 +30,10 @@ static const struct pin_config_item conf_items[] = {
>   	PCONFDUMP(PIN_CONFIG_BIAS_BUS_HOLD, "input bias bus hold", NULL, false),
>   	PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL, false),
>   	PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL, false),
> -	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL, false),
> +	PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", "ohms", true),
>   	PCONFDUMP(PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
> -				"input bias pull to pin specific state", NULL, false),
> -	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL, false),
> +				"input bias pull to pin specific state", "ohms", true),
> +	PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", "ohms", true),
>   	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL, false),
>   	PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL, false),
>   	PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL, false),
> 



From angelogioacchino.delregno at collabora.com  Tue Jan 11 05:42:50 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 11 Jan 2022 14:42:50 +0100
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <20220111112244.1483783-8-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-8-wenst@chromium.org>
Message-ID: <8a5aba82-d9e3-25d8-f34e-7182586d8ce4@collabora.com>

Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> Some of the MediaTek chips that utilize the Paris pinctrl driver library
> support a lower drive strength (<= 1mA) than the standard drive strength
> settings (2~16 mA) on certain pins. This was previously supported by the
> custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
> "mediatek,drive-strength-adv" device tree property.
> 
> The drive strength values for this hardware are 125, 250, 500, and 1000 mA,
> and can be readily described by the existing "drive-strength-microamp",
> which then gets parsed by the generic pinconf library into the parameter
> PIN_CONFIG_DRIVE_STRENGTH_UA.
> 
> Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
> custom parameter around for backward compatibility.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
> 
> The indentation in the switch/case blocks is getting somewhat out of
> control. I also have some cleanup changes to reverse the logic of the
> if/break statements. Not sure if it should be done before or after this
> patch though.

Hello Chen-Yu,



this commit is so nice that:

- My heart says that it's fine as it is, but

- My brain says that it makes a lot more sense if you push the cleanup

changes to reverse that logic before pushing this commit, as to reduce the

count of changed lines (hence, to reduce some noise)...



...so please, can you rebase this commit over the cleanups?



Thanks,

- Angelo



From christian.gmeiner at gmail.com  Tue Jan 11 05:45:48 2022
From: christian.gmeiner at gmail.com (Christian Gmeiner)
Date: Tue, 11 Jan 2022 14:45:48 +0100
Subject: [PATCH] arm64: dts: ti: k3-am64-main: add RTI watdog nodes
Message-ID: <20220111134552.800704-1-christian.gmeiner@gmail.com>

Add the needed bus mappings for the two main RTI memory ranges and
the required device tree nodes in the main domain.

Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
 arch/arm64/boot/dts/ti/k3-am64-main.dtsi | 18 ++++++++++++++++++
 arch/arm64/boot/dts/ti/k3-am64.dtsi      |  2 ++
 2 files changed, 20 insertions(+)

diff --git a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
index 5ad638b95ffc..83cd48144789 100644
--- a/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -974,6 +974,24 @@ ecap2: pwm at 23120000 {
 		clock-names = "fck";
 	};
 
+	main_rti0: watchdog at e000000 {
+			compatible = "ti,j7-rti-wdt";
+			reg = <0x00 0xe000000 0x00 0x100>;
+			clocks = <&k3_clks 125 0>;
+			power-domains = <&k3_pds 125 TI_SCI_PD_EXCLUSIVE>;
+			assigned-clocks = <&k3_clks 125 0>;
+			assigned-clock-parents = <&k3_clks 125 2>;
+	};
+
+	main_rti1: watchdog at e010000 {
+			compatible = "ti,j7-rti-wdt";
+			reg = <0x00 0xe010000 0x00 0x100>;
+			clocks = <&k3_clks 126 0>;
+			power-domains = <&k3_pds 126 TI_SCI_PD_EXCLUSIVE>;
+			assigned-clocks = <&k3_clks 126 0>;
+			assigned-clock-parents = <&k3_clks 126 2>;
+	};
+
 	icssg0: icssg at 30000000 {
 		compatible = "ti,am642-icssg";
 		reg = <0x00 0x30000000 0x00 0x80000>;
diff --git a/arch/arm64/boot/dts/ti/k3-am64.dtsi b/arch/arm64/boot/dts/ti/k3-am64.dtsi
index 120974726be8..84bd07cd1824 100644
--- a/arch/arm64/boot/dts/ti/k3-am64.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-am64.dtsi
@@ -71,6 +71,8 @@ cbass_main: bus at f4000 {
 			 <0x00 0x01000000 0x00 0x01000000 0x00 0x02330400>, /* First peripheral window */
 			 <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */
 			 <0x00 0x0d000000 0x00 0x0d000000 0x00 0x00800000>, /* PCIE_CORE */
+			 <0x00 0x0e000000 0x00 0x0e000000 0x00 0x00000100>, /* Main RTI0 */
+			 <0x00 0x0e010000 0x00 0x0e010000 0x00 0x00000100>, /* Main RTI1 */
 			 <0x00 0x0f000000 0x00 0x0f000000 0x00 0x00c44200>, /* Second peripheral window */
 			 <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */
 			 <0x00 0x30000000 0x00 0x30000000 0x00 0x000bc100>, /* ICSSG0/1 */
-- 
2.34.1



From will at kernel.org  Tue Jan 11 06:19:02 2022
From: will at kernel.org (Will Deacon)
Date: Tue, 11 Jan 2022 14:19:02 +0000
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <Ydfq051mnCeZjG3G@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
 <20220105104526.GA3015@willie-the-truck>
 <YdYDzKvYbBwjfU3W@google.com>
 <20220106103009.GA4420@willie-the-truck>
 <Ydfq051mnCeZjG3G@google.com>
Message-ID: <20220111141901.GA10338@willie-the-truck>

On Fri, Jan 07, 2022 at 12:25:07AM -0700, Yu Zhao wrote:
> On Thu, Jan 06, 2022 at 10:30:09AM +0000, Will Deacon wrote:
> > On Wed, Jan 05, 2022 at 01:47:08PM -0700, Yu Zhao wrote:
> > > On Wed, Jan 05, 2022 at 10:45:26AM +0000, Will Deacon wrote:
> > > > On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> > > > > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > > > > index 870c39537dd0..56e4ef5d95fa 100644
> > > > > --- a/arch/arm64/tools/cpucaps
> > > > > +++ b/arch/arm64/tools/cpucaps
> > > > > @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
> > > > >  HAS_SYSREG_GIC_CPUIF
> > > > >  HAS_TLB_RANGE
> > > > >  HAS_VIRT_HOST_EXTN
> > > > > +HW_AF
> > > > >  HW_DBM
> > > > >  KVM_PROTECTED_MODE
> > > > >  MISMATCHED_CACHE_TYPE
> > > > 
> > > > As discussed in the previous threads, we really don't need the complexity
> > > > of the additional cap for the arm64 part. Please can you just use the
> > > > existing code instead? It's both simpler and, as you say, it's equivalent
> > > > for existing hardware.
> > > > 
> > > > That way, this patch just ends up being a renaming exercise and we're all
> > > > good.
> > > 
> > > No, renaming alone isn't enough. A caller needs to disable preemption
> > > before calling system_has_hw_af(), and I don't think it's reasonable
> > > to ask this caller to do it on x86 as well.
> > > 
> > > It seems you really prefer not to have HW_AF. So the best I can
> > > accommodate, considering other potential archs, e.g., risc-v (I do
> > > plan to provide benchmark results on risc-v, btw), is:
> > > 
> > >   static inline bool arch_has_hw_pte_young(bool local)
> > >   {
> > > 	bool hw_af;
> > > 
> > >   	if (local) {
> > >   		WARN_ON(preemptible());
> > >   		return cpu_has_hw_af();
> > >   	}
> > >   
> > > 	preempt_disable();
> > >   	hw_af = system_has_hw_af();
> > > 	preempt_enable();
> > > 
> > > 	return hw_af;
> > >   }
> > > 
> > > Or please give me something else I can call without disabling
> > > preemption, sounds good?
> > 
> > Sure thing, let me take a look. Do you have your series on a public git
> > tree someplace?
> 
> Thanks!
> 
> This patch (updated) on Gerrit:
> https://linux-mm-review.googlesource.com/c/page-reclaim/+/1500/1

How about folding in something like the diff below? I've basically removed
that 'bool local' argument and dropped the preemptible() check from the
arm64 code.

Will

--->8

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 280123916fc2..990358eca359 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -998,27 +998,14 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  * the pte is old and cannot be marked young. So we always end up with zeroed
  * page after fork() + CoW for pfn mappings. We don't always have a
  * hardware-managed access flag on arm64.
- *
- * The system-wide support isn't used when involving correctness and therefore
- * is allowed to be flaky.
  */
-static inline bool arch_has_hw_pte_young(bool local)
-{
-	WARN_ON(local && preemptible());
-
-	return cpu_has_hw_af();
-}
-#define arch_has_hw_pte_young		arch_has_hw_pte_young
+#define arch_has_hw_pte_young		cpu_has_hw_af
 
 /*
  * Experimentally, it's cheap to set the access flag in hardware and we
  * benefit from prefaulting mappings as 'old' to start with.
  */
-static inline bool arch_wants_old_prefaulted_pte(void)
-{
-	return arch_has_hw_pte_young(true);
-}
-#define arch_wants_old_prefaulted_pte	arch_wants_old_prefaulted_pte
+#define arch_wants_old_prefaulted_pte	cpu_has_hw_af
 
 static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
 {
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index c60b16f8b741..3908780fc408 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -1398,7 +1398,7 @@ static inline bool arch_has_pfn_modify_check(void)
 }
 
 #define arch_has_hw_pte_young arch_has_hw_pte_young
-static inline bool arch_has_hw_pte_young(bool local)
+static inline bool arch_has_hw_pte_young(void)
 {
 	return true;
 }
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 599cc232d5c4..0bd1beadb545 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -260,15 +260,12 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma,
 
 #ifndef arch_has_hw_pte_young
 /*
- * Return whether the accessed bit is supported by the local CPU or system-wide.
+ * Return whether the accessed bit is supported by the local CPU.
  *
- * This stub assumes accessing thru an old PTE triggers a page fault.
+ * This stub assumes accessing through an old PTE triggers a page fault.
  * Architectures that automatically set the access bit should overwrite it.
- *
- * Note that the system-wide support can be flaky and therefore shouldn't be
- * used when involving correctness.
  */
-static inline bool arch_has_hw_pte_young(bool local)
+static inline bool arch_has_hw_pte_young(void)
 {
 	return false;
 }
diff --git a/mm/memory.c b/mm/memory.c
index ead6c7d4b9a1..1f02de6d51e4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2743,7 +2743,7 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
 	 * On architectures with software "accessed" bits, we would
 	 * take a double page fault, so mark it accessed here.
 	 */
-	if (!arch_has_hw_pte_young(true) && !pte_young(vmf->orig_pte)) {
+	if (!arch_has_hw_pte_young() && !pte_young(vmf->orig_pte)) {
 		pte_t entry;
 
 		vmf->pte = pte_offset_map_lock(mm, vmf->pmd, addr, &vmf->ptl);


From admin at hifiphile.com  Tue Jan 11 06:20:50 2022
From: admin at hifiphile.com (Zixun LI)
Date: Tue, 11 Jan 2022 14:20:50 +0000
Subject: [PATCH] clk: at91: allow setting PMC_AUDIOPINCK clock parents via DT
Message-ID: <20220111142051.37957-1-admin@hifiphile.com>

Make AUDIOPINCK accessible via phandle to select it
as peripheral clock parent using assigned-clock-parents in DT
where available.

Signed-off-by: Zixun LI <admin at hifiphile.com>
Reviewed-by: Claudiu Beznea <Claudiu.Beznea at microchip.com>
---
 drivers/clk/at91/sama5d2.c       | 4 +++-
 include/dt-bindings/clock/at91.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c
index d027294a0089..f479e39e3bb2 100644
--- a/drivers/clk/at91/sama5d2.c
+++ b/drivers/clk/at91/sama5d2.c
@@ -168,7 +168,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	if (IS_ERR(regmap))
 		return;
 
-	sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPLLCK + 1,
+	sama5d2_pmc = pmc_data_allocate(PMC_AUDIOPINCK + 1,
 					nck(sama5d2_systemck),
 					nck(sama5d2_periph32ck),
 					nck(sama5d2_gck), 3);
@@ -216,6 +216,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
 	if (IS_ERR(hw))
 		goto err_free;
 
+	sama5d2_pmc->chws[PMC_AUDIOPINCK] = hw;
+
 	hw = at91_clk_register_audio_pll_pmc(regmap, "audiopll_pmcck",
 					     "audiopll_fracck");
 	if (IS_ERR(hw))
diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
index 98e1b2ab6403..573cf8c25eb4 100644
--- a/include/dt-bindings/clock/at91.h
+++ b/include/dt-bindings/clock/at91.h
@@ -24,6 +24,7 @@
 #define PMC_PLLACK		7
 #define PMC_PLLBCK		8
 #define PMC_AUDIOPLLCK		9
+#define PMC_AUDIOPINCK		10
 
 /* SAMA7G5 */
 #define PMC_CPUPLL		(PMC_MAIN + 1)
-- 
2.30.2



From hakavlad at inbox.lv  Tue Jan 11 06:22:48 2022
From: hakavlad at inbox.lv (Alexey Avramov)
Date: Tue, 11 Jan 2022 23:22:48 +0900
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydg8AeE6JIUnC+ps@dhcp22.suse.cz> <YdjOazilBEkdUT7x@google.com>
 <YdxSUuDc3OC4pe+f@dhcp22.suse.cz>
Message-ID: <20220111232248.1629f794@mail.inbox.lv>

> I do not really see any arguments why an userspace based trashing
> detection cannot be used for those.

Firsly,
because this is the task of the kernel, not the user space. 
Memory is managed by the kernel, not by the user space. 
The absence of such a mechanism in the kernel is a fundamental problem.
The userspace tools are ugly hacks:
some of them consume a lot of CPU [1], 
some of them consume a lot of memory [2], 
some of them cannot into process_mrelease() (earlyoom, nohang), 
some of them kill only the whole cgroup (systemd-oomd, oomd) [3]
and depends on systemd and cgroup_v2 (oomd, systemd-oomd).
One of the biggest challenges for userspace oom-killers is to potentially
function under intense memory pressure and are prone to getting stuck in
memory reclaim themselves [4].

It is strange that after decades of user complaints about thrashing and
not-working OOM killer I have to explain the obvious things.
The basic mechanism must be implemented in the kernel.
Stop shifting responsibility to the user space!

Secondly,
the real reason for the min_ttl_ms mechanism is that without it, 
multi-minute stalls are possible [5] even when the killer is expected to
arrive, and memory pressure is closed to 100 at this period [6].
This fixes a bug that does not exist in the mainline LRU (this is
MGLRU-specific bug). BTW, the similar symptoms were recently fixed in the
mainline [7].

[1] https://github.com/facebookincubator/oomd/issues/79
[2] https://github.com/hakavlad/nohang#memory-and-cpu-usage
[3] https://github.com/facebookincubator/oomd/issues/125
[4] https://lore.kernel.org/all/CALvZod7vtDxJZtNhn81V=oE-EPOf=4KZB2Bv6Giz+u3bFFyOLg at mail.gmail.com/
[5] https://github.com/zen-kernel/zen-kernel/issues/223
[6] https://raw.githubusercontent.com/hakavlad/cache-tests/main/mg-LRU-v3_vs_classic-LRU/3-firefox-tail-OOM/mg-LRU-1/psi2
[7] https://lore.kernel.org/linux-mm/20211202150614.22440-1-mgorman at techsingularity.net/

[I am duplicating a previous message here - it was not delivered to mailing lists]


From robin.murphy at arm.com  Tue Jan 11 06:38:28 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 11 Jan 2022 14:38:28 +0000
Subject: [bootwrapper PATCH 06/13] aarch64: initialize SCTLR_ELx for the
 boot-wrapper
In-Reply-To: <20220111130653.2331827-7-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-7-mark.rutland@arm.com>
Message-ID: <a3010a0b-c740-da2d-c948-fedbdbec3322@arm.com>

On 2022-01-11 13:06, Mark Rutland wrote:
> The SCTLR_ELx registers contain fields which are UNKNOWN or
> IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
> defines the endianness of memory accesses (e.g. reads from literal
> pools). Due to this, portions of boot-wrapper code are not guaranteed
> top work correctly.

Nit: "to"

> Rework the startup code to explicitly initialize SCTLR_ELx for the
> exception level the boot-wrapper was entered at. When entered at EL2
> it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
> behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
> which would break the initialization performed in jump_kernel.
> 
> As we plan to eventually support the highest implemented EL being any of
> EL3/EL2/EL1, code is added to handle all of these exception levels, even
> though we do not currently support starting at EL1.
> 
> We'll initialize other registers in subsequent patches.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

[...]

> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 1053414..f0edd2a 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -14,6 +14,32 @@
>   #define MPIDR_ID_BITS		0xff00ffffff
>   
>   #define CURRENTEL_EL3		(3 << 2)
> +#define CURRENTEL_EL2		(2 << 2)
> +#define CURRENTEL_EL1		(1 << 2)
> +
> +/*
> + * RES1 bit definitions definitions as of ARM DDI 0487G.b
> + *
> + * These includes bits which are RES1 in some configurations.
> + */
> +#define SCTLR_EL3_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> +				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
> +
> +#define SCTLR_EL2_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> +				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
> +
> +#define SCTLR_EL1_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> +				 1 << 11 | 1 << 8 | 1 << 7 | 1 << 4)
> +
> +#define HCR_EL2_RES1		(1 << 1)

Maybe use the new BIT() macro in these? I reckon that would be more 
readable overall.

Robin.

> +
> +/*
> + * Initial register values required for the boot-wrapper to run out-of-reset.
> + */
> +#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
> +#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
> +#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
> +#define HCR_EL2_RESET		HCR_EL2_RES1
>   
>   #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
>   


From robin.murphy at arm.com  Tue Jan 11 06:39:35 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 11 Jan 2022 14:39:35 +0000
Subject: [bootwrapper PATCH 13/13] Unify start_el3 & start_no_el3
In-Reply-To: <20220111130653.2331827-14-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-14-mark.rutland@arm.com>
Message-ID: <91231c75-3f47-1106-a740-1fee40d4b7b5@arm.com>

On 2022-01-11 13:06, Mark Rutland wrote:
> Now that the start_el3 and start_no_el3 labels point at the same place,
> unify them into a start_bootmethod label and update callers.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>   arch/aarch32/boot.S | 5 ++---
>   arch/aarch64/boot.S | 4 ++--
>   arch/aarch64/psci.S | 3 +--
>   3 files changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 820957b..4d16c9c 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -51,7 +51,7 @@ ASM_FUNC(_start)
>   
>   	bl	cpu_init_bootwrapper
>   
> -	b	start_no_el3
> +	b	start_bootmethod
>   
>   _switch_monitor:
>   	adr	lr, _monitor
> @@ -69,8 +69,7 @@ _monitor:
>   
>   	bl	gic_secure_init
>   
> -	/* Initialise boot method */
> -	b	start_el3
> +	b	start_bootmethod
>   
>   err_invalid_id:
>   	b	.
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index c0ec518..da5fa65 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -57,7 +57,7 @@ reset_at_el3:
>   
>   	bl	gic_secure_init
>   
> -	b	start_el3
> +	b	start_bootmethod
>   
>   	/*
>   	 * EL2 initialization
> @@ -97,7 +97,7 @@ reset_no_el3:
>   
>   	bl	cpu_init_bootwrapper
>   
> -	b	start_no_el3
> +	b	start_bootmethod
>   
>   err_invalid_id:
>   	b	.
> diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> index d6ca2eb..9709dbb 100644
> --- a/arch/aarch64/psci.S
> +++ b/arch/aarch64/psci.S
> @@ -79,6 +79,5 @@ smc_exit:
>   	ldp	x18, x19, [sp], #16
>   	eret
>   
> -ASM_FUNC(start_el3)
> -ASM_FUNC(start_no_el3)
> +ASM_FUNC(start_bootmethod)

Should there be an equivalent of this hunk for arch/aarch32/psci.S?

Robin.

>   	b	psci_first_spin


From andre.przywara at arm.com  Tue Jan 11 06:40:48 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 11 Jan 2022 14:40:48 +0000
Subject: [bootwrapper PATCH 02/13] Add bit-field macros
In-Reply-To: <20220111130653.2331827-3-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-3-mark.rutland@arm.com>
Message-ID: <20220111144048.2675076e@donnerap.cambridge.arm.com>

On Tue, 11 Jan 2022 13:06:42 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> Arm architectural documentation typically defines bit-fields as
> `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> helpful if we could define fields in the same way.
> 
> Add helpers so that we can do so, along with helper to extract/insert
> bit-field values.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  include/bits.h | 33 +++++++++++++++++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100644 include/bits.h
> 
> diff --git a/include/bits.h b/include/bits.h
> new file mode 100644
> index 0000000..8824a38
> --- /dev/null
> +++ b/include/bits.h
> @@ -0,0 +1,33 @@
> +/*
> + * include/bits.h - helpers for bit-field definitions.
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __BITS_H
> +#define __BITS_H
> +
> +#ifdef __ASSEMBLY__
> +#define UL(x)	x
> +#define ULL(x)	x
> +#else
> +#define UL(x)	x##UL
> +#define ULL(x)	x##ULL
> +#endif
> +
> +#define BITS(msb, lsb) \

The kernel uses GENMASK() for this, should we follow suit here? Both
U-Boot and Trusted Firmware decided to do so, so I consider this some kind
of agreed naming for bitmask generation these days.

> +((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
> +
> +#define BIT(b)	BITS(b, b)
> +
> +#define BITS_LSB(bits)	(__builtin_ffsll(bits) - 1)

Shall there be some comment explaining the functionality and arguments? Or
maybe use "mask" instead of the more ambiguous "bits" name here?
TBH I needed to read the implementation of the next macro to understand
what it does.

> +
> +#define BITS_EXTRACT(val, bits) \

Same here, having BITS_EXTRACT(val, mask) looks more readable to me.

Cheers,
Andre

> +	(((val) & (bits)) >> BITS_LSB(bits))
> +
> +#define BITS_INSERT(bits, val) \
> +	(((val) << BITS_LSB(bits)) & (bits))
> +
> +#endif



From andre.przywara at arm.com  Tue Jan 11 06:41:49 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 11 Jan 2022 14:41:49 +0000
Subject: [bootwrapper PATCH 05/13] aarch64: add mov_64 macro
In-Reply-To: <20220111130653.2331827-6-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-6-mark.rutland@arm.com>
Message-ID: <20220111144149.6b519ede@donnerap.cambridge.arm.com>

On Tue, 11 Jan 2022 13:06:45 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> In subsequent patches we'll need to load 64-bit values into GPRs before
> the CPU is in a known endianness, where we cannot use literal pools.
> 
> In preparation for that, this patch adds a new `mov_64` macro to load a
> 64-bit value into a GPR using a sequence of MOV and MOVKs, which will
> function the same regardless of the CPU's endianness.
> 
> At the same time, move the `cpuid` macro to use `mov_64` internally.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  arch/aarch64/common.S | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
> index c7171a9..3279fa9 100644
> --- a/arch/aarch64/common.S
> +++ b/arch/aarch64/common.S
> @@ -9,9 +9,17 @@
>  
>  #include <cpu.h>
>  
> +	/* Load a 64-bit value using immediates */
> +	.macro	mov_64 dest, val
> +	mov	\dest, #(((\val) >>  0) & 0xffff)
> +	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
> +	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
> +	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
> +	.endm
> +

Trusted Firmware has an (admittedly more complicated) version that only
uses as many instructions as needed, by skipping over halfwords that are
zero:
https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/include/arch/aarch64/asm_macros.S#n125

Does that sound useful for us?

Cheers,
Andre

>  	/* Put MPIDR into \dest, clobber \tmp and flags */
>  	.macro cpuid dest, tmp
>  	mrs	\dest, mpidr_el1
> -	ldr	\tmp, =MPIDR_ID_BITS
> +	mov_64	\tmp, MPIDR_ID_BITS
>  	ands	\dest, \dest, \tmp
>  	.endm



From l.stelmach at samsung.com  Tue Jan 11 06:49:06 2022
From: l.stelmach at samsung.com (Lukasz Stelmach)
Date: Tue, 11 Jan 2022 15:49:06 +0100
Subject: [PATCH v2 11/13] media: s5p-g2d: Use platform_get_irq() to get
 the interrupt
In-Reply-To: <20220111002314.15213-12-prabhakar.mahadev-lad.rj@bp.renesas.com>
 (Lad Prabhakar's message of "Tue, 11 Jan 2022 00:23:12 +0000")
References: <20220111002314.15213-12-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CGME20220111144930eucas1p1d538f02d731983b1cd1b56472163eda4@eucas1p1.samsung.com>
Message-ID: <dleftjtuea8h0d.fsf%l.stelmach@samsung.com>

It was <2022-01-11 wto 00:23>, when Lad Prabhakar wrote:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v1->v2
> * No change.
> ---
>  drivers/media/platform/s5p-g2d/g2d.c | 10 +++-------
>  1 file changed, 3 insertions(+), 7 deletions(-)
>

Acked-by: ?ukasz Stelmach <l.stelmach at samsung.com>

> diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c
> index fa0bb31bd2b9..dd8864779a7c 100644
> --- a/drivers/media/platform/s5p-g2d/g2d.c
> +++ b/drivers/media/platform/s5p-g2d/g2d.c
> @@ -623,7 +623,6 @@ static int g2d_probe(struct platform_device *pdev)
>  {
>  	struct g2d_dev *dev;
>  	struct video_device *vfd;
> -	struct resource *res;
>  	const struct of_device_id *of_id;
>  	int ret = 0;
>  
> @@ -664,14 +663,11 @@ static int g2d_probe(struct platform_device *pdev)
>  		goto put_clk_gate;
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (!res) {
> -		dev_err(&pdev->dev, "failed to find IRQ\n");
> -		ret = -ENXIO;
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
>  		goto unprep_clk_gate;
> -	}
>  
> -	dev->irq = res->start;
> +	dev->irq = ret;
>  
>  	ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
>  						0, pdev->name, dev);

-- 
?ukasz Stelmach
Samsung R&D Institute Poland
Samsung Electronics
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/eb1c6b23/attachment.sig>

From john.p.donnelly at oracle.com  Tue Jan 11 07:03:22 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:03:22 -0600
Subject: [PATCH v19 01/13] kdump: add helper parse_crashkernel_high_low()
In-Reply-To: <20211228132612.1860-2-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-2-thunder.leizhen@huawei.com>
Message-ID: <7f420af1-9fce-5a36-5788-8de52502781f@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> The bootup command line option crashkernel=Y,low is valid only when
> crashkernel=X,high is specified. Putting their parsing into a separate
> function makes the code logic clearer and easier to understand the strong
> dependencies between them.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   include/linux/crash_core.h |  3 +++
>   kernel/crash_core.c        | 35 +++++++++++++++++++++++++++++++++++
>   2 files changed, 38 insertions(+)
> 
> diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> index de62a722431e7db..2d3a64761d18998 100644
> --- a/include/linux/crash_core.h
> +++ b/include/linux/crash_core.h
> @@ -83,5 +83,8 @@ int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
>   		unsigned long long *crash_size, unsigned long long *crash_base);
>   int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
>   		unsigned long long *crash_size, unsigned long long *crash_base);
> +int __init parse_crashkernel_high_low(char *cmdline,
> +				      unsigned long long *high_size,
> +				      unsigned long long *low_size);
>   
>   #endif /* LINUX_CRASH_CORE_H */
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index eb53f5ec62c900f..8966beaf7c4fd52 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -295,6 +295,41 @@ int __init parse_crashkernel_low(char *cmdline,
>   				"crashkernel=", suffix_tbl[SUFFIX_LOW]);
>   }
>   
> +/**
> + * parse_crashkernel_high_low - Parsing "crashkernel=X,high" and possible
> + *				"crashkernel=Y,low".
> + * @cmdline:	The bootup command line.
> + * @high_size:	Save the memory size specified by "crashkernel=X,high".
> + * @low_size:	Save the memory size specified by "crashkernel=Y,low" or "-1"
> + *		if it's not specified.
> + *
> + * Returns 0 on success, else a negative status code.
> + */
> +int __init parse_crashkernel_high_low(char *cmdline,
> +				      unsigned long long *high_size,
> +				      unsigned long long *low_size)
> +{
> +	int ret;
> +	unsigned long long base;
> +
> +	BUG_ON(!high_size || !low_size);
> +
> +	/* crashkernel=X,high */
> +	ret = parse_crashkernel_high(cmdline, 0, high_size, &base);
> +	if (ret)
> +		return ret;
> +
> +	if (*high_size <= 0)
> +		return -EINVAL;
> +
> +	/* crashkernel=Y,low */
> +	ret = parse_crashkernel_low(cmdline, 0, low_size, &base);
> +	if (ret)
> +		*low_size = -1;
> +
> +	return 0;
> +}
> +
>   Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
>   			  void *data, size_t data_len)
>   {



From john.p.donnelly at oracle.com  Tue Jan 11 07:04:02 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:04:02 -0600
Subject: [PATCH v19 02/13] x86/setup: Use parse_crashkernel_high_low() to
 simplify code
In-Reply-To: <20211228132612.1860-3-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-3-thunder.leizhen@huawei.com>
Message-ID: <097d4a87-1981-7848-6553-079d63cf6410@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> Use parse_crashkernel_high_low() to bring the parsing of
> "crashkernel=X,high" and the parsing of "crashkernel=Y,low" together, they
> are strongly dependent, make code logic clear and more readable.
> 
> Suggested-by: Borislav Petkov <bp at alien8.de>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>
> ---
>   arch/x86/kernel/setup.c | 21 +++++++++------------
>   1 file changed, 9 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 6a190c7f4d71b05..93d78aae1937db3 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -416,18 +416,16 @@ static void __init memblock_x86_reserve_range_setup_data(void)
>   # define CRASH_ADDR_HIGH_MAX	SZ_64T
>   #endif
>   
> -static int __init reserve_crashkernel_low(void)
> +static int __init reserve_crashkernel_low(unsigned long long low_size)
>   {
>   #ifdef CONFIG_X86_64
> -	unsigned long long base, low_base = 0, low_size = 0;
> +	unsigned long long low_base = 0;
>   	unsigned long low_mem_limit;
> -	int ret;
>   
>   	low_mem_limit = min(memblock_phys_mem_size(), CRASH_ADDR_LOW_MAX);
>   
> -	/* crashkernel=Y,low */
> -	ret = parse_crashkernel_low(boot_command_line, low_mem_limit, &low_size, &base);
> -	if (ret) {
> +	/* crashkernel=Y,low is not specified */
> +	if ((long)low_size < 0) {
>   		/*
>   		 * two parts from kernel/dma/swiotlb.c:
>   		 * -swiotlb size: user-specified with swiotlb= or default.
> @@ -465,7 +463,7 @@ static int __init reserve_crashkernel_low(void)
>   
>   static void __init reserve_crashkernel(void)
>   {
> -	unsigned long long crash_size, crash_base, total_mem;
> +	unsigned long long crash_size, crash_base, total_mem, low_size;
>   	bool high = false;
>   	int ret;
>   
> @@ -474,10 +472,9 @@ static void __init reserve_crashkernel(void)
>   	/* crashkernel=XM */
>   	ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
>   	if (ret != 0 || crash_size <= 0) {
> -		/* crashkernel=X,high */
> -		ret = parse_crashkernel_high(boot_command_line, total_mem,
> -					     &crash_size, &crash_base);
> -		if (ret != 0 || crash_size <= 0)
> +		/* crashkernel=X,high and possible crashkernel=Y,low */
> +		ret = parse_crashkernel_high_low(boot_command_line, &crash_size, &low_size);
> +		if (ret)
>   			return;
>   		high = true;
>   	}
> @@ -520,7 +517,7 @@ static void __init reserve_crashkernel(void)
>   		}
>   	}
>   
> -	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
> +	if (crash_base >= (1ULL << 32) && reserve_crashkernel_low(low_size)) {
>   		memblock_phys_free(crash_base, crash_size);
>   		return;
>   	}



From john.p.donnelly at oracle.com  Tue Jan 11 07:04:43 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:04:43 -0600
Subject: [PATCH v19 03/13] kdump: make parse_crashkernel_{high|low}()
 static
In-Reply-To: <20211228132612.1860-4-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-4-thunder.leizhen@huawei.com>
Message-ID: <f70c75a6-c816-8b20-797e-eda11ffed3a8@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> Make parse_crashkernel_{high|low}() static, they are only referenced by
> parse_crashkernel_high_low() in the same file. The latter is recommended.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   include/linux/crash_core.h | 4 ----
>   kernel/crash_core.c        | 4 ++--
>   2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> index 2d3a64761d18998..598fd55d83c169e 100644
> --- a/include/linux/crash_core.h
> +++ b/include/linux/crash_core.h
> @@ -79,10 +79,6 @@ void final_note(Elf_Word *buf);
>   
>   int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
>   		unsigned long long *crash_size, unsigned long long *crash_base);
> -int parse_crashkernel_high(char *cmdline, unsigned long long system_ram,
> -		unsigned long long *crash_size, unsigned long long *crash_base);
> -int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
> -		unsigned long long *crash_size, unsigned long long *crash_base);
>   int __init parse_crashkernel_high_low(char *cmdline,
>   				      unsigned long long *high_size,
>   				      unsigned long long *low_size);
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 8966beaf7c4fd52..3b9e01fc450b2a4 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -277,7 +277,7 @@ int __init parse_crashkernel(char *cmdline,
>   					"crashkernel=", NULL);
>   }
>   
> -int __init parse_crashkernel_high(char *cmdline,
> +static int __init parse_crashkernel_high(char *cmdline,
>   			     unsigned long long system_ram,
>   			     unsigned long long *crash_size,
>   			     unsigned long long *crash_base)
> @@ -286,7 +286,7 @@ int __init parse_crashkernel_high(char *cmdline,
>   				"crashkernel=", suffix_tbl[SUFFIX_HIGH]);
>   }
>   
> -int __init parse_crashkernel_low(char *cmdline,
> +static int __init parse_crashkernel_low(char *cmdline,
>   			     unsigned long long system_ram,
>   			     unsigned long long *crash_size,
>   			     unsigned long long *crash_base)



From john.p.donnelly at oracle.com  Tue Jan 11 07:05:28 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:05:28 -0600
Subject: [PATCH v19 04/13] kdump: reduce unnecessary parameters of
 parse_crashkernel_{high|low}()
In-Reply-To: <20211228132612.1860-5-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-5-thunder.leizhen@huawei.com>
Message-ID: <6dbf6d62-a860-4b69-5ea0-f540d52dbf43@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> Delete confusing parameters 'system_ram' and 'crash_base' of
> parse_crashkernel_{high|low}(), they are only needed by the case of
> "crashkernel=X@[offset]".
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   kernel/crash_core.c | 21 ++++++++++-----------
>   1 file changed, 10 insertions(+), 11 deletions(-)
> 
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index 3b9e01fc450b2a4..b7d024eb464d0ae 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -278,20 +278,20 @@ int __init parse_crashkernel(char *cmdline,
>   }
>   
>   static int __init parse_crashkernel_high(char *cmdline,
> -			     unsigned long long system_ram,
> -			     unsigned long long *crash_size,
> -			     unsigned long long *crash_base)
> +					 unsigned long long *crash_size)
>   {
> -	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
> +	unsigned long long base;
> +
> +	return __parse_crashkernel(cmdline, 0, crash_size, &base,
>   				"crashkernel=", suffix_tbl[SUFFIX_HIGH]);
>   }
>   
>   static int __init parse_crashkernel_low(char *cmdline,
> -			     unsigned long long system_ram,
> -			     unsigned long long *crash_size,
> -			     unsigned long long *crash_base)
> +					unsigned long long *crash_size)
>   {
> -	return __parse_crashkernel(cmdline, system_ram, crash_size, crash_base,
> +	unsigned long long base;
> +
> +	return __parse_crashkernel(cmdline, 0, crash_size, &base,
>   				"crashkernel=", suffix_tbl[SUFFIX_LOW]);
>   }
>   
> @@ -310,12 +310,11 @@ int __init parse_crashkernel_high_low(char *cmdline,
>   				      unsigned long long *low_size)
>   {
>   	int ret;
> -	unsigned long long base;
>   
>   	BUG_ON(!high_size || !low_size);
>   
>   	/* crashkernel=X,high */
> -	ret = parse_crashkernel_high(cmdline, 0, high_size, &base);
> +	ret = parse_crashkernel_high(cmdline, high_size);
>   	if (ret)
>   		return ret;
>   
> @@ -323,7 +322,7 @@ int __init parse_crashkernel_high_low(char *cmdline,
>   		return -EINVAL;
>   
>   	/* crashkernel=Y,low */
> -	ret = parse_crashkernel_low(cmdline, 0, low_size, &base);
> +	ret = parse_crashkernel_low(cmdline, low_size);
>   	if (ret)
>   		*low_size = -1;
>   



From john.p.donnelly at oracle.com  Tue Jan 11 07:06:00 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:06:00 -0600
Subject: [PATCH v19 05/13] x86/setup: Add and use CRASH_BASE_ALIGN
In-Reply-To: <20211228132612.1860-6-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-6-thunder.leizhen@huawei.com>
Message-ID: <36952970-6ce3-e17e-7997-3fa7e8f6307a@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> Add macro CRASH_BASE_ALIGN to indicate the alignment for crash kernel
> fixed region, in preparation for making partial implementation of
> reserve_crashkernel[_low]() generic.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>

 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   arch/x86/kernel/setup.c | 7 +++++--
>   1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index 93d78aae1937db3..cb7f237a2ae0dfa 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -392,9 +392,12 @@ static void __init memblock_x86_reserve_range_setup_data(void)
>   
>   #ifdef CONFIG_KEXEC_CORE
>   
> -/* 16M alignment for crash kernel regions */
> +/* alignment for crash kernel dynamic regions */
>   #define CRASH_ALIGN		SZ_16M
>   
> +/* alignment for crash kernel fixed region */
> +#define CRASH_BASE_ALIGN	SZ_1M
> +
>   /*
>    * Keep the crash kernel below this limit.
>    *
> @@ -509,7 +512,7 @@ static void __init reserve_crashkernel(void)
>   	} else {
>   		unsigned long long start;
>   
> -		start = memblock_phys_alloc_range(crash_size, SZ_1M, crash_base,
> +		start = memblock_phys_alloc_range(crash_size, CRASH_BASE_ALIGN, crash_base,
>   						  crash_base + crash_size);
>   		if (start != crash_base) {
>   			pr_info("crashkernel reservation failed - memory is in use.\n");



From john.p.donnelly at oracle.com  Tue Jan 11 07:06:37 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Tue, 11 Jan 2022 09:06:37 -0600
Subject: [PATCH v19 06/13] kexec: move crashk[_low]_res to crash_core
 module
In-Reply-To: <20211228132612.1860-7-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-7-thunder.leizhen@huawei.com>
Message-ID: <f376978b-095c-7ddd-54b4-1d6d91b3a00f@oracle.com>

On 12/28/21 7:26 AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> Move the definition and declaration of global variable crashk[_low]_res
> from kexec module to crash_core module, in preparation of adding generic
> reserve_crashkernel_mem[_low]() to crash_core.c, the latter refers to
> variable crashk[_low]_res. Due to the config KEXEC automatically selects
> CRASH_CORE, and the header crash_core.h is included by kexec.h, so there
> is no functional change.
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>

 >
Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   include/linux/crash_core.h |  4 ++++
>   include/linux/kexec.h      |  4 ----
>   kernel/crash_core.c        | 16 ++++++++++++++++
>   kernel/kexec_core.c        | 17 -----------------
>   4 files changed, 20 insertions(+), 21 deletions(-)
> 
> diff --git a/include/linux/crash_core.h b/include/linux/crash_core.h
> index 598fd55d83c169e..f5437c9c9411fce 100644
> --- a/include/linux/crash_core.h
> +++ b/include/linux/crash_core.h
> @@ -73,6 +73,10 @@ extern unsigned char *vmcoreinfo_data;
>   extern size_t vmcoreinfo_size;
>   extern u32 *vmcoreinfo_note;
>   
> +/* Location of a reserved region to hold the crash kernel. */
> +extern struct resource crashk_res;
> +extern struct resource crashk_low_res;
> +
>   Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
>   			  void *data, size_t data_len);
>   void final_note(Elf_Word *buf);
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index 0c994ae37729e1e..47e784d66ea8645 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -350,10 +350,6 @@ extern int kexec_load_disabled;
>   #define KEXEC_FILE_FLAGS	(KEXEC_FILE_UNLOAD | KEXEC_FILE_ON_CRASH | \
>   				 KEXEC_FILE_NO_INITRAMFS)
>   
> -/* Location of a reserved region to hold the crash kernel.
> - */
> -extern struct resource crashk_res;
> -extern struct resource crashk_low_res;
>   extern note_buf_t __percpu *crash_notes;
>   
>   /* flag to track if kexec reboot is in progress */
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index b7d024eb464d0ae..686d8a65e12a337 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -22,6 +22,22 @@ u32 *vmcoreinfo_note;
>   /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
>   static unsigned char *vmcoreinfo_data_safecopy;
>   
> +/* Location of the reserved area for the crash kernel */
> +struct resource crashk_res = {
> +	.name  = "Crash kernel",
> +	.start = 0,
> +	.end   = 0,
> +	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
> +	.desc  = IORES_DESC_CRASH_KERNEL
> +};
> +struct resource crashk_low_res = {
> +	.name  = "Crash kernel",
> +	.start = 0,
> +	.end   = 0,
> +	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
> +	.desc  = IORES_DESC_CRASH_KERNEL
> +};
> +
>   /*
>    * parsing the "crashkernel" commandline
>    *
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index 5a5d192a89ac307..1e0d4909bbb6b77 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -54,23 +54,6 @@ note_buf_t __percpu *crash_notes;
>   /* Flag to indicate we are going to kexec a new kernel */
>   bool kexec_in_progress = false;
>   
> -
> -/* Location of the reserved area for the crash kernel */
> -struct resource crashk_res = {
> -	.name  = "Crash kernel",
> -	.start = 0,
> -	.end   = 0,
> -	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
> -	.desc  = IORES_DESC_CRASH_KERNEL
> -};
> -struct resource crashk_low_res = {
> -	.name  = "Crash kernel",
> -	.start = 0,
> -	.end   = 0,
> -	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
> -	.desc  = IORES_DESC_CRASH_KERNEL
> -};
> -
>   int kexec_should_crash(struct task_struct *p)
>   {
>   	/*



From acme at kernel.org  Tue Jan 11 07:12:02 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 12:12:02 -0300
Subject: [PATCH v3 06/48] perf cpumap: Switch cpu_map__build_map to cpu
 function
In-Reply-To: <YdzSKOWJRC0dRnSn@kernel.org>
References: <20211230072030.302559-1-irogers@google.com>
 <20211230072030.302559-8-irogers@google.com>
 <YdybPJKjqx6zb28/@kernel.org> <YdyfCN1/JWJtJHTO@kernel.org>
 <Ydyjvcma/wMTPwbn@kernel.org> <Ydymdm/PoB0hQVUT@kernel.org>
 <CAP-5=fVAa3JVbdzNZg0LrVfw__9U9Q8PkHcro+TJiFVyvTho+A@mail.gmail.com>
 <YdzSKOWJRC0dRnSn@kernel.org>
Message-ID: <Yd2eQiPIvEf0c42x@kernel.org>

Em Mon, Jan 10, 2022 at 09:41:12PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Mon, Jan 10, 2022 at 02:29:58PM -0800, Ian Rogers escreveu:
> > On Mon, Jan 10, 2022 at 1:34 PM Arnaldo Carvalho de Melo
> > <acme at kernel.org> wrote:
> > >
> > > Em Mon, Jan 10, 2022 at 06:23:09PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > Em Mon, Jan 10, 2022 at 06:03:04PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > Em Mon, Jan 10, 2022 at 05:46:52PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > > > > At this point we need to remove the now unused perf_env__get_cpu(), and
> > > > > > then deal with the fallout in the following patches that needlessly
> > > > > > modify this unused function.
> > > > > >
> > > > > > Doing that now.
> > > > >
> > > > > Done, force pushed to tmp.perf/perf_cpu, now it is going again thru the
> > > > > build containers, a better start now:
> > >
> > > > So far so good:
> > >
> > > perf test ok, just that one that is failing, but before this series as
> > > well:
> > >
> > >  89: perf all metricgroups test                                      : FAILED!
> > 
> > Could you add the verbose output? I suspect it is fixed by this:
> > https://lore.kernel.org/lkml/20211223183948.3423989-1-irogers at google.com/
> 
> I'll try it.
> 
> BTW, here are the final tests, problems with arm 32 and 64-bit, I'll go thru
> them tomorrow, to fix in the cset the problem appears, so that we keep it
> bisectable, else you can get what I have in tmp.perf/perf_cpu, fix it and
> tomorrow I'll retest.
> 
>   27    85.67 debian:11                     : Ok   gcc (Debian 10.2.1-6) 10.2.1 20210110 , Debian clang version 11.0.1-2
>   28    98.65 debian:experimental           : Ok   gcc (Debian 11.2.0-13) 11.2.0 , Debian clang version 13.0.0-9+b2
>   29     8.69 debian:experimental-x-arm64   : FAIL gcc version 11.2.0 (Debian 11.2.0-9)
>     arch/arm64/util/pmu.c: In function 'pmu_events_map__find':
>     arch/arm64/util/pmu.c:18:35: error: invalid operands to binary != (have 'int' and 'struct perf_cpu')
>        18 |                 if (pmu->cpus->nr != cpu__max_cpu())
>           |                     ~~~~~~~~~~~~~ ^~ ~~~~~~~~~~~~~~
>           |                              |       |
>           |                              int     struct perf_cpu
>     make[5]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: util] Error 2
>     make[4]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arm64] Error 2
>     make[3]: *** [/git/perf-5.16.0/tools/build/Makefile.build:139: arch] Error 2
>   30    19.15 debian:experimental-x-mips    : Ok   mips-linux-gnu-gcc (Debian 10.2.1-6) 10.2.1 20210110

Fixed with the patch below squashed into 48/48 where the problem
was introduced.

tmp.perf/perf_cpu updated.

[perfbuilder at five ~]$ dm debian:experimental-x-arm64 ubuntu:16.04-x-arm ubuntu:16.04-x-arm64 ubuntu:18.04-x-arm  ubuntu:18.04-x-arm64
   1    26.08 debian:experimental-x-arm64   : Ok   aarch64-linux-gnu-gcc (Debian 11.2.0-9) 11.2.0
   2    21.68 ubuntu:16.04-x-arm            : Ok   arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
   3    21.53 ubuntu:16.04-x-arm64          : Ok   aarch64-linux-gnu-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
   4    61.22 ubuntu:18.04-x-arm            : Ok   arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0
   5   108.41 ubuntu:18.04-x-arm64          : Ok   aarch64-linux-gnu-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0
BUILD_TARBALL_HEAD=5610e6f0b9e64a02dfc906c9db9d18fd198200d9
 6 238.918
[perfbuilder at five ~]$

diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 129c0272d65b8596..2e8b2c4365a0003f 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -203,9 +203,11 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
 	struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
 
 	/* Set option of each CPU we have */
-	for (i = 0; i < cpu__max_cpu(); i++) {
-		if (!perf_cpu_map__has(event_cpus, i) ||
-		    !perf_cpu_map__has(online_cpus, i))
+	for (i = 0; i < cpu__max_cpu().cpu; i++) {
+		struct perf_cpu cpu = { .cpu = i, };
+
+		if (!perf_cpu_map__has(event_cpus, cpu) ||
+		    !perf_cpu_map__has(online_cpus, cpu))
 			continue;
 
 		if (option & BIT(ETM_OPT_CTXTID)) {
@@ -522,9 +524,11 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 
 	/* cpu map is not empty, we have specific CPUs to work with */
 	if (!perf_cpu_map__empty(event_cpus)) {
-		for (i = 0; i < cpu__max_cpu(); i++) {
-			if (!perf_cpu_map__has(event_cpus, i) ||
-			    !perf_cpu_map__has(online_cpus, i))
+		for (i = 0; i < cpu__max_cpu().cpu; i++) {
+			struct perf_cpu cpu = { .cpu = i, };
+
+			if (!perf_cpu_map__has(event_cpus, cpu) ||
+			    !perf_cpu_map__has(online_cpus, cpu))
 				continue;
 
 			if (cs_etm_is_ete(itr, i))
@@ -536,8 +540,10 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 		}
 	} else {
 		/* get configuration for all CPUs in the system */
-		for (i = 0; i < cpu__max_cpu(); i++) {
-			if (!perf_cpu_map__has(online_cpus, i))
+		for (i = 0; i < cpu__max_cpu().cpu; i++) {
+			struct perf_cpu cpu = { .cpu = i, };
+
+			if (!perf_cpu_map__has(online_cpus, cpu))
 				continue;
 
 			if (cs_etm_is_ete(itr, i))
@@ -722,8 +728,10 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 	} else {
 		/* Make sure all specified CPUs are online */
 		for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
-			if (perf_cpu_map__has(event_cpus, i) &&
-			    !perf_cpu_map__has(online_cpus, i))
+			struct perf_cpu cpu = { .cpu = i, };
+
+			if (perf_cpu_map__has(event_cpus, cpu) &&
+			    !perf_cpu_map__has(online_cpus, cpu))
 				return -EINVAL;
 		}
 
@@ -743,9 +751,12 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 
 	offset = CS_ETM_SNAPSHOT + 1;
 
-	for (i = 0; i < cpu__max_cpu() && offset < priv_size; i++)
-		if (perf_cpu_map__has(cpu_map, i))
+	for (i = 0; i < cpu__max_cpu().cpu && offset < priv_size; i++) {
+		struct perf_cpu cpu = { .cpu = i, };
+
+		if (perf_cpu_map__has(cpu_map, cpu))
 			cs_etm_get_metadata(i, &offset, itr, info);
+	}
 
 	perf_cpu_map__put(online_cpus);
 
diff --git a/tools/perf/arch/arm64/util/pmu.c b/tools/perf/arch/arm64/util/pmu.c
index d3a18f9c85f6a731..79124bba713e5f0d 100644
--- a/tools/perf/arch/arm64/util/pmu.c
+++ b/tools/perf/arch/arm64/util/pmu.c
@@ -15,7 +15,7 @@ const struct pmu_events_map *pmu_events_map__find(void)
 		 * The cpumap should cover all CPUs. Otherwise, some CPUs may
 		 * not support some events or have different event IDs.
 		 */
-		if (pmu->cpus->nr != cpu__max_cpu())
+		if (pmu->cpus->nr != cpu__max_cpu().cpu)
 			return NULL;
 
 		return perf_pmu__find_map(pmu);


From tsbogend at alpha.franken.de  Tue Jan 11 07:18:41 2022
From: tsbogend at alpha.franken.de (Thomas Bogendoerfer)
Date: Tue, 11 Jan 2022 16:18:41 +0100
Subject: [PATCH v1 0/4] PCI: brcmstb: Augment driver for MIPs SOCs
In-Reply-To: <20211209204726.6676-1-jim2101024@gmail.com>
References: <20211209204726.6676-1-jim2101024@gmail.com>
Message-ID: <20220111151841.GB11006@alpha.franken.de>

On Thu, Dec 09, 2021 at 03:47:21PM -0500, Jim Quinlan wrote:
> With this patchset, the Broadcom STB PCIe controller driver 
> supports Arm, Arm64, and now MIPs.
> 
> Jim Quinlan (4):
>   dt-bindings: PCI: Add compatible string for Brcmstb 74[23]5 MIPs SOCs
>   MIPS: bmips: Add support PCIe controller device nodes
>   MIPS: bmips: Remove obsolete DMA mapping support
>   PCI: brcmstb: Augment driver for MIPs SOCs
> 
>  .../bindings/pci/brcm,stb-pcie.yaml           |   2 +
>  arch/mips/Kconfig                             |   1 -
>  arch/mips/bmips/dma.c                         | 106 +-----------------
>  arch/mips/boot/dts/brcm/bcm7425.dtsi          |  30 +++++
>  arch/mips/boot/dts/brcm/bcm7435.dtsi          |  30 +++++
>  arch/mips/boot/dts/brcm/bcm97425svmb.dts      |   9 ++
>  arch/mips/boot/dts/brcm/bcm97435svmb.dts      |   9 ++
>  drivers/pci/controller/Kconfig                |   2 +-
>  drivers/pci/controller/pcie-brcmstb.c         |  82 +++++++++++++-
>  9 files changed, 161 insertions(+), 110 deletions(-)

series applied to mips-next.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]


From Claudiu.Beznea at microchip.com  Tue Jan 11 07:23:02 2022
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Tue, 11 Jan 2022 15:23:02 +0000
Subject: [PATCH] clk: at91: sama7g5: Allow MCK1 to be exported and
 referenced in DT
In-Reply-To: <20220111125310.902856-1-tudor.ambarus@microchip.com>
References: <20220111125310.902856-1-tudor.ambarus@microchip.com>
Message-ID: <528f5d1b-aeeb-6c2a-42a5-e4e2f2fba2c5@microchip.com>

On 11.01.2022 14:53, Tudor Ambarus wrote:
> MCK1 feeds the External Bus Interface (EBI). EBI's clock rate is used
> to translate EBI's timmings to SMC timings, thus we need to handle MCK1
> in the EBI driver. Allow MCK1 to be referenced as a PMC_TYPE_CORE clock
> from phandle in DT.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>

Reviewed-by: Claudiu Beznea <claudiu.beznea at microchip.com>

> ---
>  drivers/clk/at91/sama7g5.c       | 8 +++++++-
>  include/dt-bindings/clock/at91.h | 1 +
>  2 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c
> index 369dfafabbca..e43458673afb 100644
> --- a/drivers/clk/at91/sama7g5.c
> +++ b/drivers/clk/at91/sama7g5.c
> @@ -302,6 +302,7 @@ static const struct {
>   * @ep_count:		extra parents count
>   * @ep_mux_table:	mux table for extra parents
>   * @id:			clock id
> + * @eid:		export index in sama7g5->chws[] array
>   * @c:			true if clock is critical and cannot be disabled
>   */
>  static const struct {
> @@ -311,6 +312,7 @@ static const struct {
>  	u8 ep_count;
>  	u8 ep_mux_table[4];
>  	u8 id;
> +	u8 eid;
>  	u8 c;
>  } sama7g5_mckx[] = {
>  	{ .n = "mck1",
> @@ -319,6 +321,7 @@ static const struct {
>  	  .ep_mux_table = { 5, },
>  	  .ep_count = 1,
>  	  .ep_chg_id = INT_MIN,
> +	  .eid = PMC_MCK1,
>  	  .c = 1, },
>  
>  	{ .n = "mck2",
> @@ -913,7 +916,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
>  	if (IS_ERR(regmap))
>  		return;
>  
> -	sama7g5_pmc = pmc_data_allocate(PMC_CPU + 1,
> +	sama7g5_pmc = pmc_data_allocate(PMC_MCK1 + 1,
>  					nck(sama7g5_systemck),
>  					nck(sama7g5_periphck),
>  					nck(sama7g5_gck), 8);
> @@ -1027,6 +1030,9 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
>  			goto err_free;
>  
>  		alloc_mem[alloc_mem_size++] = mux_table;
> +
> +		if (sama7g5_mckx[i].eid)
> +			sama7g5_pmc->chws[sama7g5_mckx[i].eid] = hw;
>  	}
>  
>  	hw = at91_clk_sama7g5_register_utmi(regmap, "utmick", "main_xtal");
> diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h
> index 98e1b2ab6403..8498c0cd95fe 100644
> --- a/include/dt-bindings/clock/at91.h
> +++ b/include/dt-bindings/clock/at91.h
> @@ -35,6 +35,7 @@
>  #define PMC_AUDIOIOPLL		(PMC_MAIN + 7)
>  #define PMC_ETHPLL		(PMC_MAIN + 8)
>  #define PMC_CPU			(PMC_MAIN + 9)
> +#define PMC_MCK1		(PMC_MAIN + 10)
>  
>  #ifndef AT91_PMC_MOSCS
>  #define AT91_PMC_MOSCS		0		/* MOSCS Flag */


From arnd at arndb.de  Tue Jan 11 07:33:30 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 11 Jan 2022 16:33:30 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <20220111083515.502308-5-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
Message-ID: <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:35 AM Christoph Hellwig <hch at lst.de> wrote:
>
> The fcntl F_GETLK64/F_SETLK64/F_SETLKW64 are only implemented for the
> 32-bit syscall APIs, but we also need them for compat handling on 64-bit
> builds.  Redefining them is error prone (as shown by the example that
> parisc gets it wrong currently), so we should use the same defines for
> both case.  In theory we could try to hide them from userspace, but
> given that only MIPS actually gets that right, while the asm-generic
> version used by most architectures relies on a Kconfig symbol that can't
> be relied on to be set properly by userspace is a clear indicator to not
> bother.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---

> diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
> index 98f4ff165b776..43d7c44031be0 100644
> --- a/include/uapi/asm-generic/fcntl.h
> +++ b/include/uapi/asm-generic/fcntl.h
> @@ -116,13 +116,11 @@
>  #define F_GETSIG       11      /* for sockets. */
>  #endif
>
> -#ifndef CONFIG_64BIT
>  #ifndef F_GETLK64
>  #define F_GETLK64      12      /*  using 'struct flock64' */
>  #define F_SETLK64      13
>  #define F_SETLKW64     14
>  #endif
> -#endif
>
>  #ifndef F_SETOWN_EX
>  #define F_SETOWN_EX    15

This is a very subtle change to the exported UAPI header contents:
On 64-bit architectures, the three unusable numbers are now always
shown, rather than depending on a user-controlled symbol.

This is probably what we want here for compatibility reasons, but I think
it should be explained in the changelog text, and I'd like Jeff or Bruce
to comment on it as well: the alternative here would be to make the
uapi definition depend on __BITS_PER_LONG==32, which is
technically the right thing to do but more a of a change.

       Arnd


From nathan at kernel.org  Tue Jan 11 07:34:09 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 11 Jan 2022 08:34:09 -0700
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic
 function groups
In-Reply-To: <20211216162206.8027-4-zajec5@gmail.com>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com>
Message-ID: <Yd2jcfXqqKHK/NaG@archlinux-ax161>

Hi Rafa?,

On Thu, Dec 16, 2021 at 05:22:06PM +0100, Rafa? Mi?ecki wrote:
> From: Rafa? Mi?ecki <rafal at milecki.pl>
> 
> Generic code doesn't modify those strings and .get_function_groups
> callback has that extra "const" as well. This allows more flexibility in
> GENERIC_PINMUX_FUNCTIONS users.
> 
> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> ---
>  drivers/pinctrl/pinmux.c | 2 +-
>  drivers/pinctrl/pinmux.h | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> index 6cdbd9ccf2f0..f94d43b082d9 100644
> --- a/drivers/pinctrl/pinmux.c
> +++ b/drivers/pinctrl/pinmux.c
> @@ -875,7 +875,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
>   */
>  int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>  				const char *name,
> -				const char **groups,
> +				const char * const *groups,
>  				const unsigned int num_groups,
>  				void *data)
>  {
> diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
> index 78c3a31be882..72fcf03eaa43 100644
> --- a/drivers/pinctrl/pinmux.h
> +++ b/drivers/pinctrl/pinmux.h
> @@ -129,7 +129,7 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot,
>   */
>  struct function_desc {
>  	const char *name;
> -	const char **group_names;
> +	const char * const *group_names;
>  	int num_group_names;
>  	void *data;
>  };
> @@ -150,7 +150,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
>  
>  int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>  				const char *name,
> -				const char **groups,
> +				const char * const *groups,
>  				unsigned const num_groups,
>  				void *data);
>  
> -- 
> 2.31.1
> 
> 

I have not seen this reported yet, even though it has been broken for a
couple of weeks now. I see the following error in -next:

$ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig drivers/pinctrl/pinctrl-thunderbay.o
drivers/pinctrl/pinctrl-thunderbay.c: In function ?thunderbay_add_functions?:
drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]
  815 |                         grp = func->group_names;
      |                             ^
cc1: all warnings being treated as errors

Looks like something like the third patch of the series is needed for
the Thunderbay driver, which it appears was in development at the same
time as this series.

Cheers,
Nathan


From jacopo at jmondi.org  Tue Jan 11 07:43:01 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Tue, 11 Jan 2022 16:43:01 +0100
Subject: [PATCH v3 03/23] media: atmel: introduce microchip csi2dc driver
In-Reply-To: <20211213134940.324266-4-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-4-eugen.hristev@microchip.com>
Message-ID: <20220111154301.35uv4dmjw567cmjm@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:20PM +0200, Eugen Hristev wrote:
> Microchip CSI2DC (CSI2 Demultiplexer Controller) is a misc bridge device
> that converts a byte stream in IDI Synopsys format (coming from a CSI2HOST)
> to a pixel stream that can be captured by a sensor controller.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

Thanks for addressing my comments on previous versions
Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j


> ---
> Changes in v3:
> - on set format, disable setting the source sink.
> - removed useless request to pm_request_idle
> - fixed YUV DT
> - added last frame debug info
> - removed writing read only VPCOL and VPROW registers
> - minor cosmetic changes
>
> Changes in v2:
> - implement try formats
> - added parallel mode
> - moved to fwlink endpoints
> - many other minor corrections from Jacopo's review
>
> Changes in this revision:
> - addressed comments by Jacopo and Laurent as in this thread:
> https://www.spinics.net/lists/linux-media/msg181044.html
>
> Previous change log :
> Changes in v5:
> - only in bindings
>
> Changes in v4:
> - now using get_mbus_config ops to get data from the subdevice, like the
> virtual channel id, and the clock type.
> - now having possibility to select any of the RAW10 data modes
> - at completion time, select which formats are also available in the subdevice,
> and move to the dynamic list accordingly
> - changed the pipeline integration, do not advertise subdev ready at probe time.
> wait until completion is done, and then start a workqueue that will register
> this device as a subdevice for the next element in pipeline.
> - moved the s_power code into a different function called now csi2dc_power
> that is called with CONFIG_PM functions. This is also called at completion,
> to have the device ready in case CONFIG_PM is not selected on the platform.
> - merged try_fmt into set_fmt
> - driver cleanup, wrapped lines over 80 characters
>
> Changes in v2:
> - moved driver to platform/atmel
> - fixed minor things as per Sakari's review
> - still some things from v2 review are not yet addressed, to be followed up
>
>
>
>  drivers/media/platform/Makefile               |   1 +
>  drivers/media/platform/atmel/Kconfig          |  15 +
>  drivers/media/platform/atmel/Makefile         |   1 +
>  .../media/platform/atmel/microchip-csi2dc.c   | 806 ++++++++++++++++++
>  4 files changed, 823 insertions(+)
>  create mode 100644 drivers/media/platform/atmel/microchip-csi2dc.c
>
> diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
> index 832357240e89..b18e5f704145 100644
> --- a/drivers/media/platform/Makefile
> +++ b/drivers/media/platform/Makefile
> @@ -69,6 +69,7 @@ obj-$(CONFIG_VIDEO_RCAR_VIN)		+= rcar-vin/
>  obj-$(CONFIG_VIDEO_ATMEL_ISC)		+= atmel/
>  obj-$(CONFIG_VIDEO_ATMEL_ISI)		+= atmel/
>  obj-$(CONFIG_VIDEO_ATMEL_XISC)		+= atmel/
> +obj-$(CONFIG_VIDEO_MICROCHIP_CSI2DC)	+= atmel/
>
>  obj-$(CONFIG_VIDEO_STM32_DCMI)		+= stm32/
>
> diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig
> index dda2f27da317..f83bee373d82 100644
> --- a/drivers/media/platform/atmel/Kconfig
> +++ b/drivers/media/platform/atmel/Kconfig
> @@ -40,3 +40,18 @@ config VIDEO_ATMEL_ISI
>  	help
>  	  This module makes the ATMEL Image Sensor Interface available
>  	  as a v4l2 device.
> +
> +config VIDEO_MICROCHIP_CSI2DC
> +	tristate "Microchip CSI2 Demux Controller"
> +	depends on VIDEO_V4L2 && COMMON_CLK && OF
> +	depends on ARCH_AT91 || COMPILE_TEST
> +	select MEDIA_CONTROLLER
> +	select VIDEO_V4L2_SUBDEV_API
> +	select V4L2_FWNODE
> +	help
> +	  CSI2 Demux Controller driver. CSI2DC is a helper chip
> +	  that converts IDI interface byte stream to a parallel pixel stream.
> +	  It supports various RAW formats as input.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called microchip-csi2dc.
> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
> index 46d264ab7948..39f0a7eba702 100644
> --- a/drivers/media/platform/atmel/Makefile
> +++ b/drivers/media/platform/atmel/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
>  obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-base.o
>  obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o
>  obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o
> +obj-$(CONFIG_VIDEO_MICROCHIP_CSI2DC) += microchip-csi2dc.o
> diff --git a/drivers/media/platform/atmel/microchip-csi2dc.c b/drivers/media/platform/atmel/microchip-csi2dc.c
> new file mode 100644
> index 000000000000..6bc549c28e05
> --- /dev/null
> +++ b/drivers/media/platform/atmel/microchip-csi2dc.c
> @@ -0,0 +1,806 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Microchip CSI2 Demux Controller (CSI2DC) driver
> + *
> + * Copyright (C) 2018 Microchip Technology, Inc.
> + *
> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
> + *
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/mod_devicetable.h>
> +#include <linux/module.h>
> +#include <linux/of_graph.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/videodev2.h>
> +
> +#include <media/v4l2-fwnode.h>
> +#include <media/v4l2-subdev.h>
> +
> +/* Global configuration register */
> +#define CSI2DC_GCFG			0x0
> +
> +/* MIPI sensor pixel clock is free running */
> +#define CSI2DC_GCFG_MIPIFRN		BIT(0)
> +/* GPIO parallel interface selection */
> +#define CSI2DC_GCFG_GPIOSEL		BIT(1)
> +/* Output waveform inter-line minimum delay */
> +#define CSI2DC_GCFG_HLC(v)		((v) << 4)
> +#define CSI2DC_GCFG_HLC_MASK		GENMASK(7, 4)
> +/* SAMA7G5 requires a HLC delay of 15 */
> +#define SAMA7G5_HLC			(15)
> +
> +/* Global control register */
> +#define CSI2DC_GCTLR			0x04
> +#define CSI2DC_GCTLR_SWRST		BIT(0)
> +
> +/* Global status register */
> +#define CSI2DC_GS			0x08
> +
> +/* SSP interrupt status register */
> +#define CSI2DC_SSPIS			0x28
> +/* Pipe update register */
> +#define CSI2DC_PU			0xc0
> +/* Video pipe attributes update */
> +#define CSI2DC_PU_VP			BIT(0)
> +
> +/* Pipe update status register */
> +#define CSI2DC_PUS			0xc4
> +
> +/* Video pipeline Interrupt Status Register */
> +#define CSI2DC_VPISR			0xf4
> +
> +/* Video pipeline enable register */
> +#define CSI2DC_VPE			0xf8
> +#define CSI2DC_VPE_ENABLE		BIT(0)
> +
> +/* Video pipeline configuration register */
> +#define CSI2DC_VPCFG			0xfc
> +/* Data type */
> +#define CSI2DC_VPCFG_DT(v)		((v) << 0)
> +#define CSI2DC_VPCFG_DT_MASK		GENMASK(5, 0)
> +/* Virtual channel identifier */
> +#define CSI2DC_VPCFG_VC(v)		((v) << 6)
> +#define CSI2DC_VPCFG_VC_MASK		GENMASK(7, 6)
> +/* Decompression enable */
> +#define CSI2DC_VPCFG_DE			BIT(8)
> +/* Decoder mode */
> +#define CSI2DC_VPCFG_DM(v)		((v) << 9)
> +#define CSI2DC_VPCFG_DM_DECODER8TO12	0
> +/* Decoder predictor 2 selection */
> +#define CSI2DC_VPCFG_DP2		BIT(12)
> +/* Recommended memory storage */
> +#define CSI2DC_VPCFG_RMS		BIT(13)
> +/* Post adjustment */
> +#define CSI2DC_VPCFG_PA			BIT(14)
> +
> +/* Video pipeline column register */
> +#define CSI2DC_VPCOL			0x100
> +/* Column number */
> +#define CSI2DC_VPCOL_COL(v)		((v) << 0)
> +#define CSI2DC_VPCOL_COL_MASK		GENMASK(15, 0)
> +
> +/* Video pipeline row register */
> +#define CSI2DC_VPROW			0x104
> +/* Row number */
> +#define CSI2DC_VPROW_ROW(v)		((v) << 0)
> +#define CSI2DC_VPROW_ROW_MASK		GENMASK(15, 0)
> +
> +/* Version register */
> +#define CSI2DC_VERSION			0x1fc
> +
> +/* register read/write helpers */
> +#define csi2dc_readl(st, reg)		readl_relaxed((st)->base + (reg))
> +#define csi2dc_writel(st, reg, val)	writel_relaxed((val), \
> +					(st)->base + (reg))
> +
> +/* supported RAW data types */
> +#define CSI2DC_DT_RAW6			0x28
> +#define CSI2DC_DT_RAW7			0x29
> +#define CSI2DC_DT_RAW8			0x2a
> +#define CSI2DC_DT_RAW10			0x2b
> +#define CSI2DC_DT_RAW12			0x2c
> +#define CSI2DC_DT_RAW14			0x2d
> +/* YUV data types */
> +#define CSI2DC_DT_YUV422_8B		0x1e
> +
> +/*
> + * struct csi2dc_format - CSI2DC format type struct
> + * @mbus_code:		Media bus code for the format
> + * @dt:			Data type constant for this format
> + */
> +struct csi2dc_format {
> +	u32				mbus_code;
> +	u32				dt;
> +};
> +
> +static const struct csi2dc_format csi2dc_formats[] = {
> +	{
> +		.mbus_code =		MEDIA_BUS_FMT_SRGGB8_1X8,
> +		.dt =			CSI2DC_DT_RAW8,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SBGGR8_1X8,
> +		.dt =			CSI2DC_DT_RAW8,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SGRBG8_1X8,
> +		.dt =			CSI2DC_DT_RAW8,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SGBRG8_1X8,
> +		.dt =			CSI2DC_DT_RAW8,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SRGGB10_1X10,
> +		.dt =			CSI2DC_DT_RAW10,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SBGGR10_1X10,
> +		.dt =			CSI2DC_DT_RAW10,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SGRBG10_1X10,
> +		.dt =			CSI2DC_DT_RAW10,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_SGBRG10_1X10,
> +		.dt =			CSI2DC_DT_RAW10,
> +	}, {
> +		.mbus_code =		MEDIA_BUS_FMT_YUYV8_2X8,
> +		.dt =			CSI2DC_DT_YUV422_8B,
> +	},
> +};
> +
> +enum mipi_csi_pads {
> +	CSI2DC_PAD_SINK			= 0,
> +	CSI2DC_PAD_SOURCE		= 1,
> +	CSI2DC_PADS_NUM			= 2,
> +};
> +
> +/*
> + * struct csi2dc_device - CSI2DC device driver data/config struct
> + * @base:		Register map base address
> + * @csi2dc_sd:		v4l2 subdevice for the csi2dc device
> + *			This is the subdevice that the csi2dc device itself
> + *			registers in v4l2 subsystem
> + * @dev:		struct device for this csi2dc device
> + * @pclk:		Peripheral clock reference
> + *			Input clock that clocks the hardware block internal
> + *			logic
> + * @scck:		Sensor Controller clock reference
> + *			Input clock that is used to generate the pixel clock
> + * @format:		Current saved format used in g/s fmt
> + * @cur_fmt:		Current state format
> + * @try_fmt:		Try format that is being tried
> + * @pads:		Media entity pads for the csi2dc subdevice
> + * @clk_gated:		Whether the clock is gated or free running
> + * @video_pipe:		Whether video pipeline is configured
> + * @parallel_mode:	The underlying subdevice is connected on a parallel bus
> + * @vc:			Current set virtual channel
> + * @notifier:		Async notifier that is used to bound the underlying
> + *			subdevice to the csi2dc subdevice
> + * @input_sd:		Reference to the underlying subdevice bound to the
> + *			csi2dc subdevice
> + * @remote_pad:		Pad number of the underlying subdevice that is linked
> + *			to the csi2dc subdevice sink pad.
> + */
> +struct csi2dc_device {
> +	void __iomem			*base;
> +	struct v4l2_subdev		csi2dc_sd;
> +	struct device			*dev;
> +	struct clk			*pclk;
> +	struct clk			*scck;
> +
> +	struct v4l2_mbus_framefmt	 format;
> +
> +	const struct csi2dc_format	*cur_fmt;
> +	const struct csi2dc_format	*try_fmt;
> +
> +	struct media_pad		pads[CSI2DC_PADS_NUM];
> +
> +	bool				clk_gated;
> +	bool				video_pipe;
> +	bool				parallel_mode;
> +	u32				vc;
> +
> +	struct v4l2_async_notifier	notifier;
> +
> +	struct v4l2_subdev		*input_sd;
> +
> +	u32				remote_pad;
> +};
> +
> +static inline struct csi2dc_device *
> +csi2dc_sd_to_csi2dc_device(struct v4l2_subdev *csi2dc_sd)
> +{
> +	return container_of(csi2dc_sd, struct csi2dc_device, csi2dc_sd);
> +}
> +
> +static int csi2dc_enum_mbus_code(struct v4l2_subdev *csi2dc_sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	if (code->index >= ARRAY_SIZE(csi2dc_formats))
> +		return -EINVAL;
> +
> +	code->code = csi2dc_formats[code->index].mbus_code;
> +
> +	return 0;
> +}
> +
> +static int csi2dc_get_fmt(struct v4l2_subdev *csi2dc_sd,
> +			  struct v4l2_subdev_state *sd_state,
> +			  struct v4l2_subdev_format *format)
> +{
> +	struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd);
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt;
> +
> +	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd, sd_state,
> +							  format->pad);
> +		format->format = *v4l2_try_fmt;
> +
> +		return 0;
> +	}
> +
> +	format->format = csi2dc->format;
> +
> +	return 0;
> +}
> +
> +static int csi2dc_set_fmt(struct v4l2_subdev *csi2dc_sd,
> +			  struct v4l2_subdev_state *sd_state,
> +			  struct v4l2_subdev_format *req_fmt)
> +{
> +	struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd);
> +	const struct csi2dc_format *fmt, *try_fmt = NULL;
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt;
> +	unsigned int i;
> +
> +	/*
> +	 * Setting the source pad is disabled.
> +	 * The same format is being propagated from the sink to source.
> +	 */
> +	if (req_fmt->pad == CSI2DC_PAD_SOURCE)
> +		return -EINVAL;
> +
> +	for (i = 0; i < ARRAY_SIZE(csi2dc_formats);  i++) {
> +		fmt = &csi2dc_formats[i];
> +		if (req_fmt->format.code == fmt->mbus_code)
> +			try_fmt = fmt;
> +		fmt++;
> +	}
> +
> +	/* in case we could not find the desired format, default to something */
> +	if (!try_fmt) {
> +		try_fmt = &csi2dc_formats[0];
> +
> +		dev_dbg(csi2dc->dev,
> +			"CSI2DC unsupported format 0x%x, defaulting to 0x%x\n",
> +			req_fmt->format.code, csi2dc_formats[0].mbus_code);
> +	}
> +
> +	req_fmt->format.code = try_fmt->mbus_code;
> +	req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
> +	req_fmt->format.field = V4L2_FIELD_NONE;
> +
> +	if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd, sd_state,
> +							  req_fmt->pad);
> +		*v4l2_try_fmt = req_fmt->format;
> +		/* Trying on the sink pad makes the source pad change too */
> +		v4l2_try_fmt = v4l2_subdev_get_try_format(csi2dc_sd,
> +							  sd_state,
> +							  CSI2DC_PAD_SOURCE);
> +		*v4l2_try_fmt = req_fmt->format;
> +
> +		/* if we are just trying, we are done */
> +		return 0;
> +	}
> +
> +	/* save the format for later requests */
> +	csi2dc->format = req_fmt->format;
> +
> +	/* update config */
> +	csi2dc->cur_fmt = try_fmt;
> +
> +	dev_dbg(csi2dc->dev, "new format set: 0x%x @%dx%d\n",
> +		csi2dc->format.code, csi2dc->format.width,
> +		csi2dc->format.height);
> +
> +	return 0;
> +}
> +
> +static int csi2dc_power(struct csi2dc_device *csi2dc, int on)
> +{
> +	int ret = 0;
> +
> +	if (on) {
> +		ret = clk_prepare_enable(csi2dc->pclk);
> +		if (ret) {
> +			dev_err(csi2dc->dev, "failed to enable pclk:%d\n", ret);
> +			return ret;
> +		}
> +
> +		ret = clk_prepare_enable(csi2dc->scck);
> +		if (ret) {
> +			dev_err(csi2dc->dev, "failed to enable scck:%d\n", ret);
> +			clk_disable_unprepare(csi2dc->pclk);
> +			return ret;
> +		}
> +
> +		/* if powering up, deassert reset line */
> +		csi2dc_writel(csi2dc, CSI2DC_GCTLR, CSI2DC_GCTLR_SWRST);
> +	} else {
> +		/* if powering down, assert reset line */
> +		csi2dc_writel(csi2dc, CSI2DC_GCTLR, 0);
> +
> +		clk_disable_unprepare(csi2dc->scck);
> +		clk_disable_unprepare(csi2dc->pclk);
> +	}
> +
> +	return ret;
> +}
> +
> +static int csi2dc_get_mbus_config(struct csi2dc_device *csi2dc)
> +{
> +	struct v4l2_mbus_config mbus_config = { 0 };
> +	int ret;
> +
> +	ret = v4l2_subdev_call(csi2dc->input_sd, pad, get_mbus_config,
> +			       csi2dc->remote_pad, &mbus_config);
> +	if (ret == -ENOIOCTLCMD) {
> +		dev_dbg(csi2dc->dev,
> +			"no remote mbus configuration available\n");
> +		goto csi2dc_get_mbus_config_defaults;
> +	}
> +
> +	if (ret) {
> +		dev_err(csi2dc->dev,
> +			"failed to get remote mbus configuration\n");
> +		goto csi2dc_get_mbus_config_defaults;
> +	}
> +
> +	if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_0)
> +		csi2dc->vc = 0;
> +	else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_1)
> +		csi2dc->vc = 1;
> +	else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_2)
> +		csi2dc->vc = 2;
> +	else if (mbus_config.flags & V4L2_MBUS_CSI2_CHANNEL_3)
> +		csi2dc->vc = 3;
> +
> +	dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc);
> +
> +	csi2dc->clk_gated = mbus_config.flags &
> +				V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
> +
> +	dev_dbg(csi2dc->dev, "mbus_config: %s clock\n",
> +		csi2dc->clk_gated ? "gated" : "free running");
> +
> +	return 0;
> +
> +csi2dc_get_mbus_config_defaults:
> +	csi2dc->vc = 0; /* Virtual ID 0 by default */
> +
> +	return 0;
> +}
> +
> +static void csi2dc_vp_update(struct csi2dc_device *csi2dc)
> +{
> +	u32 vp, gcfg;
> +
> +	if (!csi2dc->video_pipe) {
> +		dev_err(csi2dc->dev, "video pipeline unavailable\n");
> +		return;
> +	}
> +
> +	if (csi2dc->parallel_mode) {
> +		/* In parallel mode, GPIO parallel interface must be selected */
> +		gcfg = csi2dc_readl(csi2dc, CSI2DC_GCFG);
> +		gcfg |= CSI2DC_GCFG_GPIOSEL;
> +		csi2dc_writel(csi2dc, CSI2DC_GCFG, gcfg);
> +		return;
> +	}
> +
> +	/* serial video pipeline */
> +
> +	csi2dc_writel(csi2dc, CSI2DC_GCFG,
> +		      (SAMA7G5_HLC & CSI2DC_GCFG_HLC_MASK) |
> +		      (csi2dc->clk_gated ? 0 : CSI2DC_GCFG_MIPIFRN));
> +
> +	vp = CSI2DC_VPCFG_DT(csi2dc->cur_fmt->dt) & CSI2DC_VPCFG_DT_MASK;
> +	vp |= CSI2DC_VPCFG_VC(csi2dc->vc) & CSI2DC_VPCFG_VC_MASK;
> +	vp &= ~CSI2DC_VPCFG_DE;
> +	vp |= CSI2DC_VPCFG_DM(CSI2DC_VPCFG_DM_DECODER8TO12);
> +	vp &= ~CSI2DC_VPCFG_DP2;
> +	vp &= ~CSI2DC_VPCFG_RMS;
> +	vp |= CSI2DC_VPCFG_PA;
> +
> +	csi2dc_writel(csi2dc, CSI2DC_VPCFG, vp);
> +	csi2dc_writel(csi2dc, CSI2DC_VPE, CSI2DC_VPE_ENABLE);
> +	csi2dc_writel(csi2dc, CSI2DC_PU, CSI2DC_PU_VP);
> +}
> +
> +static int csi2dc_s_stream(struct v4l2_subdev *csi2dc_sd, int enable)
> +{
> +	struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd);
> +	int ret;
> +
> +	if (enable) {
> +		ret = pm_runtime_resume_and_get(csi2dc->dev);
> +		if (ret < 0)
> +			return ret;
> +
> +		csi2dc_get_mbus_config(csi2dc);
> +
> +		csi2dc_vp_update(csi2dc);
> +
> +		return v4l2_subdev_call(csi2dc->input_sd, video, s_stream,
> +					true);
> +	}
> +
> +	dev_dbg(csi2dc->dev,
> +		"Last frame received: VPCOLR = %u, VPROWR= %u, VPISR = %x\n",
> +		csi2dc_readl(csi2dc, CSI2DC_VPCOL),
> +		csi2dc_readl(csi2dc, CSI2DC_VPROW),
> +		csi2dc_readl(csi2dc, CSI2DC_VPISR));
> +
> +	/* stop streaming scenario */
> +	ret = v4l2_subdev_call(csi2dc->input_sd, video, s_stream, false);
> +
> +	pm_runtime_put_sync(csi2dc->dev);
> +
> +	return ret;
> +}
> +
> +static int csi2dc_init_cfg(struct v4l2_subdev *csi2dc_sd,
> +			   struct v4l2_subdev_state *sd_state)
> +{
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt =
> +		v4l2_subdev_get_try_format(csi2dc_sd, sd_state, 0);
> +
> +	v4l2_try_fmt->height = 480;
> +	v4l2_try_fmt->width = 640;
> +	v4l2_try_fmt->code = csi2dc_formats[0].mbus_code;
> +	v4l2_try_fmt->colorspace = V4L2_COLORSPACE_SRGB;
> +	v4l2_try_fmt->field = V4L2_FIELD_NONE;
> +	v4l2_try_fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	v4l2_try_fmt->quantization = V4L2_QUANTIZATION_DEFAULT;
> +	v4l2_try_fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_subdev_pad_ops csi2dc_pad_ops = {
> +	.enum_mbus_code = csi2dc_enum_mbus_code,
> +	.set_fmt = csi2dc_set_fmt,
> +	.get_fmt = csi2dc_get_fmt,
> +	.init_cfg = csi2dc_init_cfg,
> +};
> +
> +static const struct v4l2_subdev_video_ops csi2dc_video_ops = {
> +	.s_stream = csi2dc_s_stream,
> +};
> +
> +static const struct v4l2_subdev_ops csi2dc_subdev_ops = {
> +	.pad = &csi2dc_pad_ops,
> +	.video = &csi2dc_video_ops,
> +};
> +
> +static int csi2dc_async_bound(struct v4l2_async_notifier *notifier,
> +			      struct v4l2_subdev *subdev,
> +			      struct v4l2_async_subdev *asd)
> +{
> +	struct csi2dc_device *csi2dc = container_of(notifier,
> +						struct csi2dc_device, notifier);
> +	int pad;
> +	int ret;
> +
> +	csi2dc->input_sd = subdev;
> +
> +	pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
> +					  MEDIA_PAD_FL_SOURCE);
> +	if (pad < 0) {
> +		dev_err(csi2dc->dev, "Failed to find pad for %s\n",
> +			subdev->name);
> +		return pad;
> +	}
> +
> +	csi2dc->remote_pad = pad;
> +
> +	ret = media_create_pad_link(&csi2dc->input_sd->entity,
> +				    csi2dc->remote_pad,
> +				    &csi2dc->csi2dc_sd.entity, 0,
> +				    MEDIA_LNK_FL_ENABLED);
> +	if (ret) {
> +		dev_err(csi2dc->dev,
> +			"Failed to create pad link: %s to %s\n",
> +			csi2dc->input_sd->entity.name,
> +			csi2dc->csi2dc_sd.entity.name);
> +		return ret;
> +	}
> +
> +	dev_dbg(csi2dc->dev, "link with %s pad: %d\n",
> +		csi2dc->input_sd->name, csi2dc->remote_pad);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_async_notifier_operations csi2dc_async_ops = {
> +	.bound = csi2dc_async_bound,
> +};
> +
> +static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc,
> +				   struct fwnode_handle *input_fwnode)
> +{
> +	struct v4l2_async_subdev *asd;
> +	int ret = 0;
> +
> +	v4l2_async_nf_init(&csi2dc->notifier);
> +
> +	asd = v4l2_async_nf_add_fwnode_remote(&csi2dc->notifier,
> +					      input_fwnode,
> +					      struct v4l2_async_subdev);
> +
> +	fwnode_handle_put(input_fwnode);
> +
> +	if (IS_ERR(asd)) {
> +		ret = PTR_ERR(asd);
> +		dev_err(csi2dc->dev,
> +			"failed to add async notifier for node %pOF: %d\n",
> +			to_of_node(input_fwnode), ret);
> +		v4l2_async_nf_cleanup(&csi2dc->notifier);
> +		return ret;
> +	}
> +
> +	csi2dc->notifier.ops = &csi2dc_async_ops;
> +
> +	ret = v4l2_async_subdev_nf_register(&csi2dc->csi2dc_sd,
> +					    &csi2dc->notifier);
> +	if (ret) {
> +		dev_err(csi2dc->dev, "fail to register async notifier: %d\n",
> +			ret);
> +		v4l2_async_nf_cleanup(&csi2dc->notifier);
> +	}
> +
> +	return ret;
> +}
> +
> +static int csi2dc_of_parse(struct csi2dc_device *csi2dc,
> +			   struct device_node *of_node)
> +{
> +	struct fwnode_handle *input_fwnode, *output_fwnode;
> +	struct v4l2_fwnode_endpoint input_endpoint = { 0 },
> +				    output_endpoint = { 0 };
> +	int ret;
> +
> +	input_fwnode = fwnode_graph_get_next_endpoint(of_fwnode_handle(of_node),
> +						      NULL);
> +	if (!input_fwnode) {
> +		dev_err(csi2dc->dev,
> +			"missing port node at %pOF, input node is mandatory.\n",
> +			of_node);
> +		return -EINVAL;
> +	}
> +
> +	ret = v4l2_fwnode_endpoint_parse(input_fwnode, &input_endpoint);
> +	if (ret) {
> +		dev_err(csi2dc->dev, "endpoint not defined at %pOF\n", of_node);
> +		goto csi2dc_of_parse_err;
> +	}
> +
> +	if (input_endpoint.bus_type == V4L2_MBUS_PARALLEL ||
> +	    input_endpoint.bus_type == V4L2_MBUS_BT656) {
> +		csi2dc->parallel_mode = true;
> +		dev_dbg(csi2dc->dev,
> +			"subdevice connected on parallel interface\n");
> +	}
> +
> +	if (input_endpoint.bus_type == V4L2_MBUS_CSI2_DPHY) {
> +		csi2dc->clk_gated = input_endpoint.bus.mipi_csi2.flags &
> +					V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
> +		dev_dbg(csi2dc->dev,
> +			"subdevice connected on serial interface\n");
> +		dev_dbg(csi2dc->dev, "DT: %s clock\n",
> +			csi2dc->clk_gated ? "gated" : "free running");
> +	}
> +
> +	output_fwnode = fwnode_graph_get_next_endpoint
> +				(of_fwnode_handle(of_node), input_fwnode);
> +
> +	if (output_fwnode)
> +		ret = v4l2_fwnode_endpoint_parse(output_fwnode,
> +						 &output_endpoint);
> +
> +	fwnode_handle_put(output_fwnode);
> +
> +	if (!output_fwnode || ret) {
> +		dev_info(csi2dc->dev,
> +			 "missing output node at %pOF, data pipe available only.\n",
> +			 of_node);
> +	} else {
> +		if (output_endpoint.bus_type != V4L2_MBUS_PARALLEL &&
> +		    output_endpoint.bus_type != V4L2_MBUS_BT656) {
> +			dev_err(csi2dc->dev,
> +				"output port must be parallel/bt656.\n");
> +			ret = -EINVAL;
> +			goto csi2dc_of_parse_err;
> +		}
> +
> +		csi2dc->video_pipe = true;
> +
> +		dev_dbg(csi2dc->dev,
> +			"block %pOF [%d.%d]->[%d.%d] video pipeline\n",
> +			of_node, input_endpoint.base.port,
> +			input_endpoint.base.id, output_endpoint.base.port,
> +			output_endpoint.base.id);
> +	}
> +
> +	/* prepare async notifier for subdevice completion */
> +	return csi2dc_prepare_notifier(csi2dc, input_fwnode);
> +
> +csi2dc_of_parse_err:
> +	fwnode_handle_put(input_fwnode);
> +	return ret;
> +}
> +
> +static void csi2dc_default_format(struct csi2dc_device *csi2dc)
> +{
> +	csi2dc->cur_fmt = &csi2dc_formats[0];
> +
> +	csi2dc->format.height = 480;
> +	csi2dc->format.width = 640;
> +	csi2dc->format.code = csi2dc_formats[0].mbus_code;
> +	csi2dc->format.colorspace = V4L2_COLORSPACE_SRGB;
> +	csi2dc->format.field = V4L2_FIELD_NONE;
> +	csi2dc->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	csi2dc->format.quantization = V4L2_QUANTIZATION_DEFAULT;
> +	csi2dc->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +}
> +
> +static int csi2dc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct csi2dc_device *csi2dc;
> +	int ret = 0;
> +	u32 ver;
> +
> +	csi2dc = devm_kzalloc(dev, sizeof(*csi2dc), GFP_KERNEL);
> +	if (!csi2dc)
> +		return -ENOMEM;
> +
> +	csi2dc->dev = dev;
> +
> +	csi2dc->base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(csi2dc->base)) {
> +		dev_err(dev, "base address not set\n");
> +		return PTR_ERR(csi2dc->base);
> +	}
> +
> +	csi2dc->pclk = devm_clk_get(dev, "pclk");
> +	if (IS_ERR(csi2dc->pclk)) {
> +		ret = PTR_ERR(csi2dc->pclk);
> +		dev_err(dev, "failed to get pclk: %d\n", ret);
> +		return ret;
> +	}
> +
> +	csi2dc->scck = devm_clk_get(dev, "scck");
> +	if (IS_ERR(csi2dc->scck)) {
> +		ret = PTR_ERR(csi2dc->scck);
> +		dev_err(dev, "failed to get scck: %d\n", ret);
> +		return ret;
> +	}
> +
> +	v4l2_subdev_init(&csi2dc->csi2dc_sd, &csi2dc_subdev_ops);
> +
> +	csi2dc->csi2dc_sd.owner = THIS_MODULE;
> +	csi2dc->csi2dc_sd.dev = dev;
> +	snprintf(csi2dc->csi2dc_sd.name, sizeof(csi2dc->csi2dc_sd.name),
> +		 "csi2dc");
> +
> +	csi2dc->csi2dc_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	csi2dc->csi2dc_sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
> +
> +	platform_set_drvdata(pdev, csi2dc);
> +
> +	ret = csi2dc_of_parse(csi2dc, dev->of_node);
> +	if (ret)
> +		goto csi2dc_probe_cleanup_entity;
> +
> +	csi2dc->pads[CSI2DC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> +	if (csi2dc->video_pipe)
> +		csi2dc->pads[CSI2DC_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> +
> +	ret = media_entity_pads_init(&csi2dc->csi2dc_sd.entity,
> +				     csi2dc->video_pipe ? CSI2DC_PADS_NUM : 1,
> +				     csi2dc->pads);
> +	if (ret < 0) {
> +		dev_err(dev, "media entity init failed\n");
> +		goto csi2dc_probe_cleanup_notifier;
> +	}
> +
> +	csi2dc_default_format(csi2dc);
> +
> +	/* turn power on to validate capabilities */
> +	ret = csi2dc_power(csi2dc, true);
> +	if (ret < 0)
> +		goto csi2dc_probe_cleanup_notifier;
> +
> +	pm_runtime_set_active(dev);
> +	pm_runtime_enable(dev);
> +	ver = csi2dc_readl(csi2dc, CSI2DC_VERSION);
> +
> +	/*
> +	 * we must register the subdev after PM runtime has been requested,
> +	 * otherwise we might bound immediately and request pm_runtime_resume
> +	 * before runtime_enable.
> +	 */
> +	ret = v4l2_async_register_subdev(&csi2dc->csi2dc_sd);
> +	if (ret) {
> +		dev_err(csi2dc->dev, "failed to register the subdevice\n");
> +		goto csi2dc_probe_cleanup_notifier;
> +	}
> +
> +	dev_info(dev, "Microchip CSI2DC version %x\n", ver);
> +
> +	return 0;
> +
> +csi2dc_probe_cleanup_notifier:
> +	v4l2_async_nf_cleanup(&csi2dc->notifier);
> +csi2dc_probe_cleanup_entity:
> +	media_entity_cleanup(&csi2dc->csi2dc_sd.entity);
> +
> +	return ret;
> +}
> +
> +static int csi2dc_remove(struct platform_device *pdev)
> +{
> +	struct csi2dc_device *csi2dc = platform_get_drvdata(pdev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +
> +	v4l2_async_unregister_subdev(&csi2dc->csi2dc_sd);
> +	v4l2_async_nf_unregister(&csi2dc->notifier);
> +	v4l2_async_nf_cleanup(&csi2dc->notifier);
> +	media_entity_cleanup(&csi2dc->csi2dc_sd.entity);
> +
> +	return 0;
> +}
> +
> +static int __maybe_unused csi2dc_runtime_suspend(struct device *dev)
> +{
> +	struct csi2dc_device *csi2dc = dev_get_drvdata(dev);
> +
> +	return csi2dc_power(csi2dc, false);
> +}
> +
> +static int __maybe_unused csi2dc_runtime_resume(struct device *dev)
> +{
> +	struct csi2dc_device *csi2dc = dev_get_drvdata(dev);
> +
> +	return csi2dc_power(csi2dc, true);
> +}
> +
> +static const struct dev_pm_ops csi2dc_dev_pm_ops = {
> +	SET_RUNTIME_PM_OPS(csi2dc_runtime_suspend, csi2dc_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id csi2dc_of_match[] = {
> +	{ .compatible = "microchip,sama7g5-csi2dc" },
> +	{ }
> +};
> +
> +MODULE_DEVICE_TABLE(of, csi2dc_of_match);
> +
> +static struct platform_driver csi2dc_driver = {
> +	.probe	= csi2dc_probe,
> +	.remove = csi2dc_remove,
> +	.driver = {
> +		.name =			"microchip-csi2dc",
> +		.pm =			&csi2dc_dev_pm_ops,
> +		.of_match_table =	of_match_ptr(csi2dc_of_match),
> +	},
> +};
> +
> +module_platform_driver(csi2dc_driver);
> +
> +MODULE_AUTHOR("Eugen Hristev <eugen.hristev at microchip.com>");
> +MODULE_DESCRIPTION("Microchip CSI2 Demux Controller driver");
> +MODULE_LICENSE("GPL v2");
> --
> 2.25.1
>


From jacopo at jmondi.org  Tue Jan 11 07:43:27 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Tue, 11 Jan 2022 16:43:27 +0100
Subject: [PATCH v3 04/23] media: atmel: atmel-isc: split the clock code
 into separate source file
In-Reply-To: <20211213134940.324266-5-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-5-eugen.hristev@microchip.com>
Message-ID: <20220111154327.jehoy33ajyxhqgu3@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:21PM +0200, Eugen Hristev wrote:
> The atmel-isc-base is getting crowded. Split the clock functions into
> atmel-isc-clk.c.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j

> ---
> Changes in v3:
> - squash with maintainers, add patterns in maintainers
>
>  MAINTAINERS                                   |   7 +-
>  drivers/media/platform/atmel/Makefile         |   3 +-
>  drivers/media/platform/atmel/atmel-isc-base.c | 295 -----------------
>  drivers/media/platform/atmel/atmel-isc-clk.c  | 311 ++++++++++++++++++
>  drivers/media/platform/atmel/atmel-isc.h      |   7 +
>  5 files changed, 322 insertions(+), 301 deletions(-)
>  create mode 100644 drivers/media/platform/atmel/atmel-isc-clk.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index afb74460e5c1..6aa274129751 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -12500,11 +12500,8 @@ L:	linux-media at vger.kernel.org
>  S:	Supported
>  F:	Documentation/devicetree/bindings/media/atmel,isc.yaml
>  F:	Documentation/devicetree/bindings/media/microchip,xisc.yaml
> -F:	drivers/media/platform/atmel/atmel-isc-base.c
> -F:	drivers/media/platform/atmel/atmel-isc-regs.h
> -F:	drivers/media/platform/atmel/atmel-isc.h
> -F:	drivers/media/platform/atmel/atmel-sama5d2-isc.c
> -F:	drivers/media/platform/atmel/atmel-sama7g5-isc.c
> +F:	drivers/media/platform/atmel/atmel-isc*
> +F:	drivers/media/platform/atmel/atmel-sama*-isc*
>  F:	include/linux/atmel-isc-media.h
>
>  MICROCHIP ISI DRIVER
> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
> index 39f0a7eba702..794e8f739287 100644
> --- a/drivers/media/platform/atmel/Makefile
> +++ b/drivers/media/platform/atmel/Makefile
> @@ -1,9 +1,10 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  atmel-isc-objs = atmel-sama5d2-isc.o
>  atmel-xisc-objs = atmel-sama7g5-isc.o
> +atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
>
>  obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
> -obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-base.o
> +obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
>  obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o
>  obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o
>  obj-$(CONFIG_VIDEO_MICROCHIP_CSI2DC) += microchip-csi2dc.o
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index 660cd0ab6749..58f468d32613 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -8,10 +8,6 @@
>   * Author: Eugen Hristev <eugen.hristev at microchip.com>
>   *
>   */
> -
> -#include <linux/clk.h>
> -#include <linux/clkdev.h>
> -#include <linux/clk-provider.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
>  #include <linux/math64.h>
> @@ -100,297 +96,6 @@ static inline void isc_reset_awb_ctrls(struct isc_device *isc)
>  	}
>  }
>
> -static int isc_wait_clk_stable(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	struct regmap *regmap = isc_clk->regmap;
> -	unsigned long timeout = jiffies + usecs_to_jiffies(1000);
> -	unsigned int status;
> -
> -	while (time_before(jiffies, timeout)) {
> -		regmap_read(regmap, ISC_CLKSR, &status);
> -		if (!(status & ISC_CLKSR_SIP))
> -			return 0;
> -
> -		usleep_range(10, 250);
> -	}
> -
> -	return -ETIMEDOUT;
> -}
> -
> -static int isc_clk_prepare(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	int ret;
> -
> -	ret = pm_runtime_resume_and_get(isc_clk->dev);
> -	if (ret < 0)
> -		return ret;
> -
> -	return isc_wait_clk_stable(hw);
> -}
> -
> -static void isc_clk_unprepare(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -
> -	isc_wait_clk_stable(hw);
> -
> -	pm_runtime_put_sync(isc_clk->dev);
> -}
> -
> -static int isc_clk_enable(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	u32 id = isc_clk->id;
> -	struct regmap *regmap = isc_clk->regmap;
> -	unsigned long flags;
> -	unsigned int status;
> -
> -	dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n",
> -		__func__, id, isc_clk->div, isc_clk->parent_id);
> -
> -	spin_lock_irqsave(&isc_clk->lock, flags);
> -	regmap_update_bits(regmap, ISC_CLKCFG,
> -			   ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
> -			   (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
> -			   (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
> -
> -	regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
> -	spin_unlock_irqrestore(&isc_clk->lock, flags);
> -
> -	regmap_read(regmap, ISC_CLKSR, &status);
> -	if (status & ISC_CLK(id))
> -		return 0;
> -	else
> -		return -EINVAL;
> -}
> -
> -static void isc_clk_disable(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	u32 id = isc_clk->id;
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&isc_clk->lock, flags);
> -	regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
> -	spin_unlock_irqrestore(&isc_clk->lock, flags);
> -}
> -
> -static int isc_clk_is_enabled(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	u32 status;
> -	int ret;
> -
> -	ret = pm_runtime_resume_and_get(isc_clk->dev);
> -	if (ret < 0)
> -		return 0;
> -
> -	regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
> -
> -	pm_runtime_put_sync(isc_clk->dev);
> -
> -	return status & ISC_CLK(isc_clk->id) ? 1 : 0;
> -}
> -
> -static unsigned long
> -isc_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -
> -	return DIV_ROUND_CLOSEST(parent_rate, isc_clk->div + 1);
> -}
> -
> -static int isc_clk_determine_rate(struct clk_hw *hw,
> -				   struct clk_rate_request *req)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	long best_rate = -EINVAL;
> -	int best_diff = -1;
> -	unsigned int i, div;
> -
> -	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
> -		struct clk_hw *parent;
> -		unsigned long parent_rate;
> -
> -		parent = clk_hw_get_parent_by_index(hw, i);
> -		if (!parent)
> -			continue;
> -
> -		parent_rate = clk_hw_get_rate(parent);
> -		if (!parent_rate)
> -			continue;
> -
> -		for (div = 1; div < ISC_CLK_MAX_DIV + 2; div++) {
> -			unsigned long rate;
> -			int diff;
> -
> -			rate = DIV_ROUND_CLOSEST(parent_rate, div);
> -			diff = abs(req->rate - rate);
> -
> -			if (best_diff < 0 || best_diff > diff) {
> -				best_rate = rate;
> -				best_diff = diff;
> -				req->best_parent_rate = parent_rate;
> -				req->best_parent_hw = parent;
> -			}
> -
> -			if (!best_diff || rate < req->rate)
> -				break;
> -		}
> -
> -		if (!best_diff)
> -			break;
> -	}
> -
> -	dev_dbg(isc_clk->dev,
> -		"ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
> -		__func__, best_rate,
> -		__clk_get_name((req->best_parent_hw)->clk),
> -		req->best_parent_rate);
> -
> -	if (best_rate < 0)
> -		return best_rate;
> -
> -	req->rate = best_rate;
> -
> -	return 0;
> -}
> -
> -static int isc_clk_set_parent(struct clk_hw *hw, u8 index)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -
> -	if (index >= clk_hw_get_num_parents(hw))
> -		return -EINVAL;
> -
> -	isc_clk->parent_id = index;
> -
> -	return 0;
> -}
> -
> -static u8 isc_clk_get_parent(struct clk_hw *hw)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -
> -	return isc_clk->parent_id;
> -}
> -
> -static int isc_clk_set_rate(struct clk_hw *hw,
> -			     unsigned long rate,
> -			     unsigned long parent_rate)
> -{
> -	struct isc_clk *isc_clk = to_isc_clk(hw);
> -	u32 div;
> -
> -	if (!rate)
> -		return -EINVAL;
> -
> -	div = DIV_ROUND_CLOSEST(parent_rate, rate);
> -	if (div > (ISC_CLK_MAX_DIV + 1) || !div)
> -		return -EINVAL;
> -
> -	isc_clk->div = div - 1;
> -
> -	return 0;
> -}
> -
> -static const struct clk_ops isc_clk_ops = {
> -	.prepare	= isc_clk_prepare,
> -	.unprepare	= isc_clk_unprepare,
> -	.enable		= isc_clk_enable,
> -	.disable	= isc_clk_disable,
> -	.is_enabled	= isc_clk_is_enabled,
> -	.recalc_rate	= isc_clk_recalc_rate,
> -	.determine_rate	= isc_clk_determine_rate,
> -	.set_parent	= isc_clk_set_parent,
> -	.get_parent	= isc_clk_get_parent,
> -	.set_rate	= isc_clk_set_rate,
> -};
> -
> -static int isc_clk_register(struct isc_device *isc, unsigned int id)
> -{
> -	struct regmap *regmap = isc->regmap;
> -	struct device_node *np = isc->dev->of_node;
> -	struct isc_clk *isc_clk;
> -	struct clk_init_data init;
> -	const char *clk_name = np->name;
> -	const char *parent_names[3];
> -	int num_parents;
> -
> -	if (id == ISC_ISPCK && !isc->ispck_required)
> -		return 0;
> -
> -	num_parents = of_clk_get_parent_count(np);
> -	if (num_parents < 1 || num_parents > 3)
> -		return -EINVAL;
> -
> -	if (num_parents > 2 && id == ISC_ISPCK)
> -		num_parents = 2;
> -
> -	of_clk_parent_fill(np, parent_names, num_parents);
> -
> -	if (id == ISC_MCK)
> -		of_property_read_string(np, "clock-output-names", &clk_name);
> -	else
> -		clk_name = "isc-ispck";
> -
> -	init.parent_names	= parent_names;
> -	init.num_parents	= num_parents;
> -	init.name		= clk_name;
> -	init.ops		= &isc_clk_ops;
> -	init.flags		= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
> -
> -	isc_clk = &isc->isc_clks[id];
> -	isc_clk->hw.init	= &init;
> -	isc_clk->regmap		= regmap;
> -	isc_clk->id		= id;
> -	isc_clk->dev		= isc->dev;
> -	spin_lock_init(&isc_clk->lock);
> -
> -	isc_clk->clk = clk_register(isc->dev, &isc_clk->hw);
> -	if (IS_ERR(isc_clk->clk)) {
> -		dev_err(isc->dev, "%s: clock register fail\n", clk_name);
> -		return PTR_ERR(isc_clk->clk);
> -	} else if (id == ISC_MCK)
> -		of_clk_add_provider(np, of_clk_src_simple_get, isc_clk->clk);
> -
> -	return 0;
> -}
> -
> -int isc_clk_init(struct isc_device *isc)
> -{
> -	unsigned int i;
> -	int ret;
> -
> -	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++)
> -		isc->isc_clks[i].clk = ERR_PTR(-EINVAL);
> -
> -	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
> -		ret = isc_clk_register(isc, i);
> -		if (ret)
> -			return ret;
> -	}
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(isc_clk_init);
> -
> -void isc_clk_cleanup(struct isc_device *isc)
> -{
> -	unsigned int i;
> -
> -	of_clk_del_provider(isc->dev->of_node);
> -
> -	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
> -		struct isc_clk *isc_clk = &isc->isc_clks[i];
> -
> -		if (!IS_ERR(isc_clk->clk))
> -			clk_unregister(isc_clk->clk);
> -	}
> -}
> -EXPORT_SYMBOL_GPL(isc_clk_cleanup);
>
>  static int isc_queue_setup(struct vb2_queue *vq,
>  			    unsigned int *nbuffers, unsigned int *nplanes,
> diff --git a/drivers/media/platform/atmel/atmel-isc-clk.c b/drivers/media/platform/atmel/atmel-isc-clk.c
> new file mode 100644
> index 000000000000..2059fe376b00
> --- /dev/null
> +++ b/drivers/media/platform/atmel/atmel-isc-clk.c
> @@ -0,0 +1,311 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Microchip Image Sensor Controller (ISC) common clock driver setup
> + *
> + * Copyright (C) 2016 Microchip Technology, Inc.
> + *
> + * Author: Songjun Wu
> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
> + *
> + */
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +
> +#include "atmel-isc-regs.h"
> +#include "atmel-isc.h"
> +
> +static int isc_wait_clk_stable(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	struct regmap *regmap = isc_clk->regmap;
> +	unsigned long timeout = jiffies + usecs_to_jiffies(1000);
> +	unsigned int status;
> +
> +	while (time_before(jiffies, timeout)) {
> +		regmap_read(regmap, ISC_CLKSR, &status);
> +		if (!(status & ISC_CLKSR_SIP))
> +			return 0;
> +
> +		usleep_range(10, 250);
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static int isc_clk_prepare(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	int ret;
> +
> +	ret = pm_runtime_resume_and_get(isc_clk->dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	return isc_wait_clk_stable(hw);
> +}
> +
> +static void isc_clk_unprepare(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +
> +	isc_wait_clk_stable(hw);
> +
> +	pm_runtime_put_sync(isc_clk->dev);
> +}
> +
> +static int isc_clk_enable(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	u32 id = isc_clk->id;
> +	struct regmap *regmap = isc_clk->regmap;
> +	unsigned long flags;
> +	unsigned int status;
> +
> +	dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n",
> +		__func__, id, isc_clk->div, isc_clk->parent_id);
> +
> +	spin_lock_irqsave(&isc_clk->lock, flags);
> +	regmap_update_bits(regmap, ISC_CLKCFG,
> +			   ISC_CLKCFG_DIV_MASK(id) | ISC_CLKCFG_SEL_MASK(id),
> +			   (isc_clk->div << ISC_CLKCFG_DIV_SHIFT(id)) |
> +			   (isc_clk->parent_id << ISC_CLKCFG_SEL_SHIFT(id)));
> +
> +	regmap_write(regmap, ISC_CLKEN, ISC_CLK(id));
> +	spin_unlock_irqrestore(&isc_clk->lock, flags);
> +
> +	regmap_read(regmap, ISC_CLKSR, &status);
> +	if (status & ISC_CLK(id))
> +		return 0;
> +	else
> +		return -EINVAL;
> +}
> +
> +static void isc_clk_disable(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	u32 id = isc_clk->id;
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&isc_clk->lock, flags);
> +	regmap_write(isc_clk->regmap, ISC_CLKDIS, ISC_CLK(id));
> +	spin_unlock_irqrestore(&isc_clk->lock, flags);
> +}
> +
> +static int isc_clk_is_enabled(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	u32 status;
> +	int ret;
> +
> +	ret = pm_runtime_resume_and_get(isc_clk->dev);
> +	if (ret < 0)
> +		return 0;
> +
> +	regmap_read(isc_clk->regmap, ISC_CLKSR, &status);
> +
> +	pm_runtime_put_sync(isc_clk->dev);
> +
> +	return status & ISC_CLK(isc_clk->id) ? 1 : 0;
> +}
> +
> +static unsigned long
> +isc_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +
> +	return DIV_ROUND_CLOSEST(parent_rate, isc_clk->div + 1);
> +}
> +
> +static int isc_clk_determine_rate(struct clk_hw *hw,
> +				  struct clk_rate_request *req)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	long best_rate = -EINVAL;
> +	int best_diff = -1;
> +	unsigned int i, div;
> +
> +	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
> +		struct clk_hw *parent;
> +		unsigned long parent_rate;
> +
> +		parent = clk_hw_get_parent_by_index(hw, i);
> +		if (!parent)
> +			continue;
> +
> +		parent_rate = clk_hw_get_rate(parent);
> +		if (!parent_rate)
> +			continue;
> +
> +		for (div = 1; div < ISC_CLK_MAX_DIV + 2; div++) {
> +			unsigned long rate;
> +			int diff;
> +
> +			rate = DIV_ROUND_CLOSEST(parent_rate, div);
> +			diff = abs(req->rate - rate);
> +
> +			if (best_diff < 0 || best_diff > diff) {
> +				best_rate = rate;
> +				best_diff = diff;
> +				req->best_parent_rate = parent_rate;
> +				req->best_parent_hw = parent;
> +			}
> +
> +			if (!best_diff || rate < req->rate)
> +				break;
> +		}
> +
> +		if (!best_diff)
> +			break;
> +	}
> +
> +	dev_dbg(isc_clk->dev,
> +		"ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n",
> +		__func__, best_rate,
> +		__clk_get_name((req->best_parent_hw)->clk),
> +		req->best_parent_rate);
> +
> +	if (best_rate < 0)
> +		return best_rate;
> +
> +	req->rate = best_rate;
> +
> +	return 0;
> +}
> +
> +static int isc_clk_set_parent(struct clk_hw *hw, u8 index)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +
> +	if (index >= clk_hw_get_num_parents(hw))
> +		return -EINVAL;
> +
> +	isc_clk->parent_id = index;
> +
> +	return 0;
> +}
> +
> +static u8 isc_clk_get_parent(struct clk_hw *hw)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +
> +	return isc_clk->parent_id;
> +}
> +
> +static int isc_clk_set_rate(struct clk_hw *hw,
> +			    unsigned long rate,
> +			    unsigned long parent_rate)
> +{
> +	struct isc_clk *isc_clk = to_isc_clk(hw);
> +	u32 div;
> +
> +	if (!rate)
> +		return -EINVAL;
> +
> +	div = DIV_ROUND_CLOSEST(parent_rate, rate);
> +	if (div > (ISC_CLK_MAX_DIV + 1) || !div)
> +		return -EINVAL;
> +
> +	isc_clk->div = div - 1;
> +
> +	return 0;
> +}
> +
> +static const struct clk_ops isc_clk_ops = {
> +	.prepare	= isc_clk_prepare,
> +	.unprepare	= isc_clk_unprepare,
> +	.enable		= isc_clk_enable,
> +	.disable	= isc_clk_disable,
> +	.is_enabled	= isc_clk_is_enabled,
> +	.recalc_rate	= isc_clk_recalc_rate,
> +	.determine_rate	= isc_clk_determine_rate,
> +	.set_parent	= isc_clk_set_parent,
> +	.get_parent	= isc_clk_get_parent,
> +	.set_rate	= isc_clk_set_rate,
> +};
> +
> +static int isc_clk_register(struct isc_device *isc, unsigned int id)
> +{
> +	struct regmap *regmap = isc->regmap;
> +	struct device_node *np = isc->dev->of_node;
> +	struct isc_clk *isc_clk;
> +	struct clk_init_data init;
> +	const char *clk_name = np->name;
> +	const char *parent_names[3];
> +	int num_parents;
> +
> +	if (id == ISC_ISPCK && !isc->ispck_required)
> +		return 0;
> +
> +	num_parents = of_clk_get_parent_count(np);
> +	if (num_parents < 1 || num_parents > 3)
> +		return -EINVAL;
> +
> +	if (num_parents > 2 && id == ISC_ISPCK)
> +		num_parents = 2;
> +
> +	of_clk_parent_fill(np, parent_names, num_parents);
> +
> +	if (id == ISC_MCK)
> +		of_property_read_string(np, "clock-output-names", &clk_name);
> +	else
> +		clk_name = "isc-ispck";
> +
> +	init.parent_names	= parent_names;
> +	init.num_parents	= num_parents;
> +	init.name		= clk_name;
> +	init.ops		= &isc_clk_ops;
> +	init.flags		= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
> +
> +	isc_clk = &isc->isc_clks[id];
> +	isc_clk->hw.init	= &init;
> +	isc_clk->regmap		= regmap;
> +	isc_clk->id		= id;
> +	isc_clk->dev		= isc->dev;
> +	spin_lock_init(&isc_clk->lock);
> +
> +	isc_clk->clk = clk_register(isc->dev, &isc_clk->hw);
> +	if (IS_ERR(isc_clk->clk)) {
> +		dev_err(isc->dev, "%s: clock register fail\n", clk_name);
> +		return PTR_ERR(isc_clk->clk);
> +	} else if (id == ISC_MCK) {
> +		of_clk_add_provider(np, of_clk_src_simple_get, isc_clk->clk);
> +	}
> +
> +	return 0;
> +}
> +
> +int isc_clk_init(struct isc_device *isc)
> +{
> +	unsigned int i;
> +	int ret;
> +
> +	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++)
> +		isc->isc_clks[i].clk = ERR_PTR(-EINVAL);
> +
> +	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
> +		ret = isc_clk_register(isc, i);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(isc_clk_init);
> +
> +void isc_clk_cleanup(struct isc_device *isc)
> +{
> +	unsigned int i;
> +
> +	of_clk_del_provider(isc->dev->of_node);
> +
> +	for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) {
> +		struct isc_clk *isc_clk = &isc->isc_clks[i];
> +
> +		if (!IS_ERR(isc_clk->clk))
> +			clk_unregister(isc_clk->clk);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(isc_clk_cleanup);
> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> index 2bfcb135ef13..32448ccfc636 100644
> --- a/drivers/media/platform/atmel/atmel-isc.h
> +++ b/drivers/media/platform/atmel/atmel-isc.h
> @@ -10,6 +10,13 @@
>   */
>  #ifndef _ATMEL_ISC_H_
>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>
> +
> +#include <media/v4l2-ctrls.h>
> +#include <media/v4l2-device.h>
> +#include <media/videobuf2-dma-contig.h>
> +
>  #define ISC_CLK_MAX_DIV		255
>
>  enum isc_clk_id {
> --
> 2.25.1
>


From arnd at arndb.de  Tue Jan 11 07:46:21 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 11 Jan 2022 16:46:21 +0100
Subject: consolidate the compat fcntl definitions
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <CAK8P3a2nY60Pgz1Q0YJ-bMsJdJfFNw8q6R7R2WzPCj+tVdA=+g@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:35 AM Christoph Hellwig <hch at lst.de> wrote:
>
> Hi all,
>
> currenty the compat fcnt definitions are duplicate for all compat
> architectures, and the native fcntl64 definitions aren't even usable
> from userspace due to a bogus CONFIG_64BIT ifdef.  This series tries
> to sort out all that.

The changes look good, but I have the same comment on your last patch that
I had for Guo Ren's version. Once we have resolved that, I can apply the
series in the asm-generic tree, or provide an Ack to have it all merged
along with the compat mode changes in the risc-v tree.

       Arnd


From hverkuil at xs4all.nl  Tue Jan 11 07:53:40 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 11 Jan 2022 16:53:40 +0100
Subject: [PATCH v3 07/23] media: atmel: atmel-isc-base: use streaming
 status when queueing buffers
In-Reply-To: <20211213134940.324266-8-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-8-eugen.hristev@microchip.com>
Message-ID: <c6adb59e-4554-dc08-3772-148eb22c29ba@xs4all.nl>

On 13/12/2021 14:49, Eugen Hristev wrote:
> During experiments with libcamera, it looks like vb2_is_streaming returns
> true before our start streaming is called.
> Order of operations is streamon -> queue -> start_streaming
> ISC would have started the DMA immediately when a buffer is being added
> to the vbqueue if the queue is streaming.
> It is more safe to start the DMA after the start streaming of the driver is
> called.
> Thus, even if vb2queue is streaming, add the buffer to the dma queue of the
> driver instead of actually starting the DMA process, if the start streaming
> has not been called yet.
> 
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
>  drivers/media/platform/atmel/atmel-isc-base.c | 17 ++++++++++-------
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index 26a6090f056c..e6c9071c04f0 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -441,12 +441,14 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
>  	unsigned long flags;
>  
>  	spin_lock_irqsave(&isc->dma_queue_lock, flags);
> -	if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
> -		vb2_is_streaming(vb->vb2_queue)) {
> +
> +	if (!isc->cur_frm && list_empty(&isc->dma_queue) && !isc->stop) {
>  		isc->cur_frm = buf;
>  		isc_start_dma(isc);
> -	} else
> +	} else {
>  		list_add_tail(&buf->list, &isc->dma_queue);
> +	}
> +
>  	spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
>  }

Both the old and new code doesn't make a lot of sense.

buf_queue is only called by vb2 if start_streaming has already been called or is
about to be called.

Typically all that the buf_queue op does is to call list_add_tail(&buf->list, &isc->dma_queue);
inside the spinlock.

>  
> @@ -1014,7 +1016,7 @@ static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>  {
>  	struct isc_device *isc = video_drvdata(file);
>  
> -	if (vb2_is_streaming(&isc->vb2_vidq))
> +	if (!isc->stop)

This is weird as well. Normally this calls vb2_is_busy to check if the
queue is busy (that really means that buffers are already allocated, so
changing the format isn't allowed anymore).

>  		return -EBUSY;
>  
>  	return isc_set_fmt(isc, f);
> @@ -1536,7 +1538,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>  
>  		isc_update_awb_ctrls(isc);
>  
> -		if (vb2_is_streaming(&isc->vb2_vidq)) {
> +		if (!isc->stop) {

Ditto.

>  			/*
>  			 * If we are streaming, we can update profile to
>  			 * have the new settings in place.
> @@ -1552,8 +1554,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>  		}
>  
>  		/* if we have autowhitebalance on, start histogram procedure */
> -		if (ctrls->awb == ISC_WB_AUTO &&
> -		    vb2_is_streaming(&isc->vb2_vidq) &&
> +		if (ctrls->awb == ISC_WB_AUTO && !isc->stop &&
>  		    ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>  			isc_set_histogram(isc, true);
>  
> @@ -1829,6 +1830,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>  	struct vb2_queue *q = &isc->vb2_vidq;
>  	int ret = 0;
>  
> +	isc->stop = true;
> +

I'm really not sure that you need the stop bool at all.

>  	INIT_WORK(&isc->awb_work, isc_awb_work);
>  
>  	ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);

Regards,

	Hans


From boger at wirenboard.com  Tue Jan 11 07:57:06 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 18:57:06 +0300
Subject: [PATCH v2 0/3] add support for Allwinner R40 CAN controller
Message-ID: <20220111155709.56501-1-boger@wirenboard.com>

Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
controller is the same as in earlier A10 and A20 SoCs, but needs reset
line to be deasserted before use.

This patch series introduce new compatible for R40 CAN controller,
add support for reset line in driver and add the corresponding nodes
to the SoC .dtsi file.

The CAN IP was documented in early V40 datasheet [1]. It also fully
supported in vendor BSP. However, CAN description was removed from
more recent A40i, T3 and R40 user manuals and datasheets.
Anyway, we verified that the CAN controller is indeed there and tested
it extensively on A40i-based custom hardware [2].

[1] https://linux-sunxi.org/File:Allwinner_V40_Datasheet_V1.0.pdf
[2] https://wirenboard.com/en/product/wiren-board-7/

Changes in v2:
  - sort pinmux nodes alphabetically and mark them with omit-if-no-ref

Evgeny Boger (3):
  dt-bindings: net: can: add support for Allwinner R40 CAN controller
  can: sun4i_can: add support for R40 CAN controller
  ARM: dts: sun8i: r40: add node for CAN controller

 .../net/can/allwinner,sun4i-a10-can.yaml      | 24 ++++++++
 arch/arm/boot/dts/sun8i-r40.dtsi              | 21 +++++++
 drivers/net/can/sun4i_can.c                   | 61 ++++++++++++++++++-
 3 files changed, 105 insertions(+), 1 deletion(-)

-- 
2.25.1


From boger at wirenboard.com  Tue Jan 11 07:57:07 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 18:57:07 +0300
Subject: [PATCH v2 1/3] dt-bindings: net: can: add support for Allwinner R40
 CAN controller
In-Reply-To: <20220111155709.56501-1-boger@wirenboard.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
Message-ID: <20220111155709.56501-2-boger@wirenboard.com>

Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
controller is the same as in earlier A10 and A20 SoCs, but needs reset
line to be deasserted before use.

This patch Introduces new compatible for R40 CAN controller with
required resets property.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 .../net/can/allwinner,sun4i-a10-can.yaml      | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml b/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
index a95960ee3feb..c93fe9d3ea82 100644
--- a/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
+++ b/Documentation/devicetree/bindings/net/can/allwinner,sun4i-a10-can.yaml
@@ -17,6 +17,7 @@ properties:
           - const: allwinner,sun7i-a20-can
           - const: allwinner,sun4i-a10-can
       - const: allwinner,sun4i-a10-can
+      - const: allwinner,sun8i-r40-can
 
   reg:
     maxItems: 1
@@ -27,6 +28,19 @@ properties:
   clocks:
     maxItems: 1
 
+  resets:
+    maxItems: 1
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: allwinner,sun8i-r40-can
+
+then:
+  required:
+    - resets
+
 required:
   - compatible
   - reg
@@ -47,5 +61,15 @@ examples:
         interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
         clocks = <&ccu CLK_APB1_CAN>;
     };
+  - |
+    #define RST_BUS_CAN		68
+    #define CLK_BUS_CAN		91
+    can1: can at 1c2bc00 {
+        compatible = "allwinner,sun8i-r40-can";
+        reg = <0x01c2bc00 0x400>;
+        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&ccu CLK_BUS_CAN>;
+        resets = <&ccu RST_BUS_CAN>;
+    };
 
 ...
-- 
2.25.1



From boger at wirenboard.com  Tue Jan 11 07:57:08 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 18:57:08 +0300
Subject: [PATCH v2 2/3] can: sun4i_can: add support for R40 CAN controller
In-Reply-To: <20220111155709.56501-1-boger@wirenboard.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
Message-ID: <20220111155709.56501-3-boger@wirenboard.com>

Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
controller is the same as in earlier A10 and A20 SoCs, but needs reset
line to be deasserted before use.

This patch adds a new compatible for R40 CAN controller. Depending
on the compatible, reset line can be requested from DT.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 drivers/net/can/sun4i_can.c | 61 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 54aa7c25c4de..24a61326915e 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -61,6 +61,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reset.h>
 
 #define DRV_NAME "sun4i_can"
 
@@ -200,10 +201,20 @@
 #define SUN4I_CAN_MAX_IRQ	20
 #define SUN4I_MODE_MAX_RETRIES	100
 
+/**
+ * struct sun4ican_quirks - Differences between SoC variants.
+ *
+ * @has_reset: SoC needs reset deasserted.
+ */
+struct sun4ican_quirks {
+	bool		has_reset;
+};
+
 struct sun4ican_priv {
 	struct can_priv can;
 	void __iomem *base;
 	struct clk *clk;
+	struct reset_control *reset;
 	spinlock_t cmdreg_lock;	/* lock for concurrent cmd register writes */
 };
 
@@ -702,6 +713,13 @@ static int sun4ican_open(struct net_device *dev)
 		goto exit_irq;
 	}
 
+	/* software reset deassert */
+	err = reset_control_deassert(priv->reset);
+	if (err) {
+		netdev_err(dev, "could not deassert CAN reset\n");
+		goto exit_soft_reset;
+	}
+
 	/* turn on clocking for CAN peripheral block */
 	err = clk_prepare_enable(priv->clk);
 	if (err) {
@@ -723,6 +741,8 @@ static int sun4ican_open(struct net_device *dev)
 exit_can_start:
 	clk_disable_unprepare(priv->clk);
 exit_clock:
+	reset_control_assert(priv->reset);
+exit_soft_reset:
 	free_irq(dev->irq, dev);
 exit_irq:
 	close_candev(dev);
@@ -736,6 +756,7 @@ static int sun4ican_close(struct net_device *dev)
 	netif_stop_queue(dev);
 	sun4i_can_stop(dev);
 	clk_disable_unprepare(priv->clk);
+	reset_control_assert(priv->reset);
 
 	free_irq(dev->irq, dev);
 	close_candev(dev);
@@ -750,8 +771,27 @@ static const struct net_device_ops sun4ican_netdev_ops = {
 	.ndo_start_xmit = sun4ican_start_xmit,
 };
 
+static const struct sun4ican_quirks sun4ican_quirks_a10 = {
+	.has_reset = false,
+};
+
+static const struct sun4ican_quirks sun4ican_quirks_r40 = {
+	.has_reset = true,
+};
+
 static const struct of_device_id sun4ican_of_match[] = {
-	{.compatible = "allwinner,sun4i-a10-can"},
+	{
+		.compatible = "allwinner,sun4i-a10-can",
+		.data = &sun4ican_quirks_a10
+	},
+	{
+		.compatible = "allwinner,sun7i-a20-can",
+		.data = &sun4ican_quirks_a10
+	},
+	{
+		.compatible = "allwinner,sun8i-r40-can",
+		.data = &sun4ican_quirks_r40
+	},
 	{},
 };
 
@@ -771,10 +811,28 @@ static int sun4ican_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
 	struct clk *clk;
+	struct reset_control *reset = NULL;
 	void __iomem *addr;
 	int err, irq;
 	struct net_device *dev;
 	struct sun4ican_priv *priv;
+	const struct sun4ican_quirks *quirks;
+
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (!quirks) {
+		dev_err(&pdev->dev, "failed to determine the quirks to use\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	if (quirks->has_reset) {
+		reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+		if (IS_ERR(reset)) {
+			dev_err(&pdev->dev, "unable to request reset\n");
+			err = PTR_ERR(reset);
+			goto exit;
+		}
+	}
 
 	clk = of_clk_get(np, 0);
 	if (IS_ERR(clk)) {
@@ -818,6 +876,7 @@ static int sun4ican_probe(struct platform_device *pdev)
 				       CAN_CTRLMODE_3_SAMPLES;
 	priv->base = addr;
 	priv->clk = clk;
+	priv->reset = reset;
 	spin_lock_init(&priv->cmdreg_lock);
 
 	platform_set_drvdata(pdev, dev);
-- 
2.25.1



From boger at wirenboard.com  Tue Jan 11 07:57:09 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 18:57:09 +0300
Subject: [PATCH v2 3/3] ARM: dts: sun8i: r40: add node for CAN controller
In-Reply-To: <20220111155709.56501-1-boger@wirenboard.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
Message-ID: <20220111155709.56501-4-boger@wirenboard.com>

Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
controller is the same as in earlier A10 and A20 SoCs, but needs reset
line to be deasserted before use.

This patch adds a CAN node and the corresponding pinctrl descriptions.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 arch/arm/boot/dts/sun8i-r40.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
index 1d87fc0c24ee..2ba0e681a7ac 100644
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
@@ -511,6 +511,18 @@ pio: pinctrl at 1c20800 {
 			#interrupt-cells = <3>;
 			#gpio-cells = <3>;
 
+			/omit-if-no-ref/
+			can_pa_pins: can-pa-pins {
+				pins = "PA16", "PA17";
+				function = "can";
+			};
+
+			/omit-if-no-ref/
+			can_ph_pins: can-ph-pins {
+				pins = "PH20", "PH21";
+				function = "can";
+			};
+
 			clk_out_a_pin: clk-out-a-pin {
 				pins = "PI12";
 				function = "clk_out_a";
@@ -926,6 +938,15 @@ i2c3: i2c at 1c2b800 {
 			#size-cells = <0>;
 		};
 
+		can0: can at 1c2bc00 {
+			compatible = "allwinner,sun8i-r40-can";
+			reg = <0x01c2bc00 0x400>;
+			interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_CAN>;
+			resets = <&ccu RST_BUS_CAN>;
+			status = "disabled";
+		};
+
 		i2c4: i2c at 1c2c000 {
 			compatible = "allwinner,sun6i-a31-i2c";
 			reg = <0x01c2c000 0x400>;
-- 
2.25.1



From jacopo at jmondi.org  Tue Jan 11 08:06:03 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Tue, 11 Jan 2022 17:06:03 +0100
Subject: [PATCH v3 12/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <20211213134940.324266-13-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-13-eugen.hristev@microchip.com>
Message-ID: <20220111160603.qi4kbp6rn45hp7po@uno.localdomain>

Hi Eugen,

On Mon, Dec 13, 2021 at 03:49:29PM +0200, Eugen Hristev wrote:
> Implement the support for media-controller.
> This means that the capabilities of the driver have changed and now
> it also advertises the IO_MC .
> The driver will register it's media device, and add the video entity to this
> media device. The subdevices are registered to the same media device.
> The ISC will have a base entity which is auto-detected as atmel_isc_base.
> It will also register a subdevice that allows cropping of the incoming frame
> to the maximum frame size supported by the ISC.
> The ISC will create a link between the subdevice that is asynchronously
> registered and the atmel_isc_scaler entity.
> Then, the atmel_isc_scaler and atmel_isc_base are connected through another
> link.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
> Changes in v2:
> - implement try formats
>
>  drivers/media/platform/atmel/Makefile         |   2 +-
>  drivers/media/platform/atmel/atmel-isc-base.c |  27 +-
>  drivers/media/platform/atmel/atmel-isc-mc.c   | 287 ++++++++++++++++++
>  drivers/media/platform/atmel/atmel-isc.h      |  36 +++
>  .../media/platform/atmel/atmel-sama5d2-isc.c  |  14 +-
>  .../media/platform/atmel/atmel-sama7g5-isc.c  |  12 +-
>  6 files changed, 370 insertions(+), 8 deletions(-)
>  create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
>
> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
> index 794e8f739287..aa7a18b428f6 100644
> --- a/drivers/media/platform/atmel/Makefile
> +++ b/drivers/media/platform/atmel/Makefile
> @@ -1,7 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  atmel-isc-objs = atmel-sama5d2-isc.o
>  atmel-xisc-objs = atmel-sama7g5-isc.o
> -atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
> +atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o atmel-isc-mc.o
>
>  obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
>  obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index d0542b97a391..b0c3ed21f372 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -1726,6 +1726,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>  					      struct isc_device, v4l2_dev);
>  	struct isc_subdev_entity *subdev_entity =
>  		container_of(notifier, struct isc_subdev_entity, notifier);
> +	int pad;
>
>  	if (video_is_registered(&isc->video_dev)) {
>  		v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
> @@ -1734,6 +1735,16 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>
>  	subdev_entity->sd = subdev;
>
> +	pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
> +					  MEDIA_PAD_FL_SOURCE);
> +	if (pad < 0) {
> +		v4l2_err(&isc->v4l2_dev, "failed to find pad for %s\n",
> +			 subdev->name);
> +		return pad;
> +	}
> +
> +	isc->remote_pad = pad;
> +
>  	return 0;
>  }
>
> @@ -1748,8 +1759,8 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
>  	v4l2_ctrl_handler_free(&isc->ctrls.handler);
>  }
>
> -static struct isc_format *find_format_by_code(struct isc_device *isc,
> -					      unsigned int code, int *index)
> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
> +					   unsigned int code, int *index)
>  {
>  	struct isc_format *fmt = &isc->formats_list[0];
>  	unsigned int i;
> @@ -1765,6 +1776,7 @@ static struct isc_format *find_format_by_code(struct isc_device *isc,
>
>  	return NULL;
>  }
> +EXPORT_SYMBOL_GPL(isc_find_format_by_code);
>
>  static int isc_formats_init(struct isc_device *isc)
>  {
> @@ -1781,7 +1793,7 @@ static int isc_formats_init(struct isc_device *isc)
>  	       NULL, &mbus_code)) {
>  		mbus_code.index++;
>
> -		fmt = find_format_by_code(isc, mbus_code.code, &i);
> +		fmt = isc_find_format_by_code(isc, mbus_code.code, &i);
>  		if (!fmt) {
>  			v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
>  				  mbus_code.code);
> @@ -1909,7 +1921,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>  	vdev->queue		= q;
>  	vdev->lock		= &isc->lock;
>  	vdev->ctrl_handler	= &isc->ctrls.handler;
> -	vdev->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
> +	vdev->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
> +				  V4L2_CAP_IO_MC;
>  	video_set_drvdata(vdev, isc);
>
>  	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
> @@ -1919,8 +1932,14 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>  		goto isc_async_complete_err;
>  	}
>
> +	ret = isc_mc_register(isc);
> +	if (ret < 0)
> +		goto isc_async_complete_unregister_device;
>  	return 0;
>
> +isc_async_complete_unregister_device:
> +	video_unregister_device(vdev);
> +
>  isc_async_complete_err:
>  	mutex_destroy(&isc->lock);
>  	return ret;
> diff --git a/drivers/media/platform/atmel/atmel-isc-mc.c b/drivers/media/platform/atmel/atmel-isc-mc.c
> new file mode 100644
> index 000000000000..2aea81d77b2f
> --- /dev/null
> +++ b/drivers/media/platform/atmel/atmel-isc-mc.c
> @@ -0,0 +1,287 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Microchip Image Sensor Controller (ISC) Media Controller support
> + *
> + * Copyright (C) 2021 Microchip Technology, Inc.
> + *
> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
> + *
> + */
> +
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-subdev.h>

Should you include <media/media-entity.h> and <media/media-device.h> ?

Also, should you select MEDIA_CONTROLLER and V4L2_SUBDEV_API for all
the Kconfig symbols ?

> +
> +#include "atmel-isc-regs.h"
> +#include "atmel-isc.h"
> +
> +static const struct media_device_ops isc_media_ops = {
> +};

Do you need this even if it's empty ?

> +
> +static int isc_scaler_get_fmt(struct v4l2_subdev *sd,
> +			      struct v4l2_subdev_state *sd_state,
> +			      struct v4l2_subdev_format *format)
> +{
> +	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt;
> +
> +	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> +							  format->pad);
> +		format->format = *v4l2_try_fmt;
> +
> +		return 0;
> +	}
> +
> +	format->format = isc->scaler_format;
> +
> +	return 0;
> +}
> +
> +static int isc_scaler_set_fmt(struct v4l2_subdev *sd,
> +			      struct v4l2_subdev_state *sd_state,
> +			      struct v4l2_subdev_format *req_fmt)
> +{
> +	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt;
> +	struct isc_format *fmt;
> +	unsigned int i;
> +
> +	if (req_fmt->pad == ISC_SCALER_PAD_SOURCE)
> +		v4l_bound_align_image
> +			(&req_fmt->format.width, 16, isc->max_width, 0,
> +			 &req_fmt->format.height, 16, isc->max_height, 0, 0);
> +	else
> +		v4l_bound_align_image
> +			(&req_fmt->format.width, 16, 10000, 0,
> +			 &req_fmt->format.height, 16, 10000, 0, 0);
> +
> +	req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
> +	req_fmt->format.field = V4L2_FIELD_NONE;
> +	req_fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	req_fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
> +	req_fmt->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +
> +	fmt = isc_find_format_by_code(isc, req_fmt->format.code, &i);
> +
> +	if (!fmt)
> +		fmt = &isc->formats_list[0];
> +
> +	req_fmt->format.code = fmt->mbus_code;
> +
> +	if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> +		v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> +							  req_fmt->pad);
> +		*v4l2_try_fmt = req_fmt->format;
> +		/* Trying on the pad sink makes the source sink change too */
> +		if (req_fmt->pad == ISC_SCALER_PAD_SINK) {
> +			v4l2_try_fmt =
> +				v4l2_subdev_get_try_format(sd, sd_state,
> +							   ISC_SCALER_PAD_SOURCE);
> +			*v4l2_try_fmt = req_fmt->format;
> +
> +			v4l_bound_align_image(&v4l2_try_fmt->width,
> +					      16, isc->max_width, 0,
> +					      &v4l2_try_fmt->height,
> +					      16, isc->max_height, 0, 0);
> +		}
> +		/* if we are just trying, we are done */
> +		return 0;
> +	}
> +
> +	isc->scaler_format = req_fmt->format;
> +
> +	return 0;
> +}
> +
> +static int isc_scaler_enum_mbus_code(struct v4l2_subdev *sd,
> +				     struct v4l2_subdev_state *sd_state,
> +				     struct v4l2_subdev_mbus_code_enum *code)
> +{
> +	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> +	int supported_index = 0;
> +	int i;
> +
> +	for (i = 0; i < isc->formats_list_size; i++) {
> +		if (!isc->formats_list[i].sd_support)
> +			continue;
> +		if (supported_index == code->index) {
> +			code->code = isc->formats_list[i].mbus_code;
> +			return 0;
> +		}
> +		supported_index++;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static int isc_scaler_g_sel(struct v4l2_subdev *sd,
> +			    struct v4l2_subdev_state *sd_state,
> +			    struct v4l2_subdev_selection *sel)
> +{
> +	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> +
> +	if (sel->pad == ISC_SCALER_PAD_SOURCE)
> +		return -EINVAL;
> +
> +	if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS &&
> +	    sel->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	sel->r.height = isc->max_height;
> +	sel->r.width = isc->max_width;
> +
> +	sel->r.left = 0;
> +	sel->r.top = 0;
> +
> +	return 0;
> +}
> +
> +static int isc_scaler_init_cfg(struct v4l2_subdev *sd,
> +			       struct v4l2_subdev_state *sd_state)
> +{
> +	struct v4l2_mbus_framefmt *v4l2_try_fmt =
> +		v4l2_subdev_get_try_format(sd, sd_state, 0);
> +	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> +
> +	*v4l2_try_fmt = isc->scaler_format;
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
> +	.enum_mbus_code = isc_scaler_enum_mbus_code,
> +	.set_fmt = isc_scaler_set_fmt,
> +	.get_fmt = isc_scaler_get_fmt,
> +	.get_selection = isc_scaler_g_sel,
> +	.init_cfg = isc_scaler_init_cfg,
> +};
> +
> +static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
> +	.pad = &isc_scaler_pad_ops,
> +};
> +
> +static int isc_init_own_sd(struct isc_device *isc)
> +{
> +	int ret;
> +
> +	v4l2_subdev_init(&isc->scaler_sd, &xisc_scaler_subdev_ops);
> +
> +	isc->scaler_sd.owner = THIS_MODULE;
> +	isc->scaler_sd.dev = isc->dev;
> +	snprintf(isc->scaler_sd.name, sizeof(isc->scaler_sd.name),
> +		 "atmel_isc_scaler");
> +
> +	isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> +	isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
> +	isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> +	isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> +
> +	isc->scaler_format.height = isc->max_height;
> +	isc->scaler_format.width = isc->max_width;
> +	isc->scaler_format.code = isc->formats_list[0].mbus_code;
> +	isc->scaler_format.colorspace = V4L2_COLORSPACE_SRGB;
> +	isc->scaler_format.field = V4L2_FIELD_NONE;
> +	isc->scaler_format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> +	isc->scaler_format.quantization = V4L2_QUANTIZATION_DEFAULT;
> +	isc->scaler_format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> +
> +	ret = media_entity_pads_init(&isc->scaler_sd.entity,
> +				     ISC_SCALER_PADS_NUM,
> +				     isc->scaler_pads);
> +	if (ret < 0) {
> +		dev_err(isc->dev, "scaler sd media entity init failed\n");
> +		return ret;
> +	}
> +	ret = v4l2_device_register_subdev(&isc->v4l2_dev, &isc->scaler_sd);
> +	if (ret < 0) {
> +		dev_err(isc->dev, "scaler sd failed to register subdev\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int isc_mc_init(struct isc_device *isc, u32 ver)
> +{
> +	const struct of_device_id *match;
> +	int ret;
> +
> +	isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
> +	isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
> +	isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> +
> +	ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
> +				     isc->pads);
> +	if (ret < 0) {
> +		dev_err(isc->dev, "media entity init failed\n");
> +		return ret;
> +	}
> +
> +	isc->mdev.dev = isc->dev;
> +	isc->mdev.ops = &isc_media_ops;
> +
> +	match = of_match_node(isc->dev->driver->of_match_table,
> +			      isc->dev->of_node);
> +
> +	strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
> +		sizeof(isc->mdev.driver_name));
> +	strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
> +	snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
> +		 isc->v4l2_dev.name);
> +	isc->mdev.hw_revision = ver;
> +
> +	media_device_init(&isc->mdev);
> +
> +	isc->v4l2_dev.mdev = &isc->mdev;
> +
> +	return isc_init_own_sd(isc);
> +}
> +EXPORT_SYMBOL_GPL(isc_mc_init);
> +
> +int isc_mc_register(struct isc_device *isc)
> +{
> +	int ret;
> +
> +	ret = media_create_pad_link(&isc->current_subdev->sd->entity,
> +				    isc->remote_pad, &isc->scaler_sd.entity,
> +				    ISC_SCALER_PAD_SINK,
> +				    MEDIA_LNK_FL_ENABLED |
> +				    MEDIA_LNK_FL_IMMUTABLE);
> +
> +	if (ret < 0) {
> +		v4l2_err(&isc->v4l2_dev,
> +			 "Failed to create pad link: %s to %s\n",
> +			 isc->current_subdev->sd->entity.name,
> +			 isc->scaler_sd.entity.name);
> +		return ret;
> +	}
> +
> +	dev_dbg(isc->dev, "link with %s pad: %d\n",
> +		isc->current_subdev->sd->name, isc->remote_pad);
> +
> +	ret = media_create_pad_link(&isc->scaler_sd.entity,
> +				    ISC_SCALER_PAD_SOURCE,
> +				    &isc->video_dev.entity, ISC_PAD_SINK,
> +				    MEDIA_LNK_FL_ENABLED |
> +				    MEDIA_LNK_FL_IMMUTABLE);
> +
> +	if (ret < 0) {
> +		v4l2_err(&isc->v4l2_dev,
> +			 "Failed to create pad link: %s to %s\n",
> +			 isc->scaler_sd.entity.name,
> +			 isc->video_dev.entity.name);
> +		return ret;
> +	}
> +
> +	dev_dbg(isc->dev, "link with %s pad: %d\n", isc->scaler_sd.name,
> +		ISC_SCALER_PAD_SOURCE);
> +
> +	return media_device_register(&isc->mdev);

I feel like the isc-base driver shold instead register the
media-controller and this file shuld actually be only about
isc-scaler or something. I might be missing why it is not possible
though. It doesn't seem to me that mc support is conditional, so it
can happen in the base driver directly ?

Links creation can still happen at async_complete() (I would have
suggested _bound() time, but you have no asyn subdev for the scaler,
so I guess the only async subdev here is the sensor).

All in all: can this function be removed and:
1) Base driver registers the media controller device in probe
2) links are created at async_complete time ?

Thanks
   j


> +}
> +EXPORT_SYMBOL_GPL(isc_mc_register);
> +
> +void isc_mc_cleanup(struct isc_device *isc)
> +{
> +	media_entity_cleanup(&isc->video_dev.entity);
> +}
> +EXPORT_SYMBOL_GPL(isc_mc_cleanup);
> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> index 07fa6dbf8460..0b6370d7775f 100644
> --- a/drivers/media/platform/atmel/atmel-isc.h
> +++ b/drivers/media/platform/atmel/atmel-isc.h
> @@ -183,6 +183,17 @@ struct isc_reg_offsets {
>  	u32 his_entry;
>  };
>
> +enum isc_mc_pads {
> +	ISC_PAD_SINK	= 0,
> +	ISC_PADS_NUM	= 1,
> +};
> +
> +enum isc_scaler_pads {
> +	ISC_SCALER_PAD_SINK	= 0,
> +	ISC_SCALER_PAD_SOURCE	= 1,
> +	ISC_SCALER_PADS_NUM	= 2,
> +};
> +
>  /*
>   * struct isc_device - ISC device driver data/config struct
>   * @regmap:		Register map
> @@ -258,6 +269,12 @@ struct isc_reg_offsets {
>   *			be used as an input to the controller
>   * @controller_formats_size:	size of controller_formats array
>   * @formats_list_size:	size of formats_list array
> + * @pads:		media controller pads for isc video entity
> + * @mdev:		media device that is registered by the isc
> + * @remote_pad:		remote pad on the connected subdevice
> + * @scaler_sd:		subdevice for the scaler that isc registers
> + * @scaler_pads:	media controller pads for the scaler subdevice
> + * @scaler_format:	current format for the scaler subdevice
>   */
>  struct isc_device {
>  	struct regmap		*regmap;
> @@ -346,6 +363,19 @@ struct isc_device {
>  	struct isc_format		*formats_list;
>  	u32				controller_formats_size;
>  	u32				formats_list_size;
> +
> +	struct {
> +		struct media_pad		pads[ISC_PADS_NUM];
> +		struct media_device		mdev;
> +
> +		u32				remote_pad;
> +	};
> +
> +	struct {
> +		struct v4l2_subdev		scaler_sd;
> +		struct media_pad		scaler_pads[ISC_SCALER_PADS_NUM];
> +		struct v4l2_mbus_framefmt	scaler_format;
> +	};
>  };
>
>  extern const struct regmap_config isc_regmap_config;
> @@ -357,4 +387,10 @@ int isc_clk_init(struct isc_device *isc);
>  void isc_subdev_cleanup(struct isc_device *isc);
>  void isc_clk_cleanup(struct isc_device *isc);
>
> +int isc_mc_init(struct isc_device *isc, u32 ver);
> +int isc_mc_register(struct isc_device *isc);
> +void isc_mc_cleanup(struct isc_device *isc);
> +
> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
> +					   unsigned int code, int *index);
>  #endif
> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> index 1b2063cce0f7..a3e4c32a66c4 100644
> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> @@ -529,6 +529,12 @@ static int atmel_isc_probe(struct platform_device *pdev)
>  			break;
>  	}
>
> +	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> +
> +	ret = isc_mc_init(isc, ver);
> +	if (ret < 0)
> +		goto isc_probe_mc_init_err;
> +
>  	pm_runtime_set_active(dev);
>  	pm_runtime_enable(dev);
>  	pm_request_idle(dev);
> @@ -538,7 +544,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
>  	ret = clk_prepare_enable(isc->ispck);
>  	if (ret) {
>  		dev_err(dev, "failed to enable ispck: %d\n", ret);
> -		goto cleanup_subdev;
> +		goto isc_probe_mc_init_err;
>  	}
>
>  	/* ispck should be greater or equal to hclock */
> @@ -548,7 +554,6 @@ static int atmel_isc_probe(struct platform_device *pdev)
>  		goto unprepare_clk;
>  	}
>
> -	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>  	dev_info(dev, "Microchip ISC version %x\n", ver);
>
>  	return 0;
> @@ -556,6 +561,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
>  unprepare_clk:
>  	clk_disable_unprepare(isc->ispck);
>
> +isc_probe_mc_init_err:
> +	isc_mc_cleanup(isc);
> +
>  cleanup_subdev:
>  	isc_subdev_cleanup(isc);
>
> @@ -576,6 +584,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
>
>  	pm_runtime_disable(&pdev->dev);
>
> +	isc_mc_cleanup(isc);
> +
>  	isc_subdev_cleanup(isc);
>
>  	v4l2_device_unregister(&isc->v4l2_dev);
> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> index 2b1082295c13..d2ac80b1ccc3 100644
> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> @@ -523,15 +523,23 @@ static int microchip_xisc_probe(struct platform_device *pdev)
>  			break;
>  	}
>
> +	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> +
> +	ret = isc_mc_init(isc, ver);
> +	if (ret < 0)
> +		goto isc_probe_mc_init_err;
> +
>  	pm_runtime_set_active(dev);
>  	pm_runtime_enable(dev);
>  	pm_request_idle(dev);
>
> -	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>  	dev_info(dev, "Microchip XISC version %x\n", ver);
>
>  	return 0;
>
> +isc_probe_mc_init_err:
> +	isc_mc_cleanup(isc);
> +
>  cleanup_subdev:
>  	isc_subdev_cleanup(isc);
>
> @@ -552,6 +560,8 @@ static int microchip_xisc_remove(struct platform_device *pdev)
>
>  	pm_runtime_disable(&pdev->dev);
>
> +	isc_mc_cleanup(isc);
> +
>  	isc_subdev_cleanup(isc);
>
>  	v4l2_device_unregister(&isc->v4l2_dev);
> --
> 2.25.1
>


From szhai2 at cs.rochester.edu  Tue Jan 11 08:04:55 2022
From: szhai2 at cs.rochester.edu (Shuang Zhai)
Date: Tue, 11 Jan 2022 11:04:55 -0500
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <Yd1Css8+jsspeZHh@google.com>
Message-ID: <20220111160455.2773-1-szhai2@cs.rochester.edu>

Yu Zhao wrote:
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
>> On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
>>> TLDR
>>> ====
>>> The current page reclaim is too expensive in terms of CPU usage and it
>>> often makes poor choices about what to evict. This patchset offers an
>>> alternative solution that is performant, versatile and
>>> straightforward.
>>
>> <snipped>
>>
>>> Summery
>>> =======
>>> The facts are:
>>> 1. The independent lab results and the real-world applications
>>>     indicate substantial improvements; there are no known regressions.
>>> 2. Thrashing prevention, working set estimation and proactive reclaim
>>>     work out of the box; there are no equivalent solutions.
>>> 3. There is a lot of new code; nobody has demonstrated smaller changes
>>>     with similar effects.
>>>
>>> Our options, accordingly, are:
>>> 1. Given the amount of evidence, the reported improvements will likely
>>>     materialize for a wide range of workloads.
>>> 2. Gauging the interest from the past discussions [14][15][16], the
>>>     new features will likely be put to use for both personal computers
>>>     and data centers.
>>> 3. Based on Google's track record, the new code will likely be well
>>>     maintained in the long term. It'd be more difficult if not
>>>     impossible to achieve similar effects on top of the existing
>>>     design.
>>
>> Hi Andrew, Linus,
>>
>> Can you please take a look at this patchset and let me know if it's
>> 5.17 material?
>>
>> My goal is to get it merged asap so that users can reap the benefits
>> and I can push the sequels. Please examine the data provided -- I
>> think the unprecedented coverage and the magnitude of the improvements
>> warrant a green light.
> 
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
> 
> Having this patchset in the mainline will make your job easier :)
> 
>     Alexandre - the XanMod Kernel maintainer
>                 https://xanmod.org
>     
>     Brian     - the Chrome OS kernel memory maintainer
>                 https://www.chromium.org
>     
>     Jan       - the Arch Linux Zen kernel maintainer
>                 https://archlinux.org
>     
>     Steven    - the Liquorix kernel maintainer
>                 https://liquorix.net
>     
>     Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                 https://chromium.googlesource.com/chromiumos/third_party/kernel
> 
> Also my gratitude to those who have helped test MGLRU:
> 
>     Daniel - researcher at Michigan Tech
>              benchmarked memcached
>     
>     Holger - who has been testing/patching/contributing to various
>              subsystems since ~2008
>     
>     Shuang - researcher at University of Rochester
>              benchmarked fio and provided a report
>     
>     Sofia  - EDI https://www.edi.works
>              benchmarked the top eight memory hogs and provided reports
> 
> Can you please provide your Tested-by tags? This will ensure the credit
> for your contributions.
> 
> Thanks!

I have tested MGLRU using fio [1]. The performance improvement is fabulous.
I hope this patchset could eventually get merged to enable large scale test
and let more users talk about their experience.

Tested-by: Shuang Zhai <szhai2 at cs.rochester.edu>

[1] https://lore.kernel.org/lkml/20220105024423.26409-1-szhai2 at cs.rochester.edu/


From boger at wirenboard.com  Tue Jan 11 08:05:57 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:05:57 +0300
Subject: [PATCH v4 0/3] sun8i: r40: second ethernet support
Message-ID: <20220111160600.58384-1-boger@wirenboard.com>

This patch series adds support for two Ethernet ports on Allwinner R40.

R40 (aka V40,A40i,T3) has two different Ethernet IPs called EMAC and GMAC.
EMAC only support 10/100 Mbit in MII mode, while GMAC support both 10/100
(MII) and 10/100/1000 (RGMII).

In contrast to A10/A20 where GMAC and EMAC share the same pins making EMAC
somewhat pointless, on R40 EMAC can be routed to port H.
Both EMAC (on port H) and GMAC (on port A) can be then enabled at the same 
time, allowing for two ethernet ports.

Tested on custom A40i board with two IP101GRI PHYs in MII mode.

Changes in v4:
 - Rename sun4i-r40-emac to sun8i-r40-emac to match R40 family.
 - remove redundant status = "okay" in dts
 - less obscure commit messages

Changes in v3:
Minor fixes in bindings. Rebased on top of linux-next/master.
dt_bindings_check and dtbs_check passed.

 - bindings: separate commit for DT bindings
 - bindings: simplify handling of compatible strings
 - bindings: make resets property required on R40
 - dts: get rid of duplicate node

Changes in v2:
 - EMAC reset is no longer optional on R40
 - Add a new DT compatible string for R40 EMAC
 - Deassert reset line before enabling the clock
 - minor fixes: formatting, DT node order, leftover pinctrl props

Evgeny Boger (3):
  net: allwinner: reset control support
  dt-bindings: net: support for Allwinner R40 EMAC controller
  ARM: dts: sun8i: r40: add second ethernet support

 .../net/allwinner,sun4i-a10-emac.yaml         | 20 +++++-
 arch/arm/boot/dts/sun8i-r40.dtsi              | 49 ++++++++++++++
 drivers/net/ethernet/allwinner/sun4i-emac.c   | 64 +++++++++++++++++--
 3 files changed, 127 insertions(+), 6 deletions(-)

-- 
2.25.1


From boger at wirenboard.com  Tue Jan 11 08:05:58 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:05:58 +0300
Subject: [PATCH v4 1/3] net: allwinner: reset control support
In-Reply-To: <20220111160600.58384-1-boger@wirenboard.com>
References: <20220111160600.58384-1-boger@wirenboard.com>
Message-ID: <20220111160600.58384-2-boger@wirenboard.com>

R40 (aka V40/A40i/T3) and A10/A20 share the same EMAC IP.
However, on R40 the EMAC reset needs to be deasserted.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 64 +++++++++++++++++++--
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 800ee022388f..368597f0ff76 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -28,6 +28,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/reset.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
 
 #include "sun4i-emac.h"
@@ -68,6 +69,15 @@ MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
  * devices, EMACA and EMACB.
  */
 
+/**
+ * struct emac_quirks - Differences between SoC variants.
+ *
+ * @has_reset: SoC needs reset deasserted.
+ */
+struct emac_quirks {
+	bool		has_reset;
+};
+
 struct emac_board_info {
 	struct clk		*clk;
 	struct device		*dev;
@@ -85,6 +95,7 @@ struct emac_board_info {
 	unsigned int		link;
 	unsigned int		speed;
 	unsigned int		duplex;
+	struct reset_control	*reset;
 
 	phy_interface_t		phy_interface;
 };
@@ -790,6 +801,7 @@ static int emac_probe(struct platform_device *pdev)
 	struct emac_board_info *db;
 	struct net_device *ndev;
 	int ret = 0;
+	const struct emac_quirks *quirks;
 
 	ndev = alloc_etherdev(sizeof(struct emac_board_info));
 	if (!ndev) {
@@ -808,6 +820,13 @@ static int emac_probe(struct platform_device *pdev)
 
 	spin_lock_init(&db->lock);
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (!quirks) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
 	db->membase = of_iomap(np, 0);
 	if (!db->membase) {
 		dev_err(&pdev->dev, "failed to remap registers\n");
@@ -824,16 +843,31 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (quirks->has_reset) {
+		db->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+		if (IS_ERR(db->reset)) {
+			dev_err(&pdev->dev, "unable to request reset\n");
+			ret = PTR_ERR(db->reset);
+			goto out_dispose_mapping;
+		}
+
+		ret = reset_control_deassert(db->reset);
+		if (ret) {
+			dev_err(&pdev->dev, "could not deassert EMAC reset\n");
+			goto out_dispose_mapping;
+		}
+	}
+
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
-		goto out_dispose_mapping;
+		goto out_assert_reset;
 	}
 
 	ret = clk_prepare_enable(db->clk);
 	if (ret) {
 		dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
-		goto out_dispose_mapping;
+		goto out_assert_reset;
 	}
 
 	ret = sunxi_sram_claim(&pdev->dev);
@@ -889,6 +923,8 @@ static int emac_probe(struct platform_device *pdev)
 	sunxi_sram_release(&pdev->dev);
 out_clk_disable_unprepare:
 	clk_disable_unprepare(db->clk);
+out_assert_reset:
+	reset_control_assert(db->reset);
 out_dispose_mapping:
 	irq_dispose_mapping(ndev->irq);
 out_iounmap:
@@ -909,6 +945,7 @@ static int emac_remove(struct platform_device *pdev)
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
+	reset_control_assert(db->reset);
 	irq_dispose_mapping(ndev->irq);
 	iounmap(db->membase);
 	free_netdev(ndev);
@@ -940,11 +977,28 @@ static int emac_resume(struct platform_device *dev)
 	return 0;
 }
 
-static const struct of_device_id emac_of_match[] = {
-	{.compatible = "allwinner,sun4i-a10-emac",},
+static const struct emac_quirks sun4i_a10_emac_quirks = {
+	.has_reset = false,
+};
+
+static const struct emac_quirks sun8i_r40_emac_quirks = {
+	.has_reset = true,
+};
 
+static const struct of_device_id emac_of_match[] = {
+	{
+		.compatible = "allwinner,sun4i-a10-emac",
+		.data = &sun4i_a10_emac_quirks
+	},
+	{
+		.compatible = "allwinner,sun8i-r40-emac",
+		.data = &sun8i_r40_emac_quirks
+	},
 	/* Deprecated */
-	{.compatible = "allwinner,sun4i-emac",},
+	{
+		.compatible = "allwinner,sun4i-emac",
+		.data = &sun4i_a10_emac_quirks
+	},
 	{},
 };
 
-- 
2.25.1



From boger at wirenboard.com  Tue Jan 11 08:05:59 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:05:59 +0300
Subject: [PATCH v4 2/3] dt-bindings: net: support for Allwinner R40 EMAC
 controller
In-Reply-To: <20220111160600.58384-1-boger@wirenboard.com>
References: <20220111160600.58384-1-boger@wirenboard.com>
Message-ID: <20220111160600.58384-3-boger@wirenboard.com>

R40 and A10/A20 share the same EMAC IP.
However, on R40 the EMAC reset needs to be deasserted first,
so resets property is required.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 .../net/allwinner,sun4i-a10-emac.yaml         | 20 ++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
index 8d8560a67abf..8b38b4e981fe 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
@@ -15,7 +15,9 @@ maintainers:
 
 properties:
   compatible:
-    const: allwinner,sun4i-a10-emac
+    enum:
+      - allwinner,sun4i-a10-emac
+      - allwinner,sun8i-r40-emac
 
   reg:
     maxItems: 1
@@ -30,6 +32,19 @@ properties:
     description: Phandle to the device SRAM
     $ref: /schemas/types.yaml#/definitions/phandle-array
 
+  resets:
+    maxItems: 1
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: allwinner,sun8i-r40-emac
+
+then:
+  required:
+    - resets
+
 required:
   - compatible
   - reg
@@ -42,11 +57,14 @@ unevaluatedProperties: false
 
 examples:
   - |
+    #define RST_BUS_EMAC		14
+
     emac: ethernet at 1c0b000 {
         compatible = "allwinner,sun4i-a10-emac";
         reg = <0x01c0b000 0x1000>;
         interrupts = <55>;
         clocks = <&ahb_gates 17>;
+        resets = <&ccu RST_BUS_EMAC>;
         phy-handle = <&phy0>;
         allwinner,sram = <&emac_sram 1>;
     };
-- 
2.25.1



From boger at wirenboard.com  Tue Jan 11 08:06:00 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:06:00 +0300
Subject: [PATCH v4 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <20220111160600.58384-1-boger@wirenboard.com>
References: <20220111160600.58384-1-boger@wirenboard.com>
Message-ID: <20220111160600.58384-4-boger@wirenboard.com>

R40 (aka V40, A40i, T3) has two different Ethernet IPs
called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).

In contrast to A10/A20 where GMAC and EMAC share the same pins
making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
Both EMAC (on port H) and GMAC (on port A) can be then enabled at
the same time, allowing for two ethernet ports.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
index 1d87fc0c24ee..870d63fae1fc 100644
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
@@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
 			#size-cells = <1>;
 			ranges;
 
+			sram_a: sram at 0 {
+				compatible = "mmio-sram";
+				reg = <0x00000000 0xc000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00000000 0xc000>;
+
+				emac_sram: sram-section at 8000 {
+					compatible = "allwinner,sun4i-a10-sram-a3-a4";
+					reg = <0x8000 0x4000>;
+				};
+			};
+
 			sram_c: sram at 1d00000 {
 				compatible = "mmio-sram";
 				reg = <0x01d00000 0xd0000>;
@@ -543,6 +556,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
 				drive-strength = <40>;
 			};
 
+			emac_pa_pins: emac-pa-pins {
+				pins = "PA0", "PA1", "PA2",
+				       "PA3", "PA4", "PA5", "PA6",
+				       "PA7", "PA8", "PA9", "PA10",
+				       "PA11", "PA12", "PA13", "PA14",
+				       "PA15", "PA16";
+				function = "emac";
+			};
+
+			emac_ph_pins: emac-ph-pins {
+				pins = "PH8", "PH9", "PH10", "PH11",
+				       "PH14", "PH15", "PH16", "PH17",
+				       "PH18","PH19", "PH20", "PH21",
+				       "PH22", "PH23", "PH24", "PH25",
+				       "PH26", "PH27";
+				function = "emac";
+			};
+
 			i2c0_pins: i2c0-pins {
 				pins = "PB0", "PB1";
 				function = "i2c0";
@@ -980,6 +1011,24 @@ gmac_mdio: mdio {
 			};
 		};
 
+		emac: ethernet at 1c0b000 {
+			compatible = "allwinner,sun8i-r40-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_EMAC>;
+			resets = <&ccu RST_BUS_EMAC>;
+			allwinner,sram = <&emac_sram 1>;
+			status = "disabled";
+		};
+
+		emac_mdio: mdio at 1c0b080 {
+			compatible = "allwinner,sun4i-a10-mdio";
+			reg = <0x01c0b080 0x14>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		mbus: dram-controller at 1c62000 {
 			compatible = "allwinner,sun8i-r40-mbus";
 			reg = <0x01c62000 0x1000>;
-- 
2.25.1



From alexandru.elisei at arm.com  Tue Jan 11 08:11:25 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 11 Jan 2022 16:11:25 +0000
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
In-Reply-To: <875yqqtn5q.wl-maz@kernel.org>
References: <20220110054042.1079932-1-reijiw@google.com>
 <YdwPCcZWD8Uc1eej@monolith.localdoman>
 <CAAeT=Fz1KPbpmcSbukBuGWMJH=V_oXAJoaDHAen_Gy9Qswo_1Q@mail.gmail.com>
 <875yqqtn5q.wl-maz@kernel.org>
Message-ID: <Yd2sLbiw/XPCZe7q@monolith.localdoman>

Hi Marc,

On Tue, Jan 11, 2022 at 01:30:41PM +0000, Marc Zyngier wrote:
> On Tue, 11 Jan 2022 07:37:57 +0000,
> Reiji Watanabe <reijiw at google.com> wrote:
> > 
> > Hi Alex,
> > 
> > On Mon, Jan 10, 2022 at 2:48 AM Alexandru Elisei
> > <alexandru.elisei at arm.com> wrote:
> > >
> > > Hi Reiji,
> > >
> > > On Sun, Jan 09, 2022 at 09:40:41PM -0800, Reiji Watanabe wrote:
> > > > vcpu_allowed_register_width() checks if all the VCPUs are either
> > > > all 32bit or all 64bit.  Since the checking is done even for vCPUs
> > > > that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
> > > > the non-initialized vCPUs are erroneously treated as 64bit vCPU,
> > > > which causes the function to incorrectly detect a mixed-width VM.
> > > >
> > > > Fix vcpu_allowed_register_width() to skip the check for vCPUs that
> > > > are not initialized yet.
> > > >
> > > > Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
> > > > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > > > ---
> > > >  arch/arm64/kvm/reset.c | 11 +++++++++++
> > > >  1 file changed, 11 insertions(+)
> > > >
> > > > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > > > index 426bd7fbc3fd..ef78bbc7566a 100644
> > > > --- a/arch/arm64/kvm/reset.c
> > > > +++ b/arch/arm64/kvm/reset.c
> > > > @@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> > > >       if (kvm_has_mte(vcpu->kvm) && is32bit)
> > > >               return false;
> > > >
> > > > +     /*
> > > > +      * Make sure vcpu->arch.target setting is visible from others so
> > > > +      * that the width consistency checking between two vCPUs is done
> > > > +      * by at least one of them at KVM_ARM_VCPU_INIT.
> > > > +      */
> > > > +     smp_mb();
> > >
> > > From ARM DDI 0487G.a, page B2-146 ("Data Memory Barrier (DMB)"):
> > >
> > > "The DMB instruction is a memory barrier instruction that ensures the relative
> > > order of memory accesses before the barrier with memory accesses after the
> > > barrier."
> > >
> > > I'm going to assume from the comment that you are referring to completion of
> > > memory accesses ("Make sure [..] is visible from others"). Please correct me if
> > > I am wrong. In this case, DMB ensures ordering of memory accesses with regards
> > > to writes and reads, not *completion*.  Have a look at
> > > tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus for
> > > the classic message passing example as an example of memory ordering.
> > > Message passing and other patterns are also explained in ARM DDI 0487G.a, page
> > > K11-8363.
> > >
> > > I'm not saying that your approach is incorrect, but the commit message should
> > > explain what memory accesses are being ordered relative to each other and why.
> > 
> > Thank you so much for the review.
> > What I meant with the comment was:
> > ---
> >   DMB is used to make sure that writing @vcpu->arch.target, which is done
> >   by kvm_vcpu_set_target() before getting here, is visible to other PEs
> >   before the following kvm_for_each_vcpu iteration reads the other vCPUs'
> >   target field.
> > ---
> > Did the comment become more clear ?? (Or do I use DMB incorrectly ?)
> > 
> > > > +
> > > >       /* Check that the vcpus are either all 32bit or all 64bit */
> > > >       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> > > > +             /* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> > > > +             if (tmp->arch.target == -1)
> > > > +                     continue;
> > 
> > I just noticed DMB(ishld) is needed here to assure ordering between
> > reading tmp->arch.target and reading vcpu->arch.features for this fix.
> > Similarly, kvm_vcpu_set_target() needs DMB(ishst) to assure ordering
> > between writing vcpu->arch.features and writing vcpu->arch.target...
> > I am going to fix them in the v2 series.
> 
> Yes, you'd need at least this, and preferably in their smp_rmb/wmb
> variants.
> 
> However, this looks like a pretty fragile construct, as there are
> multiple paths where we can change target (including some error
> paths from the run loop).
> 
> I'd rather all changes to target and the feature bits happen under the
> kvm->lock, and take that lock when checking for consistency in
> vcpu_allowed_register_width(), as this isn't a fast path. I wrote the
> following, which is obviously incomplete and as usual untested.

I think this is the better approach, because we also want to make sure that
a PE observes changes to target and features as soon as they have been
made, to avoid situations where one PE sets the target and the 32bit
feature, and another PE reads the old values and skips the check, in which
case memory ordering is not enough.

Thanks,
Alex

> 
> Thanks,
> 
> 	M.
> 
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e4727dc771bf..42f2ab80646c 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -1061,7 +1061,8 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
>  static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>  			       const struct kvm_vcpu_init *init)
>  {
> -	unsigned int i, ret;
> +	unsigned int i;
> +	int ret = 0;
>  	u32 phys_target = kvm_target_cpu();
>  
>  	if (init->target != phys_target)
> @@ -1074,32 +1075,46 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>  	if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
>  		return -EINVAL;
>  
> +	/* Hazard against a concurent check of the target in kvm_reset_vcpu() */
> +	mutex_lock(&vcpu->kvm->lock);
> +
>  	/* -ENOENT for unknown features, -EINVAL for invalid combinations. */
>  	for (i = 0; i < sizeof(init->features) * 8; i++) {
>  		bool set = (init->features[i / 32] & (1 << (i % 32)));
>  
> -		if (set && i >= KVM_VCPU_MAX_FEATURES)
> -			return -ENOENT;
> +		if (set && i >= KVM_VCPU_MAX_FEATURES) {
> +			ret = -ENOENT;
> +			break;
> +		}
>  
>  		/*
>  		 * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
>  		 * use the same feature set.
>  		 */
>  		if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES &&
> -		    test_bit(i, vcpu->arch.features) != set)
> -			return -EINVAL;
> +		    test_bit(i, vcpu->arch.features) != set) {
> +			ret = -EINVAL;
> +			break;
> +		}
>  
>  		if (set)
>  			set_bit(i, vcpu->arch.features);
>  	}
>  
> -	vcpu->arch.target = phys_target;
> +	if (!ret)
> +		vcpu->arch.target = phys_target;
> +
> +	mutex_unlock(&vcpu->kvm->lock);
> +	if (ret)
> +		return ret;
>  
>  	/* Now we know what it is, we can reset it. */
>  	ret = kvm_reset_vcpu(vcpu);
>  	if (ret) {
> +		mutex_lock(&vcpu->kvm->lock);
>  		vcpu->arch.target = -1;
>  		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
> +		mutex_unlock(&vcpu->kvm->lock);
>  	}
>  
>  	return ret;
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index ef78bbc7566a..fae88a703140 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -180,13 +180,6 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
>  	if (kvm_has_mte(vcpu->kvm) && is32bit)
>  		return false;
>  
> -	/*
> -	 * Make sure vcpu->arch.target setting is visible from others so
> -	 * that the width consistency checking between two vCPUs is done
> -	 * by at least one of them at KVM_ARM_VCPU_INIT.
> -	 */
> -	smp_mb();
> -
>  	/* Check that the vcpus are either all 32bit or all 64bit */
>  	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
>  		/* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> @@ -222,14 +215,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
>  int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  {
>  	struct vcpu_reset_state reset_state;
> -	int ret;
> +	int ret = -EINVAL;
>  	bool loaded;
>  	u32 pstate;
>  
>  	mutex_lock(&vcpu->kvm->lock);
> -	reset_state = vcpu->arch.reset_state;
> -	WRITE_ONCE(vcpu->arch.reset_state.reset, false);
> +	if (vcpu_allowed_register_width(vcpu)) {
> +		reset_state = vcpu->arch.reset_state;
> +		WRITE_ONCE(vcpu->arch.reset_state.reset, false);
> +		ret = 0;
> +	}
>  	mutex_unlock(&vcpu->kvm->lock);
> +	if (ret)
> +		goto out;
>  
>  	/* Reset PMU outside of the non-preemptible section */
>  	kvm_pmu_vcpu_reset(vcpu);
> @@ -257,11 +255,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  		}
>  	}
>  
> -	if (!vcpu_allowed_register_width(vcpu)) {
> -		ret = -EINVAL;
> -		goto out;
> -	}
> -
>  	switch (vcpu->arch.target) {
>  	default:
>  		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
> 
> -- 
> Without deviation from the norm, progress is not possible.


From andre.przywara at arm.com  Tue Jan 11 08:24:22 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 11 Jan 2022 16:24:22 +0000
Subject: [PATCH v2 2/3] can: sun4i_can: add support for R40 CAN controller
In-Reply-To: <20220111155709.56501-3-boger@wirenboard.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
 <20220111155709.56501-3-boger@wirenboard.com>
Message-ID: <20220111162422.62d0ceb0@donnerap.cambridge.arm.com>

On Tue, 11 Jan 2022 18:57:08 +0300
Evgeny Boger <boger at wirenboard.com> wrote:

Hi,

> Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
> controller is the same as in earlier A10 and A20 SoCs, but needs reset
> line to be deasserted before use.
> 
> This patch adds a new compatible for R40 CAN controller. Depending
> on the compatible, reset line can be requested from DT.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> ---
>  drivers/net/can/sun4i_can.c | 61 ++++++++++++++++++++++++++++++++++++-
>  1 file changed, 60 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
> index 54aa7c25c4de..24a61326915e 100644
> --- a/drivers/net/can/sun4i_can.c
> +++ b/drivers/net/can/sun4i_can.c
> @@ -61,6 +61,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/reset.h>
>  
>  #define DRV_NAME "sun4i_can"
>  
> @@ -200,10 +201,20 @@
>  #define SUN4I_CAN_MAX_IRQ	20
>  #define SUN4I_MODE_MAX_RETRIES	100
>  
> +/**
> + * struct sun4ican_quirks - Differences between SoC variants.
> + *
> + * @has_reset: SoC needs reset deasserted.
> + */
> +struct sun4ican_quirks {
> +	bool		has_reset;
> +};
> +
>  struct sun4ican_priv {
>  	struct can_priv can;
>  	void __iomem *base;
>  	struct clk *clk;
> +	struct reset_control *reset;
>  	spinlock_t cmdreg_lock;	/* lock for concurrent cmd register writes */
>  };
>  
> @@ -702,6 +713,13 @@ static int sun4ican_open(struct net_device *dev)
>  		goto exit_irq;
>  	}
>  
> +	/* software reset deassert */
> +	err = reset_control_deassert(priv->reset);
> +	if (err) {
> +		netdev_err(dev, "could not deassert CAN reset\n");
> +		goto exit_soft_reset;
> +	}
> +
>  	/* turn on clocking for CAN peripheral block */
>  	err = clk_prepare_enable(priv->clk);
>  	if (err) {
> @@ -723,6 +741,8 @@ static int sun4ican_open(struct net_device *dev)
>  exit_can_start:
>  	clk_disable_unprepare(priv->clk);
>  exit_clock:
> +	reset_control_assert(priv->reset);
> +exit_soft_reset:
>  	free_irq(dev->irq, dev);
>  exit_irq:
>  	close_candev(dev);
> @@ -736,6 +756,7 @@ static int sun4ican_close(struct net_device *dev)
>  	netif_stop_queue(dev);
>  	sun4i_can_stop(dev);
>  	clk_disable_unprepare(priv->clk);
> +	reset_control_assert(priv->reset);
>  
>  	free_irq(dev->irq, dev);
>  	close_candev(dev);
> @@ -750,8 +771,27 @@ static const struct net_device_ops sun4ican_netdev_ops = {
>  	.ndo_start_xmit = sun4ican_start_xmit,
>  };
>  
> +static const struct sun4ican_quirks sun4ican_quirks_a10 = {
> +	.has_reset = false,
> +};
> +
> +static const struct sun4ican_quirks sun4ican_quirks_r40 = {
> +	.has_reset = true,
> +};
> +
>  static const struct of_device_id sun4ican_of_match[] = {
> -	{.compatible = "allwinner,sun4i-a10-can"},
> +	{
> +		.compatible = "allwinner,sun4i-a10-can",
> +		.data = &sun4ican_quirks_a10
> +	},
> +	{
> +		.compatible = "allwinner,sun7i-a20-can",
> +		.data = &sun4ican_quirks_a10
> +	},

This one looks unnecessary, the binding says that it must be paired with
the A10 fallback.
We should only add an A20 compatible match if there is really a reason,
otherwise it encourages people to produce DTs with *only* the A20
compatible (violating the binding).

Cheers,
Andre

> +	{
> +		.compatible = "allwinner,sun8i-r40-can",
> +		.data = &sun4ican_quirks_r40
> +	},
>  	{},
>  };
>  
> @@ -771,10 +811,28 @@ static int sun4ican_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np = pdev->dev.of_node;
>  	struct clk *clk;
> +	struct reset_control *reset = NULL;
>  	void __iomem *addr;
>  	int err, irq;
>  	struct net_device *dev;
>  	struct sun4ican_priv *priv;
> +	const struct sun4ican_quirks *quirks;
> +
> +	quirks = of_device_get_match_data(&pdev->dev);
> +	if (!quirks) {
> +		dev_err(&pdev->dev, "failed to determine the quirks to use\n");
> +		err = -ENODEV;
> +		goto exit;
> +	}
> +
> +	if (quirks->has_reset) {
> +		reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +		if (IS_ERR(reset)) {
> +			dev_err(&pdev->dev, "unable to request reset\n");
> +			err = PTR_ERR(reset);
> +			goto exit;
> +		}
> +	}
>  
>  	clk = of_clk_get(np, 0);
>  	if (IS_ERR(clk)) {
> @@ -818,6 +876,7 @@ static int sun4ican_probe(struct platform_device *pdev)
>  				       CAN_CTRLMODE_3_SAMPLES;
>  	priv->base = addr;
>  	priv->clk = clk;
> +	priv->reset = reset;
>  	spin_lock_init(&priv->cmdreg_lock);
>  
>  	platform_set_drvdata(pdev, dev);



From Eugen.Hristev at microchip.com  Tue Jan 11 08:30:15 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Tue, 11 Jan 2022 16:30:15 +0000
Subject: [PATCH v3 12/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <20220111160603.qi4kbp6rn45hp7po@uno.localdomain>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-13-eugen.hristev@microchip.com>
 <20220111160603.qi4kbp6rn45hp7po@uno.localdomain>
Message-ID: <e089d9f3-d07b-1e61-f59b-a695912b6558@microchip.com>

On 1/11/22 6:06 PM, Jacopo Mondi wrote:
> Hi Eugen,
> 
> On Mon, Dec 13, 2021 at 03:49:29PM +0200, Eugen Hristev wrote:
>> Implement the support for media-controller.
>> This means that the capabilities of the driver have changed and now
>> it also advertises the IO_MC .
>> The driver will register it's media device, and add the video entity to this
>> media device. The subdevices are registered to the same media device.
>> The ISC will have a base entity which is auto-detected as atmel_isc_base.
>> It will also register a subdevice that allows cropping of the incoming frame
>> to the maximum frame size supported by the ISC.
>> The ISC will create a link between the subdevice that is asynchronously
>> registered and the atmel_isc_scaler entity.
>> Then, the atmel_isc_scaler and atmel_isc_base are connected through another
>> link.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> ---
>> Changes in v2:
>> - implement try formats
>>
>>   drivers/media/platform/atmel/Makefile         |   2 +-
>>   drivers/media/platform/atmel/atmel-isc-base.c |  27 +-
>>   drivers/media/platform/atmel/atmel-isc-mc.c   | 287 ++++++++++++++++++
>>   drivers/media/platform/atmel/atmel-isc.h      |  36 +++
>>   .../media/platform/atmel/atmel-sama5d2-isc.c  |  14 +-
>>   .../media/platform/atmel/atmel-sama7g5-isc.c  |  12 +-
>>   6 files changed, 370 insertions(+), 8 deletions(-)
>>   create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
>>
>> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
>> index 794e8f739287..aa7a18b428f6 100644
>> --- a/drivers/media/platform/atmel/Makefile
>> +++ b/drivers/media/platform/atmel/Makefile
>> @@ -1,7 +1,7 @@
>>   # SPDX-License-Identifier: GPL-2.0-only
>>   atmel-isc-objs = atmel-sama5d2-isc.o
>>   atmel-xisc-objs = atmel-sama7g5-isc.o
>> -atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
>> +atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o atmel-isc-mc.o
>>
>>   obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
>>   obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>> index d0542b97a391..b0c3ed21f372 100644
>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>> @@ -1726,6 +1726,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>>                                              struct isc_device, v4l2_dev);
>>        struct isc_subdev_entity *subdev_entity =
>>                container_of(notifier, struct isc_subdev_entity, notifier);
>> +     int pad;
>>
>>        if (video_is_registered(&isc->video_dev)) {
>>                v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
>> @@ -1734,6 +1735,16 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>>
>>        subdev_entity->sd = subdev;
>>
>> +     pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
>> +                                       MEDIA_PAD_FL_SOURCE);
>> +     if (pad < 0) {
>> +             v4l2_err(&isc->v4l2_dev, "failed to find pad for %s\n",
>> +                      subdev->name);
>> +             return pad;
>> +     }
>> +
>> +     isc->remote_pad = pad;
>> +
>>        return 0;
>>   }
>>
>> @@ -1748,8 +1759,8 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
>>        v4l2_ctrl_handler_free(&isc->ctrls.handler);
>>   }
>>
>> -static struct isc_format *find_format_by_code(struct isc_device *isc,
>> -                                           unsigned int code, int *index)
>> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
>> +                                        unsigned int code, int *index)
>>   {
>>        struct isc_format *fmt = &isc->formats_list[0];
>>        unsigned int i;
>> @@ -1765,6 +1776,7 @@ static struct isc_format *find_format_by_code(struct isc_device *isc,
>>
>>        return NULL;
>>   }
>> +EXPORT_SYMBOL_GPL(isc_find_format_by_code);
>>
>>   static int isc_formats_init(struct isc_device *isc)
>>   {
>> @@ -1781,7 +1793,7 @@ static int isc_formats_init(struct isc_device *isc)
>>               NULL, &mbus_code)) {
>>                mbus_code.index++;
>>
>> -             fmt = find_format_by_code(isc, mbus_code.code, &i);
>> +             fmt = isc_find_format_by_code(isc, mbus_code.code, &i);
>>                if (!fmt) {
>>                        v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
>>                                  mbus_code.code);
>> @@ -1909,7 +1921,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>        vdev->queue             = q;
>>        vdev->lock              = &isc->lock;
>>        vdev->ctrl_handler      = &isc->ctrls.handler;
>> -     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
>> +     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
>> +                               V4L2_CAP_IO_MC;
>>        video_set_drvdata(vdev, isc);
>>
>>        ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
>> @@ -1919,8 +1932,14 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>                goto isc_async_complete_err;
>>        }
>>
>> +     ret = isc_mc_register(isc);
>> +     if (ret < 0)
>> +             goto isc_async_complete_unregister_device;
>>        return 0;
>>
>> +isc_async_complete_unregister_device:
>> +     video_unregister_device(vdev);
>> +
>>   isc_async_complete_err:
>>        mutex_destroy(&isc->lock);
>>        return ret;
>> diff --git a/drivers/media/platform/atmel/atmel-isc-mc.c b/drivers/media/platform/atmel/atmel-isc-mc.c
>> new file mode 100644
>> index 000000000000..2aea81d77b2f
>> --- /dev/null
>> +++ b/drivers/media/platform/atmel/atmel-isc-mc.c
>> @@ -0,0 +1,287 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Microchip Image Sensor Controller (ISC) Media Controller support
>> + *
>> + * Copyright (C) 2021 Microchip Technology, Inc.
>> + *
>> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
>> + *
>> + */
>> +
>> +#include <media/v4l2-device.h>
>> +#include <media/v4l2-subdev.h>
> 
> Should you include <media/media-entity.h> and <media/media-device.h> ?

Hi Jacopo,

They are probably being included from another header. I will add them.

> 
> Also, should you select MEDIA_CONTROLLER and V4L2_SUBDEV_API for all
> the Kconfig symbols ?


VIDEO_ATMEL_ISC directly selects:
select MEDIA_CONTROLLER
select VIDEO_V4L2_SUBDEV_API

and VIDEO_ATMEL_XISC
depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API

and VIDEO_V4L2_SUBDEV_API depends on MEDIA_CONTROLLER

> 
>> +
>> +#include "atmel-isc-regs.h"
>> +#include "atmel-isc.h"
>> +
>> +static const struct media_device_ops isc_media_ops = {
>> +};
> 
> Do you need this even if it's empty ?
> 

Not sure. I can remove it and pass NULL, but I haven't checked what the 
subsystem is doing if there is no ops. I will try.

>> +
>> +static int isc_scaler_get_fmt(struct v4l2_subdev *sd,
>> +                           struct v4l2_subdev_state *sd_state,
>> +                           struct v4l2_subdev_format *format)
>> +{
>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
>> +
>> +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
>> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
>> +                                                       format->pad);
>> +             format->format = *v4l2_try_fmt;
>> +
>> +             return 0;
>> +     }
>> +
>> +     format->format = isc->scaler_format;
>> +
>> +     return 0;
>> +}
>> +
>> +static int isc_scaler_set_fmt(struct v4l2_subdev *sd,
>> +                           struct v4l2_subdev_state *sd_state,
>> +                           struct v4l2_subdev_format *req_fmt)
>> +{
>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
>> +     struct isc_format *fmt;
>> +     unsigned int i;
>> +
>> +     if (req_fmt->pad == ISC_SCALER_PAD_SOURCE)
>> +             v4l_bound_align_image
>> +                     (&req_fmt->format.width, 16, isc->max_width, 0,
>> +                      &req_fmt->format.height, 16, isc->max_height, 0, 0);
>> +     else
>> +             v4l_bound_align_image
>> +                     (&req_fmt->format.width, 16, 10000, 0,
>> +                      &req_fmt->format.height, 16, 10000, 0, 0);
>> +
>> +     req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
>> +     req_fmt->format.field = V4L2_FIELD_NONE;
>> +     req_fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
>> +     req_fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
>> +     req_fmt->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
>> +
>> +     fmt = isc_find_format_by_code(isc, req_fmt->format.code, &i);
>> +
>> +     if (!fmt)
>> +             fmt = &isc->formats_list[0];
>> +
>> +     req_fmt->format.code = fmt->mbus_code;
>> +
>> +     if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
>> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
>> +                                                       req_fmt->pad);
>> +             *v4l2_try_fmt = req_fmt->format;
>> +             /* Trying on the pad sink makes the source sink change too */
>> +             if (req_fmt->pad == ISC_SCALER_PAD_SINK) {
>> +                     v4l2_try_fmt =
>> +                             v4l2_subdev_get_try_format(sd, sd_state,
>> +                                                        ISC_SCALER_PAD_SOURCE);
>> +                     *v4l2_try_fmt = req_fmt->format;
>> +
>> +                     v4l_bound_align_image(&v4l2_try_fmt->width,
>> +                                           16, isc->max_width, 0,
>> +                                           &v4l2_try_fmt->height,
>> +                                           16, isc->max_height, 0, 0);
>> +             }
>> +             /* if we are just trying, we are done */
>> +             return 0;
>> +     }
>> +
>> +     isc->scaler_format = req_fmt->format;
>> +
>> +     return 0;
>> +}
>> +
>> +static int isc_scaler_enum_mbus_code(struct v4l2_subdev *sd,
>> +                                  struct v4l2_subdev_state *sd_state,
>> +                                  struct v4l2_subdev_mbus_code_enum *code)
>> +{
>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>> +     int supported_index = 0;
>> +     int i;
>> +
>> +     for (i = 0; i < isc->formats_list_size; i++) {
>> +             if (!isc->formats_list[i].sd_support)
>> +                     continue;
>> +             if (supported_index == code->index) {
>> +                     code->code = isc->formats_list[i].mbus_code;
>> +                     return 0;
>> +             }
>> +             supported_index++;
>> +     }
>> +
>> +     return -EINVAL;
>> +}
>> +
>> +static int isc_scaler_g_sel(struct v4l2_subdev *sd,
>> +                         struct v4l2_subdev_state *sd_state,
>> +                         struct v4l2_subdev_selection *sel)
>> +{
>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>> +
>> +     if (sel->pad == ISC_SCALER_PAD_SOURCE)
>> +             return -EINVAL;
>> +
>> +     if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS &&
>> +         sel->target != V4L2_SEL_TGT_CROP)
>> +             return -EINVAL;
>> +
>> +     sel->r.height = isc->max_height;
>> +     sel->r.width = isc->max_width;
>> +
>> +     sel->r.left = 0;
>> +     sel->r.top = 0;
>> +
>> +     return 0;
>> +}
>> +
>> +static int isc_scaler_init_cfg(struct v4l2_subdev *sd,
>> +                            struct v4l2_subdev_state *sd_state)
>> +{
>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt =
>> +             v4l2_subdev_get_try_format(sd, sd_state, 0);
>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>> +
>> +     *v4l2_try_fmt = isc->scaler_format;
>> +
>> +     return 0;
>> +}
>> +
>> +static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
>> +     .enum_mbus_code = isc_scaler_enum_mbus_code,
>> +     .set_fmt = isc_scaler_set_fmt,
>> +     .get_fmt = isc_scaler_get_fmt,
>> +     .get_selection = isc_scaler_g_sel,
>> +     .init_cfg = isc_scaler_init_cfg,
>> +};
>> +
>> +static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
>> +     .pad = &isc_scaler_pad_ops,
>> +};
>> +
>> +static int isc_init_own_sd(struct isc_device *isc)
>> +{
>> +     int ret;
>> +
>> +     v4l2_subdev_init(&isc->scaler_sd, &xisc_scaler_subdev_ops);
>> +
>> +     isc->scaler_sd.owner = THIS_MODULE;
>> +     isc->scaler_sd.dev = isc->dev;
>> +     snprintf(isc->scaler_sd.name, sizeof(isc->scaler_sd.name),
>> +              "atmel_isc_scaler");
>> +
>> +     isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>> +     isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
>> +     isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>> +     isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
>> +
>> +     isc->scaler_format.height = isc->max_height;
>> +     isc->scaler_format.width = isc->max_width;
>> +     isc->scaler_format.code = isc->formats_list[0].mbus_code;
>> +     isc->scaler_format.colorspace = V4L2_COLORSPACE_SRGB;
>> +     isc->scaler_format.field = V4L2_FIELD_NONE;
>> +     isc->scaler_format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
>> +     isc->scaler_format.quantization = V4L2_QUANTIZATION_DEFAULT;
>> +     isc->scaler_format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
>> +
>> +     ret = media_entity_pads_init(&isc->scaler_sd.entity,
>> +                                  ISC_SCALER_PADS_NUM,
>> +                                  isc->scaler_pads);
>> +     if (ret < 0) {
>> +             dev_err(isc->dev, "scaler sd media entity init failed\n");
>> +             return ret;
>> +     }
>> +     ret = v4l2_device_register_subdev(&isc->v4l2_dev, &isc->scaler_sd);
>> +     if (ret < 0) {
>> +             dev_err(isc->dev, "scaler sd failed to register subdev\n");
>> +             return ret;
>> +     }
>> +
>> +     return ret;
>> +}
>> +
>> +int isc_mc_init(struct isc_device *isc, u32 ver)
>> +{
>> +     const struct of_device_id *match;
>> +     int ret;
>> +
>> +     isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
>> +     isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
>> +     isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>> +
>> +     ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
>> +                                  isc->pads);
>> +     if (ret < 0) {
>> +             dev_err(isc->dev, "media entity init failed\n");
>> +             return ret;
>> +     }
>> +
>> +     isc->mdev.dev = isc->dev;
>> +     isc->mdev.ops = &isc_media_ops;
>> +
>> +     match = of_match_node(isc->dev->driver->of_match_table,
>> +                           isc->dev->of_node);
>> +
>> +     strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
>> +             sizeof(isc->mdev.driver_name));
>> +     strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
>> +     snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
>> +              isc->v4l2_dev.name);
>> +     isc->mdev.hw_revision = ver;
>> +
>> +     media_device_init(&isc->mdev);
>> +
>> +     isc->v4l2_dev.mdev = &isc->mdev;
>> +
>> +     return isc_init_own_sd(isc);
>> +}
>> +EXPORT_SYMBOL_GPL(isc_mc_init);
>> +
>> +int isc_mc_register(struct isc_device *isc)
>> +{
>> +     int ret;
>> +
>> +     ret = media_create_pad_link(&isc->current_subdev->sd->entity,
>> +                                 isc->remote_pad, &isc->scaler_sd.entity,
>> +                                 ISC_SCALER_PAD_SINK,
>> +                                 MEDIA_LNK_FL_ENABLED |
>> +                                 MEDIA_LNK_FL_IMMUTABLE);
>> +
>> +     if (ret < 0) {
>> +             v4l2_err(&isc->v4l2_dev,
>> +                      "Failed to create pad link: %s to %s\n",
>> +                      isc->current_subdev->sd->entity.name,
>> +                      isc->scaler_sd.entity.name);
>> +             return ret;
>> +     }
>> +
>> +     dev_dbg(isc->dev, "link with %s pad: %d\n",
>> +             isc->current_subdev->sd->name, isc->remote_pad);
>> +
>> +     ret = media_create_pad_link(&isc->scaler_sd.entity,
>> +                                 ISC_SCALER_PAD_SOURCE,
>> +                                 &isc->video_dev.entity, ISC_PAD_SINK,
>> +                                 MEDIA_LNK_FL_ENABLED |
>> +                                 MEDIA_LNK_FL_IMMUTABLE);
>> +
>> +     if (ret < 0) {
>> +             v4l2_err(&isc->v4l2_dev,
>> +                      "Failed to create pad link: %s to %s\n",
>> +                      isc->scaler_sd.entity.name,
>> +                      isc->video_dev.entity.name);
>> +             return ret;
>> +     }
>> +
>> +     dev_dbg(isc->dev, "link with %s pad: %d\n", isc->scaler_sd.name,
>> +             ISC_SCALER_PAD_SOURCE);
>> +
>> +     return media_device_register(&isc->mdev);
> 
> I feel like the isc-base driver shold instead register the
> media-controller and this file shuld actually be only about
> isc-scaler or something. I might be missing why it is not possible
> though. It doesn't seem to me that mc support is conditional, so it
> can happen in the base driver directly ?

This actually is the base driver. Just that the atmel-isc-base.c is 
pretty crowded. So I moved the MC part in this file. But it's the same 
base driver.

> 
> Links creation can still happen at async_complete() (I would have
> suggested _bound() time, but you have no asyn subdev for the scaler,
> so I guess the only async subdev here is the sensor).

Yes, the sensor or any kind of subdevice (XISC normally is connected to 
a bridge, ISC to a sensor directly )

> 
> All in all: can this function be removed and:
> 1) Base driver registers the media controller device in probe

Should we register the media device even if it's not operational ? and 
no video device has been registered ?
I thought it would be safer to have it registered with all the 
links/entities/etc once the video node has been completed.

But if you say this is the proper way, I can do that.
I wanted to keep things separated and not overcrowd the base file /probe 
function, but if it's just a media_device_register call, I can do it there.

> 2) links are created at async_complete time ?

That works too. I think I could move them there.

Thanks for reviewing,

Eugen

> 
> Thanks
>     j
> 
> 
>> +}
>> +EXPORT_SYMBOL_GPL(isc_mc_register);
>> +
>> +void isc_mc_cleanup(struct isc_device *isc)
>> +{
>> +     media_entity_cleanup(&isc->video_dev.entity);
>> +}
>> +EXPORT_SYMBOL_GPL(isc_mc_cleanup);
>> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
>> index 07fa6dbf8460..0b6370d7775f 100644
>> --- a/drivers/media/platform/atmel/atmel-isc.h
>> +++ b/drivers/media/platform/atmel/atmel-isc.h
>> @@ -183,6 +183,17 @@ struct isc_reg_offsets {
>>        u32 his_entry;
>>   };
>>
>> +enum isc_mc_pads {
>> +     ISC_PAD_SINK    = 0,
>> +     ISC_PADS_NUM    = 1,
>> +};
>> +
>> +enum isc_scaler_pads {
>> +     ISC_SCALER_PAD_SINK     = 0,
>> +     ISC_SCALER_PAD_SOURCE   = 1,
>> +     ISC_SCALER_PADS_NUM     = 2,
>> +};
>> +
>>   /*
>>    * struct isc_device - ISC device driver data/config struct
>>    * @regmap:          Register map
>> @@ -258,6 +269,12 @@ struct isc_reg_offsets {
>>    *                   be used as an input to the controller
>>    * @controller_formats_size: size of controller_formats array
>>    * @formats_list_size:       size of formats_list array
>> + * @pads:            media controller pads for isc video entity
>> + * @mdev:            media device that is registered by the isc
>> + * @remote_pad:              remote pad on the connected subdevice
>> + * @scaler_sd:               subdevice for the scaler that isc registers
>> + * @scaler_pads:     media controller pads for the scaler subdevice
>> + * @scaler_format:   current format for the scaler subdevice
>>    */
>>   struct isc_device {
>>        struct regmap           *regmap;
>> @@ -346,6 +363,19 @@ struct isc_device {
>>        struct isc_format               *formats_list;
>>        u32                             controller_formats_size;
>>        u32                             formats_list_size;
>> +
>> +     struct {
>> +             struct media_pad                pads[ISC_PADS_NUM];
>> +             struct media_device             mdev;
>> +
>> +             u32                             remote_pad;
>> +     };
>> +
>> +     struct {
>> +             struct v4l2_subdev              scaler_sd;
>> +             struct media_pad                scaler_pads[ISC_SCALER_PADS_NUM];
>> +             struct v4l2_mbus_framefmt       scaler_format;
>> +     };
>>   };
>>
>>   extern const struct regmap_config isc_regmap_config;
>> @@ -357,4 +387,10 @@ int isc_clk_init(struct isc_device *isc);
>>   void isc_subdev_cleanup(struct isc_device *isc);
>>   void isc_clk_cleanup(struct isc_device *isc);
>>
>> +int isc_mc_init(struct isc_device *isc, u32 ver);
>> +int isc_mc_register(struct isc_device *isc);
>> +void isc_mc_cleanup(struct isc_device *isc);
>> +
>> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
>> +                                        unsigned int code, int *index);
>>   #endif
>> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>> index 1b2063cce0f7..a3e4c32a66c4 100644
>> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>> @@ -529,6 +529,12 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>                        break;
>>        }
>>
>> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>> +
>> +     ret = isc_mc_init(isc, ver);
>> +     if (ret < 0)
>> +             goto isc_probe_mc_init_err;
>> +
>>        pm_runtime_set_active(dev);
>>        pm_runtime_enable(dev);
>>        pm_request_idle(dev);
>> @@ -538,7 +544,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>        ret = clk_prepare_enable(isc->ispck);
>>        if (ret) {
>>                dev_err(dev, "failed to enable ispck: %d\n", ret);
>> -             goto cleanup_subdev;
>> +             goto isc_probe_mc_init_err;
>>        }
>>
>>        /* ispck should be greater or equal to hclock */
>> @@ -548,7 +554,6 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>                goto unprepare_clk;
>>        }
>>
>> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>        dev_info(dev, "Microchip ISC version %x\n", ver);
>>
>>        return 0;
>> @@ -556,6 +561,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>   unprepare_clk:
>>        clk_disable_unprepare(isc->ispck);
>>
>> +isc_probe_mc_init_err:
>> +     isc_mc_cleanup(isc);
>> +
>>   cleanup_subdev:
>>        isc_subdev_cleanup(isc);
>>
>> @@ -576,6 +584,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
>>
>>        pm_runtime_disable(&pdev->dev);
>>
>> +     isc_mc_cleanup(isc);
>> +
>>        isc_subdev_cleanup(isc);
>>
>>        v4l2_device_unregister(&isc->v4l2_dev);
>> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>> index 2b1082295c13..d2ac80b1ccc3 100644
>> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>> @@ -523,15 +523,23 @@ static int microchip_xisc_probe(struct platform_device *pdev)
>>                        break;
>>        }
>>
>> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>> +
>> +     ret = isc_mc_init(isc, ver);
>> +     if (ret < 0)
>> +             goto isc_probe_mc_init_err;
>> +
>>        pm_runtime_set_active(dev);
>>        pm_runtime_enable(dev);
>>        pm_request_idle(dev);
>>
>> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>        dev_info(dev, "Microchip XISC version %x\n", ver);
>>
>>        return 0;
>>
>> +isc_probe_mc_init_err:
>> +     isc_mc_cleanup(isc);
>> +
>>   cleanup_subdev:
>>        isc_subdev_cleanup(isc);
>>
>> @@ -552,6 +560,8 @@ static int microchip_xisc_remove(struct platform_device *pdev)
>>
>>        pm_runtime_disable(&pdev->dev);
>>
>> +     isc_mc_cleanup(isc);
>> +
>>        isc_subdev_cleanup(isc);
>>
>>        v4l2_device_unregister(&isc->v4l2_dev);
>> --
>> 2.25.1
>>


From clabbe.montjoie at gmail.com  Tue Jan 11 08:32:11 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 11 Jan 2022 17:32:11 +0100
Subject: [PATCH v3] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>
Message-ID: <Yd2xC7ZaHrTAXcZd@Red>

Le Tue, Jan 11, 2022 at 11:05:53AM +0800, Conley Lee a ?crit :
> This patch remove magic numbers in sun4i-emac.c and replace with macros
> defined in sun4i-emac.h
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>

Hello

I sent a CI job witch next-20220107+yourpatch and saw no regression.

Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Tested-on: sun4i-a10-olinuxino-lime

Thanks!
Regards


From Eugen.Hristev at microchip.com  Tue Jan 11 08:38:16 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Tue, 11 Jan 2022 16:38:16 +0000
Subject: [PATCH v3 07/23] media: atmel: atmel-isc-base: use streaming
 status when queueing buffers
In-Reply-To: <c6adb59e-4554-dc08-3772-148eb22c29ba@xs4all.nl>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-8-eugen.hristev@microchip.com>
 <c6adb59e-4554-dc08-3772-148eb22c29ba@xs4all.nl>
Message-ID: <5e4f591b-9105-9de0-5067-2bd82dc04983@microchip.com>

On 1/11/22 5:53 PM, Hans Verkuil wrote:
> On 13/12/2021 14:49, Eugen Hristev wrote:
>> During experiments with libcamera, it looks like vb2_is_streaming returns
>> true before our start streaming is called.
>> Order of operations is streamon -> queue -> start_streaming
>> ISC would have started the DMA immediately when a buffer is being added
>> to the vbqueue if the queue is streaming.
>> It is more safe to start the DMA after the start streaming of the driver is
>> called.
>> Thus, even if vb2queue is streaming, add the buffer to the dma queue of the
>> driver instead of actually starting the DMA process, if the start streaming
>> has not been called yet.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> ---
>>   drivers/media/platform/atmel/atmel-isc-base.c | 17 ++++++++++-------
>>   1 file changed, 10 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>> index 26a6090f056c..e6c9071c04f0 100644
>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>> @@ -441,12 +441,14 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
>>        unsigned long flags;
>>
>>        spin_lock_irqsave(&isc->dma_queue_lock, flags);
>> -     if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
>> -             vb2_is_streaming(vb->vb2_queue)) {
>> +
>> +     if (!isc->cur_frm && list_empty(&isc->dma_queue) && !isc->stop) {
>>                isc->cur_frm = buf;
>>                isc_start_dma(isc);
>> -     } else
>> +     } else {
>>                list_add_tail(&buf->list, &isc->dma_queue);
>> +     }
>> +
>>        spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
>>   }
> 
> Both the old and new code doesn't make a lot of sense.

Hello Hans,

I debated this a bit with Laurent when I initially wrote the patch.

The problem with the current code, or the current way things are 
working, is the fact that vb2_is_streaming returns true from the moment 
of streamon.
The DMA engine of the ISC is being started at the moment of 
start_streaming, and if buffers are being sent earlier/later, they are 
just added to the queue and DMA engine is restarted if it finished 
previously.
However if frames are added beforehand, like, first streamon, then add 
some frames, and then later call the start_streaming, ISC will crash. 
(as I said, DMA engine is prepared at start_streaming).
To avoid this, I changed the vb2_is_streaming calls to keeping an 
internal state of the streaming.
Do you think I should try another different approach to solve this ?
Perhaps do not prepare the ISC dma engine at start_streaming, but at 
another place ?

Laurent do you remember the talk we had about this problem a while back ?

> 
> buf_queue is only called by vb2 if start_streaming has already been called or is
> about to be called.

That's a huge difference for ISC driver as it is today. start_streaming 
being called afterwards, means the ISC DMA engine is not started (not 
started streaming), hence a crash.

> 
> Typically all that the buf_queue op does is to call list_add_tail(&buf->list, &isc->dma_queue);
> inside the spinlock.
> 
>>
>> @@ -1014,7 +1016,7 @@ static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>>   {
>>        struct isc_device *isc = video_drvdata(file);
>>
>> -     if (vb2_is_streaming(&isc->vb2_vidq))
>> +     if (!isc->stop)
> 
> This is weird as well. Normally this calls vb2_is_busy to check if the
> queue is busy (that really means that buffers are already allocated, so
> changing the format isn't allowed anymore).

You think the query to the streaming status makes no sense here hence it 
should be removed completely ?
I can do that with a prequel patch if it's the case.

Thanks for reviewing,

Eugen

> 
>>                return -EBUSY;
>>
>>        return isc_set_fmt(isc, f);
>> @@ -1536,7 +1538,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>
>>                isc_update_awb_ctrls(isc);
>>
>> -             if (vb2_is_streaming(&isc->vb2_vidq)) {
>> +             if (!isc->stop) {
> 
> Ditto.
> 
>>                        /*
>>                         * If we are streaming, we can update profile to
>>                         * have the new settings in place.
>> @@ -1552,8 +1554,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>                }
>>
>>                /* if we have autowhitebalance on, start histogram procedure */
>> -             if (ctrls->awb == ISC_WB_AUTO &&
>> -                 vb2_is_streaming(&isc->vb2_vidq) &&
>> +             if (ctrls->awb == ISC_WB_AUTO && !isc->stop &&
>>                    ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>>                        isc_set_histogram(isc, true);
>>
>> @@ -1829,6 +1830,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>        struct vb2_queue *q = &isc->vb2_vidq;
>>        int ret = 0;
>>
>> +     isc->stop = true;
>> +
> 
> I'm really not sure that you need the stop bool at all.
> 
>>        INIT_WORK(&isc->awb_work, isc_awb_work);
>>
>>        ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
> 
> Regards,
> 
>          Hans
> 


From krzysztof.kozlowski at canonical.com  Tue Jan 11 08:43:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 17:43:21 +0100
Subject: [PATCH 2/3] regulator: dt-bindings: maxim,max77802: Convert to
 dtschema
In-Reply-To: <YdRoyQsABBGen54D@robh.at.kernel.org>
References: <20211228164305.35877-1-krzysztof.kozlowski@canonical.com>
 <20211228164305.35877-3-krzysztof.kozlowski@canonical.com>
 <YdRoyQsABBGen54D@robh.at.kernel.org>
Message-ID: <a5feb8ad-e6af-0222-db07-eeaea184dbba@canonical.com>

On 04/01/2022 16:33, Rob Herring wrote:
> On Tue, Dec 28, 2021 at 05:43:04PM +0100, Krzysztof Kozlowski wrote:
>> Convert the regulators of Maxim MAX77802 PMIC to DT schema format.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/regulator/max77802.txt           | 111 ----------------
>>  .../bindings/regulator/maxim,max77802.yaml    | 118 ++++++++++++++++++
>>  2 files changed, 118 insertions(+), 111 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/regulator/max77802.txt
>>  create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt
>> deleted file mode 100644
>> index b82943d83677..000000000000
>> --- a/Documentation/devicetree/bindings/regulator/max77802.txt
>> +++ /dev/null
>> @@ -1,111 +0,0 @@
>> -Binding for Maxim MAX77802 regulators
>> -
>> -This is a part of device tree bindings of MAX77802 multi-function device.
>> -More information can be found in bindings/mfd/max77802.txt file.
>> -
>> -The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO)
>> -regulators that can be controlled over I2C.
>> -
>> -Following properties should be present in main device node of the MFD chip.
>> -
>> -Optional properties:
>> -- inb1-supply:  The input supply for BUCK1
>> -- inb2-supply:  The input supply for BUCK2
>> -- inb3-supply:  The input supply for BUCK3
>> -- inb4-supply:  The input supply for BUCK4
>> -- inb5-supply:  The input supply for BUCK5
>> -- inb6-supply:  The input supply for BUCK6
>> -- inb7-supply:  The input supply for BUCK7
>> -- inb8-supply:  The input supply for BUCK8
>> -- inb9-supply:  The input supply for BUCK9
>> -- inb10-supply: The input supply for BUCK10
>> -- inl1-supply:  The input supply for LDO8 and LDO15
>> -- inl2-supply:  The input supply for LDO17, LDO27, LDO30 and LDO35
>> -- inl3-supply:  The input supply for LDO3, LDO5, LDO6 and LDO7
>> -- inl4-supply:  The input supply for LDO10, LDO11, LDO13 and LDO14
>> -- inl5-supply:  The input supply for LDO9 and LDO19
>> -- inl6-supply:  The input supply for LDO4, LDO21, LDO24 and LDO33
>> -- inl7-supply:  The input supply for LDO18, LDO20, LDO28 and LDO29
>> -- inl9-supply:  The input supply for LDO12, LDO23, LDO25, LDO26, LDO32 and LDO34
>> -- inl10-supply: The input supply for LDO1 and LDO2
>> -
>> -Optional nodes:
>> -- regulators : The regulators of max77802 have to be instantiated
>> -  under subnode named "regulators" using the following format.
>> -
>> -	regulator-name {
>> -		standard regulator constraints....
>> -	};
>> -	refer Documentation/devicetree/bindings/regulator/regulator.txt
>> -
>> -The regulator node name should be initialized with a string to get matched
>> -with their hardware counterparts as follow. The valid names are:
>> -
>> -	-LDOn 	:	for LDOs, where n can lie in ranges 1-15, 17-21, 23-30
>> -			and 32-35.
>> -			example: LDO1, LDO2, LDO35.
>> -	-BUCKn 	:	for BUCKs, where n can lie in range 1 to 10.
>> -			example: BUCK1, BUCK5, BUCK10.
>> -
>> -The max77802 regulator supports two different operating modes: Normal and Low
>> -Power Mode. Some regulators support the modes to be changed at startup or by
>> -the consumers during normal operation while others only support to change the
>> -mode during system suspend. The standard regulator suspend states binding can
>> -be used to configure the regulator operating mode.
>> -
>> -The regulators that support the standard "regulator-initial-mode" property,
>> -changing their mode during normal operation are: LDOs 1, 3, 20 and 21.
>> -
>> -The possible values for "regulator-initial-mode" and "regulator-mode" are:
>> -	1: Normal regulator voltage output mode.
>> -	3: Low Power which reduces the quiescent current down to only 1uA
>> -
>> -The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
>> -header and can be included by device tree source files.
>> -
>> -The standard "regulator-mode" property can only be used for regulators that
>> -support changing their mode to Low Power Mode during suspend. These regulators
>> -are: BUCKs 2-4 and LDOs 1-35. Also, it only takes effect if the regulator has
>> -been enabled for the given suspend state using "regulator-on-in-suspend" and
>> -has not been disabled for that state using "regulator-off-in-suspend".
>> -
>> -Example:
>> -
>> -	max77802 at 9 {
>> -		compatible = "maxim,max77802";
>> -		interrupt-parent = <&wakeup_eint>;
>> -		interrupts = <26 0>;
>> -		reg = <0x09>;
>> -		#address-cells = <1>;
>> -		#size-cells = <0>;
>> -
>> -		inb1-supply = <&parent_reg>;
>> -
>> -		regulators {
>> -			ldo1_reg: LDO1 {
>> -				regulator-name = "vdd_1v0";
>> -				regulator-min-microvolt = <1000000>;
>> -				regulator-max-microvolt = <1000000>;
>> -				regulator-always-on;
>> -				regulator-initial-mode = <MAX77802_OPMODE_LP>;
>> -			};
>> -
>> -			ldo11_reg: LDO11 {
>> -				regulator-name = "vdd_ldo11";
>> -				regulator-min-microvolt = <1900000>;
>> -				regulator-max-microvolt = <1900000>;
>> -				regulator-always-on;
>> -				regulator-state-mem {
>> -					regulator-on-in-suspend;
>> -					regulator-mode = <MAX77802_OPMODE_LP>;
>> -				};
>> -			};
>> -
>> -			buck1_reg: BUCK1 {
>> -				regulator-name = "vdd_mif";
>> -				regulator-min-microvolt = <950000>;
>> -				regulator-max-microvolt = <1300000>;
>> -				regulator-always-on;
>> -				regulator-boot-on;
>> -			};
>> -	};
>> diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
>> new file mode 100644
>> index 000000000000..01e1c40685ff
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
>> @@ -0,0 +1,118 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/regulator/maxim,max77802.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Maxim MAX77802 Power Management IC regulators
>> +
>> +maintainers:
>> +  - Javier Martinez Canillas <javier at dowhile0.org>
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description: |
>> +  This is a part of device tree bindings for Maxim MAX77802 Power Management
>> +  Integrated Circuit (PMIC).
>> +
>> +  The Maxim MAX77686 provides 10 high-efficiency Buck and 32 Low-DropOut (LDO)
>> +  regulators.
>> +
>> +  See also Documentation/devicetree/bindings/mfd/maxim,max77802.yaml for
>> +  additional information and example.
>> +
>> +  Certain regulators support "regulator-initial-mode" and "regulator-mode".
>> +  The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
>> +  and their meaning is:
>> +    1 - Normal regulator voltage output mode.
>> +    3 - Low Power which reduces the quiescent current down to only 1uA
>> +
>> +  The standard "regulator-mode" property can only be used for regulators that
>> +  support changing their mode to Low Power Mode during suspend. These
>> +  regulators are: bucks 2-4 and LDOs 1-35. Also, it only takes effect if the
>> +  regulator has been enabled for the given suspend state using
>> +  "regulator-on-in-suspend" and has not been disabled for that state using
>> +  "regulator-off-in-suspend".
>> +
>> +patternProperties:
>> +  # LDO1, LDO3, LDO20, LDO21
>> +  "^LDO([13]|2[01])$":
>> +    type: object
>> +    $ref: regulator.yaml#
>> +    unevaluatedProperties: false
>> +    description:
>> +      LDOs supporting the regulator-initial-mode property and changing their
>> +      mode during normal operation.
>> +
>> +    properties:
>> +      regulator-initial-mode: true
> 
> Same issues here as the other series.

Right.

> 
>> +
>> +    patternProperties:
>> +      regulator-state-(standby|mem|disk):
>> +        type: object
>> +        properties:
>> +          regulator-mode: true
> 
> Is this the only valid property? 
> 
No. I will skip entire patternProperties for regulators where there are
no constraints about other properties.

Best regards,
Krzysztof


From valentin.caron at foss.st.com  Tue Jan 11 08:44:39 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 11 Jan 2022 17:44:39 +0100
Subject: [PATCH 0/2] serial: stm32: fix software flow control
Message-ID: <20220111164441.6178-1-valentin.caron@foss.st.com>

This serie fix issues on STM32 USART driver when using software flow control.

Valentin Caron (2):
  serial: stm32: prevent TDR register overwrite when sending x_char
  serial: stm32: fix software flow control transfer

 drivers/tty/serial/stm32-usart.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan 11 08:44:41 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 11 Jan 2022 17:44:41 +0100
Subject: [PATCH 2/2] serial: stm32: fix software flow control transfer
In-Reply-To: <20220111164441.6178-1-valentin.caron@foss.st.com>
References: <20220111164441.6178-1-valentin.caron@foss.st.com>
Message-ID: <20220111164441.6178-3-valentin.caron@foss.st.com>

x_char is ignored by stm32_usart_start_tx() when xmit buffer is empty.

Fix start_tx condition to allow x_char to be sent.

Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver")

Signed-off-by: Erwan Le Ray <erwan.leray at foss.st.com>
Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index c1b8828451c8..9570002d07e7 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -742,7 +742,7 @@ static void stm32_usart_start_tx(struct uart_port *port)
 	struct serial_rs485 *rs485conf = &port->rs485;
 	struct circ_buf *xmit = &port->state->xmit;
 
-	if (uart_circ_empty(xmit))
+	if (uart_circ_empty(xmit) && !port->x_char)
 		return;
 
 	if (rs485conf->flags & SER_RS485_ENABLED) {
-- 
2.17.1



From valentin.caron at foss.st.com  Tue Jan 11 08:44:40 2022
From: valentin.caron at foss.st.com (Valentin Caron)
Date: Tue, 11 Jan 2022 17:44:40 +0100
Subject: [PATCH 1/2] serial: stm32: prevent TDR register overwrite when
 sending x_char
In-Reply-To: <20220111164441.6178-1-valentin.caron@foss.st.com>
References: <20220111164441.6178-1-valentin.caron@foss.st.com>
Message-ID: <20220111164441.6178-2-valentin.caron@foss.st.com>

When sending x_char in stm32_usart_transmit_chars(), driver can overwrite
the value of TDR register by the value of x_char. If this happens, the
previous value that was present in TDR register will not be sent through
uart.

This code checks if the previous value in TDR register is sent before
writing the x_char value into register.

Fixes: 48a6092fb41f ("serial: stm32-usart: Add STM32 USART Driver")

Signed-off-by: Valentin Caron <valentin.caron at foss.st.com>
---
 drivers/tty/serial/stm32-usart.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
index 1f89ab0e49ac..c1b8828451c8 100644
--- a/drivers/tty/serial/stm32-usart.c
+++ b/drivers/tty/serial/stm32-usart.c
@@ -550,11 +550,23 @@ static void stm32_usart_transmit_chars(struct uart_port *port)
 	struct stm32_port *stm32_port = to_stm32_port(port);
 	const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs;
 	struct circ_buf *xmit = &port->state->xmit;
+	u32 isr;
+	int ret;
 
 	if (port->x_char) {
 		if (stm32_usart_tx_dma_started(stm32_port) &&
 		    stm32_usart_tx_dma_enabled(stm32_port))
 			stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT);
+
+		/* Check that TDR is empty before filling FIFO */
+		ret =
+		readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr,
+						  isr,
+						  (isr & USART_SR_TXE),
+						  10, 1000);
+		if (ret)
+			dev_warn(port->dev, "1 character may be erased\n");
+
 		writel_relaxed(port->x_char, port->membase + ofs->tdr);
 		port->x_char = 0;
 		port->icount.tx++;
-- 
2.17.1



From jacopo at jmondi.org  Tue Jan 11 08:51:32 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Tue, 11 Jan 2022 17:51:32 +0100
Subject: [PATCH v3 12/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <e089d9f3-d07b-1e61-f59b-a695912b6558@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-13-eugen.hristev@microchip.com>
 <20220111160603.qi4kbp6rn45hp7po@uno.localdomain>
 <e089d9f3-d07b-1e61-f59b-a695912b6558@microchip.com>
Message-ID: <20220111165132.g62ykrjjk3jh4eyd@uno.localdomain>

On Tue, Jan 11, 2022 at 04:30:15PM +0000, Eugen.Hristev at microchip.com wrote:
> On 1/11/22 6:06 PM, Jacopo Mondi wrote:
> > Hi Eugen,
> >
> > On Mon, Dec 13, 2021 at 03:49:29PM +0200, Eugen Hristev wrote:
> >> Implement the support for media-controller.
> >> This means that the capabilities of the driver have changed and now
> >> it also advertises the IO_MC .
> >> The driver will register it's media device, and add the video entity to this
> >> media device. The subdevices are registered to the same media device.
> >> The ISC will have a base entity which is auto-detected as atmel_isc_base.
> >> It will also register a subdevice that allows cropping of the incoming frame
> >> to the maximum frame size supported by the ISC.
> >> The ISC will create a link between the subdevice that is asynchronously
> >> registered and the atmel_isc_scaler entity.
> >> Then, the atmel_isc_scaler and atmel_isc_base are connected through another
> >> link.
> >>
> >> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> >> ---
> >> Changes in v2:
> >> - implement try formats
> >>
> >>   drivers/media/platform/atmel/Makefile         |   2 +-
> >>   drivers/media/platform/atmel/atmel-isc-base.c |  27 +-
> >>   drivers/media/platform/atmel/atmel-isc-mc.c   | 287 ++++++++++++++++++
> >>   drivers/media/platform/atmel/atmel-isc.h      |  36 +++
> >>   .../media/platform/atmel/atmel-sama5d2-isc.c  |  14 +-
> >>   .../media/platform/atmel/atmel-sama7g5-isc.c  |  12 +-
> >>   6 files changed, 370 insertions(+), 8 deletions(-)
> >>   create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
> >>
> >> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
> >> index 794e8f739287..aa7a18b428f6 100644
> >> --- a/drivers/media/platform/atmel/Makefile
> >> +++ b/drivers/media/platform/atmel/Makefile
> >> @@ -1,7 +1,7 @@
> >>   # SPDX-License-Identifier: GPL-2.0-only
> >>   atmel-isc-objs = atmel-sama5d2-isc.o
> >>   atmel-xisc-objs = atmel-sama7g5-isc.o
> >> -atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
> >> +atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o atmel-isc-mc.o
> >>
> >>   obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
> >>   obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
> >> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> >> index d0542b97a391..b0c3ed21f372 100644
> >> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> >> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> >> @@ -1726,6 +1726,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
> >>                                              struct isc_device, v4l2_dev);
> >>        struct isc_subdev_entity *subdev_entity =
> >>                container_of(notifier, struct isc_subdev_entity, notifier);
> >> +     int pad;
> >>
> >>        if (video_is_registered(&isc->video_dev)) {
> >>                v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
> >> @@ -1734,6 +1735,16 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
> >>
> >>        subdev_entity->sd = subdev;
> >>
> >> +     pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
> >> +                                       MEDIA_PAD_FL_SOURCE);
> >> +     if (pad < 0) {
> >> +             v4l2_err(&isc->v4l2_dev, "failed to find pad for %s\n",
> >> +                      subdev->name);
> >> +             return pad;
> >> +     }
> >> +
> >> +     isc->remote_pad = pad;
> >> +
> >>        return 0;
> >>   }
> >>
> >> @@ -1748,8 +1759,8 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
> >>        v4l2_ctrl_handler_free(&isc->ctrls.handler);
> >>   }
> >>
> >> -static struct isc_format *find_format_by_code(struct isc_device *isc,
> >> -                                           unsigned int code, int *index)
> >> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
> >> +                                        unsigned int code, int *index)
> >>   {
> >>        struct isc_format *fmt = &isc->formats_list[0];
> >>        unsigned int i;
> >> @@ -1765,6 +1776,7 @@ static struct isc_format *find_format_by_code(struct isc_device *isc,
> >>
> >>        return NULL;
> >>   }
> >> +EXPORT_SYMBOL_GPL(isc_find_format_by_code);
> >>
> >>   static int isc_formats_init(struct isc_device *isc)
> >>   {
> >> @@ -1781,7 +1793,7 @@ static int isc_formats_init(struct isc_device *isc)
> >>               NULL, &mbus_code)) {
> >>                mbus_code.index++;
> >>
> >> -             fmt = find_format_by_code(isc, mbus_code.code, &i);
> >> +             fmt = isc_find_format_by_code(isc, mbus_code.code, &i);
> >>                if (!fmt) {
> >>                        v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
> >>                                  mbus_code.code);
> >> @@ -1909,7 +1921,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
> >>        vdev->queue             = q;
> >>        vdev->lock              = &isc->lock;
> >>        vdev->ctrl_handler      = &isc->ctrls.handler;
> >> -     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
> >> +     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
> >> +                               V4L2_CAP_IO_MC;
> >>        video_set_drvdata(vdev, isc);
> >>
> >>        ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
> >> @@ -1919,8 +1932,14 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
> >>                goto isc_async_complete_err;
> >>        }
> >>
> >> +     ret = isc_mc_register(isc);
> >> +     if (ret < 0)
> >> +             goto isc_async_complete_unregister_device;
> >>        return 0;
> >>
> >> +isc_async_complete_unregister_device:
> >> +     video_unregister_device(vdev);
> >> +
> >>   isc_async_complete_err:
> >>        mutex_destroy(&isc->lock);
> >>        return ret;
> >> diff --git a/drivers/media/platform/atmel/atmel-isc-mc.c b/drivers/media/platform/atmel/atmel-isc-mc.c
> >> new file mode 100644
> >> index 000000000000..2aea81d77b2f
> >> --- /dev/null
> >> +++ b/drivers/media/platform/atmel/atmel-isc-mc.c
> >> @@ -0,0 +1,287 @@
> >> +// SPDX-License-Identifier: GPL-2.0-only
> >> +/*
> >> + * Microchip Image Sensor Controller (ISC) Media Controller support
> >> + *
> >> + * Copyright (C) 2021 Microchip Technology, Inc.
> >> + *
> >> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
> >> + *
> >> + */
> >> +
> >> +#include <media/v4l2-device.h>
> >> +#include <media/v4l2-subdev.h>
> >
> > Should you include <media/media-entity.h> and <media/media-device.h> ?
>
> Hi Jacopo,
>
> They are probably being included from another header. I will add them.
>

Thank you :)

> >
> > Also, should you select MEDIA_CONTROLLER and V4L2_SUBDEV_API for all
> > the Kconfig symbols ?
>
>
> VIDEO_ATMEL_ISC directly selects:
> select MEDIA_CONTROLLER
> select VIDEO_V4L2_SUBDEV_API
>
> and VIDEO_ATMEL_XISC
> depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API

And selects VIDEO_ATMEL_ISC_BASE so it's fine!

VIDEO_ATMEL_ISI does not. I'm fine if this is intended, I might have
got lost in the several pieces this driver is composed of :)

>
> and VIDEO_V4L2_SUBDEV_API depends on MEDIA_CONTROLLER
>
> >
> >> +
> >> +#include "atmel-isc-regs.h"
> >> +#include "atmel-isc.h"
> >> +
> >> +static const struct media_device_ops isc_media_ops = {
> >> +};
> >
> > Do you need this even if it's empty ?
> >
>
> Not sure. I can remove it and pass NULL, but I haven't checked what the
> subsystem is doing if there is no ops. I will try.
>

Seems like it is safe as the core checks for if (mdev->ops) before
accessing it (except for mc-request for which operations are
mandatory)

> >> +
> >> +static int isc_scaler_get_fmt(struct v4l2_subdev *sd,
> >> +                           struct v4l2_subdev_state *sd_state,
> >> +                           struct v4l2_subdev_format *format)
> >> +{
> >> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> >> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
> >> +
> >> +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
> >> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> >> +                                                       format->pad);
> >> +             format->format = *v4l2_try_fmt;
> >> +
> >> +             return 0;
> >> +     }
> >> +
> >> +     format->format = isc->scaler_format;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int isc_scaler_set_fmt(struct v4l2_subdev *sd,
> >> +                           struct v4l2_subdev_state *sd_state,
> >> +                           struct v4l2_subdev_format *req_fmt)
> >> +{
> >> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> >> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
> >> +     struct isc_format *fmt;
> >> +     unsigned int i;
> >> +
> >> +     if (req_fmt->pad == ISC_SCALER_PAD_SOURCE)
> >> +             v4l_bound_align_image
> >> +                     (&req_fmt->format.width, 16, isc->max_width, 0,
> >> +                      &req_fmt->format.height, 16, isc->max_height, 0, 0);
> >> +     else
> >> +             v4l_bound_align_image
> >> +                     (&req_fmt->format.width, 16, 10000, 0,
> >> +                      &req_fmt->format.height, 16, 10000, 0, 0);
> >> +
> >> +     req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
> >> +     req_fmt->format.field = V4L2_FIELD_NONE;
> >> +     req_fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> >> +     req_fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
> >> +     req_fmt->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> >> +
> >> +     fmt = isc_find_format_by_code(isc, req_fmt->format.code, &i);
> >> +
> >> +     if (!fmt)
> >> +             fmt = &isc->formats_list[0];
> >> +
> >> +     req_fmt->format.code = fmt->mbus_code;
> >> +
> >> +     if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> >> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
> >> +                                                       req_fmt->pad);
> >> +             *v4l2_try_fmt = req_fmt->format;
> >> +             /* Trying on the pad sink makes the source sink change too */
> >> +             if (req_fmt->pad == ISC_SCALER_PAD_SINK) {
> >> +                     v4l2_try_fmt =
> >> +                             v4l2_subdev_get_try_format(sd, sd_state,
> >> +                                                        ISC_SCALER_PAD_SOURCE);
> >> +                     *v4l2_try_fmt = req_fmt->format;
> >> +
> >> +                     v4l_bound_align_image(&v4l2_try_fmt->width,
> >> +                                           16, isc->max_width, 0,
> >> +                                           &v4l2_try_fmt->height,
> >> +                                           16, isc->max_height, 0, 0);
> >> +             }
> >> +             /* if we are just trying, we are done */
> >> +             return 0;
> >> +     }
> >> +
> >> +     isc->scaler_format = req_fmt->format;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int isc_scaler_enum_mbus_code(struct v4l2_subdev *sd,
> >> +                                  struct v4l2_subdev_state *sd_state,
> >> +                                  struct v4l2_subdev_mbus_code_enum *code)
> >> +{
> >> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> >> +     int supported_index = 0;
> >> +     int i;
> >> +
> >> +     for (i = 0; i < isc->formats_list_size; i++) {
> >> +             if (!isc->formats_list[i].sd_support)
> >> +                     continue;
> >> +             if (supported_index == code->index) {
> >> +                     code->code = isc->formats_list[i].mbus_code;
> >> +                     return 0;
> >> +             }
> >> +             supported_index++;
> >> +     }
> >> +
> >> +     return -EINVAL;
> >> +}
> >> +
> >> +static int isc_scaler_g_sel(struct v4l2_subdev *sd,
> >> +                         struct v4l2_subdev_state *sd_state,
> >> +                         struct v4l2_subdev_selection *sel)
> >> +{
> >> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> >> +
> >> +     if (sel->pad == ISC_SCALER_PAD_SOURCE)
> >> +             return -EINVAL;
> >> +
> >> +     if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS &&
> >> +         sel->target != V4L2_SEL_TGT_CROP)
> >> +             return -EINVAL;
> >> +
> >> +     sel->r.height = isc->max_height;
> >> +     sel->r.width = isc->max_width;
> >> +
> >> +     sel->r.left = 0;
> >> +     sel->r.top = 0;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static int isc_scaler_init_cfg(struct v4l2_subdev *sd,
> >> +                            struct v4l2_subdev_state *sd_state)
> >> +{
> >> +     struct v4l2_mbus_framefmt *v4l2_try_fmt =
> >> +             v4l2_subdev_get_try_format(sd, sd_state, 0);
> >> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
> >> +
> >> +     *v4l2_try_fmt = isc->scaler_format;
> >> +
> >> +     return 0;
> >> +}
> >> +
> >> +static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
> >> +     .enum_mbus_code = isc_scaler_enum_mbus_code,
> >> +     .set_fmt = isc_scaler_set_fmt,
> >> +     .get_fmt = isc_scaler_get_fmt,
> >> +     .get_selection = isc_scaler_g_sel,
> >> +     .init_cfg = isc_scaler_init_cfg,
> >> +};
> >> +
> >> +static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
> >> +     .pad = &isc_scaler_pad_ops,
> >> +};
> >> +
> >> +static int isc_init_own_sd(struct isc_device *isc)
> >> +{
> >> +     int ret;
> >> +
> >> +     v4l2_subdev_init(&isc->scaler_sd, &xisc_scaler_subdev_ops);
> >> +
> >> +     isc->scaler_sd.owner = THIS_MODULE;
> >> +     isc->scaler_sd.dev = isc->dev;
> >> +     snprintf(isc->scaler_sd.name, sizeof(isc->scaler_sd.name),
> >> +              "atmel_isc_scaler");
> >> +
> >> +     isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> >> +     isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
> >> +     isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> >> +     isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
> >> +
> >> +     isc->scaler_format.height = isc->max_height;
> >> +     isc->scaler_format.width = isc->max_width;
> >> +     isc->scaler_format.code = isc->formats_list[0].mbus_code;
> >> +     isc->scaler_format.colorspace = V4L2_COLORSPACE_SRGB;
> >> +     isc->scaler_format.field = V4L2_FIELD_NONE;
> >> +     isc->scaler_format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> >> +     isc->scaler_format.quantization = V4L2_QUANTIZATION_DEFAULT;
> >> +     isc->scaler_format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
> >> +
> >> +     ret = media_entity_pads_init(&isc->scaler_sd.entity,
> >> +                                  ISC_SCALER_PADS_NUM,
> >> +                                  isc->scaler_pads);
> >> +     if (ret < 0) {
> >> +             dev_err(isc->dev, "scaler sd media entity init failed\n");
> >> +             return ret;
> >> +     }
> >> +     ret = v4l2_device_register_subdev(&isc->v4l2_dev, &isc->scaler_sd);
> >> +     if (ret < 0) {
> >> +             dev_err(isc->dev, "scaler sd failed to register subdev\n");
> >> +             return ret;
> >> +     }
> >> +
> >> +     return ret;
> >> +}
> >> +
> >> +int isc_mc_init(struct isc_device *isc, u32 ver)
> >> +{
> >> +     const struct of_device_id *match;
> >> +     int ret;
> >> +
> >> +     isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
> >> +     isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
> >> +     isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
> >> +
> >> +     ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
> >> +                                  isc->pads);
> >> +     if (ret < 0) {
> >> +             dev_err(isc->dev, "media entity init failed\n");
> >> +             return ret;
> >> +     }
> >> +
> >> +     isc->mdev.dev = isc->dev;
> >> +     isc->mdev.ops = &isc_media_ops;
> >> +
> >> +     match = of_match_node(isc->dev->driver->of_match_table,
> >> +                           isc->dev->of_node);
> >> +
> >> +     strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
> >> +             sizeof(isc->mdev.driver_name));
> >> +     strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
> >> +     snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
> >> +              isc->v4l2_dev.name);
> >> +     isc->mdev.hw_revision = ver;
> >> +
> >> +     media_device_init(&isc->mdev);
> >> +
> >> +     isc->v4l2_dev.mdev = &isc->mdev;
> >> +
> >> +     return isc_init_own_sd(isc);
> >> +}
> >> +EXPORT_SYMBOL_GPL(isc_mc_init);
> >> +
> >> +int isc_mc_register(struct isc_device *isc)
> >> +{
> >> +     int ret;
> >> +
> >> +     ret = media_create_pad_link(&isc->current_subdev->sd->entity,
> >> +                                 isc->remote_pad, &isc->scaler_sd.entity,
> >> +                                 ISC_SCALER_PAD_SINK,
> >> +                                 MEDIA_LNK_FL_ENABLED |
> >> +                                 MEDIA_LNK_FL_IMMUTABLE);
> >> +
> >> +     if (ret < 0) {
> >> +             v4l2_err(&isc->v4l2_dev,
> >> +                      "Failed to create pad link: %s to %s\n",
> >> +                      isc->current_subdev->sd->entity.name,
> >> +                      isc->scaler_sd.entity.name);
> >> +             return ret;
> >> +     }
> >> +
> >> +     dev_dbg(isc->dev, "link with %s pad: %d\n",
> >> +             isc->current_subdev->sd->name, isc->remote_pad);
> >> +
> >> +     ret = media_create_pad_link(&isc->scaler_sd.entity,
> >> +                                 ISC_SCALER_PAD_SOURCE,
> >> +                                 &isc->video_dev.entity, ISC_PAD_SINK,
> >> +                                 MEDIA_LNK_FL_ENABLED |
> >> +                                 MEDIA_LNK_FL_IMMUTABLE);
> >> +
> >> +     if (ret < 0) {
> >> +             v4l2_err(&isc->v4l2_dev,
> >> +                      "Failed to create pad link: %s to %s\n",
> >> +                      isc->scaler_sd.entity.name,
> >> +                      isc->video_dev.entity.name);
> >> +             return ret;
> >> +     }
> >> +
> >> +     dev_dbg(isc->dev, "link with %s pad: %d\n", isc->scaler_sd.name,
> >> +             ISC_SCALER_PAD_SOURCE);
> >> +
> >> +     return media_device_register(&isc->mdev);
> >
> > I feel like the isc-base driver shold instead register the
> > media-controller and this file shuld actually be only about
> > isc-scaler or something. I might be missing why it is not possible
> > though. It doesn't seem to me that mc support is conditional, so it
> > can happen in the base driver directly ?
>
> This actually is the base driver. Just that the atmel-isc-base.c is
> pretty crowded. So I moved the MC part in this file. But it's the same
> base driver.
>

I understand. isc-base is pretty big, you're right.
However breaking mc apart in a file that mixes registering an entity
for the scaler and initializing mc for the whole driver feels weird,
at least to me, as I don't immediately get why the mc part is handled
by the scaler file...

> >
> > Links creation can still happen at async_complete() (I would have
> > suggested _bound() time, but you have no asyn subdev for the scaler,
> > so I guess the only async subdev here is the sensor).
>
> Yes, the sensor or any kind of subdevice (XISC normally is connected to
> a bridge, ISC to a sensor directly )
>
> >
> > All in all: can this function be removed and:
> > 1) Base driver registers the media controller device in probe
>
> Should we register the media device even if it's not operational ? and
> no video device has been registered ?
> I thought it would be safer to have it registered with all the
> links/entities/etc once the video node has been completed.
>
> But if you say this is the proper way, I can do that.
> I wanted to keep things separated and not overcrowd the base file /probe
> function, but if it's just a media_device_register call, I can do it there.

You are right. Calling media_device_register() at async_complete time
is the right thing to do.

Thanks
   j


>
> > 2) links are created at async_complete time ?
>
> That works too. I think I could move them there.
>
> Thanks for reviewing,
>
> Eugen
>
> >
> > Thanks
> >     j
> >
> >
> >> +}
> >> +EXPORT_SYMBOL_GPL(isc_mc_register);
> >> +
> >> +void isc_mc_cleanup(struct isc_device *isc)
> >> +{
> >> +     media_entity_cleanup(&isc->video_dev.entity);
> >> +}
> >> +EXPORT_SYMBOL_GPL(isc_mc_cleanup);
> >> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> >> index 07fa6dbf8460..0b6370d7775f 100644
> >> --- a/drivers/media/platform/atmel/atmel-isc.h
> >> +++ b/drivers/media/platform/atmel/atmel-isc.h
> >> @@ -183,6 +183,17 @@ struct isc_reg_offsets {
> >>        u32 his_entry;
> >>   };
> >>
> >> +enum isc_mc_pads {
> >> +     ISC_PAD_SINK    = 0,
> >> +     ISC_PADS_NUM    = 1,
> >> +};
> >> +
> >> +enum isc_scaler_pads {
> >> +     ISC_SCALER_PAD_SINK     = 0,
> >> +     ISC_SCALER_PAD_SOURCE   = 1,
> >> +     ISC_SCALER_PADS_NUM     = 2,
> >> +};
> >> +
> >>   /*
> >>    * struct isc_device - ISC device driver data/config struct
> >>    * @regmap:          Register map
> >> @@ -258,6 +269,12 @@ struct isc_reg_offsets {
> >>    *                   be used as an input to the controller
> >>    * @controller_formats_size: size of controller_formats array
> >>    * @formats_list_size:       size of formats_list array
> >> + * @pads:            media controller pads for isc video entity
> >> + * @mdev:            media device that is registered by the isc
> >> + * @remote_pad:              remote pad on the connected subdevice
> >> + * @scaler_sd:               subdevice for the scaler that isc registers
> >> + * @scaler_pads:     media controller pads for the scaler subdevice
> >> + * @scaler_format:   current format for the scaler subdevice
> >>    */
> >>   struct isc_device {
> >>        struct regmap           *regmap;
> >> @@ -346,6 +363,19 @@ struct isc_device {
> >>        struct isc_format               *formats_list;
> >>        u32                             controller_formats_size;
> >>        u32                             formats_list_size;
> >> +
> >> +     struct {
> >> +             struct media_pad                pads[ISC_PADS_NUM];
> >> +             struct media_device             mdev;
> >> +
> >> +             u32                             remote_pad;
> >> +     };
> >> +
> >> +     struct {
> >> +             struct v4l2_subdev              scaler_sd;
> >> +             struct media_pad                scaler_pads[ISC_SCALER_PADS_NUM];
> >> +             struct v4l2_mbus_framefmt       scaler_format;
> >> +     };
> >>   };
> >>
> >>   extern const struct regmap_config isc_regmap_config;
> >> @@ -357,4 +387,10 @@ int isc_clk_init(struct isc_device *isc);
> >>   void isc_subdev_cleanup(struct isc_device *isc);
> >>   void isc_clk_cleanup(struct isc_device *isc);
> >>
> >> +int isc_mc_init(struct isc_device *isc, u32 ver);
> >> +int isc_mc_register(struct isc_device *isc);
> >> +void isc_mc_cleanup(struct isc_device *isc);
> >> +
> >> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
> >> +                                        unsigned int code, int *index);
> >>   #endif
> >> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> >> index 1b2063cce0f7..a3e4c32a66c4 100644
> >> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> >> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> >> @@ -529,6 +529,12 @@ static int atmel_isc_probe(struct platform_device *pdev)
> >>                        break;
> >>        }
> >>
> >> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> >> +
> >> +     ret = isc_mc_init(isc, ver);
> >> +     if (ret < 0)
> >> +             goto isc_probe_mc_init_err;
> >> +
> >>        pm_runtime_set_active(dev);
> >>        pm_runtime_enable(dev);
> >>        pm_request_idle(dev);
> >> @@ -538,7 +544,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
> >>        ret = clk_prepare_enable(isc->ispck);
> >>        if (ret) {
> >>                dev_err(dev, "failed to enable ispck: %d\n", ret);
> >> -             goto cleanup_subdev;
> >> +             goto isc_probe_mc_init_err;
> >>        }
> >>
> >>        /* ispck should be greater or equal to hclock */
> >> @@ -548,7 +554,6 @@ static int atmel_isc_probe(struct platform_device *pdev)
> >>                goto unprepare_clk;
> >>        }
> >>
> >> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> >>        dev_info(dev, "Microchip ISC version %x\n", ver);
> >>
> >>        return 0;
> >> @@ -556,6 +561,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
> >>   unprepare_clk:
> >>        clk_disable_unprepare(isc->ispck);
> >>
> >> +isc_probe_mc_init_err:
> >> +     isc_mc_cleanup(isc);
> >> +
> >>   cleanup_subdev:
> >>        isc_subdev_cleanup(isc);
> >>
> >> @@ -576,6 +584,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
> >>
> >>        pm_runtime_disable(&pdev->dev);
> >>
> >> +     isc_mc_cleanup(isc);
> >> +
> >>        isc_subdev_cleanup(isc);
> >>
> >>        v4l2_device_unregister(&isc->v4l2_dev);
> >> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> >> index 2b1082295c13..d2ac80b1ccc3 100644
> >> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> >> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> >> @@ -523,15 +523,23 @@ static int microchip_xisc_probe(struct platform_device *pdev)
> >>                        break;
> >>        }
> >>
> >> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> >> +
> >> +     ret = isc_mc_init(isc, ver);
> >> +     if (ret < 0)
> >> +             goto isc_probe_mc_init_err;
> >> +
> >>        pm_runtime_set_active(dev);
> >>        pm_runtime_enable(dev);
> >>        pm_request_idle(dev);
> >>
> >> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
> >>        dev_info(dev, "Microchip XISC version %x\n", ver);
> >>
> >>        return 0;
> >>
> >> +isc_probe_mc_init_err:
> >> +     isc_mc_cleanup(isc);
> >> +
> >>   cleanup_subdev:
> >>        isc_subdev_cleanup(isc);
> >>
> >> @@ -552,6 +560,8 @@ static int microchip_xisc_remove(struct platform_device *pdev)
> >>
> >>        pm_runtime_disable(&pdev->dev);
> >>
> >> +     isc_mc_cleanup(isc);
> >> +
> >>        isc_subdev_cleanup(isc);
> >>
> >>        v4l2_device_unregister(&isc->v4l2_dev);
> >> --
> >> 2.25.1
> >>
>


From zajec5 at gmail.com  Tue Jan 11 08:51:44 2022
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 11 Jan 2022 17:51:44 +0100
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic function
 groups
In-Reply-To: <Yd2jcfXqqKHK/NaG@archlinux-ax161>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com> <Yd2jcfXqqKHK/NaG@archlinux-ax161>
Message-ID: <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>

On 11.01.2022 16:34, Nathan Chancellor wrote:
> On Thu, Dec 16, 2021 at 05:22:06PM +0100, Rafa? Mi?ecki wrote:
>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>
>> Generic code doesn't modify those strings and .get_function_groups
>> callback has that extra "const" as well. This allows more flexibility in
>> GENERIC_PINMUX_FUNCTIONS users.
>>
>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>> ---
>>   drivers/pinctrl/pinmux.c | 2 +-
>>   drivers/pinctrl/pinmux.h | 4 ++--
>>   2 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
>> index 6cdbd9ccf2f0..f94d43b082d9 100644
>> --- a/drivers/pinctrl/pinmux.c
>> +++ b/drivers/pinctrl/pinmux.c
>> @@ -875,7 +875,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
>>    */
>>   int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>>   				const char *name,
>> -				const char **groups,
>> +				const char * const *groups,
>>   				const unsigned int num_groups,
>>   				void *data)
>>   {
>> diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
>> index 78c3a31be882..72fcf03eaa43 100644
>> --- a/drivers/pinctrl/pinmux.h
>> +++ b/drivers/pinctrl/pinmux.h
>> @@ -129,7 +129,7 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot,
>>    */
>>   struct function_desc {
>>   	const char *name;
>> -	const char **group_names;
>> +	const char * const *group_names;
>>   	int num_group_names;
>>   	void *data;
>>   };
>> @@ -150,7 +150,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
>>   
>>   int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>>   				const char *name,
>> -				const char **groups,
>> +				const char * const *groups,
>>   				unsigned const num_groups,
>>   				void *data);
>>   
>> -- 
>> 2.31.1
>>
>>
> 
> I have not seen this reported yet, even though it has been broken for a
> couple of weeks now. I see the following error in -next:
> 
> $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig drivers/pinctrl/pinctrl-thunderbay.o
> drivers/pinctrl/pinctrl-thunderbay.c: In function ?thunderbay_add_functions?:
> drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]
>    815 |                         grp = func->group_names;
>        |                             ^
> cc1: all warnings being treated as errors
> 
> Looks like something like the third patch of the series is needed for
> the Thunderbay driver, which it appears was in development at the same
> time as this series.

Correct, this driver didn't exist in Linus's tree when I developed my changes.

Too bad thunderbay copies that old & complex logic that I just fixed in the keembay driver. I'll have to redo my changes for the thunderbay now.

I don't agree with the idea of reverting my patchset and working on V3 though. It's a relatively simple thing we need to fix, it just be just a follow-up commit.


From boger at wirenboard.com  Tue Jan 11 08:51:52 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:51:52 +0300
Subject: [PATCH v2 0/1] fix USB host in HS mode on Allwinner H3 and newer
Message-ID: <20220111165153.63632-1-boger@wirenboard.com>

This patch makes USB host work reliably in HS mode on Allwinner A40i (R40)
and some other SoCs by fixing the way the internal PHY registers are
written.

Changes in v2:
  As suggested by Andre, I've added the detailed description of the nature
  of the issue. Appart from commit message, nothing is changed compared to
  v1.

Evgeny Boger (1):
  phy: sun4i-usb: fix phy write on H3 and newer

 drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

-- 
2.25.1


From boger at wirenboard.com  Tue Jan 11 08:51:53 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:51:53 +0300
Subject: [PATCH v2 1/1] phy: sun4i-usb: fix phy write on H3 and newer
In-Reply-To: <20220111165153.63632-1-boger@wirenboard.com>
References: <20220111165153.63632-1-boger@wirenboard.com>
Message-ID: <20220111165153.63632-2-boger@wirenboard.com>

We noticed that USB hosts won't reliably enumerate USB HS (480Mb/s) devices
in our custom A40i-based design. What we observe is that after several
attempts USB device would fail to enumerate on EHCI port (HS) and will be
enumerated instead on OHCI (FS, 12Mb/s) only:

[    6.368009] usb 1-1: new high-speed USB device number 5 using ehci-platform
[    6.818008] usb 1-1: device not accepting address 5, error -71
[    6.823868] usb usb1-port1: unable to enumerate USB device
[    7.308013] usb 3-1: new full-speed USB device number 2 using ohci-platform
[    7.575045] usb 3-1: not running at top speed; connect to a high speed hub

On some boards one of the ports would work in high-speed mode, but
on most of the boards all three USB ports would only work in FS mode.

At the same time, USB work flawlessly in high-speed mode in vendor kernel.

Looking for the differences in USB code, we found the issue with USB PHY
register initialization. Basically, USB PHY driver sets a couple of
internal undocumented PHY registers to the predefined constants. These PHY
registers are accessed in a very (and I mean VERY) weird way by shifting
register addresses and values bit-by-bit. This access method was slightly
changed starting from H3 SoC, according to the BSP source for different
SoCs.

As a result, mainline PHY driver won't set these PHY registers properly
resulting in unreliable enumeration in high-speed mode.

We don't know whether this issue will result in broken HS mode on all
affected SoCs or instead the A40i is an unfortunate exception. What we
indeed verified, is that BSPs for all affected SoCs write these registers
properly while mainline kernel don't. We also were able to reproduce the
USB issue on a couple of A40i boards from other vendors, so we are pretty
sure these registers have to always be properly set, regardlress of
a hardware layout.

The proposed patch is tested on A40i-based Wiren Board 7 building
automation controller. More details are below.

On older SoCs (prior to H3) PHY register are accessed by manipulating
the common register for all PHYs. PHY index is specified by pulsing
usbc bit.

Newer SoCs leave the access procedure mostly unchanged, the
difference being that the latch registers are separate for each PHY.

Additionally, accessing USB PHY registers is only possible if phy0 is
routed to musb IP instead of HCI.

Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.

On A83t, H6, H616, T507 and probably on more recent hardware,
these PHY registers are not used in vendor BSP.
So don't set v2 flag for these even newer SoCs as a precaution.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
index 788dd5cdbb7d..cf10e385f199 100644
--- a/drivers/phy/allwinner/phy-sun4i-usb.c
+++ b/drivers/phy/allwinner/phy-sun4i-usb.c
@@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
 	bool dedicated_clocks;
 	bool enable_pmu_unk1;
 	bool phy0_dual_route;
+	bool phy_reg_access_v2;
 	int missing_phys;
 };
 
@@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 				int len)
 {
 	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
-	u32 temp, usbc_bit = BIT(phy->index * 2);
+	u32 otgctl_val, temp, usbc_bit;
 	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
+	void __iomem *phyctl_latch;
 	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&phy_data->reg_lock, flags);
 
+	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
+	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
+	 * Newer SoCs leave the access procedure mostly unchanged, the difference
+	 * being that the latch registers are separate for each PHY.
+	 */
+	if (phy_data->cfg->phy_reg_access_v2) {
+		if (phy->index == 0)
+			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
+		else
+			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
+		usbc_bit = 1;
+
+		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
+		 * As it's not clear whether is this related to actual PHY
+		 * routing or rather the hardware is just reusing the same bit,
+		 * don't check phy0_dual_route here.
+		 */
+		otgctl_val = readl(phy_data->base + REG_PHY_OTGCTL);
+		writel(otgctl_val | OTGCTL_ROUTE_MUSB, phy_data->base + REG_PHY_OTGCTL);
+	} else {
+		phyctl_latch = phyctl;
+		usbc_bit = BIT(phy->index * 2);
+	}
+
 	if (phy_data->cfg->phyctl_offset == REG_PHYCTL_A33) {
 		/* SoCs newer than A33 need us to set phyctl to 0 explicitly */
 		writel(0, phyctl);
@@ -224,17 +250,21 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
 		writeb(temp, phyctl);
 
 		/* pulse usbc_bit */
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp |= usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
-		temp = readb(phyctl);
+		temp = readb(phyctl_latch);
 		temp &= ~usbc_bit;
-		writeb(temp, phyctl);
+		writeb(temp, phyctl_latch);
 
 		data >>= 1;
 	}
 
+	/* Restore PHY routing and the rest of OTGCTL */
+	if (phy_data->cfg->phy_reg_access_v2)
+		writel(otgctl_val, phy_data->base + REG_PHY_OTGCTL);
+
 	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
 }
 
@@ -927,6 +957,7 @@ static const struct sun4i_usb_phy_cfg sun8i_h3_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
@@ -937,6 +968,7 @@ static const struct sun4i_usb_phy_cfg sun8i_r40_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
@@ -947,6 +979,7 @@ static const struct sun4i_usb_phy_cfg sun8i_v3s_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
@@ -957,6 +990,7 @@ static const struct sun4i_usb_phy_cfg sun50i_a64_cfg = {
 	.dedicated_clocks = true,
 	.enable_pmu_unk1 = true,
 	.phy0_dual_route = true,
+	.phy_reg_access_v2 = true,
 };
 
 static const struct sun4i_usb_phy_cfg sun50i_h6_cfg = {
-- 
2.25.1



From boger at wirenboard.com  Tue Jan 11 08:58:48 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Tue, 11 Jan 2022 19:58:48 +0300
Subject: [PATCH v2 2/3] can: sun4i_can: add support for R40 CAN controller
In-Reply-To: <20220111162422.62d0ceb0@donnerap.cambridge.arm.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
 <20220111155709.56501-3-boger@wirenboard.com>
 <20220111162422.62d0ceb0@donnerap.cambridge.arm.com>
Message-ID: <e6b51670-1e08-abff-8bb8-b920e68ec118@wirenboard.com>

11.01.2022 19:24, Andre Przywara ?????:
> On Tue, 11 Jan 2022 18:57:08 +0300
> Evgeny Boger <boger at wirenboard.com> wrote:
>
> Hi,
>
>> Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
>> controller is the same as in earlier A10 and A20 SoCs, but needs reset
>> line to be deasserted before use.
>>
>> This patch adds a new compatible for R40 CAN controller. Depending
>> on the compatible, reset line can be requested from DT.
>>
>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
>> ---
>>   drivers/net/can/sun4i_can.c | 61 ++++++++++++++++++++++++++++++++++++-
>>   1 file changed, 60 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
>> index 54aa7c25c4de..24a61326915e 100644
>> --- a/drivers/net/can/sun4i_can.c
>> +++ b/drivers/net/can/sun4i_can.c
>> @@ -61,6 +61,7 @@
>>   #include <linux/of.h>
>>   #include <linux/of_device.h>
>>   #include <linux/platform_device.h>
>> +#include <linux/reset.h>
>>   
>>   #define DRV_NAME "sun4i_can"
>>   
>> @@ -200,10 +201,20 @@
>>   #define SUN4I_CAN_MAX_IRQ	20
>>   #define SUN4I_MODE_MAX_RETRIES	100
>>   
>> +/**
>> + * struct sun4ican_quirks - Differences between SoC variants.
>> + *
>> + * @has_reset: SoC needs reset deasserted.
>> + */
>> +struct sun4ican_quirks {
>> +	bool		has_reset;
>> +};
>> +
>>   struct sun4ican_priv {
>>   	struct can_priv can;
>>   	void __iomem *base;
>>   	struct clk *clk;
>> +	struct reset_control *reset;
>>   	spinlock_t cmdreg_lock;	/* lock for concurrent cmd register writes */
>>   };
>>   
>> @@ -702,6 +713,13 @@ static int sun4ican_open(struct net_device *dev)
>>   		goto exit_irq;
>>   	}
>>   
>> +	/* software reset deassert */
>> +	err = reset_control_deassert(priv->reset);
>> +	if (err) {
>> +		netdev_err(dev, "could not deassert CAN reset\n");
>> +		goto exit_soft_reset;
>> +	}
>> +
>>   	/* turn on clocking for CAN peripheral block */
>>   	err = clk_prepare_enable(priv->clk);
>>   	if (err) {
>> @@ -723,6 +741,8 @@ static int sun4ican_open(struct net_device *dev)
>>   exit_can_start:
>>   	clk_disable_unprepare(priv->clk);
>>   exit_clock:
>> +	reset_control_assert(priv->reset);
>> +exit_soft_reset:
>>   	free_irq(dev->irq, dev);
>>   exit_irq:
>>   	close_candev(dev);
>> @@ -736,6 +756,7 @@ static int sun4ican_close(struct net_device *dev)
>>   	netif_stop_queue(dev);
>>   	sun4i_can_stop(dev);
>>   	clk_disable_unprepare(priv->clk);
>> +	reset_control_assert(priv->reset);
>>   
>>   	free_irq(dev->irq, dev);
>>   	close_candev(dev);
>> @@ -750,8 +771,27 @@ static const struct net_device_ops sun4ican_netdev_ops = {
>>   	.ndo_start_xmit = sun4ican_start_xmit,
>>   };
>>   
>> +static const struct sun4ican_quirks sun4ican_quirks_a10 = {
>> +	.has_reset = false,
>> +};
>> +
>> +static const struct sun4ican_quirks sun4ican_quirks_r40 = {
>> +	.has_reset = true,
>> +};
>> +
>>   static const struct of_device_id sun4ican_of_match[] = {
>> -	{.compatible = "allwinner,sun4i-a10-can"},
>> +	{
>> +		.compatible = "allwinner,sun4i-a10-can",
>> +		.data = &sun4ican_quirks_a10
>> +	},
>> +	{
>> +		.compatible = "allwinner,sun7i-a20-can",
>> +		.data = &sun4ican_quirks_a10
>> +	},
> This one looks unnecessary, the binding says that it must be paired with
> the A10 fallback.
> We should only add an A20 compatible match if there is really a reason,
> otherwise it encourages people to produce DTs with *only* the A20
> compatible (violating the binding).

Right, thank you! Since this series has been around for a couple of 
months already,
and changes in v2 are trivial, would it make sense to submit v3 right away?


> Cheers,
> Andre
>
>> +	{
>> +		.compatible = "allwinner,sun8i-r40-can",
>> +		.data = &sun4ican_quirks_r40
>> +	},
>>   	{},
>>   };
>>   
>> @@ -771,10 +811,28 @@ static int sun4ican_probe(struct platform_device *pdev)
>>   {
>>   	struct device_node *np = pdev->dev.of_node;
>>   	struct clk *clk;
>> +	struct reset_control *reset = NULL;
>>   	void __iomem *addr;
>>   	int err, irq;
>>   	struct net_device *dev;
>>   	struct sun4ican_priv *priv;
>> +	const struct sun4ican_quirks *quirks;
>> +
>> +	quirks = of_device_get_match_data(&pdev->dev);
>> +	if (!quirks) {
>> +		dev_err(&pdev->dev, "failed to determine the quirks to use\n");
>> +		err = -ENODEV;
>> +		goto exit;
>> +	}
>> +
>> +	if (quirks->has_reset) {
>> +		reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
>> +		if (IS_ERR(reset)) {
>> +			dev_err(&pdev->dev, "unable to request reset\n");
>> +			err = PTR_ERR(reset);
>> +			goto exit;
>> +		}
>> +	}
>>   
>>   	clk = of_clk_get(np, 0);
>>   	if (IS_ERR(clk)) {
>> @@ -818,6 +876,7 @@ static int sun4ican_probe(struct platform_device *pdev)
>>   				       CAN_CTRLMODE_3_SAMPLES;
>>   	priv->base = addr;
>>   	priv->clk = clk;
>> +	priv->reset = reset;
>>   	spin_lock_init(&priv->cmdreg_lock);
>>   
>>   	platform_set_drvdata(pdev, dev);



From Eugen.Hristev at microchip.com  Tue Jan 11 09:00:28 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Tue, 11 Jan 2022 17:00:28 +0000
Subject: [PATCH v3 12/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <20220111165132.g62ykrjjk3jh4eyd@uno.localdomain>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-13-eugen.hristev@microchip.com>
 <20220111160603.qi4kbp6rn45hp7po@uno.localdomain>
 <e089d9f3-d07b-1e61-f59b-a695912b6558@microchip.com>
 <20220111165132.g62ykrjjk3jh4eyd@uno.localdomain>
Message-ID: <7a05c500-b46d-e7c9-25d6-f787c01352bf@microchip.com>

On 1/11/22 6:51 PM, Jacopo Mondi wrote:
> On Tue, Jan 11, 2022 at 04:30:15PM +0000, Eugen.Hristev at microchip.com wrote:
>> On 1/11/22 6:06 PM, Jacopo Mondi wrote:
>>> Hi Eugen,
>>>
>>> On Mon, Dec 13, 2021 at 03:49:29PM +0200, Eugen Hristev wrote:
>>>> Implement the support for media-controller.
>>>> This means that the capabilities of the driver have changed and now
>>>> it also advertises the IO_MC .
>>>> The driver will register it's media device, and add the video entity to this
>>>> media device. The subdevices are registered to the same media device.
>>>> The ISC will have a base entity which is auto-detected as atmel_isc_base.
>>>> It will also register a subdevice that allows cropping of the incoming frame
>>>> to the maximum frame size supported by the ISC.
>>>> The ISC will create a link between the subdevice that is asynchronously
>>>> registered and the atmel_isc_scaler entity.
>>>> Then, the atmel_isc_scaler and atmel_isc_base are connected through another
>>>> link.
>>>>
>>>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>>>> ---
>>>> Changes in v2:
>>>> - implement try formats
>>>>
>>>>    drivers/media/platform/atmel/Makefile         |   2 +-
>>>>    drivers/media/platform/atmel/atmel-isc-base.c |  27 +-
>>>>    drivers/media/platform/atmel/atmel-isc-mc.c   | 287 ++++++++++++++++++
>>>>    drivers/media/platform/atmel/atmel-isc.h      |  36 +++
>>>>    .../media/platform/atmel/atmel-sama5d2-isc.c  |  14 +-
>>>>    .../media/platform/atmel/atmel-sama7g5-isc.c  |  12 +-
>>>>    6 files changed, 370 insertions(+), 8 deletions(-)
>>>>    create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
>>>>
>>>> diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
>>>> index 794e8f739287..aa7a18b428f6 100644
>>>> --- a/drivers/media/platform/atmel/Makefile
>>>> +++ b/drivers/media/platform/atmel/Makefile
>>>> @@ -1,7 +1,7 @@
>>>>    # SPDX-License-Identifier: GPL-2.0-only
>>>>    atmel-isc-objs = atmel-sama5d2-isc.o
>>>>    atmel-xisc-objs = atmel-sama7g5-isc.o
>>>> -atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
>>>> +atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o atmel-isc-mc.o
>>>>
>>>>    obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
>>>>    obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
>>>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>>>> index d0542b97a391..b0c3ed21f372 100644
>>>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>>>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>>>> @@ -1726,6 +1726,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>>>>                                               struct isc_device, v4l2_dev);
>>>>         struct isc_subdev_entity *subdev_entity =
>>>>                 container_of(notifier, struct isc_subdev_entity, notifier);
>>>> +     int pad;
>>>>
>>>>         if (video_is_registered(&isc->video_dev)) {
>>>>                 v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
>>>> @@ -1734,6 +1735,16 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
>>>>
>>>>         subdev_entity->sd = subdev;
>>>>
>>>> +     pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
>>>> +                                       MEDIA_PAD_FL_SOURCE);
>>>> +     if (pad < 0) {
>>>> +             v4l2_err(&isc->v4l2_dev, "failed to find pad for %s\n",
>>>> +                      subdev->name);
>>>> +             return pad;
>>>> +     }
>>>> +
>>>> +     isc->remote_pad = pad;
>>>> +
>>>>         return 0;
>>>>    }
>>>>
>>>> @@ -1748,8 +1759,8 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
>>>>         v4l2_ctrl_handler_free(&isc->ctrls.handler);
>>>>    }
>>>>
>>>> -static struct isc_format *find_format_by_code(struct isc_device *isc,
>>>> -                                           unsigned int code, int *index)
>>>> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
>>>> +                                        unsigned int code, int *index)
>>>>    {
>>>>         struct isc_format *fmt = &isc->formats_list[0];
>>>>         unsigned int i;
>>>> @@ -1765,6 +1776,7 @@ static struct isc_format *find_format_by_code(struct isc_device *isc,
>>>>
>>>>         return NULL;
>>>>    }
>>>> +EXPORT_SYMBOL_GPL(isc_find_format_by_code);
>>>>
>>>>    static int isc_formats_init(struct isc_device *isc)
>>>>    {
>>>> @@ -1781,7 +1793,7 @@ static int isc_formats_init(struct isc_device *isc)
>>>>                NULL, &mbus_code)) {
>>>>                 mbus_code.index++;
>>>>
>>>> -             fmt = find_format_by_code(isc, mbus_code.code, &i);
>>>> +             fmt = isc_find_format_by_code(isc, mbus_code.code, &i);
>>>>                 if (!fmt) {
>>>>                         v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
>>>>                                   mbus_code.code);
>>>> @@ -1909,7 +1921,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>>>         vdev->queue             = q;
>>>>         vdev->lock              = &isc->lock;
>>>>         vdev->ctrl_handler      = &isc->ctrls.handler;
>>>> -     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
>>>> +     vdev->device_caps       = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
>>>> +                               V4L2_CAP_IO_MC;
>>>>         video_set_drvdata(vdev, isc);
>>>>
>>>>         ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
>>>> @@ -1919,8 +1932,14 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>>>                 goto isc_async_complete_err;
>>>>         }
>>>>
>>>> +     ret = isc_mc_register(isc);
>>>> +     if (ret < 0)
>>>> +             goto isc_async_complete_unregister_device;
>>>>         return 0;
>>>>
>>>> +isc_async_complete_unregister_device:
>>>> +     video_unregister_device(vdev);
>>>> +
>>>>    isc_async_complete_err:
>>>>         mutex_destroy(&isc->lock);
>>>>         return ret;
>>>> diff --git a/drivers/media/platform/atmel/atmel-isc-mc.c b/drivers/media/platform/atmel/atmel-isc-mc.c
>>>> new file mode 100644
>>>> index 000000000000..2aea81d77b2f
>>>> --- /dev/null
>>>> +++ b/drivers/media/platform/atmel/atmel-isc-mc.c
>>>> @@ -0,0 +1,287 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Microchip Image Sensor Controller (ISC) Media Controller support
>>>> + *
>>>> + * Copyright (C) 2021 Microchip Technology, Inc.
>>>> + *
>>>> + * Author: Eugen Hristev <eugen.hristev at microchip.com>
>>>> + *
>>>> + */
>>>> +
>>>> +#include <media/v4l2-device.h>
>>>> +#include <media/v4l2-subdev.h>
>>>
>>> Should you include <media/media-entity.h> and <media/media-device.h> ?
>>
>> Hi Jacopo,
>>
>> They are probably being included from another header. I will add them.
>>
> 
> Thank you :)
> 
>>>
>>> Also, should you select MEDIA_CONTROLLER and V4L2_SUBDEV_API for all
>>> the Kconfig symbols ?
>>
>>
>> VIDEO_ATMEL_ISC directly selects:
>> select MEDIA_CONTROLLER
>> select VIDEO_V4L2_SUBDEV_API
>>
>> and VIDEO_ATMEL_XISC
>> depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API
> 
> And selects VIDEO_ATMEL_ISC_BASE so it's fine!
> 
> VIDEO_ATMEL_ISI does not. I'm fine if this is intended, I might have
> got lost in the several pieces this driver is composed of :)

The ISI is a totally different driver with no code shared with the ISC.
It's a different hardware, on some older platforms.
It does not support media controller and will not in the near future.

Initially there was ISI, then ISC appeared and a new driver was created. 
Then a newer version of the ISC appeared named XISC, but a lot was 
common with the old ISC, so I created a new driver XISC with shared 
common base with the old ISC.
So now we have ISI, and ISC/XISC who share ATMEL_ISC_BASE

> 
>>
>> and VIDEO_V4L2_SUBDEV_API depends on MEDIA_CONTROLLER
>>
>>>
>>>> +
>>>> +#include "atmel-isc-regs.h"
>>>> +#include "atmel-isc.h"
>>>> +
>>>> +static const struct media_device_ops isc_media_ops = {
>>>> +};
>>>
>>> Do you need this even if it's empty ?
>>>
>>
>> Not sure. I can remove it and pass NULL, but I haven't checked what the
>> subsystem is doing if there is no ops. I will try.
>>
> 
> Seems like it is safe as the core checks for if (mdev->ops) before
> accessing it (except for mc-request for which operations are
> mandatory)
> 
>>>> +
>>>> +static int isc_scaler_get_fmt(struct v4l2_subdev *sd,
>>>> +                           struct v4l2_subdev_state *sd_state,
>>>> +                           struct v4l2_subdev_format *format)
>>>> +{
>>>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>>>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
>>>> +
>>>> +     if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
>>>> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
>>>> +                                                       format->pad);
>>>> +             format->format = *v4l2_try_fmt;
>>>> +
>>>> +             return 0;
>>>> +     }
>>>> +
>>>> +     format->format = isc->scaler_format;
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +
>>>> +static int isc_scaler_set_fmt(struct v4l2_subdev *sd,
>>>> +                           struct v4l2_subdev_state *sd_state,
>>>> +                           struct v4l2_subdev_format *req_fmt)
>>>> +{
>>>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>>>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt;
>>>> +     struct isc_format *fmt;
>>>> +     unsigned int i;
>>>> +
>>>> +     if (req_fmt->pad == ISC_SCALER_PAD_SOURCE)
>>>> +             v4l_bound_align_image
>>>> +                     (&req_fmt->format.width, 16, isc->max_width, 0,
>>>> +                      &req_fmt->format.height, 16, isc->max_height, 0, 0);
>>>> +     else
>>>> +             v4l_bound_align_image
>>>> +                     (&req_fmt->format.width, 16, 10000, 0,
>>>> +                      &req_fmt->format.height, 16, 10000, 0, 0);
>>>> +
>>>> +     req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
>>>> +     req_fmt->format.field = V4L2_FIELD_NONE;
>>>> +     req_fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
>>>> +     req_fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
>>>> +     req_fmt->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
>>>> +
>>>> +     fmt = isc_find_format_by_code(isc, req_fmt->format.code, &i);
>>>> +
>>>> +     if (!fmt)
>>>> +             fmt = &isc->formats_list[0];
>>>> +
>>>> +     req_fmt->format.code = fmt->mbus_code;
>>>> +
>>>> +     if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
>>>> +             v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
>>>> +                                                       req_fmt->pad);
>>>> +             *v4l2_try_fmt = req_fmt->format;
>>>> +             /* Trying on the pad sink makes the source sink change too */
>>>> +             if (req_fmt->pad == ISC_SCALER_PAD_SINK) {
>>>> +                     v4l2_try_fmt =
>>>> +                             v4l2_subdev_get_try_format(sd, sd_state,
>>>> +                                                        ISC_SCALER_PAD_SOURCE);
>>>> +                     *v4l2_try_fmt = req_fmt->format;
>>>> +
>>>> +                     v4l_bound_align_image(&v4l2_try_fmt->width,
>>>> +                                           16, isc->max_width, 0,
>>>> +                                           &v4l2_try_fmt->height,
>>>> +                                           16, isc->max_height, 0, 0);
>>>> +             }
>>>> +             /* if we are just trying, we are done */
>>>> +             return 0;
>>>> +     }
>>>> +
>>>> +     isc->scaler_format = req_fmt->format;
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +
>>>> +static int isc_scaler_enum_mbus_code(struct v4l2_subdev *sd,
>>>> +                                  struct v4l2_subdev_state *sd_state,
>>>> +                                  struct v4l2_subdev_mbus_code_enum *code)
>>>> +{
>>>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>>>> +     int supported_index = 0;
>>>> +     int i;
>>>> +
>>>> +     for (i = 0; i < isc->formats_list_size; i++) {
>>>> +             if (!isc->formats_list[i].sd_support)
>>>> +                     continue;
>>>> +             if (supported_index == code->index) {
>>>> +                     code->code = isc->formats_list[i].mbus_code;
>>>> +                     return 0;
>>>> +             }
>>>> +             supported_index++;
>>>> +     }
>>>> +
>>>> +     return -EINVAL;
>>>> +}
>>>> +
>>>> +static int isc_scaler_g_sel(struct v4l2_subdev *sd,
>>>> +                         struct v4l2_subdev_state *sd_state,
>>>> +                         struct v4l2_subdev_selection *sel)
>>>> +{
>>>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>>>> +
>>>> +     if (sel->pad == ISC_SCALER_PAD_SOURCE)
>>>> +             return -EINVAL;
>>>> +
>>>> +     if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS &&
>>>> +         sel->target != V4L2_SEL_TGT_CROP)
>>>> +             return -EINVAL;
>>>> +
>>>> +     sel->r.height = isc->max_height;
>>>> +     sel->r.width = isc->max_width;
>>>> +
>>>> +     sel->r.left = 0;
>>>> +     sel->r.top = 0;
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +
>>>> +static int isc_scaler_init_cfg(struct v4l2_subdev *sd,
>>>> +                            struct v4l2_subdev_state *sd_state)
>>>> +{
>>>> +     struct v4l2_mbus_framefmt *v4l2_try_fmt =
>>>> +             v4l2_subdev_get_try_format(sd, sd_state, 0);
>>>> +     struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
>>>> +
>>>> +     *v4l2_try_fmt = isc->scaler_format;
>>>> +
>>>> +     return 0;
>>>> +}
>>>> +
>>>> +static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
>>>> +     .enum_mbus_code = isc_scaler_enum_mbus_code,
>>>> +     .set_fmt = isc_scaler_set_fmt,
>>>> +     .get_fmt = isc_scaler_get_fmt,
>>>> +     .get_selection = isc_scaler_g_sel,
>>>> +     .init_cfg = isc_scaler_init_cfg,
>>>> +};
>>>> +
>>>> +static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
>>>> +     .pad = &isc_scaler_pad_ops,
>>>> +};
>>>> +
>>>> +static int isc_init_own_sd(struct isc_device *isc)
>>>> +{
>>>> +     int ret;
>>>> +
>>>> +     v4l2_subdev_init(&isc->scaler_sd, &xisc_scaler_subdev_ops);
>>>> +
>>>> +     isc->scaler_sd.owner = THIS_MODULE;
>>>> +     isc->scaler_sd.dev = isc->dev;
>>>> +     snprintf(isc->scaler_sd.name, sizeof(isc->scaler_sd.name),
>>>> +              "atmel_isc_scaler");
>>>> +
>>>> +     isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>>>> +     isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
>>>> +     isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>>>> +     isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
>>>> +
>>>> +     isc->scaler_format.height = isc->max_height;
>>>> +     isc->scaler_format.width = isc->max_width;
>>>> +     isc->scaler_format.code = isc->formats_list[0].mbus_code;
>>>> +     isc->scaler_format.colorspace = V4L2_COLORSPACE_SRGB;
>>>> +     isc->scaler_format.field = V4L2_FIELD_NONE;
>>>> +     isc->scaler_format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
>>>> +     isc->scaler_format.quantization = V4L2_QUANTIZATION_DEFAULT;
>>>> +     isc->scaler_format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
>>>> +
>>>> +     ret = media_entity_pads_init(&isc->scaler_sd.entity,
>>>> +                                  ISC_SCALER_PADS_NUM,
>>>> +                                  isc->scaler_pads);
>>>> +     if (ret < 0) {
>>>> +             dev_err(isc->dev, "scaler sd media entity init failed\n");
>>>> +             return ret;
>>>> +     }
>>>> +     ret = v4l2_device_register_subdev(&isc->v4l2_dev, &isc->scaler_sd);
>>>> +     if (ret < 0) {
>>>> +             dev_err(isc->dev, "scaler sd failed to register subdev\n");
>>>> +             return ret;
>>>> +     }
>>>> +
>>>> +     return ret;
>>>> +}
>>>> +
>>>> +int isc_mc_init(struct isc_device *isc, u32 ver)
>>>> +{
>>>> +     const struct of_device_id *match;
>>>> +     int ret;
>>>> +
>>>> +     isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
>>>> +     isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
>>>> +     isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
>>>> +
>>>> +     ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
>>>> +                                  isc->pads);
>>>> +     if (ret < 0) {
>>>> +             dev_err(isc->dev, "media entity init failed\n");
>>>> +             return ret;
>>>> +     }
>>>> +
>>>> +     isc->mdev.dev = isc->dev;
>>>> +     isc->mdev.ops = &isc_media_ops;
>>>> +
>>>> +     match = of_match_node(isc->dev->driver->of_match_table,
>>>> +                           isc->dev->of_node);
>>>> +
>>>> +     strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
>>>> +             sizeof(isc->mdev.driver_name));
>>>> +     strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
>>>> +     snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
>>>> +              isc->v4l2_dev.name);
>>>> +     isc->mdev.hw_revision = ver;
>>>> +
>>>> +     media_device_init(&isc->mdev);
>>>> +
>>>> +     isc->v4l2_dev.mdev = &isc->mdev;
>>>> +
>>>> +     return isc_init_own_sd(isc);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(isc_mc_init);
>>>> +
>>>> +int isc_mc_register(struct isc_device *isc)
>>>> +{
>>>> +     int ret;
>>>> +
>>>> +     ret = media_create_pad_link(&isc->current_subdev->sd->entity,
>>>> +                                 isc->remote_pad, &isc->scaler_sd.entity,
>>>> +                                 ISC_SCALER_PAD_SINK,
>>>> +                                 MEDIA_LNK_FL_ENABLED |
>>>> +                                 MEDIA_LNK_FL_IMMUTABLE);
>>>> +
>>>> +     if (ret < 0) {
>>>> +             v4l2_err(&isc->v4l2_dev,
>>>> +                      "Failed to create pad link: %s to %s\n",
>>>> +                      isc->current_subdev->sd->entity.name,
>>>> +                      isc->scaler_sd.entity.name);
>>>> +             return ret;
>>>> +     }
>>>> +
>>>> +     dev_dbg(isc->dev, "link with %s pad: %d\n",
>>>> +             isc->current_subdev->sd->name, isc->remote_pad);
>>>> +
>>>> +     ret = media_create_pad_link(&isc->scaler_sd.entity,
>>>> +                                 ISC_SCALER_PAD_SOURCE,
>>>> +                                 &isc->video_dev.entity, ISC_PAD_SINK,
>>>> +                                 MEDIA_LNK_FL_ENABLED |
>>>> +                                 MEDIA_LNK_FL_IMMUTABLE);
>>>> +
>>>> +     if (ret < 0) {
>>>> +             v4l2_err(&isc->v4l2_dev,
>>>> +                      "Failed to create pad link: %s to %s\n",
>>>> +                      isc->scaler_sd.entity.name,
>>>> +                      isc->video_dev.entity.name);
>>>> +             return ret;
>>>> +     }
>>>> +
>>>> +     dev_dbg(isc->dev, "link with %s pad: %d\n", isc->scaler_sd.name,
>>>> +             ISC_SCALER_PAD_SOURCE);
>>>> +
>>>> +     return media_device_register(&isc->mdev);
>>>
>>> I feel like the isc-base driver shold instead register the
>>> media-controller and this file shuld actually be only about
>>> isc-scaler or something. I might be missing why it is not possible
>>> though. It doesn't seem to me that mc support is conditional, so it
>>> can happen in the base driver directly ?
>>
>> This actually is the base driver. Just that the atmel-isc-base.c is
>> pretty crowded. So I moved the MC part in this file. But it's the same
>> base driver.
>>
> 
> I understand. isc-base is pretty big, you're right.
> However breaking mc apart in a file that mixes registering an entity
> for the scaler and initializing mc for the whole driver feels weird,
> at least to me, as I don't immediately get why the mc part is handled
> by the scaler file...
> 
>>>
>>> Links creation can still happen at async_complete() (I would have
>>> suggested _bound() time, but you have no asyn subdev for the scaler,
>>> so I guess the only async subdev here is the sensor).
>>
>> Yes, the sensor or any kind of subdevice (XISC normally is connected to
>> a bridge, ISC to a sensor directly )
>>
>>>
>>> All in all: can this function be removed and:
>>> 1) Base driver registers the media controller device in probe
>>
>> Should we register the media device even if it's not operational ? and
>> no video device has been registered ?
>> I thought it would be safer to have it registered with all the
>> links/entities/etc once the video node has been completed.
>>
>> But if you say this is the proper way, I can do that.
>> I wanted to keep things separated and not overcrowd the base file /probe
>> function, but if it's just a media_device_register call, I can do it there.
> 
> You are right. Calling media_device_register() at async_complete time
> is the right thing to do.
> 
> Thanks
>     j
> 
> 
>>
>>> 2) links are created at async_complete time ?
>>
>> That works too. I think I could move them there.
>>
>> Thanks for reviewing,
>>
>> Eugen
>>
>>>
>>> Thanks
>>>      j
>>>
>>>
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(isc_mc_register);
>>>> +
>>>> +void isc_mc_cleanup(struct isc_device *isc)
>>>> +{
>>>> +     media_entity_cleanup(&isc->video_dev.entity);
>>>> +}
>>>> +EXPORT_SYMBOL_GPL(isc_mc_cleanup);
>>>> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
>>>> index 07fa6dbf8460..0b6370d7775f 100644
>>>> --- a/drivers/media/platform/atmel/atmel-isc.h
>>>> +++ b/drivers/media/platform/atmel/atmel-isc.h
>>>> @@ -183,6 +183,17 @@ struct isc_reg_offsets {
>>>>         u32 his_entry;
>>>>    };
>>>>
>>>> +enum isc_mc_pads {
>>>> +     ISC_PAD_SINK    = 0,
>>>> +     ISC_PADS_NUM    = 1,
>>>> +};
>>>> +
>>>> +enum isc_scaler_pads {
>>>> +     ISC_SCALER_PAD_SINK     = 0,
>>>> +     ISC_SCALER_PAD_SOURCE   = 1,
>>>> +     ISC_SCALER_PADS_NUM     = 2,
>>>> +};
>>>> +
>>>>    /*
>>>>     * struct isc_device - ISC device driver data/config struct
>>>>     * @regmap:          Register map
>>>> @@ -258,6 +269,12 @@ struct isc_reg_offsets {
>>>>     *                   be used as an input to the controller
>>>>     * @controller_formats_size: size of controller_formats array
>>>>     * @formats_list_size:       size of formats_list array
>>>> + * @pads:            media controller pads for isc video entity
>>>> + * @mdev:            media device that is registered by the isc
>>>> + * @remote_pad:              remote pad on the connected subdevice
>>>> + * @scaler_sd:               subdevice for the scaler that isc registers
>>>> + * @scaler_pads:     media controller pads for the scaler subdevice
>>>> + * @scaler_format:   current format for the scaler subdevice
>>>>     */
>>>>    struct isc_device {
>>>>         struct regmap           *regmap;
>>>> @@ -346,6 +363,19 @@ struct isc_device {
>>>>         struct isc_format               *formats_list;
>>>>         u32                             controller_formats_size;
>>>>         u32                             formats_list_size;
>>>> +
>>>> +     struct {
>>>> +             struct media_pad                pads[ISC_PADS_NUM];
>>>> +             struct media_device             mdev;
>>>> +
>>>> +             u32                             remote_pad;
>>>> +     };
>>>> +
>>>> +     struct {
>>>> +             struct v4l2_subdev              scaler_sd;
>>>> +             struct media_pad                scaler_pads[ISC_SCALER_PADS_NUM];
>>>> +             struct v4l2_mbus_framefmt       scaler_format;
>>>> +     };
>>>>    };
>>>>
>>>>    extern const struct regmap_config isc_regmap_config;
>>>> @@ -357,4 +387,10 @@ int isc_clk_init(struct isc_device *isc);
>>>>    void isc_subdev_cleanup(struct isc_device *isc);
>>>>    void isc_clk_cleanup(struct isc_device *isc);
>>>>
>>>> +int isc_mc_init(struct isc_device *isc, u32 ver);
>>>> +int isc_mc_register(struct isc_device *isc);
>>>> +void isc_mc_cleanup(struct isc_device *isc);
>>>> +
>>>> +struct isc_format *isc_find_format_by_code(struct isc_device *isc,
>>>> +                                        unsigned int code, int *index);
>>>>    #endif
>>>> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>>>> index 1b2063cce0f7..a3e4c32a66c4 100644
>>>> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>>>> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
>>>> @@ -529,6 +529,12 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>>>                         break;
>>>>         }
>>>>
>>>> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>>> +
>>>> +     ret = isc_mc_init(isc, ver);
>>>> +     if (ret < 0)
>>>> +             goto isc_probe_mc_init_err;
>>>> +
>>>>         pm_runtime_set_active(dev);
>>>>         pm_runtime_enable(dev);
>>>>         pm_request_idle(dev);
>>>> @@ -538,7 +544,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>>>         ret = clk_prepare_enable(isc->ispck);
>>>>         if (ret) {
>>>>                 dev_err(dev, "failed to enable ispck: %d\n", ret);
>>>> -             goto cleanup_subdev;
>>>> +             goto isc_probe_mc_init_err;
>>>>         }
>>>>
>>>>         /* ispck should be greater or equal to hclock */
>>>> @@ -548,7 +554,6 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>>>                 goto unprepare_clk;
>>>>         }
>>>>
>>>> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>>>         dev_info(dev, "Microchip ISC version %x\n", ver);
>>>>
>>>>         return 0;
>>>> @@ -556,6 +561,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
>>>>    unprepare_clk:
>>>>         clk_disable_unprepare(isc->ispck);
>>>>
>>>> +isc_probe_mc_init_err:
>>>> +     isc_mc_cleanup(isc);
>>>> +
>>>>    cleanup_subdev:
>>>>         isc_subdev_cleanup(isc);
>>>>
>>>> @@ -576,6 +584,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
>>>>
>>>>         pm_runtime_disable(&pdev->dev);
>>>>
>>>> +     isc_mc_cleanup(isc);
>>>> +
>>>>         isc_subdev_cleanup(isc);
>>>>
>>>>         v4l2_device_unregister(&isc->v4l2_dev);
>>>> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>>>> index 2b1082295c13..d2ac80b1ccc3 100644
>>>> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>>>> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
>>>> @@ -523,15 +523,23 @@ static int microchip_xisc_probe(struct platform_device *pdev)
>>>>                         break;
>>>>         }
>>>>
>>>> +     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>>> +
>>>> +     ret = isc_mc_init(isc, ver);
>>>> +     if (ret < 0)
>>>> +             goto isc_probe_mc_init_err;
>>>> +
>>>>         pm_runtime_set_active(dev);
>>>>         pm_runtime_enable(dev);
>>>>         pm_request_idle(dev);
>>>>
>>>> -     regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
>>>>         dev_info(dev, "Microchip XISC version %x\n", ver);
>>>>
>>>>         return 0;
>>>>
>>>> +isc_probe_mc_init_err:
>>>> +     isc_mc_cleanup(isc);
>>>> +
>>>>    cleanup_subdev:
>>>>         isc_subdev_cleanup(isc);
>>>>
>>>> @@ -552,6 +560,8 @@ static int microchip_xisc_remove(struct platform_device *pdev)
>>>>
>>>>         pm_runtime_disable(&pdev->dev);
>>>>
>>>> +     isc_mc_cleanup(isc);
>>>> +
>>>>         isc_subdev_cleanup(isc);
>>>>
>>>>         v4l2_device_unregister(&isc->v4l2_dev);
>>>> --
>>>> 2.25.1
>>>>
>>


From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:06:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:06:15 +0100
Subject: [PATCH 3/5] regulator: dt-bindings: maxim, max77843: add MAX77843
 bindings
In-Reply-To: <YdRrWGry08M+h2IZ@robh.at.kernel.org>
References: <20211229124631.21576-1-krzysztof.kozlowski@canonical.com>
 <20211229124631.21576-4-krzysztof.kozlowski@canonical.com>
 <YdRrWGry08M+h2IZ@robh.at.kernel.org>
Message-ID: <dd6caaeb-f395-2109-b1a3-6076f8c41ad0@canonical.com>

On 04/01/2022 16:44, Rob Herring wrote:
> On Wed, Dec 29, 2021 at 01:46:29PM +0100, Krzysztof Kozlowski wrote:
>> Document the bindings for MAX77843 regulator driver.  The bindings are
>> almost identical to MAX77693 bindings, except the actual names of
>> regulators.
> 
> Same issues here as your other Maxim regulator conversions.
> 

Thanks, all comments (also from extcon and mfd) applied.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:19:50 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:19:50 +0100
Subject: [PATCH 4/4] dt-bindings: mfd: maxim, max14577: convert to dtschema
In-Reply-To: <YdyMiHcyKNHipYCE@robh.at.kernel.org>
References: <20211229141524.34174-1-krzysztof.kozlowski@canonical.com>
 <20211229141524.34174-5-krzysztof.kozlowski@canonical.com>
 <YdyMiHcyKNHipYCE@robh.at.kernel.org>
Message-ID: <64649172-e32c-2d1a-9c12-aed562071876@canonical.com>

On 10/01/2022 20:44, Rob Herring wrote:
> On Wed, Dec 29, 2021 at 03:15:24PM +0100, Krzysztof Kozlowski wrote:
>> Convert the MFD part of Maxim MAX14577/MAX77836 MUIC to DT schema
>> format.  The example DTS was copied from existing DTS
>> (exynos3250-rinato.dts), so keep the license as GPL-2.0-only.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../devicetree/bindings/mfd/max14577.txt      | 147 -------------
>>  .../bindings/mfd/maxim,max14577.yaml          | 195 ++++++++++++++++++
>>  MAINTAINERS                                   |   2 +-
>>  3 files changed, 196 insertions(+), 148 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt
>>  create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/max14577.txt b/Documentation/devicetree/bindings/mfd/max14577.txt
>> deleted file mode 100644
>> index be11943a0560..000000000000
>> --- a/Documentation/devicetree/bindings/mfd/max14577.txt
>> +++ /dev/null
>> @@ -1,147 +0,0 @@
>> -Maxim MAX14577/77836 Multi-Function Device
>> -
>> -MAX14577 is a Multi-Function Device with Micro-USB Interface Circuit, Li+
>> -Battery Charger and SFOUT LDO output for powering USB devices. It is
>> -interfaced to host controller using I2C.
>> -
>> -MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
>> -For the description of Fuel Gauge low SOC alert interrupt see:
>> -../power/supply/max17040_battery.txt
>> -
>> -
>> -Required properties:
>> -- compatible : Must be "maxim,max14577" or "maxim,max77836".
>> -- reg : I2C slave address for the max14577 chip (0x25 for max14577/max77836)
>> -- interrupts : IRQ line for the chip.
>> -
>> -
>> -Required nodes:
>> - - charger :
>> -	Node for configuring the charger driver.
>> -	Required properties:
>> -		- compatible : "maxim,max14577-charger"
>> -			or "maxim,max77836-charger"
>> -		- maxim,fast-charge-uamp : Current in uA for Fast Charge;
>> -			Valid values:
>> -			- for max14577: 90000 - 950000;
>> -			- for max77836: 45000 - 475000;
>> -		- maxim,eoc-uamp : Current in uA for End-Of-Charge mode;
>> -			Valid values:
>> -			- for max14577: 50000 - 200000;
>> -			- for max77836: 5000 - 100000;
>> -		- maxim,ovp-uvolt : OverVoltage Protection Threshold in uV;
>> -			In an overvoltage condition, INT asserts and charging
>> -			stops. Valid values:
>> -			- 6000000, 6500000, 7000000, 7500000;
>> -		- maxim,constant-uvolt : Battery Constant Voltage in uV;
>> -			Valid values:
>> -			- 4000000 - 4280000 (step by 20000);
>> -			- 4350000;
>> -
>> -
>> -Optional nodes:
>> -- max14577-muic/max77836-muic :
>> -	Node used only by extcon consumers.
>> -	Required properties:
>> -		- compatible : "maxim,max14577-muic" or "maxim,max77836-muic"
>> -
>> -- regulators :
>> -	Required properties:
>> -		- compatible : "maxim,max14577-regulator"
>> -			or "maxim,max77836-regulator"
>> -
>> -	May contain a sub-node per regulator from the list below. Each
>> -	sub-node should contain the constraints and initialization information
>> -	for that regulator. See regulator.txt for a description of standard
>> -	properties for these sub-nodes.
>> -
>> -	List of valid regulator names:
>> -	- for max14577: CHARGER, SAFEOUT.
>> -	- for max77836: CHARGER, SAFEOUT, LDO1, LDO2.
>> -
>> -	The SAFEOUT is a fixed voltage regulator so there is no need to specify
>> -	voltages for it.
>> -
>> -
>> -Example:
>> -
>> -#include <dt-bindings/interrupt-controller/irq.h>
>> -
>> -max14577 at 25 {
>> -	compatible = "maxim,max14577";
>> -	reg = <0x25>;
>> -	interrupt-parent = <&gpx1>;
>> -	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
>> -
>> -	muic: max14577-muic {
>> -		compatible = "maxim,max14577-muic";
>> -	};
>> -
>> -	regulators {
>> -		compatible = "maxim,max14577-regulator";
>> -
>> -		SAFEOUT {
>> -			regulator-name = "SAFEOUT";
>> -		};
>> -		CHARGER {
>> -			regulator-name = "CHARGER";
>> -			regulator-min-microamp = <90000>;
>> -			regulator-max-microamp = <950000>;
>> -			regulator-boot-on;
>> -		};
>> -	};
>> -
>> -	charger {
>> -		compatible = "maxim,max14577-charger";
>> -
>> -		maxim,constant-uvolt = <4350000>;
>> -		maxim,fast-charge-uamp = <450000>;
>> -		maxim,eoc-uamp = <50000>;
>> -		maxim,ovp-uvolt = <6500000>;
>> -	};
>> -};
>> -
>> -
>> -max77836 at 25 {
>> -	compatible = "maxim,max77836";
>> -	reg = <0x25>;
>> -	interrupt-parent = <&gpx1>;
>> -	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
>> -
>> -	muic: max77836-muic {
>> -		compatible = "maxim,max77836-muic";
>> -	};
>> -
>> -	regulators {
>> -		compatible = "maxim,max77836-regulator";
>> -
>> -		SAFEOUT {
>> -			regulator-name = "SAFEOUT";
>> -		};
>> -		CHARGER {
>> -			regulator-name = "CHARGER";
>> -			regulator-min-microamp = <90000>;
>> -			regulator-max-microamp = <950000>;
>> -			regulator-boot-on;
>> -		};
>> -		LDO1 {
>> -			regulator-name = "LDO1";
>> -			regulator-min-microvolt = <2700000>;
>> -			regulator-max-microvolt = <2700000>;
>> -		};
>> -		LDO2 {
>> -			regulator-name = "LDO2";
>> -			regulator-min-microvolt = <800000>;
>> -			regulator-max-microvolt = <3950000>;
>> -		};
>> -	};
>> -
>> -	charger {
>> -		compatible = "maxim,max77836-charger";
>> -
>> -		maxim,constant-uvolt = <4350000>;
>> -		maxim,fast-charge-uamp = <225000>;
>> -		maxim,eoc-uamp = <7500>;
>> -		maxim,ovp-uvolt = <6500000>;
>> -	};
>> -};
>> diff --git a/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
>> new file mode 100644
>> index 000000000000..512fd671595c
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
>> @@ -0,0 +1,195 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/mfd/maxim,max14577.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description: |
>> +  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
>> +  Integrated Circuit (MUIC).
>> +
>> +  The Maxim MAX14577 is a MicroUSB and Companion Power Management IC which
>> +  includes voltage safeout regulators, charger and MicroUSB management IC.
>> +
>> +  The Maxim MAX77836 is a MicroUSB and Companion Power Management IC which
>> +  includes voltage safeout and LDO regulators, charger, fuel-gauge and MicroUSB
>> +  management IC.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - maxim,max14577
>> +      - maxim,max77836
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +  wakeup-source: true
>> +
>> +  charger:
>> +    $ref: ../power/supply/maxim,max14577.yaml
> 
> /schemas/power/...
> 
> With those fixed,
> 
> Reviewed-by: Rob Herring <robh at kernel.org>

Thanks, fixed also regulator reference below and the regulator bindings
as in my other Maxim patches.


Best regards,
Krzysztof


From pierre-louis.bossart at linux.intel.com  Tue Jan 11 09:02:03 2022
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Tue, 11 Jan 2022 11:02:03 -0600
Subject: [PATCH] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220111071011.5964-1-allen-kh.cheng@mediatek.com>
References: <20220111071011.5964-1-allen-kh.cheng@mediatek.com>
Message-ID: <91eef4c9-adda-1921-16b5-af181b30d36e@linux.intel.com>


> +int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
> +{
> +	struct mtk_adsp_chan *dsp_chan;
> +	int ret;
> +
> +	if (idx >= MTK_ADSP_MBOX_NUM)
> +		return -EINVAL;
> +
> +	dsp_chan = &ipc->chans[idx];
> +	ret = mbox_send_message(dsp_chan->ch, &msg);
> +	if (ret < 0)
> +		return ret;
> +
> +	return 0;

this can be simplified a bit without the 'ret' variable

return mbox_send_message(dsp_chan->ch, &msg);

> +}
> +EXPORT_SYMBOL(mtk_adsp_ipc_send);


> +static int mtk_adsp_ipc_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_adsp_ipc *dsp_ipc;
> +	struct mtk_adsp_chan *dsp_chan;
> +	struct mbox_client *cl;
> +	char *chan_name;
> +	int ret;
> +	int i, j;
> +
> +	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
> +
> +	dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
> +	if (!dsp_ipc)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
> +		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
> +		if (!chan_name) {
> +			ret = -ENOMEM;
> +			goto out;
> +		}

in this case with the existing code you will free something that was not
allocated. It's not super elegant, consider using different labels as
suggested below.

> +
> +		dsp_chan = &dsp_ipc->chans[i];
> +		cl = &dsp_chan->cl;
> +		cl->dev = dev->parent;
> +		cl->tx_block = false;
> +		cl->knows_txdone = false;
> +		cl->tx_prepare = NULL;
> +		cl->rx_callback = mtk_adsp_ipc_recv;
> +
> +		dsp_chan->ipc = dsp_ipc;
> +		dsp_chan->idx = i;
> +		dsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
> +		if (IS_ERR(dsp_chan->ch)) {
> +			ret = PTR_ERR(dsp_chan->ch);
> +			if (ret != -EPROBE_DEFER)
> +				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
> +					i, ret);
> +			goto out;

goto out_free;

> +		}
> +
> +		dev_dbg(dev, "request mbox chan %s\n", chan_name);
> +		kfree(chan_name);
> +	}
> +
> +	dsp_ipc->dev = dev;
> +	dev_set_drvdata(dev, dsp_ipc);
> +	dev_dbg(dev, "MTK ADSP IPC initialized\n");
> +
> +	return 0;
> +
> +out:

out_free:
> +	kfree(chan_name);

out:

> +	for (j = 0; j < i; j++) {
> +		dsp_chan = &dsp_ipc->chans[j];
> +		mbox_free_channel(dsp_chan->ch);
> +	}
> +
> +	return ret;
> +}
> +
> +static int mtk_adsp_ipc_remove(struct platform_device *pdev)
> +{
> +	struct mtk_adsp_ipc *dsp_ipc = dev_get_drvdata(&pdev->dev);
> +	struct mtk_adsp_chan *dsp_chan;
> +	int i;
> +
> +	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
> +		dsp_chan = &dsp_ipc->chans[i];
> +		mbox_free_channel(dsp_chan->ch);
> +	}
> +
> +	return 0;
> +}
> +
> +static struct platform_driver mtk_adsp_ipc_driver = {
> +	.driver = {
> +		.name = "mtk-adsp-ipc",
> +	},
> +	.probe = mtk_adsp_ipc_probe,
> +	.remove = mtk_adsp_ipc_remove,
> +};
> +builtin_platform_driver(mtk_adsp_ipc_driver);
> +
> +MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
> +MODULE_DESCRIPTION("MTK ADSP IPC Driver");
> +MODULE_LICENSE("GPL v2");

the v2 here isn't useful, the license information can be found in the
SPDX line.

MODULE_LICENSE("GPL");




From palmer at dabbelt.com  Tue Jan 11 09:29:30 2022
From: palmer at dabbelt.com (Palmer Dabbelt)
Date: Tue, 11 Jan 2022 09:29:30 -0800 (PST)
Subject: [PATCH v2 2/5] riscv: mm: init: use IS_ENABLED(CONFIG_KEXEC_CORE)
 instead of #ifdef
In-Reply-To: <20211206160514.2000-3-jszhang@kernel.org>
Message-ID: <mhng-ef554c87-32d1-443f-805d-3f74b88cd1f0@palmer-ri-x1c9>

On Mon, 06 Dec 2021 08:05:11 PST (-0800), jszhang at kernel.org wrote:
> Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> and increase compile coverage.
>
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> ---
>  arch/riscv/mm/init.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index a15640eeb334..84879a5ce818 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -748,7 +748,6 @@ static inline void setup_vm_final(void)
>  }
>  #endif /* CONFIG_MMU */
>
> -#ifdef CONFIG_KEXEC_CORE
>  /*
>   * reserve_crashkernel() - reserves memory for crash kernel
>   *
> @@ -765,6 +764,8 @@ static void __init reserve_crashkernel(void)
>
>  	int ret = 0;
>
> +	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
> +		return;
>  	/*
>  	 * Don't reserve a region for a crash kernel on a crash kernel
>  	 * since it doesn't make much sense and we have limited memory
> @@ -805,7 +806,6 @@ static void __init reserve_crashkernel(void)
>  	crashk_res.start = crash_base;
>  	crashk_res.end = crash_base + crash_size - 1;
>  }
> -#endif /* CONFIG_KEXEC_CORE */
>
>  void __init paging_init(void)
>  {
> @@ -819,9 +819,7 @@ void __init misc_mem_init(void)
>  	arch_numa_init();
>  	sparse_init();
>  	zone_sizes_init();
> -#ifdef CONFIG_KEXEC_CORE
>  	reserve_crashkernel();
> -#endif
>  	memblock_dump_all();
>  }

Acked-by: Palmer Dabbelt <palmer at rivosinc.com>

LMK if you wanted me to take this through the RISC-V tree, otherwise I'm 
going to assume all these are going in together.

Thanks!


From seanjc at google.com  Tue Jan 11 09:36:25 2022
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 11 Jan 2022 17:36:25 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
Message-ID: <Yd3AGRtkBgWSmGf2@google.com>

On Mon, Jan 10, 2022, Raghavendra Rao Ananta wrote:
> On Fri, Jan 7, 2022 at 5:06 PM Sean Christopherson <seanjc at google.com> wrote:
> >
> > On Tue, Jan 04, 2022, Raghavendra Rao Ananta wrote:
> > > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> >
> > Needs parantheses around (kvm), but why bother with a macro?  This is the same
> > header that defines struct kvm.
> >
> No specific reason for creating a macro as such. I can remove it if it
> feels noisy.

Please do.  In the future, don't use a macro unless there's a good reason to do
so.  Don't get me wrong, I love abusing macros, but for things like this they are
completely inferior to

  static inline bool kvm_vm_has_started(struct kvm *kvm)
  {
  	return kvm->vm_started;
  }

because a helper function gives us type safety, doesn't suffer from concatenation
of tokens potentially doing weird things, is easier to extend to a multi-line
implementation, etc...

An example of when it's ok to use a macro is x86's

  #define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0)

which uses a macro instead of a proper function to avoid a circular dependency
due to arch/x86/include/asm/kvm_host.h being included by include/linux/kvm_host.h
and thus x86's implementation of kvm_arch_vcpu_memslots_id() coming before the
definition of struct kvm_vcpu.  But that's very much an exception and done only
because the alternatives suck more.

> > > +                      */
> > > +                     mutex_lock(&kvm->lock);
> >
> > This adds unnecessary lock contention when running vCPUs.  The naive solution
> > would be:
> >                         if (!kvm->vm_started) {
> >                                 ...
> >                         }
> >
> Not sure if I understood the solution..

In your proposed patch, KVM_RUN will take kvm->lock _every_ time.  That introduces
unnecessary contention as it will serialize this bit of code if multiple vCPUs
are attempting KVM_RUN.  By checking !vm_started, only the "first" KVM_RUN for a
VM will acquire kvm->lock and thus avoid contention once the VM is up and running.
There's still a possibility that multiple vCPUs will contend for kvm->lock on their
first KVM_RUN, hence the quotes.  I called it "naive" because it's possible there's
a more elegant solution depending on the use case, e.g. a lockless approach might
work (or it might not).

> > > +                     kvm->vm_started = true;
> > > +                     mutex_unlock(&kvm->lock);
> >
> > Lastly, why is this in generic KVM?
> >
> The v1 of the series originally had it in the arm specific code.
> However, I was suggested to move it to the generic code since the book
> keeping is not arch specific and could be helpful to others too [1].

I'm definitely in favor of moving/adding thing to generic KVM when it makes sense,
but I'm skeptical in this particular case.  The code _is_ arch specific in that
arm64 apparently needs to acquire kvm->lock when checking if a vCPU has run, e.g.
versus a hypothetical x86 use case that might be completely ok with a lockless
implementation.  And it's not obvious that there's a plausible, safe use case
outside of arm64, e.g. on x86, there is very, very little that is truly shared
across the entire VM/system, most things are per-thread/core/package in some way,
shape, or form.  In other words, I'm a wary of providing something like this for
x86 because odds are good that any use will be functionally incorrect.


From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:43:34 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:43:34 +0100
Subject: [PATCH v2 1/4] ARM: dts: exynos: Align MAX77836 nodes with dtschema
 on Monk and Rinato
In-Reply-To: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174337.223320-2-krzysztof.kozlowski@canonical.com>

The newly introduced dtschema for MAX77836 MUIC requires proper naming
of extcon child node.

This should not have actual impact on MFD children driver binding,
because the max77836 MFD driver uses compatibles.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos3250-monk.dts   | 2 +-
 arch/arm/boot/dts/exynos3250-rinato.dts | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-monk.dts b/arch/arm/boot/dts/exynos3250-monk.dts
index 8b41a9d5e2db..02a9dc479d34 100644
--- a/arch/arm/boot/dts/exynos3250-monk.dts
+++ b/arch/arm/boot/dts/exynos3250-monk.dts
@@ -69,7 +69,7 @@ max77836: pmic at 25 {
 			reg = <0x25>;
 			wakeup-source;
 
-			muic: max77836-muic {
+			extcon {
 				compatible = "maxim,max77836-muic";
 			};
 
diff --git a/arch/arm/boot/dts/exynos3250-rinato.dts b/arch/arm/boot/dts/exynos3250-rinato.dts
index 5f7f8fedfb92..6d2c7bb19184 100644
--- a/arch/arm/boot/dts/exynos3250-rinato.dts
+++ b/arch/arm/boot/dts/exynos3250-rinato.dts
@@ -70,7 +70,7 @@ max77836: pmic at 25 {
 			reg = <0x25>;
 			wakeup-source;
 
-			muic: max77836-muic {
+			extcon {
 				compatible = "maxim,max77836-muic";
 			};
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:43:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:43:33 +0100
Subject: [PATCH v2 0/4] mfd/power/regulators: dt-bindings: max14577: convert
 to dtschema
Message-ID: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v1
================
1. MFD: Use absolute path to schemas
2. Regulator: mention all allowed properties,
   additionalProperties=false, add min/max values for voltages and
   current, don't use patternProperties when not needed.

Dependencies
============
1. DTS patch 1/4: nothing depends on it, sending here so Rob's automatic
   checker won't complain about DTS.
   I will take it via Samsung SoC tree.

2. Final MFD patch (4/4) depends on regulator and power, so the last
   patches (2+3+4) should go via same tree.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  ARM: dts: exynos: Align MAX77836 nodes with dtschema on Monk and
    Rinato
  dt-bindings: power: supply: maxim,max14577: convert to dtschema
  regulator: dt-bindings: maxim,max14577: convert to dtschema
  dt-bindings: mfd: maxim,max14577: convert to dtschema

 .../devicetree/bindings/mfd/max14577.txt      | 147 -------------
 .../bindings/mfd/maxim,max14577.yaml          | 195 ++++++++++++++++++
 .../bindings/power/supply/maxim,max14577.yaml |  84 ++++++++
 .../bindings/regulator/maxim,max14577.yaml    |  92 +++++++++
 MAINTAINERS                                   |   3 +-
 arch/arm/boot/dts/exynos3250-monk.dts         |   2 +-
 arch/arm/boot/dts/exynos3250-rinato.dts       |   2 +-
 7 files changed, 375 insertions(+), 150 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
 create mode 100644 Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
 create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max14577.yaml

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:43:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:43:35 +0100
Subject: [PATCH v2 2/4] dt-bindings: power: supply: maxim,
 max14577: convert to dtschema
In-Reply-To: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174337.223320-3-krzysztof.kozlowski@canonical.com>

Convert the Charger bindings of Maxim MAX14577/MAX77836 MUIC to DT
schema format.  The existing bindings were defined in
../bindings/mfd/max14577.txt.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/power/supply/maxim,max14577.yaml | 84 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml

diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
new file mode 100644
index 000000000000..3978b48299de
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/supply/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC Charger
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+  Integrated Circuit (MUIC).
+
+  See also Documentation/devicetree/bindings/mfd/maxim,max14577.yaml for
+  additional information and example.
+
+properties:
+  compatible:
+    enum:
+      - maxim,max14577-charger
+      - maxim,max77836-charger
+
+  maxim,constant-uvolt:
+    description:
+      Battery Constant Voltage in uV
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 4000000
+    maximum: 4350000
+
+  maxim,eoc-uamp:
+    description: |
+      Current in uA for End-Of-Charge mode.
+      MAX14577: 50000-20000
+      MAX77836: 5000-100000
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  maxim,fast-charge-uamp:
+    description: |
+      Current in uA for Fast Charge
+      MAX14577: 90000-950000
+      MAX77836: 45000-475000
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  maxim,ovp-uvolt:
+    description:
+      OverVoltage Protection Threshold in uV; In an overvoltage condition, INT
+      asserts and charging stops.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [6000000, 6500000, 7000000, 7500000]
+
+required:
+  - compatible
+  - maxim,constant-uvolt
+  - maxim,eoc-uamp
+  - maxim,fast-charge-uamp
+  - maxim,ovp-uvolt
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: maxim,max14577-charger
+    then:
+      properties:
+        maxim,eoc-uamp:
+          minimum: 50000
+          maximum: 200000
+        maxim,fast-charge-uamp:
+          minimum: 90000
+          maximum: 950000
+    else:
+      # max77836
+      properties:
+        maxim,eoc-uamp:
+          minimum: 5000
+          maximum: 100000
+        maxim,fast-charge-uamp:
+          minimum: 45000
+          maximum: 475000
+
+additionalProperties: false
diff --git a/MAINTAINERS b/MAINTAINERS
index d1f8f312f322..13e21c229c5d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11681,6 +11681,7 @@ M:	Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
 M:	Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
 L:	linux-pm at vger.kernel.org
 S:	Supported
+F:	Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
 F:	Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
 F:	drivers/power/supply/max14577_charger.c
 F:	drivers/power/supply/max77693_charger.c
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:43:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:43:36 +0100
Subject: [PATCH v2 3/4] regulator: dt-bindings: maxim,
 max14577: convert to dtschema
In-Reply-To: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174337.223320-4-krzysztof.kozlowski@canonical.com>

Convert the regulator bindings of Maxim MAX14577/MAX77835 MUIC to DT
schema format.  The existing bindings were defined in
../bindings/mfd/max14577.txt.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/regulator/maxim,max14577.yaml    | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max14577.yaml

diff --git a/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml b/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml
new file mode 100644
index 000000000000..4212f10644a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max14577.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC regulators
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+  Integrated Circuit (MUIC).
+
+  See also Documentation/devicetree/bindings/mfd/maxim,max14577.yaml for
+  additional information and example.
+
+properties:
+  compatible:
+    enum:
+      - maxim,max14577-regulator
+      - maxim,max77836-regulator
+
+  CHARGER:
+    type: object
+    $ref: regulator.yaml#
+    additionalProperties: false
+    description: |
+      Current regulator.
+
+    properties:
+      regulator-name: true
+      regulator-always-on: true
+      regulator-boot-on: true
+      regulator-min-microamp: true
+      regulator-max-microamp: true
+
+    required:
+      - regulator-name
+
+  SAFEOUT:
+    type: object
+    $ref: regulator.yaml#
+    additionalProperties: false
+    description: |
+      Safeout LDO regulator (fixed voltage).
+
+    properties:
+      regulator-name: true
+      regulator-always-on: true
+      regulator-boot-on: true
+      regulator-min-microvolt:
+        const: 4900000
+      regulator-max-microvolt:
+        const: 4900000
+
+    required:
+      - regulator-name
+
+patternProperties:
+  "^LDO[12]$":
+    type: object
+    $ref: regulator.yaml#
+    additionalProperties: false
+    description: |
+      Current regulator.
+
+    properties:
+      regulator-name: true
+      regulator-always-on: true
+      regulator-boot-on: true
+      regulator-min-microvolt:
+        minimum: 800000
+      regulator-max-microvolt:
+        maximum: 3950000
+
+    required:
+      - regulator-name
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: maxim,max14577-regulator
+    then:
+      properties:
+        LDO1: false
+        LDO2: false
+
+additionalProperties: false
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:43:37 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:43:37 +0100
Subject: [PATCH v2 4/4] dt-bindings: mfd: maxim,max14577: convert to dtschema
In-Reply-To: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174337.223320-5-krzysztof.kozlowski@canonical.com>

Convert the MFD part of Maxim MAX14577/MAX77836 MUIC to DT schema
format.  The example DTS was copied from existing DTS
(exynos3250-rinato.dts), so keep the license as GPL-2.0-only.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/mfd/max14577.txt      | 147 -------------
 .../bindings/mfd/maxim,max14577.yaml          | 195 ++++++++++++++++++
 MAINTAINERS                                   |   2 +-
 3 files changed, 196 insertions(+), 148 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mfd/max14577.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max14577.yaml

diff --git a/Documentation/devicetree/bindings/mfd/max14577.txt b/Documentation/devicetree/bindings/mfd/max14577.txt
deleted file mode 100644
index be11943a0560..000000000000
--- a/Documentation/devicetree/bindings/mfd/max14577.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-Maxim MAX14577/77836 Multi-Function Device
-
-MAX14577 is a Multi-Function Device with Micro-USB Interface Circuit, Li+
-Battery Charger and SFOUT LDO output for powering USB devices. It is
-interfaced to host controller using I2C.
-
-MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
-For the description of Fuel Gauge low SOC alert interrupt see:
-../power/supply/max17040_battery.txt
-
-
-Required properties:
-- compatible : Must be "maxim,max14577" or "maxim,max77836".
-- reg : I2C slave address for the max14577 chip (0x25 for max14577/max77836)
-- interrupts : IRQ line for the chip.
-
-
-Required nodes:
- - charger :
-	Node for configuring the charger driver.
-	Required properties:
-		- compatible : "maxim,max14577-charger"
-			or "maxim,max77836-charger"
-		- maxim,fast-charge-uamp : Current in uA for Fast Charge;
-			Valid values:
-			- for max14577: 90000 - 950000;
-			- for max77836: 45000 - 475000;
-		- maxim,eoc-uamp : Current in uA for End-Of-Charge mode;
-			Valid values:
-			- for max14577: 50000 - 200000;
-			- for max77836: 5000 - 100000;
-		- maxim,ovp-uvolt : OverVoltage Protection Threshold in uV;
-			In an overvoltage condition, INT asserts and charging
-			stops. Valid values:
-			- 6000000, 6500000, 7000000, 7500000;
-		- maxim,constant-uvolt : Battery Constant Voltage in uV;
-			Valid values:
-			- 4000000 - 4280000 (step by 20000);
-			- 4350000;
-
-
-Optional nodes:
-- max14577-muic/max77836-muic :
-	Node used only by extcon consumers.
-	Required properties:
-		- compatible : "maxim,max14577-muic" or "maxim,max77836-muic"
-
-- regulators :
-	Required properties:
-		- compatible : "maxim,max14577-regulator"
-			or "maxim,max77836-regulator"
-
-	May contain a sub-node per regulator from the list below. Each
-	sub-node should contain the constraints and initialization information
-	for that regulator. See regulator.txt for a description of standard
-	properties for these sub-nodes.
-
-	List of valid regulator names:
-	- for max14577: CHARGER, SAFEOUT.
-	- for max77836: CHARGER, SAFEOUT, LDO1, LDO2.
-
-	The SAFEOUT is a fixed voltage regulator so there is no need to specify
-	voltages for it.
-
-
-Example:
-
-#include <dt-bindings/interrupt-controller/irq.h>
-
-max14577 at 25 {
-	compatible = "maxim,max14577";
-	reg = <0x25>;
-	interrupt-parent = <&gpx1>;
-	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
-
-	muic: max14577-muic {
-		compatible = "maxim,max14577-muic";
-	};
-
-	regulators {
-		compatible = "maxim,max14577-regulator";
-
-		SAFEOUT {
-			regulator-name = "SAFEOUT";
-		};
-		CHARGER {
-			regulator-name = "CHARGER";
-			regulator-min-microamp = <90000>;
-			regulator-max-microamp = <950000>;
-			regulator-boot-on;
-		};
-	};
-
-	charger {
-		compatible = "maxim,max14577-charger";
-
-		maxim,constant-uvolt = <4350000>;
-		maxim,fast-charge-uamp = <450000>;
-		maxim,eoc-uamp = <50000>;
-		maxim,ovp-uvolt = <6500000>;
-	};
-};
-
-
-max77836 at 25 {
-	compatible = "maxim,max77836";
-	reg = <0x25>;
-	interrupt-parent = <&gpx1>;
-	interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
-
-	muic: max77836-muic {
-		compatible = "maxim,max77836-muic";
-	};
-
-	regulators {
-		compatible = "maxim,max77836-regulator";
-
-		SAFEOUT {
-			regulator-name = "SAFEOUT";
-		};
-		CHARGER {
-			regulator-name = "CHARGER";
-			regulator-min-microamp = <90000>;
-			regulator-max-microamp = <950000>;
-			regulator-boot-on;
-		};
-		LDO1 {
-			regulator-name = "LDO1";
-			regulator-min-microvolt = <2700000>;
-			regulator-max-microvolt = <2700000>;
-		};
-		LDO2 {
-			regulator-name = "LDO2";
-			regulator-min-microvolt = <800000>;
-			regulator-max-microvolt = <3950000>;
-		};
-	};
-
-	charger {
-		compatible = "maxim,max77836-charger";
-
-		maxim,constant-uvolt = <4350000>;
-		maxim,fast-charge-uamp = <225000>;
-		maxim,eoc-uamp = <7500>;
-		maxim,ovp-uvolt = <6500000>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
new file mode 100644
index 000000000000..55ab60750798
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max14577.yaml
@@ -0,0 +1,195 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max14577.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
+  Integrated Circuit (MUIC).
+
+  The Maxim MAX14577 is a MicroUSB and Companion Power Management IC which
+  includes voltage safeout regulators, charger and MicroUSB management IC.
+
+  The Maxim MAX77836 is a MicroUSB and Companion Power Management IC which
+  includes voltage safeout and LDO regulators, charger, fuel-gauge and MicroUSB
+  management IC.
+
+properties:
+  compatible:
+    enum:
+      - maxim,max14577
+      - maxim,max77836
+
+  interrupts:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+  wakeup-source: true
+
+  charger:
+    $ref: /schemas/power/supply/maxim,max14577.yaml
+
+  extcon:
+    type: object
+    properties:
+      compatible:
+        enum:
+          - maxim,max14577-muic
+          - maxim,max77836-muic
+
+    required:
+      - compatible
+
+  regulators:
+    $ref: /schemas/regulator/maxim,max14577.yaml
+
+required:
+  - compatible
+  - interrupts
+  - reg
+  - charger
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: maxim,max14577
+    then:
+      properties:
+        charger:
+          properties:
+            compatible:
+              const: maxim,max14577-charger
+        extcon:
+          properties:
+            compatible:
+              const: maxim,max14577-muic
+        regulator:
+          properties:
+            compatible:
+              const: maxim,max14577-regulator
+    else:
+      properties:
+        charger:
+          properties:
+            compatible:
+              const: maxim,max77836-charger
+        extcon:
+          properties:
+            compatible:
+              const: maxim,max77836-muic
+        regulator:
+          properties:
+            compatible:
+              const: maxim,max77836-regulator
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic at 25 {
+            compatible = "maxim,max14577";
+            reg = <0x25>;
+            interrupt-parent = <&gpx1>;
+            interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+            extcon {
+                compatible = "maxim,max14577-muic";
+            };
+
+            regulators {
+                compatible = "maxim,max14577-regulator";
+
+                SAFEOUT {
+                    regulator-name = "SAFEOUT";
+                };
+
+                CHARGER {
+                    regulator-name = "CHARGER";
+                    regulator-min-microamp = <90000>;
+                    regulator-max-microamp = <950000>;
+                    regulator-boot-on;
+                };
+            };
+
+            charger {
+                compatible = "maxim,max14577-charger";
+
+                maxim,constant-uvolt = <4350000>;
+                maxim,fast-charge-uamp = <450000>;
+                maxim,eoc-uamp = <50000>;
+                maxim,ovp-uvolt = <6500000>;
+            };
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic at 25 {
+            compatible = "maxim,max77836";
+            interrupt-parent = <&gpx1>;
+            interrupts = <5 IRQ_TYPE_NONE>;
+            reg = <0x25>;
+            wakeup-source;
+
+            extcon {
+                compatible = "maxim,max77836-muic";
+            };
+
+            regulators {
+                compatible = "maxim,max77836-regulator";
+
+                SAFEOUT {
+                  regulator-name = "SAFEOUT";
+                };
+
+                CHARGER {
+                  regulator-name = "CHARGER";
+                  regulator-min-microamp = <45000>;
+                  regulator-max-microamp = <475000>;
+                  regulator-boot-on;
+                };
+
+                LDO1 {
+                  regulator-name = "MOT_2.7V";
+                  regulator-min-microvolt = <1100000>;
+                  regulator-max-microvolt = <2700000>;
+                };
+
+                LDO2 {
+                  regulator-name = "UNUSED_LDO2";
+                  regulator-min-microvolt = <800000>;
+                  regulator-max-microvolt = <3950000>;
+                };
+            };
+
+            charger {
+                compatible = "maxim,max77836-charger";
+
+                maxim,constant-uvolt = <4350000>;
+                maxim,fast-charge-uamp = <225000>;
+                maxim,eoc-uamp = <7500>;
+                maxim,ovp-uvolt = <6500000>;
+            };
+        };
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 13e21c229c5d..af392bd04874 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11692,11 +11692,11 @@ M:	Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
 M:	Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
 L:	linux-kernel at vger.kernel.org
 S:	Supported
+F:	Documentation/devicetree/bindings/*/maxim,max14577.yaml
 F:	Documentation/devicetree/bindings/*/maxim,max77686.yaml
 F:	Documentation/devicetree/bindings/*/maxim,max77693.yaml
 F:	Documentation/devicetree/bindings/*/maxim,max77843.yaml
 F:	Documentation/devicetree/bindings/clock/maxim,max77686.txt
-F:	Documentation/devicetree/bindings/mfd/max14577.txt
 F:	drivers/*/*max77843.c
 F:	drivers/*/max14577*.c
 F:	drivers/*/max77686*.c
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:00 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:00 +0100
Subject: [PATCH v2 0/5] mfd/extcon/regulators: max77843: add dtschema/bindings
Message-ID: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>

Hi,

The max77843 shares some parts with max77693 but it lacked bindings.  All
its compatibles were undocumented.  Add basic bindings for max77843,
matching existing devicetree.  These are not complete bindings, but
rather reverse-engineered to match current state.

I do not have access to device with MAX77843, so if anyone else
volunteers to be the bindings maintainer, please join.

Changes since v1
================
1. MFD: Use absolute path to schemas.
2. Regulator: mention all allowed properties,
   additionalProperties=false, add min/max values for voltages and
   current, don't use patternProperties when not needed.
3. extcon: Use absolute path to schemas.

Dependencies
============
1. Patch 1/5 (dts): nothing depends on it, sending here so Rob's automatic
   checker won't complain about DTS.
   I will take it via Samsung SoC tree.

2. The patch 4/5 (mfd bindings) depends on regulator and extcon, so they
   should come together (2+3+4+5).

Best regards,
Krzysztof

Krzysztof Kozlowski (5):
  arm64: dts: exynos: Align MAX77843 nodes with dtschema on TM2
  dt-bindings: extcon: maxim,max77843: add MAX77843 bindings
  regulator: dt-bindings: maxim,max77843: add MAX77843 bindings
  dt-bindings: mfd: maxim,max77843: add MAX77843 bindings
  MAINTAINERS: mfd: cover MAX77843 by Maxim PMIC/MUIC for Exynos boards
    entry

 .../bindings/extcon/maxim,max77843.yaml       |  40 +++++
 .../bindings/mfd/maxim,max77843.yaml          | 144 ++++++++++++++++++
 .../bindings/regulator/maxim,max77843.yaml    |  65 ++++++++
 MAINTAINERS                                   |   2 +
 .../dts/exynos/exynos5433-tm2-common.dtsi     |  17 ++-
 5 files changed, 265 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
 create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
 create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77843.yaml

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:01 +0100
Subject: [PATCH v2 1/5] arm64: dts: exynos: Align MAX77843 nodes with dtschema
 on TM2
In-Reply-To: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174805.223732-2-krzysztof.kozlowski@canonical.com>

The newly introduced dtschema for MAX77843 MUIC require the children to
have proper naming and a port at 0 property.

This should not have actual impact on MFD children driver binding,
because the max77843 MFD driver uses compatibles.  The port at 0 is
disabled to avoid any impact.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Please kindly test or even better - fix the DTS and extcon driver.
---
 .../boot/dts/exynos/exynos5433-tm2-common.dtsi  | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
index cbcc01a66aab..03f7c9acaacb 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -858,10 +858,10 @@ pmic at 66 {
 		interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
 		reg = <0x66>;
 
-		muic: max77843-muic {
+		muic: extcon {
 			compatible = "maxim,max77843-muic";
 
-			musb_con: musb-connector {
+			musb_con: connector {
 				compatible = "samsung,usb-connector-11pin",
 					     "usb-b-connector";
 				label = "micro-USB";
@@ -871,6 +871,17 @@ ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
 
+					port at 0 {
+						/*
+						 * TODO: The DTS this is based on does not have
+						 * port at 0 which is a required property. The ports
+						 * look incomplete and need fixing.
+						 * Add a disabled port just to satisfy dtschema.
+						 */
+						reg = <0>;
+						status = "disabled";
+					};
+
 					port at 3 {
 						reg = <3>;
 						musb_con_to_mhl: endpoint {
@@ -910,7 +921,7 @@ charger_reg: CHARGER {
 			};
 		};
 
-		haptic: max77843-haptic {
+		haptic: motor-driver {
 			compatible = "maxim,max77843-haptic";
 			haptic-supply = <&ldo38_reg>;
 			pwms = <&pwm 0 33670 0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:02 +0100
Subject: [PATCH v2 2/5] dt-bindings: extcon: maxim,
 max77843: add MAX77843 bindings
In-Reply-To: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174805.223732-3-krzysztof.kozlowski@canonical.com>

Document the bindings for MAX77843 MUIC/extcon driver, based on
Exynos5433 TM2 devicetree.  These are neither accurate nor finished
bindings but at least allow parsing existing DTS files.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/extcon/maxim,max77843.yaml       | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/extcon/maxim,max77843.yaml

diff --git a/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
new file mode 100644
index 000000000000..f9ffe3d6f957
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/extcon/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC Extcon
+
+maintainers:
+  - Chanwoo Choi <cw00.choi at samsung.com>
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX77843 MicroUSB
+  Integrated Circuit (MUIC).
+
+  See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
+  additional information and example.
+
+properties:
+  compatible:
+    const: maxim,max77843-muic
+
+  connector:
+    $ref: /schemas/connector/usb-connector.yaml#
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      Any connector to the data bus of this controller should be modelled using
+      the OF graph bindings specified
+    properties:
+      port:
+        $ref: /schemas/graph.yaml#/properties/port
+
+required:
+  - compatible
+  - connector
+
+additionalProperties: false
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:03 +0100
Subject: [PATCH v2 3/5] regulator: dt-bindings: maxim,
 max77843: add MAX77843 bindings
In-Reply-To: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174805.223732-4-krzysztof.kozlowski@canonical.com>

Document the bindings for MAX77843 regulator driver.  The bindings are
almost identical to MAX77693 bindings, except the actual names of
regulators.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/regulator/maxim,max77843.yaml    | 65 +++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77843.yaml

diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
new file mode 100644
index 000000000000..a963025e96c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/regulator/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC regulators
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX77843 MicroUSB Integrated
+  Circuit (MUIC).
+
+  See also Documentation/devicetree/bindings/mfd/maxim,max77843.yaml for
+  additional information and example.
+
+properties:
+  compatible:
+    const: maxim,max77843-regulator
+
+  CHARGER:
+    type: object
+    $ref: regulator.yaml#
+    additionalProperties: false
+    description: |
+      Current regulator.
+
+    properties:
+      regulator-name: true
+      regulator-always-on: true
+      regulator-boot-on: true
+      regulator-min-microamp:
+        minimum: 100000
+      regulator-max-microamp:
+        maximum: 3150000
+
+    required:
+      - regulator-name
+
+patternProperties:
+  "^SAFEOUT[12]$":
+    type: object
+    $ref: regulator.yaml#
+    additionalProperties: false
+    description: |
+      Safeout LDO regulator.
+
+    properties:
+      regulator-name: true
+      regulator-always-on: true
+      regulator-boot-on: true
+      regulator-min-microvolt:
+        minimum: 3300000
+      regulator-max-microvolt:
+        maximum: 4950000
+
+    required:
+      - regulator-name
+
+required:
+  - compatible
+
+additionalProperties: false
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:04 +0100
Subject: [PATCH v2 4/5] dt-bindings: mfd: maxim,
 max77843: add MAX77843 bindings
In-Reply-To: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174805.223732-5-krzysztof.kozlowski@canonical.com>

Document the bindings for MAX77843 MFD driver, based on Exynos5433 TM2
devicetree.  These are neither accurate nor finished bindings but at
least allow parsing existing DTS files.

The example DTS was copied from existing DTS
(exynos5433-tm2-common.dtsi), so keep the license as GPL-2.0-only.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/mfd/maxim,max77843.yaml          | 144 ++++++++++++++++++
 1 file changed, 144 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/maxim,max77843.yaml

diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
new file mode 100644
index 000000000000..61a0f9dcb983
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77843.yaml
@@ -0,0 +1,144 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77843.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Maxim MAX77843 MicroUSB and Companion Power Management IC
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  This is a part of device tree bindings for Maxim MAX77843 MicroUSB
+  Integrated Circuit (MUIC).
+
+  The Maxim MAX77843 is a MicroUSB and Companion Power Management IC which
+  includes voltage current regulators, charger, fuel-gauge, haptic motor driver
+  and MicroUSB management IC.
+
+properties:
+  compatible:
+    const: maxim,max77843
+
+  interrupts:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+  extcon:
+    $ref: /schemas/extcon/maxim,max77843.yaml
+
+  motor-driver:
+    type: object
+    properties:
+      compatible:
+        const: maxim,max77843-haptic
+
+      haptic-supply:
+        description: Power supply to the haptic motor
+
+      pwms:
+        maxItems: 1
+
+    required:
+      - compatible
+      - haptic-supply
+      - pwms
+
+  regulators:
+    $ref: /schemas/regulator/maxim,max77843.yaml
+
+required:
+  - compatible
+  - interrupts
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic at 66 {
+            compatible = "maxim,max77843";
+            interrupt-parent = <&gpa1>;
+            interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+            reg = <0x66>;
+
+            extcon {
+                compatible = "maxim,max77843-muic";
+
+                connector {
+                    compatible = "samsung,usb-connector-11pin",
+                                 "usb-b-connector";
+                    label = "micro-USB";
+                    type = "micro";
+
+                    ports {
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+
+                        port at 0 {
+                            /*
+                             * TODO: The DTS this is based on does not have
+                             * port at 0 which is a required property. The ports
+                             * look incomplete and need fixing.
+                             * Add a disabled port just to satisfy dtschema.
+                             */
+                            reg = <0>;
+                            status = "disabled";
+                        };
+
+                        port at 3 {
+                            reg = <3>;
+                            endpoint {
+                                remote-endpoint = <&mhl_to_musb_con>;
+                            };
+                        };
+                    };
+                };
+
+                ports {
+                    port {
+                        endpoint {
+                            remote-endpoint = <&usb_to_muic>;
+                        };
+                    };
+                };
+            };
+
+            regulators {
+                compatible = "maxim,max77843-regulator";
+
+                SAFEOUT1 {
+                    regulator-name = "SAFEOUT1";
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <4950000>;
+                };
+
+                SAFEOUT2 {
+                    regulator-name = "SAFEOUT2";
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <4950000>;
+                };
+
+                CHARGER {
+                    regulator-name = "CHARGER";
+                    regulator-min-microamp = <100000>;
+                    regulator-max-microamp = <3150000>;
+                };
+            };
+
+            motor-driver {
+                compatible = "maxim,max77843-haptic";
+                haptic-supply = <&ldo38_reg>;
+                pwms = <&pwm 0 33670 0>;
+            };
+        };
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 09:48:05 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 18:48:05 +0100
Subject: [PATCH v2 5/5] MAINTAINERS: mfd: cover MAX77843 by Maxim PMIC/MUIC
 for Exynos boards entry
In-Reply-To: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111174805.223732-6-krzysztof.kozlowski@canonical.com>

The MAX77843 is used in Exynos5433-based TM2 boards and shares some
parts of code with MAX77693 (regulator and haptic motor drivers).
Include all MAX77843 drivers in the entry for Maxim PMIC/MUIC drivers
for Exynos boards, so they will receive some dedicated review coverage.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 MAINTAINERS | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e5f2758531bc..d1f8f312f322 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11693,8 +11693,10 @@ L:	linux-kernel at vger.kernel.org
 S:	Supported
 F:	Documentation/devicetree/bindings/*/maxim,max77686.yaml
 F:	Documentation/devicetree/bindings/*/maxim,max77693.yaml
+F:	Documentation/devicetree/bindings/*/maxim,max77843.yaml
 F:	Documentation/devicetree/bindings/clock/maxim,max77686.txt
 F:	Documentation/devicetree/bindings/mfd/max14577.txt
+F:	drivers/*/*max77843.c
 F:	drivers/*/max14577*.c
 F:	drivers/*/max77686*.c
 F:	drivers/*/max77693*.c
-- 
2.32.0



From robh at kernel.org  Tue Jan 11 09:50:01 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 11:50:01 -0600
Subject: [PATCH] dt-bindings: net: stm32-dwmac: Make each example a
 separate entry
In-Reply-To: <20220106182518.1435497-8-robh@kernel.org>
References: <20220106182518.1435497-8-robh@kernel.org>
Message-ID: <Yd3DSb6gJLgIcjxG@robh.at.kernel.org>

On Thu, 06 Jan 2022 12:25:16 -0600, Rob Herring wrote:
> Each independent example should be a separate entry. This allows for
> 'interrupts' to have different cell sizes.
> 
> The first example also has a phandle in 'interrupts', so drop the phandle.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/net/stm32-dwmac.yaml | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 

Applied, thanks!


From robh at kernel.org  Tue Jan 11 09:50:13 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 11:50:13 -0600
Subject: [PATCH] dt-bindings: i2c: st,stm32-i2c: Make each example a
 separate entry
In-Reply-To: <20220106183037.1443931-1-robh@kernel.org>
References: <20220106183037.1443931-1-robh@kernel.org>
Message-ID: <Yd3DVdvmWBT9L6l0@robh.at.kernel.org>

On Thu, 06 Jan 2022 12:30:36 -0600, Rob Herring wrote:
> Each independent example should be a separate entry. This allows for
> 'interrupts' to have different cell sizes.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml | 6 ++++++
>  1 file changed, 6 insertions(+)
> 

Applied, thanks!


From robh at kernel.org  Tue Jan 11 09:51:00 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 11:51:00 -0600
Subject: [PATCH] dt-bindings: net: wireless: mt76: Fix 8-bit property sizes
In-Reply-To: <20220107030419.2380198-1-robh@kernel.org>
References: <20220107030419.2380198-1-robh@kernel.org>
Message-ID: <Yd3DhO7bel0NH5UL@robh.at.kernel.org>

On Thu, 06 Jan 2022 21:04:17 -0600, Rob Herring wrote:
> The '/bits/ 8' notation applies the next <> list of values. Another <> list
> is encoded as 32-bits by default. IOW, each <> list needs to be preceeded
> with '/bits/ 8'.
> 
> While the dts format allows this, as a rule we don't mix sizes for DT
> properties since all size information is lost in the dtb file.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/net/wireless/mediatek,mt76.yaml       | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Tue Jan 11 09:51:46 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 11:51:46 -0600
Subject: [PATCH] dt-bindings: Drop required 'interrupt-parent'
In-Reply-To: <20220107031905.2406176-1-robh@kernel.org>
References: <20220107031905.2406176-1-robh@kernel.org>
Message-ID: <Yd3DsoMYTylcOWDo@robh.at.kernel.org>

On Thu, 06 Jan 2022 21:19:04 -0600, Rob Herring wrote:
> 'interrupt-parent' is never required as it can be in a parent node or a
> parent node itself can be an interrupt provider. Where exactly it lives is
> outside the scope of a binding schema.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/gpio/toshiba,gpio-visconti.yaml  | 1 -
>  .../devicetree/bindings/mailbox/ti,omap-mailbox.yaml     | 9 ---------
>  Documentation/devicetree/bindings/mfd/cirrus,madera.yaml | 1 -
>  .../devicetree/bindings/net/lantiq,etop-xway.yaml        | 1 -
>  .../devicetree/bindings/net/lantiq,xrx200-net.yaml       | 1 -
>  .../devicetree/bindings/pci/sifive,fu740-pcie.yaml       | 1 -
>  .../devicetree/bindings/pci/xilinx-versal-cpm.yaml       | 1 -
>  7 files changed, 15 deletions(-)
> 

Applied, thanks!


From tharvey at gateworks.com  Tue Jan 11 09:53:29 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Tue, 11 Jan 2022 09:53:29 -0800
Subject: (EXT) Re: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt
 overlays for serial modes
In-Reply-To: <2226437.ElGaqSPkdT@steina-w>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
 <2226437.ElGaqSPkdT@steina-w>
Message-ID: <CAJ+vNU2PxF=9VwMv4f8N5W5Gs2Ynxdn9jHTSkWH7zd3Fo5hBiw@mail.gmail.com>

On Mon, Jan 10, 2022 at 11:20 PM Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> Am Dienstag, 11. Januar 2022, 01:00:21 CET schrieb Tim Harvey:
> > [SNIP]
> > > diff --git a/arch/arm64/boot/dts/freescale/Makefile
> > > b/arch/arm64/boot/dts/freescale/Makefile index a14a6173b765..5ec8d59347b6
> > > 100644
> > > --- a/arch/arm64/boot/dts/freescale/Makefile
> > > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > > @@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
> > >
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
> > >
> > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
> > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
> > >
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
> > >  dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
> > >
> > [SNIP]
> > I'm mostly interested to see if my approach to dt fragments here and
> > the naming of the files makes sense to others.
> >
> > This patch causes the kernel to build dtbo files for:
> > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dtbo
> > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dtbo
> >
> > The intention is that these files are used by boot firmware (U-Boot)
> > to adjust the dtb before passing it to the kernel.
>
> Hi Tim,
>
> do these dtbo actually work? I'm wondering because I was trying to useoverlays
> myself and noticed that the had to be compiled with -@ for u-boot to be able
> to apply them. Apparently there are 2 possibilities:

Alexander,

Yes, they work, but I do manually set DTC_FLAGS=-@ when building
kernel dtbs to make them work.

> * Set "DTC_FLAGS_[dtb] := -@" yourself
> See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> commit/?id=e426d63e752bdbe7d5ba2d872319dde9ab844a07
>
> * Use dedicated overlay target
> See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> commit/?id=15d16d6dadf6947ac7f9a686c615995c5a426ce2
>
> You use neither of them. IIRC just naming the target file .dtbo will not apply
> symbols (-Q) during dtc call. Can you verify using 'V=1'
> Also I'm wondering which way is the best to go.
>

I wasn't aware there was a way to do this via Makefiles. It seems that
perhaps Rob's approach with 'kbuild: Add generic rule to apply
fdtoverlay' is a way to avoid having to add them all manually in the
first approach? I must admit I'm not sure how to use that.

Best regards,

Tim


From cristian.marussi at arm.com  Tue Jan 11 10:13:21 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Tue, 11 Jan 2022 18:13:21 +0000
Subject: [PATCH v8 00/11] Introduce atomic support for SCMI transports
In-Reply-To: <20211220195646.44498-1-cristian.marussi@arm.com>
References: <20211220195646.44498-1-cristian.marussi@arm.com>
Message-ID: <20220111181321.GC6113@e120937-lin>

On Mon, Dec 20, 2021 at 07:56:35PM +0000, Cristian Marussi wrote:
> Hi all,
> 

Hi

this series has now been partially queued (01-->08), the remaining
patches on virtio polling and SCMI CLK atomic support will be posted as
a new small patchset in the next cycle.

Thanks,
Cristian


From rananta at google.com  Tue Jan 11 10:46:40 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue, 11 Jan 2022 10:46:40 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <Yd3AGRtkBgWSmGf2@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
 <Yd3AGRtkBgWSmGf2@google.com>
Message-ID: <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:36 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Mon, Jan 10, 2022, Raghavendra Rao Ananta wrote:
> > On Fri, Jan 7, 2022 at 5:06 PM Sean Christopherson <seanjc at google.com> wrote:
> > >
> > > On Tue, Jan 04, 2022, Raghavendra Rao Ananta wrote:
> > > > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> > >
> > > Needs parantheses around (kvm), but why bother with a macro?  This is the same
> > > header that defines struct kvm.
> > >
> > No specific reason for creating a macro as such. I can remove it if it
> > feels noisy.
>
> Please do.  In the future, don't use a macro unless there's a good reason to do
> so.  Don't get me wrong, I love abusing macros, but for things like this they are
> completely inferior to
>
>   static inline bool kvm_vm_has_started(struct kvm *kvm)
>   {
>         return kvm->vm_started;
>   }
>
> because a helper function gives us type safety, doesn't suffer from concatenation
> of tokens potentially doing weird things, is easier to extend to a multi-line
> implementation, etc...
>
> An example of when it's ok to use a macro is x86's
>
>   #define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0)
>
> which uses a macro instead of a proper function to avoid a circular dependency
> due to arch/x86/include/asm/kvm_host.h being included by include/linux/kvm_host.h
> and thus x86's implementation of kvm_arch_vcpu_memslots_id() coming before the
> definition of struct kvm_vcpu.  But that's very much an exception and done only
> because the alternatives suck more.
>
Understood. Thanks for the explanation! Will switch to an inline function.

> > > > +                      */
> > > > +                     mutex_lock(&kvm->lock);
> > >
> > > This adds unnecessary lock contention when running vCPUs.  The naive solution
> > > would be:
> > >                         if (!kvm->vm_started) {
> > >                                 ...
> > >                         }
> > >
> > Not sure if I understood the solution..
>
> In your proposed patch, KVM_RUN will take kvm->lock _every_ time.  That introduces
> unnecessary contention as it will serialize this bit of code if multiple vCPUs
> are attempting KVM_RUN.  By checking !vm_started, only the "first" KVM_RUN for a
> VM will acquire kvm->lock and thus avoid contention once the VM is up and running.
> There's still a possibility that multiple vCPUs will contend for kvm->lock on their
> first KVM_RUN, hence the quotes.  I called it "naive" because it's possible there's
> a more elegant solution depending on the use case, e.g. a lockless approach might
> work (or it might not).
>
But is it safe to read kvm->vm_started without grabbing the lock in
the first place? use atomic_t maybe for this?

> > > > +                     kvm->vm_started = true;
> > > > +                     mutex_unlock(&kvm->lock);
> > >
> > > Lastly, why is this in generic KVM?
> > >
> > The v1 of the series originally had it in the arm specific code.
> > However, I was suggested to move it to the generic code since the book
> > keeping is not arch specific and could be helpful to others too [1].
>
> I'm definitely in favor of moving/adding thing to generic KVM when it makes sense,
> but I'm skeptical in this particular case.  The code _is_ arch specific in that
> arm64 apparently needs to acquire kvm->lock when checking if a vCPU has run, e.g.
> versus a hypothetical x86 use case that might be completely ok with a lockless
> implementation.  And it's not obvious that there's a plausible, safe use case
> outside of arm64, e.g. on x86, there is very, very little that is truly shared
> across the entire VM/system, most things are per-thread/core/package in some way,
> shape, or form.  In other words, I'm a wary of providing something like this for
> x86 because odds are good that any use will be functionally incorrect.
I've been going back and forth on this. I've seen a couple of
variables declared in the generic struct and used only in the arch
code. vcpu->valid_wakeup for instance, which is used only by s390
arch. Maybe I'm looking at it the wrong way as to what can and can't
go in the generic kvm code.

Thanks,
Raghavendra


From irogers at google.com  Tue Jan 11 10:46:41 2022
From: irogers at google.com (Ian Rogers)
Date: Tue, 11 Jan 2022 10:46:41 -0800
Subject: [PATCH v4 05/48] perf stat: Switch to cpu version of cpu_map__get
In-Reply-To: <64d64526-7d3e-0c31-f43e-f03810f72ac2@huawei.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-6-irogers@google.com>
 <64d64526-7d3e-0c31-f43e-f03810f72ac2@huawei.com>
Message-ID: <CAP-5=fW2JzePV=rQG=Ww1Omub0_r2gi38FUVyaG+a3L=44R9XA@mail.gmail.com>

On Mon, Jan 10, 2022 at 11:04 AM John Garry <john.garry at huawei.com> wrote:
>
> On 05/01/2022 06:13, Ian Rogers wrote:
> > Avoid bugs where the wrong index is passed with the cpu_map.
>
> nit: Don't you mean possible bugs?

You are right. I'll watch myself doing this in the future.

Thanks,
Ian

> >
> > Reviewed-by: James Clark <james.clark at arm.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>


From arnaldo.melo at gmail.com  Tue Jan 11 10:50:07 2022
From: arnaldo.melo at gmail.com (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 15:50:07 -0300
Subject: [PATCH v4 05/48] perf stat: Switch to cpu version of cpu_map__get
In-Reply-To: <CAP-5=fW2JzePV=rQG=Ww1Omub0_r2gi38FUVyaG+a3L=44R9XA@mail.gmail.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-6-irogers@google.com>
 <64d64526-7d3e-0c31-f43e-f03810f72ac2@huawei.com>
 <CAP-5=fW2JzePV=rQG=Ww1Omub0_r2gi38FUVyaG+a3L=44R9XA@mail.gmail.com>
Message-ID: <F6E1C874-F64D-4563-915B-F6420F987264@gmail.com>



On January 11, 2022 3:46:41 PM GMT-03:00, Ian Rogers <irogers at google.com> wrote:
>On Mon, Jan 10, 2022 at 11:04 AM John Garry <john.garry at huawei.com> wrote:
>>
>> On 05/01/2022 06:13, Ian Rogers wrote:
>> > Avoid bugs where the wrong index is passed with the cpu_map.
>>
>> nit: Don't you mean possible bugs?
>
>You are right. I'll watch myself doing this in the future.

I'll update the comment,

I'm still testing it and giving more time for review, including to the adjustments I made..

- Arnaldo

>
>Thanks,
>Ian
>
>> >
>> > Reviewed-by: James Clark <james.clark at arm.com>
>> > Signed-off-by: Ian Rogers <irogers at google.com>


From rananta at google.com  Tue Jan 11 10:52:45 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue, 11 Jan 2022 10:52:45 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
Message-ID: <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>

On Mon, Jan 10, 2022 at 3:57 PM Jim Mattson <jmattson at google.com> wrote:
>
> On Mon, Jan 10, 2022 at 3:07 PM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > On Fri, Jan 7, 2022 at 4:05 PM Jim Mattson <jmattson at google.com> wrote:
> > >
> > > On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> > > <rananta at google.com> wrote:
> > > >
> > > > Hi Reiji,
> > > >
> > > > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > > > >
> > > > > Hi Raghu,
> > > > >
> > > > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > > > <rananta at google.com> wrote:
> > > > > >
> > > > > > Capture the start of the KVM VM, which is basically the
> > > > > > start of any vCPU run. This state of the VM is helpful
> > > > > > in the upcoming patches to prevent user-space from
> > > > > > configuring certain VM features after the VM has started
> > > > > > running.
> > >
> > > What about live migration, where the VM has already technically been
> > > started before the first call to KVM_RUN?
> >
> > My understanding is that a new 'struct kvm' is created on the target
> > machine and this flag should be reset, which would allow the VMM to
> > restore the firmware registers. However, we would be running KVM_RUN
> > for the first time on the target machine, thus setting the flag.
> > So, you are right; It's more of a resume operation from the guest's
> > point of view. I guess the name of the variable is what's confusing
> > here.
>
> I was actually thinking that live migration gives userspace an easy
> way to circumvent your restriction. You said, "This state of the VM is
> helpful in the upcoming patches to prevent user-space from configuring
> certain VM features after the VM has started running." However, if you
> don't ensure that these VM features are configured the same way on the
> target machine as they were on the source machine, you have not
> actually accomplished your stated goal.
>
Isn't that up to the VMM to save/restore and validate the registers
across migrations?
Perhaps I have to re-word my intentions for the patch- userspace
should be able to configure the registers before issuing the first
KVM_RUN.

Thanks,
Raghavendra

> > Thanks,
> > Raghavendra


From rananta at google.com  Tue Jan 11 10:54:05 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue, 11 Jan 2022 10:54:05 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAAeT=FwfjUiaWAJHCEqTCyu9PRr+JEKx1v0P-CJ=2-yGBvaGbA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CAAeT=FwfjUiaWAJHCEqTCyu9PRr+JEKx1v0P-CJ=2-yGBvaGbA@mail.gmail.com>
Message-ID: <CAJHc60zTkVb6LJDrYLrYgZ8dDigcAFkCq9sr96g4Lz0fkVGROw@mail.gmail.com>

On Mon, Jan 10, 2022 at 4:04 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > Hi Reiji,
> >
> > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > >
> > > Hi Raghu,
> > >
> > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > <rananta at google.com> wrote:
> > > >
> > > > Capture the start of the KVM VM, which is basically the
> > > > start of any vCPU run. This state of the VM is helpful
> > > > in the upcoming patches to prevent user-space from
> > > > configuring certain VM features after the VM has started
> > > > running.
> > > >
> > > > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > > > ---
> > > >  include/linux/kvm_host.h | 3 +++
> > > >  virt/kvm/kvm_main.c      | 9 +++++++++
> > > >  2 files changed, 12 insertions(+)
> > > >
> > > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> > > > index c310648cc8f1..d0bd8f7a026c 100644
> > > > --- a/include/linux/kvm_host.h
> > > > +++ b/include/linux/kvm_host.h
> > > > @@ -623,6 +623,7 @@ struct kvm {
> > > >         struct notifier_block pm_notifier;
> > > >  #endif
> > > >         char stats_id[KVM_STATS_NAME_SIZE];
> > > > +       bool vm_started;
> > >
> > > Since KVM_RUN on any vCPUs doesn't necessarily mean that the VM
> > > started yet, the name might be a bit misleading IMHO.  I would
> > > think 'has_run_once' or 'ran_once' might be more clear (?).
> > >
> > I always struggle with the names; but if you feel that 'ran_once'
> > makes more sense for a reader, I can change it.
>
> I would prefer 'ran_once'.
>
Yes, that makes sense. I think the name created a lot of confusion for
the patch.

Thanks,
Raghavendra
>
> > > >  };
> > > >
> > > >  #define kvm_err(fmt, ...) \
> > > > @@ -1666,6 +1667,8 @@ static inline bool kvm_check_request(int req, struct kvm_vcpu *vcpu)
> > > >         }
> > > >  }
> > > >
> > > > +#define kvm_vm_has_started(kvm) (kvm->vm_started)
> > > > +
> > > >  extern bool kvm_rebooting;
> > > >
> > > >  extern unsigned int halt_poll_ns;
> > > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > > > index 72c4e6b39389..962b91ac2064 100644
> > > > --- a/virt/kvm/kvm_main.c
> > > > +++ b/virt/kvm/kvm_main.c
> > > > @@ -3686,6 +3686,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
> > > >         int r;
> > > >         struct kvm_fpu *fpu = NULL;
> > > >         struct kvm_sregs *kvm_sregs = NULL;
> > > > +       struct kvm *kvm = vcpu->kvm;
> > > >
> > > >         if (vcpu->kvm->mm != current->mm || vcpu->kvm->vm_dead)
> > > >                 return -EIO;
> > > > @@ -3723,6 +3724,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
> > > >                         if (oldpid)
> > > >                                 synchronize_rcu();
> > > >                         put_pid(oldpid);
> > > > +
> > > > +                       /*
> > > > +                        * Since we land here even on the first vCPU run,
> > > > +                        * we can mark that the VM has started running.
> > > > +                        */
> > >
> > > It might be nicer to add a comment why the code below gets kvm->lock.
> > >
> > I've been going back and forth on this one. Initially I considered
> > simply going with atomic_t, but the patch 4/11 (KVM: arm64: Setup a
> > framework for hypercall bitmap firmware registers)
> > kvm_arm_set_fw_reg_bmap()'s implementation felt like we need a lock to
> > have the whole 'is the register busy?' operation atomic. But, that's
> > just one of the applications.
>
> I understand why you need the code to get the lock here with the
> current implementation.
> But, since the code just set the one field (vm_started) with the lock,
> I thought the intention of getting the lock might not be so obvious.
> (But, maybe clear enough looking at the code in the patch-4)
>
> Thanks,
> Reiji
>
>
> > > Anyway, the patch generally looks good to me, and thank you
> > > for making this change (it works for my purpose as well).
> > >
> > > Reviewed-by: Reiji Watanabe <reijiw at google.com>
> > >
> > Glad that it's helping you as well and thanks for the review.
> >
> > Regards,
> > Raghavendra
> >
> > > Thanks,
> > > Reiji
> > >
> > >
> > > > +                       mutex_lock(&kvm->lock);
> > > > +                       kvm->vm_started = true;
> > > > +                       mutex_unlock(&kvm->lock);
> > > >                 }
> > > >                 r = kvm_arch_vcpu_ioctl_run(vcpu);
> > > >                 trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
> > > > --
> > > > 2.34.1.448.ga2b2bfdf31-goog
> > > >


From lyude at redhat.com  Tue Jan 11 10:58:39 2022
From: lyude at redhat.com (Lyude Paul)
Date: Tue, 11 Jan 2022 13:58:39 -0500
Subject: [Nouveau] [PATCH v2 3/5] drm/dp: Move DisplayPort helpers into
 separate helper module
In-Reply-To: <20211215104318.18866-4-tzimmermann@suse.de>
References: <20211215104318.18866-1-tzimmermann@suse.de>
 <20211215104318.18866-4-tzimmermann@suse.de>
Message-ID: <58056ee59acc791c0ef1562fab45e24f9aaa19b4.camel@redhat.com>

Acked-by: Lyude Paul <lyude at redhat.com>

On Wed, 2021-12-15 at 11:43 +0100, Thomas Zimmermann wrote:
> Move DisplayPort functions into a separate module to reduce the size
> of the KMS helpers. Select DRM_DP_HELPER for all users of the code. To
> avoid naming conflicts, rename drm_dp_helper.c to drm_dp.c
> 
> This change can help to reduce the size of the kernel binary. Some
> numbers from a x86-64 test build:
> 
> Before:
> ????????drm_kms_helper.ko:??????447480 bytes
> 
> After:
> ????????drm_dp_helper.ko:???????216632 bytes
> ????????drm_kms_helper.ko:??????239424 bytes
> 
> For early-boot graphics, generic DRM drivers, such as simpledrm,
> require DRM KMS helpers to be built into the kernel. Generic helper
> functions for DisplayPort take up a significant portion of DRM KMS
> helper library. These functions are not used by generic drivers and
> can be loaded as a module.
> 
> v2:
> ????????* move DP helper code into dp/ (Jani)
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann at suse.de>
> ---
> ?drivers/gpu/drm/Kconfig?????????????????????? |? 8 +++++++
> ?drivers/gpu/drm/Makefile????????????????????? | 10 ++++-----
> ?drivers/gpu/drm/bridge/Kconfig??????????????? |? 4 ++++
> ?drivers/gpu/drm/bridge/analogix/Kconfig?????? |? 2 ++
> ?drivers/gpu/drm/bridge/cadence/Kconfig??????? |? 1 +
> ?drivers/gpu/drm/dp/Makefile?????????????????? |? 7 ++++++
> ?.../gpu/drm/{drm_dp_helper.c => dp/drm_dp.c}? |? 0
> ?drivers/gpu/drm/{ => dp}/drm_dp_aux_dev.c???? |? 0
> ?drivers/gpu/drm/{ => dp}/drm_dp_cec.c???????? |? 0
> ?.../drm/{ => dp}/drm_dp_dual_mode_helper.c??? |? 0
> ?.../gpu/drm/{ => dp}/drm_dp_helper_internal.h |? 0
> ?drivers/gpu/drm/dp/drm_dp_helper_mod.c??????? | 22 +++++++++++++++++++
> ?.../gpu/drm/{ => dp}/drm_dp_mst_topology.c??? |? 0
> ?.../{ => dp}/drm_dp_mst_topology_internal.h?? |? 0
> ?drivers/gpu/drm/drm_kms_helper_common.c?????? | 15 -------------
> ?drivers/gpu/drm/i915/Kconfig????????????????? |? 1 +
> ?drivers/gpu/drm/msm/Kconfig?????????????????? |? 1 +
> ?drivers/gpu/drm/nouveau/Kconfig?????????????? |? 1 +
> ?drivers/gpu/drm/rockchip/Kconfig????????????? |? 1 +
> ?drivers/gpu/drm/tegra/Kconfig???????????????? |? 1 +
> ?drivers/gpu/drm/xlnx/Kconfig????????????????? |? 1 +
> ?21 files changed, 54 insertions(+), 21 deletions(-)
> ?create mode 100644 drivers/gpu/drm/dp/Makefile
> ?rename drivers/gpu/drm/{drm_dp_helper.c => dp/drm_dp.c} (100%)
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_aux_dev.c (100%)
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_cec.c (100%)
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_dual_mode_helper.c (100%)
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_helper_internal.h (100%)
> ?create mode 100644 drivers/gpu/drm/dp/drm_dp_helper_mod.c
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_mst_topology.c (100%)
> ?rename drivers/gpu/drm/{ => dp}/drm_dp_mst_topology_internal.h (100%)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index b1f22e457fd0..91f54aeb0b7c 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -80,6 +80,12 @@ config DRM_DEBUG_SELFTEST
> ?
> ????????? If in doubt, say "N".
> ?
> +config DRM_DP_HELPER
> +???????tristate
> +???????depends on DRM
> +???????help
> +???????? DRM helpers for DisplayPort.
> +
> ?config DRM_KMS_HELPER
> ????????tristate
> ????????depends on DRM
> @@ -236,6 +242,7 @@ config DRM_RADEON
> ????????depends on DRM && PCI && MMU
> ????????depends on AGP || !AGP
> ????????select FW_LOADER
> +???????select DRM_DP_HELPER
> ???????? select DRM_KMS_HELPER
> ???????? select DRM_TTM
> ????????select DRM_TTM_HELPER
> @@ -256,6 +263,7 @@ config DRM_AMDGPU
> ????????tristate "AMD GPU"
> ????????depends on DRM && PCI && MMU
> ????????select FW_LOADER
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_SCHED
> ????????select DRM_TTM
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 301a44dc18e3..69be80ef1d31 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -48,21 +48,18 @@ obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
> ?drm_ttm_helper-y := drm_gem_ttm_helper.o
> ?obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
> ?
> -drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o
> drm_dp_helper.o \
> +drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o \
> ????????????????drm_dsc.o drm_encoder_slave.o drm_flip_work.o drm_hdcp.o \
> ????????????????drm_probe_helper.o \
> -???????????????drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
> \
> -???????????????drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
> +???????????????drm_plane_helper.o drm_atomic_helper.o \
> +???????????????drm_kms_helper_common.o \
> ????????????????drm_simple_kms_helper.o drm_modeset_helper.o \
> ????????????????drm_scdc_helper.o drm_gem_atomic_helper.o \
> ????????????????drm_gem_framebuffer_helper.o \
> ????????????????drm_atomic_state_helper.o drm_damage_helper.o \
> ????????????????drm_format_helper.o drm_self_refresh_helper.o drm_rect.o
> -
> ?drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
> ?drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
> -drm_kms_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
> -drm_kms_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
> ?
> ?obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
> ?obj-$(CONFIG_DRM_DEBUG_SELFTEST) += selftests/
> @@ -72,6 +69,7 @@ obj-$(CONFIG_DRM_MIPI_DBI) += drm_mipi_dbi.o
> ?obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
> ?obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) +=
> drm_panel_orientation_quirks.o
> ?obj-y??????????????????+= arm/
> +obj-y??????????????????+= dp/
> ?obj-$(CONFIG_DRM_TTM)??+= ttm/
> ?obj-$(CONFIG_DRM_SCHED)????????+= scheduler/
> ?obj-$(CONFIG_DRM_TDFX)?+= tdfx/
> diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
> index 61db5a66b493..a27435a4c9c4 100644
> --- a/drivers/gpu/drm/bridge/Kconfig
> +++ b/drivers/gpu/drm/bridge/Kconfig
> @@ -183,6 +183,7 @@ config DRM_PARADE_PS8640
> ????????tristate "Parade PS8640 MIPI DSI to eDP Converter"
> ????????depends on OF
> ????????select DRM_DP_AUX_BUS
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_MIPI_DSI
> ????????select DRM_PANEL
> @@ -253,6 +254,7 @@ config DRM_TOSHIBA_TC358764
> ?config DRM_TOSHIBA_TC358767
> ????????tristate "Toshiba TC358767 eDP bridge"
> ????????depends on OF
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select REGMAP_I2C
> ????????select DRM_PANEL
> @@ -272,6 +274,7 @@ config DRM_TOSHIBA_TC358768
> ?config DRM_TOSHIBA_TC358775
> ????????tristate "Toshiba TC358775 DSI/LVDS bridge"
> ????????depends on OF
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select REGMAP_I2C
> ????????select DRM_PANEL
> @@ -299,6 +302,7 @@ config DRM_TI_SN65DSI83
> ?config DRM_TI_SN65DSI86
> ????????tristate "TI SN65DSI86 DSI to eDP bridge"
> ????????depends on OF
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select REGMAP_I2C
> ????????select DRM_PANEL
> diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig
> b/drivers/gpu/drm/bridge/analogix/Kconfig
> index 2ef6eb2b786c..319ba0df57be 100644
> --- a/drivers/gpu/drm/bridge/analogix/Kconfig
> +++ b/drivers/gpu/drm/bridge/analogix/Kconfig
> @@ -3,6 +3,7 @@ config DRM_ANALOGIX_ANX6345
> ????????tristate "Analogix ANX6345 bridge"
> ????????depends on OF
> ????????select DRM_ANALOGIX_DP
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select REGMAP_I2C
> ????????help
> @@ -14,6 +15,7 @@ config DRM_ANALOGIX_ANX6345
> ?config DRM_ANALOGIX_ANX78XX
> ????????tristate "Analogix ANX78XX bridge"
> ????????select DRM_ANALOGIX_DP
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select REGMAP_I2C
> ????????help
> diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig
> b/drivers/gpu/drm/bridge/cadence/Kconfig
> index ef8c230e0f62..de697bade05e 100644
> --- a/drivers/gpu/drm/bridge/cadence/Kconfig
> +++ b/drivers/gpu/drm/bridge/cadence/Kconfig
> @@ -1,6 +1,7 @@
> ?# SPDX-License-Identifier: GPL-2.0-only
> ?config DRM_CDNS_MHDP8546
> ????????tristate "Cadence DPI/DP bridge"
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_PANEL_BRIDGE
> ????????depends on OF
> diff --git a/drivers/gpu/drm/dp/Makefile b/drivers/gpu/drm/dp/Makefile
> new file mode 100644
> index 000000000000..5b892aeff5ab
> --- /dev/null
> +++ b/drivers/gpu/drm/dp/Makefile
> @@ -0,0 +1,7 @@
> +# SPDX-License-Identifier: MIT
> +
> +drm_dp_helper-y := drm_dp.o drm_dp_dual_mode_helper.o drm_dp_helper_mod.o
> drm_dp_mst_topology.o
> +drm_dp_helper-$(CONFIG_DRM_DP_AUX_CHARDEV) += drm_dp_aux_dev.o
> +drm_dp_helper-$(CONFIG_DRM_DP_CEC) += drm_dp_cec.o
> +
> +obj-$(CONFIG_DRM_DP_HELPER) += drm_dp_helper.o
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/dp/drm_dp.c
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_helper.c
> rename to drivers/gpu/drm/dp/drm_dp.c
> diff --git a/drivers/gpu/drm/drm_dp_aux_dev.c
> b/drivers/gpu/drm/dp/drm_dp_aux_dev.c
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_aux_dev.c
> rename to drivers/gpu/drm/dp/drm_dp_aux_dev.c
> diff --git a/drivers/gpu/drm/drm_dp_cec.c b/drivers/gpu/drm/dp/drm_dp_cec.c
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_cec.c
> rename to drivers/gpu/drm/dp/drm_dp_cec.c
> diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c
> b/drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_dual_mode_helper.c
> rename to drivers/gpu/drm/dp/drm_dp_dual_mode_helper.c
> diff --git a/drivers/gpu/drm/drm_dp_helper_internal.h
> b/drivers/gpu/drm/dp/drm_dp_helper_internal.h
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_helper_internal.h
> rename to drivers/gpu/drm/dp/drm_dp_helper_internal.h
> diff --git a/drivers/gpu/drm/dp/drm_dp_helper_mod.c
> b/drivers/gpu/drm/dp/drm_dp_helper_mod.c
> new file mode 100644
> index 000000000000..db753de24000
> --- /dev/null
> +++ b/drivers/gpu/drm/dp/drm_dp_helper_mod.c
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: MIT
> +
> +#include <linux/module.h>
> +
> +#include "drm_dp_helper_internal.h"
> +
> +MODULE_DESCRIPTION("DRM DisplayPort helper");
> +MODULE_LICENSE("GPL and additional rights");
> +
> +static int __init drm_dp_helper_module_init(void)
> +{
> +???????return drm_dp_aux_dev_init();
> +}
> +
> +static void __exit drm_dp_helper_module_exit(void)
> +{
> +???????/* Call exit functions from specific dp helpers here */
> +???????drm_dp_aux_dev_exit();
> +}
> +
> +module_init(drm_dp_helper_module_init);
> +module_exit(drm_dp_helper_module_exit);
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/dp/drm_dp_mst_topology.c
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_mst_topology.c
> rename to drivers/gpu/drm/dp/drm_dp_mst_topology.c
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology_internal.h
> b/drivers/gpu/drm/dp/drm_dp_mst_topology_internal.h
> similarity index 100%
> rename from drivers/gpu/drm/drm_dp_mst_topology_internal.h
> rename to drivers/gpu/drm/dp/drm_dp_mst_topology_internal.h
> diff --git a/drivers/gpu/drm/drm_kms_helper_common.c
> b/drivers/gpu/drm/drm_kms_helper_common.c
> index 88260d26409c..8be20080cd8d 100644
> --- a/drivers/gpu/drm/drm_kms_helper_common.c
> +++ b/drivers/gpu/drm/drm_kms_helper_common.c
> @@ -29,7 +29,6 @@
> ?
> ?#include <drm/drm_print.h>
> ?
> -#include "drm_dp_helper_internal.h"
> ?#include "drm_crtc_helper_internal.h"
> ?
> ?MODULE_AUTHOR("David Airlie, Jesse Barnes");
> @@ -62,17 +61,3 @@ MODULE_PARM_DESC(edid_firmware,
> ???????????????? "DEPRECATED. Use drm.edid_firmware module parameter
> instead.");
> ?
> ?#endif
> -
> -static int __init drm_kms_helper_init(void)
> -{
> -???????return drm_dp_aux_dev_init();
> -}
> -
> -static void __exit drm_kms_helper_exit(void)
> -{
> -???????/* Call exit functions from specific kms helpers here */
> -???????drm_dp_aux_dev_exit();
> -}
> -
> -module_init(drm_kms_helper_init);
> -module_exit(drm_kms_helper_exit);
> diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
> index a4c94dc2e216..b68e8b551b83 100644
> --- a/drivers/gpu/drm/i915/Kconfig
> +++ b/drivers/gpu/drm/i915/Kconfig
> @@ -9,6 +9,7 @@ config DRM_I915
> ????????# the shmem_readpage() which depends upon tmpfs
> ????????select SHMEM
> ????????select TMPFS
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_PANEL
> ????????select DRM_MIPI_DSI
> diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
> index 39197b4beea7..75015b0e165e 100644
> --- a/drivers/gpu/drm/msm/Kconfig
> +++ b/drivers/gpu/drm/msm/Kconfig
> @@ -12,6 +12,7 @@ config DRM_MSM
> ????????select IOMMU_IO_PGTABLE
> ????????select QCOM_MDT_LOADER if ARCH_QCOM
> ????????select REGULATOR
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_PANEL
> ????????select DRM_BRIDGE
> diff --git a/drivers/gpu/drm/nouveau/Kconfig
> b/drivers/gpu/drm/nouveau/Kconfig
> index 9436310d0854..3ec690b6f0b4 100644
> --- a/drivers/gpu/drm/nouveau/Kconfig
> +++ b/drivers/gpu/drm/nouveau/Kconfig
> @@ -4,6 +4,7 @@ config DRM_NOUVEAU
> ????????depends on DRM && PCI && MMU
> ????????select IOMMU_API
> ????????select FW_LOADER
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_TTM
> ????????select DRM_TTM_HELPER
> diff --git a/drivers/gpu/drm/rockchip/Kconfig
> b/drivers/gpu/drm/rockchip/Kconfig
> index 9f1ecefc3933..d59dca5efb52 100644
> --- a/drivers/gpu/drm/rockchip/Kconfig
> +++ b/drivers/gpu/drm/rockchip/Kconfig
> @@ -2,6 +2,7 @@
> ?config DRM_ROCKCHIP
> ????????tristate "DRM Support for Rockchip"
> ????????depends on DRM && ROCKCHIP_IOMMU
> +???????select DRM_DP_HELPER
> ????????select DRM_GEM_CMA_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_PANEL
> diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
> index 1650a448eabd..dc88adc7ba40 100644
> --- a/drivers/gpu/drm/tegra/Kconfig
> +++ b/drivers/gpu/drm/tegra/Kconfig
> @@ -5,6 +5,7 @@ config DRM_TEGRA
> ????????depends on COMMON_CLK
> ????????depends on DRM
> ????????depends on OF
> +???????select DRM_DP_HELPER
> ????????select DRM_KMS_HELPER
> ????????select DRM_MIPI_DSI
> ????????select DRM_PANEL
> diff --git a/drivers/gpu/drm/xlnx/Kconfig b/drivers/gpu/drm/xlnx/Kconfig
> index d8d38d86d5c6..06cf477dbcdd 100644
> --- a/drivers/gpu/drm/xlnx/Kconfig
> +++ b/drivers/gpu/drm/xlnx/Kconfig
> @@ -6,6 +6,7 @@ config DRM_ZYNQMP_DPSUB
> ????????depends on PHY_XILINX_ZYNQMP
> ????????depends on XILINX_ZYNQMP_DPDMA
> ????????select DMA_ENGINE
> +???????select DRM_DP_HELPER
> ????????select DRM_GEM_CMA_HELPER
> ????????select DRM_KMS_HELPER
> ????????select GENERIC_PHY

-- 
Cheers,
 Lyude Paul (she/her)
 Software Engineer at Red Hat



From seanjc at google.com  Tue Jan 11 11:04:42 2022
From: seanjc at google.com (Sean Christopherson)
Date: Tue, 11 Jan 2022 19:04:42 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
 <Yd3AGRtkBgWSmGf2@google.com>
 <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>
Message-ID: <Yd3UymPg++JW98/2@google.com>

On Tue, Jan 11, 2022, Raghavendra Rao Ananta wrote:
> On Tue, Jan 11, 2022 at 9:36 AM Sean Christopherson <seanjc at google.com> wrote:
> > In your proposed patch, KVM_RUN will take kvm->lock _every_ time.  That introduces
> > unnecessary contention as it will serialize this bit of code if multiple vCPUs
> > are attempting KVM_RUN.  By checking !vm_started, only the "first" KVM_RUN for a
> > VM will acquire kvm->lock and thus avoid contention once the VM is up and running.
> > There's still a possibility that multiple vCPUs will contend for kvm->lock on their
> > first KVM_RUN, hence the quotes.  I called it "naive" because it's possible there's
> > a more elegant solution depending on the use case, e.g. a lockless approach might
> > work (or it might not).
> >
> But is it safe to read kvm->vm_started without grabbing the lock in
> the first place?

Don't know, but that's my point.  Without a consumer in generic KVM and due to
my lack of arm64 knowledge, without a high-level description of how the flag will
be used by arm64, it's really difficult to determine what's safe and what's not.
For other architectures, it's an impossible question to answer because we don't
know how the flag might be used.

> use atomic_t maybe for this?

No.  An atomic_t is generally useful only if there are multiple writers that can
possibly write different values.  It's highly unlikely that simply switching to an
atomic address the needs of arm64.

> > > > > +                     kvm->vm_started = true;
> > > > > +                     mutex_unlock(&kvm->lock);
> > > >
> > > > Lastly, why is this in generic KVM?
> > > >
> > > The v1 of the series originally had it in the arm specific code.
> > > However, I was suggested to move it to the generic code since the book
> > > keeping is not arch specific and could be helpful to others too [1].
> >
> > I'm definitely in favor of moving/adding thing to generic KVM when it makes sense,
> > but I'm skeptical in this particular case.  The code _is_ arch specific in that
> > arm64 apparently needs to acquire kvm->lock when checking if a vCPU has run, e.g.
> > versus a hypothetical x86 use case that might be completely ok with a lockless
> > implementation.  And it's not obvious that there's a plausible, safe use case
> > outside of arm64, e.g. on x86, there is very, very little that is truly shared
> > across the entire VM/system, most things are per-thread/core/package in some way,
> > shape, or form.  In other words, I'm a wary of providing something like this for
> > x86 because odds are good that any use will be functionally incorrect.
> I've been going back and forth on this. I've seen a couple of
> variables declared in the generic struct and used only in the arch
> code. vcpu->valid_wakeup for instance, which is used only by s390
> arch. Maybe I'm looking at it the wrong way as to what can and can't
> go in the generic kvm code.

Ya, valid_wakeup is an oddball, I don't know why it's in kvm_vcpu instead of
arch code that's wrapped with e.g. kvm_arch_vcpu_valid_wakeup().

That said, valid_wakeup is consumed by generic KVM, i.e. has well defined semantics
for how it is used, so it's purely a "this code is rather odd" issue.  vm_started
on the other hand is only produced by generic KVM, and so its required semantics are
unclear.


From nfraprado at collabora.com  Tue Jan 11 11:15:01 2022
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Tue, 11 Jan 2022 14:15:01 -0500
Subject: [PATCH v2 1/5] arm64: dts: mediatek: Correct uart clock of MT8192
In-Reply-To: <20220106032420.11544-2-allen-kh.cheng@mediatek.com>
References: <20220106032420.11544-1-allen-kh.cheng@mediatek.com>
 <20220106032420.11544-2-allen-kh.cheng@mediatek.com>
Message-ID: <20220111191501.dspzjabuuohinufz@notapiano>

Hi Allen,

thank you for improving the commit message! However, please see my comment
below.

On Thu, Jan 06, 2022 at 11:24:16AM +0800, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the uart clock property to point to the actual

This sentence is incomplete. It is missing "clock." at the end. Could you please
add it?

Same thing for all other patches in this series.

After fixing that typo in the commit message of all patches, please add my
reviewed-by in all patches:

Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Thanks,
N?colas


From irogers at google.com  Tue Jan 11 11:16:16 2022
From: irogers at google.com (Ian Rogers)
Date: Tue, 11 Jan 2022 11:16:16 -0800
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <YdyOFd8JJHbm1W+m@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
 <YdyOFd8JJHbm1W+m@kernel.org>
Message-ID: <CAP-5=fWZWMweYhWvv1vr6quZe=ZJrhF_WEXqbELVitzofBcQrA@mail.gmail.com>

On Mon, Jan 10, 2022 at 11:50 AM Arnaldo Carvalho de Melo
<acme at kernel.org> wrote:
>
> Em Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers escreveu:
> > A common problem is confusing CPU map indices with the CPU, by wrapping
> > the CPU with a struct then this is avoided. This approach is similar to
> > atomic_t.
>
> This one needed this to build with BUILD_BPF_SKEL=1, please check, I'll
> soon push this to tmp.perf/perf_cpu so that you can take a look and test
> it.


Thanks Arnaldo, I did eye-ball one issue where cpu_map__default_new's
behavior would be impacted (nr would be 1 rather than nr_cpus). The
fix is:

--- a/tools/lib/perf/cpumap.c
+++ b/tools/lib/perf/cpumap.c
@@ -18,7 +18,7 @@ static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
        if (!cpus)
                return NULL;

-       cpus->nr = 1;
+       cpus->nr = nr_cpus;
        refcount_set(&cpus->refcnt, 1);
        return cpus;
 }

Could you add that into this patch as well?

Thanks,
Ian


> - Arnaldo
>
> diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
> index 80d1a3a31052fe55..328479df5e16a638 100644
> --- a/tools/perf/util/bpf_counter.c
> +++ b/tools/perf/util/bpf_counter.c
> @@ -540,7 +540,7 @@ static int bperf__load(struct evsel *evsel, struct target *target)
>                     filter_type == BPERF_FILTER_TGID)
>                         key = evsel->core.threads->map[i].pid;
>                 else if (filter_type == BPERF_FILTER_CPU)
> -                       key = evsel->core.cpus->map[i];
> +                       key = evsel->core.cpus->map[i].cpu;
>                 else
>                         break;
>
> @@ -584,7 +584,7 @@ static int bperf_sync_counters(struct evsel *evsel)
>
>         num_cpu = all_cpu_map->nr;
>         for (i = 0; i < num_cpu; i++) {
> -               cpu = all_cpu_map->map[i];
> +               cpu = all_cpu_map->map[i].cpu;
>                 bperf_trigger_reading(evsel->bperf_leader_prog_fd, cpu);
>         }
>         return 0;
> @@ -605,7 +605,7 @@ static int bperf__disable(struct evsel *evsel)
>  static int bperf__read(struct evsel *evsel)
>  {
>         struct bperf_follower_bpf *skel = evsel->follower_skel;
> -       __u32 num_cpu_bpf = cpu__max_cpu();
> +       __u32 num_cpu_bpf = cpu__max_cpu().cpu;
>         struct bpf_perf_event_value values[num_cpu_bpf];
>         int reading_map_fd, err = 0;
>         __u32 i;
> @@ -615,6 +615,7 @@ static int bperf__read(struct evsel *evsel)
>         reading_map_fd = bpf_map__fd(skel->maps.accum_readings);
>
>         for (i = 0; i < bpf_map__max_entries(skel->maps.accum_readings); i++) {
> +               struct perf_cpu entry;
>                 __u32 cpu;
>
>                 err = bpf_map_lookup_elem(reading_map_fd, &i, values);
> @@ -624,14 +625,15 @@ static int bperf__read(struct evsel *evsel)
>                 case BPERF_FILTER_GLOBAL:
>                         assert(i == 0);
>
> -                       perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
> +                       perf_cpu_map__for_each_cpu(entry, j, all_cpu_map) {
> +                               cpu = entry.cpu;
>                                 perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
>                                 perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
>                                 perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
>                         }
>                         break;
>                 case BPERF_FILTER_CPU:
> -                       cpu = evsel->core.cpus->map[i];
> +                       cpu = evsel->core.cpus->map[i].cpu;
>                         perf_counts(evsel->counts, i, 0)->val = values[cpu].counter;
>                         perf_counts(evsel->counts, i, 0)->ena = values[cpu].enabled;
>                         perf_counts(evsel->counts, i, 0)->run = values[cpu].running;
> diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
> index cbc6c2bca488f6bf..631e34a0b66ff084 100644
> --- a/tools/perf/util/bpf_counter_cgroup.c
> +++ b/tools/perf/util/bpf_counter_cgroup.c
> @@ -48,7 +48,7 @@ static int bperf_load_program(struct evlist *evlist)
>         struct cgroup *cgrp, *leader_cgrp;
>         __u32 i, cpu;
>         __u32 nr_cpus = evlist->core.all_cpus->nr;
> -       int total_cpus = cpu__max_cpu();
> +       int total_cpus = cpu__max_cpu().cpu;
>         int map_size, map_fd;
>         int prog_fd, err;
>
> @@ -125,7 +125,7 @@ static int bperf_load_program(struct evlist *evlist)
>                         for (cpu = 0; cpu < nr_cpus; cpu++) {
>                                 int fd = FD(evsel, cpu);
>                                 __u32 idx = evsel->core.idx * total_cpus +
> -                                       evlist->core.all_cpus->map[cpu];
> +                                       evlist->core.all_cpus->map[cpu].cpu;
>
>                                 err = bpf_map_update_elem(map_fd, &idx, &fd,
>                                                           BPF_ANY);
> @@ -212,7 +212,7 @@ static int bperf_cgrp__sync_counters(struct evlist *evlist)
>         int prog_fd = bpf_program__fd(skel->progs.trigger_read);
>
>         for (i = 0; i < nr_cpus; i++) {
> -               cpu = evlist->core.all_cpus->map[i];
> +               cpu = evlist->core.all_cpus->map[i].cpu;
>                 bperf_trigger_reading(prog_fd, cpu);
>         }
>
> @@ -245,7 +245,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
>  {
>         struct evlist *evlist = evsel->evlist;
>         int i, cpu, nr_cpus = evlist->core.all_cpus->nr;
> -       int total_cpus = cpu__max_cpu();
> +       int total_cpus = cpu__max_cpu().cpu;
>         struct perf_counts_values *counts;
>         struct bpf_perf_event_value *values;
>         int reading_map_fd, err = 0;
> @@ -272,7 +272,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
>                 }
>
>                 for (i = 0; i < nr_cpus; i++) {
> -                       cpu = evlist->core.all_cpus->map[i];
> +                       cpu = evlist->core.all_cpus->map[i].cpu;
>
>                         counts = perf_counts(evsel->counts, i, 0);
>                         counts->val = values[cpu].counter;
> diff --git a/tools/perf/util/bpf_ftrace.c b/tools/perf/util/bpf_ftrace.c
> index 28dc4c60c7884818..d756cc66eef32ae8 100644
> --- a/tools/perf/util/bpf_ftrace.c
> +++ b/tools/perf/util/bpf_ftrace.c
> @@ -63,7 +63,7 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace *ftrace)
>                 fd = bpf_map__fd(skel->maps.cpu_filter);
>
>                 for (i = 0; i < ncpus; i++) {
> -                       cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i);
> +                       cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i).cpu;
>                         bpf_map_update_elem(fd, &cpu, &val, BPF_ANY);
>                 }
>         }
> @@ -122,7 +122,7 @@ int perf_ftrace__latency_read_bpf(struct perf_ftrace *ftrace __maybe_unused,
>         int i, fd, err;
>         u32 idx;
>         u64 *hist;
> -       int ncpus = cpu__max_cpu();
> +       int ncpus = cpu__max_cpu().cpu;
>
>         fd = bpf_map__fd(skel->maps.latency);
>


From jmattson at google.com  Tue Jan 11 11:16:46 2022
From: jmattson at google.com (Jim Mattson)
Date: Tue, 11 Jan 2022 11:16:46 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
Message-ID: <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>

On Tue, Jan 11, 2022 at 10:52 AM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> On Mon, Jan 10, 2022 at 3:57 PM Jim Mattson <jmattson at google.com> wrote:
> >
> > On Mon, Jan 10, 2022 at 3:07 PM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > On Fri, Jan 7, 2022 at 4:05 PM Jim Mattson <jmattson at google.com> wrote:
> > > >
> > > > On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> > > > <rananta at google.com> wrote:
> > > > >
> > > > > Hi Reiji,
> > > > >
> > > > > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > > > > >
> > > > > > Hi Raghu,
> > > > > >
> > > > > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > > > > <rananta at google.com> wrote:
> > > > > > >
> > > > > > > Capture the start of the KVM VM, which is basically the
> > > > > > > start of any vCPU run. This state of the VM is helpful
> > > > > > > in the upcoming patches to prevent user-space from
> > > > > > > configuring certain VM features after the VM has started
> > > > > > > running.
> > > >
> > > > What about live migration, where the VM has already technically been
> > > > started before the first call to KVM_RUN?
> > >
> > > My understanding is that a new 'struct kvm' is created on the target
> > > machine and this flag should be reset, which would allow the VMM to
> > > restore the firmware registers. However, we would be running KVM_RUN
> > > for the first time on the target machine, thus setting the flag.
> > > So, you are right; It's more of a resume operation from the guest's
> > > point of view. I guess the name of the variable is what's confusing
> > > here.
> >
> > I was actually thinking that live migration gives userspace an easy
> > way to circumvent your restriction. You said, "This state of the VM is
> > helpful in the upcoming patches to prevent user-space from configuring
> > certain VM features after the VM has started running." However, if you
> > don't ensure that these VM features are configured the same way on the
> > target machine as they were on the source machine, you have not
> > actually accomplished your stated goal.
> >
> Isn't that up to the VMM to save/restore and validate the registers
> across migrations?

Yes, just as it is up to userspace not to make bad configuration
changes after the first VMRUN.

> Perhaps I have to re-word my intentions for the patch- userspace
> should be able to configure the registers before issuing the first
> KVM_RUN.

Perhaps it would help if you explained *why* you are doing this. It
sounds like you are either trying to protect against a malicious
userspace, or you are trying to keep userspace from doing something
stupid. In general, kvm only enforces constraints that are necessary
to protect the host. If that's what you're doing, I don't understand
why live migration doesn't provide an end-run around your protections.


From acme at kernel.org  Tue Jan 11 11:33:01 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 16:33:01 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <20220105061351.120843-3-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
Message-ID: <Yd3bbelDA1qGPodk@kernel.org>

Em Tue, Jan 04, 2022 at 10:13:05PM -0800, Ian Rogers escreveu:
> The cpu_map and index can get confused. Add variants of the cpu_map__get
> routines that are passed a cpu. Make the existing cpu_map__get routines
> use the new functions with a view to remove them when no longer used.
> 
> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/perf/util/cpumap.c | 79 +++++++++++++++++++++++-----------------
>  tools/perf/util/cpumap.h |  6 ++-
>  2 files changed, 51 insertions(+), 34 deletions(-)
> 
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index 87d3eca9b872..49fba2c53822 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -128,21 +128,23 @@ int cpu_map__get_socket_id(int cpu)
>  	return ret ?: value;
>  }
>  
> -struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> -					void *data __maybe_unused)
> +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
>  {
> -	int cpu;
>  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
>  
> -	if (idx > map->nr)
> -		return id;
> -
> -	cpu = map->map[idx];
> -
>  	id.socket = cpu_map__get_socket_id(cpu);
>  	return id;
>  }
>  
> +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> +				       void *data)
> +{
> +	if (idx < 0 || idx > map->nr)
> +		return cpu_map__empty_aggr_cpu_id();
> +
> +	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> +}
> +


This 'idx < 0' wasn't in the original code nor is described in the
comment log message, please avoid doing this, this may be harmless or
even a good hardening, but either way would be interesting to have it in
a separate patch. This eases review as in the end this code is just a
refactoring, moving things around but in the end should be equivalent code.

There are a few more, please consider this and if you agree, to speed
things up I can make the changes here, if I think this won't fallout in
changes to subsequent patches touching this area.

- Arnaldo

>  static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
>  {
>  	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
> @@ -200,15 +202,10 @@ int cpu_map__get_die_id(int cpu)
>  	return ret ?: value;
>  }
>  
> -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data)
> +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
>  {
> -	int cpu, die;
> -	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> -
> -	if (idx > map->nr)
> -		return id;
> -
> -	cpu = map->map[idx];
> +	struct aggr_cpu_id id;
> +	int die;
>  
>  	die = cpu_map__get_die_id(cpu);
>  	/* There is no die_id on legacy system. */
> @@ -220,7 +217,7 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
>  	 * with the socket ID and then add die to
>  	 * make a unique ID.
>  	 */
> -	id = cpu_map__get_socket(map, idx, data);
> +	id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
>  	if (cpu_map__aggr_cpu_id_is_empty(id))
>  		return id;
>  
> @@ -228,6 +225,15 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
>  	return id;
>  }
>  
> +struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
> +				    void *data)
> +{
> +	if (idx < 0 || idx > map->nr)
> +		return cpu_map__empty_aggr_cpu_id();

Ditto

> +
> +	return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
> +}
> +
>  int cpu_map__get_core_id(int cpu)
>  {
>  	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
> @@ -239,20 +245,13 @@ int cpu_map__get_node_id(int cpu)
>  	return cpu__get_node(cpu);
>  }
>  
> -struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
>  {
> -	int cpu;
> -	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> -
> -	if (idx > map->nr)
> -		return id;
> -
> -	cpu = map->map[idx];
> -
> -	cpu = cpu_map__get_core_id(cpu);
> +	struct aggr_cpu_id id;
> +	int core = cpu_map__get_core_id(cpu);
>  
>  	/* cpu_map__get_die returns a struct with socket and die set*/
> -	id = cpu_map__get_die(map, idx, data);
> +	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
>  	if (cpu_map__aggr_cpu_id_is_empty(id))
>  		return id;
>  
> @@ -260,19 +259,33 @@ struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *da
>  	 * core_id is relative to socket and die, we need a global id.
>  	 * So we combine the result from cpu_map__get_die with the core id
>  	 */
> -	id.core = cpu;
> +	id.core = core;
>  	return id;
> +
>  }
>  
> -struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data __maybe_unused)
> +struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> +{
> +	if (idx < 0 || idx > map->nr)
> +		return cpu_map__empty_aggr_cpu_id();

Ditto

> +
> +	return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
> +}
> +
> +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
>  {
>  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
>  
> +	id.node = cpu_map__get_node_id(cpu);
> +	return id;
> +}
> +
> +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
> +{
>  	if (idx < 0 || idx >= map->nr)
> -		return id;
> +		return cpu_map__empty_aggr_cpu_id();
>  
> -	id.node = cpu_map__get_node_id(map->map[idx]);
> -	return id;
> +	return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
>  }
>  
>  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index a27eeaf086e8..c62d67704425 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -31,13 +31,17 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
>  size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
>  size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
>  int cpu_map__get_socket_id(int cpu);
> +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
>  struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
>  int cpu_map__get_die_id(int cpu);
> +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
>  struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
>  int cpu_map__get_core_id(int cpu);
> +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
>  struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
>  int cpu_map__get_node_id(int cpu);
> -struct aggr_cpu_id  cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
> +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
>  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
>  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
>  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
> -- 
> 2.34.1.448.ga2b2bfdf31-goog

-- 

- Arnaldo


From irogers at google.com  Tue Jan 11 11:36:02 2022
From: irogers at google.com (Ian Rogers)
Date: Tue, 11 Jan 2022 11:36:02 -0800
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <Yd3bbelDA1qGPodk@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <Yd3bbelDA1qGPodk@kernel.org>
Message-ID: <CAP-5=fVSuF-BCKuv6dutwLaAEKOctNYPtHzGYYDzZ7cm0110GQ@mail.gmail.com>

On Tue, Jan 11, 2022 at 11:33 AM Arnaldo Carvalho de Melo
<acme at kernel.org> wrote:
>
> Em Tue, Jan 04, 2022 at 10:13:05PM -0800, Ian Rogers escreveu:
> > The cpu_map and index can get confused. Add variants of the cpu_map__get
> > routines that are passed a cpu. Make the existing cpu_map__get routines
> > use the new functions with a view to remove them when no longer used.
> >
> > Reviewed-by: James Clark <james.clark at arm.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/util/cpumap.c | 79 +++++++++++++++++++++++-----------------
> >  tools/perf/util/cpumap.h |  6 ++-
> >  2 files changed, 51 insertions(+), 34 deletions(-)
> >
> > diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> > index 87d3eca9b872..49fba2c53822 100644
> > --- a/tools/perf/util/cpumap.c
> > +++ b/tools/perf/util/cpumap.c
> > @@ -128,21 +128,23 @@ int cpu_map__get_socket_id(int cpu)
> >       return ret ?: value;
> >  }
> >
> > -struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > -                                     void *data __maybe_unused)
> > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
> >  {
> > -     int cpu;
> >       struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> >
> > -     if (idx > map->nr)
> > -             return id;
> > -
> > -     cpu = map->map[idx];
> > -
> >       id.socket = cpu_map__get_socket_id(cpu);
> >       return id;
> >  }
> >
> > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > +                                    void *data)
> > +{
> > +     if (idx < 0 || idx > map->nr)
> > +             return cpu_map__empty_aggr_cpu_id();
> > +
> > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
>
>
> This 'idx < 0' wasn't in the original code nor is described in the
> comment log message, please avoid doing this, this may be harmless or
> even a good hardening, but either way would be interesting to have it in
> a separate patch. This eases review as in the end this code is just a
> refactoring, moving things around but in the end should be equivalent code.
>
> There are a few more, please consider this and if you agree, to speed
> things up I can make the changes here, if I think this won't fallout in
> changes to subsequent patches touching this area.
>
> - Arnaldo

Fwiw, there's the same issue in cpu_map__get_die that's also in
cpu_map__get_core, but weirdly not copied into cpu_map__get_node. As
these functions are removed later I think doing nothing is best here.

Thanks,
Ian

> >  static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
> >  {
> >       struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
> > @@ -200,15 +202,10 @@ int cpu_map__get_die_id(int cpu)
> >       return ret ?: value;
> >  }
> >
> > -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data)
> > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
> >  {
> > -     int cpu, die;
> > -     struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > -
> > -     if (idx > map->nr)
> > -             return id;
> > -
> > -     cpu = map->map[idx];
> > +     struct aggr_cpu_id id;
> > +     int die;
> >
> >       die = cpu_map__get_die_id(cpu);
> >       /* There is no die_id on legacy system. */
> > @@ -220,7 +217,7 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> >        * with the socket ID and then add die to
> >        * make a unique ID.
> >        */
> > -     id = cpu_map__get_socket(map, idx, data);
> > +     id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
> >       if (cpu_map__aggr_cpu_id_is_empty(id))
> >               return id;
> >
> > @@ -228,6 +225,15 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> >       return id;
> >  }
> >
> > +struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
> > +                                 void *data)
> > +{
> > +     if (idx < 0 || idx > map->nr)
> > +             return cpu_map__empty_aggr_cpu_id();
>
> Ditto
>
> > +
> > +     return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
> >  int cpu_map__get_core_id(int cpu)
> >  {
> >       int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
> > @@ -239,20 +245,13 @@ int cpu_map__get_node_id(int cpu)
> >       return cpu__get_node(cpu);
> >  }
> >
> > -struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
> >  {
> > -     int cpu;
> > -     struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > -
> > -     if (idx > map->nr)
> > -             return id;
> > -
> > -     cpu = map->map[idx];
> > -
> > -     cpu = cpu_map__get_core_id(cpu);
> > +     struct aggr_cpu_id id;
> > +     int core = cpu_map__get_core_id(cpu);
> >
> >       /* cpu_map__get_die returns a struct with socket and die set*/
> > -     id = cpu_map__get_die(map, idx, data);
> > +     id = cpu_map__get_die_aggr_by_cpu(cpu, data);
> >       if (cpu_map__aggr_cpu_id_is_empty(id))
> >               return id;
> >
> > @@ -260,19 +259,33 @@ struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *da
> >        * core_id is relative to socket and die, we need a global id.
> >        * So we combine the result from cpu_map__get_die with the core id
> >        */
> > -     id.core = cpu;
> > +     id.core = core;
> >       return id;
> > +
> >  }
> >
> > -struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data __maybe_unused)
> > +struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > +{
> > +     if (idx < 0 || idx > map->nr)
> > +             return cpu_map__empty_aggr_cpu_id();
>
> Ditto
>
> > +
> > +     return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
> > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
> >  {
> >       struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> >
> > +     id.node = cpu_map__get_node_id(cpu);
> > +     return id;
> > +}
> > +
> > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
> > +{
> >       if (idx < 0 || idx >= map->nr)
> > -             return id;
> > +             return cpu_map__empty_aggr_cpu_id();
> >
> > -     id.node = cpu_map__get_node_id(map->map[idx]);
> > -     return id;
> > +     return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
> >  }
> >
> >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
> > diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> > index a27eeaf086e8..c62d67704425 100644
> > --- a/tools/perf/util/cpumap.h
> > +++ b/tools/perf/util/cpumap.h
> > @@ -31,13 +31,17 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
> >  size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
> >  size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
> >  int cpu_map__get_socket_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_die_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_core_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_node_id(int cpu);
> > -struct aggr_cpu_id  cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
> > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
> >  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
> >  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
>
> --
>
> - Arnaldo


From acme at kernel.org  Tue Jan 11 11:49:54 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 16:49:54 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <Yd3bbelDA1qGPodk@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <Yd3bbelDA1qGPodk@kernel.org>
Message-ID: <Yd3fYqKi9X+fonEn@kernel.org>

Em Tue, Jan 11, 2022 at 04:33:01PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 04, 2022 at 10:13:05PM -0800, Ian Rogers escreveu:
> > The cpu_map and index can get confused. Add variants of the cpu_map__get
> > routines that are passed a cpu. Make the existing cpu_map__get routines
> > use the new functions with a view to remove them when no longer used.
> > 
> > Reviewed-by: James Clark <james.clark at arm.com>
> > Signed-off-by: Ian Rogers <irogers at google.com>
> > ---
> >  tools/perf/util/cpumap.c | 79 +++++++++++++++++++++++-----------------
> >  tools/perf/util/cpumap.h |  6 ++-
> >  2 files changed, 51 insertions(+), 34 deletions(-)
> > 
> > diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> > index 87d3eca9b872..49fba2c53822 100644
> > --- a/tools/perf/util/cpumap.c
> > +++ b/tools/perf/util/cpumap.c
> > @@ -128,21 +128,23 @@ int cpu_map__get_socket_id(int cpu)
> >  	return ret ?: value;
> >  }
> >  
> > -struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > -					void *data __maybe_unused)
> > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
> >  {
> > -	int cpu;
> >  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> >  
> > -	if (idx > map->nr)
> > -		return id;
> > -
> > -	cpu = map->map[idx];
> > -
> >  	id.socket = cpu_map__get_socket_id(cpu);
> >  	return id;
> >  }
> >  
> > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > +				       void *data)
> > +{
> > +	if (idx < 0 || idx > map->nr)
> > +		return cpu_map__empty_aggr_cpu_id();
> > +
> > +	return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
> 
> 
> This 'idx < 0' wasn't in the original code nor is described in the
> comment log message, please avoid doing this, this may be harmless or
> even a good hardening, but either way would be interesting to have it in
> a separate patch. This eases review as in the end this code is just a
> refactoring, moving things around but in the end should be equivalent code.
> 
> There are a few more, please consider this and if you agree, to speed
> things up I can make the changes here, if I think this won't fallout in
> changes to subsequent patches touching this area.

Nah, should be harmless, and its too much work already, so lets leave it
as-is, but please consider this in the future.

- Arnaldo
 
> - Arnaldo
> 
> >  static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
> >  {
> >  	struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
> > @@ -200,15 +202,10 @@ int cpu_map__get_die_id(int cpu)
> >  	return ret ?: value;
> >  }
> >  
> > -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data)
> > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
> >  {
> > -	int cpu, die;
> > -	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > -
> > -	if (idx > map->nr)
> > -		return id;
> > -
> > -	cpu = map->map[idx];
> > +	struct aggr_cpu_id id;
> > +	int die;
> >  
> >  	die = cpu_map__get_die_id(cpu);
> >  	/* There is no die_id on legacy system. */
> > @@ -220,7 +217,7 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> >  	 * with the socket ID and then add die to
> >  	 * make a unique ID.
> >  	 */
> > -	id = cpu_map__get_socket(map, idx, data);
> > +	id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
> >  	if (cpu_map__aggr_cpu_id_is_empty(id))
> >  		return id;
> >  
> > @@ -228,6 +225,15 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> >  	return id;
> >  }
> >  
> > +struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
> > +				    void *data)
> > +{
> > +	if (idx < 0 || idx > map->nr)
> > +		return cpu_map__empty_aggr_cpu_id();
> 
> Ditto
> 
> > +
> > +	return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
> >  int cpu_map__get_core_id(int cpu)
> >  {
> >  	int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
> > @@ -239,20 +245,13 @@ int cpu_map__get_node_id(int cpu)
> >  	return cpu__get_node(cpu);
> >  }
> >  
> > -struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
> >  {
> > -	int cpu;
> > -	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > -
> > -	if (idx > map->nr)
> > -		return id;
> > -
> > -	cpu = map->map[idx];
> > -
> > -	cpu = cpu_map__get_core_id(cpu);
> > +	struct aggr_cpu_id id;
> > +	int core = cpu_map__get_core_id(cpu);
> >  
> >  	/* cpu_map__get_die returns a struct with socket and die set*/
> > -	id = cpu_map__get_die(map, idx, data);
> > +	id = cpu_map__get_die_aggr_by_cpu(cpu, data);
> >  	if (cpu_map__aggr_cpu_id_is_empty(id))
> >  		return id;
> >  
> > @@ -260,19 +259,33 @@ struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *da
> >  	 * core_id is relative to socket and die, we need a global id.
> >  	 * So we combine the result from cpu_map__get_die with the core id
> >  	 */
> > -	id.core = cpu;
> > +	id.core = core;
> >  	return id;
> > +
> >  }
> >  
> > -struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data __maybe_unused)
> > +struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > +{
> > +	if (idx < 0 || idx > map->nr)
> > +		return cpu_map__empty_aggr_cpu_id();
> 
> Ditto
> 
> > +
> > +	return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
> > +}
> > +
> > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
> >  {
> >  	struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> >  
> > +	id.node = cpu_map__get_node_id(cpu);
> > +	return id;
> > +}
> > +
> > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
> > +{
> >  	if (idx < 0 || idx >= map->nr)
> > -		return id;
> > +		return cpu_map__empty_aggr_cpu_id();
> >  
> > -	id.node = cpu_map__get_node_id(map->map[idx]);
> > -	return id;
> > +	return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
> >  }
> >  
> >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
> > diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> > index a27eeaf086e8..c62d67704425 100644
> > --- a/tools/perf/util/cpumap.h
> > +++ b/tools/perf/util/cpumap.h
> > @@ -31,13 +31,17 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
> >  size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
> >  size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
> >  int cpu_map__get_socket_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_die_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_core_id(int cpu);
> > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
> >  struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__get_node_id(int cpu);
> > -struct aggr_cpu_id  cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
> > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
> >  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
> >  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
> > -- 
> > 2.34.1.448.ga2b2bfdf31-goog
> 
> -- 
> 
> - Arnaldo

-- 

- Arnaldo


From nicolas at ndufresne.ca  Tue Jan 11 11:55:35 2022
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Tue, 11 Jan 2022 14:55:35 -0500
Subject: [PATCH v4, 00/15] media: mtk-vcodec: support for MT8192 decoder
In-Reply-To: <20220110083442.32604-1-yunfei.dong@mediatek.com>
References: <20220110083442.32604-1-yunfei.dong@mediatek.com>
Message-ID: <91a41f3a17f94d25f84054daa1854603d113ecaf.camel@ndufresne.ca>

Hello Yunfei,

Le lundi 10 janvier 2022 ? 16:34 +0800, Yunfei Dong a ?crit?:
> This series adds support for mt8192 h264/vp8/vp9 decoder drivers. Firstly, refactor
> power/clock/interrupt interfaces for mt8192 is lat and core architecture.
> 
> Secondly, add new functions to get frame buffer size and resolution according
> to decoder capability from scp side. Then add callback function to get/put
> capture buffer in order to enable lat and core decoder in parallel. 
> 
> Then add to support MT21C compressed mode and fix v4l2-compliance fail.

Perhaps you wanted to append the referred v4l2-compliance output (fixed) ?

As we started doing with other codec driver submission (just did last month for
NXP), can you state which software this driver was tested with ? I have started
receiving feedback from third party that MTK driver support is not reproducible,
I would like to work with you to fix the situation.

regards,
Nicolas

> 
> Next, extract H264 request api driver to let mt8183 and mt8192 use the same
> code, and adds mt8192 frame based h264 driver for stateless decoder.
> 
> Lastly, add vp8 and vp9 stateless decoder drivers.
> 
> Patches 1 to refactor power/clock/interrupt interface.
> Patches 2~4 get frame buffer size and resolution according to decoder capability.
> Patches 5~6 enable lat and core decode in parallel.
> Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail.
> patch 11 record capture queue format type.
> Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder.
> Patch 14~15 add vp8 and vp9 stateless decoder drivers.
> ----
> Dependents on "Support multi hardware decode using of_platform_populate"[1].
> 
> This patches are the second part used to add mt8192 h264 decoder. And the base part is [1].
> 
> [1]https://patchwork.linuxtv.org/project/linux-media/cover/20211215061552.8523-1-yunfei.dong at mediatek.com/
> ---
> changes compared with v3:
> - remove enum mtk_chip for patch 2.
> - add vp8 stateless decoder drivers for patch 14.
> - add vp9 stateless decoder drivers for patch 15.
> changes compared with v2:
> - add new patch 11 to record capture queue format type.
> - separate patch 4 according to tzung-bi's suggestion.
> - re-write commit message for patch 5 according to tzung-bi's suggestion.
> changes compared with v1:
> - rewrite commit message for patch 12.
> - rewrite cover-letter message.
> ---
> Yunfei Dong (15):
>   media: mtk-vcodec: Add vdec enable/disable hardware helpers
>   media: mtk-vcodec: Using firmware type to separate different firmware
>     architecture
>   media: mtk-vcodec: get capture queue buffer size from scp
>   media: mtk-vcodec: Read max resolution from dec_capability
>   media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer
>     buffered
>   media: mtk-vcodec: Refactor get and put capture buffer flow
>   media: mtk-vcodec: Refactor supported vdec formats and framesizes
>   media: mtk-vcodec: Add format to support MT21C
>   media: mtk-vcodec: disable vp8 4K capability
>   media: mtk-vcodec: Fix v4l2-compliance fail
>   media: mtk-vcodec: record capture queue format type
>   media: mtk-vcodec: Extract H264 common code
>   media: mtk-vcodec: Add h264 decoder driver for mt8192
>   media: mtk-vcodec: Add vp8 decoder driver for mt8192
>   media: mtk-vcodec: Add vp9 decoder driver for mt8192
> 
>  drivers/media/platform/mtk-vcodec/Makefile    |    4 +
>  .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   49 +-
>  .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |    5 -
>  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  168 +-
>  .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |    6 +-
>  .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   14 +-
>  .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  284 ++-
>  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   40 +-
>  .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |    5 -
>  .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |    6 +
>  .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |    1 +
>  .../mtk-vcodec/vdec/vdec_h264_req_common.c    |  311 +++
>  .../mtk-vcodec/vdec/vdec_h264_req_common.h    |  254 ++
>  .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  416 +---
>  .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  |  605 +++++
>  .../mtk-vcodec/vdec/vdec_vp8_req_if.c         |  445 ++++
>  .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 2066 +++++++++++++++++
>  .../media/platform/mtk-vcodec/vdec_drv_if.c   |   36 +-
>  .../media/platform/mtk-vcodec/vdec_drv_if.h   |    3 +
>  .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |   37 +
>  .../platform/mtk-vcodec/vdec_msg_queue.c      |    2 +
>  .../media/platform/mtk-vcodec/vdec_vpu_if.c   |   54 +-
>  .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   15 +
>  .../media/platform/mtk-vcodec/venc_vpu_if.c   |    2 +-
>  include/linux/remoteproc/mtk_scp.h            |    2 +
>  25 files changed, 4248 insertions(+), 582 deletions(-)
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
>  create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
> 



From acme at kernel.org  Tue Jan 11 11:56:31 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 16:56:31 -0300
Subject: [PATCH v4 02/48] perf stat: Add aggr creators that are passed a
 cpu.
In-Reply-To: <CAP-5=fVSuF-BCKuv6dutwLaAEKOctNYPtHzGYYDzZ7cm0110GQ@mail.gmail.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-3-irogers@google.com>
 <Yd3bbelDA1qGPodk@kernel.org>
 <CAP-5=fVSuF-BCKuv6dutwLaAEKOctNYPtHzGYYDzZ7cm0110GQ@mail.gmail.com>
Message-ID: <Yd3g7+y0ZeUHt+Rx@kernel.org>

Em Tue, Jan 11, 2022 at 11:36:02AM -0800, Ian Rogers escreveu:
> On Tue, Jan 11, 2022 at 11:33 AM Arnaldo Carvalho de Melo
> <acme at kernel.org> wrote:
> >
> > Em Tue, Jan 04, 2022 at 10:13:05PM -0800, Ian Rogers escreveu:
> > > The cpu_map and index can get confused. Add variants of the cpu_map__get
> > > routines that are passed a cpu. Make the existing cpu_map__get routines
> > > use the new functions with a view to remove them when no longer used.
> > >
> > > Reviewed-by: James Clark <james.clark at arm.com>
> > > Signed-off-by: Ian Rogers <irogers at google.com>
> > > ---
> > >  tools/perf/util/cpumap.c | 79 +++++++++++++++++++++++-----------------
> > >  tools/perf/util/cpumap.h |  6 ++-
> > >  2 files changed, 51 insertions(+), 34 deletions(-)
> > >
> > > diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> > > index 87d3eca9b872..49fba2c53822 100644
> > > --- a/tools/perf/util/cpumap.c
> > > +++ b/tools/perf/util/cpumap.c
> > > @@ -128,21 +128,23 @@ int cpu_map__get_socket_id(int cpu)
> > >       return ret ?: value;
> > >  }
> > >
> > > -struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > > -                                     void *data __maybe_unused)
> > > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data __maybe_unused)
> > >  {
> > > -     int cpu;
> > >       struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > >
> > > -     if (idx > map->nr)
> > > -             return id;
> > > -
> > > -     cpu = map->map[idx];
> > > -
> > >       id.socket = cpu_map__get_socket_id(cpu);
> > >       return id;
> > >  }
> > >
> > > +struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx,
> > > +                                    void *data)
> > > +{
> > > +     if (idx < 0 || idx > map->nr)
> > > +             return cpu_map__empty_aggr_cpu_id();
> > > +
> > > +     return cpu_map__get_socket_aggr_by_cpu(map->map[idx], data);
> > > +}
> > > +
> >
> >
> > This 'idx < 0' wasn't in the original code nor is described in the
> > comment log message, please avoid doing this, this may be harmless or
> > even a good hardening, but either way would be interesting to have it in
> > a separate patch. This eases review as in the end this code is just a
> > refactoring, moving things around but in the end should be equivalent code.
> >
> > There are a few more, please consider this and if you agree, to speed
> > things up I can make the changes here, if I think this won't fallout in
> > changes to subsequent patches touching this area.
> >
> > - Arnaldo
> 
> Fwiw, there's the same issue in cpu_map__get_die that's also in
> cpu_map__get_core, but weirdly not copied into cpu_map__get_node. As
> these functions are removed later I think doing nothing is best here.

Sure.
 
> Thanks,
> Ian
> 
> > >  static int cmp_aggr_cpu_id(const void *a_pointer, const void *b_pointer)
> > >  {
> > >       struct aggr_cpu_id *a = (struct aggr_cpu_id *)a_pointer;
> > > @@ -200,15 +202,10 @@ int cpu_map__get_die_id(int cpu)
> > >       return ret ?: value;
> > >  }
> > >
> > > -struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data)
> > > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data)
> > >  {
> > > -     int cpu, die;
> > > -     struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > > -
> > > -     if (idx > map->nr)
> > > -             return id;
> > > -
> > > -     cpu = map->map[idx];
> > > +     struct aggr_cpu_id id;
> > > +     int die;
> > >
> > >       die = cpu_map__get_die_id(cpu);
> > >       /* There is no die_id on legacy system. */
> > > @@ -220,7 +217,7 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> > >        * with the socket ID and then add die to
> > >        * make a unique ID.
> > >        */
> > > -     id = cpu_map__get_socket(map, idx, data);
> > > +     id = cpu_map__get_socket_aggr_by_cpu(cpu, data);
> > >       if (cpu_map__aggr_cpu_id_is_empty(id))
> > >               return id;
> > >
> > > @@ -228,6 +225,15 @@ struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *dat
> > >       return id;
> > >  }
> > >
> > > +struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx,
> > > +                                 void *data)
> > > +{
> > > +     if (idx < 0 || idx > map->nr)
> > > +             return cpu_map__empty_aggr_cpu_id();
> >
> > Ditto
> >
> > > +
> > > +     return cpu_map__get_die_aggr_by_cpu(map->map[idx], data);
> > > +}
> > > +
> > >  int cpu_map__get_core_id(int cpu)
> > >  {
> > >       int value, ret = cpu__get_topology_int(cpu, "core_id", &value);
> > > @@ -239,20 +245,13 @@ int cpu_map__get_node_id(int cpu)
> > >       return cpu__get_node(cpu);
> > >  }
> > >
> > > -struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data)
> > >  {
> > > -     int cpu;
> > > -     struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > > -
> > > -     if (idx > map->nr)
> > > -             return id;
> > > -
> > > -     cpu = map->map[idx];
> > > -
> > > -     cpu = cpu_map__get_core_id(cpu);
> > > +     struct aggr_cpu_id id;
> > > +     int core = cpu_map__get_core_id(cpu);
> > >
> > >       /* cpu_map__get_die returns a struct with socket and die set*/
> > > -     id = cpu_map__get_die(map, idx, data);
> > > +     id = cpu_map__get_die_aggr_by_cpu(cpu, data);
> > >       if (cpu_map__aggr_cpu_id_is_empty(id))
> > >               return id;
> > >
> > > @@ -260,19 +259,33 @@ struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *da
> > >        * core_id is relative to socket and die, we need a global id.
> > >        * So we combine the result from cpu_map__get_die with the core id
> > >        */
> > > -     id.core = cpu;
> > > +     id.core = core;
> > >       return id;
> > > +
> > >  }
> > >
> > > -struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data __maybe_unused)
> > > +struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data)
> > > +{
> > > +     if (idx < 0 || idx > map->nr)
> > > +             return cpu_map__empty_aggr_cpu_id();
> >
> > Ditto
> >
> > > +
> > > +     return cpu_map__get_core_aggr_by_cpu(map->map[idx], data);
> > > +}
> > > +
> > > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data __maybe_unused)
> > >  {
> > >       struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
> > >
> > > +     id.node = cpu_map__get_node_id(cpu);
> > > +     return id;
> > > +}
> > > +
> > > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data)
> > > +{
> > >       if (idx < 0 || idx >= map->nr)
> > > -             return id;
> > > +             return cpu_map__empty_aggr_cpu_id();
> > >
> > > -     id.node = cpu_map__get_node_id(map->map[idx]);
> > > -     return id;
> > > +     return cpu_map__get_node_aggr_by_cpu(map->map[idx], data);
> > >  }
> > >
> > >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp)
> > > diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> > > index a27eeaf086e8..c62d67704425 100644
> > > --- a/tools/perf/util/cpumap.h
> > > +++ b/tools/perf/util/cpumap.h
> > > @@ -31,13 +31,17 @@ size_t cpu_map__snprint(struct perf_cpu_map *map, char *buf, size_t size);
> > >  size_t cpu_map__snprint_mask(struct perf_cpu_map *map, char *buf, size_t size);
> > >  size_t cpu_map__fprintf(struct perf_cpu_map *map, FILE *fp);
> > >  int cpu_map__get_socket_id(int cpu);
> > > +struct aggr_cpu_id cpu_map__get_socket_aggr_by_cpu(int cpu, void *data);
> > >  struct aggr_cpu_id cpu_map__get_socket(struct perf_cpu_map *map, int idx, void *data);
> > >  int cpu_map__get_die_id(int cpu);
> > > +struct aggr_cpu_id cpu_map__get_die_aggr_by_cpu(int cpu, void *data);
> > >  struct aggr_cpu_id cpu_map__get_die(struct perf_cpu_map *map, int idx, void *data);
> > >  int cpu_map__get_core_id(int cpu);
> > > +struct aggr_cpu_id cpu_map__get_core_aggr_by_cpu(int cpu, void *data);
> > >  struct aggr_cpu_id cpu_map__get_core(struct perf_cpu_map *map, int idx, void *data);
> > >  int cpu_map__get_node_id(int cpu);
> > > -struct aggr_cpu_id  cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> > > +struct aggr_cpu_id cpu_map__get_node_aggr_by_cpu(int cpu, void *data);
> > > +struct aggr_cpu_id cpu_map__get_node(struct perf_cpu_map *map, int idx, void *data);
> > >  int cpu_map__build_socket_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **sockp);
> > >  int cpu_map__build_die_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **diep);
> > >  int cpu_map__build_core_map(struct perf_cpu_map *cpus, struct cpu_aggr_map **corep);
> > > --
> > > 2.34.1.448.ga2b2bfdf31-goog
> >
> > --
> >
> > - Arnaldo

-- 

- Arnaldo


From acme at kernel.org  Tue Jan 11 12:01:10 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 17:01:10 -0300
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <CAP-5=fWZWMweYhWvv1vr6quZe=ZJrhF_WEXqbELVitzofBcQrA@mail.gmail.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
 <YdyOFd8JJHbm1W+m@kernel.org>
 <CAP-5=fWZWMweYhWvv1vr6quZe=ZJrhF_WEXqbELVitzofBcQrA@mail.gmail.com>
Message-ID: <Yd3iBvVim1vB81pM@kernel.org>

Em Tue, Jan 11, 2022 at 11:16:16AM -0800, Ian Rogers escreveu:
> On Mon, Jan 10, 2022 at 11:50 AM Arnaldo Carvalho de Melo
> <acme at kernel.org> wrote:
> >
> > Em Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers escreveu:
> > > A common problem is confusing CPU map indices with the CPU, by wrapping
> > > the CPU with a struct then this is avoided. This approach is similar to
> > > atomic_t.
> >
> > This one needed this to build with BUILD_BPF_SKEL=1, please check, I'll
> > soon push this to tmp.perf/perf_cpu so that you can take a look and test
> > it.
> 
> 
> Thanks Arnaldo, I did eye-ball one issue where cpu_map__default_new's
> behavior would be impacted (nr would be 1 rather than nr_cpus). The
> fix is:
> 
> --- a/tools/lib/perf/cpumap.c
> +++ b/tools/lib/perf/cpumap.c
> @@ -18,7 +18,7 @@ static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
>         if (!cpus)
>                 return NULL;
> 
> -       cpus->nr = 1;
> +       cpus->nr = nr_cpus;
>         refcount_set(&cpus->refcnt, 1);
>         return cpus;
>  }

> Could you add that into this patch as well?

Sure.

I?m now running perf-test after each of those csets, so far so good.
 
> Thanks,
> Ian
> 
> 
> > - Arnaldo
> >
> > diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c
> > index 80d1a3a31052fe55..328479df5e16a638 100644
> > --- a/tools/perf/util/bpf_counter.c
> > +++ b/tools/perf/util/bpf_counter.c
> > @@ -540,7 +540,7 @@ static int bperf__load(struct evsel *evsel, struct target *target)
> >                     filter_type == BPERF_FILTER_TGID)
> >                         key = evsel->core.threads->map[i].pid;
> >                 else if (filter_type == BPERF_FILTER_CPU)
> > -                       key = evsel->core.cpus->map[i];
> > +                       key = evsel->core.cpus->map[i].cpu;
> >                 else
> >                         break;
> >
> > @@ -584,7 +584,7 @@ static int bperf_sync_counters(struct evsel *evsel)
> >
> >         num_cpu = all_cpu_map->nr;
> >         for (i = 0; i < num_cpu; i++) {
> > -               cpu = all_cpu_map->map[i];
> > +               cpu = all_cpu_map->map[i].cpu;
> >                 bperf_trigger_reading(evsel->bperf_leader_prog_fd, cpu);
> >         }
> >         return 0;
> > @@ -605,7 +605,7 @@ static int bperf__disable(struct evsel *evsel)
> >  static int bperf__read(struct evsel *evsel)
> >  {
> >         struct bperf_follower_bpf *skel = evsel->follower_skel;
> > -       __u32 num_cpu_bpf = cpu__max_cpu();
> > +       __u32 num_cpu_bpf = cpu__max_cpu().cpu;
> >         struct bpf_perf_event_value values[num_cpu_bpf];
> >         int reading_map_fd, err = 0;
> >         __u32 i;
> > @@ -615,6 +615,7 @@ static int bperf__read(struct evsel *evsel)
> >         reading_map_fd = bpf_map__fd(skel->maps.accum_readings);
> >
> >         for (i = 0; i < bpf_map__max_entries(skel->maps.accum_readings); i++) {
> > +               struct perf_cpu entry;
> >                 __u32 cpu;
> >
> >                 err = bpf_map_lookup_elem(reading_map_fd, &i, values);
> > @@ -624,14 +625,15 @@ static int bperf__read(struct evsel *evsel)
> >                 case BPERF_FILTER_GLOBAL:
> >                         assert(i == 0);
> >
> > -                       perf_cpu_map__for_each_cpu(cpu, j, all_cpu_map) {
> > +                       perf_cpu_map__for_each_cpu(entry, j, all_cpu_map) {
> > +                               cpu = entry.cpu;
> >                                 perf_counts(evsel->counts, cpu, 0)->val = values[cpu].counter;
> >                                 perf_counts(evsel->counts, cpu, 0)->ena = values[cpu].enabled;
> >                                 perf_counts(evsel->counts, cpu, 0)->run = values[cpu].running;
> >                         }
> >                         break;
> >                 case BPERF_FILTER_CPU:
> > -                       cpu = evsel->core.cpus->map[i];
> > +                       cpu = evsel->core.cpus->map[i].cpu;
> >                         perf_counts(evsel->counts, i, 0)->val = values[cpu].counter;
> >                         perf_counts(evsel->counts, i, 0)->ena = values[cpu].enabled;
> >                         perf_counts(evsel->counts, i, 0)->run = values[cpu].running;
> > diff --git a/tools/perf/util/bpf_counter_cgroup.c b/tools/perf/util/bpf_counter_cgroup.c
> > index cbc6c2bca488f6bf..631e34a0b66ff084 100644
> > --- a/tools/perf/util/bpf_counter_cgroup.c
> > +++ b/tools/perf/util/bpf_counter_cgroup.c
> > @@ -48,7 +48,7 @@ static int bperf_load_program(struct evlist *evlist)
> >         struct cgroup *cgrp, *leader_cgrp;
> >         __u32 i, cpu;
> >         __u32 nr_cpus = evlist->core.all_cpus->nr;
> > -       int total_cpus = cpu__max_cpu();
> > +       int total_cpus = cpu__max_cpu().cpu;
> >         int map_size, map_fd;
> >         int prog_fd, err;
> >
> > @@ -125,7 +125,7 @@ static int bperf_load_program(struct evlist *evlist)
> >                         for (cpu = 0; cpu < nr_cpus; cpu++) {
> >                                 int fd = FD(evsel, cpu);
> >                                 __u32 idx = evsel->core.idx * total_cpus +
> > -                                       evlist->core.all_cpus->map[cpu];
> > +                                       evlist->core.all_cpus->map[cpu].cpu;
> >
> >                                 err = bpf_map_update_elem(map_fd, &idx, &fd,
> >                                                           BPF_ANY);
> > @@ -212,7 +212,7 @@ static int bperf_cgrp__sync_counters(struct evlist *evlist)
> >         int prog_fd = bpf_program__fd(skel->progs.trigger_read);
> >
> >         for (i = 0; i < nr_cpus; i++) {
> > -               cpu = evlist->core.all_cpus->map[i];
> > +               cpu = evlist->core.all_cpus->map[i].cpu;
> >                 bperf_trigger_reading(prog_fd, cpu);
> >         }
> >
> > @@ -245,7 +245,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
> >  {
> >         struct evlist *evlist = evsel->evlist;
> >         int i, cpu, nr_cpus = evlist->core.all_cpus->nr;
> > -       int total_cpus = cpu__max_cpu();
> > +       int total_cpus = cpu__max_cpu().cpu;
> >         struct perf_counts_values *counts;
> >         struct bpf_perf_event_value *values;
> >         int reading_map_fd, err = 0;
> > @@ -272,7 +272,7 @@ static int bperf_cgrp__read(struct evsel *evsel)
> >                 }
> >
> >                 for (i = 0; i < nr_cpus; i++) {
> > -                       cpu = evlist->core.all_cpus->map[i];
> > +                       cpu = evlist->core.all_cpus->map[i].cpu;
> >
> >                         counts = perf_counts(evsel->counts, i, 0);
> >                         counts->val = values[cpu].counter;
> > diff --git a/tools/perf/util/bpf_ftrace.c b/tools/perf/util/bpf_ftrace.c
> > index 28dc4c60c7884818..d756cc66eef32ae8 100644
> > --- a/tools/perf/util/bpf_ftrace.c
> > +++ b/tools/perf/util/bpf_ftrace.c
> > @@ -63,7 +63,7 @@ int perf_ftrace__latency_prepare_bpf(struct perf_ftrace *ftrace)
> >                 fd = bpf_map__fd(skel->maps.cpu_filter);
> >
> >                 for (i = 0; i < ncpus; i++) {
> > -                       cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i);
> > +                       cpu = perf_cpu_map__cpu(ftrace->evlist->core.cpus, i).cpu;
> >                         bpf_map_update_elem(fd, &cpu, &val, BPF_ANY);
> >                 }
> >         }
> > @@ -122,7 +122,7 @@ int perf_ftrace__latency_read_bpf(struct perf_ftrace *ftrace __maybe_unused,
> >         int i, fd, err;
> >         u32 idx;
> >         u64 *hist;
> > -       int ncpus = cpu__max_cpu();
> > +       int ncpus = cpu__max_cpu().cpu;
> >
> >         fd = bpf_map__fd(skel->maps.latency);
> >

-- 

- Arnaldo


From rinni at inventati.org  Tue Jan 11 12:08:23 2022
From: rinni at inventati.org (Philip Rinn)
Date: Tue, 11 Jan 2022 21:08:23 +0100
Subject: [PATCH RESEND v3] arm64: dts: allwinner: a64: olinuxino: Enable audio
In-Reply-To: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
Message-ID: <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>

Enable the audio hardware on the Olimex A64-OLinuXino board family.
Tested on the A64-OLinuXino-2Ge8G-IND variant.

Signed-off-by: Philip Rinn <rinni at inventati.org>

---


Changes in v2: added missing &sound {...} part
Changes in v3: removed HDMI audio part as requested by Jernej ?krabec

  arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts    | 30 +++++++++++++++++++

  1 file changed, 30 insertions(+)



diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts

index ec7e2c0e82c1..6f2674bb1b7f 100644

--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts

+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts

@@ -58,6 +58,15 @@ wifi_pwrseq: wifi_pwrseq {

  	};

  };

  

+&codec {

+	status = "okay";

+};

+

+&codec_analog {

+	cpvdd-supply = <&reg_eldo1>;

+	status = "okay";

+};

+

  &cpu0 {

  	cpu-supply = <&reg_dcdc2>;

  };

@@ -74,6 +83,10 @@ &cpu3 {

  	cpu-supply = <&reg_dcdc2>;

  };

  

+&dai {

+	status = "okay";

+};

+

  &de {

  	status = "okay";

  };

@@ -328,6 +341,23 @@ &simplefb_hdmi {

  	vcc-hdmi-supply = <&reg_dldo1>;

  };

  

+&sound {

+	simple-audio-card,aux-devs = <&codec_analog>;

+	simple-audio-card,widgets = "Microphone", "Microphone Jack Left",

+		    "Microphone", "Microphone Jack Right",

+		    "Headphone", "Headphone Jack";

+	simple-audio-card,routing = "Left DAC", "DACL",

+		    "Right DAC", "DACR",

+		    "Headphone Jack", "HP",

+		    "ADCL", "Left ADC",

+		    "ADCR", "Right ADC",

+		    "Microphone Jack Left", "MBIAS",

+		    "MIC1", "Microphone Jack Left",

+		    "Microphone Jack Left", "HBIAS",

+		    "MIC2", "Microphone Jack Right";

+	status = "okay";

+};

+

  &uart0 {

  	pinctrl-names = "default";

  	pinctrl-0 = <&uart0_pb_pins>;

-- 

2.34.1


-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220111/8c9d481b/attachment.sig>

From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:14:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:14:02 +0100
Subject: [PATCH v2 04/28] ARM: dts: exynos: simplify PMIC DVS pin
 configuration in Odroid XU
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-5-krzysztof.kozlowski@canonical.com>

The pin configuration for PMIC DVS (pmic-dvs-2 and pmic-dvs-3) are
exactly the same, so merge them.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5410-odroidxu.dts | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index 884fef55836c..9f2200dd5b43 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -188,8 +188,7 @@ max77802: pmic at 9 {
 		interrupt-parent = <&gpx0>;
 		interrupts = <4 IRQ_TYPE_NONE>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&max77802_irq>, <&pmic_dvs_1>, <&pmic_dvs_2>,
-			    <&pmic_dvs_3>;
+		pinctrl-0 = <&max77802_irq>, <&pmic_dvs_1>, <&pmic_dvs_2>;
 		wakeup-source;
 		#clock-cells = <1>;
 
@@ -563,15 +562,8 @@ sd2_wp: sd2-wp {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	pmic_dvs_3: pmic-dvs-3 {
-		samsung,pins = "gpx0-0";
-		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-	};
-
 	pmic_dvs_2: pmic-dvs-2 {
-		samsung,pins = "gpx0-1";
+		samsung,pins = "gpx0-0", "gpx0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:14:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:14:01 +0100
Subject: [PATCH v2 03/28] ARM: dts: exynos: drop unused pinctrl defines in
 Exynos3250
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-4-krzysztof.kozlowski@canonical.com>

The PIN_OUT/PIN_OUT_SET/PIN_CFG defines for pin controller pin
configuration are not used.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 25 -----------------------
 1 file changed, 25 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index dff3c6e3aa1f..a616cb1aca29 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -19,31 +19,6 @@ _pin {								\
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;		\
 	}
 
-#define PIN_OUT(_pin, _drv)						\
-	_pin {								\
-		samsung,pins = #_pin;					\
-		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;	\
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;		\
-		samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;		\
-	}
-
-#define PIN_OUT_SET(_pin, _val, _drv)					\
-	_pin {								\
-		samsung,pins = #_pin;					\
-		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;	\
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;		\
-		samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;		\
-		samsung,pin-val = <_val>;				\
-	}
-
-#define PIN_CFG(_pin, _sel, _pull, _drv)				\
-	_pin {								\
-		samsung,pins = #_pin;					\
-		samsung,pin-function = <_sel>;				\
-		samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>;		\
-		samsung,pin-drv = <EXYNOS4_PIN_DRV_ ##_drv>;		\
-	}
-
 #define PIN_SLP(_pin, _mode, _pull)					\
 	_pin {								\
 		samsung,pins = #_pin;					\
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:13:59 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:13:59 +0100
Subject: [PATCH v2 01/28] pinctrl: samsung: drop pin banks references on error
 paths
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-2-krzysztof.kozlowski@canonical.com>

The driver iterates over its devicetree children with
for_each_child_of_node() and stores for later found node pointer.  This
has to be put in error paths to avoid leak during re-probing.

Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device nodes")
Cc: <stable at vger.kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/pinctrl/samsung/pinctrl-samsung.c | 30 +++++++++++++++++------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 8941f658e7f1..b19ebc43d886 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1002,6 +1002,16 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
 	return &(of_data->ctrl[id]);
 }
 
+static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
+{
+	struct samsung_pin_bank *bank;
+	unsigned int i;
+
+	bank = d->pin_banks;
+	for (i = 0; i < d->nr_banks; ++i, ++bank)
+		of_node_put(bank->of_node);
+}
+
 /* retrieve the soc specific data */
 static const struct samsung_pin_ctrl *
 samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
@@ -1116,19 +1126,19 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
 	if (ctrl->retention_data) {
 		drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,
 							  ctrl->retention_data);
-		if (IS_ERR(drvdata->retention_ctrl))
-			return PTR_ERR(drvdata->retention_ctrl);
+		if (IS_ERR(drvdata->retention_ctrl)) {
+			ret = PTR_ERR(drvdata->retention_ctrl);
+			goto err_put_banks;
+		}
 	}
 
 	ret = samsung_pinctrl_register(pdev, drvdata);
 	if (ret)
-		return ret;
+		goto err_put_banks;
 
 	ret = samsung_gpiolib_register(pdev, drvdata);
-	if (ret) {
-		samsung_pinctrl_unregister(pdev, drvdata);
-		return ret;
-	}
+	if (ret)
+		goto err_unregister;
 
 	if (ctrl->eint_gpio_init)
 		ctrl->eint_gpio_init(drvdata);
@@ -1138,6 +1148,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, drvdata);
 
 	return 0;
+
+err_unregister:
+	samsung_pinctrl_unregister(pdev, drvdata);
+err_put_banks:
+	samsung_banks_of_node_put(drvdata);
+	return ret;
 }
 
 /*
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:13:58 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:13:58 +0100
Subject: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to dtschema
Message-ID: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v1
================
1. Patch #1: add missing pin assignment (Alim).
2. Patch #2: correct double sizeof() (Alim).
3. Patch #7, #8: put label-override in proper patch (Alim).
4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
5. New patches: #25 - #28.
   Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
   handling, so they need their own compatibles.
   Please kindly review and provide feedback on these as I do not have
   details.
6. Add review tags.

Dependencies
============
1. Patch #2 ("pinctrl: samsung: accept GPIO bank nodes with a suffix") is
   necessary for DTS patches.

2. Last patches #27 and #28 depend on patch #26 adding the compatibles.

Best regards,
Krzysztof

Krzysztof Kozlowski (28):
  pinctrl: samsung: drop pin banks references on error paths
  pinctrl: samsung: accept GPIO bank nodes with a suffix
  ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
  ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
  ARM: dts: exynos: override pins by label in Peach Pit
  ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
  ARM: dts: exynos: override pins by label in Peach Pi
  ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
  ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
  ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
  ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
  ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
  ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
  ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
  ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
  ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
  arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
  arm64: dts: exynos: align pinctrl with dtschema in Exynos7
  arm64: dts: exynos: align pinctrl with dtschema in Exynos850
  arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
  ARM: dts: s3c24xx: align pinctrl with dtschema
  ARM: dts: s3c64xx: align pinctrl with dtschema
  ARM: dts: s5pv210: align pinctrl with dtschema
  dt-bindings: pinctrl: samsung: convert to dtschema
  dt-bindings: pinctrl: samsung: describe Exynos850 and ExynosAutov9
    wake-ups
  pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups
  arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
    Exynos850
  arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
    ExynosAutov9

 .../pinctrl/samsung,pinctrl-gpio-bank.yaml    |  52 +++
 .../pinctrl/samsung,pinctrl-pins-cfg.yaml     |  81 ++++
 .../samsung,pinctrl-wakeup-interrupt.yaml     | 106 +++++
 .../bindings/pinctrl/samsung,pinctrl.yaml     | 392 ++++++++++++++++++
 .../bindings/pinctrl/samsung-pinctrl.txt      | 383 -----------------
 MAINTAINERS                                   |   2 +-
 arch/arm/boot/dts/exynos3250-artik5.dtsi      |  10 +-
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi     | 165 ++++----
 arch/arm/boot/dts/exynos4210-i9100.dts        |  30 +-
 arch/arm/boot/dts/exynos4210-origen.dts       |   2 +-
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi     | 226 +++++-----
 arch/arm/boot/dts/exynos4210-smdkv310.dts     |   4 +-
 arch/arm/boot/dts/exynos4210-trats.dts        |   6 +-
 .../boot/dts/exynos4210-universal_c210.dts    |  12 +-
 arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi   |   4 +-
 arch/arm/boot/dts/exynos4412-itop-elite.dts   |   2 +-
 .../boot/dts/exynos4412-itop-scp-core.dtsi    |   2 +-
 arch/arm/boot/dts/exynos4412-midas.dtsi       |  30 +-
 .../boot/dts/exynos4412-odroid-common.dtsi    |   8 +-
 arch/arm/boot/dts/exynos4412-odroidx.dts      |   2 +-
 arch/arm/boot/dts/exynos4412-origen.dts       |   4 +-
 arch/arm/boot/dts/exynos4412-p4note.dtsi      |  44 +-
 arch/arm/boot/dts/exynos4412-pinctrl.dtsi     | 252 +++++------
 arch/arm/boot/dts/exynos4412-smdk4412.dts     |   4 +-
 arch/arm/boot/dts/exynos5250-arndale.dts      |   2 +-
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi     | 220 +++++-----
 arch/arm/boot/dts/exynos5250-smdk5250.dts     |   2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi |  22 +-
 arch/arm/boot/dts/exynos5250-snow-rev5.dts    |   2 +-
 arch/arm/boot/dts/exynos5250-snow.dts         |   2 +-
 arch/arm/boot/dts/exynos5250-spring.dts       |  20 +-
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi     | 148 +++----
 arch/arm/boot/dts/exynos5260-xyref5260.dts    |   2 +-
 arch/arm/boot/dts/exynos5410-odroidxu.dts     |  22 +-
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi     | 170 ++++----
 arch/arm/boot/dts/exynos5410-smdk5410.dts     |   4 +-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts |   2 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts    |  89 ++--
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi     | 194 ++++-----
 arch/arm/boot/dts/exynos5420-smdk5420.dts     |   6 +-
 arch/arm/boot/dts/exynos5422-odroid-core.dtsi |   2 +-
 .../boot/dts/exynos5422-odroidxu3-common.dtsi |   6 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts     |  89 ++--
 arch/arm/boot/dts/s3c2416-pinctrl.dtsi        |  60 +--
 arch/arm/boot/dts/s3c6410-mini6410.dts        |   4 +-
 arch/arm/boot/dts/s3c64xx-pinctrl.dtsi        | 210 +++++-----
 arch/arm/boot/dts/s3c64xx.dtsi                |  16 +-
 arch/arm/boot/dts/s5pv210-aquila.dts          |   2 +-
 arch/arm/boot/dts/s5pv210-aries.dtsi          |  40 +-
 arch/arm/boot/dts/s5pv210-fascinate4g.dts     |  12 +-
 arch/arm/boot/dts/s5pv210-galaxys.dts         |  16 +-
 arch/arm/boot/dts/s5pv210-pinctrl.dtsi        | 226 +++++-----
 .../boot/dts/exynos/exynos5433-pinctrl.dtsi   | 211 +++++-----
 .../dts/exynos/exynos5433-tm2-common.dtsi     | 259 ++++++------
 .../boot/dts/exynos/exynos7-espresso.dts      |   6 +-
 .../boot/dts/exynos/exynos7-pinctrl.dtsi      | 176 ++++----
 .../boot/dts/exynos/exynos850-pinctrl.dtsi    |  52 +--
 arch/arm64/boot/dts/exynos/exynos850.dtsi     |   4 +-
 .../boot/dts/exynos/exynosautov9-pinctrl.dtsi |  50 +--
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi  |   2 +-
 drivers/pinctrl/samsung/pinctrl-exynos.c      |   4 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  87 +++-
 62 files changed, 2261 insertions(+), 2003 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:14:00 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:14:00 +0100
Subject: [PATCH v2 02/28] pinctrl: samsung: accept GPIO bank nodes with a
 suffix
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-3-krzysztof.kozlowski@canonical.com>

Existing dt-bindings expected that each GPIO/pin bank within pin
controller has its own node with name matching the bank (e.g. gpa0,
gpx2) and "gpio-controller" property.  The node name is then used for
matching between driver data and DTS.

Newly introduced dtschema expects to have nodes ending with "-gpio-bank"
suffix, so rewrite bank-devicetree matching to look for old and new
style of naming.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/pinctrl/samsung/pinctrl-samsung.c | 57 ++++++++++++++++++-----
 1 file changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index b19ebc43d886..b3a5bc473841 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1012,13 +1012,56 @@ static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
 		of_node_put(bank->of_node);
 }
 
+/*
+ * Iterate over all driver pin banks to find one matching the name of node,
+ * skipping optional "-gpio" node suffix. When found, assign node to the bank.
+ */
+static void samsung_banks_of_node_get(struct device *dev,
+				      struct samsung_pinctrl_drv_data *d,
+				      struct device_node *node)
+{
+	const char *suffix = "-gpio-bank";
+	struct samsung_pin_bank *bank;
+	struct device_node *child;
+	/* Pin bank names are up to 4 characters */
+	char node_name[20];
+	unsigned int i;
+	size_t len;
+
+	bank = d->pin_banks;
+	for (i = 0; i < d->nr_banks; ++i, ++bank) {
+		strscpy(node_name, bank->name, sizeof(node_name));
+		len = strlcat(node_name, suffix, sizeof(node_name));
+		if (len >= sizeof(node_name)) {
+			dev_err(dev, "Too long pin bank name '%s', ignoring\n",
+				bank->name);
+			continue;
+		}
+
+		for_each_child_of_node(node, child) {
+			if (!of_find_property(child, "gpio-controller", NULL))
+				continue;
+			if (of_node_name_eq(child, node_name))
+				break;
+			else if (of_node_name_eq(child, bank->name))
+				break;
+		}
+
+		if (child)
+			bank->of_node = child;
+		else
+			dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
+				 bank->name);
+		/* child reference dropped in samsung_drop_banks_of_node() */
+	}
+}
+
 /* retrieve the soc specific data */
 static const struct samsung_pin_ctrl *
 samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
 			     struct platform_device *pdev)
 {
 	struct device_node *node = pdev->dev.of_node;
-	struct device_node *np;
 	const struct samsung_pin_bank_data *bdata;
 	const struct samsung_pin_ctrl *ctrl;
 	struct samsung_pin_bank *bank;
@@ -1082,17 +1125,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
 	 */
 	d->virt_base = virt_base[0];
 
-	for_each_child_of_node(node, np) {
-		if (!of_find_property(np, "gpio-controller", NULL))
-			continue;
-		bank = d->pin_banks;
-		for (i = 0; i < d->nr_banks; ++i, ++bank) {
-			if (of_node_name_eq(np, bank->name)) {
-				bank->of_node = np;
-				break;
-			}
-		}
-	}
+	samsung_banks_of_node_get(&pdev->dev, d, node);
 
 	d->pin_base = pin_base;
 	pin_base += d->nr_pins;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:14:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:14:04 +0100
Subject: [PATCH v2 06/28] ARM: dts: exynos: simplify PMIC DVS pin
 configuration in Peach Pit
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-7-krzysztof.kozlowski@canonical.com>

The pin configuration for PMIC DVS (pmic-dvs-2 and pmic-dvs-3) are
exactly the same, so merge them.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index 1ae5528e9ebf..e8819659081a 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -212,7 +212,7 @@ max77802: pmic at 9 {
 		interrupts = <1 IRQ_TYPE_NONE>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
-			    <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+			    <&pmic_dvs_1>, <&pmic_dvs_2>;
 		wakeup-source;
 		reg = <0x9>;
 		#clock-cells = <1>;
@@ -892,14 +892,7 @@ &sd1_cmd {
 
 &pinctrl_2 {
 	pmic_dvs_2: pmic-dvs-2 {
-		samsung,pins = "gpj4-2";
-		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-	};
-
-	pmic_dvs_3: pmic-dvs-3 {
-		samsung,pins = "gpj4-3";
+		samsung,pins = "gpj4-2", "gpj4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:14:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:14:03 +0100
Subject: [PATCH v2 05/28] ARM: dts: exynos: override pins by label in Peach Pit
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201426.326777-6-krzysztof.kozlowski@canonical.com>

Using node paths to extend or override a device tree node is error
prone.  If there was a typo error, a new node will be created instead of
extending the existing node.  This will lead to run-time errors that
could be hard to detect.

A mistyped label on the other hand, will cause a dtc compile error
(during build time).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 44 +++++++++++-----------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index e76fb104db19..1ae5528e9ebf 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -868,27 +868,26 @@ pmic_dvs_1: pmic-dvs-1 {
 	};
 };
 
-&pinctrl_1 {
-	/* Adjust WiFi drive strengths lower for EMI */
-	sd1_clk: sd1-clk {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+/* pinctrl_1 */
+/* Adjust WiFi drive strengths lower for EMI */
+&sd1_bus1 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_cmd: sd1-cmd {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_bus4 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus1: sd1-bus-width1 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_bus8 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus4: sd1-bus-width4 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_clk {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus8: sd1-bus-width8 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_cmd {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
 };
 
 &pinctrl_2 {
@@ -907,12 +906,13 @@ pmic_dvs_3: pmic-dvs-3 {
 	};
 };
 
-&pinctrl_3 {
-	/* Drive SPI lines at x2 for better integrity */
-	spi2-bus {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+/* pinctrl_3*/
+/* Drive SPI lines at x2 for better integrity */
+&spi2_bus {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
+&pinctrl_3 {
 	/* Drive SPI chip select at x2 for better integrity */
 	ec_spi_cs: ec-spi-cs {
 		samsung,pins = "gpb1-2";
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:01 +0100
Subject: [PATCH v2 07/28] ARM: dts: exynos: override pins by label in Peach Pi
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-1-krzysztof.kozlowski@canonical.com>

Using node paths to extend or override a device tree node is error
prone.  If there was a typo error, a new node will be created instead of
extending the existing node.  This will lead to run-time errors that
could be hard to detect.

A mistyped label on the other hand, will cause a dtc compile error
(during build time).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5800-peach-pi.dts | 44 +++++++++++------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 77013ee586f8..01f310f387d6 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -850,27 +850,26 @@ pmic_dvs_1: pmic-dvs-1 {
 	};
 };
 
-&pinctrl_1 {
-	/* Adjust WiFi drive strengths lower for EMI */
-	sd1_clk: sd1-clk {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+/* pinctrl_1 */
+/* Adjust WiFi drive strengths lower for EMI */
+&sd1_bus1 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_cmd: sd1-cmd {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_bus4 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus1: sd1-bus-width1 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_bus8 {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus4: sd1-bus-width4 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_clk {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
-	sd1_bus8: sd1-bus-width8 {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+&sd1_cmd {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
 };
 
 &pinctrl_2 {
@@ -889,12 +888,13 @@ pmic_dvs_3: pmic-dvs-3 {
 	};
 };
 
-&pinctrl_3 {
-	/* Drive SPI lines at x2 for better integrity */
-	spi2-bus {
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
-	};
+/* pinctrl_3*/
+/* Drive SPI lines at x2 for better integrity */
+&spi2_bus {
+	samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
+};
 
+&pinctrl_3 {
 	/* Drive SPI chip select at x2 for better integrity */
 	ec_spi_cs: ec-spi-cs {
 		samsung,pins = "gpb1-2";
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:02 +0100
Subject: [PATCH v2 08/28] ARM: dts: exynos: simplify PMIC DVS pin
 configuration in Peach Pi
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-2-krzysztof.kozlowski@canonical.com>

The pin configuration for PMIC DVS (pmic-dvs-2 and pmic-dvs-3) are
exactly the same, so merge them.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5800-peach-pi.dts | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 01f310f387d6..eca805b83816 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -221,7 +221,7 @@ max77802: pmic at 9 {
 		interrupts = <1 IRQ_TYPE_NONE>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&max77802_irq>, <&pmic_selb>,
-			    <&pmic_dvs_1>, <&pmic_dvs_2>, <&pmic_dvs_3>;
+			    <&pmic_dvs_1>, <&pmic_dvs_2>;
 		wakeup-source;
 		reg = <0x9>;
 		#clock-cells = <1>;
@@ -874,14 +874,7 @@ &sd1_cmd {
 
 &pinctrl_2 {
 	pmic_dvs_2: pmic-dvs-2 {
-		samsung,pins = "gpj4-2";
-		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
-		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-	};
-
-	pmic_dvs_3: pmic-dvs-3 {
-		samsung,pins = "gpj4-3";
+		samsung,pins = "gpj4-2", "gpj4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:03 +0100
Subject: [PATCH v2 09/28] ARM: dts: s3c64xx: drop unneeded pinctrl wake-up
 interrupt mapping
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-3-krzysztof.kozlowski@canonical.com>

Simplify the nodes of S3C64xx pin controller with wake-up interrupts by
removing the artificial pinctrl-interrupt-map mapping node and use
interrupts-extended.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/s3c64xx.dtsi | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/s3c64xx.dtsi b/arch/arm/boot/dts/s3c64xx.dtsi
index cb11a87dbc42..67a7a66e11d5 100644
--- a/arch/arm/boot/dts/s3c64xx.dtsi
+++ b/arch/arm/boot/dts/s3c64xx.dtsi
@@ -178,20 +178,12 @@ pinctrl0: pinctrl at 7f008000 {
 			interrupt-parent = <&vic1>;
 			interrupts = <21>;
 
-			pctrl_int_map: pinctrl-interrupt-map {
-				interrupt-map = <0 &vic0 0>,
-						<1 &vic0 1>,
-						<2 &vic1 0>,
-						<3 &vic1 1>;
-				#address-cells = <0>;
-				#size-cells = <0>;
-				#interrupt-cells = <1>;
-			};
-
 			wakeup-interrupt-controller {
 				compatible = "samsung,s3c64xx-wakeup-eint";
-				interrupts = <0>, <1>, <2>, <3>;
-				interrupt-parent = <&pctrl_int_map>;
+				interrupts-extended = <&vic0 0>,
+						      <&vic0 1>,
+						      <&vic1 0>,
+						      <&vic1 1>;
 			};
 		};
 	};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:04 +0100
Subject: [PATCH v2 10/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos3250
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-4-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos3250-artik5.dtsi  |  10 +-
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi | 140 +++++++++++-----------
 2 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250-artik5.dtsi b/arch/arm/boot/dts/exynos3250-artik5.dtsi
index 829c05b2c405..7b429622a288 100644
--- a/arch/arm/boot/dts/exynos3250-artik5.dtsi
+++ b/arch/arm/boot/dts/exynos3250-artik5.dtsi
@@ -356,7 +356,7 @@ &mshc_1 {
 };
 
 &pinctrl_1 {
-	bten: bten {
+	bten: bten-pins {
 		samsung,pins ="gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -364,7 +364,7 @@ bten: bten {
 		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_DOWN>;
 	};
 
-	wlanen: wlanen {
+	wlanen: wlanen-pins {
 		samsung,pins = "gpx2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -372,12 +372,12 @@ wlanen: wlanen {
 		samsung,pin-val = <1>;
 	};
 
-	s2mps14_irq: s2mps14-irq {
+	s2mps14_irq: s2mps14-irq-pins {
 		samsung,pins = "gpx3-5";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bthostwake: bthostwake {
+	bthostwake: bthostwake-pins {
 		samsung,pins = "gpx3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -385,7 +385,7 @@ bthostwake: bthostwake {
 		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	btwake: btwake {
+	btwake: btwake-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
diff --git a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
index a616cb1aca29..cc30d154ec94 100644
--- a/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos3250-pinctrl.dtsi
@@ -12,7 +12,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 #define PIN_IN(_pin, _pull, _drv)					\
-	_pin {								\
+	pin- ## _pin {							\
 		samsung,pins = #_pin;					\
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;		\
 		samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>;		\
@@ -20,14 +20,14 @@ _pin {								\
 	}
 
 #define PIN_SLP(_pin, _mode, _pull)					\
-	_pin {								\
+	pin- ## _pin {							\
 		samsung,pins = #_pin;					\
 		samsung,pin-con-pdn = <EXYNOS_PIN_PDN_ ##_mode>;	\
 		samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_ ##_pull>;	\
 	}
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -35,7 +35,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -43,7 +43,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -51,7 +51,7 @@ gpb: gpb {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -59,7 +59,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -67,7 +67,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -75,7 +75,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -83,84 +83,84 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c4_bus: i2c4-bus {
+	i2c4_bus: i2c4-bus-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c5_bus: i2c5-bus {
+	i2c5_bus: i2c5-bus-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -168,7 +168,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -176,63 +176,63 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c6_bus: i2c6-bus {
+	i2c6_bus: i2c6-bus-pins {
 		samsung,pins = "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c7_bus: i2c7-bus {
+	i2c7_bus: i2c7-bus-pins {
 		samsung,pins = "gpd0-2", "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	mipi0_clk: mipi0-clk {
+	mipi0_clk: mipi0-clk-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -241,22 +241,22 @@ i2c1_bus: i2c1-bus {
 };
 
 &pinctrl_1 {
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpe2: gpe2 {
+	gpe2: gpe2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpk0: gpk0 {
+	gpk0: gpk0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -264,7 +264,7 @@ gpk0: gpk0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk1: gpk1 {
+	gpk1: gpk1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -272,7 +272,7 @@ gpk1: gpk1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk2: gpk2 {
+	gpk2: gpk2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -280,7 +280,7 @@ gpk2: gpk2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl0: gpl0 {
+	gpl0: gpl0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -288,7 +288,7 @@ gpl0: gpl0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm0: gpm0 {
+	gpm0: gpm0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -296,7 +296,7 @@ gpm0: gpm0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm1: gpm1 {
+	gpm1: gpm1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -304,7 +304,7 @@ gpm1: gpm1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm2: gpm2 {
+	gpm2: gpm2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -312,7 +312,7 @@ gpm2: gpm2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm3: gpm3 {
+	gpm3: gpm3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -320,7 +320,7 @@ gpm3: gpm3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm4: gpm4 {
+	gpm4: gpm4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -328,7 +328,7 @@ gpm4: gpm4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -345,7 +345,7 @@ gpx0: gpx0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -362,7 +362,7 @@ gpx1: gpx1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -370,7 +370,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -378,126 +378,126 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpk0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpk0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpk0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_rdqs: sd0-rdqs {
+	sd0_rdqs: sd0-rdqs-pins {
 		samsung,pins = "gpk0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpk0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpk0-4", "gpk0-5", "gpk0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpl0-0", "gpl0-1", "gpl0-2", "gpl0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpk1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpk1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpk1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpk1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpk2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpk2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpk2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpk2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpk2-4", "gpk2-5", "gpk2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_b_io: cam-port-b-io {
+	cam_port_b_io: cam-port-b-io-pins {
 		samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
 				"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
 				"gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
@@ -506,35 +506,35 @@ cam_port_b_io: cam-port-b-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_b_clk_active: cam-port-b-clk-active {
+	cam_port_b_clk_active: cam-port-b-clk-active-pins {
 		samsung,pins = "gpm2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_b_clk_idle: cam-port-b-clk-idle {
+	cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
 		samsung,pins = "gpm2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_i2c0: fimc-is-i2c0 {
+	fimc_is_i2c0: fimc-is-i2c0-pins {
 		samsung,pins = "gpm4-0", "gpm4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_i2c1: fimc-is-i2c1 {
+	fimc_is_i2c1: fimc-is-i2c1-pins {
 		samsung,pins = "gpm4-2", "gpm4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_uart: fimc-is-uart {
+	fimc_is_uart: fimc-is-uart-pins {
 		samsung,pins = "gpm3-5", "gpm3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:05 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:05 +0100
Subject: [PATCH v2 11/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos4210
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-5-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos4210-i9100.dts        |  30 +--
 arch/arm/boot/dts/exynos4210-origen.dts       |   2 +-
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi     | 226 +++++++++---------
 arch/arm/boot/dts/exynos4210-smdkv310.dts     |   4 +-
 arch/arm/boot/dts/exynos4210-trats.dts        |   6 +-
 .../boot/dts/exynos4210-universal_c210.dts    |  12 +-
 6 files changed, 140 insertions(+), 140 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4210-i9100.dts b/arch/arm/boot/dts/exynos4210-i9100.dts
index 33894054b8b0..3c0a18b30837 100644
--- a/arch/arm/boot/dts/exynos4210-i9100.dts
+++ b/arch/arm/boot/dts/exynos4210-i9100.dts
@@ -672,26 +672,26 @@ &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep0>;
 
-	sleep0: sleep-states {
-		gpa0-0 {
+	sleep0: sleep-state {
+		gpa0-0-pin {
 			samsung,pins = "gpa0-0";
 			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
 			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
 		};
 
-		gpa0-1 {
+		gpa0-1-pin {
 			samsung,pins = "gpa0-1";
 			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
 			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
 		};
 
-		gpa0-2 {
+		gpa0-2-pin {
 			samsung,pins = "gpa0-2";
 			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
 			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
 		};
 
-		gpa0-3 {
+		gpa0-3-pin {
 			samsung,pins = "gpa0-3";
 			samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT1>;
 			samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
@@ -700,19 +700,19 @@ gpa0-3 {
 };
 
 &pinctrl_1 {
-	mhl_int: mhl-int {
+	mhl_int: mhl-int-pins {
 		samsung,pins = "gpf3-5";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	i2c_mhl_bus: i2c-mhl-bus {
+	i2c_mhl_bus: i2c-mhl-bus-pins {
 		samsung,pins = "gpf0-4", "gpf0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	usb_sel: usb-sel {
+	usb_sel: usb-sel-pins {
 		samsung,pins = "gpl0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -720,7 +720,7 @@ usb_sel: usb-sel {
 		samsung,pin-val = <0>;
 	};
 
-	bt_en: bt-en {
+	bt_en: bt-en-pins {
 		samsung,pins = "gpl0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -728,7 +728,7 @@ bt_en: bt-en {
 		samsung,pin-val = <0>;
 	};
 
-	bt_res: bt-res {
+	bt_res: bt-res-pins {
 		samsung,pins = "gpl1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -736,7 +736,7 @@ bt_res: bt-res {
 		samsung,pin-val = <0>;
 	};
 
-	otg_gp: otg-gp {
+	otg_gp: otg-gp-pins {
 		samsung,pins = "gpx3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -744,23 +744,23 @@ otg_gp: otg-gp {
 		samsung,pin-val = <0>;
 	};
 
-	mag_mhl_gpio: mag-mhl {
+	mag_mhl_gpio: mag-mhl-pins {
 		samsung,pins = "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max8997_irq: max8997-irq {
+	max8997_irq: max8997-irq-pins {
 		samsung,pins = "gpx0-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max17042_fuel_irq: max17042-fuel-irq {
+	max17042_fuel_irq: max17042-fuel-irq-pins {
 		samsung,pins = "gpx2-3";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	tsp224_irq: tsp224-irq {
+	tsp224_irq: tsp224-irq-pins {
 		samsung,pins = "gpx0-4";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 	};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index 435fda60e86d..a08ce2f37ea2 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -316,7 +316,7 @@ EN32KHZ_AP {
 };
 
 &pinctrl_1 {
-	max8997_irq: max8997-irq {
+	max8997_irq: max8997-irq-pins {
 		samsung,pins = "gpx0-3", "gpx0-4";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
diff --git a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
index 520c5934a8d4..6373009bb727 100644
--- a/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4210-pinctrl.dtsi
@@ -14,7 +14,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -22,7 +22,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -30,7 +30,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -38,7 +38,7 @@ gpb: gpb {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -46,7 +46,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -54,7 +54,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -62,7 +62,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -70,7 +70,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -78,7 +78,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -86,7 +86,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe2: gpe2 {
+	gpe2: gpe2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -94,7 +94,7 @@ gpe2: gpe2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe3: gpe3 {
+	gpe3: gpe3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -102,7 +102,7 @@ gpe3: gpe3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe4: gpe4 {
+	gpe4: gpe4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -110,7 +110,7 @@ gpe4: gpe4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -118,7 +118,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -126,7 +126,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -134,7 +134,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -142,112 +142,112 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart_audio_a: uart-audio-a {
+	uart_audio_a: uart-audio-a-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart_audio_b: uart-audio-b {
+	uart_audio_b: uart-audio-b-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c4_bus: i2c4-bus {
+	i2c4_bus: i2c4-bus-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c5_bus: i2c5-bus {
+	i2c5_bus: i2c5-bus-pins {
 		samsung,pins = "gpb-6", "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -255,7 +255,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -263,7 +263,7 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ac97_bus: ac97-bus {
+	ac97_bus: ac97-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -271,7 +271,7 @@ ac97_bus: ac97-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -279,7 +279,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -287,105 +287,105 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c6_bus: i2c6-bus {
+	i2c6_bus: i2c6-bus-pins {
 		samsung,pins = "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c7_bus: i2c7-bus {
+	i2c7_bus: i2c7-bus-pins {
 		samsung,pins = "gpd0-2", "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_ctrl: lcd-ctrl {
+	lcd_ctrl: lcd-ctrl-pins {
 		samsung,pins = "gpd0-0", "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_sync: lcd-sync {
+	lcd_sync: lcd-sync-pins {
 		samsung,pins = "gpf0-0", "gpf0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_en: lcd-en {
+	lcd_en: lcd-en-pins {
 		samsung,pins = "gpe3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_clk: lcd-clk {
+	lcd_clk: lcd-clk-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data16: lcd-data-width16 {
+	lcd_data16: lcd-data-width16-pins {
 		samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
 				"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
 				"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
@@ -395,7 +395,7 @@ lcd_data16: lcd-data-width16 {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data18: lcd-data-width18 {
+	lcd_data18: lcd-data-width18-pins {
 		samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
 				"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
 				"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
@@ -406,7 +406,7 @@ lcd_data18: lcd-data-width18 {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data24: lcd-data-width24 {
+	lcd_data24: lcd-data-width24-pins {
 		samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
 				"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
 				"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
@@ -420,7 +420,7 @@ lcd_data24: lcd-data-width24 {
 };
 
 &pinctrl_1 {
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -428,7 +428,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -436,7 +436,7 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk0: gpk0 {
+	gpk0: gpk0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -444,7 +444,7 @@ gpk0: gpk0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk1: gpk1 {
+	gpk1: gpk1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -452,7 +452,7 @@ gpk1: gpk1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk2: gpk2 {
+	gpk2: gpk2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -460,7 +460,7 @@ gpk2: gpk2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk3: gpk3 {
+	gpk3: gpk3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -468,7 +468,7 @@ gpk3: gpk3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl0: gpl0 {
+	gpl0: gpl0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -476,7 +476,7 @@ gpl0: gpl0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl1: gpl1 {
+	gpl1: gpl1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -484,7 +484,7 @@ gpl1: gpl1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl2: gpl2 {
+	gpl2: gpl2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -492,42 +492,42 @@ gpl2: gpl2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpy0: gpy0 {
+	gpy0: gpy0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy1: gpy1 {
+	gpy1: gpy1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy2: gpy2 {
+	gpy2: gpy2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy3: gpy3 {
+	gpy3: gpy3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy4: gpy4 {
+	gpy4: gpy4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy5: gpy5 {
+	gpy5: gpy5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy6: gpy6 {
+	gpy6: gpy6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -544,7 +544,7 @@ gpx0: gpx0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -561,7 +561,7 @@ gpx1: gpx1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -569,7 +569,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -577,238 +577,238 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpk0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpk0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpk0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpk0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_clk: sd4-clk {
+	sd4_clk: sd4-clk-pins {
 		samsung,pins = "gpk0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_cmd: sd4-cmd {
+	sd4_cmd: sd4-cmd-pins {
 		samsung,pins = "gpk0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_cd: sd4-cd {
+	sd4_cd: sd4-cd-pins {
 		samsung,pins = "gpk0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus1: sd4-bus-width1 {
+	sd4_bus1: sd4-bus-width1-pins {
 		samsung,pins = "gpk0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus4: sd4-bus-width4 {
+	sd4_bus4: sd4-bus-width4-pins {
 		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus8: sd4-bus-width8 {
+	sd4_bus8: sd4-bus-width8-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpk1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpk1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpk1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpk1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpk2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpk2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpk2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpk2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus8: sd2-bus-width8 {
+	sd2_bus8: sd2-bus-width8-pins {
 		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_clk: sd3-clk {
+	sd3_clk: sd3-clk-pins {
 		samsung,pins = "gpk3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cmd: sd3-cmd {
+	sd3_cmd: sd3-cmd-pins {
 		samsung,pins = "gpk3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cd: sd3-cd {
+	sd3_cd: sd3-cd-pins {
 		samsung,pins = "gpk3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus1: sd3-bus-width1 {
+	sd3_bus1: sd3-bus-width1-pins {
 		samsung,pins = "gpk3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus4: sd3-bus-width4 {
+	sd3_bus4: sd3-bus-width4-pins {
 		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	eint0: ext-int0 {
+	eint0: ext-int0-pins {
 		samsung,pins = "gpx0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint8: ext-int8 {
+	eint8: ext-int8-pins {
 		samsung,pins = "gpx1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint15: ext-int15 {
+	eint15: ext-int15-pins {
 		samsung,pins = "gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint16: ext-int16 {
+	eint16: ext-int16-pins {
 		samsung,pins = "gpx2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint31: ext-int31 {
+	eint31: ext-int31-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_io: cam-port-a-io {
+	cam_port_a_io: cam-port-a-io-pins {
 		samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
 				"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
 				"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -817,21 +817,21 @@ cam_port_a_io: cam-port-a-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_clk_active: cam-port-a-clk-active {
+	cam_port_a_clk_active: cam-port-a-clk-active-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_a_clk_idle: cam-port-a-clk-idle {
+	cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_cec: hdmi-cec {
+	hdmi_cec: hdmi-cec-pins {
 		samsung,pins = "gpx3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -840,12 +840,12 @@ hdmi_cec: hdmi-cec {
 };
 
 &pinctrl_2 {
-	gpz: gpz {
+	gpz: gpz-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4", "gpz-5", "gpz-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -853,7 +853,7 @@ i2s0_bus: i2s0-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm0_bus: pcm0-bus {
+	pcm0_bus: pcm0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index d5797a67bf48..a5dfd7fd49b3 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -152,14 +152,14 @@ key-e {
 };
 
 &pinctrl_1 {
-	keypad_rows: keypad-rows {
+	keypad_rows: keypad-rows-pins {
 		samsung,pins = "gpx2-0", "gpx2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_cols: keypad-cols {
+	keypad_cols: keypad-cols-pins {
 		samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
 			       "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 9c4ff7521348..01f44d95f671 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -464,19 +464,19 @@ EN32KHZ_CP {
 };
 
 &pinctrl_1 {
-	bt_shutdown: bt-shutdown {
+	bt_shutdown: bt-shutdown-pins {
 		samsung,pins = "gpl1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_host_wakeup: bt-host-wakeup {
+	bt_host_wakeup: bt-host-wakeup-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_device_wakeup: bt-device-wakeup {
+	bt_device_wakeup: bt-device-wakeup-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 9f93e7464aed..170d54a0bb5c 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -533,37 +533,37 @@ &ohci {
 };
 
 &pinctrl_1 {
-	bt_shutdown: bt-shutdown {
+	bt_shutdown: bt-shutdown-pins {
 		samsung,pins = "gpe1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_host_wakeup: bt-host-wakeup {
+	bt_host_wakeup: bt-host-wakeup-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_device_wakeup: bt-device-wakeup {
+	bt_device_wakeup: bt-device-wakeup-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	lp3974_irq: lp3974-irq {
+	lp3974_irq: lp3974-irq-pins {
 		samsung,pins = "gpx0-7", "gpx2-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	hdmi_hpd: hdmi-hpd {
+	hdmi_hpd: hdmi-hpd-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 };
 
 &pinctrl_0 {
-	i2c_ddc_bus: i2c-ddc-bus {
+	i2c_ddc_bus: i2c-ddc-bus-pins {
 		samsung,pins = "gpe4-2", "gpe4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:06 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:06 +0100
Subject: [PATCH v2 12/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos4412
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-6-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi   |   4 +-
 arch/arm/boot/dts/exynos4412-itop-elite.dts   |   2 +-
 .../boot/dts/exynos4412-itop-scp-core.dtsi    |   2 +-
 arch/arm/boot/dts/exynos4412-midas.dtsi       |  30 +--
 .../boot/dts/exynos4412-odroid-common.dtsi    |   8 +-
 arch/arm/boot/dts/exynos4412-odroidx.dts      |   2 +-
 arch/arm/boot/dts/exynos4412-origen.dts       |   4 +-
 arch/arm/boot/dts/exynos4412-p4note.dtsi      |  44 +--
 arch/arm/boot/dts/exynos4412-pinctrl.dtsi     | 252 +++++++++---------
 arch/arm/boot/dts/exynos4412-smdk4412.dts     |   4 +-
 10 files changed, 176 insertions(+), 176 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
index c14e37dc3a9b..03dffc690b79 100644
--- a/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
+++ b/arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
@@ -151,13 +151,13 @@ &ldo25_reg {
 };
 
 &pinctrl_0 {
-	camera_flash_host: camera-flash-host {
+	camera_flash_host: camera-flash-host-pins {
 		samsung,pins = "gpj1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-val = <0>;
 	};
 
-	camera_flash_isp: camera-flash-isp {
+	camera_flash_isp: camera-flash-isp-pins {
 		samsung,pins = "gpj1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-val = <1>;
diff --git a/arch/arm/boot/dts/exynos4412-itop-elite.dts b/arch/arm/boot/dts/exynos4412-itop-elite.dts
index 47431307cb3c..a9406280b979 100644
--- a/arch/arm/boot/dts/exynos4412-itop-elite.dts
+++ b/arch/arm/boot/dts/exynos4412-itop-elite.dts
@@ -192,7 +192,7 @@ &i2s0 {
 };
 
 &pinctrl_1 {
-	ether-reset {
+	ether-reset-pins {
 		samsung,pins = "gpc0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
index b3726d4d7d93..a67cb61e3cbb 100644
--- a/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
+++ b/arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
@@ -484,7 +484,7 @@ &mshc_0 {
 };
 
 &pinctrl_1 {
-	hsic_reset: hsic-reset {
+	hsic_reset: hsic-reset-pins {
 		samsung,pins = "gpm2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-midas.dtsi b/arch/arm/boot/dts/exynos4412-midas.dtsi
index 968c7943653e..23f50c9be527 100644
--- a/arch/arm/boot/dts/exynos4412-midas.dtsi
+++ b/arch/arm/boot/dts/exynos4412-midas.dtsi
@@ -987,19 +987,19 @@ &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep0>;
 
-	mhl_int: mhl-int {
+	mhl_int: mhl-int-pins {
 		samsung,pins = "gpf3-5";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	i2c_mhl_bus: i2c-mhl-bus {
+	i2c_mhl_bus: i2c-mhl-bus-pins {
 		samsung,pins = "gpf0-4", "gpf0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	sleep0: sleep-states {
+	sleep0: sleep-state {
 		PIN_SLP(gpa0-0, INPUT, NONE);
 		PIN_SLP(gpa0-1, OUT0, NONE);
 		PIN_SLP(gpa0-2, INPUT, NONE);
@@ -1102,52 +1102,52 @@ &pinctrl_1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep1>;
 
-	gpio_keys: gpio-keys {
+	gpio_keys: gpio-keys-pins {
 		samsung,pins = "gpx0-1", "gpx2-2", "gpx2-7", "gpx3-3";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_shutdown: bt-shutdown {
+	bt_shutdown: bt-shutdown-pins {
 		samsung,pins = "gpl0-6";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_host_wakeup: bt-host-wakeup {
+	bt_host_wakeup: bt-host-wakeup-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_device_wakeup: bt-device-wakeup {
+	bt_device_wakeup: bt-device-wakeup-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max77686_irq: max77686-irq {
+	max77686_irq: max77686-irq-pins {
 		samsung,pins = "gpx0-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max77693_irq: max77693-irq {
+	max77693_irq: max77693-irq-pins {
 		samsung,pins = "gpx1-5";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max77693_fuel_irq: max77693-fuel-irq {
+	max77693_fuel_irq: max77693-fuel-irq-pins {
 		samsung,pins = "gpx2-3";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	sdhci2_cd: sdhci2-cd-irq {
+	sdhci2_cd: sdhci2-cd-irq-pins {
 		samsung,pins = "gpx3-4";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	hdmi_hpd: hdmi-hpd {
+	hdmi_hpd: hdmi-hpd-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 	};
 
-	sleep1: sleep-states {
+	sleep1: sleep-state {
 		PIN_SLP(gpk0-0, PREV, NONE);
 		PIN_SLP(gpk0-1, PREV, NONE);
 		PIN_SLP(gpk0-2, OUT0, NONE);
@@ -1300,7 +1300,7 @@ &pinctrl_2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep2>;
 
-	sleep2: sleep-states {
+	sleep2: sleep-state {
 		PIN_SLP(gpz-0, INPUT, DOWN);
 		PIN_SLP(gpz-1, INPUT, DOWN);
 		PIN_SLP(gpz-2, INPUT, DOWN);
@@ -1315,7 +1315,7 @@ &pinctrl_3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep3>;
 
-	sleep3: sleep-states {
+	sleep3: sleep-state {
 		PIN_SLP(gpv0-0, INPUT, DOWN);
 		PIN_SLP(gpv0-1, INPUT, DOWN);
 		PIN_SLP(gpv0-2, INPUT, DOWN);
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index 5b1d4591b35c..e7669b9e9edb 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -172,24 +172,24 @@ cooling_map1: map1 {
 };
 
 &pinctrl_1 {
-	gpio_power_key: power-key {
+	gpio_power_key: power-key-pins {
 		samsung,pins = "gpx1-3";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max77686_irq: max77686-irq {
+	max77686_irq: max77686-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd: hdmi-hpd {
+	hdmi_hpd: hdmi-hpd-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 	};
 
-	emmc_rstn: emmc-rstn {
+	emmc_rstn: emmc-rstn-pins {
 		samsung,pins = "gpk1-2";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
index 440135d0ff2a..a9fada51eb50 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx.dts
@@ -112,7 +112,7 @@ &mshc_0 {
 };
 
 &pinctrl_1 {
-	gpio_home_key: home-key {
+	gpio_home_key: home-key-pins {
 		samsung,pins = "gpx2-2";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index e6aec5facabf..6db09dba07ff 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -506,14 +506,14 @@ &mshc_0 {
 };
 
 &pinctrl_1 {
-	keypad_rows: keypad-rows {
+	keypad_rows: keypad-rows-pins {
 		samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_cols: keypad-cols {
+	keypad_cols: keypad-cols-pins {
 		samsung,pins = "gpx1-0", "gpx1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos4412-p4note.dtsi b/arch/arm/boot/dts/exynos4412-p4note.dtsi
index 22c3086e0076..b386a9b8e188 100644
--- a/arch/arm/boot/dts/exynos4412-p4note.dtsi
+++ b/arch/arm/boot/dts/exynos4412-p4note.dtsi
@@ -641,19 +641,19 @@ &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep0>;
 
-	tsp_reg_gpio_2: tsp-reg-gpio-2 {
+	tsp_reg_gpio_2: tsp-reg-gpio-2-pins {
 		samsung,pins = "gpb-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	tsp_reg_gpio_3: tsp-reg-gpio-3 {
+	tsp_reg_gpio_3: tsp-reg-gpio-3-pins {
 		samsung,pins = "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	sleep0: sleep-states {
+	sleep0: sleep-state {
 		PIN_SLP(gpa0-0, INPUT, NONE);
 		PIN_SLP(gpa0-1, OUT0, NONE);
 		PIN_SLP(gpa0-2, INPUT, NONE);
@@ -755,19 +755,19 @@ &pinctrl_1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep1>;
 
-	sd3_wifi: sd3-wifi {
+	sd3_wifi: sd3-wifi-pins {
 		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_shutdown: bt-shutdown {
+	bt_shutdown: bt-shutdown-pins {
 		samsung,pins = "gpl0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	uart_sel: uart-sel {
+	uart_sel: uart-sel-pins {
 		samsung,pins = "gpl2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -775,82 +775,82 @@ uart_sel: uart-sel {
 		/* 0 = CP, 1 = AP (serial output) */
 	};
 
-	tsp_rst: tsp-rst {
+	tsp_rst: tsp-rst-pins {
 		samsung,pins = "gpm0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	tsp_irq: tsp-irq {
+	tsp_irq: tsp-irq-pins {
 		samsung,pins = "gpm2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	wifi_reset: wifi-reset {
+	wifi_reset: wifi-reset-pins {
 		samsung,pins = "gpm3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	tsp_reg_gpio_1: tsp-reg-gpio-1 {
+	tsp_reg_gpio_1: tsp-reg-gpio-1-pins {
 		samsung,pins = "gpm4-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	ak8975_irq: ak8975-irq {
+	ak8975_irq: ak8975-irq-pins {
 		samsung,pins = "gpm4-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 	};
 
-	stmpe_adc_irq: stmpe-adc-irq {
+	stmpe_adc_irq: stmpe-adc-irq-pins {
 		samsung,pins = "gpx0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	max77686_irq: max77686-irq {
+	max77686_irq: max77686-irq-pins {
 		samsung,pins = "gpx0-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	gpio_keys: gpio-keys {
+	gpio_keys: gpio-keys-pins {
 		samsung,pins = "gpx2-2", "gpx2-7", "gpx3-3";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	fuel_alert_irq: fuel-alert-irq {
+	fuel_alert_irq: fuel-alert-irq-pins {
 		samsung,pins = "gpx2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	wifi_host_wake: wifi-host-wake {
+	wifi_host_wake: wifi-host-wake-pins {
 		samsung,pins = "gpx2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 	};
 
-	bt_host_wakeup: bt-host-wakeup {
+	bt_host_wakeup: bt-host-wakeup-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	bt_device_wakeup: bt-device-wakeup {
+	bt_device_wakeup: bt-device-wakeup-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	sdhci2_cd: sdhci2-cd {
+	sdhci2_cd: sdhci2-cd-pins {
 		samsung,pins = "gpx3-4";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	sleep1: sleep-states {
+	sleep1: sleep-state {
 		PIN_SLP(gpk0-0, PREV, NONE);
 		PIN_SLP(gpk0-1, PREV, NONE);
 		PIN_SLP(gpk0-2, PREV, NONE);
@@ -1004,7 +1004,7 @@ &pinctrl_2 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep2>;
 
-	sleep2: sleep-states {
+	sleep2: sleep-state {
 		PIN_SLP(gpz-0, INPUT, DOWN);
 		PIN_SLP(gpz-1, INPUT, DOWN);
 		PIN_SLP(gpz-2, INPUT, DOWN);
@@ -1019,7 +1019,7 @@ &pinctrl_3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep3>;
 
-	sleep3: sleep-states {
+	sleep3: sleep-state {
 		PIN_SLP(gpv0-0, INPUT, DOWN);
 		PIN_SLP(gpv0-1, INPUT, DOWN);
 		PIN_SLP(gpv0-2, INPUT, DOWN);
diff --git a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
index d7d5fdc230d8..88b8afd55664 100644
--- a/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos4412-pinctrl.dtsi
@@ -19,7 +19,7 @@ _pin {								\
 	}
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -27,7 +27,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -35,7 +35,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -43,7 +43,7 @@ gpb: gpb {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -51,7 +51,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -59,7 +59,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -67,7 +67,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -75,7 +75,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -83,7 +83,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -91,7 +91,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -99,7 +99,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -107,7 +107,7 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -115,7 +115,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -123,112 +123,112 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart_audio_a: uart-audio-a {
+	uart_audio_a: uart-audio-a-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart_audio_b: uart-audio-b {
+	uart_audio_b: uart-audio-b-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c4_bus: i2c4-bus {
+	i2c4_bus: i2c4-bus-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c5_bus: i2c5-bus {
+	i2c5_bus: i2c5-bus-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -236,7 +236,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -244,7 +244,7 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ac97_bus: ac97-bus {
+	ac97_bus: ac97-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -252,7 +252,7 @@ ac97_bus: ac97-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -260,7 +260,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -268,105 +268,105 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c6_bus: i2c6-bus {
+	i2c6_bus: i2c6-bus-pins {
 		samsung,pins = "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpc1-1", "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_ctrl: lcd-ctrl {
+	lcd_ctrl: lcd-ctrl-pins {
 		samsung,pins = "gpd0-0", "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c7_bus: i2c7-bus {
+	i2c7_bus: i2c7-bus-pins {
 		samsung,pins = "gpd0-2", "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	mipi0_clk: mipi0-clk {
+	mipi0_clk: mipi0-clk-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	mipi1_clk: mipi1-clk {
+	mipi1_clk: mipi1-clk-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_clk: lcd-clk {
+	lcd_clk: lcd-clk-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data16: lcd-data-width16 {
+	lcd_data16: lcd-data-width16-pins {
 		samsung,pins = "gpf0-7", "gpf1-0", "gpf1-1", "gpf1-2",
 				"gpf1-3", "gpf1-6", "gpf1-7", "gpf2-0",
 				"gpf2-1", "gpf2-2", "gpf2-3", "gpf2-7",
@@ -376,7 +376,7 @@ lcd_data16: lcd-data-width16 {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data18: lcd-data-width18 {
+	lcd_data18: lcd-data-width18-pins {
 		samsung,pins = "gpf0-6", "gpf0-7", "gpf1-0", "gpf1-1",
 				"gpf1-2", "gpf1-3", "gpf1-6", "gpf1-7",
 				"gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3",
@@ -387,7 +387,7 @@ lcd_data18: lcd-data-width18 {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data24: lcd-data-width24 {
+	lcd_data24: lcd-data-width24-pins {
 		samsung,pins = "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
 				"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
 				"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
@@ -399,14 +399,14 @@ lcd_data24: lcd-data-width24 {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_ldi: lcd-ldi {
+	lcd_ldi: lcd-ldi-pins {
 		samsung,pins = "gpf3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_io: cam-port-a-io {
+	cam_port_a_io: cam-port-a-io-pins {
 		samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
 				"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
 				"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -415,14 +415,14 @@ cam_port_a_io: cam-port-a-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_clk_active: cam-port-a-clk-active {
+	cam_port_a_clk_active: cam-port-a-clk-active-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_a_clk_idle: cam-port-a-clk-idle {
+	cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -431,7 +431,7 @@ cam_port_a_clk_idle: cam-port-a-clk-idle {
 };
 
 &pinctrl_1 {
-	gpk0: gpk0 {
+	gpk0: gpk0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -439,7 +439,7 @@ gpk0: gpk0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk1: gpk1 {
+	gpk1: gpk1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -447,7 +447,7 @@ gpk1: gpk1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk2: gpk2 {
+	gpk2: gpk2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -455,7 +455,7 @@ gpk2: gpk2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk3: gpk3 {
+	gpk3: gpk3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -463,7 +463,7 @@ gpk3: gpk3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl0: gpl0 {
+	gpl0: gpl0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -471,7 +471,7 @@ gpl0: gpl0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl1: gpl1 {
+	gpl1: gpl1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -479,7 +479,7 @@ gpl1: gpl1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpl2: gpl2 {
+	gpl2: gpl2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -487,7 +487,7 @@ gpl2: gpl2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm0: gpm0 {
+	gpm0: gpm0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -495,7 +495,7 @@ gpm0: gpm0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm1: gpm1 {
+	gpm1: gpm1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -503,7 +503,7 @@ gpm1: gpm1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm2: gpm2 {
+	gpm2: gpm2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -511,7 +511,7 @@ gpm2: gpm2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm3: gpm3 {
+	gpm3: gpm3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -519,7 +519,7 @@ gpm3: gpm3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm4: gpm4 {
+	gpm4: gpm4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -527,42 +527,42 @@ gpm4: gpm4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpy0: gpy0 {
+	gpy0: gpy0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy1: gpy1 {
+	gpy1: gpy1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy2: gpy2 {
+	gpy2: gpy2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy3: gpy3 {
+	gpy3: gpy3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy4: gpy4 {
+	gpy4: gpy4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy5: gpy5 {
+	gpy5: gpy5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy6: gpy6 {
+	gpy6: gpy6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -579,7 +579,7 @@ gpx0: gpx0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -596,7 +596,7 @@ gpx1: gpx1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -604,7 +604,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -612,203 +612,203 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpk0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpk0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpk0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpk0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_clk: sd4-clk {
+	sd4_clk: sd4-clk-pins {
 		samsung,pins = "gpk0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_cmd: sd4-cmd {
+	sd4_cmd: sd4-cmd-pins {
 		samsung,pins = "gpk0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_cd: sd4-cd {
+	sd4_cd: sd4-cd-pins {
 		samsung,pins = "gpk0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus1: sd4-bus-width1 {
+	sd4_bus1: sd4-bus-width1-pins {
 		samsung,pins = "gpk0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus4: sd4-bus-width4 {
+	sd4_bus4: sd4-bus-width4-pins {
 		samsung,pins = "gpk0-3", "gpk0-4", "gpk0-5", "gpk0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd4_bus8: sd4-bus-width8 {
+	sd4_bus8: sd4-bus-width8-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpk1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpk1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpk1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpk1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpk1-3", "gpk1-4", "gpk1-5", "gpk1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpk2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpk2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpk2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpk2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpk2-3", "gpk2-4", "gpk2-5", "gpk2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus8: sd2-bus-width8 {
+	sd2_bus8: sd2-bus-width8-pins {
 		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_clk: sd3-clk {
+	sd3_clk: sd3-clk-pins {
 		samsung,pins = "gpk3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cmd: sd3-cmd {
+	sd3_cmd: sd3-cmd-pins {
 		samsung,pins = "gpk3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cd: sd3-cd {
+	sd3_cd: sd3-cd-pins {
 		samsung,pins = "gpk3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus1: sd3-bus-width1 {
+	sd3_bus1: sd3-bus-width1-pins {
 		samsung,pins = "gpk3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus4: sd3-bus-width4 {
+	sd3_bus4: sd3-bus-width4-pins {
 		samsung,pins = "gpk3-3", "gpk3-4", "gpk3-5", "gpk3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_b_io: cam-port-b-io {
+	cam_port_b_io: cam-port-b-io-pins {
 		samsung,pins = "gpm0-0", "gpm0-1", "gpm0-2", "gpm0-3",
 				"gpm0-4", "gpm0-5", "gpm0-6", "gpm0-7",
 				"gpm1-0", "gpm1-1", "gpm2-0", "gpm2-1";
@@ -817,77 +817,77 @@ cam_port_b_io: cam-port-b-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_b_clk_active: cam-port-b-clk-active {
+	cam_port_b_clk_active: cam-port-b-clk-active-pins {
 		samsung,pins = "gpm2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_b_clk_idle: cam-port-b-clk-idle {
+	cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
 		samsung,pins = "gpm2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint0: ext-int0 {
+	eint0: ext-int0-pins {
 		samsung,pins = "gpx0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint8: ext-int8 {
+	eint8: ext-int8-pins {
 		samsung,pins = "gpx1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint15: ext-int15 {
+	eint15: ext-int15-pins {
 		samsung,pins = "gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint16: ext-int16 {
+	eint16: ext-int16-pins {
 		samsung,pins = "gpx2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint31: ext-int31 {
+	eint31: ext-int31-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_i2c0: fimc-is-i2c0 {
+	fimc_is_i2c0: fimc-is-i2c0-pins {
 		samsung,pins = "gpm4-0", "gpm4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_i2c1: fimc-is-i2c1 {
+	fimc_is_i2c1: fimc-is-i2c1-pins {
 		samsung,pins = "gpm4-2", "gpm4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fimc_is_uart: fimc-is-uart {
+	fimc_is_uart: fimc-is-uart-pins {
 		samsung,pins = "gpm3-5", "gpm3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_cec: hdmi-cec {
+	hdmi_cec: hdmi-cec-pins {
 		samsung,pins = "gpx3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -896,7 +896,7 @@ hdmi_cec: hdmi-cec {
 };
 
 &pinctrl_2 {
-	gpz: gpz {
+	gpz: gpz-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -904,7 +904,7 @@ gpz: gpz {
 		#interrupt-cells = <2>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4", "gpz-5", "gpz-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -912,7 +912,7 @@ i2s0_bus: i2s0-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm0_bus: pcm0-bus {
+	pcm0_bus: pcm0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -922,7 +922,7 @@ pcm0_bus: pcm0-bus {
 };
 
 &pinctrl_3 {
-	gpv0: gpv0 {
+	gpv0: gpv0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -930,7 +930,7 @@ gpv0: gpv0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv1: gpv1 {
+	gpv1: gpv1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -938,7 +938,7 @@ gpv1: gpv1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv2: gpv2 {
+	gpv2: gpv2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -946,7 +946,7 @@ gpv2: gpv2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv3: gpv3 {
+	gpv3: gpv3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -954,7 +954,7 @@ gpv3: gpv3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv4: gpv4 {
+	gpv4: gpv4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -962,7 +962,7 @@ gpv4: gpv4 {
 		#interrupt-cells = <2>;
 	};
 
-	c2c_bus: c2c-bus {
+	c2c_bus: c2c-bus-pins {
 		samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
 				"gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
 				"gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index cc99b955af0c..a40ff394977c 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -133,14 +133,14 @@ key-E {
 };
 
 &pinctrl_1 {
-	keypad_rows: keypad-rows {
+	keypad_rows: keypad-rows-pins {
 		samsung,pins = "gpx2-0", "gpx2-1", "gpx2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_cols: keypad-cols {
+	keypad_cols: keypad-cols-pins {
 		samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
 			       "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:07 +0100
Subject: [PATCH v2 13/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos5250
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-7-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250-arndale.dts      |   2 +-
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi     | 220 +++++++++---------
 arch/arm/boot/dts/exynos5250-smdk5250.dts     |   2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi |  22 +-
 arch/arm/boot/dts/exynos5250-snow-rev5.dts    |   2 +-
 arch/arm/boot/dts/exynos5250-snow.dts         |   2 +-
 arch/arm/boot/dts/exynos5250-spring.dts       |  20 +-
 7 files changed, 135 insertions(+), 135 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 3583095fbb2a..693bf9e48183 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -590,7 +590,7 @@ &mmc_2 {
 };
 
 &pinctrl_0 {
-	s5m8767_irq: s5m8767-irq {
+	s5m8767_irq: s5m8767-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
index d7d756614edd..918947a3897e 100644
--- a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
@@ -12,7 +12,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -20,7 +20,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -28,7 +28,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -36,7 +36,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -44,7 +44,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -52,7 +52,7 @@ gpb1: gpb1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb2: gpb2 {
+	gpb2: gpb2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -60,7 +60,7 @@ gpb2: gpb2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb3: gpb3 {
+	gpb3: gpb3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -68,7 +68,7 @@ gpb3: gpb3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -76,7 +76,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -84,7 +84,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -92,7 +92,7 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -100,7 +100,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -108,7 +108,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -116,42 +116,42 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpy0: gpy0 {
+	gpy0: gpy0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy1: gpy1 {
+	gpy1: gpy1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy2: gpy2 {
+	gpy2: gpy2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy3: gpy3 {
+	gpy3: gpy3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy4: gpy4 {
+	gpy4: gpy4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy5: gpy5 {
+	gpy5: gpy5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy6: gpy6 {
+	gpy6: gpy6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpc4: gpc4 {
+	gpc4: gpc4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -159,7 +159,7 @@ gpc4: gpc4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -170,7 +170,7 @@ gpx0: gpx0 {
 			     <26 0>, <26 1>, <27 0>, <27 1>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -181,7 +181,7 @@ gpx1: gpx1 {
 			     <30 0>, <30 1>, <31 0>, <31 1>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -189,7 +189,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -197,104 +197,104 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_hs_bus: i2c2-hs-bus {
+	i2c2_hs_bus: i2c2-hs-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_gpio_bus: i2c2-gpio-bus {
+	i2c2_gpio_bus: i2c2-gpio-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c3_hs_bus: i2c3-hs-bus {
+	i2c3_hs_bus: i2c3-hs-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c4_bus: i2c4-bus {
+	i2c4_bus: i2c4-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c5_bus: i2c5-bus {
+	i2c5_bus: i2c5-bus-pins {
 		samsung,pins = "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 			       "gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -302,7 +302,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 			       "gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -310,7 +310,7 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ac97_bus: ac97-bus {
+	ac97_bus: ac97-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 			       "gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -318,7 +318,7 @@ ac97_bus: ac97-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
 			       "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -326,7 +326,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
 			       "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -334,280 +334,280 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c6_bus: i2c6-bus {
+	i2c6_bus: i2c6-bus-pins {
 		samsung,pins = "gpb1-3", "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpb2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpb2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpb2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c7_bus: i2c7-bus {
+	i2c7_bus: i2c7-bus-pins {
 		samsung,pins = "gpb2-2", "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpb3-0", "gpb3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpb3-2", "gpb3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_hs_bus: i2c0-hs-bus {
+	i2c0_hs_bus: i2c0-hs-bus-pins {
 		samsung,pins = "gpb3-0", "gpb3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_hs_bus: i2c1-hs-bus {
+	i2c1_hs_bus: i2c1-hs-bus-pins {
 		samsung,pins = "gpb3-2", "gpb3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpc0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpc0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpc0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpc0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpc2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpc2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpc2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpc2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpc3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpc3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus8: sd2-bus-width8 {
+	sd2_bus8: sd2-bus-width8-pins {
 		samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_clk: sd3-clk {
+	sd3_clk: sd3-clk-pins {
 		samsung,pins = "gpc4-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cmd: sd3-cmd {
+	sd3_cmd: sd3-cmd-pins {
 		samsung,pins = "gpc4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cd: sd3-cd {
+	sd3_cd: sd3-cd-pins {
 		samsung,pins = "gpc4-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus1: sd3-bus-width1 {
+	sd3_bus1: sd3-bus-width1-pins {
 		samsung,pins = "gpc4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus4: sd3-bus-width4 {
+	sd3_bus4: sd3-bus-width4-pins {
 		samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpd0-0", "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpd0-2", "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	dp_hpd: dp_hpd {
+	dp_hpd: dp-hpd-pins {
 		samsung,pins = "gpx0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_cec: hdmi-cec {
+	hdmi_cec: hdmi-cec-pins {
 		samsung,pins = "gpx3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd: hdmi-hpd {
+	hdmi_hpd: hdmi-hpd-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 };
 
 &pinctrl_1 {
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -615,7 +615,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -623,7 +623,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -631,7 +631,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -639,7 +639,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -647,7 +647,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -655,7 +655,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -663,7 +663,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gph0: gph0 {
+	gph0: gph0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -671,7 +671,7 @@ gph0: gph0 {
 		#interrupt-cells = <2>;
 	};
 
-	gph1: gph1 {
+	gph1: gph1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -679,7 +679,7 @@ gph1: gph1 {
 		#interrupt-cells = <2>;
 	};
 
-	cam_gpio_a: cam-gpio-a {
+	cam_gpio_a: cam-gpio-a-pins {
 		samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
 			       "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
 			       "gpe1-0", "gpe1-1";
@@ -688,7 +688,7 @@ cam_gpio_a: cam-gpio-a {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_gpio_b: cam-gpio-b {
+	cam_gpio_b: cam-gpio-b-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
 			       "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -696,42 +696,42 @@ cam_gpio_b: cam-gpio-b {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_i2c2_bus: cam-i2c2-bus {
+	cam_i2c2_bus: cam-i2c2-bus-pins {
 		samsung,pins = "gpe0-6", "gpe1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_spi1_bus: cam-spi1-bus {
+	cam_spi1_bus: cam-spi1-bus-pins {
 		samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_i2c1_bus: cam-i2c1-bus {
+	cam_i2c1_bus: cam-i2c1-bus-pins {
 		samsung,pins = "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_i2c0_bus: cam-i2c0-bus {
+	cam_i2c0_bus: cam-i2c0-bus-pins {
 		samsung,pins = "gpf0-0", "gpf0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_spi0_bus: cam-spi0-bus {
+	cam_spi0_bus: cam-spi0-bus-pins {
 		samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_bayrgb_bus: cam-bayrgb-bus {
+	cam_bayrgb_bus: cam-bayrgb-bus-pins {
 		samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
 			       "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
 			       "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
@@ -742,7 +742,7 @@ cam_bayrgb_bus: cam-bayrgb-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a: cam-port-a {
+	cam_port_a: cam-port-a-pins {
 		samsung,pins = "gph0-0", "gph0-1", "gph0-2", "gph0-3",
 			       "gph1-0", "gph1-1", "gph1-2", "gph1-3",
 			       "gph1-4", "gph1-5", "gph1-6", "gph1-7";
@@ -753,7 +753,7 @@ cam_port_a: cam-port-a {
 };
 
 &pinctrl_2 {
-	gpv0: gpv0 {
+	gpv0: gpv0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -761,7 +761,7 @@ gpv0: gpv0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv1: gpv1 {
+	gpv1: gpv1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -769,7 +769,7 @@ gpv1: gpv1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv2: gpv2 {
+	gpv2: gpv2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -777,7 +777,7 @@ gpv2: gpv2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv3: gpv3 {
+	gpv3: gpv3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -785,7 +785,7 @@ gpv3: gpv3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv4: gpv4 {
+	gpv4: gpv4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -793,7 +793,7 @@ gpv4: gpv4 {
 		#interrupt-cells = <2>;
 	};
 
-	c2c_rxd: c2c-rxd {
+	c2c_rxd: c2c-rxd-pins {
 		samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
 			       "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
 			       "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
@@ -803,7 +803,7 @@ c2c_rxd: c2c-rxd {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	c2c_txd: c2c-txd {
+	c2c_txd: c2c-txd-pins {
 		samsung,pins = "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
 			       "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
 			       "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
@@ -815,7 +815,7 @@ c2c_txd: c2c-txd {
 };
 
 &pinctrl_3 {
-	gpz: gpz {
+	gpz: gpz-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -823,7 +823,7 @@ gpz: gpz {
 		#interrupt-cells = <2>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4", "gpz-5", "gpz-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 39bbe18145cf..497fbd009ae5 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -410,7 +410,7 @@ partition at 40000 {
 };
 
 &pinctrl_0 {
-	max77686_irq: max77686-irq {
+	max77686_irq: max77686-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index 2335c4687349..f7f5630a620b 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -587,63 +587,63 @@ &mmc_3 {
 };
 
 &pinctrl_0 {
-	wifi_en: wifi-en {
+	wifi_en: wifi-en-pins {
 		samsung,pins = "gpx0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	wifi_rst: wifi-rst {
+	wifi_rst: wifi-rst-pins {
 		samsung,pins = "gpx0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	power_key_irq: power-key-irq {
+	power_key_irq: power-key-irq-pins {
 		samsung,pins = "gpx1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ec_irq: ec-irq {
+	ec_irq: ec-irq-pins {
 		samsung,pins = "gpx1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	tps65090_irq: tps65090-irq {
+	tps65090_irq: tps65090-irq-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	usb3_vbus_en: usb3-vbus-en {
+	usb3_vbus_en: usb3-vbus-en-pins {
 		samsung,pins = "gpx2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	max77686_irq: max77686-irq {
+	max77686_irq: max77686-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lid_irq: lid-irq {
+	lid_irq: lid-irq-pins {
 		samsung,pins = "gpx3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -652,14 +652,14 @@ hdmi_hpd_irq: hdmi-hpd-irq {
 };
 
 &pinctrl_1 {
-	arb_their_claim: arb-their-claim {
+	arb_their_claim: arb-their-claim-pins {
 		samsung,pins = "gpe0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	arb_our_claim: arb-our-claim {
+	arb_our_claim: arb-our-claim-pins {
 		samsung,pins = "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5250-snow-rev5.dts b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
index f8ca61df6981..0a47597d6f0d 100644
--- a/arch/arm/boot/dts/exynos5250-snow-rev5.dts
+++ b/arch/arm/boot/dts/exynos5250-snow-rev5.dts
@@ -47,7 +47,7 @@ max98090: audio-codec at 10 {
 };
 
 &pinctrl_0 {
-	max98090_irq: max98090-irq {
+	max98090_irq: max98090-irq-pins {
 		samsung,pins = "gpx0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts
index a630bc654a49..906aa7aae710 100644
--- a/arch/arm/boot/dts/exynos5250-snow.dts
+++ b/arch/arm/boot/dts/exynos5250-snow.dts
@@ -43,7 +43,7 @@ max98095: audio-codec at 11 {
 };
 
 &pinctrl_0 {
-	max98095_en: max98095-en {
+	max98095_en: max98095-en-pins {
 		samsung,pins = "gpx1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index e0feedcf54bb..d52b5e4e5870 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -451,63 +451,63 @@ &mmc_1 {
 };
 
 &pinctrl_0 {
-	s5m8767_dvs: s5m8767-dvs {
+	s5m8767_dvs: s5m8767-dvs-pins {
 		samsung,pins = "gpd1-0", "gpd1-1", "gpd1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	dp_hpd_gpio: dp-hpd {
+	dp_hpd_gpio: dp-hpd-pins {
 		samsung,pins = "gpc3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	trackpad_irq: trackpad-irq {
+	trackpad_irq: trackpad-irq-pins {
 		samsung,pins = "gpx1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	power_key_irq: power-key-irq {
+	power_key_irq: power-key-irq-pins {
 		samsung,pins = "gpx1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ec_irq: ec-irq {
+	ec_irq: ec-irq-pins {
 		samsung,pins = "gpx1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	s5m8767_ds: s5m8767-ds {
+	s5m8767_ds: s5m8767-ds-pins {
 		samsung,pins = "gpx2-3", "gpx2-4", "gpx2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	s5m8767_irq: s5m8767-irq {
+	s5m8767_irq: s5m8767-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lid_irq: lid-irq {
+	lid_irq: lid-irq-pins {
 		samsung,pins = "gpx3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -516,7 +516,7 @@ hdmi_hpd_irq: hdmi-hpd-irq {
 };
 
 &pinctrl_1 {
-	hsic_reset: hsic-reset {
+	hsic_reset: hsic-reset-pins {
 		samsung,pins = "gpe1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:08 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:08 +0100
Subject: [PATCH v2 14/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos5260
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-8-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi  | 148 ++++++++++-----------
 arch/arm/boot/dts/exynos5260-xyref5260.dts |   2 +-
 2 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
index 17e2f3e0d71e..150607f8103d 100644
--- a/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5260-pinctrl.dtsi
@@ -12,7 +12,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -20,7 +20,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -28,7 +28,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -36,7 +36,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -44,7 +44,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -52,7 +52,7 @@ gpb1: gpb1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb2: gpb2 {
+	gpb2: gpb2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -60,7 +60,7 @@ gpb2: gpb2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb3: gpb3 {
+	gpb3: gpb3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -68,7 +68,7 @@ gpb3: gpb3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb4: gpb4 {
+	gpb4: gpb4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -76,7 +76,7 @@ gpb4: gpb4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb5: gpb5 {
+	gpb5: gpb5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -84,7 +84,7 @@ gpb5: gpb5 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -92,7 +92,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -100,7 +100,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd2: gpd2 {
+	gpd2: gpd2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -108,7 +108,7 @@ gpd2: gpd2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -116,7 +116,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -124,7 +124,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -132,7 +132,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -140,7 +140,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk0: gpk0 {
+	gpk0: gpk0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -148,7 +148,7 @@ gpk0: gpk0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -164,7 +164,7 @@ gpx0: gpx0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -180,7 +180,7 @@ gpx1: gpx1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -188,7 +188,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -196,63 +196,63 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	usb3_vbus0_en: usb3-vbus0-en {
+	usb3_vbus0_en: usb3-vbus0-en-pins {
 		samsung,pins = "gpa2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 				"gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -260,7 +260,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 				"gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -268,105 +268,105 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	spdif1_bus: spdif1-bus {
+	spdif1_bus: spdif1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-2", "gpb1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c0_hs_bus: i2c0-hs-bus {
+	i2c0_hs_bus: i2c0-hs-bus-pins {
 		samsung,pins = "gpb3-0", "gpb3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c1_hs_bus: i2c1-hs-bus {
+	i2c1_hs_bus: i2c1-hs-bus-pins {
 		samsung,pins = "gpb3-2", "gpb3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c2_hs_bus: i2c2-hs-bus {
+	i2c2_hs_bus: i2c2-hs-bus-pins {
 		samsung,pins = "gpb3-4", "gpb3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c3_hs_bus: i2c3-hs-bus {
+	i2c3_hs_bus: i2c3-hs-bus-pins {
 		samsung,pins = "gpb3-6", "gpb3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c4_bus: i2c4-bus {
+	i2c4_bus: i2c4-bus-pins {
 		samsung,pins = "gpb4-0", "gpb4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c5_bus: i2c5-bus {
+	i2c5_bus: i2c5-bus-pins {
 		samsung,pins = "gpb4-2", "gpb4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c6_bus: i2c6-bus {
+	i2c6_bus: i2c6-bus-pins {
 		samsung,pins = "gpb4-4", "gpb4-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c7_bus: i2c7-bus {
+	i2c7_bus: i2c7-bus-pins {
 		samsung,pins = "gpb4-6", "gpb4-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c8_bus: i2c8-bus {
+	i2c8_bus: i2c8-bus-pins {
 		samsung,pins = "gpb5-0", "gpb5-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c9_bus: i2c9-bus {
+	i2c9_bus: i2c9-bus-pins {
 		samsung,pins = "gpb5-2", "gpb5-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c10_bus: i2c10-bus {
+	i2c10_bus: i2c10-bus-pins {
 		samsung,pins = "gpb5-4", "gpb5-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	i2c11_bus: i2c11-bus {
+	i2c11_bus: i2c11-bus-pins {
 		samsung,pins = "gpb5-6", "gpb5-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_gpio_a: cam-gpio-a {
+	cam_gpio_a: cam-gpio-a-pins {
 		samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
 			"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
 			"gpe1-0", "gpe1-1";
@@ -375,7 +375,7 @@ cam_gpio_a: cam-gpio-a {
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_gpio_b: cam-gpio-b {
+	cam_gpio_b: cam-gpio-b-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
 			"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -383,28 +383,28 @@ cam_gpio_b: cam-gpio-b {
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_i2c1_bus: cam-i2c1-bus {
+	cam_i2c1_bus: cam-i2c1-bus-pins {
 		samsung,pins = "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_i2c0_bus: cam-i2c0-bus {
+	cam_i2c0_bus: cam-i2c0-bus-pins {
 		samsung,pins = "gpf0-0", "gpf0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_spi0_bus: cam-spi0-bus {
+	cam_spi0_bus: cam-spi0-bus-pins {
 		samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV1>;
 	};
 
-	cam_spi1_bus: cam-spi1-bus {
+	cam_spi1_bus: cam-spi1-bus-pins {
 		samsung,pins = "gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -413,7 +413,7 @@ cam_spi1_bus: cam-spi1-bus {
 };
 
 &pinctrl_1 {
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -421,7 +421,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -429,7 +429,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -437,7 +437,7 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -445,7 +445,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc4: gpc4 {
+	gpc4: gpc4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -453,112 +453,112 @@ gpc4: gpc4 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpc0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpc0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpc0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd0_rdqs: sd0-rdqs {
+	sd0_rdqs: sd0-rdqs-pins {
 		samsung,pins = "gpc0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpc1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpc1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpc1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpc1-3", "gpc1-4", "gpc1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd1_bus8: sd1-bus-width8 {
+	sd1_bus8: sd1-bus-width8-pins {
 		samsung,pins = "gpc4-0", "gpc4-1", "gpc4-2", "gpc4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpc2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpc2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5260_PIN_DRV_LV6>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -567,7 +567,7 @@ sd2_bus4: sd2-bus-width4 {
 };
 
 &pinctrl_2 {
-	gpz0: gpz0 {
+	gpz0: gpz0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -575,7 +575,7 @@ gpz0: gpz0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpz1: gpz1 {
+	gpz1: gpz1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts
index 0dc2ec16aa0a..82d8441c8908 100644
--- a/arch/arm/boot/dts/exynos5260-xyref5260.dts
+++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts
@@ -38,7 +38,7 @@ xrtcxti: xrtcxti {
 };
 
 &pinctrl_0 {
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:09 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:09 +0100
Subject: [PATCH v2 15/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos5410
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-9-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5410-odroidxu.dts |  10 +-
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi | 170 +++++++++++-----------
 arch/arm/boot/dts/exynos5410-smdk5410.dts |   4 +-
 3 files changed, 92 insertions(+), 92 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5410-odroidxu.dts b/arch/arm/boot/dts/exynos5410-odroidxu.dts
index 9f2200dd5b43..ca121859b124 100644
--- a/arch/arm/boot/dts/exynos5410-odroidxu.dts
+++ b/arch/arm/boot/dts/exynos5410-odroidxu.dts
@@ -547,14 +547,14 @@ &mmc_2 {
 };
 
 &pinctrl_0 {
-	emmc_nrst_pin: emmc-nrst {
+	emmc_nrst_pin: emmc-nrst-pins {
 		samsung,pins = "gpd1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	sd2_wp: sd2-wp {
+	sd2_wp: sd2-wp-pins {
 		samsung,pins = "gpm5-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		/* Pin is floating so be sure to disable write-protect */
@@ -562,14 +562,14 @@ sd2_wp: sd2-wp {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	pmic_dvs_2: pmic-dvs-2 {
+	pmic_dvs_2: pmic-dvs-2-pins {
 		samsung,pins = "gpx0-0", "gpx0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pmic_dvs_1: pmic-dvs-1 {
+	pmic_dvs_1: pmic-dvs-1-pins {
 		samsung,pins = "gpx0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -577,7 +577,7 @@ pmic_dvs_1: pmic-dvs-1 {
 		samsung,pin-val = <1>;
 	};
 
-	max77802_irq: max77802-irq {
+	max77802_irq: max77802-irq-pins {
 		samsung,pins = "gpx0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
index 9599ba8ba798..6c7814b4372e 100644
--- a/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5410-pinctrl.dtsi
@@ -9,7 +9,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -17,7 +17,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -25,7 +25,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -33,7 +33,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -41,7 +41,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -49,7 +49,7 @@ gpb1: gpb1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb2: gpb2 {
+	gpb2: gpb2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -57,7 +57,7 @@ gpb2: gpb2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb3: gpb3 {
+	gpb3: gpb3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -65,7 +65,7 @@ gpb3: gpb3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -73,7 +73,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -81,7 +81,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -89,7 +89,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -97,12 +97,12 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm5: gpm5 {
+	gpm5: gpm5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -110,7 +110,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -118,7 +118,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -126,7 +126,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -134,7 +134,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -142,7 +142,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -150,7 +150,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -158,7 +158,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -166,7 +166,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gph0: gph0 {
+	gph0: gph0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -174,7 +174,7 @@ gph0: gph0 {
 		#interrupt-cells = <2>;
 	};
 
-	gph1: gph1 {
+	gph1: gph1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -182,52 +182,52 @@ gph1: gph1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpm7: gpm7 {
+	gpm7: gpm7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy0: gpy0 {
+	gpy0: gpy0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy1: gpy1 {
+	gpy1: gpy1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy2: gpy2 {
+	gpy2: gpy2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy3: gpy3 {
+	gpy3: gpy3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy4: gpy4 {
+	gpy4: gpy4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy5: gpy5 {
+	gpy5: gpy5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy6: gpy6 {
+	gpy6: gpy6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy7: gpy7 {
+	gpy7: gpy7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -244,7 +244,7 @@ gpx0: gpx0 {
 			     <27 1>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -261,7 +261,7 @@ gpx1: gpx1 {
 			     <31 1>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -269,7 +269,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -277,210 +277,210 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c4_hs_bus: i2c4-hs-bus {
+	i2c4_hs_bus: i2c4-hs-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c5_hs_bus: i2c5-hs-bus {
+	i2c5_hs_bus: i2c5-hs-bus-pins {
 		samsung,pins = "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c6_hs_bus: i2c6-hs-bus {
+	i2c6_hs_bus: i2c6-hs-bus-pins {
 		samsung,pins = "gpb1-3", "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpb2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpb2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpb2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c7_hs_bus: i2c7-hs-bus {
+	i2c7_hs_bus: i2c7-hs-bus-pins {
 		samsung,pins = "gpb2-2", "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpb3-0", "gpb3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpb3-2", "gpb3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpc0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpc0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpc0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpc0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpc2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpc2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -489,7 +489,7 @@ sd0_bus8: sd0-bus-width8 {
 };
 
 &pinctrl_1 {
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -497,7 +497,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -505,7 +505,7 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj2: gpj2 {
+	gpj2: gpj2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -513,7 +513,7 @@ gpj2: gpj2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj3: gpj3 {
+	gpj3: gpj3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -521,7 +521,7 @@ gpj3: gpj3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj4: gpj4 {
+	gpj4: gpj4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -529,7 +529,7 @@ gpj4: gpj4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk0: gpk0 {
+	gpk0: gpk0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -537,7 +537,7 @@ gpk0: gpk0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk1: gpk1 {
+	gpk1: gpk1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -545,7 +545,7 @@ gpk1: gpk1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk2: gpk2 {
+	gpk2: gpk2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -553,7 +553,7 @@ gpk2: gpk2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpk3: gpk3 {
+	gpk3: gpk3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -561,28 +561,28 @@ gpk3: gpk3 {
 		#interrupt-cells = <2>;
 	};
 
-	usb3_1_oc: usb3-1-oc {
+	usb3_1_oc: usb3-1-oc-pins {
 		samsung,pins = "gpk2-4", "gpk2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb3_1_vbusctrl: usb3-1-vbusctrl {
+	usb3_1_vbusctrl: usb3-1-vbusctrl-pins {
 		samsung,pins = "gpk2-6", "gpk2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb3_0_oc: usb3-0-oc {
+	usb3_0_oc: usb3-0-oc-pins {
 		samsung,pins = "gpk3-0", "gpk3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb3_0_vbusctrl: usb3-0-vbusctrl {
+	usb3_0_vbusctrl: usb3-0-vbusctrl-pins {
 		samsung,pins = "gpk3-2", "gpk3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -591,7 +591,7 @@ usb3_0_vbusctrl: usb3-0-vbusctrl {
 };
 
 &pinctrl_2 {
-	gpv0: gpv0 {
+	gpv0: gpv0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -599,7 +599,7 @@ gpv0: gpv0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv1: gpv1 {
+	gpv1: gpv1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -607,7 +607,7 @@ gpv1: gpv1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv2: gpv2 {
+	gpv2: gpv2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -615,7 +615,7 @@ gpv2: gpv2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv3: gpv3 {
+	gpv3: gpv3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -623,7 +623,7 @@ gpv3: gpv3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv4: gpv4 {
+	gpv4: gpv4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -633,7 +633,7 @@ gpv4: gpv4 {
 };
 
 &pinctrl_3 {
-	gpz: gpz {
+	gpz: gpz-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -641,7 +641,7 @@ gpz: gpz {
 		#interrupt-cells = <2>;
 	};
 
-	audi2s0_bus: audi2s0-bus {
+	audi2s0_bus: audi2s0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4";
 		samsung,pin-function = <2>;
diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts
index 2a3ade77a2de..5b2e567809ae 100644
--- a/arch/arm/boot/dts/exynos5410-smdk5410.dts
+++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts
@@ -66,14 +66,14 @@ &mmc_2 {
 };
 
 &pinctrl_0 {
-	srom_ctl: srom-ctl {
+	srom_ctl: srom-ctl-pins {
 		samsung,pins = "gpy0-3", "gpy0-4", "gpy0-5",
 			       "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	srom_ebi: srom-ebi {
+	srom_ebi: srom-ebi-pins {
 		samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3",
 			       "gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7",
 			       "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3",
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:11 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:11 +0100
Subject: [PATCH v2 17/28] arm64: dts: exynos: align pinctrl with dtschema in
 Exynos5433
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-11-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

The macros used to define pin configuration do not work well with node
name suffix "-pin" or prefix "pin-", so level of indirection via second
macro is needed.  For similar reason pcie-wlanen has to stop using the
macro.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../boot/dts/exynos/exynos5433-pinctrl.dtsi   | 211 +++++++-------
 .../dts/exynos/exynos5433-tm2-common.dtsi     | 259 +++++++++---------
 2 files changed, 241 insertions(+), 229 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
index 32a6518517e5..4b46af3e164d 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi
@@ -11,16 +11,25 @@
 
 #include <dt-bindings/pinctrl/samsung.h>
 
-#define PIN(_func, _pin, _pull, _drv)					\
-	_pin {								\
+#define PIN(_pin, _func, _pull, _drv)					\
+	pin- ## _pin {							\
 		samsung,pins = #_pin;					\
 		samsung,pin-function = <EXYNOS_PIN_FUNC_ ##_func>;	\
 		samsung,pin-pud = <EXYNOS_PIN_PULL_ ##_pull>;		\
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_ ##_drv>;		\
 	}
 
+#define PIN_IN(_pin, _pull, _drv)					\
+	PIN(_pin, INPUT, _pull, _drv)
+
+#define PIN_OT(_pin, _pull, _drv)					\
+	PIN(_pin, OUTPUT, _pull, _drv)
+
+#define PIN_F2(_pin, _pull, _drv)					\
+	PIN(_pin, 2, _pull, _drv)
+
 &pinctrl_alive {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -37,7 +46,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -54,7 +63,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -62,7 +71,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa3: gpa3 {
+	gpa3: gpa3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -70,7 +79,7 @@ gpa3: gpa3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -78,7 +87,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -86,7 +95,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -94,7 +103,7 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf4: gpf4 {
+	gpf4: gpf4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -102,7 +111,7 @@ gpf4: gpf4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf5: gpf5 {
+	gpf5: gpf5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -112,7 +121,7 @@ gpf5: gpf5 {
 };
 
 &pinctrl_aud {
-	gpz0: gpz0 {
+	gpz0: gpz0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -120,7 +129,7 @@ gpz0: gpz0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpz1: gpz1 {
+	gpz1: gpz1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -128,7 +137,7 @@ gpz1: gpz1 {
 		#interrupt-cells = <2>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
 				"gpz0-4", "gpz0-5", "gpz0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -136,14 +145,14 @@ i2s0_bus: i2s0-bus {
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pcm0_bus: pcm0-bus {
+	pcm0_bus: pcm0-bus-pins {
 		samsung,pins = "gpz1-0", "gpz1-1", "gpz1-2", "gpz1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	uart_aud_bus: uart-aud-bus {
+	uart_aud_bus: uart-aud-bus-pins {
 		samsung,pins = "gpz1-3", "gpz1-2", "gpz1-1", "gpz1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -152,7 +161,7 @@ uart_aud_bus: uart-aud-bus {
 };
 
 &pinctrl_cpif {
-	gpv6: gpv6 {
+	gpv6: gpv6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -162,7 +171,7 @@ gpv6: gpv6 {
 };
 
 &pinctrl_ese {
-	gpj2: gpj2 {
+	gpj2: gpj2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -172,7 +181,7 @@ gpj2: gpj2 {
 };
 
 &pinctrl_finger {
-	gpd5: gpd5 {
+	gpd5: gpd5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -180,14 +189,14 @@ gpd5: gpd5 {
 		#interrupt-cells = <2>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpd5-0", "gpd5-2", "gpd5-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c6_bus: hs-i2c6-bus {
+	hs_i2c6_bus: hs-i2c6-bus-pins {
 		samsung,pins = "gpd5-3", "gpd5-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -196,7 +205,7 @@ hs_i2c6_bus: hs-i2c6-bus {
 };
 
 &pinctrl_fsys {
-	gph1: gph1 {
+	gph1: gph1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -204,7 +213,7 @@ gph1: gph1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr4: gpr4 {
+	gpr4: gpr4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -212,7 +221,7 @@ gpr4: gpr4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr0: gpr0 {
+	gpr0: gpr0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -220,7 +229,7 @@ gpr0: gpr0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr1: gpr1 {
+	gpr1: gpr1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -228,7 +237,7 @@ gpr1: gpr1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr2: gpr2 {
+	gpr2: gpr2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -236,7 +245,7 @@ gpr2: gpr2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr3: gpr3 {
+	gpr3: gpr3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -244,139 +253,139 @@ gpr3: gpr3 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpr0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpr0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_rdqs: sd0-rdqs {
+	sd0_rdqs: sd0-rdqs-pins {
 		samsung,pins = "gpr0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_qrdy: sd0-qrdy {
+	sd0_qrdy: sd0-qrdy-pins {
 		samsung,pins = "gpr0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpr1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpr2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpr2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpr3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd1_bus8: sd1-bus-width8 {
+	sd1_bus8: sd1-bus-width8-pins {
 		samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	pcie_bus: pcie_bus {
+	pcie_bus: pcie-bus-pins {
 		samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpr4-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpr4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpr4-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpr4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
-	sd2_clk_output: sd2-clk-output {
+	sd2_clk_output: sd2-clk-output-pins {
 		samsung,pins = "gpr4-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR3>;
 	};
 
-	sd2_cmd_output: sd2-cmd-output {
+	sd2_cmd_output: sd2-cmd-output-pins {
 		samsung,pins = "gpr4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -385,7 +394,7 @@ sd2_cmd_output: sd2-cmd-output {
 };
 
 &pinctrl_imem {
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -395,7 +404,7 @@ gpf0: gpf0 {
 };
 
 &pinctrl_nfc {
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -403,7 +412,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c4_bus: hs-i2c4-bus {
+	hs_i2c4_bus: hs-i2c4-bus-pins {
 		samsung,pins = "gpj0-1", "gpj0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -412,7 +421,7 @@ hs_i2c4_bus: hs-i2c4-bus {
 };
 
 &pinctrl_peric {
-	gpv7: gpv7 {
+	gpv7: gpv7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -420,7 +429,7 @@ gpv7: gpv7 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -428,7 +437,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -436,7 +445,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -444,7 +453,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -452,7 +461,7 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -460,7 +469,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -468,7 +477,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -476,7 +485,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -484,7 +493,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd2: gpd2 {
+	gpd2: gpd2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -492,7 +501,7 @@ gpd2: gpd2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd4: gpd4 {
+	gpd4: gpd4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -500,7 +509,7 @@ gpd4: gpd4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd8: gpd8 {
+	gpd8: gpd8-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -508,7 +517,7 @@ gpd8: gpd8 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd6: gpd6 {
+	gpd6: gpd6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -516,7 +525,7 @@ gpd6: gpd6 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd7: gpd7 {
+	gpd7: gpd7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -524,7 +533,7 @@ gpd7: gpd7 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -532,7 +541,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -540,7 +549,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg3: gpg3 {
+	gpg3: gpg3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -548,21 +557,21 @@ gpg3: gpg3 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c8_bus: hs-i2c8-bus {
+	hs_i2c8_bus: hs-i2c8-bus-pins {
 		samsung,pins = "gpb0-1", "gpb0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c9_bus: hs-i2c9-bus {
+	hs_i2c9_bus: hs-i2c9-bus-pins {
 		samsung,pins = "gpb0-3", "gpb0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
 				"gpd4-3", "gpd4-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -570,7 +579,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpd4-0", "gpd4-1", "gpd4-2",
 				"gpd4-3", "gpd4-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -578,193 +587,193 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpd4-3", "gpd4-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_spi_pin0: fimc-is-spi-pin0 {
+	fimc_is_spi_pin0: fimc-is-spi-pin0-pins {
 		samsung,pins = "gpc3-3", "gpc3-2", "gpc3-1", "gpc3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_spi_pin1: fimc-is-spi-pin1 {
+	fimc_is_spi_pin1: fimc-is-spi-pin1-pins {
 		samsung,pins = "gpc3-7", "gpc3-6", "gpc3-5", "gpc3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	uart0_bus: uart0-bus {
+	uart0_bus: uart0-bus-pins {
 		samsung,pins = "gpd0-3", "gpd0-2", "gpd0-1", "gpd0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	hs_i2c2_bus: hs-i2c2-bus {
+	hs_i2c2_bus: hs-i2c2-bus-pins {
 		samsung,pins = "gpd0-3", "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	uart2_bus: uart2-bus {
+	uart2_bus: uart2-bus-pins {
 		samsung,pins = "gpd1-5", "gpd1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	uart1_bus: uart1-bus {
+	uart1_bus: uart1-bus-pins {
 		samsung,pins = "gpd1-3", "gpd1-2", "gpd1-1", "gpd1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 	};
 
-	hs_i2c3_bus: hs-i2c3-bus {
+	hs_i2c3_bus: hs-i2c3-bus-pins {
 		samsung,pins = "gpd1-3", "gpd1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c0_bus: hs-i2c0-bus {
+	hs_i2c0_bus: hs-i2c0-bus-pins {
 		samsung,pins = "gpd2-1", "gpd2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c1_bus: hs-i2c1-bus {
+	hs_i2c1_bus: hs-i2c1-bus-pins {
 		samsung,pins = "gpd2-3", "gpd2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpd6-2", "gpd6-4", "gpd6-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c7_bus: hs-i2c7-bus {
+	hs_i2c7_bus: hs-i2c7-bus-pins {
 		samsung,pins = "gpd2-7", "gpd2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpd8-0", "gpd6-0", "gpd6-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c10_bus: hs-i2c10-bus {
+	hs_i2c10_bus: hs-i2c10-bus-pins {
 		samsung,pins = "gpg3-1", "gpg3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	hs_i2c11_bus: hs-i2c11-bus {
+	hs_i2c11_bus: hs-i2c11-bus-pins {
 		samsung,pins = "gpg3-3", "gpg3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	spi3_bus: spi3-bus {
+	spi3_bus: spi3-bus-pins {
 		samsung,pins = "gpg3-4", "gpg3-6", "gpg3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	spi4_bus: spi4-bus {
+	spi4_bus: spi4-bus-pins {
 		samsung,pins = "gpv7-1", "gpv7-3", "gpv7-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_uart: fimc-is-uart {
+	fimc_is_uart: fimc-is-uart-pins {
 		samsung,pins = "gpc1-1", "gpc0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch0_i2c: fimc-is-ch0_i2c {
+	fimc_is_ch0_i2c: fimc-is-ch0-i2c-pins {
 		samsung,pins = "gpc2-1", "gpc2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch0_mclk: fimc-is-ch0_mclk {
+	fimc_is_ch0_mclk: fimc-is-ch0-mclk-pins {
 		samsung,pins = "gpd7-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch1_i2c: fimc-is-ch1-i2c {
+	fimc_is_ch1_i2c: fimc-is-ch1-i2c-pins {
 		samsung,pins = "gpc2-3", "gpc2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch1_mclk: fimc-is-ch1-mclk {
+	fimc_is_ch1_mclk: fimc-is-ch1-mclk-pins {
 		samsung,pins = "gpd7-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch2_i2c: fimc-is-ch2-i2c {
+	fimc_is_ch2_i2c: fimc-is-ch2-i2c-pins {
 		samsung,pins = "gpc2-5", "gpc2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
 	};
 
-	fimc_is_ch2_mclk: fimc-is-ch2-mclk {
+	fimc_is_ch2_mclk: fimc-is-ch2-mclk-pins {
 		samsung,pins = "gpd7-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -773,7 +782,7 @@ fimc_is_ch2_mclk: fimc-is-ch2-mclk {
 };
 
 &pinctrl_touch {
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -781,7 +790,7 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c5_bus: hs-i2c5-bus {
+	hs_i2c5_bus: hs-i2c5-bus-pins {
 		samsung,pins = "gpj1-1", "gpj1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
index cbcc01a66aab..be1b6b7da059 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -1011,80 +1011,80 @@ &pinctrl_alive {
 	pinctrl-0 = <&initial_alive>;
 
 	initial_alive: initial-state {
-		PIN(INPUT, gpa0-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-1, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-3, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa0-6, NONE, FAST_SR1);
-		PIN(INPUT, gpa0-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa1-0, UP, FAST_SR1);
-		PIN(INPUT, gpa1-1, UP, FAST_SR1);
-		PIN(INPUT, gpa1-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa1-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpa1-5, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-6, NONE, FAST_SR1);
-		PIN(INPUT, gpa1-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa2-0, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-1, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa2-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpa2-7, NONE, FAST_SR1);
-
-		PIN(INPUT, gpa3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-2, NONE, FAST_SR1);
-		PIN(INPUT, gpa3-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-4, NONE, FAST_SR1);
-		PIN(INPUT, gpa3-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpa3-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf1-0, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-1, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf1-4, UP, FAST_SR1);
-		PIN(OUTPUT, gpf1-5, NONE, FAST_SR1);
-		PIN(INPUT, gpf1-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf1-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf2-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf2-3, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf3-2, NONE, FAST_SR1);
-		PIN(INPUT, gpf3-3, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf4-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf4-7, DOWN, FAST_SR1);
-
-		PIN(INPUT, gpf5-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-3, DOWN, FAST_SR1);
-		PIN(OUTPUT, gpf5-4, NONE, FAST_SR1);
-		PIN(INPUT, gpf5-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf5-7, DOWN, FAST_SR1);
+		PIN_IN(gpa0-0, DOWN, FAST_SR1);
+		PIN_IN(gpa0-1, NONE, FAST_SR1);
+		PIN_IN(gpa0-2, DOWN, FAST_SR1);
+		PIN_IN(gpa0-3, NONE, FAST_SR1);
+		PIN_IN(gpa0-4, NONE, FAST_SR1);
+		PIN_IN(gpa0-5, DOWN, FAST_SR1);
+		PIN_IN(gpa0-6, NONE, FAST_SR1);
+		PIN_IN(gpa0-7, NONE, FAST_SR1);
+
+		PIN_IN(gpa1-0, UP, FAST_SR1);
+		PIN_IN(gpa1-1, UP, FAST_SR1);
+		PIN_IN(gpa1-2, NONE, FAST_SR1);
+		PIN_IN(gpa1-3, DOWN, FAST_SR1);
+		PIN_IN(gpa1-4, DOWN, FAST_SR1);
+		PIN_IN(gpa1-5, NONE, FAST_SR1);
+		PIN_IN(gpa1-6, NONE, FAST_SR1);
+		PIN_IN(gpa1-7, NONE, FAST_SR1);
+
+		PIN_IN(gpa2-0, NONE, FAST_SR1);
+		PIN_IN(gpa2-1, NONE, FAST_SR1);
+		PIN_IN(gpa2-2, NONE, FAST_SR1);
+		PIN_IN(gpa2-3, DOWN, FAST_SR1);
+		PIN_IN(gpa2-4, NONE, FAST_SR1);
+		PIN_IN(gpa2-5, DOWN, FAST_SR1);
+		PIN_IN(gpa2-6, DOWN, FAST_SR1);
+		PIN_IN(gpa2-7, NONE, FAST_SR1);
+
+		PIN_IN(gpa3-0, DOWN, FAST_SR1);
+		PIN_IN(gpa3-1, DOWN, FAST_SR1);
+		PIN_IN(gpa3-2, NONE, FAST_SR1);
+		PIN_IN(gpa3-3, DOWN, FAST_SR1);
+		PIN_IN(gpa3-4, NONE, FAST_SR1);
+		PIN_IN(gpa3-5, DOWN, FAST_SR1);
+		PIN_IN(gpa3-6, DOWN, FAST_SR1);
+		PIN_IN(gpa3-7, DOWN, FAST_SR1);
+
+		PIN_IN(gpf1-0, NONE, FAST_SR1);
+		PIN_IN(gpf1-1, NONE, FAST_SR1);
+		PIN_IN(gpf1-2, DOWN, FAST_SR1);
+		PIN_IN(gpf1-4, UP, FAST_SR1);
+		PIN_OT(gpf1-5, NONE, FAST_SR1);
+		PIN_IN(gpf1-6, DOWN, FAST_SR1);
+		PIN_IN(gpf1-7, DOWN, FAST_SR1);
+
+		PIN_IN(gpf2-0, DOWN, FAST_SR1);
+		PIN_IN(gpf2-1, DOWN, FAST_SR1);
+		PIN_IN(gpf2-2, DOWN, FAST_SR1);
+		PIN_IN(gpf2-3, DOWN, FAST_SR1);
+
+		PIN_IN(gpf3-0, DOWN, FAST_SR1);
+		PIN_IN(gpf3-1, DOWN, FAST_SR1);
+		PIN_IN(gpf3-2, NONE, FAST_SR1);
+		PIN_IN(gpf3-3, DOWN, FAST_SR1);
+
+		PIN_IN(gpf4-0, DOWN, FAST_SR1);
+		PIN_IN(gpf4-1, DOWN, FAST_SR1);
+		PIN_IN(gpf4-2, DOWN, FAST_SR1);
+		PIN_IN(gpf4-3, DOWN, FAST_SR1);
+		PIN_IN(gpf4-4, DOWN, FAST_SR1);
+		PIN_IN(gpf4-5, DOWN, FAST_SR1);
+		PIN_IN(gpf4-6, DOWN, FAST_SR1);
+		PIN_IN(gpf4-7, DOWN, FAST_SR1);
+
+		PIN_IN(gpf5-0, DOWN, FAST_SR1);
+		PIN_IN(gpf5-1, DOWN, FAST_SR1);
+		PIN_IN(gpf5-2, DOWN, FAST_SR1);
+		PIN_IN(gpf5-3, DOWN, FAST_SR1);
+		PIN_OT(gpf5-4, NONE, FAST_SR1);
+		PIN_IN(gpf5-5, DOWN, FAST_SR1);
+		PIN_IN(gpf5-6, DOWN, FAST_SR1);
+		PIN_IN(gpf5-7, DOWN, FAST_SR1);
 	};
 
-	te_irq: te-irq {
+	te_irq: te-irq-pins {
 		samsung,pins = "gpf1-3";
 		samsung,pin-function = <0xf>;
 	};
@@ -1095,8 +1095,8 @@ &pinctrl_cpif {
 	pinctrl-0 = <&initial_cpif>;
 
 	initial_cpif: initial-state {
-		PIN(INPUT, gpv6-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpv6-1, DOWN, FAST_SR1);
+		PIN_IN(gpv6-0, DOWN, FAST_SR1);
+		PIN_IN(gpv6-1, DOWN, FAST_SR1);
 	};
 };
 
@@ -1104,13 +1104,16 @@ &pinctrl_ese {
 	pinctrl-names = "default";
 	pinctrl-0 = <&initial_ese>;
 
-	pcie_wlanen: pcie-wlanen {
-		PIN(INPUT, gpj2-0, UP, FAST_SR4);
+	pcie_wlanen: pcie-wlanen-pins {
+		samsung,pins = "gpj2-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR4>;
 	};
 
 	initial_ese: initial-state {
-		PIN(INPUT, gpj2-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpj2-2, DOWN, FAST_SR1);
+		PIN_IN(gpj2-1, DOWN, FAST_SR1);
+		PIN_IN(gpj2-2, DOWN, FAST_SR1);
 	};
 };
 
@@ -1119,11 +1122,11 @@ &pinctrl_fsys {
 	pinctrl-0 = <&initial_fsys>;
 
 	initial_fsys: initial-state {
-		PIN(INPUT, gpr3-0, NONE, FAST_SR1);
-		PIN(INPUT, gpr3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpr3-7, NONE, FAST_SR1);
+		PIN_IN(gpr3-0, NONE, FAST_SR1);
+		PIN_IN(gpr3-1, DOWN, FAST_SR1);
+		PIN_IN(gpr3-2, DOWN, FAST_SR1);
+		PIN_IN(gpr3-3, DOWN, FAST_SR1);
+		PIN_IN(gpr3-7, NONE, FAST_SR1);
 	};
 };
 
@@ -1132,14 +1135,14 @@ &pinctrl_imem {
 	pinctrl-0 = <&initial_imem>;
 
 	initial_imem: initial-state {
-		PIN(INPUT, gpf0-0, UP, FAST_SR1);
-		PIN(INPUT, gpf0-1, UP, FAST_SR1);
-		PIN(INPUT, gpf0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-3, UP, FAST_SR1);
-		PIN(INPUT, gpf0-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-5, NONE, FAST_SR1);
-		PIN(INPUT, gpf0-6, DOWN, FAST_SR1);
-		PIN(INPUT, gpf0-7, UP, FAST_SR1);
+		PIN_IN(gpf0-0, UP, FAST_SR1);
+		PIN_IN(gpf0-1, UP, FAST_SR1);
+		PIN_IN(gpf0-2, DOWN, FAST_SR1);
+		PIN_IN(gpf0-3, UP, FAST_SR1);
+		PIN_IN(gpf0-4, DOWN, FAST_SR1);
+		PIN_IN(gpf0-5, NONE, FAST_SR1);
+		PIN_IN(gpf0-6, DOWN, FAST_SR1);
+		PIN_IN(gpf0-7, UP, FAST_SR1);
 	};
 };
 
@@ -1148,7 +1151,7 @@ &pinctrl_nfc {
 	pinctrl-0 = <&initial_nfc>;
 
 	initial_nfc: initial-state {
-		PIN(INPUT, gpj0-2, DOWN, FAST_SR1);
+		PIN_IN(gpj0-2, DOWN, FAST_SR1);
 	};
 };
 
@@ -1157,53 +1160,53 @@ &pinctrl_peric {
 	pinctrl-0 = <&initial_peric>;
 
 	initial_peric: initial-state {
-		PIN(INPUT, gpv7-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-2, NONE, FAST_SR1);
-		PIN(INPUT, gpv7-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-4, DOWN, FAST_SR1);
-		PIN(INPUT, gpv7-5, DOWN, FAST_SR1);
+		PIN_IN(gpv7-0, DOWN, FAST_SR1);
+		PIN_IN(gpv7-1, DOWN, FAST_SR1);
+		PIN_IN(gpv7-2, NONE, FAST_SR1);
+		PIN_IN(gpv7-3, DOWN, FAST_SR1);
+		PIN_IN(gpv7-4, DOWN, FAST_SR1);
+		PIN_IN(gpv7-5, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpb0-4, DOWN, FAST_SR1);
+		PIN_IN(gpb0-4, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpc0-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpc0-5, DOWN, FAST_SR1);
-		PIN(INPUT, gpc0-7, DOWN, FAST_SR1);
+		PIN_IN(gpc0-2, DOWN, FAST_SR1);
+		PIN_IN(gpc0-5, DOWN, FAST_SR1);
+		PIN_IN(gpc0-7, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpc1-1, DOWN, FAST_SR1);
+		PIN_IN(gpc1-1, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpc3-4, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-5, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-6, NONE, FAST_SR1);
-		PIN(INPUT, gpc3-7, NONE, FAST_SR1);
+		PIN_IN(gpc3-4, NONE, FAST_SR1);
+		PIN_IN(gpc3-5, NONE, FAST_SR1);
+		PIN_IN(gpc3-6, NONE, FAST_SR1);
+		PIN_IN(gpc3-7, NONE, FAST_SR1);
 
-		PIN(OUTPUT, gpg0-0, NONE, FAST_SR1);
-		PIN(2, gpg0-1, DOWN, FAST_SR1);
+		PIN_OT(gpg0-0, NONE, FAST_SR1);
+		PIN_F2(gpg0-1, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpd2-5, DOWN, FAST_SR1);
+		PIN_IN(gpd2-5, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpd4-0, NONE, FAST_SR1);
-		PIN(INPUT, gpd4-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpd4-4, DOWN, FAST_SR1);
+		PIN_IN(gpd4-0, NONE, FAST_SR1);
+		PIN_IN(gpd4-1, DOWN, FAST_SR1);
+		PIN_IN(gpd4-2, DOWN, FAST_SR1);
+		PIN_IN(gpd4-3, DOWN, FAST_SR1);
+		PIN_IN(gpd4-4, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpd6-3, DOWN, FAST_SR1);
+		PIN_IN(gpd6-3, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpd8-1, UP, FAST_SR1);
+		PIN_IN(gpd8-1, UP, FAST_SR1);
 
-		PIN(INPUT, gpg1-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-2, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-3, DOWN, FAST_SR1);
-		PIN(INPUT, gpg1-4, DOWN, FAST_SR1);
+		PIN_IN(gpg1-0, DOWN, FAST_SR1);
+		PIN_IN(gpg1-1, DOWN, FAST_SR1);
+		PIN_IN(gpg1-2, DOWN, FAST_SR1);
+		PIN_IN(gpg1-3, DOWN, FAST_SR1);
+		PIN_IN(gpg1-4, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpg2-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg2-1, DOWN, FAST_SR1);
+		PIN_IN(gpg2-0, DOWN, FAST_SR1);
+		PIN_IN(gpg2-1, DOWN, FAST_SR1);
 
-		PIN(INPUT, gpg3-0, DOWN, FAST_SR1);
-		PIN(INPUT, gpg3-1, DOWN, FAST_SR1);
-		PIN(INPUT, gpg3-5, DOWN, FAST_SR1);
+		PIN_IN(gpg3-0, DOWN, FAST_SR1);
+		PIN_IN(gpg3-1, DOWN, FAST_SR1);
+		PIN_IN(gpg3-5, DOWN, FAST_SR1);
 	};
 };
 
@@ -1212,7 +1215,7 @@ &pinctrl_touch {
 	pinctrl-0 = <&initial_touch>;
 
 	initial_touch: initial-state {
-		PIN(INPUT, gpj1-2, DOWN, FAST_SR1);
+		PIN_IN(gpj1-2, DOWN, FAST_SR1);
 	};
 };
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:12 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:12 +0100
Subject: [PATCH v2 18/28] arm64: dts: exynos: align pinctrl with dtschema in
 Exynos7
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-12-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../boot/dts/exynos/exynos7-espresso.dts      |   6 +-
 .../boot/dts/exynos/exynos7-pinctrl.dtsi      | 176 +++++++++---------
 2 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 125c03f351d9..2826bafade8a 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -354,7 +354,7 @@ buck10_reg: BUCK10 {
 };
 
 &pinctrl_alive {
-	pmic_irq: pmic-irq {
+	pmic_irq: pmic-irq-pins {
 		samsung,pins = "gpa0-2";
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
@@ -393,14 +393,14 @@ &mmc_2 {
 };
 
 &pinctrl_bus1 {
-	usb30_vbus_en: usb30-vbus-en {
+	usb30_vbus_en: usb30-vbus-en-pins {
 		samsung,pins = "gph1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	usb3drd_boost_en: usb3drd-boost-en {
+	usb3drd_boost_en: usb3drd-boost-en-pins {
 		samsung,pins = "gpf4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
index 472dd649aa7e..be9b971f3697 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
@@ -12,7 +12,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_alive {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -29,7 +29,7 @@ gpa0: gpa0 {
 			     <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -46,7 +46,7 @@ gpa1: gpa1 {
 			     <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -54,7 +54,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa3: gpa3 {
+	gpa3: gpa3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -64,7 +64,7 @@ gpa3: gpa3 {
 };
 
 &pinctrl_bus0 {
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -72,7 +72,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -80,7 +80,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -88,7 +88,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -96,7 +96,7 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -104,7 +104,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -112,7 +112,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -120,7 +120,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd2: gpd2 {
+	gpd2: gpd2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -128,7 +128,7 @@ gpd2: gpd2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd4: gpd4 {
+	gpd4: gpd4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -136,7 +136,7 @@ gpd4: gpd4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd5: gpd5 {
+	gpd5: gpd5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -144,7 +144,7 @@ gpd5: gpd5 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd6: gpd6 {
+	gpd6: gpd6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -152,7 +152,7 @@ gpd6: gpd6 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd7: gpd7 {
+	gpd7: gpd7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -160,7 +160,7 @@ gpd7: gpd7 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd8: gpd8 {
+	gpd8: gpd8-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -168,7 +168,7 @@ gpd8: gpd8 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -176,7 +176,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg3: gpg3 {
+	gpg3: gpg3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -184,161 +184,161 @@ gpg3: gpg3 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c10_bus: hs-i2c10-bus {
+	hs_i2c10_bus: hs-i2c10-bus-pins {
 		samsung,pins = "gpb0-1", "gpb0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c11_bus: hs-i2c11-bus {
+	hs_i2c11_bus: hs-i2c11-bus-pins {
 		samsung,pins = "gpb0-3", "gpb0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c2_bus: hs-i2c2-bus {
+	hs_i2c2_bus: hs-i2c2-bus-pins {
 		samsung,pins = "gpd0-3", "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpd0-0", "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpd0-2", "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpd1-4", "gpd1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c3_bus: hs-i2c3-bus {
+	hs_i2c3_bus: hs-i2c3-bus-pins {
 		samsung,pins = "gpd1-3", "gpd1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c0_bus: hs-i2c0-bus {
+	hs_i2c0_bus: hs-i2c0-bus-pins {
 		samsung,pins = "gpd2-1", "gpd2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c1_bus: hs-i2c1-bus {
+	hs_i2c1_bus: hs-i2c1-bus-pins {
 		samsung,pins = "gpd2-3", "gpd2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c9_bus: hs-i2c9-bus {
+	hs_i2c9_bus: hs-i2c9-bus-pins {
 		samsung,pins = "gpd2-7", "gpd2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c8_bus: hs-i2c8-bus {
+	hs_i2c8_bus: hs-i2c8-bus-pins {
 		samsung,pins = "gpd5-3", "gpd5-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpd5-0", "gpd5-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpd5-0", "gpd5-1", "gpd5-2", "gpd5-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpd6-2", "gpd6-3", "gpd6-4", "gpd6-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpd8-0", "gpd8-1", "gpd6-0", "gpd6-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c4_bus: hs-i2c4-bus {
+	hs_i2c4_bus: hs-i2c4-bus-pins {
 		samsung,pins = "gpg3-1", "gpg3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	hs_i2c5_bus: hs-i2c5-bus {
+	hs_i2c5_bus: hs-i2c5-bus-pins {
 		samsung,pins = "gpg3-3", "gpg3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -347,7 +347,7 @@ hs_i2c5_bus: hs-i2c5-bus {
 };
 
 &pinctrl_nfc {
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -355,7 +355,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c6_bus: hs-i2c6-bus {
+	hs_i2c6_bus: hs-i2c6-bus-pins {
 		samsung,pins = "gpj0-1", "gpj0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -364,7 +364,7 @@ hs_i2c6_bus: hs-i2c6-bus {
 };
 
 &pinctrl_touch {
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -372,7 +372,7 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	hs_i2c7_bus: hs-i2c7-bus {
+	hs_i2c7_bus: hs-i2c7-bus-pins {
 		samsung,pins = "gpj1-1", "gpj1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -381,7 +381,7 @@ hs_i2c7_bus: hs-i2c7-bus {
 };
 
 &pinctrl_ff {
-	gpg4: gpg4 {
+	gpg4: gpg4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -389,7 +389,7 @@ gpg4: gpg4 {
 		#interrupt-cells = <2>;
 	};
 
-	spi3_bus: spi3-bus {
+	spi3_bus: spi3-bus-pins {
 		samsung,pins = "gpg4-0", "gpg4-1", "gpg4-2", "gpg4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -398,7 +398,7 @@ spi3_bus: spi3-bus {
 };
 
 &pinctrl_ese {
-	gpv7: gpv7 {
+	gpv7: gpv7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -406,7 +406,7 @@ gpv7: gpv7 {
 		#interrupt-cells = <2>;
 	};
 
-	spi4_bus: spi4-bus {
+	spi4_bus: spi4-bus-pins {
 		samsung,pins = "gpv7-0", "gpv7-1", "gpv7-2", "gpv7-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -415,7 +415,7 @@ spi4_bus: spi4-bus {
 };
 
 &pinctrl_fsys0 {
-	gpr4: gpr4 {
+	gpr4: gpr4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -423,35 +423,35 @@ gpr4: gpr4 {
 		#interrupt-cells = <2>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpr4-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpr4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpr4-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpr4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -460,7 +460,7 @@ sd2_bus4: sd2-bus-width4 {
 };
 
 &pinctrl_fsys1 {
-	gpr0: gpr0 {
+	gpr0: gpr0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -468,7 +468,7 @@ gpr0: gpr0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr1: gpr1 {
+	gpr1: gpr1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -476,7 +476,7 @@ gpr1: gpr1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr2: gpr2 {
+	gpr2: gpr2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -484,7 +484,7 @@ gpr2: gpr2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpr3: gpr3 {
+	gpr3: gpr3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -492,105 +492,105 @@ gpr3: gpr3 {
 		#interrupt-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpr0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpr0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_ds: sd0-ds {
+	sd0_ds: sd0-ds-pins {
 		samsung,pins = "gpr0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_qrdy: sd0-qrdy {
+	sd0_qrdy: sd0-qrdy-pins {
 		samsung,pins = "gpr0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpr1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpr2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpr2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
 	};
 
-	sd1_ds: sd1-ds {
+	sd1_ds: sd1-ds-pins {
 		samsung,pins = "gpr2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
 	};
 
-	sd1_qrdy: sd1-qrdy {
+	sd1_qrdy: sd1-qrdy-pins {
 		samsung,pins = "gpr2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
 	};
 
-	sd1_int: sd1-int {
+	sd1_int: sd1-int-pins {
 		samsung,pins = "gpr2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpr3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
 	};
 
-	sd1_bus8: sd1-bus-width8 {
+	sd1_bus8: sd1-bus-width8-pins {
 		samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -599,7 +599,7 @@ sd1_bus8: sd1-bus-width8 {
 };
 
 &pinctrl_bus1 {
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -607,7 +607,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -615,7 +615,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -623,7 +623,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -631,7 +631,7 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf4: gpf4 {
+	gpf4: gpf4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -639,7 +639,7 @@ gpf4: gpf4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf5: gpf5 {
+	gpf5: gpf5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -647,7 +647,7 @@ gpf5: gpf5 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -655,7 +655,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -663,7 +663,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gph1: gph1 {
+	gph1: gph1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -671,7 +671,7 @@ gph1: gph1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpv6: gpv6 {
+	gpv6: gpv6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -679,21 +679,21 @@ gpv6: gpv6 {
 		#interrupt-cells = <2>;
 	};
 
-	spi5_bus: spi5-bus {
+	spi5_bus: spi5-bus-pins {
 		samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ufs_refclk_out: ufs-refclk-out {
+	ufs_refclk_out: ufs-refclk-out-pins {
 		samsung,pins = "gpg2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
 	};
 
-	ufs_rst_n: ufs-rst-n {
+	ufs_rst_n: ufs-rst-n-pins {
 		samsung,pins = "gph1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:15 +0100
Subject: [PATCH v2 21/28] ARM: dts: s3c24xx: align pinctrl with dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-15-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/s3c2416-pinctrl.dtsi | 60 +++++++++++++-------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/arch/arm/boot/dts/s3c2416-pinctrl.dtsi b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
index 92439ee5d7de..20a7d72827c2 100644
--- a/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s3c2416-pinctrl.dtsi
@@ -12,66 +12,66 @@ &pinctrl_0 {
 	 * Pin banks
 	 */
 
-	gpa: gpa {
+	gpa: gpa-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpc: gpc {
+	gpc: gpc-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpd: gpd {
+	gpd: gpd-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpe: gpe {
+	gpe: gpe-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpf: gpf {
+	gpf: gpf-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpg: gpg {
+	gpg: gpg-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gph: gph {
+	gph: gph-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpj: gpj {
+	gpj: gpj-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpk: gpk {
+	gpk: gpk-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpl: gpl {
+	gpl: gpl-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpm: gpm {
+	gpm: gpm-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
@@ -80,92 +80,92 @@ gpm: gpm {
 	 * Pin groups
 	 */
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gph-0", "gph-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gph-8", "gph-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gph-2", "gph-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gph-10", "gph-11";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gph-4", "gph-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gph-6", "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gph-6", "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	extuart_clk: extuart-clk {
+	extuart_clk: extuart-clk-pins {
 		samsung,pins = "gph-12";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpe-14", "gpe-15";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpe-11", "gpe-12", "gpe-13";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpe-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpe-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd0_bus1: sd0-bus1 {
+	sd0_bus1: sd0-bus1-pins {
 		samsung,pins = "gpe-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd0_bus4: sd0-bus4 {
+	sd0_bus4: sd0-bus4-pins {
 		samsung,pins = "gpe-8", "gpe-9", "gpe-10";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpl-8";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpl-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd1_bus1: sd1-bus1 {
+	sd1_bus1: sd1-bus1-pins {
 		samsung,pins = "gpl-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	sd1_bus4: sd1-bus4 {
+	sd1_bus4: sd1-bus4-pins {
 		samsung,pins = "gpl-1", "gpl-2", "gpl-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:13 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:13 +0100
Subject: [PATCH v2 19/28] arm64: dts: exynos: align pinctrl with dtschema in
 Exynos850
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-13-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 52 +++++++++----------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
index f576b29c9b16..a71acf358d2d 100644
--- a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
@@ -13,7 +13,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_alive {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -30,7 +30,7 @@ gpa0: gpa0 {
 			     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -47,7 +47,7 @@ gpa1: gpa1 {
 			     <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -64,7 +64,7 @@ gpa2: gpa2 {
 			     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa3: gpa3 {
+	gpa3: gpa3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -81,7 +81,7 @@ gpa3: gpa3 {
 			     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa4: gpa4 {
+	gpa4: gpa4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -94,7 +94,7 @@ gpa4: gpa4 {
 			     <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpq0: gpq0 {
+	gpq0: gpq0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -134,7 +134,7 @@ uart1_pins: uart1-pins {
 };
 
 &pinctrl_cmgp {
-	gpm0: gpm0 {
+	gpm0: gpm0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -144,7 +144,7 @@ gpm0: gpm0 {
 		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpm1: gpm1 {
+	gpm1: gpm1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -154,7 +154,7 @@ gpm1: gpm1 {
 		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpm2: gpm2 {
+	gpm2: gpm2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -164,7 +164,7 @@ gpm2: gpm2 {
 		interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpm3: gpm3 {
+	gpm3: gpm3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -174,7 +174,7 @@ gpm3: gpm3 {
 		interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpm4: gpm4 {
+	gpm4: gpm4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -184,7 +184,7 @@ gpm4: gpm4 {
 		interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpm5: gpm5 {
+	gpm5: gpm5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -256,7 +256,7 @@ spi2_pins: spi2-pins {
 };
 
 &pinctrl_aud {
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -264,7 +264,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -322,7 +322,7 @@ aud_fm_idle_pins: aud-fm-idle-pins {
 };
 
 &pinctrl_hsi {
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -367,7 +367,7 @@ sd2_pdn_pins: sd2-pdn-pins {
 };
 
 &pinctrl_core {
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -375,7 +375,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -434,7 +434,7 @@ sd0_bus8_pins: sd0-bus8-pins {
 };
 
 &pinctrl_peri {
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -442,7 +442,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -450,7 +450,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -458,7 +458,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -466,7 +466,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -474,7 +474,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg3: gpg3 {
+	gpg3: gpg3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -482,14 +482,14 @@ gpg3: gpg3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp0: gpp0 {
+	gpp0: gpp0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
-	gpp1: gpp1 {
+	gpp1: gpp1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -497,7 +497,7 @@ gpp1: gpp1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp2: gpp2 {
+	gpp2: gpp2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:14 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:14 +0100
Subject: [PATCH v2 20/28] arm64: dts: exynos: align pinctrl with dtschema in
 ExynosAutov9
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-14-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../boot/dts/exynos/exynosautov9-pinctrl.dtsi | 50 +++++++++----------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
index 2407b03b5404..ef0349d1c3d0 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
@@ -11,7 +11,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_alive {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
@@ -27,7 +27,7 @@ gpa0: gpa0 {
 			     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
@@ -47,7 +47,7 @@ dp1_hpd: dp1-hpd-pins {
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 	};
 
-	gpq0: gpq0 {
+	gpq0: gpq0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -69,7 +69,7 @@ speedy1_bus: speedy1-bus-pins {
 };
 
 &pinctrl_aud {
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -77,7 +77,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -85,7 +85,7 @@ gpb1: gpb1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb2: gpb2 {
+	gpb2: gpb2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -93,7 +93,7 @@ gpb2: gpb2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb3: gpb3 {
+	gpb3: gpb3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -199,7 +199,7 @@ aud_i2s6_idle: aaud-i2s6-idle-pins {
 };
 
 &pinctrl_fsys0 {
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -207,7 +207,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -355,7 +355,7 @@ pcie_perst5_in: pcie-perst5-in-pins {
 };
 
 &pinctrl_fsys1 {
-	gpf8: gpf8 {
+	gpf8: gpf8-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -393,7 +393,7 @@ sd2_bus4: sd2-bus-width4-pins {
 };
 
 &pinctrl_fsys2 {
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -401,7 +401,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -409,7 +409,7 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf4: gpf4 {
+	gpf4: gpf4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -417,7 +417,7 @@ gpf4: gpf4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf5: gpf5 {
+	gpf5: gpf5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -425,7 +425,7 @@ gpf5: gpf5 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf6: gpf6 {
+	gpf6: gpf6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -499,7 +499,7 @@ eth1_pps_out: eth1-pps-out-pins {
 };
 
 &pinctrl_peric0 {
-	gpp0: gpp0 {
+	gpp0: gpp0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -507,7 +507,7 @@ gpp0: gpp0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp1: gpp1 {
+	gpp1: gpp1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -515,7 +515,7 @@ gpp1: gpp1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp2: gpp2 {
+	gpp2: gpp2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -523,7 +523,7 @@ gpp2: gpp2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -833,7 +833,7 @@ uart5_bus_dual: uart5-bus-dual-pins {
 };
 
 &pinctrl_peric1 {
-	gpp3: gpp3 {
+	gpp3: gpp3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -841,7 +841,7 @@ gpp3: gpp3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp4: gpp4 {
+	gpp4: gpp4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -849,7 +849,7 @@ gpp4: gpp4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpp5: gpp5 {
+	gpp5: gpp5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -857,7 +857,7 @@ gpp5: gpp5 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -865,7 +865,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -873,7 +873,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg3: gpg3 {
+	gpg3: gpg3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:10 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:10 +0100
Subject: [PATCH v2 16/28] ARM: dts: exynos: align pinctrl with dtschema in
 Exynos542x/5800
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-10-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts |   2 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts    |  36 ++--
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi     | 194 +++++++++---------
 arch/arm/boot/dts/exynos5420-smdk5420.dts     |   6 +-
 arch/arm/boot/dts/exynos5422-odroid-core.dtsi |   2 +-
 .../boot/dts/exynos5422-odroidxu3-common.dtsi |   6 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts     |  36 ++--
 7 files changed, 141 insertions(+), 141 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index dfc7f14f5772..327cf7105a35 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -808,7 +808,7 @@ &mmc_2 {
 };
 
 &pinctrl_0 {
-	s2mps11_irq: s2mps11-irq {
+	s2mps11_irq: s2mps11-irq-pins {
 		samsung,pins = "gpx3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index e8819659081a..915878ee3ec6 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -774,14 +774,14 @@ &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mask_tpm_reset>;
 
-	wifi_en: wifi-en {
+	wifi_en: wifi-en-pins {
 		samsung,pins = "gpx0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	max98090_irq: max98090-irq {
+	max98090_irq: max98090-irq-pins {
 		samsung,pins = "gpx0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -789,7 +789,7 @@ max98090_irq: max98090-irq {
 	};
 
 	/* We need GPX0_6 to be low at sleep time; just keep it low always */
-	mask_tpm_reset: mask-tpm-reset {
+	mask_tpm_reset: mask-tpm-reset-pins {
 		samsung,pins = "gpx0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -797,70 +797,70 @@ mask_tpm_reset: mask-tpm-reset {
 		samsung,pin-val = <0>;
 	};
 
-	tpm_irq: tpm-irq {
+	tpm_irq: tpm-irq-pins {
 		samsung,pins = "gpx1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	trackpad_irq: trackpad-irq {
+	trackpad_irq: trackpad-irq-pins {
 		samsung,pins = "gpx1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	power_key_irq: power-key-irq {
+	power_key_irq: power-key-irq-pins {
 		samsung,pins = "gpx1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	ec_irq: ec-irq {
+	ec_irq: ec-irq-pins {
 		samsung,pins = "gpx1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	tps65090_irq: tps65090-irq {
+	tps65090_irq: tps65090-irq-pins {
 		samsung,pins = "gpx2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	dp_hpd_gpio: dp_hpd_gpio {
+	dp_hpd_gpio: dp-hpd-gpio-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	max77802_irq: max77802-irq {
+	max77802_irq: max77802-irq-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	lid_irq: lid-irq {
+	lid_irq: lid-irq-pins {
 		samsung,pins = "gpx3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pmic_dvs_1: pmic-dvs-1 {
+	pmic_dvs_1: pmic-dvs-1-pins {
 		samsung,pins = "gpy7-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -891,7 +891,7 @@ &sd1_cmd {
 };
 
 &pinctrl_2 {
-	pmic_dvs_2: pmic-dvs-2 {
+	pmic_dvs_2: pmic-dvs-2-pins {
 		samsung,pins = "gpj4-2", "gpj4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -907,28 +907,28 @@ &spi2_bus {
 
 &pinctrl_3 {
 	/* Drive SPI chip select at x2 for better integrity */
-	ec_spi_cs: ec-spi-cs {
+	ec_spi_cs: ec-spi-cs-pins {
 		samsung,pins = "gpb1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
 	};
 
-	usb300_vbus_en: usb300-vbus-en {
+	usb300_vbus_en: usb300-vbus-en-pins {
 		samsung,pins = "gph0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb301_vbus_en: usb301-vbus-en {
+	usb301_vbus_en: usb301-vbus-en-pins {
 		samsung,pins = "gph0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pmic_selb: pmic-selb {
+	pmic_selb: pmic-selb-pins {
 		samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
 			       "gph0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
diff --git a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
index b82af7c89654..546ba274f4e5 100644
--- a/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
+++ b/arch/arm/boot/dts/exynos5420-pinctrl.dtsi
@@ -12,7 +12,7 @@
 #include <dt-bindings/pinctrl/samsung.h>
 
 &pinctrl_0 {
-	gpy7: gpy7 {
+	gpy7: gpy7-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -20,7 +20,7 @@ gpy7: gpy7 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx0: gpx0 {
+	gpx0: gpx0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -31,7 +31,7 @@ gpx0: gpx0 {
 			     <26 0>, <26 1>, <27 0>, <27 1>;
 	};
 
-	gpx1: gpx1 {
+	gpx1: gpx1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -42,7 +42,7 @@ gpx1: gpx1 {
 			     <30 0>, <30 1>, <31 0>, <31 1>;
 	};
 
-	gpx2: gpx2 {
+	gpx2: gpx2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -50,7 +50,7 @@ gpx2: gpx2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpx3: gpx3 {
+	gpx3: gpx3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -58,14 +58,14 @@ gpx3: gpx3 {
 		#interrupt-cells = <2>;
 	};
 
-	dp_hpd: dp_hpd {
+	dp_hpd: dp-hpd-pins {
 		samsung,pins = "gpx0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	hdmi_cec: hdmi-cec {
+	hdmi_cec: hdmi-cec-pins {
 		samsung,pins = "gpx3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -74,7 +74,7 @@ hdmi_cec: hdmi-cec {
 };
 
 &pinctrl_1 {
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -82,7 +82,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -90,7 +90,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc2: gpc2 {
+	gpc2: gpc2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -98,7 +98,7 @@ gpc2: gpc2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc3: gpc3 {
+	gpc3: gpc3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -106,7 +106,7 @@ gpc3: gpc3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc4: gpc4 {
+	gpc4: gpc4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -114,7 +114,7 @@ gpc4: gpc4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -122,175 +122,175 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpy0: gpy0 {
+	gpy0: gpy0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy1: gpy1 {
+	gpy1: gpy1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy2: gpy2 {
+	gpy2: gpy2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy3: gpy3 {
+	gpy3: gpy3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy4: gpy4 {
+	gpy4: gpy4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy5: gpy5 {
+	gpy5: gpy5-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpy6: gpy6 {
+	gpy6: gpy6-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpc0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpc0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpc0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpc0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpc0-4", "gpc0-5", "gpc0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpc3-0", "gpc3-1", "gpc3-2", "gpc3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd0_rclk: sd0-rclk {
+	sd0_rclk: sd0-rclk-pins {
 		samsung,pins = "gpc0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpc1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpc1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpc1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_int: sd1-int {
+	sd1_int: sd1-int-pins {
 		samsung,pins = "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpc1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpc1-4", "gpc1-5", "gpc1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd1_bus8: sd1-bus-width8 {
+	sd1_bus8: sd1-bus-width8-pins {
 		samsung,pins = "gpd1-4", "gpd1-5", "gpd1-6", "gpd1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpc2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpc2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpc2-4", "gpc2-5", "gpc2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
 	};
 
-	sd2_wp: sd2-wp {
+	sd2_wp: sd2-wp-pins {
 		samsung,pins = "gpc4-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -299,7 +299,7 @@ sd2_wp: sd2-wp {
 };
 
 &pinctrl_2 {
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -307,7 +307,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -315,7 +315,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -323,7 +323,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -331,7 +331,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -339,7 +339,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -347,7 +347,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -355,7 +355,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj4: gpj4 {
+	gpj4: gpj4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -363,7 +363,7 @@ gpj4: gpj4 {
 		#interrupt-cells = <2>;
 	};
 
-	cam_gpio_a: cam-gpio-a {
+	cam_gpio_a: cam-gpio-a-pins {
 		samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
 			       "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
 			       "gpe1-0", "gpe1-1";
@@ -372,7 +372,7 @@ cam_gpio_a: cam-gpio-a {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_gpio_b: cam-gpio-b {
+	cam_gpio_b: cam-gpio-b-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
 			       "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -380,42 +380,42 @@ cam_gpio_b: cam-gpio-b {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_i2c2_bus: cam-i2c2-bus {
+	cam_i2c2_bus: cam-i2c2-bus-pins {
 		samsung,pins = "gpf0-4", "gpf0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_spi1_bus: cam-spi1-bus {
+	cam_spi1_bus: cam-spi1-bus-pins {
 		samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_i2c1_bus: cam-i2c1-bus {
+	cam_i2c1_bus: cam-i2c1-bus-pins {
 		samsung,pins = "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_i2c0_bus: cam-i2c0-bus {
+	cam_i2c0_bus: cam-i2c0-bus-pins {
 		samsung,pins = "gpf0-0", "gpf0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_spi0_bus: cam-spi0-bus {
+	cam_spi0_bus: cam-spi0-bus-pins {
 		samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	cam_bayrgb_bus: cam-bayrgb-bus {
+	cam_bayrgb_bus: cam-bayrgb-bus-pins {
 		samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
 			       "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
 			       "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
@@ -428,7 +428,7 @@ cam_bayrgb_bus: cam-bayrgb-bus {
 };
 
 &pinctrl_3 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -436,7 +436,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -444,7 +444,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa2: gpa2 {
+	gpa2: gpa2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -452,7 +452,7 @@ gpa2: gpa2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb0: gpb0 {
+	gpb0: gpb0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -460,7 +460,7 @@ gpb0: gpb0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb1: gpb1 {
+	gpb1: gpb1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -468,7 +468,7 @@ gpb1: gpb1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb2: gpb2 {
+	gpb2: gpb2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -476,7 +476,7 @@ gpb2: gpb2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb3: gpb3 {
+	gpb3: gpb3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -484,7 +484,7 @@ gpb3: gpb3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb4: gpb4 {
+	gpb4: gpb4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -492,7 +492,7 @@ gpb4: gpb4 {
 		#interrupt-cells = <2>;
 	};
 
-	gph0: gph0 {
+	gph0: gph0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -500,98 +500,98 @@ gph0: gph0 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c3_bus: i2c3-bus {
+	i2c3_bus: i2c3-bus-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-4", "gpa1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c4_hs_bus: i2c4-hs-bus {
+	i2c4_hs_bus: i2c4-hs-bus-pins {
 		samsung,pins = "gpa2-0", "gpa2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c5_hs_bus: i2c5-hs-bus {
+	i2c5_hs_bus: i2c5-hs-bus-pins {
 		samsung,pins = "gpa2-2", "gpa2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 			       "gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -599,7 +599,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
 			       "gpb0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -607,7 +607,7 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
 			       "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -615,7 +615,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
 			       "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -623,91 +623,91 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpb1-0", "gpb1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c6_hs_bus: i2c6-hs-bus {
+	i2c6_hs_bus: i2c6-hs-bus-pins {
 		samsung,pins = "gpb1-3", "gpb1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpb2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpb2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpb2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c7_hs_bus: i2c7-hs-bus {
+	i2c7_hs_bus: i2c7-hs-bus-pins {
 		samsung,pins = "gpb2-2", "gpb2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpb3-0", "gpb3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpb3-2", "gpb3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c8_hs_bus: i2c8-hs-bus {
+	i2c8_hs_bus: i2c8-hs-bus-pins {
 		samsung,pins = "gpb3-4", "gpb3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c9_hs_bus: i2c9-hs-bus {
+	i2c9_hs_bus: i2c9-hs-bus-pins {
 		samsung,pins = "gpb3-6", "gpb3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	i2c10_hs_bus: i2c10-hs-bus {
+	i2c10_hs_bus: i2c10-hs-bus-pins {
 		samsung,pins = "gpb4-0", "gpb4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
@@ -716,7 +716,7 @@ i2c10_hs_bus: i2c10-hs-bus {
 };
 
 &pinctrl_4 {
-	gpz: gpz {
+	gpz: gpz-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -724,7 +724,7 @@ gpz: gpz {
 		#interrupt-cells = <2>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
 				"gpz-4", "gpz-5", "gpz-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index a4f0e3ffedbd..b8b1418d36e3 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -377,7 +377,7 @@ &mmc_2 {
 };
 
 &pinctrl_0 {
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -386,14 +386,14 @@ hdmi_hpd_irq: hdmi-hpd-irq {
 };
 
 &pinctrl_2 {
-	usb300_vbus_en: usb300-vbus-en {
+	usb300_vbus_en: usb300-vbus-en-pins {
 		samsung,pins = "gpg0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb301_vbus_en: usb301-vbus-en {
+	usb301_vbus_en: usb301-vbus-en-pins {
 		samsung,pins = "gpg1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
index e7958dbecfd2..24c428b84192 100644
--- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
@@ -999,7 +999,7 @@ &nocp_mem1_1 {
 };
 
 &pinctrl_0 {
-	s2mps11_irq: s2mps11-irq {
+	s2mps11_irq: s2mps11-irq-pins {
 		samsung,pins = "gpx0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
index e35af40a55cb..a6961ff24030 100644
--- a/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi
@@ -480,14 +480,14 @@ &mmc_0 {
 };
 
 &pinctrl_0 {
-	power_key: power-key {
+	power_key: power-key-pins {
 		samsung,pins = "gpx0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
@@ -496,7 +496,7 @@ hdmi_hpd_irq: hdmi-hpd-irq {
 };
 
 &pinctrl_1 {
-	emmc_nrst_pin: emmc-nrst {
+	emmc_nrst_pin: emmc-nrst-pins {
 		samsung,pins = "gpd1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index eca805b83816..3bc40840573f 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -756,14 +756,14 @@ &pinctrl_0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&mask_tpm_reset>;
 
-	wifi_en: wifi-en {
+	wifi_en: wifi-en-pins {
 		samsung,pins = "gpx0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	max98091_irq: max98091-irq {
+	max98091_irq: max98091-irq-pins {
 		samsung,pins = "gpx0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -771,7 +771,7 @@ max98091_irq: max98091-irq {
 	};
 
 	/* We need GPX0_6 to be low at sleep time; just keep it low always */
-	mask_tpm_reset: mask-tpm-reset {
+	mask_tpm_reset: mask-tpm-reset-pins {
 		samsung,pins = "gpx0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -779,70 +779,70 @@ mask_tpm_reset: mask-tpm-reset {
 		samsung,pin-val = <0>;
 	};
 
-	tpm_irq: tpm-irq {
+	tpm_irq: tpm-irq-pins {
 		samsung,pins = "gpx1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	trackpad_irq: trackpad-irq {
+	trackpad_irq: trackpad-irq-pins {
 		samsung,pins = "gpx1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	power_key_irq: power-key-irq {
+	power_key_irq: power-key-irq-pins {
 		samsung,pins = "gpx1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	ec_irq: ec-irq {
+	ec_irq: ec-irq-pins {
 		samsung,pins = "gpx1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	tps65090_irq: tps65090-irq {
+	tps65090_irq: tps65090-irq-pins {
 		samsung,pins = "gpx2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	dp_hpd_gpio: dp_hpd_gpio {
+	dp_hpd_gpio: dp-hpd-gpio-pins {
 		samsung,pins = "gpx2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	max77802_irq: max77802-irq {
+	max77802_irq: max77802-irq-pins {
 		samsung,pins = "gpx3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	lid_irq: lid-irq {
+	lid_irq: lid-irq-pins {
 		samsung,pins = "gpx3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	hdmi_hpd_irq: hdmi-hpd-irq {
+	hdmi_hpd_irq: hdmi-hpd-irq-pins {
 		samsung,pins = "gpx3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pmic_dvs_1: pmic-dvs-1 {
+	pmic_dvs_1: pmic-dvs-1-pins {
 		samsung,pins = "gpy7-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -873,7 +873,7 @@ &sd1_cmd {
 };
 
 &pinctrl_2 {
-	pmic_dvs_2: pmic-dvs-2 {
+	pmic_dvs_2: pmic-dvs-2-pins {
 		samsung,pins = "gpj4-2", "gpj4-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
@@ -889,28 +889,28 @@ &spi2_bus {
 
 &pinctrl_3 {
 	/* Drive SPI chip select at x2 for better integrity */
-	ec_spi_cs: ec-spi-cs {
+	ec_spi_cs: ec-spi-cs-pins {
 		samsung,pins = "gpb1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
 	};
 
-	usb300_vbus_en: usb300-vbus-en {
+	usb300_vbus_en: usb300-vbus-en-pins {
 		samsung,pins = "gph0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	usb301_vbus_en: usb301-vbus-en {
+	usb301_vbus_en: usb301-vbus-en-pins {
 		samsung,pins = "gph0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
 	};
 
-	pmic_selb: pmic-selb {
+	pmic_selb: pmic-selb-pins {
 		samsung,pins = "gph0-2", "gph0-3", "gph0-4", "gph0-5",
 			       "gph0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:16 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:16 +0100
Subject: [PATCH v2 22/28] ARM: dts: s3c64xx: align pinctrl with dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-16-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/s3c6410-mini6410.dts |   4 +-
 arch/arm/boot/dts/s3c64xx-pinctrl.dtsi | 210 ++++++++++++-------------
 2 files changed, 107 insertions(+), 107 deletions(-)

diff --git a/arch/arm/boot/dts/s3c6410-mini6410.dts b/arch/arm/boot/dts/s3c6410-mini6410.dts
index 285555b9ed94..17097da36f5e 100644
--- a/arch/arm/boot/dts/s3c6410-mini6410.dts
+++ b/arch/arm/boot/dts/s3c6410-mini6410.dts
@@ -193,12 +193,12 @@ &uart3 {
 };
 
 &pinctrl0 {
-	gpio_leds: gpio-leds {
+	gpio_leds: gpio-leds-pins {
 		samsung,pins = "gpk-4", "gpk-5", "gpk-6", "gpk-7";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	gpio_keys: gpio-keys {
+	gpio_keys: gpio-keys-pins {
 		samsung,pins = "gpn-0", "gpn-1", "gpn-2", "gpn-3",
 				"gpn-4", "gpn-5", "gpl-11", "gpl-12";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
index 8e9594d64b57..0a3186d57cb5 100644
--- a/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s3c64xx-pinctrl.dtsi
@@ -16,111 +16,111 @@ &pinctrl0 {
 	 * Pin banks
 	 */
 
-	gpa: gpa {
+	gpa: gpa-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpc: gpc {
+	gpc: gpc-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpd: gpd {
+	gpd: gpd-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpe: gpe {
+	gpe: gpe-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpf: gpf {
+	gpf: gpf-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpg: gpg {
+	gpg: gpg-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gph: gph {
+	gph: gph-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpi: gpi {
+	gpi: gpi-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpj: gpj {
+	gpj: gpj-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpk: gpk {
+	gpk: gpk-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gpl: gpl {
+	gpl: gpl-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpm: gpm {
+	gpm: gpm-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpn: gpn {
+	gpn: gpn-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpo: gpo {
+	gpo: gpo-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpp: gpp {
+	gpp: gpp-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
 		#interrupt-cells = <2>;
 	};
 
-	gpq: gpq {
+	gpq: gpq-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 		interrupt-controller;
@@ -131,225 +131,225 @@ gpq: gpq {
 	 * Pin groups
 	 */
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa-0", "gpa-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa-2", "gpa-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa-4", "gpa-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa-6", "gpa-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ext_dma_0: ext-dma-0 {
+	ext_dma_0: ext-dma-0-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ext_dma_1: ext-dma-1 {
+	ext_dma_1: ext-dma-1-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_data_0: irda-data-0 {
+	irda_data_0: irda-data-0-pins {
 		samsung,pins = "gpb-0", "gpb-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_data_1: irda-data-1 {
+	irda_data_1: irda-data-1-pins {
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	irda_sdbw: irda-sdbw {
+	irda_sdbw: irda-sdbw-pins {
 		samsung,pins = "gpb-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpb-5", "gpb-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_6>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpc-0", "gpc-1", "gpc-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi0_cs: spi0-cs {
+	spi0_cs: spi0-cs-pins {
 		samsung,pins = "gpc-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpc-4", "gpc-5", "gpc-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	spi1_cs: spi1-cs {
+	spi1_cs: spi1-cs-pins {
 		samsung,pins = "gpc-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpg-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpg-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_bus1: sd0-bus1 {
+	sd0_bus1: sd0-bus1-pins {
 		samsung,pins = "gpg-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_bus4: sd0-bus4 {
+	sd0_bus4: sd0-bus4-pins {
 		samsung,pins = "gpg-2", "gpg-3", "gpg-4", "gpg-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpg-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gph-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gph-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus1: sd1-bus1 {
+	sd1_bus1: sd1-bus1-pins {
 		samsung,pins = "gph-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus4: sd1-bus4 {
+	sd1_bus4: sd1-bus4-pins {
 		samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_bus8: sd1-bus8 {
+	sd1_bus8: sd1-bus8-pins {
 		samsung,pins = "gph-2", "gph-3", "gph-4", "gph-5",
 				"gph-6", "gph-7", "gph-8", "gph-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpg-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpc-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpc-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_bus1: sd2-bus1 {
+	sd2_bus1: sd2-bus1-pins {
 		samsung,pins = "gph-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	sd2_bus4: sd2-bus4 {
+	sd2_bus4: sd2-bus4-pins {
 		samsung,pins = "gph-6", "gph-7", "gph-8", "gph-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s0_cdclk: i2s0-cdclk {
+	i2s0_cdclk: i2s0-cdclk-pins {
 		samsung,pins = "gpd-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s1_cdclk: i2s1-cdclk {
+	i2s1_cdclk: i2s1-cdclk-pins {
 		samsung,pins = "gpe-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpc-4", "gpc-5", "gpc-6", "gph-6",
 				"gph-8", "gph-9";
@@ -357,50 +357,50 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	i2s2_cdclk: i2s2-cdclk {
+	i2s2_cdclk: i2s2-cdclk-pins {
 		/* S3C6410-only */
 		samsung,pins = "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm0_bus: pcm0-bus {
+	pcm0_bus: pcm0-bus-pins {
 		samsung,pins = "gpd-0", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm0_extclk: pcm0-extclk {
+	pcm0_extclk: pcm0-extclk-pins {
 		samsung,pins = "gpd-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpe-0", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pcm1_extclk: pcm1-extclk {
+	pcm1_extclk: pcm1-extclk-pins {
 		samsung,pins = "gpe-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ac97_bus_0: ac97-bus-0 {
+	ac97_bus_0: ac97-bus-0-pins {
 		samsung,pins = "gpd-0", "gpd-1", "gpd-2", "gpd-3", "gpd-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	ac97_bus_1: ac97-bus-1 {
+	ac97_bus_1: ac97-bus-1-pins {
 		samsung,pins = "gpe-0", "gpe-1", "gpe-2", "gpe-3", "gpe-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_port: cam-port {
+	cam_port: cam-port-pins {
 		samsung,pins = "gpf-0", "gpf-1", "gpf-2", "gpf-4",
 				"gpf-5", "gpf-6", "gpf-7", "gpf-8",
 				"gpf-9", "gpf-10", "gpf-11", "gpf-12";
@@ -408,242 +408,242 @@ cam_port: cam-port {
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_rst: cam-rst {
+	cam_rst: cam-rst-pins {
 		samsung,pins = "gpf-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	cam_field: cam-field {
+	cam_field: cam-field-pins {
 		/* S3C6410-only */
 		samsung,pins = "gpb-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm_extclk: pwm-extclk {
+	pwm_extclk: pwm-extclk-pins {
 		samsung,pins = "gpf-13";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpf-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpf-15";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	clkout0: clkout-0 {
+	clkout0: clkout-0-pins {
 		samsung,pins = "gpf-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col0_0: keypad-col0-0 {
+	keypad_col0_0: keypad-col0-0-pins {
 		samsung,pins = "gph-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col1_0: keypad-col1-0 {
+	keypad_col1_0: keypad-col1-0-pins {
 		samsung,pins = "gph-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col2_0: keypad-col2-0 {
+	keypad_col2_0: keypad-col2-0-pins {
 		samsung,pins = "gph-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col3_0: keypad-col3-0 {
+	keypad_col3_0: keypad-col3-0-pins {
 		samsung,pins = "gph-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col4_0: keypad-col4-0 {
+	keypad_col4_0: keypad-col4-0-pins {
 		samsung,pins = "gph-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col5_0: keypad-col5-0 {
+	keypad_col5_0: keypad-col5-0-pins {
 		samsung,pins = "gph-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col6_0: keypad-col6-0 {
+	keypad_col6_0: keypad-col6-0-pins {
 		samsung,pins = "gph-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col7_0: keypad-col7-0 {
+	keypad_col7_0: keypad-col7-0-pins {
 		samsung,pins = "gph-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col0_1: keypad-col0-1 {
+	keypad_col0_1: keypad-col0-1-pins {
 		samsung,pins = "gpl-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col1_1: keypad-col1-1 {
+	keypad_col1_1: keypad-col1-1-pins {
 		samsung,pins = "gpl-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col2_1: keypad-col2-1 {
+	keypad_col2_1: keypad-col2-1-pins {
 		samsung,pins = "gpl-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col3_1: keypad-col3-1 {
+	keypad_col3_1: keypad-col3-1-pins {
 		samsung,pins = "gpl-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col4_1: keypad-col4-1 {
+	keypad_col4_1: keypad-col4-1-pins {
 		samsung,pins = "gpl-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col5_1: keypad-col5-1 {
+	keypad_col5_1: keypad-col5-1-pins {
 		samsung,pins = "gpl-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col6_1: keypad-col6-1 {
+	keypad_col6_1: keypad-col6-1-pins {
 		samsung,pins = "gpl-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_col7_1: keypad-col7-1 {
+	keypad_col7_1: keypad-col7-1-pins {
 		samsung,pins = "gpl-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row0_0: keypad-row0-0 {
+	keypad_row0_0: keypad-row0-0-pins {
 		samsung,pins = "gpk-8";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row1_0: keypad-row1-0 {
+	keypad_row1_0: keypad-row1-0-pins {
 		samsung,pins = "gpk-9";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row2_0: keypad-row2-0 {
+	keypad_row2_0: keypad-row2-0-pins {
 		samsung,pins = "gpk-10";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row3_0: keypad-row3-0 {
+	keypad_row3_0: keypad-row3-0-pins {
 		samsung,pins = "gpk-11";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row4_0: keypad-row4-0 {
+	keypad_row4_0: keypad-row4-0-pins {
 		samsung,pins = "gpk-12";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row5_0: keypad-row5-0 {
+	keypad_row5_0: keypad-row5-0-pins {
 		samsung,pins = "gpk-13";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row6_0: keypad-row6-0 {
+	keypad_row6_0: keypad-row6-0-pins {
 		samsung,pins = "gpk-14";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row7_0: keypad-row7-0 {
+	keypad_row7_0: keypad-row7-0-pins {
 		samsung,pins = "gpk-15";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row0_1: keypad-row0-1 {
+	keypad_row0_1: keypad-row0-1-pins {
 		samsung,pins = "gpn-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row1_1: keypad-row1-1 {
+	keypad_row1_1: keypad-row1-1-pins {
 		samsung,pins = "gpn-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row2_1: keypad-row2-1 {
+	keypad_row2_1: keypad-row2-1-pins {
 		samsung,pins = "gpn-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row3_1: keypad-row3-1 {
+	keypad_row3_1: keypad-row3-1-pins {
 		samsung,pins = "gpn-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row4_1: keypad-row4-1 {
+	keypad_row4_1: keypad-row4-1-pins {
 		samsung,pins = "gpn-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row5_1: keypad-row5-1 {
+	keypad_row5_1: keypad-row5-1-pins {
 		samsung,pins = "gpn-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row6_1: keypad-row6-1 {
+	keypad_row6_1: keypad-row6-1-pins {
 		samsung,pins = "gpn-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	keypad_row7_1: keypad-row7-1 {
+	keypad_row7_1: keypad-row7-1-pins {
 		samsung,pins = "gpn-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_ctrl: lcd-ctrl {
+	lcd_ctrl: lcd-ctrl-pins {
 		samsung,pins = "gpj-8", "gpj-9", "gpj-10", "gpj-11";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data16: lcd-data-width16 {
+	lcd_data16: lcd-data-width16-pins {
 		samsung,pins = "gpi-3", "gpi-4", "gpi-5", "gpi-6",
 				"gpi-7", "gpi-10", "gpi-11", "gpi-12",
 				"gpi-13", "gpi-14", "gpi-15", "gpj-3",
@@ -652,7 +652,7 @@ lcd_data16: lcd-data-width16 {
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data18: lcd-data-width18 {
+	lcd_data18: lcd-data-width18-pins {
 		samsung,pins = "gpi-2", "gpi-3", "gpi-4", "gpi-5",
 				"gpi-6", "gpi-7", "gpi-10", "gpi-11",
 				"gpi-12", "gpi-13", "gpi-14", "gpi-15",
@@ -662,7 +662,7 @@ lcd_data18: lcd-data-width18 {
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	lcd_data24: lcd-data-width24 {
+	lcd_data24: lcd-data-width24-pins {
 		samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
 				"gpi-4", "gpi-5", "gpi-6", "gpi-7",
 				"gpi-8", "gpi-9", "gpi-10", "gpi-11",
@@ -673,7 +673,7 @@ lcd_data24: lcd-data-width24 {
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	hsi_bus: hsi-bus {
+	hsi_bus: hsi-bus-pins {
 		samsung,pins = "gpk-0", "gpk-1", "gpk-2", "gpk-3",
 				"gpk-4", "gpk-5", "gpk-6", "gpk-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:18 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:18 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) pin
controller bindings to DT schema format.  Parts of description and DTS
example was copied from existing sources, so keep the license as
GPL-2.0-only.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../pinctrl/samsung,pinctrl-gpio-bank.yaml    |  52 +++
 .../pinctrl/samsung,pinctrl-pins-cfg.yaml     |  81 ++++
 .../samsung,pinctrl-wakeup-interrupt.yaml     |  85 ++++
 .../bindings/pinctrl/samsung,pinctrl.yaml     | 392 ++++++++++++++++++
 .../bindings/pinctrl/samsung-pinctrl.txt      | 383 -----------------
 MAINTAINERS                                   |   2 +-
 6 files changed, 611 insertions(+), 384 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
new file mode 100644
index 000000000000..f73348c54748
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-gpio-bank.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - gpio bank
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+  controller.
+
+  GPIO bank description for Samsung S3C/S5P/Exynos SoC pin controller.
+
+  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+  additional information and example.
+
+properties:
+  '#gpio-cells':
+    const: 2
+
+  gpio-controller: true
+
+  '#interrupt-cells':
+    description:
+      For GPIO banks supporting external GPIO interrupts or external wake-up
+      interrupts.
+    const: 2
+
+  interrupt-controller:
+    description:
+      For GPIO banks supporting external GPIO interrupts or external wake-up
+      interrupts.
+
+  interrupts:
+    description:
+      For GPIO banks supporting direct external wake-up interrupts (without
+      multiplexing).  Number of interrupts must match number of wake-up capable
+      pins of this bank.
+    minItems: 1
+    maxItems: 8
+
+required:
+  - '#gpio-cells'
+  - gpio-controller
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
new file mode 100644
index 000000000000..c71939ac8b63
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-pins-cfg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - pins configuration
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+  controller.
+
+  Pins configuration for Samsung S3C/S5P/Exynos SoC pin controller.
+
+  The values used for config properties should be derived from the hardware
+  manual and these values are programmed as-is into the pin pull up/down and
+  driver strength register of the pin-controller.
+  See also include/dt-bindings/pinctrl/samsung.h with useful constants.
+
+  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+  additional information and example.
+
+properties:
+  samsung,pins:
+    description: |
+      List of pins to configure. For initial and sleep states, the maximum
+      number is one pin. In other cases there is no upper limit.
+
+      The pins should use lowercase names matching hardware manual, e.g. for
+      GPA0 bank: gpa0-0, gpa0-1, gpa0-2.
+    $ref: /schemas/types.yaml#/definitions/string-array
+
+  samsung,pin-function:
+    description: |
+      The pin function selection that should be applied on the pins listed in the
+      child node is specified using the "samsung,pin-function" property. The value
+      of this property that should be applied to each of the pins listed in the
+      "samsung,pins" property should be picked from the hardware manual of the SoC
+      for the specified pin group. This property is optional in the child node if
+      no specific function selection is desired for the pins listed in the child
+      node. The value of this property is used as-is to program the pin-controller
+      function selector register of the pin-bank.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 15
+
+  samsung,pin-drv:
+    description: Drive strength configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 0
+    maximum: 15
+
+  samsung,pin-pud:
+    description: Pull up/down configuration.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2, 3]
+
+  samsung,pin-val:
+    description: Initial value of pin output buffer.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1]
+
+  samsung,pin-con-pdn:
+    description: Function in power down mode.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2, 3]
+
+  samsung,pin-pud-pdn:
+    description: Pull up/down configuration in power down mode.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [0, 1, 2, 3]
+
+required:
+  - samsung,pins
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
new file mode 100644
index 000000000000..6b684a53119b
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller - wake-up interrupt controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+  controller.
+
+  External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
+  Only one pin-controller device node can include external wake-up interrupts
+  child node (in other words, only one External wake-up interrupts
+  pin-controller is supported).
+
+  See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
+  additional information and example.
+
+properties:
+  compatible:
+    enum:
+      - samsung,s3c2410-wakeup-eint
+      - samsung,s3c2412-wakeup-eint
+      - samsung,s3c64xx-wakeup-eint
+      - samsung,s5pv210-wakeup-eint
+      - samsung,exynos4210-wakeup-eint
+      - samsung,exynos7-wakeup-eint
+
+  interrupts:
+    description:
+      Interrupt used by multiplexed external wake-up interrupts.
+    minItems: 1
+    maxItems: 6
+
+required:
+  - compatible
+  - interrupts
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,s3c2410-wakeup-eint
+              - samsung,s3c2412-wakeup-eint
+    then:
+      properties:
+        interrupts:
+          minItems: 6
+          maxItems: 6
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,s3c64xx-wakeup-eint
+    then:
+      properties:
+        interrupts:
+          minItems: 4
+          maxItems: 4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,s5pv210-wakeup-eint
+              - samsung,exynos4210-wakeup-eint
+              - samsung,exynos7-wakeup-eint
+    then:
+      properties:
+        interrupts:
+          minItems: 1
+          maxItems: 1
+
+additionalProperties: false
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
new file mode 100644
index 000000000000..28f0851d07bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
@@ -0,0 +1,392 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/samsung,pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC pin controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+  - Tomasz Figa <tomasz.figa at gmail.com>
+
+description: |
+  This is a part of device tree bindings for Samsung S3C/S5P/Exynos SoC pin
+  controller.
+
+  Pin group settings (like drive strength, pull up/down) are available as
+  macros in include/dt-bindings/pinctrl/samsung.h.
+
+  All the pin controller nodes should be represented in the aliases node using
+  the following format 'pinctrl{n}' where n is a unique number for the alias.
+
+  The controller supports three types of interrupts::
+   - External GPIO interrupts (see interrupts property in pin controller node);
+
+   - External wake-up interrupts - multiplexed (capable of waking up the system
+     see interrupts property in external wake-up interrupt controller node -
+     samsung,pinctrl-wakeup-interrupt.yaml);
+
+   - External wake-up interrupts - direct (capable of waking up the system, see
+     interrupts property in every bank of pin controller with external wake-up
+     interrupt controller - samsung,pinctrl-gpio-bank.yaml).
+
+properties:
+  $nodename:
+    pattern: "^pinctrl(@.*)?"
+
+  compatible:
+    enum:
+      - samsung,s3c2412-pinctrl
+      - samsung,s3c2416-pinctrl
+      - samsung,s3c2440-pinctrl
+      - samsung,s3c2450-pinctrl
+      - samsung,s3c64xx-pinctrl
+      - samsung,s5pv210-pinctrl
+      - samsung,exynos3250-pinctrl
+      - samsung,exynos4210-pinctrl
+      - samsung,exynos4x12-pinctrl
+      - samsung,exynos5250-pinctrl
+      - samsung,exynos5260-pinctrl
+      - samsung,exynos5410-pinctrl
+      - samsung,exynos5420-pinctrl
+      - samsung,exynos5433-pinctrl
+      - samsung,exynos7-pinctrl
+      - samsung,exynos7885-pinctrl
+      - samsung,exynos850-pinctrl
+      - samsung,exynosautov9-pinctrl
+
+  interrupts:
+    description:
+      Required for GPIO banks supporting external GPIO interrupts.
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  reg:
+    description:
+      Second base address of the pin controller if the specific registers of
+      the pin controller are separated into the different base address.
+      Only certain banks of certain pin controller might need it.
+    minItems: 1
+    maxItems: 2
+
+  wakeup-interrupt-controller:
+    $ref: samsung,pinctrl-wakeup-interrupt.yaml
+
+patternProperties:
+  "^[a-z]+[0-9]*-gpio-bank$":
+    description:
+      Pin banks of the controller are represented by child nodes of the
+      controller node. Bank name is taken from name of the node.
+    $ref: samsung,pinctrl-gpio-bank.yaml
+
+  "^[a-z0-9-]+-pins$":
+    oneOf:
+      - $ref: samsung,pinctrl-pins-cfg.yaml
+        required:
+          - samsung,pins
+      - type: object
+        patternProperties:
+          "^[a-z0-9-]+-pins$":
+            $ref: samsung,pinctrl-pins-cfg.yaml
+
+        additionalProperties: false
+
+  "^(initial|sleep)-state$":
+    patternProperties:
+      "^(pin-[a-z0-9-]+|[a-z0-9-]+-pin)$":
+        $ref: samsung,pinctrl-pins-cfg.yaml
+
+        properties:
+          samsung,pins:
+            description: See samsung,pinctrl-pins-cfg.yaml
+            $ref: /schemas/types.yaml#/definitions/string-array
+            maxItems: 1
+
+        required:
+          - samsung,pins
+
+        unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - $ref: "pinctrl.yaml#"
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-pinctrl
+    then:
+      properties:
+        reg:
+          minItems: 1
+          maxItems: 2
+    else:
+      properties:
+        reg:
+          minItems: 1
+          maxItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/samsung.h>
+
+    pinctrl at 7f008000 {
+        compatible = "samsung,s3c64xx-pinctrl";
+        reg = <0x7f008000 0x1000>;
+        interrupt-parent = <&vic1>;
+        interrupts = <21>;
+
+        wakeup-interrupt-controller {
+            compatible = "samsung,s3c64xx-wakeup-eint";
+            interrupts-extended = <&vic0 0>,
+                                  <&vic0 1>,
+                                  <&vic1 0>,
+                                  <&vic1 1>;
+        };
+
+        /* Pin bank with external GPIO or muxed external wake-up interrupts */
+        gpa-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        // ...
+
+        uart0-data-pins {
+            samsung,pins = "gpa-0", "gpa-1";
+            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+            samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
+        };
+
+        // ...
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/samsung.h>
+
+    pinctrl at 11400000 {
+        compatible = "samsung,exynos4210-pinctrl";
+        reg = <0x11400000 0x1000>;
+        interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+
+        pinctrl-names = "default";
+        pinctrl-0 = <&sleep0>;
+
+        /* Pin bank with external GPIO or muxed external wake-up interrupts */
+        gpa0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        // ...
+
+        uart0-data-pins {
+            samsung,pins = "gpa0-0", "gpa0-1";
+            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+        };
+
+        // ...
+
+        sleep0: sleep-state {
+            gpa0-0-pin {
+                samsung,pins = "gpa0-0";
+                samsung,pin-con-pdn = <EXYNOS_PIN_PDN_INPUT>;
+                samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+            };
+
+            gpa0-1-pin {
+                samsung,pins = "gpa0-1";
+                samsung,pin-con-pdn = <EXYNOS_PIN_PDN_OUT0>;
+                samsung,pin-pud-pdn = <EXYNOS_PIN_PULL_NONE>;
+            };
+
+            // ...
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/samsung.h>
+
+    pinctrl at 11000000 {
+        compatible = "samsung,exynos4210-pinctrl";
+        reg = <0x11000000 0x1000>;
+        interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+
+        wakeup-interrupt-controller {
+            compatible = "samsung,exynos4210-wakeup-eint";
+            interrupt-parent = <&gic>;
+            interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+        };
+
+        /* Pin bank with external GPIO or muxed external wake-up interrupts */
+        gpj0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        /* Pin bank without external interrupts */
+        gpy0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+        };
+
+        /* Pin bank with external direct wake-up interrupts */
+        gpx0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+
+            interrupt-controller;
+            interrupt-parent = <&gic>;
+            interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+            #interrupt-cells = <2>;
+        };
+
+        // ...
+
+        sd0-clk-pins {
+            samsung,pins = "gpk0-0";
+            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+        };
+
+        sd4-bus-width8-pins {
+            part-1-pins {
+                samsung,pins = "gpk0-3", "gpk0-4",
+                               "gpk0-5", "gpk0-6";
+                samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
+                samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+            };
+
+            part-2-pins {
+                samsung,pins = "gpk1-3", "gpk1-4",
+                               "gpk1-5", "gpk1-6";
+                samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
+                samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+                samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
+            };
+        };
+
+        // ...
+
+        otg-gp-pins {
+            samsung,pins = "gpx3-3";
+            samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
+            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+            samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+            samsung,pin-val = <0>;
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/samsung.h>
+
+    pinctrl at 10580000 {
+        compatible = "samsung,exynos5433-pinctrl";
+        reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
+
+        pinctrl-names = "default";
+        pinctrl-0 = <&initial_alive>;
+
+        wakeup-interrupt-controller {
+            compatible = "samsung,exynos7-wakeup-eint";
+            interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+        };
+
+        /* Pin bank with external direct wake-up interrupts */
+        gpa0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+
+            interrupt-controller;
+            interrupt-parent = <&gic>;
+            interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+            #interrupt-cells = <2>;
+        };
+
+        // ...
+
+        te-irq-pins {
+            samsung,pins = "gpf1-3";
+            samsung,pin-function = <0xf>;
+        };
+
+        // ..
+
+        initial_alive: initial-state {
+            gpa0-0-pin {
+                samsung,pins = "gpa0-0";
+                samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
+                samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
+                samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
+            };
+
+            // ...
+        };
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/pinctrl/samsung.h>
+
+    pinctrl at 114b0000 {
+        compatible = "samsung,exynos5433-pinctrl";
+        reg = <0x114b0000 0x1000>;
+        interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
+        power-domains = <&pd_aud>;
+
+        /* Pin bank with external GPIO or muxed external wake-up interrupts */
+        gpz0-gpio-bank {
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+        };
+
+        // ...
+
+        i2s0-bus-pins {
+            samsung,pins = "gpz0-0", "gpz0-1", "gpz0-2", "gpz0-3",
+                           "gpz0-4", "gpz0-5", "gpz0-6";
+            samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+            samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+            samsung,pin-drv = <EXYNOS5433_PIN_DRV_FAST_SR1>;
+        };
+
+        // ...
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
deleted file mode 100644
index 9e70edceb21b..000000000000
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ /dev/null
@@ -1,383 +0,0 @@
-Samsung GPIO and Pin Mux/Config controller
-
-Samsung's ARM based SoC's integrates a GPIO and Pin mux/config hardware
-controller. It controls the input/output settings on the available pads/pins
-and also provides ability to multiplex and configure the output of various
-on-chip controllers onto these pads.
-
-Required Properties:
-- compatible: should be one of the following.
-  - "samsung,s3c2412-pinctrl": for S3C2412-compatible pin-controller,
-  - "samsung,s3c2416-pinctrl": for S3C2416-compatible pin-controller,
-  - "samsung,s3c2440-pinctrl": for S3C2440-compatible pin-controller,
-  - "samsung,s3c2450-pinctrl": for S3C2450-compatible pin-controller,
-  - "samsung,s3c64xx-pinctrl": for S3C64xx-compatible pin-controller,
-  - "samsung,s5pv210-pinctrl": for S5PV210-compatible pin-controller,
-  - "samsung,exynos3250-pinctrl": for Exynos3250 compatible pin-controller.
-  - "samsung,exynos4210-pinctrl": for Exynos4210 compatible pin-controller.
-  - "samsung,exynos4x12-pinctrl": for Exynos4x12 compatible pin-controller.
-  - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
-  - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
-  - "samsung,exynos5410-pinctrl": for Exynos5410 compatible pin-controller.
-  - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
-  - "samsung,exynos5433-pinctrl": for Exynos5433 compatible pin-controller.
-  - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
-  - "samsung,exynos7885-pinctrl": for Exynos7885 compatible pin-controller.
-  - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
-  - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
-
-- reg: Base address of the pin controller hardware module and length of
-  the address space it occupies.
-
-  - reg: Second base address of the pin controller if the specific registers
-  of the pin controller are separated into the different base address.
-
-	Eg: GPF[1-5] of Exynos5433 are separated into the two base address.
-	- First base address is for GPAx and GPF[1-5] external interrupt
-	  registers.
-	- Second base address is for GPF[1-5] pinctrl registers.
-
-	pinctrl_0: pinctrl at 10580000 {
-		compatible = "samsung,exynos5433-pinctrl";
-		reg = <0x10580000 0x1a20>, <0x11090000 0x100>;
-
-		wakeup-interrupt-controller {
-			compatible = "samsung,exynos7-wakeup-eint";
-			interrupts = <0 16 0>;
-		};
-	};
-
-- Pin banks as child nodes: Pin banks of the controller are represented by child
-  nodes of the controller node. Bank name is taken from name of the node. Each
-  bank node must contain following properties:
-
-  - gpio-controller: identifies the node as a gpio controller and pin bank.
-  - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
-    binding is used, the amount of cells must be specified as 2. See the below
-    mentioned gpio binding representation for description of particular cells.
-
-	Eg: <&gpx2 6 0>
-	<[phandle of the gpio controller node]
-	[pin number within the gpio controller]
-	[flags]>
-
-	Values for gpio specifier:
-	- Pin number: is a value between 0 to 7.
-	- Flags: 0 - Active High
-		 1 - Active Low
-
-- Pin mux/config groups as child nodes: The pin mux (selecting pin function
-  mode) and pin config (pull up/down, driver strength) settings are represented
-  as child nodes of the pin-controller node. There should be at least one
-  child node and there is no limit on the count of these child nodes. It is
-  also possible for a child node to consist of several further child nodes
-  to allow grouping multiple pinctrl groups into one. The format of second
-  level child nodes is exactly the same as for first level ones and is
-  described below.
-
-  The child node should contain a list of pin(s) on which a particular pin
-  function selection or pin configuration (or both) have to applied. This
-  list of pins is specified using the property name "samsung,pins". There
-  should be at least one pin specified for this property and there is no upper
-  limit on the count of pins that can be specified. The pins are specified
-  using pin names which are derived from the hardware manual of the SoC. As
-  an example, the pins in GPA0 bank of the pin controller can be represented
-  as "gpa0-0", "gpa0-1", "gpa0-2" and so on. The names should be in lower case.
-  The format of the pin names should be (as per the hardware manual)
-  "[pin bank name]-[pin number within the bank]".
-
-  The pin function selection that should be applied on the pins listed in the
-  child node is specified using the "samsung,pin-function" property. The value
-  of this property that should be applied to each of the pins listed in the
-  "samsung,pins" property should be picked from the hardware manual of the SoC
-  for the specified pin group. This property is optional in the child node if
-  no specific function selection is desired for the pins listed in the child
-  node. The value of this property is used as-is to program the pin-controller
-  function selector register of the pin-bank.
-
-  The child node can also optionally specify one or more of the pin
-  configuration that should be applied on all the pins listed in the
-  "samsung,pins" property of the child node. The following pin configuration
-  properties are supported.
-
-  - samsung,pin-val: Initial value of pin output buffer.
-  - samsung,pin-pud: Pull up/down configuration.
-  - samsung,pin-drv: Drive strength configuration.
-  - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
-  - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
-
-  The values specified by these config properties should be derived from the
-  hardware manual and these values are programmed as-is into the pin
-  pull up/down and driver strength register of the pin-controller.
-
-  Note: A child should include at least a pin function selection property or
-  pin configuration property (one or more) or both.
-
-  The client nodes that require a particular pin function selection and/or
-  pin configuration should use the bindings listed in the "pinctrl-bindings.txt"
-  file.
-
-External GPIO and Wakeup Interrupts:
-
-The controller supports two types of external interrupts over gpio. The first
-is the external gpio interrupt and second is the external wakeup interrupts.
-The difference between the two is that the external wakeup interrupts can be
-used as system wakeup events.
-
-A. External GPIO Interrupts: For supporting external gpio interrupts, the
-   following properties should be specified in the pin-controller device node.
-
-   - interrupts: interrupt specifier for the controller. The format and value of
-     the interrupt specifier depends on the interrupt parent for the controller.
-
-   In addition, following properties must be present in node of every bank
-   of pins supporting GPIO interrupts:
-
-   - interrupt-controller: identifies the controller node as interrupt-parent.
-   - #interrupt-cells: the value of this property should be 2.
-     - First Cell: represents the external gpio interrupt number local to the
-       external gpio interrupt space of the controller.
-     - Second Cell: flags to identify the type of the interrupt
-       - 1 = rising edge triggered
-       - 2 = falling edge triggered
-       - 3 = rising and falling edge triggered
-       - 4 = high level triggered
-       - 8 = low level triggered
-
-B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
-   child node representing the external wakeup interrupt controller should be
-   included in the pin-controller device node.
-
-   Only one pin-controller device node can include external wakeup interrupts
-   child node (in other words, only one External Wakeup Interrupts
-   pin-controller is supported).
-
-   This child node should include following properties:
-
-   - compatible: identifies the type of the external wakeup interrupt controller
-     The possible values are:
-     - samsung,s3c2410-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung S3C24xx SoCs except S3C2412 and S3C2413,
-     - samsung,s3c2412-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung S3C2412 and S3C2413 SoCs,
-     - samsung,s3c64xx-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung S3C64xx SoCs,
-     - samsung,s5pv210-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung S5Pv210 SoCs,
-     - samsung,exynos4210-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung Exynos4210 and S5PC110/S5PV210 SoCs.
-     - samsung,exynos7-wakeup-eint: represents wakeup interrupt controller
-       found on Samsung Exynos7 SoC.
-   - interrupts: interrupt used by multiplexed wakeup interrupts.
-
-   In addition, following properties must be present in node of every bank
-   of pins supporting wake-up interrupts:
-
-   - interrupt-controller: identifies the node as interrupt-parent.
-   - #interrupt-cells: the value of this property should be 2
-     - First Cell: represents the external wakeup interrupt number local to
-       the external wakeup interrupt space of the controller.
-     - Second Cell: flags to identify the type of the interrupt
-       - 1 = rising edge triggered
-       - 2 = falling edge triggered
-       - 3 = rising and falling edge triggered
-       - 4 = high level triggered
-       - 8 = low level triggered
-
-   Node of every bank of pins supporting direct wake-up interrupts (without
-   multiplexing) must contain following properties:
-
-   - interrupts: interrupts of the interrupt parent which are used for external
-     wakeup interrupts from pins of the bank, must contain interrupts for all
-     pins of the bank.
-
-Aliases:
-
-All the pin controller nodes should be represented in the aliases node using
-the following format 'pinctrl{n}' where n is a unique number for the alias.
-
-Aliases for controllers compatible with "samsung,exynos7-pinctrl":
-- pinctrl0: pin controller of ALIVE block,
-- pinctrl1: pin controller of BUS0 block,
-- pinctrl2: pin controller of NFC block,
-- pinctrl3: pin controller of TOUCH block,
-- pinctrl4: pin controller of FF block,
-- pinctrl5: pin controller of ESE block,
-- pinctrl6: pin controller of FSYS0 block,
-- pinctrl7: pin controller of FSYS1 block,
-- pinctrl8: pin controller of BUS1 block,
-- pinctrl9: pin controller of AUDIO block,
-
-Example: A pin-controller node with pin banks:
-
-	pinctrl_0: pinctrl at 11400000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x11400000 0x1000>;
-		interrupts = <0 47 0>;
-
-		/* ... */
-
-		/* Pin bank without external interrupts */
-		gpy0: gpy0 {
-			gpio-controller;
-			#gpio-cells = <2>;
-		};
-
-		/* ... */
-
-		/* Pin bank with external GPIO or muxed wake-up interrupts */
-		gpj0: gpj0 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			#interrupt-cells = <2>;
-		};
-
-		/* ... */
-
-		/* Pin bank with external direct wake-up interrupts */
-		gpx0: gpx0 {
-			gpio-controller;
-			#gpio-cells = <2>;
-
-			interrupt-controller;
-			interrupt-parent = <&gic>;
-			interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
-				     <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
-			#interrupt-cells = <2>;
-		};
-
-		/* ... */
-	};
-
-Example 1: A pin-controller node with pin groups.
-
-	#include <dt-bindings/pinctrl/samsung.h>
-
-	pinctrl_0: pinctrl at 11400000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x11400000 0x1000>;
-		interrupts = <0 47 0>;
-
-		/* ... */
-
-		uart0_data: uart0-data {
-			samsung,pins = "gpa0-0", "gpa0-1";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart0_fctl: uart0-fctl {
-			samsung,pins = "gpa0-2", "gpa0-3";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_data: uart1-data {
-			samsung,pins = "gpa0-4", "gpa0-5";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		uart1_fctl: uart1-fctl {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		i2c2_bus: i2c2-bus {
-			samsung,pins = "gpa0-6", "gpa0-7";
-			samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-			samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-			samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
-		};
-
-		sd4_bus8: sd4-bus-width8 {
-			part-1 {
-				samsung,pins = "gpk0-3", "gpk0-4",
-						"gpk0-5", "gpk0-6";
-				samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
-				samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-				samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-			};
-			part-2 {
-				samsung,pins = "gpk1-3", "gpk1-4",
-						"gpk1-5", "gpk1-6";
-				samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
-				samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
-				samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
-			};
-		};
-	};
-
-Example 2: A pin-controller node with external wakeup interrupt controller node.
-
-	pinctrl_1: pinctrl at 11000000 {
-		compatible = "samsung,exynos4210-pinctrl";
-		reg = <0x11000000 0x1000>;
-		interrupts = <0 46 0>
-
-		/* ... */
-
-		wakeup-interrupt-controller {
-			compatible = "samsung,exynos4210-wakeup-eint";
-			interrupt-parent = <&gic>;
-			interrupts = <0 32 0>;
-		};
-	};
-
-Example 3: A uart client node that supports 'default' and 'flow-control' states.
-
-	uart at 13800000 {
-		compatible = "samsung,exynos4210-uart";
-		reg = <0x13800000 0x100>;
-		interrupts = <0 52 0>;
-		pinctrl-names = "default", "flow-control;
-		pinctrl-0 = <&uart0_data>;
-		pinctrl-1 = <&uart0_data>, <&uart0_fctl>;
-	};
-
-Example 4: Set up the default pin state for uart controller.
-
-	static int s3c24xx_serial_probe(struct platform_device *pdev) {
-		struct pinctrl *pinctrl;
-
-		/* ... */
-
-		pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
-	}
-
-Example 5: A display port client node that supports 'default' pinctrl state
-	   and gpio binding.
-
-	display-port-controller {
-		/* ... */
-
-		samsung,hpd-gpio = <&gpx2 6 0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&dp_hpd>;
-	};
-
-Example 6: Request the gpio for display port controller
-
-	static int exynos_dp_probe(struct platform_device *pdev)
-	{
-		int hpd_gpio, ret;
-		struct device *dev = &pdev->dev;
-		struct device_node *dp_node = dev->of_node;
-
-		/* ... */
-
-		hpd_gpio = of_get_named_gpio(dp_node, "samsung,hpd-gpio", 0);
-
-		/* ... */
-
-		ret = devm_gpio_request_one(&pdev->dev, hpd_gpio, GPIOF_IN,
-					    "hpd_gpio");
-		/* ... */
-	}
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..33005c10e956 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15242,7 +15242,7 @@ L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
 Q:	https://patchwork.kernel.org/project/linux-samsung-soc/list/
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
-F:	Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+F:	Documentation/devicetree/bindings/pinctrl/samsung,pinctrl*yaml
 F:	drivers/pinctrl/samsung/
 F:	include/dt-bindings/pinctrl/samsung.h
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:17 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:17 +0100
Subject: [PATCH v2 23/28] ARM: dts: s5pv210: align pinctrl with dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-17-krzysztof.kozlowski@canonical.com>

Align the pin controller related nodes with dtschema.  No functional
change expected.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/s5pv210-aquila.dts      |   2 +-
 arch/arm/boot/dts/s5pv210-aries.dtsi      |  40 ++--
 arch/arm/boot/dts/s5pv210-fascinate4g.dts |  12 +-
 arch/arm/boot/dts/s5pv210-galaxys.dts     |  16 +-
 arch/arm/boot/dts/s5pv210-pinctrl.dtsi    | 226 +++++++++++-----------
 5 files changed, 148 insertions(+), 148 deletions(-)

diff --git a/arch/arm/boot/dts/s5pv210-aquila.dts b/arch/arm/boot/dts/s5pv210-aquila.dts
index 6423348034b6..54de3bc77c30 100644
--- a/arch/arm/boot/dts/s5pv210-aquila.dts
+++ b/arch/arm/boot/dts/s5pv210-aquila.dts
@@ -391,7 +391,7 @@ timing0: timing {
 };
 
 &pinctrl0 {
-	t_flash_detect: t-flash-detect {
+	t_flash_detect: t-flash-detect-pins {
 		samsung,pins = "gph3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
diff --git a/arch/arm/boot/dts/s5pv210-aries.dtsi b/arch/arm/boot/dts/s5pv210-aries.dtsi
index 160f8cd9a68d..c8f1c324a6c2 100644
--- a/arch/arm/boot/dts/s5pv210-aries.dtsi
+++ b/arch/arm/boot/dts/s5pv210-aries.dtsi
@@ -645,21 +645,21 @@ &mfc {
 };
 
 &pinctrl0 {
-	bt_reset: bt-reset {
+	bt_reset: bt-reset-pins {
 		samsung,pins = "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	wlan_bt_en: wlan-bt-en {
+	wlan_bt_en: wlan-bt-en-pins {
 		samsung,pins = "gpb-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-val = <1>;
 	};
 
-	codec_ldo: codec-ldo {
+	codec_ldo: codec-ldo-pins {
 		samsung,pins = "gpf3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
@@ -671,19 +671,19 @@ prox_i2c_pins: gp2a-i2c-pins {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	wlan_gpio_rst: wlan-gpio-rst {
+	wlan_gpio_rst: wlan-gpio-rst-pins {
 		samsung,pins = "gpg1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	bt_wake: bt-wake {
+	bt_wake: bt-wake-pins {
 		samsung,pins = "gpg3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	gp2a_irq: gp2a-irq {
+	gp2a_irq: gp2a-irq-pins {
 		samsung,pins = "gph0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
@@ -698,67 +698,67 @@ pmic_dvs_pins: pmic-dvs-pins {
 		samsung,pin-val = <0>;
 	};
 
-	pmic_irq: pmic-irq {
+	pmic_irq: pmic-irq-pins {
 		samsung,pins = "gph0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	wifi_host_wake: wifi-host-wake {
+	wifi_host_wake: wifi-host-wake-pins {
 		samsung,pins = "gph2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	bt_host_wake: bt-host-wake {
+	bt_host_wake: bt-host-wake-pins {
 		samsung,pins = "gph2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	musb_irq: musq-irq {
+	musb_irq: musq-irq-pins {
 		samsung,pins = "gph2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	tf_detect: tf-detect {
+	tf_detect: tf-detect-pins {
 		samsung,pins = "gph3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	wifi_wake: wifi-wake {
+	wifi_wake: wifi-wake-pins {
 		samsung,pins = "gph3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	magnetometer_i2c_pins: yas529-i2c-pins {
+	magnetometer_i2c_pins: yas529-i2c-pins-pins {
 		samsung,pins = "gpj0-0", "gpj0-1";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ts_irq: ts-irq {
+	ts_irq: ts-irq-pins {
 		samsung,pins = "gpj0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	vibrator_ena: vibrator-ena {
+	vibrator_ena: vibrator-ena-pins {
 		samsung,pins = "gpj1-1";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	gp2a_power: gp2a-power {
+	gp2a_power: gp2a-power-pins {
 		samsung,pins = "gpj1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
@@ -771,7 +771,7 @@ touchkey_i2c_pins: touchkey-i2c-pins {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	touchkey_vdd_ena: touchkey-vdd-ena {
+	touchkey_vdd_ena: touchkey-vdd-ena-pins {
 		samsung,pins = "gpj3-2";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
@@ -789,13 +789,13 @@ accel_i2c_pins: accel-i2c-pins {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pmic_i2c_pins: pmic-i2c-pins {
+	pmic_i2c_pins: pmic-i2c-pins-pins {
 		samsung,pins = "gpj4-0", "gpj4-3";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	touchkey_irq: touchkey-irq {
+	touchkey_irq: touchkey-irq-pins {
 		samsung,pins = "gpj4-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
@@ -820,7 +820,7 @@ sound_i2c_pins: sound-i2c-pins {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	panel_rst: panel-rst {
+	panel_rst: panel-rst-pins {
 		samsung,pins = "mp05-5";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
diff --git a/arch/arm/boot/dts/s5pv210-fascinate4g.dts b/arch/arm/boot/dts/s5pv210-fascinate4g.dts
index 7427c84f1126..dfb2ee65e4a8 100644
--- a/arch/arm/boot/dts/s5pv210-fascinate4g.dts
+++ b/arch/arm/boot/dts/s5pv210-fascinate4g.dts
@@ -126,39 +126,39 @@ &pinctrl0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep_cfg>;
 
-	headset_det: headset-det {
+	headset_det: headset-det-pins {
 		samsung,pins = "gph0-6", "gph3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	fg_irq: fg-irq {
+	fg_irq: fg-irq-pins {
 		samsung,pins = "gph3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	headset_micbias_ena: headset-micbias-ena {
+	headset_micbias_ena: headset-micbias-ena-pins {
 		samsung,pins = "gpj2-5";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	earpath_sel: earpath-sel {
+	earpath_sel: earpath-sel-pins {
 		samsung,pins = "gpj2-6";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	main_micbias_ena: main-micbias-ena {
+	main_micbias_ena: main-micbias-ena-pins {
 		samsung,pins = "gpj4-2";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
 	/* Based on vendor kernel v2.6.35.7 */
-	sleep_cfg: sleep-cfg {
+	sleep_cfg: sleep-state {
 		PIN_SLP(gpa0-0, PREV, NONE);
 		PIN_SLP(gpa0-1, PREV, NONE);
 		PIN_SLP(gpa0-2, PREV, NONE);
diff --git a/arch/arm/boot/dts/s5pv210-galaxys.dts b/arch/arm/boot/dts/s5pv210-galaxys.dts
index eeec2bdece11..a78caaa1f3c5 100644
--- a/arch/arm/boot/dts/s5pv210-galaxys.dts
+++ b/arch/arm/boot/dts/s5pv210-galaxys.dts
@@ -150,53 +150,53 @@ &pinctrl0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&sleep_cfg>;
 
-	fm_i2c_pins: fm-i2c-pins {
+	fm_i2c_pins: fm-i2c-pins-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	headset_det: headset-det {
+	headset_det: headset-det-pins {
 		samsung,pins = "gph0-6", "gph3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 	};
 
-	fm_irq: fm-irq {
+	fm_irq: fm-irq-pins {
 		samsung,pins = "gpj2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	fm_rst: fm-rst {
+	fm_rst: fm-rst-pins {
 		samsung,pins = "gpj2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	earpath_sel: earpath-sel {
+	earpath_sel: earpath-sel-pins {
 		samsung,pins = "gpj2-6";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	massmemory_en: massmemory-en {
+	massmemory_en: massmemory-en-pins {
 		samsung,pins = "gpj2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	micbias_reg_ena: micbias-reg-ena {
+	micbias_reg_ena: micbias-reg-ena-pins {
 		samsung,pins = "gpj4-2";
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
 	/* Based on CyanogenMod 3.0.101 kernel */
-	sleep_cfg: sleep-cfg {
+	sleep_cfg: sleep-state {
 		PIN_SLP(gpa0-0, PREV, NONE);
 		PIN_SLP(gpa0-1, PREV, NONE);
 		PIN_SLP(gpa0-2, PREV, NONE);
diff --git a/arch/arm/boot/dts/s5pv210-pinctrl.dtsi b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
index b8c5172c31dd..ae34e7e57892 100644
--- a/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
+++ b/arch/arm/boot/dts/s5pv210-pinctrl.dtsi
@@ -26,7 +26,7 @@ _pin {								\
 	}
 
 &pinctrl0 {
-	gpa0: gpa0 {
+	gpa0: gpa0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -34,7 +34,7 @@ gpa0: gpa0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpa1: gpa1 {
+	gpa1: gpa1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -42,7 +42,7 @@ gpa1: gpa1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpb: gpb {
+	gpb: gpb-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -50,7 +50,7 @@ gpb: gpb {
 		#interrupt-cells = <2>;
 	};
 
-	gpc0: gpc0 {
+	gpc0: gpc0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -58,7 +58,7 @@ gpc0: gpc0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpc1: gpc1 {
+	gpc1: gpc1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -66,7 +66,7 @@ gpc1: gpc1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd0: gpd0 {
+	gpd0: gpd0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -74,7 +74,7 @@ gpd0: gpd0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpd1: gpd1 {
+	gpd1: gpd1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -82,7 +82,7 @@ gpd1: gpd1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe0: gpe0 {
+	gpe0: gpe0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -90,7 +90,7 @@ gpe0: gpe0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpe1: gpe1 {
+	gpe1: gpe1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -98,7 +98,7 @@ gpe1: gpe1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf0: gpf0 {
+	gpf0: gpf0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -106,7 +106,7 @@ gpf0: gpf0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf1: gpf1 {
+	gpf1: gpf1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -114,7 +114,7 @@ gpf1: gpf1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf2: gpf2 {
+	gpf2: gpf2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -122,7 +122,7 @@ gpf2: gpf2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpf3: gpf3 {
+	gpf3: gpf3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -130,7 +130,7 @@ gpf3: gpf3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg0: gpg0 {
+	gpg0: gpg0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -138,7 +138,7 @@ gpg0: gpg0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg1: gpg1 {
+	gpg1: gpg1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -146,7 +146,7 @@ gpg1: gpg1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg2: gpg2 {
+	gpg2: gpg2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -154,7 +154,7 @@ gpg2: gpg2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpg3: gpg3 {
+	gpg3: gpg3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -162,7 +162,7 @@ gpg3: gpg3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj0: gpj0 {
+	gpj0: gpj0-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -170,7 +170,7 @@ gpj0: gpj0 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj1: gpj1 {
+	gpj1: gpj1-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -178,7 +178,7 @@ gpj1: gpj1 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj2: gpj2 {
+	gpj2: gpj2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -186,7 +186,7 @@ gpj2: gpj2 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj3: gpj3 {
+	gpj3: gpj3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -194,7 +194,7 @@ gpj3: gpj3 {
 		#interrupt-cells = <2>;
 	};
 
-	gpj4: gpj4 {
+	gpj4: gpj4-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -202,47 +202,47 @@ gpj4: gpj4 {
 		#interrupt-cells = <2>;
 	};
 
-	gpi: gpi {
+	gpi: gpi-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp01: mp01 {
+	mp01: mp01-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp02: mp02 {
+	mp02: mp02-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp03: mp03 {
+	mp03: mp03-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp04: mp04 {
+	mp04: mp04-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp05: mp05 {
+	mp05: mp05-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp06: mp06 {
+	mp06: mp06-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	mp07: mp07 {
+	mp07: mp07-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 	};
 
-	gph0: gph0 {
+	gph0: gph0-gpio-bank {
 		gpio-controller;
 		interrupt-controller;
 		interrupt-parent = <&vic0>;
@@ -252,7 +252,7 @@ gph0: gph0 {
 		#interrupt-cells = <2>;
 	};
 
-	gph1: gph1 {
+	gph1: gph1-gpio-bank {
 		gpio-controller;
 		interrupt-controller;
 		interrupt-parent = <&vic0>;
@@ -262,7 +262,7 @@ gph1: gph1 {
 		#interrupt-cells = <2>;
 	};
 
-	gph2: gph2 {
+	gph2: gph2-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -270,7 +270,7 @@ gph2: gph2 {
 		#interrupt-cells = <2>;
 	};
 
-	gph3: gph3 {
+	gph3: gph3-gpio-bank {
 		gpio-controller;
 		#gpio-cells = <2>;
 
@@ -278,77 +278,77 @@ gph3: gph3 {
 		#interrupt-cells = <2>;
 	};
 
-	uart0_data: uart0-data {
+	uart0_data: uart0-data-pins {
 		samsung,pins = "gpa0-0", "gpa0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart0_fctl: uart0-fctl {
+	uart0_fctl: uart0-fctl-pins {
 		samsung,pins = "gpa0-2", "gpa0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_data: uart1-data {
+	uart1_data: uart1-data-pins {
 		samsung,pins = "gpa0-4", "gpa0-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart1_fctl: uart1-fctl {
+	uart1_fctl: uart1-fctl-pins {
 		samsung,pins = "gpa0-6", "gpa0-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_data: uart2-data {
+	uart2_data: uart2-data-pins {
 		samsung,pins = "gpa1-0", "gpa1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart2_fctl: uart2-fctl {
+	uart2_fctl: uart2-fctl-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart3_data: uart3-data {
+	uart3_data: uart3-data-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	uart_audio: uart-audio {
+	uart_audio: uart-audio-pins {
 		samsung,pins = "gpa1-2", "gpa1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi0_bus: spi0-bus {
+	spi0_bus: spi0-bus-pins {
 		samsung,pins = "gpb-0", "gpb-2", "gpb-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi1_bus: spi1-bus {
+	spi1_bus: spi1-bus-pins {
 		samsung,pins = "gpb-4", "gpb-6", "gpb-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s0_bus: i2s0-bus {
+	i2s0_bus: i2s0-bus-pins {
 		samsung,pins = "gpi-0", "gpi-1", "gpi-2", "gpi-3",
 				"gpi-4", "gpi-5", "gpi-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -356,7 +356,7 @@ i2s0_bus: i2s0-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s1_bus: i2s1-bus {
+	i2s1_bus: i2s1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -364,7 +364,7 @@ i2s1_bus: i2s1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -372,7 +372,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm1_bus: pcm1-bus {
+	pcm1_bus: pcm1-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -380,7 +380,7 @@ pcm1_bus: pcm1-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	ac97_bus: ac97-bus {
+	ac97_bus: ac97-bus-pins {
 		samsung,pins = "gpc0-0", "gpc0-1", "gpc0-2", "gpc0-3",
 				"gpc0-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
@@ -388,7 +388,7 @@ ac97_bus: ac97-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2s2_bus: i2s2-bus {
+	i2s2_bus: i2s2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
@@ -396,7 +396,7 @@ i2s2_bus: i2s2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pcm2_bus: pcm2-bus {
+	pcm2_bus: pcm2-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3",
 				"gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
@@ -404,371 +404,371 @@ pcm2_bus: pcm2-bus {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spdif_bus: spdif-bus {
+	spdif_bus: spdif-bus-pins {
 		samsung,pins = "gpc1-0", "gpc1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_4>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	spi2_bus: spi2-bus {
+	spi2_bus: spi2-bus-pins {
 		samsung,pins = "gpc1-1", "gpc1-2", "gpc1-3", "gpc1-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_5>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c0_bus: i2c0-bus {
+	i2c0_bus: i2c0-bus-pins {
 		samsung,pins = "gpd1-0", "gpd1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c1_bus: i2c1-bus {
+	i2c1_bus: i2c1-bus-pins {
 		samsung,pins = "gpd1-2", "gpd1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	i2c2_bus: i2c2-bus {
+	i2c2_bus: i2c2-bus-pins {
 		samsung,pins = "gpd1-4", "gpd1-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm0_out: pwm0-out {
+	pwm0_out: pwm0-out-pins {
 		samsung,pins = "gpd0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm1_out: pwm1-out {
+	pwm1_out: pwm1-out-pins {
 		samsung,pins = "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm2_out: pwm2-out {
+	pwm2_out: pwm2-out-pins {
 		samsung,pins = "gpd0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	pwm3_out: pwm3-out {
+	pwm3_out: pwm3-out-pins {
 		samsung,pins = "gpd0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row0: keypad-row-0 {
+	keypad_row0: keypad-row-0-pins {
 		samsung,pins = "gph3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row1: keypad-row-1 {
+	keypad_row1: keypad-row-1-pins {
 		samsung,pins = "gph3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row2: keypad-row-2 {
+	keypad_row2: keypad-row-2-pins {
 		samsung,pins = "gph3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row3: keypad-row-3 {
+	keypad_row3: keypad-row-3-pins {
 		samsung,pins = "gph3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row4: keypad-row-4 {
+	keypad_row4: keypad-row-4-pins {
 		samsung,pins = "gph3-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row5: keypad-row-5 {
+	keypad_row5: keypad-row-5-pins {
 		samsung,pins = "gph3-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row6: keypad-row-6 {
+	keypad_row6: keypad-row-6-pins {
 		samsung,pins = "gph3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_row7: keypad-row-7 {
+	keypad_row7: keypad-row-7-pins {
 		samsung,pins = "gph3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col0: keypad-col-0 {
+	keypad_col0: keypad-col-0-pins {
 		samsung,pins = "gph2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col1: keypad-col-1 {
+	keypad_col1: keypad-col-1-pins {
 		samsung,pins = "gph2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col2: keypad-col-2 {
+	keypad_col2: keypad-col-2-pins {
 		samsung,pins = "gph2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col3: keypad-col-3 {
+	keypad_col3: keypad-col-3-pins {
 		samsung,pins = "gph2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col4: keypad-col-4 {
+	keypad_col4: keypad-col-4-pins {
 		samsung,pins = "gph2-4";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col5: keypad-col-5 {
+	keypad_col5: keypad-col-5-pins {
 		samsung,pins = "gph2-5";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col6: keypad-col-6 {
+	keypad_col6: keypad-col-6-pins {
 		samsung,pins = "gph2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	keypad_col7: keypad-col-7 {
+	keypad_col7: keypad-col-7-pins {
 		samsung,pins = "gph2-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	sd0_clk: sd0-clk {
+	sd0_clk: sd0-clk-pins {
 		samsung,pins = "gpg0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cmd: sd0-cmd {
+	sd0_cmd: sd0-cmd-pins {
 		samsung,pins = "gpg0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_cd: sd0-cd {
+	sd0_cd: sd0-cd-pins {
 		samsung,pins = "gpg0-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus1: sd0-bus-width1 {
+	sd0_bus1: sd0-bus-width1-pins {
 		samsung,pins = "gpg0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus4: sd0-bus-width4 {
+	sd0_bus4: sd0-bus-width4-pins {
 		samsung,pins = "gpg0-3", "gpg0-4", "gpg0-5", "gpg0-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd0_bus8: sd0-bus-width8 {
+	sd0_bus8: sd0-bus-width8-pins {
 		samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_clk: sd1-clk {
+	sd1_clk: sd1-clk-pins {
 		samsung,pins = "gpg1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cmd: sd1-cmd {
+	sd1_cmd: sd1-cmd-pins {
 		samsung,pins = "gpg1-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_cd: sd1-cd {
+	sd1_cd: sd1-cd-pins {
 		samsung,pins = "gpg1-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus1: sd1-bus-width1 {
+	sd1_bus1: sd1-bus-width1-pins {
 		samsung,pins = "gpg1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd1_bus4: sd1-bus-width4 {
+	sd1_bus4: sd1-bus-width4-pins {
 		samsung,pins = "gpg1-3", "gpg1-4", "gpg1-5", "gpg1-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_clk: sd2-clk {
+	sd2_clk: sd2-clk-pins {
 		samsung,pins = "gpg2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cmd: sd2-cmd {
+	sd2_cmd: sd2-cmd-pins {
 		samsung,pins = "gpg2-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_cd: sd2-cd {
+	sd2_cd: sd2-cd-pins {
 		samsung,pins = "gpg2-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus1: sd2-bus-width1 {
+	sd2_bus1: sd2-bus-width1-pins {
 		samsung,pins = "gpg2-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus4: sd2-bus-width4 {
+	sd2_bus4: sd2-bus-width4-pins {
 		samsung,pins = "gpg2-3", "gpg2-4", "gpg2-5", "gpg2-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd2_bus8: sd2-bus-width8 {
+	sd2_bus8: sd2-bus-width8-pins {
 		samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_clk: sd3-clk {
+	sd3_clk: sd3-clk-pins {
 		samsung,pins = "gpg3-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cmd: sd3-cmd {
+	sd3_cmd: sd3-cmd-pins {
 		samsung,pins = "gpg3-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_cd: sd3-cd {
+	sd3_cd: sd3-cd-pins {
 		samsung,pins = "gpg3-2";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus1: sd3-bus-width1 {
+	sd3_bus1: sd3-bus-width1-pins {
 		samsung,pins = "gpg3-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	sd3_bus4: sd3-bus-width4 {
+	sd3_bus4: sd3-bus-width4-pins {
 		samsung,pins = "gpg3-3", "gpg3-4", "gpg3-5", "gpg3-6";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_UP>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	eint0: ext-int0 {
+	eint0: ext-int0-pins {
 		samsung,pins = "gph0-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint8: ext-int8 {
+	eint8: ext-int8-pins {
 		samsung,pins = "gph1-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint15: ext-int15 {
+	eint15: ext-int15-pins {
 		samsung,pins = "gph1-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint16: ext-int16 {
+	eint16: ext-int16-pins {
 		samsung,pins = "gph2-0";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	eint31: ext-int31 {
+	eint31: ext-int31-pins {
 		samsung,pins = "gph3-7";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_io: cam-port-a-io {
+	cam_port_a_io: cam-port-a-io-pins {
 		samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
 				"gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
 				"gpe1-0", "gpe1-1", "gpe1-2", "gpe1-4";
@@ -777,21 +777,21 @@ cam_port_a_io: cam-port-a-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_a_clk_active: cam-port-a-clk-active {
+	cam_port_a_clk_active: cam-port-a-clk-active-pins {
 		samsung,pins = "gpe1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_a_clk_idle: cam-port-a-clk-idle {
+	cam_port_a_clk_idle: cam-port-a-clk-idle-pins {
 		samsung,pins = "gpe1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_b_io: cam-port-b-io {
+	cam_port_b_io: cam-port-b-io-pins {
 		samsung,pins = "gpj0-0", "gpj0-1", "gpj0-2", "gpj0-3",
 				"gpj0-4", "gpj0-5", "gpj0-6", "gpj0-7",
 				"gpj1-0", "gpj1-1", "gpj1-2", "gpj1-4";
@@ -800,42 +800,42 @@ cam_port_b_io: cam-port-b-io {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	cam_port_b_clk_active: cam-port-b-clk-active {
+	cam_port_b_clk_active: cam-port-b-clk-active-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
 	};
 
-	cam_port_b_clk_idle: cam-port-b-clk-idle {
+	cam_port_b_clk_idle: cam-port-b-clk-idle-pins {
 		samsung,pins = "gpj1-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_DOWN>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-		lcd_ctrl: lcd-ctrl {
+	lcd_ctrl: lcd-ctrl-pins {
 		samsung,pins = "gpd0-0", "gpd0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_sync: lcd-sync {
+	lcd_sync: lcd-sync-pins {
 		samsung,pins = "gpf0-0", "gpf0-1";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_clk: lcd-clk {
+	lcd_clk: lcd-clk-pins {
 		samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3";
 		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
 		samsung,pin-pud = <S3C64XX_PIN_PULL_NONE>;
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 
-	lcd_data24: lcd-data-width24 {
+	lcd_data24: lcd-data-width24-pins {
 		samsung,pins =  "gpf0-4", "gpf0-5", "gpf0-6", "gpf0-7",
 				"gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3",
 				"gpf1-4", "gpf1-5", "gpf1-6", "gpf1-7",
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:19 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:19 +0100
Subject: [PATCH v2 25/28] dt-bindings: pinctrl: samsung: describe Exynos850
 and ExynosAutov9 wake-ups
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-19-krzysztof.kozlowski@canonical.com>

Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
Exynos5, Exynos5433) with external wake-up interrupts, expected to have
one interrupt for multiplexing these wake-up interrupts.  Also they
expected to have exactly one pin controller capable of external wake-up
interrupts.

It seems however that newer ARMv8 Exynos SoC like Exynos850 and
ExynosAutov9 have differences of their pin controller node capable of
external wake-up interrupts:
1. No multiplexed external wake-up interrupt, only direct,
2. More than one pin controller capable of external wake-up interrupts.

Add dedicated Exynos850 and ExynosAutov9 compatibles.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../samsung,pinctrl-wakeup-interrupt.yaml     | 27 ++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
index 6b684a53119b..a822f70f5702 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
@@ -16,9 +16,12 @@ description: |
   controller.
 
   External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
-  Only one pin-controller device node can include external wake-up interrupts
-  child node (in other words, only one External wake-up interrupts
+  For S3C24xx, S3C64xx, S5PV210 and Exynos4210 compatible wake-up interrupt
+  controllers, only one pin-controller device node can include external wake-up
+  interrupts child node (in other words, only one External wake-up interrupts
   pin-controller is supported).
+  For newer controllers, multiple pin-controller device node can include
+  external wake-up interrupts child node.
 
   See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
   additional information and example.
@@ -32,6 +35,8 @@ properties:
       - samsung,s5pv210-wakeup-eint
       - samsung,exynos4210-wakeup-eint
       - samsung,exynos7-wakeup-eint
+      - samsung,exynos850-wakeup-eint
+      - samsung,exynosautov9-wakeup-eint
 
   interrupts:
     description:
@@ -41,7 +46,6 @@ properties:
 
 required:
   - compatible
-  - interrupts
 
 allOf:
   - if:
@@ -56,6 +60,8 @@ allOf:
         interrupts:
           minItems: 6
           maxItems: 6
+      required:
+        - interrupts
 
   - if:
       properties:
@@ -67,6 +73,8 @@ allOf:
         interrupts:
           minItems: 4
           maxItems: 4
+      required:
+        - interrupts
 
   - if:
       properties:
@@ -81,5 +89,18 @@ allOf:
         interrupts:
           minItems: 1
           maxItems: 1
+      required:
+        - interrupts
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos850-wakeup-eint
+              - samsung,exynosautov9-wakeup-eint
+    then:
+      properties:
+        interrupts: false
 
 additionalProperties: false
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:20 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:20 +0100
Subject: [PATCH v2 26/28] pinctrl: samsung: add support for Exynos850 and
 ExynosAutov9 wake-ups
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-20-krzysztof.kozlowski@canonical.com>

It seems that newer ARMv8 Exynos SoC like Exynos850 and
ExynosAutov9 have differences of their pin controller node capable of
external wake-up interrupts:
1. No multiplexed external wake-up interrupt, only direct,
2. More than one pin controller capable of external wake-up interrupts.

Add support for dedicated Exynos850 and ExynosAutov9 compatibles.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/pinctrl/samsung/pinctrl-exynos.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 0489c899b401..a158d587814e 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -465,6 +465,10 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
 			.data = &exynos4210_wkup_irq_chip },
 	{ .compatible = "samsung,exynos7-wakeup-eint",
 			.data = &exynos7_wkup_irq_chip },
+	{ .compatible = "samsung,exynos850-wakeup-eint",
+			.data = &exynos7_wkup_irq_chip },
+	{ .compatible = "samsung,exynosautov9-wakeup-eint",
+			.data = &exynos7_wkup_irq_chip },
 	{ }
 };
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:22 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:22 +0100
Subject: [PATCH v2 28/28] arm64: dts: exynos: use dedicated wake-up pinctrl
 compatible in ExynosAutov9
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-22-krzysztof.kozlowski@canonical.com>

Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
Exynos5, Exynos5433) with external wake-up interrupts, expected to have
one interrupt for multiplexing these wake-up interrupts.  Also they
expected to have exactly one pin controller capable of external wake-up
interrupts.

It seems however that newer ARMv8 Exynos SoC like Exynos850 and
ExynosAutov9 have differences:
1. No multiplexed external wake-up interrupt, only direct,
2. More than one pin controller capable of external wake-up interrupts.

Use dedicated ExynosAutov9 compatible for its external wake-up interrupts
controller to indicate the differences.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
index de8fcb82eaec..807d500d6022 100644
--- a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
@@ -208,7 +208,7 @@ pinctrl_alive: pinctrl at 10450000 {
 			reg = <0x10450000 0x1000>;
 
 			wakeup-interrupt-controller {
-				compatible = "samsung,exynos7-wakeup-eint";
+				compatible = "samsung,exynosautov9-wakeup-eint";
 			};
 		};
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Tue Jan 11 12:17:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 11 Jan 2022 21:17:21 +0100
Subject: [PATCH v2 27/28] arm64: dts: exynos: use dedicated wake-up pinctrl
 compatible in Exynos850
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220111201722.327219-21-krzysztof.kozlowski@canonical.com>

Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
Exynos5, Exynos5433) with external wake-up interrupts, expected to have
one interrupt for multiplexing these wake-up interrupts.  Also they
expected to have exactly one pin controller capable of external wake-up
interrupts.

It seems however that newer ARMv8 Exynos SoC like Exynos850 and
ExynosAutov9 have differences:
1. No multiplexed external wake-up interrupt, only direct,
2. More than one pin controller capable of external wake-up interrupts.

Use dedicated Exynos850 compatible for its external wake-up interrupts
controller to indicate the differences.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos850.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
index 4f0a40de5e67..bcae772e8d91 100644
--- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -346,7 +346,7 @@ pinctrl_alive: pinctrl at 11850000 {
 			reg = <0x11850000 0x1000>;
 
 			wakeup-interrupt-controller {
-				compatible = "samsung,exynos7-wakeup-eint";
+				compatible = "samsung,exynos850-wakeup-eint";
 			};
 		};
 
@@ -355,7 +355,7 @@ pinctrl_cmgp: pinctrl at 11c30000 {
 			reg = <0x11c30000 0x1000>;
 
 			wakeup-interrupt-controller {
-				compatible = "samsung,exynos7-wakeup-eint";
+				compatible = "samsung,exynos850-wakeup-eint";
 			};
 		};
 
-- 
2.32.0



From sfr at canb.auug.org.au  Tue Jan 11 12:41:47 2022
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Wed, 12 Jan 2022 07:41:47 +1100
Subject: linux-next: error fetching the arm-soc-fixes tree
Message-ID: <20220112074147.7d38bc43@canb.auug.org.au>

Hi all,

Fetching the arm-soc-fixes tree
(git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#arm/fixes)
produces this error:

fatal: couldn't find remote ref refs/heads/arm/fixes

-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/5869b99a/attachment.sig>

From fllinden at amazon.com  Tue Jan 11 12:44:41 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Tue, 11 Jan 2022 20:44:41 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <Yd1cnquQFZoNE7FP@kernel.org>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com> <Yd1cnquQFZoNE7FP@kernel.org>
Message-ID: <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>

On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote:
> > --- a/include/linux/memblock.h
> > +++ b/include/linux/memblock.h
> > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
> >  phys_addr_t memblock_start_of_DRAM(void);
> >  phys_addr_t memblock_end_of_DRAM(void);
> >  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> > +void memblock_enforce_usable_range(void);
> >  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
> >  void memblock_mem_limit_remove_map(phys_addr_t limit);
> 
> We already have 3 very similar interfaces that deal with memory capping.
> Now you suggest to add fourth that will "generically" solve a single use
> case of DT, EFI and kdump interaction on arm64.
> 
> Looks like a workaround for a fundamental issue of incompatibility between
> DT and EFI wrt memory registration.

Yep, I figured this would be the main argument against this - arm64
already added several other more-or-less special cased interfaces over
time.

I'm more than happy to solve this in a different way.

What would you suggest:

1) Try to merge the similar interfaces in to one.
2) Just deal with it at a lower (arm64) level?
3) Some other way?

Thanks,

- Frank


From acme at kernel.org  Tue Jan 11 12:47:11 2022
From: acme at kernel.org (Arnaldo Carvalho de Melo)
Date: Tue, 11 Jan 2022 17:47:11 -0300
Subject: [PATCH v4 48/48] perf cpumap: Give CPUs their own type.
In-Reply-To: <Yd3iBvVim1vB81pM@kernel.org>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-49-irogers@google.com>
 <YdyOFd8JJHbm1W+m@kernel.org>
 <CAP-5=fWZWMweYhWvv1vr6quZe=ZJrhF_WEXqbELVitzofBcQrA@mail.gmail.com>
 <Yd3iBvVim1vB81pM@kernel.org>
Message-ID: <Yd3sz/P3UXae7xxx@kernel.org>

Em Tue, Jan 11, 2022 at 05:01:10PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jan 11, 2022 at 11:16:16AM -0800, Ian Rogers escreveu:
> > On Mon, Jan 10, 2022 at 11:50 AM Arnaldo Carvalho de Melo <acme at kernel.org> wrote:

> > > Em Tue, Jan 04, 2022 at 10:13:51PM -0800, Ian Rogers escreveu:
> > > > A common problem is confusing CPU map indices with the CPU, by wrapping
> > > > the CPU with a struct then this is avoided. This approach is similar to
> > > > atomic_t.
> > >
> > > This one needed this to build with BUILD_BPF_SKEL=1, please check, I'll
> > > soon push this to tmp.perf/perf_cpu so that you can take a look and test
> > > it.

> > Thanks Arnaldo, I did eye-ball one issue where cpu_map__default_new's
> > behavior would be impacted (nr would be 1 rather than nr_cpus). The
> > fix is:
> > 
> > --- a/tools/lib/perf/cpumap.c
> > +++ b/tools/lib/perf/cpumap.c
> > @@ -18,7 +18,7 @@ static struct perf_cpu_map *perf_cpu_map__alloc(int nr_cpus)
> >         if (!cpus)
> >                 return NULL;
> > 
> > -       cpus->nr = 1;
> > +       cpus->nr = nr_cpus;
> >         refcount_set(&cpus->refcnt, 1);
> >         return cpus;
> >  }
> 
> > Could you add that into this patch as well?
> 
> Sure.
> 
> I?m now running perf-test after each of those csets, so far so good.

This is what I'm running now after doing a 'git rebase -i
start-of-your-patchkit' with all set to 'edit'.

Will take a while :-)

# cat ~/bin/perf-test-build
#!/bin/bash

while true ; do
	rm -rf /tmp/build/perf ; sudo -u acme mkdir /tmp/build/perf
	sudo -u acme make -k BUILD_BPF_SKEL=1 PYTHON=python3 O=/tmp/build/perf -C tools/perf install-bin || exit 1
	cd ..
	perf test || exit 2
	cd -
	sudo -u acme git rebase --continue || exit 0
done

- Arnaldo


From abel.vesa at nxp.com  Tue Jan 11 12:52:29 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 11 Jan 2022 22:52:29 +0200
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050
 clock driver
In-Reply-To: <baa991a5-31d8-80fb-faf0-b443626030d4@gmail.com>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
 <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
 <20220110201201.C1E37C36AE9@smtp.kernel.org>
 <Ydy3qvT5w6IWnR7s@abelvesa>
 <baa991a5-31d8-80fb-faf0-b443626030d4@gmail.com>
Message-ID: <Yd3uDSAwQMoNz8e3@abelvesa>

On 22-01-10 19:18:58, Jesse Taube wrote:
> 
> 
> On 1/10/22 17:48, Abel Vesa wrote:
> > On 22-01-10 12:12:00, Stephen Boyd wrote:
> > > Quoting Jesse Taube (2022-01-09 11:07:42)
> > > > > > +
> > > > > > +       clk_hw_data->num = IMXRT1050_CLK_END;
> > > > > > +       hws = clk_hw_data->hws;
> > > > > > +
> > > > > > +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> > > > > 
> > > > > Use clk_parent_data instead and reference the binding name with .fw_name
> > > > 
> > > > Hi Stephen, sorry to bother you again.
> > > > I'm wondering if adding `clk_parent_data` is necessary as it seems like
> > > > it wold be a big change and the other IMX boards haven't implemented
> > > > this yet would it be okay if I don't do this, or if it is necessary
> > > > could you link to a patch set to change it.
> > > > 
> > > 
> > > Is it a big change because the imx_clk_hw*() APIs aren't prepared for
> > > non-string parents? Can you make some clk_parent_data based APIs and
> > > migrate things over gradually? This is really a question for i.MX folks
> > > to see if anyone is working on moving away from the string names.
> > 
> > I'm currently looking into it. I would suggest we take this patch as is
> > and I'll switch it later on to clk_parent_data.
> Thanks so much that would be great!
> 
> Should I sent the other changes requested I have them ready? Or should i
> wait.

Sure, send it. If Stephen is OK with my suggestion, I will pick it.

> 
> Best regards
> 	Jesse Taube


From stefan at agner.ch  Tue Jan 11 12:58:42 2022
From: stefan at agner.ch (Stefan Agner)
Date: Tue, 11 Jan 2022 21:58:42 +0100
Subject: [PATCH 4.19 5/6] ARM: 8788/1: ftrace: remove old mcount support
In-Reply-To: <YcBhqJMLdwieZa8X@kroah.com>
References: <20211217144119.2538175-1-anders.roxell@linaro.org>
 <20211217144119.2538175-6-anders.roxell@linaro.org>
 <YcBhqJMLdwieZa8X@kroah.com>
Message-ID: <cf6f7b9e8694fa87c3e27bd6be67afd2@agner.ch>

On 2021-12-20 11:57, Greg KH wrote:
> On Fri, Dec 17, 2021 at 03:41:18PM +0100, Anders Roxell wrote:
>> From: Stefan Agner <stefan at agner.ch>
>>
>> commit d3c61619568c88d48eccd5e74b4f84faa1440652 upstream.
>>
>> Commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6")
>> raised the minimum GCC version to 4.6. Old mcount is only required for
>> GCC versions older than 4.4.0. Hence old mcount support can be dropped
>> too.
>>
>> Signed-off-by: Stefan Agner <stefan at agner.ch>
>> Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
>> Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
> 
> Why is this needed for clang builds in 4.19?

As far as I remember, Clang tripped over this part:

-#ifndef CONFIG_OLD_MCOUNT
-#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
-#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than
4.4.0.
-#endif
-#endif

Since mcount support wasn't required upstream at that point, instead of
fixing it for Clang I just removed it.

--
Stefan


From ndesaulniers at google.com  Tue Jan 11 13:04:18 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 11 Jan 2022 13:04:18 -0800
Subject: [PATCH 4.19 5/6] ARM: 8788/1: ftrace: remove old mcount support
In-Reply-To: <20211217144119.2538175-6-anders.roxell@linaro.org>
References: <20211217144119.2538175-1-anders.roxell@linaro.org>
 <20211217144119.2538175-6-anders.roxell@linaro.org>
Message-ID: <CAKwvOdk0p98ac0yVLwLiJXndvyJw+Ufpxke2WEVrhyUOftN6=Q@mail.gmail.com>

 On Fri, Dec 17, 2021 at 6:41 AM Anders Roxell <anders.roxell at linaro.org> wrote:
>
> From: Stefan Agner <stefan at agner.ch>
>
> commit d3c61619568c88d48eccd5e74b4f84faa1440652 upstream.
>
> Commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6")
> raised the minimum GCC version to 4.6. Old mcount is only required for
> GCC versions older than 4.4.0. Hence old mcount support can be dropped
> too.

cafa0010cd51 first landed in v4.19-rc1, so that lgtm.
-- 
Thanks,
~Nick Desaulniers


From mr.bossman075 at gmail.com  Tue Jan 11 13:25:59 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:25:59 -0500
Subject: [PATCH v7 0/7] Add initial support for the i.MXRTxxxx SoC family
 starting from i.IMXRT1050 SoC.
Message-ID: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>

This patchset contains:
- i.MXRT10xx family infrastructure
- i.MXRT1050 pinctrl driver adaption
- i.MXRT1050 clock driver adaption
- i.MXRT1050 sd-card driver adaption
- i.MXRT1050 uart driver adaption
- i.MXRT1050-evk basic support

The i.MXRTxxxx family that could have support by Linux actually spreads
from i.MXRT1020 to i.MXRT1170 with the first one supporting 1 USB OTG &
100M ethernet with a cortex-M7 at 500Mhz up to the latter with i.MXRT1170
with cortex-M7 at 1Ghz and cortex-M4 at 400Mhz, 2MB of internal SRAM, 2D GPU,
2x 1Gb and 1x 100Mb ENET. The i.MXRT family is NXP's answer to
STM32F7XX, as it uses only simple SDRAM, it gives the chance of a 4 or
less layer PCBs. Seeing that these chips are comparable to the
STM32F7XXs which have linux ported to them it seems reasonable to add
support for them.

Giving Linux support to this family should ease the development process,
instead of using a RTOS they could use Embedded Linux allowing for more
portability, ease of design and will broaden the scope of people using
embedded linux.

The EVK has very little SDRAM, generally 32MB starting from
i.MXRT1020(the lowest P/N), although the i.MXRT1160/70 provide instead
64MB of SDRAM for more functionality.

At the moment we do not support XIP for either u-boot or Linux but it
should be done in the future. XIP will also save SDRAM.

Another interesting fact is the amount of internal SRAM, as the P/N
increases the SRAM will reach up to 2MB(some could be for cache and
some would be for video).

Also, some parts have embed flash of 4MB that can be used for
u-boot/Linux, if both correctly sized it will leave the SDRAM free.

External flash can be Quad SPI and HyperFlash, so throughput would be
decent.

The i.MXRT11xx series supports MIPI interface too.

The family in general provide CAN bus, audio I/O, 1 or more
USB(otg/host), 1 or more 100Mb/1Gb ethernet, camera interface, sd-card.

All this can be used for simple GUIs, web-servers, point-of-sale
stations, etc.


Giulio Benetti (4):
  ARM: imx: Add initial support for i.MXRT10xx family
  dt-bindings: imx: Add clock binding for i.MXRT1050
  ARM: dts: imx: Add i.MXRT1050-EVK support
  ARM: imxrt_defconfig: Add i.MXRT family defconfig

Jesse Taube (3):
  ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
  dt-bindings: clock: imx: Add documentation for i.MXRT1050 clock
  clk: imx: Add initial support for i.MXRT1050 clock driver

 .../bindings/clock/imxrt1050-clock.yaml       |  67 ++
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts           |  72 ++
 arch/arm/boot/dts/imxrt1050-pinfunc.h         | 993 ++++++++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi              | 160 +++
 arch/arm/configs/imxrt_defconfig              |  35 +
 arch/arm/mach-imx/Kconfig                     |   7 +
 arch/arm/mach-imx/Makefile                    |   2 +
 arch/arm/mach-imx/mach-imxrt.c                |  19 +
 drivers/clk/imx/Kconfig                       |   7 +
 drivers/clk/imx/Makefile                      |   1 +
 drivers/clk/imx/clk-imxrt1050.c               | 168 +++
 include/dt-bindings/clock/imxrt1050-clock.h   |  72 ++
 13 files changed, 1605 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi
 create mode 100644 arch/arm/configs/imxrt_defconfig
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:00 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:00 -0500
Subject: [PATCH v7 1/7] ARM: imx: Add initial support for i.MXRT10xx family
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-2-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The i.MXRT10xx family of processors features NXP's implementation of the
Arm Cortex-M7 core and in some case the Arm Cortex-M4 core too.

This patch aims to add an initial support for imxrt.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: removed SOC_IMXRT's 'depends on ARCH_MULTI_V7' and 'select
ARM_GIC if ARCH_MULTI_V7']
---
V1->V2:
* Remove depends ARCH_MULTI_V7
* Remove select PINCTRL_IMXRT
* Change commit description
V2->V3:
* Nothing done
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/mach-imx/Kconfig      |  7 +++++++
 arch/arm/mach-imx/Makefile     |  2 ++
 arch/arm/mach-imx/mach-imxrt.c | 19 +++++++++++++++++++
 3 files changed, 28 insertions(+)
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b407b024dde3..5ad3a8b9b4b6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -239,6 +239,13 @@ config SOC_IMX7ULP
 	help
 	  This enables support for Freescale i.MX7 Ultra Low Power processor.
 
+config SOC_IMXRT
+	bool "i.MXRT support"
+	depends on ARM_SINGLE_ARMV7M
+	select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+	help
+	  This enables support for Freescale i.MXRT Crossover processor.
+
 config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d1506ef7a537..3b1145722a44 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -65,6 +65,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
+obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
+
 obj-$(CONFIG_SOC_VF610) += mach-vf610.o
 
 obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
diff --git a/arch/arm/mach-imx/mach-imxrt.c b/arch/arm/mach-imx/mach-imxrt.c
new file mode 100644
index 000000000000..2063a3059c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imxrt.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include <asm/v7m.h>
+
+static const char *const imxrt_compat[] __initconst = {
+	"fsl,imxrt1050",
+	NULL
+};
+
+DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
+	.dt_compat = imxrt_compat,
+	.restart = armv7m_restart,
+MACHINE_END
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:02 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:02 -0500
Subject: [PATCH v7 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-4-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add the clock binding doc for i.MXRT1050.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
[Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]
---
V1->V2:
* Nothing done
V2->V3:
* Added GPT binding
V3->V4:
* Change License to MIT or GPL-2
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Fix typo in numbering
* Remove GPT
V7->V8:
* Nothing done
---
 include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h
new file mode 100644
index 000000000000..93bef0832d16
--- /dev/null
+++ b/include/dt-bindings/clock/imxrt1050-clock.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright(C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMXRT1050_H
+#define __DT_BINDINGS_CLOCK_IMXRT1050_H
+
+#define IMXRT1050_CLK_DUMMY			0
+#define IMXRT1050_CLK_CKIL			1
+#define IMXRT1050_CLK_CKIH			2
+#define IMXRT1050_CLK_OSC			3
+#define IMXRT1050_CLK_PLL2_PFD0_352M		4
+#define IMXRT1050_CLK_PLL2_PFD1_594M		5
+#define IMXRT1050_CLK_PLL2_PFD2_396M		6
+#define IMXRT1050_CLK_PLL3_PFD0_720M		7
+#define IMXRT1050_CLK_PLL3_PFD1_664_62M		8
+#define IMXRT1050_CLK_PLL3_PFD2_508_24M		9
+#define IMXRT1050_CLK_PLL3_PFD3_454_74M		10
+#define IMXRT1050_CLK_PLL2_198M			11
+#define IMXRT1050_CLK_PLL3_120M			12
+#define IMXRT1050_CLK_PLL3_80M			13
+#define IMXRT1050_CLK_PLL3_60M			14
+#define IMXRT1050_CLK_PLL1_BYPASS		15
+#define IMXRT1050_CLK_PLL2_BYPASS		16
+#define IMXRT1050_CLK_PLL3_BYPASS		17
+#define IMXRT1050_CLK_PLL5_BYPASS		19
+#define IMXRT1050_CLK_PLL1_REF_SEL		20
+#define IMXRT1050_CLK_PLL2_REF_SEL		21
+#define IMXRT1050_CLK_PLL3_REF_SEL		22
+#define IMXRT1050_CLK_PLL5_REF_SEL		23
+#define IMXRT1050_CLK_PRE_PERIPH_SEL		24
+#define IMXRT1050_CLK_PERIPH_SEL		25
+#define IMXRT1050_CLK_SEMC_ALT_SEL		26
+#define IMXRT1050_CLK_SEMC_SEL			27
+#define IMXRT1050_CLK_USDHC1_SEL		28
+#define IMXRT1050_CLK_USDHC2_SEL		29
+#define IMXRT1050_CLK_LPUART_SEL		30
+#define IMXRT1050_CLK_LCDIF_SEL			31
+#define IMXRT1050_CLK_VIDEO_POST_DIV_SEL	32
+#define IMXRT1050_CLK_VIDEO_DIV			33
+#define IMXRT1050_CLK_ARM_PODF			34
+#define IMXRT1050_CLK_LPUART_PODF		35
+#define IMXRT1050_CLK_USDHC1_PODF		36
+#define IMXRT1050_CLK_USDHC2_PODF		37
+#define IMXRT1050_CLK_SEMC_PODF			38
+#define IMXRT1050_CLK_AHB_PODF			39
+#define IMXRT1050_CLK_LCDIF_PRED		40
+#define IMXRT1050_CLK_LCDIF_PODF		41
+#define IMXRT1050_CLK_USDHC1			42
+#define IMXRT1050_CLK_USDHC2			43
+#define IMXRT1050_CLK_LPUART1			44
+#define IMXRT1050_CLK_SEMC			45
+#define IMXRT1050_CLK_LCDIF_APB			46
+#define IMXRT1050_CLK_PLL1_ARM			47
+#define IMXRT1050_CLK_PLL2_SYS			48
+#define IMXRT1050_CLK_PLL3_USB_OTG		49
+#define IMXRT1050_CLK_PLL4_AUDIO		50
+#define IMXRT1050_CLK_PLL5_VIDEO		51
+#define IMXRT1050_CLK_PLL6_ENET			52
+#define IMXRT1050_CLK_PLL7_USB_HOST		53
+#define IMXRT1050_CLK_LCDIF_PIX			54
+#define IMXRT1050_CLK_USBOH3			55
+#define IMXRT1050_CLK_IPG_PDOF			56
+#define IMXRT1050_CLK_PER_CLK_SEL		57
+#define IMXRT1050_CLK_PER_PDOF			58
+#define IMXRT1050_CLK_DMA			59
+#define IMXRT1050_CLK_DMA_MUX			60
+#define IMXRT1050_CLK_END			61
+
+#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:03 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:03 -0500
Subject: [PATCH v7 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-5-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add DT binding documentation for i.MXRT1050 clock driver.

Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Replace macros with values
V2->V3:
* Remove anatop
* Use lpuart not gpt
* include imxrt1050-clock.h
* 2 space tabs to 4
* Remove oneOf enum
* Change maxItems to 2
V3->V4:
* Nothing done
V4->V5:
* Remove extra newline
* Rename ccm to clock-controller
* Change minItems to const
* Change minItems to description
* Rename file to add 1050
* Change commit description to just 1050
V5->V6:
* Add maxItems for clocks description
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 .../bindings/clock/imxrt1050-clock.yaml       | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
new file mode 100644
index 000000000000..35fd08c143f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imxrt1050-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MXRT
+
+maintainers:
+  - Giulio Benetti <giulio.benetti at benettiengineering.com>
+  - Jesse Taube <Mr.Bossman075 at gmail.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imxrt*-clock.h
+  for the full list of i.MXRT clock IDs.
+
+properties:
+  compatible:
+    const: fsl,imxrt1050-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 2
+
+  clocks:
+    description: 24m osc
+    maxItems: 1
+
+  clock-names:
+    const: osc
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imxrt1050-clock.h>
+
+    clks: clock-controller at 400fc000 {
+        compatible = "fsl,imxrt1050-ccm";
+        reg = <0x400fc000 0x4000>;
+        interrupts = <95>, <96>;
+        clocks = <&osc>;
+        clock-names = "osc";
+        #clock-cells = <1>;
+    };
+
+    lpuart1: serial at 40184000 {
+        compatible = "fsl,imxrt1050-lpuart";
+        reg = <0x40184000 0x4000>;
+        interrupts = <20>;
+        clocks = <&clks IMXRT1050_CLK_LPUART1>;
+        clock-names = "ipg";
+    };
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:01 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:01 -0500
Subject: [PATCH v7 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-3-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add binding header for i.MXRT1050 pinctrl device tree.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: move pinfunc from dt-bindings to dts folder]
---
V1->V2:
* Move pinfunc from dt-binding to dts
* Change subject and description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Change License comment style
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/boot/dts/imxrt1050-pinfunc.h | 993 ++++++++++++++++++++++++++
 1 file changed, 993 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h

diff --git a/arch/arm/boot/dts/imxrt1050-pinfunc.h b/arch/arm/boot/dts/imxrt1050-pinfunc.h
new file mode 100644
index 000000000000..22c14a3262ad
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-pinfunc.h
@@ -0,0 +1,993 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+#define _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+
+#define IMX_PAD_SION	0x40000000
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MXRT1050_IOMUXC_GPIO_EMC_00_SEMC_DA00				0x014 0x204 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXPWM4_PWM0_A			0x014 0x204 0x494 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_LPSPI2_SCK				0x014 0x204 0x500 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_00_XBAR_INOUT2				0x014 0x204 0x60C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXIO1_D00				0x014 0x204 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_GPIO4_IO00				0x014 0x204 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_01_SEMC_DA01				0x018 0x208 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXPWM4_PWM0_B			0x018 0x208 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_LPSPI2_PCS0				0x018 0x208 0x4FC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_01_XBAR_INOUT3				0x018 0x208 0x610 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXIO1_D01				0x018 0x208 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_GPIO4_IO01				0x018 0x208 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_02_SEMC_DA02				0x01C 0x20C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXPWM4_PWM1_A			0x01C 0x20C 0x498 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_LPSPI2_SDO				0x01C 0x20C 0x508 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_02_XBAR_INOUT4				0x01C 0x20C 0x614 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXIO1_D02				0x01C 0x20C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_GPIO4_IO02				0x01C 0x20C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_03_SEMC_DA03				0x020 0x210 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXPWM4_PWM1_B			0x020 0x210 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_LPSPI2_SDI				0x020 0x210 0x504 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_03_XBAR_INOUT5				0x020 0x210 0x618 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXIO1_D03				0x020 0x210 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_GPIO4_IO03				0x020 0x210 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SEMC_DA04				0x024 0x214 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXPWM4_PWM2_A			0x024 0x214 0x49C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SAI2_TX_DATA			0x024 0x214 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_XBAR_INOUT6				0x024 0x214 0x61C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXIO1_D04				0x024 0x214 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_GPIO4_IO04				0x024 0x214 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SEMC_DA05				0x028 0x218 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXPWM4_PWM2_B			0x028 0x218 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SAI2_TX_SYNC			0x028 0x218 0x5C4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_XBAR_INOUT7				0x028 0x218 0x620 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXIO1_D05				0x028 0x218 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_GPIO4_IO05				0x028 0x218 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SEMC_DA06				0x02C 0x21C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXPWM2_PWM0_A			0x02C 0x21C 0x478 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SAI2_TX_BCLK			0x02C 0x21C 0x5C0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_XBAR_INOUT8				0x02C 0x21C 0x624 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXIO1_D06				0x02C 0x21C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_GPIO4_IO06				0x02C 0x21C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SEMC_DA07				0x030 0x220 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXPWM2_PWM0_B			0x030 0x220 0x488 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SAI2_MCLK				0x030 0x220 0x5B0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_XBAR_INOUT9				0x030 0x220 0x628 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXIO1_D07				0x030 0x220 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_GPIO4_IO07				0x030 0x220 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SEMC_DM00				0x034 0x224 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXPWM2_PWM1_A			0x034 0x224 0x47C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SAI2_RX_DATA			0x034 0x224 0x5B8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_XBAR_INOUT17			0x034 0x224 0x62C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXIO1_D08				0x034 0x224 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_GPIO4_IO08				0x034 0x224 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SEMC_ADDR00				0x038 0x228 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXPWM2_PWM1_B			0x038 0x228 0x48C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SAI2_RX_SYNC			0x038 0x228 0x5BC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXCAN2_TX				0x038 0x228 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXIO1_D09				0x038 0x228 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_GPIO4_IO09				0x038 0x228 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SEMC_ADDR01				0x03C 0x22C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXPWM2_PWM2_A			0x03C 0x22C 0x480 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SAI2_RX_BCLK			0x03C 0x22C 0x5B4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXCAN2_RX				0x03C 0x22C 0x450 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXIO1_D10				0x03C 0x22C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_GPIO4_IO10				0x03C 0x22C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_11_SEMC_ADDR02				0x040 0x230 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXPWM2_PWM2_B			0x040 0x230 0x490 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_LPI2C4_SDA				0x040 0x230 0x4E8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_USDHC2_RESET_B			0x040 0x230 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXIO1_D11				0x040 0x230 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_GPIO4_IO11				0x040 0x230 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_12_SEMC_ADDR03				0x044 0x234 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_XBAR_INOUT24			0x044 0x234 0x640 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_LPI2C4_SCL				0x044 0x234 0x4E4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_USDHC2_WP				0x044 0x234 0x5D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_FLEXPWM1_PWM3_A			0x044 0x234 0x454 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_12_GPIO4_IO12				0x044 0x234 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_13_SEMC_ADDR04				0x048 0x238 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_XBAR_INOUT25			0x048 0x238 0x650 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_LPUART3_TXD				0x048 0x238 0x53C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_MQS_RIGHT				0x048 0x238 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_FLEXPWM1_PWM3_B			0x048 0x238 0x464 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_GPIO4_IO13				0x048 0x238 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_14_SEMC_ADDR05				0x04C 0x23C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_XBAR_INOUT19			0x04C 0x23C 0x654 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPUART3_RXD				0x04C 0x23C 0x538 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_MQS_LEFT				0x04C 0x23C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPSPI2_PCS1				0x04C 0x23C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_GPIO4_IO14				0x04C 0x23C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SEMC_ADDR06				0x050 0x240 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_XBAR_INOUT20			0x050 0x240 0x634 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_LPUART3_CTS_B			0x050 0x240 0x534 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SPDIF_OUT				0x050 0x240 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_TMR3_TIMER0				0x050 0x240 0x57C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_GPIO4_IO15				0x050 0x240 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SEMC_ADDR07				0x054 0x244 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_XBAR_INOUT21			0x054 0x244 0x658 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_LPUART3_RTS_B			0x054 0x244 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SPDIF_IN				0x054 0x244 0x5C8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_16_TMR3_TIMER1				0x054 0x244 0x580 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_GPIO4_IO16				0x054 0x244 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_17_SEMC_ADDR08				0x058 0x248 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXPWM4_PWM3_A			0x058 0x248 0x4A0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_LPUART4_CTS_B			0x058 0x248 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXCAN1_TX				0x058 0x248 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_TMR3_TIMER2				0x058 0x248 0x584 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_GPIO4_IO17				0x058 0x248 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SEMC_ADDR09				0x05C 0x24C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXPWM4_PWM3_B			0x05C 0x24C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_LPUART4_RTS_B			0x05C 0x24C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXCAN1_RX				0x05C 0x24C 0x44C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_18_TMR3_TIMER3				0x05C 0x24C 0x588 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_GPIO4_IO18				0x05C 0x24C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SNVS_VIO_5_CTL			0x05C 0x24C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SEMC_ADDR11				0x060 0x250 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_FLEXPWM2_PWM3_A			0x060 0x250 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_LPUART4_TXD				0x060 0x250 0x544 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_19_ENET_RX_DATA01			0x060 0x250 0x438 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_TMR2_TIMER0				0x060 0x250 0x56C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_GPIO4_IO19				0x060 0x250 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SNVS_VIO_5				0x060 0x250 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_20_SEMC_ADDR12				0x064 0x254 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_FLEXPWM2_PWM3_B			0x064 0x254 0x484 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_LPUART4_RXD				0x064 0x254 0x540 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_ENET_RX_DATA00			0x064 0x254 0x434 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_TMR2_TIMER0				0x064 0x254 0x570 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_GPIO4_IO20				0x064 0x254 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_21_SEMC_BA0				0x068 0x258 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_FLEXPWM3_PWM3_A			0x068 0x258 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_LPI2C3_SDA				0x068 0x258 0x4E0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_ENET_TX_DATA01			0x068 0x258 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_TMR2_TIMER2				0x068 0x258 0x574 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_GPIO4_IO21				0x068 0x258 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_22_SEMC_BA1				0x06C 0x25C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_FLEXPWM3_PWM3_B			0x06C 0x25C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_LPI2C3_SCL				0x06C 0x25C 0x4DC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_ENET_TX_DATA00			0x06C 0x25C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_TMR2_TIMER3				0x06C 0x25C 0x578 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_GPIO4_IO22				0x06C 0x25C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_23_SEMC_ADDR10				0x070 0x260 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_FLEXPWM1_PWM0_A			0x070 0x260 0x458 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_LPUART5_TXD				0x070 0x260 0x54C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_ENET_RX_EN				0x070 0x260 0x43C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPT1_CAPTURE2			0x070 0x260 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPIO4_IO23				0x070 0x260 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_24_SEMC_CAS				0x074 0x264 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_FLEXPWM1_PWM0_B			0x074 0x264 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_LPUART5_RXD				0x074 0x264 0x548 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_ENET_TX_EN				0x074 0x264 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPT1_CAPTURE1			0x074 0x264 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPIO4_IO24				0x074 0x264 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_25_SEMC_RAS				0x078 0x268 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_FLEXPWM1_PWM1_A			0x078 0x268 0x45C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_LPUART6_TXD				0x078 0x268 0x554 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_TX_CLK				0x078 0x268 0x448 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_REF_CLK			0x078 0x268 0x42C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_GPIO4_IO25				0x078 0x268 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_26_SEMC_CLK				0x07C 0x26C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXPWM1_PWM1_B			0x07C 0x26C 0x46C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_LPUART6_RXD				0x07C 0x26C 0x550 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_ENET_RX_ER				0x07C 0x26C 0x440 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXIO1_D12				0x07C 0x26C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_GPIO4_IO26				0x07C 0x26C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_27_SEMC_CKE				0x080 0x270 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXPWM1_PWM2_A			0x080 0x270 0x460 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPUART5_RTS_B			0x080 0x270 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPSPI1_SCK				0x080 0x270 0x4F0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXIO1_D13				0x080 0x270 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_GPIO4_IO27				0x080 0x270 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_28_SEMC_WE				0x084 0x274 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXPWM1_PWM2_B			0x084 0x274 0x470 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPUART5_CTS_B			0x084 0x274 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPSPI1_SDO				0x084 0x274 0x4F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXIO1_D14				0x084 0x274 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_GPIO4_IO28				0x084 0x274 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_29_SEMC_CS0				0x088 0x278 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXPWM3_PWM0_A			0x088 0x278 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPUART6_RTS_B			0x088 0x278 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPSPI1_SDI				0x088 0x278 0x4F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXIO1_D15				0x088 0x278 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_GPIO4_IO29				0x088 0x278 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_30_SEMC_DA08				0x08C 0x27C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_FLEXPWM3_PWM0_B			0x08C 0x27C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPUART6_CTS_B			0x08C 0x27C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPSPI1_PCS0				0x08C 0x27C 0x4EC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_30_CSI_DATA23				0x08C 0x27C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_GPIO4_IO30				0x08C 0x27C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_31_SEMC_DA09				0x090 0x280 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_FLEXPWM3_PWM1_A			0x090 0x280 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPUART7_TXD				0x090 0x280 0x55C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPSPI1_PCS1				0x090 0x280 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_CSI_DATA22				0x090 0x280 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_GPIO4_IO31				0x090 0x280 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_32_SEMC_DA10				0x094 0x284 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_FLEXPWM3_PWM1_B			0x094 0x284 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_LPUART7_RXD				0x094 0x284 0x558 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CCM_PMIC_READY			0x094 0x284 0x3FC 0x3 0x4
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CSI_DATA21				0x094 0x284 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_GPIO3_IO18				0x094 0x284 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SEMC_DA11				0x098 0x288 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_FLEXPWM3_PWM2_A			0x098 0x288 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_USDHC1_RESET_B			0x098 0x288 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SAI3_RX_DATA			0x098 0x288 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_CSI_DATA20				0x098 0x288 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_GPIO3_IO19				0x098 0x288 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SEMC_DA12				0x09C 0x28C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_FLEXPWM3_PWM2_B			0x09C 0x28C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_USDHC1_VSELECT			0x09C 0x28C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SAI3_RX_SYNC			0x09C 0x28C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_CSI_DATA19				0x09C 0x28C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_GPIO3_IO20				0x09C 0x28C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SEMC_DA13				0x0A0 0x290 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_XBAR_INOUT18			0x0A0 0x290 0x630 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPT1_COMPARE1			0x0A0 0x290 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SAI3_RX_BCLK			0x0A0 0x290 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_CSI_DATA18				0x0A0 0x290 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPIO3_IO21				0x0A0 0x290 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_USDHC1_CD_B				0x0A0 0x290 0x5D4 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SEMC_DA14				0x0A4 0x294 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_XBAR_INOUT22			0x0A4 0x294 0x638 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPT1_COMPARE2			0x0A4 0x294 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SAI3_TX_DATA			0x0A4 0x294 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_CSI_DATA17				0x0A4 0x294 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPIO3_IO22				0x0A4 0x294 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_USDHC1_WP				0x0A4 0x294 0x5D8 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SEMC_DA15				0x0A8 0x298 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_XBAR_INOUT23			0x0A8 0x298 0x63C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPT1_COMPARE3			0x0A8 0x298 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SAI3_MCLK				0x0A8 0x298 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_CSI_DATA16				0x0A8 0x298 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPIO3_IO23				0x0A8 0x298 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_USDHC2_WP				0x0A8 0x298 0x608 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SEMC_DM01				0x0AC 0x29C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_FLEXPWM1_PWM3_A			0x0AC 0x29C 0x454 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_LPUART8_TXD				0x0AC 0x29C 0x564 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SAI3_TX_BCLK			0x0AC 0x29C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_CSI_FIELD				0x0AC 0x29C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_GPIO3_IO24				0x0AC 0x29C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_USDHC2_VSELECT			0x0AC 0x29C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SEMC_DQS				0x0B0 0x2A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_FLEXPWM1_PWM3_B			0x0B0 0x2A0 0x464 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_LPUART8_RXD				0x0B0 0x2A0 0x560 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SAI3_TX_SYNC			0x0B0 0x2A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_WDOG1_B				0x0B0 0x2A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_GPIO3_IO25				0x0B0 0x2A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_USDHC2_CD_B				0x0B0 0x2A0 0x5E0 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_40_SEMC_RDY				0x0B4 0x2A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPT2_CAPTURE2			0x0B4 0x2A4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_LPSPI1_PCS2				0x0B4 0x2A4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USB_OTG2_OC				0x0B4 0x2A4 0x5CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_40_ENET_MDC				0x0B4 0x2A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPIO3_IO26				0x0B4 0x2A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USDHC2_RESET_B			0x0B4 0x2A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_41_SEMC_CSX0				0x0B8 0x2A8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPT2_CAPTURE1			0x0B8 0x2A8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_LPSPI1_PCS3				0x0B8 0x2A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USB_OTG2_PWR			0x0B8 0x2A8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_ENET_MDIO				0x0B8 0x2A8 0x430 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPIO3_IO27				0x0B8 0x2A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USDHC2_VSELECT			0x0B8 0x2A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_FLEXPWM2_PWM3_A			0x0BC 0x2AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_XBAR_INOUT14			0x0BC 0x2AC 0x644 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_REF_CLK_32K			0x0BC 0x2AC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USB_OTG2_ID			0x0BC 0x2AC 0x3F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPI2C1_SCLS			0x0BC 0x2AC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_GPIO1_IO00			0x0BC 0x2AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USDHC1_RESET_B			0x0BC 0x2AC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK			0x0BC 0x2AC 0x510 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_FLEXPWM2_PWM3_B			0x0C0 0x2B0 0x484 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_XBAR_INOUT15			0x0C0 0x2B0 0x648 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_REF_CLK_24M			0x0C0 0x2B0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_USB_OTG1_ID			0x0C0 0x2B0 0x3F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPI2C1_SDAS			0x0C0 0x2B0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_GPIO1_IO01			0x0C0 0x2B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_EWM_OUT_B				0x0C0 0x2B0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO			0x0C0 0x2B0 0x518 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXCAN2_TX			0x0C4 0x2B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_XBAR_INOUT16			0x0C4 0x2B4 0x64C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPUART6_TXD			0x0C4 0x2B4 0x554 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_USB_OTG1_PWR			0x0C4 0x2B4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXPWM1_PWM0_X			0x0C4 0x2B4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_GPIO1_IO02			0x0C4 0x2B4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPI2C1_HREQ			0x0C4 0x2B4 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI			0x0C4 0x2B4 0x514 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXCAN2_RX			0x0C8 0x2B8 0x450 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_XBAR_INOUT17			0x0C8 0x2B8 0x62C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPUART6_RXD			0x0C8 0x2B8 0x550 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_USB_OTG1_OC			0x0C8 0x2B8 0x5D0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXPWM1_PWM1_X			0x0C8 0x2B8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_GPIO1_IO03			0x0C8 0x2B8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_REF_CLK_24M			0x0C8 0x2B8 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0			0x0C8 0x2B8 0x50C 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SRC_BOOT_MODE00			0x0CC 0x2BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_MQS_RIGHT				0x0CC 0x2BC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_ENET_TX_DATA03			0x0CC 0x2BC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SAI2_TX_SYNC			0x0CC 0x2BC 0x5C4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_CSI_DATA09			0x0CC 0x2BC 0x41C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_GPIO1_IO04			0x0CC 0x2BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_PIT_TRIGGER00			0x0CC 0x2BC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_LPSPI3_PCS1			0x0CC 0x2BC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SRC_BOOT_MODE01			0x0D0 0x2C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_MQS_LEFT				0x0D0 0x2C0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_ENET_TX_DATA02			0x0D0 0x2C0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SAI2_TX_BCLK			0x0D0 0x2C0 0x5C0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_CSI_DATA08			0x0D0 0x2C0 0x418 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_GPIO1_IO05			0x0D0 0x2C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_XBAR_INOUT17			0x0D0 0x2C0 0x62C 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_LPSPI3_PCS2			0x0D0 0x2C0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_JTAG_TMS				0x0D4 0x2C4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPT2_COMPARE1			0x0D4 0x2C4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_ENET_RX_CLK			0x0D4 0x2C4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_SAI2_RX_BCLK			0x0D4 0x2C4 0x5B4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_CSI_DATA07			0x0D4 0x2C4 0x414 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPIO1_IO06			0x0D4 0x2C4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_XBAR_INOUT18			0x0D4 0x2C4 0x630 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_LPSPI3_PCS3			0x0D4 0x2C4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_JTAG_TCK				0x0D8 0x2C8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPT2_COMPARE2			0x0D8 0x2C8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_TX_ER			0x0D8 0x2C8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_SAI2_RX_SYNC			0x0D8 0x2C8 0x5BC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_CSI_DATA06			0x0D8 0x2C8 0x410 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPIO1_IO07			0x0D8 0x2C8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_XBAR_INOUT19			0x0D8 0x2C8 0x654 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_1588_EVENT3_OUT		0x0D8 0x2C8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_JTAG_MOD				0x0DC 0x2CC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPT2_COMPARE3			0x0DC 0x2CC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_RX_DATA03			0x0DC 0x2CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_SAI2_RX_DATA			0x0DC 0x2CC 0x5B8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_CSI_DATA05			0x0DC 0x2CC 0x40C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPIO1_IO08			0x0DC 0x2CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_XBAR_INOUT20			0x0DC 0x2CC 0x634 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_1588_EVENT3_IN		0x0DC 0x2CC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_JTAG_TDI				0x0E0 0x2D0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_FLEXPWM2_PWM3_A			0x0E0 0x2D0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_ENET_RX_DATA02			0x0E0 0x2D0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_SAI2_TX_DATA			0x0E0 0x2D0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_CSI_DATA04			0x0E0 0x2D0 0x408 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPIO1_IO09			0x0E0 0x2D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_XBAR_INOUT21			0x0E0 0x2D0 0x658 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPT2_CLK				0x0E0 0x2D0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_JTAG_TDO				0x0E4 0x2D4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWM3_A			0x0E4 0x2D4 0x454 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_CRS				0x0E4 0x2D4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_SAI2_MCLK				0x0E4 0x2D4 0x5B0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_CSI_DATA03			0x0E4 0x2D4 0x404 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_GPIO1_IO10			0x0E4 0x2D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_XBAR_INOUT22			0x0E4 0x2D4 0x638 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_1588_EVENT0_OUT		0x0E4 0x2D4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_JTAG_TRSTB			0x0E8 0x2D8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_FLEXPWM1_PWM3_B			0x0E8 0x2D8 0x464 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_COL				0x0E8 0x2D8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_WDOG1_B				0x0E8 0x2D8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_CSI_DATA02			0x0E8 0x2D8 0x400 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_GPIO1_IO11			0x0E8 0x2D8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_XBAR_INOUT23			0x0E8 0x2D8 0x63C 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_1588_EVENT0_IN		0x0E8 0x2D8 0x444 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL			0x0EC 0x2DC 0x4E4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_CCM_PMIC_READY			0x0EC 0x2DC 0x3FC 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD			0x0EC 0x2DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_WDOG2_B				0x0EC 0x2DC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_FLEXPWM1_PWM2_X			0x0EC 0x2DC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_GPIO1_IO12			0x0EC 0x2DC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_ENET_1588_EVENT1_OUT		0x0EC 0x2DC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_NMI				0x0EC 0x2DC 0x568 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA			0x0F0 0x2E0 0x4E8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPT1_CLK				0x0F0 0x2E0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD			0x0F0 0x2E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_EWM_OUT_B				0x0F0 0x2E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_FLEXPWM1_PWM3_X			0x0F0 0x2E0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPIO1_IO13			0x0F0 0x2E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_ENET_1588_EVENT1_IN		0x0F0 0x2E0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_REF_CLK_24M			0x0F0 0x2E0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_USB_OTG2_OC			0x0F4 0x2E4 0x5CC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_XBAR_INOUT24			0x0F4 0x2E4 0x640 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_LPUART1_CTS_B			0x0F4 0x2E4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_ENET_1588_EVENT0_OUT		0x0F4 0x2E4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_CSI_VSYNC				0x0F4 0x2E4 0x428 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_GPIO1_IO14			0x0F4 0x2E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX			0x0F4 0x2E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_USB_OTG2_PWR			0x0F8 0x2E8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_XBAR_INOUT25			0x0F8 0x2E8 0x650 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_LPUART1_RTS_B			0x0F8 0x2E8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_ENET_1588_EVENT0_IN		0x0F8 0x2E8 0x444 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_CSI_HSYNC				0x0F8 0x2E8 0x420 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_GPIO1_IO15			0x0F8 0x2E8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX			0x0F8 0x2E8 0x450 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_WDOG1_WDOG_RST_B_DEB		0x0F8 0x2E8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USB_OTG2_ID			0x0FC 0x2EC 0x3F8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_TMR3_TIMER0			0x0FC 0x2EC 0x57C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPUART2_CTS_B			0x0FC 0x2EC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL			0x0FC 0x2EC 0x4CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_WDOG1_B				0x0FC 0x2EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_GPIO1_IO16			0x0FC 0x2EC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USDHC1_WP				0x0FC 0x2EC 0x5D8 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_KPP_ROW07				0x0FC 0x2EC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USB_OTG1_PWR			0x100 0x2F0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_TMR3_TIMER1			0x100 0x2F0 0x580 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPUART2_RTS_B			0x100 0x2F0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA			0x100 0x2F0 0x4D0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_CCM_PMIC_READY			0x100 0x2F0 0x3FC 0x4 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_GPIO1_IO17			0x100 0x2F0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USDHC1_VSELECT			0x100 0x2F0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_KPP_COL07				0x100 0x2F0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USB_OTG1_ID			0x104 0x2F4 0x3F4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_TMR3_TIMER2			0x104 0x2F4 0x584 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_LPUART2_TXD			0x104 0x2F4 0x530 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_SPDIF_OUT				0x104 0x2F4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_ENET_1588_EVENT2_OUT		0x104 0x2F4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_GPIO1_IO18			0x104 0x2F4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USDHC1_CD_B			0x104 0x2F4 0x5D4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_KPP_ROW06				0x104 0x2F4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USB_OTG1_OC			0x108 0x2F8 0x5D0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_TMR3_TIMER3			0x108 0x2F8 0x588 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_LPUART2_RXD			0x108 0x2F8 0x52C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_SPDIF_IN				0x108 0x2F8 0x5C8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_ENET_1588_EVENT2_IN		0x108 0x2F8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_GPIO1_IO19			0x108 0x2F8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USDHC2_CD_B			0x108 0x2F8 0x5E0 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_KPP_COL06				0x108 0x2F8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_FLEXSPI_B_DATA3			0x10C 0x2FC 0x4C4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_ENET_MDC				0x10C 0x2FC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_LPUART3_CTS_B			0x10C 0x2FC 0x534 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_SPDIF_SR_CLK			0x10C 0x2FC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK			0x10C 0x2FC 0x424 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_GPIO1_IO20			0x10C 0x2FC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_USDHC2_DATA0			0x10C 0x2FC 0x5E8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_KPP_ROW05				0x10C 0x2FC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_FLEXSPI_B_DATA2			0x110 0x300 0x4C0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_ENET_MDIO				0x110 0x300 0x430 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_LPUART3_RTS_B			0x110 0x300 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_SPDIF_OUT				0x110 0x300 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_CSI_MCLK				0x110 0x300 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_GPIO1_IO21			0x110 0x300 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_USDHC2_DATA1			0x110 0x300 0x5EC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_KPP_COL05				0x110 0x300 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_FLEXSPI_B_DATA1			0x114 0x304 0x4BC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA			0x114 0x304 0x4E0 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPUART3_TXD			0x114 0x304 0x53C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_SPDIF_LOCK			0x114 0x304 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_CSI_VSYNC				0x114 0x304 0x428 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_GPIO1_IO22			0x114 0x304 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_USDHC2_DATA2			0x114 0x304 0x5F0 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_KPP_ROW04				0x114 0x304 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_FLEXSPI_B_DATA0			0x118 0x308 0x4B8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL			0x118 0x308 0x4DC 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPUART3_RXD			0x118 0x308 0x538 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_SPDIF_EXT_CLK			0x118 0x308 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_CSI_HSYNC				0x118 0x308 0x420 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_GPIO1_IO23			0x118 0x308 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_USDHC2_DATA3			0x118 0x308 0x5F4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_KPP_COL04				0x118 0x308 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXSPI_A_SS1_B			0x11C 0x30C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXPWM4_PWM0_A			0x11C 0x30C 0x494 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX			0x11C 0x30C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CCM_PMIC_READY			0x11C 0x30C 0x3FC 0x3 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CSI_DATA09			0x11C 0x30C 0x41C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_GPIO1_IO24			0x11C 0x30C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_USDHC2_CMD			0x11C 0x30C 0x5E4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_KPP_ROW03				0x11C 0x30C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXSPI_A_DQS			0x120 0x310 0x4A4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXPWM4_PWM1_A			0x120 0x310 0x498 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX			0x120 0x310 0x44C 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_SAI1_MCLK				0x120 0x310 0x58C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_CSI_DATA08			0x120 0x310 0x418 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_GPIO1_IO25			0x120 0x310 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_USDHC2_CLK			0x120 0x310 0x5DC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_KPP_COL03				0x120 0x310 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_FLEXSPI_A_DATA3			0x124 0x314 0x4B4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_WDOG1_B				0x124 0x314 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_LPUART8_TXD			0x124 0x314 0x564 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_SAI1_RX_SYNC			0x124 0x314 0x5A4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_CSI_DATA07			0x124 0x314 0x414 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_GPIO1_IO26			0x124 0x314 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_USDHC2_WP				0x124 0x314 0x608 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_KPP_ROW02				0x124 0x314 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_FLEXSPI_A_DATA2			0x128 0x318 0x4B0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_EWM_OUT_B				0x128 0x318 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_LPUART8_RXD			0x128 0x318 0x560 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_SAI1_RX_BCLK			0x128 0x318 0x590 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_CSI_DATA06			0x128 0x318 0x410 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_GPIO1_IO27			0x128 0x318 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_USDHC2_RESET_B			0x128 0x318 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_KPP_COL02				0x128 0x318 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_FLEXSPI_A_DATA1			0x12C 0x31C 0x4AC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_ACMP1_OUT				0x12C 0x31C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0			0x12C 0x31C 0x50C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00			0x12C 0x31C 0x594 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_CSI_DATA05			0x12C 0x31C 0x40C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_GPIO1_IO28			0x12C 0x31C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_USDHC2_DATA4			0x12C 0x31C 0x5F8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_KPP_ROW01				0x12C 0x31C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_FLEXSPI_A_DATA0			0x130 0x320 0x4A8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_ACMP2_OUT				0x130 0x320 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI			0x130 0x320 0x514 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00			0x130 0x320 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_CSI_DATA04			0x130 0x320 0x408 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_GPIO1_IO29			0x130 0x320 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_USDHC2_DATA5			0x130 0x320 0x5FC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_KPP_COL01				0x130 0x320 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_FLEXSPI_A_SCLK			0x134 0x324 0x4C8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_ACMP3_OUT				0x134 0x324 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO			0x134 0x324 0x518 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK			0x134 0x324 0x5A8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_CSI_DATA03			0x134 0x324 0x404 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_GPIO1_IO30			0x134 0x324 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_USDHC2_DATA6			0x134 0x324 0x600 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_KPP_ROW00				0x134 0x324 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_FLEXSPI_A_SS0_B			0x138 0x328 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_ACMP4_OUT				0x138 0x328 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK			0x138 0x328 0x510 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC			0x138 0x328 0x5AC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_CSI_DATA02			0x138 0x328 0x400 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_GPIO1_IO31			0x138 0x328 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_USDHC2_DATA7			0x138 0x328 0x604 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_KPP_COL00				0x138 0x328 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_00_LCD_CLK				0x13C 0x32C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_TMR1_TIMER0				0x13C 0x32C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_MQS_RIGHT				0x13C 0x32C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_LPSPI4_PCS0				0x13C 0x32C 0x51C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_FLEXIO2_D00				0x13C 0x32C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_GPIO2_IO00				0x13C 0x32C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_SEMC_CSX1				0x13C 0x32C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_01_LCD_ENABLE				0x140 0x330 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_TMR1_TIMER1				0x140 0x330 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_MQS_LEFT				0x140 0x330 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_LPSPI4_SDI				0x140 0x330 0x524 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_FLEXIO2_D01				0x140 0x330 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_GPIO2_IO01				0x140 0x330 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_SEMC_CSX2				0x140 0x330 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_02_LCD_HSYNC				0x144 0x334 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_TMR1_TIMER2				0x144 0x334 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXCAN1_TX				0x144 0x334 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_LPSPI4_SDO				0x144 0x334 0x528 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXIO2_D02				0x144 0x334 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_GPIO2_IO02				0x144 0x334 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_SEMC_CSX3				0x144 0x334 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_03_LCD_VSYNC				0x148 0x338 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_TMR2_TIMER0				0x148 0x338 0x56C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXCAN1_RX				0x148 0x338 0x44C 0x2 0x3
+#define MXRT1050_IOMUXC_GPIO_B0_03_LPSPI4_SCK				0x148 0x338 0x520 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXIO2_D03				0x148 0x338 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_GPIO2_IO03				0x148 0x338 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_WDOG2_RESET_B_DEB			0x148 0x338 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_04_LCD_DATA00				0x14C 0x33C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_TMR2_TIMER1				0x14C 0x33C 0x570 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_LPI2C2_SCL				0x14C 0x33C 0x4D4 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_ARM_TRACE00				0x14C 0x33C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_FLEXIO2_D04				0x14C 0x33C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_GPIO2_IO04				0x14C 0x33C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_SRC_BT_CFG00				0x14C 0x33C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_05_LCD_DATA01				0x150 0x340 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_TMR2_TIMER2				0x150 0x340 0x574 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_LPI2C2_SDA				0x150 0x340 0x4D8 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_ARM_TRACE01				0x150 0x340 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_FLEXIO2_D05				0x150 0x340 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_GPIO2_IO05				0x150 0x340 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_SRC_BT_CFG01				0x150 0x340 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_06_LCD_DATA02				0x154 0x344 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_TMR3_TIMER0				0x154 0x344 0x57C 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXPWM2_PWM0_A			0x154 0x344 0x478 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_06_ARM_TRACE02				0x154 0x344 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXIO2_D06				0x154 0x344 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_GPIO2_IO06				0x154 0x344 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_SRC_BT_CFG02				0x154 0x344 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_07_LCD_DATA03				0x158 0x348 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_TMR3_TIMER1				0x158 0x348 0x580 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXPWM2_PWM0_B			0x158 0x348 0x488 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_07_ARM_TRACE03				0x158 0x348 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXIO2_D07				0x158 0x348 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_GPIO2_IO07				0x158 0x348 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_SRC_BT_CFG03				0x158 0x348 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_08_LCD_DATA04				0x15C 0x34C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_TMR3_TIMER2				0x15C 0x34C 0x584 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXPWM2_PWM1_A			0x15C 0x34C 0x47C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_08_LPUART3_TXD				0x15C 0x34C 0x53C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXIO2_D08				0x15C 0x34C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_GPIO2_IO08				0x15C 0x34C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_SRC_BT_CFG04				0x15C 0x34C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_09_LCD_DATA05				0x160 0x350 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_TMR4_TIMER0				0x160 0x350 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXPWM2_PWM1_B			0x160 0x350 0x48C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_09_LPUART3_RXD				0x160 0x350 0x538 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXIO2_D09				0x160 0x350 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_GPIO2_IO09				0x160 0x350 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_SRC_BT_CFG05				0x160 0x350 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_10_LCD_DATA06				0x164 0x354 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_TMR4_TIMER1				0x164 0x354 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXPWM2_PWM2_A			0x164 0x354 0x480 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_SAI1_TX_DATA03			0x164 0x354 0x598 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXIO2_D10				0x164 0x354 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_GPIO2_IO10				0x164 0x354 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_SRC_BT_CFG06				0x164 0x354 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_11_LCD_DATA07				0x168 0x358 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_TMR4_TIMER2				0x168 0x358 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXPWM2_PWM2_B			0x168 0x358 0x490 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_SAI1_TX_DATA02			0x168 0x358 0x59C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXIO2_D11				0x168 0x358 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_GPIO2_IO11				0x168 0x358 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_SRC_BT_CFG07				0x168 0x358 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_12_LCD_DATA08				0x16C 0x35C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_XBAR_INOUT10				0x16C 0x35C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_ARM_TRACE_CLK			0x16C 0x35C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SAI1_TX_DATA01			0x16C 0x35C 0x5A0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_12_FLEXIO2_D12				0x16C 0x35C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_GPIO2_IO12				0x16C 0x35C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SRC_BT_CFG08				0x16C 0x35C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_13_LCD_DATA09				0x170 0x360 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_XBAR_INOUT11				0x170 0x360 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_ARM_TRACE_SWO			0x170 0x360 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SAI1_MCLK				0x170 0x360 0x58C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_13_FLEXIO2_D13				0x170 0x360 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_GPIO2_IO13				0x170 0x360 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SRC_BT_CFG09				0x170 0x360 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_14_LCD_DATA10				0x174 0x364 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_XBAR_INOUT12				0x174 0x364 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_ARM_CM7_TXEV				0x174 0x364 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SAI1_RX_SYNC				0x174 0x364 0x5A4 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_14_FLEXIO2_D14				0x174 0x364 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_GPIO2_IO14				0x174 0x364 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SRC_BT_CFG10				0x174 0x364 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_15_LCD_DATA11				0x178 0x368 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_XBAR_INOUT13				0x178 0x368 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_ARM_CM7_RXEV				0x178 0x368 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SAI1_RX_BCLK				0x178 0x368 0x590 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_15_FLEXIO2_D15				0x178 0x368 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_GPIO2_IO15				0x178 0x368 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SRC_BT_CFG11				0x178 0x368 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_00_LCD_DATA12				0x17C 0x36C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_XBAR_INOUT14				0x17C 0x36C 0x644 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_00_LPUART4_TXD				0x17C 0x36C 0x544 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_SAI1_RX_DATA00			0x17C 0x36C 0x594 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXIO2_D16				0x17C 0x36C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_GPIO2_IO16				0x17C 0x36C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXPWM1_PWM3_A			0x17C 0x36C 0x454 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_01_LCD_DATA13				0x180 0x370 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_XBAR_INOUT15				0x180 0x370 0x648 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_01_LPUART4_RXD				0x180 0x370 0x540 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_01_SAI1_TX_DATA00			0x180 0x370 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXIO2_D17				0x180 0x370 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_GPIO2_IO17				0x180 0x370 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXPWM1_PWM3_B			0x180 0x370 0x464 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_02_LCD_DATA14				0x184 0x374 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_XBAR_INOUT16				0x184 0x374 0x64C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_02_LPSPI4_PCS2				0x184 0x374 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_SAI1_TX_BCLK				0x184 0x374 0x5A8 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXIO2_D18				0x184 0x374 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_GPIO2_IO18				0x184 0x374 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXPWM2_PWM3_A			0x184 0x374 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_03_LCD_DATA15				0x188 0x378 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_XBAR_INOUT17				0x188 0x378 0x62C 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_B1_03_LPSPI4_PCS1				0x188 0x378 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_SAI1_TX_SYNC				0x188 0x378 0x5AC 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXIO2_D19				0x188 0x378 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_GPIO2_IO19				0x188 0x378 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXPWM2_PWM3_B			0x188 0x378 0x484 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_04_LCD_DATA16				0x18C 0x37C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_LPSPI4_PCS0				0x18C 0x37C 0x51C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_CSI_DATA15				0x18C 0x37C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_ENET_RX_DATA00			0x18C 0x37C 0x434 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_FLEXIO2_D20				0x18C 0x37C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_GPIO2_IO20				0x18C 0x37C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_05_LCD_DATA17				0x190 0x380 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_LPSPI4_SDI				0x190 0x380 0x524 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_CSI_DATA14				0x190 0x380 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_ENET_RX_DATA01			0x190 0x380 0x438 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_FLEXIO2_D21				0x190 0x380 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_GPIO2_IO21				0x190 0x380 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_06_LCD_DATA18				0x194 0x384 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_LPSPI4_SDO				0x194 0x384 0x528 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_CSI_DATA13				0x194 0x384 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_ENET_RX_EN				0x194 0x384 0x43C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_FLEXIO2_D22				0x194 0x384 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_GPIO2_IO22				0x194 0x384 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_07_LCD_DATA19				0x198 0x388 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_LPSPI4_SCK				0x198 0x388 0x520 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_07_CSI_DATA12				0x198 0x388 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_ENET_TX_DATA00			0x198 0x388 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_FLEXIO2_D23				0x198 0x388 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_GPIO2_IO23				0x198 0x388 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_08_LCD_DATA20				0x19C 0x38C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_TMR1_TIMER3				0x19C 0x38C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_CSI_DATA11				0x19C 0x38C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_ENET_TX_DATA01			0x19C 0x38C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXIO2_D24				0x19C 0x38C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_GPIO2_IO24				0x19C 0x38C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXCAN2_TX				0x19C 0x38C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_09_LCD_DATA21				0x1A0 0x390 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_TMR2_TIMER3				0x1A0 0x390 0x578 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_09_CSI_DATA10				0x1A0 0x390 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_ENET_TX_EN				0x1A0 0x390 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXIO2_D25				0x1A0 0x390 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_GPIO2_IO25				0x1A0 0x390 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXCAN2_RX				0x1A0 0x390 0x450 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_10_LCD_DATA22				0x1A4 0x394 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_TMR3_TIMER3				0x1A4 0x394 0x588 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_10_CSI_DATA00				0x1A4 0x394 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_TX_CLK				0x1A4 0x394 0x448 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_10_FLEXIO2_D26				0x1A4 0x394 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_GPIO2_IO26				0x1A4 0x394 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_REF_CLK				0x1A4 0x394 0x42C 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_B1_11_LCD_DATA23				0x1A8 0x398 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_TMR4_TIMER3				0x1A8 0x398 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_CSI_DATA01				0x1A8 0x398 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_ENET_RX_ER				0x1A8 0x398 0x440 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_11_FLEXIO2_D27				0x1A8 0x398 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_GPIO2_IO27				0x1A8 0x398 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_LPSPI4_PCS3				0x1A8 0x398 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_12_LPUART5_TXD				0x1AC 0x39C 0x54C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_CSI_PIXCLK				0x1AC 0x39C 0x424 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_ENET_1588_EVENT0_IN			0x1AC 0x39C 0x444 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_12_FLEXIO2_D28				0x1AC 0x39C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_GPIO2_IO28				0x1AC 0x39C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B				0x1AC 0x39C 0x5D4 0x6 0x2
+
+#define MXRT1050_IOMUXC_GPIO_B1_13_WDOG1_B				0x1B0 0x3A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_LPUART5_RXD				0x1B0 0x3A0 0x548 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_13_CSI_VSYNC				0x1B0 0x3A0 0x428 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_13_ENET_1588_EVENT0_OUT			0x1B0 0x3A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_FLEXIO2_D29				0x1B0 0x3A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_GPIO2_IO29				0x1B0 0x3A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_USDHC1_WP				0x1B0 0x3A0 0x5D8 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_14_ENET_MDC				0x1B4 0x3A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXPWM4_PWM2_A			0x1B4 0x3A4 0x49C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_CSI_HSYNC				0x1B4 0x3A4 0x420 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_14_XBAR_INOUT02				0x1B4 0x3A4 0x60C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXIO2_D30				0x1B4 0x3A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_GPIO2_IO30				0x1B4 0x3A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT			0x1B4 0x3A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_15_ENET_MDIO				0x1B8 0x3A8 0x430 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXPWM4_PWM3_A			0x1B8 0x3A8 0x4A0 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_CSI_MCLK				0x1B8 0x3A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_XBAR_INOUT03				0x1B8 0x3A8 0x610 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXIO2_D31				0x1B8 0x3A8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_GPIO2_IO31				0x1B8 0x3A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_USDHC1_RESET_B			0x1B8 0x3A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD			0x1BC 0x3AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXPWM1_PWM0_A			0x1BC 0x3AC 0x458 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPI2C3_SCL			0x1BC 0x3AC 0x4DC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_XBAR_INOUT04			0x1BC 0x3AC 0x614 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK			0x1BC 0x3AC 0x4F0 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_GPIO3_IO12			0x1BC 0x3AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXSPI_A_SS1_B			0x1BC 0x3AC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK			0x1C0 0x3B0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXPWM1_PWM0_B			0x1C0 0x3B0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPI2C3_SDA			0x1C0 0x3B0 0x4E0 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_XBAR_INOUT05			0x1C0 0x3B0 0x618 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0			0x1C0 0x3B0 0x4EC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_GPIO3_IO13			0x1C0 0x3B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXSPI_B_SS1_B			0x1C0 0x3B0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0			0x1C4 0x3B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_FLEXPWM1_PWM1_A			0x1C4 0x3B4 0x45C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPUART8_CTS_B			0x1C4 0x3B4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_XBAR_INOUT06			0x1C4 0x3B4 0x61C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO			0x1C4 0x3B4 0x4F8 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_GPIO3_IO14			0x1C4 0x3B4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1			0x1C8 0x3B8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_FLEXPWM1_PWM1_B			0x1C8 0x3B8 0x46C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPUART8_RTS_B			0x1C8 0x3B8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_XBAR_INOUT07			0x1C8 0x3B8 0x620 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI			0x1C8 0x3B8 0x4F4 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_GPIO3_IO15			0x1C8 0x3B8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2			0x1CC 0x3BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXPWM1_PWM2_A			0x1CC 0x3BC 0x460 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_LPUART8_TXD			0x1CC 0x3BC 0x564 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_XBAR_INOUT08			0x1CC 0x3BC 0x624 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXSPI_B_SS0_B			0x1CC 0x3BC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_GPIO3_IO16			0x1CC 0x3BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_CCM_CLKO1				0x1CC 0x3BC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3			0x1D0 0x3C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXPWM1_PWM2_B			0x1D0 0x3C0 0x470 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_LPUART8_RXD			0x1D0 0x3C0 0x560 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_XBAR_INOUT09			0x1D0 0x3C0 0x628 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXSPI_B_DQS			0x1D0 0x3C0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_GPIO3_IO17			0x1D0 0x3C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_CCM_CLKO2				0x1D0 0x3C0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3			0x1D4 0x3C4 0x5F4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3			0x1D4 0x3C4 0x4C4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXPWM1_PWM3_A			0x1D4 0x3C4 0x454 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_SAI1_TX_DATA03			0x1D4 0x3C4 0x598 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_LPUART4_TXD			0x1D4 0x3C4 0x544 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_GPIO3_IO00			0x1D4 0x3C4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2			0x1D8 0x3C8 0x5F0 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2			0x1D8 0x3C8 0x4C0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXPWM1_PWM3_B			0x1D8 0x3C8 0x464 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_SAI1_TX_DATA02			0x1D8 0x3C8 0x59C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_LPUART4_RXD			0x1D8 0x3C8 0x540 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_GPIO3_IO01			0x1D8 0x3C8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1			0x1DC 0x3CC 0x5EC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1			0x1DC 0x3CC 0x4BC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWM3_A			0x1DC 0x3CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_SAI1_TX_DATA01			0x1DC 0x3CC 0x5A0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXCAN1_TX			0x1DC 0x3CC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_GPIO3_IO02			0x1DC 0x3CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_CCM_WAIT				0x1DC 0x3CC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0			0x1E0 0x3D0 0x5E8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0			0x1E0 0x3D0 0x4B8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWM3_B			0x1E0 0x3D0 0x484 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_SAI1_MCLK				0x1E0 0x3D0 0x58C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXCAN1_RX			0x1E0 0x3D0 0x44C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_GPIO3_IO03			0x1E0 0x3D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_CCM_PMIC_READY			0x1E0 0x3D0 0x3FC 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_USDHC2_CLK			0x1E4 0x3D4 0x5DC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK			0x1E4 0x3D4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_LPI2C1_SCL			0x1E4 0x3D4 0x4CC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_SAI1_RX_SYNC			0x1E4 0x3D4 0x5A4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXCAN1_A_SS1_B			0x1E4 0x3D4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_GPIO3_IO04			0x1E4 0x3D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_CCM_STOP				0x1E4 0x3D4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_USDHC2_CMD			0x1E8 0x3D8 0x5E4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS			0x1E8 0x3D8 0x4A4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_LPI2C1_SDA			0x1E8 0x3D8 0x4D0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_SAI1_RX_BCLK			0x1E8 0x3D8 0x590 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXCAN1_B_SS0_B			0x1E8 0x3D8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_GPIO3_IO05			0x1E8 0x3D8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_USDHC2_RESET_B			0x1EC 0x3DC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B			0x1EC 0x3DC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPUART7_CTS_B			0x1EC 0x3DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_SAI1_RX_DATA00			0x1EC 0x3DC 0x594 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPSPI2_PCS0			0x1EC 0x3DC 0x4FC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_GPIO3_IO06			0x1EC 0x3DC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SEMC_CSX1				0x1F0 0x3E0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK			0x1F0 0x3E0 0x4C8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPUART7_RTS_B			0x1F0 0x3E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SAI1_TX_DATA00			0x1F0 0x3E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK			0x1F0 0x3E0 0x500 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_GPIO3_IO07			0x1F0 0x3E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_CCM_REF_EN_B			0x1F0 0x3E0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4			0x1F4 0x3E4 0x5F8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA0			0x1F4 0x3E4 0x4A8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPUART7_TXD			0x1F4 0x3E4 0x55C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SAI1_TX_BLCK			0x1F4 0x3E4 0x5A8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPSPI2_SDO			0x1F4 0x3E4 0x508 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_GPIO3_IO08			0x1F4 0x3E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SEMC_CSX2				0x1F4 0x3E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5			0x1F8 0x3E8 0x5FC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1			0x1F8 0x3E8 0x4AC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPUART7_RXD			0x1F8 0x3E8 0x558 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_SAI1_TX_SYNC			0x1F8 0x3E8 0x5AC 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI			0x1F8 0x3E8 0x504 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_GPIO3_IO09			0x1F8 0x3E8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6			0x1FC 0x3EC 0x600 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2			0x1FC 0x3EC 0x4B0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPUART2_RXD			0x1FC 0x3EC 0x52C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPI2C2_SDA			0x1FC 0x3EC 0x4D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPSPI2_PCS2			0x1FC 0x3EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_GPIO3_IO10			0x1FC 0x3EC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7			0x200 0x3F0 0x604 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3			0x200 0x3F0 0x4B4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPUART2_TXD			0x200 0x3F0 0x530 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPI2C2_SCL			0x200 0x3F0 0x4D4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPSPI2_PCS3			0x200 0x3F0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_GPIO3_IO11			0x200 0x3F0 0x000 0x5 0x0
+
+#endif /* _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:04 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:04 -0500
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-6-Mr.Bossman075@gmail.com>

Add clock driver support for i.MXRT1050.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
---
V1->V2:
* Kconfig: Add new line
* clk-imxrt.c: Remove unused const
* clk-imxrt.c: Remove set parents
* clk-imxrt.c: Use fsl,imxrt-anatop for anatop base address
V2->V3:
* Remove unused ANATOP_BASE_ADDR
* Move to hw API
* Add GPT's own clock
* Add SEMC clocks to set muxing to CRITICAL
V3->V4:
* Rename clk-imxrt.c to clk-imxrt1050.c
* Rename CONFIG_CLK_IMXRT to CONFIG_CLK_IMXRT1050
* Make CONFIG_CLK_IMXRT1050 selectable
V4->V5:
* Move to platform driver
V5->V6:
* Remove "fsl" from platform driver name
V6->V7:
* Remove GPT
* Remove of_match_ptr
V7->V8:
* Add help message
* Change to config to tristate
* Fix Makefile ordering
* Remove unused inlcude
* Remove imxrt_clocks_common_init
---
 drivers/clk/imx/Kconfig         |   7 ++
 drivers/clk/imx/Makefile        |   1 +
 drivers/clk/imx/clk-imxrt1050.c | 168 ++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index c08edbd04d22..45641b8bdc50 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -105,3 +105,10 @@ config CLK_IMX8ULP
 	select MXC_CLK
 	help
 	    Build the driver for i.MX8ULP CCM Clock Driver
+
+config CLK_IMXRT1050
+	tristate "IMXRT1050 CCM Clock Driver"
+	depends on SOC_IMXRT
+	select MXC_CLK
+	help
+	    Build the driver for i.MXRT1050 CCM Clock Driver
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index b5e040026dfb..1e13c5cb37d9 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -46,4 +46,5 @@ obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o
 obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
 obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
 obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
+obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o
 obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
new file mode 100644
index 000000000000..9539d35588ee
--- /dev/null
+++ b/drivers/clk/imx/clk-imxrt1050.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2021
+ * Author(s):
+ * Jesse Taube <Mr.Bossman075 at gmail.com>
+ * Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+
+#include "clk.h"
+
+static const char * const pll_ref_sels[] = {"osc", "dummy", };
+static const char * const per_sels[] = {"ipg_pdof", "osc", };
+static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
+static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
+static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
+static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
+static const char *const pre_periph_sels[] = {
+	"pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
+static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
+static const char *const lcdif_sels[] = {
+	"pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
+	"pll2_pfd1_594m", "pll3_pfd1_664_62m", };
+static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
+static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
+
+static struct clk_hw **hws;
+static struct clk_hw_onecell_data *clk_hw_data;
+
+static int imxrt1050_clocks_probe(struct platform_device *pdev)
+{
+	void __iomem *ccm_base;
+	void __iomem *pll_base;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *anp;
+	int ret;
+
+	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+					  IMXRT1050_CLK_END), GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMXRT1050_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMXRT1050_CLK_OSC] = imx_obtain_fixed_clk_hw(np, "osc");
+
+	anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
+	pll_base = of_iomap(anp, 0);
+	of_node_put(anp);
+	if (WARN_ON(!pll_base))
+		return -ENOMEM;
+
+	/* Anatop clocks */
+	hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
+
+	hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
+		pll_base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
+		pll_base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
+		pll_base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
+		pll_base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
+		"pll1_arm_ref_sel", pll_base + 0x0, 0x7f);
+	hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
+		"pll2_sys_ref_sel", pll_base + 0x30, 0x1);
+	hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
+		"pll3_usb_otg_ref_sel", pll_base + 0x10, 0x1);
+	hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
+		"pll5_video_ref_sel", pll_base + 0xa0, 0x7f);
+
+	/* PLL bypass out */
+	hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", pll_base + 0x0, 16, 1,
+		pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", pll_base + 0x30, 16, 1,
+		pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", pll_base + 0x10, 16, 1,
+		pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", pll_base + 0xa0, 16, 1,
+		pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+
+	hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
+		"pll5_video", pll_base + 0xa0, 19, 2);
+	hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
+		"video_post_div_sel", pll_base + 0x170, 30, 2);
+
+	hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
+
+	hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", pll_base + 0x100, 0);
+	hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", pll_base + 0x100, 1);
+	hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", pll_base + 0x100, 2);
+	hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", pll_base + 0xf0, 1);
+	hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", pll_base + 0xf0, 3);
+
+	/* CCM clocks */
+	ccm_base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(ccm_base)))
+		return PTR_ERR(ccm_base);
+
+	hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
+	hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
+		pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+	hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
+		periph_sels, ARRAY_SIZE(periph_sels));
+	hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
+		lpuart_sels, ARRAY_SIZE(lpuart_sels));
+	hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
+		lcdif_sels, ARRAY_SIZE(lcdif_sels));
+	hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
+		per_sels, ARRAY_SIZE(per_sels));
+	hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
+		semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
+	hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
+		semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
+
+	hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
+	hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
+	hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
+
+	hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
+	hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
+	hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
+	hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
+	hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
+
+	hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
+	hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
+	hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
+	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
+	hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
+	hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
+	imx_check_clk_hws(hws, IMXRT1050_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
+		imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
+	}
+	return ret;
+}
+static const struct of_device_id imxrt1050_clk_of_match[] = {
+	{ .compatible = "fsl,imxrt1050-ccm" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
+
+static struct platform_driver imxrt1050_clk_driver = {
+	.probe = imxrt1050_clocks_probe,
+	.driver = {
+		.name = "imxrt1050-ccm",
+		.of_match_table = imxrt1050_clk_of_match,
+	},
+};
+module_platform_driver(imxrt1050_clk_driver);
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:05 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:05 -0500
Subject: [PATCH v7 6/7] ARM: dts: imx: Add i.MXRT1050-EVK support
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-7-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The NXP i.MXRT1050 Evaluation Kit (EVK) provides a platform for rapid
evaluation of the i.MXRT, which features NXP's implementation of the Arm
Cortex-M7 core.

The EVK provides 32 MB SDRAM, 64 MB Quad SPI flash, Micro SD card socket,
USB 2.0 OTG.

This patch aims to support the preliminary booting up features
as follows:
GPIO
LPUART
SD/MMC

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: Add clock-parents, edma, usdhc, anatop, remove old pinctl]
---
V1->V2:
* dtsi: Add clock parent definitions
* dtsi: Change hex values to lowercase
* dtsi: Move anatop definition from driver
* dts: Remove unused pin controll (semc)
* dts: Use moved pin controll header
* Move aliases from dtsi to dts
* Change commit description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Remove bootargs, comments, unused container
* Remove unnecessary new lines
* Rename imxrt to imxrt1050 for seiral and mmc
* GPT uses own clock
* fix memory at 0
* Change GPT compatible handles
V3->V4:
* Remove "fsl,imx-osc"
* Add space on serial compatible
* Change "iomuxc@" to "pinctrl@"
* Change "ccm@" to "clock-controller@"
* Change "fsl,imxrt-gpio" to "fsl,imxrt1050-gpio"
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Add fixed clock for GPT
* Fix lpuart compatible
* Add usdhc compatible
V7->V8:
* Nothing done
---
 arch/arm/boot/dts/Makefile          |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts |  72 +++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi    | 160 ++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..07acd6189cae 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_IMXRT) += \
+	imxrt1050-evk.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/imxrt1050-evk.dts b/arch/arm/boot/dts/imxrt1050-evk.dts
new file mode 100644
index 000000000000..6a9c10decf52
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-evk.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+/dts-v1/;
+#include "imxrt1050.dtsi"
+#include "imxrt1050-pinfunc.h"
+
+/ {
+	model = "NXP IMXRT1050-evk board";
+	compatible = "fsl,imxrt1050-evk", "fsl,imxrt1050";
+
+	chosen {
+		stdout-path = &lpuart1;
+	};
+
+	aliases {
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		mmc0 = &usdhc1;
+		serial0 = &lpuart1;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x2000000>;
+	};
+};
+
+&lpuart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart1>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl_lpuart1: lpuart1grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD	0xf1
+			MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD	0xf1
+		>;
+	};
+
+	pinctrl_usdhc0: usdhc0grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B		0x1B000
+			MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT	0xB069
+			MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0	0x17061
+		>;
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+	pinctrl-0 = <&pinctrl_usdhc0>;
+	pinctrl-1 = <&pinctrl_usdhc0>;
+	pinctrl-2 = <&pinctrl_usdhc0>;
+	pinctrl-3 = <&pinctrl_usdhc0>;
+	cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imxrt1050.dtsi b/arch/arm/boot/dts/imxrt1050.dtsi
new file mode 100644
index 000000000000..77b911b06041
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050.dtsi
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include "armv7-m.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	clocks {
+		osc: osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+		};
+
+		osc3M: osc3M {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <3000000>;
+		};
+	};
+
+	soc {
+		lpuart1: serial at 40184000 {
+			compatible = "fsl,imxrt1050-lpuart", "fsl,imx7ulp-lpuart";
+			reg = <0x40184000 0x4000>;
+			interrupts = <20>;
+			clocks = <&clks IMXRT1050_CLK_LPUART1>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		iomuxc: pinctrl at 401f8000 {
+			compatible = "fsl,imxrt1050-iomuxc";
+			reg = <0x401f8000 0x4000>;
+			fsl,mux_mask = <0x7>;
+		};
+
+		anatop: anatop at 400d8000 {
+			compatible = "fsl,imxrt-anatop";
+			reg = <0x400d8000 0x4000>;
+		};
+
+		clks: clock-controller at 400fc000 {
+			compatible = "fsl,imxrt1050-ccm";
+			reg = <0x400fc000 0x4000>;
+			interrupts = <95>, <96>;
+			clocks = <&osc>;
+			clock-names = "osc";
+			#clock-cells = <1>;
+			assigned-clocks = <&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL2_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_PFD1_664_62M>,
+				<&clks IMXRT1050_CLK_PLL2_PFD2_396M>;
+			assigned-clock-parents = <&clks IMXRT1050_CLK_PLL1_REF_SEL>,
+				<&clks IMXRT1050_CLK_PLL1_ARM>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>;
+		};
+
+		edma1: dma-controller at 400e8000 {
+			#dma-cells = <2>;
+			compatible = "fsl,imx7ulp-edma";
+			reg = <0x400e8000 0x4000>,
+				<0x400ec000 0x4000>;
+			dma-channels = <32>;
+			interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>,
+				<9>, <10>, <11>, <12>, <13>, <14>, <15>, <16>;
+			clock-names = "dma", "dmamux0";
+			clocks = <&clks IMXRT1050_CLK_DMA>,
+				 <&clks IMXRT1050_CLK_DMA_MUX>;
+		};
+
+		usdhc1: mmc at 402c0000 {
+			compatible ="fsl,imxrt1050-usdhc", "fsl,imx6sl-usdhc";
+			reg = <0x402c0000 0x4000>;
+			interrupts = <110>;
+			clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
+				<&clks IMXRT1050_CLK_OSC>,
+				<&clks IMXRT1050_CLK_USDHC1>;
+			clock-names = "ipg", "ahb", "per";
+			bus-width = <4>;
+			fsl,wp-controller;
+			no-1-8-v;
+			max-frequency = <4000000>;
+			fsl,tuning-start-tap = <20>;
+			fsl,tuning-step= <2>;
+			status = "disabled";
+		};
+
+		gpio1: gpio at 401b8000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401b8000 0x4000>;
+			interrupts = <80>, <81>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio at 401bc000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401bc000 0x4000>;
+			interrupts = <82>, <83>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio at 401c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c0000 0x4000>;
+			interrupts = <84>, <85>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio at 401c4000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c4000 0x4000>;
+			interrupts = <86>, <87>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio5: gpio at 400c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x400c0000 0x4000>;
+			interrupts = <88>, <89>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpt: timer at 401ec000 {
+			compatible = "fsl,imxrt1050-gpt", "fsl,imx6dl-gpt", "fsl,imx6sl-gpt";
+			reg = <0x401ec000 0x4000>;
+			interrupts = <100>;
+			clocks = <&osc3M>;
+			clock-names = "per";
+		};
+	};
+};
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:26:06 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:26:06 -0500
Subject: [PATCH v7 7/7] ARM: imxrt_defconfig: Add i.MXRT family defconfig
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111212606.2072669-8-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add generic i.MXRT family defconfig.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Nothing done
V2->V3:
* Nothing done
V3->V4:
* Remove unnecessary CONFIGs
* Add futex suport after "ARM: 9122/1: select HAVE_FUTEX_CMPXCHG"
9d417cbe36eee7afdd85c2e871685f8dab7c2dba
V4->V5:
* Change commit description
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/configs/imxrt_defconfig | 35 ++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 arch/arm/configs/imxrt_defconfig

diff --git a/arch/arm/configs/imxrt_defconfig b/arch/arm/configs/imxrt_defconfig
new file mode 100644
index 000000000000..52dba3762996
--- /dev/null
+++ b/arch/arm/configs/imxrt_defconfig
@@ -0,0 +1,35 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BPF_SYSCALL=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_MMU is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMXRT=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x80000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_LEGACY_PTY_COUNT=2
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_PINCTRL_IMXRT1050=y
+CONFIG_GPIO_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_IMXRT1050=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_UTF8=y
-- 
2.34.1



From helgaas at kernel.org  Tue Jan 11 13:46:08 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 11 Jan 2022 15:46:08 -0600
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20200722022514.1283916-20-robh@kernel.org>
Message-ID: <20220111214608.GA169999@bhelgaas>

[-cc many, +cc iproc, loongson, tegra maintainers]

On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> The majority of DT based host drivers use the default .map_irq() and
> .swizzle_irq() functions, so let's initialize the function pointers to
> the default and drop setting them in the host drivers.
> 
> Drivers like iProc which don't support legacy interrupts need to set
> .map_irq() back to NULL.

Probably a dumb question...

This patch removed all the ->swizzle_irq users in drivers/pci/, which
is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
r1.2, sec 9.1, and should not be device-specific.  I assume the few
remaining arch/ users (arm and alpha) are either bugs or workarounds
for broken devices.

My question is why we still have a few users of ->map_irq: loongson,
tegra, iproc.  Shouldn't this mapping be described somehow via DT?

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index fc4e38fec928..97433beff6cf 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -2709,7 +2709,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> -	host->swizzle_irq = pci_common_swizzle;
>  
>  	err = pci_host_probe(host);
>  	if (err < 0) {

> diff --git a/drivers/pci/controller/pcie-iproc-platform.c b/drivers/pci/controller/pcie-iproc-platform.c
> index 7c10c1cb6f65..a956b0c18bd1 100644
> --- a/drivers/pci/controller/pcie-iproc-platform.c
> +++ b/drivers/pci/controller/pcie-iproc-platform.c
> @@ -99,9 +99,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
>  	switch (pcie->type) {
>  	case IPROC_PCIE_PAXC:
>  	case IPROC_PCIE_PAXC_V2:
> +		pcie->map_irq = 0;
>  		break;
>  	default:
> -		pcie->map_irq = of_irq_parse_and_map_pci;
> +		break;
>  	}
>  
>  	ret = iproc_pcie_setup(pcie, &bridge->windows);

> diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c
> index e98dafd0fff4..905e93808243 100644
> --- a/drivers/pci/controller/pcie-iproc.c
> +++ b/drivers/pci/controller/pcie-iproc.c
> @@ -1526,7 +1526,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
>  	host->ops = &iproc_pcie_ops;
>  	host->sysdata = pcie;
>  	host->map_irq = pcie->map_irq;
> -	host->swizzle_irq = pci_common_swizzle;
>  
>  	ret = pci_host_probe(host);
>  	if (ret < 0) {

drivers/pci/controller/pci-loongson.c:

  static int loongson_pci_probe(struct platform_device *pdev)
  {
    ...
    bridge->map_irq = loongson_map_irq;



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:08 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:08 -0500
Subject: [PATCH v8 0/7] Add initial support for the i.MXRTxxxx SoC family
 starting from i.IMXRT1050 SoC.
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>

This patchset contains:
- i.MXRT10xx family infrastructure
- i.MXRT1050 pinctrl driver adaption
- i.MXRT1050 clock driver adaption
- i.MXRT1050 sd-card driver adaption
- i.MXRT1050 uart driver adaption
- i.MXRT1050-evk basic support

The i.MXRTxxxx family that could have support by Linux actually spreads
from i.MXRT1020 to i.MXRT1170 with the first one supporting 1 USB OTG &
100M ethernet with a cortex-M7 at 500Mhz up to the latter with i.MXRT1170
with cortex-M7 at 1Ghz and cortex-M4 at 400Mhz, 2MB of internal SRAM, 2D GPU,
2x 1Gb and 1x 100Mb ENET. The i.MXRT family is NXP's answer to
STM32F7XX, as it uses only simple SDRAM, it gives the chance of a 4 or
less layer PCBs. Seeing that these chips are comparable to the
STM32F7XXs which have linux ported to them it seems reasonable to add
support for them.

Giving Linux support to this family should ease the development process,
instead of using a RTOS they could use Embedded Linux allowing for more
portability, ease of design and will broaden the scope of people using
embedded linux.

The EVK has very little SDRAM, generally 32MB starting from
i.MXRT1020(the lowest P/N), although the i.MXRT1160/70 provide instead
64MB of SDRAM for more functionality.

At the moment we do not support XIP for either u-boot or Linux but it
should be done in the future. XIP will also save SDRAM.

Another interesting fact is the amount of internal SRAM, as the P/N
increases the SRAM will reach up to 2MB(some could be for cache and
some would be for video).

Also, some parts have embed flash of 4MB that can be used for
u-boot/Linux, if both correctly sized it will leave the SDRAM free.

External flash can be Quad SPI and HyperFlash, so throughput would be
decent.

The i.MXRT11xx series supports MIPI interface too.

The family in general provide CAN bus, audio I/O, 1 or more
USB(otg/host), 1 or more 100Mb/1Gb ethernet, camera interface, sd-card.

All this can be used for simple GUIs, web-servers, point-of-sale
stations, etc.


Giulio Benetti (4):
  ARM: imx: Add initial support for i.MXRT10xx family
  dt-bindings: imx: Add clock binding for i.MXRT1050
  ARM: dts: imx: Add i.MXRT1050-EVK support
  ARM: imxrt_defconfig: Add i.MXRT family defconfig

Jesse Taube (3):
  ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
  dt-bindings: clock: imx: Add documentation for i.MXRT1050 clock
  clk: imx: Add initial support for i.MXRT1050 clock driver

 .../bindings/clock/imxrt1050-clock.yaml       |  67 ++
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts           |  72 ++
 arch/arm/boot/dts/imxrt1050-pinfunc.h         | 993 ++++++++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi              | 160 +++
 arch/arm/configs/imxrt_defconfig              |  35 +
 arch/arm/mach-imx/Kconfig                     |   7 +
 arch/arm/mach-imx/Makefile                    |   2 +
 arch/arm/mach-imx/mach-imxrt.c                |  19 +
 drivers/clk/imx/Kconfig                       |   7 +
 drivers/clk/imx/Makefile                      |   1 +
 drivers/clk/imx/clk-imxrt1050.c               | 168 +++
 include/dt-bindings/clock/imxrt1050-clock.h   |  72 ++
 13 files changed, 1605 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi
 create mode 100644 arch/arm/configs/imxrt_defconfig
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:09 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:09 -0500
Subject: [PATCH v8 1/7] ARM: imx: Add initial support for i.MXRT10xx family
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-2-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The i.MXRT10xx family of processors features NXP's implementation of the
Arm Cortex-M7 core and in some case the Arm Cortex-M4 core too.

This patch aims to add an initial support for imxrt.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: removed SOC_IMXRT's 'depends on ARCH_MULTI_V7' and 'select
ARM_GIC if ARCH_MULTI_V7']
---
V1->V2:
* Remove depends ARCH_MULTI_V7
* Remove select PINCTRL_IMXRT
* Change commit description
V2->V3:
* Nothing done
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/mach-imx/Kconfig      |  7 +++++++
 arch/arm/mach-imx/Makefile     |  2 ++
 arch/arm/mach-imx/mach-imxrt.c | 19 +++++++++++++++++++
 3 files changed, 28 insertions(+)
 create mode 100644 arch/arm/mach-imx/mach-imxrt.c

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index b407b024dde3..5ad3a8b9b4b6 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -239,6 +239,13 @@ config SOC_IMX7ULP
 	help
 	  This enables support for Freescale i.MX7 Ultra Low Power processor.
 
+config SOC_IMXRT
+	bool "i.MXRT support"
+	depends on ARM_SINGLE_ARMV7M
+	select ARMV7M_SYSTICK if ARM_SINGLE_ARMV7M
+	help
+	  This enables support for Freescale i.MXRT Crossover processor.
+
 config SOC_VF610
 	bool "Vybrid Family VF610 support"
 	select ARM_GIC if ARCH_MULTI_V7
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index d1506ef7a537..3b1145722a44 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -65,6 +65,8 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o
 obj-$(CONFIG_SOC_IMX51) += mach-imx51.o
 obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
 
+obj-$(CONFIG_SOC_IMXRT) += mach-imxrt.o
+
 obj-$(CONFIG_SOC_VF610) += mach-vf610.o
 
 obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o
diff --git a/arch/arm/mach-imx/mach-imxrt.c b/arch/arm/mach-imx/mach-imxrt.c
new file mode 100644
index 000000000000..2063a3059c84
--- /dev/null
+++ b/arch/arm/mach-imx/mach-imxrt.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+#include <asm/v7m.h>
+
+static const char *const imxrt_compat[] __initconst = {
+	"fsl,imxrt1050",
+	NULL
+};
+
+DT_MACHINE_START(IMXRTDT, "IMXRT (Device Tree Support)")
+	.dt_compat = imxrt_compat,
+	.restart = armv7m_restart,
+MACHINE_END
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:12 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:12 -0500
Subject: [PATCH v8 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-5-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add DT binding documentation for i.MXRT1050 clock driver.

Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Replace macros with values
V2->V3:
* Remove anatop
* Use lpuart not gpt
* include imxrt1050-clock.h
* 2 space tabs to 4
* Remove oneOf enum
* Change maxItems to 2
V3->V4:
* Nothing done
V4->V5:
* Remove extra newline
* Rename ccm to clock-controller
* Change minItems to const
* Change minItems to description
* Rename file to add 1050
* Change commit description to just 1050
V5->V6:
* Add maxItems for clocks description
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 .../bindings/clock/imxrt1050-clock.yaml       | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
new file mode 100644
index 000000000000..35fd08c143f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imxrt1050-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Clock bindings for Freescale i.MXRT
+
+maintainers:
+  - Giulio Benetti <giulio.benetti at benettiengineering.com>
+  - Jesse Taube <Mr.Bossman075 at gmail.com>
+
+description: |
+  The clock consumer should specify the desired clock by having the clock
+  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imxrt*-clock.h
+  for the full list of i.MXRT clock IDs.
+
+properties:
+  compatible:
+    const: fsl,imxrt1050-ccm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 2
+
+  clocks:
+    description: 24m osc
+    maxItems: 1
+
+  clock-names:
+    const: osc
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imxrt1050-clock.h>
+
+    clks: clock-controller at 400fc000 {
+        compatible = "fsl,imxrt1050-ccm";
+        reg = <0x400fc000 0x4000>;
+        interrupts = <95>, <96>;
+        clocks = <&osc>;
+        clock-names = "osc";
+        #clock-cells = <1>;
+    };
+
+    lpuart1: serial at 40184000 {
+        compatible = "fsl,imxrt1050-lpuart";
+        reg = <0x40184000 0x4000>;
+        interrupts = <20>;
+        clocks = <&clks IMXRT1050_CLK_LPUART1>;
+        clock-names = "ipg";
+    };
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:10 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:10 -0500
Subject: [PATCH v8 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-3-Mr.Bossman075@gmail.com>

From: Jesse Taube <mr.bossman075 at gmail.com>

Add binding header for i.MXRT1050 pinctrl device tree.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: move pinfunc from dt-bindings to dts folder]
---
V1->V2:
* Move pinfunc from dt-binding to dts
* Change subject and description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Change License comment style
V3->V4:
* Nothing done
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/boot/dts/imxrt1050-pinfunc.h | 993 ++++++++++++++++++++++++++
 1 file changed, 993 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h

diff --git a/arch/arm/boot/dts/imxrt1050-pinfunc.h b/arch/arm/boot/dts/imxrt1050-pinfunc.h
new file mode 100644
index 000000000000..22c14a3262ad
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-pinfunc.h
@@ -0,0 +1,993 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+#define _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H
+
+#define IMX_PAD_SION	0x40000000
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+
+#define MXRT1050_IOMUXC_GPIO_EMC_00_SEMC_DA00				0x014 0x204 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXPWM4_PWM0_A			0x014 0x204 0x494 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_LPSPI2_SCK				0x014 0x204 0x500 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_00_XBAR_INOUT2				0x014 0x204 0x60C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_FLEXIO1_D00				0x014 0x204 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_00_GPIO4_IO00				0x014 0x204 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_01_SEMC_DA01				0x018 0x208 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXPWM4_PWM0_B			0x018 0x208 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_LPSPI2_PCS0				0x018 0x208 0x4FC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_01_XBAR_INOUT3				0x018 0x208 0x610 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_FLEXIO1_D01				0x018 0x208 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_01_GPIO4_IO01				0x018 0x208 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_02_SEMC_DA02				0x01C 0x20C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXPWM4_PWM1_A			0x01C 0x20C 0x498 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_LPSPI2_SDO				0x01C 0x20C 0x508 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_02_XBAR_INOUT4				0x01C 0x20C 0x614 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_FLEXIO1_D02				0x01C 0x20C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_02_GPIO4_IO02				0x01C 0x20C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_03_SEMC_DA03				0x020 0x210 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXPWM4_PWM1_B			0x020 0x210 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_LPSPI2_SDI				0x020 0x210 0x504 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_03_XBAR_INOUT5				0x020 0x210 0x618 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_FLEXIO1_D03				0x020 0x210 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_03_GPIO4_IO03				0x020 0x210 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SEMC_DA04				0x024 0x214 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXPWM4_PWM2_A			0x024 0x214 0x49C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_SAI2_TX_DATA			0x024 0x214 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_XBAR_INOUT6				0x024 0x214 0x61C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_FLEXIO1_D04				0x024 0x214 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_04_GPIO4_IO04				0x024 0x214 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SEMC_DA05				0x028 0x218 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXPWM4_PWM2_B			0x028 0x218 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_SAI2_TX_SYNC			0x028 0x218 0x5C4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_XBAR_INOUT7				0x028 0x218 0x620 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_FLEXIO1_D05				0x028 0x218 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_05_GPIO4_IO05				0x028 0x218 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SEMC_DA06				0x02C 0x21C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXPWM2_PWM0_A			0x02C 0x21C 0x478 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_SAI2_TX_BCLK			0x02C 0x21C 0x5C0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_XBAR_INOUT8				0x02C 0x21C 0x624 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_FLEXIO1_D06				0x02C 0x21C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_06_GPIO4_IO06				0x02C 0x21C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SEMC_DA07				0x030 0x220 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXPWM2_PWM0_B			0x030 0x220 0x488 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_SAI2_MCLK				0x030 0x220 0x5B0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_XBAR_INOUT9				0x030 0x220 0x628 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_FLEXIO1_D07				0x030 0x220 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_07_GPIO4_IO07				0x030 0x220 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SEMC_DM00				0x034 0x224 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXPWM2_PWM1_A			0x034 0x224 0x47C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_SAI2_RX_DATA			0x034 0x224 0x5B8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_XBAR_INOUT17			0x034 0x224 0x62C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_FLEXIO1_D08				0x034 0x224 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_08_GPIO4_IO08				0x034 0x224 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SEMC_ADDR00				0x038 0x228 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXPWM2_PWM1_B			0x038 0x228 0x48C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_SAI2_RX_SYNC			0x038 0x228 0x5BC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXCAN2_TX				0x038 0x228 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_FLEXIO1_D09				0x038 0x228 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_09_GPIO4_IO09				0x038 0x228 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SEMC_ADDR01				0x03C 0x22C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXPWM2_PWM2_A			0x03C 0x22C 0x480 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_SAI2_RX_BCLK			0x03C 0x22C 0x5B4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXCAN2_RX				0x03C 0x22C 0x450 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_FLEXIO1_D10				0x03C 0x22C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_10_GPIO4_IO10				0x03C 0x22C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_11_SEMC_ADDR02				0x040 0x230 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXPWM2_PWM2_B			0x040 0x230 0x490 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_LPI2C4_SDA				0x040 0x230 0x4E8 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_USDHC2_RESET_B			0x040 0x230 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_FLEXIO1_D11				0x040 0x230 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_11_GPIO4_IO11				0x040 0x230 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_12_SEMC_ADDR03				0x044 0x234 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_XBAR_INOUT24			0x044 0x234 0x640 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_LPI2C4_SCL				0x044 0x234 0x4E4 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_USDHC2_WP				0x044 0x234 0x5D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_12_FLEXPWM1_PWM3_A			0x044 0x234 0x454 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_12_GPIO4_IO12				0x044 0x234 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_13_SEMC_ADDR04				0x048 0x238 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_XBAR_INOUT25			0x048 0x238 0x650 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_LPUART3_TXD				0x048 0x238 0x53C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_MQS_RIGHT				0x048 0x238 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_13_FLEXPWM1_PWM3_B			0x048 0x238 0x464 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_13_GPIO4_IO13				0x048 0x238 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_14_SEMC_ADDR05				0x04C 0x23C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_XBAR_INOUT19			0x04C 0x23C 0x654 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPUART3_RXD				0x04C 0x23C 0x538 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_MQS_LEFT				0x04C 0x23C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_LPSPI2_PCS1				0x04C 0x23C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_14_GPIO4_IO14				0x04C 0x23C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SEMC_ADDR06				0x050 0x240 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_XBAR_INOUT20			0x050 0x240 0x634 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_LPUART3_CTS_B			0x050 0x240 0x534 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_SPDIF_OUT				0x050 0x240 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_TMR3_TIMER0				0x050 0x240 0x57C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_15_GPIO4_IO15				0x050 0x240 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SEMC_ADDR07				0x054 0x244 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_XBAR_INOUT21			0x054 0x244 0x658 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_LPUART3_RTS_B			0x054 0x244 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_SPDIF_IN				0x054 0x244 0x5C8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_16_TMR3_TIMER1				0x054 0x244 0x580 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_16_GPIO4_IO16				0x054 0x244 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_17_SEMC_ADDR08				0x058 0x248 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXPWM4_PWM3_A			0x058 0x248 0x4A0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_LPUART4_CTS_B			0x058 0x248 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_FLEXCAN1_TX				0x058 0x248 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_TMR3_TIMER2				0x058 0x248 0x584 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_17_GPIO4_IO17				0x058 0x248 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SEMC_ADDR09				0x05C 0x24C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXPWM4_PWM3_B			0x05C 0x24C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_LPUART4_RTS_B			0x05C 0x24C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_FLEXCAN1_RX				0x05C 0x24C 0x44C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_18_TMR3_TIMER3				0x05C 0x24C 0x588 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_GPIO4_IO18				0x05C 0x24C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_18_SNVS_VIO_5_CTL			0x05C 0x24C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SEMC_ADDR11				0x060 0x250 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_FLEXPWM2_PWM3_A			0x060 0x250 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_LPUART4_TXD				0x060 0x250 0x544 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_19_ENET_RX_DATA01			0x060 0x250 0x438 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_TMR2_TIMER0				0x060 0x250 0x56C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_GPIO4_IO19				0x060 0x250 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_19_SNVS_VIO_5				0x060 0x250 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_20_SEMC_ADDR12				0x064 0x254 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_FLEXPWM2_PWM3_B			0x064 0x254 0x484 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_LPUART4_RXD				0x064 0x254 0x540 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_20_ENET_RX_DATA00			0x064 0x254 0x434 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_TMR2_TIMER0				0x064 0x254 0x570 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_20_GPIO4_IO20				0x064 0x254 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_21_SEMC_BA0				0x068 0x258 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_FLEXPWM3_PWM3_A			0x068 0x258 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_LPI2C3_SDA				0x068 0x258 0x4E0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_ENET_TX_DATA01			0x068 0x258 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_TMR2_TIMER2				0x068 0x258 0x574 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_21_GPIO4_IO21				0x068 0x258 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_22_SEMC_BA1				0x06C 0x25C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_FLEXPWM3_PWM3_B			0x06C 0x25C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_LPI2C3_SCL				0x06C 0x25C 0x4DC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_ENET_TX_DATA00			0x06C 0x25C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_TMR2_TIMER3				0x06C 0x25C 0x578 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_22_GPIO4_IO22				0x06C 0x25C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_23_SEMC_ADDR10				0x070 0x260 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_FLEXPWM1_PWM0_A			0x070 0x260 0x458 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_LPUART5_TXD				0x070 0x260 0x54C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_ENET_RX_EN				0x070 0x260 0x43C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPT1_CAPTURE2			0x070 0x260 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_23_GPIO4_IO23				0x070 0x260 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_24_SEMC_CAS				0x074 0x264 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_FLEXPWM1_PWM0_B			0x074 0x264 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_LPUART5_RXD				0x074 0x264 0x548 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_ENET_TX_EN				0x074 0x264 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPT1_CAPTURE1			0x074 0x264 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_24_GPIO4_IO24				0x074 0x264 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_25_SEMC_RAS				0x078 0x268 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_FLEXPWM1_PWM1_A			0x078 0x268 0x45C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_LPUART6_TXD				0x078 0x268 0x554 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_TX_CLK				0x078 0x268 0x448 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_ENET_REF_CLK			0x078 0x268 0x42C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_25_GPIO4_IO25				0x078 0x268 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_26_SEMC_CLK				0x07C 0x26C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXPWM1_PWM1_B			0x07C 0x26C 0x46C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_LPUART6_RXD				0x07C 0x26C 0x550 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_ENET_RX_ER				0x07C 0x26C 0x440 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_FLEXIO1_D12				0x07C 0x26C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_26_GPIO4_IO26				0x07C 0x26C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_27_SEMC_CKE				0x080 0x270 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXPWM1_PWM2_A			0x080 0x270 0x460 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPUART5_RTS_B			0x080 0x270 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_LPSPI1_SCK				0x080 0x270 0x4F0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_FLEXIO1_D13				0x080 0x270 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_27_GPIO4_IO27				0x080 0x270 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_28_SEMC_WE				0x084 0x274 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXPWM1_PWM2_B			0x084 0x274 0x470 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPUART5_CTS_B			0x084 0x274 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_LPSPI1_SDO				0x084 0x274 0x4F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_FLEXIO1_D14				0x084 0x274 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_28_GPIO4_IO28				0x084 0x274 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_29_SEMC_CS0				0x088 0x278 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXPWM3_PWM0_A			0x088 0x278 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPUART6_RTS_B			0x088 0x278 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_LPSPI1_SDI				0x088 0x278 0x4F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_FLEXIO1_D15				0x088 0x278 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_29_GPIO4_IO29				0x088 0x278 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_30_SEMC_DA08				0x08C 0x27C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_FLEXPWM3_PWM0_B			0x08C 0x27C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPUART6_CTS_B			0x08C 0x27C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_LPSPI1_PCS0				0x08C 0x27C 0x4EC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_30_CSI_DATA23				0x08C 0x27C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_30_GPIO4_IO30				0x08C 0x27C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_31_SEMC_DA09				0x090 0x280 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_FLEXPWM3_PWM1_A			0x090 0x280 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPUART7_TXD				0x090 0x280 0x55C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_31_LPSPI1_PCS1				0x090 0x280 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_CSI_DATA22				0x090 0x280 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_31_GPIO4_IO31				0x090 0x280 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_32_SEMC_DA10				0x094 0x284 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_FLEXPWM3_PWM1_B			0x094 0x284 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_LPUART7_RXD				0x094 0x284 0x558 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CCM_PMIC_READY			0x094 0x284 0x3FC 0x3 0x4
+#define MXRT1050_IOMUXC_GPIO_EMC_32_CSI_DATA21				0x094 0x284 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_32_GPIO3_IO18				0x094 0x284 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SEMC_DA11				0x098 0x288 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_FLEXPWM3_PWM2_A			0x098 0x288 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_USDHC1_RESET_B			0x098 0x288 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_SAI3_RX_DATA			0x098 0x288 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_CSI_DATA20				0x098 0x288 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_33_GPIO3_IO19				0x098 0x288 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SEMC_DA12				0x09C 0x28C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_FLEXPWM3_PWM2_B			0x09C 0x28C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_USDHC1_VSELECT			0x09C 0x28C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_SAI3_RX_SYNC			0x09C 0x28C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_CSI_DATA19				0x09C 0x28C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_34_GPIO3_IO20				0x09C 0x28C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SEMC_DA13				0x0A0 0x290 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_XBAR_INOUT18			0x0A0 0x290 0x630 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPT1_COMPARE1			0x0A0 0x290 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_SAI3_RX_BCLK			0x0A0 0x290 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_CSI_DATA18				0x0A0 0x290 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_GPIO3_IO21				0x0A0 0x290 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_35_USDHC1_CD_B				0x0A0 0x290 0x5D4 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SEMC_DA14				0x0A4 0x294 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_XBAR_INOUT22			0x0A4 0x294 0x638 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPT1_COMPARE2			0x0A4 0x294 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_SAI3_TX_DATA			0x0A4 0x294 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_CSI_DATA17				0x0A4 0x294 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_GPIO3_IO22				0x0A4 0x294 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_36_USDHC1_WP				0x0A4 0x294 0x5D8 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SEMC_DA15				0x0A8 0x298 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_XBAR_INOUT23			0x0A8 0x298 0x63C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPT1_COMPARE3			0x0A8 0x298 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_SAI3_MCLK				0x0A8 0x298 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_CSI_DATA16				0x0A8 0x298 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_GPIO3_IO23				0x0A8 0x298 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_37_USDHC2_WP				0x0A8 0x298 0x608 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SEMC_DM01				0x0AC 0x29C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_FLEXPWM1_PWM3_A			0x0AC 0x29C 0x454 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_LPUART8_TXD				0x0AC 0x29C 0x564 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_38_SAI3_TX_BCLK			0x0AC 0x29C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_CSI_FIELD				0x0AC 0x29C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_GPIO3_IO24				0x0AC 0x29C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_38_USDHC2_VSELECT			0x0AC 0x29C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SEMC_DQS				0x0B0 0x2A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_FLEXPWM1_PWM3_B			0x0B0 0x2A0 0x464 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_LPUART8_RXD				0x0B0 0x2A0 0x560 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_EMC_39_SAI3_TX_SYNC			0x0B0 0x2A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_WDOG1_B				0x0B0 0x2A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_GPIO3_IO25				0x0B0 0x2A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_39_USDHC2_CD_B				0x0B0 0x2A0 0x5E0 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_EMC_40_SEMC_RDY				0x0B4 0x2A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPT2_CAPTURE2			0x0B4 0x2A4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_LPSPI1_PCS2				0x0B4 0x2A4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USB_OTG2_OC				0x0B4 0x2A4 0x5CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_40_ENET_MDC				0x0B4 0x2A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_GPIO3_IO26				0x0B4 0x2A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_40_USDHC2_RESET_B			0x0B4 0x2A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_EMC_41_SEMC_CSX0				0x0B8 0x2A8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPT2_CAPTURE1			0x0B8 0x2A8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_LPSPI1_PCS3				0x0B8 0x2A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USB_OTG2_PWR			0x0B8 0x2A8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_ENET_MDIO				0x0B8 0x2A8 0x430 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_EMC_41_GPIO3_IO27				0x0B8 0x2A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_EMC_41_USDHC2_VSELECT			0x0B8 0x2A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_FLEXPWM2_PWM3_A			0x0BC 0x2AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_XBAR_INOUT14			0x0BC 0x2AC 0x644 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_REF_CLK_32K			0x0BC 0x2AC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USB_OTG2_ID			0x0BC 0x2AC 0x3F8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPI2C1_SCLS			0x0BC 0x2AC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_GPIO1_IO00			0x0BC 0x2AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_USDHC1_RESET_B			0x0BC 0x2AC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_00_LPSPI3_SCK			0x0BC 0x2AC 0x510 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_FLEXPWM2_PWM3_B			0x0C0 0x2B0 0x484 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_XBAR_INOUT15			0x0C0 0x2B0 0x648 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_REF_CLK_24M			0x0C0 0x2B0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_USB_OTG1_ID			0x0C0 0x2B0 0x3F4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPI2C1_SDAS			0x0C0 0x2B0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_GPIO1_IO01			0x0C0 0x2B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_EWM_OUT_B				0x0C0 0x2B0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_01_LPSPI3_SDO			0x0C0 0x2B0 0x518 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXCAN2_TX			0x0C4 0x2B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_XBAR_INOUT16			0x0C4 0x2B4 0x64C 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPUART6_TXD			0x0C4 0x2B4 0x554 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_USB_OTG1_PWR			0x0C4 0x2B4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_FLEXPWM1_PWM0_X			0x0C4 0x2B4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_GPIO1_IO02			0x0C4 0x2B4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPI2C1_HREQ			0x0C4 0x2B4 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI			0x0C4 0x2B4 0x514 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXCAN2_RX			0x0C8 0x2B8 0x450 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_XBAR_INOUT17			0x0C8 0x2B8 0x62C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPUART6_RXD			0x0C8 0x2B8 0x550 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_USB_OTG1_OC			0x0C8 0x2B8 0x5D0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_FLEXPWM1_PWM1_X			0x0C8 0x2B8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_GPIO1_IO03			0x0C8 0x2B8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_REF_CLK_24M			0x0C8 0x2B8 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0			0x0C8 0x2B8 0x50C 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SRC_BOOT_MODE00			0x0CC 0x2BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_MQS_RIGHT				0x0CC 0x2BC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_ENET_TX_DATA03			0x0CC 0x2BC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_SAI2_TX_SYNC			0x0CC 0x2BC 0x5C4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_CSI_DATA09			0x0CC 0x2BC 0x41C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_GPIO1_IO04			0x0CC 0x2BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_PIT_TRIGGER00			0x0CC 0x2BC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_04_LPSPI3_PCS1			0x0CC 0x2BC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SRC_BOOT_MODE01			0x0D0 0x2C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_MQS_LEFT				0x0D0 0x2C0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_ENET_TX_DATA02			0x0D0 0x2C0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_SAI2_TX_BCLK			0x0D0 0x2C0 0x5C0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_CSI_DATA08			0x0D0 0x2C0 0x418 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_GPIO1_IO05			0x0D0 0x2C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_XBAR_INOUT17			0x0D0 0x2C0 0x62C 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_05_LPSPI3_PCS2			0x0D0 0x2C0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_JTAG_TMS				0x0D4 0x2C4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPT2_COMPARE1			0x0D4 0x2C4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_ENET_RX_CLK			0x0D4 0x2C4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_SAI2_RX_BCLK			0x0D4 0x2C4 0x5B4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_CSI_DATA07			0x0D4 0x2C4 0x414 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_GPIO1_IO06			0x0D4 0x2C4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_XBAR_INOUT18			0x0D4 0x2C4 0x630 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_06_LPSPI3_PCS3			0x0D4 0x2C4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_JTAG_TCK				0x0D8 0x2C8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPT2_COMPARE2			0x0D8 0x2C8 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_TX_ER			0x0D8 0x2C8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_SAI2_RX_SYNC			0x0D8 0x2C8 0x5BC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_CSI_DATA06			0x0D8 0x2C8 0x410 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_GPIO1_IO07			0x0D8 0x2C8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_XBAR_INOUT19			0x0D8 0x2C8 0x654 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_07_ENET_1588_EVENT3_OUT		0x0D8 0x2C8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_JTAG_MOD				0x0DC 0x2CC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPT2_COMPARE3			0x0DC 0x2CC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_RX_DATA03			0x0DC 0x2CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_SAI2_RX_DATA			0x0DC 0x2CC 0x5B8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_CSI_DATA05			0x0DC 0x2CC 0x40C 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_GPIO1_IO08			0x0DC 0x2CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_XBAR_INOUT20			0x0DC 0x2CC 0x634 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_08_ENET_1588_EVENT3_IN		0x0DC 0x2CC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_JTAG_TDI				0x0E0 0x2D0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_FLEXPWM2_PWM3_A			0x0E0 0x2D0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_ENET_RX_DATA02			0x0E0 0x2D0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_SAI2_TX_DATA			0x0E0 0x2D0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_CSI_DATA04			0x0E0 0x2D0 0x408 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPIO1_IO09			0x0E0 0x2D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_XBAR_INOUT21			0x0E0 0x2D0 0x658 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_09_GPT2_CLK				0x0E0 0x2D0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_JTAG_TDO				0x0E4 0x2D4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_FLEXPWM1_PWM3_A			0x0E4 0x2D4 0x454 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_CRS				0x0E4 0x2D4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_SAI2_MCLK				0x0E4 0x2D4 0x5B0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_CSI_DATA03			0x0E4 0x2D4 0x404 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_GPIO1_IO10			0x0E4 0x2D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_XBAR_INOUT22			0x0E4 0x2D4 0x638 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_10_ENET_1588_EVENT0_OUT		0x0E4 0x2D4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_JTAG_TRSTB			0x0E8 0x2D8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_FLEXPWM1_PWM3_B			0x0E8 0x2D8 0x464 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_COL				0x0E8 0x2D8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_WDOG1_B				0x0E8 0x2D8 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_CSI_DATA02			0x0E8 0x2D8 0x400 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_GPIO1_IO11			0x0E8 0x2D8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_XBAR_INOUT23			0x0E8 0x2D8 0x63C 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_11_ENET_1588_EVENT0_IN		0x0E8 0x2D8 0x444 0x7 0x1
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPI2C4_SCL			0x0EC 0x2DC 0x4E4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_CCM_PMIC_READY			0x0EC 0x2DC 0x3FC 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD			0x0EC 0x2DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_WDOG2_B				0x0EC 0x2DC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_FLEXPWM1_PWM2_X			0x0EC 0x2DC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_GPIO1_IO12			0x0EC 0x2DC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_ENET_1588_EVENT1_OUT		0x0EC 0x2DC 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_12_NMI				0x0EC 0x2DC 0x568 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPI2C4_SDA			0x0F0 0x2E0 0x4E8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPT1_CLK				0x0F0 0x2E0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD			0x0F0 0x2E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_EWM_OUT_B				0x0F0 0x2E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_FLEXPWM1_PWM3_X			0x0F0 0x2E0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_GPIO1_IO13			0x0F0 0x2E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_ENET_1588_EVENT1_IN		0x0F0 0x2E0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_13_REF_CLK_24M			0x0F0 0x2E0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_USB_OTG2_OC			0x0F4 0x2E4 0x5CC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_XBAR_INOUT24			0x0F4 0x2E4 0x640 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_LPUART1_CTS_B			0x0F4 0x2E4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_ENET_1588_EVENT0_OUT		0x0F4 0x2E4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_CSI_VSYNC				0x0F4 0x2E4 0x428 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_GPIO1_IO14			0x0F4 0x2E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX			0x0F4 0x2E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_USB_OTG2_PWR			0x0F8 0x2E8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_XBAR_INOUT25			0x0F8 0x2E8 0x650 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_LPUART1_RTS_B			0x0F8 0x2E8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_ENET_1588_EVENT0_IN		0x0F8 0x2E8 0x444 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_CSI_HSYNC				0x0F8 0x2E8 0x420 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_GPIO1_IO15			0x0F8 0x2E8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX			0x0F8 0x2E8 0x450 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B0_15_WDOG1_WDOG_RST_B_DEB		0x0F8 0x2E8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USB_OTG2_ID			0x0FC 0x2EC 0x3F8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_TMR3_TIMER0			0x0FC 0x2EC 0x57C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPUART2_CTS_B			0x0FC 0x2EC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL			0x0FC 0x2EC 0x4CC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_WDOG1_B				0x0FC 0x2EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_GPIO1_IO16			0x0FC 0x2EC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_USDHC1_WP				0x0FC 0x2EC 0x5D8 0x6 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_00_KPP_ROW07				0x0FC 0x2EC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USB_OTG1_PWR			0x100 0x2F0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_TMR3_TIMER1			0x100 0x2F0 0x580 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPUART2_RTS_B			0x100 0x2F0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA			0x100 0x2F0 0x4D0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_CCM_PMIC_READY			0x100 0x2F0 0x3FC 0x4 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_GPIO1_IO17			0x100 0x2F0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_USDHC1_VSELECT			0x100 0x2F0 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_01_KPP_COL07				0x100 0x2F0 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USB_OTG1_ID			0x104 0x2F4 0x3F4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_TMR3_TIMER2			0x104 0x2F4 0x584 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_LPUART2_TXD			0x104 0x2F4 0x530 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_SPDIF_OUT				0x104 0x2F4 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_ENET_1588_EVENT2_OUT		0x104 0x2F4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_GPIO1_IO18			0x104 0x2F4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_USDHC1_CD_B			0x104 0x2F4 0x5D4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_02_KPP_ROW06				0x104 0x2F4 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USB_OTG1_OC			0x108 0x2F8 0x5D0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_TMR3_TIMER3			0x108 0x2F8 0x588 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_LPUART2_RXD			0x108 0x2F8 0x52C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_SPDIF_IN				0x108 0x2F8 0x5C8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_ENET_1588_EVENT2_IN		0x108 0x2F8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_GPIO1_IO19			0x108 0x2F8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_USDHC2_CD_B			0x108 0x2F8 0x5E0 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_03_KPP_COL06				0x108 0x2F8 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_FLEXSPI_B_DATA3			0x10C 0x2FC 0x4C4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_ENET_MDC				0x10C 0x2FC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_LPUART3_CTS_B			0x10C 0x2FC 0x534 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_SPDIF_SR_CLK			0x10C 0x2FC 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK			0x10C 0x2FC 0x424 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_GPIO1_IO20			0x10C 0x2FC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_USDHC2_DATA0			0x10C 0x2FC 0x5E8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_04_KPP_ROW05				0x10C 0x2FC 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_FLEXSPI_B_DATA2			0x110 0x300 0x4C0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_ENET_MDIO				0x110 0x300 0x430 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_LPUART3_RTS_B			0x110 0x300 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_SPDIF_OUT				0x110 0x300 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_CSI_MCLK				0x110 0x300 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_GPIO1_IO21			0x110 0x300 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_USDHC2_DATA1			0x110 0x300 0x5EC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_05_KPP_COL05				0x110 0x300 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_FLEXSPI_B_DATA1			0x114 0x304 0x4BC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA			0x114 0x304 0x4E0 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_LPUART3_TXD			0x114 0x304 0x53C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_SPDIF_LOCK			0x114 0x304 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_CSI_VSYNC				0x114 0x304 0x428 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_GPIO1_IO22			0x114 0x304 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_USDHC2_DATA2			0x114 0x304 0x5F0 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_06_KPP_ROW04				0x114 0x304 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_FLEXSPI_B_DATA0			0x118 0x308 0x4B8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL			0x118 0x308 0x4DC 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_LPUART3_RXD			0x118 0x308 0x538 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_SPDIF_EXT_CLK			0x118 0x308 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_CSI_HSYNC				0x118 0x308 0x420 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_GPIO1_IO23			0x118 0x308 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_USDHC2_DATA3			0x118 0x308 0x5F4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_07_KPP_COL04				0x118 0x308 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXSPI_A_SS1_B			0x11C 0x30C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXPWM4_PWM0_A			0x11C 0x30C 0x494 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_FLEXCAN1_TX			0x11C 0x30C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CCM_PMIC_READY			0x11C 0x30C 0x3FC 0x3 0x3
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_CSI_DATA09			0x11C 0x30C 0x41C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_GPIO1_IO24			0x11C 0x30C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_USDHC2_CMD			0x11C 0x30C 0x5E4 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_08_KPP_ROW03				0x11C 0x30C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXSPI_A_DQS			0x120 0x310 0x4A4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXPWM4_PWM1_A			0x120 0x310 0x498 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_FLEXCAN1_RX			0x120 0x310 0x44C 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_SAI1_MCLK				0x120 0x310 0x58C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_CSI_DATA08			0x120 0x310 0x418 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_GPIO1_IO25			0x120 0x310 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_USDHC2_CLK			0x120 0x310 0x5DC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_09_KPP_COL03				0x120 0x310 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_FLEXSPI_A_DATA3			0x124 0x314 0x4B4 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_WDOG1_B				0x124 0x314 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_LPUART8_TXD			0x124 0x314 0x564 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_SAI1_RX_SYNC			0x124 0x314 0x5A4 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_CSI_DATA07			0x124 0x314 0x414 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_GPIO1_IO26			0x124 0x314 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_USDHC2_WP				0x124 0x314 0x608 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_10_KPP_ROW02				0x124 0x314 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_FLEXSPI_A_DATA2			0x128 0x318 0x4B0 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_EWM_OUT_B				0x128 0x318 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_LPUART8_RXD			0x128 0x318 0x560 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_SAI1_RX_BCLK			0x128 0x318 0x590 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_CSI_DATA06			0x128 0x318 0x410 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_GPIO1_IO27			0x128 0x318 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_USDHC2_RESET_B			0x128 0x318 0x000 0x6 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_11_KPP_COL02				0x128 0x318 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_FLEXSPI_A_DATA1			0x12C 0x31C 0x4AC 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_ACMP1_OUT				0x12C 0x31C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0			0x12C 0x31C 0x50C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_SAI1_RX_DATA00			0x12C 0x31C 0x594 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_CSI_DATA05			0x12C 0x31C 0x40C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_GPIO1_IO28			0x12C 0x31C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_USDHC2_DATA4			0x12C 0x31C 0x5F8 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_12_KPP_ROW01				0x12C 0x31C 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_FLEXSPI_A_DATA0			0x130 0x320 0x4A8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_ACMP2_OUT				0x130 0x320 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI			0x130 0x320 0x514 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_SAI1_TX_DATA00			0x130 0x320 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_CSI_DATA04			0x130 0x320 0x408 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_GPIO1_IO29			0x130 0x320 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_USDHC2_DATA5			0x130 0x320 0x5FC 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_13_KPP_COL01				0x130 0x320 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_FLEXSPI_A_SCLK			0x134 0x324 0x4C8 0x0 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_ACMP3_OUT				0x134 0x324 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO			0x134 0x324 0x518 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_SAI1_TX_BCLK			0x134 0x324 0x5A8 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_CSI_DATA03			0x134 0x324 0x404 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_GPIO1_IO30			0x134 0x324 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_USDHC2_DATA6			0x134 0x324 0x600 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_14_KPP_ROW00				0x134 0x324 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_FLEXSPI_A_SS0_B			0x138 0x328 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_ACMP4_OUT				0x138 0x328 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK			0x138 0x328 0x510 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_SAI1_TX_SYNC			0x138 0x328 0x5AC 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_CSI_DATA02			0x138 0x328 0x400 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_GPIO1_IO31			0x138 0x328 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_USDHC2_DATA7			0x138 0x328 0x604 0x6 0x1
+#define MXRT1050_IOMUXC_GPIO_AD_B1_15_KPP_COL00				0x138 0x328 0x000 0x7 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_00_LCD_CLK				0x13C 0x32C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_TMR1_TIMER0				0x13C 0x32C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_MQS_RIGHT				0x13C 0x32C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_LPSPI4_PCS0				0x13C 0x32C 0x51C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_FLEXIO2_D00				0x13C 0x32C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_GPIO2_IO00				0x13C 0x32C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_00_SEMC_CSX1				0x13C 0x32C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_01_LCD_ENABLE				0x140 0x330 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_TMR1_TIMER1				0x140 0x330 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_MQS_LEFT				0x140 0x330 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_LPSPI4_SDI				0x140 0x330 0x524 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_FLEXIO2_D01				0x140 0x330 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_GPIO2_IO01				0x140 0x330 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_01_SEMC_CSX2				0x140 0x330 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_02_LCD_HSYNC				0x144 0x334 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_TMR1_TIMER2				0x144 0x334 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXCAN1_TX				0x144 0x334 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_LPSPI4_SDO				0x144 0x334 0x528 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_FLEXIO2_D02				0x144 0x334 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_GPIO2_IO02				0x144 0x334 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_02_SEMC_CSX3				0x144 0x334 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_03_LCD_VSYNC				0x148 0x338 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_TMR2_TIMER0				0x148 0x338 0x56C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXCAN1_RX				0x148 0x338 0x44C 0x2 0x3
+#define MXRT1050_IOMUXC_GPIO_B0_03_LPSPI4_SCK				0x148 0x338 0x520 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_FLEXIO2_D03				0x148 0x338 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_GPIO2_IO03				0x148 0x338 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_03_WDOG2_RESET_B_DEB			0x148 0x338 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_04_LCD_DATA00				0x14C 0x33C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_TMR2_TIMER1				0x14C 0x33C 0x570 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_LPI2C2_SCL				0x14C 0x33C 0x4D4 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_04_ARM_TRACE00				0x14C 0x33C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_FLEXIO2_D04				0x14C 0x33C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_GPIO2_IO04				0x14C 0x33C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_04_SRC_BT_CFG00				0x14C 0x33C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_05_LCD_DATA01				0x150 0x340 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_TMR2_TIMER2				0x150 0x340 0x574 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_LPI2C2_SDA				0x150 0x340 0x4D8 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_05_ARM_TRACE01				0x150 0x340 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_FLEXIO2_D05				0x150 0x340 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_GPIO2_IO05				0x150 0x340 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_05_SRC_BT_CFG01				0x150 0x340 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_06_LCD_DATA02				0x154 0x344 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_TMR3_TIMER0				0x154 0x344 0x57C 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXPWM2_PWM0_A			0x154 0x344 0x478 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_06_ARM_TRACE02				0x154 0x344 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_FLEXIO2_D06				0x154 0x344 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_GPIO2_IO06				0x154 0x344 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_06_SRC_BT_CFG02				0x154 0x344 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_07_LCD_DATA03				0x158 0x348 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_TMR3_TIMER1				0x158 0x348 0x580 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXPWM2_PWM0_B			0x158 0x348 0x488 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_07_ARM_TRACE03				0x158 0x348 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_FLEXIO2_D07				0x158 0x348 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_GPIO2_IO07				0x158 0x348 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_07_SRC_BT_CFG03				0x158 0x348 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_08_LCD_DATA04				0x15C 0x34C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_TMR3_TIMER2				0x15C 0x34C 0x584 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXPWM2_PWM1_A			0x15C 0x34C 0x47C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_08_LPUART3_TXD				0x15C 0x34C 0x53C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_08_FLEXIO2_D08				0x15C 0x34C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_GPIO2_IO08				0x15C 0x34C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_08_SRC_BT_CFG04				0x15C 0x34C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_09_LCD_DATA05				0x160 0x350 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_TMR4_TIMER0				0x160 0x350 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXPWM2_PWM1_B			0x160 0x350 0x48C 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_09_LPUART3_RXD				0x160 0x350 0x538 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_09_FLEXIO2_D09				0x160 0x350 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_GPIO2_IO09				0x160 0x350 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_09_SRC_BT_CFG05				0x160 0x350 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_10_LCD_DATA06				0x164 0x354 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_TMR4_TIMER1				0x164 0x354 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXPWM2_PWM2_A			0x164 0x354 0x480 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_SAI1_TX_DATA03			0x164 0x354 0x598 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_10_FLEXIO2_D10				0x164 0x354 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_GPIO2_IO10				0x164 0x354 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_10_SRC_BT_CFG06				0x164 0x354 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_11_LCD_DATA07				0x168 0x358 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_TMR4_TIMER2				0x168 0x358 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXPWM2_PWM2_B			0x168 0x358 0x490 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_SAI1_TX_DATA02			0x168 0x358 0x59C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_11_FLEXIO2_D11				0x168 0x358 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_GPIO2_IO11				0x168 0x358 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_11_SRC_BT_CFG07				0x168 0x358 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_12_LCD_DATA08				0x16C 0x35C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_XBAR_INOUT10				0x16C 0x35C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_ARM_TRACE_CLK			0x16C 0x35C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SAI1_TX_DATA01			0x16C 0x35C 0x5A0 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B0_12_FLEXIO2_D12				0x16C 0x35C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_GPIO2_IO12				0x16C 0x35C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_12_SRC_BT_CFG08				0x16C 0x35C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_13_LCD_DATA09				0x170 0x360 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_XBAR_INOUT11				0x170 0x360 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_ARM_TRACE_SWO			0x170 0x360 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SAI1_MCLK				0x170 0x360 0x58C 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_13_FLEXIO2_D13				0x170 0x360 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_GPIO2_IO13				0x170 0x360 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_13_SRC_BT_CFG09				0x170 0x360 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_14_LCD_DATA10				0x174 0x364 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_XBAR_INOUT12				0x174 0x364 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_ARM_CM7_TXEV				0x174 0x364 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SAI1_RX_SYNC				0x174 0x364 0x5A4 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_14_FLEXIO2_D14				0x174 0x364 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_GPIO2_IO14				0x174 0x364 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_14_SRC_BT_CFG10				0x174 0x364 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B0_15_LCD_DATA11				0x178 0x368 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_XBAR_INOUT13				0x178 0x368 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_ARM_CM7_RXEV				0x178 0x368 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SAI1_RX_BCLK				0x178 0x368 0x590 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B0_15_FLEXIO2_D15				0x178 0x368 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_GPIO2_IO15				0x178 0x368 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B0_15_SRC_BT_CFG11				0x178 0x368 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_00_LCD_DATA12				0x17C 0x36C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_XBAR_INOUT14				0x17C 0x36C 0x644 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_00_LPUART4_TXD				0x17C 0x36C 0x544 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_SAI1_RX_DATA00			0x17C 0x36C 0x594 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXIO2_D16				0x17C 0x36C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_GPIO2_IO16				0x17C 0x36C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_00_FLEXPWM1_PWM3_A			0x17C 0x36C 0x454 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_01_LCD_DATA13				0x180 0x370 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_XBAR_INOUT15				0x180 0x370 0x648 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_01_LPUART4_RXD				0x180 0x370 0x540 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_01_SAI1_TX_DATA00			0x180 0x370 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXIO2_D17				0x180 0x370 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_GPIO2_IO17				0x180 0x370 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_01_FLEXPWM1_PWM3_B			0x180 0x370 0x464 0x6 0x4
+
+#define MXRT1050_IOMUXC_GPIO_B1_02_LCD_DATA14				0x184 0x374 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_XBAR_INOUT16				0x184 0x374 0x64C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_02_LPSPI4_PCS2				0x184 0x374 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_SAI1_TX_BCLK				0x184 0x374 0x5A8 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXIO2_D18				0x184 0x374 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_GPIO2_IO18				0x184 0x374 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_02_FLEXPWM2_PWM3_A			0x184 0x374 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_03_LCD_DATA15				0x188 0x378 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_XBAR_INOUT17				0x188 0x378 0x62C 0x1 0x3
+#define MXRT1050_IOMUXC_GPIO_B1_03_LPSPI4_PCS1				0x188 0x378 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_SAI1_TX_SYNC				0x188 0x378 0x5AC 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXIO2_D19				0x188 0x378 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_GPIO2_IO19				0x188 0x378 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_03_FLEXPWM2_PWM3_B			0x188 0x378 0x484 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_04_LCD_DATA16				0x18C 0x37C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_LPSPI4_PCS0				0x18C 0x37C 0x51C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_CSI_DATA15				0x18C 0x37C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_ENET_RX_DATA00			0x18C 0x37C 0x434 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_04_FLEXIO2_D20				0x18C 0x37C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_04_GPIO2_IO20				0x18C 0x37C 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_05_LCD_DATA17				0x190 0x380 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_LPSPI4_SDI				0x190 0x380 0x524 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_CSI_DATA14				0x190 0x380 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_ENET_RX_DATA01			0x190 0x380 0x438 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_05_FLEXIO2_D21				0x190 0x380 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_05_GPIO2_IO21				0x190 0x380 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_06_LCD_DATA18				0x194 0x384 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_LPSPI4_SDO				0x194 0x384 0x528 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_CSI_DATA13				0x194 0x384 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_ENET_RX_EN				0x194 0x384 0x43C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_06_FLEXIO2_D22				0x194 0x384 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_06_GPIO2_IO22				0x194 0x384 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_07_LCD_DATA19				0x198 0x388 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_LPSPI4_SCK				0x198 0x388 0x520 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_07_CSI_DATA12				0x198 0x388 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_ENET_TX_DATA00			0x198 0x388 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_FLEXIO2_D23				0x198 0x388 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_07_GPIO2_IO23				0x198 0x388 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_08_LCD_DATA20				0x19C 0x38C 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_TMR1_TIMER3				0x19C 0x38C 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_CSI_DATA11				0x19C 0x38C 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_ENET_TX_DATA01			0x19C 0x38C 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXIO2_D24				0x19C 0x38C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_GPIO2_IO24				0x19C 0x38C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_08_FLEXCAN2_TX				0x19C 0x38C 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_09_LCD_DATA21				0x1A0 0x390 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_TMR2_TIMER3				0x1A0 0x390 0x578 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_09_CSI_DATA10				0x1A0 0x390 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_ENET_TX_EN				0x1A0 0x390 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXIO2_D25				0x1A0 0x390 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_GPIO2_IO25				0x1A0 0x390 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_09_FLEXCAN2_RX				0x1A0 0x390 0x450 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_10_LCD_DATA22				0x1A4 0x394 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_TMR3_TIMER3				0x1A4 0x394 0x588 0x1 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_10_CSI_DATA00				0x1A4 0x394 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_TX_CLK				0x1A4 0x394 0x448 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_10_FLEXIO2_D26				0x1A4 0x394 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_GPIO2_IO26				0x1A4 0x394 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_10_ENET_REF_CLK				0x1A4 0x394 0x42C 0x6 0x1
+
+#define MXRT1050_IOMUXC_GPIO_B1_11_LCD_DATA23				0x1A8 0x398 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_TMR4_TIMER3				0x1A8 0x398 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_CSI_DATA01				0x1A8 0x398 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_ENET_RX_ER				0x1A8 0x398 0x440 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_11_FLEXIO2_D27				0x1A8 0x398 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_GPIO2_IO27				0x1A8 0x398 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_11_LPSPI4_PCS3				0x1A8 0x398 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_12_LPUART5_TXD				0x1AC 0x39C 0x54C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_CSI_PIXCLK				0x1AC 0x39C 0x424 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_12_ENET_1588_EVENT0_IN			0x1AC 0x39C 0x444 0x3 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_12_FLEXIO2_D28				0x1AC 0x39C 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_GPIO2_IO28				0x1AC 0x39C 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B				0x1AC 0x39C 0x5D4 0x6 0x2
+
+#define MXRT1050_IOMUXC_GPIO_B1_13_WDOG1_B				0x1B0 0x3A0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_LPUART5_RXD				0x1B0 0x3A0 0x548 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_13_CSI_VSYNC				0x1B0 0x3A0 0x428 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_13_ENET_1588_EVENT0_OUT			0x1B0 0x3A0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_FLEXIO2_D29				0x1B0 0x3A0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_GPIO2_IO29				0x1B0 0x3A0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_13_USDHC1_WP				0x1B0 0x3A0 0x5D8 0x6 0x3
+
+#define MXRT1050_IOMUXC_GPIO_B1_14_ENET_MDC				0x1B4 0x3A4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXPWM4_PWM2_A			0x1B4 0x3A4 0x49C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_CSI_HSYNC				0x1B4 0x3A4 0x420 0x2 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_14_XBAR_INOUT02				0x1B4 0x3A4 0x60C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_14_FLEXIO2_D30				0x1B4 0x3A4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_GPIO2_IO30				0x1B4 0x3A4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT			0x1B4 0x3A4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_B1_15_ENET_MDIO				0x1B8 0x3A8 0x430 0x0 0x2
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXPWM4_PWM3_A			0x1B8 0x3A8 0x4A0 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_CSI_MCLK				0x1B8 0x3A8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_XBAR_INOUT03				0x1B8 0x3A8 0x610 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_B1_15_FLEXIO2_D31				0x1B8 0x3A8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_GPIO2_IO31				0x1B8 0x3A8 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_B1_15_USDHC1_RESET_B			0x1B8 0x3A8 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD			0x1BC 0x3AC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXPWM1_PWM0_A			0x1BC 0x3AC 0x458 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPI2C3_SCL			0x1BC 0x3AC 0x4DC 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_XBAR_INOUT04			0x1BC 0x3AC 0x614 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK			0x1BC 0x3AC 0x4F0 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_GPIO3_IO12			0x1BC 0x3AC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_00_FLEXSPI_A_SS1_B			0x1BC 0x3AC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK			0x1C0 0x3B0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXPWM1_PWM0_B			0x1C0 0x3B0 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPI2C3_SDA			0x1C0 0x3B0 0x4E0 0x2 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_XBAR_INOUT05			0x1C0 0x3B0 0x618 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0			0x1C0 0x3B0 0x4EC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_GPIO3_IO13			0x1C0 0x3B0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_01_FLEXSPI_B_SS1_B			0x1C0 0x3B0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0			0x1C4 0x3B4 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_FLEXPWM1_PWM1_A			0x1C4 0x3B4 0x45C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPUART8_CTS_B			0x1C4 0x3B4 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_XBAR_INOUT06			0x1C4 0x3B4 0x61C 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO			0x1C4 0x3B4 0x4F8 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_02_GPIO3_IO14			0x1C4 0x3B4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1			0x1C8 0x3B8 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_FLEXPWM1_PWM1_B			0x1C8 0x3B8 0x46C 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPUART8_RTS_B			0x1C8 0x3B8 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_XBAR_INOUT07			0x1C8 0x3B8 0x620 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI			0x1C8 0x3B8 0x4F4 0x4 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_03_GPIO3_IO15			0x1C8 0x3B8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2			0x1CC 0x3BC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXPWM1_PWM2_A			0x1CC 0x3BC 0x460 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_LPUART8_TXD			0x1CC 0x3BC 0x564 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_XBAR_INOUT08			0x1CC 0x3BC 0x624 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_FLEXSPI_B_SS0_B			0x1CC 0x3BC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_GPIO3_IO16			0x1CC 0x3BC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_04_CCM_CLKO1				0x1CC 0x3BC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3			0x1D0 0x3C0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXPWM1_PWM2_B			0x1D0 0x3C0 0x470 0x1 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_LPUART8_RXD			0x1D0 0x3C0 0x560 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_XBAR_INOUT09			0x1D0 0x3C0 0x628 0x3 0x1
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_FLEXSPI_B_DQS			0x1D0 0x3C0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_GPIO3_IO17			0x1D0 0x3C0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B0_05_CCM_CLKO2				0x1D0 0x3C0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_USDHC2_DATA3			0x1D4 0x3C4 0x5F4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXSPI_B_DATA3			0x1D4 0x3C4 0x4C4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_FLEXPWM1_PWM3_A			0x1D4 0x3C4 0x454 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_SAI1_TX_DATA03			0x1D4 0x3C4 0x598 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_LPUART4_TXD			0x1D4 0x3C4 0x544 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_00_GPIO3_IO00			0x1D4 0x3C4 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_USDHC2_DATA2			0x1D8 0x3C8 0x5F0 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXSPI_B_DATA2			0x1D8 0x3C8 0x4C0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_FLEXPWM1_PWM3_B			0x1D8 0x3C8 0x464 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_SAI1_TX_DATA02			0x1D8 0x3C8 0x59C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_LPUART4_RXD			0x1D8 0x3C8 0x540 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_01_GPIO3_IO01			0x1D8 0x3C8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_USDHC2_DATA1			0x1DC 0x3CC 0x5EC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXSPI_B_DATA1			0x1DC 0x3CC 0x4BC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXPWM2_PWM3_A			0x1DC 0x3CC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_SAI1_TX_DATA01			0x1DC 0x3CC 0x5A0 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_FLEXCAN1_TX			0x1DC 0x3CC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_GPIO3_IO02			0x1DC 0x3CC 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_02_CCM_WAIT				0x1DC 0x3CC 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_USDHC2_DATA0			0x1E0 0x3D0 0x5E8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXSPI_B_DATA0			0x1E0 0x3D0 0x4B8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXPWM2_PWM3_B			0x1E0 0x3D0 0x484 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_SAI1_MCLK				0x1E0 0x3D0 0x58C 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_FLEXCAN1_RX			0x1E0 0x3D0 0x44C 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_GPIO3_IO03			0x1E0 0x3D0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_03_CCM_PMIC_READY			0x1E0 0x3D0 0x3FC 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_USDHC2_CLK			0x1E4 0x3D4 0x5DC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXSPI_B_SCLK			0x1E4 0x3D4 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_LPI2C1_SCL			0x1E4 0x3D4 0x4CC 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_SAI1_RX_SYNC			0x1E4 0x3D4 0x5A4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_FLEXCAN1_A_SS1_B			0x1E4 0x3D4 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_GPIO3_IO04			0x1E4 0x3D4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_04_CCM_STOP				0x1E4 0x3D4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_USDHC2_CMD			0x1E8 0x3D8 0x5E4 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS			0x1E8 0x3D8 0x4A4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_LPI2C1_SDA			0x1E8 0x3D8 0x4D0 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_SAI1_RX_BCLK			0x1E8 0x3D8 0x590 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_FLEXCAN1_B_SS0_B			0x1E8 0x3D8 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_05_GPIO3_IO05			0x1E8 0x3D8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_USDHC2_RESET_B			0x1EC 0x3DC 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_SS0_B			0x1EC 0x3DC 0x000 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPUART7_CTS_B			0x1EC 0x3DC 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_SAI1_RX_DATA00			0x1EC 0x3DC 0x594 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_LPSPI2_PCS0			0x1EC 0x3DC 0x4FC 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_06_GPIO3_IO06			0x1EC 0x3DC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SEMC_CSX1				0x1F0 0x3E0 0x000 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK			0x1F0 0x3E0 0x4C8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPUART7_RTS_B			0x1F0 0x3E0 0x000 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_SAI1_TX_DATA00			0x1F0 0x3E0 0x000 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_LPSPI2_SCK			0x1F0 0x3E0 0x500 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_GPIO3_IO07			0x1F0 0x3E0 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_07_CCM_REF_EN_B			0x1F0 0x3E0 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_USDHC2_DATA4			0x1F4 0x3E4 0x5F8 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA0			0x1F4 0x3E4 0x4A8 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPUART7_TXD			0x1F4 0x3E4 0x55C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SAI1_TX_BLCK			0x1F4 0x3E4 0x5A8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_LPSPI2_SDO			0x1F4 0x3E4 0x508 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_GPIO3_IO08			0x1F4 0x3E4 0x000 0x5 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_08_SEMC_CSX2				0x1F4 0x3E4 0x000 0x6 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_USDHC2_DATA5			0x1F8 0x3E8 0x5FC 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA1			0x1F8 0x3E8 0x4AC 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPUART7_RXD			0x1F8 0x3E8 0x558 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_SAI1_TX_SYNC			0x1F8 0x3E8 0x5AC 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_LPSPI2_SDI			0x1F8 0x3E8 0x504 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_09_GPIO3_IO09			0x1F8 0x3E8 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_USDHC2_DATA6			0x1FC 0x3EC 0x600 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA2			0x1FC 0x3EC 0x4B0 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPUART2_RXD			0x1FC 0x3EC 0x52C 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPI2C2_SDA			0x1FC 0x3EC 0x4D8 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_LPSPI2_PCS2			0x1FC 0x3EC 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_10_GPIO3_IO10			0x1FC 0x3EC 0x000 0x5 0x0
+
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_USDHC2_DATA7			0x200 0x3F0 0x604 0x0 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_DATA3			0x200 0x3F0 0x4B4 0x1 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPUART2_TXD			0x200 0x3F0 0x530 0x2 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPI2C2_SCL			0x200 0x3F0 0x4D4 0x3 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_LPSPI2_PCS3			0x200 0x3F0 0x000 0x4 0x0
+#define MXRT1050_IOMUXC_GPIO_SD_B1_11_GPIO3_IO11			0x200 0x3F0 0x000 0x5 0x0
+
+#endif /* _DT_BINDINGS_PINCTRL_IMXRT1050_PINFUNC_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:13 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:13 -0500
Subject: [PATCH v8 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-6-Mr.Bossman075@gmail.com>

Add clock driver support for i.MXRT1050.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
---
V1->V2:
* Kconfig: Add new line
* clk-imxrt.c: Remove unused const
* clk-imxrt.c: Remove set parents
* clk-imxrt.c: Use fsl,imxrt-anatop for anatop base address
V2->V3:
* Remove unused ANATOP_BASE_ADDR
* Move to hw API
* Add GPT's own clock
* Add SEMC clocks to set muxing to CRITICAL
V3->V4:
* Rename clk-imxrt.c to clk-imxrt1050.c
* Rename CONFIG_CLK_IMXRT to CONFIG_CLK_IMXRT1050
* Make CONFIG_CLK_IMXRT1050 selectable
V4->V5:
* Move to platform driver
V5->V6:
* Remove "fsl" from platform driver name
V6->V7:
* Remove GPT
* Remove of_match_ptr
V7->V8:
* Add help message
* Change to config to tristate
* Fix Makefile ordering
* Remove unused inlcude
* Remove imxrt_clocks_common_init
---
 drivers/clk/imx/Kconfig         |   7 ++
 drivers/clk/imx/Makefile        |   1 +
 drivers/clk/imx/clk-imxrt1050.c | 168 ++++++++++++++++++++++++++++++++
 3 files changed, 176 insertions(+)
 create mode 100644 drivers/clk/imx/clk-imxrt1050.c

diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
index c08edbd04d22..45641b8bdc50 100644
--- a/drivers/clk/imx/Kconfig
+++ b/drivers/clk/imx/Kconfig
@@ -105,3 +105,10 @@ config CLK_IMX8ULP
 	select MXC_CLK
 	help
 	    Build the driver for i.MX8ULP CCM Clock Driver
+
+config CLK_IMXRT1050
+	tristate "IMXRT1050 CCM Clock Driver"
+	depends on SOC_IMXRT
+	select MXC_CLK
+	help
+	    Build the driver for i.MXRT1050 CCM Clock Driver
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index b5e040026dfb..1e13c5cb37d9 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -46,4 +46,5 @@ obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o
 obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
 obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
 obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
+obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o
 obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
new file mode 100644
index 000000000000..9539d35588ee
--- /dev/null
+++ b/drivers/clk/imx/clk-imxrt1050.c
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) 2021
+ * Author(s):
+ * Jesse Taube <Mr.Bossman075 at gmail.com>
+ * Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+
+#include "clk.h"
+
+static const char * const pll_ref_sels[] = {"osc", "dummy", };
+static const char * const per_sels[] = {"ipg_pdof", "osc", };
+static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
+static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
+static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
+static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
+static const char *const pre_periph_sels[] = {
+	"pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
+static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
+static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
+static const char *const lcdif_sels[] = {
+	"pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
+	"pll2_pfd1_594m", "pll3_pfd1_664_62m", };
+static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
+static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
+
+static struct clk_hw **hws;
+static struct clk_hw_onecell_data *clk_hw_data;
+
+static int imxrt1050_clocks_probe(struct platform_device *pdev)
+{
+	void __iomem *ccm_base;
+	void __iomem *pll_base;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *anp;
+	int ret;
+
+	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+					  IMXRT1050_CLK_END), GFP_KERNEL);
+	if (WARN_ON(!clk_hw_data))
+		return -ENOMEM;
+
+	clk_hw_data->num = IMXRT1050_CLK_END;
+	hws = clk_hw_data->hws;
+
+	hws[IMXRT1050_CLK_OSC] = imx_obtain_fixed_clk_hw(np, "osc");
+
+	anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
+	pll_base = of_iomap(anp, 0);
+	of_node_put(anp);
+	if (WARN_ON(!pll_base))
+		return -ENOMEM;
+
+	/* Anatop clocks */
+	hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
+
+	hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
+		pll_base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
+		pll_base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
+		pll_base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+	hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
+		pll_base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+	hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
+		"pll1_arm_ref_sel", pll_base + 0x0, 0x7f);
+	hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
+		"pll2_sys_ref_sel", pll_base + 0x30, 0x1);
+	hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
+		"pll3_usb_otg_ref_sel", pll_base + 0x10, 0x1);
+	hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
+		"pll5_video_ref_sel", pll_base + 0xa0, 0x7f);
+
+	/* PLL bypass out */
+	hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", pll_base + 0x0, 16, 1,
+		pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", pll_base + 0x30, 16, 1,
+		pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", pll_base + 0x10, 16, 1,
+		pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
+	hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", pll_base + 0xa0, 16, 1,
+		pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
+
+	hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
+		"pll5_video", pll_base + 0xa0, 19, 2);
+	hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
+		"video_post_div_sel", pll_base + 0x170, 30, 2);
+
+	hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
+
+	hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", pll_base + 0x100, 0);
+	hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", pll_base + 0x100, 1);
+	hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", pll_base + 0x100, 2);
+	hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", pll_base + 0xf0, 1);
+	hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", pll_base + 0xf0, 3);
+
+	/* CCM clocks */
+	ccm_base = devm_platform_ioremap_resource(pdev, 0);
+	if (WARN_ON(IS_ERR(ccm_base)))
+		return PTR_ERR(ccm_base);
+
+	hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
+	hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
+		pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
+	hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
+		periph_sels, ARRAY_SIZE(periph_sels));
+	hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
+		usdhc_sels, ARRAY_SIZE(usdhc_sels));
+	hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
+		lpuart_sels, ARRAY_SIZE(lpuart_sels));
+	hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
+		lcdif_sels, ARRAY_SIZE(lcdif_sels));
+	hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
+		per_sels, ARRAY_SIZE(per_sels));
+	hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
+		semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
+	hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
+		semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
+
+	hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
+	hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
+	hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
+
+	hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
+	hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
+	hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
+	hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
+	hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
+
+	hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
+	hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
+	hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
+	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
+	hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
+	hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
+	imx_check_clk_hws(hws, IMXRT1050_CLK_END);
+
+	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
+		imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
+	}
+	return ret;
+}
+static const struct of_device_id imxrt1050_clk_of_match[] = {
+	{ .compatible = "fsl,imxrt1050-ccm" },
+	{ /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
+
+static struct platform_driver imxrt1050_clk_driver = {
+	.probe = imxrt1050_clocks_probe,
+	.driver = {
+		.name = "imxrt1050-ccm",
+		.of_match_table = imxrt1050_clk_of_match,
+	},
+};
+module_platform_driver(imxrt1050_clk_driver);
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:11 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:11 -0500
Subject: [PATCH v8 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-4-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add the clock binding doc for i.MXRT1050.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
[Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]
---
V1->V2:
* Nothing done
V2->V3:
* Added GPT binding
V3->V4:
* Change License to MIT or GPL-2
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Fix typo in numbering
* Remove GPT
V7->V8:
* Nothing done
---
 include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h

diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h
new file mode 100644
index 000000000000..93bef0832d16
--- /dev/null
+++ b/include/dt-bindings/clock/imxrt1050-clock.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright(C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMXRT1050_H
+#define __DT_BINDINGS_CLOCK_IMXRT1050_H
+
+#define IMXRT1050_CLK_DUMMY			0
+#define IMXRT1050_CLK_CKIL			1
+#define IMXRT1050_CLK_CKIH			2
+#define IMXRT1050_CLK_OSC			3
+#define IMXRT1050_CLK_PLL2_PFD0_352M		4
+#define IMXRT1050_CLK_PLL2_PFD1_594M		5
+#define IMXRT1050_CLK_PLL2_PFD2_396M		6
+#define IMXRT1050_CLK_PLL3_PFD0_720M		7
+#define IMXRT1050_CLK_PLL3_PFD1_664_62M		8
+#define IMXRT1050_CLK_PLL3_PFD2_508_24M		9
+#define IMXRT1050_CLK_PLL3_PFD3_454_74M		10
+#define IMXRT1050_CLK_PLL2_198M			11
+#define IMXRT1050_CLK_PLL3_120M			12
+#define IMXRT1050_CLK_PLL3_80M			13
+#define IMXRT1050_CLK_PLL3_60M			14
+#define IMXRT1050_CLK_PLL1_BYPASS		15
+#define IMXRT1050_CLK_PLL2_BYPASS		16
+#define IMXRT1050_CLK_PLL3_BYPASS		17
+#define IMXRT1050_CLK_PLL5_BYPASS		19
+#define IMXRT1050_CLK_PLL1_REF_SEL		20
+#define IMXRT1050_CLK_PLL2_REF_SEL		21
+#define IMXRT1050_CLK_PLL3_REF_SEL		22
+#define IMXRT1050_CLK_PLL5_REF_SEL		23
+#define IMXRT1050_CLK_PRE_PERIPH_SEL		24
+#define IMXRT1050_CLK_PERIPH_SEL		25
+#define IMXRT1050_CLK_SEMC_ALT_SEL		26
+#define IMXRT1050_CLK_SEMC_SEL			27
+#define IMXRT1050_CLK_USDHC1_SEL		28
+#define IMXRT1050_CLK_USDHC2_SEL		29
+#define IMXRT1050_CLK_LPUART_SEL		30
+#define IMXRT1050_CLK_LCDIF_SEL			31
+#define IMXRT1050_CLK_VIDEO_POST_DIV_SEL	32
+#define IMXRT1050_CLK_VIDEO_DIV			33
+#define IMXRT1050_CLK_ARM_PODF			34
+#define IMXRT1050_CLK_LPUART_PODF		35
+#define IMXRT1050_CLK_USDHC1_PODF		36
+#define IMXRT1050_CLK_USDHC2_PODF		37
+#define IMXRT1050_CLK_SEMC_PODF			38
+#define IMXRT1050_CLK_AHB_PODF			39
+#define IMXRT1050_CLK_LCDIF_PRED		40
+#define IMXRT1050_CLK_LCDIF_PODF		41
+#define IMXRT1050_CLK_USDHC1			42
+#define IMXRT1050_CLK_USDHC2			43
+#define IMXRT1050_CLK_LPUART1			44
+#define IMXRT1050_CLK_SEMC			45
+#define IMXRT1050_CLK_LCDIF_APB			46
+#define IMXRT1050_CLK_PLL1_ARM			47
+#define IMXRT1050_CLK_PLL2_SYS			48
+#define IMXRT1050_CLK_PLL3_USB_OTG		49
+#define IMXRT1050_CLK_PLL4_AUDIO		50
+#define IMXRT1050_CLK_PLL5_VIDEO		51
+#define IMXRT1050_CLK_PLL6_ENET			52
+#define IMXRT1050_CLK_PLL7_USB_HOST		53
+#define IMXRT1050_CLK_LCDIF_PIX			54
+#define IMXRT1050_CLK_USBOH3			55
+#define IMXRT1050_CLK_IPG_PDOF			56
+#define IMXRT1050_CLK_PER_CLK_SEL		57
+#define IMXRT1050_CLK_PER_PDOF			58
+#define IMXRT1050_CLK_DMA			59
+#define IMXRT1050_CLK_DMA_MUX			60
+#define IMXRT1050_CLK_END			61
+
+#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:15 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:15 -0500
Subject: [PATCH v8 7/7] ARM: imxrt_defconfig: Add i.MXRT family defconfig
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-8-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

Add generic i.MXRT family defconfig.

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1->V2:
* Nothing done
V2->V3:
* Nothing done
V3->V4:
* Remove unnecessary CONFIGs
* Add futex suport after "ARM: 9122/1: select HAVE_FUTEX_CMPXCHG"
9d417cbe36eee7afdd85c2e871685f8dab7c2dba
V4->V5:
* Change commit description
V5->V6:
* Nothing done
V6->V7:
* Nothing done
V7->V8:
* Nothing done
---
 arch/arm/configs/imxrt_defconfig | 35 ++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 arch/arm/configs/imxrt_defconfig

diff --git a/arch/arm/configs/imxrt_defconfig b/arch/arm/configs/imxrt_defconfig
new file mode 100644
index 000000000000..52dba3762996
--- /dev/null
+++ b/arch/arm/configs/imxrt_defconfig
@@ -0,0 +1,35 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_BPF_SYSCALL=y
+CONFIG_SCHED_AUTOGROUP=y
+# CONFIG_MMU is not set
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMXRT=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x80000000
+CONFIG_DRAM_SIZE=0x02000000
+CONFIG_BINFMT_FLAT=y
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_IMX_WEIM=y
+CONFIG_LEGACY_PTY_COUNT=2
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_PINCTRL_IMXRT1050=y
+CONFIG_GPIO_MXC=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
+CONFIG_CLK_IMXRT1050=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_EXFAT_FS=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_UTF8=y
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:54:14 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:54:14 -0500
Subject: [PATCH v8 6/7] ARM: dts: imx: Add i.MXRT1050-EVK support
In-Reply-To: <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
Message-ID: <20220111215415.2075257-7-Mr.Bossman075@gmail.com>

From: Giulio Benetti <giulio.benetti at benettiengineering.com>

The NXP i.MXRT1050 Evaluation Kit (EVK) provides a platform for rapid
evaluation of the i.MXRT, which features NXP's implementation of the Arm
Cortex-M7 core.

The EVK provides 32 MB SDRAM, 64 MB Quad SPI flash, Micro SD card socket,
USB 2.0 OTG.

This patch aims to support the preliminary booting up features
as follows:
GPIO
LPUART
SD/MMC

Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
[Jesse: Add clock-parents, edma, usdhc, anatop, remove old pinctl]
---
V1->V2:
* dtsi: Add clock parent definitions
* dtsi: Change hex values to lowercase
* dtsi: Move anatop definition from driver
* dts: Remove unused pin controll (semc)
* dts: Use moved pin controll header
* Move aliases from dtsi to dts
* Change commit description
* Change licence to "GPL-2.0+ OR MIT"
V2->V3:
* Remove bootargs, comments, unused container
* Remove unnecessary new lines
* Rename imxrt to imxrt1050 for seiral and mmc
* GPT uses own clock
* fix memory at 0
* Change GPT compatible handles
V3->V4:
* Remove "fsl,imx-osc"
* Add space on serial compatible
* Change "iomuxc@" to "pinctrl@"
* Change "ccm@" to "clock-controller@"
* Change "fsl,imxrt-gpio" to "fsl,imxrt1050-gpio"
V4->V5:
* Nothing done
V5->V6:
* Nothing done
V6->V7:
* Add fixed clock for GPT
* Fix lpuart compatible
* Add usdhc compatible
V7->V8:
* Nothing done
---
 arch/arm/boot/dts/Makefile          |   2 +
 arch/arm/boot/dts/imxrt1050-evk.dts |  72 +++++++++++++
 arch/arm/boot/dts/imxrt1050.dtsi    | 160 ++++++++++++++++++++++++++++
 3 files changed, 234 insertions(+)
 create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
 create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..07acd6189cae 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_IMXRT) += \
+	imxrt1050-evk.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/imxrt1050-evk.dts b/arch/arm/boot/dts/imxrt1050-evk.dts
new file mode 100644
index 000000000000..6a9c10decf52
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050-evk.dts
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+/dts-v1/;
+#include "imxrt1050.dtsi"
+#include "imxrt1050-pinfunc.h"
+
+/ {
+	model = "NXP IMXRT1050-evk board";
+	compatible = "fsl,imxrt1050-evk", "fsl,imxrt1050";
+
+	chosen {
+		stdout-path = &lpuart1;
+	};
+
+	aliases {
+		gpio0 = &gpio1;
+		gpio1 = &gpio2;
+		gpio2 = &gpio3;
+		gpio3 = &gpio4;
+		gpio4 = &gpio5;
+		mmc0 = &usdhc1;
+		serial0 = &lpuart1;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x2000000>;
+	};
+};
+
+&lpuart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lpuart1>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl_lpuart1: lpuart1grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD	0xf1
+			MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD	0xf1
+		>;
+	};
+
+	pinctrl_usdhc0: usdhc0grp {
+		fsl,pins = <
+			MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B		0x1B000
+			MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT	0xB069
+			MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1	0x17061
+			MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0	0x17061
+		>;
+	};
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
+	pinctrl-0 = <&pinctrl_usdhc0>;
+	pinctrl-1 = <&pinctrl_usdhc0>;
+	pinctrl-2 = <&pinctrl_usdhc0>;
+	pinctrl-3 = <&pinctrl_usdhc0>;
+	cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imxrt1050.dtsi b/arch/arm/boot/dts/imxrt1050.dtsi
new file mode 100644
index 000000000000..77b911b06041
--- /dev/null
+++ b/arch/arm/boot/dts/imxrt1050.dtsi
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019
+ * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
+ */
+
+#include "armv7-m.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/imxrt1050-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	clocks {
+		osc: osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <24000000>;
+		};
+
+		osc3M: osc3M {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <3000000>;
+		};
+	};
+
+	soc {
+		lpuart1: serial at 40184000 {
+			compatible = "fsl,imxrt1050-lpuart", "fsl,imx7ulp-lpuart";
+			reg = <0x40184000 0x4000>;
+			interrupts = <20>;
+			clocks = <&clks IMXRT1050_CLK_LPUART1>;
+			clock-names = "ipg";
+			status = "disabled";
+		};
+
+		iomuxc: pinctrl at 401f8000 {
+			compatible = "fsl,imxrt1050-iomuxc";
+			reg = <0x401f8000 0x4000>;
+			fsl,mux_mask = <0x7>;
+		};
+
+		anatop: anatop at 400d8000 {
+			compatible = "fsl,imxrt-anatop";
+			reg = <0x400d8000 0x4000>;
+		};
+
+		clks: clock-controller at 400fc000 {
+			compatible = "fsl,imxrt1050-ccm";
+			reg = <0x400fc000 0x4000>;
+			interrupts = <95>, <96>;
+			clocks = <&osc>;
+			clock-names = "osc";
+			#clock-cells = <1>;
+			assigned-clocks = <&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL1_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL2_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_BYPASS>,
+				<&clks IMXRT1050_CLK_PLL3_PFD1_664_62M>,
+				<&clks IMXRT1050_CLK_PLL2_PFD2_396M>;
+			assigned-clock-parents = <&clks IMXRT1050_CLK_PLL1_REF_SEL>,
+				<&clks IMXRT1050_CLK_PLL1_ARM>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
+				<&clks IMXRT1050_CLK_PLL2_SYS>;
+		};
+
+		edma1: dma-controller at 400e8000 {
+			#dma-cells = <2>;
+			compatible = "fsl,imx7ulp-edma";
+			reg = <0x400e8000 0x4000>,
+				<0x400ec000 0x4000>;
+			dma-channels = <32>;
+			interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>,
+				<9>, <10>, <11>, <12>, <13>, <14>, <15>, <16>;
+			clock-names = "dma", "dmamux0";
+			clocks = <&clks IMXRT1050_CLK_DMA>,
+				 <&clks IMXRT1050_CLK_DMA_MUX>;
+		};
+
+		usdhc1: mmc at 402c0000 {
+			compatible ="fsl,imxrt1050-usdhc", "fsl,imx6sl-usdhc";
+			reg = <0x402c0000 0x4000>;
+			interrupts = <110>;
+			clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
+				<&clks IMXRT1050_CLK_OSC>,
+				<&clks IMXRT1050_CLK_USDHC1>;
+			clock-names = "ipg", "ahb", "per";
+			bus-width = <4>;
+			fsl,wp-controller;
+			no-1-8-v;
+			max-frequency = <4000000>;
+			fsl,tuning-start-tap = <20>;
+			fsl,tuning-step= <2>;
+			status = "disabled";
+		};
+
+		gpio1: gpio at 401b8000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401b8000 0x4000>;
+			interrupts = <80>, <81>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio at 401bc000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401bc000 0x4000>;
+			interrupts = <82>, <83>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio at 401c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c0000 0x4000>;
+			interrupts = <84>, <85>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio4: gpio at 401c4000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x401c4000 0x4000>;
+			interrupts = <86>, <87>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio5: gpio at 400c0000 {
+			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
+			reg = <0x400c0000 0x4000>;
+			interrupts = <88>, <89>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpt: timer at 401ec000 {
+			compatible = "fsl,imxrt1050-gpt", "fsl,imx6dl-gpt", "fsl,imx6sl-gpt";
+			reg = <0x401ec000 0x4000>;
+			interrupts = <100>;
+			clocks = <&osc3M>;
+			clock-names = "per";
+		};
+	};
+};
-- 
2.34.1



From mr.bossman075 at gmail.com  Tue Jan 11 13:57:42 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Tue, 11 Jan 2022 16:57:42 -0500
Subject: [PATCH v7 0/7] Add initial support for the i.MXRTxxxx SoC family
 starting from i.IMXRT1050 SoC.
In-Reply-To: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
Message-ID: <fc0169c3-eea7-e067-784b-eebeccee13b8@gmail.com>



On 1/11/22 16:25, Jesse Taube wrote:
> This patchset contains:
> - i.MXRT10xx family infrastructure
> - i.MXRT1050 pinctrl driver adaption
> - i.MXRT1050 clock driver adaption
> - i.MXRT1050 sd-card driver adaption
> - i.MXRT1050 uart driver adaption
> - i.MXRT1050-evk basic support
> 
> The i.MXRTxxxx family that could have support by Linux actually spreads
> from i.MXRT1020 to i.MXRT1170 with the first one supporting 1 USB OTG &
> 100M ethernet with a cortex-M7 at 500Mhz up to the latter with i.MXRT1170
> with cortex-M7 at 1Ghz and cortex-M4 at 400Mhz, 2MB of internal SRAM, 2D GPU,
> 2x 1Gb and 1x 100Mb ENET. The i.MXRT family is NXP's answer to
> STM32F7XX, as it uses only simple SDRAM, it gives the chance of a 4 or
> less layer PCBs. Seeing that these chips are comparable to the
> STM32F7XXs which have linux ported to them it seems reasonable to add
> support for them.
> 
> Giving Linux support to this family should ease the development process,
> instead of using a RTOS they could use Embedded Linux allowing for more
> portability, ease of design and will broaden the scope of people using
> embedded linux.
> 
> The EVK has very little SDRAM, generally 32MB starting from
> i.MXRT1020(the lowest P/N), although the i.MXRT1160/70 provide instead
> 64MB of SDRAM for more functionality.
> 
> At the moment we do not support XIP for either u-boot or Linux but it
> should be done in the future. XIP will also save SDRAM.
> 
> Another interesting fact is the amount of internal SRAM, as the P/N
> increases the SRAM will reach up to 2MB(some could be for cache and
> some would be for video).
> 
> Also, some parts have embed flash of 4MB that can be used for
> u-boot/Linux, if both correctly sized it will leave the SDRAM free.
> 
> External flash can be Quad SPI and HyperFlash, so throughput would be
> decent.
> 
> The i.MXRT11xx series supports MIPI interface too.
> 
> The family in general provide CAN bus, audio I/O, 1 or more
> USB(otg/host), 1 or more 100Mb/1Gb ethernet, camera interface, sd-card.
> 
> All this can be used for simple GUIs, web-servers, point-of-sale
> stations, etc.
> 
> 
> Giulio Benetti (4):
>    ARM: imx: Add initial support for i.MXRT10xx family
>    dt-bindings: imx: Add clock binding for i.MXRT1050
>    ARM: dts: imx: Add i.MXRT1050-EVK support
>    ARM: imxrt_defconfig: Add i.MXRT family defconfig
> 
> Jesse Taube (3):
>    ARM: dts: imxrt1050-pinfunc: Add pinctrl binding header
>    dt-bindings: clock: imx: Add documentation for i.MXRT1050 clock
>    clk: imx: Add initial support for i.MXRT1050 clock driver
> 
>   .../bindings/clock/imxrt1050-clock.yaml       |  67 ++
>   arch/arm/boot/dts/Makefile                    |   2 +
>   arch/arm/boot/dts/imxrt1050-evk.dts           |  72 ++
>   arch/arm/boot/dts/imxrt1050-pinfunc.h         | 993 ++++++++++++++++++
>   arch/arm/boot/dts/imxrt1050.dtsi              | 160 +++
>   arch/arm/configs/imxrt_defconfig              |  35 +
>   arch/arm/mach-imx/Kconfig                     |   7 +
>   arch/arm/mach-imx/Makefile                    |   2 +
>   arch/arm/mach-imx/mach-imxrt.c                |  19 +
>   drivers/clk/imx/Kconfig                       |   7 +
>   drivers/clk/imx/Makefile                      |   1 +
>   drivers/clk/imx/clk-imxrt1050.c               | 168 +++
>   include/dt-bindings/clock/imxrt1050-clock.h   |  72 ++
>   13 files changed, 1605 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
>   create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
>   create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
>   create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi
>   create mode 100644 arch/arm/configs/imxrt_defconfig
>   create mode 100644 arch/arm/mach-imx/mach-imxrt.c
>   create mode 100644 drivers/clk/imx/clk-imxrt1050.c
>   create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h
> 

Oh No!
I'm very sorry I sent v8 under the wrong version number. I sent it again...

Sincerely,
	Jesse Taube



From robh at kernel.org  Tue Jan 11 14:21:26 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:21:26 -0600
Subject: [PATCH v2 3/4] regulator: dt-bindings: maxim,max14577: convert
 to dtschema
In-Reply-To: <20220111174337.223320-4-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
 <20220111174337.223320-4-krzysztof.kozlowski@canonical.com>
Message-ID: <Yd4C5mx/FzBpB6Bm@robh.at.kernel.org>

On Tue, 11 Jan 2022 18:43:36 +0100, Krzysztof Kozlowski wrote:
> Convert the regulator bindings of Maxim MAX14577/MAX77835 MUIC to DT
> schema format.  The existing bindings were defined in
> ../bindings/mfd/max14577.txt.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/regulator/maxim,max14577.yaml    | 92 +++++++++++++++++++
>  1 file changed, 92 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max14577.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 14:21:57 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:21:57 -0600
Subject: [PATCH v2 3/5] regulator: dt-bindings: maxim,max77843: add
 MAX77843 bindings
In-Reply-To: <20220111174805.223732-4-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
 <20220111174805.223732-4-krzysztof.kozlowski@canonical.com>
Message-ID: <Yd4DBfhJcNgazdpG@robh.at.kernel.org>

On Tue, 11 Jan 2022 18:48:03 +0100, Krzysztof Kozlowski wrote:
> Document the bindings for MAX77843 regulator driver.  The bindings are
> almost identical to MAX77693 bindings, except the actual names of
> regulators.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/regulator/maxim,max77843.yaml    | 65 +++++++++++++++++++
>  1 file changed, 65 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/regulator/maxim,max77843.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From yuzhao at google.com  Tue Jan 11 14:27:08 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 11 Jan 2022 15:27:08 -0700
Subject: [PATCH v6 1/9] mm: x86, arm64: add arch_has_hw_pte_young()
In-Reply-To: <20220111141901.GA10338@willie-the-truck>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-2-yuzhao@google.com>
 <20220105104526.GA3015@willie-the-truck>
 <YdYDzKvYbBwjfU3W@google.com>
 <20220106103009.GA4420@willie-the-truck>
 <Ydfq051mnCeZjG3G@google.com>
 <20220111141901.GA10338@willie-the-truck>
Message-ID: <Yd4EPGM+Uj6iDu1l@google.com>

On Tue, Jan 11, 2022 at 02:19:02PM +0000, Will Deacon wrote:
> On Fri, Jan 07, 2022 at 12:25:07AM -0700, Yu Zhao wrote:
> > On Thu, Jan 06, 2022 at 10:30:09AM +0000, Will Deacon wrote:
> > > On Wed, Jan 05, 2022 at 01:47:08PM -0700, Yu Zhao wrote:
> > > > On Wed, Jan 05, 2022 at 10:45:26AM +0000, Will Deacon wrote:
> > > > > On Tue, Jan 04, 2022 at 01:22:20PM -0700, Yu Zhao wrote:
> > > > > > diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> > > > > > index 870c39537dd0..56e4ef5d95fa 100644
> > > > > > --- a/arch/arm64/tools/cpucaps
> > > > > > +++ b/arch/arm64/tools/cpucaps
> > > > > > @@ -36,6 +36,7 @@ HAS_STAGE2_FWB
> > > > > >  HAS_SYSREG_GIC_CPUIF
> > > > > >  HAS_TLB_RANGE
> > > > > >  HAS_VIRT_HOST_EXTN
> > > > > > +HW_AF
> > > > > >  HW_DBM
> > > > > >  KVM_PROTECTED_MODE
> > > > > >  MISMATCHED_CACHE_TYPE
> > > > > 
> > > > > As discussed in the previous threads, we really don't need the complexity
> > > > > of the additional cap for the arm64 part. Please can you just use the
> > > > > existing code instead? It's both simpler and, as you say, it's equivalent
> > > > > for existing hardware.
> > > > > 
> > > > > That way, this patch just ends up being a renaming exercise and we're all
> > > > > good.
> > > > 
> > > > No, renaming alone isn't enough. A caller needs to disable preemption
> > > > before calling system_has_hw_af(), and I don't think it's reasonable
> > > > to ask this caller to do it on x86 as well.
> > > > 
> > > > It seems you really prefer not to have HW_AF. So the best I can
> > > > accommodate, considering other potential archs, e.g., risc-v (I do
> > > > plan to provide benchmark results on risc-v, btw), is:
> > > > 
> > > >   static inline bool arch_has_hw_pte_young(bool local)
> > > >   {
> > > > 	bool hw_af;
> > > > 
> > > >   	if (local) {
> > > >   		WARN_ON(preemptible());
> > > >   		return cpu_has_hw_af();
> > > >   	}
> > > >   
> > > > 	preempt_disable();
> > > >   	hw_af = system_has_hw_af();
> > > > 	preempt_enable();
> > > > 
> > > > 	return hw_af;
> > > >   }
> > > > 
> > > > Or please give me something else I can call without disabling
> > > > preemption, sounds good?
> > > 
> > > Sure thing, let me take a look. Do you have your series on a public git
> > > tree someplace?
> > 
> > Thanks!
> > 
> > This patch (updated) on Gerrit:
> > https://linux-mm-review.googlesource.com/c/page-reclaim/+/1500/1
> 
> How about folding in something like the diff below? I've basically removed
> that 'bool local' argument and dropped the preemptible() check from the
> arm64 code.

This looks great, thanks.


From robh at kernel.org  Tue Jan 11 14:54:50 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:54:50 -0600
Subject: [PATCH v2 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220103163956.6581-3-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-3-christianshewitt@gmail.com>
Message-ID: <Yd4KulrOCjS4PdWG@robh.at.kernel.org>

On Mon, 03 Jan 2022 16:39:49 +0000, Christian Hewitt wrote:
> Add board bindings for the Amediatech X96-AIR STB which ships with
> model variants distiguished by Ethernet configuration: models using
> an external Gigabit PHY have a -gbit suffix, while models using an
> internal 10/100 PHY have no suffix.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 14:55:40 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 16:55:40 -0600
Subject: [PATCH v2 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220103163956.6581-6-christianshewitt@gmail.com>
References: <20220103163956.6581-1-christianshewitt@gmail.com>
 <20220103163956.6581-6-christianshewitt@gmail.com>
Message-ID: <Yd4K7PqBM/qNLDkI@robh.at.kernel.org>

On Mon, Jan 03, 2022 at 04:39:52PM +0000, Christian Hewitt wrote:
> Add board bindings for the CYX A95XF3-AIR set-top box which ships
> with model variants distiguished by Ethernet configuration: models

typo: distinguished

> using external Gigabit PHY have a -gbit suffix, while models using
> an internal 10/100 PHY have no suffix.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Otherwise,

Acked-by: Rob Herring <robh at kernel.org>


From yuzhao at google.com  Tue Jan 11 15:16:57 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 11 Jan 2022 16:16:57 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdxKORU9OWCv114O@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <YdxKORU9OWCv114O@dhcp22.suse.cz>
Message-ID: <Yd4P6bEJI8YlXq0H@google.com>

On Mon, Jan 10, 2022 at 04:01:13PM +0100, Michal Hocko wrote:
> On Thu 06-01-22 17:12:18, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > > +{
> > > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> 
> One thing I have overlooked completely.

I appreciate your attention to details but GFP_KERNEL is legit in the
reclaim path. It's been used many years in our production, e.g.,
  page reclaim
    swap_writepage()
      frontswap_store()
        zswap_frontswap_store()
          zswap_entry_cache_alloc(GFP_KERNEL)

(And I always test my changes with lockdep, kasan, DEBUG_VM, etc., no
 warnings ever seen from using GFP_KERNEL in the reclaim path.)

> You cannot really use GFP_KERNEL
> allocation here because the reclaim context can be constrained (e.g.
> GFP_NOFS). This allocation will not do any reclaim as it is PF_MEMALLOC
> but I suspect that the lockdep will complain anyway.
> 
> Also kvmalloc is not really great here. a) vmalloc path is never
> executed for small objects and b) we do not really want to make a
> dependency between vmalloc and the reclaim (by vmalloc -> reclaim ->
> vmalloc).
> 
> Even if we rule out vmalloc and look at kmalloc alone. Is this really
> safe? I do not see any recursion prevention in the SL.B code. Maybe this
> just happens to work but the dependency should be really documented so
> that future SL.B changes won't break the whole scheme. 

Affirmative, as Vlastimil has clarified.

Thanks!


From robh at kernel.org  Tue Jan 11 15:36:55 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 17:36:55 -0600
Subject: [PATCH net-next v10 6/6] net: dt-bindings: dwmac: add support for
 mt8195
In-Reply-To: <be023f9d2fb2a8f947bd0075e8732ba07cfd7b89.camel@mediatek.com>
References: <20211216055328.15953-1-biao.huang@mediatek.com>
 <20211216055328.15953-7-biao.huang@mediatek.com>
 <1639662782.987227.4004875.nullmailer@robh.at.kernel.org>
 <be023f9d2fb2a8f947bd0075e8732ba07cfd7b89.camel@mediatek.com>
Message-ID: <CAL_JsqLo7z-KWtwFx+Kng2aQuCpQwJaO6mHnyBzmCKCJDK5n+Q@mail.gmail.com>

On Thu, Dec 16, 2021 at 8:06 PM Biao Huang <biao.huang at mediatek.com> wrote:
>
> Dear Rob,
>   Thanks for your comments~
>
>   For mt8195, the eth device node will look like:
>   eth: ethernet at 11021000 {
>     compatible = "mediatek,mt8195-gmac", "snps,dwmac-5.10a";
>     ...
>     clock-names = "axi",
>                   "apb",
>                   "mac_cg",
>                   "mac_main",
>                   "ptp_ref",
>                   "rmii_internal";
>     clocks = <&pericfg_ao CLK_PERI_AO_ETHERNET>,
>              <&pericfg_ao CLK_PERI_AO_ETHERNET_BUS>,
>              <&pericfg_ao CLK_PERI_AO_ETHERNET_MAC>,
>              <&topckgen CLK_TOP_SNPS_ETH_250M>,
>              <&topckgen CLK_TOP_SNPS_ETH_62P4M_PTP>,
>              <&topckgen CLK_TOP_SNPS_ETH_50M_RMII>;
>     ...
>   }
>
> 1. "rmii_internal" is a special clock only required for
>    RMII phy interface, dwmac-mediatek.c will enable clocks
>    invoking clk_bulk_prepare_enable(xx, 6) for RMII,
>    and clk_bulk_prepare_enable(xx, 5) for other phy interfaces.
>    so, mt2712/mt8195 all put "rmii_internal" clock to the
>    end of clock list to simplify clock handling.
>
>    If I put mac_cg as described above, a if condition is required
> for clocks description in dt-binding, just like what I do in v7 send:
>   - if:
>       properties:
>         compatible:
>           contains:
>             enum:
>               - mediatek,mt2712-gmac
>
>     then:
>       properties:
>         clocks:
>           minItems: 5
>           items:
>             - description: AXI clock
>             - description: APB clock
>             - description: MAC Main clock
>             - description: PTP clock
>             - description: RMII reference clock provided by MAC
>
>         clock-names:
>           minItems: 5
>           items:
>             - const: axi
>             - const: apb
>             - const: mac_main
>             - const: ptp_ref
>             - const: rmii_internal
>
>   - if:
>       properties:
>         compatible:
>           contains:
>             enum:
>               - mediatek,mt8195-gmac
>
>     then:
>       properties:
>         clocks:
>           minItems: 6
>           items:
>             - description: AXI clock
>             - description: APB clock
>             - description: MAC clock gate
>             - description: MAC Main clock
>             - description: PTP clock
>             - description: RMII reference clock provided by MAC
>
>    This introduces some duplicated description.
>
> 2. If I put "mac_cg" to the end of clock list,
>    the dt-binding file can be simple just like
>    what we do in this v10 patch(need fix warnings reported by "make
> DT_CHECKER_FLAGS=-m dt_binding_check").
>
>    But for mt8195:
>      the eth node in dts should be modified,

I hope you are defining the binding before you use it... That's not
good practice and not a valid argument.

>      and eth driver clock handling will be complex;

How so?

Rob


From joel at jms.id.au  Tue Jan 11 16:51:53 2022
From: joel at jms.id.au (Joel Stanley)
Date: Wed, 12 Jan 2022 00:51:53 +0000
Subject: [PATCH] media: aspeed: Fix no complete irq for non-64-aligned
 width
In-Reply-To: <20211214045348.13702-1-jammy_huang@aspeedtech.com>
References: <20211214045348.13702-1-jammy_huang@aspeedtech.com>
Message-ID: <CACPK8XfkXi6M=gzfkYcuoga6WxnzSm2+mspBt4gjop7Ytm+VCA@mail.gmail.com>

On Tue, 14 Dec 2021 at 04:53, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>
> In ast2500, engine will stop occasionally for 1360x768.
>
> This is a bug which has been addressed, but the workaround is specific
> for 1680 only. Here we make it more complete.
>
> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
> ---
>  drivers/media/platform/aspeed-video.c | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
> index 793b2adaa0f5..4d3e6b105d44 100644
> --- a/drivers/media/platform/aspeed-video.c
> +++ b/drivers/media/platform/aspeed-video.c
> @@ -1055,18 +1055,20 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
>         /* Set capture/compression frame sizes */
>         aspeed_video_calc_compressed_size(video, size);
>
> -       if (video->active_timings.width == 1680) {
> +       if (!IS_ALIGNED(act->width, 64)) {
>                 /*
>                  * This is a workaround to fix a silicon bug on A1 and A2

Please add:  "a AST2500 silicon bug" so we know which A1/A2 this is
referring to.

With that added, you can add:

 Reviewed-by: Joel Stanley <joel at jms.id.au>

>                  * revisions. Since it doesn't break capturing operation of
>                  * other revisions, use it for all revisions without checking
> -                * the revision ID. It picked 1728 which is a very next
> -                * 64-pixels aligned value to 1680 to minimize memory bandwidth
> +                * the revision ID. It picked new width which is a very next
> +                * 64-pixels aligned value to minimize memory bandwidth
>                  * and to get better access speed from video engine.
>                  */
> +               u32 width = ALIGN(act->width, 64);
> +
>                 aspeed_video_write(video, VE_CAP_WINDOW,
> -                                  1728 << 16 | act->height);
> -               size += (1728 - 1680) * video->active_timings.height;
> +                                  width << 16 | act->height);
> +               size = width * act->height;

You could make it clearer by putting the write on one line:

                aspeed_video_write(video, VE_CAP_WINDOW, width << 16 |
act->height);


From joel at jms.id.au  Tue Jan 11 16:53:12 2022
From: joel at jms.id.au (Joel Stanley)
Date: Wed, 12 Jan 2022 00:53:12 +0000
Subject: [PATCH v1 1/1] gpio: gpio-aspeed-sgpio: Fix wrong hwirq base in
 irq handler
In-Reply-To: <CAMRc=McjZZTMjR+riwjj6SLEh=fYq0yjBQYNgzGXHok6=OTz_w@mail.gmail.com>
References: <20211214040239.8977-1-steven_lee@aspeedtech.com>
 <20211214040239.8977-2-steven_lee@aspeedtech.com>
 <CAMRc=MdAgK7zKuJ=7cA2T-mSTJD3tWSW2aEB6G=0Tz4X+iHcZQ@mail.gmail.com>
 <CAMRc=McjZZTMjR+riwjj6SLEh=fYq0yjBQYNgzGXHok6=OTz_w@mail.gmail.com>
Message-ID: <CACPK8XdXkrTfsMoZRDjQ_-MwOQ-no_B2yG3F79_SkQ0o6mGuQg@mail.gmail.com>

On Mon, 3 Jan 2022 at 09:50, Bartosz Golaszewski <brgl at bgdev.pl> wrote:
>
> On Wed, Dec 22, 2021 at 10:18 AM Bartosz Golaszewski <brgl at bgdev.pl> wrote:
> >
> > On Tue, Dec 14, 2021 at 5:03 AM Steven Lee <steven_lee at aspeedtech.com> wrote:
> > >
> > > Each aspeed sgpio bank has 64 gpio pins(32 input pins and 32 output pins).
> > > The hwirq base for each sgpio bank should be multiples of 64 rather than
> > > multiples of 32.
> > >
> > > Signed-off-by: Steven Lee <steven_lee at aspeedtech.com>
> > > ---
> > >  drivers/gpio/gpio-aspeed-sgpio.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
> > > index 3d6ef37a7702..b3a9b8488f11 100644
> > > --- a/drivers/gpio/gpio-aspeed-sgpio.c
> > > +++ b/drivers/gpio/gpio-aspeed-sgpio.c
> > > @@ -395,7 +395,7 @@ static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
> > >                 reg = ioread32(bank_reg(data, bank, reg_irq_status));
> > >
> > >                 for_each_set_bit(p, &reg, 32)
> > > -                       generic_handle_domain_irq(gc->irq.domain, i * 32 + p * 2);
> > > +                       generic_handle_domain_irq(gc->irq.domain, (i * 32 + p) * 2);
> > >         }
> > >
> > >         chained_irq_exit(ic, desc);
> > > --
> > > 2.17.1
> > >
> >
> > Joel, Andrew: any comments on this? I'd like to send it upstream tomorrow.
> >
> > Bart
>
> I don't want to delay it anymore, it looks good so I queued it for fixes.

Thanks for queuing. We were on leave over the holiday break, so no
time for reviewing kernel patches.

Cheers,

Joel


From yuzhao at google.com  Tue Jan 11 17:01:29 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 11 Jan 2022 18:01:29 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz>
Message-ID: <Yd4oaUwHkpadAKwe@google.com>

On Mon, Jan 10, 2022 at 05:57:39PM +0100, Michal Hocko wrote:
> On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> [...]
> > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > +{
> > +	static const struct mm_walk_ops mm_walk_ops = {
> > +		.test_walk = should_skip_vma,
> > +		.p4d_entry = walk_pud_range,
> > +	};
> > +
> > +	int err;
> > +#ifdef CONFIG_MEMCG
> > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > +#endif
> > +
> > +	walk->next_addr = FIRST_USER_ADDRESS;
> > +
> > +	do {
> > +		unsigned long start = walk->next_addr;
> > +		unsigned long end = mm->highest_vm_end;
> > +
> > +		err = -EBUSY;
> > +
> > +		rcu_read_lock();
> > +#ifdef CONFIG_MEMCG
> > +		if (memcg && atomic_read(&memcg->moving_account))
> > +			goto contended;
> > +#endif
> 
> Why do you need to check for moving_account?

This check, if succeeds, blocks memcg migration.

Our goal is to move pages between different generations of the same
lruvec (the first arg). Meanwhile, pages can also be migrated between
different memcgs (different lruvecs).

The active/inactive lru uses isolation to block memcg migration.

Generations account pages similarly to the active/inactive lru, i.e.,
each generation has nr_pages counter. However, unlike the active/
inactive lru, a page can be moved to a different generation without
getting isolated or even without being under the lru lock, as long as
the delta is eventually accounted for (which does require the lru lock
when it happens).

The generation counter in page->flags (folio->flags to be precise)
stores 0 when a page is isolated, to synchronize with isolation.


From robh at kernel.org  Tue Jan 11 17:03:27 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:03:27 -0600
Subject: [PATCH 5/7] dt-bindings: mailbox: imx-mu: add i.MX8 SECO MU
 support
In-Reply-To: <20220104062547.2103016-6-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
 <20220104062547.2103016-6-peng.fan@oss.nxp.com>
Message-ID: <Yd4o3+LesMIc3RLP@robh.at.kernel.org>

On Tue, 04 Jan 2022 14:25:45 +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Similar to i.MX8QM/QXP SCU, i.MX8 SECO MU is dedicated for
> communication between SECO and Cortex-A cores from hardware design,
> it could not be reused for other purpose. To use SECO MU more
> effectivly, add "fsl,imx8-mu-seco" compatile to support fast IPC.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  Documentation/devicetree/bindings/mailbox/fsl,mu.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From zev at bewilderbeest.net  Tue Jan 11 17:14:38 2022
From: zev at bewilderbeest.net (Zev Weiss)
Date: Tue, 11 Jan 2022 17:14:38 -0800
Subject: [PATCH] ARM: dts: aspeed: Add ASRock ROMED8HM3 BMC
In-Reply-To: <CACPK8XeHyoo0D1vQm=L8m284kC5n-O+FEMp1HN+ROWJfx7qjhQ@mail.gmail.com>
References: <20220105101719.7093-1-zev@bewilderbeest.net>
 <CACPK8XeHyoo0D1vQm=L8m284kC5n-O+FEMp1HN+ROWJfx7qjhQ@mail.gmail.com>
Message-ID: <Yd4rfi/iICQ5EjGh@hatter.bewilderbeest.net>

On Tue, Jan 11, 2022 at 02:59:28AM PST, Joel Stanley wrote:
>On Wed, 5 Jan 2022 at 23:10, Zev Weiss <zev at bewilderbeest.net> wrote:
>>
>> This is a half-width, single-socket Epyc server board with an AST2500
>> BMC.  This device tree is sufficient for basic OpenBMC functionality,
>> but we'll need to add a few more devices (as driver support becomes
>> available) before it's fully usable.
>>
>> Signed-off-by: Zev Weiss <zev at bewilderbeest.net>
>
>Reviewed-by: Joel Stanley <joel at jms.id.au>
>

Thanks!

>Have you considered using the openbmc gpio naming scheme for the
>gpio-line-names?
>

I looked at it, but decided not to for a few reasons:

  - For systems that are in the early stages of a porting effort (like 
    this one currently is), I'm still referring to hardware schematics 
    fairly often, and using the same identifiers in software that are 
    used in the schematics simplifies things by avoiding an extra
    translation step between the two.

  - Most of the GPIO-related userspace components (that I'm dealing with 
    anyway, e.g. x86-power-control and host-error-monitor) already have 
    their own GPIO line-name configuration/remapping mechanisms that need 
    to be set up anyway.

  - There's a solid mix of GPIOs that would be covered by the naming 
    guidelines and others that aren't; having a mix of the two styles 
    seems a bit awkward to me.

That said, I sympathize with the motivation behind it and I'm not 
vehemently opposed on the whole, so if there's a strong preference to 
follow that scheme I could probably be talked into changing it.


Zev



From robh at kernel.org  Tue Jan 11 17:20:48 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:20:48 -0600
Subject: [PATCH 1/4] dt-bindings: dma: Add bindings for ox810se dma engine
In-Reply-To: <20220104145206.135524-2-narmstrong@baylibre.com>
References: <20220104145206.135524-1-narmstrong@baylibre.com>
 <20220104145206.135524-2-narmstrong@baylibre.com>
Message-ID: <Yd4s8OYf7QSryXzr@robh.at.kernel.org>

On Tue, Jan 04, 2022 at 03:52:03PM +0100, Neil Armstrong wrote:
> This adds the YAML dt-bindings for the DMA engine found in the
> Oxford Semiconductor OX810SE SoC.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../bindings/dma/oxsemi,ox810se-dma.yaml      | 97 +++++++++++++++++++
>  1 file changed, 97 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
> 
> diff --git a/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml b/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
> new file mode 100644
> index 000000000000..6efa28e8b124
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/dma/oxsemi,ox810se-dma.yaml
> @@ -0,0 +1,97 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/dma/oxsemi,ox810se-dma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Oxford Semiconductor DMA Controller Device Tree Bindings
> +
> +maintainers:
> +  - Neil Armstrong <narmstrong at baylibre.com>
> +
> +allOf:
> +  - $ref: "dma-controller.yaml#"
> +
> +properties:
> +  "#dma-cells":
> +    const: 1
> +
> +  compatible:
> +    const: oxsemi,ox810se-dma
> +
> +  reg:
> +    maxItems: 2
> +
> +  reg-names:
> +    items:
> +      - const: dma
> +      - const: sgdma
> +
> +  interrupts:
> +    maxItems: 5

Need to define what each one is.

> +
> +  clocks:
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 2
> +
> +  reset-names:
> +    items:
> +      - const: dma
> +      - const: sgdma
> +
> +  dma-channels: true

Constraints on number of channels?

> +
> +  oxsemi,targets-types:
> +    description:
> +      Table with allowed memory ranges and memory type associated.
> +    $ref: "/schemas/types.yaml#/definitions/uint32-matrix"
> +    minItems: 4
> +    items:
> +      items:
> +        - description:
> +            The first cell defines the memory range start address
> +        - description:
> +            The first cell defines the memory range end address
> +        - description:
> +            The third cell represents memory type, 0 for SATA,
> +            1 for DPE RX, 2 for DPE TX, 5 for AUDIO TX, 6 for AUDIO RX,
> +            15 for DRAM MEMORY.
> +          enum: [ 0, 1, 2, 5, 6, 15 ]
> +
> +required:
> +  - "#dma-cells"
> +  - dma-channels
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +  - reset-names
> +  - oxsemi,targets-types
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    dma: dma-controller at 600000 {

Drop unused labels.

> +        compatible = "oxsemi,ox810se-dma";
> +        reg = <0x600000 0x100000>, <0xc00000 0x100000>;
> +        reg-names = "dma", "sgdma";
> +        interrupts = <13>, <14>, <15>, <16>, <20>;
> +        clocks = <&stdclk 1>;
> +        resets = <&reset 8>, <&reset 24>;
> +        reset-names = "dma", "sgdma";
> +
> +        /* Encodes the authorized memory types */
> +        oxsemi,targets-types =
> +            <0x45900000 0x45a00000 0>,  /* SATA */
> +            <0x42000000 0x43000000 0>,  /* SATA DATA */
> +            <0x48000000 0x58000000 15>, /* DDR */
> +            <0x58000000 0x58020000 15>; /* SRAM */
> +
> +        #dma-cells = <1>;
> +        dma-channels = <5>;
> +    };
> +...
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Tue Jan 11 17:23:19 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:23:19 -0600
Subject: [PATCH net-next v2 1/3] dt-bindings: net: oxnas-dwmac: Add
 bindings for OX810SE
In-Reply-To: <20220104145646.135877-2-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
 <20220104145646.135877-2-narmstrong@baylibre.com>
Message-ID: <Yd4th9QfJO62KkQC@robh.at.kernel.org>

On Tue, 04 Jan 2022 15:56:44 +0100, Neil Armstrong wrote:
> Add SoC specific bindings for OX810SE support.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  Documentation/devicetree/bindings/net/oxnas-dwmac.txt | 3 +++
>  1 file changed, 3 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:24:36 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:24:36 -0600
Subject: [PATCH v2 2/2] sunxi.yaml: add HAOYU Electronics Marsboard A20
In-Reply-To: <tencent_9A79E4BC3715D4948E6D69363916D4B26D0A@qq.com>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <20220105024551.807713-1-conleylee@foxmail.com>
 <tencent_9A79E4BC3715D4948E6D69363916D4B26D0A@qq.com>
Message-ID: <Yd4t1NTa/ZEDsUyz@robh.at.kernel.org>

On Wed, Jan 05, 2022 at 10:45:51AM +0800, conleylee at foxmail.com wrote:
> From: conley <conleylee at foxmail.com>

Need a full name here and a commit message.

> 
> Signed-off-by: conley <conleylee at foxmail.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index 889128acf49a..4bd93ae26bd1 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -444,6 +444,11 @@ properties:
>            - const: haoyu,a10-marsboard
>            - const: allwinner,sun4i-a10
>  
> +      - description: HAOYU Electronics Marsboard A20
> +        items:
> +          - const: haoyu,a20-marsboard
> +          - const: allwinner,sun7i-a20
> +
>        - description: MapleBoard MP130
>          items:
>            - const: mapleboard,mp130
> -- 
> 2.31.1
> 
> 


From robh at kernel.org  Tue Jan 11 17:25:51 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:25:51 -0600
Subject: [PATCH v2 2/2] sunxi.yaml: add HAOYU Electronics Marsboard A20
In-Reply-To: <tencent_9A79E4BC3715D4948E6D69363916D4B26D0A@qq.com>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <20220105024551.807713-1-conleylee@foxmail.com>
 <tencent_9A79E4BC3715D4948E6D69363916D4B26D0A@qq.com>
Message-ID: <Yd4uH3GrjBBLorrY@robh.at.kernel.org>

On Wed, Jan 05, 2022 at 10:45:51AM +0800, conleylee at foxmail.com wrote:
> From: conley <conleylee at foxmail.com>

And for the subject: 'dt-bindings: arm: allwinner: ...'

(Follow the subject style for the dir/subsystem.)

> 
> Signed-off-by: conley <conleylee at foxmail.com>
> ---
>  Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
> index 889128acf49a..4bd93ae26bd1 100644
> --- a/Documentation/devicetree/bindings/arm/sunxi.yaml
> +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
> @@ -444,6 +444,11 @@ properties:
>            - const: haoyu,a10-marsboard
>            - const: allwinner,sun4i-a10
>  
> +      - description: HAOYU Electronics Marsboard A20
> +        items:
> +          - const: haoyu,a20-marsboard
> +          - const: allwinner,sun7i-a20
> +
>        - description: MapleBoard MP130
>          items:
>            - const: mapleboard,mp130
> -- 
> 2.31.1
> 
> 


From robh at kernel.org  Tue Jan 11 17:28:06 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:28:06 -0600
Subject: [PATCH 1/2] dt-bindings: reset: mt7986: Add reset-controller
 header file
In-Reply-To: <20220105100456.7126-2-sam.shih@mediatek.com>
References: <20220105100456.7126-1-sam.shih@mediatek.com>
 <20220105100456.7126-2-sam.shih@mediatek.com>
Message-ID: <Yd4uplioThv8eJJE@robh.at.kernel.org>

On Wed, 05 Jan 2022 18:04:55 +0800, Sam Shih wrote:
> Add infracfg, toprgu, and ethsys reset-controller header file
> for MT7986 platform.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> ---
>  include/dt-bindings/reset/mt7986-resets.h | 55 +++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
>  create mode 100644 include/dt-bindings/reset/mt7986-resets.h
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:29:53 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:29:53 -0600
Subject: [PATCH 04/11] dt-bindings: PCI: mvebu: Add num-lanes property
In-Reply-To: <20220105150239.9628-5-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-5-pali@kernel.org>
Message-ID: <Yd4vESC55qFruR/6@robh.at.kernel.org>

On Wed, 05 Jan 2022 16:02:32 +0100, Pali Roh?r wrote:
> Controller driver needs to correctly configure PCIe link if it contains 1
> or 4 SerDes PCIe lanes. Therefore add a new 'num-lanes' DT property for
> mvebu PCIe controller. Property 'num-lanes' seems to be de-facto standard
> way how number of lanes is specified in other PCIe controllers.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  Documentation/devicetree/bindings/pci/mvebu-pci.txt | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:30:36 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:30:36 -0600
Subject: [PATCH 09/11] dt-bindings: PCI: mvebu: Update information about
 intx interrupts
In-Reply-To: <20220105150239.9628-10-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-10-pali@kernel.org>
Message-ID: <Yd4vPDAu82Ec6fEc@robh.at.kernel.org>

On Wed, 05 Jan 2022 16:02:37 +0100, Pali Roh?r wrote:
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  Documentation/devicetree/bindings/pci/mvebu-pci.txt | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From liuqi115 at huawei.com  Tue Jan 11 17:31:46 2022
From: liuqi115 at huawei.com (liuqi (BA))
Date: Wed, 12 Jan 2022 09:31:46 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
Message-ID: <dbcbc161-228d-ee78-e1f0-b59ad9b0a36f@huawei.com>



On 2022/1/4 10:35, Masami Hiramatsu wrote:
> Hi Jianhua,
> 
> On Mon, 3 Jan 2022 17:03:33 +0800
> Jianhua Liu <jianhua.ljh at gmail.com> wrote:
> 
>> Hi Qi,
>> I have tested your patch on UNISOC s9863a.
>> Test case "kprobe_example & kretprobe_example" is OK.
>>
>> Two point:
>> 1. backtrace is not perfect.
>>     optprobe_common does not saved frame pointer,
>>     backtrace lacks two calls.
>> such as for dup_mm: lack copy_process-->dup_mm
>> dup_mm backtrace from your patch:
>> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
>> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>> [  832.387083] Call trace:
>> [  832.387086]  dump_backtrace+0x0/0x1e0
>> [  832.387103]  show_stack+0x24/0x30
>> [  832.387112]  dump_stack_lvl+0x68/0x84
>> [  832.387123]  dump_stack+0x18/0x34
>> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
>> [  832.387143]  opt_pre_handler+0x84/0xc0
>> [  832.387154]  optprobe_optimized_callback+0xec/0x164
>> [  832.387164]  optprobe_common+0x70/0xc4
>> [  832.387173]  kernel_clone+0x98/0x440
>> [  832.387182]  __do_sys_clone+0x54/0x80
>> [  832.387191]  __arm64_sys_clone+0x2c/0x40
>> [  832.387199]  invoke_syscall+0x50/0x120
>> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
>> [  832.387217]  do_el0_svc+0x30/0x9c
>> [  832.387225]  el0_svc+0x20/0x60
>> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
>> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
>>
>>
>> dup_mm backtrace from other:
>> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
>> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>> [  173.352304] Call trace:
>> [  173.352307]  dump_backtrace+0x0/0x1d4
>> [  173.352319]  show_stack+0x18/0x24
>> [  173.352326]  dump_stack_lvl+0x68/0x84
>> [  173.352333]  dump_stack+0x18/0x34
>> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
>> [  173.352347]  opt_pre_handler+0x74/0xb0
>> [  173.352354]  optimized_callback+0x108/0x130
>> [  173.352361]  optinsn_slot+0x258/0x1000
>> [  173.352366]  dup_mm+0x4/0x4b0
>> [  173.352373]  copy_process+0x1284/0x1360
>> [  173.352378]  kernel_clone+0x5c/0x3c0
>> [  173.352384]  __do_sys_clone+0x54/0x80
>> [  173.352390]  __arm64_sys_clone+0x24/0x30
>> [  173.352396]  invoke_syscall+0x48/0x114
>> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
>> [  173.352408]  do_el0_svc+0x24/0x90
>> [  173.352413]  el0_svc+0x20/0x60
>> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
>> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
> 

Hi Masami and Jianhua,

optprobe_common() is added to minize size of code in trampoline, but 
each trampoline is alloced as PAGE_SIZE, so optprobe_common() seems 
unnecessary, and will make optprobe_trampoline.S much more complicated.
How about drop optprobe_common() and use a maro to reduce duplicate code .

Thanks,
Qi
> Is the second one with your patch?
> 
>>
>> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
>>     kernel/kprobe.c used only one PAGE_SIZE slot memory.
> 
> Good catch!
> Qi, can you make an array (or bit map) of usage flags and
> manage the reserved memory?
> 
> #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
> static bool insn_page_in_use[OPT_INSN_PAGES];
> 
> void *alloc_optinsn_page(void)
> {
> 	int i;
> 
> 	for (i = 0; i < OPT_INSN_PAGES; i++)
> 		if (!insn_page_in_use[i])
> 			goto found;
> 	return NULL;
> found:
> 	insn_page_in_use[i] = true;
> 	return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
> }
> 
> void free_optinsn_page(void *page)
> {
> 	unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
> 
> 	WARN_ONCE(idx & (PAGE_SIZE - 1));
> 	idx >>= PAGE_SHIFT;
> 	if (WARN_ONCE(idx >= OPT_INSN_PAGES))
> 		return;
> 	insn_page_in_use[idx] = false;
> }
> 
> Thank you,
> 
> 
> 
> 


From robh at kernel.org  Tue Jan 11 17:43:18 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:43:18 -0600
Subject: [PATCH v4] dt-bindings: dsp: mediatek: add mt8195 dsp document
In-Reply-To: <20220106064847.15588-1-yc.hung@mediatek.com>
References: <20220106064847.15588-1-yc.hung@mediatek.com>
Message-ID: <Yd4yNkeGlzdULNlv@robh.at.kernel.org>

On Thu, 06 Jan 2022 14:48:48 +0800, YC Hung wrote:
> From: "YC Hung" <yc.hung at mediatek.com>
> 
> This patch adds mt8195 dsp document. The dsp is used for Sound Open
> Firmware driver node. It includes registers,  clocks, memory regions,
> and mailbox for dsp.
> 
> Signed-off-by: yc.hung <yc.hung at mediatek.com>
> ---
> Changes since v3:
>   Fix patch v3 error : v3 only provide difference between v3 and v2.
> 
> Changes since v2:
>   Remove useless watchdog interrupt.
>   Add commit message more detail description.
> 
> Changes since v1:
>   Rename yaml file name as mediatek,mt8195-dsp.yaml
>   Refine descriptions for mailbox, memory-region and drop unused labels
>   in examples.
> ---
>  .../bindings/dsp/mediatek,mt8195-dsp.yaml     | 105 ++++++++++++++++++
>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From pali at kernel.org  Tue Jan 11 17:43:56 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Wed, 12 Jan 2022 02:43:56 +0100
Subject: [PATCH 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-9-pali@kernel.org>
 <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>
Message-ID: <20220112014356.h2pm7nc3vzsvjexq@pali>

On Wednesday 05 January 2022 09:41:51 Rob Herring wrote:
> On Wed, Jan 5, 2022 at 9:03 AM Pali Roh?r <pali at kernel.org> wrote:
> >
> > Split struct pci_ops between ops and child_ops. Member ops is used for
> > accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> > accessing real PCIe cards.
> >
> > There is no need to mix these two struct pci_ops into one as PCI core code
> > already provides separate callbacks via bridge->ops and bridge->child_ops.
> 
> I had similar patches including mvebu that I never got around to
> sending out. I pushed the branch out now at least[1].

Are you going to finish your patch series and send it? Because if yes,
I can drop this my patch in v3 and let all ->child_ops conversion for
you.


From robh at kernel.org  Tue Jan 11 17:44:34 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:44:34 -0600
Subject: [PATCH 3/4] dt-bindings: mfd: Add compatible for the MediaTek
 MT6366 PMIC
In-Reply-To: <20220106065407.16036-4-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
 <20220106065407.16036-4-johnson.wang@mediatek.com>
Message-ID: <Yd4ygpoi7KrzU012@robh.at.kernel.org>

On Thu, 06 Jan 2022 14:54:06 +0800, Johnson Wang wrote:
> This adds compatible for the MediaTek MT6366 PMIC.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/mfd/mt6397.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:45:47 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:45:47 -0600
Subject: [PATCH 4/4] dt-bindings: regulator: Add MT6358 regulators
In-Reply-To: <20220106065407.16036-5-johnson.wang@mediatek.com>
References: <20220106065407.16036-1-johnson.wang@mediatek.com>
 <20220106065407.16036-5-johnson.wang@mediatek.com>
Message-ID: <Yd4yy2emxSSh80UW@robh.at.kernel.org>

On Thu, 06 Jan 2022 14:54:07 +0800, Johnson Wang wrote:
> Add buck_vcore_sshub and ldo_vsram_others_sshub
> regulators to binding document for MT6358 and MT6366.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>  .../bindings/regulator/mt6358-regulator.txt   | 22 ++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From suleiman at google.com  Tue Jan 11 17:46:19 2022
From: suleiman at google.com (Suleiman Souhlal)
Date: Wed, 12 Jan 2022 10:46:19 +0900
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <CABCjUKBiECMEgnMaCrfApVbWPgw3UuwNH+-Y9ME+2ogJSm+p-Q@mail.gmail.com>

On Tue, Jan 11, 2022 at 5:41 PM Yu Zhao <yuzhao at google.com> wrote:
>
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> > On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > > TLDR
> > > ====
> > > The current page reclaim is too expensive in terms of CPU usage and it
> > > often makes poor choices about what to evict. This patchset offers an
> > > alternative solution that is performant, versatile and
> > > straightforward.
> >
> > <snipped>
> >
> > > Summery
> > > =======
> > > The facts are:
> > > 1. The independent lab results and the real-world applications
> > >    indicate substantial improvements; there are no known regressions.
> > > 2. Thrashing prevention, working set estimation and proactive reclaim
> > >    work out of the box; there are no equivalent solutions.
> > > 3. There is a lot of new code; nobody has demonstrated smaller changes
> > >    with similar effects.
> > >
> > > Our options, accordingly, are:
> > > 1. Given the amount of evidence, the reported improvements will likely
> > >    materialize for a wide range of workloads.
> > > 2. Gauging the interest from the past discussions [14][15][16], the
> > >    new features will likely be put to use for both personal computers
> > >    and data centers.
> > > 3. Based on Google's track record, the new code will likely be well
> > >    maintained in the long term. It'd be more difficult if not
> > >    impossible to achieve similar effects on top of the existing
> > >    design.
> >
> > Hi Andrew, Linus,
> >
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> >
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.
>
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
>
> Having this patchset in the mainline will make your job easier :)
>
>    Alexandre - the XanMod Kernel maintainer
>                https://xanmod.org
>
>    Brian     - the Chrome OS kernel memory maintainer
>                https://www.chromium.org
>
>    Jan       - the Arch Linux Zen kernel maintainer
>                https://archlinux.org
>
>    Steven    - the Liquorix kernel maintainer
>                https://liquorix.net
>
>    Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                https://chromium.googlesource.com/chromiumos/third_party/kernel

Android on ChromeOS has been using MGLRU for a while now, with great results.
It would be great for more people to more easily be able to benefit from it.

Acked-by: Suleiman Souhlal <suleiman at google.com>

-- Suleiman


From robh at kernel.org  Tue Jan 11 17:48:10 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:48:10 -0600
Subject: [PATCH 1/3] dt-bindings: reset: Add compatible for Meson-S4
 Reset Controller
In-Reply-To: <20220107023931.13251-2-zelong.dong@amlogic.com>
References: <20220107023931.13251-1-zelong.dong@amlogic.com>
 <20220107023931.13251-2-zelong.dong@amlogic.com>
Message-ID: <Yd4zWnQxB1ZK8IPo@robh.at.kernel.org>

On Fri, 07 Jan 2022 10:39:29 +0800, Zelong Dong wrote:
> Add new compatible for Amlogic's Meson-S4 Reset Controller
> 
> Signed-off-by: Zelong Dong <zelong.dong at amlogic.com>
> ---
>  Documentation/devicetree/bindings/reset/amlogic,meson-reset.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:48:57 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:48:57 -0600
Subject: [PATCH v21 6/8] dt-bindings: soc: mediatek: add mt8192 svs
 dt-bindings
In-Reply-To: <20220107095200.4389-7-roger.lu@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-7-roger.lu@mediatek.com>
Message-ID: <Yd4ziRBDa2W34/Cn@robh.at.kernel.org>

On Fri, 07 Jan 2022 17:51:58 +0800, Roger Lu wrote:
> Add mt8192 svs compatible/resets in dt-bindings.
> 
> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> ---
>  .../devicetree/bindings/soc/mediatek/mtk-svs.yaml         | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:49:08 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:49:08 -0600
Subject: [PATCH v2 2/2] dt-bindings: mediatek: add compatible for MT8186
 pwrap
In-Reply-To: <20220107104633.7500-3-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-3-johnson.wang@mediatek.com>
Message-ID: <Yd4zlMykh8GfZQtH@robh.at.kernel.org>

On Fri, 07 Jan 2022 18:46:33 +0800, Johnson Wang wrote:
> This adds dt-binding documentation of pwrap for Mediatek MT8186
> SoCs Platform.
> 
> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/soc/mediatek/pwrap.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:51:19 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:51:19 -0600
Subject: [PATCH v8 3/4] dt-bindings: pinctrl: mt8195: Add
 mediatek,drive-strength-adv property
In-Reply-To: <20220107115345.9075-4-tinghan.shen@mediatek.com>
References: <20220107115345.9075-1-tinghan.shen@mediatek.com>
 <20220107115345.9075-4-tinghan.shen@mediatek.com>
Message-ID: <Yd40F1noUJW4VNpJ@robh.at.kernel.org>

On Fri, 07 Jan 2022 19:53:44 +0800, Tinghan Shen wrote:
> Extend pin driving support for I2C pins on SoC mt8195.
> This property is also documented in mediatek,mt8183-pinctrl.yaml.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> ---
>  .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:54:24 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:54:24 -0600
Subject: [PATCH 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220107145515.613009-2-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-2-narmstrong@baylibre.com>
Message-ID: <Yd400IApAqHeSW4B@robh.at.kernel.org>

On Fri, Jan 07, 2022 at 03:55:10PM +0100, Neil Armstrong wrote:
> The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
> on the same Amlogic SoCs.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../display/amlogic,meson-dw-mipi-dsi.yaml    | 118 ++++++++++++++++++
>  1 file changed, 118 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> 
> diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> new file mode 100644
> index 000000000000..f3070783d606
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
> @@ -0,0 +1,118 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2020 BayLibre, SAS
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
> +
> +maintainers:
> +  - Neil Armstrong <narmstrong at baylibre.com>
> +
> +description: |
> +  The Amlogic Meson Synopsys Designware Integration is composed of
> +  - A Synopsys DesignWare MIPI DSI Host Controller IP
> +  - A TOP control block controlling the Clocks & Resets of the IP
> +
> +allOf:
> +  - $ref: dsi-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - amlogic,meson-g12a-dw-mipi-dsi
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    minItems: 2
> +
> +  clock-names:
> +    minItems: 2
> +    items:
> +      - const: pclk
> +      - const: px_clk
> +      - const: meas_clk
> +
> +  resets:
> +    minItems: 1
> +
> +  reset-names:
> +    items:
> +      - const: top
> +
> +  phys:
> +    minItems: 1
> +
> +  phy-names:
> +    items:
> +      - const: dphy
> +
> +  ports:
> +    $ref: /schemas/graph.yaml#/properties/ports
> +
> +    properties:
> +      port at 0:
> +        $ref: /schemas/graph.yaml#/$defs/port-base

/schemas/graph.yaml#/properties/port

> +        unevaluatedProperties: false

And this can be dropped.

> +        description: Input node to receive pixel data.
> +
> +      port at 1:
> +        $ref: /schemas/graph.yaml#/$defs/port-base
> +        unevaluatedProperties: false

Same here.

With that,

Reviewed-by: Rob Herring <robh at kernel.org>

> +        description: DSI output node to panel.
> +
> +    required:
> +      - port at 0
> +      - port at 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - resets
> +  - reset-names
> +  - phys
> +  - phy-names
> +  - ports
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    dsi at 7000 {
> +          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
> +          reg = <0x6000 0x400>;
> +          resets = <&reset_top>;
> +          reset-names = "top";
> +          clocks = <&clk_pclk>, <&clk_px>;
> +          clock-names = "pclk", "px_clk";
> +          phys = <&mipi_dphy>;
> +          phy-names = "dphy";
> +
> +          ports {
> +              #address-cells = <1>;
> +              #size-cells = <0>;
> +
> +              /* VPU VENC Input */
> +              mipi_dsi_venc_port: port at 0 {
> +                  reg = <0>;
> +
> +                  mipi_dsi_in: endpoint {
> +                       remote-endpoint = <&dpi_out>;
> +                  };
> +              };
> +
> +              /* DSI Output */
> +              mipi_dsi_panel_port: port at 1 {
> +                  reg = <1>;
> +
> +                  mipi_out_panel: endpoint {
> +                      remote-endpoint = <&mipi_in_panel>;
> +                  };
> +              };
> +          };
> +    };
> -- 
> 2.25.1
> 
> 


From robh at kernel.org  Tue Jan 11 17:54:46 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:54:46 -0600
Subject: [PATCH 2/6] dt-bindings: display: meson-vpu: add third DPI
 output port
In-Reply-To: <20220107145515.613009-3-narmstrong@baylibre.com>
References: <20220107145515.613009-1-narmstrong@baylibre.com>
 <20220107145515.613009-3-narmstrong@baylibre.com>
Message-ID: <Yd405jhJtNSiOgzm@robh.at.kernel.org>

On Fri, 07 Jan 2022 15:55:11 +0100, Neil Armstrong wrote:
> Add third port corresponding to the ENCL DPI encoder used to connect
> to DSI or LVDS transceivers.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
>  1 file changed, 5 insertions(+)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:58:13 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:58:13 -0600
Subject: [PATCH v1 02/14] dt-bindings: gpio: fix gpio-hog example
In-Reply-To: <20220107180314.1816515-3-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-3-marcel@ziswiler.com>
Message-ID: <Yd41tcVzxDjk+151@robh.at.kernel.org>

On Fri, 07 Jan 2022 19:03:02 +0100, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Even if this is no yaml yet at least fix the example to be compliant to
> later schema as e.g. found in gpio-pca95xx.yaml, fairchild,74hc595.yaml
> and gpio/fsl-imx-gpio.yaml.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  Documentation/devicetree/bindings/gpio/gpio.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:58:42 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:58:42 -0600
Subject: [PATCH v1 13/14] dt-bindings: arm: fsl: add
 toradex,verdin-imx8mm et al.
In-Reply-To: <20220107180314.1816515-14-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-14-marcel@ziswiler.com>
Message-ID: <Yd410mxlPDradVc2@robh.at.kernel.org>

On Fri, 07 Jan 2022 19:03:13 +0100, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Add toradex,verdin-imx8mm for our new Verdin iMX8M Mini modules, its
> nonwifi and wifi variants and the carrier boards (both Dahlia and the
> Verdin Development Board) they may be mated in.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
> 
>  .../devicetree/bindings/arm/fsl.yaml          | 21 +++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 17:59:27 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 19:59:27 -0600
Subject: [PATCH 02/10] dt-bindings: devfreq: rk3399_dmc: Deprecate
 unused/redundant properties
In-Reply-To: <20220107155215.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>
References: <20220107235320.965497-1-briannorris@chromium.org>
 <20220107155215.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>
Message-ID: <Yd41/06PvO7DDGlO@robh.at.kernel.org>

On Fri, 07 Jan 2022 15:53:12 -0800, Brian Norris wrote:
> These DRAM configuration properties are all handled in ARM Trusted
> Firmware (and have been since the early days of this SoC), and there are
> no in-tree users of the DMC binding yet. It's better to just defer to
> firmware instead of maintaining this large list of properties.
> 
> There's also some confusion about units: many of these are specified in
> MHz, but the downstream users and driver code are treating them as Hz, I
> believe. Rather than straighten all that out, I just drop them.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
> 
>  .../bindings/devfreq/rk3399_dmc.yaml          | 42 +++++++++----------
>  1 file changed, 21 insertions(+), 21 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 18:01:17 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:01:17 -0600
Subject: [PATCH 03/10] dt-bindings: devfreq: rk3399_dmc: Fix Hz units
In-Reply-To: <20220107155215.3.I9341269171c114d0e04e41d48037fd32816e2d8c@changeid>
References: <20220107235320.965497-1-briannorris@chromium.org>
 <20220107155215.3.I9341269171c114d0e04e41d48037fd32816e2d8c@changeid>
Message-ID: <Yd42bfH5skA+TZup@robh.at.kernel.org>

On Fri, 07 Jan 2022 15:53:13 -0800, Brian Norris wrote:
> The driver and all downstream device trees [1] are using Hz units, but
> the document claims MHz. DRAM frequency for these systems can't possibly
> exceed 2^32-1 Hz, so the choice of unit doesn't really matter than much.
> 
> Rather than add unnecessary risk in getting the units wrong, let's just
> go with the unofficial convention and make the docs match reality.
> 
> A sub-1MHz frequency is extremely unlikely, so include a minimum in the
> schema, to help catch anybody who might have believed this was MHz.
> 
> [1] And notably, also those trying to upstream them:
> https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
> 
>  .../bindings/devfreq/rk3399_dmc.yaml          | 24 +++++++++----------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 18:04:04 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:04:04 -0600
Subject: [PATCH 04/10] dt-bindings: devfreq: rk3399_dmc: Add more
 disable-freq properties
In-Reply-To: <20220107155215.4.I382d4de737198ea52deb118c9bdc4d93d76e009e@changeid>
References: <20220107235320.965497-1-briannorris@chromium.org>
 <20220107155215.4.I382d4de737198ea52deb118c9bdc4d93d76e009e@changeid>
Message-ID: <Yd43FL2JihCdn8Ta@robh.at.kernel.org>

On Fri, Jan 07, 2022 at 03:53:14PM -0800, Brian Norris wrote:
> DDR DVFS tuning has found that several power-saving features don't have
> good tradeoffs at higher frequencies -- at higher frequencies, we'll see
> glitches or other errors. Provide tuning controls so these can be
> disabled at higher OPPs, and left active only at the lower ones.
> 
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
> 
>  .../bindings/devfreq/rk3399_dmc.yaml          | 42 +++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> index 2c871c57fd97..357d07c5a3df 100644
> --- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> +++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
> @@ -271,6 +271,43 @@ properties:
>        When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
>        strength. Default value is 60.
>  
> +  rockchip,pd_idle_dis_freq:

s/_/-/

on all the new properties.

> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the power-down idle disable frequency in Hz. When the DDR
> +      frequency is greater than pd_idle_dis_freq, power-down idle is disabled.
> +      See also rockchip,pd_idle.
> +
> +  rockchip,sr_idle_dis_freq:

'-hz' suffix. Let's not repeat the same problem.


> +    $ref: /schemas/types.yaml#/definitions/uint32

And then the type can be dropped.

> +    description:
> +      Defines the self-refresh idle disable frequency in Hz. When the DDR
> +      frequency is greater than sr_idle_dis_freq, self-refresh idle is
> +      disabled. See also rockchip,sr_idle.
> +
> +  rockchip,sr_mc_gate_idle_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the self-refresh and memory-controller clock gating disable
> +      frequency in Hz. When the DDR frequency is greater than
> +      sr_mc_gate_idle_dis_freq, the clock will not be gated when idle. See also
> +      rockchip,sr_mc_gate_idle.
> +
> +  rockchip,srpd_lite_idle_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the self-refresh power down idle disable frequency in Hz. When
> +      the DDR frequency is greater than srpd_lite_idle_dis_freq, memory will
> +      not be placed into self-refresh power down mode when idle. See also
> +      rockchip,srpd_lite_idle.
> +
> +  rockchip,standby_idle_dis_freq:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description:
> +      Defines the standby idle disable frequency in Hz. When the DDR frequency
> +      is greater than standby_idle_dis_freq, standby idle is disabled. See also
> +      rockchip,standby_idle.
> +
>  additionalProperties: false
>  
>  examples:
> @@ -294,4 +331,9 @@ examples:
>        rockchip,ddr3_odt_dis_freq = <333000000>;
>        rockchip,lpddr3_odt_dis_freq = <333000000>;
>        rockchip,lpddr4_odt_dis_freq = <333000000>;
> +      rockchip,pd_idle_dis_freq = <1000000000>;
> +      rockchip,sr_idle_dis_freq = <1000000000>;
> +      rockchip,sr_mc_gate_idle_dis_freq = <1000000000>;
> +      rockchip,srpd_lite_idle_dis_freq = <0>;
> +      rockchip,standby_idle_dis_freq = <928000000>;
>      };
> -- 
> 2.34.1.575.g55b058a8bb-goog
> 
> 


From robh at kernel.org  Tue Jan 11 18:04:46 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:04:46 -0600
Subject: [PATCH 1/2] dt-bindings: i2c: update bindings for MT8186 SoC
In-Reply-To: <20220108095418.16602-2-kewei.xu@mediatek.com>
References: <20220108095418.16602-1-kewei.xu@mediatek.com>
 <20220108095418.16602-2-kewei.xu@mediatek.com>
Message-ID: <Yd43Ptp6dTxd93Ej@robh.at.kernel.org>

On Sat, 08 Jan 2022 17:54:17 +0800, Kewei Xu wrote:
> Add a DT binding documentation for the MT8186 soc.
> 
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
> ---
>  Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 18:05:11 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:05:11 -0600
Subject: [v1 1/2] dt-bindings: power: Add MT8186 power domains
In-Reply-To: <20220108131953.16744-2-chun-jie.chen@mediatek.com>
References: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
 <20220108131953.16744-2-chun-jie.chen@mediatek.com>
Message-ID: <Yd43V1woRMAcXOfS@robh.at.kernel.org>

On Sat, Jan 08, 2022 at 09:19:52PM +0800, Chun-Jie Chen wrote:
> Add power domains dt-bindings for MT8186.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  .../power/mediatek,power-controller.yaml      |  1 +
>  include/dt-bindings/power/mt8186-power.h      | 32 +++++++++++++++++++
>  2 files changed, 33 insertions(+)
>  create mode 100644 include/dt-bindings/power/mt8186-power.h
> 
> diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> index d6ebd77d28a7..135c6f722091 100644
> --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
> @@ -26,6 +26,7 @@ properties:
>        - mediatek,mt8167-power-controller
>        - mediatek,mt8173-power-controller
>        - mediatek,mt8183-power-controller
> +      - mediatek,mt8186-power-controller
>        - mediatek,mt8192-power-controller
>        - mediatek,mt8195-power-controller
>  
> diff --git a/include/dt-bindings/power/mt8186-power.h b/include/dt-bindings/power/mt8186-power.h
> new file mode 100644
> index 000000000000..ca8ea2d24801
> --- /dev/null
> +++ b/include/dt-bindings/power/mt8186-power.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */

Dual license please.

> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> + */
> +
> +#ifndef _DT_BINDINGS_POWER_MT8186_POWER_H
> +#define _DT_BINDINGS_POWER_MT8186_POWER_H
> +
> +#define MT8186_POWER_DOMAIN_MFG0			0
> +#define MT8186_POWER_DOMAIN_MFG1			1
> +#define MT8186_POWER_DOMAIN_MFG2			2
> +#define MT8186_POWER_DOMAIN_MFG3			3
> +#define MT8186_POWER_DOMAIN_SSUSB			4
> +#define MT8186_POWER_DOMAIN_SSUSB_P1			5
> +#define MT8186_POWER_DOMAIN_DIS				6
> +#define MT8186_POWER_DOMAIN_IMG				7
> +#define MT8186_POWER_DOMAIN_IMG2			8
> +#define MT8186_POWER_DOMAIN_IPE				9
> +#define MT8186_POWER_DOMAIN_CAM				10
> +#define MT8186_POWER_DOMAIN_CAM_RAWA			11
> +#define MT8186_POWER_DOMAIN_CAM_RAWB			12
> +#define MT8186_POWER_DOMAIN_VENC			13
> +#define MT8186_POWER_DOMAIN_VDEC			14
> +#define MT8186_POWER_DOMAIN_WPE				15
> +#define MT8186_POWER_DOMAIN_CONN_ON			16
> +#define MT8186_POWER_DOMAIN_CSIRX_TOP			17
> +#define MT8186_POWER_DOMAIN_ADSP_AO			18
> +#define MT8186_POWER_DOMAIN_ADSP_INFRA			19
> +#define MT8186_POWER_DOMAIN_ADSP_TOP			20
> +
> +#endif /* _DT_BINDINGS_POWER_MT8186_POWER_H */
> -- 
> 2.18.0
> 
> 


From guoren at kernel.org  Tue Jan 11 18:08:42 2022
From: guoren at kernel.org (Guo Ren)
Date: Wed, 12 Jan 2022 10:08:42 +0800
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
Message-ID: <CAJF2gTS81o1bsAGj=016F=Nw7MszhsYa95cw6JLThjwW50YRpw@mail.gmail.com>

On Tue, Jan 11, 2022 at 11:33 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Tue, Jan 11, 2022 at 9:35 AM Christoph Hellwig <hch at lst.de> wrote:
> >
> > The fcntl F_GETLK64/F_SETLK64/F_SETLKW64 are only implemented for the
> > 32-bit syscall APIs, but we also need them for compat handling on 64-bit
> > builds.  Redefining them is error prone (as shown by the example that
> > parisc gets it wrong currently), so we should use the same defines for
> > both case.  In theory we could try to hide them from userspace, but
> > given that only MIPS actually gets that right, while the asm-generic
> > version used by most architectures relies on a Kconfig symbol that can't
> > be relied on to be set properly by userspace is a clear indicator to not
> > bother.
> >
> > Signed-off-by: Christoph Hellwig <hch at lst.de>
> > ---
>
> > diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
> > index 98f4ff165b776..43d7c44031be0 100644
> > --- a/include/uapi/asm-generic/fcntl.h
> > +++ b/include/uapi/asm-generic/fcntl.h
> > @@ -116,13 +116,11 @@
> >  #define F_GETSIG       11      /* for sockets. */
> >  #endif
> >
> > -#ifndef CONFIG_64BIT
> >  #ifndef F_GETLK64
> >  #define F_GETLK64      12      /*  using 'struct flock64' */
> >  #define F_SETLK64      13
> >  #define F_SETLKW64     14
> >  #endif
> > -#endif
> >
> >  #ifndef F_SETOWN_EX
> >  #define F_SETOWN_EX    15
>
> This is a very subtle change to the exported UAPI header contents:
> On 64-bit architectures, the three unusable numbers are now always
> shown, rather than depending on a user-controlled symbol.
>
> This is probably what we want here for compatibility reasons, but I think
> it should be explained in the changelog text, and I'd like Jeff or Bruce
> to comment on it as well: the alternative here would be to make the
> uapi definition depend on __BITS_PER_LONG==32, which is

__BITS_PER_LONG==32 || __KERNEL__  just for kernel use in compat.

> technically the right thing to do but more a of a change.
>
>        Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From mirela.rabulea at oss.nxp.com  Tue Jan 11 18:09:02 2022
From: mirela.rabulea at oss.nxp.com (mirela.rabulea at oss.nxp.com)
Date: Wed, 12 Jan 2022 04:09:02 +0200
Subject: [PATCH v1] media: imx-jpeg: use NV12M to represent non contiguous
 NV12
In-Reply-To: <20211224030241.4624-1-ming.qian@nxp.com>
References: <20211224030241.4624-1-ming.qian@nxp.com>
Message-ID: <9a1a19cf-b6ee-16bf-6e9e-195df5b47ebf@oss.nxp.com>

Hi Ming,

On 24.12.2021 05:02, Ming Qian wrote:
> V4L2_PIX_FMT_NV12 requires num_planes equals to 1,
> V4L2_PIX_FMT_NV12M requires num_planes equals to 2.
> and mxc-jpeg supports 2 planes for nv12,
> so we should use 4L2_PIX_FMT_NV12M instead of V4L2_PIX_FMT_NV12,
> otherwise it will confuses gstreamer and prevent encoding and decoding.

I missed some typos here:
and mxc-jpeg supports => Since mxc-jpeg supports
4L2_PIX_FMT_NV12M => V4L2_PIX_FMT_NV12M
will confuses => will confuse

For the patch contents: Reviewed-by: Mirela Rabulea 
<mirela.rabulea at oss.nxp.com>

Regards,
Mirela

> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
> Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
> Reviewed-by: Mirela Rabulea <mirela.rabulea at oss.nxp.com>
> ---
>   drivers/media/platform/imx-jpeg/mxc-jpeg.c | 12 ++++++------
>   1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
> index 4ca96cf9def7..7c0366f5f801 100644
> --- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
> +++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
> @@ -96,7 +96,7 @@ static const struct mxc_jpeg_fmt mxc_formats[] = {
>   	},
>   	{
>   		.name		= "YUV420", /* 1st plane = Y, 2nd plane = UV */
> -		.fourcc		= V4L2_PIX_FMT_NV12,
> +		.fourcc		= V4L2_PIX_FMT_NV12M,
>   		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
>   		.nc		= 3,
>   		.depth		= 12, /* 6 bytes (4Y + UV) for 4 pixels */
> @@ -404,7 +404,7 @@ static enum mxc_jpeg_image_format mxc_jpeg_fourcc_to_imgfmt(u32 fourcc)
>   		return MXC_JPEG_GRAY;
>   	case V4L2_PIX_FMT_YUYV:
>   		return MXC_JPEG_YUV422;
> -	case V4L2_PIX_FMT_NV12:
> +	case V4L2_PIX_FMT_NV12M:
>   		return MXC_JPEG_YUV420;
>   	case V4L2_PIX_FMT_YUV24:
>   		return MXC_JPEG_YUV444;
> @@ -673,7 +673,7 @@ static int mxc_jpeg_fixup_sof(struct mxc_jpeg_sof *sof,
>   	_bswap16(&sof->width);
>   
>   	switch (fourcc) {
> -	case V4L2_PIX_FMT_NV12:
> +	case V4L2_PIX_FMT_NV12M:
>   		sof->components_no = 3;
>   		sof->comp[0].v = 0x2;
>   		sof->comp[0].h = 0x2;
> @@ -709,7 +709,7 @@ static int mxc_jpeg_fixup_sos(struct mxc_jpeg_sos *sos,
>   	u8 *sof_u8 = (u8 *)sos;
>   
>   	switch (fourcc) {
> -	case V4L2_PIX_FMT_NV12:
> +	case V4L2_PIX_FMT_NV12M:
>   		sos->components_no = 3;
>   		break;
>   	case V4L2_PIX_FMT_YUYV:
> @@ -1183,7 +1183,7 @@ static void mxc_jpeg_bytesperline(struct mxc_jpeg_q_data *q,
>   		/* bytesperline unused for compressed formats */
>   		q->bytesperline[0] = 0;
>   		q->bytesperline[1] = 0;
> -	} else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12) {
> +	} else if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M) {
>   		/* When the image format is planar the bytesperline value
>   		 * applies to the first plane and is divided by the same factor
>   		 * as the width field for the other planes
> @@ -1215,7 +1215,7 @@ static void mxc_jpeg_sizeimage(struct mxc_jpeg_q_data *q)
>   	} else {
>   		q->sizeimage[0] = q->bytesperline[0] * q->h;
>   		q->sizeimage[1] = 0;
> -		if (q->fmt->fourcc == V4L2_PIX_FMT_NV12)
> +		if (q->fmt->fourcc == V4L2_PIX_FMT_NV12M)
>   			q->sizeimage[1] = q->sizeimage[0] / 2;
>   	}
>   }
> 
> base-commit: 68b9bcc8a534cd11fe55f8bc82f948aae7d81b3c
> 


From mirela.rabulea at oss.nxp.com  Tue Jan 11 18:09:50 2022
From: mirela.rabulea at oss.nxp.com (Mirela Rabulea)
Date: Wed, 12 Jan 2022 04:09:50 +0200
Subject: [PATCH] media: imx-jpeg: Prevent decoding NV12M jpegs into
 single-planar buffers
Message-ID: <20220112020950.656796-1-mirela.rabulea@oss.nxp.com>

If the application queues an NV12M jpeg as output buffer, but then
queues a single planar capture buffer, the kernel will crash with
"Unable to handle kernel NULL pointer dereference" in mxc_jpeg_addrs,
prevent this by finishing the job with error.

Signed-off-by: Mirela Rabulea <mirela.rabulea at oss.nxp.com>
---
 drivers/media/platform/imx-jpeg/mxc-jpeg.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
index 4ca96cf9def7..6acb17318cf4 100644
--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
@@ -947,6 +947,11 @@ static void mxc_jpeg_device_run(void *priv)
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
 
 	jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
+	if (q_data_cap->fmt->colplanes == 2 &&
+	    dst_buf->vb2_buf.num_planes < 2) {
+		dev_err(dev, "Decoding multi-planar, but capture buffer is single-planar\n");
+		jpeg_src_buf->jpeg_parse_error = true;
+	}
 	if (jpeg_src_buf->jpeg_parse_error) {
 		jpeg->slot_data[ctx->slot].used = false;
 		v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-- 
2.25.1



From robh at kernel.org  Tue Jan 11 18:14:14 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:14:14 -0600
Subject: [PATCH] dt-bindings: vendor-prefixes: add Huawei
In-Reply-To: <20220110121307.GA1894@standask-GA-A55M-S2HP>
References: <20220109132311.GA2827@standask-GA-A55M-S2HP>
 <20220110095543.00001ac0@Huawei.com>
 <20220110121307.GA1894@standask-GA-A55M-S2HP>
Message-ID: <Yd45dgW8Fgsmuzrm@robh.at.kernel.org>

On Mon, Jan 10, 2022 at 01:13:07PM +0100, Stanislav Jakubek wrote:
> On Mon, Jan 10, 2022 at 09:55:43AM +0000, Jonathan Cameron wrote:
> > On Sun, 9 Jan 2022 14:23:11 +0100
> > Stanislav Jakubek <stano.jakubek at gmail.com> wrote:
> > 
> > > Add vendor prefix for Huawei (https://www.huawei.com/en/)
> > 
> > Patch description should say why...  Is there an existing binding
> > using a huawei vendor prefix?
> 
> Not sure about bindings, but there are device trees using the huawei 
> vendor prefix. I'm aware of at least these two:
> /arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
> /arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> 
> Similar situation with the other vendor prefix patches I've sent yesterday.
> 
> Should I send a v2 with an updated patch description for this and
> the other patches?

Yes.

Rob


From yuzhao at google.com  Tue Jan 11 18:16:15 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 11 Jan 2022 19:16:15 -0700
Subject: [PATCH v6 4/9] mm: multigenerational lru: groundwork
In-Reply-To: <878rvm661z.fsf@linux.ibm.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-5-yuzhao@google.com>
 <878rvm661z.fsf@linux.ibm.com>
Message-ID: <Yd457900iUIzwpnc@google.com>

On Tue, Jan 11, 2022 at 01:46:24PM +0530, Aneesh Kumar K.V wrote:
> Yu Zhao <yuzhao at google.com> writes:
> 
> .....
> 
>  +
> > +/*
> > + * Evictable pages are divided into multiple generations. The youngest and the
> > + * oldest generation numbers, max_seq and min_seq, are monotonically increasing.
> > + * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An
> > + * offset within MAX_NR_GENS, gen, indexes the lru list of the corresponding
> > + * generation. The gen counter in folio->flags stores gen+1 while a page is on
> > + * lrugen->lists[]. Otherwise, it stores 0.
> > + *
> > + * A page is added to the youngest generation on faulting. The aging needs to
> > + * check the accessed bit at least twice before handing this page over to the
> > + * eviction. The first check takes care of the accessed bit set on the initial
> > + * fault; the second check makes sure this page hasn't been used since then.
> > + * This process, AKA second chance, requires a minimum of two generations,
> > + * hence MIN_NR_GENS. And to be compatible with the active/inactive lru, these
> > + * two generations are mapped to the active; the rest of generations, if they
> > + * exist, are mapped to the inactive. PG_active is always cleared while a page
> > + * is on lrugen->lists[] so that demotion, which happens consequently when the
> > + * aging creates a new generation, needs not to worry about it.
> > + */
> 
> Where do we clear PG_active in the code? Is this the reason we endup
> with

We clear PG_active when we add a page (folio) to MGLRU lists:
  include/linux/mm_inline.h
    lru_gen_add_folio()
	do {
		new_flags = old_flags = READ_ONCE(folio->flags);

		...

		new_flags &= ~(LRU_GEN_MASK | BIT(PG_active));
                                                  ^^^^^^^^^
		...

	} while (cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);

We also set it when we isolate a page (for page migration):
  include/linux/mm_inline.h
    lru_gen_del_folio()
	do {
		new_flags = old_flags = READ_ONCE(folio->flags);

		...

		else if (lru_gen_is_active(lruvec, gen))
			new_flags |= BIT(PG_active);
                                         ^^^^^^^^^
	} while (cmpxchg(&folio->flags, old_flags, new_flags) != old_flags);

> 
>   void deactivate_page(struct page *page)
>   {
>  -	if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) {
>  +	if (PageLRU(page) && !PageUnevictable(page) && (PageActive(page) || lru_gen_enabled())) {

That's correct.

> > +#define MIN_NR_GENS		2U
> > +#define MAX_NR_GENS		((unsigned int)CONFIG_NR_LRU_GENS)
> > +
> > +struct lru_gen_struct {
> > +	/* the aging increments the youngest generation number */
> > +	unsigned long max_seq;
> > +	/* the eviction increments the oldest generation numbers */
> > +	unsigned long min_seq[ANON_AND_FILE];
> > +	/* the birth time of each generation in jiffies */
> > +	unsigned long timestamps[MAX_NR_GENS];
> > +	/* the multigenerational lru lists */
> > +	struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
> > +	/* the sizes of the above lists */
> > +	unsigned long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
> > +	/* whether the multigenerational lru is enabled */
> > +	bool enabled;
> > +};
> > +
> 
> ....
> 
> >  static void __meminit zone_init_internals(struct zone *zone, enum zone_type idx, int nid,
> > diff --git a/mm/swap.c b/mm/swap.c
> > index e8c9dc6d0377..d7dde3b7d4b5 100644
> > --- a/mm/swap.c
> > +++ b/mm/swap.c
> > @@ -462,6 +462,11 @@ void folio_add_lru(struct folio *folio)
> >  	VM_BUG_ON_FOLIO(folio_test_active(folio) && folio_test_unevictable(folio), folio);
> >  	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
> >  
> > +	/* see the comment in lru_gen_add_folio() */
> > +	if (lru_gen_enabled() && !folio_test_unevictable(folio) &&
> > +	    task_in_lru_fault() && !(current->flags & PF_MEMALLOC))
> > +		folio_set_active(folio);
> > +
> 
> 
> Can you explain this better? What is the significance of marking the
> folio active here. Do we need to differentiate parallel page faults (across
> different vmas) w.r.t task_in_lru_fault()?

All pages faulted in need to be added to the youngest generation. But
without PG_active, lru_gen_add_folio() doesn't know whether a page was
faulted in, or something else, e.g., page cache readahead. This is
because pages aren't immediately sent to lru_gen_add_folio(). They are
batched by lru_pvecs:

/**
 * folio_add_lru - Add a folio to an LRU list.
 * @folio: The folio to be added to the LRU.
 *
 * Queue the folio for addition to the LRU. The decision on whether
 * to add the page to the [in]active [file|anon] list is deferred until the
 * pagevec is drained. This gives a chance for the caller of folio_add_lru()
 * have the folio added to the active list using folio_mark_accessed().
 */
void folio_add_lru(struct folio *folio)
{
	struct pagevec *pvec;

	VM_BUG_ON_FOLIO(folio_test_active(folio) && folio_test_unevictable(folio), folio);
	VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);

	/* see the comment in lru_gen_add_folio() */
	if (lru_gen_enabled() && !folio_test_unevictable(folio) &&
	    lru_gen_in_pgfault() && !(current->flags & PF_MEMALLOC))
		folio_set_active(folio);

	folio_get(folio);
	local_lock(&lru_pvecs.lock);
	pvec = this_cpu_ptr(&lru_pvecs.lru_add);
	if (pagevec_add_and_need_flush(pvec, &folio->page))
		__pagevec_lru_add(pvec);
	local_unlock(&lru_pvecs.lock);
}


From robh at kernel.org  Tue Jan 11 18:25:15 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:25:15 -0600
Subject: [PATCH v2 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220111101338.58630-3-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
 <20220111101338.58630-3-krzysztof.kozlowski@canonical.com>
Message-ID: <Yd48C4pRH7tQz++f@robh.at.kernel.org>

On Tue, Jan 11, 2022 at 11:13:36AM +0100, Krzysztof Kozlowski wrote:
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> controller bindings to DT schema format
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
>  .../devicetree/bindings/spi/samsung,spi.yaml  | 198 ++++++++++++++++++
>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 -----------
>  MAINTAINERS                                   |   2 +-
>  5 files changed, 235 insertions(+), 123 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> new file mode 100644
> index 000000000000..aa5a1f48494b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description:
> +  See spi-peripheral-props.yaml for more info.
> +
> +properties:
> +  controller-data:
> +    type: object
> +    additionalProperties: false
> +
> +    properties:
> +      samsung,spi-feedback-delay:
> +        description: |
> +          The sampling phase shift to be applied on the miso line (to account
> +          for any lag in the miso line). Valid values:
> +           - 0: No phase shift.
> +           - 1: 90 degree phase shift sampling.
> +           - 2: 180 degree phase shift sampling.
> +           - 3: 270 degree phase shift sampling.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [0, 1, 2, 3]
> +
> +    required:
> +      - samsung,spi-feedback-delay
> +
> +additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> new file mode 100644
> index 000000000000..da4533feb946
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -0,0 +1,198 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Samsung S3C/S5P/Exynos SoC SPI controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description:
> +  All the SPI controller nodes should be represented in the aliases node using
> +  the following format 'spi{n}' where n is a unique number for the alias.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - enum:
> +          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
> +          - samsung,s3c6410-spi
> +          - samsung,s5pv210-spi # for S5PV210 and S5PC110
> +          - samsung,exynos5433-spi
> +      - const: samsung,exynos7-spi
> +        deprecated: true
> +
> +  clocks:
> +    minItems: 2
> +    maxItems: 3
> +
> +  clock-names:
> +    minItems: 2
> +    maxItems: 3
> +
> +  cs-gpios: true
> +
> +  dmas:
> +    minItems: 2
> +    maxItems: 2
> +
> +  dma-names:
> +    items:
> +      - const: tx
> +      - const: rx
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  no-cs-readback:
> +    description:
> +      The CS line is disconnected, therefore the device should not operate
> +      based on CS signalling.
> +    type: boolean
> +
> +  num-cs:
> +    minimum: 1
> +    maximum: 4
> +    default: 1
> +
> +  samsung,spi-src-clk:
> +    description:
> +      If the spi controller includes a internal clock mux to select the clock
> +      source for the spi bus clock, this property can be used to indicate the
> +      clock to be used for driving the spi bus clock. If not specified, the
> +      clock number 0 is used as default.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    default: 0
> +
> +  reg:
> +    maxItems: 1
> +
> +patternProperties:
> +  "^.*@[0-9a-f]+$":
> +    type: object
> +    allOf:
> +      - $ref: spi-peripheral-props.yaml
> +
> +    required:
> +      - controller-data
> +
> +    unevaluatedProperties: false

This is wrong because the child nodes will certainly have device 
specific properties.

The whole child node schema can be dropped.

> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - dmas
> +  - dma-names
> +  - interrupts
> +  - reg
> +
> +allOf:
> +  - $ref: spi-controller.yaml#
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: samsung,exynos5433-spi
> +    then:
> +      properties:
> +        clocks:
> +          minItems: 3
> +          maxItems: 3
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +            - const: spi_ioclk
> +    else:
> +      properties:
> +        clocks:
> +          minItems: 2
> +          maxItems: 2
> +        clock-names:
> +          items:
> +            - const: spi
> +            - enum:
> +                - spi_busclk0
> +                - spi_busclk1
> +                - spi_busclk2
> +                - spi_busclk3
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/exynos5433.h>
> +    #include <dt-bindings/clock/samsung,s2mps11.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +
> +    spi at 14d30000 {
> +        compatible = "samsung,exynos5433-spi";
> +        reg = <0x14d30000 0x100>;
> +        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
> +        dmas = <&pdma0 11>, <&pdma0 10>;
> +        dma-names = "tx", "rx";
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +        clocks = <&cmu_peric CLK_PCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_SPI1>,
> +                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
> +        clock-names = "spi",
> +                      "spi_busclk0",
> +                      "spi_ioclk";
> +        samsung,spi-src-clk = <0>;
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&spi1_bus>;
> +        num-cs = <1>;
> +
> +        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
> +
> +        audio-codec at 0 {
> +            compatible = "wlf,wm5110";
> +            reg = <0x0>;
> +            spi-max-frequency = <20000000>;
> +            interrupt-parent = <&gpa0>;
> +            interrupts = <4 IRQ_TYPE_NONE>;
> +            clocks = <&pmu_system_controller 0>,
> +                     <&s2mps13_osc S2MPS11_CLK_BT>;
> +            clock-names = "mclk1", "mclk2";
> +
> +            gpio-controller;
> +            #gpio-cells = <2>;
> +            interrupt-controller;
> +            #interrupt-cells = <2>;
> +
> +            wlf,micd-detect-debounce = <300>;
> +            wlf,micd-bias-start-time = <0x1>;
> +            wlf,micd-rate = <0x7>;
> +            wlf,micd-dbtime = <0x2>;
> +            wlf,micd-force-micbias;
> +            wlf,micd-configs = <0x0 1 0>;
> +            wlf,hpdet-channel = <1>;
> +            wlf,gpsw = <0x1>;
> +            wlf,inmode = <2 0 2 0>;
> +
> +            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
> +            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
> +
> +            /* core supplies */
> +            AVDD-supply = <&ldo18_reg>;
> +            DBVDD1-supply = <&ldo18_reg>;
> +            CPVDD-supply = <&ldo18_reg>;
> +            DBVDD2-supply = <&ldo18_reg>;
> +            DBVDD3-supply = <&ldo18_reg>;
> +            SPKVDDL-supply = <&ldo18_reg>;
> +            SPKVDDR-supply = <&ldo18_reg>;
> +
> +            controller-data {
> +                samsung,spi-feedback-delay = <0>;
> +            };
> +        };
> +    };
> diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
> index 5dd209206e88..df885eeb144f 100644
> --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
> +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
> @@ -85,5 +85,6 @@ properties:
>  # The controller specific properties go here.
>  allOf:
>    - $ref: cdns,qspi-nor-peripheral-props.yaml#
> +  - $ref: samsung,spi-peripheral-props.yaml#
>  
>  additionalProperties: true
> diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> deleted file mode 100644
> index 49028a4f5df1..000000000000
> --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
> +++ /dev/null
> @@ -1,122 +0,0 @@
> -* Samsung SPI Controller
> -
> -The Samsung SPI controller is used to interface with various devices such as flash
> -and display controllers using the SPI communication interface.
> -
> -Required SoC Specific Properties:
> -
> -- compatible: should be one of the following.
> -    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
> -    - samsung,s3c6410-spi: for s3c6410 platforms
> -    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
> -    - samsung,exynos5433-spi: for exynos5433 compatible controllers
> -    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
> -
> -- reg: physical base address of the controller and length of memory mapped
> -  region.
> -
> -- interrupts: The interrupt number to the cpu. The interrupt specifier format
> -  depends on the interrupt controller.
> -
> -- dmas : Two or more DMA channel specifiers following the convention outlined
> -  in bindings/dma/dma.txt
> -
> -- dma-names: Names for the dma channels. There must be at least one channel
> -  named "tx" for transmit and named "rx" for receive.
> -
> -- clocks: specifies the clock IDs provided to the SPI controller; they are
> -  required for interacting with the controller itself, for synchronizing the bus
> -  and as I/O clock (the latter is required by exynos5433 and exynos7).
> -
> -- clock-names: string names of the clocks in the 'clocks' property; for all the
> -  the devices the names must be "spi", "spi_busclkN" (where N is determined by
> -  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
> -  "spi_ioclk" for the I/O clock.
> -
> -Required Board Specific Properties:
> -
> -- #address-cells: should be 1.
> -- #size-cells: should be 0.
> -
> -Optional Board Specific Properties:
> -
> -- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
> -  select the clock source for the spi bus clock, this property can be used to
> -  indicate the clock to be used for driving the spi bus clock. If not specified,
> -  the clock number 0 is used as default.
> -
> -- num-cs: Specifies the number of chip select lines supported. If
> -  not specified, the default number of chip select lines is set to 1.
> -
> -- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
> -
> -- no-cs-readback: the CS line is disconnected, therefore the device should not
> -  operate based on CS signalling.
> -
> -SPI Controller specific data in SPI slave nodes:
> -
> -- The spi slave nodes should provide the following information which is required
> -  by the spi controller.
> -
> -  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
> -    miso line (to account for any lag in the miso line). The following are the
> -    valid values.
> -
> -      - 0: No phase shift.
> -      - 1: 90 degree phase shift sampling.
> -      - 2: 180 degree phase shift sampling.
> -      - 3: 270 degree phase shift sampling.
> -
> -Aliases:
> -
> -- All the SPI controller nodes should be represented in the aliases node using
> -  the following format 'spi{n}' where n is a unique number for the alias.
> -
> -
> -Example:
> -
> -- SoC Specific Portion:
> -
> -	spi_0: spi at 12d20000 {
> -		compatible = "samsung,exynos4210-spi";
> -		reg = <0x12d20000 0x100>;
> -		interrupts = <0 66 0>;
> -		dmas = <&pdma0 5
> -			&pdma0 4>;
> -		dma-names = "tx", "rx";
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -	};
> -
> -- Board Specific Portion:
> -
> -	spi_0: spi at 12d20000 {
> -		#address-cells = <1>;
> -		#size-cells = <0>;
> -		pinctrl-names = "default";
> -		pinctrl-0 = <&spi0_bus>;
> -		cs-gpios = <&gpa2 5 0>;
> -
> -		w25q80bw at 0 {
> -			#address-cells = <1>;
> -			#size-cells = <1>;
> -			compatible = "w25x80";
> -			reg = <0>;
> -			spi-max-frequency = <10000>;
> -
> -			controller-data {
> -				samsung,spi-feedback-delay = <0>;
> -			};
> -
> -			partition at 0 {
> -				label = "U-Boot";
> -				reg = <0x0 0x40000>;
> -				read-only;
> -			};
> -
> -			partition at 40000 {
> -				label = "Kernel";
> -				reg = <0x40000 0xc0000>;
> -			};
> -		};
> -	};
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 5ea5655a29c3..1f951bc877f0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -17054,7 +17054,7 @@ M:	Andi Shyti <andi at etezian.org>
>  L:	linux-spi at vger.kernel.org
>  L:	linux-samsung-soc at vger.kernel.org
>  S:	Maintained
> -F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
> +F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
>  F:	drivers/spi/spi-s3c*
>  F:	include/linux/platform_data/spi-s3c64xx.h
>  F:	include/linux/spi/s3c24xx-fiq.h
> -- 
> 2.32.0
> 
> 


From robh at kernel.org  Tue Jan 11 18:25:39 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:25:39 -0600
Subject: [PATCH v2 3/4] spi: dt-bindings: samsung: allow controller-data
 to be optional
In-Reply-To: <20220111101338.58630-4-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
 <20220111101338.58630-4-krzysztof.kozlowski@canonical.com>
Message-ID: <Yd48I0+IfUXbJ0B8@robh.at.kernel.org>

On Tue, 11 Jan 2022 11:13:37 +0100, Krzysztof Kozlowski wrote:
> The Samsung SoC SPI bindings requires to provide controller-data node
> for each of SPI peripheral device nodes.  Make this controller-data node
> optional, so DTS could be simpler.
> 
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../devicetree/bindings/spi/samsung,spi-peripheral-props.yaml  | 1 +
>  Documentation/devicetree/bindings/spi/samsung,spi.yaml         | 3 ---
>  2 files changed, 1 insertion(+), 3 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Tue Jan 11 18:26:42 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 11 Jan 2022 20:26:42 -0600
Subject: [PATCH v2 25/28] dt-bindings: pinctrl: samsung: describe
 Exynos850 and ExynosAutov9 wake-ups
In-Reply-To: <20220111201722.327219-19-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-19-krzysztof.kozlowski@canonical.com>
Message-ID: <Yd48YtTFYez0yx9N@robh.at.kernel.org>

On Tue, 11 Jan 2022 21:17:19 +0100, Krzysztof Kozlowski wrote:
> Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
> Exynos5, Exynos5433) with external wake-up interrupts, expected to have
> one interrupt for multiplexing these wake-up interrupts.  Also they
> expected to have exactly one pin controller capable of external wake-up
> interrupts.
> 
> It seems however that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences of their pin controller node capable of
> external wake-up interrupts:
> 1. No multiplexed external wake-up interrupt, only direct,
> 2. More than one pin controller capable of external wake-up interrupts.
> 
> Add dedicated Exynos850 and ExynosAutov9 compatibles.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../samsung,pinctrl-wakeup-interrupt.yaml     | 27 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 3 deletions(-)
> 

Reviewed-by: Rob Herring <robh at kernel.org>


From christianshewitt at gmail.com  Tue Jan 11 18:27:04 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:04 +0000
Subject: [PATCH v3 0/9] arm64: dts: meson: add support for ac2xx devices
Message-ID: <20220112022713.25962-1-christianshewitt@gmail.com>

This series adds support for several popular Amlogic S905X3 (SM1) Android
Set-Top Box devices. Like most Android box devices, they ship in variants
with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
something we need to consider to get a working boot, but we do need to get
the correct connectivity spec. Broadly speaking we see boxes with Higher
and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
some low-end boxes BT is omitted.

As initial distro setup is frequently performed over SSH or an HDMI GUI
app it is important for users to pick a device-tree with the correct
Ethernet PHY spec else connectivity is impossible. To aid this we append
a -gbit suffix to X96-AIR and A95XF3-AIR models using an external Gigabit
PHY, while 10/00 models with internal PHY have no suffix.

NB: At the current time the Realtek 8822CS and MT7668 WiFi/BT modules we
have seen on 'AIR' devices are not supported in the kernel so these are
deliberately omitted. The H96-Max uses a conventional Broadcom module
so has more complete support. For now the boxes have simple HDMI audio
support; wiring up the Headphone socket will be done at a later date.

Changes since v2 series:
- Add Robs binding acks (patches 2/5)
- Add Martin/Piotir's Tested-By's (patches 1/3)
- Reorder Tested-By on patch 9
- Correct 'distinguished' typo in patch 5
- Correct typo in series name/subject

Changes since RFC(v1) series:
- Add Robs binding acks on patches 4/7/8 (patches 2/5 still need acks)
- Rename and rework patches around -gbit (as requested by Neil)
- Correct 'manufacturer' typo on patch 8
- Rebase against v5.18/dt64 branch

Christian Hewitt (9):
  arm64: dts: meson: add common SM1 ac2xx dtsi
  dt-bindings: arm: amlogic: add X96-AIR bindings
  arm64: dts: meson: add initial device-trees for X96-AIR
  dt-bindings: vendor-prefixes: add cyx prefix
  dt-bindings: arm: amlogic: add A95XF3-AIR bindings
  arm64: dts: meson: add initial device-trees for A95XF3-AIR
  dt-bindings: vendor-prefixes: add haochuangyi prefix
  dt-bindings: arm: amlogic: add H96-Max bindings
  arm64: dts: meson: add initial device-tree for H96-Max

 .../devicetree/bindings/arm/amlogic.yaml      |   5 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   4 +
 arch/arm64/boot/dts/amlogic/Makefile          |   5 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 +++++++++
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++
 9 files changed, 941 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:05 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:05 +0000
Subject: [PATCH v3 1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-2-christianshewitt@gmail.com>

Add a common dtsi for Android STB devices based on the Amlogic S905X3
(AC213/AC214) and S905D3 (AC201/AC202) reference designs. The dtsi is
loosely based on the existing SEI610 device-tree.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit PHY
---
 .../boot/dts/amlogic/meson-sm1-ac2xx.dtsi     | 300 ++++++++++++++++++
 1 file changed, 300 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
new file mode 100644
index 000000000000..46a34731f7e2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-ac2xx.dtsi
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ *
+ * AC200/AC202 = S905D3
+ * AC213/AC214 = S905X3
+ *
+ */
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	aliases {
+		serial0 = &uart_AO;
+		ethernet0 = &ethmac;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	emmc_pwrseq: emmc-pwrseq {
+		compatible = "mmc-pwrseq-emmc";
+		reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+	};
+
+	cvbs-connector {
+		compatible = "composite-video-connector";
+
+		port {
+			cvbs_connector_in: endpoint {
+				remote-endpoint = <&cvbs_vdac_out>;
+			};
+		};
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_connector_in: endpoint {
+				remote-endpoint = <&hdmi_tx_tmds_out>;
+			};
+		};
+	};
+
+	memory at 0 {
+		device_type = "memory";
+		reg = <0x0 0x0 0x0 0x40000000>;
+	};
+
+	ao_5v: regulator-ao_5v {
+		compatible = "regulator-fixed";
+		regulator-name = "AO_5V";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	dc_in: regulator-dc_in {
+		compatible = "regulator-fixed";
+		regulator-name = "DC_IN";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-always-on;
+	};
+
+	emmc_1v8: regulator-emmc_1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "EMMC_1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	vddao_3v3: regulator-vddao_3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDAO_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_in>;
+		regulator-always-on;
+	};
+
+	vddcpu: regulator-vddcpu {
+		compatible = "pwm-regulator";
+
+		regulator-name = "VDDCPU";
+		regulator-min-microvolt = <690000>;
+		regulator-max-microvolt = <1050000>;
+
+		vin-supply = <&dc_in>;
+
+		pwms = <&pwm_AO_cd 1 1500 0>;
+		pwm-dutycycle-range = <100 0>;
+
+		regulator-boot-on;
+		regulator-always-on;
+	};
+
+	vddio_ao1v8: regulator-vddio_ao1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDDIO_AO1V8";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		vin-supply = <&vddao_3v3>;
+		regulator-always-on;
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+		clocks = <&wifi32k>;
+		clock-names = "ext_clock";
+	};
+
+	wifi32k: wifi32k {
+		compatible = "pwm-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+	};
+};
+
+&cec_AO {
+	pinctrl-0 = <&cec_ao_a_h_pins>;
+	pinctrl-names = "default";
+	status = "disabled";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+	pinctrl-0 = <&cec_ao_b_h_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+	hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu1 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU1_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu2 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU2_CLK>;
+	clock-latency = <50000>;
+};
+
+&cpu3 {
+	cpu-supply = <&vddcpu>;
+	operating-points-v2 = <&cpu_opp_table>;
+	clocks = <&clkc CLKID_CPU3_CLK>;
+	clock-latency = <50000>;
+};
+
+&cvbs_vdac_port {
+	cvbs_vdac_out: endpoint {
+		remote-endpoint = <&cvbs_connector_in>;
+	};
+};
+
+&hdmi_tx {
+	status = "okay";
+	pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+	pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+	hdmi_tx_tmds_out: endpoint {
+		remote-endpoint = <&hdmi_connector_in>;
+	};
+};
+
+&ir {
+	status = "okay";
+	pinctrl-0 = <&remote_input_ao_pins>;
+	pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+	status = "okay";
+	pinctrl-0 = <&pwm_ao_a_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&pwm_AO_cd {
+	pinctrl-0 = <&pwm_ao_d_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin1";
+	status = "okay";
+};
+
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&xtal>;
+	clock-names = "clkin0";
+};
+
+&saradc {
+	status = "okay";
+	vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+	status = "okay";
+	pinctrl-0 = <&sdio_pins>;
+	pinctrl-1 = <&sdio_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr104;
+	max-frequency = <200000000>;
+
+	non-removable;
+	disable-wp;
+
+	/* WiFi firmware requires power to be kept while in suspend */
+	keep-power-in-suspend;
+
+	mmc-pwrseq = <&sdio_pwrseq>;
+
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddio_ao1v8>;
+};
+
+/* SD Card */
+&sd_emmc_b {
+	status = "okay";
+	pinctrl-0 = <&sdcard_c_pins>;
+	pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <4>;
+	cap-sd-highspeed;
+	/* CRC errors are observed at 50MHz */
+	max-frequency = <35000000>;
+	disable-wp;
+
+	cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+	status = "okay";
+	pinctrl-0 = <&emmc_ctrl_pins>, <&emmc_data_8b_pins>, <&emmc_ds_pins>;
+	pinctrl-1 = <&emmc_clk_gate_pins>;
+	pinctrl-names = "default", "clk-gate";
+
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	max-frequency = <200000000>;
+	non-removable;
+	disable-wp;
+
+	mmc-pwrseq = <&emmc_pwrseq>;
+	vmmc-supply = <&vddao_3v3>;
+	vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_AO {
+	status = "okay";
+	pinctrl-0 = <&uart_ao_a_pins>;
+	pinctrl-names = "default";
+};
+
+&usb {
+	status = "okay";
+	dr_mode = "otg";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:06 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:06 +0000
Subject: [PATCH v3 2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-3-christianshewitt@gmail.com>

Add board bindings for the Amediatech X96-AIR STB which ships with
model variants distiguished by Ethernet configuration: models using
an external Gigabit PHY have a -gbit suffix, while models using an
internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 31df120d73b0..b5b995941d3b 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -170,6 +170,8 @@ properties:
       - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
         items:
           - enum:
+              - amediatech,x96-air
+              - amediatech,x96-air-gbit
               - bananapi,bpi-m5
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:07 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:07 +0000
Subject: [PATCH v3 3/9] arm64: dts: meson: add initial device-trees for X96-AIR
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-4-christianshewitt@gmail.com>

The Amediatek X96-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 2x USB 2.0 inc. OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com> # X96-Air with Gbit PHY
Tested-by: Piotr Oniszczuk <piotr.oniszczuk at gmail.com> # X96-Air with 10/100 Eth
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-x96-air-gbit.dts    | 133 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-x96-air.dts    | 112 +++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 5148cd9e5146..1c0e554f54fc 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -56,4 +56,6 @@ dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-x96-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
new file mode 100644
index 000000000000..7e1a74046ba5
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air-gbit.dts
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air-gbit", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-x96max";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
new file mode 100644
index 000000000000..cd93d798f2a3
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-x96-air.dts
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "amediatech,x96-air", "amlogic,sm1";
+	model = "Shenzhen Amediatech Technology Co., Ltd X96 Air";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "X96-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&ir {
+	linux,rc-map-name = "rc-beelink-gs1";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:08 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:08 +0000
Subject: [PATCH v3 4/9] dt-bindings: vendor-prefixes: add cyx prefix
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-5-christianshewitt@gmail.com>

Shenzhen CYX Industrial Co., Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index eb8ab0d82198..c9202a101d71 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -281,6 +281,8 @@ patternProperties:
     description: CUI Devices
   "^cypress,.*":
     description: Cypress Semiconductor Corporation
+  "^cyx,.*":
+    description: Shenzhen CYX Industrial Co., Ltd
   "^cznic,.*":
     description: CZ.NIC, z.s.p.o.
   "^dallas,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:09 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:09 +0000
Subject: [PATCH v3 5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-6-christianshewitt@gmail.com>

Add board bindings for the CYX A95XF3-AIR set-top box which ships
with model variants distinguished by Ethernet configuration: models
using external Gigabit PHY have a -gbit suffix, while models using
an internal 10/100 PHY have no suffix.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index b5b995941d3b..2027ce81a834 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -173,6 +173,8 @@ properties:
               - amediatech,x96-air
               - amediatech,x96-air-gbit
               - bananapi,bpi-m5
+              - cyx,a95xf3-air
+              - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
               - khadas,vim3l
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:10 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:10 +0000
Subject: [PATCH v3 6/9] arm64: dts: meson: add initial device-trees for
 A95XF3-AIR
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-7-christianshewitt@gmail.com>

The CYX A95XF3-AIR is based on Amlogic S905X3 reference board
designs and ships in multiple configurations:

? 4GB DDR3 + 64GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 4GB DDR3 + 32GB eMMC + WiFi a/b/g/n/ac + BT + Gb Ethernet
? 2GB DDR3 + 16GB eMMC + WiFi b/g/n (no BT) + 10/100 Ethernet
...
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD
- Multicolour case LED 'arc'

The device-tree with -gbit suffix supports models with Gigabit
Ethernet, and the device-tree with no suffix supports models
with 10/100 Ethernet.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   2 +
 .../dts/amlogic/meson-sm1-a95xf3-air-gbit.dts | 129 ++++++++++++++++++
 .../boot/dts/amlogic/meson-sm1-a95xf3-air.dts | 108 +++++++++++++++
 3 files changed, 239 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 1c0e554f54fc..e87adc6593df 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -51,6 +51,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
new file mode 100644
index 000000000000..d1debccdc1c2
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air-gbit.dts
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air-gbit", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
new file mode 100644
index 000000000000..c94f2870b78b
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-a95xf3-air.dts
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "cyx,a95xf3-air", "amlogic,sm1";
+	model = "Shenzhen CYX Industrial Co., Ltd A95XF3-AIR";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "A95XF3-AIR";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+	phy-handle = <&internal_ephy>;
+	phy-mode = "rmii";
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:11 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:11 +0000
Subject: [PATCH v3 7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-8-christianshewitt@gmail.com>

Shenzhen Haochuangyi Technology Co.,Ltd are a manufacturer of Android
Set-Top Box devices.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index c9202a101d71..f4160ee3b5df 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -485,6 +485,8 @@ patternProperties:
     deprecated: true
   "^hannstar,.*":
     description: HannStar Display Corporation
+  "^haochuangyi,.*":
+    description: Shenzhen Haochuangyi Technology Co.,Ltd
   "^haoyu,.*":
     description: Haoyu Microelectronic Co. Ltd.
   "^hardkernel,.*":
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:12 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:12 +0000
Subject: [PATCH v3 8/9] dt-bindings: arm: amlogic: add H96-Max bindings
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-9-christianshewitt@gmail.com>

Add the board binding for the Haochuangyi H96-Max STB device.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 2027ce81a834..a073a959232c 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -177,6 +177,7 @@ properties:
               - cyx,a95xf3-air-gbit
               - hardkernel,odroid-c4
               - hardkernel,odroid-hc4
+              - haochuangyi,h96-max
               - khadas,vim3l
               - seirobotics,sei610
           - const: amlogic,sm1
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 11 18:27:13 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 12 Jan 2022 02:27:13 +0000
Subject: [PATCH v3 9/9] arm64: dts: meson: add initial device-tree for H96-Max
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <20220112022713.25962-10-christianshewitt@gmail.com>

The Haochuangyi H96-Max is based on the Amlogic S905X3 reference
design with the following specs:

- 4GB DDR4 RAM
- 32/64/128GB eMMC
- HDMI 2.1 video
- S/PDIF optical output
- AV output
- 10/100/1000 Base-T Ethernet
- AP6356S Wireless (802.11 a/b/g/n/ac, BT 4.1)
- 1x USB 2.0 OTG port
- 1x USB 3.0 port
- IR receiver
- 1x micro SD card slot (internal)
- 1x Reset/Update button (in AV jack)
- 7-segment VFD

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Benoit Masson <yahoo at perenite.com>
---
 arch/arm64/boot/dts/amlogic/Makefile          |   1 +
 .../boot/dts/amlogic/meson-sm1-h96-max.dts    | 145 ++++++++++++++++++
 2 files changed, 146 insertions(+)
 create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts

diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index e87adc6593df..868d74044072 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -54,6 +54,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-wetek-core2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-a95xf3-air-gbit.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-bananapi-m5.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-h96-max.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-hc4.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
new file mode 100644
index 000000000000..0f6660e68e72
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-h96-max.dts
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Copyright (c) 2020 Christian Hewitt <christianshewitt at gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1-ac2xx.dtsi"
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+	compatible = "haochuangyi,h96-max", "amlogic,sm1";
+	model = "Shenzhen Haochuangyi Technology Co., Ltd H96 Max";
+
+	sound {
+		compatible = "amlogic,axg-sound-card";
+		model = "H96-MAX";
+		audio-aux-devs = <&tdmout_b>;
+		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
+				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
+				"TDM_B Playback", "TDMOUT_B OUT";
+
+		assigned-clocks = <&clkc CLKID_MPLL2>,
+				  <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&frddr_a>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&frddr_b>;
+		};
+
+		dai-link-2 {
+			sound-dai = <&frddr_c>;
+		};
+
+		/* 8ch hdmi interface */
+		dai-link-3 {
+			sound-dai = <&tdmif_b>;
+			dai-format = "i2s";
+			dai-tdm-slot-tx-mask-0 = <1 1>;
+			dai-tdm-slot-tx-mask-1 = <1 1>;
+			dai-tdm-slot-tx-mask-2 = <1 1>;
+			dai-tdm-slot-tx-mask-3 = <1 1>;
+			mclk-fs = <256>;
+
+			codec {
+				sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+			};
+		};
+
+		/* hdmi glue */
+		dai-link-4 {
+			sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+			codec {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&arb {
+	status = "okay";
+};
+
+&clkc_audio {
+	status = "okay";
+};
+
+&ethmac {
+	status = "okay";
+
+	pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+	pinctrl-names = "default";
+	phy-mode = "rgmii-txid";
+	phy-handle = <&external_phy>;
+
+	rx-internal-delay-ps = <800>;
+};
+
+&ext_mdio {
+	external_phy: ethernet-phy at 0 {
+		/* Realtek RTL8211F (0x001cc916) */
+		reg = <0>;
+		max-speed = <1000>;
+
+		reset-assert-us = <10000>;
+		reset-deassert-us = <80000>;
+		reset-gpios = <&gpio GPIOZ_15 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+
+		interrupt-parent = <&gpio_intc>;
+		/* MAC_INTR on GPIOZ_14 */
+		interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&frddr_a {
+	status = "okay";
+};
+
+&frddr_b {
+	status = "okay";
+};
+
+&frddr_c {
+	status = "okay";
+};
+
+&tdmif_b {
+	status = "okay";
+};
+
+&tdmout_b {
+	status = "okay";
+};
+
+&tohdmitx {
+	status = "okay";
+};
+
+&uart_A {
+	status = "okay";
+
+	pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+		max-speed = <2000000>;
+		clocks = <&wifi32k>;
+		clock-names = "lpo";
+	};
+};
-- 
2.17.1



From conleylee at foxmail.com  Tue Jan 11 18:37:55 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Wed, 12 Jan 2022 10:37:55 +0800
Subject: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20 support
In-Reply-To: <20220111103542.f7ilg2ugqklpztr5@houat>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <tencent_13C536D91764B05D794CBCF3156C963E6C0A@qq.com>
 <20220111103542.f7ilg2ugqklpztr5@houat>
Message-ID: <tencent_361798B1357958BC1B1694977A6C9935CD0A@qq.com>

On 01/11/22 at 11:35??, Maxime Ripard wrote:
> Date: Tue, 11 Jan 2022 11:35:42 +0100
> From: Maxime Ripard <maxime at cerno.tech>
> To: conleylee at foxmail.com
> Cc: robh at kernel.org, wens at csie.org, devicetree at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20
>  support
> 
> Hi,
> 
> On Wed, Jan 05, 2022 at 10:45:50AM +0800, conleylee at foxmail.com wrote:
> > From: conley <conleylee at foxmail.com>
> 
> This should be your full name in the author and signed-off-by
> 
> > ARM dts: sun7i: Add Marsboard A20 board
> > 
> > This patch add support for Marsboard A20 board.
> > 
> > The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
> > card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
> > USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.
> > 
> > Change since v1.
> >   - Spearate biddings and dts as two patches.
> >   - use SPDX tag
> 
> And the changelog should be after the --- below
> 
> > Signed-off-by: conley <conleylee at foxmail.com>
> > ---
> >  arch/arm/boot/dts/Makefile                |   1 +
> >  arch/arm/boot/dts/sun7i-a20-marsboard.dts | 183 ++++++++++++++++++++++
> >  2 files changed, 184 insertions(+)
> >  create mode 100644 arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > 
> > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > index 0de64f237cd8..4628a2617313 100644
> > --- a/arch/arm/boot/dts/Makefile
> > +++ b/arch/arm/boot/dts/Makefile
> > @@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
> >  	sun7i-a20-icnova-swac.dtb \
> >  	sun7i-a20-lamobo-r1.dtb \
> >  	sun7i-a20-linutronix-testbox-v2.dtb \
> > +	sun7i-a20-marsboard.dtb \
> >  	sun7i-a20-m3.dtb \
> >  	sun7i-a20-mk808c.dtb \
> >  	sun7i-a20-olimex-som-evb.dtb \
> > diff --git a/arch/arm/boot/dts/sun7i-a20-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > new file mode 100644
> > index 000000000000..7ab6aa30fee6
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > @@ -0,0 +1,183 @@
> > +// SPDX-License-Identifier: LGPL-2.1+
> 
> The license for DT files is usually a dual-license with GPL and MIT,
> which would be:
> 
> SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> 
> You can't link to a DT, so GPL and LGPL should be equivalent here, and
> MIT is useful for other projects (like the *BSD) that reuse the DT.
> 
> > +/*
> > + * Copyright 2021 Conley Lee
> > + * Conley Lee <conleylee at foxmail.com>
> > + */
> > +
> > +/dts-v1/;
> > +#include "sun7i-a20.dtsi"
> > +#include "sunxi-common-regulators.dtsi"
> > +
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +/ {
> > +	model = "HAOYU Electronics Marsboard A20";
> > +	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
> 
> Is there multiple boards called marsboard?
> 
> If not, then the compatible should be haoyu,marsboard.
> 
> The file name should be sun7i-a20-haoyu-marsboard too.
> 
> > +	aliases {
> > +		serial0 = &uart0;
> > +	};
> > +
> > +	chosen {
> > +		stdout-path = "serial0:115200n8";
> > +	};
> > +
> > +	hdmi-connector {
> > +		compatible = "hdmi-connector";
> > +		type = "a";
> > +
> > +		port {
> > +			hdmi_con_in: endpoint {
> > +				remote-endpoint = <&hdmi_out_con>;
> > +			};
> > +		};
> > +	};
> > +};
> > +
> > +&ahci {
> > +	target-supply = <&reg_ahci_5v>;
> > +	status = "okay";
> > +};
> > +
> > +&codec {
> > +	status = "okay";
> > +};
> > +
> > +&cpu0 {
> > +	cpu-supply = <&reg_dcdc2>;
> > +};
> > +
> > +&de {
> > +	status = "okay";
> > +};
> > +
> > +&ehci0 {
> > +	status = "okay";
> > +};
> > +
> > +&ehci1 {
> > +	status = "okay";
> > +};
> > +
> > +&gmac_mii_pins {
> > +	pins = "PA0", "PA1", "PA2",
> > +	"PA3", "PA4", "PA5", "PA6",
> > +	"PA7", "PA8", "PA9", "PA10",
> > +	"PA11", "PA12", "PA13", "PA14",
> > +	"PA15", "PA16", "PA17";
> > +};
> 
> Why do you need that node?
> 
> Maxime

1. There are two boards called marsboard, another one is based on
   sun4i-a10.
2. About the gmac_mii_pins node: the pin PA17 is connected to PHY
   as EXTERR signal on sun7i-a20-marsboard, it's different from 
   the definetion in dtsi.

Thanks ~


From sboyd at kernel.org  Tue Jan 11 18:46:20 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 11 Jan 2022 18:46:20 -0800
Subject: [PATCH v7 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <Ydy3qvT5w6IWnR7s@abelvesa>
References: <20220103233948.198119-1-Mr.Bossman075@gmail.com>
 <20220103233948.198119-6-Mr.Bossman075@gmail.com>
 <20220105235157.8ED80C36AEB@smtp.kernel.org>
 <89046151-e44e-6828-ad76-8574fba4fca8@gmail.com>
 <20220110201201.C1E37C36AE9@smtp.kernel.org> <Ydy3qvT5w6IWnR7s@abelvesa>
Message-ID: <20220112024621.C5266C36AE3@smtp.kernel.org>

Quoting Abel Vesa (2022-01-10 14:48:10)
> On 22-01-10 12:12:00, Stephen Boyd wrote:
> > Quoting Jesse Taube (2022-01-09 11:07:42)
> > > >> +
> > > >> +       clk_hw_data->num = IMXRT1050_CLK_END;
> > > >> +       hws = clk_hw_data->hws;
> > > >> +
> > > >> +       hws[IMXRT1050_CLK_OSC] = __clk_get_hw(of_clk_get_by_name(np, "osc"));
> > > > 
> > > > Use clk_parent_data instead and reference the binding name with .fw_name
> > > 
> > > Hi Stephen, sorry to bother you again.
> > > I'm wondering if adding `clk_parent_data` is necessary as it seems like 
> > > it wold be a big change and the other IMX boards haven't implemented 
> > > this yet would it be okay if I don't do this, or if it is necessary 
> > > could you link to a patch set to change it.
> > > 
> > 
> > Is it a big change because the imx_clk_hw*() APIs aren't prepared for
> > non-string parents? Can you make some clk_parent_data based APIs and
> > migrate things over gradually? This is really a question for i.MX folks
> > to see if anyone is working on moving away from the string names.
> 
> I'm currently looking into it. I would suggest we take this patch as is
> and I'll switch it later on to clk_parent_data.
> 

Ok sounds like a plan.


From sboyd at kernel.org  Tue Jan 11 18:57:01 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 11 Jan 2022 18:57:01 -0800
Subject: [PATCH v8 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220111215415.2075257-4-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-4-Mr.Bossman075@gmail.com>
Message-ID: <20220112025702.C76F0C36AF2@smtp.kernel.org>

Quoting Jesse Taube (2022-01-11 13:54:11)
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> Add the clock binding doc for i.MXRT1050.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> [Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
> IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Tue Jan 11 18:57:17 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 11 Jan 2022 18:57:17 -0800
Subject: [PATCH v8 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220111215415.2075257-5-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-5-Mr.Bossman075@gmail.com>
Message-ID: <20220112025718.9DD36C36AEB@smtp.kernel.org>

Quoting Jesse Taube (2022-01-11 13:54:12)
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add DT binding documentation for i.MXRT1050 clock driver.
> 
> Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Tue Jan 11 18:57:51 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 11 Jan 2022 18:57:51 -0800
Subject: [PATCH v8 5/7] clk: imx: Add initial support for i.MXRT1050 clock
 driver
In-Reply-To: <20220111215415.2075257-6-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-6-Mr.Bossman075@gmail.com>
Message-ID: <20220112025752.C2402C36AE3@smtp.kernel.org>

Quoting Jesse Taube (2022-01-11 13:54:13)
> Add clock driver support for i.MXRT1050.
> 
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> ---

Reviewed-by: Stephen Boyd <sboyd at kernel.org>


From conleylee at foxmail.com  Tue Jan 11 19:13:47 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Wed, 12 Jan 2022 11:13:47 +0800
Subject: [PATCH v3 2/2] sunxi.yaml: add HAOYU Electronics Marsboard A20
In-Reply-To: <20220112031347.2492813-1-conleylee@foxmail.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220112031347.2492813-1-conleylee@foxmail.com>
Message-ID: <tencent_A92DC943F79DB360AE14672BB749BFE08A05@qq.com>

add haoyu,a20-marsboard bindings

Signed-off-by: Conley Lee <conleylee at foxmail.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..4bd93ae26bd1 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,11 @@ properties:
           - const: haoyu,a10-marsboard
           - const: allwinner,sun4i-a10
 
+      - description: HAOYU Electronics Marsboard A20
+        items:
+          - const: haoyu,a20-marsboard
+          - const: allwinner,sun7i-a20
+
       - description: MapleBoard MP130
         items:
           - const: mapleboard,mp130
-- 
2.31.1



From conleylee at foxmail.com  Tue Jan 11 19:13:45 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Wed, 12 Jan 2022 11:13:45 +0800
Subject: [PATCH v3 0/2] dt-bindings: arm: allwinner: add marsboard A20
In-Reply-To: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
Message-ID: <tencent_FDDA0568A55F5BBE4D20055A6C2D1E34EF08@qq.com>

ARM dts: sun7i: Add Marsboard A20 board

This patch add support for Marsboard A20 board, patch 1 is for the
dts file and patch 2 is for the biddings

The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.

Change since v1.
  - Spearate biddings and dts as two patches.
  - use SPDX tag

Change since v2.
  - reformat patch
  - dual-license with GPL and MIT
  - rename dts filename to sun7i-a20-haoyu-marsboard.dts

Conley Lee (2):
  sun7i-a20-haoyu-marsboard.dts: add marsboard-a20 support
  sunxi.yaml: add HAOYU Electronics Marsboard A20

 .../devicetree/bindings/arm/sunxi.yaml        |   5 +
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/sun7i-a20-haoyu-marsboard.dts    | 183 ++++++++++++++++++
 3 files changed, 189 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts

-- 
2.31.1



From conleylee at foxmail.com  Tue Jan 11 19:13:46 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Wed, 12 Jan 2022 11:13:46 +0800
Subject: [PATCH v3 1/2] sun7i-a20-haoyu-marsboard.dts: add marsboard-a20
 support
In-Reply-To: <20220112031347.2492813-1-conleylee@foxmail.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220112031347.2492813-1-conleylee@foxmail.com>
Message-ID: <tencent_00147CCBB6C9A0A0830DCE43F25DBC40A505@qq.com>

Add sun7i-a20-haoyu-marsboard.dts to support haoyu marsboard a20 SBC

Signed-off-by: Conley Lee <conleylee at foxmail.com>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/sun7i-a20-haoyu-marsboard.dts    | 183 ++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..5f1602d62927 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-icnova-swac.dtb \
 	sun7i-a20-lamobo-r1.dtb \
 	sun7i-a20-linutronix-testbox-v2.dtb \
+	sun7i-a20-haoyu-marsboard.dtb \
 	sun7i-a20-m3.dtb \
 	sun7i-a20-mk808c.dtb \
 	sun7i-a20-olimex-som-evb.dtb \
diff --git a/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
new file mode 100644
index 000000000000..4c6c6ae0c459
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Conley Lee
+ * Conley Lee <conleylee at foxmail.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "HAOYU Electronics Marsboard A20";
+	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&codec {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac_mii_pins {
+	pins = "PA0", "PA1", "PA2",
+	"PA3", "PA4", "PA5", "PA6",
+	"PA7", "PA8", "PA9", "PA10",
+	"PA11", "PA12", "PA13", "PA14",
+	"PA15", "PA16", "PA17";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_mii_pins>;
+	phy-handle = <&phy0>;
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	axp209: pmic at 34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
+	status = "okay";
+};
+
+&gmac_mdio {
+	phy0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&reg_ahci_5v {
+	status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1450000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&pio 7 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH4 */
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
-- 
2.31.1



From heying24 at huawei.com  Tue Jan 11 19:24:10 2022
From: heying24 at huawei.com (He Ying)
Date: Tue, 11 Jan 2022 22:24:10 -0500
Subject: [PATCH] arm64: entry: Save some nops when CONFIG_ARM64_PSEUDO_NMI is
 not set
In-Reply-To: <20220107085536.214501-1-heying24@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
Message-ID: <20220112032410.29231-1-heying24@huawei.com>

Arm64 pseudo-NMI feature code brings some additional nops
when CONFIG_ARM64_PSEUDO_NMI is not set, which is not
necessary. So add necessary ifdeffery to avoid it.

Signed-off-by: He Ying <heying24 at huawei.com>
---
 arch/arm64/kernel/entry.S | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 2f69ae43941d..ffc32d3d909a 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -300,6 +300,7 @@ alternative_else_nop_endif
 	str	w21, [sp, #S_SYSCALLNO]
 	.endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	/* Save pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	mrs_s	x20, SYS_ICC_PMR_EL1
@@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
 	msr_s	SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
+#endif
 
 	/* Re-enable tag checking (TCO set on exception entry) */
 #ifdef CONFIG_ARM64_MTE
@@ -330,6 +332,7 @@ alternative_else_nop_endif
 	disable_daif
 	.endif
 
+#ifdef CONFIG_ARM64_PSEUDO_NMI
 	/* Restore pmr */
 alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	ldr	x20, [sp, #S_PMR_SAVE]
@@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	dsb	sy				// Ensure priority change is seen by redistributor
 .L__skip_pmr_sync\@:
 alternative_else_nop_endif
+#endif
 
 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
 
-- 
2.17.1



From patchwork-bot+netdevbpf at kernel.org  Tue Jan 11 20:40:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 12 Jan 2022 04:40:10 +0000
Subject: [PATCH v3] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>
References: <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>
Message-ID: <164196241011.16336.16287095642350727734.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by Jakub Kicinski <kuba at kernel.org>:

On Tue, 11 Jan 2022 11:05:53 +0800 you wrote:
> This patch remove magic numbers in sun4i-emac.c and replace with macros
> defined in sun4i-emac.h
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
> Change since v2.
> - fix some code style issues
> 
> [...]

Here is the summary with links:
  - [v3] net: ethernet: sun4i-emac: replace magic number with macro
    https://git.kernel.org/netdev/net/c/274c224062ff

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From reijiw at google.com  Tue Jan 11 21:11:52 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Tue, 11 Jan 2022 21:11:52 -0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <CAJHc60ywYgAPfG11Ljkj3qzLoUn9mZPKnPH0P-HYS-pfs+A__g@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
 <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>
 <CAJHc60ywYgAPfG11Ljkj3qzLoUn9mZPKnPH0P-HYS-pfs+A__g@mail.gmail.com>
Message-ID: <CAAeT=FwA9X9eXrF+Q31Wzah=UkM-B8bMJObjJ=oCV0rjLfX6=g@mail.gmail.com>

On Mon, Jan 10, 2022 at 4:51 PM Raghavendra Rao Ananta
<rananta at google.com> wrote:
>
> On Sun, Jan 9, 2022 at 10:29 PM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Hi Raghu,
> >
> > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > <rananta at google.com> wrote:
> > >
> > > KVM regularly introduces new hypercall services to the guests without
> > > any consent from the Virtual Machine Manager (VMM). This means, the
> > > guests can observe hypercall services in and out as they migrate
> > > across various host kernel versions. This could be a major problem
> > > if the guest discovered a hypercall, started using it, and after
> > > getting migrated to an older kernel realizes that it's no longer
> > > available. Depending on how the guest handles the change, there's
> > > a potential chance that the guest would just panic.
> > >
> > > As a result, there's a need for the VMM to elect the services that
> > > it wishes the guest to discover. VMM can elect these services based
> > > on the kernels spread across its (migration) fleet. To remedy this,
> > > extend the existing firmware psuedo-registers, such as
> > > KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.
> > >
> > > These firmware registers are categorized based on the service call
> > > owners, and unlike the existing firmware psuedo-registers, they hold
> > > the features supported in the form of a bitmap.
> > >
> > > The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
> > > this extension, which returns the number of psuedo-firmware
> > > registers supported. During the VM initialization, the registers
> > > holds an upper-limit of the features supported by the corresponding
> > > registers. It's expected that the VMMs discover the features
> > > provided by each register via GET_ONE_REG, and writeback the
> > > desired values using SET_ONE_REG. KVM allows this modification
> > > only until the VM has started.
> > >
> > > Older VMMs can simply ignore the capability and the hypercall services
> > > will be exposed unconditionally to the guests, thus ensuring backward
> > > compatibility.
> > >
> > > In this patch, the framework adds the register only for ARM's standard
> > > secure services (owner value 4). Currently, this includes support only
> > > for ARM True Random Number Generator (TRNG) service, with bit-0 of the
> > > register representing mandatory features of v1.0. Other services are
> > > momentarily added in the upcoming patches.
> > >
> > > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_host.h |  12 ++++
> > >  arch/arm64/include/uapi/asm/kvm.h |   4 ++
> > >  arch/arm64/kvm/arm.c              |   4 ++
> > >  arch/arm64/kvm/hypercalls.c       | 103 +++++++++++++++++++++++++++++-
> > >  arch/arm64/kvm/trng.c             |   8 +--
> > >  include/kvm/arm_hypercalls.h      |   6 ++
> > >  6 files changed, 129 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 2a5f7f38006f..a32cded0371b 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -102,6 +102,15 @@ struct kvm_s2_mmu {
> > >  struct kvm_arch_memory_slot {
> > >  };
> > >
> > > +/**
> > > + * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
> > > + *
> > > + * @hvc_std_bmap: Bitmap of standard secure service calls
> > > + */
> > > +struct kvm_hvc_desc {
> > > +       u64 hvc_std_bmap;
> > > +};
> > > +
> > >  struct kvm_arch {
> > >         struct kvm_s2_mmu mmu;
> > >
> > > @@ -137,6 +146,9 @@ struct kvm_arch {
> > >
> > >         /* Memory Tagging Extension enabled for the guest */
> > >         bool mte_enabled;
> > > +
> > > +       /* Hypercall firmware register' descriptor */
> > > +       struct kvm_hvc_desc hvc_desc;
> > >  };
> > >
> > >  struct kvm_vcpu_fault_info {
> > > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > > index b3edde68bc3e..0d6f29c58456 100644
> > > --- a/arch/arm64/include/uapi/asm/kvm.h
> > > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > > @@ -281,6 +281,10 @@ struct kvm_arm_copy_mte_tags {
> > >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
> > >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
> > >
> > > +#define KVM_REG_ARM_STD_BMAP                   KVM_REG_ARM_FW_REG(3)
> > > +#define KVM_REG_ARM_STD_BIT_TRNG_V1_0          BIT(0)
> > > +#define KVM_REG_ARM_STD_BMAP_BIT_MAX           0       /* Last valid bit */
> > > +
> > >  /* SVE registers */
> > >  #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
> > >
> > > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > > index e4727dc771bf..56fe81565235 100644
> > > --- a/arch/arm64/kvm/arm.c
> > > +++ b/arch/arm64/kvm/arm.c
> > > @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> > >         kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
> > >
> > >         set_default_spectre(kvm);
> > > +       kvm_arm_init_hypercalls(kvm);
> > >
> > >         return ret;
> > >  out_free_stage2_pgd:
> > > @@ -283,6 +284,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> > >         case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > >                 r = system_has_full_ptr_auth();
> > >                 break;
> > > +       case KVM_CAP_ARM_HVC_FW_REG_BMAP:
> > > +               r = kvm_arm_num_fw_bmap_regs();
> > > +               break;
> >
> > Looking at the discussion for the v2 series,
> >
> >  https://lore.kernel.org/kvmarm/20211130101958.fcdqthphyhxzvzla at gator.home/
> >
> > I assume that the number of the pseudo-firmware bitmap registers
> > will be used to clear pseudo firmware bitmap registers that
> > userspace doesn't know.
> > I'm wondering how userspace can identify which pseudo-firmware
> > registers that KVM_GET_REG_LIST provides are the pseudo-firmware
> > bitmap registers that it doesn't know.
> > For instance, suppose pseudo-firmware registers that KVM_GET_REG_LIST
> > provides are KVM_REG_ARM_FW_REG(0) to KVM_REG_ARM_FW_REG(9), userspace
> > doesn't knows KVM_REG_ARM_FW_REG(6) to KVM_REG_ARM_FW_REG(9), and
> > KVM_CAP_ARM_HVC_FW_REG_BMAP returns 5, how can userspace identify
> > remaining two bitmap registers from those 4 (fw-reg #6 to #9)
> > firmware registers ?
> >
> In v3, we leave the decision upto the userspace. If the userspace
> encounters a register that it's unaware, it can choose either to clear
> it or let it get exposed to the guest as is (see the code snipped
> shared by Andrew in the link).
> Trying to understand the question better- are you asking how would
> userspace distinguish between bitmap and regular fw registers with
> intermixed sequence numbers?

Yes, that's my question.


> If yes, do you foresee a reason why they 'unaware' registers needed to
> be treated differently?

Since I'm not sure what the specification of 'unaware' (non-bitmap)
registers will be, it would be safer for us to assume that they might
need to be treated differently from the bitmap registers.
Considering there is KVM_REG_ARM_PSCI_VERSION, which KVM doesn't allow
userspace to set to 0, there might be similar registers that userspace
cannot set to 0 in the future.

BTW, If you assume that all those 'unaware' firmware registers are
treated in the same way, I don't think userspace needs the number of
those bitmap registers from KVM_CAP_ARM_HVC_FW_REG_BMAP (Instead,
I would think it can handle the 'unaware' registers with a list of
firmware registers from KVM_GET_REG_LIST).

> >
> > >         default:
> > >                 r = 0;
> > >         }
> > > diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> > > index 3c2fcf31ad3d..06243e4670eb 100644
> > > --- a/arch/arm64/kvm/hypercalls.c
> > > +++ b/arch/arm64/kvm/hypercalls.c
> > > @@ -58,6 +58,29 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
> > >         val[3] = lower_32_bits(cycles);
> > >  }
> > >
> > > +static bool kvm_arm_fw_reg_feat_enabled(u64 reg_bmap, u64 feat_bit)
> > > +{
> > > +       return reg_bmap & feat_bit;
> > > +}
> > > +
> > > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
> > > +{
> > > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> > > +
> > > +       switch (func_id) {
> > > +       case ARM_SMCCC_TRNG_VERSION:
> > > +       case ARM_SMCCC_TRNG_FEATURES:
> > > +       case ARM_SMCCC_TRNG_GET_UUID:
> > > +       case ARM_SMCCC_TRNG_RND32:
> > > +       case ARM_SMCCC_TRNG_RND64:
> > > +               return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
> > > +                                               KVM_REG_ARM_STD_BIT_TRNG_V1_0);
> > > +       default:
> > > +               /* By default, allow the services that aren't listed here */
> > > +               return true;
> > > +       }
> > > +}
> >
> > kvm_hvc_call_supported() could return true even for @func_id that
> > kvm_hvc_call_handler() returns -EINVAL for.  Is this behavior what
> > you really want ?
> Yes. My idea was to let kvm_hvc_call_supported() check for the
> support, while kvm_hvc_call_handler() does the real processing of the
> call.
>
> > If so, IMHO the function name might be a bit mis-leading.
> > "kvm_hvc_call_disabled" (and flip the return value)
> > might be closer to what it does(?).
> >
> Sorry, I'm unclear how flipping is helping. Wouldn't we return 'false'
> if we don't have a case for the func_id, indicating it's NOT disabled,
> but kvm_hvc_call_handler() can still return SMCCC_RET_NOT_SUPPORTED?

Yes, that's fine, too.
Since those services are disabled (because they are enabled by default),
I just thought checking 'disabled' might be closer to what it does than
checking 'enabled'.  But, 'enabled' is also fine.

> >
> > > +
> > >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > >  {
> > >         u32 func_id = smccc_get_function(vcpu);
> > > @@ -65,6 +88,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > >         u32 feature;
> > >         gpa_t gpa;
> > >
> > > +       if (!kvm_hvc_call_supported(vcpu, func_id))
> > > +               goto out;
> > > +
> > >         switch (func_id) {
> > >         case ARM_SMCCC_VERSION_FUNC_ID:
> > >                 val[0] = ARM_SMCCC_VERSION_1_1;
> > > @@ -143,6 +169,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > >                 return kvm_psci_call(vcpu);
> > >         }
> > >
> > > +out:
> > >         smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
> > >         return 1;
> > >  }
> > > @@ -153,9 +180,25 @@ static const u64 kvm_arm_fw_reg_ids[] = {
> > >         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
> > >  };
> > >
> > > +static const u64 kvm_arm_fw_reg_bmap_ids[] = {
> > > +       KVM_REG_ARM_STD_BMAP,
> > > +};
> > > +
> > > +void kvm_arm_init_hypercalls(struct kvm *kvm)
> > > +{
> > > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > > +
> > > +       hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
> > > +}
> > > +
> > > +int kvm_arm_num_fw_bmap_regs(void)
> > > +{
> > > +       return ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids);
> > > +}
> > > +
> > >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
> > >  {
> > > -       return ARRAY_SIZE(kvm_arm_fw_reg_ids);
> > > +       return ARRAY_SIZE(kvm_arm_fw_reg_ids) + kvm_arm_num_fw_bmap_regs();
> > >  }
> > >
> > >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> > > @@ -167,6 +210,11 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> > >                         return -EFAULT;
> > >         }
> > >
> > > +       for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids); i++) {
> > > +               if (put_user(kvm_arm_fw_reg_bmap_ids[i], uindices++))
> > > +                       return -EFAULT;
> > > +       }
> > > +
> > >         return 0;
> > >  }
> > >
> > > @@ -211,9 +259,20 @@ static int get_kernel_wa_level(u64 regid)
> > >         return -EINVAL;
> > >  }
> > >
> > > +static void
> > > +kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
> > > +{
> > > +       struct kvm *kvm = vcpu->kvm;
> > > +
> > > +       mutex_lock(&kvm->lock);
> > > +       *val = fw_reg_bmap;
> > > +       mutex_unlock(&kvm->lock);
> >
> > Why does it need to hold the lock ? (Wouldn't READ_ONCE be enough ?)
> >
> I don't have much experience with READ_ONCE at this point, but do you
> think this read can be protected again the read/write in
> kvm_arm_set_fw_reg_bmap()?

If kvm_arm_set_fw_reg_bmap is changed to use WRITE_ONCE to
update hvc_desc->hvc_*_bmap (kvm_arm_set_fw_reg_bmap still needs
to get the lock to prevent other vCPUs from running KVM_RUN),
I would think using READ_ONCE in kvm_arm_get_fw_reg_bmap() without
getting the lock should work (will see either old or new value).

Thanks,
Reiji


> >
> > > +}
> > > +
> > >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > >  {
> > >         void __user *uaddr = (void __user *)(long)reg->addr;
> > > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> > >         u64 val;
> > >
> > >         switch (reg->id) {
> > > @@ -224,6 +283,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > >         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
> > >                 val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
> > >                 break;
> > > +       case KVM_REG_ARM_STD_BMAP:
> > > +               kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
> > > +               break;
> > >         default:
> > >                 return -ENOENT;
> > >         }
> > > @@ -234,6 +296,43 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > >         return 0;
> > >  }
> > >
> > > +static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
> > > +{
> > > +       int ret = 0;
> > > +       struct kvm *kvm = vcpu->kvm;
> > > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > > +       u64 *fw_reg_bmap, fw_reg_features;
> > > +
> > > +       switch (reg_id) {
> > > +       case KVM_REG_ARM_STD_BMAP:
> > > +               fw_reg_bmap = &hvc_desc->hvc_std_bmap;
> > > +               fw_reg_features = ARM_SMCCC_STD_FEATURES;
> > > +               break;
> > > +       default:
> > > +               return -ENOENT;
> > > +       }
> > > +
> > > +       /* Check for unsupported bit */
> > > +       if (val & ~fw_reg_features)
> > > +               return -EINVAL;
> > > +
> > > +       mutex_lock(&kvm->lock);
> > > +
> > > +       /*
> > > +        * If the VM (any vCPU) has already started running, return success
> > > +        * if there's no change in the value. Else, return -EBUSY.
> > > +        */
> > > +       if (kvm_vm_has_started(kvm)) {
> > > +               ret = *fw_reg_bmap != val ? -EBUSY : 0;
> > > +               goto out;
> > > +       }
> > > +
> > > +       *fw_reg_bmap = val;
> > > +out:
> > > +       mutex_unlock(&kvm->lock);
> > > +       return ret;
> > > +}
> > > +
> > >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > >  {
> > >         void __user *uaddr = (void __user *)(long)reg->addr;
> > > @@ -310,6 +409,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > >                         return -EINVAL;
> > >
> > >                 return 0;
> > > +       case KVM_REG_ARM_STD_BMAP:
> > > +               return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
> > >         default:
> > >                 return -ENOENT;
> > >         }
> > > diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c
> > > index 99bdd7103c9c..23f912514b06 100644
> > > --- a/arch/arm64/kvm/trng.c
> > > +++ b/arch/arm64/kvm/trng.c
> > > @@ -60,14 +60,8 @@ int kvm_trng_call(struct kvm_vcpu *vcpu)
> > >                 val = ARM_SMCCC_TRNG_VERSION_1_0;
> > >                 break;
> > >         case ARM_SMCCC_TRNG_FEATURES:
> > > -               switch (smccc_get_arg1(vcpu)) {
> > > -               case ARM_SMCCC_TRNG_VERSION:
> > > -               case ARM_SMCCC_TRNG_FEATURES:
> > > -               case ARM_SMCCC_TRNG_GET_UUID:
> > > -               case ARM_SMCCC_TRNG_RND32:
> > > -               case ARM_SMCCC_TRNG_RND64:
> > > +               if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu)))
> > >                         val = TRNG_SUCCESS;
> >
> > kvm_hvc_call_supported() returns true for any values that are
> > not explicitly listed in kvm_hvc_call_supported() (i.e. it returns
> > true even for @func_id that are not any of ARM_SMCCC_TRNG_*).
> > So, I don't think it can simply use the current kvm_hvc_call_supported.
> >
> You are right. Probably I should leave the case statements as is (or
> think of some better way).
>
>
> Thanks for the review and suggestions.
>
> Regards,
> Raghavendra
> > Thanks,
> > Reiji
> >
> > > -               }
> > >                 break;
> > >         case ARM_SMCCC_TRNG_GET_UUID:
> > >                 smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]),
> > > diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
> > > index 5d38628a8d04..8fe68d8d6d96 100644
> > > --- a/include/kvm/arm_hypercalls.h
> > > +++ b/include/kvm/arm_hypercalls.h
> > > @@ -6,6 +6,9 @@
> > >
> > >  #include <asm/kvm_emulate.h>
> > >
> > > +#define ARM_SMCCC_STD_FEATURES \
> > > +       GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
> > > +
> > >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
> > >
> > >  static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
> > > @@ -42,9 +45,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
> > >
> > >  struct kvm_one_reg;
> > >
> > > +void kvm_arm_init_hypercalls(struct kvm *kvm);
> > > +int kvm_arm_num_fw_bmap_regs(void);
> > >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
> > >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
> > >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> > >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> > > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id);
> > >
> > >  #endif
> > > --
> > > 2.34.1.448.ga2b2bfdf31-goog
> > >


From chanho61.park at samsung.com  Tue Jan 11 21:21:25 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Wed, 12 Jan 2022 14:21:25 +0900
Subject: [PATCH v2 20/28] arm64: dts: exynos: align pinctrl with
 dtschema in ExynosAutov9
In-Reply-To: <20220111201722.327219-14-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <CGME20220111201852epcas2p2bb09ed439ccca57c51ece984727e87be@epcas2p2.samsung.com>
 <20220111201722.327219-14-krzysztof.kozlowski@canonical.com>
Message-ID: <000001d80774$3e971880$bbc54980$@samsung.com>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: Wednesday, January 12, 2022 5:17 AM
> To: Tomasz Figa <tomasz.figa at gmail.com>; Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com>; Sylwester Nawrocki
> <s.nawrocki at samsung.com>; Linus Walleij <linus.walleij at linaro.org>; Rob
> Herring <robh+dt at kernel.org>; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; linux-gpio at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>; Sam Protsenko
> <semen.protsenko at linaro.org>; Chanho Park <chanho61.park at samsung.com>;
> Alim Akhtar <alim.akhtar at gmail.com>
> Subject: [PATCH v2 20/28] arm64: dts: exynos: align pinctrl with dtschema
> in ExynosAutov9
> 
> Align the pin controller related nodes with dtschema.  No functional
> change expected.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Great.
Reviewed-by: Chanho Park <chanho61.park at samsung.com>
And you can also put
Tested-by: Chanho Park <chanho61.park at samsung.com>

Best Regards,
Chanho Park



From chanho61.park at samsung.com  Tue Jan 11 21:21:49 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Wed, 12 Jan 2022 14:21:49 +0900
Subject: [PATCH v2 26/28] pinctrl: samsung: add support for Exynos850
 and ExynosAutov9 wake-ups
In-Reply-To: <20220111201722.327219-20-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <CGME20220111201913epcas2p3208da25a15fe94b120706aa1c200c34f@epcas2p3.samsung.com>
 <20220111201722.327219-20-krzysztof.kozlowski@canonical.com>
Message-ID: <000101d80774$4cc9e450$e65dacf0$@samsung.com>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: Wednesday, January 12, 2022 5:17 AM
> To: Tomasz Figa <tomasz.figa at gmail.com>; Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com>; Sylwester Nawrocki
> <s.nawrocki at samsung.com>; Linus Walleij <linus.walleij at linaro.org>; Rob
> Herring <robh+dt at kernel.org>; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; linux-gpio at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>; Sam Protsenko
> <semen.protsenko at linaro.org>; Chanho Park <chanho61.park at samsung.com>;
> Alim Akhtar <alim.akhtar at gmail.com>
> Subject: [PATCH v2 26/28] pinctrl: samsung: add support for Exynos850 and
> ExynosAutov9 wake-ups
> 
> It seems that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences of their pin controller node capable of
> external wake-up interrupts:
> 1. No multiplexed external wake-up interrupt, only direct, 2. More than
> one pin controller capable of external wake-up interrupts.
> 
> Add support for dedicated Exynos850 and ExynosAutov9 compatibles.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Reviewed-by: Chanho Park <chanho61.park at samsung.com>
And you can also put
Tested-by: Chanho Park <chanho61.park at samsung.com>

Best Regards,
Chanho Park



From chanho61.park at samsung.com  Tue Jan 11 21:28:08 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Wed, 12 Jan 2022 14:28:08 +0900
Subject: [PATCH v2 01/28] pinctrl: samsung: drop pin banks references on
 error paths
In-Reply-To: <20220111201426.326777-2-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <CGME20220111201525epcas2p144b5308bb4ce008232366fae822ba464@epcas2p1.samsung.com>
 <20220111201426.326777-2-krzysztof.kozlowski@canonical.com>
Message-ID: <000201d80775$2f22af80$8d680e80$@samsung.com>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: Wednesday, January 12, 2022 5:14 AM
> To: Tomasz Figa <tomasz.figa at gmail.com>; Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com>; Sylwester Nawrocki
> <s.nawrocki at samsung.com>; Linus Walleij <linus.walleij at linaro.org>; Rob
> Herring <robh+dt at kernel.org>; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; linux-gpio at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>; Sam Protsenko
> <semen.protsenko at linaro.org>; Chanho Park <chanho61.park at samsung.com>;
> Alim Akhtar <alim.akhtar at gmail.com>; stable at vger.kernel.org
> Subject: [PATCH v2 01/28] pinctrl: samsung: drop pin banks references on
> error paths
> 
> The driver iterates over its devicetree children with
> for_each_child_of_node() and stores for later found node pointer.  This
> has to be put in error paths to avoid leak during re-probing.
> 
> Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device
> nodes")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Reviewed-by: Chanho Park <chanho61.park at samsung.com>

Best Regards,
Chanho Park



From chanho61.park at samsung.com  Tue Jan 11 21:28:56 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Wed, 12 Jan 2022 14:28:56 +0900
Subject: [PATCH v2 28/28] arm64: dts: exynos: use dedicated wake-up
 pinctrl compatible in ExynosAutov9
In-Reply-To: <20220111201722.327219-22-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <CGME20220111201838epcas2p313dbfd5a364c64f5286e332b434abf49@epcas2p3.samsung.com>
 <20220111201722.327219-22-krzysztof.kozlowski@canonical.com>
Message-ID: <000301d80775$4b8f7310$e2ae5930$@samsung.com>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: Wednesday, January 12, 2022 5:17 AM
> To: Tomasz Figa <tomasz.figa at gmail.com>; Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com>; Sylwester Nawrocki
> <s.nawrocki at samsung.com>; Linus Walleij <linus.walleij at linaro.org>; Rob
> Herring <robh+dt at kernel.org>; linux-arm-kernel at lists.infradead.org; linux-
> samsung-soc at vger.kernel.org; linux-gpio at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>; Sam Protsenko
> <semen.protsenko at linaro.org>; Chanho Park <chanho61.park at samsung.com>;
> Alim Akhtar <alim.akhtar at gmail.com>
> Subject: [PATCH v2 28/28] arm64: dts: exynos: use dedicated wake-up
> pinctrl compatible in ExynosAutov9
> 
> Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
> Exynos5, Exynos5433) with external wake-up interrupts, expected to have
> one interrupt for multiplexing these wake-up interrupts.  Also they
> expected to have exactly one pin controller capable of external wake-up
> interrupts.
> 
> It seems however that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences:
> 1. No multiplexed external wake-up interrupt, only direct, 2. More than
> one pin controller capable of external wake-up interrupts.
> 
> Use dedicated ExynosAutov9 compatible for its external wake-up interrupts
> controller to indicate the differences.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Reviewed-by: Chanho Park <chanho61.park at samsung.com>
And you can also put
Tested-by: Chanho Park <chanho61.park at samsung.com>

Best Regards,
Chanho Park



From kjain at linux.ibm.com  Tue Jan 11 21:35:51 2022
From: kjain at linux.ibm.com (kajoljain)
Date: Wed, 12 Jan 2022 11:05:51 +0530
Subject: [PATCH v4 01/48] libperf: Add comments to perf_cpu_map.
In-Reply-To: <20220105061351.120843-2-irogers@google.com>
References: <20220105061351.120843-1-irogers@google.com>
 <20220105061351.120843-2-irogers@google.com>
Message-ID: <7344589b-1e17-ea8f-2d31-2905331fdcb3@linux.ibm.com>



On 1/5/22 11:43 AM, Ian Rogers wrote:
> A particular observed problem is confusing the index with the CPU value,
> documentation should hopefully reduce this type of problem.
> 

Patch looks good.

Reviewed-by: Kajol Jain<kjain at linux.ibm.com>

> Reviewed-by: James Clark <james.clark at arm.com>
> Signed-off-by: Ian Rogers <irogers at google.com>
> ---
>  tools/lib/perf/include/internal/cpumap.h | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/tools/lib/perf/include/internal/cpumap.h b/tools/lib/perf/include/internal/cpumap.h
> index 840d4032587b..4054169c12c5 100644
> --- a/tools/lib/perf/include/internal/cpumap.h
> +++ b/tools/lib/perf/include/internal/cpumap.h
> @@ -4,9 +4,18 @@
>  
>  #include <linux/refcount.h>
>  
> +/**
> + * A sized, reference counted, sorted array of integers representing CPU
> + * numbers. This is commonly used to capture which CPUs a PMU is associated
> + * with. The indices into the cpumap are frequently used as they avoid having
> + * gaps if CPU numbers were used. For events associated with a pid, rather than
> + * a CPU, a single dummy map with an entry of -1 is used.
> + */
>  struct perf_cpu_map {
>  	refcount_t	refcnt;
> +	/** Length of the map array. */
>  	int		nr;
> +	/** The CPU values. */
>  	int		map[];
>  };
>  
> 


From sofia.trinh at edi.works  Tue Jan 11 22:07:19 2022
From: sofia.trinh at edi.works (Sofia Trinh)
Date: Tue, 11 Jan 2022 22:07:19 -0800
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <CAMwLHrZi0ZGFsuc74Yj3DErT1zyG2DEudS3ZgPEsexj0XfZJyA@mail.gmail.com>

On Tue, Jan 11, 2022 at 12:41 AM Yu Zhao <yuzhao at google.com> wrote:
>
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> > On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > > TLDR
> > > ====
> > > The current page reclaim is too expensive in terms of CPU usage and it
> > > often makes poor choices about what to evict. This patchset offers an
> > > alternative solution that is performant, versatile and
> > > straightforward.
> >
> > <snipped>
> >
> > > Summery
> > > =======
> > > The facts are:
> > > 1. The independent lab results and the real-world applications
> > >    indicate substantial improvements; there are no known regressions.
> > > 2. Thrashing prevention, working set estimation and proactive reclaim
> > >    work out of the box; there are no equivalent solutions.
> > > 3. There is a lot of new code; nobody has demonstrated smaller changes
> > >    with similar effects.
> > >
> > > Our options, accordingly, are:
> > > 1. Given the amount of evidence, the reported improvements will likely
> > >    materialize for a wide range of workloads.
> > > 2. Gauging the interest from the past discussions [14][15][16], the
> > >    new features will likely be put to use for both personal computers
> > >    and data centers.
> > > 3. Based on Google's track record, the new code will likely be well
> > >    maintained in the long term. It'd be more difficult if not
> > >    impossible to achieve similar effects on top of the existing
> > >    design.
> >
> > Hi Andrew, Linus,
> >
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> >
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.
>
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
>
> Having this patchset in the mainline will make your job easier :)
>
>    Alexandre - the XanMod Kernel maintainer
>                https://xanmod.org
>
>    Brian     - the Chrome OS kernel memory maintainer
>                https://www.chromium.org
>
>    Jan       - the Arch Linux Zen kernel maintainer
>                https://archlinux.org
>
>    Steven    - the Liquorix kernel maintainer
>                https://liquorix.net
>
>    Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                https://chromium.googlesource.com/chromiumos/third_party/kernel
>
> Also my gratitude to those who have helped test MGLRU:
>
>    Daniel - researcher at Michigan Tech
>             benchmarked memcached
>
>    Holger - who has been testing/patching/contributing to various
>             subsystems since ~2008
>
>    Shuang - researcher at University of Rochester
>             benchmarked fio and provided a report
>
>    Sofia  - EDI https://www.edi.works
>             benchmarked the top eight memory hogs and provided reports

Tested-by: Sofia Trinh <sofia.trinh at edi.works>


From conleylee at foxmail.com  Tue Jan 11 22:16:27 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Wed, 12 Jan 2022 14:16:27 +0800
Subject: [PATCH v3] net: ethernet: sun4i-emac: replace magic number with
 macro
In-Reply-To: <Yd2xC7ZaHrTAXcZd@Red>
References: <tencent_58B12979F0BFDB1520949A6DB536ED15940A@qq.com>
 <tencent_71466C2135CD1780B19D7844BE3F167C940A@qq.com>
 <Yd2xC7ZaHrTAXcZd@Red>
Message-ID: <tencent_236C8935F1179CB3D1788CBF3B179494D60A@qq.com>

On 01/11/22 at 05:32??, Corentin Labbe wrote:
> Date: Tue, 11 Jan 2022 17:32:11 +0100
> From: Corentin Labbe <clabbe.montjoie at gmail.com>
> To: Conley Lee <conleylee at foxmail.com>
> Cc: davem at davemloft.net, kuba at kernel.org, mripard at kernel.org,
>  wens at csie.org, netdev at vger.kernel.org,
>  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Subject: Re: [PATCH v3] net: ethernet: sun4i-emac: replace magic number
>  with macro
> 
> Le Tue, Jan 11, 2022 at 11:05:53AM +0800, Conley Lee a ?crit :
> > This patch remove magic numbers in sun4i-emac.c and replace with macros
> > defined in sun4i-emac.h
> > 
> > Signed-off-by: Conley Lee <conleylee at foxmail.com>
> 
> Hello
> 
> I sent a CI job witch next-20220107+yourpatch and saw no regression.
> 
> Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
> Tested-on: sun4i-a10-olinuxino-lime
> 
> Thanks!
> Regards
> 
Could you please provide more information about it ? I test it on my
marsboard-a20 and everything work well.

Thanks 


From leo.yan at linaro.org  Tue Jan 11 22:40:47 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Wed, 12 Jan 2022 14:40:47 +0800
Subject: [PATCH v2 0/7] pid: Introduce helper task_is_in_root_ns()
In-Reply-To: <20211208083320.472503-1-leo.yan@linaro.org>
References: <20211208083320.472503-1-leo.yan@linaro.org>
Message-ID: <20220112064046.GA3316542@leoy-ThinkPad-X240s>

Hi David,

On Wed, Dec 08, 2021 at 04:33:13PM +0800, Leo Yan wrote:
> The kernel uses open code to check if a process is in root PID namespace
> or not in several places.
> 
> Suggested by Suzuki, this patch set is to create a helper function
> task_is_in_init_pid_ns() to replace open code.
> 
> This patch set has been applied on the mainline kernel and built for
> Arm64 kernel with enabling all relevant modules.

I'd like sync for how to merging this patch set.  Except patch 05/07,
all of other patches in this patch set have been received the reviewed
or acked tags.  So could you pick up this patch set?

Furthermore, we have another patch set "coresight: etm: Correct PID
tracing for non-root namespace" [1], which is dependent on the current
patch set and it has been Acked by Suzuki.

I'd like to get opinions from David and CoreSight maintainers Mathieu
and Suzuki, should we merge the patch set [1] via David's tree as well
to avoid dependency issue, or prefer to merge it via CoreSight tree?
If David prefers the prior option, I can resend the patch set [1] with
looping David.

Thanks,
Leo

[1] https://lore.kernel.org/lkml/20211213121323.1887180-1-leo.yan at linaro.org/


From boger at wirenboard.com  Tue Jan 11 22:51:22 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Wed, 12 Jan 2022 09:51:22 +0300
Subject: [PATCH v2 0/3] add support for Allwinner R40 CAN controller
In-Reply-To: <20220111155709.56501-1-boger@wirenboard.com>
References: <20220111155709.56501-1-boger@wirenboard.com>
Message-ID: <4c7fa5f4-8a65-c840-7928-5e78559a4732@wirenboard.com>

11.01.2022 18:57, Evgeny Boger ?????:
> Allwinner R40 (also known as A40i, T3, V40) has a CAN controller. The
> controller is the same as in earlier A10 and A20 SoCs, but needs reset
> line to be deasserted before use.
>
> This patch series introduce new compatible for R40 CAN controller,
> add support for reset line in driver and add the corresponding nodes
> to the SoC .dtsi file.
>
> The CAN IP was documented in early V40 datasheet [1]. It also fully
> supported in vendor BSP. However, CAN description was removed from
> more recent A40i, T3 and R40 user manuals and datasheets.
> Anyway, we verified that the CAN controller is indeed there and tested
> it extensively on A40i-based custom hardware [2].
>
> [1] https://linux-sunxi.org/File:Allwinner_V40_Datasheet_V1.0.pdf
> [2] https://wirenboard.com/en/product/wiren-board-7/
>
> Changes in v2:
>    - sort pinmux nodes alphabetically and mark them with omit-if-no-ref
>
> Evgeny Boger (3):
>    dt-bindings: net: can: add support for Allwinner R40 CAN controller
>    can: sun4i_can: add support for R40 CAN controller
>    ARM: dts: sun8i: r40: add node for CAN controller
>
>   .../net/can/allwinner,sun4i-a10-can.yaml      | 24 ++++++++
>   arch/arm/boot/dts/sun8i-r40.dtsi              | 21 +++++++
>   drivers/net/can/sun4i_can.c                   | 61 ++++++++++++++++++-
>   3 files changed, 105 insertions(+), 1 deletion(-)
>
oh, v1 is already in Linus' tree. Please ignore this series then.

I'll send patches addressing the comments soon.




From alexander.stein at ew.tq-group.com  Tue Jan 11 22:58:00 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 12 Jan 2022 07:58:00 +0100
Subject: (EXT) Re: (EXT) Re: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x:
 add dt overlays for serial modes
In-Reply-To: <CAJ+vNU2PxF=9VwMv4f8N5W5Gs2Ynxdn9jHTSkWH7zd3Fo5hBiw@mail.gmail.com>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <2226437.ElGaqSPkdT@steina-w>
 <CAJ+vNU2PxF=9VwMv4f8N5W5Gs2Ynxdn9jHTSkWH7zd3Fo5hBiw@mail.gmail.com>
Message-ID: <6686721.lOV4Wx5bFT@steina-w>

Am Dienstag, 11. Januar 2022, 18:53:29 CET schrieb Tim Harvey:
> On Mon, Jan 10, 2022 at 11:20 PM Alexander Stein
> 
> <alexander.stein at ew.tq-group.com> wrote:
> > Am Dienstag, 11. Januar 2022, 01:00:21 CET schrieb Tim Harvey:
> > > [SNIP]
> > > 
> > > > diff --git a/arch/arm64/boot/dts/freescale/Makefile
> > > > b/arch/arm64/boot/dts/freescale/Makefile index
> > > > a14a6173b765..5ec8d59347b6
> > > > 100644
> > > > --- a/arch/arm64/boot/dts/freescale/Makefile
> > > > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > > > @@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) +=
> > > > imx8mm-var-som-symphony.dtb
> > > > 
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
> > > > 
> > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
> > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
> > > > 
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
> > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
> > > 
> > > [SNIP]
> > > I'm mostly interested to see if my approach to dt fragments here and
> > > the naming of the files makes sense to others.
> > > 
> > > This patch causes the kernel to build dtbo files for:
> > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dtbo
> > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dtbo
> > > 
> > > The intention is that these files are used by boot firmware (U-Boot)
> > > to adjust the dtb before passing it to the kernel.
> > 
> > Hi Tim,
> > 
> > do these dtbo actually work? I'm wondering because I was trying to
> > useoverlays myself and noticed that the had to be compiled with -@ for
> > u-boot to be able
> > to apply them. Apparently there are 2 possibilities:
> Alexander,
> 
> Yes, they work, but I do manually set DTC_FLAGS=-@ when building
> kernel dtbs to make them work.

I see, I expected something like this. That's why I responded to you.

> > * Set "DTC_FLAGS_[dtb] := -@" yourself
> > See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> > commit/?id=e426d63e752bdbe7d5ba2d872319dde9ab844a07
> > 
> > * Use dedicated overlay target
> > See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> > commit/?id=15d16d6dadf6947ac7f9a686c615995c5a426ce2
> > 
> > You use neither of them. IIRC just naming the target file .dtbo will not
> > apply symbols (-Q) during dtc call. Can you verify using 'V=1'
> > Also I'm wondering which way is the best to go.
> 
> I wasn't aware there was a way to do this via Makefiles. It seems that
> perhaps Rob's approach with 'kbuild: Add generic rule to apply
> fdtoverlay' is a way to avoid having to add them all manually in the
> first approach? I must admit I'm not sure how to use that.

I tried using this myself for my custom board. I feel it is a bit cumbersome 
to get it right.
See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
arch/arm64/boot/dts/xilinx/Makefile for an example.

Essentially you define your .dtb as before and add another target (e.g. sm-
k26-revA-sck-kv-g-revA-dtbs) where you add your .dtbo _after_ the original 
.dtb. This target needs to be added to 'dtb-y' as before.

I suspect this way is needed to check the .dtbo against the base .dtb if it 
actually matches.

HTH
Alexander






From wenst at chromium.org  Tue Jan 11 23:02:10 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 12 Jan 2022 15:02:10 +0800
Subject: [PATCH 1/7] pinctrl: pinconf-generic: Print arguments for
 bias-pull-*
In-Reply-To: <2dc957b1-300f-161c-edb6-efacf11942e0@collabora.com>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-2-wenst@chromium.org>
 <2dc957b1-300f-161c-edb6-efacf11942e0@collabora.com>
Message-ID: <CAGXv+5HV+Ca74paF-L54owyCBtBwTNU0r2aT7drjmBxo2dV=uA@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:42 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> Il 11/01/22 12:22, Chen-Yu Tsai ha scritto:
> > The bias-pull-* properties, or PIN_CONFIG_BIAS_PULL_* pin config
> > parameters, accept optional arguments in ohms denoting the strength of
> > the pin bias.
> >
> > Print these values out in debugfs as well.
> >
> > Fixes: eec450713e5c ("pinctrl: pinconf-generic: Add flag to print arguments")
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
> Tested on qcom-SC7180 Trogdor, mtk-MT8173 Elm, and others;

Cool! I'll take that as a Tested-by tag.

> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From jagan at amarulasolutions.com  Tue Jan 11 23:09:46 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Wed, 12 Jan 2022 12:39:46 +0530
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
References: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAMty3ZAojTyw3H8VprH9aiyTyWjeL8oqPxNNr=J33_5FrcUj9Q@mail.gmail.com>

On Tue, Jan 4, 2022 at 3:30 PM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:
>
> DRM bridge drivers are now attaching their DSI device at probe time,
> which requires us to register our DSI host in order to let the bridge
> to probe: this recently started producing an endless -EPROBE_DEFER
> loop on some machines that are using external bridges, like the
> parade-ps8640, found on the ACER Chromebook R13.
>
> Now that the DSI hosts/devices probe sequence is documented, we can
> do adjustments to the mtk_dsi driver as to both fix now and make sure
> to avoid this situation in the future: for this, following what is
> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> mtk_dsi_ops.attach callback and delete it in the detach callback;
> keeping in mind that we are registering a drm_bridge for our DSI,
> which is only used/attached if the DSI Host is bound, it wouldn't
> make sense to keep adding our bridge at probe time (as it would
> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> that one to the dsi host attach function (and remove it in detach).
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> ---

Eventually I've observed similar issue on other Component based DSI
controllers, hence

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>


From hch at lst.de  Tue Jan 11 23:56:09 2022
From: hch at lst.de (Christoph Hellwig)
Date: Wed, 12 Jan 2022 08:56:09 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64
 in fcntl.h
In-Reply-To: <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
Message-ID: <20220112075609.GA4854@lst.de>

On Tue, Jan 11, 2022 at 04:33:30PM +0100, Arnd Bergmann wrote:
> This is a very subtle change to the exported UAPI header contents:
> On 64-bit architectures, the three unusable numbers are now always
> shown, rather than depending on a user-controlled symbol.

Well, the change is bigger and less subtle.  Before this change the
constants were never visible to userspace at all (except on mips),
because the #ifdef CONFIG_64BIT it never set for userspace builds.

> This is probably what we want here for compatibility reasons, but I think
> it should be explained in the changelog text, and I'd like Jeff or Bruce
> to comment on it as well: the alternative here would be to make the
> uapi definition depend on __BITS_PER_LONG==32, which is
> technically the right thing to do but more a of a change.

I can change this to #if __BITS_PER_LONG==32 || defined(__KERNEL__),
but it will still be change in what userspace sees.


From yuzhao at google.com  Wed Jan 12 00:05:51 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 12 Jan 2022 01:05:51 -0700
Subject: [PATCH v6 7/9] mm: multigenerational lru: eviction
In-Reply-To: <87czkyzhfe.fsf@linux.ibm.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-8-yuzhao@google.com>
 <87czkyzhfe.fsf@linux.ibm.com>
Message-ID: <Yd6L349/aJd8hbYn@google.com>

On Tue, Jan 11, 2022 at 04:07:57PM +0530, Aneesh Kumar K.V wrote:
> ...
> 
>  +static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int swappiness,
> > +			  int *type_scanned, struct list_head *list)
> > +{
> > +	int i;
> > +	int type;
> > +	int scanned;
> > +	int tier = -1;
> > +	DEFINE_MIN_SEQ(lruvec);
> > +
> > +	VM_BUG_ON(!seq_is_valid(lruvec));
> > +
> > +	/*
> > +	 * Try to make the obvious choice first. When anon and file are both
> > +	 * available from the same generation, interpret swappiness 1 as file
> > +	 * first and 200 as anon first.
> > +	 */
> > +	if (!swappiness)
> > +		type = 1;
> > +	else if (min_seq[0] < min_seq[1])
> > +		type = 0;
> > +	else if (swappiness == 1)
> > +		type = 1;
> > +	else if (swappiness == 200)
> > +		type = 0;
> > +	else
> > +		type = get_type_to_scan(lruvec, swappiness, &tier);
> > +
> 
> Wondering wether it will make it simpler to use
> #define ANON 0
> #define FILE 1
> 
> and then
> 	else if (min_seq[ANON] < min_seq[FILE])
> 		type = ANON;
> 
> The usage of 0/1 across code do confuse

I agree, and I plan to do this later because the existing code uses
this convention and needs renaming too.


From yuzhao at google.com  Wed Jan 12 00:08:14 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 12 Jan 2022 01:08:14 -0700
Subject: [PATCH v6 5/9] mm: multigenerational lru: mm_struct list
In-Reply-To: <YdxPEdsfl771Z7IX@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-6-yuzhao@google.com>
 <YdgChw4vNb43XsU/@dhcp22.suse.cz> <YdjYkFmtMdrYg736@google.com>
 <YdxPEdsfl771Z7IX@dhcp22.suse.cz>
Message-ID: <Yd6MbsVkU7fChCrc@google.com>

On Mon, Jan 10, 2022 at 04:21:53PM +0100, Michal Hocko wrote:
> On Fri 07-01-22 17:19:28, Yu Zhao wrote:
> > On Fri, Jan 07, 2022 at 10:06:15AM +0100, Michal Hocko wrote:
> > > On Tue 04-01-22 13:22:24, Yu Zhao wrote:
> > > > To exploit spatial locality, the aging prefers to walk page tables to
> > > > search for young PTEs. And this patch paves the way for that.
> > > > 
> > > > An mm_struct list is maintained for each memcg, and an mm_struct
> > > > follows its owner task to the new memcg when this task is migrated.
> > > 
> > > How does this work actually for the memcg reclaim? I can see you
> > > lru_gen_migrate_mm on the task migration. My concern is, though, that
> > > such a task leaves all the memory behind in the previous memcg (in
> > > cgroup v2, in v1 you can opt in for charge migration). If you move the
> > > mm to a new memcg then you age it somewhere where the memory is not
> > > really consumed.
> > 
> > There are two options to gather the accessed bit: page table walks and
> > rmap walks. Page table walks sweep dense hotspots that are NOT
> > misplaced in terms of reclaim scope (lruvec); rmap walks cover what
> > page table walks miss, e.g., misplaced dense hotspots or sparse ones.
> > 
> > Dense hotspots are stored in Bloom filters for each lruvec.
> > 
> > If an mm leaves everything in the old memcg, page table walks in the
> > new memcg reclaim path basically ignore this mm after the first scan,
> > because everything is misplaced.
> 
> OK, so do I get it right that pages mapped from a different memcg than
> the reclaimed one are considered effectivelly non-present from the the
> reclaim logic POV? This would be worth mentioning in the migration
> callback because it is not really that straightforward to put those two
> together.

That's correct. Will document this in detail.

> > In the old memcg reclaim path, page table walks won't see this mm
> > at all. But rmap walks will catch everything later in the eviction
> > path, i.e., lru_gen_look_around(). This function is less efficient
> > compared with page table walks because, for each rmap walk of a
> > non-shared page, it only can gather the accessed bit from 64 PTEs at
> > most. But it's still a lot faster than the original rmap, which only
> > gathers the accessed bit from a single PTE, for each walk of a
> > non-shared page.
> 
> Again, something that should be really documented.

Noted.


From narmstrong at baylibre.com  Wed Jan 12 00:28:22 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:22 +0100
Subject: [PATCH v3 0/9] arm64: dts: meson: add support for ac2xx devices
In-Reply-To: <20220112022713.25962-1-christianshewitt@gmail.com>
References: <20220112022713.25962-1-christianshewitt@gmail.com>
Message-ID: <164197609474.825600.7106897196640617717.b4-ty@baylibre.com>

Hi,

On Wed, 12 Jan 2022 02:27:04 +0000, Christian Hewitt wrote:
> This series adds support for several popular Amlogic S905X3 (SM1) Android
> Set-Top Box devices. Like most Android box devices, they ship in variants
> with multiple RAM, eMMC, WiFi and BT configurations. RAM and eMMC are not
> something we need to consider to get a working boot, but we do need to get
> the correct connectivity spec. Broadly speaking we see boxes with Higher
> and Lower spec connectivity; High spec is Gigabit Ethernet and Faster dual
> antennna WiFi, and Lower spec is Megabit Ethernet and a single antenna. In
> some low-end boxes BT is omitted.
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/9] arm64: dts: meson: add common SM1 ac2xx dtsi
      https://git.kernel.org/amlogic/c/b5a03ecec30c1a71d51de3e73a2e7ab23c3ddeb6
[2/9] dt-bindings: arm: amlogic: add X96-AIR bindings
      https://git.kernel.org/amlogic/c/d2ecf5ae59c8eef9fe2ad20d83977c2889646d4c
[3/9] arm64: dts: meson: add initial device-trees for X96-AIR
      https://git.kernel.org/amlogic/c/37875d9dcb42d489ba28518b50fed0b2ba768b03
[4/9] dt-bindings: vendor-prefixes: add cyx prefix
      https://git.kernel.org/amlogic/c/3dbabb9ac746ab01c71aa019c58a2e0cc6eafe1c
[5/9] dt-bindings: arm: amlogic: add A95XF3-AIR bindings
      https://git.kernel.org/amlogic/c/bc7811bd4e884bbc21cc7b7031cb7c297662db9c
[6/9] arm64: dts: meson: add initial device-trees for A95XF3-AIR
      https://git.kernel.org/amlogic/c/8b749a0205bd41cafae37e878fd4a1b57b7b24f3
[7/9] dt-bindings: vendor-prefixes: add haochuangyi prefix
      https://git.kernel.org/amlogic/c/bf510ace20ac153946d6d0ab6305dd8aa52eec6c
[8/9] dt-bindings: arm: amlogic: add H96-Max bindings
      https://git.kernel.org/amlogic/c/2ca889b1201625d36efcd51d25371d937a6a0b8f
[9/9] arm64: dts: meson: add initial device-tree for H96-Max
      https://git.kernel.org/amlogic/c/ac7b4433714a37e2c4b61acc6ce9b4538175e836

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:28:23 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:23 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <20211215030236.340841-1-art@khadas.com>
References: <20211215030236.340841-1-art@khadas.com>
Message-ID: <164197609473.825600.7789792176979118539.b4-ty@baylibre.com>

Hi,

On Wed, 15 Dec 2021 11:02:36 +0800, Artem Lapkin wrote:
> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] arm64: dts: meson-sm1: add spdifin spdifout nodes
      https://git.kernel.org/amlogic/c/86f2159468d55aca1793c1f0f3d95213501b32f3

-- 
Neil


From narmstrong at baylibre.com  Wed Jan 12 00:28:24 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:28:24 +0100
Subject: [PATCH V3] dt-bindings: arm: amlogic: add S4 based AQ222 bindings
In-Reply-To: <20211221030014.434-1-xianwei.zhao@amlogic.com>
References: <20211221030014.434-1-xianwei.zhao@amlogic.com>
Message-ID: <164197609473.825600.4070247492095618792.b4-ty@baylibre.com>

Hi,

On Tue, 21 Dec 2021 11:00:14 +0800, Xianwei Zhao wrote:
> Add bindings for the new Amlogic S4 SoC family,
> and add binds the compatible for the Amlogic S4 Based AQ222 board.
> 
> S4 is an application processor designed for hybrid OTT/IP Set To
> Box(STB) and high-end media box applications, with quad core Cortex-A35.
> 
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] dt-bindings: arm: amlogic: add S4 based AQ222 bindings
      https://git.kernel.org/amlogic/c/fc32ca1ea6f74c1be7abf9d21b0bac8bce11bec3

-- 
Neil


From arnd at arndb.de  Wed Jan 12 00:28:26 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 12 Jan 2022 09:28:26 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <20220112075609.GA4854@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
 <20220112075609.GA4854@lst.de>
Message-ID: <CAK8P3a1ONn=FiPU3669MjBMntS-1K5bgX4pHforUsYJ7yhwZ-g@mail.gmail.com>

On Wed, Jan 12, 2022 at 8:56 AM Christoph Hellwig <hch at lst.de> wrote:
>
> On Tue, Jan 11, 2022 at 04:33:30PM +0100, Arnd Bergmann wrote:
> > This is a very subtle change to the exported UAPI header contents:
> > On 64-bit architectures, the three unusable numbers are now always
> > shown, rather than depending on a user-controlled symbol.
>
> Well, the change is bigger and less subtle.  Before this change the
> constants were never visible to userspace at all (except on mips),
> because the #ifdef CONFIG_64BIT it never set for userspace builds.

I suppose you mean /always/ visible here, with that ifndef.

> > This is probably what we want here for compatibility reasons, but I think
> > it should be explained in the changelog text, and I'd like Jeff or Bruce
> > to comment on it as well: the alternative here would be to make the
> > uapi definition depend on __BITS_PER_LONG==32, which is
> > technically the right thing to do but more a of a change.
>
> I can change this to #if __BITS_PER_LONG==32 || defined(__KERNEL__),
> but it will still be change in what userspace sees.

Exactly, that is the tradeoff, which is why I'd like the flock maintainers
to say which way they prefer. We can either do it more correctly (hiding
the constants from user space when they are not usable), or with less
change (removing the incorrect #ifdef). Either way sounds reasonable
to me, I mainly care that this is explained in the changelog and that the
maintainers are aware of the two options.

        Arnd


From narmstrong at baylibre.com  Wed Jan 12 00:30:37 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:30:37 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-2-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-2-gary.bisson@boundarydevices.com>
Message-ID: <cd92df54-caa1-deed-3a93-929ba43adba8@baylibre.com>

On 03/01/2022 16:46, Gary Bisson wrote:
> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Linus Walleij <linus.walleij at linaro.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: linux-gpio at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> index cd9656b13836..d182a575981e 100644
> --- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> +++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
> @@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
>  static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
>  
>  /* pwm_f */
> +static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
> +static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
>  static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
>  static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
>  
> @@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
>  	GROUP(tdm_c_dout2_z,		4),
>  	GROUP(tdm_c_dout3_z,		4),
>  	GROUP(mclk1_z,			4),
> +	GROUP(pwm_f_z,			5),
>  
>  	/* bank GPIOX */
>  	GROUP(sdio_d0,			1),
> @@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
>  	GROUP(tdm_c_dout3_a,		2),
>  	GROUP(mclk0_a,			1),
>  	GROUP(mclk1_a,			2),
> +	GROUP(pwm_f_a,			3),
>  };
>  
>  /* uart_ao_a */
> @@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
>  };
>  
>  static const char * const pwm_f_groups[] = {
> -	"pwm_f_x", "pwm_f_h",
> +	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
>  };
>  
>  static const char * const cec_ao_a_h_groups[] = {
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Wed Jan 12 00:30:54 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:30:54 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220103154616.308376-3-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-3-gary.bisson@boundarydevices.com>
Message-ID: <a4282cb9-3ebd-0c95-7a47-522eb1bbb770@baylibre.com>

On 03/01/2022 16:46, Gary Bisson wrote:
> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index 00c6f53290d4..af1357c48bee 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -894,6 +894,22 @@ mux {
>  						};
>  					};
>  
> +					pwm_f_z_pins: pwm-f-z {
> +						mux {
> +							groups = "pwm_f_z";
> +							function = "pwm_f";
> +							bias-disable;
> +						};
> +					};
> +
> +					pwm_f_a_pins: pwm-f-a {
> +						mux {
> +							groups = "pwm_f_a";
> +							function = "pwm_f";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_f_x_pins: pwm-f-x {
>  						mux {
>  							groups = "pwm_f_x";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Wed Jan 12 00:33:42 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:33:42 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <20220103154616.308376-4-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
Message-ID: <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>

Hi,

On 03/01/2022 16:46, Gary Bisson wrote:
> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>   both options
> - RTS/CTS signals however only have 1 option available
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index af1357c48bee..3a7773ffbd08 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -1952,6 +1952,33 @@ mux {
>  						};
>  					};
>  
> +					uart_ao_b_1_pins: uart-ao-b-1 {
> +						mux {
> +							groups = "uart_ao_b_tx_2",
> +								 "uart_ao_b_rx_3";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_2_pins: uart-ao-b-2 {
> +						mux {
> +							groups = "uart_ao_b_tx_8",
> +								 "uart_ao_b_rx_9";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};

I'm not fan of these nodes namings.

Perhaps :
- uart-ao-b-2-3
- uart-ao-b-8-9

so the actual pins numbers used are more clear ?

> +
> +					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
> +						mux {
> +							groups = "uart_ao_b_cts",
> +								 "uart_ao_b_rts";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_a_e_pins: pwm-a-e {
>  						mux {
>  							groups = "pwm_a_e";
> 



From yuzhao at google.com  Wed Jan 12 00:35:52 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 12 Jan 2022 01:35:52 -0700
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <YdwKB3SfF7hkB9Xv@kernel.org>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <YdwKB3SfF7hkB9Xv@kernel.org>
Message-ID: <Yd6S6Js1W4AnFFmv@google.com>

On Mon, Jan 10, 2022 at 12:27:19PM +0200, Mike Rapoport wrote:
> Hi,
> 
> On Tue, Jan 04, 2022 at 01:22:27PM -0700, Yu Zhao wrote:
> > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> > 
> > Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention.
> > Compared with the size-based approach, e.g., [1], this time-based
> > approach has the following advantages:
> > 1) It's easier to configure because it's agnostic to applications and
> >    memory sizes.
> > 2) It's more reliable because it's directly wired to the OOM killer.
> > 
> > Add /sys/kernel/debug/lru_gen for working set estimation and proactive
> > reclaim. Compared with the page table-based approach and the PFN-based
> > approach, e.g., mm/damon/[vp]addr.c, this lruvec-based approach has
> > the following advantages:
> > 1) It offers better choices because it's aware of memcgs, NUMA nodes,
> >    shared mappings and unmapped page cache.
> > 2) It's more scalable because it's O(nr_hot_evictable_pages), whereas
> >    the PFN-based approach is O(nr_total_pages).
> > 
> > Add /sys/kernel/debug/lru_gen_full for debugging.
> > 
> > [1] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/
> > 
> > Signed-off-by: Yu Zhao <yuzhao at google.com>
> > Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> > ---
> >  Documentation/vm/index.rst        |   1 +
> >  Documentation/vm/multigen_lru.rst |  62 +++++
> 
> The description of user visible interfaces should go to
> Documentation/admin-guide/mm
> 
> Documentation/vm/multigen_lru.rst should have contained design description
> and the implementation details and it would be great to actually have such
> document.

Will do, thanks.

> >  include/linux/nodemask.h          |   1 +
> >  mm/vmscan.c                       | 415 ++++++++++++++++++++++++++++++
> >  4 files changed, 479 insertions(+)
> >  create mode 100644 Documentation/vm/multigen_lru.rst
> > 
> > diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
> > index 6f5ffef4b716..f25e755b4ff4 100644
> > --- a/Documentation/vm/index.rst
> > +++ b/Documentation/vm/index.rst
> > @@ -38,3 +38,4 @@ algorithms.  If you are looking for advice on simply allocating memory, see the
> >     unevictable-lru
> >     z3fold
> >     zsmalloc
> > +   multigen_lru
> > diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
> > new file mode 100644
> > index 000000000000..6f9e0181348b
> > --- /dev/null
> > +++ b/Documentation/vm/multigen_lru.rst
> > @@ -0,0 +1,62 @@
> > +.. SPDX-License-Identifier: GPL-2.0
> > +
> > +=====================
> > +Multigenerational LRU
> > +=====================
> > +
> > +Quick start
> > +===========
> > +Runtime configurations
> > +----------------------
> > +:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
> > + feature wasn't enabled by default.
> 
> Required for what? This sentence seem to lack context. Maybe add an
> overview what is Multigenerational LRU so that users will have an idea what
> these knobs control.

Apparently I left an important part of this quick start in the next
patch, where Kconfig options are added. I'm wonder whether I should
squash the next patch into this one.

I always separate Kconfig changes and leave them in the last patch
because it gives me peace of mind knowing it'll never give any auto
bisectors a hard time.

But I saw people not following this practice, and I'm also tempted to
do so. Can anybody remind me whether it's considered a bad practice to
have code changes and Kconfig changes in the same patch?

> > +
> > +Recipes
> > +=======
> 
> Some more context here will be also helpful.

Will do.

> > +Personal computers
> > +------------------
> > +:Thrashing prevention: Write ``N`` to
> > + ``/sys/kernel/mm/lru_gen/min_ttl_ms`` to prevent the working set of
> > + ``N`` milliseconds from getting evicted. The OOM killer is invoked if
> > + this working set can't be kept in memory. Based on the average human
> > + detectable lag (~100ms), ``N=1000`` usually eliminates intolerable
> > + lags due to thrashing. Larger values like ``N=3000`` make lags less
> > + noticeable at the cost of more OOM kills.
> > +
> > +Data centers
> > +------------
> > +:Debugfs interface: ``/sys/kernel/debug/lru_gen`` has the following
> > + format:
> > + ::
> > +
> > +   memcg  memcg_id  memcg_path
> > +     node  node_id
> > +       min_gen  birth_time  anon_size  file_size
> > +       ...
> > +       max_gen  birth_time  anon_size  file_size
> > +
> > + ``min_gen`` is the oldest generation number and ``max_gen`` is the
> > + youngest generation number. ``birth_time`` is in milliseconds.
> > + ``anon_size`` and ``file_size`` are in pages.
> 
> And what does oldest and youngest generations mean from the user
> perspective?

Good question. Will add more details in the next spin.


From narmstrong at baylibre.com  Wed Jan 12 00:36:23 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:36:23 +0100
Subject: [PATCH V2 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
References: <20211230094434.3053195-1-shunzhou.jiang@amlogic.com>
 <20211230094434.3053195-3-shunzhou.jiang@amlogic.com>
 <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
Message-ID: <b2a9b8f0-2b12-c49f-9609-21999b1fffc8@baylibre.com>

Hi Shunzhou,

On 30/12/2021 23:15, Martin Blumenstingl wrote:
> On Thu, Dec 30, 2021 at 10:44 AM Shunzhou.Jiang
> <shunzhou.jiang at amlogic.com> wrote:
>>
>> From: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>>
>> Add support s4 Power controller. In s4, power control
>> registers are in secure domain, and should be accessed by smc.
>>
>> Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
> Also here I don't have any datasheet to compare this with, so this gets my:
> Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> 
> [...]
>> +       SEC_PD(S4_VPU_HDMI,     GENPD_FLAG_ALWAYS_ON),
>> +       SEC_PD(S4_USB_COMB,     GENPD_FLAG_ALWAYS_ON),
>> +       SEC_PD(S4_GE2D,         0),
>> +       SEC_PD(S4_ETH,          GENPD_FLAG_ALWAYS_ON),
> For the A1 SoC's UART entry we have the following comment which
> explains why we want to to be "always on":
>   UART should keep working in ATF after suspend and before resume
> 
> If for some reason you need to re-send this series then it would be
> great if you could add a comment above each entry with
> GENPD_FLAG_ALWAYS_ON.
> It will help others (like me) understand these SoCs better.

Can you resend with those comments added so I can apply the patches ?

Thanks,
Neil

> 
> 
> Best regards,
> Martin
> 



From narmstrong at baylibre.com  Wed Jan 12 00:39:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:39:35 +0100
Subject: [PATCH V4] arm64: dts: add support for S4 based Amlogic AQ222
In-Reply-To: <20220106112214.6987-1-xianwei.zhao@amlogic.com>
References: <20220106112214.6987-1-xianwei.zhao@amlogic.com>
Message-ID: <164197677138.826461.16430612345551126459.b4-ty@baylibre.com>

Hi,

On Thu, 6 Jan 2022 19:22:14 +0800, Xianwei Zhao wrote:
> Add basic support for the Amlogic S4 based Amlogic AQ222 board:
> which describe components as follows: CPU, GIC, IRQ, Timer, UART.
> It's capable of booting up into the serial console.
> 
> 

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v5.18/dt64)

[1/1] arm64: dts: add support for S4 based Amlogic AQ222
      https://git.kernel.org/amlogic/c/1c1475389af077a9636c22dcb8c9ef498b48fcfc

-- 
Neil


From maxime at cerno.tech  Wed Jan 12 00:42:23 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 12 Jan 2022 09:42:23 +0100
Subject: [PATCH v2 1/1] phy: sun4i-usb: fix phy write on H3 and newer
In-Reply-To: <20220111165153.63632-2-boger@wirenboard.com>
References: <20220111165153.63632-1-boger@wirenboard.com>
 <20220111165153.63632-2-boger@wirenboard.com>
Message-ID: <20220112084223.j5nm4ennfv7f6ekt@houat>

Hi,

On Tue, Jan 11, 2022 at 07:51:53PM +0300, Evgeny Boger wrote:
> We noticed that USB hosts won't reliably enumerate USB HS (480Mb/s) devices
> in our custom A40i-based design. What we observe is that after several
> attempts USB device would fail to enumerate on EHCI port (HS) and will be
> enumerated instead on OHCI (FS, 12Mb/s) only:
> 
> [    6.368009] usb 1-1: new high-speed USB device number 5 using ehci-platform
> [    6.818008] usb 1-1: device not accepting address 5, error -71
> [    6.823868] usb usb1-port1: unable to enumerate USB device
> [    7.308013] usb 3-1: new full-speed USB device number 2 using ohci-platform
> [    7.575045] usb 3-1: not running at top speed; connect to a high speed hub
> 
> On some boards one of the ports would work in high-speed mode, but
> on most of the boards all three USB ports would only work in FS mode.
> 
> At the same time, USB work flawlessly in high-speed mode in vendor kernel.
> 
> Looking for the differences in USB code, we found the issue with USB PHY
> register initialization. Basically, USB PHY driver sets a couple of
> internal undocumented PHY registers to the predefined constants. These PHY
> registers are accessed in a very (and I mean VERY) weird way by shifting
> register addresses and values bit-by-bit. This access method was slightly
> changed starting from H3 SoC, according to the BSP source for different
> SoCs.
> 
> As a result, mainline PHY driver won't set these PHY registers properly
> resulting in unreliable enumeration in high-speed mode.
> 
> We don't know whether this issue will result in broken HS mode on all
> affected SoCs or instead the A40i is an unfortunate exception. What we
> indeed verified, is that BSPs for all affected SoCs write these registers
> properly while mainline kernel don't. We also were able to reproduce the
> USB issue on a couple of A40i boards from other vendors, so we are pretty
> sure these registers have to always be properly set, regardlress of
> a hardware layout.
> 
> The proposed patch is tested on A40i-based Wiren Board 7 building
> automation controller. More details are below.
> 
> On older SoCs (prior to H3) PHY register are accessed by manipulating
> the common register for all PHYs. PHY index is specified by pulsing
> usbc bit.
> 
> Newer SoCs leave the access procedure mostly unchanged, the
> difference being that the latch registers are separate for each PHY.
> 
> Additionally, accessing USB PHY registers is only possible if phy0 is
> routed to musb IP instead of HCI.
> 
> Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
> R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.
> 
> On A83t, H6, H616, T507 and probably on more recent hardware,
> these PHY registers are not used in vendor BSP.
> So don't set v2 flag for these even newer SoCs as a precaution.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>

This should probably be sent to stable, and have a Fixes tag?

> ---
>  drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
>  1 file changed, 39 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
> index 788dd5cdbb7d..cf10e385f199 100644
> --- a/drivers/phy/allwinner/phy-sun4i-usb.c
> +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
> @@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
>  	bool dedicated_clocks;
>  	bool enable_pmu_unk1;
>  	bool phy0_dual_route;
> +	bool phy_reg_access_v2;
>  	int missing_phys;
>  };
>  
> @@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>  				int len)
>  {
>  	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
> -	u32 temp, usbc_bit = BIT(phy->index * 2);
> +	u32 otgctl_val, temp, usbc_bit;
>  	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
> +	void __iomem *phyctl_latch;
>  	unsigned long flags;
>  	int i;
>  
>  	spin_lock_irqsave(&phy_data->reg_lock, flags);
>  
> +	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
> +	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
> +	 * Newer SoCs leave the access procedure mostly unchanged, the difference
> +	 * being that the latch registers are separate for each PHY.
> +	 */

Multi-line comments need to start with an empty line

> +	if (phy_data->cfg->phy_reg_access_v2) {
> +		if (phy->index == 0)
> +			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
> +		else
> +			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
> +		usbc_bit = 1;
> +
> +		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
> +		 * As it's not clear whether is this related to actual PHY
> +		 * routing or rather the hardware is just reusing the same bit,
> +		 * don't check phy0_dual_route here.
> +		 */

Ditto

Thanks!
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/fe47e3df/attachment.sig>

From maxime at cerno.tech  Wed Jan 12 00:48:31 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 12 Jan 2022 09:48:31 +0100
Subject: [PATCH RESEND v3] arm64: dts: allwinner: a64: olinuxino: Enable
 audio
In-Reply-To: <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
 <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>
Message-ID: <20220112084831.cwu6qcvxoygvfcyy@houat>

Hi,

On Tue, Jan 11, 2022 at 09:08:23PM +0100, Philip Rinn wrote:
> Enable the audio hardware on the Olimex A64-OLinuXino board family.
> Tested on the A64-OLinuXino-2Ge8G-IND variant.
> 
> Signed-off-by: Philip Rinn <rinni at inventati.org>
> 
> ---
> 
> 
> Changes in v2: added missing &sound {...} part
> Changes in v3: removed HDMI audio part as requested by Jernej ?krabec
> 
>  arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts    | 30 +++++++++++++++++++
> 
>  1 file changed, 30 insertions(+)
> 
> 
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
> 
> index ec7e2c0e82c1..6f2674bb1b7f 100644
> 
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
> 
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts

Your mailer scrambled the patch completely, please use git send-email

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/8c608a5d/attachment-0001.sig>

From wenst at chromium.org  Wed Jan 12 00:53:31 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 12 Jan 2022 16:53:31 +0800
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <20220111112244.1483783-8-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-8-wenst@chromium.org>
Message-ID: <CAGXv+5Gq0uH-eA799f1MRgzeUU9fsfi-Xz0XyW7ZJW==i_mcYg@mail.gmail.com>

On Tue, Jan 11, 2022 at 7:23 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> Some of the MediaTek chips that utilize the Paris pinctrl driver library
> support a lower drive strength (<= 1mA) than the standard drive strength
> settings (2~16 mA) on certain pins. This was previously supported by the
> custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
> "mediatek,drive-strength-adv" device tree property.
>
> The drive strength values for this hardware are 125, 250, 500, and 1000 mA,
> and can be readily described by the existing "drive-strength-microamp",
> which then gets parsed by the generic pinconf library into the parameter
> PIN_CONFIG_DRIVE_STRENGTH_UA.

So I am actually unsure how to implement support for this properly.
My intention was to map "mediatek,drive-strength-adv" to
"drive-strength-microamp". This implies using the advanced mode if
the property is present, and vice versa.

(Also unsure if such a binding would be acceptable.)

However the pin configs are passed in one-by-one within the driver, so
it doesn't seem viable to check for the absence of a certain parameter.
This might involve a bit more rewriting.

ChenYu

> Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
> custom parameter around for backward compatibility.
>
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>
> The indentation in the switch/case blocks is getting somewhat out of
> control. I also have some cleanup changes to reverse the logic of the
> if/break statements. Not sure if it should be done before or after this
> patch though.
>
> ---
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 84 ++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 678c8aa33012..5a94903ae372 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = {
>         "func12", "func13", "func14", "func15",
>  };
>
> +/*
> + * This section supports converting to/from custom MTK_PIN_CONFIG_DRV_ADV
> + * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs.
> + *
> + * The custom value encodes three hardware bits as follows:
> + *
> + *   |           Bits           |
> + *   | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA)
> + *   ------------------------------------------------
> + *   |    x   |    x   |    0   | disabled, use standard drive strength
> + *   -------------------------------------
> + *   |    0   |    0   |    1   |  125 uA
> + *   |    0   |    1   |    1   |  250 uA
> + *   |    1   |    0   |    1   |  500 uA
> + *   |    1   |    1   |    1   | 1000 uA
> + */
> +static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 };
> +
> +static int mtk_drv_adv_to_uA(int val)
> +{
> +       /* This should never happen. */
> +       if (WARN_ON_ONCE(val < 0 || val > 7))
> +               return -EINVAL;
> +
> +       /* Bit 0 simply enables this hardware part */
> +       if (!(val & BIT(0)))
> +               return -EINVAL;
> +
> +       return mtk_drv_adv_uA[(val >> 1)];
> +}
> +
> +static int mtk_drv_uA_to_adv(int val)
> +{
> +       switch (val) {
> +       case 125:
> +               return 0x1;
> +       case 250:
> +               return 0x3;
> +       case 500:
> +               return 0x5;
> +       case 1000:
> +               return 0x7;
> +       }
> +
> +       return -EINVAL;
> +}
> +
>  static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev *pctldev,
>                                           struct pinctrl_gpio_range *range,
>                                           unsigned int pin)
> @@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev *pctldev,
>
>                 break;
>         case PIN_CONFIG_DRIVE_STRENGTH:
> +               if (hw->soc->adv_drive_get) {
> +                       err = hw->soc->adv_drive_get(hw, desc, &ret);
> +                       if (!err) {
> +                               err = mtk_drv_adv_to_uA(ret);
> +                               if (err > 0) {
> +                                       /* PIN_CONFIG_DRIVE_STRENGTH_UA used */
> +                                       err = -EINVAL;
> +                                       break;
> +                               }
> +                       }
> +               }
> +
>                 if (hw->soc->drive_get)
>                         err = hw->soc->drive_get(hw, desc, &ret);
>                 else
>                         err = -ENOTSUPP;
>                 break;
> +       case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +               if (hw->soc->adv_drive_get) {
> +                       err = hw->soc->adv_drive_get(hw, desc, &ret);
> +                       if (err)
> +                               break;
> +                       err = mtk_drv_adv_to_uA(ret);
> +                       if (err < 0)
> +                               break;
> +
> +                       ret = err;
> +                       err = 0;
> +               } else {
> +                       err = -ENOTSUPP;
> +               }
> +               break;
>         case MTK_PIN_CONFIG_TDSEL:
>         case MTK_PIN_CONFIG_RDSEL:
>                 reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> @@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
>                 else
>                         err = -ENOTSUPP;
>                 break;
> +       case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +               if (hw->soc->adv_drive_set) {
> +                       err = mtk_drv_uA_to_adv(arg);
> +                       if (err < 0)
> +                               break;
> +                       err = hw->soc->adv_drive_set(hw, desc, err);
> +               } else {
> +                       err = -ENOTSUPP;
> +               }
> +               break;
>         case MTK_PIN_CONFIG_TDSEL:
>         case MTK_PIN_CONFIG_RDSEL:
>                 reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> --
> 2.34.1.575.g55b058a8bb-goog
>


From narmstrong at baylibre.com  Wed Jan 12 00:57:10 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:57:10 +0100
Subject: [PATCH v3] media: meson: vdec: Fix a NULL pointer dereference in
 amvdec_add_ts()
In-Reply-To: <CA+Cm_xSOv5NnW5GXcKKGi8bQSvT45iH6=65YJk3EG6uW0c5_Vw@mail.gmail.com>
References: <20211214144613.35fec82a@coco.lan>
 <20211215033535.40422-1-zhou1615@umn.edu>
 <368bc1b7-ff86-beaa-6749-afbe5960eaeb@xs4all.nl>
 <CA+Cm_xSOv5NnW5GXcKKGi8bQSvT45iH6=65YJk3EG6uW0c5_Vw@mail.gmail.com>
Message-ID: <7e9f1b17-7087-3513-84b9-f5dd25211b87@baylibre.com>

Hi,

On 11/01/2022 14:03, Qingyang Zhou wrote:
> Hi Hans:
> 
> Here I certify that this is an origin patch I wrote. I did not copy Neil's patch, and I did not know his patch.
> 
> Neil, please post your original patch here, so everyone can see both patches.
> 
> Yours?
> Zhou Qingyang.
> 
> On Tue, Jan 11, 2022 at 5:16 PM Hans Verkuil <hverkuil-cisco at xs4all.nl <mailto:hverkuil-cisco at xs4all.nl>> wrote:
> 
>     Zhou Qingyang, this is exactly the patch Neil wrote, except you just stuck your
>     name on it. Not nice.
> 
>     Neil, can you post your patch with your own Signed-off-by, then I'll take that one.
> 
>     Regards,
> 
>     ? ? ? ? Hans
> 
>     On 15/12/2021 04:35, Zhou Qingyang wrote:
>     > In amvdec_add_ts(), there is a dereference of kzalloc(), which could lead
>     > to a NULL pointer dereference on failure of kzalloc().
>     >
>     > Fix this bug by adding a NULL check of new_ts.
>     >
>     > This bug was found by a static analyzer[1].
>     >
>     > Builds with CONFIG_VIDEO_MESON_VDEC=m show no new warnings,
>     > and our static analyzer no longer warns about this code.
>     >
>     > Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
>     > Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu <mailto:zhou1615 at umn.edu>>
>     > ---
>     >
>     > [1] The analysis employs differential checking to identify inconsistent
>     > security operations (e.g., checks or kfrees) between two code paths and
>     > confirms that the inconsistent operations are not recovered in the
>     > current function or the callers, so they constitute bugs.
>     >
>     > Note that, as a bug found by static analysis, it can be a false
>     > positive or hard to trigger. Multiple researchers have cross-reviewed
>     > the bug.
>     >
>     > Changes in v3:
>     >? ?-? Change the description of patch
>     >? ?-? Turn the return type from 'void' to 'int'
>     >? ?-? Check the return value in the caller 'esparser_queue()'
>     >
>     > Changes in v2:
>     >? ?-? Delete dev_err() message
>     >
>     >? drivers/staging/media/meson/vdec/esparser.c? ? ?| 7 ++++++-
>     >? drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>     >? drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>     >? 3 files changed, 14 insertions(+), 5 deletions(-)
>     >
>     > diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
>     > index db7022707ff8..095100a50da8 100644
>     > --- a/drivers/staging/media/meson/vdec/esparser.c
>     > +++ b/drivers/staging/media/meson/vdec/esparser.c
>     > @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>     >?
>     >? ? ? ?offset = esparser_get_offset(sess);
>     >?
>     > -? ? ?amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>     > +? ? ?ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
>     > +? ? ?if (!ret) {
>     > +? ? ? ? ? ? ?v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
>     > +? ? ? ? ? ? ?return ret;
>     > +? ? ?}
>     > +
>     >? ? ? ?dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>     >? ? ? ? ? ? ? ?vb->timestamp, payload_size, offset, vbuf->flags);
>     >?
>     > diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > index b9125c295d1d..06fd66539797 100644
>     > --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
>     > @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>     >? }
>     >? EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>     >?
>     > -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > -? ? ? ? ? ? ? ? struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>     > +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > +? ? ? ? ? ? ? ?struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>     >? {
>     >? ? ? ?struct amvdec_timestamp *new_ts;
>     >? ? ? ?unsigned long flags;
>     >?
>     >? ? ? ?new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
>     > +? ? ?if (!new_ts)
>     > +? ? ? ? ? ? ?return -ENOMEM;
>     > +
>     >? ? ? ?new_ts->ts = ts;
>     >? ? ? ?new_ts->tc = tc;
>     >? ? ? ?new_ts->offset = offset;
>     > @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     >? ? ? ?spin_lock_irqsave(&sess->ts_spinlock, flags);
>     >? ? ? ?list_add_tail(&new_ts->list, &sess->timestamps);
>     >? ? ? ?spin_unlock_irqrestore(&sess->ts_spinlock, flags);
>     > +? ? ?return 0;
>     >? }
>     >? EXPORT_SYMBOL_GPL(amvdec_add_ts);
>     >?
>     > diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > index 88137d15aa3a..4bf3e61d081b 100644
>     > --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
>     > @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>     >? ?* @offset: offset in the VIFIFO where the associated packet was written
>     >? ?* @flags: the vb2_v4l2_buffer flags
>     >? ?*/
>     > -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > -? ? ? ? ? ? ? ? struct v4l2_timecode tc, u32 offset, u32 flags);
>     > +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>     > +? ? ? ? ? ? ? ?struct v4l2_timecode tc, u32 offset, u32 flags);
>     >? void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>     >?
>     >? /**
> 

Let's inspect:

I posted a probable solution the 09/12/2021 in a reply to 20211209085840.2081024-1-jiasheng at iscas.ac.cn :

===================><=============================
diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..df733eff9ac7 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,11 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)

        offset = esparser_get_offset(sess);

-       amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+       ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+       if (ret) {
+               v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+               return ret;
+       }
        dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
                vb->timestamp, payload_size, offset, vbuf->flags);

diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index b9125c295d1d..593b2ccbece2 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,15 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);

-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-                  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                 struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
        struct amvdec_timestamp *new_ts;
        unsigned long flags;

        new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+       if (!new_ts)
+               return -ENOMEM;
        new_ts->ts = ts;
        new_ts->tc = tc;
        new_ts->offset = offset;
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-                  struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+                 struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
===================><=============================


Then the patches were sent:
- 20211210015620.2143555-1-jiasheng at iscas.ac.cn on 10/12/2021
- 20211215033535.40422-1-zhou1615 at umn.edu on 15/12/2021

They are extremely close but not similar, mostly indenting differs.

Both patches have the missing final "return 0" in amvdec_add_ts which is missing in my proposal.

But only 20211210015620.2143555-1-jiasheng at iscas.ac.cn has the correct "if (ret)" in esparser_queue().
Patch 20211215033535.40422-1-zhou1615 at umn.ed has a wrong "if (!ret)".

But when comparing, 20211215033535.40422-1-zhou1615 at umn.edu is an almost exact copy of my proposal, minus the fixes and the bogus return check.

To be honest, there is a limited way to fix this, it's probable 20211215033535.40422-1-zhou1615 at umn.edu was written independently from
my proposal since there is a bug return check, and 20211210015620.2143555-1-jiasheng at iscas.ac.cn was rewritten from my proposal.

Since 20211215033535.40422-1-zhou1615 at umn.ed has a bogus return check, it should be naked.

I'll only ask 20211210015620.2143555-1-jiasheng at iscas.ac.cn to be resent with a "Suggested-by" and indentation fixed like my proposal.

Neil



From jacopo at jmondi.org  Wed Jan 12 00:58:35 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 09:58:35 +0100
Subject: [PATCH v3 17/23] media: atmel: atmel-isc-base: use mutex to lock
 awb workqueue from streaming
In-Reply-To: <20211213134940.324266-18-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-18-eugen.hristev@microchip.com>
Message-ID: <20220112085835.twjhxjnigl3uhgqj@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:34PM +0200, Eugen Hristev wrote:
> The AWB workqueue runs in a kernel thread and needs to be synchronized
> w.r.t. the streaming status.
> It is possible that streaming is stopped while the AWB workq is running.
> In this case it is likely that the check for isc->stop is done at one point
> in time, but the AWB computations are done later, including a call to
> isc_update_profile, which requires streaming to be started.
> Thus , isc_update_profile will fail if during this operation sequence the
> streaming was stopped.
> To solve this issue, a mutex is added, that will serialize the awb work and
> streaming stopping, with the mention that either streaming is stopped
> completely including termination of the last frame is done, and after that
> the AWB work can check stream status and stop; either first AWB work is
> completed and after that the streaming can stop correctly.
> The awb spin lock cannot be used since this spinlock is taken in the same
> context and using it in the stop streaming will result in a recursion BUG.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
>  drivers/media/platform/atmel/atmel-isc-base.c | 31 ++++++++++++++++---
>  drivers/media/platform/atmel/atmel-isc.h      |  1 +
>  2 files changed, 28 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index b0c3ed21f372..53cac1aac0fd 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -401,6 +401,7 @@ static void isc_stop_streaming(struct vb2_queue *vq)
>  	struct isc_buffer *buf;
>  	int ret;
>
> +	mutex_lock(&isc->awb_mutex);
>  	v4l2_ctrl_activate(isc->do_wb_ctrl, false);
>
>  	isc->stop = true;
> @@ -410,6 +411,8 @@ static void isc_stop_streaming(struct vb2_queue *vq)
>  		v4l2_err(&isc->v4l2_dev,
>  			 "Timeout waiting for end of the capture\n");
>
> +	mutex_unlock(&isc->awb_mutex);
> +
>  	/* Disable DMA interrupt */
>  	regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
>
> @@ -1416,10 +1419,6 @@ static void isc_awb_work(struct work_struct *w)
>  	u32 min, max;
>  	int ret;
>
> -	/* streaming is not active anymore */
> -	if (isc->stop)
> -		return;
> -
>  	if (ctrls->hist_stat != HIST_ENABLED)
>  		return;
>
> @@ -1470,7 +1469,24 @@ static void isc_awb_work(struct work_struct *w)
>  	}
>  	regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
>  		     hist_id | baysel | ISC_HIS_CFG_RAR);

isc_stop_streaming() calls runtime_put and here you access the hw.

Feels like it's safer to hold the mutex for the whole duration of the
AWB routine ?

> +
> +	/*
> +	 * We have to make sure the streaming has not stopped meanwhile.
> +	 * ISC requires a frame to clock the internal profile update.
> +	 * To avoid issues, lock the sequence with a mutex
> +	 */
> +	mutex_lock(&isc->awb_mutex);
> +
> +	/* streaming is not active anymore */
> +	if (isc->stop) {
> +		mutex_unlock(&isc->awb_mutex);
> +		return;
> +	};
> +
>  	isc_update_profile(isc);
> +
> +	mutex_unlock(&isc->awb_mutex);
> +
>  	/* if awb has been disabled, we don't need to start another histogram */
>  	if (ctrls->awb)
>  		regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
> @@ -1549,6 +1565,8 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>
>  		isc_update_awb_ctrls(isc);
>
> +		mutex_lock(&isc->awb_mutex);
> +
>  		if (!isc->stop) {
>  			/*
>  			 * If we are streaming, we can update profile to
> @@ -1563,6 +1581,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>  			 */
>  			v4l2_ctrl_activate(isc->do_wb_ctrl, false);
>  		}
> +		mutex_unlock(&isc->awb_mutex);
>
>  		/* if we have autowhitebalance on, start histogram procedure */
>  		if (ctrls->awb == ISC_WB_AUTO && !isc->stop &&
> @@ -1754,6 +1773,7 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
>  {
>  	struct isc_device *isc = container_of(notifier->v4l2_dev,
>  					      struct isc_device, v4l2_dev);
> +	mutex_destroy(&isc->awb_mutex);
>  	cancel_work_sync(&isc->awb_work);
>  	video_unregister_device(&isc->video_dev);
>  	v4l2_ctrl_handler_free(&isc->ctrls.handler);
> @@ -1866,6 +1886,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>  	isc->current_subdev = container_of(notifier,
>  					   struct isc_subdev_entity, notifier);
>  	mutex_init(&isc->lock);
> +	mutex_init(&isc->awb_mutex);
> +
>  	init_completion(&isc->comp);
>
>  	/* Initialize videobuf2 queue */
> @@ -1941,6 +1963,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>  	video_unregister_device(vdev);
>
>  isc_async_complete_err:
> +	mutex_destroy(&isc->awb_mutex);
>  	mutex_destroy(&isc->lock);
>  	return ret;
>  }
> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> index 0b6370d7775f..c2cb805faff3 100644
> --- a/drivers/media/platform/atmel/atmel-isc.h
> +++ b/drivers/media/platform/atmel/atmel-isc.h
> @@ -307,6 +307,7 @@ struct isc_device {
>  	struct work_struct	awb_work;
>
>  	struct mutex		lock; /* serialize access to file operations */
> +	struct mutex		awb_mutex; /* serialize access to streaming status from awb work queue */
>  	spinlock_t		awb_lock; /* serialize access to DMA buffers from awb work queue */
>
>  	struct regmap_field	*pipeline[ISC_PIPE_LINE_NODE_NUM];
> --
> 2.25.1
>


From narmstrong at baylibre.com  Wed Jan 12 00:57:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 09:57:51 +0100
Subject: [PATCH] arm64: dts: meson-sm1: add spdifin spdifout nodes
In-Reply-To: <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>
References: <20211215030236.340841-1-art@khadas.com>
 <1jtuekrfsf.fsf@starbuckisacylon.baylibre.com>
Message-ID: <b4b62e3d-dc43-a56c-06c5-78e6ee7f6303@baylibre.com>

On 03/01/2022 16:35, Jerome Brunet wrote:
> 
> On Wed 15 Dec 2021 at 11:02, Artem Lapkin <email2tema at gmail.com> wrote:
> 
>> Add spdifin spdifout nodes for Amlogic SM1 SoCs.
>              ^ add (same in the title)
> 
>>
>> Signed-off-by: Artem Lapkin <art at khadas.com>
>> ---
>>
>> SPDIF IN and SPDIF OUT both tested and works fine for VIM3L (meson-sm1)
>> same as for VIM3 (meson-g12)
>>
>> SPDIF in and SPDIF OUT both pins available via GPIO header (SPDIF_OUT PIN
>> 13 spdif_ao_out_pins and SPDIF_IN PIN 35 - same PWM_F spdif_in_h_pins)
>>
>> https://lore.kernel.org/linux-arm-kernel/1jtuhwvqxa.fsf at starbuckisacylon.baylibre.com/t/
>>
>> ALSA spdifin test example
>> =========================
>>
>> # arecord -fS16_LE -r48000 -c2 -Dplug:spdifin
>>
>> # cat .asoundrc
>> pcm.spdifin {
>> type iec958
>> slave {
>> pcm "hw:0,1"
>> format IEC958_SUBFRAME_LE
>> }
>> }
>>
>> DT sound card configs for testing
>> =================================
>>
>> &spdifout {
>>     pinctrl-0 = <&spdif_ao_out_pins>;
>>     pinctrl-names = "default";
>>     status = "okay";
>> };
>>
>> &spdifin {
>>     pinctrl-0 = <&spdif_in_h_pins>;
>>     pinctrl-names = "default";
>>     status = "okay";
>> };
>>
>> ...
>>     spdif_dit: audio-codec-1 {
>> 	#sound-dai-cells = <0>;
>> 	compatible = "linux,spdif-dit";
>> 	status = "okay";
>> 	sound-name-prefix = "DIT";
>>     };
>>
>>     spdif_dir: audio-codec-2 {
>> 	#sound-dai-cells = <0>;
>> 	compatible = "linux,spdif-dir";
>> 	status = "okay";
>> 	sound-name-prefix = "DIR";
>>     };
>> ...
>> 	audio-routing = ...
>> 		"TODDR_B IN 3", "SPDIFIN Capture",
>> 		"SPDIFOUT IN 0", "FRDDR_A OUT 3";
>>
>> ...
>> 	dai-link-10 {
>> 	    sound-dai = <&spdifout>;
>>
>> 	    codec-0 {
>> 		sound-dai = <&spdif_dit>;
>> 	    };
>> 	};
>>
>> 	/* spdif or toslink interface */
>> 	dai-link-11 {
>> 	    sound-dai = <&spdifin>;
>>
>> 	    codec-0 {
>> 		sound-dai = <&spdif_dir>;
>> 	    };
>> 	};
>> ...
>>
>> ---
>>  arch/arm64/boot/dts/amlogic/meson-sm1.dtsi | 27 ++++++++++++++++++++++
>>  1 file changed, 27 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> index 3d8b1f4f2001..1e0adf259d61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
>> @@ -356,6 +356,33 @@ tdmin_lb: audio-controller at 3c0 {
>>  			status = "disabled";
>>  		};
>>  
>> +		spdifin: audio-controller at 400 {
>> +			compatible = "amlogic,g12a-spdifin",
>> +			"amlogic,axg-spdifin";
>> +			reg = <0x0 0x400 0x0 0x30>;
>> +			#sound-dai-cells = <0>;
>> +			sound-name-prefix = "SPDIFIN";
>> +			interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
>> +			clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
>> +			<&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
>> +			clock-names = "pclk", "refclk";
>> +			resets = <&clkc_audio AUD_RESET_SPDIFIN>;
>> +			status = "disabled";
>> +		};
>> +
>> +		spdifout: audio-controller at 480 {
> 
> Node should still be named spdifout_a, even if the spdifout_b is not added yet
> 
>> +			compatible = "amlogic,g12a-spdifout",
>> +			"amlogic,axg-spdifout";
>> +			reg = <0x0 0x480 0x0 0x50>;
>> +			#sound-dai-cells = <0>;
>> +			sound-name-prefix = "SPDIFOUT";
> 
> Same here
> 
>> +			clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
>> +			<&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
>> +			clock-names = "pclk", "mclk";
>> +			resets = <&clkc_audio AUD_RESET_SPDIFOUT>;
>> +			status = "disabled";
>> +		};
>> +
>>  		tdmout_a: audio-controller at 500 {
>>  			compatible = "amlogic,sm1-tdmout";
>>  			reg = <0x0 0x500 0x0 0x40>;
> 

All these fixed while applying, no need to send a new version.

Neil


From jacopo at jmondi.org  Wed Jan 12 01:00:03 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:00:03 +0100
Subject: [PATCH v3 18/23] media: atmel: atmel-isc-base: add wb debug
 messages
In-Reply-To: <20211213134940.324266-19-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-19-eugen.hristev@microchip.com>
Message-ID: <20220112090003.nktnhm3oho4mdx6g@uno.localdomain>

Hello Eugen,

On Mon, Dec 13, 2021 at 03:49:35PM +0200, Eugen Hristev wrote:
> Add debug messages that make it easier to debug white balance algorithm.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

The dev_dbg() infrastructure is preferred, as far as I know v4l2_dbg()
is legacy and should be removed.

However the driver uses v4l2_dbg() already, so
Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j

> ---
>  drivers/media/platform/atmel/atmel-isc-base.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index 53cac1aac0fd..f1f1019f9d82 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -1329,10 +1329,15 @@ static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max)
>
>  	if (!*min)
>  		*min = 1;
> +
> +	v4l2_dbg(1, debug, &isc->v4l2_dev,
> +		 "isc wb: hist_id %u, hist_count %u",
> +		 ctrls->hist_id, *hist_count);
>  }
>
>  static void isc_wb_update(struct isc_ctrls *ctrls)
>  {
> +	struct isc_device *isc = container_of(ctrls, struct isc_device, ctrls);
>  	u32 *hist_count = &ctrls->hist_count[0];
>  	u32 c, offset[4];
>  	u64 avg = 0;
> @@ -1349,6 +1354,9 @@ static void isc_wb_update(struct isc_ctrls *ctrls)
>  		(u64)hist_count[ISC_HIS_CFG_MODE_GB];
>  	avg >>= 1;
>
> +	v4l2_dbg(1, debug, &isc->v4l2_dev,
> +		 "isc wb: green components average %llu\n", avg);
> +
>  	/* Green histogram is null, nothing to do */
>  	if (!avg)
>  		return;
> @@ -1401,9 +1409,15 @@ static void isc_wb_update(struct isc_ctrls *ctrls)
>  		else
>  			gw_gain[c] = 1 << 9;
>
> +		v4l2_dbg(1, debug, &isc->v4l2_dev,
> +			 "isc wb: component %d, s_gain %u, gw_gain %u\n",
> +			 c, s_gain[c], gw_gain[c]);
>  		/* multiply both gains and adjust for decimals */
>  		ctrls->gain[c] = s_gain[c] * gw_gain[c];
>  		ctrls->gain[c] >>= 9;
> +		v4l2_dbg(1, debug, &isc->v4l2_dev,
> +			 "isc wb: component %d, final gain %u\n",
> +			 c, ctrls->gain[c]);
>  	}
>  }
>
> @@ -1423,6 +1437,10 @@ static void isc_awb_work(struct work_struct *w)
>  		return;
>
>  	isc_hist_count(isc, &min, &max);
> +
> +	v4l2_dbg(1, debug, &isc->v4l2_dev,
> +		 "isc wb mode %d: hist min %u , max %u\n", hist_id, min, max);
> +
>  	ctrls->hist_minmax[hist_id][HIST_MIN_INDEX] = min;
>  	ctrls->hist_minmax[hist_id][HIST_MAX_INDEX] = max;
>
> --
> 2.25.1
>


From boger at wirenboard.com  Wed Jan 12 00:59:31 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Wed, 12 Jan 2022 11:59:31 +0300
Subject: [PATCH v2 1/1] phy: sun4i-usb: fix phy write on H3 and newer
In-Reply-To: <20220112084223.j5nm4ennfv7f6ekt@houat>
References: <20220111165153.63632-1-boger@wirenboard.com>
 <20220111165153.63632-2-boger@wirenboard.com>
 <20220112084223.j5nm4ennfv7f6ekt@houat>
Message-ID: <1e13f894-6900-15a8-66ea-f5e4d65bf822@wirenboard.com>

Hi Maxime!
12.01.2022 11:42, Maxime Ripard ?????:
> Hi,
>
> On Tue, Jan 11, 2022 at 07:51:53PM +0300, Evgeny Boger wrote:
>> We noticed that USB hosts won't reliably enumerate USB HS (480Mb/s) devices
>> in our custom A40i-based design. What we observe is that after several
>> attempts USB device would fail to enumerate on EHCI port (HS) and will be
>> enumerated instead on OHCI (FS, 12Mb/s) only:
>>
>> [    6.368009] usb 1-1: new high-speed USB device number 5 using ehci-platform
>> [    6.818008] usb 1-1: device not accepting address 5, error -71
>> [    6.823868] usb usb1-port1: unable to enumerate USB device
>> [    7.308013] usb 3-1: new full-speed USB device number 2 using ohci-platform
>> [    7.575045] usb 3-1: not running at top speed; connect to a high speed hub
>>
>> On some boards one of the ports would work in high-speed mode, but
>> on most of the boards all three USB ports would only work in FS mode.
>>
>> At the same time, USB work flawlessly in high-speed mode in vendor kernel.
>>
>> Looking for the differences in USB code, we found the issue with USB PHY
>> register initialization. Basically, USB PHY driver sets a couple of
>> internal undocumented PHY registers to the predefined constants. These PHY
>> registers are accessed in a very (and I mean VERY) weird way by shifting
>> register addresses and values bit-by-bit. This access method was slightly
>> changed starting from H3 SoC, according to the BSP source for different
>> SoCs.
>>
>> As a result, mainline PHY driver won't set these PHY registers properly
>> resulting in unreliable enumeration in high-speed mode.
>>
>> We don't know whether this issue will result in broken HS mode on all
>> affected SoCs or instead the A40i is an unfortunate exception. What we
>> indeed verified, is that BSPs for all affected SoCs write these registers
>> properly while mainline kernel don't. We also were able to reproduce the
>> USB issue on a couple of A40i boards from other vendors, so we are pretty
>> sure these registers have to always be properly set, regardlress of
>> a hardware layout.
>>
>> The proposed patch is tested on A40i-based Wiren Board 7 building
>> automation controller. More details are below.
>>
>> On older SoCs (prior to H3) PHY register are accessed by manipulating
>> the common register for all PHYs. PHY index is specified by pulsing
>> usbc bit.
>>
>> Newer SoCs leave the access procedure mostly unchanged, the
>> difference being that the latch registers are separate for each PHY.
>>
>> Additionally, accessing USB PHY registers is only possible if phy0 is
>> routed to musb IP instead of HCI.
>>
>> Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
>> R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.
>>
>> On A83t, H6, H616, T507 and probably on more recent hardware,
>> these PHY registers are not used in vendor BSP.
>> So don't set v2 flag for these even newer SoCs as a precaution.
>>
>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> This should probably be sent to stable, and have a Fixes tag?

well, phy register writes never worked on H3 SoC and newer, so there is 
no specific commit which broke it. So nothing to put to Fixes: tag.

I'm not sure it qualifies for stable too. Citing guidelines:

 >It must be obviously correct and tested

I was only able to test it on handful of A40i boards and on one A20 board

 >It must fix a real bug that bothers people

this bug for certain bothers *us*, but our users won't benefit from 
porting this fix to stable.
I didn't find reports on this bug from other people.
I think unfortunately not many people are using mainline kernel on these 
SoCs.


>
>> ---
>>   drivers/phy/allwinner/phy-sun4i-usb.c | 44 ++++++++++++++++++++++++---
>>   1 file changed, 39 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c
>> index 788dd5cdbb7d..cf10e385f199 100644
>> --- a/drivers/phy/allwinner/phy-sun4i-usb.c
>> +++ b/drivers/phy/allwinner/phy-sun4i-usb.c
>> @@ -119,6 +119,7 @@ struct sun4i_usb_phy_cfg {
>>   	bool dedicated_clocks;
>>   	bool enable_pmu_unk1;
>>   	bool phy0_dual_route;
>> +	bool phy_reg_access_v2;
>>   	int missing_phys;
>>   };
>>   
>> @@ -192,13 +193,38 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
>>   				int len)
>>   {
>>   	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
>> -	u32 temp, usbc_bit = BIT(phy->index * 2);
>> +	u32 otgctl_val, temp, usbc_bit;
>>   	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
>> +	void __iomem *phyctl_latch;
>>   	unsigned long flags;
>>   	int i;
>>   
>>   	spin_lock_irqsave(&phy_data->reg_lock, flags);
>>   
>> +	/* On older SoCs (prior to H3) PHY register are accessed by manipulating the
>> +	 * common register for all PHYs. PHY index is specified by pulsing usbc bit.
>> +	 * Newer SoCs leave the access procedure mostly unchanged, the difference
>> +	 * being that the latch registers are separate for each PHY.
>> +	 */
> Multi-line comments need to start with an empty line
>
>> +	if (phy_data->cfg->phy_reg_access_v2) {
>> +		if (phy->index == 0)
>> +			phyctl_latch = phy_data->base + phy_data->cfg->phyctl_offset;
>> +		else
>> +			phyctl_latch = phy->pmu + phy_data->cfg->phyctl_offset;
>> +		usbc_bit = 1;
>> +
>> +		/* Accessing USB PHY registers is only possible if phy0 is routed to musb.
>> +		 * As it's not clear whether is this related to actual PHY
>> +		 * routing or rather the hardware is just reusing the same bit,
>> +		 * don't check phy0_dual_route here.
>> +		 */
> Ditto
>
> Thanks!
> Maxime


-- 
? ?????????,
     ??????? ????? / Evgeny Boger
     CTO, Wiren Board Team
     https://wirenboard.com/ru
     +7 495 150 66 19 (# 33)



From jacopo at jmondi.org  Wed Jan 12 01:04:05 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:04:05 +0100
Subject: [PATCH v3 19/23] media: atmel: atmel-isc-base: clamp wb gain
 coefficients
In-Reply-To: <20211213134940.324266-20-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-20-eugen.hristev@microchip.com>
Message-ID: <20220112090405.tjgz47dhdbyjrwxr@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:36PM +0200, Eugen Hristev wrote:
> White balance computed gains can overflow above the 13 bits hardware
> coefficient that can be used, in some specific scenarios like a subexposure
> from the sensor when the image is mostly black.
> In this case the computed gain has to be clamped to the maximum value
> allowed by the hardware.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
>  drivers/media/platform/atmel/atmel-isc-base.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index f1f1019f9d82..31c8e3029eee 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -1415,6 +1415,10 @@ static void isc_wb_update(struct isc_ctrls *ctrls)
>  		/* multiply both gains and adjust for decimals */
>  		ctrls->gain[c] = s_gain[c] * gw_gain[c];
>  		ctrls->gain[c] >>= 9;
> +
> +		/* make sure we are not out of range */
> +		ctrls->gain[c] = clamp_val(ctrls->gain[c], 0, GENMASK(12, 0));

#include <linux/minmax.h>

What is the type of gain[c} ? If it's unsigned clamping with [0 is not
required. I would in that case gain[c] = min(gain[c], ...)

It's fine anyway
Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
   j


> +
>  		v4l2_dbg(1, debug, &isc->v4l2_dev,
>  			 "isc wb: component %d, final gain %u\n",
>  			 c, ctrls->gain[c]);
> --
> 2.25.1
>


From jacopo at jmondi.org  Wed Jan 12 01:04:33 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:04:33 +0100
Subject: [PATCH v3 20/23] media: atmel: atmel-sama7g5-isc: fix UYVY input
 format mbus_code typo
In-Reply-To: <20211213134940.324266-21-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-21-eugen.hristev@microchip.com>
Message-ID: <20220112090433.uy6aflzudfqy65y3@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:37PM +0200, Eugen Hristev wrote:
> Fix the mbus code for UYVY input format type to the right color rotation.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j

> ---
>  drivers/media/platform/atmel/atmel-sama7g5-isc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> index d2ac80b1ccc3..38721bd902e2 100644
> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> @@ -188,7 +188,7 @@ static struct isc_format sama7g5_formats_list[] = {
>  	},
>  	{
>  		.fourcc		= V4L2_PIX_FMT_UYVY,
> -		.mbus_code	= MEDIA_BUS_FMT_YUYV8_2X8,
> +		.mbus_code	= MEDIA_BUS_FMT_UYVY8_2X8,
>  		.pfe_cfg0_bps	= ISC_PFE_CFG0_BPS_EIGHT,
>  	},
>  	{
> --
> 2.25.1
>


From maxime at cerno.tech  Wed Jan 12 01:04:01 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 12 Jan 2022 10:04:01 +0100
Subject: [PATCH v4 2/3] dt-bindings: net: support for Allwinner R40 EMAC
 controller
In-Reply-To: <20220111160600.58384-3-boger@wirenboard.com>
References: <20220111160600.58384-1-boger@wirenboard.com>
 <20220111160600.58384-3-boger@wirenboard.com>
Message-ID: <20220112090401.vbwhqudqvdce7jm4@houat>

Hi,

On Tue, Jan 11, 2022 at 07:05:59PM +0300, Evgeny Boger wrote:
> R40 and A10/A20 share the same EMAC IP.
> However, on R40 the EMAC reset needs to be deasserted first,
> so resets property is required.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> ---
>  .../net/allwinner,sun4i-a10-emac.yaml         | 20 ++++++++++++++++++-
>  1 file changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
> index 8d8560a67abf..8b38b4e981fe 100644
> --- a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
> +++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
> @@ -15,7 +15,9 @@ maintainers:
>  
>  properties:
>    compatible:
> -    const: allwinner,sun4i-a10-emac
> +    enum:
> +      - allwinner,sun4i-a10-emac
> +      - allwinner,sun8i-r40-emac
>  
>    reg:
>      maxItems: 1
> @@ -30,6 +32,19 @@ properties:
>      description: Phandle to the device SRAM
>      $ref: /schemas/types.yaml#/definitions/phandle-array
>  
> +  resets:
> +    maxItems: 1
> +
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        const: allwinner,sun8i-r40-emac
> +
> +then:
> +  required:
> +    - resets
> +
>  required:
>    - compatible
>    - reg
> @@ -42,11 +57,14 @@ unevaluatedProperties: false
>  
>  examples:
>    - |
> +    #define RST_BUS_EMAC		14
> +
>      emac: ethernet at 1c0b000 {
>          compatible = "allwinner,sun4i-a10-emac";
>          reg = <0x01c0b000 0x1000>;
>          interrupts = <55>;
>          clocks = <&ahb_gates 17>;
> +        resets = <&ccu RST_BUS_EMAC>;
>          phy-handle = <&phy0>;
>          allwinner,sram = <&emac_sram 1>;
>      };

The example doesn't make much sense now, since we can't have an A10
controller with the reset line.

Either leave it like it was, or create a new example

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/028a5391/attachment.sig>

From jacopo at jmondi.org  Wed Jan 12 01:05:39 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:05:39 +0100
Subject: [PATCH v3 21/23] media: atmel: atmel-isc: add raw Bayer 8bit
 10bit output formats
In-Reply-To: <20211213134940.324266-22-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-22-eugen.hristev@microchip.com>
Message-ID: <20220112090539.ksn4civgcceopsc3@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:38PM +0200, Eugen Hristev wrote:
> The ISC can dump the 8 bit and 10 bit raw bayer formats directly to
> the memory.
> Thus, add them to the supported output format list.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j

> ---
>  .../media/platform/atmel/atmel-sama5d2-isc.c  | 24 +++++++++++++++++++
>  .../media/platform/atmel/atmel-sama7g5-isc.c  | 24 +++++++++++++++++++
>  2 files changed, 48 insertions(+)
>
> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> index a8d4ba60d3ac..025c3e8a7e95 100644
> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> @@ -88,6 +88,30 @@ static const struct isc_format sama5d2_controller_formats[] = {
>  	{
>  		.fourcc		= V4L2_PIX_FMT_Y10,
>  	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SBGGR8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGBRG8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGRBG8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SRGGB8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SBGGR10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGBRG10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGRBG10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SRGGB10,
> +	},
>  };
>
>  /* This is a list of formats that the ISC can receive as *input* */
> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> index 38721bd902e2..9dc75eed0098 100644
> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> @@ -100,6 +100,30 @@ static const struct isc_format sama7g5_controller_formats[] = {
>  	{
>  		.fourcc		= V4L2_PIX_FMT_Y16,
>  	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SBGGR8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGBRG8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGRBG8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SRGGB8,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SBGGR10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGBRG10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SGRBG10,
> +	},
> +	{
> +		.fourcc		= V4L2_PIX_FMT_SRGGB10,
> +	},
>  };
>
>  /* This is a list of formats that the ISC can receive as *input* */
> --
> 2.25.1
>


From jacopo at jmondi.org  Wed Jan 12 01:06:15 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:06:15 +0100
Subject: [PATCH v3 22/23] media: atmel: atmel-isc: compact the controller
 formats list
In-Reply-To: <20211213134940.324266-23-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-23-eugen.hristev@microchip.com>
Message-ID: <20220112090615.6mbzd7fwn4a7yjtw@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:39PM +0200, Eugen Hristev wrote:
> Compact the list array to be more readable.
> No other changes, only cosmetic.
>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>

Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>

Thanks
  j

> ---
>  .../media/platform/atmel/atmel-sama5d2-isc.c  | 51 ++++++----------
>  .../media/platform/atmel/atmel-sama7g5-isc.c  | 60 +++++++------------
>  2 files changed, 37 insertions(+), 74 deletions(-)
>
> diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> index 025c3e8a7e95..d96ee3373889 100644
> --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
> @@ -60,56 +60,39 @@
>  static const struct isc_format sama5d2_controller_formats[] = {
>  	{
>  		.fourcc		= V4L2_PIX_FMT_ARGB444,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_ARGB555,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_RGB565,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_ABGR32,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_XBGR32,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUV420,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUYV,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUV422P,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_GREY,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_Y10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SBGGR8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGBRG8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGRBG8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SRGGB8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SBGGR10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGBRG10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGRBG10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SRGGB10,
>  	},
>  };
> diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> index 9dc75eed0098..e07ae188c15f 100644
> --- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> +++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
> @@ -63,65 +63,45 @@
>  static const struct isc_format sama7g5_controller_formats[] = {
>  	{
>  		.fourcc		= V4L2_PIX_FMT_ARGB444,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_ARGB555,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_RGB565,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_ABGR32,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_XBGR32,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUV420,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_UYVY,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_VYUY,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUYV,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_YUV422P,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_GREY,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_Y10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_Y16,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SBGGR8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGBRG8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGRBG8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SRGGB8,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SBGGR10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGBRG10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SGRBG10,
> -	},
> -	{
> +	}, {
>  		.fourcc		= V4L2_PIX_FMT_SRGGB10,
>  	},
>  };
> --
> 2.25.1
>


From clabbe.montjoie at gmail.com  Wed Jan 12 01:09:35 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Wed, 12 Jan 2022 10:09:35 +0100
Subject: [PATCH v4 1/3] net: allwinner: reset control support
In-Reply-To: <20220111160600.58384-2-boger@wirenboard.com>
References: <20220111160600.58384-1-boger@wirenboard.com>
 <20220111160600.58384-2-boger@wirenboard.com>
Message-ID: <Yd6az3ZlQ4UsSpSM@Red>

Le Tue, Jan 11, 2022 at 07:05:58PM +0300, Evgeny Boger a ?crit :
> R40 (aka V40/A40i/T3) and A10/A20 share the same EMAC IP.
> However, on R40 the EMAC reset needs to be deasserted.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> ---
>  drivers/net/ethernet/allwinner/sun4i-emac.c | 64 +++++++++++++++++++--
>  1 file changed, 59 insertions(+), 5 deletions(-)
> 

Hello

You need to rebase your patch, it does not apply cleanly anymore due to the dmaengine addition to sun4i-emac.

Regards


From plaes at plaes.org  Wed Jan 12 01:09:24 2022
From: plaes at plaes.org (Priit Laes)
Date: Wed, 12 Jan 2022 09:09:24 +0000
Subject: [linux-sunxi] [PATCH RESEND v3] arm64: dts: allwinner: a64:
 olinuxino: Enable audio
In-Reply-To: <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
 <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>
Message-ID: <Yd6axIURzudUq5Ah@plaes.org>

On Tue, Jan 11, 2022 at 09:08:23PM +0100, 'Philip Rinn' via linux-sunxi wrote:
> Enable the audio hardware on the Olimex A64-OLinuXino board family.
> Tested on the A64-OLinuXino-2Ge8G-IND variant.

I have similar patch in one of my "long forgotten branches", but I'm not 100%
sure whether the cpvdd-supply is required for codec_analog. IIRC, sound worked
for me without the issues on A64-Olinuxino board (Rev D).

'cpvdd-supply = <&reg_eldo1>' for codec_analog

And we also need to enable these configuration options in the defconfig:

+CONFIG_SND_SUN8I_CODEC=m
+CONFIG_SND_SUN50I_CODEC_ANALOG=m


> 
> Signed-off-by: Philip Rinn <rinni at inventati.org>
> 
> ---
> 
> 
> Changes in v2: added missing &sound {...} part
> Changes in v3: removed HDMI audio part as requested by Jernej ?krabec
> 
>  arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts    | 30 +++++++++++++++++++
> 
>  1 file changed, 30 insertions(+)
> 
> 
> 
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
> 
> index ec7e2c0e82c1..6f2674bb1b7f 100644
> 
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
> 
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
> 
> @@ -58,6 +58,15 @@ wifi_pwrseq: wifi_pwrseq {
> 
>  	};
> 
>  };
> 
> 
> +&codec {
> 
> +	status = "okay";
> 
> +};
> 
> +
> 
> +&codec_analog {
> 
> +	cpvdd-supply = <&reg_eldo1>;
> 
> +	status = "okay";
> 
> +};
> 
> +
> 
>  &cpu0 {
> 
>  	cpu-supply = <&reg_dcdc2>;
> 
>  };
> 
> @@ -74,6 +83,10 @@ &cpu3 {
> 
>  	cpu-supply = <&reg_dcdc2>;
> 
>  };
> 
> 
> +&dai {
> 
> +	status = "okay";
> 
> +};
> 
> +
> 
>  &de {
> 
>  	status = "okay";
> 
>  };
> 
> @@ -328,6 +341,23 @@ &simplefb_hdmi {
> 
>  	vcc-hdmi-supply = <&reg_dldo1>;
> 
>  };
> 
> 
> +&sound {
> 
> +	simple-audio-card,aux-devs = <&codec_analog>;
> 
> +	simple-audio-card,widgets = "Microphone", "Microphone Jack Left",
> 
> +		    "Microphone", "Microphone Jack Right",
> 
> +		    "Headphone", "Headphone Jack";
> 
> +	simple-audio-card,routing = "Left DAC", "DACL",
> 
> +		    "Right DAC", "DACR",
> 
> +		    "Headphone Jack", "HP",
> 
> +		    "ADCL", "Left ADC",
> 
> +		    "ADCR", "Right ADC",
> 
> +		    "Microphone Jack Left", "MBIAS",
> 
> +		    "MIC1", "Microphone Jack Left",
> 
> +		    "Microphone Jack Left", "HBIAS",
> 
> +		    "MIC2", "Microphone Jack Right";
> 
> +	status = "okay";
> 
> +};
> 
> +
> 
>  &uart0 {
> 
>  	pinctrl-names = "default";
> 
>  	pinctrl-0 = <&uart0_pb_pins>;
> 
> -- 
> 
> 2.34.1
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe at googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/87654fd3-6007-6067-1851-7bc4b6de2f05%40inventati.org.





From jacopo at jmondi.org  Wed Jan 12 01:21:37 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Wed, 12 Jan 2022 10:21:37 +0100
Subject: [PATCH v3 23/23] media: atmel: atmel-isc: change format
 propagation to subdev into only verification
In-Reply-To: <20211213134940.324266-24-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-24-eugen.hristev@microchip.com>
Message-ID: <20220112092137.rzgmo436hjl2bdfv@uno.localdomain>

Hi Eugen

On Mon, Dec 13, 2021 at 03:49:40PM +0200, Eugen Hristev wrote:
> As a top MC video driver, the atmel-isc should not propagate the format to the
> subdevice.
> It should rather check at streamon() time if the subdev is properly configured
> with a compatible format.
> Removed the whole format finding logic, and reworked the format verification
> at streamon time, such that the ISC will return an error if the subdevice
> is not properly configured.
> With this being done, the module parameter 'sensor_prefered' makes no sense
> anymore. The ISC should not decide which format the sensor is using. The
> ISC should only cope with the situation and inform userspace if the streaming
> is possible in the current configuration.

Sounds great!

>
> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> ---
> Changes in v3:
> - clamp to maximum resolution once the frame size from the subdev is found
>
>  drivers/media/platform/atmel/atmel-isc-base.c | 271 ++++++++----------
>  drivers/media/platform/atmel/atmel-isc.h      |   1 +
>  2 files changed, 126 insertions(+), 146 deletions(-)
>
> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> index 31c8e3029eee..00c8c9588a78 100644
> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> @@ -36,11 +36,6 @@ static unsigned int debug;
>  module_param(debug, int, 0644);
>  MODULE_PARM_DESC(debug, "debug level (0-2)");
>
> -static unsigned int sensor_preferred = 1;
> -module_param(sensor_preferred, uint, 0644);
> -MODULE_PARM_DESC(sensor_preferred,
> -		 "Sensor is preferred to output the specified format (1-on 0-off), default 1");
> -
>  #define ISC_IS_FORMAT_RAW(mbus_code) \
>  	(((mbus_code) & 0xf000) == 0x3000)
>
> @@ -532,7 +527,7 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
>  	 * convert it to any of the formats that we usually can with a
>  	 * RAW sensor. Thus, do not advertise them.
>  	 */
> -	if (!isc->config.sd_format ||
> +	if (isc->config.sd_format &&

Is this change intentional ?

>  	    !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>  		return -EINVAL;
>
> @@ -621,20 +616,30 @@ static int isc_try_validate_formats(struct isc_device *isc)
>  		break;
>  	default:
>  	/* any other different formats are not supported */
> +		v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n");
>  		ret = -EINVAL;
>  	}
>  	v4l2_dbg(1, debug, &isc->v4l2_dev,
>  		 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
>  		 rgb, yuv, grey, bayer);

Would it make sense to move this before the switch so that the
error messages, if any, appear later ?

>
> -	/* we cannot output RAW if we do not receive RAW */
> -	if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
> +	if ((bayer) &&
> +	    !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
> +		v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n");
>  		return -EINVAL;
> +	}
>
> -	/* we cannot output GREY if we do not receive RAW/GREY */
>  	if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
> -	    !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
> +	    !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
> +		v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
>  		return -EINVAL;
> +	}
> +
> +	if ((rgb || bayer || yuv) &&
> +	    ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
> +		v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n");
> +		return -EINVAL;
> +	}
>
>  	return ret;
>  }
> @@ -862,7 +867,7 @@ static void isc_try_fse(struct isc_device *isc,
>  	 * If we do not know yet which format the subdev is using, we cannot
>  	 * do anything.
>  	 */
> -	if (!isc->try_config.sd_format)
> +	if (!isc->config.sd_format)
>  		return;
>
>  	fse.code = isc->try_config.sd_format->mbus_code;
> @@ -883,180 +888,141 @@ static void isc_try_fse(struct isc_device *isc,
>  	}
>  }
>
> -static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
> -			u32 *code)
> +static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
>  {
> -	int i;
> -	struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
>  	struct v4l2_pix_format *pixfmt = &f->fmt.pix;
> -	struct v4l2_subdev_pad_config pad_cfg = {};
> -	struct v4l2_subdev_state pad_state = {
> -		.pads = &pad_cfg
> -		};
> -	struct v4l2_subdev_format format = {
> -		.which = V4L2_SUBDEV_FORMAT_TRY,
> -	};
> -	u32 mbus_code;
> -	int ret;
> -	bool rlp_dma_direct_dump = false;
> +	unsigned int i;
>
>  	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>  		return -EINVAL;
>
> -	/* Step 1: find a RAW format that is supported */
> -	for (i = 0; i < isc->num_user_formats; i++) {
> -		if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
> -			sd_fmt = isc->user_formats[i];
> +	isc->try_config.fourcc = isc->user_formats[0]->fourcc;
> +
> +	/* find if the format requested is supported */
> +	for (i = 0; i < isc->controller_formats_size; i++)
> +		if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
> +			isc->try_config.fourcc = pixfmt->pixelformat;
>  			break;
>  		}
> -	}
> -	/* Step 2: We can continue with this RAW format, or we can look
> -	 * for better: maybe sensor supports directly what we need.
> -	 */
> -	direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
> -
> -	/* Step 3: We have both. We decide given the module parameter which
> -	 * one to use.
> -	 */
> -	if (direct_fmt && sd_fmt && sensor_preferred)
> -		sd_fmt = direct_fmt;
> -
> -	/* Step 4: we do not have RAW but we have a direct format. Use it. */
> -	if (direct_fmt && !sd_fmt)
> -		sd_fmt = direct_fmt;
> -
> -	/* Step 5: if we are using a direct format, we need to package
> -	 * everything as 8 bit data and just dump it
> -	 */
> -	if (sd_fmt == direct_fmt)
> -		rlp_dma_direct_dump = true;
> -
> -	/* Step 6: We have no format. This can happen if the userspace
> -	 * requests some weird/invalid format.
> -	 * In this case, default to whatever we have
> -	 */
> -	if (!sd_fmt && !direct_fmt) {
> -		sd_fmt = isc->user_formats[isc->num_user_formats - 1];
> -		v4l2_dbg(1, debug, &isc->v4l2_dev,
> -			 "Sensor not supporting %.4s, using %.4s\n",
> -			 (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
> -	}
> -
> -	if (!sd_fmt) {
> -		ret = -EINVAL;
> -		goto isc_try_fmt_err;
> -	}
> -
> -	/* Step 7: Print out what we decided for debugging */
> -	v4l2_dbg(1, debug, &isc->v4l2_dev,
> -		 "Preferring to have sensor using format %.4s\n",
> -		 (char *)&sd_fmt->fourcc);
> -
> -	/* Step 8: at this moment we decided which format the subdev will use */
> -	isc->try_config.sd_format = sd_fmt;
> -
> -	/* Limit to Atmel ISC hardware capabilities */
> -	if (pixfmt->width > isc->max_width)
> -		pixfmt->width = isc->max_width;
> -	if (pixfmt->height > isc->max_height)
> -		pixfmt->height = isc->max_height;
> -
> -	/*
> -	 * The mbus format is the one the subdev outputs.
> -	 * The pixels will be transferred in this format Sensor -> ISC
> -	 */
> -	mbus_code = sd_fmt->mbus_code;
> -
> -	/*
> -	 * Validate formats. If the required format is not OK, default to raw.
> -	 */
> -
> -	isc->try_config.fourcc = pixfmt->pixelformat;
> -
> -	if (isc_try_validate_formats(isc)) {
> -		pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
> -		/* Re-try to validate the new format */
> -		ret = isc_try_validate_formats(isc);
> -		if (ret)
> -			goto isc_try_fmt_err;
> -	}
> -
> -	ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
> -	if (ret)
> -		goto isc_try_fmt_err;
> -
> -	ret = isc_try_configure_pipeline(isc);
> -	if (ret)
> -		goto isc_try_fmt_err;
>
> -	/* Obtain frame sizes if possible to have crop requirements ready */
> -	isc_try_fse(isc, &pad_state);
> -
> -	v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
> -	ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
> -			       &pad_state, &format);
> -	if (ret < 0)
> -		goto isc_try_fmt_subdev_err;
> +	/* If we did not find the requested format, we will fallback here */
> +	pixfmt->pixelformat = isc->try_config.fourcc;
> +	pixfmt->colorspace = V4L2_COLORSPACE_SRGB;
> +	pixfmt->field = V4L2_FIELD_NONE;
>
> -	v4l2_fill_pix_format(pixfmt, &format.format);
> +	isc_try_configure_rlp_dma(isc, false);
>
>  	/* Limit to Atmel ISC hardware capabilities */
> -	if (pixfmt->width > isc->max_width)
> -		pixfmt->width = isc->max_width;
> -	if (pixfmt->height > isc->max_height)
> -		pixfmt->height = isc->max_height;
> +	v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
> +			      &pixfmt->height, 16, isc->max_height, 0, 0);
>
>  	pixfmt->field = V4L2_FIELD_NONE;
>  	pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
>  	pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
>  			     pixfmt->height;
>
> -	if (code)
> -		*code = mbus_code;
> +	isc->try_fmt = *f;
>
>  	return 0;
> +}
>
> -isc_try_fmt_err:
> -	v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
> -isc_try_fmt_subdev_err:
> -	memset(&isc->try_config, 0, sizeof(isc->try_config));
> +static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
> +{
> +	isc_try_fmt(isc, f);
>
> -	return ret;
> +	/* make the try configuration active */
> +	isc->config = isc->try_config;
> +	isc->fmt = isc->try_fmt;
> +
> +	v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n",
> +		 (char *)&f->fmt.pix.pixelformat,
> +		 f->fmt.pix.width, f->fmt.pix.height);
> +
> +	return 0;
>  }
>
> -static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
> +static int isc_validate(struct isc_device *isc)
>  {
> +	int ret;
> +	int i;
> +	struct isc_format *sd_fmt = NULL;
> +	struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
>  	struct v4l2_subdev_format format = {
>  		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
> +		.pad = isc->remote_pad,
> +	};
> +	struct v4l2_subdev_pad_config pad_cfg = {};
> +	struct v4l2_subdev_state pad_state = {
> +		.pads = &pad_cfg,
>  	};
> -	u32 mbus_code = 0;
> -	int ret;
>
> -	ret = isc_try_fmt(isc, f, &mbus_code);
> +	/* Get current format from subdev */
> +	ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
> +			       &format);

Ah! Haven't you just said we don't care anymore about the subdev
format ? :)

Kidding, I might got a bit lost in the logic, but if I look at your
above isc_try_validate_formats() it seems like an ideal candidate for
.link_validate() media_entity operation.

Just to make sure we're on the same page, here's how it should ideally
look like:
- set format does care about subdev format. It only checks that the
  format required from the user is one of the ISC supported one. Ie.
  no v4l2_subdev_call()

- as s_stream time your top driver calls media_pipeline_start()

- media_pipeline_start() walks all the entities in the pipeline and
  validates the format of connected pads. To validate formats the
  __media_pipeline_start() functions calls link_validate() on each
  entity. You should in your driver set

        static const struct media_entity_operations your_media_entity_ops = {
                .link_validate = v4l2_subdev_link_validate,
        };

  if you want to use the default link validation procedure, or set the
  callback to your custom validation function, which can behave more
  or less like isc_try_validate_formats()

Does it match your understanding too ?

Thanks
   j



>  	if (ret)
>  		return ret;
>
> -	v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
> -	ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
> -			       set_fmt, NULL, &format);
> -	if (ret < 0)
> -		return ret;
> +	/* Identify the subdev's format configuration */
> +	for (i = 0; i < isc->num_user_formats; i++)
> +		if (isc->user_formats[i]->mbus_code == format.format.code) {
> +			sd_fmt = isc->user_formats[i];
> +			break;
> +		}
> +
> +	/* Check if the format is not supported */
> +	if (!sd_fmt) {
> +		v4l2_err(&isc->v4l2_dev,
> +			 "Current subdevice is streaming a media bus code that is not supported 0x%x\n",
> +			 format.format.code);
> +		return -EPIPE;
> +	}
> +
> +	/* At this moment we know which format the subdev will use */
> +	isc->try_config.sd_format = sd_fmt;
> +
> +	/* If the sensor is not RAW, we can only do a direct dump */
> +	if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
> +		isc_try_configure_rlp_dma(isc, true);
>
>  	/* Limit to Atmel ISC hardware capabilities */
> -	if (f->fmt.pix.width > isc->max_width)
> -		f->fmt.pix.width = isc->max_width;
> -	if (f->fmt.pix.height > isc->max_height)
> -		f->fmt.pix.height = isc->max_height;
> +	v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
> +			      &format.format.height, 16, isc->max_height, 0, 0);
>
> -	isc->fmt = *f;
> +	/* Check if the frame size is the same. Otherwise we may overflow */
> +	if (pixfmt->height != format.format.height ||
> +	    pixfmt->width != format.format.width) {
> +		v4l2_err(&isc->v4l2_dev,
> +			 "ISC not configured with the proper frame size: %dx%d\n",
> +			 format.format.width, format.format.height);
> +		return -EPIPE;
> +	}
>
> +	v4l2_dbg(1, debug, &isc->v4l2_dev,
> +		 "Identified subdev using format %.4s with %dx%d %d bpp\n",
> +		 (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height,
> +		 isc->try_config.bpp);
> +
> +	/* Reset and restart AWB if the subdevice changed the format */
>  	if (isc->try_config.sd_format && isc->config.sd_format &&
>  	    isc->try_config.sd_format != isc->config.sd_format) {
>  		isc->ctrls.hist_stat = HIST_INIT;
>  		isc_reset_awb_ctrls(isc);
>  		isc_update_v4l2_ctrls(isc);
>  	}
> -	/* make the try configuration active */
> +
> +	/* Validate formats */
> +	ret = isc_try_validate_formats(isc);
> +	if (ret)
> +		return ret;
> +
> +	/* Obtain frame sizes if possible to have crop requirements ready */
> +	isc_try_fse(isc, &pad_state);
> +
> +	/* Configure ISC pipeline for the config */
> +	ret = isc_try_configure_pipeline(isc);
> +	if (ret)
> +		return ret;
> +
>  	isc->config = isc->try_config;
>
>  	v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
> @@ -1064,6 +1030,19 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>  	return 0;
>  }
>
> +static int isc_streamon(struct file *file, void *priv, enum v4l2_buf_type bt)
> +{
> +	struct isc_device *isc = video_drvdata(file);
> +	int ret;
> +
> +	ret = isc_validate(isc);
> +
> +	if (ret)
> +		return ret;
> +
> +	return vb2_ioctl_streamon(file, priv, bt);
> +}
> +
>  static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>  			      struct v4l2_format *f)
>  {
> @@ -1080,7 +1059,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
>  {
>  	struct isc_device *isc = video_drvdata(file);
>
> -	return isc_try_fmt(isc, f, NULL);
> +	return isc_try_fmt(isc, f);
>  }
>
>  static int isc_enum_input(struct file *file, void *priv,
> @@ -1176,7 +1155,7 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = {
>  	.vidioc_dqbuf			= vb2_ioctl_dqbuf,
>  	.vidioc_create_bufs		= vb2_ioctl_create_bufs,
>  	.vidioc_prepare_buf		= vb2_ioctl_prepare_buf,
> -	.vidioc_streamon		= vb2_ioctl_streamon,
> +	.vidioc_streamon		= isc_streamon,
>  	.vidioc_streamoff		= vb2_ioctl_streamoff,
>
>  	.vidioc_g_parm			= isc_g_parm,
> @@ -1879,7 +1858,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
>  	};
>  	int ret;
>
> -	ret = isc_try_fmt(isc, &f, NULL);
> +	ret = isc_try_fmt(isc, &f);
>  	if (ret)
>  		return ret;
>
> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> index c2cb805faff3..7081698adddd 100644
> --- a/drivers/media/platform/atmel/atmel-isc.h
> +++ b/drivers/media/platform/atmel/atmel-isc.h
> @@ -297,6 +297,7 @@ struct isc_device {
>  	struct completion	comp;
>
>  	struct v4l2_format	fmt;
> +	struct v4l2_format	try_fmt;
>  	struct isc_format	**user_formats;
>  	unsigned int		num_user_formats;
>
> --
> 2.25.1
>


From maxime at cerno.tech  Wed Jan 12 01:20:54 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 12 Jan 2022 10:20:54 +0100
Subject: [PATCH 2/3] mmc:sunxi-mmc:fix clock division for timing mode
In-Reply-To: <20211222031521.34170-1-michael@allwinnertech.com>
References: <20211222031521.34170-1-michael@allwinnertech.com>
Message-ID: <20220112092054.4agh3lydvibea5wh@houat>

Hi Michael,

Thanks for your patch

On Wed, Dec 22, 2021 at 11:15:21AM +0800, Michael Wu wrote:
> When use new timings,all speed mode requires a doubled module clock
> if speed mode is ddr,requires a four times module clock
> When use old timings,only 8 bit ddr requires a doubled module clock
> 
> Signed-off-by: Michael Wu <michael at allwinnertech.com>
> ---
>  drivers/mmc/host/sunxi-mmc.c | 27 +++++++++++++++------------
>  1 file changed, 15 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index afeefead6501..7b47ec453fb6 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -774,20 +774,23 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
>  	if (!ios->clock)
>  		return 0;
>  
> -	/*
> -	 * Under the old timing mode, 8 bit DDR requires the module
> -	 * clock to be double the card clock. Under the new timing
> -	 * mode, all DDR modes require a doubled module clock.
> -	 *
> -	 * We currently only support the standard MMC DDR52 mode.
> -	 * This block should be updated once support for other DDR
> -	 * modes is added.
> +	/**
> +	 * When use new timings, all speed mode requires a doubled module clock.
> +	 * if speed mode is ddr, requires a four times module clock.
> +	 * When use old timings, only 8 bit ddr requires a doubled module clock.
>  	 */

I found the original comment to be clearer, maybe we can change it to
something like:

    /*
     * Under the old timing mode, 8 bit DDR requires the module
     * clock to be double the card clock. Under the new timing
     * mode, all modes require a doubled module clock, and DDR modes
     * require a quadrupled module clock.
     *
     * ...

> -	if (ios->timing == MMC_TIMING_MMC_DDR52 &&
> -	    (host->use_new_timings ||
> -	     ios->bus_width == MMC_BUS_WIDTH_8)) {
> -		div = 2;
> +	if (host->use_new_timings) {
>  		clock <<= 1;
> +		if (ios->timing == MMC_TIMING_MMC_DDR52) {
> +			div = 2;

Shouldn't that be 4?

> +			clock <<= 1;
> +		}
> +	} else {
> +		if (ios->timing == MMC_TIMING_MMC_DDR52 &&
> +				(ios->bus_width == MMC_BUS_WIDTH_8)) {

This creates some checkpatch.pl --strict warnings

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/22d598a1/attachment.sig>

From maxime at cerno.tech  Wed Jan 12 01:34:15 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 12 Jan 2022 10:34:15 +0100
Subject: [PATCH v2] mmc: sunxi-mmc: check ocr_avail on resource request
In-Reply-To: <20220104060325.3957-1-michael@allwinnertech.com>
References: <20220104060325.3957-1-michael@allwinnertech.com>
Message-ID: <20220112093415.wdy3ht5yizw5lffl@houat>

Hi,

On Tue, Jan 04, 2022 at 02:03:25PM +0800, Michael Wu wrote:
> Some platforms have no regulator, discrete power devices are used instead.

Is it really the case? vmmc at least should be mandatory so a platform
not having a regulator would violate the binding itself.

> However, sunxi_mmc_probe does not catch this exception when regulator is
> absent in DTS. This leads to sd or eMMC init failure.

This will still happen with your patch though?

> To solve this, a fixed vmmc regulator must be hooked up in DTS, like this:
> reg_dummy_vmmc: dummy_vmmc {
> 	compatible = "regulator-fixed";
> 	regulator-name = "dummy-vmmc";
> 	regulator-min-microvolt = <3300000>;
> 	regulator-max-microvolt = <3300000>;
> };
> 
> mmc0:mmc at 4020000 {
> 	compatible = "allwinner,sun50i-a100-emmc";
> 	device_type = "mmc0";
> 	vmmc-supply = <&reg_dummy_vmmc>;
> }
> 
> In this patch, we print an error message and abort the probe process if
> the regulator is not specified in DTS.

I'm fine with the patch itself, but it's really not clear to me what
situation is being fixed or improved here.

You're first mentioning that this is fixing the driver probing even if a
regulator is absent, but then states (rightfully) that in such a case we
should use a fixed regulator. So we should always have a regulator then?

I assume that you want the driver to properly error out instead of going
on if either a regulator is missing or if its voltages are out of range?

If the former, then we should probably check if host->mmc->supply.vmmc
returned an error. If the latter, then yes, checking ocr_avail is
probably fine but we should make it clearer in the error message that
it's what it's about.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/a56d1454/attachment-0001.sig>

From anshuman.khandual at arm.com  Wed Jan 12 01:34:57 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 12 Jan 2022 15:04:57 +0530
Subject: [PATCH 0/2] coresight: trbe: Update existing errata for Cortex-X2
Message-ID: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>

Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
well. This series updates the errata definition and detection as required.
This series applies on v5.16.

Relevant identification document can be found here.

https://developer.arm.com/documentation/101803/0200/AArch64-system-registers/
AArch64-identification-register-summary/MIDR-EL1--Main-ID-Register

Relevant errata document can be found here.

https://developer.arm.com/documentation/SDEN1775100

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (2):
  arm64: Add Cortex-X2 CPU part definition
  arm64: errata: Update ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges

 arch/arm64/Kconfig               | 12 ++++++------
 arch/arm64/include/asm/cputype.h |  2 ++
 arch/arm64/kernel/cpu_errata.c   |  2 ++
 3 files changed, 10 insertions(+), 6 deletions(-)

-- 
2.20.1



From anshuman.khandual at arm.com  Wed Jan 12 01:34:58 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 12 Jan 2022 15:04:58 +0530
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..657eeb06c784 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -74,6 +74,7 @@
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
 #define ARM_CPU_PART_CORTEX_A710	0xD47
+#define ARM_CPU_PART_CORTEX_X2		0xD48
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
 #define APM_CPU_PART_POTENZA		0x000
@@ -116,6 +117,7 @@
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
-- 
2.20.1



From anshuman.khandual at arm.com  Wed Jan 12 01:34:59 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 12 Jan 2022 15:04:59 +0530
Subject: [PATCH 2/2] arm64: errata: Update ARM64_ERRATUM_[2119858|2224489]
 with Cortex-X2 ranges
In-Reply-To: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1641980099-20315-3-git-send-email-anshuman.khandual@arm.com>

Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
well. Lets update these errata definition and detection to accommodate all
new Cortex-X2 based cpu MIDR ranges.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig             | 12 ++++++------
 arch/arm64/kernel/cpu_errata.c |  2 ++
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..d8046c832225 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -671,14 +671,14 @@ config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	bool
 
 config ARM64_ERRATUM_2119858
-	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
+	bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
 	default y
 	depends on CORESIGHT_TRBE
 	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	help
-	  This option adds the workaround for ARM Cortex-A710 erratum 2119858.
+	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858.
 
-	  Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace
+	  Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace
 	  data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in
 	  the event of a WRAP event.
 
@@ -761,14 +761,14 @@ config ARM64_ERRATUM_2253138
 	  If unsure, say Y.
 
 config ARM64_ERRATUM_2224489
-	bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
+	bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range"
 	depends on CORESIGHT_TRBE
 	default y
 	select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
 	help
-	  This option adds the workaround for ARM Cortex-A710 erratum 2224489.
+	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489.
 
-	  Affected Cortex-A710 cores might write to an out-of-range address, not reserved
+	  Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved
 	  for TRBE. Under some conditions, the TRBE might generate a write to the next
 	  virtually addressed page following the last page of the TRBE address space
 	  (i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..29cc062a4153 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -347,6 +347,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2119858
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
 #endif
 	{},
 };
@@ -371,6 +372,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2224489
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
 #endif
 	{},
 };
-- 
2.20.1



From yannick.fertre at foss.st.com  Wed Jan 12 01:44:26 2022
From: yannick.fertre at foss.st.com (yannick Fertre)
Date: Wed, 12 Jan 2022 10:44:26 +0100
Subject: [PATCH v2 6/6] drm/stm: ltdc: Drop format_mod_supported function
In-Reply-To: <20211222090552.25972-7-jose.exposito89@gmail.com>
References: <20211222090552.25972-1-jose.exposito89@gmail.com>
 <20211222090552.25972-7-jose.exposito89@gmail.com>
Message-ID: <c5ffa201-4811-b070-75b5-85064cd78506@foss.st.com>

Hello Jos?,
thanks for your patch.

Reviewed-by: Yannick Fertre <yannick.fertre at foss.st.com>
Tested-by: Yannick Fertre <yannick.fertre at foss.st.com>


On 12/22/21 10:05 AM, Jos? Exp?sito wrote:
> The "drm_plane_funcs.format_mod_supported" can be removed in favor of
> the default implementation.
> 
> Signed-off-by: Jos? Exp?sito <jose.exposito89 at gmail.com>
> ---
>   drivers/gpu/drm/stm/ltdc.c | 11 -----------
>   1 file changed, 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c
> index dbdee954692a..ef909e50f0e4 100644
> --- a/drivers/gpu/drm/stm/ltdc.c
> +++ b/drivers/gpu/drm/stm/ltdc.c
> @@ -925,16 +925,6 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p,
>   	fpsi->counter = 0;
>   }
>   
> -static bool ltdc_plane_format_mod_supported(struct drm_plane *plane,
> -					    u32 format,
> -					    u64 modifier)
> -{
> -	if (modifier == DRM_FORMAT_MOD_LINEAR)
> -		return true;
> -
> -	return false;
> -}
> -
>   static const struct drm_plane_funcs ltdc_plane_funcs = {
>   	.update_plane = drm_atomic_helper_update_plane,
>   	.disable_plane = drm_atomic_helper_disable_plane,
> @@ -943,7 +933,6 @@ static const struct drm_plane_funcs ltdc_plane_funcs = {
>   	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
>   	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
>   	.atomic_print_state = ltdc_plane_atomic_print_state,
> -	.format_mod_supported = ltdc_plane_format_mod_supported,
>   };
>   
>   static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
> 


From suzuki.poulose at arm.com  Wed Jan 12 01:46:38 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Wed, 12 Jan 2022 09:46:38 +0000
Subject: [PATCH 2/3] coresight: Fail to open with return stacks if they
 are unavailable
In-Reply-To: <70b562dc-adcd-da34-3811-ff872bc7cab8@arm.com>
References: <20211208160907.749482-1-james.clark@arm.com>
 <20211208160907.749482-2-james.clark@arm.com>
 <b52ef2f3-9e30-59a6-2aea-e46c93915868@arm.com>
 <b61ef2e3-e573-4867-af5d-fd5fabece4b1@arm.com>
 <70b562dc-adcd-da34-3811-ff872bc7cab8@arm.com>
Message-ID: <f6e2378a-11be-0886-6105-86ad9ccbc992@arm.com>

On 07/01/2022 15:10, James Clark wrote:
> 
> 
> On 09/12/2021 11:13, James Clark wrote:
>>
>>
>> On 09/12/2021 11:00, Suzuki K Poulose wrote:
>>> On 08/12/2021 16:09, James Clark wrote:
>>>> Maintain consistency with the other options by failing to open when they
>>>> aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
>>>> added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
>>>> requested but not supported by hardware.
>>>>
>>>> The consequence of not doing this is that the user may not be
>>>> aware that they are not enabling the feature as it is silently disabled.
>>>>
>>>> Signed-off-by: James Clark <james.clark at arm.com>
>>>> ---
>>>>  ? drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
>>>>  ? 1 file changed, 9 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> index d2bafb50c66a..0a9bb943a5e5 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>> @@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>>>>  ????? }
>>>>  ? ????? /* return stack - enable if selected and supported */
>>>> -??? if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
>>>> -??????? /* bit[12], Return stack enable bit */
>>>> -??????? config->cfg |= BIT(12);
>>>> -
>>>> +??? if (attr->config & BIT(ETM_OPT_RETSTK)) {
>>>> +??????? if (!drvdata->retstack) {
>>>> +??????????? ret = -EINVAL;
>>>> +??????????? goto out;
>>>> +??????? } else {
>>>> +??????????? /* bit[12], Return stack enable bit */
>>>> +??????????? config->cfg |= BIT(12);
>>>> +??????? }
>>>
>>> nit: While at this, please could you change the hard coded value
>>> to ETM4_CFG_BIT_RETSTK ?
>>>
>> I started changing them all because I had trouble searching for bits by name but then
>> I thought it would snowball into a bigger change so I undid it.
>>
>> I think I'll just go and do it now if it's an issue here.
> 
> Hi Suzuki,
> 
> I started on this and I think the only worthwhile change is to make them all consistent
> with sysreg.h. As in have xxx_SHIFT and xxx_MASK style definitions like:
> 
>    #define TRCCONFIGR_INSTP0_SHIFT		1
>    #define TRCCONFIGR_INSTPO_MASK		GENMASK(1,0)
> 
> This has been done for SPE and some of the new ETM stuff. If that sounds right to you
> I will go and do it as a followup patch to this one. It is quite a bit change so I can
> see maybe we don't want to do it? (Personally I would vote to do it)

Yes, please go ahead with that. Thanks for taking it up !

Suzuki


From yunfei.dong at mediatek.com  Wed Jan 12 01:49:05 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:05 +0800
Subject: [PATCH v18,
 01/19] media: mtk-vcodec: Get numbers of register bases from DT
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-2-yunfei.dong@mediatek.com>

Different platforms may have different numbers of register bases. Gets the
numbers of register bases from dts (sizeof(u32) * 4 bytes for each).

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 37 ++++++++++++++-----
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 40c39e1e596b..e1a82e233971 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -75,6 +75,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int reg_num, i;
+
+	/* Sizeof(u32) * 4 bytes for each register base. */
+	reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
+		sizeof(u32) * 4);
+	if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
+		dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reg_num; i++) {
+		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
+		if (IS_ERR(dev->reg_base[i]))
+			return PTR_ERR(dev->reg_base[i]);
+
+		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -203,7 +227,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int i, ret;
+	int ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -235,14 +259,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
-		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
-		if (IS_ERR((__force void *)dev->reg_base[i])) {
-			ret = PTR_ERR((__force void *)dev->reg_base[i]);
-			goto err_res;
-		}
-		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
-	}
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		goto err_res;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:04 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:04 +0800
Subject: [PATCH v18,
 00/19] Support multi hardware decode using of_platform_populate
Message-ID: <20220112094923.16839-1-yunfei.dong@mediatek.com>

This series adds support for multi hardware decode into mtk-vcodec, by first adding use
of_platform_populate to manage each hardware information: interrupt, clock, register
bases and power. Secondly add core work queue to deal with core hardware message,
at the same time, add msg queue for different hardware share messages. Lastly, the
architecture of different specs are not the same, using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.
Patches 4 export decoder pm interfaces.
Patches 5 add to support 8192.
Patch 6 support multi hardware.
Patch 7 separate video encoder and decoder document
Patch 8-17 add interfaces to support core hardware.
Patch 18-19 remove mtk_vcodec_release_dec/enc_pm interfaces.
---
changes compared with v17:
- fix checkpatch fail.
- fix kernel-doc fail
- fix smatch fail.

changes compared with v16:
- fix build warning for patch 13.

changes compared with v15:
- add Reviewed-by for patch 10.

changes compared with v14:
- rebase to latest media stage.

changes compared with v13:
- change some function position in case of ko dependency for patch 15.
- add reviewed-by for patch 06/13/15.

changes compared with v12:
- fix comments from rob for patch 15.
- fix comments from steve for 06 and 13.

changes compared with v11:
- fix comments from AngeloGioacchino for patch 09~11/19.
- fix comments from steve for patch 03/19.

changes compared with v10:
- fix comments from tzung-bi for patch 06/19.
- add more detail information for hardware block diagram 15/19

changes compared with v9:
- need not to build ko, just export pm interfaces for patch 04/19.
- fix comments for patch 06/19

changes compared with v8:
- add new patch 18~19 to remove mtk_vcodec_release_de/enc_pm interfaces.
- fix spelling mistakes for patch 17/19
- fix yaml comments for patch 15/19

Changes compared with v7:
- add new patch 4 to build decoder pm file as module
- add new patch 5 to support 8192
- fix comments for patch 6/17
- change some logic for using work queue instead of create thread for core hardware decode for patch 10/17
- using work queue for hardware decode instead of create thread for patch 13/17
- add returen value for patch 14/17
- fix yaml check fail 15/17

Changes compared with v6:
- Use of_platform_populate to manage multi hardware, not component framework for patch 4/15
- Re-write dtsi document for hardware architecture changed for patch 13/15 -The dtsi will write like below in patch 13/15:
    vcodec_dec: vcodec_dec at 16000000 {
        compatible = "mediatek,mt8192-vcodec-dec";
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
        mediatek,scp = <&scp>;
        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
        vcodec_lat {
            compatible = "mediatek,mtk-vcodec-lat";
            reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
            reg-name = "reg-misc";
            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
                 <&vdecsys_soc CLK_VDEC_SOC_LAT>,
                 <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
        };

        vcodec_core {
            compatible = "mediatek,mtk-vcodec-core";
            reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
            reg-names = "reg-misc";
            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys CLK_VDEC_VDEC>,
                 <&vdecsys CLK_VDEC_LAT>,
                 <&vdecsys CLK_VDEC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
        };
    };

Changes compared with v5:
- Add decoder hardware block diagram for patch 13/15

Changes compared with v4:
- Fix comments for patch 4/15
  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  Fix platform_set_drvdata.
- Fix build error for patch 9/15
- Add depend patch in case of error header file for patch 13/15

Changes compared with v3:
- Fix return value for patch 1/15
- Fix comments for patch 4/15
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
- Fix yaml files check fail for patch 5/15
- Fix yaml file check fail for patch 14/15

Changes compared with v1:
- Fix many comments for patch 3/14
- Remove unnecessary code for patch 4/14
- Using enum mtk_vdec_hw_count instead of magic numbers for patch 6/14
- Reconstructed get/put lat buffer for lat and core hardware for patch 7/14
- Using yaml format to instead of txt file for patch 12/14

Yunfei Dong (19):
  media: mtk-vcodec: Get numbers of register bases from DT
  media: mtk-vcodec: Align vcodec wake up interrupt interface
  media: mtk-vcodec: Refactor vcodec pm interface
  media: mtk-vcodec: export decoder pm functions
  media: mtk-vcodec: Support MT8192
  media: mtk-vcodec: Add to support multi hardware decode
  dt-bindings: media: mtk-vcodec: Separate video encoder and decoder
    dt-bindings
  media: mtk-vcodec: Use pure single core for MT8183
  media: mtk-vcodec: Add irq interface for multi hardware
  media: mtk-vcodec: Add msg queue feature for lat and core architecture
  media: mtk-vcodec: Generalize power and clock on/off interfaces
  media: mtk-vcodec: Add new interface to lock different hardware
  media: mtk-vcodec: Add work queue for core hardware decode
  media: mtk-vcodec: Support 34bits dma address for vdec
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  media: mtk-vcodec: Add core dec and dec end ipi msg
  media: mtk-vcodec: Use codec type to separate different hardware
  media: mtk-vcodec: Remove mtk_vcodec_release_dec_pm
  media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm

 .../media/mediatek,vcodec-decoder.yaml        | 176 +++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 187 ++++++++++++
 .../media/mediatek,vcodec-subdev-decoder.yaml | 265 ++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 131 --------
 drivers/media/platform/mtk-vcodec/Makefile    |   6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 177 ++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 201 ++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  56 ++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 106 +++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  12 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   2 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  21 ++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  73 ++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  21 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  10 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |   3 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     |  27 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  59 +++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   8 +-
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |   2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |   2 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  21 +-
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  16 +-
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 289 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 +++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  46 ++-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  22 ++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 34 files changed, 1812 insertions(+), 295 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:07 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:07 +0800
Subject: [PATCH v18, 03/19] media: mtk-vcodec: Refactor vcodec pm interface
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-4-yunfei.dong@mediatek.com>

Using the needed params for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 24 ++++++++-----------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  5 ++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
 5 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index e5f6e400a587..af235fa4c487 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -246,7 +246,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev);
+	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 		goto err_dec_pm;
@@ -377,7 +377,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -416,7 +416,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..ba96e62c6bb1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,15 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int i = 0, ret = 0;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	pm->mtkdev = mtkdev;
 	dec_clk = &pm->vdec_clk;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
@@ -32,13 +29,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 		return -1;
 	}
 
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (WARN_ON(!pdev)) {
+	if (WARN_ON(!larb_pdev))
 		return -1;
-	}
-	pm->larbvdec = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+
+	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -82,10 +78,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvdec);
 }
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..a3df6aef6cb9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,9 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+	struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1d2370608d0d..0fa9d85114b9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	venc_clk;
 	struct device	*larbvenc;
 	struct device	*dev;
-	struct mtk_vcodec_dev	*mtkdev;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..0c8c8f86788c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:12 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:12 +0800
Subject: [PATCH v18, 08/19] media: mtk-vcodec: Use pure single core for MT8183
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-9-yunfei.dong@mediatek.com>

Separates different architecture for hardware: pure_sin_core
and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
distinguish.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c     |  2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index c7f9259ad094..04ca43c77e5f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -626,4 +626,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 3294c8957ae5..23d997ac114d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,6 +357,7 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
 
 /* This platform data is used for one lat and one core architecture. */
@@ -375,4 +376,5 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = true,
+	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ab2004242c43..17e7deee10b5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -324,6 +324,14 @@ enum mtk_chip {
 	MTK_MT8195,
 };
 
+/*
+ * enum mtk_vdec_hw_arch - Used to separate different hardware architecture
+ */
+enum mtk_vdec_hw_arch {
+	MTK_VDEC_PURE_SINGLE_CORE,
+	MTK_VDEC_LAT_SINGLE_CORE,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -342,6 +350,7 @@ enum mtk_chip {
  * @num_framesizes: count of video decoder frame sizes
  *
  * @chip: chip this decoder is compatible with
+ * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
@@ -364,6 +373,7 @@ struct mtk_vcodec_dec_pdata {
 	const int num_framesizes;
 
 	enum mtk_chip chip;
+	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
 	bool uses_stateless_api;
-- 
2.25.1



From hverkuil at xs4all.nl  Wed Jan 12 01:52:16 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Wed, 12 Jan 2022 10:52:16 +0100
Subject: [PATCH v3 07/23] media: atmel: atmel-isc-base: use streaming
 status when queueing buffers
In-Reply-To: <5e4f591b-9105-9de0-5067-2bd82dc04983@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-8-eugen.hristev@microchip.com>
 <c6adb59e-4554-dc08-3772-148eb22c29ba@xs4all.nl>
 <5e4f591b-9105-9de0-5067-2bd82dc04983@microchip.com>
Message-ID: <aaa692f7-174a-83a9-8aae-64cda91044cb@xs4all.nl>

On 11/01/2022 17:38, Eugen.Hristev at microchip.com wrote:
> On 1/11/22 5:53 PM, Hans Verkuil wrote:
>> On 13/12/2021 14:49, Eugen Hristev wrote:
>>> During experiments with libcamera, it looks like vb2_is_streaming returns
>>> true before our start streaming is called.
>>> Order of operations is streamon -> queue -> start_streaming
>>> ISC would have started the DMA immediately when a buffer is being added
>>> to the vbqueue if the queue is streaming.
>>> It is more safe to start the DMA after the start streaming of the driver is
>>> called.
>>> Thus, even if vb2queue is streaming, add the buffer to the dma queue of the
>>> driver instead of actually starting the DMA process, if the start streaming
>>> has not been called yet.
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>>> ---
>>>   drivers/media/platform/atmel/atmel-isc-base.c | 17 ++++++++++-------
>>>   1 file changed, 10 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>>> index 26a6090f056c..e6c9071c04f0 100644
>>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>>> @@ -441,12 +441,14 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
>>>        unsigned long flags;
>>>
>>>        spin_lock_irqsave(&isc->dma_queue_lock, flags);
>>> -     if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
>>> -             vb2_is_streaming(vb->vb2_queue)) {
>>> +
>>> +     if (!isc->cur_frm && list_empty(&isc->dma_queue) && !isc->stop) {
>>>                isc->cur_frm = buf;
>>>                isc_start_dma(isc);
>>> -     } else
>>> +     } else {
>>>                list_add_tail(&buf->list, &isc->dma_queue);
>>> +     }
>>> +
>>>        spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
>>>   }
>>
>> Both the old and new code doesn't make a lot of sense.
> 
> Hello Hans,
> 
> I debated this a bit with Laurent when I initially wrote the patch.
> 
> The problem with the current code, or the current way things are 
> working, is the fact that vb2_is_streaming returns true from the moment 
> of streamon.
> The DMA engine of the ISC is being started at the moment of 
> start_streaming, and if buffers are being sent earlier/later, they are 
> just added to the queue and DMA engine is restarted if it finished 
> previously.
> However if frames are added beforehand, like, first streamon, then add 

beforehand -> afterwards?

> some frames, and then later call the start_streaming, ISC will crash. 
> (as I said, DMA engine is prepared at start_streaming).
> To avoid this, I changed the vb2_is_streaming calls to keeping an 
> internal state of the streaming.
> Do you think I should try another different approach to solve this ?
> Perhaps do not prepare the ISC dma engine at start_streaming, but at 
> another place ?
> 
> Laurent do you remember the talk we had about this problem a while back ?
> 
>>
>> buf_queue is only called by vb2 if start_streaming has already been called or is
>> about to be called.
> 
> That's a huge difference for ISC driver as it is today. start_streaming 
> being called afterwards, means the ISC DMA engine is not started (not 
> started streaming), hence a crash.

The start_streaming op is called when streamon is called and if there are
sufficient buffers (>= q->min_buffers_needed). If there are insufficient
buffers at streamon time, then start_streaming is only called when the number
of queued buffers reaches the minimum.

vb2 has three different state checks that you can use:

vb2_is_busy() is true if buffers are allocated. Typically this means that you
can no longer do format changes or anything that might change the buffer
sizes or layout.

vb2_is_streaming() is true if streamon was called. If this is true, then vb2_is_busy()
is also true.

And finally vb2_start_streaming_called() is true if the start_streaming op
was called (i.e. DMA is in progress). If this is true, then vb2_is_streaming is
also true.

Basically vb2_is_streaming() reports the streaming state that userspace sees,
while vb2_start_streaming_called() reports the internal DMA streaming state.

The confusion is probably that you were using vb2_is_streaming instead of
vb2_start_streaming_called.

> 
>>
>> Typically all that the buf_queue op does is to call list_add_tail(&buf->list, &isc->dma_queue);
>> inside the spinlock.
>>
>>>
>>> @@ -1014,7 +1016,7 @@ static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>>>   {
>>>        struct isc_device *isc = video_drvdata(file);
>>>
>>> -     if (vb2_is_streaming(&isc->vb2_vidq))
>>> +     if (!isc->stop)
>>
>> This is weird as well. Normally this calls vb2_is_busy to check if the
>> queue is busy (that really means that buffers are already allocated, so
>> changing the format isn't allowed anymore).
> 
> You think the query to the streaming status makes no sense here hence it 
> should be removed completely ?

Right. And instead check vb2_is_busy().

I actually think that this is something that would fail with v4l2-compliance.

Do you still run v4l2-compliance?

> I can do that with a prequel patch if it's the case.

Probably wise.

Regards,

	Hans

> 
> Thanks for reviewing,
> 
> Eugen
> 
>>
>>>                return -EBUSY;
>>>
>>>        return isc_set_fmt(isc, f);
>>> @@ -1536,7 +1538,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>>
>>>                isc_update_awb_ctrls(isc);
>>>
>>> -             if (vb2_is_streaming(&isc->vb2_vidq)) {
>>> +             if (!isc->stop) {
>>
>> Ditto.
>>
>>>                        /*
>>>                         * If we are streaming, we can update profile to
>>>                         * have the new settings in place.
>>> @@ -1552,8 +1554,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>>                }
>>>
>>>                /* if we have autowhitebalance on, start histogram procedure */
>>> -             if (ctrls->awb == ISC_WB_AUTO &&
>>> -                 vb2_is_streaming(&isc->vb2_vidq) &&
>>> +             if (ctrls->awb == ISC_WB_AUTO && !isc->stop &&
>>>                    ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>>>                        isc_set_histogram(isc, true);
>>>
>>> @@ -1829,6 +1830,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>>        struct vb2_queue *q = &isc->vb2_vidq;
>>>        int ret = 0;
>>>
>>> +     isc->stop = true;
>>> +
>>
>> I'm really not sure that you need the stop bool at all.
>>
>>>        INIT_WORK(&isc->awb_work, isc_awb_work);
>>>
>>>        ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
>>
>> Regards,
>>
>>          Hans
>>
> 



From krzysztof.kozlowski at canonical.com  Wed Jan 12 01:52:58 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 10:52:58 +0100
Subject: [PATCH v2 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <Yd48C4pRH7tQz++f@robh.at.kernel.org>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
 <20220111101338.58630-3-krzysztof.kozlowski@canonical.com>
 <Yd48C4pRH7tQz++f@robh.at.kernel.org>
Message-ID: <efcd2b6d-0565-47b2-87b6-ec1a356e6a47@canonical.com>

On 12/01/2022 03:25, Rob Herring wrote:
> On Tue, Jan 11, 2022 at 11:13:36AM +0100, Krzysztof Kozlowski wrote:
>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
>> controller bindings to DT schema format
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
>> ---
>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 198 ++++++++++++++++++
>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 -----------
>>  MAINTAINERS                                   |   2 +-
>>  5 files changed, 235 insertions(+), 123 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>>
>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>> new file mode 100644
>> index 000000000000..aa5a1f48494b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>> @@ -0,0 +1,35 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description:
>> +  See spi-peripheral-props.yaml for more info.
>> +
>> +properties:
>> +  controller-data:
>> +    type: object
>> +    additionalProperties: false
>> +
>> +    properties:
>> +      samsung,spi-feedback-delay:
>> +        description: |
>> +          The sampling phase shift to be applied on the miso line (to account
>> +          for any lag in the miso line). Valid values:
>> +           - 0: No phase shift.
>> +           - 1: 90 degree phase shift sampling.
>> +           - 2: 180 degree phase shift sampling.
>> +           - 3: 270 degree phase shift sampling.
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        enum: [0, 1, 2, 3]
>> +
>> +    required:
>> +      - samsung,spi-feedback-delay
>> +
>> +additionalProperties: true
>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> new file mode 100644
>> index 000000000000..da4533feb946
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
>> @@ -0,0 +1,198 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Samsung S3C/S5P/Exynos SoC SPI controller
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description:
>> +  All the SPI controller nodes should be represented in the aliases node using
>> +  the following format 'spi{n}' where n is a unique number for the alias.
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - enum:
>> +          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
>> +          - samsung,s3c6410-spi
>> +          - samsung,s5pv210-spi # for S5PV210 and S5PC110
>> +          - samsung,exynos5433-spi
>> +      - const: samsung,exynos7-spi
>> +        deprecated: true
>> +
>> +  clocks:
>> +    minItems: 2
>> +    maxItems: 3
>> +
>> +  clock-names:
>> +    minItems: 2
>> +    maxItems: 3
>> +
>> +  cs-gpios: true
>> +
>> +  dmas:
>> +    minItems: 2
>> +    maxItems: 2
>> +
>> +  dma-names:
>> +    items:
>> +      - const: tx
>> +      - const: rx
>> +
>> +  interrupts:
>> +    maxItems: 1
>> +
>> +  no-cs-readback:
>> +    description:
>> +      The CS line is disconnected, therefore the device should not operate
>> +      based on CS signalling.
>> +    type: boolean
>> +
>> +  num-cs:
>> +    minimum: 1
>> +    maximum: 4
>> +    default: 1
>> +
>> +  samsung,spi-src-clk:
>> +    description:
>> +      If the spi controller includes a internal clock mux to select the clock
>> +      source for the spi bus clock, this property can be used to indicate the
>> +      clock to be used for driving the spi bus clock. If not specified, the
>> +      clock number 0 is used as default.
>> +    $ref: /schemas/types.yaml#/definitions/uint32
>> +    default: 0
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +patternProperties:
>> +  "^.*@[0-9a-f]+$":
>> +    type: object
>> +    allOf:
>> +      - $ref: spi-peripheral-props.yaml
>> +
>> +    required:
>> +      - controller-data
>> +
>> +    unevaluatedProperties: false
> 
> This is wrong because the child nodes will certainly have device 
> specific properties.
> 
> The whole child node schema can be dropped.

The controller-data at this point is still required (this is merely
existing bindings conversion), but I guess we can skip it since next
commit will remove it anyway, right?


Best regards,
Krzysztof


From yunfei.dong at mediatek.com  Wed Jan 12 01:49:09 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:09 +0800
Subject: [PATCH v18, 05/19] media: mtk-vcodec: Support MT8192
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-6-yunfei.dong@mediatek.com>

Adds MT8192's compatible "mediatek,mt8192-vcodec-dec".
Adds MT8192's device private data mtk_lat_sig_core_pdata.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec.h   |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c     |  4 ++++
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c        | 16 ++++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index e08886a600a3..66cd6d2242c3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -68,6 +68,7 @@ extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
+extern const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata;
 
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index af235fa4c487..c17927f79e22 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -392,6 +392,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
 		.compatible = "mediatek,mt8183-vcodec-dec",
 		.data = &mtk_vdec_8183_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8192-vcodec-dec",
+		.data = &mtk_lat_sig_core_pdata,
+	},
 	{},
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 3d9f47555884..183cd67a334a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,3 +357,19 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 };
+
+const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
+	.chip = MTK_MT8192,
+	.init_vdec_params = mtk_init_vdec_params,
+	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
+	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
+	.vdec_formats = mtk_video_formats,
+	.num_formats = NUM_FORMATS,
+	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
+	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.vdec_framesizes = mtk_vdec_framesizes,
+	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.uses_stateless_api = true,
+	.worker = mtk_vdec_worker,
+	.flush_decoder = mtk_vdec_flush_decoder,
+};
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:19 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:19 +0800
Subject: [PATCH v18,
 15/19] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-16-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../media/mediatek,vcodec-subdev-decoder.yaml | 265 ++++++++++++++++++
 1 file changed, 265 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
new file mode 100644
index 000000000000..d587fc3e39fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -0,0 +1,265 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Video Decode Accelerator With Multi Hardware
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities. Required
+  parent and child device node.
+
+  About the Decoder Hardware Block Diagram, please check below:
+
+    +---------------------------------+------------------------------------+
+    |                                 |                                    |
+    | input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output |
+    |            ||                   |                     ||             |
+    +------------||-------------------+---------------------||-------------+
+              lat workqueue           |              core workqueue     <parent>
+    -------------||-----------------------------------------||------------------
+                 ||                                         ||          <child>
+                 \/ <----------------HW index-------------->\/
+           +------------------------------------------------------+
+           |                    enable/disable                    |
+           |           clk     power    irq    iommu              |
+           |                 (lat/lat soc/core0/core1)            |
+           +------------------------------------------------------+
+
+  As above, there are parent and child devices, child mean each hardware. The child device
+  controls the information of each hardware independent which include clk/power/irq.
+
+  There are two workqueues in parent device: lat workqueue and core workqueue. They are used
+  to lat and core hardware deocder. Lat workqueue need to get input bitstream and lat buffer,
+  then enable lat to decode, writing the result to lat buffer, dislabe hardware when lat decode
+  done. Core workqueue need to get lat buffer and output buffer, then enable core to decode,
+  writing the result to output buffer, disable hardware when core decode done. These two
+  hardwares will decode each frame cyclically.
+
+  For the smi common may not the same for each hardware, can't combine all hardware in one node,
+  or leading to iommu fault when access dram data.
+
+properties:
+  compatible:
+    const: mediatek,mt8192-vcodec-dec
+
+  reg:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+# Required child node:
+patternProperties:
+  '^vcodec-lat@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-lat
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - interrupts
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+  '^vcodec-core@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-core
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - interrupts
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - iommus
+  - mediatek,scp
+  - dma-ranges
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8192-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8192-clk.h>
+    #include <dt-bindings/power/mt8192-power.h>
+
+    video-codec at 16000000 {
+        compatible = "mediatek,mt8192-vcodec-dec";
+        mediatek,scp = <&scp>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0 0x16000000 0x40000>;
+        reg = <0x16000000 0x1000>;		/* VDEC_SYS */
+        vcodec-lat at 10000 {
+            compatible = "mediatek,mtk-vcodec-lat";
+            reg = <0x10000 0x800>;
+            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+                <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+                <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+                <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+        };
+
+        vcodec-core at 25000 {
+            compatible = "mediatek,mtk-vcodec-core";
+            reg = <0x25000 0x1000>;
+            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                <&vdecsys CLK_VDEC_VDEC>,
+                <&vdecsys CLK_VDEC_LAT>,
+                <&vdecsys CLK_VDEC_LARB1>,
+                <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+        };
+    };
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:21 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:21 +0800
Subject: [PATCH v18,
 17/19] media: mtk-vcodec: Use codec type to separate different
 hardware
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-18-yunfei.dong@mediatek.com>

There is just one core thread, in order to separate different
hardware, using codec type to separeate it in scp driver.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 9d8079c4f976..5daca8d52ebb 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -35,6 +35,8 @@ enum vdec_ipi_msgid {
  * @msg_id	: vdec_ipi_msgid
  * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
  * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @codec_type	: codec fourcc
+ * @reserved	: reserved param
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
@@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd {
 		uint32_t vpu_inst_addr;
 		uint32_t inst_id;
 	};
+	uint32_t codec_type;
+	uint32_t reserved;
 };
 
 /**
@@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack {
 /**
  * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
  * @msg_id	: AP_IPIMSG_DEC_INIT
- * @reserved	: Reserved field
+ * @codec_type	: codec fourcc
  * @ap_inst_addr	: AP video decoder instance address
  */
 struct vdec_ap_ipi_init {
 	uint32_t msg_id;
-	uint32_t reserved;
+	uint32_t codec_type;
 	uint64_t ap_inst_addr;
 };
 
@@ -77,7 +81,7 @@ struct vdec_ap_ipi_init {
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
  *	VP9 decoder  [0]:profile, [1][2] width/height
- * @reserved	: Reserved field
+ * @codec_type	: codec fourcc
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
@@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start {
 		uint32_t inst_id;
 	};
 	uint32_t data[3];
-	uint32_t reserved;
+	uint32_t codec_type;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index bfd8e87dceff..c84fac52fe26 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
-	int err;
+	int err, id, msgid;
 
-	mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
+	msgid = *(uint32_t *)msg;
+	mtk_vcodec_debug(vpu, "id=%X", msgid);
 
 	vpu->failure = 0;
 	vpu->signaled = 0;
 
-	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		if (msgid == AP_IPIMSG_DEC_CORE ||
+			msgid == AP_IPIMSG_DEC_CORE_END)
+			id = vpu->core_id;
+		else
+			id = vpu->id;
+	} else {
+		id = vpu->id;
+	}
+
+	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
 				     len, 2000);
 	if (err) {
 		mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-			       vpu->id, *(uint32_t *)msg, err);
+			       id, msgid, err);
 		return err;
 	}
 
@@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 		msg.vpu_inst_addr = vpu->inst_addr;
 	else
 		msg.inst_id = vpu->inst_id;
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
 
 	err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
 					 vpu->handler, "vdec", NULL);
-	if (err != 0) {
+	if (err) {
 		mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
 		return err;
 	}
 
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
+					 vpu->core_id, vpu->handler,
+					 "vdec", NULL);
+		if (err) {
+			mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
+			return err;
+		}
+	}
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_INIT;
 	msg.ap_inst_addr = (unsigned long)vpu;
+	msg.codec_type = vpu->codec_type;
 
 	mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
 
@@ -187,6 +210,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- ret=%d", err);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index ae24b75d1649..4cb3c7f5a3ad 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_ctx;
 /**
  * struct vdec_vpu_inst - VPU instance for video codec
  * @id          : ipi msg id for each decoder
+ * @core_id     : core id used to separate different hardware
  * @vsi         : driver structure allocated by VPU side and shared to AP side
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
@@ -26,9 +27,11 @@ struct mtk_vcodec_ctx;
  * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
+ * @codec_type     : use codec type to separate different codecs
  */
 struct vdec_vpu_inst {
 	int id;
+	int core_id;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
@@ -38,6 +41,7 @@ struct vdec_vpu_inst {
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
+	unsigned int codec_type;
 };
 
 /**
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:14 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:14 +0800
Subject: [PATCH v18,
 10/19] media: mtk-vcodec: Add msg queue feature for lat and core
 architecture
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-11-yunfei.dong@mediatek.com>

For lat and core architecture, lat thread will send message to core
thread when lat decode done. Core hardware will use the message
from lat to decode, then free message to lat thread when decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   9 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 257 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 149 ++++++++++
 4 files changed, 416 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index c61bfb179bcc..359619653a0e 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -12,6 +12,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
+		vdec_msg_queue.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 7023a572c64b..29a0950badf0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -15,7 +15,9 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
+
 #include "mtk_vcodec_util.h"
+#include "vdec_msg_queue.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
@@ -282,6 +284,8 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ *
+ * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	struct vdec_msg_queue msg_queue;
 };
 
 enum mtk_chip {
@@ -457,6 +462,8 @@ struct mtk_vcodec_enc_pdata {
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
  *
+ * @msg_queue_core_ctx: msg queue context used for core workqueue
+ *
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
@@ -498,6 +505,8 @@ struct mtk_vcodec_dev {
 	unsigned int dec_capability;
 	unsigned int enc_capability;
 
+	struct vdec_msg_queue_ctx msg_queue_core_ctx;
+
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
new file mode 100644
index 000000000000..59dbb5c369bd
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_drv.h"
+#include "vdec_msg_queue.h"
+
+#define VDEC_MSG_QUEUE_TIMEOUT_MS 1500
+
+/* the size used to store lat slice header information */
+#define VDEC_LAT_SLICE_HEADER_SZ    (640 * SZ_1K)
+
+/* the size used to store avc error information */
+#define VDEC_ERR_MAP_SZ_AVC         (17 * SZ_1K)
+
+/* core will read the trans buffer which decoded by lat to decode again.
+ * The trans buffer size of FHD and 4K bitstreams are different.
+ */
+static int vde_msg_queue_get_trans_size(int width, int height)
+{
+	if (width > 1920 || height > 1088)
+		return 30 * SZ_1M;
+	else
+		return 6 * SZ_1M;
+}
+
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index)
+{
+	init_waitqueue_head(&ctx->ready_to_use);
+	INIT_LIST_HEAD(&ctx->ready_queue);
+	spin_lock_init(&ctx->ready_lock);
+	ctx->ready_num = 0;
+	ctx->hardware_index = hardware_index;
+}
+
+static struct list_head *vdec_get_buf_list(int hardware_index, struct vdec_lat_buf *buf)
+{
+	switch (hardware_index) {
+	case MTK_VDEC_CORE:
+		return &buf->core_list;
+	case MTK_VDEC_LAT0:
+		return &buf->lat_list;
+	default:
+		return NULL;
+	}
+}
+
+int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf)
+{
+	struct list_head *head;
+
+	head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to qbuf: %d", msg_ctx->hardware_index);
+		return -EINVAL;
+	}
+
+	spin_lock(&msg_ctx->ready_lock);
+	list_add_tail(head, &msg_ctx->ready_queue);
+	msg_ctx->ready_num++;
+
+	if (msg_ctx->hardware_index != MTK_VDEC_CORE)
+		wake_up_all(&msg_ctx->ready_to_use);
+
+	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+		msg_ctx->hardware_index, buf, msg_ctx->ready_num);
+	spin_unlock(&msg_ctx->ready_lock);
+
+	return 0;
+}
+
+static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *msg_ctx)
+{
+	int ret;
+
+	ret = wait_event_timeout(msg_ctx->ready_to_use,
+		!list_empty(&msg_ctx->ready_queue),
+		msecs_to_jiffies(VDEC_MSG_QUEUE_TIMEOUT_MS));
+	if (!ret)
+		return false;
+
+	return true;
+}
+
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx)
+{
+	struct vdec_lat_buf *buf;
+	struct list_head *head;
+	int ret;
+
+	spin_lock(&msg_ctx->ready_lock);
+	if (list_empty(&msg_ctx->ready_queue)) {
+		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
+			msg_ctx->hardware_index, msg_ctx->ready_num);
+		spin_unlock(&msg_ctx->ready_lock);
+
+		if (msg_ctx->hardware_index == MTK_VDEC_CORE)
+			return NULL;
+
+		ret = vdec_msg_queue_wait_event(msg_ctx);
+		if (!ret)
+			return NULL;
+		spin_lock(&msg_ctx->ready_lock);
+	}
+
+	if (msg_ctx->hardware_index == MTK_VDEC_CORE)
+		buf = list_first_entry(&msg_ctx->ready_queue,
+			struct vdec_lat_buf, core_list);
+	else
+		buf = list_first_entry(&msg_ctx->ready_queue,
+			struct vdec_lat_buf, lat_list);
+
+	head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
+	if (!head) {
+		spin_unlock(&msg_ctx->ready_lock);
+		mtk_v4l2_err("fail to dqbuf: %d", msg_ctx->hardware_index);
+		return NULL;
+	}
+	list_del(head);
+
+	msg_ctx->ready_num--;
+	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+		msg_ctx->hardware_index, buf, msg_ctx->ready_num);
+	spin_unlock(&msg_ctx->ready_lock);
+
+	return buf;
+}
+
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_rptr_addr = ube_rptr;
+	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_wptr_addr = ube_wptr;
+	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
+		msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr, ube_wptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+{
+	long timeout_jiff;
+	int ret;
+
+	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
+		msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+		timeout_jiff);
+	if (ret) {
+		mtk_v4l2_debug(3, "success to get lat buf: %d",
+			msg_queue->lat_ctx.ready_num);
+		return true;
+	}
+	mtk_v4l2_err("failed with lat buf isn't full: %d",
+		msg_queue->lat_ctx.ready_num);
+	return false;
+}
+
+void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_mem *mem;
+	int i;
+
+	mem = &msg_queue->wdma_addr;
+	if (mem->va)
+		mtk_vcodec_mem_free(ctx, mem);
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		mem = &lat_buf->wdma_err_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		mem = &lat_buf->slice_bc_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		kfree(lat_buf->private_data);
+	}
+}
+
+int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
+	int private_size)
+{
+	struct vdec_lat_buf *lat_buf;
+	int i, err;
+
+	/* already init msg queue */
+	if (msg_queue->wdma_addr.size)
+		return 0;
+
+	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
+		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+
+	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+	if (err) {
+		mtk_v4l2_err("failed to allocate wdma_addr buf");
+		return -ENOMEM;
+	}
+	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
+		if (!lat_buf->private_data) {
+			mtk_v4l2_err("failed to allocate private_data[%d]", i);
+			err = -ENOMEM;
+			goto mem_alloc_err;
+		}
+
+		lat_buf->ctx = ctx;
+		lat_buf->core_decode = core_decode;
+		err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
+		if (err) {
+			mtk_v4l2_err("failed to qbuf buf[%d]", i);
+			goto mem_alloc_err;
+		}
+	}
+	return 0;
+
+mem_alloc_err:
+	vdec_msg_queue_deinit(msg_queue, ctx);
+	return err;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
new file mode 100644
index 000000000000..b793e23e628d
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_MSG_QUEUE_H_
+#define _VDEC_MSG_QUEUE_H_
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "mtk_vcodec_util.h"
+
+#define NUM_BUFFER_COUNT 3
+
+struct vdec_lat_buf;
+struct mtk_vcodec_ctx;
+struct mtk_vcodec_dev;
+typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
+
+/**
+ * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed
+ * @ready_to_use: ready used queue used to signalize when get a job queue
+ * @ready_queue: list of ready lat buffer queues
+ * @ready_lock: spin lock to protect the lat buffer usage
+ * @ready_num: number of buffers ready to be processed
+ * @hardware_index: hardware id that this queue is used for
+ */
+struct vdec_msg_queue_ctx {
+	wait_queue_head_t ready_to_use;
+	struct list_head ready_queue;
+	spinlock_t ready_lock;
+	int ready_num;
+	int hardware_index;
+};
+
+/**
+ * struct vdec_lat_buf - lat buffer message used to store lat info for core decode
+ * @wdma_err_addr: wdma error address used for lat hardware
+ * @slice_bc_addr: slice bc address used for lat hardware
+ * @ts_info: need to set timestamp from output to capture
+ *
+ * @private_data: shared information used to lat and core hardware
+ * @ctx: mtk vcodec context information
+ * @core_decode: different codec use different decode callback function
+ * @lat_list: add lat buffer to lat head list
+ * @core_list: add lat buffer to core head list
+ */
+struct vdec_lat_buf {
+	struct mtk_vcodec_mem wdma_err_addr;
+	struct mtk_vcodec_mem slice_bc_addr;
+	struct vb2_v4l2_buffer ts_info;
+
+	void *private_data;
+	struct mtk_vcodec_ctx *ctx;
+	core_decode_cb_t core_decode;
+	struct list_head lat_list;
+	struct list_head core_list;
+};
+
+/**
+ * struct vdec_msg_queue - used to store lat buffer message
+ * @lat_buf: lat buffer used to store lat buffer information
+ * @wdma_addr: wdma address used for ube
+ * @wdma_rptr_addr: ube read point
+ * @wdma_wptr_addr: ube write point
+ * @lat_ctx: used to store lat buffer list
+ */
+struct vdec_msg_queue {
+	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+
+	struct mtk_vcodec_mem wdma_addr;
+	uint64_t wdma_rptr_addr;
+	uint64_t wdma_wptr_addr;
+
+	struct vdec_msg_queue_ctx lat_ctx;
+};
+
+/**
+ * vdec_msg_queue_init - init lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ * @core_decode: core decode callback for each codec
+ * @private_size: the private data size used to share with core
+ *
+ * Return: returns 0 if init successfully, or fail.
+ */
+int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+	struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
+	int private_size);
+
+/**
+ * vdec_msg_queue_init_ctx - used to init msg queue context information.
+ * @ctx: message queue context
+ * @hardware_index: hardware index
+ */
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index);
+
+/**
+ * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
+ * @ctx: message queue context
+ * @buf: current lat buffer
+ *
+ * Return: returns 0 if qbuf successfully, or fail.
+ */
+int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx, struct vdec_lat_buf *buf);
+
+/**
+ * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
+ * @ctx: message queue context
+ *
+ * Return: returns not null if dq successfully, or fail.
+ */
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
+
+/**
+ * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_rptr: current ube read point
+ */
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr);
+
+/**
+ * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_wptr: current ube write point
+ */
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr);
+
+/**
+ * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
+ *                                    in lat list.
+ * @msg_queue: used to store the lat buffer information
+ *
+ * Return: returns true if successfully, or fail.
+ */
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
+
+/**
+ * vdec_msg_queue_deinit - deinit lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ */
+void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, struct mtk_vcodec_ctx *ctx);
+
+#endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:22 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:22 +0800
Subject: [PATCH v18, 18/19] media: mtk-vcodec: Remove mtk_vcodec_release_dec_pm
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-19-yunfei.dong@mediatek.com>

There are only two lines in mtk_vcodec_release_dec_pm, using
pm_runtime_disable and put_device instead directly.

Move pm_runtime_enable outside mtk_vcodec_init_dec_pm to symmetry with
pm_runtime_disable, after that, rename mtk_vcodec_init_dec_pm to *_clk
since it only has clock operations now.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Co-developed-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c   | 10 +++++++---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c    |  7 +++++--
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c    | 12 ++----------
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h    |  3 +--
 4 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 1c2b96b4930b..d44894fa2f6e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
@@ -128,12 +129,13 @@ static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
 		return ret;
 	}
 
-	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	ret = mtk_vcodec_init_dec_clk(pdev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to get mt vcodec clock source");
 		return ret;
 	}
 
+	pm_runtime_enable(&pdev->dev);
 	return 0;
 }
 
@@ -446,7 +448,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
 		destroy_workqueue(dev->core_workqueue);
 err_res:
-	mtk_vcodec_release_dec_pm(&dev->pm);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvdec);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -489,7 +492,8 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(&dev->pm);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvdec);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 4f946e21b5d7..c853afe3b3f7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "mtk_vcodec_drv.h"
@@ -140,9 +141,10 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	subdev_dev->plat_dev = pdev;
-	ret = mtk_vcodec_init_dec_pm(pdev, &subdev_dev->pm);
+	ret = mtk_vcodec_init_dec_clk(pdev, &subdev_dev->pm);
 	if (ret)
 		return ret;
+	pm_runtime_enable(&pdev->dev);
 
 	of_id = of_match_device(mtk_vdec_hw_match, dev);
 	if (!of_id) {
@@ -181,7 +183,8 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, subdev_dev);
 	return 0;
 err:
-	mtk_vcodec_release_dec_pm(&subdev_dev->pm);
+	pm_runtime_disable(subdev_dev->pm.dev);
+	put_device(subdev_dev->pm.larbvdec);
 	return ret;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index b91c29afdfde..37941e322a01 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -15,7 +15,7 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
@@ -73,20 +73,12 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 		}
 	}
 
-	pm_runtime_enable(&pdev->dev);
 	return 0;
 put_device:
 	put_device(pm->larbvdec);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm);
-
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
-{
-	pm_runtime_disable(pm->dev);
-	put_device(pm->larbvdec);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 6ae29fea4e7f..c4121df9764f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,9 +9,8 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
+int mtk_vcodec_init_dec_clk(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:15 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:15 +0800
Subject: [PATCH v18,
 11/19] media: mtk-vcodec: Generalize power and clock on/off interfaces
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-12-yunfei.dong@mediatek.com>

Generalizes power and clock on/off interfaces to support different
hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     | 59 +++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
 9 files changed, 146 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 9802e5cc535f..64359cf692f5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -46,7 +46,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[0]);
@@ -193,7 +193,7 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(&dev->pm);
+		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
 		if (ret < 0)
 			goto err_load_fw;
 		/*
@@ -253,7 +253,7 @@ static int fops_vcodec_release(struct file *file)
 	mtk_vcodec_dec_release(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(&dev->pm);
+		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 2cd65a083994..4f946e21b5d7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -65,7 +65,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[VDEC_HW_SYS]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index 5c2cfeaa9d9f..a63e4b1b81c3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -35,6 +35,8 @@ enum mtk_vdec_hw_reg_idx {
  * @main_dev: main device
  * @reg_base: mapped address of MTK Vcodec registers.
  *
+ * @curr_ctx: the context that is waiting for codec hardware
+ *
  * @dec_irq : decoder irq resource
  * @pm      : power management control
  * @hw_idx  : each hardware index
@@ -44,6 +46,8 @@ struct mtk_vdec_hw_dev {
 	struct mtk_vcodec_dev *main_dev;
 	void __iomem *reg_base[VDEC_HW_MAX];
 
+	struct mtk_vcodec_ctx *curr_ctx;
+
 	int dec_irq;
 	struct mtk_vcodec_pm pm;
 	int hw_idx;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 1fc2a4b2a137..b91c29afdfde 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
  */
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -86,10 +88,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return -EINVAL;
+		}
+		pm = &subdev_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -98,21 +113,50 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int ret, i = 0;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int ret, i;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+		enable_irq(subdev_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		enable_irq(vdec_dev->dec_irq);
+	}
 
+	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
 		if (ret) {
@@ -135,11 +179,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int i = 0;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int i;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+		disable_irq(subdev_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		disable_irq(vdec_dev->dec_irq);
+	}
+
+	dec_clk = &pm->vdec_clk;
 	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index a3df6aef6cb9..6ae29fea4e7f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -13,9 +13,9 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 	struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 29a0950badf0..d74ca88de827 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -284,6 +284,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @hw_id: hardware index used to identify different hardware.
  *
  * @msg_queue: msg queue used to store lat buffer information.
  */
@@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
 
 	int decoded_frame_cnt;
 	struct mutex lock;
+	int hw_id;
 
 	struct vdec_msg_queue msg_queue;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index 5bac820a47fc..5f42748714a5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -6,7 +6,10 @@
 */
 
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
 
@@ -71,25 +74,59 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_mem_free);
 
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx)
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx)
 {
-	unsigned long flags;
+	if (hw_idx >= MTK_VDEC_HW_MAX || hw_idx < 0 || !dev->subdev_dev[hw_idx]) {
+		mtk_v4l2_err("hw idx is out of range:%d", hw_idx);
+		return NULL;
+	}
+
+	return dev->subdev_dev[hw_idx];
+}
+EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
 
-	spin_lock_irqsave(&dev->irqlock, flags);
-	dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	unsigned long flags;
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return;
+		}
+		subdev_dev->curr_ctx = ctx;
+	} else {
+		vdec_dev->curr_ctx = ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 }
 EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
 
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+	unsigned int hw_idx)
 {
 	unsigned long flags;
 	struct mtk_vcodec_ctx *ctx;
-
-	spin_lock_irqsave(&dev->irqlock, flags);
-	ctx = dev->curr_ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return NULL;
+		}
+		ctx = subdev_dev->curr_ctx;
+	} else {
+		ctx = vdec_dev->curr_ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 87c3d6d4bfa7..c245321f8dcb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -54,8 +54,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+				struct mtk_vcodec_ctx *ctx, int hw_idx);
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+				unsigned int hw_idx);
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx);
 
 #endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 42008243ceac..05a5b240e906 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -24,21 +24,24 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP9:
 		ctx->dec_if = &vdec_vp9_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	return ret;
@@ -69,13 +72,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 
 	mtk_vdec_lock(ctx);
 
-	mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
-	enable_irq(ctx->dev->dec_irq);
+	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	disable_irq(ctx->dev->dec_irq);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
-	mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
+	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
 
 	mtk_vdec_unlock(ctx);
 
@@ -103,9 +104,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return;
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1



From s.shtylyov at omp.ru  Wed Jan 12 01:56:31 2022
From: s.shtylyov at omp.ru (Sergey Shtylyov)
Date: Wed, 12 Jan 2022 12:56:31 +0300
Subject: consolidate the compat fcntl definitions
In-Reply-To: <20220111083515.502308-1-hch@lst.de>
References: <20220111083515.502308-1-hch@lst.de>
Message-ID: <4ae57b3d-0758-1a05-b743-c46a97d09e5e@omp.ru>

Hello!

On 1/11/22 11:35 AM, Christoph Hellwig wrote:

> currenty the compat fcnt definitions are duplicate for all compat

   fcntl?

> architectures, and the native fcntl64 definitions aren't even usable
> from userspace due to a bogus CONFIG_64BIT ifdef.  This series tries
> to sort out all that.

[...]

MBR, Sergey


From yunfei.dong at mediatek.com  Wed Jan 12 01:49:16 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:16 +0800
Subject: [PATCH v18,
 12/19] media: mtk-vcodec: Add new interface to lock different hardware
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-13-yunfei.dong@mediatek.com>

For add new hardware, not only need to lock lat hardware, also
need to lock core hardware in case of different instance start
to decoder at the same time.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c     | 4 ++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 5 +++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 2 +-
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 2b334a8a81c6..130ecef2e766 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_unlock(&ctx->dev->dec_mutex);
+	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_lock(&ctx->dev->dec_mutex);
+	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 64359cf692f5..471b8c6ba7f2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -279,7 +279,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_dec;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int i, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -311,7 +311,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	mutex_init(&dev->dec_mutex);
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
+		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
 	spin_lock_init(&dev->irqlock);
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index d74ca88de827..ae8e9adb389a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -500,7 +500,7 @@ struct mtk_vcodec_dev {
 	int dec_irq;
 	int enc_irq;
 
-	struct mutex dec_mutex;
+	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex enc_mutex;
 
 	struct mtk_vcodec_pm pm;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:06 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:06 +0800
Subject: [PATCH v18,
 02/19] media: mtk-vcodec: Align vcodec wake up interrupt interface
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-3-yunfei.dong@mediatek.com>

Vdec and venc can use the same function to wake up interrupt event.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 --------
 3 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index e1a82e233971..e5f6e400a587 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -28,13 +28,6 @@
 #define VDEC_IRQ_CLR	0x10
 #define VDEC_IRQ_CFG_REG	0xa4
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
-{
-	ctx->int_cond = 1;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -66,7 +59,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 581522177308..1d2370608d0d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -473,4 +473,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 	return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
 }
 
+/* Wake up context wait_queue */
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+{
+	ctx->int_cond = 1;
+	ctx->int_type = reason;
+	wake_up_interruptible(&ctx->queue);
+}
+
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index aeaecb8d416e..027546108f44 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -62,14 +62,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_vp8[] =  {
 	},
 };
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
-{
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:23 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:23 +0800
Subject: [PATCH v18, 19/19] media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-20-yunfei.dong@mediatek.com>

There are only two lines in mtk_vcodec_release_enc_pm, using
pm_runtime_disable and put_device instead directly.

Move pm_runtime_enable outside mtk_vcodec_release_enc_pm to symmetry with
pm_runtime_disable, after that, rename mtk_vcodec_init_enc_pm to *_clk
since it only has clock operations now.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Co-developed-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 9 ++++++---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c  | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h  | 3 +--
 3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 347f0d87e2ff..507ad1ea2104 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
@@ -257,7 +258,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		return PTR_ERR(dev->fw_handler);
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
-	ret = mtk_vcodec_init_enc_pm(dev);
+	ret = mtk_vcodec_init_enc_clk(dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
 		goto err_enc_pm;
@@ -369,7 +370,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_enc_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_enc_pm(dev);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvenc);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -458,7 +460,8 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_enc);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_enc_pm(dev);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvenc);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 0c8c8f86788c..0825c6ec4eb7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -13,7 +13,7 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 {
 	struct device_node *node;
 	struct platform_device *pdev;
@@ -86,13 +86,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
-{
-	pm_runtime_disable(mtkdev->pm.dev);
-	put_device(mtkdev->pm.larbvenc);
-}
-
-
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 {
 	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index b7ecdfd74823..bc455cefc0cd 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -9,8 +9,7 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev);
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:08 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:08 +0800
Subject: [PATCH v18, 04/19] media: mtk-vcodec: export decoder pm functions
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-5-yunfei.dong@mediatek.com>

When mtk vcodec decoder is build as a module, we need to export
mtk-vcodec-dec pm functions to make them visible by the other components.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index ba96e62c6bb1..1fc2a4b2a137 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -77,12 +77,14 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev,
 	put_device(pm->larbvdec);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm);
 
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
 	pm_runtime_disable(pm->dev);
 	put_device(pm->larbvdec);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
@@ -94,6 +96,7 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
@@ -103,6 +106,7 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
 void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
@@ -129,6 +133,7 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
 void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
@@ -139,3 +144,4 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:17 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:17 +0800
Subject: [PATCH v18,
 13/19] media: mtk-vcodec: Add work queue for core hardware decode
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-14-yunfei.dong@mediatek.com>

Add work queue to process core hardware information.
First, get lat_buf from message queue, then call core
hardware of each codec(H264/VP9/AV1) to decode, finally
puts lat_buf back to the message.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 16 +++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 ++
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      |  2 ++
 4 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 471b8c6ba7f2..10215ccc85f7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -311,6 +311,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
+	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
+		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE);
+		dev->core_workqueue = alloc_ordered_workqueue("core-decoder",
+			WQ_MEM_RECLAIM | WQ_FREEZABLE);
+		if (!dev->core_workqueue) {
+			mtk_v4l2_err("Failed to create core workqueue");
+			ret = -EINVAL;
+			goto err_res;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
@@ -322,7 +333,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 	if (ret) {
 		mtk_v4l2_err("v4l2_device_register err=%d", ret);
-		goto err_res;
+		goto err_core_workq;
 	}
 
 	init_waitqueue_head(&dev->queue);
@@ -423,6 +434,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	video_unregister_device(vfd_dec);
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
+err_core_workq:
+	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
+		destroy_workqueue(dev->core_workqueue);
 err_res:
 	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ae8e9adb389a..55e4ce2c2135 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -27,6 +27,7 @@
 #define MTK_VCODEC_MAX_PLANES	3
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
+#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -464,6 +465,7 @@ struct mtk_vcodec_enc_pdata {
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
  *
+ * @core_workqueue: queue used for core hardware decode
  * @msg_queue_core_ctx: msg queue context used for core workqueue
  *
  * @subdev_dev: subdev hardware device
@@ -507,6 +509,7 @@ struct mtk_vcodec_dev {
 	unsigned int dec_capability;
 	unsigned int enc_capability;
 
+	struct workqueue_struct *core_workqueue;
 	struct vdec_msg_queue_ctx msg_queue_core_ctx;
 
 	void *subdev_dev[MTK_VDEC_HW_MAX];
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index 59dbb5c369bd..d6b919a61e04 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -68,6 +68,9 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf
 
 	if (msg_ctx->hardware_index != MTK_VDEC_CORE)
 		wake_up_all(&msg_ctx->ready_to_use);
+	else
+		queue_work(buf->ctx->dev->core_workqueue,
+			&buf->ctx->msg_queue.core_work);
 
 	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
 		msg_ctx->hardware_index, buf, msg_ctx->ready_num);
@@ -194,6 +197,34 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
 	}
 }
 
+static void vdec_msg_queue_core_work(struct work_struct *work)
+{
+	struct vdec_msg_queue *msg_queue =
+		container_of(work, struct vdec_msg_queue, core_work);
+	struct mtk_vcodec_ctx *ctx =
+		container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue);
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	struct vdec_lat_buf *lat_buf;
+
+	lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+	if (!lat_buf)
+		return;
+
+	ctx = lat_buf->ctx;
+	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
+
+	lat_buf->core_decode(lat_buf);
+
+	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+
+	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
+		mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
+			dev->msg_queue_core_ctx.ready_num);
+		queue_work(dev->core_workqueue, &msg_queue->core_work);
+	}
+}
+
 int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
 	struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
 	int private_size)
@@ -206,6 +237,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
 		return 0;
 
 	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
 	msg_queue->wdma_addr.size = vde_msg_queue_get_trans_size(
 		ctx->picinfo.buf_w, ctx->picinfo.buf_h);
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
index b793e23e628d..f62922753c64 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -67,6 +67,7 @@ struct vdec_lat_buf {
  * @wdma_addr: wdma address used for ube
  * @wdma_rptr_addr: ube read point
  * @wdma_wptr_addr: ube write point
+ * @core_work: core hardware work
  * @lat_ctx: used to store lat buffer list
  */
 struct vdec_msg_queue {
@@ -76,6 +77,7 @@ struct vdec_msg_queue {
 	uint64_t wdma_rptr_addr;
 	uint64_t wdma_wptr_addr;
 
+	struct work_struct core_work;
 	struct vdec_msg_queue_ctx lat_ctx;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:10 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:10 +0800
Subject: [PATCH v18,
 06/19] media: mtk-vcodec: Add to support multi hardware decode
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-7-yunfei.dong@mediatek.com>

There are more than two hardwares for decoder: LAT0, LAT1 and CORE. In
order to manage these hardwares, register each hardware as independent
platform device for the larbs are different.

Each hardware module controls its own information which includes
interrupt/power/clocks/registers.

Calling of_platform_populate in parent device, and use subdev_bitmap to
record whether the hardwares are registered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   5 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  85 +++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 198 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  52 +++++
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   3 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  21 ++
 7 files changed, 333 insertions(+), 32 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..c61bfb179bcc 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -2,7 +2,8 @@
 
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 				       mtk-vcodec-enc.o \
-				       mtk-vcodec-common.o
+				       mtk-vcodec-common.o \
+				       mtk-vcodec-dec-hw.o
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
@@ -16,6 +17,8 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
 
+mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o
+
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
 		mtk_vcodec_enc.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index c17927f79e22..f03f99108929 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -18,16 +18,12 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
-#define VDEC_HW_ACTIVE	0x10
-#define VDEC_IRQ_CFG	0x11
-#define VDEC_IRQ_CLR	0x10
-#define VDEC_IRQ_CFG_REG	0xa4
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -92,6 +88,42 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
 	return 0;
 }
 
+static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		return ret;
+
+	if (dev->vdec_pdata->is_subdev_supported)
+		return 0;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "failed to get irq number");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+		mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to get mt vcodec clock source");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -113,6 +145,11 @@ static int fops_vcodec_open(struct file *file)
 	init_waitqueue_head(&ctx->queue);
 	mutex_init(&ctx->lock);
 
+	if (dev->vdec_pdata->is_subdev_supported && dev->subdev_prob_done) {
+		ret = dev->subdev_prob_done(dev);
+		if (ret)
+			goto err_ctrls_setup;
+	}
 	ctx->type = MTK_INST_DECODER;
 	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
@@ -217,7 +254,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_dec;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
@@ -246,32 +282,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
-		goto err_dec_pm;
-	}
-
-	ret = mtk_vcodec_get_reg_bases(dev);
-	if (ret)
-		goto err_res;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
-
-	dev->dec_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
-			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	ret = mtk_vcodec_init_dec_resources(dev);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
-			dev->dec_irq,
-			ret);
-		goto err_res;
+		dev_err(&pdev->dev, "Failed to init dec resources");
+		goto err_dec_pm;
 	}
 
 	mutex_init(&dev->dec_mutex);
@@ -326,6 +340,15 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_event_workq;
 	}
 
+	if (dev->vdec_pdata->is_subdev_supported) {
+		ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
+			&pdev->dev);
+		if (ret) {
+			mtk_v4l2_err("Main device of_platform_populate failed.");
+			goto err_event_workq;
+		}
+	}
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
new file mode 100644
index 000000000000..dbcb65dae01f
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+
+static const struct of_device_id mtk_vdec_hw_match[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+		.data = (void *)MTK_VDEC_LAT0,
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+		.data = (void *)MTK_VDEC_CORE,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match);
+
+static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev)
+{
+	struct platform_device *pdev = vdec_dev->plat_dev;
+	struct device_node *subdev_node;
+	enum mtk_vdec_hw_id hw_idx;
+	const struct of_device_id *of_id;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_vdec_hw_match); i++) {
+		of_id = &mtk_vdec_hw_match[i];
+		subdev_node = of_find_compatible_node(NULL, NULL,
+			of_id->compatible);
+		if (!subdev_node)
+			continue;
+
+		hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
+		if (!test_bit(hw_idx, vdec_dev->subdev_bitmap)) {
+			dev_err(&pdev->dev, "vdec %d is not ready", hw_idx);
+			return -EAGAIN;
+		}
+	}
+
+	return 0;
+}
+
+static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
+{
+	struct mtk_vdec_hw_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	u32 cg_status;
+	unsigned int dec_done_status;
+	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
+					VDEC_IRQ_CFG_REG;
+
+	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev);
+
+	/* check if HW active or not */
+	cg_status = readl(dev->reg_base[VDEC_HW_SYS]);
+	if (cg_status & VDEC_HW_ACTIVE) {
+		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
+			cg_status);
+		return IRQ_HANDLED;
+	}
+
+	dec_done_status = readl(vdec_misc_addr);
+	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+	    MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+		return IRQ_HANDLED;
+
+	/* clear interrupt */
+	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
+	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+
+	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
+		ctx->id, dec_done_status);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_vdec_hw_init_irq(struct mtk_vdec_hw_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+				mtk_vdec_hw_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_vdec_hw_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_dev *main_dev;
+	const struct of_device_id *of_id;
+	int hw_idx;
+	int ret;
+
+	if (!dev->parent) {
+		dev_err(dev, "no parent for hardware devices.\n");
+		return -ENODEV;
+	}
+
+	main_dev = dev_get_drvdata(dev->parent);
+	if (!main_dev) {
+		dev_err(dev, "failed to get parent driver data");
+		return -EINVAL;
+	}
+
+	subdev_dev = devm_kzalloc(dev, sizeof(*subdev_dev), GFP_KERNEL);
+	if (!subdev_dev)
+		return -ENOMEM;
+
+	subdev_dev->plat_dev = pdev;
+	ret = mtk_vcodec_init_dec_pm(pdev, &subdev_dev->pm);
+	if (ret)
+		return ret;
+
+	of_id = of_match_device(mtk_vdec_hw_match, dev);
+	if (!of_id) {
+		dev_err(dev, "Can't get vdec subdev id.\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
+	if (hw_idx >= MTK_VDEC_HW_MAX) {
+		dev_err(dev, "Hardware index %d not correct.\n", hw_idx);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	main_dev->subdev_dev[hw_idx] = subdev_dev;
+	subdev_dev->hw_idx = hw_idx;
+	subdev_dev->main_dev = main_dev;
+	subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS];
+	set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
+
+	ret = mtk_vdec_hw_init_irq(subdev_dev);
+	if (ret)
+		goto err;
+
+	subdev_dev->reg_base[VDEC_HW_MISC] =
+		devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC])) {
+		ret = PTR_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC]);
+		goto err;
+	}
+
+	if (!main_dev->subdev_prob_done)
+		main_dev->subdev_prob_done = mtk_vdec_hw_prob_done;
+
+	platform_set_drvdata(pdev, subdev_dev);
+	return 0;
+err:
+	mtk_vcodec_release_dec_pm(&subdev_dev->pm);
+	return ret;
+}
+
+static struct platform_driver mtk_vdec_driver = {
+	.probe	= mtk_vdec_hw_probe,
+	.driver	= {
+		.name	= "mtk-vdec-comp",
+		.of_match_table = mtk_vdec_hw_match,
+	},
+};
+module_platform_driver(mtk_vdec_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video decoder hardware driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
new file mode 100644
index 000000000000..5c2cfeaa9d9f
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_HW_H_
+#define _MTK_VCODEC_DEC_HW_H_
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "mtk_vcodec_drv.h"
+
+#define VDEC_HW_ACTIVE 0x10
+#define VDEC_IRQ_CFG 0x11
+#define VDEC_IRQ_CLR 0x10
+#define VDEC_IRQ_CFG_REG 0xa4
+
+/**
+ * enum mtk_vdec_hw_reg_idx - subdev hardware register base index
+ * @VDEC_HW_SYS : vdec soc register index
+ * @VDEC_HW_MISC: vdec misc register index
+ * @VDEC_HW_MAX : vdec supported max register index
+ */
+enum mtk_vdec_hw_reg_idx {
+	VDEC_HW_SYS,
+	VDEC_HW_MISC,
+	VDEC_HW_MAX
+};
+
+/**
+ * struct mtk_vdec_hw_dev - vdec hardware driver data
+ * @plat_dev: platform device
+ * @main_dev: main device
+ * @reg_base: mapped address of MTK Vcodec registers.
+ *
+ * @dec_irq : decoder irq resource
+ * @pm      : power management control
+ * @hw_idx  : each hardware index
+ */
+struct mtk_vdec_hw_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *main_dev;
+	void __iomem *reg_base[VDEC_HW_MAX];
+
+	int dec_irq;
+	struct mtk_vcodec_pm pm;
+	int hw_idx;
+};
+
+#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index bef49244e61b..c7f9259ad094 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -625,4 +625,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 183cd67a334a..3294c8957ae5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -356,8 +356,10 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = false,
 };
 
+/* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
@@ -372,4 +374,5 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = true,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 0fa9d85114b9..ab2004242c43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -93,6 +93,17 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+/*
+ * enum mtk_vdec_hw_id - Hardware index used to separate
+ *                         different hardware
+ */
+enum mtk_vdec_hw_id {
+	MTK_VDEC_CORE,
+	MTK_VDEC_LAT0,
+	MTK_VDEC_LAT1,
+	MTK_VDEC_HW_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -332,6 +343,7 @@ enum mtk_chip {
  *
  * @chip: chip this decoder is compatible with
  *
+ * @is_subdev_supported: whether support parent-node architecture(subdev)
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -353,6 +365,7 @@ struct mtk_vcodec_dec_pdata {
 
 	enum mtk_chip chip;
 
+	bool is_subdev_supported;
 	bool uses_stateless_api;
 };
 
@@ -423,6 +436,10 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ *
+ * @subdev_dev: subdev hardware device
+ * @subdev_prob_done: check whether all used hw device is prob done
+ * @subdev_bitmap: used to record hardware is ready or not
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -460,6 +477,10 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	void *subdev_dev[MTK_VDEC_HW_MAX];
+	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
+	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:11 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:11 +0800
Subject: [PATCH v18,
 07/19] dt-bindings: media: mtk-vcodec: Separate video encoder and
 decoder dt-bindings
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-8-yunfei.dong@mediatek.com>

Separate decoder and encoder document for the dts are big difference.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../media/mediatek,vcodec-decoder.yaml        | 176 +++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 187 ++++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 131 ------------
 3 files changed, 363 insertions(+), 131 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..df1d677098fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,176 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-dec
+      - mediatek,mt8183-vcodec-dec
+
+  reg:
+    maxItems: 12
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 8
+
+  clock-names:
+    items:
+      - const: vcodecpll
+      - const: univpll_d2
+      - const: clk_cci400_sel
+      - const: vdec_sel
+      - const: vdecpll
+      - const: vencpll
+      - const: venc_lt_sel
+      - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-dec
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-dec
+
+    then:
+      required:
+        - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8173-power.h>
+
+    vcodec_dec: vcodec at 16000000 {
+      compatible = "mediatek,mt8173-vcodec-dec";
+      reg = <0x16000000 0x100>,   /*VDEC_SYS*/
+          <0x16020000 0x1000>,  /*VDEC_MISC*/
+          <0x16021000 0x800>,   /*VDEC_LD*/
+          <0x16021800 0x800>,   /*VDEC_TOP*/
+          <0x16022000 0x1000>,  /*VDEC_CM*/
+          <0x16023000 0x1000>,  /*VDEC_AD*/
+          <0x16024000 0x1000>,  /*VDEC_AV*/
+          <0x16025000 0x1000>,  /*VDEC_PP*/
+          <0x16026800 0x800>,   /*VP8_VD*/
+          <0x16027000 0x800>,   /*VP6_VD*/
+          <0x16027800 0x800>,   /*VP8_VL*/
+          <0x16028400 0x400>;   /*VP9_VD*/
+      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+      mediatek,larb = <&larb1>;
+      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+      mediatek,vpu = <&vpu>;
+      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+             <&topckgen CLK_TOP_UNIVPLL_D2>,
+             <&topckgen CLK_TOP_CCI400_SEL>,
+             <&topckgen CLK_TOP_VDEC_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL>,
+             <&apmixedsys CLK_APMIXED_VENCPLL>,
+             <&topckgen CLK_TOP_VENC_LT_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL_370P5>;
+      clock-names = "vcodecpll",
+                  "univpll_d2",
+                  "clk_cci400_sel",
+                  "vdec_sel",
+                  "vdecpll",
+                  "vencpll",
+                  "venc_lt_sel",
+                  "vdec_bus_clk_src";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+                      <&topckgen CLK_TOP_CCI400_SEL>,
+                      <&topckgen CLK_TOP_VDEC_SEL>,
+                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
+                      <&apmixedsys CLK_APMIXED_VENCPLL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+                             <&topckgen CLK_TOP_UNIVPLL_D2>,
+                             <&topckgen CLK_TOP_VCODECPLL>;
+      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..b72c1a50e89e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-enc-vp8
+      - mediatek,mt8173-vcodec-enc
+      - mediatek,mt8183-vcodec-enc
+      - mediatek,mt8192-vcodec-enc
+      - mediatek,mt8195-vcodec-enc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-enc
+              - mediatek,mt8192-vcodec-enc
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-enc-vp8
+              - mediatek,mt8173-vcodec-enc
+
+    then:
+      required:
+        - mediatek,vpu
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - mediatek,mt8173-vcodec-enc
+            - mediatek,mt8192-vcodec-enc
+            - mediatek,mt8173-vcodec-enc
+
+    then:
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_sel
+    else:  # for vp8 hw decoder
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_lt_sel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    vcodec_enc_avc: vcodec at 18002000 {
+      compatible = "mediatek,mt8173-vcodec-enc";
+      reg = <0x18002000 0x1000>;
+      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU>,
+             <&iommu M4U_PORT_VENC_REC>,
+             <&iommu M4U_PORT_VENC_BSDMA>,
+             <&iommu M4U_PORT_VENC_SV_COMV>,
+             <&iommu M4U_PORT_VENC_RD_COMV>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+             <&iommu M4U_PORT_VENC_REF_LUMA>,
+             <&iommu M4U_PORT_VENC_REF_CHROMA>,
+             <&iommu M4U_PORT_VENC_NBM_RDMA>,
+             <&iommu M4U_PORT_VENC_NBM_WDMA>;
+      mediatek,larb = <&larb3>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      clock-names = "venc_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+    };
+
+    vcodec_enc_vp8: vcodec at 19002000 {
+      compatible = "mediatek,mt8173-vcodec-enc-vp8";
+      reg =  <0x19002000 0x1000>;	/* VENC_LT_SYS */
+      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+      mediatek,larb = <&larb5>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      clock-names = "venc_lt_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index 665a9508708e..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,131 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
-  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
-  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
-  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
-  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
-  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
-  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
-  "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
-- reg : Physical base address of the video codec registers and length of
-  memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
-  the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
-  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
-  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
-  "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec at 16000000 {
-    compatible = "mediatek,mt8173-vcodec-dec";
-    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
-          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
-          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
-          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
-          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
-          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
-          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
-          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
-          <0 0x16026800 0 0x800>,   /*VP8_VD*/
-          <0 0x16027000 0 0x800>,   /*VP6_VD*/
-          <0 0x16027800 0 0x800>,   /*VP8_VL*/
-          <0 0x16028400 0 0x400>;   /*VP9_VD*/
-    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-    mediatek,larb = <&larb1>;
-    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
-    mediatek,vpu = <&vpu>;
-    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
-    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
-             <&topckgen CLK_TOP_UNIVPLL_D2>,
-             <&topckgen CLK_TOP_CCI400_SEL>,
-             <&topckgen CLK_TOP_VDEC_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL>,
-             <&apmixedsys CLK_APMIXED_VENCPLL>,
-             <&topckgen CLK_TOP_VENC_LT_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL_370P5>;
-    clock-names = "vcodecpll",
-                  "univpll_d2",
-                  "clk_cci400_sel",
-                  "vdec_sel",
-                  "vdecpll",
-                  "vencpll",
-                  "venc_lt_sel",
-                  "vdec_bus_clk_src";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
-                      <&topckgen CLK_TOP_CCI400_SEL>,
-                      <&topckgen CLK_TOP_VDEC_SEL>,
-                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
-                      <&apmixedsys CLK_APMIXED_VENCPLL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
-                             <&topckgen CLK_TOP_UNIVPLL_D2>,
-                             <&topckgen CLK_TOP_VCODECPLL>;
-    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
-  };
-
-vcodec_enc_avc: vcodec at 18002000 {
-    compatible = "mediatek,mt8173-vcodec-enc";
-    reg = <0 0x18002000 0 0x1000>;
-    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU>,
-             <&iommu M4U_PORT_VENC_REC>,
-             <&iommu M4U_PORT_VENC_BSDMA>,
-             <&iommu M4U_PORT_VENC_SV_COMV>,
-             <&iommu M4U_PORT_VENC_RD_COMV>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
-             <&iommu M4U_PORT_VENC_REF_LUMA>,
-             <&iommu M4U_PORT_VENC_REF_CHROMA>,
-             <&iommu M4U_PORT_VENC_NBM_RDMA>,
-             <&iommu M4U_PORT_VENC_NBM_WDMA>;
-    mediatek,larb = <&larb3>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    clock-names = "venc_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
-  };
-
-vcodec_enc_vp8: vcodec at 19002000 {
-    compatible = "mediatek,mt8173-vcodec-enc-vp8";
-    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
-    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
-             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
-             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
-             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
-             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-    mediatek,larb = <&larb5>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    clock-names = "venc_lt_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
-  };
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:18 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:18 +0800
Subject: [PATCH v18,
 14/19] media: mtk-vcodec: Support 34bits dma address for vdec
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-15-yunfei.dong@mediatek.com>

Use the dma_set_mask_and_coherent helper to set vdec
DMA bit mask to support 34bits iova space(16GB) that
the mt8192 iommu HW support.

Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
regarding which iova range VDEC actually locate, it
depends on the dma-ranges property of vdec dtsi node.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 10215ccc85f7..1c2b96b4930b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -322,6 +322,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+		if (ret) {
+			mtk_v4l2_err("Failed to set mask");
+			goto err_core_workq;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:20 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:20 +0800
Subject: [PATCH v18, 16/19] media: mtk-vcodec: Add core dec and dec end ipi msg
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-17-yunfei.dong@mediatek.com>

Add core dec and dec end ipi msg:
AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5f45a537beb4..9d8079c4f976 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -18,12 +18,16 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_END = 0xA002,
 	AP_IPIMSG_DEC_DEINIT = 0xA003,
 	AP_IPIMSG_DEC_RESET = 0xA004,
+	AP_IPIMSG_DEC_CORE = 0xA005,
+	AP_IPIMSG_DEC_CORE_END = 0xA006,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
 	VPU_IPIMSG_DEC_END_ACK = 0xB002,
 	VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
+	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
+	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 5dffc459a33d..bfd8e87dceff 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_END_ACK:
 		case VPU_IPIMSG_DEC_DEINIT_ACK:
 		case VPU_IPIMSG_DEC_RESET_ACK:
+		case VPU_IPIMSG_DEC_CORE_ACK:
+		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
 		default:
@@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_core(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
+}
+
 int vpu_dec_end(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
 }
 
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
+}
+
 int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index c2ed5b6cab8b..ae24b75d1649 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_reset(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_core - core start decoding, basically the function will be invoked once
+ *                 every frame.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core(struct vdec_vpu_inst *vpu);
+
+/**
+ * vpu_dec_core_end - core end decoding, basically the function will be invoked once
+ *               when core HW decoding done and receive interrupt successfully. The
+ *               decoder in VPU will updata hardware information and deinit hardware
+ *               and check if there is a new decoded frame available to display.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
+
 #endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 01:49:13 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Wed, 12 Jan 2022 17:49:13 +0800
Subject: [PATCH v18,
 09/19] media: mtk-vcodec: Add irq interface for multi hardware
In-Reply-To: <20220112094923.16839-1-yunfei.dong@mediatek.com>
References: <20220112094923.16839-1-yunfei.dong@mediatek.com>
Message-ID: <20220112094923.16839-10-yunfei.dong@mediatek.com>

Adds irq interface for multi hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 27 +++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  4 +--
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 12 files changed, 69 insertions(+), 38 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index f03f99108929..9802e5cc535f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -24,6 +24,19 @@
 #include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
+static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
+{
+	switch (dev->vdec_pdata->hw_arch) {
+	case MTK_VDEC_PURE_SINGLE_CORE:
+		return MTK_VDEC_ONE_CORE;
+	case MTK_VDEC_LAT_SINGLE_CORE:
+		return MTK_VDEC_ONE_LAT_ONE_CORE;
+	default:
+		mtk_v4l2_err("hw arch %d not supported", dev->vdec_pdata->hw_arch);
+		return MTK_VDEC_NO_HW;
+	}
+}
+
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -55,7 +68,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
@@ -128,7 +141,7 @@ static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
-	int ret = 0;
+	int ret = 0, i, hw_count;
 	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -142,14 +155,24 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
-	mutex_init(&ctx->lock);
+	if (ctx->dev->vdec_pdata->is_subdev_supported) {
+		hw_count = mtk_vcodec_get_hw_count(dev);
+		if (!hw_count || !dev->subdev_prob_done) {
+			ret = -EINVAL;
+			goto err_ctrls_setup;
+		}
 
-	if (dev->vdec_pdata->is_subdev_supported && dev->subdev_prob_done) {
 		ret = dev->subdev_prob_done(dev);
 		if (ret)
 			goto err_ctrls_setup;
+
+		for (i = 0; i < hw_count; i++)
+			init_waitqueue_head(&ctx->queue[i]);
+	} else {
+		init_waitqueue_head(&ctx->queue[0]);
 	}
+	mutex_init(&ctx->lock);
+
 	ctx->type = MTK_INST_DECODER;
 	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index dbcb65dae01f..2cd65a083994 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -84,7 +84,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
 	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
 	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
 
 	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
 		ctx->id, dec_done_status);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 17e7deee10b5..7023a572c64b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_HW_MAX,
 };
 
+/*
+ * enum mtk_vdec_hw_count - Supported hardware count
+ */
+enum mtk_vdec_hw_count {
+	MTK_VDEC_NO_HW = 0,
+	MTK_VDEC_ONE_CORE,
+	MTK_VDEC_ONE_LAT_ONE_CORE,
+	MTK_VDEC_MAX_HW_COUNT,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -293,9 +303,9 @@ struct mtk_vcodec_ctx {
 	struct vdec_pic_info picinfo;
 	int dpb_size;
 
-	int int_cond;
-	int int_type;
-	wait_queue_head_t queue;
+	int int_cond[MTK_VDEC_HW_MAX];
+	int int_type[MTK_VDEC_HW_MAX];
+	wait_queue_head_t queue[MTK_VDEC_HW_MAX];
 	unsigned int irq_status;
 
 	struct v4l2_ctrl_handler ctrl_hdl;
@@ -504,11 +514,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 }
 
 /* Wake up context wait_queue */
-static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason,
+	unsigned int hw_id)
 {
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
+	ctx->int_cond[hw_id] = 1;
+	ctx->int_type[hw_id] = reason;
+	wake_up_interruptible(&ctx->queue[hw_id]);
 }
 
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 027546108f44..347f0d87e2ff 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -103,7 +103,7 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 	return IRQ_HANDLED;
 }
 
@@ -129,7 +129,7 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+	init_waitqueue_head(&ctx->queue[0]);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
index 70580c2525ba..677fbba09934 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
@@ -11,34 +11,31 @@
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx  *ctx, int command,
-				 unsigned int timeout_ms)
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+	int command, unsigned int timeout_ms, unsigned int hw_id)
 {
-	wait_queue_head_t *waitqueue;
 	long timeout_jiff, ret;
 	int status = 0;
 
-	waitqueue = (wait_queue_head_t *)&ctx->queue;
 	timeout_jiff = msecs_to_jiffies(timeout_ms);
-
-	ret = wait_event_interruptible_timeout(*waitqueue,
-				ctx->int_cond,
+	ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
+				ctx->int_cond[hw_id],
 				timeout_jiff);
 
 	if (!ret) {
 		status = -1;	/* timeout */
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout time=%ums out %d %d!",
-			     ctx->id, ctx->type, command, timeout_ms,
-			     ctx->int_cond, ctx->int_type);
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
+				ctx->id, command, ctx->type, timeout_ms,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	} else if (-ERESTARTSYS == ret) {
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout interrupted by a signal %d %d",
-			     ctx->id, ctx->type, command, ctx->int_cond,
-			     ctx->int_type);
 		status = -1;
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
+				ctx->id, command, ctx->type,
+				ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	}
 
-	ctx->int_cond = 0;
-	ctx->int_type = 0;
+	ctx->int_cond[hw_id] = 0;
+	ctx->int_type[hw_id] = 0;
 
 	return status;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
index 638cd1f3526a..2bf4cabfaa43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
@@ -12,7 +12,7 @@
 struct mtk_vcodec_ctx;
 
 /* timeout is ms */
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *data, int command,
-				unsigned int timeout_ms);
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+				int command, unsigned int timeout_ms, unsigned int hw_id);
 
 #endif /* _MTK_VCODEC_INTR_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index 40d6e6c5ac7a..481655bb6016 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -413,7 +413,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		/* wait decoder done interrupt */
 		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 						   MTK_INST_IRQ_RECEIVED,
-						   WAIT_INTR_TIMEOUT_MS);
+						   WAIT_INTR_TIMEOUT_MS, 0);
 		if (err)
 			goto err_free_fb_out;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index fada4d146703..43542de11e9c 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -727,7 +727,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 	/* wait decoder done interrupt */
 	err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 					   MTK_INST_IRQ_RECEIVED,
-					   WAIT_INTR_TIMEOUT_MS);
+					   WAIT_INTR_TIMEOUT_MS, 0);
 	if (err)
 		goto err_free_fb_out;
 	vpu_dec_end(vpu);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index e5393f841080..88c046731754 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -488,7 +488,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	/* wait decoder done interrupt */
 	mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
-				     WAIT_INTR_TIMEOUT_MS);
+				     WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (inst->vsi->load_data)
 		load_dec_table(inst);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index 71cdc3ddafcb..70b8383f7c8e 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -539,7 +539,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
 
 	mtk_vcodec_wait_for_done_ctx(inst->ctx,
 			MTK_INST_IRQ_RECEIVED,
-			WAIT_INTR_TIMEOUT_MS);
+			WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
 		return true;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index bf03888a824f..4d9b8798dffe 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -335,7 +335,7 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
 	}
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 6b66957d5192..56ce58f761f1 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -222,7 +222,7 @@ static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "isr return %x", irq_status);
 	}
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:00:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:00:42 +0100
Subject: [PATCH v3 0/4] spi: dt-bindings: samsung: convert to dtschema
Message-ID: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v2
================
1. Patch 2: drop child device schema, as Rob suggested.

Changes since v1
================
1. Patch 2: describe devices matching compatible, correct issues pointed out by
   Rob, add reviewed-by tag.
2. New patches 3 and 4.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  ARM: dts: exynos: split dmas into array of phandles in Exynos5250
  spi: dt-bindings: samsung: convert to dtschema
  spi: dt-bindings: samsung: allow controller-data to be optional
  spi: s3c64xx: allow controller-data to be optional

 .../spi/samsung,spi-peripheral-props.yaml     |  36 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 arch/arm/boot/dts/exynos5250.dtsi             |   9 +-
 drivers/spi/spi-s3c64xx.c                     |  14 +-
 7 files changed, 234 insertions(+), 137 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:00:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:00:45 +0100
Subject: [PATCH v3 3/4] spi: dt-bindings: samsung: allow controller-data to be
 optional
In-Reply-To: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220112100046.68068-4-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI bindings requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/spi/samsung,spi-peripheral-props.yaml    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
index aa5a1f48494b..cadc8a5f061f 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -28,6 +28,7 @@ properties:
            - 3: 270 degree phase shift sampling.
         $ref: /schemas/types.yaml#/definitions/uint32
         enum: [0, 1, 2, 3]
+        default: 0
 
     required:
       - samsung,spi-feedback-delay
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:00:46 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:00:46 +0100
Subject: [PATCH v3 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220112100046.68068-5-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI driver requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/spi/spi-s3c64xx.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..769d958a2f86 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
 		return ERR_PTR(-EINVAL);
 	}
 
-	data_np = of_get_child_by_name(slave_np, "controller-data");
-	if (!data_np) {
-		dev_err(&spi->dev, "child node 'controller-data' not found\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		of_node_put(data_np);
+	if (!cs)
 		return ERR_PTR(-ENOMEM);
+
+	data_np = of_get_child_by_name(slave_np, "controller-data");
+	if (!data_np) {
+		dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");
+		return cs;
 	}
 
 	of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:00:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:00:43 +0100
Subject: [PATCH v3 1/4] ARM: dts: exynos: split dmas into array of phandles in
 Exynos5250
In-Reply-To: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220112100046.68068-2-krzysztof.kozlowski@canonical.com>

"dmas" property should be rather an array of phandles, as dtschema
points.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..102bb57bf704 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
 			status = "disabled";
 			reg = <0x12d20000 0x100>;
 			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 5
-				&pdma0 4>;
+			dmas = <&pdma0 5>, <&pdma0 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
 			status = "disabled";
 			reg = <0x12d30000 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma1 5
-				&pdma1 4>;
+			dmas = <&pdma1 5>, <&pdma1 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
 			status = "disabled";
 			reg = <0x12d40000 0x100>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 7
-				&pdma0 6>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:00:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:00:44 +0100
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 5 files changed, 224 insertions(+), 123 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..aa5a1f48494b
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  See spi-peripheral-props.yaml for more info.
+
+properties:
+  controller-data:
+    type: object
+    additionalProperties: false
+
+    properties:
+      samsung,spi-feedback-delay:
+        description: |
+          The sampling phase shift to be applied on the miso line (to account
+          for any lag in the miso line). Valid values:
+           - 0: No phase shift.
+           - 1: 90 degree phase shift sampling.
+           - 2: 180 degree phase shift sampling.
+           - 3: 270 degree phase shift sampling.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2, 3]
+
+    required:
+      - samsung,spi-feedback-delay
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..61c77088e8ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi # for S5PV210 and S5PC110
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..df885eeb144f 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -85,5 +85,6 @@ properties:
 # The controller specific properties go here.
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
+  - $ref: samsung,spi-peripheral-props.yaml#
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..1f951bc877f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17054,7 +17054,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From jagan at amarulasolutions.com  Wed Jan 12 02:01:21 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Wed, 12 Jan 2022 15:31:21 +0530
Subject: [PATCH v2 6/6] drm/stm: ltdc: Drop format_mod_supported function
In-Reply-To: <20211222090552.25972-7-jose.exposito89@gmail.com>
References: <20211222090552.25972-1-jose.exposito89@gmail.com>
 <20211222090552.25972-7-jose.exposito89@gmail.com>
Message-ID: <CAMty3ZD_R+Tzab-qcWEcbTKVCKq3pNTi7Mr7903Vu9a9M5EefQ@mail.gmail.com>

On Wed, Dec 22, 2021 at 2:36 PM Jos? Exp?sito <jose.exposito89 at gmail.com> wrote:
>
> The "drm_plane_funcs.format_mod_supported" can be removed in favor of
> the default implementation.
>
> Signed-off-by: Jos? Exp?sito <jose.exposito89 at gmail.com>
> ---

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
Tested-by: Jagan Teki <jagan at amarulasolutions.com> # i.Core STM32MP1


From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:11:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:11:07 +0100
Subject: [PATCH v2 1/6] dt-bindings: memory: mtk-smi: Fix larb-id
 dtbs_check warning
In-Reply-To: <20220111063904.7583-2-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-2-yong.wu@mediatek.com>
Message-ID: <82e235d9-4e57-a4e4-66af-84277f9b9da6@canonical.com>

On 11/01/2022 07:38, Yong Wu wrote:
> Mute the warning from "make dtbs_check":
> 
> larb at 14016000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
> larb at 15001000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
> larb at 16010000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml

Please explain why larb-id is not necessary on mediatek,mt8167-smi-larb.
IOW, what logical error was there (except the dtschema pointed out issue).

> 
> Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  .../bindings/memory-controllers/mediatek,smi-larb.yaml           | 1 -
>  1 file changed, 1 deletion(-)
> 


Best regards,
Krzysztof


From mhocko at suse.com  Wed Jan 12 02:17:53 2022
From: mhocko at suse.com (Michal Hocko)
Date: Wed, 12 Jan 2022 11:17:53 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd4oaUwHkpadAKwe@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz> <Yd4oaUwHkpadAKwe@google.com>
Message-ID: <Yd6q0QdLVTS53vu4@dhcp22.suse.cz>

On Tue 11-01-22 18:01:29, Yu Zhao wrote:
> On Mon, Jan 10, 2022 at 05:57:39PM +0100, Michal Hocko wrote:
> > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > [...]
> > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > +{
> > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > +		.test_walk = should_skip_vma,
> > > +		.p4d_entry = walk_pud_range,
> > > +	};
> > > +
> > > +	int err;
> > > +#ifdef CONFIG_MEMCG
> > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > +#endif
> > > +
> > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > +
> > > +	do {
> > > +		unsigned long start = walk->next_addr;
> > > +		unsigned long end = mm->highest_vm_end;
> > > +
> > > +		err = -EBUSY;
> > > +
> > > +		rcu_read_lock();
> > > +#ifdef CONFIG_MEMCG
> > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > +			goto contended;
> > > +#endif
> > 
> > Why do you need to check for moving_account?
> 
> This check, if succeeds, blocks memcg migration.

OK, I can see that you rely on the RCU here for the synchronization. A
comment which mentions mem_cgroup_move_charge would be helpful for
clarity. Is there any reason you are not using folio_memcg_lock in the
pte walk instead?
-- 
Michal Hocko
SUSE Labs


From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:18:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:18:04 +0100
Subject: [PATCH v2 2/6] dt-bindings: memory: mtk-smi: Fix the larb
 clock/clock-names dtbs warning
In-Reply-To: <20220111063904.7583-3-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-3-yong.wu@mediatek.com>
Message-ID: <b8b8fe77-2ea8-d05c-5fa2-d4cae01baba5@canonical.com>

On 11/01/2022 07:39, Yong Wu wrote:
> Mute the warning from "make dtbs_check":
> 
> larb at 14017000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 	...
> 
> larb at 16010000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 
> larb at 17010000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 
> If a platform's larb supports gals, there will be some larbs have one
> more "gals" clock while the others still only need "apb"/"smi" clocks,
> then the minItems for clock and clock-names are 2.
> 
> Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  .../bindings/memory-controllers/mediatek,smi-larb.yaml      | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
> index 80907e357892..884c0c74e5e4 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
> @@ -80,10 +80,10 @@ allOf:
>      then:
>        properties:
>          clock:

Separate patch:
This should be clocks. The same in second if. Now it is simply not
working...

> -          items:

Putting min/maxItems under items is wrong. The second if also needs the
fixing. Please make it a separate patch before this one.

The schema was clearly not tested before...


> -            minItems: 3
> -            maxItems: 3
> +          minItems: 2
> +          maxItems: 3
>          clock-names:
> +          minItems: 2
>            items:
>              - const: apb
>              - const: smi
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:20:11 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:20:11 +0100
Subject: [PATCH v2 4/6] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <20220111063904.7583-5-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-5-yong.wu@mediatek.com>
Message-ID: <a3c48c27-515d-f741-e447-98e0ddfe3b01@canonical.com>

On 11/01/2022 07:39, Yong Wu wrote:
> The successful return value for clk_bulk_prepare_enable is 0, rather than
> "< 0". Fix this.

I do not understand. The commit description does not match the code.
What is the error here?

> 
> Fixes: 0e14917c57f9 ("memory: mtk-smi: Use clk_bulk clock ops")

There is no bug to fix...

> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  drivers/memory/mtk-smi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> index b883dcc0bbfa..e7b1a22b12ea 100644
> --- a/drivers/memory/mtk-smi.c
> +++ b/drivers/memory/mtk-smi.c
> @@ -480,7 +480,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
>  	int ret;
>  
>  	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
> -	if (ret < 0)
> +	if (ret)
>  		return ret;
>  
>  	/* Configure the basic setting for this larb */
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Jan 12 02:27:59 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 12 Jan 2022 11:27:59 +0100
Subject: [PATCH v2 5/6] memory: mtk-smi: Add sleep ctrl function
In-Reply-To: <20220111063904.7583-6-yong.wu@mediatek.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-6-yong.wu@mediatek.com>
Message-ID: <22935ffa-469c-a609-c30b-919ba85b842c@canonical.com>

On 11/01/2022 07:39, Yong Wu wrote:
> Sleep control means that when the larb goes to sleep, we should wait a bit
> until all the current commands are finished. Thus, when the larb runtime
> suspends, we need to enable this function to wait until all the existed
> commands are finished. When the larb resumes, just disable this function.
> This function only improves the safety of bus. Add a new flag for this
> function. Prepare for mt8186.
> 
> Signed-off-by: Anan Sun <anan.sun at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  drivers/memory/mtk-smi.c | 35 ++++++++++++++++++++++++++++++++++-
>  1 file changed, 34 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> index e7b1a22b12ea..d8552f4caba4 100644
> --- a/drivers/memory/mtk-smi.c
> +++ b/drivers/memory/mtk-smi.c
> @@ -8,6 +8,7 @@
>  #include <linux/device.h>
>  #include <linux/err.h>
>  #include <linux/io.h>
> +#include <linux/iopoll.h>
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/of_platform.h>
> @@ -32,6 +33,10 @@
>  #define SMI_DUMMY			0x444
>  
>  /* SMI LARB */
> +#define SMI_LARB_SLP_CON                0xc
> +#define SLP_PROT_EN                     BIT(0)
> +#define SLP_PROT_RDY                    BIT(16)
> +
>  #define SMI_LARB_CMD_THRT_CON		0x24
>  #define SMI_LARB_THRT_RD_NU_LMT_MSK	GENMASK(7, 4)
>  #define SMI_LARB_THRT_RD_NU_LMT		(5 << 4)
> @@ -81,6 +86,7 @@
>  
>  #define MTK_SMI_FLAG_THRT_UPDATE	BIT(0)
>  #define MTK_SMI_FLAG_SW_FLAG		BIT(1)
> +#define MTK_SMI_FLAG_SLEEP_CTL		BIT(2)
>  #define MTK_SMI_CAPS(flags, _x)		(!!((flags) & (_x)))
>  
>  struct mtk_smi_reg_pair {
> @@ -371,6 +377,26 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
>  	{}
>  };
>  
> +static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
> +{
> +	int ret;
> +	u32 tmp;
> +
> +	writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON);
> +	ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON,
> +					tmp, !!(tmp & SLP_PROT_RDY), 10, 1000);
> +	if (ret) {
> +		/* TODO: Reset this larb if it fails here. */
> +		dev_warn(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp);
> +	}
> +	return ret;
> +}
> +
> +static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb)
> +{
> +	writel_relaxed(0, larb->base + SMI_LARB_SLP_CON);
> +}
> +
>  static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
>  {
>  	struct platform_device *smi_com_pdev;
> @@ -483,6 +509,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
>  	if (ret)
>  		return ret;
>  
> +	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
> +		mtk_smi_larb_sleep_ctrl_disable(larb);
> +
>  	/* Configure the basic setting for this larb */
>  	larb_gen->config_port(dev);
>  
> @@ -492,9 +521,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
>  static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
>  {
>  	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
> +	int ret = 0;
> +
> +	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
> +		ret = mtk_smi_larb_sleep_ctrl_enable(larb);
>  
>  	clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
> -	return 0;
> +	return ret;

I am wondering whether disabling clocks in error case is a proper step.
On suspend error, the PM core won't run any further callbacks on this
device. This means, it won't be resumed and your clocks stay disabled. I
think you should return early and leave the device in active state in
case of error.


Best regards,
Krzysztof


From mhocko at suse.com  Wed Jan 12 02:28:57 2022
From: mhocko at suse.com (Michal Hocko)
Date: Wed, 12 Jan 2022 11:28:57 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd4P6bEJI8YlXq0H@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <YdxKORU9OWCv114O@dhcp22.suse.cz>
 <Yd4P6bEJI8YlXq0H@google.com>
Message-ID: <Yd6tafG3CS7BoRYn@dhcp22.suse.cz>

On Tue 11-01-22 16:16:57, Yu Zhao wrote:
> On Mon, Jan 10, 2022 at 04:01:13PM +0100, Michal Hocko wrote:
> > On Thu 06-01-22 17:12:18, Michal Hocko wrote:
> > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > > > +{
> > > > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > > > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> > 
> > One thing I have overlooked completely.
> 
> I appreciate your attention to details but GFP_KERNEL is legit in the
> reclaim path. It's been used many years in our production, e.g.,
>   page reclaim
>     swap_writepage()
>       frontswap_store()
>         zswap_frontswap_store()
>           zswap_entry_cache_alloc(GFP_KERNEL)
> 
> (And I always test my changes with lockdep, kasan, DEBUG_VM, etc., no
>  warnings ever seen from using GFP_KERNEL in the reclaim path.)

OK, I can see it now. __need_reclaim will check for PF_MEMALLOC and skip
the fs_reclaim tracking.

I still maintain I am not really happy about (nor in the zswap example)
allocations from the direct reclaim context. I would really recommend
using a pre-allocated pool of objects.

If there are strong reasons for not doing so then at lease change that
to kzalloc.

Thanks!
-- 
Michal Hocko
SUSE Labs


From mhocko at suse.com  Wed Jan 12 02:31:57 2022
From: mhocko at suse.com (Michal Hocko)
Date: Wed, 12 Jan 2022 11:31:57 +0100
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <Yd6S6Js1W4AnFFmv@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <YdwKB3SfF7hkB9Xv@kernel.org> <Yd6S6Js1W4AnFFmv@google.com>
Message-ID: <Yd6uHYtjGfgqjDpw@dhcp22.suse.cz>

On Wed 12-01-22 01:35:52, Yu Zhao wrote:
[...]
> But I saw people not following this practice, and I'm also tempted to
> do so. Can anybody remind me whether it's considered a bad practice to
> have code changes and Kconfig changes in the same patch?

If you want to have the patch series bisectable then it is preferable to
add kconfig options early so that the code is enabled in the respective
steps. Sometimes that can be impractical though (e.g. when the feature is
incomplete at that stage).
-- 
Michal Hocko
SUSE Labs


From mark.rutland at arm.com  Wed Jan 12 02:32:44 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 10:32:44 +0000
Subject: [PATCH 2/2] arm64: errata: Update
 ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges
In-Reply-To: <1641980099-20315-3-git-send-email-anshuman.khandual@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Yd6uTCwjzDdBrtGI@FVFF77S0Q05N>

Hi Anshuman,

On Wed, Jan 12, 2022 at 03:04:59PM +0530, Anshuman Khandual wrote:
> Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
> well. Lets update these errata definition and detection to accommodate all
> new Cortex-X2 based cpu MIDR ranges.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/Kconfig             | 12 ++++++------
>  arch/arm64/kernel/cpu_errata.c |  2 ++
>  2 files changed, 8 insertions(+), 6 deletions(-)

I think you've misssed Documentation/arm64/silicon-errata.rst -- for other
common errata we add lines for each affected part, e.g. as we do for
ARM64_ERRATUM_1418040.

Other than that, this looks good to me!

Thanks,
Mark.

> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index c4207cf9bb17..d8046c832225 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -671,14 +671,14 @@ config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  	bool
>  
>  config ARM64_ERRATUM_2119858
> -	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
> +	bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
>  	default y
>  	depends on CORESIGHT_TRBE
>  	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  	help
> -	  This option adds the workaround for ARM Cortex-A710 erratum 2119858.
> +	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858.
>  
> -	  Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace
> +	  Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace
>  	  data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in
>  	  the event of a WRAP event.
>  
> @@ -761,14 +761,14 @@ config ARM64_ERRATUM_2253138
>  	  If unsure, say Y.
>  
>  config ARM64_ERRATUM_2224489
> -	bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
> +	bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range"
>  	depends on CORESIGHT_TRBE
>  	default y
>  	select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>  	help
> -	  This option adds the workaround for ARM Cortex-A710 erratum 2224489.
> +	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489.
>  
> -	  Affected Cortex-A710 cores might write to an out-of-range address, not reserved
> +	  Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved
>  	  for TRBE. Under some conditions, the TRBE might generate a write to the next
>  	  virtually addressed page following the last page of the TRBE address space
>  	  (i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..29cc062a4153 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -347,6 +347,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2119858
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
>  #endif
>  	{},
>  };
> @@ -371,6 +372,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
>  #endif
>  #ifdef CONFIG_ARM64_ERRATUM_2224489
>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
> +	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
>  #endif
>  	{},
>  };
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From leilk.liu at mediatek.com  Wed Jan 12 02:36:06 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 12 Jan 2022 18:36:06 +0800
Subject: [PATCH V2 0/3] Add compatible for Mediatek MT8186
Message-ID: <20220112103609.17421-1-leilk.liu@mediatek.com>

Subject: [PATCH V2 0/3] Add compatible for Mediatek MT8186

v2:
1. Fix Rob review comment.
2. split spi-mt65xx & spi-slave-mt27xx to 2 patches.

Leilk Liu (3):
  dt-bindings: spi: Convert spi-slave-mt27xx to json-schema
  dt-bindings: spi: Convert spi-mt65xx to json-schema
  dt-bindings: spi: Add compatible for Mediatek MT8186

 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 100 ++++++++++++++++++
 .../spi/mediatek,spi-slave-mt27xx.yaml        |  73 +++++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    |  68 ------------
 .../bindings/spi/spi-slave-mt27xx.txt         |  33 ------
 4 files changed, 173 insertions(+), 101 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

--
2.25.1





From leilk.liu at mediatek.com  Wed Jan 12 02:36:07 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 12 Jan 2022 18:36:07 +0800
Subject: [PATCH V2 1/3] dt-bindings: spi: Convert spi-slave-mt27xx to
 json-schema
In-Reply-To: <20220112103609.17421-1-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
Message-ID: <20220112103609.17421-2-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Slave controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../spi/mediatek,spi-slave-mt27xx.yaml        | 73 +++++++++++++++++++
 .../bindings/spi/spi-slave-mt27xx.txt         | 33 ---------
 2 files changed, 73 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
new file mode 100644
index 000000000000..3364fff08cca
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Slave controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: /spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt2712-spi-slave
+      - items:
+          - enum:
+              - mediatek,mt8195-spi-slave
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: spi
+
+  assigned-clocks:
+    maxItems: 1
+    description: |
+      The mux clock for the given platform.
+
+  assigned-clock-parents:
+    maxItems: 1
+    description: |
+      The parent of mux clock for the given platform.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2712-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 10013000 {
+      compatible = "mediatek,mt2712-spi-slave";
+      reg = <0x10013000 0x100>;
+      interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&infracfg CLK_INFRA_AO_SPI1>;
+      clock-names = "spi";
+      assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt b/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
deleted file mode 100644
index 9192724540fd..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Binding for MTK SPI Slave controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2712-spi-slave: for mt2712 platforms
-    - mediatek,mt8195-spi-slave: for mt8195 platforms
-- reg: Address and length of the register set for the device.
-- interrupts: Should contain spi interrupt.
-- clocks: phandles to input clocks.
-  It's clock gate, and should be <&infracfg CLK_INFRA_AO_SPI1>.
-- clock-names: should be "spi" for the clock gate.
-
-Optional properties:
-- assigned-clocks: it's mux clock, should be <&topckgen CLK_TOP_SPISLV_SEL>.
-- assigned-clock-parents: parent of mux clock.
-  It's PLL, and should be one of the following.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D2>: specify parent clock 312MHZ.
-				       It's the default one.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D4>: specify parent clock 156MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-
-Example:
-- SoC Specific Portion:
-spis1: spi at 10013000 {
-	compatible = "mediatek,mt2712-spi-slave";
-	reg = <0 0x10013000 0 0x100>;
-	interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&infracfg CLK_INFRA_AO_SPI1>;
-	clock-names = "spi";
-	assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
-	assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
-};
-- 
2.25.1



From leilk.liu at mediatek.com  Wed Jan 12 02:36:08 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 12 Jan 2022 18:36:08 +0800
Subject: [PATCH V2 2/3] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <20220112103609.17421-1-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
Message-ID: <20220112103609.17421-3-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Master controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 99 +++++++++++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
 2 files changed, 99 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
new file mode 100644
index 000000000000..71f0cf6e5d70
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Bus controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: /spi/spi-controller.yaml#
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt7629-spi
+          - const: mediatek,mt7622-spi
+      - items:
+          - enum:
+              - mediatek,mt8516-spi
+          - const: mediatek,mt2712-spi
+      - items:
+          - enum:
+              - mediatek,mt6779-spi
+              - mediatek,mt8192-spi
+              - mediatek,mt8195-spi
+          - const: mediatek,mt6765-spi
+      - const: mediatek,mt2701-spi
+      - const: mediatek,mt2712-spi
+      - const: mediatek,mt6589-spi
+      - const: mediatek,mt6765-spi
+      - const: mediatek,mt6893-spi
+      - const: mediatek,mt7622-spi
+      - const: mediatek,mt8135-spi
+      - const: mediatek,mt8173-spi
+      - const: mediatek,mt8183-spi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the parent clock
+      - description: clock used for the muxes clock
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: parent-clk
+      - const: sel-clk
+      - const: spi-clk
+
+  mediatek,pad-select:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    maxItems: 4
+    items:
+      enum: [0, 1, 2, 3]
+    description:
+      specify which pins group(ck/mi/mo/cs) spi controller used.
+      This is an array.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 1100a000 {
+      compatible = "mediatek,mt8173-spi";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      reg = <0x1100a000 0x1000>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+               <&topckgen CLK_TOP_SPI_SEL>,
+               <&pericfg CLK_PERI_SPI0>;
+      clock-names = "parent-clk", "sel-clk", "spi-clk";
+      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
+      mediatek,pad-select = <1>, <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
deleted file mode 100644
index 2a24969159cc..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Binding for MTK SPI controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2701-spi: for mt2701 platforms
-    - mediatek,mt2712-spi: for mt2712 platforms
-    - mediatek,mt6589-spi: for mt6589 platforms
-    - mediatek,mt6765-spi: for mt6765 platforms
-    - mediatek,mt7622-spi: for mt7622 platforms
-    - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
-    - mediatek,mt8135-spi: for mt8135 platforms
-    - mediatek,mt8173-spi: for mt8173 platforms
-    - mediatek,mt8183-spi: for mt8183 platforms
-    - mediatek,mt6893-spi: for mt6893 platforms
-    - "mediatek,mt8192-spi", "mediatek,mt6765-spi": for mt8192 platforms
-    - "mediatek,mt8195-spi", "mediatek,mt6765-spi": for mt8195 platforms
-    - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
-    - "mediatek,mt6779-spi", "mediatek,mt6765-spi": for mt6779 platforms
-
-- #address-cells: should be 1.
-
-- #size-cells: should be 0.
-
-- reg: Address and length of the register set for the device
-
-- interrupts: Should contain spi interrupt
-
-- clocks: phandles to input clocks.
-  The first should be one of the following. It's PLL.
-   -  <&clk26m>: specify parent clock 26MHZ.
-   -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
-				      It's the default one.
-   -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
-  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
-
-- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
-  muxes clock, and "spi-clk" for the clock gate.
-
-Optional properties:
--cs-gpios: see spi-bus.txt.
-
-- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
-  controller used. This is an array, the element value should be 0~3,
-  only required for MT8173.
-    0: specify GPIO69,70,71,72 for spi pins.
-    1: specify GPIO102,103,104,105 for spi pins.
-    2: specify GPIO128,129,130,131 for spi pins.
-    3: specify GPIO5,6,7,8 for spi pins.
-
-Example:
-
-- SoC Specific Portion:
-spi: spi at 1100a000 {
-	compatible = "mediatek,mt8173-spi";
-	#address-cells = <1>;
-	#size-cells = <0>;
-	reg = <0 0x1100a000 0 0x1000>;
-	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
-		 <&topckgen CLK_TOP_SPI_SEL>,
-		 <&pericfg CLK_PERI_SPI0>;
-	clock-names = "parent-clk", "sel-clk", "spi-clk";
-	cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
-	mediatek,pad-select = <1>, <0>;
-};
-- 
2.25.1



From leilk.liu at mediatek.com  Wed Jan 12 02:36:09 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Wed, 12 Jan 2022 18:36:09 +0800
Subject: [PATCH V2 3/3] dt-bindings: spi: Add compatible for Mediatek MT8186
In-Reply-To: <20220112103609.17421-1-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
Message-ID: <20220112103609.17421-4-leilk.liu@mediatek.com>

This commit adds dt-binding documentation of spi bus for Mediatek MT8186 SoC
Platform.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
index 71f0cf6e5d70..9a6fb8ecb752 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -26,6 +26,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt6779-spi
+              - mediatek,mt8186-spi
               - mediatek,mt8192-spi
               - mediatek,mt8195-spi
           - const: mediatek,mt6765-spi
-- 
2.25.1



From ulf.hansson at linaro.org  Wed Jan 12 02:37:44 2022
From: ulf.hansson at linaro.org (Ulf Hansson)
Date: Wed, 12 Jan 2022 11:37:44 +0100
Subject: [PATCH v2] mmc: sunxi-mmc: check ocr_avail on resource request
In-Reply-To: <20220112093415.wdy3ht5yizw5lffl@houat>
References: <20220104060325.3957-1-michael@allwinnertech.com>
 <20220112093415.wdy3ht5yizw5lffl@houat>
Message-ID: <CAPDyKFrD_c36Di66_TCJP3hFFwGHmAgH-DQAPLkJLx-m57VQvw@mail.gmail.com>

On Wed, 12 Jan 2022 at 10:34, Maxime Ripard <maxime at cerno.tech> wrote:
>
> Hi,
>
> On Tue, Jan 04, 2022 at 02:03:25PM +0800, Michael Wu wrote:
> > Some platforms have no regulator, discrete power devices are used instead.
>
> Is it really the case? vmmc at least should be mandatory so a platform
> not having a regulator would violate the binding itself.
>
> > However, sunxi_mmc_probe does not catch this exception when regulator is
> > absent in DTS. This leads to sd or eMMC init failure.
>
> This will still happen with your patch though?
>
> > To solve this, a fixed vmmc regulator must be hooked up in DTS, like this:
> > reg_dummy_vmmc: dummy_vmmc {
> >       compatible = "regulator-fixed";
> >       regulator-name = "dummy-vmmc";
> >       regulator-min-microvolt = <3300000>;
> >       regulator-max-microvolt = <3300000>;
> > };
> >
> > mmc0:mmc at 4020000 {
> >       compatible = "allwinner,sun50i-a100-emmc";
> >       device_type = "mmc0";
> >       vmmc-supply = <&reg_dummy_vmmc>;
> > }
> >
> > In this patch, we print an error message and abort the probe process if
> > the regulator is not specified in DTS.
>
> I'm fine with the patch itself, but it's really not clear to me what
> situation is being fixed or improved here.
>
> You're first mentioning that this is fixing the driver probing even if a
> regulator is absent, but then states (rightfully) that in such a case we
> should use a fixed regulator. So we should always have a regulator then?
>
> I assume that you want the driver to properly error out instead of going
> on if either a regulator is missing or if its voltages are out of range?
>
> If the former, then we should probably check if host->mmc->supply.vmmc
> returned an error. If the latter, then yes, checking ocr_avail is
> probably fine but we should make it clearer in the error message that
> it's what it's about.

Just wanted to mention that I just had a very similar discussion
around another patch [1]. Please have a look at that discussion to get
my opinion on this.

Kind regards
Uffe

[1]
https://patchwork.kernel.org/project/linux-mmc/patch/20211215130711.111186-4-gsomlo at gmail.com/


From arnd at arndb.de  Wed Jan 12 02:50:54 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 12 Jan 2022 11:50:54 +0100
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
Message-ID: <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>

On Wed, Jan 12, 2022 at 10:34 AM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
> Add the CPU Partnumbers for the new Arm designs.
>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/include/asm/cputype.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
> index 19b8441aa8f2..657eeb06c784 100644
> --- a/arch/arm64/include/asm/cputype.h
> +++ b/arch/arm64/include/asm/cputype.h
> @@ -74,6 +74,7 @@
>  #define ARM_CPU_PART_NEOVERSE_N1       0xD0C
>  #define ARM_CPU_PART_CORTEX_A77                0xD0D
>  #define ARM_CPU_PART_CORTEX_A710       0xD47
> +#define ARM_CPU_PART_CORTEX_X2         0xD48
>  #define ARM_CPU_PART_NEOVERSE_N2       0xD49

No objections to the patch, but would it be possible to just add all the missing
ones here to the degree that they are known already? I don't see any entries for
Cortex-A34, Cortex-A65AE, Cortex-A78, Cortex-A78C, Cortex-A78AE,
Neoverse-E1, Neoverse-V1, Cortex-X1, Cortex-X2, Cortex-A510, Cortex-A710
and Cortex-R82 among the Arm-designed cores that can run Linux, and there
are probably others that I missed going through the list.

        Arnd


From anshuman.khandual at arm.com  Wed Jan 12 03:06:07 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 12 Jan 2022 16:36:07 +0530
Subject: [PATCH 2/2] arm64: errata: Update ARM64_ERRATUM_[2119858|2224489]
 with Cortex-X2 ranges
In-Reply-To: <Yd6uTCwjzDdBrtGI@FVFF77S0Q05N>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-3-git-send-email-anshuman.khandual@arm.com>
 <Yd6uTCwjzDdBrtGI@FVFF77S0Q05N>
Message-ID: <73b5cc05-4318-8eb8-bc3a-84af1ad6145c@arm.com>



On 1/12/22 4:02 PM, Mark Rutland wrote:
> Hi Anshuman,
> 
> On Wed, Jan 12, 2022 at 03:04:59PM +0530, Anshuman Khandual wrote:
>> Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
>> well. Lets update these errata definition and detection to accommodate all
>> new Cortex-X2 based cpu MIDR ranges.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/Kconfig             | 12 ++++++------
>>  arch/arm64/kernel/cpu_errata.c |  2 ++
>>  2 files changed, 8 insertions(+), 6 deletions(-)
> 
> I think you've misssed Documentation/arm64/silicon-errata.rst -- for other
> common errata we add lines for each affected part, e.g. as we do for
> ARM64_ERRATUM_1418040.

Sure, will do. I guess Cortex-X2 lines will come just after Cortex-A710
but before Neoverse-N1.

+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Cortex-A710     | #2224489        | ARM64_ERRATUM_2224489       |
+----------------+-----------------+-----------------+-----------------------------+
>
>
+----------------+-----------------+-----------------+-----------------------------+
| ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
+----------------+-----------------+-----------------+-----------------------------+


> 
> Other than that, this looks good to me!
> 
> Thanks,
> Mark.
> 
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index c4207cf9bb17..d8046c832225 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -671,14 +671,14 @@ config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>>  	bool
>>  
>>  config ARM64_ERRATUM_2119858
>> -	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
>> +	bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
>>  	default y
>>  	depends on CORESIGHT_TRBE
>>  	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>>  	help
>> -	  This option adds the workaround for ARM Cortex-A710 erratum 2119858.
>> +	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858.
>>  
>> -	  Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace
>> +	  Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace
>>  	  data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in
>>  	  the event of a WRAP event.
>>  
>> @@ -761,14 +761,14 @@ config ARM64_ERRATUM_2253138
>>  	  If unsure, say Y.
>>  
>>  config ARM64_ERRATUM_2224489
>> -	bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
>> +	bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range"
>>  	depends on CORESIGHT_TRBE
>>  	default y
>>  	select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
>>  	help
>> -	  This option adds the workaround for ARM Cortex-A710 erratum 2224489.
>> +	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489.
>>  
>> -	  Affected Cortex-A710 cores might write to an out-of-range address, not reserved
>> +	  Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved
>>  	  for TRBE. Under some conditions, the TRBE might generate a write to the next
>>  	  virtually addressed page following the last page of the TRBE address space
>>  	  (i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
>> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
>> index 9e1c1aef9ebd..29cc062a4153 100644
>> --- a/arch/arm64/kernel/cpu_errata.c
>> +++ b/arch/arm64/kernel/cpu_errata.c
>> @@ -347,6 +347,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
>>  #endif
>>  #ifdef CONFIG_ARM64_ERRATUM_2119858
>>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
>> +	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
>>  #endif
>>  	{},
>>  };
>> @@ -371,6 +372,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
>>  #endif
>>  #ifdef CONFIG_ARM64_ERRATUM_2224489
>>  	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
>> +	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
>>  #endif
>>  	{},
>>  };
>> -- 
>> 2.20.1
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From jlayton at kernel.org  Wed Jan 12 03:15:33 2022
From: jlayton at kernel.org (Jeff Layton)
Date: Wed, 12 Jan 2022 06:15:33 -0500
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64
 in fcntl.h
In-Reply-To: <CAK8P3a1ONn=FiPU3669MjBMntS-1K5bgX4pHforUsYJ7yhwZ-g@mail.gmail.com>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
 <20220112075609.GA4854@lst.de>
 <CAK8P3a1ONn=FiPU3669MjBMntS-1K5bgX4pHforUsYJ7yhwZ-g@mail.gmail.com>
Message-ID: <f86483fca8b0dc68ce243ba47998ff3296a3b6f8.camel@kernel.org>

On Wed, 2022-01-12 at 09:28 +0100, Arnd Bergmann wrote:
> On Wed, Jan 12, 2022 at 8:56 AM Christoph Hellwig <hch at lst.de> wrote:
> > 
> > On Tue, Jan 11, 2022 at 04:33:30PM +0100, Arnd Bergmann wrote:
> > > This is a very subtle change to the exported UAPI header contents:
> > > On 64-bit architectures, the three unusable numbers are now always
> > > shown, rather than depending on a user-controlled symbol.
> > 
> > Well, the change is bigger and less subtle.  Before this change the
> > constants were never visible to userspace at all (except on mips),
> > because the #ifdef CONFIG_64BIT it never set for userspace builds.
> 
> I suppose you mean /always/ visible here, with that ifndef.
> 
> > > This is probably what we want here for compatibility reasons, but I think
> > > it should be explained in the changelog text, and I'd like Jeff or Bruce
> > > to comment on it as well: the alternative here would be to make the
> > > uapi definition depend on __BITS_PER_LONG==32, which is
> > > technically the right thing to do but more a of a change.
> > 
> > I can change this to #if __BITS_PER_LONG==32 || defined(__KERNEL__),
> > but it will still be change in what userspace sees.
> 
> Exactly, that is the tradeoff, which is why I'd like the flock maintainers
> to say which way they prefer. We can either do it more correctly (hiding
> the constants from user space when they are not usable), or with less
> change (removing the incorrect #ifdef). Either way sounds reasonable
> to me, I mainly care that this is explained in the changelog and that the
> maintainers are aware of the two options.
> 

I don't have a strong opinion here. If we were taking symbols away that
were previously visible to userland it would be one thing, but since
we're just adding symbols that may not have been there before, this
seems less likely to break anything.

I probably lean toward Christoph's original solution instead of keeping
the conditional definitions. It's hard to imagine there are many
programs that care whether these other symbols are defined or not.

You can add this to the original patch:

Acked-by: Jeff Layton <jlayton at kernel.org>



From mark.rutland at arm.com  Wed Jan 12 03:26:03 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 11:26:03 +0000
Subject: [PATCH 2/2] arm64: errata: Update
 ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges
In-Reply-To: <73b5cc05-4318-8eb8-bc3a-84af1ad6145c@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-3-git-send-email-anshuman.khandual@arm.com>
 <Yd6uTCwjzDdBrtGI@FVFF77S0Q05N>
 <73b5cc05-4318-8eb8-bc3a-84af1ad6145c@arm.com>
Message-ID: <Yd66y1OvDmkFT5wJ@FVFF77S0Q05N>

On Wed, Jan 12, 2022 at 04:36:07PM +0530, Anshuman Khandual wrote:
> 
> 
> On 1/12/22 4:02 PM, Mark Rutland wrote:
> > Hi Anshuman,
> > 
> > On Wed, Jan 12, 2022 at 03:04:59PM +0530, Anshuman Khandual wrote:
> >> Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
> >> well. Lets update these errata definition and detection to accommodate all
> >> new Cortex-X2 based cpu MIDR ranges.
> >>
> >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >> Cc: Will Deacon <will at kernel.org>
> >> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> >> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> >> Cc: coresight at lists.linaro.org
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Cc: linux-kernel at vger.kernel.org
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >>  arch/arm64/Kconfig             | 12 ++++++------
> >>  arch/arm64/kernel/cpu_errata.c |  2 ++
> >>  2 files changed, 8 insertions(+), 6 deletions(-)
> > 
> > I think you've misssed Documentation/arm64/silicon-errata.rst -- for other
> > common errata we add lines for each affected part, e.g. as we do for
> > ARM64_ERRATUM_1418040.
> 
> Sure, will do. I guess Cortex-X2 lines will come just after Cortex-A710
> but before Neoverse-N1.
> 
> +----------------+-----------------+-----------------+-----------------------------+
> | ARM            | Cortex-A710     | #2224489        | ARM64_ERRATUM_2224489       |
> +----------------+-----------------+-----------------+-----------------------------+
> >
> >
> +----------------+-----------------+-----------------+-----------------------------+
> | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
> +----------------+-----------------+-----------------+-----------------------------+

That sounds right to me, yes.

Thanks,
Mark.


From sebastian.reichel at collabora.com  Wed Jan 12 03:29:05 2022
From: sebastian.reichel at collabora.com (Sebastian Reichel)
Date: Wed, 12 Jan 2022 12:29:05 +0100
Subject: [PATCH v2 2/4] dt-bindings: power: supply: maxim,max14577:
 convert to dtschema
In-Reply-To: <20220111174337.223320-3-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
 <20220111174337.223320-3-krzysztof.kozlowski@canonical.com>
Message-ID: <20220112112905.n6zb36kwop2kfm2n@earth.universe>

Hi,

On Tue, Jan 11, 2022 at 06:43:35PM +0100, Krzysztof Kozlowski wrote:
> Convert the Charger bindings of Maxim MAX14577/MAX77836 MUIC to DT
> schema format.  The existing bindings were defined in
> ../bindings/mfd/max14577.txt.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---

I expect this to be merged through MFD:

Acked-by: Sebastian Reichel <sebastian.reichel at collabora.com>

-- Sebastian

>  .../bindings/power/supply/maxim,max14577.yaml | 84 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
> 
> diff --git a/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
> new file mode 100644
> index 000000000000..3978b48299de
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
> @@ -0,0 +1,84 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/power/supply/maxim,max14577.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Maxim MAX14577/MAX77836 MicroUSB and Companion Power Management IC Charger
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description: |
> +  This is a part of device tree bindings for Maxim MAX14577/MAX77836 MicroUSB
> +  Integrated Circuit (MUIC).
> +
> +  See also Documentation/devicetree/bindings/mfd/maxim,max14577.yaml for
> +  additional information and example.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - maxim,max14577-charger
> +      - maxim,max77836-charger
> +
> +  maxim,constant-uvolt:
> +    description:
> +      Battery Constant Voltage in uV
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    minimum: 4000000
> +    maximum: 4350000
> +
> +  maxim,eoc-uamp:
> +    description: |
> +      Current in uA for End-Of-Charge mode.
> +      MAX14577: 50000-20000
> +      MAX77836: 5000-100000
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  maxim,fast-charge-uamp:
> +    description: |
> +      Current in uA for Fast Charge
> +      MAX14577: 90000-950000
> +      MAX77836: 45000-475000
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +
> +  maxim,ovp-uvolt:
> +    description:
> +      OverVoltage Protection Threshold in uV; In an overvoltage condition, INT
> +      asserts and charging stops.
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [6000000, 6500000, 7000000, 7500000]
> +
> +required:
> +  - compatible
> +  - maxim,constant-uvolt
> +  - maxim,eoc-uamp
> +  - maxim,fast-charge-uamp
> +  - maxim,ovp-uvolt
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: maxim,max14577-charger
> +    then:
> +      properties:
> +        maxim,eoc-uamp:
> +          minimum: 50000
> +          maximum: 200000
> +        maxim,fast-charge-uamp:
> +          minimum: 90000
> +          maximum: 950000
> +    else:
> +      # max77836
> +      properties:
> +        maxim,eoc-uamp:
> +          minimum: 5000
> +          maximum: 100000
> +        maxim,fast-charge-uamp:
> +          minimum: 45000
> +          maximum: 475000
> +
> +additionalProperties: false
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d1f8f312f322..13e21c229c5d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11681,6 +11681,7 @@ M:	Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>  M:	Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
>  L:	linux-pm at vger.kernel.org
>  S:	Supported
> +F:	Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml
>  F:	Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml
>  F:	drivers/power/supply/max14577_charger.c
>  F:	drivers/power/supply/max77693_charger.c
> -- 
> 2.32.0
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/1c374273/attachment.sig>

From allen-kh.cheng at mediatek.com  Wed Jan 12 03:29:54 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:29:54 +0800
Subject: [PATCH] firmware: mediatek: add adsp ipc protocol interface
Message-ID: <20220112112954.27128-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 ++
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 137 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++++
 6 files changed, 215 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..b45f16cec063
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *dsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	dsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(dsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "Wrong mbox chan %d \n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *dsp_ipc;
+	struct mtk_adsp_chan *dsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
+	if (!dsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		dsp_chan = &dsp_ipc->chans[i];
+		cl = &dsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		dsp_chan->ipc = dsp_ipc;
+		dsp_chan->idx = i;
+		dsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(dsp_chan->ch)) {
+			ret = PTR_ERR(dsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	dsp_ipc->dev = dev;
+	dev_set_drvdata(dev, dsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out:
+	kfree(chan_name);
+	for (j = 0; j < i; j++) {
+		dsp_chan = &dsp_ipc->chans[j];
+		mbox_free_channel(dsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *dsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *dsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		dsp_chan = &dsp_ipc->chans[i];
+		mbox_free_channel(dsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..08e3c7d3b405
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:30:24 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:30:24 +0800
Subject: [PATCH v11 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220112113024.27448-1-allen-kh.cheng@mediatek.com>
References: <20220112113024.27448-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112113024.27448-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 176 +++++++++++++++++++++++++++++
 3 files changed, 185 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..b8174f155f8d
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return &mbox->chans[sp->args[0]];
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear DSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear DSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:30:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:30:23 +0800
Subject: [PATCH v11 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220112113024.27448-1-allen-kh.cheng@mediatek.com>
References: <20220112113024.27448-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112113024.27448-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:30:22 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:30:22 +0800
Subject: [PATCH v11 0/2] This patches provide ADSP IPC support for MT8195
Message-ID: <20220112113024.27448-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between
processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox
registers to kick dsp.

Two mailboxes used to send notification or short message between processors with
dsp

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error

Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 176 ++++++++++++++++++
 4 files changed, 237 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:32:46 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:32:46 +0800
Subject: [PATCH v2 0/1] firmware: mtk: add adsp ipc protocol for sof
Message-ID: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch provides mtk adsp ipc support for sof.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove unuseful MODULE_LICENSE
- change label name to out_free

Allen-KH Cheng (1):
  firmware: mediatek: add adsp ipc protocol interface

 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 159 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 237 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:37:23 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:37:23 +0800
Subject: [PATCH v12 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220112113723.32041-1-allen-kh.cheng@mediatek.com>
References: <20220112113723.32041-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112113723.32041-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 175 +++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..064817be6a74
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:32:47 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:32:47 +0800
Subject: [PATCH v2 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>
References: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112113247.29135-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 159 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 237 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..e4aa312a3e3f
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *adsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	adsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(adsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * mbox_send_message returns non-negative value on success,
+	 * return zero for success
+	 */
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "wrong mbox chan %d \n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *adsp_ipc;
+	struct mtk_adsp_chan *adsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+	if (!adsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out_free;
+		}
+
+		adsp_chan = &adsp_ipc->chans[i];
+		cl = &adsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		adsp_chan->ipc = adsp_ipc;
+		adsp_chan->idx = i;
+		adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(adsp_chan->ch)) {
+			ret = PTR_ERR(adsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out_free;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	adsp_ipc->dev = dev;
+	dev_set_drvdata(dev, adsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out_free:
+	kfree(chan_name);
+	for (j = 0; j < i; j++) {
+		adsp_chan = &adsp_ipc->chans[j];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *adsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		adsp_chan = &adsp_ipc->chans[i];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:37:22 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:37:22 +0800
Subject: [PATCH v12 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220112113723.32041-1-allen-kh.cheng@mediatek.com>
References: <20220112113723.32041-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112113723.32041-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:37:21 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:37:21 +0800
Subject: [PATCH v12 0/2] This patches provide ADSP MBOX support for MT8195
Message-ID: <20220112113723.32041-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox registers to kick dsp.

Two mailboxes used to send notification or short message between processors with dsp

changes since v11:
- remove unuseful MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error



Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 175 ++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From tinghan.shen at mediatek.com  Wed Jan 12 03:47:23 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Wed, 12 Jan 2022 19:47:23 +0800
Subject: [PATCH v9 2/3] dt-bindings: pinctrl: mt8195: Add mediatek,
 drive-strength-adv property
In-Reply-To: <20220112114724.1953-1-tinghan.shen@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
Message-ID: <20220112114724.1953-3-tinghan.shen@mediatek.com>

Extend driving support for I2C pins on SoC mt8195.
This property is already documented in mediatek,mt8183-pinctrl.yaml.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
index 328ea59c5466..4db4899af6b1 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
@@ -98,6 +98,32 @@ patternProperties:
           drive-strength:
             enum: [2, 4, 6, 8, 10, 12, 14, 16]
 
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
           bias-pull-down:
             description: |
               For pull down type is normal, it don't need add RSEL & R1R0 define
@@ -268,4 +294,13 @@ examples:
           bias-pull-down;
         };
       };
+
+      i2c0-pins {
+        pins {
+          pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+                   <PINMUX_GPIO9__FUNC_SCL0>;
+          bias-disable;
+          mediatek,drive-strength-adv = <7>;
+        };
+      };
     };
-- 
2.18.0



From tinghan.shen at mediatek.com  Wed Jan 12 03:47:22 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Wed, 12 Jan 2022 19:47:22 +0800
Subject: [PATCH v9 1/3] dt-bindings: arm: mediatek: Add mt8195 pericfg
 compatible
In-Reply-To: <20220112114724.1953-1-tinghan.shen@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
Message-ID: <20220112114724.1953-2-tinghan.shen@mediatek.com>

Add mt8195 pericfg compatible to binding document.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
index 8723dfe34bab..611f666f359d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
@@ -26,6 +26,7 @@ properties:
               - mediatek,mt8135-pericfg
               - mediatek,mt8173-pericfg
               - mediatek,mt8183-pericfg
+              - mediatek,mt8195-pericfg
               - mediatek,mt8516-pericfg
           - const: syscon
       - items:
-- 
2.18.0



From tinghan.shen at mediatek.com  Wed Jan 12 03:47:21 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Wed, 12 Jan 2022 19:47:21 +0800
Subject: [PATCH v9 0/3] Add basic SoC support for mediatek mt8195
Message-ID: <20220112114724.1953-1-tinghan.shen@mediatek.com>

This series adds basic SoC support for Mediatek's SoC MT8195.

---
Changes in v9:
  - remove duplicated cpus dt-bindings patch in v8
Changes in v8:
  - v7 mediatek,spi-mtk-nor.yaml patch is applied in branch for-5.17 at 
    kernel/git/broonie/spi.git
  - v7 pinctrl-mt8195.yaml patch is applied in branch for-next at 
    kernel/git/linusw/linux-pinctrl.git
  - add cortex-a78 compatible to cpus dt-bindings
  - add mediatek,drive-strength-adv property to pinctrl dt-bindings
  - fix evb dts
    - remove i2c nodes with disabled status from dts
    - fix pin properties not match pinctrl dt-bindings
    - remove unnecessary u3port*
  - fix dtsi
    - fix node format
    - reorder oscillator* nodes 
    - fix node name of cpu idle nodes
    - remove clock-frequency property in the timer node
    - reorder clock and clock names in usb nodes
Changes in v7:
  - refine title of spi-nor dt-bindings patch
  - refine commit message of pinctrl dt-bindings patch
  - update pinctrl-mt8195.yaml
    - change property pattern from 'pins' to '^pins'
    - update examples with new property in descriptions
    - add new example
  - drop '_' from node names of pinctrl subnodes in mt8195-evb.dts
Changes in v6:
  - rebase on 5.16-rc1
  - add new clock name to spi-nor dt-bindings
  - add "pins" property in pinctrl dt-bindings
  - fix fails of dtbs_checks
    - remove "arm,armv8" not matched in yaml from cpu compatile
    - fix node name of xhci
    - remvoe xhci upstreaming wakeup properties
    - remove xhci unused properties address-cells and size-cells
    - fix node name of ufs-phy 
    - fix node name of spi-nor
    - fix node name and sub-nodes of pinctrl
    - fix mmc compatible
Changes in v5:
  - enable basic nodes in mt8195-evb.dts
  - remove dedicated clock nodes
  - add mmc2 node
  - fix interrupt number of pinctrl node
  - update clock nodes to apply internal fixes
  - add dt-bindings for perficfg node

v4 thread:
https://lore.kernel.org/all/20210922093303.23720-2-seiya.wang at mediatek.com/
v3 thread:
https://lore.kernel.org/all/20210601075350.31515-2-seiya.wang at mediatek.com/
v2 thread:
https://lore.kernel.org/all/20210319023427.16711-10-seiya.wang at mediatek.com/
v1 thread:
https://lore.kernel.org/all/20210316111443.3332-11-seiya.wang at mediatek.com/
---

Tinghan Shen (3):
  dt-bindings: arm: mediatek: Add mt8195 pericfg compatible
  dt-bindings: pinctrl: mt8195: Add mediatek,drive-strength-adv property
  arm64: dts: Add mediatek SoC mt8195 and evaluation board

 .../arm/mediatek/mediatek,pericfg.yaml        |    1 +
 .../bindings/pinctrl/pinctrl-mt8195.yaml      |   35 +
 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts   |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 1049 +++++++++++++++++
 5 files changed, 1247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

-- 
2.18.0



From tinghan.shen at mediatek.com  Wed Jan 12 03:47:24 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Wed, 12 Jan 2022 19:47:24 +0800
Subject: [PATCH v9 3/3] arm64: dts: Add mediatek SoC mt8195 and evaluation
 board
In-Reply-To: <20220112114724.1953-1-tinghan.shen@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
Message-ID: <20220112114724.1953-4-tinghan.shen@mediatek.com>

Add basic chip support for mediatek mt8195.

Signed-off-by: Seiya Wang <seiya.wang at mediatek.com>
Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 1049 +++++++++++++++++++
 3 files changed, 1211 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8c1e18032f9f..5da29e7223e4 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -38,4 +38,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
new file mode 100644
index 000000000000..51633d91d984
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+/dts-v1/;
+#include "mt8195.dtsi"
+
+/ {
+	model = "MediaTek MT8195 evaluation board";
+	compatible = "mediatek,mt8195-evb", "mediatek,mt8195";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pin>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&nor_flash {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&pio {
+	i2c0_pin: i2c0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+				 <PINMUX_GPIO9__FUNC_SCL0>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c1_pin: i2c1-pins {
+		pins {
+			pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+				 <PINMUX_GPIO11__FUNC_SCL1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c4_pin: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <7>;
+		};
+	};
+
+	i2c6_pin: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	i2c7_pin: i2c7-pins {
+		pins {
+			pinmux = <PINMUX_GPIO27__FUNC_SCL7>,
+				 <PINMUX_GPIO28__FUNC_SDA7>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	nor_pins_default: nor-pins {
+		pins0 {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			bias-pull-down;
+		};
+
+		pins1 {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>,
+				 <PINMUX_GPIO130__FUNC_SPINOR_IO2>,
+				 <PINMUX_GPIO131__FUNC_SPINOR_IO3>;
+			bias-pull-up;
+		};
+	};
+
+	uart0_pin: uart0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+				 <PINMUX_GPIO99__FUNC_URXD0>;
+		};
+	};
+};
+
+&u2port0 {
+	status = "okay";
+};
+
+&u2port1 {
+	status = "okay";
+};
+
+&u3phy0 {
+	status="okay";
+};
+
+&u3phy1 {
+	status="okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pin>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
new file mode 100644
index 000000000000..a363e82f6988
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/reset/ti-syscon.h>
+
+/ {
+	compatible = "mediatek,mt8195";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x000>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x400>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x500>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu6: cpu at 600 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x600>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu7: cpu at 700 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x700>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_off_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <95>;
+				min-residency-us = <580>;
+			};
+
+			cpu_off_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <45>;
+				exit-latency-us = <140>;
+				min-residency-us = <740>;
+			};
+
+			cluster_off_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <55>;
+				exit-latency-us = <155>;
+				min-residency-us = <840>;
+			};
+
+			cluster_off_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <200>;
+				min-residency-us = <1000>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH 0>;
+		cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
+		       <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "clk32k";
+	};
+
+	pmu-a55 {
+		compatible = "arm,cortex-a55-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>;
+	};
+
+	pmu-a78 {
+		compatible = "arm,cortex-a78-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <4>;
+			#redistributor-regions = <1>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,
+			      <0 0x0c040000 0 0x200000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+
+			ppi-partitions {
+				ppi_cluster0: interrupt-partition-0 {
+					affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+
+				ppi_cluster1: interrupt-partition-1 {
+					affinity = <&cpu4 &cpu5 &cpu6 &cpu7>;
+				};
+			};
+		};
+
+		topckgen: syscon at 10000000 {
+			compatible = "mediatek,mt8195-topckgen", "syscon";
+			reg = <0 0x10000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		infracfg_ao: syscon at 10001000 {
+			compatible = "mediatek,mt8195-infracfg_ao", "syscon", "simple-mfd";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+
+			infracfg_rst: reset-controller {
+				compatible = "ti,syscon-reset";
+				#reset-cells = <1>;
+				ti,reset-bits = <
+					0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* pcie */
+					0x120 0  0x124 0  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x730 10 0x734 10 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x150 5  0x154 5  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* svs gpu */
+				>;
+			};
+		};
+
+		pericfg: syscon at 10003000 {
+			compatible = "mediatek,mt8195-pericfg", "syscon";
+			reg = <0 0x10003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl at 10005000 {
+			compatible = "mediatek,mt8195-pinctrl";
+			reg = <0 0x10005000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>,
+			      <0 0x11d30000 0 0x1000>,
+			      <0 0x11d40000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11eb0000 0 0x1000>,
+			      <0 0x11f40000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "iocfg0", "iocfg_bm", "iocfg_bl",
+				    "iocfg_br", "iocfg_lm", "iocfg_rb",
+				    "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 144>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH 0>;
+			#interrupt-cells = <2>;
+		};
+
+		watchdog: watchdog at 10007000 {
+			compatible = "mediatek,mt8195-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x10007000 0 0x100>;
+		};
+
+		apmixedsys: syscon at 1000c000 {
+			compatible = "mediatek,mt8195-apmixedsys", "syscon";
+			reg = <0 0x1000c000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		systimer: timer at 10017000 {
+			compatible = "mediatek,mt8195-timer",
+				     "mediatek,mt6765-timer";
+			reg = <0 0x10017000 0 0x1000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_CLK26M_D2>;
+		};
+
+		pwrap: pwrap at 10024000 {
+			compatible = "mediatek,mt8195-pwrap", "syscon";
+			reg = <0 0x10024000 0 0x1000>;
+			reg-names = "pwrap";
+			interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_PMIC_AP>,
+				 <&infracfg_ao CLK_INFRA_AO_PMIC_TMR>;
+			clock-names = "spi", "wrap";
+			assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC>;
+			assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
+		};
+
+		scp_adsp: clock-controller at 10720000 {
+			compatible = "mediatek,mt8195-scp_adsp";
+			reg = <0 0x10720000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		uart0: serial at 11001100 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001100 0 0x100>;
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART0>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart1: serial at 11001200 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001200 0 0x100>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART1>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart2: serial at 11001300 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001300 0 0x100>;
+			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART2>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart3: serial at 11001400 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001400 0 0x100>;
+			interrupts = <GIC_SPI 723 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART3>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart4: serial at 11001500 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001500 0 0x100>;
+			interrupts = <GIC_SPI 724 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART4>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart5: serial at 11001600 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001600 0 0x100>;
+			interrupts = <GIC_SPI 725 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART5>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		auxadc: auxadc at 11002000 {
+			compatible = "mediatek,mt8195-auxadc",
+				     "mediatek,mt8173-auxadc";
+			reg = <0 0x11002000 0 0x1000>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_AUXADC>;
+			clock-names = "main";
+			#io-channel-cells = <1>;
+			status = "disabled";
+		};
+
+		pericfg_ao: syscon at 11003000 {
+			compatible = "mediatek,mt8195-pericfg_ao", "syscon";
+			reg = <0 0x11003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		spi0: spi at 1100a000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI0>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi1: spi at 11010000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11010000 0 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI1>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi2: spi at 11012000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11012000 0 0x1000>;
+			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI2>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi3: spi at 11013000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11013000 0 0x1000>;
+			interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI3>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi4: spi at 11018000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11018000 0 0x1000>;
+			interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI4>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi5: spi at 11019000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11019000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI5>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spis0: spi at 1101d000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101d000 0 0x1000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS0>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		spis1: spi at 1101e000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101e000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS1>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		xhci0: usb at 11200000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11200000 0 0x1000>,
+			      <0 0x11203e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port0 PHY_TYPE_USB2>,
+			       <&u3port0 PHY_TYPE_USB3>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
+				 <&topckgen CLK_TOP_SSUSB_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11230000 0 0x10000>,
+			      <0 0x11f50000 0 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC50_0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			status = "disabled";
+		};
+
+		mmc1: mmc at 11240000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11240000 0 0x1000>,
+			      <0 0x11c70000 0 0x1000>;
+			interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_1>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		mmc2: mmc at 11250000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11250000 0 0x1000>,
+			      <0 0x11e60000 0 0x1000>;
+			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG1_MSDC2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG3_MSDC2>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_2>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		xhci1: usb at 11290000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11290000 0 0x1000>,
+			      <0 0x11293e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port1 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_1P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_1P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_1P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P1_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_1P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck","xhci_ck";
+			status = "disabled";
+		};
+
+		xhci2: usb at 112a0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112a0000 0 0x1000>,
+			      <0 0x112a3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port2 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_2P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_2P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_2P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P2_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		xhci3: usb at 112b0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112b0000 0 0x1000>,
+			      <0 0x112b3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port3 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_3P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_3P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_3P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P3_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			/* This controller is connected with a BT device.
+			 * Disable usb2 lpm to prevent konwn issues.
+			 */
+			usb2-lpm-disable;
+			status = "disabled";
+		};
+
+		nor_flash: spi at 1132c000 {
+			compatible = "mediatek,mt8195-nor",
+				     "mediatek,mt8173-nor";
+			reg = <0 0x1132c000 0 0x1000>;
+			interrupts = <GIC_SPI 825 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_SPINOR>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_FLASH>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_BUS>;
+			clock-names = "spi", "sf", "axi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		u3phy2: t-phy at 11c40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c40000 0x700>;
+			status = "disabled";
+
+			u2port2: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P2_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy3: t-phy at 11c50000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c50000 0x700>;
+			status = "disabled";
+
+			u2port3: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P3_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		i2c5: i2c at 11d00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d00000 0 0x1000>,
+			      <0 0x10220580 0 0x80>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C5>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c6: i2c at 11d01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d01000 0 0x1000>,
+			      <0 0x10220600 0 0x80>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C6>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c7: i2c at 11d02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d02000 0 0x1000>,
+			      <0 0x10220680 0 0x80>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_s: clock-controller at 11d03000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_s";
+			reg = <0 0x11d03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		i2c0: i2c at 11e00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e00000 0 0x1000>,
+			      <0 0x10220080 0 0x80>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C0>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+		};
+
+		i2c1: i2c at 11e01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e01000 0 0x1000>,
+			      <0 0x10220200 0 0x80>;
+			interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C1>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at 11e02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e02000 0 0x1000>,
+			      <0 0x10220380 0 0x80>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C2>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at 11e03000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e03000 0 0x1000>,
+			      <0 0x10220480 0 0x80>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C3>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at 11e04000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e04000 0 0x1000>,
+			      <0 0x10220500 0 0x80>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C4>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_w: clock-controller at 11e05000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_w";
+			reg = <0 0x11e05000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		u3phy1: t-phy at 11e30000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e30000 0xe00>;
+			status = "disabled";
+
+			u2port1: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port1: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy0: t-phy at 11e40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e40000 0xe00>;
+			status = "disabled";
+
+			u2port0: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port0: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		ufsphy: ufs-phy at 11fa0000 {
+			compatible = "mediatek,mt8195-ufsphy", "mediatek,mt8183-ufsphy";
+			reg = <0 0x11fa0000 0 0xc000>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "unipro", "mp";
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		mfgcfg: clock-controller at 13fbf000 {
+			compatible = "mediatek,mt8195-mfgcfg";
+			reg = <0 0x13fbf000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys: clock-controller at 14e00000 {
+			compatible = "mediatek,mt8195-wpesys";
+			reg = <0 0x14e00000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp0: clock-controller at 14e02000 {
+			compatible = "mediatek,mt8195-wpesys_vpp0";
+			reg = <0 0x14e02000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp1: clock-controller at 14e03000 {
+			compatible = "mediatek,mt8195-wpesys_vpp1";
+			reg = <0 0x14e03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys: clock-controller at 15000000 {
+			compatible = "mediatek,mt8195-imgsys";
+			reg = <0 0x15000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_top: clock-controller at 15110000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_top";
+			reg = <0 0x15110000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_nr: clock-controller at 15130000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_nr";
+			reg = <0 0x15130000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_wpe: clock-controller at 15220000 {
+			compatible = "mediatek,mt8195-imgsys1_wpe";
+			reg = <0 0x15220000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ipesys: clock-controller at 15330000 {
+			compatible = "mediatek,mt8195-ipesys";
+			reg = <0 0x15330000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys: clock-controller at 16000000 {
+			compatible = "mediatek,mt8195-camsys";
+			reg = <0 0x16000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawa: clock-controller at 1604f000 {
+			compatible = "mediatek,mt8195-camsys_rawa";
+			reg = <0 0x1604f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuva: clock-controller at 1606f000 {
+			compatible = "mediatek,mt8195-camsys_yuva";
+			reg = <0 0x1606f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawb: clock-controller at 1608f000 {
+			compatible = "mediatek,mt8195-camsys_rawb";
+			reg = <0 0x1608f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuvb: clock-controller at 160af000 {
+			compatible = "mediatek,mt8195-camsys_yuvb";
+			reg = <0 0x160af000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_mraw: clock-controller at 16140000 {
+			compatible = "mediatek,mt8195-camsys_mraw";
+			reg = <0 0x16140000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ccusys: clock-controller at 17200000 {
+			compatible = "mediatek,mt8195-ccusys";
+			reg = <0 0x17200000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_soc: clock-controller at 1800f000 {
+			compatible = "mediatek,mt8195-vdecsys_soc";
+			reg = <0 0x1800f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys: clock-controller at 1802f000 {
+			compatible = "mediatek,mt8195-vdecsys";
+			reg = <0 0x1802f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_core1: clock-controller at 1803f000 {
+			compatible = "mediatek,mt8195-vdecsys_core1";
+			reg = <0 0x1803f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		apusys_pll: clock-controller at 190f3000 {
+			compatible = "mediatek,mt8195-apusys_pll";
+			reg = <0 0x190f3000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys: clock-controller at 1a000000 {
+			compatible = "mediatek,mt8195-vencsys";
+			reg = <0 0x1a000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys_core1: clock-controller at 1b000000 {
+			compatible = "mediatek,mt8195-vencsys_core1";
+			reg = <0 0x1b000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+	};
+};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:37 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:37 +0800
Subject: [PATCH v3 0/5] Update MT8192 Clock Setting
Message-ID: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is base on v5.16-rc8,
series "Mediatek MT8192 clock support"[1], [2] annd [3].
[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
[2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/
[3] https://lore.kernel.org/all/20210825011120.30481-1-chun-jie.chen at mediatek.com/

changes since v2:
 - add missing "clock" at the end of commit message

changes since v1:
 - update the commit message

Allen-KH Cheng (5):
  arm64: dts: mediatek: Correct uart clock of MT8192
  arm64: dts: mediatek: Correct SPI clock of MT8192
  arm64: dts: mediatek: Correct Nor Flash clock of MT8192
  arm64: dts: mediatek: Correct I2C clock of MT8192
  arm64: dts: mediatek: Correct system timer clock of MT8192

 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++-----------
 1 file changed, 52 insertions(+), 40 deletions(-)

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:39 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:39 +0800
Subject: [PATCH v3 2/5] arm64: dts: mediatek: Correct SPI clock of MT8192
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112115542.10606-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the SPI clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 48 ++++++++++++------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index cfb67cc40c2c..47d056cc5dad 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -355,9 +355,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1100a000 0 0x1000>;
 			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI0>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -369,9 +369,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11010000 0 0x1000>;
 			interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI1>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -383,9 +383,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11012000 0 0x1000>;
 			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI2>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -397,9 +397,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11013000 0 0x1000>;
 			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI3>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -411,9 +411,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11018000 0 0x1000>;
 			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI4>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -425,9 +425,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11019000 0 0x1000>;
 			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI5>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -439,9 +439,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101d000 0 0x1000>;
 			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI6>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -453,9 +453,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101e000 0 0x1000>;
 			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI7>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:42 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:42 +0800
Subject: [PATCH v3 5/5] arm64: dts: mediatek: Correct system timer clock of
 MT8192
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112115542.10606-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the systimer clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 1eb5874c09a9..4f6c4ce885af 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -312,7 +312,7 @@
 				     "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
 			interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>;
+			clocks = <&topckgen CLK_TOP_CSW_F26M_D2>;
 			clock-names = "clk13m";
 		};
 
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:40 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:40 +0800
Subject: [PATCH v3 3/5] arm64: dts: mediatek: Correct Nor Flash clock of MT8192
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112115542.10606-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the Nor Flash clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 47d056cc5dad..8584a20440c5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -464,10 +464,12 @@
 			compatible = "mediatek,mt8192-nor";
 			reg = <0 0x11234000 0 0xe0>;
 			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_SFLASH_SEL>,
+				 <&infracfg CLK_INFRA_FLASHIF_SFLASH>,
+				 <&infracfg CLK_INFRA_FLASHIF_TOP_H_133M>;
 			clock-names = "spi", "sf", "axi";
+			assigned-clocks = <&topckgen CLK_TOP_SFLASH_SEL>;
+			assigned-clock-parents = <&clk26m>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disable";
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:38 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:38 +0800
Subject: [PATCH v3 1/5] arm64: dts: mediatek: Correct uart clock of MT8192
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112115542.10606-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the uart clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..cfb67cc40c2c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -327,7 +327,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11002000 0 0x1000>;
 			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
@@ -337,7 +337,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11003000 0 0x1000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 03:55:41 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Wed, 12 Jan 2022 19:55:41 +0800
Subject: [PATCH v3 4/5] arm64: dts: mediatek: Correct I2C clock of MT8192
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220112115542.10606-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the I2C clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 30 ++++++++++++++++--------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 8584a20440c5..1eb5874c09a9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -486,7 +486,8 @@
 			reg = <0 0x11cb0000 0 0x1000>,
 			      <0 0x10217300 0 0x80>;
 			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -505,7 +506,8 @@
 			reg = <0 0x11d00000 0 0x1000>,
 			      <0 0x10217600 0 0x180>;
 			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -518,7 +520,8 @@
 			reg = <0 0x11d01000 0 0x1000>,
 			      <0 0x10217780 0 0x180>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -531,7 +534,8 @@
 			reg = <0 0x11d02000 0 0x1000>,
 			      <0 0x10217900 0 0x180>;
 			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -550,7 +554,8 @@
 			reg = <0 0x11d20000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -563,7 +568,8 @@
 			reg = <0 0x11d21000 0 0x1000>,
 			      <0 0x10217180 0 0x180>;
 			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -576,7 +582,8 @@
 			reg = <0 0x11d22000 0 0x1000>,
 			      <0 0x10217380 0 0x180>;
 			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -595,7 +602,8 @@
 			reg = <0 0x11e00000 0 0x1000>,
 			      <0 0x10217500 0 0x80>;
 			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -614,7 +622,8 @@
 			reg = <0 0x11f00000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C0>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -627,7 +636,8 @@
 			reg = <0 0x11f01000 0 0x1000>,
 			      <0 0x10217580 0 0x80>;
 			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C6>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
-- 
2.18.0



From mark.rutland at arm.com  Wed Jan 12 04:01:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 12:01:57 +0000
Subject: [PATCH] arm64: mm: hugetlb: add support for free vmemmap pages
 of HugeTLB
In-Reply-To: <20220111131652.61947-1-songmuchun@bytedance.com>
References: <20220111131652.61947-1-songmuchun@bytedance.com>
Message-ID: <Yd7DNesaCACPndv2@FVFF77S0Q05N>

Hi,

On Tue, Jan 11, 2022 at 09:16:52PM +0800, Muchun Song wrote:
> The preparation of supporting freeing vmemmap associated with each
> HugeTLB page is ready, so we can support this feature for arm64.
> 
> Signed-off-by: Muchun Song <songmuchun at bytedance.com>

It's a bit difficult to understand this commit message, as there's not much
context here.

What is HUGETLB_PAGE_FREE_VMEMMAP intended to achieve? Is this intended to save
memory, find bugs, or some other goal? If this is a memory saving or
performance improvement, can we quantify that benefit?

Does the alloc/free happen dynamically, or does this happen once during kernel
boot? IIUC it's the former, which sounds pretty scary. Especially if we need to
re-allocate the vmmemmap pages later -- can't we run out of memory, and then
fail to free a HugeTLB page?

Are there any requirements upon arch code, e.g. mutual exclusion?

Below there are a bunch of comments trying to explain that this is safe. Having
some of that rationale in the commit message itself would be helpful.

I see that commit:

  6be24bed9da367c2 ("mm: hugetlb: introduce a new config HUGETLB_PAGE_FREE_VMEMMAP")

... has a much more complete description, and cribbing some of that wording
would be helpful.


> ---
> There is already some discussions about this in [1], but there was no
> conclusion in the end. I copied the concern proposed by Anshuman to here.
> 
> 1st concern:
> "
>   But what happens when a hot remove section's vmemmap area (which is being
>   teared down) is nearby another vmemmap area which is either created or
>   being destroyed for HugeTLB alloc/free purpose. As you mentioned HugeTLB
>   pages inside the hot remove section might be safe. But what about other
>   HugeTLB areas whose vmemmap area shares page table entries with vmemmap
>   entries for a section being hot removed ? Massive HugeTLB alloc/use/free
>   test cycle using memory just adjacent to a memory hotplug area, which is
>   always added and removed periodically, should be able to expose this problem.
> "
> My Answer: As you already know HugeTLB pages inside the hot remove section
> is safe.

It would be helpful if you could explain *why* that's safe, since those of us
coming at this cold have no idea whether this is the case.

> Let's talk your question "what about other HugeTLB areas whose
> vmemmap area shares page table entries with vmemmap entries for a section
> being hot removed ?", the question is not established. Why? The minimal
> granularity size of hotplug memory 128MB (on arm64, 4k base page), so any
> HugeTLB smaller than 128MB is within a section, then, there is no share
> (PTE) page tables between HugeTLB in this section and ones in other
> sections and a HugeTLB could not cross two sections.

Am I correct in assuming that in this case we never free the section?

> Any HugeTLB bigger than 128MB (e.g. 1GB) whose size is an integer multible of
> a section and vmemmap area is also an integer multiple of 2MB. At the time
> memory is removed, all huge pages either have been migrated away or
> dissolved. The vmemmap is stable. So there is no problem in this case as
> well.

Are you mention 2MB here because we PMD-map the vmemmap with 4K pages?

IIUC, so long as:

1) HugeTLBs are naturally aligned, power-of-two sizes
2) The HugeTLB size >= the section size
3) The HugeTLB size >= the vmemmap leaf mapping size

... then a HugeTLB will not share any leaf page table entries with *anything
else*, but will share intermediate entries.

Perhaps that's a clearer line of argument?

Regardless, this should be in the commit message.

> 2nd concern:
> "
>   differently, not sure if ptdump would require any synchronization.
> 
>   Dumping an wrong value is probably okay but crashing because a page table
>   entry is being freed after ptdump acquired the pointer is bad. On arm64,
>   ptdump() is protected against hotremove via [get|put]_online_mems().
> "
> My Answer: The ptdump should be fine since vmemmap_remap_free() only exchanges
> PTEs or split the PMD entry (which means allocating a PTE page table). Both
> operations do not free any page tables, so ptdump cannot run into a UAF on
> any page tables. The wrost case is just dumping an wrong value.

This should be in the commit message.

Thanks,
Mark.

> 
> [1] https://lore.kernel.org/linux-mm/b8cdc9c8-853c-8392-a2fa-4f1a8f02057a at arm.com/T/
> 
>  fs/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/Kconfig b/fs/Kconfig
> index 7a2b11c0b803..04cfd5bf5ec9 100644
> --- a/fs/Kconfig
> +++ b/fs/Kconfig
> @@ -247,7 +247,7 @@ config HUGETLB_PAGE
>  
>  config HUGETLB_PAGE_FREE_VMEMMAP
>  	def_bool HUGETLB_PAGE
> -	depends on X86_64
> +	depends on X86_64 || ARM64
>  	depends on SPARSEMEM_VMEMMAP
>  
>  config HUGETLB_PAGE_FREE_VMEMMAP_DEFAULT_ON
> -- 
> 2.11.0
> 


From hverkuil at xs4all.nl  Wed Jan 12 04:07:20 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Wed, 12 Jan 2022 13:07:20 +0100
Subject: [PATCH v3 00/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <20211213134940.324266-1-eugen.hristev@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
Message-ID: <50bb6274-b004-eff7-56d5-68ec8e10d3c4@xs4all.nl>

Hi Eugen,

On 13/12/2021 14:49, Eugen Hristev wrote:
> This series is the v3 of the series that attempts to support media controller
> in the atmel ISC and XISC drivers.
> This series also includes the csi2dc driver which was previously sent in a
> separate series:
> https://www.spinics.net/lists/linux-media/msg181042.html
> https://www.spinics.net/lists/linux-media/msg181044.html
> The driver now addresses comments received in latest v5 series from last year.
> 
> The series includes some minor changes and fixes that improve the isc common
> code base, like removing the enum frameintervals VIDIOC, fixing bytesperline
> for planar formats, etc.
> 
> Many thanks to folks from libcamera who helped a lot with understanding
> how a media controller driver should behave.
> 
> Feedback is welcome !
> 
> Changes in v3:
> - change in bindings, small fixes in csi2dc driver and conversion to mc
> for the isc-base.
> - removed some MAINTAINERS patches and used patterns in MAINTAINERS
> 
> Changes in v2:
> - integrated many changes suggested by Jacopo in the review of the v1 series.
> - add a few new patches

Based on the current review status I think it would make sense to add
the following patches from this series to a PR:

1-6, 8-9, 11, 16, 18-22.

Are there any patches (esp. 11 and later) that require other patches
not in this list? In other words, does this make sense?

Regards,

	Hans

> 
> 
> Eugen Hristev (23):
>   MAINTAINERS: add microchip csi2dc
>   dt-bindings: media: atmel: csi2dc: add bindings for microchip csi2dc
>   media: atmel: introduce microchip csi2dc driver
>   media: atmel: atmel-isc: split the clock code into separate source
>     file
>   media: atmel: atmel-isc: replace video device name with module name
>   media: atmel: atmel-sama7g5-isc: fix ispck leftover
>   media: atmel: atmel-isc-base: use streaming status when queueing
>     buffers
>   media: atmel: atmel-isc-base: remove frameintervals VIDIOC
>   media: atmel: atmel-isc-base: report frame sizes as full supported
>     range
>   media: atmel: atmel-isc-base: implement mbus_code support in enumfmt
>   media: atmel: atmel-isc-base: fix bytesperline value for planar
>     formats
>   media: atmel: atmel-isc: implement media controller
>   ARM: dts: at91: sama7g5: add nodes for video capture
>   ARM: configs: at91: sama7: add xisc and csi2dc
>   ARM: multi_v7_defconfig: add atmel video pipeline modules
>   media: atmel: atmel-sama5d2-isc: fix wrong mask in YUYV format check
>   media: atmel: atmel-isc-base: use mutex to lock awb workqueue from
>     streaming
>   media: atmel: atmel-isc-base: add wb debug messages
>   media: atmel: atmel-isc-base: clamp wb gain coefficients
>   media: atmel: atmel-sama7g5-isc: fix UYVY input format mbus_code typo
>   media: atmel: atmel-isc: add raw Bayer 8bit 10bit output formats
>   media: atmel: atmel-isc: compact the controller formats list
>   media: atmel: atmel-isc: change format propagation to subdev into only
>     verification
> 
>  .../bindings/media/microchip,csi2dc.yaml      | 197 +++++
>  MAINTAINERS                                   |  14 +-
>  arch/arm/boot/dts/sama7g5.dtsi                |  48 ++
>  arch/arm/configs/multi_v7_defconfig           |   3 +
>  arch/arm/configs/sama7_defconfig              |   2 +
>  drivers/media/platform/Makefile               |   1 +
>  drivers/media/platform/atmel/Kconfig          |  15 +
>  drivers/media/platform/atmel/Makefile         |   4 +-
>  drivers/media/platform/atmel/atmel-isc-base.c | 790 ++++++-----------
>  drivers/media/platform/atmel/atmel-isc-clk.c  | 311 +++++++
>  drivers/media/platform/atmel/atmel-isc-mc.c   | 287 +++++++
>  drivers/media/platform/atmel/atmel-isc.h      |  49 ++
>  .../media/platform/atmel/atmel-sama5d2-isc.c  |  59 +-
>  .../media/platform/atmel/atmel-sama7g5-isc.c  |  72 +-
>  .../media/platform/atmel/microchip-csi2dc.c   | 806 ++++++++++++++++++
>  15 files changed, 2085 insertions(+), 573 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
>  create mode 100644 drivers/media/platform/atmel/atmel-isc-clk.c
>  create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
>  create mode 100644 drivers/media/platform/atmel/microchip-csi2dc.c
> 



From clabbe.montjoie at gmail.com  Wed Jan 12 04:07:52 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Wed, 12 Jan 2022 13:07:52 +0100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
In-Reply-To: <Yd1SIHUNdLIvKhzz@Red>
References: <Yd1SIHUNdLIvKhzz@Red>
Message-ID: <Yd7EmC7HlxTg/fIl@Red>

Le Tue, Jan 11, 2022 at 10:47:12AM +0100, Corentin Labbe a ?crit :

I forgot to add some mailing list (linux-crypto) and I add ipsec maintainer as spinlock is from ipsec code.

And I have now identified the spin_lock which is stuck:
It is the one from net/xfrm/xfrm_input.c:649

This is the patch used to identify it:
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index a732d62dbe35..63d388fe0363 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -354,6 +354,12 @@ static __always_inline void spin_lock(spinlock_t *lock)
 	raw_spin_lock(&lock->rlock);
 }
 
+static __always_inline void spin_lock2(spinlock_t *lock, int vid)
+{
+	raw_spin_lock(&lock->rlock);
+	atomic64_set(&lock->rlock.id, vid);	\
+}
+
 static __always_inline void spin_lock_bh(spinlock_t *lock)
 {
 	raw_spin_lock_bh(&lock->rlock);
diff --git a/include/linux/spinlock_types_raw.h b/include/linux/spinlock_types_raw.h
index 91cb36b65a17..247ed688e9e7 100644
--- a/include/linux/spinlock_types_raw.h
+++ b/include/linux/spinlock_types_raw.h
@@ -2,6 +2,7 @@
 #define __LINUX_SPINLOCK_TYPES_RAW_H
 
 #include <linux/types.h>
+#include <linux/atomic.h>
 
 #if defined(CONFIG_SMP)
 # include <asm/spinlock_types.h>
@@ -16,6 +17,7 @@ typedef struct raw_spinlock {
 #ifdef CONFIG_DEBUG_SPINLOCK
 	unsigned int magic, owner_cpu;
 	void *owner;
+	atomic64_t id;
 #endif
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 	struct lockdep_map dep_map;
diff --git a/kernel/locking/spinlock_debug.c b/kernel/locking/spinlock_debug.c
index 14235671a1a7..685981594c54 100644
--- a/kernel/locking/spinlock_debug.c
+++ b/kernel/locking/spinlock_debug.c
@@ -27,6 +27,7 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
 	lock->magic = SPINLOCK_MAGIC;
 	lock->owner = SPINLOCK_OWNER_INIT;
 	lock->owner_cpu = -1;
+	atomic64_set(&lock->id, 666);	\
 }
 
 EXPORT_SYMBOL(__raw_spin_lock_init);
@@ -61,11 +62,12 @@ static void spin_dump(raw_spinlock_t *lock, const char *msg)
 		msg, raw_smp_processor_id(),
 		current->comm, task_pid_nr(current));
 	printk(KERN_EMERG " lock: %pS, .magic: %08x, .owner: %s/%d, "
-			".owner_cpu: %d\n",
+			".owner_cpu: %d ID=%lu\n",
 		lock, READ_ONCE(lock->magic),
 		owner ? owner->comm : "<none>",
 		owner ? task_pid_nr(owner) : -1,
-		READ_ONCE(lock->owner_cpu));
+		READ_ONCE(lock->owner_cpu),
+		atomic64_read(&lock->id));
 	dump_stack();
 }
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 144238a50f3d..f874c4af9220 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -596,7 +596,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		}
 
 lock:
-		spin_lock(&x->lock);
+		spin_lock2(&x->lock, 15);
 
 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
 			if (x->km.state == XFRM_STATE_ACQ)
@@ -646,7 +646,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 resume:
 		dev_put(skb->dev);
 
-		spin_lock(&x->lock);
+		spin_lock2(&x->lock, 14);
 		if (nexthdr < 0) {
 			if (nexthdr == -EBADMSG) {
 				xfrm_audit_state_icvfail(x, skb,
And I got:
[   49.170676] BUG: spinlock recursion on CPU#0, 1c15000.crypto-/58
[   49.176747]  lock: 0xc43642a8, .magic: dead4ead, .owner: 1c15000.crypto-/58, .owner_cpu: 0 ID=14

Anyway, I believed that spinlock was from crypto/crypto_engine.c but the stack trace said the problem is from a basic spin_lock() and crypto_engine use only spin_lock_irq()

Regards

> Hello
> 
> I work on adding crypto/engine support to my crypto driver sun4i-ss.
> Selftests are passed but when doing iperf over ipsec I hit a spinlock recursion BUG.
> 
> This bug happen also against my sun8i-ce driver.
> But this bug happen only on ARM (SoCs H3) and not on arm64 (SoCs H6, a64 tested) for it.
> 
> This is the full trace:
> iperf 3.10.1
> Linux buildroot 5.15.13-00003-g14f78eca130d #199 SMP Fri Jan 7 08:35:20 CET 2022 armv7l
> Control connection MSS 1386
> Time: Fri, 07 Jan 2022 08:52:27 GMT
> Connecting to host ipsec.lava.local, port 5201
>       Cookie: ylt5ilt5n4jnw72qu2lik5njq63rfalkshz6
>       TCP MSS: 1386 (default)
> [  5] local 192.168.1.204 port 33828 connected to 192.168.1.40 port 5201
> Starting Test: protocol: TCP, 1 streams, 131072 byte blocks, omitting 0 seconds, 10 second test, tos 0
> [   44.412526] BUG: spinlock recursion on CPU#0, 1c15000.crypto-/111
> [   44.418674]  lock: 0xc3f40268, .magic: dead4ead, .owner: 1c15000.crypto-/111, .owner_cpu: 0
> [   44.427040] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
> [   44.435647] Hardware name: Allwinner sun8i Family
> [   44.440354] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
> [   44.448110] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
> [   44.455685] [<c0857fc4>] (dump_stack_lvl) from [<c016c5dc>] (do_raw_spin_lock+0x11c/0x120)
> [   44.463953] [<c016c5dc>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
> [   44.471961] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
> [   44.479451] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
> [   44.488156] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
> [   44.497636] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
> [   44.506944] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
> [   44.515645] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
> [   44.523391] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
> [   44.532527] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
> [   44.543394] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
> [   44.553306] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
> [   44.562182] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
> [   44.570359] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
> [   44.578016] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
> [   44.585848] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
> [   44.593162] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
> [   44.600824] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
> [   44.609007] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
> [   44.616491] Exception stack(0xc1b79e38 to 0xc1b79e80)
> [   44.621541] 9e20:                                                       c1c13c00 c0de5100
> [   44.629712] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
> [   44.637883] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
> [   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> [   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> [   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> [   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> [   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> [   44.688600] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
> [   44.697045] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
> [   44.704793] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
> [   44.712017] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
> [   44.717066] 9fa0:                                     00000000 00000000 00000000 00000000
> [   44.725237] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [   44.733406] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ ID] Interval           Transfer     Bitrate         Retr  Cwnd
> [  5]   0.00-1.11   sec  1.11 MBytes  8.39 Mbits/sec    1   1.35 KBytes       
> [  5]   1.11-2.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [   46.438402] sched: RT throttling activated
> [   46.438402] sched: RT throttling activated
> [  5]   2.00-3.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   3.00-4.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   4.00-5.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   5.00-6.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   6.00-7.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   7.00-8.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [  5]   8.00-9.00   sec  0.00 Bytes  0.00 bits/sec    0   1.35 KBytes       
> [   65.398401] rcu: INFO: rcu_sched self-detected stall on CPU
> [   65.403987] rcu: 	0-....: (2068 ticks this GP) idle=afd/1/0x40000004 softirq=3056/3057 fqs=1050 
> [   65.412774] 	(t=2102 jiffies g=1437 q=434)
> [   65.416873] NMI backtrace for cpu 0
> [   65.420361] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
> [   65.428965] Hardware name: Allwinner sun8i Family
> [   65.433669] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
> [   65.441424] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
> [   65.448998] [<c0857fc4>] (dump_stack_lvl) from [<c042dc1c>] (nmi_cpu_backtrace+0xdc/0x110)
> [   65.457267] [<c042dc1c>] (nmi_cpu_backtrace) from [<c042dd58>] (nmi_trigger_cpumask_backtrace+0x108/0x168)
> [   65.466918] [<c042dd58>] (nmi_trigger_cpumask_backtrace) from [<c0856bf8>] (rcu_dump_cpu_stacks+0x128/0x15c)
> [   65.476745] [<c0856bf8>] (rcu_dump_cpu_stacks) from [<c0188224>] (rcu_sched_clock_irq+0x798/0x950)
> [   65.485707] [<c0188224>] (rcu_sched_clock_irq) from [<c0193608>] (update_process_times+0x9c/0xd0)
> [   65.494581] [<c0193608>] (update_process_times) from [<c01a5b14>] (tick_sched_timer+0x7c/0xf0)
> [   65.503197] [<c01a5b14>] (tick_sched_timer) from [<c0193e3c>] (__hrtimer_run_queues+0x15c/0x218)
> [   65.511984] [<c0193e3c>] (__hrtimer_run_queues) from [<c0194efc>] (hrtimer_interrupt+0x124/0x2b0)
> [   65.520857] [<c0194efc>] (hrtimer_interrupt) from [<c06a552c>] (arch_timer_handler_phys+0x28/0x30)
> [   65.529820] [<c06a552c>] (arch_timer_handler_phys) from [<c017a654>] (handle_percpu_devid_irq+0x78/0x13c)
> [   65.539388] [<c017a654>] (handle_percpu_devid_irq) from [<c01742fc>] (handle_domain_irq+0x5c/0x78)
> [   65.548352] [<c01742fc>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
> [   65.556533] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
> [   65.564017] Exception stack(0xc1b79a30 to 0xc1b79a78)
> [   65.569067] 9a20:                                     00000000 00000000 000003dc 000003da
> [   65.577238] 9a40: c3f40268 ffffe000 00000000 c1b78000 00000002 00000000 c3f40268 c0de5100
> [   65.585408] 9a60: c0b496d0 c1b79a80 c016c5b0 c016c538 80000113 ffffffff
> [   65.592015] [<c0100afc>] (__irq_svc) from [<c016c538>] (do_raw_spin_lock+0x78/0x120)
> [   65.599759] [<c016c538>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
> [   65.607765] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
> [   65.615255] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
> [   65.623960] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
> [   65.633440] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
> [   65.642747] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
> [   65.651447] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
> [   65.659193] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
> [   65.668329] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
> [   65.679196] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
> [   65.689108] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
> [   65.697982] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
> [   65.706159] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
> [   65.713816] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
> [   65.721647] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
> [   65.728960] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
> [   65.736620] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
> [   65.744799] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
> [   65.752281] Exception stack(0xc1b79e38 to 0xc1b79e80)
> [   65.757329] 9e20:                                                       c1c13c00 c0de5100
> [   65.765500] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
> [   65.773671] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
> [   65.781837] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> [   65.789929] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> [   65.798196] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> [   65.806552] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> [   65.815686] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> [   65.824384] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
> [   65.832827] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
> [   65.840574] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
> [   65.847799] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
> [   65.852847] 9fa0:                                     00000000 00000000 00000000 00000000
> [   65.861017] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [   65.869186] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [  128.458402] rcu: INFO: rcu_sched self-detected stall on CPU
> [  128.463984] rcu: 	0-....: (8328 ticks this GP) idle=afd/1/0x40000004 softirq=3056/3057 fqs=3872 
> [  128.472769] 	(t=8408 jiffies g=1437 q=435)
> [  128.476867] NMI backtrace for cpu 0
> [  128.480354] CPU: 0 PID: 111 Comm: 1c15000.crypto- Not tainted 5.15.13-00003-g14f78eca130d #199
> [  128.488958] Hardware name: Allwinner sun8i Family
> [  128.493660] [<c010d7a0>] (unwind_backtrace) from [<c0109fa0>] (show_stack+0x10/0x14)
> [  128.501413] [<c0109fa0>] (show_stack) from [<c0857fc4>] (dump_stack_lvl+0x40/0x4c)
> [  128.508985] [<c0857fc4>] (dump_stack_lvl) from [<c042dc1c>] (nmi_cpu_backtrace+0xdc/0x110)
> [  128.517252] [<c042dc1c>] (nmi_cpu_backtrace) from [<c042dd58>] (nmi_trigger_cpumask_backtrace+0x108/0x168)
> [  128.526904] [<c042dd58>] (nmi_trigger_cpumask_backtrace) from [<c0856bf8>] (rcu_dump_cpu_stacks+0x128/0x15c)
> [  128.536730] [<c0856bf8>] (rcu_dump_cpu_stacks) from [<c0188224>] (rcu_sched_clock_irq+0x798/0x950)
> [  128.545691] [<c0188224>] (rcu_sched_clock_irq) from [<c0193608>] (update_process_times+0x9c/0xd0)
> [  128.554564] [<c0193608>] (update_process_times) from [<c01a5b14>] (tick_sched_timer+0x7c/0xf0)
> [  128.563179] [<c01a5b14>] (tick_sched_timer) from [<c0193e3c>] (__hrtimer_run_queues+0x15c/0x218)
> [  128.571966] [<c0193e3c>] (__hrtimer_run_queues) from [<c0194efc>] (hrtimer_interrupt+0x124/0x2b0)
> [  128.580838] [<c0194efc>] (hrtimer_interrupt) from [<c06a552c>] (arch_timer_handler_phys+0x28/0x30)
> [  128.589800] [<c06a552c>] (arch_timer_handler_phys) from [<c017a654>] (handle_percpu_devid_irq+0x78/0x13c)
> [  128.599369] [<c017a654>] (handle_percpu_devid_irq) from [<c01742fc>] (handle_domain_irq+0x5c/0x78)
> [  128.608332] [<c01742fc>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
> [  128.616514] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
> [  128.623997] Exception stack(0xc1b79a30 to 0xc1b79a78)
> [  128.629047] 9a20:                                     00000000 00000000 000003dc 000003da
> [  128.637218] 9a40: c3f40268 ffffe000 00000000 c1b78000 00000002 00000000 c3f40268 c0de5100
> [  128.645388] 9a60: c0b496d0 c1b79a80 c016c5b0 c016c538 80000113 ffffffff
> [  128.651995] [<c0100afc>] (__irq_svc) from [<c016c538>] (do_raw_spin_lock+0x78/0x120)
> [  128.659738] [<c016c538>] (do_raw_spin_lock) from [<c0809034>] (xfrm_input+0x17c/0x1304)
> [  128.667744] [<c0809034>] (xfrm_input) from [<c07f9804>] (xfrm4_esp_rcv+0x44/0x84)
> [  128.675233] [<c07f9804>] (xfrm4_esp_rcv) from [<c0794c58>] (ip_protocol_deliver_rcu+0x2c/0x2b8)
> [  128.683936] [<c0794c58>] (ip_protocol_deliver_rcu) from [<c0794f48>] (ip_local_deliver_finish+0x64/0x80)
> [  128.693408] [<c0794f48>] (ip_local_deliver_finish) from [<c0793f58>] (ip_sublist_rcv_finish+0x3c/0x50)
> [  128.702716] [<c0793f58>] (ip_sublist_rcv_finish) from [<c0794af8>] (ip_sublist_rcv+0x180/0x1a0)
> [  128.711417] [<c0794af8>] (ip_sublist_rcv) from [<c07952d8>] (ip_list_rcv+0xf0/0x110)
> [  128.719163] [<c07952d8>] (ip_list_rcv) from [<c0735f5c>] (__netif_receive_skb_list_core+0x194/0x1fc)
> [  128.728299] [<c0735f5c>] (__netif_receive_skb_list_core) from [<c07361b0>] (netif_receive_skb_list_internal+0x1ec/0x304)
> [  128.739165] [<c07361b0>] (netif_receive_skb_list_internal) from [<c0736ef0>] (napi_complete_done+0x130/0x1c8)
> [  128.749077] [<c0736ef0>] (napi_complete_done) from [<c05ab408>] (stmmac_napi_poll_rx+0xa7c/0xbd8)
> [  128.757951] [<c05ab408>] (stmmac_napi_poll_rx) from [<c0736fb0>] (__napi_poll+0x28/0x170)
> [  128.766129] [<c0736fb0>] (__napi_poll) from [<c0737364>] (net_rx_action+0xf0/0x278)
> [  128.773786] [<c0737364>] (net_rx_action) from [<c010126c>] (__do_softirq+0x104/0x29c)
> [  128.781617] [<c010126c>] (__do_softirq) from [<c01231ac>] (irq_exit+0xbc/0x100)
> [  128.788930] [<c01231ac>] (irq_exit) from [<c0174300>] (handle_domain_irq+0x60/0x78)
> [  128.796589] [<c0174300>] (handle_domain_irq) from [<c044000c>] (gic_handle_irq+0x7c/0x90)
> [  128.804768] [<c044000c>] (gic_handle_irq) from [<c0100afc>] (__irq_svc+0x5c/0x78)
> [  128.812250] Exception stack(0xc1b79e38 to 0xc1b79e80)
> [  128.817298] 9e20:                                                       c1c13c00 c0de5100
> [  128.825469] 9e40: c1b78000 00000002 c3f40240 ffffe000 ec010000 c1b78000 00000002 00000000
> [  128.833640] 9e60: c3f40268 c0de5100 c3c369c0 c1b79e88 c0809388 c080b9d4 a0000113 ffffffff
> [  128.841806] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> [  128.849898] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> [  128.858163] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> [  128.866518] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> [  128.875651] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> [  128.884349] [<c03a4264>] (crypto_pump_work) from [<c013e448>] (kthread_worker_fn+0xd8/0x220)
> [  128.892790] [<c013e448>] (kthread_worker_fn) from [<c013f708>] (kthread+0x15c/0x180)
> [  128.900537] [<c013f708>] (kthread) from [<c0100130>] (ret_from_fork+0x14/0x24)
> [  128.907760] Exception stack(0xc1b79fb0 to 0xc1b79ff8)
> [  128.912809] 9fa0:                                     00000000 00000000 00000000 00000000
> [  128.920978] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [  128.929147] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
> 
> None on my drivers are using spinlock so the only one which remains is crypto/engine one (queue_lock)
> 
> I have started to bisect this, but this lead to unrelated commits. (I tried twice with different starting point)
> 
> Known broken version are
> 5.13 5.14 5.15.13 next-20220105 5.10
> I randomly hit also "NOHZ tick-stop error: Non-RCU local softirq work is pending, handler #08!!!".
> On 5.6 and 5.7 I got: NOHZ: local_softirq_pending 08
> 
> Working version are 5.4.170 and 5.5
> 
> The normal iperf performance is at least 30Mbit/s, when bug is present, iperf never end.
> But When the bug is present with "NOHZ: local_softirq_pending 08", iperf give 1Mbit/s.
> 
> I started also to test other crypto driver which use the crypto/crypto_engine
> On my sun8i-ss, no kernel trace are given, but iperf performance decrease is present.
> I also tested omap-aes and it seems un-impacted.
> 
> Any help to debug that is welcome.
> Thanks in advance
> 
> Regards
> 


From arnd at arndb.de  Wed Jan 12 04:08:24 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 12 Jan 2022 13:08:24 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <f86483fca8b0dc68ce243ba47998ff3296a3b6f8.camel@kernel.org>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
 <20220112075609.GA4854@lst.de>
 <CAK8P3a1ONn=FiPU3669MjBMntS-1K5bgX4pHforUsYJ7yhwZ-g@mail.gmail.com>
 <f86483fca8b0dc68ce243ba47998ff3296a3b6f8.camel@kernel.org>
Message-ID: <CAK8P3a3FgHQ+w+Sj00yOERRLWfVhx7NYsGJ1NBAXQ0=is3G=Kg@mail.gmail.com>

On Wed, Jan 12, 2022 at 12:15 PM Jeff Layton <jlayton at kernel.org> wrote:
> On Wed, 2022-01-12 at 09:28 +0100, Arnd Bergmann wrote:
> > On Wed, Jan 12, 2022 at 8:56 AM Christoph Hellwig <hch at lst.de> wrote:
> >
> > Exactly, that is the tradeoff, which is why I'd like the flock maintainers
> > to say which way they prefer. We can either do it more correctly (hiding
> > the constants from user space when they are not usable), or with less
> > change (removing the incorrect #ifdef). Either way sounds reasonable
> > to me, I mainly care that this is explained in the changelog and that the
> > maintainers are aware of the two options.
> >
>
> I don't have a strong opinion here. If we were taking symbols away that
> were previously visible to userland it would be one thing, but since
> we're just adding symbols that may not have been there before, this
> seems less likely to break anything.

Changing

#ifndef CONFIG_64BIT

to

#if __BITS_PER_LONG==32 || defined(__KERNEL__),

would take symbols away, since the CONFIG_64BIT macro is never
set in user space.

> I probably lean toward Christoph's original solution instead of keeping
> the conditional definitions. It's hard to imagine there are many
> programs that care whether these other symbols are defined or not.
>
> You can add this to the original patch:
>
> Acked-by: Jeff Layton <jlayton at kernel.org>

Sounds good, thanks

         Arnd


From jianhua.ljh at gmail.com  Wed Jan 12 04:21:57 2022
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Wed, 12 Jan 2022 20:21:57 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <dbcbc161-228d-ee78-e1f0-b59ad9b0a36f@huawei.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
 <dbcbc161-228d-ee78-e1f0-b59ad9b0a36f@huawei.com>
Message-ID: <CAAgTQPUEgSf-E_GOUNY_=4Piiy0K_-5U_YVbnoMAZ94Q3ducOg@mail.gmail.com>

On Wed, Jan 12, 2022 at 9:31 AM liuqi (BA) <liuqi115 at huawei.com> wrote:
>
>
>
> On 2022/1/4 10:35, Masami Hiramatsu wrote:
> > Hi Jianhua,
> >
> > On Mon, 3 Jan 2022 17:03:33 +0800
> > Jianhua Liu <jianhua.ljh at gmail.com> wrote:
> >
> >> Hi Qi,
> >> I have tested your patch on UNISOC s9863a.
> >> Test case "kprobe_example & kretprobe_example" is OK.
> >>
> >> Two point:
> >> 1. backtrace is not perfect.
> >>     optprobe_common does not saved frame pointer,
> >>     backtrace lacks two calls.
> >> such as for dup_mm: lack copy_process-->dup_mm
> >> dup_mm backtrace from your patch:
> >> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
> >> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> >> [  832.387083] Call trace:
> >> [  832.387086]  dump_backtrace+0x0/0x1e0
> >> [  832.387103]  show_stack+0x24/0x30
> >> [  832.387112]  dump_stack_lvl+0x68/0x84
> >> [  832.387123]  dump_stack+0x18/0x34
> >> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
> >> [  832.387143]  opt_pre_handler+0x84/0xc0
> >> [  832.387154]  optprobe_optimized_callback+0xec/0x164
> >> [  832.387164]  optprobe_common+0x70/0xc4
> >> [  832.387173]  kernel_clone+0x98/0x440
> >> [  832.387182]  __do_sys_clone+0x54/0x80
> >> [  832.387191]  __arm64_sys_clone+0x2c/0x40
> >> [  832.387199]  invoke_syscall+0x50/0x120
> >> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
> >> [  832.387217]  do_el0_svc+0x30/0x9c
> >> [  832.387225]  el0_svc+0x20/0x60
> >> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
> >> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
> >>
> >>
> >> dup_mm backtrace from other:
> >> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
> >> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> >> [  173.352304] Call trace:
> >> [  173.352307]  dump_backtrace+0x0/0x1d4
> >> [  173.352319]  show_stack+0x18/0x24
> >> [  173.352326]  dump_stack_lvl+0x68/0x84
> >> [  173.352333]  dump_stack+0x18/0x34
> >> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
> >> [  173.352347]  opt_pre_handler+0x74/0xb0
> >> [  173.352354]  optimized_callback+0x108/0x130
> >> [  173.352361]  optinsn_slot+0x258/0x1000
> >> [  173.352366]  dup_mm+0x4/0x4b0
> >> [  173.352373]  copy_process+0x1284/0x1360
> >> [  173.352378]  kernel_clone+0x5c/0x3c0
> >> [  173.352384]  __do_sys_clone+0x54/0x80
> >> [  173.352390]  __arm64_sys_clone+0x24/0x30
> >> [  173.352396]  invoke_syscall+0x48/0x114
> >> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
> >> [  173.352408]  do_el0_svc+0x24/0x90
> >> [  173.352413]  el0_svc+0x20/0x60
> >> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
> >> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
> >
>
> Hi Masami and Jianhua,
>
> optprobe_common() is added to minize size of code in trampoline, but
> each trampoline is alloced as PAGE_SIZE, so optprobe_common() seems
> unnecessary, and will make optprobe_trampoline.S much more complicated.
> How about drop optprobe_common() and use a maro to reduce duplicate code .
>
1. each trampoline is allocated as
(MAX_OPTINSN_SIZE*sizeof(kprobe_opcode_t)), not PAGE_SIZE
2. MAX_OPTINSN_SIZE should be "((unsigned long)(optprobe_template_end
- optprobe_template_entry)),
   your MAX_OPTINSN_SIZE  is not accurate.

3.optprobe_template_val in different kprobe may not be aligned with 8 byte.
   ldr instruction for this value, may use address that not aligned 8 byte.
   "ldr x0, 1f
   .global optprobe_template_common"

Thanks,
Jianhua
> Thanks,
> Qi
> > Is the second one with your patch?
> >
> >>
> >> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
> >>     kernel/kprobe.c used only one PAGE_SIZE slot memory.
> >
> > Good catch!
> > Qi, can you make an array (or bit map) of usage flags and
> > manage the reserved memory?
> >
> > #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
> > static bool insn_page_in_use[OPT_INSN_PAGES];
> >
> > void *alloc_optinsn_page(void)
> > {
> >       int i;
> >
> >       for (i = 0; i < OPT_INSN_PAGES; i++)
> >               if (!insn_page_in_use[i])
> >                       goto found;
> >       return NULL;
> > found:
> >       insn_page_in_use[i] = true;
> >       return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
> > }
> >
> > void free_optinsn_page(void *page)
> > {
> >       unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
> >
> >       WARN_ONCE(idx & (PAGE_SIZE - 1));
> >       idx >>= PAGE_SHIFT;
> >       if (WARN_ONCE(idx >= OPT_INSN_PAGES))
> >               return;
> >       insn_page_in_use[idx] = false;
> > }
> >
> > Thank you,
> >
> >
> >
> >


From Eugen.Hristev at microchip.com  Wed Jan 12 04:46:44 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Wed, 12 Jan 2022 12:46:44 +0000
Subject: [PATCH v3 00/23] media: atmel: atmel-isc: implement media
 controller
In-Reply-To: <50bb6274-b004-eff7-56d5-68ec8e10d3c4@xs4all.nl>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <50bb6274-b004-eff7-56d5-68ec8e10d3c4@xs4all.nl>
Message-ID: <6cf11fa8-2a9c-badf-2243-a7ead42aa91c@microchip.com>

On 1/12/22 2:07 PM, Hans Verkuil wrote:
> Hi Eugen,
> 
> On 13/12/2021 14:49, Eugen Hristev wrote:
>> This series is the v3 of the series that attempts to support media controller
>> in the atmel ISC and XISC drivers.
>> This series also includes the csi2dc driver which was previously sent in a
>> separate series:
>> https://www.spinics.net/lists/linux-media/msg181042.html
>> https://www.spinics.net/lists/linux-media/msg181044.html
>> The driver now addresses comments received in latest v5 series from last year.
>>
>> The series includes some minor changes and fixes that improve the isc common
>> code base, like removing the enum frameintervals VIDIOC, fixing bytesperline
>> for planar formats, etc.
>>
>> Many thanks to folks from libcamera who helped a lot with understanding
>> how a media controller driver should behave.
>>
>> Feedback is welcome !
>>
>> Changes in v3:
>> - change in bindings, small fixes in csi2dc driver and conversion to mc
>> for the isc-base.
>> - removed some MAINTAINERS patches and used patterns in MAINTAINERS
>>
>> Changes in v2:
>> - integrated many changes suggested by Jacopo in the review of the v1 series.
>> - add a few new patches
> 
> Based on the current review status I think it would make sense to add
> the following patches from this series to a PR:
> 
> 1-6, 8-9, 11, 16, 18-22.
> 
> Are there any patches (esp. 11 and later) that require other patches
> not in this list? In other words, does this make sense?

Hello Hans,

Yes, this sounds good . I will rework the patches that are left next week.
Then I will send a v4 of this series with only the patches that are not 
yet applied. And I will rebase it on top of the media tree.

Thanks for reviewing !

Eugen
> 
> Regards,
> 
>          Hans
> 
>>
>>
>> Eugen Hristev (23):
>>    MAINTAINERS: add microchip csi2dc
>>    dt-bindings: media: atmel: csi2dc: add bindings for microchip csi2dc
>>    media: atmel: introduce microchip csi2dc driver
>>    media: atmel: atmel-isc: split the clock code into separate source
>>      file
>>    media: atmel: atmel-isc: replace video device name with module name
>>    media: atmel: atmel-sama7g5-isc: fix ispck leftover
>>    media: atmel: atmel-isc-base: use streaming status when queueing
>>      buffers
>>    media: atmel: atmel-isc-base: remove frameintervals VIDIOC
>>    media: atmel: atmel-isc-base: report frame sizes as full supported
>>      range
>>    media: atmel: atmel-isc-base: implement mbus_code support in enumfmt
>>    media: atmel: atmel-isc-base: fix bytesperline value for planar
>>      formats
>>    media: atmel: atmel-isc: implement media controller
>>    ARM: dts: at91: sama7g5: add nodes for video capture
>>    ARM: configs: at91: sama7: add xisc and csi2dc
>>    ARM: multi_v7_defconfig: add atmel video pipeline modules
>>    media: atmel: atmel-sama5d2-isc: fix wrong mask in YUYV format check
>>    media: atmel: atmel-isc-base: use mutex to lock awb workqueue from
>>      streaming
>>    media: atmel: atmel-isc-base: add wb debug messages
>>    media: atmel: atmel-isc-base: clamp wb gain coefficients
>>    media: atmel: atmel-sama7g5-isc: fix UYVY input format mbus_code typo
>>    media: atmel: atmel-isc: add raw Bayer 8bit 10bit output formats
>>    media: atmel: atmel-isc: compact the controller formats list
>>    media: atmel: atmel-isc: change format propagation to subdev into only
>>      verification
>>
>>   .../bindings/media/microchip,csi2dc.yaml      | 197 +++++
>>   MAINTAINERS                                   |  14 +-
>>   arch/arm/boot/dts/sama7g5.dtsi                |  48 ++
>>   arch/arm/configs/multi_v7_defconfig           |   3 +
>>   arch/arm/configs/sama7_defconfig              |   2 +
>>   drivers/media/platform/Makefile               |   1 +
>>   drivers/media/platform/atmel/Kconfig          |  15 +
>>   drivers/media/platform/atmel/Makefile         |   4 +-
>>   drivers/media/platform/atmel/atmel-isc-base.c | 790 ++++++-----------
>>   drivers/media/platform/atmel/atmel-isc-clk.c  | 311 +++++++
>>   drivers/media/platform/atmel/atmel-isc-mc.c   | 287 +++++++
>>   drivers/media/platform/atmel/atmel-isc.h      |  49 ++
>>   .../media/platform/atmel/atmel-sama5d2-isc.c  |  59 +-
>>   .../media/platform/atmel/atmel-sama7g5-isc.c  |  72 +-
>>   .../media/platform/atmel/microchip-csi2dc.c   | 806 ++++++++++++++++++
>>   15 files changed, 2085 insertions(+), 573 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/media/microchip,csi2dc.yaml
>>   create mode 100644 drivers/media/platform/atmel/atmel-isc-clk.c
>>   create mode 100644 drivers/media/platform/atmel/atmel-isc-mc.c
>>   create mode 100644 drivers/media/platform/atmel/microchip-csi2dc.c
>>
> 


From jiaxun.yang at flygoat.com  Wed Jan 12 04:57:44 2022
From: jiaxun.yang at flygoat.com (Jiaxun Yang)
Date: Wed, 12 Jan 2022 12:57:44 +0000
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20220111214608.GA169999@bhelgaas>
References: <20220111214608.GA169999@bhelgaas>
Message-ID: <013cc25a-d460-49eb-8cc0-8f59a0c5a45e@www.fastmail.com>



?2022?1?11??? ??9:46?Bjorn Helgaas???
> [-cc many, +cc iproc, loongson, tegra maintainers]
>
> On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
>> The majority of DT based host drivers use the default .map_irq() and
>> .swizzle_irq() functions, so let's initialize the function pointers to
>> the default and drop setting them in the host drivers.
>> 
>> Drivers like iProc which don't support legacy interrupts need to set
>> .map_irq() back to NULL.
>
> Probably a dumb question...
>
> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.
>
> My question is why we still have a few users of ->map_irq: loongson,
> tegra, iproc.  Shouldn't this mapping be described somehow via DT?
>

Hi all,

For Loongson we are describing IRQ map in DT for newer platforms.
But for legacy platforms (AMD RS780E North Bridge) with i8259 irqchip,
we need to read PCI IRQ registers to get mapping information.

It is not known until boot time, so we have to use map_irq callback.

Thanks.
- Jiaxun

[...]

-- 
- Jiaxun


From gary.bisson at boundarydevices.com  Wed Jan 12 05:01:15 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 14:01:15 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
 <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com>
Message-ID: <Yd7RG80hhjZilGs7@p1g2>

Hi,

On Wed, Jan 12, 2022 at 09:33:42AM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 03/01/2022 16:46, Gary Bisson wrote:
> > - RX/TX signals can be mapped on 2 different pairs of pins so supporting
> >   both options
> > - RTS/CTS signals however only have 1 option available
> > 
> > Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> > ---
> > Cc: Rob Herring <robh+dt at kernel.org>
> > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > Cc: Kevin Hilman <khilman at baylibre.com>
> > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > Cc: devicetree at vger.kernel.org
> > Cc: linux-arm-kernel at lists.infradead.org
> > Cc: linux-kernel at vger.kernel.org
> > ---
> >  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
> >  1 file changed, 27 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > index af1357c48bee..3a7773ffbd08 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> > @@ -1952,6 +1952,33 @@ mux {
> >  						};
> >  					};
> >  
> > +					uart_ao_b_1_pins: uart-ao-b-1 {
> > +						mux {
> > +							groups = "uart_ao_b_tx_2",
> > +								 "uart_ao_b_rx_3";
> > +							function = "uart_ao_b";
> > +							bias-disable;
> > +						};
> > +					};
> > +
> > +					uart_ao_b_2_pins: uart-ao-b-2 {
> > +						mux {
> > +							groups = "uart_ao_b_tx_8",
> > +								 "uart_ao_b_rx_9";
> > +							function = "uart_ao_b";
> > +							bias-disable;
> > +						};
> > +					};
> 
> I'm not fan of these nodes namings.
> 
> Perhaps :
> - uart-ao-b-2-3
> - uart-ao-b-8-9
> 
> so the actual pins numbers used are more clear ?

Sure, I wasn't convinced by that naming either. I although thought
about:
- uart-ao-b
- uart-ao-b-alt

Let me know which one you prefer and I'll respin the patch.
Also let me know if I should re-send the entire series or just this
patch.

Regards,
Gary


From aisheng.dong at nxp.com  Wed Jan 12 05:15:50 2022
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Wed, 12 Jan 2022 21:15:50 +0800
Subject: [PATCH v2 0/2] mm: fix cma allocation fail sometimes
Message-ID: <20220112131552.3329380-1-aisheng.dong@nxp.com>

We observed an issue with NXP 5.15 LTS kernel that dma_alloc_coherent()
may fail sometimes when there're multiple processes trying to allocate
CMA memory.

This issue can be very easily reproduced on MX6Q SDB board with latest
linux-next kernel by writing a test module creating 16 or 32 threads
allocating random size of CMA memory in parallel at the background.
Or simply enabling CONFIG_CMA_DEBUG, you can see endless of CMA alloc
retries during booting:
[    1.452124] cma: cma_alloc(): memory range at (ptrval) is busy,retrying
....
(thousands of reties)
NOTE: MX6 has CONFIG_FORCE_MAX_ZONEORDER=14 which means MAX_ORDER is
13 (32M).

The root cause of this issue is that since commit a4efc174b382
("mm/cma.c: remove redundant cma_mutex lock"), CMA supports concurrent
memory allocation.
It's possible that the pageblock process A try to alloc has already
been isolated by the allocation of process B during memory migration.

When there're multi process allocating CMA memory in parallel, it's
likely that other the remain pageblocks may have also been isolated,
then CMA alloc fail finally during the first round of scanning of the
whole available CMA bitmap.

This patchset introduces a retry mechanism to rescan CMA bitmap for -EBUSY
error in case the target pageblock may has been temporarily isolated
by others and released later.
It also improves the CMA allocation performance by trying the next
pageblock during reties rather than looping in the same pageblock
which is in -EBUSY state.

Theoretically, this issue can be easily reproduced on ARMv7 platforms
with big MAX_ORDER/pageblock 
e.g. 1G RAM(320M reserved CMA) and 32M pageblock ARM platform:
Page block order: 13
Pages per block:  8192

The following test is based on linux-next: next-20211213.

Without the fix, it's easily fail.
# insmod cma_alloc.ko pnum=16
[  274.322369] CMA alloc test enter: thread number: 16
[  274.329948] cpu: 0, pid: 692, index 4 pages 144
[  274.330143] cpu: 1, pid: 694, index 2 pages 44
[  274.330359] cpu: 2, pid: 695, index 7 pages 757
[  274.330760] cpu: 2, pid: 696, index 4 pages 144
[  274.330974] cpu: 2, pid: 697, index 6 pages 512
[  274.331223] cpu: 2, pid: 698, index 6 pages 512
[  274.331499] cpu: 2, pid: 699, index 2 pages 44
[  274.332228] cpu: 2, pid: 700, index 0 pages 7
[  274.337421] cpu: 0, pid: 701, index 1 pages 38
[  274.337618] cpu: 2, pid: 702, index 0 pages 7
[  274.344669] cpu: 1, pid: 703, index 0 pages 7
[  274.344807] cpu: 3, pid: 704, index 6 pages 512
[  274.348269] cpu: 2, pid: 705, index 5 pages 148
[  274.349490] cma: cma_alloc: reserved: alloc failed, req-size: 38 pages, ret: -16
[  274.366292] cpu: 1, pid: 706, index 4 pages 144
[  274.366562] cpu: 0, pid: 707, index 3 pages 128
[  274.367356] cma: cma_alloc: reserved: alloc failed, req-size: 128 pages, ret: -16
[  274.367370] cpu: 0, pid: 707, index 3 pages 128 failed
[  274.371148] cma: cma_alloc: reserved: alloc failed, req-size: 148 pages, ret: -16
[  274.375348] cma: cma_alloc: reserved: alloc failed, req-size: 144 pages, ret: -16
[  274.384256] cpu: 2, pid: 708, index 0 pages 7
....

With the fix, 32 threads allocating in parallel can pass overnight
stress test.

root at imx6qpdlsolox:~# insmod cma_alloc.ko pnum=32
[  112.976809] cma_alloc: loading out-of-tree module taints kernel.
[  112.984128] CMA alloc test enter: thread number: 32
[  112.989748] cpu: 2, pid: 707, index 6 pages 512
[  112.994342] cpu: 1, pid: 708, index 6 pages 512
[  112.995162] cpu: 0, pid: 709, index 3 pages 128
[  112.995867] cpu: 2, pid: 710, index 0 pages 7
[  112.995910] cpu: 3, pid: 711, index 2 pages 44
[  112.996005] cpu: 3, pid: 712, index 7 pages 757
[  112.996098] cpu: 3, pid: 713, index 7 pages 757
...
[41877.368163] cpu: 1, pid: 737, index 2 pages 44
[41877.369388] cpu: 1, pid: 736, index 3 pages 128
[41878.486516] cpu: 0, pid: 737, index 2 pages 44
[41878.486515] cpu: 2, pid: 739, index 4 pages 144
[41878.486622] cpu: 1, pid: 736, index 3 pages 128
[41878.486948] cpu: 2, pid: 735, index 7 pages 757
[41878.487279] cpu: 2, pid: 738, index 4 pages 144
[41879.526603] cpu: 1, pid: 739, index 3 pages 128
[41879.606491] cpu: 2, pid: 737, index 3 pages 128
[41879.606550] cpu: 0, pid: 736, index 0 pages 7
[41879.612271] cpu: 2, pid: 738, index 4 pages 144
...

v1:
https://patchwork.kernel.org/project/linux-mm/cover/20211215080242.3034856-1-aisheng.dong at nxp.com/

Dong Aisheng (2):
  mm: cma: fix allocation may fail sometimes
  mm: cma: try next MAX_ORDER_NR_PAGES during retry

 mm/cma.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

-- 
2.25.1



From aisheng.dong at nxp.com  Wed Jan 12 05:15:51 2022
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Wed, 12 Jan 2022 21:15:51 +0800
Subject: [PATCH v2 1/2] mm: cma: fix allocation may fail sometimes
In-Reply-To: <20220112131552.3329380-1-aisheng.dong@nxp.com>
References: <20220112131552.3329380-1-aisheng.dong@nxp.com>
Message-ID: <20220112131552.3329380-2-aisheng.dong@nxp.com>

We met dma_alloc_coherent() fail sometimes when doing 8 VPU decoder
test in parallel on a MX6Q SDB board.

Error log:
cma: cma_alloc: linux,cma: alloc failed, req-size: 148 pages, ret: -16
cma: number of available pages:
3 at 125+20@172+12 at 236+4@380+32 at 736+17@2287+23 at 2473+20@36076+99 at 40477+108@40852+44 at 41108+20@41196+108 at 41364+108@41620+
108 at 42900+108@43156+483 at 44061+1763@45341+1440 at 47712+20@49324+20 at 49388+5076@49452+2304 at 55040+35@58141+20 at 58220+20@58284+
7188 at 58348+84@66220+7276 at 66452+227@74525+6371 at 75549=> 33161 free of 81920 total pages

When issue happened, we saw there were still 33161 pages (129M) free CMA
memory and a lot available free slots for 148 pages in CMA bitmap that we
want to allocate.

If dumping memory info, we found that there was also ~342M normal memory,
but only 1352K CMA memory left in buddy system while a lot of pageblocks
were isolated.

Memory info log:
Normal free:351096kB min:30000kB low:37500kB high:45000kB reserved_highatomic:0KB
	    active_anon:98060kB inactive_anon:98948kB active_file:60864kB inactive_file:31776kB
	    unevictable:0kB writepending:0kB present:1048576kB managed:1018328kB mlocked:0kB
	    bounce:0kB free_pcp:220kB local_pcp:192kB free_cma:1352kB lowmem_reserve[]: 0 0 0
Normal: 78*4kB (UECI) 1772*8kB (UMECI) 1335*16kB (UMECI) 360*32kB (UMECI) 65*64kB (UMCI)
	36*128kB (UMECI) 16*256kB (UMCI) 6*512kB (EI) 8*1024kB (UEI) 4*2048kB (MI) 8*4096kB (EI)
	8*8192kB (UI) 3*16384kB (EI) 8*32768kB (M) = 489288kB

The root cause of this issue is that since commit a4efc174b382
("mm/cma.c: remove redundant cma_mutex lock"), CMA supports concurrent
memory allocation. It's possible that the pageblock process A try to alloc
has already been isolated by the allocation of process B during memory
migration.

When there're multi process allocating CMA memory in parallel, it's
likely that other the remain pageblocks may have also been isolated,
then CMA alloc fail finally during the first round of scanning of the
whole available CMA bitmap.

This patch introduces a retry mechanism to rescan CMA bitmap for -EBUSY
error in case the target pageblock may has been temporarily isolated
by others and released later.

Theoretically, this issue can be easily reproduced on ARMv7 platforms
with big MAX_ORDER/pageblock
e.g. 1G RAM(320M reserved CMA) and 32M pageblock ARM platform:
Page block order: 13
Pages per block:  8192

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Lecopzer Chen <lecopzer.chen at mediatek.com>
Cc: David Hildenbrand <david at redhat.com>
Cc: Vlastimil Babka <vbabka at suse.cz>
CC: stable at vger.kernel.org # 5.11+
Fixes: a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock")
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
ChangeLog:
 * v1->v2: no changes
---
 mm/cma.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/mm/cma.c b/mm/cma.c
index bc9ca8f3c487..1c13a729d274 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -433,6 +433,7 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
 	unsigned long i;
 	struct page *page = NULL;
 	int ret = -ENOMEM;
+	int loop = 0;
 
 	if (!cma || !cma->count || !cma->bitmap)
 		goto out;
@@ -460,6 +461,16 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
 				offset);
 		if (bitmap_no >= bitmap_maxno) {
 			spin_unlock_irq(&cma->lock);
+			pr_debug("%s(): alloc fail, retry loop %d\n", __func__, loop++);
+			/*
+			 * rescan as others may finish the memory migration
+			 * and quit if no available CMA memory found finally
+			 */
+			if (start) {
+				schedule();
+				start = 0;
+				continue;
+			}
 			break;
 		}
 		bitmap_set(cma->bitmap, bitmap_no, bitmap_count);
-- 
2.25.1



From aisheng.dong at nxp.com  Wed Jan 12 05:15:52 2022
From: aisheng.dong at nxp.com (Dong Aisheng)
Date: Wed, 12 Jan 2022 21:15:52 +0800
Subject: [PATCH v2 2/2] mm: cma: try next MAX_ORDER_NR_PAGES during retry
In-Reply-To: <20220112131552.3329380-1-aisheng.dong@nxp.com>
References: <20220112131552.3329380-1-aisheng.dong@nxp.com>
Message-ID: <20220112131552.3329380-3-aisheng.dong@nxp.com>

On an ARMv7 platform with 32M pageblock(MAX_ORDER 14), we observed a
huge number of repeat retries of CMA allocation (1k+) during booting
when allocating one page for each of 3 mmc instance probe.

This is caused by CMA now supports cocurrent allocation since commit
a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock").
The pageblock or (MAX_ORDER -1) from which we are trying to allocate
memory may have already been acquired and isolated by others.
Current cma_alloc() will then retry the next area by the step of
bitmap_no + mask + 1 which are very likely within the same isolated range
and fail again. So when the pageblock or MAX_ORDER is big (e.g. 8192),
keep retrying in a small step become meaningless because it will be known
to fail at a huge number of times due to the pageblock has been isolated
by others, especially when allocating only one or two pages.

Instread of looping in the same pageblock and wasting CPU mips a lot,
especially for big pageblock system (e.g. 16M or 32M),
we try the next MAX_ORDER_NR_PAGES directly.

Doing this way can greatly mitigate the situtation.

Below is the original error log during booting:
[    2.004804] cma: cma_alloc(cma (ptrval), count 1, align 0)
[    2.010318] cma: cma_alloc(cma (ptrval), count 1, align 0)
[    2.010776] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
[    2.010785] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
[    2.010793] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
[    2.010800] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
[    2.010807] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
[    2.010814] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
.... (+1K retries)

After fix, the 1200+ reties can be reduced to 0.
Another test running 8 VPU decoder in parallel shows that 1500+ retries
dropped to ~145.

IOW this patch can improve the CMA allocation speed a lot when there're
enough CMA memory by reducing retries significantly.

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Marek Szyprowski <m.szyprowski at samsung.com>
Cc: Lecopzer Chen <lecopzer.chen at mediatek.com>
Cc: David Hildenbrand <david at redhat.com>
Cc: Vlastimil Babka <vbabka at suse.cz>
CC: stable at vger.kernel.org # 5.11+
Fixes: a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock")
Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
---
v1->v2:
 * change to align with MAX_ORDER_NR_PAGES instead of pageblock_nr_pages
---
 mm/cma.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mm/cma.c b/mm/cma.c
index 1c13a729d274..1251f65e2364 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -500,7 +500,9 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
 		trace_cma_alloc_busy_retry(cma->name, pfn, pfn_to_page(pfn),
 					   count, align);
 		/* try again with a bit different memory target */
-		start = bitmap_no + mask + 1;
+		start = ALIGN(bitmap_no + mask + 1,
+			      MAX_ORDER_NR_PAGES >> cma->order_per_bit);
+
 	}
 
 	trace_cma_alloc_finish(cma->name, pfn, page, count, align);
-- 
2.25.1



From patrice.chotard at foss.st.com  Wed Jan 12 05:18:01 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Wed, 12 Jan 2022 14:18:01 +0100
Subject: spi: stm32-qspi: Update spi registering
In-Reply-To: <Ydbz2JkT8jRvNBBZ@sirena.org.uk>
References: <20220106132052.7227-1-patrice.chotard@foss.st.com>
 <Ydbz2JkT8jRvNBBZ@sirena.org.uk>
Message-ID: <dda713f1-165b-0877-5467-457805fb9d43@foss.st.com>

Hi Mark

On 1/6/22 2:51 PM, Mark Brown wrote:
> On Thu, Jan 06, 2022 at 02:20:52PM +0100, patrice.chotard at foss.st.com wrote:
>> From: Patrice Chotard <patrice.chotard at foss.st.com>
>>
>> Replace devm_spi_register_master() by spi_register_master() to ensure
>> that spi sub-nodes are unregistered in the correct order when qspi driver
>> is removed.
> 
> This commit message doesn't describe the actual issue.  The change is
> fixing ordering within the driver itself - the driver is freeing things
> in the remove() callback which are used by the controller but thanks to
> the use of devm the controller isn't unregistered from the core until
> after the remove() callback has run so we might still have something
> running.  "Subnodes" aren't an issue here.

OK i will update this comment to be clearer.

> 
> Please submit patches using subject lines reflecting the style for the
> subsystem, this makes it easier for people to identify relevant patches.
> Look at what existing commits in the area you're changing are doing and
> make sure your subject lines visually resemble what they're doing.
> There's no need to resubmit to fix this alone.
> 

Agree, i forgot to use the correct script to submit patches to ML.

Thanks
Patrice


From patrice.chotard at foss.st.com  Wed Jan 12 05:54:09 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Wed, 12 Jan 2022 14:54:09 +0100
Subject: spi: stm32-qspi: Update spi registering
In-Reply-To: <20220108194819.GA5467@wunner.de>
References: <20220106132052.7227-1-patrice.chotard@foss.st.com>
 <20220108194819.GA5467@wunner.de>
Message-ID: <ba5de6f6-a4f0-4974-cc68-abcb62ebf96e@foss.st.com>

Hi Lukas

On 1/8/22 8:48 PM, Lukas Wunner wrote:
> On Thu, Jan 06, 2022 at 02:20:52PM +0100, patrice.chotard at foss.st.com wrote:
>> --- a/drivers/spi/spi-stm32-qspi.c
>> +++ b/drivers/spi/spi-stm32-qspi.c
>> @@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
>>  	pm_runtime_enable(dev);
>>  	pm_runtime_get_noresume(dev);
>>  
>> -	ret = devm_spi_register_master(dev, ctrl);
>> +	ret = spi_register_master(ctrl);
>>  	if (ret)
>>  		goto err_pm_runtime_free;
>>  
>> @@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
>>  	struct stm32_qspi *qspi = platform_get_drvdata(pdev);
>>  
>>  	pm_runtime_get_sync(qspi->dev);
>> +	spi_unregister_master(qspi->ctrl);
>>  	/* disable qspi */
>>  	writel_relaxed(0, qspi->io_base + QSPI_CR);
>>  	stm32_qspi_dma_free(qspi);
> 
> NAK, this introduces a use-after-free because the "qspi" allocation
> is freed by spi_unregister_master(), yet is subsequently accessed.
> 
> You need to convert the driver to devm_spi_alloc_master() to avoid that.
> Do it in the same patch to ease backporting.

Ok i see, spi_unregister_controller() is releasing the controller if it wasn't
 previously devm allocated. I will make usage of devm_spi_alloc_master as you suggested.

> 
> Please add a stable designation and a Fixes: tag.  Chances are the patch
> needs to be backported all the way back to the release when the driver
> was first introduced.
> 
> Thanks,
> 
> Lukas
> 
Thanks
Patrice


From geert+renesas at glider.be  Wed Jan 12 06:00:47 2022
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 12 Jan 2022 15:00:47 +0100
Subject: [PATCH] perf: MARVELL_CN10K_TAD_PMU should depend on ARCH_THUNDER
Message-ID: <b4662a2c767d04cca19417e0c845edea2da262ad.1641995941.git.geert+renesas@glider.be>

The Marvell CN10K Last-Level cache Tag-and-data Units (LLC-TAD)
performance monitor is only present on Marvell CN10K SoCs.  Hence add a
dependency on ARCH_THUNDER, to prevent asking the user about this driver
when configuring a kernel without Cavium Thunder (incl. Marvell CN10K)
SoC support.

Fixes: 036a7584bede317d ("drivers: perf: Add LLC-TAD perf counter support")
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 drivers/perf/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index e1a0c44bc686493e..7d6ffdf44a415a66 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -141,7 +141,7 @@ config ARM_DMC620_PMU
 
 config MARVELL_CN10K_TAD_PMU
 	tristate "Marvell CN10K LLC-TAD PMU"
-	depends on ARM64 || (COMPILE_TEST && 64BIT)
+	depends on ARCH_THUNDER || (COMPILE_TEST && 64BIT)
 	help
 	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
 	  performance monitors on CN10K family silicons.
-- 
2.25.1



From geert+renesas at glider.be  Wed Jan 12 06:07:37 2022
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Wed, 12 Jan 2022 15:07:37 +0100
Subject: [PATCH] arm64: Remove ARCH_VULCAN
Message-ID: <9e8fef2cf4f2d5648e87076bc96601cff945ce40.1641996361.git.geert+renesas@glider.be>

Commit a314520d82317650 ("arm64: disable Broadcom Vulcan platform")
did not remove the ARCH_VULCAN configuration symbol, as there were still
references to this symbol.

As of commits 240d3d5b2a7a3263 ("gpio: xlp: update GPIO_XLP dependency") and
f85a543e5373eeba ("arm64: defconfig: drop ARCH_VULCAN"), the last users
of ARCH_VULCAN have been removed.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
 arch/arm64/Kconfig.platforms | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d588001708856..21697449d762fa99 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -309,9 +309,6 @@ config ARCH_VISCONTI
 	help
 	  This enables support for Toshiba Visconti SoCs Family.
 
-config ARCH_VULCAN
-	def_bool n
-
 config ARCH_XGENE
 	bool "AppliedMicro X-Gene SOC Family"
 	help
-- 
2.25.1



From m.tretter at pengutronix.de  Wed Jan 12 06:12:29 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 12 Jan 2022 15:12:29 +0100
Subject: [PATCH] clk: zynqmp: warn always when a clock op fails
Message-ID: <20220112141229.700708-1-m.tretter@pengutronix.de>

The warning that a clock operation failed is only printed once. However,
the function is called for various different clocks. The limit hides
warnings if different clock are affected by the failures.

Print the warning every time when a clock operation fails.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
 drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
 drivers/clk/zynqmp/divider.c         | 12 +++++------
 drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
 4 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index 565ed67a0430..0d9a39110f29 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_enable(clk_id);
 
 	if (ret)
-		pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock enable failed for %s (id %d), ret = %d\n",
+			__func__, clk_name, clk_id, ret);
 
 	return ret;
 }
@@ -61,8 +61,8 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_disable(clk_id);
 
 	if (ret)
-		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock disable failed for %s (id %d), ret = %d\n",
+			__func__, clk_name, clk_id, ret);
 }
 
 /**
@@ -80,8 +80,8 @@ static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_getstate(clk_id, &state);
 	if (ret) {
-		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock get state failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 		return -EIO;
 	}
 
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index 17afce594f28..6bc16500231e 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -51,8 +51,8 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_getparent(clk_id, &val);
 
 	if (ret) {
-		pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() getparent failed for clock: %s, ret = %d\n",
+			__func__, clk_name, ret);
 		/*
 		 * clk_core_get_parent_by_index() takes num_parents as incorrect
 		 * index which is exactly what I want to return here
@@ -80,8 +80,8 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 	ret = zynqmp_pm_clock_setparent(clk_id, index);
 
 	if (ret)
-		pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() set parent failed for clock: %s, ret = %d\n",
+			__func__, clk_name, ret);
 
 	return ret;
 }
diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index cb49281f9cf9..c6d6a2fb5866 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -89,8 +89,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
 	ret = zynqmp_pm_clock_getdivider(clk_id, &div);
 
 	if (ret)
-		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() get divider failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 
 	if (div_type == TYPE_DIV1)
 		value = div & 0xFFFF;
@@ -177,8 +177,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
 		ret = zynqmp_pm_clock_getdivider(clk_id, &bestdiv);
 
 		if (ret)
-			pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-				     __func__, clk_name, ret);
+			pr_warn("%s() get divider failed for %s, ret = %d\n",
+				__func__, clk_name, ret);
 		if (div_type == TYPE_DIV1)
 			bestdiv = bestdiv & 0xFFFF;
 		else
@@ -244,8 +244,8 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 	ret = zynqmp_pm_clock_setdivider(clk_id, div);
 
 	if (ret)
-		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() set divider failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 
 	return ret;
 }
diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
index 036e4ff64a2f..6c4dfae3df1d 100644
--- a/drivers/clk/zynqmp/pll.c
+++ b/drivers/clk/zynqmp/pll.c
@@ -56,8 +56,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
 
 	ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
 	if (ret) {
-		pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() PLL get frac mode failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 		return PLL_MODE_ERROR;
 	}
 
@@ -84,8 +84,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
 
 	ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
 	if (ret)
-		pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() PLL set frac mode failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 	else
 		clk->set_pll_mode = true;
 }
@@ -145,8 +145,8 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
 
 	ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
 	if (ret) {
-		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() get divider failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 		return 0ul;
 	}
 
@@ -200,8 +200,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
 			     clk_name);
 		else if (ret)
-			pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-				     __func__, clk_name, ret);
+			pr_warn("%s() set divider failed for %s, ret = %d\n",
+				__func__, clk_name, ret);
 		zynqmp_pm_set_pll_frac_data(clk_id, f);
 
 		return rate + frac;
@@ -211,8 +211,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
 	ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
 	if (ret)
-		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() set divider failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 
 	return parent_rate * fbdiv;
 }
@@ -233,8 +233,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_getstate(clk_id, &state);
 	if (ret) {
-		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock get state failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 		return -EIO;
 	}
 
@@ -265,8 +265,8 @@ static int zynqmp_pll_enable(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_enable(clk_id);
 	if (ret)
-		pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock enable failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 
 	return ret;
 }
@@ -287,8 +287,8 @@ static void zynqmp_pll_disable(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_disable(clk_id);
 	if (ret)
-		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_warn("%s() clock disable failed for %s, ret = %d\n",
+			__func__, clk_name, ret);
 }
 
 static const struct clk_ops zynqmp_pll_ops = {
-- 
2.30.2



From mark.rutland at arm.com  Wed Jan 12 06:16:21 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 14:16:21 +0000
Subject: [bootwrapper PATCH 02/13] Add bit-field macros
In-Reply-To: <20220111144048.2675076e@donnerap.cambridge.arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-3-mark.rutland@arm.com>
 <20220111144048.2675076e@donnerap.cambridge.arm.com>
Message-ID: <Yd7itXaf30d3Nv+x@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 02:40:48PM +0000, Andre Przywara wrote:
> On Tue, 11 Jan 2022 13:06:42 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > Arm architectural documentation typically defines bit-fields as
> > `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> > helpful if we could define fields in the same way.
> > 
> > Add helpers so that we can do so, along with helper to extract/insert
> > bit-field values.
> > 
> > There should be no functional change as a result of this patch.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >  include/bits.h | 33 +++++++++++++++++++++++++++++++++
> >  1 file changed, 33 insertions(+)
> >  create mode 100644 include/bits.h
> > 
> > diff --git a/include/bits.h b/include/bits.h
> > new file mode 100644
> > index 0000000..8824a38
> > --- /dev/null
> > +++ b/include/bits.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * include/bits.h - helpers for bit-field definitions.
> > + *
> > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > + *
> > + * Use of this source code is governed by a BSD-style license that can be
> > + * found in the LICENSE.txt file.
> > + */
> > +#ifndef __BITS_H
> > +#define __BITS_H
> > +
> > +#ifdef __ASSEMBLY__
> > +#define UL(x)	x
> > +#define ULL(x)	x
> > +#else
> > +#define UL(x)	x##UL
> > +#define ULL(x)	x##ULL
> > +#endif
> > +
> > +#define BITS(msb, lsb) \
> 
> The kernel uses GENMASK() for this, should we follow suit here? Both
> U-Boot and Trusted Firmware decided to do so, so I consider this some kind
> of agreed naming for bitmask generation these days.

TBH, I always forget the naming of GENMASK(), and chose `BITS()` to more
clearly align with `BIT()`, and also the way the architecture documentation
speaks about "bits [msb:lsb]".

I'm not wedded to the naming, but IMO `GENMASK()` isn't any better, even if
that's what linux uses. Regardless of the specific names, I'd like the
single-bit and multi-bit helpers to clearly align naming-wise.

For now I'd prefer to stick with `BIT()` and `BITS()`.

> > +((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
> > +
> > +#define BIT(b)	BITS(b, b)
> > +
> > +#define BITS_LSB(bits)	(__builtin_ffsll(bits) - 1)
> 
> Shall there be some comment explaining the functionality and arguments? Or
> maybe use "mask" instead of the more ambiguous "bits" name here?
> TBH I needed to read the implementation of the next macro to understand
> what it does.

If there's any confusion here I think we need comments regardless, since
neither `bits` nor `mask` imply contiguity, which is the important factor. I'll
add some comments with examples.

I'm happy to also rename the `bits` parameter to `mask`.

> > +
> > +#define BITS_EXTRACT(val, bits) \
> 
> Same here, having BITS_EXTRACT(val, mask) looks more readable to me.

I'll do as above hree, and likewise for the cases below.

Thanks,
Mark.

> 
> Cheers,
> Andre
> 
> > +	(((val) & (bits)) >> BITS_LSB(bits))
> > +
> > +#define BITS_INSERT(bits, val) \
> > +	(((val) << BITS_LSB(bits)) & (bits))
> > +
> > +#endif
> 


From mark.rutland at arm.com  Wed Jan 12 06:18:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 14:18:52 +0000
Subject: [bootwrapper PATCH 05/13] aarch64: add mov_64 macro
In-Reply-To: <20220111144149.6b519ede@donnerap.cambridge.arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-6-mark.rutland@arm.com>
 <20220111144149.6b519ede@donnerap.cambridge.arm.com>
Message-ID: <Yd7jTD1GFrD3/jGA@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 02:41:49PM +0000, Andre Przywara wrote:
> On Tue, 11 Jan 2022 13:06:45 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi,
> 
> > In subsequent patches we'll need to load 64-bit values into GPRs before
> > the CPU is in a known endianness, where we cannot use literal pools.
> > 
> > In preparation for that, this patch adds a new `mov_64` macro to load a
> > 64-bit value into a GPR using a sequence of MOV and MOVKs, which will
> > function the same regardless of the CPU's endianness.
> > 
> > At the same time, move the `cpuid` macro to use `mov_64` internally.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >  arch/aarch64/common.S | 10 +++++++++-
> >  1 file changed, 9 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
> > index c7171a9..3279fa9 100644
> > --- a/arch/aarch64/common.S
> > +++ b/arch/aarch64/common.S
> > @@ -9,9 +9,17 @@
> >  
> >  #include <cpu.h>
> >  
> > +	/* Load a 64-bit value using immediates */
> > +	.macro	mov_64 dest, val
> > +	mov	\dest, #(((\val) >>  0) & 0xffff)
> > +	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
> > +	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
> > +	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
> > +	.endm
> > +
> 
> Trusted Firmware has an (admittedly more complicated) version that only
> uses as many instructions as needed, by skipping over halfwords that are
> zero:
> https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/include/arch/aarch64/asm_macros.S#n125
> 
> Does that sound useful for us?

For simplicity/clarity, I'd prefer to keep this as-is.

That and I'm not entirely sure about how the boot-wrapper and TF-A licenses
interact, so generally I'd strongly prefer to avoid importing code.

Thanks,
Mark.

> 
> Cheers,
> Andre
> 
> >  	/* Put MPIDR into \dest, clobber \tmp and flags */
> >  	.macro cpuid dest, tmp
> >  	mrs	\dest, mpidr_el1
> > -	ldr	\tmp, =MPIDR_ID_BITS
> > +	mov_64	\tmp, MPIDR_ID_BITS
> >  	ands	\dest, \dest, \tmp
> >  	.endm
> 


From narmstrong at baylibre.com  Wed Jan 12 06:34:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 12 Jan 2022 15:34:02 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <Yd7RG80hhjZilGs7@p1g2>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-4-gary.bisson@boundarydevices.com>
 <fe58c139-f127-d102-a6a6-b8c2151aac20@baylibre.com> <Yd7RG80hhjZilGs7@p1g2>
Message-ID: <10696e08-80ca-7dcf-9766-60d0a2475c6e@baylibre.com>

On 12/01/2022 14:01, Gary Bisson wrote:
> Hi,
> 
> On Wed, Jan 12, 2022 at 09:33:42AM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> On 03/01/2022 16:46, Gary Bisson wrote:
>>> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>>>   both options
>>> - RTS/CTS signals however only have 1 option available
>>>
>>> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
>>> ---
>>> Cc: Rob Herring <robh+dt at kernel.org>
>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>> Cc: devicetree at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>> ---
>>>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>>>  1 file changed, 27 insertions(+)
>>>
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> index af1357c48bee..3a7773ffbd08 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
>>> @@ -1952,6 +1952,33 @@ mux {
>>>  						};
>>>  					};
>>>  
>>> +					uart_ao_b_1_pins: uart-ao-b-1 {
>>> +						mux {
>>> +							groups = "uart_ao_b_tx_2",
>>> +								 "uart_ao_b_rx_3";
>>> +							function = "uart_ao_b";
>>> +							bias-disable;
>>> +						};
>>> +					};
>>> +
>>> +					uart_ao_b_2_pins: uart-ao-b-2 {
>>> +						mux {
>>> +							groups = "uart_ao_b_tx_8",
>>> +								 "uart_ao_b_rx_9";
>>> +							function = "uart_ao_b";
>>> +							bias-disable;
>>> +						};
>>> +					};
>>
>> I'm not fan of these nodes namings.
>>
>> Perhaps :
>> - uart-ao-b-2-3
>> - uart-ao-b-8-9
>>
>> so the actual pins numbers used are more clear ?
> 
> Sure, I wasn't convinced by that naming either. I although thought
> about:
> - uart-ao-b
> - uart-ao-b-alt

Not sure about these because it means one is the default and the second
is an alternate one, and I'm not sure about that. If it's the case, then
this naming is ok.

> 
> Let me know which one you prefer and I'll respin the patch.
> Also let me know if I should re-send the entire series or just this
> patch.

I'm lazy, so the entire patchset please :-)

Thanks,
Neil

> 
> Regards,
> Gary
> 



From mark.rutland at arm.com  Wed Jan 12 06:34:45 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 14:34:45 +0000
Subject: [bootwrapper PATCH 06/13] aarch64: initialize SCTLR_ELx for the
 boot-wrapper
In-Reply-To: <a3010a0b-c740-da2d-c948-fedbdbec3322@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-7-mark.rutland@arm.com>
 <a3010a0b-c740-da2d-c948-fedbdbec3322@arm.com>
Message-ID: <Yd7nBd+LCbmNrEy2@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 02:38:28PM +0000, Robin Murphy wrote:
> On 2022-01-11 13:06, Mark Rutland wrote:
> > The SCTLR_ELx registers contain fields which are UNKNOWN or
> > IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
> > defines the endianness of memory accesses (e.g. reads from literal
> > pools). Due to this, portions of boot-wrapper code are not guaranteed
> > top work correctly.
> 
> Nit: "to"

Cheers; fixed.

> > +/*
> > + * RES1 bit definitions definitions as of ARM DDI 0487G.b
> > + *
> > + * These includes bits which are RES1 in some configurations.
> > + */
> > +#define SCTLR_EL3_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> > +				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
> > +
> > +#define SCTLR_EL2_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> > +				 1 << 18 | 1 << 16 | 1 << 11 | 1 << 5 | 1 << 4)
> > +
> > +#define SCTLR_EL1_RES1		(1 << 29 | 1 << 28 | 1 << 23 | 1 << 22 | \
> > +				 1 << 11 | 1 << 8 | 1 << 7 | 1 << 4)
> > +
> > +#define HCR_EL2_RES1		(1 << 1)
> 
> Maybe use the new BIT() macro in these? I reckon that would be more readable
> overall.

Hmm; I'm not sure why I didn't do that to start with. Done.

Mark.


From mark.rutland at arm.com  Wed Jan 12 06:37:41 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 12 Jan 2022 14:37:41 +0000
Subject: [bootwrapper PATCH 13/13] Unify start_el3 & start_no_el3
In-Reply-To: <91231c75-3f47-1106-a740-1fee40d4b7b5@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-14-mark.rutland@arm.com>
 <91231c75-3f47-1106-a740-1fee40d4b7b5@arm.com>
Message-ID: <Yd7ntQlK04RsrMVz@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 02:39:35PM +0000, Robin Murphy wrote:
> On 2022-01-11 13:06, Mark Rutland wrote:
> > Now that the start_el3 and start_no_el3 labels point at the same place,
> > unify them into a start_bootmethod label and update callers.
> > 
> > There should be no functional change as a result of this patch.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >   arch/aarch32/boot.S | 5 ++---
> >   arch/aarch64/boot.S | 4 ++--
> >   arch/aarch64/psci.S | 3 +--
> >   3 files changed, 5 insertions(+), 7 deletions(-)
> > 
> > diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> > index 820957b..4d16c9c 100644
> > --- a/arch/aarch32/boot.S
> > +++ b/arch/aarch32/boot.S
> > @@ -51,7 +51,7 @@ ASM_FUNC(_start)
> >   	bl	cpu_init_bootwrapper
> > -	b	start_no_el3
> > +	b	start_bootmethod
> >   _switch_monitor:
> >   	adr	lr, _monitor
> > @@ -69,8 +69,7 @@ _monitor:
> >   	bl	gic_secure_init
> > -	/* Initialise boot method */
> > -	b	start_el3
> > +	b	start_bootmethod
> >   err_invalid_id:
> >   	b	.
> > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> > index c0ec518..da5fa65 100644
> > --- a/arch/aarch64/boot.S
> > +++ b/arch/aarch64/boot.S
> > @@ -57,7 +57,7 @@ reset_at_el3:
> >   	bl	gic_secure_init
> > -	b	start_el3
> > +	b	start_bootmethod
> >   	/*
> >   	 * EL2 initialization
> > @@ -97,7 +97,7 @@ reset_no_el3:
> >   	bl	cpu_init_bootwrapper
> > -	b	start_no_el3
> > +	b	start_bootmethod
> >   err_invalid_id:
> >   	b	.
> > diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> > index d6ca2eb..9709dbb 100644
> > --- a/arch/aarch64/psci.S
> > +++ b/arch/aarch64/psci.S
> > @@ -79,6 +79,5 @@ smc_exit:
> >   	ldp	x18, x19, [sp], #16
> >   	eret
> > -ASM_FUNC(start_el3)
> > -ASM_FUNC(start_no_el3)
> > +ASM_FUNC(start_bootmethod)
> 
> Should there be an equivalent of this hunk for arch/aarch32/psci.S?

Yes, and likewise for arch/aarch64/spin.S.

I'll go fix that an re-test.

Mark.


From dave.kleikamp at oracle.com  Wed Jan 12 06:45:15 2022
From: dave.kleikamp at oracle.com (Dave Kleikamp)
Date: Wed, 12 Jan 2022 08:45:15 -0600
Subject: [PATCH v19 11/13] arm64: kdump: reimplement crashkernel=X
In-Reply-To: <20211228132612.1860-12-thunder.leizhen@huawei.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-12-thunder.leizhen@huawei.com>
Message-ID: <e48ac849-cc3d-3c0b-e159-7408af61eece@oracle.com>

On 12/28/21 7:26AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> There are following issues in arm64 kdump:
> 1. We use crashkernel=X to reserve crashkernel below 4G, which
> will fail when there is no enough low memory.
> 2. If reserving crashkernel above 4G, in this case, crash dump
> kernel will boot failure because there is no low memory available
> for allocation.
> 
> To solve these issues, change the behavior of crashkernel=X and
> introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
> in DMA zone, and fall back to high allocation if it fails.
> We can also use "crashkernel=X,high" to select a region above DMA zone,
> which also tries to allocate at least 256M in DMA zone automatically.
> "crashkernel=Y,low" can be used to allocate specified size low memory.
> 
> Another minor change, there may be two regions reserved for crash
> dump kernel, in order to distinct from the high region and make no
> effect to the use of existing kexec-tools, rename the low region as
> "Crash kernel (low)".
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> ---
>   arch/arm64/kernel/machine_kexec.c      |  5 +++-
>   arch/arm64/kernel/machine_kexec_file.c | 12 ++++++--
>   arch/arm64/kernel/setup.c              | 13 +++++++-
>   arch/arm64/mm/init.c                   | 41 ++++++++++----------------
>   4 files changed, 42 insertions(+), 29 deletions(-)
> 
> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> index 6fb31c117ebe08c..6665bf31f6b6a19 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -327,7 +327,10 @@ bool crash_is_nosave(unsigned long pfn)
>   
>   	/* in reserved memory? */
>   	addr = __pfn_to_phys(pfn);
> -	if ((addr < crashk_res.start) || (crashk_res.end < addr))
> +	if (((addr < crashk_res.start) || (crashk_res.end < addr)) && !crashk_low_res.end)
> +		return false;
> +
> +	if ((addr < crashk_low_res.start) || (crashk_low_res.end < addr))
>   		return false;
>   
>   	if (!kexec_crash_image)
> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
> index 59c648d51848886..889951291cc0f9c 100644
> --- a/arch/arm64/kernel/machine_kexec_file.c
> +++ b/arch/arm64/kernel/machine_kexec_file.c
> @@ -65,10 +65,18 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
>   
>   	/* Exclude crashkernel region */
>   	ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> +	if (ret)
> +		goto out;
> +
> +	if (crashk_low_res.end) {
> +		ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
> +		if (ret)
> +			goto out;
> +	}
>   
> -	if (!ret)
> -		ret =  crash_prepare_elf64_headers(cmem, true, addr, sz);
> +	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>   
> +out:
>   	kfree(cmem);
>   	return ret;
>   }
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index be5f85b0a24de69..4bb2e55366be64d 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -248,7 +248,18 @@ static void __init request_standard_resources(void)
>   		    kernel_data.end <= res->end)
>   			request_resource(res, &kernel_data);
>   #ifdef CONFIG_KEXEC_CORE
> -		/* Userspace will find "Crash kernel" region in /proc/iomem. */
> +		/*
> +		 * Userspace will find "Crash kernel" or "Crash kernel (low)"
> +		 * region in /proc/iomem.
> +		 * In order to distinct from the high region and make no effect
> +		 * to the use of existing kexec-tools, rename the low region as
> +		 * "Crash kernel (low)".
> +		 */
> +		if (crashk_low_res.end && crashk_low_res.start >= res->start &&
> +				crashk_low_res.end <= res->end) {
> +			crashk_low_res.name = "Crash kernel (low)";
> +			request_resource(res, &crashk_low_res);
> +		}
>   		if (crashk_res.end && crashk_res.start >= res->start &&
>   		    crashk_res.end <= res->end)
>   			request_resource(res, &crashk_res);
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index be4595dc7459115..91b8038a1529068 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -74,41 +74,32 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>    */
>   static void __init reserve_crashkernel(void)
>   {
> -	unsigned long long crash_base, crash_size;
> -	unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
> +	unsigned long long crash_size, crash_base, total_mem, low_size;

low_size needs to be initialized to -1.

If parse_crashkernel() succeeds, then an uninitialized low_size will be 
passed to reserve_crashkernel_mem().

> +	bool high = false;
>   	int ret;
>   
> -	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> -				&crash_size, &crash_base);
> -	/* no crashkernel= or invalid value specified */
> -	if (ret || !crash_size)
> -		return;
> -
> -	crash_size = PAGE_ALIGN(crash_size);
> -
> -	/* User specifies base address explicitly. */
> -	if (crash_base)
> -		crash_max = crash_base + crash_size;
> +	total_mem = memblock_phys_mem_size();
>   
> -	/* Current arm64 boot protocol requires 2MB alignment */
> -	crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
> -					       crash_base, crash_max);
> -	if (!crash_base) {
> -		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
> -			crash_size);
> -		return;
> +	ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
> +	if (ret != 0 || crash_size <= 0) {
> +		/* crashkernel=X,high and possible crashkernel=Y,low */
> +		ret = parse_crashkernel_high_low(boot_command_line, &crash_size, &low_size);
> +		if (ret)
> +			return;
> +		high = true;
>   	}
>   
> -	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
> -		crash_base, crash_base + crash_size, crash_size >> 20);
> +	ret = reserve_crashkernel_mem(total_mem, crash_size, crash_base, low_size, high);
> +	if (ret)
> +		return;
>   
>   	/*
>   	 * The crashkernel memory will be removed from the kernel linear
>   	 * map. Inform kmemleak so that it won't try to access it.
>   	 */
> -	kmemleak_ignore_phys(crash_base);
> -	crashk_res.start = crash_base;
> -	crashk_res.end = crash_base + crash_size - 1;
> +	kmemleak_ignore_phys(crashk_res.start);
> +	if (crashk_low_res.end)
> +		kmemleak_ignore_phys(crashk_low_res.start);
>   }
>   #else
>   static void __init reserve_crashkernel(void)



From patrice.chotard at foss.st.com  Wed Jan 12 06:44:24 2022
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Wed, 12 Jan 2022 15:44:24 +0100
Subject: [PATCH v2] spi: stm32-qspi: Update spi registering
Message-ID: <20220112144424.5278-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Some device driver need to communicate to qspi device during the remove
process, qspi controller must be functional when spi_unregister_master()
is called.

To ensure this, replace devm_spi_register_master() by spi_register_master()
and spi_unregister_master() is called directly in .remove callback before
stopping the qspi controller.

This issue was put in evidence using kernel v5.11 and later
with a spi-nor which supports the software reset feature introduced
by commit d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on
shutdown")

Fixes: c530cd1d9d5e ("spi: spi-mem: add stm32 qspi controller")

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: <stable at vger.kernel.org> # 5.8.x
---

v2: 
  _ update commit message
  _ make usage of devm_spi_alloc_master() instead of spi_alloc_master()

 drivers/spi/spi-stm32-qspi.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 514337c86d2c..09839a3dbb26 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -688,7 +688,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	int ret, irq;
 
-	ctrl = spi_alloc_master(dev, sizeof(*qspi));
+	ctrl = devm_spi_alloc_master(dev, sizeof(*qspi));
 	if (!ctrl)
 		return -ENOMEM;
 
@@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_noresume(dev);
 
-	ret = devm_spi_register_master(dev, ctrl);
+	ret = spi_register_master(ctrl);
 	if (ret)
 		goto err_pm_runtime_free;
 
@@ -817,6 +817,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
 	struct stm32_qspi *qspi = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(qspi->dev);
+	spi_unregister_master(qspi->ctrl);
 	/* disable qspi */
 	writel_relaxed(0, qspi->io_base + QSPI_CR);
 	stm32_qspi_dma_free(qspi);
-- 
2.17.1



From robh+dt at kernel.org  Wed Jan 12 06:53:34 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 12 Jan 2022 08:53:34 -0600
Subject: [PATCH 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220112014356.h2pm7nc3vzsvjexq@pali>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220105150239.9628-9-pali@kernel.org>
 <CAL_Jsq+1hoAUVOzyOGZ1vVMsChhHJJpzk5HNU4Gi=Luy_8LArA@mail.gmail.com>
 <20220112014356.h2pm7nc3vzsvjexq@pali>
Message-ID: <CAL_JsqLaB=WnZjD3UBSyLHdWC4N3V8rFS47u57NZmmB1o0j1XA@mail.gmail.com>

On Tue, Jan 11, 2022 at 7:44 PM Pali Roh?r <pali at kernel.org> wrote:
>
> On Wednesday 05 January 2022 09:41:51 Rob Herring wrote:
> > On Wed, Jan 5, 2022 at 9:03 AM Pali Roh?r <pali at kernel.org> wrote:
> > >
> > > Split struct pci_ops between ops and child_ops. Member ops is used for
> > > accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> > > accessing real PCIe cards.
> > >
> > > There is no need to mix these two struct pci_ops into one as PCI core code
> > > already provides separate callbacks via bridge->ops and bridge->child_ops.
> >
> > I had similar patches including mvebu that I never got around to
> > sending out. I pushed the branch out now at least[1].
>
> Are you going to finish your patch series and send it? Because if yes,
> I can drop this my patch in v3 and let all ->child_ops conversion for
> you.

Not any time soon.

Rob


From maciej.szmigiero at oracle.com  Wed Jan 12 06:54:12 2022
From: maciej.szmigiero at oracle.com (Maciej S. Szmigiero)
Date: Wed, 12 Jan 2022 15:54:12 +0100
Subject: [PATCH v9 0/3] Add basic SoC support for mediatek mt8195
In-Reply-To: <20220112114724.1953-1-tinghan.shen@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
Message-ID: <e4f20498-3685-207f-2b94-0cb0ada725a4@oracle.com>

On 12.01.2022 12:47, Tinghan Shen wrote:
> This series adds basic SoC support for Mediatek's SoC MT8195.

Nice patchset Tinghan, however I can't stop wondering why I was CCed on
it (and Paolo and Sean, too) - this isn't KVM related at all.

scripts/get_maintainer.pl going wild?

Thanks,
Maciej


From robh at kernel.org  Wed Jan 12 07:09:31 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 12 Jan 2022 09:09:31 -0600
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20220111214608.GA169999@bhelgaas>
References: <20200722022514.1283916-20-robh@kernel.org>
 <20220111214608.GA169999@bhelgaas>
Message-ID: <CAL_JsqKoK6Vewwn4X0L+TKAz-UdK4n7CQ+OKpiEwGe2HqR5L8g@mail.gmail.com>

On Tue, Jan 11, 2022 at 3:46 PM Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> [-cc many, +cc iproc, loongson, tegra maintainers]
>
> On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> > The majority of DT based host drivers use the default .map_irq() and
> > .swizzle_irq() functions, so let's initialize the function pointers to
> > the default and drop setting them in the host drivers.
> >
> > Drivers like iProc which don't support legacy interrupts need to set
> > .map_irq() back to NULL.
>
> Probably a dumb question...
>
> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.
>
> My question is why we still have a few users of ->map_irq: loongson,
> tegra, iproc.  Shouldn't this mapping be described somehow via DT?

Tegra could perhaps be written another way. The mapping is standard,
but it's disabling an idle state when PCI interrupts are used. It just
needs some way to know if legacy interrupts are being used.

iproc looks pretty special with its bcma bus.

Adding something to DT doesn't really help because we'd still have to
support the old way.

Rob


From jitao.shi at mediatek.com  Wed Jan 12 07:01:33 2022
From: jitao.shi at mediatek.com (Jitao Shi)
Date: Wed, 12 Jan 2022 23:01:33 +0800
Subject: [PATCH] drm/mediatek: DP HPD Detect with debounce
Message-ID: <20220112150133.11275-1-jitao.shi@mediatek.com>

DP Spec 1.4a 3.3 requires dp detect the hpd with debounce.

Upstream implementations should implement HPD signal de-bouncing on
an external connection. A period of 100ms should be used for
detecting an HPD connect event (i.e., the event, ?HPD high,? is
confirmed only after HPD has been continuously asserted for 100ms).
Care should be taken to not implement de-bouncing on an IRQ_HPD and
on a downstream device-generated pair of HPD disconnect/reconnect
events (typically HPD shall be de-asserted for more than 2ms, but
less than 100ms in this case). To cover these cases, HPD de-bounce
should be implemented only after HPD low has been detected for 100ms.
 Timing requirements in this Standard related to the detection of
HPD high are to be interpreted as applying from the completion of an
implementation-dependent de-bounce period.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dp.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
index a256d55346a2..05f401a024a4 100644
--- a/drivers/gpu/drm/mediatek/mtk_dp.c
+++ b/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -193,6 +193,8 @@ struct mtk_dp {
 	struct mutex eld_lock;
 	u8 connector_eld[MAX_ELD_BYTES];
 	struct drm_connector *conn;
+	bool need_debounce;
+	struct timer_list debounce_timer;
 };
 
 enum mtk_dp_sdp_type {
@@ -2217,6 +2219,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
 	if (event < 0)
 		return IRQ_HANDLED;
 
+	if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
+		msleep(100);
+
 	if (mtk_dp->drm_dev) {
 		dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
 		drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
@@ -2296,6 +2301,14 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
 		mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
 	}
 	train_info->cable_state_change = true;
+
+	if (train_info->cable_state_change) {
+		if (!train_info->cable_plugged_in) {
+			mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
+			mtk_dp->need_debounce = false;
+		}
+	}
+
 	return IRQ_WAKE_THREAD;
 }
 
@@ -2903,6 +2916,13 @@ static int mtk_dp_register_audio_driver(struct device *dev)
 	return 0;
 }
 
+static void mtk_dp_debounce_timer(struct timer_list *t)
+{
+	struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
+
+	mtk_dp->need_debounce = true;
+}
+
 static int mtk_dp_probe(struct platform_device *pdev)
 {
 	struct mtk_dp *mtk_dp;
@@ -2990,6 +3010,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
 	else
 		mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
 
+	mtk_dp->need_debounce = true;
+	timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
+
 	mtk_dp->bridge.ops =
 		DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
 	drm_bridge_add(&mtk_dp->bridge);
@@ -3008,6 +3031,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
 
 	mtk_dp_video_mute(mtk_dp, true);
 	mtk_dp_audio_mute(mtk_dp, true);
+	del_timer_sync(&mtk_dp->debounce_timer);
 
 	pm_runtime_disable(&pdev->dev);
 
-- 
2.12.5



From m.tretter at pengutronix.de  Wed Jan 12 07:15:38 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 12 Jan 2022 16:15:38 +0100
Subject: [PATCH 0/3] dt-bindings: dmaengine: zynqmp_dma: Convert binding to
 YAML
Message-ID: <20220112151541.1328732-1-m.tretter@pengutronix.de>

Hi,

This series converts the ZynqMP dma engine dt bindings to yaml and fixes the
ZynqMP device tree following the stricter yaml bindings.

The series is based on https://github.com/Xilinx/linux-xlnx/tree/zynqmp/dt to
avoid conflicts when applying the patches to the zynqmp/dt tree.

Patch 1 converts the binding to yaml, Patches 2 and 3 cleanup the dma engine
nodes in the zynqmp.dtsi that is included by actual board device trees.

Michael

Michael Tretter (3):
  dt-bindings: dmaengine: zynqmp_dma: convert to yaml
  arm64: zynqmp: Add missing #dma-cells property
  arm64: zynqmp: Rename dma to dma-controller

 .../dma/xilinx/xlnx,zynqmp-dma-1.0.yaml       | 85 +++++++++++++++++++
 .../bindings/dma/xilinx/zynqmp_dma.txt        | 26 ------
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 48 +++++++----
 3 files changed, 117 insertions(+), 42 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt

-- 
2.30.2



From m.tretter at pengutronix.de  Wed Jan 12 07:15:40 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 12 Jan 2022 16:15:40 +0100
Subject: [PATCH 2/3] arm64: zynqmp: Add missing #dma-cells property
In-Reply-To: <20220112151541.1328732-1-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
Message-ID: <20220112151541.1328732-3-m.tretter@pengutronix.de>

Requesting the dma controllers fails if #dma-cells is not defined. Add
the missing property.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 493719f71fb5..6d96b6b99f84 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -261,6 +261,7 @@ fpd_dma_chan1: dma at fd500000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 124 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14e8>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -273,6 +274,7 @@ fpd_dma_chan2: dma at fd510000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 125 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14e9>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -285,6 +287,7 @@ fpd_dma_chan3: dma at fd520000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 126 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14ea>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -297,6 +300,7 @@ fpd_dma_chan4: dma at fd530000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 127 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14eb>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -309,6 +313,7 @@ fpd_dma_chan5: dma at fd540000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 128 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14ec>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -321,6 +326,7 @@ fpd_dma_chan6: dma at fd550000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 129 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14ed>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -333,6 +339,7 @@ fpd_dma_chan7: dma at fd560000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 130 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14ee>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -345,6 +352,7 @@ fpd_dma_chan8: dma at fd570000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 131 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <128>;
 			iommus = <&smmu 0x14ef>;
 			power-domains = <&zynqmp_firmware PD_GDMA>;
@@ -374,6 +382,7 @@ lpd_dma_chan1: dma at ffa80000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 77 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x868>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -386,6 +395,7 @@ lpd_dma_chan2: dma at ffa90000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 78 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x869>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -398,6 +408,7 @@ lpd_dma_chan3: dma at ffaa0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 79 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86a>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -410,6 +421,7 @@ lpd_dma_chan4: dma at ffab0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 80 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86b>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -422,6 +434,7 @@ lpd_dma_chan5: dma at ffac0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 81 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86c>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -434,6 +447,7 @@ lpd_dma_chan6: dma at ffad0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 82 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86d>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -446,6 +460,7 @@ lpd_dma_chan7: dma at ffae0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 83 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86e>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
@@ -458,6 +473,7 @@ lpd_dma_chan8: dma at ffaf0000 {
 			interrupt-parent = <&gic>;
 			interrupts = <0 84 4>;
 			clock-names = "clk_main", "clk_apb";
+			#dma-cells = <1>;
 			xlnx,bus-width = <64>;
 			iommus = <&smmu 0x86f>;
 			power-domains = <&zynqmp_firmware PD_ADMA>;
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Jan 12 07:15:41 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 12 Jan 2022 16:15:41 +0100
Subject: [PATCH 3/3] arm64: zynqmp: Rename dma to dma-controller
In-Reply-To: <20220112151541.1328732-1-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
Message-ID: <20220112151541.1328732-4-m.tretter@pengutronix.de>

The ZynqMP dma engines are actually dma-controllers as specified by the
device tree binding. Rename the device tree nodes accordingly.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 32 +++++++++++++-------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 6d96b6b99f84..3e15391e5b37 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -254,7 +254,7 @@ pmu at 9000 {
 		};
 
 		/* GDMA */
-		fpd_dma_chan1: dma at fd500000 {
+		fpd_dma_chan1: dma-controller at fd500000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd500000 0x0 0x1000>;
@@ -267,7 +267,7 @@ fpd_dma_chan1: dma at fd500000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan2: dma at fd510000 {
+		fpd_dma_chan2: dma-controller at fd510000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd510000 0x0 0x1000>;
@@ -280,7 +280,7 @@ fpd_dma_chan2: dma at fd510000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan3: dma at fd520000 {
+		fpd_dma_chan3: dma-controller at fd520000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd520000 0x0 0x1000>;
@@ -293,7 +293,7 @@ fpd_dma_chan3: dma at fd520000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan4: dma at fd530000 {
+		fpd_dma_chan4: dma-controller at fd530000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd530000 0x0 0x1000>;
@@ -306,7 +306,7 @@ fpd_dma_chan4: dma at fd530000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan5: dma at fd540000 {
+		fpd_dma_chan5: dma-controller at fd540000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd540000 0x0 0x1000>;
@@ -319,7 +319,7 @@ fpd_dma_chan5: dma at fd540000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan6: dma at fd550000 {
+		fpd_dma_chan6: dma-controller at fd550000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd550000 0x0 0x1000>;
@@ -332,7 +332,7 @@ fpd_dma_chan6: dma at fd550000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan7: dma at fd560000 {
+		fpd_dma_chan7: dma-controller at fd560000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd560000 0x0 0x1000>;
@@ -345,7 +345,7 @@ fpd_dma_chan7: dma at fd560000 {
 			power-domains = <&zynqmp_firmware PD_GDMA>;
 		};
 
-		fpd_dma_chan8: dma at fd570000 {
+		fpd_dma_chan8: dma-controller at fd570000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xfd570000 0x0 0x1000>;
@@ -375,7 +375,7 @@ gic: interrupt-controller at f9010000 {
 		 * These dma channels, Users should ensure that these dma
 		 * Channels are allowed for non secure access.
 		 */
-		lpd_dma_chan1: dma at ffa80000 {
+		lpd_dma_chan1: dma-controller at ffa80000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffa80000 0x0 0x1000>;
@@ -388,7 +388,7 @@ lpd_dma_chan1: dma at ffa80000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan2: dma at ffa90000 {
+		lpd_dma_chan2: dma-controller at ffa90000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffa90000 0x0 0x1000>;
@@ -401,7 +401,7 @@ lpd_dma_chan2: dma at ffa90000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan3: dma at ffaa0000 {
+		lpd_dma_chan3: dma-controller at ffaa0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffaa0000 0x0 0x1000>;
@@ -414,7 +414,7 @@ lpd_dma_chan3: dma at ffaa0000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan4: dma at ffab0000 {
+		lpd_dma_chan4: dma-controller at ffab0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffab0000 0x0 0x1000>;
@@ -427,7 +427,7 @@ lpd_dma_chan4: dma at ffab0000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan5: dma at ffac0000 {
+		lpd_dma_chan5: dma-controller at ffac0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffac0000 0x0 0x1000>;
@@ -440,7 +440,7 @@ lpd_dma_chan5: dma at ffac0000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan6: dma at ffad0000 {
+		lpd_dma_chan6: dma-controller at ffad0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffad0000 0x0 0x1000>;
@@ -453,7 +453,7 @@ lpd_dma_chan6: dma at ffad0000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan7: dma at ffae0000 {
+		lpd_dma_chan7: dma-controller at ffae0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffae0000 0x0 0x1000>;
@@ -466,7 +466,7 @@ lpd_dma_chan7: dma at ffae0000 {
 			power-domains = <&zynqmp_firmware PD_ADMA>;
 		};
 
-		lpd_dma_chan8: dma at ffaf0000 {
+		lpd_dma_chan8: dma-controller at ffaf0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dma-1.0";
 			reg = <0x0 0xffaf0000 0x0 0x1000>;
-- 
2.30.2



From m.tretter at pengutronix.de  Wed Jan 12 07:15:39 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 12 Jan 2022 16:15:39 +0100
Subject: [PATCH 1/3] dt-bindings: dmaengine: zynqmp_dma: convert to yaml
In-Reply-To: <20220112151541.1328732-1-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
Message-ID: <20220112151541.1328732-2-m.tretter@pengutronix.de>

Convert the Xilinx ZynqMP DMA engine bindings to Yaml.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 .../dma/xilinx/xlnx,zynqmp-dma-1.0.yaml       | 85 +++++++++++++++++++
 .../bindings/dma/xilinx/zynqmp_dma.txt        | 26 ------
 2 files changed, 85 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
 delete mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
new file mode 100644
index 000000000000..c0a1408b12ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx ZynqMP DMA Engine
+
+description: |
+  The Xilinx ZynqMP DMA engine supports memory to memory transfers,
+  memory to device and device to memory transfers. It also has flow
+  control and rate control support for slave/peripheral dma access.
+
+maintainers:
+  - Michael Tretter <m.tretter at pengutronix.de>
+
+allOf:
+  - $ref: "../dma-controller.yaml#"
+
+properties:
+  "#dma-cells":
+    const: 1
+
+  compatible:
+    const: xlnx,zynqmp-dma-1.0
+
+  reg:
+    description: memory map for gdma/adma module access
+    maxItems: 1
+
+  interrupts:
+    description: DMA channel interrupt
+    maxItems: 1
+
+  clocks:
+    description: input clocks
+    minItems: 2
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: clk_main
+      - const: clk_apb
+
+  xlnx,bus-width:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum:
+      - 64
+      - 128
+    description: AXI bus width in bits
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  dma-coherent:
+    description: present if dma operations are coherent
+
+required:
+  - "#dma-cells"
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/xlnx-zynqmp-clk.h>
+
+    fpd_dma_chan1: dma-controller at fd500000 {
+      compatible = "xlnx,zynqmp-dma-1.0";
+      reg = <0xfd500000 0x1000>;
+      interrupt-parent = <&gic>;
+      interrupts = <0 117 0x4>;
+      #dma-cells = <1>;
+      clock-names = "clk_main", "clk_apb";
+      clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+      xlnx,bus-width = <128>;
+      dma-coherent;
+    };
diff --git a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
deleted file mode 100644
index 07a5a7aa9ea0..000000000000
--- a/Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Xilinx ZynqMP DMA engine, it does support memory to memory transfers,
-memory to device and device to memory transfers. It also has flow
-control and rate control support for slave/peripheral dma access.
-
-Required properties:
-- compatible		: Should be "xlnx,zynqmp-dma-1.0"
-- reg			: Memory map for gdma/adma module access.
-- interrupts		: Should contain DMA channel interrupt.
-- xlnx,bus-width	: Axi buswidth in bits. Should contain 128 or 64
-- clock-names		: List of input clocks "clk_main", "clk_apb"
-			  (see clock bindings for details)
-
-Optional properties:
-- dma-coherent		: Present if dma operations are coherent.
-
-Example:
-++++++++
-fpd_dma_chan1: dma at fd500000 {
-	compatible = "xlnx,zynqmp-dma-1.0";
-	reg = <0x0 0xFD500000 0x1000>;
-	interrupt-parent = <&gic>;
-	interrupts = <0 117 4>;
-	clock-names = "clk_main", "clk_apb";
-	xlnx,bus-width = <128>;
-	dma-coherent;
-};
-- 
2.30.2



From pali at kernel.org  Wed Jan 12 07:18:03 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:03 +0100
Subject: [PATCH v2 00/11] PCI: mvebu: subsystem ids, AER and INTx
In-Reply-To: <20220105150239.9628-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
Message-ID: <20220112151814.24361-1-pali@kernel.org>

This patch series extends pci-bridge-emul.c driver to emulate PCI Subsystem
Vendor ID capability and PCIe extended capabilities. And then implement
in pci-mvebu.c driver support for PCI Subsystem Vendor IDs, PCIe AER
registers, support for legacy INTx interrupts, configuration for X1/X4
mode and usage of new PCI child_ops API.

This patch series depends on other pci-mvebu and pci-bridge-emul patches from:
https://lore.kernel.org/linux-pci/20220104153529.31647-1-pali at kernel.org/

Changes in v2:
* use static structures for INTx interrupts
* remove INTx domain after unregistering INTx handler

Pali Roh?r (9):
  PCI: pci-bridge-emul: Add support for PCI Bridge Subsystem Vendor ID
    capability
  dt-bindings: PCI: mvebu: Add num-lanes property
  PCI: mvebu: Correctly configure x1/x4 mode
  PCI: mvebu: Add support for PCI Bridge Subsystem Vendor ID on emulated
    bridge
  PCI: mvebu: Add support for Advanced Error Reporting registers on
    emulated bridge
  PCI: mvebu: Use child_ops API
  dt-bindings: PCI: mvebu: Update information about intx interrupts
  PCI: mvebu: Implement support for legacy INTx interrupts
  ARM: dts: armada-385.dtsi: Add definitions for PCIe legacy INTx
    interrupts

Russell King (2):
  PCI: pci-bridge-emul: Re-arrange register tests
  PCI: pci-bridge-emul: Add support for PCIe extended capabilities

 .../devicetree/bindings/pci/mvebu-pci.txt     |  16 +
 arch/arm/boot/dts/armada-385.dtsi             |  52 ++-
 drivers/pci/controller/pci-mvebu.c            | 355 +++++++++++++++---
 drivers/pci/pci-bridge-emul.c                 | 167 +++++---
 drivers/pci/pci-bridge-emul.h                 |  17 +
 5 files changed, 497 insertions(+), 110 deletions(-)

-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:06 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:06 +0100
Subject: [PATCH v2 03/11] PCI: pci-bridge-emul: Add support for PCI Bridge
 Subsystem Vendor ID capability
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-4-pali@kernel.org>

This is read-only capability in PCI config space. Put it between base PCI
capability and base PCI Express capability.

Driver just have to specify subsystem_vendor_id and subsystem_id fields in
emulated bridge structure and pci-bridge-emul takes care of correctly
compose PCI Bridge Subsystem Vendor ID capability.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 69 +++++++++++++++++++++++++----------
 drivers/pci/pci-bridge-emul.h |  2 +
 2 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 9f4f173f0650..c84f423a5893 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -21,8 +21,11 @@
 #include "pci-bridge-emul.h"
 
 #define PCI_BRIDGE_CONF_END	PCI_STD_HEADER_SIZEOF
+#define PCI_CAP_SSID_SIZEOF	(PCI_SSVID_DEVICE_ID + 2)
+#define PCI_CAP_SSID_START	PCI_BRIDGE_CONF_END
+#define PCI_CAP_SSID_END	(PCI_CAP_SSID_START + PCI_CAP_SSID_SIZEOF)
 #define PCI_CAP_PCIE_SIZEOF	(PCI_EXP_SLTSTA2 + 2)
-#define PCI_CAP_PCIE_START	PCI_BRIDGE_CONF_END
+#define PCI_CAP_PCIE_START	PCI_CAP_SSID_END
 #define PCI_CAP_PCIE_END	(PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF)
 
 /**
@@ -315,6 +318,25 @@ struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] =
 	},
 };
 
+static pci_bridge_emul_read_status_t
+pci_bridge_emul_read_ssid(struct pci_bridge_emul *bridge, int reg, u32 *value)
+{
+	switch (reg) {
+	case PCI_CAP_LIST_ID:
+		*value = PCI_CAP_ID_SSVID |
+			(bridge->has_pcie ? (PCI_CAP_PCIE_START << 8) : 0);
+		return PCI_BRIDGE_EMUL_HANDLED;
+
+	case PCI_SSVID_VENDOR_ID:
+		*value = bridge->subsystem_vendor_id |
+			(bridge->subsystem_id << 16);
+		return PCI_BRIDGE_EMUL_HANDLED;
+
+	default:
+		return PCI_BRIDGE_EMUL_NOT_HANDLED;
+	}
+}
+
 /*
  * Initialize a pci_bridge_emul structure to represent a fake PCI
  * bridge configuration space. The caller needs to have initialized
@@ -337,9 +359,17 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
 	if (!bridge->pci_regs_behavior)
 		return -ENOMEM;
 
-	if (bridge->has_pcie) {
+	if (bridge->subsystem_vendor_id)
+		bridge->conf.capabilities_pointer = PCI_CAP_SSID_START;
+	else if (bridge->has_pcie)
 		bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START;
+	else
+		bridge->conf.capabilities_pointer = 0;
+
+	if (bridge->conf.capabilities_pointer)
 		bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST);
+
+	if (bridge->has_pcie) {
 		bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP;
 		bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4);
 		bridge->pcie_cap_regs_behavior =
@@ -423,26 +453,28 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 		read_op = bridge->ops->read_base;
 		cfgspace = (__le32 *) &bridge->conf;
 		behavior = bridge->pci_regs_behavior;
-	} else if (!bridge->has_pcie) {
-		/* PCIe space is not implemented, and no PCI capabilities */
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	} else if (reg < PCI_CAP_PCIE_END) {
+	} else if (reg >= PCI_CAP_SSID_START && reg < PCI_CAP_SSID_END && bridge->subsystem_vendor_id) {
+		/* Emulated PCI Bridge Subsystem Vendor ID capability */
+		reg -= PCI_CAP_SSID_START;
+		read_op = pci_bridge_emul_read_ssid;
+		cfgspace = NULL;
+		behavior = NULL;
+	} else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) {
 		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else if (reg < PCI_CFG_SPACE_SIZE) {
-		/* Rest of PCI space not implemented */
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	} else {
+	} else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
 		/* PCIe extended capability space */
 		reg -= PCI_CFG_SPACE_SIZE;
 		read_op = bridge->ops->read_ext;
 		cfgspace = NULL;
 		behavior = NULL;
+	} else {
+		/* Not implemented */
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	if (read_op)
@@ -500,24 +532,21 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 		write_op = bridge->ops->write_base;
 		cfgspace = (__le32 *) &bridge->conf;
 		behavior = bridge->pci_regs_behavior;
-	} else if (!bridge->has_pcie) {
-		/* PCIe space is not implemented, and no PCI capabilities */
-		return PCIBIOS_SUCCESSFUL;
-	} else if (reg < PCI_CAP_PCIE_END) {
+	} else if (reg >= PCI_CAP_PCIE_START && reg < PCI_CAP_PCIE_END && bridge->has_pcie) {
 		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		write_op = bridge->ops->write_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else if (reg < PCI_CFG_SPACE_SIZE) {
-		/* Rest of PCI space not implemented */
-		return PCIBIOS_SUCCESSFUL;
-	} else {
+	} else if (reg >= PCI_CFG_SPACE_SIZE && bridge->has_pcie) {
 		/* PCIe extended capability space */
 		reg -= PCI_CFG_SPACE_SIZE;
 		write_op = bridge->ops->write_ext;
 		cfgspace = NULL;
 		behavior = NULL;
+	} else {
+		/* Not implemented */
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	shift = (where & 0x3) * 8;
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 6b5f75b2ad02..71392b67471d 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -132,6 +132,8 @@ struct pci_bridge_emul {
 	struct pci_bridge_reg_behavior *pcie_cap_regs_behavior;
 	void *data;
 	bool has_pcie;
+	u16 subsystem_vendor_id;
+	u16 subsystem_id;
 };
 
 enum {
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:07 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:07 +0100
Subject: [PATCH v2 04/11] dt-bindings: PCI: mvebu: Add num-lanes property
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-5-pali@kernel.org>

Controller driver needs to correctly configure PCIe link if it contains 1
or 4 SerDes PCIe lanes. Therefore add a new 'num-lanes' DT property for
mvebu PCIe controller. Property 'num-lanes' seems to be de-facto standard
way how number of lanes is specified in other PCIe controllers.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/mvebu-pci.txt | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 6173af6885f8..24225852bce0 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -77,6 +77,7 @@ and the following optional properties:
 - marvell,pcie-lane: the physical PCIe lane number, for ports having
   multiple lanes. If this property is not found, we assume that the
   value is 0.
+- num-lanes: number of SerDes PCIe lanes for this link (1 or 4)
 - reset-gpios: optional GPIO to PERST#
 - reset-delay-us: delay in us to wait after reset de-assertion, if not
   specified will default to 100ms, as required by the PCIe specification.
@@ -141,6 +142,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 58>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		/* low-active PERST# reset on GPIO 25 */
 		reset-gpios = <&gpio0 25 1>;
 		/* wait 20ms for device settle after reset deassertion */
@@ -161,6 +163,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 59>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <1>;
+		num-lanes = <1>;
 		clocks = <&gateclk 6>;
 	};
 
@@ -177,6 +180,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 60>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <2>;
+		num-lanes = <1>;
 		clocks = <&gateclk 7>;
 	};
 
@@ -193,6 +197,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 61>;
 		marvell,pcie-port = <0>;
 		marvell,pcie-lane = <3>;
+		num-lanes = <1>;
 		clocks = <&gateclk 8>;
 	};
 
@@ -209,6 +214,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 62>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 9>;
 	};
 
@@ -225,6 +231,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 63>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <1>;
+		num-lanes = <1>;
 		clocks = <&gateclk 10>;
 	};
 
@@ -241,6 +248,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 64>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <2>;
+		num-lanes = <1>;
 		clocks = <&gateclk 11>;
 	};
 
@@ -257,6 +265,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 65>;
 		marvell,pcie-port = <1>;
 		marvell,pcie-lane = <3>;
+		num-lanes = <1>;
 		clocks = <&gateclk 12>;
 	};
 
@@ -273,6 +282,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 99>;
 		marvell,pcie-port = <2>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 26>;
 	};
 
@@ -289,6 +299,7 @@ pcie-controller {
 		interrupt-map = <0 0 0 0 &mpic 103>;
 		marvell,pcie-port = <3>;
 		marvell,pcie-lane = <0>;
+		num-lanes = <1>;
 		clocks = <&gateclk 27>;
 	};
 };
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:05 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:05 +0100
Subject: [PATCH v2 02/11] PCI: pci-bridge-emul: Add support for PCIe extended
 capabilities
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-3-pali@kernel.org>

From: Russell King <rmk+kernel at armlinux.org.uk>

Add support for PCIe extended capabilities, which we just redirect to the
emulating driver.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
[pali: Fix writing new value with W1C bits]
Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 77 +++++++++++++++++++++++------------
 drivers/pci/pci-bridge-emul.h | 15 +++++++
 2 files changed, 67 insertions(+), 25 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 56b2cb741498..9f4f173f0650 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -433,10 +433,16 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
-		/* Beyond our PCIe space */
+	} else if (reg < PCI_CFG_SPACE_SIZE) {
+		/* Rest of PCI space not implemented */
 		*value = 0;
 		return PCIBIOS_SUCCESSFUL;
+	} else {
+		/* PCIe extended capability space */
+		reg -= PCI_CFG_SPACE_SIZE;
+		read_op = bridge->ops->read_ext;
+		cfgspace = NULL;
+		behavior = NULL;
 	}
 
 	if (read_op)
@@ -444,15 +450,20 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 	else
 		ret = PCI_BRIDGE_EMUL_NOT_HANDLED;
 
-	if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED)
-		*value = le32_to_cpu(cfgspace[reg / 4]);
+	if (ret == PCI_BRIDGE_EMUL_NOT_HANDLED) {
+		if (cfgspace)
+			*value = le32_to_cpu(cfgspace[reg / 4]);
+		else
+			*value = 0;
+	}
 
 	/*
 	 * Make sure we never return any reserved bit with a value
 	 * different from 0.
 	 */
-	*value &= behavior[reg / 4].ro | behavior[reg / 4].rw |
-		  behavior[reg / 4].w1c;
+	if (behavior)
+		*value &= behavior[reg / 4].ro | behavior[reg / 4].rw |
+			  behavior[reg / 4].w1c;
 
 	if (size == 1)
 		*value = (*value >> (8 * (where & 3))) & 0xff;
@@ -498,8 +509,15 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 		write_op = bridge->ops->write_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
+	} else if (reg < PCI_CFG_SPACE_SIZE) {
+		/* Rest of PCI space not implemented */
 		return PCIBIOS_SUCCESSFUL;
+	} else {
+		/* PCIe extended capability space */
+		reg -= PCI_CFG_SPACE_SIZE;
+		write_op = bridge->ops->write_ext;
+		cfgspace = NULL;
+		behavior = NULL;
 	}
 
 	shift = (where & 0x3) * 8;
@@ -513,29 +531,38 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	else
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	/* Keep all bits, except the RW bits */
-	new = old & (~mask | ~behavior[reg / 4].rw);
+	if (behavior) {
+		/* Keep all bits, except the RW bits */
+		new = old & (~mask | ~behavior[reg / 4].rw);
 
-	/* Update the value of the RW bits */
-	new |= (value << shift) & (behavior[reg / 4].rw & mask);
+		/* Update the value of the RW bits */
+		new |= (value << shift) & (behavior[reg / 4].rw & mask);
 
-	/* Clear the W1C bits */
-	new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+		/* Clear the W1C bits */
+		new &= ~((value << shift) & (behavior[reg / 4].w1c & mask));
+	} else {
+		new = old & ~mask;
+		new |= (value << shift) & mask;
+	}
 
-	/* Save the new value with the cleared W1C bits into the cfgspace */
-	cfgspace[reg / 4] = cpu_to_le32(new);
+	if (cfgspace) {
+		/* Save the new value with the cleared W1C bits into the cfgspace */
+		cfgspace[reg / 4] = cpu_to_le32(new);
+	}
 
-	/*
-	 * Clear the W1C bits not specified by the write mask, so that the
-	 * write_op() does not clear them.
-	 */
-	new &= ~(behavior[reg / 4].w1c & ~mask);
+	if (behavior) {
+		/*
+		 * Clear the W1C bits not specified by the write mask, so that the
+		 * write_op() does not clear them.
+		 */
+		new &= ~(behavior[reg / 4].w1c & ~mask);
 
-	/*
-	 * Set the W1C bits specified by the write mask, so that write_op()
-	 * knows about that they are to be cleared.
-	 */
-	new |= (value << shift) & (behavior[reg / 4].w1c & mask);
+		/*
+		 * Set the W1C bits specified by the write mask, so that write_op()
+		 * knows about that they are to be cleared.
+		 */
+		new |= (value << shift) & (behavior[reg / 4].w1c & mask);
+	}
 
 	if (write_op)
 		write_op(bridge, reg, old, new, mask);
diff --git a/drivers/pci/pci-bridge-emul.h b/drivers/pci/pci-bridge-emul.h
index 4953274cac18..6b5f75b2ad02 100644
--- a/drivers/pci/pci-bridge-emul.h
+++ b/drivers/pci/pci-bridge-emul.h
@@ -90,6 +90,14 @@ struct pci_bridge_emul_ops {
 	 */
 	pci_bridge_emul_read_status_t (*read_pcie)(struct pci_bridge_emul *bridge,
 						   int reg, u32 *value);
+
+	/*
+	 * Same as ->read_base(), except it is for reading from the
+	 * PCIe extended capability configuration space.
+	 */
+	pci_bridge_emul_read_status_t (*read_ext)(struct pci_bridge_emul *bridge,
+						  int reg, u32 *value);
+
 	/*
 	 * Called when writing to the regular PCI bridge configuration
 	 * space. old is the current value, new is the new value being
@@ -105,6 +113,13 @@ struct pci_bridge_emul_ops {
 	 */
 	void (*write_pcie)(struct pci_bridge_emul *bridge, int reg,
 			   u32 old, u32 new, u32 mask);
+
+	/*
+	 * Same as ->write_base(), except it is for writing from the
+	 * PCIe extended capability configuration space.
+	 */
+	void (*write_ext)(struct pci_bridge_emul *bridge, int reg,
+			  u32 old, u32 new, u32 mask);
 };
 
 struct pci_bridge_reg_behavior;
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:04 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:04 +0100
Subject: [PATCH v2 01/11] PCI: pci-bridge-emul: Re-arrange register tests
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-2-pali@kernel.org>

From: Russell King <rmk+kernel at armlinux.org.uk>

Re-arrange the tests for which sets of registers are being accessed so that
it is easier to add further regions later. No functional change.

Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
[pali: Fix reading old value in pci_bridge_emul_conf_write]
Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/pci-bridge-emul.c | 61 ++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 30 deletions(-)

diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c
index 033bbeb99176..56b2cb741498 100644
--- a/drivers/pci/pci-bridge-emul.c
+++ b/drivers/pci/pci-bridge-emul.c
@@ -418,25 +418,25 @@ int pci_bridge_emul_conf_read(struct pci_bridge_emul *bridge, int where,
 	__le32 *cfgspace;
 	const struct pci_bridge_reg_behavior *behavior;
 
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END) {
-		*value = 0;
-		return PCIBIOS_SUCCESSFUL;
-	}
-
-	if (!bridge->has_pcie && reg >= PCI_BRIDGE_CONF_END) {
+	if (reg < PCI_BRIDGE_CONF_END) {
+		/* Emulated PCI space */
+		read_op = bridge->ops->read_base;
+		cfgspace = (__le32 *) &bridge->conf;
+		behavior = bridge->pci_regs_behavior;
+	} else if (!bridge->has_pcie) {
+		/* PCIe space is not implemented, and no PCI capabilities */
 		*value = 0;
 		return PCIBIOS_SUCCESSFUL;
-	}
-
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
+	} else if (reg < PCI_CAP_PCIE_END) {
+		/* Our emulated PCIe capability */
 		reg -= PCI_CAP_PCIE_START;
 		read_op = bridge->ops->read_pcie;
 		cfgspace = (__le32 *) &bridge->pcie_conf;
 		behavior = bridge->pcie_cap_regs_behavior;
 	} else {
-		read_op = bridge->ops->read_base;
-		cfgspace = (__le32 *) &bridge->conf;
-		behavior = bridge->pci_regs_behavior;
+		/* Beyond our PCIe space */
+		*value = 0;
+		return PCIBIOS_SUCCESSFUL;
 	}
 
 	if (read_op)
@@ -480,11 +480,27 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	__le32 *cfgspace;
 	const struct pci_bridge_reg_behavior *behavior;
 
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_END)
-		return PCIBIOS_SUCCESSFUL;
+	ret = pci_bridge_emul_conf_read(bridge, reg, 4, &old);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return ret;
 
-	if (!bridge->has_pcie && reg >= PCI_BRIDGE_CONF_END)
+	if (reg < PCI_BRIDGE_CONF_END) {
+		/* Emulated PCI space */
+		write_op = bridge->ops->write_base;
+		cfgspace = (__le32 *) &bridge->conf;
+		behavior = bridge->pci_regs_behavior;
+	} else if (!bridge->has_pcie) {
+		/* PCIe space is not implemented, and no PCI capabilities */
 		return PCIBIOS_SUCCESSFUL;
+	} else if (reg < PCI_CAP_PCIE_END) {
+		/* Our emulated PCIe capability */
+		reg -= PCI_CAP_PCIE_START;
+		write_op = bridge->ops->write_pcie;
+		cfgspace = (__le32 *) &bridge->pcie_conf;
+		behavior = bridge->pcie_cap_regs_behavior;
+	} else {
+		return PCIBIOS_SUCCESSFUL;
+	}
 
 	shift = (where & 0x3) * 8;
 
@@ -497,21 +513,6 @@ int pci_bridge_emul_conf_write(struct pci_bridge_emul *bridge, int where,
 	else
 		return PCIBIOS_BAD_REGISTER_NUMBER;
 
-	ret = pci_bridge_emul_conf_read(bridge, reg, 4, &old);
-	if (ret != PCIBIOS_SUCCESSFUL)
-		return ret;
-
-	if (bridge->has_pcie && reg >= PCI_CAP_PCIE_START) {
-		reg -= PCI_CAP_PCIE_START;
-		write_op = bridge->ops->write_pcie;
-		cfgspace = (__le32 *) &bridge->pcie_conf;
-		behavior = bridge->pcie_cap_regs_behavior;
-	} else {
-		write_op = bridge->ops->write_base;
-		cfgspace = (__le32 *) &bridge->conf;
-		behavior = bridge->pci_regs_behavior;
-	}
-
 	/* Keep all bits, except the RW bits */
 	new = old & (~mask | ~behavior[reg / 4].rw);
 
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:08 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:08 +0100
Subject: [PATCH v2 05/11] PCI: mvebu: Correctly configure x1/x4 mode
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-6-pali@kernel.org>

If x1/x4 mode is not set correctly then link with endpoint card is not
established.

Use DTS property 'num-lanes' to deteriminate x1/x4 mode.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index a075ba26cff1..0f2ec0a17874 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -93,6 +93,7 @@ struct mvebu_pcie_port {
 	void __iomem *base;
 	u32 port;
 	u32 lane;
+	bool is_x4;
 	int devfn;
 	unsigned int mem_target;
 	unsigned int mem_attr;
@@ -233,13 +234,25 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, cmd, dev_rev, mask;
+	u32 ctrl, lnkcap, cmd, dev_rev, mask;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
 	ctrl |= PCIE_CTRL_RC_MODE;
 	mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
 
+	/*
+	 * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
+	 * Capability register. This register is defined by PCIe specification
+	 * as read-only but this mvebu controller has it as read-write and must
+	 * be set to number of SerDes PCIe lanes (1 or 4). If this register is
+	 * not set correctly then link with endpoint card is not established.
+	 */
+	lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
+	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
+	lnkcap |= (port->is_x4 ? 4 : 1) << 4;
+	mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
+
 	/* Disable Root Bridge I/O space, memory space and bus mastering. */
 	cmd = mvebu_readl(port, PCIE_CMD_OFF);
 	cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
@@ -986,6 +999,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 	struct device *dev = &pcie->pdev->dev;
 	enum of_gpio_flags flags;
 	int reset_gpio, ret;
+	u32 num_lanes;
 
 	port->pcie = pcie;
 
@@ -998,6 +1012,9 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 	if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane))
 		port->lane = 0;
 
+	if (!of_property_read_u32(child, "num-lanes", &num_lanes) && num_lanes == 4)
+		port->is_x4 = true;
+
 	port->name = devm_kasprintf(dev, GFP_KERNEL, "pcie%d.%d", port->port,
 				    port->lane);
 	if (!port->name) {
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:09 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:09 +0100
Subject: [PATCH v2 06/11] PCI: mvebu: Add support for PCI Bridge Subsystem
 Vendor ID on emulated bridge
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-7-pali@kernel.org>

Register with Subsystem Device/Vendor ID is at offset 0x2c. Export is via
emulated bridge.

After this change Subsystem ID is visible in lspci output at line:

  Capabilities: [40] Subsystem

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 0f2ec0a17874..811af9e6ede5 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -32,6 +32,7 @@
 #define PCIE_DEV_REV_OFF	0x0008
 #define PCIE_BAR_LO_OFF(n)	(0x0010 + ((n) << 3))
 #define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
+#define PCIE_SSDEV_ID_OFF	0x002c
 #define PCIE_CAP_PCIEXP		0x0060
 #define PCIE_HEADER_LOG_4_OFF	0x0128
 #define PCIE_BAR_CTRL_OFF(n)	(0x1804 + (((n) - 1) * 4))
@@ -731,6 +732,7 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	struct pci_bridge_emul *bridge = &port->bridge;
 	u32 dev_id = mvebu_readl(port, PCIE_DEV_ID_OFF);
 	u32 dev_rev = mvebu_readl(port, PCIE_DEV_REV_OFF);
+	u32 ssdev_id = mvebu_readl(port, PCIE_SSDEV_ID_OFF);
 	u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP);
 	u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS);
 
@@ -752,6 +754,8 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	 */
 	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
 
+	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
+	bridge->subsystem_id = ssdev_id >> 16;
 	bridge->has_pcie = true;
 	bridge->data = port;
 	bridge->ops = &mvebu_pci_bridge_emul_ops;
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:10 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:10 +0100
Subject: [PATCH v2 07/11] PCI: mvebu: Add support for Advanced Error Reporting
 registers on emulated bridge
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-8-pali@kernel.org>

AER registers start at mvebu offset 0x0100. Registers PCI_ERR_ROOT_COMMAND,
PCI_ERR_ROOT_STATUS and PCI_ERR_ROOT_ERR_SRC are not supported on pre-XP
hardware and returns zeros.

Note that AER interrupt is not supported yet as mvebu emulated bridge does
not implement interrupts support at all yet.

Also remove custom macro PCIE_HEADER_LOG_4_OFF as it is unused and
correctly this register should be referenced via standard macros with
offset, e.g. as: PCIE_CAP_PCIERR_OFF + PCI_ERR_HEADER_LOG + 4.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 67 +++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 811af9e6ede5..9ea2f6a7c2b0 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -34,7 +34,7 @@
 #define PCIE_BAR_HI_OFF(n)	(0x0014 + ((n) << 3))
 #define PCIE_SSDEV_ID_OFF	0x002c
 #define PCIE_CAP_PCIEXP		0x0060
-#define PCIE_HEADER_LOG_4_OFF	0x0128
+#define PCIE_CAP_PCIERR_OFF	0x0100
 #define PCIE_BAR_CTRL_OFF(n)	(0x1804 + (((n) - 1) * 4))
 #define PCIE_WIN04_CTRL_OFF(n)	(0x1820 + ((n) << 4))
 #define PCIE_WIN04_BASE_OFF(n)	(0x1824 + ((n) << 4))
@@ -603,6 +603,37 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 	return PCI_BRIDGE_EMUL_HANDLED;
 }
 
+static pci_bridge_emul_read_status_t
+mvebu_pci_bridge_emul_ext_conf_read(struct pci_bridge_emul *bridge,
+				    int reg, u32 *value)
+{
+	struct mvebu_pcie_port *port = bridge->data;
+
+	switch (reg) {
+	case 0:
+	case PCI_ERR_UNCOR_STATUS:
+	case PCI_ERR_UNCOR_MASK:
+	case PCI_ERR_UNCOR_SEVER:
+	case PCI_ERR_COR_STATUS:
+	case PCI_ERR_COR_MASK:
+	case PCI_ERR_CAP:
+	case PCI_ERR_HEADER_LOG+0:
+	case PCI_ERR_HEADER_LOG+4:
+	case PCI_ERR_HEADER_LOG+8:
+	case PCI_ERR_HEADER_LOG+12:
+	case PCI_ERR_ROOT_COMMAND:
+	case PCI_ERR_ROOT_STATUS:
+	case PCI_ERR_ROOT_ERR_SRC:
+		*value = mvebu_readl(port, PCIE_CAP_PCIERR_OFF + reg);
+		break;
+
+	default:
+		return PCI_BRIDGE_EMUL_NOT_HANDLED;
+	}
+
+	return PCI_BRIDGE_EMUL_HANDLED;
+}
+
 static void
 mvebu_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge,
 				      int reg, u32 old, u32 new, u32 mask)
@@ -715,11 +746,45 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 	}
 }
 
+static void
+mvebu_pci_bridge_emul_ext_conf_write(struct pci_bridge_emul *bridge,
+				     int reg, u32 old, u32 new, u32 mask)
+{
+	struct mvebu_pcie_port *port = bridge->data;
+
+	switch (reg) {
+	/* These are W1C registers, so clear other bits */
+	case PCI_ERR_UNCOR_STATUS:
+	case PCI_ERR_COR_STATUS:
+	case PCI_ERR_ROOT_STATUS:
+		new &= mask;
+		fallthrough;
+
+	case PCI_ERR_UNCOR_MASK:
+	case PCI_ERR_UNCOR_SEVER:
+	case PCI_ERR_COR_MASK:
+	case PCI_ERR_CAP:
+	case PCI_ERR_HEADER_LOG+0:
+	case PCI_ERR_HEADER_LOG+4:
+	case PCI_ERR_HEADER_LOG+8:
+	case PCI_ERR_HEADER_LOG+12:
+	case PCI_ERR_ROOT_COMMAND:
+	case PCI_ERR_ROOT_ERR_SRC:
+		mvebu_writel(port, new, PCIE_CAP_PCIERR_OFF + reg);
+		break;
+
+	default:
+		break;
+	}
+}
+
 static const struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = {
 	.read_base = mvebu_pci_bridge_emul_base_conf_read,
 	.write_base = mvebu_pci_bridge_emul_base_conf_write,
 	.read_pcie = mvebu_pci_bridge_emul_pcie_conf_read,
 	.write_pcie = mvebu_pci_bridge_emul_pcie_conf_write,
+	.read_ext = mvebu_pci_bridge_emul_ext_conf_read,
+	.write_ext = mvebu_pci_bridge_emul_ext_conf_write,
 };
 
 /*
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:11 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:11 +0100
Subject: [PATCH v2 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-9-pali@kernel.org>

Split struct pci_ops between ops and child_ops. Member ops is used for
accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
accessing real PCIe cards.

There is no need to mix these two struct pci_ops into one as PCI core code
already provides separate callbacks via bridge->ops and bridge->child_ops.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
 1 file changed, 44 insertions(+), 38 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 9ea2f6a7c2b0..1e90ab888075 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	mvebu_writel(port, mask, PCIE_MASK_OFF);
 }
 
-static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
-				 struct pci_bus *bus,
-				 u32 devfn, int where, int size, u32 *val)
+static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
+						    struct pci_bus *bus,
+						    int devfn);
+
+static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+				    int size, u32 *val)
 {
-	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+	struct mvebu_pcie *pcie = bus->sysdata;
+	struct mvebu_pcie_port *port;
+	void __iomem *conf_data;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	if (!mvebu_pcie_link_up(port)) {
+		*val = 0xffffffff;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	}
+
+	conf_data = port->base + PCIE_CONF_DATA_OFF;
 
 	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
 		     PCIE_CONF_ADDR_OFF);
@@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
-				 struct pci_bus *bus,
-				 u32 devfn, int where, int size, u32 val)
+static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
+				    int where, int size, u32 val)
 {
-	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
+	struct mvebu_pcie *pcie = bus->sysdata;
+	struct mvebu_pcie_port *port;
+	void __iomem *conf_data;
+
+	port = mvebu_pcie_find_port(pcie, bus, devfn);
+	if (!port)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (!mvebu_pcie_link_up(port))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	conf_data = port->base + PCIE_CONF_DATA_OFF;
 
 	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
 		     PCIE_CONF_ADDR_OFF);
@@ -347,6 +375,11 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
 	return PCIBIOS_SUCCESSFUL;
 }
 
+static struct pci_ops mvebu_pcie_child_ops = {
+	.read = mvebu_pcie_child_rd_conf,
+	.write = mvebu_pcie_child_wr_conf,
+};
+
 /*
  * Remove windows, starting from the largest ones to the smallest
  * ones.
@@ -862,25 +895,12 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 {
 	struct mvebu_pcie *pcie = bus->sysdata;
 	struct mvebu_pcie_port *port;
-	int ret;
 
 	port = mvebu_pcie_find_port(pcie, bus, devfn);
 	if (!port)
 		return PCIBIOS_DEVICE_NOT_FOUND;
 
-	/* Access the emulated PCI-to-PCI bridge */
-	if (bus->number == 0)
-		return pci_bridge_emul_conf_write(&port->bridge, where,
-						  size, val);
-
-	if (!mvebu_pcie_link_up(port))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	/* Access the real PCIe interface */
-	ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
-				    where, size, val);
-
-	return ret;
+	return pci_bridge_emul_conf_write(&port->bridge, where, size, val);
 }
 
 /* PCI configuration space read function */
@@ -889,7 +909,6 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 {
 	struct mvebu_pcie *pcie = bus->sysdata;
 	struct mvebu_pcie_port *port;
-	int ret;
 
 	port = mvebu_pcie_find_port(pcie, bus, devfn);
 	if (!port) {
@@ -897,21 +916,7 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	}
 
-	/* Access the emulated PCI-to-PCI bridge */
-	if (bus->number == 0)
-		return pci_bridge_emul_conf_read(&port->bridge, where,
-						 size, val);
-
-	if (!mvebu_pcie_link_up(port)) {
-		*val = 0xffffffff;
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
-	/* Access the real PCIe interface */
-	ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
-				    where, size, val);
-
-	return ret;
+	return pci_bridge_emul_conf_read(&port->bridge, where, size, val);
 }
 
 static struct pci_ops mvebu_pcie_ops = {
@@ -1421,6 +1426,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	bridge->sysdata = pcie;
 	bridge->ops = &mvebu_pcie_ops;
+	bridge->child_ops = &mvebu_pcie_child_ops;
 	bridge->align_resource = mvebu_pcie_align_resource;
 	bridge->map_irq = mvebu_pcie_map_irq;
 
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:12 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:12 +0100
Subject: [PATCH v2 09/11] dt-bindings: PCI: mvebu: Update information about
 intx interrupts
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-10-pali@kernel.org>

Signed-off-by: Pali Roh?r <pali at kernel.org>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/pci/mvebu-pci.txt | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
index 24225852bce0..6d022a9d36ee 100644
--- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
+++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
@@ -81,6 +81,11 @@ and the following optional properties:
 - reset-gpios: optional GPIO to PERST#
 - reset-delay-us: delay in us to wait after reset de-assertion, if not
   specified will default to 100ms, as required by the PCIe specification.
+- interrupt-names: list of interrupt names, supported are:
+   - "intx" - interrupt line triggered by one of the legacy interrupt
+- interrupts or interrupts-extended: List of the interrupt sources which
+  corresponding to the "interrupt-names". If non-empty then also additional
+  'interrupt-controller' subnode must be defined.
 
 Example:
 
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:13 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:13 +0100
Subject: [PATCH v2 10/11] PCI: mvebu: Implement support for legacy INTx
 interrupts
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-11-pali@kernel.org>

This adds support for legacy INTx interrupts received from other PCIe
devices and which are reported by a new INTx irq chip.

With this change, kernel can distinguish between INTA, INTB, INTC and INTD
interrupts.

Note that for this support, device tree files has to be properly adjusted
to provide "interrupts" or "interrupts-extended" property with intx
interrupt source, "interrupt-names" property with "intx" string and also
'interrupt-controller' subnode must be defined.

If device tree files do not provide these nodes then driver would work as
before.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 drivers/pci/controller/pci-mvebu.c | 185 +++++++++++++++++++++++++++--
 1 file changed, 177 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index 1e90ab888075..dbb6ecb4cb70 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -54,9 +54,10 @@
 	 PCIE_CONF_ADDR_EN)
 #define PCIE_CONF_DATA_OFF	0x18fc
 #define PCIE_INT_CAUSE_OFF	0x1900
+#define PCIE_INT_UNMASK_OFF	0x1910
+#define  PCIE_INT_INTX(i)		BIT(24+i)
 #define  PCIE_INT_PM_PME		BIT(28)
-#define PCIE_MASK_OFF		0x1910
-#define  PCIE_MASK_ENABLE_INTS          0x0f000000
+#define  PCIE_INT_ALL_MASK		GENMASK(31, 0)
 #define PCIE_CTRL_OFF		0x1a00
 #define  PCIE_CTRL_X1_MODE		0x0001
 #define  PCIE_CTRL_RC_MODE		BIT(1)
@@ -110,6 +111,9 @@ struct mvebu_pcie_port {
 	struct mvebu_pcie_window iowin;
 	u32 saved_pcie_stat;
 	struct resource regs;
+	struct irq_domain *intx_irq_domain;
+	raw_spinlock_t irq_lock;
+	int intx_irq;
 };
 
 static inline void mvebu_writel(struct mvebu_pcie_port *port, u32 val, u32 reg)
@@ -235,7 +239,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, lnkcap, cmd, dev_rev, mask;
+	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
@@ -288,10 +292,30 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	/* Point PCIe unit MBUS decode windows to DRAM space. */
 	mvebu_pcie_setup_wins(port);
 
-	/* Enable interrupt lines A-D. */
-	mask = mvebu_readl(port, PCIE_MASK_OFF);
-	mask |= PCIE_MASK_ENABLE_INTS;
-	mvebu_writel(port, mask, PCIE_MASK_OFF);
+	/* Mask all interrupt sources. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+	/* Clear all interrupt causes. */
+	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+	if (port->intx_irq <= 0) {
+		/*
+		 * When neither "summary" interrupt, nor "intx" interrupt was
+		 * specified in DT then unmask all legacy INTx interrupts as in
+		 * this case driver does not provide a way for masking and
+		 * unmasking of individual legacy INTx interrupts. In this case
+		 * all interrupts, including legacy INTx are reported via one
+		 * shared GIC source and therefore kernel cannot distinguish
+		 * which individual legacy INTx was triggered. These interrupts
+		 * are shared, so it should not cause any issue. Just
+		 * performance penalty as every PCIe interrupt handler needs to
+		 * be called when some interrupt is triggered.
+		 */
+		unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+		unmask |= PCIE_INT_INTX(0) | PCIE_INT_INTX(1) |
+			  PCIE_INT_INTX(2) | PCIE_INT_INTX(3);
+		mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	}
 }
 
 static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
@@ -924,6 +948,108 @@ static struct pci_ops mvebu_pcie_ops = {
 	.write = mvebu_pcie_wr_conf,
 };
 
+static void mvebu_pcie_intx_irq_mask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask &= ~PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static void mvebu_pcie_intx_irq_unmask(struct irq_data *d)
+{
+	struct mvebu_pcie_port *port = d->domain->host_data;
+	irq_hw_number_t hwirq = irqd_to_hwirq(d);
+	unsigned long flags;
+	u32 unmask;
+
+	raw_spin_lock_irqsave(&port->irq_lock, flags);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	unmask |= PCIE_INT_INTX(hwirq);
+	mvebu_writel(port, unmask, PCIE_INT_UNMASK_OFF);
+	raw_spin_unlock_irqrestore(&port->irq_lock, flags);
+}
+
+static struct irq_chip intx_irq_chip = {
+	.name = "mvebu-INTx",
+	.irq_mask = mvebu_pcie_intx_irq_mask,
+	.irq_unmask = mvebu_pcie_intx_irq_unmask,
+};
+
+static int mvebu_pcie_intx_irq_map(struct irq_domain *h,
+				   unsigned int virq, irq_hw_number_t hwirq)
+{
+	struct mvebu_pcie_port *port = h->host_data;
+
+	irq_set_status_flags(virq, IRQ_LEVEL);
+	irq_set_chip_and_handler(virq, &intx_irq_chip, handle_level_irq);
+	irq_set_chip_data(virq, port);
+
+	return 0;
+}
+
+static const struct irq_domain_ops mvebu_pcie_intx_irq_domain_ops = {
+	.map = mvebu_pcie_intx_irq_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int mvebu_pcie_init_irq_domain(struct mvebu_pcie_port *port)
+{
+	struct device *dev = &port->pcie->pdev->dev;
+	struct device_node *pcie_intc_node;
+
+	raw_spin_lock_init(&port->irq_lock);
+
+	pcie_intc_node = of_get_next_child(port->dn, NULL);
+	if (!pcie_intc_node) {
+		dev_err(dev, "No PCIe Intc node found for %s\n", port->name);
+		return -ENODEV;
+	}
+
+	port->intx_irq_domain = irq_domain_add_linear(pcie_intc_node, PCI_NUM_INTX,
+						      &mvebu_pcie_intx_irq_domain_ops,
+						      port);
+	of_node_put(pcie_intc_node);
+	if (!port->intx_irq_domain) {
+		dev_err(dev, "Failed to get INTx IRQ domain for %s\n", port->name);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void mvebu_pcie_irq_handler(struct irq_desc *desc)
+{
+	struct mvebu_pcie_port *port = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	struct device *dev = &port->pcie->pdev->dev;
+	u32 cause, unmask, status;
+	int i;
+
+	chained_irq_enter(chip, desc);
+
+	cause = mvebu_readl(port, PCIE_INT_CAUSE_OFF);
+	unmask = mvebu_readl(port, PCIE_INT_UNMASK_OFF);
+	status = cause & unmask;
+
+	/* Process legacy INTx interrupts */
+	for (i = 0; i < PCI_NUM_INTX; i++) {
+		if (!(status & PCIE_INT_INTX(i)))
+			continue;
+
+		if (generic_handle_domain_irq(port->intx_irq_domain, i) == -EINVAL)
+			dev_err_ratelimited(dev, "unexpected INT%c IRQ\n", (char)i+'A');
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
 static int mvebu_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 	/* Interrupt support on mvebu emulated bridges is not implemented yet */
@@ -1121,6 +1247,21 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 		port->io_attr = -1;
 	}
 
+	/*
+	 * Old DT bindings do not contain "intx" interrupt
+	 * so do not fail probing driver when interrupt does not exist.
+	 */
+	port->intx_irq = of_irq_get_byname(child, "intx");
+	if (port->intx_irq == -EPROBE_DEFER) {
+		ret = port->intx_irq;
+		goto err;
+	}
+	if (port->intx_irq <= 0) {
+		dev_warn(dev, "%s: legacy INTx interrupts cannot be masked individually, "
+			      "%pOF does not contain intx interrupt\n",
+			 port->name, child);
+	}
+
 	reset_gpio = of_get_named_gpio_flags(child, "reset-gpios", 0, &flags);
 	if (reset_gpio == -EPROBE_DEFER) {
 		ret = reset_gpio;
@@ -1317,6 +1458,7 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		child = port->dn;
 		if (!child)
@@ -1344,6 +1486,22 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		if (irq > 0) {
+			ret = mvebu_pcie_init_irq_domain(port);
+			if (ret) {
+				dev_err(dev, "%s: cannot init irq domain\n",
+					port->name);
+				pci_bridge_emul_cleanup(&port->bridge);
+				devm_iounmap(dev, port->base);
+				port->base = NULL;
+				mvebu_pcie_powerdown(port);
+				continue;
+			}
+			irq_set_chained_handler_and_data(irq,
+							 mvebu_pcie_irq_handler,
+							 port);
+		}
+
 		/*
 		 * PCIe topology exported by mvebu hw is quite complicated. In
 		 * reality has something like N fully independent host bridges
@@ -1448,6 +1606,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 
 	for (i = 0; i < pcie->nports; i++) {
 		struct mvebu_pcie_port *port = &pcie->ports[i];
+		int irq = port->intx_irq;
 
 		if (!port->base)
 			continue;
@@ -1458,7 +1617,17 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 		mvebu_writel(port, cmd, PCIE_CMD_OFF);
 
 		/* Mask all interrupt sources. */
-		mvebu_writel(port, 0, PCIE_MASK_OFF);
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
+
+		/* Clear all interrupt causes. */
+		mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_CAUSE_OFF);
+
+		if (irq > 0)
+			irq_set_chained_handler_and_data(irq, NULL, NULL);
+
+		/* Remove IRQ domains. */
+		if (port->intx_irq_domain)
+			irq_domain_remove(port->intx_irq_domain);
 
 		/* Free config space for emulated root bridge. */
 		pci_bridge_emul_cleanup(&port->bridge);
-- 
2.20.1



From pali at kernel.org  Wed Jan 12 07:18:14 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Wed, 12 Jan 2022 16:18:14 +0100
Subject: [PATCH v2 11/11] ARM: dts: armada-385.dtsi: Add definitions for PCIe
 legacy INTx interrupts
In-Reply-To: <20220112151814.24361-1-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
Message-ID: <20220112151814.24361-12-pali@kernel.org>

With this change legacy INTA, INTB, INTC and INTD interrupts are reported
separately and not mixed into one Linux virq source anymore.

Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 arch/arm/boot/dts/armada-385.dtsi | 52 ++++++++++++++++++++++++++-----
 1 file changed, 44 insertions(+), 8 deletions(-)

diff --git a/arch/arm/boot/dts/armada-385.dtsi b/arch/arm/boot/dts/armada-385.dtsi
index f0022d10c715..83392b92dae2 100644
--- a/arch/arm/boot/dts/armada-385.dtsi
+++ b/arch/arm/boot/dts/armada-385.dtsi
@@ -69,16 +69,25 @@
 				reg = <0x0800 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
 					  0x81000000 0 0 0x81000000 0x1 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie1_intc 0>,
+						<0 0 0 2 &pcie1_intc 1>,
+						<0 0 0 3 &pcie1_intc 2>,
+						<0 0 0 4 &pcie1_intc 3>;
 				marvell,pcie-port = <0>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 8>;
 				status = "disabled";
+				pcie1_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/* x1 port */
@@ -88,16 +97,25 @@
 				reg = <0x1000 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
 					  0x81000000 0 0 0x81000000 0x2 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie2_intc 0>,
+						<0 0 0 2 &pcie2_intc 1>,
+						<0 0 0 3 &pcie2_intc 2>,
+						<0 0 0 4 &pcie2_intc 3>;
 				marvell,pcie-port = <1>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 5>;
 				status = "disabled";
+				pcie2_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/* x1 port */
@@ -107,16 +125,25 @@
 				reg = <0x1800 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
 					  0x81000000 0 0 0x81000000 0x3 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie3_intc 0>,
+						<0 0 0 2 &pcie3_intc 1>,
+						<0 0 0 3 &pcie3_intc 2>,
+						<0 0 0 4 &pcie3_intc 3>;
 				marvell,pcie-port = <2>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 6>;
 				status = "disabled";
+				pcie3_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 
 			/*
@@ -129,16 +156,25 @@
 				reg = <0x2000 0 0 0 0>;
 				#address-cells = <3>;
 				#size-cells = <2>;
+				interrupt-names = "intx";
+				interrupts-extended = <&gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
 				#interrupt-cells = <1>;
 				ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
 					  0x81000000 0 0 0x81000000 0x4 0 1 0>;
 				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &gic GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-map-mask = <0 0 0 7>;
+				interrupt-map = <0 0 0 1 &pcie4_intc 0>,
+						<0 0 0 2 &pcie4_intc 1>,
+						<0 0 0 3 &pcie4_intc 2>,
+						<0 0 0 4 &pcie4_intc 3>;
 				marvell,pcie-port = <3>;
 				marvell,pcie-lane = <0>;
 				clocks = <&gateclk 7>;
 				status = "disabled";
+				pcie4_intc: interrupt-controller {
+					interrupt-controller;
+					#interrupt-cells = <1>;
+				};
 			};
 		};
 	};
-- 
2.20.1



From helgaas at kernel.org  Wed Jan 12 07:19:03 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 12 Jan 2022 09:19:03 -0600
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <013cc25a-d460-49eb-8cc0-8f59a0c5a45e@www.fastmail.com>
Message-ID: <20220112151903.GA257550@bhelgaas>

On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
> ?2022?1?11??? ??9:46?Bjorn Helgaas???
> > [-cc many, +cc iproc, loongson, tegra maintainers]
> >
> > On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> >> The majority of DT based host drivers use the default .map_irq() and
> >> .swizzle_irq() functions, so let's initialize the function pointers to
> >> the default and drop setting them in the host drivers.
> >> 
> >> Drivers like iProc which don't support legacy interrupts need to set
> >> .map_irq() back to NULL.
> >
> > Probably a dumb question...
> >
> > This patch removed all the ->swizzle_irq users in drivers/pci/, which
> > is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> > r1.2, sec 9.1, and should not be device-specific.  I assume the few
> > remaining arch/ users (arm and alpha) are either bugs or workarounds
> > for broken devices.
> >
> > My question is why we still have a few users of ->map_irq: loongson,
> > tegra, iproc.  Shouldn't this mapping be described somehow via DT?
> 
> For Loongson we are describing IRQ map in DT for newer platforms.
> But for legacy platforms (AMD RS780E North Bridge) with i8259 irqchip,
> we need to read PCI IRQ registers to get mapping information.
> 
> It is not known until boot time, so we have to use map_irq callback.

I see these:

  Documentation/devicetree/bindings/pci/loongson.yaml
  arch/mips/boot/dts/loongson/rs780e-pch.dtsi

which makes me think there are Loongson systems with DT.  Are there
some Loongson systems with DT and some legacy ones without?

The only driver I see is drivers/pci/controller/pci-loongson.c.  Is
that used for all Loongson system?  It unconditionally uses ->map_irq
= loongson_map_irq().

loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends on
firmware having previously programmed it, right?

Bjorn


From rinni at inventati.org  Wed Jan 12 07:29:51 2022
From: rinni at inventati.org (Philip Rinn)
Date: Wed, 12 Jan 2022 16:29:51 +0100
Subject: [linux-sunxi] [PATCH RESEND v3] arm64: dts: allwinner: a64:
 olinuxino: Enable audio
In-Reply-To: <Yd6axIURzudUq5Ah@plaes.org>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
 <87654fd3-6007-6067-1851-7bc4b6de2f05@inventati.org>
 <Yd6axIURzudUq5Ah@plaes.org>
Message-ID: <2e1a6b23-e713-7f2b-3634-5aa9b7724a50@inventati.org>

Hi,

On 12.01.22 at 10:09, Priit Laes wrote:
> On Tue, Jan 11, 2022 at 09:08:23PM +0100, 'Philip Rinn' via linux-sunxi wrote:
>> Enable the audio hardware on the Olimex A64-OLinuXino board family.
>> Tested on the A64-OLinuXino-2Ge8G-IND variant.
> 
> I have similar patch in one of my "long forgotten branches", but I'm not 100%
> sure whether the cpvdd-supply is required for codec_analog. IIRC, sound worked
> for me without the issues on A64-Olinuxino board (Rev D).
> 
> 'cpvdd-supply = <&reg_eldo1>' for codec_analog

I didn't test it without but as it is present for all other a64 board with audio and also in Olimex' tree I think it is needed.

> And we also need to enable these configuration options in the defconfig:
> 
> +CONFIG_SND_SUN8I_CODEC=m
> +CONFIG_SND_SUN50I_CODEC_ANALOG=m

Hm, probably, but why wasn't it added when audio was added for the other a64 boards? Or are we talking about different defconfigs here?

Best regards
Philip
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220112/fe7972e8/attachment.sig>

From helgaas at kernel.org  Wed Jan 12 07:32:40 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 12 Jan 2022 09:32:40 -0600
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <CAL_JsqKoK6Vewwn4X0L+TKAz-UdK4n7CQ+OKpiEwGe2HqR5L8g@mail.gmail.com>
Message-ID: <20220112153240.GA258585@bhelgaas>

On Wed, Jan 12, 2022 at 09:09:31AM -0600, Rob Herring wrote:
> On Tue, Jan 11, 2022 at 3:46 PM Bjorn Helgaas <helgaas at kernel.org> wrote:
> > On Tue, Jul 21, 2020 at 08:25:14PM -0600, Rob Herring wrote:
> > > The majority of DT based host drivers use the default .map_irq() and
> > > .swizzle_irq() functions, so let's initialize the function pointers to
> > > the default and drop setting them in the host drivers.
> > >
> > > Drivers like iProc which don't support legacy interrupts need to set
> > > .map_irq() back to NULL.
> >
> > Probably a dumb question...
> >
> > This patch removed all the ->swizzle_irq users in drivers/pci/, which
> > is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> > r1.2, sec 9.1, and should not be device-specific.  I assume the few
> > remaining arch/ users (arm and alpha) are either bugs or workarounds
> > for broken devices.
> >
> > My question is why we still have a few users of ->map_irq: loongson,
> > tegra, iproc.  Shouldn't this mapping be described somehow via DT?
> 
> Tegra could perhaps be written another way. The mapping is standard,
> but it's disabling an idle state when PCI interrupts are used. It just
> needs some way to know if legacy interrupts are being used.
>
> iproc looks pretty special with its bcma bus.
> 
> Adding something to DT doesn't really help because we'd still have to
> support the old way.

I guess my underlying question is whether new drivers should ever use
->swizzle_irq() and ->map_irq().  I'm hoping the answer is "no".

If we need them for pre-DT systems or things with incomplete DTs in
the field, I guess we have to live with that.

All ACPI really gives you is the _PRT, and I'm not sure that's
expressive enough to describe platforms that need these things, so
maybe this will eventually solve itself.

Bjorn


From kabel at kernel.org  Wed Jan 12 07:36:27 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Wed, 12 Jan 2022 16:36:27 +0100
Subject: [PATCH v2 09/11] dt-bindings: PCI: mvebu: Update information
 about intx interrupts
In-Reply-To: <20220112151814.24361-10-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-10-pali@kernel.org>
Message-ID: <20220112163627.4e975d24@thinkpad>

On Wed, 12 Jan 2022 16:18:12 +0100
Pali Roh?r <pali at kernel.org> wrote:

> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Acked-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/pci/mvebu-pci.txt | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/mvebu-pci.txt b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> index 24225852bce0..6d022a9d36ee 100644
> --- a/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> +++ b/Documentation/devicetree/bindings/pci/mvebu-pci.txt
> @@ -81,6 +81,11 @@ and the following optional properties:
>  - reset-gpios: optional GPIO to PERST#
>  - reset-delay-us: delay in us to wait after reset de-assertion, if not
>    specified will default to 100ms, as required by the PCIe specification.
> +- interrupt-names: list of interrupt names, supported are:
> +   - "intx" - interrupt line triggered by one of the legacy interrupt
> +- interrupts or interrupts-extended: List of the interrupt sources which
> +  corresponding to the "interrupt-names". If non-empty then also additional
> +  'interrupt-controller' subnode must be defined.
>  
>  Example:
>  

Empty commit message. At least add something like this:

Document the following additional properties in the mvebu-pci DT
binding:
- interrupt-names
- interrupts / interrupts-extended


Marek


From rex-bc.chen at mediatek.com  Wed Jan 12 07:36:36 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 12 Jan 2022 23:36:36 +0800
Subject: [v8, PATCH 0/3] force hsa hbp hfp packets multiple of lanenum to avoid
 screen shift
Message-ID: <20220112153639.12343-1-rex-bc.chen@mediatek.com>

Changes since v7:
 - Rebase to kernel 5.16
 - Add tags of reviewed-by and acked-by.
 - Add detailed commit message for flag "hs_packet_end_aligned" in DSI common driver.

Changes since v6:
 - Add "bool hs_packet_end_aligned" in "struct mipi_dsi_device" to control the dsi aligned.
 - Config the "hs_packet_end_aligned" in ANX7725 .attach().

Changes since v5:
 - Search the anx7625 compatible as flag to control dsi output aligned.

Changes since v4:
 - Move "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null" before
   "drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid".
 - Retitle "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null".

Rex-BC Chen (3):
  drm/dsi: transfer DSI HS packets ending at the same time
  drm/mediatek: implement the DSI hs packets aligned
  drm/bridge: anx7625: config hs packets end aligned to avoid screen shift

 drivers/gpu/drm/bridge/analogix/anx7625.c |  1 +
 drivers/gpu/drm/mediatek/mtk_dsi.c        | 10 ++++++++++
 include/drm/drm_mipi_dsi.h                |  3 +++
 3 files changed, 14 insertions(+)

-- 
2.18.0



From rex-bc.chen at mediatek.com  Wed Jan 12 07:36:39 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 12 Jan 2022 23:36:39 +0800
Subject: [v8, PATCH 3/3] drm/bridge: anx7625: config hs packets end aligned to
 avoid screen shift
In-Reply-To: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
References: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
Message-ID: <20220112153639.12343-4-rex-bc.chen@mediatek.com>

This device requires the packets on lanes aligned at the end to fix
screen shift or scroll.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Reviewed-by: Xin Ji <xji at analogixsemi.com>
Acked-by: Robert Foss <robert.foss at linaro.org>
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 2346dbcc505f..672705a68dae 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1674,6 +1674,7 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
 		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
 		MIPI_DSI_MODE_VIDEO_HSE;
+	dsi->hs_packet_end_aligned = true;
 
 	ret = devm_mipi_dsi_attach(dev, dsi);
 	if (ret) {
-- 
2.18.0



From rex-bc.chen at mediatek.com  Wed Jan 12 07:36:38 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 12 Jan 2022 23:36:38 +0800
Subject: [v8, PATCH 2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
References: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
Message-ID: <20220112153639.12343-3-rex-bc.chen@mediatek.com>

Some DSI RX devices require the packets on all lanes aligned at the end.
Otherwise, there will be some issues of shift or scroll for screen.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..2f3ff9b595a4 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -195,6 +195,8 @@ struct mtk_dsi {
 	struct clk *hs_clk;
 
 	u32 data_rate;
+	/* force dsi line end without dsi_null data */
+	bool hs_packet_end_aligned;
 
 	unsigned long mode_flags;
 	enum mipi_dsi_pixel_format format;
@@ -500,6 +502,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
 	}
 
+	if (dsi->hs_packet_end_aligned) {
+		horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
+		horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
+	}
+
 	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
@@ -794,6 +803,7 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
+	dsi->hs_packet_end_aligned = device->hs_packet_end_aligned;
 
 	return 0;
 }
-- 
2.18.0



From rppt at kernel.org  Wed Jan 12 07:45:40 2022
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 12 Jan 2022 17:45:40 +0200
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <Yd6S6Js1W4AnFFmv@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <YdwKB3SfF7hkB9Xv@kernel.org> <Yd6S6Js1W4AnFFmv@google.com>
Message-ID: <Yd73pDkMOMVHhXzu@kernel.org>

On Wed, Jan 12, 2022 at 01:35:52AM -0700, Yu Zhao wrote:
> On Mon, Jan 10, 2022 at 12:27:19PM +0200, Mike Rapoport wrote:
> > Hi,
> > 
> > On Tue, Jan 04, 2022 at 01:22:27PM -0700, Yu Zhao wrote:
> > > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> > > 
> > > Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention.
> > > Compared with the size-based approach, e.g., [1], this time-based
> > > approach has the following advantages:
> > > 1) It's easier to configure because it's agnostic to applications and
> > >    memory sizes.
> > > 2) It's more reliable because it's directly wired to the OOM killer.
> > > 
> > > Add /sys/kernel/debug/lru_gen for working set estimation and proactive
> > > reclaim. Compared with the page table-based approach and the PFN-based
> > > approach, e.g., mm/damon/[vp]addr.c, this lruvec-based approach has
> > > the following advantages:
> > > 1) It offers better choices because it's aware of memcgs, NUMA nodes,
> > >    shared mappings and unmapped page cache.
> > > 2) It's more scalable because it's O(nr_hot_evictable_pages), whereas
> > >    the PFN-based approach is O(nr_total_pages).
> > > 
> > > Add /sys/kernel/debug/lru_gen_full for debugging.
> > > 
> > > [1] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/
> > > 
> > > Signed-off-by: Yu Zhao <yuzhao at google.com>
> > > Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> > > ---
> > >  Documentation/vm/index.rst        |   1 +
> > >  Documentation/vm/multigen_lru.rst |  62 +++++
> > 
> > The description of user visible interfaces should go to
> > Documentation/admin-guide/mm
> > 
> > Documentation/vm/multigen_lru.rst should have contained design description
> > and the implementation details and it would be great to actually have such
> > document.
> 
> Will do, thanks.
> 
> > >  include/linux/nodemask.h          |   1 +
> > >  mm/vmscan.c                       | 415 ++++++++++++++++++++++++++++++
> > >  4 files changed, 479 insertions(+)
> > >  create mode 100644 Documentation/vm/multigen_lru.rst
> > > 
> > > diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
> > > index 6f5ffef4b716..f25e755b4ff4 100644
> > > --- a/Documentation/vm/index.rst
> > > +++ b/Documentation/vm/index.rst
> > > @@ -38,3 +38,4 @@ algorithms.  If you are looking for advice on simply allocating memory, see the
> > >     unevictable-lru
> > >     z3fold
> > >     zsmalloc
> > > +   multigen_lru
> > > diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
> > > new file mode 100644
> > > index 000000000000..6f9e0181348b
> > > --- /dev/null
> > > +++ b/Documentation/vm/multigen_lru.rst
> > > @@ -0,0 +1,62 @@
> > > +.. SPDX-License-Identifier: GPL-2.0
> > > +
> > > +=====================
> > > +Multigenerational LRU
> > > +=====================
> > > +
> > > +Quick start
> > > +===========
> > > +Runtime configurations
> > > +----------------------
> > > +:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
> > > + feature wasn't enabled by default.
> > 
> > Required for what? This sentence seem to lack context. Maybe add an
> > overview what is Multigenerational LRU so that users will have an idea what
> > these knobs control.
> 
> Apparently I left an important part of this quick start in the next
> patch, where Kconfig options are added. I'm wonder whether I should
> squash the next patch into this one.

I think documentation deserves a separate patch.
 

-- 
Sincerely yours,
Mike.


From rex-bc.chen at mediatek.com  Wed Jan 12 07:36:37 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 12 Jan 2022 23:36:37 +0800
Subject: [v8,
 PATCH 1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
References: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
Message-ID: <20220112153639.12343-2-rex-bc.chen@mediatek.com>

Since a HS transmission is composed of an arbitrary number
of bytes that may not be an integer multiple of lanes, some
lanes may run out of data before others.
(Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)

However, for some DSI RX devices (for example, anx7625),
there is a limitation that packet number should be the same
on all DSI lanes. In other words, they need to end a HS at
the same time.

Because this limitation is for some specific DSI RX devices,
it is more reasonable to put the enable control in these
DSI RX drivers. If DSI TX driver knows the information,
they can adjust the setting for this situation.

Therefore, add a flag to control this situation beacuse the
mipi DSI specification is not forbidden this situation.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 include/drm/drm_mipi_dsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 147e51b6d241..df4d15345326 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -177,6 +177,8 @@ struct mipi_dsi_device_info {
  * @lp_rate: maximum lane frequency for low power mode in hertz, this should
  * be set to the real limits of the hardware, zero is only accepted for
  * legacy drivers
+ * @hs_packet_end_aligned: transfer DSI HS packets ending at the same time
+ * for all DSI lanes
  */
 struct mipi_dsi_device {
 	struct mipi_dsi_host *host;
@@ -189,6 +191,7 @@ struct mipi_dsi_device {
 	unsigned long mode_flags;
 	unsigned long hs_rate;
 	unsigned long lp_rate;
+	bool hs_packet_end_aligned;
 };
 
 #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
-- 
2.18.0



From rinni at inventati.org  Wed Jan 12 07:49:27 2022
From: rinni at inventati.org (Philip Rinn)
Date: Wed, 12 Jan 2022 16:49:27 +0100
Subject: [PATCH RESEND v3] arm64: dts: allwinner: a64: olinuxino: Enable
 audio
In-Reply-To: <20220112084831.cwu6qcvxoygvfcyy@houat>
References: <20220112084831.cwu6qcvxoygvfcyy@houat>
Message-ID: <20220112154926.13619-1-rinni@inventati.org>

Enable the audio hardware on the Olimex A64-OLinuXino board family.
Tested on the A64-OLinuXino-2Ge8G-IND variant.

Signed-off-by: Philip Rinn <rinni at inventati.org>
---

Changes in v2: added missing &sound {...} part
Changes in v3: removed HDMI audio part as requested by Jernej ?krabec

 arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts    | 30 +++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
index ec7e2c0e82c1..6f2674bb1b7f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
@@ -58,6 +58,15 @@ wifi_pwrseq: wifi_pwrseq {
 	};
 };
 
+&codec {
+	status = "okay";
+};
+
+&codec_analog {
+	cpvdd-supply = <&reg_eldo1>;
+	status = "okay";
+};
+
 &cpu0 {
 	cpu-supply = <&reg_dcdc2>;
 };
@@ -74,6 +83,10 @@ &cpu3 {
 	cpu-supply = <&reg_dcdc2>;
 };
 
+&dai {
+	status = "okay";
+};
+
 &de {
 	status = "okay";
 };
@@ -328,6 +341,23 @@ &simplefb_hdmi {
 	vcc-hdmi-supply = <&reg_dldo1>;
 };
 
+&sound {
+	simple-audio-card,aux-devs = <&codec_analog>;
+	simple-audio-card,widgets = "Microphone", "Microphone Jack Left",
+		    "Microphone", "Microphone Jack Right",
+		    "Headphone", "Headphone Jack";
+	simple-audio-card,routing = "Left DAC", "DACL",
+		    "Right DAC", "DACR",
+		    "Headphone Jack", "HP",
+		    "ADCL", "Left ADC",
+		    "ADCR", "Right ADC",
+		    "Microphone Jack Left", "MBIAS",
+		    "MIC1", "Microphone Jack Left",
+		    "Microphone Jack Left", "HBIAS",
+		    "MIC2", "Microphone Jack Right";
+	status = "okay";
+};
+
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pb_pins>;
-- 
2.34.1



From hch at lst.de  Wed Jan 12 08:09:35 2022
From: hch at lst.de (Christoph Hellwig)
Date: Wed, 12 Jan 2022 17:09:35 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64
 in fcntl.h
In-Reply-To: <CAK8P3a3FgHQ+w+Sj00yOERRLWfVhx7NYsGJ1NBAXQ0=is3G=Kg@mail.gmail.com>
References: <20220111083515.502308-1-hch@lst.de>
 <20220111083515.502308-5-hch@lst.de>
 <CAK8P3a0mHC5=OOGV=sGnC9JqZWxzsJyZbTefnCtryQU3o3PY_g@mail.gmail.com>
 <20220112075609.GA4854@lst.de>
 <CAK8P3a1ONn=FiPU3669MjBMntS-1K5bgX4pHforUsYJ7yhwZ-g@mail.gmail.com>
 <f86483fca8b0dc68ce243ba47998ff3296a3b6f8.camel@kernel.org>
 <CAK8P3a3FgHQ+w+Sj00yOERRLWfVhx7NYsGJ1NBAXQ0=is3G=Kg@mail.gmail.com>
Message-ID: <20220112160935.GA3684@lst.de>

On Wed, Jan 12, 2022 at 01:08:24PM +0100, Arnd Bergmann wrote:
> > I don't have a strong opinion here. If we were taking symbols away that
> > were previously visible to userland it would be one thing, but since
> > we're just adding symbols that may not have been there before, this
> > seems less likely to break anything.
> 
> Changing
> 
> #ifndef CONFIG_64BIT
> 
> to
> 
> #if __BITS_PER_LONG==32 || defined(__KERNEL__),
> 
> would take symbols away, since the CONFIG_64BIT macro is never
> set in user space.

Yes.

> > I probably lean toward Christoph's original solution instead of keeping
> > the conditional definitions. It's hard to imagine there are many
> > programs that care whether these other symbols are defined or not.
> >
> > You can add this to the original patch:
> >
> > Acked-by: Jeff Layton <jlayton at kernel.org>
> 
> Sounds good, thanks

So should we go ahead with the series as-is?  Or respin it?  Or add
the above change ontop?


From lkp at intel.com  Wed Jan 12 08:08:44 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 00:08:44 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <202201130013.KVlPG5Gj-lkp@intel.com>

Hi Yu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on next-20220112]
[cannot apply to robh/for-next soc/for-next clk/clk-next v5.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yu-Tu/the-UART-driver-compatible-with/20220110-170020
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: m68k-randconfig-m031-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130013.KVlPG5Gj-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/6d55159e6626326d9001d4c8f20b914a69c2c40b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yu-Tu/the-UART-driver-compatible-with/20220110-170020
        git checkout 6d55159e6626326d9001d4c8f20b914a69c2c40b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   m68k-linux-ld: arch/m68k/kernel/machine_kexec.o: in function `machine_kexec':
   machine_kexec.c:(.text+0x6a): undefined reference to `m68k_mmutype'
   m68k-linux-ld: machine_kexec.c:(.text+0x72): undefined reference to `m68k_cputype'
   m68k-linux-ld: arch/m68k/kernel/relocate_kernel.o:(.m68k_fixup+0x0): undefined reference to `M68K_FIXUP_MEMOFFSET'
   m68k-linux-ld: arch/m68k/kernel/relocate_kernel.o:(.m68k_fixup+0x8): undefined reference to `M68K_FIXUP_MEMOFFSET'
   m68k-linux-ld: arch/m68k/kernel/uboot.o: in function `process_uboot_commandline':
   uboot.c:(.init.text+0x32): undefined reference to `_init_sp'
   m68k-linux-ld: drivers/tty/serial/meson_uart.o: in function `meson_uart_probe_clocks':
   meson_uart.c:(.text+0x4de): undefined reference to `__clk_get_name'
>> m68k-linux-ld: meson_uart.c:(.text+0x53c): undefined reference to `__devm_clk_hw_register_divider'
>> m68k-linux-ld: meson_uart.c:(.text+0x5a8): undefined reference to `__devm_clk_hw_register_mux'
>> m68k-linux-ld: meson_uart.c:(.text+0x5c0): undefined reference to `clk_hw_get_rate'
>> m68k-linux-ld: meson_uart.c:(.text+0x5d2): undefined reference to `clk_hw_get_name'
   m68k-linux-ld: meson_uart.c:(.text+0x622): undefined reference to `__devm_clk_hw_register_divider'
>> m68k-linux-ld: meson_uart.c:(.text+0x63c): undefined reference to `clk_hw_get_clk'
>> m68k-linux-ld: meson_uart.c:(.text+0x666): undefined reference to `__clk_get_name'
>> m68k-linux-ld: meson_uart.c:(.text+0x6ae): undefined reference to `devm_clk_hw_register_fixed_factor'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mathieu.desnoyers at efficios.com  Wed Jan 12 08:11:04 2022
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Date: Wed, 12 Jan 2022 11:11:04 -0500 (EST)
Subject: [PATCH 07/23] membarrier: Rewrite sync_core_before_usermode()
 and improve documentation
In-Reply-To: <d2f76c148fa039d2dea404c03e5fcd2f3dbf3750.1641659630.git.luto@kernel.org>
References: <cover.1641659630.git.luto@kernel.org>
 <d2f76c148fa039d2dea404c03e5fcd2f3dbf3750.1641659630.git.luto@kernel.org>
Message-ID: <1769209086.24770.1642003864649.JavaMail.zimbra@efficios.com>

----- On Jan 8, 2022, at 11:43 AM, Andy Lutomirski luto at kernel.org wrote:

> The old sync_core_before_usermode() comments suggested that a
> non-icache-syncing return-to-usermode instruction is x86-specific and that
> all other architectures automatically notice cross-modified code on return
> to userspace.
> 
> This is misleading.  The incantation needed to modify code from one
> CPU and execute it on another CPU is highly architecture dependent.
> On x86, according to the SDM, one must modify the code, issue SFENCE
> if the modification was WC or nontemporal, and then issue a "serializing
> instruction" on the CPU that will execute the code.  membarrier() can do
> the latter.
> 
> On arm, arm64 and powerpc, one must flush the icache and then flush the
> pipeline on the target CPU, although the CPU manuals don't necessarily use
> this language.
> 
> So let's drop any pretense that we can have a generic way to define or
> implement membarrier's SYNC_CORE operation and instead require all
> architectures to define the helper and supply their own documentation as to
> how to use it.  This means x86, arm64, and powerpc for now.  Let's also
> rename the function from sync_core_before_usermode() to
> membarrier_sync_core_before_usermode() because the precise flushing details
> may very well be specific to membarrier, and even the concept of
> "sync_core" in the kernel is mostly an x86-ism.
> 
> (It may well be the case that, on real x86 processors, synchronizing the
> icache (which requires no action at all) and "flushing the pipeline" is
> sufficient, but trying to use this language would be confusing at best.
> LFENCE does something awfully like "flushing the pipeline", but the SDM
> does not permit LFENCE as an alternative to a "serializing instruction"
> for this purpose.)

A few comments below:

[...]

> +# On powerpc, a program can use MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE
> +# similarly to arm64.  It would be nice if the powerpc maintainers could
> +# add a more clear explanantion.

Any thoughts from ppc maintainers ?

[...]

> diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
> index e9da3dc71254..b47cd22b2eb1 100644
> --- a/arch/x86/kernel/alternative.c
> +++ b/arch/x86/kernel/alternative.c
> @@ -17,7 +17,7 @@
> #include <linux/kprobes.h>
> #include <linux/mmu_context.h>
> #include <linux/bsearch.h>
> -#include <linux/sync_core.h>
> +#include <asm/sync_core.h>

All this churn wrt move from linux/sync_core.h to asm/sync_core.h
should probably be moved to a separate cleanup patch.

> #include <asm/text-patching.h>
> #include <asm/alternative.h>
> #include <asm/sections.h>
> diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c
> index 193204aee880..a2529e09f620 100644
> --- a/arch/x86/kernel/cpu/mce/core.c
> +++ b/arch/x86/kernel/cpu/mce/core.c
> @@ -41,12 +41,12 @@
> #include <linux/irq_work.h>
> #include <linux/export.h>
> #include <linux/set_memory.h>
> -#include <linux/sync_core.h>
> #include <linux/task_work.h>
> #include <linux/hardirq.h>
> 
> #include <asm/intel-family.h>
> #include <asm/processor.h>
> +#include <asm/sync_core.h>
> #include <asm/traps.h>
> #include <asm/tlbflush.h>
> #include <asm/mce.h>

[...]

> diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
> index d7ef61e602ed..462c667bd6c4 100644
> --- a/drivers/misc/sgi-gru/grufault.c
> +++ b/drivers/misc/sgi-gru/grufault.c
> @@ -20,8 +20,8 @@
> #include <linux/io.h>
> #include <linux/uaccess.h>
> #include <linux/security.h>
> -#include <linux/sync_core.h>
> #include <linux/prefetch.h>
> +#include <asm/sync_core.h>
> #include "gru.h"
> #include "grutables.h"
> #include "grulib.h"
> diff --git a/drivers/misc/sgi-gru/gruhandles.c
> b/drivers/misc/sgi-gru/gruhandles.c
> index 1d75d5e540bc..c8cba1c1b00f 100644
> --- a/drivers/misc/sgi-gru/gruhandles.c
> +++ b/drivers/misc/sgi-gru/gruhandles.c
> @@ -16,7 +16,7 @@
> #define GRU_OPERATION_TIMEOUT	(((cycles_t) local_cpu_data->itc_freq)*10)
> #define CLKS2NSEC(c)		((c) *1000000000 / local_cpu_data->itc_freq)
> #else
> -#include <linux/sync_core.h>
> +#include <asm/sync_core.h>
> #include <asm/tsc.h>
> #define GRU_OPERATION_TIMEOUT	((cycles_t) tsc_khz*10*1000)
> #define CLKS2NSEC(c)		((c) * 1000000 / tsc_khz)
> diff --git a/drivers/misc/sgi-gru/grukservices.c
> b/drivers/misc/sgi-gru/grukservices.c
> index 0ea923fe6371..ce03ff3f7c3a 100644
> --- a/drivers/misc/sgi-gru/grukservices.c
> +++ b/drivers/misc/sgi-gru/grukservices.c
> @@ -16,10 +16,10 @@
> #include <linux/miscdevice.h>
> #include <linux/proc_fs.h>
> #include <linux/interrupt.h>
> -#include <linux/sync_core.h>
> #include <linux/uaccess.h>
> #include <linux/delay.h>
> #include <linux/export.h>
> +#include <asm/sync_core.h>
> #include <asm/io_apic.h>
> #include "gru.h"
> #include "grulib.h"
> diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
> index e8919995d8dd..e107f292fc42 100644
> --- a/include/linux/sched/mm.h
> +++ b/include/linux/sched/mm.h
> @@ -7,7 +7,6 @@
> #include <linux/sched.h>
> #include <linux/mm_types.h>
> #include <linux/gfp.h>
> -#include <linux/sync_core.h>
> 
> /*
>  * Routines for handling mm_structs
> diff --git a/include/linux/sync_core.h b/include/linux/sync_core.h
> deleted file mode 100644
> index 013da4b8b327..000000000000
> --- a/include/linux/sync_core.h
> +++ /dev/null
> @@ -1,21 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -#ifndef _LINUX_SYNC_CORE_H
> -#define _LINUX_SYNC_CORE_H
> -
> -#ifdef CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
> -#include <asm/sync_core.h>
> -#else
> -/*
> - * This is a dummy sync_core_before_usermode() implementation that can be used
> - * on all architectures which return to user-space through core serializing
> - * instructions.
> - * If your architecture returns to user-space through non-core-serializing
> - * instructions, you need to write your own functions.
> - */
> -static inline void sync_core_before_usermode(void)
> -{
> -}
> -#endif
> -
> -#endif /* _LINUX_SYNC_CORE_H */
> -

Thanks,

Mathieu

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


From yann.gautier at foss.st.com  Wed Jan 12 08:32:23 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:23 +0100
Subject: [PATCH 07/10] ARM: dts: stm32: add sdmmc sleep config for
 STM32MP135F-DK
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-8-yann.gautier@foss.st.com>

Add sleep properties in pinctrl config for SDMMC1.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp135f-dk.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp135f-dk.dts b/arch/arm/boot/dts/stm32mp135f-dk.dts
index aae8d3512f4b..ee100d108ea2 100644
--- a/arch/arm/boot/dts/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/stm32mp135f-dk.dts
@@ -38,9 +38,10 @@
 };
 
 &sdmmc1 {
-	pinctrl-names = "default", "opendrain";
+	pinctrl-names = "default", "opendrain", "sleep";
 	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
 	pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>;
+	pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
 	broken-cd;
 	disable-wp;
 	st,neg-edge;
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:16 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:16 +0100
Subject: [PATCH 00/10] ARM: dts: stm32: update sdmmc nodes
Message-ID: <20220112163226.25384-1-yann.gautier@foss.st.com>

This patches series brings updates for SDMMC nodes on STM32MP13
(max frequency, pins slew-rates, sleep pins, and controller version).
The sdmmc2 node is also added as STM32MP13 embeds 2 SDMMC controllers.

The compatible for sdmmc nodes is also updated for both STM32MP13
and STM32MP15, to align with bootloaders DT, and after arm,pl18x.yaml
has been updated [1].

[1] commit 552bc46484b3 ("dt-bindings: mmc: mmci: Add st,stm32-sdmmc2
    compatible")

Gerald Baeza (1):
  ARM: dts: stm32: update sdmmc slew-rate in stm32mp13 pinctrl

Yann Gautier (9):
  ARM: dts: stm32: add st,stm32-sdmmc2 compatible on stm32mp151
  ARM: dts: stm32: add st,stm32-sdmmc2 compatible on stm32mp131
  ARM: dts: stm32: increase SDMMC max-frequency for STM32MP13
  ARM: dts: stm32: update SDMMC clock slew-rate on STM32MP135F-DK board
  ARM: dts: stm32: add sdmmc sleep pins for STM32MP13
  ARM: dts: stm32: add sdmmc sleep config for STM32MP135F-DK
  ARM: dts: stm32: update SDMMC version for STM32MP13
  ARM: dts: stm32: add SDMMC2 in STM32MP13 DT
  ARM: dts: stm32: add sdmmc2 pins for STM32MP13

 arch/arm/boot/dts/stm32mp13-pinctrl.dtsi | 81 ++++++++++++++++++++----
 arch/arm/boot/dts/stm32mp131.dtsi        | 20 +++++-
 arch/arm/boot/dts/stm32mp135f-dk.dts     |  7 +-
 arch/arm/boot/dts/stm32mp151.dtsi        |  6 +-
 4 files changed, 94 insertions(+), 20 deletions(-)

-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:21 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:21 +0100
Subject: [PATCH 05/10] ARM: dts: stm32: update SDMMC clock slew-rate on
 STM32MP135F-DK board
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-6-yann.gautier@foss.st.com>

Add sdmmc1_clk_pins_a in sdmmc1 pinctrl nodes, to properly manage
clock slew-rate.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp135f-dk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp135f-dk.dts b/arch/arm/boot/dts/stm32mp135f-dk.dts
index 7e96d9e36217..aae8d3512f4b 100644
--- a/arch/arm/boot/dts/stm32mp135f-dk.dts
+++ b/arch/arm/boot/dts/stm32mp135f-dk.dts
@@ -39,8 +39,8 @@
 
 &sdmmc1 {
 	pinctrl-names = "default", "opendrain";
-	pinctrl-0 = <&sdmmc1_b4_pins_a>;
-	pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+	pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_clk_pins_a>;
+	pinctrl-1 = <&sdmmc1_b4_od_pins_a &sdmmc1_clk_pins_a>;
 	broken-cd;
 	disable-wp;
 	st,neg-edge;
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:19 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:19 +0100
Subject: [PATCH 03/10] ARM: dts: stm32: increase SDMMC max-frequency for
 STM32MP13
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-4-yann.gautier@foss.st.com>

The max-frequency limitation is due to IOs.
On STM32MP13, it is 130MHz. Update the corresponding property.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index 9b318fcd6ef0..672ac9360619 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -131,7 +131,7 @@
 			clock-names = "apb_pclk";
 			cap-sd-highspeed;
 			cap-mmc-highspeed;
-			max-frequency = <120000000>;
+			max-frequency = <130000000>;
 			status = "disabled";
 		};
 
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:18 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:18 +0100
Subject: [PATCH 02/10] ARM: dts: stm32: add st,
 stm32-sdmmc2 compatible on stm32mp131
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-3-yann.gautier@foss.st.com>

To align with bootloaders device tree files, and thanks to what was
added in yaml file [1], the compatible property for sdmmc1 node is
updated with "st,stm32-sdmmc2" string.

[1] commit 552bc46484b3 ("dt-bindings: mmc: mmci: Add st,stm32-sdmmc2
    compatible")

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index 86126dc0d898..9b318fcd6ef0 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -122,7 +122,7 @@
 		};
 
 		sdmmc1: mmc at 58005000 {
-			compatible = "arm,pl18x", "arm,primecell";
+			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x00253180>;
 			reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
 			interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:20 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:20 +0100
Subject: [PATCH 04/10] ARM: dts: stm32: update sdmmc slew-rate in stm32mp13
 pinctrl
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-5-yann.gautier@foss.st.com>

From: Gerald Baeza <gerald.baeza at foss.st.com>

SDMMC1/2 CK <= 50 MHz so slew-rate = <1>
A new node sdmmc1-clk-0 is added to manage the new clock pin slew-rate.

Signed-off-by: Gerald Baeza <gerald.baeza at foss.st.com>
Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp13-pinctrl.dtsi | 23 ++++++++++-------------
 1 file changed, 10 insertions(+), 13 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
index 069f95f2b628..ebb83c56c350 100644
--- a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
@@ -7,7 +7,7 @@
 
 &pinctrl {
 	sdmmc1_b4_pins_a: sdmmc1-b4-0 {
-		pins1 {
+		pins {
 			pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
 				 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
 				 <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
@@ -17,12 +17,6 @@
 			drive-push-pull;
 			bias-disable;
 		};
-		pins2 {
-			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
-			slew-rate = <2>;
-			drive-push-pull;
-			bias-disable;
-		};
 	};
 
 	sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
@@ -36,12 +30,6 @@
 			bias-disable;
 		};
 		pins2 {
-			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
-			slew-rate = <2>;
-			drive-push-pull;
-			bias-disable;
-		};
-		pins3 {
 			pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
 			slew-rate = <1>;
 			drive-open-drain;
@@ -49,6 +37,15 @@
 		};
 	};
 
+	sdmmc1_clk_pins_a: sdmmc1-clk-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-disable;
+		};
+	};
+
 	uart4_pins_a: uart4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 6, AF8)>; /* UART4_TX */
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:17 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:17 +0100
Subject: [PATCH 01/10] ARM: dts: stm32: add st,
 stm32-sdmmc2 compatible on stm32mp151
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-2-yann.gautier@foss.st.com>

To align with bootloaders device tree files, and thanks to what was
added in yaml file [1], the compatible property for sdmmc nodes is
updated with "st,stm32-sdmmc2" string.

[1] commit 552bc46484b3 ("dt-bindings: mmc: mmci: Add st,stm32-sdmmc2
    compatible")

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp151.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi
index 1cfc2f011e70..39e5ea16db88 100644
--- a/arch/arm/boot/dts/stm32mp151.dtsi
+++ b/arch/arm/boot/dts/stm32mp151.dtsi
@@ -1059,7 +1059,7 @@
 		};
 
 		sdmmc3: mmc at 48004000 {
-			compatible = "arm,pl18x", "arm,primecell";
+			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x00253180>;
 			reg = <0x48004000 0x400>;
 			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
@@ -1381,7 +1381,7 @@
 		};
 
 		sdmmc1: mmc at 58005000 {
-			compatible = "arm,pl18x", "arm,primecell";
+			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x00253180>;
 			reg = <0x58005000 0x1000>;
 			interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
@@ -1396,7 +1396,7 @@
 		};
 
 		sdmmc2: mmc at 58007000 {
-			compatible = "arm,pl18x", "arm,primecell";
+			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
 			arm,primecell-periphid = <0x00253180>;
 			reg = <0x58007000 0x1000>;
 			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:32:22 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:32:22 +0100
Subject: [PATCH 06/10] ARM: dts: stm32: add sdmmc sleep pins for STM32MP13
In-Reply-To: <20220112163226.25384-1-yann.gautier@foss.st.com>
References: <20220112163226.25384-1-yann.gautier@foss.st.com>
Message-ID: <20220112163226.25384-7-yann.gautier@foss.st.com>

The node sdmmc1_b4_sleep_pins_a is added in stm32mp13-pinctrl.dtsi file.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp13-pinctrl.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
index ebb83c56c350..c6f78eef3698 100644
--- a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
@@ -37,6 +37,17 @@
 		};
 	};
 
+	sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
+				 <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
+				 <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
+				 <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
+				 <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
+				 <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
+		};
+	};
+
 	sdmmc1_clk_pins_a: sdmmc1-clk-0 {
 		pins {
 			pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:33:54 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:33:54 +0100
Subject: [PATCH 08/10] ARM: dts: stm32: update SDMMC version for STM32MP13
Message-ID: <20220112163356.25634-9-yann.gautier@foss.st.com>

From: Yann Gautier <yann.gautier at st.com>

On STM32MP13, the embedded SDMMC peripheral version is v2.2.
Update arm,primecell-periphid for SDMMC in the SoC DT file.

Signed-off-by: Yann Gautier <yann.gautier at st.com>
---
 arch/arm/boot/dts/stm32mp131.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index 672ac9360619..7189cba6b256 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -123,7 +123,7 @@
 
 		sdmmc1: mmc at 58005000 {
 			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
-			arm,primecell-periphid = <0x00253180>;
+			arm,primecell-periphid = <0x20253180>;
 			reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
 			interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "cmd_irq";
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:33:55 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:33:55 +0100
Subject: [PATCH 09/10] ARM: dts: stm32: add SDMMC2 in STM32MP13 DT
In-Reply-To: <20220112163356.25634-9-yann.gautier@foss.st.com>
References: <20220112163356.25634-9-yann.gautier@foss.st.com>
Message-ID: <20220112163356.25634-10-yann.gautier@foss.st.com>

STM32MP13 embeds 2 instances of SDMMC peripheral.
Add the required information in SoC device tree file.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp131.dtsi | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp131.dtsi b/arch/arm/boot/dts/stm32mp131.dtsi
index 7189cba6b256..a1efb545ca3d 100644
--- a/arch/arm/boot/dts/stm32mp131.dtsi
+++ b/arch/arm/boot/dts/stm32mp131.dtsi
@@ -135,6 +135,20 @@
 			status = "disabled";
 		};
 
+		sdmmc2: mmc at 58007000 {
+			compatible = "st,stm32-sdmmc2", "arm,pl18x", "arm,primecell";
+			arm,primecell-periphid = <0x20253180>;
+			reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+			interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "cmd_irq";
+			clocks = <&clk_pll4_p>;
+			clock-names = "apb_pclk";
+			cap-sd-highspeed;
+			cap-mmc-highspeed;
+			max-frequency = <130000000>;
+			status = "disabled";
+		};
+
 		iwdg2: watchdog at 5a002000 {
 			compatible = "st,stm32mp1-iwdg";
 			reg = <0x5a002000 0x400>;
-- 
2.17.1



From yann.gautier at foss.st.com  Wed Jan 12 08:33:56 2022
From: yann.gautier at foss.st.com (Yann Gautier)
Date: Wed, 12 Jan 2022 17:33:56 +0100
Subject: [PATCH 10/10] ARM: dts: stm32: add sdmmc2 pins for STM32MP13
In-Reply-To: <20220112163356.25634-9-yann.gautier@foss.st.com>
References: <20220112163356.25634-9-yann.gautier@foss.st.com>
Message-ID: <20220112163356.25634-11-yann.gautier@foss.st.com>

Those pins are used for SDIO on STM32MP135F-DK board.

Signed-off-by: Yann Gautier <yann.gautier at foss.st.com>
---
 arch/arm/boot/dts/stm32mp13-pinctrl.dtsi | 51 ++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
index c6f78eef3698..d2472cd8f1d0 100644
--- a/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp13-pinctrl.dtsi
@@ -57,6 +57,57 @@
 		};
 	};
 
+	sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF10)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
+		pins1 {
+			pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, AF10)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, AF10)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, AF10)>; /* SDMMC2_D3 */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+			slew-rate = <1>;
+			drive-open-drain;
+			bias-pull-up;
+		};
+	};
+
+	sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
+				 <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
+				 <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
+				 <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
+				 <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
+				 <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
+		};
+	};
+
+	sdmmc2_clk_pins_a: sdmmc2-clk-0 {
+		pins {
+			pinmux = <STM32_PINMUX('E', 3, AF10)>; /* SDMMC2_CK */
+			slew-rate = <1>;
+			drive-push-pull;
+			bias-pull-up;
+		};
+	};
+
 	uart4_pins_a: uart4-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 6, AF8)>; /* UART4_TX */
-- 
2.17.1



From pierre-louis.bossart at linux.intel.com  Wed Jan 12 08:42:04 2022
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Wed, 12 Jan 2022 10:42:04 -0600
Subject: [PATCH v2 0/1] firmware: mtk: add adsp ipc protocol for sof
In-Reply-To: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>
References: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>
Message-ID: <61ba06c7-74e4-03f9-2fe7-f12f862c7942@linux.intel.com>



On 1/12/22 5:32 AM, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> This patch provides mtk adsp ipc support for sof.
> 
> ADSP IPC protocol offers (send/recv) interfaces using
> mediatek-mailbox APIs.
> 
> changes since v1:
> - add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
> - remove unuseful MODULE_LICENSE
> - change label name to out_free

my comment was not on changing the label name, but making sure you only
free something that was allocated by using *two* labels.

> 
> Allen-KH Cheng (1):
>   firmware: mediatek: add adsp ipc protocol interface
> 
>  drivers/firmware/Kconfig                      |   1 +
>  drivers/firmware/Makefile                     |   1 +
>  drivers/firmware/mediatek/Kconfig             |   9 +
>  drivers/firmware/mediatek/Makefile            |   2 +
>  drivers/firmware/mediatek/mtk-adsp-ipc.c      | 159 ++++++++++++++++++
>  .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
>  6 files changed, 237 insertions(+)
>  create mode 100644 drivers/firmware/mediatek/Kconfig
>  create mode 100644 drivers/firmware/mediatek/Makefile
>  create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
>  create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h
> 


From matthias.bgg at gmail.com  Wed Jan 12 08:51:23 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Wed, 12 Jan 2022 17:51:23 +0100
Subject: [PATCH v3 0/5] Update MT8192 Clock Setting
In-Reply-To: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
Message-ID: <d36d276a-c3be-431b-3636-c313cabda3d4@gmail.com>



On 12/01/2022 12:55, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> This patch is base on v5.16-rc8,
> series "Mediatek MT8192 clock support"[1], [2] annd [3].
> [1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127
> [2] https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/
> [3] https://lore.kernel.org/all/20210825011120.30481-1-chun-jie.chen at mediatek.com/

Please update that list to only who the patches that are not yet upstream. That 
will help me to understand if I can take them right now or if we have to wait 
for something to get applied first.

Thanks,
Matthias

> 
> changes since v2:
>   - add missing "clock" at the end of commit message
> 
> changes since v1:
>   - update the commit message
> 
> Allen-KH Cheng (5):
>    arm64: dts: mediatek: Correct uart clock of MT8192
>    arm64: dts: mediatek: Correct SPI clock of MT8192
>    arm64: dts: mediatek: Correct Nor Flash clock of MT8192
>    arm64: dts: mediatek: Correct I2C clock of MT8192
>    arm64: dts: mediatek: Correct system timer clock of MT8192
> 
>   arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++-----------
>   1 file changed, 52 insertions(+), 40 deletions(-)
> 


From mathieu.poirier at linaro.org  Wed Jan 12 09:22:49 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 12 Jan 2022 10:22:49 -0700
Subject: [PATCH v2 6/6] Documentation: coresight: docs for config load
 via configfs
In-Reply-To: <20211130220100.25888-7-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-7-mike.leach@linaro.org>
Message-ID: <20220112172249.GA892261@p14s>

Hi Mike,

On Tue, Nov 30, 2021 at 10:01:00PM +0000, Mike Leach wrote:
> Add documentation covering the configfs updates that allow
> binary configuration files to be loaded and unloaded via configfs,
> along with the demonstration programs in samples.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  .../trace/coresight/coresight-config.rst      | 151 +++++++++++++++++-
>  1 file changed, 145 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst
> index 6d5ffa6f7347..f11def230fab 100644
> --- a/Documentation/trace/coresight/coresight-config.rst
> +++ b/Documentation/trace/coresight/coresight-config.rst
> @@ -152,7 +152,7 @@ follows::
>  
>      $ cd configurations/
>      $ ls
> -    autofdo
> +    autofdo last_load_status  load  unload
>      $ cd autofdo/
>      $ ls
>      description  feature_refs  preset1  preset3  preset5  preset7  preset9
> @@ -278,9 +278,19 @@ Creating and Loading Custom Configurations
>  ==========================================
>  
>  Custom configurations and / or features can be dynamically loaded into the
> -system by using a loadable module.
> +system by using a loadable module, or by loading a binary configuration
> +file in configfs.
> +
> +Loaded configurations can use previously loaded features. The system will
> +ensure that it is not possible to unload a feature that is currently in
> +use, by enforcing the unload order as the strict reverse of the load order.
> +
> +An example of a custom configuration module, and generators for binary
> +configuration files are found in './samples/coresight'.
>  
> -An example of a custom configuration is found in ./samples/coresight.
> +
> +Using a Loadable Module
> +-----------------------
>  
>  This creates a new configuration that uses the existing built in
>  strobing feature, but provides a different set of presets.
> @@ -289,6 +299,135 @@ When the module is loaded, then the configuration appears in the configfs
>  file system and is selectable in the same way as the built in configuration
>  described above.
>  
> -Configurations can use previously loaded features. The system will ensure
> -that it is not possible to unload a feature that is currently in use, by
> -enforcing the unload order as the strict reverse of the load order.
> +The file 'coresight-cfg-sample.c' contains the configuration and module
> +initialisation code needed to create the loadable module.
> +
> +This will be built alongside the kernel modules if select in KConfig.
> +
> +
> +Using a Binary Configuration File
> +---------------------------------
> +
> +Building the samples creates the 'coresight-cfg-filegen' program that will
> +generate a configuration binary 'example1.cscfg' that can be loaded into the
> +system using configfs. The configuration declared in the source file
> +'coresight-cfg-filegen.c' is named 'autofdo3' - the name that will be used
> +once loaded.
> +
> +The source files 'coresight-cfg-bufw.h' and 'coresight-cfg-bufw.c' provide a
> +standard function to convert a configuration declared in 'C' into the correct
> +binary buffer format. These files can be re-used to create new custom
> +configurations.
> +
> +The program  'coresight-cfg-file-read' can read back and print a configuration
> +binary. This is built using the reader from the driver code.
> +
> +There are additional attributes in the configurations directory - load, unload
> +and last_load_status that can be used to load and unload configuration
> +binary files. To load, 'cat' the binary config into the load attribute::
> +
> +    $ ls /config/cs-syscfg/configurations/
> +    autofdo last_load_status  load  unload
> +    $ cat example1.cscfg > /config/cs-syscfg/configurations/load
> +    $ ls /config/cs-syscfg/configurations/
> +    autofdo  autofdo3  last_load_status  load  unload
> +    $ cat /config/cs-syscfg/configurations/last_load_status
> +    OK: configuration file loaded (autofdo3).
> +
> +To unload, use the same file in the unload attribute::
> +
> +    $ cat example1.cscfg > /config/cs-syscfg/configurations/unload
> +    $ cat /config/cs-syscfg/configurations/last_load_status
> +    OK: configuration file unloaded (autofdo3).
> +    ls /config/cs-syscfg/configurations/
> +    autofdo  last_load_status  load  unload
> +
> +The generator and reader programs can also be built directly, separately from
> +the kernel build by using the 'Makefile.host' file. This allows native binaries
> +to be created on the host machine rather than cross compiled version for the
> +target.
> +
> +
> +Binary Configuration File Format
> +--------------------------------
> +
> +The file format is defined in the source file **coresight-config-file.h**
> +
> +The source reader and generator examples produce a binary of this format.
> +
> +This arrangement is reproduced below:-
> +
> +Overall File structure
> +~~~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_header]   // Mandatory
> +   [CONFIG_ELEM]         // Optional - one per file, if present, first element in file.
> +   [FEATURE_ELEM]*       // Optional - multiple, defined by cscfg_file_header.nr_features
> +
> +File is invalid if both [CONFIG_ELEM] and [FEATURE_ELEM] are omitted.
> +
> +A file that contains only [FEATURE_ELEM] may be loaded, and the features used
> +by subsequently loaded files with [CONFIG_ELEM] elements.
> +
> +Where [CONFIG_ELEM] is present, then **cscfg_file_header.nr_features** and
> +**CONFIG_ELEM.nr_feat_refs** must have the same value.
> +
> +CONFIG_ELEM element
> +~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_header]                // header length value to end of feature strings.
> +   [cscfg_file_elem_str]                   // name of the configuration.
> +   [cscfg_file_elem_str]                   // description of configuration.
> +   [u16 value](nr_presets)                 // number of defined presets.
> +   [u32 value](nr_total_params)            // total parameters defined by all used features.
> +   [u16 value](nr_feat_refs)               // number of features referenced by the configuration
> +   [u64 values] * (nr_presets * nr_total_params)     // the preset values.
> +   [cscfg_file_elem_str] * (nr_feat_refs)  // the features used in the configurations.

There seems to be a discrepency between the above format and the afdo3 structure
definition in sample file coresight-cfg-filegen.c. 

More comments to come...

Thanks,
Mathieu

> +
> +FEATURE_ELEM element
> +~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_header]                // header length is total bytes to end of param structures.
> +   [cscfg_file_elem_str]                   // feature name.
> +   [cscfg_file_elem_str]                   // feature description.
> +   [u32 value](match_flags)                // flags to associate the feature with a device.
> +   [u16 value](nr_regs)                    // number of registers.
> +   [u16 value](nr_params)                  // number of parameters.
> +   [cscfg_regval_desc struct] * (nr_regs)  // register definitions
> +   [PARAM_ELEM] * (nr_params)              // parameters definitions
> +
> +PARAM_ELEM element
> +~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_str]         // parameter name.
> +   [u64 value](param_value]      // initial value.
> +
> +Additional definitions.
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The following structures are defined in **coresight-config-file.h**
> +
> + * **struct cscfg_file_header** : This structure contains an initial magic number, the total
> +   length of the file, and the number of features in the file.
> + * **struct cscfg_file_elem_header**: This defines the total length and type of a CONFIG_ELEM
> +   or a FEATURE_ELEM.
> + * **struct cscfg_file_elem_str**: This defines a string and its length.
> +
> +The magic number in cscfg_file_header is defined as two bitfields::
> +
> +   [31:8] Fixed magic number to identify file type.
> +   [7:0]  Current file format version.
> +
> +The following defines determine the maximum overall file size and maximum individual
> +string size::
> +
> +   CSCFG_FILE_MAXSIZE       // maximum overall file size.
> +   CSCFG_FILE_STR_MAXSIZE   // maximum individual string size.
> -- 
> 2.17.1
> 


From jeanmichel.hautbois at ideasonboard.com  Wed Jan 12 09:27:18 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Wed, 12 Jan 2022 18:27:18 +0100
Subject: [RFC PATCH 1/3] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220112172719.1178446-2-jeanmichel.hautbois@ideasonboard.com>

Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera
interface. Also add a MAINTAINERS entry for it.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
Dave: I assumed you were the maintainer for this file, as I based it on the
bcm2835-unicam.txt file. Are  you happy to be added directly as the
maintainer, or should this be specified as "Raspberry Pi Kernel
Maintenance <kernel-list at raspberrypi.com>"
---
 .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
 MAINTAINERS                                   |   6 +
 2 files changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml

diff --git a/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
new file mode 100644
index 000000000000..1427514142cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/brcm,bcm2835-unicam.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM283x Camera Interface (Unicam)
+
+maintainers:
+  - Dave Stevenson <dave.stevenson at raspberrypi.com>
+
+description: |-
+  The Unicam block on BCM283x SoCs is the receiver for either
+  CSI-2 or CCP2 data from image sensors or similar devices.
+
+  The main platform using this SoC is the Raspberry Pi family of boards.
+  On the Pi the VideoCore firmware can also control this hardware block,
+  and driving it from two different processors will cause issues.
+  To avoid this, the firmware checks the device tree configuration
+  during boot. If it finds device tree nodes called csi0 or csi1 then
+  it will stop the firmware accessing the block, and it can then
+  safely be used via the device tree binding.
+
+properties:
+  compatible:
+    const: brcm,bcm2835-unicam
+
+  reg:
+    description:
+      physical base address and length of the register sets for the device.
+    maxItems: 1
+
+  interrupts:
+    description: the IRQ line for this Unicam instance.
+    maxItems: 1
+
+  clocks:
+    description: |-
+      list of clock specifiers, corresponding to entries in clock-names
+      property.
+
+  clock-names:
+    items:
+      - const: lp
+      - const: vpu
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: False
+
+examples:
+  - |
+    csi1: csi1 at 7e801000 {
+        compatible = "brcm,bcm2835-unicam";
+        reg = <0x7e801000 0x800>,
+              <0x7e802004 0x4>;
+        interrupts = <2 7>;
+        clocks = <&clocks BCM2835_CLOCK_CAM1>,
+                 <&firmware_clocks 4>;
+        clock-names = "lp", "vpu";
+        port {
+                csi1_ep: endpoint {
+                        remote-endpoint = <&tc358743_0>;
+                        data-lanes = <1 2>;
+                };
+        };
+    };
+
+    i2c0: i2c at 7e205000 {
+        tc358743: csi-hdmi-bridge at 0f {
+            compatible = "toshiba,tc358743";
+            reg = <0x0f>;
+            clocks = <&tc358743_clk>;
+            clock-names = "refclk";
+
+            tc358743_clk: bridge-clk {
+                    compatible = "fixed-clock";
+                    #clock-cells = <0>;
+                    clock-frequency = <27000000>;
+            };
+
+            port {
+                    tc358743_0: endpoint {
+                            remote-endpoint = <&csi1_ep>;
+                            clock-lanes = <0>;
+                            data-lanes = <1 2>;
+                            clock-noncontinuous;
+                            link-frequencies =
+                                /bits/ 64 <297000000>;
+                    };
+            };
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 269aa4d6b94a..7484255cad31 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3653,6 +3653,12 @@ N:	bcm113*
 N:	bcm216*
 N:	kona
 
+BROADCOM BCM2835 CAMERA DRIVER
+M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+
 BROADCOM BCM47XX MIPS ARCHITECTURE
 M:	Hauke Mehrtens <hauke at hauke-m.de>
 M:	Rafa? Mi?ecki <zajec5 at gmail.com>
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Wed Jan 12 09:27:17 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Wed, 12 Jan 2022 18:27:17 +0100
Subject: [RFC PATCH 0/3] Add support for BCM2835 camera interface (unicam)
Message-ID: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>

Hello !

This patch series adds the BCM2835 CCP2/CSI2 camera interface named
unicam. This driver is already used in the out-of-tree linux-rpi
repository [1], and this work aims to support it in mainline.

The series is based on top of:
- Rebased on top of 5.16 Tomi Valkeinen's multiplexed stream work, on
  his multistream/work branch [2] which has been submitted as v10 at the
  time of this writing. The objective is to demonstrate the use of
  multiplexed streams on a real world widely used example as well as
  supporting unicam mainline.
- "Add 12bit and 14bit luma-only formats" series [3].

The series is made of 4 patches:
- 2/3 introduces dt-bindings documentation and MAINTAINERS entry
  I have tentatively assigned maintainership, is this fine ?
- 2/3 adds the driver support in media/platform
- 3/3 modifies imx219 driver to make it use the multiplexed streams API

All those patches are in my tree [4].

Patch 2/3 comes from the linux-rpi work [1] with substantial
modifications:
- Removed the non-mc API which is deprecated, and not needed upstream
- Moved from one video node with two source pads (image and embedded) to
  two video nodes
- Added a subdev between the sensor and the video nodes to properly
  route the streams
- Added support for multiplexed streams API

In order to test it, one will need a RPi board and the camv2 (imx219)
sensor.  An updated v4l-utils is also needed [5] to have support for
multiplexed streams.

v4l2-compliance passes on both video devices, without streaming testing
though.

The downstream DTB's and overlays are used from the existing Raspberry
Pi OS for testing, and this series does not yet integrate the device
tree nodes into the upstream BCM2835 or BCM2711 device tree support.

The media-ctl topology is:
```
pi at raspberrypi:~ $ media-ctl -d0 -p
Media controller API version 5.16.0

Media device information
------------------------
driver          unicam
model           unicam
serial          
bus info        platform:fe801000.csi
hw revision     0x0
driver version  5.16.0

Device topology
- entity 1: unicam-subdev (3 pads, 3 links, 1 route)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
	routes:
		0/0 -> 1/0 [ACTIVE]
	pad0: Sink
		[stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
		<- "imx219 10-0010":0 [ENABLED,IMMUTABLE]
	pad1: Source
		[stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
		-> "unicam-image":0 [ENABLED,IMMUTABLE]
	pad2: Source
		-> "unicam-embedded":0 [ENABLED,IMMUTABLE]

- entity 5: imx219 10-0010 (1 pad, 1 link, 2 routes)
            type V4L2 subdev subtype Sensor flags 0
            device node name /dev/v4l-subdev1
	routes:
		0/0 -> 0/0 [ACTIVE, IMMUTABLE, SOURCE]
		0/0 -> 0/1 [ACTIVE, SOURCE]
	pad0: Source
		[stream:0 fmt:SRGGB10_1X10/3280x2464 field:none colorspace:raw
		crop.bounds:(8,8)/3280x2464
		crop:(8,8)/3280x2464]
		[stream:1 fmt:METADATA_8/16384x1 field:none
		crop.bounds:(8,8)/3280x2464
		crop:(8,8)/3280x2464]
		-> "unicam-subdev":0 [ENABLED,IMMUTABLE]

- entity 7: unicam-image (1 pad, 1 link, 0 route)
            type Node subtype V4L flags 1
            device node name /dev/video0
	pad0: Sink
		<- "unicam-subdev":1 [ENABLED,IMMUTABLE]

- entity 13: unicam-embedded (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video1
	pad0: Sink
		<- "unicam-subdev":2 [ENABLED,IMMUTABLE]
```

In order to properly configure the media pipeline, it is needed to call
the usual ioctls, and configure routing in order to send the embedded
data from the sensor to the "unicam-embedded" device node :

``` media=0
media-ctl -d${media} -l "'imx219 10-0010':0->'unicam-subdev':0 [1]"
media-ctl -d${media} -l "'unicam-subdev':1->'unicam-image':0 [1]"
media-ctl -d${media} -v -R "'unicam-subdev' [0/0->1/0[1],0/1->2/0[1]]"
media-ctl -d${media} -V "'imx219 10-0010':0/0
[fmt:SRGGB10_1X10/3280x2464 field:none]" v4l2-ctl -d0 --set-fmt-video
width=3280,height=2464,pixelformat='pRAA',field=none media-ctl
-d${media} -v -V "'imx219 10-0010':0/1 [fmt:METADATA_8/16384x1
field:none]" media-ctl -d${media} -p ```

Be sure to configure the routes before setting the format, as s_routing
resets the default format.

Then a frame can be capture with yavta:
`yavta --capture=1 /dev/video0 -F/tmp/test-#.bin`


[1]: https://github.com/raspberrypi/linux/tree/rpi-5.15.y
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git/log/?h=multistream/work
[3]: https://patchwork.linuxtv.org/project/linux-media/list/?series=7099
[4]: https://github.com/jhautbois/linux-rpi/tree/jmh/tomba/multistream/work-v10
[5]: https://github.com/tomba/v4l-utils

Jean-Michel Hautbois (3):
  media: dt-bindings: media: Add bindings for bcm2835-unicam
  media: bcm2835-unicam: Add support for for CCP2/CSI2 camera interface
  media: imx219: Add support for multiplexed streams

 .../bindings/media/brcm,bcm2835-unicam.yaml   |  103 +
 MAINTAINERS                                   |    7 +
 drivers/media/i2c/imx219.c                    |  458 +--
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/bcm2835/Kconfig        |   21 +
 drivers/media/platform/bcm2835/Makefile       |    3 +
 .../media/platform/bcm2835/bcm2835-unicam.c   | 2694 +++++++++++++++++
 .../media/platform/bcm2835/vc4-regs-unicam.h  |  253 ++
 9 files changed, 3332 insertions(+), 210 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
 create mode 100644 drivers/media/platform/bcm2835/Kconfig
 create mode 100644 drivers/media/platform/bcm2835/Makefile
 create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
 create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h

-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Wed Jan 12 09:27:20 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Wed, 12 Jan 2022 18:27:20 +0100
Subject: [RFC PATCH 3/3] media: imx219: Add support for multiplexed streams
In-Reply-To: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220112172719.1178446-4-jeanmichel.hautbois@ideasonboard.com>

As of now, imx219 was not supporting anything more than one stream. Add
support for embedded data, based on linux-rpi kernel, and make it work
with multiplexed streams. We have only one source pad with two streams:
stream 0 is the image, and stream 1 is the embedded data.

Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
 drivers/media/i2c/imx219.c | 458 ++++++++++++++++++++-----------------
 1 file changed, 248 insertions(+), 210 deletions(-)

diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index e10af3f74b38..d531b67f541b 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -118,6 +118,16 @@
 #define IMX219_PIXEL_ARRAY_WIDTH	3280U
 #define IMX219_PIXEL_ARRAY_HEIGHT	2464U
 
+/* Embedded metadata stream structure */
+#define IMX219_EMBEDDED_LINE_WIDTH 16384
+#define IMX219_NUM_EMBEDDED_LINES 1
+
+enum pad_types {
+	IMAGE_PAD,
+	METADATA_PAD,
+	NUM_PADS
+};
+
 struct imx219_reg {
 	u16 address;
 	u8 val;
@@ -429,7 +439,7 @@ static const char * const imx219_supply_name[] = {
  * - v flip
  * - h&v flips
  */
-static const u32 codes[] = {
+static const u32 imx219_mbus_formats[] = {
 	MEDIA_BUS_FMT_SRGGB10_1X10,
 	MEDIA_BUS_FMT_SGRBG10_1X10,
 	MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -655,62 +665,17 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
 
 	lockdep_assert_held(&imx219->mutex);
 
-	for (i = 0; i < ARRAY_SIZE(codes); i++)
-		if (codes[i] == code)
+	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); i++)
+		if (imx219_mbus_formats[i] == code)
 			break;
 
-	if (i >= ARRAY_SIZE(codes))
+	if (i >= ARRAY_SIZE(imx219_mbus_formats))
 		i = 0;
 
 	i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
 	    (imx219->hflip->val ? 1 : 0);
 
-	return codes[i];
-}
-
-static void imx219_set_default_format(struct imx219 *imx219)
-{
-	struct v4l2_mbus_framefmt *fmt;
-
-	fmt = &imx219->fmt;
-	fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
-	fmt->colorspace = V4L2_COLORSPACE_SRGB;
-	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
-	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-							  fmt->colorspace,
-							  fmt->ycbcr_enc);
-	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
-	fmt->width = supported_modes[0].width;
-	fmt->height = supported_modes[0].height;
-	fmt->field = V4L2_FIELD_NONE;
-}
-
-static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	struct imx219 *imx219 = to_imx219(sd);
-	struct v4l2_mbus_framefmt *try_fmt =
-		v4l2_subdev_get_try_format(sd, fh->state, 0);
-	struct v4l2_rect *try_crop;
-
-	mutex_lock(&imx219->mutex);
-
-	/* Initialize try_fmt */
-	try_fmt->width = supported_modes[0].width;
-	try_fmt->height = supported_modes[0].height;
-	try_fmt->code = imx219_get_format_code(imx219,
-					       MEDIA_BUS_FMT_SRGGB10_1X10);
-	try_fmt->field = V4L2_FIELD_NONE;
-
-	/* Initialize try_crop rectangle. */
-	try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
-	try_crop->top = IMX219_PIXEL_ARRAY_TOP;
-	try_crop->left = IMX219_PIXEL_ARRAY_LEFT;
-	try_crop->width = IMX219_PIXEL_ARRAY_WIDTH;
-	try_crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
-
-	mutex_unlock(&imx219->mutex);
-
-	return 0;
+	return imx219_mbus_formats[i];
 }
 
 static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -802,98 +767,148 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
 	.s_ctrl = imx219_set_ctrl,
 };
 
-static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
-				 struct v4l2_subdev_state *sd_state,
-				 struct v4l2_subdev_mbus_code_enum *code)
+static void imx219_init_formats(struct v4l2_subdev_state *state)
 {
-	struct imx219 *imx219 = to_imx219(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_state_get_stream_format(state, 0, 0);
+	format->code = imx219_mbus_formats[0];
+	format->width = supported_modes[0].width;
+	format->height = supported_modes[0].height;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_RAW;
+
+	if (state->routing.routes[1].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
+		format = v4l2_state_get_stream_format(state, 0, 1);
+		format->code = MEDIA_BUS_FMT_METADATA_8;
+		format->width = IMX219_EMBEDDED_LINE_WIDTH;
+		format->height = 1;
+		format->field = V4L2_FIELD_NONE;
+		format->colorspace = V4L2_COLORSPACE_DEFAULT;
+	}
+}
 
-	if (code->index >= (ARRAY_SIZE(codes) / 4))
-		return -EINVAL;
+static int _imx219_set_routing(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_IMMUTABLE |
+				 V4L2_SUBDEV_ROUTE_FL_SOURCE |
+				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+			.flags = V4L2_SUBDEV_ROUTE_FL_SOURCE |
+				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		}
+	};
 
-	mutex_lock(&imx219->mutex);
-	code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
-	mutex_unlock(&imx219->mutex);
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret)
+		return ret;
+
+	imx219_init_formats(state);
 
 	return 0;
 }
 
-static int imx219_enum_frame_size(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_state *sd_state,
-				  struct v4l2_subdev_frame_size_enum *fse)
+static int imx219_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
 {
-	struct imx219 *imx219 = to_imx219(sd);
-	u32 code;
+	int ret;
 
-	if (fse->index >= ARRAY_SIZE(supported_modes))
+	if (routing->num_routes == 0 || routing->num_routes > 2)
 		return -EINVAL;
 
-	mutex_lock(&imx219->mutex);
-	code = imx219_get_format_code(imx219, fse->code);
-	mutex_unlock(&imx219->mutex);
-	if (fse->code != code)
-		return -EINVAL;
+	v4l2_subdev_lock_state(state);
 
-	fse->min_width = supported_modes[fse->index].width;
-	fse->max_width = fse->min_width;
-	fse->min_height = supported_modes[fse->index].height;
-	fse->max_height = fse->min_height;
+	ret = _imx219_set_routing(sd, state);
 
-	return 0;
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
 }
 
-static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
+static int imx219_init_cfg(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *state)
 {
-	fmt->colorspace = V4L2_COLORSPACE_SRGB;
-	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
-	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-							  fmt->colorspace,
-							  fmt->ycbcr_enc);
-	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
+	int ret;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = _imx219_set_routing(sd, state);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
 }
 
-static void imx219_update_pad_format(struct imx219 *imx219,
-				     const struct imx219_mode *mode,
-				     struct v4l2_subdev_format *fmt)
+static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
 {
-	fmt->format.width = mode->width;
-	fmt->format.height = mode->height;
-	fmt->format.field = V4L2_FIELD_NONE;
-	imx219_reset_colorspace(&fmt->format);
+	if (code->index >= ARRAY_SIZE(imx219_mbus_formats))
+		return -EINVAL;
+
+	code->code = imx219_mbus_formats[code->index];
+
+	return 0;
 }
 
-static int __imx219_get_pad_format(struct imx219 *imx219,
-				   struct v4l2_subdev_state *sd_state,
-				   struct v4l2_subdev_format *fmt)
+static int imx219_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
 {
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		struct v4l2_mbus_framefmt *try_fmt =
-			v4l2_subdev_get_try_format(&imx219->sd, sd_state,
-						   fmt->pad);
-		/* update the code which could change due to vflip or hflip: */
-		try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
-		fmt->format = *try_fmt;
+	unsigned int i;
+
+	if (fse->stream == 0) {
+		for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
+			if (imx219_mbus_formats[i] == fse->code)
+				break;
+		}
+
+		if (i == ARRAY_SIZE(imx219_mbus_formats))
+			return -EINVAL;
+
+		if (fse->index >= ARRAY_SIZE(supported_modes))
+			return -EINVAL;
+
+		fse->min_width  = supported_modes[fse->index].width;
+		fse->max_width  = fse->min_width;
+		fse->max_height = supported_modes[fse->index].height;
+		fse->min_height = fse->max_height;
 	} else {
-		imx219_update_pad_format(imx219, imx219->mode, fmt);
-		fmt->format.code = imx219_get_format_code(imx219,
-							  imx219->fmt.code);
+		if (fse->code != MEDIA_BUS_FMT_METADATA_8)
+			return -EINVAL;
+
+		fse->min_width = IMX219_EMBEDDED_LINE_WIDTH;
+		fse->max_width = fse->min_width;
+		fse->min_height = IMX219_NUM_EMBEDDED_LINES;
+		fse->max_height = fse->min_height;
 	}
 
 	return 0;
 }
 
-static int imx219_get_pad_format(struct v4l2_subdev *sd,
-				 struct v4l2_subdev_state *sd_state,
-				 struct v4l2_subdev_format *fmt)
+static void imx219_update_metadata_pad_format(struct v4l2_subdev_format *fmt)
 {
-	struct imx219 *imx219 = to_imx219(sd);
-	int ret;
-
-	mutex_lock(&imx219->mutex);
-	ret = __imx219_get_pad_format(imx219, sd_state, fmt);
-	mutex_unlock(&imx219->mutex);
-
-	return ret;
+	fmt->format.width = IMX219_EMBEDDED_LINE_WIDTH;
+	fmt->format.height = IMX219_NUM_EMBEDDED_LINES;
+	fmt->format.code = MEDIA_BUS_FMT_METADATA_8;
+	fmt->format.field = V4L2_FIELD_NONE;
 }
 
 static int imx219_set_pad_format(struct v4l2_subdev *sd,
@@ -901,82 +916,99 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_format *fmt)
 {
 	struct imx219 *imx219 = to_imx219(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
 	const struct imx219_mode *mode;
-	struct v4l2_mbus_framefmt *framefmt;
-	int exposure_max, exposure_def, hblank;
+	struct v4l2_mbus_framefmt *format;
+	u32 code;
 	unsigned int i;
+	int ret = 0;
+	int exposure_max, exposure_def, hblank;
 
-	mutex_lock(&imx219->mutex);
+	if (fmt->pad != 0) {
+		dev_err(&client->dev, "%s Could not get pad %d\n", __func__,
+			fmt->pad);
+		return -EINVAL;
+	}
+
+	if (fmt->stream == 1) {
+		/* Only one embedded data mode is supported */
+		imx219_update_metadata_pad_format(fmt);
+		return 0;
+	}
+
+	if (fmt->stream != 0)
+		return -EINVAL;
 
-	for (i = 0; i < ARRAY_SIZE(codes); i++)
-		if (codes[i] == fmt->format.code)
+	/*
+	 * Validate the media bus code, defaulting to the first one if the
+	 * requested code isn't supported.
+	 */
+	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
+		if (imx219_mbus_formats[i] == fmt->format.code) {
+			code = fmt->format.code;
 			break;
-	if (i >= ARRAY_SIZE(codes))
-		i = 0;
+		}
+	}
+
+	if (i == ARRAY_SIZE(imx219_mbus_formats))
+		code = imx219_mbus_formats[0];
 
 	/* Bayer order varies with flips */
-	fmt->format.code = imx219_get_format_code(imx219, codes[i]);
+	fmt->format.code = imx219_get_format_code(imx219, imx219_mbus_formats[i]);
 
 	mode = v4l2_find_nearest_size(supported_modes,
 				      ARRAY_SIZE(supported_modes),
 				      width, height,
-				      fmt->format.width, fmt->format.height);
-	imx219_update_pad_format(imx219, mode, fmt);
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
-		*framefmt = fmt->format;
-	} else if (imx219->mode != mode ||
-		   imx219->fmt.code != fmt->format.code) {
-		imx219->fmt = fmt->format;
-		imx219->mode = mode;
-		/* Update limits and set FPS to default */
-		__v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
-					 IMX219_VTS_MAX - mode->height, 1,
-					 mode->vts_def - mode->height);
-		__v4l2_ctrl_s_ctrl(imx219->vblank,
-				   mode->vts_def - mode->height);
-		/* Update max exposure while meeting expected vblanking */
-		exposure_max = mode->vts_def - 4;
-		exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
-			exposure_max : IMX219_EXPOSURE_DEFAULT;
-		__v4l2_ctrl_modify_range(imx219->exposure,
-					 imx219->exposure->minimum,
-					 exposure_max, imx219->exposure->step,
-					 exposure_def);
-		/*
-		 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
-		 * depends on mode->width only, and is not changeble in any
-		 * way other than changing the mode.
-		 */
-		hblank = IMX219_PPL_DEFAULT - mode->width;
-		__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
-					 hblank);
-	}
+				      fmt->format.width,
+				      fmt->format.height);
 
-	mutex_unlock(&imx219->mutex);
+	v4l2_subdev_lock_state(sd_state);
 
-	return 0;
-}
+	/* Update the stored format and return it. */
+	format = v4l2_state_get_stream_format(sd_state, fmt->pad, fmt->stream);
 
-static int imx219_set_framefmt(struct imx219 *imx219)
-{
-	switch (imx219->fmt.code) {
-	case MEDIA_BUS_FMT_SRGGB8_1X8:
-	case MEDIA_BUS_FMT_SGRBG8_1X8:
-	case MEDIA_BUS_FMT_SGBRG8_1X8:
-	case MEDIA_BUS_FMT_SBGGR8_1X8:
-		return imx219_write_regs(imx219, raw8_framefmt_regs,
-					ARRAY_SIZE(raw8_framefmt_regs));
-
-	case MEDIA_BUS_FMT_SRGGB10_1X10:
-	case MEDIA_BUS_FMT_SGRBG10_1X10:
-	case MEDIA_BUS_FMT_SGBRG10_1X10:
-	case MEDIA_BUS_FMT_SBGGR10_1X10:
-		return imx219_write_regs(imx219, raw10_framefmt_regs,
-					ARRAY_SIZE(raw10_framefmt_regs));
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && imx219->streaming) {
+		ret = -EBUSY;
+		goto done;
 	}
 
-	return -EINVAL;
+	format->code = code;
+	format->width = mode->width;
+	format->height = mode->height;
+
+	fmt->format = *format;
+
+	/* Update limits and set FPS to default */
+	__v4l2_ctrl_modify_range(imx219->vblank,
+				 IMX219_VBLANK_MIN,
+				 IMX219_VTS_MAX - mode->height,
+				 1,
+				 mode->vts_def - mode->height);
+	__v4l2_ctrl_s_ctrl(imx219->vblank, mode->vts_def - mode->height);
+	/*
+	 * Update max exposure while meeting
+	 * expected vblanking
+	 */
+	exposure_max = mode->vts_def - 4;
+	exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
+			exposure_max : IMX219_EXPOSURE_DEFAULT;
+	__v4l2_ctrl_modify_range(imx219->exposure,
+				 imx219->exposure->minimum,
+				 exposure_max,
+				 imx219->exposure->step,
+				 exposure_def);
+	/*
+	 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so
+	 * hblank depends on mode->width only, and is not
+	 * changeble in any way other than changing the mode.
+	 */
+	hblank = IMX219_PPL_DEFAULT - mode->width;
+	__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, hblank);
+
+done:
+	v4l2_subdev_unlock_state(sd_state);
+
+	return ret;
 }
 
 static const struct v4l2_rect *
@@ -1037,9 +1069,11 @@ static int imx219_start_streaming(struct imx219 *imx219)
 	const struct imx219_reg_list *reg_list;
 	int ret;
 
-	ret = pm_runtime_resume_and_get(&client->dev);
-	if (ret < 0)
+	ret = pm_runtime_get_sync(&client->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&client->dev);
 		return ret;
+	}
 
 	/* Apply default values of current mode */
 	reg_list = &imx219->mode->reg_list;
@@ -1049,13 +1083,6 @@ static int imx219_start_streaming(struct imx219 *imx219)
 		goto err_rpm_put;
 	}
 
-	ret = imx219_set_framefmt(imx219);
-	if (ret) {
-		dev_err(&client->dev, "%s failed to set frame format: %d\n",
-			__func__, ret);
-		goto err_rpm_put;
-	}
-
 	/* Apply customized values from user */
 	ret =  __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
 	if (ret)
@@ -1133,21 +1160,22 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
 /* Power/clock management functions */
 static int imx219_power_on(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 	int ret;
 
 	ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
 				    imx219->supplies);
 	if (ret) {
-		dev_err(dev, "%s: failed to enable regulators\n",
+		dev_err(&client->dev, "%s: failed to enable regulators\n",
 			__func__);
 		return ret;
 	}
 
 	ret = clk_prepare_enable(imx219->xclk);
 	if (ret) {
-		dev_err(dev, "%s: failed to enable clock\n",
+		dev_err(&client->dev, "%s: failed to enable clock\n",
 			__func__);
 		goto reg_off;
 	}
@@ -1166,7 +1194,8 @@ static int imx219_power_on(struct device *dev)
 
 static int imx219_power_off(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 
 	gpiod_set_value_cansleep(imx219->reset_gpio, 0);
@@ -1178,7 +1207,8 @@ static int imx219_power_off(struct device *dev)
 
 static int __maybe_unused imx219_suspend(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 
 	if (imx219->streaming)
@@ -1189,7 +1219,8 @@ static int __maybe_unused imx219_suspend(struct device *dev)
 
 static int __maybe_unused imx219_resume(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 	int ret;
 
@@ -1255,11 +1286,13 @@ static const struct v4l2_subdev_video_ops imx219_video_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
-	.enum_mbus_code = imx219_enum_mbus_code,
-	.get_fmt = imx219_get_pad_format,
-	.set_fmt = imx219_set_pad_format,
-	.get_selection = imx219_get_selection,
-	.enum_frame_size = imx219_enum_frame_size,
+	.init_cfg		= imx219_init_cfg,
+	.enum_mbus_code		= imx219_enum_mbus_code,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= imx219_set_pad_format,
+	.get_selection		= imx219_get_selection,
+	.set_routing		= imx219_set_routing,
+	.enum_frame_size	= imx219_enum_frame_size,
 };
 
 static const struct v4l2_subdev_ops imx219_subdev_ops = {
@@ -1268,10 +1301,6 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = {
 	.pad = &imx219_pad_ops,
 };
 
-static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
-	.open = imx219_open,
-};
-
 /* Initialize control handlers */
 static int imx219_init_controls(struct imx219 *imx219)
 {
@@ -1446,6 +1475,7 @@ static int imx219_check_hwcfg(struct device *dev)
 static int imx219_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
+	struct v4l2_subdev *sd;
 	struct imx219 *imx219;
 	int ret;
 
@@ -1453,7 +1483,8 @@ static int imx219_probe(struct i2c_client *client)
 	if (!imx219)
 		return -ENOMEM;
 
-	v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
+	sd = &imx219->sd;
+	v4l2_i2c_subdev_init(sd, client, &imx219_subdev_ops);
 
 	/* Check the hardware configuration in device tree */
 	if (imx219_check_hwcfg(dev))
@@ -1520,27 +1551,29 @@ static int imx219_probe(struct i2c_client *client)
 		goto error_power_off;
 
 	/* Initialize subdev */
-	imx219->sd.internal_ops = &imx219_internal_ops;
-	imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
-			    V4L2_SUBDEV_FL_HAS_EVENTS;
-	imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS |
+		     V4L2_SUBDEV_FL_MULTIPLEXED;
 
-	/* Initialize source pad */
+	/* Initialize the media entity. */
 	imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
-
-	/* Initialize default format */
-	imx219_set_default_format(imx219);
-
-	ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &imx219->pad);
 	if (ret) {
 		dev_err(dev, "failed to init entity pads: %d\n", ret);
 		goto error_handler_free;
 	}
 
-	ret = v4l2_async_register_subdev_sensor(&imx219->sd);
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret) {
+		dev_err(dev, "failed to finalize sensor init: %d\n", ret);
+		goto error_media_entity;
+	}
+
+	ret = v4l2_async_register_subdev_sensor(sd);
 	if (ret < 0) {
 		dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
-		goto error_media_entity;
+		goto error_free_state;
 	}
 
 	/* Enable runtime PM and turn off the device */
@@ -1550,6 +1583,8 @@ static int imx219_probe(struct i2c_client *client)
 
 	return 0;
 
+error_free_state:
+	v4l2_subdev_cleanup(sd);
 error_media_entity:
 	media_entity_cleanup(&imx219->sd.entity);
 
@@ -1568,6 +1603,9 @@ static int imx219_remove(struct i2c_client *client)
 	struct imx219 *imx219 = to_imx219(sd);
 
 	v4l2_async_unregister_subdev(sd);
+
+	v4l2_subdev_cleanup(sd);
+
 	media_entity_cleanup(&sd->entity);
 	imx219_free_controls(imx219);
 
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Wed Jan 12 09:27:19 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Wed, 12 Jan 2022 18:27:19 +0100
Subject: [RFC PATCH 2/3] media: bcm2835-unicam: Add support for for CCP2/CSI2
 camera interface
In-Reply-To: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220112172719.1178446-3-jeanmichel.hautbois@ideasonboard.com>

Add driver for the Unicam camera receiver block on BCM283x processors.
It is represented as two video device nodes: unicam-image and
unicam-embedded which are connected to an internal subdev (named
unicam-subdev) in order to manage streams routing.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
 MAINTAINERS                                   |    1 +
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/bcm2835/Kconfig        |   21 +
 drivers/media/platform/bcm2835/Makefile       |    3 +
 .../media/platform/bcm2835/bcm2835-unicam.c   | 2694 +++++++++++++++++
 .../media/platform/bcm2835/vc4-regs-unicam.h  |  253 ++
 7 files changed, 2975 insertions(+)
 create mode 100644 drivers/media/platform/bcm2835/Kconfig
 create mode 100644 drivers/media/platform/bcm2835/Makefile
 create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
 create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 7484255cad31..dd7f8321fe27 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3658,6 +3658,7 @@ M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+F:	drivers/media/platform/bcm2835/
 
 BROADCOM BCM47XX MIPS ARCHITECTURE
 M:	Hauke Mehrtens <hauke at hauke-m.de>
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 9fbdba0fd1e7..033b0358fbb8 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -170,6 +170,7 @@ source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 source "drivers/media/platform/rcar-vin/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
+source "drivers/media/platform/bcm2835/Kconfig"
 source "drivers/media/platform/sunxi/Kconfig"
 
 config VIDEO_TI_CAL
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 19bcbced7382..689e64857db1 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -85,6 +85,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)		+= qcom/camss/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 
+obj-y					+= bcm2835/
+
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig
new file mode 100644
index 000000000000..bd1370199650
--- /dev/null
+++ b/drivers/media/platform/bcm2835/Kconfig
@@ -0,0 +1,21 @@
+# Broadcom VideoCore4 V4L2 camera support
+
+config VIDEO_BCM2835_UNICAM
+	tristate "Broadcom BCM283x/BCM271x Unicam video capture driver"
+	depends on VIDEO_V4L2
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	select VIDEO_V4L2_SUBDEV_API
+	select MEDIA_CONTROLLER
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver.
+	  This is a V4L2 driver that controls the CSI-2 receiver directly,
+	  independently from the VC4 firmware.
+	  This driver is mutually exclusive with the use of bcm2835-camera. The
+	  firmware will disable all access to the peripheral from within the
+	  firmware if it finds a DT node using it, and bcm2835-camera will
+	  therefore fail to probe.
+
+	  To compile this driver as a module, choose M here. The module will be
+	  called bcm2835-unicam.
diff --git a/drivers/media/platform/bcm2835/Makefile b/drivers/media/platform/bcm2835/Makefile
new file mode 100644
index 000000000000..a98aba03598a
--- /dev/null
+++ b/drivers/media/platform/bcm2835/Makefile
@@ -0,0 +1,3 @@
+# Makefile for BCM2835 Unicam driver
+
+obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o
diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
new file mode 100644
index 000000000000..2970d318f3f9
--- /dev/null
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -0,0 +1,2694 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * BCM283x / BCM271x Unicam Capture Driver
+ *
+ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
+ *
+ * Dave Stevenson <dave.stevenson at raspberrypi.com>
+ *
+ * Based on TI am437x driver by
+ *   Benoit Parrot <bparrot at ti.com>
+ *   Lad, Prabhakar <prabhakar.csengg at gmail.com>
+ *
+ * and TI CAL camera interface driver by
+ *    Benoit Parrot <bparrot at ti.com>
+ *
+ *
+ * There are two camera drivers in the kernel for BCM283x - this one
+ * and bcm2835-camera (currently in staging).
+ *
+ * This driver directly controls the Unicam peripheral - there is no
+ * involvement with the VideoCore firmware. Unicam receives CSI-2 or
+ * CCP2 data and writes it into SDRAM.
+ * The only potential processing options are to repack Bayer data into an
+ * alternate format, and applying windowing.
+ * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P
+ * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12,
+ * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both
+ * formats where the relevant formats are defined, and will automatically
+ * configure the repacking as required.
+ * Support for windowing may be added later.
+ *
+ * It should be possible to connect this driver to any sensor with a
+ * suitable output interface and V4L2 subdevice driver.
+ *
+ * bcm2835-camera uses the VideoCore firmware to control the sensor,
+ * Unicam, ISP, and all tuner control loops. Fully processed frames are
+ * delivered to the driver by the firmware. It only has sensor drivers
+ * for Omnivision OV5647, and Sony IMX219 sensors.
+ *
+ * The two drivers are mutually exclusive for the same Unicam instance.
+ * The VideoCore firmware checks the device tree configuration during boot.
+ * If it finds device tree nodes called csi0 or csi1 it will block the
+ * firmware from accessing the peripheral, and bcm2835-camera will
+ * not be able to stream data.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fwnode.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include <media/v4l2-async.h>
+#define v4l2_async_nf_add_subdev __v4l2_async_nf_add_subdev
+
+#include "vc4-regs-unicam.h"
+
+#define UNICAM_MODULE_NAME	"unicam"
+#define UNICAM_VERSION		"0.1.0"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-3");
+
+#define unicam_dbg(level, dev, fmt, arg...)	\
+		v4l2_dbg(level, debug, &(dev)->v4l2_dev, fmt, ##arg)
+#define unicam_info(dev, fmt, arg...)	\
+		v4l2_info(&(dev)->v4l2_dev, fmt, ##arg)
+#define unicam_err(dev, fmt, arg...)	\
+		v4l2_err(&(dev)->v4l2_dev, fmt, ##arg)
+
+/*
+ * Unicam must request a minimum of 250Mhz from the VPU clock.
+ * Otherwise the input FIFOs overrun and cause image corruption.
+ */
+#define MIN_VPU_CLOCK_RATE (250 * 1000 * 1000)
+/*
+ * To protect against a dodgy sensor driver never returning an error from
+ * enum_mbus_code, set a maximum index value to be used.
+ */
+#define MAX_ENUM_MBUS_CODE	128
+
+/*
+ * Stride is a 16 bit register, but also has to be a multiple of 32.
+ */
+#define BPL_ALIGNMENT		32
+#define MAX_BYTESPERLINE	((1 << 16) - BPL_ALIGNMENT)
+/*
+ * Max width is therefore determined by the max stride divided by
+ * the number of bits per pixel. Take 32bpp as a
+ * worst case.
+ * No imposed limit on the height, so adopt a square image for want
+ * of anything better.
+ */
+#define MAX_WIDTH		(MAX_BYTESPERLINE / 4)
+#define MAX_HEIGHT		MAX_WIDTH
+/* Define a nominal minimum image size */
+#define MIN_WIDTH		16
+#define MIN_HEIGHT		16
+/* Default size of the embedded buffer */
+#define UNICAM_EMBEDDED_SIZE	16384
+
+/*
+ * Size of the dummy buffer. Can be any size really, but the DMA
+ * allocation works in units of page sizes.
+ */
+#define DUMMY_BUF_SIZE		(PAGE_SIZE)
+
+#define UNICAM_SD_PAD_SINK		0
+#define UNICAM_SD_PAD_FIRST_SOURCE	1
+#define UNICAM_SD_NUM_SOURCE_PADS	2
+#define UNICAM_SD_NUM_PADS		(1 + UNICAM_SD_NUM_SOURCE_PADS)
+
+static inline bool unicam_sd_pad_is_sink(u32 pad)
+{
+	/* Camera RX has 1 sink pad, and N source pads */
+	return pad == 0;
+}
+
+static inline bool unicam_sd_pad_is_source(u32 pad)
+{
+	/* Camera RX has 1 sink pad, and N source pads */
+	return pad >= UNICAM_SD_PAD_FIRST_SOURCE &&
+	       pad <= UNICAM_SD_NUM_SOURCE_PADS;
+}
+
+enum node_types {
+	IMAGE_NODE,
+	METADATA_NODE,
+	MAX_NODES
+};
+
+#define MASK_CS_DEFAULT		BIT(V4L2_COLORSPACE_DEFAULT)
+#define MASK_CS_SMPTE170M	BIT(V4L2_COLORSPACE_SMPTE170M)
+#define MASK_CS_SMPTE240M	BIT(V4L2_COLORSPACE_SMPTE240M)
+#define MASK_CS_REC709		BIT(V4L2_COLORSPACE_REC709)
+#define MASK_CS_BT878		BIT(V4L2_COLORSPACE_BT878)
+#define MASK_CS_470_M		BIT(V4L2_COLORSPACE_470_SYSTEM_M)
+#define MASK_CS_470_BG		BIT(V4L2_COLORSPACE_470_SYSTEM_BG)
+#define MASK_CS_JPEG		BIT(V4L2_COLORSPACE_JPEG)
+#define MASK_CS_SRGB		BIT(V4L2_COLORSPACE_SRGB)
+#define MASK_CS_OPRGB		BIT(V4L2_COLORSPACE_OPRGB)
+#define MASK_CS_BT2020		BIT(V4L2_COLORSPACE_BT2020)
+#define MASK_CS_RAW		BIT(V4L2_COLORSPACE_RAW)
+#define MASK_CS_DCI_P3		BIT(V4L2_COLORSPACE_DCI_P3)
+
+#define MAX_COLORSPACE		32
+
+/*
+ * struct unicam_fmt - Unicam media bus format information
+ * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a.
+ * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded
+ * out to 16bpp. 0 if n/a.
+ * @code: V4L2 media bus format code.
+ * @depth: Bits per pixel as delivered from the source.
+ * @csi_dt: CSI data type.
+ * @valid_colorspaces: Bitmask of valid colorspaces so that the Media Controller
+ *		centric try_fmt can validate the colorspace and pass
+ *		v4l2-compliance.
+ * @check_variants: Flag to denote that there are multiple mediabus formats
+ *		still in the list that could match this V4L2 format.
+ * @mc_skip: Media Controller shouldn't list this format via ENUM_FMT as it is
+ *		a duplicate of an earlier format.
+ * @metadata_fmt: This format only applies to the metadata pad.
+ */
+struct unicam_fmt {
+	u32	fourcc;
+	u32	repacked_fourcc;
+	u32	code;
+	u8	depth;
+	u8	csi_dt;
+	u32	valid_colorspaces;
+	u8	check_variants:1;
+	u8	mc_skip:1;
+	u8	metadata_fmt:1;
+};
+
+static const struct unicam_fmt formats[] = {
+	/* YUV Formats */
+	{
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.code		= MEDIA_BUS_FMT_YUYV8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.code		= MEDIA_BUS_FMT_YVYU8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.code		= MEDIA_BUS_FMT_YUYV8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.code		= MEDIA_BUS_FMT_UYVY8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.code		= MEDIA_BUS_FMT_YVYU8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.code		= MEDIA_BUS_FMT_VYUY8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+	/* RGB Formats */
+		.fourcc		= V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+		.code		= MEDIA_BUS_FMT_RGB565_2X8_LE,
+		.depth		= 16,
+		.csi_dt		= 0x22,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+		.code		= MEDIA_BUS_FMT_RGB565_2X8_BE,
+		.depth		= 16,
+		.csi_dt		= 0x22,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+		.code		= MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+		.depth		= 16,
+		.csi_dt		= 0x21,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+		.code		= MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+		.depth		= 16,
+		.csi_dt		= 0x21,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB24, /* rgb */
+		.code		= MEDIA_BUS_FMT_RGB888_1X24,
+		.depth		= 24,
+		.csi_dt		= 0x24,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_BGR24, /* bgr */
+		.code		= MEDIA_BUS_FMT_BGR888_1X24,
+		.depth		= 24,
+		.csi_dt		= 0x24,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB32, /* argb */
+		.code		= MEDIA_BUS_FMT_ARGB8888_1X32,
+		.depth		= 32,
+		.csi_dt		= 0x0,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+	/* Bayer Formats */
+		.fourcc		= V4L2_PIX_FMT_SBGGR8,
+		.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG8,
+		.code		= MEDIA_BUS_FMT_SGBRG8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG8,
+		.code		= MEDIA_BUS_FMT_SGRBG8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB8,
+		.code		= MEDIA_BUS_FMT_SRGGB8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR10,
+		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG10,
+		.code		= MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG10,
+		.code		= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB10,
+		.code		= MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR12,
+		.code		= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG12,
+		.code		= MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG12,
+		.code		= MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB12,
+		.code		= MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR14,
+		.code		= MEDIA_BUS_FMT_SBGGR14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG14,
+		.code		= MEDIA_BUS_FMT_SGBRG14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG14,
+		.code		= MEDIA_BUS_FMT_SGRBG14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB14,
+		.code		= MEDIA_BUS_FMT_SRGGB14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+	/*
+	 * 16 bit Bayer formats could be supported, but there is no CSI2
+	 * data_type defined for raw 16, and no sensors that produce it at
+	 * present.
+	 */
+
+	/* Greyscale formats */
+		.fourcc		= V4L2_PIX_FMT_GREY,
+		.code		= MEDIA_BUS_FMT_Y8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y10P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y10,
+		.code		= MEDIA_BUS_FMT_Y10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y12P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y12,
+		.code		= MEDIA_BUS_FMT_Y12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y14P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y14,
+		.code		= MEDIA_BUS_FMT_Y14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	},
+	/* Embedded data format */
+	{
+		.fourcc		= V4L2_META_FMT_8,
+		.code		= MEDIA_BUS_FMT_METADATA_8,
+		.depth		= 8,
+		.metadata_fmt	= 1,
+	}
+};
+
+struct unicam_buffer {
+	struct vb2_v4l2_buffer vb;
+	struct list_head list;
+};
+
+static inline struct unicam_buffer *to_unicam_buffer(struct vb2_buffer *vb)
+{
+	return container_of(vb, struct unicam_buffer, vb.vb2_buf);
+}
+
+struct unicam_node {
+	bool registered;
+	int open;
+	bool streaming;
+	unsigned int node_id;
+	/* Source pad id on the sensor for this node */
+	unsigned int src_pad_id;
+	/* Pointer pointing to current v4l2_buffer */
+	struct unicam_buffer *cur_frm;
+	/* Pointer pointing to next v4l2_buffer */
+	struct unicam_buffer *next_frm;
+	/* video capture */
+	const struct unicam_fmt *fmt;
+	/* Used to store current pixel format */
+	struct v4l2_format v_fmt;
+	/* Used to store current mbus frame format */
+	struct v4l2_mbus_framefmt m_fmt;
+	/* Buffer queue used in video-buf */
+	struct vb2_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* IRQ lock for DMA queue */
+	spinlock_t dma_queue_lock;
+	/* lock used to access this structure */
+	struct mutex lock;
+	/* Identifies video device for this channel */
+	struct video_device video_dev;
+	/* Pointer to the parent handle */
+	struct unicam_device *dev;
+	struct media_pad pad;
+	unsigned int embedded_lines;
+	struct media_pipeline pipe;
+	/*
+	 * Dummy buffer intended to be used by unicam
+	 * if we have no other queued buffers to swap to.
+	 */
+	void *dummy_buf_cpu_addr;
+	dma_addr_t dummy_buf_dma_addr;
+};
+
+struct unicam_device {
+	struct kref kref;
+
+	/* V4l2 specific parameters */
+	struct v4l2_async_subdev asd;
+
+	/* peripheral base address */
+	void __iomem *base;
+	/* clock gating base address */
+	void __iomem *clk_gate_base;
+	/* lp clock handle */
+	struct clk *clock;
+	/* vpu clock handle */
+	struct clk *vpu_clock;
+	/* vpu clock request */
+	struct clk_request *vpu_req;
+	/* clock status for error handling */
+	bool clocks_enabled;
+	/* V4l2 device */
+	struct v4l2_device v4l2_dev;
+	struct media_device mdev;
+
+	/* parent device */
+	struct platform_device *pdev;
+	/* subdevice async Notifier */
+	struct v4l2_async_notifier notifier;
+	unsigned int sequence;
+
+	/* ptr to  sub device */
+	struct v4l2_subdev *sensor;
+	/* Pad config for the sensor */
+	struct v4l2_subdev_state *sensor_state;
+
+	/* Internal subdev */
+	struct v4l2_subdev sd;
+	struct media_pad pads[UNICAM_SD_NUM_PADS];
+
+	bool streaming;
+
+	enum v4l2_mbus_type bus_type;
+	/*
+	 * Stores bus.mipi_csi2.flags for CSI2 sensors, or
+	 * bus.mipi_csi1.strobe for CCP2.
+	 */
+	unsigned int bus_flags;
+	unsigned int max_data_lanes;
+	unsigned int active_data_lanes;
+	bool sensor_embedded_data;
+
+	struct unicam_node node[MAX_NODES];
+	struct v4l2_ctrl_handler ctrl_handler;
+
+	bool mc_api;
+};
+
+static inline struct unicam_device *
+to_unicam_device(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct unicam_device, v4l2_dev);
+}
+
+static inline struct unicam_device *
+sd_to_unicam_device(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct unicam_device, sd);
+}
+
+static inline bool is_metadata_node(struct unicam_node *node)
+{
+	return node->video_dev.device_caps & V4L2_CAP_META_CAPTURE;
+}
+
+static inline bool is_image_node(struct unicam_node *node)
+{
+	return node->video_dev.device_caps & V4L2_CAP_VIDEO_CAPTURE;
+}
+
+/* Hardware access */
+static inline void clk_write(struct unicam_device *dev, u32 val)
+{
+	writel(val | 0x5a000000, dev->clk_gate_base);
+}
+
+static inline u32 reg_read(struct unicam_device *dev, u32 offset)
+{
+	return readl(dev->base + offset);
+}
+
+static inline void reg_write(struct unicam_device *dev, u32 offset, u32 val)
+{
+	writel(val, dev->base + offset);
+}
+
+static inline int get_field(u32 value, u32 mask)
+{
+	return (value & mask) >> __ffs(mask);
+}
+
+static inline void set_field(u32 *valp, u32 field, u32 mask)
+{
+	u32 val = *valp;
+
+	val &= ~mask;
+	val |= (field << __ffs(mask)) & mask;
+	*valp = val;
+}
+
+static inline u32 reg_read_field(struct unicam_device *dev, u32 offset,
+				 u32 mask)
+{
+	return get_field(reg_read(dev, offset), mask);
+}
+
+static inline void reg_write_field(struct unicam_device *dev, u32 offset,
+				   u32 field, u32 mask)
+{
+	u32 val = reg_read(dev, offset);
+
+	set_field(&val, field, mask);
+	reg_write(dev, offset, val);
+}
+
+/* Power management functions */
+static inline int unicam_runtime_get(struct unicam_device *dev)
+{
+	return pm_runtime_get_sync(&dev->pdev->dev);
+}
+
+static inline void unicam_runtime_put(struct unicam_device *dev)
+{
+	pm_runtime_put_sync(&dev->pdev->dev);
+}
+
+/* Format setup functions */
+static const struct unicam_fmt *find_format_by_code(u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].code == code)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static const struct unicam_fmt *find_format_by_fourcc(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+		if (formats[i].fourcc == fourcc)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt,
+				   u32 v4l2_fourcc)
+{
+	if (v4l2_fourcc == fmt->repacked_fourcc)
+		/* Repacking always goes to 16bpp */
+		return ALIGN(width << 1, BPL_ALIGNMENT);
+	else
+		return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT);
+}
+
+static int unicam_calc_format_size_bpl(struct unicam_device *dev,
+				       const struct unicam_fmt *fmt,
+				       struct v4l2_format *f)
+{
+	unsigned int min_bytesperline;
+
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2,
+			      &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0,
+			      0);
+
+	min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt,
+					  f->fmt.pix.pixelformat);
+
+	if (f->fmt.pix.bytesperline > min_bytesperline &&
+	    f->fmt.pix.bytesperline <= MAX_BYTESPERLINE)
+		f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
+						BPL_ALIGNMENT);
+	else
+		f->fmt.pix.bytesperline = min_bytesperline;
+
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+	unicam_dbg(3, dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n",
+		   __func__,
+		   f->fmt.pix.pixelformat,
+		   f->fmt.pix.width, f->fmt.pix.height,
+		   f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	return 0;
+}
+
+static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr,
+			       unsigned int buffer_size, int node_id)
+{
+	dma_addr_t endaddr = dmaaddr + buffer_size;
+
+	if (node_id == IMAGE_NODE) {
+		reg_write(dev, UNICAM_IBSA0, dmaaddr);
+		reg_write(dev, UNICAM_IBEA0, endaddr);
+	} else {
+		reg_write(dev, UNICAM_DBSA0, dmaaddr);
+		reg_write(dev, UNICAM_DBEA0, endaddr);
+	}
+}
+
+static unsigned int unicam_get_lines_done(struct unicam_device *dev)
+{
+	dma_addr_t start_addr, cur_addr;
+	unsigned int stride = dev->node[IMAGE_NODE].v_fmt.fmt.pix.bytesperline;
+	struct unicam_buffer *frm = dev->node[IMAGE_NODE].cur_frm;
+
+	if (!frm)
+		return 0;
+
+	start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0);
+	cur_addr = reg_read(dev, UNICAM_IBWP);
+	return (unsigned int)(cur_addr - start_addr) / stride;
+}
+
+static void unicam_schedule_next_buffer(struct unicam_node *node)
+{
+	struct unicam_device *dev = node->dev;
+	struct unicam_buffer *buf;
+	unsigned int size;
+	dma_addr_t addr;
+
+	buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list);
+	node->next_frm = buf;
+	list_del(&buf->list);
+
+	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+	if (is_image_node(node)) {
+		size = node->v_fmt.fmt.pix.sizeimage;
+		unicam_wr_dma_addr(dev, addr, size, IMAGE_NODE);
+	} else {
+		size = node->v_fmt.fmt.meta.buffersize;
+		unicam_wr_dma_addr(dev, addr, size, METADATA_NODE);
+	}
+}
+
+static void unicam_schedule_dummy_buffer(struct unicam_node *node)
+{
+	struct unicam_device *dev = node->dev;
+	int node_id = is_image_node(node) ? IMAGE_NODE : METADATA_NODE;
+
+	unicam_dbg(3, dev, "Scheduling dummy buffer for node %d\n", node_id);
+
+	unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, DUMMY_BUF_SIZE,
+			   node_id);
+	node->next_frm = NULL;
+}
+
+static void unicam_process_buffer_complete(struct unicam_node *node,
+					   unsigned int sequence)
+{
+	node->cur_frm->vb.field = node->m_fmt.field;
+	node->cur_frm->vb.sequence = sequence;
+
+	vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+static void unicam_queue_event_sof(struct unicam_device *unicam)
+{
+	struct v4l2_event event = {
+		.type = V4L2_EVENT_FRAME_SYNC,
+		.u.frame_sync.frame_sequence = unicam->sequence,
+	};
+
+	v4l2_event_queue(&unicam->node[IMAGE_NODE].video_dev, &event);
+}
+
+/*
+ * unicam_isr : ISR handler for unicam capture
+ * @irq: irq number
+ * @dev_id: dev_id ptr
+ *
+ * It changes status of the captured buffer, takes next buffer from the queue
+ * and sets its address in unicam registers
+ */
+static irqreturn_t unicam_isr(int irq, void *dev)
+{
+	struct unicam_device *unicam = dev;
+	unsigned int lines_done = unicam_get_lines_done(dev);
+	unsigned int sequence = unicam->sequence;
+	unsigned int i;
+	u32 ista, sta;
+	bool fe;
+	u64 ts;
+
+	sta = reg_read(unicam, UNICAM_STA);
+	/* Write value back to clear the interrupts */
+	reg_write(unicam, UNICAM_STA, sta);
+
+	ista = reg_read(unicam, UNICAM_ISTA);
+	/* Write value back to clear the interrupts */
+	reg_write(unicam, UNICAM_ISTA, ista);
+
+	unicam_dbg(3, unicam, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d",
+		   ista, sta, sequence, lines_done);
+
+	if (!(sta & (UNICAM_IS | UNICAM_PI0)))
+		return IRQ_HANDLED;
+
+	/*
+	 * Look for either the Frame End interrupt or the Packet Capture status
+	 * to signal a frame end.
+	 */
+	fe = (ista & UNICAM_FEI || sta & UNICAM_PI0);
+
+	/*
+	 * We must run the frame end handler first. If we have a valid next_frm
+	 * and we get a simultaneout FE + FS interrupt, running the FS handler
+	 * first would null out the next_frm ptr and we would have lost the
+	 * buffer forever.
+	 */
+	if (fe) {
+		/*
+		 * Ensure we have swapped buffers already as we can't
+		 * stop the peripheral. If no buffer is available, use a
+		 * dummy buffer to dump out frames until we get a new buffer
+		 * to use.
+		 */
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			/*
+			 * If cur_frm == next_frm, it means we have not had
+			 * a chance to swap buffers, likely due to having
+			 * multiple interrupts occurring simultaneously (like FE
+			 * + FS + LS). In this case, we cannot signal the buffer
+			 * as complete, as the HW will reuse that buffer.
+			 */
+			if (unicam->node[i].cur_frm &&
+			    unicam->node[i].cur_frm != unicam->node[i].next_frm)
+				unicam_process_buffer_complete(&unicam->node[i],
+							       sequence);
+			unicam->node[i].cur_frm = unicam->node[i].next_frm;
+		}
+		unicam->sequence++;
+	}
+
+	if (ista & UNICAM_FSI) {
+		/*
+		 * Timestamp is to be when the first data byte was captured,
+		 * aka frame start.
+		 */
+		ts = ktime_get_ns();
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			if (unicam->node[i].cur_frm)
+				unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
+								ts;
+			else
+				unicam_dbg(2, unicam, "ISR: [%d] Dropping frame, buffer not available at FS\n",
+					   i);
+			/*
+			 * Set the next frame output to go to a dummy frame
+			 * if we have not managed to obtain another frame
+			 * from the queue.
+			 */
+			unicam_schedule_dummy_buffer(&unicam->node[i]);
+		}
+
+		unicam_queue_event_sof(unicam);
+	}
+
+	/*
+	 * Cannot swap buffer at frame end, there may be a race condition
+	 * where the HW does not actually swap it if the new frame has
+	 * already started.
+	 */
+	if (ista & (UNICAM_FSI | UNICAM_LCI) && !fe) {
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			spin_lock(&unicam->node[i].dma_queue_lock);
+			if (!list_empty(&unicam->node[i].dma_queue) &&
+			    !unicam->node[i].next_frm)
+				unicam_schedule_next_buffer(&unicam->node[i]);
+			spin_unlock(&unicam->node[i].dma_queue_lock);
+		}
+	}
+
+	if (reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) {
+		/* Switch out of trigger mode if selected */
+		reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
+		reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM);
+	}
+	return IRQ_HANDLED;
+}
+
+/* V4L2 Common IOCTLs */
+static int unicam_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+
+	strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
+	strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
+
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s", dev_name(&dev->pdev->dev));
+
+	cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE;
+
+	return 0;
+}
+
+static int unicam_log_status(struct file *file, void *fh)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+	u32 reg;
+
+	/* status for sub devices */
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status);
+
+	unicam_info(dev, "-----Receiver status-----\n");
+	unicam_info(dev, "V4L2 width/height:   %ux%u\n",
+		    node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height);
+	unicam_info(dev, "Mediabus format:     %08x\n", node->fmt->code);
+	unicam_info(dev, "V4L2 format:         %08x\n",
+		    node->v_fmt.fmt.pix.pixelformat);
+	reg = reg_read(dev, UNICAM_IPIPE);
+	unicam_info(dev, "Unpacking/packing:   %u / %u\n",
+		    get_field(reg, UNICAM_PUM_MASK),
+		    get_field(reg, UNICAM_PPM_MASK));
+	unicam_info(dev, "----Live data----\n");
+	unicam_info(dev, "Programmed stride:   %4u\n",
+		    reg_read(dev, UNICAM_IBLS));
+	unicam_info(dev, "Detected resolution: %ux%u\n",
+		    reg_read(dev, UNICAM_IHSTA),
+		    reg_read(dev, UNICAM_IVSTA));
+	unicam_info(dev, "Write pointer:       %08x\n",
+		    reg_read(dev, UNICAM_IBWP));
+
+	return 0;
+}
+
+static int unicam_subscribe_event(struct v4l2_fh *fh,
+				  const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_FRAME_SYNC:
+		return v4l2_event_subscribe(fh, sub, 2, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_event_subscribe(fh, sub, 4, NULL);
+	}
+
+	return v4l2_ctrl_subscribe_event(fh, sub);
+}
+
+static void unicam_notify(struct v4l2_subdev *sd,
+			  unsigned int notification, void *arg)
+{
+	struct unicam_device *dev = to_unicam_device(sd->v4l2_dev);
+
+	switch (notification) {
+	case V4L2_DEVICE_NOTIFY_EVENT:
+		v4l2_event_queue(&dev->node[IMAGE_NODE].video_dev, arg);
+		break;
+	default:
+		break;
+	}
+}
+
+/* V4L2 Media Controller Centric IOCTLs */
+
+static int unicam_mc_enum_fmt_vid_cap(struct file *file, void  *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	int i, j;
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(formats); i++) {
+		if (f->mbus_code && formats[i].code != f->mbus_code)
+			continue;
+		if (formats[i].mc_skip || formats[i].metadata_fmt)
+			continue;
+
+		if (formats[i].fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].fourcc;
+				f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+		if (formats[i].repacked_fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].repacked_fourcc;
+				f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int unicam_mc_g_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_image_node(node))
+		return -EINVAL;
+
+	*f = node->v_fmt;
+
+	return 0;
+}
+
+static void unicam_mc_try_fmt(struct unicam_node *node, struct v4l2_format *f,
+			      const struct unicam_fmt **ret_fmt)
+{
+	struct v4l2_pix_format *v4l2_format = &f->fmt.pix;
+	struct unicam_device *dev = node->dev;
+	const struct unicam_fmt *fmt;
+	int is_rgb;
+
+	/*
+	 * Default to the first format if the requested pixel format code isn't
+	 * supported.
+	 */
+	fmt = find_format_by_fourcc(v4l2_format->pixelformat);
+	if (!fmt) {
+		fmt = &formats[0];
+		v4l2_format->pixelformat = fmt->fourcc;
+	}
+
+	unicam_calc_format_size_bpl(dev, fmt, f);
+
+	if (v4l2_format->field == V4L2_FIELD_ANY)
+		v4l2_format->field = V4L2_FIELD_NONE;
+
+	if (v4l2_format->colorspace >= MAX_COLORSPACE ||
+	    !(fmt->valid_colorspaces & (1 << v4l2_format->colorspace))) {
+		v4l2_format->colorspace = __ffs(fmt->valid_colorspaces);
+
+		v4l2_format->xfer_func =
+			V4L2_MAP_XFER_FUNC_DEFAULT(v4l2_format->colorspace);
+		v4l2_format->ycbcr_enc =
+			V4L2_MAP_YCBCR_ENC_DEFAULT(v4l2_format->colorspace);
+		is_rgb = v4l2_format->colorspace == V4L2_COLORSPACE_SRGB;
+		v4l2_format->quantization =
+			V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb,
+						      v4l2_format->colorspace,
+						      v4l2_format->ycbcr_enc);
+	}
+
+	if (ret_fmt)
+		*ret_fmt = fmt;
+
+	unicam_dbg(3, dev, "%s: %08x %ux%u (bytesperline %u sizeimage %u)\n",
+		   __func__, v4l2_format->pixelformat,
+		   v4l2_format->width, v4l2_format->height,
+		   v4l2_format->bytesperline, v4l2_format->sizeimage);
+}
+
+static int unicam_mc_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	unicam_mc_try_fmt(node, f, NULL);
+	return 0;
+}
+
+static int unicam_mc_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+	const struct unicam_fmt *fmt;
+
+	if (vb2_is_busy(&node->buffer_queue)) {
+		unicam_dbg(3, dev, "%s device busy\n", __func__);
+		return -EBUSY;
+	}
+
+	unicam_mc_try_fmt(node, f, &fmt);
+
+	node->v_fmt = *f;
+	node->fmt = fmt;
+
+	return 0;
+}
+
+static int unicam_mc_enum_framesizes(struct file *file, void *fh,
+				     struct v4l2_frmsizeenum *fsize)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+
+	if (fsize->index > 0)
+		return -EINVAL;
+
+	if (!find_format_by_fourcc(fsize->pixel_format)) {
+		unicam_dbg(3, dev, "Invalid pixel format 0x%08x\n",
+			   fsize->pixel_format);
+		return -EINVAL;
+	}
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = MIN_WIDTH;
+	fsize->stepwise.max_width = MAX_WIDTH;
+	fsize->stepwise.step_width = 1;
+	fsize->stepwise.min_height = MIN_HEIGHT;
+	fsize->stepwise.max_height = MAX_HEIGHT;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
+static int unicam_mc_enum_fmt_meta_cap(struct file *file, void  *priv,
+				       struct v4l2_fmtdesc *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+	int i, j;
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(formats); i++) {
+		if (f->mbus_code && formats[i].code != f->mbus_code)
+			continue;
+		if (!formats[i].metadata_fmt)
+			continue;
+
+		if (formats[i].fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].fourcc;
+				f->type = V4L2_BUF_TYPE_META_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int unicam_mc_g_fmt_meta_cap(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	*f = node->v_fmt;
+
+	return 0;
+}
+
+static int unicam_mc_try_fmt_meta_cap(struct file *file, void *priv,
+				      struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	f->fmt.meta.dataformat = V4L2_META_FMT_8;
+
+	return 0;
+}
+
+static int unicam_mc_s_fmt_meta_cap(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	unicam_mc_try_fmt_meta_cap(file, priv, f);
+
+	node->v_fmt = *f;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops unicam_mc_ioctl_ops = {
+	.vidioc_querycap      = unicam_querycap,
+	.vidioc_enum_fmt_vid_cap  = unicam_mc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap     = unicam_mc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap   = unicam_mc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap     = unicam_mc_s_fmt_vid_cap,
+
+	.vidioc_enum_fmt_meta_cap	= unicam_mc_enum_fmt_meta_cap,
+	.vidioc_g_fmt_meta_cap		= unicam_mc_g_fmt_meta_cap,
+	.vidioc_try_fmt_meta_cap	= unicam_mc_try_fmt_meta_cap,
+	.vidioc_s_fmt_meta_cap		= unicam_mc_s_fmt_meta_cap,
+
+	.vidioc_enum_framesizes   = unicam_mc_enum_framesizes,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs   = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_expbuf        = vb2_ioctl_expbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
+
+	.vidioc_log_status		= unicam_log_status,
+	.vidioc_subscribe_event		= unicam_subscribe_event,
+	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
+};
+
+static const struct media_entity_operations unicam_mc_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+	.has_route = v4l2_subdev_has_route,
+};
+
+/* videobuf2 Operations */
+
+static int unicam_queue_setup(struct vb2_queue *vq,
+			      unsigned int *nbuffers,
+			      unsigned int *nplanes,
+			      unsigned int sizes[],
+			      struct device *alloc_devs[])
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+	unsigned int size = is_image_node(node) ?
+				node->v_fmt.fmt.pix.sizeimage :
+				node->v_fmt.fmt.meta.buffersize;
+
+	if (vq->num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - vq->num_buffers;
+
+	if (*nplanes) {
+		if (sizes[0] < size) {
+			unicam_err(dev, "sizes[0] %i < size %u\n", sizes[0],
+				   size);
+			return -EINVAL;
+		}
+		size = sizes[0];
+	}
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	return 0;
+}
+
+static int unicam_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+	struct unicam_device *dev = node->dev;
+	struct unicam_buffer *buf = to_unicam_buffer(vb);
+	unsigned long size;
+
+	if (WARN_ON(!node->fmt))
+		return -EINVAL;
+
+	size = is_image_node(node) ? node->v_fmt.fmt.pix.sizeimage :
+				     node->v_fmt.fmt.meta.buffersize;
+	if (vb2_plane_size(vb, 0) < size) {
+		unicam_err(dev, "data will not fit into plane (%lu < %lu)\n",
+			   vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+	return 0;
+}
+
+static void unicam_buffer_queue(struct vb2_buffer *vb)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+	struct unicam_buffer *buf = to_unicam_buffer(vb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	list_add_tail(&buf->list, &node->dma_queue);
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+}
+
+static void unicam_set_packing_config(struct unicam_device *dev)
+{
+	u32 pack, unpack;
+	u32 val;
+
+	if (dev->node[IMAGE_NODE].v_fmt.fmt.pix.pixelformat ==
+	    dev->node[IMAGE_NODE].fmt->fourcc) {
+		unpack = UNICAM_PUM_NONE;
+		pack = UNICAM_PPM_NONE;
+	} else {
+		switch (dev->node[IMAGE_NODE].fmt->depth) {
+		case 8:
+			unpack = UNICAM_PUM_UNPACK8;
+			break;
+		case 10:
+			unpack = UNICAM_PUM_UNPACK10;
+			break;
+		case 12:
+			unpack = UNICAM_PUM_UNPACK12;
+			break;
+		case 14:
+			unpack = UNICAM_PUM_UNPACK14;
+			break;
+		case 16:
+			unpack = UNICAM_PUM_UNPACK16;
+			break;
+		default:
+			unpack = UNICAM_PUM_NONE;
+			break;
+		}
+
+		/* Repacking is always to 16bpp */
+		pack = UNICAM_PPM_PACK16;
+	}
+
+	val = 0;
+	set_field(&val, unpack, UNICAM_PUM_MASK);
+	set_field(&val, pack, UNICAM_PPM_MASK);
+	reg_write(dev, UNICAM_IPIPE, val);
+}
+
+static void unicam_cfg_image_id(struct unicam_device *dev)
+{
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 mode, hardcode VC 0 for now. */
+		reg_write(dev, UNICAM_IDI0,
+			  (0 << 6) | dev->node[IMAGE_NODE].fmt->csi_dt);
+	} else {
+		/* CCP2 mode */
+		reg_write(dev, UNICAM_IDI0,
+			  0x80 | dev->node[IMAGE_NODE].fmt->csi_dt);
+	}
+}
+
+static void unicam_enable_ed(struct unicam_device *dev)
+{
+	u32 val = reg_read(dev, UNICAM_DCS);
+
+	set_field(&val, 2, UNICAM_EDL_MASK);
+	/* Do not wrap at the end of the embedded data buffer */
+	set_field(&val, 0, UNICAM_DBOB);
+
+	reg_write(dev, UNICAM_DCS, val);
+}
+
+static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr)
+{
+	int line_int_freq = dev->node[IMAGE_NODE].v_fmt.fmt.pix.height >> 2;
+	unsigned int size, i;
+	u32 val;
+
+	if (line_int_freq < 128)
+		line_int_freq = 128;
+
+	/* Enable lane clocks */
+	val = 1;
+	for (i = 0; i < dev->active_data_lanes; i++)
+		val = val << 2 | 1;
+	clk_write(dev, val);
+
+	/* Basic init */
+	reg_write(dev, UNICAM_CTRL, UNICAM_MEM);
+
+	/* Enable analogue control, and leave in reset. */
+	val = UNICAM_AR;
+	set_field(&val, 7, UNICAM_CTATADJ_MASK);
+	set_field(&val, 7, UNICAM_PTATADJ_MASK);
+	reg_write(dev, UNICAM_ANA, val);
+	usleep_range(1000, 2000);
+
+	/* Come out of reset */
+	reg_write_field(dev, UNICAM_ANA, 0, UNICAM_AR);
+
+	/* Peripheral reset */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
+
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
+
+	/* Enable Rx control. */
+	val = reg_read(dev, UNICAM_CTRL);
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK);
+		set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK);
+	} else {
+		set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK);
+		set_field(&val, dev->bus_flags, UNICAM_DCM_MASK);
+	}
+	/* Packet framer timeout */
+	set_field(&val, 0xf, UNICAM_PFT_MASK);
+	set_field(&val, 128, UNICAM_OET_MASK);
+	reg_write(dev, UNICAM_CTRL, val);
+
+	reg_write(dev, UNICAM_IHWIN, 0);
+	reg_write(dev, UNICAM_IVWIN, 0);
+
+	/* AXI bus access QoS setup */
+	val = reg_read(dev, UNICAM_PRI);
+	set_field(&val, 0, UNICAM_BL_MASK);
+	set_field(&val, 0, UNICAM_BS_MASK);
+	set_field(&val, 0xe, UNICAM_PP_MASK);
+	set_field(&val, 8, UNICAM_NP_MASK);
+	set_field(&val, 2, UNICAM_PT_MASK);
+	set_field(&val, 1, UNICAM_PE);
+	reg_write(dev, UNICAM_PRI, val);
+
+	reg_write_field(dev, UNICAM_ANA, 0, UNICAM_DDL);
+
+	/* Always start in trigger frame capture mode (UNICAM_FCM set) */
+	val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB;
+	set_field(&val, line_int_freq, UNICAM_LCIE_MASK);
+	reg_write(dev, UNICAM_ICTL, val);
+	reg_write(dev, UNICAM_STA, UNICAM_STA_MASK_ALL);
+	reg_write(dev, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL);
+
+	/* tclk_term_en */
+	reg_write_field(dev, UNICAM_CLT, 2, UNICAM_CLT1_MASK);
+	/* tclk_settle */
+	reg_write_field(dev, UNICAM_CLT, 6, UNICAM_CLT2_MASK);
+	/* td_term_en */
+	reg_write_field(dev, UNICAM_DLT, 2, UNICAM_DLT1_MASK);
+	/* ths_settle */
+	reg_write_field(dev, UNICAM_DLT, 6, UNICAM_DLT2_MASK);
+	/* trx_enable */
+	reg_write_field(dev, UNICAM_DLT, 0, UNICAM_DLT3_MASK);
+
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_SOE);
+
+	/* Packet compare setup - required to avoid missing frame ends */
+	val = 0;
+	set_field(&val, 1, UNICAM_PCE);
+	set_field(&val, 1, UNICAM_GI);
+	set_field(&val, 1, UNICAM_CPH);
+	set_field(&val, 0, UNICAM_PCVC_MASK);
+	set_field(&val, 1, UNICAM_PCDT_MASK);
+	reg_write(dev, UNICAM_CMP0, val);
+
+	/* Enable clock lane and set up terminations */
+	val = 0;
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 */
+		set_field(&val, 1, UNICAM_CLE);
+		set_field(&val, 1, UNICAM_CLLPE);
+		if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+			set_field(&val, 1, UNICAM_CLTRE);
+			set_field(&val, 1, UNICAM_CLHSE);
+		}
+	} else {
+		/* CCP2 */
+		set_field(&val, 1, UNICAM_CLE);
+		set_field(&val, 1, UNICAM_CLHSE);
+		set_field(&val, 1, UNICAM_CLTRE);
+	}
+	reg_write(dev, UNICAM_CLK, val);
+
+	/*
+	 * Enable required data lanes with appropriate terminations.
+	 * The same value needs to be written to UNICAM_DATn registers for
+	 * the active lanes, and 0 for inactive ones.
+	 */
+	val = 0;
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 */
+		set_field(&val, 1, UNICAM_DLE);
+		set_field(&val, 1, UNICAM_DLLPE);
+		if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+			set_field(&val, 1, UNICAM_DLTRE);
+			set_field(&val, 1, UNICAM_DLHSE);
+		}
+	} else {
+		/* CCP2 */
+		set_field(&val, 1, UNICAM_DLE);
+		set_field(&val, 1, UNICAM_DLHSE);
+		set_field(&val, 1, UNICAM_DLTRE);
+	}
+	reg_write(dev, UNICAM_DAT0, val);
+
+	if (dev->active_data_lanes == 1)
+		val = 0;
+	reg_write(dev, UNICAM_DAT1, val);
+
+	if (dev->max_data_lanes > 2) {
+		/*
+		 * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the
+		 * instance supports more than 2 data lanes.
+		 */
+		if (dev->active_data_lanes == 2)
+			val = 0;
+		reg_write(dev, UNICAM_DAT2, val);
+
+		if (dev->active_data_lanes == 3)
+			val = 0;
+		reg_write(dev, UNICAM_DAT3, val);
+	}
+
+	reg_write(dev, UNICAM_IBLS,
+		  dev->node[IMAGE_NODE].v_fmt.fmt.pix.bytesperline);
+	size = dev->node[IMAGE_NODE].v_fmt.fmt.pix.sizeimage;
+	unicam_wr_dma_addr(dev, addr[IMAGE_NODE], size, IMAGE_NODE);
+	unicam_set_packing_config(dev);
+	unicam_cfg_image_id(dev);
+
+	val = reg_read(dev, UNICAM_MISC);
+	set_field(&val, 1, UNICAM_FL0);
+	set_field(&val, 1, UNICAM_FL1);
+	reg_write(dev, UNICAM_MISC, val);
+
+	if (dev->node[METADATA_NODE].streaming && dev->sensor_embedded_data) {
+		unicam_dbg(3, dev, "enable metadata dma\n");
+		size = dev->node[METADATA_NODE].v_fmt.fmt.meta.buffersize;
+		unicam_enable_ed(dev);
+		unicam_wr_dma_addr(dev, addr[METADATA_NODE], size, METADATA_NODE);
+	}
+
+	/* Enable peripheral */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPE);
+
+	/* Load image pointers */
+	reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_LIP_MASK);
+
+	/* Load embedded data buffer pointers if needed */
+	if (dev->node[METADATA_NODE].streaming && dev->sensor_embedded_data)
+		reg_write_field(dev, UNICAM_DCS, 1, UNICAM_LDP);
+
+	/*
+	 * Enable trigger only for the first frame to
+	 * sync correctly to the FS from the source.
+	 */
+	reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_TFC);
+}
+
+static void unicam_disable(struct unicam_device *dev)
+{
+	/* Analogue lane control disable */
+	reg_write_field(dev, UNICAM_ANA, 1, UNICAM_DDL);
+
+	/* Stop the output engine */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_SOE);
+
+	/* Disable the data lanes. */
+	reg_write(dev, UNICAM_DAT0, 0);
+	reg_write(dev, UNICAM_DAT1, 0);
+
+	if (dev->max_data_lanes > 2) {
+		reg_write(dev, UNICAM_DAT2, 0);
+		reg_write(dev, UNICAM_DAT3, 0);
+	}
+
+	/* Peripheral reset */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
+	usleep_range(50, 100);
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
+
+	/* Disable peripheral */
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
+
+	/* Clear ED setup */
+	reg_write(dev, UNICAM_DCS, 0);
+
+	/* Disable all lane clocks */
+	clk_write(dev, 0);
+}
+
+static void unicam_return_buffers(struct unicam_node *node,
+				  enum vb2_buffer_state state)
+{
+	struct unicam_buffer *buf, *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, state);
+	}
+
+	if (node->cur_frm)
+		vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
+				state);
+	if (node->next_frm && node->cur_frm != node->next_frm)
+		vb2_buffer_done(&node->next_frm->vb.vb2_buf,
+				state);
+
+	node->cur_frm = NULL;
+	node->next_frm = NULL;
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+}
+
+static int unicam_video_check_format(struct unicam_node *node)
+{
+	const struct v4l2_mbus_framefmt *format;
+	struct media_pad *remote_pad;
+	struct v4l2_subdev_state *state;
+	int ret = 0;
+
+	remote_pad = media_entity_remote_pad(&node->pad);
+	if (!remote_pad)
+		return -ENODEV;
+
+	state = v4l2_subdev_lock_active_state(node->dev->sensor);
+
+	format = v4l2_state_get_stream_format(state,
+					      remote_pad->index, 0);
+	if (!format) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (node->fmt->code != format->code ||
+	    node->v_fmt.fmt.pix.height != format->height ||
+	    node->v_fmt.fmt.pix.width != format->width ||
+	    node->v_fmt.fmt.pix.field != format->field) {
+		ret = -EPIPE;
+		goto out;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+	dma_addr_t buffer_addr[MAX_NODES] = { 0 };
+	struct unicam_buffer *buf;
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+
+	node->streaming = true;
+
+	dev->sequence = 0;
+	ret = unicam_runtime_get(dev);
+	if (ret < 0) {
+		unicam_dbg(3, dev, "unicam_runtime_get failed\n");
+		goto err_streaming;
+	}
+
+	ret = media_pipeline_start(node->video_dev.entity.pads, &node->pipe);
+	if (ret < 0) {
+		unicam_err(dev, "Failed to start media pipeline: %d\n", ret);
+		goto err_pm_put;
+	}
+
+	dev->active_data_lanes = dev->max_data_lanes;
+
+	unicam_video_check_format(node);
+
+	unicam_dbg(1, dev, "Running with %u data lanes\n",
+		   dev->active_data_lanes);
+
+	ret = clk_set_min_rate(dev->vpu_clock, MIN_VPU_CLOCK_RATE);
+	if (ret) {
+		unicam_err(dev, "failed to set up VPU clock\n");
+		goto error_pipeline;
+	}
+
+	ret = clk_prepare_enable(dev->vpu_clock);
+	if (ret) {
+		unicam_err(dev, "Failed to enable VPU clock: %d\n", ret);
+		goto error_pipeline;
+	}
+
+	ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
+	if (ret) {
+		unicam_err(dev, "failed to set up CSI clock\n");
+		goto err_vpu_clock;
+	}
+
+	ret = clk_prepare_enable(dev->clock);
+	if (ret) {
+		unicam_err(dev, "Failed to enable CSI clock: %d\n", ret);
+		goto err_vpu_clock;
+	}
+
+	unicam_dbg(3, dev, "node %s\n", node->video_dev.name);
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	buf = list_first_entry(&node->dma_queue,
+			       struct unicam_buffer, list);
+	node->cur_frm = buf;
+	node->next_frm = buf;
+	list_del(&buf->list);
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+
+	buffer_addr[i] =
+		vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+
+	unicam_start_rx(dev, buffer_addr);
+
+	ret = v4l2_subdev_call(&dev->sd, video, s_stream, 1);
+	if (ret < 0) {
+		unicam_err(dev, "stream on failed in subdev\n");
+		goto err_disable_unicam;
+	}
+
+	dev->clocks_enabled = true;
+	return 0;
+
+err_disable_unicam:
+	unicam_disable(dev);
+	clk_disable_unprepare(dev->clock);
+err_vpu_clock:
+	if (clk_set_min_rate(dev->vpu_clock, 0))
+		unicam_err(dev, "failed to reset the VPU clock\n");
+	clk_disable_unprepare(dev->vpu_clock);
+error_pipeline:
+	media_pipeline_stop(node->video_dev.entity.pads);
+err_pm_put:
+	unicam_runtime_put(dev);
+err_streaming:
+	unicam_return_buffers(node, VB2_BUF_STATE_QUEUED);
+	node->streaming = false;
+
+	return ret;
+}
+
+static void unicam_stop_streaming(struct vb2_queue *vq)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+
+	node->streaming = false;
+	/*
+	 * Stop streaming the sensor and disable the peripheral.
+	 * We cannot continue streaming embedded data with the
+	 * image pad disabled.
+	 */
+	if (v4l2_subdev_call(dev->sensor, video, s_stream, 0) < 0)
+		unicam_err(dev, "stream off failed in subdev\n");
+
+	unicam_disable(dev);
+
+	media_pipeline_stop(node->video_dev.entity.pads);
+
+	if (dev->clocks_enabled) {
+		if (clk_set_min_rate(dev->vpu_clock, 0))
+			unicam_err(dev, "failed to reset the VPU clock\n");
+		clk_disable_unprepare(dev->vpu_clock);
+		clk_disable_unprepare(dev->clock);
+		dev->clocks_enabled = false;
+	}
+	unicam_runtime_put(dev);
+
+	if (is_metadata_node(node)) {
+		/*
+		 * Allow the hardware to spin in the dummy buffer.
+		 * This is only really needed if the embedded data pad is
+		 * disabled before the image pad.
+		 */
+		unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr,
+				   DUMMY_BUF_SIZE, METADATA_NODE);
+	}
+
+	/* Clear all queued buffers for the node */
+	unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
+}
+
+static const struct vb2_ops unicam_video_qops = {
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+	.queue_setup		= unicam_queue_setup,
+	.buf_prepare		= unicam_buffer_prepare,
+	.buf_queue		= unicam_buffer_queue,
+	.start_streaming	= unicam_start_streaming,
+	.stop_streaming		= unicam_stop_streaming,
+};
+
+/* unicam capture driver file operations */
+static const struct v4l2_file_operations unicam_fops = {
+	.owner		= THIS_MODULE,
+	.open           = v4l2_fh_open,
+	.release        = vb2_fop_release,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+	.mmap           = vb2_fop_mmap,
+};
+
+static int
+unicam_async_bound(struct v4l2_async_notifier *notifier,
+		   struct v4l2_subdev *subdev,
+		   struct v4l2_async_subdev *asd)
+{
+	struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
+
+	if (unicam->sensor) {
+		unicam_info(unicam, "Rejecting subdev %s (Already set!!)",
+			    subdev->name);
+		return 0;
+	}
+
+	unicam->sensor = subdev;
+	unicam_dbg(1, unicam, "Using sensor %s for capture\n", subdev->name);
+
+	return 0;
+}
+
+static void unicam_release(struct kref *kref)
+{
+	struct unicam_device *unicam =
+		container_of(kref, struct unicam_device, kref);
+
+	v4l2_ctrl_handler_free(&unicam->ctrl_handler);
+	media_device_cleanup(&unicam->mdev);
+
+	if (unicam->sensor_state)
+		__v4l2_subdev_state_free(unicam->sensor_state);
+
+	kfree(unicam);
+}
+
+static void unicam_put(struct unicam_device *unicam)
+{
+	kref_put(&unicam->kref, unicam_release);
+}
+
+static void unicam_get(struct unicam_device *unicam)
+{
+	kref_get(&unicam->kref);
+}
+
+static void unicam_node_release(struct video_device *vdev)
+{
+	struct unicam_node *node = video_get_drvdata(vdev);
+
+	unicam_put(node->dev);
+}
+
+static void unicam_mc_set_default_format(struct unicam_node *node)
+{
+	unicam_dbg(3, node->dev, "Set default format for %s node\n",
+		   node->node_id == IMAGE_NODE ? "image" : "metadata");
+
+	if (is_image_node(node)) {
+		struct v4l2_pix_format *pix_fmt = &node->v_fmt.fmt.pix;
+
+		pix_fmt->width = 640;
+		pix_fmt->height = 480;
+		pix_fmt->field = V4L2_FIELD_NONE;
+		pix_fmt->colorspace = V4L2_COLORSPACE_SRGB;
+		pix_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+		pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+		pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
+		pix_fmt->pixelformat = formats[0].fourcc;
+		unicam_calc_format_size_bpl(node->dev, &formats[0],
+					    &node->v_fmt);
+		node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+		node->fmt = &formats[0];
+	} else {
+		const struct unicam_fmt *fmt;
+
+		/* Fix this node format as embedded data. */
+		fmt = find_format_by_code(MEDIA_BUS_FMT_METADATA_8);
+		node->v_fmt.fmt.meta.dataformat = fmt->fourcc;
+		node->fmt = fmt;
+		node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE;
+		node->embedded_lines = 1;
+		node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE;
+	}
+}
+
+static int register_node(struct unicam_device *unicam, struct unicam_node *node,
+			 enum v4l2_buf_type type)
+{
+	struct video_device *vdev;
+	struct vb2_queue *q;
+	int ret;
+
+	node->dev = unicam;
+	node->node_id = type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
+				IMAGE_NODE :
+				METADATA_NODE;
+
+	spin_lock_init(&node->dma_queue_lock);
+	mutex_init(&node->lock);
+
+	vdev = &node->video_dev;
+	/*
+	 * If the sensor subdevice has any controls, associate the node
+	 *  with the ctrl handler to allow access from userland.
+	 */
+	if (!list_empty(&unicam->ctrl_handler.ctrls))
+		vdev->ctrl_handler = &unicam->ctrl_handler;
+
+	q = &node->buffer_queue;
+	q->type = type;
+	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+	q->drv_priv = node;
+	q->ops = &unicam_video_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->buf_struct_size = sizeof(struct unicam_buffer);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &node->lock;
+	q->min_buffers_needed = 1;
+	q->dev = &unicam->pdev->dev;
+
+	ret = vb2_queue_init(q);
+	if (ret) {
+		unicam_err(unicam, "vb2_queue_init() failed\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&node->dma_queue);
+
+	vdev->release = unicam_node_release;
+	vdev->fops = &unicam_fops;
+	vdev->ioctl_ops = &unicam_mc_ioctl_ops;
+	vdev->v4l2_dev = &unicam->v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	vdev->queue = q;
+	vdev->lock = &node->lock;
+	vdev->device_caps = (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+				V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_META_CAPTURE;
+	vdev->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+	vdev->entity.ops = &unicam_mc_entity_ops;
+
+	/* Define the device names */
+	snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME,
+		 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "image" : "embedded");
+
+	video_set_drvdata(vdev, node);
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
+	node->pad.flags = MEDIA_PAD_FL_SINK;
+	media_entity_pads_init(&vdev->entity, 1, &node->pad);
+
+	node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev,
+						      DUMMY_BUF_SIZE,
+						      &node->dummy_buf_dma_addr,
+						      GFP_KERNEL);
+	if (!node->dummy_buf_cpu_addr) {
+		unicam_err(unicam, "Unable to allocate dummy buffer.\n");
+		return -ENOMEM;
+	}
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		unicam_err(unicam, "Unable to register video device %s\n",
+			   vdev->name);
+		return ret;
+	}
+
+	/*
+	 * Acquire a reference to unicam, which will be released when the video
+	 * device will be unregistered and userspace will have closed all open
+	 * file handles.
+	 */
+	unicam_get(unicam);
+	node->registered = true;
+
+	ret = media_create_pad_link(&unicam->sd.entity,
+				    node->src_pad_id,
+				    &node->video_dev.entity,
+				    0,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		unicam_err(unicam, "Unable to create pad link for %s",
+			   unicam->sensor->name);
+
+	unicam_mc_set_default_format(node);
+
+	return ret;
+}
+
+static void unregister_nodes(struct unicam_device *unicam)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+		struct unicam_node *node = &unicam->node[i];
+
+		if (node->dummy_buf_cpu_addr) {
+			dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE,
+					  node->dummy_buf_cpu_addr,
+					  node->dummy_buf_dma_addr);
+		}
+
+		if (node->registered) {
+			node->registered = false;
+			video_unregister_device(&node->video_dev);
+		}
+	}
+}
+
+static int unicam_async_complete(struct v4l2_async_notifier *notifier)
+{
+	struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
+	unsigned int i, source_pads = 0;
+	int ret;
+	static struct lock_class_key key;
+
+	unicam->v4l2_dev.notify = unicam_notify;
+
+	unicam->sensor_state = __v4l2_subdev_state_alloc(unicam->sensor,
+							 "unicam:state->lock",
+							 &key);
+	if (!unicam->sensor_state)
+		return -ENOMEM;
+
+	for (i = 0; i < unicam->sd.entity.num_pads; i++) {
+		if (unicam->sd.entity.pads[i].flags & MEDIA_PAD_FL_SOURCE) {
+			if (source_pads < MAX_NODES) {
+				unicam->node[source_pads].src_pad_id = i;
+				unicam_dbg(3, unicam, "source pad %u is index %u\n",
+					   source_pads, i);
+			}
+			source_pads++;
+		}
+	}
+	if (!source_pads) {
+		unicam_err(unicam, "No source pads on sensor.\n");
+		goto unregister;
+	}
+
+	ret = register_node(unicam, &unicam->node[IMAGE_NODE],
+			    V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret) {
+		unicam_err(unicam, "Unable to register image video device.\n");
+		goto unregister;
+	}
+
+	/* \todo: check before :-) */
+	unicam->sensor_embedded_data = true;
+
+	ret = register_node(unicam, &unicam->node[METADATA_NODE],
+			    V4L2_BUF_TYPE_META_CAPTURE);
+	if (ret) {
+		unicam_err(unicam, "Unable to register metadata video device.\n");
+		goto unregister;
+	}
+
+	ret = media_create_pad_link(&unicam->sensor->entity,
+				    0,
+				    &unicam->sd.entity,
+				    UNICAM_SD_PAD_SINK,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		unicam_err(unicam, "Unable to create pad link for %s",
+			   unicam->sensor->name);
+
+	ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev);
+	if (ret) {
+		unicam_err(unicam, "Unable to register subdev nodes.\n");
+		goto unregister;
+	}
+
+	/*
+	 * Release the initial reference, all references are now owned by the
+	 * video devices.
+	 */
+	unicam_put(unicam);
+	return 0;
+
+unregister:
+	unregister_nodes(unicam);
+	unicam_put(unicam);
+
+	return ret;
+}
+
+static const struct v4l2_async_notifier_operations unicam_async_ops = {
+	.bound = unicam_async_bound,
+	.complete = unicam_async_complete,
+};
+
+static int of_unicam_connect_subdevs(struct unicam_device *dev)
+{
+	struct platform_device *pdev = dev->pdev;
+	struct v4l2_fwnode_endpoint ep = { };
+	struct device_node *ep_node;
+	struct device_node *sensor_node;
+	unsigned int lane;
+	int ret = -EINVAL;
+
+	if (of_property_read_u32(pdev->dev.of_node, "brcm,num-data-lanes",
+				 &dev->max_data_lanes) < 0) {
+		unicam_err(dev, "number of data lanes not set\n");
+		return -EINVAL;
+	}
+
+	/* Get the local endpoint and remote device. */
+	ep_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+	if (!ep_node) {
+		unicam_dbg(3, dev, "can't get next endpoint\n");
+		return -EINVAL;
+	}
+
+	unicam_dbg(3, dev, "ep_node is %pOF\n", ep_node);
+
+	sensor_node = of_graph_get_remote_port_parent(ep_node);
+	if (!sensor_node) {
+		unicam_dbg(3, dev, "can't get remote parent\n");
+		goto cleanup_exit;
+	}
+
+	unicam_dbg(1, dev, "found subdevice %pOF\n", sensor_node);
+
+	/* Parse the local endpoint and validate its configuration. */
+	v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);
+
+	unicam_dbg(3, dev, "parsed local endpoint, bus_type %u\n",
+		   ep.bus_type);
+
+	dev->bus_type = ep.bus_type;
+
+	switch (ep.bus_type) {
+	case V4L2_MBUS_CSI2_DPHY:
+		switch (ep.bus.mipi_csi2.num_data_lanes) {
+		case 1:
+		case 2:
+		case 4:
+			break;
+
+		default:
+			unicam_err(dev, "subdevice %pOF: %u data lanes not supported\n",
+				   sensor_node,
+				   ep.bus.mipi_csi2.num_data_lanes);
+			goto cleanup_exit;
+		}
+
+		for (lane = 0; lane < ep.bus.mipi_csi2.num_data_lanes; lane++) {
+			if (ep.bus.mipi_csi2.data_lanes[lane] != lane + 1) {
+				unicam_err(dev, "subdevice %pOF: data lanes reordering not supported\n",
+					   sensor_node);
+				goto cleanup_exit;
+			}
+		}
+
+		if (ep.bus.mipi_csi2.num_data_lanes > dev->max_data_lanes) {
+			unicam_err(dev, "subdevice requires %u data lanes when %u are supported\n",
+				   ep.bus.mipi_csi2.num_data_lanes,
+				   dev->max_data_lanes);
+		}
+
+		dev->max_data_lanes = ep.bus.mipi_csi2.num_data_lanes;
+		dev->bus_flags = ep.bus.mipi_csi2.flags;
+
+		break;
+
+	case V4L2_MBUS_CCP2:
+		if (ep.bus.mipi_csi1.clock_lane != 0 ||
+		    ep.bus.mipi_csi1.data_lane != 1) {
+			unicam_err(dev, "subdevice %pOF: unsupported lanes configuration\n",
+				   sensor_node);
+			goto cleanup_exit;
+		}
+
+		dev->max_data_lanes = 1;
+		dev->bus_flags = ep.bus.mipi_csi1.strobe;
+		break;
+
+	default:
+		/* Unsupported bus type */
+		unicam_err(dev, "subdevice %pOF: unsupported bus type %u\n",
+			   sensor_node, ep.bus_type);
+		goto cleanup_exit;
+	}
+
+	unicam_dbg(3, dev, "subdevice %pOF: %s bus, %u data lanes, flags=0x%08x\n",
+		   sensor_node,
+		   dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI-2" : "CCP2",
+		   dev->max_data_lanes, dev->bus_flags);
+
+	/* Initialize and register the async notifier. */
+	v4l2_async_nf_init(&dev->notifier);
+	dev->notifier.ops = &unicam_async_ops;
+
+	dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+	dev->asd.match.fwnode = fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep_node));
+	ret = v4l2_async_nf_add_subdev(&dev->notifier, &dev->asd);
+	if (ret) {
+		unicam_err(dev, "Error adding subdevice: %d\n", ret);
+		goto cleanup_exit;
+	}
+
+	ret = v4l2_async_nf_register(&dev->v4l2_dev, &dev->notifier);
+	if (ret) {
+		unicam_err(dev, "Error registering async notifier: %d\n", ret);
+		ret = -EINVAL;
+	}
+
+cleanup_exit:
+	of_node_put(sensor_node);
+	of_node_put(ep_node);
+
+	return ret;
+}
+
+static int bcm2835_media_dev_init(struct unicam_device *unicam,
+				  struct platform_device *pdev)
+{
+	int ret = 0;
+
+	unicam->mdev.dev = &pdev->dev;
+	strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
+		sizeof(unicam->mdev.model));
+	strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial));
+	snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info),
+		 "platform:%s", dev_name(&pdev->dev));
+	unicam->mdev.hw_revision = 0;
+
+	media_device_init(&unicam->mdev);
+
+	unicam->v4l2_dev.mdev = &unicam->mdev;
+
+	ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev);
+
+	return ret;
+}
+
+/* Internal subdev */
+
+static int _unicam_subdev_set_routing(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state,
+				      struct v4l2_subdev_krouting *routing)
+{
+	static const struct v4l2_mbus_framefmt format = {
+		.width = 640,
+		.height = 480,
+		.code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.ycbcr_enc = V4L2_YCBCR_ENC_601,
+		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_SRGB,
+		.flags = 0,
+	};
+	int ret;
+
+	ret = v4l2_subdev_routing_validate_1_to_1(routing);
+	if (ret)
+		return ret;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+
+	v4l2_subdev_unlock_state(state);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int unicam_subdev_set_routing(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *state,
+				     enum v4l2_subdev_format_whence which,
+				     struct v4l2_subdev_krouting *routing)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+
+	if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->streaming)
+		return -EBUSY;
+
+	return _unicam_subdev_set_routing(sd, state, routing);
+}
+
+static int unicam_subdev_init_cfg(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = 0,
+			.sink_stream = 0,
+			.source_pad = 1,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	/* Initialize routing to single route to the fist source pad */
+	return _unicam_subdev_set_routing(sd, state, &routing);
+}
+
+static int unicam_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					struct v4l2_subdev_mbus_code_enum *code)
+{
+	int ret = 0;
+
+	v4l2_subdev_lock_state(state);
+
+	/* No transcoding, source and sink codes must match. */
+	if (unicam_sd_pad_is_source(code->pad)) {
+		struct v4l2_mbus_framefmt *fmt;
+
+		if (code->index > 0) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fmt = v4l2_subdev_state_get_opposite_stream_format(state,
+								   code->pad,
+								   code->stream);
+		if (!fmt) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		code->code = fmt->code;
+	} else {
+		if (code->index >= ARRAY_SIZE(formats)) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		code->code = formats[code->index].code;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_subdev_start_streaming(struct unicam_device *unicam)
+{
+	const struct v4l2_subdev_krouting *routing;
+	struct v4l2_subdev_state *state;
+	int ret = 0;
+
+	state = v4l2_subdev_lock_active_state(&unicam->sd);
+
+	routing = &state->routing;
+
+	v4l2_subdev_unlock_state(state);
+
+	unicam->streaming = true;
+
+	ret = v4l2_subdev_call(unicam->sensor, video, s_stream, 1);
+	if (ret) {
+		v4l2_subdev_call(unicam->sensor, video, s_stream, 0);
+		unicam->streaming = false;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int unicam_subdev_stop_streaming(struct unicam_device *unicam)
+{
+	v4l2_subdev_call(unicam->sensor, video, s_stream, 0);
+
+	unicam->streaming = false;
+
+	return 0;
+}
+
+static int unicam_subdev_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+
+	if (enable)
+		return unicam_subdev_start_streaming(unicam);
+	else
+		return unicam_subdev_stop_streaming(unicam);
+	return 0;
+}
+
+static int unicam_subdev_set_pad_format(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					struct v4l2_subdev_format *format)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+	struct v4l2_mbus_framefmt *fmt;
+	int ret = 0;
+
+	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->streaming)
+		return -EBUSY;
+
+	/* No transcoding, source and sink formats must match. */
+	if (unicam_sd_pad_is_source(format->pad))
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	// TODO: implement fmt validation
+
+	v4l2_subdev_lock_state(state);
+
+	fmt = v4l2_state_get_stream_format(state, format->pad, format->stream);
+	if (!fmt) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*fmt = format->format;
+
+	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!fmt) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*fmt = format->format;
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_subdev_enum_frame_size(struct v4l2_subdev *sd,
+					 struct v4l2_subdev_state *state,
+					 struct v4l2_subdev_frame_size_enum *fse)
+{
+	const struct unicam_fmt *fmtinfo;
+	int ret = 0;
+
+	if (fse->index > 0)
+		return -EINVAL;
+
+	v4l2_subdev_lock_state(state);
+
+	/* No transcoding, source and sink formats must match. */
+	if (unicam_sd_pad_is_source(fse->pad)) {
+		struct v4l2_mbus_framefmt *fmt;
+
+		fmt = v4l2_subdev_state_get_opposite_stream_format(state,
+								   fse->pad,
+								   fse->stream);
+
+		if (!fmt) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (fse->code != fmt->code) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fse->min_width = fmt->width;
+		fse->max_width = fmt->width;
+		fse->min_height = fmt->height;
+		fse->max_height = fmt->height;
+	} else {
+		fmtinfo = find_format_by_code(fse->code);
+		if (!fmtinfo) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fse->min_width = MIN_WIDTH * 8 / ALIGN(fmtinfo->depth, 8);
+		fse->max_width = MAX_WIDTH * 8 / ALIGN(fmtinfo->depth, 8);
+		fse->min_height = MIN_HEIGHT;
+		fse->max_height = MAX_HEIGHT;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops unicam_subdev_video_ops = {
+	.s_stream	= unicam_subdev_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops unicam_subdev_pad_ops = {
+	.init_cfg		= unicam_subdev_init_cfg,
+	.enum_mbus_code		= unicam_subdev_enum_mbus_code,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= unicam_subdev_set_pad_format,
+	.set_routing		= unicam_subdev_set_routing,
+	.enum_frame_size	= unicam_subdev_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops unicam_subdev_ops = {
+	.video		= &unicam_subdev_video_ops,
+	.pad		= &unicam_subdev_pad_ops,
+};
+
+static struct media_entity_operations unicam_subdev_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+	.has_route = v4l2_subdev_has_route,
+};
+
+static int unicam_probe(struct platform_device *pdev)
+{
+	struct unicam_device *unicam;
+	int ret = 0;
+	int i;
+
+	unicam = kzalloc(sizeof(*unicam), GFP_KERNEL);
+	if (!unicam)
+		return -ENOMEM;
+
+	kref_init(&unicam->kref);
+	unicam->pdev = pdev;
+
+	/*
+	 * Adopt the current setting of the module parameter, and check if
+	 * device tree requests it.
+	 */
+	if (!of_property_read_bool(pdev->dev.of_node, "brcm,media-controller")) {
+		unicam_err(unicam, "Failed to find media-controller node\n");
+		goto err_unicam_put;
+	}
+
+	unicam->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(unicam->base)) {
+		unicam_err(unicam, "Failed to get main io block\n");
+		ret = PTR_ERR(unicam->base);
+		goto err_unicam_put;
+	}
+
+	unicam->clk_gate_base = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(unicam->clk_gate_base)) {
+		unicam_err(unicam, "Failed to get 2nd io block\n");
+		ret = PTR_ERR(unicam->clk_gate_base);
+		goto err_unicam_put;
+	}
+
+	unicam->clock = devm_clk_get(&pdev->dev, "lp");
+	if (IS_ERR(unicam->clock)) {
+		unicam_err(unicam, "Failed to get lp clock\n");
+		ret = PTR_ERR(unicam->clock);
+		goto err_unicam_put;
+	}
+
+	unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu");
+	if (IS_ERR(unicam->vpu_clock)) {
+		unicam_err(unicam, "Failed to get vpu clock\n");
+		ret = PTR_ERR(unicam->vpu_clock);
+		goto err_unicam_put;
+	}
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret <= 0) {
+		dev_err(&pdev->dev, "No IRQ resource\n");
+		ret = -EINVAL;
+		goto err_unicam_put;
+	}
+
+	ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
+			       "unicam_capture0", unicam);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to request interrupt\n");
+		ret = -EINVAL;
+		goto err_unicam_put;
+	}
+
+	ret = bcm2835_media_dev_init(unicam, pdev);
+	if (ret) {
+		unicam_err(unicam,
+			   "Unable to register v4l2 device.\n");
+		goto err_unicam_put;
+	}
+
+	ret = media_device_register(&unicam->mdev);
+	if (ret < 0) {
+		unicam_err(unicam,
+			   "Unable to register media-controller device.\n");
+		goto err_v4l2_unregister;
+	}
+
+	/* Reserve space for the controls */
+	ret = v4l2_ctrl_handler_init(&unicam->ctrl_handler, 16);
+	if (ret < 0)
+		goto err_media_unregister;
+
+	/* set the driver data in platform device */
+	platform_set_drvdata(pdev, unicam);
+
+	unicam_dbg(3, unicam, "Initialize internal subdev");
+	v4l2_subdev_init(&unicam->sd, &unicam_subdev_ops);
+	v4l2_set_subdevdata(&unicam->sd, unicam);
+	unicam->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	unicam->sd.dev = &pdev->dev;
+	unicam->sd.owner = THIS_MODULE;
+	unicam->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_MULTIPLEXED;
+	snprintf(unicam->sd.name, sizeof(unicam->sd.name), "unicam-subdev");
+
+	unicam->pads[UNICAM_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+
+	for (i = UNICAM_SD_PAD_FIRST_SOURCE; i < UNICAM_SD_NUM_PADS; ++i)
+		unicam->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+	unicam->sd.entity.ops = &unicam_subdev_media_ops;
+	ret = media_entity_pads_init(&unicam->sd.entity,
+				     ARRAY_SIZE(unicam->pads), unicam->pads);
+	if (ret) {
+		unicam_err(unicam, "Could not init media controller for subdev");
+		goto err_subdev_unregister;
+	}
+
+	ret = v4l2_subdev_init_finalize(&unicam->sd);
+	if (ret) {
+		unicam_err(unicam, "Could not finalize init for subdev");
+		goto err_entity_cleanup;
+	}
+
+	ret = v4l2_device_register_subdev(&unicam->v4l2_dev, &unicam->sd);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register internal subdev\n");
+		goto err_subdev_unregister;
+	}
+
+	ret = of_unicam_connect_subdevs(unicam);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to connect subdevs\n");
+		goto err_subdev_unregister;
+	}
+
+	/* Enable the block power domain */
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+err_subdev_unregister:
+	v4l2_subdev_cleanup(&unicam->sd);
+err_entity_cleanup:
+	media_entity_cleanup(&unicam->sd.entity);
+err_media_unregister:
+	media_device_unregister(&unicam->mdev);
+err_v4l2_unregister:
+	v4l2_device_unregister(&unicam->v4l2_dev);
+err_unicam_put:
+	unicam_put(unicam);
+
+	return ret;
+}
+
+static int unicam_remove(struct platform_device *pdev)
+{
+	struct unicam_device *unicam = platform_get_drvdata(pdev);
+
+	v4l2_async_nf_unregister(&unicam->notifier);
+	v4l2_device_unregister(&unicam->v4l2_dev);
+	media_device_unregister(&unicam->mdev);
+	unregister_nodes(unicam);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id unicam_of_match[] = {
+	{ .compatible = "brcm,bcm2835-unicam", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, unicam_of_match);
+
+static struct platform_driver unicam_driver = {
+	.probe		= unicam_probe,
+	.remove		= unicam_remove,
+	.driver = {
+		.name	= UNICAM_MODULE_NAME,
+		.of_match_table = of_match_ptr(unicam_of_match),
+	},
+};
+
+module_platform_driver(unicam_driver);
+
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson at raspberrypi.com>");
+MODULE_DESCRIPTION("BCM2835 Unicam driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(UNICAM_VERSION);
diff --git a/drivers/media/platform/bcm2835/vc4-regs-unicam.h b/drivers/media/platform/bcm2835/vc4-regs-unicam.h
new file mode 100644
index 000000000000..ae059a171d0f
--- /dev/null
+++ b/drivers/media/platform/bcm2835/vc4-regs-unicam.h
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Copyright (C) 2017-2020 Raspberry Pi Trading.
+ * Dave Stevenson <dave.stevenson at raspberrypi.com>
+ */
+
+#ifndef VC4_REGS_UNICAM_H
+#define VC4_REGS_UNICAM_H
+
+/*
+ * The following values are taken from files found within the code drop
+ * made by Broadcom for the BCM21553 Graphics Driver, predominantly in
+ * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h.
+ * They have been modified to be only the register offset.
+ */
+#define UNICAM_CTRL	0x000
+#define UNICAM_STA	0x004
+#define UNICAM_ANA	0x008
+#define UNICAM_PRI	0x00c
+#define UNICAM_CLK	0x010
+#define UNICAM_CLT	0x014
+#define UNICAM_DAT0	0x018
+#define UNICAM_DAT1	0x01c
+#define UNICAM_DAT2	0x020
+#define UNICAM_DAT3	0x024
+#define UNICAM_DLT	0x028
+#define UNICAM_CMP0	0x02c
+#define UNICAM_CMP1	0x030
+#define UNICAM_CAP0	0x034
+#define UNICAM_CAP1	0x038
+#define UNICAM_ICTL	0x100
+#define UNICAM_ISTA	0x104
+#define UNICAM_IDI0	0x108
+#define UNICAM_IPIPE	0x10c
+#define UNICAM_IBSA0	0x110
+#define UNICAM_IBEA0	0x114
+#define UNICAM_IBLS	0x118
+#define UNICAM_IBWP	0x11c
+#define UNICAM_IHWIN	0x120
+#define UNICAM_IHSTA	0x124
+#define UNICAM_IVWIN	0x128
+#define UNICAM_IVSTA	0x12c
+#define UNICAM_ICC	0x130
+#define UNICAM_ICS	0x134
+#define UNICAM_IDC	0x138
+#define UNICAM_IDPO	0x13c
+#define UNICAM_IDCA	0x140
+#define UNICAM_IDCD	0x144
+#define UNICAM_IDS	0x148
+#define UNICAM_DCS	0x200
+#define UNICAM_DBSA0	0x204
+#define UNICAM_DBEA0	0x208
+#define UNICAM_DBWP	0x20c
+#define UNICAM_DBCTL	0x300
+#define UNICAM_IBSA1	0x304
+#define UNICAM_IBEA1	0x308
+#define UNICAM_IDI1	0x30c
+#define UNICAM_DBSA1	0x310
+#define UNICAM_DBEA1	0x314
+#define UNICAM_MISC	0x400
+
+/*
+ * The following bitmasks are from the kernel released by Broadcom
+ * for Android - https://android.googlesource.com/kernel/bcm/
+ * The Rhea, Hawaii, and Java chips all contain the same VideoCore4
+ * Unicam block as BCM2835, as defined in eg
+ * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar.
+ * Values reworked to use the kernel BIT and GENMASK macros.
+ *
+ * Some of the bit mnenomics have been amended to match the datasheet.
+ */
+/* UNICAM_CTRL Register */
+#define UNICAM_CPE		BIT(0)
+#define UNICAM_MEM		BIT(1)
+#define UNICAM_CPR		BIT(2)
+#define UNICAM_CPM_MASK		GENMASK(3, 3)
+#define UNICAM_CPM_CSI2		0
+#define UNICAM_CPM_CCP2		1
+#define UNICAM_SOE		BIT(4)
+#define UNICAM_DCM_MASK		GENMASK(5, 5)
+#define UNICAM_DCM_STROBE	0
+#define UNICAM_DCM_DATA		1
+#define UNICAM_SLS		BIT(6)
+#define UNICAM_PFT_MASK		GENMASK(11, 8)
+#define UNICAM_OET_MASK		GENMASK(20, 12)
+
+/* UNICAM_STA Register */
+#define UNICAM_SYN		BIT(0)
+#define UNICAM_CS		BIT(1)
+#define UNICAM_SBE		BIT(2)
+#define UNICAM_PBE		BIT(3)
+#define UNICAM_HOE		BIT(4)
+#define UNICAM_PLE		BIT(5)
+#define UNICAM_SSC		BIT(6)
+#define UNICAM_CRCE		BIT(7)
+#define UNICAM_OES		BIT(8)
+#define UNICAM_IFO		BIT(9)
+#define UNICAM_OFO		BIT(10)
+#define UNICAM_BFO		BIT(11)
+#define UNICAM_DL		BIT(12)
+#define UNICAM_PS		BIT(13)
+#define UNICAM_IS		BIT(14)
+#define UNICAM_PI0		BIT(15)
+#define UNICAM_PI1		BIT(16)
+#define UNICAM_FSI_S		BIT(17)
+#define UNICAM_FEI_S		BIT(18)
+#define UNICAM_LCI_S		BIT(19)
+#define UNICAM_BUF0_RDY		BIT(20)
+#define UNICAM_BUF0_NO		BIT(21)
+#define UNICAM_BUF1_RDY		BIT(22)
+#define UNICAM_BUF1_NO		BIT(23)
+#define UNICAM_DI		BIT(24)
+
+#define UNICAM_STA_MASK_ALL \
+		(UNICAM_DL + \
+		UNICAM_SBE + \
+		UNICAM_PBE + \
+		UNICAM_HOE + \
+		UNICAM_PLE + \
+		UNICAM_SSC + \
+		UNICAM_CRCE + \
+		UNICAM_IFO + \
+		UNICAM_OFO + \
+		UNICAM_PS + \
+		UNICAM_PI0 + \
+		UNICAM_PI1)
+
+/* UNICAM_ANA Register */
+#define UNICAM_APD		BIT(0)
+#define UNICAM_BPD		BIT(1)
+#define UNICAM_AR		BIT(2)
+#define UNICAM_DDL		BIT(3)
+#define UNICAM_CTATADJ_MASK	GENMASK(7, 4)
+#define UNICAM_PTATADJ_MASK	GENMASK(11, 8)
+
+/* UNICAM_PRI Register */
+#define UNICAM_PE		BIT(0)
+#define UNICAM_PT_MASK		GENMASK(2, 1)
+#define UNICAM_NP_MASK		GENMASK(7, 4)
+#define UNICAM_PP_MASK		GENMASK(11, 8)
+#define UNICAM_BS_MASK		GENMASK(15, 12)
+#define UNICAM_BL_MASK		GENMASK(17, 16)
+
+/* UNICAM_CLK Register */
+#define UNICAM_CLE		BIT(0)
+#define UNICAM_CLPD		BIT(1)
+#define UNICAM_CLLPE		BIT(2)
+#define UNICAM_CLHSE		BIT(3)
+#define UNICAM_CLTRE		BIT(4)
+#define UNICAM_CLAC_MASK	GENMASK(8, 5)
+#define UNICAM_CLSTE		BIT(29)
+
+/* UNICAM_CLT Register */
+#define UNICAM_CLT1_MASK	GENMASK(7, 0)
+#define UNICAM_CLT2_MASK	GENMASK(15, 8)
+
+/* UNICAM_DATn Registers */
+#define UNICAM_DLE		BIT(0)
+#define UNICAM_DLPD		BIT(1)
+#define UNICAM_DLLPE		BIT(2)
+#define UNICAM_DLHSE		BIT(3)
+#define UNICAM_DLTRE		BIT(4)
+#define UNICAM_DLSM		BIT(5)
+#define UNICAM_DLFO		BIT(28)
+#define UNICAM_DLSTE		BIT(29)
+
+#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO)
+
+/* UNICAM_DLT Register */
+#define UNICAM_DLT1_MASK	GENMASK(7, 0)
+#define UNICAM_DLT2_MASK	GENMASK(15, 8)
+#define UNICAM_DLT3_MASK	GENMASK(23, 16)
+
+/* UNICAM_ICTL Register */
+#define UNICAM_FSIE		BIT(0)
+#define UNICAM_FEIE		BIT(1)
+#define UNICAM_IBOB		BIT(2)
+#define UNICAM_FCM		BIT(3)
+#define UNICAM_TFC		BIT(4)
+#define UNICAM_LIP_MASK		GENMASK(6, 5)
+#define UNICAM_LCIE_MASK	GENMASK(28, 16)
+
+/* UNICAM_IDI0/1 Register */
+#define UNICAM_ID0_MASK		GENMASK(7, 0)
+#define UNICAM_ID1_MASK		GENMASK(15, 8)
+#define UNICAM_ID2_MASK		GENMASK(23, 16)
+#define UNICAM_ID3_MASK		GENMASK(31, 24)
+
+/* UNICAM_ISTA Register */
+#define UNICAM_FSI		BIT(0)
+#define UNICAM_FEI		BIT(1)
+#define UNICAM_LCI		BIT(2)
+
+#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI)
+
+/* UNICAM_IPIPE Register */
+#define UNICAM_PUM_MASK		GENMASK(2, 0)
+		/* Unpacking modes */
+		#define UNICAM_PUM_NONE		0
+		#define UNICAM_PUM_UNPACK6	1
+		#define UNICAM_PUM_UNPACK7	2
+		#define UNICAM_PUM_UNPACK8	3
+		#define UNICAM_PUM_UNPACK10	4
+		#define UNICAM_PUM_UNPACK12	5
+		#define UNICAM_PUM_UNPACK14	6
+		#define UNICAM_PUM_UNPACK16	7
+#define UNICAM_DDM_MASK		GENMASK(6, 3)
+#define UNICAM_PPM_MASK		GENMASK(9, 7)
+		/* Packing modes */
+		#define UNICAM_PPM_NONE		0
+		#define UNICAM_PPM_PACK8	1
+		#define UNICAM_PPM_PACK10	2
+		#define UNICAM_PPM_PACK12	3
+		#define UNICAM_PPM_PACK14	4
+		#define UNICAM_PPM_PACK16	5
+#define UNICAM_DEM_MASK		GENMASK(11, 10)
+#define UNICAM_DEBL_MASK	GENMASK(14, 12)
+#define UNICAM_ICM_MASK		GENMASK(16, 15)
+#define UNICAM_IDM_MASK		GENMASK(17, 17)
+
+/* UNICAM_ICC Register */
+#define UNICAM_ICFL_MASK	GENMASK(4, 0)
+#define UNICAM_ICFH_MASK	GENMASK(9, 5)
+#define UNICAM_ICST_MASK	GENMASK(12, 10)
+#define UNICAM_ICLT_MASK	GENMASK(15, 13)
+#define UNICAM_ICLL_MASK	GENMASK(31, 16)
+
+/* UNICAM_DCS Register */
+#define UNICAM_DIE		BIT(0)
+#define UNICAM_DIM		BIT(1)
+#define UNICAM_DBOB		BIT(3)
+#define UNICAM_FDE		BIT(4)
+#define UNICAM_LDP		BIT(5)
+#define UNICAM_EDL_MASK		GENMASK(15, 8)
+
+/* UNICAM_DBCTL Register */
+#define UNICAM_DBEN		BIT(0)
+#define UNICAM_BUF0_IE		BIT(1)
+#define UNICAM_BUF1_IE		BIT(2)
+
+/* UNICAM_CMP[0,1] register */
+#define UNICAM_PCE		BIT(31)
+#define UNICAM_GI		BIT(9)
+#define UNICAM_CPH		BIT(8)
+#define UNICAM_PCVC_MASK	GENMASK(7, 6)
+#define UNICAM_PCDT_MASK	GENMASK(5, 0)
+
+/* UNICAM_MISC register */
+#define UNICAM_FL0		BIT(6)
+#define UNICAM_FL1		BIT(9)
+
+#endif
-- 
2.32.0



From daniel.thompson at linaro.org  Wed Jan 12 09:29:03 2022
From: daniel.thompson at linaro.org (Daniel Thompson)
Date: Wed, 12 Jan 2022 17:29:03 +0000
Subject: [PATCH v5 08/10] ARM: uaccess: add __{get,put}_kernel_nofault
In-Reply-To: <20210726141141.2839385-9-arnd@kernel.org>
References: <20210726141141.2839385-1-arnd@kernel.org>
 <20210726141141.2839385-9-arnd@kernel.org>
Message-ID: <Yd8P37V/N9EkwmYq@wychelm>

On Mon, Jul 26, 2021 at 04:11:39PM +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd at arndb.de>
> 
> These mimic the behavior of get_user and put_user, except
> for domain switching, address limit checking and handling
> of mismatched sizes, none of which are relevant here.
> 
> To work with pre-Armv6 kernels, this has to avoid TUSER()
> inside of the new macros, the new approach passes the "t"
> string along with the opcode, which is a bit uglier but
> avoids duplicating more code.
> 
> As there is no __get_user_asm_dword(), I work around it
> by copying 32 bit at a time, which is possible because
> the output size is known.
> 
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

I've just been bisecting some regressions running the kgdbts tests on
arm and this patch came up.

It looks like once this patch applies then copy_from_kernel_nofault()
starts faulting when it called from kgdb. I've put an example stack
trace at the bottom of this mail and the most simplified reproduction
I currently have is:
~~~
make multi_v7_defconfig
../scripts/config --enable KGDB --enable KGDB_TESTS
make olddefconfig
make -j `nproc`
qemu-system-arm -M virt -m 1G -nographic \
                -kernel arch/arm/boot/zImage -initrd rootfs.cpio.gz
# Boot and login
echo V1 > /sys/module/kgdbts/parameters/kgdbts
~~~

I suspect this will reproduce on any arm system with CONFIG_KGDB and
CONFIG_KGDB_TESTS enabled simply by running that last echo command...
but I have only tested on QEMU for now.


Daniel.


Stack trace:
~~~
# echo kgdbts=V1F1000 > /sys/module/kgdbts/parameters/kgdbts
[   34.995507] KGDB: Registered I/O driver kgdbts
[   35.038102] kgdbts:RUN plant and detach test

Entering kdb (current=0xd4264380, pid 134) on processor 0 due to Keyboard Entry
[0]kdb> [   35.056005] kgdbts:RUN sw breakpoint test
[   35.062309] kgdbts:RUN bad memory access test
[   35.063619] 8<--- cut here ---
[   35.064022] Unhandled fault: page domain fault (0x01b) at 0x00000000
[   35.064212] pgd = (ptrval)
[   35.064459] [00000000] *pgd=942dc835, *pte=00000000, *ppte=00000000
[   35.065071] Internal error: : 1b [#1] SMP ARM
[   35.065381] KGDB: re-enter exception: ALL breakpoints killed
[   35.065850] ---[ end trace 909d8c43057666be ]---
[   35.066088] 8<--- cut here ---
[   35.066189] Unhandled fault: page domain fault (0x01b) at 0x00000000
[   35.066332] pgd = (ptrval)
[   35.066406] [00000000] *pgd=942dc835, *pte=00000000, *ppte=00000000
[   35.066597] Internal error: : 1b [#2] SMP ARM
[   35.066906] CPU: 0 PID: 134 Comm: sh Tainted: G      D           5.14.0-rc1-00013-g2df4c9a741a0 #60
[   35.067152] Hardware name: ARM-Versatile Express
[   35.067432] [<c0311bdc>] (unwind_backtrace) from [<c030bdc0>] (show_stack+0x10/0x14)
[   35.067880] [<c030bdc0>] (show_stack) from [<c114b9c8>] (dump_stack_lvl+0x58/0x70)
[   35.068054] [<c114b9c8>] (dump_stack_lvl) from [<c0430cdc>] (kgdb_reenter_check+0x104/0x150)
[   35.068213] [<c0430cdc>] (kgdb_reenter_check) from [<c0430dcc>] (kgdb_handle_exception+0xa4/0x114)
[   35.068395] [<c0430dcc>] (kgdb_handle_exception) from [<c0311268>] (kgdb_notify+0x30/0x74)
[   35.068563] [<c0311268>] (kgdb_notify) from [<c037422c>] (atomic_notifier_call_chain+0xac/0x194)
[   35.068745] [<c037422c>] (atomic_notifier_call_chain) from [<c0374370>] (notify_die+0x5c/0xbc)
[   35.068933] [<c0374370>] (notify_die) from [<c030bf04>] (die+0x140/0x544)
[   35.069079] [<c030bf04>] (die) from [<c03164d4>] (do_DataAbort+0xb8/0xbc)
[   35.069220] [<c03164d4>] (do_DataAbort) from [<c0300afc>] (__dabt_svc+0x5c/0xa0)
[   35.069434] Exception stack(0xd4249c10 to 0xd4249c58)
[   35.069616] 9c00:                                     ???????? ???????? ???????? ????????
[   35.069776] 9c20: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
[   35.069943] 9c40: ???????? ???????? ???????? ???????? ???????? ????????
[   35.070107] [<c0300afc>] (__dabt_svc) from [<c049c8c4>] (copy_from_kernel_nofault+0x114/0x13c)
[   35.070291] [<c049c8c4>] (copy_from_kernel_nofault) from [<c0431688>] (kgdb_mem2hex+0x1c/0x88)
[   35.070463] [<c0431688>] (kgdb_mem2hex) from [<c04322b0>] (gdb_serial_stub+0x8c4/0x1088)
[   35.070640] [<c04322b0>] (gdb_serial_stub) from [<c04302e8>] (kgdb_cpu_enter+0x4f4/0x988)
[   35.070796] [<c04302e8>] (kgdb_cpu_enter) from [<c0430e08>] (kgdb_handle_exception+0xe0/0x114)
[   35.070982] [<c0430e08>] (kgdb_handle_exception) from [<c0311210>] (kgdb_compiled_brk_fn+0x24/0x2c)
[   35.071166] [<c0311210>] (kgdb_compiled_brk_fn) from [<c030c40c>] (do_undefinstr+0x104/0x230)
[   35.071342] [<c030c40c>] (do_undefinstr) from [<c0300c6c>] (__und_svc_finish+0x0/0x54)
[   35.071502] Exception stack(0xd4249dc8 to 0xd4249e10)
[   35.071614] 9dc0:                   ???????? ???????? ???????? ???????? ???????? ????????
[   35.071778] 9de0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
[   35.071944] 9e00: ???????? ???????? ???????? ????????
[   35.072054] [<c0300c6c>] (__und_svc_finish) from [<c042fd20>] (kgdb_breakpoint+0x30/0x58)
[   35.072211] [<c042fd20>] (kgdb_breakpoint) from [<c0b14b08>] (configure_kgdbts+0x228/0x68c)
[   35.072395] [<c0b14b08>] (configure_kgdbts) from [<c036fdcc>] (param_attr_store+0x60/0xb8)
[   35.072560] [<c036fdcc>] (param_attr_store) from [<c05bcf14>] (kernfs_fop_write_iter+0x110/0x1d4)
[   35.072745] [<c05bcf14>] (kernfs_fop_write_iter) from [<c050f074>] (vfs_write+0x350/0x508)
[   35.072920] [<c050f074>] (vfs_write) from [<c050f370>] (ksys_write+0x64/0xdc)
[   35.073075] [<c050f370>] (ksys_write) from [<c03000c0>] (ret_fast_syscall+0x0/0x2c)
[   35.073259] Exception stack(0xd4249fa8 to 0xd4249ff0)
[   35.073372] 9fa0:                   ???????? ???????? ???????? ???????? ???????? ????????
[   35.073527] 9fc0: ???????? ???????? ???????? ???????? ???????? ???????? ???????? ????????
[   35.073679] 9fe0: ???????? ???????? ???????? ????????
[   35.073960] Kernel panic - not syncing: Recursive entry to debugger
[   36.286118] SMP: failed to stop secondary CPUs
[   36.286568] ---[ end Kernel panic - not syncing: Recursive entry to debugger ]---
~~~


From mans at mansr.com  Wed Jan 12 09:33:27 2022
From: mans at mansr.com (Mans Rullgard)
Date: Wed, 12 Jan 2022 17:33:27 +0000
Subject: [PATCH] ARM: dts: sunxi: h3/h5: add r_uart node
Message-ID: <20220112173327.26317-1-mans@mansr.com>

There is an additional UART in the PL I/O block.
Add a node and pinmux for it.

Signed-off-by: Mans Rullgard <mans at mansr.com>
---
The "documentation" doesn't mention any DMA channels for this UART.
If it nonetheless does have DMA capability and someone knows the channel
assignments, feel free to amend.
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 22d533d18992..55ffba5a4e9f 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -884,6 +884,19 @@ r_i2c: i2c at 1f02400 {
 			#size-cells = <0>;
 		};
 
+		r_uart: serial at 1f02800 {
+			compatible = "snps,dw-apb-uart";
+			reg = <0x01f02800 0x400>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			reg-shift = <2>;
+			reg-io-width = <4>;
+			clocks = <&r_ccu CLK_APB0_UART>;
+			resets = <&r_ccu RST_APB0_UART>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&r_uart_pins>;
+			status = "disabled";
+		};
+
 		r_pio: pinctrl at 1f02c00 {
 			compatible = "allwinner,sun8i-h3-r-pinctrl";
 			reg = <0x01f02c00 0x400>;
@@ -909,6 +922,11 @@ r_pwm_pin: r-pwm-pin {
 				pins = "PL10";
 				function = "s_pwm";
 			};
+
+			r_uart_pins: r-uart-pins {
+				pins = "PL2", "PL3";
+				function = "s_uart";
+			};
 		};
 
 		r_pwm: pwm at 1f03800 {
-- 
2.34.1



From kuba at kernel.org  Wed Jan 12 09:36:29 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Wed, 12 Jan 2022 09:36:29 -0800
Subject: [PATCH v2 0/3] ARM: ox810se: Add Ethernet support
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <20220112093629.03ffcb65@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Tue,  4 Jan 2022 15:56:43 +0100 Neil Armstrong wrote:
> This adds support for the Synopsys DWMAC controller found in the
> OX820SE SoC, by using almost the same glue code as the OX820.

Alright, patches 1 and 2 are in net and on their way to 5.17. Thanks!


From robert.hancock at calian.com  Wed Jan 12 09:36:51 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:51 -0600
Subject: [PATCH net v2 0/9] Xilinx axienet fixes
Message-ID: <20220112173700.873002-1-robert.hancock@calian.com>

Various fixes for the Xilinx AXI Ethernet driver.

Changed since v1:
-corrected a Fixes tag to point to mainline commit
-split up reset changes into 3 patches
-added ratelimit on netdev_warn in TX busy case

Robert Hancock (9):
  net: axienet: increase reset timeout
  net: axienet: Wait for PhyRstCmplt after core reset
  net: axienet: reset core on initialization prior to MDIO access
  net: axienet: add missing memory barriers
  net: axienet: limit minimum TX ring size
  net: axienet: Fix TX ring slot available check
  net: axienet: fix number of TX ring slots for available check
  net: axienet: fix for TX busy handling
  net: axienet: increase default TX ring size to 128

 .../net/ethernet/xilinx/xilinx_axienet_main.c | 135 +++++++++++-------
 1 file changed, 84 insertions(+), 51 deletions(-)

-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:54 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:54 -0600
Subject: [PATCH net v2 3/9] net: axienet: reset core on initialization prior
 to MDIO access
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-4-robert.hancock@calian.com>

In some cases where the Xilinx Ethernet core was used in 1000Base-X or
SGMII modes, which use the internal PCS/PMA PHY, and the MGT
transceiver clock source for the PCS was not running at the time the
FPGA logic was loaded, the core would come up in a state where the
PCS could not be found on the MDIO bus. To fix this, the Ethernet core
(including the PCS) should be reset after enabling the clocks, prior to
attempting to access the PCS using of_mdio_find_device.

Fixes: 1a02556086fc (net: axienet: Properly handle PCS/PMA PHY for 1000BaseX mode)
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index f425a8404a9b..f4ae035bed35 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -2055,6 +2055,11 @@ static int axienet_probe(struct platform_device *pdev)
 	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
 	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
 
+	/* Reset core now that clocks are enabled, prior to accessing MDIO */
+	ret = __axienet_device_reset(lp);
+	if (ret)
+		goto cleanup_clk;
+
 	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
 	if (lp->phy_node) {
 		ret = axienet_mdio_setup(lp);
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:52 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:52 -0600
Subject: [PATCH net v2 1/9] net: axienet: increase reset timeout
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-2-robert.hancock@calian.com>

The previous timeout of 1ms was too short to handle some cases where the
core is reset just after the input clocks were started, which will
be introduced in an upcoming patch. Increase the timeout to 50ms. Also
simplify the reset timeout checking to use read_poll_timeout.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 90144ac7aee8..f950342f6467 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -496,7 +496,8 @@ static void axienet_setoptions(struct net_device *ndev, u32 options)
 
 static int __axienet_device_reset(struct axienet_local *lp)
 {
-	u32 timeout;
+	u32 value;
+	int ret;
 
 	/* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset
 	 * process of Axi DMA takes a while to complete as all pending
@@ -506,15 +507,13 @@ static int __axienet_device_reset(struct axienet_local *lp)
 	 * they both reset the entire DMA core, so only one needs to be used.
 	 */
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, XAXIDMA_CR_RESET_MASK);
-	timeout = DELAY_OF_ONE_MILLISEC;
-	while (axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET) &
-				XAXIDMA_CR_RESET_MASK) {
-		udelay(1);
-		if (--timeout == 0) {
-			netdev_err(lp->ndev, "%s: DMA reset timeout!\n",
-				   __func__);
-			return -ETIMEDOUT;
-		}
+	ret = read_poll_timeout(axienet_dma_in32, value,
+				!(value & XAXIDMA_CR_RESET_MASK),
+				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
+				XAXIDMA_TX_CR_OFFSET);
+	if (ret) {
+		dev_err(lp->dev, "%s: DMA reset timeout!\n", __func__);
+		return ret;
 	}
 
 	return 0;
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:53 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:53 -0600
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core reset
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-3-robert.hancock@calian.com>

When resetting the device, wait for the PhyRstCmplt bit to be set
in the interrupt status register before continuing initialization, to
ensure that the core is actually ready. The MgtRdy bit could also be
waited for, but unfortunately when using 7-series devices, the bit does
not appear to work as documented (it seems to behave as some sort of
link state indication and not just an indication the transceiver is
ready) so it can't really be relied on.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index f950342f6467..f425a8404a9b 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local *lp)
 		return ret;
 	}
 
+	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has finished */
+	ret = read_poll_timeout(axienet_ior, value,
+				value & XAE_INT_PHYRSTCMPLT_MASK,
+				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
+				XAE_IS_OFFSET);
+	if (ret) {
+		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n", __func__);
+		return ret;
+	}
+
 	return 0;
 }
 
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:56 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:56 -0600
Subject: [PATCH net v2 5/9] net: axienet: limit minimum TX ring size
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-6-robert.hancock@calian.com>

The driver will not work properly if the TX ring size is set to below
MAX_SKB_FRAGS + 1 since it needs to hold at least one full maximally
fragmented packet in the TX ring. Limit setting the ring size to below
this value.

Fixes: 8b09ca823ffb4 ("net: axienet: Make RX/TX ring sizes configurable")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index de8f85175a6c..8a60219d3bfb 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -43,6 +43,7 @@
 /* Descriptors defines for Tx and Rx DMA */
 #define TX_BD_NUM_DEFAULT		64
 #define RX_BD_NUM_DEFAULT		1024
+#define TX_BD_NUM_MIN			(MAX_SKB_FRAGS + 1)
 #define TX_BD_NUM_MAX			4096
 #define RX_BD_NUM_MAX			4096
 
@@ -1389,7 +1390,8 @@ axienet_ethtools_set_ringparam(struct net_device *ndev,
 	if (ering->rx_pending > RX_BD_NUM_MAX ||
 	    ering->rx_mini_pending ||
 	    ering->rx_jumbo_pending ||
-	    ering->rx_pending > TX_BD_NUM_MAX)
+	    ering->tx_pending < TX_BD_NUM_MIN ||
+	    ering->tx_pending > TX_BD_NUM_MAX)
 		return -EINVAL;
 
 	if (netif_running(ndev))
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:55 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:55 -0600
Subject: [PATCH net v2 4/9] net: axienet: add missing memory barriers
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-5-robert.hancock@calian.com>

This driver was missing some required memory barriers:

Use dma_rmb to ensure we see all updates to the descriptor after we see
that an entry has been completed.

Use wmb and rmb to avoid stale descriptor status between the TX path and
TX complete IRQ path.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index f4ae035bed35..de8f85175a6c 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -632,6 +632,8 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		if (nr_bds == -1 && !(status & XAXIDMA_BD_STS_COMPLETE_MASK))
 			break;
 
+		/* Ensure we see complete descriptor update */
+		dma_rmb();
 		phys = desc_get_phys_addr(lp, cur_p);
 		dma_unmap_single(ndev->dev.parent, phys,
 				 (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
@@ -645,8 +647,10 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		cur_p->app1 = 0;
 		cur_p->app2 = 0;
 		cur_p->app4 = 0;
-		cur_p->status = 0;
 		cur_p->skb = NULL;
+		/* ensure our transmit path and device don't prematurely see status cleared */
+		wmb();
+		cur_p->status = 0;
 
 		if (sizep)
 			*sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
@@ -704,6 +708,9 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
 					    int num_frag)
 {
 	struct axidma_bd *cur_p;
+
+	/* Ensure we see all descriptor updates from device or TX IRQ path */
+	rmb();
 	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
 	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
 		return NETDEV_TX_BUSY;
@@ -843,6 +850,8 @@ static void axienet_recv(struct net_device *ndev)
 
 		tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
 
+		/* Ensure we see complete descriptor update */
+		dma_rmb();
 		phys = desc_get_phys_addr(lp, cur_p);
 		dma_unmap_single(ndev->dev.parent, phys, lp->max_frm_size,
 				 DMA_FROM_DEVICE);
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:58 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:58 -0600
Subject: [PATCH net v2 7/9] net: axienet: fix number of TX ring slots for
 available check
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-8-robert.hancock@calian.com>

The check for the number of available TX ring slots was off by 1 since a
slot is required for the skb header as well as each fragment. This could
result in overwriting a TX ring slot that was still in use.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index ee8d656200b8..c5d214abd4d5 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -747,7 +747,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	num_frag = skb_shinfo(skb)->nr_frags;
 	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
-	if (axienet_check_tx_bd_space(lp, num_frag)) {
+	if (axienet_check_tx_bd_space(lp, num_frag + 1)) {
 		if (netif_queue_stopped(ndev))
 			return NETDEV_TX_BUSY;
 
@@ -757,7 +757,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 		smp_mb();
 
 		/* Space might have just been freed - check again */
-		if (axienet_check_tx_bd_space(lp, num_frag))
+		if (axienet_check_tx_bd_space(lp, num_frag + 1))
 			return NETDEV_TX_BUSY;
 
 		netif_wake_queue(ndev);
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:57 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:57 -0600
Subject: [PATCH net v2 6/9] net: axienet: Fix TX ring slot available check
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-7-robert.hancock@calian.com>

The check for whether a TX ring slot was available was incorrect,
since a slot which had been loaded with transmit data but the device had
not started transmitting would be treated as available, potentially
causing non-transmitted slots to be overwritten. The control field in
the descriptor should be checked, rather than the status field (which may
only be updated when the device completes the entry).

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 8a60219d3bfb..ee8d656200b8 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -643,7 +643,6 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK))
 			dev_consume_skb_irq(cur_p->skb);
 
-		cur_p->cntrl = 0;
 		cur_p->app0 = 0;
 		cur_p->app1 = 0;
 		cur_p->app2 = 0;
@@ -651,6 +650,7 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		cur_p->skb = NULL;
 		/* ensure our transmit path and device don't prematurely see status cleared */
 		wmb();
+		cur_p->cntrl = 0;
 		cur_p->status = 0;
 
 		if (sizep)
@@ -713,7 +713,7 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
 	/* Ensure we see all descriptor updates from device or TX IRQ path */
 	rmb();
 	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
-	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
+	if (cur_p->cntrl)
 		return NETDEV_TX_BUSY;
 	return 0;
 }
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:36:59 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:36:59 -0600
Subject: [PATCH net v2 8/9] net: axienet: fix for TX busy handling
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-9-robert.hancock@calian.com>

Network driver documentation indicates we should be avoiding returning
NETDEV_TX_BUSY from ndo_start_xmit in normal cases, since it requires
the packets to be requeued. Instead the queue should be stopped after
a packet is added to the TX ring when there may not be enough room for an
additional one. Also, when TX ring entries are completed, we should only
wake the queue if we know there is room for another full maximally
fragmented packet.

Print a warning if there is insufficient space at the start of start_xmit,
since this should no longer happen.

Combined with increasing the default TX ring size (in a subsequent
patch), this appears to recover the TX performance lost by previous changes
to actually manage the TX ring state properly.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 86 ++++++++++---------
 1 file changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index c5d214abd4d5..8ac277ef1f99 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -660,6 +660,32 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 	return i;
 }
 
+/**
+ * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy
+ * @lp:		Pointer to the axienet_local structure
+ * @num_frag:	The number of BDs to check for
+ *
+ * Return: 0, on success
+ *	    NETDEV_TX_BUSY, if any of the descriptors are not free
+ *
+ * This function is invoked before BDs are allocated and transmission starts.
+ * This function returns 0 if a BD or group of BDs can be allocated for
+ * transmission. If the BD or any of the BDs are not free the function
+ * returns a busy status. This is invoked from axienet_start_xmit.
+ */
+static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+					    int num_frag)
+{
+	struct axidma_bd *cur_p;
+
+	/* Ensure we see all descriptor updates from device or TX IRQ path */
+	rmb();
+	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
+	if (cur_p->cntrl)
+		return NETDEV_TX_BUSY;
+	return 0;
+}
+
 /**
  * axienet_start_xmit_done - Invoked once a transmit is completed by the
  * Axi DMA Tx channel.
@@ -689,33 +715,8 @@ static void axienet_start_xmit_done(struct net_device *ndev)
 	/* Matches barrier in axienet_start_xmit */
 	smp_mb();
 
-	netif_wake_queue(ndev);
-}
-
-/**
- * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy
- * @lp:		Pointer to the axienet_local structure
- * @num_frag:	The number of BDs to check for
- *
- * Return: 0, on success
- *	    NETDEV_TX_BUSY, if any of the descriptors are not free
- *
- * This function is invoked before BDs are allocated and transmission starts.
- * This function returns 0 if a BD or group of BDs can be allocated for
- * transmission. If the BD or any of the BDs are not free the function
- * returns a busy status. This is invoked from axienet_start_xmit.
- */
-static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
-					    int num_frag)
-{
-	struct axidma_bd *cur_p;
-
-	/* Ensure we see all descriptor updates from device or TX IRQ path */
-	rmb();
-	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
-	if (cur_p->cntrl)
-		return NETDEV_TX_BUSY;
-	return 0;
+	if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
+		netif_wake_queue(ndev);
 }
 
 /**
@@ -748,19 +749,14 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
 	if (axienet_check_tx_bd_space(lp, num_frag + 1)) {
-		if (netif_queue_stopped(ndev))
-			return NETDEV_TX_BUSY;
-
+		/* Should not happen as last start_xmit call should have
+		 * checked for sufficient space and queue should only be
+		 * woken when sufficient space is available.
+		 */
 		netif_stop_queue(ndev);
-
-		/* Matches barrier in axienet_start_xmit_done */
-		smp_mb();
-
-		/* Space might have just been freed - check again */
-		if (axienet_check_tx_bd_space(lp, num_frag + 1))
-			return NETDEV_TX_BUSY;
-
-		netif_wake_queue(ndev);
+		if (net_ratelimit())
+			netdev_warn(ndev, "TX ring unexpectedly full\n");
+		return NETDEV_TX_BUSY;
 	}
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -821,6 +817,18 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	if (++lp->tx_bd_tail >= lp->tx_bd_num)
 		lp->tx_bd_tail = 0;
 
+	/* Stop queue if next transmit may not have space */
+	if (axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) {
+		netif_stop_queue(ndev);
+
+		/* Matches barrier in axienet_start_xmit_done */
+		smp_mb();
+
+		/* Space might have just been freed - check again */
+		if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
+			netif_wake_queue(ndev);
+	}
+
 	return NETDEV_TX_OK;
 }
 
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 12 09:37:00 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 11:37:00 -0600
Subject: [PATCH net v2 9/9] net: axienet: increase default TX ring size to 128
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <20220112173700.873002-10-robert.hancock@calian.com>

With previous changes to make the driver handle the TX ring size more
correctly, the default TX ring size of 64 appears to significantly
bottleneck TX performance to around 600 Mbps on a 1 Gbps link on ZynqMP.
Increasing this to 128 seems to bring performance up to near line rate and
shouldn't cause excess bufferbloat (this driver doesn't yet support modern
byte-based queue management).

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 8ac277ef1f99..d5ea093fbd32 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -41,7 +41,7 @@
 #include "xilinx_axienet.h"
 
 /* Descriptors defines for Tx and Rx DMA */
-#define TX_BD_NUM_DEFAULT		64
+#define TX_BD_NUM_DEFAULT		128
 #define RX_BD_NUM_DEFAULT		1024
 #define TX_BD_NUM_MIN			(MAX_SKB_FRAGS + 1)
 #define TX_BD_NUM_MAX			4096
-- 
2.31.1



From rananta at google.com  Wed Jan 12 10:02:01 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Wed, 12 Jan 2022 10:02:01 -0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <CAAeT=FwA9X9eXrF+Q31Wzah=UkM-B8bMJObjJ=oCV0rjLfX6=g@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
 <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>
 <CAJHc60ywYgAPfG11Ljkj3qzLoUn9mZPKnPH0P-HYS-pfs+A__g@mail.gmail.com>
 <CAAeT=FwA9X9eXrF+Q31Wzah=UkM-B8bMJObjJ=oCV0rjLfX6=g@mail.gmail.com>
Message-ID: <CAJHc60y6b-scY8zcPuLnjGtr6HzSBnmhi2mCnmkNm4nTxgMTUQ@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:12 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> On Mon, Jan 10, 2022 at 4:51 PM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > On Sun, Jan 9, 2022 at 10:29 PM Reiji Watanabe <reijiw at google.com> wrote:
> > >
> > > Hi Raghu,
> > >
> > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > <rananta at google.com> wrote:
> > > >
> > > > KVM regularly introduces new hypercall services to the guests without
> > > > any consent from the Virtual Machine Manager (VMM). This means, the
> > > > guests can observe hypercall services in and out as they migrate
> > > > across various host kernel versions. This could be a major problem
> > > > if the guest discovered a hypercall, started using it, and after
> > > > getting migrated to an older kernel realizes that it's no longer
> > > > available. Depending on how the guest handles the change, there's
> > > > a potential chance that the guest would just panic.
> > > >
> > > > As a result, there's a need for the VMM to elect the services that
> > > > it wishes the guest to discover. VMM can elect these services based
> > > > on the kernels spread across its (migration) fleet. To remedy this,
> > > > extend the existing firmware psuedo-registers, such as
> > > > KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.
> > > >
> > > > These firmware registers are categorized based on the service call
> > > > owners, and unlike the existing firmware psuedo-registers, they hold
> > > > the features supported in the form of a bitmap.
> > > >
> > > > The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
> > > > this extension, which returns the number of psuedo-firmware
> > > > registers supported. During the VM initialization, the registers
> > > > holds an upper-limit of the features supported by the corresponding
> > > > registers. It's expected that the VMMs discover the features
> > > > provided by each register via GET_ONE_REG, and writeback the
> > > > desired values using SET_ONE_REG. KVM allows this modification
> > > > only until the VM has started.
> > > >
> > > > Older VMMs can simply ignore the capability and the hypercall services
> > > > will be exposed unconditionally to the guests, thus ensuring backward
> > > > compatibility.
> > > >
> > > > In this patch, the framework adds the register only for ARM's standard
> > > > secure services (owner value 4). Currently, this includes support only
> > > > for ARM True Random Number Generator (TRNG) service, with bit-0 of the
> > > > register representing mandatory features of v1.0. Other services are
> > > > momentarily added in the upcoming patches.
> > > >
> > > > Signed-off-by: Raghavendra Rao Ananta <rananta at google.com>
> > > > ---
> > > >  arch/arm64/include/asm/kvm_host.h |  12 ++++
> > > >  arch/arm64/include/uapi/asm/kvm.h |   4 ++
> > > >  arch/arm64/kvm/arm.c              |   4 ++
> > > >  arch/arm64/kvm/hypercalls.c       | 103 +++++++++++++++++++++++++++++-
> > > >  arch/arm64/kvm/trng.c             |   8 +--
> > > >  include/kvm/arm_hypercalls.h      |   6 ++
> > > >  6 files changed, 129 insertions(+), 8 deletions(-)
> > > >
> > > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > > index 2a5f7f38006f..a32cded0371b 100644
> > > > --- a/arch/arm64/include/asm/kvm_host.h
> > > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > > @@ -102,6 +102,15 @@ struct kvm_s2_mmu {
> > > >  struct kvm_arch_memory_slot {
> > > >  };
> > > >
> > > > +/**
> > > > + * struct kvm_hvc_desc: KVM ARM64 hypercall descriptor
> > > > + *
> > > > + * @hvc_std_bmap: Bitmap of standard secure service calls
> > > > + */
> > > > +struct kvm_hvc_desc {
> > > > +       u64 hvc_std_bmap;
> > > > +};
> > > > +
> > > >  struct kvm_arch {
> > > >         struct kvm_s2_mmu mmu;
> > > >
> > > > @@ -137,6 +146,9 @@ struct kvm_arch {
> > > >
> > > >         /* Memory Tagging Extension enabled for the guest */
> > > >         bool mte_enabled;
> > > > +
> > > > +       /* Hypercall firmware register' descriptor */
> > > > +       struct kvm_hvc_desc hvc_desc;
> > > >  };
> > > >
> > > >  struct kvm_vcpu_fault_info {
> > > > diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> > > > index b3edde68bc3e..0d6f29c58456 100644
> > > > --- a/arch/arm64/include/uapi/asm/kvm.h
> > > > +++ b/arch/arm64/include/uapi/asm/kvm.h
> > > > @@ -281,6 +281,10 @@ struct kvm_arm_copy_mte_tags {
> > > >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED       3
> > > >  #define KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED            (1U << 4)
> > > >
> > > > +#define KVM_REG_ARM_STD_BMAP                   KVM_REG_ARM_FW_REG(3)
> > > > +#define KVM_REG_ARM_STD_BIT_TRNG_V1_0          BIT(0)
> > > > +#define KVM_REG_ARM_STD_BMAP_BIT_MAX           0       /* Last valid bit */
> > > > +
> > > >  /* SVE registers */
> > > >  #define KVM_REG_ARM64_SVE              (0x15 << KVM_REG_ARM_COPROC_SHIFT)
> > > >
> > > > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > > > index e4727dc771bf..56fe81565235 100644
> > > > --- a/arch/arm64/kvm/arm.c
> > > > +++ b/arch/arm64/kvm/arm.c
> > > > @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> > > >         kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
> > > >
> > > >         set_default_spectre(kvm);
> > > > +       kvm_arm_init_hypercalls(kvm);
> > > >
> > > >         return ret;
> > > >  out_free_stage2_pgd:
> > > > @@ -283,6 +284,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
> > > >         case KVM_CAP_ARM_PTRAUTH_GENERIC:
> > > >                 r = system_has_full_ptr_auth();
> > > >                 break;
> > > > +       case KVM_CAP_ARM_HVC_FW_REG_BMAP:
> > > > +               r = kvm_arm_num_fw_bmap_regs();
> > > > +               break;
> > >
> > > Looking at the discussion for the v2 series,
> > >
> > >  https://lore.kernel.org/kvmarm/20211130101958.fcdqthphyhxzvzla at gator.home/
> > >
> > > I assume that the number of the pseudo-firmware bitmap registers
> > > will be used to clear pseudo firmware bitmap registers that
> > > userspace doesn't know.
> > > I'm wondering how userspace can identify which pseudo-firmware
> > > registers that KVM_GET_REG_LIST provides are the pseudo-firmware
> > > bitmap registers that it doesn't know.
> > > For instance, suppose pseudo-firmware registers that KVM_GET_REG_LIST
> > > provides are KVM_REG_ARM_FW_REG(0) to KVM_REG_ARM_FW_REG(9), userspace
> > > doesn't knows KVM_REG_ARM_FW_REG(6) to KVM_REG_ARM_FW_REG(9), and
> > > KVM_CAP_ARM_HVC_FW_REG_BMAP returns 5, how can userspace identify
> > > remaining two bitmap registers from those 4 (fw-reg #6 to #9)
> > > firmware registers ?
> > >
> > In v3, we leave the decision upto the userspace. If the userspace
> > encounters a register that it's unaware, it can choose either to clear
> > it or let it get exposed to the guest as is (see the code snipped
> > shared by Andrew in the link).
> > Trying to understand the question better- are you asking how would
> > userspace distinguish between bitmap and regular fw registers with
> > intermixed sequence numbers?
>
> Yes, that's my question.
>
>
> > If yes, do you foresee a reason why they 'unaware' registers needed to
> > be treated differently?
>
> Since I'm not sure what the specification of 'unaware' (non-bitmap)
> registers will be, it would be safer for us to assume that they might
> need to be treated differently from the bitmap registers.
> Considering there is KVM_REG_ARM_PSCI_VERSION, which KVM doesn't allow
> userspace to set to 0, there might be similar registers that userspace
> cannot set to 0 in the future.
>
> BTW, If you assume that all those 'unaware' firmware registers are
> treated in the same way, I don't think userspace needs the number of
> those bitmap registers from KVM_CAP_ARM_HVC_FW_REG_BMAP (Instead,
> I would think it can handle the 'unaware' registers with a list of
> firmware registers from KVM_GET_REG_LIST).
>
You are right; mixing these registers would create an issue for the
VMM. Instead, we can probably have a subset of the KVM_REG_ARM_FW_REG
space dedicated for the bitmapped firmware registers, something like:

#define KVM_REG_ARM_FW_BMAP_BASE     KVM_REG_ARM_FW_REG(0xff00)  /*
Upper half of the fw reg space */
#define KVM_REG_ARM_FW_BMAP_REG(r)    (KVM_REG_ARM_FW_BMAP_BASE | (r))

#define KVM_REG_ARM_STD_BMAP              KVM_REG_ARM_FW_BMAP_REG(0)

With this, I think the VMM can easily detect a bitmap fw register.
Also, if it encounters an unknown bitmapped register it can handle it
separately if it likes.
The minor advantage of the CAP still returning the number of bitmapped
registers can be an inexpensive shortcut to VMM to get a general idea
of the number of registers.

> > >
> > > >         default:
> > > >                 r = 0;
> > > >         }
> > > > diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
> > > > index 3c2fcf31ad3d..06243e4670eb 100644
> > > > --- a/arch/arm64/kvm/hypercalls.c
> > > > +++ b/arch/arm64/kvm/hypercalls.c
> > > > @@ -58,6 +58,29 @@ static void kvm_ptp_get_time(struct kvm_vcpu *vcpu, u64 *val)
> > > >         val[3] = lower_32_bits(cycles);
> > > >  }
> > > >
> > > > +static bool kvm_arm_fw_reg_feat_enabled(u64 reg_bmap, u64 feat_bit)
> > > > +{
> > > > +       return reg_bmap & feat_bit;
> > > > +}
> > > > +
> > > > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id)
> > > > +{
> > > > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> > > > +
> > > > +       switch (func_id) {
> > > > +       case ARM_SMCCC_TRNG_VERSION:
> > > > +       case ARM_SMCCC_TRNG_FEATURES:
> > > > +       case ARM_SMCCC_TRNG_GET_UUID:
> > > > +       case ARM_SMCCC_TRNG_RND32:
> > > > +       case ARM_SMCCC_TRNG_RND64:
> > > > +               return kvm_arm_fw_reg_feat_enabled(hvc_desc->hvc_std_bmap,
> > > > +                                               KVM_REG_ARM_STD_BIT_TRNG_V1_0);
> > > > +       default:
> > > > +               /* By default, allow the services that aren't listed here */
> > > > +               return true;
> > > > +       }
> > > > +}
> > >
> > > kvm_hvc_call_supported() could return true even for @func_id that
> > > kvm_hvc_call_handler() returns -EINVAL for.  Is this behavior what
> > > you really want ?
> > Yes. My idea was to let kvm_hvc_call_supported() check for the
> > support, while kvm_hvc_call_handler() does the real processing of the
> > call.
> >
> > > If so, IMHO the function name might be a bit mis-leading.
> > > "kvm_hvc_call_disabled" (and flip the return value)
> > > might be closer to what it does(?).
> > >
> > Sorry, I'm unclear how flipping is helping. Wouldn't we return 'false'
> > if we don't have a case for the func_id, indicating it's NOT disabled,
> > but kvm_hvc_call_handler() can still return SMCCC_RET_NOT_SUPPORTED?
>
> Yes, that's fine, too.
> Since those services are disabled (because they are enabled by default),
> I just thought checking 'disabled' might be closer to what it does than
> checking 'enabled'.  But, 'enabled' is also fine.
>
> > >
> > > > +
> > > >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > > >  {
> > > >         u32 func_id = smccc_get_function(vcpu);
> > > > @@ -65,6 +88,9 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > > >         u32 feature;
> > > >         gpa_t gpa;
> > > >
> > > > +       if (!kvm_hvc_call_supported(vcpu, func_id))
> > > > +               goto out;
> > > > +
> > > >         switch (func_id) {
> > > >         case ARM_SMCCC_VERSION_FUNC_ID:
> > > >                 val[0] = ARM_SMCCC_VERSION_1_1;
> > > > @@ -143,6 +169,7 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu)
> > > >                 return kvm_psci_call(vcpu);
> > > >         }
> > > >
> > > > +out:
> > > >         smccc_set_retval(vcpu, val[0], val[1], val[2], val[3]);
> > > >         return 1;
> > > >  }
> > > > @@ -153,9 +180,25 @@ static const u64 kvm_arm_fw_reg_ids[] = {
> > > >         KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2,
> > > >  };
> > > >
> > > > +static const u64 kvm_arm_fw_reg_bmap_ids[] = {
> > > > +       KVM_REG_ARM_STD_BMAP,
> > > > +};
> > > > +
> > > > +void kvm_arm_init_hypercalls(struct kvm *kvm)
> > > > +{
> > > > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > > > +
> > > > +       hvc_desc->hvc_std_bmap = ARM_SMCCC_STD_FEATURES;
> > > > +}
> > > > +
> > > > +int kvm_arm_num_fw_bmap_regs(void)
> > > > +{
> > > > +       return ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids);
> > > > +}
> > > > +
> > > >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu)
> > > >  {
> > > > -       return ARRAY_SIZE(kvm_arm_fw_reg_ids);
> > > > +       return ARRAY_SIZE(kvm_arm_fw_reg_ids) + kvm_arm_num_fw_bmap_regs();
> > > >  }
> > > >
> > > >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> > > > @@ -167,6 +210,11 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> > > >                         return -EFAULT;
> > > >         }
> > > >
> > > > +       for (i = 0; i < ARRAY_SIZE(kvm_arm_fw_reg_bmap_ids); i++) {
> > > > +               if (put_user(kvm_arm_fw_reg_bmap_ids[i], uindices++))
> > > > +                       return -EFAULT;
> > > > +       }
> > > > +
> > > >         return 0;
> > > >  }
> > > >
> > > > @@ -211,9 +259,20 @@ static int get_kernel_wa_level(u64 regid)
> > > >         return -EINVAL;
> > > >  }
> > > >
> > > > +static void
> > > > +kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
> > > > +{
> > > > +       struct kvm *kvm = vcpu->kvm;
> > > > +
> > > > +       mutex_lock(&kvm->lock);
> > > > +       *val = fw_reg_bmap;
> > > > +       mutex_unlock(&kvm->lock);
> > >
> > > Why does it need to hold the lock ? (Wouldn't READ_ONCE be enough ?)
> > >
> > I don't have much experience with READ_ONCE at this point, but do you
> > think this read can be protected again the read/write in
> > kvm_arm_set_fw_reg_bmap()?
>
> If kvm_arm_set_fw_reg_bmap is changed to use WRITE_ONCE to
> update hvc_desc->hvc_*_bmap (kvm_arm_set_fw_reg_bmap still needs
> to get the lock to prevent other vCPUs from running KVM_RUN),
> I would think using READ_ONCE in kvm_arm_get_fw_reg_bmap() without
> getting the lock should work (will see either old or new value).
>
That makes sense. Thanks for the suggestion and all the reviews.

Regards,
Raghavendra

> Thanks,
> Reiji
>
>
> > >
> > > > +}
> > > > +
> > > >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > > >  {
> > > >         void __user *uaddr = (void __user *)(long)reg->addr;
> > > > +       struct kvm_hvc_desc *hvc_desc = &vcpu->kvm->arch.hvc_desc;
> > > >         u64 val;
> > > >
> > > >         switch (reg->id) {
> > > > @@ -224,6 +283,9 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > > >         case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2:
> > > >                 val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK;
> > > >                 break;
> > > > +       case KVM_REG_ARM_STD_BMAP:
> > > > +               kvm_arm_get_fw_reg_bmap(vcpu, hvc_desc->hvc_std_bmap, &val);
> > > > +               break;
> > > >         default:
> > > >                 return -ENOENT;
> > > >         }
> > > > @@ -234,6 +296,43 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > > >         return 0;
> > > >  }
> > > >
> > > > +static int kvm_arm_set_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 reg_id, u64 val)
> > > > +{
> > > > +       int ret = 0;
> > > > +       struct kvm *kvm = vcpu->kvm;
> > > > +       struct kvm_hvc_desc *hvc_desc = &kvm->arch.hvc_desc;
> > > > +       u64 *fw_reg_bmap, fw_reg_features;
> > > > +
> > > > +       switch (reg_id) {
> > > > +       case KVM_REG_ARM_STD_BMAP:
> > > > +               fw_reg_bmap = &hvc_desc->hvc_std_bmap;
> > > > +               fw_reg_features = ARM_SMCCC_STD_FEATURES;
> > > > +               break;
> > > > +       default:
> > > > +               return -ENOENT;
> > > > +       }
> > > > +
> > > > +       /* Check for unsupported bit */
> > > > +       if (val & ~fw_reg_features)
> > > > +               return -EINVAL;
> > > > +
> > > > +       mutex_lock(&kvm->lock);
> > > > +
> > > > +       /*
> > > > +        * If the VM (any vCPU) has already started running, return success
> > > > +        * if there's no change in the value. Else, return -EBUSY.
> > > > +        */
> > > > +       if (kvm_vm_has_started(kvm)) {
> > > > +               ret = *fw_reg_bmap != val ? -EBUSY : 0;
> > > > +               goto out;
> > > > +       }
> > > > +
> > > > +       *fw_reg_bmap = val;
> > > > +out:
> > > > +       mutex_unlock(&kvm->lock);
> > > > +       return ret;
> > > > +}
> > > > +
> > > >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > > >  {
> > > >         void __user *uaddr = (void __user *)(long)reg->addr;
> > > > @@ -310,6 +409,8 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
> > > >                         return -EINVAL;
> > > >
> > > >                 return 0;
> > > > +       case KVM_REG_ARM_STD_BMAP:
> > > > +               return kvm_arm_set_fw_reg_bmap(vcpu, reg->id, val);
> > > >         default:
> > > >                 return -ENOENT;
> > > >         }
> > > > diff --git a/arch/arm64/kvm/trng.c b/arch/arm64/kvm/trng.c
> > > > index 99bdd7103c9c..23f912514b06 100644
> > > > --- a/arch/arm64/kvm/trng.c
> > > > +++ b/arch/arm64/kvm/trng.c
> > > > @@ -60,14 +60,8 @@ int kvm_trng_call(struct kvm_vcpu *vcpu)
> > > >                 val = ARM_SMCCC_TRNG_VERSION_1_0;
> > > >                 break;
> > > >         case ARM_SMCCC_TRNG_FEATURES:
> > > > -               switch (smccc_get_arg1(vcpu)) {
> > > > -               case ARM_SMCCC_TRNG_VERSION:
> > > > -               case ARM_SMCCC_TRNG_FEATURES:
> > > > -               case ARM_SMCCC_TRNG_GET_UUID:
> > > > -               case ARM_SMCCC_TRNG_RND32:
> > > > -               case ARM_SMCCC_TRNG_RND64:
> > > > +               if (kvm_hvc_call_supported(vcpu, smccc_get_arg1(vcpu)))
> > > >                         val = TRNG_SUCCESS;
> > >
> > > kvm_hvc_call_supported() returns true for any values that are
> > > not explicitly listed in kvm_hvc_call_supported() (i.e. it returns
> > > true even for @func_id that are not any of ARM_SMCCC_TRNG_*).
> > > So, I don't think it can simply use the current kvm_hvc_call_supported.
> > >
> > You are right. Probably I should leave the case statements as is (or
> > think of some better way).
> >
> >
> > Thanks for the review and suggestions.
> >
> > Regards,
> > Raghavendra
> > > Thanks,
> > > Reiji
> > >
> > > > -               }
> > > >                 break;
> > > >         case ARM_SMCCC_TRNG_GET_UUID:
> > > >                 smccc_set_retval(vcpu, le32_to_cpu(u[0]), le32_to_cpu(u[1]),
> > > > diff --git a/include/kvm/arm_hypercalls.h b/include/kvm/arm_hypercalls.h
> > > > index 5d38628a8d04..8fe68d8d6d96 100644
> > > > --- a/include/kvm/arm_hypercalls.h
> > > > +++ b/include/kvm/arm_hypercalls.h
> > > > @@ -6,6 +6,9 @@
> > > >
> > > >  #include <asm/kvm_emulate.h>
> > > >
> > > > +#define ARM_SMCCC_STD_FEATURES \
> > > > +       GENMASK_ULL(KVM_REG_ARM_STD_BMAP_BIT_MAX, 0)
> > > > +
> > > >  int kvm_hvc_call_handler(struct kvm_vcpu *vcpu);
> > > >
> > > >  static inline u32 smccc_get_function(struct kvm_vcpu *vcpu)
> > > > @@ -42,9 +45,12 @@ static inline void smccc_set_retval(struct kvm_vcpu *vcpu,
> > > >
> > > >  struct kvm_one_reg;
> > > >
> > > > +void kvm_arm_init_hypercalls(struct kvm *kvm);
> > > > +int kvm_arm_num_fw_bmap_regs(void);
> > > >  int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu);
> > > >  int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices);
> > > >  int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> > > >  int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg);
> > > > +bool kvm_hvc_call_supported(struct kvm_vcpu *vcpu, u32 func_id);
> > > >
> > > >  #endif
> > > > --
> > > > 2.34.1.448.ga2b2bfdf31-goog
> > > >


From rppt at kernel.org  Wed Jan 12 10:05:41 2022
From: rppt at kernel.org (Mike Rapoport)
Date: Wed, 12 Jan 2022 20:05:41 +0200
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com>
 <Yd1cnquQFZoNE7FP@kernel.org>
 <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
Message-ID: <Yd8Yda7oadoB1E+w@kernel.org>

On Tue, Jan 11, 2022 at 08:44:41PM +0000, Frank van der Linden wrote:
> On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote:
> > > --- a/include/linux/memblock.h
> > > +++ b/include/linux/memblock.h
> > > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
> > >  phys_addr_t memblock_start_of_DRAM(void);
> > >  phys_addr_t memblock_end_of_DRAM(void);
> > >  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> > > +void memblock_enforce_usable_range(void);
> > >  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
> > >  void memblock_mem_limit_remove_map(phys_addr_t limit);
> > 
> > We already have 3 very similar interfaces that deal with memory capping.
> > Now you suggest to add fourth that will "generically" solve a single use
> > case of DT, EFI and kdump interaction on arm64.
> > 
> > Looks like a workaround for a fundamental issue of incompatibility between
> > DT and EFI wrt memory registration.
> 
> Yep, I figured this would be the main argument against this - arm64
> already added several other more-or-less special cased interfaces over
> time.
> 
> I'm more than happy to solve this in a different way.
> 
> What would you suggest:
> 
> 1) Try to merge the similar interfaces in to one.

This could be a nice cleanup regardless of how we handle
"linux,usable-memory-range".

> 2) Just deal with it at a lower (arm64) level?

Probably it will be the simplest solution in the short term.

> 3) Some other way?

I'm not expert enough on DT and EFI to see how they communicate the
linux,usable-memory-range property. 

One thought I have is since we already create a DT for kexec/kdump why
can't we add some data to EFI memory description similar to
linux,usable-memore-range?

Another thing is, if we could presume that DT and EFI are consistent in
their view what is the span of the physical memory, we could drop
memblock_remove(EVERYTHIING) and early_init_dt_add_memory_arch() from
efi_init::reserve_regions() and then the loop over EFI memory descriptors
will only take care of reserved and nomap regions.

> Thanks,
> 
> - Frank
> 

-- 
Sincerely yours,
Mike.


From rananta at google.com  Wed Jan 12 10:08:32 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Wed, 12 Jan 2022 10:08:32 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <Yd3UymPg++JW98/2@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
 <Yd3AGRtkBgWSmGf2@google.com>
 <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>
 <Yd3UymPg++JW98/2@google.com>
Message-ID: <CAJHc60yPmdyonJESHPHvXJR+ekugZev4XzsZc2YV2mnfBdy-bw@mail.gmail.com>

On Tue, Jan 11, 2022 at 11:04 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Tue, Jan 11, 2022, Raghavendra Rao Ananta wrote:
> > On Tue, Jan 11, 2022 at 9:36 AM Sean Christopherson <seanjc at google.com> wrote:
> > > In your proposed patch, KVM_RUN will take kvm->lock _every_ time.  That introduces
> > > unnecessary contention as it will serialize this bit of code if multiple vCPUs
> > > are attempting KVM_RUN.  By checking !vm_started, only the "first" KVM_RUN for a
> > > VM will acquire kvm->lock and thus avoid contention once the VM is up and running.
> > > There's still a possibility that multiple vCPUs will contend for kvm->lock on their
> > > first KVM_RUN, hence the quotes.  I called it "naive" because it's possible there's
> > > a more elegant solution depending on the use case, e.g. a lockless approach might
> > > work (or it might not).
> > >
> > But is it safe to read kvm->vm_started without grabbing the lock in
> > the first place?
>
> Don't know, but that's my point.  Without a consumer in generic KVM and due to
> my lack of arm64 knowledge, without a high-level description of how the flag will
> be used by arm64, it's really difficult to determine what's safe and what's not.
> For other architectures, it's an impossible question to answer because we don't
> know how the flag might be used.
>
> > use atomic_t maybe for this?
>
> No.  An atomic_t is generally useful only if there are multiple writers that can
> possibly write different values.  It's highly unlikely that simply switching to an
> atomic address the needs of arm64.
>
> > > > > > +                     kvm->vm_started = true;
> > > > > > +                     mutex_unlock(&kvm->lock);
> > > > >
> > > > > Lastly, why is this in generic KVM?
> > > > >
> > > > The v1 of the series originally had it in the arm specific code.
> > > > However, I was suggested to move it to the generic code since the book
> > > > keeping is not arch specific and could be helpful to others too [1].
> > >
> > > I'm definitely in favor of moving/adding thing to generic KVM when it makes sense,
> > > but I'm skeptical in this particular case.  The code _is_ arch specific in that
> > > arm64 apparently needs to acquire kvm->lock when checking if a vCPU has run, e.g.
> > > versus a hypothetical x86 use case that might be completely ok with a lockless
> > > implementation.  And it's not obvious that there's a plausible, safe use case
> > > outside of arm64, e.g. on x86, there is very, very little that is truly shared
> > > across the entire VM/system, most things are per-thread/core/package in some way,
> > > shape, or form.  In other words, I'm a wary of providing something like this for
> > > x86 because odds are good that any use will be functionally incorrect.
> > I've been going back and forth on this. I've seen a couple of
> > variables declared in the generic struct and used only in the arch
> > code. vcpu->valid_wakeup for instance, which is used only by s390
> > arch. Maybe I'm looking at it the wrong way as to what can and can't
> > go in the generic kvm code.
>
> Ya, valid_wakeup is an oddball, I don't know why it's in kvm_vcpu instead of
> arch code that's wrapped with e.g. kvm_arch_vcpu_valid_wakeup().
>
> That said, valid_wakeup is consumed by generic KVM, i.e. has well defined semantics
> for how it is used, so it's purely a "this code is rather odd" issue.  vm_started
> on the other hand is only produced by generic KVM, and so its required semantics are
> unclear.

Understood. I'll move it to arm64 and we can refactor it if there's a
need for any other arch(s).

Thanks,
Raghavendra


From linux at armlinux.org.uk  Wed Jan 12 10:08:17 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 12 Jan 2022 18:08:17 +0000
Subject: [PATCH v5 08/10] ARM: uaccess: add __{get,put}_kernel_nofault
In-Reply-To: <Yd8P37V/N9EkwmYq@wychelm>
References: <20210726141141.2839385-1-arnd@kernel.org>
 <20210726141141.2839385-9-arnd@kernel.org>
 <Yd8P37V/N9EkwmYq@wychelm>
Message-ID: <Yd8ZEbywqjXkAx9k@shell.armlinux.org.uk>

On Wed, Jan 12, 2022 at 05:29:03PM +0000, Daniel Thompson wrote:
> On Mon, Jul 26, 2021 at 04:11:39PM +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann <arnd at arndb.de>
> > 
> > These mimic the behavior of get_user and put_user, except
> > for domain switching, address limit checking and handling
> > of mismatched sizes, none of which are relevant here.
> > 
> > To work with pre-Armv6 kernels, this has to avoid TUSER()
> > inside of the new macros, the new approach passes the "t"
> > string along with the opcode, which is a bit uglier but
> > avoids duplicating more code.
> > 
> > As there is no __get_user_asm_dword(), I work around it
> > by copying 32 bit at a time, which is possible because
> > the output size is known.
> > 
> > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> 
> I've just been bisecting some regressions running the kgdbts tests on
> arm and this patch came up.

So the software PAN code is working :)

The kernel attempted to access an address that is in the userspace
domain (NULL pointer) and took an exception.

I suppose we should handle a domain fault more gracefully - what are
the required semantics if the kernel attempts a userspace access
using one of the _nofault() accessors?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From seanjc at google.com  Wed Jan 12 10:24:31 2022
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 12 Jan 2022 18:24:31 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60yPmdyonJESHPHvXJR+ekugZev4XzsZc2YV2mnfBdy-bw@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
 <Yd3AGRtkBgWSmGf2@google.com>
 <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>
 <Yd3UymPg++JW98/2@google.com>
 <CAJHc60yPmdyonJESHPHvXJR+ekugZev4XzsZc2YV2mnfBdy-bw@mail.gmail.com>
Message-ID: <Yd8c3zlTweSGhwtt@google.com>

On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> Understood. I'll move it to arm64 and we can refactor it if there's a
> need for any other arch(s).

Before you do that, can you answer Jim's question on _why_ arm64 needs this?


From rananta at google.com  Wed Jan 12 10:29:07 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Wed, 12 Jan 2022 10:29:07 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
Message-ID: <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>

On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
>
> On Tue, Jan 11, 2022 at 10:52 AM Raghavendra Rao Ananta
> <rananta at google.com> wrote:
> >
> > On Mon, Jan 10, 2022 at 3:57 PM Jim Mattson <jmattson at google.com> wrote:
> > >
> > > On Mon, Jan 10, 2022 at 3:07 PM Raghavendra Rao Ananta
> > > <rananta at google.com> wrote:
> > > >
> > > > On Fri, Jan 7, 2022 at 4:05 PM Jim Mattson <jmattson at google.com> wrote:
> > > > >
> > > > > On Fri, Jan 7, 2022 at 3:43 PM Raghavendra Rao Ananta
> > > > > <rananta at google.com> wrote:
> > > > > >
> > > > > > Hi Reiji,
> > > > > >
> > > > > > On Thu, Jan 6, 2022 at 10:07 PM Reiji Watanabe <reijiw at google.com> wrote:
> > > > > > >
> > > > > > > Hi Raghu,
> > > > > > >
> > > > > > > On Tue, Jan 4, 2022 at 11:49 AM Raghavendra Rao Ananta
> > > > > > > <rananta at google.com> wrote:
> > > > > > > >
> > > > > > > > Capture the start of the KVM VM, which is basically the
> > > > > > > > start of any vCPU run. This state of the VM is helpful
> > > > > > > > in the upcoming patches to prevent user-space from
> > > > > > > > configuring certain VM features after the VM has started
> > > > > > > > running.
> > > > >
> > > > > What about live migration, where the VM has already technically been
> > > > > started before the first call to KVM_RUN?
> > > >
> > > > My understanding is that a new 'struct kvm' is created on the target
> > > > machine and this flag should be reset, which would allow the VMM to
> > > > restore the firmware registers. However, we would be running KVM_RUN
> > > > for the first time on the target machine, thus setting the flag.
> > > > So, you are right; It's more of a resume operation from the guest's
> > > > point of view. I guess the name of the variable is what's confusing
> > > > here.
> > >
> > > I was actually thinking that live migration gives userspace an easy
> > > way to circumvent your restriction. You said, "This state of the VM is
> > > helpful in the upcoming patches to prevent user-space from configuring
> > > certain VM features after the VM has started running." However, if you
> > > don't ensure that these VM features are configured the same way on the
> > > target machine as they were on the source machine, you have not
> > > actually accomplished your stated goal.
> > >
> > Isn't that up to the VMM to save/restore and validate the registers
> > across migrations?
>
> Yes, just as it is up to userspace not to make bad configuration
> changes after the first VMRUN.
>
> > Perhaps I have to re-word my intentions for the patch- userspace
> > should be able to configure the registers before issuing the first
> > KVM_RUN.
>
> Perhaps it would help if you explained *why* you are doing this. It
> sounds like you are either trying to protect against a malicious
> userspace, or you are trying to keep userspace from doing something
> stupid. In general, kvm only enforces constraints that are necessary
> to protect the host. If that's what you're doing, I don't understand
> why live migration doesn't provide an end-run around your protections.
It's mainly to safeguard the guests. With respect to migration, KVM
and the userspace are collectively playing a role here. It's up to the
userspace to ensure that the registers are configured the same across
migrations and KVM ensures that the userspace doesn't modify the
registers after KVM_RUN so that they don't see features turned OFF/ON
during execution. I'm not sure if it falls into the definition of
protecting the host. Do you see a value in adding this extra
protection from KVM?

Regards,
Raghavendra


From seanjc at google.com  Wed Jan 12 10:31:35 2022
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 12 Jan 2022 18:31:35 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <Yd8c3zlTweSGhwtt@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <Ydjje8qBOP3zDOZi@google.com>
 <CAJHc60ziKv6P4ZmpLXrv+s4DrrDtOwuQRAc4bKcrbR3aNAK5mQ@mail.gmail.com>
 <Yd3AGRtkBgWSmGf2@google.com>
 <CAJHc60w7vfHkg+9XkPw+38nZBWLLhETJj310ekM1HpQQTL_O0Q@mail.gmail.com>
 <Yd3UymPg++JW98/2@google.com>
 <CAJHc60yPmdyonJESHPHvXJR+ekugZev4XzsZc2YV2mnfBdy-bw@mail.gmail.com>
 <Yd8c3zlTweSGhwtt@google.com>
Message-ID: <Yd8eh2dAjN49TlQH@google.com>

On Wed, Jan 12, 2022, Sean Christopherson wrote:
> On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> > Understood. I'll move it to arm64 and we can refactor it if there's a
> > need for any other arch(s).
> 
> Before you do that, can you answer Jim's question on _why_ arm64 needs this?

Gah, sorry, kvmarm at lists.cs.columbia.edu once again lost the spam battle with Gmail.


From laurent.pinchart at ideasonboard.com  Wed Jan 12 10:34:13 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 12 Jan 2022 20:34:13 +0200
Subject: [RFC PATCH 1/3] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <20220112172719.1178446-2-jeanmichel.hautbois@ideasonboard.com>
References: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
 <20220112172719.1178446-2-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <Yd8fJd2SASGkhOjm@pendragon.ideasonboard.com>

Hi Jean-Michel,

Thank you for the patch.

On Wed, Jan 12, 2022 at 06:27:18PM +0100, Jean-Michel Hautbois wrote:
> Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera
> interface. Also add a MAINTAINERS entry for it.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
> Dave: I assumed you were the maintainer for this file, as I based it on the
> bcm2835-unicam.txt file. Are  you happy to be added directly as the
> maintainer, or should this be specified as "Raspberry Pi Kernel
> Maintenance <kernel-list at raspberrypi.com>"
> ---
>  .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
>  MAINTAINERS                                   |   6 +
>  2 files changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> new file mode 100644
> index 000000000000..1427514142cf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> @@ -0,0 +1,103 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/brcm,bcm2835-unicam.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BCM283x Camera Interface (Unicam)
> +
> +maintainers:
> +  - Dave Stevenson <dave.stevenson at raspberrypi.com>
> +
> +description: |-
> +  The Unicam block on BCM283x SoCs is the receiver for either
> +  CSI-2 or CCP2 data from image sensors or similar devices.
> +
> +  The main platform using this SoC is the Raspberry Pi family of boards.
> +  On the Pi the VideoCore firmware can also control this hardware block,
> +  and driving it from two different processors will cause issues.
> +  To avoid this, the firmware checks the device tree configuration
> +  during boot. If it finds device tree nodes called csi0 or csi1 then
> +  it will stop the firmware accessing the block, and it can then
> +  safely be used via the device tree binding.
> +
> +properties:
> +  compatible:
> +    const: brcm,bcm2835-unicam
> +
> +  reg:
> +    description:
> +      physical base address and length of the register sets for the device.

You can drop the description, that's the default for the reg property.

> +    maxItems: 1
> +
> +  interrupts:
> +    description: the IRQ line for this Unicam instance.

Same here.

> +    maxItems: 1
> +
> +  clocks:
> +    description: |-
> +      list of clock specifiers, corresponding to entries in clock-names
> +      property.

Same here, but a description of each entry would be useful.

  clocks:
    items:
      - description: Clock for foo.
      - description: Clock for bar.

> +
> +  clock-names:
> +    items:
> +      - const: lp
> +      - const: vpu
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port

You need to use port-base and list the valid endpoint properties.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - port
> +
> +additionalProperties: False

s/False/false/

> +
> +examples:
> +  - |

Does this validate without #include'ing headers that define the
BCM2835_CLOCK_CAM1 macro ?

> +    csi1: csi1 at 7e801000 {

You can drop the label.

> +        compatible = "brcm,bcm2835-unicam";
> +        reg = <0x7e801000 0x800>,
> +              <0x7e802004 0x4>;

That's two items, while the bindings document one item only. Please run
the DT bindings validation, it will validate the examples.

> +        interrupts = <2 7>;

On RPi 4 don't we need 3 interrupt cells ?

> +        clocks = <&clocks BCM2835_CLOCK_CAM1>,
> +                 <&firmware_clocks 4>;
> +        clock-names = "lp", "vpu";

A blank line would be good here.

> +        port {
> +                csi1_ep: endpoint {

Inconsistent indentation. Same below.

> +                        remote-endpoint = <&tc358743_0>;
> +                        data-lanes = <1 2>;
> +                };
> +        };
> +    };
> +
> +    i2c0: i2c at 7e205000 {
> +        tc358743: csi-hdmi-bridge at 0f {

You can drop those two labels.

> +            compatible = "toshiba,tc358743";

This isn't documented upstream in yaml. How about using an imx219 sensor
instead ?

> +            reg = <0x0f>;
> +            clocks = <&tc358743_clk>;
> +            clock-names = "refclk";
> +
> +            tc358743_clk: bridge-clk {
> +                    compatible = "fixed-clock";
> +                    #clock-cells = <0>;
> +                    clock-frequency = <27000000>;
> +            };

You can drop this, there's no need to declare the clock in the example.

> +
> +            port {
> +                    tc358743_0: endpoint {
> +                            remote-endpoint = <&csi1_ep>;
> +                            clock-lanes = <0>;
> +                            data-lanes = <1 2>;
> +                            clock-noncontinuous;
> +                            link-frequencies =
> +                                /bits/ 64 <297000000>;
> +                    };
> +            };
> +        };
> +    };
> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 269aa4d6b94a..7484255cad31 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3653,6 +3653,12 @@ N:	bcm113*
>  N:	bcm216*
>  N:	kona
>  
> +BROADCOM BCM2835 CAMERA DRIVER
> +M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
> +L:	linux-media at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> +
>  BROADCOM BCM47XX MIPS ARCHITECTURE
>  M:	Hauke Mehrtens <hauke at hauke-m.de>
>  M:	Rafa? Mi?ecki <zajec5 at gmail.com>

-- 
Regards,

Laurent Pinchart


From lkp at intel.com  Wed Jan 12 10:21:52 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 02:21:52 +0800
Subject: [xilinx-xlnx:master 316/326] drivers/usb/misc/usb2244.c:30:62:
 warning: format '%d' expects argument of type 'int', but argument 4 has type
 'long int'
Message-ID: <202201130250.ZQDPqjLv-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 86b8431235c705e722728c75c641b002bf527c13 [316/326] usb: misc: usb2244: add support for USB2 ultra fast sd controller
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20220113/202201130250.ZQDPqjLv-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/86b8431235c705e722728c75c641b002bf527c13
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 86b8431235c705e722728c75c641b002bf527c13
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash drivers/usb/misc/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/usb/misc/usb2244.c: In function 'usb2244_init_hw':
>> drivers/usb/misc/usb2244.c:30:62: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long int' [-Wformat=]
      30 |                               "Failed to request reset GPIO %d, errcode",
         |                                                             ~^
         |                                                              |
         |                                                              int
         |                                                             %ld
      31 |                               PTR_ERR(data->reset_gpio));
         |                               ~~~~~~~~~~~~~~~~~~~~~~~~~       
         |                               |
         |                               long int

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for DRM_PANEL_SIMPLE
   Depends on HAS_IOMEM && DRM && DRM_PANEL && OF && BACKLIGHT_CLASS_DEVICE && PM
   Selected by
   - DRM_XLNX_DSI && HAS_IOMEM && DRM_XLNX


vim +30 drivers/usb/misc/usb2244.c

    20	
    21	static int usb2244_init_hw(struct device *dev, struct usb2244 *data)
    22	{
    23		data = devm_kzalloc(dev, sizeof(struct usb2244), GFP_KERNEL);
    24		if (!data)
    25			return -ENOMEM;
    26	
    27		data->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
    28		if (IS_ERR(data->reset_gpio)) {
    29			dev_err_probe(dev, PTR_ERR(data->reset_gpio),
  > 30				      "Failed to request reset GPIO %d, errcode",
    31				      PTR_ERR(data->reset_gpio));
    32			return PTR_ERR(data->reset_gpio);
    33		}
    34	
    35		/* Toggle RESET_N to reset the hub. */
    36		gpiod_set_value_cansleep(data->reset_gpio, 0);
    37		usleep_range(5, 10);
    38		gpiod_set_value_cansleep(data->reset_gpio, 1);
    39		msleep(5);
    40	
    41		return 0;
    42	}
    43	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mathieu.poirier at linaro.org  Wed Jan 12 10:43:20 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 12 Jan 2022 11:43:20 -0700
Subject: [PATCH v2 6/6] Documentation: coresight: docs for config load
 via configfs
In-Reply-To: <20220112172249.GA892261@p14s>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-7-mike.leach@linaro.org>
 <20220112172249.GA892261@p14s>
Message-ID: <20220112184320.GB892261@p14s>

[...]


> > +
> > +CONFIG_ELEM element
> > +~~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_header]                // header length value to end of feature strings.
> > +   [cscfg_file_elem_str]                   // name of the configuration.
> > +   [cscfg_file_elem_str]                   // description of configuration.
> > +   [u16 value](nr_presets)                 // number of defined presets.
> > +   [u32 value](nr_total_params)            // total parameters defined by all used features.
> > +   [u16 value](nr_feat_refs)               // number of features referenced by the configuration
> > +   [u64 values] * (nr_presets * nr_total_params)     // the preset values.
> > +   [cscfg_file_elem_str] * (nr_feat_refs)  // the features used in the configurations.
> 
> There seems to be a discrepency between the above format and the afdo3 structure
> definition in sample file coresight-cfg-filegen.c. 
> 

Void that comment - the above and the struct cscfg_config_desc don't have a 1:1
mapping.

> More comments to come...
> 
> Thanks,
> Mathieu
> 
> > +
> > +FEATURE_ELEM element
> > +~~~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_header]                // header length is total bytes to end of param structures.
> > +   [cscfg_file_elem_str]                   // feature name.
> > +   [cscfg_file_elem_str]                   // feature description.
> > +   [u32 value](match_flags)                // flags to associate the feature with a device.
> > +   [u16 value](nr_regs)                    // number of registers.
> > +   [u16 value](nr_params)                  // number of parameters.
> > +   [cscfg_regval_desc struct] * (nr_regs)  // register definitions
> > +   [PARAM_ELEM] * (nr_params)              // parameters definitions
> > +
> > +PARAM_ELEM element
> > +~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_str]         // parameter name.
> > +   [u64 value](param_value]      // initial value.
> > +
> > +Additional definitions.
> > +~~~~~~~~~~~~~~~~~~~~~~~
> > +
> > +The following structures are defined in **coresight-config-file.h**
> > +
> > + * **struct cscfg_file_header** : This structure contains an initial magic number, the total
> > +   length of the file, and the number of features in the file.
> > + * **struct cscfg_file_elem_header**: This defines the total length and type of a CONFIG_ELEM
> > +   or a FEATURE_ELEM.
> > + * **struct cscfg_file_elem_str**: This defines a string and its length.
> > +
> > +The magic number in cscfg_file_header is defined as two bitfields::
> > +
> > +   [31:8] Fixed magic number to identify file type.
> > +   [7:0]  Current file format version.
> > +
> > +The following defines determine the maximum overall file size and maximum individual
> > +string size::
> > +
> > +   CSCFG_FILE_MAXSIZE       // maximum overall file size.
> > +   CSCFG_FILE_STR_MAXSIZE   // maximum individual string size.
> > -- 
> > 2.17.1
> > 


From andrew at lunn.ch  Wed Jan 12 11:11:18 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 12 Jan 2022 20:11:18 +0100
Subject: [PATCH net v2 1/9] net: axienet: increase reset timeout
In-Reply-To: <20220112173700.873002-2-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-2-robert.hancock@calian.com>
Message-ID: <Yd8n1vjj7G0xga5U@lunn.ch>

On Wed, Jan 12, 2022 at 11:36:52AM -0600, Robert Hancock wrote:
> The previous timeout of 1ms was too short to handle some cases where the
> core is reset just after the input clocks were started, which will
> be introduced in an upcoming patch. Increase the timeout to 50ms. Also
> simplify the reset timeout checking to use read_poll_timeout.
> 
> Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From mirela.rabulea at oss.nxp.com  Wed Jan 12 11:12:08 2022
From: mirela.rabulea at oss.nxp.com (Mirela Rabulea)
Date: Wed, 12 Jan 2022 21:12:08 +0200
Subject: [PATCH v2] media: imx-jpeg: Prevent decoding NV12M jpegs into
 single-planar buffers
Message-ID: <20220112191208.823698-1-mirela.rabulea@oss.nxp.com>

If the application queues an NV12M jpeg as output buffer, but then
queues a single planar capture buffer, the kernel will crash with
"Unable to handle kernel NULL pointer dereference" in mxc_jpeg_addrs,
prevent this by finishing the job with error.

Signed-off-by: Mirela Rabulea <mirela.rabulea at oss.nxp.com>
---
Changed in v2:
  Simplified and generalized the condition check for mismatching number of planes (feedback from Ming)
  Updated error message

 drivers/media/platform/imx-jpeg/mxc-jpeg.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/platform/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
index 4ca96cf9def7..b249c1bbfac8 100644
--- a/drivers/media/platform/imx-jpeg/mxc-jpeg.c
+++ b/drivers/media/platform/imx-jpeg/mxc-jpeg.c
@@ -947,6 +947,12 @@ static void mxc_jpeg_device_run(void *priv)
 	v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, true);
 
 	jpeg_src_buf = vb2_to_mxc_buf(&src_buf->vb2_buf);
+	if (q_data_cap->fmt->colplanes != dst_buf->vb2_buf.num_planes) {
+		dev_err(dev, "Capture format %s has %d planes, but capture buffer has %d planes\n",
+			q_data_cap->fmt->name, q_data_cap->fmt->colplanes,
+			dst_buf->vb2_buf.num_planes);
+		jpeg_src_buf->jpeg_parse_error = true;
+	}
 	if (jpeg_src_buf->jpeg_parse_error) {
 		jpeg->slot_data[ctx->slot].used = false;
 		v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
-- 
2.25.1



From lkp at intel.com  Wed Jan 12 11:13:38 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 03:13:38 +0800
Subject: [xilinx-xlnx:master 324/326] drivers/usb/misc/usb5744.c:35:62:
 warning: format '%d' expects argument of type 'int', but argument 4 has type
 'long int'
Message-ID: <202201130345.WgSNJfhS-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 6ca1f4cd372fb97452dda4dfe6e79e285d604776 [324/326] usb: misc: usb5744: fix error handling for reset-gpio
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20220113/202201130345.WgSNJfhS-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/6ca1f4cd372fb97452dda4dfe6e79e285d604776
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 6ca1f4cd372fb97452dda4dfe6e79e285d604776
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash drivers/usb/misc/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/usb/misc/usb5744.c: In function 'usb5744_init_hw':
>> drivers/usb/misc/usb5744.c:35:62: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long int' [-Wformat=]
      35 |                               "Failed to request reset GPIO %d, errcode",
         |                                                             ~^
         |                                                              |
         |                                                              int
         |                                                             %ld
      36 |                               PTR_ERR(data->reset_gpio));
         |                               ~~~~~~~~~~~~~~~~~~~~~~~~~       
         |                               |
         |                               long int

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for DRM_PANEL_SIMPLE
   Depends on HAS_IOMEM && DRM && DRM_PANEL && OF && BACKLIGHT_CLASS_DEVICE && PM
   Selected by
   - DRM_XLNX_DSI && HAS_IOMEM && DRM_XLNX


vim +35 drivers/usb/misc/usb5744.c

    25	
    26	static int usb5744_init_hw(struct device *dev, struct usb5744 *data)
    27	{
    28		data = devm_kzalloc(dev, sizeof(struct usb5744), GFP_KERNEL);
    29		if (!data)
    30			return -ENOMEM;
    31	
    32		data->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
    33		if (IS_ERR(data->reset_gpio)) {
    34			dev_err_probe(dev, PTR_ERR(data->reset_gpio),
  > 35				      "Failed to request reset GPIO %d, errcode",
    36				      PTR_ERR(data->reset_gpio));
    37			return PTR_ERR(data->reset_gpio);
    38		}
    39	
    40		if (data->reset_gpio) {
    41			/* Toggle RESET_N to reset the hub. */
    42			if (dev_is_platform(dev))
    43				gpiod_set_value(data->reset_gpio, 0);
    44			else
    45				gpiod_set_value_cansleep(data->reset_gpio, 0);
    46	
    47			/* Delay - Sleep for an approximate time 5 to 20 usecs */
    48			usleep_range(5, 20);
    49	
    50			if (dev_is_platform(dev))
    51				gpiod_set_value(data->reset_gpio, 1);
    52			else
    53				gpiod_set_value_cansleep(data->reset_gpio, 1);
    54	
    55			msleep(5);
    56		}
    57	
    58		return 0;
    59	}
    60	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andrew at lunn.ch  Wed Jan 12 11:15:52 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 12 Jan 2022 20:15:52 +0100
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
 reset
In-Reply-To: <20220112173700.873002-3-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-3-robert.hancock@calian.com>
Message-ID: <Yd8o6P6Pp7V7S+oL@lunn.ch>

On Wed, Jan 12, 2022 at 11:36:53AM -0600, Robert Hancock wrote:
> When resetting the device, wait for the PhyRstCmplt bit to be set
> in the interrupt status register before continuing initialization, to
> ensure that the core is actually ready. The MgtRdy bit could also be
> waited for, but unfortunately when using 7-series devices, the bit does
> not appear to work as documented (it seems to behave as some sort of
> link state indication and not just an indication the transceiver is
> ready) so it can't really be relied on.
> 
> Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index f950342f6467..f425a8404a9b 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local *lp)
>  		return ret;
>  	}
>  
> +	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has finished */
> +	ret = read_poll_timeout(axienet_ior, value,
> +				value & XAE_INT_PHYRSTCMPLT_MASK,
> +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> +				XAE_IS_OFFSET);
> +	if (ret) {
> +		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n", __func__);
> +		return ret;
> +	}
> +

Is this bit guaranteed to be clear before you start waiting for it?

   Andrew


From andrew at lunn.ch  Wed Jan 12 11:21:35 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 12 Jan 2022 20:21:35 +0100
Subject: [PATCH net v2 3/9] net: axienet: reset core on initialization
 prior to MDIO access
In-Reply-To: <20220112173700.873002-4-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-4-robert.hancock@calian.com>
Message-ID: <Yd8qP+guqHYQJVaO@lunn.ch>

On Wed, Jan 12, 2022 at 11:36:54AM -0600, Robert Hancock wrote:
> In some cases where the Xilinx Ethernet core was used in 1000Base-X or
> SGMII modes, which use the internal PCS/PMA PHY, and the MGT
> transceiver clock source for the PCS was not running at the time the
> FPGA logic was loaded, the core would come up in a state where the
> PCS could not be found on the MDIO bus. To fix this, the Ethernet core
> (including the PCS) should be reset after enabling the clocks, prior to
> attempting to access the PCS using of_mdio_find_device.
> 
> Fixes: 1a02556086fc (net: axienet: Properly handle PCS/PMA PHY for 1000BaseX mode)
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From cujomalainey at google.com  Wed Jan 12 11:25:42 2022
From: cujomalainey at google.com (Curtis Malainey)
Date: Wed, 12 Jan 2022 11:25:42 -0800
Subject: [PATCH v2 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220112113247.29135-2-allen-kh.cheng@mediatek.com>
References: <20220112113247.29135-1-allen-kh.cheng@mediatek.com>
 <20220112113247.29135-2-allen-kh.cheng@mediatek.com>
Message-ID: <CAOReqxga6hLXs4P2hD1k_X01AWesQBae5AhJTLtiK_3Ndex_Sw@mail.gmail.com>

On Wed, Jan 12, 2022 at 3:43 AM allen-kh.cheng
<allen-kh.cheng at mediatek.com> wrote:
>
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
>
> Some of mediatek processors contain
> the Tensilica HiFix DSP for audio processing.
>
> The communication between Host CPU and DSP firmware is
> taking place using a shared memory area for message passing.
>
> ADSP IPC protocol offers (send/recv) interfaces using
> mediatek-mailbox APIs.
>
> We use two mbox channels to implement a request-reply protocol.
>
> Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>


From robert.hancock at calian.com  Wed Jan 12 11:25:58 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 12 Jan 2022 19:25:58 +0000
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
 reset
In-Reply-To: <Yd8o6P6Pp7V7S+oL@lunn.ch>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-3-robert.hancock@calian.com>
 <Yd8o6P6Pp7V7S+oL@lunn.ch>
Message-ID: <d0b00b8c96be17e6ad636f5a74ebfb170a603eac.camel@calian.com>

On Wed, 2022-01-12 at 20:15 +0100, Andrew Lunn wrote:
> On Wed, Jan 12, 2022 at 11:36:53AM -0600, Robert Hancock wrote:
> > When resetting the device, wait for the PhyRstCmplt bit to be set
> > in the interrupt status register before continuing initialization, to
> > ensure that the core is actually ready. The MgtRdy bit could also be
> > waited for, but unfortunately when using 7-series devices, the bit does
> > not appear to work as documented (it seems to behave as some sort of
> > link state indication and not just an indication the transceiver is
> > ready) so it can't really be relied on.
> > 
> > Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI
> > Ethernet driver")
> > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > ---
> >  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > index f950342f6467..f425a8404a9b 100644
> > --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > @@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local
> > *lp)
> >  		return ret;
> >  	}
> >  
> > +	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has
> > finished */
> > +	ret = read_poll_timeout(axienet_ior, value,
> > +				value & XAE_INT_PHYRSTCMPLT_MASK,
> > +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> > +				XAE_IS_OFFSET);
> > +	if (ret) {
> > +		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n",
> > __func__);
> > +		return ret;
> > +	}
> > +
> 
> Is this bit guaranteed to be clear before you start waiting for it?

The documentation for the IP core ( 
https://www.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/axi_ethernet/v7_2/pg138-axi-ethernet.pdf
 ) states for the phy_rst_n output signal: "This active-Low reset is held
active for 10 ms after power is applied and during any reset. After the reset
goes inactive, the PHY cannot be accessed for an additional 5 ms." The
PhyRstComplt bit definition mentions "This signal does not transition to 1 for
5 ms after PHY_RST_N transitions to 1". Given that a reset of the core has just
been completed above, the PHY reset should at least have been initiated as
well, so it should be sufficient to just wait for the bit to become 1 at this
point.

> 
>    Andrew

From msys.mizuma at gmail.com  Wed Jan 12 11:31:08 2022
From: msys.mizuma at gmail.com (Masayoshi Mizuma)
Date: Wed, 12 Jan 2022 14:31:08 -0500
Subject: [PATCH v7 0/7] arm64: Add framework to turn an IPI as NMI
In-Reply-To: <CAFA6WYN-wpQ86ik5FeAhimCcCoRAs9_g3BGL8CiSUmHxfeCSbg@mail.gmail.com>
References: <1604317487-14543-1-git-send-email-sumit.garg@linaro.org>
 <CAGb2v66mVoWiCibjq25d3Z8OvbWNO9p+vMo761RJLiD-BqVbqw@mail.gmail.com>
 <CAFA6WYN-wpQ86ik5FeAhimCcCoRAs9_g3BGL8CiSUmHxfeCSbg@mail.gmail.com>
Message-ID: <Yd8sfP0IXN4KiLuP@gabell>

On Wed, Jul 07, 2021 at 11:29:29AM +0530, Sumit Garg wrote:
> On Fri, 25 Jun 2021 at 20:26, Chen-Yu Tsai <wens at kernel.org> wrote:
> >
> > On Mon, Nov 2, 2020 at 7:46 PM Sumit Garg <sumit.garg at linaro.org> wrote:
> > >
> > > With pseudo NMIs support available its possible to configure SGIs to be
> > > triggered as pseudo NMIs running in NMI context. And kernel features
> > > such as:
> > > - NMI backtrace can leverage IPI turned as NMI to get a backtrace of CPU
> > >   stuck in hard lockup using magic SYSRQ.
> > > - kgdb relies on NMI support to round up CPUs which are stuck in hard
> > >   lockup state with interrupts disabled.
> > >
> > > This patch-set adds framework to turn an IPI as NMI which can be triggered
> > > as a pseudo NMI which in turn invokes registered NMI handlers.
> > >
> > > After this patch-set we should be able to get a backtrace for a CPU
> > > stuck in HARDLOCKUP. Have a look at an examples below from a hard lockup
> > > testcase run on Developerbox:
> > >
> > > $ echo HARDLOCKUP > /sys/kernel/debug/provoke-crash/DIRECT
> > >
> > > NMI backtrace:
> > > ==============
> > >
> > > # Issue Magic SysRq to dump backtrace
> > >
> > > [  376.894502] NMI backtrace for cpu 8
> > > [  376.894506] CPU: 8 PID: 555 Comm: bash Not tainted 5.9.0-rc3-00740-g06ff047-dirty #242
> > > [  376.894510] Hardware name: Socionext SynQuacer E-series DeveloperBox, BIOS build #73 Apr  6 2020
> > > [  376.894514] pstate: 40000005 (nZcv daif -PAN -UAO BTYPE=--)
> > > [  376.894517] pc : lkdtm_HARDLOCKUP+0x8/0x18
> > > [  376.894520] lr : lkdtm_do_action+0x24/0x30
> > > [  376.894524] sp : ffff800012cebd20
> > > [  376.894527] pmr_save: 00000060
> > > [  376.894530] x29: ffff800012cebd20 x28: ffff000875ae8000
> > > [  376.894540] x27: 0000000000000000 x26: 0000000000000000
> > > [  376.894550] x25: 000000000000001a x24: ffff800012cebe40
> > > [  376.894560] x23: 000000000000000b x22: ffff800010fc5040
> > > [  376.894569] x21: ffff000878b61000 x20: ffff8000113b2870
> > > [  376.894579] x19: 000000000000001b x18: 0000000000000010
> > > [  376.894588] x17: 0000000000000000 x16: 0000000000000000
> > > [  376.894598] x15: ffff000875ae8470 x14: 00000000000002ad
> > > [  376.894613] x13: 0000000000000000 x12: 0000000000000000
> > > [  376.894622] x11: 0000000000000007 x10: 00000000000009c0
> > > [  376.894631] x9 : ffff800012ceba80 x8 : ffff000875ae8a20
> > > [  376.894641] x7 : ffff00087f6b3280 x6 : ffff00087f6b3200
> > > [  376.894651] x5 : 0000000000000000 x4 : ffff00087f6a91f8
> > > [  376.894660] x3 : ffff00087f6b0120 x2 : 1aa310cec69eb500
> > > [  376.894670] x1 : 0000000000000000 x0 : 0000000000000060
> > > [  376.894679] Call trace:
> > > [  376.894683]  lkdtm_HARDLOCKUP+0x8/0x18
> > > [  376.894686]  direct_entry+0x124/0x1c0
> > > [  376.894689]  full_proxy_write+0x60/0xb0
> > > [  376.894693]  vfs_write+0xf0/0x230
> > > [  376.894696]  ksys_write+0x6c/0xf8
> > > [  376.894699]  __arm64_sys_write+0x1c/0x28
> > > [  376.894703]  el0_svc_common.constprop.0+0x74/0x1f0
> > > [  376.894707]  do_el0_svc+0x24/0x90
> > > [  376.894710]  el0_sync_handler+0x180/0x2f8
> > > [  376.894713]  el0_sync+0x158/0x180
> > >
> > > KGDB:
> > > =====
> > >
> > > # Enter kdb via Magic SysRq
> > >
> > > [6]kdb> btc
> > > btc: cpu status: Currently on cpu 6
> > > Available cpus: 0-5(I), 6, 7(I), 8, 9-23(I)
> > > <snip>
> > > Stack traceback for pid 555
> > > 0xffff000875ae8000      555      554  1    8   R  0xffff000875ae89c0  bash
> > > CPU: 8 PID: 555 Comm: bash Not tainted 5.9.0-rc3-00740-g06ff047-dirty #242
> > > Hardware name: Socionext SynQuacer E-series DeveloperBox, BIOS build #73 Apr  6 2020
> > > Call trace:
> > >  dump_backtrace+0x0/0x1a0
> > >  show_stack+0x18/0x28
> > >  dump_stack+0xc0/0x11c
> > >  kgdb_cpu_enter+0x648/0x660
> > >  kgdb_nmicallback+0xa0/0xa8
> > >  ipi_kgdb_nmicallback+0x24/0x30
> > >  ipi_nmi_handler+0x48/0x60
> > >  handle_percpu_devid_fasteoi_ipi+0x74/0x88
> > >  generic_handle_irq+0x30/0x48
> > >  handle_domain_nmi+0x48/0x80
> > >  gic_handle_irq+0x18c/0x34c
> > >  el1_irq+0xcc/0x180
> > >  lkdtm_HARDLOCKUP+0x8/0x18
> > >  direct_entry+0x124/0x1c0
> > >  full_proxy_write+0x60/0xb0
> > >  vfs_write+0xf0/0x230
> > >  ksys_write+0x6c/0xf8
> > >  __arm64_sys_write+0x1c/0x28
> > >  el0_svc_common.constprop.0+0x74/0x1f0
> > >  do_el0_svc+0x24/0x90
> > >  el0_sync_handler+0x180/0x2f8
> > >  el0_sync+0x158/0x180
> > > <snip>
> > >
> > > Changes in v7:
> > > - Add a new library function: kgdb_smp_call_nmi_hook() to expose fallback
> > >   mechanism to arch specific code.
> > > - Addressed other misc comments from Daniel.
> > >
> > > Changes in v6:
> > > - Two new patches: #4 and #6 which adds runtime fallback framework for
> > >   sysrq backtrace and kgdb roundup features.
> > > - Reversed order of NMI backtrace and kgdb roundup feaure patches.
> > > - Addressed other misc. comments from Marc.
> > > - I haven't picked any tags from v5 since I think there is major rework
> > >   involved. Masayoshi, could you please confirm if these features still
> > >   work for you?
> > >
> > > Changes in v5:
> > > - Rebased to head of upstream master.
> > > - Remove redundant invocation of ipi_nmi_setup().
> > > - Addressed misc. comments.
> > >
> > > Changes in v4:
> > > - Move IPI NMI framework to a separate file.
> > > - Get rid of hard-coded IPI_CALL_NMI_FUNC allocation.
> > > - Add NMI backtrace support leveraged via magic SYSRQ.
> > >
> > > Changes in v3:
> > > - Rebased to Marc's latest IPIs patch-set [1].
> > >
> > > [1] https://lkml.org/lkml/2020/9/1/603
> > >
> > > Changes since RFC version [1]:
> > > - Switch to use generic interrupt framework to turn an IPI as NMI.
> > > - Dependent on Marc's patch-set [2] which turns IPIs into normal
> > >   interrupts.
> > > - Addressed misc. comments from Doug on patch #4.
> > > - Posted kgdb NMI printk() fixup separately which has evolved since
> > >   to be solved using different approach via changing kgdb interception
> > >   of printk() in common printk() code (see patch [3]).
> > >
> > > [1] https://lkml.org/lkml/2020/4/24/328
> > > [2] https://lkml.org/lkml/2020/5/19/710
> > > [3] https://lkml.org/lkml/2020/5/20/418
> > >
> > > Sumit Garg (7):
> > >   arm64: Add framework to turn IPI as NMI
> > >   irqchip/gic-v3: Enable support for SGIs to act as NMIs
> > >   arm64: smp: Assign and setup an IPI as NMI
> > >   nmi: backtrace: Allow runtime arch specific override
> > >   arm64: ipi_nmi: Add support for NMI backtrace
> > >   kgdb: Expose default CPUs roundup fallback mechanism
> > >   arm64: kgdb: Roundup cpus using IPI as NMI
> >
> > Tested-by: Chen-Yu Tsai <wens at csie.org>
> >
> > on an ROC-RK3399-PC.
> 
> Thanks for testing this feature.
> 
> -Sumit

Hello Sumit,

How is this patch series going?

- Masa


From tharvey at gateworks.com  Wed Jan 12 11:42:24 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Wed, 12 Jan 2022 11:42:24 -0800
Subject: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt overlays for
 serial modes
In-Reply-To: <20220111102609.1f52b923@ipc1.ka-ro>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <CAJ+vNU0U7HknAZcnua39r9to+kJBea6Fg3NiJ9ybZ1xygKoF4g@mail.gmail.com>
 <20220111102609.1f52b923@ipc1.ka-ro>
Message-ID: <CAJ+vNU2Nmc_buYP_7BE6N4rp8tEA9GhaiJmXU+bWc=8Ksa0sng@mail.gmail.com>

On Tue, Jan 11, 2022 at 1:27 AM Lothar Wa?mann <LW at karo-electronics.de> wrote:
>
> Hi,
>
> On Mon, 10 Jan 2022 16:00:21 -0800 Tim Harvey wrote:
> > On Tue, Dec 14, 2021 at 1:36 PM Tim Harvey <tharvey at gateworks.com> wrote:
> > >
> [...]
> > > diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> > > new file mode 100644
> > > index 000000000000..97f19c15c3d0
> > > --- /dev/null
> > > +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
> > > @@ -0,0 +1,61 @@
> > > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > > +/*
> > > + * Copyright 2021 Gateworks Corporation
> > > + *
> > > + * GW73xx RS485 HD:
> > > + *  - GPIO1_0 rs485_term selects on-chip termination
> > > + *  - GPIO4_0 rs485_en needs to be driven high (active)
> > > + *  - GPIO4_2 rs485_hd needs to be driven high (active)
> > > + *  - UART4_TX is DE for RS485 transmitter
> > > + *  - RS485_EN needs to be pulled high
> > > + *  - RS485_HALF needs to be pulled high
> > > + */
> > > +
> > > +#include <dt-bindings/gpio/gpio.h>
> > > +
> > > +#include "imx8mm-pinfunc.h"
> > > +
> > > +/dts-v1/;
> > > +/plugin/;
> > > +
> > > +&{/} {
> > > +       compatible = "gw,imx8mm-gw73xx-0x";
> > > +};
> > > +
> > > +&gpio4 {
> > > +       rs485_en {
> > > +               gpio-hog;
> > > +               gpios = <0 GPIO_ACTIVE_HIGH>;
> > > +               output-high;
> > > +               line-name = "rs485_en";
> > > +       };
> > > +
> > > +       rs485_hd {
> > > +               gpio-hog;
> > > +               gpios = <2 GPIO_ACTIVE_HIGH>;
> > > +               output-high;
> > > +               line-name = "rs485_hd";
> > > +       };
> > > +};
> > > +
> > > +&uart2 {
> > > +       pinctrl-names = "default";
> > > +       pinctrl-0 = <&pinctrl_uart2>;
> > > +       rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
> > > +       linux,rs485-enabled-at-boot-time;
> > > +       status = "okay";
> > > +};
> > > +
> > > +&uart4 {
> > > +       status = "disabled";
> > > +};
> > > +
> > > +&iomuxc {
> > > +       pinctrl_uart2: uast2grp {
> >
> s/uast/uart/
>
>

Lothar,

Thanks - will fix in v2.

Tim


From andrew at lunn.ch  Wed Jan 12 11:44:58 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 12 Jan 2022 20:44:58 +0100
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
 reset
In-Reply-To: <d0b00b8c96be17e6ad636f5a74ebfb170a603eac.camel@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-3-robert.hancock@calian.com>
 <Yd8o6P6Pp7V7S+oL@lunn.ch>
 <d0b00b8c96be17e6ad636f5a74ebfb170a603eac.camel@calian.com>
Message-ID: <Yd8vukDquQLHYAXR@lunn.ch>

> > Is this bit guaranteed to be clear before you start waiting for it?
> 
> The documentation for the IP core ( 
> https://www.xilinx.com/content/dam/xilinx/support/documentation/ip_documentation/axi_ethernet/v7_2/pg138-axi-ethernet.pdf
>  ) states for the phy_rst_n output signal: "This active-Low reset is held
> active for 10 ms after power is applied and during any reset. After the reset
> goes inactive, the PHY cannot be accessed for an additional 5 ms." The
> PhyRstComplt bit definition mentions "This signal does not transition to 1 for
> 5 ms after PHY_RST_N transitions to 1". Given that a reset of the core has just
> been completed above, the PHY reset should at least have been initiated as
> well, so it should be sufficient to just wait for the bit to become 1 at this
> point.

Great, thanks for checking.

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From lkp at intel.com  Wed Jan 12 11:54:55 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 03:54:55 +0800
Subject: [xilinx-xlnx:master 173/326]
 drivers/clk/clk-xlnx-clock-wizard.c:324:15: error: implicit declaration of
 function 'FIELD_PREP'
Message-ID: <202201130305.ViNXFidF-lkp@intel.com>

Hi Shubhrajyoti,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: bf7387ee9a75c2a390b19f63c47076344e664b86 [173/326] clocking-wizard: Support higher frequency accuracy
config: arc-randconfig-r043-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130305.ViNXFidF-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/bf7387ee9a75c2a390b19f63c47076344e664b86
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout bf7387ee9a75c2a390b19f63c47076344e664b86
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash drivers/clk/ drivers/spi/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-xlnx-clock-wizard.c: In function 'clk_wzrd_dynamic_all_nolock':
>> drivers/clk/clk-xlnx-clock-wizard.c:324:15: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
     324 |         reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
         |               ^~~~~~~~~~
   drivers/clk/clk-xlnx-clock-wizard.c: In function 'clk_wzrd_recalc_rate_all':
>> drivers/clk/clk-xlnx-clock-wizard.c:392:13: error: implicit declaration of function 'FIELD_GET' [-Werror=implicit-function-declaration]
     392 |         d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
         |             ^~~~~~~~~
   cc1: some warnings being treated as errors


vim +/FIELD_PREP +324 drivers/clk/clk-xlnx-clock-wizard.c

   301	
   302	static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
   303					       unsigned long parent_rate)
   304	{
   305		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   306		u32 reg, pre;
   307		u16 retries;
   308		int err;
   309		u64 vco_freq, rate_div, f, clockout0_div;
   310	
   311		err = clk_wzrd_get_divisors(hw, rate, parent_rate);
   312		if (err)
   313			pr_err("failed to get divisors\n");
   314	
   315		vco_freq = DIV_ROUND_CLOSEST((parent_rate * divider->valuem), divider->valued);
   316		rate_div = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   317	
   318		clockout0_div = rate_div / WZRD_FRAC_POINTS;
   319	
   320		pre = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   321		f = (u32)(pre - (clockout0_div * WZRD_FRAC_POINTS));
   322		f = f & WZRD_CLKOUT_FRAC_MASK;
   323	
 > 324		reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
   325		      FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
   326	
   327		writel(reg, divider->base + WZRD_CLK_CFG_REG(2));
   328		/* Set divisor and clear phase offset */
   329		reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->valuem) |
   330		      FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->valued);
   331		writel(reg, divider->base + WZRD_CLK_CFG_REG(0));
   332		writel(divider->valueo, divider->base + WZRD_CLK_CFG_REG(2));
   333		writel(0, divider->base + WZRD_CLK_CFG_REG(3));
   334		/* Check status register */
   335		retries = WZRD_DR_NUM_RETRIES;
   336		while (retries--) {
   337			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   338								WZRD_DR_LOCK_BIT_MASK)
   339				break;
   340		}
   341	
   342		if (!retries)
   343			return -ETIMEDOUT;
   344	
   345		/* Initiate reconfiguration */
   346		writel(WZRD_DR_BEGIN_DYNA_RECONF,
   347		       divider->base + WZRD_DR_INIT_REG_OFFSET);
   348	
   349		/* Check status register */
   350		retries = WZRD_DR_NUM_RETRIES;
   351		while (retries--) {
   352			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   353								WZRD_DR_LOCK_BIT_MASK)
   354				break;
   355		}
   356	
   357		if (!retries)
   358			return -ETIMEDOUT;
   359	
   360		return 0;
   361	}
   362	
   363	static int clk_wzrd_dynamic_all(struct clk_hw *hw, unsigned long rate,
   364					unsigned long parent_rate)
   365	{
   366		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   367		unsigned long flags = 0;
   368		int ret;
   369	
   370		if (divider->lock)
   371			spin_lock_irqsave(divider->lock, flags);
   372		else
   373			__acquire(divider->lock);
   374	
   375		ret = clk_wzrd_dynamic_all_nolock(hw, rate, parent_rate);
   376	
   377		if (divider->lock)
   378			spin_unlock_irqrestore(divider->lock, flags);
   379		else
   380			__release(divider->lock);
   381	
   382		return ret;
   383	}
   384	
   385	static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
   386						      unsigned long parent_rate)
   387	{
   388		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   389		u32 m, d, o, div, reg, f;
   390	
   391		reg = readl(divider->base + WZRD_CLK_CFG_REG(0));
 > 392		d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   393		m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
   394		reg = readl(divider->base + WZRD_CLK_CFG_REG(2));
   395		o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   396		f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
   397	
   398		div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
   399		return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
   400				divider->flags, divider->width);
   401	}
   402	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Jan 12 12:05:21 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 04:05:21 +0800
Subject: [xilinx-xlnx:master 173/326]
 drivers/clk/clk-xlnx-clock-wizard.c:324:8: error: implicit declaration of
 function 'FIELD_PREP'
Message-ID: <202201130302.pmg1cg7e-lkp@intel.com>

Hi Shubhrajyoti,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: bf7387ee9a75c2a390b19f63c47076344e664b86 [173/326] clocking-wizard: Support higher frequency accuracy
config: riscv-randconfig-r042-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130302.pmg1cg7e-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 244dd2913a43a200f5a6544d424cdc37b771028b)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://github.com/Xilinx/linux-xlnx/commit/bf7387ee9a75c2a390b19f63c47076344e664b86
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout bf7387ee9a75c2a390b19f63c47076344e664b86
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/clk/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/clk/clk-xlnx-clock-wizard.c:324:8: error: implicit declaration of function 'FIELD_PREP' [-Werror,-Wimplicit-function-declaration]
           reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
                 ^
>> drivers/clk/clk-xlnx-clock-wizard.c:392:6: error: implicit declaration of function 'FIELD_GET' [-Werror,-Wimplicit-function-declaration]
           d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
               ^
   2 errors generated.


vim +/FIELD_PREP +324 drivers/clk/clk-xlnx-clock-wizard.c

   301	
   302	static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
   303					       unsigned long parent_rate)
   304	{
   305		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   306		u32 reg, pre;
   307		u16 retries;
   308		int err;
   309		u64 vco_freq, rate_div, f, clockout0_div;
   310	
   311		err = clk_wzrd_get_divisors(hw, rate, parent_rate);
   312		if (err)
   313			pr_err("failed to get divisors\n");
   314	
   315		vco_freq = DIV_ROUND_CLOSEST((parent_rate * divider->valuem), divider->valued);
   316		rate_div = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   317	
   318		clockout0_div = rate_div / WZRD_FRAC_POINTS;
   319	
   320		pre = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   321		f = (u32)(pre - (clockout0_div * WZRD_FRAC_POINTS));
   322		f = f & WZRD_CLKOUT_FRAC_MASK;
   323	
 > 324		reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
   325		      FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
   326	
   327		writel(reg, divider->base + WZRD_CLK_CFG_REG(2));
   328		/* Set divisor and clear phase offset */
   329		reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->valuem) |
   330		      FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->valued);
   331		writel(reg, divider->base + WZRD_CLK_CFG_REG(0));
   332		writel(divider->valueo, divider->base + WZRD_CLK_CFG_REG(2));
   333		writel(0, divider->base + WZRD_CLK_CFG_REG(3));
   334		/* Check status register */
   335		retries = WZRD_DR_NUM_RETRIES;
   336		while (retries--) {
   337			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   338								WZRD_DR_LOCK_BIT_MASK)
   339				break;
   340		}
   341	
   342		if (!retries)
   343			return -ETIMEDOUT;
   344	
   345		/* Initiate reconfiguration */
   346		writel(WZRD_DR_BEGIN_DYNA_RECONF,
   347		       divider->base + WZRD_DR_INIT_REG_OFFSET);
   348	
   349		/* Check status register */
   350		retries = WZRD_DR_NUM_RETRIES;
   351		while (retries--) {
   352			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   353								WZRD_DR_LOCK_BIT_MASK)
   354				break;
   355		}
   356	
   357		if (!retries)
   358			return -ETIMEDOUT;
   359	
   360		return 0;
   361	}
   362	
   363	static int clk_wzrd_dynamic_all(struct clk_hw *hw, unsigned long rate,
   364					unsigned long parent_rate)
   365	{
   366		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   367		unsigned long flags = 0;
   368		int ret;
   369	
   370		if (divider->lock)
   371			spin_lock_irqsave(divider->lock, flags);
   372		else
   373			__acquire(divider->lock);
   374	
   375		ret = clk_wzrd_dynamic_all_nolock(hw, rate, parent_rate);
   376	
   377		if (divider->lock)
   378			spin_unlock_irqrestore(divider->lock, flags);
   379		else
   380			__release(divider->lock);
   381	
   382		return ret;
   383	}
   384	
   385	static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
   386						      unsigned long parent_rate)
   387	{
   388		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   389		u32 m, d, o, div, reg, f;
   390	
   391		reg = readl(divider->base + WZRD_CLK_CFG_REG(0));
 > 392		d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   393		m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
   394		reg = readl(divider->base + WZRD_CLK_CFG_REG(2));
   395		o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   396		f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
   397	
   398		div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
   399		return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
   400				divider->flags, divider->width);
   401	}
   402	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Wed Jan 12 12:05:24 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 04:05:24 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <20220110085604.18042-4-yu.tu@amlogic.com>
References: <20220110085604.18042-4-yu.tu@amlogic.com>
Message-ID: <202201130331.dzluDr3h-lkp@intel.com>

Hi Yu,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on next-20220112]
[cannot apply to robh/for-next soc/for-next clk/clk-next v5.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Yu-Tu/the-UART-driver-compatible-with/20220110-170020
base:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: powerpc-randconfig-s031-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130331.dzluDr3h-lkp at intel.com/config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/0day-ci/linux/commit/6d55159e6626326d9001d4c8f20b914a69c2c40b
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Yu-Tu/the-UART-driver-compatible-with/20220110-170020
        git checkout 6d55159e6626326d9001d4c8f20b914a69c2c40b
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=powerpc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   powerpc-linux-ld: drivers/tty/serial/meson_uart.o: in function `meson_uart_probe_clocks':
   meson_uart.c:(.text+0x464): undefined reference to `__clk_get_name'
>> powerpc-linux-ld: meson_uart.c:(.text+0x4bc): undefined reference to `__devm_clk_hw_register_divider'
>> powerpc-linux-ld: meson_uart.c:(.text+0x4fc): undefined reference to `__clk_get_name'
>> powerpc-linux-ld: meson_uart.c:(.text+0x518): undefined reference to `devm_clk_hw_register_fixed_factor'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5a8): undefined reference to `__devm_clk_hw_register_mux'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5c0): undefined reference to `clk_hw_get_rate'
>> powerpc-linux-ld: meson_uart.c:(.text+0x5f8): undefined reference to `clk_hw_get_name'
   powerpc-linux-ld: meson_uart.c:(.text+0x640): undefined reference to `__devm_clk_hw_register_divider'
>> powerpc-linux-ld: meson_uart.c:(.text+0x65c): undefined reference to `clk_hw_get_clk'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From jiaxun.yang at flygoat.com  Wed Jan 12 12:08:45 2022
From: jiaxun.yang at flygoat.com (Jiaxun Yang)
Date: Wed, 12 Jan 2022 20:08:45 +0000
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20220112151903.GA257550@bhelgaas>
References: <20220112151903.GA257550@bhelgaas>
Message-ID: <84d849b5-9386-4db5-87fe-34de3d6c487b@www.fastmail.com>



?2022?1?12??? ??3:19?Bjorn Helgaas???
> On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
>> ?2022?1?11??? ??9:46?Bjorn Helgaas???
>> > [-cc many, +cc iproc, loongson, tegra maintainers]
[...]
> I see these:
>
>   Documentation/devicetree/bindings/pci/loongson.yaml
>   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
>
> which makes me think there are Loongson systems with DT.  Are there
> some Loongson systems with DT and some legacy ones without?

Actually all present MIPS/Loongson systems are legacy and we just built-in
DTs in kernel and select which one to use at boot time. 

>
> The only driver I see is drivers/pci/controller/pci-loongson.c.  Is
> that used for all Loongson system?  It unconditionally uses ->map_irq
> = loongson_map_irq().

Yes, it's used among all Loongson systems.
For system using LS7A PCH the IRQ mapping is fixed so we just programed
it in DT. For RS780E we use this rountine to read PCI_INTERRUPT_LINE to
select which I8259 IRQ to use.

>
> loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends on
> firmware having previously programmed it, right?

I'm unclear about what did firmware do but as AMD RS780E is used in x86
PCs as well it should be the same way.

Thanks.

>
> Bjorn

-- 
- Jiaxun


From keescook at chromium.org  Wed Jan 12 12:18:58 2022
From: keescook at chromium.org (Kees Cook)
Date: Wed, 12 Jan 2022 12:18:58 -0800
Subject: [PATCH] arm64: atomics: Dereference matching size
In-Reply-To: <YdwKLwvDRfc59c8U@FVFF77S0Q05N>
References: <20220107232746.1540130-1-keescook@chromium.org>
 <YdwKLwvDRfc59c8U@FVFF77S0Q05N>
Message-ID: <202201121217.FB408C2362@keescook>

On Mon, Jan 10, 2022 at 10:27:59AM +0000, Mark Rutland wrote:
> Hi Kees,
> 
> On Fri, Jan 07, 2022 at 03:27:46PM -0800, Kees Cook wrote:
> > When building with -Warray-bounds (which is desired to be enabled
> > globally), the following warning is generated:
> > 
> > In file included from ./arch/arm64/include/asm/lse.h:16,
> >                  from ./arch/arm64/include/asm/cmpxchg.h:14,
> >                  from ./arch/arm64/include/asm/atomic.h:16,
> >                  from ./include/linux/atomic.h:7,
> >                  from ./include/asm-generic/bitops/atomic.h:5,
> >                  from ./arch/arm64/include/asm/bitops.h:25,
> >                  from ./include/linux/bitops.h:33,
> >                  from ./include/linux/kernel.h:22,
> >                  from kernel/printk/printk.c:22:
> > ./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
> >   247 |         asm volatile(                                                   \
> >       |         ^~~
> > ./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
> >   266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
> >       | ^~~~~~~~~~~~~~
> > kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
> >  3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
> >       |                 ^~~~~~~~~~~~~~~~~~~~
> > 
> > This is due to the compiler seeing an unsigned long * cast against
> > something (atomic_t) that is int sized. Replace the cast with the
> > matching size cast. This results in no change in binary output.
> 
> Just to check, I assume both GCC and Clang are happy with this applied?
> 
> I recall that (historically at least) clang would warn about size mismatches
> for inline assembly and would sometimes require more care. I don't see anythign
> for which that would matter, but I just want to check.

Yup, Clang is happy with this AFAICT.

> 
> > Cc: Will Deacon <will at kernel.org>
> > Cc: Peter Zijlstra <peterz at infradead.org>
> > Cc: Boqun Feng <boqun.feng at gmail.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: linux-arm-kernel at lists.infradead.org
> > Signed-off-by: Kees Cook <keescook at chromium.org>
> > ---
> >  arch/arm64/include/asm/atomic_lse.h | 2 +-
> >  arch/arm64/include/asm/cmpxchg.h    | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
> > index d955ade5df7c..5d460f6b7675 100644
> > --- a/arch/arm64/include/asm/atomic_lse.h
> > +++ b/arch/arm64/include/asm/atomic_lse.h
> > @@ -249,7 +249,7 @@ __lse__cmpxchg_case_##name##sz(volatile void *ptr,			\
> >  	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
> >  	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
> >  	"	mov	%" #w "[ret], %" #w "[tmp]"			\
> > -	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
> > +	: [ret] "+r" (x0), [v] "+Q" (*(u##sz *)ptr),			\
> >  	  [tmp] "=&r" (tmp)						\
> >  	: [old] "r" (x1), [new] "r" (x2)				\
> >  	: cl);								\
> 
> It might be worth nothing that __ll_sc__cmpxchg_case_##name##sz already uses
> the same constraint:
> 
> 	[v] "+Q" (*(u##sz *)ptr
> 
> ... since that explains why we only need to update the LSE form and not the
> LL/SC form, and indicates that this is unlikely to be problematic.

Good idea, I'll note that in a v2.

> 
> Either way:
> 
> Acked-by: Mark Rutland <mark.rutland at arm.com>

Thanks!

-Kees

> 
> Thanks,
> Mark.
> 
> > diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
> > index f9bef42c1411..497acf134d99 100644
> > --- a/arch/arm64/include/asm/cmpxchg.h
> > +++ b/arch/arm64/include/asm/cmpxchg.h
> > @@ -243,7 +243,7 @@ static inline void __cmpwait_case_##sz(volatile void *ptr,		\
> >  	"	cbnz	%" #w "[tmp], 1f\n"				\
> >  	"	wfe\n"							\
> >  	"1:"								\
> > -	: [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr)		\
> > +	: [tmp] "=&r" (tmp), [v] "+Q" (*(u##sz *)ptr)			\
> >  	: [val] "r" (val));						\
> >  }
> >  
> > -- 
> > 2.30.2
> > 

-- 
Kees Cook


From keescook at chromium.org  Wed Jan 12 12:22:59 2022
From: keescook at chromium.org (Kees Cook)
Date: Wed, 12 Jan 2022 12:22:59 -0800
Subject: [PATCH v2] arm64: atomics: lse: Dereference matching size
Message-ID: <20220112202259.3950286-1-keescook@chromium.org>

When building with -Warray-bounds, the following warning is generated:

In file included from ./arch/arm64/include/asm/lse.h:16,
                 from ./arch/arm64/include/asm/cmpxchg.h:14,
                 from ./arch/arm64/include/asm/atomic.h:16,
                 from ./include/linux/atomic.h:7,
                 from ./include/asm-generic/bitops/atomic.h:5,
                 from ./arch/arm64/include/asm/bitops.h:25,
                 from ./include/linux/bitops.h:33,
                 from ./include/linux/kernel.h:22,
                 from kernel/printk/printk.c:22:
./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
  247 |         asm volatile(                                                   \
      |         ^~~
./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
  266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
      | ^~~~~~~~~~~~~~
kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
 3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
      |                 ^~~~~~~~~~~~~~~~~~~~

This is due to the compiler seeing an unsigned long * cast against
something (atomic_t) that is int sized. Replace the cast with the
matching size cast. This results in no change in binary output.

Note that __ll_sc__cmpxchg_case_##name##sz already uses the same
constraint:

	[v] "+Q" (*(u##sz *)ptr

Which is why only the LSE form needs updating and not the
LL/SC form, so this change is unlikely to be problematic.

Cc: Will Deacon <will at kernel.org>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Boqun Feng <boqun.feng at gmail.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Kees Cook <keescook at chromium.org>
---
v1: https://lore.kernel.org/linux-hardening/20220107232746.1540130-1-keescook at chromium.org/
v2:
 - add Acks
 - note the existing LL/SC form
---
 arch/arm64/include/asm/atomic_lse.h | 2 +-
 arch/arm64/include/asm/cmpxchg.h    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/atomic_lse.h b/arch/arm64/include/asm/atomic_lse.h
index d955ade5df7c..5d460f6b7675 100644
--- a/arch/arm64/include/asm/atomic_lse.h
+++ b/arch/arm64/include/asm/atomic_lse.h
@@ -249,7 +249,7 @@ __lse__cmpxchg_case_##name##sz(volatile void *ptr,			\
 	"	mov	%" #w "[tmp], %" #w "[old]\n"			\
 	"	cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"	\
 	"	mov	%" #w "[ret], %" #w "[tmp]"			\
-	: [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),		\
+	: [ret] "+r" (x0), [v] "+Q" (*(u##sz *)ptr),			\
 	  [tmp] "=&r" (tmp)						\
 	: [old] "r" (x1), [new] "r" (x2)				\
 	: cl);								\
diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h
index f9bef42c1411..497acf134d99 100644
--- a/arch/arm64/include/asm/cmpxchg.h
+++ b/arch/arm64/include/asm/cmpxchg.h
@@ -243,7 +243,7 @@ static inline void __cmpwait_case_##sz(volatile void *ptr,		\
 	"	cbnz	%" #w "[tmp], 1f\n"				\
 	"	wfe\n"							\
 	"1:"								\
-	: [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr)		\
+	: [tmp] "=&r" (tmp), [v] "+Q" (*(u##sz *)ptr)			\
 	: [val] "r" (val));						\
 }
 
-- 
2.30.2



From sboyd at kernel.org  Wed Jan 12 12:29:35 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 12 Jan 2022 12:29:35 -0800
Subject: [PATCH] clk: zynqmp: warn always when a clock op fails
In-Reply-To: <20220112141229.700708-1-m.tretter@pengutronix.de>
References: <20220112141229.700708-1-m.tretter@pengutronix.de>
Message-ID: <20220112202937.034D9C36AE5@smtp.kernel.org>

Quoting Michael Tretter (2022-01-12 06:12:29)
> The warning that a clock operation failed is only printed once. However,
> the function is called for various different clocks. The limit hides
> warnings if different clock are affected by the failures.
> 
> Print the warning every time when a clock operation fails.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---
>  drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
>  drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
>  drivers/clk/zynqmp/divider.c         | 12 +++++------
>  drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
>  4 files changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> index 565ed67a0430..0d9a39110f29 100644
> --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
> +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> @@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
>         ret = zynqmp_pm_clock_enable(clk_id);
>  
>         if (ret)
> -               pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
> -                            __func__, clk_name, ret);
> +               pr_warn("%s() clock enable failed for %s (id %d), ret = %d\n",
> +                       __func__, clk_name, clk_id, ret);

Can we just remove these prints entirely? The driver that calls
clk_enable() should be checking the return value and taking proper
action. What is the user going to do with these messages?


From lkp at intel.com  Wed Jan 12 12:46:14 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 04:46:14 +0800
Subject: [xilinx-xlnx:master 269/326]
 include/linux/firmware/xlnx-zynqmp.h:1244:5: warning: no previous prototype
 for function 'zynqmp_pm_get_meta_header'
Message-ID: <202201130455.ASiUDDqB-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 22272cc48b5399af99792722fa7004735b769e0a [269/326] firmware: xilinx: Add support to get the image meta-header info
config: hexagon-randconfig-r041-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130455.ASiUDDqB-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 244dd2913a43a200f5a6544d424cdc37b771028b)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/22272cc48b5399af99792722fa7004735b769e0a
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 22272cc48b5399af99792722fa7004735b769e0a
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/fpga/zynqmp-fpga.c:14:
>> include/linux/firmware/xlnx-zynqmp.h:1244:5: warning: no previous prototype for function 'zynqmp_pm_get_meta_header' [-Wmissing-prototypes]
   int zynqmp_pm_get_meta_header(const u64 src, const u64 dst,
       ^
   include/linux/firmware/xlnx-zynqmp.h:1244:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   int zynqmp_pm_get_meta_header(const u64 src, const u64 dst,
   ^
   static 
   include/linux/firmware/xlnx-zynqmp.h:1212:12: warning: unused function 'zynqmp_pm_sec_read_reg' [-Wunused-function]
   static int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
              ^
   include/linux/firmware/xlnx-zynqmp.h:1217:12: warning: unused function 'zynqmp_pm_sec_mask_write_reg' [-Wunused-function]
   static int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
              ^
   3 warnings generated.


vim +/zynqmp_pm_get_meta_header +1244 include/linux/firmware/xlnx-zynqmp.h

  1243	
> 1244	int zynqmp_pm_get_meta_header(const u64 src, const u64 dst,
  1245				      const u32 size, u32 *count)
  1246	{
  1247		return -ENODEV;
  1248	}
  1249	#endif
  1250	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From oleksandr at natalenko.name  Wed Jan 12 12:56:58 2022
From: oleksandr at natalenko.name (Oleksandr Natalenko)
Date: Wed, 12 Jan 2022 21:56:58 +0100
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <11900935.O9o76ZdvQC@natalenko.name>

Hello.

On ?ter? 4. ledna 2022 21:22:19 CET Yu Zhao wrote:
> TLDR
> ====
> The current page reclaim is too expensive in terms of CPU usage and it
> often makes poor choices about what to evict. This patchset offers an
> alternative solution that is performant, versatile and
> straightforward.
> 
> Design objectives
> =================
> The design objectives are:
> 1. Better representation of access recency
> 2. Try to profit from spatial locality
> 3. Clear fast path making obvious choices
> 4. Simple self-correcting heuristics
> 
> The representation of access recency is at the core of all LRU
> approximations. The multigenerational LRU (MGLRU) divides pages into
> multiple lists (generations), each having bounded access recency (a
> time interval). Generations establish a common frame of reference and
> help make better choices, e.g., between different memcgs on a computer
> or different computers in a data center (for cluster job scheduling).
> 
> Exploiting spatial locality improves the efficiency when gathering the
> accessed bit. A rmap walk targets a single page and doesn't try to
> profit from discovering an accessed PTE. A page table walk can sweep
> all hotspots in an address space, but its search space can be too
> large to make a profit. The key is to optimize both methods and use
> them in combination. (PMU is another option for further exploration.)
> 
> Fast path reduces code complexity and runtime overhead. Unmapped pages
> don't require TLB flushes; clean pages don't require writeback. These
> facts are only helpful when other conditions, e.g., access recency,
> are similar. With generations as a common frame of reference,
> additional factors stand out. But obvious choices might not be good
> choices; thus self-correction is required (the next objective).
> 
> The benefits of simple self-correcting heuristics are self-evident.
> Again with generations as a common frame of reference, this becomes
> attainable. Specifically, pages in the same generation are categorized
> based on additional factors, and a closed-loop control statistically
> compares the refault percentages across all categories and throttles
> the eviction of those that have higher percentages.
> 
> Patchset overview
> =================
> 1. mm: x86, arm64: add arch_has_hw_pte_young()
> 2. mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
> Materializing hardware optimizations when trying to clear the accessed
> bit in many PTEs. If hardware automatically sets the accessed bit in
> PTEs, there is no need to worry about bursty page faults (emulating
> the accessed bit). If it also sets the accessed bit in non-leaf PMD
> entries, there is no need to search the PTE table pointed to by a PMD
> entry that doesn't have the accessed bit set.
> 
> 3. mm/vmscan.c: refactor shrink_node()
> A minor refactor.
> 
> 4. mm: multigenerational lru: groundwork
> Adding the basic data structure and the functions to initialize it and
> insert/remove pages.
> 
> 5. mm: multigenerational lru: mm_struct list
> An infra keeps track of mm_struct's for page table walkers and
> provides them with optimizations, i.e., switch_mm() tracking and Bloom
> filters.
> 
> 6. mm: multigenerational lru: aging
> 7. mm: multigenerational lru: eviction
> "The page reclaim" is a producer/consumer model. "The aging" produces
> cold pages, whereas "the eviction " consumes them. Cold pages flow
> through generations. The aging uses the mm_struct list infra to sweep
> dense hotspots in page tables. During a page table walk, the aging
> clears the accessed bit and tags accessed pages with the youngest
> generation number. The eviction sorts those pages when it encounters
> them. For pages in the oldest generation, eviction walks the rmap to
> check the accessed bit one more time before evicting them. During an
> rmap walk, the eviction feeds dense hotspots back to the aging. Dense
> hotspots flow through the Bloom filters. For pages not mapped in page
> tables, the eviction uses the PID controller to statistically
> determine whether they have higher refaults. If so, the eviction
> throttles their eviction by moving them to the next generation (the
> second oldest).
> 
> 8. mm: multigenerational lru: user interface
> The knobs to turn on/off MGLRU and provide the userspace with
> thrashing prevention, working set estimation (the aging) and proactive
> reclaim (the eviction).
> 
> 9. mm: multigenerational lru: Kconfig
> The Kconfig options.
> 
> Benchmark results
> =================
> Independent lab results
> -----------------------
> Based on the popularity of searches [01] and the memory usage in
> Google's public cloud, the most popular open-source memory-hungry
> applications, in alphabetical order, are:
>       Apache Cassandra      Memcached
>       Apache Hadoop         MongoDB
>       Apache Spark          PostgreSQL
>       MariaDB (MySQL)       Redis
> 
> An independent lab evaluated MGLRU with the most widely used benchmark
> suites for the above applications. They posted 960 data points along
> with kernel metrics and perf profiles collected over more than 500
> hours of total benchmark time. Their final reports show that, with 95%
> confidence intervals (CIs), the above applications all performed
> significantly better for at least part of their benchmark matrices.
> 
> On 5.14:
> 1. Apache Spark [02] took 95% CIs [9.28, 11.19]% and [12.20, 14.93]%
>    less wall time to sort three billion random integers, respectively,
>    under the medium- and the high-concurrency conditions, when
>    overcommitting memory. There were no statistically significant
>    changes in wall time for the rest of the benchmark matrix.
> 2. MariaDB [03] achieved 95% CIs [5.24, 10.71]% and [20.22, 25.97]%
>    more transactions per minute (TPM), respectively, under the medium-
>    and the high-concurrency conditions, when overcommitting memory.
>    There were no statistically significant changes in TPM for the rest
>    of the benchmark matrix.
> 3. Memcached [04] achieved 95% CIs [23.54, 32.25]%, [20.76, 41.61]%
>    and [21.59, 30.02]% more operations per second (OPS), respectively,
>    for sequential access, random access and Gaussian (distribution)
>    access, when THP=always; 95% CIs [13.85, 15.97]% and
>    [23.94, 29.92]% more OPS, respectively, for random access and
>    Gaussian access, when THP=never. There were no statistically
>    significant changes in OPS for the rest of the benchmark matrix.
> 4. MongoDB [05] achieved 95% CIs [2.23, 3.44]%, [6.97, 9.73]% and
>    [2.16, 3.55]% more operations per second (OPS), respectively, for
>    exponential (distribution) access, random access and Zipfian
>    (distribution) access, when underutilizing memory; 95% CIs
>    [8.83, 10.03]%, [21.12, 23.14]% and [5.53, 6.46]% more OPS,
>    respectively, for exponential access, random access and Zipfian
>    access, when overcommitting memory.
> 
> On 5.15:
> 5. Apache Cassandra [06] achieved 95% CIs [1.06, 4.10]%, [1.94, 5.43]%
>    and [4.11, 7.50]% more operations per second (OPS), respectively,
>    for exponential (distribution) access, random access and Zipfian
>    (distribution) access, when swap was off; 95% CIs [0.50, 2.60]%,
>    [6.51, 8.77]% and [3.29, 6.75]% more OPS, respectively, for
>    exponential access, random access and Zipfian access, when swap was
>    on.
> 6. Apache Hadoop [07] took 95% CIs [5.31, 9.69]% and [2.02, 7.86]%
>    less average wall time to finish twelve parallel TeraSort jobs,
>    respectively, under the medium- and the high-concurrency
>    conditions, when swap was on. There were no statistically
>    significant changes in average wall time for the rest of the
>    benchmark matrix.
> 7. PostgreSQL [08] achieved 95% CI [1.75, 6.42]% more transactions per
>    minute (TPM) under the high-concurrency condition, when swap was
>    off; 95% CIs [12.82, 18.69]% and [22.70, 46.86]% more TPM,
>    respectively, under the medium- and the high-concurrency
>    conditions, when swap was on. There were no statistically
>    significant changes in TPM for the rest of the benchmark matrix.
> 8. Redis [09] achieved 95% CIs [0.58, 5.94]%, [6.55, 14.58]% and
>    [11.47, 19.36]% more total operations per second (OPS),
>    respectively, for sequential access, random access and Gaussian
>    (distribution) access, when THP=always; 95% CIs [1.27, 3.54]%,
>    [10.11, 14.81]% and [8.75, 13.64]% more total OPS, respectively,
>    for sequential access, random access and Gaussian access, when
>    THP=never.
> 
> Our lab results
> ---------------
> To supplement the above results, we ran the following benchmark suites
> on 5.16-rc7 and found no regressions [10]. (These synthetic benchmarks
> are popular among MM developers, but we prefer large-scale A/B
> experiments to validate improvements.)
>       fs_fio_bench_hdd_mq      pft
>       fs_lmbench               pgsql-hammerdb
>       fs_parallelio            redis
>       fs_postmark              stream
>       hackbench                sysbenchthread
>       kernbench                tpcc_spark
>       memcached                unixbench
>       multichase               vm-scalability
>       mutilate                 will-it-scale
>       nginx
> 
> [01] https://trends.google.com
> [02] https://lore.kernel.org/linux-mm/20211102002002.92051-1-bot at edi.works/
> [03] https://lore.kernel.org/linux-mm/20211009054315.47073-1-bot at edi.works/
> [04] https://lore.kernel.org/linux-mm/20211021194103.65648-1-bot at edi.works/
> [05] https://lore.kernel.org/linux-mm/20211109021346.50266-1-bot at edi.works/
> [06] https://lore.kernel.org/linux-mm/20211202062806.80365-1-bot at edi.works/
> [07] https://lore.kernel.org/linux-mm/20211209072416.33606-1-bot at edi.works/
> [08] https://lore.kernel.org/linux-mm/20211218071041.24077-1-bot at edi.works/
> [09] https://lore.kernel.org/linux-mm/20211122053248.57311-1-bot at edi.works/
> [10] https://lore.kernel.org/linux-mm/20220104202247.2903702-1-yuzhao at google.com/
> 
> Read-world applications
> =======================
> Third-party testimonials
> ------------------------
> Konstantin wrote [11]:
>    I have Archlinux with 8G RAM + zswap + swap. While developing, I
>    have lots of apps opened such as multiple LSP-servers for different
>    langs, chats, two browsers, etc... Usually, my system gets quickly
>    to a point of SWAP-storms, where I have to kill LSP-servers,
>    restart browsers to free memory, etc, otherwise the system lags
>    heavily and is barely usable.
>    
>    1.5 day ago I migrated from 5.11.15 kernel to 5.12 + the LRU
>    patchset, and I started up by opening lots of apps to create memory
>    pressure, and worked for a day like this. Till now I had *not a
>    single SWAP-storm*, and mind you I got 3.4G in SWAP. I was never
>    getting to the point of 3G in SWAP before without a single
>    SWAP-storm.
> 
> The Arch Linux Zen kernel [12] has been using MGLRU since 5.12. Many
> of its users reported their positive experiences to me, e.g., Shivodit
> wrote:
>    I've tried the latest Zen kernel (5.14.13-zen1-1-zen in the
>    archlinux testing repos), everything's been smooth so far. I also
>    decided to copy a large volume of files to check performance under
>    I/O load, and everything went smoothly - no stuttering was present,
>    everything was responsive.
> 
> Large-scale deployments
> -----------------------
> We've rolled out MGLRU to tens of millions of Chrome OS users and
> about a million Android users. Google's fleetwide profiling [13] shows
> an overall 40% decrease in kswapd CPU usage, in addition to
> improvements in other UX metrics, e.g., an 85% decrease in the number
> of low-memory kills at the 75th percentile and an 18% decrease in
> rendering latency at the 50th percentile.
> 
> [11] https://lore.kernel.org/linux-mm/140226722f2032c86301fbd326d91baefe3d7d23.camel at yandex.ru/
> [12] https://github.com/zen-kernel/zen-kernel/
> [13] https://research.google/pubs/pub44271/
> 
> Summery
> =======
> The facts are:
> 1. The independent lab results and the real-world applications
>    indicate substantial improvements; there are no known regressions.
> 2. Thrashing prevention, working set estimation and proactive reclaim
>    work out of the box; there are no equivalent solutions.
> 3. There is a lot of new code; nobody has demonstrated smaller changes
>    with similar effects.
> 
> Our options, accordingly, are:
> 1. Given the amount of evidence, the reported improvements will likely
>    materialize for a wide range of workloads.
> 2. Gauging the interest from the past discussions [14][15][16], the
>    new features will likely be put to use for both personal computers
>    and data centers.
> 3. Based on Google's track record, the new code will likely be well
>    maintained in the long term. It'd be more difficult if not
>    impossible to achieve similar effects on top of the existing
>    design.
> 
> [14] https://lore.kernel.org/lkml/20201005081313.732745-1-andrea.righi at canonical.com/
> [15] https://lore.kernel.org/lkml/20210716081449.22187-1-sj38.park at gmail.com/
> [16] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/
> 
> Yu Zhao (9):
>   mm: x86, arm64: add arch_has_hw_pte_young()
>   mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
>   mm/vmscan.c: refactor shrink_node()
>   mm: multigenerational lru: groundwork
>   mm: multigenerational lru: mm_struct list
>   mm: multigenerational lru: aging
>   mm: multigenerational lru: eviction
>   mm: multigenerational lru: user interface
>   mm: multigenerational lru: Kconfig
> 
>  Documentation/vm/index.rst          |    1 +
>  Documentation/vm/multigen_lru.rst   |   80 +
>  arch/Kconfig                        |    9 +
>  arch/arm64/include/asm/cpufeature.h |    5 +
>  arch/arm64/include/asm/pgtable.h    |   13 +-
>  arch/arm64/kernel/cpufeature.c      |   19 +
>  arch/arm64/tools/cpucaps            |    1 +
>  arch/x86/Kconfig                    |    1 +
>  arch/x86/include/asm/pgtable.h      |    9 +-
>  arch/x86/mm/pgtable.c               |    5 +-
>  fs/exec.c                           |    2 +
>  fs/fuse/dev.c                       |    3 +-
>  include/linux/cgroup.h              |   15 +-
>  include/linux/memcontrol.h          |   11 +
>  include/linux/mm.h                  |   42 +
>  include/linux/mm_inline.h           |  204 ++
>  include/linux/mm_types.h            |   78 +
>  include/linux/mmzone.h              |  175 ++
>  include/linux/nodemask.h            |    1 +
>  include/linux/oom.h                 |   16 +
>  include/linux/page-flags-layout.h   |   19 +-
>  include/linux/page-flags.h          |    4 +-
>  include/linux/pgtable.h             |   17 +-
>  include/linux/sched.h               |    4 +
>  include/linux/swap.h                |    4 +
>  kernel/bounds.c                     |    3 +
>  kernel/cgroup/cgroup-internal.h     |    1 -
>  kernel/exit.c                       |    1 +
>  kernel/fork.c                       |    9 +
>  kernel/sched/core.c                 |    1 +
>  mm/Kconfig                          |   48 +
>  mm/huge_memory.c                    |    3 +-
>  mm/memcontrol.c                     |   26 +
>  mm/memory.c                         |   21 +-
>  mm/mm_init.c                        |    6 +-
>  mm/oom_kill.c                       |    4 +-
>  mm/page_alloc.c                     |    1 +
>  mm/rmap.c                           |    7 +
>  mm/swap.c                           |   51 +-
>  mm/vmscan.c                         | 2691 ++++++++++++++++++++++++++-
>  mm/workingset.c                     |  119 +-
>  41 files changed, 3591 insertions(+), 139 deletions(-)
>  create mode 100644 Documentation/vm/multigen_lru.rst

For the series:

Tested-by: Oleksandr Natalenko <oleksandr at natalenko.name>

I run this (and one of the previous spins) on nine machines (physical, virtual, workstations, servers) for quite some time with no hassle.

Thanks for your job, and please keep me in Cc once you post new spins. I'm more than happy to deploy those across the fleet.

-- 
Oleksandr Natalenko (post-factum)




From helgaas at kernel.org  Wed Jan 12 13:10:39 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 12 Jan 2022 15:10:39 -0600
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <84d849b5-9386-4db5-87fe-34de3d6c487b@www.fastmail.com>
Message-ID: <20220112211039.GA281591@bhelgaas>

On Wed, Jan 12, 2022 at 08:08:45PM +0000, Jiaxun Yang wrote:
> ?2022?1?12??? ??3:19?Bjorn Helgaas???
> > On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
> >> ?2022?1?11??? ??9:46?Bjorn Helgaas???
> >> > [-cc many, +cc iproc, loongson, tegra maintainers]
> [...]
> > I see these:
> >
> >   Documentation/devicetree/bindings/pci/loongson.yaml
> >   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
> >
> > which makes me think there are Loongson systems with DT.  Are there
> > some Loongson systems with DT and some legacy ones without?
> 
> Actually all present MIPS/Loongson systems are legacy and we just
> built-in DTs in kernel and select which one to use at boot time. 

So I guess you know enough about what platform it is to select which
DT to use, but you don't know enough to know the I8259 routing?

If you *could* select a DT that described the I8259 routing, I guess
maybe you could select a matching DT or update a DT in-place?

> > The only driver I see is drivers/pci/controller/pci-loongson.c.
> > Is that used for all Loongson system?  It unconditionally uses
> > ->map_irq = loongson_map_irq().
> 
> Yes, it's used among all Loongson systems.  For system using LS7A
> PCH the IRQ mapping is fixed so we just programmed it in DT. For
> RS780E we use this routine to read PCI_INTERRUPT_LINE to select
> which I8259 IRQ to use.
> 
> > loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends
> > on firmware having previously programmed it, right?
> 
> I'm unclear about what did firmware do but as AMD RS780E is used in
> x86 PCs as well it should be the same way.

PCI devices don't use the value in PCI_INTERRUPT_LINE, and the spec
doesn't define a default value.  It's only for use by software.

I'm pretty sure that on ACPI x86, we don't depend on
PCI_INTERRUPT_LINE except for things like quirks.

I think the ACPI MADT and _PRT are supposed to contain all the INTx
routing information we need.  Obviously this isn't an ACPI system.
I'm just making the point that it *should* be possible to remove this
dependency on firmware if we can identify the specific platform (which
determines the I8259 routing).

Bjorn


From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:40 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:40 +0100
Subject: [PATCH v2 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-2-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>
---
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: linux-gpio at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 drivers/pinctrl/meson/pinctrl-meson-g12a.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index cd9656b13836..d182a575981e 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -283,6 +283,8 @@ static const unsigned int pwm_d_x6_pins[]		= { GPIOX_6 };
 static const unsigned int pwm_e_pins[]			= { GPIOX_16 };
 
 /* pwm_f */
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_12 };
+static const unsigned int pwm_f_a_pins[]		= { GPIOA_11 };
 static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
 static const unsigned int pwm_f_h_pins[]		= { GPIOH_5 };
 
@@ -618,6 +620,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout2_z,		4),
 	GROUP(tdm_c_dout3_z,		4),
 	GROUP(mclk1_z,			4),
+	GROUP(pwm_f_z,			5),
 
 	/* bank GPIOX */
 	GROUP(sdio_d0,			1),
@@ -768,6 +771,7 @@ static struct meson_pmx_group meson_g12a_periphs_groups[] = {
 	GROUP(tdm_c_dout3_a,		2),
 	GROUP(mclk0_a,			1),
 	GROUP(mclk1_a,			2),
+	GROUP(pwm_f_a,			3),
 };
 
 /* uart_ao_a */
@@ -1069,7 +1073,7 @@ static const char * const pwm_e_groups[] = {
 };
 
 static const char * const pwm_f_groups[] = {
-	"pwm_f_x", "pwm_f_h",
+	"pwm_f_z", "pwm_f_a", "pwm_f_x", "pwm_f_h",
 };
 
 static const char * const cec_ao_a_h_groups[] = {
-- 
2.34.1



From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:41 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:41 +0100
Subject: [PATCH v2 2/3] arm64: dts: meson-g12-common: add more pwm_f options
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-3-gary.bisson@boundarydevices.com>

Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>
---
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../arm64/boot/dts/amlogic/meson-g12-common.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 00c6f53290d4..af1357c48bee 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -894,6 +894,22 @@ mux {
 						};
 					};
 
+					pwm_f_z_pins: pwm-f-z {
+						mux {
+							groups = "pwm_f_z";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
+					pwm_f_a_pins: pwm-f-a {
+						mux {
+							groups = "pwm_f_a";
+							function = "pwm_f";
+							bias-disable;
+						};
+					};
+
 					pwm_f_x_pins: pwm-f-x {
 						mux {
 							groups = "pwm_f_x";
-- 
2.34.1



From gary.bisson at boundarydevices.com  Wed Jan 12 13:16:42 2022
From: gary.bisson at boundarydevices.com (Gary Bisson)
Date: Wed, 12 Jan 2022 22:16:42 +0100
Subject: [PATCH v2 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins muxing
In-Reply-To: <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
Message-ID: <20220112211642.2248901-4-gary.bisson@boundarydevices.com>

- RX/TX signals can be mapped on 2 different pairs of pins so supporting
  both options
- RTS/CTS signals however only have 1 option available

Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
---
Changes v1->v2:
- renamed nodes as suggested by Neil

Cc: Rob Herring <robh+dt at kernel.org>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
---
 .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index af1357c48bee..62350c408e16 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1952,6 +1952,33 @@ mux {
 						};
 					};
 
+					uart_ao_b_2_3_pins: uart-ao-b-2-3 {
+						mux {
+							groups = "uart_ao_b_tx_2",
+								 "uart_ao_b_rx_3";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_8_9_pins: uart-ao-b-8-9 {
+						mux {
+							groups = "uart_ao_b_tx_8",
+								 "uart_ao_b_rx_9";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
+					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
+						mux {
+							groups = "uart_ao_b_cts",
+								 "uart_ao_b_rts";
+							function = "uart_ao_b";
+							bias-disable;
+						};
+					};
+
 					pwm_a_e_pins: pwm-a-e {
 						mux {
 							groups = "pwm_a_e";
-- 
2.34.1



From lkp at intel.com  Wed Jan 12 13:47:46 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 05:47:46 +0800
Subject: [xilinx-xlnx:master 248/326] include/linux/mtd/cfi.h:62:2: warning:
 #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
Message-ID: <202201130520.jQUd0BWN-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 9b62852ec04b7d48971ce8016b13c27403929908 [248/326] Merge tag 'v5.15' into master
config: arc-randconfig-r043-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130520.jQUd0BWN-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/9b62852ec04b7d48971ce8016b13c27403929908
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 9b62852ec04b7d48971ce8016b13c27403929908
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/linux/mtd/spi-nor.h:10,
                    from drivers/spi/spi-zynqmp-gqspi.c:26:
>> include/linux/mtd/cfi.h:62:2: warning: #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. [-Wcpp]
      62 | #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
         |  ^~~~~~~
   In file included from drivers/spi/spi-zynqmp-gqspi.c:13:
   include/linux/firmware/xlnx-zynqmp.h:1187:12: warning: 'zynqmp_pm_sec_mask_write_reg' defined but not used [-Wunused-function]
    1187 | static int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/firmware/xlnx-zynqmp.h:1182:12: warning: 'zynqmp_pm_sec_read_reg' defined but not used [-Wunused-function]
    1182 | static int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
         |            ^~~~~~~~~~~~~~~~~~~~~~


vim +62 include/linux/mtd/cfi.h

^1da177e4c3f41 Linus Torvalds  2005-04-16  60  
241651d04d672f David Woodhouse 2007-09-06  61  #ifndef cfi_interleave
241651d04d672f David Woodhouse 2007-09-06 @62  #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
241651d04d672f David Woodhouse 2007-09-06  63  static inline int cfi_interleave(void *cfi)
241651d04d672f David Woodhouse 2007-09-06  64  {
241651d04d672f David Woodhouse 2007-09-06  65  	BUG();
241651d04d672f David Woodhouse 2007-09-06  66  	return 0;
241651d04d672f David Woodhouse 2007-09-06  67  }
241651d04d672f David Woodhouse 2007-09-06  68  #endif
241651d04d672f David Woodhouse 2007-09-06  69  

:::::: The code at line 62 was first introduced by commit
:::::: 241651d04d672fb685b2874707016cbbf95931e5 [MTD] Fix CFI build error when no map width or interleave supported

:::::: TO: David Woodhouse <dwmw2 at infradead.org>
:::::: CC: David Woodhouse <dwmw2 at infradead.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From jammy_huang at aspeedtech.com  Tue Jan 11 22:07:25 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 12 Jan 2022 14:07:25 +0800
Subject: [PATCH v2] media: aspeed: Fix no complete irq for non-64-aligned width
Message-ID: <20220112060725.13751-1-jammy_huang@aspeedtech.com>

In ast2500, engine will stop occasionally for 1360x768.

This is a bug which has been addressed, but the workaround is specific
for 1680 only. Here we make it more complete.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 drivers/media/platform/aspeed-video.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 4c75dc58a33c..4f5f5dd364ee 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -1068,18 +1068,19 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
 	/* Set capture/compression frame sizes */
 	aspeed_video_calc_compressed_size(video, size);
 
-	if (video->active_timings.width == 1680) {
+	if (!IS_ALIGNED(act->width, 64)) {
 		/*
-		 * This is a workaround to fix a silicon bug on A1 and A2
-		 * revisions. Since it doesn't break capturing operation of
+		 * This is a workaround to fix a AST2500 silicon bug on A1 and
+		 * A2 revisions. Since it doesn't break capturing operation of
 		 * other revisions, use it for all revisions without checking
-		 * the revision ID. It picked 1728 which is a very next
-		 * 64-pixels aligned value to 1680 to minimize memory bandwidth
+		 * the revision ID. It picked new width which is a very next
+		 * 64-pixels aligned value to minimize memory bandwidth
 		 * and to get better access speed from video engine.
 		 */
-		aspeed_video_write(video, VE_CAP_WINDOW,
-				   1728 << 16 | act->height);
-		size += (1728 - 1680) * video->active_timings.height;
+		u32 width = ALIGN(act->width, 64);
+
+		aspeed_video_write(video, VE_CAP_WINDOW, width << 16 | act->height);
+		size = width * act->height;
 	} else {
 		aspeed_video_write(video, VE_CAP_WINDOW,
 				   act->width << 16 | act->height);
-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 11 22:05:41 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 12 Jan 2022 14:05:41 +0800
Subject: [PATCH] media: aspeed: Fix no complete irq for non-64-aligned
 width
In-Reply-To: <CACPK8XfkXi6M=gzfkYcuoga6WxnzSm2+mspBt4gjop7Ytm+VCA@mail.gmail.com>
References: <20211214045348.13702-1-jammy_huang@aspeedtech.com>
 <CACPK8XfkXi6M=gzfkYcuoga6WxnzSm2+mspBt4gjop7Ytm+VCA@mail.gmail.com>
Message-ID: <a779f1c1-e5b0-5d55-bc6c-5f253d03525d@aspeedtech.com>

Hi Joel,

OK, thanks for your review. I will send another updated patch per your 
advice.

On 2022/1/12 ?? 08:51, Joel Stanley wrote:
> On Tue, 14 Dec 2021 at 04:53, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>> In ast2500, engine will stop occasionally for 1360x768.
>>
>> This is a bug which has been addressed, but the workaround is specific
>> for 1680 only. Here we make it more complete.
>>
>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>> ---
>>   drivers/media/platform/aspeed-video.c | 12 +++++++-----
>>   1 file changed, 7 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>> index 793b2adaa0f5..4d3e6b105d44 100644
>> --- a/drivers/media/platform/aspeed-video.c
>> +++ b/drivers/media/platform/aspeed-video.c
>> @@ -1055,18 +1055,20 @@ static void aspeed_video_set_resolution(struct aspeed_video *video)
>>          /* Set capture/compression frame sizes */
>>          aspeed_video_calc_compressed_size(video, size);
>>
>> -       if (video->active_timings.width == 1680) {
>> +       if (!IS_ALIGNED(act->width, 64)) {
>>                  /*
>>                   * This is a workaround to fix a silicon bug on A1 and A2
> Please add:  "a AST2500 silicon bug" so we know which A1/A2 this is
> referring to.
>
> With that added, you can add:
>
>   Reviewed-by: Joel Stanley <joel at jms.id.au>
>
>>                   * revisions. Since it doesn't break capturing operation of
>>                   * other revisions, use it for all revisions without checking
>> -                * the revision ID. It picked 1728 which is a very next
>> -                * 64-pixels aligned value to 1680 to minimize memory bandwidth
>> +                * the revision ID. It picked new width which is a very next
>> +                * 64-pixels aligned value to minimize memory bandwidth
>>                   * and to get better access speed from video engine.
>>                   */
>> +               u32 width = ALIGN(act->width, 64);
>> +
>>                  aspeed_video_write(video, VE_CAP_WINDOW,
>> -                                  1728 << 16 | act->height);
>> -               size += (1728 - 1680) * video->active_timings.height;
>> +                                  width << 16 | act->height);
>> +               size = width * act->height;
> You could make it clearer by putting the write on one line:
>
>                  aspeed_video_write(video, VE_CAP_WINDOW, width << 16 |
> act->height);

-- 
Best Regards
Jammy



From lkp at intel.com  Wed Jan 12 14:38:50 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 06:38:50 +0800
Subject: [xilinx-xlnx:master 269/326]
 include/linux/firmware/xlnx-zynqmp.h:1244:5: warning: no previous prototype
 for 'zynqmp_pm_get_meta_header'
Message-ID: <202201130615.SDjeIfek-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 22272cc48b5399af99792722fa7004735b769e0a [269/326] firmware: xilinx: Add support to get the image meta-header info
config: arc-randconfig-r043-20220112 (https://download.01.org/0day-ci/archive/20220113/202201130615.SDjeIfek-lkp at intel.com/config)
compiler: arceb-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/22272cc48b5399af99792722fa7004735b769e0a
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 22272cc48b5399af99792722fa7004735b769e0a
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/spi/spi-zynqmp-gqspi.c:13:
>> include/linux/firmware/xlnx-zynqmp.h:1244:5: warning: no previous prototype for 'zynqmp_pm_get_meta_header' [-Wmissing-prototypes]
    1244 | int zynqmp_pm_get_meta_header(const u64 src, const u64 dst,
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/mtd/spi-nor.h:10,
                    from drivers/spi/spi-zynqmp-gqspi.c:26:
   include/linux/mtd/cfi.h:62:2: warning: #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. [-Wcpp]
      62 | #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
         |  ^~~~~~~
   In file included from drivers/spi/spi-zynqmp-gqspi.c:13:
   include/linux/firmware/xlnx-zynqmp.h:1217:12: warning: 'zynqmp_pm_sec_mask_write_reg' defined but not used [-Wunused-function]
    1217 | static int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
         |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/firmware/xlnx-zynqmp.h:1212:12: warning: 'zynqmp_pm_sec_read_reg' defined but not used [-Wunused-function]
    1212 | static int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
         |            ^~~~~~~~~~~~~~~~~~~~~~


vim +/zynqmp_pm_get_meta_header +1244 include/linux/firmware/xlnx-zynqmp.h

  1243	
> 1244	int zynqmp_pm_get_meta_header(const u64 src, const u64 dst,
  1245				      const u32 size, u32 *count)
  1246	{
  1247		return -ENODEV;
  1248	}
  1249	#endif
  1250	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From iwona.winiarska at intel.com  Wed Jan 12 15:02:34 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:34 +0100
Subject: [PATCH v5 00/13] Introduce PECI subsystem
Message-ID: <20220112230247.982212-1-iwona.winiarska@intel.com>

Hi!

Changes in this revision are limited to peci-aspeed controller driver
and its DTS schema (except small cosmetic change in peci-dimmtemp
hwmon).
Major change is related to clock programming - common clock framework
is now used in peci-aspeed.
This required appropriate changes in peci-aspeed DTS schema. The
properties that had impact on clock programming were removed and
replaced with "clock-frequency", which is simply passed to
clk_aspeed_peci.
Additionally, "aspeed,rd-sampling-point" was removed. The driver is
now just using a default value. DTS property can be reintroduced in
the future if needed.

Here is the usual cover letter from the previous revision:

The Platform Environment Control Interface (PECI) is a communication
interface between Intel processors and management controllers (e.g.
Baseboard Management Controller, BMC).

This series adds a PECI subsystem and introduces drivers which run in
the Linux instance on the management controller (not the main Intel
processor) and is intended to be used by the OpenBMC [1], a Linux
distribution for BMC devices.
The information exposed over PECI (like processor and DIMM
temperature) refers to the Intel processor and can be consumed by
daemons running on the BMC to, for example, display the processor
temperature in its web interface.

The PECI bus is collection of code that provides interface support
between PECI devices (that actually represent processors) and PECI
controllers (such as the "peci-aspeed" controller) that allow to
access physical PECI interface. PECI devices are bound to PECI
drivers that provides access to PECI services. This series introduces
a generic "peci-cpu" driver that exposes hardware monitoring "cputemp"
and "dimmtemp" using the auxiliary bus.

Exposing "raw" PECI to userspace, either to write userspace drivers or
for debug/testing purpose was left out of this series to encourage
writing kernel drivers instead, but may be pursued in the future.

Introducing PECI to upstream Linux was already attempted before [2].
Since it's been over a year since last revision, and the series
changed quite a bit in the meantime, I've decided to start from v1.

I would also like to give credit to everyone who helped me with
different aspects of preliminary review:
- Pierre-Louis Bossart,
- Tony Luck, 
- Andy Shevchenko,
- Dave Hansen.

[1] https://github.com/openbmc/openbmc
[2] https://lore.kernel.org/openbmc/20191211194624.2872-1-jae.hyun.yoo at linux.intel.com/

Changes v4 -> v5:
* Added clk_aspeed_peci to express controller programming using common
  clock framework (Billy)
* Modified peci-aspeed DTS schema to match clock changes (Billy)
* Added workaround for peci-aspeed controller hang (Billy)
* Removed unnecessary "else after return" (Guenter)

Changes v3 -> v4:
* Fixed an issue where peci doesn't work after host shutdown (Zev)
* Replaced kill_device() with peci_device_del_lock (Greg)
* Fixed dts_valid() parameter type (Guenter)
* Removed Jae from MAINTAINERS file (Jae)

Changes v2 -> v3:

* Dropped x86/cpu patches (Boris)
* Dropped pr_fmt() for PECI module (Dan)
* Fixed releasing peci controller device flow (Dan) 
* Improved peci-aspeed commit-msg and Kconfig help (Dan)
* Fixed aspeed_peci_xfer() to use the proper spin_lock function (Dan) 
* Wrapped print_hex_dump_bytes() in CONFIG_DYNAMIC_DEBUG (Dan)
* Removed debug status logs from aspeed_peci_irq_handler() (Dan)
* Renamed functions using devres to start with "devm" (Dan)
* Changed request to be allocated on stack in peci_detect (Dan)
* Removed redundant WARN_ON on invalid PECI addr (Dan)
* Changed peci_device_create() to use device_initialize() + device_add() pattern (Dan)
* Fixed peci_device_destroy() to use kill_device() avoiding double-free (Dan)
* Renamed functions that perform xfer using "peci_xfer_*" prefix (Dan) 
* Renamed peci_request_data_dib(temp) -> peci_request_dib(temp)_read (Dan)
* Fixed thermal margin readings for older Intel processors (Zev) 
* Misc hwmon simplifications (Guenter)
* Used BIT_PER_TYPE to verify macro value constrains (Guenter)
* Improved WARN_ON message to print chan_rank_max and idx_dimm_max (Guenter)
* Improved dimmtemp to not reattempt probe if no dimms are populated

Changes v1 -> v2:

Biggest changes when it comes to diffstat are locking in HWMON
(I decided to clean things up a bit while adding it), switching to
devres usage in more places and exposing sysfs interface in separate patch.

* Moved extending X86 ARCHITECTURE MAINTAINERS earlier in series (Dan)
* Removed "default n" for GENERIC_LIB_X86 (Dan)
* Added vendor prefix for peci-aspeed specific properties (Rob)
* Refactored PECI to use devres consistently (Dan)
* Added missing sysfs documentation and excluded adding peci-sysfs to
  separate patch (Dan)
* Used module_init() instead of subsys_init() for peci module initialization (Dan)
* Removed redundant struct peci_device member (Dan)
* Improved PECI Kconfig help (Randy/Dan)
* Fixed/removed log messages (Dan, Guenter)
* Refactored peci-cputemp and peci-dimmtemp and added missing locks (Guenter)
* Removed unused dev_set_drvdata() in peci-cputemp and peci-dimmtemp (Guenter)
* Fixed used types, names, fixed broken and added additional comments
  to peci-hwmon (Guenter, Zev)
* Refactored peci-dimmtemp to not return -ETIMEDOUT (Guenter)
* Added sanity check for min_peci_revision in peci-hwmon drivers (Zev)
* Added assert for DIMM_NUMS_MAX and additional warning in peci-dimmtemp (Zev)
* Fixed macro names in peci-aspeed (Zev)
* Refactored peci-aspeed sanitizing properties to a single helper function (Zev)
* Fixed peci_cpu_device_ids definition for Broadwell Xeon D (David)
* Refactor peci_request to use a single allocation (Zev)
* Used min_t() to improve code readability (Zev)
* Added macro for PECI_RDENDPTCFG_MMIO_WR_LEN_BASE and fixed adev type
  array name to more descriptive (Zev)
* Fixed peci-hwmon commit-msg and documentation (Zev)

Thanks
-Iwona

Iwona Winiarska (11):
  dt-bindings: Add generic bindings for PECI
  dt-bindings: Add bindings for peci-aspeed
  ARM: dts: aspeed: Add PECI controller nodes
  peci: Add core infrastructure
  peci: Add device detection
  peci: Add sysfs interface for PECI bus
  peci: Add support for PECI device drivers
  peci: Add peci-cpu driver
  hwmon: peci: Add cputemp driver
  hwmon: peci: Add dimmtemp driver
  docs: Add PECI documentation

Jae Hyun Yoo (2):
  peci: Add peci-aspeed controller driver
  docs: hwmon: Document PECI drivers

 Documentation/ABI/testing/sysfs-bus-peci      |  16 +
 .../devicetree/bindings/peci/peci-aspeed.yaml |  72 ++
 .../bindings/peci/peci-controller.yaml        |  33 +
 Documentation/hwmon/index.rst                 |   2 +
 Documentation/hwmon/peci-cputemp.rst          |  90 +++
 Documentation/hwmon/peci-dimmtemp.rst         |  57 ++
 Documentation/index.rst                       |   1 +
 Documentation/peci/index.rst                  |  16 +
 Documentation/peci/peci.rst                   |  51 ++
 MAINTAINERS                                   |  26 +
 arch/arm/boot/dts/aspeed-g4.dtsi              |  11 +
 arch/arm/boot/dts/aspeed-g5.dtsi              |  11 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  11 +
 drivers/Kconfig                               |   3 +
 drivers/Makefile                              |   1 +
 drivers/hwmon/Kconfig                         |   2 +
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/peci/Kconfig                    |  31 +
 drivers/hwmon/peci/Makefile                   |   7 +
 drivers/hwmon/peci/common.h                   |  58 ++
 drivers/hwmon/peci/cputemp.c                  | 592 ++++++++++++++++
 drivers/hwmon/peci/dimmtemp.c                 | 630 ++++++++++++++++++
 drivers/peci/Kconfig                          |  36 +
 drivers/peci/Makefile                         |  10 +
 drivers/peci/controller/Kconfig               |  17 +
 drivers/peci/controller/Makefile              |   3 +
 drivers/peci/controller/peci-aspeed.c         | 584 ++++++++++++++++
 drivers/peci/core.c                           | 236 +++++++
 drivers/peci/cpu.c                            | 343 ++++++++++
 drivers/peci/device.c                         | 252 +++++++
 drivers/peci/internal.h                       | 136 ++++
 drivers/peci/request.c                        | 482 ++++++++++++++
 drivers/peci/sysfs.c                          |  82 +++
 include/linux/peci-cpu.h                      |  40 ++
 include/linux/peci.h                          | 112 ++++
 35 files changed, 4055 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c
 create mode 100644 drivers/hwmon/peci/dimmtemp.c
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 drivers/peci/request.c
 create mode 100644 drivers/peci/sysfs.c
 create mode 100644 include/linux/peci-cpu.h
 create mode 100644 include/linux/peci.h

-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:35 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:35 +0100
Subject: [PATCH v5 01/13] dt-bindings: Add generic bindings for PECI
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-2-iwona.winiarska@intel.com>

Add device tree bindings for the PECI controller.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/peci/peci-controller.yaml        | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-controller.yaml b/Documentation/devicetree/bindings/peci/peci-controller.yaml
new file mode 100644
index 000000000000..bbc3d3f3a929
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-controller.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic Device Tree Bindings for PECI
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+
+description:
+  PECI (Platform Environment Control Interface) is an interface that provides a
+  communication channel from Intel processors and chipset components to external
+  monitoring or control devices.
+
+properties:
+  $nodename:
+    pattern: "^peci-controller(@.*)?$"
+
+  cmd-timeout-ms:
+    description:
+      Command timeout in units of ms.
+
+additionalProperties: true
+
+examples:
+  - |
+    peci-controller at 1e78b000 {
+      reg = <0x1e78b000 0x100>;
+      cmd-timeout-ms = <500>;
+    };
+...
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:36 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:36 +0100
Subject: [PATCH v5 02/13] dt-bindings: Add bindings for peci-aspeed
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-3-iwona.winiarska@intel.com>

Add device tree bindings for the peci-aspeed controller driver.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 .../devicetree/bindings/peci/peci-aspeed.yaml | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-aspeed.yaml b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
new file mode 100644
index 000000000000..1e68a801a92a
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-aspeed.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed PECI Bus Device Tree Bindings
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+  - Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+allOf:
+  - $ref: peci-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-peci
+      - aspeed,ast2500-peci
+      - aspeed,ast2600-peci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description:
+      Clock source for PECI controller. Should reference the external
+      oscillator clock.
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  cmd-timeout-ms:
+    minimum: 1
+    maximum: 1000
+    default: 1000
+
+  clock-frequency:
+    description:
+      The desired operation frequency of PECI controller in Hz.
+    minimum: 2000
+    maximum: 2000000
+    default: 1000000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+    peci-controller at 1e78b000 {
+      compatible = "aspeed,ast2600-peci";
+      reg = <0x1e78b000 0x100>;
+      interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+      resets = <&syscon ASPEED_RESET_PECI>;
+      cmd-timeout-ms = <1000>;
+      clock-frequency = <1000000>;
+    };
+...
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:37 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:37 +0100
Subject: [PATCH v5 03/13] ARM: dts: aspeed: Add PECI controller nodes
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-4-iwona.winiarska@intel.com>

Add PECI controller nodes with all required information.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 11 +++++++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 11 +++++++++++
 arch/arm/boot/dts/aspeed-g6.dtsi | 11 +++++++++++
 3 files changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index b313a1cf5f73..3c2961da6272 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -391,6 +391,17 @@ uart_routing: uart-routing at 9c {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2400-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index c7049454c7cb..aab1c3ecb4dc 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -511,6 +511,17 @@ ibt: ibt at 140 {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2500-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index 5106a424f1ce..564f1292993f 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -507,6 +507,17 @@ wdt4: watchdog at 1e7850c0 {
 				status = "disabled";
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2600-peci";
+				reg = <0x1e78b000 0x100>;
+				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			lpc: lpc at 1e789000 {
 				compatible = "aspeed,ast2600-lpc-v2", "simple-mfd", "syscon";
 				reg = <0x1e789000 0x1000>;
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:38 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:38 +0100
Subject: [PATCH v5 04/13] peci: Add core infrastructure
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-5-iwona.winiarska@intel.com>

Intel processors provide access for various services designed to support
processor and DRAM thermal management, platform manageability and
processor interface tuning and diagnostics.
Those services are available via the Platform Environment Control
Interface (PECI) that provides a communication channel between the
processor and the Baseboard Management Controller (BMC) or other
platform management device.

This change introduces PECI subsystem by adding the initial core module
and API for controller drivers.

Co-developed-by: Jason M Bills <jason.m.bills at linux.intel.com>
Signed-off-by: Jason M Bills <jason.m.bills at linux.intel.com>
Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS             |   8 ++
 drivers/Kconfig         |   3 +
 drivers/Makefile        |   1 +
 drivers/peci/Kconfig    |  15 ++++
 drivers/peci/Makefile   |   5 ++
 drivers/peci/core.c     | 158 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  16 ++++
 include/linux/peci.h    |  99 +++++++++++++++++++++++++
 8 files changed, 305 insertions(+)
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 include/linux/peci.h

diff --git a/MAINTAINERS b/MAINTAINERS
index dd36acc87ce6..3b079e193bf3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14922,6 +14922,14 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI SUBSYSTEM
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/
+F:	drivers/peci/
+F:	include/linux/peci.h
+
 PENSANDO ETHERNET DRIVERS
 M:	Shannon Nelson <snelson at pensando.io>
 M:	drivers at pensando.io
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 0d399ddaa185..8d6cd5d08722 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -236,4 +236,7 @@ source "drivers/interconnect/Kconfig"
 source "drivers/counter/Kconfig"
 
 source "drivers/most/Kconfig"
+
+source "drivers/peci/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..020780b6b4d2 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -187,3 +187,4 @@ obj-$(CONFIG_GNSS)		+= gnss/
 obj-$(CONFIG_INTERCONNECT)	+= interconnect/
 obj-$(CONFIG_COUNTER)		+= counter/
 obj-$(CONFIG_MOST)		+= most/
+obj-$(CONFIG_PECI)		+= peci/
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
new file mode 100644
index 000000000000..71a4ad81225a
--- /dev/null
+++ b/drivers/peci/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig PECI
+	tristate "PECI support"
+	help
+	  The Platform Environment Control Interface (PECI) is an interface
+	  that provides a communication channel to Intel processors and
+	  chipset components from external monitoring or control devices.
+
+	  If you are building a Baseboard Management Controller (BMC) kernel
+	  for Intel platform say Y here and also to the specific driver for
+	  your adapter(s) below. If unsure say N.
+
+	  This support is also available as a module. If so, the module
+	  will be called peci.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
new file mode 100644
index 000000000000..e789a354e842
--- /dev/null
+++ b/drivers/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Core functionality
+peci-y := core.o
+obj-$(CONFIG_PECI) += peci.o
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
new file mode 100644
index 000000000000..73ad0a47fa9d
--- /dev/null
+++ b/drivers/peci/core.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/idr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+static DEFINE_IDA(peci_controller_ida);
+
+static void peci_controller_dev_release(struct device *dev)
+{
+	struct peci_controller *controller = to_peci_controller(dev);
+
+	mutex_destroy(&controller->bus_lock);
+	ida_free(&peci_controller_ida, controller->id);
+	kfree(controller);
+}
+
+struct device_type peci_controller_type = {
+	.release	= peci_controller_dev_release,
+};
+
+static struct peci_controller *peci_controller_alloc(struct device *dev,
+						     struct peci_controller_ops *ops)
+{
+	struct peci_controller *controller;
+	int ret;
+
+	if (!ops->xfer)
+		return ERR_PTR(-EINVAL);
+
+	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return ERR_PTR(-ENOMEM);
+
+	ret = ida_alloc_max(&peci_controller_ida, U8_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err;
+	controller->id = ret;
+
+	controller->ops = ops;
+
+	controller->dev.parent = dev;
+	controller->dev.bus = &peci_bus_type;
+	controller->dev.type = &peci_controller_type;
+
+	device_initialize(&controller->dev);
+
+	mutex_init(&controller->bus_lock);
+
+	return controller;
+
+err:
+	kfree(controller);
+	return ERR_PTR(ret);
+}
+
+static void unregister_controller(void *_controller)
+{
+	struct peci_controller *controller = _controller;
+
+	device_unregister(&controller->dev);
+
+	fwnode_handle_put(controller->dev.fwnode);
+
+	pm_runtime_disable(&controller->dev);
+}
+
+/**
+ * devm_peci_controller_add() - add PECI controller
+ * @dev: device for devm operations
+ * @ops: pointer to controller specific methods
+ *
+ * In final stage of its probe(), peci_controller driver calls
+ * devm_peci_controller_add() to register itself with the PECI bus.
+ *
+ * Return: Pointer to the newly allocated controller or ERR_PTR() in case of failure.
+ */
+struct peci_controller *devm_peci_controller_add(struct device *dev,
+						 struct peci_controller_ops *ops)
+{
+	struct peci_controller *controller;
+	int ret;
+
+	controller = peci_controller_alloc(dev, ops);
+	if (IS_ERR(controller))
+		return controller;
+
+	ret = dev_set_name(&controller->dev, "peci-%d", controller->id);
+	if (ret)
+		goto err_put;
+
+	pm_runtime_no_callbacks(&controller->dev);
+	pm_suspend_ignore_children(&controller->dev, true);
+	pm_runtime_enable(&controller->dev);
+
+	device_set_node(&controller->dev, fwnode_handle_get(dev_fwnode(dev)));
+
+	ret = device_add(&controller->dev);
+	if (ret)
+		goto err_fwnode;
+
+	ret = devm_add_action_or_reset(dev, unregister_controller, controller);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return controller;
+
+err_fwnode:
+	fwnode_handle_put(controller->dev.fwnode);
+
+	pm_runtime_disable(&controller->dev);
+
+err_put:
+	put_device(&controller->dev);
+
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
+
+struct bus_type peci_bus_type = {
+	.name		= "peci",
+};
+
+static int __init peci_init(void)
+{
+	int ret;
+
+	ret = bus_register(&peci_bus_type);
+	if (ret < 0) {
+		pr_err("peci: failed to register PECI bus type!\n");
+		return ret;
+	}
+
+	return 0;
+}
+module_init(peci_init);
+
+static void __exit peci_exit(void)
+{
+	bus_unregister(&peci_bus_type);
+}
+module_exit(peci_exit);
+
+MODULE_AUTHOR("Jason M Bills <jason.m.bills at linux.intel.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI bus core module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
new file mode 100644
index 000000000000..918dea745a86
--- /dev/null
+++ b/drivers/peci/internal.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __PECI_INTERNAL_H
+#define __PECI_INTERNAL_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+struct peci_controller;
+
+extern struct bus_type peci_bus_type;
+
+extern struct device_type peci_controller_type;
+
+#endif /* __PECI_INTERNAL_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
new file mode 100644
index 000000000000..26e0a4e73b50
--- /dev/null
+++ b/include/linux/peci.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_H
+#define __LINUX_PECI_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+/*
+ * Currently we don't support any PECI command over 32 bytes.
+ */
+#define PECI_REQUEST_MAX_BUF_SIZE 32
+
+struct peci_controller;
+struct peci_request;
+
+/**
+ * struct peci_controller_ops - PECI controller specific methods
+ * @xfer: PECI transfer function
+ *
+ * PECI controllers may have different hardware interfaces - the drivers
+ * implementing PECI controllers can use this structure to abstract away those
+ * differences by exposing a common interface for PECI core.
+ */
+struct peci_controller_ops {
+	int (*xfer)(struct peci_controller *controller, u8 addr, struct peci_request *req);
+};
+
+/**
+ * struct peci_controller - PECI controller
+ * @dev: device object to register PECI controller to the device model
+ * @ops: pointer to device specific controller operations
+ * @bus_lock: lock used to protect multiple callers
+ * @id: PECI controller ID
+ *
+ * PECI controllers usually connect to their drivers using non-PECI bus,
+ * such as the platform bus.
+ * Each PECI controller can communicate with one or more PECI devices.
+ */
+struct peci_controller {
+	struct device dev;
+	struct peci_controller_ops *ops;
+	struct mutex bus_lock; /* held for the duration of xfer */
+	u8 id;
+};
+
+struct peci_controller *devm_peci_controller_add(struct device *parent,
+						 struct peci_controller_ops *ops);
+
+static inline struct peci_controller *to_peci_controller(void *d)
+{
+	return container_of(d, struct peci_controller, dev);
+}
+
+/**
+ * struct peci_device - PECI device
+ * @dev: device object to register PECI device to the device model
+ * @controller: manages the bus segment hosting this PECI device
+ * @addr: address used on the PECI bus connected to the parent controller
+ *
+ * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
+ * The behaviour exposed to the rest of the system is defined by the PECI driver
+ * managing the device.
+ */
+struct peci_device {
+	struct device dev;
+	u8 addr;
+};
+
+static inline struct peci_device *to_peci_device(struct device *d)
+{
+	return container_of(d, struct peci_device, dev);
+}
+
+/**
+ * struct peci_request - PECI request
+ * @device: PECI device to which the request is sent
+ * @tx: TX buffer specific data
+ * @tx.buf: TX buffer
+ * @tx.len: transfer data length in bytes
+ * @rx: RX buffer specific data
+ * @rx.buf: RX buffer
+ * @rx.len: received data length in bytes
+ *
+ * A peci_request represents a request issued by PECI originator (TX) and
+ * a response received from PECI responder (RX).
+ */
+struct peci_request {
+	struct peci_device *device;
+	struct {
+		u8 buf[PECI_REQUEST_MAX_BUF_SIZE];
+		u8 len;
+	} rx, tx;
+};
+
+#endif /* __LINUX_PECI_H */
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:39 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:39 +0100
Subject: [PATCH v5 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-6-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

ASPEED AST24xx/AST25xx/AST26xx SoCs support the PECI electrical
interface (a.k.a PECI wire) that provides a communication channel with
Intel processors.
This driver allows BMC to discover devices connected to it and
communicate with them using PECI protocol.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS                           |   8 +
 drivers/peci/Kconfig                  |   6 +
 drivers/peci/Makefile                 |   3 +
 drivers/peci/controller/Kconfig       |  17 +
 drivers/peci/controller/Makefile      |   3 +
 drivers/peci/controller/peci-aspeed.c | 584 ++++++++++++++++++++++++++
 6 files changed, 621 insertions(+)
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3b079e193bf3..6564c3b58c83 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2955,6 +2955,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/asix,ax88796c.yaml
 F:	drivers/net/ethernet/asix/ax88796c_*
 
+ASPEED PECI CONTROLLER
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/peci-aspeed.yaml
+F:	drivers/peci/controller/peci-aspeed.c
+
 ASPEED PINCTRL DRIVERS
 M:	Andrew Jeffery <andrew at aj.id.au>
 L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 71a4ad81225a..99279df97a78 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -13,3 +13,9 @@ menuconfig PECI
 
 	  This support is also available as a module. If so, the module
 	  will be called peci.
+
+if PECI
+
+source "drivers/peci/controller/Kconfig"
+
+endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index e789a354e842..926d8df15cbd 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,3 +3,6 @@
 # Core functionality
 peci-y := core.o
 obj-$(CONFIG_PECI) += peci.o
+
+# Hardware specific bus drivers
+obj-y += controller/
diff --git a/drivers/peci/controller/Kconfig b/drivers/peci/controller/Kconfig
new file mode 100644
index 000000000000..3008b1b81049
--- /dev/null
+++ b/drivers/peci/controller/Kconfig
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PECI_ASPEED
+	tristate "ASPEED PECI support"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on OF
+	depends on HAS_IOMEM
+	help
+	  This option enables PECI controller driver for ASPEED AST2400,
+	  AST2500 and AST2600 SoCs. It allows BMC to discover devices
+	  connected to it, and communicate with them using PECI protocol.
+
+	  Say Y here if your system runs on ASPEED SoC and you are using it
+	  as BMC for Intel platform.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called peci-aspeed.
diff --git a/drivers/peci/controller/Makefile b/drivers/peci/controller/Makefile
new file mode 100644
index 000000000000..022c28ef1bf0
--- /dev/null
+++ b/drivers/peci/controller/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PECI_ASPEED)	+= peci-aspeed.o
diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c
new file mode 100644
index 000000000000..51b3d059e2eb
--- /dev/null
+++ b/drivers/peci/controller/peci-aspeed.c
@@ -0,0 +1,584 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2012-2017 ASPEED Technology Inc.
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/jiffies.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* ASPEED PECI Registers */
+/* Control Register */
+#define ASPEED_PECI_CTRL			0x00
+#define   ASPEED_PECI_CTRL_SAMPLING_MASK	GENMASK(19, 16)
+#define   ASPEED_PECI_CTRL_RD_MODE_MASK		GENMASK(13, 12)
+#define     ASPEED_PECI_CTRL_RD_MODE_DBG	BIT(13)
+#define     ASPEED_PECI_CTRL_RD_MODE_COUNT	BIT(12)
+#define   ASPEED_PECI_CTRL_CLK_SRC_HCLK		BIT(11)
+#define   ASPEED_PECI_CTRL_CLK_DIV_MASK		GENMASK(10, 8)
+#define   ASPEED_PECI_CTRL_INVERT_OUT		BIT(7)
+#define   ASPEED_PECI_CTRL_INVERT_IN		BIT(6)
+#define   ASPEED_PECI_CTRL_BUS_CONTENTION_EN	BIT(5)
+#define   ASPEED_PECI_CTRL_PECI_EN		BIT(4)
+#define   ASPEED_PECI_CTRL_PECI_CLK_EN		BIT(0)
+
+/* Timing Negotiation Register */
+#define ASPEED_PECI_TIMING_NEGOTIATION		0x04
+#define   ASPEED_PECI_T_NEGO_MSG_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_T_NEGO_ADDR_MASK		GENMASK(7, 0)
+
+/* Command Register */
+#define ASPEED_PECI_CMD				0x08
+#define   ASPEED_PECI_CMD_PIN_MONITORING	BIT(31)
+#define   ASPEED_PECI_CMD_STS_MASK		GENMASK(27, 24)
+#define     ASPEED_PECI_CMD_STS_ADDR_T_NEGO	0x3
+#define   ASPEED_PECI_CMD_IDLE_MASK		\
+	  (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
+#define   ASPEED_PECI_CMD_FIRE			BIT(0)
+
+/* Read/Write Length Register */
+#define ASPEED_PECI_RW_LENGTH			0x0c
+#define   ASPEED_PECI_AW_FCS_EN			BIT(31)
+#define   ASPEED_PECI_RD_LEN_MASK		GENMASK(23, 16)
+#define   ASPEED_PECI_WR_LEN_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_TARGET_ADDR_MASK		GENMASK(7, 0)
+
+/* Expected FCS Data Register */
+#define ASPEED_PECI_EXPECTED_FCS		0x10
+#define   ASPEED_PECI_EXPECTED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK	GENMASK(15, 8)
+#define   ASPEED_PECI_EXPECTED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Captured FCS Data Register */
+#define ASPEED_PECI_CAPTURED_FCS		0x14
+#define   ASPEED_PECI_CAPTURED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_CAPTURED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Interrupt Register */
+#define ASPEED_PECI_INT_CTRL			0x18
+#define   ASPEED_PECI_TIMING_NEGO_SEL_MASK	GENMASK(31, 30)
+#define     ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO	0
+#define     ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO	1
+#define     ASPEED_PECI_MESSAGE_NEGO		2
+#define   ASPEED_PECI_INT_MASK			GENMASK(4, 0)
+#define     ASPEED_PECI_INT_BUS_TIMEOUT		BIT(4)
+#define     ASPEED_PECI_INT_BUS_CONTENTION	BIT(3)
+#define     ASPEED_PECI_INT_WR_FCS_BAD		BIT(2)
+#define     ASPEED_PECI_INT_WR_FCS_ABORT	BIT(1)
+#define     ASPEED_PECI_INT_CMD_DONE		BIT(0)
+
+/* Interrupt Status Register */
+#define ASPEED_PECI_INT_STS			0x1c
+#define   ASPEED_PECI_INT_TIMING_RESULT_MASK	GENMASK(29, 16)
+	  /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
+
+/* Rx/Tx Data Buffer Registers */
+#define ASPEED_PECI_WR_DATA0			0x20
+#define ASPEED_PECI_WR_DATA1			0x24
+#define ASPEED_PECI_WR_DATA2			0x28
+#define ASPEED_PECI_WR_DATA3			0x2c
+#define ASPEED_PECI_RD_DATA0			0x30
+#define ASPEED_PECI_RD_DATA1			0x34
+#define ASPEED_PECI_RD_DATA2			0x38
+#define ASPEED_PECI_RD_DATA3			0x3c
+#define ASPEED_PECI_WR_DATA4			0x40
+#define ASPEED_PECI_WR_DATA5			0x44
+#define ASPEED_PECI_WR_DATA6			0x48
+#define ASPEED_PECI_WR_DATA7			0x4c
+#define ASPEED_PECI_RD_DATA4			0x50
+#define ASPEED_PECI_RD_DATA5			0x54
+#define ASPEED_PECI_RD_DATA6			0x58
+#define ASPEED_PECI_RD_DATA7			0x5c
+#define   ASPEED_PECI_DATA_BUF_SIZE_MAX		32
+
+/* Timing Negotiation */
+#define ASPEED_PECI_CLK_FREQUENCY_MIN		2000
+#define ASPEED_PECI_CLK_FREQUENCY_DEFAULT	1000000
+#define ASPEED_PECI_CLK_FREQUENCY_MAX		2000000
+#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT	8
+/* Timeout */
+#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_US	(50 * USEC_PER_MSEC)
+#define ASPEED_PECI_IDLE_CHECK_INTERVAL_US	(10 * USEC_PER_MSEC)
+#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT	1000
+#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX		1000
+
+#define ASPEED_PECI_CLK_DIV1(msg_timing) (4 * (msg_timing) + 1)
+#define ASPEED_PECI_CLK_DIV2(clk_div_exp) BIT(clk_div_exp)
+#define ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp) \
+	(4 * ASPEED_PECI_CLK_DIV1(msg_timing) * ASPEED_PECI_CLK_DIV2(clk_div_exp))
+
+struct aspeed_peci {
+	struct peci_controller *controller;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *rst;
+	int irq;
+	spinlock_t lock; /* to sync completion status handling */
+	struct completion xfer_complete;
+	struct clk *clk;
+	u32 clk_frequency;
+	u32 status;
+	u32 cmd_timeout_ms;
+};
+
+struct clk_aspeed_peci {
+	struct clk_hw hw;
+	struct aspeed_peci *aspeed_peci;
+};
+
+static void aspeed_peci_controller_enable(struct aspeed_peci *priv)
+{
+	u32 val = readl(priv->base + ASPEED_PECI_CTRL);
+
+	val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
+	val |= ASPEED_PECI_CTRL_PECI_EN;
+
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+}
+
+static void aspeed_peci_init_regs(struct aspeed_peci *priv)
+{
+	u32 val;
+
+	/* Clear interrupts */
+	val = readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK;
+	writel(val, priv->base + ASPEED_PECI_INT_STS);
+
+	/* Set timing negotiation mode and enable interrupts */
+	val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK, ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
+	val |= ASPEED_PECI_INT_MASK;
+	writel(val, priv->base + ASPEED_PECI_INT_CTRL);
+
+	val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT);
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+}
+
+static int aspeed_peci_check_idle(struct aspeed_peci *priv)
+{
+	u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
+	int ret;
+
+	/*
+	 * Under normal circumstances, we expect to be idle here.
+	 * In case there were any errors/timeouts that led to the situation
+	 * where the hardware is not in idle state - we need to reset and
+	 * reinitialize it to avoid potential controller hang.
+	 */
+	if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts)) {
+		reset_control_assert(priv->rst);
+
+		ret = reset_control_deassert(priv->rst);
+		if (ret) {
+			dev_err(priv->dev, "cannot deassert reset control\n");
+			return ret;
+		}
+
+		aspeed_peci_init_regs(priv);
+
+		ret = clk_set_rate(priv->clk, priv->clk_frequency);
+		if (ret < 0) {
+			dev_err(priv->dev, "cannot set clock frequency\n");
+			return ret;
+		}
+
+		aspeed_peci_controller_enable(priv);
+	}
+
+	return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
+				  cmd_sts,
+				  !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
+				  ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
+				  ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
+}
+
+static int aspeed_peci_xfer(struct peci_controller *controller,
+			    u8 addr, struct peci_request *req)
+{
+	struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
+	unsigned long timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
+	u32 peci_head;
+	int ret;
+
+	if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
+	    req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
+		return -EINVAL;
+
+	/* Check command sts and bus idle state */
+	ret = aspeed_peci_check_idle(priv);
+	if (ret)
+		return ret; /* -ETIMEDOUT */
+
+	spin_lock_irq(&priv->lock);
+	reinit_completion(&priv->xfer_complete);
+
+	peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
+		    FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
+		    FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
+
+	writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
+
+	memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf, min_t(u8, req->tx.len, 16));
+	if (req->tx.len > 16)
+		memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf + 16,
+			    req->tx.len - 16);
+
+#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
+	dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
+	print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req->tx.len);
+#endif
+	priv->status = 0;
+	writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
+	spin_unlock_irq(&priv->lock);
+
+	ret = wait_for_completion_interruptible_timeout(&priv->xfer_complete, timeout);
+	if (ret < 0)
+		return ret;
+
+	if (ret == 0) {
+		dev_dbg(priv->dev, "Timeout waiting for a response!\n");
+		return -ETIMEDOUT;
+	}
+
+	spin_lock_irq(&priv->lock);
+
+	if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
+		spin_unlock_irq(&priv->lock);
+		dev_dbg(priv->dev, "No valid response, status: %#02x\n", priv->status);
+		return -EIO;
+	}
+
+	spin_unlock_irq(&priv->lock);
+
+	memcpy_fromio(req->rx.buf, priv->base + ASPEED_PECI_RD_DATA0, min_t(u8, req->rx.len, 16));
+	if (req->rx.len > 16)
+		memcpy_fromio(req->rx.buf + 16, priv->base + ASPEED_PECI_RD_DATA4,
+			      req->rx.len - 16);
+
+#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
+	print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req->rx.len);
+#endif
+	return 0;
+}
+
+static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
+{
+	struct aspeed_peci *priv = arg;
+	u32 status;
+
+	spin_lock(&priv->lock);
+	status = readl(priv->base + ASPEED_PECI_INT_STS);
+	writel(status, priv->base + ASPEED_PECI_INT_STS);
+	priv->status |= (status & ASPEED_PECI_INT_MASK);
+
+	/*
+	 * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE bit
+	 * set even in an error case.
+	 */
+	if (status & ASPEED_PECI_INT_CMD_DONE)
+		complete(&priv->xfer_complete);
+
+	writel(0, priv->base + ASPEED_PECI_CMD);
+
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void clk_aspeed_peci_find_div_values(unsigned long rate, int *msg_timing, int *clk_div_exp)
+{
+	unsigned long best_diff = ~0ul, diff;
+	int msg_timing_temp, clk_div_exp_temp, i, j;
+
+	for (i = 1; i <= 255; i++)
+		for (j = 0; j < 8; j++) {
+			diff = abs(rate - ASPEED_PECI_CLK_DIV1(i) * ASPEED_PECI_CLK_DIV2(j));
+			if (diff < best_diff) {
+				msg_timing_temp = i;
+				clk_div_exp_temp = j;
+				best_diff = diff;
+			}
+		}
+
+	*msg_timing = msg_timing_temp;
+	*clk_div_exp = clk_div_exp_temp;
+}
+
+static int clk_aspeed_peci_get_div(unsigned long rate, const unsigned long *prate)
+{
+	unsigned long this_rate = *prate / (4 * rate);
+	int msg_timing, clk_div_exp;
+
+	clk_aspeed_peci_find_div_values(this_rate, &msg_timing, &clk_div_exp);
+
+	return ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp);
+}
+
+static int clk_aspeed_peci_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long prate)
+{
+	struct clk_aspeed_peci *peci_clk = container_of(hw, struct clk_aspeed_peci, hw);
+	struct aspeed_peci *aspeed_peci = peci_clk->aspeed_peci;
+	unsigned long this_rate = prate / (4 * rate);
+	int clk_div_exp, msg_timing;
+	u32 val;
+
+	clk_aspeed_peci_find_div_values(this_rate, &msg_timing, &clk_div_exp);
+
+	val = readl(aspeed_peci->base + ASPEED_PECI_CTRL);
+	val |= FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, clk_div_exp);
+	writel(val, aspeed_peci->base + ASPEED_PECI_CTRL);
+
+	val = FIELD_PREP(ASPEED_PECI_T_NEGO_MSG_MASK, msg_timing);
+	val |= FIELD_PREP(ASPEED_PECI_T_NEGO_ADDR_MASK, msg_timing);
+	writel(val, aspeed_peci->base + ASPEED_PECI_TIMING_NEGOTIATION);
+
+	return 0;
+}
+
+static long clk_aspeed_peci_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *prate)
+{
+	int div = clk_aspeed_peci_get_div(rate, prate);
+
+	return DIV_ROUND_UP_ULL(*prate, div);
+}
+
+static unsigned long clk_aspeed_peci_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+	struct clk_aspeed_peci *peci_clk = container_of(hw, struct clk_aspeed_peci, hw);
+	struct aspeed_peci *aspeed_peci = peci_clk->aspeed_peci;
+	int div, msg_timing, addr_timing, clk_div_exp;
+	u32 reg;
+
+	reg = readl(aspeed_peci->base + ASPEED_PECI_TIMING_NEGOTIATION);
+	msg_timing = FIELD_GET(ASPEED_PECI_T_NEGO_MSG_MASK, reg);
+	addr_timing = FIELD_GET(ASPEED_PECI_T_NEGO_ADDR_MASK, reg);
+
+	if (msg_timing != addr_timing)
+		return 0;
+
+	reg = readl(aspeed_peci->base + ASPEED_PECI_CTRL);
+	clk_div_exp = FIELD_GET(ASPEED_PECI_CTRL_CLK_DIV_MASK, reg);
+
+	div = ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp);
+
+	return DIV_ROUND_UP_ULL(prate, div);
+}
+
+static const struct clk_ops clk_aspeed_peci_ops = {
+	.set_rate = clk_aspeed_peci_set_rate,
+	.round_rate = clk_aspeed_peci_round_rate,
+	.recalc_rate = clk_aspeed_peci_recalc_rate,
+};
+
+/*
+ * PECI HW contains a clock divider which is a combination of:
+ *  div0: 4 (fixed divider)
+ *  div1: x + 1
+ *  div2: 1 << y
+ * In other words, out_clk = in_clk / (div0 * div1 * div2)
+ * The resulting frequency is used by PECI Controller to drive the PECI bus to
+ * negotiate optimal transfer rate.
+ */
+static struct clk *devm_aspeed_peci_register_clk_div(struct device *dev, struct clk *parent,
+						     struct aspeed_peci *priv)
+{
+	struct clk_aspeed_peci *peci_clk;
+	struct clk_init_data init;
+	const char *parent_name;
+	char name[32];
+	int ret;
+
+	snprintf(name, sizeof(name), "%s_div", dev_name(dev));
+
+	parent_name = __clk_get_name(parent);
+
+	init.ops = &clk_aspeed_peci_ops;
+	init.name = name;
+	init.parent_names = (const char* []) { parent_name };
+	init.num_parents = 1;
+	init.flags = 0;
+
+	peci_clk = devm_kzalloc(dev, sizeof(struct clk_aspeed_peci), GFP_KERNEL);
+	if (!peci_clk)
+		return ERR_PTR(-ENOMEM);
+
+	peci_clk->hw.init = &init;
+	peci_clk->aspeed_peci = priv;
+
+	ret = devm_clk_hw_register(dev, &peci_clk->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return peci_clk->hw.clk;
+}
+
+static void aspeed_peci_property_sanitize(struct device *dev, const char *propname,
+					  u32 min, u32 max, u32 default_val, u32 *propval)
+{
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, propname, &val);
+	if (ret) {
+		val = default_val;
+	} else if (val > max || val < min) {
+		dev_warn(dev, "Invalid %s: %u, falling back to: %u\n",
+			 propname, val, default_val);
+
+		val = default_val;
+	}
+
+	*propval = val;
+}
+
+static void aspeed_peci_property_setup(struct aspeed_peci *priv)
+{
+	aspeed_peci_property_sanitize(priv->dev, "clock-frequency",
+				      ASPEED_PECI_CLK_FREQUENCY_MIN, ASPEED_PECI_CLK_FREQUENCY_MAX,
+				      ASPEED_PECI_CLK_FREQUENCY_DEFAULT, &priv->clk_frequency);
+	aspeed_peci_property_sanitize(priv->dev, "cmd-timeout-ms",
+				      1, ASPEED_PECI_CMD_TIMEOUT_MS_MAX,
+				      ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT, &priv->cmd_timeout_ms);
+}
+
+static struct peci_controller_ops aspeed_ops = {
+	.xfer = aspeed_peci_xfer,
+};
+
+static void aspeed_peci_reset_control_release(void *data)
+{
+	reset_control_assert(data);
+}
+
+static int devm_aspeed_peci_reset_control_deassert(struct device *dev, struct reset_control *rst)
+{
+	int ret;
+
+	ret = reset_control_deassert(rst);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_reset_control_release, rst);
+}
+
+static void aspeed_peci_clk_release(void *data)
+{
+	clk_disable_unprepare(data);
+}
+
+static int devm_aspeed_peci_clk_enable(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_clk_release, clk);
+}
+
+static int aspeed_peci_probe(struct platform_device *pdev)
+{
+	struct peci_controller *controller;
+	struct aspeed_peci *priv;
+	struct clk *ref_clk;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	dev_set_drvdata(priv->dev, priv);
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (!priv->irq)
+		return priv->irq;
+
+	ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
+			       0, "peci-aspeed", priv);
+	if (ret)
+		return ret;
+
+	init_completion(&priv->xfer_complete);
+	spin_lock_init(&priv->lock);
+
+	priv->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->rst))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->rst),
+				     "failed to get reset control\n");
+
+	ret = devm_aspeed_peci_reset_control_deassert(priv->dev, priv->rst);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "cannot deassert reset control\n");
+
+	aspeed_peci_property_setup(priv);
+
+	aspeed_peci_init_regs(priv);
+
+	ref_clk = devm_clk_get(priv->dev, NULL);
+	if (IS_ERR(ref_clk))
+		return dev_err_probe(priv->dev, PTR_ERR(ref_clk), "failed to get ref clock\n");
+
+	priv->clk = devm_aspeed_peci_register_clk_div(priv->dev, ref_clk, priv);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->clk), "cannot register clock\n");
+
+	ret = clk_set_rate(priv->clk, priv->clk_frequency);
+	if (ret < 0)
+		return dev_err_probe(priv->dev, ret, "cannot set clock frequency\n");
+
+	ret = devm_aspeed_peci_clk_enable(priv->dev, priv->clk);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "failed to enable clock\n");
+
+	aspeed_peci_controller_enable(priv);
+
+	controller = devm_peci_controller_add(priv->dev, &aspeed_ops);
+	if (IS_ERR(controller))
+		return dev_err_probe(priv->dev, PTR_ERR(controller),
+				     "failed to add aspeed peci controller\n");
+
+	priv->controller = controller;
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_peci_of_table[] = {
+	{ .compatible = "aspeed,ast2400-peci", },
+	{ .compatible = "aspeed,ast2500-peci", },
+	{ .compatible = "aspeed,ast2600-peci", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
+
+static struct platform_driver aspeed_peci_driver = {
+	.probe  = aspeed_peci_probe,
+	.driver = {
+		.name           = "peci-aspeed",
+		.of_match_table = aspeed_peci_of_table,
+	},
+};
+module_platform_driver(aspeed_peci_driver);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED PECI driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:40 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:40 +0100
Subject: [PATCH v5 06/13] peci: Add device detection
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-7-iwona.winiarska@intel.com>

Since PECI devices are discoverable, we can dynamically detect devices
that are actually available in the system.

This change complements the earlier implementation by rescanning PECI
bus to detect available devices. For this purpose, it also introduces the
minimal API for PECI requests.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/Makefile   |   2 +-
 drivers/peci/core.c     |  33 +++++++++++
 drivers/peci/device.c   | 120 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  14 +++++
 drivers/peci/request.c  |  55 ++++++++++++++++++
 include/linux/peci.h    |   2 +
 6 files changed, 225 insertions(+), 1 deletion(-)
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/request.c

diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 926d8df15cbd..c5f9d3fe21bb 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o
+peci-y := core.o request.o device.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index 73ad0a47fa9d..c3361e6e043a 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,6 +29,20 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
+static int peci_controller_scan_devices(struct peci_controller *controller)
+{
+	int ret;
+	u8 addr;
+
+	for (addr = PECI_BASE_ADDR; addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; addr++) {
+		ret = peci_device_create(controller, addr);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static struct peci_controller *peci_controller_alloc(struct device *dev,
 						     struct peci_controller_ops *ops)
 {
@@ -64,10 +78,23 @@ static struct peci_controller *peci_controller_alloc(struct device *dev,
 	return ERR_PTR(ret);
 }
 
+static int unregister_child(struct device *dev, void *dummy)
+{
+	peci_device_destroy(to_peci_device(dev));
+
+	return 0;
+}
+
 static void unregister_controller(void *_controller)
 {
 	struct peci_controller *controller = _controller;
 
+	/*
+	 * Detach any active PECI devices. This can't fail, thus we do not
+	 * check the returned value.
+	 */
+	device_for_each_child_reverse(&controller->dev, NULL, unregister_child);
+
 	device_unregister(&controller->dev);
 
 	fwnode_handle_put(controller->dev.fwnode);
@@ -113,6 +140,12 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	/*
+	 * Ignoring retval since failures during scan are non-critical for
+	 * controller itself.
+	 */
+	peci_controller_scan_devices(controller);
+
 	return controller;
 
 err_fwnode:
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
new file mode 100644
index 000000000000..2b3a2d893aaf
--- /dev/null
+++ b/drivers/peci/device.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/peci.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+/*
+ * PECI device can be removed using sysfs, but the removal can also happen as
+ * a result of controller being removed.
+ * Mutex is used to protect PECI device from being double-deleted.
+ */
+static DEFINE_MUTEX(peci_device_del_lock);
+
+static int peci_detect(struct peci_controller *controller, u8 addr)
+{
+	/*
+	 * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
+	 * We expect correct Write FCS if the device at the target address
+	 * is able to respond.
+	 */
+	struct peci_request req = { 0 };
+	int ret;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, addr, &req);
+	mutex_unlock(&controller->bus_lock);
+
+	return ret;
+}
+
+static bool peci_addr_valid(u8 addr)
+{
+	return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
+}
+
+static int peci_dev_exists(struct device *dev, void *data)
+{
+	struct peci_device *device = to_peci_device(dev);
+	u8 *addr = data;
+
+	if (device->addr == *addr)
+		return -EBUSY;
+
+	return 0;
+}
+
+int peci_device_create(struct peci_controller *controller, u8 addr)
+{
+	struct peci_device *device;
+	int ret;
+
+	if (!peci_addr_valid(addr))
+		return -EINVAL;
+
+	/* Check if we have already detected this device before. */
+	ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
+	if (ret)
+		return 0;
+
+	ret = peci_detect(controller, addr);
+	if (ret) {
+		/*
+		 * Device not present or host state doesn't allow successful
+		 * detection at this time.
+		 */
+		if (ret == -EIO || ret == -ETIMEDOUT)
+			return 0;
+
+		return ret;
+	}
+
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
+	if (!device)
+		return -ENOMEM;
+
+	device_initialize(&device->dev);
+
+	device->addr = addr;
+	device->dev.parent = &controller->dev;
+	device->dev.bus = &peci_bus_type;
+	device->dev.type = &peci_device_type;
+
+	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
+	if (ret)
+		goto err_put;
+
+	ret = device_add(&device->dev);
+	if (ret)
+		goto err_put;
+
+	return 0;
+
+err_put:
+	put_device(&device->dev);
+
+	return ret;
+}
+
+void peci_device_destroy(struct peci_device *device)
+{
+	mutex_lock(&peci_device_del_lock);
+	if (!device->deleted) {
+		device_unregister(&device->dev);
+		device->deleted = true;
+	}
+	mutex_unlock(&peci_device_del_lock);
+}
+
+static void peci_device_release(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+
+	kfree(device);
+}
+
+struct device_type peci_device_type = {
+	.release	= peci_device_release,
+};
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 918dea745a86..57d11a902c5d 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,20 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct peci_device;
+struct peci_request;
+
+/* PECI CPU address range 0x30-0x37 */
+#define PECI_BASE_ADDR		0x30
+#define PECI_DEVICE_NUM_MAX	8
+
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
+void peci_request_free(struct peci_request *req);
+
+extern struct device_type peci_device_type;
+
+int peci_device_create(struct peci_controller *controller, u8 addr);
+void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
 
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
new file mode 100644
index 000000000000..7dee51c50dd2
--- /dev/null
+++ b/drivers/peci/request.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/export.h>
+#include <linux/peci.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "internal.h"
+
+/**
+ * peci_request_alloc() - allocate &struct peci_requests
+ * @device: PECI device to which request is going to be sent
+ * @tx_len: TX length
+ * @rx_len: RX length
+ *
+ * Return: A pointer to a newly allocated &struct peci_request on success or NULL otherwise.
+ */
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len)
+{
+	struct peci_request *req;
+
+	/*
+	 * TX and RX buffers are fixed length members of peci_request, this is
+	 * just a warn for developers to make sure to expand the buffers (or
+	 * change the allocation method) if we go over the current limit.
+	 */
+	if (WARN_ON_ONCE(tx_len > PECI_REQUEST_MAX_BUF_SIZE || rx_len > PECI_REQUEST_MAX_BUF_SIZE))
+		return NULL;
+	/*
+	 * PECI controllers that we are using now don't support DMA, this
+	 * should be converted to DMA API once support for controllers that do
+	 * allow it is added to avoid an extra copy.
+	 */
+	req = kzalloc(sizeof(*req), GFP_KERNEL);
+	if (!req)
+		return NULL;
+
+	req->device = device;
+	req->tx.len = tx_len;
+	req->rx.len = rx_len;
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_alloc, PECI);
+
+/**
+ * peci_request_free() - free peci_request
+ * @req: the PECI request to be freed
+ */
+void peci_request_free(struct peci_request *req)
+{
+	kfree(req);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 26e0a4e73b50..7e35673f3786 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -60,6 +60,7 @@ static inline struct peci_controller *to_peci_controller(void *d)
  * @dev: device object to register PECI device to the device model
  * @controller: manages the bus segment hosting this PECI device
  * @addr: address used on the PECI bus connected to the parent controller
+ * @deleted: indicates that PECI device was already deleted
  *
  * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
  * The behaviour exposed to the rest of the system is defined by the PECI driver
@@ -68,6 +69,7 @@ static inline struct peci_controller *to_peci_controller(void *d)
 struct peci_device {
 	struct device dev;
 	u8 addr;
+	bool deleted;
 };
 
 static inline struct peci_device *to_peci_device(struct device *d)
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:41 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:41 +0100
Subject: [PATCH v5 07/13] peci: Add sysfs interface for PECI bus
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-8-iwona.winiarska@intel.com>

PECI devices may not be discoverable at the time when PECI controller is
being added (e.g. BMC can boot up when the Host system is still in S5).
Since we currently don't have the capabilities to figure out the Host
system state inside the PECI subsystem itself, we have to rely on
userspace to do it for us.

In the future, PECI subsystem may be expanded with mechanisms that allow
us to avoid depending on userspace interaction (e.g. CPU presence could
be detected using GPIO, and the information on whether it's discoverable
could be obtained over IPMI).
Unfortunately, those methods may ultimately not be available (support
will vary from platform to platform), which means that we still need
platform independent method triggered by userspace.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 Documentation/ABI/testing/sysfs-bus-peci | 16 +++++
 drivers/peci/Makefile                    |  2 +-
 drivers/peci/core.c                      |  3 +-
 drivers/peci/device.c                    |  1 +
 drivers/peci/internal.h                  |  5 ++
 drivers/peci/sysfs.c                     | 82 ++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 drivers/peci/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-bus-peci b/Documentation/ABI/testing/sysfs-bus-peci
new file mode 100644
index 000000000000..56c2b2216bbd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-peci
@@ -0,0 +1,16 @@
+What:		/sys/bus/peci/rescan
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		initiate scan for PECI devices on all PECI controllers
+		in the system.
+
+What:		/sys/bus/peci/devices/<controller_id>-<device_addr>/remove
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		remove the PECI device and any of its children.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index c5f9d3fe21bb..917f689e147a 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o request.o device.o
+peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index c3361e6e043a..e993615cf521 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,7 +29,7 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
-static int peci_controller_scan_devices(struct peci_controller *controller)
+int peci_controller_scan_devices(struct peci_controller *controller)
 {
 	int ret;
 	u8 addr;
@@ -162,6 +162,7 @@ EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.bus_groups	= peci_bus_groups,
 };
 
 static int __init peci_init(void)
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 2b3a2d893aaf..d10ed1cfcd48 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -116,5 +116,6 @@ static void peci_device_release(struct device *dev)
 }
 
 struct device_type peci_device_type = {
+	.groups		= peci_device_groups,
 	.release	= peci_device_release,
 };
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 57d11a902c5d..978e12c8e1d3 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct attribute_group;
 struct peci_device;
 struct peci_request;
 
@@ -19,12 +20,16 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u
 void peci_request_free(struct peci_request *req);
 
 extern struct device_type peci_device_type;
+extern const struct attribute_group *peci_device_groups[];
 
 int peci_device_create(struct peci_controller *controller, u8 addr);
 void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
+extern const struct attribute_group *peci_bus_groups[];
 
 extern struct device_type peci_controller_type;
 
+int peci_controller_scan_devices(struct peci_controller *controller);
+
 #endif /* __PECI_INTERNAL_H */
diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c
new file mode 100644
index 000000000000..db9ef05776e3
--- /dev/null
+++ b/drivers/peci/sysfs.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/peci.h>
+
+#include "internal.h"
+
+static int rescan_controller(struct device *dev, void *data)
+{
+	if (dev->type != &peci_controller_type)
+		return 0;
+
+	return peci_controller_scan_devices(to_peci_controller(dev));
+}
+
+static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (!res)
+		return count;
+
+	ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static BUS_ATTR_WO(rescan);
+
+static struct attribute *peci_bus_attrs[] = {
+	&bus_attr_rescan.attr,
+	NULL
+};
+
+static const struct attribute_group peci_bus_group = {
+	.attrs = peci_bus_attrs,
+};
+
+const struct attribute_group *peci_bus_groups[] = {
+	&peci_bus_group,
+	NULL
+};
+
+static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct peci_device *device = to_peci_device(dev);
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (res && device_remove_file_self(dev, attr))
+		peci_device_destroy(device);
+
+	return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
+
+static struct attribute *peci_device_attrs[] = {
+	&dev_attr_remove.attr,
+	NULL
+};
+
+static const struct attribute_group peci_device_group = {
+	.attrs = peci_device_attrs,
+};
+
+const struct attribute_group *peci_device_groups[] = {
+	&peci_device_group,
+	NULL
+};
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:42 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:42 +0100
Subject: [PATCH v5 08/13] peci: Add support for PECI device drivers
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-9-iwona.winiarska@intel.com>

Add support for PECI device drivers, which unlike PECI controller
drivers are actually able to provide functionalities to userspace.

Also, extend peci_request API to allow querying more details about PECI
device (e.g. model/family), that's going to be used to find a compatible
peci_driver.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/core.c     |  44 +++++++++
 drivers/peci/device.c   | 130 ++++++++++++++++++++++++
 drivers/peci/internal.h |  74 ++++++++++++++
 drivers/peci/request.c  | 214 ++++++++++++++++++++++++++++++++++++++++
 include/linux/peci.h    |  19 ++++
 5 files changed, 481 insertions(+)

diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index e993615cf521..9c8cf07e51c7 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -160,8 +160,52 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 }
 EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
+static const struct peci_device_id *
+peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device)
+{
+	while (id->family != 0) {
+		if (id->family == device->info.family &&
+		    id->model == device->info.model)
+			return id;
+		id++;
+	}
+
+	return NULL;
+}
+
+static int peci_bus_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *peci_drv = to_peci_driver(drv);
+
+	if (dev->type != &peci_device_type)
+		return 0;
+
+	return !!peci_bus_match_device_id(peci_drv->id_table, device);
+}
+
+static int peci_bus_device_probe(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	return driver->probe(device, peci_bus_match_device_id(driver->id_table, device));
+}
+
+static void peci_bus_device_remove(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	if (driver->remove)
+		driver->remove(device);
+}
+
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.match		= peci_bus_device_match,
+	.probe		= peci_bus_device_probe,
+	.remove		= peci_bus_device_remove,
 	.bus_groups	= peci_bus_groups,
 };
 
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index d10ed1cfcd48..184b5e650b0b 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2018-2021 Intel Corporation
 
+#include <linux/bitfield.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 
@@ -13,6 +14,104 @@
  */
 static DEFINE_MUTEX(peci_device_del_lock);
 
+#define REVISION_NUM_MASK GENMASK(15, 8)
+static int peci_get_revision(struct peci_device *device, u8 *revision)
+{
+	struct peci_request *req;
+	u64 dib;
+
+	req = peci_xfer_get_dib(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/*
+	 * PECI device may be in a state where it is unable to return a proper
+	 * DIB, in which case it returns 0 as DIB value.
+	 * Let's treat this as an error to avoid carrying on with the detection
+	 * using invalid revision.
+	 */
+	dib = peci_request_dib_read(req);
+	if (dib == 0) {
+		peci_request_free(req);
+		return -EIO;
+	}
+
+	*revision = FIELD_GET(REVISION_NUM_MASK, dib);
+
+	peci_request_free(req);
+
+	return 0;
+}
+
+static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*cpu_id = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+
+static unsigned int peci_x86_cpu_family(unsigned int sig)
+{
+	unsigned int x86;
+
+	x86 = (sig >> 8) & 0xf;
+
+	if (x86 == 0xf)
+		x86 += (sig >> 20) & 0xff;
+
+	return x86;
+}
+
+static unsigned int peci_x86_cpu_model(unsigned int sig)
+{
+	unsigned int fam, model;
+
+	fam = peci_x86_cpu_family(sig);
+
+	model = (sig >> 4) & 0xf;
+
+	if (fam >= 0x6)
+		model += ((sig >> 16) & 0xf) << 4;
+
+	return model;
+}
+
+static int peci_device_info_init(struct peci_device *device)
+{
+	u8 revision;
+	u32 cpu_id;
+	int ret;
+
+	ret = peci_get_cpu_id(device, &cpu_id);
+	if (ret)
+		return ret;
+
+	device->info.family = peci_x86_cpu_family(cpu_id);
+	device->info.model = peci_x86_cpu_model(cpu_id);
+
+	ret = peci_get_revision(device, &revision);
+	if (ret)
+		return ret;
+	device->info.peci_revision = revision;
+
+	device->info.socket_id = device->addr - PECI_BASE_ADDR;
+
+	return 0;
+}
+
 static int peci_detect(struct peci_controller *controller, u8 addr)
 {
 	/*
@@ -82,6 +181,10 @@ int peci_device_create(struct peci_controller *controller, u8 addr)
 	device->dev.bus = &peci_bus_type;
 	device->dev.type = &peci_device_type;
 
+	ret = peci_device_info_init(device);
+	if (ret)
+		goto err_put;
+
 	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
 	if (ret)
 		goto err_put;
@@ -108,6 +211,33 @@ void peci_device_destroy(struct peci_device *device)
 	mutex_unlock(&peci_device_del_lock);
 }
 
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name)
+{
+	driver->driver.bus = &peci_bus_type;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	if (!driver->probe) {
+		pr_err("peci: trying to register driver without probe callback\n");
+		return -EINVAL;
+	}
+
+	if (!driver->id_table) {
+		pr_err("peci: trying to register driver without device id table\n");
+		return -EINVAL;
+	}
+
+	return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
+
+void peci_driver_unregister(struct peci_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
+
 static void peci_device_release(struct device *dev)
 {
 	struct peci_device *device = to_peci_device(dev);
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 978e12c8e1d3..52c02e12874f 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -19,6 +19,35 @@ struct peci_request;
 struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
 void peci_request_free(struct peci_request *req);
 
+int peci_request_status(struct peci_request *req);
+
+u64 peci_request_dib_read(struct peci_request *req);
+
+u8 peci_request_data_readb(struct peci_request *req);
+u16 peci_request_data_readw(struct peci_request *req);
+u32 peci_request_data_readl(struct peci_request *req);
+u64 peci_request_data_readq(struct peci_request *req);
+
+struct peci_request *peci_xfer_get_dib(struct peci_device *device);
+struct peci_request *peci_xfer_get_temp(struct peci_device *device);
+
+struct peci_request *peci_xfer_pkg_cfg_readb(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readw(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
+
+/**
+ * struct peci_device_id - PECI device data to match
+ * @data: pointer to driver private data specific to device
+ * @family: device family
+ * @model: device model
+ */
+struct peci_device_id {
+	const void *data;
+	u16 family;
+	u8 model;
+};
+
 extern struct device_type peci_device_type;
 extern const struct attribute_group *peci_device_groups[];
 
@@ -28,6 +57,51 @@ void peci_device_destroy(struct peci_device *device);
 extern struct bus_type peci_bus_type;
 extern const struct attribute_group *peci_bus_groups[];
 
+/**
+ * struct peci_driver - PECI driver
+ * @driver: inherit device driver
+ * @probe: probe callback
+ * @remove: remove callback
+ * @id_table: PECI device match table to decide which device to bind
+ */
+struct peci_driver {
+	struct device_driver driver;
+	int (*probe)(struct peci_device *device, const struct peci_device_id *id);
+	void (*remove)(struct peci_device *device);
+	const struct peci_device_id *id_table;
+};
+
+static inline struct peci_driver *to_peci_driver(struct device_driver *d)
+{
+	return container_of(d, struct peci_driver, driver);
+}
+
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name);
+/**
+ * peci_driver_register() - register PECI driver
+ * @driver: the driver to be registered
+ *
+ * PECI drivers that don't need to do anything special in module init should
+ * use the convenience "module_peci_driver" macro instead
+ *
+ * Return: zero on success, else a negative error code.
+ */
+#define peci_driver_register(driver) \
+	__peci_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+void peci_driver_unregister(struct peci_driver *driver);
+
+/**
+ * module_peci_driver() - helper macro for registering a modular PECI driver
+ * @__peci_driver: peci_driver struct
+ *
+ * Helper macro for PECI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_peci_driver(__peci_driver) \
+	module_driver(__peci_driver, peci_driver_register, peci_driver_unregister)
+
 extern struct device_type peci_controller_type;
 
 int peci_controller_scan_devices(struct peci_controller *controller);
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index 7dee51c50dd2..9bd1d81c6093 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -1,13 +1,140 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2021 Intel Corporation
 
+#include <linux/bug.h>
 #include <linux/export.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include <asm/unaligned.h>
+
 #include "internal.h"
 
+#define PECI_GET_DIB_CMD		0xf7
+#define  PECI_GET_DIB_WR_LEN		1
+#define  PECI_GET_DIB_RD_LEN		8
+
+#define PECI_RDPKGCFG_CMD		0xa1
+#define  PECI_RDPKGCFG_WR_LEN		5
+#define  PECI_RDPKGCFG_RD_LEN_BASE	1
+#define PECI_WRPKGCFG_CMD		0xa5
+#define  PECI_WRPKGCFG_WR_LEN_BASE	6
+#define  PECI_WRPKGCFG_RD_LEN		1
+
+/* Device Specific Completion Code (CC) Definition */
+#define PECI_CC_SUCCESS				0x40
+#define PECI_CC_NEED_RETRY			0x80
+#define PECI_CC_OUT_OF_RESOURCE			0x81
+#define PECI_CC_UNAVAIL_RESOURCE		0x82
+#define PECI_CC_INVALID_REQ			0x90
+#define PECI_CC_MCA_ERROR			0x91
+#define PECI_CC_CATASTROPHIC_MCA_ERROR		0x93
+#define PECI_CC_FATAL_MCA_ERROR			0x94
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB		0x98
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR	0x9B
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA	0x9C
+
+#define PECI_RETRY_BIT			BIT(0)
+
+#define PECI_RETRY_TIMEOUT		msecs_to_jiffies(700)
+#define PECI_RETRY_INTERVAL_MIN		msecs_to_jiffies(1)
+#define PECI_RETRY_INTERVAL_MAX		msecs_to_jiffies(128)
+
+static u8 peci_request_data_cc(struct peci_request *req)
+{
+	return req->rx.buf[0];
+}
+
+/**
+ * peci_request_status() - return -errno based on PECI completion code
+ * @req: the PECI request that contains response data with completion code
+ *
+ * It can't be used for Ping(), GetDIB() and GetTemp() - for those commands we
+ * don't expect completion code in the response.
+ *
+ * Return: -errno
+ */
+int peci_request_status(struct peci_request *req)
+{
+	u8 cc = peci_request_data_cc(req);
+
+	if (cc != PECI_CC_SUCCESS)
+		dev_dbg(&req->device->dev, "ret: %#02x\n", cc);
+
+	switch (cc) {
+	case PECI_CC_SUCCESS:
+		return 0;
+	case PECI_CC_NEED_RETRY:
+	case PECI_CC_OUT_OF_RESOURCE:
+	case PECI_CC_UNAVAIL_RESOURCE:
+		return -EAGAIN;
+	case PECI_CC_INVALID_REQ:
+		return -EINVAL;
+	case PECI_CC_MCA_ERROR:
+	case PECI_CC_CATASTROPHIC_MCA_ERROR:
+	case PECI_CC_FATAL_MCA_ERROR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA:
+		return -EIO;
+	}
+
+	WARN_ONCE(1, "Unknown PECI completion code: %#02x\n", cc);
+
+	return -EIO;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_status, PECI);
+
+static int peci_request_xfer(struct peci_request *req)
+{
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	int ret;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, device->addr, req);
+	mutex_unlock(&controller->bus_lock);
+
+	return ret;
+}
+
+static int peci_request_xfer_retry(struct peci_request *req)
+{
+	long wait_interval = PECI_RETRY_INTERVAL_MIN;
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	unsigned long start = jiffies;
+	int ret;
+
+	/* Don't try to use it for ping */
+	if (WARN_ON(!req->rx.buf))
+		return 0;
+
+	do {
+		ret = peci_request_xfer(req);
+		if (ret) {
+			dev_dbg(&controller->dev, "xfer error: %d\n", ret);
+			return ret;
+		}
+
+		if (peci_request_status(req) != -EAGAIN)
+			return 0;
+
+		/* Set the retry bit to indicate a retry attempt */
+		req->tx.buf[1] |= PECI_RETRY_BIT;
+
+		if (schedule_timeout_interruptible(wait_interval))
+			return -ERESTARTSYS;
+
+		wait_interval = min_t(long, wait_interval * 2, PECI_RETRY_INTERVAL_MAX);
+	} while (time_before(jiffies, start + PECI_RETRY_TIMEOUT));
+
+	dev_dbg(&controller->dev, "request timed out\n");
+
+	return -ETIMEDOUT;
+}
+
 /**
  * peci_request_alloc() - allocate &struct peci_requests
  * @device: PECI device to which request is going to be sent
@@ -53,3 +180,90 @@ void peci_request_free(struct peci_request *req)
 	kfree(req);
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
+
+struct peci_request *peci_xfer_get_dib(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_DIB_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, PECI);
+
+static struct peci_request *
+__pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPKGCFG_WR_LEN, PECI_RDPKGCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDPKGCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = index;
+	put_unaligned_le16(param, &req->tx.buf[3]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+u8 peci_request_data_readb(struct peci_request *req)
+{
+	return req->rx.buf[1];
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, PECI);
+
+u16 peci_request_data_readw(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, PECI);
+
+u32 peci_request_data_readl(struct peci_request *req)
+{
+	return get_unaligned_le32(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, PECI);
+
+u64 peci_request_data_readq(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, PECI);
+
+u64 peci_request_dib_read(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, PECI);
+
+#define __read_pkg_config(x, type) \
+struct peci_request *peci_xfer_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
+{ \
+	return __pkg_cfg_read(device, index, param, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_pkg_cfg_##x, PECI)
+
+__read_pkg_config(readb, u8);
+__read_pkg_config(readw, u16);
+__read_pkg_config(readl, u32);
+__read_pkg_config(readq, u64);
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 7e35673f3786..4eda423ba10c 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,6 +14,14 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+
 struct peci_controller;
 struct peci_request;
 
@@ -59,6 +67,11 @@ static inline struct peci_controller *to_peci_controller(void *d)
  * struct peci_device - PECI device
  * @dev: device object to register PECI device to the device model
  * @controller: manages the bus segment hosting this PECI device
+ * @info: PECI device characteristics
+ * @info.family: device family
+ * @info.model: device model
+ * @info.peci_revision: PECI revision supported by the PECI device
+ * @info.socket_id: the socket ID represented by the PECI device
  * @addr: address used on the PECI bus connected to the parent controller
  * @deleted: indicates that PECI device was already deleted
  *
@@ -68,6 +81,12 @@ static inline struct peci_controller *to_peci_controller(void *d)
  */
 struct peci_device {
 	struct device dev;
+	struct {
+		u16 family;
+		u8 model;
+		u8 peci_revision;
+		u8 socket_id;
+	} info;
 	u8 addr;
 	bool deleted;
 };
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:43 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:43 +0100
Subject: [PATCH v5 09/13] peci: Add peci-cpu driver
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-10-iwona.winiarska@intel.com>

PECI is an interface that may be used by different types of devices.
Add a peci-cpu driver compatible with Intel processors. The driver is
responsible for handling auxiliary devices that can subsequently be used
by other drivers (e.g. hwmons).

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS              |   1 +
 drivers/peci/Kconfig     |  15 ++
 drivers/peci/Makefile    |   2 +
 drivers/peci/cpu.c       | 343 +++++++++++++++++++++++++++++++++++++++
 drivers/peci/device.c    |   1 +
 drivers/peci/internal.h  |  27 +++
 drivers/peci/request.c   | 213 ++++++++++++++++++++++++
 include/linux/peci-cpu.h |  40 +++++
 include/linux/peci.h     |   8 -
 9 files changed, 642 insertions(+), 8 deletions(-)
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 include/linux/peci-cpu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6564c3b58c83..e79322cc6d29 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14936,6 +14936,7 @@ L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
 F:	drivers/peci/
+F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
 
 PENSANDO ETHERNET DRIVERS
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 99279df97a78..89872ad83320 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -16,6 +16,21 @@ menuconfig PECI
 
 if PECI
 
+config PECI_CPU
+	tristate "PECI CPU"
+	select AUXILIARY_BUS
+	help
+	  This option enables peci-cpu driver for Intel processors. It is
+	  responsible for creating auxiliary devices that can subsequently
+	  be used by other drivers in order to perform various
+	  functionalities such as e.g. temperature monitoring.
+
+	  Additional drivers must be enabled in order to use the functionality
+	  of the device.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cpu.
+
 source "drivers/peci/controller/Kconfig"
 
 endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 917f689e147a..7de18137e738 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,6 +3,8 @@
 # Core functionality
 peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
+peci-cpu-y := cpu.o
+obj-$(CONFIG_PECI_CPU) += peci-cpu.o
 
 # Hardware specific bus drivers
 obj-y += controller/
diff --git a/drivers/peci/cpu.c b/drivers/peci/cpu.c
new file mode 100644
index 000000000000..68eb61c65d34
--- /dev/null
+++ b/drivers/peci/cpu.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+/**
+ * peci_temp_read() - read the maximum die temperature from PECI target device
+ * @device: PECI device to which request is going to be sent
+ * @temp_raw: where to store the read temperature
+ *
+ * It uses GetTemp PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_temp_read(struct peci_device *device, s16 *temp_raw)
+{
+	struct peci_request *req;
+
+	req = peci_xfer_get_temp(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	*temp_raw = peci_request_temp_read(req);
+
+	peci_request_free(req);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(peci_temp_read, PECI_CPU);
+
+/**
+ * peci_pcs_read() - read PCS register
+ * @device: PECI device to which request is going to be sent
+ * @index: PCS index
+ * @param: PCS parameter
+ * @data: where to store the read data
+ *
+ * It uses RdPkgConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pcs_read(struct peci_device *device, u8 index, u16 param, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pkg_cfg_readl(device, index, param);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pcs_read, PECI_CPU);
+
+/**
+ * peci_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * It uses RdPCIConfigLocal PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func,
+			u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pci_cfg_local_readl(device, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pci_local_read, PECI_CPU);
+
+/**
+ * peci_ep_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * Like &peci_pci_local_read, but it uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_ep_pci_cfg_local_readl(device, seg, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_ep_pci_local_read, PECI_CPU);
+
+/**
+ * peci_mmio_read() - read 32-bit memory location using 64-bit bar offset address
+ * @device: PECI device to which request is going to be sent
+ * @bar: PCI bar
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @address: 64-bit MMIO address
+ * @data: where to store the read data
+ *
+ * It uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_ep_mmio64_readl(device, bar, seg, bus, dev, func, address);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_mmio_read, PECI_CPU);
+
+static const char * const peci_adev_types[] = {
+	"cputemp",
+	"dimmtemp",
+};
+
+struct peci_cpu {
+	struct peci_device *device;
+	const struct peci_device_id *id;
+};
+
+static void adev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	auxiliary_device_uninit(adev);
+
+	kfree(adev->name);
+	kfree(adev);
+}
+
+static struct auxiliary_device *adev_alloc(struct peci_cpu *priv, int idx)
+{
+	struct peci_controller *controller = to_peci_controller(priv->device->dev.parent);
+	struct auxiliary_device *adev;
+	const char *name;
+	int ret;
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s.%s", peci_adev_types[idx], (const char *)priv->id->data);
+	if (!name) {
+		ret = -ENOMEM;
+		goto free_adev;
+	}
+
+	adev->name = name;
+	adev->dev.parent = &priv->device->dev;
+	adev->dev.release = adev_release;
+	adev->id = (controller->id << 16) | (priv->device->addr);
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		goto free_name;
+
+	return adev;
+
+free_name:
+	kfree(name);
+free_adev:
+	kfree(adev);
+	return ERR_PTR(ret);
+}
+
+static void unregister_adev(void *_adev)
+{
+	struct auxiliary_device *adev = _adev;
+
+	auxiliary_device_delete(adev);
+}
+
+static int devm_adev_add(struct device *dev, int idx)
+{
+	struct peci_cpu *priv = dev_get_drvdata(dev);
+	struct auxiliary_device *adev;
+	int ret;
+
+	adev = adev_alloc(priv, idx);
+	if (IS_ERR(adev))
+		return PTR_ERR(adev);
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&priv->device->dev, unregister_adev, adev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void peci_cpu_add_adevices(struct peci_cpu *priv)
+{
+	struct device *dev = &priv->device->dev;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(peci_adev_types); i++) {
+		ret = devm_adev_add(dev, i);
+		if (ret) {
+			dev_warn(dev, "Failed to register PECI auxiliary: %s, ret = %d\n",
+				 peci_adev_types[i], ret);
+			continue;
+		}
+	}
+}
+
+static int
+peci_cpu_probe(struct peci_device *device, const struct peci_device_id *id)
+{
+	struct device *dev = &device->dev;
+	struct peci_cpu *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+	priv->device = device;
+	priv->id = id;
+
+	peci_cpu_add_adevices(priv);
+
+	return 0;
+}
+
+static const struct peci_device_id peci_cpu_device_ids[] = {
+	{ /* Haswell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_HASWELL_X,
+		.data	= "hsx",
+	},
+	{ /* Broadwell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_X,
+		.data	= "bdx",
+	},
+	{ /* Broadwell Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_D,
+		.data	= "bdxd",
+	},
+	{ /* Skylake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_SKYLAKE_X,
+		.data	= "skx",
+	},
+	{ /* Icelake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_X,
+		.data	= "icx",
+	},
+	{ /* Icelake Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_D,
+		.data	= "icxd",
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(peci, peci_cpu_device_ids);
+
+static struct peci_driver peci_cpu_driver = {
+	.probe		= peci_cpu_probe,
+	.id_table	= peci_cpu_device_ids,
+	.driver		= {
+		.name		= "peci-cpu",
+	},
+};
+module_peci_driver(peci_cpu_driver);
+
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI CPU driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 184b5e650b0b..e6b0bffb14f4 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -3,6 +3,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/peci.h>
+#include <linux/peci-cpu.h>
 #include <linux/slab.h>
 
 #include "internal.h"
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 52c02e12874f..9d75ea54504c 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -22,6 +22,7 @@ void peci_request_free(struct peci_request *req);
 int peci_request_status(struct peci_request *req);
 
 u64 peci_request_dib_read(struct peci_request *req);
+s16 peci_request_temp_read(struct peci_request *req);
 
 u8 peci_request_data_readb(struct peci_request *req);
 u16 peci_request_data_readw(struct peci_request *req);
@@ -36,6 +37,32 @@ struct peci_request *peci_xfer_pkg_cfg_readw(struct peci_device *device, u8 inde
 struct peci_request *peci_xfer_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
 struct peci_request *peci_xfer_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
 
+struct peci_request *peci_xfer_pci_cfg_local_readb(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_pci_cfg_local_readw(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_pci_cfg_local_readl(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_pci_cfg_local_readb(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_local_readw(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_local_readl(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_pci_cfg_readb(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_readw(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_readl(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_mmio32_readl(struct peci_device *device, u8 bar, u8 seg,
+					       u8 bus, u8 dev, u8 func, u64 offset);
+
+struct peci_request *peci_xfer_ep_mmio64_readl(struct peci_device *device, u8 bar, u8 seg,
+					       u8 bus, u8 dev, u8 func, u64 offset);
 /**
  * struct peci_device_id - PECI device data to match
  * @data: pointer to driver private data specific to device
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index 9bd1d81c6093..33da90d801d5 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -3,6 +3,7 @@
 
 #include <linux/bug.h>
 #include <linux/export.h>
+#include <linux/pci.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -15,6 +16,10 @@
 #define  PECI_GET_DIB_WR_LEN		1
 #define  PECI_GET_DIB_RD_LEN		8
 
+#define PECI_GET_TEMP_CMD		0x01
+#define  PECI_GET_TEMP_WR_LEN		1
+#define  PECI_GET_TEMP_RD_LEN		2
+
 #define PECI_RDPKGCFG_CMD		0xa1
 #define  PECI_RDPKGCFG_WR_LEN		5
 #define  PECI_RDPKGCFG_RD_LEN_BASE	1
@@ -22,6 +27,45 @@
 #define  PECI_WRPKGCFG_WR_LEN_BASE	6
 #define  PECI_WRPKGCFG_RD_LEN		1
 
+#define PECI_RDIAMSR_CMD		0xb1
+#define  PECI_RDIAMSR_WR_LEN		5
+#define  PECI_RDIAMSR_RD_LEN		9
+#define PECI_WRIAMSR_CMD		0xb5
+#define PECI_RDIAMSREX_CMD		0xd1
+#define  PECI_RDIAMSREX_WR_LEN		6
+#define  PECI_RDIAMSREX_RD_LEN		9
+
+#define PECI_RDPCICFG_CMD		0x61
+#define  PECI_RDPCICFG_WR_LEN		6
+#define  PECI_RDPCICFG_RD_LEN		5
+#define  PECI_RDPCICFG_RD_LEN_MAX	24
+#define PECI_WRPCICFG_CMD		0x65
+
+#define PECI_RDPCICFGLOCAL_CMD			0xe1
+#define  PECI_RDPCICFGLOCAL_WR_LEN		5
+#define  PECI_RDPCICFGLOCAL_RD_LEN_BASE		1
+#define PECI_WRPCICFGLOCAL_CMD			0xe5
+#define  PECI_WRPCICFGLOCAL_WR_LEN_BASE		6
+#define  PECI_WRPCICFGLOCAL_RD_LEN		1
+
+#define PECI_ENDPTCFG_TYPE_LOCAL_PCI		0x03
+#define PECI_ENDPTCFG_TYPE_PCI			0x04
+#define PECI_ENDPTCFG_TYPE_MMIO			0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_PCI		0x04
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_D		0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q		0x06
+#define PECI_RDENDPTCFG_CMD			0xc1
+#define  PECI_RDENDPTCFG_PCI_WR_LEN		12
+#define  PECI_RDENDPTCFG_MMIO_WR_LEN_BASE	10
+#define  PECI_RDENDPTCFG_MMIO_D_WR_LEN		14
+#define  PECI_RDENDPTCFG_MMIO_Q_WR_LEN		18
+#define  PECI_RDENDPTCFG_RD_LEN_BASE		1
+#define PECI_WRENDPTCFG_CMD			0xc5
+#define  PECI_WRENDPTCFG_PCI_WR_LEN_BASE	13
+#define  PECI_WRENDPTCFG_MMIO_D_WR_LEN_BASE	15
+#define  PECI_WRENDPTCFG_MMIO_Q_WR_LEN_BASE	19
+#define  PECI_WRENDPTCFG_RD_LEN			1
+
 /* Device Specific Completion Code (CC) Definition */
 #define PECI_CC_SUCCESS				0x40
 #define PECI_CC_NEED_RETRY			0x80
@@ -202,6 +246,27 @@ struct peci_request *peci_xfer_get_dib(struct peci_device *device)
 }
 EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, PECI);
 
+struct peci_request *peci_xfer_get_temp(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_TEMP_WR_LEN, PECI_GET_TEMP_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_TEMP_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_xfer_get_temp, PECI);
+
 static struct peci_request *
 __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 {
@@ -226,6 +291,108 @@ __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 	return req;
 }
 
+static u32 __get_pci_addr(u8 bus, u8 dev, u8 func, u16 reg)
+{
+	return reg | PCI_DEVID(bus, PCI_DEVFN(dev, func)) << 12;
+}
+
+static struct peci_request *
+__pci_cfg_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPCICFGLOCAL_WR_LEN,
+				 PECI_RDPCICFGLOCAL_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDPCICFGLOCAL_CMD;
+	req->tx.buf[1] = 0;
+	put_unaligned_le24(pci_addr, &req->tx.buf[2]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_pci_cfg_read(struct peci_device *device, u8 msg_type, u8 seg,
+		  u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDENDPTCFG_PCI_WR_LEN,
+				 PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = msg_type;
+	req->tx.buf[3] = 0;
+	req->tx.buf[4] = 0;
+	req->tx.buf[5] = 0;
+	req->tx.buf[6] = PECI_ENDPTCFG_ADDR_TYPE_PCI;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	put_unaligned_le32(pci_addr, &req->tx.buf[8]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_mmio_read(struct peci_device *device, u8 bar, u8 addr_type, u8 seg,
+	       u8 bus, u8 dev, u8 func, u64 offset, u8 tx_len, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, tx_len, PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = PECI_ENDPTCFG_TYPE_MMIO;
+	req->tx.buf[3] = 0; /* Endpoint ID */
+	req->tx.buf[4] = 0; /* Reserved */
+	req->tx.buf[5] = bar;
+	req->tx.buf[6] = addr_type;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	req->tx.buf[8] = PCI_DEVFN(dev, func);
+	req->tx.buf[9] = bus; /* PCI Bus */
+
+	if (addr_type == PECI_ENDPTCFG_ADDR_TYPE_MMIO_D)
+		put_unaligned_le32(offset, &req->tx.buf[10]);
+	else
+		put_unaligned_le64(offset, &req->tx.buf[10]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
 u8 peci_request_data_readb(struct peci_request *req)
 {
 	return req->rx.buf[1];
@@ -256,6 +423,12 @@ u64 peci_request_dib_read(struct peci_request *req)
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, PECI);
 
+s16 peci_request_temp_read(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_temp_read, PECI);
+
 #define __read_pkg_config(x, type) \
 struct peci_request *peci_xfer_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
 { \
@@ -267,3 +440,43 @@ __read_pkg_config(readb, u8);
 __read_pkg_config(readw, u16);
 __read_pkg_config(readl, u32);
 __read_pkg_config(readq, u64);
+
+#define __read_pci_config_local(x, type) \
+struct peci_request * \
+peci_xfer_pci_cfg_local_##x(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __pci_cfg_local_read(device, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_pci_cfg_local_##x, PECI)
+
+__read_pci_config_local(readb, u8);
+__read_pci_config_local(readw, u16);
+__read_pci_config_local(readl, u32);
+
+#define __read_ep_pci_config(x, msg_type, type) \
+struct peci_request * \
+peci_xfer_ep_pci_cfg_##x(struct peci_device *device, u8 seg, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __ep_pci_cfg_read(device, msg_type, seg, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_pci_cfg_##x, PECI)
+
+__read_ep_pci_config(local_readb, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u8);
+__read_ep_pci_config(local_readw, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u16);
+__read_ep_pci_config(local_readl, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u32);
+__read_ep_pci_config(readb, PECI_ENDPTCFG_TYPE_PCI, u8);
+__read_ep_pci_config(readw, PECI_ENDPTCFG_TYPE_PCI, u16);
+__read_ep_pci_config(readl, PECI_ENDPTCFG_TYPE_PCI, u32);
+
+#define __read_ep_mmio(x, y, addr_type, type1, type2) \
+struct peci_request *peci_xfer_ep_mmio##y##_##x(struct peci_device *device, u8 bar, u8 seg, \
+					   u8 bus, u8 dev, u8 func, u64 offset) \
+{ \
+	return __ep_mmio_read(device, bar, addr_type, seg, bus, dev, func, \
+			      offset, PECI_RDENDPTCFG_MMIO_WR_LEN_BASE + sizeof(type1), \
+			      sizeof(type2)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_mmio##y##_##x, PECI)
+
+__read_ep_mmio(readl, 32, PECI_ENDPTCFG_ADDR_TYPE_MMIO_D, u32, u32);
+__read_ep_mmio(readl, 64, PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q, u64, u32);
diff --git a/include/linux/peci-cpu.h b/include/linux/peci-cpu.h
new file mode 100644
index 000000000000..ff8ae9c26c80
--- /dev/null
+++ b/include/linux/peci-cpu.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_CPU_H
+#define __LINUX_PECI_CPU_H
+
+#include <linux/types.h>
+
+#include "../../arch/x86/include/asm/intel-family.h"
+
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+#define PECI_PCS_MODULE_TEMP		9  /* Per Core DTS Temperature Read */
+#define PECI_PCS_THERMAL_MARGIN		10 /* DTS thermal margin */
+#define PECI_PCS_DDR_DIMM_TEMP		14 /* DDR DIMM Temperature */
+#define PECI_PCS_TEMP_TARGET		16 /* Temperature Target Read */
+#define PECI_PCS_TDP_UNITS		30 /* Units for power/energy registers */
+
+struct peci_device;
+
+int peci_temp_read(struct peci_device *device, s16 *temp_raw);
+
+int peci_pcs_read(struct peci_device *device, u8 index,
+		  u16 param, u32 *data);
+
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev,
+			u8 func, u16 reg, u32 *data);
+
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data);
+
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data);
+
+#endif /* __LINUX_PECI_CPU_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 4eda423ba10c..06e6ef935297 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,14 +14,6 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
-#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
-#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
-#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
-#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
-#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
-#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
-#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
-
 struct peci_controller;
 struct peci_request;
 
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:44 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:44 +0100
Subject: [PATCH v5 10/13] hwmon: peci: Add cputemp driver
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-11-iwona.winiarska@intel.com>

Add peci-cputemp driver for Digital Thermal Sensor (DTS) thermal
readings of the processor package and processor cores that are
accessible via the PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain the DTS readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 MAINTAINERS                  |   6 +
 drivers/hwmon/Kconfig        |   2 +
 drivers/hwmon/Makefile       |   1 +
 drivers/hwmon/peci/Kconfig   |  18 ++
 drivers/hwmon/peci/Makefile  |   5 +
 drivers/hwmon/peci/common.h  |  58 ++++
 drivers/hwmon/peci/cputemp.c | 592 +++++++++++++++++++++++++++++++++++
 7 files changed, 682 insertions(+)
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e79322cc6d29..3b9047b814fd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14930,6 +14930,12 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI HARDWARE MONITORING DRIVERS
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Supported
+F:	drivers/hwmon/peci/
+
 PECI SUBSYSTEM
 M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 64bd3dfba2c4..4858f7cfa81e 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1528,6 +1528,8 @@ config SENSORS_PCF8591
 	  These devices are hard to detect and rarely found on mainstream
 	  hardware. If unsure, say N.
 
+source "drivers/hwmon/peci/Kconfig"
+
 source "drivers/hwmon/pmbus/Kconfig"
 
 config SENSORS_PWM_FAN
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index baee6a8d4dd1..2c0e210a28b8 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -204,6 +204,7 @@ obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
 obj-$(CONFIG_SENSORS_XGENE)	+= xgene-hwmon.o
 
 obj-$(CONFIG_SENSORS_OCC)	+= occ/
+obj-$(CONFIG_SENSORS_PECI)	+= peci/
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
 ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
new file mode 100644
index 000000000000..e10eed68d70a
--- /dev/null
+++ b/drivers/hwmon/peci/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SENSORS_PECI_CPUTEMP
+	tristate "PECI CPU temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI
+	  cputemp driver which provides Digital Thermal Sensor (DTS) thermal
+	  readings of the CPU package and CPU cores that are accessible via
+	  the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cputemp.
+
+config SENSORS_PECI
+	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
new file mode 100644
index 000000000000..e8a0ada5ab1f
--- /dev/null
+++ b/drivers/hwmon/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+peci-cputemp-y := cputemp.o
+
+obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
new file mode 100644
index 000000000000..734506b0eca2
--- /dev/null
+++ b/drivers/hwmon/peci/common.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#ifndef __PECI_HWMON_COMMON_H
+#define __PECI_HWMON_COMMON_H
+
+#define PECI_HWMON_UPDATE_INTERVAL	HZ
+
+/**
+ * struct peci_sensor_state - PECI state information
+ * @valid: flag to indicate the sensor value is valid
+ * @last_updated: time of the last update in jiffies
+ * @lock: mutex to protect sensor access
+ */
+struct peci_sensor_state {
+	bool valid;
+	unsigned long last_updated;
+	struct mutex lock; /* protect sensor access */
+};
+
+/**
+ * struct peci_sensor_data - PECI sensor information
+ * @value: sensor value in milli units
+ * @state: sensor update state
+ */
+
+struct peci_sensor_data {
+	s32 value;
+	struct peci_sensor_state state;
+};
+
+/**
+ * peci_sensor_need_update() - check whether sensor update is needed or not
+ * @sensor: pointer to sensor data struct
+ *
+ * Return: true if update is needed, false if not.
+ */
+
+static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
+{
+	return !state->valid ||
+	       time_after(jiffies, state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
+}
+
+/**
+ * peci_sensor_mark_updated() - mark the sensor is updated
+ * @sensor: pointer to sensor data struct
+ */
+static inline void peci_sensor_mark_updated(struct peci_sensor_state *state)
+{
+	state->valid = true;
+	state->last_updated = jiffies;
+}
+
+#endif /* __PECI_HWMON_COMMON_H */
diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c
new file mode 100644
index 000000000000..12156328f5cf
--- /dev/null
+++ b/drivers/hwmon/peci/cputemp.c
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+
+#include "common.h"
+
+#define CORE_NUMS_MAX		64
+
+#define BASE_CHANNEL_NUMS	5
+#define CPUTEMP_CHANNEL_NUMS	(BASE_CHANNEL_NUMS + CORE_NUMS_MAX)
+
+#define TEMP_TARGET_FAN_TEMP_MASK	GENMASK(15, 8)
+#define TEMP_TARGET_REF_TEMP_MASK	GENMASK(23, 16)
+#define TEMP_TARGET_TJ_OFFSET_MASK	GENMASK(29, 24)
+
+#define DTS_MARGIN_MASK		GENMASK(15, 0)
+#define PCS_MODULE_TEMP_MASK	GENMASK(15, 0)
+
+struct resolved_cores_reg {
+	u8 bus;
+	u8 dev;
+	u8 func;
+	u8 offset;
+};
+
+struct cpu_info {
+	struct resolved_cores_reg *reg;
+	u8 min_peci_revision;
+	s32 (*thermal_margin_to_millidegree)(u16 val);
+};
+
+struct peci_temp_target {
+	s32 tcontrol;
+	s32 tthrottle;
+	s32 tjmax;
+	struct peci_sensor_state state;
+};
+
+enum peci_temp_target_type {
+	tcontrol_type,
+	tthrottle_type,
+	tjmax_type,
+	crit_hyst_type,
+};
+
+struct peci_cputemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct cpu_info *gen_info;
+	struct {
+		struct peci_temp_target target;
+		struct peci_sensor_data die;
+		struct peci_sensor_data dts;
+		struct peci_sensor_data core[CORE_NUMS_MAX];
+	} temp;
+	const char **coretemp_label;
+	DECLARE_BITMAP(core_mask, CORE_NUMS_MAX);
+};
+
+enum cputemp_channels {
+	channel_die,
+	channel_dts,
+	channel_tcontrol,
+	channel_tthrottle,
+	channel_tjmax,
+	channel_core,
+};
+
+static const char * const cputemp_label[BASE_CHANNEL_NUMS] = {
+	"Die",
+	"DTS",
+	"Tcontrol",
+	"Tthrottle",
+	"Tjmax",
+};
+
+static int update_temp_target(struct peci_cputemp *priv)
+{
+	s32 tthrottle_offset, tcontrol_margin;
+	u32 pcs;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->temp.target.state))
+		return 0;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_TEMP_TARGET, 0, &pcs);
+	if (ret)
+		return ret;
+
+	priv->temp.target.tjmax =
+		FIELD_GET(TEMP_TARGET_REF_TEMP_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+
+	tcontrol_margin = FIELD_GET(TEMP_TARGET_FAN_TEMP_MASK, pcs);
+	tcontrol_margin = sign_extend32(tcontrol_margin, 7) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tcontrol = priv->temp.target.tjmax - tcontrol_margin;
+
+	tthrottle_offset = FIELD_GET(TEMP_TARGET_TJ_OFFSET_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tthrottle = priv->temp.target.tjmax - tthrottle_offset;
+
+	peci_sensor_mark_updated(&priv->temp.target.state);
+
+	return 0;
+}
+
+static int get_temp_target(struct peci_cputemp *priv, enum peci_temp_target_type type, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->temp.target.state.lock);
+
+	ret = update_temp_target(priv);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case tcontrol_type:
+		*val = priv->temp.target.tcontrol;
+		break;
+	case tthrottle_type:
+		*val = priv->temp.target.tthrottle;
+		break;
+	case tjmax_type:
+		*val = priv->temp.target.tjmax;
+		break;
+	case crit_hyst_type:
+		*val = priv->temp.target.tjmax - priv->temp.target.tcontrol;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->temp.target.state.lock);
+
+	return ret;
+}
+
+/*
+ * Error codes:
+ *   0x8000: General sensor error
+ *   0x8001: Reserved
+ *   0x8002: Underflow on reading value
+ *   0x8003-0x81ff: Reserved
+ */
+static bool dts_valid(u16 val)
+{
+	return val < 0x8000 || val > 0x81ff;
+}
+
+/*
+ * Processors return a value of DTS reading in S10.6 fixed point format
+ * (16 bits: 10-bit signed magnitude, 6-bit fraction).
+ */
+static s32 dts_ten_dot_six_to_millidegree(u16 val)
+{
+	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / 64;
+}
+
+/*
+ * For older processors, thermal margin reading is returned in S8.8 fixed
+ * point format (16 bits: 8-bit signed magnitude, 8-bit fraction).
+ */
+static s32 dts_eight_dot_eight_to_millidegree(u16 val)
+{
+	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / 256;
+}
+
+static int get_die_temp(struct peci_cputemp *priv, long *val)
+{
+	int ret = 0;
+	long tjmax;
+	u16 temp;
+
+	mutex_lock(&priv->temp.die.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.die.state))
+		goto skip_update;
+
+	ret = peci_temp_read(priv->peci_dev, &temp);
+	if (ret)
+		goto err_unlock;
+
+	if (!dts_valid(temp)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	priv->temp.die.value = (s32)tjmax + dts_ten_dot_six_to_millidegree(temp);
+
+	peci_sensor_mark_updated(&priv->temp.die.state);
+
+skip_update:
+	*val = priv->temp.die.value;
+err_unlock:
+	mutex_unlock(&priv->temp.die.state.lock);
+	return ret;
+}
+
+static int get_dts(struct peci_cputemp *priv, long *val)
+{
+	int ret = 0;
+	u16 thermal_margin;
+	long tcontrol;
+	u32 pcs;
+
+	mutex_lock(&priv->temp.dts.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.dts.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_THERMAL_MARGIN, 0, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	thermal_margin = FIELD_GET(DTS_MARGIN_MASK, pcs);
+	if (!dts_valid(thermal_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tcontrol_type, &tcontrol);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tcontrol should be available before calling it */
+	priv->temp.dts.value =
+		(s32)tcontrol - priv->gen_info->thermal_margin_to_millidegree(thermal_margin);
+
+	peci_sensor_mark_updated(&priv->temp.dts.state);
+
+skip_update:
+	*val = priv->temp.dts.value;
+err_unlock:
+	mutex_unlock(&priv->temp.dts.state.lock);
+	return ret;
+}
+
+static int get_core_temp(struct peci_cputemp *priv, int core_index, long *val)
+{
+	int ret = 0;
+	u16 core_dts_margin;
+	long tjmax;
+	u32 pcs;
+
+	mutex_lock(&priv->temp.core[core_index].state.lock);
+	if (!peci_sensor_need_update(&priv->temp.core[core_index].state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_MODULE_TEMP, core_index, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	core_dts_margin = FIELD_GET(PCS_MODULE_TEMP_MASK, pcs);
+	if (!dts_valid(core_dts_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tjmax should be available before calling it */
+	priv->temp.core[core_index].value =
+		(s32)tjmax + dts_ten_dot_six_to_millidegree(core_dts_margin);
+
+	peci_sensor_mark_updated(&priv->temp.core[core_index].state);
+
+skip_update:
+	*val = priv->temp.core[core_index].value;
+err_unlock:
+	mutex_unlock(&priv->temp.core[core_index].state.lock);
+	return ret;
+}
+
+static int cputemp_read_string(struct device *dev, enum hwmon_sensor_types type,
+			       u32 attr, int channel, const char **str)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = channel < channel_core ?
+		cputemp_label[channel] : priv->coretemp_label[channel - channel_core];
+
+	return 0;
+}
+
+static int cputemp_read(struct device *dev, enum hwmon_sensor_types type,
+			u32 attr, int channel, long *val)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		switch (channel) {
+		case channel_die:
+			return get_die_temp(priv, val);
+		case channel_dts:
+			return get_dts(priv, val);
+		case channel_tcontrol:
+			return get_temp_target(priv, tcontrol_type, val);
+		case channel_tthrottle:
+			return get_temp_target(priv, tthrottle_type, val);
+		case channel_tjmax:
+			return get_temp_target(priv, tjmax_type, val);
+		default:
+			return get_core_temp(priv, channel - channel_core, val);
+		}
+		break;
+	case hwmon_temp_max:
+		return get_temp_target(priv, tcontrol_type, val);
+	case hwmon_temp_crit:
+		return get_temp_target(priv, tjmax_type, val);
+	case hwmon_temp_crit_hyst:
+		return get_temp_target(priv, crit_hyst_type, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static umode_t cputemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				  u32 attr, int channel)
+{
+	const struct peci_cputemp *priv = data;
+
+	if (channel > CPUTEMP_CHANNEL_NUMS)
+		return 0;
+
+	if (channel < channel_core)
+		return 0444;
+
+	if (test_bit(channel - channel_core, priv->core_mask))
+		return 0444;
+
+	return 0;
+}
+
+static int init_core_mask(struct peci_cputemp *priv)
+{
+	struct peci_device *peci_dev = priv->peci_dev;
+	struct resolved_cores_reg *reg = priv->gen_info->reg;
+	u64 core_mask;
+	u32 data;
+	int ret;
+
+	/* Get the RESOLVED_CORES register value */
+	switch (peci_dev->info.model) {
+	case INTEL_FAM6_ICELAKE_X:
+	case INTEL_FAM6_ICELAKE_D:
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset + 4, &data);
+		if (ret)
+			return ret;
+
+		core_mask = (u64)data << 32;
+
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask |= data;
+
+		break;
+	default:
+		ret = peci_pci_local_read(peci_dev, reg->bus, reg->dev,
+					  reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask = data;
+
+		break;
+	}
+
+	if (!core_mask)
+		return -EIO;
+
+	bitmap_from_u64(priv->core_mask, core_mask);
+
+	return 0;
+}
+
+static int create_temp_label(struct peci_cputemp *priv)
+{
+	unsigned long core_max = find_last_bit(priv->core_mask, CORE_NUMS_MAX);
+	int i;
+
+	priv->coretemp_label = devm_kzalloc(priv->dev, core_max * sizeof(char *), GFP_KERNEL);
+	if (!priv->coretemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX) {
+		priv->coretemp_label[i] = devm_kasprintf(priv->dev, GFP_KERNEL, "Core %d", i);
+		if (!priv->coretemp_label[i])
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void check_resolved_cores(struct peci_cputemp *priv)
+{
+	/*
+	 * Failure to resolve cores is non-critical, we're still able to
+	 * provide other sensor data.
+	 */
+
+	if (init_core_mask(priv))
+		return;
+
+	if (create_temp_label(priv))
+		bitmap_zero(priv->core_mask, CORE_NUMS_MAX);
+}
+
+static void sensor_init(struct peci_cputemp *priv)
+{
+	int i;
+
+	mutex_init(&priv->temp.target.state.lock);
+	mutex_init(&priv->temp.die.state.lock);
+	mutex_init(&priv->temp.dts.state.lock);
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX)
+		mutex_init(&priv->temp.core[i].state.lock);
+}
+
+static const struct hwmon_ops peci_cputemp_ops = {
+	.is_visible = cputemp_is_visible,
+	.read_string = cputemp_read_string,
+	.read = cputemp_read,
+};
+
+static const u32 peci_cputemp_temp_channel_config[] = {
+	/* Die temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* DTS margin */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* Tcontrol temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
+	/* Tthrottle temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Tjmax temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Core temperature - for all core channels */
+	[channel_core ... CPUTEMP_CHANNEL_NUMS - 1] = HWMON_T_LABEL | HWMON_T_INPUT,
+	0
+};
+
+static const struct hwmon_channel_info peci_cputemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_cputemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_cputemp_info[] = {
+	&peci_cputemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_cputemp_chip_info = {
+	.ops = &peci_cputemp_ops,
+	.info = peci_cputemp_info,
+};
+
+static int peci_cputemp_probe(struct auxiliary_device *adev,
+			      const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_cputemp *priv;
+	struct device *hwmon_dev;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_cputemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct cpu_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	check_resolved_cores(priv);
+
+	sensor_init(priv);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, priv->name,
+							 priv, &peci_cputemp_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+/*
+ * RESOLVED_CORES PCI configuration register may have different location on
+ * different platforms.
+ */
+static struct resolved_cores_reg resolved_cores_reg_hsx = {
+	.bus = 1,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xb4,
+};
+
+static struct resolved_cores_reg resolved_cores_reg_icx = {
+	.bus = 14,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xd0,
+};
+
+static const struct cpu_info cpu_hsx = {
+	.reg		= &resolved_cores_reg_hsx,
+	.min_peci_revision = 0x33,
+	.thermal_margin_to_millidegree = &dts_eight_dot_eight_to_millidegree,
+};
+
+static const struct cpu_info cpu_icx = {
+	.reg		= &resolved_cores_reg_icx,
+	.min_peci_revision = 0x40,
+	.thermal_margin_to_millidegree = &dts_ten_dot_six_to_millidegree,
+};
+
+static const struct auxiliary_device_id peci_cputemp_ids[] = {
+	{
+		.name = "peci_cpu.cputemp.hsx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdxd",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.skx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icx",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icxd",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_cputemp_ids);
+
+static struct auxiliary_driver peci_cputemp_driver = {
+	.probe		= peci_cputemp_probe,
+	.id_table	= peci_cputemp_ids,
+};
+
+module_auxiliary_driver(peci_cputemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI cputemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:45 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:45 +0100
Subject: [PATCH v5 11/13] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-12-iwona.winiarska@intel.com>

Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
are accessible via the processor PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain thermal readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/hwmon/peci/Kconfig    |  13 +
 drivers/hwmon/peci/Makefile   |   2 +
 drivers/hwmon/peci/dimmtemp.c | 630 ++++++++++++++++++++++++++++++++++
 3 files changed, 645 insertions(+)
 create mode 100644 drivers/hwmon/peci/dimmtemp.c

diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
index e10eed68d70a..9d32a57badfe 100644
--- a/drivers/hwmon/peci/Kconfig
+++ b/drivers/hwmon/peci/Kconfig
@@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
 	  This driver can also be built as a module. If so, the module
 	  will be called peci-cputemp.
 
+config SENSORS_PECI_DIMMTEMP
+	tristate "PECI DIMM temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI hwmon
+	  driver which provides Temperature Sensor on DIMM readings that are
+	  accessible via the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-dimmtemp.
+
 config SENSORS_PECI
 	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
index e8a0ada5ab1f..191cfa0227f3 100644
--- a/drivers/hwmon/peci/Makefile
+++ b/drivers/hwmon/peci/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 peci-cputemp-y := cputemp.o
+peci-dimmtemp-y := dimmtemp.o
 
 obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
+obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)	+= peci-dimmtemp.o
diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
new file mode 100644
index 000000000000..c8222354c005
--- /dev/null
+++ b/drivers/hwmon/peci/dimmtemp.c
@@ -0,0 +1,630 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+#include <linux/workqueue.h>
+
+#include "common.h"
+
+#define DIMM_MASK_CHECK_DELAY_JIFFIES	msecs_to_jiffies(5000)
+
+/* Max number of channel ranks and DIMM index per channel */
+#define CHAN_RANK_MAX_ON_HSX	8
+#define DIMM_IDX_MAX_ON_HSX	3
+#define CHAN_RANK_MAX_ON_BDX	4
+#define DIMM_IDX_MAX_ON_BDX	3
+#define CHAN_RANK_MAX_ON_BDXD	2
+#define DIMM_IDX_MAX_ON_BDXD	2
+#define CHAN_RANK_MAX_ON_SKX	6
+#define DIMM_IDX_MAX_ON_SKX	2
+#define CHAN_RANK_MAX_ON_ICX	8
+#define DIMM_IDX_MAX_ON_ICX	2
+#define CHAN_RANK_MAX_ON_ICXD	4
+#define DIMM_IDX_MAX_ON_ICXD	2
+
+#define CHAN_RANK_MAX		CHAN_RANK_MAX_ON_HSX
+#define DIMM_IDX_MAX		DIMM_IDX_MAX_ON_HSX
+#define DIMM_NUMS_MAX		(CHAN_RANK_MAX * DIMM_IDX_MAX)
+
+#define CPU_SEG_MASK		GENMASK(23, 16)
+#define GET_CPU_SEG(x)		(((x) & CPU_SEG_MASK) >> 16)
+#define CPU_BUS_MASK		GENMASK(7, 0)
+#define GET_CPU_BUS(x)		((x) & CPU_BUS_MASK)
+
+#define DIMM_TEMP_MAX		GENMASK(15, 8)
+#define DIMM_TEMP_CRIT		GENMASK(23, 16)
+#define GET_TEMP_MAX(x)		(((x) & DIMM_TEMP_MAX) >> 8)
+#define GET_TEMP_CRIT(x)	(((x) & DIMM_TEMP_CRIT) >> 16)
+
+#define NO_DIMM_RETRY_COUNT_MAX	5
+
+struct peci_dimmtemp;
+
+struct dimm_info {
+	int chan_rank_max;
+	int dimm_idx_max;
+	u8 min_peci_revision;
+	int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
+			       int chan_rank, u32 *data);
+};
+
+struct peci_dimm_thresholds {
+	long temp_max;
+	long temp_crit;
+	struct peci_sensor_state state;
+};
+
+enum peci_dimm_threshold_type {
+	temp_max_type,
+	temp_crit_type,
+};
+
+struct peci_dimmtemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct dimm_info *gen_info;
+	struct delayed_work detect_work;
+	struct {
+		struct peci_sensor_data temp;
+		struct peci_dimm_thresholds thresholds;
+	} dimm[DIMM_NUMS_MAX];
+	char **dimmtemp_label;
+	DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
+	u8 no_dimm_retry_count;
+};
+
+static u8 __dimm_temp(u32 reg, int dimm_order)
+{
+	return (reg >> (dimm_order * 8)) & 0xff;
+}
+
+static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long *val)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	int ret = 0;
+	u32 data;
+
+	mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &data);
+	if (ret)
+		goto unlock;
+
+	priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
+
+skip_update:
+	*val = priv->dimm[dimm_no].temp.value;
+unlock:
+	mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
+	return ret;
+}
+
+static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	u32 data;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
+		return 0;
+
+	ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
+	if (ret == -ENODATA) /* Use default or previous value */
+		return 0;
+	if (ret)
+		return ret;
+
+	priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * MILLIDEGREE_PER_DEGREE;
+	priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
+
+	return 0;
+}
+
+static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum peci_dimm_threshold_type type,
+			       int dimm_no, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
+	ret = update_thresholds(priv, dimm_no);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case temp_max_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_max;
+		break;
+	case temp_crit_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_crit;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
+
+	return ret;
+}
+
+static int dimmtemp_read_string(struct device *dev,
+				enum hwmon_sensor_types type,
+				u32 attr, int channel, const char **str)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = (const char *)priv->dimmtemp_label[channel];
+
+	return 0;
+}
+
+static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
+			 u32 attr, int channel, long *val)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		return get_dimm_temp(priv, channel, val);
+	case hwmon_temp_max:
+		return get_dimm_thresholds(priv, temp_max_type, channel, val);
+	case hwmon_temp_crit:
+		return get_dimm_thresholds(priv, temp_crit_type, channel, val);
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static umode_t dimmtemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				   u32 attr, int channel)
+{
+	const struct peci_dimmtemp *priv = data;
+
+	if (test_bit(channel, priv->dimm_mask))
+		return 0444;
+
+	return 0;
+}
+
+static const struct hwmon_ops peci_dimmtemp_ops = {
+	.is_visible = dimmtemp_is_visible,
+	.read_string = dimmtemp_read_string,
+	.read = dimmtemp_read,
+};
+
+static int check_populated_dimms(struct peci_dimmtemp *priv)
+{
+	int chan_rank_max = priv->gen_info->chan_rank_max;
+	int dimm_idx_max = priv->gen_info->dimm_idx_max;
+	u32 chan_rank_empty = 0;
+	u64 dimm_mask = 0;
+	int chan_rank, dimm_idx, ret;
+	u32 pcs;
+
+	BUILD_BUG_ON(BITS_PER_TYPE(chan_rank_empty) < CHAN_RANK_MAX);
+	BUILD_BUG_ON(BITS_PER_TYPE(dimm_mask) < DIMM_NUMS_MAX);
+	if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
+		WARN_ONCE(1, "Unsupported number of DIMMs - chan_rank_max: %d, dimm_idx_max: %d",
+			  chan_rank_max, dimm_idx_max);
+		return -EINVAL;
+	}
+
+	for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
+		ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &pcs);
+		if (ret) {
+			/*
+			 * Overall, we expect either success or -EINVAL in
+			 * order to determine whether DIMM is populated or not.
+			 * For anything else we fall back to deferring the
+			 * detection to be performed at a later point in time.
+			 */
+			if (ret == -EINVAL) {
+				chan_rank_empty |= BIT(chan_rank);
+				continue;
+			}
+
+			return -EAGAIN;
+		}
+
+		for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
+			if (__dimm_temp(pcs, dimm_idx))
+				dimm_mask |= BIT(chan_rank * dimm_idx_max + dimm_idx);
+	}
+
+	/*
+	 * If we got all -EINVALs, it means that the CPU doesn't have any
+	 * DIMMs. Unfortunately, it may also happen at the very start of
+	 * host platform boot. Retrying a couple of times lets us make sure
+	 * that the state is persistent.
+	 */
+	if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0)) {
+		if (priv->no_dimm_retry_count < NO_DIMM_RETRY_COUNT_MAX) {
+			priv->no_dimm_retry_count++;
+
+			return -EAGAIN;
+		}
+
+		return -ENODEV;
+	}
+
+	/*
+	 * It's possible that memory training is not done yet. In this case we
+	 * defer the detection to be performed at a later point in time.
+	 */
+	if (!dimm_mask) {
+		priv->no_dimm_retry_count = 0;
+		return -EAGAIN;
+	}
+
+	dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
+
+	bitmap_from_u64(priv->dimm_mask, dimm_mask);
+
+	return 0;
+}
+
+static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
+{
+	int rank = chan / priv->gen_info->dimm_idx_max;
+	int idx = chan % priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
+						    "DIMM %c%d", 'A' + rank,
+						    idx + 1);
+	if (!priv->dimmtemp_label[chan])
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const u32 peci_dimmtemp_temp_channel_config[] = {
+	[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
+	0
+};
+
+static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_dimmtemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
+	&peci_dimmtemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
+	.ops = &peci_dimmtemp_ops,
+	.info = peci_dimmtemp_temp_info,
+};
+
+static int create_dimm_temp_info(struct peci_dimmtemp *priv)
+{
+	int ret, i, channels;
+	struct device *dev;
+
+	/*
+	 * We expect to either find populated DIMMs and carry on with creating
+	 * sensors, or find out that there are no DIMMs populated.
+	 * All other states mean that the platform never reached the state that
+	 * allows to check DIMM state - causing us to retry later on.
+	 */
+	ret = check_populated_dimms(priv);
+	if (ret == -ENODEV) {
+		dev_dbg(priv->dev, "No DIMMs found\n");
+		return 0;
+	} else if (ret) {
+		schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
+		dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
+		return ret;
+	}
+
+	channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label = devm_kzalloc(priv->dev, channels * sizeof(char *), GFP_KERNEL);
+	if (!priv->dimmtemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
+		ret = create_dimm_temp_label(priv, i);
+		if (ret)
+			return ret;
+		mutex_init(&priv->dimm[i].thresholds.state.lock);
+		mutex_init(&priv->dimm[i].temp.state.lock);
+	}
+
+	dev = devm_hwmon_device_register_with_info(priv->dev, priv->name, priv,
+						   &peci_dimmtemp_chip_info, NULL);
+	if (IS_ERR(dev)) {
+		dev_err(priv->dev, "Failed to register hwmon device\n");
+		return PTR_ERR(dev);
+	}
+
+	dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
+
+	return 0;
+}
+
+static void create_dimm_temp_info_delayed(struct work_struct *work)
+{
+	struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
+						  struct peci_dimmtemp,
+						  detect_work);
+	int ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN)
+		dev_err(priv->dev, "Failed to populate DIMM temp info\n");
+}
+
+static void remove_delayed_work(void *_priv)
+{
+	struct peci_dimmtemp *priv = _priv;
+
+	cancel_delayed_work_sync(&priv->detect_work);
+}
+
+static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_dimmtemp *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct dimm_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
+
+	ret = devm_add_action_or_reset(priv->dev, remove_delayed_work, priv);
+	if (ret)
+		return ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN) {
+		dev_err(dev, "Failed to populate DIMM temp info\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 20, Function 0: IMC 0 channel 0 -> rank 0
+	 * Device 20, Function 1: IMC 0 channel 1 -> rank 1
+	 * Device 21, Function 0: IMC 0 channel 2 -> rank 2
+	 * Device 21, Function 1: IMC 0 channel 3 -> rank 3
+	 * Device 23, Function 0: IMC 1 channel 0 -> rank 4
+	 * Device 23, Function 1: IMC 1 channel 1 -> rank 5
+	 * Device 24, Function 0: IMC 1 channel 2 -> rank 6
+	 * Device 24, Function 1: IMC 1 channel 3 -> rank 7
+	 */
+	dev = 20 + chan_rank / 2 + chan_rank / 4;
+	func = chan_rank % 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 2
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 3
+	 */
+	dev = 10 + chan_rank / 2 * 2;
+	func = (chan_rank % 2) ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 11, Function 2: IMC 0 channel 2 -> rank 2
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 3
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 4
+	 * Device 13, Function 2: IMC 1 channel 2 -> rank 5
+	 */
+	dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
+	func = chan_rank % 3 == 1 ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u32 reg_val;
+	u64 offset;
+	int ret;
+	u8 dev;
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, &reg_val);
+	if (ret || !(reg_val & BIT(31)))
+		return -ENODATA; /* Use default or previous value */
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, &reg_val);
+	if (ret)
+		return -ENODATA; /* Use default or previous value */
+
+	/*
+	 * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
+	 * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
+	 * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
+	 * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
+	 * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
+	 * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
+	 * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
+	 * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
+	 */
+	dev = 26 + chan_rank / 2;
+	offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
+
+	ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val), GET_CPU_BUS(reg_val),
+			     dev, 0, offset, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct dimm_info dimm_hsx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_HSX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_HSX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDXD,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_bdxd,
+};
+
+static const struct dimm_info dimm_skx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_SKX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_SKX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_skx,
+};
+
+static const struct dimm_info dimm_icx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICX,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct dimm_info dimm_icxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICXD,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
+	{
+		.name = "peci_cpu.dimmtemp.hsx",
+		.driver_data = (kernel_ulong_t)&dimm_hsx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdx",
+		.driver_data = (kernel_ulong_t)&dimm_bdx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdxd",
+		.driver_data = (kernel_ulong_t)&dimm_bdxd,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.skx",
+		.driver_data = (kernel_ulong_t)&dimm_skx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icx",
+		.driver_data = (kernel_ulong_t)&dimm_icx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icxd",
+		.driver_data = (kernel_ulong_t)&dimm_icxd,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
+
+static struct auxiliary_driver peci_dimmtemp_driver = {
+	.probe		= peci_dimmtemp_probe,
+	.id_table	= peci_dimmtemp_ids,
+};
+
+module_auxiliary_driver(peci_dimmtemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI dimmtemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:46 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:46 +0100
Subject: [PATCH v5 12/13] docs: hwmon: Document PECI drivers
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-13-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

Add documentation for peci-cputemp driver that provides DTS thermal
readings for CPU packages and CPU cores, and peci-dimmtemp driver that
provides Temperature Sensor on DIMM readings.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 Documentation/hwmon/index.rst         |  2 +
 Documentation/hwmon/peci-cputemp.rst  | 90 +++++++++++++++++++++++++++
 Documentation/hwmon/peci-dimmtemp.rst | 57 +++++++++++++++++
 MAINTAINERS                           |  2 +
 4 files changed, 151 insertions(+)
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 7046bf1870d9..6ebd73a55c26 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -156,6 +156,8 @@ Hardware Monitoring Kernel Drivers
    pcf8591
    pim4328
    pm6764tr
+   peci-cputemp
+   peci-dimmtemp
    pmbus
    powr1220
    pxe1610
diff --git a/Documentation/hwmon/peci-cputemp.rst b/Documentation/hwmon/peci-cputemp.rst
new file mode 100644
index 000000000000..fe0422248dc5
--- /dev/null
+++ b/Documentation/hwmon/peci-cputemp.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+Kernel driver peci-cputemp
+==========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides Digital
+Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that are
+accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+temp1_label		"Die"
+temp1_input		Provides current die temperature of the CPU package.
+temp1_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp1_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp1_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp2_label		"DTS"
+temp2_input		Provides current temperature of the CPU package scaled
+			to match DTS thermal profile.
+temp2_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp2_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp2_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp3_label		"Tcontrol"
+temp3_input		Provides current Tcontrol temperature of the CPU
+			package which is also known as Fan Temperature target.
+			Indicates the relative value from thermal monitor trip
+			temperature at which fans should be engaged.
+temp3_crit		Provides Tcontrol critical value of the CPU package
+			which is same to Tjmax.
+
+temp4_label		"Tthrottle"
+temp4_input		Provides current Tthrottle temperature of the CPU
+			package. Used for throttling temperature. If this value
+			is allowed and lower than Tjmax - the throttle will
+			occur and reported at lower than Tjmax.
+
+temp5_label		"Tjmax"
+temp5_input		Provides the maximum junction temperature, Tjmax of the
+			CPU package.
+
+temp[6-N]_label		Provides string "Core X", where X is resolved core
+			number.
+temp[6-N]_input		Provides current temperature of each core.
+
+======================= =======================================================
diff --git a/Documentation/hwmon/peci-dimmtemp.rst b/Documentation/hwmon/peci-dimmtemp.rst
new file mode 100644
index 000000000000..e562aed620de
--- /dev/null
+++ b/Documentation/hwmon/peci-dimmtemp.rst
@@ -0,0 +1,57 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver peci-dimmtemp
+===========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides
+Temperature sensor on DIMM readings that are accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+
+temp[N]_label		Provides string "DIMM CI", where C is DIMM channel and
+			I is DIMM index of the populated DIMM.
+temp[N]_input		Provides current temperature of the populated DIMM.
+temp[N]_max		Provides thermal control temperature of the DIMM.
+temp[N]_crit		Provides shutdown temperature of the DIMM.
+
+======================= =======================================================
+
+Note:
+	DIMM temperature attributes will appear when the client CPU's BIOS
+	completes memory training and testing.
diff --git a/MAINTAINERS b/MAINTAINERS
index 3b9047b814fd..6ae398baffc8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14934,6 +14934,8 @@ PECI HARDWARE MONITORING DRIVERS
 M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	linux-hwmon at vger.kernel.org
 S:	Supported
+F:	Documentation/hwmon/peci-cputemp.rst
+F:	Documentation/hwmon/peci-dimmtemp.rst
 F:	drivers/hwmon/peci/
 
 PECI SUBSYSTEM
-- 
2.31.1



From iwona.winiarska at intel.com  Wed Jan 12 15:02:47 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Thu, 13 Jan 2022 00:02:47 +0100
Subject: [PATCH v5 13/13] docs: Add PECI documentation
In-Reply-To: <20220112230247.982212-1-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
Message-ID: <20220112230247.982212-14-iwona.winiarska@intel.com>

Add a brief overview of PECI and PECI wire interface.
The documentation also contains kernel-doc for PECI subsystem internals
and PECI CPU Driver API.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 Documentation/index.rst      |  1 +
 Documentation/peci/index.rst | 16 +++++++++++
 Documentation/peci/peci.rst  | 51 ++++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |  1 +
 4 files changed, 69 insertions(+)
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst

diff --git a/Documentation/index.rst b/Documentation/index.rst
index 54ce34fd6fbd..7671f2cd474f 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -137,6 +137,7 @@ needed).
    misc-devices/index
    scheduler/index
    mhi/index
+   peci/index
 
 Architecture-agnostic documentation
 -----------------------------------
diff --git a/Documentation/peci/index.rst b/Documentation/peci/index.rst
new file mode 100644
index 000000000000..989de10416e7
--- /dev/null
+++ b/Documentation/peci/index.rst
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+====================
+Linux PECI Subsystem
+====================
+
+.. toctree::
+
+   peci
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/peci/peci.rst b/Documentation/peci/peci.rst
new file mode 100644
index 000000000000..331b1ec00e22
--- /dev/null
+++ b/Documentation/peci/peci.rst
@@ -0,0 +1,51 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+========
+Overview
+========
+
+The Platform Environment Control Interface (PECI) is a communication
+interface between Intel processor and management controllers
+(e.g. Baseboard Management Controller, BMC).
+PECI provides services that allow the management controller to
+configure, monitor and debug platform by accessing various registers.
+It defines a dedicated command protocol, where the management
+controller is acting as a PECI originator and the processor - as
+a PECI responder.
+PECI can be used in both single processor and multiple-processor based
+systems.
+
+NOTE:
+Intel PECI specification is not released as a dedicated document,
+instead it is a part of External Design Specification (EDS) for given
+Intel CPU. External Design Specifications are usually not publicly
+available.
+
+PECI Wire
+---------
+
+PECI Wire interface uses a single wire for self-clocking and data
+transfer. It does not require any additional control lines - the
+physical layer is a self-clocked one-wire bus signal that begins each
+bit with a driven, rising edge from an idle near zero volts. The
+duration of the signal driven high allows to determine whether the bit
+value is logic '0' or logic '1'. PECI Wire also includes variable data
+rate established with every message.
+
+For PECI Wire, each processor package will utilize unique, fixed
+addresses within a defined range and that address should
+have a fixed relationship with the processor socket ID - if one of the
+processors is removed, it does not affect addresses of remaining
+processors.
+
+PECI subsystem internals
+------------------------
+
+.. kernel-doc:: include/linux/peci.h
+.. kernel-doc:: drivers/peci/internal.h
+.. kernel-doc:: drivers/peci/core.c
+.. kernel-doc:: drivers/peci/request.c
+
+PECI CPU Driver API
+-------------------
+.. kernel-doc:: drivers/peci/cpu.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 6ae398baffc8..908ebdf5ffff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14943,6 +14943,7 @@ M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
+F:	Documentation/peci/
 F:	drivers/peci/
 F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
-- 
2.31.1



From yuzhao at google.com  Wed Jan 12 15:43:15 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 12 Jan 2022 16:43:15 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd6q0QdLVTS53vu4@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz> <Yd4oaUwHkpadAKwe@google.com>
 <Yd6q0QdLVTS53vu4@dhcp22.suse.cz>
Message-ID: <Yd9nk0qlK3jK9baN@google.com>

On Wed, Jan 12, 2022 at 11:17:53AM +0100, Michal Hocko wrote:
> On Tue 11-01-22 18:01:29, Yu Zhao wrote:
> > On Mon, Jan 10, 2022 at 05:57:39PM +0100, Michal Hocko wrote:
> > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > [...]
> > > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > > +{
> > > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > > +		.test_walk = should_skip_vma,
> > > > +		.p4d_entry = walk_pud_range,
> > > > +	};
> > > > +
> > > > +	int err;
> > > > +#ifdef CONFIG_MEMCG
> > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > +#endif
> > > > +
> > > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > > +
> > > > +	do {
> > > > +		unsigned long start = walk->next_addr;
> > > > +		unsigned long end = mm->highest_vm_end;
> > > > +
> > > > +		err = -EBUSY;
> > > > +
> > > > +		rcu_read_lock();
> > > > +#ifdef CONFIG_MEMCG
> > > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > > +			goto contended;
> > > > +#endif
> > > 
> > > Why do you need to check for moving_account?
> > 
> > This check, if succeeds, blocks memcg migration.
> 
> OK, I can see that you rely on the RCU here for the synchronization. A
> comment which mentions mem_cgroup_move_charge would be helpful for
> clarity.

Will do

> Is there any reason you are not using folio_memcg_lock in the
> pte walk instead?

We have a particular lruvec (the first arg), hence a particular memcg
to lock. But we don't have a particular page to lock.


From andrzej.hajda at intel.com  Wed Jan 12 16:14:14 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Thu, 13 Jan 2022 01:14:14 +0100
Subject: [v8, PATCH 1/3] drm/dsi: transfer DSI HS packets ending at the
 same time
In-Reply-To: <20220112153639.12343-2-rex-bc.chen@mediatek.com>
References: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
 <20220112153639.12343-2-rex-bc.chen@mediatek.com>
Message-ID: <2f0fd4a9-4d24-a6b7-12ae-51763f304761@intel.com>

Hi,

On 12.01.2022 16:36, Rex-BC Chen wrote:
> Since a HS transmission is composed of an arbitrary number
> of bytes that may not be an integer multiple of lanes, some
> lanes may run out of data before others.
> (Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)
>
> However, for some DSI RX devices (for example, anx7625),
> there is a limitation that packet number should be the same
> on all DSI lanes. In other words, they need to end a HS at
> the same time.


Is it documented in anx7625 manual? Is it confirmed with hw team?

If not, how it was detected? Have you tried to find workaround for it by 
inspecting registers, maybe it is just matter of clock gating deferral, 
timings or sth similar ???.

>
> Because this limitation is for some specific DSI RX devices,
> it is more reasonable to put the enable control in these
> DSI RX drivers. If DSI TX driver knows the information,
> they can adjust the setting for this situation.
>
> Therefore, add a flag to control this situation beacuse the
> mipi DSI specification is not forbidden this situation.


I am not sure what you mean here.

I have an impression (according t 6.1.3 of spec) that devices should 
allow transmission of arbitrary number of bytes, so this is bug in hw/fw.

The question if it can be fixed. If not patches are welcome.


>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>   include/drm/drm_mipi_dsi.h | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 147e51b6d241..df4d15345326 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -177,6 +177,8 @@ struct mipi_dsi_device_info {
>    * @lp_rate: maximum lane frequency for low power mode in hertz, this should
>    * be set to the real limits of the hardware, zero is only accepted for
>    * legacy drivers
> + * @hs_packet_end_aligned: transfer DSI HS packets ending at the same time
> + * for all DSI lanes
>    */
>   struct mipi_dsi_device {
>   	struct mipi_dsi_host *host;
> @@ -189,6 +191,7 @@ struct mipi_dsi_device {
>   	unsigned long mode_flags;
>   	unsigned long hs_rate;
>   	unsigned long lp_rate;
> +	bool hs_packet_end_aligned;


Maybe it would be better to add another mode_flag.


Regards

Andrzej



>   };
>   
>   #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"


From helgaas at kernel.org  Wed Jan 12 16:19:21 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 12 Jan 2022 18:19:21 -0600
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220107234658.oav7oofcbwa7o6sz@pali>
Message-ID: <20220113001921.GA286275@bhelgaas>

On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Roh?r wrote:
> On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > > Properly propagate failure from mvebu_pcie_add_windows() function back to
> > > > > the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> > > > > PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> > > > > On error set base value higher than limit value which indicates that
> > > > > address range is disabled. 
> > > > 
> > > > Does the spec say that if software programs something invalid,
> > > > hardware should proactively set the base and limit registers to
> > > > disable the window?
> > > 
> > > No. But this patch address something totally different. Software can do
> > > fully valid operation, e.g. try to set forwarding memory window as large
> > > as possible. But because this driver "emulates" pci bridge by calling
> > > software/kernel function (mvebu_pcie_add_windows), some operations which
> > > in real HW cannot happen, are possible in software.
> > > 
> > > For example there are limitations in sizes of forwarding memory windows,
> > > because it is done by mvebu-mbus driver, which is responsible for
> > > configuring mapping and forwarding of PCIe I/O and MEM windows. And due
> > > to Marvell HW, there are restrictions which are not in PCIe HW.
> > > 
> > > Currently if such error happens, obviously kernel is not able to set
> > > PCIe windows and it just print warnings to dmesg. Trying to access these
> > > windows would result in the worst case in crashes.
> > > 
> > > With this change when mvebu_pcie_add_windows() function fails then into
> > > emulated config space is put information that particular forwarding
> > > window is disabled. I think that it is better to indicate it in config
> > > space what is the current "reality" of hardware configuration. If window
> > > is disabled in real-HW (meaning in mvebu-mbus driver) then show it also
> > > in emulated config space of pci bridge.
> > > 
> > > Do you have better idea what should emulated pci bridge do, if software
> > > try to set fully valid configuration of forwarding window, but it is not
> > > possible to achieve it (even compliant PCI bridge must be able to do
> > > it)?
> > 
> > On an ACPI system, the host bridge window sizes are constrained by the
> > host bridge _CRS method.  I assume there's a similar constraint in DT.
> > 
> > Is the fact that mvebu_pcie_add_windows() can fail a symptom of a DT
> > that describes more available space than mvebu-bus can map?
> 
> Memory maps for mvebu are more complicated. There is no explicit size in
> DT ranges property as it is dynamically allocated by mvebu-mbus:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47

I wish I knew how to really interpret those "ranges" properties.  (Is
there a good description in Documentation/ somewhere?  All I've found
so far is https://elinux.org/Device_Tree_Usage, which is good, but
doesn't match this example completely.)

I see:

  pciec: pcie {
    ranges = <...>;
    pcie1: pcie at 1,0 {
      ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
	        0x81000000 0 0 0x81000000 0x1 0 1 0>;
    };
    pcie2: pcie at 2,0 {
      ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
	        0x81000000 0 0 0x81000000 0x2 0 1 0>;
    };
    pcie3: pcie at 3,0 {
      ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
	        0x81000000 0 0 0x81000000 0x3 0 1 0>;
    };
    pcie4: pcie at 4,0 {
      ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
	        0x81000000 0 0 0x81000000 0x4 0 1 0>;
    };
  };

What does this look like in dmesg, i.e., what CPU address ranges are
mapped to what PCI bus addresses?

Are pcie1, pcie2, etc Root Ports?  Or are they each separate host
bridges (they each have "bus-range = <0x00 0xff>")?

Is space from pciec dynamically assigned to pcie1, pcie2, etc?  If so,
I assume there are more restrictions on the size and alignment than on
PCI bridge windows, which allow size/alignment down to 1MB?

I'm trying to see how this could be described in ACPI because that's a
fairly general model that accommodates most machines.  Possibly
describing mvebu in ACPI would involve losing some flexibility.

Bjorn


From thunder.leizhen at huawei.com  Wed Jan 12 17:17:38 2022
From: thunder.leizhen at huawei.com (Leizhen (ThunderTown))
Date: Thu, 13 Jan 2022 09:17:38 +0800
Subject: [PATCH v19 11/13] arm64: kdump: reimplement crashkernel=X
In-Reply-To: <e48ac849-cc3d-3c0b-e159-7408af61eece@oracle.com>
References: <20211228132612.1860-1-thunder.leizhen@huawei.com>
 <20211228132612.1860-12-thunder.leizhen@huawei.com>
 <e48ac849-cc3d-3c0b-e159-7408af61eece@oracle.com>
Message-ID: <6bcea8a4-c244-bb0c-ff55-92cbe463b4cc@huawei.com>



On 2022/1/12 22:45, Dave Kleikamp wrote:
> On 12/28/21 7:26AM, Zhen Lei wrote:
>> From: Chen Zhou <chenzhou10 at huawei.com>
>>
>> There are following issues in arm64 kdump:
>> 1. We use crashkernel=X to reserve crashkernel below 4G, which
>> will fail when there is no enough low memory.
>> 2. If reserving crashkernel above 4G, in this case, crash dump
>> kernel will boot failure because there is no low memory available
>> for allocation.
>>
>> To solve these issues, change the behavior of crashkernel=X and
>> introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
>> in DMA zone, and fall back to high allocation if it fails.
>> We can also use "crashkernel=X,high" to select a region above DMA zone,
>> which also tries to allocate at least 256M in DMA zone automatically.
>> "crashkernel=Y,low" can be used to allocate specified size low memory.
>>
>> Another minor change, there may be two regions reserved for crash
>> dump kernel, in order to distinct from the high region and make no
>> effect to the use of existing kexec-tools, rename the low region as
>> "Crash kernel (low)".
>>
>> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
>> Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
>> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
>> ---
>> ? arch/arm64/kernel/machine_kexec.c????? |? 5 +++-
>> ? arch/arm64/kernel/machine_kexec_file.c | 12 ++++++--
>> ? arch/arm64/kernel/setup.c????????????? | 13 +++++++-
>> ? arch/arm64/mm/init.c?????????????????? | 41 ++++++++++----------------
>> ? 4 files changed, 42 insertions(+), 29 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
>> index 6fb31c117ebe08c..6665bf31f6b6a19 100644
>> --- a/arch/arm64/kernel/machine_kexec.c
>> +++ b/arch/arm64/kernel/machine_kexec.c
>> @@ -327,7 +327,10 @@ bool crash_is_nosave(unsigned long pfn)
>> ? ????? /* in reserved memory? */
>> ????? addr = __pfn_to_phys(pfn);
>> -??? if ((addr < crashk_res.start) || (crashk_res.end < addr))
>> +??? if (((addr < crashk_res.start) || (crashk_res.end < addr)) && !crashk_low_res.end)
>> +??????? return false;
>> +
>> +??? if ((addr < crashk_low_res.start) || (crashk_low_res.end < addr))
>> ????????? return false;
>> ? ????? if (!kexec_crash_image)
>> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
>> index 59c648d51848886..889951291cc0f9c 100644
>> --- a/arch/arm64/kernel/machine_kexec_file.c
>> +++ b/arch/arm64/kernel/machine_kexec_file.c
>> @@ -65,10 +65,18 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
>> ? ????? /* Exclude crashkernel region */
>> ????? ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
>> +??? if (ret)
>> +??????? goto out;
>> +
>> +??? if (crashk_low_res.end) {
>> +??????? ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
>> +??????? if (ret)
>> +??????????? goto out;
>> +??? }
>> ? -??? if (!ret)
>> -??????? ret =? crash_prepare_elf64_headers(cmem, true, addr, sz);
>> +??? ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>> ? +out:
>> ????? kfree(cmem);
>> ????? return ret;
>> ? }
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index be5f85b0a24de69..4bb2e55366be64d 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -248,7 +248,18 @@ static void __init request_standard_resources(void)
>> ????????????? kernel_data.end <= res->end)
>> ????????????? request_resource(res, &kernel_data);
>> ? #ifdef CONFIG_KEXEC_CORE
>> -??????? /* Userspace will find "Crash kernel" region in /proc/iomem. */
>> +??????? /*
>> +???????? * Userspace will find "Crash kernel" or "Crash kernel (low)"
>> +???????? * region in /proc/iomem.
>> +???????? * In order to distinct from the high region and make no effect
>> +???????? * to the use of existing kexec-tools, rename the low region as
>> +???????? * "Crash kernel (low)".
>> +???????? */
>> +??????? if (crashk_low_res.end && crashk_low_res.start >= res->start &&
>> +??????????????? crashk_low_res.end <= res->end) {
>> +??????????? crashk_low_res.name = "Crash kernel (low)";
>> +??????????? request_resource(res, &crashk_low_res);
>> +??????? }
>> ????????? if (crashk_res.end && crashk_res.start >= res->start &&
>> ????????????? crashk_res.end <= res->end)
>> ????????????? request_resource(res, &crashk_res);
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index be4595dc7459115..91b8038a1529068 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -74,41 +74,32 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>> ?? */
>> ? static void __init reserve_crashkernel(void)
>> ? {
>> -??? unsigned long long crash_base, crash_size;
>> -??? unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
>> +??? unsigned long long crash_size, crash_base, total_mem, low_size;
> 
> low_size needs to be initialized to -1.
> 
> If parse_crashkernel() succeeds, then an uninitialized low_size will be passed to reserve_crashkernel_mem().

Right, thanks, I noticed that too. I'm waiting for v5.17-rc1 to release v20.

In addition, I found that the current implementation on x86 was problematic in case
"crashkernel=4G crashkernel=512M,low". According to the document, "crashkernel=512M,low"
should not take effect at this case. But reserve_crashkernel_low() didn't do that well.

> 
>> +??? bool high = false;
>> ????? int ret;
>> ? -??? ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
>> -??????????????? &crash_size, &crash_base);
>> -??? /* no crashkernel= or invalid value specified */
>> -??? if (ret || !crash_size)
>> -??????? return;
>> -
>> -??? crash_size = PAGE_ALIGN(crash_size);
>> -
>> -??? /* User specifies base address explicitly. */
>> -??? if (crash_base)
>> -??????? crash_max = crash_base + crash_size;
>> +??? total_mem = memblock_phys_mem_size();
>> ? -??? /* Current arm64 boot protocol requires 2MB alignment */
>> -??? crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
>> -?????????????????????????? crash_base, crash_max);
>> -??? if (!crash_base) {
>> -??????? pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>> -??????????? crash_size);
>> -??????? return;
>> +??? ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
>> +??? if (ret != 0 || crash_size <= 0) {
>> +??????? /* crashkernel=X,high and possible crashkernel=Y,low */
>> +??????? ret = parse_crashkernel_high_low(boot_command_line, &crash_size, &low_size);
>> +??????? if (ret)
>> +??????????? return;
>> +??????? high = true;
>> ????? }
>> ? -??? pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>> -??????? crash_base, crash_base + crash_size, crash_size >> 20);
>> +??? ret = reserve_crashkernel_mem(total_mem, crash_size, crash_base, low_size, high);
>> +??? if (ret)
>> +??????? return;
>> ? ????? /*
>> ?????? * The crashkernel memory will be removed from the kernel linear
>> ?????? * map. Inform kmemleak so that it won't try to access it.
>> ?????? */
>> -??? kmemleak_ignore_phys(crash_base);
>> -??? crashk_res.start = crash_base;
>> -??? crashk_res.end = crash_base + crash_size - 1;
>> +??? kmemleak_ignore_phys(crashk_res.start);
>> +??? if (crashk_low_res.end)
>> +??????? kmemleak_ignore_phys(crashk_low_res.start);
>> ? }
>> ? #else
>> ? static void __init reserve_crashkernel(void)
> 
> .
> 

-- 
Regards,
  Zhen Lei


From liuqi115 at huawei.com  Wed Jan 12 17:43:32 2022
From: liuqi115 at huawei.com (liuqi (BA))
Date: Thu, 13 Jan 2022 09:43:32 +0800
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAAgTQPUEgSf-E_GOUNY_=4Piiy0K_-5U_YVbnoMAZ94Q3ducOg@mail.gmail.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
 <dbcbc161-228d-ee78-e1f0-b59ad9b0a36f@huawei.com>
 <CAAgTQPUEgSf-E_GOUNY_=4Piiy0K_-5U_YVbnoMAZ94Q3ducOg@mail.gmail.com>
Message-ID: <dad6f2e1-732f-4456-a77c-ea937082c87f@huawei.com>



On 2022/1/12 20:21, Jianhua Liu wrote:
> On Wed, Jan 12, 2022 at 9:31 AM liuqi (BA) <liuqi115 at huawei.com> wrote:
>>
>>
>>
>> On 2022/1/4 10:35, Masami Hiramatsu wrote:
>>> Hi Jianhua,
>>>
>>> On Mon, 3 Jan 2022 17:03:33 +0800
>>> Jianhua Liu <jianhua.ljh at gmail.com> wrote:
>>>
>>>> Hi Qi,
>>>> I have tested your patch on UNISOC s9863a.
>>>> Test case "kprobe_example & kretprobe_example" is OK.
>>>>
>>>> Two point:
>>>> 1. backtrace is not perfect.
>>>>      optprobe_common does not saved frame pointer,
>>>>      backtrace lacks two calls.
>>>> such as for dup_mm: lack copy_process-->dup_mm
>>>> dup_mm backtrace from your patch:
>>>> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
>>>> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>>>> [  832.387083] Call trace:
>>>> [  832.387086]  dump_backtrace+0x0/0x1e0
>>>> [  832.387103]  show_stack+0x24/0x30
>>>> [  832.387112]  dump_stack_lvl+0x68/0x84
>>>> [  832.387123]  dump_stack+0x18/0x34
>>>> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
>>>> [  832.387143]  opt_pre_handler+0x84/0xc0
>>>> [  832.387154]  optprobe_optimized_callback+0xec/0x164
>>>> [  832.387164]  optprobe_common+0x70/0xc4
>>>> [  832.387173]  kernel_clone+0x98/0x440
>>>> [  832.387182]  __do_sys_clone+0x54/0x80
>>>> [  832.387191]  __arm64_sys_clone+0x2c/0x40
>>>> [  832.387199]  invoke_syscall+0x50/0x120
>>>> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
>>>> [  832.387217]  do_el0_svc+0x30/0x9c
>>>> [  832.387225]  el0_svc+0x20/0x60
>>>> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
>>>> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
>>>>
>>>>
>>>> dup_mm backtrace from other:
>>>> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
>>>> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
>>>> [  173.352304] Call trace:
>>>> [  173.352307]  dump_backtrace+0x0/0x1d4
>>>> [  173.352319]  show_stack+0x18/0x24
>>>> [  173.352326]  dump_stack_lvl+0x68/0x84
>>>> [  173.352333]  dump_stack+0x18/0x34
>>>> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
>>>> [  173.352347]  opt_pre_handler+0x74/0xb0
>>>> [  173.352354]  optimized_callback+0x108/0x130
>>>> [  173.352361]  optinsn_slot+0x258/0x1000
>>>> [  173.352366]  dup_mm+0x4/0x4b0
>>>> [  173.352373]  copy_process+0x1284/0x1360
>>>> [  173.352378]  kernel_clone+0x5c/0x3c0
>>>> [  173.352384]  __do_sys_clone+0x54/0x80
>>>> [  173.352390]  __arm64_sys_clone+0x24/0x30
>>>> [  173.352396]  invoke_syscall+0x48/0x114
>>>> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
>>>> [  173.352408]  do_el0_svc+0x24/0x90
>>>> [  173.352413]  el0_svc+0x20/0x60
>>>> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
>>>> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
>>>
>>
>> Hi Masami and Jianhua,
>>
>> optprobe_common() is added to minize size of code in trampoline, but
>> each trampoline is alloced as PAGE_SIZE, so optprobe_common() seems
>> unnecessary, and will make optprobe_trampoline.S much more complicated.
>> How about drop optprobe_common() and use a maro to reduce duplicate code .
>>
> 1. each trampoline is allocated as
> (MAX_OPTINSN_SIZE*sizeof(kprobe_opcode_t)), not PAGE_SIZE
> 2. MAX_OPTINSN_SIZE should be "((unsigned long)(optprobe_template_end
> - optprobe_template_entry)),
>     your MAX_OPTINSN_SIZE  is not accurate.
> 

Hi Jianhua,

Maybe I didn't express myself exactly, I mean that we use 
alloc_optinsn_page() to alloc PAGE_SIZE for each slot, and each time we 
copy instructions from a trampoline (which size of MAX_OPTINSN_SIZE) to 
slot.

So does the size of trampoline matters a lot? I mean I'm not sure 
minimize the size of trampoline by adding optprobe_common() could save 
memory...

> 3.optprobe_template_val in different kprobe may not be aligned with 8 byte.
>     ldr instruction for this value, may use address that not aligned 8 byte.
>     "ldr x0, 1f
>     .global optprobe_template_common"

uh I misunderstood. not sure I've missed something.Does 
optprobe_template_val aligned with 8 byte or not influence optprobe? We 
just load this address to X0 and use it as a input parameter.

Thanks,
Qi
> 
> Thanks,
> Jianhua
>> Thanks,
>> Qi
>>> Is the second one with your patch?
>>>
>>>>
>>>> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
>>>>      kernel/kprobe.c used only one PAGE_SIZE slot memory.
>>>
>>> Good catch!
>>> Qi, can you make an array (or bit map) of usage flags and
>>> manage the reserved memory?
>>>
>>> #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
>>> static bool insn_page_in_use[OPT_INSN_PAGES];
>>>
>>> void *alloc_optinsn_page(void)
>>> {
>>>        int i;
>>>
>>>        for (i = 0; i < OPT_INSN_PAGES; i++)
>>>                if (!insn_page_in_use[i])
>>>                        goto found;
>>>        return NULL;
>>> found:
>>>        insn_page_in_use[i] = true;
>>>        return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
>>> }
>>>
>>> void free_optinsn_page(void *page)
>>> {
>>>        unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
>>>
>>>        WARN_ONCE(idx & (PAGE_SIZE - 1));
>>>        idx >>= PAGE_SHIFT;
>>>        if (WARN_ONCE(idx >= OPT_INSN_PAGES))
>>>                return;
>>>        insn_page_in_use[idx] = false;
>>> }
>>>
>>> Thank you,
>>>
>>>
>>>
>>>
> .
> 


From tinghan.shen at mediatek.com  Wed Jan 12 18:17:21 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Thu, 13 Jan 2022 10:17:21 +0800
Subject: [PATCH v9 0/3] Add basic SoC support for mediatek mt8195
In-Reply-To: <e4f20498-3685-207f-2b94-0cb0ada725a4@oracle.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
 <e4f20498-3685-207f-2b94-0cb0ada725a4@oracle.com>
Message-ID: <903a27d5d68dddb23b9ace2708689a55f22714e8.camel@mediatek.com>

Hi Maciej,

On Wed, 2022-01-12 at 15:54 +0100, Maciej S. Szmigiero wrote:
> On 12.01.2022 12:47, Tinghan Shen wrote:
> > This series adds basic SoC support for Mediatek's SoC MT8195.
> 
> Nice patchset Tinghan, however I can't stop wondering why I was CCed
> on
> it (and Paolo and Sean, too) - this isn't KVM related at all.
> 
> scripts/get_maintainer.pl going wild?
> 
Thanks,
Maciej

I'm sorry. I just find out that the file pattern I used includes
unrelated files to this series.

I'll clean up the CC list at next version.

Best regards,
TingHan



From jassisinghbrar at gmail.com  Wed Jan 12 18:28:54 2022
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Wed, 12 Jan 2022 20:28:54 -0600
Subject: [GIT PULL] Mailbox changes for v5.17
Message-ID: <CABb+yY3o9pOY1EbedNRM_++MxM8TNFrB3EbrZ+07h_p3O4i1LA@mail.gmail.com>

Hi Linus,

The following changes since commit c9e6606c7fe92b50a02ce51dda82586ebdf99b48:

  Linux 5.16-rc8 (2022-01-02 14:23:25 -0800)

are available in the Git repository at:

  git://git.linaro.org/landing-teams/working/fujitsu/integration.git
tags/mailbox-v5.17

for you to fetch changes up to 869b6ca39c08c5b10eeb29d4b3c4bc433bf8ba5e:

  dt-bindings: mailbox: Add more protocol and client ID (2022-01-11
23:47:33 -0600)

----------------------------------------------------------------
- qcom: misc updates to qcom-ipcc driver
- mpfs: change compatible string
- pcc: fix handling of subtypes
avoid uninit variable
- mtk: add missing of_node_put
enable control_by_sw
silent probe-defer prints
fix gce_num for mt8192
- zynq: add missing of_node_put
- imx: check for NULL instead of IS_ERR
- appple: switch to generic compatibles
- hi3660: convert comments to kernel-doc notation

----------------------------------------------------------------
Conor Dooley (1):
      mailbox: change mailbox-mpfs compatible string

Dan Carpenter (1):
      mailbox: imx: Fix an IS_ERR() vs NULL bug

Hector Martin (2):
      dt-bindings: mailbox: apple,mailbox: Add generic and t6000 compatibles
      mailbox: apple: Bind to generic compatibles

Hsin-Yi Wang (1):
      mailbox: mtk-cmdq: Silent EPROBE_DEFER errors for clks

Huang Yiwei (4):
      mailbox: qcom-ipcc: Dynamic alloc for channel arrangement
      mailbox: qcom-ipcc: Support more IPCC instance
      mailbox: qcom-ipcc: Support interrupt wake up from suspend
      dt-bindings: mailbox: Add more protocol and client ID

Randy Dunlap (1):
      mailbox: hi3660: convert struct comments to kernel-doc notation

Sudeep Holla (2):
      mailbox: pcc: Avoid using the uninitialized variable 'dev'
      mailbox: pcc: Handle all PCC subtypes correctly in pcc_mbox_irq

Wang Qing (2):
      mailbox: zynq: add missing of_node_put before return
      mailbox: mtk: add missing of_node_put before return

jason-jh.lin (2):
      mailbox: fix gce_num of mt8192 driver data
      mailbox: add control_by_sw for mt8195

 .../devicetree/bindings/mailbox/apple,mailbox.yaml | 12 ++-
 drivers/mailbox/apple-mailbox.c                    |  4 +-
 drivers/mailbox/hi3660-mailbox.c                   | 18 ++--
 drivers/mailbox/imx-mailbox.c                      |  4 +-
 drivers/mailbox/mailbox-mpfs.c                     |  2 +-
 drivers/mailbox/mtk-cmdq-mailbox.c                 | 15 ++--
 drivers/mailbox/pcc.c                              | 10 ++-
 drivers/mailbox/qcom-ipcc.c                        | 99 +++++++++++++++++-----
 drivers/mailbox/zynqmp-ipi-mailbox.c               |  1 +
 include/dt-bindings/mailbox/qcom-ipcc.h            |  2 +
 10 files changed, 116 insertions(+), 51 deletions(-)


From linux at roeck-us.net  Wed Jan 12 18:40:53 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Wed, 12 Jan 2022 18:40:53 -0800
Subject: [PATCH v5 11/13] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20220112230247.982212-12-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-12-iwona.winiarska@intel.com>
Message-ID: <20220113024053.GA413166@roeck-us.net>

On Thu, Jan 13, 2022 at 12:02:45AM +0100, Iwona Winiarska wrote:
> Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
> are accessible via the processor PECI interface.
> 
> The main use case for the driver (and PECI interface) is out-of-band
> management, where we're able to obtain thermal readings from an external
> entity connected with PECI, e.g. BMC on server platforms.
> 
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>

Acked-by: Guenter Roeck <linux at roeck-us.net>

> ---
>  drivers/hwmon/peci/Kconfig    |  13 +
>  drivers/hwmon/peci/Makefile   |   2 +
>  drivers/hwmon/peci/dimmtemp.c | 630 ++++++++++++++++++++++++++++++++++
>  3 files changed, 645 insertions(+)
>  create mode 100644 drivers/hwmon/peci/dimmtemp.c
> 
> diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
> index e10eed68d70a..9d32a57badfe 100644
> --- a/drivers/hwmon/peci/Kconfig
> +++ b/drivers/hwmon/peci/Kconfig
> @@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
>  	  This driver can also be built as a module. If so, the module
>  	  will be called peci-cputemp.
>  
> +config SENSORS_PECI_DIMMTEMP
> +	tristate "PECI DIMM temperature monitoring client"
> +	depends on PECI
> +	select SENSORS_PECI
> +	select PECI_CPU
> +	help
> +	  If you say yes here you get support for the generic Intel PECI hwmon
> +	  driver which provides Temperature Sensor on DIMM readings that are
> +	  accessible via the processor PECI interface.
> +
> +	  This driver can also be built as a module. If so, the module
> +	  will be called peci-dimmtemp.
> +
>  config SENSORS_PECI
>  	tristate
> diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
> index e8a0ada5ab1f..191cfa0227f3 100644
> --- a/drivers/hwmon/peci/Makefile
> +++ b/drivers/hwmon/peci/Makefile
> @@ -1,5 +1,7 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
>  peci-cputemp-y := cputemp.o
> +peci-dimmtemp-y := dimmtemp.o
>  
>  obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
> +obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)	+= peci-dimmtemp.o
> diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
> new file mode 100644
> index 000000000000..c8222354c005
> --- /dev/null
> +++ b/drivers/hwmon/peci/dimmtemp.c
> @@ -0,0 +1,630 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// Copyright (c) 2018-2021 Intel Corporation
> +
> +#include <linux/auxiliary_bus.h>
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>
> +#include <linux/hwmon.h>
> +#include <linux/jiffies.h>
> +#include <linux/module.h>
> +#include <linux/peci.h>
> +#include <linux/peci-cpu.h>
> +#include <linux/units.h>
> +#include <linux/workqueue.h>
> +
> +#include "common.h"
> +
> +#define DIMM_MASK_CHECK_DELAY_JIFFIES	msecs_to_jiffies(5000)
> +
> +/* Max number of channel ranks and DIMM index per channel */
> +#define CHAN_RANK_MAX_ON_HSX	8
> +#define DIMM_IDX_MAX_ON_HSX	3
> +#define CHAN_RANK_MAX_ON_BDX	4
> +#define DIMM_IDX_MAX_ON_BDX	3
> +#define CHAN_RANK_MAX_ON_BDXD	2
> +#define DIMM_IDX_MAX_ON_BDXD	2
> +#define CHAN_RANK_MAX_ON_SKX	6
> +#define DIMM_IDX_MAX_ON_SKX	2
> +#define CHAN_RANK_MAX_ON_ICX	8
> +#define DIMM_IDX_MAX_ON_ICX	2
> +#define CHAN_RANK_MAX_ON_ICXD	4
> +#define DIMM_IDX_MAX_ON_ICXD	2
> +
> +#define CHAN_RANK_MAX		CHAN_RANK_MAX_ON_HSX
> +#define DIMM_IDX_MAX		DIMM_IDX_MAX_ON_HSX
> +#define DIMM_NUMS_MAX		(CHAN_RANK_MAX * DIMM_IDX_MAX)
> +
> +#define CPU_SEG_MASK		GENMASK(23, 16)
> +#define GET_CPU_SEG(x)		(((x) & CPU_SEG_MASK) >> 16)
> +#define CPU_BUS_MASK		GENMASK(7, 0)
> +#define GET_CPU_BUS(x)		((x) & CPU_BUS_MASK)
> +
> +#define DIMM_TEMP_MAX		GENMASK(15, 8)
> +#define DIMM_TEMP_CRIT		GENMASK(23, 16)
> +#define GET_TEMP_MAX(x)		(((x) & DIMM_TEMP_MAX) >> 8)
> +#define GET_TEMP_CRIT(x)	(((x) & DIMM_TEMP_CRIT) >> 16)
> +
> +#define NO_DIMM_RETRY_COUNT_MAX	5
> +
> +struct peci_dimmtemp;
> +
> +struct dimm_info {
> +	int chan_rank_max;
> +	int dimm_idx_max;
> +	u8 min_peci_revision;
> +	int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
> +			       int chan_rank, u32 *data);
> +};
> +
> +struct peci_dimm_thresholds {
> +	long temp_max;
> +	long temp_crit;
> +	struct peci_sensor_state state;
> +};
> +
> +enum peci_dimm_threshold_type {
> +	temp_max_type,
> +	temp_crit_type,
> +};
> +
> +struct peci_dimmtemp {
> +	struct peci_device *peci_dev;
> +	struct device *dev;
> +	const char *name;
> +	const struct dimm_info *gen_info;
> +	struct delayed_work detect_work;
> +	struct {
> +		struct peci_sensor_data temp;
> +		struct peci_dimm_thresholds thresholds;
> +	} dimm[DIMM_NUMS_MAX];
> +	char **dimmtemp_label;
> +	DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
> +	u8 no_dimm_retry_count;
> +};
> +
> +static u8 __dimm_temp(u32 reg, int dimm_order)
> +{
> +	return (reg >> (dimm_order * 8)) & 0xff;
> +}
> +
> +static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long *val)
> +{
> +	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> +	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> +	int ret = 0;
> +	u32 data;
> +
> +	mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
> +	if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
> +		goto skip_update;
> +
> +	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &data);
> +	if (ret)
> +		goto unlock;
> +
> +	priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * MILLIDEGREE_PER_DEGREE;
> +
> +	peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
> +
> +skip_update:
> +	*val = priv->dimm[dimm_no].temp.value;
> +unlock:
> +	mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
> +	return ret;
> +}
> +
> +static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
> +{
> +	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
> +	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
> +	u32 data;
> +	int ret;
> +
> +	if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
> +		return 0;
> +
> +	ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
> +	if (ret == -ENODATA) /* Use default or previous value */
> +		return 0;
> +	if (ret)
> +		return ret;
> +
> +	priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * MILLIDEGREE_PER_DEGREE;
> +	priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * MILLIDEGREE_PER_DEGREE;
> +
> +	peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
> +
> +	return 0;
> +}
> +
> +static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum peci_dimm_threshold_type type,
> +			       int dimm_no, long *val)
> +{
> +	int ret;
> +
> +	mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
> +	ret = update_thresholds(priv, dimm_no);
> +	if (ret)
> +		goto unlock;
> +
> +	switch (type) {
> +	case temp_max_type:
> +		*val = priv->dimm[dimm_no].thresholds.temp_max;
> +		break;
> +	case temp_crit_type:
> +		*val = priv->dimm[dimm_no].thresholds.temp_crit;
> +		break;
> +	default:
> +		ret = -EOPNOTSUPP;
> +		break;
> +	}
> +unlock:
> +	mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
> +
> +	return ret;
> +}
> +
> +static int dimmtemp_read_string(struct device *dev,
> +				enum hwmon_sensor_types type,
> +				u32 attr, int channel, const char **str)
> +{
> +	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> +
> +	if (attr != hwmon_temp_label)
> +		return -EOPNOTSUPP;
> +
> +	*str = (const char *)priv->dimmtemp_label[channel];
> +
> +	return 0;
> +}
> +
> +static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
> +			 u32 attr, int channel, long *val)
> +{
> +	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
> +
> +	switch (attr) {
> +	case hwmon_temp_input:
> +		return get_dimm_temp(priv, channel, val);
> +	case hwmon_temp_max:
> +		return get_dimm_thresholds(priv, temp_max_type, channel, val);
> +	case hwmon_temp_crit:
> +		return get_dimm_thresholds(priv, temp_crit_type, channel, val);
> +	default:
> +		break;
> +	}
> +
> +	return -EOPNOTSUPP;
> +}
> +
> +static umode_t dimmtemp_is_visible(const void *data, enum hwmon_sensor_types type,
> +				   u32 attr, int channel)
> +{
> +	const struct peci_dimmtemp *priv = data;
> +
> +	if (test_bit(channel, priv->dimm_mask))
> +		return 0444;
> +
> +	return 0;
> +}
> +
> +static const struct hwmon_ops peci_dimmtemp_ops = {
> +	.is_visible = dimmtemp_is_visible,
> +	.read_string = dimmtemp_read_string,
> +	.read = dimmtemp_read,
> +};
> +
> +static int check_populated_dimms(struct peci_dimmtemp *priv)
> +{
> +	int chan_rank_max = priv->gen_info->chan_rank_max;
> +	int dimm_idx_max = priv->gen_info->dimm_idx_max;
> +	u32 chan_rank_empty = 0;
> +	u64 dimm_mask = 0;
> +	int chan_rank, dimm_idx, ret;
> +	u32 pcs;
> +
> +	BUILD_BUG_ON(BITS_PER_TYPE(chan_rank_empty) < CHAN_RANK_MAX);
> +	BUILD_BUG_ON(BITS_PER_TYPE(dimm_mask) < DIMM_NUMS_MAX);
> +	if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
> +		WARN_ONCE(1, "Unsupported number of DIMMs - chan_rank_max: %d, dimm_idx_max: %d",
> +			  chan_rank_max, dimm_idx_max);
> +		return -EINVAL;
> +	}
> +
> +	for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
> +		ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &pcs);
> +		if (ret) {
> +			/*
> +			 * Overall, we expect either success or -EINVAL in
> +			 * order to determine whether DIMM is populated or not.
> +			 * For anything else we fall back to deferring the
> +			 * detection to be performed at a later point in time.
> +			 */
> +			if (ret == -EINVAL) {
> +				chan_rank_empty |= BIT(chan_rank);
> +				continue;
> +			}
> +
> +			return -EAGAIN;
> +		}
> +
> +		for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
> +			if (__dimm_temp(pcs, dimm_idx))
> +				dimm_mask |= BIT(chan_rank * dimm_idx_max + dimm_idx);
> +	}
> +
> +	/*
> +	 * If we got all -EINVALs, it means that the CPU doesn't have any
> +	 * DIMMs. Unfortunately, it may also happen at the very start of
> +	 * host platform boot. Retrying a couple of times lets us make sure
> +	 * that the state is persistent.
> +	 */
> +	if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0)) {
> +		if (priv->no_dimm_retry_count < NO_DIMM_RETRY_COUNT_MAX) {
> +			priv->no_dimm_retry_count++;
> +
> +			return -EAGAIN;
> +		}
> +
> +		return -ENODEV;
> +	}
> +
> +	/*
> +	 * It's possible that memory training is not done yet. In this case we
> +	 * defer the detection to be performed at a later point in time.
> +	 */
> +	if (!dimm_mask) {
> +		priv->no_dimm_retry_count = 0;
> +		return -EAGAIN;
> +	}
> +
> +	dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
> +
> +	bitmap_from_u64(priv->dimm_mask, dimm_mask);
> +
> +	return 0;
> +}
> +
> +static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
> +{
> +	int rank = chan / priv->gen_info->dimm_idx_max;
> +	int idx = chan % priv->gen_info->dimm_idx_max;
> +
> +	priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
> +						    "DIMM %c%d", 'A' + rank,
> +						    idx + 1);
> +	if (!priv->dimmtemp_label[chan])
> +		return -ENOMEM;
> +
> +	return 0;
> +}
> +
> +static const u32 peci_dimmtemp_temp_channel_config[] = {
> +	[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
> +	0
> +};
> +
> +static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
> +	.type = hwmon_temp,
> +	.config = peci_dimmtemp_temp_channel_config,
> +};
> +
> +static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
> +	&peci_dimmtemp_temp_channel,
> +	NULL
> +};
> +
> +static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
> +	.ops = &peci_dimmtemp_ops,
> +	.info = peci_dimmtemp_temp_info,
> +};
> +
> +static int create_dimm_temp_info(struct peci_dimmtemp *priv)
> +{
> +	int ret, i, channels;
> +	struct device *dev;
> +
> +	/*
> +	 * We expect to either find populated DIMMs and carry on with creating
> +	 * sensors, or find out that there are no DIMMs populated.
> +	 * All other states mean that the platform never reached the state that
> +	 * allows to check DIMM state - causing us to retry later on.
> +	 */
> +	ret = check_populated_dimms(priv);
> +	if (ret == -ENODEV) {
> +		dev_dbg(priv->dev, "No DIMMs found\n");
> +		return 0;
> +	} else if (ret) {
> +		schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
> +		dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
> +		return ret;
> +	}
> +
> +	channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
> +
> +	priv->dimmtemp_label = devm_kzalloc(priv->dev, channels * sizeof(char *), GFP_KERNEL);
> +	if (!priv->dimmtemp_label)
> +		return -ENOMEM;
> +
> +	for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
> +		ret = create_dimm_temp_label(priv, i);
> +		if (ret)
> +			return ret;
> +		mutex_init(&priv->dimm[i].thresholds.state.lock);
> +		mutex_init(&priv->dimm[i].temp.state.lock);
> +	}
> +
> +	dev = devm_hwmon_device_register_with_info(priv->dev, priv->name, priv,
> +						   &peci_dimmtemp_chip_info, NULL);
> +	if (IS_ERR(dev)) {
> +		dev_err(priv->dev, "Failed to register hwmon device\n");
> +		return PTR_ERR(dev);
> +	}
> +
> +	dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
> +
> +	return 0;
> +}
> +
> +static void create_dimm_temp_info_delayed(struct work_struct *work)
> +{
> +	struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
> +						  struct peci_dimmtemp,
> +						  detect_work);
> +	int ret;
> +
> +	ret = create_dimm_temp_info(priv);
> +	if (ret && ret != -EAGAIN)
> +		dev_err(priv->dev, "Failed to populate DIMM temp info\n");
> +}
> +
> +static void remove_delayed_work(void *_priv)
> +{
> +	struct peci_dimmtemp *priv = _priv;
> +
> +	cancel_delayed_work_sync(&priv->detect_work);
> +}
> +
> +static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
> +{
> +	struct device *dev = &adev->dev;
> +	struct peci_device *peci_dev = to_peci_device(dev->parent);
> +	struct peci_dimmtemp *priv;
> +	int ret;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
> +				    peci_dev->info.socket_id);
> +	if (!priv->name)
> +		return -ENOMEM;
> +
> +	priv->dev = dev;
> +	priv->peci_dev = peci_dev;
> +	priv->gen_info = (const struct dimm_info *)id->driver_data;
> +
> +	/*
> +	 * This is just a sanity check. Since we're using commands that are
> +	 * guaranteed to be supported on a given platform, we should never see
> +	 * revision lower than expected.
> +	 */
> +	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
> +		dev_warn(priv->dev,
> +			 "Unexpected PECI revision %#x, some features may be unavailable\n",
> +			 peci_dev->info.peci_revision);
> +
> +	INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
> +
> +	ret = devm_add_action_or_reset(priv->dev, remove_delayed_work, priv);
> +	if (ret)
> +		return ret;
> +
> +	ret = create_dimm_temp_info(priv);
> +	if (ret && ret != -EAGAIN) {
> +		dev_err(dev, "Failed to populate DIMM temp info\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 20, Function 0: IMC 0 channel 0 -> rank 0
> +	 * Device 20, Function 1: IMC 0 channel 1 -> rank 1
> +	 * Device 21, Function 0: IMC 0 channel 2 -> rank 2
> +	 * Device 21, Function 1: IMC 0 channel 3 -> rank 3
> +	 * Device 23, Function 0: IMC 1 channel 0 -> rank 4
> +	 * Device 23, Function 1: IMC 1 channel 1 -> rank 5
> +	 * Device 24, Function 0: IMC 1 channel 2 -> rank 6
> +	 * Device 24, Function 1: IMC 1 channel 3 -> rank 7
> +	 */
> +	dev = 20 + chan_rank / 2 + chan_rank / 4;
> +	func = chan_rank % 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> +	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> +	 * Device 12, Function 2: IMC 1 channel 0 -> rank 2
> +	 * Device 12, Function 6: IMC 1 channel 1 -> rank 3
> +	 */
> +	dev = 10 + chan_rank / 2 * 2;
> +	func = (chan_rank % 2) ? 6 : 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u8 dev, func;
> +	u16 reg;
> +	int ret;
> +
> +	/*
> +	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
> +	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
> +	 * Device 11, Function 2: IMC 0 channel 2 -> rank 2
> +	 * Device 12, Function 2: IMC 1 channel 0 -> rank 3
> +	 * Device 12, Function 6: IMC 1 channel 1 -> rank 4
> +	 * Device 13, Function 2: IMC 1 channel 2 -> rank 5
> +	 */
> +	dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
> +	func = chan_rank % 3 == 1 ? 6 : 2;
> +	reg = 0x120 + dimm_order * 4;
> +
> +	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static int
> +read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
> +{
> +	u32 reg_val;
> +	u64 offset;
> +	int ret;
> +	u8 dev;
> +
> +	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, &reg_val);
> +	if (ret || !(reg_val & BIT(31)))
> +		return -ENODATA; /* Use default or previous value */
> +
> +	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, &reg_val);
> +	if (ret)
> +		return -ENODATA; /* Use default or previous value */
> +
> +	/*
> +	 * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
> +	 * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
> +	 * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
> +	 * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
> +	 * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
> +	 * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
> +	 * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
> +	 * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
> +	 */
> +	dev = 26 + chan_rank / 2;
> +	offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
> +
> +	ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val), GET_CPU_BUS(reg_val),
> +			     dev, 0, offset, data);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static const struct dimm_info dimm_hsx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_HSX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_HSX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_hsx,
> +};
> +
> +static const struct dimm_info dimm_bdx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_BDX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_hsx,
> +};
> +
> +static const struct dimm_info dimm_bdxd = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_BDXD,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDXD,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_bdxd,
> +};
> +
> +static const struct dimm_info dimm_skx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_SKX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_SKX,
> +	.min_peci_revision = 0x33,
> +	.read_thresholds = &read_thresholds_skx,
> +};
> +
> +static const struct dimm_info dimm_icx = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_ICX,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICX,
> +	.min_peci_revision = 0x40,
> +	.read_thresholds = &read_thresholds_icx,
> +};
> +
> +static const struct dimm_info dimm_icxd = {
> +	.chan_rank_max	= CHAN_RANK_MAX_ON_ICXD,
> +	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICXD,
> +	.min_peci_revision = 0x40,
> +	.read_thresholds = &read_thresholds_icx,
> +};
> +
> +static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
> +	{
> +		.name = "peci_cpu.dimmtemp.hsx",
> +		.driver_data = (kernel_ulong_t)&dimm_hsx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.bdx",
> +		.driver_data = (kernel_ulong_t)&dimm_bdx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.bdxd",
> +		.driver_data = (kernel_ulong_t)&dimm_bdxd,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.skx",
> +		.driver_data = (kernel_ulong_t)&dimm_skx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.icx",
> +		.driver_data = (kernel_ulong_t)&dimm_icx,
> +	},
> +	{
> +		.name = "peci_cpu.dimmtemp.icxd",
> +		.driver_data = (kernel_ulong_t)&dimm_icxd,
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
> +
> +static struct auxiliary_driver peci_dimmtemp_driver = {
> +	.probe		= peci_dimmtemp_probe,
> +	.id_table	= peci_dimmtemp_ids,
> +};
> +
> +module_auxiliary_driver(peci_dimmtemp_driver);
> +
> +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
> +MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
> +MODULE_DESCRIPTION("PECI dimmtemp driver");
> +MODULE_LICENSE("GPL");
> +MODULE_IMPORT_NS(PECI_CPU);
> -- 
> 2.31.1
> 


From anshuman.khandual at arm.com  Wed Jan 12 19:03:04 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 13 Jan 2022 08:33:04 +0530
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
 <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
Message-ID: <00e28671-8d3a-f789-91c4-109814792a07@arm.com>



On 1/12/22 4:20 PM, Arnd Bergmann wrote:
> On Wed, Jan 12, 2022 at 10:34 AM Anshuman Khandual
> <anshuman.khandual at arm.com> wrote:
>>
>> Add the CPU Partnumbers for the new Arm designs.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/include/asm/cputype.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
>> index 19b8441aa8f2..657eeb06c784 100644
>> --- a/arch/arm64/include/asm/cputype.h
>> +++ b/arch/arm64/include/asm/cputype.h
>> @@ -74,6 +74,7 @@
>>  #define ARM_CPU_PART_NEOVERSE_N1       0xD0C
>>  #define ARM_CPU_PART_CORTEX_A77                0xD0D
>>  #define ARM_CPU_PART_CORTEX_A710       0xD47
>> +#define ARM_CPU_PART_CORTEX_X2         0xD48
>>  #define ARM_CPU_PART_NEOVERSE_N2       0xD49
> 
> No objections to the patch, but would it be possible to just add all the missing
> ones here to the degree that they are known already? I don't see any entries for
> Cortex-A34, Cortex-A65AE, Cortex-A78, Cortex-A78C, Cortex-A78AE,
> Neoverse-E1, Neoverse-V1, Cortex-X1, Cortex-X2, Cortex-A510, Cortex-A710
> and Cortex-R82 among the Arm-designed cores that can run Linux, and there
> are probably others that I missed going through the list.

Hi Arnd,

IIUC the part numbers are enumerated here only if there is an errata
applicable for them which needs to be detected at boot. I am not sure
whether all cpu versions that can run Linux, needs to be defined here.
But then I might be missing something.

- Anshuman

> 
>         Arnd
> 


From qianggui.song at amlogic.com  Wed Jan 12 19:10:40 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:40 +0800
Subject: [PATCH v4 0/3] pinctrl: meson-s4: add pinctrl driver
Message-ID: <20220113031044.2665-1-qianggui.song@amlogic.com>

This patchset adds Pin controller driver support for Meson-S4 SoC
which shares the same register layout with previous Meson-A1

Changes since v3 at [2]:
- collect Martin's Acked-by and Reviewed-by
- remove useless empty line

Changes since v2 at [1]:
- add dt-bindings header file patch back with Rob's Acked-by

Changes since v1 at [0]:
- fix typos in commit message
- fix coding style problem in pinctrl-meson-s4.c
- change tdm groups makeup and split mclk groups

[0] https://lore.kernel.org/linux-amlogic/20211214022100.14841-1-qianggui.song at amlogic.com/
[1] https://lore.kernel.org/linux-amlogic/20211227080649.32275-1-qianggui.song at amlogic.com/
[2] https://lore.kernel.org/linux-amlogic/20211229121605.10513-1-qianggui.song at amlogic.com

Qianggui Song (3):
  dt-bindings: pinctrl: meson: Add compatible for S4
  dt-bindings: gpio: Add a header file for Amlogic Meson S4
  pinctrl: meson: add pinctrl driver support for Meson-S4 Soc

 .../bindings/pinctrl/meson,pinctrl.txt        |    1 +
 drivers/pinctrl/meson/Kconfig                 |    6 +
 drivers/pinctrl/meson/Makefile                |    1 +
 drivers/pinctrl/meson/pinctrl-meson-s4.c      | 1232 +++++++++++++++++
 include/dt-bindings/gpio/meson-s4-gpio.h      |   99 ++
 5 files changed, 1339 insertions(+)
 create mode 100644 drivers/pinctrl/meson/pinctrl-meson-s4.c
 create mode 100644 include/dt-bindings/gpio/meson-s4-gpio.h

-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:41 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:41 +0800
Subject: [PATCH v4 1/3] dt-bindings: pinctrl: meson: Add compatible for S4
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-2-qianggui.song@amlogic.com>

Add new compatible for Amlogic's Meson-S4 pin controller

Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
index 0aff1f28495c..8146193bd8ac 100644
--- a/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/meson,pinctrl.txt
@@ -16,6 +16,7 @@ Required properties for the root node:
 		      "amlogic,meson-g12a-periphs-pinctrl"
 		      "amlogic,meson-g12a-aobus-pinctrl"
 		      "amlogic,meson-a1-periphs-pinctrl"
+		      "amlogic,meson-s4-periphs-pinctrl"
  - reg: address and size of registers controlling irq functionality
 
 === GPIO sub-nodes ===
-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:42 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:42 +0800
Subject: [PATCH v4 2/3] dt-bindings: gpio: Add a header file for Amlogic Meson
 S4
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-3-qianggui.song@amlogic.com>

Add a new dt-binding header file which documents the detail pin names.

Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 include/dt-bindings/gpio/meson-s4-gpio.h | 99 ++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 include/dt-bindings/gpio/meson-s4-gpio.h

diff --git a/include/dt-bindings/gpio/meson-s4-gpio.h b/include/dt-bindings/gpio/meson-s4-gpio.h
new file mode 100644
index 000000000000..35aee21b94f1
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-s4-gpio.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song at amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_S4_GPIO_H
+#define _DT_BINDINGS_MESON_S4_GPIO_H
+
+#define	GPIOB_0		0
+#define	GPIOB_1		1
+#define	GPIOB_2		2
+#define	GPIOB_3		3
+#define	GPIOB_4		4
+#define	GPIOB_5		5
+#define	GPIOB_6		6
+#define	GPIOB_7		7
+#define	GPIOB_8		8
+#define	GPIOB_9		9
+#define	GPIOB_10	10
+#define	GPIOB_11	11
+#define	GPIOB_12	12
+#define	GPIOB_13	13
+
+#define	GPIOC_0		14
+#define	GPIOC_1		15
+#define	GPIOC_2		16
+#define	GPIOC_3		17
+#define	GPIOC_4		18
+#define	GPIOC_5		19
+#define	GPIOC_6		20
+#define	GPIOC_7		21
+
+#define	GPIOE_0		22
+#define	GPIOE_1		23
+
+#define	GPIOD_0		24
+#define	GPIOD_1		25
+#define	GPIOD_2		26
+#define	GPIOD_3		27
+#define	GPIOD_4		28
+#define	GPIOD_5		29
+#define	GPIOD_6		30
+#define	GPIOD_7		31
+#define	GPIOD_8		32
+#define	GPIOD_9		33
+#define	GPIOD_10	34
+#define	GPIOD_11	35
+
+#define	GPIOH_0		36
+#define	GPIOH_1		37
+#define	GPIOH_2		38
+#define	GPIOH_3		39
+#define	GPIOH_4		40
+#define	GPIOH_5		41
+#define	GPIOH_6		42
+#define	GPIOH_7		43
+#define	GPIOH_8		44
+#define	GPIOH_9		45
+#define	GPIOH_10	46
+#define	GPIOH_11	47
+
+#define	GPIOX_0		48
+#define	GPIOX_1		49
+#define	GPIOX_2		50
+#define	GPIOX_3		51
+#define	GPIOX_4		52
+#define	GPIOX_5		53
+#define	GPIOX_6		54
+#define	GPIOX_7		55
+#define	GPIOX_8		56
+#define	GPIOX_9		57
+#define	GPIOX_10	58
+#define	GPIOX_11	59
+#define	GPIOX_12	60
+#define	GPIOX_13	61
+#define	GPIOX_14	62
+#define	GPIOX_15	63
+#define	GPIOX_16	64
+#define	GPIOX_17	65
+#define	GPIOX_18	66
+#define	GPIOX_19	67
+
+#define	GPIOZ_0		68
+#define	GPIOZ_1		69
+#define	GPIOZ_2		70
+#define	GPIOZ_3		71
+#define	GPIOZ_4		72
+#define	GPIOZ_5		73
+#define	GPIOZ_6		74
+#define	GPIOZ_7		75
+#define	GPIOZ_8		76
+#define	GPIOZ_9		77
+#define	GPIOZ_10	78
+#define	GPIOZ_11	79
+#define	GPIOZ_12	80
+
+#define	GPIO_TEST_N	81
+#endif /* _DT_BINDINGS_MESON_S4_GPIO_H */
-- 
2.34.1



From qianggui.song at amlogic.com  Wed Jan 12 19:10:43 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Thu, 13 Jan 2022 11:10:43 +0800
Subject: [PATCH v4 3/3] pinctrl: meson: add pinctrl driver support for
 Meson-S4 Soc
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <20220113031044.2665-4-qianggui.song@amlogic.com>

Add new pinctrl driver for Amlogic's Meson-S4 SoC which share the
same register layout as the previous Meson-A1.

Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/pinctrl/meson/Kconfig            |    6 +
 drivers/pinctrl/meson/Makefile           |    1 +
 drivers/pinctrl/meson/pinctrl-meson-s4.c | 1232 ++++++++++++++++++++++
 3 files changed, 1239 insertions(+)
 create mode 100644 drivers/pinctrl/meson/pinctrl-meson-s4.c

diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index b2855e341a75..d1955c65b4b6 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -61,4 +61,10 @@ config PINCTRL_MESON_A1
 	select PINCTRL_MESON_AXG_PMX
 	default y
 
+config PINCTRL_MESON_S4
+	tristate "Meson s4 Soc pinctrl driver"
+	depends on ARM64
+	select PINCTRL_MESON_AXG_PMX
+	default y
+
 endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index 1a5bffe953f9..694f0596bfbc 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
 obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
 obj-$(CONFIG_PINCTRL_MESON_G12A) += pinctrl-meson-g12a.o
 obj-$(CONFIG_PINCTRL_MESON_A1) += pinctrl-meson-a1.o
+obj-$(CONFIG_PINCTRL_MESON_S4) += pinctrl-meson-s4.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-s4.c b/drivers/pinctrl/meson/pinctrl-meson-s4.c
new file mode 100644
index 000000000000..3c7358f53302
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-s4.c
@@ -0,0 +1,1232 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Pin controller and GPIO driver for Amlogic Meson S4 SoC.
+ *
+ * Copyright (c) 2021 Amlogic, Inc. All rights reserved.
+ * Author: Qianggui Song <qianggui.song at amlogic.com>
+ */
+
+#include <dt-bindings/gpio/meson-s4-gpio.h>
+#include "pinctrl-meson.h"
+#include "pinctrl-meson-axg-pmx.h"
+
+static const struct pinctrl_pin_desc meson_s4_periphs_pins[] = {
+	MESON_PIN(GPIOE_0),
+	MESON_PIN(GPIOE_1),
+
+	MESON_PIN(GPIOB_0),
+	MESON_PIN(GPIOB_1),
+	MESON_PIN(GPIOB_2),
+	MESON_PIN(GPIOB_3),
+	MESON_PIN(GPIOB_4),
+	MESON_PIN(GPIOB_5),
+	MESON_PIN(GPIOB_6),
+	MESON_PIN(GPIOB_7),
+	MESON_PIN(GPIOB_8),
+	MESON_PIN(GPIOB_9),
+	MESON_PIN(GPIOB_10),
+	MESON_PIN(GPIOB_11),
+	MESON_PIN(GPIOB_12),
+	MESON_PIN(GPIOB_13),
+
+	MESON_PIN(GPIOC_0),
+	MESON_PIN(GPIOC_1),
+	MESON_PIN(GPIOC_2),
+	MESON_PIN(GPIOC_3),
+	MESON_PIN(GPIOC_4),
+	MESON_PIN(GPIOC_5),
+	MESON_PIN(GPIOC_6),
+	MESON_PIN(GPIOC_7),
+
+	MESON_PIN(GPIOD_0),
+	MESON_PIN(GPIOD_1),
+	MESON_PIN(GPIOD_2),
+	MESON_PIN(GPIOD_3),
+	MESON_PIN(GPIOD_4),
+	MESON_PIN(GPIOD_5),
+	MESON_PIN(GPIOD_6),
+	MESON_PIN(GPIOD_7),
+	MESON_PIN(GPIOD_8),
+	MESON_PIN(GPIOD_9),
+	MESON_PIN(GPIOD_10),
+	MESON_PIN(GPIOD_11),
+
+	MESON_PIN(GPIOH_0),
+	MESON_PIN(GPIOH_1),
+	MESON_PIN(GPIOH_2),
+	MESON_PIN(GPIOH_3),
+	MESON_PIN(GPIOH_4),
+	MESON_PIN(GPIOH_5),
+	MESON_PIN(GPIOH_6),
+	MESON_PIN(GPIOH_7),
+	MESON_PIN(GPIOH_8),
+	MESON_PIN(GPIOH_9),
+	MESON_PIN(GPIOH_10),
+	MESON_PIN(GPIOH_11),
+
+	MESON_PIN(GPIOX_0),
+	MESON_PIN(GPIOX_1),
+	MESON_PIN(GPIOX_2),
+	MESON_PIN(GPIOX_3),
+	MESON_PIN(GPIOX_4),
+	MESON_PIN(GPIOX_5),
+	MESON_PIN(GPIOX_6),
+	MESON_PIN(GPIOX_7),
+	MESON_PIN(GPIOX_8),
+	MESON_PIN(GPIOX_9),
+	MESON_PIN(GPIOX_10),
+	MESON_PIN(GPIOX_11),
+	MESON_PIN(GPIOX_12),
+	MESON_PIN(GPIOX_13),
+	MESON_PIN(GPIOX_14),
+	MESON_PIN(GPIOX_15),
+	MESON_PIN(GPIOX_16),
+	MESON_PIN(GPIOX_17),
+	MESON_PIN(GPIOX_18),
+	MESON_PIN(GPIOX_19),
+
+	MESON_PIN(GPIOZ_0),
+	MESON_PIN(GPIOZ_1),
+	MESON_PIN(GPIOZ_2),
+	MESON_PIN(GPIOZ_3),
+	MESON_PIN(GPIOZ_4),
+	MESON_PIN(GPIOZ_5),
+	MESON_PIN(GPIOZ_6),
+	MESON_PIN(GPIOZ_7),
+	MESON_PIN(GPIOZ_8),
+	MESON_PIN(GPIOZ_9),
+	MESON_PIN(GPIOZ_10),
+	MESON_PIN(GPIOZ_11),
+	MESON_PIN(GPIOZ_12),
+
+	MESON_PIN(GPIO_TEST_N),
+};
+
+/* BANK E func1 */
+static const unsigned int i2c0_sda_pins[]		= { GPIOE_0 };
+static const unsigned int i2c0_scl_pins[]		= { GPIOE_1 };
+
+/* BANK E func2 */
+static const unsigned int uart_b_tx_e_pins[]		= { GPIOE_0 };
+static const unsigned int uart_b_rx_e_pins[]		= { GPIOE_1 };
+
+/* BANK E func3 */
+static const unsigned int pwm_h_pins[]			= { GPIOE_0 };
+static const unsigned int pwm_j_pins[]			= { GPIOE_1 };
+
+/* BANK B func1 */
+static const unsigned int emmc_nand_d0_pins[]		= { GPIOB_0 };
+static const unsigned int emmc_nand_d1_pins[]		= { GPIOB_1 };
+static const unsigned int emmc_nand_d2_pins[]		= { GPIOB_2 };
+static const unsigned int emmc_nand_d3_pins[]		= { GPIOB_3 };
+static const unsigned int emmc_nand_d4_pins[]		= { GPIOB_4 };
+static const unsigned int emmc_nand_d5_pins[]		= { GPIOB_5 };
+static const unsigned int emmc_nand_d6_pins[]		= { GPIOB_6 };
+static const unsigned int emmc_nand_d7_pins[]		= { GPIOB_7 };
+static const unsigned int emmc_clk_pins[]		= { GPIOB_8 };
+static const unsigned int emmc_rst_pins[]		= { GPIOB_9 };
+static const unsigned int emmc_cmd_pins[]		= { GPIOB_10 };
+static const unsigned int emmc_nand_ds_pins[]		= { GPIOB_11 };
+
+/* Bank B func2 */
+static const unsigned int nand_wen_clk_pins[]		= { GPIOB_8 };
+static const unsigned int nand_ale_pins[]		= { GPIOB_9 };
+static const unsigned int nand_ren_wr_pins[]		= { GPIOB_10 };
+static const unsigned int nand_cle_pins[]		= { GPIOB_11 };
+static const unsigned int nand_ce0_pins[]		= { GPIOB_12 };
+
+/* Bank B func3 */
+static const unsigned int spif_hold_pins[]		= { GPIOB_3 };
+static const unsigned int spif_mo_pins[]		= { GPIOB_4 };
+static const unsigned int spif_mi_pins[]		= { GPIOB_5 };
+static const unsigned int spif_clk_pins[]		= { GPIOB_6 };
+static const unsigned int spif_wp_pins[]		= { GPIOB_7 };
+static const unsigned int spif_cs_pins[]		= { GPIOB_13 };
+
+/* Bank C func1 */
+static const unsigned int sdcard_d0_c_pins[]		= { GPIOC_0 };
+static const unsigned int sdcard_d1_c_pins[]		= { GPIOC_1 };
+static const unsigned int sdcard_d2_c_pins[]		= { GPIOC_2 };
+static const unsigned int sdcard_d3_c_pins[]		= { GPIOC_3 };
+static const unsigned int sdcard_clk_c_pins[]		= { GPIOC_4 };
+static const unsigned int sdcard_cmd_c_pins[]		= { GPIOC_5 };
+static const unsigned int sdcard_cd_pins[]		= { GPIOC_6 };
+
+/* Bank C func2 */
+static const unsigned int jtag_2_tdo_pins[]		= { GPIOC_0 };
+static const unsigned int jtag_2_tdi_pins[]		= { GPIOC_1 };
+static const unsigned int uart_b_rx_c_pins[]		= { GPIOC_2 };
+static const unsigned int uart_b_tx_c_pins[]		= { GPIOC_3 };
+static const unsigned int jtag_2_clk_pins[]		= { GPIOC_4 };
+static const unsigned int jtag_2_tms_pins[]		= { GPIOC_5 };
+static const unsigned int i2c1_sda_c_pins[]		= { GPIOC_6 };
+static const unsigned int i2c1_scl_c_pins[]		= { GPIOC_7 };
+
+/* Bank C func3 */
+static const unsigned int pdm_din1_c_pins[]		= { GPIOC_0 };
+static const unsigned int pdm_din0_c_pins[]		= { GPIOC_1 };
+static const unsigned int i2c4_sda_c_pins[]		= { GPIOC_2 };
+static const unsigned int i2c4_scl_c_pins[]		= { GPIOC_3 };
+static const unsigned int pdm_dclk_c_pins[]		= { GPIOC_4 };
+static const unsigned int iso7816_clk_c_pins[]		= { GPIOC_5 };
+static const unsigned int iso7816_data_c_pins[]		= { GPIOC_6 };
+
+/* Bank C func4 */
+static const unsigned int tdm_d2_c_pins[]		= { GPIOC_0 };
+static const unsigned int tdm_d3_c_pins[]		= { GPIOC_1 };
+static const unsigned int tdm_fs1_c_pins[]		= { GPIOC_2 };
+static const unsigned int tdm_sclk1_c_pins[]		= { GPIOC_3 };
+static const unsigned int mclk_1_c_pins[]		= { GPIOC_4 };
+static const unsigned int tdm_d4_c_pins[]		= { GPIOC_5 };
+static const unsigned int tdm_d5_c_pins[]		= { GPIOC_6 };
+
+/* Bank D func1 */
+static const unsigned int uart_b_tx_d_pins[]		= { GPIOD_0 };
+static const unsigned int uart_b_rx_d_pins[]		= { GPIOD_1 };
+static const unsigned int uart_b_cts_d_pins[]		= { GPIOD_2 };
+static const unsigned int uart_b_rts_d_pins[]		= { GPIOD_3 };
+static const unsigned int remote_out_pins[]		= { GPIOD_4 };
+static const unsigned int remote_in_pins[]		= { GPIOD_5 };
+static const unsigned int jtag_1_clk_pins[]		= { GPIOD_6 };
+static const unsigned int jtag_1_tms_pins[]		= { GPIOD_7 };
+static const unsigned int jtag_1_tdi_pins[]		= { GPIOD_8 };
+static const unsigned int jtag_1_tdo_pins[]		= { GPIOD_9 };
+static const unsigned int clk12_24_pins[]		= { GPIOD_10 };
+static const unsigned int pwm_g_hiz_pins[]		= { GPIOD_11 };
+
+/* Bank D func2 */
+static const unsigned int i2c4_sda_d_pins[]		= { GPIOD_2 };
+static const unsigned int i2c4_scl_d_pins[]		= { GPIOD_3 };
+static const unsigned int mclk_1_d_pins[]		= { GPIOD_4 };
+static const unsigned int tdm_sclk1_d_pins[]		= { GPIOD_6 };
+static const unsigned int tdm_fs1_d_pins[]		= { GPIOD_7 };
+static const unsigned int tdm_d4_d_pins[]		= { GPIOD_8 };
+static const unsigned int tdm_d3_d_pins[]		= { GPIOD_9 };
+static const unsigned int tdm_d2_d_pins[]		= { GPIOD_10 };
+static const unsigned int pwm_g_d_pins[]		= { GPIOD_11 };
+
+/* Bank D func3 */
+static const unsigned int uart_c_tx_pins[]		= { GPIOD_2 };
+static const unsigned int uart_c_rx_pins[]		= { GPIOD_3 };
+static const unsigned int pwm_b_d_pins[]		= { GPIOD_4 };
+static const unsigned int pwm_a_d_pins[]		= { GPIOD_6 };
+static const unsigned int pwm_c_d_pins[]		= { GPIOD_7 };
+static const unsigned int pwm_d_d_pins[]		= { GPIOD_8 };
+static const unsigned int pwm_i_d_pins[]		= { GPIOD_9 };
+
+/* Bank D func4 */
+static const unsigned int clk_32k_in_pins[]		= { GPIOD_2 };
+static const unsigned int pwm_b_hiz_pins[]		= { GPIOD_4 };
+static const unsigned int pwm_a_hiz_pins[]		= { GPIOD_6 };
+static const unsigned int pwm_c_hiz_pins[]		= { GPIOD_7 };
+static const unsigned int pdm_dclk_d_pins[]		= { GPIOD_8 };
+static const unsigned int pdm_din0_d_pins[]		= { GPIOD_9 };
+static const unsigned int pdm_din1_d_pins[]		= { GPIOD_10 };
+
+/* Bank D func5 */
+static const unsigned int mic_mute_en_pins[]		= { GPIOD_2 };
+static const unsigned int mic_mute_key_pins[]		= { GPIOD_3 };
+static const unsigned int i2c1_sda_d_pins[]		= { GPIOD_6 };
+static const unsigned int i2c1_scl_d_pins[]		= { GPIOD_7 };
+static const unsigned int i2c2_sda_d_pins[]		= { GPIOD_10 };
+static const unsigned int i2c2_scl_d_pins[]		= { GPIOD_11 };
+
+/* Bank D func6 */
+static const unsigned int gen_clk_d_pins[]		= { GPIOD_10 };
+static const unsigned int tsin_b_clk_c_pins[]		= { GPIOD_6 };
+static const unsigned int tsin_b_sop_c_pins[]		= { GPIOD_7 };
+static const unsigned int tsin_b_valid_c_pins[]		= { GPIOD_8 };
+static const unsigned int tsin_b_d0_c_pins[]		= { GPIOD_9 };
+
+/* Bank H func1 */
+static const unsigned int hdmitx_sda_pins[]		= { GPIOH_0 };
+static const unsigned int hdmitx_sck_pins[]		= { GPIOH_1 };
+static const unsigned int hdmitx_hpd_in_pins[]		= { GPIOH_2 };
+static const unsigned int ao_cec_a_pins[]		= { GPIOH_3 };
+static const unsigned int spdif_out_h_pins[]		= { GPIOH_4 };
+static const unsigned int spdif_in_pins[]		= { GPIOH_5 };
+static const unsigned int i2c1_sda_h_pins[]		= { GPIOH_6 };
+static const unsigned int i2c1_scl_h_pins[]		= { GPIOH_7 };
+static const unsigned int i2c2_sda_h8_pins[]		= { GPIOH_8 };
+static const unsigned int i2c2_scl_h9_pins[]		= { GPIOH_9 };
+static const unsigned int eth_link_led_pins[]		= { GPIOH_10 };
+static const unsigned int eth_act_led_pins[]		= { GPIOH_11 };
+
+/* Bank H func2 */
+static const unsigned int i2c2_sda_h0_pins[]		= { GPIOH_0 };
+static const unsigned int i2c2_scl_h1_pins[]		= { GPIOH_1 };
+static const unsigned int ao_cec_b_pins[]		= { GPIOH_3 };
+static const unsigned int uart_d_tx_h_pins[]		= { GPIOH_4 };
+static const unsigned int uart_d_rx_h_pins[]		= { GPIOH_5 };
+static const unsigned int uart_d_cts_h_pins[]		= { GPIOH_6 };
+static const unsigned int uart_d_rts_h_pins[]		= { GPIOH_7 };
+static const unsigned int iso7816_clk_h_pins[]		= { GPIOH_8 };
+static const unsigned int iso7816_data_h_pins[]		= { GPIOH_9 };
+static const unsigned int uart_e_tx_h_pins[]		= { GPIOH_10 };
+static const unsigned int uart_e_rx_h_pins[]		= { GPIOH_11 };
+
+/* Bank H func3 */
+static const unsigned int pwm_d_h_pins[]		= { GPIOH_6 };
+static const unsigned int pwm_i_h_pins[]		= { GPIOH_7 };
+static const unsigned int pdm_dclk_h_pins[]		= { GPIOH_8 };
+static const unsigned int pdm_din0_h_pins[]		= { GPIOH_9 };
+static const unsigned int pdm_din1_h_pins[]		= { GPIOH_10 };
+
+/* Bank H func4 */
+static const unsigned int mclk_1_h_pins[]		= { GPIOH_4 };
+static const unsigned int tdm_sclk1_h_pins[]		= { GPIOH_5 };
+static const unsigned int tdm_fs1_h_pins[]		= { GPIOH_6 };
+static const unsigned int tdm_d2_h_pins[]		= { GPIOH_7 };
+static const unsigned int tdm_d3_h_pins[]		= { GPIOH_8 };
+static const unsigned int tdm_d4_h_pins[]		= { GPIOH_9 };
+
+/* Bank H func5 */
+static const unsigned int spi_a_miso_h_pins[]		= { GPIOH_4 };
+static const unsigned int spi_a_mosi_h_pins[]		= { GPIOH_5 };
+static const unsigned int spi_a_clk_h_pins[]		= { GPIOH_6 };
+static const unsigned int spi_a_ss0_h_pins[]		= { GPIOH_7 };
+
+/* Bank H func6 */
+static const unsigned int gen_clk_h_pins[]		= { GPIOH_11 };
+static const unsigned int tsin_b1_clk_pins[]		= { GPIOH_4 };
+static const unsigned int tsin_b1_sop_pins[]		= { GPIOH_5 };
+static const unsigned int tsin_b1_valid_pins[]		= { GPIOH_6 };
+static const unsigned int tsin_b1_d0_pins[]		= { GPIOH_7 };
+
+/* Bank X func1 */
+static const unsigned int sdio_d0_pins[]		= { GPIOX_0 };
+static const unsigned int sdio_d1_pins[]		= { GPIOX_1 };
+static const unsigned int sdio_d2_pins[]		= { GPIOX_2 };
+static const unsigned int sdio_d3_pins[]		= { GPIOX_3 };
+static const unsigned int sdio_clk_pins[]		= { GPIOX_4 };
+static const unsigned int sdio_cmd_pins[]		= { GPIOX_5 };
+static const unsigned int pwm_a_x_pins[]		= { GPIOX_6 };
+static const unsigned int pwm_f_x_pins[]		= { GPIOX_7 };
+static const unsigned int tdm_d1_pins[]			= { GPIOX_8 };
+static const unsigned int tdm_d0_pins[]			= { GPIOX_9 };
+static const unsigned int tdm_fs0_pins[]		= { GPIOX_10 };
+static const unsigned int tdm_sclk0_pins[]		= { GPIOX_11 };
+static const unsigned int uart_a_tx_pins[]		= { GPIOX_12 };
+static const unsigned int uart_a_rx_pins[]		= { GPIOX_13 };
+static const unsigned int uart_a_cts_pins[]		= { GPIOX_14 };
+static const unsigned int uart_a_rts_pins[]		= { GPIOX_15 };
+static const unsigned int pwm_e_x_pins[]		= { GPIOX_16 };
+static const unsigned int i2c1_sda_x_pins[]		= { GPIOX_17 };
+static const unsigned int i2c1_scl_x_pins[]		= { GPIOX_18 };
+static const unsigned int pwm_b_x_pins[]		= { GPIOX_19 };
+
+/* Bank X func2 */
+static const unsigned int pdm_din0_x_pins[]		= { GPIOX_8 };
+static const unsigned int pdm_din1_x_pins[]		= { GPIOX_9 };
+static const unsigned int pdm_dclk_x_pins[]		= { GPIOX_11 };
+
+/* Bank X func3 */
+static const unsigned int spi_a_mosi_x_pins[]		= { GPIOX_8 };
+static const unsigned int spi_a_miso_x_pins[]		= { GPIOX_9 };
+static const unsigned int spi_a_ss0_x_pins[]		= { GPIOX_10 };
+static const unsigned int spi_a_clk_x_pins[]		= { GPIOX_11 };
+
+/* Bank X func4 */
+static const unsigned int pwm_c_x_pins[]		= { GPIOX_8 };
+static const unsigned int i2c_slave_scl_pins[]		= { GPIOX_10 };
+static const unsigned int i2c_slave_sda_pins[]		= { GPIOX_11 };
+
+/* Bank X func5 */
+static const unsigned int i2c3_sda_x_pins[]		= { GPIOX_10 };
+static const unsigned int i2c3_scl_x_pins[]		= { GPIOX_11 };
+
+/* Bank Z func1 */
+static const unsigned int tdm_fs2_pins[]		= { GPIOZ_0 };
+static const unsigned int tdm_sclk2_pins[]		= { GPIOZ_1 };
+static const unsigned int tdm_d4_z_pins[]		= { GPIOZ_2 };
+static const unsigned int tdm_d5_z_pins[]		= { GPIOZ_3 };
+static const unsigned int tdm_d6_pins[]			= { GPIOZ_4 };
+static const unsigned int tdm_d7_pins[]			= { GPIOZ_5 };
+static const unsigned int mclk_2_pins[]			= { GPIOZ_6 };
+static const unsigned int spdif_out_z_pins[]		= { GPIOZ_9 };
+static const unsigned int dtv_a_if_agc_z10_pins[]	= { GPIOZ_10 };
+static const unsigned int uart_e_tx_z11_pins[]		= { GPIOZ_11 };
+static const unsigned int uart_e_rx_z12_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func2 */
+static const unsigned int tsin_a_clk_pins[]		= { GPIOZ_0 };
+static const unsigned int tsin_a_sop_pins[]		= { GPIOZ_1 };
+static const unsigned int tsin_a_valid_pins[]		= { GPIOZ_2 };
+static const unsigned int tsin_a_din0_pins[]		= { GPIOZ_3 };
+static const unsigned int dtv_a_if_agc_z6_pins[]	= { GPIOZ_6 };
+static const unsigned int dtv_b_if_agc_pins[]		= { GPIOZ_7 };
+static const unsigned int i2c3_sda_z_pins[]		= { GPIOZ_8 };
+static const unsigned int i2c3_scl_z_pins[]		= { GPIOZ_9 };
+static const unsigned int dtv_a_rf_agc_pins[]		= { GPIOZ_10 };
+static const unsigned int dtv_b_rf_agc_pins[]		= { GPIOZ_11 };
+
+/* Bank Z func3 */
+static const unsigned int sdcard_d0_z_pins[]		= { GPIOZ_0 };
+static const unsigned int sdcard_d1_z_pins[]		= { GPIOZ_1 };
+static const unsigned int sdcard_d2_z_pins[]		= { GPIOZ_2 };
+static const unsigned int sdcard_d3_z_pins[]		= { GPIOZ_3 };
+static const unsigned int sdcard_clk_z_pins[]		= { GPIOZ_4 };
+static const unsigned int sdcard_cmd_z_pins[]		= { GPIOZ_5 };
+static const unsigned int uart_e_tx_z8_pins[]		= { GPIOZ_8 };
+static const unsigned int uart_e_rx_z9_pins[]		= { GPIOZ_9 };
+static const unsigned int pdm_din1_z_pins[]		= { GPIOZ_10 };
+static const unsigned int pdm_din0_z_pins[]		= { GPIOZ_11 };
+static const unsigned int pdm_dclk_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func4 */
+static const unsigned int spi_a_miso_z_pins[]		= { GPIOZ_0 };
+static const unsigned int spi_a_mosi_z_pins[]		= { GPIOZ_1 };
+static const unsigned int spi_a_clk_z_pins[]		= { GPIOZ_2 };
+static const unsigned int spi_a_ss0_z_pins[]		= { GPIOZ_3 };
+static const unsigned int spi_a_ss1_z_pins[]		= { GPIOZ_4 };
+static const unsigned int spi_a_ss2_z_pins[]		= { GPIOZ_5 };
+static const unsigned int i2c4_scl_z_pins[]		= { GPIOZ_11 };
+static const unsigned int i2c4_sda_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func5 */
+static const unsigned int uart_d_tx_z_pins[]		= { GPIOZ_0 };
+static const unsigned int uart_d_rx_z_pins[]		= { GPIOZ_1 };
+static const unsigned int uart_d_cts_z_pins[]		= { GPIOZ_2 };
+static const unsigned int uart_d_rts_z_pins[]		= { GPIOZ_3 };
+static const unsigned int pwm_g_z_pins[]		= { GPIOZ_4 };
+static const unsigned int pwm_f_z_pins[]		= { GPIOZ_5 };
+static const unsigned int pwm_e_z_pins[]		= { GPIOZ_6 };
+static const unsigned int tsin_b_clk_z_pins[]		= { GPIOZ_7 };
+static const unsigned int tsin_b_sop_z_pins[]		= { GPIOZ_10 };
+static const unsigned int tsin_b_valid_z_pins[]		= { GPIOZ_11 };
+static const unsigned int tsin_b_d0_z_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func6 */
+static const unsigned int s2_demod_gpio7_pins[]		= { GPIOZ_0 };
+static const unsigned int s2_demod_gpio6_pins[]		= { GPIOZ_1 };
+static const unsigned int s2_demod_gpio5_pins[]		= { GPIOZ_2 };
+static const unsigned int s2_demod_gpio4_pins[]		= { GPIOZ_3 };
+static const unsigned int s2_demod_gpio3_pins[]		= { GPIOZ_4 };
+static const unsigned int s2_demod_gpio2_pins[]		= { GPIOZ_5 };
+static const unsigned int diseqc_out_pins[]		= { GPIOZ_7 };
+static const unsigned int s2_demod_gpio1_pins[]		= { GPIOZ_8 };
+static const unsigned int s2_demod_gpio0_pins[]		= { GPIOZ_12 };
+
+/* Bank Z func7 */
+static const unsigned int gen_clk_z9_pins[]		= { GPIOZ_9 };
+static const unsigned int gen_clk_z12_pins[]		= { GPIOZ_12 };
+
+static struct meson_pmx_group meson_s4_periphs_groups[] = {
+	GPIO_GROUP(GPIOE_0),
+	GPIO_GROUP(GPIOE_1),
+
+	GPIO_GROUP(GPIOB_0),
+	GPIO_GROUP(GPIOB_1),
+	GPIO_GROUP(GPIOB_2),
+	GPIO_GROUP(GPIOB_3),
+	GPIO_GROUP(GPIOB_4),
+	GPIO_GROUP(GPIOB_5),
+	GPIO_GROUP(GPIOB_6),
+	GPIO_GROUP(GPIOB_7),
+	GPIO_GROUP(GPIOB_8),
+	GPIO_GROUP(GPIOB_9),
+	GPIO_GROUP(GPIOB_10),
+	GPIO_GROUP(GPIOB_11),
+	GPIO_GROUP(GPIOB_12),
+	GPIO_GROUP(GPIOB_13),
+
+	GPIO_GROUP(GPIOC_0),
+	GPIO_GROUP(GPIOC_1),
+	GPIO_GROUP(GPIOC_2),
+	GPIO_GROUP(GPIOC_3),
+	GPIO_GROUP(GPIOC_4),
+	GPIO_GROUP(GPIOC_5),
+	GPIO_GROUP(GPIOC_6),
+	GPIO_GROUP(GPIOC_7),
+
+	GPIO_GROUP(GPIOD_0),
+	GPIO_GROUP(GPIOD_1),
+	GPIO_GROUP(GPIOD_2),
+	GPIO_GROUP(GPIOD_3),
+	GPIO_GROUP(GPIOD_4),
+	GPIO_GROUP(GPIOD_5),
+	GPIO_GROUP(GPIOD_6),
+	GPIO_GROUP(GPIOD_7),
+	GPIO_GROUP(GPIOD_8),
+	GPIO_GROUP(GPIOD_9),
+	GPIO_GROUP(GPIOD_10),
+	GPIO_GROUP(GPIOD_11),
+
+	GPIO_GROUP(GPIOH_0),
+	GPIO_GROUP(GPIOH_1),
+	GPIO_GROUP(GPIOH_2),
+	GPIO_GROUP(GPIOH_3),
+	GPIO_GROUP(GPIOH_4),
+	GPIO_GROUP(GPIOH_5),
+	GPIO_GROUP(GPIOH_6),
+	GPIO_GROUP(GPIOH_7),
+	GPIO_GROUP(GPIOH_8),
+	GPIO_GROUP(GPIOH_9),
+	GPIO_GROUP(GPIOH_10),
+	GPIO_GROUP(GPIOH_11),
+
+	GPIO_GROUP(GPIOX_0),
+	GPIO_GROUP(GPIOX_1),
+	GPIO_GROUP(GPIOX_2),
+	GPIO_GROUP(GPIOX_3),
+	GPIO_GROUP(GPIOX_4),
+	GPIO_GROUP(GPIOX_5),
+	GPIO_GROUP(GPIOX_6),
+	GPIO_GROUP(GPIOX_7),
+	GPIO_GROUP(GPIOX_8),
+	GPIO_GROUP(GPIOX_9),
+	GPIO_GROUP(GPIOX_10),
+	GPIO_GROUP(GPIOX_11),
+	GPIO_GROUP(GPIOX_12),
+	GPIO_GROUP(GPIOX_13),
+	GPIO_GROUP(GPIOX_14),
+	GPIO_GROUP(GPIOX_15),
+	GPIO_GROUP(GPIOX_16),
+	GPIO_GROUP(GPIOX_17),
+	GPIO_GROUP(GPIOX_18),
+	GPIO_GROUP(GPIOX_19),
+
+	GPIO_GROUP(GPIOZ_0),
+	GPIO_GROUP(GPIOZ_1),
+	GPIO_GROUP(GPIOZ_2),
+	GPIO_GROUP(GPIOZ_3),
+	GPIO_GROUP(GPIOZ_4),
+	GPIO_GROUP(GPIOZ_5),
+	GPIO_GROUP(GPIOZ_6),
+	GPIO_GROUP(GPIOZ_7),
+	GPIO_GROUP(GPIOZ_8),
+	GPIO_GROUP(GPIOZ_9),
+	GPIO_GROUP(GPIOZ_10),
+	GPIO_GROUP(GPIOZ_11),
+	GPIO_GROUP(GPIOZ_12),
+
+	GPIO_GROUP(GPIO_TEST_N),
+
+	/* BANK E func1 */
+	GROUP(i2c0_sda,			1),
+	GROUP(i2c0_scl,			1),
+
+	/* BANK E func2 */
+	GROUP(uart_b_tx_e,		2),
+	GROUP(uart_b_rx_e,		2),
+
+	/* BANK E func3 */
+	GROUP(pwm_h,			3),
+	GROUP(pwm_j,			3),
+
+	/* BANK B func1 */
+	GROUP(emmc_nand_d0,		1),
+	GROUP(emmc_nand_d1,		1),
+	GROUP(emmc_nand_d2,		1),
+	GROUP(emmc_nand_d3,		1),
+	GROUP(emmc_nand_d4,		1),
+	GROUP(emmc_nand_d5,		1),
+	GROUP(emmc_nand_d6,		1),
+	GROUP(emmc_nand_d7,		1),
+	GROUP(emmc_clk,			1),
+	GROUP(emmc_rst,			1),
+	GROUP(emmc_cmd,			1),
+	GROUP(emmc_nand_ds,		1),
+
+	/* Bank B func2 */
+	GROUP(nand_wen_clk,		2),
+	GROUP(nand_ale,			2),
+	GROUP(nand_ren_wr,		2),
+	GROUP(nand_cle,			2),
+	GROUP(nand_ce0,			2),
+
+	/* Bank B func3 */
+	GROUP(spif_hold,		3),
+	GROUP(spif_mo,			3),
+	GROUP(spif_mi,			3),
+	GROUP(spif_clk,			3),
+	GROUP(spif_wp,			3),
+	GROUP(spif_cs,			3),
+
+	/* Bank C func1 */
+	GROUP(sdcard_d0_c,		1),
+	GROUP(sdcard_d1_c,		1),
+	GROUP(sdcard_d2_c,		1),
+	GROUP(sdcard_d3_c,		1),
+	GROUP(sdcard_clk_c,		1),
+	GROUP(sdcard_cmd_c,		1),
+	GROUP(sdcard_cd,		1),
+
+	/* Bank C func2 */
+	GROUP(jtag_2_tdo,		2),
+	GROUP(jtag_2_tdi,		2),
+	GROUP(uart_b_rx_c,		2),
+	GROUP(uart_b_tx_c,		2),
+	GROUP(jtag_2_clk,		2),
+	GROUP(jtag_2_tms,		2),
+	GROUP(i2c1_sda_c,		2),
+	GROUP(i2c1_scl_c,		2),
+
+	/* Bank C func3 */
+	GROUP(pdm_din1_c,		3),
+	GROUP(pdm_din0_c,		3),
+	GROUP(i2c4_sda_c,		3),
+	GROUP(i2c4_scl_c,		3),
+	GROUP(pdm_dclk_c,		3),
+	GROUP(iso7816_clk_c,		3),
+	GROUP(iso7816_data_c,		3),
+
+	/* Bank C func4 */
+	GROUP(tdm_d2_c,			4),
+	GROUP(tdm_d3_c,			4),
+	GROUP(tdm_fs1_c,		4),
+	GROUP(mclk_1_c,			4),
+	GROUP(tdm_d4_c,			4),
+	GROUP(tdm_d5_c,			4),
+
+	/* Bank D func1 */
+	GROUP(uart_b_tx_d,		1),
+	GROUP(uart_b_rx_d,		1),
+	GROUP(uart_b_cts_d,		1),
+	GROUP(uart_b_rts_d,		1),
+	GROUP(remote_out,		1),
+	GROUP(remote_in,		1),
+	GROUP(jtag_1_clk,		1),
+	GROUP(jtag_1_tms,		1),
+	GROUP(jtag_1_tdi,		1),
+	GROUP(jtag_1_tdo,		1),
+	GROUP(clk12_24,			1),
+	GROUP(pwm_g_hiz,		1),
+
+	/* Bank D func2 */
+	GROUP(i2c4_sda_d,		2),
+	GROUP(i2c4_scl_d,		2),
+	GROUP(mclk_1_d,			2),
+	GROUP(tdm_sclk1_d,		2),
+	GROUP(tdm_fs1_d,		2),
+	GROUP(tdm_d4_d,			2),
+	GROUP(tdm_d3_d,			2),
+	GROUP(tdm_d2_d,			2),
+	GROUP(pwm_g_d,			2),
+
+	/* Bank D func3 */
+	GROUP(uart_c_tx,		3),
+	GROUP(uart_c_rx,		3),
+	GROUP(pwm_b_d,			3),
+	GROUP(pwm_a_d,			3),
+	GROUP(pwm_c_d,			3),
+	GROUP(pwm_d_d,			3),
+	GROUP(pwm_i_d,			3),
+
+	/* Bank D func4 */
+	GROUP(clk_32k_in,		4),
+	GROUP(pwm_b_hiz,		4),
+	GROUP(pwm_a_hiz,		4),
+	GROUP(pwm_c_hiz,		4),
+	GROUP(pdm_dclk_d,		4),
+	GROUP(pdm_din0_d,		4),
+	GROUP(pdm_din1_d,		4),
+
+	/* Bank D func5 */
+	GROUP(mic_mute_en,		5),
+	GROUP(mic_mute_key,		5),
+	GROUP(i2c1_sda_d,		5),
+	GROUP(i2c1_scl_d,		5),
+	GROUP(i2c2_sda_d,		5),
+	GROUP(i2c2_scl_d,		5),
+
+	/* Bank D func6 */
+	GROUP(gen_clk_d,		6),
+	GROUP(tsin_b_clk_c,		6),
+	GROUP(tsin_b_sop_c,		6),
+	GROUP(tsin_b_valid_c,		6),
+	GROUP(tsin_b_d0_c,		6),
+
+	/* Bank H func1 */
+	GROUP(hdmitx_sda,		1),
+	GROUP(hdmitx_sck,		1),
+	GROUP(hdmitx_hpd_in,		1),
+	GROUP(ao_cec_a,			1),
+	GROUP(spdif_out_h,		1),
+	GROUP(spdif_in,			1),
+	GROUP(i2c1_sda_h,		1),
+	GROUP(i2c1_scl_h,		1),
+	GROUP(i2c2_sda_h8,		1),
+	GROUP(i2c2_scl_h9,		1),
+	GROUP(eth_link_led,		1),
+	GROUP(eth_act_led,		1),
+
+	/* Bank H func2 */
+	GROUP(i2c2_sda_h0,		2),
+	GROUP(i2c2_scl_h1,		2),
+	GROUP(ao_cec_b,			2),
+	GROUP(uart_d_tx_h,		2),
+	GROUP(uart_d_rx_h,		2),
+	GROUP(uart_d_cts_h,		2),
+	GROUP(uart_d_rts_h,		2),
+	GROUP(iso7816_clk_h,		2),
+	GROUP(iso7816_data_h,		2),
+	GROUP(uart_e_tx_h,		2),
+	GROUP(uart_e_rx_h,		2),
+
+	/* Bank H func3 */
+	GROUP(pwm_d_h,			3),
+	GROUP(pwm_i_h,			3),
+	GROUP(pdm_dclk_h,		3),
+	GROUP(pdm_din0_h,		3),
+	GROUP(pdm_din1_h,		3),
+
+	/* Bank H func4 */
+	GROUP(mclk_1_h,			4),
+	GROUP(tdm_sclk1_h,		4),
+	GROUP(tdm_fs1_h,		4),
+	GROUP(tdm_d2_h,			4),
+	GROUP(tdm_d3_h,			4),
+	GROUP(tdm_d4_h,			4),
+
+	/* Bank H func5 */
+	GROUP(spi_a_miso_h,		5),
+	GROUP(spi_a_mosi_h,		5),
+	GROUP(spi_a_clk_h,		5),
+	GROUP(spi_a_ss0_h,		5),
+
+	/* Bank H func6 */
+	GROUP(gen_clk_h,		6),
+	GROUP(tsin_b1_clk,		6),
+	GROUP(tsin_b1_sop,		6),
+	GROUP(tsin_b1_valid,		6),
+	GROUP(tsin_b1_d0,		6),
+
+	/* Bank X func1 */
+	GROUP(sdio_d0,			1),
+	GROUP(sdio_d1,			1),
+	GROUP(sdio_d2,			1),
+	GROUP(sdio_d3,			1),
+	GROUP(sdio_clk,			1),
+	GROUP(sdio_cmd,			1),
+	GROUP(pwm_a_x,			1),
+	GROUP(pwm_f_x,			1),
+	GROUP(tdm_d1,			1),
+	GROUP(tdm_d0,			1),
+	GROUP(tdm_fs0,			1),
+	GROUP(tdm_sclk0,		1),
+	GROUP(uart_a_tx,		1),
+	GROUP(uart_a_rx,		1),
+	GROUP(uart_a_cts,		1),
+	GROUP(uart_a_rts,		1),
+	GROUP(pwm_e_x,			1),
+	GROUP(i2c1_sda_x,		1),
+	GROUP(i2c1_scl_x,		1),
+	GROUP(pwm_b_x,			1),
+
+	/* Bank X func2 */
+	GROUP(pdm_din0_x,		2),
+	GROUP(pdm_din1_x,		2),
+	GROUP(pdm_dclk_x,		2),
+
+	/* Bank X func3 */
+	GROUP(spi_a_mosi_x,		3),
+	GROUP(spi_a_miso_x,		3),
+	GROUP(spi_a_ss0_x,		3),
+	GROUP(spi_a_clk_x,		3),
+
+	/* Bank X func4 */
+	GROUP(pwm_c_x,			4),
+	GROUP(i2c_slave_scl,		4),
+	GROUP(i2c_slave_sda,		4),
+
+	/* Bank X func5 */
+	GROUP(i2c3_sda_x,		5),
+	GROUP(i2c3_scl_x,		5),
+
+	/* Bank Z func1 */
+	GROUP(tdm_fs2,			1),
+	GROUP(tdm_sclk2,		1),
+	GROUP(tdm_d4_z,			1),
+	GROUP(tdm_d5_z,			1),
+	GROUP(tdm_d6,			1),
+	GROUP(tdm_d7,			1),
+	GROUP(mclk_2,			1),
+	GROUP(spdif_out_z,		1),
+	GROUP(dtv_a_if_agc_z10,		1),
+	GROUP(uart_e_tx_z11,		1),
+	GROUP(uart_e_rx_z12,		1),
+
+	/* Bank Z func2 */
+	GROUP(tsin_a_clk,		2),
+	GROUP(tsin_a_sop,		2),
+	GROUP(tsin_a_valid,		2),
+	GROUP(tsin_a_din0,		2),
+	GROUP(dtv_a_if_agc_z6,		2),
+	GROUP(dtv_b_if_agc,		2),
+	GROUP(i2c3_sda_z,		2),
+	GROUP(i2c3_scl_z,		2),
+	GROUP(dtv_a_rf_agc,		2),
+	GROUP(dtv_b_rf_agc,		2),
+
+	/* Bank Z func3 */
+	GROUP(sdcard_d0_z,		3),
+	GROUP(sdcard_d1_z,		3),
+	GROUP(sdcard_d2_z,		3),
+	GROUP(sdcard_d3_z,		3),
+	GROUP(sdcard_clk_z,		3),
+	GROUP(sdcard_cmd_z,		3),
+	GROUP(uart_e_tx_z8,		3),
+	GROUP(uart_e_rx_z9,		3),
+	GROUP(pdm_din1_z,		3),
+	GROUP(pdm_din0_z,		3),
+	GROUP(pdm_dclk_z,		3),
+
+	/* Bank Z func4 */
+	GROUP(spi_a_miso_z,		4),
+	GROUP(spi_a_mosi_z,		4),
+	GROUP(spi_a_clk_z,		4),
+	GROUP(spi_a_ss0_z,		4),
+	GROUP(spi_a_ss1_z,		4),
+	GROUP(spi_a_ss2_z,		4),
+	GROUP(i2c4_scl_z,		4),
+	GROUP(i2c4_sda_z,		4),
+
+	/* Bank Z func5 */
+	GROUP(uart_d_tx_z,		5),
+	GROUP(uart_d_rx_z,		5),
+	GROUP(uart_d_cts_z,		5),
+	GROUP(uart_d_rts_z,		5),
+	GROUP(pwm_g_z,			5),
+	GROUP(pwm_f_z,			5),
+	GROUP(pwm_e_z,			5),
+	GROUP(tsin_b_clk_z,		5),
+	GROUP(tsin_b_sop_z,		5),
+	GROUP(tsin_b_valid_z,		5),
+	GROUP(tsin_b_d0_z,		5),
+
+	/* Bank Z func6 */
+	GROUP(s2_demod_gpio7,		6),
+	GROUP(s2_demod_gpio6,		6),
+	GROUP(s2_demod_gpio5,		6),
+	GROUP(s2_demod_gpio4,		6),
+	GROUP(s2_demod_gpio3,		6),
+	GROUP(s2_demod_gpio2,		6),
+	GROUP(diseqc_out,		6),
+	GROUP(s2_demod_gpio1,		6),
+	GROUP(s2_demod_gpio0,		6),
+
+	/* Bank Z func7 */
+	GROUP(gen_clk_z9,		7),
+	GROUP(gen_clk_z12,		7),
+};
+
+static const char * const gpio_periphs_groups[] = {
+	"GPIOE_0", "GPIOE_1",
+
+	"GPIOB_0", "GPIOB_1", "GPIOB_2", "GPIOB_3", "GPIOB_4", "GPIOB_5",
+	"GPIOB_6", "GPIOB_7", "GPIOB_8", "GPIOB_9", "GPIOB_10", "GPIOB_11",
+	"GPIOB_12", "GPIOB_13",
+
+	"GPIOC_0", "GPIOC_1", "GPIOC_2", "GPIOC_3", "GPIOC_4", "GPIOC_5",
+	"GPIOC_6", "GPIOC_7",
+
+	"GPIOD_0", "GPIOD_1", "GPIOD_2", "GPIOD_3", "GPIOD_4", "GPIOD_5",
+	"GPIOD_6", "GPIOD_7", "GPIOD_8", "GPIOD_9", "GPIOD_10", "GPIOD_11",
+
+	"GPIOH_0", "GPIOH_1", "GPIOH_2", "GPIOH_3", "GPIOH_4", "GPIOH_5",
+	"GPIOH_6", "GPIOH_7", "GPIOH_8", "GPIOH_9", "GPIOH_10", "GPIOH_11",
+
+	"GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4", "GPIOX_5",
+	"GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11",
+	"GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", "GPIOX_16", "GPIOX_17",
+	"GPIOX_18", "GPIOX_19",
+
+	"GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4", "GPIOZ_5",
+	"GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9", "GPIOZ_10",
+	"GPIOZ_11", "GPIOZ_12",
+
+	"GPIO_TEST_N",
+};
+
+static const char * const i2c0_groups[] = {
+	"i2c0_sda", "i2c0_scl",
+};
+
+static const char * const i2c1_groups[] = {
+	"i2c1_sda_c", "i2c1_scl_c",
+	"i2c1_sda_d", "i2c1_scl_d",
+	"i2c1_sda_h", "i2c1_scl_h",
+	"i2c1_sda_x", "i2c1_scl_x",
+};
+
+static const char * const i2c2_groups[] = {
+	"i2c2_sda_d", "i2c2_scl_d",
+	"i2c2_sda_h8", "i2c2_scl_h9",
+	"i2c2_sda_h0", "i2c2_scl_h1l,"
+};
+
+static const char * const i2c3_groups[] = {
+	"i2c3_sda_x", "i2c3_scl_x",
+	"i2c3_sda_z", "i2c3_scl_z",
+};
+
+static const char * const i2c4_groups[] = {
+	"i2c4_sda_c", "i2c4_scl_c",
+	"i2c4_sda_d", "i2c4_scl_d",
+	"i2c4_scl_z", "i2c4_sda_z",
+};
+
+static const char * const uart_a_groups[] = {
+	"uart_a_tx", "uart_a_rx", "uart_a_cts", "uart_a_rts",
+};
+
+static const char * const uart_b_groups[] = {
+	"uart_b_tx_e", "uart_b_rx_e", "uart_b_rx_c", "uart_b_tx_c",
+	"uart_b_tx_d", "uart_b_rx_d", "uart_b_cts_d", "uart_b_rts_d",
+};
+
+static const char * const uart_c_groups[] = {
+	"uart_c_tx", "uart_c_rx",
+};
+
+static const char * const uart_d_groups[] = {
+	"uart_d_tx_h", "uart_d_rx_h", "uart_d_cts_h", "uart_d_rts_h",
+	"uart_d_tx_z", "uart_d_rx_z", "uart_d_cts_z", "uart_d_rts_z",
+};
+
+static const char * const uart_e_groups[] = {
+	"uart_e_tx_h", "uart_e_rx_h", "uart_e_tx_z11", "uart_e_rx_z12",
+	"uart_e_tx_z8", "uart_e_rx_z9",
+};
+
+static const char * const emmc_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", "emmc_nand_d3",
+	"emmc_nand_d4", "emmc_nand_d5", "emmc_nand_d6", "emmc_nand_d7",
+	"emmc_clk", "emmc_rst", "emmc_cmd", "emmc_nand_ds",
+};
+
+static const char * const nand_groups[] = {
+	"emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2", "emmc_nand_d3",
+	"emmc_nand_d4", "emmc_nand_d5", "emmc_nand_d6", "emmc_nand_d7",
+	"nand_wen_clk", "nand_ale", "nand_ren_wr", "nand_cle", "nand_ce0",
+};
+
+static const char * const spif_groups[] = {
+	"spif_hold", "spif_mo", "spif_mi", "spif_clk", "spif_wp",
+	"spif_cs",
+};
+
+static const char * const sdcard_groups[] = {
+	"sdcard_d0_c", "sdcard_d1_c", "sdcard_d2_c", "sdcard_d3_c",
+	"sdcard_clk_c", "sdcard_cmd_c", "sdcard_cd",
+	"sdcard_d0_z", "sdcard_d1_z", "sdcard_d2_z", "sdcard_d3_z",
+	"sdcard_clk_z", "sdcard_cmd_z",
+};
+
+static const char * const jtag_1_groups[] = {
+	"jtag_1_clk", "jtag_1_tms", "jtag_1_tdi", "jtag_1_tdo",
+};
+
+static const char * const jtag_2_groups[] = {
+	"jtag_2_tdo", "jtag_2_tdi", "jtag_2_clk", "jtag_2_tms",
+};
+
+static const char * const pdm_groups[] = {
+	"pdm_din1_c", "pdm_din0_c", "pdm_dclk_c",
+	"pdm_dclk_d", "pdm_din0_d", "pdm_din1_d",
+	"pdm_dclk_h", "pdm_din0_h", "pdm_din1_h",
+	"pdm_din0_x", "pdm_din1_x", "pdm_dclk_x",
+	"pdm_din1_z", "pdm_din0_z", "pdm_dclk_z",
+};
+
+static const char * const iso7816_groups[] = {
+	"iso7816_clk_c", "iso7816_data_c",
+	"iso7816_clk_h", "iso7816_data_h",
+};
+
+static const char * const tdm_groups[] = {
+	"tdm_d2_c", "tdm_d3_c", "tdm_fs1_c", "tdm_d4_c", "tdm_d5_c",
+	"tdm_fs1_d", "tdm_d4_d", "tdm_d3_d", "tdm_d2_d", "tdm_sclk1_d",
+	"tdm_sclk1_h", "tdm_fs1_h", "tdm_d2_h", "tdm_d3_h", "tdm_d4_h",
+	"tdm_d1", "tdm_d0", "tdm_fs0", "tdm_sclk0", "tdm_fs2", "tdm_sclk2",
+	"tdm_d4_z", "tdm_d5_z", "tdm_d6", "tdm_d7",
+};
+
+static const char * const mclk_1_groups[] = {
+	"mclk_1_c", "mclk_1_d", "mclk_1_h", "mclk_2",
+};
+
+static const char * const mclk_2_groups[] = {
+	"mclk_2",
+};
+
+static const char * const remote_out_groups[] = {
+	"remote_out",
+};
+
+static const char * const remote_in_groups[] = {
+	"remote_in",
+};
+
+static const char * const clk12_24_groups[] = {
+	"clk12_24",
+};
+
+static const char * const clk_32k_in_groups[] = {
+	"clk_32k_in",
+};
+
+static const char * const pwm_a_hiz_groups[] = {
+	"pwm_a_hiz",
+};
+
+static const char * const pwm_b_hiz_groups[] = {
+	"pwm_b_hiz",
+};
+
+static const char * const pwm_c_hiz_groups[] = {
+	"pwm_c_hiz",
+};
+
+static const char * const pwm_g_hiz_groups[] = {
+	"pwm_g_hiz",
+};
+
+static const char * const pwm_a_groups[] = {
+	"pwm_a_d",
+};
+
+static const char * const pwm_b_groups[] = {
+	"pwm_b_d", "pwm_b_x",
+};
+
+static const char * const pwm_c_groups[] = {
+	"pwm_c_d", "pwm_c_x",
+};
+
+static const char * const pwm_d_groups[] = {
+	"pwm_d_d", "pwm_d_h",
+};
+
+static const char * const pwm_e_groups[] = {
+	"pwm_e_x", "pwm_e_z",
+};
+
+static const char * const pwm_f_groups[] = {
+	"pwm_f_x", "pwm_f_z",
+};
+
+static const char * const pwm_g_groups[] = {
+	"pwm_g_d", "pwm_g_z",
+};
+
+static const char * const pwm_h_groups[] = {
+	"pwm_h",
+};
+
+static const char * const pwm_i_groups[] = {
+	"pwm_i_d", "pwm_i_h"
+};
+
+static const char * const pwm_j_groups[] = {
+	"pwm_j",
+};
+
+static const char * const mic_mute_groups[] = {
+	"mic_mute_en", "mic_mute_key",
+};
+
+static const char * const hdmitx_groups[] = {
+	"hdmitx_sda", "hdmitx_sck", "hdmitx_hpd_in",
+};
+
+static const char * const ao_cec_a_groups[] = {
+	"ao_cec_a",
+};
+
+static const char * const ao_cec_b_groups[] = {
+	"ao_cec_b",
+};
+
+static const char * const spdif_out_groups[] = {
+	"spdif_out_h", "spdif_out_z",
+};
+
+static const char * const spdif_in_groups[] = {
+	"spdif_in",
+};
+
+static const char * const eth_groups[] = {
+	"eth_link_led", "eth_act_led",
+};
+
+static const char * const spi_a_groups[] = {
+	"spi_a_miso_h", "spi_a_mosi_h", "spi_a_clk_h", "spi_a_ss0_h",
+
+	"spi_a_mosi_x", "spi_a_miso_x", "spi_a_ss0_x", "spi_a_clk_x",
+
+	"spi_a_miso_z", "spi_a_mosi_z", "spi_a_clk_z", "spi_a_ss0_z",
+	"spi_a_ss1_z", "spi_a_ss2_z",
+};
+
+static const char * const gen_clk_groups[] = {
+	"gen_clk_h", "gen_clk_z9", "gen_clk_z12",
+};
+
+static const char * const sdio_groups[] = {
+	"sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3", "sdio_clk", "sdio_cmd",
+};
+
+static const char * const i2c_slave_groups[] = {
+	"i2c_slave_scl", "i2c_slave_sda",
+};
+
+static const char * const dtv_groups[] = {
+	"dtv_a_if_agc_z10", "dtv_a_if_agc_z6", "dtv_b_if_agc",
+	"dtv_a_rf_agc", "dtv_b_rf_agc",
+};
+
+static const char * const tsin_a_groups[] = {
+	"tsin_a_clk", "tsin_a_sop", "tsin_a_valid", "tsin_a_din0",
+};
+
+static const char * const tsin_b_groups[] = {
+	"tsin_b_clk_c", "tsin_b_sop_c", "tsin_b_valid_c", "tsin_b_d0_c",
+	"tsin_b_clk_z", "tsin_b_sop_z", "tsin_b_valid_z", "tsin_b_d0_z",
+};
+
+static const char * const tsin_b1_groups[] = {
+	"tsin_b1_clk", "tsin_b1_sop", "tsin_b1_valid", "tsin_b1_d0",
+};
+
+static const char * const diseqc_out_groups[] = {
+	"diseqc_out",
+};
+
+static const char * const s2_demod_groups[] = {
+	"s2_demod_gpio7", "s2_demod_gpio6", "s2_demod_gpio5", "s2_demod_gpio4",
+	"s2_demod_gpio3", "s2_demod_gpio2", "s2_demod_gpio1", "s2_demod_gpio0",
+};
+
+static struct meson_pmx_func meson_s4_periphs_functions[] = {
+	FUNCTION(gpio_periphs),
+	FUNCTION(i2c0),
+	FUNCTION(i2c1),
+	FUNCTION(i2c2),
+	FUNCTION(i2c3),
+	FUNCTION(i2c4),
+	FUNCTION(uart_a),
+	FUNCTION(uart_b),
+	FUNCTION(uart_c),
+	FUNCTION(uart_d),
+	FUNCTION(uart_e),
+	FUNCTION(emmc),
+	FUNCTION(nand),
+	FUNCTION(spif),
+	FUNCTION(sdcard),
+	FUNCTION(jtag_1),
+	FUNCTION(jtag_2),
+	FUNCTION(pdm),
+	FUNCTION(iso7816),
+	FUNCTION(tdm),
+	FUNCTION(mclk_1),
+	FUNCTION(mclk_2),
+	FUNCTION(remote_out),
+	FUNCTION(remote_in),
+	FUNCTION(clk12_24),
+	FUNCTION(clk_32k_in),
+	FUNCTION(pwm_a_hiz),
+	FUNCTION(pwm_b_hiz),
+	FUNCTION(pwm_c_hiz),
+	FUNCTION(pwm_g_hiz),
+	FUNCTION(pwm_a),
+	FUNCTION(pwm_b),
+	FUNCTION(pwm_c),
+	FUNCTION(pwm_d),
+	FUNCTION(pwm_e),
+	FUNCTION(pwm_f),
+	FUNCTION(pwm_g),
+	FUNCTION(pwm_h),
+	FUNCTION(pwm_i),
+	FUNCTION(pwm_j),
+	FUNCTION(mic_mute),
+	FUNCTION(hdmitx),
+	FUNCTION(ao_cec_a),
+	FUNCTION(ao_cec_b),
+	FUNCTION(spdif_out),
+	FUNCTION(spdif_in),
+	FUNCTION(eth),
+	FUNCTION(spi_a),
+	FUNCTION(gen_clk),
+	FUNCTION(sdio),
+	FUNCTION(i2c_slave),
+	FUNCTION(dtv),
+	FUNCTION(tsin_a),
+	FUNCTION(tsin_b),
+	FUNCTION(tsin_b1),
+	FUNCTION(diseqc_out),
+	FUNCTION(s2_demod),
+};
+
+static struct meson_bank meson_s4_periphs_banks[] = {
+	/* name  first  last  irq  pullen  pull  dir  out  in */
+	BANK_DS("B", GPIOB_0,    GPIOB_13,  0, 13,
+		0x63,  0,  0x64,  0,  0x62, 0,  0x61, 0,  0x60, 0, 0x67, 0),
+	BANK_DS("C", GPIOC_0,    GPIOC_7,   14, 21,
+		0x53,  0,  0x54,  0,  0x52, 0,  0x51, 0,  0x50, 0, 0x57, 0),
+	BANK_DS("E", GPIOE_0,    GPIOE_1,   22, 23,
+		0x43,  0,  0x44,  0,  0x42, 0,  0x41, 0,  0x40, 0, 0x47, 0),
+	BANK_DS("D", GPIOD_0,    GPIOD_11,  24, 35,
+		0x33,  0,  0x34,  0,  0x32, 0,  0x31, 0,  0x30, 0, 0x37, 0),
+	BANK_DS("H", GPIOH_0,    GPIOH_11,  36, 47,
+		0x23,  0,  0x24,  0,  0x22, 0,  0x21, 0,  0x20, 0, 0x27, 0),
+	BANK_DS("X", GPIOX_0,    GPIOX_19,   48, 67,
+		0x13,  0,  0x14,  0,  0x12, 0,  0x11, 0,  0x10, 0, 0x17, 0),
+	BANK_DS("Z", GPIOZ_0,    GPIOZ_12,  68, 80,
+		0x03,  0,  0x04,  0,  0x02, 0,  0x01, 0,  0x00, 0, 0x07, 0),
+	BANK_DS("TEST_N", GPIO_TEST_N,    GPIO_TEST_N,   -1, -1,
+		0x83,  0,  0x84,  0,  0x82, 0,  0x81,  0, 0x80, 0, 0x87, 0),
+};
+
+static struct meson_pmx_bank meson_s4_periphs_pmx_banks[] = {
+	/*name	            first	 lask        reg offset*/
+	BANK_PMX("B",      GPIOB_0,     GPIOB_13,    0x00, 0),
+	BANK_PMX("C",      GPIOC_0,     GPIOC_7,     0x9,  0),
+	BANK_PMX("E",      GPIOE_0,     GPIOE_1,     0x12, 0),
+	BANK_PMX("D",      GPIOD_0,     GPIOD_11,    0x10, 0),
+	BANK_PMX("H",      GPIOH_0,     GPIOH_11,    0xb,  0),
+	BANK_PMX("X",      GPIOX_0,     GPIOX_19,    0x3,  0),
+	BANK_PMX("Z",      GPIOZ_0,     GPIOZ_12,    0x6,  0),
+	BANK_PMX("TEST_N", GPIO_TEST_N, GPIO_TEST_N, 0xf,  0)
+};
+
+static struct meson_axg_pmx_data meson_s4_periphs_pmx_banks_data = {
+	.pmx_banks	= meson_s4_periphs_pmx_banks,
+	.num_pmx_banks	= ARRAY_SIZE(meson_s4_periphs_pmx_banks),
+};
+
+static struct meson_pinctrl_data meson_s4_periphs_pinctrl_data = {
+	.name		= "periphs-banks",
+	.pins		= meson_s4_periphs_pins,
+	.groups		= meson_s4_periphs_groups,
+	.funcs		= meson_s4_periphs_functions,
+	.banks		= meson_s4_periphs_banks,
+	.num_pins	= ARRAY_SIZE(meson_s4_periphs_pins),
+	.num_groups	= ARRAY_SIZE(meson_s4_periphs_groups),
+	.num_funcs	= ARRAY_SIZE(meson_s4_periphs_functions),
+	.num_banks	= ARRAY_SIZE(meson_s4_periphs_banks),
+	.pmx_ops	= &meson_axg_pmx_ops,
+	.pmx_data	= &meson_s4_periphs_pmx_banks_data,
+	.parse_dt	= &meson_a1_parse_dt_extra,
+};
+
+static const struct of_device_id meson_s4_pinctrl_dt_match[] = {
+	{
+		.compatible = "amlogic,meson-s4-periphs-pinctrl",
+		.data = &meson_s4_periphs_pinctrl_data,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_s4_pinctrl_dt_match);
+
+static struct platform_driver meson_s4_pinctrl_driver = {
+	.probe  = meson_pinctrl_probe,
+	.driver = {
+		.name	= "meson-s4-pinctrl",
+		.of_match_table = meson_s4_pinctrl_dt_match,
+	},
+};
+module_platform_driver(meson_s4_pinctrl_driver);
+
+MODULE_LICENSE("Dual BSD/GPL");
-- 
2.34.1



From joel at jms.id.au  Wed Jan 12 19:16:25 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 13 Jan 2022 03:16:25 +0000
Subject: [PATCH v5 03/13] ARM: dts: aspeed: Add PECI controller nodes
In-Reply-To: <20220112230247.982212-4-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-4-iwona.winiarska@intel.com>
Message-ID: <CACPK8XfL8-TovFWBxXo7ryijPXeS+sFwejxz-fKNNwxgD1N+oA@mail.gmail.com>

On Wed, 12 Jan 2022 at 23:04, Iwona Winiarska <iwona.winiarska at intel.com> wrote:
>
> Add PECI controller nodes with all required information.
>
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>

Reviewed-by: Joel Stanley <joel at jms.id.au>

> ---
>  arch/arm/boot/dts/aspeed-g4.dtsi | 11 +++++++++++
>  arch/arm/boot/dts/aspeed-g5.dtsi | 11 +++++++++++
>  arch/arm/boot/dts/aspeed-g6.dtsi | 11 +++++++++++
>  3 files changed, 33 insertions(+)
>
> diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
> index b313a1cf5f73..3c2961da6272 100644
> --- a/arch/arm/boot/dts/aspeed-g4.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g4.dtsi
> @@ -391,6 +391,17 @@ uart_routing: uart-routing at 9c {
>                                 };
>                         };
>
> +                       peci0: peci-controller at 1e78b000 {
> +                               compatible = "aspeed,ast2400-peci";
> +                               reg = <0x1e78b000 0x60>;
> +                               interrupts = <15>;
> +                               clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
> +                               resets = <&syscon ASPEED_RESET_PECI>;
> +                               cmd-timeout-ms = <1000>;
> +                               clock-frequency = <1000000>;
> +                               status = "disabled";
> +                       };
> +
>                         uart2: serial at 1e78d000 {
>                                 compatible = "ns16550a";
>                                 reg = <0x1e78d000 0x20>;
> diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
> index c7049454c7cb..aab1c3ecb4dc 100644
> --- a/arch/arm/boot/dts/aspeed-g5.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g5.dtsi
> @@ -511,6 +511,17 @@ ibt: ibt at 140 {
>                                 };
>                         };
>
> +                       peci0: peci-controller at 1e78b000 {
> +                               compatible = "aspeed,ast2500-peci";
> +                               reg = <0x1e78b000 0x60>;
> +                               interrupts = <15>;
> +                               clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
> +                               resets = <&syscon ASPEED_RESET_PECI>;
> +                               cmd-timeout-ms = <1000>;
> +                               clock-frequency = <1000000>;
> +                               status = "disabled";
> +                       };
> +
>                         uart2: serial at 1e78d000 {
>                                 compatible = "ns16550a";
>                                 reg = <0x1e78d000 0x20>;
> diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
> index 5106a424f1ce..564f1292993f 100644
> --- a/arch/arm/boot/dts/aspeed-g6.dtsi
> +++ b/arch/arm/boot/dts/aspeed-g6.dtsi
> @@ -507,6 +507,17 @@ wdt4: watchdog at 1e7850c0 {
>                                 status = "disabled";
>                         };
>
> +                       peci0: peci-controller at 1e78b000 {
> +                               compatible = "aspeed,ast2600-peci";
> +                               reg = <0x1e78b000 0x100>;
> +                               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +                               clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
> +                               resets = <&syscon ASPEED_RESET_PECI>;
> +                               cmd-timeout-ms = <1000>;
> +                               clock-frequency = <1000000>;
> +                               status = "disabled";
> +                       };
> +
>                         lpc: lpc at 1e789000 {
>                                 compatible = "aspeed,ast2600-lpc-v2", "simple-mfd", "syscon";
>                                 reg = <0x1e789000 0x1000>;
> --
> 2.31.1
>


From joel at jms.id.au  Wed Jan 12 19:17:20 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 13 Jan 2022 03:17:20 +0000
Subject: [PATCH v5 02/13] dt-bindings: Add bindings for peci-aspeed
In-Reply-To: <20220112230247.982212-3-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-3-iwona.winiarska@intel.com>
Message-ID: <CACPK8XcO5Z0f2bU6=+o2q7caGnoBdzQ5Dm8AVt-BNs3d_xmOJg@mail.gmail.com>

On Wed, 12 Jan 2022 at 23:04, Iwona Winiarska <iwona.winiarska at intel.com> wrote:
>
> Add device tree bindings for the peci-aspeed controller driver.
>
> Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>

Reviewed-by: Joel Stanley <joel at jms.id.au>

> ---
>  .../devicetree/bindings/peci/peci-aspeed.yaml | 72 +++++++++++++++++++
>  1 file changed, 72 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml
>
> diff --git a/Documentation/devicetree/bindings/peci/peci-aspeed.yaml b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
> new file mode 100644
> index 000000000000..1e68a801a92a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
> @@ -0,0 +1,72 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/peci/peci-aspeed.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Aspeed PECI Bus Device Tree Bindings
> +
> +maintainers:
> +  - Iwona Winiarska <iwona.winiarska at intel.com>
> +  - Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> +
> +allOf:
> +  - $ref: peci-controller.yaml#
> +
> +properties:
> +  compatible:
> +    enum:
> +      - aspeed,ast2400-peci
> +      - aspeed,ast2500-peci
> +      - aspeed,ast2600-peci
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    description:
> +      Clock source for PECI controller. Should reference the external
> +      oscillator clock.
> +    maxItems: 1
> +
> +  resets:
> +    maxItems: 1
> +
> +  cmd-timeout-ms:
> +    minimum: 1
> +    maximum: 1000
> +    default: 1000
> +
> +  clock-frequency:
> +    description:
> +      The desired operation frequency of PECI controller in Hz.
> +    minimum: 2000
> +    maximum: 2000000
> +    default: 1000000
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - resets
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/clock/ast2600-clock.h>
> +    peci-controller at 1e78b000 {
> +      compatible = "aspeed,ast2600-peci";
> +      reg = <0x1e78b000 0x100>;
> +      interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +      clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
> +      resets = <&syscon ASPEED_RESET_PECI>;
> +      cmd-timeout-ms = <1000>;
> +      clock-frequency = <1000000>;
> +    };
> +...
> --
> 2.31.1
>


From joel at jms.id.au  Wed Jan 12 19:17:42 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 13 Jan 2022 03:17:42 +0000
Subject: [PATCH v5 01/13] dt-bindings: Add generic bindings for PECI
In-Reply-To: <20220112230247.982212-2-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-2-iwona.winiarska@intel.com>
Message-ID: <CACPK8Xfi33mr38_sdxF_Hi8Pw7VHzxH0zJd09gQz0voJm2xDBA@mail.gmail.com>

On Wed, 12 Jan 2022 at 23:03, Iwona Winiarska <iwona.winiarska at intel.com> wrote:
>
> Add device tree bindings for the PECI controller.
>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Rob Herring <robh at kernel.org>

Reviewed-by: Joel Stanley <joel at jms.id.au>

> ---
>  .../bindings/peci/peci-controller.yaml        | 33 +++++++++++++++++++
>  1 file changed, 33 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml
>
> diff --git a/Documentation/devicetree/bindings/peci/peci-controller.yaml b/Documentation/devicetree/bindings/peci/peci-controller.yaml
> new file mode 100644
> index 000000000000..bbc3d3f3a929
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/peci/peci-controller.yaml
> @@ -0,0 +1,33 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/peci/peci-controller.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Generic Device Tree Bindings for PECI
> +
> +maintainers:
> +  - Iwona Winiarska <iwona.winiarska at intel.com>
> +
> +description:
> +  PECI (Platform Environment Control Interface) is an interface that provides a
> +  communication channel from Intel processors and chipset components to external
> +  monitoring or control devices.
> +
> +properties:
> +  $nodename:
> +    pattern: "^peci-controller(@.*)?$"
> +
> +  cmd-timeout-ms:
> +    description:
> +      Command timeout in units of ms.
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    peci-controller at 1e78b000 {
> +      reg = <0x1e78b000 0x100>;
> +      cmd-timeout-ms = <500>;
> +    };
> +...
> --
> 2.31.1
>


From yunfei.dong at mediatek.com  Wed Jan 12 20:10:37 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:37 +0800
Subject: [PATCH v19,
 01/19] media: mtk-vcodec: Get numbers of register bases from DT
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-2-yunfei.dong@mediatek.com>

Different platforms may have different numbers of register bases. Gets the
numbers of register bases from dts (sizeof(u32) * 4 bytes for each).

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 37 ++++++++++++++-----
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 40c39e1e596b..6980549e56e8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -75,6 +75,30 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	return IRQ_HANDLED;
 }
 
+static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int reg_num, i;
+
+	/* Sizeof(u32) * 4 bytes for each register base. */
+	reg_num = of_property_count_elems_of_size(pdev->dev.of_node, "reg",
+						  sizeof(u32) * 4);
+	if (reg_num <= 0 || reg_num > NUM_MAX_VDEC_REG_BASE) {
+		dev_err(&pdev->dev, "Invalid register property size: %d\n", reg_num);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < reg_num; i++) {
+		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
+		if (IS_ERR(dev->reg_base[i]))
+			return PTR_ERR(dev->reg_base[i]);
+
+		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -203,7 +227,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int i, ret;
+	int ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -235,14 +259,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	for (i = 0; i < NUM_MAX_VDEC_REG_BASE; i++) {
-		dev->reg_base[i] = devm_platform_ioremap_resource(pdev, i);
-		if (IS_ERR((__force void *)dev->reg_base[i])) {
-			ret = PTR_ERR((__force void *)dev->reg_base[i]);
-			goto err_res;
-		}
-		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
-	}
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		goto err_res;
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (res == NULL) {
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:45 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:45 +0800
Subject: [PATCH v19, 09/19] media: mtk-vcodec: Use pure single core for MT8183
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-10-yunfei.dong@mediatek.com>

Separates different architecture for hardware: pure_sin_core
and lat_sin_core. MT8183 is pure single core. Uses .hw_arch to
distinguish.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c     |  2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index c7f9259ad094..04ca43c77e5f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -626,4 +626,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 3294c8957ae5..23d997ac114d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,6 +357,7 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
 
 /* This platform data is used for one lat and one core architecture. */
@@ -375,4 +376,5 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = true,
+	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index ab2004242c43..17e7deee10b5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -324,6 +324,14 @@ enum mtk_chip {
 	MTK_MT8195,
 };
 
+/*
+ * enum mtk_vdec_hw_arch - Used to separate different hardware architecture
+ */
+enum mtk_vdec_hw_arch {
+	MTK_VDEC_PURE_SINGLE_CORE,
+	MTK_VDEC_LAT_SINGLE_CORE,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -342,6 +350,7 @@ enum mtk_chip {
  * @num_framesizes: count of video decoder frame sizes
  *
  * @chip: chip this decoder is compatible with
+ * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
@@ -364,6 +373,7 @@ struct mtk_vcodec_dec_pdata {
 	const int num_framesizes;
 
 	enum mtk_chip chip;
+	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
 	bool uses_stateless_api;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:43 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:43 +0800
Subject: [PATCH v19, 07/19] media: mtk-vcodec: Support MT8192
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-8-yunfei.dong@mediatek.com>

Adds MT8192's compatible "mediatek,mt8192-vcodec-dec".
Adds MT8192's device private data mtk_lat_sig_core_pdata.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec.h   |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c     |  4 ++++
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c        | 16 ++++++++++++++++
 3 files changed, 21 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index e08886a600a3..66cd6d2242c3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -68,6 +68,7 @@ extern const struct v4l2_m2m_ops mtk_vdec_m2m_ops;
 extern const struct media_device_ops mtk_vcodec_media_ops;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
+extern const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata;
 
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index b9f612fb630e..201ae71d0899 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -392,6 +392,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
 		.compatible = "mediatek,mt8183-vcodec-dec",
 		.data = &mtk_vdec_8183_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8192-vcodec-dec",
+		.data = &mtk_lat_sig_core_pdata,
+	},
 	{},
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 3d9f47555884..183cd67a334a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -357,3 +357,19 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 };
+
+const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
+	.chip = MTK_MT8192,
+	.init_vdec_params = mtk_init_vdec_params,
+	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
+	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
+	.vdec_formats = mtk_video_formats,
+	.num_formats = NUM_FORMATS,
+	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
+	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.vdec_framesizes = mtk_vdec_framesizes,
+	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.uses_stateless_api = true,
+	.worker = mtk_vdec_worker,
+	.flush_decoder = mtk_vdec_flush_decoder,
+};
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:39 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:39 +0800
Subject: [PATCH v19, 03/19] media: mtk-vcodec: Refactor vcodec pm interface
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-4-yunfei.dong@mediatek.com>

Using the needed params for pm init/release function and remove unused
param mtkdev in 'struct mtk_vcodec_pm'.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 ++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 23 ++++++++-----------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  4 ++--
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  1 -
 5 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 30257e4f989b..b9f612fb630e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -246,7 +246,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev);
+	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
 		goto err_dec_pm;
@@ -377,7 +377,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -416,7 +416,7 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(dev);
+	mtk_vcodec_release_dec_pm(&dev->pm);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 6038db96f71c..5ba54bb813c8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -13,18 +13,14 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
+	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int i = 0, ret = 0;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	pm->mtkdev = mtkdev;
 	dec_clk = &pm->vdec_clk;
 	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
 	if (!node) {
@@ -32,13 +28,12 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 		return -1;
 	}
 
-	pdev = of_find_device_by_node(node);
+	larb_pdev = of_find_device_by_node(node);
 	of_node_put(node);
-	if (WARN_ON(!pdev)) {
+	if (WARN_ON(!larb_pdev))
 		return -1;
-	}
-	pm->larbvdec = &pdev->dev;
-	pdev = mtkdev->plat_dev;
+
+	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -82,10 +77,10 @@ int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev)
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
+	pm_runtime_disable(pm->dev);
+	put_device(pm->larbvdec);
 }
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 280aeaefdb65..08769c7648eb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,8 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
+void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 1d2370608d0d..0fa9d85114b9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -195,7 +195,6 @@ struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	venc_clk;
 	struct device	*larbvenc;
 	struct device	*dev;
-	struct mtk_vcodec_dev	*mtkdev;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 1b2e4930ed27..0c8c8f86788c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -26,7 +26,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
-	pm->mtkdev = mtkdev;
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:40 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:40 +0800
Subject: [PATCH v19, 04/19] media: mtk-vcodec: export decoder pm functions
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-5-yunfei.dong@mediatek.com>

When mtk vcodec decoder is build as a module, we need to export
mtk-vcodec-dec pm functions to make them visible by the other components.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 5ba54bb813c8..64535d33bff8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -76,12 +76,14 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *p
 	put_device(pm->larbvdec);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm);
 
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 {
 	pm_runtime_disable(pm->dev);
 	put_device(pm->larbvdec);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
@@ -93,6 +95,7 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
@@ -102,6 +105,7 @@ void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
 void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
@@ -128,6 +132,7 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
 void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
@@ -138,3 +143,4 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:38 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:38 +0800
Subject: [PATCH v19,
 02/19] media: mtk-vcodec: Align vcodec wake up interrupt interface
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-3-yunfei.dong@mediatek.com>

Vdec and venc can use the same function to wake up interrupt event.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 8 ++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 8 --------
 3 files changed, 9 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 6980549e56e8..30257e4f989b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -28,13 +28,6 @@
 #define VDEC_IRQ_CLR	0x10
 #define VDEC_IRQ_CFG_REG	0xa4
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx)
-{
-	ctx->int_cond = 1;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -66,7 +59,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 581522177308..1d2370608d0d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -473,4 +473,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 	return container_of(ctrl->handler, struct mtk_vcodec_ctx, ctrl_hdl);
 }
 
+/* Wake up context wait_queue */
+static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+{
+	ctx->int_cond = 1;
+	ctx->int_type = reason;
+	wake_up_interruptible(&ctx->queue);
+}
+
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index aeaecb8d416e..027546108f44 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -62,14 +62,6 @@ static const struct mtk_video_fmt mtk_video_formats_capture_vp8[] =  {
 	},
 };
 
-/* Wake up context wait_queue */
-static void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
-{
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
-}
-
 static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 {
 	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:47 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:47 +0800
Subject: [PATCH v19,
 11/19] media: mtk-vcodec: Add msg queue feature for lat and core
 architecture
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-12-yunfei.dong@mediatek.com>

For lat and core architecture, lat thread will send message to core
thread when lat decode done. Core hardware will use the message
from lat to decode, then free message to lat thread when decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   9 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 258 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 151 ++++++++++
 4 files changed, 419 insertions(+)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index c61bfb179bcc..359619653a0e 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -12,6 +12,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
+		vdec_msg_queue.o \
 		mtk_vcodec_dec.o \
 		mtk_vcodec_dec_stateful.o \
 		mtk_vcodec_dec_stateless.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 9667310cb55a..c9a377035e80 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -15,7 +15,9 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-core.h>
+
 #include "mtk_vcodec_util.h"
+#include "vdec_msg_queue.h"
 
 #define MTK_VCODEC_DRV_NAME	"mtk_vcodec_drv"
 #define MTK_VCODEC_DEC_NAME	"mtk-vcodec-dec"
@@ -282,6 +284,8 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ *
+ * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -325,6 +329,7 @@ struct mtk_vcodec_ctx {
 	int decoded_frame_cnt;
 	struct mutex lock;
 
+	struct vdec_msg_queue msg_queue;
 };
 
 enum mtk_chip {
@@ -457,6 +462,8 @@ struct mtk_vcodec_enc_pdata {
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
  *
+ * @msg_queue_core_ctx: msg queue context used for core workqueue
+ *
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
@@ -498,6 +505,8 @@ struct mtk_vcodec_dev {
 	unsigned int dec_capability;
 	unsigned int enc_capability;
 
+	struct vdec_msg_queue_ctx msg_queue_core_ctx;
+
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
new file mode 100644
index 000000000000..d0276b32a6b6
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/freezer.h>
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_drv.h"
+#include "vdec_msg_queue.h"
+
+#define VDEC_MSG_QUEUE_TIMEOUT_MS 1500
+
+/* the size used to store lat slice header information */
+#define VDEC_LAT_SLICE_HEADER_SZ    (640 * SZ_1K)
+
+/* the size used to store avc error information */
+#define VDEC_ERR_MAP_SZ_AVC         (17 * SZ_1K)
+
+/* core will read the trans buffer which decoded by lat to decode again.
+ * The trans buffer size of FHD and 4K bitstreams are different.
+ */
+static int vde_msg_queue_get_trans_size(int width, int height)
+{
+	if (width > 1920 || height > 1088)
+		return 30 * SZ_1M;
+	else
+		return 6 * SZ_1M;
+}
+
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index)
+{
+	init_waitqueue_head(&ctx->ready_to_use);
+	INIT_LIST_HEAD(&ctx->ready_queue);
+	spin_lock_init(&ctx->ready_lock);
+	ctx->ready_num = 0;
+	ctx->hardware_index = hardware_index;
+}
+
+static struct list_head *vdec_get_buf_list(int hardware_index, struct vdec_lat_buf *buf)
+{
+	switch (hardware_index) {
+	case MTK_VDEC_CORE:
+		return &buf->core_list;
+	case MTK_VDEC_LAT0:
+		return &buf->lat_list;
+	default:
+		return NULL;
+	}
+}
+
+int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf *buf)
+{
+	struct list_head *head;
+
+	head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
+	if (!head) {
+		mtk_v4l2_err("fail to qbuf: %d", msg_ctx->hardware_index);
+		return -EINVAL;
+	}
+
+	spin_lock(&msg_ctx->ready_lock);
+	list_add_tail(head, &msg_ctx->ready_queue);
+	msg_ctx->ready_num++;
+
+	if (msg_ctx->hardware_index != MTK_VDEC_CORE)
+		wake_up_all(&msg_ctx->ready_to_use);
+
+	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
+		       msg_ctx->hardware_index, buf, msg_ctx->ready_num);
+	spin_unlock(&msg_ctx->ready_lock);
+
+	return 0;
+}
+
+static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *msg_ctx)
+{
+	int ret;
+
+	ret = wait_event_timeout(msg_ctx->ready_to_use,
+				 !list_empty(&msg_ctx->ready_queue),
+				 msecs_to_jiffies(VDEC_MSG_QUEUE_TIMEOUT_MS));
+	if (!ret)
+		return false;
+
+	return true;
+}
+
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx)
+{
+	struct vdec_lat_buf *buf;
+	struct list_head *head;
+	int ret;
+
+	spin_lock(&msg_ctx->ready_lock);
+	if (list_empty(&msg_ctx->ready_queue)) {
+		mtk_v4l2_debug(3, "queue is NULL, type:%d num: %d",
+			       msg_ctx->hardware_index, msg_ctx->ready_num);
+		spin_unlock(&msg_ctx->ready_lock);
+
+		if (msg_ctx->hardware_index == MTK_VDEC_CORE)
+			return NULL;
+
+		ret = vdec_msg_queue_wait_event(msg_ctx);
+		if (!ret)
+			return NULL;
+		spin_lock(&msg_ctx->ready_lock);
+	}
+
+	if (msg_ctx->hardware_index == MTK_VDEC_CORE)
+		buf = list_first_entry(&msg_ctx->ready_queue,
+				       struct vdec_lat_buf, core_list);
+	else
+		buf = list_first_entry(&msg_ctx->ready_queue,
+				       struct vdec_lat_buf, lat_list);
+
+	head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
+	if (!head) {
+		spin_unlock(&msg_ctx->ready_lock);
+		mtk_v4l2_err("fail to dqbuf: %d", msg_ctx->hardware_index);
+		return NULL;
+	}
+	list_del(head);
+
+	msg_ctx->ready_num--;
+	mtk_v4l2_debug(3, "dqueue buf type:%d addr: 0x%p num: %d",
+		       msg_ctx->hardware_index, buf, msg_ctx->ready_num);
+	spin_unlock(&msg_ctx->ready_lock);
+
+	return buf;
+}
+
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_rptr_addr = ube_rptr;
+	mtk_v4l2_debug(3, "update ube rprt (0x%llx)", ube_rptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr)
+{
+	spin_lock(&msg_queue->lat_ctx.ready_lock);
+	msg_queue->wdma_wptr_addr = ube_wptr;
+	mtk_v4l2_debug(3, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
+		       msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr,
+		       ube_wptr);
+	spin_unlock(&msg_queue->lat_ctx.ready_lock);
+}
+
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
+{
+	long timeout_jiff;
+	int ret;
+
+	timeout_jiff = msecs_to_jiffies(1000 * (NUM_BUFFER_COUNT + 2));
+	ret = wait_event_timeout(msg_queue->lat_ctx.ready_to_use,
+				 msg_queue->lat_ctx.ready_num == NUM_BUFFER_COUNT,
+				 timeout_jiff);
+	if (ret) {
+		mtk_v4l2_debug(3, "success to get lat buf: %d",
+			       msg_queue->lat_ctx.ready_num);
+		return true;
+	}
+	mtk_v4l2_err("failed with lat buf isn't full: %d",
+		     msg_queue->lat_ctx.ready_num);
+	return false;
+}
+
+void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
+			   struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_lat_buf *lat_buf;
+	struct mtk_vcodec_mem *mem;
+	int i;
+
+	mem = &msg_queue->wdma_addr;
+	if (mem->va)
+		mtk_vcodec_mem_free(ctx, mem);
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		mem = &lat_buf->wdma_err_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		mem = &lat_buf->slice_bc_addr;
+		if (mem->va)
+			mtk_vcodec_mem_free(ctx, mem);
+
+		kfree(lat_buf->private_data);
+	}
+}
+
+int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+			struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
+			int private_size)
+{
+	struct vdec_lat_buf *lat_buf;
+	int i, err;
+
+	/* already init msg queue */
+	if (msg_queue->wdma_addr.size)
+		return 0;
+
+	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	msg_queue->wdma_addr.size =
+		vde_msg_queue_get_trans_size(ctx->picinfo.buf_w,
+					     ctx->picinfo.buf_h);
+
+	err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr);
+	if (err) {
+		mtk_v4l2_err("failed to allocate wdma_addr buf");
+		return -ENOMEM;
+	}
+	msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr;
+	msg_queue->wdma_wptr_addr = msg_queue->wdma_addr.dma_addr;
+
+	for (i = 0; i < NUM_BUFFER_COUNT; i++) {
+		lat_buf = &msg_queue->lat_buf[i];
+
+		lat_buf->wdma_err_addr.size = VDEC_ERR_MAP_SZ_AVC;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->wdma_err_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_err_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->slice_bc_addr.size = VDEC_LAT_SLICE_HEADER_SZ;
+		err = mtk_vcodec_mem_alloc(ctx, &lat_buf->slice_bc_addr);
+		if (err) {
+			mtk_v4l2_err("failed to allocate wdma_addr buf[%d]", i);
+			goto mem_alloc_err;
+		}
+
+		lat_buf->private_data = kzalloc(private_size, GFP_KERNEL);
+		if (!lat_buf->private_data) {
+			err = -ENOMEM;
+			goto mem_alloc_err;
+		}
+
+		lat_buf->ctx = ctx;
+		lat_buf->core_decode = core_decode;
+		err = vdec_msg_queue_qbuf(&msg_queue->lat_ctx, lat_buf);
+		if (err) {
+			mtk_v4l2_err("failed to qbuf buf[%d]", i);
+			goto mem_alloc_err;
+		}
+	}
+	return 0;
+
+mem_alloc_err:
+	vdec_msg_queue_deinit(msg_queue, ctx);
+	return err;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
new file mode 100644
index 000000000000..7096b77a456c
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_MSG_QUEUE_H_
+#define _VDEC_MSG_QUEUE_H_
+
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/slab.h>
+#include <media/videobuf2-v4l2.h>
+
+#include "mtk_vcodec_util.h"
+
+#define NUM_BUFFER_COUNT 3
+
+struct vdec_lat_buf;
+struct mtk_vcodec_ctx;
+struct mtk_vcodec_dev;
+typedef int (*core_decode_cb_t)(struct vdec_lat_buf *lat_buf);
+
+/**
+ * struct vdec_msg_queue_ctx - represents a queue for buffers ready to be processed
+ * @ready_to_use: ready used queue used to signalize when get a job queue
+ * @ready_queue: list of ready lat buffer queues
+ * @ready_lock: spin lock to protect the lat buffer usage
+ * @ready_num: number of buffers ready to be processed
+ * @hardware_index: hardware id that this queue is used for
+ */
+struct vdec_msg_queue_ctx {
+	wait_queue_head_t ready_to_use;
+	struct list_head ready_queue;
+	/* protect lat buffer */
+	spinlock_t ready_lock;
+	int ready_num;
+	int hardware_index;
+};
+
+/**
+ * struct vdec_lat_buf - lat buffer message used to store lat info for core decode
+ * @wdma_err_addr: wdma error address used for lat hardware
+ * @slice_bc_addr: slice bc address used for lat hardware
+ * @ts_info: need to set timestamp from output to capture
+ *
+ * @private_data: shared information used to lat and core hardware
+ * @ctx: mtk vcodec context information
+ * @core_decode: different codec use different decode callback function
+ * @lat_list: add lat buffer to lat head list
+ * @core_list: add lat buffer to core head list
+ */
+struct vdec_lat_buf {
+	struct mtk_vcodec_mem wdma_err_addr;
+	struct mtk_vcodec_mem slice_bc_addr;
+	struct vb2_v4l2_buffer ts_info;
+
+	void *private_data;
+	struct mtk_vcodec_ctx *ctx;
+	core_decode_cb_t core_decode;
+	struct list_head lat_list;
+	struct list_head core_list;
+};
+
+/**
+ * struct vdec_msg_queue - used to store lat buffer message
+ * @lat_buf: lat buffer used to store lat buffer information
+ * @wdma_addr: wdma address used for ube
+ * @wdma_rptr_addr: ube read point
+ * @wdma_wptr_addr: ube write point
+ * @lat_ctx: used to store lat buffer list
+ */
+struct vdec_msg_queue {
+	struct vdec_lat_buf lat_buf[NUM_BUFFER_COUNT];
+
+	struct mtk_vcodec_mem wdma_addr;
+	u64 wdma_rptr_addr;
+	u64 wdma_wptr_addr;
+
+	struct vdec_msg_queue_ctx lat_ctx;
+};
+
+/**
+ * vdec_msg_queue_init - init lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ * @core_decode: core decode callback for each codec
+ * @private_size: the private data size used to share with core
+ *
+ * Return: returns 0 if init successfully, or fail.
+ */
+int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
+			struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
+			int private_size);
+
+/**
+ * vdec_msg_queue_init_ctx - used to init msg queue context information.
+ * @ctx: message queue context
+ * @hardware_index: hardware index
+ */
+void vdec_msg_queue_init_ctx(struct vdec_msg_queue_ctx *ctx, int hardware_index);
+
+/**
+ * vdec_msg_queue_qbuf - enqueue lat buffer to queue list.
+ * @ctx: message queue context
+ * @buf: current lat buffer
+ *
+ * Return: returns 0 if qbuf successfully, or fail.
+ */
+int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *ctx, struct vdec_lat_buf *buf);
+
+/**
+ * vdec_msg_queue_dqbuf - dequeue lat buffer from queue list.
+ * @ctx: message queue context
+ *
+ * Return: returns not null if dq successfully, or fail.
+ */
+struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *ctx);
+
+/**
+ * vdec_msg_queue_update_ube_rptr - used to updata the ube read point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_rptr: current ube read point
+ */
+void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr);
+
+/**
+ * vdec_msg_queue_update_ube_wptr - used to updata the ube write point.
+ * @msg_queue: used to store the lat buffer information
+ * @ube_wptr: current ube write point
+ */
+void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr);
+
+/**
+ * vdec_msg_queue_wait_lat_buf_full - used to check whether all lat buffer
+ *                                    in lat list.
+ * @msg_queue: used to store the lat buffer information
+ *
+ * Return: returns true if successfully, or fail.
+ */
+bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue);
+
+/**
+ * vdec_msg_queue_deinit - deinit lat buffer information.
+ * @msg_queue: used to store the lat buffer information
+ * @ctx: v4l2 ctx
+ */
+void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
+			   struct mtk_vcodec_ctx *ctx);
+
+#endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:44 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:44 +0800
Subject: [PATCH v19,
 08/19] media: mtk-vcodec: Add to support multi hardware decode
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-9-yunfei.dong@mediatek.com>

There are more than two hardwares for decoder: LAT0, LAT1 and CORE. In
order to manage these hardwares, register each hardware as independent
platform device for the larbs are different.

Each hardware module controls its own information which includes
interrupt/power/clocks/registers.

Calling of_platform_populate in parent device, and use subdev_bitmap to
record whether the hardwares are registered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   5 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  85 +++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 198 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  52 +++++
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   3 +
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  21 ++
 7 files changed, 333 insertions(+), 32 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index ca8e9e7a9c4e..c61bfb179bcc 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -2,7 +2,8 @@
 
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 				       mtk-vcodec-enc.o \
-				       mtk-vcodec-common.o
+				       mtk-vcodec-common.o \
+				       mtk-vcodec-dec-hw.o
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
@@ -16,6 +17,8 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		mtk_vcodec_dec_stateless.o \
 		mtk_vcodec_dec_pm.o \
 
+mtk-vcodec-dec-hw-y := mtk_vcodec_dec_hw.o
+
 mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc/venc_h264_if.o \
 		mtk_vcodec_enc.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 201ae71d0899..7e2c9c381dd2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -18,16 +18,12 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
-#define VDEC_HW_ACTIVE	0x10
-#define VDEC_IRQ_CFG	0x11
-#define VDEC_IRQ_CLR	0x10
-#define VDEC_IRQ_CFG_REG	0xa4
-
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -92,6 +88,42 @@ static int mtk_vcodec_get_reg_bases(struct mtk_vcodec_dev *dev)
 	return 0;
 }
 
+static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	ret = mtk_vcodec_get_reg_bases(dev);
+	if (ret)
+		return ret;
+
+	if (dev->vdec_pdata->is_subdev_supported)
+		return 0;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "failed to get irq number");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+			       mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to get mt vcodec clock source");
+		return ret;
+	}
+
+	return 0;
+}
+
 static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
@@ -113,6 +145,11 @@ static int fops_vcodec_open(struct file *file)
 	init_waitqueue_head(&ctx->queue);
 	mutex_init(&ctx->lock);
 
+	if (dev->vdec_pdata->is_subdev_supported && dev->subdev_prob_done) {
+		ret = dev->subdev_prob_done(dev);
+		if (ret)
+			goto err_ctrls_setup;
+	}
 	ctx->type = MTK_INST_DECODER;
 	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
@@ -217,7 +254,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_dec;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
 	int ret;
@@ -246,32 +282,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR(dev->fw_handler))
 		return PTR_ERR(dev->fw_handler);
 
-	ret = mtk_vcodec_init_dec_pm(dev->plat_dev, &dev->pm);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mt vcodec clock source");
-		goto err_dec_pm;
-	}
-
-	ret = mtk_vcodec_get_reg_bases(dev);
-	if (ret)
-		goto err_res;
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
-
-	dev->dec_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
-			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
+	ret = mtk_vcodec_init_dec_resources(dev);
 	if (ret) {
-		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
-			dev->dec_irq,
-			ret);
-		goto err_res;
+		dev_err(&pdev->dev, "Failed to init dec resources");
+		goto err_dec_pm;
 	}
 
 	mutex_init(&dev->dec_mutex);
@@ -326,6 +340,15 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_event_workq;
 	}
 
+	if (dev->vdec_pdata->is_subdev_supported) {
+		ret = of_platform_populate(pdev->dev.of_node, NULL, NULL,
+					   &pdev->dev);
+		if (ret) {
+			mtk_v4l2_err("Main device of_platform_populate failed.");
+			goto err_event_workq;
+		}
+	}
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
new file mode 100644
index 000000000000..cde9442e7ce6
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_dec.h"
+#include "mtk_vcodec_dec_hw.h"
+#include "mtk_vcodec_dec_pm.h"
+#include "mtk_vcodec_intr.h"
+#include "mtk_vcodec_util.h"
+
+static const struct of_device_id mtk_vdec_hw_match[] = {
+	{
+		.compatible = "mediatek,mtk-vcodec-lat",
+		.data = (void *)MTK_VDEC_LAT0,
+	},
+	{
+		.compatible = "mediatek,mtk-vcodec-core",
+		.data = (void *)MTK_VDEC_CORE,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match);
+
+static int mtk_vdec_hw_prob_done(struct mtk_vcodec_dev *vdec_dev)
+{
+	struct platform_device *pdev = vdec_dev->plat_dev;
+	struct device_node *subdev_node;
+	enum mtk_vdec_hw_id hw_idx;
+	const struct of_device_id *of_id;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mtk_vdec_hw_match); i++) {
+		of_id = &mtk_vdec_hw_match[i];
+		subdev_node = of_find_compatible_node(NULL, NULL,
+						      of_id->compatible);
+		if (!subdev_node)
+			continue;
+
+		hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
+		if (!test_bit(hw_idx, vdec_dev->subdev_bitmap)) {
+			dev_err(&pdev->dev, "vdec %d is not ready", hw_idx);
+			return -EAGAIN;
+		}
+	}
+
+	return 0;
+}
+
+static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
+{
+	struct mtk_vdec_hw_dev *dev = priv;
+	struct mtk_vcodec_ctx *ctx;
+	u32 cg_status;
+	unsigned int dec_done_status;
+	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
+					VDEC_IRQ_CFG_REG;
+
+	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev);
+
+	/* check if HW active or not */
+	cg_status = readl(dev->reg_base[VDEC_HW_SYS]);
+	if (cg_status & VDEC_HW_ACTIVE) {
+		mtk_v4l2_err("vdec active is not 0x0 (0x%08x)",
+			     cg_status);
+		return IRQ_HANDLED;
+	}
+
+	dec_done_status = readl(vdec_misc_addr);
+	if ((dec_done_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS) !=
+	    MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
+		return IRQ_HANDLED;
+
+	/* clear interrupt */
+	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
+	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+
+	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
+		       ctx->id, dec_done_status);
+
+	return IRQ_HANDLED;
+}
+
+static int mtk_vdec_hw_init_irq(struct mtk_vdec_hw_dev *dev)
+{
+	struct platform_device *pdev = dev->plat_dev;
+	int ret;
+
+	dev->dec_irq = platform_get_irq(pdev, 0);
+	if (dev->dec_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		return dev->dec_irq;
+	}
+
+	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
+	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
+			       mtk_vdec_hw_irq_handler, 0, pdev->name, dev);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to install dev->dec_irq %d (%d)",
+			dev->dec_irq, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mtk_vdec_hw_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_dev *main_dev;
+	const struct of_device_id *of_id;
+	int hw_idx;
+	int ret;
+
+	if (!dev->parent) {
+		dev_err(dev, "no parent for hardware devices.\n");
+		return -ENODEV;
+	}
+
+	main_dev = dev_get_drvdata(dev->parent);
+	if (!main_dev) {
+		dev_err(dev, "failed to get parent driver data");
+		return -EINVAL;
+	}
+
+	subdev_dev = devm_kzalloc(dev, sizeof(*subdev_dev), GFP_KERNEL);
+	if (!subdev_dev)
+		return -ENOMEM;
+
+	subdev_dev->plat_dev = pdev;
+	ret = mtk_vcodec_init_dec_pm(pdev, &subdev_dev->pm);
+	if (ret)
+		return ret;
+
+	of_id = of_match_device(mtk_vdec_hw_match, dev);
+	if (!of_id) {
+		dev_err(dev, "Can't get vdec subdev id.\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	hw_idx = (enum mtk_vdec_hw_id)(uintptr_t)of_id->data;
+	if (hw_idx >= MTK_VDEC_HW_MAX) {
+		dev_err(dev, "Hardware index %d not correct.\n", hw_idx);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	main_dev->subdev_dev[hw_idx] = subdev_dev;
+	subdev_dev->hw_idx = hw_idx;
+	subdev_dev->main_dev = main_dev;
+	subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS];
+	set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
+
+	ret = mtk_vdec_hw_init_irq(subdev_dev);
+	if (ret)
+		goto err;
+
+	subdev_dev->reg_base[VDEC_HW_MISC] =
+		devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC])) {
+		ret = PTR_ERR((__force void *)subdev_dev->reg_base[VDEC_HW_MISC]);
+		goto err;
+	}
+
+	if (!main_dev->subdev_prob_done)
+		main_dev->subdev_prob_done = mtk_vdec_hw_prob_done;
+
+	platform_set_drvdata(pdev, subdev_dev);
+	return 0;
+err:
+	mtk_vcodec_release_dec_pm(&subdev_dev->pm);
+	return ret;
+}
+
+static struct platform_driver mtk_vdec_driver = {
+	.probe	= mtk_vdec_hw_probe,
+	.driver	= {
+		.name	= "mtk-vdec-comp",
+		.of_match_table = mtk_vdec_hw_match,
+	},
+};
+module_platform_driver(mtk_vdec_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video decoder hardware driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
new file mode 100644
index 000000000000..5c2cfeaa9d9f
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _MTK_VCODEC_DEC_HW_H_
+#define _MTK_VCODEC_DEC_HW_H_
+
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include "mtk_vcodec_drv.h"
+
+#define VDEC_HW_ACTIVE 0x10
+#define VDEC_IRQ_CFG 0x11
+#define VDEC_IRQ_CLR 0x10
+#define VDEC_IRQ_CFG_REG 0xa4
+
+/**
+ * enum mtk_vdec_hw_reg_idx - subdev hardware register base index
+ * @VDEC_HW_SYS : vdec soc register index
+ * @VDEC_HW_MISC: vdec misc register index
+ * @VDEC_HW_MAX : vdec supported max register index
+ */
+enum mtk_vdec_hw_reg_idx {
+	VDEC_HW_SYS,
+	VDEC_HW_MISC,
+	VDEC_HW_MAX
+};
+
+/**
+ * struct mtk_vdec_hw_dev - vdec hardware driver data
+ * @plat_dev: platform device
+ * @main_dev: main device
+ * @reg_base: mapped address of MTK Vcodec registers.
+ *
+ * @dec_irq : decoder irq resource
+ * @pm      : power management control
+ * @hw_idx  : each hardware index
+ */
+struct mtk_vdec_hw_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *main_dev;
+	void __iomem *reg_base[VDEC_HW_MAX];
+
+	int dec_irq;
+	struct mtk_vcodec_pm pm;
+	int hw_idx;
+};
+
+#endif /* _MTK_VCODEC_DEC_HW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index bef49244e61b..c7f9259ad094 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -625,4 +625,5 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = false,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 183cd67a334a..3294c8957ae5 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -356,8 +356,10 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = false,
 };
 
+/* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
@@ -372,4 +374,5 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.is_subdev_supported = true,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 0fa9d85114b9..ab2004242c43 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -93,6 +93,17 @@ enum mtk_fmt_type {
 	MTK_FMT_FRAME = 2,
 };
 
+/*
+ * enum mtk_vdec_hw_id - Hardware index used to separate
+ *                         different hardware
+ */
+enum mtk_vdec_hw_id {
+	MTK_VDEC_CORE,
+	MTK_VDEC_LAT0,
+	MTK_VDEC_LAT1,
+	MTK_VDEC_HW_MAX,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -332,6 +343,7 @@ enum mtk_chip {
  *
  * @chip: chip this decoder is compatible with
  *
+ * @is_subdev_supported: whether support parent-node architecture(subdev)
  * @uses_stateless_api: whether the decoder uses the stateless API with requests
  */
 
@@ -353,6 +365,7 @@ struct mtk_vcodec_dec_pdata {
 
 	enum mtk_chip chip;
 
+	bool is_subdev_supported;
 	bool uses_stateless_api;
 };
 
@@ -423,6 +436,10 @@ struct mtk_vcodec_enc_pdata {
  * @pm: power management control
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
+ *
+ * @subdev_dev: subdev hardware device
+ * @subdev_prob_done: check whether all used hw device is prob done
+ * @subdev_bitmap: used to record hardware is ready or not
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -460,6 +477,10 @@ struct mtk_vcodec_dev {
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
 	unsigned int enc_capability;
+
+	void *subdev_dev[MTK_VDEC_HW_MAX];
+	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
+	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:49 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:49 +0800
Subject: [PATCH v19,
 13/19] media: mtk-vcodec: Add new interface to lock different hardware
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-14-yunfei.dong@mediatek.com>

For add new hardware, not only need to lock lat hardware, also
need to lock core hardware in case of different instance start
to decoder at the same time.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c     | 4 ++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 5 +++--
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h     | 3 ++-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 2b334a8a81c6..130ecef2e766 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -105,12 +105,12 @@ static int vidioc_decoder_cmd(struct file *file, void *priv,
 
 void mtk_vdec_unlock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_unlock(&ctx->dev->dec_mutex);
+	mutex_unlock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vdec_lock(struct mtk_vcodec_ctx *ctx)
 {
-	mutex_lock(&ctx->dev->dec_mutex);
+	mutex_lock(&ctx->dev->dec_mutex[ctx->hw_id]);
 }
 
 void mtk_vcodec_dec_release(struct mtk_vcodec_ctx *ctx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index ffc4ba698876..d592104023d9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -279,7 +279,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_dec;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int i, ret;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -311,7 +311,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
-	mutex_init(&dev->dec_mutex);
+	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
+		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
 	spin_lock_init(&dev->irqlock);
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 4d3fd2a7a56e..cefac0262426 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -500,7 +500,8 @@ struct mtk_vcodec_dev {
 	int dec_irq;
 	int enc_irq;
 
-	struct mutex dec_mutex;
+	/* decoder hardware mutex lock */
+	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex enc_mutex;
 
 	struct mtk_vcodec_pm pm;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:46 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:46 +0800
Subject: [PATCH v19,
 10/19] media: mtk-vcodec: Add irq interface for multi hardware
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-11-yunfei.dong@mediatek.com>

Adds irq interface for multi hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 33 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 25 ++++++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     | 30 ++++++++---------
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |  5 +--
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |  2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |  2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |  2 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |  2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  2 +-
 12 files changed, 72 insertions(+), 39 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 7e2c9c381dd2..40d1f16a0a25 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -24,6 +24,19 @@
 #include "mtk_vcodec_util.h"
 #include "mtk_vcodec_fw.h"
 
+static int mtk_vcodec_get_hw_count(struct mtk_vcodec_dev *dev)
+{
+	switch (dev->vdec_pdata->hw_arch) {
+	case MTK_VDEC_PURE_SINGLE_CORE:
+		return MTK_VDEC_ONE_CORE;
+	case MTK_VDEC_LAT_SINGLE_CORE:
+		return MTK_VDEC_ONE_LAT_ONE_CORE;
+	default:
+		mtk_v4l2_err("hw arch %d not supported", dev->vdec_pdata->hw_arch);
+		return MTK_VDEC_NO_HW;
+	}
+}
+
 static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 {
 	struct mtk_vcodec_dev *dev = priv;
@@ -55,7 +68,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	writel((readl(vdec_misc_addr) & ~VDEC_IRQ_CLR),
 		dev->reg_base[VDEC_MISC] + VDEC_IRQ_CFG_REG);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 
 	mtk_v4l2_debug(3,
 			"mtk_vcodec_dec_irq_handler :wake up ctx %d, dec_done_status=%x",
@@ -128,7 +141,7 @@ static int fops_vcodec_open(struct file *file)
 {
 	struct mtk_vcodec_dev *dev = video_drvdata(file);
 	struct mtk_vcodec_ctx *ctx = NULL;
-	int ret = 0;
+	int ret = 0, i, hw_count;
 	struct vb2_queue *src_vq;
 
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
@@ -142,14 +155,24 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
-	mutex_init(&ctx->lock);
+	if (ctx->dev->vdec_pdata->is_subdev_supported) {
+		hw_count = mtk_vcodec_get_hw_count(dev);
+		if (!hw_count || !dev->subdev_prob_done) {
+			ret = -EINVAL;
+			goto err_ctrls_setup;
+		}
 
-	if (dev->vdec_pdata->is_subdev_supported && dev->subdev_prob_done) {
 		ret = dev->subdev_prob_done(dev);
 		if (ret)
 			goto err_ctrls_setup;
+
+		for (i = 0; i < hw_count; i++)
+			init_waitqueue_head(&ctx->queue[i]);
+	} else {
+		init_waitqueue_head(&ctx->queue[0]);
 	}
+	mutex_init(&ctx->lock);
+
 	ctx->type = MTK_INST_DECODER;
 	ret = dev->vdec_pdata->ctrls_setup(ctx);
 	if (ret) {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index cde9442e7ce6..6b248dd94dd3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -84,7 +84,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
 	writel(dec_done_status | VDEC_IRQ_CFG, vdec_misc_addr);
 	writel(dec_done_status & ~VDEC_IRQ_CLR, vdec_misc_addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, dev->hw_idx);
 
 	mtk_v4l2_debug(3, "wake up ctx %d, dec_done_status=%x",
 		       ctx->id, dec_done_status);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 17e7deee10b5..9667310cb55a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,16 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_HW_MAX,
 };
 
+/*
+ * enum mtk_vdec_hw_count - Supported hardware count
+ */
+enum mtk_vdec_hw_count {
+	MTK_VDEC_NO_HW = 0,
+	MTK_VDEC_ONE_CORE,
+	MTK_VDEC_ONE_LAT_ONE_CORE,
+	MTK_VDEC_MAX_HW_COUNT,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -293,9 +303,9 @@ struct mtk_vcodec_ctx {
 	struct vdec_pic_info picinfo;
 	int dpb_size;
 
-	int int_cond;
-	int int_type;
-	wait_queue_head_t queue;
+	int int_cond[MTK_VDEC_HW_MAX];
+	int int_type[MTK_VDEC_HW_MAX];
+	wait_queue_head_t queue[MTK_VDEC_HW_MAX];
 	unsigned int irq_status;
 
 	struct v4l2_ctrl_handler ctrl_hdl;
@@ -504,11 +514,12 @@ static inline struct mtk_vcodec_ctx *ctrl_to_ctx(struct v4l2_ctrl *ctrl)
 }
 
 /* Wake up context wait_queue */
-static inline void wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason)
+static inline void
+wake_up_ctx(struct mtk_vcodec_ctx *ctx, unsigned int reason, unsigned int hw_id)
 {
-	ctx->int_cond = 1;
-	ctx->int_type = reason;
-	wake_up_interruptible(&ctx->queue);
+	ctx->int_cond[hw_id] = 1;
+	ctx->int_type[hw_id] = reason;
+	wake_up_interruptible(&ctx->queue[hw_id]);
 }
 
 #endif /* _MTK_VCODEC_DRV_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 027546108f44..347f0d87e2ff 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -103,7 +103,7 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED);
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
 	return IRQ_HANDLED;
 }
 
@@ -129,7 +129,7 @@ static int fops_vcodec_open(struct file *file)
 	v4l2_fh_add(&ctx->fh);
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
-	init_waitqueue_head(&ctx->queue);
+	init_waitqueue_head(&ctx->queue[0]);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
index 70580c2525ba..552b4c93d972 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.c
@@ -11,34 +11,32 @@
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx  *ctx, int command,
-				 unsigned int timeout_ms)
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+				 int command, unsigned int timeout_ms,
+				 unsigned int hw_id)
 {
-	wait_queue_head_t *waitqueue;
 	long timeout_jiff, ret;
 	int status = 0;
 
-	waitqueue = (wait_queue_head_t *)&ctx->queue;
 	timeout_jiff = msecs_to_jiffies(timeout_ms);
-
-	ret = wait_event_interruptible_timeout(*waitqueue,
-				ctx->int_cond,
-				timeout_jiff);
+	ret = wait_event_interruptible_timeout(ctx->queue[hw_id],
+					       ctx->int_cond[hw_id],
+					       timeout_jiff);
 
 	if (!ret) {
 		status = -1;	/* timeout */
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout time=%ums out %d %d!",
-			     ctx->id, ctx->type, command, timeout_ms,
-			     ctx->int_cond, ctx->int_type);
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec timeout=%ums (%d %d)",
+			     ctx->id, command, ctx->type, timeout_ms,
+			     ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	} else if (-ERESTARTSYS == ret) {
-		mtk_v4l2_err("[%d] ctx->type=%d, cmd=%d, wait_event_interruptible_timeout interrupted by a signal %d %d",
-			     ctx->id, ctx->type, command, ctx->int_cond,
-			     ctx->int_type);
 		status = -1;
+		mtk_v4l2_err("[%d] cmd=%d, type=%d, dec inter fail (%d %d)",
+			     ctx->id, command, ctx->type,
+			     ctx->int_cond[hw_id], ctx->int_type[hw_id]);
 	}
 
-	ctx->int_cond = 0;
-	ctx->int_type = 0;
+	ctx->int_cond[hw_id] = 0;
+	ctx->int_type[hw_id] = 0;
 
 	return status;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
index 638cd1f3526a..9681f492813b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_intr.h
@@ -12,7 +12,8 @@
 struct mtk_vcodec_ctx;
 
 /* timeout is ms */
-int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *data, int command,
-				unsigned int timeout_ms);
+int mtk_vcodec_wait_for_done_ctx(struct mtk_vcodec_ctx *ctx,
+				 int command, unsigned int timeout_ms,
+				 unsigned int hw_id);
 
 #endif /* _MTK_VCODEC_INTR_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
index 40d6e6c5ac7a..481655bb6016 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c
@@ -413,7 +413,7 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		/* wait decoder done interrupt */
 		err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 						   MTK_INST_IRQ_RECEIVED,
-						   WAIT_INTR_TIMEOUT_MS);
+						   WAIT_INTR_TIMEOUT_MS, 0);
 		if (err)
 			goto err_free_fb_out;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index fada4d146703..43542de11e9c 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -727,7 +727,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 	/* wait decoder done interrupt */
 	err = mtk_vcodec_wait_for_done_ctx(inst->ctx,
 					   MTK_INST_IRQ_RECEIVED,
-					   WAIT_INTR_TIMEOUT_MS);
+					   WAIT_INTR_TIMEOUT_MS, 0);
 	if (err)
 		goto err_free_fb_out;
 	vpu_dec_end(vpu);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
index e5393f841080..88c046731754 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_if.c
@@ -488,7 +488,7 @@ static int vdec_vp8_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	/* wait decoder done interrupt */
 	mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
-				     WAIT_INTR_TIMEOUT_MS);
+				     WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (inst->vsi->load_data)
 		load_dec_table(inst);
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
index 71cdc3ddafcb..70b8383f7c8e 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_if.c
@@ -539,7 +539,7 @@ static bool vp9_wait_dec_end(struct vdec_vp9_inst *inst)
 
 	mtk_vcodec_wait_for_done_ctx(inst->ctx,
 			MTK_INST_IRQ_RECEIVED,
-			WAIT_INTR_TIMEOUT_MS);
+			WAIT_INTR_TIMEOUT_MS, 0);
 
 	if (ctx->irq_status & MTK_VDEC_IRQ_STATUS_DEC_SUCCESS)
 		return true;
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index bf03888a824f..4d9b8798dffe 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -335,7 +335,7 @@ static unsigned int h264_enc_wait_venc_done(struct venc_h264_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "irq_status %x <-", irq_status);
 	}
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 6b66957d5192..56ce58f761f1 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -222,7 +222,7 @@ static unsigned int vp8_enc_wait_venc_done(struct venc_vp8_inst *inst)
 	struct mtk_vcodec_ctx *ctx = (struct mtk_vcodec_ctx *)inst->ctx;
 
 	if (!mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
-					  WAIT_INTR_TIMEOUT_MS)) {
+					  WAIT_INTR_TIMEOUT_MS, 0)) {
 		irq_status = ctx->irq_status;
 		mtk_vcodec_debug(inst, "isr return %x", irq_status);
 	}
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:41 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:41 +0800
Subject: [PATCH v19,
 05/19] dt-bindings: media: mtk-vcodec: Separate video encoder and
 decoder dt-bindings
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-6-yunfei.dong@mediatek.com>

Separate decoder and encoder document for the dts are big difference.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../media/mediatek,vcodec-decoder.yaml        | 176 +++++++++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 187 ++++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 131 ------------
 3 files changed, 363 insertions(+), 131 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
new file mode 100644
index 000000000000..df1d677098fd
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -0,0 +1,176 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-decoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Decode Accelerator
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-dec
+      - mediatek,mt8183-vcodec-dec
+
+  reg:
+    maxItems: 12
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 8
+
+  clock-names:
+    items:
+      - const: vcodecpll
+      - const: univpll_d2
+      - const: clk_cci400_sel
+      - const: vdec_sel
+      - const: vdecpll
+      - const: vencpll
+      - const: venc_lt_sel
+      - const: vdec_bus_clk_src
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  assigned-clock-rates: true
+
+  power-domains:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-dec
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-dec
+
+    then:
+      required:
+        - mediatek,vpu
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt8173-power.h>
+
+    vcodec_dec: vcodec at 16000000 {
+      compatible = "mediatek,mt8173-vcodec-dec";
+      reg = <0x16000000 0x100>,   /*VDEC_SYS*/
+          <0x16020000 0x1000>,  /*VDEC_MISC*/
+          <0x16021000 0x800>,   /*VDEC_LD*/
+          <0x16021800 0x800>,   /*VDEC_TOP*/
+          <0x16022000 0x1000>,  /*VDEC_CM*/
+          <0x16023000 0x1000>,  /*VDEC_AD*/
+          <0x16024000 0x1000>,  /*VDEC_AV*/
+          <0x16025000 0x1000>,  /*VDEC_PP*/
+          <0x16026800 0x800>,   /*VP8_VD*/
+          <0x16027000 0x800>,   /*VP6_VD*/
+          <0x16027800 0x800>,   /*VP8_VL*/
+          <0x16028400 0x400>;   /*VP9_VD*/
+      interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
+      mediatek,larb = <&larb1>;
+      iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
+             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
+      mediatek,vpu = <&vpu>;
+      power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
+      clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
+             <&topckgen CLK_TOP_UNIVPLL_D2>,
+             <&topckgen CLK_TOP_CCI400_SEL>,
+             <&topckgen CLK_TOP_VDEC_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL>,
+             <&apmixedsys CLK_APMIXED_VENCPLL>,
+             <&topckgen CLK_TOP_VENC_LT_SEL>,
+             <&topckgen CLK_TOP_VCODECPLL_370P5>;
+      clock-names = "vcodecpll",
+                  "univpll_d2",
+                  "clk_cci400_sel",
+                  "vdec_sel",
+                  "vdecpll",
+                  "vencpll",
+                  "venc_lt_sel",
+                  "vdec_bus_clk_src";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
+                      <&topckgen CLK_TOP_CCI400_SEL>,
+                      <&topckgen CLK_TOP_VDEC_SEL>,
+                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
+                      <&apmixedsys CLK_APMIXED_VENCPLL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
+                             <&topckgen CLK_TOP_UNIVPLL_D2>,
+                             <&topckgen CLK_TOP_VCODECPLL>;
+      assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
new file mode 100644
index 000000000000..b72c1a50e89e
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,vcodec-encoder.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Video Encode Accelerator
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |+
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8173-vcodec-enc-vp8
+      - mediatek,mt8173-vcodec-enc
+      - mediatek,mt8183-vcodec-enc
+      - mediatek,mt8192-vcodec-enc
+      - mediatek,mt8195-vcodec-enc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 5
+
+  clock-names:
+    minItems: 1
+    maxItems: 5
+
+  assigned-clocks: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  mediatek,larb:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      Must contain the local arbiters in the current Socs.
+
+  mediatek,vpu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to vpu.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description:
+      Describes point to scp.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - iommus
+  - assigned-clocks
+  - assigned-clock-parents
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8183-vcodec-enc
+              - mediatek,mt8192-vcodec-enc
+
+    then:
+      required:
+        - mediatek,scp
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - mediatek,mt8173-vcodec-enc-vp8
+              - mediatek,mt8173-vcodec-enc
+
+    then:
+      required:
+        - mediatek,vpu
+
+  - if:
+      properties:
+        compatible:
+          enum:
+            - mediatek,mt8173-vcodec-enc
+            - mediatek,mt8192-vcodec-enc
+            - mediatek,mt8173-vcodec-enc
+
+    then:
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_sel
+    else:  # for vp8 hw decoder
+      properties:
+        clock:
+          items:
+            minItems: 1
+            maxItems: 1
+        clock-names:
+          items:
+            - const: venc_lt_sel
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/memory/mt8173-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    vcodec_enc_avc: vcodec at 18002000 {
+      compatible = "mediatek,mt8173-vcodec-enc";
+      reg = <0x18002000 0x1000>;
+      interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU>,
+             <&iommu M4U_PORT_VENC_REC>,
+             <&iommu M4U_PORT_VENC_BSDMA>,
+             <&iommu M4U_PORT_VENC_SV_COMV>,
+             <&iommu M4U_PORT_VENC_RD_COMV>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
+             <&iommu M4U_PORT_VENC_REF_LUMA>,
+             <&iommu M4U_PORT_VENC_REF_CHROMA>,
+             <&iommu M4U_PORT_VENC_NBM_RDMA>,
+             <&iommu M4U_PORT_VENC_NBM_WDMA>;
+      mediatek,larb = <&larb3>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      clock-names = "venc_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
+    };
+
+    vcodec_enc_vp8: vcodec at 19002000 {
+      compatible = "mediatek,mt8173-vcodec-enc-vp8";
+      reg =  <0x19002000 0x1000>;	/* VENC_LT_SYS */
+      interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
+      iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
+             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
+             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
+             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
+             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
+             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
+      mediatek,larb = <&larb5>;
+      mediatek,vpu = <&vpu>;
+      clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      clock-names = "venc_lt_sel";
+      assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt b/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
deleted file mode 100644
index 665a9508708e..000000000000
--- a/Documentation/devicetree/bindings/media/mediatek-vcodec.txt
+++ /dev/null
@@ -1,131 +0,0 @@
-Mediatek Video Codec
-
-Mediatek Video Codec is the video codec hw present in Mediatek SoCs which
-supports high resolution encoding and decoding functionalities.
-
-Required properties:
-- compatible : must be one of the following string:
-  "mediatek,mt8173-vcodec-enc-vp8" for mt8173 vp8 encoder.
-  "mediatek,mt8173-vcodec-enc" for mt8173 avc encoder.
-  "mediatek,mt8183-vcodec-enc" for MT8183 encoder.
-  "mediatek,mt8173-vcodec-dec" for MT8173 decoder.
-  "mediatek,mt8192-vcodec-enc" for MT8192 encoder.
-  "mediatek,mt8183-vcodec-dec" for MT8183 decoder.
-  "mediatek,mt8195-vcodec-enc" for MT8195 encoder.
-- reg : Physical base address of the video codec registers and length of
-  memory mapped region.
-- interrupts : interrupt number to the cpu.
-- mediatek,larb : must contain the local arbiters in the current Socs.
-- clocks : list of clock specifiers, corresponding to entries in
-  the clock-names property.
-- clock-names: avc encoder must contain "venc_sel", vp8 encoder must
-  contain "venc_lt_sel", decoder must contain "vcodecpll", "univpll_d2",
-  "clk_cci400_sel", "vdec_sel", "vdecpll", "vencpll", "venc_lt_sel",
-  "vdec_bus_clk_src".
-- iommus : should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-- dma-ranges : describes the dma address range space that the codec hw access.
-One of the two following nodes:
-- mediatek,vpu : the node of the video processor unit, if using VPU.
-- mediatek,scp : the node of the SCP unit, if using SCP.
-
-
-Example:
-
-vcodec_dec: vcodec at 16000000 {
-    compatible = "mediatek,mt8173-vcodec-dec";
-    reg = <0 0x16000000 0 0x100>,   /*VDEC_SYS*/
-          <0 0x16020000 0 0x1000>,  /*VDEC_MISC*/
-          <0 0x16021000 0 0x800>,   /*VDEC_LD*/
-          <0 0x16021800 0 0x800>,   /*VDEC_TOP*/
-          <0 0x16022000 0 0x1000>,  /*VDEC_CM*/
-          <0 0x16023000 0 0x1000>,  /*VDEC_AD*/
-          <0 0x16024000 0 0x1000>,  /*VDEC_AV*/
-          <0 0x16025000 0 0x1000>,  /*VDEC_PP*/
-          <0 0x16026800 0 0x800>,   /*VP8_VD*/
-          <0 0x16027000 0 0x800>,   /*VP6_VD*/
-          <0 0x16027800 0 0x800>,   /*VP8_VL*/
-          <0 0x16028400 0 0x400>;   /*VP9_VD*/
-    interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-    mediatek,larb = <&larb1>;
-    iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_RD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_PRED_WR_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_UFO_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD_EXT>,
-             <&iommu M4U_PORT_HW_VDEC_VLD2_EXT>;
-    mediatek,vpu = <&vpu>;
-    power-domains = <&scpsys MT8173_POWER_DOMAIN_VDEC>;
-    clocks = <&apmixedsys CLK_APMIXED_VCODECPLL>,
-             <&topckgen CLK_TOP_UNIVPLL_D2>,
-             <&topckgen CLK_TOP_CCI400_SEL>,
-             <&topckgen CLK_TOP_VDEC_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL>,
-             <&apmixedsys CLK_APMIXED_VENCPLL>,
-             <&topckgen CLK_TOP_VENC_LT_SEL>,
-             <&topckgen CLK_TOP_VCODECPLL_370P5>;
-    clock-names = "vcodecpll",
-                  "univpll_d2",
-                  "clk_cci400_sel",
-                  "vdec_sel",
-                  "vdecpll",
-                  "vencpll",
-                  "venc_lt_sel",
-                  "vdec_bus_clk_src";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>,
-                      <&topckgen CLK_TOP_CCI400_SEL>,
-                      <&topckgen CLK_TOP_VDEC_SEL>,
-                      <&apmixedsys CLK_APMIXED_VCODECPLL>,
-                      <&apmixedsys CLK_APMIXED_VENCPLL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>,
-                             <&topckgen CLK_TOP_UNIVPLL_D2>,
-                             <&topckgen CLK_TOP_VCODECPLL>;
-    assigned-clock-rates = <0>, <0>, <0>, <1482000000>, <800000000>;
-  };
-
-vcodec_enc_avc: vcodec at 18002000 {
-    compatible = "mediatek,mt8173-vcodec-enc";
-    reg = <0 0x18002000 0 0x1000>;
-    interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU>,
-             <&iommu M4U_PORT_VENC_REC>,
-             <&iommu M4U_PORT_VENC_BSDMA>,
-             <&iommu M4U_PORT_VENC_SV_COMV>,
-             <&iommu M4U_PORT_VENC_RD_COMV>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA>,
-             <&iommu M4U_PORT_VENC_REF_LUMA>,
-             <&iommu M4U_PORT_VENC_REF_CHROMA>,
-             <&iommu M4U_PORT_VENC_NBM_RDMA>,
-             <&iommu M4U_PORT_VENC_NBM_WDMA>;
-    mediatek,larb = <&larb3>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    clock-names = "venc_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL>;
-  };
-
-vcodec_enc_vp8: vcodec at 19002000 {
-    compatible = "mediatek,mt8173-vcodec-enc-vp8";
-    reg =  <0 0x19002000 0 0x1000>;	/* VENC_LT_SYS */
-    interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_LOW>;
-    iommus = <&iommu M4U_PORT_VENC_RCPU_SET2>,
-             <&iommu M4U_PORT_VENC_REC_FRM_SET2>,
-             <&iommu M4U_PORT_VENC_BSDMA_SET2>,
-             <&iommu M4U_PORT_VENC_SV_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_RD_COMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
-             <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
-             <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-    mediatek,larb = <&larb5>;
-    mediatek,vpu = <&vpu>;
-    clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    clock-names = "venc_lt_sel";
-    assigned-clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
-    assigned-clock-parents = <&topckgen CLK_TOP_VCODECPLL_370P5>;
-  };
-- 
2.25.1



From joel at jms.id.au  Wed Jan 12 20:12:16 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 13 Jan 2022 04:12:16 +0000
Subject: [PATCH v5 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <20220112230247.982212-6-iwona.winiarska@intel.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-6-iwona.winiarska@intel.com>
Message-ID: <CACPK8XewQJBvwssM6zQKQoxT=JLpk-qjGhsiTAa980OtbU7JBw@mail.gmail.com>

On Wed, 12 Jan 2022 at 23:06, Iwona Winiarska <iwona.winiarska at intel.com> wrote:
>
> From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
>
> ASPEED AST24xx/AST25xx/AST26xx SoCs support the PECI electrical
> interface (a.k.a PECI wire) that provides a communication channel with
> Intel processors.
> This driver allows BMC to discover devices connected to it and
> communicate with them using PECI protocol.
>
> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>

The driver looks good to me. I would be happy to see it merged in its
current state.

Reviewed-by: Joel Stanley <joel at jms.id.au>

I've a few questions below that can be followed up later if need be.

> +
> +static void aspeed_peci_init_regs(struct aspeed_peci *priv)
> +{
> +       u32 val;
> +
> +       /* Clear interrupts */
> +       val = readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK;

Should that be & MASK?

As you're just sanitising the registers, you could clear the status
unconditionally:

 writel(ASPEED_PECI_INT_MASK, priv->base + ASPEED_PECI_INT_STS);

> +       writel(val, priv->base + ASPEED_PECI_INT_STS);
> +
> +       /* Set timing negotiation mode and enable interrupts */
> +       val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK, ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);

That's a complicated way to set val to zero :)

> +       val |= ASPEED_PECI_INT_MASK;
> +       writel(val, priv->base + ASPEED_PECI_INT_CTRL);
> +
> +       val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT);
> +       writel(val, priv->base + ASPEED_PECI_CTRL);

This will clear the rest of the ctrl register, including the divisor
settings. Was that your intention?

Reading the rest of your driver you only call _init_regs after
_controller_enable, so I guess you're fine.

> +}
> +
> +static int aspeed_peci_check_idle(struct aspeed_peci *priv)
> +{
> +       u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
> +       int ret;
> +
> +       /*
> +        * Under normal circumstances, we expect to be idle here.
> +        * In case there were any errors/timeouts that led to the situation
> +        * where the hardware is not in idle state - we need to reset and
> +        * reinitialize it to avoid potential controller hang.
> +        */
> +       if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts)) {
> +               reset_control_assert(priv->rst);
> +
> +               ret = reset_control_deassert(priv->rst);
> +               if (ret) {
> +                       dev_err(priv->dev, "cannot deassert reset control\n");
> +                       return ret;
> +               }
> +
> +               aspeed_peci_init_regs(priv);
> +
> +               ret = clk_set_rate(priv->clk, priv->clk_frequency);
> +               if (ret < 0) {
> +                       dev_err(priv->dev, "cannot set clock frequency\n");
> +                       return ret;
> +               }
> +
> +               aspeed_peci_controller_enable(priv);
> +       }
> +
> +       return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
> +                                 cmd_sts,
> +                                 !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
> +                                 ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
> +                                 ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
> +}
> +
> +static int aspeed_peci_xfer(struct peci_controller *controller,
> +                           u8 addr, struct peci_request *req)
> +{
> +       struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
> +       unsigned long timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
> +       u32 peci_head;
> +       int ret;
> +
> +       if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> +           req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> +               return -EINVAL;
> +
> +       /* Check command sts and bus idle state */
> +       ret = aspeed_peci_check_idle(priv);
> +       if (ret)
> +               return ret; /* -ETIMEDOUT */
> +
> +       spin_lock_irq(&priv->lock);
> +       reinit_completion(&priv->xfer_complete);
> +
> +       peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> +                   FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> +                   FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> +
> +       writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> +
> +       memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf, min_t(u8, req->tx.len, 16));
> +       if (req->tx.len > 16)
> +               memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf + 16,
> +                           req->tx.len - 16);
> +
> +#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
> +       dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
> +       print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req->tx.len);
> +#endif

The ifdef is unfortunate. Could you do this?

dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG))
       print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf,
req->tx.len);

Not a biggie though, don't let this hold up merging.

> +       priv->status = 0;
> +       writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> +       spin_unlock_irq(&priv->lock);
> +


From yunfei.dong at mediatek.com  Wed Jan 12 20:10:51 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:51 +0800
Subject: [PATCH v19,
 15/19] media: mtk-vcodec: Support 34bits dma address for vdec
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-16-yunfei.dong@mediatek.com>

Use the dma_set_mask_and_coherent helper to set vdec
DMA bit mask to support 34bits iova space(16GB) that
the mt8192 iommu HW support.

Whole the iova range separate to 0~4G/4G~8G/8G~12G/12G~16G,
regarding which iova range VDEC actually locate, it
depends on the dma-ranges property of vdec dtsi node.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 1b67ed8f7f52..08d8e02559c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -323,6 +323,14 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL)) {
+		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+		if (ret) {
+			mtk_v4l2_err("Failed to set mask");
+			goto err_core_workq;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:53 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:53 +0800
Subject: [PATCH v19,
 17/19] media: mtk-vcodec: Use codec type to separate different
 hardware
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-18-yunfei.dong@mediatek.com>

There is just one core thread, in order to separate different
hardware, using codec type to separeate it in scp driver.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 12 ++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 34 ++++++++++++++++---
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  4 +++
 3 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 9d8079c4f976..bf54d6d9a857 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -35,6 +35,8 @@ enum vdec_ipi_msgid {
  * @msg_id	: vdec_ipi_msgid
  * @vpu_inst_addr : VPU decoder instance address. Used if ABI version < 2.
  * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @codec_type	: codec fourcc
+ * @reserved	: reserved param
  */
 struct vdec_ap_ipi_cmd {
 	uint32_t msg_id;
@@ -42,6 +44,8 @@ struct vdec_ap_ipi_cmd {
 		uint32_t vpu_inst_addr;
 		uint32_t inst_id;
 	};
+	u32 codec_type;
+	u32 reserved;
 };
 
 /**
@@ -59,12 +63,12 @@ struct vdec_vpu_ipi_ack {
 /**
  * struct vdec_ap_ipi_init - for AP_IPIMSG_DEC_INIT
  * @msg_id	: AP_IPIMSG_DEC_INIT
- * @reserved	: Reserved field
+ * @codec_type	: codec fourcc
  * @ap_inst_addr	: AP video decoder instance address
  */
 struct vdec_ap_ipi_init {
 	uint32_t msg_id;
-	uint32_t reserved;
+	u32 codec_type;
 	uint64_t ap_inst_addr;
 };
 
@@ -77,7 +81,7 @@ struct vdec_ap_ipi_init {
  *	H264 decoder [0]:buf_sz [1]:nal_start
  *	VP8 decoder  [0]:width/height
  *	VP9 decoder  [0]:profile, [1][2] width/height
- * @reserved	: Reserved field
+ * @codec_type	: codec fourcc
  */
 struct vdec_ap_ipi_dec_start {
 	uint32_t msg_id;
@@ -86,7 +90,7 @@ struct vdec_ap_ipi_dec_start {
 		uint32_t inst_id;
 	};
 	uint32_t data[3];
-	uint32_t reserved;
+	u32 codec_type;
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index bfd8e87dceff..dd35d2c5f920 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -100,18 +100,29 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 
 static int vcodec_vpu_send_msg(struct vdec_vpu_inst *vpu, void *msg, int len)
 {
-	int err;
+	int err, id, msgid;
 
-	mtk_vcodec_debug(vpu, "id=%X", *(uint32_t *)msg);
+	msgid = *(uint32_t *)msg;
+	mtk_vcodec_debug(vpu, "id=%X", msgid);
 
 	vpu->failure = 0;
 	vpu->signaled = 0;
 
-	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, vpu->id, msg,
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		if (msgid == AP_IPIMSG_DEC_CORE ||
+		    msgid == AP_IPIMSG_DEC_CORE_END)
+			id = vpu->core_id;
+		else
+			id = vpu->id;
+	} else {
+		id = vpu->id;
+	}
+
+	err = mtk_vcodec_fw_ipi_send(vpu->ctx->dev->fw_handler, id, msg,
 				     len, 2000);
 	if (err) {
 		mtk_vcodec_err(vpu, "send fail vpu_id=%d msg_id=%X status=%d",
-			       vpu->id, *(uint32_t *)msg, err);
+			       id, msgid, err);
 		return err;
 	}
 
@@ -131,6 +142,7 @@ static int vcodec_send_ap_ipi(struct vdec_vpu_inst *vpu, unsigned int msg_id)
 		msg.vpu_inst_addr = vpu->inst_addr;
 	else
 		msg.inst_id = vpu->inst_id;
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, &msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- id=%X ret=%d", msg_id, err);
@@ -149,14 +161,25 @@ int vpu_dec_init(struct vdec_vpu_inst *vpu)
 
 	err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler, vpu->id,
 					 vpu->handler, "vdec", NULL);
-	if (err != 0) {
+	if (err) {
 		mtk_vcodec_err(vpu, "vpu_ipi_register fail status=%d", err);
 		return err;
 	}
 
+	if (vpu->ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_LAT_SINGLE_CORE) {
+		err = mtk_vcodec_fw_ipi_register(vpu->ctx->dev->fw_handler,
+						 vpu->core_id, vpu->handler,
+						 "vdec", NULL);
+		if (err) {
+			mtk_vcodec_err(vpu, "vpu_ipi_register core fail status=%d", err);
+			return err;
+		}
+	}
+
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_id = AP_IPIMSG_DEC_INIT;
 	msg.ap_inst_addr = (unsigned long)vpu;
+	msg.codec_type = vpu->codec_type;
 
 	mtk_vcodec_debug(vpu, "vdec_inst=%p", vpu);
 
@@ -187,6 +210,7 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 
 	for (i = 0; i < len; i++)
 		msg.data[i] = data[i];
+	msg.codec_type = vpu->codec_type;
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
 	mtk_vcodec_debug(vpu, "- ret=%d", err);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index ae24b75d1649..4cb3c7f5a3ad 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -14,6 +14,7 @@ struct mtk_vcodec_ctx;
 /**
  * struct vdec_vpu_inst - VPU instance for video codec
  * @id          : ipi msg id for each decoder
+ * @core_id     : core id used to separate different hardware
  * @vsi         : driver structure allocated by VPU side and shared to AP side
  *                for control and info share
  * @failure     : VPU execution result status, 0: success, others: fail
@@ -26,9 +27,11 @@ struct mtk_vcodec_ctx;
  * @dev		: platform device of VPU
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
+ * @codec_type     : use codec type to separate different codecs
  */
 struct vdec_vpu_inst {
 	int id;
+	int core_id;
 	void *vsi;
 	int32_t failure;
 	uint32_t inst_addr;
@@ -38,6 +41,7 @@ struct vdec_vpu_inst {
 	struct mtk_vcodec_ctx *ctx;
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
+	unsigned int codec_type;
 };
 
 /**
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:48 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:48 +0800
Subject: [PATCH v19,
 12/19] media: mtk-vcodec: Generalize power and clock on/off interfaces
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-13-yunfei.dong@mediatek.com>

Generalizes power and clock on/off interfaces to support different
hardware.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  2 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 76 +++++++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  8 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     | 59 +++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   | 21 ++---
 9 files changed, 146 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 40d1f16a0a25..ffc4ba698876 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -46,7 +46,7 @@ static irqreturn_t mtk_vcodec_dec_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev, MTK_VDEC_CORE);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[0]);
@@ -193,7 +193,7 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(&dev->pm);
+		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
 		if (ret < 0)
 			goto err_load_fw;
 		/*
@@ -253,7 +253,7 @@ static int fops_vcodec_release(struct file *file)
 	mtk_vcodec_dec_release(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(&dev->pm);
+		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 6b248dd94dd3..f2f5d8869c70 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -65,7 +65,7 @@ static irqreturn_t mtk_vdec_hw_irq_handler(int irq, void *priv)
 	void __iomem *vdec_misc_addr = dev->reg_base[VDEC_HW_MISC] +
 					VDEC_IRQ_CFG_REG;
 
-	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev);
+	ctx = mtk_vcodec_get_curr_ctx(dev->main_dev, dev->hw_idx);
 
 	/* check if HW active or not */
 	cg_status = readl(dev->reg_base[VDEC_HW_SYS]);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index 5c2cfeaa9d9f..a63e4b1b81c3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -35,6 +35,8 @@ enum mtk_vdec_hw_reg_idx {
  * @main_dev: main device
  * @reg_base: mapped address of MTK Vcodec registers.
  *
+ * @curr_ctx: the context that is waiting for codec hardware
+ *
  * @dec_irq : decoder irq resource
  * @pm      : power management control
  * @hw_idx  : each hardware index
@@ -44,6 +46,8 @@ struct mtk_vdec_hw_dev {
 	struct mtk_vcodec_dev *main_dev;
 	void __iomem *reg_base[VDEC_HW_MAX];
 
+	struct mtk_vcodec_ctx *curr_ctx;
+
 	int dec_irq;
 	struct mtk_vcodec_pm pm;
 	int hw_idx;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 64535d33bff8..f5b1e1aab301 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -5,11 +5,13 @@
  */
 
 #include <linux/clk.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -85,10 +87,23 @@ void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return -EINVAL;
+		}
+		pm = &subdev_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
@@ -97,21 +112,50 @@ int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
 	int ret;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+	} else {
+		pm = &vdec_dev->pm;
+	}
+
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int ret, i = 0;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int ret, i;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+		enable_irq(subdev_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		enable_irq(vdec_dev->dec_irq);
+	}
 
+	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
 		if (ret) {
@@ -134,11 +178,27 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
-	struct mtk_vcodec_clk *dec_clk = &pm->vdec_clk;
-	int i = 0;
+	struct mtk_vdec_hw_dev *subdev_dev;
+	struct mtk_vcodec_pm *pm;
+	struct mtk_vcodec_clk *dec_clk;
+	int i;
 
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev\n");
+			return;
+		}
+		pm = &subdev_dev->pm;
+		disable_irq(subdev_dev->dec_irq);
+	} else {
+		pm = &vdec_dev->pm;
+		disable_irq(vdec_dev->dec_irq);
+	}
+
+	dec_clk = &pm->vdec_clk;
 	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 08769c7648eb..ff979d384f4c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -12,9 +12,9 @@
 int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
 void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c9a377035e80..4d3fd2a7a56e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -284,6 +284,7 @@ struct vdec_pic_info {
  * @decoded_frame_cnt: number of decoded frames
  * @lock: protect variables accessed by V4L2 threads and worker thread such as
  *	  mtk_video_dec_buf.
+ * @hw_id: hardware index used to identify different hardware.
  *
  * @msg_queue: msg queue used to store lat buffer information.
  */
@@ -328,6 +329,7 @@ struct mtk_vcodec_ctx {
 
 	int decoded_frame_cnt;
 	struct mutex lock;
+	int hw_id;
 
 	struct vdec_msg_queue msg_queue;
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index 5bac820a47fc..ace78c4b5b9e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -6,7 +6,10 @@
 */
 
 #include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
+#include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
 
@@ -71,25 +74,59 @@ void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_mem_free);
 
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx)
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx)
 {
-	unsigned long flags;
+	if (hw_idx >= MTK_VDEC_HW_MAX || hw_idx < 0 || !dev->subdev_dev[hw_idx]) {
+		mtk_v4l2_err("hw idx is out of range:%d", hw_idx);
+		return NULL;
+	}
+
+	return dev->subdev_dev[hw_idx];
+}
+EXPORT_SYMBOL(mtk_vcodec_get_hw_dev);
 
-	spin_lock_irqsave(&dev->irqlock, flags);
-	dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+			     struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	unsigned long flags;
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return;
+		}
+		subdev_dev->curr_ctx = ctx;
+	} else {
+		vdec_dev->curr_ctx = ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 }
 EXPORT_SYMBOL(mtk_vcodec_set_curr_ctx);
 
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev)
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+					       unsigned int hw_idx)
 {
 	unsigned long flags;
 	struct mtk_vcodec_ctx *ctx;
-
-	spin_lock_irqsave(&dev->irqlock, flags);
-	ctx = dev->curr_ctx;
-	spin_unlock_irqrestore(&dev->irqlock, flags);
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	spin_lock_irqsave(&vdec_dev->irqlock, flags);
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (!subdev_dev) {
+			mtk_v4l2_err("Failed to get hw dev");
+			spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
+			return NULL;
+		}
+		ctx = subdev_dev->curr_ctx;
+	} else {
+		ctx = vdec_dev->curr_ctx;
+	}
+	spin_unlock_irqrestore(&vdec_dev->irqlock, flags);
 	return ctx;
 }
 EXPORT_SYMBOL(mtk_vcodec_get_curr_ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 87c3d6d4bfa7..71956627a0e2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -54,8 +54,10 @@ int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
-void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *dev,
-	struct mtk_vcodec_ctx *ctx);
-struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *dev);
+void mtk_vcodec_set_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+			     struct mtk_vcodec_ctx *ctx, int hw_idx);
+struct mtk_vcodec_ctx *mtk_vcodec_get_curr_ctx(struct mtk_vcodec_dev *vdec_dev,
+					       unsigned int hw_idx);
+void *mtk_vcodec_get_hw_dev(struct mtk_vcodec_dev *dev, int hw_idx);
 
 #endif /* _MTK_VCODEC_UTIL_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 42008243ceac..05a5b240e906 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -24,21 +24,24 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	case V4L2_PIX_FMT_VP9:
 		ctx->dec_if = &vdec_vp9_if;
+		ctx->hw_id = MTK_VDEC_CORE;
 		break;
 	default:
 		return -EINVAL;
 	}
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	return ret;
@@ -69,13 +72,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 
 	mtk_vdec_lock(ctx);
 
-	mtk_vcodec_set_curr_ctx(ctx->dev, ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
-	enable_irq(ctx->dev->dec_irq);
+	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	disable_irq(ctx->dev->dec_irq);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
-	mtk_vcodec_set_curr_ctx(ctx->dev, NULL);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
+	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
 
 	mtk_vdec_unlock(ctx);
 
@@ -103,9 +104,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return;
 
 	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(&ctx->dev->pm);
+	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vdec_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:54 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:54 +0800
Subject: [PATCH v19, 18/19] media: mtk-vcodec: Remove mtk_vcodec_release_dec_pm
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-19-yunfei.dong@mediatek.com>

There are only two lines in mtk_vcodec_release_dec_pm, using
pm_runtime_disable and put_device instead directly.

Move pm_runtime_enable outside mtk_vcodec_init_dec_pm to symmetry with
pm_runtime_disable, after that, rename mtk_vcodec_init_dec_pm to *_clk
since it only has clock operations now.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c   | 10 +++++++---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c    |  7 +++++--
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c    | 12 ++----------
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h    |  3 +--
 4 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 08d8e02559c6..86b639d82be8 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
@@ -128,12 +129,13 @@ static int mtk_vcodec_init_dec_resources(struct mtk_vcodec_dev *dev)
 		return ret;
 	}
 
-	ret = mtk_vcodec_init_dec_pm(pdev, &dev->pm);
+	ret = mtk_vcodec_init_dec_clk(pdev, &dev->pm);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed to get mt vcodec clock source");
 		return ret;
 	}
 
+	pm_runtime_enable(&pdev->dev);
 	return 0;
 }
 
@@ -447,7 +449,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
 		destroy_workqueue(dev->core_workqueue);
 err_res:
-	mtk_vcodec_release_dec_pm(&dev->pm);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvdec);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -490,7 +493,8 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_dec);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_dec_pm(&dev->pm);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvdec);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index f2f5d8869c70..7b5da3e4cac2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -9,6 +9,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "mtk_vcodec_drv.h"
@@ -140,9 +141,10 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	subdev_dev->plat_dev = pdev;
-	ret = mtk_vcodec_init_dec_pm(pdev, &subdev_dev->pm);
+	ret = mtk_vcodec_init_dec_clk(pdev, &subdev_dev->pm);
 	if (ret)
 		return ret;
+	pm_runtime_enable(&pdev->dev);
 
 	of_id = of_match_device(mtk_vdec_hw_match, dev);
 	if (!of_id) {
@@ -181,7 +183,8 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, subdev_dev);
 	return 0;
 err:
-	mtk_vcodec_release_dec_pm(&subdev_dev->pm);
+	pm_runtime_disable(subdev_dev->pm.dev);
+	put_device(subdev_dev->pm.larbvdec);
 	return ret;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index f5b1e1aab301..44035a50e335 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -15,7 +15,7 @@
 #include "mtk_vcodec_dec_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *pm)
+int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
 	struct platform_device *larb_pdev;
@@ -72,20 +72,12 @@ int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *p
 		}
 	}
 
-	pm_runtime_enable(&pdev->dev);
 	return 0;
 put_device:
 	put_device(pm->larbvdec);
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_pm);
-
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm)
-{
-	pm_runtime_disable(pm->dev);
-	put_device(pm->larbvdec);
-}
-EXPORT_SYMBOL_GPL(mtk_vcodec_release_dec_pm);
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index ff979d384f4c..3cc721bbfaf6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -9,8 +9,7 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_dec_pm(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
-void mtk_vcodec_release_dec_pm(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
 
 int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
 void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:42 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:42 +0800
Subject: [PATCH v19,
 06/19] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8192
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-7-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../media/mediatek,vcodec-subdev-decoder.yaml | 265 ++++++++++++++++++
 1 file changed, 265 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
new file mode 100644
index 000000000000..d587fc3e39fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -0,0 +1,265 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/mediatek,vcodec-subdev-decoder.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Video Decode Accelerator With Multi Hardware
+
+maintainers:
+  - Yunfei Dong <yunfei.dong at mediatek.com>
+
+description: |
+  Mediatek Video Decode is the video decode hardware present in Mediatek
+  SoCs which supports high resolution decoding functionalities. Required
+  parent and child device node.
+
+  About the Decoder Hardware Block Diagram, please check below:
+
+    +---------------------------------+------------------------------------+
+    |                                 |                                    |
+    | input -> lat HW -> lat buffer --|--> lat buffer -> core HW -> output |
+    |            ||                   |                     ||             |
+    +------------||-------------------+---------------------||-------------+
+              lat workqueue           |              core workqueue     <parent>
+    -------------||-----------------------------------------||------------------
+                 ||                                         ||          <child>
+                 \/ <----------------HW index-------------->\/
+           +------------------------------------------------------+
+           |                    enable/disable                    |
+           |           clk     power    irq    iommu              |
+           |                 (lat/lat soc/core0/core1)            |
+           +------------------------------------------------------+
+
+  As above, there are parent and child devices, child mean each hardware. The child device
+  controls the information of each hardware independent which include clk/power/irq.
+
+  There are two workqueues in parent device: lat workqueue and core workqueue. They are used
+  to lat and core hardware deocder. Lat workqueue need to get input bitstream and lat buffer,
+  then enable lat to decode, writing the result to lat buffer, dislabe hardware when lat decode
+  done. Core workqueue need to get lat buffer and output buffer, then enable core to decode,
+  writing the result to output buffer, disable hardware when core decode done. These two
+  hardwares will decode each frame cyclically.
+
+  For the smi common may not the same for each hardware, can't combine all hardware in one node,
+  or leading to iommu fault when access dram data.
+
+properties:
+  compatible:
+    const: mediatek,mt8192-vcodec-dec
+
+  reg:
+    maxItems: 1
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+# Required child node:
+patternProperties:
+  '^vcodec-lat@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-lat
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - interrupts
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+  '^vcodec-core@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-core
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - interrupts
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - iommus
+  - mediatek,scp
+  - dma-ranges
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8192-larb-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8192-clk.h>
+    #include <dt-bindings/power/mt8192-power.h>
+
+    video-codec at 16000000 {
+        compatible = "mediatek,mt8192-vcodec-dec";
+        mediatek,scp = <&scp>;
+        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0 0x16000000 0x40000>;
+        reg = <0x16000000 0x1000>;		/* VDEC_SYS */
+        vcodec-lat at 10000 {
+            compatible = "mediatek,mtk-vcodec-lat";
+            reg = <0x10000 0x800>;
+            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
+                <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
+                <&vdecsys_soc CLK_VDEC_SOC_LAT>,
+                <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
+                <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
+        };
+
+        vcodec-core at 25000 {
+            compatible = "mediatek,mtk-vcodec-core";
+            reg = <0x25000 0x1000>;
+            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
+            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
+                <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
+            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
+                <&vdecsys CLK_VDEC_VDEC>,
+                <&vdecsys CLK_VDEC_LAT>,
+                <&vdecsys CLK_VDEC_LARB1>,
+                <&topckgen CLK_TOP_MAINPLL_D4>;
+            clock-names = "sel", "soc-vdec", "soc-lat", "vdec", "top";
+            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
+            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
+            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
+        };
+    };
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:36 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:36 +0800
Subject: [PATCH v19,
 00/19] Support multi hardware decode using of_platform_populate
Message-ID: <20220113041055.25213-1-yunfei.dong@mediatek.com>

This series adds support for multi hardware decode into mtk-vcodec, by first adding use
of_platform_populate to manage each hardware information: interrupt, clock, register
bases and power. Secondly add core work queue to deal with core hardware message,
at the same time, add msg queue for different hardware share messages. Lastly, the
architecture of different specs are not the same, using specs type to separate them.

This series has been tested with both MT8183 and MT8173. Decoding was working for both chips.

Patches 1~3 rewrite get register bases and power on/off interface.
Patches 4 export decoder pm interfaces.
Patches 5 separate video encoder and decoder document
Patches 6 add 8192 document
Patches 7 add to support 8192.
Patch 8 support multi hardware.
Patch 9-17 add interfaces to support core hardware.
Patch 18-19 remove mtk_vcodec_release_dec/enc_pm interfaces.
---
changes compared with v18:
- fix checkpatch fail.
	all file's maintainer still the same.
- for patch 5 is separated video decoder and encoder document to different yaml fils.

changes compared with v17:
- fix checkpatch fail.
- fix kernel-doc fail
- fix smatch fail.

changes compared with v16:
- fix build warning for patch 13.

changes compared with v15:
- add Reviewed-by for patch 10.

changes compared with v14:
- rebase to latest media stage.

changes compared with v13:
- change some function position in case of ko dependency for patch 15.
- add reviewed-by for patch 06/13/15.

changes compared with v12:
- fix comments from rob for patch 15.
- fix comments from steve for 06 and 13.

changes compared with v11:
- fix comments from AngeloGioacchino for patch 09~11/19.
- fix comments from steve for patch 03/19.

changes compared with v10:
- fix comments from tzung-bi for patch 06/19.
- add more detail information for hardware block diagram 15/19

changes compared with v9:
- need not to build ko, just export pm interfaces for patch 04/19.
- fix comments for patch 06/19

changes compared with v8:
- add new patch 18~19 to remove mtk_vcodec_release_de/enc_pm interfaces.
- fix spelling mistakes for patch 17/19
- fix yaml comments for patch 15/19

Changes compared with v7:
- add new patch 4 to build decoder pm file as module
- add new patch 5 to support 8192
- fix comments for patch 6/17
- change some logic for using work queue instead of create thread for core hardware decode for patch 10/17
- using work queue for hardware decode instead of create thread for patch 13/17
- add returen value for patch 14/17
- fix yaml check fail 15/17

Changes compared with v6:
- Use of_platform_populate to manage multi hardware, not component framework for patch 4/15
- Re-write dtsi document for hardware architecture changed for patch 13/15 -The dtsi will write like below in patch 13/15:
    vcodec_dec: vcodec_dec at 16000000 {
        compatible = "mediatek,mt8192-vcodec-dec";
        #address-cells = <2>;
        #size-cells = <2>;
        ranges;
        reg = <0 0x16000000 0 0x1000>;		/* VDEC_SYS */
        mediatek,scp = <&scp>;
        iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>;
        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
        vcodec_lat {
            compatible = "mediatek,mtk-vcodec-lat";
            reg = <0 0x16010000 0 0x800>;		/* VDEC_MISC */
            reg-name = "reg-misc";
            interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_TILE_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_WDMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_LAT0_RG_CTRL_DMA_EXT>,
                 <&iommu0 M4U_PORT_L5_VDEC_UFO_ENC_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys_soc CLK_VDEC_SOC_VDEC>,
                 <&vdecsys_soc CLK_VDEC_SOC_LAT>,
                 <&vdecsys_soc CLK_VDEC_SOC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC>;
        };

        vcodec_core {
            compatible = "mediatek,mtk-vcodec-core";
            reg = <0 0x16025000 0 0x1000>;		/* VDEC_CORE_MISC */
            reg-names = "reg-misc";
            interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>;
            iommus = <&iommu0 M4U_PORT_L4_VDEC_MC_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_UFO_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_RD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PRED_WR_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_PPWRAP_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_TILE_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_VLD2_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_AVC_MV_EXT>,
                 <&iommu0 M4U_PORT_L4_VDEC_RG_CTRL_DMA_EXT>;
            clocks = <&topckgen CLK_TOP_VDEC_SEL>,
                 <&vdecsys CLK_VDEC_VDEC>,
                 <&vdecsys CLK_VDEC_LAT>,
                 <&vdecsys CLK_VDEC_LARB1>,
                 <&topckgen CLK_TOP_MAINPLL_D4>;
            clock-names = "vdec-sel", "vdec-soc-vdec", "vdec-soc-lat",
                  "vdec-vdec", "vdec-top";
            assigned-clocks = <&topckgen CLK_TOP_VDEC_SEL>;
            assigned-clock-parents = <&topckgen CLK_TOP_MAINPLL_D4>;
            power-domains = <&spm MT8192_POWER_DOMAIN_VDEC2>;
        };
    };

Changes compared with v5:
- Add decoder hardware block diagram for patch 13/15

Changes compared with v4:
- Fix comments for patch 4/15
  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  Fix platform_set_drvdata.
- Fix build error for patch 9/15
- Add depend patch in case of error header file for patch 13/15

Changes compared with v3:
- Fix return value for patch 1/15
- Fix comments for patch 4/15
  > Looking up "mediatek,mtk-vcodec-core" to determine if it uses component framwork sounds like...
  Add prameter in pdata, for all platform will use compoent after mt8183

  >> +     if (dev->is_comp_supported) {
  >> +             ret = mtk_vcodec_init_master(dev);
  >> +             if (ret < 0)
  >> +                     goto err_component_match;
  >> +     } else {
  >> +             platform_set_drvdata(pdev, dev);
  >> +     }
  > + Has asked the same question in [1].  Why it removes the
  > +platform_set_drvdata() above?  mtk_vcodec_init_master() also calls platform_set_drvdata().
  Must call component_master_add_with_match after platform_set_drvdata for component architecture.
- Fix yaml files check fail for patch 5/15
- Fix yaml file check fail for patch 14/15

Changes compared with v1:
- Fix many comments for patch 3/14
- Remove unnecessary code for patch 4/14
- Using enum mtk_vdec_hw_count instead of magic numbers for patch 6/14
- Reconstructed get/put lat buffer for lat and core hardware for patch 7/14
- Using yaml format to instead of txt file for patch 12/14

Yunfei Dong (19):
  media: mtk-vcodec: Get numbers of register bases from DT
  media: mtk-vcodec: Align vcodec wake up interrupt interface
  media: mtk-vcodec: Refactor vcodec pm interface
  media: mtk-vcodec: export decoder pm functions
  dt-bindings: media: mtk-vcodec: Separate video encoder and decoder
    dt-bindings
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8192
  media: mtk-vcodec: Support MT8192
  media: mtk-vcodec: Add to support multi hardware decode
  media: mtk-vcodec: Use pure single core for MT8183
  media: mtk-vcodec: Add irq interface for multi hardware
  media: mtk-vcodec: Add msg queue feature for lat and core architecture
  media: mtk-vcodec: Generalize power and clock on/off interfaces
  media: mtk-vcodec: Add new interface to lock different hardware
  media: mtk-vcodec: Add work queue for core hardware decode
  media: mtk-vcodec: Support 34bits dma address for vdec
  media: mtk-vcodec: Add core dec and dec end ipi msg
  media: mtk-vcodec: Use codec type to separate different hardware
  media: mtk-vcodec: Remove mtk_vcodec_release_dec_pm
  media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm

 .../media/mediatek,vcodec-decoder.yaml        | 176 +++++++++++
 .../media/mediatek,vcodec-encoder.yaml        | 187 +++++++++++
 .../media/mediatek,vcodec-subdev-decoder.yaml | 265 ++++++++++++++++
 .../bindings/media/mediatek-vcodec.txt        | 131 --------
 drivers/media/platform/mtk-vcodec/Makefile    |   6 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 178 ++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 201 ++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  56 ++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 105 +++++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |  11 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   2 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  21 ++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  74 ++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  21 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   |  10 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |   3 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.c     |  30 +-
 .../platform/mtk-vcodec/mtk_vcodec_intr.h     |   5 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  59 +++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   8 +-
 .../platform/mtk-vcodec/vdec/vdec_h264_if.c   |   2 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp8_if.c    |   2 +-
 .../platform/mtk-vcodec/vdec/vdec_vp9_if.c    |   2 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  21 +-
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |  16 +-
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 290 ++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      | 153 +++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  46 ++-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |  22 ++
 .../platform/mtk-vcodec/venc/venc_h264_if.c   |   2 +-
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   2 +-
 34 files changed, 1818 insertions(+), 296 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-vcodec.txt
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec_msg_queue.h

-- 
2.25.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:43 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:43 +0000
Subject: [PATCH 0/3] arm64: dts: meson: minor P212/VIM1 fixups
Message-ID: <20220113041746.16040-1-christianshewitt@gmail.com>

The P212 (S905X reference board) dts is used with a number of no-name
Android boxes that follow the reference design, and users had noticed
that BT worked but WiFi did not. While investigating and adding the
missing WiFi bits to the dtsi for testing I spotted that VIM1 inherits
from the p212 dtsi and has the BT node duplicated, so we can clean that
up too. And since we're tidying things, the pwm_ef node can be moved
to maintain normal alpha sorting.

Christian Hewitt (3):
  arm64: dts: meson: add Broadcom WiFi to P212 dtsi
  arm64: dts: meson: move pwm_ef node in P212 dtsi
  arm64: dts: meson: remove Broadcom WiFi/BT nodes from Khadas VIM1

 .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 ---------------
 .../dts/amlogic/meson-gxl-s905x-p212.dtsi     | 23 +++++++++++--------
 2 files changed, 14 insertions(+), 28 deletions(-)

-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:44 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:44 +0000
Subject: [PATCH 1/3] arm64: dts: meson: add Broadcom WiFi to P212 dtsi
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-2-christianshewitt@gmail.com>

The P212 has a combined WiFi/BT module. The BT side is already enabled
in the dtsi but the WiFi side is not. Let's tweak SDIO speed (in-line
with other GXL/GXM devices) and enable the WiFi module.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index 05cb2f5e5c36..c635e5858929 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -113,7 +113,7 @@
 
 	bus-width = <4>;
 	cap-sd-highspeed;
-	max-frequency = <50000000>;
+	max-frequency = <100000000>;
 
 	non-removable;
 	disable-wp;
@@ -125,6 +125,11 @@
 
 	vmmc-supply = <&vddao_3v3>;
 	vqmmc-supply = <&vddio_boot>;
+
+	brcmf: wifi at 1 {
+		reg = <1>;
+		compatible = "brcm,bcm4329-fmac";
+	};
 };
 
 /* SD card */
-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:45 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:45 +0000
Subject: [PATCH 2/3] arm64: dts: meson: move pwm_ef node in P212 dtsi
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-3-christianshewitt@gmail.com>

Cosmetic-only change to move/alpha-sort the node.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi   | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
index c635e5858929..b3d7b8613d6d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
@@ -97,6 +97,14 @@
 	pinctrl-names = "default";
 };
 
+&pwm_ef {
+	status = "okay";
+	pinctrl-0 = <&pwm_e_pins>;
+	pinctrl-names = "default";
+	clocks = <&clkc CLKID_FCLK_DIV4>;
+	clock-names = "clkin0";
+};
+
 &saradc {
 	status = "okay";
 	vref-supply = <&vddio_ao18>;
@@ -170,14 +178,6 @@
 	vqmmc-supply = <&vddio_boot>;
 };
 
-&pwm_ef {
-	status = "okay";
-	pinctrl-0 = <&pwm_e_pins>;
-	pinctrl-names = "default";
-	clocks = <&clkc CLKID_FCLK_DIV4>;
-	clock-names = "clkin0";
-};
-
 /* This is connected to the Bluetooth module: */
 &uart_A {
 	status = "okay";
-- 
2.17.1



From christianshewitt at gmail.com  Wed Jan 12 20:17:46 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:17:46 +0000
Subject: [PATCH 3/3] arm64: dts: meson: remove Broadcom WiFi/BT nodes from
 Khadas VIM1
In-Reply-To: <20220113041746.16040-1-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
Message-ID: <20220113041746.16040-4-christianshewitt@gmail.com>

The Broadcom WiFi/BT SDIO nodes are now inherited from the P212 common dtsi
so we can remove them from the VIM1 board dts.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 -------------------
 1 file changed, 19 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
index 6ab1cc125b96..108232a5aa2e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
@@ -217,25 +217,6 @@
 	pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
 };
 
-&sd_emmc_a {
-	max-frequency = <100000000>;
-
-	brcmf: wifi at 1 {
-		reg = <1>;
-		compatible = "brcm,bcm4329-fmac";
-	};
-};
-
-&uart_A {
-	bluetooth {
-		compatible = "brcm,bcm43438-bt";
-		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
-		max-speed = <2000000>;
-		clocks = <&wifi32k>;
-		clock-names = "lpo";
-	};
-};
-
 /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
 &uart_AO {
 	status = "okay";
-- 
2.17.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:50 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:50 +0800
Subject: [PATCH v19,
 14/19] media: mtk-vcodec: Add work queue for core hardware decode
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-15-yunfei.dong@mediatek.com>

Add work queue to process core hardware information.
First, get lat_buf from message queue, then call core
hardware of each codec(H264/VP9/AV1) to decode, finally
puts lat_buf back to the message.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Steve Cho <stevecho at chromium.org>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 17 +++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 ++
 .../platform/mtk-vcodec/vdec_msg_queue.c      | 32 +++++++++++++++++++
 .../platform/mtk-vcodec/vdec_msg_queue.h      |  2 ++
 4 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index d592104023d9..1b67ed8f7f52 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -311,6 +311,18 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_dec_pm;
 	}
 
+	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch)) {
+		vdec_msg_queue_init_ctx(&dev->msg_queue_core_ctx, MTK_VDEC_CORE);
+		dev->core_workqueue =
+			alloc_ordered_workqueue("core-decoder",
+						WQ_MEM_RECLAIM | WQ_FREEZABLE);
+		if (!dev->core_workqueue) {
+			mtk_v4l2_err("Failed to create core workqueue");
+			ret = -EINVAL;
+			goto err_res;
+		}
+	}
+
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
@@ -322,7 +334,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
 	if (ret) {
 		mtk_v4l2_err("v4l2_device_register err=%d", ret);
-		goto err_res;
+		goto err_core_workq;
 	}
 
 	init_waitqueue_head(&dev->queue);
@@ -423,6 +435,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	video_unregister_device(vfd_dec);
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
+err_core_workq:
+	if (IS_VDEC_LAT_ARCH(dev->vdec_pdata->hw_arch))
+		destroy_workqueue(dev->core_workqueue);
 err_res:
 	mtk_vcodec_release_dec_pm(&dev->pm);
 err_dec_pm:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cefac0262426..94b47b7c912b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -27,6 +27,7 @@
 #define MTK_VCODEC_MAX_PLANES	3
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
+#define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -464,6 +465,7 @@ struct mtk_vcodec_enc_pdata {
  * @dec_capability: used to identify decode capability, ex: 4k
  * @enc_capability: used to identify encode capability
  *
+ * @core_workqueue: queue used for core hardware decode
  * @msg_queue_core_ctx: msg queue context used for core workqueue
  *
  * @subdev_dev: subdev hardware device
@@ -508,6 +510,7 @@ struct mtk_vcodec_dev {
 	unsigned int dec_capability;
 	unsigned int enc_capability;
 
+	struct workqueue_struct *core_workqueue;
 	struct vdec_msg_queue_ctx msg_queue_core_ctx;
 
 	void *subdev_dev[MTK_VDEC_HW_MAX];
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index d0276b32a6b6..4b062a8128b4 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -68,6 +68,9 @@ int vdec_msg_queue_qbuf(struct vdec_msg_queue_ctx *msg_ctx, struct vdec_lat_buf
 
 	if (msg_ctx->hardware_index != MTK_VDEC_CORE)
 		wake_up_all(&msg_ctx->ready_to_use);
+	else
+		queue_work(buf->ctx->dev->core_workqueue,
+			   &buf->ctx->msg_queue.core_work);
 
 	mtk_v4l2_debug(3, "enqueue buf type: %d addr: 0x%p num: %d",
 		       msg_ctx->hardware_index, buf, msg_ctx->ready_num);
@@ -195,6 +198,34 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue,
 	}
 }
 
+static void vdec_msg_queue_core_work(struct work_struct *work)
+{
+	struct vdec_msg_queue *msg_queue =
+		container_of(work, struct vdec_msg_queue, core_work);
+	struct mtk_vcodec_ctx *ctx =
+		container_of(msg_queue, struct mtk_vcodec_ctx, msg_queue);
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	struct vdec_lat_buf *lat_buf;
+
+	lat_buf = vdec_msg_queue_dqbuf(&dev->msg_queue_core_ctx);
+	if (!lat_buf)
+		return;
+
+	ctx = lat_buf->ctx;
+	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
+
+	lat_buf->core_decode(lat_buf);
+
+	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
+
+	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
+		mtk_v4l2_debug(3, "re-schedule to decode for core: %d",
+			       dev->msg_queue_core_ctx.ready_num);
+		queue_work(dev->core_workqueue, &msg_queue->core_work);
+	}
+}
+
 int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
 			struct mtk_vcodec_ctx *ctx, core_decode_cb_t core_decode,
 			int private_size)
@@ -207,6 +238,7 @@ int vdec_msg_queue_init(struct vdec_msg_queue *msg_queue,
 		return 0;
 
 	vdec_msg_queue_init_ctx(&msg_queue->lat_ctx, MTK_VDEC_LAT0);
+	INIT_WORK(&msg_queue->core_work, vdec_msg_queue_core_work);
 	msg_queue->wdma_addr.size =
 		vde_msg_queue_get_trans_size(ctx->picinfo.buf_w,
 					     ctx->picinfo.buf_h);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
index 7096b77a456c..b6ba66d3e026 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.h
@@ -68,6 +68,7 @@ struct vdec_lat_buf {
  * @wdma_addr: wdma address used for ube
  * @wdma_rptr_addr: ube read point
  * @wdma_wptr_addr: ube write point
+ * @core_work: core hardware work
  * @lat_ctx: used to store lat buffer list
  */
 struct vdec_msg_queue {
@@ -77,6 +78,7 @@ struct vdec_msg_queue {
 	u64 wdma_rptr_addr;
 	u64 wdma_wptr_addr;
 
+	struct work_struct core_work;
 	struct vdec_msg_queue_ctx lat_ctx;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:55 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:55 +0800
Subject: [PATCH v19, 19/19] media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-20-yunfei.dong@mediatek.com>

There are only two lines in mtk_vcodec_release_enc_pm, using
pm_runtime_disable and put_device instead directly.

Move pm_runtime_enable outside mtk_vcodec_release_enc_pm to symmetry with
pm_runtime_disable, after that, rename mtk_vcodec_init_enc_pm to *_clk
since it only has clock operations now.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 9 ++++++---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c  | 9 +--------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h  | 3 +--
 3 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 347f0d87e2ff..507ad1ea2104 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
+#include <linux/pm_runtime.h>
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
@@ -257,7 +258,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		return PTR_ERR(dev->fw_handler);
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
-	ret = mtk_vcodec_init_enc_pm(dev);
+	ret = mtk_vcodec_init_enc_clk(dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
 		goto err_enc_pm;
@@ -369,7 +370,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_enc_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	mtk_vcodec_release_enc_pm(dev);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvenc);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -458,7 +460,8 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_enc);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	mtk_vcodec_release_enc_pm(dev);
+	pm_runtime_disable(dev->pm.dev);
+	put_device(dev->pm.larbvenc);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 0c8c8f86788c..0825c6ec4eb7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -13,7 +13,7 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 {
 	struct device_node *node;
 	struct platform_device *pdev;
@@ -86,13 +86,6 @@ int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *mtkdev)
 	return ret;
 }
 
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *mtkdev)
-{
-	pm_runtime_disable(mtkdev->pm.dev);
-	put_device(mtkdev->pm.larbvenc);
-}
-
-
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 {
 	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index b7ecdfd74823..bc455cefc0cd 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -9,8 +9,7 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_enc_pm(struct mtk_vcodec_dev *dev);
-void mtk_vcodec_release_enc_pm(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev);
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 12 20:10:52 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 13 Jan 2022 12:10:52 +0800
Subject: [PATCH v19, 16/19] media: mtk-vcodec: Add core dec and dec end ipi msg
In-Reply-To: <20220113041055.25213-1-yunfei.dong@mediatek.com>
References: <20220113041055.25213-1-yunfei.dong@mediatek.com>
Message-ID: <20220113041055.25213-17-yunfei.dong@mediatek.com>

Add core dec and dec end ipi msg:
AP_IPIMSG_DEC_CORE/AP_IPIMSG_DEC_CORE_END.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h   |  4 ++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c    | 12 ++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h    | 18 ++++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index 5f45a537beb4..9d8079c4f976 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -18,12 +18,16 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_END = 0xA002,
 	AP_IPIMSG_DEC_DEINIT = 0xA003,
 	AP_IPIMSG_DEC_RESET = 0xA004,
+	AP_IPIMSG_DEC_CORE = 0xA005,
+	AP_IPIMSG_DEC_CORE_END = 0xA006,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
 	VPU_IPIMSG_DEC_END_ACK = 0xB002,
 	VPU_IPIMSG_DEC_DEINIT_ACK = 0xB003,
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
+	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
+	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 5dffc459a33d..bfd8e87dceff 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -85,6 +85,8 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_END_ACK:
 		case VPU_IPIMSG_DEC_DEINIT_ACK:
 		case VPU_IPIMSG_DEC_RESET_ACK:
+		case VPU_IPIMSG_DEC_CORE_ACK:
+		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
 		default:
@@ -191,11 +193,21 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_core(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
+}
+
 int vpu_dec_end(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_END);
 }
 
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu)
+{
+	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE_END);
+}
+
 int vpu_dec_deinit(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_DEINIT);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index c2ed5b6cab8b..ae24b75d1649 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -82,4 +82,22 @@ int vpu_dec_deinit(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_reset(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_core - core start decoding, basically the function will be invoked once
+ *                 every frame.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core(struct vdec_vpu_inst *vpu);
+
+/**
+ * vpu_dec_core_end - core end decoding, basically the function will be invoked once
+ *               when core HW decoding done and receive interrupt successfully. The
+ *               decoder in VPU will updata hardware information and deinit hardware
+ *               and check if there is a new decoded frame available to display.
+ *
+ * @vpu : instance for vdec_vpu_inst
+ */
+int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
+
 #endif
-- 
2.25.1



From christianshewitt at gmail.com  Wed Jan 12 20:45:46 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Thu, 13 Jan 2022 04:45:46 +0000
Subject: [PATCH] arm64: dts: meson: add audio playback to P212
Message-ID: <20220113044546.16856-1-christianshewitt@gmail.com>

Add initial audio support limited to HDMI i2s.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
The P212 dts is widely used with Android box devices that follow the
reference design. The real P212 development board probably has many
more audio capabilities, but as a minimum we can enable HDMI output
and help box users too.

 .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 40 +++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
index 2602940c2077..a39830379c74 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include "meson-gxl-s905x-p212.dtsi"
+#include <dt-bindings/sound/meson-aiu.h>
 
 / {
 	compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
@@ -32,6 +33,45 @@
 			};
 		};
 	};
+
+	sound {
+		compatible = "amlogic,gx-sound-card";
+		model = "S905X-P212";
+		assigned-clocks = <&clkc CLKID_MPLL0>,
+				  <&clkc CLKID_MPLL1>,
+				  <&clkc CLKID_MPLL2>;
+		assigned-clock-parents = <0>, <0>, <0>;
+		assigned-clock-rates = <294912000>,
+				       <270950400>,
+				       <393216000>;
+		status = "okay";
+
+		dai-link-0 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
+		};
+
+		dai-link-1 {
+			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
+			dai-format = "i2s";
+			mclk-fs = <256>;
+
+			codec-0 {
+				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
+			};
+		};
+
+		dai-link-2 {
+			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
+
+			codec-0 {
+				sound-dai = <&hdmi_tx>;
+			};
+		};
+	};
+};
+
+&aiu {
+	status = "okay";
 };
 
 &cec_AO {
-- 
2.17.1



From reijiw at google.com  Wed Jan 12 21:33:21 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed, 12 Jan 2022 21:33:21 -0800
Subject: [PATCH 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
In-Reply-To: <Yd2sLbiw/XPCZe7q@monolith.localdoman>
References: <20220110054042.1079932-1-reijiw@google.com>
 <YdwPCcZWD8Uc1eej@monolith.localdoman>
 <CAAeT=Fz1KPbpmcSbukBuGWMJH=V_oXAJoaDHAen_Gy9Qswo_1Q@mail.gmail.com>
 <875yqqtn5q.wl-maz@kernel.org> <Yd2sLbiw/XPCZe7q@monolith.localdoman>
Message-ID: <CAAeT=Fx62SZJvQYfFWj2sA-pcvrghuh8dSGuAaAtYWnJ5T5HCA@mail.gmail.com>

Hi Marc and Alex,

On Tue, Jan 11, 2022 at 8:11 AM Alexandru Elisei
<alexandru.elisei at arm.com> wrote:
>
> Hi Marc,
>
> On Tue, Jan 11, 2022 at 01:30:41PM +0000, Marc Zyngier wrote:
> > On Tue, 11 Jan 2022 07:37:57 +0000,
> > Reiji Watanabe <reijiw at google.com> wrote:
> > >
> > > Hi Alex,
> > >
> > > On Mon, Jan 10, 2022 at 2:48 AM Alexandru Elisei
> > > <alexandru.elisei at arm.com> wrote:
> > > >
> > > > Hi Reiji,
> > > >
> > > > On Sun, Jan 09, 2022 at 09:40:41PM -0800, Reiji Watanabe wrote:
> > > > > vcpu_allowed_register_width() checks if all the VCPUs are either
> > > > > all 32bit or all 64bit.  Since the checking is done even for vCPUs
> > > > > that are not initialized (KVM_ARM_VCPU_INIT has not been done) yet,
> > > > > the non-initialized vCPUs are erroneously treated as 64bit vCPU,
> > > > > which causes the function to incorrectly detect a mixed-width VM.
> > > > >
> > > > > Fix vcpu_allowed_register_width() to skip the check for vCPUs that
> > > > > are not initialized yet.
> > > > >
> > > > > Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
> > > > > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > > > > ---
> > > > >  arch/arm64/kvm/reset.c | 11 +++++++++++
> > > > >  1 file changed, 11 insertions(+)
> > > > >
> > > > > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > > > > index 426bd7fbc3fd..ef78bbc7566a 100644
> > > > > --- a/arch/arm64/kvm/reset.c
> > > > > +++ b/arch/arm64/kvm/reset.c
> > > > > @@ -180,8 +180,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> > > > >       if (kvm_has_mte(vcpu->kvm) && is32bit)
> > > > >               return false;
> > > > >
> > > > > +     /*
> > > > > +      * Make sure vcpu->arch.target setting is visible from others so
> > > > > +      * that the width consistency checking between two vCPUs is done
> > > > > +      * by at least one of them at KVM_ARM_VCPU_INIT.
> > > > > +      */
> > > > > +     smp_mb();
> > > >
> > > > From ARM DDI 0487G.a, page B2-146 ("Data Memory Barrier (DMB)"):
> > > >
> > > > "The DMB instruction is a memory barrier instruction that ensures the relative
> > > > order of memory accesses before the barrier with memory accesses after the
> > > > barrier."
> > > >
> > > > I'm going to assume from the comment that you are referring to completion of
> > > > memory accesses ("Make sure [..] is visible from others"). Please correct me if
> > > > I am wrong. In this case, DMB ensures ordering of memory accesses with regards
> > > > to writes and reads, not *completion*.  Have a look at
> > > > tools/memory-model/litmus-tests/MP+fencewmbonceonce+fencermbonceonce.litmus for
> > > > the classic message passing example as an example of memory ordering.
> > > > Message passing and other patterns are also explained in ARM DDI 0487G.a, page
> > > > K11-8363.
> > > >
> > > > I'm not saying that your approach is incorrect, but the commit message should
> > > > explain what memory accesses are being ordered relative to each other and why.
> > >
> > > Thank you so much for the review.
> > > What I meant with the comment was:
> > > ---
> > >   DMB is used to make sure that writing @vcpu->arch.target, which is done
> > >   by kvm_vcpu_set_target() before getting here, is visible to other PEs
> > >   before the following kvm_for_each_vcpu iteration reads the other vCPUs'
> > >   target field.
> > > ---
> > > Did the comment become more clear ?? (Or do I use DMB incorrectly ?)
> > >
> > > > > +
> > > > >       /* Check that the vcpus are either all 32bit or all 64bit */
> > > > >       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> > > > > +             /* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> > > > > +             if (tmp->arch.target == -1)
> > > > > +                     continue;
> > >
> > > I just noticed DMB(ishld) is needed here to assure ordering between
> > > reading tmp->arch.target and reading vcpu->arch.features for this fix.
> > > Similarly, kvm_vcpu_set_target() needs DMB(ishst) to assure ordering
> > > between writing vcpu->arch.features and writing vcpu->arch.target...
> > > I am going to fix them in the v2 series.
> >
> > Yes, you'd need at least this, and preferably in their smp_rmb/wmb
> > variants.
> >
> > However, this looks like a pretty fragile construct, as there are
> > multiple paths where we can change target (including some error
> > paths from the run loop).
> >
> > I'd rather all changes to target and the feature bits happen under the
> > kvm->lock, and take that lock when checking for consistency in
> > vcpu_allowed_register_width(), as this isn't a fast path. I wrote the
> > following, which is obviously incomplete and as usual untested.
>
> I think this is the better approach, because we also want to make sure that
> a PE observes changes to target and features as soon as they have been
> made, to avoid situations where one PE sets the target and the 32bit
> feature, and another PE reads the old values and skips the check, in which
> case memory ordering is not enough.

Thank you for the comments and the suggestion.
I will look into fixing this based on the suggestion.

Thanks,
Reiji




>
> Thanks,
> Alex
>
> >
> > Thanks,
> >
> >       M.
> >
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index e4727dc771bf..42f2ab80646c 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -1061,7 +1061,8 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
> >  static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> >                              const struct kvm_vcpu_init *init)
> >  {
> > -     unsigned int i, ret;
> > +     unsigned int i;
> > +     int ret = 0;
> >       u32 phys_target = kvm_target_cpu();
> >
> >       if (init->target != phys_target)
> > @@ -1074,32 +1075,46 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
> >       if (vcpu->arch.target != -1 && vcpu->arch.target != init->target)
> >               return -EINVAL;
> >
> > +     /* Hazard against a concurent check of the target in kvm_reset_vcpu() */
> > +     mutex_lock(&vcpu->kvm->lock);
> > +
> >       /* -ENOENT for unknown features, -EINVAL for invalid combinations. */
> >       for (i = 0; i < sizeof(init->features) * 8; i++) {
> >               bool set = (init->features[i / 32] & (1 << (i % 32)));
> >
> > -             if (set && i >= KVM_VCPU_MAX_FEATURES)
> > -                     return -ENOENT;
> > +             if (set && i >= KVM_VCPU_MAX_FEATURES) {
> > +                     ret = -ENOENT;
> > +                     break;
> > +             }
> >
> >               /*
> >                * Secondary and subsequent calls to KVM_ARM_VCPU_INIT must
> >                * use the same feature set.
> >                */
> >               if (vcpu->arch.target != -1 && i < KVM_VCPU_MAX_FEATURES &&
> > -                 test_bit(i, vcpu->arch.features) != set)
> > -                     return -EINVAL;
> > +                 test_bit(i, vcpu->arch.features) != set) {
> > +                     ret = -EINVAL;
> > +                     break;
> > +             }
> >
> >               if (set)
> >                       set_bit(i, vcpu->arch.features);
> >       }
> >
> > -     vcpu->arch.target = phys_target;
> > +     if (!ret)
> > +             vcpu->arch.target = phys_target;
> > +
> > +     mutex_unlock(&vcpu->kvm->lock);
> > +     if (ret)
> > +             return ret;
> >
> >       /* Now we know what it is, we can reset it. */
> >       ret = kvm_reset_vcpu(vcpu);
> >       if (ret) {
> > +             mutex_lock(&vcpu->kvm->lock);
> >               vcpu->arch.target = -1;
> >               bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
> > +             mutex_unlock(&vcpu->kvm->lock);
> >       }
> >
> >       return ret;
> > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > index ef78bbc7566a..fae88a703140 100644
> > --- a/arch/arm64/kvm/reset.c
> > +++ b/arch/arm64/kvm/reset.c
> > @@ -180,13 +180,6 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> >       if (kvm_has_mte(vcpu->kvm) && is32bit)
> >               return false;
> >
> > -     /*
> > -      * Make sure vcpu->arch.target setting is visible from others so
> > -      * that the width consistency checking between two vCPUs is done
> > -      * by at least one of them at KVM_ARM_VCPU_INIT.
> > -      */
> > -     smp_mb();
> > -
> >       /* Check that the vcpus are either all 32bit or all 64bit */
> >       kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
> >               /* Skip if KVM_ARM_VCPU_INIT is not done for the vcpu yet */
> > @@ -222,14 +215,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> >  int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> >  {
> >       struct vcpu_reset_state reset_state;
> > -     int ret;
> > +     int ret = -EINVAL;
> >       bool loaded;
> >       u32 pstate;
> >
> >       mutex_lock(&vcpu->kvm->lock);
> > -     reset_state = vcpu->arch.reset_state;
> > -     WRITE_ONCE(vcpu->arch.reset_state.reset, false);
> > +     if (vcpu_allowed_register_width(vcpu)) {
> > +             reset_state = vcpu->arch.reset_state;
> > +             WRITE_ONCE(vcpu->arch.reset_state.reset, false);
> > +             ret = 0;
> > +     }
> >       mutex_unlock(&vcpu->kvm->lock);
> > +     if (ret)
> > +             goto out;
> >
> >       /* Reset PMU outside of the non-preemptible section */
> >       kvm_pmu_vcpu_reset(vcpu);
> > @@ -257,11 +255,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
> >               }
> >       }
> >
> > -     if (!vcpu_allowed_register_width(vcpu)) {
> > -             ret = -EINVAL;
> > -             goto out;
> > -     }
> > -
> >       switch (vcpu->arch.target) {
> >       default:
> >               if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
> >
> > --
> > Without deviation from the norm, progress is not possible.


From boger at wirenboard.com  Wed Jan 12 21:37:31 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Thu, 13 Jan 2022 08:37:31 +0300
Subject: [PATCH v5 0/3] sun8i: r40: second ethernet support
Message-ID: <20220113053734.105813-1-boger@wirenboard.com>

Maxime, Corentin, thank you for the review of v4!

This patch series adds support for two Ethernet ports on Allwinner R40.

R40 (aka V40,A40i,T3) has two different Ethernet IPs called EMAC and GMAC.
EMAC only support 10/100 Mbit in MII mode, while GMAC support both 10/100
(MII) and 10/100/1000 (RGMII).

In contrast to A10/A20 where GMAC and EMAC share the same pins making EMAC
somewhat pointless, on R40 EMAC can be routed to port H.
Both EMAC (on port H) and GMAC (on port A) can be then enabled at the same 
time, allowing for two ethernet ports.

Tested on custom A40i board with two IP101GRI PHYs in MII mode.

Changes in v5:
 - Rebase on fresh linux-next
 - Remove reset line from example bindings

Changes in v4:
 - Rename sun4i-r40-emac to sun8i-r40-emac to match R40 family.
 - remove redundant status = "okay" in dts
 - less obscure commit messages

Changes in v3:
Minor fixes in bindings. Rebased on top of linux-next/master.
dt_bindings_check and dtbs_check passed.

 - bindings: separate commit for DT bindings
 - bindings: simplify handling of compatible strings
 - bindings: make resets property required on R40
 - dts: get rid of duplicate node

Changes in v2:
 - EMAC reset is no longer optional on R40
 - Add a new DT compatible string for R40 EMAC
 - Deassert reset line before enabling the clock
 - minor fixes: formatting, DT node order, leftover pinctrl props

Evgeny Boger (3):
  net: allwinner: reset control support
  dt-bindings: net: support for Allwinner R40 EMAC controller
  ARM: dts: sun8i: r40: add second ethernet support

 .../net/allwinner,sun4i-a10-emac.yaml         | 17 ++++-
 arch/arm/boot/dts/sun8i-r40.dtsi              | 49 ++++++++++++++
 drivers/net/ethernet/allwinner/sun4i-emac.c   | 64 +++++++++++++++++--
 3 files changed, 124 insertions(+), 6 deletions(-)

-- 
2.25.1


From boger at wirenboard.com  Wed Jan 12 21:37:32 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Thu, 13 Jan 2022 08:37:32 +0300
Subject: [PATCH v5 1/3] net: allwinner: reset control support
In-Reply-To: <20220113053734.105813-1-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
Message-ID: <20220113053734.105813-2-boger@wirenboard.com>

R40 (aka V40/A40i/T3) and A10/A20 share the same EMAC IP.
However, on R40 the EMAC reset needs to be deasserted.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 64 +++++++++++++++++++--
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 74635a6fa8ca..56e811b0a279 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -28,6 +28,7 @@
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/reset.h>
 #include <linux/soc/sunxi/sunxi_sram.h>
 #include <linux/dmaengine.h>
 
@@ -69,6 +70,15 @@ MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
  * devices, EMACA and EMACB.
  */
 
+/**
+ * struct emac_quirks - Differences between SoC variants.
+ *
+ * @has_reset: SoC needs reset deasserted.
+ */
+struct emac_quirks {
+	bool		has_reset;
+};
+
 struct emac_board_info {
 	struct clk		*clk;
 	struct device		*dev;
@@ -85,6 +95,7 @@ struct emac_board_info {
 	unsigned int		link;
 	unsigned int		speed;
 	unsigned int		duplex;
+	struct reset_control	*reset;
 
 	phy_interface_t		phy_interface;
 	struct dma_chan	*rx_chan;
@@ -968,6 +979,7 @@ static int emac_probe(struct platform_device *pdev)
 	struct emac_board_info *db;
 	struct net_device *ndev;
 	int ret = 0;
+	const struct emac_quirks *quirks;
 
 	ndev = alloc_etherdev(sizeof(struct emac_board_info));
 	if (!ndev) {
@@ -986,6 +998,13 @@ static int emac_probe(struct platform_device *pdev)
 
 	spin_lock_init(&db->lock);
 
+	quirks = of_device_get_match_data(&pdev->dev);
+	if (!quirks) {
+		dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
 	db->membase = of_iomap(np, 0);
 	if (!db->membase) {
 		dev_err(&pdev->dev, "failed to remap registers\n");
@@ -1002,19 +1021,34 @@ static int emac_probe(struct platform_device *pdev)
 		goto out_iounmap;
 	}
 
+	if (quirks->has_reset) {
+		db->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+		if (IS_ERR(db->reset)) {
+			dev_err(&pdev->dev, "unable to request reset\n");
+			ret = PTR_ERR(db->reset);
+			goto out_dispose_mapping;
+		}
+
+		ret = reset_control_deassert(db->reset);
+		if (ret) {
+			dev_err(&pdev->dev, "could not deassert EMAC reset\n");
+			goto out_dispose_mapping;
+		}
+	}
+
 	if (emac_configure_dma(db))
 		netdev_info(ndev, "configure dma failed. disable dma.\n");
 
 	db->clk = devm_clk_get(&pdev->dev, NULL);
 	if (IS_ERR(db->clk)) {
 		ret = PTR_ERR(db->clk);
-		goto out_dispose_mapping;
+		goto out_assert_reset;
 	}
 
 	ret = clk_prepare_enable(db->clk);
 	if (ret) {
 		dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
-		goto out_dispose_mapping;
+		goto out_assert_reset;
 	}
 
 	ret = sunxi_sram_claim(&pdev->dev);
@@ -1070,6 +1104,8 @@ static int emac_probe(struct platform_device *pdev)
 	sunxi_sram_release(&pdev->dev);
 out_clk_disable_unprepare:
 	clk_disable_unprepare(db->clk);
+out_assert_reset:
+	reset_control_assert(db->reset);
 out_dispose_mapping:
 	irq_dispose_mapping(ndev->irq);
 out_iounmap:
@@ -1095,6 +1131,7 @@ static int emac_remove(struct platform_device *pdev)
 	unregister_netdev(ndev);
 	sunxi_sram_release(&pdev->dev);
 	clk_disable_unprepare(db->clk);
+	reset_control_assert(db->reset);
 	irq_dispose_mapping(ndev->irq);
 	iounmap(db->membase);
 	free_netdev(ndev);
@@ -1126,11 +1163,28 @@ static int emac_resume(struct platform_device *dev)
 	return 0;
 }
 
-static const struct of_device_id emac_of_match[] = {
-	{.compatible = "allwinner,sun4i-a10-emac",},
+static const struct emac_quirks sun4i_a10_emac_quirks = {
+	.has_reset = false,
+};
+
+static const struct emac_quirks sun8i_r40_emac_quirks = {
+	.has_reset = true,
+};
 
+static const struct of_device_id emac_of_match[] = {
+	{
+		.compatible = "allwinner,sun4i-a10-emac",
+		.data = &sun4i_a10_emac_quirks
+	},
+	{
+		.compatible = "allwinner,sun8i-r40-emac",
+		.data = &sun8i_r40_emac_quirks
+	},
 	/* Deprecated */
-	{.compatible = "allwinner,sun4i-emac",},
+	{
+		.compatible = "allwinner,sun4i-emac",
+		.data = &sun4i_a10_emac_quirks
+	},
 	{},
 };
 
-- 
2.25.1



From boger at wirenboard.com  Wed Jan 12 21:37:34 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Thu, 13 Jan 2022 08:37:34 +0300
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <20220113053734.105813-1-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
Message-ID: <20220113053734.105813-4-boger@wirenboard.com>

R40 (aka V40, A40i, T3) has two different Ethernet IPs
called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).

In contrast to A10/A20 where GMAC and EMAC share the same pins
making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
Both EMAC (on port H) and GMAC (on port A) can be then enabled at
the same time, allowing for two ethernet ports.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
index 03d3e5f45a09..8770b105f86e 100644
--- a/arch/arm/boot/dts/sun8i-r40.dtsi
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi
@@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
 			#size-cells = <1>;
 			ranges;
 
+			sram_a: sram at 0 {
+				compatible = "mmio-sram";
+				reg = <0x00000000 0xc000>;
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x00000000 0xc000>;
+
+				emac_sram: sram-section at 8000 {
+					compatible = "allwinner,sun4i-a10-sram-a3-a4";
+					reg = <0x8000 0x4000>;
+				};
+			};
+
 			sram_c: sram at 1d00000 {
 				compatible = "mmio-sram";
 				reg = <0x01d00000 0xd0000>;
@@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
 				drive-strength = <40>;
 			};
 
+			emac_pa_pins: emac-pa-pins {
+				pins = "PA0", "PA1", "PA2",
+				       "PA3", "PA4", "PA5", "PA6",
+				       "PA7", "PA8", "PA9", "PA10",
+				       "PA11", "PA12", "PA13", "PA14",
+				       "PA15", "PA16";
+				function = "emac";
+			};
+
+			emac_ph_pins: emac-ph-pins {
+				pins = "PH8", "PH9", "PH10", "PH11",
+				       "PH14", "PH15", "PH16", "PH17",
+				       "PH18","PH19", "PH20", "PH21",
+				       "PH22", "PH23", "PH24", "PH25",
+				       "PH26", "PH27";
+				function = "emac";
+			};
+
 			i2c0_pins: i2c0-pins {
 				pins = "PB0", "PB1";
 				function = "i2c0";
@@ -999,6 +1030,24 @@ gmac_mdio: mdio {
 			};
 		};
 
+		emac: ethernet at 1c0b000 {
+			compatible = "allwinner,sun8i-r40-emac";
+			reg = <0x01c0b000 0x1000>;
+			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&ccu CLK_BUS_EMAC>;
+			resets = <&ccu RST_BUS_EMAC>;
+			allwinner,sram = <&emac_sram 1>;
+			status = "disabled";
+		};
+
+		emac_mdio: mdio at 1c0b080 {
+			compatible = "allwinner,sun4i-a10-mdio";
+			reg = <0x01c0b080 0x14>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		mbus: dram-controller at 1c62000 {
 			compatible = "allwinner,sun8i-r40-mbus";
 			reg = <0x01c62000 0x1000>;
-- 
2.25.1



From boger at wirenboard.com  Wed Jan 12 21:37:33 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Thu, 13 Jan 2022 08:37:33 +0300
Subject: [PATCH v5 2/3] dt-bindings: net: support for Allwinner R40 EMAC
 controller
In-Reply-To: <20220113053734.105813-1-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
Message-ID: <20220113053734.105813-3-boger@wirenboard.com>

R40 and A10/A20 share the same EMAC IP.
However, on R40 the EMAC reset needs to be deasserted first,
so resets property is required.

Signed-off-by: Evgeny Boger <boger at wirenboard.com>
---
 .../bindings/net/allwinner,sun4i-a10-emac.yaml  | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
index 8d8560a67abf..d9ed7b547af3 100644
--- a/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
+++ b/Documentation/devicetree/bindings/net/allwinner,sun4i-a10-emac.yaml
@@ -15,7 +15,9 @@ maintainers:
 
 properties:
   compatible:
-    const: allwinner,sun4i-a10-emac
+    enum:
+      - allwinner,sun4i-a10-emac
+      - allwinner,sun8i-r40-emac
 
   reg:
     maxItems: 1
@@ -30,6 +32,19 @@ properties:
     description: Phandle to the device SRAM
     $ref: /schemas/types.yaml#/definitions/phandle-array
 
+  resets:
+    maxItems: 1
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: allwinner,sun8i-r40-emac
+
+then:
+  required:
+    - resets
+
 required:
   - compatible
   - reg
-- 
2.25.1



From yong.wu at mediatek.com  Wed Jan 12 22:02:37 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 14:02:37 +0800
Subject: [PATCH v2 5/6] memory: mtk-smi: Add sleep ctrl function
In-Reply-To: <22935ffa-469c-a609-c30b-919ba85b842c@canonical.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-6-yong.wu@mediatek.com>
 <22935ffa-469c-a609-c30b-919ba85b842c@canonical.com>
Message-ID: <6d2759f9d2ea74affa040bfec524e87b765c67af.camel@mediatek.com>

On Wed, 2022-01-12 at 11:27 +0100, Krzysztof Kozlowski wrote:
> On 11/01/2022 07:39, Yong Wu wrote:
> > Sleep control means that when the larb goes to sleep, we should
> > wait a bit
> > until all the current commands are finished. Thus, when the larb
> > runtime
> > suspends, we need to enable this function to wait until all the
> > existed
> > commands are finished. When the larb resumes, just disable this
> > function.
> > This function only improves the safety of bus. Add a new flag for
> > this
> > function. Prepare for mt8186.
> > 
> > Signed-off-by: Anan Sun <anan.sun at mediatek.com>
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >  drivers/memory/mtk-smi.c | 35 ++++++++++++++++++++++++++++++++++-
> >  1 file changed, 34 insertions(+), 1 deletion(-)

[...]

> > @@ -492,9 +521,13 @@ static int __maybe_unused
> > mtk_smi_larb_resume(struct device *dev)
> >  static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
> >  {
> >  	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
> > +	int ret = 0;
> > +
> > +	if (MTK_SMI_CAPS(larb->larb_gen->flags_general,
> > MTK_SMI_FLAG_SLEEP_CTL))
> > +		ret = mtk_smi_larb_sleep_ctrl_enable(larb);
> >  
> >  	clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
> > -	return 0;
> > +	return ret;
> 
> I am wondering whether disabling clocks in error case is a proper
> step.
> On suspend error, the PM core won't run any further callbacks on this
> device. This means, it won't be resumed and your clocks stay
> disabled. I
> think you should return early and leave the device in active state in
> case of error.

oh, Yes. Thanks for pointing this out.

I will fix this in next version.

> 
> 
> Best regards,
> Krzysztof
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

From mhiramat at kernel.org  Wed Jan 12 22:04:15 2022
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Thu, 13 Jan 2022 15:04:15 +0900
Subject: [PATCH v5] arm64: kprobe: Enable OPTPROBE for arm64
In-Reply-To: <CAAgTQPUEgSf-E_GOUNY_=4Piiy0K_-5U_YVbnoMAZ94Q3ducOg@mail.gmail.com>
References: <20211207124002.59877-1-liuqi115@huawei.com>
 <20211213183851.GD12405@willie-the-truck>
 <20211214092657.5b9c26b4e3852602eced4fda@kernel.org>
 <CAAgTQPUKqFn9_ENKbfJkFjT3v9L2NiFAY2xvULEj_6wguqWYNg@mail.gmail.com>
 <f4552c3e-8f1a-bef1-9396-39aa2405b486@huawei.com>
 <CAAgTQPWAK==cYPKeYNGE7nPGh0Y7Py4TcUoMPz76h15YNBNsLQ@mail.gmail.com>
 <CAAgTQPWomoiGdVJxwYBmXOj7RegHM4TSa2+yKVTQFhBFg8PtLg@mail.gmail.com>
 <20220104113559.7dd1ff2cb575f62e0b01fb47@kernel.org>
 <dbcbc161-228d-ee78-e1f0-b59ad9b0a36f@huawei.com>
 <CAAgTQPUEgSf-E_GOUNY_=4Piiy0K_-5U_YVbnoMAZ94Q3ducOg@mail.gmail.com>
Message-ID: <20220113150415.2a3c9129ba17893a89428489@kernel.org>

On Wed, 12 Jan 2022 20:21:57 +0800
Jianhua Liu <jianhua.ljh at gmail.com> wrote:

> On Wed, Jan 12, 2022 at 9:31 AM liuqi (BA) <liuqi115 at huawei.com> wrote:
> >
> >
> >
> > On 2022/1/4 10:35, Masami Hiramatsu wrote:
> > > Hi Jianhua,
> > >
> > > On Mon, 3 Jan 2022 17:03:33 +0800
> > > Jianhua Liu <jianhua.ljh at gmail.com> wrote:
> > >
> > >> Hi Qi,
> > >> I have tested your patch on UNISOC s9863a.
> > >> Test case "kprobe_example & kretprobe_example" is OK.
> > >>
> > >> Two point:
> > >> 1. backtrace is not perfect.
> > >>     optprobe_common does not saved frame pointer,
> > >>     backtrace lacks two calls.
> > >> such as for dup_mm: lack copy_process-->dup_mm
> > >> dup_mm backtrace from your patch:
> > >> [  832.387066] CPU: 0 PID: 296 Comm: sh Not tainted 5.16.0-rc5+ #8
> > >> [  832.387078] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> > >> [  832.387083] Call trace:
> > >> [  832.387086]  dump_backtrace+0x0/0x1e0
> > >> [  832.387103]  show_stack+0x24/0x30
> > >> [  832.387112]  dump_stack_lvl+0x68/0x84
> > >> [  832.387123]  dump_stack+0x18/0x34
> > >> [  832.387131]  handler_pre+0x40/0x50 [kprobe_example]
> > >> [  832.387143]  opt_pre_handler+0x84/0xc0
> > >> [  832.387154]  optprobe_optimized_callback+0xec/0x164
> > >> [  832.387164]  optprobe_common+0x70/0xc4
> > >> [  832.387173]  kernel_clone+0x98/0x440
> > >> [  832.387182]  __do_sys_clone+0x54/0x80
> > >> [  832.387191]  __arm64_sys_clone+0x2c/0x40
> > >> [  832.387199]  invoke_syscall+0x50/0x120
> > >> [  832.387208]  el0_svc_common.constprop.0+0x4c/0xf4
> > >> [  832.387217]  do_el0_svc+0x30/0x9c
> > >> [  832.387225]  el0_svc+0x20/0x60
> > >> [  832.387235]  el0t_64_sync_handler+0xe8/0xf0
> > >> [  832.387242]  el0t_64_sync+0x1a0/0x1a4
> > >>
> > >>
> > >> dup_mm backtrace from other:
> > >> [  173.352294] CPU: 6 PID: 309 Comm: sh Not tainted 5.16.0-rc5+ #19
> > >> [  173.352301] Hardware name: Spreadtrum SP9863A-1H10 Board (DT)
> > >> [  173.352304] Call trace:
> > >> [  173.352307]  dump_backtrace+0x0/0x1d4
> > >> [  173.352319]  show_stack+0x18/0x24
> > >> [  173.352326]  dump_stack_lvl+0x68/0x84
> > >> [  173.352333]  dump_stack+0x18/0x34
> > >> [  173.352338]  handler_pre+0x38/0x48 [kprobe_example]
> > >> [  173.352347]  opt_pre_handler+0x74/0xb0
> > >> [  173.352354]  optimized_callback+0x108/0x130
> > >> [  173.352361]  optinsn_slot+0x258/0x1000
> > >> [  173.352366]  dup_mm+0x4/0x4b0
> > >> [  173.352373]  copy_process+0x1284/0x1360
> > >> [  173.352378]  kernel_clone+0x5c/0x3c0
> > >> [  173.352384]  __do_sys_clone+0x54/0x80
> > >> [  173.352390]  __arm64_sys_clone+0x24/0x30
> > >> [  173.352396]  invoke_syscall+0x48/0x114
> > >> [  173.352402]  el0_svc_common.constprop.0+0x44/0xec
> > >> [  173.352408]  do_el0_svc+0x24/0x90
> > >> [  173.352413]  el0_svc+0x20/0x60
> > >> [  173.352420]  el0t_64_sync_handler+0xe8/0xf0
> > >> [  173.352427]  el0t_64_sync+0x1a0/0x1a4
> > >
> >
> > Hi Masami and Jianhua,
> >
> > optprobe_common() is added to minize size of code in trampoline, but
> > each trampoline is alloced as PAGE_SIZE, so optprobe_common() seems
> > unnecessary, and will make optprobe_trampoline.S much more complicated.
> > How about drop optprobe_common() and use a maro to reduce duplicate code .
> >
> 1. each trampoline is allocated as
> (MAX_OPTINSN_SIZE*sizeof(kprobe_opcode_t)), not PAGE_SIZE

Right. What Jianhua pointed was the alloc_optinsn_page() is expected to
return the PAGE_SIZE memory. Each trampoline "slot" is allocated on
that page. See __get_insn_slot()@kernel/kprobes.c for detail.

> 2. MAX_OPTINSN_SIZE should be "((unsigned long)(optprobe_template_end
> - optprobe_template_entry)),
>    your MAX_OPTINSN_SIZE  is not accurate.

Good catch! The MAX_OPTINSN_SIZE is not in byte, but in sizeof(kprobe_opcode_t).

+#define MAX_OPTINSN_SIZE                                                       \
+       ((unsigned long)optprobe_template_restore_end - (unsigned long)optprobe_template_entry)

This will calculate the MAX_OPTINSN_SIZE in byte. Hmm, arm 32bit 
implementation has same mistake. Thanks for pointing it out!

> 3.optprobe_template_val in different kprobe may not be aligned with 8 byte.
>    ldr instruction for this value, may use address that not aligned 8 byte.
>    "ldr x0, 1f
>    .global optprobe_template_common"

Ouch. Hmm, I think we should adjust MAX_OPTINSN_SIZE is always 2n, or
just add a nop (or additional .long 0) with a comment.

BTW, the filename of arch/arm64/kernel/probes/opt_arm64.c is redundant,
it should be arch/arm64/kernel/probes/optprobe.c, since we are sure
that is for arm64.

Thank you!

> 
> Thanks,
> Jianhua
> > Thanks,
> > Qi
> > > Is the second one with your patch?
> > >
> > >>
> > >> 2. The reserve memory "OPT_SLOT_SIZE - PAGE_SIZE"  is waste.
> > >>     kernel/kprobe.c used only one PAGE_SIZE slot memory.
> > >
> > > Good catch!
> > > Qi, can you make an array (or bit map) of usage flags and
> > > manage the reserved memory?
> > >
> > > #define OPT_INSN_PAGES (OPT_SLOT_SIZE/PAGE_SIZE)
> > > static bool insn_page_in_use[OPT_INSN_PAGES];
> > >
> > > void *alloc_optinsn_page(void)
> > > {
> > >       int i;
> > >
> > >       for (i = 0; i < OPT_INSN_PAGES; i++)
> > >               if (!insn_page_in_use[i])
> > >                       goto found;
> > >       return NULL;
> > > found:
> > >       insn_page_in_use[i] = true;
> > >       return (void *)((unsigned long)optinsn_slot + PAGE_SIZE * i);
> > > }
> > >
> > > void free_optinsn_page(void *page)
> > > {
> > >       unsigned long idx = (unsigned long)page - (unsigned long)optinsn_slot;
> > >
> > >       WARN_ONCE(idx & (PAGE_SIZE - 1));
> > >       idx >>= PAGE_SHIFT;
> > >       if (WARN_ONCE(idx >= OPT_INSN_PAGES))
> > >               return;
> > >       insn_page_in_use[idx] = false;
> > > }
> > >
> > > Thank you,
> > >
> > >
> > >
> > >


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From yong.wu at mediatek.com  Wed Jan 12 22:05:59 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 14:05:59 +0800
Subject: [PATCH v2 4/6] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <00efa277-6475-4f20-f045-443a0706e9e2@collabora.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-5-yong.wu@mediatek.com>
 <00efa277-6475-4f20-f045-443a0706e9e2@collabora.com>
Message-ID: <18d7e049adc69f4b7f0ecfdf8520a02bd6e17149.camel@mediatek.com>

On Tue, 2022-01-11 at 10:10 +0100, AngeloGioacchino Del Regno wrote:
> Il 11/01/22 07:39, Yong Wu ha scritto:
> > The successful return value for clk_bulk_prepare_enable is 0,
> > rather than
> > "< 0". Fix this.
> > 
> 
> Hello! Thanks for this commit!
> However, there are a few comments...
> 
> This description is a bit confusing, please reword it, something
> like...
> 
> "Function clk_bulk_prepare_enable() returns 0 for success or a
> negative
> number for error. Fix this code style issue."

Thanks for your quickly reviewing.

I will use this in next version and remove the "Fixes" tag.

> 
> In any case, you're not fixing any bad logic issue here, as the
> function
> will never return anything > 0.
> 
> What you're fixing is a common pattern usage issue, so the Fixes tag
> can be
> removed since it's not really useful to schedule this commit for
> backport
> over older stable versions.
> 
> 
> After the requested changes:
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> 
> > Fixes: 0e14917c57f9 ("memory: mtk-smi: Use clk_bulk clock ops")
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >   drivers/memory/mtk-smi.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index b883dcc0bbfa..e7b1a22b12ea 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -480,7 +480,7 @@ static int __maybe_unused
> > mtk_smi_larb_resume(struct device *dev)
> >   	int ret;
> >   
> >   	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb-
> > >smi.clks);
> > -	if (ret < 0)
> > +	if (ret)
> >   		return ret;
> >   
> >   	/* Configure the basic setting for this larb */
> > 
> 
> 

From jkchen at linux.alibaba.com  Wed Jan 12 22:06:00 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Thu, 13 Jan 2022 14:06:00 +0800
Subject: [RESEND PATCH] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <20220105023832.4729-1-jkchen@linux.alibaba.com>
References: <20220105023832.4729-1-jkchen@linux.alibaba.com>
Message-ID: <b021efc9-736d-7180-ccdf-c6ce7d745a83@linux.alibaba.com>

hi all

? 2022/1/5 10:38, Jay Chen ??:
> Currently, there are 130 etr and etf on our machine,
> but the current coresight tmc driver uses misc_register
> to register the device, which leads to the error that
> the device number is not enough.
>
> coresight-tmc: probe of xxxxx failed with error -16
>
> This patch changes the device registration method
> to cdev's dynamic registration method to solve the
> problem of insufficient device numbers.
>
> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> ---
>   .../hwtracing/coresight/coresight-tmc-core.c  | 91 +++++++++++++++----
>   drivers/hwtracing/coresight/coresight-tmc.h   | 11 ++-
>   2 files changed, 82 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index d0276af82494..55a131c059fe 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -12,7 +12,6 @@
>   #include <linux/io.h>
>   #include <linux/err.h>
>   #include <linux/fs.h>
> -#include <linux/miscdevice.h>
>   #include <linux/mutex.h>
>   #include <linux/property.h>
>   #include <linux/uaccess.h>
> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>   
> +static DEFINE_IDA(tmc_ida);
> +static dev_t tmc_major;
> +static struct class *tmc_class;
> +
> +#define TMC_DEV_MAX	(MINORMASK + 1)
> +
>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>   {
>   	struct coresight_device *csdev = drvdata->csdev;
> @@ -147,7 +152,7 @@ static int tmc_open(struct inode *inode, struct file *file)
>   {
>   	int ret;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +		

I found a mistake in this place. I'll revise it again;

sorry

> 				   struct tmc_drvdata, cdev);
>   
>   	ret = tmc_read_prepare(drvdata);
>   	if (ret)
> @@ -179,7 +184,7 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>   	char *bufp;
>   	ssize_t actual;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>   	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>   	if (actual <= 0)
>   		return 0;
> @@ -200,7 +205,7 @@ static int tmc_release(struct inode *inode, struct file *file)
>   {
>   	int ret;
>   	struct tmc_drvdata *drvdata = container_of(file->private_data,
> -						   struct tmc_drvdata, miscdev);
> +						   struct tmc_drvdata, cdev);
>   
>   	ret = tmc_read_unprepare(drvdata);
>   	if (ret)
> @@ -451,6 +456,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   {
>   	int ret = 0;
>   	u32 devid;
> +	dev_t devt;
>   	void __iomem *base;
>   	struct device *dev = &adev->dev;
>   	struct coresight_platform_data *pdata = NULL;
> @@ -546,14 +552,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>   		goto out;
>   	}
>   
> -	drvdata->miscdev.name = desc.name;
> -	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> -	drvdata->miscdev.fops = &tmc_fops;
> -	ret = misc_register(&drvdata->miscdev);
> +	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> +	if (ret < 0)
> +		goto err_coresight_unregister;
> +
> +	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> +	drvdata->cdev.cdev.owner = THIS_MODULE;
> +	devt = MKDEV(MAJOR(tmc_major), ret);
> +	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>   	if (ret)
> -		coresight_unregister(drvdata->csdev);
> -	else
> +		goto err_free_tmc_ida;
> +
> +	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> +	if (IS_ERR(drvdata->cdev.dev)) {
> +		ret = PTR_ERR(drvdata->cdev.dev);
> +		goto err_delete_cdev;
> +	} else
>   		pm_runtime_put(&adev->dev);
> +
> +	return 0;
> +
> +err_delete_cdev:
> +	cdev_del(&drvdata->cdev.cdev);
> +err_free_tmc_ida:
> +	ida_simple_remove(&tmc_ida, MINOR(devt));
> +err_coresight_unregister:
> +	coresight_unregister(drvdata->csdev);
>   out:
>   	return ret;
>   }
> @@ -583,13 +607,11 @@ static void tmc_shutdown(struct amba_device *adev)
>   static void tmc_remove(struct amba_device *adev)
>   {
>   	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +	struct device *dev = drvdata->cdev.dev;
>   
> -	/*
> -	 * Since misc_open() holds a refcount on the f_ops, which is
> -	 * etb fops in this case, device is there until last file
> -	 * handler to this device is closed.
> -	 */
> -	misc_deregister(&drvdata->miscdev);
> +	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
> +	device_destroy(tmc_class, dev->devt);
> +	cdev_del(&drvdata->cdev.cdev);
>   	coresight_unregister(drvdata->csdev);
>   }
>   
> @@ -618,7 +640,42 @@ static struct amba_driver tmc_driver = {
>   	.id_table	= tmc_ids,
>   };
>   
> -module_amba_driver(tmc_driver);
> +static int __init tmc_init(void)
> +{
> +	int ret;
> +
> +	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> +	if (ret < 0) {
> +		pr_err("tmc: failed to allocate char dev region\n");
> +		return ret;
> +	}
> +
> +	tmc_class = class_create(THIS_MODULE, "tmc");
> +	if (IS_ERR(tmc_class)) {
> +		pr_err("tmc: failed to create class\n");
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +		return PTR_ERR(tmc_class);
> +	}
> +
> +	ret = amba_driver_register(&tmc_driver);
> +	if (ret) {
> +		pr_err("tmc: error registering amba driver\n");
> +		class_destroy(tmc_class);
> +		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +	}
> +
> +	return ret;
> +}
> +
> +static void __exit tmc_exit(void)
> +{
> +	amba_driver_unregister(&tmc_driver);
> +	class_destroy(tmc_class);
> +	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +}
> +
> +module_init(tmc_init);
> +module_exit(tmc_exit);
>   
>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6bec20a392b3..11441c6b9c26 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -7,9 +7,9 @@
>   #ifndef _CORESIGHT_TMC_H
>   #define _CORESIGHT_TMC_H
>   
> +#include <linux/cdev.h>
>   #include <linux/dma-mapping.h>
>   #include <linux/idr.h>
> -#include <linux/miscdevice.h>
>   #include <linux/mutex.h>
>   #include <linux/refcount.h>
>   
> @@ -163,11 +163,16 @@ struct etr_buf {
>   	void				*private;
>   };
>   
> +struct tmc_cdev {
> +	struct cdev cdev;
> +	struct device *dev;
> +};
> +
>   /**
>    * struct tmc_drvdata - specifics associated to an TMC component
>    * @base:	memory mapped base address for this component.
>    * @csdev:	component vitals needed by the framework.
> - * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
> + * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
>    * @spinlock:	only one at a time pls.
>    * @pid:	Process ID of the process being monitored by the session
>    *		that is using this component.
> @@ -191,7 +196,7 @@ struct etr_buf {
>   struct tmc_drvdata {
>   	void __iomem		*base;
>   	struct coresight_device	*csdev;
> -	struct miscdevice	miscdev;
> +	struct tmc_cdev		cdev;
>   	spinlock_t		spinlock;
>   	pid_t			pid;
>   	bool			reading;


From yong.wu at mediatek.com  Wed Jan 12 22:06:20 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 14:06:20 +0800
Subject: [PATCH v2 2/6] dt-bindings: memory: mtk-smi: Fix the larb
 clock/clock-names dtbs warning
In-Reply-To: <b8b8fe77-2ea8-d05c-5fa2-d4cae01baba5@canonical.com>
References: <20220111063904.7583-1-yong.wu@mediatek.com>
 <20220111063904.7583-3-yong.wu@mediatek.com>
 <b8b8fe77-2ea8-d05c-5fa2-d4cae01baba5@canonical.com>
Message-ID: <1eb2bc6432aa5a1c0371542457a86764df77153b.camel@mediatek.com>

On Wed, 2022-01-12 at 11:18 +0100, Krzysztof Kozlowski wrote:
> On 11/01/2022 07:39, Yong Wu wrote:
> > Mute the warning from "make dtbs_check":
> > 
> > larb at 14017000: clock-names: ['apb', 'smi'] is too short
> > 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> > 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-
> > burnet.dt.yaml
> > 	...
> > 
> > larb at 16010000: clock-names: ['apb', 'smi'] is too short
> > 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> > 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-
> > burnet.dt.yaml
> > 
> > larb at 17010000: clock-names: ['apb', 'smi'] is too short
> > 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> > 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-
> > burnet.dt.yaml
> > 
> > If a platform's larb supports gals, there will be some larbs have
> > one
> > more "gals" clock while the others still only need "apb"/"smi"
> > clocks,
> > then the minItems for clock and clock-names are 2.
> > 
> > Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to
> > DT schema")
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >  .../bindings/memory-controllers/mediatek,smi-larb.yaml      | 6
> > +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/memory-
> > controllers/mediatek,smi-larb.yaml
> > b/Documentation/devicetree/bindings/memory-
> > controllers/mediatek,smi-larb.yaml
> > index 80907e357892..884c0c74e5e4 100644
> > --- a/Documentation/devicetree/bindings/memory-
> > controllers/mediatek,smi-larb.yaml
> > +++ b/Documentation/devicetree/bindings/memory-
> > controllers/mediatek,smi-larb.yaml
> > @@ -80,10 +80,10 @@ allOf:
> >      then:
> >        properties:
> >          clock:
> 
> Separate patch:
> This should be clocks. The same in second if. Now it is simply not
> working...
> 
> > -          items:
> 
> Putting min/maxItems under items is wrong. The second if also needs
> the
> fixing. Please make it a separate patch before this one.

Oh. I will use a new patch for renaming "clock" to "clocks" and
removing the "items".

Thanks.

> 
> The schema was clearly not tested before...
> 
> 
> > -            minItems: 3
> > -            maxItems: 3
> > +          minItems: 2
> > +          maxItems: 3
> >          clock-names:
> > +          minItems: 2
> >            items:
> >              - const: apb
> >              - const: smi
> > 
> 
> 
> Best regards,
> Krzysztof

From jkchen at linux.alibaba.com  Wed Jan 12 22:12:09 2022
From: jkchen at linux.alibaba.com (Jay Chen)
Date: Thu, 13 Jan 2022 14:12:09 +0800
Subject: [RESEND PATCH v2] coresight: change tmc from misc device to cdev
 device
Message-ID: <20220113061209.14271-1-jkchen@linux.alibaba.com>

Currently, there are 130 etr and etf on our machine,
but the current coresight tmc driver uses misc_register
to register the device, which leads to the error that
the device number is not enough.

coresight-tmc: probe of xxxxx failed with error -16

This patch changes the device registration method
to cdev's dynamic registration method to solve the
problem of insufficient device numbers.

Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
 2 files changed, 91 insertions(+), 23 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index d0276af82494..0977f1ce6338 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -12,7 +12,6 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
@@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+static DEFINE_IDA(tmc_ida);
+static dev_t tmc_major;
+static struct class *tmc_class;
+
+#define TMC_DEV_MAX	(MINORMASK + 1)
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
 static int tmc_open(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_prepare(drvdata);
 	if (ret)
@@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 {
 	char *bufp;
 	ssize_t actual;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
 	if (actual <= 0)
 		return 0;
@@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 static int tmc_release(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_unprepare(drvdata);
 	if (ret)
@@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	u32 devid;
+	dev_t devt;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		goto out;
 	}
 
-	drvdata->miscdev.name = desc.name;
-	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
-	drvdata->miscdev.fops = &tmc_fops;
-	ret = misc_register(&drvdata->miscdev);
+	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err_coresight_unregister;
+
+	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
+	drvdata->cdev.cdev.owner = THIS_MODULE;
+	devt = MKDEV(MAJOR(tmc_major), ret);
+	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
 	if (ret)
-		coresight_unregister(drvdata->csdev);
-	else
+		goto err_free_tmc_ida;
+
+	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
+	if (IS_ERR(drvdata->cdev.dev)) {
+		ret = PTR_ERR(drvdata->cdev.dev);
+		goto err_delete_cdev;
+	} else
 		pm_runtime_put(&adev->dev);
+
+	return 0;
+
+err_delete_cdev:
+	cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
+	ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
+	coresight_unregister(drvdata->csdev);
 out:
 	return ret;
 }
@@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
 static void tmc_remove(struct amba_device *adev)
 {
 	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct device *dev = drvdata->cdev.dev;
 
-	/*
-	 * Since misc_open() holds a refcount on the f_ops, which is
-	 * etb fops in this case, device is there until last file
-	 * handler to this device is closed.
-	 */
-	misc_deregister(&drvdata->miscdev);
+	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
+	device_destroy(tmc_class, dev->devt);
+	cdev_del(&drvdata->cdev.cdev);
 	coresight_unregister(drvdata->csdev);
 }
 
@@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int __init tmc_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
+	if (ret < 0) {
+		pr_err("tmc: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	tmc_class = class_create(THIS_MODULE, "tmc");
+	if (IS_ERR(tmc_class)) {
+		pr_err("tmc: failed to create class\n");
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+		return PTR_ERR(tmc_class);
+	}
+
+	ret = amba_driver_register(&tmc_driver);
+	if (ret) {
+		pr_err("tmc: error registering amba driver\n");
+		class_destroy(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+	}
+
+	return ret;
+}
+
+static void __exit tmc_exit(void)
+{
+	amba_driver_unregister(&tmc_driver);
+	class_destroy(tmc_class);
+	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+
+module_init(tmc_init);
+module_exit(tmc_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6bec20a392b3..11441c6b9c26 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -7,9 +7,9 @@
 #ifndef _CORESIGHT_TMC_H
 #define _CORESIGHT_TMC_H
 
+#include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 
@@ -163,11 +163,16 @@ struct etr_buf {
 	void				*private;
 };
 
+struct tmc_cdev {
+	struct cdev cdev;
+	struct device *dev;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
- * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process being monitored by the session
  *		that is using this component.
@@ -191,7 +196,7 @@ struct etr_buf {
 struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
-	struct miscdevice	miscdev;
+	struct tmc_cdev		cdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
-- 
2.27.0



From songmuchun at bytedance.com  Wed Jan 12 22:28:08 2022
From: songmuchun at bytedance.com (Muchun Song)
Date: Thu, 13 Jan 2022 14:28:08 +0800
Subject: [PATCH] arm64: mm: hugetlb: add support for free vmemmap pages of
 HugeTLB
In-Reply-To: <Yd7DNesaCACPndv2@FVFF77S0Q05N>
References: <20220111131652.61947-1-songmuchun@bytedance.com>
 <Yd7DNesaCACPndv2@FVFF77S0Q05N>
Message-ID: <CAMZfGtUWWvxFkstCEv+wubrP0==Kob=NsxwZ-qw-953hEoZntA@mail.gmail.com>

On Wed, Jan 12, 2022 at 8:02 PM Mark Rutland <mark.rutland at arm.com> wrote:
>
> Hi,
>
> On Tue, Jan 11, 2022 at 09:16:52PM +0800, Muchun Song wrote:
> > The preparation of supporting freeing vmemmap associated with each
> > HugeTLB page is ready, so we can support this feature for arm64.
> >
> > Signed-off-by: Muchun Song <songmuchun at bytedance.com>
>
> It's a bit difficult to understand this commit message, as there's not much
> context here.

Hi Mark,

My bad. More infos can be found here [1].

[1] https://lore.kernel.org/all/20210510030027.56044-1-songmuchun at bytedance.com/T/#u

>
> What is HUGETLB_PAGE_FREE_VMEMMAP intended to achieve? Is this intended to save
> memory, find bugs, or some other goal? If this is a memory saving or
> performance improvement, can we quantify that benefit?

It is for memory saving. It can save about 12GB or 16GB per 1TB HugeTLB
pages (2MB or 1GB type).

>
> Does the alloc/free happen dynamically, or does this happen once during kernel
> boot? IIUC it's the former, which sounds pretty scary. Especially if we need to
> re-allocate the vmmemmap pages later -- can't we run out of memory, and then
> fail to free a HugeTLB page?

Right. The implementations about this can found in commit:

  ad2fa3717b74994 ("mm: hugetlb: alloc the vmemmap pages associated
with each HugeTLB page")

>
> Are there any requirements upon arch code, e.g. mutual exclusion?

No. The implementation is generic. There is no architecture specific code
needed to be implemented.

>
> Below there are a bunch of comments trying to explain that this is safe. Having
> some of that rationale in the commit message itself would be helpful.
>
> I see that commit:
>
>   6be24bed9da367c2 ("mm: hugetlb: introduce a new config HUGETLB_PAGE_FREE_VMEMMAP")
>
> ... has a much more complete description, and cribbing some of that wording
> would be helpful.

Will do in the next version once we are on the same page about this feature.

>
>
> > ---
> > There is already some discussions about this in [1], but there was no
> > conclusion in the end. I copied the concern proposed by Anshuman to here.
> >
> > 1st concern:
> > "
> >   But what happens when a hot remove section's vmemmap area (which is being
> >   teared down) is nearby another vmemmap area which is either created or
> >   being destroyed for HugeTLB alloc/free purpose. As you mentioned HugeTLB
> >   pages inside the hot remove section might be safe. But what about other
> >   HugeTLB areas whose vmemmap area shares page table entries with vmemmap
> >   entries for a section being hot removed ? Massive HugeTLB alloc/use/free
> >   test cycle using memory just adjacent to a memory hotplug area, which is
> >   always added and removed periodically, should be able to expose this problem.
> > "
> > My Answer: As you already know HugeTLB pages inside the hot remove section
> > is safe.
>
> It would be helpful if you could explain *why* that's safe, since those of us
> coming at this cold have no idea whether this is the case.

At the time memory is removed, all huge pages either have been migrated
away or dissolved. So there is no race between memory hot remove and
free_huge_page_vmemmap().

>
> > Let's talk your question "what about other HugeTLB areas whose
> > vmemmap area shares page table entries with vmemmap entries for a section
> > being hot removed ?", the question is not established. Why? The minimal
> > granularity size of hotplug memory 128MB (on arm64, 4k base page), so any
> > HugeTLB smaller than 128MB is within a section, then, there is no share
> > (PTE) page tables between HugeTLB in this section and ones in other
> > sections and a HugeTLB could not cross two sections.
>
> Am I correct in assuming that in this case we never free the section?

Right. So there is no race between memory hot remove and
free_huge_page_vmemmap() as well.

>
> > Any HugeTLB bigger than 128MB (e.g. 1GB) whose size is an integer multible of
> > a section and vmemmap area is also an integer multiple of 2MB. At the time
> > memory is removed, all huge pages either have been migrated away or
> > dissolved. The vmemmap is stable. So there is no problem in this case as
> > well.
>
> Are you mention 2MB here because we PMD-map the vmemmap with 4K pages?

Right.

>
> IIUC, so long as:
>
> 1) HugeTLBs are naturally aligned, power-of-two sizes
> 2) The HugeTLB size >= the section size
> 3) The HugeTLB size >= the vmemmap leaf mapping size
>
> ... then a HugeTLB will not share any leaf page table entries with *anything
> else*, but will share intermediate entries.

Right.

>
> Perhaps that's a clearer line of argument?
>
> Regardless, this should be in the commit message.

Will do.

>
> > 2nd concern:
> > "
> >   differently, not sure if ptdump would require any synchronization.
> >
> >   Dumping an wrong value is probably okay but crashing because a page table
> >   entry is being freed after ptdump acquired the pointer is bad. On arm64,
> >   ptdump() is protected against hotremove via [get|put]_online_mems().
> > "
> > My Answer: The ptdump should be fine since vmemmap_remap_free() only exchanges
> > PTEs or split the PMD entry (which means allocating a PTE page table). Both
> > operations do not free any page tables, so ptdump cannot run into a UAF on
> > any page tables. The wrost case is just dumping an wrong value.
>
> This should be in the commit message.
>

Will do.

Thanks.


From allen-kh.cheng at mediatek.com  Wed Jan 12 22:36:16 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:36:16 +0800
Subject: [PATCH v3 0/5] Update MT8192 Clock Setting
In-Reply-To: <d36d276a-c3be-431b-3636-c313cabda3d4@gmail.com>
References: <20220112115542.10606-1-allen-kh.cheng@mediatek.com>
 <d36d276a-c3be-431b-3636-c313cabda3d4@gmail.com>
Message-ID: <6598ee7223a429d40e9a2f833a189f6d9592f04e.camel@mediatek.com>

On Wed, 2022-01-12 at 17:51 +0100, Matthias Brugger wrote:
> 
> On 12/01/2022 12:55, allen-kh.cheng wrote:
> > From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> > 
> > This patch is base on v5.16-rc8,
> > series "Mediatek MT8192 clock support"[1], [2] annd [3].
> > [1] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=521127__;!!CTRNKA9wMg0ARbw!y4P6pz_u9M3axQ-m02SGlirjXL2ZKklxIqILLsUy4wXY9bVdhpSWqgRL0Me352sLvBo6xw$
> >  
> > [2] 
> > https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/patch/20210727023205.20319-2-chun-jie.chen at mediatek.com/__;!!CTRNKA9wMg0ARbw!y4P6pz_u9M3axQ-m02SGlirjXL2ZKklxIqILLsUy4wXY9bVdhpSWqgRL0Me352vbYrxOog$
> >  
> > [3] 
> > https://urldefense.com/v3/__https://lore.kernel.org/all/20210825011120.30481-1-chun-jie.chen at mediatek.com/__;!!CTRNKA9wMg0ARbw!y4P6pz_u9M3axQ-m02SGlirjXL2ZKklxIqILLsUy4wXY9bVdhpSWqgRL0Me352sfbDoBBA$
> >  
> 
> Please update that list to only who the patches that are not yet
> upstream. That 
> will help me to understand if I can take them right now or if we have
> to wait 
> for something to get applied first.
> 
> Thanks,
> Matthias

Hi Matthias,

There is no patches we need to wait related to this serial.

I will update the list in next version.

Thanks.

> 
> > 
> > changes since v2:
> >   - add missing "clock" at the end of commit message
> > 
> > changes since v1:
> >   - update the commit message
> > 
> > Allen-KH Cheng (5):
> >    arm64: dts: mediatek: Correct uart clock of MT8192
> >    arm64: dts: mediatek: Correct SPI clock of MT8192
> >    arm64: dts: mediatek: Correct Nor Flash clock of MT8192
> >    arm64: dts: mediatek: Correct I2C clock of MT8192
> >    arm64: dts: mediatek: Correct system timer clock of MT8192
> > 
> >   arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++----
> > -------
> >   1 file changed, 52 insertions(+), 40 deletions(-)
> > 



From kevin at bracey.fi  Wed Jan 12 22:41:14 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 08:41:14 +0200
Subject: [PATCH 0/4] arm64: accelerate crc32_be
Message-ID: <20220113064118.1580916-1-kevin@bracey.fi>

This series completes the crc32 helper acceleration by adding crc32_be.

There are plenty of users, for example OF.

To compensate for the extra supporting cruft in lib/crc32.c, a couple of minor
tidies.

Kevin Bracey (4):
  lib/crc32.c: remove unneeded casts
  lib/crc32.c: Make crc32_be weak for arch override
  lib/crc32test.c: correct printed bytes count
  arm64: accelerate crc32_be

 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 lib/crc32.c            | 14 +++----
 lib/crc32test.c        |  2 +-
 3 files changed, 80 insertions(+), 23 deletions(-)

-- 
2.25.1



From kevin at bracey.fi  Wed Jan 12 22:41:15 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 08:41:15 +0200
Subject: [PATCH 1/4] lib/crc32.c: remove unneeded casts
In-Reply-To: <20220113064118.1580916-1-kevin@bracey.fi>
References: <20220113064118.1580916-1-kevin@bracey.fi>
Message-ID: <20220113064118.1580916-2-kevin@bracey.fi>

Casts were added in 8f243af42ade ("sections: fix const sections for
crc32 table") to cope with the tables not being const. They are no
longer required since f5e38b9284e1 ("lib: crc32: constify crc32 lookup
table").

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 2a68dfd3b96c..7f062a2639df 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -194,13 +194,11 @@ u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_le, CRC32_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32table_le, CRC32_POLY_LE);
 }
 u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
 EXPORT_SYMBOL(crc32_le);
@@ -339,8 +337,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_be_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_be, CRC32_POLY_BE);
+	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
 #endif
 EXPORT_SYMBOL(crc32_be);
-- 
2.25.1



From kevin at bracey.fi  Wed Jan 12 22:41:16 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 08:41:16 +0200
Subject: [PATCH 2/4] lib/crc32.c: Make crc32_be weak for arch override
In-Reply-To: <20220113064118.1580916-1-kevin@bracey.fi>
References: <20220113064118.1580916-1-kevin@bracey.fi>
Message-ID: <20220113064118.1580916-3-kevin@bracey.fi>

crc32_le and __crc32c_le can be overridden - extend this to crc32_be.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 7f062a2639df..5649847d0a8d 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -206,6 +206,7 @@ EXPORT_SYMBOL(__crc32c_le);
 
 u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
+u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
 
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
@@ -330,12 +331,12 @@ static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
 }
 
 #if CRC_BE_BITS == 1
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, NULL, CRC32_POLY_BE);
 }
 #else
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
-- 
2.25.1



From kevin at bracey.fi  Wed Jan 12 22:41:17 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 08:41:17 +0200
Subject: [PATCH 3/4] lib/crc32test.c: correct printed bytes count
In-Reply-To: <20220113064118.1580916-1-kevin@bracey.fi>
References: <20220113064118.1580916-1-kevin@bracey.fi>
Message-ID: <20220113064118.1580916-4-kevin@bracey.fi>

crc32c_le self test had a stray multiply by two inherited from
the crc32_le+crc32_be test loop.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/crc32test.c b/lib/crc32test.c
index 61ddce2cff77..9b4af79412c4 100644
--- a/lib/crc32test.c
+++ b/lib/crc32test.c
@@ -675,7 +675,7 @@ static int __init crc32c_test(void)
 
 	/* pre-warm the cache */
 	for (i = 0; i < 100; i++) {
-		bytes += 2*test[i].length;
+		bytes += test[i].length;
 
 		crc ^= __crc32c_le(test[i].crc, test_buf +
 		    test[i].start, test[i].length);
-- 
2.25.1



From kevin at bracey.fi  Wed Jan 12 22:41:18 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 08:41:18 +0200
Subject: [PATCH 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220113064118.1580916-1-kevin@bracey.fi>
References: <20220113064118.1580916-1-kevin@bracey.fi>
Message-ID: <20220113064118.1580916-5-kevin@bracey.fi>

It makes no sense to leave crc32_be using the generic code while we
only accelerate the little-endian ops.

Even though the big-endian form doesn't fit as smoothly into the arm64,
we can speed it up and avoid hitting the D cache.

Tested on Cortex-A53. Without acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 192240 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21360 nsec

With acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 53480 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21480 nsec

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
index 0f9e10ecda23..906210441d76 100644
--- a/arch/arm64/lib/crc32.S
+++ b/arch/arm64/lib/crc32.S
@@ -11,7 +11,44 @@
 
 	.arch		armv8-a+crc
 
-	.macro		__crc32, c
+	.macro		byteorder, reg, be
+	.if \be
+CPU_LE( rev		\reg, \reg	)
+	.else
+CPU_BE( rev		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		byteorder16, reg, be
+	.if \be
+CPU_LE( rev16		\reg, \reg	)
+	.else
+CPU_BE( rev16		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		bitorder, reg, be
+	.if \be
+	rbit		\reg, \reg
+	.endif
+	.endm
+
+	.macro		bitorder16, reg, be
+	.if \be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #16
+	.endif
+	.endm
+
+	.macro		bitorder8, reg, be
+	.if \be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #24
+	.endif
+	.endm
+
+	.macro		__crc32, c, be=0
+	bitorder	w0, \be
 	cmp		x2, #16
 	b.lt		8f			// less than 16 bytes
 
@@ -24,10 +61,14 @@
 	add		x8, x8, x1
 	add		x1, x1, x7
 	ldp		x5, x6, [x8]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 
 	tst		x7, #8
 	crc32\c\()x	w8, w0, x3
@@ -55,33 +96,43 @@ CPU_BE(	rev		x6, x6		)
 32:	ldp		x3, x4, [x1], #32
 	sub		x2, x2, #32
 	ldp		x5, x6, [x1, #-16]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 	crc32\c\()x	w0, w0, x3
 	crc32\c\()x	w0, w0, x4
 	crc32\c\()x	w0, w0, x5
 	crc32\c\()x	w0, w0, x6
 	cbnz		x2, 32b
-0:	ret
+0:	bitorder	w0, \be
+	ret
 
 8:	tbz		x2, #3, 4f
 	ldr		x3, [x1], #8
-CPU_BE(	rev		x3, x3		)
+	byteorder	x3, \be
+	bitorder	x3, \be
 	crc32\c\()x	w0, w0, x3
 4:	tbz		x2, #2, 2f
 	ldr		w3, [x1], #4
-CPU_BE(	rev		w3, w3		)
+	byteorder	w3, \be
+	bitorder	w3, \be
 	crc32\c\()w	w0, w0, w3
 2:	tbz		x2, #1, 1f
 	ldrh		w3, [x1], #2
-CPU_BE(	rev16		w3, w3		)
+	byteorder16	w3, \be
+	bitorder16	w3, \be
 	crc32\c\()h	w0, w0, w3
 1:	tbz		x2, #0, 0f
 	ldrb		w3, [x1]
+	bitorder8	w3, \be
 	crc32\c\()b	w0, w0, w3
-0:	ret
+0:	bitorder	w0, \be
+	ret
 	.endm
 
 	.align		5
@@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
 alternative_else_nop_endif
 	__crc32		c
 SYM_FUNC_END(__crc32c_le)
+
+	.align		5
+SYM_FUNC_START(crc32_be)
+alternative_if_not ARM64_HAS_CRC32
+	b		crc32_be_base
+alternative_else_nop_endif
+	__crc32		, 1
+SYM_FUNC_END(crc32_be)
-- 
2.25.1



From jiasheng at iscas.ac.cn  Wed Jan 12 22:56:36 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Thu, 13 Jan 2022 14:56:36 +0800
Subject: [PATCH] media: meson: vdec: potential dereference of null pointer
Message-ID: <20220113065636.1198072-1-jiasheng@iscas.ac.cn>

As the possible failure of the kzalloc(), the 'new_ts' could be NULL
pointer.
Therefore, it should be better to check it in order to avoid the
dereference of the NULL pointer.
Also, the caller esparser_queue() needs to deal with the return value of
the amvdec_add_ts().

Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
 drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
 drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
 drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..86ccc8937afc 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
 
 	offset = esparser_get_offset(sess);
 
-	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	if (ret) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return ret;
+	}
+
 	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
 		vb->timestamp, payload_size, offset, vbuf->flags);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index 203d7afa085d..7d2a75653250 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);
 
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
 	struct amvdec_timestamp *new_ts;
 	unsigned long flags;
 
 	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+	if (!new_ts)
+		return -ENOMEM;
+
 	new_ts->ts = ts;
 	new_ts->tc = tc;
 	new_ts->offset = offset;
@@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
 	spin_lock_irqsave(&sess->ts_spinlock, flags);
 	list_add_tail(&new_ts->list, &sess->timestamps);
 	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(amvdec_add_ts);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
 
 /**
-- 
2.25.1



From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:18 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:18 +0800
Subject: [PATCH v4 1/5] arm64: dts: mediatek: Correct uart clock of MT8192
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113065822.11809-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the uart clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index c7c7d4e017ae..cfb67cc40c2c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -327,7 +327,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11002000 0 0x1000>;
 			interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART0>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
@@ -337,7 +337,7 @@
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11003000 0 0x1000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&clk26m>, <&infracfg CLK_INFRA_UART1>;
 			clock-names = "baud", "bus";
 			status = "disabled";
 		};
-- 
2.18.0



From jiasheng at iscas.ac.cn  Wed Jan 12 22:59:28 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Thu, 13 Jan 2022 14:59:28 +0800
Subject: [PATCH v3] media: meson: vdec: potential dereference of null pointer
Message-ID: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>

As the possible failure of the kzalloc(), the 'new_ts' could be NULL
pointer.
Therefore, it should be better to check it in order to avoid the
dereference of the NULL pointer.
Also, the caller esparser_queue() needs to deal with the return value of
the amvdec_add_ts().

Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
Changelog

v1 -> v2

* Change 1. Change the return type of amvdec_add_ts from void to int.
* Change 2. Return -ENOMEN if alloc fail and return 0 if not.
* Change 3. Modify the caller to deal with the error.

v2 -> v3

* Change 1. Fix the indentation and refine the commit message.
---
 drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
 drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
 drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
index db7022707ff8..86ccc8937afc 100644
--- a/drivers/staging/media/meson/vdec/esparser.c
+++ b/drivers/staging/media/meson/vdec/esparser.c
@@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
 
 	offset = esparser_get_offset(sess);
 
-	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
+	if (ret) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return ret;
+	}
+
 	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
 		vb->timestamp, payload_size, offset, vbuf->flags);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
index 203d7afa085d..7d2a75653250 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.c
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
@@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
 }
 EXPORT_SYMBOL_GPL(amvdec_set_canvases);
 
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
 {
 	struct amvdec_timestamp *new_ts;
 	unsigned long flags;
 
 	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
+	if (!new_ts)
+		return -ENOMEM;
+
 	new_ts->ts = ts;
 	new_ts->tc = tc;
 	new_ts->offset = offset;
@@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
 	spin_lock_irqsave(&sess->ts_spinlock, flags);
 	list_add_tail(&new_ts->list, &sess->timestamps);
 	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
+	return 0;
 }
 EXPORT_SYMBOL_GPL(amvdec_add_ts);
 
diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
index 88137d15aa3a..4bf3e61d081b 100644
--- a/drivers/staging/media/meson/vdec/vdec_helpers.h
+++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
@@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
  * @offset: offset in the VIFIFO where the associated packet was written
  * @flags: the vb2_v4l2_buffer flags
  */
-void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
-		   struct v4l2_timecode tc, u32 offset, u32 flags);
+int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
+		  struct v4l2_timecode tc, u32 offset, u32 flags);
 void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
 
 /**
-- 
2.25.1



From jernej.skrabec at gmail.com  Wed Jan 12 22:59:54 2022
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 13 Jan 2022 07:59:54 +0100
Subject: [linux-sunxi] [PATCH RESEND v3] arm64: dts: allwinner: a64:
 olinuxino: Enable audio
In-Reply-To: <2e1a6b23-e713-7f2b-3634-5aa9b7724a50@inventati.org>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
 <Yd6axIURzudUq5Ah@plaes.org>
 <2e1a6b23-e713-7f2b-3634-5aa9b7724a50@inventati.org>
Message-ID: <5782735.lOV4Wx5bFT@jernej-laptop>

Hi,

Dne sreda, 12. januar 2022 ob 16:29:51 CET je Philip Rinn napisal(a):
> Hi,
> 
> On 12.01.22 at 10:09, Priit Laes wrote:
> 
> > On Tue, Jan 11, 2022 at 09:08:23PM +0100, 'Philip Rinn' via linux-sunxi
> > wrote:
> 
> >> Enable the audio hardware on the Olimex A64-OLinuXino board family.
> >> Tested on the A64-OLinuXino-2Ge8G-IND variant.
> > 
> > 
> > I have similar patch in one of my "long forgotten branches", but I'm not
> > 100%
 sure whether the cpvdd-supply is required for codec_analog. IIRC,
> > sound worked for me without the issues on A64-Olinuxino board (Rev D).
> > 
> > 'cpvdd-supply = <&reg_eldo1>' for codec_analog
> 
> 
> I didn't test it without but as it is present for all other a64 board with
> audio and also in Olimex' tree I think it is needed.

It's not question if it works with or without it, nor if other boards have it 
or not. Only deciding factor is board design. On schematic it can be seen that 
cpvdd is connected to eldo1, so having this property is correct, mandatory 
even.

Best regards,
Jernej
 
> 
> > And we also need to enable these configuration options in the defconfig:
> > 
> > +CONFIG_SND_SUN8I_CODEC=m
> > +CONFIG_SND_SUN50I_CODEC_ANALOG=m
> 
> 
> Hm, probably, but why wasn't it added when audio was added for the other a64
> boards? Or are we talking about different defconfigs here?
 
> Best regards
> Philip






From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:20 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:20 +0800
Subject: [PATCH v4 3/5] arm64: dts: mediatek: Correct Nor Flash clock of MT8192
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113065822.11809-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the Nor Flash clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 47d056cc5dad..8584a20440c5 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -464,10 +464,12 @@
 			compatible = "mediatek,mt8192-nor";
 			reg = <0 0x11234000 0 0xe0>;
 			interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_SFLASH_SEL>,
+				 <&infracfg CLK_INFRA_FLASHIF_SFLASH>,
+				 <&infracfg CLK_INFRA_FLASHIF_TOP_H_133M>;
 			clock-names = "spi", "sf", "axi";
+			assigned-clocks = <&topckgen CLK_TOP_SFLASH_SEL>;
+			assigned-clock-parents = <&clk26m>;
 			#address-cells = <1>;
 			#size-cells = <0>;
 			status = "disable";
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:21 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:21 +0800
Subject: [PATCH v4 4/5] arm64: dts: mediatek: Correct I2C clock of MT8192
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113065822.11809-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the I2C clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 30 ++++++++++++++++--------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 8584a20440c5..1eb5874c09a9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -486,7 +486,8 @@
 			reg = <0 0x11cb0000 0 0x1000>,
 			      <0 0x10217300 0 0x80>;
 			interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_e CLK_IMP_IIC_WRAP_E_I2C3>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -505,7 +506,8 @@
 			reg = <0 0x11d00000 0 0x1000>,
 			      <0 0x10217600 0 0x180>;
 			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -518,7 +520,8 @@
 			reg = <0 0x11d01000 0 0x1000>,
 			      <0 0x10217780 0 0x180>;
 			interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C8>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -531,7 +534,8 @@
 			reg = <0 0x11d02000 0 0x1000>,
 			      <0 0x10217900 0 0x180>;
 			interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C9>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -550,7 +554,8 @@
 			reg = <0 0x11d20000 0 0x1000>,
 			      <0 0x10217100 0 0x80>;
 			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C1>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -563,7 +568,8 @@
 			reg = <0 0x11d21000 0 0x1000>,
 			      <0 0x10217180 0 0x180>;
 			interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C2>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -576,7 +582,8 @@
 			reg = <0 0x11d22000 0 0x1000>,
 			      <0 0x10217380 0 0x180>;
 			interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_ws CLK_IMP_IIC_WRAP_WS_I2C4>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -595,7 +602,8 @@
 			reg = <0 0x11e00000 0 0x1000>,
 			      <0 0x10217500 0 0x80>;
 			interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C5>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -614,7 +622,8 @@
 			reg = <0 0x11f00000 0 0x1000>,
 			      <0 0x10217080 0 0x80>;
 			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C0>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
@@ -627,7 +636,8 @@
 			reg = <0 0x11f01000 0 0x1000>,
 			      <0 0x10217580 0 0x80>;
 			interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>, <&clk26m>;
+			clocks = <&imp_iic_wrap_n CLK_IMP_IIC_WRAP_N_I2C6>,
+				 <&infracfg CLK_INFRA_AP_DMA>;
 			clock-names = "main", "dma";
 			clock-div = <1>;
 			#address-cells = <1>;
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:19 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:19 +0800
Subject: [PATCH v4 2/5] arm64: dts: mediatek: Correct SPI clock of MT8192
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113065822.11809-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the SPI clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 48 ++++++++++++------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index cfb67cc40c2c..47d056cc5dad 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -355,9 +355,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1100a000 0 0x1000>;
 			interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI0>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -369,9 +369,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11010000 0 0x1000>;
 			interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI1>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -383,9 +383,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11012000 0 0x1000>;
 			interrupts = <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI2>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -397,9 +397,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11013000 0 0x1000>;
 			interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI3>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -411,9 +411,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11018000 0 0x1000>;
 			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI4>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -425,9 +425,9 @@
 			#size-cells = <0>;
 			reg = <0 0x11019000 0 0x1000>;
 			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI5>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -439,9 +439,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101d000 0 0x1000>;
 			interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI6>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
@@ -453,9 +453,9 @@
 			#size-cells = <0>;
 			reg = <0 0x1101e000 0 0x1000>;
 			interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>,
-				 <&clk26m>,
-				 <&clk26m>;
+			clocks = <&topckgen CLK_TOP_MAINPLL_D5_D4>,
+				 <&topckgen CLK_TOP_SPI_SEL>,
+				 <&infracfg CLK_INFRA_SPI7>;
 			clock-names = "parent-clk", "sel-clk", "spi-clk";
 			status = "disabled";
 		};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:17 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:17 +0800
Subject: [PATCH v4 0/5] Update MT8192 Clock Setting
Message-ID: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is base on v5.16-rc8,

changes since v3:
 - update that list(remove already upstream patch)

changes since v2:
 - add missing "clock" at the end of commit message

changes since v1:
 - update the commit message

Allen-KH Cheng (5):
  arm64: dts: mediatek: Correct uart clock of MT8192
  arm64: dts: mediatek: Correct SPI clock of MT8192
  arm64: dts: mediatek: Correct Nor Flash clock of MT8192
  arm64: dts: mediatek: Correct I2C clock of MT8192
  arm64: dts: mediatek: Correct system timer clock of MT8192

 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++-----------
 1 file changed, 52 insertions(+), 40 deletions(-)

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Wed Jan 12 22:58:22 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 14:58:22 +0800
Subject: [PATCH v4 5/5] arm64: dts: mediatek: Correct system timer clock of
 MT8192
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113065822.11809-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
clock driver for mt8192 was not yet upstream, so the clock property nodes
were set to the clk26m clock as a placeholder.

Given that the clock driver has since been added through 710573dee31b ("clk:
mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
clock controllers"), fix the systimer clock property to point to the actual
clock.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8192.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
index 1eb5874c09a9..4f6c4ce885af 100644
--- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -312,7 +312,7 @@
 				     "mediatek,mt6765-timer";
 			reg = <0 0x10017000 0 0x1000>;
 			interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&clk26m>;
+			clocks = <&topckgen CLK_TOP_CSW_F26M_D2>;
 			clock-names = "clk13m";
 		};
 
-- 
2.18.0



From jernej.skrabec at gmail.com  Wed Jan 12 23:09:01 2022
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Thu, 13 Jan 2022 08:09:01 +0100
Subject: [PATCH] pinctrl: sunxi: Fix H616 I2S3 pin data
In-Reply-To: <20220105172952.23347-1-andre.przywara@arm.com>
References: <20220105172952.23347-1-andre.przywara@arm.com>
Message-ID: <4368018.LvFx2qVVIh@jernej-laptop>

Hi Andre!

Dne sreda, 05. januar 2022 ob 18:29:52 CET je Andre Przywara napisal(a):
> Two bugs have sneaked in the H616 pinctrl data:
> - PH9 uses the mux value of 0x3 twice (one should be 0x5 instead)
> - PH8 and PH9 use the "i2s3" function name twice in each pin
> 
> For the double pin name we use the same trick we pulled for i2s0: append
> the pin function to the group name to designate the special function.
> 
> Fixes: 25adc29407fb ("pinctrl: sunxi: Add support for the Allwinner H616 pin
> controller") Reported-by: SASANO Takayoshi <uaa at mx5.nisiq.net>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Reviewed-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej




From ming.qian at nxp.com  Wed Jan 12 23:18:55 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Thu, 13 Jan 2022 07:18:55 +0000
Subject: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
 skip
In-Reply-To: <8984f8a3c0dfd3a5f83fb5cc7b0357dca4787274.camel@ndufresne.ca>
References: <cover.1631002447.git.ming.qian@nxp.com>
 <647f84c1e7c2a48d6492d38fa4f06586235500b8.1631002447.git.ming.qian@nxp.com>
 <fffd24d3374ecb2fbfafa9b85fa0ef8012fc7efa.camel@ndufresne.ca>
 <AM6PR04MB634124118288EC775F05AFC3E7D59@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <8984f8a3c0dfd3a5f83fb5cc7b0357dca4787274.camel@ndufresne.ca>
Message-ID: <AM6PR04MB63417E126287421BCA133514E7539@AM6PR04MB6341.eurprd04.prod.outlook.com>

Hi Nicolas,

   I have question about skip event or similar concepts.
If the client control the input frame count, and it won't queue any more frames unless some frame is decoded.
But after seek, There is no requirement to begin queuing coded data starting exactly from a resume point (e.g. SPS or a keyframe). Any queued OUTPUT buffers will be processed and returned to the client until a suitable resume point is found. While looking for a resume point, the decoder should not produce any decoded frames into CAPTURE buffers.

So client may have queued some frames but without any resume point, in this case the decoder won't produce any decoded frames into CAPTURE buffers, and the client won't queue frames into output buffers. This creates some kind of deadlock.

In our previous solution, we send skip event to client to tell it that some frame is skipped instead of decoded, then the client can continue to queue frames.
But the skip event is flawed, so we need some solution to resolve it.
1. decoder can produce an empty buffer with V4L2_BUF_FLAG_SKIPPED (or V4L2_BUF_FLAG_ERROR) as you advised, but this seems to conflict with the above description in specification.
2. Define a notification mechanism to notify the client

Can you give some advice?  This constraint of frame depth is common on android

Ming

> > > > +    * - ``V4L2_EVENT_SKIP``
> > > > +      - 8
> > > > +      - This event is triggered when one frame is decoded, but it
> > > > + won't
> > > > be
> > > outputed
> > > > +     to the display. So the application can't get this frame, and
> > > > + the
> > > > input
> > > frame count
> > > > +     is dismatch with the output frame count. And this evevt is
> > > > + telling
> > > > the
> > > client to
> > > > +     handle this case.
> > >
> > > Similar to my previous comment, this event is flawed, since
> > > userspace cannot know were the skip is located in the queued
> > > buffers. Currently, all decoders are mandated to support
> > > V4L2_BUF_FLAG_TIMESTAMP_COPY. The timestamp must NOT be
> interpreted
> > > by the driver and must be reproduce as-is in the associated CAPTURE
> > > buffer. It is possible to "garbage" collect skipped frames with this
> > > method, though tedious.
> > >
> > > An alternative, and I think it would be much nicer then this, would
> > > be to use the v4l2_buffer.sequence counter, and just make it skip 1
> > > on skips. Though, the down side is that userspace must also know how
> > > to reorder frames (a driver job for stateless codecs) in order to
> > > identify which frame was skipped. So this is perhaps not that
> > > useful, other then knowing something was skipped in the past.
> > >
> > > A third option would be to introduce V4L2_BUF_FLAG_SKIPPED. This way
> > > the driver could return an empty payload (bytesused = 0) buffer with
> > > this flag set, and the proper timestamp properly copied. This would
> > > let the driver communicate skipped frames in real-time. Note that
> > > this could break with existing userspace, so it would need to be
> > > opted-in somehow (a control or some flags).
> >
> > Hi Nicolas,
> >    The problem we meet is that userspace doesn't care which frame is
> > skipped, it just need to know that there are a frame is skipped, the
> > driver should promise the input frame count is equals to the output frame
> count.
> >     Your first method is possible in theory, but we find the timestamp
> > may be unreliable, we meet many timestamp issues that userspace may
> > enqueue invalid timestamp or repeated timestamp and so on, so we can't
> accept this solution.
> 
> The driver should not interpret the provided timestamp, so it should not be
> able to say if the timestamp is valid or not, this is not the driver's task.
> 
> The driver task is to match the timestamp to the CAPTURE buffer (if that buffer
> was produced), and reproduce it exactly.
> 
> >     I think your second option is better. And there are only 1
> > question, we find some application prefer to use the V4L2_EVENT_EOS to
> > check the eos, not checking the empty buffer, if we use this method to
> > check skipped frame, the
> 
> Checking the empty buffer is a legacy method, only available in Samsung MFC
> driver. The spec says that the last buffer should be flagged with _LAST, and any
> further attempt to poll should unblock and DQBUF return EPIPE.
> 
> > application should check empty buffer instead of V4L2_EVENT_EOS,
> > otherwise if the last frame is skipped, the application will miss it.
> > Of course this is not a problem, it just increases the complexity of
> > the userspace implementation
> 
> The EPIPE mechanism covers this issue, which we initially had with the LAST
> flag.
> 
> >     I don't think your third method is feasible, the reasons are as below
> >               1. usually the empty payload means eos, and as you say,
> > it may introduce confusion.
> >       2. The driver may not have the opportunity to return an empty
> > payload during decoding, in our driver, driver will pass the capture
> > buffer to firmware, and when some frame is skipped, the firmware won't
> > return the buffer, driver may not find an available capture buffer to
> > return to userspace.
> >
> >    The requirement is that userspace need to match the input frame
> > count and output frame count. It doesn't care which frame is skipped,
> > so the V4L2_EVENT_SKIP is the easiest way for driver and userspace.
> >    If you think this event is really inappropriate, I prefer to adopt
> > your second option
> 
> Please, drop SKIP from you driver and this patchset and fix your draining
> process handling to follow the spec. The Samsung OMX component is
> irrelevant to mainline submission, the OMX code should be updated to follow
> the spec.
> 
> >

From jirislaby at kernel.org  Wed Jan 12 23:25:49 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Thu, 13 Jan 2022 08:25:49 +0100
Subject: [PATCH V5 2/5] tty: serial: meson: Move request the register
 region.
In-Reply-To: <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>
References: <20220110104214.25321-1-yu.tu@amlogic.com>
 <20220110104214.25321-3-yu.tu@amlogic.com>
 <01066e66-5d97-ab40-b4a6-99e962b47073@kernel.org>
 <cad33ab0-26d3-5b78-3bcf-62217aa70871@amlogic.com>
Message-ID: <efce614d-c8e6-bb06-e3c1-cb67b26bbc6a@kernel.org>

On 11. 01. 22, 3:48, Yu Tu wrote:
>> And no, do not resend a new version in the next few days. Having v5 in 
>> 20 days is a bit too much. Give maintainers and reviewers some more 
>> space to express themselves.
> I am so sorry if PATCH is sent too frequently, which has disturbed you.
> How often should I send it? Or under what circumstances can I send the 
> next version?

~ one week after the last reply to your previous patchset is about fine. 
You could see that people were still responding to v4 while v5 was 
already on the list.

thanks,
-- 
js


From lkp at intel.com  Wed Jan 12 23:54:26 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 15:54:26 +0800
Subject: [PATCH v5 08/13] peci: Add support for PECI device drivers
In-Reply-To: <20220112230247.982212-9-iwona.winiarska@intel.com>
References: <20220112230247.982212-9-iwona.winiarska@intel.com>
Message-ID: <202201131534.HcDrC30f-lkp@intel.com>

Hi Iwona,

I love your patch! Perhaps something to improve:

[auto build test WARNING on groeck-staging/hwmon-next]
[also build test WARNING on linux/master linus/master v5.16 next-20220112]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Iwona-Winiarska/Introduce-PECI-subsystem/20220113-071131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: hexagon-randconfig-r033-20220113 (https://download.01.org/0day-ci/archive/20220113/202201131534.HcDrC30f-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project d1021978b8e7e35dcc30201ca1731d64b5a602a8)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/0c9888d465568adc8526df1407c9a75be5ce6cd4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Iwona-Winiarska/Introduce-PECI-subsystem/20220113-071131
        git checkout 0c9888d465568adc8526df1407c9a75be5ce6cd4
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/peci/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/peci/request.c:111:23: warning: address of array 'req->rx.buf' will always evaluate to 'true' [-Wpointer-bool-conversion]
           if (WARN_ON(!req->rx.buf))
                       ~~~~~~~~~^~~
   include/asm-generic/bug.h:121:25: note: expanded from macro 'WARN_ON'
           int __ret_warn_on = !!(condition);                              \
                                  ^~~~~~~~~
   1 warning generated.


vim +111 drivers/peci/request.c

   101	
   102	static int peci_request_xfer_retry(struct peci_request *req)
   103	{
   104		long wait_interval = PECI_RETRY_INTERVAL_MIN;
   105		struct peci_device *device = req->device;
   106		struct peci_controller *controller = to_peci_controller(device->dev.parent);
   107		unsigned long start = jiffies;
   108		int ret;
   109	
   110		/* Don't try to use it for ping */
 > 111		if (WARN_ON(!req->rx.buf))
   112			return 0;
   113	
   114		do {
   115			ret = peci_request_xfer(req);
   116			if (ret) {
   117				dev_dbg(&controller->dev, "xfer error: %d\n", ret);
   118				return ret;
   119			}
   120	
   121			if (peci_request_status(req) != -EAGAIN)
   122				return 0;
   123	
   124			/* Set the retry bit to indicate a retry attempt */
   125			req->tx.buf[1] |= PECI_RETRY_BIT;
   126	
   127			if (schedule_timeout_interruptible(wait_interval))
   128				return -ERESTARTSYS;
   129	
   130			wait_interval = min_t(long, wait_interval * 2, PECI_RETRY_INTERVAL_MAX);
   131		} while (time_before(jiffies, start + PECI_RETRY_TIMEOUT));
   132	
   133		dev_dbg(&controller->dev, "request timed out\n");
   134	
   135		return -ETIMEDOUT;
   136	}
   137	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From axe.yang at mediatek.com  Wed Jan 12 23:58:52 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Thu, 13 Jan 2022 15:58:52 +0800
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
 <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
Message-ID: <83670f12a4eda1d8aecde3c0bf225642106d1267.camel@mediatek.com>


Andy, thank you for the review.
But for the comment for 'dev_dbg', can you explain more about that?

On Tue, 2022-01-11 at 13:46 +0200, Andy Shevchenko wrote:
> On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:
> > Add support for eint irq when MSDC is used as an SDIO host. This
> 
> IRQ
> 
> > feature requires SDIO device support async irq function. With this
> 
> IRQ
> 
> > feature,SDIO host can be awakened by SDIO card in suspend state,
> 
> feature, SDIO
> 
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in msdc node
> 
> MSDC
> 
> > to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
> 
> IRQ
> 
> > are mandatory. And cap-sdio-async-irq flag is necessary since this
> > feature depends on asynchronous interrupt:
> >         &mmcX {
> >                 ...
> >                 pinctrl-names = "default", "state_uhs",
> > "state_eint",
> >                                 "state_dat1";
> >                 ...
> >                 pinctrl-2 = <&mmc2_pins_eint>;
> >                 pinctrl-3 = <&mmc2_pins_dat1>;
> >                 ...
> >                 cap-sdio-async-irq;
> >                 ...
> >         };
> 
> ...
> 
> > - * Copyright (c) 2014-2015 MediaTek Inc.
> > + * Copyright (c) 2014-2022 MediaTek Inc.
> 
> Shouldn't it be rather like
> 
>  * Copyright (c) 2014-2015,2022 MediaTek Inc.
> 
> ?
> 
> ...
> 
> > +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> > +{
> > +	unsigned long flags;
> > +	struct msdc_host *host = (struct msdc_host *)dev_id;
> 
> No casting is needed.
> 
> > +	struct mmc_host *mmc = mmc_from_priv(host);
> 
> Perhaps reversed xmas tree order
> 
> 	struct msdc_host *host = dev_id;
> 	struct mmc_host *mmc = mmc_from_priv(host);
> 	unsigned long flags;
> 
> ?
> 
> But hey, why do you need flags?
> 
> > +	spin_lock_irqsave(&host->lock, flags);
> > +	if (likely(host->sdio_irq_cnt > 0)) {
> > +		disable_irq_nosync(host->eint_irq);
> > +		disable_irq_wake(host->eint_irq);
> > +		host->sdio_irq_cnt--;
> > +	}
> > +	spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +	sdio_signal_irq(mmc);
> > +
> > +	return IRQ_HANDLED;
> > +}
> 
> ...
> 
> > +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> > +{
> > +	struct gpio_desc *desc;
> > +	int irq, ret;
> > +
> > +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> > +	if (IS_ERR(desc))
> > +		return PTR_ERR(desc);
> > +
> > +	ret = gpiod_to_irq(desc);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	irq = ret;
> > +	ret = devm_request_threaded_irq(host->dev, irq, NULL,
> > msdc_sdio_eint_irq,
> > +					IRQF_TRIGGER_LOW | IRQF_ONESHOT
> > | IRQF_NO_AUTOEN,
> > +					"sdio-eint", host);
> > +
> 
> Redundant blank line.
> 
> > +	if (!ret)
> > +		host->eint_irq = irq;
> > +
> > +	return ret;
> 
> I guess I have already commented on this, i.e. use standard pattern
> 
> 	if (ret)
> 		return ret;
> 
> 	...
> 	return 0;
> 
> > +}
> 
> ...
> 
> > +		host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> > "state_eint");
> > +		if (IS_ERR(host->pins_eint)) {
> > +			dev_dbg(&pdev->dev, "Cannot find pinctrl
> > eint!\n");
> 
> In debug mode of pin control this will bring a duplicate message.

Can you explain more about this comment? 
I don't understand what the 'duplicate message' refers for.

> 
> > +		} else {
> > +			host->pins_dat1 = pinctrl_lookup_state(host-
> > >pinctrl, "state_dat1");
> > +			if (IS_ERR(host->pins_dat1)) {
> > +				ret = dev_err_probe(&pdev->dev,
> > PTR_ERR(host->pins_dat1),
> > +						    "Cannot find
> > pinctrl dat1!\n");
> > +				goto host_free;
> > +			}
> > +
> > +			host->sdio_eint_ready = true;
> > +		}
> > +	}
> 
> 

From kavyasree.kotagiri at microchip.com  Thu Jan 13 00:00:17 2022
From: kavyasree.kotagiri at microchip.com (Kavyasree Kotagiri)
Date: Thu, 13 Jan 2022 13:30:17 +0530
Subject: [PATCH v3] ARM: dts: add DT for lan966x SoC and 2-port board pcb8291
Message-ID: <20220113080017.30155-1-kavyasree.kotagiri@microchip.com>

This patch adds basic DT for Microchip lan966x SoC and associated board
pcb8291(2-port EVB). Adds peripherals required to allow booting: IRQs,
clocks, timers, memory, flexcoms, GPIOs. Also adds other peripherals like
crypto(AES,SHA), DMA and watchdog.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
---
v2 -> v3:
- Enabling trng in dtsi itself.
- Removed "status=okay" dma0.
- Add gpio pin settings for can0(missed adding this in previous version)

v1 -> v2:
- Moved flx3 usart0 node to dtsi file.
- Removed status="okay" for dma0 to maintain consistency across nodes
  (which means enabling dma0 by default)

 arch/arm/boot/dts/Makefile            |   2 +
 arch/arm/boot/dts/lan966x.dtsi        | 242 ++++++++++++++++++++++++++
 arch/arm/boot/dts/lan966x_pcb8291.dts |  53 ++++++
 3 files changed, 297 insertions(+)
 create mode 100644 arch/arm/boot/dts/lan966x.dtsi
 create mode 100644 arch/arm/boot/dts/lan966x_pcb8291.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 235ad559acb2..2040a990f08c 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -735,6 +735,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
 dtb-$(CONFIG_SOC_IMX7ULP) += \
 	imx7ulp-com.dtb \
 	imx7ulp-evk.dtb
+dtb-$(CONFIG_SOC_LAN966) += \
+	lan966x_pcb8291.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
 	ls1021a-moxa-uc-8410a.dtb \
 	ls1021a-qds.dtb \
diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
new file mode 100644
index 000000000000..d7bc36a998bc
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x.dtsi
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x.dtsi - Device Tree Include file for Microchip LAN966x family SoC
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
+ *
+ * Author: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
+ *
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/microchip,lan966x.h>
+
+/ {
+	model = "Microchip LAN966x family SoC";
+	compatible = "microchip,lan966x";
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			clock-frequency = <600000000>;
+			reg = <0x0>;
+		};
+	};
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x40000000>;  /* 1GB */
+	};
+
+	clocks {
+		sys_clk: sys_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <162500000>;
+		};
+
+		cpu_clk: cpu_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <600000000>;
+		};
+
+		ddr_clk: ddr_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <300000000>;
+		};
+
+		nic_clk: nic_clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <200000000>;
+		};
+	};
+
+	clks: clock-controller at e00c00a8 {
+		compatible = "microchip,lan966x-gck";
+		#clock-cells = <1>;
+		clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
+		clock-names = "cpu", "ddr", "sys";
+		reg = <0xe00c00a8 0x38>;
+	};
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <37500000>;
+		arm,cpu-registers-not-fw-configured;
+	};
+
+	soc {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		flx0: flexcom at e0040000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0040000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0040000 0x800>;
+			status = "disabled";
+		};
+
+		flx1: flexcom at e0044000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0044000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM1>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0044000 0x800>;
+			status = "disabled";
+		};
+
+		trng: trng at e0048000 {
+			compatible = "atmel,at91sam9g45-trng";
+			reg = <0xe0048000 0x100>;
+			clocks = <&nic_clk>;
+		};
+
+		aes: aes at e004c000 {
+			compatible = "atmel,at91sam9g46-aes";
+			reg = <0xe004c000 0x100>;
+			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
+			       <&dma0 AT91_XDMAC_DT_PERID(12)>;
+			dma-names = "rx", "tx";
+			clocks = <&nic_clk>;
+			clock-names = "aes_clk";
+		};
+
+		flx2: flexcom at e0060000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0060000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM2>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0060000 0x800>;
+			status = "disabled";
+		};
+
+		flx3: flexcom at e0064000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0064000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM3>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0064000 0x800>;
+			status = "disabled";
+
+			usart0: serial at 200 {
+				compatible = "atmel,at91sam9260-usart";
+				reg = <0x200 0x200>;
+				interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&nic_clk>;
+				clock-names = "usart";
+				atmel,fifo-size = <32>;
+				status = "disabled";
+			};
+		};
+
+		dma0: dma-controller at e0068000 {
+			compatible = "microchip,sama7g5-dma";
+			reg = <0xe0068000 0x1000>;
+			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			clocks = <&nic_clk>;
+			clock-names = "dma_clk";
+		};
+
+		sha: sha at e006c000 {
+			compatible = "atmel,at91sam9g46-sha";
+			reg = <0xe006c000 0xec>;
+			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
+			dma-names = "tx";
+			clocks = <&nic_clk>;
+			clock-names = "sha_clk";
+		};
+
+		flx4: flexcom at e0070000 {
+			compatible = "atmel,sama5d2-flexcom";
+			reg = <0xe0070000 0x100>;
+			clocks = <&clks GCK_ID_FLEXCOM4>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0x0 0xe0070000 0x800>;
+			status = "disabled";
+		};
+
+		timer0: timer at e008c000 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0xe008c000 0x400>;
+			clocks = <&nic_clk>;
+			clock-names = "timer";
+			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		watchdog: watchdog at e0090000 {
+			compatible = "snps,dw-wdt";
+			reg = <0xe0090000 0x1000>;
+			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&nic_clk>;
+		};
+
+		can0: can at e081c000 {
+			compatible = "bosch,m_can";
+			reg = <0xe081c000 0xfc>, <0x00100000 0x4000>;
+			reg-names = "m_can", "message_ram";
+			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "int0", "int1";
+			clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
+			clock-names = "hclk", "cclk";
+			assigned-clocks = <&clks GCK_ID_MCAN0>;
+			assigned-clock-rates = <40000000>;
+			bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
+			status = "disabled";
+		};
+
+		gpio: pinctrl at e2004064 {
+			compatible = "microchip,lan966x-pinctrl";
+			reg = <0xe2004064 0xb4>,
+			    <0xe2010024 0x138>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&gpio 0 0 78>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <2>;
+		};
+
+		gic: interrupt-controller at e8c11000 {
+			compatible = "arm,gic-400", "arm,cortex-a7-gic";
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			reg = <0xe8c11000 0x1000>,
+			      <0xe8c12000 0x2000>,
+			      <0xe8c14000 0x2000>,
+			      <0xe8c16000 0x2000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts b/arch/arm/boot/dts/lan966x_pcb8291.dts
new file mode 100644
index 000000000000..cf54f42c763d
--- /dev/null
+++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * lan966x_pcb8291.dts - Device Tree file for PCB8291
+ */
+/dts-v1/;
+#include "lan966x.dtsi"
+
+/ {
+	model = "Microchip EVB - LAN9662";
+	compatible = "microchip,lan9662-pcb8291", "microchip,lan9662", "microchip,lan966";
+};
+
+&gpio {
+	fc_shrd7_pins: fc_shrd7-pins {
+		pins = "GPIO_49";
+		function = "fc_shrd7";
+	};
+
+	fc_shrd8_pins: fc_shrd8-pins {
+		pins = "GPIO_54";
+		function = "fc_shrd8";
+	};
+
+	fc3_b_pins: fcb3-spi-pins {
+		/* SCK, RXD, TXD */
+		pins = "GPIO_51", "GPIO_52", "GPIO_53";
+		function = "fc3_b";
+	};
+
+	can0_b_pins:  can0_b_pins {
+		/* RX, TX */
+		pins = "GPIO_35", "GPIO_36";
+		function = "can0_b";
+	};
+};
+
+&can0 {
+	pinctrl-0 = <&can0_b_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&flx3 {
+	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+	status = "okay";
+
+	usart0: serial at 200 {
+		pinctrl-0 = <&fc3_b_pins>, <&fc_shrd7_pins>, <&fc_shrd8_pins>;
+		pinctrl-names = "default";
+		status = "okay";
+	};
+};
+
-- 
2.17.1



From marcel.ziswiler at toradex.com  Thu Jan 13 00:07:11 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Thu, 13 Jan 2022 08:07:11 +0000
Subject: [PATCH v7 0/8] Add the imx8m pcie phy driver and imx8mm pcie
 support
In-Reply-To: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <8c11bbded57df020ba0897f7ad0295d60c9ee2cb.camel@toradex.com>

Hi Richard

On Thu, 2021-12-02 at 16:02 +0800, Richard Zhu wrote:
> Refer to the discussion [1] when try to enable i.MX8MM PCIe support,
> one standalone PCIe PHY driver should be seperated from i.MX PCIe
> driver when enable i.MX8MM PCIe support.
> 
> This patch-set adds the standalone PCIe PHY driver suport[1-5], and i.MX8MM
> PCIe support[6-8] to have whole view to review this patch-set.
> 
> The PCIe works on i.MX8MM EVK board based the the blkctrl power driver
> [2] and this patch-set. And tested by Tim and Marcel on the different
> reference clock modes boards.
> 
> [1] https://patchwork.ozlabs.org/project/linux-pci/patch/20210510141509.929120-3-l.stach at pengutronix.de/
> [2]
> https://patchwork.kernel.org/project/linux-arm-kernel/cover/20210910202640.980366-1-l.stach at pengutronix.de/
> 
> Main changes v6 --> v7:
> - Add "Reviewed-by: Rob Herring <robh at kernel.org>" into #2 patches.
> - Regarding Vinod's review comments do the following changes.
> ? - Don't build in the PHY driver in default.
> ? - Remove the extra blank line
> ? - Correct the license tag.
> 
> Main changes v5 --> v6:
> - Add "Reviewed-by: Rob Herring <robh at kernel.org>" into #1 and #3 patches.
> - Merge Rob's review comments to the #2 patch.
> 
> Main changes v4 --> v5:
> - Set the AUX_EN always 1b'1, thus it can fix the regression introduced in v4
> ? series on Marcel's board.
> - Use the lower-case letter in the devicetreee refer to Marcel's comments.
> - Since the default value of the deemphasis parameters are zero, only set
> ? the deemphasis registers when the input paramters are none zero.
> 
> Main changes v3 --> v4:
> - Update the yaml to fix syntax error, add maxitems and drop description of phy
> - Correct the clock name in PHY DT node.
> - Squash the EVK board relalted dts changes into one patch, and drop the
> ? useless dummy clock and gpio suffix in DT nodes.
> - Add board specific de-emphasis parameters as DT properties. Thus each board
> ? can specify its actual de-emphasis values.
> - Update the commit log of PHY driver.
> - Remove the useless codes from PCIe driver, since they are moved to PHY driver
> - After the discussion and verification of the CLKREQ# configurations with Tim,
> ? agree to add an optional boolean property "fsl,clkreq-unsupported", indicates
> ? the CLKREQ# signal is hooked or not in HW designs.
> - Add "Tested-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>" tag, since
> ? Marcel help to test the v3 patch-set.
> 
> Main changes v2 --> v3:
> - Regarding Lucas' comments.
> ?- to have a whole view to review the patches, send out the i.MX8MM PCIe support too.
> ?- move the PHY related bits manipulations of the GPR/SRC to standalone PHY driver.
> ?- split the dts changes to SOC and board DT, and use the enum instead of raw value.
> ?- update the license of the dt-binding header file.
> 
> Changes v1 --> v2:
> - Update the license of the dt-binding header file to make the license
> ? compatible with dts files.
> - Fix the dt_binding_check errors.
> 
> Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml??? |?? 6 +++
> Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml |? 92 +++++++++++++++++++++++++++++++
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi??????????????? |? 55 +++++++++++++++++++
> arch/arm64/boot/dts/freescale/imx8mm.dtsi??????????????????? |? 46 +++++++++++++++-
> drivers/pci/controller/dwc/pci-imx6.c??????????????????????? |? 83 +++++++++++++++++++++++++---
> drivers/phy/freescale/Kconfig??????????????????????????????? |?? 8 +++
> drivers/phy/freescale/Makefile?????????????????????????????? |?? 1 +
> drivers/phy/freescale/phy-fsl-imx8m-pcie.c?????????????????? | 236
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> include/dt-bindings/phy/phy-imx8-pcie.h????????????????????? |? 14 +++++
> 9 files changed, 532 insertions(+), 9 deletions(-)
> 
> [PATCH v7 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the
> [PATCH v7 2/8] dt-bindings: phy: Add imx8 pcie phy driver support
> [PATCH v7 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name
> [PATCH v7 4/8] arm64: dts: imx8mm: Add the pcie phy support
> [PATCH v7 5/8] phy: freescale: pcie: Initialize the imx8 pcie
> [PATCH v7 6/8] arm64: dts: imx8mm: Add the pcie support
> [PATCH v7 7/8] arm64: dts: imx8mm-evk: Add the pcie support on imx8mm
> [PATCH v7 8/8] PCI: imx: Add the imx8mm pcie support

What is the status of patches 4, 6 and 7? While the rest has been pulled those are still missing in today's -
next.

Cheers

Marcel

From allen-kh.cheng at mediatek.com  Thu Jan 13 00:21:01 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 16:21:01 +0800
Subject: [PATCH v13 0/2] Mediatek ADSP mailbox controller support for MT8195
Message-ID: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox registers to kick dsp.

Two mailboxes used to send notification or short message between processors with dsp

changes since v12:
- remove of_device_get_match_data ptr check:
  of_device_get_match_data(dev) will never going to return NULL.
  driver probe with compatible mediatek,mt8195-adsp-mbox.

changes since v11:
- remove unuseful MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error


Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 172 ++++++++++++++++++
 4 files changed, 233 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 13 00:21:02 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 16:21:02 +0800
Subject: [PATCH v13 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
References: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113082103.27911-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 13 00:21:03 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 16:21:03 +0800
Subject: [PATCH v13 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
References: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113082103.27911-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 172 +++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..ee131ed8b449
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	priv->cfg = of_device_get_match_data(dev);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 13 00:22:33 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 16:22:33 +0800
Subject: [PATCH v3 0/1] firmware: mtk: add adsp ipc protocol for sof
Message-ID: <20220113082234.29013-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch provides mtk adsp ipc support for sof.

ADSP IPC protocol offers (send/recv) interfaces using mediatek-mailbox APIs.

changes since v2:
- add out tag for two memroy free phases

changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove unuseful MODULE_LICENSE
- change label name to out_free

Allen-KH Cheng (1):
  firmware: mediatek: add adsp ipc protocol interface

 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 13 00:22:34 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Thu, 13 Jan 2022 16:22:34 +0800
Subject: [PATCH v3 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220113082234.29013-1-allen-kh.cheng@mediatek.com>
References: <20220113082234.29013-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220113082234.29013-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..faaf2b25a3bf
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *adsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	adsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(adsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * mbox_send_message returns non-negative value on success,
+	 * return zero for success
+	 */
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "wrong mbox chan %d \n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *adsp_ipc;
+	struct mtk_adsp_chan *adsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+	if (!adsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		adsp_chan = &adsp_ipc->chans[i];
+		cl = &adsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		adsp_chan->ipc = adsp_ipc;
+		adsp_chan->idx = i;
+		adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(adsp_chan->ch)) {
+			ret = PTR_ERR(adsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out_free;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	adsp_ipc->dev = dev;
+	dev_set_drvdata(dev, adsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out_free:
+	kfree(chan_name);
+out:
+	for (j = 0; j < i; j++) {
+		adsp_chan = &adsp_ipc->chans[j];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *adsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		adsp_chan = &adsp_ipc->chans[i];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From nicolas.ferre at microchip.com  Thu Jan 13 00:33:48 2022
From: nicolas.ferre at microchip.com (Nicolas Ferre)
Date: Thu, 13 Jan 2022 09:33:48 +0100
Subject: [PATCH v3] ARM: dts: add DT for lan966x SoC and 2-port board
 pcb8291
In-Reply-To: <20220113080017.30155-1-kavyasree.kotagiri@microchip.com>
References: <20220113080017.30155-1-kavyasree.kotagiri@microchip.com>
Message-ID: <f8b83cf0-7ebf-1ecd-b544-f0d0079d9dde@microchip.com>

On 13/01/2022 at 09:00, Kavyasree Kotagiri wrote:
> This patch adds basic DT for Microchip lan966x SoC and associated board
> pcb8291(2-port EVB). Adds peripherals required to allow booting: IRQs,
> clocks, timers, memory, flexcoms, GPIOs. Also adds other peripherals like
> crypto(AES,SHA), DMA and watchdog.
> 
> Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>

Looks good to me:
Reviewed-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Best regards,
   Nicolas


> ---
> v2 -> v3:
> - Enabling trng in dtsi itself.
> - Removed "status=okay" dma0.
> - Add gpio pin settings for can0(missed adding this in previous version)
> 
> v1 -> v2:
> - Moved flx3 usart0 node to dtsi file.
> - Removed status="okay" for dma0 to maintain consistency across nodes
>    (which means enabling dma0 by default)
> 
>   arch/arm/boot/dts/Makefile            |   2 +
>   arch/arm/boot/dts/lan966x.dtsi        | 242 ++++++++++++++++++++++++++
>   arch/arm/boot/dts/lan966x_pcb8291.dts |  53 ++++++
>   3 files changed, 297 insertions(+)
>   create mode 100644 arch/arm/boot/dts/lan966x.dtsi
>   create mode 100644 arch/arm/boot/dts/lan966x_pcb8291.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 235ad559acb2..2040a990f08c 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -735,6 +735,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
>   dtb-$(CONFIG_SOC_IMX7ULP) += \
>   	imx7ulp-com.dtb \
>   	imx7ulp-evk.dtb
> +dtb-$(CONFIG_SOC_LAN966) += \
> +	lan966x_pcb8291.dtb
>   dtb-$(CONFIG_SOC_LS1021A) += \
>   	ls1021a-moxa-uc-8410a.dtb \
>   	ls1021a-qds.dtb \
> diff --git a/arch/arm/boot/dts/lan966x.dtsi b/arch/arm/boot/dts/lan966x.dtsi
> new file mode 100644
> index 000000000000..d7bc36a998bc
> --- /dev/null
> +++ b/arch/arm/boot/dts/lan966x.dtsi
> @@ -0,0 +1,242 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * lan966x.dtsi - Device Tree Include file for Microchip LAN966x family SoC
> + *
> + * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries
> + *
> + * Author: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> + *
> + */
> +
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/mfd/atmel-flexcom.h>
> +#include <dt-bindings/dma/at91.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clock/microchip,lan966x.h>
> +
> +/ {
> +	model = "Microchip LAN966x family SoC";
> +	compatible = "microchip,lan966x";
> +	interrupt-parent = <&gic>;
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	cpus {
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a7";
> +			clock-frequency = <600000000>;
> +			reg = <0x0>;
> +		};
> +	};
> +
> +	memory at 60000000 {
> +		device_type = "memory";
> +		reg = <0x60000000 0x40000000>;  /* 1GB */
> +	};
> +
> +	clocks {
> +		sys_clk: sys_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <162500000>;
> +		};
> +
> +		cpu_clk: cpu_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <600000000>;
> +		};
> +
> +		ddr_clk: ddr_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <300000000>;
> +		};
> +
> +		nic_clk: nic_clk {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <200000000>;
> +		};
> +	};
> +
> +	clks: clock-controller at e00c00a8 {
> +		compatible = "microchip,lan966x-gck";
> +		#clock-cells = <1>;
> +		clocks = <&cpu_clk>, <&ddr_clk>, <&sys_clk>;
> +		clock-names = "cpu", "ddr", "sys";
> +		reg = <0xe00c00a8 0x38>;
> +	};
> +
> +	timer {
> +		compatible = "arm,armv7-timer";
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
> +			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
> +		clock-frequency = <37500000>;
> +		arm,cpu-registers-not-fw-configured;
> +	};
> +
> +	soc {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		flx0: flexcom at e0040000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe0040000 0x100>;
> +			clocks = <&clks GCK_ID_FLEXCOM0>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe0040000 0x800>;
> +			status = "disabled";
> +		};
> +
> +		flx1: flexcom at e0044000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe0044000 0x100>;
> +			clocks = <&clks GCK_ID_FLEXCOM1>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe0044000 0x800>;
> +			status = "disabled";
> +		};
> +
> +		trng: trng at e0048000 {
> +			compatible = "atmel,at91sam9g45-trng";
> +			reg = <0xe0048000 0x100>;
> +			clocks = <&nic_clk>;
> +		};
> +
> +		aes: aes at e004c000 {
> +			compatible = "atmel,at91sam9g46-aes";
> +			reg = <0xe004c000 0x100>;
> +			interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
> +			dmas = <&dma0 AT91_XDMAC_DT_PERID(13)>,
> +			       <&dma0 AT91_XDMAC_DT_PERID(12)>;
> +			dma-names = "rx", "tx";
> +			clocks = <&nic_clk>;
> +			clock-names = "aes_clk";
> +		};
> +
> +		flx2: flexcom at e0060000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe0060000 0x100>;
> +			clocks = <&clks GCK_ID_FLEXCOM2>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe0060000 0x800>;
> +			status = "disabled";
> +		};
> +
> +		flx3: flexcom at e0064000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe0064000 0x100>;
> +			clocks = <&clks GCK_ID_FLEXCOM3>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe0064000 0x800>;
> +			status = "disabled";
> +
> +			usart0: serial at 200 {
> +				compatible = "atmel,at91sam9260-usart";
> +				reg = <0x200 0x200>;
> +				interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
> +				clocks = <&nic_clk>;
> +				clock-names = "usart";
> +				atmel,fifo-size = <32>;
> +				status = "disabled";
> +			};
> +		};
> +
> +		dma0: dma-controller at e0068000 {
> +			compatible = "microchip,sama7g5-dma";
> +			reg = <0xe0068000 0x1000>;
> +			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
> +			#dma-cells = <1>;
> +			clocks = <&nic_clk>;
> +			clock-names = "dma_clk";
> +		};
> +
> +		sha: sha at e006c000 {
> +			compatible = "atmel,at91sam9g46-sha";
> +			reg = <0xe006c000 0xec>;
> +			interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
> +			dmas = <&dma0 AT91_XDMAC_DT_PERID(14)>;
> +			dma-names = "tx";
> +			clocks = <&nic_clk>;
> +			clock-names = "sha_clk";
> +		};
> +
> +		flx4: flexcom at e0070000 {
> +			compatible = "atmel,sama5d2-flexcom";
> +			reg = <0xe0070000 0x100>;
> +			clocks = <&clks GCK_ID_FLEXCOM4>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x0 0xe0070000 0x800>;
> +			status = "disabled";
> +		};
> +
> +		timer0: timer at e008c000 {
> +			compatible = "snps,dw-apb-timer";
> +			reg = <0xe008c000 0x400>;
> +			clocks = <&nic_clk>;
> +			clock-names = "timer";
> +			interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
> +		};
> +
> +		watchdog: watchdog at e0090000 {
> +			compatible = "snps,dw-wdt";
> +			reg = <0xe0090000 0x1000>;
> +			interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&nic_clk>;
> +		};
> +
> +		can0: can at e081c000 {
> +			compatible = "bosch,m_can";
> +			reg = <0xe081c000 0xfc>, <0x00100000 0x4000>;
> +			reg-names = "m_can", "message_ram";
> +			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
> +				     <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "int0", "int1";
> +			clocks = <&clks GCK_ID_MCAN0>, <&clks GCK_ID_MCAN0>;
> +			clock-names = "hclk", "cclk";
> +			assigned-clocks = <&clks GCK_ID_MCAN0>;
> +			assigned-clock-rates = <40000000>;
> +			bosch,mram-cfg = <0x0 0 0 64 0 0 32 32>;
> +			status = "disabled";
> +		};
> +
> +		gpio: pinctrl at e2004064 {
> +			compatible = "microchip,lan966x-pinctrl";
> +			reg = <0xe2004064 0xb4>,
> +			    <0xe2010024 0x138>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			gpio-ranges = <&gpio 0 0 78>;
> +			interrupt-controller;
> +			interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gic: interrupt-controller at e8c11000 {
> +			compatible = "arm,gic-400", "arm,cortex-a7-gic";
> +			#interrupt-cells = <3>;
> +			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-controller;
> +			reg = <0xe8c11000 0x1000>,
> +			      <0xe8c12000 0x2000>,
> +			      <0xe8c14000 0x2000>,
> +			      <0xe8c16000 0x2000>;
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/lan966x_pcb8291.dts b/arch/arm/boot/dts/lan966x_pcb8291.dts
> new file mode 100644
> index 000000000000..cf54f42c763d
> --- /dev/null
> +++ b/arch/arm/boot/dts/lan966x_pcb8291.dts
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * lan966x_pcb8291.dts - Device Tree file for PCB8291
> + */
> +/dts-v1/;
> +#include "lan966x.dtsi"
> +
> +/ {
> +	model = "Microchip EVB - LAN9662";
> +	compatible = "microchip,lan9662-pcb8291", "microchip,lan9662", "microchip,lan966";
> +};
> +
> +&gpio {
> +	fc_shrd7_pins: fc_shrd7-pins {
> +		pins = "GPIO_49";
> +		function = "fc_shrd7";
> +	};
> +
> +	fc_shrd8_pins: fc_shrd8-pins {
> +		pins = "GPIO_54";
> +		function = "fc_shrd8";
> +	};
> +
> +	fc3_b_pins: fcb3-spi-pins {
> +		/* SCK, RXD, TXD */
> +		pins = "GPIO_51", "GPIO_52", "GPIO_53";
> +		function = "fc3_b";
> +	};
> +
> +	can0_b_pins:  can0_b_pins {
> +		/* RX, TX */
> +		pins = "GPIO_35", "GPIO_36";
> +		function = "can0_b";
> +	};
> +};
> +
> +&can0 {
> +	pinctrl-0 = <&can0_b_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +};
> +
> +&flx3 {
> +	atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
> +	status = "okay";
> +
> +	usart0: serial at 200 {
> +		pinctrl-0 = <&fc3_b_pins>, <&fc_shrd7_pins>, <&fc_shrd8_pins>;
> +		pinctrl-names = "default";
> +		status = "okay";
> +	};
> +};
> +
> 


-- 
Nicolas Ferre


From narmstrong at baylibre.com  Thu Jan 13 00:56:08 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 09:56:08 +0100
Subject: [PATCH v3] media: meson: vdec: potential dereference of null
 pointer
In-Reply-To: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>
References: <20220113065928.1198125-1-jiasheng@iscas.ac.cn>
Message-ID: <9790448d-53bb-cc61-655e-dda70ae97fa3@baylibre.com>

On 13/01/2022 07:59, Jiasheng Jiang wrote:
> As the possible failure of the kzalloc(), the 'new_ts' could be NULL
> pointer.
> Therefore, it should be better to check it in order to avoid the
> dereference of the NULL pointer.
> Also, the caller esparser_queue() needs to deal with the return value of
> the amvdec_add_ts().
> 
> Fixes: 876f123b8956 ("media: meson: vdec: bring up to compliance")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---
> Changelog
> 
> v1 -> v2
> 
> * Change 1. Change the return type of amvdec_add_ts from void to int.
> * Change 2. Return -ENOMEN if alloc fail and return 0 if not.
> * Change 3. Modify the caller to deal with the error.
> 
> v2 -> v3
> 
> * Change 1. Fix the indentation and refine the commit message.
> ---
>  drivers/staging/media/meson/vdec/esparser.c     | 7 ++++++-
>  drivers/staging/media/meson/vdec/vdec_helpers.c | 8 ++++++--
>  drivers/staging/media/meson/vdec/vdec_helpers.h | 4 ++--
>  3 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/staging/media/meson/vdec/esparser.c b/drivers/staging/media/meson/vdec/esparser.c
> index db7022707ff8..86ccc8937afc 100644
> --- a/drivers/staging/media/meson/vdec/esparser.c
> +++ b/drivers/staging/media/meson/vdec/esparser.c
> @@ -328,7 +328,12 @@ esparser_queue(struct amvdec_session *sess, struct vb2_v4l2_buffer *vbuf)
>  
>  	offset = esparser_get_offset(sess);
>  
> -	amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	ret = amvdec_add_ts(sess, vb->timestamp, vbuf->timecode, offset, vbuf->flags);
> +	if (ret) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return ret;
> +	}
> +
>  	dev_dbg(core->dev, "esparser: ts = %llu pld_size = %u offset = %08X flags = %08X\n",
>  		vb->timestamp, payload_size, offset, vbuf->flags);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c
> index 203d7afa085d..7d2a75653250 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.c
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c
> @@ -227,13 +227,16 @@ int amvdec_set_canvases(struct amvdec_session *sess,
>  }
>  EXPORT_SYMBOL_GPL(amvdec_set_canvases);
>  
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 vbuf_flags)
>  {
>  	struct amvdec_timestamp *new_ts;
>  	unsigned long flags;
>  
>  	new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL);
> +	if (!new_ts)
> +		return -ENOMEM;
> +
>  	new_ts->ts = ts;
>  	new_ts->tc = tc;
>  	new_ts->offset = offset;
> @@ -242,6 +245,7 @@ void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
>  	spin_lock_irqsave(&sess->ts_spinlock, flags);
>  	list_add_tail(&new_ts->list, &sess->timestamps);
>  	spin_unlock_irqrestore(&sess->ts_spinlock, flags);
> +	return 0;
>  }
>  EXPORT_SYMBOL_GPL(amvdec_add_ts);
>  
> diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.h b/drivers/staging/media/meson/vdec/vdec_helpers.h
> index 88137d15aa3a..4bf3e61d081b 100644
> --- a/drivers/staging/media/meson/vdec/vdec_helpers.h
> +++ b/drivers/staging/media/meson/vdec/vdec_helpers.h
> @@ -56,8 +56,8 @@ void amvdec_dst_buf_done_offset(struct amvdec_session *sess,
>   * @offset: offset in the VIFIFO where the associated packet was written
>   * @flags: the vb2_v4l2_buffer flags
>   */
> -void amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> -		   struct v4l2_timecode tc, u32 offset, u32 flags);
> +int amvdec_add_ts(struct amvdec_session *sess, u64 ts,
> +		  struct v4l2_timecode tc, u32 offset, u32 flags);
>  void amvdec_remove_ts(struct amvdec_session *sess, u64 ts);
>  
>  /**
> 

Suggested-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Neil


From narmstrong at baylibre.com  Thu Jan 13 00:57:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 09:57:47 +0100
Subject: [PATCH v2 3/3] arm64: dts: meson-g12-common: add uart_ao_b pins
 muxing
In-Reply-To: <20220112211642.2248901-4-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-1-gary.bisson@boundarydevices.com>
 <20220112211642.2248901-4-gary.bisson@boundarydevices.com>
Message-ID: <78e5049b-5e39-ff70-7c77-9f233c7b2fd2@baylibre.com>

On 12/01/2022 22:16, Gary Bisson wrote:
> - RX/TX signals can be mapped on 2 different pairs of pins so supporting
>   both options
> - RTS/CTS signals however only have 1 option available
> 
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>
> ---
> Changes v1->v2:
> - renamed nodes as suggested by Neil
> 
> Cc: Rob Herring <robh+dt at kernel.org>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: devicetree at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> ---
>  .../boot/dts/amlogic/meson-g12-common.dtsi    | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index af1357c48bee..62350c408e16 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -1952,6 +1952,33 @@ mux {
>  						};
>  					};
>  
> +					uart_ao_b_2_3_pins: uart-ao-b-2-3 {
> +						mux {
> +							groups = "uart_ao_b_tx_2",
> +								 "uart_ao_b_rx_3";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_8_9_pins: uart-ao-b-8-9 {
> +						mux {
> +							groups = "uart_ao_b_tx_8",
> +								 "uart_ao_b_rx_9";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
> +					uart_ao_b_cts_rts_pins: uart-ao-b-cts-rts {
> +						mux {
> +							groups = "uart_ao_b_cts",
> +								 "uart_ao_b_rts";
> +							function = "uart_ao_b";
> +							bias-disable;
> +						};
> +					};
> +
>  					pwm_a_e_pins: pwm-a-e {
>  						mux {
>  							groups = "pwm_a_e";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks !
Neil


From yuzhao at google.com  Thu Jan 13 00:59:54 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 01:59:54 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <11900935.O9o76ZdvQC@natalenko.name>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <11900935.O9o76ZdvQC@natalenko.name>
Message-ID: <Yd/qClw7x7SxmnJw@google.com>

On Wed, Jan 12, 2022 at 09:56:58PM +0100, Oleksandr Natalenko wrote:
> Hello.
> 
> On ?ter? 4. ledna 2022 21:22:19 CET Yu Zhao wrote:
> > TLDR
> > ====
> > The current page reclaim is too expensive in terms of CPU usage and it
> > often makes poor choices about what to evict. This patchset offers an
> > alternative solution that is performant, versatile and
> > straightforward.

<snipped>

> For the series:
> 
> Tested-by: Oleksandr Natalenko <oleksandr at natalenko.name>
> 
> I run this (and one of the previous spins) on nine machines (physical, virtual, workstations, servers) for quite some time with no hassle.
> 
> Thanks for your job, and please keep me in Cc once you post new spins. I'm more than happy to deploy those across the fleet.

Thanks, Oleksandr. And if I may take the liberty of introducing you as:

   Oleksandr - the post-factum kernel maintainer
               https://gitlab.com/post-factum/pf-kernel

in addition to other downstream kernel maintainers I've introduced:

>   Alexandre - the XanMod kernel maintainer
>               https://xanmod.org
>
>   Brian     - the Chrome OS kernel memory maintainer
>               https://www.chromium.org
>
>   Jan       - the Arch Linux Zen kernel maintainer
>               https://archlinux.org
>
>   Steven    - the Liquorix kernel maintainer
>               https://liquorix.net
>
>   Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>               https://chromium.googlesource.com/chromiumos/third_party/kernel


From marcel at ziswiler.com  Thu Jan 13 01:03:21 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Thu, 13 Jan 2022 10:03:21 +0100
Subject: [PATCH v2] phy: freescale: pcie: cosmetic clean-up
Message-ID: <20220113090321.119880-1-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Sort includes alphabethically and add a new line before the dt-bindings
one as usually done.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Was 'phy: freescale: pcie: fix building for x86_64 as a module' but as
  Vinod already pushed a fix for that build issue this now only
  addresses the minor cosmetic clean-up as requested by him.

 drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
index 04b1aafb29f4..f1eb03ba25d6 100644
--- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
+++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c
@@ -5,9 +5,9 @@
 
 #include <linux/bitfield.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
-#include <linux/delay.h>
 #include <linux/mfd/syscon.h>
 #include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
 #include <linux/module.h>
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+
 #include <dt-bindings/phy/phy-imx8-pcie.h>
 
 #define IMX8MM_PCIE_PHY_CMN_REG061	0x184
-- 
2.33.1



From james.clark at arm.com  Thu Jan 13 01:08:51 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:08:51 +0000
Subject: [PATCH 2/3] coresight: Fail to open with return stacks if they
 are unavailable
In-Reply-To: <CAJ9a7VgUGhjOq2p5oitnCj9HY=vA8Byfi+-W8OB8949-Q49=oA@mail.gmail.com>
References: <20211208160907.749482-1-james.clark@arm.com>
 <20211208160907.749482-2-james.clark@arm.com>
 <b52ef2f3-9e30-59a6-2aea-e46c93915868@arm.com>
 <b61ef2e3-e573-4867-af5d-fd5fabece4b1@arm.com>
 <20211210172220.GA1238770@p14s>
 <CAJ9a7VgBxO0-R4jX6+-Vu10DtcsOeMiq9YrPkEEFQ=6ixNXXVQ@mail.gmail.com>
 <d884f96c-1d4c-119e-5e83-3674260a9694@arm.com>
 <CAJ9a7VgUGhjOq2p5oitnCj9HY=vA8Byfi+-W8OB8949-Q49=oA@mail.gmail.com>
Message-ID: <b235206c-aa46-46e6-f238-174265642031@arm.com>



On 17/12/2021 11:52, Mike Leach wrote:
> Hi James
> 
> On Fri, 17 Dec 2021 at 09:41, James Clark <james.clark at arm.com> wrote:
>>
>>
>>
>> On 13/12/2021 09:48, Mike Leach wrote:
>>> Hi James,
>>>
>>> A couple of points - relating mainly to docs:
>>>
>>
>> Hi Mike,
>>
>> Thanks for the feedback. I was in the process of adding some docs and
>> ran into this https://lkml.org/lkml/2021/12/16/1087 so I went to fix
>> that first. Now I will add some more details and resubmit.
>>
>>> 1. Activating branch broadcast overrides any setting of return stack.
>>> As a minimum there needs to be a documentation update to reflect this
>>> -Setting both options is not prohibited in hardware - and in the case
>>> where we can use branch broadcast over a range both are then relevant.
>>>
>>
>> Do you mean that if branch broadcast and return stacks are both requested,
>> but branch broadcast is limited to a range, return stacks will only be
>> available outside that branch broadcast range? But if branch broadcast is
>> enabled for all ranges there will be no return stacks at all?
>>
> 
> Correct - you may want to branch broadcast over a small ranges, but
> otherwise use return stack to decrease the amount of trace in other
> areas.
> Once the complex config sets are accepted upstream then this set-up
> will be possible by writing a config to do this.
> 
>>> 2. A documented note to reflect that choosing this option will result
>>> in a significant increase in the amount of trace generated - possible
>>> danger of overflows, or less actual instructions covered. In addition
>>> perhaps documents could reflect the intended use-case for this option,
>>> given the disadvantages.
>>>
>>
>> Will do.
>>
>>> 3. Has this been tested in a situation where it will be of use?
>>> Testing against static code images will show the same decoded trace
>>> output as not using branch broadcast. (although the packet dumps will
>>> show additional output)>
>>> Given a primary use is for situations where code is patched or
>>> dynamically altered at runtime - then this can affect the full decode
>>> output. If the code is being patched to only alter the branch
>>> addresses then decode should work against static images.
>>> If, however, we are tracing code that adds in new branches, on top of
>>> NOPs for example, then the decoding against the original static image
>>> will be wrong, as the image will have the NOPs, rather than the branch
>>> instructions so the apparent location of E atoms will be in a
>>> different position to the actual code. Is there anything in perf that
>>> will ensure that the patched code is presented to the decoder?
>>>
>>> If there are potential decode issues - these too need documenting.
>>>
>>
>> I'm not sure this should be a blocking issue for this set. Branch broadcast
>> could already be enabled by setting the mode via sysfs. And the perf decode
>> part isn't necessarily a step in the workflow, maybe someone wants to gather
>> data for another tool.
>>
> 
> Someone could set this in sysfs - when collecting data via sysfs.  In
> this case they would not be using perf for decode anyway as you say.
> 
> What you have added here is a new method for perf to set this feature
> and perf always starts off with a clean configuration - then adds
> according to command line options.
> Therefore this will be the first time anyone will have been able to
> set this for a perf session.
> 
> It there are potential limitations, then we need to be clear about
> them - then users of perf, and other hypothetical tools can make a
> good choice about if this option is appropriate - and we avoid mailing
> list complaints (or at least can point to the docs) if users find
> issues that they were warned about!
> 
>> I will do some testing after this change though, but I imagine we would have
>> had issues reported it it wasn't working already which lowers the priority.
>>
> 
> really depends on what was tested! If it is being used over static
> code then the subsequent decode will be fine,
> 

I've posted v2 of this change with some docs changes. I also did some testing
around JITed code in java to see if there were any bad errors which I put
in the cover letter. Although I think the main point of adding this format
flag for perf is to open another avenue of testing or for people who just want
to look at the raw trace manually for now.

James

> Regards
> 
> Mike
> 
>> James
>>
>>> Other than the documents and testing,  I cannot see any issues with
>>> this patch set in terms of setting and enabling the option.
>>>
>>> Regards
>>>
>>> Mike
>>>
>>>
>>> On Fri, 10 Dec 2021 at 17:22, Mathieu Poirier
>>> <mathieu.poirier at linaro.org> wrote:
>>>>
>>>> Hi James,
>>>>
>>>> On Thu, Dec 09, 2021 at 11:13:55AM +0000, James Clark wrote:
>>>>>
>>>>>
>>>>> On 09/12/2021 11:00, Suzuki K Poulose wrote:
>>>>>> On 08/12/2021 16:09, James Clark wrote:
>>>>>>> Maintain consistency with the other options by failing to open when they
>>>>>>> aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
>>>>>>> added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
>>>>>>> requested but not supported by hardware.
>>>>>>>
>>>>>>> The consequence of not doing this is that the user may not be
>>>>>>> aware that they are not enabling the feature as it is silently disabled.
>>>>>>>
>>>>>>> Signed-off-by: James Clark <james.clark at arm.com>
>>>>>>> ---
>>>>>>>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
>>>>>>>   1 file changed, 9 insertions(+), 4 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>>> index d2bafb50c66a..0a9bb943a5e5 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
>>>>>>> @@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>>>>>>>       }
>>>>>>>         /* return stack - enable if selected and supported */
>>>>>>> -    if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
>>>>>>> -        /* bit[12], Return stack enable bit */
>>>>>>> -        config->cfg |= BIT(12);
>>>>>>> -
>>>>>>> +    if (attr->config & BIT(ETM_OPT_RETSTK)) {
>>>>>>> +        if (!drvdata->retstack) {
>>>>>>> +            ret = -EINVAL;
>>>>>>> +            goto out;
>>>>>>> +        } else {
>>>>>>> +            /* bit[12], Return stack enable bit */
>>>>>>> +            config->cfg |= BIT(12);
>>>>>>> +        }
>>>>>>
>>>>>> nit: While at this, please could you change the hard coded value
>>>>>> to ETM4_CFG_BIT_RETSTK ?
>>>>>>
>>>>> I started changing them all because I had trouble searching for bits by name but then
>>>>> I thought it would snowball into a bigger change so I undid it.
>>>>>
>>>>> I think I'll just go and do it now if it's an issue here.
>>>>
>>>> I can apply this set right away and you send another patch to fix all hard coded
>>>> bitfields or you can send another revision with all 4 patches included in it
>>>> (bitfields fix plus these 3).  Just let me know what you want to do.  And next
>>>> time please add a cover letter.
>>>>
>>>> Thanks,
>>>> Mathieu
>>>>
>>>>>
>>>>>> Otherwise, looks good to me
>>>>>>
>>>>>> Suzuki
>>>
>>>
>>>
> 
> 
> 


From james.clark at arm.com  Thu Jan 13 01:09:37 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:09:37 +0000
Subject: [PATCH 3/3] perf cs-etm: Update deduction of TRCCONFIGR register
 for branch broadcast
In-Reply-To: <20211210024137.GB622826@leoy-ThinkPad-X240s>
References: <20211208160907.749482-1-james.clark@arm.com>
 <20211208160907.749482-3-james.clark@arm.com>
 <20211210024137.GB622826@leoy-ThinkPad-X240s>
Message-ID: <cfc92a41-7371-f5a7-db01-354c87027223@arm.com>



On 10/12/2021 02:41, Leo Yan wrote:
> On Wed, Dec 08, 2021 at 04:09:07PM +0000, James Clark wrote:
>> Now that a config flag for branch broadcast has been added, take it into
>> account when trying to deduce what the driver would have programmed the
>> TRCCONFIGR register to.
>>
>> Signed-off-by: James Clark <james.clark at arm.com>
>> ---
>>  tools/include/linux/coresight-pmu.h | 2 ++
>>  tools/perf/arch/arm/util/cs-etm.c   | 3 +++
>>  2 files changed, 5 insertions(+)
>>
>> diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h
>> index 4ac5c081af93..6c2fd6cc5a98 100644
>> --- a/tools/include/linux/coresight-pmu.h
>> +++ b/tools/include/linux/coresight-pmu.h
>> @@ -18,6 +18,7 @@
>>   * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
>>   * directly use below macros as config bits.
>>   */
>> +#define ETM_OPT_BRANCH_BROADCAST 8
> 
> I checked ETMv3 architecture spec (ARM IHI 0014Q), its bit 8 is "branch
> output" for all branch address outputting.  I am not sure if it is the
> same thing between ETMv3's "branch output" and ETMv4's "branch
> broadcasting", but it makes sense for me to use bit 8 as an unified
> config bit to control these two options for ETMv3 and ETMv4
> respectively.
> 
> Just note, I understand this patch set is to enable branch broadcasting
> for entire memory region rather than using any comparators (see
> TRCBBCTLR) to limit branch broadcasting ranges.  This is fine for me and
> we could enable ranges later.
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>

Hi Leo,

Thanks for the review, I've posted v2, but I only put your reviewed by tag
on this commit because I wasn't sure if you meant for the full set. Please
take another look

Thanks
James

> 
>>  #define ETM_OPT_CYCACC		12
>>  #define ETM_OPT_CTXTID		14
>>  #define ETM_OPT_CTXTID2		15
>> @@ -25,6 +26,7 @@
>>  #define ETM_OPT_RETSTK		29
>>  
>>  /* ETMv4 CONFIGR programming bits for the ETM OPTs */
>> +#define ETM4_CFG_BIT_BB         3
>>  #define ETM4_CFG_BIT_CYCACC	4
>>  #define ETM4_CFG_BIT_CTXTID	6
>>  #define ETM4_CFG_BIT_VMID	7
>> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
>> index 293a23bf8be3..c7ef4e9b4a3a 100644
>> --- a/tools/perf/arch/arm/util/cs-etm.c
>> +++ b/tools/perf/arch/arm/util/cs-etm.c
>> @@ -527,6 +527,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
>>  	if (config_opts & BIT(ETM_OPT_CTXTID2))
>>  		config |= BIT(ETM4_CFG_BIT_VMID) |
>>  			  BIT(ETM4_CFG_BIT_VMID_OPT);
>> +	if (config_opts & BIT(ETM_OPT_BRANCH_BROADCAST))
>> +		config |= BIT(ETM4_CFG_BIT_BB);
>> +
>>  	return config;
>>  }
>>  
>> -- 
>> 2.28.0
>>


From james.clark at arm.com  Thu Jan 13 01:10:49 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:49 +0000
Subject: [PATCH v2 0/6] coresight: Add config flag to enable branch broadcast
Message-ID: <20220113091056.1297982-1-james.clark@arm.com>

This allows enabling branch broadcast for Perf hosted sessions (the option
is currently only available for the sysfs interface). Hopefully this could
be useful for testing the decode in perf, for example does a determinisitic
run with branch broadcast enabled look the same as with it disabled? It
could also be used for scenarios like OpenJ9's support for JIT code:

  java -Xjit:perfTool hello.java

Currently this is not working and you get the usual errors of a missing
DSO, but branch broadcast would have to be enabled anyway before working
through this next issue:

  CS ETM Trace: Debug data not found for address 0xffff7b94b058 in /tmp/perf-29360.map

Address range support in Perf for branch broadcast has also not been added
here, but could be added later.

The documentation has been refactored slightly to allow updates to be made
that link the Perf format arguments with the existing documentation.

For Suzuki's comment, I will do it as a separate change that converts all
the other hard coded values to a more consistent sysreg.h style:

  nit: While at this, please could you change the hard coded value
  to ETM4_CFG_BIT_RETSTK ? 

Changes since v1:

  * Added Leo's reviewed by on patch 3
  * Fix bracket styling
  * Add documentation

Applies on top of coresight/next efa56eddf5d5c. But this docs fix is also
required to get the links to work:
  https://marc.info/?l=linux-doc&m=164139331923986&w=2

Also available at: https://gitlab.arm.com/linux-arm/linux-jc/-/tree/james-branch-broadcast-v2

James Clark (6):
  coresight: Add config flag to enable branch broadcast
  coresight: Fail to open with return stacks if they are unavailable
  perf cs-etm: Update deduction of TRCCONFIGR register for branch
    broadcast
  Documentation: coresight: Turn numbered subsections into real
    subsections
  Documentation: coresight: Link config options to existing
    documentation
  Documentation: coresight: Expand branch broadcast documentation

 .../coresight/coresight-etm4x-reference.rst   | 14 ++++-
 Documentation/trace/coresight/coresight.rst   | 56 +++++++++++++++++--
 .../hwtracing/coresight/coresight-etm-perf.c  |  2 +
 .../coresight/coresight-etm4x-core.c          | 23 ++++++--
 include/linux/coresight-pmu.h                 |  2 +
 tools/include/linux/coresight-pmu.h           |  2 +
 tools/perf/arch/arm/util/cs-etm.c             |  3 +
 7 files changed, 92 insertions(+), 10 deletions(-)

-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:50 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:50 +0000
Subject: [PATCH v2 1/6] coresight: Add config flag to enable branch broadcast
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-2-james.clark@arm.com>

When enabled, all taken branch addresses are output, even if the branch
was because of a direct branch instruction. This enables reconstruction
of the program flow without having access to the memory image of the
code being executed.

Use bit 8 for the config option which would be the correct bit for
programming ETMv3. Although branch broadcast can't be enabled on ETMv3
because it's not in the define ETM3X_SUPPORTED_OPTIONS, using the
correct bit might help prevent future collisions or allow it to be
enabled if needed.

Signed-off-by: James Clark <james.clark at arm.com>
---
 drivers/hwtracing/coresight/coresight-etm-perf.c   |  2 ++
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 ++++++++++
 include/linux/coresight-pmu.h                      |  2 ++
 3 files changed, 14 insertions(+)

diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index c039b6ae206f..43bbd5dc3d3b 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -52,6 +52,7 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
  * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config';
  * now take them as general formats and apply on all ETMs.
  */
+PMU_FORMAT_ATTR(branch_broadcast, "config:"__stringify(ETM_OPT_BRANCH_BROADCAST));
 PMU_FORMAT_ATTR(cycacc,		"config:" __stringify(ETM_OPT_CYCACC));
 /* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
 PMU_FORMAT_ATTR(contextid1,	"config:" __stringify(ETM_OPT_CTXTID));
@@ -97,6 +98,7 @@ static struct attribute *etm_config_formats_attr[] = {
 	&format_attr_sinkid.attr,
 	&format_attr_preset.attr,
 	&format_attr_configid.attr,
+	&format_attr_branch_broadcast.attr,
 	NULL,
 };
 
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index bf18128cf5de..04669ecc0efa 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -692,6 +692,16 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
 	}
 
+	/* branch broadcast - enable if selected and supported */
+	if (attr->config & BIT(ETM_OPT_BRANCH_BROADCAST)) {
+		if (!drvdata->trcbb) {
+			ret = -EINVAL;
+			goto out;
+		} else {
+			config->cfg |= BIT(ETM4_CFG_BIT_BB);
+		}
+	}
+
 out:
 	return ret;
 }
diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h
index 4ac5c081af93..6c2fd6cc5a98 100644
--- a/include/linux/coresight-pmu.h
+++ b/include/linux/coresight-pmu.h
@@ -18,6 +18,7 @@
  * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
  * directly use below macros as config bits.
  */
+#define ETM_OPT_BRANCH_BROADCAST 8
 #define ETM_OPT_CYCACC		12
 #define ETM_OPT_CTXTID		14
 #define ETM_OPT_CTXTID2		15
@@ -25,6 +26,7 @@
 #define ETM_OPT_RETSTK		29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
+#define ETM4_CFG_BIT_BB         3
 #define ETM4_CFG_BIT_CYCACC	4
 #define ETM4_CFG_BIT_CTXTID	6
 #define ETM4_CFG_BIT_VMID	7
-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:51 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:51 +0000
Subject: [PATCH v2 2/6] coresight: Fail to open with return stacks if they are
 unavailable
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-3-james.clark@arm.com>

Maintain consistency with the other options by failing to open when they
aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
requested but not supported by hardware.

The consequence of not doing this is that the user may not be
aware that they are not enabling the feature as it is silently disabled.

Signed-off-by: James Clark <james.clark at arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
index 04669ecc0efa..a93c1a5fe045 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
 	}
 
 	/* return stack - enable if selected and supported */
-	if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
-		/* bit[12], Return stack enable bit */
-		config->cfg |= BIT(12);
-
+	if (attr->config & BIT(ETM_OPT_RETSTK)) {
+		if (!drvdata->retstack) {
+			ret = -EINVAL;
+			goto out;
+		} else {
+			/* bit[12], Return stack enable bit */
+			config->cfg |= BIT(12);
+		}
+	}
 	/*
 	 * Set any selected configuration and preset.
 	 *
-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:52 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:52 +0000
Subject: [PATCH v2 3/6] perf cs-etm: Update deduction of TRCCONFIGR register
 for branch broadcast
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-4-james.clark@arm.com>

Now that a config flag for branch broadcast has been added, take it into
account when trying to deduce what the driver would have programmed the
TRCCONFIGR register to.

Reviewed-by: Leo Yan <leo.yan at linaro.org>
Signed-off-by: James Clark <james.clark at arm.com>
---
 tools/include/linux/coresight-pmu.h | 2 ++
 tools/perf/arch/arm/util/cs-etm.c   | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h
index 4ac5c081af93..6c2fd6cc5a98 100644
--- a/tools/include/linux/coresight-pmu.h
+++ b/tools/include/linux/coresight-pmu.h
@@ -18,6 +18,7 @@
  * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
  * directly use below macros as config bits.
  */
+#define ETM_OPT_BRANCH_BROADCAST 8
 #define ETM_OPT_CYCACC		12
 #define ETM_OPT_CTXTID		14
 #define ETM_OPT_CTXTID2		15
@@ -25,6 +26,7 @@
 #define ETM_OPT_RETSTK		29
 
 /* ETMv4 CONFIGR programming bits for the ETM OPTs */
+#define ETM4_CFG_BIT_BB         3
 #define ETM4_CFG_BIT_CYCACC	4
 #define ETM4_CFG_BIT_CTXTID	6
 #define ETM4_CFG_BIT_VMID	7
diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
index 293a23bf8be3..c7ef4e9b4a3a 100644
--- a/tools/perf/arch/arm/util/cs-etm.c
+++ b/tools/perf/arch/arm/util/cs-etm.c
@@ -527,6 +527,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
 	if (config_opts & BIT(ETM_OPT_CTXTID2))
 		config |= BIT(ETM4_CFG_BIT_VMID) |
 			  BIT(ETM4_CFG_BIT_VMID_OPT);
+	if (config_opts & BIT(ETM_OPT_BRANCH_BROADCAST))
+		config |= BIT(ETM4_CFG_BIT_BB);
+
 	return config;
 }
 
-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:53 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:53 +0000
Subject: [PATCH v2 4/6] Documentation: coresight: Turn numbered subsections
 into real subsections
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-5-james.clark@arm.com>

This is to allow them to be referenced in a later commit. There was
also a mistake where sysFS was introduced as section 2, but numbered
as section 1. And vice versa for 'Using perf framework'. This can't
happen with unnumbered sections.

Signed-off-by: James Clark <james.clark at arm.com>
---
 Documentation/trace/coresight/coresight.rst | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
index a15571d96cc8..db66ff45ff4c 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -339,7 +339,8 @@ Preference is given to the former as using the sysFS interface
 requires a deep understanding of the Coresight HW.  The following sections
 provide details on using both methods.
 
-1) Using the sysFS interface:
+Using the sysFS interface
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Before trace collection can start, a coresight sink needs to be identified.
 There is no limit on the amount of sinks (nor sources) that can be enabled at
@@ -446,7 +447,8 @@ wealth of possibilities that coresight provides.
     Instruction     0       0x8026B588      E8BD8000        true    LDM      sp!,{pc}
     Timestamp                                       Timestamp: 17107041535
 
-2) Using perf framework:
+Using perf framework
+~~~~~~~~~~~~~~~~~~~~
 
 Coresight tracers are represented using the Perf framework's Performance
 Monitoring Unit (PMU) abstraction.  As such the perf framework takes charge of
@@ -495,7 +497,11 @@ More information on the above and other example on how to use Coresight with
 the perf tools can be found in the "HOWTO.md" file of the openCSD gitHub
 repository [#third]_.
 
-2.1) AutoFDO analysis using the perf tools:
+Advanced perf framework usage
+-----------------------------
+
+AutoFDO analysis using the perf tools
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 perf can be used to record and analyze trace of programs.
 
@@ -513,7 +519,8 @@ The --itrace option controls the type and frequency of synthesized events
 Note that only 64-bit programs are currently supported - further work is
 required to support instruction decode of 32-bit Arm programs.
 
-2.2) Tracing PID
+Tracing PID
+~~~~~~~~~~~
 
 The kernel can be built to write the PID value into the PE ContextID registers.
 For a kernel running at EL1, the PID is stored in CONTEXTIDR_EL1.  A PE may
@@ -547,7 +554,7 @@ wants to trace PIDs for both host and guest, the two configs "contextid1" and
 
 
 Generating coverage files for Feedback Directed Optimization: AutoFDO
----------------------------------------------------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 'perf inject' accepts the --itrace option in which case tracing data is
 removed and replaced with the synthesized events. e.g.
-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:54 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:54 +0000
Subject: [PATCH v2 5/6] Documentation: coresight: Link config options to
 existing documentation
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-6-james.clark@arm.com>

In order to document the newly added branch_broadcast option, create a
table that links all of the config option formats to any existing docs.
That way when the branch broadcast docs are expanded they are accessible
from both places.

Signed-off-by: James Clark <james.clark at arm.com>
---
 .../coresight/coresight-etm4x-reference.rst   |  4 ++
 Documentation/trace/coresight/coresight.rst   | 39 +++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.rst b/Documentation/trace/coresight/coresight-etm4x-reference.rst
index d25dfe86af9b..0439b4006227 100644
--- a/Documentation/trace/coresight/coresight-etm4x-reference.rst
+++ b/Documentation/trace/coresight/coresight-etm4x-reference.rst
@@ -650,6 +650,7 @@ Bit assignments shown below:-
     parameter is set this value is applied to the currently indexed
     address range.
 
+.. _coresight-branch-broadcast:
 
 **bit (4):**
     ETM_MODE_BB
@@ -657,6 +658,7 @@ Bit assignments shown below:-
 **description:**
     Set to enable branch broadcast if supported in hardware [IDR0].
 
+.. _coresight-cycle-accurate:
 
 **bit (5):**
     ETMv4_MODE_CYCACC
@@ -678,6 +680,7 @@ Bit assignments shown below:-
 **description:**
     Set to enable virtual machine ID tracing if supported [IDR2].
 
+.. _coresight-timestamp:
 
 **bit (11):**
     ETMv4_MODE_TIMESTAMP
@@ -685,6 +688,7 @@ Bit assignments shown below:-
 **description:**
     Set to enable timestamp generation if supported [IDR0].
 
+.. _coresight-return-stack:
 
 **bit (12):**
     ETM_MODE_RETURNSTACK
diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
index db66ff45ff4c..803a224dbb0e 100644
--- a/Documentation/trace/coresight/coresight.rst
+++ b/Documentation/trace/coresight/coresight.rst
@@ -585,6 +585,45 @@ sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tuto
 	Bubble sorting array of 30000 elements
 	5806 ms
 
+Config option formats
+~~~~~~~~~~~~~~~~~~~~~
+
+The following strings can be provided between // on the perf command line to enable various options.
+They are also listed in the folder /sys/bus/event_source/devices/cs_etm/format/
+
+.. list-table::
+   :header-rows: 1
+
+   * - Option
+     - Description
+   * - branch_broadcast
+     - Session local version of the system wide setting:
+       :ref:`ETM_MODE_BB <coresight-branch-broadcast>`
+   * - contextid
+     - See `Tracing PID`_
+   * - contextid1
+     - See `Tracing PID`_
+   * - contextid2
+     - See `Tracing PID`_
+   * - configid
+     - Selection for a custom configuration. This is an implementation detail and not used directly,
+       see :ref:`trace/coresight/coresight-config:Using Configurations in perf`
+   * - preset
+     - Override for parameters in a custom configuration, see
+       :ref:`trace/coresight/coresight-config:Using Configurations in perf`
+   * - sinkid
+     - Hashed version of the string to select a sink, automatically set when using the @ notation.
+       This is an internal implementation detail and is not used directly, see `Using perf
+       framework`_.
+   * - cycacc
+     - Session local version of the system wide setting: :ref:`ETMv4_MODE_CYCACC
+       <coresight-cycle-accurate>`
+   * - retstack
+     - Session local version of the system wide setting: :ref:`ETM_MODE_RETURNSTACK
+       <coresight-return-stack>`
+   * - timestamp
+     - Session local version of the system wide setting: :ref:`ETMv4_MODE_TIMESTAMP
+       <coresight-timestamp>`
 
 How to use the STM module
 -------------------------
-- 
2.28.0



From james.clark at arm.com  Thu Jan 13 01:10:55 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 13 Jan 2022 09:10:55 +0000
Subject: [PATCH v2 6/6] Documentation: coresight: Expand branch broadcast
 documentation
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <20220113091056.1297982-7-james.clark@arm.com>

Now that there is a way of enabling branch broadcast via perf, mention
the possible use cases and known limitations.

Signed-off-by: James Clark <james.clark at arm.com>
---
 .../trace/coresight/coresight-etm4x-reference.rst      | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.rst b/Documentation/trace/coresight/coresight-etm4x-reference.rst
index 0439b4006227..ec336575919c 100644
--- a/Documentation/trace/coresight/coresight-etm4x-reference.rst
+++ b/Documentation/trace/coresight/coresight-etm4x-reference.rst
@@ -656,7 +656,15 @@ Bit assignments shown below:-
     ETM_MODE_BB
 
 **description:**
-    Set to enable branch broadcast if supported in hardware [IDR0].
+    Set to enable branch broadcast if supported in hardware [IDR0]. The primary use for this feature
+    is when code is patched dynamically at run time and the full program flow may not be able to be
+    reconstructed using only conditional branches.
+
+    Choosing this option will result in a significant increase in the amount of trace generated -
+    possible danger of overflows, or fewer instructions covered. Note, that this option also
+    overrides any setting of :ref:`ETM_MODE_RETURNSTACK <coresight-return-stack>`, so where a branch
+    broadcast range overlaps a return stack range, return stacks will not be available for that
+    range.
 
 .. _coresight-cycle-accurate:
 
-- 
2.28.0



From narmstrong at baylibre.com  Thu Jan 13 01:12:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 10:12:34 +0100
Subject: [PATCH v2 0/3] ARM: ox810se: Add Ethernet support
In-Reply-To: <20220104145646.135877-1-narmstrong@baylibre.com>
References: <20220104145646.135877-1-narmstrong@baylibre.com>
Message-ID: <164206502761.1011244.11952182860924885505.b4-ty@baylibre.com>

Hi,

On Tue, 4 Jan 2022 15:56:43 +0100, Neil Armstrong wrote:
> This adds support for the Synopsys DWMAC controller found in the
> OX820SE SoC, by using almost the same glue code as the OX820.
> 
> Patch 1 & 2 are for net branch, patch 3 will be queued to arm-soc.
> 
> Changes since v1:
> - correctly update value read from register
> - add proper tag on patch 3 for arm-soc tree
> 
> [...]

Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/narmstrong/linux-oxnas.git (v5.18/dt)

[3/3] ARM: dts: ox810se: Add Ethernet support
      https://git.kernel.org/narmstrong/linux-oxnas/c/ae552c33f6edad1097dec7a5543314d35d413b3e

-- 
Neil


From yuzhao at google.com  Thu Jan 13 01:25:31 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 02:25:31 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd6tafG3CS7BoRYn@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <YdxKORU9OWCv114O@dhcp22.suse.cz>
 <Yd4P6bEJI8YlXq0H@google.com> <Yd6tafG3CS7BoRYn@dhcp22.suse.cz>
Message-ID: <Yd/wC8K3+0pE+3UZ@google.com>

On Wed, Jan 12, 2022 at 11:28:57AM +0100, Michal Hocko wrote:
> On Tue 11-01-22 16:16:57, Yu Zhao wrote:
> > On Mon, Jan 10, 2022 at 04:01:13PM +0100, Michal Hocko wrote:
> > > On Thu 06-01-22 17:12:18, Michal Hocko wrote:
> > > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > > +static struct lru_gen_mm_walk *alloc_mm_walk(void)
> > > > > +{
> > > > > +	if (!current->reclaim_state || !current->reclaim_state->mm_walk)
> > > > > +		return kvzalloc(sizeof(struct lru_gen_mm_walk), GFP_KERNEL);
> > > 
> > > One thing I have overlooked completely.
> > 
> > I appreciate your attention to details but GFP_KERNEL is legit in the
> > reclaim path. It's been used many years in our production, e.g.,
> >   page reclaim
> >     swap_writepage()
> >       frontswap_store()
> >         zswap_frontswap_store()
> >           zswap_entry_cache_alloc(GFP_KERNEL)
> > 
> > (And I always test my changes with lockdep, kasan, DEBUG_VM, etc., no
> >  warnings ever seen from using GFP_KERNEL in the reclaim path.)
> 
> OK, I can see it now. __need_reclaim will check for PF_MEMALLOC and skip
> the fs_reclaim tracking.
> 
> I still maintain I am not really happy about (nor in the zswap example)
> allocations from the direct reclaim context. I would really recommend
> using a pre-allocated pool of objects.

Not trying to argue anything -- there are many other places in the
reclaim path that must allocate memory to make progress, e.g.,

  add_to_swap_cache()
    xas_nomem()

  __swap_writepage()
    bio_alloc()

The only way to not allocate memory is drop clean pages. Writing dirty
pages (not swap) might require allocations as well. (But we only write
dirty pages in kswapd, not in the direct reclaim path.)

> If there are strong reasons for not doing so then at lease change that
> to kzalloc.

Consider it done.


From raphael.gallais-pou at foss.st.com  Thu Jan 13 01:37:28 2022
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Thu, 13 Jan 2022 10:37:28 +0100
Subject: [PATCH 1/5] drm/stm: ltdc: switch to regmap
In-Reply-To: <20211215214738.19946-1-yannick.fertre@foss.st.com>
References: <20211215214738.19946-1-yannick.fertre@foss.st.com>
Message-ID: <87cd3111-75bd-e66c-5ba8-af3ff76bedad@foss.st.com>


On 12/15/21 10:47 PM, Yannick Fertre wrote:
> Replace the legacy register access by regmap API.
>
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>  drivers/gpu/drm/stm/ltdc.c | 138 ++++++++++++++++++-------------------
>  drivers/gpu/drm/stm/ltdc.h |   1 +
>  2 files changed, 68 insertions(+), 71 deletions(-)


Hello Yannick,

Reviewed-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Tested-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Thanks for the patch,

Rapha?l



From anshuman.khandual at arm.com  Thu Jan 13 01:41:08 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 13 Jan 2022 15:11:08 +0530
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
Message-ID: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>

MDCR_EL3.SBRBE resets to an UNKNOWN value. Configure it to allow the BRBE
buffer usage and direct register access in the non-secure world. But just
before that, check AA64DFR0_EL1.BRBE and make sure BRBE is implemented. We
still continue to reset MDCR_EL3 register to zero with the exception of
MDCR_EL3.NSPB, MDCR_EL3.NSTB and MDCR_EL3.SBRBE.

Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/aarch64/boot.S | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index bfbb6ec..ca1b292 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -103,6 +103,14 @@ ASM_FUNC(_start)
 	ldr	x1, =(0x3 << 24)
 	orr	x0, x0, x1
 
+1:	mrs     x1, id_aa64dfr0_el1
+	ubfx    x1, x1, #52, #4
+	cbz     x1, 1f
+
+	// Enable BRBE for the non-secure world.
+	ldr     x1, =(0x3 << 32)
+	orr     x0, x0, x1
+
 1:	msr	mdcr_el3, x0			// Disable traps to EL3
 
 	mrs	x0, id_aa64pfr0_el1
-- 
2.7.4



From yuzhao at google.com  Thu Jan 13 01:43:38 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 02:43:38 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
 <Yduuyrk/AZG717Hs@google.com> <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>
Message-ID: <Yd/0Sgxy+jLm5cqd@google.com>

On Mon, Jan 10, 2022 at 03:37:28PM +0100, Michal Hocko wrote:
> On Sun 09-01-22 20:58:02, Yu Zhao wrote:
> > On Fri, Jan 07, 2022 at 10:00:31AM +0100, Michal Hocko wrote:
> > > On Fri 07-01-22 09:55:09, Michal Hocko wrote:
> > > [...]
> > > > > In this case, lru_gen_mm_walk is small (160 bytes); it's per direct
> > > > > reclaimer; and direct reclaimers rarely come here, i.e., only when
> > > > > kswapd can't keep up in terms of the aging, which is similar to the
> > > > > condition where the inactive list is empty for the active/inactive
> > > > > lru.
> > > > 
> > > > Well, this is not a strong argument to be honest. Kswapd being stuck
> > > > and the majority of the reclaim being done in the direct reclaim
> > > > context is a situation I have seen many many times.
> > > 
> > > Also do not forget that memcg reclaim is effectivelly only direct
> > > reclaim. Not that the memcg reclaim indicates a global memory shortage
> > > but it can add up and race with the global reclaim as well.
> > 
> > I don't dispute any of the above, and I probably don't like this code
> > more than you do.
> > 
> > But let's not forget the purposes of PF_MEMALLOC, besides preventing
> > recursive reclaims, include letting reclaim dip into reserves so that
> > it can make more free memory. So I think it's acceptable if the
> > following conditions are met:
> > 1. The allocation size is small.
> > 2. The number of allocations is bounded.
> > 3. Its failure doesn't stall reclaim.
> > And it'd be nice if
> > 4. The allocation happens rarely, e.g., slow path only.
> 
> I would add 
>   0. The allocation should be done only if absolutely _necessary_.
> 
> Please keep in mind that whatever you allocate from that context will be
> consuming a very precious memory reserves which are shared with other
> components of the system. Even worse these can go all the way to
> depleting memory completely where other things can fall apart.

I agree but I also see a distinction:
   1,2,3 are objective;
   0,4 are subjective.

For some users, page reclaim itself could be not absolutely necessary
because they are okay with OOM kills. But for others, the situation
could be reversed.

> > The code in question meets all of them.
> > 
> > 1. This allocation is 160 bytes.
> > 2. It's bounded by the number of page table walkers which, in the
> >    worst, is same as the number of mm_struct's.
> > 3. Most importantly, its failure doesn't stall the aging. The aging
> >    will fallback to the rmap-based function lru_gen_look_around().
> >    But this function only gathers the accessed bit from at most 64
> >    PTEs, meaning it's less efficient (retains ~80% performance gains).
> > 4. This allocation is rare, i.e., only when the aging is required,
> >    which is similar to the low inactive case for the active/inactive
> >    lru.
> 
> I think this fallback behavior deserves much more detailed explanation
> in changelogs.

Will do.

> > The bottom line is I can try various optimizations, e.g., preallocate
> > a few buffers for a limited number of page walkers and if this number
> > has been reached, fallback to the rmap-based function. But I have yet
> > to see evidence that calls for additional complexity.
> 
> I would disagree here. This is not an optimization. You should be
> avoiding allocations from the memory reclaim because any allocation just
> add a runtime behavior complexity and potential corner cases.

Would __GFP_NOMEMALLOC address your concern? It prevents allocations
from accessing the reserves even under PF_MEMALLOC.


From yuzhao at google.com  Thu Jan 13 01:47:51 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 02:47:51 -0700
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <Yd73pDkMOMVHhXzu@kernel.org>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <YdwKB3SfF7hkB9Xv@kernel.org> <Yd6S6Js1W4AnFFmv@google.com>
 <Yd73pDkMOMVHhXzu@kernel.org>
Message-ID: <Yd/1Rz+ne38Mh8R9@google.com>

On Wed, Jan 12, 2022 at 05:45:40PM +0200, Mike Rapoport wrote:
> On Wed, Jan 12, 2022 at 01:35:52AM -0700, Yu Zhao wrote:
> > On Mon, Jan 10, 2022 at 12:27:19PM +0200, Mike Rapoport wrote:
> > > Hi,
> > > 
> > > On Tue, Jan 04, 2022 at 01:22:27PM -0700, Yu Zhao wrote:
> > > > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> > > > 
> > > > Add /sys/kernel/mm/lru_gen/min_ttl_ms for thrashing prevention.
> > > > Compared with the size-based approach, e.g., [1], this time-based
> > > > approach has the following advantages:
> > > > 1) It's easier to configure because it's agnostic to applications and
> > > >    memory sizes.
> > > > 2) It's more reliable because it's directly wired to the OOM killer.
> > > > 
> > > > Add /sys/kernel/debug/lru_gen for working set estimation and proactive
> > > > reclaim. Compared with the page table-based approach and the PFN-based
> > > > approach, e.g., mm/damon/[vp]addr.c, this lruvec-based approach has
> > > > the following advantages:
> > > > 1) It offers better choices because it's aware of memcgs, NUMA nodes,
> > > >    shared mappings and unmapped page cache.
> > > > 2) It's more scalable because it's O(nr_hot_evictable_pages), whereas
> > > >    the PFN-based approach is O(nr_total_pages).
> > > > 
> > > > Add /sys/kernel/debug/lru_gen_full for debugging.
> > > > 
> > > > [1] https://lore.kernel.org/lkml/20211130201652.2218636d at mail.inbox.lv/
> > > > 
> > > > Signed-off-by: Yu Zhao <yuzhao at google.com>
> > > > Tested-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
> > > > ---
> > > >  Documentation/vm/index.rst        |   1 +
> > > >  Documentation/vm/multigen_lru.rst |  62 +++++
> > > 
> > > The description of user visible interfaces should go to
> > > Documentation/admin-guide/mm
> > > 
> > > Documentation/vm/multigen_lru.rst should have contained design description
> > > and the implementation details and it would be great to actually have such
> > > document.
> > 
> > Will do, thanks.
> > 
> > > >  include/linux/nodemask.h          |   1 +
> > > >  mm/vmscan.c                       | 415 ++++++++++++++++++++++++++++++
> > > >  4 files changed, 479 insertions(+)
> > > >  create mode 100644 Documentation/vm/multigen_lru.rst
> > > > 
> > > > diff --git a/Documentation/vm/index.rst b/Documentation/vm/index.rst
> > > > index 6f5ffef4b716..f25e755b4ff4 100644
> > > > --- a/Documentation/vm/index.rst
> > > > +++ b/Documentation/vm/index.rst
> > > > @@ -38,3 +38,4 @@ algorithms.  If you are looking for advice on simply allocating memory, see the
> > > >     unevictable-lru
> > > >     z3fold
> > > >     zsmalloc
> > > > +   multigen_lru
> > > > diff --git a/Documentation/vm/multigen_lru.rst b/Documentation/vm/multigen_lru.rst
> > > > new file mode 100644
> > > > index 000000000000..6f9e0181348b
> > > > --- /dev/null
> > > > +++ b/Documentation/vm/multigen_lru.rst
> > > > @@ -0,0 +1,62 @@
> > > > +.. SPDX-License-Identifier: GPL-2.0
> > > > +
> > > > +=====================
> > > > +Multigenerational LRU
> > > > +=====================
> > > > +
> > > > +Quick start
> > > > +===========
> > > > +Runtime configurations
> > > > +----------------------
> > > > +:Required: Write ``1`` to ``/sys/kernel/mm/lru_gen/enable`` if the
> > > > + feature wasn't enabled by default.
> > > 
> > > Required for what? This sentence seem to lack context. Maybe add an
> > > overview what is Multigenerational LRU so that users will have an idea what
> > > these knobs control.
> > 
> > Apparently I left an important part of this quick start in the next
> > patch, where Kconfig options are added. I'm wonder whether I should
> > squash the next patch into this one.
> 
> I think documentation deserves a separate patch.

Will do.


From daniel.thompson at linaro.org  Thu Jan 13 01:47:54 2022
From: daniel.thompson at linaro.org (Daniel Thompson)
Date: Thu, 13 Jan 2022 09:47:54 +0000
Subject: [PATCH v5 08/10] ARM: uaccess: add __{get,put}_kernel_nofault
In-Reply-To: <Yd8ZEbywqjXkAx9k@shell.armlinux.org.uk>
References: <20210726141141.2839385-1-arnd@kernel.org>
 <20210726141141.2839385-9-arnd@kernel.org>
 <Yd8P37V/N9EkwmYq@wychelm> <Yd8ZEbywqjXkAx9k@shell.armlinux.org.uk>
Message-ID: <20220113094754.6ei6ssiqbuw7tfj7@maple.lan>

On Wed, Jan 12, 2022 at 06:08:17PM +0000, Russell King (Oracle) wrote:
> On Wed, Jan 12, 2022 at 05:29:03PM +0000, Daniel Thompson wrote:
> > On Mon, Jul 26, 2021 at 04:11:39PM +0200, Arnd Bergmann wrote:
> > > From: Arnd Bergmann <arnd at arndb.de>
> > > 
> > > These mimic the behavior of get_user and put_user, except
> > > for domain switching, address limit checking and handling
> > > of mismatched sizes, none of which are relevant here.
> > > 
> > > To work with pre-Armv6 kernels, this has to avoid TUSER()
> > > inside of the new macros, the new approach passes the "t"
> > > string along with the opcode, which is a bit uglier but
> > > avoids duplicating more code.
> > > 
> > > As there is no __get_user_asm_dword(), I work around it
> > > by copying 32 bit at a time, which is possible because
> > > the output size is known.
> > > 
> > > Signed-off-by: Arnd Bergmann <arnd at arndb.de>
> > 
> > I've just been bisecting some regressions running the kgdbts tests on
> > arm and this patch came up.
> 
> So the software PAN code is working :)

Interesting. I noticed it was odd that kgdbts works just fine
if launched from kernel command line. I guess that runs before
PAN is activated. Neat.


> The kernel attempted to access an address that is in the userspace
> domain (NULL pointer) and took an exception.
> 
> I suppose we should handle a domain fault more gracefully - what are
> the required semantics if the kernel attempts a userspace access
> using one of the _nofault() accessors?

I think the best answer might well be that, if the arch provides
implementations of hooks such as copy_from_kernel_nofault_allowed()
then the kernel should never attempt a userspace access using the
_nofault() accessors. That means they can do whatever they like!

In other words something like the patch below looks like a promising
approach.


Daniel.


>From f66a63b504ff582f261a506c54ceab8c0e77a98c Mon Sep 17 00:00:00 2001
From: Daniel Thompson <daniel.thompson at linaro.org>
Date: Thu, 13 Jan 2022 09:34:45 +0000
Subject: [PATCH] arm: mm: Implement copy_from_kernel_nofault_allowed()

Currently copy_from_kernel_nofault() can actually fault (due to software
PAN) if we attempt userspace access. In any case, the documented
behaviour for this function is to return -ERANGE if we attempt an access
outside of kernel space.

Implementing copy_from_kernel_nofault_allowed() solves both these
problems.

Signed-off-by: Daniel Thompson <daniel.thompson at linaro.org>
---
 arch/arm/mm/Makefile  | 2 +-
 arch/arm/mm/maccess.c | 9 +++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mm/maccess.c

diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 3510503bc5e6..d1c5f4f256de 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -3,7 +3,7 @@
 # Makefile for the linux arm-specific parts of the memory manager.
 #
 
-obj-y				:= extable.o fault.o init.o iomap.o
+obj-y				:= extable.o fault.o init.o iomap.o maccess.o
 obj-y				+= dma-mapping$(MMUEXT).o
 obj-$(CONFIG_MMU)		+= fault-armv.o flush.o idmap.o ioremap.o \
 				   mmap.o pgd.o mmu.o pageattr.o
diff --git a/arch/arm/mm/maccess.c b/arch/arm/mm/maccess.c
new file mode 100644
index 000000000000..0251062cb40d
--- /dev/null
+++ b/arch/arm/mm/maccess.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/uaccess.h>
+#include <linux/kernel.h>
+
+bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
+{
+	return (unsigned long)unsafe_src >= TASK_SIZE;
+}
-- 
2.33.1


From raphael.gallais-pou at foss.st.com  Thu Jan 13 01:57:02 2022
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Thu, 13 Jan 2022 10:57:02 +0100
Subject: [PATCH 2/5] drm/stm: ltdc: add YCbCr 422 output support
In-Reply-To: <20211215214750.20105-1-yannick.fertre@foss.st.com>
References: <20211215214750.20105-1-yannick.fertre@foss.st.com>
Message-ID: <71eb2c1d-e2d6-7c4a-e66d-3f43c296eac7@foss.st.com>


On 12/15/21 10:47 PM, Yannick Fertre wrote:
> LTDC 40100 hw version supports the YCbCr 422 output,
> reducing the output pins from 24 to 16. This feature
> is useful for some external devices like HDMI bridges.
>
> Both ITU-R BT.601 & ITU-R BT.709 are supported.
>
> It is also possible to choose the chrominance order between
> * Cb is output first (Y0Cb, then Y1Cr, Y2Cb and so on).
> * Cr is output first (Y0Cr, then Y1Cb, Y2Cr and so on).
>
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>  drivers/gpu/drm/stm/ltdc.c | 44 +++++++++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/stm/ltdc.h |  1 +
>  2 files changed, 44 insertions(+), 1 deletion(-)


Hello Yannick,


Reviewed-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Thanks,

Rapha?l



From raphael.gallais-pou at foss.st.com  Thu Jan 13 01:59:54 2022
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Thu, 13 Jan 2022 10:59:54 +0100
Subject: [PATCH 3/5] drm/stm: ltdc: add per plane update support
In-Reply-To: <20211215214817.20310-1-yannick.fertre@foss.st.com>
References: <20211215214817.20310-1-yannick.fertre@foss.st.com>
Message-ID: <c86e1338-c8d6-f3b7-698c-73d8f04219cb@foss.st.com>


On 12/15/21 10:48 PM, Yannick Fertre wrote:
> Recent ltdc hardware versions offer the ability
> to update a plane independently of others planes.
> This is could be useful especially if a plane is
> assigned to another OS.
>
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>  drivers/gpu/drm/stm/ltdc.c | 26 +++++++++++++++++++++++---
>  drivers/gpu/drm/stm/ltdc.h |  1 +
>  2 files changed, 24 insertions(+), 3 deletions(-)

Hello Yannick,

Reviewed-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Thank you for this patch,
Rapha?l



From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:03:06 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:03:06 +0100
Subject: [PATCH v4 5/5] arm64: dts: mediatek: Correct system timer clock
 of MT8192
In-Reply-To: <20220113065822.11809-6-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
 <20220113065822.11809-6-allen-kh.cheng@mediatek.com>
Message-ID: <963c8993-a63e-2282-66e3-415ac897bded@collabora.com>

Il 13/01/22 07:58, allen-kh.cheng ha scritto:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the systimer clock property to point to the actual
> clock.
> 
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:03:06 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:03:06 +0100
Subject: [PATCH v4 4/5] arm64: dts: mediatek: Correct I2C clock of MT8192
In-Reply-To: <20220113065822.11809-5-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
 <20220113065822.11809-5-allen-kh.cheng@mediatek.com>
Message-ID: <b9068bf4-5019-f322-24e6-3869ab36ec90@collabora.com>

Il 13/01/22 07:58, allen-kh.cheng ha scritto:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the I2C clock property to point to the actual
> clock.
> 
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:03:07 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:03:07 +0100
Subject: [PATCH v4 3/5] arm64: dts: mediatek: Correct Nor Flash clock of
 MT8192
In-Reply-To: <20220113065822.11809-4-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
 <20220113065822.11809-4-allen-kh.cheng@mediatek.com>
Message-ID: <e9becd98-f9ea-3119-cfea-d94d04d5ebe6@collabora.com>

Il 13/01/22 07:58, allen-kh.cheng ha scritto:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the Nor Flash clock property to point to the actual
> clock.
> 
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:03:09 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:03:09 +0100
Subject: [PATCH v4 2/5] arm64: dts: mediatek: Correct SPI clock of MT8192
In-Reply-To: <20220113065822.11809-3-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
 <20220113065822.11809-3-allen-kh.cheng@mediatek.com>
Message-ID: <2eab99dd-07a9-65b1-b662-9d45538ce898@collabora.com>

Il 13/01/22 07:58, allen-kh.cheng ha scritto:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the SPI clock property to point to the actual
> clock.
> 
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:03:11 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:03:11 +0100
Subject: [PATCH v4 1/5] arm64: dts: mediatek: Correct uart clock of MT8192
In-Reply-To: <20220113065822.11809-2-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
 <20220113065822.11809-2-allen-kh.cheng@mediatek.com>
Message-ID: <3eeea0ce-0551-1186-7011-9bda27d62b98@collabora.com>

Il 13/01/22 07:58, allen-kh.cheng ha scritto:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> When the initial devicetree for mt8192 was added in 48489980e27e ("arm64:
> dts: Add Mediatek SoC MT8192 and evaluation board dts and Makefile"), the
> clock driver for mt8192 was not yet upstream, so the clock property nodes
> were set to the clk26m clock as a placeholder.
> 
> Given that the clock driver has since been added through 710573dee31b ("clk:
> mediatek: Add MT8192 basic clocks support"), as well as its dt-bindings
> through f35f1a23e0e1 ("clk: mediatek: Add dt-bindings of MT8192 clocks") and
> devicetree nodes through 5d2b897bc6f5 ("arm64: dts: mediatek: Add mt8192
> clock controllers"), fix the uart clock property to point to the actual
> clock.
> 
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:11:40 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:11:40 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
Message-ID: <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>

Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
> Il 12/11/21 11:55, Yong Wu ha scritto:
>> After this patchset, mtk_vcodec_release_enc_pm has only one line.
>> then remove that function, use pm_runtime_disable instead.
>>
>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
>> rename it from the _pm to _clk.
>>
>> No functional change.
>>
>> CC: Tiffany Lin <tiffany.lin at mediatek.com>
>> CC: Irui Wang <irui.wang at mediatek.com>
>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> 
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> 

Hello Yong,
the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans has
scheduled that for v5.18.

Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the
media: mtk-vcodec: *) from this series?

For the records, I think that after sending v10 this series is ready to be merged,
as it was well reviewed and also tested on many MTK platforms.

Thank you,
- Angelo


From hverkuil at xs4all.nl  Thu Jan 13 02:15:48 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 13 Jan 2022 11:15:48 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
 <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
Message-ID: <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>

On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote:
> Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
>> Il 12/11/21 11:55, Yong Wu ha scritto:
>>> After this patchset, mtk_vcodec_release_enc_pm has only one line.
>>> then remove that function, use pm_runtime_disable instead.
>>>
>>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
>>> rename it from the _pm to _clk.
>>>
>>> No functional change.
>>>
>>> CC: Tiffany Lin <tiffany.lin at mediatek.com>
>>> CC: Irui Wang <irui.wang at mediatek.com>
>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>
>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>
> 
> Hello Yong,
> the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans has
> scheduled that for v5.18.
> 
> Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the
> media: mtk-vcodec: *) from this series?
> 
> For the records, I think that after sending v10 this series is ready to be merged,
> as it was well reviewed and also tested on many MTK platforms.

Good to know. When I have the v10 I'll try to prioritize reviewing it and running
my usual tests.

Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches and fix
any issues (using common sense).

Regards,

	Hans

> 
> Thank you,
> - Angelo



From angelogioacchino.delregno at collabora.com  Thu Jan 13 02:17:52 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 11:17:52 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
 <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
 <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
Message-ID: <d3f4896f-d254-e0fb-0d2a-e78fbe50d84d@collabora.com>

Il 13/01/22 11:15, Hans Verkuil ha scritto:
> On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote:
>> Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
>>> Il 12/11/21 11:55, Yong Wu ha scritto:
>>>> After this patchset, mtk_vcodec_release_enc_pm has only one line.
>>>> then remove that function, use pm_runtime_disable instead.
>>>>
>>>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
>>>> rename it from the _pm to _clk.
>>>>
>>>> No functional change.
>>>>
>>>> CC: Tiffany Lin <tiffany.lin at mediatek.com>
>>>> CC: Irui Wang <irui.wang at mediatek.com>
>>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>>
>>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>
>>
>> Hello Yong,
>> the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans has
>> scheduled that for v5.18.
>>
>> Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the
>> media: mtk-vcodec: *) from this series?
>>
>> For the records, I think that after sending v10 this series is ready to be merged,
>> as it was well reviewed and also tested on many MTK platforms.
> 
> Good to know. When I have the v10 I'll try to prioritize reviewing it and running
> my usual tests.

Thank you Hans, that's very much appreciated!

> 
> Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches and fix
> any issues (using common sense).
> 
> Regards,
> 
> 	Hans
> 
>>
>> Thank you,
>> - Angelo
> 




From raphael.gallais-pou at foss.st.com  Thu Jan 13 02:21:05 2022
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Thu, 13 Jan 2022 11:21:05 +0100
Subject: [PATCH 4/5] drm/stm: ltdc: add support of flexible pixel formats
In-Reply-To: <20211215214835.20593-1-yannick.fertre@foss.st.com>
References: <20211215214835.20593-1-yannick.fertre@foss.st.com>
Message-ID: <9a718ddb-163b-6c9a-b83b-a52df94805cf@foss.st.com>


On 12/15/21 10:48 PM, Yannick Fertre wrote:
> This feature allows the generation of any RGB pixel format.
> The list of supported formats is no longer linked to the
> register LXPFCR_PF, that the reason why a list of drm formats is
> defined for each display controller version.
>
> Signed-off-by: Yannick Fertre <yannick.fertre at foss.st.com>
> ---
>  drivers/gpu/drm/stm/ltdc.c | 196 ++++++++++++++++++++++++++-----------
>  drivers/gpu/drm/stm/ltdc.h |   5 +-
>  2 files changed, 145 insertions(+), 56 deletions(-)


Hello Yannick,


Reviewed-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
Tested-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>

Many thanks, this is an interesting patch.

Rapha?l



From mark.rutland at arm.com  Thu Jan 13 02:24:07 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 13 Jan 2022 10:24:07 +0000
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
In-Reply-To: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
References: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>

Hi Anshuman,

This looks fine structurally, I'm just not sure of a couple of details because
I can't find the relevant documentation -- more on that below.

On Thu, Jan 13, 2022 at 03:11:08PM +0530, Anshuman Khandual wrote:
> MDCR_EL3.SBRBE resets to an UNKNOWN value. Configure it to allow the BRBE
> buffer usage and direct register access in the non-secure world. But just
> before that, check AA64DFR0_EL1.BRBE and make sure BRBE is implemented. We
> still continue to reset MDCR_EL3 register to zero with the exception of
> MDCR_EL3.NSPB, MDCR_EL3.NSTB and MDCR_EL3.SBRBE.

I'm struggling to find where the BRBE system register fields are documented.

I looked at the latest ARM ARM (DDI 0487G.b):

  https://developer.arm.com/documentation/ddi0487/gb/

... and the Armv9 supplement (DDI 0608A.a):

  https://developer.arm.com/documentation/ddi0608/aa/

... but AFAICT, neither of those describe the bit-positions of the relevant
fields, so I can't check that those are correct. The other extensions (at leat
TME) describe that in the supplement, so this looks like a bug/oversight. 

Am I looking at the right documents? If this is meant to be in the supplement,
could you please raise a bug report to get that fixed?

> 
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/aarch64/boot.S | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index bfbb6ec..ca1b292 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -103,6 +103,14 @@ ASM_FUNC(_start)
>  	ldr	x1, =(0x3 << 24)
>  	orr	x0, x0, x1
>  
> +1:	mrs     x1, id_aa64dfr0_el1
> +	ubfx    x1, x1, #52, #4
> +	cbz     x1, 1f
> +
> +	// Enable BRBE for the non-secure world.
> +	ldr     x1, =(0x3 << 32)
> +	orr     x0, x0, x1
> +

I assume this is the `SBRBE` field, which naming-wise sounds like it controls
Secure rather than Non-Secure (e,g. by way of comparison to `NSPB`). Is that
correct? What effect does the value 0x3 have?

Thanks,
Mark.

>  1:	msr	mdcr_el3, x0			// Disable traps to EL3
>  
>  	mrs	x0, id_aa64pfr0_el1
> -- 
> 2.7.4
> 


From anders.roxell at linaro.org  Thu Jan 13 02:27:46 2022
From: anders.roxell at linaro.org (Anders Roxell)
Date: Thu, 13 Jan 2022 11:27:46 +0100
Subject: [PATCH] arm64: dts: amlogic: meson-s4-aq222: fix waring for leading 0s
Message-ID: <20220113102746.598763-1-anders.roxell@linaro.org>

When building allmodconfig the following waring shows up:

arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts:21.18-24.4: Warning (unit_address_format): /memory at 00000000: unit name should not have leading 0s

Fixing the waring by dropping all the '0' except one.

Fixes: 1c1475389af0 ("arm64: dts: add support for S4 based Amlogic AQ222")
Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
---
 arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
index a942d7e06d6e..8ffbcb2b1ac5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
@@ -18,7 +18,7 @@ aliases {
 		serial0 = &uart_B;
 	};
 
-	memory at 00000000 {
+	memory at 0 {
 		device_type = "memory";
 		reg = <0x0 0x0 0x0 0x40000000>;
 	};
-- 
2.34.1



From stano.jakubek at gmail.com  Thu Jan 13 02:28:42 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Thu, 13 Jan 2022 11:28:42 +0100
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add 8devices
Message-ID: <20220113102842.GA4357@standask-GA-A55M-S2HP>

The vendor prefix for 8devices [1] is used in device tree [2], but was
not documented so far. Add it to the schema to document it.

[1] https://www.8devices.com/
[2] arch/arm/boot/dts/qcom-ipq4018-jalapeno.dts

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Reworked patch description
  - Rebase on next-20220113

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b3de81e8290f..8928884ba186 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -25,6 +25,8 @@ patternProperties:
   # Keep list in alphabetical order.
   "^70mai,.*":
     description: 70mai Co., Ltd.
+  "^8dev,.*":
+    description: 8devices, UAB
   "^abb,.*":
     description: ABB
   "^abilis,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Thu Jan 13 02:29:26 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Thu, 13 Jan 2022 11:29:26 +0100
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add F(x)tec
Message-ID: <20220113102926.GA4388@standask-GA-A55M-S2HP>

The vendor prefix for F(x)tec [1] is used in device tree [2], but was
not documented so far. Add it to the schema to document it.

[1] https://www.fxtec.com/
[2] arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Reworked patch description
  - Rebase on next-20220113

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b3de81e8290f..ff59ce74f4d1 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -443,6 +443,8 @@ patternProperties:
     description: Freescale Semiconductor
   "^fujitsu,.*":
     description: Fujitsu Ltd.
+  "^fxtec,.*":
+    description: FX Technology Ltd.
   "^gardena,.*":
     description: GARDENA GmbH
   "^gateworks,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Thu Jan 13 02:30:05 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Thu, 13 Jan 2022 11:30:05 +0100
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Huawei
Message-ID: <20220113103005.GA4421@standask-GA-A55M-S2HP>

The vendor prefix for Huawei [1] is used in device trees [2][3], but was
not documented so far. Add it to the schema to document it.

[1] https://www.huawei.com/en/
[2] arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
[3] arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Reworked patch description
  - Rebase on next-20220113

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b3de81e8290f..76e89f26820d 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -519,6 +519,8 @@ patternProperties:
     description: HannStar Display Co.
   "^holtek,.*":
     description: Holtek Semiconductor, Inc.
+  "^huawei,.*":
+    description: Huawei Technologies Co., Ltd.
   "^hugsun,.*":
     description: Shenzhen Hugsun Technology Co. Ltd.
   "^hwacom,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Thu Jan 13 02:30:36 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Thu, 13 Jan 2022 11:30:36 +0100
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Thundercomm
Message-ID: <20220113103036.GA4456@standask-GA-A55M-S2HP>

The vendor prefix for Thundercomm [1] is used in device tree [2], but
was not documented so far. Add it to the schema to document it.

[1] https://www.thundercomm.com/
[2] arch/arm64/boot/dts/qcom/sdm845-db845c.dts

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Reworked patch description
  - Rebase on next-20220113

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b3de81e8290f..81815b8fb0a5 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1211,6 +1211,8 @@ patternProperties:
     description: THine Electronics, Inc.
   "^thingyjp,.*":
     description: thingy.jp
+  "^thundercomm,.*":
+    description: Thundercomm Technology Co., Ltd.
   "^ti,.*":
     description: Texas Instruments
   "^tianma,.*":
-- 
2.25.1



From stano.jakubek at gmail.com  Thu Jan 13 02:31:10 2022
From: stano.jakubek at gmail.com (Stanislav Jakubek)
Date: Thu, 13 Jan 2022 11:31:10 +0100
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Wingtech
Message-ID: <20220113103110.GA4488@standask-GA-A55M-S2HP>

The vendor prefix for Wingtech [1] is used in device tree [2], but was
not documented so far. Add it to the schema to document it.

[1] http://www.wingtech.com/en
[2] arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts

Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
---
Changes in v2:
  - Reworked patch description
  - Rebase on next-20220113

 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index b3de81e8290f..eaf7f4940978 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1338,6 +1338,8 @@ patternProperties:
     description: Wiligear, Ltd.
   "^winbond,.*":
     description: Winbond Electronics corp.
+  "^wingtech,.*":
+    description: Wingtech Technology Co., Ltd.
   "^winlink,.*":
     description: WinLink Co., Ltd
   "^winstar,.*":
-- 
2.25.1



From aneesh.kumar at linux.ibm.com  Thu Jan 13 02:31:31 2022
From: aneesh.kumar at linux.ibm.com (Aneesh Kumar K.V)
Date: Thu, 13 Jan 2022 16:01:31 +0530
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <20220104202227.2903605-9-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
Message-ID: <87a6g0nczg.fsf@linux.ibm.com>

Yu Zhao <yuzhao at google.com> writes:

> Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.


Got the below lockdep warning while using the above kill/enable switch


[   84.252952] ======================================================
[   84.253012] WARNING: possible circular locking dependency detected
[   84.253074] 5.16.0-rc8-16204-g1cdcf1120b31 #511 Not tainted
[   84.253135] ------------------------------------------------------
[   84.253194] bash/2862 is trying to acquire lock:
[   84.253243] c0000000021ff740 (cgroup_mutex){+.+.}-{3:3}, at: store_enable+0x80/0x1510
[   84.253340]
               but task is already holding lock:
[   84.253410] c000000002221348 (mem_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x30/0x50
[   84.253503]
               which lock already depends on the new lock.

[   84.253608]
               the existing dependency chain (in reverse order) is:
[   84.253693]
               -> #2 (mem_hotplug_lock){++++}-{0:0}:
[   84.253768]        lock_acquire+0x134/0x4a0
[   84.253821]        percpu_down_write+0x80/0x1c0
[   84.253872]        try_online_node+0x40/0x90
[   84.253924]        cpu_up+0x7c/0x160
[   84.253976]        bringup_nonboot_cpus+0xc4/0x120
[   84.254027]        smp_init+0x48/0xd4
[   84.254079]        kernel_init_freeable+0x274/0x45c
[   84.254134]        kernel_init+0x44/0x194
[   84.254188]        ret_from_kernel_thread+0x5c/0x64
[   84.254241]
               -> #1 (cpu_hotplug_lock){++++}-{0:0}:
[   84.254321]        lock_acquire+0x134/0x4a0
[   84.254373]        cpus_read_lock+0x6c/0x180
[   84.254426]        static_key_disable+0x24/0x50
[   84.254477]        rebind_subsystems+0x3b0/0x5a0
[   84.254528]        cgroup_setup_root+0x24c/0x530
[   84.254581]        cgroup1_get_tree+0x7d8/0xb80
[   84.254638]        vfs_get_tree+0x48/0x150
[   84.254695]        path_mount+0x8b8/0xd20
[   84.254752]        do_mount+0xb8/0xe0
[   84.254808]        sys_mount+0x250/0x390
[   84.254863]        system_call_exception+0x15c/0x2b0
[   84.254932]        system_call_common+0xec/0x250
[   84.254989]
               -> #0 (cgroup_mutex){+.+.}-{3:3}:
[   84.255072]        check_prev_add+0x180/0x1050
[   84.255129]        __lock_acquire+0x17b8/0x25c0
[   84.255186]        lock_acquire+0x134/0x4a0
[   84.255243]        __mutex_lock+0xdc/0xa90
[   84.255300]        store_enable+0x80/0x1510
[   84.255356]        kobj_attr_store+0x2c/0x50
[   84.255413]        sysfs_kf_write+0x6c/0xb0
[   84.255471]        kernfs_fop_write_iter+0x1bc/0x2b0
[   84.255539]        new_sync_write+0x130/0x1d0
[   84.255594]        vfs_write+0x2cc/0x4c0
[   84.255645]        ksys_write+0x84/0x140
[   84.255699]        system_call_exception+0x15c/0x2b0
[   84.255771]        system_call_common+0xec/0x250
[   84.255829]
               other info that might help us debug this:

[   84.255933] Chain exists of:
                 cgroup_mutex --> cpu_hotplug_lock --> mem_hotplug_lock

[   84.256070]  Possible unsafe locking scenario:

[   84.256149]        CPU0                    CPU1
[   84.256201]        ----                    ----
[   84.256255]   lock(mem_hotplug_lock);
[   84.256311]                                lock(cpu_hotplug_lock);
[   84.256380]                                lock(mem_hotplug_lock);
[   84.256448]   lock(cgroup_mutex);
[   84.256491]
                *** DEADLOCK ***

[   84.256571] 5 locks held by bash/2862:
[   84.256626]  #0: c00000002043d460 (sb_writers#5){.+.+}-{0:0}, at: ksys_write+0x84/0x140
[   84.256728]  #1: c00000004bafc888 (&of->mutex){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x178/0x2b0
[   84.256830]  #2: c000000020b993b8 (kn->active#207){.+.+}-{0:0}, at: kernfs_fop_write_iter+0x184/0x2b0
[   84.256942]  #3: c0000000020e5cd0 (cpu_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x20/0x50
[   84.257045]  #4: c000000002221348 (mem_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x30/0x50
[   84.257152]
               stack backtrace:
[   84.257220] CPU: 107 PID: 2862 Comm: bash Not tainted 5.16.0-rc8-16204-g1cdcf1120b31 #511
[   84.257309] Call Trace:
[   84.257346] [c000000040d5b4a0] [c000000000a89f94] dump_stack_lvl+0x98/0xe0 (unreliable)
[   84.257438] [c000000040d5b4e0] [c000000000267244] print_circular_bug.isra.0+0x3b4/0x3e0
[   84.257528] [c000000040d5b580] [c0000000002673e0] check_noncircular+0x170/0x1a0
[   84.257605] [c000000040d5b650] [c000000000268be0] check_prev_add+0x180/0x1050
[   84.257683] [c000000040d5b710] [c00000000026ca48] __lock_acquire+0x17b8/0x25c0
[   84.257760] [c000000040d5b840] [c00000000026e4c4] lock_acquire+0x134/0x4a0
[   84.257837] [c000000040d5b940] [c00000000148a53c] __mutex_lock+0xdc/0xa90
[   84.257914] [c000000040d5ba60] [c0000000004d5080] store_enable+0x80/0x1510
[   84.257989] [c000000040d5bbc0] [c000000000a9286c] kobj_attr_store+0x2c/0x50
[   84.258066] [c000000040d5bbe0] [c000000000752c4c] sysfs_kf_write+0x6c/0xb0
[   84.258143] [c000000040d5bc20] [c000000000750fcc] kernfs_fop_write_iter+0x1bc/0x2b0
[   84.258219] [c000000040d5bc70] [c000000000615df0] new_sync_write+0x130/0x1d0
[   84.258295] [c000000040d5bd10] [c00000000061997c] vfs_write+0x2cc/0x4c0
[   84.258373] [c000000040d5bd60] [c000000000619d54] ksys_write+0x84/0x140
[   84.258450] [c000000040d5bdb0] [c00000000002c91c] system_call_exception+0x15c/0x2b0
[   84.258528] [c000000040d5be10] [c00000000000c64c] system_call_common+0xec/0x250
[   84.258604] --- interrupt: c00 at 0x79c551e76554
[   84.258658] NIP:  000079c551e76554 LR: 000079c551de2674 CTR: 0000000000000000
[   84.258732] REGS: c000000040d5be80 TRAP: 0c00   Not tainted  (5.16.0-rc8-16204-g1cdcf1120b31)
[   84.258817] MSR:  800000000280f033 <SF,VEC,VSX,EE,PR,FP,ME,IR,DR,RI,LE>  CR: 28422428  XER: 00000000
[   84.258931] IRQMASK: 0
               GPR00: 0000000000000004 00007fffc8e9a320 000079c551f77100 0000000000000001
               GPR04: 0000017190973cc0 0000000000000002 0000000000000010 0000017190973cc0
               GPR08: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
               GPR12: 0000000000000000 000079c5520ab1d0 0000017190943590 000001718749b738
               GPR16: 00000171873b0ae0 0000000000000000 0000000020000000 0000017190973a60
               GPR20: 0000000000000000 0000000000000001 0000017187443ca0 00007fffc8e9a514
               GPR24: 00007fffc8e9a510 000001718749b0d0 000079c551f719d8 000079c551f72308
               GPR28: 0000000000000002 000079c551f717e8 0000017190973cc0 0000000000000002
[   84.259600] NIP [000079c551e76554] 0x79c551e76554
[   84.259651] LR [000079c551de2674] 0x79c551de2674
[   84.259701] --- interrupt: c00


From pali at kernel.org  Thu Jan 13 02:35:23 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 13 Jan 2022 11:35:23 +0100
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220113001921.GA286275@bhelgaas>
References: <20220107234658.oav7oofcbwa7o6sz@pali>
 <20220113001921.GA286275@bhelgaas>
Message-ID: <20220113103523.5usmja7bp44f7ju7@pali>

On Wednesday 12 January 2022 18:19:21 Bjorn Helgaas wrote:
> On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Roh?r wrote:
> > On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> > > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > > > Properly propagate failure from mvebu_pcie_add_windows() function back to
> > > > > > the caller mvebu_pci_bridge_emul_base_conf_write() and correctly updates
> > > > > > PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16 registers on error.
> > > > > > On error set base value higher than limit value which indicates that
> > > > > > address range is disabled. 
> > > > > 
> > > > > Does the spec say that if software programs something invalid,
> > > > > hardware should proactively set the base and limit registers to
> > > > > disable the window?
> > > > 
> > > > No. But this patch address something totally different. Software can do
> > > > fully valid operation, e.g. try to set forwarding memory window as large
> > > > as possible. But because this driver "emulates" pci bridge by calling
> > > > software/kernel function (mvebu_pcie_add_windows), some operations which
> > > > in real HW cannot happen, are possible in software.
> > > > 
> > > > For example there are limitations in sizes of forwarding memory windows,
> > > > because it is done by mvebu-mbus driver, which is responsible for
> > > > configuring mapping and forwarding of PCIe I/O and MEM windows. And due
> > > > to Marvell HW, there are restrictions which are not in PCIe HW.
> > > > 
> > > > Currently if such error happens, obviously kernel is not able to set
> > > > PCIe windows and it just print warnings to dmesg. Trying to access these
> > > > windows would result in the worst case in crashes.
> > > > 
> > > > With this change when mvebu_pcie_add_windows() function fails then into
> > > > emulated config space is put information that particular forwarding
> > > > window is disabled. I think that it is better to indicate it in config
> > > > space what is the current "reality" of hardware configuration. If window
> > > > is disabled in real-HW (meaning in mvebu-mbus driver) then show it also
> > > > in emulated config space of pci bridge.
> > > > 
> > > > Do you have better idea what should emulated pci bridge do, if software
> > > > try to set fully valid configuration of forwarding window, but it is not
> > > > possible to achieve it (even compliant PCI bridge must be able to do
> > > > it)?
> > > 
> > > On an ACPI system, the host bridge window sizes are constrained by the
> > > host bridge _CRS method.  I assume there's a similar constraint in DT.
> > > 
> > > Is the fact that mvebu_pcie_add_windows() can fail a symptom of a DT
> > > that describes more available space than mvebu-bus can map?
> > 
> > Memory maps for mvebu are more complicated. There is no explicit size in
> > DT ranges property as it is dynamically allocated by mvebu-mbus:
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47
> 
> I wish I knew how to really interpret those "ranges" properties.  (Is
> there a good description in Documentation/ somewhere?  All I've found
> so far is https://elinux.org/Device_Tree_Usage, which is good, but
> doesn't match this example completely.)
> 
> I see:
> 
>   pciec: pcie {
>     ranges = <...>;
>     pcie1: pcie at 1,0 {
>       ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
> 	        0x81000000 0 0 0x81000000 0x1 0 1 0>;
>     };
>     pcie2: pcie at 2,0 {
>       ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
> 	        0x81000000 0 0 0x81000000 0x2 0 1 0>;
>     };
>     pcie3: pcie at 3,0 {
>       ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
> 	        0x81000000 0 0 0x81000000 0x3 0 1 0>;
>     };
>     pcie4: pcie at 4,0 {
>       ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
> 	        0x81000000 0 0 0x81000000 0x4 0 1 0>;
>     };
>   };
> 
> What does this look like in dmesg, i.e., what CPU address ranges are
> mapped to what PCI bus addresses?

These explicit ranges in DT are probably ignored as they are invalid.
You can see them (0xffffffffffffffff) in dmesg. MEM and I/O resources
are parsed in pci-mvebu.c driver in mvebu_pcie_parse_request_resources()
function.

Here is relevant dmesg output:

[    0.671607] mvebu-pcie soc:pcie: host bridge /soc/pcie ranges:
[    0.677474] mvebu-pcie soc:pcie:      MEM 0x00f1080000..0x00f1081fff -> 0x0000080000
[    0.685245] mvebu-pcie soc:pcie:      MEM 0x00f1040000..0x00f1041fff -> 0x0000040000
[    0.693017] mvebu-pcie soc:pcie:      MEM 0x00f1044000..0x00f1045fff -> 0x0000044000
[    0.700788] mvebu-pcie soc:pcie:      MEM 0x00f1048000..0x00f1049fff -> 0x0000048000
[    0.708562] mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
[    0.716856] mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
[    0.725146] mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
[    0.733438] mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
[    0.741730] mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
[    0.750022] mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
[    0.758314] mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
[    0.766606] mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
[    0.907763] mvebu-pcie soc:pcie: PCI host bridge to bus 0000:00
[    0.913698] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.919203] pci_bus 0000:00: root bus resource [mem 0xf1080000-0xf1081fff] (bus address [0x00080000-0x00081fff])
[    0.929406] pci_bus 0000:00: root bus resource [mem 0xf1040000-0xf1041fff] (bus address [0x00040000-0x00041fff])
[    0.939608] pci_bus 0000:00: root bus resource [mem 0xf1044000-0xf1045fff] (bus address [0x00044000-0x00045fff])
[    0.949812] pci_bus 0000:00: root bus resource [mem 0xf1048000-0xf1049fff] (bus address [0x00048000-0x00049fff])
[    0.960014] pci_bus 0000:00: root bus resource [mem 0xe0000000-0xe7ffffff]
[    0.966908] pci_bus 0000:00: root bus resource [io  0x1000-0xeffff]
[    0.973261] pci 0000:00:01.0: [11ab:6820] type 01 class 0x060400
[    0.979458] pci 0000:00:02.0: [11ab:6820] type 01 class 0x060400
[    0.985643] pci 0000:00:03.0: [11ab:6820] type 01 class 0x060400
[    0.992482] PCI: bus0: Fast back to back transfers disabled
[    0.998075] pci 0000:00:01.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.006108] pci 0000:00:02.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.014134] pci 0000:00:03.0: bridge configuration invalid ([bus 00-00]), reconfiguring
[    1.022242] pci 0000:01:00.0: [1e0f:0001] type 00 class 0x010802
[    1.028289] pci 0000:01:00.0: reg 0x10: [mem 0xc0000000-0xc0003fff 64bit]
[    1.035233] pci 0000:01:00.0: PME# supported from D0 D3hot
[    1.040787] pci 0000:01:00.0: 2.000 Gb/s available PCIe bandwidth, limited by 2.5 GT/s PCIe x1 link at 0000:00:01.0 (capable of 31.504 Gb/s with 8.0 GT/s PCIe x4 link)
[    1.056630] PCI: bus1: Fast back to back transfers disabled
[    1.062217] pci_bus 0000:01: busn_res: [bus 01-ff] end is updated to 01
[    1.068935] pci 0000:02:00.0: [168c:003c] type 00 class 0x028000
[    1.074975] pci 0000:02:00.0: reg 0x10: [mem 0xc8000000-0xc81fffff 64bit]
[    1.081817] pci 0000:02:00.0: reg 0x30: [mem 0xc8200000-0xc820ffff pref]
[    1.088611] pci 0000:02:00.0: supports D1 D2
[    1.093765] PCI: bus2: Fast back to back transfers disabled
[    1.099356] pci_bus 0000:02: busn_res: [bus 02-ff] end is updated to 02
[    1.106070] pci 0000:03:00.0: [168c:002e] type 00 class 0x028000
[    1.112110] pci 0000:03:00.0: reg 0x10: [mem 0xd0000000-0xd000ffff 64bit]
[    1.119031] pci 0000:03:00.0: supports D1
[    1.123049] pci 0000:03:00.0: PME# supported from D0 D1 D3hot
[    1.129688] PCI: bus3: Fast back to back transfers disabled
[    1.135274] pci_bus 0000:03: busn_res: [bus 03-ff] end is updated to 03
[    1.141926] pci 0000:00:01.0: BAR 8: assigned [mem 0xe0000000-0xe00fffff]
[    1.148738] pci 0000:00:02.0: BAR 8: assigned [mem 0xe0200000-0xe04fffff]
[    1.155544] pci 0000:00:03.0: BAR 8: assigned [mem 0xe0100000-0xe01fffff]
[    1.162357] pci 0000:01:00.0: BAR 0: assigned [mem 0xe0000000-0xe0003fff 64bit]
[    1.169696] pci 0000:00:01.0: PCI bridge to [bus 01]
[    1.174674] pci 0000:00:01.0:   bridge window [mem 0xe0000000-0xe00fffff]
[    1.181490] pci 0000:02:00.0: BAR 0: assigned [mem 0xe0200000-0xe03fffff 64bit]
[    1.188830] pci 0000:02:00.0: BAR 6: assigned [mem 0xe0400000-0xe040ffff pref]
[    1.196074] pci 0000:00:02.0: PCI bridge to [bus 02]
[    1.201050] pci 0000:00:02.0:   bridge window [mem 0xe0200000-0xe04fffff]
[    1.207867] pci 0000:03:00.0: BAR 0: assigned [mem 0xe0100000-0xe010ffff 64bit]
[    1.215200] pci 0000:00:03.0: PCI bridge to [bus 03]
[    1.220179] pci 0000:00:03.0:   bridge window [mem 0xe0100000-0xe01fffff]
[    1.227028] pcieport 0000:00:01.0: enabling device (0140 -> 0142)
[    1.233186] pcieport 0000:00:02.0: enabling device (0140 -> 0142)
[    1.239339] pcieport 0000:00:03.0: enabling device (0140 -> 0142)

And some more information from /proc:

$ cat /proc/ioports
00001000-000effff : PCI I/O

$ cat /proc/iomem
...
e0000000-e7ffffff : PCI MEM
  e0000000-e00fffff : PCI Bus 0000:01
    e0000000-e0003fff : 0000:01:00.0
      e0000000-e0003fff : nvme
  e0100000-e01fffff : PCI Bus 0000:03
    e0100000-e010ffff : 0000:03:00.0
      e0100000-e010ffff : ath9k
  e0200000-e04fffff : PCI Bus 0000:02
    e0200000-e03fffff : 0000:02:00.0
      e0200000-e03fffff : ath
    e0400000-e040ffff : 0000:02:00.0
...

> Are pcie1, pcie2, etc Root Ports?  Or are they each separate host
> bridges (they each have "bus-range = <0x00 0xff>")?

>From kernel point of view they are root ports. But in reality every of
these root port is on separate bus segment, but kernel pci-mvebu.c
driver merges all these segments/domains into one host bridge and put
all root ports into bus 0.

Here is lspci -tvnn output with topology:

$ lspci -tvnn
-[0000:00]-+-01.0-[01]----00.0  Device [1e0f:0001]
           +-02.0-[02]----00.0  Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter [168c:003c]
           \-03.0-[03]----00.0  Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e]

And without topology:

$ lspci -nn
00:01.0 PCI bridge [0604]: Marvell Technology Group Ltd. Device [11ab:6820] (rev 04)
00:02.0 PCI bridge [0604]: Marvell Technology Group Ltd. Device [11ab:6820] (rev 04)
00:03.0 PCI bridge [0604]: Marvell Technology Group Ltd. Device [11ab:6820] (rev 04)
01:00.0 Non-Volatile memory controller [0108]: Device [1e0f:0001]
02:00.0 Network controller [0280]: Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter [168c:003c]
03:00.0 Network controller [0280]: Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e] (rev 01)

Buses 1, 2 and 3 represents mPCIe cards, all of them are in reality in
separate bus segments and on different HW host bridges. So they do *not*
share access to config space, do *not* share INTx interrupts, etc...

> Is space from pciec dynamically assigned to pcie1, pcie2, etc?  If so,
> I assume there are more restrictions on the size and alignment than on
> PCI bridge windows, which allow size/alignment down to 1MB?

Yes, exactly. I do not know now all restrictions. At least there are
fixed number of memory slots and each has to be of size 2^N. They are
dynamically assigned by kernel mbus driver at time when somebody updates
BASE/LIMIT registers. And that kernel mbus driver takes care to split
non-aligned window size to more slots of size 2^N. And resources are
shared from pool with other HW parts (e.g. DMA), so other drivers loaded
in kernel can "eat" available slots before pci-mvebu and then there does
not have to be nothing to allocate for PCI.

But most Armada boards do not have exported all peripherals from SoC,
unconnected are disabled in DT and therefore exhaustion should not
happen.

> I'm trying to see how this could be described in ACPI because that's a
> fairly general model that accommodates most machines.  Possibly
> describing mvebu in ACPI would involve losing some flexibility.
> 
> Bjorn

I do not understand APCI model very well and I'm in impression that it
is impossible to represent mvebu in ACPI.


From narmstrong at baylibre.com  Thu Jan 13 02:39:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 13 Jan 2022 11:39:47 +0100
Subject: [PATCH] arm64: dts: amlogic: meson-s4-aq222: fix waring for
 leading 0s
In-Reply-To: <20220113102746.598763-1-anders.roxell@linaro.org>
References: <20220113102746.598763-1-anders.roxell@linaro.org>
Message-ID: <e0a8be1b-025f-a599-0298-3521066860b0@baylibre.com>

Hi,


On 13/01/2022 11:27, Anders Roxell wrote:
> When building allmodconfig the following waring shows up:
> 
> arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts:21.18-24.4: Warning (unit_address_format): /memory at 00000000: unit name should not have leading 0s
> 
> Fixing the waring by dropping all the '0' except one.
> 
> Fixes: 1c1475389af0 ("arm64: dts: add support for S4 based Amlogic AQ222")
> Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
> ---
>  arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> index a942d7e06d6e..8ffbcb2b1ac5 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts
> @@ -18,7 +18,7 @@ aliases {
>  		serial0 = &uart_B;
>  	};
>  
> -	memory at 00000000 {
> +	memory at 0 {
>  		device_type = "memory";
>  		reg = <0x0 0x0 0x0 0x40000000>;
>  	};
> 


Thanks, I also noticed and fixed in the commit directly, it should be fixed on next -next

Neil


From andriy.shevchenko at linux.intel.com  Thu Jan 13 02:47:53 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 13 Jan 2022 12:47:53 +0200
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <83670f12a4eda1d8aecde3c0bf225642106d1267.camel@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
 <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
 <83670f12a4eda1d8aecde3c0bf225642106d1267.camel@mediatek.com>
Message-ID: <YeADWXPGPW253ssR@smile.fi.intel.com>

On Thu, Jan 13, 2022 at 03:58:52PM +0800, Axe Yang wrote:

> But for the comment for 'dev_dbg', can you explain more about that?

Sure.

> On Tue, 2022-01-11 at 13:46 +0200, Andy Shevchenko wrote:
> > On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:

...

> > > +		host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> > > "state_eint");
> > > +		if (IS_ERR(host->pins_eint)) {
> > > +			dev_dbg(&pdev->dev, "Cannot find pinctrl
> > > eint!\n");
> > 
> > In debug mode of pin control this will bring a duplicate message.
> 
> Can you explain more about this comment?
> I don't understand what the 'duplicate message' refers for.

Have you chance to read the implementation of pinctrl_lookup_state()?

-- 
With Best Regards,
Andy Shevchenko




From sumit.semwal at linaro.org  Thu Jan 13 02:50:36 2022
From: sumit.semwal at linaro.org (Sumit Semwal)
Date: Thu, 13 Jan 2022 16:20:36 +0530
Subject: [PATCH v2] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <20220105063643.119874-1-guangming.cao@mediatek.com>
References: <c05749d0-4c24-8763-a459-27257b2524ed@amd.com>
 <20220105063643.119874-1-guangming.cao@mediatek.com>
Message-ID: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>

Hello Guangming,

On Wed, 5 Jan 2022 at 12:05, <guangming.cao at mediatek.com> wrote:
>
> From: Guangming.Cao <guangming.cao at mediatek.com>
>
> On Tue, 2022-01-04 at 08:47 +0100, Christian K?ig wrote:
> > Am 03.01.22 um 19:57 schrieb John Stultz:
> > > On Mon, Dec 27, 2021 at 1:52 AM <guangming.cao at mediatek.com> wrote:
> > > > From: Guangming <Guangming.Cao at mediatek.com>
> > > >
> > >
> > > Thanks for submitting this!
> > >
> > > > Add a size check for allcation since the allocation size is
> > >
> > > nit: "allocation" above.
> > >
> > > > always less than the total DRAM size.
> > >
> > > In general, it might be good to add more context to the commit
> > > message
> > > to better answer *why* this change is needed rather than what the
> > > change is doing.  ie: What negative thing happens without this
> > > change?
> > > And so how does this change avoid or improve things?
> >
> > Completely agree, just one little addition: Could you also add this
> > why
> > as comment to the code?
> >
> > When we stumble over this five years from now it is absolutely not
> > obvious why we do this.
> >
> > Thanks,
> > Christian.
> >
> Thanks for your reply!
> I will update the related reason in the patch later.
>
> The reason for adding this check is that we met a case that the user
> sent an invalid size(It seems it's a negative value, MSB is 0xff, it's
> larger than DRAM size after convert it to size_t) to dma-heap to alloc
> memory, and this allocation was running on a process(such as "gralloc"
> on Android device) can't be killed by OOM flow, and we also couldn't
> find the related dmabuf in "dma_buf_debug_show" because the related
> dmabuf was not exported yet since the allocation is still on going.
>
> Since this invalid argument case can be prevented at dma-heap side, so,
> I added this size check, and moreover, to let debug it easily, I also
> added logs when size is bigger than a threshold we set in mtk system
> heap.
> If you think that print logs in dma-heap framework is better, I will
> update it in next version.
>
> If you have better solution(such as dump the size under allocating
> in "dma_buf_debug_show", which maybe need add global variable to record
> it), please kindly let me know.

Thank you for the patch!

I think just adding the reasoning above as the commit message and a
comment in the code should be enough for now; the debug parts may be
easy to add in case someone runs into issues.

> Thanks :)
> Guangming

Best,
Sumit.

>
> > >
> > >
> > > > Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> > > > Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
> > > > ---
> > > > v2: 1. update size limitation as total_dram page size.
> > > >      2. update commit message
> > > > ---
> > > >   drivers/dma-buf/dma-heap.c | 2 ++
> > > >   1 file changed, 2 insertions(+)
> > > >
> > > > diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-
> > > > heap.c
> > > > index 56bf5ad01ad5..e39d2be98d69 100644
> > > > --- a/drivers/dma-buf/dma-heap.c
> > > > +++ b/drivers/dma-buf/dma-heap.c
> > > > @@ -55,6 +55,8 @@ static int dma_heap_buffer_alloc(struct
> > > > dma_heap *heap, size_t len,
> > > >          struct dma_buf *dmabuf;
> > > >          int fd;
> > > >
> > > > +       if (len / PAGE_SIZE > totalram_pages())
> > > > +               return -EINVAL;
> > >
> > > This seems sane. I know ION used to have some 1/2 of memory cap to
> > > avoid unnecessary memory pressure on crazy allocations.
> > >
> > > Could you send again with an improved commit message?
> > >
> > > thanks
> > > -john
> >
> >



--
Thanks and regards,

Sumit Semwal (he / him)
Tech Lead - LCG, Vertical Technologies
Linaro.org ? Open source software for ARM SoCs


From sumit.garg at linaro.org  Thu Jan 13 03:00:42 2022
From: sumit.garg at linaro.org (Sumit Garg)
Date: Thu, 13 Jan 2022 16:30:42 +0530
Subject: [PATCH v7 0/7] arm64: Add framework to turn an IPI as NMI
In-Reply-To: <Yd8sfP0IXN4KiLuP@gabell>
References: <1604317487-14543-1-git-send-email-sumit.garg@linaro.org>
 <CAGb2v66mVoWiCibjq25d3Z8OvbWNO9p+vMo761RJLiD-BqVbqw@mail.gmail.com>
 <CAFA6WYN-wpQ86ik5FeAhimCcCoRAs9_g3BGL8CiSUmHxfeCSbg@mail.gmail.com>
 <Yd8sfP0IXN4KiLuP@gabell>
Message-ID: <CAFA6WYO0+LQ=mB1spCstt0cNZ0G+sZu_+Wrv6BKSeXqF5SRq4A@mail.gmail.com>

Hi Masa,

On Thu, 13 Jan 2022 at 01:01, Masayoshi Mizuma <msys.mizuma at gmail.com> wrote:
>
> On Wed, Jul 07, 2021 at 11:29:29AM +0530, Sumit Garg wrote:
> > On Fri, 25 Jun 2021 at 20:26, Chen-Yu Tsai <wens at kernel.org> wrote:
> > >
> > > On Mon, Nov 2, 2020 at 7:46 PM Sumit Garg <sumit.garg at linaro.org> wrote:
> > > >
> > > > With pseudo NMIs support available its possible to configure SGIs to be
> > > > triggered as pseudo NMIs running in NMI context. And kernel features
> > > > such as:
> > > > - NMI backtrace can leverage IPI turned as NMI to get a backtrace of CPU
> > > >   stuck in hard lockup using magic SYSRQ.
> > > > - kgdb relies on NMI support to round up CPUs which are stuck in hard
> > > >   lockup state with interrupts disabled.
> > > >
> > > > This patch-set adds framework to turn an IPI as NMI which can be triggered
> > > > as a pseudo NMI which in turn invokes registered NMI handlers.
> > > >
> > > > After this patch-set we should be able to get a backtrace for a CPU
> > > > stuck in HARDLOCKUP. Have a look at an examples below from a hard lockup
> > > > testcase run on Developerbox:
> > > >
> > > > $ echo HARDLOCKUP > /sys/kernel/debug/provoke-crash/DIRECT
> > > >
> > > > NMI backtrace:
> > > > ==============
> > > >
> > > > # Issue Magic SysRq to dump backtrace
> > > >
> > > > [  376.894502] NMI backtrace for cpu 8
> > > > [  376.894506] CPU: 8 PID: 555 Comm: bash Not tainted 5.9.0-rc3-00740-g06ff047-dirty #242
> > > > [  376.894510] Hardware name: Socionext SynQuacer E-series DeveloperBox, BIOS build #73 Apr  6 2020
> > > > [  376.894514] pstate: 40000005 (nZcv daif -PAN -UAO BTYPE=--)
> > > > [  376.894517] pc : lkdtm_HARDLOCKUP+0x8/0x18
> > > > [  376.894520] lr : lkdtm_do_action+0x24/0x30
> > > > [  376.894524] sp : ffff800012cebd20
> > > > [  376.894527] pmr_save: 00000060
> > > > [  376.894530] x29: ffff800012cebd20 x28: ffff000875ae8000
> > > > [  376.894540] x27: 0000000000000000 x26: 0000000000000000
> > > > [  376.894550] x25: 000000000000001a x24: ffff800012cebe40
> > > > [  376.894560] x23: 000000000000000b x22: ffff800010fc5040
> > > > [  376.894569] x21: ffff000878b61000 x20: ffff8000113b2870
> > > > [  376.894579] x19: 000000000000001b x18: 0000000000000010
> > > > [  376.894588] x17: 0000000000000000 x16: 0000000000000000
> > > > [  376.894598] x15: ffff000875ae8470 x14: 00000000000002ad
> > > > [  376.894613] x13: 0000000000000000 x12: 0000000000000000
> > > > [  376.894622] x11: 0000000000000007 x10: 00000000000009c0
> > > > [  376.894631] x9 : ffff800012ceba80 x8 : ffff000875ae8a20
> > > > [  376.894641] x7 : ffff00087f6b3280 x6 : ffff00087f6b3200
> > > > [  376.894651] x5 : 0000000000000000 x4 : ffff00087f6a91f8
> > > > [  376.894660] x3 : ffff00087f6b0120 x2 : 1aa310cec69eb500
> > > > [  376.894670] x1 : 0000000000000000 x0 : 0000000000000060
> > > > [  376.894679] Call trace:
> > > > [  376.894683]  lkdtm_HARDLOCKUP+0x8/0x18
> > > > [  376.894686]  direct_entry+0x124/0x1c0
> > > > [  376.894689]  full_proxy_write+0x60/0xb0
> > > > [  376.894693]  vfs_write+0xf0/0x230
> > > > [  376.894696]  ksys_write+0x6c/0xf8
> > > > [  376.894699]  __arm64_sys_write+0x1c/0x28
> > > > [  376.894703]  el0_svc_common.constprop.0+0x74/0x1f0
> > > > [  376.894707]  do_el0_svc+0x24/0x90
> > > > [  376.894710]  el0_sync_handler+0x180/0x2f8
> > > > [  376.894713]  el0_sync+0x158/0x180
> > > >
> > > > KGDB:
> > > > =====
> > > >
> > > > # Enter kdb via Magic SysRq
> > > >
> > > > [6]kdb> btc
> > > > btc: cpu status: Currently on cpu 6
> > > > Available cpus: 0-5(I), 6, 7(I), 8, 9-23(I)
> > > > <snip>
> > > > Stack traceback for pid 555
> > > > 0xffff000875ae8000      555      554  1    8   R  0xffff000875ae89c0  bash
> > > > CPU: 8 PID: 555 Comm: bash Not tainted 5.9.0-rc3-00740-g06ff047-dirty #242
> > > > Hardware name: Socionext SynQuacer E-series DeveloperBox, BIOS build #73 Apr  6 2020
> > > > Call trace:
> > > >  dump_backtrace+0x0/0x1a0
> > > >  show_stack+0x18/0x28
> > > >  dump_stack+0xc0/0x11c
> > > >  kgdb_cpu_enter+0x648/0x660
> > > >  kgdb_nmicallback+0xa0/0xa8
> > > >  ipi_kgdb_nmicallback+0x24/0x30
> > > >  ipi_nmi_handler+0x48/0x60
> > > >  handle_percpu_devid_fasteoi_ipi+0x74/0x88
> > > >  generic_handle_irq+0x30/0x48
> > > >  handle_domain_nmi+0x48/0x80
> > > >  gic_handle_irq+0x18c/0x34c
> > > >  el1_irq+0xcc/0x180
> > > >  lkdtm_HARDLOCKUP+0x8/0x18
> > > >  direct_entry+0x124/0x1c0
> > > >  full_proxy_write+0x60/0xb0
> > > >  vfs_write+0xf0/0x230
> > > >  ksys_write+0x6c/0xf8
> > > >  __arm64_sys_write+0x1c/0x28
> > > >  el0_svc_common.constprop.0+0x74/0x1f0
> > > >  do_el0_svc+0x24/0x90
> > > >  el0_sync_handler+0x180/0x2f8
> > > >  el0_sync+0x158/0x180
> > > > <snip>
> > > >
> > > > Changes in v7:
> > > > - Add a new library function: kgdb_smp_call_nmi_hook() to expose fallback
> > > >   mechanism to arch specific code.
> > > > - Addressed other misc comments from Daniel.
> > > >
> > > > Changes in v6:
> > > > - Two new patches: #4 and #6 which adds runtime fallback framework for
> > > >   sysrq backtrace and kgdb roundup features.
> > > > - Reversed order of NMI backtrace and kgdb roundup feaure patches.
> > > > - Addressed other misc. comments from Marc.
> > > > - I haven't picked any tags from v5 since I think there is major rework
> > > >   involved. Masayoshi, could you please confirm if these features still
> > > >   work for you?
> > > >
> > > > Changes in v5:
> > > > - Rebased to head of upstream master.
> > > > - Remove redundant invocation of ipi_nmi_setup().
> > > > - Addressed misc. comments.
> > > >
> > > > Changes in v4:
> > > > - Move IPI NMI framework to a separate file.
> > > > - Get rid of hard-coded IPI_CALL_NMI_FUNC allocation.
> > > > - Add NMI backtrace support leveraged via magic SYSRQ.
> > > >
> > > > Changes in v3:
> > > > - Rebased to Marc's latest IPIs patch-set [1].
> > > >
> > > > [1] https://lkml.org/lkml/2020/9/1/603
> > > >
> > > > Changes since RFC version [1]:
> > > > - Switch to use generic interrupt framework to turn an IPI as NMI.
> > > > - Dependent on Marc's patch-set [2] which turns IPIs into normal
> > > >   interrupts.
> > > > - Addressed misc. comments from Doug on patch #4.
> > > > - Posted kgdb NMI printk() fixup separately which has evolved since
> > > >   to be solved using different approach via changing kgdb interception
> > > >   of printk() in common printk() code (see patch [3]).
> > > >
> > > > [1] https://lkml.org/lkml/2020/4/24/328
> > > > [2] https://lkml.org/lkml/2020/5/19/710
> > > > [3] https://lkml.org/lkml/2020/5/20/418
> > > >
> > > > Sumit Garg (7):
> > > >   arm64: Add framework to turn IPI as NMI
> > > >   irqchip/gic-v3: Enable support for SGIs to act as NMIs
> > > >   arm64: smp: Assign and setup an IPI as NMI
> > > >   nmi: backtrace: Allow runtime arch specific override
> > > >   arm64: ipi_nmi: Add support for NMI backtrace
> > > >   kgdb: Expose default CPUs roundup fallback mechanism
> > > >   arm64: kgdb: Roundup cpus using IPI as NMI
> > >
> > > Tested-by: Chen-Yu Tsai <wens at csie.org>
> > >
> > > on an ROC-RK3399-PC.
> >
> > Thanks for testing this feature.
> >
> > -Sumit
>
> Hello Sumit,
>
> How is this patch series going?

I am still awaiting feedback from arm64 maintainers.

arm64 maintainers,

Do you believe that features leveraging pseudo NMIs on arm64 can make
it to the mainline? Or the pseudo NMIs feature itself isn't mature
enough that we don't want to have any further users at this point?

-Sumit

>
> - Masa


From xji at analogixsemi.com  Thu Jan 13 03:09:41 2022
From: xji at analogixsemi.com (Xin Ji)
Date: Thu, 13 Jan 2022 19:09:41 +0800
Subject: [v8, PATCH 1/3] drm/dsi: transfer DSI HS packets ending at the
 same time
In-Reply-To: <2f0fd4a9-4d24-a6b7-12ae-51763f304761@intel.com>
References: <20220112153639.12343-1-rex-bc.chen@mediatek.com>
 <20220112153639.12343-2-rex-bc.chen@mediatek.com>
 <2f0fd4a9-4d24-a6b7-12ae-51763f304761@intel.com>
Message-ID: <20220113110941.GA2480843@anxtwsw-Precision-3640-Tower>

Hi Andrzej Hajda,

On Thu, Jan 13, 2022 at 01:14:14AM +0100, Andrzej Hajda wrote:
> Hi,
> 
> On 12.01.2022 16:36, Rex-BC Chen wrote:
> > Since a HS transmission is composed of an arbitrary number
> > of bytes that may not be an integer multiple of lanes, some
> > lanes may run out of data before others.
> > (Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)
> > 
> > However, for some DSI RX devices (for example, anx7625),
> > there is a limitation that packet number should be the same
> > on all DSI lanes. In other words, they need to end a HS at
> > the same time.
> 
> 
> Is it documented in anx7625 manual? Is it confirmed with hw team?
We have application note, and it is confirmed by designer, hw team.
> 
> If not, how it was detected? Have you tried to find workaround for it by
> inspecting registers, maybe it is just matter of clock gating deferral,
> timings or sth similar ???.
> 
> > 
> > Because this limitation is for some specific DSI RX devices,
> > it is more reasonable to put the enable control in these
> > DSI RX drivers. If DSI TX driver knows the information,
> > they can adjust the setting for this situation.
> > 
> > Therefore, add a flag to control this situation beacuse the
> > mipi DSI specification is not forbidden this situation.
> 
> 
> I am not sure what you mean here.
> 
> I have an impression (according t 6.1.3 of spec) that devices should allow
> transmission of arbitrary number of bytes, so this is bug in hw/fw.
This is anx7625 bridge chip design limitation.

> 
> The question if it can be fixed. If not patches are welcome.
> 
> 
> > 
> > Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> > Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> > ---
> >   include/drm/drm_mipi_dsi.h | 2 ++
> >   1 file changed, 2 insertions(+)
> > 
> > diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> > index 147e51b6d241..df4d15345326 100644
> > --- a/include/drm/drm_mipi_dsi.h
> > +++ b/include/drm/drm_mipi_dsi.h
> > @@ -177,6 +177,8 @@ struct mipi_dsi_device_info {
> >    * @lp_rate: maximum lane frequency for low power mode in hertz, this should
> >    * be set to the real limits of the hardware, zero is only accepted for
> >    * legacy drivers
> > + * @hs_packet_end_aligned: transfer DSI HS packets ending at the same time
> > + * for all DSI lanes
> >    */
> >   struct mipi_dsi_device {
> >   	struct mipi_dsi_host *host;
> > @@ -189,6 +191,7 @@ struct mipi_dsi_device {
> >   	unsigned long mode_flags;
> >   	unsigned long hs_rate;
> >   	unsigned long lp_rate;
> > +	bool hs_packet_end_aligned;
> 
> 
> Maybe it would be better to add another mode_flag.
mode_flag should be OK.

Thanks,
Xin
> 
> 
> Regards
> 
> Andrzej
> 
> 
> 
> >   };
> >   #define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"


From yong.wu at mediatek.com  Thu Jan 13 03:10:50 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:50 +0800
Subject: [PATCH v3 0/7] MT8186 SMI SUPPORT
Message-ID: <20220113111057.29918-1-yong.wu@mediatek.com>

This patchset adds mt8186 smi support.
mainly adds a sleep control function.

Change note:
v3: a) Add a new binding patch for renaming "clock" to "clocks".
    b) Reword the title for the binding patches, more detailed.
    c) Add the sleep control error path: if err, return directly.
       also change the log from dev_warn to dev_err.    

v2: https://lore.kernel.org/linux-devicetree/20220111063904.7583-1-yong.wu at mediatek.com/
    a) Add two patches for the "make dtbs_check" warning.
    b) Seperate the "sleep control" into two functions.
       And add a "TODO" comment while sleep control fails.

v1: https://lore.kernel.org/linux-mediatek/20211203064027.14993-1-yong.wu at mediatek.com/
    Base on v5.16-rc1.

Yong Wu (7):
  dt-bindings: memory: mtk-smi: Rename clock to clocks
  dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167
  dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals
    clocks
  dt-bindings: memory: mediatek: Add mt8186 support
  memory: mtk-smi: Fix the return value for clk_bulk_prepare_enable
  memory: mtk-smi: Add sleep ctrl function
  memory: mtk-smi: mt8186: Add smi support

 .../mediatek,smi-common.yaml                  | 32 ++++++------
 .../memory-controllers/mediatek,smi-larb.yaml | 19 +++----
 drivers/memory/mtk-smi.c                      | 51 ++++++++++++++++++-
 3 files changed, 75 insertions(+), 27 deletions(-)

-- 
2.18.0




From arnd at kernel.org  Thu Jan 13 03:14:50 2022
From: arnd at kernel.org (Arnd Bergmann)
Date: Thu, 13 Jan 2022 12:14:50 +0100
Subject: [PATCH v5 08/10] ARM: uaccess: add __{get,put}_kernel_nofault
In-Reply-To: <20220113094754.6ei6ssiqbuw7tfj7@maple.lan>
References: <20210726141141.2839385-1-arnd@kernel.org>
 <20210726141141.2839385-9-arnd@kernel.org>
 <Yd8P37V/N9EkwmYq@wychelm> <Yd8ZEbywqjXkAx9k@shell.armlinux.org.uk>
 <20220113094754.6ei6ssiqbuw7tfj7@maple.lan>
Message-ID: <CAK8P3a0=OkFcKbL+utDPTPf+RskFNdR8Vt-3BEWkO9g_FqSj5w@mail.gmail.com>

On Thu, Jan 13, 2022 at 10:47 AM Daniel Thompson
<daniel.thompson at linaro.org> wrote:
> On Wed, Jan 12, 2022 at 06:08:17PM +0000, Russell King (Oracle) wrote:
>
> > The kernel attempted to access an address that is in the userspace
> > domain (NULL pointer) and took an exception.
> >
> > I suppose we should handle a domain fault more gracefully - what are
> > the required semantics if the kernel attempts a userspace access
> > using one of the _nofault() accessors?
>
> I think the best answer might well be that, if the arch provides
> implementations of hooks such as copy_from_kernel_nofault_allowed()
> then the kernel should never attempt a userspace access using the
> _nofault() accessors. That means they can do whatever they like!
>
> In other words something like the patch below looks like a promising
> approach.

Right, it seems this is the same as on x86.

> From f66a63b504ff582f261a506c54ceab8c0e77a98c Mon Sep 17 00:00:00 2001
> From: Daniel Thompson <daniel.thompson at linaro.org>
> Date: Thu, 13 Jan 2022 09:34:45 +0000
> Subject: [PATCH] arm: mm: Implement copy_from_kernel_nofault_allowed()
>
> Currently copy_from_kernel_nofault() can actually fault (due to software
> PAN) if we attempt userspace access. In any case, the documented
> behaviour for this function is to return -ERANGE if we attempt an access
> outside of kernel space.
>
> Implementing copy_from_kernel_nofault_allowed() solves both these
> problems.
>
> Signed-off-by: Daniel Thompson <daniel.thompson at linaro.org>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From yong.wu at mediatek.com  Thu Jan 13 03:10:56 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:56 +0800
Subject: [PATCH v3 6/7] memory: mtk-smi: Add sleep ctrl function
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-7-yong.wu@mediatek.com>

Sleep control means that when the larb goes to sleep, we should wait a bit
until all the current commands are finished. Thus, when the larb runtime
suspends, we need to enable this function to wait until all the existed
commands are finished. When the larb resumes, just disable this function.
This function only improves the safety of bus. Add a new flag for this
function. Prepare for mt8186.

Signed-off-by: Anan Sun <anan.sun at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/memory/mtk-smi.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index e7b1a22b12ea..12d15fcc65e2 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -8,6 +8,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -32,6 +33,10 @@
 #define SMI_DUMMY			0x444
 
 /* SMI LARB */
+#define SMI_LARB_SLP_CON                0xc
+#define SLP_PROT_EN                     BIT(0)
+#define SLP_PROT_RDY                    BIT(16)
+
 #define SMI_LARB_CMD_THRT_CON		0x24
 #define SMI_LARB_THRT_RD_NU_LMT_MSK	GENMASK(7, 4)
 #define SMI_LARB_THRT_RD_NU_LMT		(5 << 4)
@@ -81,6 +86,7 @@
 
 #define MTK_SMI_FLAG_THRT_UPDATE	BIT(0)
 #define MTK_SMI_FLAG_SW_FLAG		BIT(1)
+#define MTK_SMI_FLAG_SLEEP_CTL		BIT(2)
 #define MTK_SMI_CAPS(flags, _x)		(!!((flags) & (_x)))
 
 struct mtk_smi_reg_pair {
@@ -371,6 +377,26 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{}
 };
 
+static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
+{
+	int ret;
+	u32 tmp;
+
+	writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON);
+	ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON,
+					tmp, !!(tmp & SLP_PROT_RDY), 10, 1000);
+	if (ret) {
+		/* TODO: Reset this larb if it fails here. */
+		dev_err(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp);
+	}
+	return ret;
+}
+
+static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb)
+{
+	writel_relaxed(0, larb->base + SMI_LARB_SLP_CON);
+}
+
 static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
 {
 	struct platform_device *smi_com_pdev;
@@ -483,6 +509,9 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
+		mtk_smi_larb_sleep_ctrl_disable(larb);
+
 	/* Configure the basic setting for this larb */
 	larb_gen->config_port(dev);
 
@@ -492,6 +521,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
 {
 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+	int ret;
+
+	if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL)) {
+		ret = mtk_smi_larb_sleep_ctrl_enable(larb);
+		if (ret)
+			return ret;
+	}
 
 	clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
 	return 0;
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:51 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:51 +0800
Subject: [PATCH v3 1/7] dt-bindings: memory: mtk-smi: Rename clock to clocks
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-2-yong.wu@mediatek.com>

The property "clock" should be rename to "clocks", and delete the "items",
the minItems/maxItems should not be put under "items".

Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../mediatek,smi-common.yaml                  | 28 ++++++++-----------
 .../memory-controllers/mediatek,smi-larb.yaml | 14 ++++------
 2 files changed, 18 insertions(+), 24 deletions(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 3a82b0b27fa0..4fca71f34310 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -88,10 +88,9 @@ allOf:
               - mediatek,mt2701-smi-common
     then:
       properties:
-        clock:
-          items:
-            minItems: 3
-            maxItems: 3
+        clocks:
+          minItems: 3
+          maxItems: 3
         clock-names:
           items:
             - const: apb
@@ -108,10 +107,9 @@ allOf:
       required:
         - mediatek,smi
       properties:
-        clock:
-          items:
-            minItems: 3
-            maxItems: 3
+        clocks:
+          minItems: 3
+          maxItems: 3
         clock-names:
           items:
             - const: apb
@@ -133,10 +131,9 @@ allOf:
 
     then:
       properties:
-        clock:
-          items:
-            minItems: 4
-            maxItems: 4
+        clocks:
+          minItems: 4
+          maxItems: 4
         clock-names:
           items:
             - const: apb
@@ -146,10 +143,9 @@ allOf:
 
     else:  # for gen2 HW that don't have gals
       properties:
-        clock:
-          items:
-            minItems: 2
-            maxItems: 2
+        clocks:
+          minItems: 2
+          maxItems: 2
         clock-names:
           items:
             - const: apb
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index eaeff1ada7f8..bd7aa8257949 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -79,10 +79,9 @@ allOf:
 
     then:
       properties:
-        clock:
-          items:
-            minItems: 3
-            maxItems: 3
+        clocks:
+          minItems: 3
+          maxItems: 3
         clock-names:
           items:
             - const: apb
@@ -91,10 +90,9 @@ allOf:
 
     else:
       properties:
-        clock:
-          items:
-            minItems: 2
-            maxItems: 2
+        clocks:
+          minItems: 2
+          maxItems: 2
         clock-names:
           items:
             - const: apb
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:54 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:54 +0800
Subject: [PATCH v3 4/7] dt-bindings: memory: mediatek: Add mt8186 support
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-5-yong.wu@mediatek.com>

Add mt8186 smi support in the bindings.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 .../bindings/memory-controllers/mediatek,smi-common.yaml      | 4 +++-
 .../bindings/memory-controllers/mediatek,smi-larb.yaml        | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
index 4fca71f34310..a98b359bf909 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ description: |
   MediaTek SMI have two generations of HW architecture, here is the list
   which generation the SoCs use:
   generation 1: mt2701 and mt7623.
-  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8192 and mt8195.
+  generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8192 and mt8195.
 
   There's slight differences between the two SMI, for generation 2, the
   register which control the iommu port is at each larb's register base. But
@@ -35,6 +35,7 @@ properties:
           - mediatek,mt8167-smi-common
           - mediatek,mt8173-smi-common
           - mediatek,mt8183-smi-common
+          - mediatek,mt8186-smi-common
           - mediatek,mt8192-smi-common
           - mediatek,mt8195-smi-common-vdo
           - mediatek,mt8195-smi-common-vpp
@@ -125,6 +126,7 @@ allOf:
           enum:
             - mediatek,mt6779-smi-common
             - mediatek,mt8183-smi-common
+            - mediatek,mt8186-smi-common
             - mediatek,mt8192-smi-common
             - mediatek,mt8195-smi-common-vdo
             - mediatek,mt8195-smi-common-vpp
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index c5c32c910045..4db8690829cd 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -23,6 +23,7 @@ properties:
           - mediatek,mt8167-smi-larb
           - mediatek,mt8173-smi-larb
           - mediatek,mt8183-smi-larb
+          - mediatek,mt8186-smi-larb
           - mediatek,mt8192-smi-larb
           - mediatek,mt8195-smi-larb
 
@@ -75,6 +76,7 @@ allOf:
         compatible:
           enum:
             - mediatek,mt8183-smi-larb
+            - mediatek,mt8186-smi-larb
             - mediatek,mt8195-smi-larb
 
     then:
@@ -107,6 +109,7 @@ allOf:
               - mediatek,mt2701-smi-larb
               - mediatek,mt2712-smi-larb
               - mediatek,mt6779-smi-larb
+              - mediatek,mt8186-smi-larb
               - mediatek,mt8192-smi-larb
               - mediatek,mt8195-smi-larb
 
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:55 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:55 +0800
Subject: [PATCH v3 5/7] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-6-yong.wu@mediatek.com>

Function clk_bulk_prepare_enable() returns 0 for success or a negative
number for error. Fix this code style issue.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/memory/mtk-smi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b883dcc0bbfa..e7b1a22b12ea 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -480,7 +480,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
 	int ret;
 
 	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
-	if (ret < 0)
+	if (ret)
 		return ret;
 
 	/* Configure the basic setting for this larb */
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:53 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:53 +0800
Subject: [PATCH v3 3/7] dt-bindings: memory: mtk-smi: Correct minItems to 2
 for the gals clocks
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-4-yong.wu@mediatek.com>

Mute the warning from "make dtbs_check":

larb at 14017000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
	...

larb at 16010000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml

larb at 17010000: clock-names: ['apb', 'smi'] is too short
	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml

If a platform's larb supports gals, there will be some larbs have one
more "gals" clock while the others still only need "apb"/"smi" clocks,
then the minItems for clocks and clock-names are 2.

Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../bindings/memory-controllers/mediatek,smi-larb.yaml         | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index 6d61c51893d2..c5c32c910045 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -80,9 +80,10 @@ allOf:
     then:
       properties:
         clocks:
-          minItems: 3
+          minItems: 2
           maxItems: 3
         clock-names:
+          minItems: 2
           items:
             - const: apb
             - const: smi
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:57 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:57 +0800
Subject: [PATCH v3 7/7] memory: mtk-smi: mt8186: Add smi support
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-8-yong.wu@mediatek.com>

Add mt8186 SMI support.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/memory/mtk-smi.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index 12d15fcc65e2..378affd43fc4 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -355,6 +355,11 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
 				      /* IPU0 | IPU1 | CCU */
 };
 
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
+	.config_port                = mtk_smi_larb_config_port_gen2_general,
+	.flags_general	            = MTK_SMI_FLAG_SLEEP_CTL,
+};
+
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
 	.config_port                = mtk_smi_larb_config_port_gen2_general,
 };
@@ -372,6 +377,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
 	{.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
 	{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
 	{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
+	{.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
 	{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
 	{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
 	{}
@@ -580,6 +586,12 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
 		    F_MMU1_LARB(7),
 };
 
+static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = {
+	.type     = MTK_SMI_GEN2,
+	.has_gals = true,
+	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7),
+};
+
 static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
 	.type     = MTK_SMI_GEN2,
 	.has_gals = true,
@@ -614,6 +626,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
 	{.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
 	{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
 	{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
+	{.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
 	{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
 	{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
 	{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
-- 
2.18.0



From yong.wu at mediatek.com  Thu Jan 13 03:10:52 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Thu, 13 Jan 2022 19:10:52 +0800
Subject: [PATCH v3 2/7] dt-bindings: memory: mtk-smi: No need mediatek,
 larb-id for mt8167
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <20220113111057.29918-3-yong.wu@mediatek.com>

Mute the warning from "make dtbs_check":

larb at 14016000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
larb at 15001000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
larb at 16010000: 'mediatek,larb-id' is a required property
	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml

As the description of mediatek,larb-id, the property is only
required when the larbid is not consecutive from its IOMMU point of view.

Also, from the description of mediatek,larbs in
Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml, all the larbs
must sort by the larb index.

In mt8167, there is only one IOMMU HW and three larbs. The drivers already
know its larb index from the mediatek,larbs property of IOMMU, thus no
need this property.

Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../bindings/memory-controllers/mediatek,smi-larb.yaml           | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
index bd7aa8257949..6d61c51893d2 100644
--- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -106,7 +106,6 @@ allOf:
               - mediatek,mt2701-smi-larb
               - mediatek,mt2712-smi-larb
               - mediatek,mt6779-smi-larb
-              - mediatek,mt8167-smi-larb
               - mediatek,mt8192-smi-larb
               - mediatek,mt8195-smi-larb
 
-- 
2.18.0



From arnd at arndb.de  Thu Jan 13 03:47:34 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 13 Jan 2022 12:47:34 +0100
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <00e28671-8d3a-f789-91c4-109814792a07@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
 <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
 <00e28671-8d3a-f789-91c4-109814792a07@arm.com>
Message-ID: <CAK8P3a2Q+iN1O6FEdUJRt=0bQu=6fkWAD3RCECfdhu4DKHq0pg@mail.gmail.com>

On Thu, Jan 13, 2022 at 4:03 AM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
> On 1/12/22 4:20 PM, Arnd Bergmann wrote:
> > On Wed, Jan 12, 2022 at 10:34 AM Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> >> Add the CPU Partnumbers for the new Arm designs.
> >> @@ -74,6 +74,7 @@
> >>  #define ARM_CPU_PART_NEOVERSE_N1       0xD0C
> >>  #define ARM_CPU_PART_CORTEX_A77                0xD0D
> >>  #define ARM_CPU_PART_CORTEX_A710       0xD47
> >> +#define ARM_CPU_PART_CORTEX_X2         0xD48
> >>  #define ARM_CPU_PART_NEOVERSE_N2       0xD49
> >
> > No objections to the patch, but would it be possible to just add all the missing
> > ones here to the degree that they are known already? I don't see any entries for
> > Cortex-A34, Cortex-A65AE, Cortex-A78, Cortex-A78C, Cortex-A78AE,
> > Neoverse-E1, Neoverse-V1, Cortex-X1, Cortex-X2, Cortex-A510, Cortex-A710
> > and Cortex-R82 among the Arm-designed cores that can run Linux, and there
> > are probably others that I missed going through the list.
>
> Hi Arnd,
>
> IIUC the part numbers are enumerated here only if there is an errata
> applicable for them which needs to be detected at boot. I am not sure
> whether all cpu versions that can run Linux, needs to be defined here.
> But then I might be missing something.

They clearly don't need to be defined here, and for other constants such
as the system registers we may not want to list them all, but I think for
the CPU IDs it makes sense to just list them all here rather than adding
them one at a time, as we tend to need them sooner or later anyway.

It also helps me personally to have a known place to look up the names
by value rather than chasing through reference manuals.

      Arnd


From radheys at xilinx.com  Thu Jan 13 03:53:06 2022
From: radheys at xilinx.com (Radhey Shyam Pandey)
Date: Thu, 13 Jan 2022 11:53:06 +0000
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
 reset
In-Reply-To: <20220112173700.873002-3-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-3-robert.hancock@calian.com>
Message-ID: <SA1PR02MB8560F3EF51828D9065763968C7539@SA1PR02MB8560.namprd02.prod.outlook.com>

> -----Original Message-----
> From: Robert Hancock <robert.hancock at calian.com>
> Sent: Wednesday, January 12, 2022 11:07 PM
> To: netdev at vger.kernel.org
> Cc: Radhey Shyam Pandey <radheys at xilinx.com>; davem at davemloft.net;
> kuba at kernel.org; linux-arm-kernel at lists.infradead.org; Michal Simek
> <michals at xilinx.com>; ariane.keller at tik.ee.ethz.ch; daniel at iogearbox.net;
> Robert Hancock <robert.hancock at calian.com>
> Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core reset
> 
> When resetting the device, wait for the PhyRstCmplt bit to be set
> in the interrupt status register before continuing initialization, to
> ensure that the core is actually ready. The MgtRdy bit could also be
> waited for, but unfortunately when using 7-series devices, the bit does

Just to understand - can you share 7- series design details.
Based on documentation - This MgtRdy bit indicates if the TEMAC core is
out of reset and ready for use. In systems that use an serial transceiver, 
this bit goes to 1 when the serial transceiver is ready to use.

Also if we don't wait for phy reset - what is the issue we are seeing?

> not appear to work as documented (it seems to behave as some sort of
> link state indication and not just an indication the transceiver is
> ready) so it can't really be relied on.
> 
> Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet
> driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index f950342f6467..f425a8404a9b 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local
> *lp)
>  		return ret;
>  	}
> 
> +	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has
> finished */
> +	ret = read_poll_timeout(axienet_ior, value,
> +				value & XAE_INT_PHYRSTCMPLT_MASK,
> +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> +				XAE_IS_OFFSET);
> +	if (ret) {
> +		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n",
> __func__);
> +		return ret;
> +	}
> +
>  	return 0;
>  }
> 
> --
> 2.31.1



From ardb at kernel.org  Thu Jan 13 03:56:39 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 13 Jan 2022 12:56:39 +0100
Subject: [PATCH 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220113064118.1580916-5-kevin@bracey.fi>
References: <20220113064118.1580916-1-kevin@bracey.fi>
 <20220113064118.1580916-5-kevin@bracey.fi>
Message-ID: <CAMj1kXG2ZWQQYa6r74ahq+5H3+9uoZgaCwZCKg7qKijXVd1xuA@mail.gmail.com>

On Thu, 13 Jan 2022 at 07:41, Kevin Bracey <kevin at bracey.fi> wrote:
>
> It makes no sense to leave crc32_be using the generic code while we
> only accelerate the little-endian ops.
>
> Even though the big-endian form doesn't fit as smoothly into the arm64,
> we can speed it up and avoid hitting the D cache.
>
> Tested on Cortex-A53. Without acceleration:
>
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 192240 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21360 nsec
>
> With acceleration:
>
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 53480 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21480 nsec
>
> Signed-off-by: Kevin Bracey <kevin at bracey.fi>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Ard Biesheuvel <ardb at kernel.org>

I've given this a spin on LE and BE builds:

Tested-by: Ard Biesheuvel <ardb at kernel.org>

Some nits below

> ---
>  arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 73 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
> index 0f9e10ecda23..906210441d76 100644
> --- a/arch/arm64/lib/crc32.S
> +++ b/arch/arm64/lib/crc32.S
> @@ -11,7 +11,44 @@
>
>         .arch           armv8-a+crc
>
> -       .macro          __crc32, c
> +       .macro          byteorder, reg, be
> +       .if \be

Please indent the \be so it aligns with the rest of the right hand column.
(below as well)

> +CPU_LE( rev            \reg, \reg      )
> +       .else
> +CPU_BE( rev            \reg, \reg      )
> +       .endif
> +       .endm
> +
> +       .macro          byteorder16, reg, be
> +       .if \be
> +CPU_LE( rev16          \reg, \reg      )
> +       .else
> +CPU_BE( rev16          \reg, \reg      )
> +       .endif
> +       .endm
> +
> +       .macro          bitorder, reg, be
> +       .if \be
> +       rbit            \reg, \reg
> +       .endif
> +       .endm
> +
> +       .macro          bitorder16, reg, be
> +       .if \be
> +       rbit            \reg, \reg
> +       lsr             \reg, \reg, #16
> +       .endif
> +       .endm
> +
> +       .macro          bitorder8, reg, be
> +       .if \be
> +       rbit            \reg, \reg
> +       lsr             \reg, \reg, #24
> +       .endif
> +       .endm
> +
> +       .macro          __crc32, c, be=0
> +       bitorder        w0, \be
>         cmp             x2, #16
>         b.lt            8f                      // less than 16 bytes
>
> @@ -24,10 +61,14 @@
>         add             x8, x8, x1
>         add             x1, x1, x7
>         ldp             x5, x6, [x8]
> -CPU_BE(        rev             x3, x3          )
> -CPU_BE(        rev             x4, x4          )
> -CPU_BE(        rev             x5, x5          )
> -CPU_BE(        rev             x6, x6          )
> +       byteorder       x3, \be
> +       byteorder       x4, \be
> +       byteorder       x5, \be
> +       byteorder       x6, \be
> +       bitorder        x3, \be
> +       bitorder        x4, \be
> +       bitorder        x5, \be
> +       bitorder        x6, \be
>
>         tst             x7, #8
>         crc32\c\()x     w8, w0, x3
> @@ -55,33 +96,43 @@ CPU_BE(     rev             x6, x6          )
>  32:    ldp             x3, x4, [x1], #32
>         sub             x2, x2, #32
>         ldp             x5, x6, [x1, #-16]
> -CPU_BE(        rev             x3, x3          )
> -CPU_BE(        rev             x4, x4          )
> -CPU_BE(        rev             x5, x5          )
> -CPU_BE(        rev             x6, x6          )
> +       byteorder       x3, \be
> +       byteorder       x4, \be
> +       byteorder       x5, \be
> +       byteorder       x6, \be
> +       bitorder        x3, \be
> +       bitorder        x4, \be
> +       bitorder        x5, \be
> +       bitorder        x6, \be
>         crc32\c\()x     w0, w0, x3
>         crc32\c\()x     w0, w0, x4
>         crc32\c\()x     w0, w0, x5
>         crc32\c\()x     w0, w0, x6
>         cbnz            x2, 32b
> -0:     ret
> +0:     bitorder        w0, \be
> +       ret
>
>  8:     tbz             x2, #3, 4f
>         ldr             x3, [x1], #8
> -CPU_BE(        rev             x3, x3          )
> +       byteorder       x3, \be
> +       bitorder        x3, \be
>         crc32\c\()x     w0, w0, x3
>  4:     tbz             x2, #2, 2f
>         ldr             w3, [x1], #4
> -CPU_BE(        rev             w3, w3          )
> +       byteorder       w3, \be
> +       bitorder        w3, \be
>         crc32\c\()w     w0, w0, w3
>  2:     tbz             x2, #1, 1f
>         ldrh            w3, [x1], #2
> -CPU_BE(        rev16           w3, w3          )
> +       byteorder16     w3, \be
> +       bitorder16      w3, \be
>         crc32\c\()h     w0, w0, w3
>  1:     tbz             x2, #0, 0f
>         ldrb            w3, [x1]
> +       bitorder8       w3, \be
>         crc32\c\()b     w0, w0, w3
> -0:     ret
> +0:     bitorder        w0, \be
> +       ret
>         .endm
>
>         .align          5
> @@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
>  alternative_else_nop_endif
>         __crc32         c
>  SYM_FUNC_END(__crc32c_le)
> +
> +       .align          5
> +SYM_FUNC_START(crc32_be)
> +alternative_if_not ARM64_HAS_CRC32
> +       b               crc32_be_base
> +alternative_else_nop_endif
> +       __crc32         , 1

Please rewrite this as

__crc32     be=1

instead of using positional arguments.


> +SYM_FUNC_END(crc32_be)
> --
> 2.25.1
>

WIth those fixed.

Reviewed-by: Ard Biesheuvel <ardb at kernel.org>


From mhocko at suse.com  Thu Jan 13 03:57:35 2022
From: mhocko at suse.com (Michal Hocko)
Date: Thu, 13 Jan 2022 12:57:35 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd9nk0qlK3jK9baN@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz> <Yd4oaUwHkpadAKwe@google.com>
 <Yd6q0QdLVTS53vu4@dhcp22.suse.cz> <Yd9nk0qlK3jK9baN@google.com>
Message-ID: <YeATr//U6XD87fWF@dhcp22.suse.cz>

On Wed 12-01-22 16:43:15, Yu Zhao wrote:
> On Wed, Jan 12, 2022 at 11:17:53AM +0100, Michal Hocko wrote:
[...]
> > Is there any reason you are not using folio_memcg_lock in the
> > pte walk instead?
> 
> We have a particular lruvec (the first arg), hence a particular memcg
> to lock. But we don't have a particular page to lock.

That is certainly true at this layer but the locking should be needed
only for specific pages, no? So you can move the lock down to the
callback which examines respective pages. Or is there anything
preventing that?

To be honest, and that is the reason I am asking, I really do not like
to open code the migration synchronization outside of the memcg proper.
Code paths which need a stable memcg are supposed to be using
folio_memcg_lock for the specific examination time. If you prefer a
trylock approach for this usecase then we can add one.

-- 
Michal Hocko
SUSE Labs


From liang.yang at amlogic.com  Thu Jan 13 03:57:41 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:41 +0800
Subject: [PATCH v9 0/4] clk: meson: add a sub EMMC clock controller support
Message-ID: <20220113115745.45826-1-liang.yang@amlogic.com>

Changes since v8 [9]
 - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
 - use struct_size to caculate onecell_data
 - add clk-phase-delay.h
 - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG

Changes since v7 [8]
 - move meson_clk_get_phase_delay_data() from header to driver
 - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
 - remove onecell date and ID for internal MUX clk
 - use helper for functions for ONE_BASED in sclk-div
 - add ONE_BASED support for duty cycle

Changes since v6 [7]:
 - add one based support for sclk divier
 - alloc sclk in probe for multiple instance
 - fix coding styles

Changes since v5 [6]:
 - remove divider ops with .init and use sclk_div instead
 - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
 - drop the useless type cast 

Changes since v4 [5]:
 - use struct parm in phase delay driver
 - remove 0 delay releted part in phase delay driver
 - don't rebuild the parent name once again
 - add divider ops with .init

Changes since v3 [4]:
 - separate clk-phase-delay driver
 - replace clk_get_rate() with clk_hw_get_rate()
 - collect Rob's R-Y
 - drop 'meson-' prefix from compatible string

 Changes since v2 [3]:
 - squash dt-binding clock-id patch
 - update license
 - fix alignment
 - construct a clk register helper() function

Changes since v1 [2]:
 - implement phase clock
 - update compatible name
 - adjust file name
 - divider probe() into small functions, and re-use them

[1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
[2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
[3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
[4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
[5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
[6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
[7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
[8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
[9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
Liang Yang (4):
  clk: meson: add one based divider support for sclk
  clk: meson: add emmc sub clock phase delay driver
  clk: meson: add DT documentation for emmc clock controller
  clk: meson: add sub MMC clock controller driver

 .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
 drivers/clk/meson/Kconfig                     |  18 ++
 drivers/clk/meson/Makefile                    |   2 +
 drivers/clk/meson/clk-phase-delay.c           |  69 ++++
 drivers/clk/meson/clk-phase-delay.h           |  20 ++
 drivers/clk/meson/mmc-clkc.c                  | 300 ++++++++++++++++++
 drivers/clk/meson/sclk-div.c                  |  61 ++--
 drivers/clk/meson/sclk-div.h                  |   3 +
 include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
 9 files changed, 529 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h
 create mode 100644 drivers/clk/meson/mmc-clkc.c
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:42 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:42 +0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-2-liang.yang@amlogic.com>

When MESON_SCLK_ONE_BASED flag is set, the sclk divider will be:
one based divider (div = val), and zero value gates the clock

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/sclk-div.c | 61 +++++++++++++++++++++++-------------
 drivers/clk/meson/sclk-div.h |  3 ++
 2 files changed, 42 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index 76d31c0a3342..79c9efd28115 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -4,16 +4,17 @@
  * Author: Jerome Brunet <jbrunet at baylibre.com>
  *
  * Sample clock generator divider:
- * This HW divider gates with value 0 but is otherwise a zero based divider:
+ * This HW divider gates with value 0:
  *
  * val >= 1
- * divider = val + 1
+ * divider = val + 1 if ONE_BASED is not set, otherwise divider = val.
  *
  * The duty cycle may also be set for the LR clock variant. The duty cycle
  * ratio is:
  *
  * hi = [0 - val]
- * duty_cycle = (1 + hi) / (1 + val)
+ * duty_cycle = (1 + hi) / (1 + val) if ONE_BASED is not set, otherwise:
+ * duty_cycle = hi / (1 + val)
  */
 
 #include <linux/clk-provider.h>
@@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
 	return (struct meson_sclk_div_data *)clk->data;
 }
 
-static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
+static inline int sclk_get_reg(int val, unsigned char flag)
 {
-	return (1 << sclk->div.width) - 1;
+	if ((flag & MESON_SCLK_ONE_BASED) || !val)
+		return val;
+	else
+		return val - 1;
+}
+
+static inline int sclk_get_divider(int reg, unsigned char flag)
+{
+	if (flag & MESON_SCLK_ONE_BASED)
+		return reg;
+	else
+		return reg + 1;
 }
 
 static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
 {
-	return sclk_div_maxval(sclk) + 1;
+	unsigned int reg = (1 << sclk->div.width) - 1;
+
+	return sclk_get_divider(reg, sclk->flags);
 }
 
 static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate,
-			   unsigned long prate, int maxdiv)
+			   unsigned long prate)
 {
 	int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
+	int mindiv = sclk_get_divider(1, sclk->flags);
+	int maxdiv = sclk_div_maxdiv(sclk);
 
-	return clamp(div, 2, maxdiv);
+	return clamp(div, mindiv, maxdiv);
 }
 
 static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
@@ -51,25 +69,25 @@ static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
 			    struct meson_sclk_div_data *sclk)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
-	int bestdiv = 0, i;
+	int bestdiv = 0, i, mindiv;
 	unsigned long maxdiv, now, parent_now;
 	unsigned long best = 0, best_parent = 0;
 
 	if (!rate)
 		rate = 1;
 
-	maxdiv = sclk_div_maxdiv(sclk);
-
 	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-		return sclk_div_getdiv(hw, rate, *prate, maxdiv);
+		return sclk_div_getdiv(hw, rate, *prate);
 
 	/*
 	 * The maximum divider we can use without overflowing
 	 * unsigned long in rate * i below
 	 */
+	maxdiv = sclk_div_maxdiv(sclk);
 	maxdiv = min(ULONG_MAX / rate, maxdiv);
+	mindiv = sclk_get_divider(1, sclk->flags);
 
-	for (i = 2; i <= maxdiv; i++) {
+	for (i = mindiv; i <= maxdiv; i++) {
 		/*
 		 * It's the most ideal case if the requested rate can be
 		 * divided from parent clock without needing to change
@@ -115,10 +133,7 @@ static void sclk_apply_ratio(struct clk_regmap *clk,
 					    sclk->cached_duty.num,
 					    sclk->cached_duty.den);
 
-	if (hi)
-		hi -= 1;
-
-	meson_parm_write(clk->map, &sclk->hi, hi);
+	meson_parm_write(clk->map, &sclk->hi, sclk_get_reg(hi, sclk->flags));
 }
 
 static int sclk_div_set_duty_cycle(struct clk_hw *hw,
@@ -149,7 +164,7 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 	}
 
 	hi = meson_parm_read(clk->map, &sclk->hi);
-	duty->num = hi + 1;
+	duty->num = sclk_get_divider(hi, sclk->flags);
 	duty->den = sclk->cached_div;
 	return 0;
 }
@@ -157,10 +172,13 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 static void sclk_apply_divider(struct clk_regmap *clk,
 			       struct meson_sclk_div_data *sclk)
 {
+	unsigned int div;
+
 	if (MESON_PARM_APPLICABLE(&sclk->hi))
 		sclk_apply_ratio(clk, sclk);
 
-	meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1);
+	div = sclk_get_reg(sclk->cached_div, sclk->flags);
+	meson_parm_write(clk->map, &sclk->div, div);
 }
 
 static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -168,9 +186,8 @@ static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
-	unsigned long maxdiv = sclk_div_maxdiv(sclk);
 
-	sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv);
+	sclk->cached_div = sclk_div_getdiv(hw, rate, prate);
 
 	if (clk_hw_is_enabled(hw))
 		sclk_apply_divider(clk, sclk);
@@ -228,7 +245,7 @@ static int sclk_div_init(struct clk_hw *hw)
 	if (!val)
 		sclk->cached_div = sclk_div_maxdiv(sclk);
 	else
-		sclk->cached_div = val + 1;
+		sclk->cached_div = sclk_get_divider(val, sclk->flags);
 
 	sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
 
diff --git a/drivers/clk/meson/sclk-div.h b/drivers/clk/meson/sclk-div.h
index b64b2a32005f..944dab5ec0cf 100644
--- a/drivers/clk/meson/sclk-div.h
+++ b/drivers/clk/meson/sclk-div.h
@@ -10,11 +10,14 @@
 #include <linux/clk-provider.h>
 #include "parm.h"
 
+#define MESON_SCLK_ONE_BASED	BIT(0)
+
 struct meson_sclk_div_data {
 	struct parm div;
 	struct parm hi;
 	unsigned int cached_div;
 	struct clk_duty cached_duty;
+	u8 flags;
 };
 
 extern const struct clk_ops meson_sclk_div_ops;
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:43 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:43 +0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-3-liang.yang@amlogic.com>

Export the emmc sub clock phase delay ops which will be used
by the emmc sub clock driver itself.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig           |  4 ++
 drivers/clk/meson/Makefile          |  1 +
 drivers/clk/meson/clk-phase-delay.c | 69 +++++++++++++++++++++++++++++
 drivers/clk/meson/clk-phase-delay.h | 20 +++++++++
 4 files changed, 94 insertions(+)
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 3014e2f1fbb4..bb0f59eea366 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -18,6 +18,10 @@ config COMMON_CLK_MESON_PHASE
 	tristate
 	select COMMON_CLK_MESON_REGMAP
 
+config COMMON_CLK_MESON_PHASE_DELAY
+	tristate
+	select COMMON_CLK_MESON_REGMAP
+
 config COMMON_CLK_MESON_PLL
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index b3ef5f67820f..c450f38d3801 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
 obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
 obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
 obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
+obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 
 # Amlogic Clock controllers
 
diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
new file mode 100644
index 000000000000..3c1ae0ee2a24
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-phase-delay.h"
+
+static inline struct meson_clk_phase_delay_data *
+meson_clk_get_phase_delay_data(struct clk_regmap *clk)
+{
+	return clk->data;
+}
+
+static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, p, d;
+	int degrees;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	p = meson_parm_read(clk->map, &ph->phase);
+	degrees = p * 360 / (1 << (ph->phase.width));
+
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	d = meson_parm_read(clk->map, &ph->delay);
+	degrees += d * ph->delay_step_ps * 360 / period_ps;
+	degrees %= 360;
+
+	return degrees;
+}
+
+static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, d = 0;
+	unsigned int p;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	/*
+	 * First compute the phase index (p), the remainder (r) is the
+	 * part we'll try to acheive using the delays (d).
+	 */
+	p = 360 / 1 << (ph->phase.width);
+	degrees = degrees / p;
+	d = DIV_ROUND_CLOSEST((degrees % p) * period_ps,
+			      360 * ph->delay_step_ps);
+	d = min(d, PMASK(ph->delay.width));
+
+	meson_parm_write(clk->map, &ph->phase, degrees);
+	meson_parm_write(clk->map, &ph->delay, d);
+	return 0;
+}
+
+const struct clk_ops meson_clk_phase_delay_ops = {
+	.get_phase = meson_clk_phase_delay_get_phase,
+	.set_phase = meson_clk_phase_delay_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
diff --git a/drivers/clk/meson/clk-phase-delay.h b/drivers/clk/meson/clk-phase-delay.h
new file mode 100644
index 000000000000..b4f211d02c84
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_CLK_PHASE_DELAY_H
+#define __MESON_CLK_PHASE_DELAY_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_phase_delay_data {
+	struct parm     phase;
+	struct parm     delay;
+	unsigned int    delay_step_ps;
+};
+
+extern const struct clk_ops meson_clk_phase_delay_ops;
+
+#endif /* __MESON_CLK_PHASE_DELAY_H */
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:44 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:44 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-4-liang.yang@amlogic.com>

Document the MMC sub clock controller driver, the potential consumer
of this driver is MMC or NAND. Also add four clock bindings IDs which
provided by this driver.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
 include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
 2 files changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
new file mode 100644
index 000000000000..a274c3d5fc2e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
+
+maintainers:
+  - jianxin.pan at amlogic.com
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,axg-mmc-clkc", "syscon"
+      - "amlogic,gx-mmc-clkc", "syscon"
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "clkin0", "clkin1"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    sd_mmc_c_clkc: clock-controller at 7000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x7000 0x0 0x4>;
+	#clock-cells = <1>;
+
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_MMC_C_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+     };
+
+  - |
+    sd_emmc_b_clkc: clock-controller at 5000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x5000 0x0 0x4>;
+
+	#clock-cells = <1>;
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_B_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+    };
+
+...
\ No newline at end of file
diff --git a/include/dt-bindings/clock/amlogic,mmc-clkc.h b/include/dt-bindings/clock/amlogic,mmc-clkc.h
new file mode 100644
index 000000000000..71301517b183
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,mmc-clkc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MMC_CLKC_H
+#define __MMC_CLKC_H
+
+#define CLKID_MMC_DIV		0
+#define CLKID_MMC_PHASE_CORE	1
+#define CLKID_MMC_PHASE_TX	2
+#define CLKID_MMC_PHASE_RX	3
+
+#endif
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 13 03:57:45 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Thu, 13 Jan 2022 19:57:45 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113115745.45826-1-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
Message-ID: <20220113115745.45826-5-liang.yang@amlogic.com>

The patch will add a MMC clock controller driver which used by MMC or NAND,
It provide a mux and divider clock, and three phase clocks - core, tx, tx.

Two clocks are provided as the parent of MMC clock controller from
upper layer clock controller - eg "amlogic,axg-clkc" in AXG platform.

To specify which clock the MMC or NAND driver may consume,
the preprocessor macros in the dt-bindings/clock/amlogic,mmc-clkc.h header
can be used in the device tree sources.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig    |  14 ++
 drivers/clk/meson/Makefile   |   1 +
 drivers/clk/meson/mmc-clkc.c | 300 +++++++++++++++++++++++++++++++++++
 3 files changed, 315 insertions(+)
 create mode 100644 drivers/clk/meson/mmc-clkc.c

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index bb0f59eea366..3de6f3b24461 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
 	select COMMON_CLK_MESON_REGMAP
 	select RESET_CONTROLLER
 
+config COMMON_CLK_MMC_MESON
+	tristate "Meson MMC Sub Clock Controller Driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	select MFD_SYSCON
+	select COMMON_CLK_AMLOGIC
+	select COMMON_CLK_MESON_PHASE
+	select COMMON_CLK_MESON_PHASE_DELAY
+	select COMMON_CLK_MESON_SCLK_DIV
+	help
+	  Support for the MMC sub clock controller on
+	  Amlogic Meson Platform, which includes S905 (GXBB, GXL),
+	  A113D/X (AXG) devices . Say Y if you want this
+	  clock enabled.
+
 config COMMON_CLK_MESON_EE_CLKC
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index c450f38d3801..f7a94a33e789 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_MMC_MESON) += mmc-clkc.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
new file mode 100644
index 000000000000..f53977f61390
--- /dev/null
+++ b/drivers/clk/meson/mmc-clkc.c
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/amlogic,mmc-clkc.h>
+
+#include "sclk-div.h"
+#include "clk-phase-delay.h"
+#include "clk-regmap.h"
+#include "clk-phase.h"
+
+/* clock ID used by internal driver */
+
+#define SD_EMMC_CLOCK		0
+#define CLK_DELAY_STEP_PS_GX	200
+#define CLK_DELAY_STEP_PS_AXG	78
+#define MUX_CLK_NUM_PARENTS	2
+#define MMC_MAX_CLKS		4
+
+struct mmc_clkc_data {
+	struct meson_clk_phase_delay_data tx;
+	struct meson_clk_phase_delay_data rx;
+};
+
+static struct clk_regmap_mux_data mmc_clkc_mux_data = {
+	.offset = SD_EMMC_CLOCK,
+	.mask   = 0x3,
+	.shift  = 6,
+};
+
+static const struct meson_sclk_div_data mmc_clkc_div_data = {
+	.div = {
+		.reg_off = SD_EMMC_CLOCK,
+		.width   = 6,
+	},
+	.flags = MESON_SCLK_ONE_BASED,
+};
+
+static struct meson_clk_phase_data mmc_clkc_core_phase = {
+	.ph = {
+		.reg_off = SD_EMMC_CLOCK,
+		.shift   = 8,
+		.width   = 2,
+	}
+};
+
+static const struct mmc_clkc_data mmc_clkc_gx_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 4,
+		},
+		.delay_step_ps = CLK_DELAY_STEP_PS_GX,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 20,
+			.width   = 4,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_GX,
+	},
+};
+
+static const struct mmc_clkc_data mmc_clkc_axg_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 22,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+};
+
+static const struct of_device_id mmc_clkc_match_table[] = {
+	{
+		.compatible	= "amlogic,gx-mmc-clkc",
+		.data		= &mmc_clkc_gx_data
+	},
+	{
+		.compatible	= "amlogic,axg-mmc-clkc",
+		.data		= &mmc_clkc_axg_data
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
+
+static struct clk_regmap *
+mmc_clkc_register_clk(struct device *dev, struct regmap *map,
+		      struct clk_init_data *init,
+		      const char *suffix, void *data)
+{
+	struct clk_regmap *clk;
+	char *name;
+	int ret;
+
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
+
+	init->name = name;
+	clk->map = map;
+	clk->data = data;
+	clk->hw.init = init;
+	ret = devm_clk_hw_register(dev, &clk->hw);
+	if (ret)
+		clk = ERR_PTR(ret);
+
+	kfree(name);
+	return clk;
+}
+
+static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
+						struct regmap *map)
+{
+	const char *parent_names[MUX_CLK_NUM_PARENTS];
+	struct clk_init_data init;
+	struct clk_regmap *mux;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+		char name[8];
+
+		snprintf(name, sizeof(name), "clkin%d", i);
+		clk = devm_clk_get(dev, name);
+		if (IS_ERR(clk)) {
+			if (clk != ERR_PTR(-EPROBE_DEFER))
+				dev_err(dev, "Missing clock %s\n", name);
+			return ERR_CAST(clk);
+		}
+
+		parent_names[i] = __clk_get_name(clk);
+	}
+
+	init.ops = &clk_regmap_mux_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_names = parent_names;
+	init.num_parents = MUX_CLK_NUM_PARENTS;
+
+	mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
+	if (IS_ERR(mux))
+		dev_err(dev, "Mux clock registration failed\n");
+
+	return mux;
+}
+
+static struct clk_regmap *
+mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
+				  char *suffix, const struct clk_hw *hw,
+				  unsigned long flags,
+				  const struct clk_ops *ops, void *data)
+{
+	struct clk_init_data init;
+	struct clk_regmap *clk;
+	const char *parent_name = clk_hw_get_name(hw);
+
+	init.ops = ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
+	if (IS_ERR(clk))
+		dev_err(dev, "%s clock registration failed\n", suffix);
+
+	return clk;
+}
+
+static int mmc_clkc_probe(struct platform_device *pdev)
+{
+	struct clk_hw_onecell_data *onecell_data;
+	struct device *dev = &pdev->dev;
+	struct mmc_clkc_data *data;
+	struct regmap *map;
+	struct clk_regmap *clk, *core;
+	struct meson_sclk_div_data *div_data;
+
+	/*cast to drop the const in match->data*/
+	data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
+	map = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(map)) {
+		dev_err(dev, "could not find mmc clock controller\n");
+		return PTR_ERR(map);
+	}
+
+	onecell_data = devm_kzalloc(dev,
+				    struct_size(onecell_data, hws,
+						MMC_MAX_CLKS),
+				    GFP_KERNEL);
+	if (!onecell_data)
+		return -ENOMEM;
+
+	clk = mmc_clkc_register_mux(dev, map);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
+	if (!div_data)
+		return -ENOMEM;
+
+	memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
+						&clk->hw,
+						CLK_SET_RATE_PARENT,
+						&meson_sclk_div_ops,
+						div_data);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
+	core = mmc_clkc_register_clk_with_parent(dev, map, "core",
+						 &clk->hw,
+						 CLK_SET_RATE_PARENT,
+						 &meson_clk_phase_ops,
+						 &mmc_clkc_core_phase);
+	if (IS_ERR(core))
+		return PTR_ERR(core);
+
+	onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						&data->rx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						&data->tx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
+	onecell_data->num = MMC_MAX_CLKS;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   onecell_data);
+}
+
+static struct platform_driver mmc_clkc_driver = {
+	.probe		= mmc_clkc_probe,
+	.driver		= {
+		.name	= "meson-mmc-clkc",
+		.of_match_table = of_match_ptr(mmc_clkc_match_table),
+	},
+};
+
+module_platform_driver(mmc_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
+MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From mhocko at suse.com  Thu Jan 13 04:02:26 2022
From: mhocko at suse.com (Michal Hocko)
Date: Thu, 13 Jan 2022 13:02:26 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd/0Sgxy+jLm5cqd@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
 <Yduuyrk/AZG717Hs@google.com> <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>
 <Yd/0Sgxy+jLm5cqd@google.com>
Message-ID: <YeAU0n1puxyr4N6Y@dhcp22.suse.cz>

On Thu 13-01-22 02:43:38, Yu Zhao wrote:
[...]
> > > The bottom line is I can try various optimizations, e.g., preallocate
> > > a few buffers for a limited number of page walkers and if this number
> > > has been reached, fallback to the rmap-based function. But I have yet
> > > to see evidence that calls for additional complexity.
> > 
> > I would disagree here. This is not an optimization. You should be
> > avoiding allocations from the memory reclaim because any allocation just
> > add a runtime behavior complexity and potential corner cases.
> 
> Would __GFP_NOMEMALLOC address your concern? It prevents allocations
> from accessing the reserves even under PF_MEMALLOC.

__GFP_NOMEMALLOC would deal with the complete memory depletion concern
for sure but I am not sure how any of these allocations would succeed
when called from the direct reclaim. Some access to memory reserves is
necessary if you insist on allocating from the reclaim process.

You can have a look at the limited memory reserves access by oom victims
for an example of how this can be done.

-- 
Michal Hocko
SUSE Labs


From radheys at xilinx.com  Thu Jan 13 04:09:41 2022
From: radheys at xilinx.com (Radhey Shyam Pandey)
Date: Thu, 13 Jan 2022 12:09:41 +0000
Subject: [PATCH net v2 4/9] net: axienet: add missing memory barriers
In-Reply-To: <20220112173700.873002-5-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-5-robert.hancock@calian.com>
Message-ID: <SA1PR02MB85604DE700BA8511C604B632C7539@SA1PR02MB8560.namprd02.prod.outlook.com>

> -----Original Message-----
> From: Robert Hancock <robert.hancock at calian.com>
> Sent: Wednesday, January 12, 2022 11:07 PM
> To: netdev at vger.kernel.org
> Cc: Radhey Shyam Pandey <radheys at xilinx.com>; davem at davemloft.net;
> kuba at kernel.org; linux-arm-kernel at lists.infradead.org; Michal Simek
> <michals at xilinx.com>; ariane.keller at tik.ee.ethz.ch; daniel at iogearbox.net;
> Robert Hancock <robert.hancock at calian.com>
> Subject: [PATCH net v2 4/9] net: axienet: add missing memory barriers
> 
> This driver was missing some required memory barriers:
> 
> Use dma_rmb to ensure we see all updates to the descriptor after we see that
> an entry has been completed.
> 
> Use wmb and rmb to avoid stale descriptor status between the TX path and TX
> complete IRQ path.
> 
> Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet
> driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 11 ++++++++++-
>  1 file changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> index f4ae035bed35..de8f85175a6c 100644
> --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> @@ -632,6 +632,8 @@ static int axienet_free_tx_chain(struct net_device
> *ndev, u32 first_bd,
>  		if (nr_bds == -1 && !(status &
> XAXIDMA_BD_STS_COMPLETE_MASK))
>  			break;
> 
> +		/* Ensure we see complete descriptor update */
> +		dma_rmb();
>  		phys = desc_get_phys_addr(lp, cur_p);
>  		dma_unmap_single(ndev->dev.parent, phys,
>  				 (cur_p->cntrl &
> XAXIDMA_BD_CTRL_LENGTH_MASK), @@ -645,8 +647,10 @@ static int
> axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
>  		cur_p->app1 = 0;
>  		cur_p->app2 = 0;
>  		cur_p->app4 = 0;
> -		cur_p->status = 0;
>  		cur_p->skb = NULL;
> +		/* ensure our transmit path and device don't prematurely see
> status cleared */
> +		wmb();
> +		cur_p->status = 0;

Any reason for moving status initialization down?

> 
>  		if (sizep)
>  			*sizep += status &
> XAXIDMA_BD_STS_ACTUAL_LEN_MASK; @@ -704,6 +708,9 @@ static inline
> int axienet_check_tx_bd_space(struct axienet_local *lp,
>  					    int num_frag)
>  {
>  	struct axidma_bd *cur_p;
> +
> +	/* Ensure we see all descriptor updates from device or TX IRQ path */
> +	rmb();
>  	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
>  	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
>  		return NETDEV_TX_BUSY;
> @@ -843,6 +850,8 @@ static void axienet_recv(struct net_device *ndev)
> 
>  		tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
> 
> +		/* Ensure we see complete descriptor update */
> +		dma_rmb();
>  		phys = desc_get_phys_addr(lp, cur_p);
>  		dma_unmap_single(ndev->dev.parent, phys, lp-
> >max_frm_size,
>  				 DMA_FROM_DEVICE);

Ideally we would also need a write barrier in xmit function just before 
updating tail descriptor.

> --
> 2.31.1



From alexandru.elisei at arm.com  Thu Jan 13 04:12:04 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 13 Jan 2022 12:12:04 +0000
Subject: [PATCH v5 05/69] KVM: arm64: Allow preservation of the S2 SW bits
In-Reply-To: <20211129200150.351436-6-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-6-maz@kernel.org>
Message-ID: <YeAXFOR1wf3LekrQ@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:46PM +0000, Marc Zyngier wrote:
> The S2 page table code has a limited use the SW bits, but we are about
> to need them to encode some guest Stage-2 information (its mapping size
> in the form of the TTL encoding).
> 
> Propagate the SW bits specified by the caller, and store them into
> the corresponding entry.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 8cdbc43fa651..d69e400b2de6 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -1064,9 +1064,6 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
>  	u32 level;
>  	kvm_pte_t set = 0, clr = 0;
>  
> -	if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
> -		return -EINVAL;
> -
>  	if (prot & KVM_PGTABLE_PROT_R)
>  		set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
>  
> @@ -1076,6 +1073,10 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
>  	if (prot & KVM_PGTABLE_PROT_X)
>  		clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
>  
> +	/* Always propagate the SW bits */
> +	clr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_SW, 0xf);

Nitpick: isn't that the same as:

	clr |= KVM_PTE_LEAF_ATTR_HI_SW;

which looks more readable to me.

> +	set |= prot & KVM_PTE_LEAF_ATTR_HI_SW;

Checked stage2_attr_walker() callbak, first it clears the bits in clr, then
sets the bits in set, so this looks correct to me:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,
Alex

> +
>  	ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level);
>  	if (!ret)
>  		kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, pgt->mmu, addr, level);
> -- 
> 2.30.2
> 


From alim.akhtar at samsung.com  Thu Jan 13 04:11:20 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:20 +0530
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-1-alim.akhtar@samsung.com>

This patch set adds basic support for the Tesla Full Self-Driving (FSD)
SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
as well as several IPs.

Patches 1 to 8 provide support for the clock controller
(which is designed similarly to Exynos SoCs).

The remaining changes provide pinmux support, initial device tree support,
and SPI, ADC, and MCT IP functionality.


Alim Akhtar (21):
  dt-bindings: clock: Document FSD CMU bindings
  dt-bindings: clock: Add bindings definitions for FSD CMU blocks
  clk: samsung: fsd: Add initial clock support
  clk: samsung: fsd: Add cmu_peric block clock information
  clk: samsung: fsd: Add cmu_fsys0 clock information
  clk: samsung: fsd: Add cmu_fsys1 clock information
  clk: samsung: fsd: Add cmu_imem block clock information
  clk: samsung: fsd: Add cmu_mfc block clock information
  clk: samsung: fsd: Add cam_csi block clock information
  dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
  pinctrl: samsung: add FSD SoC specific data
  dt-bindings: add vendor prefix for Tesla
  dt-bindings: arm: add Tesla FSD ARM SoC
  arm64: dts: fsd: Add initial device tree support
  arm64: dts: fsd: Add initial pinctrl support
  arm64: defconfig: Enable Tesla FSD SoC
  Documentation: bindings: Add fsd spi compatible in dt-bindings
    document
  spi: s3c64xx: Add spi port configuration for Tesla FSD SoC
  dt-bindings: iio: adc: exynos-adc: Add ADC-V3 variant
  iio: adc: exynos-adc: Add support for ADC V3 controller
  arm64: dts: fsd: Add ADC device tree node

Aswani Reddy (2):
  arm64: dts: fsd: Add SPI device nodes
  clocksource: exynos_mct: Add support for handling three clusters

 .../devicetree/bindings/arm/tesla.yaml        |   25 +
 .../bindings/clock/tesla,fsd-clock.yaml       |  212 ++
 .../bindings/iio/adc/samsung,exynos-adc.yaml  |    1 +
 .../bindings/pinctrl/samsung-pinctrl.txt      |    1 +
 .../devicetree/bindings/spi/spi-samsung.txt   |    1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    8 +
 arch/arm64/Kconfig.platforms                  |    6 +
 arch/arm64/boot/dts/Makefile                  |    1 +
 arch/arm64/boot/dts/tesla/Makefile            |    3 +
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  338 +++
 arch/arm64/boot/dts/tesla/fsd.dts             |  156 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  805 +++++++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-fsd.c                 | 1858 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |    1 +
 drivers/clk/samsung/clk-pll.h                 |    1 +
 drivers/clocksource/exynos_mct.c              |    6 +-
 drivers/iio/adc/exynos_adc.c                  |   74 +-
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    |   71 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |    1 +
 drivers/spi/spi-s3c64xx.c                     |   13 +
 include/dt-bindings/clock/fsd-clk.h           |  146 ++
 25 files changed, 3731 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
 create mode 100644 drivers/clk/samsung/clk-fsd.c
 create mode 100644 include/dt-bindings/clock/fsd-clk.h


base-commit: c9e6606c7fe92b50a02ce51dda82586ebdf99b48
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:21 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:21 +0530
Subject: [PATCH 01/23] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122311epcas5p4b7c253b49dce3bd3580407fcf312e70e@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-2-alim.akhtar@samsung.com>

Add dt-schema documentation for Tesla FSD SoC clock controller.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../bindings/clock/tesla,fsd-clock.yaml       | 212 ++++++++++++++++++
 1 file changed, 212 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..58f341e5004d
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,212 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+description: |
+  FSD clock controller consist of several clock management unit
+  (CMU), which generates clocks for various inteernal SoC blocks.
+  The root clock comes from external OSC clock (24 MHz).
+
+  All available clocks are defined as preprocessor macros in
+  'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+  compatible:
+    enum:
+      - tesla,fsd-clock-cmu
+      - tesla,fsd-clock-imem
+      - tesla,fsd-clock-peric
+      - tesla,fsd-clock-fsys0
+      - tesla,fsd-clock-fsys1
+      - tesla,fsd-clock-mfc
+      - tesla,fsd-clock-cam_csi
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  clock-names:
+    minItems: 1
+    maxItems: 6
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cmu
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-imem
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: IMEM TCU clock (from CMU_CMU)
+            - description: IMEM bus clock (from CMU_CMU)
+            - description: IMEM DMA clock (from CMU_CMU)
+
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_imem_tcuclk
+            - const: dout_cmu_imem_aclk
+            - const: dout_cmu_imem_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-peric
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div4 clock (from CMU_CMU)
+            - description: PERIC shared1 div36 clock (from CMU_CMU)
+            - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+            - description: PERIC shared0 div20 clock (from CMU_CMU)
+            - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div4
+            - const: dout_cmu_peric_shared1div36
+            - const: dout_cmu_peric_shared0div3_tbuclk
+            - const: dout_cmu_peric_shared0div20
+            - const: dout_cmu_peric_shared1div4_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys0
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div6 clock (from CMU_CMU)
+            - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+            - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div6
+            - const: dout_cmu_fsys0_shared1div4
+            - const: dout_cmu_fsys0_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys1
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+            - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_fsys1_shared0div8
+            - const: dout_cmu_fsys1_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-mfc
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cam_csi
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+
+        clock-names:
+          items:
+            - const: fin_pll
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_FSYS1
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+
+    clock_fsys1: clock-controller at 16810000 {
+          compatible = "tesla,fsd-clock-fsys1";
+          reg = <0x0 0x16810000 0x0 0x3000>;
+          #clock-cells = <1>;
+
+          clocks = <&fin_pll>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+          clock-names = "fin_pll",
+                        "dout_cmu_fsys1_shared0div8",
+                        "dout_cmu_fsys1_shared0div4";
+    };
+
+...
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:22 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:22 +0530
Subject: [PATCH 02/23] dt-bindings: clock: Add bindings definitions for FSD
 CMU blocks
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122317epcas5p11937078e2701b319a13b29e044224ec0@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-3-alim.akhtar@samsung.com>

Clock controller driver of FSD platform is designed to have separate
instances for each particular CMU. So clock IDs in this bindings header
also start from 1 for each CMU block.

Cc: linux-fsd at tesla.com
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 include/dt-bindings/clock/fsd-clk.h | 146 ++++++++++++++++++++++++++++
 1 file changed, 146 insertions(+)
 create mode 100644 include/dt-bindings/clock/fsd-clk.h

diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
new file mode 100644
index 000000000000..9b97417ea6a1
--- /dev/null
+++ b/include/dt-bindings/clock/fsd-clk.h
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * The constants defined in this header are being used in dts
+ * and fsd platform driver.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_FSD_H
+#define _DT_BINDINGS_CLOCK_FSD_H
+
+/* CMU */
+#define DOUT_CMU_PLL_SHARED0_DIV4		1
+#define DOUT_CMU_PERIC_SHARED1DIV36		2
+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
+#define DOUT_CMU_PERIC_SHARED0DIV20		4
+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
+#define DOUT_CMU_PLL_SHARED0_DIV6		6
+#define DOUT_CMU_FSYS0_SHARED1DIV4		7
+#define DOUT_CMU_FSYS0_SHARED0DIV4		8
+#define DOUT_CMU_FSYS1_SHARED0DIV8		9
+#define DOUT_CMU_FSYS1_SHARED0DIV4		10
+#define CMU_CPUCL_SWITCH_GATE			11
+#define DOUT_CMU_IMEM_TCUCLK			12
+#define DOUT_CMU_IMEM_ACLK			13
+#define DOUT_CMU_IMEM_DMACLK			14
+#define GAT_CMU_FSYS0_SHARED0DIV4		15
+#define CMU_NR_CLK				16
+
+/* PERIC */
+#define PERIC_SCLK_UART0			1
+#define PERIC_PCLK_UART0			2
+#define PERIC_SCLK_UART1			3
+#define PERIC_PCLK_UART1			4
+#define PERIC_DMA0_IPCLKPORT_ACLK		5
+#define PERIC_DMA1_IPCLKPORT_ACLK		6
+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
+#define PERIC_PCLK_SPI0                         9
+#define PERIC_SCLK_SPI0                         10
+#define PERIC_PCLK_SPI1                         11
+#define PERIC_SCLK_SPI1                         12
+#define PERIC_PCLK_SPI2                         13
+#define PERIC_SCLK_SPI2                         14
+#define PERIC_PCLK_TDM0                         15
+#define PERIC_PCLK_HSI2C0			16
+#define PERIC_PCLK_HSI2C1			17
+#define PERIC_PCLK_HSI2C2			18
+#define PERIC_PCLK_HSI2C3			19
+#define PERIC_PCLK_HSI2C4			20
+#define PERIC_PCLK_HSI2C5			21
+#define PERIC_PCLK_HSI2C6			22
+#define PERIC_PCLK_HSI2C7			23
+#define PERIC_MCAN0_IPCLKPORT_CCLK		24
+#define PERIC_MCAN0_IPCLKPORT_PCLK		25
+#define PERIC_MCAN1_IPCLKPORT_CCLK		26
+#define PERIC_MCAN1_IPCLKPORT_PCLK		27
+#define PERIC_MCAN2_IPCLKPORT_CCLK		28
+#define PERIC_MCAN2_IPCLKPORT_PCLK		29
+#define PERIC_MCAN3_IPCLKPORT_CCLK		30
+#define PERIC_MCAN3_IPCLKPORT_PCLK		31
+#define PERIC_PCLK_ADCIF			32
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
+#define PERIC_HCLK_TDM0				40
+#define PERIC_PCLK_TDM1				41
+#define PERIC_HCLK_TDM1				42
+#define PERIC_EQOS_PHYRXCLK_MUX			43
+#define PERIC_EQOS_PHYRXCLK			44
+#define PERIC_DOUT_RGMII_CLK			45
+#define PERIC_NR_CLK				46
+
+/* FSYS0 */
+#define UFS0_MPHY_REFCLK_IXTAL24		1
+#define UFS0_MPHY_REFCLK_IXTAL26		2
+#define UFS1_MPHY_REFCLK_IXTAL24		3
+#define UFS1_MPHY_REFCLK_IXTAL26		4
+#define UFS0_TOP0_HCLK_BUS			5
+#define UFS0_TOP0_ACLK				6
+#define UFS0_TOP0_CLK_UNIPRO			7
+#define UFS0_TOP0_FMP_CLK			8
+#define UFS1_TOP1_HCLK_BUS			9
+#define UFS1_TOP1_ACLK				10
+#define UFS1_TOP1_CLK_UNIPRO			11
+#define UFS1_TOP1_FMP_CLK			12
+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
+#define FSYS0_NR_CLK				23
+
+/* FSYS1 */
+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
+#define FSYS1_NR_CLK				9
+
+/* IMEM */
+#define IMEM_DMA0_IPCLKPORT_ACLK		1
+#define IMEM_DMA1_IPCLKPORT_ACLK		2
+#define IMEM_WDT0_IPCLKPORT_PCLK		3
+#define IMEM_WDT1_IPCLKPORT_PCLK		4
+#define IMEM_WDT2_IPCLKPORT_PCLK		5
+#define IMEM_MCT_PCLK				6
+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
+#define IMEM_NR_CLK				12
+
+/* MFC */
+#define MFC_MFC_IPCLKPORT_ACLK			1
+#define MFC_NR_CLK				2
+
+/* CAM_CSI */
+#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
+#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
+#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
+#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
+#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
+#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
+#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
+#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
+#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
+#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
+#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
+#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
+#define CAM_CSI_NR_CLK				13
+#endif /* _DT_BINDINGS_CLOCK_FSD_H */
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:23 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:23 +0530
Subject: [PATCH 03/23] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122324epcas5p105c53b448b5801813a02a88c6107a2f3@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-4-alim.akhtar@samsung.com>

Add initial clock support for FSD (Full Self-Driving) SoC
which is required to bring-up platforms based on this SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/Makefile  |   1 +
 drivers/clk/samsung/clk-fsd.c | 308 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c |   1 +
 drivers/clk/samsung/clk-pll.h |   1 +
 4 files changed, 311 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-fsd.c

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index c46cf11e4d0b..d66b2ede004c 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
 obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
 obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
+obj-$(CONFIG_ARCH_TESLA_FSD)         += clk-fsd.o
 obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..e47523106d9e
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Common Clock Framework support for FSD SoC.
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+
+#include "clk.h"
+#include <dt-bindings/clock/fsd-clk.h>
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0			0x0
+#define PLL_LOCKTIME_PLL_SHARED1			0x4
+#define PLL_LOCKTIME_PLL_SHARED2			0x8
+#define PLL_LOCKTIME_PLL_SHARED3			0xc
+#define PLL_CON0_PLL_SHARED0				0x100
+#define PLL_CON0_PLL_SHARED1				0x120
+#define PLL_CON0_PLL_SHARED2				0x140
+#define PLL_CON0_PLL_SHARED3				0x160
+#define MUX_CMU_CIS0_CLKMUX				0x1000
+#define MUX_CMU_CIS1_CLKMUX				0x1004
+#define MUX_CMU_CIS2_CLKMUX				0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX				0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX				0x1014
+#define MUX_PLL_SHARED0_MUX				0x1020
+#define MUX_PLL_SHARED1_MUX				0x1024
+#define DIV_CMU_CIS0_CLK				0x1800
+#define DIV_CMU_CIS1_CLK				0x1804
+#define DIV_CMU_CIS2_CLK				0x1808
+#define DIV_CMU_CMU_ACLK				0x180c
+#define DIV_CMU_CPUCL_SWITCH				0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4			0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3			0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4			0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4			0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8			0x182c
+#define DIV_CMU_IMEM_ACLK				0x1834
+#define DIV_CMU_IMEM_DMACLK				0x1838
+#define DIV_CMU_IMEM_TCUCLK				0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20			0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK		0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36			0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK		0x1850
+#define DIV_PLL_SHARED0_DIV2				0x1858
+#define DIV_PLL_SHARED0_DIV3				0x185c
+#define DIV_PLL_SHARED0_DIV4				0x1860
+#define DIV_PLL_SHARED0_DIV6				0x1864
+#define DIV_PLL_SHARED1_DIV3				0x1868
+#define DIV_PLL_SHARED1_DIV36				0x186c
+#define DIV_PLL_SHARED1_DIV4				0x1870
+#define DIV_PLL_SHARED1_DIV9				0x1874
+#define GAT_CMU_CIS0_CLKGATE				0x2000
+#define GAT_CMU_CIS1_CLKGATE				0x2004
+#define GAT_CMU_CIS2_CLKGATE				0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE			0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE			0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK			0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE			0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE			0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE			0x2028
+#define GAT_CMU_IMEM_ACLK_GATE				0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE			0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE			0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE		0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE			0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE		0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE			0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK			0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK		0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU	0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK		0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_CON0_PLL_SHARED0,
+	PLL_CON0_PLL_SHARED1,
+	PLL_CON0_PLL_SHARED2,
+	PLL_CON0_PLL_SHARED3,
+	MUX_CMU_CIS0_CLKMUX,
+	MUX_CMU_CIS1_CLKMUX,
+	MUX_CMU_CIS2_CLKMUX,
+	MUX_CMU_CPUCL_SWITCHMUX,
+	MUX_CMU_FSYS1_ACLK_MUX,
+	MUX_PLL_SHARED0_MUX,
+	MUX_PLL_SHARED1_MUX,
+	DIV_CMU_CIS0_CLK,
+	DIV_CMU_CIS1_CLK,
+	DIV_CMU_CIS2_CLK,
+	DIV_CMU_CMU_ACLK,
+	DIV_CMU_CPUCL_SWITCH,
+	DIV_CMU_FSYS0_SHARED0DIV4,
+	DIV_CMU_FSYS0_SHARED1DIV3,
+	DIV_CMU_FSYS0_SHARED1DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV8,
+	DIV_CMU_IMEM_ACLK,
+	DIV_CMU_IMEM_DMACLK,
+	DIV_CMU_IMEM_TCUCLK,
+	DIV_CMU_PERIC_SHARED0DIV20,
+	DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+	DIV_CMU_PERIC_SHARED1DIV36,
+	DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+	DIV_PLL_SHARED0_DIV2,
+	DIV_PLL_SHARED0_DIV3,
+	DIV_PLL_SHARED0_DIV4,
+	DIV_PLL_SHARED0_DIV6,
+	DIV_PLL_SHARED1_DIV3,
+	DIV_PLL_SHARED1_DIV36,
+	DIV_PLL_SHARED1_DIV4,
+	DIV_PLL_SHARED1_DIV9,
+	GAT_CMU_CIS0_CLKGATE,
+	GAT_CMU_CIS1_CLKGATE,
+	GAT_CMU_CIS2_CLKGATE,
+	GAT_CMU_CPUCL_SWITCH_GATE,
+	GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+	GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+	GAT_CMU_IMEM_ACLK_GATE,
+	GAT_CMU_IMEM_DMACLK_GATE,
+	GAT_CMU_IMEM_TCUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+	GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+	GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+	GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+	GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+	GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+	GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2000000000, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1800000000, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+	    PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+	    PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+	    PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+	    PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+	MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+	MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+	MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+	    MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+	MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+	DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+	DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+	DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+	    DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+	DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+	    DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+	    DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+	DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+	    DIV_CMU_IMEM_ACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+	    DIV_CMU_IMEM_DMACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+	    DIV_CMU_IMEM_TCUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+	    "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+	    "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+	    "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+	    "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV2, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV3, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+	    DIV_PLL_SHARED0_DIV4, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+	    DIV_PLL_SHARED0_DIV6, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV3, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+	    DIV_PLL_SHARED1_DIV36, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV4, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+	    DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+	GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+	     GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+	     GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+	     GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+	     GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+	     GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+	     GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+	     GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+	.pll_clks		= cmu_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cmu_pll_clks),
+	.mux_clks		= cmu_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cmu_mux_clks),
+	.div_clks		= cmu_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cmu_div_clks),
+	.gate_clks		= cmu_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cmu_gate_clks),
+	.nr_clk_ids		= CMU_NR_CLK,
+	.clk_regs		= cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 83d1b03647db..e321036875f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_1450x:
 	case pll_1451x:
 	case pll_1452x:
+	case pll_142xx:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index a739f2b7ae80..9ba5d7c867c5 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -38,6 +38,7 @@ enum samsung_pll_type {
 	pll_1460x,
 	pll_0822x,
 	pll_0831x,
+	pll_142xx,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:24 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:24 +0530
Subject: [PATCH 04/23] clk: samsung: fsd: Add cmu_peric block clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122330epcas5p46ae5cd30950b1d9126479231dcf5da49@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-5-alim.akhtar@samsung.com>

This patch adds CMU_PERIC block clock information needed
for various IPs functions found in this block.

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 464 +++++++++++++++++++++++++++++++++-
 1 file changed, 463 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index e47523106d9e..6da20966ba99 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -9,12 +9,59 @@
  *
  */
 
-#include <linux/clk-provider.h>
 #include <linux/of.h>
+#include <linux/clk.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
 
 #include "clk.h"
 #include <dt-bindings/clock/fsd-clk.h>
 
+/* Gate register bits */
+#define GATE_MANUAL		BIT(20)
+#define GATE_ENABLE_HWACG	BIT(28)
+
+/* Gate register offsets range */
+#define GATE_OFF_START		0x2000
+#define GATE_OFF_END		0x2fff
+
+/**
+ * fsd_init_clocks - Set clocks initial configuration
+ * @np:			CMU device tree node with "reg" property (CMU addr)
+ * @reg_offs:		Register offsets array for clocks to init
+ * @reg_offs_len:	Number of register offsets in reg_offs array
+ *
+ * Set manual control mode for all gate clocks.
+ */
+static void __init fsd_init_clocks(struct device_node *np,
+		const unsigned long *reg_offs, size_t reg_offs_len)
+{
+	void __iomem *reg_base;
+	size_t i;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base)
+		panic("%s: failed to map registers\n", __func__);
+
+	for (i = 0; i < reg_offs_len; ++i) {
+		void __iomem *reg = reg_base + reg_offs[i];
+		u32 val;
+
+		/* Modify only gate clock registers */
+		if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
+			continue;
+
+		val = readl(reg);
+		val |= GATE_MANUAL;
+		val &= ~GATE_ENABLE_HWACG;
+		writel(val, reg);
+	}
+
+	iounmap(reg_base);
+}
+
 /* Register Offset definitions for CMU_CMU (0x11c10000) */
 #define PLL_LOCKTIME_PLL_SHARED0			0x0
 #define PLL_LOCKTIME_PLL_SHARED1			0x4
@@ -306,3 +353,418 @@ static void __init fsd_clk_cmu_init(struct device_node *np)
 }
 
 CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX		0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX		0x120
+#define PLL_CON0_PERIC_PCLK_MUX			0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX		0x160
+#define PLL_CON0_SPI_CLK			0x180
+#define PLL_CON0_SPI_PCLK			0x1a0
+#define PLL_CON0_UART_CLK			0x1c0
+#define PLL_CON0_UART_PCLK			0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK			0x1000
+#define DIV_EQOS_BUSCLK				0x1800
+#define DIV_PERIC_MCAN_CLK			0x1804
+#define DIV_RGMII_CLK				0x1808
+#define DIV_RII_CLK				0x180c
+#define DIV_RMII_CLK				0x1810
+#define DIV_SPI_CLK				0x1814
+#define DIV_UART_CLK				0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I	0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK		0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK	0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK	0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK	0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK	0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM	0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS	0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM	0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS	0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK	0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK	0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK	0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK	0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK	0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK	0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK	0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK	0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK	0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I		0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I		0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I		0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I	0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I	0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK		0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D	0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P	0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0	0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK		0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK		0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK		0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK		0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK		0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK		0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK		0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK		0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK		0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK		0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK		0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK		0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK		0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK		0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK		0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK		0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK		0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK		0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0	0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0	0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK		0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK	0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK		0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI	0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK		0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI	0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK		0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI	0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M		0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK		0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M		0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK		0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART	0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK		0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART	0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK		0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK		0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+	PLL_CON0_PERIC_DMACLK_MUX,
+	PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+	PLL_CON0_PERIC_PCLK_MUX,
+	PLL_CON0_PERIC_TBUCLK_MUX,
+	PLL_CON0_SPI_CLK,
+	PLL_CON0_SPI_PCLK,
+	PLL_CON0_UART_CLK,
+	PLL_CON0_UART_PCLK,
+	MUX_PERIC_EQOS_PHYRXCLK,
+	DIV_EQOS_BUSCLK,
+	DIV_PERIC_MCAN_CLK,
+	DIV_RGMII_CLK,
+	DIV_RII_CLK,
+	DIV_RMII_CLK,
+	DIV_SPI_CLK,
+	DIV_UART_CLK,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+	GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+	GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+	GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+	GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+	GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+	GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+	GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+	GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+	GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+	GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+	GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART0_IPCLKPORT_PCLK,
+	GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART1_IPCLKPORT_PCLK,
+	GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+	FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+	MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+	MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+	    PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+	MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+	MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+	MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+	MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+		MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+	DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+	DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+	DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+		DIV_RGMII_CLK, 0, 4),
+	DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+	DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+	DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+	DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+	     GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+	     "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+	     "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+	.mux_clks		= peric_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric_mux_clks),
+	.div_clks		= peric_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric_div_clks),
+	.gate_clks		= peric_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric_gate_clks),
+	.fixed_clks		= peric_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(peric_fixed_clks),
+	.nr_clk_ids		= PERIC_NR_CLK,
+	.clk_regs		= peric_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric_clk_regs),
+	.clk_name		= "dout_cmu_pll_shared0_div4",
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+
+	info = of_device_get_match_data(dev);
+	fsd_init_clocks(np, info->clk_regs, info->nr_clk_regs);
+	samsung_cmu_register_one(np, info);
+
+	/* Keep bus clock running, so it's possible to access CMU registers */
+	if (info->clk_name) {
+		struct clk *bus_clk;
+
+		bus_clk = clk_get(dev, info->clk_name);
+		if (IS_ERR(bus_clk)) {
+			pr_err("%s: could not find bus clock %s; err = %ld\n",
+			       __func__, info->clk_name, PTR_ERR(bus_clk));
+		} else {
+			clk_prepare_enable(bus_clk);
+		}
+	}
+
+	return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+	{
+		.compatible = "tesla,fsd-clock-peric",
+		.data = &peric_cmu_info,
+	}, {
+	},
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+	.driver	= {
+		.name = "fsd-cmu",
+		.of_match_table = fsd_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+	return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:25 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:25 +0530
Subject: [PATCH 05/23] clk: samsung: fsd: Add cmu_fsys0 clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122334epcas5p2d5958c77b0635e848f81ed2c5c98cdd5@epcas5p2.samsung.com>
Message-ID: <20220113121143.22280-6-alim.akhtar@samsung.com>

CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
the related clock information for the same.

Cc: linux-fsd at tesla.com
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 6da20966ba99..8a7a668eb4be 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -713,6 +713,305 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_pll_shared0_div4",
 };
 
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO		0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK		0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1		0x160
+#define DIV_CLK_UNIPRO				0x1800
+#define DIV_EQS_RGMII_CLK_125			0x1804
+#define DIV_PERIBUS_GRP				0x1808
+#define DIV_EQOS_RII_CLK2O5			0x180c
+#define DIV_EQOS_RMIICLK_25			0x1810
+#define DIV_PCIE_PHY_OSCCLK			0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I	0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK	0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK	0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO	0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK	0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC	0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK	0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK	0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK	0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK	0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK	0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK		0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I	0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I	0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK	0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D	0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1	0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P	0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S	0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK	0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL	0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0	0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC	0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK	0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC	0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC	0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK	0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK	0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK	0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS	0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK	0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO	0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK	0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS	0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK	0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO	0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK	0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE			0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+	PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+	PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+	PLL_CON0_EQOS_RGMII_125_MUX1,
+	DIV_CLK_UNIPRO,
+	DIV_EQS_RGMII_CLK_125,
+	DIV_PERIBUS_GRP,
+	DIV_EQOS_RII_CLK2O5,
+	DIV_EQOS_RMIICLK_25,
+	DIV_PCIE_PHY_OSCCLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+	GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+	GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+	GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+	GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+	FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+	FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+	FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+	    PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+	MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+	    PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+	MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+	    PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+	DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+	DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQS_RGMII_CLK_125, 0, 4),
+	DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+	    "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQOS_RMIICLK_25, 0, 5),
+	DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+	     "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+	     "xtal_clk_pcie_phy",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+	      "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+	      CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+	     "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+	     "dout_fsys0_pcie_phy_oscclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+	.mux_clks		= fsys0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys0_mux_clks),
+	.div_clks		= fsys0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys0_div_clks),
+	.gate_clks		= fsys0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys0_gate_clks),
+	.fixed_clks		= fsys0_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys0_fixed_clks),
+	.nr_clk_ids		= FSYS0_NR_CLK,
+	.clk_regs		= fsys0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys0_clk_regs),
+	.clk_name		= "dout_cmu_fsys0_shared1div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -750,6 +1049,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	{
 		.compatible = "tesla,fsd-clock-peric",
 		.data = &peric_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys0",
+		.data = &fsys0_cmu_info,
 	}, {
 	},
 };
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:26 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:26 +0530
Subject: [PATCH 06/23] clk: samsung: fsd: Add cmu_fsys1 clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122338epcas5p17ad3a31077b98388c0a6779904ee651e@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-7-alim.akhtar@samsung.com>

Adds cmu_fsys1 block clock information which are needed
for PCIe IPs in block FSYS1.

Cc: linux-fsd at tesla.com
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 8a7a668eb4be..d06afab39d37 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1012,6 +1012,178 @@ static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys0_shared1div4",
 };
 
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX			0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX			0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK			0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK			0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK	0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK		0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK	0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK		0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL	0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK				0x2034
+#define GAT_FSYS1_PHY1_OSCCLK				0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK		0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK	0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK	0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK		0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0	0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0	0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK		0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK	0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK	0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK	0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK		0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK		0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK	0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK	0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK		0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK		0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL	0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK		0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK		0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+	PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+	PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+	DIV_CLK_FSYS1_PHY0_OSCCLK,
+	DIV_CLK_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+	GAT_FSYS1_PHY0_OSCCLLK,
+	GAT_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+	GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+	FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+	FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+	    PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+	MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+	    PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+	DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+	    DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+	DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+	    DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+	GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+	.mux_clks		= fsys1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys1_mux_clks),
+	.div_clks		= fsys1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys1_div_clks),
+	.gate_clks		= fsys1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys1_gate_clks),
+	.fixed_clks		= fsys1_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys1_fixed_clks),
+	.nr_clk_ids		= FSYS1_NR_CLK,
+	.clk_regs		= fsys1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys1_clk_regs),
+	.clk_name		= "dout_cmu_fsys1_shared0div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1052,6 +1224,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys0",
 		.data = &fsys0_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys1",
+		.data = &fsys1_cmu_info,
 	}, {
 	},
 };
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:27 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:27 +0530
Subject: [PATCH 07/23] clk: samsung: fsd: Add cmu_imem block clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122343epcas5p23831143e4e8fb92be8ad362f4817c03b@epcas5p2.samsung.com>
Message-ID: <20220113121143.22280-8-alim.akhtar@samsung.com>

Adds cmu_imem clock related code, imem block contains IPs
like WDT, DMA, TMU etc, these clocks are required for such
IP function.

Cc: linux-fsd at tesla.com
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index d06afab39d37..dc252e63099d 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1184,6 +1184,289 @@ static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys1_shared0div4",
 };
 
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK				0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK			0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK			0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK			0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK		0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO		0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK		0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK		0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS		0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK		0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS		0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK		0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK			0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK		0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK			0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK			0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK			0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM	0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM	0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM	0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS	0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS	0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS	0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM		0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS		0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM		0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS		0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK		0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK		0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK		0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK		0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK		0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK		0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK			0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK			0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK	0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK			0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK			0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK	0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK	0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK			0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D	0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU	0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P	0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK		0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK		0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK	0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK		0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK		0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK		0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK		0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK		0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK			0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK			0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK			0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK			0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+	PLL_CON0_CLK_IMEM_ACLK,
+	PLL_CON0_CLK_IMEM_INTMEMCLK,
+	PLL_CON0_CLK_IMEM_TCUCLK,
+	DIV_OSCCLK_IMEM_TMUTSCLK,
+	GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_WDT0_IPCLKPORT_CLK,
+	GAT_IMEM_WDT1_IPCLKPORT_CLK,
+	GAT_IMEM_WDT2_IPCLKPORT_CLK,
+	GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+	GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+	GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+	GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+	GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+	GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+	GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+	GAT_IMEM_GIC_IPCLKPORT_CLK,
+	GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_PCLK,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+	GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+	GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_TCU_IPCLKPORT_ACLK,
+	GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+	MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+	    PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+	    PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+	DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+	GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+	     GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+	.mux_clks		= imem_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(imem_mux_clks),
+	.div_clks		= imem_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(imem_div_clks),
+	.gate_clks		= imem_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(imem_gate_clks),
+	.nr_clk_ids		= IMEM_NR_CLK,
+	.clk_regs		= imem_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:28 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:28 +0530
Subject: [PATCH 08/23] clk: samsung: fsd: Add cmu_mfc block clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122346epcas5p41a7d6712c07544e99795ef5465f1f106@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-9-alim.akhtar@samsung.com>

This patch adds clock related to MFC IP.

Cc: linux-fsd at tesla.com
Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index dc252e63099d..927b310ce4a4 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1467,6 +1467,124 @@ static void __init fsd_clk_imem_init(struct device_node *np)
 
 CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
 
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC					0x0
+#define PLL_CON0_PLL_MFC					0x100
+#define MUX_MFC_BUSD						0x1000
+#define MUX_MFC_BUSP						0x1008
+#define DIV_MFC_BUSD_DIV4					0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK				0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM			0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS			0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK			0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK				0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D	0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P	0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK			0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK			0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK			0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK			0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK			0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK				0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK				0x2040
+#define GAT_MFC_BUSD_DIV4_GATE					0x2044
+#define GAT_MFC_BUSD_GATE					0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_MFC,
+	PLL_CON0_PLL_MFC,
+	MUX_MFC_BUSD,
+	MUX_MFC_BUSP,
+	DIV_MFC_BUSD_DIV4,
+	GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+	GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+	GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+	GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+	GAT_MFC_BUSD_DIV4_GATE,
+	GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 666000000, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+	    PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+	MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+	MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+	MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+	DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+	GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+	     GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+	     GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+	.pll_clks		= mfc_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(mfc_pll_clks),
+	.mux_clks		= mfc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mfc_mux_clks),
+	.div_clks		= mfc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mfc_div_clks),
+	.gate_clks		= mfc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mfc_gate_clks),
+	.nr_clk_ids		= MFC_NR_CLK,
+	.clk_regs		= mfc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1510,6 +1628,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys1",
 		.data = &fsys1_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-mfc",
+		.data = &mfc_cmu_info,
 	}, {
 	},
 };
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:29 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:29 +0530
Subject: [PATCH 09/23] clk: samsung: fsd: Add cam_csi block clock information
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122351epcas5p45f49a559af9f6d0c6ba573594f95561d@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-10-alim.akhtar@samsung.com>

Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.

Cc: linux-fsd at tesla.com
Signed-off-by: Sathyakam M <sathya at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 927b310ce4a4..1bed8c7eb605 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1585,6 +1585,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
 	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
 };
 
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI		0x0
+#define PLL_CON0_PLL_CAM_CSI			0x100
+#define DIV_CAM_CSI0_ACLK			0x1800
+#define DIV_CAM_CSI1_ACLK			0x1804
+#define DIV_CAM_CSI2_ACLK			0x1808
+#define DIV_CAM_CSI_BUSD			0x180c
+#define DIV_CAM_CSI_BUSP			0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK	0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK	0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0	0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1	0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2	0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC	0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC		0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK		0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK		0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK		0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK		0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK		0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK		0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK		0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK		0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK		0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK		0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK		0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK		0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK		0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK		0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK		0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK		0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK		0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK		0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK		0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK		0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK		0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK		0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK		0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK		0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D	0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P	0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK	0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK	0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CAM_CSI,
+	PLL_CON0_PLL_CAM_CSI,
+	DIV_CAM_CSI0_ACLK,
+	DIV_CAM_CSI1_ACLK,
+	DIV_CAM_CSI2_ACLK,
+	DIV_CAM_CSI_BUSD,
+	DIV_CAM_CSI_BUSP,
+	GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+	GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1066000000, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+	    PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+	MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+	DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+	DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+	GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+	     GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+	     "dout_cam_csi_busd",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+	     "dout_cam_csi_busp",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+	     GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+	.pll_clks		= cam_csi_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cam_csi_pll_clks),
+	.mux_clks		= cam_csi_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cam_csi_mux_clks),
+	.div_clks		= cam_csi_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cam_csi_div_clks),
+	.gate_clks		= cam_csi_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cam_csi_gate_clks),
+	.nr_clk_ids		= CAM_CSI_NR_CLK,
+	.clk_regs		= cam_csi_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cam_csi_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1631,6 +1835,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-mfc",
 		.data = &mfc_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-cam_csi",
+		.data = &cam_csi_cmu_info,
 	}, {
 	},
 };
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:30 +0530
Subject: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122354epcas5p19e5cebe9e85e9ba1758fa0b9d7d1ef75@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-11-alim.akhtar@samsung.com>

Add compatible for Tesla Full Self-Driving SoC. The
pinctrl hardware IP is similar to what found on most of the
exynos series of SoC, so this new compatible is added in
samsung pinctrl binding.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index b8b475967ff9..ba972998a0e4 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -24,6 +24,7 @@ Required Properties:
   - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
   - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
   - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
+  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:31 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:31 +0530
Subject: [PATCH 11/23] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122400epcas5p34363ba8f477b4c273d601d0b64324afa@epcas5p3.samsung.com>
Message-ID: <20220113121143.22280-12-alim.akhtar@samsung.com>

This patch adds Tesla FSD SoC specific data to enable pinctrl.
FSD SoC has similar pinctrl controller as found in the most
samsung/exynos SoCs.

Cc: linux-fsd at tesla.com
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
 3 files changed, 74 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 6b77fd24571e..b9175b4911ac 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -646,3 +646,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
 	.ctrl		= exynosautov9_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
 };
+
+/*
+ * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
+ * gpio/pin-mux/pinconfig controllers.
+ */
+
+/* pin banks of FSD pin-controller 0 (FSYS) */
+static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
+};
+
+/* pin banks of FSD pin-controller 1 (PERIC) */
+static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
+};
+
+/* pin banks of FSD pin-controller 2 (PMU) */
+static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
+};
+
+const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 FSYS0 data */
+		.pin_banks	= fsd_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 1 PERIC data */
+		.pin_banks	= fsd_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 2 PMU data */
+		.pin_banks	= fsd_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks2),
+	},
+};
+
+const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
+	.ctrl		= fsd_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 23f355ae9ca0..4b348c038f7a 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1268,6 +1268,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos850_of_data },
 	{ .compatible = "samsung,exynosautov9-pinctrl",
 		.data = &exynosautov9_of_data },
+	{ .compatible = "tesla,fsd-pinctrl",
+		.data = &fsd_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 547968a31aed..43d8a8a139c3 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -341,6 +341,7 @@ extern const struct samsung_pinctrl_of_match_data exynos5433_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
+extern const struct samsung_pinctrl_of_match_data fsd_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:32 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:32 +0530
Subject: [PATCH 12/23] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122404epcas5p4aa1c3ac09510eb55cce5fdd0791993a6@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-13-alim.akhtar@samsung.com>

Add vendor prefix for the Tesla (https://www.tesla.com)

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 66d6432fd781..af71d00f1092 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1189,6 +1189,8 @@ patternProperties:
     description: Shenzhen Techstar Electronics Co., Ltd.
   "^terasic,.*":
     description: Terasic Inc.
+  "^tesla,.*":
+    description: Tesla, Inc.
   "^tfc,.*":
     description: Three Five Corp
   "^thine,.*":
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:33 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:33 +0530
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-14-alim.akhtar@samsung.com>

Add device tree bindings for the Tesla FSD ARM SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/arm/tesla.yaml        | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml

diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..9f89cde76c85
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: FSD SoC board
+        items:
+          - const: tesla,fsd
+
+additionalProperties: true
+
+...
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:34 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:34 +0530
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-15-alim.akhtar@samsung.com>

Add initial device tree support for "Full Self-Driving" (FSD) SoC
This SoC contain three clusters of four cortex-a72 CPUs and various
peripheral IPs.

Cc: linux-fsd at tesla.com
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 MAINTAINERS                        |   8 +
 arch/arm64/Kconfig.platforms       |   6 +
 arch/arm64/boot/dts/Makefile       |   1 +
 arch/arm64/boot/dts/tesla/Makefile |   3 +
 arch/arm64/boot/dts/tesla/fsd.dts  | 140 ++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi | 715 +++++++++++++++++++++++++++++
 6 files changed, 873 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index fb18ce7168aa..02d56909c5e2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2726,6 +2726,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/tegra-cec.txt
 F:	drivers/media/cec/platform/tegra/
 
+ARM/TESLA FSD SoC SUPPORT
+M:	Alim Akhtar <alim.akhtar at samsung.com>
+M:	linux-fsd at tesla.com
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	arch/arm64/boot/dts/tesla*
+
 ARM/TETON BGA MACHINE SUPPORT
 M:	"Mark F. Brown" <mark.brown314 at gmail.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 54e3910e8b9b..bb8a047c2359 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -267,6 +267,12 @@ config ARCH_TEGRA
 	help
 	  This enables support for the NVIDIA Tegra SoC family.
 
+config ARCH_TESLA_FSD
+	bool "ARMv8 based Tesla platform"
+	select ARCH_EXYNOS
+	help
+	  Support for ARMv8 based Tesla platforms.
+
 config ARCH_SPRD
 	bool "Spreadtrum SoC platform"
 	help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += tesla
 subdir-y += ti
 subdir-y += toshiba
 subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a9818cda6b08
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+	fsd.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
new file mode 100644
index 000000000000..e9bbd3284de9
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dts
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+	model = "Tesla Full Self-Driving (FSD) SoC";
+	compatible = "tesla,fsd";
+
+	aliases {
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+		linux,initrd-start = <0xE0000000>;
+		linux,initrd-end = <0xE4F00000>;
+		bootargs = "console=ttySAC0,115200n8
+			earlycon=exynos4210,0x14180000 root=/dev/ram0
+			init=/linuxrc";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
+
+&serial_0 {
+	status = "okay";
+};
+
+&serial_1 {
+	status = "okay";
+};
+
+&clock_cmu {
+	status = "okay";
+};
+
+&clock_imem {
+	status = "okay";
+};
+
+&clock_peric {
+	status = "okay";
+};
+
+&smmu_isp {
+	status = "okay";
+};
+
+&clock_fsys0 {
+	status = "okay";
+};
+
+&clock_fsys1 {
+	status = "okay";
+};
+
+&smmu_peric {
+	status = "okay";
+};
+
+&smmu_imem {
+	status = "okay";
+};
+
+&smmu_fsys0 {
+	status = "okay";
+};
+
+&hsi2c_0 {
+	status = "okay";
+};
+
+&hsi2c_1 {
+	status = "okay";
+};
+
+&hsi2c_2 {
+	status = "okay";
+};
+
+&hsi2c_3 {
+	status = "okay";
+};
+
+&hsi2c_4 {
+	status = "okay";
+};
+
+&hsi2c_5 {
+	status = "okay";
+};
+
+&hsi2c_6 {
+	status = "okay";
+};
+
+&hsi2c_7 {
+	status = "okay";
+};
+
+&pwm_0 {
+	status = "okay";
+};
+
+&pwm_1 {
+	status = "okay";
+};
+
+&mdma0 {
+	status = "okay";
+};
+
+&mdma1 {
+	status = "okay";
+};
+
+&pdma0 {
+	status = "okay";
+};
+
+&pdma1 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..47cd9f20566e
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,715 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "tesla,fsd";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		watchdog0 = &watchdog_0;
+		watchdog1 = &watchdog_1;
+		watchdog2 = &watchdog_2;
+		hsi2c0 = &hsi2c_0;
+		hsi2c1 = &hsi2c_1;
+		hsi2c2 = &hsi2c_2;
+		hsi2c3 = &hsi2c_3;
+		hsi2c4 = &hsi2c_4;
+		hsi2c5 = &hsi2c_5;
+		hsi2c6 = &hsi2c_6;
+		hsi2c7 = &hsi2c_7;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpucl0_0>;
+				};
+				core1 {
+					cpu = <&cpucl0_1>;
+				};
+				core2 {
+					cpu = <&cpucl0_2>;
+				};
+				core3 {
+					cpu = <&cpucl0_3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpucl1_0>;
+				};
+				core1 {
+					cpu = <&cpucl1_1>;
+				};
+				core2 {
+					cpu = <&cpucl1_2>;
+				};
+				core3 {
+					cpu = <&cpucl1_3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpucl2_0>;
+				};
+				core1 {
+					cpu = <&cpucl2_1>;
+				};
+				core2 {
+					cpu = <&cpucl2_2>;
+				};
+				core3 {
+					cpu = <&cpucl2_3>;
+				};
+			};
+		};
+
+		/* Cluster 0 */
+		cpucl0_0: cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x000>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl0_1: cpu at 1 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x001>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl0_2: cpu at 2 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x002>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl0_3: cpu at 3 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x003>;
+				enable-method = "psci";
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		/* Cluster 1 */
+		cpucl1_0: cpu at 100 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x100>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl1_1: cpu at 101 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x101>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl1_2: cpu at 102 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x102>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl1_3: cpu at 103 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x103>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		/* Cluster 2 */
+		cpucl2_0: cpu at 200 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x200>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl2_1: cpu at 201 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x201>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl2_2: cpu at 202 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x202>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		cpucl2_3: cpu at 203 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x203>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+				next-level-cache = <&L2_0>;
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP: cpu-sleep {
+				idle-state-name = "c2";
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <30>;
+				exit-latency-us = <75>;
+				min-residency-us = <300>;
+				status = "okay";
+			};
+		};
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+	};
+
+	psci {
+		compatible = "arm,psci";
+		method = "smc";
+		cpu_on = <0xC4000003>;
+		cpu_suspend = <0xC4000001>;
+		cpu_off = <0x84000002>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	fin_pll: clock {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		#clock-cells = <0>;
+	};
+
+	soc: soc {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+		gic: interrupt-controller at 10400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
+				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+		};
+
+		smmu_isp: iommu at 12100000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x12100000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <11>;
+			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+				     /* Per context non-secure context interrupts, 0-7 interrupts */
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+			status = "disabled";
+		};
+
+		smmu_imem: iommu at 10200000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x10200000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <7>;
+			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
+				     /* Per context non-secure context interrupts, 0-3 interrupts */
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+			status = "disabled";
+		};
+
+		smmu_peric: iommu at 14900000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x14900000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+			status = "disabled";
+		};
+
+		smmu_fsys0: iommu at 15450000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x15450000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+			status = "disabled";
+		};
+
+		clock_cmu: clock-controller at 11C10000 {
+			compatible = "tesla,fsd-clock-cmu";
+			reg = <0x0 0x11C10000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+			status = "disabled";
+		};
+
+		clock_imem: clock-controller at 10010000 {
+			compatible = "tesla,fsd-clock-imem";
+			reg = <0x0 0x10010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
+				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_imem_tcuclk",
+				"dout_cmu_imem_aclk",
+				"dout_cmu_imem_dmaclk";
+			status = "disabled";
+		};
+
+		clock_peric: clock-controller at 14010000 {
+			compatible = "tesla,fsd-clock-peric";
+			reg = <0x0 0x14010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div4",
+				"dout_cmu_peric_shared1div36",
+				"dout_cmu_peric_shared0div3_tbuclk",
+				"dout_cmu_peric_shared0div20",
+				"dout_cmu_peric_shared1div4_dmaclk";
+			status = "disabled";
+		};
+
+		clock_fsys0: clock-controller at 15010000 {
+			compatible = "tesla,fsd-clock-fsys0";
+			reg = <0x0 0x15010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div6",
+				"dout_cmu_fsys0_shared1div4",
+				"dout_cmu_fsys0_shared0div4";
+			status = "disabled";
+		};
+
+		clock_fsys1: clock-controller at 16810000 {
+			compatible = "tesla,fsd-clock-fsys1";
+			reg = <0x0 0x16810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_fsys1_shared0div8",
+				"dout_cmu_fsys1_shared0div4";
+			status = "disabled";
+		};
+
+		clock_mfc: clock-controller at 12810000 {
+			compatible = "tesla,fsd-clock-mfc";
+			reg = <0x0 0x12810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+			status = "disabled";
+		};
+
+		clock_csi: clock-controller at 12610000 {
+			compatible = "tesla,fsd-clock-cam_csi";
+			reg = <0x0 0x12610000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+			status = "disabled";
+		};
+
+		mdma0: mdma at 10100000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10100000 0x0 0x1000>;
+			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x800 0x0>;
+			status = "disabled";
+		};
+
+		mdma1: mdma at 10110000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10110000 0x0 0x1000>;
+			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x801 0x0>;
+			status = "disabled";
+		};
+
+		pdma0: pdma at 14280000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x2 0x0>;
+			status = "disabled";
+		};
+
+		pdma1: pdma at 14290000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x1 0x0>;
+			status = "disabled";
+		};
+
+		mct: mct at 10040000 {
+			compatible = "samsung,exynos4210-mct";
+			reg = <0x0 0x10040000 0x0 0x800>;
+			interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>;
+			clock-names = "fin_pll", "mct";
+		};
+
+		serial_0: serial at 14180000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14180000 0x0 0x100>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 0>, <&pdma1 1>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART0>,
+				 <&clock_peric PERIC_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		serial_1: serial at 14190000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14190000 0x0 0x100>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 2>, <&pdma1 3>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART1>,
+				 <&clock_peric PERIC_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller at 11400000 {
+			compatible = "samsung,exynos7-pmu", "syscon";
+			reg = <0x0 0x11400000 0x0 0x5000>;
+		};
+
+		watchdog_0: watchdog at 100A0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100A0000 0x0 0x100>;
+			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+			interrupt-mode = <1>;
+		};
+
+		watchdog_1: watchdog at 100B0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100B0000 0x0 0x100>;
+			interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+			interrupt-mode = <1>;
+		};
+
+		watchdog_2: watchdog at 100C0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100C0000 0x0 0x100>;
+			interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+			interrupt-mode = <1>;
+		};
+
+		pwm_0: pwm at 14100000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14100000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		pwm_1: pwm at 14110000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14110000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		hsi2c_0: hsi2c at 14200000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14200000 0x0 0x1000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: hsi2c at 14210000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14210000 0x0 0x1000>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: hsi2c at 14220000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14220000 0x0 0x1000>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: hsi2c at 14230000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14230000 0x0 0x1000>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: hsi2c at 14240000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14240000 0x0 0x1000>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: hsi2c at 14250000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14250000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: hsi2c at 14260000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: hsi2c at 14270000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+	};
+};
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:35 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:35 +0530
Subject: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122417epcas5p47398a5190cdf4c574c6f1762918b549f@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-16-alim.akhtar@samsung.com>

Add initial pin configuration nodes for FSD SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 338 +++++++++++++++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
 2 files changed, 360 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi

diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..ec8d944af636
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf6: gpf6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric {
+
+	gpc8: gpc8 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb4: gpb4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb5: gpb5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb6: gpb6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb7: gpb7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd3: gpd3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg4: gpg4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg5: gpg5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg6: gpg6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg7: gpg7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	pwm0_out: pwm0-out {
+		samsung,pins = "gpb6-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	pwm1_out: pwm1-out {
+		samsung,pins = "gpb6-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	hs_i2c0_bus: hs-i2c0-bus {
+		samsung,pins = "gpb0-0", "gpb0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus {
+		samsung,pins = "gpb0-2", "gpb0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus {
+		samsung,pins = "gpb0-4", "gpb0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus {
+		samsung,pins = "gpb0-6", "gpb0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus {
+		samsung,pins = "gpb1-0", "gpb1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus {
+		samsung,pins = "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus {
+		samsung,pins = "gpb1-4", "gpb1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus {
+		samsung,pins = "gpb1-6", "gpb1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_data: uart0-data {
+		samsung,pins = "gpb7-0", "gpb7-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data {
+		samsung,pins = "gpb7-4", "gpb7-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_pmu {
+
+	gpq0: gpq0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 47cd9f20566e..811186e5ba4d 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -29,6 +29,9 @@
 		hsi2c5 = &hsi2c_5;
 		hsi2c6 = &hsi2c_6;
 		hsi2c7 = &hsi2c_7;
+		pinctrl0 = &pinctrl_fsys0;
+		pinctrl1 = &pinctrl_peric;
+		pinctrl2 = &pinctrl_pmu;
 	};
 
 	cpus {
@@ -711,5 +714,24 @@
 			clock-names = "hsi2c";
 			status = "disabled";
 		};
+
+		pinctrl_fsys0: pinctrl at 15020000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x15020000 0x0 0x1000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_peric: pinctrl at 141F0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x141F0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_pmu: pinctrl at 114F0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x114F0000 0x0 0x1000>;
+		};
 	};
 };
+
+#include "fsd-pinctrl.dtsi"
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:36 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:36 +0530
Subject: [PATCH 16/23] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122421epcas5p1af8422fc992801ced57e0439b48ad08e@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-17-alim.akhtar@samsung.com>

This patch enables the Tesla FSD SoC in arm64 defconfig.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f2e2b9bdd702..6e6f26eb54ab 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -54,6 +54,7 @@ CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_INTEL_SOCFPGA=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:37 +0530
Subject: [PATCH 17/23] Documentation: bindings: Add fsd spi compatible in
 dt-bindings document
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122427epcas5p1885d8b3b735e8f127b6694a309796e5a@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-18-alim.akhtar@samsung.com>

This patch adds spi controller dt-binding compatible information for
Tesla Full Self-Driving SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Adithya K V <adithya.kv at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/spi/spi-samsung.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
index 49028a4f5df1..3af2408454b4 100644
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
@@ -11,6 +11,7 @@ Required SoC Specific Properties:
     - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
     - samsung,exynos5433-spi: for exynos5433 compatible controllers
     - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
+    - tesla,fsd-spi: spi controller support for Tesla Full Self-Driving SoC
 
 - reg: physical base address of the controller and length of memory mapped
   region.
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:38 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:38 +0530
Subject: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122435epcas5p18e6a2699f193b9e1287588278a570235@epcas5p1.samsung.com>
Message-ID: <20220113121143.22280-19-alim.akhtar@samsung.com>

This patch adds compatible and port configuration for
spi controller for Tesla Full Self-Driving SoC.

Cc: linux-fsd at tesla.com
Cc: broonie at kernel.org
Cc: linux-spi at vger.kernel.org
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/spi/spi-s3c64xx.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..8d0c1f03ab7a 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1442,6 +1442,16 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
+static struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.clk_ioclk	= false,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1472,6 +1482,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,exynos5433-spi",
 			.data = (void *)&exynos5433_spi_port_config,
 	},
+	{ .compatible = "tesla,fsd-spi",
+			.data = (void *)&fsd_spi_port_config,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:39 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:39 +0530
Subject: [PATCH 19/23] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122440epcas5p4651d7cb2fc6d6a70fd5eaab5eadcf996@epcas5p4.samsung.com>
Message-ID: <20220113121143.22280-20-alim.akhtar@samsung.com>

From: Aswani Reddy <aswani.reddy at samsung.com>

This patch add device tree node for SPI IPs and needed
GPIO pin configurations needed for SPI IP

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dts  | 12 +++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi | 57 ++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
index e9bbd3284de9..7f3bb6212e50 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dts
+++ b/arch/arm64/boot/dts/tesla/fsd.dts
@@ -138,3 +138,15 @@
 &pdma1 {
 	status = "okay";
 };
+
+&spi_0 {
+	status = "okay";
+};
+
+&spi_1 {
+	status = "okay";
+};
+
+&spi_2 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 811186e5ba4d..7e687c6f74f6 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -32,6 +32,9 @@
 		pinctrl0 = &pinctrl_fsys0;
 		pinctrl1 = &pinctrl_peric;
 		pinctrl2 = &pinctrl_pmu;
+		spi0 = &spi_0;
+		spi1 = &spi_1;
+		spi2 = &spi_2;
 	};
 
 	cpus {
@@ -731,6 +734,60 @@
 			compatible = "tesla,fsd-pinctrl";
 			reg = <0x0 0x114F0000 0x0 0x1000>;
 		};
+
+		spi_0: spi at 14140000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14140000 0x0 0x100>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 4>, <&pdma1 5>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI0>,
+				<&clock_peric PERIC_SCLK_SPI0>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_1: spi at 14150000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14150000 0x0 0x100>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 6>, <&pdma1 7>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI1>,
+				<&clock_peric PERIC_SCLK_SPI1>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_2: spi at 14160000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14160000 0x0 0x100>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 8>, <&pdma1 9>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI2>,
+				<&clock_peric PERIC_SCLK_SPI2>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi2_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
 	};
 };
 
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:40 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:40 +0530
Subject: [PATCH 20/23] dt-bindings: iio: adc: exynos-adc: Add ADC-V3 variant
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122447epcas5p266d44c8df143229d22dfa700c285a786@epcas5p2.samsung.com>
Message-ID: <20220113121143.22280-21-alim.akhtar@samsung.com>

This patch adds a new compatible string for exynos's ADC-V3 variant.

Cc: linux-fsd at tesla.com
Signed-off-by: Tamseel Shams <m.shams at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/iio/adc/samsung,exynos-adc.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
index 81c87295912c..9303053759ca 100644
--- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
@@ -14,6 +14,7 @@ properties:
     enum:
       - samsung,exynos-adc-v1                 # Exynos5250
       - samsung,exynos-adc-v2
+      - samsung,exynos-adc-v3
       - samsung,exynos3250-adc
       - samsung,exynos4212-adc                # Exynos4212 and Exynos4412
       - samsung,exynos7-adc
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:41 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:41 +0530
Subject: [PATCH 21/23] iio: adc: exynos-adc: Add support for ADC V3 controller
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122452epcas5p201a3a87d0e9c0e9f449a90ed62de1f1c@epcas5p2.samsung.com>
Message-ID: <20220113121143.22280-22-alim.akhtar@samsung.com>

Exynos's ADC-V3 has some difference in registers set, number of
programmable channels (16 channel) etc. This patch adds support for ADC-V3
controller version.

Cc: linux-fsd at tesla.com
Cc: jic23 at kernel.org
Cc: linux-iio at vger.kernel.org
Signed-off-by: Tamseel Shams <m.shams at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/iio/adc/exynos_adc.c | 74 +++++++++++++++++++++++++++++++++++-
 1 file changed, 72 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
index 3b3868aa2533..61752e798fd6 100644
--- a/drivers/iio/adc/exynos_adc.c
+++ b/drivers/iio/adc/exynos_adc.c
@@ -55,6 +55,11 @@
 #define ADC_V2_INT_ST(x)	((x) + 0x14)
 #define ADC_V2_VER(x)		((x) + 0x20)
 
+/* ADC_V3 register definitions */
+#define ADC_V3_DAT(x)			((x) + 0x08)
+#define ADC_V3_DAT_SUM(x)		((x) + 0x0C)
+#define ADC_V3_DBG_DATA(x)		((x) + 0x1C)
+
 /* Bit definitions for ADC_V1 */
 #define ADC_V1_CON_RES		(1u << 16)
 #define ADC_V1_CON_PRSCEN	(1u << 14)
@@ -92,6 +97,7 @@
 
 /* Bit definitions for ADC_V2 */
 #define ADC_V2_CON1_SOFT_RESET	(1u << 2)
+#define ADC_V2_CON1_SOFT_NON_RESET	(1u << 1)
 
 #define ADC_V2_CON2_OSEL	(1u << 10)
 #define ADC_V2_CON2_ESEL	(1u << 9)
@@ -100,6 +106,7 @@
 #define ADC_V2_CON2_ACH_SEL(x)	(((x) & 0xF) << 0)
 #define ADC_V2_CON2_ACH_MASK	0xF
 
+#define MAX_ADC_V3_CHANNELS		16
 #define MAX_ADC_V2_CHANNELS		10
 #define MAX_ADC_V1_CHANNELS		8
 #define MAX_EXYNOS3250_ADC_CHANNELS	2
@@ -164,6 +171,7 @@ struct exynos_adc_data {
 	void (*exit_hw)(struct exynos_adc *info);
 	void (*clear_irq)(struct exynos_adc *info);
 	void (*start_conv)(struct exynos_adc *info, unsigned long addr);
+	irqreturn_t (*adc_isr)(int irq, void *dev_id);
 };
 
 static void exynos_adc_unprepare_clk(struct exynos_adc *info)
@@ -484,6 +492,59 @@ static const struct exynos_adc_data exynos7_adc_data = {
 	.start_conv	= exynos_adc_v2_start_conv,
 };
 
+static void exynos_adc_v3_init_hw(struct exynos_adc *info)
+{
+	u32 con2;
+
+	writel(ADC_V2_CON1_SOFT_RESET, ADC_V2_CON1(info->regs));
+
+	writel(ADC_V2_CON1_SOFT_NON_RESET, ADC_V2_CON1(info->regs));
+
+	con2 = ADC_V2_CON2_C_TIME(6);
+	writel(con2, ADC_V2_CON2(info->regs));
+
+	/* Enable interrupts */
+	writel(1, ADC_V2_INT_EN(info->regs));
+}
+
+static void exynos_adc_v3_exit_hw(struct exynos_adc *info)
+{
+	u32 con2;
+
+	con2 = readl(ADC_V2_CON2(info->regs));
+	con2 &= ~ADC_V2_CON2_C_TIME(7);
+	writel(con2, ADC_V2_CON2(info->regs));
+
+	/* Disable interrupts */
+	writel(0, ADC_V2_INT_EN(info->regs));
+}
+
+static irqreturn_t exynos_adc_v3_isr(int irq, void *dev_id)
+{
+	struct exynos_adc *info = (struct exynos_adc *)dev_id;
+	u32 mask = info->data->mask;
+
+	info->value = readl(ADC_V3_DAT(info->regs)) & mask;
+
+	if (info->data->clear_irq)
+		info->data->clear_irq(info);
+
+	complete(&info->completion);
+
+	return IRQ_HANDLED;
+}
+
+static const struct exynos_adc_data exynos_adc_v3_adc_data = {
+	.num_channels	= MAX_ADC_V3_CHANNELS,
+	.mask		= ADC_DATX_MASK, /* 12 bit ADC resolution */
+
+	.init_hw	= exynos_adc_v3_init_hw,
+	.exit_hw	= exynos_adc_v3_exit_hw,
+	.clear_irq	= exynos_adc_v2_clear_irq,
+	.start_conv	= exynos_adc_v2_start_conv,
+	.adc_isr	= exynos_adc_v3_isr,
+};
+
 static const struct of_device_id exynos_adc_match[] = {
 	{
 		.compatible = "samsung,s3c2410-adc",
@@ -518,6 +579,9 @@ static const struct of_device_id exynos_adc_match[] = {
 	}, {
 		.compatible = "samsung,exynos7-adc",
 		.data = &exynos7_adc_data,
+	}, {
+		.compatible = "samsung,exynos-adc-v3",
+		.data = &exynos_adc_v3_adc_data,
 	},
 	{},
 };
@@ -719,6 +783,12 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = {
 	ADC_CHANNEL(7, "adc7"),
 	ADC_CHANNEL(8, "adc8"),
 	ADC_CHANNEL(9, "adc9"),
+	ADC_CHANNEL(10, "adc10"),
+	ADC_CHANNEL(11, "adc11"),
+	ADC_CHANNEL(12, "adc12"),
+	ADC_CHANNEL(13, "adc13"),
+	ADC_CHANNEL(14, "adc14"),
+	ADC_CHANNEL(15, "adc15"),
 };
 
 static int exynos_adc_remove_devices(struct device *dev, void *c)
@@ -885,8 +955,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
 
 	mutex_init(&info->lock);
 
-	ret = request_irq(info->irq, exynos_adc_isr,
-					0, dev_name(&pdev->dev), info);
+	ret = request_irq(info->irq, info->data->adc_isr ? info->data->adc_isr :
+				exynos_adc_isr, 0, dev_name(&pdev->dev), info);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
 							info->irq);
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:42 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:42 +0530
Subject: [PATCH 22/23] arm64: dts: fsd: Add ADC device tree node
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122456epcas5p35f6406ab03af58d2e56b0b7304d4d002@epcas5p3.samsung.com>
Message-ID: <20220113121143.22280-23-alim.akhtar@samsung.com>

This patch adds ADC device tree node and enables the same
on fsd platform.

Cc: linux-fsd at tesla.com
Signed-off-by: Tamseel Shams <m.shams at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dts  |  4 ++++
 arch/arm64/boot/dts/tesla/fsd.dtsi | 11 +++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
index 7f3bb6212e50..dd6c75fc3221 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dts
+++ b/arch/arm64/boot/dts/tesla/fsd.dts
@@ -150,3 +150,7 @@
 &spi_2 {
 	status = "okay";
 };
+
+&adc {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 7e687c6f74f6..058a9d381aed 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -788,6 +788,17 @@
 			num-cs = <1>;
 			status = "disabled";
 		};
+
+		adc: adc at 141A0000 {
+			compatible = "samsung,exynos-adc-v3";
+			reg = <0x0 0x141A0000 0x0 0x100>;
+			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clock_peric PERIC_PCLK_ADCIF>;
+			clock-names = "adc";
+			#io-channel-cells = <1>;
+			io-channel-ranges;
+			status = "disabled";
+		};
 	};
 };
 
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 04:11:43 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 13 Jan 2022 17:41:43 +0530
Subject: [PATCH 23/23] clocksource: exynos_mct: Add support for handling
 three clusters
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122502epcas5p37747b0c5c242c0571d294b9245963a1c@epcas5p3.samsung.com>
Message-ID: <20220113121143.22280-24-alim.akhtar@samsung.com>

From: Aswani Reddy <aswani.reddy at samsung.com>

This patch adds support for handling thress clusters
(upto 12 CPUs)

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clocksource/exynos_mct.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
index 5e3e96d3d1b9..ba3af940a687 100644
--- a/drivers/clocksource/exynos_mct.c
+++ b/drivers/clocksource/exynos_mct.c
@@ -78,6 +78,10 @@ enum {
 	MCT_L5_IRQ,
 	MCT_L6_IRQ,
 	MCT_L7_IRQ,
+	MCT_L8_IRQ,
+	MCT_L9_IRQ,
+	MCT_L10_IRQ,
+	MCT_L11_IRQ,
 	MCT_NR_IRQS,
 };
 
@@ -89,7 +93,7 @@ static int mct_irqs[MCT_NR_IRQS];
 struct mct_clock_event_device {
 	struct clock_event_device evt;
 	unsigned long base;
-	char name[10];
+	char name[11];
 };
 
 static void exynos4_mct_write(unsigned int value, unsigned long offset)
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:27:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:27:28 +0100
Subject: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220113121143.22280-11-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122354epcas5p19e5cebe9e85e9ba1758fa0b9d7d1ef75@epcas5p1.samsung.com>
 <20220113121143.22280-11-alim.akhtar@samsung.com>
Message-ID: <849c7772-0f7e-32ff-6ea6-c46aa6837bb4@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add compatible for Tesla Full Self-Driving SoC. The
> pinctrl hardware IP is similar to what found on most of the
> exynos series of SoC, so this new compatible is added in
> samsung pinctrl binding.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> index b8b475967ff9..ba972998a0e4 100644
> --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
> @@ -24,6 +24,7 @@ Required Properties:
>    - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
>    - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
>    - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
> +  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
>  

Please rebase this on my latest Samsung pinctrl dtschema patches. You
also need a tesla vendor prefix patch (separate).


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:31:57 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:31:57 +0100
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
Message-ID: <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch set adds basic support for the Tesla Full Self-Driving (FSD)
> SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> as well as several IPs.
> 
> Patches 1 to 8 provide support for the clock controller
> (which is designed similarly to Exynos SoCs).
> 
> The remaining changes provide pinmux support, initial device tree support,
> and SPI, ADC, and MCT IP functionality.

Does FSD have some version number? The FDS, especially in compatibles,
looks quite generic, so what will happen if a newer SoC comes later? You
would have:
 - tesla,fsd-pinctrl
 - tesla,fsd-xxxx-pinctrl (where xxxx could be some new version)

This will be extra confusing, because fsd-pinctrl looks like the generic
one, while it is specific...

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:33:22 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:33:22 +0100
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220113121143.22280-14-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
Message-ID: <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add device tree bindings for the Tesla FSD ARM SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../devicetree/bindings/arm/tesla.yaml        | 25 +++++++++++++++++++
>  1 file changed, 25 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
> new file mode 100644
> index 000000000000..9f89cde76c85
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/tesla.yaml
> @@ -0,0 +1,25 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/arm/tesla.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tesla Full Self Driving(FSD) platforms device tree bindings
> +
> +maintainers:
> +  - Alim Akhtar <alim.akhtar at samsung.com>
> +  - linux-fsd at tesla.com
> +
> +properties:
> +  $nodename:
> +    const: '/'
> +  compatible:
> +    oneOf:
> +
> +      - description: FSD SoC board
> +        items:
> +          - const: tesla,fsd

Either this is a SoC or a board compatible... Cannot be both.

> +
> +additionalProperties: true
> +
> +...
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:40:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:40:36 +0100
Subject: [PATCH 01/23] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220113121143.22280-2-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122311epcas5p4b7c253b49dce3bd3580407fcf312e70e@epcas5p4.samsung.com>
 <20220113121143.22280-2-alim.akhtar@samsung.com>
Message-ID: <c87f500e-e43e-465c-94fa-050c2b0de083@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add dt-schema documentation for Tesla FSD SoC clock controller.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../bindings/clock/tesla,fsd-clock.yaml       | 212 ++++++++++++++++++
>  1 file changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> new file mode 100644
> index 000000000000..58f341e5004d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> @@ -0,0 +1,212 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tesla FSD (Full Self-Driving) SoC clock controller
> +
> +maintainers:
> +  - Alim Akhtar <alim.akhtar at samsung.com>
> +  - linux-fsd at tesla.com
> +
> +description: |
> +  FSD clock controller consist of several clock management unit
> +  (CMU), which generates clocks for various inteernal SoC blocks.
> +  The root clock comes from external OSC clock (24 MHz).
> +
> +  All available clocks are defined as preprocessor macros in
> +  'dt-bindings/clock/fsd-clk.h' header.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - tesla,fsd-clock-cmu
> +      - tesla,fsd-clock-imem
> +      - tesla,fsd-clock-peric
> +      - tesla,fsd-clock-fsys0
> +      - tesla,fsd-clock-fsys1
> +      - tesla,fsd-clock-mfc
> +      - tesla,fsd-clock-cam_csi
> +
> +  clocks:
> +    minItems: 1
> +    maxItems: 6
> +
> +  clock-names:
> +    minItems: 1
> +    maxItems: 6
> +
> +  "#clock-cells":
> +    const: 1
> +
> +  reg:
> +    maxItems: 1
> +
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            const: tesla,fsd-clock-cmu
> +

Nitpick: Drop the white-spaces between if-then. It's easier to spot the
if-blocks if they are together.

> +    then:
> +      properties:
> +        clocks:
> +          items:
> +            - description: External reference clock (24 MHz)
> +

Drop this whitespace as well.

Rest looks good to me, except the discussion about the compatible.


Best regards,
Krzysztof


From guangming.cao at mediatek.com  Thu Jan 13 04:34:06 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 13 Jan 2022 20:34:06 +0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
Message-ID: <20220113123406.11520-1-guangming.cao@mediatek.com>

From: Guangming <Guangming.Cao at mediatek.com>

Add a size check for allocation since the allocation size is
always less than the total DRAM size.

Without this check, once the invalid size allocation runs on a process that
can't be killed by OOM flow(such as "gralloc" on Android devices), it will
cause a kernel exception, and to make matters worse, we can't find who are using
so many memory with "dma_buf_debug_show" since the relevant dma-buf hasn't exported.

To make OOM issue easier, maybe need dma-buf framework to dump the buffer size
under allocating in "dma_buf_debug_show".

Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
---
v3: 1. update patch, use right shift to replace division.
    2. update patch, add reason in code and commit message.
v2: 1. update size limitation as total_dram page size.
    2. update commit message
---
 drivers/dma-buf/dma-heap.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
index 56bf5ad01ad5..1fd382712584 100644
--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -55,6 +55,16 @@ static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
 	struct dma_buf *dmabuf;
 	int fd;
 
+	/*
+	 * Invalid size check. The "len" should be less than totalram.
+	 *
+	 * Without this check, once the invalid size allocation runs on a process that
+	 * can't be killed by OOM flow(such as "gralloc" on Android devices), it will
+	 * cause a kernel exception, and to make matters worse, we can't find who are using
+	 * so many memory with "dma_buf_debug_show" since the relevant dma-buf hasn't exported.
+	 */
+	if (len >> PAGE_SHIFT > totalram_pages())
+		return -EINVAL;
 	/*
 	 * Allocations from all heaps have to begin
 	 * and end on page boundaries.
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:49:57 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:49:57 +0100
Subject: [PATCH 03/23] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220113121143.22280-4-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122324epcas5p105c53b448b5801813a02a88c6107a2f3@epcas5p1.samsung.com>
 <20220113121143.22280-4-alim.akhtar@samsung.com>
Message-ID: <b9fac286-9227-b26b-221b-7f54b63e6b0b@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add initial clock support for FSD (Full Self-Driving) SoC
> which is required to bring-up platforms based on this SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/Makefile  |   1 +
>  drivers/clk/samsung/clk-fsd.c | 308 ++++++++++++++++++++++++++++++++++
>  drivers/clk/samsung/clk-pll.c |   1 +
>  drivers/clk/samsung/clk-pll.h |   1 +
>  4 files changed, 311 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-fsd.c
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index c46cf11e4d0b..d66b2ede004c 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -18,6 +18,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
>  obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
> +obj-$(CONFIG_ARCH_TESLA_FSD)         += clk-fsd.o

It should be rather it's own CONFIG_TESLA_FSD_CLK option, just like
other Exynos designs. This keeps unified approach with existing Samsung
clock Kconfig.

>  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
> diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
> new file mode 100644
> index 000000000000..e47523106d9e
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-fsd.c
> @@ -0,0 +1,308 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Common Clock Framework support for FSD SoC.
> + *
> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> + *             https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *             https://www.tesla.com
> + *

Drop the line break with empty * comment.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +
> +#include "clk.h"
> +#include <dt-bindings/clock/fsd-clk.h>

dt-bindings headers before local clk.h.

> +
> +/* Register Offset definitions for CMU_CMU (0x11c10000) */



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:55:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:55:03 +0100
Subject: [PATCH 04/23] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220113121143.22280-5-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122330epcas5p46ae5cd30950b1d9126479231dcf5da49@epcas5p4.samsung.com>
 <20220113121143.22280-5-alim.akhtar@samsung.com>
Message-ID: <1b246ad6-5b65-a02f-e887-5a07e8f12ec7@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds CMU_PERIC block clock information needed
> for various IPs functions found in this block.

Here and in all other commits, please do not use "This patch". Instead:
https://elixir.bootlin.com/linux/v5.13/source/Documentation/process/submitting-patches.rst#L89

> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 464 +++++++++++++++++++++++++++++++++-
>  1 file changed, 463 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
> index e47523106d9e..6da20966ba99 100644
> --- a/drivers/clk/samsung/clk-fsd.c
> +++ b/drivers/clk/samsung/clk-fsd.c
> @@ -9,12 +9,59 @@
>   *
>   */
>  
> -#include <linux/clk-provider.h>
>  #include <linux/of.h>
> +#include <linux/clk.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/clk-provider.h>
> +#include <linux/platform_device.h>

Please order the includes alphabetically.

>  
>  #include "clk.h"
>  #include <dt-bindings/clock/fsd-clk.h>
>  
> +/* Gate register bits */
> +#define GATE_MANUAL		BIT(20)
> +#define GATE_ENABLE_HWACG	BIT(28)
> +
> +/* Gate register offsets range */
> +#define GATE_OFF_START		0x2000
> +#define GATE_OFF_END		0x2fff
> +
> +/**
> + * fsd_init_clocks - Set clocks initial configuration
> + * @np:			CMU device tree node with "reg" property (CMU addr)
> + * @reg_offs:		Register offsets array for clocks to init
> + * @reg_offs_len:	Number of register offsets in reg_offs array
> + *
> + * Set manual control mode for all gate clocks.
> + */
> +static void __init fsd_init_clocks(struct device_node *np,
> +		const unsigned long *reg_offs, size_t reg_offs_len)

The same as exynos_arm64_init_clocks - please re-use instead of duplicating.

> +{
> +	void __iomem *reg_base;
> +	size_t i;
> +
> +	reg_base = of_iomap(np, 0);
> +	if (!reg_base)
> +		panic("%s: failed to map registers\n", __func__);
> +
> +	for (i = 0; i < reg_offs_len; ++i) {
> +		void __iomem *reg = reg_base + reg_offs[i];
> +		u32 val;
> +
> +		/* Modify only gate clock registers */
> +		if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
> +			continue;
> +
> +		val = readl(reg);
> +		val |= GATE_MANUAL;
> +		val &= ~GATE_ENABLE_HWACG;
> +		writel(val, reg);
> +	}
> +
> +	iounmap(reg_base);
> +}
> +

(...)

> +/**
> + * fsd_cmu_probe - Probe function for FSD platform clocks
> + * @pdev: Pointer to platform device
> + *
> + * Configure clock hierarchy for clock domains of FSD platform
> + */
> +static int __init fsd_cmu_probe(struct platform_device *pdev)
> +{
> +	const struct samsung_cmu_info *info;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +
> +	info = of_device_get_match_data(dev);
> +	fsd_init_clocks(np, info->clk_regs, info->nr_clk_regs);
> +	samsung_cmu_register_one(np, info);
> +
> +	/* Keep bus clock running, so it's possible to access CMU registers */
> +	if (info->clk_name) {
> +		struct clk *bus_clk;
> +
> +		bus_clk = clk_get(dev, info->clk_name);
> +		if (IS_ERR(bus_clk)) {
> +			pr_err("%s: could not find bus clock %s; err = %ld\n",
> +			       __func__, info->clk_name, PTR_ERR(bus_clk));
> +		} else {
> +			clk_prepare_enable(bus_clk);
> +		}
> +	}
> +
> +	return 0;
> +}

Please re-use exynos_arm64_register_cmu(). This will also solve my
previous comment about exynos_arm64_init_clocks().

> +
> +/* CMUs which belong to Power Domains and need runtime PM to be implemented */
> +static const struct of_device_id fsd_cmu_of_match[] = {
> +	{
> +		.compatible = "tesla,fsd-clock-peric",
> +		.data = &peric_cmu_info,
> +	}, {
> +	},
> +};
> +
> +static struct platform_driver fsd_cmu_driver __refdata = {
> +	.driver	= {
> +		.name = "fsd-cmu",
> +		.of_match_table = fsd_cmu_of_match,
> +		.suppress_bind_attrs = true,
> +	},
> +	.probe = fsd_cmu_probe,
> +};
> +
> +static int __init fsd_cmu_init(void)
> +{
> +	return platform_driver_register(&fsd_cmu_driver);
> +}
> +core_initcall(fsd_cmu_init);
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:57:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:57:42 +0100
Subject: [PATCH 11/23] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220113121143.22280-12-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122400epcas5p34363ba8f477b4c273d601d0b64324afa@epcas5p3.samsung.com>
 <20220113121143.22280-12-alim.akhtar@samsung.com>
Message-ID: <4b8cc931-1d87-dd8b-133e-106dd987e0b0@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds Tesla FSD SoC specific data to enable pinctrl.
> FSD SoC has similar pinctrl controller as found in the most
> samsung/exynos SoCs.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
>  drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
>  drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
>  3 files changed, 74 insertions(+)
> 
> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> index 6b77fd24571e..b9175b4911ac 100644
> --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
> @@ -646,3 +646,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
>  	.ctrl		= exynosautov9_pin_ctrl,
>  	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
>  };
> +
> +/*
> + * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
> + * gpio/pin-mux/pinconfig controllers.
> + */
> +
> +/* pin banks of FSD pin-controller 0 (FSYS) */
> +static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
> +	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
> +	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
> +	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
> +	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
> +};
> +
> +/* pin banks of FSD pin-controller 1 (PERIC) */
> +static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
> +	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
> +	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
> +	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
> +	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
> +	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
> +	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
> +	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
> +};
> +
> +/* pin banks of FSD pin-controller 2 (PMU) */
> +static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
> +	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
> +};
> +
> +const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
> +	{
> +		/* pin-controller instance 0 FSYS0 data */
> +		.pin_banks	= fsd_pin_banks0,
> +		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),

No wake-up interrupts (eint_wkup_init)? It's fine not to have them but
just looks incomplete.

In general looks ok, except discussion about compatibles.

> +		.eint_gpio_init = exynos_eint_gpio_init,
> +		.suspend	= exynos_pinctrl_suspend,
> +		.resume		= exynos_pinctrl_resume,
Best regards,
Krzysztof


From michael.j.ruhl at intel.com  Thu Jan 13 04:57:51 2022
From: michael.j.ruhl at intel.com (Ruhl, Michael J)
Date: Thu, 13 Jan 2022 12:57:51 +0000
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <20220113123406.11520-1-guangming.cao@mediatek.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
Message-ID: <4f88205c1b344aea8608960e2f85b8f4@intel.com>


>-----Original Message-----
>From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>guangming.cao at mediatek.com
>Sent: Thursday, January 13, 2022 7:34 AM
>To: sumit.semwal at linaro.org
>Cc: linux-arm-kernel at lists.infradead.org; mingyuan.ma at mediatek.com;
>Guangming <Guangming.Cao at mediatek.com>;
>wsd_upstream at mediatek.com; linux-kernel at vger.kernel.org; dri-
>devel at lists.freedesktop.org; linaro-mm-sig at lists.linaro.org;
>yf.wang at mediatek.com; libo.kang at mediatek.com;
>benjamin.gaignard at linaro.org; bo.song at mediatek.com;
>matthias.bgg at gmail.com; linux-mediatek at lists.infradead.org;
>lmark at codeaurora.org; labbott at redhat.com; christian.koenig at amd.com;
>jianjiao.zeng at mediatek.com; linux-media at vger.kernel.org
>Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
>
>From: Guangming <Guangming.Cao at mediatek.com>
>
>Add a size check for allocation since the allocation size is
>always less than the total DRAM size.
>
>Without this check, once the invalid size allocation runs on a process that
>can't be killed by OOM flow(such as "gralloc" on Android devices), it will
>cause a kernel exception, and to make matters worse, we can't find who are
>using
>so many memory with "dma_buf_debug_show" since the relevant dma-buf
>hasn't exported.
>
>To make OOM issue easier, maybe need dma-buf framework to dump the
>buffer size
>under allocating in "dma_buf_debug_show".
>
>Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
>Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
>---
>v3: 1. update patch, use right shift to replace division.
>    2. update patch, add reason in code and commit message.
>v2: 1. update size limitation as total_dram page size.
>    2. update commit message
>---
> drivers/dma-buf/dma-heap.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
>diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
>index 56bf5ad01ad5..1fd382712584 100644
>--- a/drivers/dma-buf/dma-heap.c
>+++ b/drivers/dma-buf/dma-heap.c
>@@ -55,6 +55,16 @@ static int dma_heap_buffer_alloc(struct dma_heap
>*heap, size_t len,
> 	struct dma_buf *dmabuf;
> 	int fd;
>
>+	/*
>+	 * Invalid size check. The "len" should be less than totalram.
>+	 *
>+	 * Without this check, once the invalid size allocation runs on a process
>that
>+	 * can't be killed by OOM flow(such as "gralloc" on Android devices), it
>will
>+	 * cause a kernel exception, and to make matters worse, we can't find
>who are using
>+	 * so many memory with "dma_buf_debug_show" since the relevant
>dma-buf hasn't exported.
>+	 */
>+	if (len >> PAGE_SHIFT > totalram_pages())

If your "heap" is from cma, is this still a valid check?

M

>+		return -EINVAL;
> 	/*
> 	 * Allocations from all heaps have to begin
> 	 * and end on page boundaries.
>--
>2.17.1



From krzysztof.kozlowski at canonical.com  Thu Jan 13 04:58:12 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 13:58:12 +0100
Subject: [PATCH 12/23] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220113121143.22280-13-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122404epcas5p4aa1c3ac09510eb55cce5fdd0791993a6@epcas5p4.samsung.com>
 <20220113121143.22280-13-alim.akhtar@samsung.com>
Message-ID: <176af0b0-a324-da39-2848-1c2e01cfadf5@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add vendor prefix for the Tesla (https://www.tesla.com)
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(

This should be the first patch in the series.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From broonie at kernel.org  Thu Jan 13 04:59:14 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 13 Jan 2022 12:59:14 +0000
Subject: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220113121143.22280-19-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122435epcas5p18e6a2699f193b9e1287588278a570235@epcas5p1.samsung.com>
 <20220113121143.22280-19-alim.akhtar@samsung.com>
Message-ID: <YeAiIhfN216pRWhn@sirena.org.uk>

On Thu, Jan 13, 2022 at 05:41:38PM +0530, Alim Akhtar wrote:

> +	{ .compatible = "tesla,fsd-spi",
> +			.data = (void *)&fsd_spi_port_config,
> +	},

This needs a DT bindings update to match.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220113/62584748/attachment.sig>

From michael.j.ruhl at intel.com  Thu Jan 13 05:00:46 2022
From: michael.j.ruhl at intel.com (Ruhl, Michael J)
Date: Thu, 13 Jan 2022 13:00:46 +0000
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <4f88205c1b344aea8608960e2f85b8f4@intel.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
Message-ID: <e657f5257cbf4955817b0bbf037de9f9@intel.com>


>-----Original Message-----
>From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>Ruhl, Michael J
>Sent: Thursday, January 13, 2022 7:58 AM
>To: guangming.cao at mediatek.com; sumit.semwal at linaro.org
>Cc: jianjiao.zeng at mediatek.com; lmark at codeaurora.org;
>wsd_upstream at mediatek.com; christian.koenig at amd.com; linux-
>kernel at vger.kernel.org; dri-devel at lists.freedesktop.org;
>yf.wang at mediatek.com; linaro-mm-sig at lists.linaro.org; linux-
>mediatek at lists.infradead.org; libo.kang at mediatek.com;
>benjamin.gaignard at linaro.org; bo.song at mediatek.com;
>matthias.bgg at gmail.com; labbott at redhat.com;
>mingyuan.ma at mediatek.com; linux-arm-kernel at lists.infradead.org; linux-
>media at vger.kernel.org
>Subject: RE: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
>
>
>>-----Original Message-----
>>From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>>guangming.cao at mediatek.com
>>Sent: Thursday, January 13, 2022 7:34 AM
>>To: sumit.semwal at linaro.org
>>Cc: linux-arm-kernel at lists.infradead.org; mingyuan.ma at mediatek.com;
>>Guangming <Guangming.Cao at mediatek.com>;
>>wsd_upstream at mediatek.com; linux-kernel at vger.kernel.org; dri-
>>devel at lists.freedesktop.org; linaro-mm-sig at lists.linaro.org;
>>yf.wang at mediatek.com; libo.kang at mediatek.com;
>>benjamin.gaignard at linaro.org; bo.song at mediatek.com;
>>matthias.bgg at gmail.com; linux-mediatek at lists.infradead.org;
>>lmark at codeaurora.org; labbott at redhat.com; christian.koenig at amd.com;
>>jianjiao.zeng at mediatek.com; linux-media at vger.kernel.org
>>Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
>>
>>From: Guangming <Guangming.Cao at mediatek.com>
>>
>>Add a size check for allocation since the allocation size is
>>always less than the total DRAM size.
>>
>>Without this check, once the invalid size allocation runs on a process that
>>can't be killed by OOM flow(such as "gralloc" on Android devices), it will
>>cause a kernel exception, and to make matters worse, we can't find who are
>>using
>>so many memory with "dma_buf_debug_show" since the relevant dma-buf
>>hasn't exported.
>>
>>To make OOM issue easier, maybe need dma-buf framework to dump the
>>buffer size
>>under allocating in "dma_buf_debug_show".
>>
>>Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
>>Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
>>---
>>v3: 1. update patch, use right shift to replace division.
>>    2. update patch, add reason in code and commit message.
>>v2: 1. update size limitation as total_dram page size.
>>    2. update commit message
>>---
>> drivers/dma-buf/dma-heap.c | 10 ++++++++++
>> 1 file changed, 10 insertions(+)
>>
>>diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
>>index 56bf5ad01ad5..1fd382712584 100644
>>--- a/drivers/dma-buf/dma-heap.c
>>+++ b/drivers/dma-buf/dma-heap.c
>>@@ -55,6 +55,16 @@ static int dma_heap_buffer_alloc(struct dma_heap
>>*heap, size_t len,
>> 	struct dma_buf *dmabuf;
>> 	int fd;
>>
>>+	/*
>>+	 * Invalid size check. The "len" should be less than totalram.
>>+	 *
>>+	 * Without this check, once the invalid size allocation runs on a process
>>that
>>+	 * can't be killed by OOM flow(such as "gralloc" on Android devices), it
>>will
>>+	 * cause a kernel exception, and to make matters worse, we can't find
>>who are using
>>+	 * so many memory with "dma_buf_debug_show" since the relevant
>>dma-buf hasn't exported.
>>+	 */
>>+	if (len >> PAGE_SHIFT > totalram_pages())
>
>If your "heap" is from cma, is this still a valid check?

And thinking a bit further, if I create a heap from something else (say device memory),
you will need to be able to figure out the maximum allowable check for the specific
heap.

Maybe the heap needs a callback for max size?

m
>M
>
>>+		return -EINVAL;
>> 	/*
>> 	 * Allocations from all heaps have to begin
>> 	 * and end on page boundaries.
>>--
>>2.17.1



From christian.koenig at amd.com  Thu Jan 13 05:05:24 2022
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Thu, 13 Jan 2022 14:05:24 +0100
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <e657f5257cbf4955817b0bbf037de9f9@intel.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
Message-ID: <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>

Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
>> -----Original Message-----
>> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>> Ruhl, Michael J
>> Sent: Thursday, January 13, 2022 7:58 AM
>> To: guangming.cao at mediatek.com; sumit.semwal at linaro.org
>> Cc: jianjiao.zeng at mediatek.com; lmark at codeaurora.org;
>> wsd_upstream at mediatek.com; christian.koenig at amd.com; linux-
>> kernel at vger.kernel.org; dri-devel at lists.freedesktop.org;
>> yf.wang at mediatek.com; linaro-mm-sig at lists.linaro.org; linux-
>> mediatek at lists.infradead.org; libo.kang at mediatek.com;
>> benjamin.gaignard at linaro.org; bo.song at mediatek.com;
>> matthias.bgg at gmail.com; labbott at redhat.com;
>> mingyuan.ma at mediatek.com; linux-arm-kernel at lists.infradead.org; linux-
>> media at vger.kernel.org
>> Subject: RE: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
>>
>>
>>> -----Original Message-----
>>> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>>> guangming.cao at mediatek.com
>>> Sent: Thursday, January 13, 2022 7:34 AM
>>> To: sumit.semwal at linaro.org
>>> Cc: linux-arm-kernel at lists.infradead.org; mingyuan.ma at mediatek.com;
>>> Guangming <Guangming.Cao at mediatek.com>;
>>> wsd_upstream at mediatek.com; linux-kernel at vger.kernel.org; dri-
>>> devel at lists.freedesktop.org; linaro-mm-sig at lists.linaro.org;
>>> yf.wang at mediatek.com; libo.kang at mediatek.com;
>>> benjamin.gaignard at linaro.org; bo.song at mediatek.com;
>>> matthias.bgg at gmail.com; linux-mediatek at lists.infradead.org;
>>> lmark at codeaurora.org; labbott at redhat.com; christian.koenig at amd.com;
>>> jianjiao.zeng at mediatek.com; linux-media at vger.kernel.org
>>> Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
>>>
>>> From: Guangming <Guangming.Cao at mediatek.com>
>>>
>>> Add a size check for allocation since the allocation size is
>>> always less than the total DRAM size.
>>>
>>> Without this check, once the invalid size allocation runs on a process that
>>> can't be killed by OOM flow(such as "gralloc" on Android devices), it will
>>> cause a kernel exception, and to make matters worse, we can't find who are
>>> using
>>> so many memory with "dma_buf_debug_show" since the relevant dma-buf
>>> hasn't exported.
>>>
>>> To make OOM issue easier, maybe need dma-buf framework to dump the
>>> buffer size
>>> under allocating in "dma_buf_debug_show".
>>>
>>> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
>>> Signed-off-by: jianjiao zeng <jianjiao.zeng at mediatek.com>
>>> ---
>>> v3: 1. update patch, use right shift to replace division.
>>>     2. update patch, add reason in code and commit message.
>>> v2: 1. update size limitation as total_dram page size.
>>>     2. update commit message
>>> ---
>>> drivers/dma-buf/dma-heap.c | 10 ++++++++++
>>> 1 file changed, 10 insertions(+)
>>>
>>> diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c
>>> index 56bf5ad01ad5..1fd382712584 100644
>>> --- a/drivers/dma-buf/dma-heap.c
>>> +++ b/drivers/dma-buf/dma-heap.c
>>> @@ -55,6 +55,16 @@ static int dma_heap_buffer_alloc(struct dma_heap
>>> *heap, size_t len,
>>> 	struct dma_buf *dmabuf;
>>> 	int fd;
>>>
>>> +	/*
>>> +	 * Invalid size check. The "len" should be less than totalram.
>>> +	 *
>>> +	 * Without this check, once the invalid size allocation runs on a process
>>> that
>>> +	 * can't be killed by OOM flow(such as "gralloc" on Android devices), it
>>> will
>>> +	 * cause a kernel exception, and to make matters worse, we can't find
>>> who are using
>>> +	 * so many memory with "dma_buf_debug_show" since the relevant
>>> dma-buf hasn't exported.
>>> +	 */
>>> +	if (len >> PAGE_SHIFT > totalram_pages())
>> If your "heap" is from cma, is this still a valid check?
> And thinking a bit further, if I create a heap from something else (say device memory),
> you will need to be able to figure out the maximum allowable check for the specific
> heap.
>
> Maybe the heap needs a callback for max size?

Well we currently maintain a separate allocator and don't use dma-heap, 
but yes we have systems with 16GiB device and only 8GiB system memory so 
that check here is certainly not correct.

In general I would rather let the system run into -ENOMEM or -EINVAL 
from the allocator instead.

Regards,
Christian.

>
> m
>> M
>>
>>> +		return -EINVAL;
>>> 	/*
>>> 	 * Allocations from all heaps have to begin
>>> 	 * and end on page boundaries.
>>> --
>>> 2.17.1



From hverkuil-cisco at xs4all.nl  Thu Jan 13 05:05:49 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Thu, 13 Jan 2022 14:05:49 +0100
Subject: [PATCH v2 09/13] media: mtk-vcodec: Drop unnecessary call to
 platform_get_resource()
In-Reply-To: <20220111002314.15213-10-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20220111002314.15213-10-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <d66a7182-825f-b9a3-afc9-c0117ea846a2@xs4all.nl>

Hi Prabhakar,

I'm skipping this patch since if I am not mistaken this patch fixes this as well
(as part of a larger overhaul):

https://patchwork.linuxtv.org/project/linux-media/patch/20220113041055.25213-9-yunfei.dong at mediatek.com/

I posted a PR for that series, so that's on the way in.

Please confirm so I can mark your patch as Superseded.

Regards,

	Hans

On 11/01/2022 01:23, Lad Prabhakar wrote:
> mtk_vcodec_probe() calls platform_get_resource(pdev, IORESOURCE_IRQ, ..)
> to check if IRQ resource exists and later calls platform_get_irq(pdev, ..)
> to get the actual IRQ.
> 
> This patch drops an unnecessary call to platform_get_resource() and
> checks the return value of platform_get_irq(pdev, ..) to check if the
> IRQ line is valid.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v1->v2
> * No change.
> ---
>  .../media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c    | 11 ++++-------
>  .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c    | 10 +++-------
>  2 files changed, 7 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> index 40c39e1e596b..1509c2a4de84 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
> @@ -200,7 +200,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  {
>  	struct mtk_vcodec_dev *dev;
>  	struct video_device *vfd_dec;
> -	struct resource *res;
>  	phandle rproc_phandle;
>  	enum mtk_vcodec_fw_type fw_type;
>  	int i, ret;
> @@ -244,14 +243,12 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  		mtk_v4l2_debug(2, "reg[%d] base=%p", i, dev->reg_base[i]);
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "failed to get irq resource");
> -		ret = -ENOENT;
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
>  		goto err_res;
> -	}
>  
> -	dev->dec_irq = platform_get_irq(pdev, 0);
> +	dev->dec_irq = ret;
> +
>  	irq_set_status_flags(dev->dec_irq, IRQ_NOAUTOEN);
>  	ret = devm_request_irq(&pdev->dev, dev->dec_irq,
>  			mtk_vcodec_dec_irq_handler, 0, pdev->name, dev);
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> index aeaecb8d416e..86e70d826754 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
> @@ -236,7 +236,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  {
>  	struct mtk_vcodec_dev *dev;
>  	struct video_device *vfd_enc;
> -	struct resource *res;
>  	phandle rproc_phandle;
>  	enum mtk_vcodec_fw_type fw_type;
>  	int ret;
> @@ -280,14 +279,11 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
>  		goto err_res;
>  	}
>  
> -	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(&pdev->dev, "failed to get irq resource");
> -		ret = -ENOENT;
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
>  		goto err_res;
> -	}
>  
> -	dev->enc_irq = platform_get_irq(pdev, 0);
> +	dev->enc_irq = ret;
>  	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
>  	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
>  			       mtk_vcodec_enc_irq_handler,



From ardb at kernel.org  Thu Jan 13 05:12:39 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 13 Jan 2022 14:12:39 +0100
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long based on
 RNDR
Message-ID: <20220113131239.1610455-1-ardb@kernel.org>

When support for RNDR/RNDRRS was introduced, we elected to only
implement arch_get_random_seed_int/_long(), and back them by RNDR
instead of RNDRRS. This was needed to prevent potential performance
and/or starvation issues resulting from the fact that the /dev/random
driver used to invoke these routines on various hot paths.

These issues have all been addressed now [0] [1], and so we can wire up
this API more straight-forwardly:

- map arch_get_random_int/_long() onto RNDR, which returns the output of
  a DRBG that is reseeded at an implemented defined rate;
- map arch_get_random_seed_int/_long() onto the TRNG firmware service,
  which returns true, conditioned entropy, or onto RNDRRS if the TRNG
  service is unavailable, which returns the output of a DRBG that is
  reseeded every time it is used.

[0] 390596c9959c random: avoid arch_get_random_seed_long() when collecting IRQ randomness
[1] 2ee25b6968b1 random: avoid superfluous call to RDRAND in CRNG extraction

Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Mark Brown <broonie at kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/archrandom.h | 45 +++++++++++++++++---
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
index 09e43272ccb0..d1bb5e71df25 100644
--- a/arch/arm64/include/asm/archrandom.h
+++ b/arch/arm64/include/asm/archrandom.h
@@ -42,13 +42,47 @@ static inline bool __arm64_rndr(unsigned long *v)
 	return ok;
 }
 
+static inline bool __arm64_rndrrs(unsigned long *v)
+{
+	bool ok;
+
+	/*
+	 * Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success,
+	 * and set PSTATE.NZCV to 0b0100 otherwise.
+	 */
+	asm volatile(
+		__mrs_s("%0", SYS_RNDRRS_EL0) "\n"
+	"	cset %w1, ne\n"
+	: "=r" (*v), "=r" (ok)
+	:
+	: "cc");
+
+	return ok;
+}
+
 static inline bool __must_check arch_get_random_long(unsigned long *v)
 {
+	/*
+	 * Only support the generic interface after we have detected
+	 * the system wide capability, avoiding complexity with the
+	 * cpufeature code and with potential scheduling between CPUs
+	 * with and without the feature.
+	 */
+	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+		return true;
 	return false;
 }
 
 static inline bool __must_check arch_get_random_int(unsigned int *v)
 {
+	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
+		unsigned long val;
+
+		if (__arm64_rndr(&val)) {
+			*v = val;
+			return true;
+		}
+	}
 	return false;
 }
 
@@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
 	}
 
 	/*
-	 * Only support the generic interface after we have detected
-	 * the system wide capability, avoiding complexity with the
-	 * cpufeature code and with potential scheduling between CPUs
-	 * with and without the feature.
+	 * RNDRRS is not backed by an entropy source but by a DRBG that is
+	 * reseeded after each invocation. This is not a 100% fit but good
+	 * enough to implement this API if no other entropy source exists.
 	 */
-	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
+	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
 		return true;
 
 	return false;
@@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
 	}
 
 	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
-		if (__arm64_rndr(&val)) {
+		if (__arm64_rndrrs(&val)) {
 			*v = val;
 			return true;
 		}
-- 
2.30.2



From prabhakar.csengg at gmail.com  Thu Jan 13 05:12:48 2022
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Thu, 13 Jan 2022 13:12:48 +0000
Subject: [PATCH v2 09/13] media: mtk-vcodec: Drop unnecessary call to
 platform_get_resource()
In-Reply-To: <d66a7182-825f-b9a3-afc9-c0117ea846a2@xs4all.nl>
References: <20220111002314.15213-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <20220111002314.15213-10-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <d66a7182-825f-b9a3-afc9-c0117ea846a2@xs4all.nl>
Message-ID: <CA+V-a8s9s9Q=-NiwZYhpUNuiHyTzREqzMrH60mkdcR9uUYN+2A@mail.gmail.com>

Hi Hans,

On Thu, Jan 13, 2022 at 1:05 PM Hans Verkuil <hverkuil-cisco at xs4all.nl> wrote:
>
> Hi Prabhakar,
>
> I'm skipping this patch since if I am not mistaken this patch fixes this as well
> (as part of a larger overhaul):
>
> https://patchwork.linuxtv.org/project/linux-media/patch/20220113041055.25213-9-yunfei.dong at mediatek.com/
>
> I posted a PR for that series, so that's on the way in.
>
> Please confirm so I can mark your patch as Superseded.
>
Ack.

Cheers,
Prabhakar


From maz at kernel.org  Thu Jan 13 05:14:53 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 13 Jan 2022 13:14:53 +0000
Subject: [PATCH v5 05/69] KVM: arm64: Allow preservation of the S2 SW bits
In-Reply-To: <YeAXFOR1wf3LekrQ@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-6-maz@kernel.org>
 <YeAXFOR1wf3LekrQ@monolith.localdoman>
Message-ID: <87o84f93qq.wl-maz@kernel.org>

Hi Alex,

On Thu, 13 Jan 2022 12:12:04 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:46PM +0000, Marc Zyngier wrote:
> > The S2 page table code has a limited use the SW bits, but we are about
> > to need them to encode some guest Stage-2 information (its mapping size
> > in the form of the TTL encoding).
> > 
> > Propagate the SW bits specified by the caller, and store them into
> > the corresponding entry.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/hyp/pgtable.c | 7 ++++---
> >  1 file changed, 4 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> > index 8cdbc43fa651..d69e400b2de6 100644
> > --- a/arch/arm64/kvm/hyp/pgtable.c
> > +++ b/arch/arm64/kvm/hyp/pgtable.c
> > @@ -1064,9 +1064,6 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> >  	u32 level;
> >  	kvm_pte_t set = 0, clr = 0;
> >  
> > -	if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
> > -		return -EINVAL;
> > -
> >  	if (prot & KVM_PGTABLE_PROT_R)
> >  		set |= KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R;
> >  
> > @@ -1076,6 +1073,10 @@ int kvm_pgtable_stage2_relax_perms(struct kvm_pgtable *pgt, u64 addr,
> >  	if (prot & KVM_PGTABLE_PROT_X)
> >  		clr |= KVM_PTE_LEAF_ATTR_HI_S2_XN;
> >  
> > +	/* Always propagate the SW bits */
> > +	clr |= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_SW, 0xf);
> 
> Nitpick: isn't that the same as:
> 
> 	clr |= KVM_PTE_LEAF_ATTR_HI_SW;
> 
> which looks more readable to me.
> 
> > +	set |= prot & KVM_PTE_LEAF_ATTR_HI_SW;
> 
> Checked stage2_attr_walker() callbak, first it clears the bits in clr, then
> sets the bits in set, so this looks correct to me:
> 
> Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks. However, I have now dropped this patch since as it turns out,
the PTE update does preserve pre-existing SW bits. I am now carrying
this:

@@ -1212,6 +1218,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
         * kvm_pgtable_stage2_map() should be called to change block size.
         */
        if (fault_status == FSC_PERM && vma_pagesize == fault_granule) {
+               /*
+                * Drop the SW bits in favour of those stored in the
+                * PTE, which will be preserved.
+                */
+               prot &= ~KVM_NV_GUEST_MAP_SZ;
                ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
        } else {
                ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,

as part of the patch that tags the shadow S2 with the guest's S2
mapping size (or level, which amounts to the same thing).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:16:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:16:54 +0100
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220113121143.22280-15-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
 <20220113121143.22280-15-alim.akhtar@samsung.com>
Message-ID: <55c22c3a-57ea-3320-ccb9-f03643563235@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add initial device tree support for "Full Self-Driving" (FSD) SoC
> This SoC contain three clusters of four cortex-a72 CPUs and various
> peripheral IPs.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  MAINTAINERS                        |   8 +
>  arch/arm64/Kconfig.platforms       |   6 +
>  arch/arm64/boot/dts/Makefile       |   1 +
>  arch/arm64/boot/dts/tesla/Makefile |   3 +
>  arch/arm64/boot/dts/tesla/fsd.dts  | 140 ++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi | 715 +++++++++++++++++++++++++++++
>  6 files changed, 873 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dts
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fb18ce7168aa..02d56909c5e2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2726,6 +2726,14 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/media/tegra-cec.txt
>  F:	drivers/media/cec/platform/tegra/
>  
> +ARM/TESLA FSD SoC SUPPORT
> +M:	Alim Akhtar <alim.akhtar at samsung.com>
> +M:	linux-fsd at tesla.com
> +L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> +L:	linux-samsung-soc at vger.kernel.org
> +S:	Maintained
> +F:	arch/arm64/boot/dts/tesla*
> +

+Cc Arnd,

Please Cc all SoC maintainers in new sub-architecture submissions, so
Olof and Arnd.

>  ARM/TETON BGA MACHINE SUPPORT
>  M:	"Mark F. Brown" <mark.brown314 at gmail.com>
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 54e3910e8b9b..bb8a047c2359 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -267,6 +267,12 @@ config ARCH_TEGRA
>  	help
>  	  This enables support for the NVIDIA Tegra SoC family.
>  
> +config ARCH_TESLA_FSD
> +	bool "ARMv8 based Tesla platform"
> +	select ARCH_EXYNOS

How similar it is? I think it is better to duplicate Exynos
selections/options here, instead of selecting entire ARCH. If this would
require "depends on ARCH_EXYNOS || ARCH_TESLA_FSD" everywhere in the
drivers, it's a hint that it is not a separate SoC but it is an Exynos,
so it might not need a new sub-architecture.


> +	help
> +	  Support for ARMv8 based Tesla platforms.
> +
>  config ARCH_SPRD
>  	bool "Spreadtrum SoC platform"
>  	help
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 639e01a4d855..1ba04e31a438 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -27,6 +27,7 @@ subdir-y += rockchip
>  subdir-y += socionext
>  subdir-y += sprd
>  subdir-y += synaptics
> +subdir-y += tesla
>  subdir-y += ti
>  subdir-y += toshiba
>  subdir-y += xilinx
> diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
> new file mode 100644
> index 000000000000..a9818cda6b08
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_TESLA_FSD) += \
> +	fsd.dtb
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
> new file mode 100644
> index 000000000000..e9bbd3284de9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd.dts

No, this is not a fsd.dts, but some board. You call FSD a SoC, so this
should have different name.

> @@ -0,0 +1,140 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla FSD board device tree source
> + *
> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
> + *		https://www.samsung.com
> + * Copyright (c) 2017-2021 Tesla, Inc.
> + *		https://www.tesla.com
> + */
> +
> +/dts-v1/;
> +#include "fsd.dtsi"
> +
> +/ {
> +	model = "Tesla Full Self-Driving (FSD) SoC";

Wrong model, this is DTS, not DTSI.

> +	compatible = "tesla,fsd";

Missing compatible for board.

> +
> +	aliases {
> +		serial0 = &serial_0;
> +		serial1 = &serial_1;
> +	};
> +
> +	chosen {
> +		stdout-path = &serial_0;
> +		linux,initrd-start = <0xE0000000>;
> +		linux,initrd-end = <0xE4F00000>;
> +		bootargs = "console=ttySAC0,115200n8
> +			earlycon=exynos4210,0x14180000 root=/dev/ram0
> +			init=/linuxrc";

These are not bootargs matching SoC. earlycon is purely a debug option.
console is duplicating stdout-path. root and init are also not a part of
DTSI or DTS.

> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x80000000 0x2 0x00000000>;
> +	};
> +};
> +
> +&fin_pll {
> +	clock-frequency = <24000000>;
> +};
> +
> +&serial_0 {
> +	status = "okay";
> +};
> +
> +&serial_1 {
> +	status = "okay";
> +};
> +
> +&clock_cmu {
> +	status = "okay";
> +};
> +
> +&clock_imem {
> +	status = "okay";
> +};
> +
> +&clock_peric {
> +	status = "okay";
> +};

The labels/overrides are with weird order... looks like a mess. Anyway,
clocks should be always enabled, why board has to enable them?

> +
> +&smmu_isp {
> +	status = "okay";
> +};
> +
> +&clock_fsys0 {
> +	status = "okay";
> +};
> +
> +&clock_fsys1 {
> +	status = "okay";
> +};
> +
> +&smmu_peric {
> +	status = "okay";

The same as clocks.

> +};
> +
> +&smmu_imem {
> +	status = "okay";
> +};
> +
> +&smmu_fsys0 {
> +	status = "okay";
> +};
> +
> +&hsi2c_0 {
> +	status = "okay";

This looks wrong. There is nothing attached.

> +};
> +
> +&hsi2c_1 {
> +	status = "okay";

Same here and other I2C.

> +};
> +
> +&hsi2c_2 {
> +	status = "okay";
> +};
> +
> +&hsi2c_3 {
> +	status = "okay";
> +};
> +
> +&hsi2c_4 {
> +	status = "okay";
> +};
> +
> +&hsi2c_5 {
> +	status = "okay";
> +};
> +
> +&hsi2c_6 {
> +	status = "okay";
> +};
> +
> +&hsi2c_7 {
> +	status = "okay";
> +};
> +
> +&pwm_0 {
> +	status = "okay";

Nope, nope.

> +};
> +
> +&pwm_1 {
> +	status = "okay";
> +};
> +
> +&mdma0 {
> +	status = "okay";

Can you imagine SoC with disabled DMA?

> +};
> +
> +&mdma1 {
> +	status = "okay";
> +};
> +
> +&pdma0 {
> +	status = "okay";
> +};
> +
> +&pdma1 {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
> new file mode 100644
> index 000000000000..47cd9f20566e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
> @@ -0,0 +1,715 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla Full Self-Driving SoC device tree source
> + *
> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> + *		https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *		https://www.tesla.com
> + */
> +
> +#include <dt-bindings/clock/fsd-clk.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +	compatible = "tesla,fsd";

Same compatible as board - nope.

> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		watchdog0 = &watchdog_0;
> +		watchdog1 = &watchdog_1;
> +		watchdog2 = &watchdog_2;

I think watchdogs do not need/use aliases.

> +		hsi2c0 = &hsi2c_0;
> +		hsi2c1 = &hsi2c_1;
> +		hsi2c2 = &hsi2c_2;
> +		hsi2c3 = &hsi2c_3;
> +		hsi2c4 = &hsi2c_4;
> +		hsi2c5 = &hsi2c_5;
> +		hsi2c6 = &hsi2c_6;
> +		hsi2c7 = &hsi2c_7;
> +	};
> +
> +	cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		cpu-map {
> +			cluster0 {
> +				core0 {
> +					cpu = <&cpucl0_0>;
> +				};
> +				core1 {
> +					cpu = <&cpucl0_1>;
> +				};
> +				core2 {
> +					cpu = <&cpucl0_2>;
> +				};
> +				core3 {
> +					cpu = <&cpucl0_3>;
> +				};
> +			};
> +
> +			cluster1 {
> +				core0 {
> +					cpu = <&cpucl1_0>;
> +				};
> +				core1 {
> +					cpu = <&cpucl1_1>;
> +				};
> +				core2 {
> +					cpu = <&cpucl1_2>;
> +				};
> +				core3 {
> +					cpu = <&cpucl1_3>;
> +				};
> +			};
> +
> +			cluster2 {
> +				core0 {
> +					cpu = <&cpucl2_0>;
> +				};
> +				core1 {
> +					cpu = <&cpucl2_1>;
> +				};
> +				core2 {
> +					cpu = <&cpucl2_2>;
> +				};
> +				core3 {
> +					cpu = <&cpucl2_3>;
> +				};
> +			};
> +		};
> +
> +		/* Cluster 0 */
> +		cpucl0_0: cpu at 0 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x000>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl0_1: cpu at 1 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x001>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl0_2: cpu at 2 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x002>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl0_3: cpu at 3 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x003>;
> +				enable-method = "psci";
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		/* Cluster 1 */
> +		cpucl1_0: cpu at 100 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x100>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl1_1: cpu at 101 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x101>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl1_2: cpu at 102 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x102>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl1_3: cpu at 103 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x103>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		/* Cluster 2 */
> +		cpucl2_0: cpu at 200 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x200>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl2_1: cpu at 201 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x201>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl2_2: cpu at 202 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x202>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		cpucl2_3: cpu at 203 {
> +				device_type = "cpu";
> +				compatible = "arm,cortex-a72";
> +				reg = <0x0 0x203>;
> +				enable-method = "psci";
> +				clock-frequency = <2400000000>;
> +				cpu-idle-states = <&CPU_SLEEP>;
> +				next-level-cache = <&L2_0>;
> +		};
> +
> +		idle-states {
> +			entry-method = "arm,psci";
> +
> +			CPU_SLEEP: cpu-sleep {
> +				idle-state-name = "c2";
> +				compatible = "arm,idle-state";
> +				local-timer-stop;
> +				arm,psci-suspend-param = <0x0010000>;
> +				entry-latency-us = <30>;
> +				exit-latency-us = <75>;
> +				min-residency-us = <300>;
> +				status = "okay";

No need for status.

> +			};
> +		};
> +
> +		L2_0: l2-cache0 {

lowercase letters in label.

> +			compatible = "cache";

You miss here some properties. Does your DTSI/DTS pass dtschema validation?

> +		};
> +	};
> +
> +	arm-pmu {
> +		compatible = "arm,armv8-pmuv3";
> +		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
> +				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
> +				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
> +				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci";
> +		method = "smc";
> +		cpu_on = <0xC4000003>;
> +		cpu_suspend = <0xC4000001>;
> +		cpu_off = <0x84000002>;
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,

Not sure - don't you need CPU mask?

> +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> +	};
> +
> +	fin_pll: clock {
> +		compatible = "fixed-clock";
> +		clock-output-names = "fin_pll";
> +		#clock-cells = <0>;
> +	};
> +
> +	soc: soc {
> +		compatible = "simple-bus";
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
> +		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
> +
> +		gic: interrupt-controller at 10400000 {
> +			compatible = "arm,gic-v3";
> +			#interrupt-cells = <3>;
> +			interrupt-controller;
> +			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
> +				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
> +		};
> +
> +		smmu_isp: iommu at 12100000 {
> +			compatible = "arm,mmu-500";
> +			reg = <0x0 0x12100000 0x0 0x10000>;
> +			#iommu-cells = <2>;
> +			#global-interrupts = <11>;
> +			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +				     /* Performance counter interrupts */
> +				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
> +				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
> +				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
> +				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
> +				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
> +				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
> +				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
> +				     /* Per context non-secure context interrupts, 0-7 interrupts */
> +				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
> +				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
> +				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
> +				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
> +				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
> +				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
> +				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
> +			status = "disabled";
> +		};
> +
> +		smmu_imem: iommu at 10200000 {
> +			compatible = "arm,mmu-500";
> +			reg = <0x0 0x10200000 0x0 0x10000>;
> +			#iommu-cells = <2>;
> +			#global-interrupts = <7>;
> +			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +				     /* Performance counter interrupts */
> +				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
> +				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
> +				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
> +				     /* Per context non-secure context interrupts, 0-3 interrupts */
> +				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
> +				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
> +				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
> +			status = "disabled";
> +		};
> +
> +		smmu_peric: iommu at 14900000 {
> +			compatible = "arm,mmu-500";
> +			reg = <0x0 0x14900000 0x0 0x10000>;
> +			#iommu-cells = <2>;
> +			#global-interrupts = <5>;
> +			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +				     /* Performance counter interrupts */
> +				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
> +				     /* Per context non-secure context interrupts, 0-1 interrupts */
> +				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
> +			status = "disabled";
> +		};
> +
> +		smmu_fsys0: iommu at 15450000 {
> +			compatible = "arm,mmu-500";
> +			reg = <0x0 0x15450000 0x0 0x10000>;
> +			#iommu-cells = <2>;
> +			#global-interrupts = <5>;
> +			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +				     /* Performance counter interrupts */
> +				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
> +				     /* Per context non-secure context interrupts, 0-1 interrupts */
> +				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
> +			status = "disabled";
> +		};
> +
> +		clock_cmu: clock-controller at 11C10000 {
> +			compatible = "tesla,fsd-clock-cmu";
> +			reg = <0x0 0x11C10000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>;
> +			clock-names = "fin_pll";
> +			status = "disabled";

This explains why DTS has to enable basic SoC features... why do you
disable your clock controllers?

> +		};
> +
> +		clock_imem: clock-controller at 10010000 {
> +			compatible = "tesla,fsd-clock-imem";
> +			reg = <0x0 0x10010000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>,
> +				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
> +				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
> +				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
> +			clock-names = "fin_pll",
> +				"dout_cmu_imem_tcuclk",
> +				"dout_cmu_imem_aclk",
> +				"dout_cmu_imem_dmaclk";
> +			status = "disabled";
> +		};
> +
> +		clock_peric: clock-controller at 14010000 {
> +			compatible = "tesla,fsd-clock-peric";
> +			reg = <0x0 0x14010000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>,
> +				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
> +				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
> +				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
> +				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
> +				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
> +			clock-names = "fin_pll",
> +				"dout_cmu_pll_shared0_div4",
> +				"dout_cmu_peric_shared1div36",
> +				"dout_cmu_peric_shared0div3_tbuclk",
> +				"dout_cmu_peric_shared0div20",
> +				"dout_cmu_peric_shared1div4_dmaclk";
> +			status = "disabled";
> +		};
> +
> +		clock_fsys0: clock-controller at 15010000 {
> +			compatible = "tesla,fsd-clock-fsys0";
> +			reg = <0x0 0x15010000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>,
> +				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
> +				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
> +				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
> +			clock-names = "fin_pll",
> +				"dout_cmu_pll_shared0_div6",
> +				"dout_cmu_fsys0_shared1div4",
> +				"dout_cmu_fsys0_shared0div4";
> +			status = "disabled";
> +		};
> +
> +		clock_fsys1: clock-controller at 16810000 {
> +			compatible = "tesla,fsd-clock-fsys1";
> +			reg = <0x0 0x16810000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>,
> +				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
> +				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
> +			clock-names = "fin_pll",
> +				"dout_cmu_fsys1_shared0div8",
> +				"dout_cmu_fsys1_shared0div4";
> +			status = "disabled";
> +		};
> +
> +		clock_mfc: clock-controller at 12810000 {
> +			compatible = "tesla,fsd-clock-mfc";
> +			reg = <0x0 0x12810000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>;
> +			clock-names = "fin_pll";
> +			status = "disabled";
> +		};
> +
> +		clock_csi: clock-controller at 12610000 {
> +			compatible = "tesla,fsd-clock-cam_csi";
> +			reg = <0x0 0x12610000 0x0 0x3000>;
> +			#clock-cells = <1>;
> +			clocks = <&fin_pll>;
> +			clock-names = "fin_pll";
> +			status = "disabled";
> +		};
> +
> +		mdma0: mdma at 10100000 {

Node name: just dma to be generic. Schema does not enforce it but might
at some point.

> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x0 0x10100000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
> +			#dma-cells = <1>;
> +			#dma-channels = <8>;
> +			#dma-requests = <32>;
> +			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
> +			clock-names = "apb_pclk";
> +			iommus = <&smmu_imem 0x800 0x0>;
> +			status = "disabled";
> +		};
> +
> +		mdma1: mdma at 10110000 {
> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x0 0x10110000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
> +			#dma-cells = <1>;
> +			#dma-channels = <8>;
> +			#dma-requests = <32>;
> +			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
> +			clock-names = "apb_pclk";
> +			iommus = <&smmu_imem 0x801 0x0>;
> +			status = "disabled";
> +		};
> +
> +		pdma0: pdma at 14280000 {
> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x0 0x14280000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
> +			#dma-cells = <1>;
> +			#dma-channels = <8>;
> +			#dma-requests = <32>;
> +			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
> +			clock-names = "apb_pclk";
> +			iommus = <&smmu_peric 0x2 0x0>;
> +			status = "disabled";
> +		};
> +
> +		pdma1: pdma at 14290000 {
> +			compatible = "arm,pl330", "arm,primecell";
> +			reg = <0x0 0x14290000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
> +			#dma-cells = <1>;
> +			#dma-channels = <8>;
> +			#dma-requests = <32>;
> +			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
> +			clock-names = "apb_pclk";
> +			iommus = <&smmu_peric 0x1 0x0>;
> +			status = "disabled";
> +		};
> +
> +		mct: mct at 10040000 {
> +			compatible = "samsung,exynos4210-mct";
> +			reg = <0x0 0x10040000 0x0 0x800>;
> +			interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
> +				<GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>;
> +			clock-names = "fin_pll", "mct";
> +		};
> +
> +		serial_0: serial at 14180000 {
> +			compatible = "samsung,exynos4210-uart";
> +			reg = <0x0 0x14180000 0x0 0x100>;
> +			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
> +			dmas = <&pdma1 0>, <&pdma1 1>;
> +			dma-names = "tx", "rx";
> +			clocks = <&clock_peric PERIC_PCLK_UART0>,
> +				 <&clock_peric PERIC_SCLK_UART0>;
> +			clock-names = "uart", "clk_uart_baud0";
> +			status = "disabled";
> +		};
> +
> +		serial_1: serial at 14190000 {
> +			compatible = "samsung,exynos4210-uart";
> +			reg = <0x0 0x14190000 0x0 0x100>;
> +			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
> +			dmas = <&pdma1 2>, <&pdma1 3>;
> +			dma-names = "tx", "rx";
> +			clocks = <&clock_peric PERIC_PCLK_UART1>,
> +				 <&clock_peric PERIC_SCLK_UART1>;
> +			clock-names = "uart", "clk_uart_baud0";
> +			status = "disabled";
> +		};
> +
> +		pmu_system_controller: system-controller at 11400000 {
> +			compatible = "samsung,exynos7-pmu", "syscon";
> +			reg = <0x0 0x11400000 0x0 0x5000>;
> +		};
> +
> +		watchdog_0: watchdog at 100A0000 {

lowercase hex addresses. Here, in reg below and all other nodes.

> +			compatible = "samsung,exynos7-wdt";
> +			reg = <0x0 0x100A0000 0x0 0x100>;
> +			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
> +			samsung,syscon-phandle = <&pmu_system_controller>;
> +			clocks = <&fin_pll>;
> +			clock-names = "watchdog";
> +			interrupt-mode = <1>;

This property looks unsupported. Did you run dtschema checks?

Best regards,
Krzysztof


From philippe.cornu at foss.st.com  Thu Jan 13 05:16:57 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Thu, 13 Jan 2022 14:16:57 +0100
Subject: [PATCH v3 2/6] drm/plane: Fix typo in format_mod_supported
 documentation
In-Reply-To: <20220107172601.GA122757@elementary>
References: <20211226112503.31771-1-jose.exposito89@gmail.com>
 <20211226112503.31771-3-jose.exposito89@gmail.com>
 <3DdB6YPUQr4O063yNreefZcIm6p5Z6HORoVVbk5RTMmjz8qvnxMse42hLvfDmA323KG-TWLc_JUFZEEEIkoINXQuAzjLVe2jRRM01tQgYOU=@emersion.fr>
 <20220107172601.GA122757@elementary>
Message-ID: <735432ff-d9a7-aff0-e94a-13035e944570@foss.st.com>



On 1/7/22 6:26 PM, Jos? Exp?sito wrote:
> Hi Simon,
> 
> On Wed, Jan 05, 2022 at 11:54:43PM +0000, Simon Ser wrote:
>> Pushed patches 1 & 2 to drm-misc-next. Thanks for your contribution!
> 
> Thanks a lot for the review and for applying the changes, appreciate it.
> 
> Is there something that needs to improve in the other 4 patches?
> Or just waiting on maintainers input?
> 
> Thanks,
> Jos? Exp?sito
> 

Hi Jos?,
for the drm/stm part,
Applied on drm-misc-next.
Many thanks for your patches,
Philippe :-)


From philippe.cornu at foss.st.com  Thu Jan 13 05:19:23 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Thu, 13 Jan 2022 14:19:23 +0100
Subject: [PATCH 0/5] drm/stm: new features to display controller
In-Reply-To: <20211215214651.19798-1-yannick.fertre@foss.st.com>
References: <20211215214651.19798-1-yannick.fertre@foss.st.com>
Message-ID: <14a5fdf6-020b-ecf4-d566-a1b8a5a62de5@foss.st.com>



On 12/15/21 10:46 PM, Yannick Fertre wrote:
> Hello,
> List of new feature:
> * Replace the legacy register access by regmap API.
> * Support of YCbCr 422 output
> * Update layer shadow registers per plane.
> * Support of YCbCr output (planar, semiplanar & coplanar)
> 
> These featues are available only with last hardware version of ltdc
> (0x401000) link to patch"drm/stm: ltdc: support of new hardware version"
> (https://patchwork.freedesktop.org/patch/465207).
> 
> Yannick Fertre (5):
>    drm/stm: ltdc: switch to regmap
>    drm/stm: ltdc: add YCbCr 422 output support
>    drm/stm: ltdc: add per plane update support
>    drm/stm: ltdc: add support of flexible pixel formats
>    drm/stm: ltdc: add support of ycbcr pixel formats
> 
>   drivers/gpu/drm/stm/ltdc.c | 639 +++++++++++++++++++++++++++++--------
>   drivers/gpu/drm/stm/ltdc.h |   9 +-
>   2 files changed, 518 insertions(+), 130 deletions(-)
> 

Hi Yannick,
for the entire serie,
Applied on drm-misc-next.
Many thanks for your patches,
Philippe :-)


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:19:51 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:19:51 +0100
Subject: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220113121143.22280-16-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122417epcas5p47398a5190cdf4c574c6f1762918b549f@epcas5p4.samsung.com>
 <20220113121143.22280-16-alim.akhtar@samsung.com>
Message-ID: <2927c34e-3259-4e9a-a657-aeeebf9089d2@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> Add initial pin configuration nodes for FSD SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 338 +++++++++++++++++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
>  2 files changed, 360 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> 
> diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> new file mode 100644
> index 000000000000..ec8d944af636
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> @@ -0,0 +1,338 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla Full Self-Driving SoC device tree source
> + *
> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
> + *		https://www.samsung.com
> + * Copyright (c) 2017-2021 Tesla, Inc.
> + *		https://www.tesla.com
> + */
> +
> +#include <dt-bindings/pinctrl/samsung.h>
> +
> +&pinctrl_fsys0 {
> +

No need for empty line.

> +	gpf0: gpf0 {

FYI:
It's ok now, but the nodes will have to be renamed to "xxx-gpio-bank" later.

> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf1: gpf1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf6: gpf6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf4: gpf4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf5: gpf5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +};
> +
> +&pinctrl_peric {
> +

No need for empty line.

> +	gpc8: gpc8 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf2: gpf2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf3: gpf3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd0: gpd0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb0: gpb0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb1: gpb1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb4: gpb4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb5: gpb5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb6: gpb6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb7: gpb7 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd1: gpd1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd2: gpd2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd3: gpd3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg0: gpg0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg1: gpg1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg2: gpg2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg3: gpg3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg4: gpg4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg5: gpg5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg6: gpg6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg7: gpg7 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	pwm0_out: pwm0-out {

All pin configuretion node names with "-pins" suffix. Upcoming dtschema
will require this.

> +		samsung,pins = "gpb6-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
> +	};
> +
> +	pwm1_out: pwm1-out {
> +		samsung,pins = "gpb6-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
> +	};
> +
> +	hs_i2c0_bus: hs-i2c0-bus {
> +		samsung,pins = "gpb0-0", "gpb0-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c1_bus: hs-i2c1-bus {
> +		samsung,pins = "gpb0-2", "gpb0-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c2_bus: hs-i2c2-bus {
> +		samsung,pins = "gpb0-4", "gpb0-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c3_bus: hs-i2c3-bus {
> +		samsung,pins = "gpb0-6", "gpb0-7";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c4_bus: hs-i2c4-bus {
> +		samsung,pins = "gpb1-0", "gpb1-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c5_bus: hs-i2c5-bus {
> +		samsung,pins = "gpb1-2", "gpb1-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c6_bus: hs-i2c6-bus {
> +		samsung,pins = "gpb1-4", "gpb1-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	hs_i2c7_bus: hs-i2c7-bus {
> +		samsung,pins = "gpb1-6", "gpb1-7";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	uart0_data: uart0-data {
> +		samsung,pins = "gpb7-0", "gpb7-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	uart1_data: uart1-data {
> +		samsung,pins = "gpb7-4", "gpb7-5";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	spi0_bus: spi0-bus {
> +		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	spi1_bus: spi1-bus {
> +		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +
> +	spi2_bus: spi2-bus {
> +		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
> +	};
> +};
> +
> +&pinctrl_pmu {
> +

No need for empty line.

> +	gpq0: gpq0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +	};




Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:21:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:21:01 +0100
Subject: [PATCH 17/23] Documentation: bindings: Add fsd spi compatible in
 dt-bindings document
In-Reply-To: <20220113121143.22280-18-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122427epcas5p1885d8b3b735e8f127b6694a309796e5a@epcas5p1.samsung.com>
 <20220113121143.22280-18-alim.akhtar@samsung.com>
Message-ID: <138009e6-6097-3ebf-fd20-ca9babb156e8@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds spi controller dt-binding compatible information for
> Tesla Full Self-Driving SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/spi/spi-samsung.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

Please rebase on upcoming Samsung SPI dtschema patches.

> diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> index 49028a4f5df1..3af2408454b4 100644
> --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> @@ -11,6 +11,7 @@ Required SoC Specific Properties:
>      - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
>      - samsung,exynos5433-spi: for exynos5433 compatible controllers
>      - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
> +    - tesla,fsd-spi: spi controller support for Tesla Full Self-Driving SoC

Compatible - same discussions/questions as with other ones.

>  
>  - reg: physical base address of the controller and length of memory mapped
>    region.
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:24:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:24:35 +0100
Subject: [PATCH 17/23] Documentation: bindings: Add fsd spi compatible in
 dt-bindings document
In-Reply-To: <20220113121143.22280-18-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122427epcas5p1885d8b3b735e8f127b6694a309796e5a@epcas5p1.samsung.com>
 <20220113121143.22280-18-alim.akhtar@samsung.com>
Message-ID: <0d4c7a40-5eec-2cc5-82bc-d0ba4910d665@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds spi controller dt-binding compatible information for
> Tesla Full Self-Driving SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/spi/spi-samsung.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

Also: subject prefix:
spi: dt-bindings: samsung:

> diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> index 49028a4f5df1..3af2408454b4 100644
> --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
> +++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
> @@ -11,6 +11,7 @@ Required SoC Specific Properties:
>      - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
>      - samsung,exynos5433-spi: for exynos5433 compatible controllers
>      - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
> +    - tesla,fsd-spi: spi controller support for Tesla Full Self-Driving SoC
>  
>  - reg: physical base address of the controller and length of memory mapped
>    region.
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:28:47 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:28:47 +0100
Subject: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220113121143.22280-19-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122435epcas5p18e6a2699f193b9e1287588278a570235@epcas5p1.samsung.com>
 <20220113121143.22280-19-alim.akhtar@samsung.com>
Message-ID: <dc400642-418b-6bc3-f4f8-0770c0ed4671@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds compatible and port configuration for
> spi controller for Tesla Full Self-Driving SoC.
> 
> Cc: linux-fsd at tesla.com
> Cc: broonie at kernel.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/spi/spi-s3c64xx.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 8755cd85e83c..8d0c1f03ab7a 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -1442,6 +1442,16 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
>  	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
>  };
>  
> +static struct s3c64xx_spi_port_config fsd_spi_port_config = {
> +	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
> +	.rx_lvl_offset	= 15,
> +	.tx_st_done	= 25,
> +	.high_speed	= true,
> +	.clk_from_cmu	= true,
> +	.clk_ioclk	= false,
> +	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
> +};
> +
>  static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
>  	{
>  		.name		= "s3c2443-spi",
> @@ -1472,6 +1482,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
>  	{ .compatible = "samsung,exynos5433-spi",
>  			.data = (void *)&exynos5433_spi_port_config,
>  	},
> +	{ .compatible = "tesla,fsd-spi",
> +			.data = (void *)&fsd_spi_port_config,
> +	},

Looks good, except the discussion about too generic compatible.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:30:06 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:30:06 +0100
Subject: [PATCH 19/23] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220113121143.22280-20-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122440epcas5p4651d7cb2fc6d6a70fd5eaab5eadcf996@epcas5p4.samsung.com>
 <20220113121143.22280-20-alim.akhtar@samsung.com>
Message-ID: <9c3ef183-2872-f070-4d22-0ab2e79d2555@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> From: Aswani Reddy <aswani.reddy at samsung.com>
> 
> This patch add device tree node for SPI IPs and needed
> GPIO pin configurations needed for SPI IP
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd.dts  | 12 +++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi | 57 ++++++++++++++++++++++++++++++
>  2 files changed, 69 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:32:12 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:32:12 +0100
Subject: [PATCH 20/23] dt-bindings: iio: adc: exynos-adc: Add ADC-V3
 variant
In-Reply-To: <20220113121143.22280-21-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122447epcas5p266d44c8df143229d22dfa700c285a786@epcas5p2.samsung.com>
 <20220113121143.22280-21-alim.akhtar@samsung.com>
Message-ID: <75ae8b8c-e416-5007-b995-f1317ef207d4@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds a new compatible string for exynos's ADC-V3 variant.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../devicetree/bindings/iio/adc/samsung,exynos-adc.yaml          | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> index 81c87295912c..9303053759ca 100644
> --- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> @@ -14,6 +14,7 @@ properties:
>      enum:
>        - samsung,exynos-adc-v1                 # Exynos5250
>        - samsung,exynos-adc-v2
> +      - samsung,exynos-adc-v3

Please use SoC-specific compatible. IP block versions are tricky because:
1. Documentation/datasheet mentioning which SoC has which block version
are not public.
2. Neither are public the datasheets for ADC blocks.
3. The versioning of IP blocks can be inaccurate.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:33:31 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:33:31 +0100
Subject: [PATCH 22/23] arm64: dts: fsd: Add ADC device tree node
In-Reply-To: <20220113121143.22280-23-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122456epcas5p35f6406ab03af58d2e56b0b7304d4d002@epcas5p3.samsung.com>
 <20220113121143.22280-23-alim.akhtar@samsung.com>
Message-ID: <7431da93-d3df-9c32-f614-0b6c95ed016a@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> This patch adds ADC device tree node and enables the same
> on fsd platform.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd.dts  |  4 ++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi | 11 +++++++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
> index 7f3bb6212e50..dd6c75fc3221 100644
> --- a/arch/arm64/boot/dts/tesla/fsd.dts
> +++ b/arch/arm64/boot/dts/tesla/fsd.dts
> @@ -150,3 +150,7 @@
>  &spi_2 {
>  	status = "okay";
>  };
> +
> +&adc {
> +	status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
> index 7e687c6f74f6..058a9d381aed 100644
> --- a/arch/arm64/boot/dts/tesla/fsd.dtsi
> +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
> @@ -788,6 +788,17 @@
>  			num-cs = <1>;
>  			status = "disabled";
>  		};
> +
> +		adc: adc at 141A0000 {

lowercase hex numbers please.

> +			compatible = "samsung,exynos-adc-v3";
> +			reg = <0x0 0x141A0000 0x0 0x100>;
> +			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clock_peric PERIC_PCLK_ADCIF>;
> +			clock-names = "adc";
> +			#io-channel-cells = <1>;
> +			io-channel-ranges;
> +			status = "disabled";

This does not pass dtschema. NAK.

> +		};
>  	};
>  };
>  
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Thu Jan 13 05:36:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 13 Jan 2022 14:36:30 +0100
Subject: [PATCH 23/23] clocksource: exynos_mct: Add support for handling
 three clusters
In-Reply-To: <20220113121143.22280-24-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122502epcas5p37747b0c5c242c0571d294b9245963a1c@epcas5p3.samsung.com>
 <20220113121143.22280-24-alim.akhtar@samsung.com>
Message-ID: <6719ffa5-f765-6ed1-6347-6558471e6bbb@canonical.com>

On 13/01/2022 13:11, Alim Akhtar wrote:
> From: Aswani Reddy <aswani.reddy at samsung.com>
> 
> This patch adds support for handling thress clusters
> (upto 12 CPUs)
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clocksource/exynos_mct.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
> index 5e3e96d3d1b9..ba3af940a687 100644
> --- a/drivers/clocksource/exynos_mct.c
> +++ b/drivers/clocksource/exynos_mct.c
> @@ -78,6 +78,10 @@ enum {
>  	MCT_L5_IRQ,
>  	MCT_L6_IRQ,
>  	MCT_L7_IRQ,
> +	MCT_L8_IRQ,
> +	MCT_L9_IRQ,
> +	MCT_L10_IRQ,
> +	MCT_L11_IRQ,

I think this should be variable, based on SoC compatible. The mistake
was done already when adding Exynos5420 support by Linaro/Samsung, but
at least let's correct it now.

Older MCTs/SoCs do not support 12 local interrupts, so they do not need
and should not register so many interrupts.


Best regards,
Krzysztof


From xueshuai at linux.alibaba.com  Thu Jan 13 05:38:30 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 13 Jan 2022 21:38:30 +0800
Subject: [RESEND PATCH v4] ACPI: Move sdei_init and ghes_init ahead to
 handle platform errors earlier
In-Reply-To: <75dedf3a-41c7-980e-a8a8-74d116ae6663@linux.alibaba.com>
References: <20211224001716.GA1324143@bhelgaas>
 <75dedf3a-41c7-980e-a8a8-74d116ae6663@linux.alibaba.com>
Message-ID: <8e6ee387-7dc1-6c8a-c13f-ec06621e3efa@linux.alibaba.com>

Hi, Bjorn, Rafael,

Happy New Year :)

I am wondering that do you have any comment to this implementation? Any feedback
are welcomed.

Thank you.

Best regrads,
Shuai

? 2021/12/24 PM4:55, Shuai Xue ??:
> Hi, Bjorn,
> 
> Thank you for your comments.
> 
> ? 2021/12/24 AM8:17, Bjorn Helgaas ??:
>> [+to Rafael, question about HEST/GHES/SDEI init]
>>
>> On Thu, Dec 23, 2021 at 04:11:11PM +0800, Shuai Xue wrote:
>>> ? 2021/12/22 AM7:17, Bjorn Helgaas ??:
>>>> On Thu, Dec 16, 2021 at 09:34:56PM +0800, Shuai Xue wrote:
>>>>> On an ACPI system, ACPI is initialised very early from a subsys_initcall(),
>>>>> while SDEI is not ready until a subsys_initcall_sync().
>>>>>
>>>>> The SDEI driver provides functions (e.g. apei_sdei_register_ghes,
>>>>> apei_sdei_unregister_ghes) to register or unregister event callback for
>>>>> dispatcher in firmware. When the GHES driver probing, it registers the
>>>>> corresponding callback according to the notification type specified by
>>>>> GHES. If the GHES notification type is SDEI, the GHES driver will call
>>>>> apei_sdei_register_ghes to register event call.
>>>>>
>>>>> When the firmware emits an event, it migrates the handling of the event
>>>>> into the kernel at the registered entry-point __sdei_asm_handler. And
>>>>> finally, the kernel will call the registered event callback and return
>>>>> status_code to indicate the status of event handling. SDEI_EV_FAILED
>>>>> indicates that the kernel failed to handle the event.
>>>>>
>>>>> Consequently, when an error occurs during kernel booting, the kernel is
>>>>> unable to handle and report errors until the GHES driver is initialized by
>>>>> device_initcall(), in which the event callback is registered. All errors
>>>>> that occurred before GHES initialization are missed and there is no chance
>>>>> to report and find them again.
>>>>>
>>>>> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
>>>>> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
>>>>> the estatus memory pool. On the other hand, ghes_init() relies on
>>>>> sdei_init() to detect the SDEI version and the framework for registering
>>>>> and unregistering events.
>>>>
>>>>> By the way, I don't figure out why acpi_hest_init is called in
>>>>> acpi_pci_root_init, it don't rely on any other thing. May it could
>>>>> be moved further, following acpi_iort_init in acpi_init.
>>
>>>>> sdei_init() relies on ACPI table which is initialized
>>>>> subsys_initcall(): acpi_init(), acpi_bus_init(), acpi_load_tables(),
>>>>> acpi_tb_laod_namespace().  May it should be also moved further,
>>>>> after acpi_load_tables.
>>
>>>>> In this patch, move sdei_init and ghes_init as far ahead as
>>>>> possible, right after acpi_hest_init().
>>>>
>>>> I'm having a hard time figuring out the reason for this patch.
>>>>
>>>> Apparently the relevant parts are sdei_init() and ghes_init().
>>>> Today they are executed in that order:
>>>>
>>>>   subsys_initcall_sync(sdei_init);
>>>>   device_initcall(ghes_init);
>>>>
>>>> After this patch, they would be executed in the same order, but called
>>>> explicitly instead of as initcalls:
>>>>
>>>>   acpi_pci_root_init()
>>>>   {
>>>>     acpi_hest_init();
>>>>     sdei_init();
>>>>     ghes_init();
>>>>     ...
>>>>
>>>> Explicit calls are certainly better than initcalls, but that doesn't
>>>> seem to be the reason for this patch.
>>>>
>>>> Does this patch fix a bug?  If so, what is the bug?
>>>
>>> Yes. When the kernel booting, the console logs many times from firmware
>>> before GHES drivers init:
>>>
>>> 	Trip in MM PCIe RAS handle(Intr:910)
>>>   	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
>>> 	Find RP(98:1.0)
>>> 	--Walk dev(98:1.0) CE:0 UCE:4000
>>> 	...
>>> 	ERROR:   sdei_dispatch_event(32a) ret:-1
>>> 	--handler(910) end
>>>
>>> This is because the callback function has not been registered yet.
>>> Previously reported errors will be overwritten by new ones. Therefore,
>>> all errors that occurred before GHES initialization are missed
>>> and there is no chance to report and find them again.
>>>
>>>> You say that currently "errors that occur before GHES initialization
>>>> are missed".  Isn't that still true after this patch?  Does this patch
>>>> merely reduce the time before GHES initialization?  If so, I'm
>>>> dubious, because we have to tolerate an arbitrary amount of time
>>>> there.
>>>
>>> After this patch, there are still errors missing. As you mentioned,
>>> we have to tolerate it until the software reporting capability is built.
>>>
>>> Yes, this patch merely reduce the time before GHES initialization.
>>
>> It's not a bug that errors that happen before the callback are lost.
>> At least, it's not a *Linux* bug.  It might be a poor design of the
>> firmware error reporting interface.
>>
>> If the only point of this patch is to reduce the time before GHES
>> initialization, the commit log should clearly say that.
> 
> Yep, it is a design defect of firmware. I will explicitly document
> the purpose of this patch in next version.
> 
>>> The boot dmesg before this patch:
>>>
>>> 	[    3.688586] HEST: Table parsing has been initialized.
>>> 	...
>>> 	[   33.204340] calling  sdei_init+0x0/0x120 @ 1
>>> 	[   33.208645] sdei: SDEIv1.0 (0x0) detected in firmware.
>>> 	...
>>> 	[   36.005390] calling  ghes_init+0x0/0x11c @ 1
>>> 	[   36.190021] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
>>>
>>>
>>> After this patch, the boot dmesg like bellow:
>>>
>>> 	[    3.688664] HEST: Table parsing has been initialized.
>>> 	[    3.688691] sdei: SDEIv1.0 (0x0) detected in firmware.
>>> 	[    3.694557] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
> 
> After this patch, we use explicit call to init GHES rather than initcall.
> The GHES message here is just to prove that GHES initialization is
> advanced to 3.694557 seconds.
> 
> 
>> [Tangent: I think this GHES message is confusing.  What "APEI bit"
>> does this refer to?  The only bits I remember are the Flags bits in
>> HEST Error Source Descriptor Entries, e.g., ACPI v6.3, sec 18.3.2.
> 
> From the log code behavior, the APEI bit refers to OSC_SB_APEI_SUPPORT.
> (BIT 4, ACPI v6.4, sec 6.2.11.2,  table Table 6.13 Platform-Wide _OSC
> Capabilities DWORD 2. [1])
> 
>     /* code in drivers/acpi/apei/ghes.c */
>     if (rc == 0 && osc_sb_apei_support_acked)
>         pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n");
> 
>     /* code in drivers/acpi/bus.c */
>     osc_sb_apei_support_acked =
>         capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
> 
> 
>> "WHEA _OSC" means nothing to me, and I didn't find anything useful
>> with grep, other than that "WHEA" might be an obsolete name for what
>> we now call "APEI".
> 
> Yep, WHEA is an obsolete name. I think apei_osc_setup() is added for compatibility
> in commit eccddd32ced0 ("ACPI, APEI, Add APEI bit support in generic _OSC call")'
> 
> The ACPI spec Platform-Wide OSPM Capabilities defines
> UUID "0811B06E-4A27-44F9-8D60-3CBBC22E7B48" is used in
> acpi_bus_osc_support(). The Microsoft WHEA defines
> UUID "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c" that is used
> in apei_osc_setup(). [2][3]
> 
> From the discussion[4], the GHES message is to distinguish between
> the two specs.
> 
>     To avoid confusion, can we change the message as follow.
> 
>     - generic _OSC succeeded, APEI _OSC failed: APEI firmware first mode is
>     enabled by APEI bit.
>     - generic _OSC failed, APEI _OSC succeeded: APEI firmware first mode is
>     enabled by WHEA _OSC.
>     - both succeeded: APEI firmware first mode is enabled by APEI bit and
>     WHEA _OSC.
>     - both failed: Failed to enable APEI firmware first mode!
> 
> 
>> I don't think there's anything in _OSC that mentions "firmware first."
>>
>> I don't remember anything in the spec about a way to *enable* Firmware
>> First Error Handling needing (I'm looking at ACPI v6.3, sec 18.4).
>>
>> I think the "firmware first" information is useless to the OS -- as
>> far as I can tell, the spec says nothing about anything the OS should
>> do based on the FIRMWARE_FIRST bits.]
> 
> GHES works in "Firmware First" mode to report platform hardware error
> and it depends on APEI interface. (drivers/acpi/apei/ghes.c)
> 
>    * Generic Hardware Error Source provides a way to report platform
>    * hardware errors (such as that from chipset). It works in so called
>    * "Firmware First" mode, that is, hardware errors are reported to
>    * firmware firstly, then reported to Linux by firmware.
> 
> Based on above, I think the GHES message just means that this booting
> kernel supports APEI or WHEA, and GHES report Firmware first errors on
> this machine. Is it fine to keep the message?
> 
> 
>>> As we can see, the initialization of GHES is advanced by 33 seconds.
>>> So, in my opinion, this patch is necessary, right?
>>> (It should be noted that the effect of optimization varies with the platform.)
>>
>>>>> -device_initcall(ghes_init);
>>>>
>>>>>  void __init acpi_pci_root_init(void)
>>>>>  {
>>>>>  	acpi_hest_init();
>>>>> +	sdei_init();
>>>>> +	ghes_init();
>>>>
>>>> What's the connection between PCI, SDEI, and GHES?  As far as I can
>>>> tell, SDEI and GHES are not PCI-specific, so it doesn't seem like they
>>>> should be initialized here in acpi_pci_root_init().
>>>
>>> The only reason is that acpi_hest_init() is initialized here.
>>>
>>> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
>>> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
>>> the estatus memory pool. On the other hand, ghes_init() relies on
>>> sdei_init() to detect the SDEI version and the framework for registering
>>> and unregistering events. The dependencies are as follows
>>>
>>> 	ghes_init() => acpi_hest_init()
>>> 	ghes_init() => sdei_init()
>>>
>>> I don't figure out why acpi_hest_init() is called in
>>> acpi_pci_root_init(), it don't rely on any other thing.
>>> I am wondering that should we moved all of them further? e.g.
>>> following acpi_iort_init() in acpi_init().
>>
>> I don't know why acpi_hest_init() is called from acpi_pci_root_init().
>> It looks like HEST can support error sources other than PCI (IA-32
>> Machine Checks, NMIs, GHES, etc.)  It was added by 415e12b23792
>> ("PCI/ACPI: Request _OSC control once for each root bridge (v3)");
>> maybe Rafael remembers why.
>>
>> Seem like acpi_hest_init(), sdei_init(), and ghes_init() should all go
>> somewhere else, but I don't know where.  Maybe somewhere in
>> acpi_init()?
> 
> I tried to move them into acpi_init(), and it works well.
> 
> @@ -1251,6 +1251,9 @@ static int __init acpi_init(void)
> 
>         pci_mmcfg_late_init();
>         acpi_iort_init();
> +       acpi_hest_init();
> +       sdei_init();
> +       ghes_init();
>         acpi_scan_init();
>         acpi_ec_init();
> 
> What's your opinion?
> 
> Best Regards,
> 
> Shuai
> 
> 
> [1] https://uefi.org/specs/ACPI/6.4/06_Device_Configuration/Device_Configuration.html#platform-wide-osc-capabilities-dword-2
> [2] https://www.mail-archive.com/ubuntu-bugs at lists.ubuntu.com/msg4718503.html
> [3] http://www.guyreams.com/PDF/whea.pdf
> [4] https://patchwork.kernel.org/project/linux-acpi/patch/1308640587-24502-5-git-send-email-ying.huang at intel.com/#1978922


From broonie at kernel.org  Thu Jan 13 05:39:45 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 13 Jan 2022 13:39:45 +0000
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long based
 on RNDR
In-Reply-To: <20220113131239.1610455-1-ardb@kernel.org>
References: <20220113131239.1610455-1-ardb@kernel.org>
Message-ID: <YeAroae/ydbWpDvv@sirena.org.uk>

On Thu, Jan 13, 2022 at 02:12:39PM +0100, Ard Biesheuvel wrote:
> When support for RNDR/RNDRRS was introduced, we elected to only
> implement arch_get_random_seed_int/_long(), and back them by RNDR
> instead of RNDRRS. This was needed to prevent potential performance
> and/or starvation issues resulting from the fact that the /dev/random
> driver used to invoke these routines on various hot paths.

Reviewed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220113/cb12ffa2/attachment.sig>

From Jason at zx2c4.com  Thu Jan 13 05:41:16 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Thu, 13 Jan 2022 14:41:16 +0100
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long based
 on RNDR
In-Reply-To: <20220113131239.1610455-1-ardb@kernel.org>
References: <20220113131239.1610455-1-ardb@kernel.org>
Message-ID: <YeAr/CnkF74rCp7p@zx2c4.com>

Hi Ard,

Wow, didn't expect for this to come so fast. Excellent.

On Thu, Jan 13, 2022 at 02:12:39PM +0100, Ard Biesheuvel wrote:
> - map arch_get_random_int/_long() onto RNDR, which returns the output of
>   a DRBG that is reseeded at an implemented defined rate;

implemented -> implementation?

>  static inline bool __must_check arch_get_random_long(unsigned long *v)
>  {
> +	/*
> +	 * Only support the generic interface after we have detected
> +	 * the system wide capability, avoiding complexity with the
> +	 * cpufeature code and with potential scheduling between CPUs
> +	 * with and without the feature.
> +	 */
> +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> +		return true;
>  	return false;
>  }

Can't this just become:

  return cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v);

>  
>  static inline bool __must_check arch_get_random_int(unsigned int *v)
>  {
> +	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> +		unsigned long val;
> +
> +		if (__arm64_rndr(&val)) {
> +			*v = val;
> +			return true;
> +		}
> +	}
>  	return false;
>  }

Why not implement arch_get_random_int with the same type of flow as
arch_get_random_long?

static inline bool __must_check arch_get_random_int(unsigned int *v)
{
	unsigned long val;
	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(&val))) {
		*v = val;
		return true;
	}
	return false;
}

Or, even better, just define arch_get_random_int in terms of
arch_get_random_long:

static inline bool __must_check arch_get_random_int(unsigned int *v)
{
	unsigned long val;
	if (arch_get_random_long(&val)) {
		*v = val;
		return true;
	}
	return false;
}


> @@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
>  	}
>  
>  	/*
> -	 * Only support the generic interface after we have detected
> -	 * the system wide capability, avoiding complexity with the
> -	 * cpufeature code and with potential scheduling between CPUs
> -	 * with and without the feature.
> +	 * RNDRRS is not backed by an entropy source but by a DRBG that is
> +	 * reseeded after each invocation. This is not a 100% fit but good
> +	 * enough to implement this API if no other entropy source exists.

The docs are actually a bit more optimistic than that:

https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/RNDRRS--Reseeded-Random-Number

 ~ Reseeded Random Number. Returns a 64-bit random number which is reseeded
 ~ from the True Random Number source immediately before the read of the
 ~ random number.

If I'm reading that correctly, it looks like the reseeding happens
*before* the read, and it looks like it comes from a TRNG. In
other words, it sounds to me like it's just doing something like
HASH(READ_TRNG()). That would be pretty darn good.

>  	 */
> -	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
>  		return true;
>  
>  	return false;
> @@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
>  	}
>  
>  	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> -		if (__arm64_rndr(&val)) {
> +		if (__arm64_rndrrs(&val)) {
>  			*v = val;
>  			return true;
>  		}

I suppose the same control flow simplification stuff mentioned above
could be done here too, if you feel like what I mentioned earlier is
worthwhile.

>From a randomness perspective:

Acked-by: Jason A. Donenfeld <Jason at zx2c4.com>

Thanks,
Jason


From ardb at kernel.org  Thu Jan 13 05:49:15 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 13 Jan 2022 14:49:15 +0100
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long based
 on RNDR
In-Reply-To: <YeAr/CnkF74rCp7p@zx2c4.com>
References: <20220113131239.1610455-1-ardb@kernel.org>
 <YeAr/CnkF74rCp7p@zx2c4.com>
Message-ID: <CAMj1kXG1O4HfBxedxPmkOS46A4pO=-4=MUfbYXjun-ysxXn5BA@mail.gmail.com>

On Thu, 13 Jan 2022 at 14:41, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> Hi Ard,
>
> Wow, didn't expect for this to come so fast. Excellent.
>
> On Thu, Jan 13, 2022 at 02:12:39PM +0100, Ard Biesheuvel wrote:
> > - map arch_get_random_int/_long() onto RNDR, which returns the output of
> >   a DRBG that is reseeded at an implemented defined rate;
>
> implemented -> implementation?
>

Ack

> >  static inline bool __must_check arch_get_random_long(unsigned long *v)
> >  {
> > +     /*
> > +      * Only support the generic interface after we have detected
> > +      * the system wide capability, avoiding complexity with the
> > +      * cpufeature code and with potential scheduling between CPUs
> > +      * with and without the feature.
> > +      */
> > +     if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> > +             return true;
> >       return false;
> >  }
>
> Can't this just become:
>
>   return cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v);
>

Sure, but I just retained the original style.

> >
> >  static inline bool __must_check arch_get_random_int(unsigned int *v)
> >  {
> > +     if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> > +             unsigned long val;
> > +
> > +             if (__arm64_rndr(&val)) {
> > +                     *v = val;
> > +                     return true;
> > +             }
> > +     }
> >       return false;
> >  }
>
> Why not implement arch_get_random_int with the same type of flow as
> arch_get_random_long?
>
> static inline bool __must_check arch_get_random_int(unsigned int *v)
> {
>         unsigned long val;
>         if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(&val))) {
>                 *v = val;
>                 return true;
>         }
>         return false;
> }
>
> Or, even better, just define arch_get_random_int in terms of
> arch_get_random_long:
>
> static inline bool __must_check arch_get_random_int(unsigned int *v)
> {
>         unsigned long val;
>         if (arch_get_random_long(&val)) {
>                 *v = val;
>                 return true;
>         }
>         return false;
> }
>
>

If I was interested in rewriting this header file, I might consider
all these options. For now, I am just trying to focus the change on
the parts that actually matter.

> > @@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
> >       }
> >
> >       /*
> > -      * Only support the generic interface after we have detected
> > -      * the system wide capability, avoiding complexity with the
> > -      * cpufeature code and with potential scheduling between CPUs
> > -      * with and without the feature.
> > +      * RNDRRS is not backed by an entropy source but by a DRBG that is
> > +      * reseeded after each invocation. This is not a 100% fit but good
> > +      * enough to implement this API if no other entropy source exists.
>
> The docs are actually a bit more optimistic than that:
>
> https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/RNDRRS--Reseeded-Random-Number
>
>  ~ Reseeded Random Number. Returns a 64-bit random number which is reseeded
>  ~ from the True Random Number source immediately before the read of the
>  ~ random number.
>
> If I'm reading that correctly, it looks like the reseeding happens
> *before* the read, and it looks like it comes from a TRNG. In
> other words, it sounds to me like it's just doing something like
> HASH(READ_TRNG()). That would be pretty darn good.
>

No it does not. RNDR and RNDRRS both return the output of a DRBG, the
only difference is the reseed interval.

Specifically, this means that, even though the ARM ARM references NIST
SP800-90B directly, the RNDRRS construction is a black box containing
a entropy source + DRBG, and so we shouldn't pretend that RNDRRS
itself can be treated as a source of true entropy. This is especially
relevant when it comes to seeding a DRBG of a certain security
strength N >= the security strength of the hidden DRBG, as
concatenating multiple RNDRRS results does not satisfy the
requirements for seeding a DRBG of security strength N.

> >        */
> > -     if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> > +     if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
> >               return true;
> >
> >       return false;
> > @@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
> >       }
> >
> >       if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> > -             if (__arm64_rndr(&val)) {
> > +             if (__arm64_rndrrs(&val)) {
> >                       *v = val;
> >                       return true;
> >               }
>
> I suppose the same control flow simplification stuff mentioned above
> could be done here too, if you feel like what I mentioned earlier is
> worthwhile.
>
> From a randomness perspective:
>
> Acked-by: Jason A. Donenfeld <Jason at zx2c4.com>
>

Thanks,


From Jason at zx2c4.com  Thu Jan 13 05:52:06 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Thu, 13 Jan 2022 14:52:06 +0100
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long based
 on RNDR
In-Reply-To: <CAMj1kXG1O4HfBxedxPmkOS46A4pO=-4=MUfbYXjun-ysxXn5BA@mail.gmail.com>
References: <20220113131239.1610455-1-ardb@kernel.org>
 <YeAr/CnkF74rCp7p@zx2c4.com>
 <CAMj1kXG1O4HfBxedxPmkOS46A4pO=-4=MUfbYXjun-ysxXn5BA@mail.gmail.com>
Message-ID: <CAHmME9q04UxVxUFcAiGOP=7tr=Odyq7uHGCStq18NZi2F08L1A@mail.gmail.com>

On Thu, Jan 13, 2022 at 2:49 PM Ard Biesheuvel <ardb at kernel.org> wrote:
> Sure, but I just retained the original style.
> If I was interested in rewriting this header file, I might consider
> all these options. For now, I am just trying to focus the change on
> the parts that actually matter.

Okay, no problem.

> No it does not. RNDR and RNDRRS both return the output of a DRBG, the
> only difference is the reseed interval.
>
> Specifically, this means that, even though the ARM ARM references NIST
> SP800-90B directly, the RNDRRS construction is a black box containing
> a entropy source + DRBG, and so we shouldn't pretend that RNDRRS
> itself can be treated as a source of true entropy. This is especially
> relevant when it comes to seeding a DRBG of a certain security
> strength N >= the security strength of the hidden DRBG, as
> concatenating multiple RNDRRS results does not satisfy the
> requirements for seeding a DRBG of security strength N.

Huh, interesting. I wonder why that arm.com documentation page is wrong.

Jason


From alexandru.elisei at arm.com  Thu Jan 13 06:10:39 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 13 Jan 2022 14:10:39 +0000
Subject: [PATCH v5 07/69] KVM: arm64: nv: Introduce nested virtualization
 VCPU feature
In-Reply-To: <20211129200150.351436-8-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-8-maz@kernel.org>
Message-ID: <YeAy371xsAUiSzj+@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:48PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> Introduce the feature bit and a primitive that checks if the feature is
> set behind a static key check based on the cpus_have_const_cap check.
> 
> Checking nested_virt_in_use() on systems without nested virt enabled
> should have neglgible overhead.
> 
> We don't yet allow userspace to actually set this feature.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_nested.h | 14 ++++++++++++++
>  arch/arm64/include/uapi/asm/kvm.h   |  1 +
>  2 files changed, 15 insertions(+)
>  create mode 100644 arch/arm64/include/asm/kvm_nested.h
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> new file mode 100644
> index 000000000000..1028ac65a897
> --- /dev/null
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ARM64_KVM_NESTED_H
> +#define __ARM64_KVM_NESTED_H
> +
> +#include <linux/kvm_host.h>
> +
> +static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
> +{
> +	return (!__is_defined(__KVM_NVHE_HYPERVISOR__) &&
> +		cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
> +		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));

kvm_vcpu_init_nested() checks the ARM64_HAS_NESTED_VIRT cap before setting
the features bit, so I guess you can drop this check here if you're
interested in correctness.

But the reason the cap check done is performance, right? Same with the NVHE
define.

Thanks,
Alex

> +}
> +
> +#endif /* __ARM64_KVM_NESTED_H */
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index b3edde68bc3e..395a4c039bcc 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -106,6 +106,7 @@ struct kvm_regs {
>  #define KVM_ARM_VCPU_SVE		4 /* enable SVE for this CPU */
>  #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
>  #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
> +#define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
>  
>  struct kvm_vcpu_init {
>  	__u32 target;
> -- 
> 2.30.2
> 


From lkp at intel.com  Thu Jan 13 06:17:50 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 13 Jan 2022 22:17:50 +0800
Subject: [xilinx-xlnx:master 269/326] zynqmp-fpga.c:(.text+0x7c0): multiple
 definition of `zynqmp_pm_get_meta_header';
 drivers/crypto/xilinx/zynqmp-aes-gcm.o:zynqmp-aes-gcm.c:(.text+0x1160):
 first defined here
Message-ID: <202201132200.RHfvPbwI-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 22272cc48b5399af99792722fa7004735b769e0a [269/326] firmware: xilinx: Add support to get the image meta-header info
config: ia64-randconfig-r014-20220113 (https://download.01.org/0day-ci/archive/20220113/202201132200.RHfvPbwI-lkp at intel.com/config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/22272cc48b5399af99792722fa7004735b769e0a
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 22272cc48b5399af99792722fa7004735b769e0a
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=ia64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   ia64-linux-ld: drivers/fpga/zynqmp-fpga.o: in function `zynqmp_pm_get_meta_header':
>> zynqmp-fpga.c:(.text+0x7c0): multiple definition of `zynqmp_pm_get_meta_header'; drivers/crypto/xilinx/zynqmp-aes-gcm.o:zynqmp-aes-gcm.c:(.text+0x1160): first defined here
   ia64-linux-ld: drivers/fpga/versal-fpga.o: in function `zynqmp_pm_get_meta_header':
   versal-fpga.c:(.text+0x460): multiple definition of `zynqmp_pm_get_meta_header'; drivers/crypto/xilinx/zynqmp-aes-gcm.o:zynqmp-aes-gcm.c:(.text+0x1160): first defined here

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From arnd at arndb.de  Thu Jan 13 06:23:57 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 13 Jan 2022 15:23:57 +0100
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <55c22c3a-57ea-3320-ccb9-f03643563235@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
 <20220113121143.22280-15-alim.akhtar@samsung.com>
 <55c22c3a-57ea-3320-ccb9-f03643563235@canonical.com>
Message-ID: <CAK8P3a0etf+AybUe5O9uRLAbo4J145t0-ThkEccNtKzue+0-qA@mail.gmail.com>

On Thu, Jan 13, 2022 at 2:16 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
> >  ARM/TETON BGA MACHINE SUPPORT
> >  M:   "Mark F. Brown" <mark.brown314 at gmail.com>
> >  L:   linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> > diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> > index 54e3910e8b9b..bb8a047c2359 100644
> > --- a/arch/arm64/Kconfig.platforms
> > +++ b/arch/arm64/Kconfig.platforms
> > @@ -267,6 +267,12 @@ config ARCH_TEGRA
> >       help
> >         This enables support for the NVIDIA Tegra SoC family.
> >
> > +config ARCH_TESLA_FSD
> > +     bool "ARMv8 based Tesla platform"
> > +     select ARCH_EXYNOS
>
> How similar it is? I think it is better to duplicate Exynos
> selections/options here, instead of selecting entire ARCH. If this would
> require "depends on ARCH_EXYNOS || ARCH_TESLA_FSD" everywhere in the
> drivers, it's a hint that it is not a separate SoC but it is an Exynos,
> so it might not need a new sub-architecture.

Agreed, the SoC family options mainly exist so we can quickly enable or
disable drivers based on what a kernel is built for. If most of the drivers
for this SoC are shared with Exynos, I think having a single option is
sufficient, but it may be worth pointing out both in the help text.

If we want to have a separate option (mainly to help users find it), maybe
a 'depends on ARCH_EXYNOS' would be better. How many uses of
ARCH_TESLA_FSD are there?

        Arnd


From maz at kernel.org  Thu Jan 13 06:24:47 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 13 Jan 2022 14:24:47 +0000
Subject: [PATCH v5 07/69] KVM: arm64: nv: Introduce nested virtualization
 VCPU feature
In-Reply-To: <YeAy371xsAUiSzj+@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-8-maz@kernel.org>
 <YeAy371xsAUiSzj+@monolith.localdoman>
Message-ID: <87mtjz90i8.wl-maz@kernel.org>

On Thu, 13 Jan 2022 14:10:39 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:48PM +0000, Marc Zyngier wrote:
> > From: Christoffer Dall <christoffer.dall at arm.com>
> > 
> > Introduce the feature bit and a primitive that checks if the feature is
> > set behind a static key check based on the cpus_have_const_cap check.
> > 
> > Checking nested_virt_in_use() on systems without nested virt enabled
> > should have neglgible overhead.
> > 
> > We don't yet allow userspace to actually set this feature.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/kvm_nested.h | 14 ++++++++++++++
> >  arch/arm64/include/uapi/asm/kvm.h   |  1 +
> >  2 files changed, 15 insertions(+)
> >  create mode 100644 arch/arm64/include/asm/kvm_nested.h
> > 
> > diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> > new file mode 100644
> > index 000000000000..1028ac65a897
> > --- /dev/null
> > +++ b/arch/arm64/include/asm/kvm_nested.h
> > @@ -0,0 +1,14 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +#ifndef __ARM64_KVM_NESTED_H
> > +#define __ARM64_KVM_NESTED_H
> > +
> > +#include <linux/kvm_host.h>
> > +
> > +static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
> > +{
> > +	return (!__is_defined(__KVM_NVHE_HYPERVISOR__) &&
> > +		cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
> > +		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
> 
> kvm_vcpu_init_nested() checks the ARM64_HAS_NESTED_VIRT cap before setting
> the features bit, so I guess you can drop this check here if you're
> interested in correctness.
> 
> But the reason the cap check done is performance, right? Same with the NVHE
> define.

Exactly. The capability check allows us to use a static key to bypass
the test_bit() when NV isn't enable, which is 100% of our use cases.
Given that this checked fairly often on some of the fast paths, it is
worth doing it.

The NVHE check goes even further by allowing some dead code removal in
the nVHE-specific code, which cannot use NV by construction.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From claudiu.beznea at microchip.com  Thu Jan 13 06:48:50 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:50 +0200
Subject: [PATCH v2 00/10] ARM: at91: add cpu idle and cpufreq opps for sama7g5
Message-ID: <20220113144900.906370-1-claudiu.beznea@microchip.com>


Hi,

This series adds CPU idle support for SAMA7G5. Along with this the
CPUFreq OPPs for SAMA7G5 and proper config has been added.

Thank you,
Claudiu Beznea

Changes in v2:
- collected tags
- add "opp-suspend" to 600MHz OPP on patch "ARM: dts: at91: sama7g5: add opps"
- add patches:
	ARM: dts: at91: fix low limit for CPU regulator
	ARM: dts: at91: sama7g5ek: set regulator voltages for standby state

Claudiu Beznea (10):
  ARM: at91: ddr: remove CONFIG_SOC_SAMA7 dependency
  ARM: at91: ddr: align macro definitions
  ARM: at91: ddr: fix typo to align with datasheet naming
  ARM: at91: PM: add cpu idle support for sama7g5
  ARM: at91: Kconfig: select PM_OPP
  ARM: dts: at91: fix low limit for CPU regulator
  ARM: dts: at91: sama7g5ek: set regulator voltages for standby state
  ARM: dts: at91: sama7g5: add opps
  ARM: configs: at91: sama7: enable cpu idle
  ARM: configs: at91: sama7: add config for cpufreq

 arch/arm/boot/dts/at91-sama7g5ek.dts |  7 ++++-
 arch/arm/boot/dts/sama7g5.dtsi       | 38 ++++++++++++++++++++++++++++
 arch/arm/configs/sama7_defconfig     |  9 ++++++-
 arch/arm/mach-at91/Kconfig           |  1 +
 arch/arm/mach-at91/pm.c              | 27 +++++++++++++++++++-
 arch/arm/mach-at91/pm_suspend.S      |  4 +--
 include/linux/clk/at91_pmc.h         |  4 +++
 include/soc/at91/sama7-ddr.h         | 15 +++++------
 8 files changed, 91 insertions(+), 14 deletions(-)

-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:51 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:51 +0200
Subject: [PATCH v2 01/10] ARM: at91: ddr: remove CONFIG_SOC_SAMA7 dependency
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-2-claudiu.beznea@microchip.com>

Remove CONFIG_SOC_SAMA7 dependency to avoid having #ifdef preprocessor
directives in driver code (arch/arm/mach-at91/pm.c). This prepares the
code for next commits.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 include/soc/at91/sama7-ddr.h | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
index f6542584ca13..13b47e26cdbe 100644
--- a/include/soc/at91/sama7-ddr.h
+++ b/include/soc/at91/sama7-ddr.h
@@ -11,8 +11,6 @@
 #ifndef __SAMA7_DDR_H__
 #define __SAMA7_DDR_H__
 
-#ifdef CONFIG_SOC_SAMA7
-
 /* DDR3PHY */
 #define DDR3PHY_PIR				(0x04)		/* DDR3PHY PHY Initialization Register	*/
 #define	DDR3PHY_PIR_DLLBYP		(1 << 17)	/* DLL Bypass */
@@ -75,6 +73,4 @@
 #define UDDRC_PCTRL_3				(0x6A0)		/* UDDRC Port 3 Control Register */
 #define UDDRC_PCTRL_4				(0x750)		/* UDDRC Port 4 Control Register */
 
-#endif /* CONFIG_SOC_SAMA7 */
-
 #endif /* __SAMA7_DDR_H__ */
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:52 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:52 +0200
Subject: [PATCH v2 02/10] ARM: at91: ddr: align macro definitions
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-3-claudiu.beznea@microchip.com>

Align all macro definitions.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 include/soc/at91/sama7-ddr.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
index 13b47e26cdbe..817b360efbb8 100644
--- a/include/soc/at91/sama7-ddr.h
+++ b/include/soc/at91/sama7-ddr.h
@@ -13,11 +13,11 @@
 
 /* DDR3PHY */
 #define DDR3PHY_PIR				(0x04)		/* DDR3PHY PHY Initialization Register	*/
-#define	DDR3PHY_PIR_DLLBYP		(1 << 17)	/* DLL Bypass */
+#define	DDR3PHY_PIR_DLLBYP			(1 << 17)	/* DLL Bypass */
 #define		DDR3PHY_PIR_ITMSRST		(1 << 4)	/* Interface Timing Module Soft Reset */
-#define	DDR3PHY_PIR_DLLLOCK		(1 << 2)	/* DLL Lock */
+#define	DDR3PHY_PIR_DLLLOCK			(1 << 2)	/* DLL Lock */
 #define		DDR3PHY_PIR_DLLSRST		(1 << 1)	/* DLL Soft Rest */
-#define	DDR3PHY_PIR_INIT		(1 << 0)	/* Initialization Trigger */
+#define	DDR3PHY_PIR_INIT			(1 << 0)	/* Initialization Trigger */
 
 #define DDR3PHY_PGCR				(0x08)		/* DDR3PHY PHY General Configuration Register */
 #define		DDR3PHY_PGCR_CKDV1		(1 << 13)	/* CK# Disable Value */
@@ -65,7 +65,7 @@
 #define		UDDRC_SWSTAT_SW_DONE_ACK	(1 << 0)	/* Register programming done */
 
 #define UDDRC_PSTAT				(0x3FC)		/* UDDRC Port Status Register */
-#define	UDDRC_PSTAT_ALL_PORTS		(0x1F001F)	/* Read + writes outstanding transactions on all ports */
+#define	UDDRC_PSTAT_ALL_PORTS			(0x1F001F)	/* Read + writes outstanding transactions on all ports */
 
 #define UDDRC_PCTRL_0				(0x490)		/* UDDRC Port 0 Control Register */
 #define UDDRC_PCTRL_1				(0x540)		/* UDDRC Port 1 Control Register */
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:53 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:53 +0200
Subject: [PATCH v2 03/10] ARM: at91: ddr: fix typo to align with datasheet
 naming
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-4-claudiu.beznea@microchip.com>

Fix typo on UDDRC_PWRCTL.SELFREF_SW bitmask to align with datasheet
naming.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/mach-at91/pm_suspend.S | 4 ++--
 include/soc/at91/sama7-ddr.h    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S
index fdb4f63ecde4..abe4ced33eda 100644
--- a/arch/arm/mach-at91/pm_suspend.S
+++ b/arch/arm/mach-at91/pm_suspend.S
@@ -159,7 +159,7 @@ sr_ena_1:
 
 	/* Switch to self-refresh. */
 	ldr	tmp1, [r2, #UDDRC_PWRCTL]
-	orr	tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+	orr	tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
 	str	tmp1, [r2, #UDDRC_PWRCTL]
 
 sr_ena_2:
@@ -276,7 +276,7 @@ sr_dis_5:
 
 	/* Trigger self-refresh exit. */
 	ldr	tmp1, [r2, #UDDRC_PWRCTL]
-	bic	tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW
+	bic	tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW
 	str	tmp1, [r2, #UDDRC_PWRCTL]
 
 sr_dis_6:
diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
index 817b360efbb8..fee1b11bddca 100644
--- a/include/soc/at91/sama7-ddr.h
+++ b/include/soc/at91/sama7-ddr.h
@@ -53,7 +53,7 @@
 #define		UDDRC_STAT_OPMODE_MSK		(0x7 << 0)	/* Operating mode mask */
 
 #define UDDRC_PWRCTL				(0x30)		/* UDDRC Low Power Control Register */
-#define		UDDRC_PWRCTRL_SELFREF_SW	(1 << 5)	/* Software self-refresh */
+#define		UDDRC_PWRCTL_SELFREF_SW		(1 << 5)	/* Software self-refresh */
 
 #define UDDRC_DFIMISC				(0x1B0)		/* UDDRC DFI Miscellaneous Control Register */
 #define		UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN (1 << 0)	/* PHY initialization complete enable signal */
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:54 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:54 +0200
Subject: [PATCH v2 04/10] ARM: at91: PM: add cpu idle support for sama7g5
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-5-claudiu.beznea@microchip.com>

Add CPU idle support for SAMA7G5. Support will make use of PMC_CPU_RATIO
register to divide the CPU clock by 16 before switching it to idle and
use automatic self-refresh option of DDR controller.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
Acked-by: Stephen Boyd <sboyd at kernel.org>
---
 arch/arm/mach-at91/pm.c      | 27 ++++++++++++++++++++++++++-
 include/linux/clk/at91_pmc.h |  4 ++++
 include/soc/at91/sama7-ddr.h |  1 +
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index dd6f4ce3f766..0fd609e26615 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -605,6 +605,30 @@ static void at91sam9_sdram_standby(void)
 		at91_ramc_write(1, AT91_SDRAMC_LPR, saved_lpr1);
 }
 
+static void sama7g5_standby(void)
+{
+	int pwrtmg, ratio;
+
+	pwrtmg = readl(soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+	ratio = readl(soc_pm.data.pmc + AT91_PMC_RATIO);
+
+	/*
+	 * Place RAM into self-refresh after a maximum idle clocks. The maximum
+	 * idle clocks is configured by bootloader in
+	 * UDDRC_PWRMGT.SELFREF_TO_X32.
+	 */
+	writel(pwrtmg | UDDRC_PWRCTL_SELFREF_EN,
+	       soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+	/* Divide CPU clock by 16. */
+	writel(ratio & ~AT91_PMC_RATIO_RATIO, soc_pm.data.pmc + AT91_PMC_RATIO);
+
+	cpu_do_idle();
+
+	/* Restore previous configuration. */
+	writel(ratio, soc_pm.data.pmc + AT91_PMC_RATIO);
+	writel(pwrtmg, soc_pm.data.ramc[0] + UDDRC_PWRCTL);
+}
+
 struct ramc_info {
 	void (*idle)(void);
 	unsigned int memctrl;
@@ -615,6 +639,7 @@ static const struct ramc_info ramc_infos[] __initconst = {
 	{ .idle = at91sam9_sdram_standby, .memctrl = AT91_MEMCTRL_SDRAMC},
 	{ .idle = at91_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
 	{ .idle = sama5d3_ddr_standby, .memctrl = AT91_MEMCTRL_DDRSDR},
+	{ .idle = sama7g5_standby, },
 };
 
 static const struct of_device_id ramc_ids[] __initconst = {
@@ -622,7 +647,7 @@ static const struct of_device_id ramc_ids[] __initconst = {
 	{ .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] },
 	{ .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] },
 	{ .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] },
-	{ .compatible = "microchip,sama7g5-uddrc", },
+	{ .compatible = "microchip,sama7g5-uddrc", .data = &ramc_infos[4], },
 	{ /*sentinel*/ }
 };
 
diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h
index ccb3f034bfa9..3484309b59bf 100644
--- a/include/linux/clk/at91_pmc.h
+++ b/include/linux/clk/at91_pmc.h
@@ -78,6 +78,10 @@
 #define		AT91_PMC_MAINRDY	(1	<< 16)		/* Main Clock Ready */
 
 #define	AT91_CKGR_PLLAR		0x28			/* PLL A Register */
+
+#define	AT91_PMC_RATIO		0x2c			/* Processor clock ratio register [SAMA7G5 only] */
+#define		AT91_PMC_RATIO_RATIO	(0xf)		/* CPU clock ratio. */
+
 #define	AT91_CKGR_PLLBR		0x2c			/* PLL B Register */
 #define		AT91_PMC_DIV		(0xff  <<  0)		/* Divider */
 #define		AT91_PMC_PLLCOUNT	(0x3f  <<  8)		/* PLL Counter */
diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h
index fee1b11bddca..9e17247474fa 100644
--- a/include/soc/at91/sama7-ddr.h
+++ b/include/soc/at91/sama7-ddr.h
@@ -53,6 +53,7 @@
 #define		UDDRC_STAT_OPMODE_MSK		(0x7 << 0)	/* Operating mode mask */
 
 #define UDDRC_PWRCTL				(0x30)		/* UDDRC Low Power Control Register */
+#define		UDDRC_PWRCTL_SELFREF_EN		(1 << 0)	/* Automatic self-refresh */
 #define		UDDRC_PWRCTL_SELFREF_SW		(1 << 5)	/* Software self-refresh */
 
 #define UDDRC_DFIMISC				(0x1B0)		/* UDDRC DFI Miscellaneous Control Register */
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:55 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:55 +0200
Subject: [PATCH v2 05/10] ARM: at91: Kconfig: select PM_OPP
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-6-claudiu.beznea@microchip.com>

Select PM_OPP. This is requested for CPUFreq driver.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/mach-at91/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 02f6b108fd5d..279810381256 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -63,6 +63,7 @@ config SOC_SAMA7G5
 	select HAVE_AT91_GENERATED_CLK
 	select HAVE_AT91_SAM9X60_PLL
 	select HAVE_AT91_UTMI
+	select PM_OPP
 	select SOC_SAMA7
 	help
 	  Select this if you are using one of Microchip's SAMA7G5 family SoC.
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:56 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:56 +0200
Subject: [PATCH v2 06/10] ARM: dts: at91: fix low limit for CPU regulator
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-7-claudiu.beznea@microchip.com>

Fix low limit for CPU regulator. Otherwise setting voltages lower than
1.125V will not be allowed (CPUFreq will not be allowed to set proper
voltages on proper frequencies).

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 0e1975c6812e..50f0fc3064cc 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -236,7 +236,7 @@ regulator-state-mem {
 
 				vddcpu: VDD_OTHER {
 					regulator-name = "VDD_OTHER";
-					regulator-min-microvolt = <1125000>;
+					regulator-min-microvolt = <1050000>;
 					regulator-max-microvolt = <1850000>;
 					regulator-initial-mode = <2>;
 					regulator-allowed-modes = <2>, <4>;
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:57 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:57 +0200
Subject: [PATCH v2 07/10] ARM: dts: at91: sama7g5ek: set regulator voltages
 for standby state
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-8-claudiu.beznea@microchip.com>

Set regulator voltages for standby state to avoid wrong behavior of
system while in standby. The CPU voltage has been chosen as being the
one corresponding to OPP=600MHz. Next commit will set the 600MHz OPP
as the suspend OPP.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/at91-sama7g5ek.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts
index 50f0fc3064cc..e48da0a053ec 100644
--- a/arch/arm/boot/dts/at91-sama7g5ek.dts
+++ b/arch/arm/boot/dts/at91-sama7g5ek.dts
@@ -185,6 +185,7 @@ vdd_3v3: VDD_IO {
 
 					regulator-state-standby {
 						regulator-on-in-suspend;
+						regulator-suspend-microvolt = <3300000>;
 						regulator-mode = <4>;
 					};
 
@@ -225,6 +226,7 @@ vddcore: VDD_CORE {
 
 					regulator-state-standby {
 						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1150000>;
 						regulator-mode = <4>;
 					};
 
@@ -245,6 +247,7 @@ vddcpu: VDD_OTHER {
 
 					regulator-state-standby {
 						regulator-on-in-suspend;
+						regulator-suspend-voltage = <1050000>;
 						regulator-mode = <4>;
 					};
 
@@ -261,6 +264,7 @@ vldo1: LDO1 {
 					regulator-always-on;
 
 					regulator-state-standby {
+						regulator-suspend-voltage = <1800000>;
 						regulator-on-in-suspend;
 					};
 
@@ -275,6 +279,7 @@ vldo2: LDO2 {
 					regulator-max-microvolt = <3700000>;
 
 					regulator-state-standby {
+						regulator-suspend-voltage = <1800000>;
 						regulator-on-in-suspend;
 					};
 
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:58 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:58 +0200
Subject: [PATCH v2 08/10] ARM: dts: at91: sama7g5: add opps
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-9-claudiu.beznea@microchip.com>

Add OPPs for SAMA7G5 along with clock for CPU.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/boot/dts/sama7g5.dtsi | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index 7039311bf678..21694519155e 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -30,6 +30,44 @@ cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clocks = <&pmc PMC_TYPE_CORE PMC_CPUPLL>;
+			clock-names = "cpu";
+			operating-points-v2 = <&cpu_opp_table>;
+		};
+	};
+
+	cpu_opp_table: opp-table {
+		compatible = "operating-points-v2";
+
+		opp-90000000 {
+			opp-hz = /bits/ 64 <90000000>;
+			opp-microvolt = <1050000 1050000 1225000>;
+			clock-latency-ns = <320000>;
+		};
+
+		opp-250000000 {
+			opp-hz = /bits/ 64 <250000000>;
+			opp-microvolt = <1050000 1050000 1225000>;
+			clock-latency-ns = <320000>;
+		};
+
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1050000 1050000 1225000>;
+			clock-latency-ns = <320000>;
+			opp-suspend;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1150000 1125000 1225000>;
+			clock-latency-ns = <320000>;
+		};
+
+		opp-1000000002 {
+			opp-hz = /bits/ 64 <1000000002>;
+			opp-microvolt = <1250000 1225000 1300000>;
+			clock-latency-ns = <320000>;
 		};
 	};
 
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:48:59 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:48:59 +0200
Subject: [PATCH v2 09/10] ARM: configs: at91: sama7: enable cpu idle
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-10-claudiu.beznea@microchip.com>

Enable CPU idle support for SAMA7 config.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/configs/sama7_defconfig | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 938aae4bd80b..95c2a7ed4816 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -26,6 +26,7 @@ CONFIG_FORCE_MAX_ZONEORDER=15
 CONFIG_UACCESS_WITH_MEMCPY=y
 # CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
+CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_KERNEL_MODE_NEON=y
@@ -33,7 +34,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_EFI_PARTITION is not set
 # CONFIG_COREDUMP is not set
@@ -90,6 +90,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_EEPROM_AT24=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
+# CONFIG_BLK_DEV_BSG is not set
 CONFIG_NETDEVICES=y
 CONFIG_MACB=y
 CONFIG_MICREL_PHY=y
-- 
2.32.0



From claudiu.beznea at microchip.com  Thu Jan 13 06:49:00 2022
From: claudiu.beznea at microchip.com (Claudiu Beznea)
Date: Thu, 13 Jan 2022 16:49:00 +0200
Subject: [PATCH v2 10/10] ARM: configs: at91: sama7: add config for cpufreq
In-Reply-To: <20220113144900.906370-1-claudiu.beznea@microchip.com>
References: <20220113144900.906370-1-claudiu.beznea@microchip.com>
Message-ID: <20220113144900.906370-11-claudiu.beznea@microchip.com>

Add config flags for CPUFreq. This includes enabling CPUFreq support,
CPUFreq DT driver and governors, default one being the conservative
governor.

Signed-off-by: Claudiu Beznea <claudiu.beznea at microchip.com>
---
 arch/arm/configs/sama7_defconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 95c2a7ed4816..689e9afcb5b2 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -26,6 +26,12 @@ CONFIG_FORCE_MAX_ZONEORDER=15
 CONFIG_UACCESS_WITH_MEMCPY=y
 # CONFIG_ATAGS is not set
 CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
-- 
2.32.0



From henrik at grimler.se  Thu Jan 13 07:40:16 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Thu, 13 Jan 2022 16:40:16 +0100
Subject: [PATCH 0/3] Add initial support for exynos5420-chagallwifi
Message-ID: <20220113154019.74434-1-henrik@grimler.se>

Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename chagallwifi
and is one of several tablets released in 2013 - 2014 based on Exynos
5420.  This initial devicetree adds support for accessing device over
USB or UART, and allows using a rootfs in either the internal eMMC or
an external sdcard.  4 out of 8 CPUs are brought up when device boots,
which is the same as on the somewhat similar device
exynos5420-arndale-octa.

Patch 2 is necessary after a secure-firmware node is added, otherwise
device hangs during the CPU1BOOT secure monitor call. Without the
secure-firmware node we are not able to bring up any secondary CPUs.

Henrik Grimler (3):
  dt-bindings: arm: samsung: document chagallwifi board binding
  ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
  ARM: dts: Add support for Samsung Chagallwifi

 .../bindings/arm/samsung/samsung-boards.yaml  |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagallwifi.dts  |  57 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 647 ++++++++++++++++++
 arch/arm/mach-exynos/firmware.c               |   4 +-
 5 files changed, 709 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagallwifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi


base-commit: b1cbda0fc3431b464aa78b5f335a5d35428f10c8
-- 
2.34.1



From henrik at grimler.se  Thu Jan 13 07:40:17 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Thu, 13 Jan 2022 16:40:17 +0100
Subject: [PATCH 1/3] dt-bindings: arm: samsung: document chagallwifi board
 binding
In-Reply-To: <20220113154019.74434-1-henrik@grimler.se>
References: <20220113154019.74434-1-henrik@grimler.se>
Message-ID: <20220113154019.74434-2-henrik@grimler.se>

Add binding for Samsung Galaxy Tab S 10.5", based on Exynos 5420 with
codename chagallwifi. It was released in 2014 and has several siblings
with similar hardware.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 052cd94113d4..3f2ffb0d7b46 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -140,6 +140,7 @@ properties:
         items:
           - enum:
               - insignal,arndale-octa           # Insignal Arndale Octa
+              - samsung,chagallwifi             # Samsung SM-T800
               - samsung,smdk5420                # Samsung SMDK5420 eval
           - const: samsung,exynos5420
           - const: samsung,exynos5
-- 
2.34.1



From henrik at grimler.se  Thu Jan 13 07:40:18 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Thu, 13 Jan 2022 16:40:18 +0100
Subject: [PATCH 2/3] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
In-Reply-To: <20220113154019.74434-1-henrik@grimler.se>
References: <20220113154019.74434-1-henrik@grimler.se>
Message-ID: <20220113154019.74434-3-henrik@grimler.se>

On Exynos5 the call is simply ignored by most variants of the
trustzone firmware.  However, on some devices it instead causes the
device to hang, so let's avoid the call for the SoCs where it should
not be needed.

To see that the call is ignored, we can look into sboot/tzsw.  On most
of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
the secure monitor calls is quite easy to recognise, the SMC number is
compared to known ones, and if equal it branches to the relevant
function.  In assembly this looks something like:

;-- handle_smc:
0x00000514      650070e3       cmn r0, 0x65
0x00000518      0a00000a       beq loc.smc_cmd_reg
0x0000051c      010070e3       cmn r0, 1
0x00000520      6c00000a       beq loc.smc_cmd_init
0x00000524      020070e3       cmn r0, 2
0x00000528      6b00000a       beq loc.smc_cmd_info
0x0000052c      030070e3       cmn r0, 3
0x00000530      6e00000a       beq loc.smc_cmd_sleep
0x00000534      060070e3       cmn r0, 6
0x00000538      ae00000a       beq loc.smc_cmd_save_state
0x0000053c      070070e3       cmn r0, 7
0x00000540      b400000a       beq loc.smc_cmd_standby
0x00000544      2b01001a       bne loc.smc_return_minus1

where above example is from exynos5420-arndale-octa.  As can be seen
the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
annotations are taken from github.com/hsnaves/exynos5410-firmware,
where a large part of the exynos5410 trustzone firmware has been
reverse-engineered.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
Sent previously as RFC
---
 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
 	/*
 	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
 	 * because Exynos3250 removes WFE in secure mode.
+	 *
+	 * On Exynos5 devices the call is ignored by trustzone firmware.
 	 */
-	if (soc_is_exynos3250())
+	if (!soc_is_exynos4210() && !soc_is_exynos4412())
 		return 0;
 
 	/*
-- 
2.34.1



From henrik at grimler.se  Thu Jan 13 07:40:19 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Thu, 13 Jan 2022 16:40:19 +0100
Subject: [PATCH 3/3] ARM: dts: Add support for Samsung Chagallwifi
In-Reply-To: <20220113154019.74434-1-henrik@grimler.se>
References: <20220113154019.74434-1-henrik@grimler.se>
Message-ID: <20220113154019.74434-4-henrik@grimler.se>

Chagallwifi, with product name Samsung Galaxy Tab S 10.5", is based on
Exynos 5420. This device is one of several tablet models released in
2013 - 2014 based on Exynos 5420.

The device tree added here contains support for:

- UART
- eMMC
- SD card
- USB

CCI has been disabled in the hardware, enabling it would require
(de-)soldering a resistor on the board.  Trying to boot with it
enabled in kernel makes the device hang when CCI is probed.
Exynos5420-arndale-octa also has had CCI disabled due to issues [1].

To successfully boot the mainline kernel with the stock bootloader
(SBOOT), an additional hack is needed [2]. The same hack is also
needed to boot exynos4412-i9300 with stock bootloader, and probably
other Samsung devices of similar age.

[1] https://marc.info/?l=linux-arm-kernel&m=141718639200624
[2] https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com/

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagallwifi.dts  |  57 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 647 ++++++++++++++++++
 3 files changed, 705 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagallwifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..be7a493ff1a1 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-arndale-octa.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5420-smdk5420.dtb \
+	exynos5420-chagallwifi.dtb \
 	exynos5422-odroidhc1.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
diff --git a/arch/arm/boot/dts/exynos5420-chagallwifi.dts b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
new file mode 100644
index 000000000000..51eb2bbe6bf6
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Chagallwifi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+	model = "Samsung Chagallwifi based on exynos5420";
+	compatible = "samsung,chagallwifi", "samsung,exynos5420", \
+		     "samsung,exynos5";
+};
+
+&s2mps11 {
+	regulators {
+		ldo15_reg: LDO15 {
+			/* Unused */
+			regulator-name = "VDD_LDO15";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		ldo17_reg: LDO17 {
+			regulator-name = "VDD_IRLED_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3350000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo28_reg: LDO28 {
+			/* Unused */
+			regulator-name = "VDD_LDO28";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		ldo29_reg: LDO29 {
+			regulator-name = "VDD_TCON_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
new file mode 100644
index 000000000000..cbcf1c117b67
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
@@ -0,0 +1,647 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base DT for Samsung's family of tablets based on Exynos5420.
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include "exynos5420-cpus.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/samsung,s2mps11.h>
+
+/ {
+	compatible = "samsung,exynos5420", "samsung,exynos5";
+	chassis-type = "tablet";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x20000000 0xc0000000>;
+	};
+
+	firmware at 2073000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x02073000 0x1000>;
+	};
+
+	fixed-rate-clocks {
+		oscclk {
+			compatible = "samsung,exynos5420-oscclk";
+			clock-frequency = <24000000>;
+		};
+
+		xxti {
+			compatible = "samsung,clock-xxti";
+			clock-frequency = <24000000>;
+		};
+
+		xusbxti {
+			compatible = "samsung,clock-xusbxti";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+
+		power {
+			debounce-interval = <10>;
+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+
+		home {
+			debounce-interval = <10>;
+			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
+			label = "Home";
+			linux,code = <KEY_HOME>;
+			wakeup-source;
+		};
+
+		volume-up {
+			debounce-interval = <10>;
+			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		volume-down {
+			debounce-interval = <10>;
+			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+};
+
+&cci {
+	/* CCI is disabled in hardware */
+	status = "disabled";
+};
+
+&cpu0 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&buck6_reg>;
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&buck4_reg>;
+};
+
+&hsi2c_7 {
+	status = "okay";
+
+	s2mps11: pmic at 66 {
+		compatible = "samsung,s2mps11-pmic";
+		reg = <0x66>;
+
+		interrupt-parent = <&gpx3>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&s2mps11_irq>;
+
+		s2mps11_osc: clocks {
+			compatible = "samsung,s2mps11-clk";
+			#clock-cells = <1>;
+			clock-output-names = "s2mps11_ap", "s2mps11_cp",
+					     "s2mps11_bt";
+		};
+
+		buck1_reg: BUCK1 {
+			regulator-name = "VDD_MIF_1V1";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+				regulator-suspend-microvolt = <1100000>;
+			};
+		};
+
+		buck2_reg: BUCK2 {
+			regulator-name = "VDD_ARM_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-ramp-delay = <12500>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck3_reg: BUCK3 {
+			regulator-name = "VDD_INT_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+				regulator-suspend-microvolt = <1100000>;
+			};
+		};
+
+		buck4_reg: BUCK4 {
+			regulator-name = "VDD_G3D_1V0";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-ramp-delay = <12500>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck5_reg: BUCK5 {
+			regulator-name = "VDD_MEM_1V2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		buck6_reg: BUCK6 {
+			regulator-name = "VDD_KFC_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck7_reg: BUCK7 {
+			regulator-name = "VIN_LLDO_1V4";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+		};
+
+		buck8_reg: BUCK8 {
+			regulator-name = "VIN_MLDO_2V0";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2100000>;
+			regulator-always-on;
+		};
+
+		buck9_reg: BUCK9 {
+			regulator-name = "VIN_HLDO_3V5";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3500000>;
+			regulator-always-on;
+		};
+
+		buck10_reg: BUCK10 {
+			regulator-name = "VDD_CAM_ISP_1V0";
+			regulator-min-microvolt = <750000>;
+			regulator-max-microvolt = <3550000>;
+		};
+
+		ldo1_reg: LDO1 {
+			regulator-name = "VDD_ALIVE_1.0V";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+		};
+
+		ldo2_reg: LDO2 {
+			regulator-name = "VDD_APIO_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo3_reg: LDO3 {
+			regulator-name = "VDD_APIO_MMC2_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo4_reg: LDO4 {
+			regulator-name = "VDD_ADC_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo5_reg: LDO5 {
+			/* Unused */
+			regulato-name = "VDD_LDO5";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		ldo6_reg: LDO6 {
+			regulator-name = "VDD_MIPI_1V0";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo7_reg: LDO7 {
+			regulator-name = "VDD_MIPI_PLL_ABB1_18V";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo8_reg: LDO8 {
+			/* Unused */
+			regulator-name = "VDD_LDO8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		ldo9_reg: LDO9 {
+			regulator-name = "VDD_UOTG_3V0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo10_reg: LDO10 {
+			regulator-name = "VDDQ_PRE_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo11_reg: LDO11 {
+			regulator-name = "VDD_HSIC_1V0";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo12_reg: LDO12 {
+			regulator-name = "VDD_HSIC_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo13_reg: LDO13 {
+			regulator-name = "VDD_APIO_MMC2_2V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo14_reg: LDO14 {
+			regulator-name = "VDD_MOTOR_3V0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO15 varies between devices and is
+		 * specified in the device dts
+		 */
+
+		ldo16_reg: LDO16 {
+			regulator-name = "VDD_AP_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO17 varies between devices and is
+		 * specified in the device dts
+		 */
+
+		ldo18_reg: LDO18 {
+			/* Unused */
+			regulator-name = "VDD_LDO18";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+
+		ldo19_reg: LDO19 {
+			regulator-name = "VDD_VTF_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo20_reg: LDO20 {
+			regulator-name = "VDD_CAM1_CAM_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo21_reg: LDO21 {
+			regulator-name = "VDD_CAM_IO_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo22_reg: LDO22 {
+			regulator-name = "VDD_CAM0_S_CORE_1V1";
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1200000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo23_reg: LDO23 {
+			regulator-name = "VDD_MIFS_1V1";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		ldo24_reg: LDO24 {
+			regulator-name = "VDD_TSP_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo25_reg: LDO25 {
+			/* Unused */
+			regulator-name = "VDD_LDO25";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo26_reg: LDO26 {
+			regulator-name = "VDD_CAM0_AF_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo27_reg: LDO27 {
+			regulator-name = "VDD_G3DS_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO28 and LDO29 varies between devices and
+		 * are specified in the device dts
+		 */
+
+		ldo30_reg: LDO30 {
+			regulator-name = "VDD_TOUCH_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo31_reg: LDO31 {
+			regulator-name = "VDD_GRIP_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo32_reg: LDO32 {
+			regulator-name = "VDD_TSP_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo33_reg: LDO33 {
+			regulator-name = "VDD_MHL_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo34_reg: LDO34 {
+			regulator-name = "VDD_MHL_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo35_reg: LDO35 {
+			regulator-name = "VDD_SIL_1V2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo36_reg: LDO36 {
+			/* Unused */
+			regulator-name = "VDD_LDO36";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo37_reg: LDO37 {
+			/* Unused */
+			regulator-name = "VDD_LDO37";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo38_reg: LDO38 {
+			regulator-name = "VDD_KEY_LED_3V3";
+			regulator-min-microvolt = <2500000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
+
+&mixer {
+	status = "okay";
+};
+
+/* Internal storage */
+&mmc_0 {
+	status = "okay";
+	non-removable;
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	pinctrl-names = "default", "output";
+	clk_pin = &sd0_clk;
+	clk_val = <0x3>;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+	vmmc-supply = <&ldo3_reg>;
+	vqmmc-supply = <&ldo13_reg>;
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+};
+
+/* External sdcard */
+&mmc_2 {
+	status = "okay";
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+};
+
+&pinctrl_0 {
+	s2mps11_irq: s2mps11-irq-pins {
+		samsung,pins = "gpx3-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&tmu_cpu0 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu1 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu2 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu3 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_gpu {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd3_0 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
+
+&usbdrd3_1 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
-- 
2.34.1



From angelogioacchino.delregno at collabora.com  Thu Jan 13 07:41:32 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 16:41:32 +0100
Subject: [PATCH v3 1/7] dt-bindings: memory: mtk-smi: Rename clock to
 clocks
In-Reply-To: <20220113111057.29918-2-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-2-yong.wu@mediatek.com>
Message-ID: <c88b8a01-6048-77bc-b49d-dd58ddbe5d74@collabora.com>

Il 13/01/22 12:10, Yong Wu ha scritto:
> The property "clock" should be rename to "clocks", and delete the "items",
> the minItems/maxItems should not be put under "items".
> 
> Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 07:44:05 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 16:44:05 +0100
Subject: [PATCH v3 4/7] dt-bindings: memory: mediatek: Add mt8186 support
In-Reply-To: <20220113111057.29918-5-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-5-yong.wu@mediatek.com>
Message-ID: <153264b6-1cdb-c130-d72e-6dc29bb1afd9@collabora.com>

Il 13/01/22 12:10, Yong Wu ha scritto:
> Add mt8186 smi support in the bindings.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Acked-by: Rob Herring <robh at kernel.org>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 07:44:07 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 16:44:07 +0100
Subject: [PATCH v3 3/7] dt-bindings: memory: mtk-smi: Correct minItems to
 2 for the gals clocks
In-Reply-To: <20220113111057.29918-4-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-4-yong.wu@mediatek.com>
Message-ID: <dbaf0fa5-4900-a59d-b05d-a138464a4f39@collabora.com>

Il 13/01/22 12:10, Yong Wu ha scritto:
> Mute the warning from "make dtbs_check":
> 
> larb at 14017000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 	...
> 
> larb at 16010000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 
> larb at 17010000: clock-names: ['apb', 'smi'] is too short
> 	arch/arm64/boot/dts/mediatek/mt8183-evb.dt.yaml
> 	arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dt.yaml
> 
> If a platform's larb supports gals, there will be some larbs have one
> more "gals" clock while the others still only need "apb"/"smi" clocks,
> then the minItems for clocks and clock-names are 2.
> 
> Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 07:44:09 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 16:44:09 +0100
Subject: [PATCH v3 2/7] dt-bindings: memory: mtk-smi: No need
 mediatek,larb-id for mt8167
In-Reply-To: <20220113111057.29918-3-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-3-yong.wu@mediatek.com>
Message-ID: <65919fad-3fbc-728d-4f14-5490b59e30a9@collabora.com>

Il 13/01/22 12:10, Yong Wu ha scritto:
> Mute the warning from "make dtbs_check":
> 
> larb at 14016000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
> larb at 15001000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
> larb at 16010000: 'mediatek,larb-id' is a required property
> 	arch/arm64/boot/dts/mediatek/mt8167-pumpkin.dt.yaml
> 
> As the description of mediatek,larb-id, the property is only
> required when the larbid is not consecutive from its IOMMU point of view.
> 
> Also, from the description of mediatek,larbs in
> Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml, all the larbs
> must sort by the larb index.
> 
> In mt8167, there is only one IOMMU HW and three larbs. The drivers already
> know its larb index from the mediatek,larbs property of IOMMU, thus no
> need this property.
> 
> Fixes: 27bb0e42855a ("dt-bindings: memory: mediatek: Convert SMI to DT schema")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>





From matthias.bgg at gmail.com  Thu Jan 13 08:07:29 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 13 Jan 2022 17:07:29 +0100
Subject: [PATCH v4 0/5] Update MT8192 Clock Setting
In-Reply-To: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
References: <20220113065822.11809-1-allen-kh.cheng@mediatek.com>
Message-ID: <9d82a86a-74ea-3d2a-2d7a-64fc45042974@gmail.com>



On 13/01/2022 07:58, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> This patch is base on v5.16-rc8,
> 
> changes since v3:
>   - update that list(remove already upstream patch)
> 
> changes since v2:
>   - add missing "clock" at the end of commit message
> 
> changes since v1:
>   - update the commit message
> 
> Allen-KH Cheng (5):
>    arm64: dts: mediatek: Correct uart clock of MT8192
>    arm64: dts: mediatek: Correct SPI clock of MT8192
>    arm64: dts: mediatek: Correct Nor Flash clock of MT8192
>    arm64: dts: mediatek: Correct I2C clock of MT8192
>    arm64: dts: mediatek: Correct system timer clock of MT8192
> 

Whole series queued in v5.17-tmp/dts64 which will be renamed to v5.17-next/dts64 
as soon as v5.17-rc1 is released.

Thanks!
Matthias

>   arch/arm64/boot/dts/mediatek/mt8192.dtsi | 92 +++++++++++++-----------
>   1 file changed, 52 insertions(+), 40 deletions(-)
> 


From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:00 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:00 +0100
Subject: [PATCH v11 19/22] drm/mediatek: modify mediatek-drm for mt8195
 multi mmsys support
In-Reply-To: <20220110084645.31191-20-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-20-nancy.lin@mediatek.com>
Message-ID: <d50c21ea-c62f-7d47-80e7-1db8522b2d38@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> MT8195 have two mmsys. Modify drm for MT8195 multi-mmsys support.
> The two mmsys (vdosys0 and vdosys1) will bring up two drm drivers,
> only one drm driver register as the drm device.
> Each drm driver binds its own component. The last bind drm driver
> allocates and registers the drm device to drm core.
> Each crtc path is created with the corresponding drm driver data.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>


Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:01 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:01 +0100
Subject: [PATCH v11 20/22] drm/mediatek: add drm ovl_adaptor sub driver
 for MT8195
In-Reply-To: <20220110084645.31191-21-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-21-nancy.lin@mediatek.com>
Message-ID: <005c3f95-b456-486b-e8d3-cbeddb9bb5fb@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if
> the component exists in the path.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:03 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:03 +0100
Subject: [PATCH v11 21/22] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <20220110084645.31191-22-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-22-nancy.lin@mediatek.com>
Message-ID: <c2750134-9d7d-5aa5-196c-7785c1578e4b@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add driver data of mt8195 vdosys1 to mediatek-drm.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:05 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:05 +0100
Subject: [PATCH v11 09/22] soc: mediatek: change the mutex defines and the
 mutex_mod type
In-Reply-To: <20220110084645.31191-10-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-10-nancy.lin@mediatek.com>
Message-ID: <c8f94e10-1830-6da9-f3eb-ca973b74b330@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> This is a preparation for adding support for mt8195 vdosys1 mutex.
> The vdosys1 path component contains ovl_adaptor, merge5,
> and dp_intf1. Ovl_adaptor is composed of several sub-elements,
> so change it to support multi-bit control.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:09 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:09 +0100
Subject: [PATCH v11 10/22] soc: mediatek: add mtk-mutex support for mt8195
 vdosys1
In-Reply-To: <20220110084645.31191-11-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-11-nancy.lin@mediatek.com>
Message-ID: <64582c90-f307-5918-fb49-94e0beb2cf23@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add mtk-mutex support for mt8195 vdosys1.
> The vdosys1 path component contains ovl_adaptor, merge5,
> and dp_intf1. Ovl_adaptor is composed of several sub-elements.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:09 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:09 +0100
Subject: [PATCH v11 08/22] soc: mediatek: mmsys: modify reset controller
 for MT8195 vdosys1
In-Reply-To: <20220110084645.31191-9-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-9-nancy.lin@mediatek.com>
Message-ID: <3709d43f-48f1-a768-b2e4-3ca08651bbd3@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> MT8195 vdosys1 has more than 32 reset bits and a different reset base
> than other chips. Modify mmsys for support 64 bit and different reset
> base.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:19 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:19 +0100
Subject: [PATCH v11 06/22] soc: mediatek: add mtk-mmsys config API for
 mt8195 vdosys1
In-Reply-To: <20220110084645.31191-7-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-7-nancy.lin@mediatek.com>
Message-ID: <0ce9149b-f2ee-ef59-12a1-ff7bc5cb4978@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add mmsys config API. The config API is used for config mmsys reg.
> Some mmsys regs need to be setting according to the HW engine binding
> to the mmsys simultaneously.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:21 +0100
Subject: [PATCH v11 05/22] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys1
In-Reply-To: <20220110084645.31191-6-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-6-nancy.lin@mediatek.com>
Message-ID: <1e3ff068-3335-8402-4eb6-ec4fbda44461@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add mt8195 vdosys1 clock driver name and routing table to
> the driver data of mtk-mmsys.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 13 08:08:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 13 Jan 2022 17:08:21 +0100
Subject: [PATCH v11 07/22] soc: mediatek: add cmdq support of mtk-mmsys
 config API for mt8195 vdosys1
In-Reply-To: <20220110084645.31191-8-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-8-nancy.lin@mediatek.com>
Message-ID: <98929c87-75d2-41a4-6f50-7dbe29aeb1f3@collabora.com>

Il 10/01/22 09:46, Nancy.Lin ha scritto:
> Add cmdq support for mtk-mmsys config API.
> The mmsys config register settings need to take effect with the other
> HW settings(like OVL_ADAPTOR...) at the same vblanking time.
> 
> If we use CPU to write the mmsys reg, we can't guarantee all the
> settings can be written in the same vblanking time.
> Cmdq is used for this purpose. We prepare all the related HW settings
> in one cmdq packet. The first command in the packet is "wait stream done",
> and then following with all the HW settings. After the cmdq packet is
> flush to GCE HW. The GCE waits for the "stream done event" to coming
> and then starts flushing all the HW settings. This can guarantee all
> the settings flush in the same vblanking.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From matthias.bgg at gmail.com  Thu Jan 13 08:10:17 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 13 Jan 2022 17:10:17 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
 <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
 <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
Message-ID: <e940d705-2057-4d5e-0a21-8464ca04caaf@gmail.com>

Hi Hans,

On 13/01/2022 11:15, Hans Verkuil wrote:
> On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote:
>> Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
>>> Il 12/11/21 11:55, Yong Wu ha scritto:
>>>> After this patchset, mtk_vcodec_release_enc_pm has only one line.
>>>> then remove that function, use pm_runtime_disable instead.
>>>>
>>>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
>>>> rename it from the _pm to _clk.
>>>>
>>>> No functional change.
>>>>
>>>> CC: Tiffany Lin <tiffany.lin at mediatek.com>
>>>> CC: Irui Wang <irui.wang at mediatek.com>
>>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>>
>>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>
>>
>> Hello Yong,
>> the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans has
>> scheduled that for v5.18.
>>
>> Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the
>> media: mtk-vcodec: *) from this series?
>>
>> For the records, I think that after sending v10 this series is ready to be merged,
>> as it was well reviewed and also tested on many MTK platforms.
> 
> Good to know. When I have the v10 I'll try to prioritize reviewing it and running
> my usual tests.
> 
> Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches and fix
> any issues (using common sense).
> 

Can you please take me in the look when you take the patches. I'll take the DTS 
related as soon as you queue up the others.

Thanks!
Matthias

> Regards,
> 
> 	Hans
> 
>>
>> Thank you,
>> - Angelo
> 


From robert.hancock at calian.com  Thu Jan 13 08:22:51 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Thu, 13 Jan 2022 16:22:51 +0000
Subject: [PATCH net v2 4/9] net: axienet: add missing memory barriers
In-Reply-To: <SA1PR02MB85604DE700BA8511C604B632C7539@SA1PR02MB8560.namprd02.prod.outlook.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-5-robert.hancock@calian.com>
 <SA1PR02MB85604DE700BA8511C604B632C7539@SA1PR02MB8560.namprd02.prod.outlook.com>
Message-ID: <1596c9878c684dd559abe9088c7d90daa76b1f57.camel@calian.com>

On Thu, 2022-01-13 at 12:09 +0000, Radhey Shyam Pandey wrote:
> > -----Original Message-----
> > From: Robert Hancock <robert.hancock at calian.com>
> > Sent: Wednesday, January 12, 2022 11:07 PM
> > To: netdev at vger.kernel.org
> > Cc: Radhey Shyam Pandey <radheys at xilinx.com>; davem at davemloft.net;
> > kuba at kernel.org; linux-arm-kernel at lists.infradead.org; Michal Simek
> > <michals at xilinx.com>; ariane.keller at tik.ee.ethz.ch; daniel at iogearbox.net;
> > Robert Hancock <robert.hancock at calian.com>
> > Subject: [PATCH net v2 4/9] net: axienet: add missing memory barriers
> > 
> > This driver was missing some required memory barriers:
> > 
> > Use dma_rmb to ensure we see all updates to the descriptor after we see
> > that
> > an entry has been completed.
> > 
> > Use wmb and rmb to avoid stale descriptor status between the TX path and TX
> > complete IRQ path.
> > 
> > Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI
> > Ethernet
> > driver")
> > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > ---
> >  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 11 ++++++++++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > index f4ae035bed35..de8f85175a6c 100644
> > --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > @@ -632,6 +632,8 @@ static int axienet_free_tx_chain(struct net_device
> > *ndev, u32 first_bd,
> >  		if (nr_bds == -1 && !(status &
> > XAXIDMA_BD_STS_COMPLETE_MASK))
> >  			break;
> > 
> > +		/* Ensure we see complete descriptor update */
> > +		dma_rmb();
> >  		phys = desc_get_phys_addr(lp, cur_p);
> >  		dma_unmap_single(ndev->dev.parent, phys,
> >  				 (cur_p->cntrl &
> > XAXIDMA_BD_CTRL_LENGTH_MASK), @@ -645,8 +647,10 @@ static int
> > axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
> >  		cur_p->app1 = 0;
> >  		cur_p->app2 = 0;
> >  		cur_p->app4 = 0;
> > -		cur_p->status = 0;
> >  		cur_p->skb = NULL;
> > +		/* ensure our transmit path and device don't prematurely see
> > status cleared */
> > +		wmb();
> > +		cur_p->status = 0;
> 
> Any reason for moving status initialization down?

Probably not strictly necessary, but the idea was to ensure that any of the
other writes to the descriptor were visible before the device saw the status
being cleared (indicating it is available to be read by the device).

> 
> >  		if (sizep)
> >  			*sizep += status &
> > XAXIDMA_BD_STS_ACTUAL_LEN_MASK; @@ -704,6 +708,9 @@ static inline
> > int axienet_check_tx_bd_space(struct axienet_local *lp,
> >  					    int num_frag)
> >  {
> >  	struct axidma_bd *cur_p;
> > +
> > +	/* Ensure we see all descriptor updates from device or TX IRQ path */
> > +	rmb();
> >  	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
> >  	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
> >  		return NETDEV_TX_BUSY;
> > @@ -843,6 +850,8 @@ static void axienet_recv(struct net_device *ndev)
> > 
> >  		tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
> > 
> > +		/* Ensure we see complete descriptor update */
> > +		dma_rmb();
> >  		phys = desc_get_phys_addr(lp, cur_p);
> >  		dma_unmap_single(ndev->dev.parent, phys, lp-
> > > max_frm_size,
> >  				 DMA_FROM_DEVICE);
> 
> Ideally we would also need a write barrier in xmit function just before 
> updating tail descriptor.

I don't think it should be needed there because there is an implicit barrier on
the MMIO write.

> 
> > --
> > 2.31.1
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From robert.hancock at calian.com  Thu Jan 13 08:27:11 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Thu, 13 Jan 2022 16:27:11 +0000
Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
 reset
In-Reply-To: <SA1PR02MB8560F3EF51828D9065763968C7539@SA1PR02MB8560.namprd02.prod.outlook.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <20220112173700.873002-3-robert.hancock@calian.com>
 <SA1PR02MB8560F3EF51828D9065763968C7539@SA1PR02MB8560.namprd02.prod.outlook.com>
Message-ID: <3cf8932154c2c162dc5bf4222c7f466119cfb623.camel@calian.com>

On Thu, 2022-01-13 at 11:53 +0000, Radhey Shyam Pandey wrote:
> > -----Original Message-----
> > From: Robert Hancock <robert.hancock at calian.com>
> > Sent: Wednesday, January 12, 2022 11:07 PM
> > To: netdev at vger.kernel.org
> > Cc: Radhey Shyam Pandey <radheys at xilinx.com>; davem at davemloft.net;
> > kuba at kernel.org; linux-arm-kernel at lists.infradead.org; Michal Simek
> > <michals at xilinx.com>; ariane.keller at tik.ee.ethz.ch; daniel at iogearbox.net;
> > Robert Hancock <robert.hancock at calian.com>
> > Subject: [PATCH net v2 2/9] net: axienet: Wait for PhyRstCmplt after core
> > reset
> > 
> > When resetting the device, wait for the PhyRstCmplt bit to be set
> > in the interrupt status register before continuing initialization, to
> > ensure that the core is actually ready. The MgtRdy bit could also be
> > waited for, but unfortunately when using 7-series devices, the bit does
> 
> Just to understand - can you share 7- series design details.
> Based on documentation - This MgtRdy bit indicates if the TEMAC core is
> out of reset and ready for use. In systems that use an serial transceiver, 
> this bit goes to 1 when the serial transceiver is ready to use.

From what I saw, the bit behaved as described on ZynqMP where it would go to 1
during initialization, but on a Kintex-7 design with this core, the bit never
seemed to go to 1 until an actual link was established on the transceiver, so
it wasn't really usable in this situation.

> 
> Also if we don't wait for phy reset - what is the issue we are seeing?

This is more for the case of using an external PHY device - we shouldn't be
proceeding to MDIO initialization and potentially trying to talk to the PHY
when it is potentially still in reset..

> 
> > not appear to work as documented (it seems to behave as some sort of
> > link state indication and not just an indication the transceiver is
> > ready) so it can't really be relied on.
> > 
> > Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI
> > Ethernet
> > driver")
> > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > ---
> >  drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > index f950342f6467..f425a8404a9b 100644
> > --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
> > @@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local
> > *lp)
> >  		return ret;
> >  	}
> > 
> > +	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has
> > finished */
> > +	ret = read_poll_timeout(axienet_ior, value,
> > +				value & XAE_INT_PHYRSTCMPLT_MASK,
> > +				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
> > +				XAE_IS_OFFSET);
> > +	if (ret) {
> > +		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n",
> > __func__);
> > +		return ret;
> > +	}
> > +
> >  	return 0;
> >  }
> > 
> > --
> > 2.31.1
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From robh at kernel.org  Thu Jan 13 08:29:34 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 13 Jan 2022 10:29:34 -0600
Subject: [RFC PATCH 1/3] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <20220112172719.1178446-2-jeanmichel.hautbois@ideasonboard.com>
References: <20220112172719.1178446-1-jeanmichel.hautbois@ideasonboard.com>
 <20220112172719.1178446-2-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <1642091374.239763.3647184.nullmailer@robh.at.kernel.org>

On Wed, 12 Jan 2022 18:27:18 +0100, Jean-Michel Hautbois wrote:
> Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera
> interface. Also add a MAINTAINERS entry for it.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
> Dave: I assumed you were the maintainer for this file, as I based it on the
> bcm2835-unicam.txt file. Are  you happy to be added directly as the
> maintainer, or should this be specified as "Raspberry Pi Kernel
> Maintenance <kernel-list at raspberrypi.com>"
> ---
>  .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
>  MAINTAINERS                                   |   6 +
>  2 files changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.example.dts:24.31-32 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:373: Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1413: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1579262

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From matthias.bgg at gmail.com  Thu Jan 13 08:31:57 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Thu, 13 Jan 2022 17:31:57 +0100
Subject: [PATCH v9 2/3] dt-bindings: pinctrl: mt8195: Add
 mediatek,drive-strength-adv property
In-Reply-To: <20220112114724.1953-3-tinghan.shen@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
 <20220112114724.1953-3-tinghan.shen@mediatek.com>
Message-ID: <18f7a647-6153-6d38-dff1-727b9592b01e@gmail.com>

[dopping Maciej, Paolo and Sean Christopherson]

On 12/01/2022 12:47, Tinghan Shen wrote:
> Extend driving support for I2C pins on SoC mt8195.
> This property is already documented in mediatek,mt8183-pinctrl.yaml.
> 
> Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> Reviewed-by: Rob Herring <robh at kernel.org>

Looks good to me. Linus please let me know when you are queuing this patch and 
I'll take the rest of the series. Another option is, that you provide an 
Acked-by and I can take the whole set through my branch.

Regards,
Matthias

> ---
>   .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
>   1 file changed, 35 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> index 328ea59c5466..4db4899af6b1 100644
> --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> @@ -98,6 +98,32 @@ patternProperties:
>             drive-strength:
>               enum: [2, 4, 6, 8, 10, 12, 14, 16]
>   
> +          mediatek,drive-strength-adv:
> +            description: |
> +              Describe the specific driving setup property.
> +              For I2C pins, the existing generic driving setup can only support
> +              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
> +              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
> +              driving setup, the existing generic setup will be disabled.
> +              The specific driving setup is controlled by E1E0EN.
> +              When E1=0/E0=0, the strength is 0.125mA.
> +              When E1=0/E0=1, the strength is 0.25mA.
> +              When E1=1/E0=0, the strength is 0.5mA.
> +              When E1=1/E0=1, the strength is 1mA.
> +              EN is used to enable or disable the specific driving setup.
> +              Valid arguments are described as below:
> +              0: (E1, E0, EN) = (0, 0, 0)
> +              1: (E1, E0, EN) = (0, 0, 1)
> +              2: (E1, E0, EN) = (0, 1, 0)
> +              3: (E1, E0, EN) = (0, 1, 1)
> +              4: (E1, E0, EN) = (1, 0, 0)
> +              5: (E1, E0, EN) = (1, 0, 1)
> +              6: (E1, E0, EN) = (1, 1, 0)
> +              7: (E1, E0, EN) = (1, 1, 1)
> +              So the valid arguments are from 0 to 7.
> +            $ref: /schemas/types.yaml#/definitions/uint32
> +            enum: [0, 1, 2, 3, 4, 5, 6, 7]
> +
>             bias-pull-down:
>               description: |
>                 For pull down type is normal, it don't need add RSEL & R1R0 define
> @@ -268,4 +294,13 @@ examples:
>             bias-pull-down;
>           };
>         };
> +
> +      i2c0-pins {
> +        pins {
> +          pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
> +                   <PINMUX_GPIO9__FUNC_SCL0>;
> +          bias-disable;
> +          mediatek,drive-strength-adv = <7>;
> +        };
> +      };
>       };
> 


From rinni at inventati.org  Thu Jan 13 08:37:28 2022
From: rinni at inventati.org (Philip Rinn)
Date: Thu, 13 Jan 2022 17:37:28 +0100
Subject: [linux-sunxi] [PATCH RESEND v3] arm64: dts: allwinner: a64:
 olinuxino: Enable audio
In-Reply-To: <5782735.lOV4Wx5bFT@jernej-laptop>
References: <e82d8b95-99fb-43d3-9e72-a1180de26734@inventati.org>
 <Yd6axIURzudUq5Ah@plaes.org>
 <2e1a6b23-e713-7f2b-3634-5aa9b7724a50@inventati.org>
 <5782735.lOV4Wx5bFT@jernej-laptop>
Message-ID: <8a19d309-af97-7ba7-87f6-8afb3905c9f6@inventati.org>

Hi,

On 13.01.22 at 07:59, Jernej ?krabec wrote:
> Hi,
> 
> Dne sreda, 12. januar 2022 ob 16:29:51 CET je Philip Rinn napisal(a):
>> Hi,
>>
>> On 12.01.22 at 10:09, Priit Laes wrote:
>>
>>> On Tue, Jan 11, 2022 at 09:08:23PM +0100, 'Philip Rinn' via linux-sunxi
>>> wrote:
>>
>>>> Enable the audio hardware on the Olimex A64-OLinuXino board family.
>>>> Tested on the A64-OLinuXino-2Ge8G-IND variant.
>>>
>>>
>>> I have similar patch in one of my "long forgotten branches", but I'm not
>>> 100%
>>> sure whether the cpvdd-supply is required for codec_analog. IIRC,
>>> sound worked for me without the issues on A64-Olinuxino board (Rev D).
>>>
>>> 'cpvdd-supply = <&reg_eldo1>' for codec_analog
>>
>>
>> I didn't test it without but as it is present for all other a64 board with
>> audio and also in Olimex' tree I think it is needed.
> 
> It's not question if it works with or without it, nor if other boards have it
> or not. Only deciding factor is board design. On schematic it can be seen that
> cpvdd is connected to eldo1, so having this property is correct, mandatory
> even.

Very true and it's easy to verify with the schematic available: https://raw.githubusercontent.com/OLIMEX/OLINUXINO/master/HARDWARE/A64-OLinuXino/1.%20Latest%20hardware%20revision/A64-OLinuXino%20hardware%20revision%20E/A64-OlinuXino_Rev_E.pdf

So from my point of view the patch is correct.

Best regards
Philip

> 
> Best regards,
> Jernej
>   
>>
>>> And we also need to enable these configuration options in the defconfig:
>>>
>>> +CONFIG_SND_SUN8I_CODEC=m
>>> +CONFIG_SND_SUN50I_CODEC_ANALOG=m
>>
>>
>> Hm, probably, but why wasn't it added when audio was added for the other a64
>> boards? Or are we talking about different defconfigs here?
>   
>> Best regards
>> Philip
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 840 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220113/8c65056d/attachment.sig>

From mathieu.poirier at linaro.org  Thu Jan 13 08:56:04 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 13 Jan 2022 09:56:04 -0700
Subject: [RESEND PATCH v2] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <20220113061209.14271-1-jkchen@linux.alibaba.com>
References: <20220113061209.14271-1-jkchen@linux.alibaba.com>
Message-ID: <CANLsYkwZGSYYBCn8jS5h+3dP9XXr2stw=_tUjvHWNHKyXfothQ@mail.gmail.com>

On Wed, 12 Jan 2022 at 23:12, Jay Chen <jkchen at linux.alibaba.com> wrote:
>
> Currently, there are 130 etr and etf on our machine,
> but the current coresight tmc driver uses misc_register
> to register the device, which leads to the error that
> the device number is not enough.
>
> coresight-tmc: probe of xxxxx failed with error -16
>
> This patch changes the device registration method
> to cdev's dynamic registration method to solve the
> problem of insufficient device numbers.

On December 21st you posted this patch with a "RFC V3 PATCH" tag.  On
January 5th you posted a new version with a simple "PATCH" tag which,
minutes later, was superseded by another patch labelled "RESEND
PATCH".  Today you're sending yet another revision labelled "RESEND
PATCH V2"...

Is it a "V2" of the "RESEND PATCH" that was a new revision of the "RFC
V3 PATCH"?  Are you confused?  I certainly am...

>
> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> ---
>  .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
>  drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
>  2 files changed, 91 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index d0276af82494..0977f1ce6338 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -12,7 +12,6 @@
>  #include <linux/io.h>
>  #include <linux/err.h>
>  #include <linux/fs.h>
> -#include <linux/miscdevice.h>
>  #include <linux/mutex.h>
>  #include <linux/property.h>
>  #include <linux/uaccess.h>
> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>  DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>
> +static DEFINE_IDA(tmc_ida);
> +static dev_t tmc_major;
> +static struct class *tmc_class;
> +
> +#define TMC_DEV_MAX    (MINORMASK + 1)
> +
>  void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>  {
>         struct coresight_device *csdev = drvdata->csdev;
> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
>  static int tmc_open(struct inode *inode, struct file *file)
>  {
>         int ret;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>
>         ret = tmc_read_prepare(drvdata);
>         if (ret)
> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>  {
>         char *bufp;
>         ssize_t actual;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>         actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>         if (actual <= 0)
>                 return 0;
> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>  static int tmc_release(struct inode *inode, struct file *file)
>  {
>         int ret;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>
>         ret = tmc_read_unprepare(drvdata);
>         if (ret)
> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>  {
>         int ret = 0;
>         u32 devid;
> +       dev_t devt;
>         void __iomem *base;
>         struct device *dev = &adev->dev;
>         struct coresight_platform_data *pdata = NULL;
> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>                 goto out;
>         }
>
> -       drvdata->miscdev.name = desc.name;
> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> -       drvdata->miscdev.fops = &tmc_fops;
> -       ret = misc_register(&drvdata->miscdev);
> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> +       if (ret < 0)
> +               goto err_coresight_unregister;
> +
> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> +       drvdata->cdev.cdev.owner = THIS_MODULE;
> +       devt = MKDEV(MAJOR(tmc_major), ret);
> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>         if (ret)
> -               coresight_unregister(drvdata->csdev);
> -       else
> +               goto err_free_tmc_ida;
> +
> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> +       if (IS_ERR(drvdata->cdev.dev)) {
> +               ret = PTR_ERR(drvdata->cdev.dev);
> +               goto err_delete_cdev;
> +       } else
>                 pm_runtime_put(&adev->dev);
> +
> +       return 0;
> +
> +err_delete_cdev:
> +       cdev_del(&drvdata->cdev.cdev);
> +err_free_tmc_ida:
> +       ida_simple_remove(&tmc_ida, MINOR(devt));
> +err_coresight_unregister:
> +       coresight_unregister(drvdata->csdev);
>  out:
>         return ret;
>  }
> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
>  static void tmc_remove(struct amba_device *adev)
>  {
>         struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +       struct device *dev = drvdata->cdev.dev;
>
> -       /*
> -        * Since misc_open() holds a refcount on the f_ops, which is
> -        * etb fops in this case, device is there until last file
> -        * handler to this device is closed.
> -        */
> -       misc_deregister(&drvdata->miscdev);
> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
> +       device_destroy(tmc_class, dev->devt);
> +       cdev_del(&drvdata->cdev.cdev);
>         coresight_unregister(drvdata->csdev);
>  }
>
> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
>         .id_table       = tmc_ids,
>  };
>
> -module_amba_driver(tmc_driver);
> +static int __init tmc_init(void)
> +{
> +       int ret;
> +
> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> +       if (ret < 0) {
> +               pr_err("tmc: failed to allocate char dev region\n");
> +               return ret;
> +       }
> +
> +       tmc_class = class_create(THIS_MODULE, "tmc");
> +       if (IS_ERR(tmc_class)) {
> +               pr_err("tmc: failed to create class\n");
> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +               return PTR_ERR(tmc_class);
> +       }
> +
> +       ret = amba_driver_register(&tmc_driver);
> +       if (ret) {
> +               pr_err("tmc: error registering amba driver\n");
> +               class_destroy(tmc_class);
> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +       }
> +
> +       return ret;
> +}
> +
> +static void __exit tmc_exit(void)
> +{
> +       amba_driver_unregister(&tmc_driver);
> +       class_destroy(tmc_class);
> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +}
> +
> +module_init(tmc_init);
> +module_exit(tmc_exit);
>
>  MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>  MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6bec20a392b3..11441c6b9c26 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -7,9 +7,9 @@
>  #ifndef _CORESIGHT_TMC_H
>  #define _CORESIGHT_TMC_H
>
> +#include <linux/cdev.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/idr.h>
> -#include <linux/miscdevice.h>
>  #include <linux/mutex.h>
>  #include <linux/refcount.h>
>
> @@ -163,11 +163,16 @@ struct etr_buf {
>         void                            *private;
>  };
>
> +struct tmc_cdev {
> +       struct cdev cdev;
> +       struct device *dev;
> +};
> +
>  /**
>   * struct tmc_drvdata - specifics associated to an TMC component
>   * @base:      memory mapped base address for this component.
>   * @csdev:     component vitals needed by the framework.
> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
>   * @spinlock:  only one at a time pls.
>   * @pid:       Process ID of the process being monitored by the session
>   *             that is using this component.
> @@ -191,7 +196,7 @@ struct etr_buf {
>  struct tmc_drvdata {
>         void __iomem            *base;
>         struct coresight_device *csdev;
> -       struct miscdevice       miscdev;
> +       struct tmc_cdev         cdev;
>         spinlock_t              spinlock;
>         pid_t                   pid;
>         bool                    reading;
> --
> 2.27.0
>


From kevin at bracey.fi  Thu Jan 13 08:58:03 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 18:58:03 +0200
Subject: [PATCH v2 0/4] arm64: accelerate crc32_be
Message-ID: <20220113165807.2735949-1-kevin@bracey.fi>

This series completes the crc32 helper acceleration by adding crc32_be.

There are plenty of users, for example OF.

To compensate for the extra supporting cruft in lib/crc32.c, a couple of minor
tidies.

Version 2 incorporating review from Ard Biesheuvel.

Kevin Bracey (4):
  lib/crc32.c: remove unneeded casts
  lib/crc32.c: Make crc32_be weak for arch override
  lib/crc32test.c: correct printed bytes count
  arm64: accelerate crc32_be

 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 lib/crc32.c            | 14 +++----
 lib/crc32test.c        |  2 +-
 3 files changed, 80 insertions(+), 23 deletions(-)

-- 
2.25.1



From kevin at bracey.fi  Thu Jan 13 08:58:04 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 18:58:04 +0200
Subject: [PATCH v2 1/4] lib/crc32.c: remove unneeded casts
In-Reply-To: <20220113165807.2735949-1-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
Message-ID: <20220113165807.2735949-2-kevin@bracey.fi>

Casts were added in commit 8f243af42ade ("sections: fix const sections
for crc32 table") to cope with the tables not being const. They are no
longer required since commit f5e38b9284e1 ("lib: crc32: constify crc32
lookup table").

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 2a68dfd3b96c..7f062a2639df 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -194,13 +194,11 @@ u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_le, CRC32_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32table_le, CRC32_POLY_LE);
 }
 u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
 EXPORT_SYMBOL(crc32_le);
@@ -339,8 +337,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_be_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_be, CRC32_POLY_BE);
+	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
 #endif
 EXPORT_SYMBOL(crc32_be);
-- 
2.25.1



From kevin at bracey.fi  Thu Jan 13 08:58:05 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 18:58:05 +0200
Subject: [PATCH v2 2/4] lib/crc32.c: Make crc32_be weak for arch override
In-Reply-To: <20220113165807.2735949-1-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
Message-ID: <20220113165807.2735949-3-kevin@bracey.fi>

crc32_le and __crc32c_le can be overridden - extend this to crc32_be.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 7f062a2639df..5649847d0a8d 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -206,6 +206,7 @@ EXPORT_SYMBOL(__crc32c_le);
 
 u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
+u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
 
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
@@ -330,12 +331,12 @@ static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
 }
 
 #if CRC_BE_BITS == 1
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, NULL, CRC32_POLY_BE);
 }
 #else
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
-- 
2.25.1



From kevin at bracey.fi  Thu Jan 13 08:58:06 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 18:58:06 +0200
Subject: [PATCH v2 3/4] lib/crc32test.c: correct printed bytes count
In-Reply-To: <20220113165807.2735949-1-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
Message-ID: <20220113165807.2735949-4-kevin@bracey.fi>

crc32c_le self test had a stray multiply by two inherited from
the crc32_le+crc32_be test loop.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/crc32test.c b/lib/crc32test.c
index 61ddce2cff77..9b4af79412c4 100644
--- a/lib/crc32test.c
+++ b/lib/crc32test.c
@@ -675,7 +675,7 @@ static int __init crc32c_test(void)
 
 	/* pre-warm the cache */
 	for (i = 0; i < 100; i++) {
-		bytes += 2*test[i].length;
+		bytes += test[i].length;
 
 		crc ^= __crc32c_le(test[i].crc, test_buf +
 		    test[i].start, test[i].length);
-- 
2.25.1



From kevin at bracey.fi  Thu Jan 13 08:58:07 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Thu, 13 Jan 2022 18:58:07 +0200
Subject: [PATCH v2 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220113165807.2735949-1-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
Message-ID: <20220113165807.2735949-5-kevin@bracey.fi>

It makes no sense to leave crc32_be using the generic code while we
only accelerate the little-endian ops.

Even though the big-endian form doesn't fit as smoothly into the arm64,
we can speed it up and avoid hitting the D cache.

Tested on Cortex-A53. Without acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 192240 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21360 nsec

With acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 53480 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21480 nsec

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
Tested-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
index 0f9e10ecda23..8340dccff46f 100644
--- a/arch/arm64/lib/crc32.S
+++ b/arch/arm64/lib/crc32.S
@@ -11,7 +11,44 @@
 
 	.arch		armv8-a+crc
 
-	.macro		__crc32, c
+	.macro		byteorder, reg, be
+	.if		\be
+CPU_LE( rev		\reg, \reg	)
+	.else
+CPU_BE( rev		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		byteorder16, reg, be
+	.if		\be
+CPU_LE( rev16		\reg, \reg	)
+	.else
+CPU_BE( rev16		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		bitorder, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	.endif
+	.endm
+
+	.macro		bitorder16, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #16
+	.endif
+	.endm
+
+	.macro		bitorder8, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #24
+	.endif
+	.endm
+
+	.macro		__crc32, c, be=0
+	bitorder	w0, \be
 	cmp		x2, #16
 	b.lt		8f			// less than 16 bytes
 
@@ -24,10 +61,14 @@
 	add		x8, x8, x1
 	add		x1, x1, x7
 	ldp		x5, x6, [x8]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 
 	tst		x7, #8
 	crc32\c\()x	w8, w0, x3
@@ -55,33 +96,43 @@ CPU_BE(	rev		x6, x6		)
 32:	ldp		x3, x4, [x1], #32
 	sub		x2, x2, #32
 	ldp		x5, x6, [x1, #-16]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 	crc32\c\()x	w0, w0, x3
 	crc32\c\()x	w0, w0, x4
 	crc32\c\()x	w0, w0, x5
 	crc32\c\()x	w0, w0, x6
 	cbnz		x2, 32b
-0:	ret
+0:	bitorder	w0, \be
+	ret
 
 8:	tbz		x2, #3, 4f
 	ldr		x3, [x1], #8
-CPU_BE(	rev		x3, x3		)
+	byteorder	x3, \be
+	bitorder	x3, \be
 	crc32\c\()x	w0, w0, x3
 4:	tbz		x2, #2, 2f
 	ldr		w3, [x1], #4
-CPU_BE(	rev		w3, w3		)
+	byteorder	w3, \be
+	bitorder	w3, \be
 	crc32\c\()w	w0, w0, w3
 2:	tbz		x2, #1, 1f
 	ldrh		w3, [x1], #2
-CPU_BE(	rev16		w3, w3		)
+	byteorder16	w3, \be
+	bitorder16	w3, \be
 	crc32\c\()h	w0, w0, w3
 1:	tbz		x2, #0, 0f
 	ldrb		w3, [x1]
+	bitorder8	w3, \be
 	crc32\c\()b	w0, w0, w3
-0:	ret
+0:	bitorder	w0, \be
+	ret
 	.endm
 
 	.align		5
@@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
 alternative_else_nop_endif
 	__crc32		c
 SYM_FUNC_END(__crc32c_le)
+
+	.align		5
+SYM_FUNC_START(crc32_be)
+alternative_if_not ARM64_HAS_CRC32
+	b		crc32_be_base
+alternative_else_nop_endif
+	__crc32		be=1
+SYM_FUNC_END(crc32_be)
-- 
2.25.1



From hakavlad0 at seznam.cz  Thu Jan 13 09:00:55 2022
From: hakavlad0 at seznam.cz (Alexey Avramov)
Date: Fri, 14 Jan 2022 02:00:55 +0900
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yd109jeRllJbjV9o@dhcp22.suse.cz>
Message-ID: <20220114020055.0cd8697a@PC>

> But the later one is more complex and a proper
> handling really depends on the particular workload

That is why I advocate the introduction of new tunables.

> There are workloads which prefer a temporary trashing over its working
> set during a peak memory demand rather than an OOM kill

OK, for such cases, the OOM handles can be set to 0.
It can even be the default value.

> On the other side workloads that are
> latency sensitive

I daresay that this is the case with most workloads.
An internet server that falls into thrashing is a dead server.

> no simple solution can be applied to the whole

There are several solutions and they can be taken into the kernel
at the same time, they all work:
- min_ttl_ms + MGLRU
- vm.min_filelist_kbytes-like knobs
- PSI-based solutions.

> For the most steady trashing situations I have
> seen the userspace with mlocked memory and the code can make a forward
> progress and mediate the situation.

I still don't see a problem in making all the kernel-space solutions
in the kernel.


From wells.lu at sunplus.com  Thu Jan 13 09:04:32 2022
From: wells.lu at sunplus.com (=?utf-8?B?V2VsbHMgTHUg5ZGC6Iqz6aiw?=)
Date: Thu, 13 Jan 2022 17:04:32 +0000
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
Message-ID: <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>

> ...
> 
> > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > >
> > > Why bool and not tristate?
> >
> > Pinctrl driver is selected by many drivers in SP7021 platform.
> > We never build it as a module, but build-in to kernel.
> > So we use "bool".
> >
> > Should we set it to tristate?
> 
> You still haven't answered "why", so I can't tell you.

I am puzzled because I think I have answered "why".

Because Pinctrl driver is necessary for all SP7021-based platforms.
Pinctrl driver is always built into kernel, never be built as module.
We use "bool" and select "y" for all platforms. No need "tristate".

"bool" means you can select "Y" for built in kernel or "N" not built.
"tristate" means besides "Y" and "N", you can also select "M" to 
build as module which can be loaded or unloaded manually.

Sorry, I really don't know what more I can answer.
Could you please give me some hits?


> ...
> 
> > > > +               /*
> > > > +                * Upper 16-bit word is mask. Lower 16-bit word is value.
> > > > +                * Refer to descriptions of function sppctl_master_get().
> > > > +                */
> > > > +               reg_off = (offset / 16) * 4;
> > > > +               bit_off = offset % 16;
> > > > +               reg = BIT(bit_off + SPPCTL_GPIO_MASK_SHIFT) |
> > > > + BIT(bit_off);
> > >
> > > As I commented above use helper function which takes offset as input
> > > and returns you reg and reg_off.
> >
> > I'll modify code as shown below:
> >
> >                 reg = SPPCTL_SET_MOON_REG_BIT(bit_off);
> >
> > Sorry, I don't understand your meaning "returns you reg and reg_off".
> > The helper macro will return reg but not reg_off, right?
> 
> Something like (fix types accordingly to your needs):
> 
> static inline u32 sppctl_get_reg_and_offset(unsigned int offset, u32 *roff) {
>               u32 boff = offset % 16;
>               *roff = (offset / 16) * 4;
> 
>                return  MY_COOL_MACRO(boff); // BIT(boff +
> SPPCTL_GPIO_MASK_SHIFT) | BIT(boff)
> }
> 
>     reg = sppctl_get_reg_and_offset(offset, &reg_off);

Thanks for sharing the code.
I'll add the inline function.


> ...
> 
> > > > +       if (!of_find_property(pdev->dev.of_node, "gpio-controller", NULL))
> > > > +               return dev_err_probe(&pdev->dev, -EINVAL, "Not a
> > > > + gpio-controller!\n");
> > >
> > > Why do you need this check for?
> >
> > By referring to other pinctrl driver, we check if property "gpio-controller" exists?
> > Will core help us check this?
> > Is this redundant?
> 
> You should answer this question, not me.

I'll remove the statements.
Only need to check if "gpio-controller" exists or not for child nodes.


> ...
> 
> > Should I also remove the assignment:
> >
> >                 gchip->base             = 0;
> 
> Actually this is a good catch. Why do you use 0 as a base? In the new code we are supposed
> to have -1 to be assigned.

I'll modify the statement to:

	gchip->base		= -1;

to "request dynamic ID allocation".

And I'll remove the statement:

	pctl->pctl_grange.base = gchip->base;

because the whole structure (*pctl) is initialized to zero already.


> ...
> 
> > > > +       case pinmux_type_fpmx:  /* fully-pinmux */
> > >
> > > Why do you need these comments?
> > > Shouldn't you rather to kernel doc your enum entries?
> >
> > I'll remove the comments.
> > Could you please tell me where I should write and put my kernel doc?
> > Is there any examples I can refer to?
> 
> In the enum definition you do something like this (and read documentation):
> 
> /**
>  * enum ...
>  * @pinmux_type_fpmx: fully pin muxing
>  * @pinmux_type_grp: group pin muxing
>  * ...
>  */

I see, thanks!
 
I searched and found the article "Writing kernel-doc comment" in:
https://www.kernel.org/doc/html/latest/doc-guide/kernel-doc.html

I thought kernel-doc is a document put in folder Documentation/.
Now I know they are comments prefixed with /** and embedded
in sources.


> ...
> 
> > > > +       if (unlikely(check_mul_overflow(sppctl->unq_grps_sz + 1,
> > > > +                                       sizeof(*sppctl->g2fp_maps), &prod)))
> > > > +               return -EINVAL;
> > >
> > > What the point to check it after? What the point to use it with
> > > kcalloc()? Please, do your homework, i.e. read the code which implements that.
> >
> > I'll remove the "if (unlikely(check_mul_overflow()...) return -EINVAL" statement
> next patch.
> >
> > I think I mis-understood your previous comment.
> > I thought I was asked to add check_mul_overflow() function for devm_kcalloc(...).
> > Sorry for strange codes.
> 
> There were basically two iterative comments, i.e.
> first one suggested adding a check, but second one suggested switching to kcalloc()
> API.
> 
> > I should study devm_kcalloc() furthermore. Now I know
> > devm_kcalloc(...) does multiplication overflow check for us. That's
> > why we need to replace devm_kzalloc() with devm_kcalloc().
> >
> > One question left in my mind is, in this case, even we have 10,000
> > pins, we will never get overflow. It looks not so necessary.
> 
> But it's not your issue, the kcalloc() does it for you for the good sake.
>
> ...
> 
> > > > +       struct device_node *np = of_node_get(pdev->dev.of_node);
> > >
> > > What's the role of of_node_get()?
> >
> > I'll remove the unused codes.
> > I think it was used to check if OF node exists.
> 
> And if it doesn't, what is the difference?
> 
> You are the author of this code, please be prepared to explain every line in it.

From kernel-doc comment, of_node_get() increments refcount of a node.
I think as a platform driver, we don't need to check if the node exists or not.
If not exist, platform driver will not be probed.


> ...
> 
> > > > +       dev_info(&pdev->dev, "SP7021 PinCtrl by Sunplus/Tibbo
> > > > + Tech.");
> > >
> > > Is it useful?
> >
> > I think yes. It tells users that Pinctrl driver has probed successfully.
> > If no this message, users don't know if Pinctrl driver has probed
> > successfully or not. For example, because that dts node of pinctrl is
> > "disabled" or Pinctrl driver is even not enabled.
> >
> > Can I keep this?
> 
> You can, but I think it's not needed.
> Users may easily get this from other sources. Why do you need to have such noise in
> the valuable resource, i.e. kernel message buffer?

I'll remove the dev_info() next patch.


> ...
> 
> > > > + *    - mux_f_mux:  Select the pin to a fully-pinmux pin
> > > > + *    - mux_f_gpio: Select the pin to a GPIO or IOP pin
> > > > + *    - mux_f_keep: Don't change (keep intact)
> 
> > > > +       mux_f_mux = 0,          /* select fully-pinmux       */
> > > > +       mux_f_gpio = 1,         /* select GPIO or IOP pinmux */
> > > > +       mux_f_keep = 2,         /* keep no change            */
> 
> These comments are replaced by the kernel doc above, no need to keep them.

I'll remove them next patch.


> ...
> 
> > > Why is this in the header?
> >
> > Do you mean I need to move this "struct sppctl_gpio_chip { ... }"
> > declaration to c file because it is only used by the c file?
> 
> Yes.

But "struct sppctl_gpio_chip" is not only used in c file, but also used in the
same header file just beneath it. Refer to code below:

struct sppctl_gpio_chip {
	:
	:
};

struct sppctl_pdata {
	:
	:
	struct sppctl_gpio_chip *spp_gchip;
	:
	:
};


> ...
> 
> > Your previous comments:
> > > > > > +static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct
> device_node *np_config,
> > > > > > +                                struct pinctrl_map **map,
> > > > > > +unsigned int *num_maps) {
> > > > >
> > > > > Looking into this rather quite big function why you can't use what pin control
> core provides?
> > > >
> > > > No, we cannot use functions pin-control core provides.
> > > > Please refer to dt-bindings document, "pinctrl/sunplus,sp7021-pinctrl.yaml".
> > > > We have more explanation there.
> > >
> > > Fine, can you reuse some library functions, etc? Please, consider refactoring to
> make it more readable.
> >
> > Could you please share me your idea about "refactoring"?
> > Or could you give me some hints?
> > I think many times, but have no idea about refactoring.
> 
> Just split it to a few logical parts so that code can be easier to read.

I see. I'll do it, thanks.

> --
> With Best Regards,
> Andy Shevchenko

Thanks,
Wells Lu


From pali at kernel.org  Thu Jan 13 09:07:55 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Thu, 13 Jan 2022 18:07:55 +0100
Subject: [PATCH] arm64: dts: marvell: armada-37xx: Increase PCIe IO size from
 64 KiB to 1 MiB
Message-ID: <20220113170755.11856-1-pali@kernel.org>

Commit 514ef1e62d65 ("arm64: dts: marvell: armada-37xx: Extend PCIe MEM
space") increased size of PCIe MEM to 127 MiB, which is the maximal
possible size for allocated 128 MiB PCIe window. PCIe IO size in that
commit was unchanged.

Armada 3720 PCIe controller supports 32-bit IO space mapping so it is
possible to assign more than 64 KiB if address space for IO.

Currently controller has assigned 127 MiB + 64 KiB memory and therefore
there is 960 KiB of unused memory. So assign it to IO space by increasing
IO window from 64 KiB to 1 MiB.

DTS file armada-3720-turris-mox.dts already uses whole 128 MiB space, so
only update comment about 32-bit IO space mapping.

Signed-off-by: Pali Roh?r <pali at kernel.org>
Fixes: 514ef1e62d65 ("arm64: dts: marvell: armada-37xx: Extend PCIe MEM space")
---
 arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 2 +-
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi           | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index dd01409d4bb7..23e1b07c060a 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -153,7 +153,7 @@
 	 * 2 size cells and also expects that the second range starts at 16 MB offset. If these
 	 * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
 	 * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
-	 * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
+	 * for IO and the rest 112 MB (64+32+16) for MEM. Controller supports 32-bit IO mapping.
 	 * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in
 	 * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix):
 	 * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 1c74f02535c6..8d59eabadce6 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -508,12 +508,12 @@
 			/*
 			 * The 128 MiB address range [0xe8000000-0xf0000000] is
 			 * dedicated for PCIe and can be assigned to 8 windows
-			 * with size a power of two. Use one 64 KiB window for
+			 * with size a power of two. Use one 1 MiB window for
 			 * IO at the end and the remaining seven windows
 			 * (totaling 127 MiB) for MEM.
 			 */
 			ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
-				  0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
+				  0x81000000 0 0xeff00000   0 0xeff00000   0 0x00100000>; /* Port 0 IO*/
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0 0 0 1 &pcie_intc 0>,
 					<0 0 0 2 &pcie_intc 1>,
-- 
2.20.1



From philippe.cornu at foss.st.com  Thu Jan 13 09:19:21 2022
From: philippe.cornu at foss.st.com (Philippe Cornu)
Date: Thu, 13 Jan 2022 18:19:21 +0100
Subject: [PATCH 2/2] MAINTAINERS: update drm/stm drm/sti and cec/sti
 maintainers
In-Reply-To: <20220113171921.17466-1-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
Message-ID: <20220113171921.17466-3-philippe.cornu@foss.st.com>

Add Alain as sti maintainer for both drm/sti & cec/sti.
Add Rapha?l as stm maintainer for drm/stm.

Signed-off-by: Philippe Cornu <philippe.cornu at foss.st.com>
---
 MAINTAINERS | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 6bea080d0159..708f8c86e4c9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6423,6 +6423,7 @@ F:	Documentation/devicetree/bindings/display/rockchip/
 F:	drivers/gpu/drm/rockchip/
 
 DRM DRIVERS FOR STI
+M:	Alain Volmat <alain.volmat at foss.st.com>
 L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
@@ -6431,6 +6432,7 @@ F:	drivers/gpu/drm/sti
 
 DRM DRIVERS FOR STM
 M:	Yannick Fertre <yannick.fertre at foss.st.com>
+M:	Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
 M:	Philippe Cornu <philippe.cornu at foss.st.com>
 L:	dri-devel at lists.freedesktop.org
 S:	Maintained
@@ -18152,6 +18154,7 @@ F:	Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
 F:	sound/soc/sti/
 
 STI CEC DRIVER
+M:	Alain Volmat <alain.volmat at foss.st.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/stih-cec.txt
 F:	drivers/media/cec/platform/sti/
-- 
2.17.1



From philippe.cornu at foss.st.com  Thu Jan 13 09:19:19 2022
From: philippe.cornu at foss.st.com (Philippe Cornu)
Date: Thu, 13 Jan 2022 18:19:19 +0100
Subject: [PATCH 0/2] MAINTAINERS: update various stm & sti maintainer names
Message-ID: <20220113171921.17466-1-philippe.cornu@foss.st.com>

This short serie contains the maintainer status update sent recently by
Benjamin Gaignard (see [1] for details) and add new maintainers for
various stm & sti files.

[1] https://lore.kernel.org/lkml/20210706163033.795805-1-benjamin.gaignard at collabora.com/


Benjamin Gaignard (1):
  MAINTAINERS: Update Benjamin Gaignard maintainer status

Philippe Cornu (1):
  MAINTAINERS: update drm/stm drm/sti and cec/sti maintainers

 MAINTAINERS | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

-- 
2.17.1



From philippe.cornu at foss.st.com  Thu Jan 13 09:19:20 2022
From: philippe.cornu at foss.st.com (Philippe Cornu)
Date: Thu, 13 Jan 2022 18:19:20 +0100
Subject: [PATCH 1/2] MAINTAINERS: Update Benjamin Gaignard maintainer status
In-Reply-To: <20220113171921.17466-1-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
Message-ID: <20220113171921.17466-2-philippe.cornu@foss.st.com>

From: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Update Benjamin Gaignard address and remove it from no more maintained
drivers.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 MAINTAINERS | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2345ce8521..6bea080d0159 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5702,7 +5702,7 @@ F:	tools/testing/selftests/dma/
 
 DMA-BUF HEAPS FRAMEWORK
 M:	Sumit Semwal <sumit.semwal at linaro.org>
-R:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
+R:	Benjamin Gaignard <benjamin.gaignard at collabora.com>
 R:	Liam Mark <lmark at codeaurora.org>
 R:	Laura Abbott <labbott at redhat.com>
 R:	Brian Starkey <Brian.Starkey at arm.com>
@@ -6423,7 +6423,6 @@ F:	Documentation/devicetree/bindings/display/rockchip/
 F:	drivers/gpu/drm/rockchip/
 
 DRM DRIVERS FOR STI
-M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
 L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
@@ -6433,7 +6432,6 @@ F:	drivers/gpu/drm/sti
 DRM DRIVERS FOR STM
 M:	Yannick Fertre <yannick.fertre at foss.st.com>
 M:	Philippe Cornu <philippe.cornu at foss.st.com>
-M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
 L:	dri-devel at lists.freedesktop.org
 S:	Maintained
 T:	git git://anongit.freedesktop.org/drm/drm-misc
@@ -18154,7 +18152,6 @@ F:	Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
 F:	sound/soc/sti/
 
 STI CEC DRIVER
-M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/stih-cec.txt
 F:	drivers/media/cec/platform/sti/
-- 
2.17.1



From seanjc at google.com  Thu Jan 13 09:21:19 2022
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 13 Jan 2022 17:21:19 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
Message-ID: <YeBfj89mIf8SezfD@google.com>

On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
> > Perhaps it would help if you explained *why* you are doing this. It
> > sounds like you are either trying to protect against a malicious
> > userspace, or you are trying to keep userspace from doing something
> > stupid. In general, kvm only enforces constraints that are necessary
> > to protect the host. If that's what you're doing, I don't understand
> > why live migration doesn't provide an end-run around your protections.
> It's mainly to safeguard the guests. With respect to migration, KVM
> and the userspace are collectively playing a role here. It's up to the
> userspace to ensure that the registers are configured the same across
> migrations and KVM ensures that the userspace doesn't modify the
> registers after KVM_RUN so that they don't see features turned OFF/ON
> during execution. I'm not sure if it falls into the definition of
> protecting the host. Do you see a value in adding this extra
> protection from KVM?

Short answer: probably not?

There is precedent for disallowing userspace from doing stupid things, but that's
either for KVM's protection (as Jim pointed out), or because KVM can't honor the
change, e.g. x86 is currently in the process of disallowing most CPUID changes
after KVM_RUN because KVM itself consumes the CPUID information and KVM doesn't
support updating some of it's own internal state (because removing features like
GB hugepage support is nonsensical and would require a large pile of complicated,
messy code).

Restricing CPUID changes does offer some "protection" to the guest, but that's
not the goal.  E.g. KVM won't detect CPUID misconfiguration in the migration
case, and trying to do so is a fool's errand.

If restricting updates in the arm64 is necessary to ensure KVM provides sane
behavior, then it could be justified.  But if it's purely a sanity check on
behalf of the guest, then it's not justified.


From rppt at kernel.org  Thu Jan 13 09:33:11 2022
From: rppt at kernel.org (Mike Rapoport)
Date: Thu, 13 Jan 2022 19:33:11 +0200
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com>
 <Yd1cnquQFZoNE7FP@kernel.org>
 <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
Message-ID: <YeBiV8fuCCLWyHYb@kernel.org>

On Tue, Jan 11, 2022 at 08:44:41PM +0000, Frank van der Linden wrote:
> On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote:
> > > --- a/include/linux/memblock.h
> > > +++ b/include/linux/memblock.h
> > > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
> > >  phys_addr_t memblock_start_of_DRAM(void);
> > >  phys_addr_t memblock_end_of_DRAM(void);
> > >  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> > > +void memblock_enforce_usable_range(void);
> > >  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
> > >  void memblock_mem_limit_remove_map(phys_addr_t limit);
> > 
> > We already have 3 very similar interfaces that deal with memory capping.
> > Now you suggest to add fourth that will "generically" solve a single use
> > case of DT, EFI and kdump interaction on arm64.
> > 
> > Looks like a workaround for a fundamental issue of incompatibility between
> > DT and EFI wrt memory registration.
> 
> Yep, I figured this would be the main argument against this - arm64
> already added several other more-or-less special cased interfaces over
> time.
> 
> I'm more than happy to solve this in a different way.
> 
> What would you suggest:
> 
> 1) Try to merge the similar interfaces in to one.
> 2) Just deal with it at a lower (arm64) level?
> 3) Some other way?

We've discussed this with Ard on IRC, and our conclusion was that on arm64
kdump kernel should have memblock.memory exactly the same as the normal
kernel. Then, the memory outside usable-memory-range should be reserved so
that kdump kernel won't step over it.

With that, simple (untested) patch below could be what we need:

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bdca35284ceb..371418dffaf1 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -1275,7 +1275,8 @@ void __init early_init_dt_scan_nodes(void)
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 
 	/* Handle linux,usable-memory-range property */
-	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
+	memblock_reserve(0, cap_mem_addr);
+	memblock_reserve(cap_mem_addr + cap_mem_size, PHYS_ADDR_MAX);
 }
 
 bool __init early_init_dt_scan(void *params)

> Thanks,
> 
> - Frank
> 

-- 
Sincerely yours,
Mike.


From biju.das.jz at bp.renesas.com  Thu Jan 13 09:45:05 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Thu, 13 Jan 2022 17:45:05 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
Message-ID: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi All,

RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").

After this patch, the screen becomes greenish(may be it is setting it into YUV format??).

By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.

After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.

Not sure, I am the only one seeing this issue with dw_HDMI driver.

Regards,
Biju


From jiaxun.yang at flygoat.com  Thu Jan 13 09:44:50 2022
From: jiaxun.yang at flygoat.com (Jiaxun Yang)
Date: Thu, 13 Jan 2022 17:44:50 +0000
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20220112211039.GA281591@bhelgaas>
References: <20220112211039.GA281591@bhelgaas>
Message-ID: <a660ca71-b7ed-4348-93ca-c05b0e5b1697@www.fastmail.com>



?2022?1?12??? ??9:10?Bjorn Helgaas???
> On Wed, Jan 12, 2022 at 08:08:45PM +0000, Jiaxun Yang wrote:
>> ?2022?1?12??? ??3:19?Bjorn Helgaas???
>> > On Wed, Jan 12, 2022 at 12:57:44PM +0000, Jiaxun Yang wrote:
>> >> ?2022?1?11??? ??9:46?Bjorn Helgaas???
>> >> > [-cc many, +cc iproc, loongson, tegra maintainers]
>> [...]
>> > I see these:
>> >
>> >   Documentation/devicetree/bindings/pci/loongson.yaml
>> >   arch/mips/boot/dts/loongson/rs780e-pch.dtsi
>> >
>> > which makes me think there are Loongson systems with DT.  Are there
>> > some Loongson systems with DT and some legacy ones without?
>> 
>> Actually all present MIPS/Loongson systems are legacy and we just
>> built-in DTs in kernel and select which one to use at boot time. 
>
> So I guess you know enough about what platform it is to select which
> DT to use, but you don't know enough to know the I8259 routing?
>
> If you *could* select a DT that described the I8259 routing, I guess
> maybe you could select a matching DT or update a DT in-place?
>
>> > The only driver I see is drivers/pci/controller/pci-loongson.c.
>> > Is that used for all Loongson system?  It unconditionally uses
>> > ->map_irq = loongson_map_irq().
>> 
>> Yes, it's used among all Loongson systems.  For system using LS7A
>> PCH the IRQ mapping is fixed so we just programmed it in DT. For
>> RS780E we use this routine to read PCI_INTERRUPT_LINE to select
>> which I8259 IRQ to use.
>> 
>> > loongson_map_irq() reads PCI_INTERRUPT_LINE; I think that depends
>> > on firmware having previously programmed it, right?
>> 
>> I'm unclear about what did firmware do but as AMD RS780E is used in
>> x86 PCs as well it should be the same way.
>
> PCI devices don't use the value in PCI_INTERRUPT_LINE, and the spec
> doesn't define a default value.  It's only for use by software.
>
> I'm pretty sure that on ACPI x86, we don't depend on
> PCI_INTERRUPT_LINE except for things like quirks.
>
> I think the ACPI MADT and _PRT are supposed to contain all the INTx
> routing information we need.  Obviously this isn't an ACPI system.
> I'm just making the point that it *should* be possible to remove this
> dependency on firmware if we can identify the specific platform (which
> determines the I8259 routing).

Hi,

Thanks for the information, I had send a enquire to Loongson to ask about
those details.

Patching DT at boot time should be possible :-)

Thanks.

>
> Bjorn

-- 
- Jiaxun


From german.gomez at arm.com  Thu Jan 13 09:54:15 2022
From: german.gomez at arm.com (German Gomez)
Date: Thu, 13 Jan 2022 17:54:15 +0000
Subject: [PATCH 0/2] perf: arm_spe: make the PMSCR CX bit[3] consistent across
 the session
Message-ID: <20220113175417.5523-1-german.gomez@arm.com>

The value of the CX bit of the PMSCR register is not consistent across
a perf session. There is an example in [1/2] to reproduce the issue.

This cset applies a small correction to fix the consistency issue.

- [PATCH 1/2] Makes the CX bit consistent by caching the value during
  the initialization of the SPE PMU event.
- [PATCH 2/2] Allows CONTEXT packets when profiling in CPU mode.

German Gomez (2):
  perf: arm_spe: make the PMSCR CX bit[3] consistent across the session
  perf: arm_spe: Enable CONTEXT packets if profiling in CPU mode

 drivers/perf/arm_spe_pmu.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

-- 
2.25.1



From german.gomez at arm.com  Thu Jan 13 09:54:16 2022
From: german.gomez at arm.com (German Gomez)
Date: Thu, 13 Jan 2022 17:54:16 +0000
Subject: [PATCH 1/2] perf: arm_spe: make the PMSCR CX bit[3] consistent across
 the session
In-Reply-To: <20220113175417.5523-1-german.gomez@arm.com>
References: <20220113175417.5523-1-german.gomez@arm.com>
Message-ID: <20220113175417.5523-2-german.gomez@arm.com>

The ARM SPE driver will seenablet the CX bit in the PMSCR register if it
detects that the profiler (perf tool) has enough capabilities during the
initialization of the PMU event in the "arm_spe_pmu_event_init" callback:

  reg = arm_spe_event_to_pmscr(event);
  if (!perfmon_capable() &&
      (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
              BIT(SYS_PMSCR_EL1_CX_SHIFT) |
              BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
          return -EACCES;

This implies that the CX bit should remain consistent across the entire
duration of the session. However, the value of the bit is later being
changed (from 0 to 1 and vice versa) in the "arm_spe_pmu_start" callback

Consider this example:

  1. Run a process in the background with privileges in CPU0

    $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
    [3] 3806

  2. Begin a perf session without privileges (we shouldn't see CONTEXT packets)

    $ perf record -e arm_spe_0// -C0 -- sleep 1
    $ perf report -D | grep CONTEXT
    .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    [...]

One way to fix this is by caching the value of the CX bit during the
initialization of the PMU event, so that it remains consistent during
the session.

Signed-off-by: German Gomez <german.gomez at arm.com>
---
 drivers/perf/arm_spe_pmu.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index d44bcc29d..8515bf85c 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -57,6 +57,7 @@ struct arm_spe_pmu {
 	u16					pmsver;
 	u16					min_period;
 	u16					counter_sz;
+	bool					pmscr_cx;
 
 #define SPE_PMU_FEAT_FILT_EVT			(1UL << 0)
 #define SPE_PMU_FEAT_FILT_TYP			(1UL << 1)
@@ -260,6 +261,7 @@ static const struct attribute_group *arm_spe_pmu_attr_groups[] = {
 static u64 arm_spe_event_to_pmscr(struct perf_event *event)
 {
 	struct perf_event_attr *attr = &event->attr;
+	struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu);
 	u64 reg = 0;
 
 	reg |= ATTR_CFG_GET_FLD(attr, ts_enable) << SYS_PMSCR_EL1_TS_SHIFT;
@@ -272,7 +274,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event)
 	if (!attr->exclude_kernel)
 		reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
 
-	if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
+	if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && spe_pmu->pmscr_cx)
 		reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
 
 	return reg;
@@ -709,10 +711,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
+	spe_pmu->pmscr_cx = perfmon_capable();
 	reg = arm_spe_event_to_pmscr(event);
 	if (!perfmon_capable() &&
 	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
-		    BIT(SYS_PMSCR_EL1_CX_SHIFT) |
 		    BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
 		return -EACCES;
 
-- 
2.25.1



From german.gomez at arm.com  Thu Jan 13 09:54:17 2022
From: german.gomez at arm.com (German Gomez)
Date: Thu, 13 Jan 2022 17:54:17 +0000
Subject: [PATCH 2/2] perf: arm_spe: Enable CONTEXT packets if profiling in CPU
 mode
In-Reply-To: <20220113175417.5523-1-german.gomez@arm.com>
References: <20220113175417.5523-1-german.gomez@arm.com>
Message-ID: <20220113175417.5523-3-german.gomez@arm.com>

Enable CONTEXT packets in SPE traces if the profiler runs in CPU mode.

Signed-off-by: German Gomez <german.gomez at arm.com>
---
 drivers/perf/arm_spe_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index 8515bf85c..7d9a7fa4f 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -711,7 +711,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
-	spe_pmu->pmscr_cx = perfmon_capable();
+	spe_pmu->pmscr_cx = perfmon_capable() || (event->cpu != -1);
 	reg = arm_spe_event_to_pmscr(event);
 	if (!perfmon_capable() &&
 	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
-- 
2.25.1



From mathieu.poirier at linaro.org  Thu Jan 13 09:56:36 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 13 Jan 2022 10:56:36 -0700
Subject: [PATCH v2 4/6] coresight: samples: Add an example config writer
 for configfs load
In-Reply-To: <20211130220100.25888-5-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-5-mike.leach@linaro.org>
Message-ID: <20220113175636.GA967130@p14s>

Good morning Mike,

On Tue, Nov 30, 2021 at 10:00:58PM +0000, Mike Leach wrote:
> Add an example file generator to test loading configurations via a
> binary attribute in configfs.
> 
> Provides a file buffer writer function that can be re-used in other
> userspace programs.
> 
> Buffer write format matches that expected by the corresponding reader
> in the configfs driver code.
> 

Despite trying quite hard I haven't found a single bug in this patchset, which
is a feat for user space code.

Please see comments below...

> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  samples/coresight/Makefile                |   7 +
>  samples/coresight/coresight-cfg-bufw.c    | 302 ++++++++++++++++++++++
>  samples/coresight/coresight-cfg-bufw.h    |  24 ++
>  samples/coresight/coresight-cfg-filegen.c |  89 +++++++
>  4 files changed, 422 insertions(+)
>  create mode 100644 samples/coresight/coresight-cfg-bufw.c
>  create mode 100644 samples/coresight/coresight-cfg-bufw.h
>  create mode 100644 samples/coresight/coresight-cfg-filegen.c
> 
> diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile
> index b3fce4af2347..07bfd99d7a68 100644
> --- a/samples/coresight/Makefile
> +++ b/samples/coresight/Makefile
> @@ -1,4 +1,11 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
> +# coresight config - loadable module configuration.
>  obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o
>  ccflags-y += -I$(srctree)/drivers/hwtracing/coresight
> +
> +# coresight config - configfs loadable binary config generator
> +userprogs-always-y += coresight-cfg-filegen
> +
> +coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o
> +userccflags += -I$(srctree)/drivers/hwtracing/coresight
> diff --git a/samples/coresight/coresight-cfg-bufw.c b/samples/coresight/coresight-cfg-bufw.c
> new file mode 100644
> index 000000000000..8c32a8509eef
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-bufw.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.

Are you sure you want to keep this to 2020?  Here and in all other files.

> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#include <string.h>
> +
> +#include "coresight-cfg-bufw.h"
> +
> +/*
> + * Set of macros to make writing the buffer code easier.
> + *.

Extra '.'

> + * Uses naming convention as 'buffer' for the buffer pointer and
> + * 'used' as the current bytes used by the encosing function.
> + */
> +#define cscfg_write_u64(val64) {	\
> +	*(u64 *)(buffer + used) = val64; \
> +	used += sizeof(u64); \
> +	}
> +
> +#define cscfg_write_u32(val32) { \
> +	*(u32 *)(buffer + used) = val32;	\
> +	used += sizeof(u32); \
> +	}
> +
> +#define cscfg_write_u16(val16) { \
> +	*(u16 *)(buffer + used) = val16;	\
> +	used += sizeof(u16); \
> +	}
> +
> +#define cscfg_write_u8(val8) { \
> +	*(buffer + used) = val8;	\
> +	used++;	\
> +	}
> +
> +#define CHECK_WRET(rval) { \
> +	if (rval < 0) \
> +		return rval;	   \
> +	used += rval;		   \
> +	}
> +
> +/* write the header at the start of the buffer */
> +static int cscfg_file_write_fhdr(u8 *buffer, const int buflen,
> +				 const struct cscfg_file_header *fhdr)
> +{
> +	int used = 0;
> +
> +	cscfg_write_u32(fhdr->magic_version);
> +	cscfg_write_u16(fhdr->length);
> +	cscfg_write_u16(fhdr->nr_features);
> +	return used;
> +}
> +
> +static int cscfg_file_write_string(u8 *buffer, const int buflen, const char *string)
> +{
> +	int len, used = 0;
> +
> +	len = strlen(string);
> +	if (len > CSCFG_FILE_STR_MAXSIZE)
> +		return -EINVAL;
> +
> +	if (buflen < (len + 1 + sizeof(u16)))
> +		return -EINVAL;
> +
> +	cscfg_write_u16((u16)(len + 1));
> +	strcpy((char *)(buffer + used), string);
> +	used += (len + 1);
> +
> +	return used;
> +}
> +
> +static int cscfg_file_write_elem_hdr(u8 *buffer, const int buflen,
> +				     struct cscfg_file_elem_header *ehdr)
> +{
> +	int used = 0;
> +
> +	if (buflen < (sizeof(u16) + sizeof(u8)))
> +		return -EINVAL;
> +
> +	cscfg_write_u16(ehdr->elem_length);
> +	cscfg_write_u8(ehdr->elem_type);
> +
> +	return used;
> +}
> +
> +

Extra newline

> +static int cscfg_file_write_config(u8 *buffer, const int buflen,
> +				   struct cscfg_config_desc *config_desc)
> +{
> +	int used = 0, bytes_w, space_req, preset_bytes, i;
> +	struct cscfg_file_elem_header ehdr;
> +
> +	ehdr.elem_length = 0;
> +	ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_CFG;
> +
> +	/* write element header at current buffer location */
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the configuration name */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  config_desc->name);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the description string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  config_desc->description);
> +	CHECK_WRET(bytes_w);
> +
> +	/*
> +	 * calculate the space needed for variables + presets
> +	 * [u16 value - nr_presets]
> +	 * [u32 value - nr_total_params]
> +	 * [u16 value - nr_feat_refs]
> +	 * [u64 values] * (nr_presets * nr_total_params)
> +	 */
> +	preset_bytes = sizeof(u64) * config_desc->nr_presets * config_desc->nr_total_params;
> +	space_req = (sizeof(u16) * 2) + sizeof(u32) + preset_bytes;
> +
> +	if ((buflen - used) < space_req)
> +		return -EINVAL;
> +
> +	cscfg_write_u16((u16)config_desc->nr_presets);
> +	cscfg_write_u32((u32)config_desc->nr_total_params);
> +	cscfg_write_u16((u16)config_desc->nr_feat_refs);
> +	if (preset_bytes) {
> +		memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes);
> +		used += preset_bytes;
> +	}
> +
> +	/* now write the feature ref names */
> +	for (i = 0; i < config_desc->nr_feat_refs; i++) {
> +		bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +						  config_desc->feat_ref_names[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* rewrite the element header with the correct length */
> +	ehdr.elem_length = used;
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +
> +	return used;
> +}
> +
> +/*
> + * write a parameter structure into the buffer in following format:
> + * [cscfg_file_elem_str]    - parameter name.
> + * [u64 value: param_value] - initial value.
> + */
> +static int cscfg_file_write_param(u8 *buffer, const int buflen,
> +				  struct cscfg_parameter_desc *param_desc)
> +{
> +	int used = 0, bytes_w;
> +
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  param_desc->name);
> +	CHECK_WRET(bytes_w);
> +
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +
> +	cscfg_write_u64(param_desc->value);
> +	return used;
> +}
> +/*
> + * Write a feature element from cscfg_feature_desc in following format:
> + *
> + * [cscfg_file_elem_header] - header length is total bytes to end of param structures.
> + * [cscfg_file_elem_str]    - feature name.
> + * [cscfg_file_elem_str]    - feature description.
> + * [u32 value: match_flags]
> + * [u16 value: nr_regs]	    - number of registers.
> + * [u16 value: nr_params]   - number of parameters.
> + * [cscfg_regval_desc struct] * nr_regs
> + * [PARAM_ELEM] * nr_params
> + *
> + *

Extra newlines

> + */
> +static int cscfg_file_write_feat(u8 *buffer, const int buflen,
> +				 struct cscfg_feature_desc *feat_desc)
> +{
> +	struct cscfg_file_elem_header ehdr;
> +	struct cscfg_regval_desc *p_reg_desc;
> +	int used = 0, bytes_w, i, space_req;
> +	u32 val32;
> +
> +	ehdr.elem_length = 0;
> +	ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_FEAT;
> +
> +	/* write element header at current buffer location */
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the name string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  feat_desc->name);
> +	CHECK_WRET(bytes_w)
> +
> +	/* write out the description string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  feat_desc->description);
> +	CHECK_WRET(bytes_w);
> +
> +	/* check for space for variables and register structures */
> +	space_req = (sizeof(u16) * 2) + sizeof(u32) +
> +		(sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs);
> +	if ((buflen - used) < space_req)
> +		return -EINVAL;
> +
> +	/* write the variables */
> +	cscfg_write_u32((u32)feat_desc->match_flags);
> +	cscfg_write_u16((u16)feat_desc->nr_regs);
> +	cscfg_write_u16((u16)feat_desc->nr_params);
> +
> +	/*write the registers */
> +	for (i = 0; i < feat_desc->nr_regs; i++) {
> +		p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
> +		CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_reg_desc);
> +		cscfg_write_u32(val32);
> +		cscfg_write_u64(feat_desc->regs_desc[i].val64);
> +	}
> +
> +	/* write any parameters */
> +	for (i = 0; i < feat_desc->nr_params; i++) {
> +		bytes_w = cscfg_file_write_param(buffer + used, buflen - used,
> +						 &feat_desc->params_desc[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/*
> +	 * rewrite the element header at the start of the buffer block
> +	 * with the correct length
> +	 */
> +	ehdr.elem_length = used;
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +
> +	return used;
> +}
> +
> +/*
> + * write a buffer from the configuration and feature
> + * descriptors to write into a file for configfs.
> + *
> + * Will only write one config, and/or a number of features,
> + * per the file standard.
> + */
> +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> +			    struct cscfg_config_desc *config_desc,
> +			    struct cscfg_feature_desc **feat_descs)
> +{
> +	struct cscfg_file_header fhdr;
> +	int used = 0,  bytes_w, i;
> +
> +	/* init the file header */
> +	fhdr.magic_version = CSCFG_FILE_MAGIC_VERSION;
> +	fhdr.length = 0;
> +	fhdr.nr_features = 0;
> +
> +	/* count the features */
> +	if (feat_descs) {
> +		while (feat_descs[fhdr.nr_features])
> +			fhdr.nr_features++;
> +	}
> +
> +	/* need a buffer and at least one config or feature */
> +	if ((!config_desc && !fhdr.nr_features) ||
> +	    !buffer || (buflen > CSCFG_FILE_MAXSIZE))
> +		return -EINVAL;
> +
> +	/* write a header at the start to get the length of the header */
> +	bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write a single config */
> +	if (config_desc) {
> +		bytes_w = cscfg_file_write_config(buffer + used, buflen - used,
> +						  config_desc);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* write any features */
> +	for (i = 0; i < fhdr.nr_features; i++) {
> +		bytes_w = cscfg_file_write_feat(buffer + used, buflen - used,
> +						feat_descs[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* finally re-write the header at the buffer start with the correct length */
> +	fhdr.length = (u16)used;
> +	bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +	return used;
> +}
> diff --git a/samples/coresight/coresight-cfg-bufw.h b/samples/coresight/coresight-cfg-bufw.h
> new file mode 100644
> index 000000000000..00b16c583cad
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-bufw.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#ifndef _CORESIGHT_CFG_BUFW_H
> +#define _CORESIGHT_CFG_BUFW_H
> +
> +#include "coresight-config-file.h"
> +
> +/*
> + * Function to take coresight configurations and features and
> + * write them into a supplied memory buffer for serialisation
> + * into a file.
> + *
> + * Resulting file can then be loaded into the coresight
> + * infrastructure via configfs.
> + */
> +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> +			    struct cscfg_config_desc *config_desc,
> +			    struct cscfg_feature_desc **feat_descs);
> +
> +#endif /* _CORESIGHT_CFG_BUFW_H */
> diff --git a/samples/coresight/coresight-cfg-filegen.c b/samples/coresight/coresight-cfg-filegen.c
> new file mode 100644
> index 000000000000..c8be18ee97b6
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-filegen.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/unistd.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +#include "coresight-cfg-bufw.h"
> +
> +/*
> + * generate example binary coresight configuration files for loading
> + * into the coresight subsystem via configfs
> + */
> +
> +/* create a similar configuration example as the coresight-cfg-sample.c file. */
> +
> +/* we will provide 4 sets of preset parameter values */
> +#define AFDO2_NR_PRESETS	4
> +/* the total number of parameters in used features - strobing has 2 */
> +#define AFDO2_NR_PARAM_SUM	2
> +
> +static const char *afdo2_ref_names[] = {
> +	"strobing",
> +};
> +
> +/*
> + * set of presets leaves strobing window constant while varying period to allow
> + * experimentation with mark / space ratios for various workloads
> + */
> +static u64 afdo2_presets[AFDO2_NR_PRESETS][AFDO2_NR_PARAM_SUM] = {
> +	{ 2000, 100 },
> +	{ 2000, 1000 },
> +	{ 2000, 5000 },
> +	{ 2000, 10000 },
> +};
> +
> +struct cscfg_config_desc afdo3 = {
> +	.name = "autofdo3",
> +	.description = "Setup ETMs with strobing for autofdo\n"
> +	"Supplied presets allow experimentation with mark-space ratio for various loads\n",
> +	.nr_feat_refs = ARRAY_SIZE(afdo2_ref_names),
> +	.feat_ref_names = afdo2_ref_names,
> +	.nr_presets = AFDO2_NR_PRESETS,
> +	.nr_total_params = AFDO2_NR_PARAM_SUM,
> +	.presets = &afdo2_presets[0][0],
> +};
> +
> +static struct cscfg_feature_desc *sample_feats[] = {
> +	NULL
> +};

For completeness there would be value in providing an example that requires
features.

> +
> +static struct cscfg_config_desc *sample_cfgs[] = {
> +	&afdo3,
> +	NULL
> +};

Any reason to declare sample_cfgs[] when there can only be one configuration?

Lastly I get the following [1] when compiling this set - I have not investigated
further.

Thanks,
Mathieu

[1]. https://pastebin.com/Nw2DTqTC

> +
> +
> +#define CSCFG_BIN_FILENAME "example1.cscfg"
> +
> +int main(int argc, char **argv)
> +{
> +	u8 buffer[CSCFG_FILE_MAXSIZE];
> +	int used;
> +	FILE *fp;
> +
> +	printf("Coresight Configuration file Generator\n\n");
> +
> +	used = cscfg_file_write_buffer(buffer, CSCFG_FILE_MAXSIZE,
> +				       sample_cfgs[0], sample_feats);
> +
> +	if (used < 0) {
> +		printf("Error %d writing configuration %s into buffer\n",
> +		       used, sample_cfgs[0]->name);
> +		return used;
> +	}
> +
> +	fp = fopen(CSCFG_BIN_FILENAME, "wb");
> +	if (fp == NULL) {
> +		printf("Error opening file %s\n", CSCFG_BIN_FILENAME);
> +		return -1;
> +	}
> +	fwrite(buffer, used, sizeof(u8), fp);
> +	fclose(fp);
> +	return 0;
> +}
> -- 
> 2.17.1
> 


From andy.shevchenko at gmail.com  Thu Jan 13 10:04:28 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Thu, 13 Jan 2022 20:04:28 +0200
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
Message-ID: <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>

On Thu, Jan 13, 2022 at 7:04 PM Wells Lu ??? <wells.lu at sunplus.com> wrote:

...

> > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > >
> > > > Why bool and not tristate?
> > >
> > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > We never build it as a module, but build-in to kernel.
> > > So we use "bool".
> > >
> > > Should we set it to tristate?
> >
> > You still haven't answered "why", so I can't tell you.
>
> I am puzzled because I think I have answered "why".

Nope. :-)

> Because Pinctrl driver is necessary for all SP7021-based platforms.

"Why?" Why is it necessary (to be built-in)?

...

> > > > > +       struct device_node *np = of_node_get(pdev->dev.of_node);
> > > >
> > > > What's the role of of_node_get()?
> > >
> > > I'll remove the unused codes.
> > > I think it was used to check if OF node exists.
> >
> > And if it doesn't, what is the difference?
> >
> > You are the author of this code, please be prepared to explain every line in it.
>
> From kernel-doc comment, of_node_get() increments refcount of a node.
> I think as a platform driver, we don't need to check if the node exists or not.
> If not exist, platform driver will not be probed.

Right!

...

> > > > Why is this in the header?
> > >
> > > Do you mean I need to move this "struct sppctl_gpio_chip { ... }"
> > > declaration to c file because it is only used by the c file?
> >
> > Yes.
>
> But "struct sppctl_gpio_chip" is not only used in c file, but also used in the
> same header file just beneath it. Refer to code below:

Thanks for the snippet. It actually shows the opposite. No, below is
the user of the _pointer_ to the struct of that type. You may easily
use the "opaque pointer" approach. I.o.w. my comment stays.

> struct sppctl_gpio_chip {
>         :
>         :
> };
>
> struct sppctl_pdata {
>         :
>         :
>         struct sppctl_gpio_chip *spp_gchip;
>         :
>         :
> };

-- 
With Best Regards,
Andy Shevchenko


From mathieu.poirier at linaro.org  Thu Jan 13 10:15:57 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 13 Jan 2022 11:15:57 -0700
Subject: [PATCH v2 6/6] Documentation: coresight: docs for config load
 via configfs
In-Reply-To: <20211130220100.25888-7-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-7-mike.leach@linaro.org>
Message-ID: <20220113181557.GB967130@p14s>

More comments...

On Tue, Nov 30, 2021 at 10:01:00PM +0000, Mike Leach wrote:
> Add documentation covering the configfs updates that allow
> binary configuration files to be loaded and unloaded via configfs,
> along with the demonstration programs in samples.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  .../trace/coresight/coresight-config.rst      | 151 +++++++++++++++++-
>  1 file changed, 145 insertions(+), 6 deletions(-)
> 
> diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst
> index 6d5ffa6f7347..f11def230fab 100644
> --- a/Documentation/trace/coresight/coresight-config.rst
> +++ b/Documentation/trace/coresight/coresight-config.rst
> @@ -152,7 +152,7 @@ follows::
>  
>      $ cd configurations/
>      $ ls
> -    autofdo
> +    autofdo last_load_status  load  unload
>      $ cd autofdo/
>      $ ls
>      description  feature_refs  preset1  preset3  preset5  preset7  preset9
> @@ -278,9 +278,19 @@ Creating and Loading Custom Configurations
>  ==========================================
>  
>  Custom configurations and / or features can be dynamically loaded into the
> -system by using a loadable module.
> +system by using a loadable module, or by loading a binary configuration
> +file in configfs.
> +
> +Loaded configurations can use previously loaded features. The system will
> +ensure that it is not possible to unload a feature that is currently in
> +use, by enforcing the unload order as the strict reverse of the load order.
> +
> +An example of a custom configuration module, and generators for binary
> +configuration files are found in './samples/coresight'.
>  
> -An example of a custom configuration is found in ./samples/coresight.
> +
> +Using a Loadable Module
> +-----------------------
>  
>  This creates a new configuration that uses the existing built in
>  strobing feature, but provides a different set of presets.
> @@ -289,6 +299,135 @@ When the module is loaded, then the configuration appears in the configfs
>  file system and is selectable in the same way as the built in configuration
>  described above.
>  
> -Configurations can use previously loaded features. The system will ensure
> -that it is not possible to unload a feature that is currently in use, by
> -enforcing the unload order as the strict reverse of the load order.
> +The file 'coresight-cfg-sample.c' contains the configuration and module
> +initialisation code needed to create the loadable module.
> +
> +This will be built alongside the kernel modules if select in KConfig.
> +
> +
> +Using a Binary Configuration File
> +---------------------------------
> +
> +Building the samples creates the 'coresight-cfg-filegen' program that will
> +generate a configuration binary 'example1.cscfg' that can be loaded into the
> +system using configfs. The configuration declared in the source file
> +'coresight-cfg-filegen.c' is named 'autofdo3' - the name that will be used
> +once loaded.
> +
> +The source files 'coresight-cfg-bufw.h' and 'coresight-cfg-bufw.c' provide a
> +standard function to convert a configuration declared in 'C' into the correct
> +binary buffer format. These files can be re-used to create new custom
> +configurations.
> +
> +The program  'coresight-cfg-file-read' can read back and print a configuration
> +binary. This is built using the reader from the driver code.
> +
> +There are additional attributes in the configurations directory - load, unload
> +and last_load_status that can be used to load and unload configuration
> +binary files. To load, 'cat' the binary config into the load attribute::
> +
> +    $ ls /config/cs-syscfg/configurations/
> +    autofdo last_load_status  load  unload
> +    $ cat example1.cscfg > /config/cs-syscfg/configurations/load
> +    $ ls /config/cs-syscfg/configurations/
> +    autofdo  autofdo3  last_load_status  load  unload
> +    $ cat /config/cs-syscfg/configurations/last_load_status
> +    OK: configuration file loaded (autofdo3).
> +
> +To unload, use the same file in the unload attribute::
> +
> +    $ cat example1.cscfg > /config/cs-syscfg/configurations/unload
> +    $ cat /config/cs-syscfg/configurations/last_load_status
> +    OK: configuration file unloaded (autofdo3).
> +    ls /config/cs-syscfg/configurations/
> +    autofdo  last_load_status  load  unload

I'm not certain that "last_load_status" is needed.  To me seeing the name of a
newly added configuration should be enough to confirm a successful status.  The
same applies to unload.

Thanks,
Mathieu

> +
> +The generator and reader programs can also be built directly, separately from
> +the kernel build by using the 'Makefile.host' file. This allows native binaries
> +to be created on the host machine rather than cross compiled version for the
> +target.
> +
> +
> +Binary Configuration File Format
> +--------------------------------
> +
> +The file format is defined in the source file **coresight-config-file.h**
> +
> +The source reader and generator examples produce a binary of this format.
> +
> +This arrangement is reproduced below:-
> +
> +Overall File structure
> +~~~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_header]   // Mandatory
> +   [CONFIG_ELEM]         // Optional - one per file, if present, first element in file.
> +   [FEATURE_ELEM]*       // Optional - multiple, defined by cscfg_file_header.nr_features
> +
> +File is invalid if both [CONFIG_ELEM] and [FEATURE_ELEM] are omitted.
> +
> +A file that contains only [FEATURE_ELEM] may be loaded, and the features used
> +by subsequently loaded files with [CONFIG_ELEM] elements.
> +
> +Where [CONFIG_ELEM] is present, then **cscfg_file_header.nr_features** and
> +**CONFIG_ELEM.nr_feat_refs** must have the same value.
> +
> +CONFIG_ELEM element
> +~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_header]                // header length value to end of feature strings.
> +   [cscfg_file_elem_str]                   // name of the configuration.
> +   [cscfg_file_elem_str]                   // description of configuration.
> +   [u16 value](nr_presets)                 // number of defined presets.
> +   [u32 value](nr_total_params)            // total parameters defined by all used features.
> +   [u16 value](nr_feat_refs)               // number of features referenced by the configuration
> +   [u64 values] * (nr_presets * nr_total_params)     // the preset values.
> +   [cscfg_file_elem_str] * (nr_feat_refs)  // the features used in the configurations.
> +
> +FEATURE_ELEM element
> +~~~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_header]                // header length is total bytes to end of param structures.
> +   [cscfg_file_elem_str]                   // feature name.
> +   [cscfg_file_elem_str]                   // feature description.
> +   [u32 value](match_flags)                // flags to associate the feature with a device.
> +   [u16 value](nr_regs)                    // number of registers.
> +   [u16 value](nr_params)                  // number of parameters.
> +   [cscfg_regval_desc struct] * (nr_regs)  // register definitions
> +   [PARAM_ELEM] * (nr_params)              // parameters definitions
> +
> +PARAM_ELEM element
> +~~~~~~~~~~~~~~~~~~
> +
> +::
> +
> +   [cscfg_file_elem_str]         // parameter name.
> +   [u64 value](param_value]      // initial value.
> +
> +Additional definitions.
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +The following structures are defined in **coresight-config-file.h**
> +
> + * **struct cscfg_file_header** : This structure contains an initial magic number, the total
> +   length of the file, and the number of features in the file.
> + * **struct cscfg_file_elem_header**: This defines the total length and type of a CONFIG_ELEM
> +   or a FEATURE_ELEM.
> + * **struct cscfg_file_elem_str**: This defines a string and its length.
> +
> +The magic number in cscfg_file_header is defined as two bitfields::
> +
> +   [31:8] Fixed magic number to identify file type.
> +   [7:0]  Current file format version.
> +
> +The following defines determine the maximum overall file size and maximum individual
> +string size::
> +
> +   CSCFG_FILE_MAXSIZE       // maximum overall file size.
> +   CSCFG_FILE_STR_MAXSIZE   // maximum individual string size.
> -- 
> 2.17.1
> 


From pierre-louis.bossart at linux.intel.com  Thu Jan 13 10:40:33 2022
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Thu, 13 Jan 2022 12:40:33 -0600
Subject: [PATCH v3 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220113082234.29013-2-allen-kh.cheng@mediatek.com>
References: <20220113082234.29013-1-allen-kh.cheng@mediatek.com>
 <20220113082234.29013-2-allen-kh.cheng@mediatek.com>
Message-ID: <32e116f5-7b71-2fe0-ad43-3fbc71a651a5@linux.intel.com>



On 1/13/22 2:22 AM, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> Some of mediatek processors contain
> the Tensilica HiFix DSP for audio processing.
> 
> The communication between Host CPU and DSP firmware is
> taking place using a shared memory area for message passing.
> 
> ADSP IPC protocol offers (send/recv) interfaces using
> mediatek-mailbox APIs.
> 
> We use two mbox channels to implement a request-reply protocol.
> 
> Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>
> Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>



From vladimir.murzin at arm.com  Thu Jan 13 10:42:50 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 13 Jan 2022 18:42:50 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <20211222181607.1203191-10-andre.przywara@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
Message-ID: <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>

Hi Andre,

On 12/22/21 6:16 PM, Andre Przywara wrote:
> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> the blob first, then re-compile it with our nodes and properties added.
> 
> In our input DTB the proper phandle references have already been lost,
> all we see in the DTB is phandle properties in the target node, and some
> numbers in the clocks and gpios properties:
> ===========
> 	clk24mhz {
> 		compatible = "fixed-clock";
> 		#clock-cells = <0x00>;
> 		clock-frequency = <0x16e3600>;
> 		clock-output-names = "v2m:clk24mhz";
> ->		phandle = <0x05>;
> 	};
> 	...
> 	serial at 90000 {
> 		compatible = "arm,pl011", "arm,primecell";
> 		reg = <0x90000 0x1000>;
> 		interrupts = <0x05>;
> ->		clocks = <0x05 0x05>;
> 		clock-names = "uartclk", "apb_pclk";
> 	};
> ===========
> dtc warns that those numbers might be wrong:
> =========
> <stdin>:177.6-27: Warning (clocks_property):
>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
>    clocks: cell 0 is not a phandle reference
> ....
> =========
> The proper solution would be to use references (&v2m_clk24mhz) instead,
> as there are in the source .dts file, but we don't have that information
> anymore, and cannot easily recover it.
> 
> To avoid the lengthy list of warnings, just drop those checks from the
> dtc compilation run. This disables more checks than we want or need, but
> we somewhat trust in the original DTB to be sane, so that should be
> fine.
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
>  Makefile.am | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 3d8128f..430b4a9 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
>  
>  fdt.dtb: $(KERNEL_DTB) Makefile
> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
>  
>  # The filesystem archive might not exist if INITRD is not being used
>  .PHONY: all clean $(FILESYSTEM)
> 

dtc 1.4.1 complains

FATAL ERROR: Unrecognized check name "clocks_property"

Cheers
Vladimir



From stefan.wahren at i2se.com  Thu Jan 13 10:42:57 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 13 Jan 2022 19:42:57 +0100
Subject: [PATCH v1 05/14] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <20220107180314.1816515-6-marcel@ziswiler.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-6-marcel@ziswiler.com>
Message-ID: <06d3ff4c-3c82-1b04-3dc7-3a6effe4cc3e@i2se.com>

Hi Marcel,

Am 07.01.22 um 19:03 schrieb Marcel Ziswiler:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>
> This avoids firmware load error and sysfs fallback reported as follows:
>
> [    0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
>  for imx/sdma/sdma-imx7d.bin failed with error -2
> [    0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
>  fallback for: imx/sdma/sdma-imx7d.bin

unfortunately this isn't an explanation why this solve the issue. It
looks like that the SDMA firmware is not available for the kernel. Build
the driver as a module hide the issue and just load it if the rootfs is
available.

What makes you sure that the driver is not critical for other boards
during boot?

Best regards

>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> ---
>
>  arch/arm64/configs/defconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> index 3c8106c5776a..a18785a827dc 100644
> --- a/arch/arm64/configs/defconfig
> +++ b/arch/arm64/configs/defconfig
> @@ -915,7 +915,7 @@ CONFIG_DMADEVICES=y
>  CONFIG_DMA_BCM2835=y
>  CONFIG_DMA_SUN6I=m
>  CONFIG_FSL_EDMA=y
> -CONFIG_IMX_SDMA=y
> +CONFIG_IMX_SDMA=m
>  CONFIG_K3_DMA=y
>  CONFIG_MV_XOR=y
>  CONFIG_MV_XOR_V2=y



From pierre-louis.bossart at linux.intel.com  Thu Jan 13 10:47:19 2022
From: pierre-louis.bossart at linux.intel.com (Pierre-Louis Bossart)
Date: Thu, 13 Jan 2022 12:47:19 -0600
Subject: [PATCH v13 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220113082103.27911-3-allen-kh.cheng@mediatek.com>
References: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
 <20220113082103.27911-3-allen-kh.cheng@mediatek.com>
Message-ID: <c876eda8-1fde-6c40-117a-12dde042780d@linux.intel.com>



> +static int mtk_adsp_mbox_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct mtk_adsp_mbox_priv *priv;
> +	const struct mtk_adsp_mbox_cfg *cfg;
> +	struct mbox_controller *mbox;
> +	int ret, irq;
> +
> +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	mbox = &priv->mbox;
> +	mbox->dev = dev;
> +	mbox->ops = &mtk_adsp_mbox_chan_ops;
> +	mbox->txdone_irq = false;
> +	mbox->txdone_poll = true;
> +	mbox->of_xlate = mtk_adsp_mbox_xlate;
> +	mbox->num_chans = 1;
> +	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
> +	if (!mbox->chans)
> +		return -ENOMEM;
> +
> +	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(priv->va_mboxreg))
> +		return PTR_ERR(priv->va_mboxreg);
> +
> +	priv->cfg = of_device_get_match_data(dev);

question: is any error handling needed here? some drivers do, others
don't, but that function can return NULL.

> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (irq < 0)
> +		return irq;
> +
> +	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
> +					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
> +					dev_name(dev), mbox->chans);
> +	if (ret < 0)
> +		return ret;
> +
> +	platform_set_drvdata(pdev, priv);
> +
> +	return devm_mbox_controller_register(dev, &priv->mbox);
> +}



From olof at lixom.net  Thu Jan 13 10:53:55 2022
From: olof at lixom.net (Olof Johansson)
Date: Thu, 13 Jan 2022 10:53:55 -0800
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>
Message-ID: <CAOesGMjZ8X3r2KvPLWWwJj1ckTruiGOjx9wLyu8YbCxW+OaZgQ@mail.gmail.com>

On Thu, Jan 13, 2022 at 4:32 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 13/01/2022 13:11, Alim Akhtar wrote:
> > This patch set adds basic support for the Tesla Full Self-Driving (FSD)
> > SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> > as well as several IPs.
> >
> > Patches 1 to 8 provide support for the clock controller
> > (which is designed similarly to Exynos SoCs).
> >
> > The remaining changes provide pinmux support, initial device tree support,
> > and SPI, ADC, and MCT IP functionality.
>
> Does FSD have some version number? The FDS, especially in compatibles,
> looks quite generic, so what will happen if a newer SoC comes later? You
> would have:
>  - tesla,fsd-pinctrl
>  - tesla,fsd-xxxx-pinctrl (where xxxx could be some new version)
>
> This will be extra confusing, because fsd-pinctrl looks like the generic
> one, while it is specific...

The public sources from Tesla on github uses "turbo,trav" here, but
that's also not a versioned name. The platform itself (hw3/hw31 -- 3.1
I presume?) has numbering, but that's system and not SoC:
https://github.com/teslamotors/linux/tree/tesla-4.14-hw3/arch/arm64/boot/dts/turbo

It would be easy to do "fsd2" for naming/numbering if needed for
future versions, for example. I'm not so worried about this,
especially if there's no corresponding internal version numbering that
this would map naturally to.


-Olof


From stefan.wahren at i2se.com  Thu Jan 13 10:55:58 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 13 Jan 2022 19:55:58 +0100
Subject: [PATCH 1/2] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <20220109114120.386013-2-alistair@alistair23.me>
References: <20220109114120.386013-1-alistair@alistair23.me>
 <20220109114120.386013-2-alistair@alistair23.me>
Message-ID: <4c5df296-b930-f65f-1106-c00889f1cdc1@i2se.com>

Hi,

Am 09.01.22 um 12:41 schrieb Alistair Francis:
> The i.MX watchdog cannot be disabled by softwrae once it has been
s/softwrae/software/
> enabled. This means that it can't be stopped before suspend.
>
> For systems that enter low power mode this is fine, as the watchdog will
> be automatically stopped by hardwrae in low power mode. Not all i.MX
s/hardwrae/hardware/
> platforms support low power mode in the mainline kernel. For example the
> i.MX7D does not enter low power mode and so will be rebooted 2 minutes
> after entering freeze or mem sleep states.
>
> This patch introduces a device tree property "fsl,ping-during-suspend"
> that can be used to enable ping on suspend support for these systems.

Introducing vendor specific properties for Linux behavior should be
avoided. The DT should describe just the hardware.

In case i.mx7d is affected, how about enabling this workaround for
compatible fsl,imx7d-wdt? This has the advantage that in case low power
mode will be implemented
<https://elixir.bootlin.com/linux/latest/B/ident/fsl%2Cimx7d-wdt>, we
don't have to care about DTB files.

Best regards

>
> Signed-off-by: Alistair Francis <alistair at alistair23.me>
> ---
>  .../bindings/watchdog/fsl-imx-wdt.yaml        |  7 ++++++
>  drivers/watchdog/imx2_wdt.c                   | 22 +++++++++++++------
>  2 files changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
> index fb7695515be1..b8660a3c456c 100644
> --- a/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx-wdt.yaml
> @@ -55,6 +55,13 @@ properties:
>        If present, the watchdog device is configured to assert its
>        external reset (WDOG_B) instead of issuing a software reset.
>  
> +  fsl,ping-during-suspend:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description: |
> +      If present, the kernel will ping the watchdog during suspend.
> +      This should be used on platforms that don't enter low power mode
> +      during suspend.
> +
>  required:
>    - compatible
>    - interrupts
> diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
> index 51bfb796898b..9a5fdb3173a8 100644
> --- a/drivers/watchdog/imx2_wdt.c
> +++ b/drivers/watchdog/imx2_wdt.c
> @@ -66,6 +66,7 @@ struct imx2_wdt_device {
>  	struct watchdog_device wdog;
>  	bool ext_reset;
>  	bool clk_is_on;
> +	bool no_ping;
>  };
>  
>  static bool nowayout = WATCHDOG_NOWAYOUT;
> @@ -312,12 +313,14 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
>  
>  	wdev->ext_reset = of_property_read_bool(dev->of_node,
>  						"fsl,ext-reset-output");
> +	wdev->no_ping = !of_property_read_bool(dev->of_node, "fsl,ping-during-suspend");
>  	platform_set_drvdata(pdev, wdog);
>  	watchdog_set_drvdata(wdog, wdev);
>  	watchdog_set_nowayout(wdog, nowayout);
>  	watchdog_set_restart_priority(wdog, 128);
>  	watchdog_init_timeout(wdog, timeout, dev);
> -	watchdog_stop_ping_on_suspend(wdog);
> +	if (wdev->no_ping)
> +		watchdog_stop_ping_on_suspend(wdog);
>  
>  	if (imx2_wdt_is_running(wdev)) {
>  		imx2_wdt_set_timeout(wdog, wdog->timeout);
> @@ -366,9 +369,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
>  		imx2_wdt_ping(wdog);
>  	}
>  
> -	clk_disable_unprepare(wdev->clk);
> +	if (wdev->no_ping) {
> +		clk_disable_unprepare(wdev->clk);
>  
> -	wdev->clk_is_on = false;
> +		wdev->clk_is_on = false;
> +	}
>  
>  	return 0;
>  }
> @@ -380,11 +385,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
>  	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
>  	int ret;
>  
> -	ret = clk_prepare_enable(wdev->clk);
> -	if (ret)
> -		return ret;
> +	if (wdev->no_ping) {
> +		ret = clk_prepare_enable(wdev->clk);
>  
> -	wdev->clk_is_on = true;
> +		if (ret)
> +			return ret;
> +
> +		wdev->clk_is_on = true;
> +	}
>  
>  	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
>  		/*



From pr-tracker-bot at kernel.org  Thu Jan 13 11:23:12 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Thu, 13 Jan 2022 19:23:12 +0000
Subject: [GIT PULL] Mailbox changes for v5.17
In-Reply-To: <CABb+yY3o9pOY1EbedNRM_++MxM8TNFrB3EbrZ+07h_p3O4i1LA@mail.gmail.com>
References: <CABb+yY3o9pOY1EbedNRM_++MxM8TNFrB3EbrZ+07h_p3O4i1LA@mail.gmail.com>
Message-ID: <164210179242.5840.17018685949925089577.pr-tracker-bot@kernel.org>

The pull request you sent on Wed, 12 Jan 2022 20:28:54 -0600:

> git://git.linaro.org/landing-teams/working/fujitsu/integration.git tags/mailbox-v5.17

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/fb3b0673b7d5b477ed104949450cd511337ba3c6

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From linux at roeck-us.net  Thu Jan 13 11:43:07 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 13 Jan 2022 11:43:07 -0800
Subject: [PATCH 1/2] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <4c5df296-b930-f65f-1106-c00889f1cdc1@i2se.com>
References: <20220109114120.386013-1-alistair@alistair23.me>
 <20220109114120.386013-2-alistair@alistair23.me>
 <4c5df296-b930-f65f-1106-c00889f1cdc1@i2se.com>
Message-ID: <4c3056df-2ae6-04d7-30cb-cd478f089266@roeck-us.net>

On 1/13/22 10:55 AM, Stefan Wahren wrote:
> Hi,
> 
> Am 09.01.22 um 12:41 schrieb Alistair Francis:
>> The i.MX watchdog cannot be disabled by softwrae once it has been
> s/softwrae/software/
>> enabled. This means that it can't be stopped before suspend.
>>
>> For systems that enter low power mode this is fine, as the watchdog will
>> be automatically stopped by hardwrae in low power mode. Not all i.MX
> s/hardwrae/hardware/
>> platforms support low power mode in the mainline kernel. For example the
>> i.MX7D does not enter low power mode and so will be rebooted 2 minutes
>> after entering freeze or mem sleep states.
>>
>> This patch introduces a device tree property "fsl,ping-during-suspend"
>> that can be used to enable ping on suspend support for these systems.
> 
> Introducing vendor specific properties for Linux behavior should be
> avoided. The DT should describe just the hardware.
> 
> In case i.mx7d is affected, how about enabling this workaround for
> compatible fsl,imx7d-wdt? This has the advantage that in case low power
> mode will be implemented
> <https://elixir.bootlin.com/linux/latest/B/ident/fsl%2Cimx7d-wdt>, we
> don't have to care about DTB files.
> 

Agreed.

Guenter


From andre.przywara at arm.com  Thu Jan 13 11:50:51 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 13 Jan 2022 19:50:51 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
 <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
Message-ID: <20220113195051.7100b066@slackpad.fritz.box>

On Thu, 13 Jan 2022 18:42:50 +0000
Vladimir Murzin <vladimir.murzin at arm.com> wrote:

Hi Vladimir,

> On 12/22/21 6:16 PM, Andre Przywara wrote:
> > When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> > the blob first, then re-compile it with our nodes and properties added.
> > 
> > In our input DTB the proper phandle references have already been lost,
> > all we see in the DTB is phandle properties in the target node, and some
> > numbers in the clocks and gpios properties:
> > ===========
> > 	clk24mhz {
> > 		compatible = "fixed-clock";
> > 		#clock-cells = <0x00>;
> > 		clock-frequency = <0x16e3600>;
> > 		clock-output-names = "v2m:clk24mhz";  
> > ->		phandle = <0x05>;  
> > 	};
> > 	...
> > 	serial at 90000 {
> > 		compatible = "arm,pl011", "arm,primecell";
> > 		reg = <0x90000 0x1000>;
> > 		interrupts = <0x05>;  
> > ->		clocks = <0x05 0x05>;  
> > 		clock-names = "uartclk", "apb_pclk";
> > 	};
> > ===========
> > dtc warns that those numbers might be wrong:
> > =========
> > <stdin>:177.6-27: Warning (clocks_property):
> >  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
> >    clocks: cell 0 is not a phandle reference
> > ....
> > =========
> > The proper solution would be to use references (&v2m_clk24mhz) instead,
> > as there are in the source .dts file, but we don't have that information
> > anymore, and cannot easily recover it.
> > 
> > To avoid the lengthy list of warnings, just drop those checks from the
> > dtc compilation run. This disables more checks than we want or need, but
> > we somewhat trust in the original DTB to be sane, so that should be
> > fine.
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  Makefile.am | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/Makefile.am b/Makefile.am
> > index 3d8128f..430b4a9 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
> >  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
> >  
> >  fdt.dtb: $(KERNEL_DTB) Makefile
> > -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> > +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
> >  
> >  # The filesystem archive might not exist if INITRD is not being used
> >  .PHONY: all clean $(FILESYSTEM)
> >   
> 
> dtc 1.4.1 complains

Which distro ships this version? (distrowatch doesn't list dtc)

tag v1.4.1
Tagger: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Nov 12 14:31:44 2014 +1100

Any chance it's just you and you can update this? It looks like the
first version to support it is 1.4.5, as shipped for instance with
Ubuntu 18.04.

> FATAL ERROR: Unrecognized check name "clocks_property"

Sigh, thanks for the heads up. I don't know if we want to blow up the
Makefile with a feature test?

Cheers,
Andre


From festevam at gmail.com  Thu Jan 13 12:01:34 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Thu, 13 Jan 2022 17:01:34 -0300
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge:
 display-connector: implement bus fmts callbacks")
In-Reply-To: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>

Hi Biju,

On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
>
> Hi All,
>
> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").
>
> After this patch, the screen becomes greenish(may be it is setting it into YUV format??).
>
> By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.
>
> After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
> And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.
>
> Not sure, I am the only one seeing this issue with dw_HDMI driver.

I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:

dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
(DWC HDMI 3D TX PHY)

The colors are shown correctly here.


From semen.protsenko at linaro.org  Thu Jan 13 12:37:54 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 13 Jan 2022 22:37:54 +0200
Subject: [PATCH] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
Message-ID: <20220113203754.23197-1-semen.protsenko@linaro.org>

The proper name is Exynos Auto V9, not V0. It was the typo slipped in
unnoticed, fix it.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/soc/samsung/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index a9f8b224322e..02e319508cc6 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -31,7 +31,7 @@ config EXYNOS_USI
 	help
 	  Enable support for USI block. USI (Universal Serial Interface) is an
 	  IP-core found in modern Samsung Exynos SoCs, like Exynos850 and
-	  ExynosAutoV0. USI block can be configured to provide one of the
+	  ExynosAutoV9. USI block can be configured to provide one of the
 	  following serial protocols: UART, SPI or High Speed I2C.
 
 	  This driver allows one to configure USI for desired protocol, which
-- 
2.30.2



From lkp at intel.com  Thu Jan 13 13:01:48 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 14 Jan 2022 05:01:48 +0800
Subject: [PATCH v5 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <20220112230247.982212-6-iwona.winiarska@intel.com>
References: <20220112230247.982212-6-iwona.winiarska@intel.com>
Message-ID: <202201140455.rWgkX1hh-lkp@intel.com>

Hi Iwona,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on groeck-staging/hwmon-next]
[also build test ERROR on linux/master linus/master v5.16 next-20220113]
[cannot apply to joel-aspeed/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Iwona-Winiarska/Introduce-PECI-subsystem/20220113-071131
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: ia64-randconfig-r033-20220113 (https://download.01.org/0day-ci/archive/20220114/202201140455.rWgkX1hh-lkp at intel.com/config)
compiler: ia64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/9b4f2401a427cff2efc191f507d73ec8ae1ad872
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Iwona-Winiarska/Introduce-PECI-subsystem/20220113-071131
        git checkout 9b4f2401a427cff2efc191f507d73ec8ae1ad872
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=ia64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "devm_clk_hw_register" [drivers/peci/controller/peci-aspeed.ko] undefined!
>> ERROR: modpost: "__clk_get_name" [drivers/peci/controller/peci-aspeed.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From iwona.winiarska at intel.com  Thu Jan 13 13:02:54 2022
From: iwona.winiarska at intel.com (Winiarska, Iwona)
Date: Thu, 13 Jan 2022 21:02:54 +0000
Subject: [PATCH v5 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <CACPK8XewQJBvwssM6zQKQoxT=JLpk-qjGhsiTAa980OtbU7JBw@mail.gmail.com>
References: <20220112230247.982212-1-iwona.winiarska@intel.com>
 <20220112230247.982212-6-iwona.winiarska@intel.com>
 <CACPK8XewQJBvwssM6zQKQoxT=JLpk-qjGhsiTAa980OtbU7JBw@mail.gmail.com>
Message-ID: <f2a7582d6ea4bd7fc04f3a31c98fdd8b80e46296.camel@intel.com>

On Thu, 2022-01-13 at 04:12 +0000, Joel Stanley wrote:
> On Wed, 12 Jan 2022 at 23:06, Iwona Winiarska <iwona.winiarska at intel.com> wrote:
> > 
> > From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > 
> > ASPEED AST24xx/AST25xx/AST26xx SoCs support the PECI electrical
> > interface (a.k.a PECI wire) that provides a communication channel with
> > Intel processors.
> > This driver allows BMC to discover devices connected to it and
> > communicate with them using PECI protocol.
> > 
> > Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
> > Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
> > Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> 
> The driver looks good to me. I would be happy to see it merged in its
> current state.
> 
> Reviewed-by: Joel Stanley <joel at jms.id.au>

Thank you :)

> 
> I've a few questions below that can be followed up later if need be.
> 
> > +
> > +static void aspeed_peci_init_regs(struct aspeed_peci *priv)
> > +{
> > +?????? u32 val;
> > +
> > +?????? /* Clear interrupts */
> > +?????? val = readl(priv->base + ASPEED_PECI_INT_STS) | ASPEED_PECI_INT_MASK;
> 
> Should that be & MASK?
> 
> As you're just sanitising the registers, you could clear the status
> unconditionally:
> 
> ?writel(ASPEED_PECI_INT_MASK, priv->base + ASPEED_PECI_INT_STS);
> 

The idea is to not modify any other fields in this register and write 1's only
to INT_MASK.
In theory the other fields are RO, but I already found that touching reserved
fields in other registers may make the HW upset.
I'll check whether clearing unconditionally works here.

> > +?????? writel(val, priv->base + ASPEED_PECI_INT_STS);
> > +
> > +?????? /* Set timing negotiation mode and enable interrupts */
> > +?????? val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK,
> > ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
> 
> That's a complicated way to set val to zero :)

Agreed - however, you can think of it as a way to document the programming
sequence :)

> 
> > +?????? val |= ASPEED_PECI_INT_MASK;
> > +?????? writel(val, priv->base + ASPEED_PECI_INT_CTRL);
> > +
> > +?????? val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK,
> > ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT);
> > +?????? writel(val, priv->base + ASPEED_PECI_CTRL);
> 
> This will clear the rest of the ctrl register, including the divisor
> settings. Was that your intention?

Yes, it was my intention - the register is initialized with "random" values so
it requires to be cleared when we first accessed it (if we just RMW it, the HW
gets upset).
> 
> Reading the rest of your driver you only call _init_regs after
> _controller_enable, so I guess you're fine.

aspeed_peci_init_regs() is always called after controller reset, any other
register programming is going to happen later on (with RMW). 

> 
> > +}
> > +
> > +static int aspeed_peci_check_idle(struct aspeed_peci *priv)
> > +{
> > +?????? u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
> > +?????? int ret;
> > +
> > +?????? /*
> > +??????? * Under normal circumstances, we expect to be idle here.
> > +??????? * In case there were any errors/timeouts that led to the situation
> > +??????? * where the hardware is not in idle state - we need to reset and
> > +??????? * reinitialize it to avoid potential controller hang.
> > +??????? */
> > +?????? if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts)) {
> > +?????????????? reset_control_assert(priv->rst);
> > +
> > +?????????????? ret = reset_control_deassert(priv->rst);
> > +?????????????? if (ret) {
> > +?????????????????????? dev_err(priv->dev, "cannot deassert reset control\n");
> > +?????????????????????? return ret;
> > +?????????????? }
> > +
> > +?????????????? aspeed_peci_init_regs(priv);
> > +
> > +?????????????? ret = clk_set_rate(priv->clk, priv->clk_frequency);
> > +?????????????? if (ret < 0) {
> > +?????????????????????? dev_err(priv->dev, "cannot set clock frequency\n");
> > +?????????????????????? return ret;
> > +?????????????? }
> > +
> > +?????????????? aspeed_peci_controller_enable(priv);
> > +?????? }
> > +
> > +?????? return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
> > +???????????????????????????????? cmd_sts,
> > +???????????????????????????????? !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
> > +???????????????????????????????? ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
> > +???????????????????????????????? ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
> > +}
> > +
> > +static int aspeed_peci_xfer(struct peci_controller *controller,
> > +?????????????????????????? u8 addr, struct peci_request *req)
> > +{
> > +?????? struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
> > +?????? unsigned long timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
> > +?????? u32 peci_head;
> > +?????? int ret;
> > +
> > +?????? if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
> > +?????????? req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
> > +?????????????? return -EINVAL;
> > +
> > +?????? /* Check command sts and bus idle state */
> > +?????? ret = aspeed_peci_check_idle(priv);
> > +?????? if (ret)
> > +?????????????? return ret; /* -ETIMEDOUT */
> > +
> > +?????? spin_lock_irq(&priv->lock);
> > +?????? reinit_completion(&priv->xfer_complete);
> > +
> > +?????? peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
> > +?????????????????? FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
> > +?????????????????? FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
> > +
> > +?????? writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
> > +
> > +?????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA0, req->tx.buf, min_t(u8,
> > req->tx.len, 16));
> > +?????? if (req->tx.len > 16)
> > +?????????????? memcpy_toio(priv->base + ASPEED_PECI_WR_DATA4, req->tx.buf +
> > 16,
> > +?????????????????????????? req->tx.len - 16);
> > +
> > +#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
> > +?????? dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
> > +?????? print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req-
> > >tx.len);
> > +#endif
> 
> The ifdef is unfortunate. Could you do this?
> 
> dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
> if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG))
> ?????? print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf,
> req->tx.len);
> 
> Not a biggie though, don't let this hold up merging.

I don't understand why should we treat HEAD differently that the rest of the
buffer. Ultimately (looking at this from the PECI protocol level) this is just a
part of TX packet.
Overall, this is the "hot path" of this particular driver - the ifdef is here to
avoid dumping all packets all the time (which would happen if dynamic debug is
not present).

Thanks
-Iwona

> 
> > +?????? priv->status = 0;
> > +?????? writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
> > +?????? spin_unlock_irq(&priv->lock);
> > +


From geissonator at gmail.com  Thu Jan 13 13:17:34 2022
From: geissonator at gmail.com (Andrew Geissler)
Date: Thu, 13 Jan 2022 15:17:34 -0600
Subject: [PATCH 1/2] ARM: dts: aspeed: rainier: add reset-cause-pinhole
Message-ID: <20220113211735.37861-1-geissonator@yahoo.com>

This GPIO is used on the rainier system to indicate the BMC was reset
due to a physical pinhole reset.

See the following doc for more information:
https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md

Signed-off-by: Andrew Geissler <geissonator at yahoo.com>
---
 arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
index cfaa606666e2..7ea70c7d698f 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
@@ -247,7 +247,8 @@ &gpio0 {
 	/*C0-C7*/	"","","","","","","","",
 	/*D0-D7*/	"","","","","","","","",
 	/*E0-E7*/	"","","","","","","","",
-	/*F0-F7*/	"","","battery-voltage-read-enable","","","","factory-reset-toggle","",
+	/*F0-F7*/	"","","battery-voltage-read-enable","reset-cause-pinhole","","",
+				"factory-reset-toggle","",
 	/*G0-G7*/	"","","","","","","","",
 	/*H0-H7*/	"","bmc-ingraham0","rear-enc-id0","rear-enc-fault0","","","","",
 	/*I0-I7*/	"","","","","","","bmc-secure-boot","",
-- 
2.25.1



From geissonator at gmail.com  Thu Jan 13 13:17:35 2022
From: geissonator at gmail.com (Andrew Geissler)
Date: Thu, 13 Jan 2022 15:17:35 -0600
Subject: [PATCH 2/2] ARM: dts: aspeed: everest: add reset-cause-pinhole
In-Reply-To: <20220113211735.37861-1-geissonator@yahoo.com>
References: <20220113211735.37861-1-geissonator@yahoo.com>
Message-ID: <20220113211735.37861-2-geissonator@yahoo.com>

This GPIO is used on the everest system to indicate the BMC was reset
due to a physical pinhole reset.

It has been verified that the previous name for this pin has not been
utilized by userspace so the name change is ok.

See the following doc for more information:
https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md

Signed-off-by: Andrew Geissler <geissonator at yahoo.com>
---
 arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
index f48b33b0c606..6b5d5c56951f 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-everest.dts
@@ -271,7 +271,7 @@ &gpio0 {
 	/*D0-D7*/	"","","","","","","","",
 	/*E0-E7*/	"","","","","","","","",
 	/*F0-F7*/	"PIN_HOLE_RESET_IN_N","","battery-voltage-read-enable",
-				"PIN_HOLE_RESET_OUT_N","","",
+				"reset-cause-pinhole","","",
 				"factory-reset-toggle","",
 	/*G0-G7*/	"","","","","","","","",
 	/*H0-H7*/	"led-rtc-battery","led-bmc","led-rear-enc-id0","led-rear-enc-fault0","","","","",
-- 
2.25.1



From sboyd at kernel.org  Thu Jan 13 13:28:00 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:28:00 -0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113115745.45826-2-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-2-liang.yang@amlogic.com>
Message-ID: <20220113212801.E88BFC36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:42)
> diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
> index 76d31c0a3342..79c9efd28115 100644
> --- a/drivers/clk/meson/sclk-div.c
> +++ b/drivers/clk/meson/sclk-div.c
> @@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
>         return (struct meson_sclk_div_data *)clk->data;
>  }
>  
> -static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
> +static inline int sclk_get_reg(int val, unsigned char flag)
>  {
> -       return (1 << sclk->div.width) - 1;
> +       if ((flag & MESON_SCLK_ONE_BASED) || !val)
> +               return val;
> +       else
> +               return val - 1;

Please drop the else

> +}
> +
> +static inline int sclk_get_divider(int reg, unsigned char flag)
> +{
> +       if (flag & MESON_SCLK_ONE_BASED)
> +               return reg;
> +       else

Please drop the else

> +               return reg + 1;
>  }
>  
>  static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
>  {
> -       return sclk_div_maxval(sclk) + 1;


From sboyd at kernel.org  Thu Jan 13 13:29:26 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:29:26 -0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113115745.45826-3-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-3-liang.yang@amlogic.com>
Message-ID: <20220113212928.28C10C36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:43)
> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
> index b3ef5f67820f..c450f38d3801 100644
> --- a/drivers/clk/meson/Makefile
> +++ b/drivers/clk/meson/Makefile
> @@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
>  obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
>  obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
>  obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
> +obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o

Sort by Kconfig symbol?

>  
>  # Amlogic Clock controllers
>


From sboyd at kernel.org  Thu Jan 13 13:29:56 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:29:56 -0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113115745.45826-4-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
Message-ID: <20220113212957.768FFC36AE3@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:44)
> Document the MMC sub clock controller driver, the potential consumer
> of this driver is MMC or NAND. Also add four clock bindings IDs which
> provided by this driver.
> 
> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>  include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>  2 files changed, 78 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>  create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> 
> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> new file mode 100644
> index 000000000000..a274c3d5fc2e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> @@ -0,0 +1,64 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
> +
> +maintainers:
> +  - jianxin.pan at amlogic.com
> +  - liang.yang at amlogic.com
> +
> +properties:
> +  compatible:
> +    enum:
> +      - "amlogic,axg-mmc-clkc", "syscon"

Why is it a syscon?


From sboyd at kernel.org  Thu Jan 13 13:35:12 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 13:35:12 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113115745.45826-5-liang.yang@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
Message-ID: <20220113213513.9819AC36AEA@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 03:57:45)
> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
> index bb0f59eea366..3de6f3b24461 100644
> --- a/drivers/clk/meson/Kconfig
> +++ b/drivers/clk/meson/Kconfig
> @@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
>         select COMMON_CLK_MESON_REGMAP
>         select RESET_CONTROLLER
>  
> +config COMMON_CLK_MMC_MESON
> +       tristate "Meson MMC Sub Clock Controller Driver"
> +       depends on ARCH_MESON || COMPILE_TEST
> +       select MFD_SYSCON
> +       select COMMON_CLK_AMLOGIC
> +       select COMMON_CLK_MESON_PHASE
> +       select COMMON_CLK_MESON_PHASE_DELAY
> +       select COMMON_CLK_MESON_SCLK_DIV
> +       help
> +         Support for the MMC sub clock controller on
> +         Amlogic Meson Platform, which includes S905 (GXBB, GXL),
> +         A113D/X (AXG) devices . Say Y if you want this

s/devices /devices/

> +         clock enabled.
> +
>  config COMMON_CLK_MESON_EE_CLKC
>         tristate
>         select COMMON_CLK_MESON_REGMAP
> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> new file mode 100644
> index 000000000000..f53977f61390
> --- /dev/null
> +++ b/drivers/clk/meson/mmc-clkc.c
> @@ -0,0 +1,300 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/amlogic,mmc-clkc.h>
> +
> +#include "sclk-div.h"
> +#include "clk-phase-delay.h"
> +#include "clk-regmap.h"
> +#include "clk-phase.h"
> +
> +/* clock ID used by internal driver */
> +
> +#define SD_EMMC_CLOCK          0
> +#define CLK_DELAY_STEP_PS_GX   200
> +#define CLK_DELAY_STEP_PS_AXG  78
> +#define MUX_CLK_NUM_PARENTS    2
> +#define MMC_MAX_CLKS           4
> +
> +struct mmc_clkc_data {
> +       struct meson_clk_phase_delay_data tx;
> +       struct meson_clk_phase_delay_data rx;
> +};
> +
> +static struct clk_regmap_mux_data mmc_clkc_mux_data = {
> +       .offset = SD_EMMC_CLOCK,
> +       .mask   = 0x3,
> +       .shift  = 6,
> +};
> +
> +static const struct meson_sclk_div_data mmc_clkc_div_data = {
> +       .div = {
> +               .reg_off = SD_EMMC_CLOCK,
> +               .width   = 6,
> +       },
> +       .flags = MESON_SCLK_ONE_BASED,
> +};
> +
> +static struct meson_clk_phase_data mmc_clkc_core_phase = {
> +       .ph = {
> +               .reg_off = SD_EMMC_CLOCK,
> +               .shift   = 8,
> +               .width   = 2,
> +       }
> +};
> +
> +static const struct mmc_clkc_data mmc_clkc_gx_data = {
> +       .tx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 10,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 16,
> +                       .width   = 4,
> +               },
> +               .delay_step_ps = CLK_DELAY_STEP_PS_GX,
> +       },
> +       .rx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 12,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 20,
> +                       .width   = 4,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_GX,
> +       },
> +};
> +
> +static const struct mmc_clkc_data mmc_clkc_axg_data = {
> +       .tx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 10,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 16,
> +                       .width   = 6,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
> +       },
> +       .rx = {
> +               .phase = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 12,
> +                       .width   = 2,
> +               },
> +               .delay = {
> +                       .reg_off = SD_EMMC_CLOCK,
> +                       .shift   = 22,
> +                       .width   = 6,
> +               },
> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
> +       },
> +};
> +
> +static const struct of_device_id mmc_clkc_match_table[] = {
> +       {
> +               .compatible     = "amlogic,gx-mmc-clkc",
> +               .data           = &mmc_clkc_gx_data
> +       },
> +       {
> +               .compatible     = "amlogic,axg-mmc-clkc",
> +               .data           = &mmc_clkc_axg_data
> +       },
> +       {}
> +};
> +MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
> +
> +static struct clk_regmap *
> +mmc_clkc_register_clk(struct device *dev, struct regmap *map,
> +                     struct clk_init_data *init,
> +                     const char *suffix, void *data)
> +{
> +       struct clk_regmap *clk;
> +       char *name;
> +       int ret;
> +
> +       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
> +       if (!clk)
> +               return ERR_PTR(-ENOMEM);
> +
> +       name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
> +       if (!name)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init->name = name;
> +       clk->map = map;
> +       clk->data = data;
> +       clk->hw.init = init;
> +       ret = devm_clk_hw_register(dev, &clk->hw);
> +       if (ret)
> +               clk = ERR_PTR(ret);
> +
> +       kfree(name);
> +       return clk;
> +}
> +
> +static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
> +                                               struct regmap *map)
> +{
> +       const char *parent_names[MUX_CLK_NUM_PARENTS];
> +       struct clk_init_data init;
> +       struct clk_regmap *mux;
> +       struct clk *clk;
> +       int i;
> +
> +       for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
> +               char name[8];
> +
> +               snprintf(name, sizeof(name), "clkin%d", i);
> +               clk = devm_clk_get(dev, name);
> +               if (IS_ERR(clk)) {
> +                       if (clk != ERR_PTR(-EPROBE_DEFER))
> +                               dev_err(dev, "Missing clock %s\n", name);

Use dev_err_probe()?

> +                       return ERR_CAST(clk);
> +               }
> +
> +               parent_names[i] = __clk_get_name(clk);

Why can't we use clk_parent_data?

> +       }
> +
> +       init.ops = &clk_regmap_mux_ops;
> +       init.flags = CLK_SET_RATE_PARENT;
> +       init.parent_names = parent_names;
> +       init.num_parents = MUX_CLK_NUM_PARENTS;
> +
> +       mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
> +       if (IS_ERR(mux))
> +               dev_err(dev, "Mux clock registration failed\n");
> +
> +       return mux;
> +}
> +
> +static struct clk_regmap *
> +mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
> +                                 char *suffix, const struct clk_hw *hw,
> +                                 unsigned long flags,
> +                                 const struct clk_ops *ops, void *data)
> +{
> +       struct clk_init_data init;
> +       struct clk_regmap *clk;
> +       const char *parent_name = clk_hw_get_name(hw);
> +
> +       init.ops = ops;
> +       init.flags = flags;
> +       init.parent_names = &parent_name;
> +       init.num_parents = 1;
> +
> +       clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
> +       if (IS_ERR(clk))
> +               dev_err(dev, "%s clock registration failed\n", suffix);
> +
> +       return clk;
> +}
> +
> +static int mmc_clkc_probe(struct platform_device *pdev)
> +{
> +       struct clk_hw_onecell_data *onecell_data;
> +       struct device *dev = &pdev->dev;
> +       struct mmc_clkc_data *data;
> +       struct regmap *map;
> +       struct clk_regmap *clk, *core;
> +       struct meson_sclk_div_data *div_data;
> +
> +       /*cast to drop the const in match->data*/

Space after *, also why do we need to cast away const? The user of this
pointer passes it all the way down to mmc_clkc_register_clk() which
could take the data as const void pointer and decide to cast away const
there.

> +       data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
> +       if (!data)
> +               return -ENODEV;
> +
> +       map = syscon_node_to_regmap(dev->of_node);
> +       if (IS_ERR(map)) {
> +               dev_err(dev, "could not find mmc clock controller\n");
> +               return PTR_ERR(map);
> +       }
> +
> +       onecell_data = devm_kzalloc(dev,
> +                                   struct_size(onecell_data, hws,
> +                                               MMC_MAX_CLKS),
> +                                   GFP_KERNEL);
> +       if (!onecell_data)
> +               return -ENOMEM;
> +
> +       clk = mmc_clkc_register_mux(dev, map);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
> +       if (!div_data)
> +               return -ENOMEM;
> +
> +       memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
> +                                               &clk->hw,
> +                                               CLK_SET_RATE_PARENT,
> +                                               &meson_sclk_div_ops,
> +                                               div_data);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
> +       core = mmc_clkc_register_clk_with_parent(dev, map, "core",
> +                                                &clk->hw,
> +                                                CLK_SET_RATE_PARENT,
> +                                                &meson_clk_phase_ops,
> +                                                &mmc_clkc_core_phase);
> +       if (IS_ERR(core))
> +               return PTR_ERR(core);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
> +                                               &core->hw,  0,
> +                                               &meson_clk_phase_delay_ops,
> +                                               &data->rx);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
> +                                               &core->hw,  0,
> +                                               &meson_clk_phase_delay_ops,
> +                                               &data->tx);
> +       if (IS_ERR(clk))
> +               return PTR_ERR(clk);
> +
> +       onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
> +       onecell_data->num = MMC_MAX_CLKS;
> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
> +                                          onecell_data);
> +}
> +
> +static struct platform_driver mmc_clkc_driver = {
> +       .probe          = mmc_clkc_probe,
> +       .driver         = {
> +               .name   = "meson-mmc-clkc",
> +               .of_match_table = of_match_ptr(mmc_clkc_match_table),
> +       },
> +};
> +
> +module_platform_driver(mmc_clkc_driver);
> +
> +MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
> +MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
> +MODULE_LICENSE("GPL v2");


From joel at jms.id.au  Thu Jan 13 14:35:32 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 13 Jan 2022 22:35:32 +0000
Subject: [PATCH 1/2] ARM: dts: aspeed: rainier: add reset-cause-pinhole
In-Reply-To: <20220113211735.37861-1-geissonator@yahoo.com>
References: <20220113211735.37861-1-geissonator@yahoo.com>
Message-ID: <CACPK8XfY58odFjf0KNdYXa5MbCg=A07OEfuyjsbnmMtUmxG6ww@mail.gmail.com>

Hi Andrew,

On Thu, 13 Jan 2022 at 21:18, Andrew Geissler <geissonator at gmail.com> wrote:
>
> This GPIO is used on the rainier system to indicate the BMC was reset
> due to a physical pinhole reset.
>
> See the following doc for more information:
> https://github.com/openbmc/docs/blob/master/designs/device-tree-gpio-naming.md
>
> Signed-off-by: Andrew Geissler <geissonator at yahoo.com>

I couldn't apply these cleanly to any tree I had. I think you had a
patch to add battery-voltage-read-enable, but that's not in the tree
yet.

I fixed them up to apply.

Cheers,

Joel

> ---
>  arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
> index cfaa606666e2..7ea70c7d698f 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
> +++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
> @@ -247,7 +247,8 @@ &gpio0 {
>         /*C0-C7*/       "","","","","","","","",
>         /*D0-D7*/       "","","","","","","","",
>         /*E0-E7*/       "","","","","","","","",
> -       /*F0-F7*/       "","","battery-voltage-read-enable","","","","factory-reset-toggle","",
> +       /*F0-F7*/       "","","battery-voltage-read-enable","reset-cause-pinhole","","",
> +                               "factory-reset-toggle","",
>         /*G0-G7*/       "","","","","","","","",
>         /*H0-H7*/       "","bmc-ingraham0","rear-enc-id0","rear-enc-fault0","","","","",
>         /*I0-I7*/       "","","","","","","bmc-secure-boot","",
> --
> 2.25.1
>


From yuzhao at google.com  Thu Jan 13 15:02:15 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 16:02:15 -0700
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <87a6g0nczg.fsf@linux.ibm.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <87a6g0nczg.fsf@linux.ibm.com>
Message-ID: <YeCvd4UBPy27SYGZ@google.com>

On Thu, Jan 13, 2022 at 04:01:31PM +0530, Aneesh Kumar K.V wrote:
> Yu Zhao <yuzhao at google.com> writes:
> 
> > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> 
> 
> Got the below lockdep warning while using the above kill/enable switch
> 
> 
> [   84.252952] ======================================================
> [   84.253012] WARNING: possible circular locking dependency detected
> [   84.253074] 5.16.0-rc8-16204-g1cdcf1120b31 #511 Not tainted
> [   84.253135] ------------------------------------------------------
> [   84.253194] bash/2862 is trying to acquire lock:
> [   84.253243] c0000000021ff740 (cgroup_mutex){+.+.}-{3:3}, at: store_enable+0x80/0x1510
> [   84.253340]
>                but task is already holding lock:
> [   84.253410] c000000002221348 (mem_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x30/0x50
> [   84.253503]
>                which lock already depends on the new lock.
> 
> [   84.255933] Chain exists of:
>                  cgroup_mutex --> cpu_hotplug_lock --> mem_hotplug_lock

Thanks. Will reverse the order between mem_hotplug_lock and
cgroup_mutex in the next spin.


From john.stultz at linaro.org  Thu Jan 13 15:26:47 2022
From: john.stultz at linaro.org (John Stultz)
Date: Thu, 13 Jan 2022 15:26:47 -0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
Message-ID: <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>

On Thu, Jan 13, 2022 at 5:05 AM Christian K?nig
<christian.koenig at amd.com> wrote:
> Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
> >> -----Original Message-----
> >> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
> >> Ruhl, Michael J
> >>> -----Original Message-----
> >>> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
> >>> guangming.cao at mediatek.com
> >>> +   /*
> >>> +    * Invalid size check. The "len" should be less than totalram.
> >>> +    *
> >>> +    * Without this check, once the invalid size allocation runs on a process
> >>> that
> >>> +    * can't be killed by OOM flow(such as "gralloc" on Android devices), it
> >>> will
> >>> +    * cause a kernel exception, and to make matters worse, we can't find
> >>> who are using
> >>> +    * so many memory with "dma_buf_debug_show" since the relevant
> >>> dma-buf hasn't exported.
> >>> +    */
> >>> +   if (len >> PAGE_SHIFT > totalram_pages())
> >> If your "heap" is from cma, is this still a valid check?
> > And thinking a bit further, if I create a heap from something else (say device memory),
> > you will need to be able to figure out the maximum allowable check for the specific
> > heap.
> >
> > Maybe the heap needs a callback for max size?
>
> Well we currently maintain a separate allocator and don't use dma-heap,
> but yes we have systems with 16GiB device and only 8GiB system memory so
> that check here is certainly not correct.

Good point.

> In general I would rather let the system run into -ENOMEM or -EINVAL
> from the allocator instead.

Probably the simpler solution is to push the allocation check to the
heap driver, rather than doing it at the top level here.

For CMA or other contiguous heaps, letting the allocator fail is fast
enough. For noncontiguous buffers, like the system heap, the
allocation can burn a lot of time and consume a lot of memory (causing
other trouble) before a large allocation might naturally fail.

thanks
-john


From robh at kernel.org  Thu Jan 13 15:33:55 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 13 Jan 2022 17:33:55 -0600
Subject: [PATCH 01/23] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220113121143.22280-2-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122311epcas5p4b7c253b49dce3bd3580407fcf312e70e@epcas5p4.samsung.com>
 <20220113121143.22280-2-alim.akhtar@samsung.com>
Message-ID: <1642116835.548930.374228.nullmailer@robh.at.kernel.org>

On Thu, 13 Jan 2022 17:41:21 +0530, Alim Akhtar wrote:
> Add dt-schema documentation for Tesla FSD SoC clock controller.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../bindings/clock/tesla,fsd-clock.yaml       | 212 ++++++++++++++++++
>  1 file changed, 212 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/clock/tesla,fsd-clock.example.dts:19:18: fatal error: dt-bindings/clock/fsd-clk.h: No such file or directory
   19 |         #include <dt-bindings/clock/fsd-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:373: Documentation/devicetree/bindings/clock/tesla,fsd-clock.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1413: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1579595

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From fllinden at amazon.com  Thu Jan 13 16:10:46 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Fri, 14 Jan 2022 00:10:46 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <YeBiV8fuCCLWyHYb@kernel.org>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com> <Yd1cnquQFZoNE7FP@kernel.org>
 <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
 <YeBiV8fuCCLWyHYb@kernel.org>
Message-ID: <20220114001046.GA10609@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>

On Thu, Jan 13, 2022 at 07:33:11PM +0200, Mike Rapoport wrote:
> On Tue, Jan 11, 2022 at 08:44:41PM +0000, Frank van der Linden wrote:
> > On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote:
> > > > --- a/include/linux/memblock.h
> > > > +++ b/include/linux/memblock.h
> > > > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
> > > >  phys_addr_t memblock_start_of_DRAM(void);
> > > >  phys_addr_t memblock_end_of_DRAM(void);
> > > >  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > > > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> > > > +void memblock_enforce_usable_range(void);
> > > >  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
> > > >  void memblock_mem_limit_remove_map(phys_addr_t limit);
> > >
> > > We already have 3 very similar interfaces that deal with memory capping.
> > > Now you suggest to add fourth that will "generically" solve a single use
> > > case of DT, EFI and kdump interaction on arm64.
> > >
> > > Looks like a workaround for a fundamental issue of incompatibility between
> > > DT and EFI wrt memory registration.
> >
> > Yep, I figured this would be the main argument against this - arm64
> > already added several other more-or-less special cased interfaces over
> > time.
> >
> > I'm more than happy to solve this in a different way.
> >
> > What would you suggest:
> >
> > 1) Try to merge the similar interfaces in to one.
> > 2) Just deal with it at a lower (arm64) level?
> > 3) Some other way?
> 
> We've discussed this with Ard on IRC, and our conclusion was that on arm64
> kdump kernel should have memblock.memory exactly the same as the normal
> kernel. Then, the memory outside usable-memory-range should be reserved so
> that kdump kernel won't step over it.
> 
> With that, simple (untested) patch below could be what we need:
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index bdca35284ceb..371418dffaf1 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -1275,7 +1275,8 @@ void __init early_init_dt_scan_nodes(void)
>         of_scan_flat_dt(early_init_dt_scan_memory, NULL);
> 
>         /* Handle linux,usable-memory-range property */
> -       memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
> +       memblock_reserve(0, cap_mem_addr);
> +       memblock_reserve(cap_mem_addr + cap_mem_size, PHYS_ADDR_MAX);
>  }
> 
>  bool __init early_init_dt_scan(void *params)

Thanks for discussing this further! I tried the above change, although
I wrapped it in an if (cap_mem_size != 0), so that a normal kernel
doesn't get its entire memory marked as reserved.

The crash kernel hung without producing output - I haven't chased that
down. This particular kernel was a bit older (5.15), so I'll try again
with 5.17-rc to make sure.

- Frank


From fllinden at amazon.com  Thu Jan 13 16:22:52 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Fri, 14 Jan 2022 00:22:52 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <20220114001046.GA10609@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com> <Yd1cnquQFZoNE7FP@kernel.org>
 <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
 <YeBiV8fuCCLWyHYb@kernel.org>
 <20220114001046.GA10609@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
Message-ID: <20220114002252.GA22602@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>

On Fri, Jan 14, 2022 at 12:10:46AM +0000, Frank van der Linden wrote:
> Thanks for discussing this further! I tried the above change, although
> I wrapped it in an if (cap_mem_size != 0), so that a normal kernel
> doesn't get its entire memory marked as reserved.

Just to clarify: I had to do that because the code is slightly different
on 5.15, where I tried it. It wasn't a bug in the proposed patch.

Anyway, will try 5.17-rc tomorrow, I'll let you know, thanks again.

- Frank


From rananta at google.com  Thu Jan 13 16:42:23 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Thu, 13 Jan 2022 16:42:23 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YeBfj89mIf8SezfD@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
Message-ID: <CAJHc60wRrgnvwqPWdXdvoqT0V9isXW5xH=btgdjPWQkqVW31Pw@mail.gmail.com>

On Thu, Jan 13, 2022 at 9:21 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> > On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
> > > Perhaps it would help if you explained *why* you are doing this. It
> > > sounds like you are either trying to protect against a malicious
> > > userspace, or you are trying to keep userspace from doing something
> > > stupid. In general, kvm only enforces constraints that are necessary
> > > to protect the host. If that's what you're doing, I don't understand
> > > why live migration doesn't provide an end-run around your protections.
> > It's mainly to safeguard the guests. With respect to migration, KVM
> > and the userspace are collectively playing a role here. It's up to the
> > userspace to ensure that the registers are configured the same across
> > migrations and KVM ensures that the userspace doesn't modify the
> > registers after KVM_RUN so that they don't see features turned OFF/ON
> > during execution. I'm not sure if it falls into the definition of
> > protecting the host. Do you see a value in adding this extra
> > protection from KVM?
>
> Short answer: probably not?
>
> There is precedent for disallowing userspace from doing stupid things, but that's
> either for KVM's protection (as Jim pointed out), or because KVM can't honor the
> change, e.g. x86 is currently in the process of disallowing most CPUID changes
> after KVM_RUN because KVM itself consumes the CPUID information and KVM doesn't
> support updating some of it's own internal state (because removing features like
> GB hugepage support is nonsensical and would require a large pile of complicated,
> messy code).
>
> Restricing CPUID changes does offer some "protection" to the guest, but that's
> not the goal.  E.g. KVM won't detect CPUID misconfiguration in the migration
> case, and trying to do so is a fool's errand.
>
> If restricting updates in the arm64 is necessary to ensure KVM provides sane
> behavior, then it could be justified.  But if it's purely a sanity check on
> behalf of the guest, then it's not justified.
Agreed that KVM doesn't really safeguard the guests, but just curious,
is there really a downside in adding this thin layer of safety check?
On the bright side, the guests would be safe, and it could save the
developers some time in hunting down the bugs in this path, no?

Regards,
Raghavendra


From arnd at arndb.de  Thu Jan 13 16:45:37 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 14 Jan 2022 01:45:37 +0100
Subject: [PATCH 1/2] MAINTAINERS: Update Benjamin Gaignard maintainer
 status
In-Reply-To: <20220113171921.17466-2-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
 <20220113171921.17466-2-philippe.cornu@foss.st.com>
Message-ID: <CAK8P3a0Nn3fwEMtb9f0DZhbyY+mLva5XR332XfXqX=WSmB9a8w@mail.gmail.com>

On Thu, Jan 13, 2022 at 6:19 PM Philippe Cornu
<philippe.cornu at foss.st.com> wrote:
>
>  DRM DRIVERS FOR STI
> -M:     Benjamin Gaignard <benjamin.gaignard at linaro.org>
>  L:     dri-devel at lists.freedesktop.org
>  S:     Maintained
>  T:     git git://anongit.freedesktop.org/drm/drm-misc

If there is no longer a maintainer, I suppose it should also be marked as

S: Orphaned

         Arnd


From seanjc at google.com  Thu Jan 13 17:10:03 2022
From: seanjc at google.com (Sean Christopherson)
Date: Fri, 14 Jan 2022 01:10:03 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAJHc60wRrgnvwqPWdXdvoqT0V9isXW5xH=btgdjPWQkqVW31Pw@mail.gmail.com>
References: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAJHc60wRrgnvwqPWdXdvoqT0V9isXW5xH=btgdjPWQkqVW31Pw@mail.gmail.com>
Message-ID: <YeDNa+/rF0YEVJAi@google.com>

On Thu, Jan 13, 2022, Raghavendra Rao Ananta wrote:
> On Thu, Jan 13, 2022 at 9:21 AM Sean Christopherson <seanjc at google.com> wrote:
> > If restricting updates in the arm64 is necessary to ensure KVM provides sane
> > behavior, then it could be justified.  But if it's purely a sanity check on
> > behalf of the guest, then it's not justified.
> Agreed that KVM doesn't really safeguard the guests, but just curious,
> is there really a downside in adding this thin layer of safety check?

It's more stuff that KVM has to maintain, creates an ABI that KVM must adhere to,
potentially creates inconsistencies in KVM, and prevents using KVM to intentionally
do stupid things to test scenarios that are "impossible".  And we also try to avoid
defining arbitrary CPU behavior in KVM (that may not be the case here).

> On the bright side, the guests would be safe, and it could save the
> developers some time in hunting down the bugs in this path, no?

Yes, but that can be said for lots and lots of things.  This is both a slippery
slope argument and the inconsistency argument above, e.g. if KVM actively prevents
userspace from doing X, why doesn't KVM prevent userspace from doing Y?  Having a
decently defined rule for these types of things, e.g. protect KVM/kernel and adhere
to the architecture but otherwise let userspace do whatever, avoids spending too
much time arguing over what KVM should/shouldn't allow, or wondering why on earth
KVM does XYZ, at least in theory :-)

There are certainly times where KVM could have saved userspace some pain, but
overall I do think KVM is better off staying out of the way when possible.


From sboyd at kernel.org  Thu Jan 13 17:45:29 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 17:45:29 -0800
Subject: [PATCH RESEND v2] clk: mediatek: Fix memory leaks on probe
In-Reply-To: <20220107182451.139456-1-jose.exposito89@gmail.com>
References: <20220107182451.139456-1-jose.exposito89@gmail.com>
Message-ID: <20220114014530.E127FC36AEA@smtp.kernel.org>

Please Cc the clk mailing list on clk driver patches.

Quoting Jos? Exp?sito (2022-01-07 10:24:51)
> Handle the error branches to free memory where required.
> 
> Addresses-Coverity-ID: 1491825 ("Resource leak")
> Signed-off-by: Jos? Exp?sito <jose.exposito89 at gmail.com>
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>


From hongxing.zhu at nxp.com  Thu Jan 13 18:03:03 2022
From: hongxing.zhu at nxp.com (Hongxing Zhu)
Date: Fri, 14 Jan 2022 02:03:03 +0000
Subject: [PATCH v7 0/8] Add the imx8m pcie phy driver and imx8mm pcie
 support
In-Reply-To: <8c11bbded57df020ba0897f7ad0295d60c9ee2cb.camel@toradex.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
 <8c11bbded57df020ba0897f7ad0295d60c9ee2cb.camel@toradex.com>
Message-ID: <AS8PR04MB8676CCA4C3CC431875A0657B8C549@AS8PR04MB8676.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Sent: Thursday, January 13, 2022 4:07 PM
> To: kishon at ti.com; vkoul at kernel.org; lorenzo.pieralisi at arm.com;
> l.stach at pengutronix.de; tharvey at gateworks.com; robh at kernel.org;
> galak at kernel.crashing.org; Hongxing Zhu <hongxing.zhu at nxp.com>;
> bhelgaas at google.com; shawnguo at kernel.org
> Cc: linux-phy at lists.infradead.org; linux-pci at vger.kernel.org;
> kernel at pengutronix.de; devicetree at vger.kernel.org;
> linux-kernel at vger.kernel.org; dl-linux-imx <linux-imx at nxp.com>;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [PATCH v7 0/8] Add the imx8m pcie phy driver and imx8mm
> pcie support
> 
> Hi Richard
> 
> On Thu, 2021-12-02 at 16:02 +0800, Richard Zhu wrote:
> > Refer to the discussion [1] when try to enable i.MX8MM PCIe support,
> > one standalone PCIe PHY driver should be seperated from i.MX PCIe
> > driver when enable i.MX8MM PCIe support.
> >
> > This patch-set adds the standalone PCIe PHY driver suport[1-5], and
> > i.MX8MM PCIe support[6-8] to have whole view to review this
> patch-set.
> >
> > The PCIe works on i.MX8MM EVK board based the the blkctrl power
> driver
> > [2] and this patch-set. And tested by Tim and Marcel on the different
> > reference clock modes boards.
> >
> > [1]
> >
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpa
> tc
> >
> hwork.ozlabs.org%2Fproject%2Flinux-pci%2Fpatch%2F20210510141509.
> 929120
> >
> -3-l.stach%40pengutronix.de%2F&amp;data=04%7C01%7Chongxing.zhu
> %40nxp.c
> >
> om%7C487b28aecfd14bdfe1b808d9d66bb4ce%7C686ea1d3bc2b4c6fa92
> cd99c5c3016
> >
> 35%7C0%7C0%7C637776580350900040%7CUnknown%7CTWFpbGZsb3d
> 8eyJWIjoiMC4wLj
> >
> AwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&
> amp;sdata=
> >
> 8pMSNCoRVpWBld2dSGUUw2Dpq%2FlRAqsVWLqAJ0njEgo%3D&amp;re
> served=0
> > [2]
> >
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpa
> tc
> >
> hwork.kernel.org%2Fproject%2Flinux-arm-kernel%2Fcover%2F20210910
> 202640
> > .980366-1-l.stach%40pengutronix.de%2F&amp;data=04%7C01%7Chon
> gxing.zhu%
> >
> 40nxp.com%7C487b28aecfd14bdfe1b808d9d66bb4ce%7C686ea1d3bc2b
> 4c6fa92cd99
> >
> c5c301635%7C0%7C0%7C637776580350900040%7CUnknown%7CTWFp
> bGZsb3d8eyJWIjo
> >
> iMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> 7C3000&amp
> > ;sdata=MHPLXbIyL2pnZK%2FdVkDcJBJBjlqtPIOzzwLsNEKlCqs%3D&amp
> ;reserved=0
> >
> > Main changes v6 --> v7:
> > - Add "Reviewed-by: Rob Herring <robh at kernel.org>" into #2 patches.
> > - Regarding Vinod's review comments do the following changes.
> > ? - Don't build in the PHY driver in default.
> > ? - Remove the extra blank line
> > ? - Correct the license tag.
> >
> > Main changes v5 --> v6:
> > - Add "Reviewed-by: Rob Herring <robh at kernel.org>" into #1 and #3
> patches.
> > - Merge Rob's review comments to the #2 patch.
> >
> > Main changes v4 --> v5:
> > - Set the AUX_EN always 1b'1, thus it can fix the regression
> > introduced in v4
> > ? series on Marcel's board.
> > - Use the lower-case letter in the devicetreee refer to Marcel's
> comments.
> > - Since the default value of the deemphasis parameters are zero, only
> > set
> > ? the deemphasis registers when the input paramters are none zero.
> >
> > Main changes v3 --> v4:
> > - Update the yaml to fix syntax error, add maxitems and drop
> > description of phy
> > - Correct the clock name in PHY DT node.
> > - Squash the EVK board relalted dts changes into one patch, and drop
> > the
> > ? useless dummy clock and gpio suffix in DT nodes.
> > - Add board specific de-emphasis parameters as DT properties. Thus
> > each board
> > ? can specify its actual de-emphasis values.
> > - Update the commit log of PHY driver.
> > - Remove the useless codes from PCIe driver, since they are moved to
> > PHY driver
> > - After the discussion and verification of the CLKREQ# configurations
> > with Tim,
> > ? agree to add an optional boolean property "fsl,clkreq-unsupported",
> > indicates
> > ? the CLKREQ# signal is hooked or not in HW designs.
> > - Add "Tested-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>" tag,
> > since
> > ? Marcel help to test the v3 patch-set.
> >
> > Main changes v2 --> v3:
> > - Regarding Lucas' comments.
> > ?- to have a whole view to review the patches, send out the i.MX8MM
> PCIe support too.
> > ?- move the PHY related bits manipulations of the GPR/SRC to
> standalone PHY driver.
> > ?- split the dts changes to SOC and board DT, and use the enum
> instead of raw value.
> > ?- update the license of the dt-binding header file.
> >
> > Changes v1 --> v2:
> > - Update the license of the dt-binding header file to make the license
> > ? compatible with dts files.
> > - Fix the dt_binding_check errors.
> >
> >
> Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.yaml??? |?? 6
> +++
> > Documentation/devicetree/bindings/phy/fsl,imx8-pcie-phy.yaml |? 92
> > +++++++++++++++++++++++++++++++
> >
> arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
>  |? 55
> > +++++++++++++++++++
> arch/arm64/boot/dts/freescale/imx8mm.dtsi
> 
> > |? 46 +++++++++++++++-
> drivers/pci/controller/dwc/pci-imx6.c
> > |? 83 +++++++++++++++++++++++++---
> drivers/phy/freescale/Kconfig
> 
> > |?? 8 +++
> drivers/phy/freescale/Makefile
> 
> > |?? 1 +
> drivers/phy/freescale/phy-fsl-imx8m-pcie.c?????????????????? |
> > 236
> >
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++
> >
> include/dt-bindings/phy/phy-imx8-pcie.h
>  |? 14
> > +++++
> > 9 files changed, 532 insertions(+), 9 deletions(-)
> >
> > [PATCH v7 1/8] dt-bindings: phy: phy-imx8-pcie: Add binding for the
> > [PATCH v7 2/8] dt-bindings: phy: Add imx8 pcie phy driver support
> > [PATCH v7 3/8] dt-bindings: imx6q-pcie: Add PHY phandles and name
> > [PATCH v7 4/8] arm64: dts: imx8mm: Add the pcie phy support [PATCH
> v7
> > 5/8] phy: freescale: pcie: Initialize the imx8 pcie [PATCH v7 6/8]
> > arm64: dts: imx8mm: Add the pcie support [PATCH v7 7/8] arm64: dts:
> > imx8mm-evk: Add the pcie support on imx8mm [PATCH v7 8/8] PCI:
> imx:
> > Add the imx8mm pcie support
> 
> What is the status of patches 4, 6 and 7? While the rest has been pulled
> those are still missing in today's - next.
[Richard Zhu] Thanks for your care.
I used to ping Shawn twice on Dec17/27 2021, but couldn't receive his response.
Anyway, I would continue to ping him later.

Best Regards
Richard Zhu

> 
> Cheers
> 
> Marcel


From lkp at intel.com  Thu Jan 13 18:08:09 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 14 Jan 2022 10:08:09 +0800
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220113121143.22280-15-alim.akhtar@samsung.com>
References: <20220113121143.22280-15-alim.akhtar@samsung.com>
Message-ID: <202201141032.5xT5iNdz-lkp@intel.com>

Hi Alim,

I love your patch! Yet something to improve:

[auto build test ERROR on v5.16]
[also build test ERROR on next-20220113]
[cannot apply to clk/clk-next robh/for-next pinctrl-samsung/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Alim-Akhtar/dt-bindings-clock-Document-FSD-CMU-bindings/20220113-211129
base:    df0cc57e057f18e44dac8e6c18aba47ab53202f9
config: arm64-randconfig-r014-20220113 (https://download.01.org/0day-ci/archive/20220114/202201141032.5xT5iNdz-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/7edcfae09ff2aa85ae39f2240b13ea17eac8be94
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Alim-Akhtar/dt-bindings-clock-Document-FSD-CMU-bindings/20220113-211129
        git checkout 7edcfae09ff2aa85ae39f2240b13ea17eac8be94
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/arm64/boot/dts/tesla/fsd.dtsi:11,
                    from arch/arm64/boot/dts/tesla/fsd.dts:12:
>> scripts/dtc/include-prefixes/dt-bindings/clock/fsd-clk.h:12: error: unterminated #ifndef
      12 | #ifndef _DT_BINDINGS_CLOCK_FSD_H
         | 


vim +12 scripts/dtc/include-prefixes/dt-bindings/clock/fsd-clk.h

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From sboyd at kernel.org  Thu Jan 13 18:08:23 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 18:08:23 -0800
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
Message-ID: <20220114020825.5064DC36AEA@smtp.kernel.org>

Quoting Alyssa Rosenzweig (2022-01-10 10:13:30)
> @@ -1238,6 +1265,10 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
>         if (r)
>                 return r;
>  
> +       r = clk_mt8192_infra_disable_mfg2acp(pdev);
> +       if (r)
> +               return r;

If this fails it leaves a bunch of allocations around that never get
freed. It's a problem before this patch so it's mostly just making me
grumpy that proper cleanup isn't already here. Can this be the first
thing done in probe instead?


From sboyd at kernel.org  Thu Jan 13 18:11:29 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 18:11:29 -0800
Subject: [PATCH 3/3] clk: mediatek: support COMMON_CLK_MT8192 module build
In-Reply-To: <20220110171000.24316-4-miles.chen@mediatek.com>
References: <20220110171000.24316-1-miles.chen@mediatek.com>
 <20220110171000.24316-4-miles.chen@mediatek.com>
Message-ID: <20220114021131.1F7C9C36AEA@smtp.kernel.org>

Quoting Miles Chen (2022-01-10 09:09:59)
> To support COMMON_CLK_MT8192* module build,
> add MODULE_LICENSE and include module.h.
> 
> Cc: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Cc: Chen-Yu Tsai <wenst at chromium.org>
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>

Have you tried removing the modules? And then reloading them? I also see
that mtk_clk_simple_probe() doesn't actually unregister anything, it
just frees some allocations. Please fix this before making these
modules.


From sboyd at kernel.org  Thu Jan 13 18:12:05 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 13 Jan 2022 18:12:05 -0800
Subject: [PATCH 1/3] clk: mediatek: export mtk_clk_simple_probe
In-Reply-To: <20220110171000.24316-2-miles.chen@mediatek.com>
References: <20220110171000.24316-1-miles.chen@mediatek.com>
 <20220110171000.24316-2-miles.chen@mediatek.com>
Message-ID: <20220114021206.43FB7C36AEA@smtp.kernel.org>

Quoting Miles Chen (2022-01-10 09:09:57)
> Export mtk_clk_simple_probe() to support mt8192 module build.
> 
> Cc: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Cc: Chen-Yu Tsai <wenst at chromium.org>
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>
> ---

Please send a cover letter for multi-patch series.


From ilkka at os.amperecomputing.com  Thu Jan 13 18:17:13 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Thu, 13 Jan 2022 18:17:13 -0800 (PST)
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <alpine.DEB.2.22.394.2201051530290.2489@ubuntu200401>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <20220105104602.GA4752@lpieralisi>
 <alpine.DEB.2.22.394.2201051530290.2489@ubuntu200401>
Message-ID: <alpine.DEB.2.22.394.2201131801380.3166@ubuntu200401>


Hi Lorenzo,

On Wed, 5 Jan 2022, Ilkka Koskinen wrote:
>
> Hi Lorenzo,
>
> On Wed, 5 Jan 2022, Lorenzo Pieralisi wrote:
>> [+James, for SDEI bits]
>> 
>> On Thu, Dec 30, 2021 at 07:37:25PM -0800, Ilkka Koskinen wrote:
>>> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
>>> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
>>> issue diagnostic dump and reset via an SDEI event or an interrupt.
>>> This patch implements SDEI path.
>>> 
>>> [0] https://developer.arm.com/documentation/den0093/latest/
>>> 
>>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>>> ---
>>>  drivers/acpi/arm64/Kconfig  |   8 +++
>>>  drivers/acpi/arm64/Makefile |   1 +
>>>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 134 insertions(+)
>>>  create mode 100644 drivers/acpi/arm64/agdi.c

<snip>

>>> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
>>> new file mode 100644
>>> index 000000000000..6525ccbae5c1
>>> --- /dev/null
>>> +++ b/drivers/acpi/arm64/agdi.c

<snip>

>>>
>>> +static int __init agdi_init(void)
>>> +{
>>> +	int ret;
>>> +	acpi_status status;
>>> +	struct acpi_table_agdi *agdi_table;
>>> +	struct agdi_data pdata;
>>> +	struct platform_device *pdev;
>>> +
>>> +	if (acpi_disabled)
>>> +		return 0;
>> 
>> Why don't we call agdi_init() from acpi_init() as we do for IORT/VIOT ?
>> 
>> I don't think it is necessary to add a device_initcall(), with related
>> ordering dependencies.
>
> That's a good point. I change it.

Actually, I looked at this more carefully. acpi_init() is called in 
subsys_initcall() while sdei_init() is called in subsys_initcall_sync(). 
That is, if I call this function in acpi_init(), SDEI driver won't be 
ready and this driver fails to register the event.

Cheers, Ilkka


From robh+dt at kernel.org  Thu Jan 13 18:45:42 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Thu, 13 Jan 2022 20:45:42 -0600
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220113121143.22280-15-alim.akhtar@samsung.com>
References: <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220113121143.22280-15-alim.akhtar@samsung.com>
Message-ID: <CAL_JsqKDbzy8y61Oj8Ey++atoMn1HYPyDZRc_cJQCe_tfkDGxQ@mail.gmail.com>

On Thu, Jan 13, 2022 at 6:24 AM Alim Akhtar <alim.akhtar at samsung.com> wrote:
>
> Add initial device tree support for "Full Self-Driving" (FSD) SoC
> This SoC contain three clusters of four cortex-a72 CPUs and various
> peripheral IPs.

Please make sure you run this thru 'make dtbs_check'. Fix schema
warnings as much as possible and all dtc warnings. If shared with
Samsung, there's probably a bit still missing. I see several warnings
so I won't bother manually reporting them here.

> Cc: linux-fsd at tesla.com
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  MAINTAINERS                        |   8 +
>  arch/arm64/Kconfig.platforms       |   6 +
>  arch/arm64/boot/dts/Makefile       |   1 +
>  arch/arm64/boot/dts/tesla/Makefile |   3 +
>  arch/arm64/boot/dts/tesla/fsd.dts  | 140 ++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi | 715 +++++++++++++++++++++++++++++
>  6 files changed, 873 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dts
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fb18ce7168aa..02d56909c5e2 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2726,6 +2726,14 @@ S:       Maintained
>  F:     Documentation/devicetree/bindings/media/tegra-cec.txt
>  F:     drivers/media/cec/platform/tegra/
>
> +ARM/TESLA FSD SoC SUPPORT
> +M:     Alim Akhtar <alim.akhtar at samsung.com>
> +M:     linux-fsd at tesla.com
> +L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> +L:     linux-samsung-soc at vger.kernel.org
> +S:     Maintained
> +F:     arch/arm64/boot/dts/tesla*
> +
>  ARM/TETON BGA MACHINE SUPPORT
>  M:     "Mark F. Brown" <mark.brown314 at gmail.com>
>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
> diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
> index 54e3910e8b9b..bb8a047c2359 100644
> --- a/arch/arm64/Kconfig.platforms
> +++ b/arch/arm64/Kconfig.platforms
> @@ -267,6 +267,12 @@ config ARCH_TEGRA
>         help
>           This enables support for the NVIDIA Tegra SoC family.
>
> +config ARCH_TESLA_FSD
> +       bool "ARMv8 based Tesla platform"
> +       select ARCH_EXYNOS
> +       help
> +         Support for ARMv8 based Tesla platforms.
> +
>  config ARCH_SPRD
>         bool "Spreadtrum SoC platform"
>         help
> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
> index 639e01a4d855..1ba04e31a438 100644
> --- a/arch/arm64/boot/dts/Makefile
> +++ b/arch/arm64/boot/dts/Makefile
> @@ -27,6 +27,7 @@ subdir-y += rockchip
>  subdir-y += socionext
>  subdir-y += sprd
>  subdir-y += synaptics
> +subdir-y += tesla
>  subdir-y += ti
>  subdir-y += toshiba
>  subdir-y += xilinx
> diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
> new file mode 100644
> index 000000000000..a9818cda6b08
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +dtb-$(CONFIG_ARCH_TESLA_FSD) += \
> +       fsd.dtb
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dts b/arch/arm64/boot/dts/tesla/fsd.dts
> new file mode 100644
> index 000000000000..e9bbd3284de9
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd.dts
> @@ -0,0 +1,140 @@
> +// SPDX-License-Identifier: GPL-2.0

Dual license dts files please.

> +/*
> + * Tesla FSD board device tree source
> + *
> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
> + *             https://www.samsung.com
> + * Copyright (c) 2017-2021 Tesla, Inc.
> + *             https://www.tesla.com
> + */
> +
> +/dts-v1/;
> +#include "fsd.dtsi"
> +
> +/ {
> +       model = "Tesla Full Self-Driving (FSD) SoC";
> +       compatible = "tesla,fsd";
> +
> +       aliases {
> +               serial0 = &serial_0;
> +               serial1 = &serial_1;
> +       };
> +
> +       chosen {
> +               stdout-path = &serial_0;

> +               linux,initrd-start = <0xE0000000>;
> +               linux,initrd-end = <0xE4F00000>;

Bootloaders set these.

> +               bootargs = "console=ttySAC0,115200n8

Not needed with stdout-path.

> +                       earlycon=exynos4210,0x14180000 root=/dev/ram0

earlycon is a debug option.

> +                       init=/linuxrc";

init and rootfs are user settings.

> +       };
> +
> +       memory at 80000000 {
> +               device_type = "memory";
> +               reg = <0x0 0x80000000 0x2 0x00000000>;
> +       };
> +};
> +
> +&fin_pll {
> +       clock-frequency = <24000000>;
> +};
> +
> +&serial_0 {
> +       status = "okay";
> +};
> +
> +&serial_1 {
> +       status = "okay";
> +};
> +
> +&clock_cmu {
> +       status = "okay";
> +};
> +
> +&clock_imem {
> +       status = "okay";
> +};
> +
> +&clock_peric {
> +       status = "okay";
> +};
> +
> +&smmu_isp {
> +       status = "okay";
> +};
> +
> +&clock_fsys0 {
> +       status = "okay";
> +};
> +
> +&clock_fsys1 {
> +       status = "okay";
> +};
> +
> +&smmu_peric {
> +       status = "okay";
> +};
> +
> +&smmu_imem {
> +       status = "okay";
> +};
> +
> +&smmu_fsys0 {
> +       status = "okay";
> +};
> +
> +&hsi2c_0 {
> +       status = "okay";
> +};
> +
> +&hsi2c_1 {
> +       status = "okay";
> +};
> +
> +&hsi2c_2 {
> +       status = "okay";
> +};
> +
> +&hsi2c_3 {
> +       status = "okay";
> +};
> +
> +&hsi2c_4 {
> +       status = "okay";
> +};
> +
> +&hsi2c_5 {
> +       status = "okay";
> +};
> +
> +&hsi2c_6 {
> +       status = "okay";
> +};
> +
> +&hsi2c_7 {
> +       status = "okay";
> +};
> +
> +&pwm_0 {
> +       status = "okay";
> +};
> +
> +&pwm_1 {
> +       status = "okay";
> +};
> +
> +&mdma0 {
> +       status = "okay";
> +};
> +
> +&mdma1 {
> +       status = "okay";
> +};
> +
> +&pdma0 {
> +       status = "okay";
> +};
> +
> +&pdma1 {
> +       status = "okay";
> +};
> diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
> new file mode 100644
> index 000000000000..47cd9f20566e
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
> @@ -0,0 +1,715 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla Full Self-Driving SoC device tree source
> + *
> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> + *             https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *             https://www.tesla.com
> + */
> +
> +#include <dt-bindings/clock/fsd-clk.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
> +       compatible = "tesla,fsd";
> +       interrupt-parent = <&gic>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       aliases {
> +               watchdog0 = &watchdog_0;
> +               watchdog1 = &watchdog_1;
> +               watchdog2 = &watchdog_2;
> +               hsi2c0 = &hsi2c_0;
> +               hsi2c1 = &hsi2c_1;
> +               hsi2c2 = &hsi2c_2;
> +               hsi2c3 = &hsi2c_3;
> +               hsi2c4 = &hsi2c_4;
> +               hsi2c5 = &hsi2c_5;
> +               hsi2c6 = &hsi2c_6;
> +               hsi2c7 = &hsi2c_7;

Drop all these non-standard aliases.

> +       };
> +
> +       cpus {
> +               #address-cells = <2>;
> +               #size-cells = <0>;
> +
> +               cpu-map {
> +                       cluster0 {
> +                               core0 {
> +                                       cpu = <&cpucl0_0>;
> +                               };
> +                               core1 {
> +                                       cpu = <&cpucl0_1>;
> +                               };
> +                               core2 {
> +                                       cpu = <&cpucl0_2>;
> +                               };
> +                               core3 {
> +                                       cpu = <&cpucl0_3>;
> +                               };
> +                       };
> +
> +                       cluster1 {
> +                               core0 {
> +                                       cpu = <&cpucl1_0>;
> +                               };
> +                               core1 {
> +                                       cpu = <&cpucl1_1>;
> +                               };
> +                               core2 {
> +                                       cpu = <&cpucl1_2>;
> +                               };
> +                               core3 {
> +                                       cpu = <&cpucl1_3>;
> +                               };
> +                       };
> +
> +                       cluster2 {
> +                               core0 {
> +                                       cpu = <&cpucl2_0>;
> +                               };
> +                               core1 {
> +                                       cpu = <&cpucl2_1>;
> +                               };
> +                               core2 {
> +                                       cpu = <&cpucl2_2>;
> +                               };
> +                               core3 {
> +                                       cpu = <&cpucl2_3>;
> +                               };
> +                       };
> +               };
> +
> +               /* Cluster 0 */
> +               cpucl0_0: cpu at 0 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x000>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl0_1: cpu at 1 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x001>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl0_2: cpu at 2 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x002>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl0_3: cpu at 3 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x003>;
> +                               enable-method = "psci";
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               /* Cluster 1 */
> +               cpucl1_0: cpu at 100 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x100>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl1_1: cpu at 101 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x101>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl1_2: cpu at 102 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x102>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl1_3: cpu at 103 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x103>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               /* Cluster 2 */
> +               cpucl2_0: cpu at 200 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x200>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl2_1: cpu at 201 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x201>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl2_2: cpu at 202 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x202>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               cpucl2_3: cpu at 203 {
> +                               device_type = "cpu";
> +                               compatible = "arm,cortex-a72";
> +                               reg = <0x0 0x203>;
> +                               enable-method = "psci";
> +                               clock-frequency = <2400000000>;
> +                               cpu-idle-states = <&CPU_SLEEP>;
> +                               next-level-cache = <&L2_0>;
> +               };
> +
> +               idle-states {
> +                       entry-method = "arm,psci";
> +
> +                       CPU_SLEEP: cpu-sleep {
> +                               idle-state-name = "c2";
> +                               compatible = "arm,idle-state";
> +                               local-timer-stop;
> +                               arm,psci-suspend-param = <0x0010000>;
> +                               entry-latency-us = <30>;
> +                               exit-latency-us = <75>;
> +                               min-residency-us = <300>;
> +                               status = "okay";
> +                       };
> +               };
> +
> +               L2_0: l2-cache0 {
> +                       compatible = "cache";
> +               };
> +       };
> +
> +       arm-pmu {
> +               compatible = "arm,armv8-pmuv3";
> +               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
> +                            <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
> +               interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
> +                                    <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
> +                                    <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
> +                                    <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
> +       };
> +
> +       psci {
> +               compatible = "arm,psci";
> +               method = "smc";

> +               cpu_on = <0xC4000003>;
> +               cpu_suspend = <0xC4000001>;
> +               cpu_off = <0x84000002>;

These codes are standardized since forever. Fix your firmware.

> +       };
> +
> +       timer {
> +               compatible = "arm,armv8-timer";
> +               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> +                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> +                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> +                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> +       };
> +
> +       fin_pll: clock {
> +               compatible = "fixed-clock";
> +               clock-output-names = "fin_pll";
> +               #clock-cells = <0>;
> +       };
> +
> +       soc: soc {

soc at 0

You should see a warning for this.

> +               compatible = "simple-bus";
> +               #address-cells = <2>;
> +               #size-cells = <2>;
> +               ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
> +               dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
> +
> +               gic: interrupt-controller at 10400000 {
> +                       compatible = "arm,gic-v3";
> +                       #interrupt-cells = <3>;
> +                       interrupt-controller;
> +                       reg =   <0x0 0x10400000 0x0 0x10000>, /* GICD */
> +                               <0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
> +               };
> +
> +               smmu_isp: iommu at 12100000 {
> +                       compatible = "arm,mmu-500";
> +                       reg = <0x0 0x12100000 0x0 0x10000>;
> +                       #iommu-cells = <2>;
> +                       #global-interrupts = <11>;
> +                       interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +                                    <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +                                    <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +                                    <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +                                    /* Performance counter interrupts */
> +                                    <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
> +                                    <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
> +                                    <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
> +                                    <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
> +                                    <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
> +                                    <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
> +                                    <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
> +                                    /* Per context non-secure context interrupts, 0-7 interrupts */
> +                                    <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +                                    <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
> +                                    <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
> +                                    <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
> +                                    <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
> +                                    <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
> +                                    <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
> +                                    <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
> +                       status = "disabled";

IOMMU isn't really board specific, should it really be disabled?

> +               };
> +
> +               smmu_imem: iommu at 10200000 {
> +                       compatible = "arm,mmu-500";
> +                       reg = <0x0 0x10200000 0x0 0x10000>;
> +                       #iommu-cells = <2>;
> +                       #global-interrupts = <7>;
> +                       interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +                                    <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +                                    <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +                                    <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +                                    /* Performance counter interrupts */
> +                                    <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
> +                                    <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
> +                                    <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
> +                                    /* Per context non-secure context interrupts, 0-3 interrupts */
> +                                    <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +                                    <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
> +                                    <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
> +                                    <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
> +                       status = "disabled";
> +               };
> +
> +               smmu_peric: iommu at 14900000 {
> +                       compatible = "arm,mmu-500";
> +                       reg = <0x0 0x14900000 0x0 0x10000>;
> +                       #iommu-cells = <2>;
> +                       #global-interrupts = <5>;
> +                       interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +                                    <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +                                    <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +                                    <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +                                    /* Performance counter interrupts */
> +                                    <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
> +                                    /* Per context non-secure context interrupts, 0-1 interrupts */
> +                                    <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +                                    <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
> +                       status = "disabled";
> +               };
> +
> +               smmu_fsys0: iommu at 15450000 {
> +                       compatible = "arm,mmu-500";
> +                       reg = <0x0 0x15450000 0x0 0x10000>;
> +                       #iommu-cells = <2>;
> +                       #global-interrupts = <5>;
> +                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
> +                                    <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
> +                                    <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
> +                                    <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
> +                                    /* Performance counter interrupts */
> +                                    <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
> +                                    /* Per context non-secure context interrupts, 0-1 interrupts */
> +                                    <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
> +                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
> +                       status = "disabled";
> +               };
> +
> +               clock_cmu: clock-controller at 11C10000 {

Lowercase hex for unit-addresses.

Also, arrange nodes in address order.

> +                       compatible = "tesla,fsd-clock-cmu";
> +                       reg = <0x0 0x11C10000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "fin_pll";
> +                       status = "disabled";
> +               };
> +
> +               clock_imem: clock-controller at 10010000 {
> +                       compatible = "tesla,fsd-clock-imem";
> +                       reg = <0x0 0x10010000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>,
> +                               <&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
> +                               <&clock_cmu DOUT_CMU_IMEM_ACLK>,
> +                               <&clock_cmu DOUT_CMU_IMEM_DMACLK>;
> +                       clock-names = "fin_pll",
> +                               "dout_cmu_imem_tcuclk",
> +                               "dout_cmu_imem_aclk",
> +                               "dout_cmu_imem_dmaclk";
> +                       status = "disabled";
> +               };
> +
> +               clock_peric: clock-controller at 14010000 {
> +                       compatible = "tesla,fsd-clock-peric";
> +                       reg = <0x0 0x14010000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>,
> +                               <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
> +                       clock-names = "fin_pll",
> +                               "dout_cmu_pll_shared0_div4",
> +                               "dout_cmu_peric_shared1div36",
> +                               "dout_cmu_peric_shared0div3_tbuclk",
> +                               "dout_cmu_peric_shared0div20",
> +                               "dout_cmu_peric_shared1div4_dmaclk";
> +                       status = "disabled";
> +               };
> +
> +               clock_fsys0: clock-controller at 15010000 {
> +                       compatible = "tesla,fsd-clock-fsys0";
> +                       reg = <0x0 0x15010000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>,
> +                               <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
> +                               <&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
> +                               <&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
> +                       clock-names = "fin_pll",
> +                               "dout_cmu_pll_shared0_div6",
> +                               "dout_cmu_fsys0_shared1div4",
> +                               "dout_cmu_fsys0_shared0div4";
> +                       status = "disabled";
> +               };
> +
> +               clock_fsys1: clock-controller at 16810000 {
> +                       compatible = "tesla,fsd-clock-fsys1";
> +                       reg = <0x0 0x16810000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>,
> +                               <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
> +                               <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
> +                       clock-names = "fin_pll",
> +                               "dout_cmu_fsys1_shared0div8",
> +                               "dout_cmu_fsys1_shared0div4";
> +                       status = "disabled";
> +               };
> +
> +               clock_mfc: clock-controller at 12810000 {
> +                       compatible = "tesla,fsd-clock-mfc";
> +                       reg = <0x0 0x12810000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "fin_pll";
> +                       status = "disabled";
> +               };
> +
> +               clock_csi: clock-controller at 12610000 {
> +                       compatible = "tesla,fsd-clock-cam_csi";
> +                       reg = <0x0 0x12610000 0x0 0x3000>;
> +                       #clock-cells = <1>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "fin_pll";
> +                       status = "disabled";
> +               };
> +
> +               mdma0: mdma at 10100000 {
> +                       compatible = "arm,pl330", "arm,primecell";
> +                       reg = <0x0 0x10100000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
> +                       #dma-cells = <1>;
> +                       #dma-channels = <8>;
> +                       #dma-requests = <32>;
> +                       clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
> +                       clock-names = "apb_pclk";
> +                       iommus = <&smmu_imem 0x800 0x0>;
> +                       status = "disabled";
> +               };
> +
> +               mdma1: mdma at 10110000 {
> +                       compatible = "arm,pl330", "arm,primecell";
> +                       reg = <0x0 0x10110000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
> +                       #dma-cells = <1>;
> +                       #dma-channels = <8>;
> +                       #dma-requests = <32>;
> +                       clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
> +                       clock-names = "apb_pclk";
> +                       iommus = <&smmu_imem 0x801 0x0>;
> +                       status = "disabled";
> +               };
> +
> +               pdma0: pdma at 14280000 {
> +                       compatible = "arm,pl330", "arm,primecell";
> +                       reg = <0x0 0x14280000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
> +                       #dma-cells = <1>;
> +                       #dma-channels = <8>;
> +                       #dma-requests = <32>;
> +                       clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
> +                       clock-names = "apb_pclk";
> +                       iommus = <&smmu_peric 0x2 0x0>;
> +                       status = "disabled";
> +               };
> +
> +               pdma1: pdma at 14290000 {
> +                       compatible = "arm,pl330", "arm,primecell";
> +                       reg = <0x0 0x14290000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
> +                       #dma-cells = <1>;
> +                       #dma-channels = <8>;
> +                       #dma-requests = <32>;
> +                       clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
> +                       clock-names = "apb_pclk";
> +                       iommus = <&smmu_peric 0x1 0x0>;
> +                       status = "disabled";
> +               };
> +
> +               mct: mct at 10040000 {
> +                       compatible = "samsung,exynos4210-mct";
> +                       reg = <0x0 0x10040000 0x0 0x800>;
> +                       interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
> +                               <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
> +                       clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>;
> +                       clock-names = "fin_pll", "mct";
> +               };
> +
> +               serial_0: serial at 14180000 {
> +                       compatible = "samsung,exynos4210-uart";
> +                       reg = <0x0 0x14180000 0x0 0x100>;
> +                       interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
> +                       dmas = <&pdma1 0>, <&pdma1 1>;
> +                       dma-names = "tx", "rx";
> +                       clocks = <&clock_peric PERIC_PCLK_UART0>,
> +                                <&clock_peric PERIC_SCLK_UART0>;
> +                       clock-names = "uart", "clk_uart_baud0";
> +                       status = "disabled";
> +               };
> +
> +               serial_1: serial at 14190000 {
> +                       compatible = "samsung,exynos4210-uart";
> +                       reg = <0x0 0x14190000 0x0 0x100>;
> +                       interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
> +                       dmas = <&pdma1 2>, <&pdma1 3>;
> +                       dma-names = "tx", "rx";
> +                       clocks = <&clock_peric PERIC_PCLK_UART1>,
> +                                <&clock_peric PERIC_SCLK_UART1>;
> +                       clock-names = "uart", "clk_uart_baud0";
> +                       status = "disabled";
> +               };
> +
> +               pmu_system_controller: system-controller at 11400000 {
> +                       compatible = "samsung,exynos7-pmu", "syscon";
> +                       reg = <0x0 0x11400000 0x0 0x5000>;
> +               };
> +
> +               watchdog_0: watchdog at 100A0000 {
> +                       compatible = "samsung,exynos7-wdt";
> +                       reg = <0x0 0x100A0000 0x0 0x100>;
> +                       interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
> +                       samsung,syscon-phandle = <&pmu_system_controller>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "watchdog";
> +                       interrupt-mode = <1>;
> +               };
> +
> +               watchdog_1: watchdog at 100B0000 {
> +                       compatible = "samsung,exynos7-wdt";
> +                       reg = <0x0 0x100B0000 0x0 0x100>;
> +                       interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
> +                       samsung,syscon-phandle = <&pmu_system_controller>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "watchdog";
> +                       interrupt-mode = <1>;
> +               };
> +
> +               watchdog_2: watchdog at 100C0000 {
> +                       compatible = "samsung,exynos7-wdt";
> +                       reg = <0x0 0x100C0000 0x0 0x100>;
> +                       interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
> +                       samsung,syscon-phandle = <&pmu_system_controller>;
> +                       clocks = <&fin_pll>;
> +                       clock-names = "watchdog";
> +                       interrupt-mode = <1>;
> +               };
> +
> +               pwm_0: pwm at 14100000 {
> +                       compatible = "samsung,exynos4210-pwm";
> +                       reg = <0x0 0x14100000 0x0 0x100>;
> +                       samsung,pwm-outputs = <0>, <1>, <2>, <3>;
> +                       #pwm-cells = <3>;
> +                       clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
> +                       clock-names = "timers";
> +                       status = "disabled";
> +               };
> +
> +               pwm_1: pwm at 14110000 {
> +                       compatible = "samsung,exynos4210-pwm";
> +                       reg = <0x0 0x14110000 0x0 0x100>;
> +                       samsung,pwm-outputs = <0>, <1>, <2>, <3>;
> +                       #pwm-cells = <3>;
> +                       clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
> +                       clock-names = "timers";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_0: hsi2c at 14200000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14200000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c0_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_1: hsi2c at 14210000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14210000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c1_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_2: hsi2c at 14220000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14220000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c2_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_3: hsi2c at 14230000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14230000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c3_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_4: hsi2c at 14240000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14240000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c4_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_5: hsi2c at 14250000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14250000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c5_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_6: hsi2c at 14260000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14260000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c6_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +
> +               hsi2c_7: hsi2c at 14270000 {
> +                       compatible = "samsung,exynos7-hsi2c";
> +                       reg = <0x0 0x14270000 0x0 0x1000>;
> +                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +                       pinctrl-names = "default";
> +                       pinctrl-0 = <&hs_i2c7_bus>;
> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
> +                       clock-names = "hsi2c";
> +                       status = "disabled";
> +               };
> +       };
> +};
> --
> 2.17.1
>


From wells.lu at sunplus.com  Thu Jan 13 18:51:55 2022
From: wells.lu at sunplus.com (=?utf-8?B?V2VsbHMgTHUg5ZGC6Iqz6aiw?=)
Date: Fri, 14 Jan 2022 02:51:55 +0000
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
 <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
Message-ID: <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>

> > > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > > >
> > > > > Why bool and not tristate?
> > > >
> > > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > > We never build it as a module, but build-in to kernel.
> > > > So we use "bool".
> > > >
> > > > Should we set it to tristate?
> > >
> > > You still haven't answered "why", so I can't tell you.
> >
> > I am puzzled because I think I have answered "why".
> 
> Nope. :-)
> 
> > Because Pinctrl driver is necessary for all SP7021-based platforms.
> 
> "Why?" Why is it necessary (to be built-in)?

Pinctrl is necessary to be built-in because drivers of boot-device, 
like eMMC, SD card, NAND flash, and NOR flash drivers, need it.

SP7021 supports booting from eMMC, SD card, NAND flash and NOR flash 
devices. Their drivers need Pinctrl driver probes in advance.


> ...
> 
> > > > > > +       struct device_node *np =
> > > > > > + of_node_get(pdev->dev.of_node);
> > > > >
> > > > > What's the role of of_node_get()?
> > > >
> > > > I'll remove the unused codes.
> > > > I think it was used to check if OF node exists.
> > >
> > > And if it doesn't, what is the difference?
> > >
> > > You are the author of this code, please be prepared to explain every line in it.
> >
> > From kernel-doc comment, of_node_get() increments refcount of a node.
> > I think as a platform driver, we don't need to check if the node exists or not.
> > If not exist, platform driver will not be probed.
> 
> Right!
> 
> ...
> 
> > > > > Why is this in the header?
> > > >
> > > > Do you mean I need to move this "struct sppctl_gpio_chip { ... }"
> > > > declaration to c file because it is only used by the c file?
> > >
> > > Yes.
> >
> > But "struct sppctl_gpio_chip" is not only used in c file, but also
> > used in the same header file just beneath it. Refer to code below:
> 
> Thanks for the snippet. It actually shows the opposite. No, below is the user of the
> _pointer_ to the struct of that type. You may easily use the "opaque pointer" approach.
> I.o.w. my comment stays.
> 
> > struct sppctl_gpio_chip {
> >         :
> >         :
> > };
> >
> > struct sppctl_pdata {
> >         :
> >         :
> >         struct sppctl_gpio_chip *spp_gchip;
> >         :
> >         :
> > };

I see!
I'll move struct sppctl_gpio_chip {...} to c file next patch.


> --
> With Best Regards,
> Andy Shevchenko

Thanks,
Wells Lu

From liang.yang at amlogic.com  Thu Jan 13 19:06:07 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:06:07 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220113212957.768FFC36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
Message-ID: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>

Hi Stephen,

Thanks for your quick response.

On 2022/1/14 5:29, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:44)
>> Document the MMC sub clock controller driver, the potential consumer
>> of this driver is MMC or NAND. Also add four clock bindings IDs which
>> provided by this driver.
>>
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>>   2 files changed, 78 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>
>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>> new file mode 100644
>> index 000000000000..a274c3d5fc2e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>> @@ -0,0 +1,64 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
>> +
>> +maintainers:
>> +  - jianxin.pan at amlogic.com
>> +  - liang.yang at amlogic.com
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - "amlogic,axg-mmc-clkc", "syscon"
> 
> Why is it a syscon?

The register documented by reg is shared with SD/eMMC controller port C, 
and it need to be ops on NFC driver.

> 
> .


From axe.yang at mediatek.com  Thu Jan 13 19:06:36 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 14 Jan 2022 11:06:36 +0800
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <YeADWXPGPW253ssR@smile.fi.intel.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
 <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
 <83670f12a4eda1d8aecde3c0bf225642106d1267.camel@mediatek.com>
 <YeADWXPGPW253ssR@smile.fi.intel.com>
Message-ID: <52901ebe0db555f8e58dc0d59cfd703c5a0fc2de.camel@mediatek.com>

On Thu, 2022-01-13 at 12:47 +0200, Andy Shevchenko wrote:
> On Thu, Jan 13, 2022 at 03:58:52PM +0800, Axe Yang wrote:
> 
> > But for the comment for 'dev_dbg', can you explain more about that?
> 
> Sure.
> 
> > On Tue, 2022-01-11 at 13:46 +0200, Andy Shevchenko wrote:
> > > On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:
> 
> ..
> 
> > > > +		host->pins_eint = pinctrl_lookup_state(host-
> > > > >pinctrl,
> > > > "state_eint");
> > > > +		if (IS_ERR(host->pins_eint)) {
> > > > +			dev_dbg(&pdev->dev, "Cannot find
> > > > pinctrl
> > > > eint!\n");
> > > 
> > > In debug mode of pin control this will bring a duplicate message.
> > 
> > Can you explain more about this comment?
> > I don't understand what the 'duplicate message' refers for.
> 
> Have you chance to read the implementation of pinctrl_lookup_state()?

I have read pinctrl_lookup_state(), and if the 'duplicate message' you
were talking about is 'using pinctrl dummy state...':

https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/core.c#L1214
No, this message will not appear in debug mode if pins_eint not found
because pinctrl_dummy_state is always FALSE. MTK Soc do not need dummy
state support.

--
Best Regard,
Axe Yang

From liang.yang at amlogic.com  Thu Jan 13 19:07:17 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:07:17 +0800
Subject: [PATCH v9 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220113212801.E88BFC36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-2-liang.yang@amlogic.com>
 <20220113212801.E88BFC36AE3@smtp.kernel.org>
Message-ID: <98619eef-8b51-c138-e98d-39fdbe4c9ebb@amlogic.com>

Hi Stephen,

On 2022/1/14 5:28, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:42)
>> diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
>> index 76d31c0a3342..79c9efd28115 100644
>> --- a/drivers/clk/meson/sclk-div.c
>> +++ b/drivers/clk/meson/sclk-div.c
>> @@ -28,22 +29,39 @@ meson_sclk_div_data(struct clk_regmap *clk)
>>          return (struct meson_sclk_div_data *)clk->data;
>>   }
>>   
>> -static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
>> +static inline int sclk_get_reg(int val, unsigned char flag)
>>   {
>> -       return (1 << sclk->div.width) - 1;
>> +       if ((flag & MESON_SCLK_ONE_BASED) || !val)
>> +               return val;
>> +       else
>> +               return val - 1;
> 
> Please drop the else
ok
> 
>> +}
>> +
>> +static inline int sclk_get_divider(int reg, unsigned char flag)
>> +{
>> +       if (flag & MESON_SCLK_ONE_BASED)
>> +               return reg;
>> +       else
> 
> Please drop the else
ok
> 
>> +               return reg + 1;
>>   }
>>   
>>   static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
>>   {
>> -       return sclk_div_maxval(sclk) + 1;
> 
> .


From liang.yang at amlogic.com  Thu Jan 13 19:08:05 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 11:08:05 +0800
Subject: [PATCH v9 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220113212928.28C10C36AE3@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-3-liang.yang@amlogic.com>
 <20220113212928.28C10C36AE3@smtp.kernel.org>
Message-ID: <34b86361-a823-4de0-0426-0e0fbc79e550@amlogic.com>



On 2022/1/14 5:29, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:43)
>> diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
>> index b3ef5f67820f..c450f38d3801 100644
>> --- a/drivers/clk/meson/Makefile
>> +++ b/drivers/clk/meson/Makefile
>> @@ -11,6 +11,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
>>   obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
>> +obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
> 
> Sort by Kconfig symbol?
ok, it will fix it.
> 
>>   
>>   # Amlogic Clock controllers
>>
> 
> .


From jkchen at linux.alibaba.com  Thu Jan 13 19:16:08 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Fri, 14 Jan 2022 11:16:08 +0800
Subject: [RESEND PATCH v2] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <CANLsYkwZGSYYBCn8jS5h+3dP9XXr2stw=_tUjvHWNHKyXfothQ@mail.gmail.com>
References: <20220113061209.14271-1-jkchen@linux.alibaba.com>
 <CANLsYkwZGSYYBCn8jS5h+3dP9XXr2stw=_tUjvHWNHKyXfothQ@mail.gmail.com>
Message-ID: <52b46a25-50f9-df82-124c-084db150b52b@linux.alibaba.com>

Hi Mathieu

? 2022/1/14 00:56, Mathieu Poirier ??:
> On Wed, 12 Jan 2022 at 23:12, Jay Chen <jkchen at linux.alibaba.com> wrote:
>> Currently, there are 130 etr and etf on our machine,
>> but the current coresight tmc driver uses misc_register
>> to register the device, which leads to the error that
>> the device number is not enough.
>>
>> coresight-tmc: probe of xxxxx failed with error -16
>>
>> This patch changes the device registration method
>> to cdev's dynamic registration method to solve the
>> problem of insufficient device numbers.
> On December 21st you posted this patch with a "RFC V3 PATCH" tag.  On
> January 5th you posted a new version with a simple "PATCH" tag which,
> minutes later, was superseded by another patch labelled "RESEND
> PATCH".  Today you're sending yet another revision labelled "RESEND
> PATCH V2"...
>
> Is it a "V2" of the "RESEND PATCH" that was a new revision of the "RFC
> V3 PATCH"?  Are you confused?  I certainly am...
>
this patch v2 is a new version?and it fix some bugs;

sorry

jay

>> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
>> ---
>>   .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
>>   drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
>>   2 files changed, 91 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> index d0276af82494..0977f1ce6338 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> @@ -12,7 +12,6 @@
>>   #include <linux/io.h>
>>   #include <linux/err.h>
>>   #include <linux/fs.h>
>> -#include <linux/miscdevice.h>
>>   #include <linux/mutex.h>
>>   #include <linux/property.h>
>>   #include <linux/uaccess.h>
>> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>>
>> +static DEFINE_IDA(tmc_ida);
>> +static dev_t tmc_major;
>> +static struct class *tmc_class;
>> +
>> +#define TMC_DEV_MAX    (MINORMASK + 1)
>> +
>>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>>   {
>>          struct coresight_device *csdev = drvdata->csdev;
>> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
>>   static int tmc_open(struct inode *inode, struct file *file)
>>   {
>>          int ret;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>
>>          ret = tmc_read_prepare(drvdata);
>>          if (ret)
>> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>   {
>>          char *bufp;
>>          ssize_t actual;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>          actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>>          if (actual <= 0)
>>                  return 0;
>> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>   static int tmc_release(struct inode *inode, struct file *file)
>>   {
>>          int ret;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>
>>          ret = tmc_read_unprepare(drvdata);
>>          if (ret)
>> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>   {
>>          int ret = 0;
>>          u32 devid;
>> +       dev_t devt;
>>          void __iomem *base;
>>          struct device *dev = &adev->dev;
>>          struct coresight_platform_data *pdata = NULL;
>> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>                  goto out;
>>          }
>>
>> -       drvdata->miscdev.name = desc.name;
>> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>> -       drvdata->miscdev.fops = &tmc_fops;
>> -       ret = misc_register(&drvdata->miscdev);
>> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
>> +       if (ret < 0)
>> +               goto err_coresight_unregister;
>> +
>> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
>> +       drvdata->cdev.cdev.owner = THIS_MODULE;
>> +       devt = MKDEV(MAJOR(tmc_major), ret);
>> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>>          if (ret)
>> -               coresight_unregister(drvdata->csdev);
>> -       else
>> +               goto err_free_tmc_ida;
>> +
>> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
>> +       if (IS_ERR(drvdata->cdev.dev)) {
>> +               ret = PTR_ERR(drvdata->cdev.dev);
>> +               goto err_delete_cdev;
>> +       } else
>>                  pm_runtime_put(&adev->dev);
>> +
>> +       return 0;
>> +
>> +err_delete_cdev:
>> +       cdev_del(&drvdata->cdev.cdev);
>> +err_free_tmc_ida:
>> +       ida_simple_remove(&tmc_ida, MINOR(devt));
>> +err_coresight_unregister:
>> +       coresight_unregister(drvdata->csdev);
>>   out:
>>          return ret;
>>   }
>> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
>>   static void tmc_remove(struct amba_device *adev)
>>   {
>>          struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>> +       struct device *dev = drvdata->cdev.dev;
>>
>> -       /*
>> -        * Since misc_open() holds a refcount on the f_ops, which is
>> -        * etb fops in this case, device is there until last file
>> -        * handler to this device is closed.
>> -        */
>> -       misc_deregister(&drvdata->miscdev);
>> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
>> +       device_destroy(tmc_class, dev->devt);
>> +       cdev_del(&drvdata->cdev.cdev);
>>          coresight_unregister(drvdata->csdev);
>>   }
>>
>> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
>>          .id_table       = tmc_ids,
>>   };
>>
>> -module_amba_driver(tmc_driver);
>> +static int __init tmc_init(void)
>> +{
>> +       int ret;
>> +
>> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
>> +       if (ret < 0) {
>> +               pr_err("tmc: failed to allocate char dev region\n");
>> +               return ret;
>> +       }
>> +
>> +       tmc_class = class_create(THIS_MODULE, "tmc");
>> +       if (IS_ERR(tmc_class)) {
>> +               pr_err("tmc: failed to create class\n");
>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +               return PTR_ERR(tmc_class);
>> +       }
>> +
>> +       ret = amba_driver_register(&tmc_driver);
>> +       if (ret) {
>> +               pr_err("tmc: error registering amba driver\n");
>> +               class_destroy(tmc_class);
>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static void __exit tmc_exit(void)
>> +{
>> +       amba_driver_unregister(&tmc_driver);
>> +       class_destroy(tmc_class);
>> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +}
>> +
>> +module_init(tmc_init);
>> +module_exit(tmc_exit);
>>
>>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
>> index 6bec20a392b3..11441c6b9c26 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc.h
>> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
>> @@ -7,9 +7,9 @@
>>   #ifndef _CORESIGHT_TMC_H
>>   #define _CORESIGHT_TMC_H
>>
>> +#include <linux/cdev.h>
>>   #include <linux/dma-mapping.h>
>>   #include <linux/idr.h>
>> -#include <linux/miscdevice.h>
>>   #include <linux/mutex.h>
>>   #include <linux/refcount.h>
>>
>> @@ -163,11 +163,16 @@ struct etr_buf {
>>          void                            *private;
>>   };
>>
>> +struct tmc_cdev {
>> +       struct cdev cdev;
>> +       struct device *dev;
>> +};
>> +
>>   /**
>>    * struct tmc_drvdata - specifics associated to an TMC component
>>    * @base:      memory mapped base address for this component.
>>    * @csdev:     component vitals needed by the framework.
>> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
>> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
>>    * @spinlock:  only one at a time pls.
>>    * @pid:       Process ID of the process being monitored by the session
>>    *             that is using this component.
>> @@ -191,7 +196,7 @@ struct etr_buf {
>>   struct tmc_drvdata {
>>          void __iomem            *base;
>>          struct coresight_device *csdev;
>> -       struct miscdevice       miscdev;
>> +       struct tmc_cdev         cdev;
>>          spinlock_t              spinlock;
>>          pid_t                   pid;
>>          bool                    reading;
>> --
>> 2.27.0
>>


From allen-kh.cheng at mediatek.com  Thu Jan 13 19:16:21 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 11:16:21 +0800
Subject: [PATCH v13 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <c876eda8-1fde-6c40-117a-12dde042780d@linux.intel.com>
References: <20220113082103.27911-1-allen-kh.cheng@mediatek.com>
 <20220113082103.27911-3-allen-kh.cheng@mediatek.com>
 <c876eda8-1fde-6c40-117a-12dde042780d@linux.intel.com>
Message-ID: <bc5f284872c44c6fa9f5eb6bb7a49db5ff6e0794.camel@mediatek.com>

On Thu, 2022-01-13 at 12:47 -0600, Pierre-Louis Bossart wrote:
> > +static int mtk_adsp_mbox_probe(struct platform_device *pdev)
> > +{
> > +	struct device *dev = &pdev->dev;
> > +	struct mtk_adsp_mbox_priv *priv;
> > +	const struct mtk_adsp_mbox_cfg *cfg;
> > +	struct mbox_controller *mbox;
> > +	int ret, irq;
> > +
> > +	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	mbox = &priv->mbox;
> > +	mbox->dev = dev;
> > +	mbox->ops = &mtk_adsp_mbox_chan_ops;
> > +	mbox->txdone_irq = false;
> > +	mbox->txdone_poll = true;
> > +	mbox->of_xlate = mtk_adsp_mbox_xlate;
> > +	mbox->num_chans = 1;
> > +	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans),
> > GFP_KERNEL);
> > +	if (!mbox->chans)
> > +		return -ENOMEM;
> > +
> > +	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(priv->va_mboxreg))
> > +		return PTR_ERR(priv->va_mboxreg);
> > +
> > +	priv->cfg = of_device_get_match_data(dev);
> 
> question: is any error handling needed here? some drivers do, others
> don't, but that function can return NULL.
> 

Hi Pierre,

Thanks for your question.

I prefer my previous version which check NULL from
of_device_get_match_data.

I will revert this part in the next version.

Thanks.

> > +
> > +	irq = platform_get_irq(pdev, 0);
> > +	if (irq < 0)
> > +		return irq;
> > +
> > +	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
> > +					mtk_adsp_mbox_isr,
> > IRQF_TRIGGER_NONE,
> > +					dev_name(dev), mbox->chans);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	platform_set_drvdata(pdev, priv);
> > +
> > +	return devm_mbox_controller_register(dev, &priv->mbox);
> > +}
> 
> 



From kai.heng.feng at canonical.com  Thu Jan 13 20:07:54 2022
From: kai.heng.feng at canonical.com (Kai-Heng Feng)
Date: Fri, 14 Jan 2022 12:07:54 +0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware on a
 Dell hardware
In-Reply-To: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
Message-ID: <20220114040755.1314349-2-kai.heng.feng@canonical.com>

BIOS on Dell Edge Gateway 3200 already makes its own phy LED setting, so
instead of setting another value, keep it untouched and restore the saved
value on system resume.

Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 16 +++++
 drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 +
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  4 ++
 drivers/net/phy/marvell.c                     | 58 ++++++++++++-------
 include/linux/marvell_phy.h                   |  1 +
 5 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 8e8778cfbbadd..f8a2879e0264a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -857,6 +857,16 @@ static const struct dmi_system_id quark_pci_dmi[] = {
 	{}
 };
 
+static const struct dmi_system_id use_preset_led[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell EMC"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Edge Gateway 3200"),
+		},
+	},
+	{}
+};
+
 static int quark_default_data(struct pci_dev *pdev,
 			      struct plat_stmmacenet_data *plat)
 {
@@ -989,6 +999,7 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
 	struct intel_priv_data *intel_priv;
 	struct plat_stmmacenet_data *plat;
 	struct stmmac_resources res;
+	struct stmmac_priv *priv;
 	int ret;
 
 	intel_priv = devm_kzalloc(&pdev->dev, sizeof(*intel_priv), GFP_KERNEL);
@@ -1075,6 +1086,11 @@ static int intel_eth_pci_probe(struct pci_dev *pdev,
 		goto err_dvr_probe;
 	}
 
+	if (dmi_check_system(use_preset_led)) {
+		priv = netdev_priv(dev_get_drvdata(&pdev->dev));
+		priv->use_preset_led = true;
+	}
+
 	return 0;
 
 err_dvr_probe:
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 40b5ed94cb54a..525701acbbdbb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -319,6 +319,8 @@ struct stmmac_priv {
 	/* XDP BPF Program */
 	unsigned long *af_xdp_zc_qps;
 	struct bpf_prog *xdp_prog;
+
+	bool use_preset_led;
 };
 
 enum stmmac_state {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 63ff2dad8c85f..155412656b8bf 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -49,6 +49,7 @@
 #include "dwmac1000.h"
 #include "dwxgmac2.h"
 #include "hwif.h"
+#include <linux/marvell_phy.h>
 
 /* As long as the interface is active, we keep the timestamping counter enabled
  * with fine resolution and binary rollover. This avoid non-monotonic behavior
@@ -1236,6 +1237,9 @@ static int stmmac_init_phy(struct net_device *dev)
 			return -ENODEV;
 		}
 
+		if (priv->use_preset_led)
+			phydev->dev_flags |= MARVELL_PHY_USE_PRESET_LED;
+
 		ret = phylink_connect_phy(priv->phylink, phydev);
 	}
 
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index 739859c0dfb18..45be432188781 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -304,6 +304,7 @@ struct marvell_priv {
 	u32 last;
 	u32 step;
 	s8 pair;
+	u16 led_def_config;
 };
 
 static int marvell_read_page(struct phy_device *phydev)
@@ -748,32 +749,49 @@ static int m88e1510_config_aneg(struct phy_device *phydev)
 
 static void marvell_config_led(struct phy_device *phydev)
 {
-	u16 def_config;
+	struct marvell_priv *priv = phydev->priv;
 	int err;
 
-	switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
-	/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
-	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
-	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
-		def_config = MII_88E1121_PHY_LED_DEF;
-		break;
-	/* Default PHY LED config:
-	 * LED[0] .. 1000Mbps Link
-	 * LED[1] .. 100Mbps Link
-	 * LED[2] .. Blink, Activity
-	 */
-	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
-		if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
-			def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
-		else
-			def_config = MII_88E1510_PHY_LED_DEF;
-		break;
-	default:
+	if (priv->led_def_config == -1)
 		return;
+
+	if (priv->led_def_config)
+		goto write;
+
+	if (phydev->dev_flags & MARVELL_PHY_USE_PRESET_LED) {
+		priv->led_def_config = phy_read_paged(phydev, MII_MARVELL_LED_PAGE,
+						      MII_PHY_LED_CTRL);
+		if (priv->led_def_config < 0) {
+			priv->led_def_config = -1;
+			return;
+		}
+	} else {
+		switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
+		/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
+		case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
+		case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
+			priv->led_def_config = MII_88E1121_PHY_LED_DEF;
+			break;
+		/* Default PHY LED config:
+		 * LED[0] .. 1000Mbps Link
+		 * LED[1] .. 100Mbps Link
+		 * LED[2] .. Blink, Activity
+		 */
+		case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
+			if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
+				priv->led_def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
+			else
+				priv->led_def_config = MII_88E1510_PHY_LED_DEF;
+			break;
+		default:
+			priv->led_def_config = -1;
+			return;
+		}
 	}
 
+write:
 	err = phy_write_paged(phydev, MII_MARVELL_LED_PAGE, MII_PHY_LED_CTRL,
-			      def_config);
+			      priv->led_def_config);
 	if (err < 0)
 		phydev_warn(phydev, "Fail to config marvell phy LED.\n");
 }
diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
index ea5995d9ad6c1..492f07620b6c0 100644
--- a/include/linux/marvell_phy.h
+++ b/include/linux/marvell_phy.h
@@ -43,5 +43,6 @@
 #define MARVELL_PHY_M1145_FLAGS_RESISTANCE	BIT(0)
 #define MARVELL_PHY_M1118_DNS323_LEDS		BIT(1)
 #define MARVELL_PHY_LED0_LINK_LED1_ACTIVE	BIT(2)
+#define MARVELL_PHY_USE_PRESET_LED		BIT(3)
 
 #endif /* _MARVELL_PHY_H */
-- 
2.33.1



From herbert at gondor.apana.org.au  Thu Jan 13 20:23:26 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 14 Jan 2022 15:23:26 +1100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
In-Reply-To: <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
References: <Yd1SIHUNdLIvKhzz@Red>
 <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
Message-ID: <YeD6vt47+pAl0SxG@gondor.apana.org.au>

On Fri, Jan 14, 2022 at 03:14:38PM +1100, Herbert Xu wrote:
> On Tue, Jan 11, 2022 at 10:47:12AM +0100, Corentin Labbe wrote:
> >
> > [   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> > [   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> > [   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> > [   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> > [   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> 
> So did sun8i_ce_cipher_run ensure that BH is disabled before
> invoking xfrm_input? If not then this explains the dead-lock.

The issue appears to be with crypto_engine.  It needs to ensure
that completion functions are called with BH disabled, not IRQ
disabled and definitely not BH enabled.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Thu Jan 13 20:14:38 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 14 Jan 2022 15:14:38 +1100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
In-Reply-To: <Yd1SIHUNdLIvKhzz@Red>
References: <Yd1SIHUNdLIvKhzz@Red>
Message-ID: <YeD4rt1OVnEMBr+A@gondor.apana.org.au>

On Tue, Jan 11, 2022 at 10:47:12AM +0100, Corentin Labbe wrote:
>
> [   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> [   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> [   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> [   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> [   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)

So did sun8i_ce_cipher_run ensure that BH is disabled before
invoking xfrm_input? If not then this explains the dead-lock.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From kuba at kernel.org  Thu Jan 13 20:35:23 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 13 Jan 2022 20:35:23 -0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <20220114040755.1314349-2-kai.heng.feng@canonical.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
Message-ID: <20220113203523.310e13d3@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Fri, 14 Jan 2022 12:07:54 +0800 Kai-Heng Feng wrote:
> BIOS on Dell Edge Gateway 3200 already makes its own phy LED setting, so
> instead of setting another value, keep it untouched and restore the saved
> value on system resume.
> 
> Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>

I defer to PHY experts for review. Coincidentally the first Marvell
flag appears dead, nobody sets it:

$ git grep MARVELL_PHY_M1145_FLAGS_RESISTANCE
drivers/net/phy/marvell.c:      if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
include/linux/marvell_phy.h:#define MARVELL_PHY_M1145_FLAGS_RESISTANCE  0x00000001
$

unless it's read from DT under different name or something.


Once you get some reviews please wait for net-next to open:

http://vger.kernel.org/~davem/net-next.html

and repost. It should happen the week of Jan 24th. When you repost
please drop the first patch, I believe Russell does not like the BIT()
macro, his opinion overrides checkpatch.

Thanks!


From mathieu.poirier at linaro.org  Thu Jan 13 20:55:57 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 13 Jan 2022 21:55:57 -0700
Subject: [RESEND PATCH v2] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <52b46a25-50f9-df82-124c-084db150b52b@linux.alibaba.com>
References: <20220113061209.14271-1-jkchen@linux.alibaba.com>
 <CANLsYkwZGSYYBCn8jS5h+3dP9XXr2stw=_tUjvHWNHKyXfothQ@mail.gmail.com>
 <52b46a25-50f9-df82-124c-084db150b52b@linux.alibaba.com>
Message-ID: <CANLsYkzcS07s4C12_Asm61bLz10pg2qwHYtkpxykd8oZ_mJ9tw@mail.gmail.com>

On Thu, 13 Jan 2022 at 20:16, Jiankang Chen <jkchen at linux.alibaba.com> wrote:
>
> Hi Mathieu
>
> ? 2022/1/14 00:56, Mathieu Poirier ??:
> > On Wed, 12 Jan 2022 at 23:12, Jay Chen <jkchen at linux.alibaba.com> wrote:
> >> Currently, there are 130 etr and etf on our machine,
> >> but the current coresight tmc driver uses misc_register
> >> to register the device, which leads to the error that
> >> the device number is not enough.
> >>
> >> coresight-tmc: probe of xxxxx failed with error -16
> >>
> >> This patch changes the device registration method
> >> to cdev's dynamic registration method to solve the
> >> problem of insufficient device numbers.
> > On December 21st you posted this patch with a "RFC V3 PATCH" tag.  On
> > January 5th you posted a new version with a simple "PATCH" tag which,
> > minutes later, was superseded by another patch labelled "RESEND
> > PATCH".  Today you're sending yet another revision labelled "RESEND
> > PATCH V2"...
> >
> > Is it a "V2" of the "RESEND PATCH" that was a new revision of the "RFC
> > V3 PATCH"?  Are you confused?  I certainly am...
> >
> this patch v2 is a new version?and it fix some bugs;
>

How can it be a V2 when a V3 has already been published?  I will not
review this patch, and even less apply it, until it is properly
labelled.

> sorry
>
> jay
>
> >> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> >> ---
> >>   .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
> >>   drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
> >>   2 files changed, 91 insertions(+), 23 deletions(-)
> >>
> >> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> >> index d0276af82494..0977f1ce6338 100644
> >> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> >> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> >> @@ -12,7 +12,6 @@
> >>   #include <linux/io.h>
> >>   #include <linux/err.h>
> >>   #include <linux/fs.h>
> >> -#include <linux/miscdevice.h>
> >>   #include <linux/mutex.h>
> >>   #include <linux/property.h>
> >>   #include <linux/uaccess.h>
> >> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
> >>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> >>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
> >>
> >> +static DEFINE_IDA(tmc_ida);
> >> +static dev_t tmc_major;
> >> +static struct class *tmc_class;
> >> +
> >> +#define TMC_DEV_MAX    (MINORMASK + 1)
> >> +
> >>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
> >>   {
> >>          struct coresight_device *csdev = drvdata->csdev;
> >> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
> >>   static int tmc_open(struct inode *inode, struct file *file)
> >>   {
> >>          int ret;
> >> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> >> -                                                  struct tmc_drvdata, miscdev);
> >> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> >> +                                            struct tmc_cdev, cdev);
> >> +       struct tmc_drvdata *drvdata = container_of(cdev,
> >> +                                                  struct tmc_drvdata, cdev);
> >>
> >>          ret = tmc_read_prepare(drvdata);
> >>          if (ret)
> >> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
> >>   {
> >>          char *bufp;
> >>          ssize_t actual;
> >> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> >> -                                                  struct tmc_drvdata, miscdev);
> >> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
> >> +                                            struct tmc_cdev, cdev);
> >> +       struct tmc_drvdata *drvdata = container_of(cdev,
> >> +                                                  struct tmc_drvdata, cdev);
> >>          actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
> >>          if (actual <= 0)
> >>                  return 0;
> >> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
> >>   static int tmc_release(struct inode *inode, struct file *file)
> >>   {
> >>          int ret;
> >> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> >> -                                                  struct tmc_drvdata, miscdev);
> >> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> >> +                                            struct tmc_cdev, cdev);
> >> +       struct tmc_drvdata *drvdata = container_of(cdev,
> >> +                                                  struct tmc_drvdata, cdev);
> >>
> >>          ret = tmc_read_unprepare(drvdata);
> >>          if (ret)
> >> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
> >>   {
> >>          int ret = 0;
> >>          u32 devid;
> >> +       dev_t devt;
> >>          void __iomem *base;
> >>          struct device *dev = &adev->dev;
> >>          struct coresight_platform_data *pdata = NULL;
> >> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
> >>                  goto out;
> >>          }
> >>
> >> -       drvdata->miscdev.name = desc.name;
> >> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> >> -       drvdata->miscdev.fops = &tmc_fops;
> >> -       ret = misc_register(&drvdata->miscdev);
> >> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> >> +       if (ret < 0)
> >> +               goto err_coresight_unregister;
> >> +
> >> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> >> +       drvdata->cdev.cdev.owner = THIS_MODULE;
> >> +       devt = MKDEV(MAJOR(tmc_major), ret);
> >> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
> >>          if (ret)
> >> -               coresight_unregister(drvdata->csdev);
> >> -       else
> >> +               goto err_free_tmc_ida;
> >> +
> >> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> >> +       if (IS_ERR(drvdata->cdev.dev)) {
> >> +               ret = PTR_ERR(drvdata->cdev.dev);
> >> +               goto err_delete_cdev;
> >> +       } else
> >>                  pm_runtime_put(&adev->dev);
> >> +
> >> +       return 0;
> >> +
> >> +err_delete_cdev:
> >> +       cdev_del(&drvdata->cdev.cdev);
> >> +err_free_tmc_ida:
> >> +       ida_simple_remove(&tmc_ida, MINOR(devt));
> >> +err_coresight_unregister:
> >> +       coresight_unregister(drvdata->csdev);
> >>   out:
> >>          return ret;
> >>   }
> >> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
> >>   static void tmc_remove(struct amba_device *adev)
> >>   {
> >>          struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> >> +       struct device *dev = drvdata->cdev.dev;
> >>
> >> -       /*
> >> -        * Since misc_open() holds a refcount on the f_ops, which is
> >> -        * etb fops in this case, device is there until last file
> >> -        * handler to this device is closed.
> >> -        */
> >> -       misc_deregister(&drvdata->miscdev);
> >> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
> >> +       device_destroy(tmc_class, dev->devt);
> >> +       cdev_del(&drvdata->cdev.cdev);
> >>          coresight_unregister(drvdata->csdev);
> >>   }
> >>
> >> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
> >>          .id_table       = tmc_ids,
> >>   };
> >>
> >> -module_amba_driver(tmc_driver);
> >> +static int __init tmc_init(void)
> >> +{
> >> +       int ret;
> >> +
> >> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> >> +       if (ret < 0) {
> >> +               pr_err("tmc: failed to allocate char dev region\n");
> >> +               return ret;
> >> +       }
> >> +
> >> +       tmc_class = class_create(THIS_MODULE, "tmc");
> >> +       if (IS_ERR(tmc_class)) {
> >> +               pr_err("tmc: failed to create class\n");
> >> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> >> +               return PTR_ERR(tmc_class);
> >> +       }
> >> +
> >> +       ret = amba_driver_register(&tmc_driver);
> >> +       if (ret) {
> >> +               pr_err("tmc: error registering amba driver\n");
> >> +               class_destroy(tmc_class);
> >> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> >> +       }
> >> +
> >> +       return ret;
> >> +}
> >> +
> >> +static void __exit tmc_exit(void)
> >> +{
> >> +       amba_driver_unregister(&tmc_driver);
> >> +       class_destroy(tmc_class);
> >> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> >> +}
> >> +
> >> +module_init(tmc_init);
> >> +module_exit(tmc_exit);
> >>
> >>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
> >>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> >> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> >> index 6bec20a392b3..11441c6b9c26 100644
> >> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> >> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> >> @@ -7,9 +7,9 @@
> >>   #ifndef _CORESIGHT_TMC_H
> >>   #define _CORESIGHT_TMC_H
> >>
> >> +#include <linux/cdev.h>
> >>   #include <linux/dma-mapping.h>
> >>   #include <linux/idr.h>
> >> -#include <linux/miscdevice.h>
> >>   #include <linux/mutex.h>
> >>   #include <linux/refcount.h>
> >>
> >> @@ -163,11 +163,16 @@ struct etr_buf {
> >>          void                            *private;
> >>   };
> >>
> >> +struct tmc_cdev {
> >> +       struct cdev cdev;
> >> +       struct device *dev;
> >> +};
> >> +
> >>   /**
> >>    * struct tmc_drvdata - specifics associated to an TMC component
> >>    * @base:      memory mapped base address for this component.
> >>    * @csdev:     component vitals needed by the framework.
> >> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
> >> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
> >>    * @spinlock:  only one at a time pls.
> >>    * @pid:       Process ID of the process being monitored by the session
> >>    *             that is using this component.
> >> @@ -191,7 +196,7 @@ struct etr_buf {
> >>   struct tmc_drvdata {
> >>          void __iomem            *base;
> >>          struct coresight_device *csdev;
> >> -       struct miscdevice       miscdev;
> >> +       struct tmc_cdev         cdev;
> >>          spinlock_t              spinlock;
> >>          pid_t                   pid;
> >>          bool                    reading;
> >> --
> >> 2.27.0
> >>


From liang.yang at amlogic.com  Thu Jan 13 21:14:46 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 14 Jan 2022 13:14:46 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220113213513.9819AC36AEA@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
Message-ID: <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>

Hi Stephen,

On 2022/1/14 5:35, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 03:57:45)
>> diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
>> index bb0f59eea366..3de6f3b24461 100644
>> --- a/drivers/clk/meson/Kconfig
>> +++ b/drivers/clk/meson/Kconfig
>> @@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
>>          select COMMON_CLK_MESON_REGMAP
>>          select RESET_CONTROLLER
>>   
>> +config COMMON_CLK_MMC_MESON
>> +       tristate "Meson MMC Sub Clock Controller Driver"
>> +       depends on ARCH_MESON || COMPILE_TEST
>> +       select MFD_SYSCON
>> +       select COMMON_CLK_AMLOGIC
>> +       select COMMON_CLK_MESON_PHASE
>> +       select COMMON_CLK_MESON_PHASE_DELAY
>> +       select COMMON_CLK_MESON_SCLK_DIV
>> +       help
>> +         Support for the MMC sub clock controller on
>> +         Amlogic Meson Platform, which includes S905 (GXBB, GXL),
>> +         A113D/X (AXG) devices . Say Y if you want this
> 
> s/devices /devices/
ok, i will fix it
> 
>> +         clock enabled.
>> +
>>   config COMMON_CLK_MESON_EE_CLKC
>>          tristate
>>          select COMMON_CLK_MESON_REGMAP
>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>> new file mode 100644
>> index 000000000000..f53977f61390
>> --- /dev/null
>> +++ b/drivers/clk/meson/mmc-clkc.c
>> @@ -0,0 +1,300 @@
>> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
>> +/*
>> + * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/module.h>
>> +#include <linux/regmap.h>
>> +#include <linux/slab.h>
>> +#include <linux/of_device.h>
>> +#include <linux/mfd/syscon.h>
>> +#include <linux/platform_device.h>
>> +#include <dt-bindings/clock/amlogic,mmc-clkc.h>
>> +
>> +#include "sclk-div.h"
>> +#include "clk-phase-delay.h"
>> +#include "clk-regmap.h"
>> +#include "clk-phase.h"
>> +
>> +/* clock ID used by internal driver */
>> +
>> +#define SD_EMMC_CLOCK          0
>> +#define CLK_DELAY_STEP_PS_GX   200
>> +#define CLK_DELAY_STEP_PS_AXG  78
>> +#define MUX_CLK_NUM_PARENTS    2
>> +#define MMC_MAX_CLKS           4
>> +
>> +struct mmc_clkc_data {
>> +       struct meson_clk_phase_delay_data tx;
>> +       struct meson_clk_phase_delay_data rx;
>> +};
>> +
>> +static struct clk_regmap_mux_data mmc_clkc_mux_data = {
>> +       .offset = SD_EMMC_CLOCK,
>> +       .mask   = 0x3,
>> +       .shift  = 6,
>> +};
>> +
>> +static const struct meson_sclk_div_data mmc_clkc_div_data = {
>> +       .div = {
>> +               .reg_off = SD_EMMC_CLOCK,
>> +               .width   = 6,
>> +       },
>> +       .flags = MESON_SCLK_ONE_BASED,
>> +};
>> +
>> +static struct meson_clk_phase_data mmc_clkc_core_phase = {
>> +       .ph = {
>> +               .reg_off = SD_EMMC_CLOCK,
>> +               .shift   = 8,
>> +               .width   = 2,
>> +       }
>> +};
>> +
>> +static const struct mmc_clkc_data mmc_clkc_gx_data = {
>> +       .tx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 10,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 16,
>> +                       .width   = 4,
>> +               },
>> +               .delay_step_ps = CLK_DELAY_STEP_PS_GX,
>> +       },
>> +       .rx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 12,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 20,
>> +                       .width   = 4,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_GX,
>> +       },
>> +};
>> +
>> +static const struct mmc_clkc_data mmc_clkc_axg_data = {
>> +       .tx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 10,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 16,
>> +                       .width   = 6,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
>> +       },
>> +       .rx = {
>> +               .phase = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 12,
>> +                       .width   = 2,
>> +               },
>> +               .delay = {
>> +                       .reg_off = SD_EMMC_CLOCK,
>> +                       .shift   = 22,
>> +                       .width   = 6,
>> +               },
>> +               .delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
>> +       },
>> +};
>> +
>> +static const struct of_device_id mmc_clkc_match_table[] = {
>> +       {
>> +               .compatible     = "amlogic,gx-mmc-clkc",
>> +               .data           = &mmc_clkc_gx_data
>> +       },
>> +       {
>> +               .compatible     = "amlogic,axg-mmc-clkc",
>> +               .data           = &mmc_clkc_axg_data
>> +       },
>> +       {}
>> +};
>> +MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
>> +
>> +static struct clk_regmap *
>> +mmc_clkc_register_clk(struct device *dev, struct regmap *map,
>> +                     struct clk_init_data *init,
>> +                     const char *suffix, void *data)
>> +{
>> +       struct clk_regmap *clk;
>> +       char *name;
>> +       int ret;
>> +
>> +       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
>> +       if (!clk)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
>> +       if (!name)
>> +               return ERR_PTR(-ENOMEM);
>> +
>> +       init->name = name;
>> +       clk->map = map;
>> +       clk->data = data;
>> +       clk->hw.init = init;
>> +       ret = devm_clk_hw_register(dev, &clk->hw);
>> +       if (ret)
>> +               clk = ERR_PTR(ret);
>> +
>> +       kfree(name);
>> +       return clk;
>> +}
>> +
>> +static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
>> +                                               struct regmap *map)
>> +{
>> +       const char *parent_names[MUX_CLK_NUM_PARENTS];
>> +       struct clk_init_data init;
>> +       struct clk_regmap *mux;
>> +       struct clk *clk;
>> +       int i;
>> +
>> +       for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
>> +               char name[8];
>> +
>> +               snprintf(name, sizeof(name), "clkin%d", i);
>> +               clk = devm_clk_get(dev, name);
>> +               if (IS_ERR(clk)) {
>> +                       if (clk != ERR_PTR(-EPROBE_DEFER))
>> +                               dev_err(dev, "Missing clock %s\n", name);
> 
> Use dev_err_probe()?
ok
> 
>> +                       return ERR_CAST(clk);
>> +               }
>> +
>> +               parent_names[i] = __clk_get_name(clk);
> 
> Why can't we use clk_parent_data?

ok, i will try clk_parent_data.

> 
>> +       }
>> +
>> +       init.ops = &clk_regmap_mux_ops;
>> +       init.flags = CLK_SET_RATE_PARENT;
>> +       init.parent_names = parent_names;
>> +       init.num_parents = MUX_CLK_NUM_PARENTS;
>> +
>> +       mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
>> +       if (IS_ERR(mux))
>> +               dev_err(dev, "Mux clock registration failed\n");
>> +
>> +       return mux;
>> +}
>> +
>> +static struct clk_regmap *
>> +mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
>> +                                 char *suffix, const struct clk_hw *hw,
>> +                                 unsigned long flags,
>> +                                 const struct clk_ops *ops, void *data)
>> +{
>> +       struct clk_init_data init;
>> +       struct clk_regmap *clk;
>> +       const char *parent_name = clk_hw_get_name(hw);
>> +
>> +       init.ops = ops;
>> +       init.flags = flags;
>> +       init.parent_names = &parent_name;
>> +       init.num_parents = 1;
>> +
>> +       clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
>> +       if (IS_ERR(clk))
>> +               dev_err(dev, "%s clock registration failed\n", suffix);
>> +
>> +       return clk;
>> +}
>> +
>> +static int mmc_clkc_probe(struct platform_device *pdev)
>> +{
>> +       struct clk_hw_onecell_data *onecell_data;
>> +       struct device *dev = &pdev->dev;
>> +       struct mmc_clkc_data *data;
>> +       struct regmap *map;
>> +       struct clk_regmap *clk, *core;
>> +       struct meson_sclk_div_data *div_data;
>> +
>> +       /*cast to drop the const in match->data*/
> 
> Space after *, also why do we need to cast away const? The user of this
> pointer passes it all the way down to mmc_clkc_register_clk() which
> could take the data as const void pointer and decide to cast away const
> there.

if use 'const' here, it will report a warning:
drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const? 
qualifier from pointer targe
t type [-Werror=discarded-qualifiers] 

   data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);

> 
>> +       data = (struct mmc_clkc_data *)of_device_get_match_data(dev);
>> +       if (!data)
>> +               return -ENODEV;
>> +
>> +       map = syscon_node_to_regmap(dev->of_node);
>> +       if (IS_ERR(map)) {
>> +               dev_err(dev, "could not find mmc clock controller\n");
>> +               return PTR_ERR(map);
>> +       }
>> +
>> +       onecell_data = devm_kzalloc(dev,
>> +                                   struct_size(onecell_data, hws,
>> +                                               MMC_MAX_CLKS),
>> +                                   GFP_KERNEL);
>> +       if (!onecell_data)
>> +               return -ENOMEM;
>> +
>> +       clk = mmc_clkc_register_mux(dev, map);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
>> +       if (!div_data)
>> +               return -ENOMEM;
>> +
>> +       memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
>> +                                               &clk->hw,
>> +                                               CLK_SET_RATE_PARENT,
>> +                                               &meson_sclk_div_ops,
>> +                                               div_data);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
>> +       core = mmc_clkc_register_clk_with_parent(dev, map, "core",
>> +                                                &clk->hw,
>> +                                                CLK_SET_RATE_PARENT,
>> +                                                &meson_clk_phase_ops,
>> +                                                &mmc_clkc_core_phase);
>> +       if (IS_ERR(core))
>> +               return PTR_ERR(core);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
>> +                                               &core->hw,  0,
>> +                                               &meson_clk_phase_delay_ops,
>> +                                               &data->rx);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
>> +       clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
>> +                                               &core->hw,  0,
>> +                                               &meson_clk_phase_delay_ops,
>> +                                               &data->tx);
>> +       if (IS_ERR(clk))
>> +               return PTR_ERR(clk);
>> +
>> +       onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
>> +       onecell_data->num = MMC_MAX_CLKS;
>> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
>> +                                          onecell_data);
>> +}
>> +
>> +static struct platform_driver mmc_clkc_driver = {
>> +       .probe          = mmc_clkc_probe,
>> +       .driver         = {
>> +               .name   = "meson-mmc-clkc",
>> +               .of_match_table = of_match_ptr(mmc_clkc_match_table),
>> +       },
>> +};
>> +
>> +module_platform_driver(mmc_clkc_driver);
>> +
>> +MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
>> +MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
>> +MODULE_LICENSE("GPL v2");
> 
> .


From aneesh.kumar at linux.ibm.com  Thu Jan 13 21:20:05 2022
From: aneesh.kumar at linux.ibm.com (Aneesh Kumar K.V)
Date: Fri, 14 Jan 2022 10:50:05 +0530
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <YeCvd4UBPy27SYGZ@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <87a6g0nczg.fsf@linux.ibm.com> <YeCvd4UBPy27SYGZ@google.com>
Message-ID: <877db2opve.fsf@linux.ibm.com>

Yu Zhao <yuzhao at google.com> writes:

> On Thu, Jan 13, 2022 at 04:01:31PM +0530, Aneesh Kumar K.V wrote:
>> Yu Zhao <yuzhao at google.com> writes:
>> 
>> > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
>> 
>> 
>> Got the below lockdep warning while using the above kill/enable switch
>> 
>> 
>> [   84.252952] ======================================================
>> [   84.253012] WARNING: possible circular locking dependency detected
>> [   84.253074] 5.16.0-rc8-16204-g1cdcf1120b31 #511 Not tainted
>> [   84.253135] ------------------------------------------------------
>> [   84.253194] bash/2862 is trying to acquire lock:
>> [   84.253243] c0000000021ff740 (cgroup_mutex){+.+.}-{3:3}, at: store_enable+0x80/0x1510
>> [   84.253340]
>>                but task is already holding lock:
>> [   84.253410] c000000002221348 (mem_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x30/0x50
>> [   84.253503]
>>                which lock already depends on the new lock.
>> 
>> [   84.255933] Chain exists of:
>>                  cgroup_mutex --> cpu_hotplug_lock --> mem_hotplug_lock
>
> Thanks. Will reverse the order between mem_hotplug_lock and
> cgroup_mutex in the next spin.

It also needs the unlocked variant of static_key_enable/disable.

[   71.204397][ T2819] bash/2819 is trying to acquire lock:                                       
[   71.204446][ T2819] c0000000020e5cd0 (cpu_hotplug_lock){++++}-{0:0}, at: static_key_disable+0x24/0x50
[   71.204542][ T2819]                                                                                                 
[   71.204542][ T2819] but task is already holding lock:                                                               
[   71.204613][ T2819] c0000000020e5cd0 (cpu_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x20/0x50
[   71.204710][ T2819]                                                                                                 
[   71.204710][ T2819] other info that might help us debug this:
[   71.204787][ T2819]  Possible unsafe locking scenario:
[   71.204787][ T2819]                    
[   71.204860][ T2819]        CPU0                                                                                                                                                                                                            
[   71.204901][ T2819]        ----
[   71.204941][ T2819]   lock(cpu_hotplug_lock);
[   71.204998][ T2819]   lock(cpu_hotplug_lock);
[   71.205053][ T2819] 
[   71.205053][ T2819]  *** DEADLOCK ***

-aneesh


From chunfeng.yun at mediatek.com  Thu Jan 13 21:32:02 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 14 Jan 2022 13:32:02 +0800
Subject: [PATCH 3/3] phy: mediatek: phy-mtk-mipi-dsi: Simplify with
 dev_err_probe()
In-Reply-To: <ba6c0163-fc5f-2a5f-560d-240e5fe2c3c4@collabora.com>
References: <20220103145324.48008-1-angelogioacchino.delregno@collabora.com>
 <20220103145324.48008-3-angelogioacchino.delregno@collabora.com>
 <4d7195c3ac9bc63a5f980548f0c880484403346d.camel@mediatek.com>
 <ba6c0163-fc5f-2a5f-560d-240e5fe2c3c4@collabora.com>
Message-ID: <6e75de8187b276f54c8673ccd708b299614bc5c3.camel@mediatek.com>

On Fri, 2022-01-07 at 10:23 +0100, AngeloGioacchino Del Regno wrote:
> Il 06/01/22 10:13, Chunfeng Yun ha scritto:
> > On Mon, 2022-01-03 at 15:53 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Use the dev_err_probe() helper to simplify error handling during
> > > probe.
> > > 
> > > Signed-off-by: AngeloGioacchino Del Regno <
> > > angelogioacchino.delregno at collabora.com>
> > > ---
> > >   drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 29 +++++++++---------
> > > ---
> > > ----
> > >   1 file changed, 10 insertions(+), 19 deletions(-)
> > > 
> > > diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > > b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > > index 6f7425b0bf5b..4b77508f5241 100644
> > > --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > > +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
> > > @@ -148,11 +148,9 @@ static int mtk_mipi_tx_probe(struct
> > > platform_device *pdev)
> > >   		return PTR_ERR(mipi_tx->regmap);
> > >   
> > >   	ref_clk = devm_clk_get(dev, NULL);
> > > -	if (IS_ERR(ref_clk)) {
> > > -		ret = PTR_ERR(ref_clk);
> > > -		dev_err(dev, "Failed to get reference clock: %d\n",
> > > ret);
> > > -		return ret;
> > > -	}
> > > +	if (IS_ERR(ref_clk))
> > > +		return dev_err_probe(dev, PTR_ERR(ref_clk),
> > > +				     "Failed to get reference
> > > clock\n");
> > >   
> > >   	ret = of_property_read_u32(dev->of_node, "drive-
> > > strength-
> > > microamp",
> > >   				   &mipi_tx->mipitx_drive);
> > > @@ -172,27 +170,20 @@ static int mtk_mipi_tx_probe(struct
> > > platform_device *pdev)
> > >   
> > >   	ret = of_property_read_string(dev->of_node, "clock-
> > > output-
> > > names",
> > >   				      &clk_init.name);
> > > -	if (ret < 0) {
> > > -		dev_err(dev, "Failed to read clock-output-names: %d\n",
> > > ret);
> > > -		return ret;
> > > -	}
> > > +	if (ret < 0)
> > > +		return dev_err_probe(dev, ret, "Failed to read clock-
> > > output-names\n");
> > 
> > Seems no need change it here. (no EPROBE_DEFER error)
> > 
> 
> Hello Chunfeng,
> 
> pasting from kernel driver-api infrastructure guidelines:
> 
> [...]Note that it is deemed acceptable to use this function for error
> prints during 
> probe even if the err is known to never be -EPROBE_DEFER. The benefit
> compared to a 
> normal dev_err() is the standardized format of the error code and the
> fact that the 
> error code is returned.
> 
> https://www.kernel.org/doc/html/latest/driver-api/infrastructure.html
> 
Got it, thanks a lot:)

> Regards,
> - Angelo
> 
> > Thanks
> > >   
> > >   	clk_init.ops = mipi_tx->driver_data->mipi_tx_clk_ops;
> > >   
> > >   	mipi_tx->pll_hw.init = &clk_init;
> > >   	mipi_tx->pll = devm_clk_register(dev, &mipi_tx-
> > > >pll_hw);
> > > -	if (IS_ERR(mipi_tx->pll)) {
> > > -		ret = PTR_ERR(mipi_tx->pll);
> > > -		dev_err(dev, "Failed to register PLL: %d\n", ret);
> > > -		return ret;
> > > -	}
> > > +	if (IS_ERR(mipi_tx->pll))
> > > +		return dev_err_probe(dev, PTR_ERR(mipi_tx->pll),
> > > "Cannot register PLL\n");
> > >   
> > >   	phy = devm_phy_create(dev, NULL, &mtk_mipi_tx_ops);
> > > -	if (IS_ERR(phy)) {
> > > -		ret = PTR_ERR(phy);
> > > -		dev_err(dev, "Failed to create MIPI D-PHY: %d\n", ret);
> > > -		return ret;
> > > -	}
> > > +	if (IS_ERR(phy))
> > > +		return dev_err_probe(dev, PTR_ERR(phy), "Failed to
> > > create MIPI D-PHY\n");
> > > +
> > >   	phy_set_drvdata(phy, mipi_tx);
> > >   
> > >   	phy_provider = devm_of_phy_provider_register(dev,
> > > of_phy_simple_xlate);
> 
> 

From biao.huang at mediatek.com  Thu Jan 13 21:38:24 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Fri, 14 Jan 2022 13:38:24 +0800
Subject: [PATCH net-next v10 6/6] net: dt-bindings: dwmac: add support
 for mt8195
In-Reply-To: <CAL_JsqLo7z-KWtwFx+Kng2aQuCpQwJaO6mHnyBzmCKCJDK5n+Q@mail.gmail.com>
References: <20211216055328.15953-1-biao.huang@mediatek.com>
 <20211216055328.15953-7-biao.huang@mediatek.com>
 <1639662782.987227.4004875.nullmailer@robh.at.kernel.org>
 <be023f9d2fb2a8f947bd0075e8732ba07cfd7b89.camel@mediatek.com>
 <CAL_JsqLo7z-KWtwFx+Kng2aQuCpQwJaO6mHnyBzmCKCJDK5n+Q@mail.gmail.com>
Message-ID: <14636842a61bb7631584315901bcc06ccbdb0f90.camel@mediatek.com>

On Tue, 2022-01-11 at 17:36 -0600, Rob Herring wrote:
> On Thu, Dec 16, 2021 at 8:06 PM Biao Huang <biao.huang at mediatek.com>
> wrote:
> > 
> > Dear Rob,
> >   Thanks for your comments~
> > 
> >   For mt8195, the eth device node will look like:
> >   eth: ethernet at 11021000 {
> >     compatible = "mediatek,mt8195-gmac", "snps,dwmac-5.10a";
> >     ...
> >     clock-names = "axi",
> >                   "apb",
> >                   "mac_cg",
> >                   "mac_main",
> >                   "ptp_ref",
> >                   "rmii_internal";
> >     clocks = <&pericfg_ao CLK_PERI_AO_ETHERNET>,
> >              <&pericfg_ao CLK_PERI_AO_ETHERNET_BUS>,
> >              <&pericfg_ao CLK_PERI_AO_ETHERNET_MAC>,
> >              <&topckgen CLK_TOP_SNPS_ETH_250M>,
> >              <&topckgen CLK_TOP_SNPS_ETH_62P4M_PTP>,
> >              <&topckgen CLK_TOP_SNPS_ETH_50M_RMII>;
> >     ...
> >   }
> > 
> > 1. "rmii_internal" is a special clock only required for
> >    RMII phy interface, dwmac-mediatek.c will enable clocks
> >    invoking clk_bulk_prepare_enable(xx, 6) for RMII,
> >    and clk_bulk_prepare_enable(xx, 5) for other phy interfaces.
> >    so, mt2712/mt8195 all put "rmii_internal" clock to the
> >    end of clock list to simplify clock handling.
> > 
> >    If I put mac_cg as described above, a if condition is required
> > for clocks description in dt-binding, just like what I do in v7
> > send:
> >   - if:
> >       properties:
> >         compatible:
> >           contains:
> >             enum:
> >               - mediatek,mt2712-gmac
> > 
> >     then:
> >       properties:
> >         clocks:
> >           minItems: 5
> >           items:
> >             - description: AXI clock
> >             - description: APB clock
> >             - description: MAC Main clock
> >             - description: PTP clock
> >             - description: RMII reference clock provided by MAC
> > 
> >         clock-names:
> >           minItems: 5
> >           items:
> >             - const: axi
> >             - const: apb
> >             - const: mac_main
> >             - const: ptp_ref
> >             - const: rmii_internal
> > 
> >   - if:
> >       properties:
> >         compatible:
> >           contains:
> >             enum:
> >               - mediatek,mt8195-gmac
> > 
> >     then:
> >       properties:
> >         clocks:
> >           minItems: 6
> >           items:
> >             - description: AXI clock
> >             - description: APB clock
> >             - description: MAC clock gate
> >             - description: MAC Main clock
> >             - description: PTP clock
> >             - description: RMII reference clock provided by MAC
> > 
> >    This introduces some duplicated description.
> > 
> > 2. If I put "mac_cg" to the end of clock list,
> >    the dt-binding file can be simple just like
> >    what we do in this v10 patch(need fix warnings reported by "make
> > DT_CHECKER_FLAGS=-m dt_binding_check").
> > 
> >    But for mt8195:
> >      the eth node in dts should be modified,
> 
> I hope you are defining the binding before you use it... That's not
> good practice and not a valid argument.
> 
> >      and eth driver clock handling will be complex;
> 
> How so?
> 
> Rob
OK, I'll add a driver patch to make clock setting more reasonable,
and modify this patch as previous comments.

Thanks for your comments~

From alim.akhtar at samsung.com  Thu Jan 13 21:41:02 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 11:11:02 +0530
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>
Message-ID: <076001d80909$52d201c0$f8760540$@samsung.com>

Hi Krzysztof,

>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:02 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com
>Subject: Re: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> This patch set adds basic support for the Tesla Full Self-Driving
>> (FSD) SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
>> as well as several IPs.
>>
>> Patches 1 to 8 provide support for the clock controller (which is
>> designed similarly to Exynos SoCs).
>>
>> The remaining changes provide pinmux support, initial device tree
>> support, and SPI, ADC, and MCT IP functionality.
>
>Does FSD have some version number? The FDS, especially in compatibles,
>looks quite generic, so what will happen if a newer SoC comes later? You
>would have:
> - tesla,fsd-pinctrl
> - tesla,fsd-xxxx-pinctrl (where xxxx could be some new version)
>
>This will be extra confusing, because fsd-pinctrl looks like the generic one,
>while it is specific...
>
AFAIK, there is no version for FSD SoC (like we see on Exynos or any other SoC)
In case something comes in future, may be just adopt as Olof suggested in the other thread like fsd2 etc..
>Best regards,
>Krzysztof



From alim.akhtar at samsung.com  Thu Jan 13 21:44:41 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 11:14:41 +0530
Subject: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <849c7772-0f7e-32ff-6ea6-c46aa6837bb4@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122354epcas5p19e5cebe9e85e9ba1758fa0b9d7d1ef75@epcas5p1.samsung.com>
 <20220113121143.22280-11-alim.akhtar@samsung.com>
 <849c7772-0f7e-32ff-6ea6-c46aa6837bb4@canonical.com>
Message-ID: <076101d80909$d5849060$808db120$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 5:57 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
>Tesla FSD SoC
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add compatible for Tesla Full Self-Driving SoC. The pinctrl hardware
>> IP is similar to what found on most of the exynos series of SoC, so
>> this new compatible is added in samsung pinctrl binding.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git
>> a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>> b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>> index b8b475967ff9..ba972998a0e4 100644
>> --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>> +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>> @@ -24,6 +24,7 @@ Required Properties:
>>    - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
>>    - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
>>    - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-
>controller.
>> +  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
>>
>
>Please rebase this on my latest Samsung pinctrl dtschema patches. You also
>need a tesla vendor prefix patch (separate).
>
Sure will rebase when sending v2, your latest patches are in Linux-next or still in your tree?

>
>Best regards,
>Krzysztof



From alim.akhtar at samsung.com  Thu Jan 13 21:48:10 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 11:18:10 +0530
Subject: [PATCH 01/23] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <c87f500e-e43e-465c-94fa-050c2b0de083@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122311epcas5p4b7c253b49dce3bd3580407fcf312e70e@epcas5p4.samsung.com>
 <20220113121143.22280-2-alim.akhtar@samsung.com>
 <c87f500e-e43e-465c-94fa-050c2b0de083@canonical.com>
Message-ID: <076201d8090a$5208eff0$f61acfd0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:11 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 01/23] dt-bindings: clock: Document FSD CMU bindings
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add dt-schema documentation for Tesla FSD SoC clock controller.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  .../bindings/clock/tesla,fsd-clock.yaml       | 212 ++++++++++++++++++
>>  1 file changed, 212 insertions(+)
>>  create mode 100644
>> Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
>>
>> diff --git
>> a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
>> b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
>> new file mode 100644
>> index 000000000000..58f341e5004d
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
>> @@ -0,0 +1,212 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
>> +---
>> +$id:
>> +https://protect2.fireeye.com/v1/url?k=7e607c7a-1f1d943d-7e61f735-74fe
>> +485fff30-a4acf0e03cbf256d&q=1&e=05b30de9-b535-49f7-9359-
>77edd951da07&
>> +u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Fclock%2Ftesla%2Cfsd-
>clock.y
>> +aml%23
>> +$schema:
>> +https://protect2.fireeye.com/v1/url?k=5c769dcb-3d0b758c-5c771684-74fe
>> +485fff30-b4007a892a5a3e44&q=1&e=05b30de9-b535-49f7-9359-
>77edd951da07&
>> +u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>> +
>> +title: Tesla FSD (Full Self-Driving) SoC clock controller
>> +
>> +maintainers:
>> +  - Alim Akhtar <alim.akhtar at samsung.com>
>> +  - linux-fsd at tesla.com
>> +
>> +description: |
>> +  FSD clock controller consist of several clock management unit
>> +  (CMU), which generates clocks for various inteernal SoC blocks.
>> +  The root clock comes from external OSC clock (24 MHz).
>> +
>> +  All available clocks are defined as preprocessor macros in
>> + 'dt-bindings/clock/fsd-clk.h' header.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - tesla,fsd-clock-cmu
>> +      - tesla,fsd-clock-imem
>> +      - tesla,fsd-clock-peric
>> +      - tesla,fsd-clock-fsys0
>> +      - tesla,fsd-clock-fsys1
>> +      - tesla,fsd-clock-mfc
>> +      - tesla,fsd-clock-cam_csi
>> +
>> +  clocks:
>> +    minItems: 1
>> +    maxItems: 6
>> +
>> +  clock-names:
>> +    minItems: 1
>> +    maxItems: 6
>> +
>> +  "#clock-cells":
>> +    const: 1
>> +
>> +  reg:
>> +    maxItems: 1
>> +
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            const: tesla,fsd-clock-cmu
>> +
>
>Nitpick: Drop the white-spaces between if-then. It's easier to spot the if-
>blocks if they are together.
>
Thanks will fix in next version

>> +    then:
>> +      properties:
>> +        clocks:
>> +          items:
>> +            - description: External reference clock (24 MHz)
>> +
>
>Drop this whitespace as well.
>
Noted

>Rest looks good to me, except the discussion about the compatible.
>
Have replied to the original question thread. 
>
>Best regards,
>Krzysztof



From ck.hu at mediatek.com  Thu Jan 13 21:47:12 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 14 Jan 2022 13:47:12 +0800
Subject: [PATCH v11 20/22] drm/mediatek: add drm ovl_adaptor sub driver
 for MT8195
In-Reply-To: <20220110084645.31191-21-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-21-nancy.lin@mediatek.com>
Message-ID: <fd111ceb9cb5afa1a5d2c0b4b978bcea46cd109f.camel@mediatek.com>

Hi, Nancy:

On Mon, 2022-01-10 at 16:46 +0800, Nancy.Lin wrote:
> Add drm ovl_adaptor sub driver. Bring up ovl_adaptor sub driver if
> the component exists in the path.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 16 ++++----
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 30 ++++++++++++---
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      | 41 +++++++++++++++--
> ----
>  4 files changed, 62 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index fe2871aca859..62529a954b62 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -877,15 +877,13 @@ int mtk_drm_crtc_create(struct drm_device
> *drm_dev,
>  		node = priv->comp_node[comp_id];
>  		comp = &priv->ddp_comp[comp_id];
>  
> -		if (!node) {

if (!node && comp_id != MTK_DISP_OVL_ADAPTOR)

> -			dev_info(dev,
> -				 "Not creating crtc %d because
> component %d is disabled or missing\n",
> -				 crtc_i, comp_id);
> -			return 0;
> -		}
> -
> -		if (!comp->dev) {
> -			dev_err(dev, "Component %pOF not
> initialized\n", node);
> +		/* Not all drm components have a DTS device node, such
> as ovl_adaptor,
> +		 * which is the drm bring up sub driver
> +		 */
> +		if (!node && !comp->dev) {
> +			dev_err(dev,
> +				"Not creating crtc %d because component
> %d is disabled, missing or not initialized\n",
> +				crtc_i, comp_id);
>  			return -ENODEV;
>  		}
>  	}
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> index 26d197da41c0..ce40bab9c56b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
> @@ -385,6 +385,18 @@ static const struct mtk_ddp_comp_funcs ddp_ufoe
> = {
>  	.start = mtk_ufoe_start,
>  };
>  
> +static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = {
> +	.clk_enable = mtk_ovl_adaptor_clk_enable,
> +	.clk_disable = mtk_ovl_adaptor_clk_disable,
> +	.config = mtk_ovl_adaptor_config,
> +	.start = mtk_ovl_adaptor_start,
> +	.stop = mtk_ovl_adaptor_stop,
> +	.layer_nr = mtk_ovl_adaptor_layer_nr,
> +	.layer_config = mtk_ovl_adaptor_layer_config,
> +	.enable_vblank = mtk_ovl_adaptor_enable_vblank,
> +	.disable_vblank = mtk_ovl_adaptor_disable_vblank,
> +};
> +
>  static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] =
> {
>  	[MTK_DISP_AAL] = "aal",
>  	[MTK_DISP_BLS] = "bls",
> @@ -398,6 +410,7 @@ static const char * const
> mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
>  	[MTK_DISP_OD] = "od",
>  	[MTK_DISP_OVL] = "ovl",
>  	[MTK_DISP_OVL_2L] = "ovl-2l",
> +	[MTK_DISP_OVL_ADAPTOR] = "ovl_adaptor",
>  	[MTK_DISP_POSTMASK] = "postmask",
>  	[MTK_DISP_PWM] = "pwm",
>  	[MTK_DISP_RDMA] = "rdma",
> @@ -443,6 +456,7 @@ static const struct mtk_ddp_comp_match
> mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
>  	[DDP_COMPONENT_OVL_2L0]		= { MTK_DISP_OVL_2L,	0,
> &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L1]		= { MTK_DISP_OVL_2L,	1,
> &ddp_ovl },
>  	[DDP_COMPONENT_OVL_2L2]		= { MTK_DISP_OVL_2L,    2,
> &ddp_ovl },
> +	[DDP_COMPONENT_OVL_ADAPTOR]	= { MTK_DISP_OVL_ADAPTOR,	
> 0, &ddp_ovl_adaptor },
>  	[DDP_COMPONENT_POSTMASK0]	= { MTK_DISP_POSTMASK,	0,
> &ddp_postmask },
>  	[DDP_COMPONENT_PWM0]		= { MTK_DISP_PWM,	0,
> NULL },
>  	[DDP_COMPONENT_PWM1]		= { MTK_DISP_PWM,	1,
> NULL },
> @@ -548,12 +562,17 @@ int mtk_ddp_comp_init(struct device_node *node,
> struct mtk_ddp_comp *comp,
>  
>  	comp->id = comp_id;
>  	comp->funcs = mtk_ddp_matches[comp_id].funcs;
> -	comp_pdev = of_find_device_by_node(node);
> -	if (!comp_pdev) {
> -		DRM_INFO("Waiting for device %s\n", node->full_name);
> -		return -EPROBE_DEFER;
> +	/* Not all drm components have a DTS device node, such as
> ovl_adaptor,
> +	 * which is the drm bring up sub driver
> +	 */
> +	if (node) {
> +		comp_pdev = of_find_device_by_node(node);
> +		if (!comp_pdev) {
> +			DRM_INFO("Waiting for device %s\n", node-
> >full_name);
> +			return -EPROBE_DEFER;
> +		}
> +		comp->dev = &comp_pdev->dev;
>  	}
> -	comp->dev = &comp_pdev->dev;
>  
>  	/* Only DMA capable components need the LARB property */
>  	if (type == MTK_DISP_OVL ||
> @@ -573,6 +592,7 @@ int mtk_ddp_comp_init(struct device_node *node,
> struct mtk_ddp_comp *comp,
>  	    type == MTK_DISP_MERGE ||
>  	    type == MTK_DISP_OVL ||
>  	    type == MTK_DISP_OVL_2L ||
> +	    type == MTK_DISP_OVL_ADAPTOR ||
>  	    type == MTK_DISP_PWM ||
>  	    type == MTK_DISP_RDMA ||
>  	    type == MTK_DPI ||
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> index 221e2e3a3c8d..5e1404dc20c4 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
> @@ -30,6 +30,7 @@ enum mtk_ddp_comp_type {
>  	MTK_DISP_OD,
>  	MTK_DISP_OVL,
>  	MTK_DISP_OVL_2L,
> +	MTK_DISP_OVL_ADAPTOR,
>  	MTK_DISP_POSTMASK,
>  	MTK_DISP_PWM,
>  	MTK_DISP_RDMA,
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index a05703843af2..36430f956b4f 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -351,9 +351,7 @@ static int mtk_drm_kms_init(struct drm_device
> *drm)
>  {
>  	struct mtk_drm_private *private = drm->dev_private;
>  	struct mtk_drm_private *priv_n;
> -	struct platform_device *pdev;
> -	struct device_node *np = NULL;
> -	struct device *dma_dev;
> +	struct device *dma_dev = NULL;
>  	int ret, i, j;
>  
>  	ret = drmm_mode_config_init(drm);
> @@ -400,8 +398,8 @@ static int mtk_drm_kms_init(struct drm_device
> *drm)
>  				if (ret)
>  					goto err_component_unbind;
>  
> -				if (!np)
> -					np = priv_n->comp_node[priv_n-
> >data->main_path[0]];
> +				if (!dma_dev)
> +					dma_dev = priv_n-
> >ddp_comp[priv_n->data->main_path[0]].dev;
>  
>  				continue;
>  			} else if (i == 1 && priv_n->data->ext_len) {
> @@ -410,8 +408,8 @@ static int mtk_drm_kms_init(struct drm_device
> *drm)
>  				if (ret)
>  					goto err_component_unbind;
>  
> -				if (!np)
> -					np = priv_n->comp_node[priv_n-
> >data->ext_path[0]];
> +				if (!dma_dev)
> +					dma_dev = priv_n-
> >ddp_comp[priv_n->data->ext_path[0]].dev;
>  
>  				continue;
>  			} else if (i == 2 && priv_n->data->third_len) {
> @@ -420,22 +418,20 @@ static int mtk_drm_kms_init(struct drm_device
> *drm)
>  				if (ret)
>  					goto err_component_unbind;
>  
> -				if (!np)
> -					np = priv_n->comp_node[priv_n-
> >data->third_path[0]];
> +				if (!dma_dev)
> +					dma_dev = priv_n-
> >ddp_comp[priv_n->data->third_path[0]].dev;
>  
>  				continue;
>  			}
>  		}
>  	}
>  
> -	pdev = of_find_device_by_node(np);
> -	if (!pdev) {
> +	if (!dma_dev) {

I don't know how ovl_adaptor could provide the dma function. As I know,
dma device has a device node, and there is iommu property in that node.

>  		ret = -ENODEV;
>  		dev_err(drm->dev, "Need at least one OVL device\n");
>  		goto err_component_unbind;
>  	}
>  
> -	dma_dev = &pdev->dev;
>  	for (i = 0; i < private->data->mmsys_dev_num; i++)
>  		private->all_drm_private[i]->dma_dev = dma_dev;
>  
> @@ -514,6 +510,11 @@ static int compare_of(struct device *dev, void
> *data)
>  	return dev->of_node == data;
>  }
>  
> +static int compare_dev(struct device *dev, void *data)
> +{
> +	return dev == (struct device *)data;
> +}
> +
>  static int mtk_drm_bind(struct device *dev)
>  {
>  	struct mtk_drm_private *private = dev_get_drvdata(dev);
> @@ -702,6 +703,7 @@ static int mtk_drm_probe(struct platform_device
> *pdev)
>  	struct mtk_drm_private *private;
>  	struct device_node *node;
>  	struct component_match *match = NULL;
> +	struct platform_device *ovl_adaptor;
>  	int ret;
>  	int i;
>  
> @@ -727,6 +729,19 @@ static int mtk_drm_probe(struct platform_device
> *pdev)
>  		return -ENODEV;
>  	}
>  
> +	/* Bringup ovl_adaptor */
> +	if (mtk_drm_find_mmsys_comp(private,
> DDP_COMPONENT_OVL_ADAPTOR)) {
> +		ovl_adaptor = platform_device_register_data(dev,
> "mediatek-disp-ovl-adaptor",
> +							    PLATFORM_DE
> VID_AUTO,
> +							    (void
> *)private->mmsys_dev,
> +							    sizeof(*pri
> vate->mmsys_dev));
> +		private->ddp_comp[DDP_COMPONENT_OVL_ADAPTOR].dev =
> &ovl_adaptor->dev;
> +		private->comp_node[DDP_COMPONENT_OVL_ADAPTOR] =
> ovl_adaptor->dev.of_node;

private->comp_node[DDP_COMPONENT_OVL_ADAPTOR] = NULL;

Regards,
CK

> +		mtk_ddp_comp_init(NULL, &private-
> >ddp_comp[DDP_COMPONENT_OVL_ADAPTOR],
> +				  DDP_COMPONENT_OVL_ADAPTOR);
> +		component_match_add(dev, &match, compare_dev,
> &ovl_adaptor->dev);
> +	}
> +
>  	/* Iterate over sibling DISP function blocks */
>  	for_each_child_of_node(phandle->parent, node) {
>  		const struct of_device_id *of_id;
> @@ -780,6 +795,7 @@ static int mtk_drm_probe(struct platform_device
> *pdev)
>  		    comp_type == MTK_DISP_MERGE ||
>  		    comp_type == MTK_DISP_OVL ||
>  		    comp_type == MTK_DISP_OVL_2L ||
> +		    comp_type == MTK_DISP_OVL_ADAPTOR ||
>  		    comp_type == MTK_DISP_RDMA ||
>  		    comp_type == MTK_DPI ||
>  		    comp_type == MTK_DSI) {
> @@ -882,6 +898,7 @@ static struct platform_driver * const
> mtk_drm_drivers[] = {
>  	&mtk_disp_color_driver,
>  	&mtk_disp_gamma_driver,
>  	&mtk_disp_merge_driver,
> +	&mtk_disp_ovl_adaptor_driver,
>  	&mtk_disp_ovl_driver,
>  	&mtk_disp_rdma_driver,
>  	&mtk_dpi_driver,



From chanho61.park at samsung.com  Thu Jan 13 21:57:49 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Fri, 14 Jan 2022 14:57:49 +0900
Subject: [PATCH v3 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220112100046.68068-5-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <CGME20220112100121epcas2p1ba2f59e6fa405e10e9daa80403ec17e2@epcas2p1.samsung.com>
 <20220112100046.68068-5-krzysztof.kozlowski@canonical.com>
Message-ID: <00a601d8090b$a92da220$fb88e660$@samsung.com>

> -----Original Message-----
> From: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Sent: Wednesday, January 12, 2022 7:01 PM
> To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Andi Shyti
> <andi at etezian.org>; Mark Brown <broonie at kernel.org>; Rob Herring
> <robh+dt at kernel.org>; Pratyush Yadav <p.yadav at ti.com>; linux-
> spi at vger.kernel.org; linux-samsung-soc at vger.kernel.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org
> Cc: Sam Protsenko <semen.protsenko at linaro.org>; Rob Herring
> <robh at kernel.org>
> Subject: [PATCH v3 4/4] spi: s3c64xx: allow controller-data to be optional
> 
> The Samsung SoC SPI driver requires to provide controller-data node for
> each of SPI peripheral device nodes.  Make this controller-data node
> optional, so DTS could be simpler.
> 
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Reviewed-by: Chanho Park <chanho61.park at samsung.com>



From alim.akhtar at samsung.com  Thu Jan 13 22:16:04 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 11:46:04 +0530
Subject: [PATCH 03/23] clk: samsung: fsd: Add initial clock support
In-Reply-To: <b9fac286-9227-b26b-221b-7f54b63e6b0b@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122324epcas5p105c53b448b5801813a02a88c6107a2f3@epcas5p1.samsung.com>
 <20220113121143.22280-4-alim.akhtar@samsung.com>
 <b9fac286-9227-b26b-221b-7f54b63e6b0b@canonical.com>
Message-ID: <077d01d8090e$37f75da0$a7e618e0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:20 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>Jayati Sahu <jayati.sahu at samsung.com>; Ajay Kumar
><ajaykumar.rs at samsung.com>
>Subject: Re: [PATCH 03/23] clk: samsung: fsd: Add initial clock support
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add initial clock support for FSD (Full Self-Driving) SoC which is
>> required to bring-up platforms based on this SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  drivers/clk/samsung/Makefile  |   1 +
>>  drivers/clk/samsung/clk-fsd.c | 308
>++++++++++++++++++++++++++++++++++
>>  drivers/clk/samsung/clk-pll.c |   1 +
>>  drivers/clk/samsung/clk-pll.h |   1 +
>>  4 files changed, 311 insertions(+)
>>  create mode 100644 drivers/clk/samsung/clk-fsd.c
>>
>> diff --git a/drivers/clk/samsung/Makefile
>> b/drivers/clk/samsung/Makefile index c46cf11e4d0b..d66b2ede004c 100644
>> --- a/drivers/clk/samsung/Makefile
>> +++ b/drivers/clk/samsung/Makefile
>> @@ -18,6 +18,7 @@ obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-
>exynos-audss.o
>>  obj-$(CONFIG_EXYNOS_CLKOUT)	+= clk-exynos-clkout.o
>>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos7.o
>>  obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK)	+= clk-exynos850.o
>> +obj-$(CONFIG_ARCH_TESLA_FSD)         += clk-fsd.o
>
>It should be rather it's own CONFIG_TESLA_FSD_CLK option, just like other
>Exynos designs. This keeps unified approach with existing Samsung clock
>Kconfig.
>
Ok, will add a separate config for this 

>>  obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>> obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>> obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git
>> a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c new
>> file mode 100644 index 000000000000..e47523106d9e
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk-fsd.c
>> @@ -0,0 +1,308 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Common Clock Framework support for FSD SoC.
>> + *
>> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
>> + *             https://www.samsung.com
>> + * Copyright (c) 2017-2022 Tesla, Inc.
>> + *             https://www.tesla.com
>> + *
>
>Drop the line break with empty * comment.
Will fix in next version
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/of.h>
>> +
>> +#include "clk.h"
>> +#include <dt-bindings/clock/fsd-clk.h>
>
>dt-bindings headers before local clk.h.
>
Noted, thanks
>> +
>> +/* Register Offset definitions for CMU_CMU (0x11c10000) */
>
>
>
>Best regards,
>Krzysztof



From linmq006 at gmail.com  Thu Jan 13 22:23:07 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri, 14 Jan 2022 06:23:07 +0000
Subject: [PATCH] misc: atmel-ssc: Fix IRQ check in ssc_probe
Message-ID: <20220114062307.15199-1-linmq006@gmail.com>

platform_get_irq() returns negative error number instead 0 on failure.
And the doc of platform_get_irq() provides a usage example:

    int irq = platform_get_irq(pdev, 0);
    if (irq < 0)
        return irq;

Fix the check of return value to catch errors correctly.

Fixes: eb1f2930609b ("Driver for the Atmel on-chip SSC on AT32AP and AT91")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/misc/atmel-ssc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/atmel-ssc.c b/drivers/misc/atmel-ssc.c
index d6cd5537126c..69f9b0336410 100644
--- a/drivers/misc/atmel-ssc.c
+++ b/drivers/misc/atmel-ssc.c
@@ -232,9 +232,9 @@ static int ssc_probe(struct platform_device *pdev)
 	clk_disable_unprepare(ssc->clk);
 
 	ssc->irq = platform_get_irq(pdev, 0);
-	if (!ssc->irq) {
+	if (ssc->irq < 0) {
 		dev_dbg(&pdev->dev, "could not get irq\n");
-		return -ENXIO;
+		return ssc->irq;
 	}
 
 	mutex_lock(&user_lock);
-- 
2.17.1



From reijiw at google.com  Thu Jan 13 22:23:49 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 13 Jan 2022 22:23:49 -0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <CAJHc60y6b-scY8zcPuLnjGtr6HzSBnmhi2mCnmkNm4nTxgMTUQ@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
 <CAAeT=FztkibSajKjnpRfObx+D1r8H1s_8-5MmqjemJTfmb2mpg@mail.gmail.com>
 <CAJHc60ywYgAPfG11Ljkj3qzLoUn9mZPKnPH0P-HYS-pfs+A__g@mail.gmail.com>
 <CAAeT=FwA9X9eXrF+Q31Wzah=UkM-B8bMJObjJ=oCV0rjLfX6=g@mail.gmail.com>
 <CAJHc60y6b-scY8zcPuLnjGtr6HzSBnmhi2mCnmkNm4nTxgMTUQ@mail.gmail.com>
Message-ID: <CAAeT=FyER7GWZqSHyRA4-YRwef_KmGEw+tUoxBc7GXC4-6hFhw@mail.gmail.com>

> > > > > +static void
> > > > > +kvm_arm_get_fw_reg_bmap(struct kvm_vcpu *vcpu, u64 fw_reg_bmap, u64 *val)
> > > > > +{
> > > > > +       struct kvm *kvm = vcpu->kvm;
> > > > > +
> > > > > +       mutex_lock(&kvm->lock);
> > > > > +       *val = fw_reg_bmap;
> > > > > +       mutex_unlock(&kvm->lock);
> > > >

I have another comment for kvm_arm_get_fw_reg_bmap.

I just noticed that @fw_reg_bmap is a value of the bitmap register
(not a pointer).  I believe what you meant was a pointer to
hvc_desc->hvc_*_bmap.  Also, you can remove @val and return the register
value instead (change the type of the return value from void to u64).
I'm not sure if you will keep this function in the next version though.

Thanks,
Reiji


From linmq006 at gmail.com  Thu Jan 13 22:28:40 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri, 14 Jan 2022 06:28:40 +0000
Subject: [PATCH] soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
Message-ID: <20220114062840.16620-1-linmq006@gmail.com>

platform_get_irq() returns negative error number instead 0 on failure.
And the doc of platform_get_irq() provides a usage example:

    int irq = platform_get_irq(pdev, 0);
    if (irq < 0)
        return irq;

Fix the check of return value to catch errors correctly.

Fixes: cdd5de500b2c ("soc: ti: Add wkup_m3_ipc driver")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/soc/ti/wkup_m3_ipc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c
index 72386bd393fe..2f03ced0f411 100644
--- a/drivers/soc/ti/wkup_m3_ipc.c
+++ b/drivers/soc/ti/wkup_m3_ipc.c
@@ -450,9 +450,9 @@ static int wkup_m3_ipc_probe(struct platform_device *pdev)
 		return PTR_ERR(m3_ipc->ipc_mem_base);
 
 	irq = platform_get_irq(pdev, 0);
-	if (!irq) {
+	if (irq < 0) {
 		dev_err(&pdev->dev, "no irq resource\n");
-		return -ENXIO;
+		return irq;
 	}
 
 	ret = devm_request_irq(dev, irq, wkup_m3_txev_handler,
-- 
2.17.1



From alim.akhtar at samsung.com  Thu Jan 13 22:30:17 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 12:00:17 +0530
Subject: [PATCH 04/23] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <1b246ad6-5b65-a02f-e887-5a07e8f12ec7@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122330epcas5p46ae5cd30950b1d9126479231dcf5da49@epcas5p4.samsung.com>
 <20220113121143.22280-5-alim.akhtar@samsung.com>
 <1b246ad6-5b65-a02f-e887-5a07e8f12ec7@canonical.com>
Message-ID: <077e01d80910$35ecd5b0$a1c68110$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:25 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>Aswani Reddy <aswani.reddy at samsung.com>; Niyas Ahmed S T
><niyas.ahmed at samsung.com>; Chandrasekar R <rcsekar at samsung.com>;
>Jayati Sahu <jayati.sahu at samsung.com>; Sriranjani P
><sriranjani.p at samsung.com>; Ajay Kumar <ajaykumar.rs at samsung.com>
>Subject: Re: [PATCH 04/23] clk: samsung: fsd: Add cmu_peric block clock
>information
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> This patch adds CMU_PERIC block clock information needed for various
>> IPs functions found in this block.
>
>Here and in all other commits, please do not use "This patch". Instead:
>https://protect2.fireeye.com/v1/url?k=5ec41fe1-015f26dc-5ec594ae-
>0cc47a31309a-72c796795ac37ef5&q=1&e=2a1e171b-f066-48ff-95a7-
>12605dbbf8a9&u=https%3A%2F%2Felixir.bootlin.com%2Flinux%2Fv5.13%2Fso
>urce%2FDocumentation%2Fprocess%2Fsubmitting-patches.rst%23L89
>
Noted
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>> Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
>> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
>> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
>> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  drivers/clk/samsung/clk-fsd.c | 464
>> +++++++++++++++++++++++++++++++++-
>>  1 file changed, 463 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/clk/samsung/clk-fsd.c
>> b/drivers/clk/samsung/clk-fsd.c index e47523106d9e..6da20966ba99
>> 100644
>> --- a/drivers/clk/samsung/clk-fsd.c
>> +++ b/drivers/clk/samsung/clk-fsd.c
>> @@ -9,12 +9,59 @@
>>   *
>>   */
>>
>> -#include <linux/clk-provider.h>
>>  #include <linux/of.h>
>> +#include <linux/clk.h>
>> +#include <linux/of_address.h>
>> +#include <linux/of_device.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/platform_device.h>
>
>Please order the includes alphabetically.
>
Sure will fix this
>>
>>  #include "clk.h"
>>  #include <dt-bindings/clock/fsd-clk.h>
>>
>> +/* Gate register bits */
>> +#define GATE_MANUAL		BIT(20)
>> +#define GATE_ENABLE_HWACG	BIT(28)
>> +
>> +/* Gate register offsets range */
>> +#define GATE_OFF_START		0x2000
>> +#define GATE_OFF_END		0x2fff
>> +
>> +/**
>> + * fsd_init_clocks - Set clocks initial configuration
>> + * @np:			CMU device tree node with "reg" property
>(CMU addr)
>> + * @reg_offs:		Register offsets array for clocks to init
>> + * @reg_offs_len:	Number of register offsets in reg_offs array
>> + *
>> + * Set manual control mode for all gate clocks.
>> + */
>> +static void __init fsd_init_clocks(struct device_node *np,
>> +		const unsigned long *reg_offs, size_t reg_offs_len)
>
>The same as exynos_arm64_init_clocks - please re-use instead of duplicating.
>
Will re-base on latest tree to have these common functions
>> +{
>> +	void __iomem *reg_base;
>> +	size_t i;
>> +
>> +	reg_base = of_iomap(np, 0);
>> +	if (!reg_base)
>> +		panic("%s: failed to map registers\n", __func__);
>> +
>> +	for (i = 0; i < reg_offs_len; ++i) {
>> +		void __iomem *reg = reg_base + reg_offs[i];
>> +		u32 val;
>> +
>> +		/* Modify only gate clock registers */
>> +		if (reg_offs[i] < GATE_OFF_START || reg_offs[i] >
>GATE_OFF_END)
>> +			continue;
>> +
>> +		val = readl(reg);
>> +		val |= GATE_MANUAL;
>> +		val &= ~GATE_ENABLE_HWACG;
>> +		writel(val, reg);
>> +	}
>> +
>> +	iounmap(reg_base);
>> +}
>> +
>
>(...)
>
>> +/**
>> + * fsd_cmu_probe - Probe function for FSD platform clocks
>> + * @pdev: Pointer to platform device
>> + *
>> + * Configure clock hierarchy for clock domains of FSD platform  */
>> +static int __init fsd_cmu_probe(struct platform_device *pdev) {
>> +	const struct samsung_cmu_info *info;
>> +	struct device *dev = &pdev->dev;
>> +	struct device_node *np = dev->of_node;
>> +
>> +	info = of_device_get_match_data(dev);
>> +	fsd_init_clocks(np, info->clk_regs, info->nr_clk_regs);
>> +	samsung_cmu_register_one(np, info);
>> +
>> +	/* Keep bus clock running, so it's possible to access CMU registers */
>> +	if (info->clk_name) {
>> +		struct clk *bus_clk;
>> +
>> +		bus_clk = clk_get(dev, info->clk_name);
>> +		if (IS_ERR(bus_clk)) {
>> +			pr_err("%s: could not find bus clock %s; err = %ld\n",
>> +			       __func__, info->clk_name, PTR_ERR(bus_clk));
>> +		} else {
>> +			clk_prepare_enable(bus_clk);
>> +		}
>> +	}
>> +
>> +	return 0;
>> +}
>
>Please re-use exynos_arm64_register_cmu(). This will also solve my previous
>comment about exynos_arm64_init_clocks().
>
ok
>> +
>> +/* CMUs which belong to Power Domains and need runtime PM to be
>> +implemented */ static const struct of_device_id fsd_cmu_of_match[] = {
>> +	{
>> +		.compatible = "tesla,fsd-clock-peric",
>> +		.data = &peric_cmu_info,
>> +	}, {
>> +	},
>> +};
>> +
>> +static struct platform_driver fsd_cmu_driver __refdata = {
>> +	.driver	= {
>> +		.name = "fsd-cmu",
>> +		.of_match_table = fsd_cmu_of_match,
>> +		.suppress_bind_attrs = true,
>> +	},
>> +	.probe = fsd_cmu_probe,
>> +};
>> +
>> +static int __init fsd_cmu_init(void)
>> +{
>> +	return platform_driver_register(&fsd_cmu_driver);
>> +}
>> +core_initcall(fsd_cmu_init);
>>
>
>
>Best regards,
>Krzysztof



From jkchen at linux.alibaba.com  Thu Jan 13 22:32:49 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Fri, 14 Jan 2022 14:32:49 +0800
Subject: [RESEND PATCH v2] coresight: change tmc from misc device to cdev
 device
In-Reply-To: <CANLsYkzcS07s4C12_Asm61bLz10pg2qwHYtkpxykd8oZ_mJ9tw@mail.gmail.com>
References: <20220113061209.14271-1-jkchen@linux.alibaba.com>
 <CANLsYkwZGSYYBCn8jS5h+3dP9XXr2stw=_tUjvHWNHKyXfothQ@mail.gmail.com>
 <52b46a25-50f9-df82-124c-084db150b52b@linux.alibaba.com>
 <CANLsYkzcS07s4C12_Asm61bLz10pg2qwHYtkpxykd8oZ_mJ9tw@mail.gmail.com>
Message-ID: <027d387a-a830-6d86-e8a4-7f698dcb2a06@linux.alibaba.com>


? 2022/1/14 12:55, Mathieu Poirier ??:
> On Thu, 13 Jan 2022 at 20:16, Jiankang Chen <jkchen at linux.alibaba.com> wrote:
>> Hi Mathieu
>>
>> ? 2022/1/14 00:56, Mathieu Poirier ??:
>>> On Wed, 12 Jan 2022 at 23:12, Jay Chen <jkchen at linux.alibaba.com> wrote:
>>>> Currently, there are 130 etr and etf on our machine,
>>>> but the current coresight tmc driver uses misc_register
>>>> to register the device, which leads to the error that
>>>> the device number is not enough.
>>>>
>>>> coresight-tmc: probe of xxxxx failed with error -16
>>>>
>>>> This patch changes the device registration method
>>>> to cdev's dynamic registration method to solve the
>>>> problem of insufficient device numbers.
>>> On December 21st you posted this patch with a "RFC V3 PATCH" tag.  On
>>> January 5th you posted a new version with a simple "PATCH" tag which,
>>> minutes later, was superseded by another patch labelled "RESEND
>>> PATCH".  Today you're sending yet another revision labelled "RESEND
>>> PATCH V2"...
>>>
>>> Is it a "V2" of the "RESEND PATCH" that was a new revision of the "RFC
>>> V3 PATCH"?  Are you confused?  I certainly am...
>>>
>> this patch v2 is a new version?and it fix some bugs;
>>
> How can it be a V2 when a V3 has already been published?  I will not
> review this patch, and even less apply it, until it is properly
> labelled.
>
OK, I'm going to revise the label and then send it

Thanks

Jay

>> sorry
>>
>> jay
>>
>>>> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
>>>> ---
>>>>    .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
>>>>    drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
>>>>    2 files changed, 91 insertions(+), 23 deletions(-)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> index d0276af82494..0977f1ce6338 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>>>> @@ -12,7 +12,6 @@
>>>>    #include <linux/io.h>
>>>>    #include <linux/err.h>
>>>>    #include <linux/fs.h>
>>>> -#include <linux/miscdevice.h>
>>>>    #include <linux/mutex.h>
>>>>    #include <linux/property.h>
>>>>    #include <linux/uaccess.h>
>>>> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>>>>    DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>>>>    DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>>>>
>>>> +static DEFINE_IDA(tmc_ida);
>>>> +static dev_t tmc_major;
>>>> +static struct class *tmc_class;
>>>> +
>>>> +#define TMC_DEV_MAX    (MINORMASK + 1)
>>>> +
>>>>    void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>>>>    {
>>>>           struct coresight_device *csdev = drvdata->csdev;
>>>> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
>>>>    static int tmc_open(struct inode *inode, struct file *file)
>>>>    {
>>>>           int ret;
>>>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>>>> -                                                  struct tmc_drvdata, miscdev);
>>>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>>>> +                                            struct tmc_cdev, cdev);
>>>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>>>> +                                                  struct tmc_drvdata, cdev);
>>>>
>>>>           ret = tmc_read_prepare(drvdata);
>>>>           if (ret)
>>>> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>>>    {
>>>>           char *bufp;
>>>>           ssize_t actual;
>>>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>>>> -                                                  struct tmc_drvdata, miscdev);
>>>> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
>>>> +                                            struct tmc_cdev, cdev);
>>>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>>>> +                                                  struct tmc_drvdata, cdev);
>>>>           actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>>>>           if (actual <= 0)
>>>>                   return 0;
>>>> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>>>    static int tmc_release(struct inode *inode, struct file *file)
>>>>    {
>>>>           int ret;
>>>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>>>> -                                                  struct tmc_drvdata, miscdev);
>>>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>>>> +                                            struct tmc_cdev, cdev);
>>>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>>>> +                                                  struct tmc_drvdata, cdev);
>>>>
>>>>           ret = tmc_read_unprepare(drvdata);
>>>>           if (ret)
>>>> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>>    {
>>>>           int ret = 0;
>>>>           u32 devid;
>>>> +       dev_t devt;
>>>>           void __iomem *base;
>>>>           struct device *dev = &adev->dev;
>>>>           struct coresight_platform_data *pdata = NULL;
>>>> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>>>                   goto out;
>>>>           }
>>>>
>>>> -       drvdata->miscdev.name = desc.name;
>>>> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>>>> -       drvdata->miscdev.fops = &tmc_fops;
>>>> -       ret = misc_register(&drvdata->miscdev);
>>>> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
>>>> +       if (ret < 0)
>>>> +               goto err_coresight_unregister;
>>>> +
>>>> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
>>>> +       drvdata->cdev.cdev.owner = THIS_MODULE;
>>>> +       devt = MKDEV(MAJOR(tmc_major), ret);
>>>> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>>>>           if (ret)
>>>> -               coresight_unregister(drvdata->csdev);
>>>> -       else
>>>> +               goto err_free_tmc_ida;
>>>> +
>>>> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
>>>> +       if (IS_ERR(drvdata->cdev.dev)) {
>>>> +               ret = PTR_ERR(drvdata->cdev.dev);
>>>> +               goto err_delete_cdev;
>>>> +       } else
>>>>                   pm_runtime_put(&adev->dev);
>>>> +
>>>> +       return 0;
>>>> +
>>>> +err_delete_cdev:
>>>> +       cdev_del(&drvdata->cdev.cdev);
>>>> +err_free_tmc_ida:
>>>> +       ida_simple_remove(&tmc_ida, MINOR(devt));
>>>> +err_coresight_unregister:
>>>> +       coresight_unregister(drvdata->csdev);
>>>>    out:
>>>>           return ret;
>>>>    }
>>>> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
>>>>    static void tmc_remove(struct amba_device *adev)
>>>>    {
>>>>           struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>> +       struct device *dev = drvdata->cdev.dev;
>>>>
>>>> -       /*
>>>> -        * Since misc_open() holds a refcount on the f_ops, which is
>>>> -        * etb fops in this case, device is there until last file
>>>> -        * handler to this device is closed.
>>>> -        */
>>>> -       misc_deregister(&drvdata->miscdev);
>>>> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
>>>> +       device_destroy(tmc_class, dev->devt);
>>>> +       cdev_del(&drvdata->cdev.cdev);
>>>>           coresight_unregister(drvdata->csdev);
>>>>    }
>>>>
>>>> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
>>>>           .id_table       = tmc_ids,
>>>>    };
>>>>
>>>> -module_amba_driver(tmc_driver);
>>>> +static int __init tmc_init(void)
>>>> +{
>>>> +       int ret;
>>>> +
>>>> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
>>>> +       if (ret < 0) {
>>>> +               pr_err("tmc: failed to allocate char dev region\n");
>>>> +               return ret;
>>>> +       }
>>>> +
>>>> +       tmc_class = class_create(THIS_MODULE, "tmc");
>>>> +       if (IS_ERR(tmc_class)) {
>>>> +               pr_err("tmc: failed to create class\n");
>>>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>>>> +               return PTR_ERR(tmc_class);
>>>> +       }
>>>> +
>>>> +       ret = amba_driver_register(&tmc_driver);
>>>> +       if (ret) {
>>>> +               pr_err("tmc: error registering amba driver\n");
>>>> +               class_destroy(tmc_class);
>>>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>>>> +       }
>>>> +
>>>> +       return ret;
>>>> +}
>>>> +
>>>> +static void __exit tmc_exit(void)
>>>> +{
>>>> +       amba_driver_unregister(&tmc_driver);
>>>> +       class_destroy(tmc_class);
>>>> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>>>> +}
>>>> +
>>>> +module_init(tmc_init);
>>>> +module_exit(tmc_exit);
>>>>
>>>>    MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>>>>    MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
>>>> index 6bec20a392b3..11441c6b9c26 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tmc.h
>>>> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
>>>> @@ -7,9 +7,9 @@
>>>>    #ifndef _CORESIGHT_TMC_H
>>>>    #define _CORESIGHT_TMC_H
>>>>
>>>> +#include <linux/cdev.h>
>>>>    #include <linux/dma-mapping.h>
>>>>    #include <linux/idr.h>
>>>> -#include <linux/miscdevice.h>
>>>>    #include <linux/mutex.h>
>>>>    #include <linux/refcount.h>
>>>>
>>>> @@ -163,11 +163,16 @@ struct etr_buf {
>>>>           void                            *private;
>>>>    };
>>>>
>>>> +struct tmc_cdev {
>>>> +       struct cdev cdev;
>>>> +       struct device *dev;
>>>> +};
>>>> +
>>>>    /**
>>>>     * struct tmc_drvdata - specifics associated to an TMC component
>>>>     * @base:      memory mapped base address for this component.
>>>>     * @csdev:     component vitals needed by the framework.
>>>> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
>>>> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
>>>>     * @spinlock:  only one at a time pls.
>>>>     * @pid:       Process ID of the process being monitored by the session
>>>>     *             that is using this component.
>>>> @@ -191,7 +196,7 @@ struct etr_buf {
>>>>    struct tmc_drvdata {
>>>>           void __iomem            *base;
>>>>           struct coresight_device *csdev;
>>>> -       struct miscdevice       miscdev;
>>>> +       struct tmc_cdev         cdev;
>>>>           spinlock_t              spinlock;
>>>>           pid_t                   pid;
>>>>           bool                    reading;
>>>> --
>>>> 2.27.0
>>>>


From linmq006 at gmail.com  Thu Jan 13 22:43:55 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri, 14 Jan 2022 06:43:55 +0000
Subject: [PATCH] soc: aspeed: Fix IRQ check in aspeed_lpc_snoop_config_irq
Message-ID: <20220114064357.18562-1-linmq006@gmail.com>

platform_get_irq() returns negative error number instead 0 on failure.
And the doc of platform_get_irq() provides a usage example:

    int irq = platform_get_irq(pdev, 0);
    if (irq < 0)
        return irq;

Fix the check of return value to catch errors correctly.

Fixes: 524feb799408 ("soc: add aspeed folder and misc drivers")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/soc/aspeed/aspeed-lpc-snoop.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
index eceeaf8dfbeb..c4a03b3a5cf8 100644
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
@@ -167,8 +167,8 @@ static int aspeed_lpc_snoop_config_irq(struct aspeed_lpc_snoop *lpc_snoop,
 	int rc;
 
 	lpc_snoop->irq = platform_get_irq(pdev, 0);
-	if (!lpc_snoop->irq)
-		return -ENODEV;
+	if (lpc_snoop->irq < 0)
+		return lpc_snoop->irq;
 
 	rc = devm_request_irq(dev, lpc_snoop->irq,
 			      aspeed_lpc_snoop_irq, IRQF_SHARED,
-- 
2.17.1



From kai.heng.feng at canonical.com  Thu Jan 13 22:47:47 2022
From: kai.heng.feng at canonical.com (Kai-Heng Feng)
Date: Fri, 14 Jan 2022 14:47:47 +0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <20220113203523.310e13d3@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
 <20220113203523.310e13d3@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <CAAd53p6rW7PcugY7okKsXybK2O=pS8qAhctMzsa-MEgJrKhEdg@mail.gmail.com>

On Fri, Jan 14, 2022 at 12:35 PM Jakub Kicinski <kuba at kernel.org> wrote:
>
> On Fri, 14 Jan 2022 12:07:54 +0800 Kai-Heng Feng wrote:
> > BIOS on Dell Edge Gateway 3200 already makes its own phy LED setting, so
> > instead of setting another value, keep it untouched and restore the saved
> > value on system resume.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
>
> I defer to PHY experts for review. Coincidentally the first Marvell
> flag appears dead, nobody sets it:
>
> $ git grep MARVELL_PHY_M1145_FLAGS_RESISTANCE
> drivers/net/phy/marvell.c:      if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
> include/linux/marvell_phy.h:#define MARVELL_PHY_M1145_FLAGS_RESISTANCE  0x00000001
> $
>
> unless it's read from DT under different name or something.

It was introduced by 95d21ff4c645 without any user. Should we keep it?

>
>
> Once you get some reviews please wait for net-next to open:
>
> http://vger.kernel.org/~davem/net-next.html
>
> and repost. It should happen the week of Jan 24th. When you repost
> please drop the first patch, I believe Russell does not like the BIT()
> macro, his opinion overrides checkpatch.

Of course. I'll wait for the review and resubmit the 2nd patch.

Kai-Heng

>
> Thanks!


From yuzhao at google.com  Thu Jan 13 22:50:15 2022
From: yuzhao at google.com (Yu Zhao)
Date: Thu, 13 Jan 2022 23:50:15 -0700
Subject: [PATCH v6 8/9] mm: multigenerational lru: user interface
In-Reply-To: <877db2opve.fsf@linux.ibm.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-9-yuzhao@google.com>
 <87a6g0nczg.fsf@linux.ibm.com> <YeCvd4UBPy27SYGZ@google.com>
 <877db2opve.fsf@linux.ibm.com>
Message-ID: <YeEdJxLdUaxEGBBP@google.com>

On Fri, Jan 14, 2022 at 10:50:05AM +0530, Aneesh Kumar K.V wrote:
> Yu Zhao <yuzhao at google.com> writes:
> > On Thu, Jan 13, 2022 at 04:01:31PM +0530, Aneesh Kumar K.V wrote:
> >> Yu Zhao <yuzhao at google.com> writes:
> >> 
> >> > Add /sys/kernel/mm/lru_gen/enabled as a runtime kill switch.
> >> 
> >> Got the below lockdep warning while using the above kill/enable switch
> >> 
> >> 
> >> [   84.252952] ======================================================
> >> [   84.253012] WARNING: possible circular locking dependency detected
> >> [   84.253074] 5.16.0-rc8-16204-g1cdcf1120b31 #511 Not tainted
> >> [   84.253135] ------------------------------------------------------
> >> [   84.253194] bash/2862 is trying to acquire lock:
> >> [   84.253243] c0000000021ff740 (cgroup_mutex){+.+.}-{3:3}, at: store_enable+0x80/0x1510
> >> [   84.253340]
> >>                but task is already holding lock:
> >> [   84.253410] c000000002221348 (mem_hotplug_lock){++++}-{0:0}, at: mem_hotplug_begin+0x30/0x50
> >> [   84.253503]
> >>                which lock already depends on the new lock.
> >> 
> >> [   84.255933] Chain exists of:
> >>                  cgroup_mutex --> cpu_hotplug_lock --> mem_hotplug_lock
> >
> > Thanks. Will reverse the order between mem_hotplug_lock and
> > cgroup_mutex in the next spin.
> 
> It also needs the unlocked variant of static_key_enable/disable.

Right. This is what I have at the moment. Tested with QEMU memory
hotplug. Can you please give it try too? Thanks.

    cgroup_lock()
    cpus_read_lock()
    get_online_mems()

        if (enable)
            static_branch_enable_cpuslocked()
        else
            static_branch_disable_cpuslocked()

    put_online_mems()
    cpus_read_unlock()
    cgroup_unlock()


From alim.akhtar at samsung.com  Thu Jan 13 23:10:59 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 12:40:59 +0530
Subject: [PATCH 12/23] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <176af0b0-a324-da39-2848-1c2e01cfadf5@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122404epcas5p4aa1c3ac09510eb55cce5fdd0791993a6@epcas5p4.samsung.com>
 <20220113121143.22280-13-alim.akhtar@samsung.com>
 <176af0b0-a324-da39-2848-1c2e01cfadf5@canonical.com>
Message-ID: <077f01d80915$e3dfd550$ab9f7ff0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:28 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 12/23] dt-bindings: add vendor prefix for Tesla
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add vendor prefix for the Tesla (https://www.tesla.com)
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>>  1 file changed, 2 insertions(
>
>This should be the first patch in the series.
>
>Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>
Thanks, will put this as first patch in this series
>
>Best regards,
>Krzysztof



From clabbe.montjoie at gmail.com  Thu Jan 13 23:12:26 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Fri, 14 Jan 2022 08:12:26 +0100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
In-Reply-To: <YeD6vt47+pAl0SxG@gondor.apana.org.au>
References: <Yd1SIHUNdLIvKhzz@Red> <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
 <YeD6vt47+pAl0SxG@gondor.apana.org.au>
Message-ID: <YeEiWmkyNwfgQgmn@Red>

Le Fri, Jan 14, 2022 at 03:23:26PM +1100, Herbert Xu a ?crit :
> On Fri, Jan 14, 2022 at 03:14:38PM +1100, Herbert Xu wrote:
> > On Tue, Jan 11, 2022 at 10:47:12AM +0100, Corentin Labbe wrote:
> > >
> > > [   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> > > [   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> > > [   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> > > [   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> > > [   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> > 
> > So did sun8i_ce_cipher_run ensure that BH is disabled before
> > invoking xfrm_input? If not then this explains the dead-lock.
> 
> The issue appears to be with crypto_engine.  It needs to ensure
> that completion functions are called with BH disabled, not IRQ
> disabled and definitely not BH enabled.
> 

Hello

This minimal patch fix my issue, does it is the rigth way ?

Thanks for your help
Regards

diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c
index fb07da9920ee..b3844f6d98a3 100644
--- a/crypto/crypto_engine.c
+++ b/crypto/crypto_engine.c
@@ -7,6 +7,7 @@
  * Author: Baolin Wang <baolin.wang at linaro.org>
  */
 
+#include <linux/bottom_half.h>
 #include <linux/err.h>
 #include <linux/delay.h>
 #include <linux/device.h>
@@ -53,7 +54,9 @@ static void crypto_finalize_request(struct crypto_engine *engine,
                                dev_err(engine->dev, "failed to unprepare request\n");
                }
        }
+       local_bh_disable();
        req->complete(req, err);
+       local_bh_enable();
 
        kthread_queue_work(engine->kworker, &engine->pump_requests);
 }



From kai.heng.feng at canonical.com  Thu Jan 13 23:14:30 2022
From: kai.heng.feng at canonical.com (Kai-Heng Feng)
Date: Fri, 14 Jan 2022 15:14:30 +0800
Subject: [PATCH] net: stmmac: Fix "Unbalanced pm_runtime_enable!" warning
Message-ID: <20220114071430.1335872-1-kai.heng.feng@canonical.com>

If the device is PCI based like intel-eth-pci, pm_runtime_enable() is
already called by pci_pm_init().

So only pm_runtime_enable() when it's not already enabled.

Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 63ff2dad8c85f..6708ca2aa4f73 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7159,7 +7159,8 @@ int stmmac_dvr_probe(struct device *device,
 
 	pm_runtime_get_noresume(device);
 	pm_runtime_set_active(device);
-	pm_runtime_enable(device);
+	if (!pm_runtime_enabled(device))
+		pm_runtime_enable(device);
 
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI) {
-- 
2.33.1



From alim.akhtar at samsung.com  Thu Jan 13 23:15:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 12:45:30 +0530
Subject: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for
 Tesla FSD SoC
In-Reply-To: <YeAiIhfN216pRWhn@sirena.org.uk>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122435epcas5p18e6a2699f193b9e1287588278a570235@epcas5p1.samsung.com>
 <20220113121143.22280-19-alim.akhtar@samsung.com>
 <YeAiIhfN216pRWhn@sirena.org.uk>
Message-ID: <078d01d80916$86a461c0$93ed2540$@samsung.com>



>-----Original Message-----
>From: Mark Brown [mailto:broonie at kernel.org]
>Sent: Thursday, January 13, 2022 6:29 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>
>Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; krzysztof.kozlowski at canonical.com;
>s.nawrocki at samsung.com; linux-samsung-soc at vger.kernel.org;
>pankaj.dubey at samsung.com; linux-fsd at tesla.com; linux-
>spi at vger.kernel.org; Aswani Reddy <aswani.reddy at samsung.com>
>Subject: Re: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for
Tesla
>FSD SoC
>
>On Thu, Jan 13, 2022 at 05:41:38PM +0530, Alim Akhtar wrote:
>
>> +	{ .compatible = "tesla,fsd-spi",
>> +			.data = (void *)&fsd_spi_port_config,
>> +	},
>
>This needs a DT bindings update to match.
Thanks for point it out, will update in v2.



From christian.koenig at amd.com  Thu Jan 13 23:16:30 2022
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Fri, 14 Jan 2022 08:16:30 +0100
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
 <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
Message-ID: <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>

Am 14.01.22 um 00:26 schrieb John Stultz:
> On Thu, Jan 13, 2022 at 5:05 AM Christian K?nig
> <christian.koenig at amd.com> wrote:
>> Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
>>>> -----Original Message-----
>>>> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>>>> Ruhl, Michael J
>>>>> -----Original Message-----
>>>>> From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On Behalf Of
>>>>> guangming.cao at mediatek.com
>>>>> +   /*
>>>>> +    * Invalid size check. The "len" should be less than totalram.
>>>>> +    *
>>>>> +    * Without this check, once the invalid size allocation runs on a process
>>>>> that
>>>>> +    * can't be killed by OOM flow(such as "gralloc" on Android devices), it
>>>>> will
>>>>> +    * cause a kernel exception, and to make matters worse, we can't find
>>>>> who are using
>>>>> +    * so many memory with "dma_buf_debug_show" since the relevant
>>>>> dma-buf hasn't exported.
>>>>> +    */
>>>>> +   if (len >> PAGE_SHIFT > totalram_pages())
>>>> If your "heap" is from cma, is this still a valid check?
>>> And thinking a bit further, if I create a heap from something else (say device memory),
>>> you will need to be able to figure out the maximum allowable check for the specific
>>> heap.
>>>
>>> Maybe the heap needs a callback for max size?
>> Well we currently maintain a separate allocator and don't use dma-heap,
>> but yes we have systems with 16GiB device and only 8GiB system memory so
>> that check here is certainly not correct.
> Good point.
>
>> In general I would rather let the system run into -ENOMEM or -EINVAL
>> from the allocator instead.
> Probably the simpler solution is to push the allocation check to the
> heap driver, rather than doing it at the top level here.
>
> For CMA or other contiguous heaps, letting the allocator fail is fast
> enough. For noncontiguous buffers, like the system heap, the
> allocation can burn a lot of time and consume a lot of memory (causing
> other trouble) before a large allocation might naturally fail.

Yeah, letting a alloc_page() loop run for a while is usually not nice at 
all :)

You can still do a sanity check here, e.g. the size should never have 
the most significant bit set for example.

Regards,
Christian.

>
> thanks
> -john



From alim.akhtar at samsung.com  Thu Jan 13 23:17:55 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 12:47:55 +0530
Subject: [PATCH 17/23] Documentation: bindings: Add fsd spi compatible
 in dt-bindings document
In-Reply-To: <0d4c7a40-5eec-2cc5-82bc-d0ba4910d665@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122427epcas5p1885d8b3b735e8f127b6694a309796e5a@epcas5p1.samsung.com>
 <20220113121143.22280-18-alim.akhtar@samsung.com>
 <0d4c7a40-5eec-2cc5-82bc-d0ba4910d665@canonical.com>
Message-ID: <078e01d80916$dc613c00$9523b400$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:55 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>Adithya K V <adithya.kv at samsung.com>
>Subject: Re: [PATCH 17/23] Documentation: bindings: Add fsd spi compatible
>in dt-bindings document
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> This patch adds spi controller dt-binding compatible information for
>> Tesla Full Self-Driving SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  Documentation/devicetree/bindings/spi/spi-samsung.txt | 1 +
>>  1 file changed, 1 insertion(+)
>>
>
>Also: subject prefix:
>spi: dt-bindings: samsung:
>
Ok, will update and rebase on your upcoming dt schema patch set.

>> diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt
>> b/Documentation/devicetree/bindings/spi/spi-samsung.txt
>> index 49028a4f5df1..3af2408454b4 100644
>> --- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
>> +++ b/Documentation/devicetree/bindings/spi/spi-samsung.txt
>> @@ -11,6 +11,7 @@ Required SoC Specific Properties:
>>      - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
>>      - samsung,exynos5433-spi: for exynos5433 compatible controllers
>>      - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
>> +    - tesla,fsd-spi: spi controller support for Tesla Full
>> + Self-Driving SoC
>>
>>  - reg: physical base address of the controller and length of memory mapped
>>    region.
>>
>
>
>Best regards,
>Krzysztof



From krzysztof.kozlowski at canonical.com  Thu Jan 13 23:34:26 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 14 Jan 2022 08:34:26 +0100
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <076001d80909$52d201c0$f8760540$@samsung.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <d1a852e1-c4c2-b7c4-ddeb-7fbcfd9b4e58@canonical.com>
 <076001d80909$52d201c0$f8760540$@samsung.com>
Message-ID: <5e3f84e0-7b91-8eac-1643-d44f61a47620@canonical.com>

On 14/01/2022 06:41, Alim Akhtar wrote:
> Hi Krzysztof,
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>> Sent: Thursday, January 13, 2022 6:02 PM
>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>> olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>> soc at vger.kernel.org; pankaj.dubey at samsung.com
>> Subject: Re: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
>>
>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>> This patch set adds basic support for the Tesla Full Self-Driving
>>> (FSD) SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
>>> as well as several IPs.
>>>
>>> Patches 1 to 8 provide support for the clock controller (which is
>>> designed similarly to Exynos SoCs).
>>>
>>> The remaining changes provide pinmux support, initial device tree
>>> support, and SPI, ADC, and MCT IP functionality.
>>
>> Does FSD have some version number? The FDS, especially in compatibles,
>> looks quite generic, so what will happen if a newer SoC comes later? You
>> would have:
>> - tesla,fsd-pinctrl
>> - tesla,fsd-xxxx-pinctrl (where xxxx could be some new version)
>>
>> This will be extra confusing, because fsd-pinctrl looks like the generic one,
>> while it is specific...
>>
> AFAIK, there is no version for FSD SoC (like we see on Exynos or any other SoC)
> In case something comes in future, may be just adopt as Olof suggested in the other thread like fsd2 etc..
>> Best regards,
>> Krzysztof

The naming is still confusing. The SoC is FSD, compatible is "fsd" but
entire sub-architecture is also FSD called. Therefore it looks like
creating entire sub-architecture for only one SoC, which actually in
multiple pieces is or looks like Samsung Exynos (designed by Samsung,
using several blocks from Exynos SoC).

Best regards,
Krzysztof


From wenst at chromium.org  Thu Jan 13 23:40:38 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Fri, 14 Jan 2022 15:40:38 +0800
Subject: [PATCH] drm/rockchip: Support YUV formats with U/V swapped
Message-ID: <20220114074038.2633848-1-wenst@chromium.org>

The VOP in Rockchip SoCs that support YUV planes also support swapping
of the U and V elements. Supporting the swapped variants, especially
NV21, would be beneficial for multimedia applications, as the hardware
video decoders only output NV21, and supporting this pixel format in
the display pipeline would allow the decoded video frames to be output
directly.

Add support for this to support the various formats that have U/V
swapped.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---

This was tested on an ROC-RK3399-PC with modetest only. Changes to all
other SoC platforms were based on their respective TRMs.

---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 20 +++++++++++++++++++-
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h |  1 +
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 11 +++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3e8d9e2d1b67..c75b39474977 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -262,6 +262,18 @@ static bool has_rb_swapped(uint32_t format)
 	}
 }
 
+static bool has_uv_swapped(uint32_t format)
+{
+	switch (format) {
+	case DRM_FORMAT_NV21:
+	case DRM_FORMAT_NV61:
+	case DRM_FORMAT_NV42:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static enum vop_data_format vop_convert_format(uint32_t format)
 {
 	switch (format) {
@@ -277,10 +289,13 @@ static enum vop_data_format vop_convert_format(uint32_t format)
 	case DRM_FORMAT_BGR565:
 		return VOP_FMT_RGB565;
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_NV21:
 		return VOP_FMT_YUV420SP;
 	case DRM_FORMAT_NV16:
+	case DRM_FORMAT_NV61:
 		return VOP_FMT_YUV422SP;
 	case DRM_FORMAT_NV24:
+	case DRM_FORMAT_NV42:
 		return VOP_FMT_YUV444SP;
 	default:
 		DRM_ERROR("unsupported format[%08x]\n", format);
@@ -899,7 +914,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 	unsigned long offset;
 	dma_addr_t dma_addr;
 	uint32_t val;
-	bool rb_swap;
+	bool rb_swap, uv_swap;
 	int win_index = VOP_WIN_TO_INDEX(vop_win);
 	int format;
 	int is_yuv = fb->format->is_yuv;
@@ -988,6 +1003,9 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
 							y2r_coefficients[i],
 							bt601_yuv2rgb[i]);
 		}
+
+		uv_swap = has_uv_swapped(fb->format->format);
+		VOP_WIN_SET(vop, win, uv_swap, uv_swap);
 	}
 
 	if (win->phy->scl)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
index 857d97cdc67c..3aa95fdd427d 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -166,6 +166,7 @@ struct vop_win_phy {
 	struct vop_reg gate;
 	struct vop_reg format;
 	struct vop_reg rb_swap;
+	struct vop_reg uv_swap;
 	struct vop_reg act_info;
 	struct vop_reg dsp_info;
 	struct vop_reg dsp_st;
diff --git a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
index 1f7353f0684a..af2b07fafadf 100644
--- a/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ b/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -46,8 +46,11 @@ static const uint32_t formats_win_full[] = {
 	DRM_FORMAT_RGB565,
 	DRM_FORMAT_BGR565,
 	DRM_FORMAT_NV12,
+	DRM_FORMAT_NV21,
 	DRM_FORMAT_NV16,
+	DRM_FORMAT_NV61,
 	DRM_FORMAT_NV24,
+	DRM_FORMAT_NV42,
 };
 
 static const uint64_t format_modifiers_win_full[] = {
@@ -272,6 +275,7 @@ static const struct vop_win_phy px30_win0_data = {
 	.enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
+	.uv_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 15),
 	.act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
 	.dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
 	.dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
@@ -291,6 +295,7 @@ static const struct vop_win_phy px30_win1_data = {
 	.enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
 	.format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
 	.rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
+	.uv_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 15),
 	.dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
 	.dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
 	.yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
@@ -368,6 +373,7 @@ static const struct vop_win_phy rk3066_win0_data = {
 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 0),
 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 4),
 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 19),
+	.uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 22),
 	.act_info = VOP_REG(RK3066_WIN0_ACT_INFO, 0x1fff1fff, 0),
 	.dsp_info = VOP_REG(RK3066_WIN0_DSP_INFO, 0x0fff0fff, 0),
 	.dsp_st = VOP_REG(RK3066_WIN0_DSP_ST, 0x1fff1fff, 0),
@@ -386,6 +392,7 @@ static const struct vop_win_phy rk3066_win1_data = {
 	.enable = VOP_REG(RK3066_SYS_CTRL1, 0x1, 1),
 	.format = VOP_REG(RK3066_SYS_CTRL1, 0x7, 7),
 	.rb_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 23),
+	.uv_swap = VOP_REG(RK3066_SYS_CTRL1, 0x1, 26),
 	.act_info = VOP_REG(RK3066_WIN1_ACT_INFO, 0x1fff1fff, 0),
 	.dsp_info = VOP_REG(RK3066_WIN1_DSP_INFO, 0x0fff0fff, 0),
 	.dsp_st = VOP_REG(RK3066_WIN1_DSP_ST, 0x1fff1fff, 0),
@@ -489,6 +496,7 @@ static const struct vop_win_phy rk3188_win0_data = {
 	.enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
 	.format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
 	.rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
+	.uv_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 18),
 	.act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
 	.dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
 	.dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
@@ -619,6 +627,7 @@ static const struct vop_win_phy rk3288_win01_data = {
 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+	.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
 	.dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
@@ -753,6 +762,7 @@ static const struct vop_win_phy rk3368_win01_data = {
 	.enable = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3368_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 12),
+	.uv_swap = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 15),
 	.x_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 21),
 	.y_mir_en = VOP_REG(RK3368_WIN0_CTRL0, 0x1, 22),
 	.act_info = VOP_REG(RK3368_WIN0_ACT_INFO, 0x1fff1fff, 0),
@@ -902,6 +912,7 @@ static const struct vop_win_phy rk3399_win01_data = {
 	.enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
 	.format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
 	.rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
+	.uv_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 15),
 	.y_mir_en = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 22),
 	.act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
 	.dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
-- 
2.34.1.703.g22d0c6ccf7-goog



From krzysztof.kozlowski at canonical.com  Thu Jan 13 23:49:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 14 Jan 2022 08:49:36 +0100
Subject: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <076101d80909$d5849060$808db120$@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122354epcas5p19e5cebe9e85e9ba1758fa0b9d7d1ef75@epcas5p1.samsung.com>
 <20220113121143.22280-11-alim.akhtar@samsung.com>
 <849c7772-0f7e-32ff-6ea6-c46aa6837bb4@canonical.com>
 <076101d80909$d5849060$808db120$@samsung.com>
Message-ID: <65e6f034-278a-81fa-844d-10a1865a25a4@canonical.com>

On 14/01/2022 06:44, Alim Akhtar wrote:
> 
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>> Sent: Thursday, January 13, 2022 5:57 PM
>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>> olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>> Subject: Re: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
>> Tesla FSD SoC
>>
>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>> Add compatible for Tesla Full Self-Driving SoC. The pinctrl hardware
>>> IP is similar to what found on most of the exynos series of SoC, so
>>> this new compatible is added in samsung pinctrl binding.
>>>
>>> Cc: linux-fsd at tesla.com
>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>> ---
>>>  Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git
>>> a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>> b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>> index b8b475967ff9..ba972998a0e4 100644
>>> --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>> +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>> @@ -24,6 +24,7 @@ Required Properties:
>>>    - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
>>>    - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
>>>    - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-
>> controller.
>>> +  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
>>>
>>
>> Please rebase this on my latest Samsung pinctrl dtschema patches. You also
>> need a tesla vendor prefix patch (separate).
>>
> Sure will rebase when sending v2, your latest patches are in Linux-next or still in your tree?

The SPI (v3) and pinctrl (v2) dtschema patches are on mailing lists.
They seem to be done, so after merge window they will make to
linux-next. If you want earlier, grab them from mailing list or from
branches:
https://github.com/krzk/linux/tree/n/dt-bindings-samsung-spi-schema-v3
https://github.com/krzk/linux/tree/n/dt-bindings-samsung-pinctrl-schema-v2


Best regards,
Krzysztof


From hverkuil-cisco at xs4all.nl  Fri Jan 14 00:11:37 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Fri, 14 Jan 2022 09:11:37 +0100
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <20211224012738.1551-2-jammy_huang@aspeedtech.com>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
Message-ID: <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>

On 24/12/2021 02:27, Jammy Huang wrote:
> This introduces support for the Aspeed JPEG format, where the new frame
> can refer to previous frame to reduce the amount of compressed data. The
> concept is similar to I/P frame of video compression. It will compare the
> new frame with previous one to decide which macroblock's data is
> changed, and only the changed macroblocks will be compressed.
> 
> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
> which is generally adapted for remote KVM.
> 
> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
> ---
> v8:
>   - Add decoder information for aspeed-jpeg
> v7:
>   - Add more information for aspeed-jpeg
> v6:
>   - Update description for new format, aspeed-jpeg, in Documentation.
> v5:
>   - no update
> v4:
>   - new
> ---
>  .../media/uapi/v4l/pixfmt-reserved.rst          | 17 +++++++++++++++++
>  drivers/media/v4l2-core/v4l2-ioctl.c            |  1 +
>  include/uapi/linux/videodev2.h                  |  1 +
>  3 files changed, 19 insertions(+)
> 
> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst

This is the wrong file! It should be:

Documentation/userspace-api/media/v4l/pixfmt-reserved.rst

Regards,

	Hans

> index b2cd155e691b..1d0dc8d86ed7 100644
> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
>  	of tiles, resulting in 32-aligned resolutions for the luminance plane
>  	and 16-aligned resolutions for the chrominance plane (with 2x2
>  	subsampling).
> +    * .. _V4L2-PIX-FMT-AJPG:
> +
> +      - ``V4L2_PIX_FMT_AJPG``
> +      - 'AJPG'
> +      - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
> +        which is generally adapted for remote KVM.
> +        On each frame compression, I will compare the new frame with previous
> +        one to decide which macroblock's data is changed, and only the changed
> +        macroblocks will be compressed.
> +
> +        The implementation is based on AST2600 A3 datasheet, revision 0.9, which
> +        is not publicly available. Or you can reference Video stream data format
> +        ? ASPEED mode compression of SDK_User_Guide which available on
> +        AspeedTech-BMC/openbmc/releases.
> +
> +        Decoder's implementation can be found here,
> +        `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
>  
>  .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>  
> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> index 24db33f803c0..00dde01d2f97 100644
> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>  		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
>  		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
>  		case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
> +		case V4L2_PIX_FMT_AJPG:		descr = "Aspeed JPEG"; break;
>  		default:
>  			if (fmt->description[0])
>  				return;
> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> index 3210b3c82a4a..994eb6155ea9 100644
> --- a/include/uapi/linux/videodev2.h
> +++ b/include/uapi/linux/videodev2.h
> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
>  #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
>  #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
>  #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
> +#define V4L2_PIX_FMT_AJPG     v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
>  
>  /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
>  #define V4L2_PIX_FMT_IPU3_SBGGR10	v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */



From alim.akhtar at samsung.com  Fri Jan 14 00:13:20 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 13:43:20 +0530
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <CAK8P3a0etf+AybUe5O9uRLAbo4J145t0-ThkEccNtKzue+0-qA@mail.gmail.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
 <20220113121143.22280-15-alim.akhtar@samsung.com>
 <55c22c3a-57ea-3320-ccb9-f03643563235@canonical.com>
 <CAK8P3a0etf+AybUe5O9uRLAbo4J145t0-ThkEccNtKzue+0-qA@mail.gmail.com>
Message-ID: <07ce01d8091e$9a6fd9c0$cf4f8d40$@samsung.com>

Hi Arnd and Krzysztof

>-----Original Message-----
>From: Arnd Bergmann [mailto:arnd at arndb.de]
>Sent: Thursday, January 13, 2022 7:54 PM
>To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>Cc: Alim Akhtar <alim.akhtar at samsung.com>; Linux ARM <linux-arm-
>kernel at lists.infradead.org>; Linux Kernel Mailing List <linux-
>kernel at vger.kernel.org>; SoC Team <soc at kernel.org>; linux-clk <linux-
>clk at vger.kernel.org>; DTML <devicetree at vger.kernel.org>; Olof Johansson
><olof at lixom.net>; Linus Walleij <linus.walleij at linaro.org>; Catalin Marinas
><catalin.marinas at arm.com>; Rob Herring <robh+dt at kernel.org>; Sylwester
>Nawrocki <s.nawrocki at samsung.com>; moderated list:ARM/SAMSUNG
>EXYNOS ARM ARCHITECTURES <linux-samsung-soc at vger.kernel.org>; Pankaj
>Dubey <pankaj.dubey at samsung.com>; linux-fsd at tesla.com; Arjun K V
><arjun.kv at samsung.com>; Aswani Reddy <aswani.reddy at samsung.com>;
>Ajay Kumar <ajaykumar.rs at samsung.com>; Sriranjani P
><sriranjani.p at samsung.com>; Chandrasekar R <rcsekar at samsung.com>;
>Shashank Prashar <s.prashar at samsung.com>; Arnd Bergmann
><arnd at arndb.de>
>Subject: Re: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
>
>On Thu, Jan 13, 2022 at 2:16 PM Krzysztof Kozlowski
><krzysztof.kozlowski at canonical.com> wrote:
>> >  ARM/TETON BGA MACHINE SUPPORT
>> >  M:   "Mark F. Brown" <mark.brown314 at gmail.com>
>> >  L:   linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>> > diff --git a/arch/arm64/Kconfig.platforms
>> > b/arch/arm64/Kconfig.platforms index 54e3910e8b9b..bb8a047c2359
>> > 100644
>> > --- a/arch/arm64/Kconfig.platforms
>> > +++ b/arch/arm64/Kconfig.platforms
>> > @@ -267,6 +267,12 @@ config ARCH_TEGRA
>> >       help
>> >         This enables support for the NVIDIA Tegra SoC family.
>> >
>> > +config ARCH_TESLA_FSD
>> > +     bool "ARMv8 based Tesla platform"
>> > +     select ARCH_EXYNOS
>>
>> How similar it is? I think it is better to duplicate Exynos
>> selections/options here, instead of selecting entire ARCH. If this
>> would require "depends on ARCH_EXYNOS || ARCH_TESLA_FSD"
>everywhere in
>> the drivers, it's a hint that it is not a separate SoC but it is an
>> Exynos, so it might not need a new sub-architecture.
>
>Agreed, the SoC family options mainly exist so we can quickly enable or
>disable drivers based on what a kernel is built for. If most of the drivers for
>this SoC are shared with Exynos, I think having a single option is sufficient, but
>it may be worth pointing out both in the help text.
>
>If we want to have a separate option (mainly to help users find it), maybe a
>'depends on ARCH_EXYNOS' would be better. How many uses of
>ARCH_TESLA_FSD are there?
>
It is true that FSD shares few IPs with Exynos and it dose contains Telsa specific IPs/ PCIe/some of the PHYs/ GPUs (different then Exynos) etc. to name a few.
And drivers for those will be posted in upcoming phases by Samsung, Telsa etc.
AFA architecture is concerns both Exynos and FSD has completely different architecture (at least at HW level).
In my opinion, it is make sense to have a separate option for FSD.
And as Arnd suggested "'depends on ARCH_EXYNOS" may be the way forward.

>        Arnd



From m.tretter at pengutronix.de  Fri Jan 14 00:14:42 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Fri, 14 Jan 2022 09:14:42 +0100
Subject: [PATCH] clk: zynqmp: warn always when a clock op fails
In-Reply-To: <20220112202937.034D9C36AE5@smtp.kernel.org>
References: <20220112141229.700708-1-m.tretter@pengutronix.de>
 <20220112202937.034D9C36AE5@smtp.kernel.org>
Message-ID: <20220114081442.GR26783@pengutronix.de>

On Wed, 12 Jan 2022 12:29:35 -0800, Stephen Boyd wrote:
> Quoting Michael Tretter (2022-01-12 06:12:29)
> > The warning that a clock operation failed is only printed once. However,
> > the function is called for various different clocks. The limit hides
> > warnings if different clock are affected by the failures.
> > 
> > Print the warning every time when a clock operation fails.
> > 
> > Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> > ---
> >  drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
> >  drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
> >  drivers/clk/zynqmp/divider.c         | 12 +++++------
> >  drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
> >  4 files changed, 32 insertions(+), 32 deletions(-)
> > 
> > diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > index 565ed67a0430..0d9a39110f29 100644
> > --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > @@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
> >         ret = zynqmp_pm_clock_enable(clk_id);
> >  
> >         if (ret)
> > -               pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
> > -                            __func__, clk_name, ret);
> > +               pr_warn("%s() clock enable failed for %s (id %d), ret = %d\n",
> > +                       __func__, clk_name, clk_id, ret);
> 
> Can we just remove these prints entirely? The driver that calls
> clk_enable() should be checking the return value and taking proper
> action. What is the user going to do with these messages?
> 

The clocks are handled by a firmware, which checks if the Linux system has the
permission to change certain clocks. The warnings help users to identify an
unexpected configuration of the firmware. However, I guess it would make sense
to change the warnings to pr_debug.

Michael


From vulab at iscas.ac.cn  Fri Jan 14 00:22:14 2022
From: vulab at iscas.ac.cn (Xu Wang)
Date: Fri, 14 Jan 2022 08:22:14 +0000
Subject: [PATCH] media: mtk-mdp: Remove redundant 'flush_workqueue()' calls
Message-ID: <20220114082214.41817-1-vulab@iscas.ac.cn>

'destroy_workqueue()' already drains the queue before destroying it, so
there is no need to flush it explicitly.

Remove the redundant 'flush_workqueue()' calls.

Signed-off-by: Xu Wang <vulab at iscas.ac.cn>
---
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 3d38793aaa25..fbd6e06a0567 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -246,10 +246,8 @@ static int mtk_mdp_remove(struct platform_device *pdev)
 	mtk_mdp_unregister_m2m_device(mdp);
 	v4l2_device_unregister(&mdp->v4l2_dev);
 
-	flush_workqueue(mdp->wdt_wq);
 	destroy_workqueue(mdp->wdt_wq);
 
-	flush_workqueue(mdp->job_wq);
 	destroy_workqueue(mdp->job_wq);
 
 	list_for_each_entry_safe(comp, comp_temp, &mdp->comp_list, node) {
-- 
2.25.1



From narmstrong at baylibre.com  Fri Jan 14 00:23:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 09:23:51 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
Message-ID: <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>

Hi,

On 13/01/2022 21:01, Fabio Estevam wrote:
> Hi Biju,
> 
> On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com> wrote:
>>
>> Hi All,
>>
>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till the commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts callbacks").
>>
>> After this patch, the screen becomes greenish(may be it is setting it into YUV format??).
>>
>> By checking the code, previously it used to call get_input_fmt callback and set colour as RGB24.
>>
>> After this commit, it calls get_output_fmt_callbck and returns 3 outputformats(YUV16, YUV24 and RGB24)
>> And get_input_fmt callback, I see the outputformat as YUV16 instead of RGB24.
>>
>> Not sure, I am the only one seeing this issue with dw_HDMI driver.

This patch was introduced to maintain the bridge color format negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR,
but it seems it behaves incorrectly if the first bridge doesn't implement the negotiation callbacks.

Let me check the code to see how to fix that.

> 
> I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
> 
> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> (DWC HDMI 3D TX PHY)
> 
> The colors are shown correctly here.
> 

The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation fails and use the RGB fallback input & output format.

Anyway thanks for testing

Neil


From biju.das.jz at bp.renesas.com  Fri Jan 14 00:29:28 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 08:29:28 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
Message-ID: <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,
 
+ renesas-soc

> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi,
> 
> On 13/01/2022 21:01, Fabio Estevam wrote:
> > Hi Biju,
> >
> > On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com>
> wrote:
> >>
> >> Hi All,
> >>
> >> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till
> >> the commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks").
> >>
> >> After this patch, the screen becomes greenish(may be it is setting it
> into YUV format??).
> >>
> >> By checking the code, previously it used to call get_input_fmt callback
> and set colour as RGB24.
> >>
> >> After this commit, it calls get_output_fmt_callbck and returns 3
> >> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I see
> the outputformat as YUV16 instead of RGB24.
> >>
> >> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> 
> This patch was introduced to maintain the bridge color format negotiation
> after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems it behaves
> incorrectly if the first bridge doesn't implement the negotiation
> callbacks.
> 
> Let me check the code to see how to fix that.

Thanks for the information, I am happy to test the patch/fix.

Cheers,
Biju

> 
> >
> > I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
> >
> > dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> > (DWC HDMI 3D TX PHY)
> >
> > The colors are shown correctly here.
> >
> 
> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
> fails and use the RGB fallback input & output format.
> 
> Anyway thanks for testing
> 
> Neil

From vladimir.murzin at arm.com  Fri Jan 14 00:35:06 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Fri, 14 Jan 2022 08:35:06 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <20220113195051.7100b066@slackpad.fritz.box>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
 <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
 <20220113195051.7100b066@slackpad.fritz.box>
Message-ID: <9eb63797-b313-a39a-6b9c-0f8ac447b85a@arm.com>

Hi Andre,

On 1/13/22 7:50 PM, Andre Przywara wrote:
> On Thu, 13 Jan 2022 18:42:50 +0000
> Vladimir Murzin <vladimir.murzin at arm.com> wrote:
> 
> Hi Vladimir,
> 
>> On 12/22/21 6:16 PM, Andre Przywara wrote:
>>> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
>>> the blob first, then re-compile it with our nodes and properties added.
>>>
>>> In our input DTB the proper phandle references have already been lost,
>>> all we see in the DTB is phandle properties in the target node, and some
>>> numbers in the clocks and gpios properties:
>>> ===========
>>> 	clk24mhz {
>>> 		compatible = "fixed-clock";
>>> 		#clock-cells = <0x00>;
>>> 		clock-frequency = <0x16e3600>;
>>> 		clock-output-names = "v2m:clk24mhz";  
>>> ->		phandle = <0x05>;  
>>> 	};
>>> 	...
>>> 	serial at 90000 {
>>> 		compatible = "arm,pl011", "arm,primecell";
>>> 		reg = <0x90000 0x1000>;
>>> 		interrupts = <0x05>;  
>>> ->		clocks = <0x05 0x05>;  
>>> 		clock-names = "uartclk", "apb_pclk";
>>> 	};
>>> ===========
>>> dtc warns that those numbers might be wrong:
>>> =========
>>> <stdin>:177.6-27: Warning (clocks_property):
>>>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
>>>    clocks: cell 0 is not a phandle reference
>>> ....
>>> =========
>>> The proper solution would be to use references (&v2m_clk24mhz) instead,
>>> as there are in the source .dts file, but we don't have that information
>>> anymore, and cannot easily recover it.
>>>
>>> To avoid the lengthy list of warnings, just drop those checks from the
>>> dtc compilation run. This disables more checks than we want or need, but
>>> we somewhat trust in the original DTB to be sane, so that should be
>>> fine.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
>>> ---
>>>  Makefile.am | 2 +-
>>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/Makefile.am b/Makefile.am
>>> index 3d8128f..430b4a9 100644
>>> --- a/Makefile.am
>>> +++ b/Makefile.am
>>> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
>>>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
>>>  
>>>  fdt.dtb: $(KERNEL_DTB) Makefile
>>> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
>>> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
>>>  
>>>  # The filesystem archive might not exist if INITRD is not being used
>>>  .PHONY: all clean $(FILESYSTEM)
>>>   
>>
>> dtc 1.4.1 complains
> 
> Which distro ships this version? (distrowatch doesn't list dtc)
> 
> tag v1.4.1
> Tagger: David Gibson <david at gibson.dropbear.id.au>
> Date:   Wed Nov 12 14:31:44 2014 +1100
> 
> Any chance it's just you and you can update this? It looks like the
> first version to support it is 1.4.5, as shipped for instance with
> Ubuntu 18.04.

It is shipped as LSF module. I can try to ask for an update, but I thought
that other people may run into it as well...

> 
>> FATAL ERROR: Unrecognized check name "clocks_property"
> 
> Sigh, thanks for the heads up. I don't know if we want to blow up the
> Makefile with a feature test?

I dunno, TBH. It look like warning used to be less evil than error...

Cheers
Vladimir

> 
> Cheers,
> Andre
> 



From miles.chen at mediatek.com  Fri Jan 14 00:36:10 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 14 Jan 2022 16:36:10 +0800
Subject: [PATCH 1/3] clk: mediatek: export mtk_clk_simple_probe
In-Reply-To: <20220114021206.43FB7C36AEA@smtp.kernel.org>
References: <20220114021206.43FB7C36AEA@smtp.kernel.org>
Message-ID: <20220114083611.19633-1-miles.chen@mediatek.com>

> Please send a cover letter for multi-patch series.

Sorry for that, I will submit a cover letter in next version.

Miles


From alim.akhtar at samsung.com  Fri Jan 14 00:38:19 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 14:08:19 +0530
Subject: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <65e6f034-278a-81fa-844d-10a1865a25a4@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122354epcas5p19e5cebe9e85e9ba1758fa0b9d7d1ef75@epcas5p1.samsung.com>
 <20220113121143.22280-11-alim.akhtar@samsung.com>
 <849c7772-0f7e-32ff-6ea6-c46aa6837bb4@canonical.com>
 <076101d80909$d5849060$808db120$@samsung.com>
 <65e6f034-278a-81fa-844d-10a1865a25a4@canonical.com>
Message-ID: <07cf01d80922$16d7f760$4487e620$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Friday, January 14, 2022 1:20 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add compatible for
>Tesla FSD SoC
>
>On 14/01/2022 06:44, Alim Akhtar wrote:
>>
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>>> Sent: Thursday, January 13, 2022 5:57 PM
>>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>>> Cc: soc at kernel.org; linux-clk at vger.kernel.org;
>>> devicetree at vger.kernel.org; olof at lixom.net; linus.walleij at linaro.org;
>>> catalin.marinas at arm.com;
>>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>>> Subject: Re: [PATCH 10/23] dt-bindings: pinctrl: samsung: Add
>>> compatible for Tesla FSD SoC
>>>
>>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>>> Add compatible for Tesla Full Self-Driving SoC. The pinctrl hardware
>>>> IP is similar to what found on most of the exynos series of SoC, so
>>>> this new compatible is added in samsung pinctrl binding.
>>>>
>>>> Cc: linux-fsd at tesla.com
>>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>>> ---
>>>>  Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>>> b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>>> index b8b475967ff9..ba972998a0e4 100644
>>>> --- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>>> +++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>>>> @@ -24,6 +24,7 @@ Required Properties:
>>>>    - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
>>>>    - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
>>>>    - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible
>>>> pin-
>>> controller.
>>>> +  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
>>>>
>>>
>>> Please rebase this on my latest Samsung pinctrl dtschema patches. You
>>> also need a tesla vendor prefix patch (separate).
>>>
>> Sure will rebase when sending v2, your latest patches are in Linux-next or
>still in your tree?
>
>The SPI (v3) and pinctrl (v2) dtschema patches are on mailing lists.
>They seem to be done, so after merge window they will make to linux-next. If
>you want earlier, grab them from mailing list or from
>branches:
>https://protect2.fireeye.com/v1/url?k=78372ba7-27ac12a5-7836a0e8-
>0cc47a31381a-987e4f8740569613&q=1&e=8e15033d-ca15-4f1f-b463-
>adce6ebe65ef&u=https%3A%2F%2Fgithub.com%2Fkrzk%2Flinux%2Ftree%2F
>n%2Fdt-bindings-samsung-spi-schema-v3
>https://protect2.fireeye.com/v1/url?k=32fb0ddf-6d6034dd-32fa8690-
>0cc47a31381a-a7fe8cfb89319cf3&q=1&e=8e15033d-ca15-4f1f-b463-
>adce6ebe65ef&u=https%3A%2F%2Fgithub.com%2Fkrzk%2Flinux%2Ftree%2F
>n%2Fdt-bindings-samsung-pinctrl-schema-v2
>
Thanks Krzysztof, will take them for addressing FSD comments.

>
>Best regards,
>Krzysztof



From miles.chen at mediatek.com  Fri Jan 14 00:35:10 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Fri, 14 Jan 2022 16:35:10 +0800
Subject: [PATCH 3/3] clk: mediatek: support COMMON_CLK_MT8192 module build
In-Reply-To: <20220114021131.1F7C9C36AEA@smtp.kernel.org>
References: <20220114021131.1F7C9C36AEA@smtp.kernel.org>
Message-ID: <20220114083511.18906-1-miles.chen@mediatek.com>

Hi,

>Have you tried removing the modules? And then reloading them? I also see

Thanks for the comment.
I did not try it because we do not unload our clk modules.
After testing I understand that the clock driver does not unregister clks so 
we cannot remove then unload it.

I think I have to add some unregister logic to these drivers.

>that mtk_clk_simple_probe() doesn't actually unregister anything, it
>just frees some allocations. Please fix this before making these
>modules.

You meant that mtk_clk_simple_probe() has no unregister logic in error path?

Miles


From jiayi.zhou at amlogic.com  Fri Jan 14 00:39:29 2022
From: jiayi.zhou at amlogic.com (jiayi.zhou at amlogic.com)
Date: Fri, 14 Jan 2022 16:39:29 +0800
Subject: [PATCH v2] dt-bindings: pwm: Update bindings for the Meson-S4
Message-ID: <20220114083929.2910-1-jiayi.zhou@amlogic.com>

From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>

Update the doc to explicitly support Meson-S4

Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
---
 Documentation/devicetree/bindings/pwm/pwm-meson.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pwm/pwm-meson.txt b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
index bd02b0a1496f..0fbedf20074f 100644
--- a/Documentation/devicetree/bindings/pwm/pwm-meson.txt
+++ b/Documentation/devicetree/bindings/pwm/pwm-meson.txt
@@ -10,6 +10,7 @@ Required properties:
                          or "amlogic,meson-g12a-ee-pwm"
                          or "amlogic,meson-g12a-ao-pwm-ab"
                          or "amlogic,meson-g12a-ao-pwm-cd"
+                         or "amlogic,meson-s4-pwm"
 - #pwm-cells: Should be 3. See pwm.yaml in this directory for a description of
   the cells format.
 
-- 
2.34.1



From philippe.cornu at foss.st.com  Fri Jan 14 00:42:30 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Fri, 14 Jan 2022 09:42:30 +0100
Subject: [PATCH 1/2] MAINTAINERS: Update Benjamin Gaignard maintainer
 status
In-Reply-To: <20220113171921.17466-2-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
 <20220113171921.17466-2-philippe.cornu@foss.st.com>
Message-ID: <8c6eb9c2-4e3a-136b-61b4-f3b91b9903aa@foss.st.com>



On 1/13/22 6:19 PM, Philippe Cornu wrote:
> From: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> 
> Update Benjamin Gaignard address and remove it from no more maintained
> drivers.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
> ---
>   MAINTAINERS | 5 +----
>   1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7a2345ce8521..6bea080d0159 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5702,7 +5702,7 @@ F:	tools/testing/selftests/dma/
>   
>   DMA-BUF HEAPS FRAMEWORK
>   M:	Sumit Semwal <sumit.semwal at linaro.org>
> -R:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
> +R:	Benjamin Gaignard <benjamin.gaignard at collabora.com>
>   R:	Liam Mark <lmark at codeaurora.org>
>   R:	Laura Abbott <labbott at redhat.com>
>   R:	Brian Starkey <Brian.Starkey at arm.com>
> @@ -6423,7 +6423,6 @@ F:	Documentation/devicetree/bindings/display/rockchip/
>   F:	drivers/gpu/drm/rockchip/
>   
>   DRM DRIVERS FOR STI
> -M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
>   L:	dri-devel at lists.freedesktop.org
>   S:	Maintained
>   T:	git git://anongit.freedesktop.org/drm/drm-misc
> @@ -6433,7 +6432,6 @@ F:	drivers/gpu/drm/sti
>   DRM DRIVERS FOR STM
>   M:	Yannick Fertre <yannick.fertre at foss.st.com>
>   M:	Philippe Cornu <philippe.cornu at foss.st.com>
> -M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
>   L:	dri-devel at lists.freedesktop.org
>   S:	Maintained
>   T:	git git://anongit.freedesktop.org/drm/drm-misc
> @@ -18154,7 +18152,6 @@ F:	Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
>   F:	sound/soc/sti/
>   
>   STI CEC DRIVER
> -M:	Benjamin Gaignard <benjamin.gaignard at linaro.org>
>   S:	Maintained
>   F:	Documentation/devicetree/bindings/media/stih-cec.txt
>   F:	drivers/media/cec/platform/sti/
> 

Adding my r-b as already done in the original post from Benjamin (see 
https://lore.kernel.org/lkml/20210706163033.795805-1-benjamin.gaignard at collabora.com/)

Reviewed-by: Philippe Cornu <philippe.cornu at foss.st.com>

Thank you
Philippe :-)


From chanho61.park at samsung.com  Fri Jan 14 00:50:09 2022
From: chanho61.park at samsung.com (Chanho Park)
Date: Fri, 14 Jan 2022 17:50:09 +0900
Subject: [PATCH] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
In-Reply-To: <20220113203754.23197-1-semen.protsenko@linaro.org>
References: <CGME20220113203800epcas2p193b3961d55da5296cf7dd5fffacb87c0@epcas2p1.samsung.com>
 <20220113203754.23197-1-semen.protsenko@linaro.org>
Message-ID: <016301d80923$bc172b50$344581f0$@samsung.com>

> -----Original Message-----
> From: Sam Protsenko <semen.protsenko at linaro.org>
> Sent: Friday, January 14, 2022 5:38 AM
> To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> soc at vger.kernel.org; linux-kernel at vger.kernel.org
> Subject: [PATCH] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
> 
> The proper name is Exynos Auto V9, not V0. It was the typo slipped in
> unnoticed, fix it.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>

Required "Fixes:" tag? Otherwise, LGTM.

Reviewed-by: Chanho Park <chanho61.park at samsung.com>



From philippe.cornu at foss.st.com  Fri Jan 14 00:53:03 2022
From: philippe.cornu at foss.st.com (Philippe CORNU)
Date: Fri, 14 Jan 2022 09:53:03 +0100
Subject: [PATCH 1/2] MAINTAINERS: Update Benjamin Gaignard maintainer
 status
In-Reply-To: <CAK8P3a0Nn3fwEMtb9f0DZhbyY+mLva5XR332XfXqX=WSmB9a8w@mail.gmail.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
 <20220113171921.17466-2-philippe.cornu@foss.st.com>
 <CAK8P3a0Nn3fwEMtb9f0DZhbyY+mLva5XR332XfXqX=WSmB9a8w@mail.gmail.com>
Message-ID: <0733379c-65b7-c9a8-4dc5-c84502426e9f@foss.st.com>



On 1/14/22 1:45 AM, Arnd Bergmann wrote:
> On Thu, Jan 13, 2022 at 6:19 PM Philippe Cornu
> <philippe.cornu at foss.st.com> wrote:
>>
>>   DRM DRIVERS FOR STI
>> -M:     Benjamin Gaignard <benjamin.gaignard at linaro.org>
>>   L:     dri-devel at lists.freedesktop.org
>>   S:     Maintained
>>   T:     git git://anongit.freedesktop.org/drm/drm-misc
> 
> If there is no longer a maintainer, I suppose it should also be marked as
> 
> S: Orphaned
> 
>           Arnd
> 


Hi Arnd,
I sent a serie of 2 patches containing first the original/unmodified 
patch from Benjamin (see [1]) + a new patch to avoid this "orphaned 
driver" situation.

Many thanks
Philippe :-)

[1] 
https://lore.kernel.org/lkml/20210706163033.795805-1-benjamin.gaignard at collabora.com/


From ck.hu at mediatek.com  Fri Jan 14 00:48:35 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 14 Jan 2022 16:48:35 +0800
Subject: [RFC PATCH 2/2] drm/mediatek: add mtk8195 hdmi display driver
In-Reply-To: <20211108000847.14320-3-granquet@baylibre.com>
References: <20211108000847.14320-1-granquet@baylibre.com>
 <20211108000847.14320-3-granquet@baylibre.com>
Message-ID: <b6a98bf399ce1174d717a23c9062dfc6d062650b.camel@mediatek.com>

Hi, Guillaume:

On Mon, 2021-11-08 at 01:08 +0100, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Change-Id: I6399dec26cfe56a338c2ca96989cb7cbd14e292b
> ---
>  drivers/gpu/drm/mediatek/Kconfig              |    9 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  219 +-
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |   24 +-
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c    | 1835
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h    |   26 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c    |  530 +++++
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h    |   20 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h   |  329 +++
>  9 files changed, 2932 insertions(+), 62 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig
> b/drivers/gpu/drm/mediatek/Kconfig
> index 0df75bceb74e..76cc402cbd75 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -31,3 +31,12 @@ config DRM_MEDIATEK_HDMI
>  	help
>  	  DRM/KMS HDMI driver for Mediatek SoCs
>  
> +config DRM_MEDIATEK_HDMI_MT8195_SUSPEND_LOW_POWER
> +	tristate "DRM HDMI SUSPEND LOW POWER Support for Mediatek
> mt8195 SoCs"
> +	depends on DRM_MEDIATEK_HDMI
> +	help
> +	  DRM/KMS HDMI SUSPEND_LOW_POWER for Mediatek SoCs.
> +	  Choose this option if you want to disable/enable
> +	  clock and power domain when platform enter suspend,
> +	  and this config depends on DRM_MEDIATEK_HDMI.
> +
> diff --git a/drivers/gpu/drm/mediatek/Makefile
> b/drivers/gpu/drm/mediatek/Makefile
> index 107b6fbbdbf7..477c0648643c 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -26,6 +26,8 @@ mediatek-drm-hdmi-objs := mtk_cec.o \
>  			  mtk_hdmi.o \
>  			  mtk_hdmi_ddc.o \
>  			  mtk_hdmi_common.o \
> +			  mtk_mt8195_hdmi.o \
> +			  mtk_mt8195_hdmi_ddc.o \
>  
>  obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.o
>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> index 3c38a3e73920..19083be0978a 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c
> @@ -1,5 +1,15 @@
>  #include "mtk_hdmi_common.h"
>  
> +const char *const
> mtk_hdmi_clk_names_mt8195[MTK_MT8195_HDMI_CLK_COUNT] = {
> +	[MTK_MT8195_HDMI_CLK_UNIVPLL_D6D4] = "univpll_d6_d4",
> +	[MTK_MT8195_HDMI_CLK_MSDCPLL_D2] = "msdcpll_d2",
> +	[MTK_MT8195_HDMI_CLK_HDMI_APB_SEL] = "hdmi_apb_sel",
> +	[MTK_MT8195_HDMI_UNIVPLL_D4D8] = "univpll_d4_d8",
> +	[MTK_MT8195_HDIM_HDCP_SEL] = "hdcp_sel",
> +	[MTK_MT8195_HDMI_HDCP_24M_SEL] = "hdcp24_sel",
> +	[MTK_MT8195_HDMI_VPP_SPLIT_HDMI] = "split_hdmi",
> +};
> +
>  const char * const
> mtk_hdmi_clk_names_mt8183[MTK_MT8183_HDMI_CLK_COUNT] = {
>  	[MTK_MT8183_HDMI_CLK_HDMI_PIXEL] = "pixel",
>  	[MTK_MT8183_HDMI_CLK_HDMI_PLL] = "pll",
> @@ -138,6 +148,18 @@ int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi
> *hdmi, u8 *buffer, size_t bufsz
>  		return err;
>  	}
>  
> +	if(hdmi->conf && hdmi->conf->is_mt8195) {
> +		frame.colorimetry = hdmi->colorimtery;
> +		//no need, since we cannot support other extended
> colorimetry?
> +		if (frame.colorimetry == HDMI_COLORIMETRY_EXTENDED)
> +			frame.extended_colorimetry = hdmi-
> >extended_colorimetry;

Separate colorimetry related part to an independent patch and use hdmi-
>conf->colorimetry_support instead of hdmi->conf->is_mt8195.

> +
> +		/* quantiation range:limited or full */
> +		if (frame.colorspace == HDMI_COLORSPACE_RGB)
> +			frame.quantization_range = hdmi-
> >quantization_range;
> +		else
> +			frame.ycc_quantization_range = hdmi-
> >ycc_quantization_range;
> +	}
>  	err = hdmi_avi_infoframe_pack(&frame, buffer, bufsz);
>  
>  	if (err < 0) {
> @@ -155,6 +177,11 @@ void mtk_hdmi_send_infoframe(struct mtk_hdmi
> *hdmi, u8 *buffer_spd, size_t bufsz
>  	mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd,
> "mediatek", "On-chip HDMI");
>  }
>  
> +static struct mtk_hdmi_ddc *hdmi_ddc_ctx_from_mtk_hdmi(struct
> mtk_hdmi *hdmi)
> +{
> +	return container_of(hdmi->ddc_adpt, struct mtk_hdmi_ddc, adap);
> +}
> +
>  int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi,
>  				   struct platform_device *pdev, const
> char *const *clk_names, size_t num_clocks)
>  {
> @@ -173,39 +200,41 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi
> *hdmi,
>  		return ret;
>  	}
>  
> -	/* The CEC module handles HDMI hotplug detection */
> -	cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173-
> cec");
> -	if (!cec_np) {
> -		dev_err(dev, "Failed to find CEC node\n");
> -		return -EINVAL;
> -	}
> +	if (!hdmi->conf || !hdmi->conf->is_mt8195) {
> +		/* The CEC module handles HDMI hotplug detection */

Separate CEC hoplug related part to an independent patch.

> +		cec_np = of_get_compatible_child(np->parent,
> "mediatek,mt8173-cec");
> +		if (!cec_np) {
> +			dev_err(dev, "Failed to find CEC node\n");
> +			return -EINVAL;
> +		}
>  
> -	cec_pdev = of_find_device_by_node(cec_np);
> -	if (!cec_pdev) {
> -		dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
> -				cec_np);
> +		cec_pdev = of_find_device_by_node(cec_np);
> +		if (!cec_pdev) {
> +			dev_err(hdmi->dev, "Waiting for CEC device
> %pOF\n",
> +					cec_np);
> +			of_node_put(cec_np);
> +			return -EPROBE_DEFER;
> +		}
>  		of_node_put(cec_np);
> -		return -EPROBE_DEFER;
> -	}
> -	of_node_put(cec_np);
> -	hdmi->cec_dev = &cec_pdev->dev;
> -	/*
> -	 * The mediatek,syscon-hdmi property contains a phandle link to
> the
> -	 * MMSYS_CONFIG device and the register offset of the
> HDMI_SYS_CFG
> -	 * registers it contains.
> -	 */
> -	regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-
> hdmi");
> -	ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,
> -			&hdmi->sys_offset);
> -	if (IS_ERR(regmap))
> -		ret = PTR_ERR(regmap);
> -	if (ret) {
> -		dev_err(dev,
> -				"Failed to get system configuration
> registers: %d\n",
> -				ret);
> -		goto put_device;
> +		hdmi->cec_dev = &cec_pdev->dev;
> +		/*
> +		 * The mediatek,syscon-hdmi property contains a phandle
> link to the
> +		 * MMSYS_CONFIG device and the register offset of the
> HDMI_SYS_CFG

Separate HDMI_SYS_CFG related part to an independent patch.

> +		 * registers it contains.
> +		 */
> +		regmap = syscon_regmap_lookup_by_phandle(np,
> "mediatek,syscon-hdmi");
> +		ret = of_property_read_u32_index(np, "mediatek,syscon-
> hdmi", 1,
> +				&hdmi->sys_offset);
> +		if (IS_ERR(regmap))
> +			ret = PTR_ERR(regmap);
> +		if (ret) {
> +			dev_err(dev,
> +					"Failed to get system
> configuration registers: %d\n",
> +					ret);
> +			goto put_device;
> +		}
> +		hdmi->sys_regmap = regmap;
>  	}
> -	hdmi->sys_regmap = regmap;
>  
>  	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>  	if (!mem) {
> @@ -219,20 +248,22 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi
> *hdmi,
>  		goto put_device;
>  	}
>  
> -	remote = of_graph_get_remote_node(np, 1, 0);
> -	if (!remote) {
> -		ret = -EINVAL;
> -		goto put_device;
> -	}
> -
> -	if (!of_device_is_compatible(remote, "hdmi-connector")) {
> -		hdmi->next_bridge = of_drm_find_bridge(remote);
> -		if (!hdmi->next_bridge) {
> -			dev_err(dev, "Waiting for external bridge\n");
> -			of_node_put(remote);
> -			ret = -EPROBE_DEFER;
> +	if (!hdmi->conf || !hdmi->conf->is_mt8195) {
> +		remote = of_graph_get_remote_node(np, 1, 0);
> +		if (!remote) {
> +			ret = -EINVAL;
>  			goto put_device;
>  		}
> +
> +		if (!of_device_is_compatible(remote, "hdmi-connector")) 
> {
> +			hdmi->next_bridge = of_drm_find_bridge(remote);
> +			if (!hdmi->next_bridge) {
> +				dev_err(dev, "Waiting for external
> bridge\n");
> +				of_node_put(remote);
> +				ret = -EPROBE_DEFER;
> +				goto put_device;
> +			}
> +		}
>  	}
>  
>  	i2c_np = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);
> @@ -251,9 +282,16 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi
> *hdmi,
>  		goto put_device;
>  	}
>  
> +	//TODO: rework this... this is ugly
> +	if (hdmi->conf && hdmi->conf->is_mt8195) {
> +		ddc = hdmi_ddc_ctx_from_mtk_hdmi(hdmi);
> +		ddc->regs = hdmi->regs;
> +	}

Separate ddc related part to an independent patch.

> +
>  	return 0;
>  put_device:
> -	put_device(hdmi->cec_dev);
> +	if (!hdmi->conf || !hdmi->conf->is_mt8195)
> +		put_device(hdmi->cec_dev);
>  	return ret;
>  }
>  
> @@ -265,7 +303,10 @@ static int mtk_hdmi_register_audio_driver(struct
> device *dev)
>  		.data = hdmi,
>  	};
>  
> -	set_hdmi_codec_pdata_mt8183(&codec_data);
> +	if(hdmi->conf && hdmi->conf->is_mt8195)
> +		set_hdmi_codec_pdata_mt8195(&codec_data);
> +	else
> +		set_hdmi_codec_pdata_mt8183(&codec_data);

set_hdmi_codec_pdata_mt8195() and set_hdmi_codec_pdata_mt8183() has the
same statement:

	codec_data->ops = &mtk_hdmi_audio_codec_ops;
	codec_data->max_i2s_channels = 2;
	codec_data->i2s = 1;

I think you could move these three lines out of that function, and set
ops as

	codec_data->ops = hdmi->conf->audio_codec_ops;

>  
>  	pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
>  					     PLATFORM_DEVID_AUTO,
> &codec_data,
> @@ -297,15 +338,23 @@ int mtk_drm_hdmi_probe(struct platform_device
> *pdev)
>  		return ret;
>  	}
>  
> -	ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev,
> mtk_hdmi_clk_names_mt8183, ARRAY_SIZE(mtk_hdmi_clk_names_mt8183));
> +	if(hdmi->conf && hdmi->conf->is_mt8195)
> +		ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev,
> mtk_hdmi_clk_names_mt8195, ARRAY_SIZE(mtk_hdmi_clk_names_mt8195));
> +	else
> +		ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev,
> mtk_hdmi_clk_names_mt8183, ARRAY_SIZE(mtk_hdmi_clk_names_mt8183));
>  
>  	if (ret)
>  		return ret;
>  
>  	platform_set_drvdata(pdev, hdmi);
>  
> -	mtk_hdmi_output_init_mt8183(hdmi);
> -	hdmi->bridge.funcs = &mtk_mt8183_hdmi_bridge_funcs;
> +	if (hdmi->conf && hdmi->conf->is_mt8195) {
> +		mtk_hdmi_output_init_mt8195(hdmi);
> +		hdmi->bridge.funcs = &mtk_mt8195_hdmi_bridge_funcs;
> +	} else {
> +		mtk_hdmi_output_init_mt8183(hdmi);
> +		hdmi->bridge.funcs = &mtk_mt8183_hdmi_bridge_funcs;
> +	}

mtk_hdmi_output_init_mt8195() and mtk_hdmi_output_init_mt8183() has
common code, try to merge the common part.

I review partially here. And I would keep on reviewing the rest.

Regards,
CK

>  
>  	hdmi->bridge.of_node = pdev->dev.of_node;
>  	drm_bridge_add(&hdmi->bridge);
> @@ -324,7 +373,10 @@ int mtk_drm_hdmi_remove(struct platform_device
> *pdev)
>  
>  	drm_bridge_remove(&hdmi->bridge);
>  
> -	mtk_hdmi_clk_disable_mt8183(hdmi);
> +	if(hdmi->conf && hdmi->conf->is_mt8195)
> +		mtk_hdmi_clk_disable_mt8195(hdmi);
> +	else
> +		mtk_hdmi_clk_disable_mt8183(hdmi);
>  	i2c_put_adapter(hdmi->ddc_adpt);
>  
>  	return 0;
> @@ -339,6 +391,13 @@ static const struct mtk_hdmi_conf
> mtk_hdmi_conf_mt8167 = {
>  	.cea_modes_only = true,
>  };
>  
> 



From Jiayi.Zhou at amlogic.com  Fri Jan 14 01:07:53 2022
From: Jiayi.Zhou at amlogic.com (Jiayi.Zhou at amlogic.com)
Date: Fri, 14 Jan 2022 17:07:53 +0800
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
Message-ID: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>

From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>

For PWM controller in the Meson-S4 SoC,
PWM needs to obtain an external clock source.
This patch tries to describe them in the DT compatible data.

Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
---
 drivers/pwm/pwm-meson.c | 145 ++++++++++++++++++++++++++++++----------
 1 file changed, 110 insertions(+), 35 deletions(-)

diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
index 3cf3bcf5ddfc..54db56c95be2 100644
--- a/drivers/pwm/pwm-meson.c
+++ b/drivers/pwm/pwm-meson.c
@@ -51,6 +51,7 @@
 #define REG_MISC_AB		0x8
 #define MISC_B_CLK_EN		BIT(23)
 #define MISC_A_CLK_EN		BIT(15)
+
 #define MISC_CLK_DIV_MASK	0x7f
 #define MISC_B_CLK_DIV_SHIFT	16
 #define MISC_A_CLK_DIV_SHIFT	8
@@ -93,11 +94,13 @@ struct meson_pwm_channel {
 	struct clk *clk_parent;
 	struct clk_mux mux;
 	struct clk *clk;
+	struct clk *clk_mux;
 };
 
 struct meson_pwm_data {
 	const char * const *parent_names;
 	unsigned int num_parents;
+	unsigned int extern_clk;
 };
 
 struct meson_pwm {
@@ -105,6 +108,7 @@ struct meson_pwm {
 	const struct meson_pwm_data *data;
 	struct meson_pwm_channel channels[MESON_NUM_PWMS];
 	void __iomem *base;
+
 	/*
 	 * Protects register (write) access to the REG_MISC_AB register
 	 * that is shared between the two PWMs.
@@ -130,13 +134,15 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
 
 	channel = &meson->channels[pwm->hwpwm];
 
-	if (channel->clk_parent) {
-		err = clk_set_parent(channel->clk, channel->clk_parent);
-		if (err < 0) {
-			dev_err(dev, "failed to set parent %s for %s: %d\n",
-				__clk_get_name(channel->clk_parent),
-				__clk_get_name(channel->clk), err);
-			return err;
+	if (!meson->data->extern_clk) {
+		if (channel->clk_parent) {
+			err = clk_set_parent(channel->clk, channel->clk_parent);
+			if (err < 0) {
+				dev_err(dev, "failed to set parent %s for %s: %d\n",
+					__clk_get_name(channel->clk_parent),
+					__clk_get_name(channel->clk), err);
+					return err;
+			}
 		}
 	}
 
@@ -171,7 +177,11 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
 	if (state->polarity == PWM_POLARITY_INVERSED)
 		duty = period - duty;
 
-	fin_freq = clk_get_rate(channel->clk);
+	if (meson->data->extern_clk) {
+		fin_freq = clk_get_rate(channel->clk_mux);
+	} else {
+		fin_freq = clk_get_rate(channel->clk);
+	}
 	if (fin_freq == 0) {
 		dev_err(meson->chip.dev, "invalid source clock frequency\n");
 		return -EINVAL;
@@ -228,17 +238,32 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	struct meson_pwm_channel_data *channel_data;
 	unsigned long flags;
 	u32 value;
+	unsigned long set_clk;
+	u32 err;
 
 	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
 
-	spin_lock_irqsave(&meson->lock, flags);
-
 	value = readl(meson->base + REG_MISC_AB);
-	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
-	value |= channel->pre_div << channel_data->clk_div_shift;
-	value |= channel_data->clk_en_mask;
-	writel(value, meson->base + REG_MISC_AB);
+	if (meson->data->extern_clk) {
+		set_clk = clk_get_rate(channel->clk_mux);
+
+		if (set_clk == 0)
+			dev_err(meson->chip.dev, "invalid source clock frequency\n");
+		set_clk /= channel->pre_div + 1;
+		err = clk_set_rate(channel->clk, set_clk);
+		if (err)
+			dev_err(meson->chip.dev, "%s: error in setting pwm rate!\n", __func__);
+	} else {
+		spin_lock_irqsave(&meson->lock, flags);
+
+		value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
+		value |= channel->pre_div << channel_data->clk_div_shift;
+		value |= channel_data->clk_en_mask;
+		writel(value, meson->base + REG_MISC_AB);
 
+		spin_unlock_irqrestore(&meson->lock, flags);
+	}
+	spin_lock_irqsave(&meson->lock, flags);
 	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
 		FIELD_PREP(PWM_LOW_MASK, channel->lo);
 	writel(value, meson->base + channel_data->reg_offset);
@@ -246,7 +271,6 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
 	value = readl(meson->base + REG_MISC_AB);
 	value |= channel_data->pwm_en_mask;
 	writel(value, meson->base + REG_MISC_AB);
-
 	spin_unlock_irqrestore(&meson->lock, flags);
 }
 
@@ -333,7 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 	struct meson_pwm *meson = to_meson_pwm(chip);
 	struct meson_pwm_channel_data *channel_data;
 	struct meson_pwm_channel *channel;
-	u32 value, tmp;
+	u32 value_pwm, value, tmp;
+	unsigned long gate_clk, fre;
 
 	if (!state)
 		return;
@@ -341,30 +366,42 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
 	channel = &meson->channels[pwm->hwpwm];
 	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
 
-	value = readl(meson->base + REG_MISC_AB);
-
-	tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
-	state->enabled = (value & tmp) == tmp;
-
-	tmp = value >> channel_data->clk_div_shift;
-	channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
-
+	value_pwm = readl(meson->base + REG_MISC_AB);
 	value = readl(meson->base + channel_data->reg_offset);
 
 	channel->lo = FIELD_GET(PWM_LOW_MASK, value);
 	channel->hi = FIELD_GET(PWM_HIGH_MASK, value);
 
-	if (channel->lo == 0) {
-		state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
-		state->duty_cycle = state->period;
-	} else if (channel->lo >= channel->hi) {
-		state->period = meson_pwm_cnt_to_ns(chip, pwm,
-						    channel->lo + channel->hi);
-		state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm,
-							channel->hi);
+	if (meson->data->extern_clk) {
+		gate_clk = clk_get_rate(channel->clk);
+		fre = gate_clk / (channel->lo + channel->hi);
+		state->period = div_u64(NSEC_PER_SEC, fre);
+		state->duty_cycle = div_u64(state->period * channel->hi, channel->lo + channel->hi);
+		tmp = channel_data->pwm_en_mask;
+
+		if (((value_pwm & tmp) == tmp) && __clk_is_enabled(channel->clk))
+			state->enabled = true;
+		else
+			state->enabled = false;
 	} else {
-		state->period = 0;
-		state->duty_cycle = 0;
+		tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
+
+		state->enabled = (value_pwm & tmp) == tmp;
+
+		tmp = value_pwm >> channel_data->clk_div_shift;
+		channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
+
+		if (channel->lo == 0) {
+			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
+			state->duty_cycle = state->period;
+		} else if (channel->lo >= channel->hi) {
+			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo
+							    + channel->hi);
+			state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
+		} else {
+			state->period = 0;
+			state->duty_cycle = 0;
+		}
 	}
 }
 
@@ -452,6 +489,10 @@ static const struct meson_pwm_data pwm_g12a_ee_data = {
 	.num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
 };
 
+static const struct meson_pwm_data pwm_meson_data = {
+	.extern_clk = true,
+};
+
 static const struct of_device_id meson_pwm_matches[] = {
 	{
 		.compatible = "amlogic,meson8b-pwm",
@@ -485,6 +526,10 @@ static const struct of_device_id meson_pwm_matches[] = {
 		.compatible = "amlogic,meson-g12a-ao-pwm-cd",
 		.data = &pwm_g12a_ao_cd_data
 	},
+	{
+		.compatible = "amlogic,meson-s4-pwm",
+		.data = &pwm_meson_data
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, meson_pwm_matches);
@@ -534,6 +579,33 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
 	return 0;
 }
 
+static int meson_pwm_extern_init_channels(struct meson_pwm *meson)
+{
+	struct meson_pwm_channel *channels = meson->channels;
+	struct device *dev = meson->chip.dev;
+	unsigned int i;
+	char name[255];
+
+	for (i = 0; i < meson->chip.npwm; i++) {
+		snprintf(name, sizeof(name), "clkin%u", i);
+		(channels + i)->clk = devm_clk_get(dev, name);
+		if (IS_ERR((channels + i)->clk)) {
+			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk),
+				      "can't get device clock\n");
+			return PTR_ERR((channels + i)->clk);
+		}
+		snprintf(name, sizeof(name), "mux%u", i);
+		(channels + i)->clk_mux = devm_clk_get(dev, name);
+		if (IS_ERR((channels + i)->clk_mux)) {
+			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk_mux),
+				      "can't get device clock\n");
+			return PTR_ERR((channels + i)->clk_mux);
+		}
+	}
+
+	return 0;
+}
+
 static int meson_pwm_probe(struct platform_device *pdev)
 {
 	struct meson_pwm *meson;
@@ -553,8 +625,11 @@ static int meson_pwm_probe(struct platform_device *pdev)
 	meson->chip.npwm = MESON_NUM_PWMS;
 
 	meson->data = of_device_get_match_data(&pdev->dev);
+	if (meson->data->extern_clk)
+		err = meson_pwm_extern_init_channels(meson);
+	else
+		err = meson_pwm_init_channels(meson);
 
-	err = meson_pwm_init_channels(meson);
 	if (err < 0)
 		return err;
 
-- 
2.34.1



From maxime at cerno.tech  Fri Jan 14 01:20:07 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:20:07 +0100
Subject: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20 support
In-Reply-To: <tencent_361798B1357958BC1B1694977A6C9935CD0A@qq.com>
References: <YdS1GVkRopRSoD5S@robh.at.kernel.org>
 <tencent_13C536D91764B05D794CBCF3156C963E6C0A@qq.com>
 <20220111103542.f7ilg2ugqklpztr5@houat>
 <tencent_361798B1357958BC1B1694977A6C9935CD0A@qq.com>
Message-ID: <20220114092007.7nf5m5cunbifmo5d@houat>

Hi,

On Wed, Jan 12, 2022 at 10:37:55AM +0800, Conley Lee wrote:
> On 01/11/22 at 11:35??, Maxime Ripard wrote:
> > Date: Tue, 11 Jan 2022 11:35:42 +0100
> > From: Maxime Ripard <maxime at cerno.tech>
> > To: conleylee at foxmail.com
> > Cc: robh at kernel.org, wens at csie.org, devicetree at vger.kernel.org,
> >  linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> > Subject: Re: [PATCH v2 1/2] sun7i-a20-marsboard.dts: add marsboard-a20
> >  support
> > 
> > Hi,
> > 
> > On Wed, Jan 05, 2022 at 10:45:50AM +0800, conleylee at foxmail.com wrote:
> > > From: conley <conleylee at foxmail.com>
> > 
> > This should be your full name in the author and signed-off-by
> > 
> > > ARM dts: sun7i: Add Marsboard A20 board
> > > 
> > > This patch add support for Marsboard A20 board.
> > > 
> > > The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
> > > card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
> > > USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.
> > > 
> > > Change since v1.
> > >   - Spearate biddings and dts as two patches.
> > >   - use SPDX tag
> > 
> > And the changelog should be after the --- below
> > 
> > > Signed-off-by: conley <conleylee at foxmail.com>
> > > ---
> > >  arch/arm/boot/dts/Makefile                |   1 +
> > >  arch/arm/boot/dts/sun7i-a20-marsboard.dts | 183 ++++++++++++++++++++++
> > >  2 files changed, 184 insertions(+)
> > >  create mode 100644 arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > > 
> > > diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> > > index 0de64f237cd8..4628a2617313 100644
> > > --- a/arch/arm/boot/dts/Makefile
> > > +++ b/arch/arm/boot/dts/Makefile
> > > @@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
> > >  	sun7i-a20-icnova-swac.dtb \
> > >  	sun7i-a20-lamobo-r1.dtb \
> > >  	sun7i-a20-linutronix-testbox-v2.dtb \
> > > +	sun7i-a20-marsboard.dtb \
> > >  	sun7i-a20-m3.dtb \
> > >  	sun7i-a20-mk808c.dtb \
> > >  	sun7i-a20-olimex-som-evb.dtb \
> > > diff --git a/arch/arm/boot/dts/sun7i-a20-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > > new file mode 100644
> > > index 000000000000..7ab6aa30fee6
> > > --- /dev/null
> > > +++ b/arch/arm/boot/dts/sun7i-a20-marsboard.dts
> > > @@ -0,0 +1,183 @@
> > > +// SPDX-License-Identifier: LGPL-2.1+
> > 
> > The license for DT files is usually a dual-license with GPL and MIT,
> > which would be:
> > 
> > SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > 
> > You can't link to a DT, so GPL and LGPL should be equivalent here, and
> > MIT is useful for other projects (like the *BSD) that reuse the DT.
> > 
> > > +/*
> > > + * Copyright 2021 Conley Lee
> > > + * Conley Lee <conleylee at foxmail.com>
> > > + */
> > > +
> > > +/dts-v1/;
> > > +#include "sun7i-a20.dtsi"
> > > +#include "sunxi-common-regulators.dtsi"
> > > +
> > > +#include <dt-bindings/gpio/gpio.h>
> > > +#include <dt-bindings/interrupt-controller/irq.h>
> > > +
> > > +/ {
> > > +	model = "HAOYU Electronics Marsboard A20";
> > > +	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
> > 
> > Is there multiple boards called marsboard?
> > 
> > If not, then the compatible should be haoyu,marsboard.
> > 
> > The file name should be sun7i-a20-haoyu-marsboard too.
> > 
> > > +	aliases {
> > > +		serial0 = &uart0;
> > > +	};
> > > +
> > > +	chosen {
> > > +		stdout-path = "serial0:115200n8";
> > > +	};
> > > +
> > > +	hdmi-connector {
> > > +		compatible = "hdmi-connector";
> > > +		type = "a";
> > > +
> > > +		port {
> > > +			hdmi_con_in: endpoint {
> > > +				remote-endpoint = <&hdmi_out_con>;
> > > +			};
> > > +		};
> > > +	};
> > > +};
> > > +
> > > +&ahci {
> > > +	target-supply = <&reg_ahci_5v>;
> > > +	status = "okay";
> > > +};
> > > +
> > > +&codec {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&cpu0 {
> > > +	cpu-supply = <&reg_dcdc2>;
> > > +};
> > > +
> > > +&de {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&ehci0 {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&ehci1 {
> > > +	status = "okay";
> > > +};
> > > +
> > > +&gmac_mii_pins {
> > > +	pins = "PA0", "PA1", "PA2",
> > > +	"PA3", "PA4", "PA5", "PA6",
> > > +	"PA7", "PA8", "PA9", "PA10",
> > > +	"PA11", "PA12", "PA13", "PA14",
> > > +	"PA15", "PA16", "PA17";
> > > +};
> > 
> > Why do you need that node?
>
> 1. There are two boards called marsboard, another one is based on
>    sun4i-a10.

Ok

> 2. About the gmac_mii_pins node: the pin PA17 is connected to PHY
>    as EXTERR signal on sun7i-a20-marsboard, it's different from 
>    the definetion in dtsi.

The A20-Olinuxino-Micro has the same thing then, please do it like they did.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/c01f900b/attachment-0001.sig>

From maxime at cerno.tech  Fri Jan 14 01:21:39 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:21:39 +0100
Subject: [PATCH v3 1/2] sun7i-a20-haoyu-marsboard.dts: add marsboard-a20
 support
In-Reply-To: <tencent_00147CCBB6C9A0A0830DCE43F25DBC40A505@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220112031347.2492813-1-conleylee@foxmail.com>
 <tencent_00147CCBB6C9A0A0830DCE43F25DBC40A505@qq.com>
Message-ID: <20220114092139.eecdrmonsrvjuitb@houat>

On Wed, Jan 12, 2022 at 11:13:46AM +0800, Conley Lee wrote:
> Add sun7i-a20-haoyu-marsboard.dts to support haoyu marsboard a20 SBC

A description of the board would be nice

> Signed-off-by: Conley Lee <conleylee at foxmail.com>
> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  .../boot/dts/sun7i-a20-haoyu-marsboard.dts    | 183 ++++++++++++++++++
>  2 files changed, 184 insertions(+)
>  create mode 100644 arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..5f1602d62927 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -1219,6 +1219,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
>  	sun7i-a20-icnova-swac.dtb \
>  	sun7i-a20-lamobo-r1.dtb \
>  	sun7i-a20-linutronix-testbox-v2.dtb \
> +	sun7i-a20-haoyu-marsboard.dtb \

This should be ordered alphabetically

>  	sun7i-a20-m3.dtb \
>  	sun7i-a20-mk808c.dtb \
>  	sun7i-a20-olimex-som-evb.dtb \
> diff --git a/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
> new file mode 100644
> index 000000000000..4c6c6ae0c459
> --- /dev/null
> +++ b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2021 Conley Lee
> + * Conley Lee <conleylee at foxmail.com>
> + */
> +
> +/dts-v1/;
> +#include "sun7i-a20.dtsi"
> +#include "sunxi-common-regulators.dtsi"
> +
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
> +/ {
> +	model = "HAOYU Electronics Marsboard A20";
> +	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
> +
> +	aliases {
> +		serial0 = &uart0;
> +	};
> +
> +	chosen {
> +		stdout-path = "serial0:115200n8";
> +	};
> +
> +	hdmi-connector {
> +		compatible = "hdmi-connector";
> +		type = "a";
> +
> +		port {
> +			hdmi_con_in: endpoint {
> +				remote-endpoint = <&hdmi_out_con>;
> +			};
> +		};
> +	};
> +};
> +
> +&ahci {
> +	target-supply = <&reg_ahci_5v>;
> +	status = "okay";
> +};
> +
> +&codec {
> +	status = "okay";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&reg_dcdc2>;
> +};
> +
> +&de {
> +	status = "okay";
> +};
> +
> +&ehci0 {
> +	status = "okay";
> +};
> +
> +&ehci1 {
> +	status = "okay";
> +};
> +
> +&gmac_mii_pins {
> +	pins = "PA0", "PA1", "PA2",
> +	"PA3", "PA4", "PA5", "PA6",
> +	"PA7", "PA8", "PA9", "PA10",
> +	"PA11", "PA12", "PA13", "PA14",
> +	"PA15", "PA16", "PA17";
> +};

See my comment on v3

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/231ba2dc/attachment.sig>

From maxime at cerno.tech  Fri Jan 14 01:22:16 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:22:16 +0100
Subject: [PATCH v3 1/2] sun7i-a20-haoyu-marsboard.dts: add marsboard-a20
 support
In-Reply-To: <tencent_00147CCBB6C9A0A0830DCE43F25DBC40A505@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220112031347.2492813-1-conleylee@foxmail.com>
 <tencent_00147CCBB6C9A0A0830DCE43F25DBC40A505@qq.com>
Message-ID: <20220114092216.xfuaplbrlpsr4zao@houat>

On Wed, Jan 12, 2022 at 11:13:46AM +0800, Conley Lee wrote:
> Add sun7i-a20-haoyu-marsboard.dts to support haoyu marsboard a20 SBC
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>

Also, the commit title prefix must be ARM: dts: sun7i: Add A20-Marsboard

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/b2de0f30/attachment.sig>

From maxime at cerno.tech  Fri Jan 14 01:22:47 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:22:47 +0100
Subject: [PATCH v3 2/2] sunxi.yaml: add HAOYU Electronics Marsboard A20
In-Reply-To: <tencent_A92DC943F79DB360AE14672BB749BFE08A05@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220112031347.2492813-1-conleylee@foxmail.com>
 <tencent_A92DC943F79DB360AE14672BB749BFE08A05@qq.com>
Message-ID: <20220114092247.rp6ym4jvsdqdrkib@houat>

On Wed, Jan 12, 2022 at 11:13:47AM +0800, Conley Lee wrote:
> add haoyu,a20-marsboard bindings
> 
> Signed-off-by: Conley Lee <conleylee at foxmail.com>

The prefix should be dt-bindings: arm: sunxi

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/82fa2fe5/attachment.sig>

From rex-bc.chen at mediatek.com  Fri Jan 14 01:21:09 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 14 Jan 2022 17:21:09 +0800
Subject: [v9,2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
Message-ID: <20220114092110.12137-3-rex-bc.chen@mediatek.com>

Some DSI RX devices require the packets on all lanes aligned at the end.
Otherwise, there will be some issues of shift or scroll for screen.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..ccdda15f5a66 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -195,6 +195,8 @@ struct mtk_dsi {
 	struct clk *hs_clk;
 
 	u32 data_rate;
+	/* force dsi line end without dsi_null data */
+	bool hs_packet_end_aligned;
 
 	unsigned long mode_flags;
 	enum mipi_dsi_pixel_format format;
@@ -500,6 +502,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
 	}
 
+	if (dsi->hs_packet_end_aligned) {
+		horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
+		horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
+	}
+
 	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
@@ -794,6 +803,9 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
+	dsi->hs_packet_end_aligned = (dsi->mode_flags &
+				      MIPI_DSI_HS_PKT_END_ALIGNED)
+				     ? true : false;
 
 	return 0;
 }
-- 
2.18.0



From rex-bc.chen at mediatek.com  Fri Jan 14 01:21:08 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 14 Jan 2022 17:21:08 +0800
Subject: [v9,1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
Message-ID: <20220114092110.12137-2-rex-bc.chen@mediatek.com>

Since a HS transmission is composed of an arbitrary number
of bytes that may not be an integer multiple of lanes, some
lanes may run out of data before others.
(Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)

However, for some DSI RX devices (for example, anx7625),
there is a limitation that packet number should be the same
on all DSI lanes. In other words, they need to end a HS at
the same time.

Because this limitation is for some specific DSI RX devices,
it is more reasonable to put the enable control in these
DSI RX drivers. If DSI TX driver knows the information,
they can adjust the setting for this situation.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
---
 include/drm/drm_mipi_dsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 147e51b6d241..342dfe5a0874 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -137,6 +137,8 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
 /* transmit data in low power */
 #define MIPI_DSI_MODE_LPM		BIT(11)
+/* transmit data ending in the same hsync for all lanes */
+#define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
 
 enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB888,
-- 
2.18.0



From rex-bc.chen at mediatek.com  Fri Jan 14 01:21:07 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 14 Jan 2022 17:21:07 +0800
Subject: [v9,
 0/3] force hsa hbp hfp packets multiple of lanenum to avoid screen
 shift
Message-ID: <20220114092110.12137-1-rex-bc.chen@mediatek.com>

Changes since v8:
 - Use mode_flags to control this limitation instead of "hs_packet_end_aligned".
 - Add new bit definition "MIPI_DSI_HS_PKT_END_ALIGNED" for mode_flags.

Changes since v7:
 - Rebase to kernel 5.16
 - Add tags of reviewed-by and acked-by.
 - Add detailed commit message for flag "hs_packet_end_aligned" in DSI common driver.

Changes since v6:
 - Add "bool hs_packet_end_aligned" in "struct mipi_dsi_device" to control the dsi aligned.
 - Config the "hs_packet_end_aligned" in ANX7725 .attach().

Changes since v5:
 - Search the anx7625 compatible as flag to control dsi output aligned.

Changes since v4:
 - Move "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null" before
   "drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid".
 - Retitle "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null".

Rex-BC Chen (3):
  drm/dsi: transfer DSI HS packets ending at the same time
  drm/mediatek: implement the DSI hs packets aligned
  drm/bridge: anx7625: config hs packets end aligned to avoid screen shift

 drivers/gpu/drm/bridge/analogix/anx7625.c |  3 ++-
 drivers/gpu/drm/mediatek/mtk_dsi.c        | 12 ++++++++++++
 include/drm/drm_mipi_dsi.h                |  2 ++
 3 files changed, 16 insertions(+), 1 deletion(-)

-- 
2.18.0



From rex-bc.chen at mediatek.com  Fri Jan 14 01:21:10 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 14 Jan 2022 17:21:10 +0800
Subject: [v9, 3/3] drm/bridge: anx7625: config hs packets end aligned to avoid
 screen shift
In-Reply-To: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
Message-ID: <20220114092110.12137-4-rex-bc.chen@mediatek.com>

This device requires the packets on lanes aligned at the end to fix
screen shift or scroll.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 2346dbcc505f..fe32ab0878ae 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1673,7 +1673,8 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
 	dsi->format = MIPI_DSI_FMT_RGB888;
 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
 		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
-		MIPI_DSI_MODE_VIDEO_HSE;
+		MIPI_DSI_MODE_VIDEO_HSE	|
+		MIPI_DSI_HS_PKT_END_ALIGNED;
 
 	ret = devm_mipi_dsi_attach(dev, dsi);
 	if (ret) {
-- 
2.18.0



From maxime at cerno.tech  Fri Jan 14 01:24:13 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:24:13 +0100
Subject: [PATCH v2 1/1] phy: sun4i-usb: fix phy write on H3 and newer
In-Reply-To: <1e13f894-6900-15a8-66ea-f5e4d65bf822@wirenboard.com>
References: <20220111165153.63632-1-boger@wirenboard.com>
 <20220111165153.63632-2-boger@wirenboard.com>
 <20220112084223.j5nm4ennfv7f6ekt@houat>
 <1e13f894-6900-15a8-66ea-f5e4d65bf822@wirenboard.com>
Message-ID: <20220114092413.exs7miua5n42kpbp@houat>

Hi,

On Wed, Jan 12, 2022 at 11:59:31AM +0300, Evgeny Boger wrote:
> Hi Maxime!
> 12.01.2022 11:42, Maxime Ripard ?????:
> > Hi,
> > 
> > On Tue, Jan 11, 2022 at 07:51:53PM +0300, Evgeny Boger wrote:
> > > We noticed that USB hosts won't reliably enumerate USB HS (480Mb/s) devices
> > > in our custom A40i-based design. What we observe is that after several
> > > attempts USB device would fail to enumerate on EHCI port (HS) and will be
> > > enumerated instead on OHCI (FS, 12Mb/s) only:
> > > 
> > > [    6.368009] usb 1-1: new high-speed USB device number 5 using ehci-platform
> > > [    6.818008] usb 1-1: device not accepting address 5, error -71
> > > [    6.823868] usb usb1-port1: unable to enumerate USB device
> > > [    7.308013] usb 3-1: new full-speed USB device number 2 using ohci-platform
> > > [    7.575045] usb 3-1: not running at top speed; connect to a high speed hub
> > > 
> > > On some boards one of the ports would work in high-speed mode, but
> > > on most of the boards all three USB ports would only work in FS mode.
> > > 
> > > At the same time, USB work flawlessly in high-speed mode in vendor kernel.
> > > 
> > > Looking for the differences in USB code, we found the issue with USB PHY
> > > register initialization. Basically, USB PHY driver sets a couple of
> > > internal undocumented PHY registers to the predefined constants. These PHY
> > > registers are accessed in a very (and I mean VERY) weird way by shifting
> > > register addresses and values bit-by-bit. This access method was slightly
> > > changed starting from H3 SoC, according to the BSP source for different
> > > SoCs.
> > > 
> > > As a result, mainline PHY driver won't set these PHY registers properly
> > > resulting in unreliable enumeration in high-speed mode.
> > > 
> > > We don't know whether this issue will result in broken HS mode on all
> > > affected SoCs or instead the A40i is an unfortunate exception. What we
> > > indeed verified, is that BSPs for all affected SoCs write these registers
> > > properly while mainline kernel don't. We also were able to reproduce the
> > > USB issue on a couple of A40i boards from other vendors, so we are pretty
> > > sure these registers have to always be properly set, regardlress of
> > > a hardware layout.
> > > 
> > > The proposed patch is tested on A40i-based Wiren Board 7 building
> > > automation controller. More details are below.
> > > 
> > > On older SoCs (prior to H3) PHY register are accessed by manipulating
> > > the common register for all PHYs. PHY index is specified by pulsing
> > > usbc bit.
> > > 
> > > Newer SoCs leave the access procedure mostly unchanged, the
> > > difference being that the latch registers are separate for each PHY.
> > > 
> > > Additionally, accessing USB PHY registers is only possible if phy0 is
> > > routed to musb IP instead of HCI.
> > > 
> > > Introduce phy_reg_access_v2 cfg flag for H3 (H2+, H5),
> > > R40 (V40, A40i, T3), V3s (V3, S3) and A64 SoCs.
> > > 
> > > On A83t, H6, H616, T507 and probably on more recent hardware,
> > > these PHY registers are not used in vendor BSP.
> > > So don't set v2 flag for these even newer SoCs as a precaution.
> > > 
> > > Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> > This should probably be sent to stable, and have a Fixes tag?
> 
> well, phy register writes never worked on H3 SoC and newer, so there is no
> specific commit which broke it. So nothing to put to Fixes: tag.

If anything, it should be the patch that introduces the H3 support?

> I'm not sure it qualifies for stable too. Citing guidelines:
> 
> >It must be obviously correct and tested
> 
> I was only able to test it on handful of A40i boards and on one A20 board
> 
> >It must fix a real bug that bothers people
> 
> this bug for certain bothers *us*, but our users won't benefit from porting
> this fix to stable.
> I didn't find reports on this bug from other people.
> I think unfortunately not many people are using mainline kernel on these
> SoCs.

Yeah, it makes sense then, thanks!
Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/c57482d5/attachment.sig>

From maxime at cerno.tech  Fri Jan 14 01:25:10 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:25:10 +0100
Subject: (subset) [PATCH] ARM: dts: sunxi: h3/h5: add r_uart node
In-Reply-To: <20220112173327.26317-1-mans@mansr.com>
References: <20220112173327.26317-1-mans@mansr.com>
Message-ID: <164215230543.14932.4092617393834141243.b4-ty@cerno.tech>

On Wed, 12 Jan 2022 17:33:27 +0000, Mans Rullgard wrote:
> There is an additional UART in the PL I/O block.
> Add a node and pinmux for it.
> 
> 

Applied to local tree (sunxi/dt-for-5.18).

Thanks!
Maxime


From jiasheng at iscas.ac.cn  Fri Jan 14 01:30:15 2022
From: jiasheng at iscas.ac.cn (Jiasheng Jiang)
Date: Fri, 14 Jan 2022 17:30:15 +0800
Subject: [PATCH] drm/rockchip: Check for NULL pointer after calling kzalloc
Message-ID: <20220114093015.1295274-1-jiasheng@iscas.ac.cn>

As the possible failure of the kzalloc(), crtc_state could be NULL
pointer.
Therefore, it should be better to check it in order to avoid the
dereference of the NULL pointer, like the kzalloc() in
vop_crtc_duplicate_state().
If fails, we can directly use the 'NULL' instead of the
'&crtc_state->base' and __drm_atomic_helper_crtc_duplicate_state() will
deal with it correctly.

Fixes: dc0b408f5a87 ("drm/rockchip: allocate correct crtc state structure on reset")
Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3e8d9e2d1b67..db672ff5e37b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1577,7 +1577,10 @@ static void vop_crtc_reset(struct drm_crtc *crtc)
 	if (crtc->state)
 		vop_crtc_destroy_state(crtc, crtc->state);
 
-	__drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
+	if (!crtc_state)
+		__drm_atomic_helper_crtc_reset(crtc, NULL);
+	else
+		__drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
 }
 
 #ifdef CONFIG_DRM_ANALOGIX_DP
-- 
2.25.1



From german.gomez at arm.com  Fri Jan 14 01:31:58 2022
From: german.gomez at arm.com (German Gomez)
Date: Fri, 14 Jan 2022 09:31:58 +0000
Subject: [PATCH 0/2] perf: arm_spe: make the PMSCR CX bit[3] consistent
 across the session
In-Reply-To: <20220113175417.5523-1-german.gomez@arm.com>
References: <20220113175417.5523-1-german.gomez@arm.com>
Message-ID: <4f28367f-f6a2-fcca-dd33-c98daeb6bc11@arm.com>

Apologies everyone, this was a missend.

On 13/01/2022 17:54, German Gomez wrote:
> The value of the CX bit of the PMSCR register is not consistent across
> a perf session. There is an example in [1/2] to reproduce the issue.
>
> This cset applies a small correction to fix the consistency issue.
>
> - [PATCH 1/2] Makes the CX bit consistent by caching the value during
>   the initialization of the SPE PMU event.
> - [PATCH 2/2] Allows CONTEXT packets when profiling in CPU mode.
>
> German Gomez (2):
>   perf: arm_spe: make the PMSCR CX bit[3] consistent across the session
>   perf: arm_spe: Enable CONTEXT packets if profiling in CPU mode
>
>  drivers/perf/arm_spe_pmu.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
>


From angelogioacchino.delregno at collabora.com  Fri Jan 14 01:36:43 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 14 Jan 2022 10:36:43 +0100
Subject: [v9,2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <20220114092110.12137-3-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-3-rex-bc.chen@mediatek.com>
Message-ID: <4076cb55-4546-6bbd-1a1f-19395dcd9ccd@collabora.com>

Il 14/01/22 10:21, Rex-BC Chen ha scritto:
> Some DSI RX devices require the packets on all lanes aligned at the end.
> Otherwise, there will be some issues of shift or scroll for screen.
> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>

Hello,
thanks for the patch! However, there's something to improve...

> ---
>   drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..ccdda15f5a66 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -195,6 +195,8 @@ struct mtk_dsi {
>   	struct clk *hs_clk;
>   
>   	u32 data_rate;
> +	/* force dsi line end without dsi_null data */
> +	bool hs_packet_end_aligned;

There's no need to introduce a new variable here...

>   
>   	unsigned long mode_flags;
>   	enum mipi_dsi_pixel_format format;
> @@ -500,6 +502,13 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>   		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
>   	}
>   
> +	if (dsi->hs_packet_end_aligned) {

You can simply check mode_flags here:
	if (dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) {

> +		horizontal_sync_active_byte = roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> +		horizontal_frontporch_byte = roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> +		horizontal_backporch_byte = roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> +		horizontal_backporch_byte -= (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
> +	}
> +
>   	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>   	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>   	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
> @@ -794,6 +803,9 @@ static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>   	dsi->lanes = device->lanes;
>   	dsi->format = device->format;
>   	dsi->mode_flags = device->mode_flags;
> +	dsi->hs_packet_end_aligned = (dsi->mode_flags &
> +				      MIPI_DSI_HS_PKT_END_ALIGNED)
> +				     ? true : false;

...so there's no need for this one, either.

>   
>   	return 0;
>   }
> 

Regards,
- Angelo



From maxime at cerno.tech  Fri Jan 14 01:40:51 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:40:51 +0100
Subject: [PATCH v5 1/3] net: allwinner: reset control support
In-Reply-To: <20220113053734.105813-2-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-2-boger@wirenboard.com>
Message-ID: <20220114094051.4fmlhbdetk4sagiy@houat>

On Thu, Jan 13, 2022 at 08:37:32AM +0300, Evgeny Boger wrote:
> R40 (aka V40/A40i/T3) and A10/A20 share the same EMAC IP.
> However, on R40 the EMAC reset needs to be deasserted.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/9f5e13d9/attachment.sig>

From maxime at cerno.tech  Fri Jan 14 01:41:09 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:41:09 +0100
Subject: [PATCH v5 2/3] dt-bindings: net: support for Allwinner R40 EMAC
 controller
In-Reply-To: <20220113053734.105813-3-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-3-boger@wirenboard.com>
Message-ID: <20220114094109.l2xjbdxt77aqaxcq@houat>

On Thu, Jan 13, 2022 at 08:37:33AM +0300, Evgeny Boger wrote:
> R40 and A10/A20 share the same EMAC IP.
> However, on R40 the EMAC reset needs to be deasserted first,
> so resets property is required.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>

Acked-by: Maxime Ripard <maxime at cerno.tech>

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/07b75f75/attachment.sig>

From maxime at cerno.tech  Fri Jan 14 01:42:55 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 10:42:55 +0100
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <20220113053734.105813-4-boger@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-4-boger@wirenboard.com>
Message-ID: <20220114094255.br6qqqgoajvhpt2x@houat>

Hi,

On Thu, Jan 13, 2022 at 08:37:34AM +0300, Evgeny Boger wrote:
> R40 (aka V40, A40i, T3) has two different Ethernet IPs
> called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
> while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).
> 
> In contrast to A10/A20 where GMAC and EMAC share the same pins
> making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
> Both EMAC (on port H) and GMAC (on port A) can be then enabled at
> the same time, allowing for two ethernet ports.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> ---
>  arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
> index 03d3e5f45a09..8770b105f86e 100644
> --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> @@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
>  			#size-cells = <1>;
>  			ranges;
>  
> +			sram_a: sram at 0 {
> +				compatible = "mmio-sram";
> +				reg = <0x00000000 0xc000>;
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				ranges = <0 0x00000000 0xc000>;
> +
> +				emac_sram: sram-section at 8000 {
> +					compatible = "allwinner,sun4i-a10-sram-a3-a4";
> +					reg = <0x8000 0x4000>;
> +				};
> +			};
> +
>  			sram_c: sram at 1d00000 {
>  				compatible = "mmio-sram";
>  				reg = <0x01d00000 0xd0000>;
> @@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
>  				drive-strength = <40>;
>  			};
>  
> +			emac_pa_pins: emac-pa-pins {
> +				pins = "PA0", "PA1", "PA2",
> +				       "PA3", "PA4", "PA5", "PA6",
> +				       "PA7", "PA8", "PA9", "PA10",
> +				       "PA11", "PA12", "PA13", "PA14",
> +				       "PA15", "PA16";
> +				function = "emac";
> +			};
> +
> +			emac_ph_pins: emac-ph-pins {
> +				pins = "PH8", "PH9", "PH10", "PH11",
> +				       "PH14", "PH15", "PH16", "PH17",
> +				       "PH18","PH19", "PH20", "PH21",
> +				       "PH22", "PH23", "PH24", "PH25",
> +				       "PH26", "PH27";
> +				function = "emac";
> +			};

There's 17 pins on the first group, but 18 on the second, is it intentional?

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/769d9437/attachment-0001.sig>

From andy.shevchenko at gmail.com  Fri Jan 14 01:46:04 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 14 Jan 2022 11:46:04 +0200
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
 <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
 <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>
Message-ID: <CAHp75VfxtGue7bbMm_MU2GWwWo4aZLW2Pj_U9ocCQmWr6wfGMw@mail.gmail.com>

On Fri, Jan 14, 2022 at 4:51 AM Wells Lu ??? <wells.lu at sunplus.com> wrote:

...

> > > > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > > > >
> > > > > > Why bool and not tristate?
> > > > >
> > > > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > > > We never build it as a module, but build-in to kernel.
> > > > > So we use "bool".
> > > > >
> > > > > Should we set it to tristate?
> > > >
> > > > You still haven't answered "why", so I can't tell you.
> > >
> > > I am puzzled because I think I have answered "why".
> >
> > Nope. :-)
> >
> > > Because Pinctrl driver is necessary for all SP7021-based platforms.
> >
> > "Why?" Why is it necessary (to be built-in)?
>
> Pinctrl is necessary to be built-in because drivers of boot-device,
> like eMMC, SD card, NAND flash, and NOR flash drivers, need it.
>
> SP7021 supports booting from eMMC, SD card, NAND flash and NOR flash
> devices. Their drivers need Pinctrl driver probes in advance.

On x86 platforms, for example, booting from eMMC and SD card does not
require a pin control driver to be built-in. Why is this requirement
for SP platforms?

-- 
With Best Regards,
Andy Shevchenko


From angelogioacchino.delregno at collabora.com  Fri Jan 14 01:57:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 14 Jan 2022 10:57:18 +0100
Subject: [v9, 3/3] drm/bridge: anx7625: config hs packets end aligned to
 avoid screen shift
In-Reply-To: <20220114092110.12137-4-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-4-rex-bc.chen@mediatek.com>
Message-ID: <cd19a827-d132-1011-9445-7e425817102a@collabora.com>

Il 14/01/22 10:21, Rex-BC Chen ha scritto:
> This device requires the packets on lanes aligned at the end to fix
> screen shift or scroll.
> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 2346dbcc505f..fe32ab0878ae 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -1673,7 +1673,8 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
>   	dsi->format = MIPI_DSI_FMT_RGB888;
>   	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
>   		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
> -		MIPI_DSI_MODE_VIDEO_HSE;
> +		MIPI_DSI_MODE_VIDEO_HSE	|
> +		MIPI_DSI_HS_PKT_END_ALIGNED;
>   
>   	ret = devm_mipi_dsi_attach(dev, dsi);
>   	if (ret) {
> 



From angelogioacchino.delregno at collabora.com  Fri Jan 14 01:59:16 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 14 Jan 2022 10:59:16 +0100
Subject: [v9, 1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <20220114092110.12137-2-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-2-rex-bc.chen@mediatek.com>
Message-ID: <6874ebff-3b20-807d-0fa5-ba21986bb787@collabora.com>

Il 14/01/22 10:21, Rex-BC Chen ha scritto:
> Since a HS transmission is composed of an arbitrary number
> of bytes that may not be an integer multiple of lanes, some
> lanes may run out of data before others.
> (Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)
> 
> However, for some DSI RX devices (for example, anx7625),
> there is a limitation that packet number should be the same
> on all DSI lanes. In other words, they need to end a HS at
> the same time.
> 
> Because this limitation is for some specific DSI RX devices,
> it is more reasonable to put the enable control in these
> DSI RX drivers. If DSI TX driver knows the information,
> they can adjust the setting for this situation.
> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   include/drm/drm_mipi_dsi.h | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 147e51b6d241..342dfe5a0874 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -137,6 +137,8 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
>   #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
>   /* transmit data in low power */
>   #define MIPI_DSI_MODE_LPM		BIT(11)
> +/* transmit data ending in the same hsync for all lanes */
> +#define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
>   
>   enum mipi_dsi_pixel_format {
>   	MIPI_DSI_FMT_RGB888,
> 



From narmstrong at baylibre.com  Fri Jan 14 02:16:04 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 11:16:04 +0100
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
In-Reply-To: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
References: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
Message-ID: <07581fb8-0cd9-5b76-6fa3-1d1a7353d944@baylibre.com>

Hi,

On 14/01/2022 10:07, Jiayi.Zhou at amlogic.com wrote:
> From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>
> 
> For PWM controller in the Meson-S4 SoC,
> PWM needs to obtain an external clock source.
> This patch tries to describe them in the DT compatible data.

Can you be more explicit here ? On which SoC ? Why ?

As I understand while reading the S805X2 datasheet, now the PWM clock input is
done in independent CLKCTRL registers and no more in the PWM registers, right ?

So with S4, instead of passing the mux input clock of clkin0 & clkin1, now you pass
the PWM mux output clock.

> 
> Signed-off-by: Jiayi.zhou <jiayi.zhou at amlogic.com>
> ---
>  drivers/pwm/pwm-meson.c | 145 ++++++++++++++++++++++++++++++----------
>  1 file changed, 110 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c
> index 3cf3bcf5ddfc..54db56c95be2 100644
> --- a/drivers/pwm/pwm-meson.c
> +++ b/drivers/pwm/pwm-meson.c
> @@ -51,6 +51,7 @@
>  #define REG_MISC_AB		0x8
>  #define MISC_B_CLK_EN		BIT(23)
>  #define MISC_A_CLK_EN		BIT(15)
> +
>  #define MISC_CLK_DIV_MASK	0x7f
>  #define MISC_B_CLK_DIV_SHIFT	16
>  #define MISC_A_CLK_DIV_SHIFT	8
> @@ -93,11 +94,13 @@ struct meson_pwm_channel {
>  	struct clk *clk_parent;
>  	struct clk_mux mux;
>  	struct clk *clk;
> +	struct clk *clk_mux;

Why do you add a mux ?

>  };
>  
>  struct meson_pwm_data {
>  	const char * const *parent_names;
>  	unsigned int num_parents;
> +	unsigned int extern_clk;
>  };
>  
>  struct meson_pwm {
> @@ -105,6 +108,7 @@ struct meson_pwm {
>  	const struct meson_pwm_data *data;
>  	struct meson_pwm_channel channels[MESON_NUM_PWMS];
>  	void __iomem *base;
> +
>  	/*
>  	 * Protects register (write) access to the REG_MISC_AB register
>  	 * that is shared between the two PWMs.
> @@ -130,13 +134,15 @@ static int meson_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
>  
>  	channel = &meson->channels[pwm->hwpwm];
>  
> -	if (channel->clk_parent) {
> -		err = clk_set_parent(channel->clk, channel->clk_parent);
> -		if (err < 0) {
> -			dev_err(dev, "failed to set parent %s for %s: %d\n",
> -				__clk_get_name(channel->clk_parent),
> -				__clk_get_name(channel->clk), err);
> -			return err;
> +	if (!meson->data->extern_clk) {
> +		if (channel->clk_parent) {
> +			err = clk_set_parent(channel->clk, channel->clk_parent);
> +			if (err < 0) {
> +				dev_err(dev, "failed to set parent %s for %s: %d\n",
> +					__clk_get_name(channel->clk_parent),
> +					__clk_get_name(channel->clk), err);
> +					return err;
> +			}
>  		}
>  	}
>  
> @@ -171,7 +177,11 @@ static int meson_pwm_calc(struct meson_pwm *meson, struct pwm_device *pwm,
>  	if (state->polarity == PWM_POLARITY_INVERSED)
>  		duty = period - duty;
>  
> -	fin_freq = clk_get_rate(channel->clk);
> +	if (meson->data->extern_clk) {
> +		fin_freq = clk_get_rate(channel->clk_mux);> +	} else {
> +		fin_freq = clk_get_rate(channel->clk);
> +	}
>  	if (fin_freq == 0) {
>  		dev_err(meson->chip.dev, "invalid source clock frequency\n");
>  		return -EINVAL;
> @@ -228,17 +238,32 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
>  	struct meson_pwm_channel_data *channel_data;
>  	unsigned long flags;
>  	u32 value;
> +	unsigned long set_clk;
> +	u32 err;
>  
>  	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
>  
> -	spin_lock_irqsave(&meson->lock, flags);
> -
>  	value = readl(meson->base + REG_MISC_AB);
> -	value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
> -	value |= channel->pre_div << channel_data->clk_div_shift;
> -	value |= channel_data->clk_en_mask;
> -	writel(value, meson->base + REG_MISC_AB);
> +	if (meson->data->extern_clk) {
> +		set_clk = clk_get_rate(channel->clk_mux);
> +
> +		if (set_clk == 0)
> +			dev_err(meson->chip.dev, "invalid source clock frequency\n");
> +		set_clk /= channel->pre_div + 1;
> +		err = clk_set_rate(channel->clk, set_clk);
> +		if (err)
> +			dev_err(meson->chip.dev, "%s: error in setting pwm rate!\n", __func__);
> +	} else {
> +		spin_lock_irqsave(&meson->lock, flags);
> +
> +		value &= ~(MISC_CLK_DIV_MASK << channel_data->clk_div_shift);
> +		value |= channel->pre_div << channel_data->clk_div_shift;
> +		value |= channel_data->clk_en_mask;
> +		writel(value, meson->base + REG_MISC_AB);
>  
> +		spin_unlock_irqrestore(&meson->lock, flags);
> +	}
> +	spin_lock_irqsave(&meson->lock, flags);
>  	value = FIELD_PREP(PWM_HIGH_MASK, channel->hi) |
>  		FIELD_PREP(PWM_LOW_MASK, channel->lo);
>  	writel(value, meson->base + channel_data->reg_offset);
> @@ -246,7 +271,6 @@ static void meson_pwm_enable(struct meson_pwm *meson, struct pwm_device *pwm)
>  	value = readl(meson->base + REG_MISC_AB);
>  	value |= channel_data->pwm_en_mask;
>  	writel(value, meson->base + REG_MISC_AB);
> -
>  	spin_unlock_irqrestore(&meson->lock, flags);
>  }
>  
> @@ -333,7 +357,8 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
>  	struct meson_pwm *meson = to_meson_pwm(chip);
>  	struct meson_pwm_channel_data *channel_data;
>  	struct meson_pwm_channel *channel;
> -	u32 value, tmp;
> +	u32 value_pwm, value, tmp;
> +	unsigned long gate_clk, fre;
>  
>  	if (!state)
>  		return;
> @@ -341,30 +366,42 @@ static void meson_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
>  	channel = &meson->channels[pwm->hwpwm];
>  	channel_data = &meson_pwm_per_channel_data[pwm->hwpwm];
>  
> -	value = readl(meson->base + REG_MISC_AB);
> -
> -	tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
> -	state->enabled = (value & tmp) == tmp;
> -
> -	tmp = value >> channel_data->clk_div_shift;
> -	channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
> -
> +	value_pwm = readl(meson->base + REG_MISC_AB);
>  	value = readl(meson->base + channel_data->reg_offset);
>  
>  	channel->lo = FIELD_GET(PWM_LOW_MASK, value);
>  	channel->hi = FIELD_GET(PWM_HIGH_MASK, value);
>  
> -	if (channel->lo == 0) {
> -		state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> -		state->duty_cycle = state->period;
> -	} else if (channel->lo >= channel->hi) {
> -		state->period = meson_pwm_cnt_to_ns(chip, pwm,
> -						    channel->lo + channel->hi);
> -		state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm,
> -							channel->hi);
> +	if (meson->data->extern_clk) {
> +		gate_clk = clk_get_rate(channel->clk);
> +		fre = gate_clk / (channel->lo + channel->hi);
> +		state->period = div_u64(NSEC_PER_SEC, fre);
> +		state->duty_cycle = div_u64(state->period * channel->hi, channel->lo + channel->hi);
> +		tmp = channel_data->pwm_en_mask;
> +
> +		if (((value_pwm & tmp) == tmp) && __clk_is_enabled(channel->clk))
> +			state->enabled = true;
> +		else
> +			state->enabled = false;
>  	} else {
> -		state->period = 0;
> -		state->duty_cycle = 0;
> +		tmp = channel_data->pwm_en_mask | channel_data->clk_en_mask;
> +
> +		state->enabled = (value_pwm & tmp) == tmp;
> +
> +		tmp = value_pwm >> channel_data->clk_div_shift;
> +		channel->pre_div = FIELD_GET(MISC_CLK_DIV_MASK, tmp);
> +
> +		if (channel->lo == 0) {
> +			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> +			state->duty_cycle = state->period;
> +		} else if (channel->lo >= channel->hi) {
> +			state->period = meson_pwm_cnt_to_ns(chip, pwm, channel->lo
> +							    + channel->hi);
> +			state->duty_cycle = meson_pwm_cnt_to_ns(chip, pwm, channel->hi);
> +		} else {
> +			state->period = 0;
> +			state->duty_cycle = 0;
> +		}
>  	}
>  }

You need to rewrite the clock calculation entirely, instead of relying on a fin_freq, you need
to set_rate() the needed rate to the input clock, then calculate the periods on the rate
set by CCF.

One way is to forget trying to set a rate of the input clock, simply get_rate() of the input clock
and try to calculate periods on it.

Instead rely on assignes-clock-parent & assigned-clock-rate in DT to set the right parent of the mux
and rate of the mux post divider to feed to correct rate to the PWM controller.

>  
> @@ -452,6 +489,10 @@ static const struct meson_pwm_data pwm_g12a_ee_data = {
>  	.num_parents = ARRAY_SIZE(pwm_g12a_ee_parent_names),
>  };
>  
> +static const struct meson_pwm_data pwm_meson_data = {
> +	.extern_clk = true,
> +};
> +
>  static const struct of_device_id meson_pwm_matches[] = {
>  	{
>  		.compatible = "amlogic,meson8b-pwm",
> @@ -485,6 +526,10 @@ static const struct of_device_id meson_pwm_matches[] = {
>  		.compatible = "amlogic,meson-g12a-ao-pwm-cd",
>  		.data = &pwm_g12a_ao_cd_data
>  	},
> +	{
> +		.compatible = "amlogic,meson-s4-pwm",
> +		.data = &pwm_meson_data
> +	},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, meson_pwm_matches);
> @@ -534,6 +579,33 @@ static int meson_pwm_init_channels(struct meson_pwm *meson)
>  	return 0;
>  }
>  
> +static int meson_pwm_extern_init_channels(struct meson_pwm *meson)
> +{
> +	struct meson_pwm_channel *channels = meson->channels;
> +	struct device *dev = meson->chip.dev;
> +	unsigned int i;
> +	char name[255];
> +
> +	for (i = 0; i < meson->chip.npwm; i++) {
> +		snprintf(name, sizeof(name), "clkin%u", i);
> +		(channels + i)->clk = devm_clk_get(dev, name);
> +		if (IS_ERR((channels + i)->clk)) {
> +			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk),
> +				      "can't get device clock\n");
> +			return PTR_ERR((channels + i)->clk);
> +		}
> +		snprintf(name, sizeof(name), "mux%u", i);
> +		(channels + i)->clk_mux = devm_clk_get(dev, name);
> +		if (IS_ERR((channels + i)->clk_mux)) {
> +			dev_err_probe(meson->chip.dev, PTR_ERR((channels + i)->clk_mux),
> +				      "can't get device clock\n");
> +			return PTR_ERR((channels + i)->clk_mux);

If you add mux you'll need to changes the bindings.

> +		}
> +	}
> +
> +	return 0;
> +}
> +
>  static int meson_pwm_probe(struct platform_device *pdev)
>  {
>  	struct meson_pwm *meson;
> @@ -553,8 +625,11 @@ static int meson_pwm_probe(struct platform_device *pdev)
>  	meson->chip.npwm = MESON_NUM_PWMS;
>  
>  	meson->data = of_device_get_match_data(&pdev->dev);
> +	if (meson->data->extern_clk)
> +		err = meson_pwm_extern_init_channels(meson);
> +	else
> +		err = meson_pwm_init_channels(meson);
>  
> -	err = meson_pwm_init_channels(meson);
>  	if (err < 0)
>  		return err;
>  
> 



From rex-bc.chen at mediatek.com  Fri Jan 14 02:20:12 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Fri, 14 Jan 2022 18:20:12 +0800
Subject: [v9,2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <4076cb55-4546-6bbd-1a1f-19395dcd9ccd@collabora.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-3-rex-bc.chen@mediatek.com>
 <4076cb55-4546-6bbd-1a1f-19395dcd9ccd@collabora.com>
Message-ID: <f858dd4aaa35fa3eb969baf887f038c3593232e5.camel@mediatek.com>

Hello AngeloGioacchino,

Thanks for your review.
I will modify this in next version.

BRs,
Rex-BC Chen

On Fri, 2022-01-14 at 10:36 +0100, AngeloGioacchino Del Regno wrote:
> Il 14/01/22 10:21, Rex-BC Chen ha scritto:
> > Some DSI RX devices require the packets on all lanes aligned at the
> > end.
> > Otherwise, there will be some issues of shift or scroll for screen.
> > 
> > Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> > Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> 
> Hello,
> thanks for the patch! However, there's something to improve...
> 
> > ---
> >   drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
> >   1 file changed, 12 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index 5d90d2eb0019..ccdda15f5a66 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -195,6 +195,8 @@ struct mtk_dsi {
> >   	struct clk *hs_clk;
> >   
> >   	u32 data_rate;
> > +	/* force dsi line end without dsi_null data */
> > +	bool hs_packet_end_aligned;
> 
> There's no need to introduce a new variable here...
> >   
> >   	unsigned long mode_flags;
> >   	enum mipi_dsi_pixel_format format;
> > @@ -500,6 +502,13 @@ static void mtk_dsi_config_vdo_timing(struct
> > mtk_dsi *dsi)
> >   		DRM_WARN("HFP + HBP less than d-phy, FPS will under
> > 60Hz\n");
> >   	}
> >   
> > +	if (dsi->hs_packet_end_aligned) {
> 
> You can simply check mode_flags here:
> 	if (dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) {
> 
> > +		horizontal_sync_active_byte =
> > roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> > +		horizontal_frontporch_byte =
> > roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> > +		horizontal_backporch_byte =
> > roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> > +		horizontal_backporch_byte -= (vm->hactive *
> > dsi_tmp_buf_bpp + 2) % dsi->lanes;
> > +	}
> > +
> >   	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
> >   	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
> >   	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
> > @@ -794,6 +803,9 @@ static int mtk_dsi_host_attach(struct
> > mipi_dsi_host *host,
> >   	dsi->lanes = device->lanes;
> >   	dsi->format = device->format;
> >   	dsi->mode_flags = device->mode_flags;
> > +	dsi->hs_packet_end_aligned = (dsi->mode_flags &
> > +				      MIPI_DSI_HS_PKT_END_ALIGNED)
> > +				     ? true : false;
> 
> ...so there's no need for this one, either.
> 
> >   
> >   	return 0;
> >   }
> > 
> 
> Regards,
> - Angelo
> 



From angelogioacchino.delregno at collabora.com  Fri Jan 14 02:26:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 14 Jan 2022 11:26:49 +0100
Subject: [PATCH] media: mtk-mdp: Remove redundant 'flush_workqueue()' calls
In-Reply-To: <20220114082214.41817-1-vulab@iscas.ac.cn>
References: <20220114082214.41817-1-vulab@iscas.ac.cn>
Message-ID: <d838768d-6f85-4977-d014-d5f85ae7126f@collabora.com>

Il 14/01/22 09:22, Xu Wang ha scritto:
> 'destroy_workqueue()' already drains the queue before destroying it, so
> there is no need to flush it explicitly.
> 
> Remove the redundant 'flush_workqueue()' calls.
> 
> Signed-off-by: Xu Wang <vulab at iscas.ac.cn>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From xji at analogixsemi.com  Fri Jan 14 02:27:37 2022
From: xji at analogixsemi.com (Xin Ji)
Date: Fri, 14 Jan 2022 18:27:37 +0800
Subject: [v9,3/3] drm/bridge: anx7625: config hs packets end aligned to
 avoid screen shift
In-Reply-To: <20220114092110.12137-4-rex-bc.chen@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-4-rex-bc.chen@mediatek.com>
Message-ID: <20220114102737.GA2606309@anxtwsw-Precision-3640-Tower>

Hi Rex-BC Chen, thanks for your patch, it is OK for me.

Reviewed-by: Xin Ji <xji at analogixsemi.com>

Thanks,
Xin

On Fri, Jan 14, 2022 at 05:21:10PM +0800, Rex-BC Chen wrote:
> This device requires the packets on lanes aligned at the end to fix
> screen shift or scroll.
> 
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> ---
>  drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 2346dbcc505f..fe32ab0878ae 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -1673,7 +1673,8 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
>  	dsi->format = MIPI_DSI_FMT_RGB888;
>  	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
>  		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
> -		MIPI_DSI_MODE_VIDEO_HSE;
> +		MIPI_DSI_MODE_VIDEO_HSE	|
> +		MIPI_DSI_HS_PKT_END_ALIGNED;
>  
>  	ret = devm_mipi_dsi_attach(dev, dsi);
>  	if (ret) {
> -- 
> 2.18.0


From alain.volmat at foss.st.com  Fri Jan 14 02:34:15 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Fri, 14 Jan 2022 11:34:15 +0100
Subject: [PATCH 2/2] MAINTAINERS: update drm/stm drm/sti and cec/sti
 maintainers
In-Reply-To: <20220113171921.17466-3-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
 <20220113171921.17466-3-philippe.cornu@foss.st.com>
Message-ID: <20220114103415.GA374310@gnbcxd0016.gnb.st.com>

Hi Philippe,

thanks for the patch.

Reviewed-by: Alain Volmat <alain.volmat at foss.st.com>

Alain

On Thu, Jan 13, 2022 at 06:19:21PM +0100, Philippe Cornu wrote:
> Add Alain as sti maintainer for both drm/sti & cec/sti.
> Add Rapha?l as stm maintainer for drm/stm.
> 
> Signed-off-by: Philippe Cornu <philippe.cornu at foss.st.com>
> ---
>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6bea080d0159..708f8c86e4c9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6423,6 +6423,7 @@ F:	Documentation/devicetree/bindings/display/rockchip/
>  F:	drivers/gpu/drm/rockchip/
>  
>  DRM DRIVERS FOR STI
> +M:	Alain Volmat <alain.volmat at foss.st.com>
>  L:	dri-devel at lists.freedesktop.org
>  S:	Maintained
>  T:	git git://anongit.freedesktop.org/drm/drm-misc
> @@ -6431,6 +6432,7 @@ F:	drivers/gpu/drm/sti
>  
>  DRM DRIVERS FOR STM
>  M:	Yannick Fertre <yannick.fertre at foss.st.com>
> +M:	Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
>  M:	Philippe Cornu <philippe.cornu at foss.st.com>
>  L:	dri-devel at lists.freedesktop.org
>  S:	Maintained
> @@ -18152,6 +18154,7 @@ F:	Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
>  F:	sound/soc/sti/
>  
>  STI CEC DRIVER
> +M:	Alain Volmat <alain.volmat at foss.st.com>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/media/stih-cec.txt
>  F:	drivers/media/cec/platform/sti/
> -- 
> 2.17.1
> 


From andre.przywara at foss.arm.com  Fri Jan 14 02:37:50 2022
From: andre.przywara at foss.arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 10:37:50 +0000
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <20220114094255.br6qqqgoajvhpt2x@houat>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-4-boger@wirenboard.com>
 <20220114094255.br6qqqgoajvhpt2x@houat>
Message-ID: <20220114103750.01f95d70@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:42:55 +0100
Maxime Ripard <maxime at cerno.tech> wrote:

Hi,

> On Thu, Jan 13, 2022 at 08:37:34AM +0300, Evgeny Boger wrote:
> > R40 (aka V40, A40i, T3) has two different Ethernet IPs
> > called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
> > while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).
> > 
> > In contrast to A10/A20 where GMAC and EMAC share the same pins
> > making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
> > Both EMAC (on port H) and GMAC (on port A) can be then enabled at
> > the same time, allowing for two ethernet ports.
> > 
> > Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> > ---
> >  arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
> >  1 file changed, 49 insertions(+)
> > 
> > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
> > index 03d3e5f45a09..8770b105f86e 100644
> > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> > @@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
> >  			#size-cells = <1>;
> >  			ranges;
> >  
> > +			sram_a: sram at 0 {
> > +				compatible = "mmio-sram";
> > +				reg = <0x00000000 0xc000>;
> > +				#address-cells = <1>;
> > +				#size-cells = <1>;
> > +				ranges = <0 0x00000000 0xc000>;
> > +
> > +				emac_sram: sram-section at 8000 {
> > +					compatible = "allwinner,sun4i-a10-sram-a3-a4";
> > +					reg = <0x8000 0x4000>;
> > +				};
> > +			};
> > +
> >  			sram_c: sram at 1d00000 {
> >  				compatible = "mmio-sram";
> >  				reg = <0x01d00000 0xd0000>;
> > @@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
> >  				drive-strength = <40>;
> >  			};
> >  
> > +			emac_pa_pins: emac-pa-pins {
> > +				pins = "PA0", "PA1", "PA2",
> > +				       "PA3", "PA4", "PA5", "PA6",
> > +				       "PA7", "PA8", "PA9", "PA10",
> > +				       "PA11", "PA12", "PA13", "PA14",
> > +				       "PA15", "PA16";
> > +				function = "emac";
> > +			};
> > +
> > +			emac_ph_pins: emac-ph-pins {
> > +				pins = "PH8", "PH9", "PH10", "PH11",
> > +				       "PH14", "PH15", "PH16", "PH17",
> > +				       "PH18","PH19", "PH20", "PH21",
> > +				       "PH22", "PH23", "PH24", "PH25",
> > +				       "PH26", "PH27";
> > +				function = "emac";
> > +			};  
> 
> There's 17 pins on the first group, but 18 on the second, is it intentional?

Yeah, looks like PA17 is missing above. This pin is used for MII only, so
it is omitted from the existing gmac_rgmii_pins group.

Evgeny: Did you try a 100MBit PHY on PortA? That should work with both the
GMAC and EMAC, right? I wonder if we should add a group that connects all
pins needed for MII to the GMAC as well, so basically the above (with PA17
added), but using 'function = "gmac";'? Put an "/omit-if-no-ref/" before
that (also to those above?) to avoid blowing up the DTB needlessly.

Cheers,
Andre.


From raphael.gallais-pou at foss.st.com  Fri Jan 14 02:41:08 2022
From: raphael.gallais-pou at foss.st.com (Raphael Gallais-Pou)
Date: Fri, 14 Jan 2022 11:41:08 +0100
Subject: [PATCH 2/2] MAINTAINERS: update drm/stm drm/sti and cec/sti
 maintainers
In-Reply-To: <20220113171921.17466-3-philippe.cornu@foss.st.com>
References: <20220113171921.17466-1-philippe.cornu@foss.st.com>
 <20220113171921.17466-3-philippe.cornu@foss.st.com>
Message-ID: <7bd3229c-8b66-6a4f-4fed-cd1929f2c397@foss.st.com>


On 1/13/22 6:19 PM, Philippe Cornu wrote:
> Add Alain as sti maintainer for both drm/sti & cec/sti.
> Add Rapha?l as stm maintainer for drm/stm.
>
> Signed-off-by: Philippe Cornu <philippe.cornu at foss.st.com>
> ---
>  MAINTAINERS | 3 +++
>  1 file changed, 3 insertions(+)


Hi Philippe,


Reviewed-by: Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>


Thank you ! :D
Rapha?l


>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6bea080d0159..708f8c86e4c9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6423,6 +6423,7 @@ F:	Documentation/devicetree/bindings/display/rockchip/
>  F:	drivers/gpu/drm/rockchip/
>  
>  DRM DRIVERS FOR STI
> +M:	Alain Volmat <alain.volmat at foss.st.com>
>  L:	dri-devel at lists.freedesktop.org
>  S:	Maintained
>  T:	git git://anongit.freedesktop.org/drm/drm-misc
> @@ -6431,6 +6432,7 @@ F:	drivers/gpu/drm/sti
>  
>  DRM DRIVERS FOR STM
>  M:	Yannick Fertre <yannick.fertre at foss.st.com>
> +M:	Raphael Gallais-Pou <raphael.gallais-pou at foss.st.com>
>  M:	Philippe Cornu <philippe.cornu at foss.st.com>
>  L:	dri-devel at lists.freedesktop.org
>  S:	Maintained
> @@ -18152,6 +18154,7 @@ F:	Documentation/devicetree/bindings/sound/st,sti-asoc-card.txt
>  F:	sound/soc/sti/
>  
>  STI CEC DRIVER
> +M:	Alain Volmat <alain.volmat at foss.st.com>
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/media/stih-cec.txt
>  F:	drivers/media/cec/platform/sti/


From narmstrong at baylibre.com  Fri Jan 14 02:42:35 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 11:42:35 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>

On 14/01/2022 09:29, Biju Das wrote:
> Hi Neil,
>  
> + renesas-soc
> 
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi,
>>
>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>> Hi Biju,
>>>
>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das <biju.das.jz at bp.renesas.com>
>> wrote:
>>>>
>>>> Hi All,
>>>>
>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour) till
>>>> the commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks").
>>>>
>>>> After this patch, the screen becomes greenish(may be it is setting it
>> into YUV format??).
>>>>
>>>> By checking the code, previously it used to call get_input_fmt callback
>> and set colour as RGB24.
>>>>
>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I see
>> the outputformat as YUV16 instead of RGB24.
>>>>
>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>
>> This patch was introduced to maintain the bridge color format negotiation
>> after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems it behaves
>> incorrectly if the first bridge doesn't implement the negotiation
>> callbacks.
>>
>> Let me check the code to see how to fix that.
> 
> Thanks for the information, I am happy to test the patch/fix.
> 
> Cheers,
> Biju
> 
>>
>>>
>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which shows:
>>>
>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
>>> (DWC HDMI 3D TX PHY)
>>>
>>> The colors are shown correctly here.
>>>
>>
>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
>> fails and use the RGB fallback input & output format.
>>
>> Anyway thanks for testing
>>
>> Neil

Can you test :

==><===============================
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index c96847fc0ebc..7019acd37716 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
        last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state,
                                                            last_bridge);

-       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
+       /*
+        * Only negociate with real values if both end of the bridge chain
+        * support negociation callbacks, otherwise you can end in a situation
+        * where the selected output format doesn't match with the first bridge
+        * output format.
+        */
+       if (bridge->funcs->atomic_get_input_bus_fmts &&
+           last_bridge->funcs->atomic_get_output_bus_fmts) {
                const struct drm_bridge_funcs *funcs = last_bridge->funcs;

                /*
@@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge,
                if (!out_bus_fmts)
                        return -ENOMEM;

-               if (conn->display_info.num_bus_formats &&
+               /*
+                * If first bridge doesn't support negociation, use MEDIA_BUS_FMT_FIXED
+                * as a safe value for the whole bridge chain
+                */
+               if (bridge->funcs->atomic_get_input_bus_fmts &&
+                   conn->display_info.num_bus_formats &&
                    conn->display_info.bus_formats)
                        out_bus_fmts[0] = conn->display_info.bus_formats[0];
                else
==><===============================

This should exclude your situation where the first bridge doesn't support negociation.

Neil


From mark.rutland at arm.com  Fri Jan 14 02:44:55 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:44:55 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <9eb63797-b313-a39a-6b9c-0f8ac447b85a@arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
 <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
 <20220113195051.7100b066@slackpad.fritz.box>
 <9eb63797-b313-a39a-6b9c-0f8ac447b85a@arm.com>
Message-ID: <YeFUJ+dw22Kmhwjs@FVFF77S0Q05N>

On Fri, Jan 14, 2022 at 08:35:06AM +0000, Vladimir Murzin wrote:
> Hi Andre,
> 
> On 1/13/22 7:50 PM, Andre Przywara wrote:
> > On Thu, 13 Jan 2022 18:42:50 +0000
> > Vladimir Murzin <vladimir.murzin at arm.com> wrote:
> > 
> > Hi Vladimir,
> > 
> >> On 12/22/21 6:16 PM, Andre Przywara wrote:
> >>> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> >>> the blob first, then re-compile it with our nodes and properties added.
> >>>
> >>> In our input DTB the proper phandle references have already been lost,
> >>> all we see in the DTB is phandle properties in the target node, and some
> >>> numbers in the clocks and gpios properties:
> >>> ===========
> >>> 	clk24mhz {
> >>> 		compatible = "fixed-clock";
> >>> 		#clock-cells = <0x00>;
> >>> 		clock-frequency = <0x16e3600>;
> >>> 		clock-output-names = "v2m:clk24mhz";  
> >>> ->		phandle = <0x05>;  
> >>> 	};
> >>> 	...
> >>> 	serial at 90000 {
> >>> 		compatible = "arm,pl011", "arm,primecell";
> >>> 		reg = <0x90000 0x1000>;
> >>> 		interrupts = <0x05>;  
> >>> ->		clocks = <0x05 0x05>;  
> >>> 		clock-names = "uartclk", "apb_pclk";
> >>> 	};
> >>> ===========
> >>> dtc warns that those numbers might be wrong:
> >>> =========
> >>> <stdin>:177.6-27: Warning (clocks_property):
> >>>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
> >>>    clocks: cell 0 is not a phandle reference
> >>> ....
> >>> =========
> >>> The proper solution would be to use references (&v2m_clk24mhz) instead,
> >>> as there are in the source .dts file, but we don't have that information
> >>> anymore, and cannot easily recover it.
> >>>
> >>> To avoid the lengthy list of warnings, just drop those checks from the
> >>> dtc compilation run. This disables more checks than we want or need, but
> >>> we somewhat trust in the original DTB to be sane, so that should be
> >>> fine.
> >>>
> >>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> >>> ---
> >>>  Makefile.am | 2 +-
> >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>
> >>> diff --git a/Makefile.am b/Makefile.am
> >>> index 3d8128f..430b4a9 100644
> >>> --- a/Makefile.am
> >>> +++ b/Makefile.am
> >>> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
> >>>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
> >>>  
> >>>  fdt.dtb: $(KERNEL_DTB) Makefile
> >>> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> >>> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
> >>>  
> >>>  # The filesystem archive might not exist if INITRD is not being used
> >>>  .PHONY: all clean $(FILESYSTEM)
> >>>   
> >>
> >> dtc 1.4.1 complains
> > 
> > Which distro ships this version? (distrowatch doesn't list dtc)
> > 
> > tag v1.4.1
> > Tagger: David Gibson <david at gibson.dropbear.id.au>
> > Date:   Wed Nov 12 14:31:44 2014 +1100
> > 
> > Any chance it's just you and you can update this? It looks like the
> > first version to support it is 1.4.5, as shipped for instance with
> > Ubuntu 18.04.
> 
> It is shipped as LSF module. I can try to ask for an update, but I thought
> that other people may run into it as well...
> 
> > 
> >> FATAL ERROR: Unrecognized check name "clocks_property"
> > 
> > Sigh, thanks for the heads up. I don't know if we want to blow up the
> > Makefile with a feature test?
> 
> I dunno, TBH. It look like warning used to be less evil than error...

I agree.

My preference would be to revert that for now, and consider the problem afresh.
Andre, are you ok with that?

Mark.


From mark.rutland at arm.com  Fri Jan 14 02:48:12 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:48:12 +0000
Subject: [bootwrapper PATCH 11/13] Announce locations of memory objects
In-Reply-To: <20220111130653.2331827-12-mark.rutland@arm.com>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-12-mark.rutland@arm.com>
Message-ID: <YeFU7Bg1ZcGlwpfU@FVFF77S0Q05N>

On Tue, Jan 11, 2022 at 01:06:51PM +0000, Mark Rutland wrote:
> diff --git a/common/platform.c b/common/platform.c
> index 80d0562..5a91349 100644
> --- a/common/platform.c
> +++ b/common/platform.c
> @@ -52,6 +52,20 @@ void print_string(const char *str)
>  		print_char(*str++);
>  }
>  
> +#define HEX_CHARS_PER_LONG (2 * sizeof(long))
> +#define NIBBLES_PER

I've deleted this latter definition, as it was added by mistake.

Mark.


From pali at kernel.org  Fri Jan 14 02:51:00 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Fri, 14 Jan 2022 11:51:00 +0100
Subject: [PATCH v7 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <87ee6bm9hn.fsf@BL-laptop>
References: <20210930095838.28145-1-pali@kernel.org>
 <20211103214209.azo2z3z4gy7aj5hu@pali> <87ee6bm9hn.fsf@BL-laptop>
Message-ID: <20220114105100.im6gmkt6fjl2aiwl@pali>

Hello Stephen!

On Friday 17 December 2021 18:23:00 Gregory CLEMENT wrote:
> Hello Pali,
> 
> > On Thursday 30 September 2021 11:58:32 Pali Roh?r wrote:
> >> This patch series add support for baudrates higher than 230400 on
> >> Marvell Armada 37xx boards.
> >
> > Stephen, Gregory, are there any issues with this patch series?
> 
> I am not found of these changes but let's apply it as I didn't take time
> to do a better review.
> 
> However I can't apply the dt part if the driver is not merged.

Stephen, are there any issues with driver (non-DT) part changes in this
patch series? If not, could you please merge them? This patch series is
here on the list since September without any request for change...

We would really like to see support for higher baudrates for Armada 3720
platforms in mainline kernel.

> Gregory
> 
> > If not, could you take them?
> >
> >> Changes in v7:
> >> * fixed lint errors in yaml binding file
> >> 
> >> Changes in v6:
> >> * fixed yaml binding file and dts files
> >> 
> >> Changes in v5:
> >> * fixed yaml binding file
> >> 
> >> Changes in v4:
> >> * converted armada3700-uart-clock documentation to YAML
> >> * split documentation changes into two commits:
> >>   - first which adds clock documentation
> >>   - second which updates UART documentation
> >> 
> >> Changes in v3:
> >> v3 is rebased on top of Linus master branch and all already applied patches
> >> were dropped. There are no changes in patches itself since v2.
> >> 
> >> Pali Roh?r (6):
> >>   math64: New DIV_U64_ROUND_CLOSEST helper
> >>   serial: mvebu-uart: implement UART clock driver for configuring UART
> >>     base clock
> >>   dt-bindings: mvebu-uart: document DT bindings for
> >>     marvell,armada-3700-uart-clock
> >>   dt-bindings: mvebu-uart: update information about UART clock
> >>   arm64: dts: marvell: armada-37xx: add device node for UART clock and
> >>     use it
> >>   serial: mvebu-uart: implement support for baudrates higher than 230400
> >> 
> >>  .../clock/marvell,armada-3700-uart-clock.yaml |  59 ++
> >>  .../devicetree/bindings/serial/mvebu-uart.txt |   9 +-
> >>  arch/arm64/boot/dts/marvell/armada-37xx.dtsi  |  14 +-
> >>  drivers/tty/serial/Kconfig                    |   1 +
> >>  drivers/tty/serial/mvebu-uart.c               | 592 +++++++++++++++++-
> >>  include/linux/math64.h                        |  13 +
> >>  6 files changed, 667 insertions(+), 21 deletions(-)
> >>  create mode 100644 Documentation/devicetree/bindings/clock/marvell,armada-3700-uart-clock.yaml
> >> 
> >> -- 
> >> 2.20.1
> >> 
> 
> -- 
> Gregory Clement, Bootlin
> Embedded Linux and Kernel engineering
> http://bootlin.com


From wells.lu at sunplus.com  Fri Jan 14 02:56:10 2022
From: wells.lu at sunplus.com (=?utf-8?B?V2VsbHMgTHUg5ZGC6Iqz6aiw?=)
Date: Fri, 14 Jan 2022 10:56:10 +0000
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <CAHp75VfxtGue7bbMm_MU2GWwWo4aZLW2Pj_U9ocCQmWr6wfGMw@mail.gmail.com>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
 <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
 <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>
 <CAHp75VfxtGue7bbMm_MU2GWwWo4aZLW2Pj_U9ocCQmWr6wfGMw@mail.gmail.com>
Message-ID: <b9c1876c9d0f48a3a8d7e091d47fc069@sphcmbx02.sunplus.com.tw>

> ...
> 
> > > > > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > > > > >
> > > > > > > Why bool and not tristate?
> > > > > >
> > > > > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > > > > We never build it as a module, but build-in to kernel.
> > > > > > So we use "bool".
> > > > > >
> > > > > > Should we set it to tristate?
> > > > >
> > > > > You still haven't answered "why", so I can't tell you.
> > > >
> > > > I am puzzled because I think I have answered "why".
> > >
> > > Nope. :-)
> > >
> > > > Because Pinctrl driver is necessary for all SP7021-based platforms.
> > >
> > > "Why?" Why is it necessary (to be built-in)?
> >
> > Pinctrl is necessary to be built-in because drivers of boot-device,
> > like eMMC, SD card, NAND flash, and NOR flash drivers, need it.
> >
> > SP7021 supports booting from eMMC, SD card, NAND flash and NOR flash
> > devices. Their drivers need Pinctrl driver probes in advance.
> 
> On x86 platforms, for example, booting from eMMC and SD card does not require a pin
> control driver to be built-in. Why is this requirement for SP platforms?
> 
> --
> With Best Regards,
> Andy Shevchenko

Because all pins of boot-device multiplex with GPIO pins.

SP7021 platforms support multi boot devices, including eMMC, SD card,
SPI-NOR flash, SPI-NAND flash. Each boot device has control-bit(s) 
to enable it.

For example #1, if control-bits of SPI-NOR flash is set 1,
GPIO 83, 84, 86, 87 are connected to SPI-NOR flash.
If control-bits of SPI-NOR flash is set 2,
GPIO 76, 78, 79, 81 are connected to SPI-NOR flash.
If control-bits of SPI-NOR flash is set 0, no pin is 
connected SPI-NOR flash.

For example #2, if control-bits of eMMC device is set 1,
GPIO 72, 73, 74, 75, 76, 77, 78, 79, 80, 81 are connected to
eMMC device.
If control-bits of eMMC device is set 0, no pin is connected 
eMMC device.

For example #3, if control-bits of SDCard device is set 1,
GPIO 65, 66, 67, 68, 69, 70 are connected to SD Card device.
If control-bits of SDCard device is set 0, no pin is connected 
SDCard device.

Note that all pins multiplex with GPIO pins.

Normally, only a boot-device is enabled. All other GPIO pins
are released for peripherals (controlled by fully-pinmux
Or group pinmux) or IO processor

Pinctrl driver is responsible for setup the pins.
If Pinctrl fails to probe, boot-device also fails to probe.


Best regards,
Wells Lu

From mark.rutland at arm.com  Fri Jan 14 02:56:40 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:40 +0000
Subject: [bootwrapper PATCH v2 00/13] Cleanups and improvements
Message-ID: <20220114105653.3003399-1-mark.rutland@arm.com>

This series reworks the aarch64 boot-wrapper, moving a fair amount of
initialization code to C. This has a few benefits:

1) This makes the code more legible and easier to maintain.

    Current feature detection and system register configuration is
    written in assembly, requiring runs of *almost* identical blocks of
    assembly to read ID registers and conditionally initialize register
    values. This requires a bunch of labels (which are all named
    numerically), and all the magic numbers are hard coded, so this gets
    pretty painful to read:
    
    |	mrs	x1, id_aa64isar0_el1
    |	ubfx	x1, x1, #24, #4
    |	cbz	x1, 1f
    |
    |	orr	x0, x0, #(1 << 34)		// TME enable
    |
    | 1:
    
    In C, it's much easier to add helpers which use mnemonics, which
    makes the code much easier to read, and avoids the need to manually
    allocate registers, etc:
    
    |	if (mrs_field(ID_AA64ISAR0_EL1, TME))
    |		scr |= SCR_EL3_TME;

    This should make it easier to handle new architectural extensions
    (and/or architecture variants such as ARMv8-R) in future.
    
2) This allows for better diagnostics.

    Currently a mis-configured boot-wrapper is rather unforgiving, and
    provides no indication as to what might have gone wrong. By moving
    initialization to C, we can make use to the UART code to log
    diagnostic information, and we can more easily add additional error
    handling and conditional logic.
    
    This series adds diagnostic information and error handling that can
    be used to identify problems such as the boot-wrapper being launched
    at the wrong exception level:
    
    | Boot-wrapper v0.2
    | Entered at EL2
    | Memory layout:
    | [0000000080000000..0000000080001f90] => boot-wrapper
    | [000000008000fff8..0000000080010000] => mbox
    | [0000000080200000..00000000822af200] => kernel
    | [0000000088000000..0000000088002857] => dtb
    |
    | WARNING: PSCI could not be initialized. Boot may fail

Originally I had planned for this to be a more expansive set of changes,
unifying some early control-flow, fixing some latent bugs, and making
the boot-wrapper dynamically handle being entered at any of EL{3,2,1}
with automated selection of a suitable DT. As the series has already
become pretty long, I'd like to get this preparatory cleanup out of the
way first, and handle those cases with subsequent patches.

If there are no objections, I intend to apply these by the end of the
day.

I've pushed the series to the `cleanup` branch in the boot-wrapper repo:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git/
  git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

... and it should apply cleanup atop the `master` branch.

Since v1 [1]:
* Add comments for bit-field macros
* Use BIT() for *_RES1 definitions
* Complete start_el3/start_no_el3 cleanup
* Remove extraneous macro definition

[1] https://lore.kernel.org/r/20220111130653.2331827-1-mark.rutland at arm.com/

Thanks,
Mark.

Mark Rutland (13):
  Document entry requirements
  Add bit-field macros
  aarch64: add system register accessors
  aarch32: add coprocessor accessors
  aarch64: add mov_64 macro
  aarch64: initialize SCTLR_ELx for the boot-wrapper
  Rework common init C code
  Announce boot-wrapper mode / exception level
  aarch64: move the bulk of EL3 initialization to C
  aarch32: move the bulk of Secure PL1 initialization to C
  Announce locations of memory objects
  Rework bootmethod initialization
  Unify start_el3 & start_no_el3

 Makefile.am                       |   6 +-
 arch/aarch32/boot.S               |  33 +++---
 arch/aarch32/include/asm/cpu.h    |  62 ++++++++---
 arch/aarch32/include/asm/gic-v3.h |   6 +-
 arch/aarch32/include/asm/psci.h   |  28 +++++
 arch/aarch32/init.c               |  42 ++++++++
 arch/aarch32/psci.S               |  16 +--
 arch/aarch32/utils.S              |   9 --
 arch/aarch64/boot.S               | 169 +++++++++++++-----------------
 arch/aarch64/common.S             |  10 +-
 arch/aarch64/include/asm/cpu.h    | 102 +++++++++++++++---
 arch/aarch64/include/asm/gic-v3.h |  10 +-
 arch/aarch64/include/asm/psci.h   |  28 +++++
 arch/aarch64/init.c               |  88 ++++++++++++++++
 arch/aarch64/psci.S               |  22 +---
 arch/aarch64/spin.S               |   6 +-
 arch/aarch64/utils.S              |   9 --
 common/boot.c                     |   4 -
 common/init.c                     |  60 +++++++++++
 common/platform.c                 |  45 +++++---
 common/psci.c                     |  22 +++-
 include/bits.h                    |  79 ++++++++++++++
 include/boot.h                    |   2 +
 include/platform.h                |  20 ++++
 model.lds.S                       |  20 ++--
 25 files changed, 668 insertions(+), 230 deletions(-)
 create mode 100644 arch/aarch32/include/asm/psci.h
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/include/asm/psci.h
 create mode 100644 arch/aarch64/init.c
 create mode 100644 common/init.c
 create mode 100644 include/bits.h
 create mode 100644 include/platform.h

-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:41 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:41 +0000
Subject: [bootwrapper PATCH v2 01/13] Document entry requirements
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-2-mark.rutland@arm.com>

Currently the boot-wrapper only supports some combinations of exception
levels, with other combinations not being supported.

While we generally expect the boot-wrapper to be entered at the highest
implemented exception level, the AArch32 boot-wrapper has a comment
implying it supports being entered with something else owning EL3. As
this would require such EL3 firmware to always be in sync with the
boot-wrapper's requirements, which change over time, we don't actually
support such a configuration.

Some CPU state (such as CNTFRQ/CNTFRQ_EL0) needs to be initialized at
the highest implemented exception level, but today the boot-wrapper only
does so when entered at EL3 / Secure-PL1. Thus, today the only
completely supported configurations are EL3 / Secure-PL1, and entering
in other configurations is not entirely supported.

The aarch64 `jump_kernel` function always writes to SCTLR_EL2, which is
UNDEFINED at EL1. Hence, the aarch64 boot-wrapper does not support being
entered at EL1.

The aarch32 code assumes that any non-hyp mode is Secure PL1, and
attempt to switch to monitor mode. If entered on a system without the
security extensions, where the highest privileged mode is Non-secure
PL1, this will not work. Hence the aarch32 boot-wrapper does not support
being entered at Non-secure PL1.

Actually supporting all of these configurations requires restructuring
much of the boot-wrapper. For now, document the supported configurations
in each architecture's boot.S, and remove the misleading comment from
arch/aarch32/boot.S. Subsequent patches will improve the support and add
support for additional configurations.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 14 ++++++++++++++
 arch/aarch32/psci.S |  5 -----
 arch/aarch64/boot.S | 13 +++++++++++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 4add338..00c432d 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -16,6 +16,20 @@
 	.arch_extension virt
 
 	.section .init
+
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered in the following modes:
+	 *
+	 * - PL1 / EL3 (Secure) Supervisor mode
+	 *   Entering in this mode is strongly recommended.
+	 *   PL2 must be implemented.
+	 *
+	 * - PL2 / EL2 (Non-secure) Hypervisor mode
+	 *   Entering in this mode is partially supported.
+	 *   PSCI is not supported when entered in this mode.
+	 */
 ASM_FUNC(_start)
 	/* Stack initialisation */
 	cpuid	r0, r1
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index dc7aeb7..e0d2972 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -44,11 +44,6 @@ ASM_FUNC(start_el3)
 	/* pass through */
 
 ASM_FUNC(start_no_el3)
-	/*
-	 * For no-el3, we assume that firmware launched the boot-wrapper in
-	 * non-secure EL2 or EL1. We assume it has its own PSCI implementation
-	 * sitting at EL3, and that this path is only taken by primary CPU.
-	 */
 	cpuid	r0, r1
 	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 27ba449..900b9f8 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -12,6 +12,19 @@
 
 	.section .init
 
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered at the following exception levels:
+	 *
+	 * - EL3 (Secure)
+	 *   Entering at EL3 is strongly recommended.
+	 *   EL2 must be implemented.
+	 *
+	 * - EL2 (Non-secure)
+	 *   Entering at EL2 is partially supported.
+	 *   PSCI is not supported when entered in this exception level.
+	 */
 ASM_FUNC(_start)
 	cpuid	x0, x1
 	bl	find_logical_id
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:42 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:42 +0000
Subject: [bootwrapper PATCH v2 02/13] Add bit-field macros
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-3-mark.rutland@arm.com>

Arm architectural documentation typically defines bit-fields as
`[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
helpful if we could define fields in the same way.

Add helpers so that we can do so, along with helper to extract/insert
bit-field values.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 include/bits.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 include/bits.h

diff --git a/include/bits.h b/include/bits.h
new file mode 100644
index 0000000..0bf2c67
--- /dev/null
+++ b/include/bits.h
@@ -0,0 +1,79 @@
+/*
+ * include/bits.h - helpers for bit-field definitions.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __BITS_H
+#define __BITS_H
+
+#ifdef __ASSEMBLY__
+#define UL(x)	x
+#define ULL(x)	x
+#else
+#define UL(x)	x##UL
+#define ULL(x)	x##ULL
+#endif
+
+/*
+ * Define a contiguous mask of bits with `msb` as the most significant bit and
+ * `lsb` as the least significant bit. The `msb` value must be greater than or
+ * equal to `lsb`.
+ *
+ * For example:
+ * - BITS(63, 63) is 0x8000000000000000
+ * - BITS(63, 0)  is 0xFFFFFFFFFFFFFFFF
+ * - BITS(0, 0)   is 0x0000000000000001
+ * - BITS(49, 17) is 0x0001FFFFFFFE0000
+ */
+#define BITS(msb, lsb) \
+	((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
+
+/*
+ * Define a mask of a single set bit `b`.
+ *
+ * For example:
+ * - BIT(63) is 0x8000000000000000
+ * - BIT(0)  is 0x0000000000000001
+ * - BIT(32) is 0x0000000100000000
+ */
+#define BIT(b)	BITS(b, b)
+
+/*
+ * Find the least significant set bit in the contiguous set of bits in `mask`.
+ *
+ * For example:
+ * - BITS_LSB(0x0000000000000001) is 0
+ * - BITS_LSB(0x000000000000ff00) is 8
+ * - BITS_LSB(0x8000000000000000) is 63
+ */
+#define BITS_LSB(mask)	(__builtin_ffsll(mask) - 1)
+
+/*
+ * Extract a bit-field out of `val` described by the contiguous set of bits in
+ * `mask`.
+ *
+ * For example:
+ * - BITS_EXTRACT(0xABCD, BITS(15, 12)) is 0xA
+ * - BITS_EXTRACT(0xABCD, BITS(11, 8))  is 0xB
+ * - BITS_EXTRACT(0xABCD, BIT(7))       is 0x1
+ */
+#define BITS_EXTRACT(val, mask) \
+	(((val) & (mask)) >> BITS_LSB(mask))
+
+/*
+ * Insert the least significant bits of `val` into the bit-field described by
+ * the contiguous set of bits in `mask`.
+ *
+ * For example:
+ * - BITS_INSERT(BITS(3, 0), 0xA)   is 0x000A
+ * - BITS_INSERT(BITS(15, 12), 0xA) is 0xA000
+ * - BITS_INSERT(BIT(15), 0xF)      is 0x1000
+ *
+ */
+#define BITS_INSERT(mask, val) \
+	(((val) << BITS_LSB(mask)) & (mask))
+
+#endif
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:43 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:43 +0000
Subject: [bootwrapper PATCH v2 03/13] aarch64: add system register accessors
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-4-mark.rutland@arm.com>

We open code the use of mrs/msr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/include/asm/cpu.h    | 41 ++++++++++++++++++++++---------
 arch/aarch64/include/asm/gic-v3.h | 10 +++-----
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 63eb1c3..1053414 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -9,10 +9,14 @@
 #ifndef __ASM_AARCH64_CPU_H
 #define __ASM_AARCH64_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
 
+#define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
+
 /*
  * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
  * no WXN.
@@ -29,6 +33,12 @@
 
 #define CPTR_EL3_EZ		(1 << 8)
 
+#define ICC_SRE_EL2		S3_4_C12_C9_5
+#define ICC_SRE_EL3		S3_6_C12_C12_5
+#define ICC_CTLR_EL1		S3_0_C12_C12_4
+#define ICC_CTLR_EL3		S3_6_C12_C12_4
+#define ICC_PMR_EL1		S3_0_C4_C6_0
+
 #define ZCR_EL3			s3_6_c1_c2_0
 #define ZCR_EL3_LEN_MASK	0x1ff
 
@@ -50,20 +60,27 @@
 
 #define sevl()		asm volatile ("sevl\n" : : : "memory")
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define __str(def)	#def
 
-	asm volatile ("mrs	%0, mpidr_el1\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define mrs(reg)							\
+({									\
+	unsigned long __mrs_val;					\
+	asm volatile("mrs %0, " __str(reg) : "=r" (__mrs_val));		\
+	__mrs_val;							\
+})
 
-static inline uint64_t read_id_aa64pfr0(void)
-{
-	uint64_t val;
+#define msr(reg, val)							\
+do {									\
+	unsigned long __msr_val = val;					\
+	asm volatile("msr " __str(reg) ", %0" : : "r" (__msr_val));	\
+} while (0)
+
+#define mrs_field(reg, field) \
+	BITS_EXTRACT(mrs(reg), (reg##_##field))
 
-	asm volatile ("mrs	%0, id_aa64pfr0_el1\n" : "=r" (val));
-	return val;
+static inline unsigned long read_mpidr(void)
+{
+	return mrs(mpidr_el1) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
@@ -73,7 +90,7 @@ static inline void iciallu(void)
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_aa64pfr0() >> 24) & 0xf);
+	return !!mrs_field(ID_AA64PFR0_EL1, GIC);
 }
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
index 5b32380..2447480 100644
--- a/arch/aarch64/include/asm/gic-v3.h
+++ b/arch/aarch64/include/asm/gic-v3.h
@@ -9,20 +9,16 @@
 #ifndef __ASM_AARCH64_GICV3_H
 #define __ASM_AARCH64_GICV3_H
 
-#define ICC_SRE_EL2	"S3_4_C12_C9_5"
-#define ICC_SRE_EL3	"S3_6_C12_C12_5"
-#define ICC_CTLR_EL1	"S3_0_C12_C12_4"
-#define ICC_CTLR_EL3	"S3_6_C12_C12_4"
-#define ICC_PMR_EL1	"S3_0_C4_C6_0"
+#include <asm/cpu.h>
 
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
+	msr(ICC_SRE_EL3, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
+	msr(ICC_CTLR_EL3, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:44 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:44 +0000
Subject: [bootwrapper PATCH v2 04/13] aarch32: add coprocessor accessors
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-5-mark.rutland@arm.com>

We open code the use of mrc/mcr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h    | 45 ++++++++++++++++++++-----------
 arch/aarch32/include/asm/gic-v3.h |  6 +++--
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index 105cae5..d691c7b 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -9,9 +9,13 @@
 #ifndef __ASM_AARCH32_CPU_H
 #define __ASM_AARCH32_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0x00ffffff
 #define MPIDR_INVALID		(-1)
 
+#define ID_PFR1_GIC		BITS(31, 28)
+
 /* Only RES1 bits and CP15 barriers for the kernel */
 #define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
 #define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
@@ -40,32 +44,43 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define MPIDR		"p15, 0, %0, c0, c0, 5"
+#define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
-	asm volatile ("mrc	p15, 0, %0, c0, c0, 5\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define ICC_SRE		"p15, 6, %0, c12, c12, 5"
+#define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
-static inline uint32_t read_id_pfr1(void)
-{
-	uint32_t val;
+#define mrc(reg)						\
+({								\
+	unsigned long __mrc_val;				\
+	asm volatile("mrc " reg : "=r" (__mrc_val));		\
+	__mrc_val;						\
+})
 
-	asm volatile ("mrc	p15, 0, %0, c0, c1, 1\n" : "=r" (val));
-	return val;
+#define mcr(reg, val)						\
+do {								\
+	unsigned long __mcr_val = val;				\
+	asm volatile("mcr " reg : : "r" (__mcr_val));		\
+} while (0)
+
+
+#define mrc_field(reg, field) \
+	BITS_EXTRACT(mrc(reg), (reg##_##field))
+
+static inline unsigned long read_mpidr(void)
+{
+	return mrc(MPIDR) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
 {
-	uint32_t val = 0;
-
-	asm volatile ("mcr	p15, 0, %0, c7, c5, 0" : : "r" (val));
+	mcr(ICIALLU, 0);
 }
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_pfr1() >> 28) & 0xf);
+	return !!mrc_field(ID_PFR1, GIC);
 }
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
index 65f38de..b28136a 100644
--- a/arch/aarch32/include/asm/gic-v3.h
+++ b/arch/aarch32/include/asm/gic-v3.h
@@ -9,14 +9,16 @@
 #ifndef __ASM_AARCH32_GICV3_H
 #define __ASM_AARCH32_GICV3_H
 
+#include <asm/cpu.h>
+
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
+	mcr(ICC_SRE, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
+	mcr(ICC_CTLR, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:45 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:45 +0000
Subject: [bootwrapper PATCH v2 05/13] aarch64: add mov_64 macro
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-6-mark.rutland@arm.com>

In subsequent patches we'll need to load 64-bit values into GPRs before
the CPU is in a known endianness, where we cannot use literal pools.

In preparation for that, this patch adds a new `mov_64` macro to load a
64-bit value into a GPR using a sequence of MOV and MOVKs, which will
function the same regardless of the CPU's endianness.

At the same time, move the `cpuid` macro to use `mov_64` internally.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/common.S | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
index c7171a9..3279fa9 100644
--- a/arch/aarch64/common.S
+++ b/arch/aarch64/common.S
@@ -9,9 +9,17 @@
 
 #include <cpu.h>
 
+	/* Load a 64-bit value using immediates */
+	.macro	mov_64 dest, val
+	mov	\dest, #(((\val) >>  0) & 0xffff)
+	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
+	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
+	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
+	.endm
+
 	/* Put MPIDR into \dest, clobber \tmp and flags */
 	.macro cpuid dest, tmp
 	mrs	\dest, mpidr_el1
-	ldr	\tmp, =MPIDR_ID_BITS
+	mov_64	\tmp, MPIDR_ID_BITS
 	ands	\dest, \dest, \tmp
 	.endm
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:46 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:46 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for the
 boot-wrapper
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-7-mark.rutland@arm.com>

The SCTLR_ELx registers contain fields which are UNKNOWN or
IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
defines the endianness of memory accesses (e.g. reads from literal
pools). Due to this, portions of boot-wrapper code are not guaranteed
to work correctly.

Rework the startup code to explicitly initialize SCTLR_ELx for the
exception level the boot-wrapper was entered at. When entered at EL2
it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
which would break the initialization performed in jump_kernel.

As we plan to eventually support the highest implemented EL being any of
EL3/EL2/EL1, code is added to handle all of these exception levels, even
though we do not currently support starting at EL1.

We'll initialize other registers in subsequent patches.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
 arch/aarch64/include/asm/cpu.h | 27 ++++++++++++-
 2 files changed, 85 insertions(+), 16 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 900b9f8..45a0367 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -26,26 +26,26 @@
 	 *   PSCI is not supported when entered in this exception level.
 	 */
 ASM_FUNC(_start)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cmp	x0, #MPIDR_INVALID
-	beq	err_invalid_id
-	bl	setup_stack
-
-	/*
-	 * EL3 initialisation
-	 */
 	mrs	x0, CurrentEL
 	cmp	x0, #CURRENTEL_EL3
-	b.eq	1f
+	b.eq	reset_at_el3
+	cmp	x0, #CURRENTEL_EL2
+	b.eq	reset_at_el2
+	cmp	x0, #CURRENTEL_EL1
+	b.eq	reset_at_el1
 
-	mov	w0, #1
-	ldr	x1, =flag_no_el3
-	str	w0, [x1]
+	/* Booting at EL0 is not supported */
+	b	.
 
-	b	start_no_el3
+	/*
+	 * EL3 initialisation
+	 */
+reset_at_el3:
+	mov_64	x0, SCTLR_EL3_RESET
+	msr	sctlr_el3, x0
+	isb
 
-1:	mov	x0, #0x30			// RES1
+	mov	x0, #0x30			// RES1
 	orr	x0, x0, #(1 << 0)		// Non-secure EL1
 	orr	x0, x0, #(1 << 8)		// HVC enable
 
@@ -135,10 +135,54 @@ ASM_FUNC(_start)
 	ldr	x0, =COUNTER_FREQ
 	msr	cntfrq_el0, x0
 
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
 	bl	gic_secure_init
 
 	b	start_el3
 
+	/*
+	 * EL2 initialization
+	 */
+reset_at_el2:
+	// Ensure E2H is not in use
+	mov_64	x0, HCR_EL2_RESET
+	msr	hcr_el2, x0
+	isb
+
+	mov_64	x0, SCTLR_EL2_RESET
+	msr	sctlr_el2, x0
+	isb
+
+	b	reset_no_el3
+
+	/*
+	 * EL1 initialization
+	 */
+reset_at_el1:
+	mov_64	x0, SCTLR_EL1_RESET
+	msr	sctlr_el1, x0
+	isb
+
+	b	reset_no_el3
+
+reset_no_el3:
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
+	mov	w0, #1
+	ldr	x1, =flag_no_el3
+	str	w0, [x1]
+
+	b	start_no_el3
+
 err_invalid_id:
 	b	.
 
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 1053414..1e9141a 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -14,6 +14,32 @@
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
+#define CURRENTEL_EL2		(2 << 2)
+#define CURRENTEL_EL1		(1 << 2)
+
+/*
+ * RES1 bit definitions definitions as of ARM DDI 0487G.b
+ *
+ * These includes bits which are RES1 in some configurations.
+ */
+#define SCTLR_EL3_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
+				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))
+
+#define SCTLR_EL2_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
+				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))
+
+#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
+				 BIT(11) | BIT(8) | BIT(7) | BIT(4))
+
+#define HCR_EL2_RES1		(BIT(1))
+
+/*
+ * Initial register values required for the boot-wrapper to run out-of-reset.
+ */
+#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
+#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
+#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
+#define HCR_EL2_RESET		HCR_EL2_RES1
 
 #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
 
@@ -43,7 +69,6 @@
 #define ZCR_EL3_LEN_MASK	0x1ff
 
 #define SCTLR_EL1_CP15BEN	(1 << 5)
-#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
 
 #ifdef KERNEL_32
 /* 32-bit kernel decompressor uses CP15 barriers */
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:47 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:47 +0000
Subject: [bootwrapper PATCH v2 07/13] Rework common init C code
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-8-mark.rutland@arm.com>

In init_platform() we initialize a UART and announce the presence of the
bootwrapper to the world. We do this relatively late in the boot-flow,
and prior to this will silently ignore errors (e.g. in gic_secure_init).

To make it possible to provide improved diagnostics, and to allow us to
move more initialization into C, this patch reworks the init code to
call a C function earlier, where we can announce the presence of the
boot-wrapper and perform other initialization.

In subsequent patches this will be expanded with more CPU
initialization.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am         |  2 +-
 arch/aarch32/boot.S |  5 +++++
 arch/aarch64/boot.S |  4 ++++
 common/boot.c       |  4 ----
 common/init.c       | 24 ++++++++++++++++++++++++
 common/platform.c   | 12 +++++++-----
 include/platform.h  | 17 +++++++++++++++++
 7 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 common/init.c
 create mode 100644 include/platform.h

diff --git a/Makefile.am b/Makefile.am
index f941b07..0651c38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ endif
 PSCI_CPU_OFF	:= 0x84000002
 
 COMMON_SRC	:= common/
-COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o
+COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
 ARCH_OBJ	:= boot.o stack.o utils.o
 
diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 00c432d..ee073ea 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -48,6 +48,9 @@ ASM_FUNC(_start)
 	mov	r0, #1
 	ldr	r1, =flag_no_el3
 	str	r0, [r1]
+
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 _switch_monitor:
@@ -71,6 +74,8 @@ _monitor:
 	ldr	r0, =COUNTER_FREQ
 	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	/* Initialise boot method */
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 45a0367..17b4a75 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -141,6 +141,8 @@ reset_at_el3:
 	b.eq	err_invalid_id
 	bl	setup_stack
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	b	start_el3
@@ -181,6 +183,8 @@ reset_no_el3:
 	ldr	x1, =flag_no_el3
 	str	w0, [x1]
 
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 err_invalid_id:
diff --git a/common/boot.c b/common/boot.c
index c74d34c..29d53a4 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -12,8 +12,6 @@
 extern unsigned long entrypoint;
 extern unsigned long dtb;
 
-void init_platform(void);
-
 void __noreturn jump_kernel(unsigned long address,
 			    unsigned long a0,
 			    unsigned long a1,
@@ -62,8 +60,6 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid)
 {
 	if (cpu == 0) {
-		init_platform();
-
 		*mbox = (unsigned long)&entrypoint;
 		sevl();
 		spin(mbox, invalid, 1);
diff --git a/common/init.c b/common/init.c
new file mode 100644
index 0000000..9c471c9
--- /dev/null
+++ b/common/init.c
@@ -0,0 +1,24 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+static void announce_bootwrapper(void)
+{
+	print_string("Boot-wrapper v0.2\r\n\r\n");
+}
+
+void cpu_init_bootwrapper(void)
+{
+	if (this_cpu_logical_id() == 0) {
+		init_uart();
+		announce_bootwrapper();
+		init_platform();
+	}
+}
diff --git a/common/platform.c b/common/platform.c
index d11f568..47bf547 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -1,5 +1,5 @@
 /*
- * platform.c - code to initialise everything required when first booting.
+ * platform.c - Platform initialization and I/O.
  *
  * Copyright (C) 2015 ARM Limited. All rights reserved.
  *
@@ -7,6 +7,7 @@
  * found in the LICENSE.txt file.
  */
 
+#include <cpu.h>
 #include <stdint.h>
 
 #include <asm/io.h>
@@ -30,7 +31,7 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-static void print_string(const char *str)
+void print_string(const char *str)
 {
 	uint32_t flags;
 
@@ -47,7 +48,7 @@ static void print_string(const char *str)
 	}
 }
 
-void init_platform(void)
+void init_uart(void)
 {
 	/*
 	 * UART initialisation (38400 8N1)
@@ -58,9 +59,10 @@ void init_platform(void)
 	raw_writel(0x70,	PL011(UART_LCR_H));
 	/* Enable the UART, TXen and RXen */
 	raw_writel(0x301,	PL011(UARTCR));
+}
 
-	print_string("Boot-wrapper v0.2\r\n\r\n");
-
+void init_platform(void)
+{
 #ifdef SYSREGS_BASE
 	/*
 	 * CLCD output site MB
diff --git a/include/platform.h b/include/platform.h
new file mode 100644
index 0000000..e5248e1
--- /dev/null
+++ b/include/platform.h
@@ -0,0 +1,17 @@
+/*
+ * include/platform.h - Platform initialization and I/O.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __PLATFORM_H
+#define __PLATFORM_H
+
+void print_string(const char *str);
+void init_uart(void);
+
+void init_platform(void);
+
+#endif /* __PLATFORM_H */
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:48 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:48 +0000
Subject: [bootwrapper PATCH v2 08/13] Announce boot-wrapper mode / exception
 level
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-9-mark.rutland@arm.com>

When something goes wrong within the boot-wrapper, it can be very
helpful to know where we started from. Add an arch_announce() function
to log this early in the boot process. More information can be added
here in future.

This is logged ot the serial console as:

| Boot-wrapper v0.2
| Entered at EL3

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |  2 +-
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 30 ++++++++++++++++++++++++++++++
 arch/aarch64/init.c            | 19 +++++++++++++++++++
 common/init.c                  |  6 +++++-
 common/platform.c              | 24 ++++++++++++++----------
 include/platform.h             |  1 +
 7 files changed, 79 insertions(+), 12 deletions(-)
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/init.c

diff --git a/Makefile.am b/Makefile.am
index 0651c38..885a77c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,7 +36,7 @@ PSCI_CPU_OFF	:= 0x84000002
 COMMON_SRC	:= common/
 COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
-ARCH_OBJ	:= boot.o stack.o utils.o
+ARCH_OBJ	:= boot.o stack.o utils.o init.o
 
 if BOOTWRAPPER_32
 CPPFLAGS	+= -DBOOTWRAPPER_32
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index d691c7b..aa72204 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -44,6 +44,15 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
+static inline unsigned long read_cpsr(void)
+{
+	unsigned long cpsr;
+	asm volatile ("mrs      %0, cpsr\n" : "=r" (cpsr));
+	return cpsr;
+}
+
+#define read_cpsr_mode()       (read_cpsr() & PSR_MODE_MASK)
+
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
new file mode 100644
index 0000000..b29ebb4
--- /dev/null
+++ b/arch/aarch32/init.c
@@ -0,0 +1,30 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <platform.h>
+
+#include <asm/cpu.h>
+
+static const char *mode_string(void)
+{
+	switch (read_cpsr_mode()) {
+	case PSR_MON:
+		return "PL1";
+	case PSR_HYP:
+		return "PL2 (Non-secure)";
+	default:
+		return "<UNKNOWN MODE>";
+	}
+}
+
+void announce_arch(void)
+{
+	print_string("Entered at ");
+	print_string(mode_string());
+	print_string("\r\n");
+}
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
new file mode 100644
index 0000000..82816e7
--- /dev/null
+++ b/arch/aarch64/init.c
@@ -0,0 +1,19 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+void announce_arch(void)
+{
+	unsigned char el = mrs(CurrentEl) >> 2;
+
+	print_string("Entered at EL");
+	print_char('0' + el);
+	print_string("\r\n");
+}
diff --git a/common/init.c b/common/init.c
index 9c471c9..2600f73 100644
--- a/common/init.c
+++ b/common/init.c
@@ -11,14 +11,18 @@
 
 static void announce_bootwrapper(void)
 {
-	print_string("Boot-wrapper v0.2\r\n\r\n");
+	print_string("Boot-wrapper v0.2\r\n");
 }
 
+void announce_arch(void);
+
 void cpu_init_bootwrapper(void)
 {
 	if (this_cpu_logical_id() == 0) {
 		init_uart();
 		announce_bootwrapper();
+		announce_arch();
+		print_string("\r\n");
 		init_platform();
 	}
 }
diff --git a/common/platform.c b/common/platform.c
index 47bf547..80d0562 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -31,21 +31,25 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-void print_string(const char *str)
+void print_char(char c)
 {
 	uint32_t flags;
 
-	while (*str) {
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_FIFO_FULL);
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_FIFO_FULL);
+
+	raw_writel(c, PL011(UARTDR));
 
-		raw_writel(*str++, PL011(UARTDR));
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_BUSY);
+}
 
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_BUSY);
-	}
+void print_string(const char *str)
+{
+	while (*str)
+		print_char(*str++);
 }
 
 void init_uart(void)
diff --git a/include/platform.h b/include/platform.h
index e5248e1..237b481 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -9,6 +9,7 @@
 #ifndef __PLATFORM_H
 #define __PLATFORM_H
 
+void print_char(char c);
 void print_string(const char *str);
 void init_uart(void);
 
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:49 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:49 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-10-mark.rutland@arm.com>

The majority of state that we initialize at EL3 is necessary for code at
lower ELs to function, but isnt' necessary for the boot-wrapper itself.
Given that, it would be better to write this in C where it can be
written mode clearly, and where it will be possible to add logging/debug
logic.

This patch migrates the AArch64 EL3 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |  2 +-
 arch/aarch64/boot.S            | 92 +---------------------------------
 arch/aarch64/include/asm/cpu.h | 36 ++++++++++++-
 arch/aarch64/init.c            | 69 +++++++++++++++++++++++++
 4 files changed, 107 insertions(+), 92 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 885a77c..a598b95 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,7 +153,7 @@ $(COMMON_SRC):
 %.o: %.S Makefile | $(ARCH_SRC)
 	$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
 
-%.o: %.c Makefile | $(COMMON_SRC)
+%.o: %.c Makefile | $(ARCH_SRC) $(COMMON_SRC)
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
 model.lds: $(LD_SCRIPT) Makefile
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 17b4a75..c0ec518 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -45,96 +45,6 @@ reset_at_el3:
 	msr	sctlr_el3, x0
 	isb
 
-	mov	x0, #0x30			// RES1
-	orr	x0, x0, #(1 << 0)		// Non-secure EL1
-	orr	x0, x0, #(1 << 8)		// HVC enable
-
-	/* Enable pointer authentication if present */
-	mrs	x1, id_aa64isar1_el1
-	/* We check for APA+API and GPA+GPI */
-	ldr	x2, =((0xff << 24) | (0xff << 4))
-	and	x1, x1, x2
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 16)		// AP key enable
-	orr	x0, x0, #(1 << 17)		// AP insn enable
-1:
-	/* Enable TME if present */
-	mrs	x1, id_aa64isar0_el1
-	ubfx	x1, x1, #24, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 34)		// TME enable
-1:
-	/* Enable FGT if present */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #56, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 27)		// FGT enable
-1:
-	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #60, #4
-	cmp	x1, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 28)		// ECV enable
-1:
-	/* Enable MTE if present */
-	mrs	x10, id_aa64pfr1_el1
-	ubfx	x10, x10, #8, #4
-	cmp	x10, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 26)		// ATA enable
-1:
-#ifndef KERNEL_32
-	orr	x0, x0, #(1 << 10)		// 64-bit EL2
-#endif
-	msr	scr_el3, x0
-
-	msr	cptr_el3, xzr			// Disable copro. traps to EL3
-
-	mov	x0, xzr
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #32, #4
-	cbz	x1, 1f
-
-	// Enable SPE for the non-secure world.
-	orr	x0, x0, #(0x3 << 12)
-
-	// Do not trap PMSNEVFR_EL1 if present
-	cmp	x1, #3
-	b.lt	1f
-	orr	x0, x0, #(1 << 36)
-
-1:	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #44, #4
-	cbz	x1, 1f
-
-	// Enable TRBE for the non-secure world.
-	ldr	x1, =(0x3 << 24)
-	orr	x0, x0, x1
-
-1:	msr	mdcr_el3, x0			// Disable traps to EL3
-
-	mrs	x0, id_aa64pfr0_el1
-	ubfx	x0, x0, #32, #4			// SVE present?
-	cbz	x0, 1f				// Skip SVE init if not
-
-	mrs	x0, cptr_el3
-	orr	x0, x0, #CPTR_EL3_EZ		// enable SVE
-	msr	cptr_el3, x0
-	isb
-
-	mov	x0, #ZCR_EL3_LEN_MASK		// SVE: Enable full vector len
-	msr	ZCR_EL3, x0			// for EL2.
-
-1:
-	ldr	x0, =COUNTER_FREQ
-	msr	cntfrq_el0, x0
-
 	cpuid	x0, x1
 	bl	find_logical_id
 	cmp	x0, #MPIDR_INVALID
@@ -143,6 +53,8 @@ reset_at_el3:
 
 	bl	cpu_init_bootwrapper
 
+	bl	cpu_init_el3
+
 	bl	gic_secure_init
 
 	b	start_el3
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 1e9141a..e078ae4 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -31,7 +31,41 @@
 #define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
 				 BIT(11) | BIT(8) | BIT(7) | BIT(4))
 
-#define HCR_EL2_RES1		(BIT(1))
+#define ZCR_EL3				s3_6_c1_c2_0
+#define ZCR_EL3_LEN			BITS(3, 1)
+
+#define MDCR_EL3_NSPB_NS_NOTRAP		(UL(3) << 12)
+#define MDCR_EL3_NSTB_NS_NOTRAP		(UL(3) << 24)
+#define MDCR_EL3_ENPMSN			BIT(36)
+
+#define SCR_EL3_RES1			BITS(5, 4)
+#define SCR_EL3_NS			BIT(0)
+#define SCR_EL3_HCE			BIT(8)
+#define SCR_EL3_RW			BIT(10)
+#define SCR_EL3_APK			BIT(16)
+#define SCR_EL3_API			BIT(17)
+#define SCR_EL3_ATA			BIT(26)
+#define SCR_EL3_FGTEN			BIT(27)
+#define SCR_EL3_ECVEN			BIT(28)
+#define SCR_EL3_TME			BIT(34)
+
+#define HCR_EL2_RES1			BIT(1)
+
+#define ID_AA64DFR0_EL1_PMSVER		BITS(35, 32)
+#define ID_AA64DFR0_EL1_TRACEBUFFER	BITS(47, 44)
+
+#define ID_AA64ISAR0_EL1_TME		BITS(27, 24)
+
+#define ID_AA64ISAR1_EL1_APA		BITS(7, 4)
+#define ID_AA64ISAR1_EL1_API		BITS(11, 8)
+#define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
+#define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
+
+#define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
+#define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
+
+#define ID_AA64PFR1_EL1_MTE		BITS(11, 8)
+#define ID_AA64PFR0_EL1_SVE		BITS(35, 32)
 
 /*
  * Initial register values required for the boot-wrapper to run out-of-reset.
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 82816e7..ded9871 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -8,6 +8,7 @@
  */
 #include <cpu.h>
 #include <platform.h>
+#include <stdbool.h>
 
 void announce_arch(void)
 {
@@ -17,3 +18,71 @@ void announce_arch(void)
 	print_char('0' + el);
 	print_string("\r\n");
 }
+
+static inline bool kernel_is_32bit(void)
+{
+#ifdef KERNEL_32
+	return true;
+#else
+	return false;
+#endif
+}
+
+static inline bool cpu_has_pauth(void)
+{
+	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
+				       ID_AA64ISAR1_EL1_API |
+				       ID_AA64ISAR1_EL1_GPA |
+				       ID_AA64ISAR1_EL1_GPI;
+
+	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
+}
+
+void cpu_init_el3(void)
+{
+	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
+	unsigned long mdcr = 0;
+	unsigned long cptr = 0;
+
+	if (cpu_has_pauth())
+		scr |= SCR_EL3_APK | SCR_EL3_API;
+
+	if (mrs_field(ID_AA64ISAR0_EL1, TME))
+		scr |= SCR_EL3_TME;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
+		scr |= SCR_EL3_FGTEN;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
+		scr |= SCR_EL3_ECVEN;
+
+	if (mrs_field(ID_AA64PFR1_EL1, MTE))
+		scr |= SCR_EL3_ATA;
+
+	if (!kernel_is_32bit())
+		scr |= SCR_EL3_RW;
+
+	msr(SCR_EL3, scr);
+
+	msr(CPTR_EL3, cptr);
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER))
+		mdcr |= MDCR_EL3_NSPB_NS_NOTRAP;
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER) >= 3)
+		mdcr |= MDCR_EL3_ENPMSN;
+
+	if (mrs_field(ID_AA64DFR0_EL1, TRACEBUFFER))
+		mdcr |= MDCR_EL3_NSTB_NS_NOTRAP;
+
+	msr(MDCR_EL3, mdcr);
+
+	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
+		cptr |= CPTR_EL3_EZ;
+		msr(CPTR_EL3, cptr);
+		isb();
+		msr(ZCR_EL3, ZCR_EL3_LEN);
+	}
+
+	msr(CNTFRQ_EL0, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:50 +0000
Subject: [bootwrapper PATCH v2 10/13] aarch32: move the bulk of Secure PL1
 initialization to C
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-11-mark.rutland@arm.com>

The majority of state that we initialize at Secure PL1 is necessary for
code at lower PLs to function, but isnt' necessary for the boot-wrapper
itself.  Given that, it would be better to write this in C where it can
be written mode clearly, and where it will be possible to add
logging/debug logic.

This patch migrates the AArch32 Secure PL1 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S            | 11 +----------
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 12 ++++++++++++
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index ee073ea..820957b 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -63,16 +63,7 @@ _monitor:
 	/* Move the stack to Monitor mode*/
 	mrs	sp, sp_svc
 
-	/* Setup secure registers and devices */
-	mov	r0, #1				@ Non-secure lower level
-	orr	r0, #(1 << 8)			@ HVC enable
-	mcr	p15, 0, r0, c1, c1, 0		@ SCR
-
-	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
-	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
-
-	ldr	r0, =COUNTER_FREQ
-	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
+	bl	cpu_init_secure_pl1
 
 	bl	cpu_init_bootwrapper
 
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index aa72204..c1bce9a 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -30,6 +30,11 @@
 #define PSR_I			(1 << 7)
 #define PSR_A			(1 << 8)
 
+#define SCR_NS			BIT(0)
+#define SCR_HCE			BIT(8)
+
+#define NSACR_CP10		BIT(10)
+#define NSACR_CP11		BIT(11)
 
 #define SPSR_KERNEL		(PSR_A | PSR_I | PSR_F | PSR_HYP)
 
@@ -55,11 +60,15 @@ static inline unsigned long read_cpsr(void)
 
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define SCR		"p15, 0, %0, c1, c1, 0"
+#define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
+#define CNTFRQ		"p15, 0, %0, c14, c0, 0"
+
 #define mrc(reg)						\
 ({								\
 	unsigned long __mrc_val;				\
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
index b29ebb4..5b69dcd 100644
--- a/arch/aarch32/init.c
+++ b/arch/aarch32/init.c
@@ -28,3 +28,15 @@ void announce_arch(void)
 	print_string(mode_string());
 	print_string("\r\n");
 }
+
+void cpu_init_secure_pl1(void)
+{
+	unsigned long scr = SCR_NS | SCR_HCE;
+	unsigned long nsacr = NSACR_CP10 | NSACR_CP11;
+
+	mcr(SCR, scr);
+
+	mcr(NSACR, nsacr);
+
+	mcr(CNTFRQ, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:51 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-12-mark.rutland@arm.com>

To make it easier to debug boot failures, log the location of memory
objects at boot time.

This is logged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL3
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 common/init.c      | 27 +++++++++++++++++++++++++++
 common/platform.c  | 13 +++++++++++++
 include/platform.h |  2 ++
 model.lds.S        | 20 ++++++++++++++------
 4 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/common/init.c b/common/init.c
index 2600f73..fc74b9e 100644
--- a/common/init.c
+++ b/common/init.c
@@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
 	print_string("Boot-wrapper v0.2\r\n");
 }
 
+#define announce_object(object, desc)				\
+do {								\
+	extern char object##__start[];				\
+	extern char object##__end[];				\
+	print_string("[");					\
+	print_ulong_hex((unsigned long)object##__start);	\
+	print_string("..");					\
+	print_ulong_hex((unsigned long)object##__end);		\
+	print_string("] => " desc "\r\n");			\
+} while (0)
+
+static void announce_objects(void)
+{
+	print_string("Memory layout:\r\n");
+	announce_object(text, "boot-wrapper");
+	announce_object(mbox, "mbox");
+	announce_object(kernel, "kernel");
+#ifdef XEN
+	announce_object(xen, "xen");
+#endif
+	announce_object(dtb, "dtb");
+#ifdef USE_INITRD
+	announce_object(filesystem, "initrd");
+#endif
+}
+
 void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
@@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
+		announce_objects();
 		print_string("\r\n");
 		init_platform();
 	}
diff --git a/common/platform.c b/common/platform.c
index 80d0562..26e5944 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -52,6 +52,19 @@ void print_string(const char *str)
 		print_char(*str++);
 }
 
+#define HEX_CHARS_PER_LONG (2 * sizeof(long))
+
+void print_ulong_hex(unsigned long val)
+{
+	const char hex_chars[16] = "0123456789abcdef";
+	int i;
+
+	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
+		int v = (val >> (4 * i)) & 0xf;
+		print_char(hex_chars[v]);
+	}
+}
+
 void init_uart(void)
 {
 	/*
diff --git a/include/platform.h b/include/platform.h
index 237b481..c88e124 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -11,6 +11,8 @@
 
 void print_char(char c);
 void print_string(const char *str);
+void print_ulong_hex(unsigned long val);
+
 void init_uart(void);
 
 void init_platform(void);
diff --git a/model.lds.S b/model.lds.S
index d4e7e13..dacaa25 100644
--- a/model.lds.S
+++ b/model.lds.S
@@ -35,46 +35,54 @@ SECTIONS
 	 * the boot section's *(.data)
 	 */
 	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
-		kernel = .;
+		kernel__start = .;
 		KERNEL
+		kernel__end = .;
 	}
 
 #ifdef XEN
 	.xen (PHYS_OFFSET + XEN_OFFSET): {
-		xen = .;
+		xen__start = .;
 		XEN
+		xen__end = .;
 	}
 
-	entrypoint = xen;
+	entrypoint = xen__start;
 #else
-	entrypoint = kernel;
+	entrypoint = kernel__start;
 #endif
 
 	.dtb (PHYS_OFFSET + FDT_OFFSET): {
+		dtb__start = .;
 		dtb = .;
 		./fdt.dtb
+		dtb__end = .;
 	}
 
 #ifdef USE_INITRD
 	.filesystem (PHYS_OFFSET + FS_OFFSET): {
-		filesystem = .;
+		filesystem__start = .;
 		FILESYSTEM
-		fs_size = . - filesystem;
+		filesystem__end = .;
 	}
 #endif
 
 	.boot PHYS_OFFSET: {
+		text__start = .;
 		*(.init)
 		*(.text*)
 		*(.data* .rodata* .bss* COMMON)
 		*(.vectors)
 		*(.stack)
 		PROVIDE(etext = .);
+		text__end = .;
 	}
 
 	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
+		mbox__start = .;
 		mbox = .;
 		QUAD(0x0)
+		mbox__end = .;
 	}
 
 	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:52 +0000
Subject: [bootwrapper PATCH v2 12/13] Rework bootmethod initialization
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-13-mark.rutland@arm.com>

We currently initialize the bootmethod late, in assembly code. This
requires us to maintain the el3/no_el3 distintion late into the boot
process, and means we cannot produce any helpful diagnostic when booted
at an unexpected exception level.

Rework things so that we initialize the bootmethod early, with a warning
when things are wrong. The el3/no_el3 distinction is now irrelevant to
the bootmethod code, and can be removed in subsequent patches.

When a boot-wrapper configured for PSCI is entered at EL2, a warning is
looged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL2
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb
|
| WARNING: PSCI could not be initialized. Boot may fail

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h  |  1 +
 arch/aarch32/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
 arch/aarch32/psci.S             |  8 +-------
 arch/aarch32/utils.S            |  9 ---------
 arch/aarch64/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
 arch/aarch64/psci.S             | 21 ++-------------------
 arch/aarch64/spin.S             |  3 +++
 arch/aarch64/utils.S            |  9 ---------
 common/init.c                   |  7 ++++++-
 common/psci.c                   | 22 +++++++++++++++++++---
 include/boot.h                  |  2 ++
 11 files changed, 90 insertions(+), 48 deletions(-)
 create mode 100644 arch/aarch32/include/asm/psci.h
 create mode 100644 arch/aarch64/include/asm/psci.h

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index c1bce9a..3426075 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -63,6 +63,7 @@ static inline unsigned long read_cpsr(void)
 #define SCR		"p15, 0, %0, c1, c1, 0"
 #define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
+#define MVBAR		"p15, 0, %0, c12, c0, 1"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
diff --git a/arch/aarch32/include/asm/psci.h b/arch/aarch32/include/asm/psci.h
new file mode 100644
index 0000000..50c7c70
--- /dev/null
+++ b/arch/aarch32/include/asm/psci.h
@@ -0,0 +1,28 @@
+/*
+ * arch/aarch64/include/asm/psci.h
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __ASM_AARCH64_PSCI_H
+#define __ASM_AARCH64_PSCI_H
+
+#include <cpu.h>
+#include <stdbool.h>
+
+extern char psci_vectors[];
+
+static inline bool cpu_init_psci_arch(void)
+{
+	if (read_cpsr_mode() != PSR_MON)
+		return false;
+
+	mcr(MVBAR, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+
+#endif
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index e0d2972..cdc36b0 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -15,7 +15,7 @@
 
 	.section .vectors
 	.align 6
-smc_vectors:
+ASM_DATA(psci_vectors)
 	b	err_exception			@ Reset
 	b	err_exception			@ Undef
 	b	handle_smc			@ SMC
@@ -39,11 +39,5 @@ handle_smc:
 	movs	pc, lr
 
 ASM_FUNC(start_el3)
-	ldr	r0, =smc_vectors
-	blx	setup_vector
-	/* pass through */
-
 ASM_FUNC(start_no_el3)
-	cpuid	r0, r1
-	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch32/utils.S b/arch/aarch32/utils.S
index 5809f48..58279aa 100644
--- a/arch/aarch32/utils.S
+++ b/arch/aarch32/utils.S
@@ -35,12 +35,3 @@ ASM_FUNC(find_logical_id)
 	bx	lr
 3:	mov	r0, #MPIDR_INVALID
 	bx	lr
-
-/*
- * Setup EL3 vectors.
- * r0: vector address
- */
-ASM_FUNC(setup_vector)
-	mcr	p15, 0, r0, c12, c0, 1	@ MVBAR
-	isb
-	bx	lr
diff --git a/arch/aarch64/include/asm/psci.h b/arch/aarch64/include/asm/psci.h
new file mode 100644
index 0000000..491e685
--- /dev/null
+++ b/arch/aarch64/include/asm/psci.h
@@ -0,0 +1,28 @@
+/*
+ * arch/aarch64/include/asm/psci.h
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __ASM_AARCH64_PSCI_H
+#define __ASM_AARCH64_PSCI_H
+
+#include <cpu.h>
+#include <stdbool.h>
+
+extern char psci_vectors[];
+
+static inline bool cpu_init_psci_arch(void)
+{
+	if (mrs(CurrentEL) != CURRENTEL_EL3)
+		return false;
+
+	msr(VBAR_EL3, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+
+#endif
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index 8bd224b..d6ca2eb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -19,7 +19,7 @@
 	.section .vectors, "w"
 
 	.align 11
-vector:
+ASM_DATA(psci_vectors)
 	// current EL, SP_EL0
 	ventry	err_exception	// synchronous
 	ventry	err_exception	// IRQ
@@ -80,22 +80,5 @@ smc_exit:
 	eret
 
 ASM_FUNC(start_el3)
-	ldr	x0, =vector
-	bl	setup_vector
-
-	/* only boot the primary cpu (entry 0 in the table) */
-	cpuid	x0, x1
-	bl	find_logical_id
-	b	psci_first_spin
-
-/*
- * This PSCI implementation requires EL3. Without EL3 we'll only boot the
- * primary cpu, all others will be trapped in an infinite loop.
- */
 ASM_FUNC(start_no_el3)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cbz	x0, psci_first_spin
-spin_dead:
-	wfe
-	b	spin_dead
+	b	psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 1ea1c0b..764c532 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -12,6 +12,9 @@
 
 	.text
 
+ASM_FUNC(cpu_init_bootmethod)
+	ret
+
 ASM_FUNC(start_el3)
 ASM_FUNC(start_no_el3)
 	cpuid	x0, x1
diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
index 85c7f8a..32393cc 100644
--- a/arch/aarch64/utils.S
+++ b/arch/aarch64/utils.S
@@ -32,12 +32,3 @@ ASM_FUNC(find_logical_id)
 	ret
 3:	mov	x0, #MPIDR_INVALID
 	ret
-
-/*
- * Setup EL3 vectors
- * x0: vector address
- */
-ASM_FUNC(setup_vector)
-	msr	VBAR_EL3, x0
-	isb
-	ret
diff --git a/common/init.c b/common/init.c
index fc74b9e..3c05ac3 100644
--- a/common/init.c
+++ b/common/init.c
@@ -6,6 +6,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE.txt file.
  */
+#include <boot.h>
 #include <cpu.h>
 #include <platform.h>
 
@@ -44,7 +45,9 @@ void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
 {
-	if (this_cpu_logical_id() == 0) {
+	unsigned int cpu = this_cpu_logical_id();
+
+	if (cpu == 0) {
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
@@ -52,4 +55,6 @@ void cpu_init_bootwrapper(void)
 		print_string("\r\n");
 		init_platform();
 	}
+
+	cpu_init_bootmethod(cpu);
 }
diff --git a/common/psci.c b/common/psci.c
index a0e8700..8af6870 100644
--- a/common/psci.c
+++ b/common/psci.c
@@ -12,8 +12,11 @@
 #include <bakery_lock.h>
 #include <boot.h>
 #include <cpu.h>
+#include <platform.h>
 #include <psci.h>
 
+#include <asm/psci.h>
+
 #ifndef CPU_IDS
 #error "No MPIDRs provided"
 #endif
@@ -78,12 +81,25 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
 	}
 }
 
-void __noreturn psci_first_spin(unsigned int cpu)
+void __noreturn psci_first_spin(void)
 {
-	if (cpu == MPIDR_INVALID)
-		while (1);
+	unsigned int cpu = this_cpu_logical_id();
 
 	first_spin(cpu, branch_table + cpu, PSCI_ADDR_INVALID);
 
 	unreachable();
 }
+
+void cpu_init_bootmethod(unsigned int cpu)
+{
+	if (cpu_init_psci_arch())
+		return;
+
+	if (cpu == 0) {
+		print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
+		return;
+	}
+
+	while (1)
+		wfe();
+}
diff --git a/include/boot.h b/include/boot.h
index d75e013..10968f8 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -16,4 +16,6 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
 void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid_addr);
 
+void cpu_init_bootmethod(unsigned int cpu);
+
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 14 02:56:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 10:56:53 +0000
Subject: [bootwrapper PATCH v2 13/13] Unify start_el3 & start_no_el3
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114105653.3003399-14-mark.rutland@arm.com>

Now that the start_el3 and start_no_el3 labels point at the same place,
unify them into a start_bootmethod label and update callers.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 5 ++---
 arch/aarch32/psci.S | 3 +--
 arch/aarch64/boot.S | 4 ++--
 arch/aarch64/psci.S | 3 +--
 arch/aarch64/spin.S | 3 +--
 5 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 820957b..4d16c9c 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -51,7 +51,7 @@ ASM_FUNC(_start)
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 _switch_monitor:
 	adr	lr, _monitor
@@ -69,8 +69,7 @@ _monitor:
 
 	bl	gic_secure_init
 
-	/* Initialise boot method */
-	b	start_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index cdc36b0..6613b6f 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -38,6 +38,5 @@ handle_smc:
 	pop	{r4 - r12, lr}
 	movs	pc, lr
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	b	psci_first_spin
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index c0ec518..da5fa65 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -57,7 +57,7 @@ reset_at_el3:
 
 	bl	gic_secure_init
 
-	b	start_el3
+	b	start_bootmethod
 
 	/*
 	 * EL2 initialization
@@ -97,7 +97,7 @@ reset_no_el3:
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index d6ca2eb..9709dbb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -79,6 +79,5 @@ smc_exit:
 	ldp	x18, x19, [sp], #16
 	eret
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	b	psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 764c532..375f732 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -15,8 +15,7 @@
 ASM_FUNC(cpu_init_bootmethod)
 	ret
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	cpuid	x0, x1
 	bl	find_logical_id
 
-- 
2.30.2



From inki.dae at samsung.com  Fri Jan 14 03:20:05 2022
From: inki.dae at samsung.com (Inki Dae)
Date: Fri, 14 Jan 2022 20:20:05 +0900
Subject: [PATCH 2/5] drm/exynos: mixer: Use platform_get_irq() to get
 the interrupt
In-Reply-To: <20211222190134.24866-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20211222190134.24866-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CGME20211222190203epcas1p2a7647eb2c09c29587b70982744c1a912@epcas1p2.samsung.com>
 <20211222190134.24866-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <a95b74fd-7118-b0fe-26b9-4665c719f1a0@samsung.com>

Hi Lad Prabhakar,

21. 12. 23. ?? 4:01? Lad Prabhakar ?(?) ? ?:
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypassed the hierarchical setup and messed up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> Hi,
> 
> Ideally I would expect the mixer_resources_init() to be called from probe
> instead from the bind callback. If platform_get_irq() returns -EPROBE_DEFER
> the bind callback will fail :(

If the bind callback failed then probe function of exynos drm driver will call -EPROBE_DEFER like below so it must be no problem :),
--------------------------------------------
in exynos_drm_platform_probe function
    component_master_add_with_match()

in component_master_add_with_match function
    try_to_bring_up_master()

Thanks,
Inki Dae

> 
> Cheers,
> Prabhakar
> ---
>  drivers/gpu/drm/exynos/exynos_mixer.c | 14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
> index 41c54f1f60bc..e5204be86093 100644
> --- a/drivers/gpu/drm/exynos/exynos_mixer.c
> +++ b/drivers/gpu/drm/exynos/exynos_mixer.c
> @@ -809,19 +809,17 @@ static int mixer_resources_init(struct mixer_context *mixer_ctx)
>  		return -ENXIO;
>  	}
>  
> -	res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
> -	if (res == NULL) {
> -		dev_err(dev, "get interrupt resource failed.\n");
> -		return -ENXIO;
> -	}
> +	ret = platform_get_irq(mixer_ctx->pdev, 0);
> +	if (ret < 0)
> +		return ret;
> +	mixer_ctx->irq = ret;
>  
> -	ret = devm_request_irq(dev, res->start, mixer_irq_handler,
> -						0, "drm_mixer", mixer_ctx);
> +	ret = devm_request_irq(dev, mixer_ctx->irq, mixer_irq_handler,
> +			       0, "drm_mixer", mixer_ctx);
>  	if (ret) {
>  		dev_err(dev, "request interrupt failed.\n");
>  		return ret;
>  	}
> -	mixer_ctx->irq = res->start;
>  
>  	return 0;
>  }
> 


From biju.das.jz at bp.renesas.com  Fri Jan 14 03:08:45 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 11:08:45 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
Message-ID: <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,

> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> On 14/01/2022 09:29, Biju Das wrote:
> > Hi Neil,
> >
> > + renesas-soc
> >
> >> Subject: Re: dw_hdmi is showing wrong colour after commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks")
> >>
> >> Hi,
> >>
> >> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>> Hi Biju,
> >>>
> >>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>> <biju.das.jz at bp.renesas.com>
> >> wrote:
> >>>>
> >>>> Hi All,
> >>>>
> >>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
> >>>> till the commit
> >>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks").
> >>>>
> >>>> After this patch, the screen becomes greenish(may be it is setting
> >>>> it
> >> into YUV format??).
> >>>>
> >>>> By checking the code, previously it used to call get_input_fmt
> >>>> callback
> >> and set colour as RGB24.
> >>>>
> >>>> After this commit, it calls get_output_fmt_callbck and returns 3
> >>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I
> >>>> see
> >> the outputformat as YUV16 instead of RGB24.
> >>>>
> >>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> >>
> >> This patch was introduced to maintain the bridge color format
> >> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems
> >> it behaves incorrectly if the first bridge doesn't implement the
> >> negotiation callbacks.
> >>
> >> Let me check the code to see how to fix that.
> >
> > Thanks for the information, I am happy to test the patch/fix.
> >
> > Cheers,
> > Biju
> >
> >>
> >>>
> >>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
> shows:
> >>>
> >>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
> >>> (DWC HDMI 3D TX PHY)
> >>>
> >>> The colors are shown correctly here.
> >>>
> >>
> >> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
> >> fails and use the RGB fallback input & output format.
> >>
> >> Anyway thanks for testing
> >>
> >> Neil
> 
> Can you test :
> 
> ==><===============================
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index c96847fc0ebc..7019acd37716 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> drm_bridge *bridge,
>         last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state-
> >state,
>                                                             last_bridge);
> 
> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> +       /*
> +        * Only negociate with real values if both end of the bridge chain
> +        * support negociation callbacks, otherwise you can end in a
> situation
> +        * where the selected output format doesn't match with the first
> bridge
> +        * output format.
> +        */
> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>                 const struct drm_bridge_funcs *funcs = last_bridge->funcs;
> 
>                 /*
> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> drm_bridge *bridge,
>                 if (!out_bus_fmts)
>                         return -ENOMEM;
> 
> -               if (conn->display_info.num_bus_formats &&
> +               /*
> +                * If first bridge doesn't support negociation, use
> MEDIA_BUS_FMT_FIXED
> +                * as a safe value for the whole bridge chain
> +                */
> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> +                   conn->display_info.num_bus_formats &&
>                     conn->display_info.bus_formats)
>                         out_bus_fmts[0] = conn-
> >display_info.bus_formats[0];
>                 else
> ==><===============================
> 
> This should exclude your situation where the first bridge doesn't support
> negociation.

I have tested this fix with Linux next-20220114. Still I see colour issue.

It is still negotiating and it is calling get_output_fmt_callbck

[    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=0#########
[    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
[    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=2#########

And In get_input_fmt callback, I See the outputformat as YUV16 instead of RGB24.

[    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16#########
[    3.473644] ########hdmi_video_sample MEDIA_BUS_FMT_UYVY8_1X16#########

Regards,
Biju

From andrzej.hajda at intel.com  Fri Jan 14 03:11:38 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Fri, 14 Jan 2022 12:11:38 +0100
Subject: [v9,2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <f858dd4aaa35fa3eb969baf887f038c3593232e5.camel@mediatek.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-3-rex-bc.chen@mediatek.com>
 <4076cb55-4546-6bbd-1a1f-19395dcd9ccd@collabora.com>
 <f858dd4aaa35fa3eb969baf887f038c3593232e5.camel@mediatek.com>
Message-ID: <86b76e9f-96b0-7d54-bd38-449745e30aa2@intel.com>


On 14.01.2022 11:20, Rex-BC Chen wrote:
> Hello AngeloGioacchino,
>
> Thanks for your review.
> I will modify this in next version.
>
> BRs,
> Rex-BC Chen
>
> On Fri, 2022-01-14 at 10:36 +0100, AngeloGioacchino Del Regno wrote:
>> Il 14/01/22 10:21, Rex-BC Chen ha scritto:
>>> Some DSI RX devices require the packets on all lanes aligned at the
>>> end.
>>> Otherwise, there will be some issues of shift or scroll for screen.
>>>
>>> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
>>> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
>> Hello,
>> thanks for the patch! However, there's something to improve...
>>
>>> ---
>>>    drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
>>>    1 file changed, 12 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> b/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> index 5d90d2eb0019..ccdda15f5a66 100644
>>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>>> @@ -195,6 +195,8 @@ struct mtk_dsi {
>>>    	struct clk *hs_clk;
>>>    
>>>    	u32 data_rate;
>>> +	/* force dsi line end without dsi_null data */
>>> +	bool hs_packet_end_aligned;
>> There's no need to introduce a new variable here...
>>>    
>>>    	unsigned long mode_flags;
>>>    	enum mipi_dsi_pixel_format format;
>>> @@ -500,6 +502,13 @@ static void mtk_dsi_config_vdo_timing(struct
>>> mtk_dsi *dsi)
>>>    		DRM_WARN("HFP + HBP less than d-phy, FPS will under
>>> 60Hz\n");
>>>    	}
>>>    
>>> +	if (dsi->hs_packet_end_aligned) {
>> You can simply check mode_flags here:
>> 	if (dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) {
>>
>>> +		horizontal_sync_active_byte =
>>> roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
>>> +		horizontal_frontporch_byte =
>>> roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
>>> +		horizontal_backporch_byte =
>>> roundup(horizontal_backporch_byte, dsi->lanes) - 2;
>>> +		horizontal_backporch_byte -= (vm->hactive *
>>> dsi_tmp_buf_bpp + 2) % dsi->lanes;
>>> +	}
>>> +


And if you could add comment explaining the magic here it would be nice.


Regards

Andrzej


>>>    	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>>>    	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>>>    	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
>>> @@ -794,6 +803,9 @@ static int mtk_dsi_host_attach(struct
>>> mipi_dsi_host *host,
>>>    	dsi->lanes = device->lanes;
>>>    	dsi->format = device->format;
>>>    	dsi->mode_flags = device->mode_flags;
>>> +	dsi->hs_packet_end_aligned = (dsi->mode_flags &
>>> +				      MIPI_DSI_HS_PKT_END_ALIGNED)
>>> +				     ? true : false;
>> ...so there's no need for this one, either.
>>
>>>    
>>>    	return 0;
>>>    }
>>>
>> Regards,
>> - Angelo
>>


From andy.shevchenko at gmail.com  Fri Jan 14 03:16:43 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 14 Jan 2022 13:16:43 +0200
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <b9c1876c9d0f48a3a8d7e091d47fc069@sphcmbx02.sunplus.com.tw>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
 <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
 <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>
 <CAHp75VfxtGue7bbMm_MU2GWwWo4aZLW2Pj_U9ocCQmWr6wfGMw@mail.gmail.com>
 <b9c1876c9d0f48a3a8d7e091d47fc069@sphcmbx02.sunplus.com.tw>
Message-ID: <CAHp75VdTm5T=VGgrqfp+3bLAu4chosirJ2uBeoA5MxvV+FMg_Q@mail.gmail.com>

On Fri, Jan 14, 2022 at 12:55 PM Wells Lu ??? <wells.lu at sunplus.com> wrote:

...

> > > > > > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > > > > > >
> > > > > > > > Why bool and not tristate?
> > > > > > >
> > > > > > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > > > > > We never build it as a module, but build-in to kernel.
> > > > > > > So we use "bool".
> > > > > > >
> > > > > > > Should we set it to tristate?
> > > > > >
> > > > > > You still haven't answered "why", so I can't tell you.
> > > > >
> > > > > I am puzzled because I think I have answered "why".
> > > >
> > > > Nope. :-)
> > > >
> > > > > Because Pinctrl driver is necessary for all SP7021-based platforms.
> > > >
> > > > "Why?" Why is it necessary (to be built-in)?
> > >
> > > Pinctrl is necessary to be built-in because drivers of boot-device,
> > > like eMMC, SD card, NAND flash, and NOR flash drivers, need it.
> > >
> > > SP7021 supports booting from eMMC, SD card, NAND flash and NOR flash
> > > devices. Their drivers need Pinctrl driver probes in advance.
> >
> > On x86 platforms, for example, booting from eMMC and SD card does not require a pin
> > control driver to be built-in. Why is this requirement for SP platforms?

> Because all pins of boot-device multiplex with GPIO pins.
>
> SP7021 platforms support multi boot devices, including eMMC, SD card,
> SPI-NOR flash, SPI-NAND flash. Each boot device has control-bit(s)
> to enable it.
>
> For example #1, if control-bits of SPI-NOR flash is set 1,
> GPIO 83, 84, 86, 87 are connected to SPI-NOR flash.
> If control-bits of SPI-NOR flash is set 2,
> GPIO 76, 78, 79, 81 are connected to SPI-NOR flash.
> If control-bits of SPI-NOR flash is set 0, no pin is
> connected SPI-NOR flash.
>
> For example #2, if control-bits of eMMC device is set 1,
> GPIO 72, 73, 74, 75, 76, 77, 78, 79, 80, 81 are connected to
> eMMC device.
> If control-bits of eMMC device is set 0, no pin is connected
> eMMC device.
>
> For example #3, if control-bits of SDCard device is set 1,
> GPIO 65, 66, 67, 68, 69, 70 are connected to SD Card device.
> If control-bits of SDCard device is set 0, no pin is connected
> SDCard device.
>
> Note that all pins multiplex with GPIO pins.
>
> Normally, only a boot-device is enabled. All other GPIO pins
> are released for peripherals (controlled by fully-pinmux
> Or group pinmux) or IO processor

Thanks for this detailed picture of the HW configuration.

> Pinctrl driver is responsible for setup the pins.
> If Pinctrl fails to probe, boot-device also fails to probe.

But have you tried to compile it as a module and supply it in the initramfs?

What kernel does in this case it takes address of initramfs from
memory (I believe you have bootloader that capable to setup kernel,
initramfs, command line, and device
tree blob and pass the control to the kernel) at some point, mounts it
and probes the modules that are required to get your boot device
ready.

-- 
With Best Regards,
Andy Shevchenko


From patchwork-bot+netdevbpf at kernel.org  Fri Jan 14 03:30:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 14 Jan 2022 11:30:10 +0000
Subject: [PATCH] net: stmmac: Fix "Unbalanced pm_runtime_enable!" warning
In-Reply-To: <20220114071430.1335872-1-kai.heng.feng@canonical.com>
References: <20220114071430.1335872-1-kai.heng.feng@canonical.com>
Message-ID: <164215981045.30922.3548719266097575473.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Fri, 14 Jan 2022 15:14:30 +0800 you wrote:
> If the device is PCI based like intel-eth-pci, pm_runtime_enable() is
> already called by pci_pm_init().
> 
> So only pm_runtime_enable() when it's not already enabled.
> 
> Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> 
> [...]

Here is the summary with links:
  - net: stmmac: Fix "Unbalanced pm_runtime_enable!" warning
    https://git.kernel.org/netdev/net/c/d90d0c175cf2

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From wells.lu at sunplus.com  Fri Jan 14 03:36:31 2022
From: wells.lu at sunplus.com (=?utf-8?B?V2VsbHMgTHUg5ZGC6Iqz6aiw?=)
Date: Fri, 14 Jan 2022 11:36:31 +0000
Subject: [PATCH v5 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <CAHp75VdTm5T=VGgrqfp+3bLAu4chosirJ2uBeoA5MxvV+FMg_Q@mail.gmail.com>
References: <1640331779-18277-1-git-send-email-wellslutw@gmail.com>
 <1640331779-18277-3-git-send-email-wellslutw@gmail.com>
 <CAHp75Vd3iMM+NteJXP_mMAyw5momk3xzp1Y2GX-YJZfFSAwo9A@mail.gmail.com>
 <f87b21407ed44630a86b2661deab4a58@sphcmbx02.sunplus.com.tw>
 <CAHp75VcPB_K6RD8tnMarwGCeaOKcQ_knxvKEW9WNn_4ce41szw@mail.gmail.com>
 <cf53f5dc57e342078ec14a771ba639ca@sphcmbx02.sunplus.com.tw>
 <CAHp75Vf0=Sf8sGtgCo7bMjVFGYDcJOasLqdSHTnQ0YPgSbrr2g@mail.gmail.com>
 <9e15ccc8ee844f1eab320001bc8bc235@sphcmbx02.sunplus.com.tw>
 <CAHp75VfxtGue7bbMm_MU2GWwWo4aZLW2Pj_U9ocCQmWr6wfGMw@mail.gmail.com>
 <b9c1876c9d0f48a3a8d7e091d47fc069@sphcmbx02.sunplus.com.tw>
 <CAHp75VdTm5T=VGgrqfp+3bLAu4chosirJ2uBeoA5MxvV+FMg_Q@mail.gmail.com>
Message-ID: <cbfe10d1243f4d6bb37cf936f5926351@sphcmbx02.sunplus.com.tw>

> ...
> 
> > > > > > > > > > +       bool "Sunplus SP7021 PinMux and GPIO driver"
> > > > > > > > >
> > > > > > > > > Why bool and not tristate?
> > > > > > > >
> > > > > > > > Pinctrl driver is selected by many drivers in SP7021 platform.
> > > > > > > > We never build it as a module, but build-in to kernel.
> > > > > > > > So we use "bool".
> > > > > > > >
> > > > > > > > Should we set it to tristate?
> > > > > > >
> > > > > > > You still haven't answered "why", so I can't tell you.
> > > > > >
> > > > > > I am puzzled because I think I have answered "why".
> > > > >
> > > > > Nope. :-)
> > > > >
> > > > > > Because Pinctrl driver is necessary for all SP7021-based platforms.
> > > > >
> > > > > "Why?" Why is it necessary (to be built-in)?
> > > >
> > > > Pinctrl is necessary to be built-in because drivers of
> > > > boot-device, like eMMC, SD card, NAND flash, and NOR flash drivers, need it.
> > > >
> > > > SP7021 supports booting from eMMC, SD card, NAND flash and NOR
> > > > flash devices. Their drivers need Pinctrl driver probes in advance.
> > >
> > > On x86 platforms, for example, booting from eMMC and SD card does
> > > not require a pin control driver to be built-in. Why is this requirement for SP
> platforms?
> 
> > Because all pins of boot-device multiplex with GPIO pins.
> >
> > SP7021 platforms support multi boot devices, including eMMC, SD card,
> > SPI-NOR flash, SPI-NAND flash. Each boot device has control-bit(s) to
> > enable it.
> >
> > For example #1, if control-bits of SPI-NOR flash is set 1, GPIO 83,
> > 84, 86, 87 are connected to SPI-NOR flash.
> > If control-bits of SPI-NOR flash is set 2, GPIO 76, 78, 79, 81 are
> > connected to SPI-NOR flash.
> > If control-bits of SPI-NOR flash is set 0, no pin is connected SPI-NOR
> > flash.
> >
> > For example #2, if control-bits of eMMC device is set 1, GPIO 72, 73,
> > 74, 75, 76, 77, 78, 79, 80, 81 are connected to eMMC device.
> > If control-bits of eMMC device is set 0, no pin is connected eMMC
> > device.
> >
> > For example #3, if control-bits of SDCard device is set 1, GPIO 65,
> > 66, 67, 68, 69, 70 are connected to SD Card device.
> > If control-bits of SDCard device is set 0, no pin is connected SDCard
> > device.
> >
> > Note that all pins multiplex with GPIO pins.
> >
> > Normally, only a boot-device is enabled. All other GPIO pins are
> > released for peripherals (controlled by fully-pinmux Or group pinmux)
> > or IO processor
> 
> Thanks for this detailed picture of the HW configuration.
> 
> > Pinctrl driver is responsible for setup the pins.
> > If Pinctrl fails to probe, boot-device also fails to probe.
> 
> But have you tried to compile it as a module and supply it in the initramfs?
> 
> What kernel does in this case it takes address of initramfs from memory (I believe
> you have bootloader that capable to setup kernel, initramfs, command line, and device
> tree blob and pass the control to the kernel) at some point, mounts it and probes the
> modules that are required to get your boot device ready.
> 
> --
> With Best Regards,
> Andy Shevchenko

Yes, I'll modify Kconfig and Makefile to support "compile as module".

Actually, SP7021 platforms also support booting from tftp and nfs server.
In these two cases, no boot device is enabled in Linux kernel (but 
boot device is enabled in U-Boot). Pinctrl driver can be a module.


Thanks,
Wells Lu

From inki.dae at samsung.com  Fri Jan 14 03:47:48 2022
From: inki.dae at samsung.com (Inki Dae)
Date: Fri, 14 Jan 2022 20:47:48 +0900
Subject: [PATCH 0/5] drm/exynos: Use platform_get_irq*() variants to
 fetch IRQ's
In-Reply-To: <20211222190134.24866-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <CGME20211222190157epcas1p1d556269940101a49ab245a4f1d7d45c0@epcas1p1.samsung.com>
 <20211222190134.24866-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <6f044839-e1d8-b9a8-90c3-7e929d498838@samsung.com>

Hi,

21. 12. 23. ?? 4:01? Lad Prabhakar ?(?) ? ?:
> Hi All,
> 
> This patch series aims to drop using platform_get_resource() for IRQ types
> in preparation for removal of static setup of IRQ resource from DT core
> code.
> 
> Dropping usage of platform_get_resource() was agreed based on
> the discussion [0].
> 
> [0] https://patchwork.kernel.org/project/linux-renesas-soc/
> patch/20211209001056.29774-1-prabhakar.mahadev-lad.rj at bp.renesas.com/
>

Applied.

Thanks,
Inki Dae

 
> Cheers,
> Prabhakar
> 
> Lad Prabhakar (5):
>   drm/exynos/exynos7_drm_decon: Use platform_get_irq_byname() to get the
>     interrupt
>   drm/exynos: mixer: Use platform_get_irq() to get the interrupt
>   drm/exynos/exynos_drm_fimd: Use platform_get_irq_byname() to get the
>     interrupt
>   drm/exynos/fimc: Use platform_get_irq() to get the interrupt
>   drm/exynos: gsc: Use platform_get_irq() to get the interrupt
> 
>  drivers/gpu/drm/exynos/exynos7_drm_decon.c | 12 +++---------
>  drivers/gpu/drm/exynos/exynos_drm_fimc.c   | 13 +++++--------
>  drivers/gpu/drm/exynos/exynos_drm_fimd.c   | 13 ++++---------
>  drivers/gpu/drm/exynos/exynos_drm_gsc.c    | 10 +++-------
>  drivers/gpu/drm/exynos/exynos_mixer.c      | 14 ++++++--------
>  5 files changed, 21 insertions(+), 41 deletions(-)
> 


From allen-kh.cheng at mediatek.com  Fri Jan 14 03:46:31 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 19:46:31 +0800
Subject: [PATCH v14 0/2] mtk: add ADSP mailbox controller support for MT8195
Message-ID: <20220114114633.742-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox registers to kick dsp.

Two mailboxes used to send notification or short message between processors with dsp

changes since v13:
- rebase on v5.16-rc8
- add back ptr check from of_device_get_match_data

changes since v12:
- remove of_device_get_match_data ptr check:
  of_device_get_match_data(dev) will never going to return NULL.
  driver probe with compatible mediatek,mt8195-adsp-mbox.

changes since v11:
- remove unuseful MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error

Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 175 ++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 14 03:46:32 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 19:46:32 +0800
Subject: [PATCH v14 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
References: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220114114633.742-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 14 03:46:33 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 19:46:33 +0800
Subject: [PATCH v14 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
References: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220114114633.742-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 175 +++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..0613a2befca5
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
-- 
2.18.0



From vincent.whitchurch at axis.com  Fri Jan 14 03:46:54 2022
From: vincent.whitchurch at axis.com (Vincent Whitchurch)
Date: Fri, 14 Jan 2022 12:46:54 +0100
Subject: [PATCH v11 03/19] dyndbg: add write-to-tracefs code
In-Reply-To: <20220107052942.1349447-4-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
 <20220107052942.1349447-4-jim.cromie@gmail.com>
Message-ID: <20220114114654.GA23983@axis.com>

On Fri, Jan 07, 2022 at 06:29:26AM +0100, Jim Cromie wrote:
> adds: dynamic_trace()
>  uses trace_console() temporarily to issue printk:console event
>  uses internal-ish __ftrace_trace_stack code:
>       4-context buffer stack, barriers per Steve
> 
> call it from new funcs:
>   dynamic_printk() - print to both syslog/tracefs
>   dynamic_dev_printk() - dev-print to both syslog/tracefs
> 
> These handle both _DPRINTK_FLAGS_PRINTK and _DPRINTK_FLAGS_TRACE
> cases, allowing to vsnprintf the message once and use it for both,
> skipping past the KERN_DEBUG character for tracing.
> 
> Finally, adjust the callers: __dynamic_{pr_debug,{,net,ib}dev_dbg},
> replacing printk and dev_printk with the new funcs above.
> 
> The _DPRINTK_FLAGS_TRACE flag character s 'T', so the following finds
> all callsites enabled for tracing:
> 
>   grep -P =p?T /proc/dynamic_debug/control
> 
> Enabling debug-to-tracefs is 2 steps:
> 
>   # event enable
>   echo 1 > /sys/kernel/tracing/events/dyndbg/enable
>   # callsite enable
>   echo module foo +T > /proc/dynamic_debug/control
> 
> This patch,~1,~2 are based upon:
>   https://lore.kernel.org/lkml/20200825153338.17061-1-vincent.whitchurch at axis.com/
> 
> .. with simplification of temporarily reusing trace_console() rather
> than adding a new printk:dyndbg event.  Soon, add 2 new events
> capturing the pr_debug & dev_dbg() args.

The example above does not match the code in this patch since the
dyndbg:* events are only added in a later patch.  Perhaps you could
reorder this patch stack so that you don't use trace_console() in this
patch just to replace it with the new events in the next patch?

> 
> CC: vincent.whitchurch at axis.com
> Signed-off-by: Jim Cromie <jim.cromie at gmail.com>
> ---
>  .../admin-guide/dynamic-debug-howto.rst       |   1 +
>  lib/dynamic_debug.c                           | 155 +++++++++++++++---
>  2 files changed, 130 insertions(+), 26 deletions(-)
> 
> diff --git a/Documentation/admin-guide/dynamic-debug-howto.rst b/Documentation/admin-guide/dynamic-debug-howto.rst
[...]
> @@ -723,29 +822,33 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
>  {
>  	struct va_format vaf;
>  	va_list args;
> +	unsigned int flags;
>  
>  	va_start(args, fmt);
>  
>  	vaf.fmt = fmt;
>  	vaf.va = &args;
> +	flags = descriptor->flags;
>  
>  	if (ibdev && ibdev->dev.parent) {
>  		char buf[PREFIX_SIZE] = "";
>  
> -		dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
> -				"%s%s %s %s: %pV",
> -				dynamic_emit_prefix(descriptor, buf),
> -				dev_driver_string(ibdev->dev.parent),
> -				dev_name(ibdev->dev.parent),
> -				dev_name(&ibdev->dev),
> -				&vaf);
> +		dynamic_dev_printk(flags, ibdev->dev.parent,
> +				   "%s%s %s %s: %pV",
> +				   dynamic_emit_prefix(descriptor, buf),
> +				   dev_driver_string(ibdev->dev.parent),
> +				   dev_name(ibdev->dev.parent),
> +				   dev_name(&ibdev->dev),
> +				   &vaf);
>  	} else if (ibdev) {
> -		printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
> +		dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
> +			       dev_name(&ibdev->dev), &vaf);
>  	} else {
> -		printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
> +		dynamic_printk(flags, KERN_DEBUG "(NULL ip_device): %pV",
> +			       &vaf);
>  	}
>  
> -	va_end(args);
> +va_end(args);

This looks like an unintentional whitespace change?


From vincent.whitchurch at axis.com  Fri Jan 14 03:57:18 2022
From: vincent.whitchurch at axis.com (Vincent Whitchurch)
Date: Fri, 14 Jan 2022 12:57:18 +0100
Subject: [PATCH v11 01/19] dyndbg: add _DPRINTK_FLAGS_ENABLED
In-Reply-To: <20220107052942.1349447-2-jim.cromie@gmail.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
 <20220107052942.1349447-2-jim.cromie@gmail.com>
Message-ID: <20220114115718.GB23983@axis.com>

On Fri, Jan 07, 2022 at 06:29:24AM +0100, Jim Cromie wrote:
>  #ifdef CONFIG_JUMP_LABEL
> -			if (dp->flags & _DPRINTK_FLAGS_PRINT) {
> -				if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
> +			if (dp->flags & _DPRINTK_FLAGS_ENABLED) {
> +				if (!(modifiers->flags & _DPRINTK_FLAGS_ENABLED))
>  					static_branch_disable(&dp->key.dd_key_true);
> -			} else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
> +			} else if (modifiers->flags & _DPRINTK_FLAGS_ENABLED)
>  				static_branch_enable(&dp->key.dd_key_true);
>  #endif
>  			dp->flags = newflags;
> -- 
> 2.33.1
> 

I haven't tested it so I could be mistaken, but when
_DPRINTK_FLAGS_ENABLED gets two flags in the next patch, it looks like
this code still has the problem which I mentioned in
https://lore.kernel.org/lkml/20211209150910.GA23668 at axis.com/?

| I noticed a bug inside the CONFIG_JUMP_LABEL handling (also present
| in the last version I posted) which should be fixed as part of the
| diff below (I've added a comment).
| [...] 
|  #ifdef CONFIG_JUMP_LABEL
| -			if (dp->flags & _DPRINTK_FLAGS_PRINT) {
| -				if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
| +			if (dp->flags & _DPRINTK_FLAGS_ENABLE) {
| +				/*
| +				 * The newflags check is to ensure that the
| +				 * static branch doesn't get disabled in step
| +				 * 3:
| +				 *
| +				 * (1) +pf
| +				 * (2) +x
| +				 * (3) -pf
| +				 */
| +				if (!(modifiers->flags & _DPRINTK_FLAGS_ENABLE) &&
| +				    !(newflags & _DPRINTK_FLAGS_ENABLE)) {
|  					static_branch_disable(&dp->key.dd_key_true);
| -			} else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
| +				}
| +			} else if (modifiers->flags & _DPRINTK_FLAGS_ENABLE) {
|  				static_branch_enable(&dp->key.dd_key_true);
| +			}
|  #endif


From allen-kh.cheng at mediatek.com  Fri Jan 14 03:49:13 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 19:49:13 +0800
Subject: [PATCH v4 0/1] firmware: mtk: add adsp ipc protocol for sof
Message-ID: <20220114114914.2508-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch provides mtk adsp ipc support for sof.

ADSP IPC protocol offers (send/recv) interfaces using mediatek-mailbox APIs.

changes since v3:
- rebase on v5.16-rc8
- update reviewers

changes since v2:
- add out tag for two memroy free phases

changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove unuseful MODULE_LICENSE
- change label name to out_free

Allen-KH Cheng (1):
  firmware: mediatek: add adsp ipc protocol interface

 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 14 03:49:14 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 14 Jan 2022 19:49:14 +0800
Subject: [PATCH v4 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220114114914.2508-1-allen-kh.cheng@mediatek.com>
References: <20220114114914.2508-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220114114914.2508-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..faaf2b25a3bf
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *adsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	adsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(adsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * mbox_send_message returns non-negative value on success,
+	 * return zero for success
+	 */
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "wrong mbox chan %d \n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *adsp_ipc;
+	struct mtk_adsp_chan *adsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+	if (!adsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		adsp_chan = &adsp_ipc->chans[i];
+		cl = &adsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		adsp_chan->ipc = adsp_ipc;
+		adsp_chan->idx = i;
+		adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(adsp_chan->ch)) {
+			ret = PTR_ERR(adsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out_free;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	adsp_ipc->dev = dev;
+	dev_set_drvdata(dev, adsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out_free:
+	kfree(chan_name);
+out:
+	for (j = 0; j < i; j++) {
+		adsp_chan = &adsp_ipc->chans[j];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *adsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		adsp_chan = &adsp_ipc->chans[i];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From guangming.cao at mediatek.com  Fri Jan 14 04:05:48 2022
From: guangming.cao at mediatek.com (Guangming.Cao)
Date: Fri, 14 Jan 2022 20:05:48 +0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
 <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
 <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>
Message-ID: <82faa62f1bc946cf2f9ee2f7d15c567162238eab.camel@mediatek.com>

On Fri, 2022-01-14 at 08:16 +0100, Christian K?nig wrote:
> Am 14.01.22 um 00:26 schrieb John Stultz:
> > On Thu, Jan 13, 2022 at 5:05 AM Christian K?nig
> > <christian.koenig at amd.com> wrote:
> > > Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
> > > > > -----Original Message-----
> > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > Behalf Of
> > > > > Ruhl, Michael J
> > > > > > -----Original Message-----
> > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org>
> > > > > > On Behalf Of
> > > > > > guangming.cao at mediatek.com
> > > > > > +   /*
> > > > > > +    * Invalid size check. The "len" should be less than
> > > > > > totalram.
> > > > > > +    *
> > > > > > +    * Without this check, once the invalid size allocation
> > > > > > runs on a process
> > > > > > that
> > > > > > +    * can't be killed by OOM flow(such as "gralloc" on
> > > > > > Android devices), it
> > > > > > will
> > > > > > +    * cause a kernel exception, and to make matters worse,
> > > > > > we can't find
> > > > > > who are using
> > > > > > +    * so many memory with "dma_buf_debug_show" since the
> > > > > > relevant
> > > > > > dma-buf hasn't exported.
> > > > > > +    */
> > > > > > +   if (len >> PAGE_SHIFT > totalram_pages())
> > > > > 
> > > > > If your "heap" is from cma, is this still a valid check?
> > > > 
> > > > And thinking a bit further, if I create a heap from something
> > > > else (say device memory),
> > > > you will need to be able to figure out the maximum allowable
> > > > check for the specific
> > > > heap.
> > > > 
> > > > Maybe the heap needs a callback for max size?
Yes, I agree with this solution.
If dma-heap framework support this via adding a callback to support it,
seems it's more clear than adding a limitation in dma-heap framework
since each heap maybe has different limitation.
If you prefer adding callback, I can update this patch and add totalram
limitation to system dma-heap.

Thanks!
Guangming
> > > 
> > > Well we currently maintain a separate allocator and don't use
> > > dma-heap,
> > > but yes we have systems with 16GiB device and only 8GiB system
> > > memory so
> > > that check here is certainly not correct.
> > 
> > Good point.
> > 
> > > In general I would rather let the system run into -ENOMEM or
> > > -EINVAL
> > > from the allocator instead.

For system dma-heap, it doesn't know how memory is avaliable when
allocating memory, so, use totalram_pages() just to prevent cases which
will cause oom definitely.

Just like PAGE align, this check is can be used for all heaps since
there is no dma-heap can alloc memory larger than totalram. Futhermore,
if vendors implement a variety of dma-heap like system heap for special
usages, seems need to add this check to each dma-heap, and I think this
is unnecessary.
If the dma-heap has it's own special limitations for size, and add it
into heap implementation is good.

Thanks!
Guangming
> > 
> > Probably the simpler solution is to push the allocation check to
> > the
> > heap driver, rather than doing it at the top level here.
> > 
> > For CMA or other contiguous heaps, letting the allocator fail is
> > fast
> > enough. For noncontiguous buffers, like the system heap, the
> > allocation can burn a lot of time and consume a lot of memory
> > (causing
> > other trouble) before a large allocation might naturally fail.
> 
> Yeah, letting a alloc_page() loop run for a while is usually not nice
> at 
> all :)
> 
> You can still do a sanity check here, e.g. the size should never
> have 
> the most significant bit set for example.
> 
Yes, this is a good solution. But if this a positive value, larger than
totalram, it can also pass this check, and cause OOM after some time.

From dicussion above, seems finding a proper solution that can judge
the size is valid or not for each dma-heap is more important.

Thanks!
Guangming

> Regards,
> Christian.
> 
> > 
> > thanks
> > -john
> 
> 

From andre.przywara at arm.com  Fri Jan 14 04:09:31 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 12:09:31 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <YeFUJ+dw22Kmhwjs@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
 <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
 <20220113195051.7100b066@slackpad.fritz.box>
 <9eb63797-b313-a39a-6b9c-0f8ac447b85a@arm.com>
 <YeFUJ+dw22Kmhwjs@FVFF77S0Q05N>
Message-ID: <20220114120931.36488dfe@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:44:55 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> On Fri, Jan 14, 2022 at 08:35:06AM +0000, Vladimir Murzin wrote:
> > Hi Andre,
> > 
> > On 1/13/22 7:50 PM, Andre Przywara wrote:  
> > > On Thu, 13 Jan 2022 18:42:50 +0000
> > > Vladimir Murzin <vladimir.murzin at arm.com> wrote:
> > > 
> > > Hi Vladimir,
> > >   
> > >> On 12/22/21 6:16 PM, Andre Przywara wrote:  
> > >>> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> > >>> the blob first, then re-compile it with our nodes and properties added.
> > >>>
> > >>> In our input DTB the proper phandle references have already been lost,
> > >>> all we see in the DTB is phandle properties in the target node, and some
> > >>> numbers in the clocks and gpios properties:
> > >>> ===========
> > >>> 	clk24mhz {
> > >>> 		compatible = "fixed-clock";
> > >>> 		#clock-cells = <0x00>;
> > >>> 		clock-frequency = <0x16e3600>;
> > >>> 		clock-output-names = "v2m:clk24mhz";    
> > >>> ->		phandle = <0x05>;    
> > >>> 	};
> > >>> 	...
> > >>> 	serial at 90000 {
> > >>> 		compatible = "arm,pl011", "arm,primecell";
> > >>> 		reg = <0x90000 0x1000>;
> > >>> 		interrupts = <0x05>;    
> > >>> ->		clocks = <0x05 0x05>;    
> > >>> 		clock-names = "uartclk", "apb_pclk";
> > >>> 	};
> > >>> ===========
> > >>> dtc warns that those numbers might be wrong:
> > >>> =========
> > >>> <stdin>:177.6-27: Warning (clocks_property):
> > >>>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
> > >>>    clocks: cell 0 is not a phandle reference
> > >>> ....
> > >>> =========
> > >>> The proper solution would be to use references (&v2m_clk24mhz) instead,
> > >>> as there are in the source .dts file, but we don't have that information
> > >>> anymore, and cannot easily recover it.
> > >>>
> > >>> To avoid the lengthy list of warnings, just drop those checks from the
> > >>> dtc compilation run. This disables more checks than we want or need, but
> > >>> we somewhat trust in the original DTB to be sane, so that should be
> > >>> fine.
> > >>>
> > >>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > >>> ---
> > >>>  Makefile.am | 2 +-
> > >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> > >>>
> > >>> diff --git a/Makefile.am b/Makefile.am
> > >>> index 3d8128f..430b4a9 100644
> > >>> --- a/Makefile.am
> > >>> +++ b/Makefile.am
> > >>> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
> > >>>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
> > >>>  
> > >>>  fdt.dtb: $(KERNEL_DTB) Makefile
> > >>> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> > >>> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
> > >>>  
> > >>>  # The filesystem archive might not exist if INITRD is not being used
> > >>>  .PHONY: all clean $(FILESYSTEM)
> > >>>     
> > >>
> > >> dtc 1.4.1 complains  
> > > 
> > > Which distro ships this version? (distrowatch doesn't list dtc)
> > > 
> > > tag v1.4.1
> > > Tagger: David Gibson <david at gibson.dropbear.id.au>
> > > Date:   Wed Nov 12 14:31:44 2014 +1100
> > > 
> > > Any chance it's just you and you can update this? It looks like the
> > > first version to support it is 1.4.5, as shipped for instance with
> > > Ubuntu 18.04.  
> > 
> > It is shipped as LSF module. I can try to ask for an update, but I thought
> > that other people may run into it as well...
> >   
> > >   
> > >> FATAL ERROR: Unrecognized check name "clocks_property"  
> > > 
> > > Sigh, thanks for the heads up. I don't know if we want to blow up the
> > > Makefile with a feature test?  
> > 
> > I dunno, TBH. It look like warning used to be less evil than error...  

Yeah, that's what I meant: Either revert it or extend the Makefile.

> I agree.
> 
> My preference would be to revert that for now, and consider the problem afresh.
> Andre, are you ok with that?

Sure, I don't want to break the build for people.
I think kvmtool has some lightweight feature tests in its Makefile, I can
try to steal some of it, and see how evil it looks. Or wait for half a
year to see those older dtcs flushed out and try it again ;-)

Cheers,
Andre


From boger at wirenboard.com  Fri Jan 14 04:10:34 2022
From: boger at wirenboard.com (Evgeny Boger)
Date: Fri, 14 Jan 2022 15:10:34 +0300
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <20220114103750.01f95d70@donnerap.cambridge.arm.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-4-boger@wirenboard.com>
 <20220114094255.br6qqqgoajvhpt2x@houat>
 <20220114103750.01f95d70@donnerap.cambridge.arm.com>
Message-ID: <0d62080d-e373-8b6f-699a-b7e4e84a26ce@wirenboard.com>



14.01.2022 13:37, Andre Przywara ?????:
> On Fri, 14 Jan 2022 10:42:55 +0100
> Maxime Ripard <maxime at cerno.tech> wrote:
>
> Hi,
>
>> On Thu, Jan 13, 2022 at 08:37:34AM +0300, Evgeny Boger wrote:
>>> R40 (aka V40, A40i, T3) has two different Ethernet IPs
>>> called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
>>> while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).
>>>
>>> In contrast to A10/A20 where GMAC and EMAC share the same pins
>>> making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
>>> Both EMAC (on port H) and GMAC (on port A) can be then enabled at
>>> the same time, allowing for two ethernet ports.
>>>
>>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
>>> ---
>>>   arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
>>>   1 file changed, 49 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
>>> index 03d3e5f45a09..8770b105f86e 100644
>>> --- a/arch/arm/boot/dts/sun8i-r40.dtsi
>>> +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
>>> @@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
>>>   			#size-cells = <1>;
>>>   			ranges;
>>>   
>>> +			sram_a: sram at 0 {
>>> +				compatible = "mmio-sram";
>>> +				reg = <0x00000000 0xc000>;
>>> +				#address-cells = <1>;
>>> +				#size-cells = <1>;
>>> +				ranges = <0 0x00000000 0xc000>;
>>> +
>>> +				emac_sram: sram-section at 8000 {
>>> +					compatible = "allwinner,sun4i-a10-sram-a3-a4";
>>> +					reg = <0x8000 0x4000>;
>>> +				};
>>> +			};
>>> +
>>>   			sram_c: sram at 1d00000 {
>>>   				compatible = "mmio-sram";
>>>   				reg = <0x01d00000 0xd0000>;
>>> @@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
>>>   				drive-strength = <40>;
>>>   			};
>>>   
>>> +			emac_pa_pins: emac-pa-pins {
>>> +				pins = "PA0", "PA1", "PA2",
>>> +				       "PA3", "PA4", "PA5", "PA6",
>>> +				       "PA7", "PA8", "PA9", "PA10",
>>> +				       "PA11", "PA12", "PA13", "PA14",
>>> +				       "PA15", "PA16";
>>> +				function = "emac";
>>> +			};
>>> +
>>> +			emac_ph_pins: emac-ph-pins {
>>> +				pins = "PH8", "PH9", "PH10", "PH11",
>>> +				       "PH14", "PH15", "PH16", "PH17",
>>> +				       "PH18","PH19", "PH20", "PH21",
>>> +				       "PH22", "PH23", "PH24", "PH25",
>>> +				       "PH26", "PH27";
>>> +				function = "emac";
>>> +			};
>> There's 17 pins on the first group, but 18 on the second, is it intentional?
> Yeah, looks like PA17 is missing above. This pin is used for MII only, so
> it is omitted from the existing gmac_rgmii_pins group.
>
> Evgeny: Did you try a 100MBit PHY on PortA? That should work with both the
> GMAC and EMAC, right? I wonder if we should add a group that connects all
> pins needed for MII to the GMAC as well, so basically the above (with PA17
> added), but using 'function = "gmac";'? Put an "/omit-if-no-ref/" before
> that (also to those above?) to avoid blowing up the DTB needlessly.
Hi Andre,

No, it's not intentional, thank you for noticing that!
I haven't tried EMAC on port A with the latest patch, but it should be 
trivial to do.
The problem with TXERR signal is that it's kind of optional, so it's 
hard to notice if it doesn't work properly.

As for adding gmac_*mii*_pins node, I think it could be useful. Do you 
suggest to add it to the same series? Strictly speaking, it has nothing 
to do with R40 and second ethernet support. GMAC is ubiquitous among 
Allwinner SoCs, so I think it would make sense to add to all SoCs at once.

As for /omit-if-no-ref/ on pinctrl nodes, is there a policy on it? I 
mean there are people (ourselves included) who use device tree overlays 
a lot, both in bootloader and kernel, so it's not that harmless.


> Cheers,
> Andre.


-- 
? ?????????,
     ??????? ????? / Evgeny Boger
     CTO, Wiren Board Team
     https://wirenboard.com/ru
     +7 495 150 66 19 (# 33)



From maxime at cerno.tech  Fri Jan 14 04:38:17 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Fri, 14 Jan 2022 13:38:17 +0100
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <0d62080d-e373-8b6f-699a-b7e4e84a26ce@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-4-boger@wirenboard.com>
 <20220114094255.br6qqqgoajvhpt2x@houat>
 <20220114103750.01f95d70@donnerap.cambridge.arm.com>
 <0d62080d-e373-8b6f-699a-b7e4e84a26ce@wirenboard.com>
Message-ID: <20220114123817.jg6766vsfogdkzmr@houat>

Hi,

On Fri, Jan 14, 2022 at 03:10:34PM +0300, Evgeny Boger wrote:
> 14.01.2022 13:37, Andre Przywara ?????:
> > On Fri, 14 Jan 2022 10:42:55 +0100
> > Maxime Ripard <maxime at cerno.tech> wrote:
> > 
> > Hi,
> > 
> > > On Thu, Jan 13, 2022 at 08:37:34AM +0300, Evgeny Boger wrote:
> > > > R40 (aka V40, A40i, T3) has two different Ethernet IPs
> > > > called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
> > > > while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).
> > > > 
> > > > In contrast to A10/A20 where GMAC and EMAC share the same pins
> > > > making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
> > > > Both EMAC (on port H) and GMAC (on port A) can be then enabled at
> > > > the same time, allowing for two ethernet ports.
> > > > 
> > > > Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> > > > ---
> > > >   arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
> > > >   1 file changed, 49 insertions(+)
> > > > 
> > > > diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
> > > > index 03d3e5f45a09..8770b105f86e 100644
> > > > --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> > > > +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> > > > @@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
> > > >   			#size-cells = <1>;
> > > >   			ranges;
> > > > +			sram_a: sram at 0 {
> > > > +				compatible = "mmio-sram";
> > > > +				reg = <0x00000000 0xc000>;
> > > > +				#address-cells = <1>;
> > > > +				#size-cells = <1>;
> > > > +				ranges = <0 0x00000000 0xc000>;
> > > > +
> > > > +				emac_sram: sram-section at 8000 {
> > > > +					compatible = "allwinner,sun4i-a10-sram-a3-a4";
> > > > +					reg = <0x8000 0x4000>;
> > > > +				};
> > > > +			};
> > > > +
> > > >   			sram_c: sram at 1d00000 {
> > > >   				compatible = "mmio-sram";
> > > >   				reg = <0x01d00000 0xd0000>;
> > > > @@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
> > > >   				drive-strength = <40>;
> > > >   			};
> > > > +			emac_pa_pins: emac-pa-pins {
> > > > +				pins = "PA0", "PA1", "PA2",
> > > > +				       "PA3", "PA4", "PA5", "PA6",
> > > > +				       "PA7", "PA8", "PA9", "PA10",
> > > > +				       "PA11", "PA12", "PA13", "PA14",
> > > > +				       "PA15", "PA16";
> > > > +				function = "emac";
> > > > +			};
> > > > +
> > > > +			emac_ph_pins: emac-ph-pins {
> > > > +				pins = "PH8", "PH9", "PH10", "PH11",
> > > > +				       "PH14", "PH15", "PH16", "PH17",
> > > > +				       "PH18","PH19", "PH20", "PH21",
> > > > +				       "PH22", "PH23", "PH24", "PH25",
> > > > +				       "PH26", "PH27";
> > > > +				function = "emac";
> > > > +			};
> > > There's 17 pins on the first group, but 18 on the second, is it intentional?
> > Yeah, looks like PA17 is missing above. This pin is used for MII only, so
> > it is omitted from the existing gmac_rgmii_pins group.
> > 
> > Evgeny: Did you try a 100MBit PHY on PortA? That should work with both the
> > GMAC and EMAC, right? I wonder if we should add a group that connects all
> > pins needed for MII to the GMAC as well, so basically the above (with PA17
> > added), but using 'function = "gmac";'? Put an "/omit-if-no-ref/" before
> > that (also to those above?) to avoid blowing up the DTB needlessly.
>
> No, it's not intentional, thank you for noticing that!
> I haven't tried EMAC on port A with the latest patch, but it should be
> trivial to do.
> The problem with TXERR signal is that it's kind of optional, so it's hard to
> notice if it doesn't work properly.

TXERR seems to be rarely used for our boards (there's only one in tree,
plus the A20-marsboard currently discussed) so having it as a separate
pinctrl node would make more sense.

> As for adding gmac_*mii*_pins node, I think it could be useful. Do you
> suggest to add it to the same series? Strictly speaking, it has nothing to
> do with R40 and second ethernet support. GMAC is ubiquitous among Allwinner
> SoCs, so I think it would make sense to add to all SoCs at once.
> 
> As for /omit-if-no-ref/ on pinctrl nodes, is there a policy on it? I mean
> there are people (ourselves included) who use device tree overlays a lot,
> both in bootloader and kernel, so it's not that harmless.

/omit-if-no-ref/ doesn't do anything if the DT is compiled with overlay
support (dtc -@)

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220114/5d513baa/attachment-0001.sig>

From matthias.bgg at gmail.com  Fri Jan 14 04:47:15 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 13:47:15 +0100
Subject: [v6 4/5] soc: mediatek: pm-domains: Move power status offset to
 power domain data
In-Reply-To: <20211116025045.5401-5-chun-jie.chen@mediatek.com>
References: <20211116025045.5401-1-chun-jie.chen@mediatek.com>
 <20211116025045.5401-5-chun-jie.chen@mediatek.com>
Message-ID: <dd149bad-63f8-6b2c-a280-35167460db9b@gmail.com>



On 16/11/2021 03:50, Chun-Jie Chen wrote:
> MT8195 has more than 32 power domains so it needs
> two set of pwr_sta and pwr_sta2nd registers,
> so move the register offset from soc data into power domain data.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
> ---
> no change
> ---
>   drivers/soc/mediatek/mt8167-pm-domains.h | 16 +++++++--
>   drivers/soc/mediatek/mt8173-pm-domains.h | 22 ++++++++++--
>   drivers/soc/mediatek/mt8183-pm-domains.h | 32 +++++++++++++++--
>   drivers/soc/mediatek/mt8192-pm-domains.h | 44 ++++++++++++++++++++++--
>   drivers/soc/mediatek/mtk-pm-domains.c    |  4 +--
>   drivers/soc/mediatek/mtk-pm-domains.h    |  4 +--
>   6 files changed, 110 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mt8167-pm-domains.h b/drivers/soc/mediatek/mt8167-pm-domains.h
> index 15559ddf26e4..4d6c32759606 100644
> --- a/drivers/soc/mediatek/mt8167-pm-domains.h
> +++ b/drivers/soc/mediatek/mt8167-pm-domains.h
> @@ -18,6 +18,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "mm",
>   		.sta_mask = PWR_STATUS_DISP,
>   		.ctl_offs = SPM_DIS_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -30,6 +32,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "vdec",
>   		.sta_mask = PWR_STATUS_VDEC,
>   		.ctl_offs = SPM_VDE_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.caps = MTK_SCPD_ACTIVE_WAKEUP,
> @@ -38,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "isp",
>   		.sta_mask = PWR_STATUS_ISP,
>   		.ctl_offs = SPM_ISP_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   		.caps = MTK_SCPD_ACTIVE_WAKEUP,
> @@ -46,6 +52,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "mfg_async",
>   		.sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
>   		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = 0,
>   		.sram_pdn_ack_bits = 0,
>   		.bp_infracfg = {
> @@ -57,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "mfg_2d",
>   		.sta_mask = MT8167_PWR_STATUS_MFG_2D,
>   		.ctl_offs = SPM_MFG_2D_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -64,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "mfg",
>   		.sta_mask = PWR_STATUS_MFG,
>   		.ctl_offs = SPM_MFG_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -71,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   		.name = "conn",
>   		.sta_mask = PWR_STATUS_CONN,
>   		.ctl_offs = SPM_CONN_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = 0,
>   		.caps = MTK_SCPD_ACTIVE_WAKEUP,
> @@ -85,8 +99,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
>   static const struct scpsys_soc_data mt8167_scpsys_data = {
>   	.domains_data = scpsys_domain_data_mt8167,
>   	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
> -	.pwr_sta_offs = SPM_PWR_STATUS,
> -	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   };
>   
>   #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
> diff --git a/drivers/soc/mediatek/mt8173-pm-domains.h b/drivers/soc/mediatek/mt8173-pm-domains.h
> index 714fa92575df..1a5dc63b7357 100644
> --- a/drivers/soc/mediatek/mt8173-pm-domains.h
> +++ b/drivers/soc/mediatek/mt8173-pm-domains.h
> @@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "vdec",
>   		.sta_mask = PWR_STATUS_VDEC,
>   		.ctl_offs = SPM_VDE_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "venc",
>   		.sta_mask = PWR_STATUS_VENC,
>   		.ctl_offs = SPM_VEN_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -29,6 +33,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "isp",
>   		.sta_mask = PWR_STATUS_ISP,
>   		.ctl_offs = SPM_ISP_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   	},
> @@ -36,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "mm",
>   		.sta_mask = PWR_STATUS_DISP,
>   		.ctl_offs = SPM_DIS_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -47,6 +55,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "venc_lt",
>   		.sta_mask = PWR_STATUS_VENC_LT,
>   		.ctl_offs = SPM_VEN2_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -54,6 +64,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "audio",
>   		.sta_mask = PWR_STATUS_AUDIO,
>   		.ctl_offs = SPM_AUDIO_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -61,6 +73,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "usb",
>   		.sta_mask = PWR_STATUS_USB,
>   		.ctl_offs = SPM_USB_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   		.caps = MTK_SCPD_ACTIVE_WAKEUP,
> @@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "mfg_async",
>   		.sta_mask = PWR_STATUS_MFG_ASYNC,
>   		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = 0,
>   		.caps = MTK_SCPD_DOMAIN_SUPPLY,
> @@ -77,6 +93,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "mfg_2d",
>   		.sta_mask = PWR_STATUS_MFG_2D,
>   		.ctl_offs = SPM_MFG_2D_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   	},
> @@ -84,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   		.name = "mfg",
>   		.sta_mask = PWR_STATUS_MFG,
>   		.ctl_offs = SPM_MFG_PWR_CON,
> +		.pwr_sta_offs = SPM_PWR_STATUS,
> +		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   		.sram_pdn_bits = GENMASK(13, 8),
>   		.sram_pdn_ack_bits = GENMASK(21, 16),
>   		.bp_infracfg = {
> @@ -98,8 +118,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
>   static const struct scpsys_soc_data mt8173_scpsys_data = {
>   	.domains_data = scpsys_domain_data_mt8173,
>   	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
> -	.pwr_sta_offs = SPM_PWR_STATUS,
> -	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
>   };
>   
>   #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
> diff --git a/drivers/soc/mediatek/mt8183-pm-domains.h b/drivers/soc/mediatek/mt8183-pm-domains.h
> index 98a9940d05fb..71b8757e552d 100644
> --- a/drivers/soc/mediatek/mt8183-pm-domains.h
> +++ b/drivers/soc/mediatek/mt8183-pm-domains.h
> @@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "audio",
>   		.sta_mask = PWR_STATUS_AUDIO,
>   		.ctl_offs = 0x0314,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   	},
> @@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "conn",
>   		.sta_mask = PWR_STATUS_CONN,
>   		.ctl_offs = 0x032c,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = 0,
>   		.sram_pdn_ack_bits = 0,
>   		.bp_infracfg = {
> @@ -33,6 +37,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "mfg_async",
>   		.sta_mask = PWR_STATUS_MFG_ASYNC,
>   		.ctl_offs = 0x0334,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = 0,
>   		.sram_pdn_ack_bits = 0,
>   	},
> @@ -40,6 +46,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "mfg",
>   		.sta_mask = PWR_STATUS_MFG,
>   		.ctl_offs = 0x0338,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.caps = MTK_SCPD_DOMAIN_SUPPLY,
> @@ -48,6 +56,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "mfg_core0",
>   		.sta_mask = BIT(7),
>   		.ctl_offs = 0x034c,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -55,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "mfg_core1",
>   		.sta_mask = BIT(20),
>   		.ctl_offs = 0x0310,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -62,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "mfg_2d",
>   		.sta_mask = PWR_STATUS_MFG_2D,
>   		.ctl_offs = 0x0348,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -75,6 +89,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "disp",
>   		.sta_mask = PWR_STATUS_DISP,
>   		.ctl_offs = 0x030c,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -94,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "cam",
>   		.sta_mask = BIT(25),
>   		.ctl_offs = 0x0344,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(9, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   		.bp_infracfg = {
> @@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "isp",
>   		.sta_mask = PWR_STATUS_ISP,
>   		.ctl_offs = 0x0308,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(9, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   		.bp_infracfg = {
> @@ -140,6 +160,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "vdec",
>   		.sta_mask = BIT(31),
>   		.ctl_offs = 0x0300,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_smi = {
> @@ -153,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "venc",
>   		.sta_mask = PWR_STATUS_VENC,
>   		.ctl_offs = 0x0304,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(15, 12),
>   		.bp_smi = {
> @@ -166,6 +190,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "vpu_top",
>   		.sta_mask = BIT(26),
>   		.ctl_offs = 0x0324,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -193,6 +219,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "vpu_core0",
>   		.sta_mask = BIT(27),
>   		.ctl_offs = 0x33c,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   		.bp_infracfg = {
> @@ -211,6 +239,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   		.name = "vpu_core1",
>   		.sta_mask = BIT(28),
>   		.ctl_offs = 0x0340,
> +		.pwr_sta_offs = 0x0180,
> +		.pwr_sta2nd_offs = 0x0184,
>   		.sram_pdn_bits = GENMASK(11, 8),
>   		.sram_pdn_ack_bits = GENMASK(13, 12),
>   		.bp_infracfg = {
> @@ -230,8 +260,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
>   static const struct scpsys_soc_data mt8183_scpsys_data = {
>   	.domains_data = scpsys_domain_data_mt8183,
>   	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
> -	.pwr_sta_offs = 0x0180,
> -	.pwr_sta2nd_offs = 0x0184
>   };
>   
>   #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
> diff --git a/drivers/soc/mediatek/mt8192-pm-domains.h b/drivers/soc/mediatek/mt8192-pm-domains.h
> index 543dda70de01..558c4ee4784a 100644
> --- a/drivers/soc/mediatek/mt8192-pm-domains.h
> +++ b/drivers/soc/mediatek/mt8192-pm-domains.h
> @@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "audio",
>   		.sta_mask = BIT(21),
>   		.ctl_offs = 0x0354,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -28,6 +30,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "conn",
>   		.sta_mask = PWR_STATUS_CONN,
>   		.ctl_offs = 0x0304,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = 0,
>   		.sram_pdn_ack_bits = 0,
>   		.bp_infracfg = {
> @@ -50,6 +54,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg0",
>   		.sta_mask = BIT(2),
>   		.ctl_offs = 0x0308,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -57,6 +63,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg1",
>   		.sta_mask = BIT(3),
>   		.ctl_offs = 0x030c,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -82,6 +90,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg2",
>   		.sta_mask = BIT(4),
>   		.ctl_offs = 0x0310,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -89,6 +99,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg3",
>   		.sta_mask = BIT(5),
>   		.ctl_offs = 0x0314,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -96,6 +108,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg4",
>   		.sta_mask = BIT(6),
>   		.ctl_offs = 0x0318,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -103,6 +117,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg5",
>   		.sta_mask = BIT(7),
>   		.ctl_offs = 0x031c,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -110,6 +126,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mfg6",
>   		.sta_mask = BIT(8),
>   		.ctl_offs = 0x0320,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "disp",
>   		.sta_mask = BIT(20),
>   		.ctl_offs = 0x0350,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -146,6 +166,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "ipe",
>   		.sta_mask = BIT(14),
>   		.ctl_offs = 0x0338,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -163,6 +185,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "isp",
>   		.sta_mask = BIT(12),
>   		.ctl_offs = 0x0330,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -180,6 +204,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "isp2",
>   		.sta_mask = BIT(13),
>   		.ctl_offs = 0x0334,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -197,6 +223,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "mdp",
>   		.sta_mask = BIT(19),
>   		.ctl_offs = 0x034c,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -214,6 +242,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "venc",
>   		.sta_mask = BIT(17),
>   		.ctl_offs = 0x0344,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -231,6 +261,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "vdec",
>   		.sta_mask = BIT(15),
>   		.ctl_offs = 0x033c,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -248,6 +280,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "vdec2",
>   		.sta_mask = BIT(16),
>   		.ctl_offs = 0x0340,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -255,6 +289,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "cam",
>   		.sta_mask = BIT(23),
>   		.ctl_offs = 0x035c,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   		.bp_infracfg = {
> @@ -284,6 +320,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "cam_rawa",
>   		.sta_mask = BIT(24),
>   		.ctl_offs = 0x0360,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -291,6 +329,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "cam_rawb",
>   		.sta_mask = BIT(25),
>   		.ctl_offs = 0x0364,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -298,6 +338,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   		.name = "cam_rawc",
>   		.sta_mask = BIT(26),
>   		.ctl_offs = 0x0368,
> +		.pwr_sta_offs = 0x016c,
> +		.pwr_sta2nd_offs = 0x0170,
>   		.sram_pdn_bits = GENMASK(8, 8),
>   		.sram_pdn_ack_bits = GENMASK(12, 12),
>   	},
> @@ -306,8 +348,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
>   static const struct scpsys_soc_data mt8192_scpsys_data = {
>   	.domains_data = scpsys_domain_data_mt8192,
>   	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
> -	.pwr_sta_offs = 0x016c,
> -	.pwr_sta2nd_offs = 0x0170,
>   };
>   
>   #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
> diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
> index afd2fd74802d..ad06b6f90435 100644
> --- a/drivers/soc/mediatek/mtk-pm-domains.c
> +++ b/drivers/soc/mediatek/mtk-pm-domains.c
> @@ -60,10 +60,10 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd)
>   	struct scpsys *scpsys = pd->scpsys;
>   	u32 status, status2;
>   
> -	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);
> +	regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
>   	status &= pd->data->sta_mask;
>   
> -	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);
> +	regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
>   	status2 &= pd->data->sta_mask;
>   
>   	/* A domain is on when both status bits are set. */
> diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
> index 089a31679806..c233ed828f86 100644
> --- a/drivers/soc/mediatek/mtk-pm-domains.h
> +++ b/drivers/soc/mediatek/mtk-pm-domains.h
> @@ -92,13 +92,13 @@ struct scpsys_domain_data {
>   	u8 caps;
>   	const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
>   	const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
> +	int pwr_sta_offs;
> +	int pwr_sta2nd_offs;

Please add the documentation to struct scpsys_domain_data for these two new fields.
Also please put the values in the struct after ctl_offs, to align the order of 
the struct members with the declaration of the struct.

Other then that series looks good.

Regards,
Matthias

>   };
>   
>   struct scpsys_soc_data {
>   	const struct scpsys_domain_data *domains_data;
>   	int num_domains;
> -	int pwr_sta_offs;
> -	int pwr_sta2nd_offs;
>   };
>   
>   #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
> 


From matthias.bgg at gmail.com  Fri Jan 14 04:49:04 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 13:49:04 +0100
Subject: [v1 1/2] dt-bindings: power: Add MT8186 power domains
In-Reply-To: <Yd43V1woRMAcXOfS@robh.at.kernel.org>
References: <20220108131953.16744-1-chun-jie.chen@mediatek.com>
 <20220108131953.16744-2-chun-jie.chen@mediatek.com>
 <Yd43V1woRMAcXOfS@robh.at.kernel.org>
Message-ID: <ae307028-979b-7e58-dd6f-f1d52520859b@gmail.com>



On 12/01/2022 03:05, Rob Herring wrote:
> On Sat, Jan 08, 2022 at 09:19:52PM +0800, Chun-Jie Chen wrote:
>> Add power domains dt-bindings for MT8186.
>>
>> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>> ---
>>   .../power/mediatek,power-controller.yaml      |  1 +
>>   include/dt-bindings/power/mt8186-power.h      | 32 +++++++++++++++++++
>>   2 files changed, 33 insertions(+)
>>   create mode 100644 include/dt-bindings/power/mt8186-power.h
>>
>> diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
>> index d6ebd77d28a7..135c6f722091 100644
>> --- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
>> +++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
>> @@ -26,6 +26,7 @@ properties:
>>         - mediatek,mt8167-power-controller
>>         - mediatek,mt8173-power-controller
>>         - mediatek,mt8183-power-controller
>> +      - mediatek,mt8186-power-controller
>>         - mediatek,mt8192-power-controller
>>         - mediatek,mt8195-power-controller
>>   
>> diff --git a/include/dt-bindings/power/mt8186-power.h b/include/dt-bindings/power/mt8186-power.h
>> new file mode 100644
>> index 000000000000..ca8ea2d24801
>> --- /dev/null
>> +++ b/include/dt-bindings/power/mt8186-power.h
>> @@ -0,0 +1,32 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
> 
> Dual license please.
> 

Other then that series looks good.

Regards,
Matthias

>> +/*
>> + * Copyright (c) 2022 MediaTek Inc.
>> + * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>> + */
>> +
>> +#ifndef _DT_BINDINGS_POWER_MT8186_POWER_H
>> +#define _DT_BINDINGS_POWER_MT8186_POWER_H
>> +
>> +#define MT8186_POWER_DOMAIN_MFG0			0
>> +#define MT8186_POWER_DOMAIN_MFG1			1
>> +#define MT8186_POWER_DOMAIN_MFG2			2
>> +#define MT8186_POWER_DOMAIN_MFG3			3
>> +#define MT8186_POWER_DOMAIN_SSUSB			4
>> +#define MT8186_POWER_DOMAIN_SSUSB_P1			5
>> +#define MT8186_POWER_DOMAIN_DIS				6
>> +#define MT8186_POWER_DOMAIN_IMG				7
>> +#define MT8186_POWER_DOMAIN_IMG2			8
>> +#define MT8186_POWER_DOMAIN_IPE				9
>> +#define MT8186_POWER_DOMAIN_CAM				10
>> +#define MT8186_POWER_DOMAIN_CAM_RAWA			11
>> +#define MT8186_POWER_DOMAIN_CAM_RAWB			12
>> +#define MT8186_POWER_DOMAIN_VENC			13
>> +#define MT8186_POWER_DOMAIN_VDEC			14
>> +#define MT8186_POWER_DOMAIN_WPE				15
>> +#define MT8186_POWER_DOMAIN_CONN_ON			16
>> +#define MT8186_POWER_DOMAIN_CSIRX_TOP			17
>> +#define MT8186_POWER_DOMAIN_ADSP_AO			18
>> +#define MT8186_POWER_DOMAIN_ADSP_INFRA			19
>> +#define MT8186_POWER_DOMAIN_ADSP_TOP			20
>> +
>> +#endif /* _DT_BINDINGS_POWER_MT8186_POWER_H */
>> -- 
>> 2.18.0
>>
>>


From andre.przywara at arm.com  Fri Jan 14 04:49:19 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 12:49:19 +0000
Subject: [PATCH v5 3/3] ARM: dts: sun8i: r40: add second ethernet support
In-Reply-To: <0d62080d-e373-8b6f-699a-b7e4e84a26ce@wirenboard.com>
References: <20220113053734.105813-1-boger@wirenboard.com>
 <20220113053734.105813-4-boger@wirenboard.com>
 <20220114094255.br6qqqgoajvhpt2x@houat>
 <20220114103750.01f95d70@donnerap.cambridge.arm.com>
 <0d62080d-e373-8b6f-699a-b7e4e84a26ce@wirenboard.com>
Message-ID: <20220114124919.3b312c85@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 15:10:34 +0300
Evgeny Boger <boger at wirenboard.com> wrote:

Hi,

> 14.01.2022 13:37, Andre Przywara ?????:
> > On Fri, 14 Jan 2022 10:42:55 +0100
> > Maxime Ripard <maxime at cerno.tech> wrote:
> >
> > Hi,
> >  
> >> On Thu, Jan 13, 2022 at 08:37:34AM +0300, Evgeny Boger wrote:  
> >>> R40 (aka V40, A40i, T3) has two different Ethernet IPs
> >>> called EMAC and GMAC. EMAC only support 10/100 Mbit in MII mode,
> >>> while GMAC support both 10/100 (MII) and 10/100/1000 (RGMII).
> >>>
> >>> In contrast to A10/A20 where GMAC and EMAC share the same pins
> >>> making EMAC somewhat pointless, on R40 EMAC can be routed to port H.
> >>> Both EMAC (on port H) and GMAC (on port A) can be then enabled at
> >>> the same time, allowing for two ethernet ports.
> >>>
> >>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> >>> ---
> >>>   arch/arm/boot/dts/sun8i-r40.dtsi | 49 ++++++++++++++++++++++++++++++++
> >>>   1 file changed, 49 insertions(+)
> >>>
> >>> diff --git a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
> >>> index 03d3e5f45a09..8770b105f86e 100644
> >>> --- a/arch/arm/boot/dts/sun8i-r40.dtsi
> >>> +++ b/arch/arm/boot/dts/sun8i-r40.dtsi
> >>> @@ -217,6 +217,19 @@ syscon: system-control at 1c00000 {
> >>>   			#size-cells = <1>;
> >>>   			ranges;
> >>>   
> >>> +			sram_a: sram at 0 {
> >>> +				compatible = "mmio-sram";
> >>> +				reg = <0x00000000 0xc000>;
> >>> +				#address-cells = <1>;
> >>> +				#size-cells = <1>;
> >>> +				ranges = <0 0x00000000 0xc000>;
> >>> +
> >>> +				emac_sram: sram-section at 8000 {
> >>> +					compatible = "allwinner,sun4i-a10-sram-a3-a4";
> >>> +					reg = <0x8000 0x4000>;
> >>> +				};
> >>> +			};
> >>> +
> >>>   			sram_c: sram at 1d00000 {
> >>>   				compatible = "mmio-sram";
> >>>   				reg = <0x01d00000 0xd0000>;
> >>> @@ -553,6 +566,24 @@ gmac_rgmii_pins: gmac-rgmii-pins {
> >>>   				drive-strength = <40>;
> >>>   			};
> >>>   
> >>> +			emac_pa_pins: emac-pa-pins {
> >>> +				pins = "PA0", "PA1", "PA2",
> >>> +				       "PA3", "PA4", "PA5", "PA6",
> >>> +				       "PA7", "PA8", "PA9", "PA10",
> >>> +				       "PA11", "PA12", "PA13", "PA14",
> >>> +				       "PA15", "PA16";
> >>> +				function = "emac";
> >>> +			};
> >>> +
> >>> +			emac_ph_pins: emac-ph-pins {
> >>> +				pins = "PH8", "PH9", "PH10", "PH11",
> >>> +				       "PH14", "PH15", "PH16", "PH17",
> >>> +				       "PH18","PH19", "PH20", "PH21",
> >>> +				       "PH22", "PH23", "PH24", "PH25",
> >>> +				       "PH26", "PH27";
> >>> +				function = "emac";
> >>> +			};  
> >> There's 17 pins on the first group, but 18 on the second, is it intentional?  
> > Yeah, looks like PA17 is missing above. This pin is used for MII only, so
> > it is omitted from the existing gmac_rgmii_pins group.
> >
> > Evgeny: Did you try a 100MBit PHY on PortA? That should work with both the
> > GMAC and EMAC, right? I wonder if we should add a group that connects all
> > pins needed for MII to the GMAC as well, so basically the above (with PA17
> > added), but using 'function = "gmac";'? Put an "/omit-if-no-ref/" before
> > that (also to those above?) to avoid blowing up the DTB needlessly.  
> Hi Andre,
> 
> No, it's not intentional, thank you for noticing that!

Kudos go to Maxime for spotting the different number of pins!

> I haven't tried EMAC on port A with the latest patch, but it should be 
> trivial to do.
> The problem with TXERR signal is that it's kind of optional, so it's 
> hard to notice if it doesn't work properly.

I see, I was wondering already, since you mentioned MII on both ports
before, IIRC.

> As for adding gmac_*mii*_pins node, I think it could be useful. Do you 
> suggest to add it to the same series? Strictly speaking, it has nothing 
> to do with R40 and second ethernet support. GMAC is ubiquitous among 
> Allwinner SoCs, so I think it would make sense to add to all SoCs at once.

In general we try to add those pin groups only when they get used. The A64
describes both sets of pins (MII & RGMII), because there is the Pine64
(non-plus) with a Realtek 8201FN PHY. For the H3 & H6 this was not needed
before, since board vendors use the internal PHY for 100MBit. I think
similar reasoning applies to the other SoCs.

> As for /omit-if-no-ref/ on pinctrl nodes, is there a policy on it?

Not written out, but my understanding is that if there is only a very
small number of users, we try not to bother everyone else. And connecting
a PHY via MII to the GMAC sounds like a niche use case, if you have the
EMAC on PortH (now).

> I 
> mean there are people (ourselves included) who use device tree overlays 
> a lot, both in bootloader and kernel, so it's not that harmless.

I haven't checked, do those nodes still get removed if you compile the DT
with -@?

Cheers,
Andre


From maz at kernel.org  Fri Jan 14 04:50:38 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 14 Jan 2022 12:50:38 +0000
Subject: [PATCH] KVM: arm64: pkvm: Use the mm_ops indirection for cache
 maintenance
Message-ID: <20220114125038.1336965-1-maz@kernel.org>

CMOs issued from EL2 cannot directly use the kernel helpers,
as EL2 doesn't have a mapping of the guest pages. Oops.

Instead, use the mm_ops indirection to use helpers that will
perform a mapping at EL2 and allow the CMO to be effective.

Fixes: 25aa28691bb9 ("KVM: arm64: Move guest CMOs to the fault handlers")
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/pgtable.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 844a6f003fd5..2cb3867eb7c2 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -983,13 +983,9 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
 	 */
 	stage2_put_pte(ptep, mmu, addr, level, mm_ops);
 
-	if (need_flush) {
-		kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops);
-
-		dcache_clean_inval_poc((unsigned long)pte_follow,
-				    (unsigned long)pte_follow +
-					    kvm_granule_size(level));
-	}
+	if (need_flush && mm_ops->dcache_clean_inval_poc)
+		mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
+					       kvm_granule_size(level));
 
 	if (childp)
 		mm_ops->put_page(childp);
@@ -1151,15 +1147,13 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
 	struct kvm_pgtable *pgt = arg;
 	struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
 	kvm_pte_t pte = *ptep;
-	kvm_pte_t *pte_follow;
 
 	if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte))
 		return 0;
 
-	pte_follow = kvm_pte_follow(pte, mm_ops);
-	dcache_clean_inval_poc((unsigned long)pte_follow,
-			    (unsigned long)pte_follow +
-				    kvm_granule_size(level));
+	if (mm_ops->dcache_clean_inval_poc)
+		mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
+					       kvm_granule_size(level));
 	return 0;
 }
 
-- 
2.30.2



From matthias.bgg at gmail.com  Fri Jan 14 04:56:11 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 13:56:11 +0100
Subject: [PATCH v4] dt-bindings: dsp: mediatek: add mt8195 dsp document
In-Reply-To: <Yd4yNkeGlzdULNlv@robh.at.kernel.org>
References: <20220106064847.15588-1-yc.hung@mediatek.com>
 <Yd4yNkeGlzdULNlv@robh.at.kernel.org>
Message-ID: <68895a40-559b-13ce-d433-f9b32c648323@gmail.com>



On 12/01/2022 02:43, Rob Herring wrote:
> On Thu, 06 Jan 2022 14:48:48 +0800, YC Hung wrote:
>> From: "YC Hung" <yc.hung at mediatek.com>
>>
>> This patch adds mt8195 dsp document. The dsp is used for Sound Open
>> Firmware driver node. It includes registers,  clocks, memory regions,
>> and mailbox for dsp.
>>
>> Signed-off-by: yc.hung <yc.hung at mediatek.com>
>> ---
>> Changes since v3:
>>    Fix patch v3 error : v3 only provide difference between v3 and v2.
>>
>> Changes since v2:
>>    Remove useless watchdog interrupt.
>>    Add commit message more detail description.
>>
>> Changes since v1:
>>    Rename yaml file name as mediatek,mt8195-dsp.yaml
>>    Refine descriptions for mailbox, memory-region and drop unused labels
>>    in examples.
>> ---
>>   .../bindings/dsp/mediatek,mt8195-dsp.yaml     | 105 ++++++++++++++++++
>>   1 file changed, 105 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/dsp/mediatek,mt8195-dsp.yaml
>>
> 
> Reviewed-by: Rob Herring <robh at kernel.org>
> 

Rob, it seems we don't have a maintainer for this bindings. Shall I as MediaTek 
SoC maintainer take them through my branch?

Regards,
Matthias


From matthias.bgg at gmail.com  Fri Jan 14 04:56:52 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 13:56:52 +0100
Subject: [PATCH 2/2] watchdog: mtk_wdt: mt7986: Add toprgu reset
 controller support
In-Reply-To: <20220105100456.7126-3-sam.shih@mediatek.com>
References: <20220105100456.7126-1-sam.shih@mediatek.com>
 <20220105100456.7126-3-sam.shih@mediatek.com>
Message-ID: <6719557c-b5a3-e6f4-3046-b53e5c229cf8@gmail.com>



On 05/01/2022 11:04, Sam Shih wrote:
> Besides watchdog, the mt7986 toprgu module also provides software reset
> functionality for various peripheral subsystems
> (eg, ethernet, pcie, and connectivity)
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

> ---
>   drivers/watchdog/mtk_wdt.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
> index 543cf38bd04e..c6437fe1f4c0 100644
> --- a/drivers/watchdog/mtk_wdt.c
> +++ b/drivers/watchdog/mtk_wdt.c
> @@ -10,6 +10,7 @@
>    */
>   
>   #include <dt-bindings/reset/mt2712-resets.h>
> +#include <dt-bindings/reset/mt7986-resets.h>
>   #include <dt-bindings/reset/mt8183-resets.h>
>   #include <dt-bindings/reset/mt8192-resets.h>
>   #include <dt-bindings/reset/mt8195-resets.h>
> @@ -76,6 +77,10 @@ static const struct mtk_wdt_data mt2712_data = {
>   	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
>   };
>   
> +static const struct mtk_wdt_data mt7986_data = {
> +	.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
> +};
> +
>   static const struct mtk_wdt_data mt8183_data = {
>   	.toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
>   };
> @@ -418,6 +423,7 @@ static int mtk_wdt_resume(struct device *dev)
>   static const struct of_device_id mtk_wdt_dt_ids[] = {
>   	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
>   	{ .compatible = "mediatek,mt6589-wdt" },
> +	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
>   	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
>   	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
>   	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
> 


From andrew at lunn.ch  Fri Jan 14 05:09:06 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 14 Jan 2022 14:09:06 +0100
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <20220114040755.1314349-2-kai.heng.feng@canonical.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
Message-ID: <YeF18mxKuO4/4G0V@lunn.ch>

On Fri, Jan 14, 2022 at 12:07:54PM +0800, Kai-Heng Feng wrote:
> BIOS on Dell Edge Gateway 3200 already makes its own phy LED setting, so
> instead of setting another value, keep it untouched and restore the saved
> value on system resume.
> 
> Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 16 +++++
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 +
>  .../net/ethernet/stmicro/stmmac/stmmac_main.c |  4 ++
>  drivers/net/phy/marvell.c                     | 58 ++++++++++++-------
>  include/linux/marvell_phy.h                   |  1 +
>  5 files changed, 61 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> index 8e8778cfbbadd..f8a2879e0264a 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> @@ -857,6 +857,16 @@ static const struct dmi_system_id quark_pci_dmi[] = {
>  	{}
>  };
>  
> +static const struct dmi_system_id use_preset_led[] = {
> +	{
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Dell EMC"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Edge Gateway 3200"),
> +		},
> +	},
> +	{}
> +};

This is a PHY property. Why is the MAC involved?

Please also think about how to make this generic, so any ACPI based
system can use it, with any PHY.

     Andrew


From andrew at lunn.ch  Fri Jan 14 05:20:17 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 14 Jan 2022 14:20:17 +0100
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <20220114040755.1314349-2-kai.heng.feng@canonical.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
Message-ID: <YeF4kbsqag+kZ7ji@lunn.ch>

>  static void marvell_config_led(struct phy_device *phydev)
>  {
> -	u16 def_config;
> +	struct marvell_priv *priv = phydev->priv;
>  	int err;
>  
> -	switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
> -	/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
> -	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
> -	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
> -		def_config = MII_88E1121_PHY_LED_DEF;
> -		break;
> -	/* Default PHY LED config:
> -	 * LED[0] .. 1000Mbps Link
> -	 * LED[1] .. 100Mbps Link
> -	 * LED[2] .. Blink, Activity
> -	 */
> -	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
> -		if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
> -			def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
> -		else
> -			def_config = MII_88E1510_PHY_LED_DEF;
> -		break;
> -	default:
> +	if (priv->led_def_config == -1)
>  		return;
> +
> +	if (priv->led_def_config)
> +		goto write;

Really?

Please restructure this code. Take it apart into helpers. You need:

A function to set the actual LED configuration.
A function to decide what, if any, configuration to set
A function to store the current configuration on suspend.
A function to restore the current configuration on resume.

Lots of little functions will make it much easier to understand, and
avoid 1980s BASIC style.

I'm also surprised you need to deal with suspend/resume. Why does the
BIOS not set the LED mode on resume, same as it does on power up?

      Andrew


From robin.murphy at arm.com  Fri Jan 14 05:23:51 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 14 Jan 2022 13:23:51 +0000
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
Message-ID: <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>

On 2022-01-10 18:13, Alyssa Rosenzweig wrote:
> Set a mysterious chicken bit in the MT8192 clock driver (!) to get the
> Mali GPU on MT8192 to work. This workaround is from the downstream Mali
> driver shipped in ChromeOS. The change there is unsuitable for mainline
> but good as a reference for the hardware behaviour:
> 
> https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5
> 
> That links to an internal Google issue tracker which I assume has more
> information on the bug. I would appreciate if someone from Google or
> MediaTek could explain what this change actually does and why it's
> necessary on MT8192.
> 
> At any rate, this register logically belongs to the MT8192 "infra" clock
> device, so it makes sense to set it there too. This avoids adding any
> platform-specific hacks to the 3D driver, either mainline (Panfrost) or
> legacy (kbase).

Does this really have anything to do with clocks? My (uninformed) 
impression is that the infracfg blocks are general amalgamations of 
configuration registers that simply happen to contain clock and reset 
controls among other functionality. In particular, "ACP" usually refers 
to the Accelerator Coherency Port of a CPU cluster or DSU, and given the 
stated symptom of the issue affected by it, my first guess would be that 
this bit might indeed control routing of GPU traffic either to the ACP 
or the (presumably non-coherent) main interconnect.

If that is the case, I think this would logically belong as a 
SoC-specific quirk in panfrost, where we'd need to retrieve the syscon 
regmap for ourselves (see around line 800 of drivers/iommu/mtk_iommu.c 
for a similar example).

Cheers,
Robin.

> Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
> Cc: Nick Fan <Nick.Fan at mediatek.com>
> Cc: Nicolas Boichat <drinkcat at chromium.org>
> ---
>   drivers/clk/mediatek/clk-mt8192.c | 31 +++++++++++++++++++++++++++++++
>   1 file changed, 31 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
> index cbc7c6dbe0f4..e3673494d08d 100644
> --- a/drivers/clk/mediatek/clk-mt8192.c
> +++ b/drivers/clk/mediatek/clk-mt8192.c
> @@ -1179,6 +1179,10 @@ static const struct mtk_pll_data plls[] = {
>   
>   static struct clk_onecell_data *top_clk_data;
>   
> +/* Control registers in the infra block used to set a chicken bit */
> +#define INFRA_CTRL 0x290
> +#define INFRA_CTRL_DISABLE_MFG2ACP BIT(9)
> +
>   static void clk_mt8192_top_init_early(struct device_node *node)
>   {
>   	int i;
> @@ -1224,6 +1228,29 @@ static int clk_mt8192_top_probe(struct platform_device *pdev)
>   	return of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
>   }
>   
> +/*
> + * Disable ACP on the infra clock. Setting this quirk is required for 3D to
> + * work correctly. Without this quirk, any work queued to the Mali GPU faults,
> + * for example raising a Data Invalid Fault. This suggests the GPU is failing
> + * to read back the contents of shared CPU/GPU memory correctly, perhaps due to
> + * a MT8192 platform integration issue breaking memory or caches.
> + *
> + * Relevant downstream change:
> + * https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5
> + */
> +static int clk_mt8192_infra_disable_mfg2acp(struct platform_device *pdev)
> +{
> +	void __iomem *base = devm_platform_ioremap_resource(pdev, 0);
> +	void __iomem *infra_ctrl = base + INFRA_CTRL;
> +
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	writel(readl(infra_ctrl) | INFRA_CTRL_DISABLE_MFG2ACP, infra_ctrl);
> +
> +	return 0;
> +}
> +
>   static int clk_mt8192_infra_probe(struct platform_device *pdev)
>   {
>   	struct clk_onecell_data *clk_data;
> @@ -1238,6 +1265,10 @@ static int clk_mt8192_infra_probe(struct platform_device *pdev)
>   	if (r)
>   		return r;
>   
> +	r = clk_mt8192_infra_disable_mfg2acp(pdev);
> +	if (r)
> +		return r;
> +
>   	return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>   }
>   


From marcel.ziswiler at toradex.com  Fri Jan 14 05:24:05 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 13:24:05 +0000
Subject: [PATCH v1 03/14] arm64: defconfig: rebuild default configuration
In-Reply-To: <c0d9b876-ea21-2706-4330-5878ad1cdedd@kernel.org>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-4-marcel@ziswiler.com>
 <c0d9b876-ea21-2706-4330-5878ad1cdedd@kernel.org>
Message-ID: <dcfc3bc3b7598091e172404d9ceb81876e7f15d6.camel@toradex.com>

On Mon, 2022-01-10 at 09:39 +0100, Krzysztof Kozlowski wrote:
> On 07/01/2022 19:03, Marcel Ziswiler wrote:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > Run "make defconfig; make savedefconfig" to rebuild defconfig.
> > 
> > Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > ---
> > 
> > ?arch/arm64/configs/defconfig | 135 +++++++++++++----------------------
> > ?1 file changed, 50 insertions(+), 85 deletions(-)
> > 
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index cc5d3ba166b1..79e4bf9f4c2c 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
[snip]
> > @@ -1177,11 +1146,9 @@ CONFIG_FPGA_REGION=m
> > ?CONFIG_OF_FPGA_REGION=m
> > ?CONFIG_TEE=y
> > ?CONFIG_OPTEE=y
> > -CONFIG_SLIMBUS=m
> 
> NAK, blind savedefconfig is undesirable because it later might cause
> dropping of configs (see DEBUGFS case). We discussed it from time to time...

Yes, I agree. I am very sorry that I did not include more information about it. I will do so in v2.

> Basically you should never remove user-selectable options from defconfig.

Yes, actually this particular one is now already enabled anyway. But I will detail all this in v2.

> > +CONFIG_MUX_MMIO=y
> > ?CONFIG_SLIM_QCOM_CTRL=m
> > ?CONFIG_SLIM_QCOM_NGD_CTRL=m
> > -CONFIG_MUX_MMIO=y
> > -CONFIG_INTERCONNECT=y
> 
> Same.
> 
> > ?CONFIG_INTERCONNECT_IMX=m
> > ?CONFIG_INTERCONNECT_IMX8MM=m
> > ?CONFIG_INTERCONNECT_IMX8MN=m
> > @@ -1209,7 +1176,6 @@ CONFIG_OVERLAY_FS=m
> > ?CONFIG_VFAT_FS=y
> > ?CONFIG_TMPFS_POSIX_ACL=y
> > ?CONFIG_HUGETLBFS=y
> > -CONFIG_CONFIGFS_FS=y
> 
> The same.
> 
> There might be more of such. Don't run savedefconfig blindly.

Yes, sorry again, that I did not include all the information.

> > ?CONFIG_EFIVAR_FS=y
> > ?CONFIG_SQUASHFS=y
> > ?CONFIG_NFS_FS=y
> > @@ -1241,6 +1207,5 @@ CONFIG_MAGIC_SYSRQ=y
> > ?CONFIG_DEBUG_FS=y
> > ?CONFIG_DEBUG_KERNEL=y
> > ?# CONFIG_SCHED_DEBUG is not set
> > -# CONFIG_DEBUG_PREEMPT is not set
> > ?# CONFIG_FTRACE is not set
> > ?CONFIG_MEMTEST=y
> > 
> 
> 
> Best regards,
> Krzysztof

Cheers

Marcel

From marcel.ziswiler at toradex.com  Fri Jan 14 05:25:50 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 13:25:50 +0000
Subject: [PATCH v1 06/14] arm64: defconfig: build r8169 as a module
In-Reply-To: <c3962f91-7183-dd12-f645-629acd0cf076@kernel.org>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-7-marcel@ziswiler.com>
 <c3962f91-7183-dd12-f645-629acd0cf076@kernel.org>
Message-ID: <0b32fc4f62905122042539ab3856fb670cfa0355.camel@toradex.com>

On Mon, 2022-01-10 at 09:40 +0100, Krzysztof Kozlowski wrote:
> On 07/01/2022 19:03, Marcel Ziswiler wrote:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > Build Realtek Gigabit Ethernet driver as a module.
> 
> Why?
> 
> We see what the patch does easily, so no really need of explaining it.
> What is needed here is to explain why do you do it? What board needs it?

Yes, I will do so in v2. Thanks!

[snip]
> Best regards,
> Krzysztof

Cheers

Marcel

From marcel.ziswiler at toradex.com  Fri Jan 14 05:28:11 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 13:28:11 +0000
Subject: [PATCH v1 14/14] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <c80ac4a7-d401-00c3-c6c2-61bc9a600590@kernel.org>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-15-marcel@ziswiler.com>
 <c80ac4a7-d401-00c3-c6c2-61bc9a600590@kernel.org>
Message-ID: <5fd41ac1242e0cebbb77eb1a83c3f4350c34296f.camel@toradex.com>

On Mon, 2022-01-10 at 09:47 +0100, Krzysztof Kozlowski wrote:
> On 07/01/2022 19:03, Marcel Ziswiler wrote:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > This patch adds the device tree to support Toradex Verdin iMX8M Mini a
> > computer on module which can be used on different carrier boards.
> > 
> > The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
> > Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
> > 1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
> > RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
> > Wi-Fi module.
> > 
> > Anything that is not self-contained on the module is disabled by
> > default.
> > 
> > The device tree for the Dahlia includes the module's device tree and
> > enables the supported peripherals of the carrier board.
> > 
> > The device tree for the Verdin Development Board includes the module's
> > device tree as well as the Dahlia one as it is a superset and supports
> > almost all peripherals available.
> > 
> > So far there is no display functionality supported at all but basic
> > console UART, USB host, eMMC and Ethernet and PCIe functionality work
> > fine.
> > 
> > Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > ---
> > 
> > ?arch/arm64/boot/dts/freescale/Makefile??????? |??? 4 +
> > ?.../dts/freescale/imx8mm-verdin-dahlia.dtsi?? |? 143 ++
> > ?.../boot/dts/freescale/imx8mm-verdin-dev.dtsi |?? 67 +
> > ?.../imx8mm-verdin-nonwifi-dahlia.dts????????? |?? 18 +
> > ?.../freescale/imx8mm-verdin-nonwifi-dev.dts?? |?? 18 +
> > ?.../dts/freescale/imx8mm-verdin-nonwifi.dtsi? |?? 75 +
> > ?.../freescale/imx8mm-verdin-wifi-dahlia.dts?? |?? 18 +
> > ?.../dts/freescale/imx8mm-verdin-wifi-dev.dts? |?? 18 +
> > ?.../dts/freescale/imx8mm-verdin-wifi.dtsi???? |?? 95 ++
> > ?.../boot/dts/freescale/imx8mm-verdin.dtsi???? | 1277 +++++++++++++++++
> > ?10 files changed, 1733 insertions(+)
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
> > ?create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
> > 
> 
> (...)
> 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-
> > verdin.dtsi
> > new file mode 100644
> > index 000000000000..23eb695a5266
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
> > @@ -0,0 +1,1277 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
> > +/*
> > + * Copyright 2022 Toradex
> > + */
> > +
> > +#include "dt-bindings/pwm/pwm.h"
> > +#include "imx8mm.dtsi"
> > +
> > +/ {
> > +???????chosen {
> > +???????????????bootargs = "console=ttymxc0,115200 earlycon";
> 
> earlycon is a debug tool, so should not be part of mainline DTS by
> default. Entire bootargs property looks actually not needed.

Yes, I will remove it in v2.

> > +???????????????stdout-path = &uart1;
> > +???????};
> > +
> 
> (...)
> 
> > +/* Verdin ETH_1 (On-module PHY) */
> > +&fec1 {
> > +???????fsl,magic-packet;
> > +???????phy-handle = <&ethphy0>;
> > +???????phy-mode = "rgmii-id";
> > +???????phy-supply = <&reg_ethphy>;
> > +???????pinctrl-names = "default", "sleep";
> > +???????pinctrl-0 = <&pinctrl_fec1>;
> > +???????pinctrl-1 = <&pinctrl_fec1_sleep>;
> > +
> > +???????mdio {
> > +???????????????#address-cells = <1>;
> > +???????????????#size-cells = <0>;
> > +
> > +???????????????ethphy0: ethernet-phy at 7 {
> > +???????????????????????compatible = "ethernet-phy-ieee802.3-c22";
> > +???????????????????????interrupt-parent = <&gpio1>;
> > +???????????????????????interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
> > +???????????????????????micrel,led-mode = <0>;
> > +???????????????????????reg = <7>;
> > +???????????????};
> > +???????};
> > +};
> > +
> > +/* Verdin QSPI_1 */
> > +&flexspi {
> > +???????pinctrl-names = "default";
> > +???????pinctrl-0 = <&pinctrl_flexspi0>;
> > +#if 0
> 
> Please drop it or explain with a comment why we need dead code in Linux
> kernel.

Yes, I agree.

> > +???????flash at 0 {
> > +???????????????#address-cells = <1>;
> > +???????????????#size-cells = <1>;
> > +???????????????compatible = "jedec,spi-nor";
> > +???????????????reg = <0>;
> > +???????????????spi-max-frequency = <80000000>;
> > +???????};
> > +#endif
> > +};
> > +

Thanks for your review.

> Best regards,
> Krzysztof

Cheers

Marcel

From marcel.ziswiler at toradex.com  Fri Jan 14 05:39:27 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 13:39:27 +0000
Subject: [PATCH v1 05/14] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <06d3ff4c-3c82-1b04-3dc7-3a6effe4cc3e@i2se.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-6-marcel@ziswiler.com>
 <06d3ff4c-3c82-1b04-3dc7-3a6effe4cc3e@i2se.com>
Message-ID: <0d9e38ad27cf0bebc73e104d8ea462e7cf319e40.camel@toradex.com>

Hi Stefan

On Thu, 2022-01-13 at 19:42 +0100, Stefan Wahren wrote:
> Hi Marcel,
> 
> Am 07.01.22 um 19:03 schrieb Marcel Ziswiler:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > This avoids firmware load error and sysfs fallback reported as follows:
> > 
> > [??? 0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
> > ?for imx/sdma/sdma-imx7d.bin failed with error -2
> > [??? 0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
> > ?fallback for: imx/sdma/sdma-imx7d.bin
> 
> unfortunately this isn't an explanation why this solve the issue. It
> looks like that the SDMA firmware is not available for the kernel. Build
> the driver as a module hide the issue and just load it if the rootfs is
> available.

Well, it seems to default to some built-in firmware which, unfortunately, might have some severe known errata
anyway.

> What makes you sure that the driver is not critical for other boards
> during boot?

That is a good question. I remember that there was some more discussion back when I proposed the same change
for imx_v6_v7_defconfig in the 32-bit Arm world. While nobody was able to fully answer it all it did get
accepted by the i.MX maintainer back in the day [1]. I will mention that in v2.

[1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/

Thanks for your review.

> Best regards
> 
> > 
> > Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > ---
> > 
> > ?arch/arm64/configs/defconfig | 2 +-
> > ?1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 3c8106c5776a..a18785a827dc 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -915,7 +915,7 @@ CONFIG_DMADEVICES=y
> > ?CONFIG_DMA_BCM2835=y
> > ?CONFIG_DMA_SUN6I=m
> > ?CONFIG_FSL_EDMA=y
> > -CONFIG_IMX_SDMA=y
> > +CONFIG_IMX_SDMA=m
> > ?CONFIG_K3_DMA=y
> > ?CONFIG_MV_XOR=y
> > ?CONFIG_MV_XOR_V2=y

Cheers

Marcel

From andriy.shevchenko at linux.intel.com  Fri Jan 14 05:38:27 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 14 Jan 2022 15:38:27 +0200
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <52901ebe0db555f8e58dc0d59cfd703c5a0fc2de.camel@mediatek.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
 <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
 <83670f12a4eda1d8aecde3c0bf225642106d1267.camel@mediatek.com>
 <YeADWXPGPW253ssR@smile.fi.intel.com>
 <52901ebe0db555f8e58dc0d59cfd703c5a0fc2de.camel@mediatek.com>
Message-ID: <YeF806Ucigo5vWmx@smile.fi.intel.com>

On Fri, Jan 14, 2022 at 11:06:36AM +0800, Axe Yang wrote:
> On Thu, 2022-01-13 at 12:47 +0200, Andy Shevchenko wrote:
> > On Thu, Jan 13, 2022 at 03:58:52PM +0800, Axe Yang wrote:
> > > On Tue, 2022-01-11 at 13:46 +0200, Andy Shevchenko wrote:
> > > > On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:

...

> > > > > +		host->pins_eint = pinctrl_lookup_state(host-
> > > > > >pinctrl,
> > > > > "state_eint");
> > > > > +		if (IS_ERR(host->pins_eint)) {
> > > > > +			dev_dbg(&pdev->dev, "Cannot find
> > > > > pinctrl
> > > > > eint!\n");
> > > > 
> > > > In debug mode of pin control this will bring a duplicate message.
> > > 
> > > Can you explain more about this comment?
> > > I don't understand what the 'duplicate message' refers for.
> > 
> > Have you chance to read the implementation of pinctrl_lookup_state()?
> 
> I have read pinctrl_lookup_state(), and if the 'duplicate message' you
> were talking about is 'using pinctrl dummy state...':
> 
> https://elixir.bootlin.com/linux/latest/source/drivers/pinctrl/core.c#L1214
> No, this message will not appear in debug mode if pins_eint not found
> because pinctrl_dummy_state is always FALSE. MTK Soc do not need dummy
> state support.

I see, thanks for explanation. I'm wondering how good or bad would be
the idea of adding a debug message on the !pinctrl_dummy_state case.

-- 
With Best Regards,
Andy Shevchenko




From alyssa at collabora.com  Fri Jan 14 05:47:45 2022
From: alyssa at collabora.com (Alyssa Rosenzweig)
Date: Fri, 14 Jan 2022 08:47:45 -0500
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>
Message-ID: <YeF/AYZ0DuKGwLLk@maud>

> > That links to an internal Google issue tracker which I assume has more
> > information on the bug. I would appreciate if someone from Google or
> > MediaTek could explain what this change actually does and why it's
> > necessary on MT8192.
> > 
> > At any rate, this register logically belongs to the MT8192 "infra" clock
> > device, so it makes sense to set it there too. This avoids adding any
> > platform-specific hacks to the 3D driver, either mainline (Panfrost) or
> > legacy (kbase).
> 
> Does this really have anything to do with clocks?

I have no idea. MediaTek, Google, please explain.

> In particular, "ACP" usually refers to the Accelerator Coherency Port
> of a CPU cluster or DSU, and given the stated symptom of the issue
> affected by it, my first guess would be that this bit might indeed
> control routing of GPU traffic either to the ACP or the (presumably
> non-coherent) main interconnect.

I'd easily believe that.

> If that is the case, I think this would logically belong as a SoC-specific
> quirk in panfrost, where we'd need to retrieve the syscon regmap for
> ourselves (see around line 800 of drivers/iommu/mtk_iommu.c for a similar
> example).

Alright. Doing this in panfrost seems ugly but if that's the right place
for it, that's the right place for it.


From lkp at intel.com  Fri Jan 14 05:48:22 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 14 Jan 2022 21:48:22 +0800
Subject: [xilinx-xlnx:master 157/326] ERROR: modpost:
 "dwc3_host_wakeup_capable" [drivers/usb/host/xhci-plat-hcd.ko] undefined!
Message-ID: <202201142131.Ms9Tqhl7-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 5b2efd9328312427b7830d41ce3c8dfec63457eb [157/326] usb: xhci-plat: Add remote wakeup support for xilinx
config: x86_64-randconfig-a003 (https://download.01.org/0day-ci/archive/20220114/202201142131.Ms9Tqhl7-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 82c8aca93488730ce8f66101e0f3538f14b551dd)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/5b2efd9328312427b7830d41ce3c8dfec63457eb
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 5b2efd9328312427b7830d41ce3c8dfec63457eb
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "dwc3_host_wakeup_capable" [drivers/usb/host/xhci-plat-hcd.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From qperret at google.com  Fri Jan 14 05:49:12 2022
From: qperret at google.com (Quentin Perret)
Date: Fri, 14 Jan 2022 13:49:12 +0000
Subject: [PATCH] KVM: arm64: pkvm: Use the mm_ops indirection for cache
 maintenance
In-Reply-To: <20220114125038.1336965-1-maz@kernel.org>
References: <20220114125038.1336965-1-maz@kernel.org>
Message-ID: <YeF/WMXe4HL/n8qw@google.com>

On Friday 14 Jan 2022 at 12:50:38 (+0000), Marc Zyngier wrote:
> CMOs issued from EL2 cannot directly use the kernel helpers,
> as EL2 doesn't have a mapping of the guest pages. Oops.
> 
> Instead, use the mm_ops indirection to use helpers that will
> perform a mapping at EL2 and allow the CMO to be effective.

Right, we were clearly lucky not to use those paths at EL2 _yet_, but
that's going to change soon and this is better for consistency, so:

Reviewed-by: Quentin Perret <qperret at google.com>

> Fixes: 25aa28691bb9 ("KVM: arm64: Move guest CMOs to the fault handlers")
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/hyp/pgtable.c | 18 ++++++------------
>  1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
> index 844a6f003fd5..2cb3867eb7c2 100644
> --- a/arch/arm64/kvm/hyp/pgtable.c
> +++ b/arch/arm64/kvm/hyp/pgtable.c
> @@ -983,13 +983,9 @@ static int stage2_unmap_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
>  	 */
>  	stage2_put_pte(ptep, mmu, addr, level, mm_ops);
>  
> -	if (need_flush) {
> -		kvm_pte_t *pte_follow = kvm_pte_follow(pte, mm_ops);
> -
> -		dcache_clean_inval_poc((unsigned long)pte_follow,
> -				    (unsigned long)pte_follow +
> -					    kvm_granule_size(level));
> -	}
> +	if (need_flush && mm_ops->dcache_clean_inval_poc)
> +		mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
> +					       kvm_granule_size(level));
>  
>  	if (childp)
>  		mm_ops->put_page(childp);
> @@ -1151,15 +1147,13 @@ static int stage2_flush_walker(u64 addr, u64 end, u32 level, kvm_pte_t *ptep,
>  	struct kvm_pgtable *pgt = arg;
>  	struct kvm_pgtable_mm_ops *mm_ops = pgt->mm_ops;
>  	kvm_pte_t pte = *ptep;
> -	kvm_pte_t *pte_follow;
>  
>  	if (!kvm_pte_valid(pte) || !stage2_pte_cacheable(pgt, pte))
>  		return 0;
>  
> -	pte_follow = kvm_pte_follow(pte, mm_ops);
> -	dcache_clean_inval_poc((unsigned long)pte_follow,
> -			    (unsigned long)pte_follow +
> -				    kvm_granule_size(level));
> +	if (mm_ops->dcache_clean_inval_poc)
> +		mm_ops->dcache_clean_inval_poc(kvm_pte_follow(pte, mm_ops),
> +					       kvm_granule_size(level));
>  	return 0;
>  }
>  
> -- 
> 2.30.2
> 


From narmstrong at baylibre.com  Fri Jan 14 05:56:29 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 14:56:29 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>

Hi,

On 14/01/2022 12:08, Biju Das wrote:
> Hi Neil,
> 
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> On 14/01/2022 09:29, Biju Das wrote:
>>> Hi Neil,
>>>
>>> + renesas-soc
>>>
>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks")
>>>>
>>>> Hi,
>>>>
>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>> Hi Biju,
>>>>>
>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>> <biju.das.jz at bp.renesas.com>
>>>> wrote:
>>>>>>
>>>>>> Hi All,
>>>>>>
>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>> till the commit
>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks").
>>>>>>
>>>>>> After this patch, the screen becomes greenish(may be it is setting
>>>>>> it
>>>> into YUV format??).
>>>>>>
>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>> callback
>>>> and set colour as RGB24.
>>>>>>
>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback, I
>>>>>> see
>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>
>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>
>>>> This patch was introduced to maintain the bridge color format
>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it seems
>>>> it behaves incorrectly if the first bridge doesn't implement the
>>>> negotiation callbacks.
>>>>
>>>> Let me check the code to see how to fix that.
>>>
>>> Thanks for the information, I am happy to test the patch/fix.
>>>
>>> Cheers,
>>> Biju
>>>
>>>>
>>>>>
>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>> shows:
>>>>>
>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with HDCP
>>>>> (DWC HDMI 3D TX PHY)
>>>>>
>>>>> The colors are shown correctly here.
>>>>>
>>>>
>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the negotiation
>>>> fails and use the RGB fallback input & output format.
>>>>
>>>> Anyway thanks for testing
>>>>
>>>> Neil
>>
>> Can you test :
>>
>> ==><===============================
>> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
>> index c96847fc0ebc..7019acd37716 100644
>> --- a/drivers/gpu/drm/drm_bridge.c
>> +++ b/drivers/gpu/drm/drm_bridge.c
>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>> drm_bridge *bridge,
>>         last_bridge_state = drm_atomic_get_new_bridge_state(crtc_state-
>>> state,
>>                                                             last_bridge);
>>
>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>> +       /*
>> +        * Only negociate with real values if both end of the bridge chain
>> +        * support negociation callbacks, otherwise you can end in a
>> situation
>> +        * where the selected output format doesn't match with the first
>> bridge
>> +        * output format.
>> +        */
>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>                 const struct drm_bridge_funcs *funcs = last_bridge->funcs;
>>
>>                 /*
>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>> drm_bridge *bridge,
>>                 if (!out_bus_fmts)
>>                         return -ENOMEM;
>>
>> -               if (conn->display_info.num_bus_formats &&
>> +               /*
>> +                * If first bridge doesn't support negociation, use
>> MEDIA_BUS_FMT_FIXED
>> +                * as a safe value for the whole bridge chain
>> +                */
>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>> +                   conn->display_info.num_bus_formats &&
>>                     conn->display_info.bus_formats)
>>                         out_bus_fmts[0] = conn-
>>> display_info.bus_formats[0];
>>                 else
>> ==><===============================
>>
>> This should exclude your situation where the first bridge doesn't support
>> negociation.
> 
> I have tested this fix with Linux next-20220114. Still I see colour issue.
> 
> It is still negotiating and it is calling get_output_fmt_callbck
> 
> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=0#########
> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=2#########
> 
> And In get_input_fmt callback, I See the outputformat as YUV16 instead of RGB24.
> 
> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16#########
> [    3.473644] ########hdmi_video_sample MEDIA_BUS_FMT_UYVY8_1X16#########

OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the encoder.

Let me figure that out, no sure I can find a clean solution except putting back RGB24 before YUV.

Anyway please test that:

==><===============================
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..68f79094f648 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2589,45 +2589,44 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
 	}

 	/*
-	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
+	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
 	 * if supported. In any case the default RGB888 format is added
 	 */

 	if (max_bpc >= 16 && info->bpc == 16) {
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
+
 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
-
-		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
 	}

 	if (max_bpc >= 12 && info->bpc >= 12) {
-		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;

 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;

-		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
+		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
 	}

 	if (max_bpc >= 10 && info->bpc >= 10) {
-		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
+		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;

 		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;

-		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
+		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
 	}

-	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
-		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
+	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;

 	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
 		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;

-	/* Default 8bit RGB fallback */
-	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
+	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
+		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;

 	*num_output_fmts = i;

==><===============================

Neil

> 
> Regards,
> Biju
> 



From guoheyi at linux.alibaba.com  Fri Jan 14 06:01:07 2022
From: guoheyi at linux.alibaba.com (Heyi Guo)
Date: Fri, 14 Jan 2022 22:01:07 +0800
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
In-Reply-To: <CACPK8XcYp9iAD3fjBQCax41C-1UpA+1AQW3epyEooYzNLt7R5g@mail.gmail.com>
References: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
 <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>
 <CACPK8XcYp9iAD3fjBQCax41C-1UpA+1AQW3epyEooYzNLt7R5g@mail.gmail.com>
Message-ID: <e62fba0b-ebb9-934a-d7cf-6da33ecc4335@linux.alibaba.com>

Hi Joel,


? 2022/1/11 ??6:51, Joel Stanley ??:
> On Tue, 11 Jan 2022 at 07:52, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
>> Hi all,
>>
>> Any comments?
>>
>> Thanks,
>>
>> Heyi
>>
>> ? 2022/1/9 ??9:26, Heyi Guo ??:
>>> The memory will be freed by the caller if transfer timeout occurs,
>>> then it would trigger kernel panic if the peer device responds with
>>> something after timeout and triggers the interrupt handler of aspeed
>>> i2c driver.
>>>
>>> Set the msgs pointer to NULL to avoid invalid memory reference after
>>> timeout to fix this potential kernel panic.
> Thanks for the patch. How did you discover this issue? Do you have a
> test I can run to reproduce the crash?

We are using one i2c channel to communicate with another MCU by 
implementing user space SSIF protocol, and the MCU may not respond in 
time if it is busy. If it responds after timeout occurs, it will trigger 
below kernel panic:

[11844.248998] 8<--- cut here ---
[11844.252419] Unhandled fault: page domain fault (0x81b) at 0x7edb2ff5
[11844.259509] pgd = aa62a338
[11844.262524] [7edb2ff5] *pgd=b5bee835, *pte=b020275f, *ppte=b0202c7f
[11844.269525] Internal error: : 81b [#1] SMP ARM
[11844.274479] Modules linked in: [last unloaded: i2c_dev_sysfs]
[11844.280895] CPU: 0 PID: 256 Comm: ssif-host Tainted: G?????????? 
O????? 5.4.39-e0b210f #1
[11844.290016] Hardware name: Generic DT based system
[11844.295367] PC is at aspeed_i2c_master_irq+0xc8/0x498
[11844.301001] LR is at 0x16
[11844.303917] pc : [<80636b4c>]??? lr : [<00000016>]??? psr: 000f0193
[11844.310905] sp : b5c53ce8? ip : 7edb2fe0? fp : b5c53d04
[11844.316730] r10: b5c52000? r9 : 00000000? r8 : 0000002e
[11844.322554] r7 : 00000001? r6 : 00000004? r5 : 00000004? r4 : b4b91440
[11844.329825] r3 : 00000000? r2 : b642448c? r1 : 00000015? r0 : 00000000
[11844.337107] Flags: nzcv? IRQs off? FIQs on? Mode SVC_32? ISA ARM? 
Segment none
[11844.345163] Control: 10c5387d? Table: b5a9006a? DAC: 00000051
[11844.351572] Process ssif-host (pid: 256, stack limit = 0xbe5df348)
[11844.358466] Stack: (0xb5c53ce8 to 0xb5c54000)
[11844.363325] 3ce0:?????????????????? b4b91440 00000004 b4b916bc 
00000001 b5c53d2c b5c53d08
[11844.372451] 3d00: 80636f80 80636a90 b4b8d140 80c052e4 b91e8068 
00000001 0000002e 00000000
[11844.381577] 3d20: b5c53d6c b5c53d30 8017b13c 80636f28 80839580 
b53a8600 b91e8000 b5c53d70
[11844.390702] 3d40: 80c8fcb4 b91e8000 80c052e4 b91e8068 00000001 
b900c800 b5c53e28 b648863c
[11844.399828] 3d60: b5c53d8c b5c53d70 8017b348 8017b0f4 00000000 
80c04c48 b91e8000 80c052e4
[11844.408954] 3d80: b5c53dac b5c53d90 8017b3fc 8017b318 b91e8000 
80c052e4 00000000 00000001
[11844.418079] 3da0: b5c53dc4 b5c53db0 801800f4 8017b3b0 0000002e 
80b771c0 b5c53dd4 b5c53dc8
[11844.427205] 3dc0: 8017a1bc 80180040 b5c53dfc b5c53dd8 8017a8d0 
8017a198 bf80200c 000003ff
[11844.436330] 3de0: 80c052e4 bf802000 00000000 b5c53e28 b5c53e24 
b5c53e00 801022f8 8017a87c
[11844.445456] 3e00: 80634000 200f0013 ffffffff b5c53e5c b6488640 
b5c52000 b5c53eac b5c53e28
[11844.454583] 3e20: 80101aac 801022b8 b6488640 38c3f000 00000059 
80b7ca58 7edb2974 00000000
[11844.463709] 3e40: b6424480 00000002 b6488640 b6424480 b648863c 
b5c53eac 0000005d b5c53e78
[11844.472835] 3e60: 00000001 80634000 200f0013 ffffffff 00000051 
7f000000 00000018 b53a8600
[11844.481960] 3e80: 00000018 7edb2974 00000000 b53a8600 00000051 
b4c5ce40 b5c52000 00000036
[11844.491086] 3ea0: b5c53ee4 b5c53eb0 80634850 80633fc0 b5fd3015 
802a7770 7edb2990 00000002
[11844.500212] 3ec0: b4b94778 80c04c48 7edb2974 b4b94778 b4c5ce40 
00000007 b5c53f6c b5c53ee8
[11844.509338] 3ee0: 802c6c48 80634528 00000020 b4b94778 b4c5ce48 
00000142 b5c53f34 b5c53f08
[11844.518463] 3f00: 802a604c 802a5e2c 00000000 00000000 00000000 
00000000 00000000 b5fd3000
[11844.527589] 3f20: b4c5ce40 b5fd3000 b5c53f4c b5c53f38 802c27e0 
802a6010 00000007 80c04c48
[11844.536715] 3f40: b5c53f94 b4c5ce40 00000007 00000707 7edb2974 
b4c5ce40 b5c52000 00000036
[11844.545841] 3f60: b5c53f94 b5c53f70 802c71dc 802c6870 00000007 
00000016 0000000c 00000036
[11844.554967] 3f80: 80101204 b5c52000 b5c53fa4 b5c53f98 802c7220 
802c71a4 00000000 b5c53fa8
[11844.564092] 3fa0: 80101000 802c7214 00000007 00000016 00000007 
00000707 7edb2974 7edb2990
[11844.573218] 3fc0: 00000007 00000016 0000000c 00000036 7edb2be1 
7edb2fe0 00000030 76f436b4
[11844.582344] 3fe0: 0004d110 7edb2964 00033f48 45f2ffac 200f0010 
00000007 00000000 00000000
[11844.591464] Backtrace:
[11844.594189] [<80636a84>] (aspeed_i2c_master_irq) from [<80636f80>] 
(aspeed_i2c_bus_irq+0x64/0x180)
[11844.604187]? r7:00000001 r6:b4b916bc r5:00000004 r4:b4b91440
[11844.610506] [<80636f1c>] (aspeed_i2c_bus_irq) from [<8017b13c>] 
(__handle_irq_event_percpu+0x54/0x224)
[11844.620893]? r9:00000000 r8:0000002e r7:00000001 r6:b91e8068 
r5:80c052e4 r4:b4b8d140
[11844.629537] [<8017b0e8>] (__handle_irq_event_percpu) from 
[<8017b348>] (handle_irq_event_percpu+0x3c/0x98)
[11844.640311]? r10:b648863c r9:b5c53e28 r8:b900c800 r7:00000001 
r6:b91e8068 r5:80c052e4
[11844.649044]? r4:b91e8000
[11844.651861] [<8017b30c>] (handle_irq_event_percpu) from [<8017b3fc>] 
(handle_irq_event+0x58/0x7c)
[11844.661759]? r5:80c052e4 r4:b91e8000
[11844.665747] [<8017b3a4>] (handle_irq_event) from [<801800f4>] 
(handle_fasteoi_irq+0xc0/0x180)
[11844.675259]? r7:00000001 r6:00000000 r5:80c052e4 r4:b91e8000
[11844.681574] [<80180034>] (handle_fasteoi_irq) from [<8017a1bc>] 
(generic_handle_irq+0x30/0x44)
[11844.691181]? r5:80b771c0 r4:0000002e
[11844.695169] [<8017a18c>] (generic_handle_irq) from [<8017a8d0>] 
(__handle_domain_irq+0x60/0xc4)
[11844.704878] [<8017a870>] (__handle_domain_irq) from [<801022f8>] 
(gic_handle_irq+0x4c/0x94)
[11844.714198]? r9:b5c53e28 r8:00000000 r7:bf802000 r6:80c052e4 
r5:000003ff r4:bf80200c
[11844.722838] [<801022ac>] (gic_handle_irq) from [<80101aac>] 
(__irq_svc+0x6c/0x90)
[11844.731185] Exception stack(0xb5c53e28 to 0xb5c53e70)
[11844.736819] 3e20:?????????????????? b6488640 38c3f000 00000059 
80b7ca58 7edb2974 00000000
[11844.745945] 3e40: b6424480 00000002 b6488640 b6424480 b648863c 
b5c53eac 0000005d b5c53e78
[11844.755068] 3e60: 00000001 80634000 200f0013 ffffffff
[11844.760704]? r9:b5c52000 r8:b6488640 r7:b5c53e5c r6:ffffffff 
r5:200f0013 r4:80634000
[11844.769347] [<80633fb4>] (i2cdev_ioctl_rdwr) from [<80634850>] 
(i2cdev_ioctl+0x334/0x3bc)
[11844.778473]? r10:00000036 r9:b5c52000 r8:b4c5ce40 r7:00000051 
r6:b53a8600 r5:00000000
[11844.787206]? r4:7edb2974
[11844.790024] [<8063451c>] (i2cdev_ioctl) from [<802c6c48>] 
(do_vfs_ioctl+0x3e4/0x934)
[11844.798664]? r7:00000007 r6:b4c5ce40 r5:b4b94778 r4:7edb2974
[11844.804979] [<802c6864>] (do_vfs_ioctl) from [<802c71dc>] 
(ksys_ioctl+0x44/0x70)
[11844.813232]? r10:00000036 r9:b5c52000 r8:b4c5ce40 r7:7edb2974 
r6:00000707 r5:00000007
[11844.821966]? r4:b4c5ce40
[11844.824781] [<802c7198>] (ksys_ioctl) from [<802c7220>] 
(sys_ioctl+0x18/0x1c)
[11844.832745]? r9:b5c52000 r8:80101204 r7:00000036 r6:0000000c 
r5:00000016 r4:00000007
[11844.841385] [<802c7208>] (sys_ioctl) from [<80101000>] 
(ret_fast_syscall+0x0/0x54)
[11844.849827] Exception stack(0xb5c53fa8 to 0xb5c53ff0)
[11844.855453] 3fa0:?????????????????? 00000007 00000016 00000007 
00000707 7edb2974 7edb2990
[11844.864578] 3fc0: 00000007 00000016 0000000c 00000036 7edb2be1 
7edb2fe0 00000030 76f436b4
[11844.873701] 3fe0: 0004d110 7edb2964 00033f48 45f2ffac
[11844.879337] Code: e1a03423 e281e001 e6ef3073 e584e2a4 (e7cc3001)
[11844.886143] ---[ end trace 9422f39bd8d33cb5 ]---

After applying this patch, we'll get below warning instead:

"bus in unknown state. irq_status: 0x%x\n"

The issue can be reproduced more easily by setting the timeout to some 
smaller value.

>
> Can you provide a Fixes tag?

I think the bug was introduced by the first commit of this file :(

f327c686d3ba44eda79a2d9e02a6a242e0b75787


>
> Do other i2c master drivers do this? I took a quick look at the meson
> driver and it doesn't appear to clear it's pointer to msgs.

It is hard to say. It seems other drivers have some recover scheme like 
aborting the transfer, or loop each messages in process context and 
don't do much in IRQ handler, which may disable interrupts or not retain 
the buffer pointer before returning timeout.

Thanks,

Heyi


>
>>> Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>
>>>
>>> -------
>>>
>>> Cc: Brendan Higgins <brendanhiggins at google.com>
>>> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
>>> Cc: Joel Stanley <joel at jms.id.au>
>>> Cc: Andrew Jeffery <andrew at aj.id.au>
>>> Cc: Philipp Zabel <p.zabel at pengutronix.de>
>>> Cc: linux-i2c at vger.kernel.org
>>> Cc: openbmc at lists.ozlabs.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-aspeed at lists.ozlabs.org
>>> ---
>>>    drivers/i2c/busses/i2c-aspeed.c | 5 +++++
>>>    1 file changed, 5 insertions(+)
>>>
>>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>>> index 67e8b97c0c950..3ab0396168680 100644
>>> --- a/drivers/i2c/busses/i2c-aspeed.c
>>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>>> @@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>>>                spin_lock_irqsave(&bus->lock, flags);
>>>                if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
>>>                        bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
>>> +             /*
>>> +              * All the buffers may be freed after returning to caller, so
>>> +              * set msgs to NULL to avoid memory reference after freeing.
>>> +              */
>>> +             bus->msgs = NULL;
>>>                spin_unlock_irqrestore(&bus->lock, flags);
>>>
>>>                return -ETIMEDOUT;


From marcel at ziswiler.com  Fri Jan 14 06:14:58 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:14:58 +0100
Subject: [PATCH v2 02/11] dt-bindings: gpio: fix gpio-hog example
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-3-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Even if this is no yaml yet at least fix the example to be compliant to
later schema as e.g. found in gpio-pca95xx.yaml, fairchild,74hc595.yaml
and gpio/fsl-imx-gpio.yaml.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Rob Herring <robh at kernel.org>

---

Changes in v2:
- Added Rob's ack.

 Documentation/devicetree/bindings/gpio/gpio.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
index a8895d339bfe..5663e71b751f 100644
--- a/Documentation/devicetree/bindings/gpio/gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio.txt
@@ -213,7 +213,7 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
 		gpio-controller;
 		#gpio-cells = <2>;
 
-		line_b {
+		line_b-hog {
 			gpio-hog;
 			gpios = <6 0>;
 			output-low;
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:00 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:00 +0100
Subject: [PATCH v2 04/11] arm64: defconfig: enable pcieaer configuration
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-5-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_PCIEAER which is required for CONFIG_ACPI_APEI_PCIEAER.
Commit 8c8ff55b4da7 ("PCI/AER: Don't select CONFIG_PCIEAER by default")
changed it to no longer being enabled by default.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- New patch following full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index dec189229c0a..7daf2de6c31a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -211,6 +211,7 @@ CONFIG_NFC_NCI=m
 CONFIG_NFC_S3FWRN5_I2C=m
 CONFIG_PCI=y
 CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
 CONFIG_PCI_IOV=y
 CONFIG_PCI_PASID=y
 CONFIG_HOTPLUG_PCI=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:14:57 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:14:57 +0100
Subject: [PATCH v2 01/11] arm64: dts: imx8mm: fix strange hex notation
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-2-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Fix strange hex notation with mixed lower-case and upper-case letters.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

---

Changes in v2:
- Added Laurent's reviewed-by tag.

 arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6af3353..c68a5e456025 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -279,7 +279,7 @@
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
-#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53c 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53C 0x4 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
@@ -486,7 +486,7 @@
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                0x1D8 0x440 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
-#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4Fc 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4FC 0x4 0x2
 #define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                 0x1D8 0x440 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
@@ -494,7 +494,7 @@
 #define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
 #define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX                                  0x1DC 0x444 0x000 0x4 0x0
-#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4Fc 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4FC 0x4 0x3
 #define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:14:59 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:14:59 +0100
Subject: [PATCH v2 03/11] arm64: defconfig: enable taskstats configuration
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-4-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_TASKSTATS which is required for CONFIG_TASK_XACCT (and
subsequently CONFIG_TASK_IO_ACCOUNTING). Previously, taskstats got
pulled in by KVM but that got changed in commit 63b3f96e1a98
("kvm: Select SCHED_INFO instead of TASK_DELAY_ACCT").

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- New patch following full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index cc5d3ba166b1..dec189229c0a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -7,6 +7,7 @@ CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:01 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:01 +0100
Subject: [PATCH v2 05/11] arm64: defconfig: rebuild default configuration
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-6-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Run "make defconfig; make savedefconfig" to rebuild defconfig.

This re-ordered the following configuration options:

CONFIG_BPF_JIT=y
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_INTEL_STRATIX10_SERVICE=y
CONFIG_INTEL_STRATIX10_RSU=m
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_IMX_SCU=y
CONFIG_IMX_SCU_PD=y
CONFIG_CAN_FLEXCAN=m
CONFIG_PCIE_LAYERSCAPE_GEN4=y
CONFIG_MTK_DEVAPC=m
CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
CONFIG_MESON_GXL_PHY=m
CONFIG_QCOM_CPR=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_QORIQ_THERMAL=m
CONFIG_SUN8I_THERMAL=y
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_LONTIUM_LT9611UXC=m
CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_COMMON_CLK_SCMI=y
CONFIG_IPQ_GCC_8074=y
CONFIG_SM_DISPCC_8250=y
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_ARCH_R8A774A1=y
CONFIG_ARCH_R8A774B1=y
CONFIG_ARCH_R8A774C0=y
CONFIG_ARCH_R8A774E1=y
CONFIG_ARCH_R8A77995=y
CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77965=y
CONFIG_ARCH_R8A77970=y
CONFIG_HISI_PMU=y
CONFIG_QCOM_QFPROM=y
CONFIG_MUX_MMIO=y

And dropped the following configuration options which are nowaday's
already enabled (resp. disabled) by default:

CONFIG_MEMCG_SWAP=y
CONFIG_SECCOMP=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_QCOM_SCM=y
# CONFIG_BT_HS is not set
CONFIG_FSL_MC_BUS=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_SND_SOC_FSL_SAI=m
CONFIG_USB_CONN_GPIO=m
CONFIG_USB_XHCI_PCI=m
CONFIG_MFD_CROS_EC_DEV=y
CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_SDM_GCC_845=y
CONFIG_SM_GCC_8150=y
CONFIG_SM_GCC_8250=y
CONFIG_SLIMBUS=m
CONFIG_INTERCONNECT=y
CONFIG_CONFIGFS_FS=y

CONFIG_POWER_AVS was renamed to POWER_AVS_OMAP in commit bca815d62054
("PM: AVS: smartreflex Move driver to soc specific drivers"). As there
are no 64-bit Arm OMAPs it getting dropped seems fair.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Done full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 108 ++++++++++++++---------------------
 1 file changed, 44 insertions(+), 64 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 7daf2de6c31a..bc39559c1658 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_JIT=y
 CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -14,7 +15,6 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
 CONFIG_BLK_CGROUP=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_HUGETLB=y
@@ -67,7 +67,6 @@ CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
 CONFIG_SCHED_SMT=y
 CONFIG_NUMA=y
-CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_KEXEC_FILE=y
 CONFIG_CRASH_DUMP=y
@@ -85,7 +84,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
@@ -98,15 +96,6 @@ CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
 CONFIG_ARM_SCMI_CPUFREQ=y
 CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_QORIQ_CPUFREQ=y
-CONFIG_ARM_SCMI_PROTOCOL=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_INTEL_STRATIX10_SERVICE=y
-CONFIG_INTEL_STRATIX10_RSU=m
-CONFIG_QCOM_SCM=y
-CONFIG_EFI_CAPSULE_LOADER=y
-CONFIG_IMX_SCU=y
-CONFIG_IMX_SCU_PD=y
 CONFIG_ACPI=y
 CONFIG_ACPI_APEI=y
 CONFIG_ACPI_APEI_GHES=y
@@ -183,14 +172,12 @@ CONFIG_NET_ACT_GATE=m
 CONFIG_QRTR=m
 CONFIG_QRTR_SMD=m
 CONFIG_QRTR_TUN=m
-CONFIG_BPF_JIT=y
 CONFIG_CAN=m
+CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
-CONFIG_CAN_FLEXCAN=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
-# CONFIG_BT_HS is not set
 # CONFIG_BT_LE is not set
 CONFIG_BT_LEDS=y
 # CONFIG_BT_DEBUGFS is not set
@@ -230,7 +217,6 @@ CONFIG_PCIE_ROCKCHIP_HOST=m
 CONFIG_PCIE_BRCMSTB=m
 CONFIG_PCI_IMX6=y
 CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
@@ -238,6 +224,7 @@ CONFIG_PCIE_KIRIN=y
 CONFIG_PCIE_HISI_STB=y
 CONFIG_PCIE_TEGRA194_HOST=m
 CONFIG_PCIE_VISCONTI_HOST=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
 CONFIG_PCI_ENDPOINT=y
 CONFIG_PCI_ENDPOINT_CONFIGFS=y
 CONFIG_PCI_EPF_TEST=m
@@ -245,8 +232,15 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_HISILICON_LPC=y
-CONFIG_FSL_MC_BUS=y
 CONFIG_TEGRA_ACONNECT=m
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_INTEL_STRATIX10_SERVICE=y
+CONFIG_INTEL_STRATIX10_RSU=m
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -266,8 +260,6 @@ CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_MTK_DEVAPC=m
-CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -353,13 +345,11 @@ CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
 CONFIG_TI_K3_AM65_CPSW_NUSS=y
 CONFIG_QCOM_IPA=m
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MESON_GXL_PHY=m
 CONFIG_AQUANTIA_PHY=y
 CONFIG_BCM54140_PHY=m
 CONFIG_MARVELL_PHY=m
 CONFIG_MARVELL_10G_PHY=m
-CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_MICROSEMI_PHY=y
 CONFIG_AT803X_PHY=y
@@ -367,6 +357,8 @@ CONFIG_REALTEK_PHY=y
 CONFIG_ROCKCHIP_PHY=y
 CONFIG_DP83867_PHY=y
 CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
@@ -474,6 +466,7 @@ CONFIG_SPI=y
 CONFIG_SPI_ARMADA_3700=y
 CONFIG_SPI_BCM2835=m
 CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_SPI_DESIGNWARE=m
 CONFIG_SPI_DW_DMA=y
 CONFIG_SPI_DW_MMIO=m
@@ -545,9 +538,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
-CONFIG_POWER_AVS=y
-CONFIG_QCOM_CPR=y
-CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_QCOM_PON=m
 CONFIG_POWER_RESET_XGENE=y
@@ -555,10 +545,10 @@ CONFIG_POWER_RESET_SYSCON=y
 CONFIG_SYSCON_REBOOT_MODE=y
 CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_BQ27XXX=y
-CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_BQ25890=m
 CONFIG_CHARGER_BQ25980=m
+CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
 CONFIG_SENSORS_LM90=m
@@ -570,10 +560,10 @@ CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
-CONFIG_QORIQ_THERMAL=m
-CONFIG_SUN8I_THERMAL=y
 CONFIG_IMX_SC_THERMAL=m
 CONFIG_IMX8MM_THERMAL=m
+CONFIG_QORIQ_THERMAL=m
+CONFIG_SUN8I_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=m
 CONFIG_RCAR_THERMAL=y
 CONFIG_RCAR_GEN3_THERMAL=y
@@ -582,8 +572,8 @@ CONFIG_BCM2711_THERMAL=m
 CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
-CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_TEGRA_SOCTHERM=m
+CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_QCOM_TSENS=y
 CONFIG_QCOM_SPMI_TEMP_ALARM=m
 CONFIG_QCOM_LMH=m
@@ -592,7 +582,6 @@ CONFIG_WATCHDOG=y
 CONFIG_SL28CPLD_WATCHDOG=m
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_ARM_SBSA_WATCHDOG=y
-CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=m
@@ -601,6 +590,7 @@ CONFIG_IMX_SC_WDT=m
 CONFIG_QCOM_WDT=m
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
+CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
@@ -653,13 +643,12 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 CONFIG_MEDIA_SDR_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_PLATFORM_SUPPORT=y
 # CONFIG_DVB_NET is not set
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
@@ -676,7 +665,6 @@ CONFIG_VIDEO_RCAR_DRIF=m
 CONFIG_VIDEO_IMX219=m
 CONFIG_VIDEO_OV5640=m
 CONFIG_VIDEO_OV5645=m
-CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_MALI_DISPLAY=m
@@ -703,24 +691,24 @@ CONFIG_DRM_SUN8I_DW_HDMI=m
 CONFIG_DRM_SUN8I_MIXER=m
 CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
+CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
-CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
 CONFIG_DRM_DISPLAY_CONNECTOR=m
 CONFIG_DRM_LONTIUM_LT8912B=m
-CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_LONTIUM_LT9611=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_PARADE_PS8640=m
 CONFIG_DRM_SII902X=m
 CONFIG_DRM_SIMPLE_BRIDGE=m
 CONFIG_DRM_THINE_THC63LVD1024=m
 CONFIG_DRM_TI_SN65DSI86=m
-CONFIG_DRM_LONTIUM_LT9611UXC=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@@ -751,15 +739,14 @@ CONFIG_SND_HDA_TEGRA=m
 CONFIG_SND_HDA_CODEC_HDMI=m
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
-CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_FSL_ASRC=m
 CONFIG_SND_SOC_FSL_MICFIL=m
 CONFIG_SND_SOC_FSL_EASRC=m
 CONFIG_SND_IMX_SOC=m
 CONFIG_SND_SOC_IMX_SGTL5000=m
 CONFIG_SND_SOC_IMX_SPDIF=m
-CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_SOC_FSL_ASOC_CARD=m
+CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_MESON_AXG_SOUND_CARD=m
 CONFIG_SND_MESON_GX_SOUND_CARD=m
 CONFIG_SND_SOC_QCOM=m
@@ -813,11 +800,9 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_HID_MULTITOUCH=m
 CONFIG_I2C_HID_ACPI=m
 CONFIG_I2C_HID_OF=m
-CONFIG_USB_CONN_GPIO=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=m
 CONFIG_USB_XHCI_PCI_RENESAS=m
 CONFIG_USB_XHCI_TEGRA=y
 CONFIG_USB_EHCI_HCD=y
@@ -864,8 +849,8 @@ CONFIG_TYPEC=m
 CONFIG_TYPEC_TCPM=m
 CONFIG_TYPEC_TCPCI=m
 CONFIG_TYPEC_FUSB302=m
-CONFIG_TYPEC_HD3SS3220=m
 CONFIG_TYPEC_TPS6598X=m
+CONFIG_TYPEC_HD3SS3220=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_ARMMMCI=y
@@ -963,7 +948,6 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
-CONFIG_MFD_CROS_EC_DEV=y
 CONFIG_STAGING=y
 CONFIG_STAGING_MEDIA=y
 CONFIG_VIDEO_HANTRO=m
@@ -973,15 +957,14 @@ CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_CHARDEV=m
-CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_SCPI=y
 CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_FSL_SAI=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_COMMON_CLK_PWM=y
 CONFIG_COMMON_CLK_VC5=y
-CONFIG_COMMON_CLK_ZYNQMP=y
 CONFIG_COMMON_CLK_BD718XX=m
 CONFIG_CLK_RASPBERRYPI=m
 CONFIG_CLK_IMX8MM=y
@@ -997,8 +980,8 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y
 CONFIG_QCOM_CLK_APCC_MSM8996=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
-CONFIG_IPQ_GCC_8074=y
 CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
 CONFIG_MSM_GCC_8916=y
 CONFIG_MSM_GCC_8994=y
 CONFIG_MSM_MMCC_8996=y
@@ -1007,16 +990,13 @@ CONFIG_QCS_GCC_404=y
 CONFIG_SC_GCC_7180=y
 CONFIG_SC_GCC_7280=y
 CONFIG_SDM_CAMCC_845=m
-CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_VIDEOCC_845=y
 CONFIG_SDM_DISPCC_845=y
-CONFIG_SM_GCC_8150=y
-CONFIG_SM_GCC_8250=y
+CONFIG_SM_DISPCC_8250=y
 CONFIG_SM_GCC_8350=y
 CONFIG_SM_GPUCC_8150=y
 CONFIG_SM_GPUCC_8250=y
-CONFIG_SM_DISPCC_8250=y
 CONFIG_QCOM_HFPLL=y
 CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
@@ -1050,9 +1030,11 @@ CONFIG_RASPBERRYPI_POWER=y
 CONFIG_FSL_DPAA=y
 CONFIG_FSL_MC_DPIO=y
 CONFIG_FSL_RCPM=y
+CONFIG_MTK_DEVAPC=m
 CONFIG_MTK_PMIC_WRAP=y
 CONFIG_QCOM_AOSS_QMP=y
 CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_RMTFS_MEM=m
 CONFIG_QCOM_RPMH=y
@@ -1063,24 +1045,25 @@ CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
 CONFIG_QCOM_SMSM=y
 CONFIG_QCOM_SOCINFO=m
-CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_APR=m
-CONFIG_ARCH_R8A774A1=y
-CONFIG_ARCH_R8A774B1=y
-CONFIG_ARCH_R8A774C0=y
-CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77990=y
 CONFIG_ARCH_R8A77950=y
 CONFIG_ARCH_R8A77951=y
+CONFIG_ARCH_R8A77965=y
 CONFIG_ARCH_R8A77960=y
 CONFIG_ARCH_R8A77961=y
-CONFIG_ARCH_R8A77965=y
-CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A77980=y
-CONFIG_ARCH_R8A77990=y
-CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A779A0=y
+CONFIG_ARCH_R8A774C0=y
+CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774B1=y
 CONFIG_ARCH_R9A07G044=y
+CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1159,13 +1142,13 @@ CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_ARM_SMMU_V3_PMU=m
 CONFIG_FSL_IMX8_DDR_PMU=m
-CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
+CONFIG_HISI_PMU=y
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_IMX_OCOTP_SCU=y
-CONFIG_QCOM_QFPROM=y
 CONFIG_MTK_EFUSE=y
+CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_UNIPHIER_EFUSE=y
@@ -1179,11 +1162,9 @@ CONFIG_FPGA_REGION=m
 CONFIG_OF_FPGA_REGION=m
 CONFIG_TEE=y
 CONFIG_OPTEE=y
-CONFIG_SLIMBUS=m
+CONFIG_MUX_MMIO=y
 CONFIG_SLIM_QCOM_CTRL=m
 CONFIG_SLIM_QCOM_NGD_CTRL=m
-CONFIG_MUX_MMIO=y
-CONFIG_INTERCONNECT=y
 CONFIG_INTERCONNECT_IMX=m
 CONFIG_INTERCONNECT_IMX8MM=m
 CONFIG_INTERCONNECT_IMX8MN=m
@@ -1211,7 +1192,6 @@ CONFIG_OVERLAY_FS=m
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS_POSIX_ACL=y
 CONFIG_HUGETLBFS=y
-CONFIG_CONFIGFS_FS=y
 CONFIG_EFIVAR_FS=y
 CONFIG_SQUASHFS=y
 CONFIG_NFS_FS=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:04 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:04 +0100
Subject: [PATCH v2 08/11] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-9-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Realtek Gigabit Ethernet driver as a module.

Network cards based on chipsets this driver supports are ubiquitous both
in regular PCIe as well as mini-PCIe and nowadays even various M.2
formats. It is therefore a suitable card to be used for any kind of PCIe
and/or Gigabit Ethernet testing. As it is not designed in, just enabling
it as a module seems most suitable.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Explain why enabling it may be a good idea as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 3d200a149a88..f80d7fb53b7e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -338,6 +338,7 @@ CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
 CONFIG_QCOM_EMAC=m
 CONFIG_RMNET=m
+CONFIG_R8169=m
 CONFIG_SH_ETH=y
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:03 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:03 +0100
Subject: [PATCH v2 07/11] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-8-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids firmware load error and sysfs fallback reported as follows:

[    0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
 for imx/sdma/sdma-imx7d.bin failed with error -2
[    0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
 fallback for: imx/sdma/sdma-imx7d.bin

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- A similar change got accepted for imx_v6_v7_defconfig. Further
discussion may be found in [1].
[1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/

 arch/arm64/configs/defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 872b38613c6c..3d200a149a88 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -927,7 +927,7 @@ CONFIG_DMADEVICES=y
 CONFIG_DMA_BCM2835=y
 CONFIG_DMA_SUN6I=m
 CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:02 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:02 +0100
Subject: [PATCH v2 06/11] arm64: defconfig: enable bpf/cgroup firewalling
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-7-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids the following systemd warning:

[    2.618538] systemd[1]: system-getty.slice: unit configures an IP
 firewall, but the local system does not support BPF/cgroup firewalling.
[    2.630916] systemd[1]: (This warning is only shown for the first
 unit using IP firewalling.)

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Song Liu <songliubraving at fb.com>

---

Changes in v2:
- Add Song's acked-by tag.

 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index bc39559c1658..872b38613c6c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_BPF_JIT=y
 CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
@@ -22,6 +23,7 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:05 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:05 +0100
Subject: [PATCH v2 09/11] arm64: defconfig: enable verdin-imx8mm relevant
 drivers as modules
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-10-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable various drivers which support peripherals as found on the
Verdin iMX8M Mini et al. computer/system on modules:

- CONFIG_CAN_MCP251XFD
At least one Microchip MCP2518FDT SPI CAN controller which this driver
also supports may be found on the Verdin iMX8M Mini computer/system on
module.

- CONFIG_BT_HCIUART_MRVL, CONFIG_BT_MRVL, CONFIG_BT_MRVL_SDIO and
  CONFIG_MWIFIEX_SDIO
The AzureWave AW-CM276NF which these Bluetooth and Wi-Fi drivers also
support may be found on the Verdin iMX8M Mini (as well as the Apalis
iMX8, Colibri iMX8X and Verdin iMX8M Plus for that matter) computer/
system on module.

- CONFIG_SENSORS_LM75
The TI TMP75C temperature sensor which this driver also supports may be
found on the Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for
that matter) computer/system on module.

- CONFIG_SND_SOC_NAU8822
The Nuvoton Technology Corporation (NTC) NAU88C22YG which this driver
also supports may be found on the Verdin Development Board a carrier
board for the Verdin family of computer/system on module which the
Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
may be mated in.

- CONFIG_TI_ADS1015
The TLA2024 ADC which this driver also supports may be found on the
Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
computer/system on module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Explain why enabling these may make sense and squash them relevant
  changes as requested by Krzysztof.

 arch/arm64/configs/defconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f80d7fb53b7e..6f4507b30916 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -178,6 +178,7 @@ CONFIG_CAN=m
 CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
+CONFIG_CAN_MCP251XFD=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
 # CONFIG_BT_LE is not set
@@ -188,6 +189,9 @@ CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_LL=y
 CONFIG_BT_HCIUART_BCM=y
 CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
 CONFIG_BT_QCOMSMD=m
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
@@ -379,6 +383,7 @@ CONFIG_ATH10K_SNOC=m
 CONFIG_WCN36XX=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
 CONFIG_MWIFIEX_PCIE=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
@@ -554,6 +559,7 @@ CONFIG_CHARGER_BQ25980=m
 CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
+CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_PWM_FAN=m
 CONFIG_SENSORS_RASPBERRYPI_HWMON=m
@@ -796,6 +802,7 @@ CONFIG_SND_SOC_WM8960=m
 CONFIG_SND_SOC_WM8962=m
 CONFIG_SND_SOC_WM8978=m
 CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_NAU8822=m
 CONFIG_SND_SOC_LPASS_WSA_MACRO=m
 CONFIG_SND_SOC_LPASS_VA_MACRO=m
 CONFIG_SND_SIMPLE_CARD=m
@@ -1087,6 +1094,7 @@ CONFIG_QCOM_SPMI_VADC=m
 CONFIG_QCOM_SPMI_ADC5=m
 CONFIG_ROCKCHIP_SARADC=m
 CONFIG_RZG2L_ADC=m
+CONFIG_TI_ADS1015=m
 CONFIG_IIO_CROS_EC_SENSORS_CORE=m
 CONFIG_IIO_CROS_EC_SENSORS=m
 CONFIG_IIO_ST_LSM6DSX=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:07 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:07 +0100
Subject: [PATCH v2 11/11] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-12-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This patch adds the device tree to support Toradex Verdin iMX8M Mini a
computer on module which can be used on different carrier boards.

The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
Wi-Fi module.

Anything that is not self-contained on the module is disabled by
default.

The device tree for the Dahlia includes the module's device tree and
enables the supported peripherals of the carrier board.

The device tree for the Verdin Development Board includes the module's
device tree as well as the Dahlia one as it is a superset and supports
almost all peripherals available.

So far there is no display functionality supported at all but basic
console UART, USB host, eMMC and Ethernet and PCIe functionality work
fine.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v2:
- Remove bootargs which will be filled in by the bootloader as requested
  by Krzysztof.
- Remove the previously #ifdefed-out spi-nor as requested by Krzysztof.
- Fix capitalisation in cover-letter.

 arch/arm64/boot/dts/freescale/Makefile        |    4 +
 .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  143 ++
 .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
 .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
 .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
 .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
 .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
 .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1267 +++++++++++++++++
 10 files changed, 1723 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 6d8f0a532587..04380f2e44a2 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -63,6 +63,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2pro.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
new file mode 100644
index 000000000000..b5bf025c74a2
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-wm8904";
+		simple-audio-card,routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"IN2L", "Line In Jack",
+			"IN2R", "Line In Jack",
+			"Headphone Jack", "MICBIAS",
+			"IN1L", "Headphone Jack";
+		simple-audio-card,widgets =
+			"Microphone", "Headphone Jack",
+			"Headphone", "Headphone Jack",
+			"Line", "Line In Jack";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&wm8904_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+	status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+	status = "okay";
+};
+
+&fec1 {
+	status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+	status = "okay";
+};
+
+&hwmon_temp {
+	vs-supply = <&reg_1p8v>;
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	status = "okay";
+
+	/* Audio Codec */
+	wm8904_1a: codec at 1a {
+		compatible = "wlf,wm8904";
+		AVDD-supply = <&reg_3p3v>;
+		clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+		clock-names = "mclk";
+		CPVDD-supply = <&reg_3p3v>;
+		DBVDD-supply = <&reg_3p3v>;
+		DCVDD-supply = <&reg_3p3v>;
+		MICVDD-supply = <&reg_3p3v>;
+		reg = <0x1a>;
+		#sound-dai-cells = <0>;
+	};
+};
+
+/* Verdin PCIE_1 */
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	status = "okay";
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+	status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
new file mode 100644
index 000000000000..f35d22dc546b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-nau8822";
+		simple-audio-card,routing =
+			"Headphones", "LHP",
+			"Headphones", "RHP",
+			"Speaker", "LSPK",
+			"Speaker", "RSPK",
+			"Line Out", "AUXOUT1",
+			"Line Out", "AUXOUT2",
+			"LAUX", "Line In",
+			"RAUX", "Line In",
+			"LMICP", "Mic In",
+			"RMICP", "Mic In";
+		simple-audio-card,widgets =
+			"Headphones", "Headphones",
+			"Line Out", "Line Out",
+			"Speaker", "Speaker",
+			"Microphone", "Mic In",
+			"Line", "Line In";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&nau8822_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+&gpio_expander_21 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	/* Audio Codec */
+	nau8822_1a: codec at 1a {
+		compatible = "nuvoton,nau8822";
+		reg = <0x1a>;
+	};
+};
+
+/* Verdin UART_1, connector X50 through RS485 transceiver */
+&uart2 {
+	linux,rs485-enabled-at-boot-time;
+	rs485-rts-active-low;
+	rs485-rx-during-tx;
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+	max-frequency = <100000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
new file mode 100644
index 000000000000..d64ff378a152
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dahlia",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
new file mode 100644
index 000000000000..6ae71ecac8de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dev",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
new file mode 100644
index 000000000000..9aff9dde1a02
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "SODIMM_162",
+			  "SODIMM_164",
+			  "SODIMM_166",
+			  "SODIMM_168",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "SODIMM_156",
+			  "SODIMM_160",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "SODIMM_148",
+			  "SODIMM_152",
+			  "SODIMM_154",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "SODIMM_150",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
+
+&usdhc3 {
+	bus-width = <4>;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
new file mode 100644
index 000000000000..d424c475cba1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dahlia",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
new file mode 100644
index 000000000000..ef952021832e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dev",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
new file mode 100644
index 000000000000..c400770c1df5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	reg_wifi_en: regulator-wifi-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "PDn_AW-CM276NF";
+		startup-delay-us = <2000>;
+	};
+};
+
+/* On-module Wi-Fi */
+&usdhc3 {
+	bus-width = <4>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_wifi_ctrl>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_wifi_ctrl>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_wifi_ctrl>;
+	vmmc-supply = <&reg_wifi_en>;
+	wifi-host;
+	status = "okay";
+};
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
new file mode 100644
index 000000000000..2fa9dc3dd92b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -0,0 +1,1267 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mm.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	aliases {
+		rtc0 = &rtc_i2c;
+		rtc1 = &snvs_rtc;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 45 63 88 119 158 203 255>;
+		default-brightness-level = <4>;
+		/* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+		enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+		power-supply = <&reg_3p3v>;
+		/* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+		pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+		status = "disabled";
+	};
+
+	/* Fixed clock dedicated to SPI CAN controller */
+	clk20m: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <20000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		wakeup {
+			debounce-interval = <10>;
+			/* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+			gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+			label = "Wake-Up";
+			linux,code = <KEY_WAKEUP>;
+			wakeup-source;
+		};
+	};
+
+	/* Carrier Board Supplies */
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-name = "+V1.8_SW";
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SW";
+	};
+
+	reg_5p0v: regulator-5p0v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "+V5_SW";
+	};
+
+	/* Non PMIC On-module Supplies */
+	reg_ethphy: regulator-ethphy {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+		off-on-delay = <500000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_eth>;
+		regulator-boot-on;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_ETH";
+		startup-delay-us = <200000>;
+	};
+
+	reg_usb_otg1_vbus: regulator-usb-otg1 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_1_EN (SODIMM 155) */
+		gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb1_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg1_vbus";
+	};
+
+	reg_usb_otg2_vbus: regulator-usb-otg2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_2_EN (SODIMM 185) */
+		gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb2_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg2_vbus";
+	};
+
+	reg_usdhc2_vmmc: regulator-usdhc2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin SD_1_PWR_EN (SODIMM 76) */
+		gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+		off-on-delay = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SD";
+		startup-delay-us = <2000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* Use the kernel configuration settings instead */
+		/delete-node/ linux,cma;
+
+		rpmsg_reserved: rpmsg at b8000000 {
+			no-map;
+			reg = <0 0xb8000000 0 0x400000>;
+		};
+	};
+};
+
+&A53_0 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_1 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_2 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_3 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&ddrc {
+	operating-points-v2 = <&ddrc_opp_table>;
+
+	ddrc_opp_table: opp-table {
+		compatible = "operating-points-v2";
+
+		opp-25M {
+			opp-hz = /bits/ 64 <25000000>;
+		};
+
+		opp-100M {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+
+		opp-750M {
+			opp-hz = /bits/ 64 <750000000>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+};
+
+/* Verdin CAN_1 and CAN_2 (On-module) */
+&ecspi3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>,
+		   <&gpio1 5 GPIO_ACTIVE_LOW>;
+	spi-num-chipselects = <2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi3>;
+	status = "okay";
+
+	can1: can at 0 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 6 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can1_int>;
+		reg = <0>;
+		spi-max-frequency = <8500000>;
+	};
+
+	can2: can at 1 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 7 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can2_int>;
+		reg = <1>;
+		spi-max-frequency = <8500000>;
+		/* Not assembled on regular SKUs */
+		status = "disabled";
+	};
+};
+
+/* Verdin ETH_1 (On-module PHY) */
+&fec1 {
+	fsl,magic-packet;
+	phy-handle = <&ethphy0>;
+	phy-mode = "rgmii-id";
+	phy-supply = <&reg_ethphy>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_fec1>;
+	pinctrl-1 = <&pinctrl_fec1_sleep>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy at 7 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+			micrel,led-mode = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexspi0>;
+};
+
+&gpio1 {
+	gpio-line-names = "SODIMM_216",
+			  "SODIMM_19",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_220",
+			  "SODIMM_222",
+			  "",
+			  "SODIMM_218",
+			  "SODIMM_155",
+			  "SODIMM_157",
+			  "SODIMM_185",
+			  "SODIMM_187";
+};
+
+&gpio2 {
+	gpio-line-names = "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_84",
+			  "SODIMM_78",
+			  "SODIMM_74",
+			  "SODIMM_80",
+			  "SODIMM_82",
+			  "SODIMM_70",
+			  "SODIMM_72";
+};
+
+&gpio5 {
+	gpio-line-names = "SODIMM_131",
+			  "",
+			  "SODIMM_91",
+			  "SODIMM_16",
+			  "SODIMM_15",
+			  "SODIMM_208",
+			  "SODIMM_137",
+			  "SODIMM_139",
+			  "SODIMM_141",
+			  "SODIMM_143",
+			  "SODIMM_196",
+			  "SODIMM_200",
+			  "SODIMM_198",
+			  "SODIMM_202",
+			  "",
+			  "",
+			  "SODIMM_55",
+			  "SODIMM_53",
+			  "SODIMM_95",
+			  "SODIMM_93",
+			  "SODIMM_14",
+			  "SODIMM_12",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_210",
+			  "SODIMM_212",
+			  "SODIMM_151",
+			  "SODIMM_153";
+
+	ctrl_sleep_moci-hog {
+		gpio-hog;
+		/* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+		gpios = <1 GPIO_ACTIVE_HIGH>;
+		line-name = "CTRL_SLEEP_MOCI#";
+		output-high;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+	};
+};
+
+/* On-module I2C */
+&i2c1 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+
+	pca9450: pmic at 25 {
+		compatible = "nxp,pca9450a";
+		interrupt-parent = <&gpio1>;
+		/* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pmic>;
+		reg = <0x25>;
+		sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			reg_vdd_soc: BUCK1 {
+				nxp,dvs-run-voltage = <850000>;
+				nxp,dvs-standby-voltage = <800000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <850000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+VDD_SOC";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_arm: BUCK2 {
+				nxp,dvs-run-voltage = <950000>;
+				nxp,dvs-standby-voltage = <850000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_ARM";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_dram: BUCK3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_GPU_VPU_DDR";
+			};
+
+			reg_vdd_3v3: BUCK4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <3300000>;
+				regulator-name = "+V3.3";
+			};
+
+			reg_vdd_1v8: BUCK5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "PWR_1V8_MOCI";
+			};
+
+			reg_nvcc_dram: BUCK6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1100000>;
+				regulator-min-microvolt = <1100000>;
+				regulator-name = "+VDD_DDR";
+			};
+
+			reg_nvcc_snvs: LDO1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8_SNVS";
+			};
+
+			reg_vdd_snvs: LDO2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+V0.8_SNVS";
+			};
+
+			reg_vdda: LDO3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8A";
+			};
+
+			reg_vdd_phy: LDO4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <900000>;
+				regulator-name = "+V0.9_MIPI";
+			};
+
+			reg_nvcc_sd: LDO5 {
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V3.3_1.8_SD";
+			};
+		};
+	};
+
+	rtc_i2c: rtc at 32 {
+		compatible = "epson,rx8130";
+		reg = <0x32>;
+	};
+
+	adc at 49 {
+		compatible = "ti,ads1015";
+		reg = <0x49>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Verdin I2C_1 (ADC_4 - ADC_3) */
+		channel at 0 {
+			reg = <0>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_4 - ADC_1) */
+		channel at 1 {
+			reg = <1>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_3 - ADC_1) */
+		channel at 2 {
+			reg = <2>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_2 - ADC_1) */
+		channel at 3 {
+			reg = <3>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_4 */
+		channel at 4 {
+			reg = <4>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_3 */
+		channel at 5 {
+			reg = <5>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_2 */
+		channel at 6 {
+			reg = <6>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_1 */
+		channel at 7 {
+			reg = <7>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+	};
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+	clock-frequency = <10000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "disabled";
+};
+
+/* Verdin I2C_3_HDMI N/A */
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	pinctrl-1 = <&pinctrl_i2c4_gpio>;
+	scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+	gpio_expander_21: gpio-expander at 21 {
+		compatible = "nxp,pcal6416";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x21>;
+		status = "disabled";
+		vcc-supply = <&reg_3p3v>;
+	};
+
+	lvds_ti_sn65dsi83: bridge at 2c {
+		compatible = "ti,sn65dsi83";
+		/* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		enable-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+		reg = <0x2c>;
+		status = "disabled";
+	};
+
+	/* Current measurement into module VCC */
+	hwmon: hwmon at 40 {
+		compatible = "ti,ina219";
+		reg = <0x40>;
+		shunt-resistor = <10000>;
+		status = "disabled";
+	};
+
+	hdmi_lontium_lt8912: hdmi at 48 {
+		compatible = "lontium,lt8912b";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+		reg = <0x48>;
+		/* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+		status = "disabled";
+	};
+
+	atmel_mxt_ts: touch at 4a {
+		compatible = "atmel,maxtouch";
+		/* Verdin GPIO_9_DSI */
+		/* (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused) */
+		interrupt-parent = <&gpio3>;
+		interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+		reg = <0x4a>;
+		/* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
+
+	/* Temperature sensor on carrier board */
+	hwmon_temp: sensor at 4f {
+		compatible = "ti,tmp75c";
+		reg = <0x4f>;
+		status = "disabled";
+	};
+
+	/* EEPROM on display adapter (MIPI DSI Display Adapter) */
+	eeprom_display_adapter: eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+		status = "disabled";
+	};
+
+	/* EEPROM on carrier board */
+	eeprom_carrier_board: eeprom at 57 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x57>;
+		status = "disabled";
+	};
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_1>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_2>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_3>;
+	#pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	#sound-dai-cells = <0>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <24576000>;
+	assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+};
+
+&snvs_pwrkey {
+	status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux console */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_4 */
+/*
+ * Resource allocated to M4 by default, must not be accessed from Cortex-A35 or you get an OOPS
+ */
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&usbmisc1 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+&usbmisc2 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	adp-disable;
+	dr_mode = "otg";
+	hnp-disable;
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	srp-disable;
+	vbus-supply = <&reg_usb_otg1_vbus>;
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	dr_mode = "host";
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	vbus-supply = <&reg_usb_otg2_vbus>;
+};
+
+&usbphynop1 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+&usbphynop2 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+	bus-width = <8>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	pm-ignore-notify;
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	bus-width = <4>;
+	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+&wdog1 {
+	fsl,ext-reset-output;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+		    <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+		    <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+		    <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+		    <&pinctrl_pmic_tpm_ena>;
+
+	pinctrl_can1_int: can1intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6		0x1c4>;	/* CAN_1_SPI_INT#_1.8V */
+	};
+
+	pinctrl_can2_int: can2intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7		0x1c4>;	/* CAN_2_SPI_INT#_1.8V */
+	};
+
+	pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1		0x1c4>;	/* SODIMM 256 */
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK		0x4>,	/* SODIMM 196 */
+			<MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI		0x4>,	/* SODIMM 200 */
+			<MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO		0x1c4>,	/* SODIMM 198 */
+			<MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13		0x1c4>;	/* SODIMM 202 */
+	};
+
+	pinctrl_ecspi3: ecspi3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK		0x4>,	/* CAN_SPI_SCK_1.8V */
+			<MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI		0x4>,	/* CAN_SPI_MOSI_1.8V */
+			<MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO		0x1c4>,	/* CAN_SPI_MISO_1.8V */
+			<MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25		0x1c4>,	/* CAN_1_SPI_CS_1.8V# */
+			<MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5		0x1c4>;	/* CAN_2_SPI_CS#_1.8V */
+	};
+
+	pinctrl_fec1: fec1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x1c4>;
+	};
+
+	pinctrl_fec1_sleep: fec1-sleepgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_GPIO1_IO23		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22		0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x184>;
+	};
+
+	pinctrl_flexspi0: flexspi0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK		0x1c2>,	/* SODIMM 52 */
+			<MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B		0x82>,	/* SODIMM 54 */
+			<MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B		0x82>,	/* SODIMM 64 */
+			<MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS		0x82>,	/* SODIMM 66 */
+			<MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0		0x82>,	/* SODIMM 56 */
+			<MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1		0x82>,	/* SODIMM 58 */
+			<MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2		0x82>,	/* SODIMM 60 */
+			<MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3		0x82>;	/* SODIMM 62 */
+	};
+
+	pinctrl_gpio1: gpio1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4		0x184>;	/* SODIMM 206 */
+	};
+
+	pinctrl_gpio2: gpio2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5		0x1c4>;	/* SODIMM 208 */
+	};
+
+	pinctrl_gpio3: gpio3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26		0x184>;	/* SODIMM 210 */
+	};
+
+	pinctrl_gpio4: gpio4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27		0x184>;	/* SODIMM 212 */
+	};
+
+	pinctrl_gpio5: gpio5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0		0x184>;	/* SODIMM 216 */
+	};
+
+	pinctrl_gpio6: gpio6grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11		0x184>;	/* SODIMM 218 */
+	};
+
+	pinctrl_gpio7: gpio7grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x184>;	/* SODIMM 220 */
+	};
+
+	pinctrl_gpio8: gpio8grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x184>;	/* SODIMM 222 */
+	};
+
+	/* Verdin GPIO_9_DSI (pulled-up as active-low) */
+	pinctrl_gpio_9_dsi: gpio9dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15		0x1c4>;	/* SODIMM 17 */
+	};
+
+	/* Verdin GPIO_10_DSI */
+	pinctrl_gpio_10_dsi: gpio10dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3		0x1c4>;	/* SODIMM 21 */
+	};
+
+	pinctrl_gpio_hog1: gpiohog1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20		0x1c4>,	/* SODIMM 88 */
+			<MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1		0x1c4>,	/* SODIMM 90 */
+			<MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2		0x1c4>,	/* SODIMM 92 */
+			<MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3		0x1c4>,	/* SODIMM 94 */
+			<MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4		0x1c4>,	/* SODIMM 96 */
+			<MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5		0x1c4>,	/* SODIMM 100 */
+			<MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0		0x1c4>,	/* SODIMM 102 */
+			<MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11		0x1c4>,	/* SODIMM 104 */
+			<MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12		0x1c4>,	/* SODIMM 106 */
+			<MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13		0x1c4>,	/* SODIMM 108 */
+			<MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14		0x1c4>,	/* SODIMM 112 */
+			<MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15		0x1c4>,	/* SODIMM 114 */
+			<MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16		0x1c4>,	/* SODIMM 116 */
+			<MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18		0x1c4>,	/* SODIMM 118 */
+			<MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10		0x1c4>;	/* SODIMM 120 */
+	};
+
+	pinctrl_gpio_hog2: gpiohog2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2		0x1c4>;	/* SODIMM 91 */
+	};
+
+	pinctrl_gpio_hog3: gpiohog3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13		0x1c4>,	/* SODIMM 157 */
+			<MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15		0x1c4>;	/* SODIMM 187 */
+	};
+
+	pinctrl_gpio_keys: gpiokeysgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28		0x1c4>;	/* SODIMM 252 */
+	};
+
+	/* On-module I2C */
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	pinctrl_i2c1_gpio: i2c1gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14		0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15		0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	/* Verdin I2C_4_CSI */
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL			0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA			0x400001c6>;	/* SODIMM 53 */
+	};
+
+	pinctrl_i2c2_gpio: i2c2gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16		0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17		0x400001c6>;	/* SODIMM 53 */
+	};
+
+	/* Verdin I2C_2_DSI */
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL			0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400001c6>;	/* SODIMM 93 */
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18		0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19		0x400001c6>;	/* SODIMM 93 */
+	};
+
+	/* Verdin I2C_1 */
+	pinctrl_i2c4: i2c4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c6>;	/* SODIMM 12 */
+	};
+
+	pinctrl_i2c4_gpio: i2c4gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20		0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21		0x400001c6>;	/* SODIMM 12 */
+	};
+
+	/* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+	pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23		0x184>;	/* SODIMM 42 */
+	};
+
+	/* Verdin I2S_2_D_OUT shared with SAI5 */
+	pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24		0x184>;	/* SODIMM 46 */
+	};
+
+	pinctrl_pcie0: pcie0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19		0x6>,	/* SODIMM 244 */
+			/* PMIC_EN_PCIe_CLK, unused */
+			<MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19		0x6>;
+	};
+
+	pinctrl_pmic: pmicirqgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x41>;	/* PMIC_INT# */
+	};
+
+	/* Verdin PWM_3_DSI shared with GPIO1_IO1 */
+	pinctrl_pwm_1: pwm1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT		0x6>;	/* SODIMM 19 */
+	};
+
+	pinctrl_pwm_2: pwm2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT			0x6>;	/* SODIMM 15 */
+	};
+
+	pinctrl_pwm_3: pwm3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT			0x6>;	/* SODIMM 16 */
+	};
+
+	/* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM1_OUT */
+	pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsihpdgpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1		0x184>;	/* SODIMM 19 */
+	};
+
+	pinctrl_reg_eth: regethgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_WP_GPIO2_IO20			0x184>;	/* PMIC_EN_ETH */
+	};
+
+	pinctrl_reg_usb1_en: regusb1engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12		0x184>;	/* SODIMM 155 */
+	};
+
+	pinctrl_reg_usb2_en: regusb2engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14		0x184>;	/* SODIMM 185 */
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC		0xd6>,	/* SODIMM 32 */
+			<MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK		0xd6>,	/* SODIMM 30 */
+			<MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK		0xd6>,	/* SODIMM 38 */
+			<MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0		0xd6>,	/* SODIMM 36 */
+			<MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0		0xd6>;	/* SODIMM 34 */
+	};
+
+	pinctrl_sai5: sai5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0		0xd6>,	/* SODIMM 48 */
+			<MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC		0xd6>,	/* SODIMM 44 */
+			<MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK		0xd6>,	/* SODIMM 42 */
+			<MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0		0xd6>;	/* SODIMM 46 */
+	};
+
+	/* control signal for optional ATTPM20P or SE050 */
+	pinctrl_pmic_tpm_ena: pmictpmenagrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19		0x1c4>;	/* PMIC_TPM_ENA */
+	};
+
+	pinctrl_tsp: tspgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6		0x140>,	/* SODIMM 148 */
+			<MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7		0x140>,	/* SODIMM 152 */
+			<MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8		0x140>,	/* SODIMM 154 */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x140>,	/* SODIMM 179 */
+			<MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17		0x140>;	/* SODIMM 150 */
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x1c4>,	/* SODIMM 149 */
+			<MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x1c4>;	/* SODIMM 147 */
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x1c4>,	/* SODIMM 129 */
+			<MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x1c4>,	/* SODIMM 131 */
+			<MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x1c4>,	/* SODIMM 133 */
+			<MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x1c4>;	/* SODIMM 135 */
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX		0x1c4>,	/* SODIMM 137 */
+			<MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX		0x1c4>,	/* SODIMM 139 */
+			<MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B	0x1c4>,	/* SODIMM 141 */
+			<MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B	0x1c4>;	/* SODIMM 143 */
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX		0x1c4>,	/* SODIMM 151 */
+			<MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX		0x1c4>;	/* SODIMM 153 */
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x190>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d0>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x190>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x194>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d4>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x194>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x196>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d6>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x196>;
+	};
+
+	pinctrl_usdhc2_cd: usdhc2cdgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x1c4>;	/* SODIMM 84 */
+	};
+
+	pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5		0x184>;	/* SODIMM 76 */
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x190>,	/* SODIMM 78 */
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d0>,	/* SODIMM 74 */
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0>,	/* SODIMM 80 */
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0>,	/* SODIMM 82 */
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0>,	/* SODIMM 70 */
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0>,	/* SODIMM 72 */
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x194>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x196>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	/* On-module Wi-Fi/BT or type specific SDHC interface */
+	/* (e.g. on X52 extension slot of Verdin Development Board) */
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x190>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d0>;
+	};
+
+	pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x194>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d4>;
+	};
+
+	pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x196>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d6>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6>;	/* PMIC_WDI */
+	};
+
+	pinctrl_wifi_ctrl: wifictrlgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16		0x1c4>,	/* WIFI_WKUP_BT */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x1c4>,	/* WIFI_W_WKUP_HOST */
+			<MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20		0x1c4>;	/* WIFI_WKUP_WLAN */
+	};
+
+	pinctrl_wifi_i2s: bti2sgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK		0xd6>,	/* WIFI_TX_BCLK */
+			<MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0		0xd6>,	/* WIFI_TX_DATA0 */
+			<MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC		0xd6>,	/* WIFI_TX_SYNC */
+			<MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0		0xd6>;	/* WIFI_RX_DATA0 */
+	};
+
+	pinctrl_wifi_pwr_en: wifipwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25		0x184>;	/* PMIC_EN_WIFI */
+	};
+};
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 14 06:15:06 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 15:15:06 +0100
Subject: [PATCH v2 10/11] dt-bindings: arm: fsl: add toradex,
 verdin-imx8mm et al.
In-Reply-To: <20220114141507.395271-1-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
Message-ID: <20220114141507.395271-11-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Add toradex,verdin-imx8mm for our new Verdin iMX8M Mini modules, its
nonwifi and wifi variants and the carrier boards (both Dahlia and the
Verdin Development Board) they may be mated in.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Rob Herring <robh at kernel.org>

---

Changes in v2:
- Add Rob's acked-by tag.
- Fix Colibri vs. Verdin copy/paste mistake. Thanks to Francesco Dolcini
  <francesco.dolcini at toradex.com> for pointing that out to me.

 .../devicetree/bindings/arm/fsl.yaml          | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 97f6eebad76a..7b7b6d3aa16f 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -770,6 +770,9 @@ properties:
               - gw,imx8mm-gw7901          # i.MX8MM Gateworks Board
               - gw,imx8mm-gw7902          # i.MX8MM Gateworks Board
               - kontron,imx8mm-n801x-som  # i.MX8MM Kontron SL (N801X) SOM
+              - toradex,verdin-imx8mm     # Verdin iMX8M Mini Modules
+              - toradex,verdin-imx8mm-nonwifi  # Verdin iMX8M Mini Modules without Wi-Fi / BT
+              - toradex,verdin-imx8mm-wifi  # Verdin iMX8M Mini Wi-Fi / BT Modules
               - variscite,var-som-mx8mm   # i.MX8MM Variscite VAR-SOM-MX8MM module
           - const: fsl,imx8mm
 
@@ -787,6 +790,24 @@ properties:
           - const: kontron,imx8mm-n801x-som
           - const: fsl,imx8mm
 
+      - description: Toradex Boards with Verdin iMX8M Mini Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-nonwifi-dahlia # Verdin iMX8M Mini Module on Dahlia
+              - toradex,verdin-imx8mm-nonwifi-dev    # Verdin iMX8M Mini Module on Verdin Development Board
+          - const: toradex,verdin-imx8mm-nonwifi     # Verdin iMX8M Mini Module without Wi-Fi / BT
+          - const: toradex,verdin-imx8mm             # Verdin iMX8M Mini Module
+          - const: fsl,imx8mm
+
+      - description: Toradex Boards with Verdin iMX8M Mini Wi-Fi / BT Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-wifi-dahlia # Verdin iMX8M Mini Wi-Fi / BT Module on Dahlia
+              - toradex,verdin-imx8mm-wifi-dev    # Verdin iMX8M Mini Wi-Fi / BT M. on Verdin Development B.
+          - const: toradex,verdin-imx8mm-wifi     # Verdin iMX8M Mini Wi-Fi / BT Module
+          - const: toradex,verdin-imx8mm          # Verdin iMX8M Mini Module
+          - const: fsl,imx8mm
+
       - description: Variscite VAR-SOM-MX8MM based boards
         items:
           - const: variscite,var-som-mx8mm-symphony
-- 
2.33.1



From biju.das.jz at bp.renesas.com  Fri Jan 14 06:23:52 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Fri, 14 Jan 2022 14:23:52 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
Message-ID: <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>



> -----Original Message-----
> From: Neil Armstrong <narmstrong at baylibre.com>
> Sent: 14 January 2022 13:56
> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
> <festevam at gmail.com>
> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi,
> 
> On 14/01/2022 12:08, Biju Das wrote:
> > Hi Neil,
> >
> >> Subject: Re: dw_hdmi is showing wrong colour after commit
> >> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >> callbacks")
> >>
> >> On 14/01/2022 09:29, Biju Das wrote:
> >>> Hi Neil,
> >>>
> >>> + renesas-soc
> >>>
> >>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >>>> callbacks")
> >>>>
> >>>> Hi,
> >>>>
> >>>> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>>>> Hi Biju,
> >>>>>
> >>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>>>> <biju.das.jz at bp.renesas.com>
> >>>> wrote:
> >>>>>>
> >>>>>> Hi All,
> >>>>>>
> >>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
> >>>>>> till the commit
> >>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>> fmts
> >>>> callbacks").
> >>>>>>
> >>>>>> After this patch, the screen becomes greenish(may be it is
> >>>>>> setting it
> >>>> into YUV format??).
> >>>>>>
> >>>>>> By checking the code, previously it used to call get_input_fmt
> >>>>>> callback
> >>>> and set colour as RGB24.
> >>>>>>
> >>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
> >>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
> >>>>>> I see
> >>>> the outputformat as YUV16 instead of RGB24.
> >>>>>>
> >>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
> >>>>
> >>>> This patch was introduced to maintain the bridge color format
> >>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
> >>>> seems it behaves incorrectly if the first bridge doesn't implement
> >>>> the negotiation callbacks.
> >>>>
> >>>> Let me check the code to see how to fix that.
> >>>
> >>> Thanks for the information, I am happy to test the patch/fix.
> >>>
> >>> Cheers,
> >>> Biju
> >>>
> >>>>
> >>>>>
> >>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
> >> shows:
> >>>>>
> >>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
> >>>>> HDCP (DWC HDMI 3D TX PHY)
> >>>>>
> >>>>> The colors are shown correctly here.
> >>>>>
> >>>>
> >>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
> >>>> negotiation fails and use the RGB fallback input & output format.
> >>>>
> >>>> Anyway thanks for testing
> >>>>
> >>>> Neil
> >>
> >> Can you test :
> >>
> >> ==><===============================
> >> diff --git a/drivers/gpu/drm/drm_bridge.c
> >> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
> >> 100644
> >> --- a/drivers/gpu/drm/drm_bridge.c
> >> +++ b/drivers/gpu/drm/drm_bridge.c
> >> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> >> drm_bridge *bridge,
> >>         last_bridge_state =
> >> drm_atomic_get_new_bridge_state(crtc_state-
> >>> state,
> >>
> >> last_bridge);
> >>
> >> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> >> +       /*
> >> +        * Only negociate with real values if both end of the bridge
> chain
> >> +        * support negociation callbacks, otherwise you can end in a
> >> situation
> >> +        * where the selected output format doesn't match with the
> >> + first
> >> bridge
> >> +        * output format.
> >> +        */
> >> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> >> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>                 const struct drm_bridge_funcs *funcs =
> >> last_bridge->funcs;
> >>
> >>                 /*
> >> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
> >> drm_bridge *bridge,
> >>                 if (!out_bus_fmts)
> >>                         return -ENOMEM;
> >>
> >> -               if (conn->display_info.num_bus_formats &&
> >> +               /*
> >> +                * If first bridge doesn't support negociation, use
> >> MEDIA_BUS_FMT_FIXED
> >> +                * as a safe value for the whole bridge chain
> >> +                */
> >> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> >> +                   conn->display_info.num_bus_formats &&
> >>                     conn->display_info.bus_formats)
> >>                         out_bus_fmts[0] = conn-
> >>> display_info.bus_formats[0];
> >>                 else
> >> ==><===============================
> >>
> >> This should exclude your situation where the first bridge doesn't
> >> support negociation.
> >
> > I have tested this fix with Linux next-20220114. Still I see colour
> issue.
> >
> > It is still negotiating and it is calling get_output_fmt_callbck
> >
> > [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16=0#########
> > [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_YUV8_1X24=1#########
> > [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24=2#########
> >
> > And In get_input_fmt callback, I See the outputformat as YUV16 instead
> of RGB24.
> >
> > [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16#########
> > [    3.473644] ########hdmi_video_sample
> MEDIA_BUS_FMT_UYVY8_1X16#########
> 
> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
> encoder.

Yep.

> 
> Let me figure that out, no sure I can find a clean solution except putting
> back RGB24 before YUV.
> 
> Anyway please test that:

It works now after reordering.

[    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
[    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
[    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########

[    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
[    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########

Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
at least it is fixing the colour issue??

Regards,
Biju

> 
> ==><===============================
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..68f79094f648 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2589,45 +2589,44 @@ static u32
> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>  	}
> 
>  	/*
> -	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
> +	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
>  	 * if supported. In any case the default RGB888 format is added
>  	 */
> 
>  	if (max_bpc >= 16 && info->bpc == 16) {
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
> +
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
> -
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>  	}
> 
>  	if (max_bpc >= 12 && info->bpc >= 12) {
> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
> 
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
> 
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>  	}
> 
>  	if (max_bpc >= 10 && info->bpc >= 10) {
> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
> 
>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
> 
> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>  	}
> 
> -	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> -		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
> +	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
> 
>  	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>  		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
> 
> -	/* Default 8bit RGB fallback */
> -	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
> +	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
> +		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
> 
>  	*num_output_fmts = i;
> 
> ==><===============================
> 
> Neil
> 
> >
> > Regards,
> > Biju
> >


From linux at roeck-us.net  Fri Jan 14 06:35:59 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Fri, 14 Jan 2022 06:35:59 -0800
Subject: [PATCH 2/2] watchdog: mtk_wdt: mt7986: Add toprgu reset
 controller support
In-Reply-To: <20220105100456.7126-3-sam.shih@mediatek.com>
References: <20220105100456.7126-1-sam.shih@mediatek.com>
 <20220105100456.7126-3-sam.shih@mediatek.com>
Message-ID: <8e6ed2b7-b4e7-733a-579f-e1536f68ea2f@roeck-us.net>

On 1/5/22 2:04 AM, Sam Shih wrote:
> Besides watchdog, the mt7986 toprgu module also provides software reset
> functionality for various peripheral subsystems
> (eg, ethernet, pcie, and connectivity)
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
>   drivers/watchdog/mtk_wdt.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
> index 543cf38bd04e..c6437fe1f4c0 100644
> --- a/drivers/watchdog/mtk_wdt.c
> +++ b/drivers/watchdog/mtk_wdt.c
> @@ -10,6 +10,7 @@
>    */
>   
>   #include <dt-bindings/reset/mt2712-resets.h>
> +#include <dt-bindings/reset/mt7986-resets.h>
>   #include <dt-bindings/reset/mt8183-resets.h>
>   #include <dt-bindings/reset/mt8192-resets.h>
>   #include <dt-bindings/reset/mt8195-resets.h>
> @@ -76,6 +77,10 @@ static const struct mtk_wdt_data mt2712_data = {
>   	.toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
>   };
>   
> +static const struct mtk_wdt_data mt7986_data = {
> +	.toprgu_sw_rst_num = MT7986_TOPRGU_SW_RST_NUM,
> +};
> +
>   static const struct mtk_wdt_data mt8183_data = {
>   	.toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
>   };
> @@ -418,6 +423,7 @@ static int mtk_wdt_resume(struct device *dev)
>   static const struct of_device_id mtk_wdt_dt_ids[] = {
>   	{ .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
>   	{ .compatible = "mediatek,mt6589-wdt" },
> +	{ .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data },
>   	{ .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
>   	{ .compatible = "mediatek,mt8192-wdt", .data = &mt8192_data },
>   	{ .compatible = "mediatek,mt8195-wdt", .data = &mt8195_data },
> 



From lkp at intel.com  Fri Jan 14 06:38:58 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 14 Jan 2022 22:38:58 +0800
Subject: [xilinx-xlnx:master 248/326] include/linux/mtd/cfi.h:62:2: warning:
 No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
Message-ID: <202201142208.iEdIk0Sc-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 9b62852ec04b7d48971ce8016b13c27403929908 [248/326] Merge tag 'v5.15' into master
config: i386-randconfig-a013 (https://download.01.org/0day-ci/archive/20220114/202201142208.iEdIk0Sc-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 82c8aca93488730ce8f66101e0f3538f14b551dd)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/9b62852ec04b7d48971ce8016b13c27403929908
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 9b62852ec04b7d48971ce8016b13c27403929908
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/spi/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from drivers/spi/spi-zynqmp-gqspi.c:26:
   In file included from include/linux/mtd/spi-nor.h:10:
>> include/linux/mtd/cfi.h:62:2: warning: No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work. [-W#warnings]
   #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
    ^
   In file included from drivers/spi/spi-zynqmp-gqspi.c:13:
   include/linux/firmware/xlnx-zynqmp.h:1182:12: warning: unused function 'zynqmp_pm_sec_read_reg' [-Wunused-function]
   static int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value)
              ^
   include/linux/firmware/xlnx-zynqmp.h:1187:12: warning: unused function 'zynqmp_pm_sec_mask_write_reg' [-Wunused-function]
   static int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset,
              ^
   3 warnings generated.


vim +62 include/linux/mtd/cfi.h

^1da177e4c3f41 Linus Torvalds  2005-04-16  60  
241651d04d672f David Woodhouse 2007-09-06  61  #ifndef cfi_interleave
241651d04d672f David Woodhouse 2007-09-06 @62  #warning No CONFIG_MTD_CFI_Ix selected. No NOR chip support can work.
241651d04d672f David Woodhouse 2007-09-06  63  static inline int cfi_interleave(void *cfi)
241651d04d672f David Woodhouse 2007-09-06  64  {
241651d04d672f David Woodhouse 2007-09-06  65  	BUG();
241651d04d672f David Woodhouse 2007-09-06  66  	return 0;
241651d04d672f David Woodhouse 2007-09-06  67  }
241651d04d672f David Woodhouse 2007-09-06  68  #endif
241651d04d672f David Woodhouse 2007-09-06  69  

:::::: The code at line 62 was first introduced by commit
:::::: 241651d04d672fb685b2874707016cbbf95931e5 [MTD] Fix CFI build error when no map width or interleave supported

:::::: TO: David Woodhouse <dwmw2 at infradead.org>
:::::: CC: David Woodhouse <dwmw2 at infradead.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From narmstrong at baylibre.com  Fri Jan 14 06:40:50 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Fri, 14 Jan 2022 15:40:50 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>

Hi,

On 14/01/2022 15:23, Biju Das wrote:
> 
> 
>> -----Original Message-----
>> From: Neil Armstrong <narmstrong at baylibre.com>
>> Sent: 14 January 2022 13:56
>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>> <festevam at gmail.com>
>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi,
>>
>> On 14/01/2022 12:08, Biju Das wrote:
>>> Hi Neil,
>>>
>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>> callbacks")
>>>>
>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>> Hi Neil,
>>>>>
>>>>> + renesas-soc
>>>>>
>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>> callbacks")
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>> Hi Biju,
>>>>>>>
>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>> wrote:
>>>>>>>>
>>>>>>>> Hi All,
>>>>>>>>
>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>> till the commit
>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>> fmts
>>>>>> callbacks").
>>>>>>>>
>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>> setting it
>>>>>> into YUV format??).
>>>>>>>>
>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>> callback
>>>>>> and set colour as RGB24.
>>>>>>>>
>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>> I see
>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>
>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>
>>>>>> This patch was introduced to maintain the bridge color format
>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>> the negotiation callbacks.
>>>>>>
>>>>>> Let me check the code to see how to fix that.
>>>>>
>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>
>>>>> Cheers,
>>>>> Biju
>>>>>
>>>>>>
>>>>>>>
>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>> shows:
>>>>>>>
>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>
>>>>>>> The colors are shown correctly here.
>>>>>>>
>>>>>>
>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>
>>>>>> Anyway thanks for testing
>>>>>>
>>>>>> Neil
>>>>
>>>> Can you test :
>>>>
>>>> ==><===============================
>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>> 100644
>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>> drm_bridge *bridge,
>>>>         last_bridge_state =
>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>> state,
>>>>
>>>> last_bridge);
>>>>
>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>> +       /*
>>>> +        * Only negociate with real values if both end of the bridge
>> chain
>>>> +        * support negociation callbacks, otherwise you can end in a
>>>> situation
>>>> +        * where the selected output format doesn't match with the
>>>> + first
>>>> bridge
>>>> +        * output format.
>>>> +        */
>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>                 const struct drm_bridge_funcs *funcs =
>>>> last_bridge->funcs;
>>>>
>>>>                 /*
>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>> drm_bridge *bridge,
>>>>                 if (!out_bus_fmts)
>>>>                         return -ENOMEM;
>>>>
>>>> -               if (conn->display_info.num_bus_formats &&
>>>> +               /*
>>>> +                * If first bridge doesn't support negociation, use
>>>> MEDIA_BUS_FMT_FIXED
>>>> +                * as a safe value for the whole bridge chain
>>>> +                */
>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>> +                   conn->display_info.num_bus_formats &&
>>>>                     conn->display_info.bus_formats)
>>>>                         out_bus_fmts[0] = conn-
>>>>> display_info.bus_formats[0];
>>>>                 else
>>>> ==><===============================
>>>>
>>>> This should exclude your situation where the first bridge doesn't
>>>> support negociation.
>>>
>>> I have tested this fix with Linux next-20220114. Still I see colour
>> issue.
>>>
>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>
>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>
>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>> of RGB24.
>>>
>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>> [    3.473644] ########hdmi_video_sample
>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>
>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>> encoder.
> 
> Yep.
> 
>>
>> Let me figure that out, no sure I can find a clean solution except putting
>> back RGB24 before YUV.
>>
>> Anyway please test that:
> 
> It works now after reordering.
> 
> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
> 
> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
> 
> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
> at least it is fixing the colour issue??

Yes, it gets back to default behavior before negociation, nevertheless we need to think
how to handle your use-case correctly at some point.

I'll post this as a patch ASAP so it gets applied before landing in linus master.

Neil

> 
> Regards,
> Biju
> 
>>
>> ==><===============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..68f79094f648 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2589,45 +2589,44 @@ static u32
>> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>  	}
>>
>>  	/*
>> -	 * Order bus formats from 16bit to 8bit and from YUV422 to RGB
>> +	 * Order bus formats from 16bit to 8bit and from RGB to YUV422
>>  	 * if supported. In any case the default RGB888 format is added
>>  	 */
>>
>>  	if (max_bpc >= 16 && info->bpc == 16) {
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>> +
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV16_1X48;
>> -
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB161616_1X48;
>>  	}
>>
>>  	if (max_bpc >= 12 && info->bpc >= 12) {
>> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
>>
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV12_1X36;
>>
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB121212_1X36;
>> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY12_1X24;
>>  	}
>>
>>  	if (max_bpc >= 10 && info->bpc >= 10) {
>> -		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>> +		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
>>
>>  		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  			output_fmts[i++] = MEDIA_BUS_FMT_YUV10_1X30;
>>
>> -		output_fmts[i++] = MEDIA_BUS_FMT_RGB101010_1X30;
>> +		if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +			output_fmts[i++] = MEDIA_BUS_FMT_UYVY10_1X20;
>>  	}
>>
>> -	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> -		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
>> +	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
>>
>>  	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB444)
>>  		output_fmts[i++] = MEDIA_BUS_FMT_YUV8_1X24;
>>
>> -	/* Default 8bit RGB fallback */
>> -	output_fmts[i++] = MEDIA_BUS_FMT_RGB888_1X24;
>> +	if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
>> +		output_fmts[i++] = MEDIA_BUS_FMT_UYVY8_1X16;
>>
>>  	*num_output_fmts = i;
>>
>> ==><===============================
>>
>> Neil
>>
>>>
>>> Regards,
>>> Biju
>>>
> 



From semen.protsenko at linaro.org  Fri Jan 14 06:42:57 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 16:42:57 +0200
Subject: [PATCH] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
In-Reply-To: <016301d80923$bc172b50$344581f0$@samsung.com>
References: <CGME20220113203800epcas2p193b3961d55da5296cf7dd5fffacb87c0@epcas2p1.samsung.com>
 <20220113203754.23197-1-semen.protsenko@linaro.org>
 <016301d80923$bc172b50$344581f0$@samsung.com>
Message-ID: <CAPLW+4=gtkbBUO8QXXgjpq6_-ptVAnmej6yfyh3BM2ybvqLoXA@mail.gmail.com>

On Fri, 14 Jan 2022 at 10:50, Chanho Park <chanho61.park at samsung.com> wrote:
>
> > -----Original Message-----
> > From: Sam Protsenko <semen.protsenko at linaro.org>
> > Sent: Friday, January 14, 2022 5:38 AM
> > To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > Cc: linux-arm-kernel at lists.infradead.org; linux-samsung-
> > soc at vger.kernel.org; linux-kernel at vger.kernel.org
> > Subject: [PATCH] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
> >
> > The proper name is Exynos Auto V9, not V0. It was the typo slipped in
> > unnoticed, fix it.
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>
> Required "Fixes:" tag? Otherwise, LGTM.
>

Right, will add that in v2. Thanks!

> Reviewed-by: Chanho Park <chanho61.park at samsung.com>
>


From semen.protsenko at linaro.org  Fri Jan 14 06:46:06 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 16:46:06 +0200
Subject: [PATCH v2] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
Message-ID: <20220114144606.24358-1-semen.protsenko@linaro.org>

The proper name is Exynos Auto V9, not V0. It was the typo slipped in
unnoticed, fix it.

Fixes: b603377e408f ("soc: samsung: Add USI driver")
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Chanho Park <chanho61.park at samsung.com>
---
Changes in v2:
  - Add "Fixes" tag
  - Add R-b tag by Chanho Park

 drivers/soc/samsung/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/samsung/Kconfig b/drivers/soc/samsung/Kconfig
index a9f8b224322e..02e319508cc6 100644
--- a/drivers/soc/samsung/Kconfig
+++ b/drivers/soc/samsung/Kconfig
@@ -31,7 +31,7 @@ config EXYNOS_USI
 	help
 	  Enable support for USI block. USI (Universal Serial Interface) is an
 	  IP-core found in modern Samsung Exynos SoCs, like Exynos850 and
-	  ExynosAutoV0. USI block can be configured to provide one of the
+	  ExynosAutoV9. USI block can be configured to provide one of the
 	  following serial protocols: UART, SPI or High Speed I2C.
 
 	  This driver allows one to configure USI for desired protocol, which
-- 
2.30.2



From angelogioacchino.delregno at collabora.com  Fri Jan 14 06:47:37 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 14 Jan 2022 15:47:37 +0100
Subject: [PATCH] rpmsg: mtk_rpmsg: Fix circular locking dependency
Message-ID: <20220114144737.375621-1-angelogioacchino.delregno@collabora.com>

During execution of the worker that's used to register rpmsg devices
we are safely locking the channels mutex but, when creating a new
endpoint for such devices, we are registering a IPI on the SCP, which
then makes the SCP to trigger an interrupt, lock its own mutex and in
turn register more subdevices.
This creates a circular locking dependency situation, as the mtk_rpmsg
channels_lock will then depend on the SCP IPI lock.

[   18.014514]  Possible unsafe locking scenario:
[   18.014515]        CPU0                    CPU1
[   18.014517]        ----                    ----
[   18.045467]   lock(&mtk_subdev->channels_lock);
[   18.045474]                                lock(&scp->ipi_desc[i].lock);
[   18.228399]                                lock(&mtk_subdev->channels_lock);
[   18.228405]   lock(&scp->ipi_desc[i].lock);
[   18.264405]

To solve this, simply unlock the channels_lock mutex before calling
mtk_rpmsg_register_device() and relock it right after, as safety is
still ensured by the locking mechanism that happens right after
through SCP.
Notably, mtk_rpmsg_register_device() does not even require locking.

Fixes: 7017996951fd ("rpmsg: add rpmsg support for mt8183 SCP.")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/rpmsg/mtk_rpmsg.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
index 5b4404b8be4c..d1213c33da20 100644
--- a/drivers/rpmsg/mtk_rpmsg.c
+++ b/drivers/rpmsg/mtk_rpmsg.c
@@ -234,7 +234,9 @@ static void mtk_register_device_work_function(struct work_struct *register_work)
 		if (info->registered)
 			continue;
 
+		mutex_unlock(&subdev->channels_lock);
 		ret = mtk_rpmsg_register_device(subdev, &info->info);
+		mutex_lock(&subdev->channels_lock);
 		if (ret) {
 			dev_err(&pdev->dev, "Can't create rpmsg_device\n");
 			continue;
-- 
2.33.1



From jbrunet at baylibre.com  Fri Jan 14 06:53:58 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Fri, 14 Jan 2022 15:53:58 +0100
Subject: [PATCH v2] pwm: meson: external clock configuration for s4
In-Reply-To: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
References: <20220114090753.34873-1-Jiayi.Zhou@amlogic.com>
Message-ID: <1jmtjybc05.fsf@starbuckisacylon.baylibre.com>


On Fri 14 Jan 2022 at 17:07, <Jiayi.Zhou at amlogic.com> wrote:

> From: "Jiayi.zhou" <jiayi.zhou at amlogic.com>
>
> For PWM controller in the Meson-S4 SoC,
> PWM needs to obtain an external clock source.
> This patch tries to describe them in the DT compatible data.
>

I'm sorry but I have already commented on v1 that all the mess in here
don't seem necessary. For Reference:

"""
 You trying to bypass the input selection mux. There is no reason to do
 so.

 Your input clocks should be
 * OSC
 * vid_pll
 * fdiv3
 * fdiv4

 While the pwm driver could welcome a rework around how it deal with DT
 and the clocks, this S4 chip does not warrant any change compared to
 previous generation (AFAICT)

 All the stuff around "extern_clk" should go away IMO.
"""

Unless you can *really* justify why this approach is required, it is
firm Nack.


From robh at kernel.org  Fri Jan 14 07:02:36 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 14 Jan 2022 09:02:36 -0600
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add 8devices
In-Reply-To: <20220113102842.GA4357@standask-GA-A55M-S2HP>
References: <20220113102842.GA4357@standask-GA-A55M-S2HP>
Message-ID: <YeGQjJtN9u6U1zfT@robh.at.kernel.org>

On Thu, 13 Jan 2022 11:28:42 +0100, Stanislav Jakubek wrote:
> The vendor prefix for 8devices [1] is used in device tree [2], but was
> not documented so far. Add it to the schema to document it.
> 
> [1] https://www.8devices.com/
> [2] arch/arm/boot/dts/qcom-ipq4018-jalapeno.dts
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Reworked patch description
>   - Rebase on next-20220113
> 
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!


From robh at kernel.org  Fri Jan 14 07:02:50 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 14 Jan 2022 09:02:50 -0600
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add F(x)tec
In-Reply-To: <20220113102926.GA4388@standask-GA-A55M-S2HP>
References: <20220113102926.GA4388@standask-GA-A55M-S2HP>
Message-ID: <YeGQmqxGQiYI2Mgt@robh.at.kernel.org>

On Thu, 13 Jan 2022 11:29:26 +0100, Stanislav Jakubek wrote:
> The vendor prefix for F(x)tec [1] is used in device tree [2], but was
> not documented so far. Add it to the schema to document it.
> 
> [1] https://www.fxtec.com/
> [2] arch/arm64/boot/dts/qcom/msm8998-fxtec-pro1.dts
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Reworked patch description
>   - Rebase on next-20220113
> 
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!


From robh at kernel.org  Fri Jan 14 07:03:04 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 14 Jan 2022 09:03:04 -0600
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Huawei
In-Reply-To: <20220113103005.GA4421@standask-GA-A55M-S2HP>
References: <20220113103005.GA4421@standask-GA-A55M-S2HP>
Message-ID: <YeGQqA6FJwrVoNZK@robh.at.kernel.org>

On Thu, 13 Jan 2022 11:30:05 +0100, Stanislav Jakubek wrote:
> The vendor prefix for Huawei [1] is used in device trees [2][3], but was
> not documented so far. Add it to the schema to document it.
> 
> [1] https://www.huawei.com/en/
> [2] arch/arm64/boot/dts/qcom/msm8916-huawei-g7.dts
> [3] arch/arm64/boot/dts/qcom/msm8994-angler-rev-101.dts
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Reworked patch description
>   - Rebase on next-20220113
> 
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!


From robh at kernel.org  Fri Jan 14 07:03:17 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 14 Jan 2022 09:03:17 -0600
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Thundercomm
In-Reply-To: <20220113103036.GA4456@standask-GA-A55M-S2HP>
References: <20220113103036.GA4456@standask-GA-A55M-S2HP>
Message-ID: <YeGQtZP8KIOTPmWY@robh.at.kernel.org>

On Thu, 13 Jan 2022 11:30:36 +0100, Stanislav Jakubek wrote:
> The vendor prefix for Thundercomm [1] is used in device tree [2], but
> was not documented so far. Add it to the schema to document it.
> 
> [1] https://www.thundercomm.com/
> [2] arch/arm64/boot/dts/qcom/sdm845-db845c.dts
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Reworked patch description
>   - Rebase on next-20220113
> 
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)
> 

Applied, thanks!


From andre.przywara at arm.com  Fri Jan 14 07:04:37 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:04:37 +0000
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long
 based on RNDR
In-Reply-To: <YeAr/CnkF74rCp7p@zx2c4.com>
References: <20220113131239.1610455-1-ardb@kernel.org>
 <YeAr/CnkF74rCp7p@zx2c4.com>
Message-ID: <20220114150437.1542ccbe@donnerap.cambridge.arm.com>

On Thu, 13 Jan 2022 14:41:16 +0100
"Jason A. Donenfeld" <Jason at zx2c4.com> wrote:

Hi Jason,

> Wow, didn't expect for this to come so fast. Excellent.
> 
> On Thu, Jan 13, 2022 at 02:12:39PM +0100, Ard Biesheuvel wrote:
> > - map arch_get_random_int/_long() onto RNDR, which returns the output of
> >   a DRBG that is reseeded at an implemented defined rate;  
> 
> implemented -> implementation?
> 
> >  static inline bool __must_check arch_get_random_long(unsigned long *v)
> >  {
> > +	/*
> > +	 * Only support the generic interface after we have detected
> > +	 * the system wide capability, avoiding complexity with the
> > +	 * cpufeature code and with potential scheduling between CPUs
> > +	 * with and without the feature.
> > +	 */
> > +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> > +		return true;
> >  	return false;
> >  }  
> 
> Can't this just become:
> 
>   return cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v);

It could, but this pattern is used in the other functions to simplify
having extensions later.

> >  
> >  static inline bool __must_check arch_get_random_int(unsigned int *v)
> >  {
> > +	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> > +		unsigned long val;
> > +
> > +		if (__arm64_rndr(&val)) {
> > +			*v = val;
> > +			return true;
> > +		}
> > +	}
> >  	return false;
> >  }  
> 
> Why not implement arch_get_random_int with the same type of flow as
> arch_get_random_long?
> 
> static inline bool __must_check arch_get_random_int(unsigned int *v)
> {
> 	unsigned long val;
> 	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(&val))) {
> 		*v = val;
> 		return true;
> 	}
> 	return false;
> }
> 
> Or, even better, just define arch_get_random_int in terms of
> arch_get_random_long:

arch_get_random_long() might drain more entropy than needed, at least this
is a problem for the TRNG version. For the RNDR* instructions this
doesn't really matter, since they are always using 64-bit system
registers, but for the SMC interface there is a difference between
asking for 32 or 64 bits.
So this is admittedly not a problem in *this particular case*, but I'd
consider this an implementation detail of the sources used in the current
code, and for the sake of expandability it seems more robust to use this
approach.

Cheers,
Andre

> 
> static inline bool __must_check arch_get_random_int(unsigned int *v)
> {
> 	unsigned long val;
> 	if (arch_get_random_long(&val)) {
> 		*v = val;
> 		return true;
> 	}
> 	return false;
> }
> 
> 
> > @@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
> >  	}
> >  
> >  	/*
> > -	 * Only support the generic interface after we have detected
> > -	 * the system wide capability, avoiding complexity with the
> > -	 * cpufeature code and with potential scheduling between CPUs
> > -	 * with and without the feature.
> > +	 * RNDRRS is not backed by an entropy source but by a DRBG that is
> > +	 * reseeded after each invocation. This is not a 100% fit but good
> > +	 * enough to implement this API if no other entropy source exists.  
> 
> The docs are actually a bit more optimistic than that:
> 
> https://developer.arm.com/documentation/ddi0595/2021-03/AArch64-Registers/RNDRRS--Reseeded-Random-Number
> 
>  ~ Reseeded Random Number. Returns a 64-bit random number which is reseeded
>  ~ from the True Random Number source immediately before the read of the
>  ~ random number.
> 
> If I'm reading that correctly, it looks like the reseeding happens
> *before* the read, and it looks like it comes from a TRNG. In
> other words, it sounds to me like it's just doing something like
> HASH(READ_TRNG()). That would be pretty darn good.
> 
> >  	 */
> > -	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> > +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
> >  		return true;
> >  
> >  	return false;
> > @@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
> >  	}
> >  
> >  	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> > -		if (__arm64_rndr(&val)) {
> > +		if (__arm64_rndrrs(&val)) {
> >  			*v = val;
> >  			return true;
> >  		}  
> 
> I suppose the same control flow simplification stuff mentioned above
> could be done here too, if you feel like what I mentioned earlier is
> worthwhile.
> 
> From a randomness perspective:
> 
> Acked-by: Jason A. Donenfeld <Jason at zx2c4.com>
> 
> Thanks,
> Jason



From andre.przywara at arm.com  Fri Jan 14 07:07:25 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:07:25 +0000
Subject: [PATCH] arm64: random: implement arch_get_random_int/_long
 based on RNDR
In-Reply-To: <20220113131239.1610455-1-ardb@kernel.org>
References: <20220113131239.1610455-1-ardb@kernel.org>
Message-ID: <20220114150725.23693d0e@donnerap.cambridge.arm.com>

On Thu, 13 Jan 2022 14:12:39 +0100
Ard Biesheuvel <ardb at kernel.org> wrote:

Hi,

> When support for RNDR/RNDRRS was introduced, we elected to only
> implement arch_get_random_seed_int/_long(), and back them by RNDR
> instead of RNDRRS. This was needed to prevent potential performance
> and/or starvation issues resulting from the fact that the /dev/random
> driver used to invoke these routines on various hot paths.
> 
> These issues have all been addressed now [0] [1], and so we can wire up
> this API more straight-forwardly:
> 
> - map arch_get_random_int/_long() onto RNDR, which returns the output of
>   a DRBG that is reseeded at an implemented defined rate;
> - map arch_get_random_seed_int/_long() onto the TRNG firmware service,
>   which returns true, conditioned entropy, or onto RNDRRS if the TRNG
>   service is unavailable, which returns the output of a DRBG that is
>   reseeded every time it is used.
> 
> [0] 390596c9959c random: avoid arch_get_random_seed_long() when collecting IRQ randomness
> [1] 2ee25b6968b1 random: avoid superfluous call to RDRAND in CRNG extraction
> 
> Cc: Andre Przywara <andre.przywara at arm.com>
> Cc: Mark Brown <broonie at kernel.org>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Looks alright to me, at least from the code point of view: I am not a
"crypto guy".

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/arm64/include/asm/archrandom.h | 45 +++++++++++++++++---
>  1 file changed, 39 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/archrandom.h b/arch/arm64/include/asm/archrandom.h
> index 09e43272ccb0..d1bb5e71df25 100644
> --- a/arch/arm64/include/asm/archrandom.h
> +++ b/arch/arm64/include/asm/archrandom.h
> @@ -42,13 +42,47 @@ static inline bool __arm64_rndr(unsigned long *v)
>  	return ok;
>  }
>  
> +static inline bool __arm64_rndrrs(unsigned long *v)
> +{
> +	bool ok;
> +
> +	/*
> +	 * Reads of RNDRRS set PSTATE.NZCV to 0b0000 on success,
> +	 * and set PSTATE.NZCV to 0b0100 otherwise.
> +	 */
> +	asm volatile(
> +		__mrs_s("%0", SYS_RNDRRS_EL0) "\n"
> +	"	cset %w1, ne\n"
> +	: "=r" (*v), "=r" (ok)
> +	:
> +	: "cc");
> +
> +	return ok;
> +}
> +
>  static inline bool __must_check arch_get_random_long(unsigned long *v)
>  {
> +	/*
> +	 * Only support the generic interface after we have detected
> +	 * the system wide capability, avoiding complexity with the
> +	 * cpufeature code and with potential scheduling between CPUs
> +	 * with and without the feature.
> +	 */
> +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> +		return true;
>  	return false;
>  }
>  
>  static inline bool __must_check arch_get_random_int(unsigned int *v)
>  {
> +	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> +		unsigned long val;
> +
> +		if (__arm64_rndr(&val)) {
> +			*v = val;
> +			return true;
> +		}
> +	}
>  	return false;
>  }
>  
> @@ -71,12 +105,11 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
>  	}
>  
>  	/*
> -	 * Only support the generic interface after we have detected
> -	 * the system wide capability, avoiding complexity with the
> -	 * cpufeature code and with potential scheduling between CPUs
> -	 * with and without the feature.
> +	 * RNDRRS is not backed by an entropy source but by a DRBG that is
> +	 * reseeded after each invocation. This is not a 100% fit but good
> +	 * enough to implement this API if no other entropy source exists.
>  	 */
> -	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndr(v))
> +	if (cpus_have_const_cap(ARM64_HAS_RNG) && __arm64_rndrrs(v))
>  		return true;
>  
>  	return false;
> @@ -96,7 +129,7 @@ static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
>  	}
>  
>  	if (cpus_have_const_cap(ARM64_HAS_RNG)) {
> -		if (__arm64_rndr(&val)) {
> +		if (__arm64_rndrrs(&val)) {
>  			*v = val;
>  			return true;
>  		}



From robh at kernel.org  Fri Jan 14 07:08:43 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 14 Jan 2022 09:08:43 -0600
Subject: [PATCH v2] dt-bindings: vendor-prefixes: add Wingtech
In-Reply-To: <20220113103110.GA4488@standask-GA-A55M-S2HP>
References: <20220113103110.GA4488@standask-GA-A55M-S2HP>
Message-ID: <YeGR+wpFJcPfxmfF@robh.at.kernel.org>

On Thu, Jan 13, 2022 at 11:31:10AM +0100, Stanislav Jakubek wrote:
> The vendor prefix for Wingtech [1] is used in device tree [2], but was
> not documented so far. Add it to the schema to document it.
> 
> [1] http://www.wingtech.com/en
> [2] arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Reworked patch description
>   - Rebase on next-20220113
> 
>  Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
>  1 file changed, 2 insertions(+)

Applied, thanks.

Rob


From andre.przywara at arm.com  Fri Jan 14 07:09:57 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:09:57 +0000
Subject: [bootwrapper PATCH v2 00/13] Cleanups and improvements
In-Reply-To: <20220114105653.3003399-1-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
Message-ID: <20220114150957.6914805f@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:40 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> This series reworks the aarch64 boot-wrapper, moving a fair amount of
> initialization code to C. This has a few benefits:
> 
> 1) This makes the code more legible and easier to maintain.
> 
>     Current feature detection and system register configuration is
>     written in assembly, requiring runs of *almost* identical blocks of
>     assembly to read ID registers and conditionally initialize register
>     values. This requires a bunch of labels (which are all named
>     numerically), and all the magic numbers are hard coded, so this gets
>     pretty painful to read:
>     
>     |	mrs	x1, id_aa64isar0_el1
>     |	ubfx	x1, x1, #24, #4
>     |	cbz	x1, 1f
>     |
>     |	orr	x0, x0, #(1 << 34)		// TME enable
>     |
>     | 1:
>     
>     In C, it's much easier to add helpers which use mnemonics, which
>     makes the code much easier to read, and avoids the need to manually
>     allocate registers, etc:
>     
>     |	if (mrs_field(ID_AA64ISAR0_EL1, TME))
>     |		scr |= SCR_EL3_TME;
> 
>     This should make it easier to handle new architectural extensions
>     (and/or architecture variants such as ARMv8-R) in future.
>     
> 2) This allows for better diagnostics.
> 
>     Currently a mis-configured boot-wrapper is rather unforgiving, and
>     provides no indication as to what might have gone wrong. By moving
>     initialization to C, we can make use to the UART code to log
>     diagnostic information, and we can more easily add additional error
>     handling and conditional logic.
>     
>     This series adds diagnostic information and error handling that can
>     be used to identify problems such as the boot-wrapper being launched
>     at the wrong exception level:
>     
>     | Boot-wrapper v0.2
>     | Entered at EL2
>     | Memory layout:
>     | [0000000080000000..0000000080001f90] => boot-wrapper
>     | [000000008000fff8..0000000080010000] => mbox
>     | [0000000080200000..00000000822af200] => kernel
>     | [0000000088000000..0000000088002857] => dtb
>     |
>     | WARNING: PSCI could not be initialized. Boot may fail
> 
> Originally I had planned for this to be a more expansive set of changes,
> unifying some early control-flow, fixing some latent bugs, and making
> the boot-wrapper dynamically handle being entered at any of EL{3,2,1}
> with automated selection of a suitable DT. As the series has already
> become pretty long, I'd like to get this preparatory cleanup out of the
> way first, and handle those cases with subsequent patches.
> 
> If there are no objections, I intend to apply these by the end of the
> day.

Can you hold back with that till the beginning of next week? I got stuck
halfway in the series with my review, but am on it now as we speak.

Cheers,
Andre

> 
> I've pushed the series to the `cleanup` branch in the boot-wrapper repo:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git/
>   git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git
> 
> ... and it should apply cleanup atop the `master` branch.
> 
> Since v1 [1]:
> * Add comments for bit-field macros
> * Use BIT() for *_RES1 definitions
> * Complete start_el3/start_no_el3 cleanup
> * Remove extraneous macro definition
> 
> [1] https://lore.kernel.org/r/20220111130653.2331827-1-mark.rutland at arm.com/
> 
> Thanks,
> Mark.
> 
> Mark Rutland (13):
>   Document entry requirements
>   Add bit-field macros
>   aarch64: add system register accessors
>   aarch32: add coprocessor accessors
>   aarch64: add mov_64 macro
>   aarch64: initialize SCTLR_ELx for the boot-wrapper
>   Rework common init C code
>   Announce boot-wrapper mode / exception level
>   aarch64: move the bulk of EL3 initialization to C
>   aarch32: move the bulk of Secure PL1 initialization to C
>   Announce locations of memory objects
>   Rework bootmethod initialization
>   Unify start_el3 & start_no_el3
> 
>  Makefile.am                       |   6 +-
>  arch/aarch32/boot.S               |  33 +++---
>  arch/aarch32/include/asm/cpu.h    |  62 ++++++++---
>  arch/aarch32/include/asm/gic-v3.h |   6 +-
>  arch/aarch32/include/asm/psci.h   |  28 +++++
>  arch/aarch32/init.c               |  42 ++++++++
>  arch/aarch32/psci.S               |  16 +--
>  arch/aarch32/utils.S              |   9 --
>  arch/aarch64/boot.S               | 169 +++++++++++++-----------------
>  arch/aarch64/common.S             |  10 +-
>  arch/aarch64/include/asm/cpu.h    | 102 +++++++++++++++---
>  arch/aarch64/include/asm/gic-v3.h |  10 +-
>  arch/aarch64/include/asm/psci.h   |  28 +++++
>  arch/aarch64/init.c               |  88 ++++++++++++++++
>  arch/aarch64/psci.S               |  22 +---
>  arch/aarch64/spin.S               |   6 +-
>  arch/aarch64/utils.S              |   9 --
>  common/boot.c                     |   4 -
>  common/init.c                     |  60 +++++++++++
>  common/platform.c                 |  45 +++++---
>  common/psci.c                     |  22 +++-
>  include/bits.h                    |  79 ++++++++++++++
>  include/boot.h                    |   2 +
>  include/platform.h                |  20 ++++
>  model.lds.S                       |  20 ++--
>  25 files changed, 668 insertions(+), 230 deletions(-)
>  create mode 100644 arch/aarch32/include/asm/psci.h
>  create mode 100644 arch/aarch32/init.c
>  create mode 100644 arch/aarch64/include/asm/psci.h
>  create mode 100644 arch/aarch64/init.c
>  create mode 100644 common/init.c
>  create mode 100644 include/bits.h
>  create mode 100644 include/platform.h
> 



From francesco.dolcini at toradex.com  Fri Jan 14 07:18:46 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Fri, 14 Jan 2022 16:18:46 +0100
Subject: [PATCH v1 1/2] ARM: dts: imx7s: Define operating points table for
 cpufreq
In-Reply-To: <20220114151847.290518-1-francesco.dolcini@toradex.com>
References: <20220114151847.290518-1-francesco.dolcini@toradex.com>
Message-ID: <20220114151847.290518-2-francesco.dolcini@toradex.com>

From: Denys Drozdov <denys.drozdov at toradex.com>

Processor operating points for imx7s.dtsi should be properly defined to
perform correct imx-cpufreq-dt probe and registration and provide an
access to the temperature sensors using the i.MX thermal driver.

Signed-off-by: Denys Drozdov <denys.drozdov at toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
 arch/arm/boot/dts/imx7s.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 52a9aeecdbb2..5af6d58666f4 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -76,6 +76,22 @@ cpu0: cpu at 0 {
 			clock-latency = <61036>; /* two CLK32 periods */
 			clocks = <&clks IMX7D_CLK_ARM>;
 			cpu-idle-states = <&cpu_sleep_wait>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			#cooling-cells = <2>;
+			nvmem-cells = <&fuse_grade>;
+			nvmem-cell-names = "speed_grade";
+		};
+	};
+
+	cpu0_opp_table: opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-792000000 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <150000>;
+			opp-supported-hw = <0xf>, <0xf>;
 		};
 	};
 
-- 
2.25.1



From francesco.dolcini at toradex.com  Fri Jan 14 07:18:45 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Fri, 14 Jan 2022 16:18:45 +0100
Subject: [PATCH v1 0/2] Enable i.MX7 SOLO temperature sensor
Message-ID: <20220114151847.290518-1-francesco.dolcini@toradex.com>

To be able to read the T junction on i.MX CPU the imx-cpufreq-dt needs to be
loaded, however this is currently not the case for i.MX7S given that it does
have only one operating frequency.

Add "fsl,imx7s" to cpufreq-dt-platdev blocklist and a single frequency
operating point to the CPU.

With that it is now possible to correctly read the CPU T junction.

Tested on Toradex Colibri iMX7S

[    6.232577] imx-cpufreq-dt imx-cpufreq-dt: cpu speed grade 0 mkt segment 1 supported-hw 0x1 0x2
...
[    6.880624] imx_thermal 30360000.anatop:tempmon: Extended Commercial CPU temperature grade - max:105C critical:100C passive:95C

root at colibri-imx7-02983025:~# cat /sys/class/thermal/thermal_zone0/temp 
38000


Denys Drozdov (1):
  ARM: dts: imx7s: Define operating points table for cpufreq

Stefan Agner (1):
  cpufreq: Add i.MX7S to cpufreq-dt-platdev blocklist

 arch/arm/boot/dts/imx7s.dtsi         | 16 ++++++++++++++++
 drivers/cpufreq/cpufreq-dt-platdev.c |  2 ++
 2 files changed, 18 insertions(+)

-- 
2.25.1



From francesco.dolcini at toradex.com  Fri Jan 14 07:18:47 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Fri, 14 Jan 2022 16:18:47 +0100
Subject: [PATCH v1 2/2] cpufreq: Add i.MX7S to cpufreq-dt-platdev blocklist
In-Reply-To: <20220114151847.290518-1-francesco.dolcini@toradex.com>
References: <20220114151847.290518-1-francesco.dolcini@toradex.com>
Message-ID: <20220114151847.290518-3-francesco.dolcini@toradex.com>

From: Stefan Agner <stefan.agner at toradex.com>

The i.MX 7Solo currently does not have multiple operating points,
however, in order for the i.MX Thermal driver to successfully probe
a cpufreq device is required. Add it to the cpufreq-dt-platdev
driver's blocklist to allow using imx-cpufreq-dt.

Signed-off-by: Stefan Agner <stefan.agner at toradex.com>
Cc: Stefan Agner <stefan at agner.ch>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
 drivers/cpufreq/cpufreq-dt-platdev.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index ca1d103ec449..2e08f8564a12 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -110,6 +110,8 @@ static const struct of_device_id blocklist[] __initconst = {
 
 	{ .compatible = "fsl,imx7ulp", },
 	{ .compatible = "fsl,imx7d", },
+	{ .compatible = "fsl,imx7s", },
+
 	{ .compatible = "fsl,imx8mq", },
 	{ .compatible = "fsl,imx8mm", },
 	{ .compatible = "fsl,imx8mn", },
-- 
2.25.1



From kai.heng.feng at canonical.com  Fri Jan 14 07:22:53 2022
From: kai.heng.feng at canonical.com (Kai-Heng Feng)
Date: Fri, 14 Jan 2022 23:22:53 +0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <YeF18mxKuO4/4G0V@lunn.ch>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
 <YeF18mxKuO4/4G0V@lunn.ch>
Message-ID: <CAAd53p5R2y-2JhWx3wp2=aBypJO=iV7fFS99eAgk6q7KBZMFMA@mail.gmail.com>

On Fri, Jan 14, 2022 at 9:09 PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> On Fri, Jan 14, 2022 at 12:07:54PM +0800, Kai-Heng Feng wrote:
> > BIOS on Dell Edge Gateway 3200 already makes its own phy LED setting, so
> > instead of setting another value, keep it untouched and restore the saved
> > value on system resume.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng at canonical.com>
> > ---
> >  .../net/ethernet/stmicro/stmmac/dwmac-intel.c | 16 +++++
> >  drivers/net/ethernet/stmicro/stmmac/stmmac.h  |  2 +
> >  .../net/ethernet/stmicro/stmmac/stmmac_main.c |  4 ++
> >  drivers/net/phy/marvell.c                     | 58 ++++++++++++-------
> >  include/linux/marvell_phy.h                   |  1 +
> >  5 files changed, 61 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > index 8e8778cfbbadd..f8a2879e0264a 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
> > @@ -857,6 +857,16 @@ static const struct dmi_system_id quark_pci_dmi[] = {
> >       {}
> >  };
> >
> > +static const struct dmi_system_id use_preset_led[] = {
> > +     {
> > +             .matches = {
> > +                     DMI_MATCH(DMI_SYS_VENDOR, "Dell EMC"),
> > +                     DMI_MATCH(DMI_PRODUCT_NAME, "Edge Gateway 3200"),
> > +             },
> > +     },
> > +     {}
> > +};
>
> This is a PHY property. Why is the MAC involved?

This is inspired by commit a93f7fe13454 ("net: phy: marvell: add new
default led configure for m88e151x") which passes the flag from MAC to
PHY.

>
> Please also think about how to make this generic, so any ACPI based
> system can use it, with any PHY.

ACPI property won't work because it ties to ACPI platform device or
PCI device, so the property still needs to be passed from MAC to PHY.

So the only approach I can think of is to use DMI match directly in PHY driver.

Kai-Heng

>
>      Andrew


From mark.rutland at arm.com  Fri Jan 14 07:23:28 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 15:23:28 +0000
Subject: [bootwrapper PATCH v2 00/13] Cleanups and improvements
In-Reply-To: <20220114150957.6914805f@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114150957.6914805f@donnerap.cambridge.arm.com>
Message-ID: <YeGVcO+U68moi2eU@FVFF77S0Q05N>

On Fri, Jan 14, 2022 at 03:09:57PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:40 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > If there are no objections, I intend to apply these by the end of the
> > day.
> 
> Can you hold back with that till the beginning of next week? I got stuck
> halfway in the series with my review, but am on it now as we speak.

Sure.

Thanks for taking a look. :)

Mark.


From kai.heng.feng at canonical.com  Fri Jan 14 07:25:17 2022
From: kai.heng.feng at canonical.com (Kai-Heng Feng)
Date: Fri, 14 Jan 2022 23:25:17 +0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <YeF4kbsqag+kZ7ji@lunn.ch>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
 <YeF4kbsqag+kZ7ji@lunn.ch>
Message-ID: <CAAd53p4P9STxTUsZ2fXNqOnmwLMfOBXpYR5hvcJHk5-0V7MPgA@mail.gmail.com>

On Fri, Jan 14, 2022 at 9:20 PM Andrew Lunn <andrew at lunn.ch> wrote:
>
> >  static void marvell_config_led(struct phy_device *phydev)
> >  {
> > -     u16 def_config;
> > +     struct marvell_priv *priv = phydev->priv;
> >       int err;
> >
> > -     switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
> > -     /* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
> > -     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
> > -     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1318S):
> > -             def_config = MII_88E1121_PHY_LED_DEF;
> > -             break;
> > -     /* Default PHY LED config:
> > -      * LED[0] .. 1000Mbps Link
> > -      * LED[1] .. 100Mbps Link
> > -      * LED[2] .. Blink, Activity
> > -      */
> > -     case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1510):
> > -             if (phydev->dev_flags & MARVELL_PHY_LED0_LINK_LED1_ACTIVE)
> > -                     def_config = MII_88E1510_PHY_LED0_LINK_LED1_ACTIVE;
> > -             else
> > -                     def_config = MII_88E1510_PHY_LED_DEF;
> > -             break;
> > -     default:
> > +     if (priv->led_def_config == -1)
> >               return;
> > +
> > +     if (priv->led_def_config)
> > +             goto write;
>
> Really?
>
> Please restructure this code. Take it apart into helpers. You need:
>
> A function to set the actual LED configuration.
> A function to decide what, if any, configuration to set
> A function to store the current configuration on suspend.
> A function to restore the current configuration on resume.
>
> Lots of little functions will make it much easier to understand, and
> avoid 1980s BASIC style.

Sure, will turn these into helper functions.

>
> I'm also surprised you need to deal with suspend/resume. Why does the
> BIOS not set the LED mode on resume, same as it does on power up?

I was told this is a BIOS limitation. I'll ask vendor _why_ the LED
can't be restored by BIOS.

Kai-Heng

>
>       Andrew


From andre.przywara at arm.com  Fri Jan 14 07:30:53 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:30:53 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <20220114105653.3003399-12-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-12-mark.rutland@arm.com>
Message-ID: <20220114153053.658a5ffa@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:51 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> To make it easier to debug boot failures, log the location of memory
> objects at boot time.
> 
> This is logged to the serial console as:
> 
> | Boot-wrapper v0.2
> | Entered at EL3
> | Memory layout:
> | [0000000080000000..0000000080001f90] => boot-wrapper
> | [000000008000fff8..0000000080010000] => mbox
> | [0000000080200000..00000000822af200] => kernel
> | [0000000088000000..0000000088002857] => dtb
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  common/init.c      | 27 +++++++++++++++++++++++++++
>  common/platform.c  | 13 +++++++++++++
>  include/platform.h |  2 ++
>  model.lds.S        | 20 ++++++++++++++------
>  4 files changed, 56 insertions(+), 6 deletions(-)
> 
> diff --git a/common/init.c b/common/init.c
> index 2600f73..fc74b9e 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
>  	print_string("Boot-wrapper v0.2\r\n");
>  }
>  
> +#define announce_object(object, desc)				\
> +do {								\
> +	extern char object##__start[];				\
> +	extern char object##__end[];				\
> +	print_string("[");					\
> +	print_ulong_hex((unsigned long)object##__start);	\
> +	print_string("..");					\
> +	print_ulong_hex((unsigned long)object##__end);		\
> +	print_string("] => " desc "\r\n");			\
> +} while (0)
> +
> +static void announce_objects(void)
> +{
> +	print_string("Memory layout:\r\n");
> +	announce_object(text, "boot-wrapper");
> +	announce_object(mbox, "mbox");
> +	announce_object(kernel, "kernel");
> +#ifdef XEN
> +	announce_object(xen, "xen");
> +#endif
> +	announce_object(dtb, "dtb");
> +#ifdef USE_INITRD
> +	announce_object(filesystem, "initrd");
> +#endif
> +}
> +
>  void announce_arch(void);
>  
>  void cpu_init_bootwrapper(void)
> @@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
>  		init_uart();
>  		announce_bootwrapper();
>  		announce_arch();
> +		announce_objects();
>  		print_string("\r\n");
>  		init_platform();
>  	}
> diff --git a/common/platform.c b/common/platform.c
> index 80d0562..26e5944 100644
> --- a/common/platform.c
> +++ b/common/platform.c
> @@ -52,6 +52,19 @@ void print_string(const char *str)
>  		print_char(*str++);
>  }
>  
> +#define HEX_CHARS_PER_LONG (2 * sizeof(long))
> +
> +void print_ulong_hex(unsigned long val)
> +{
> +	const char hex_chars[16] = "0123456789abcdef";

This breaks the build for me (I guess because of the const?):
-------------------
ld --gc-sections arch/aarch64/boot.o arch/aarch64/stack.o arch/aarch64/utils.o arch/aarch64/init.o arch/aarch64/psci.o common/boot.o common/bakery_lock.o common/platform.o common/lib.o common/init.o common/psci.o common/gic-v3.o -o linux-system.axf --script=model.lds
ld: common/platform.o: in function `print_ulong_hex':
/src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
ld: /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
ld: /src/boot-wrapper-aarch64.git/common/platform.c:66: undefined reference to `__stack_chk_fail'
/src/boot-wrapper-aarch64.git/common/platform.c:66:(.text.print_ulong_hex+0xa0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `__stack_chk_fail'
make: *** [Makefile:684: linux-system.axf] Error 1
------------------

Adding -fno-stack-protector fixes it again.

I am still checking on each one of those compiler options, shall I send a
smaller version of that patch 3/9 of mine, meanwhile, just carrying the
uncontested -ffreestanding and -nostdlib, plus -fno-stack-protector?

Cheers,
Andre

> +	int i;
> +
> +	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
> +		int v = (val >> (4 * i)) & 0xf;
> +		print_char(hex_chars[v]);
> +	}
> +}
> +
>  void init_uart(void)
>  {
>  	/*
> diff --git a/include/platform.h b/include/platform.h
> index 237b481..c88e124 100644
> --- a/include/platform.h
> +++ b/include/platform.h
> @@ -11,6 +11,8 @@
>  
>  void print_char(char c);
>  void print_string(const char *str);
> +void print_ulong_hex(unsigned long val);
> +
>  void init_uart(void);
>  
>  void init_platform(void);
> diff --git a/model.lds.S b/model.lds.S
> index d4e7e13..dacaa25 100644
> --- a/model.lds.S
> +++ b/model.lds.S
> @@ -35,46 +35,54 @@ SECTIONS
>  	 * the boot section's *(.data)
>  	 */
>  	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
> -		kernel = .;
> +		kernel__start = .;
>  		KERNEL
> +		kernel__end = .;
>  	}
>  
>  #ifdef XEN
>  	.xen (PHYS_OFFSET + XEN_OFFSET): {
> -		xen = .;
> +		xen__start = .;
>  		XEN
> +		xen__end = .;
>  	}
>  
> -	entrypoint = xen;
> +	entrypoint = xen__start;
>  #else
> -	entrypoint = kernel;
> +	entrypoint = kernel__start;
>  #endif
>  
>  	.dtb (PHYS_OFFSET + FDT_OFFSET): {
> +		dtb__start = .;
>  		dtb = .;
>  		./fdt.dtb
> +		dtb__end = .;
>  	}
>  
>  #ifdef USE_INITRD
>  	.filesystem (PHYS_OFFSET + FS_OFFSET): {
> -		filesystem = .;
> +		filesystem__start = .;
>  		FILESYSTEM
> -		fs_size = . - filesystem;
> +		filesystem__end = .;
>  	}
>  #endif
>  
>  	.boot PHYS_OFFSET: {
> +		text__start = .;
>  		*(.init)
>  		*(.text*)
>  		*(.data* .rodata* .bss* COMMON)
>  		*(.vectors)
>  		*(.stack)
>  		PROVIDE(etext = .);
> +		text__end = .;
>  	}
>  
>  	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
> +		mbox__start = .;
>  		mbox = .;
>  		QUAD(0x0)
> +		mbox__end = .;
>  	}
>  
>  	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")



From lkp at intel.com  Fri Jan 14 07:30:08 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 14 Jan 2022 23:30:08 +0800
Subject: [xilinx-xlnx:master 157/326] ld.lld: error: undefined symbol:
 dwc3_host_wakeup_capable
Message-ID: <202201142314.1HlCefr5-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: 5b2efd9328312427b7830d41ce3c8dfec63457eb [157/326] usb: xhci-plat: Add remote wakeup support for xilinx
config: i386-randconfig-a011 (https://download.01.org/0day-ci/archive/20220114/202201142314.1HlCefr5-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 82c8aca93488730ce8f66101e0f3538f14b551dd)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/5b2efd9328312427b7830d41ce3c8dfec63457eb
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 5b2efd9328312427b7830d41ce3c8dfec63457eb
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: dwc3_host_wakeup_capable
   >>> referenced by xhci-plat.c:94 (drivers/usb/host/xhci-plat.c:94)
   >>>               usb/host/xhci-plat.o:(xhci_plat_probe) in archive drivers/built-in.a

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From andre.przywara at arm.com  Fri Jan 14 07:32:27 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:32:27 +0000
Subject: [bootwrapper PATCH v2 03/13] aarch64: add system register
 accessors
In-Reply-To: <20220114105653.3003399-4-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-4-mark.rutland@arm.com>
Message-ID: <20220114153227.3f2a2d09@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:43 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> We open code the use of mrs/msr for specific registers, which is
> somewhat tedious. Add macros to do this generically, along with a helper
> to extract a specific register field. Existing C usage is converted to
> the new helpers, and register definitions moved to a common location.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Stared at and verified the architecture bits used in here:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch64/include/asm/cpu.h    | 41 ++++++++++++++++++++++---------
>  arch/aarch64/include/asm/gic-v3.h | 10 +++-----
>  2 files changed, 32 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 63eb1c3..1053414 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -9,10 +9,14 @@
>  #ifndef __ASM_AARCH64_CPU_H
>  #define __ASM_AARCH64_CPU_H
>  
> +#include <bits.h>
> +
>  #define MPIDR_ID_BITS		0xff00ffffff
>  
>  #define CURRENTEL_EL3		(3 << 2)
>  
> +#define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
> +
>  /*
>   * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
>   * no WXN.
> @@ -29,6 +33,12 @@
>  
>  #define CPTR_EL3_EZ		(1 << 8)
>  
> +#define ICC_SRE_EL2		S3_4_C12_C9_5
> +#define ICC_SRE_EL3		S3_6_C12_C12_5
> +#define ICC_CTLR_EL1		S3_0_C12_C12_4
> +#define ICC_CTLR_EL3		S3_6_C12_C12_4
> +#define ICC_PMR_EL1		S3_0_C4_C6_0
> +
>  #define ZCR_EL3			s3_6_c1_c2_0
>  #define ZCR_EL3_LEN_MASK	0x1ff
>  
> @@ -50,20 +60,27 @@
>  
>  #define sevl()		asm volatile ("sevl\n" : : : "memory")
>  
> -static inline unsigned long read_mpidr(void)
> -{
> -	unsigned long mpidr;
> +#define __str(def)	#def
>  
> -	asm volatile ("mrs	%0, mpidr_el1\n" : "=r" (mpidr));
> -	return mpidr & MPIDR_ID_BITS;
> -}
> +#define mrs(reg)							\
> +({									\
> +	unsigned long __mrs_val;					\
> +	asm volatile("mrs %0, " __str(reg) : "=r" (__mrs_val));		\
> +	__mrs_val;							\
> +})
>  
> -static inline uint64_t read_id_aa64pfr0(void)
> -{
> -	uint64_t val;
> +#define msr(reg, val)							\
> +do {									\
> +	unsigned long __msr_val = val;					\
> +	asm volatile("msr " __str(reg) ", %0" : : "r" (__msr_val));	\
> +} while (0)
> +
> +#define mrs_field(reg, field) \
> +	BITS_EXTRACT(mrs(reg), (reg##_##field))
>  
> -	asm volatile ("mrs	%0, id_aa64pfr0_el1\n" : "=r" (val));
> -	return val;
> +static inline unsigned long read_mpidr(void)
> +{
> +	return mrs(mpidr_el1) & MPIDR_ID_BITS;
>  }
>  
>  static inline void iciallu(void)
> @@ -73,7 +90,7 @@ static inline void iciallu(void)
>  
>  static inline int has_gicv3_sysreg(void)
>  {
> -	return !!((read_id_aa64pfr0() >> 24) & 0xf);
> +	return !!mrs_field(ID_AA64PFR0_EL1, GIC);
>  }
>  
>  #endif /* !__ASSEMBLY__ */
> diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
> index 5b32380..2447480 100644
> --- a/arch/aarch64/include/asm/gic-v3.h
> +++ b/arch/aarch64/include/asm/gic-v3.h
> @@ -9,20 +9,16 @@
>  #ifndef __ASM_AARCH64_GICV3_H
>  #define __ASM_AARCH64_GICV3_H
>  
> -#define ICC_SRE_EL2	"S3_4_C12_C9_5"
> -#define ICC_SRE_EL3	"S3_6_C12_C12_5"
> -#define ICC_CTLR_EL1	"S3_0_C12_C12_4"
> -#define ICC_CTLR_EL3	"S3_6_C12_C12_4"
> -#define ICC_PMR_EL1	"S3_0_C4_C6_0"
> +#include <asm/cpu.h>
>  
>  static inline void gic_write_icc_sre(uint32_t val)
>  {
> -	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
> +	msr(ICC_SRE_EL3, val);
>  }
>  
>  static inline void gic_write_icc_ctlr(uint32_t val)
>  {
> -	asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
> +	msr(ICC_CTLR_EL3, val);
>  }
>  
>  #endif



From andre.przywara at arm.com  Fri Jan 14 07:37:31 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:37:31 +0000
Subject: [bootwrapper PATCH 05/13] aarch64: add mov_64 macro
In-Reply-To: <Yd7jTD1GFrD3/jGA@FVFF77S0Q05N>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-6-mark.rutland@arm.com>
 <20220111144149.6b519ede@donnerap.cambridge.arm.com>
 <Yd7jTD1GFrD3/jGA@FVFF77S0Q05N>
Message-ID: <20220114153731.4c4c2004@donnerap.cambridge.arm.com>

On Wed, 12 Jan 2022 14:18:52 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> On Tue, Jan 11, 2022 at 02:41:49PM +0000, Andre Przywara wrote:
> > On Tue, 11 Jan 2022 13:06:45 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi,
> >   
> > > In subsequent patches we'll need to load 64-bit values into GPRs before
> > > the CPU is in a known endianness, where we cannot use literal pools.
> > > 
> > > In preparation for that, this patch adds a new `mov_64` macro to load a
> > > 64-bit value into a GPR using a sequence of MOV and MOVKs, which will
> > > function the same regardless of the CPU's endianness.
> > > 
> > > At the same time, move the `cpuid` macro to use `mov_64` internally.
> > > 
> > > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > > ---
> > >  arch/aarch64/common.S | 10 +++++++++-
> > >  1 file changed, 9 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
> > > index c7171a9..3279fa9 100644
> > > --- a/arch/aarch64/common.S
> > > +++ b/arch/aarch64/common.S
> > > @@ -9,9 +9,17 @@
> > >  
> > >  #include <cpu.h>
> > >  
> > > +	/* Load a 64-bit value using immediates */
> > > +	.macro	mov_64 dest, val
> > > +	mov	\dest, #(((\val) >>  0) & 0xffff)
> > > +	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
> > > +	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
> > > +	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
> > > +	.endm
> > > +  
> > 
> > Trusted Firmware has an (admittedly more complicated) version that only
> > uses as many instructions as needed, by skipping over halfwords that are
> > zero:
> > https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/include/arch/aarch64/asm_macros.S#n125
> > 
> > Does that sound useful for us?  
> 
> For simplicity/clarity, I'd prefer to keep this as-is.
> 
> That and I'm not entirely sure about how the boot-wrapper and TF-A licenses
> interact, so generally I'd strongly prefer to avoid importing code.

Fair enough, I just found the functionality of that TF-A version
particularly neat, though indeed somewhat hard to understand and possibly
over-engineered for us.

Cheers,
Andre

> >   
> > >  	/* Put MPIDR into \dest, clobber \tmp and flags */
> > >  	.macro cpuid dest, tmp
> > >  	mrs	\dest, mpidr_el1
> > > -	ldr	\tmp, =MPIDR_ID_BITS
> > > +	mov_64	\tmp, MPIDR_ID_BITS
> > >  	ands	\dest, \dest, \tmp
> > >  	.endm  
> >   



From andre.przywara at arm.com  Fri Jan 14 07:50:32 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 15:50:32 +0000
Subject: [bootwrapper PATCH v2 05/13] aarch64: add mov_64 macro
In-Reply-To: <20220114105653.3003399-6-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-6-mark.rutland@arm.com>
Message-ID: <20220114155032.2d5bab06@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:45 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> In subsequent patches we'll need to load 64-bit values into GPRs before
> the CPU is in a known endianness, where we cannot use literal pools.
> 
> In preparation for that, this patch adds a new `mov_64` macro to load a
> 64-bit value into a GPR using a sequence of MOV and MOVKs, which will
> function the same regardless of the CPU's endianness.
> 
> At the same time, move the `cpuid` macro to use `mov_64` internally.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Not sure that's worth it, but there is a simpler version of that TF-A
macro, along the lines of:

	.if ((\val) >> 16) & 0xffff
		movk    \dest, #(((\val) >> 16) & 0xffff), lsl #16
	.endif

It's a bit less optimal in a corner case than the TF-A version, but avoids
the few pointless " movk x0, #0x0, lsl #..." I found in the code.

But that's an optimisation detail, so anyway:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch64/common.S | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
> index c7171a9..3279fa9 100644
> --- a/arch/aarch64/common.S
> +++ b/arch/aarch64/common.S
> @@ -9,9 +9,17 @@
>  
>  #include <cpu.h>
>  
> +	/* Load a 64-bit value using immediates */
> +	.macro	mov_64 dest, val
> +	mov	\dest, #(((\val) >>  0) & 0xffff)
> +	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
> +	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
> +	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
> +	.endm
> +
>  	/* Put MPIDR into \dest, clobber \tmp and flags */
>  	.macro cpuid dest, tmp
>  	mrs	\dest, mpidr_el1
> -	ldr	\tmp, =MPIDR_ID_BITS
> +	mov_64	\tmp, MPIDR_ID_BITS
>  	ands	\dest, \dest, \tmp
>  	.endm



From matthias.bgg at gmail.com  Fri Jan 14 08:02:50 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 17:02:50 +0100
Subject: [PATCH v4] drm/mediatek: Fix mtk_cec_mask()
In-Reply-To: <20220103054706.8072-1-miles.chen@mediatek.com>
References: <20220103054706.8072-1-miles.chen@mediatek.com>
Message-ID: <56d0a5d3-65e7-db59-7704-e9868952bb45@gmail.com>



On 03/01/2022 06:47, Miles Chen wrote:
> In current implementation, mtk_cec_mask() writes val into target register
> and ignores the mask. After talking to our hdmi experts, mtk_cec_mask()
> should read a register, clean only mask bits, and update (val | mask) bits
> to the register.
> 
> Fixes: 8f83f26891e1 ("drm/mediatek: Add HDMI support")
> 

Normally there is no new line here.

> Cc: Zhiqiang Lin <zhiqiang.lin at mediatek.com>
> Cc: CK Hu <ck.hu at mediatek.com>
> Cc: Matthias Brugger <matthias.bgg at gmail.com>
> 

Neither here.

> Signed-off-by: Miles Chen <miles.chen at mediatek.com>
> 

But that are nit-picks. I leave it to the maintainer to decide if he want to fix 
that when applying the patch:

Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>

Thanks a lot,
Matthias

> ---
> 
> Change since v1:
> add Fixes tag
> 
> Change since v2:
> add explanation of mtk_cec_mask()
> 
> Change since v3:
> change misleading subject and modify the commit message since this is a bug fix patch
> 
> ---
>   drivers/gpu/drm/mediatek/mtk_cec.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_cec.c b/drivers/gpu/drm/mediatek/mtk_cec.c
> index e9cef5c0c8f7..cdfa648910b2 100644
> --- a/drivers/gpu/drm/mediatek/mtk_cec.c
> +++ b/drivers/gpu/drm/mediatek/mtk_cec.c
> @@ -85,7 +85,7 @@ static void mtk_cec_mask(struct mtk_cec *cec, unsigned int offset,
>   	u32 tmp = readl(cec->regs + offset) & ~mask;
>   
>   	tmp |= val & mask;
> -	writel(val, cec->regs + offset);
> +	writel(tmp, cec->regs + offset);
>   }
>   
>   void mtk_cec_set_hpd_event(struct device *dev,
> 


From robin.murphy at arm.com  Fri Jan 14 08:04:19 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 14 Jan 2022 16:04:19 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <20220114153053.658a5ffa@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-12-mark.rutland@arm.com>
 <20220114153053.658a5ffa@donnerap.cambridge.arm.com>
Message-ID: <f160d7ba-fbd8-8786-9c59-1add009ac5f3@arm.com>

On 2022-01-14 15:30, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:51 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
>> To make it easier to debug boot failures, log the location of memory
>> objects at boot time.
>>
>> This is logged to the serial console as:
>>
>> | Boot-wrapper v0.2
>> | Entered at EL3
>> | Memory layout:
>> | [0000000080000000..0000000080001f90] => boot-wrapper
>> | [000000008000fff8..0000000080010000] => mbox
>> | [0000000080200000..00000000822af200] => kernel
>> | [0000000088000000..0000000088002857] => dtb
>>
>> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
>> ---
>>   common/init.c      | 27 +++++++++++++++++++++++++++
>>   common/platform.c  | 13 +++++++++++++
>>   include/platform.h |  2 ++
>>   model.lds.S        | 20 ++++++++++++++------
>>   4 files changed, 56 insertions(+), 6 deletions(-)
>>
>> diff --git a/common/init.c b/common/init.c
>> index 2600f73..fc74b9e 100644
>> --- a/common/init.c
>> +++ b/common/init.c
>> @@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
>>   	print_string("Boot-wrapper v0.2\r\n");
>>   }
>>   
>> +#define announce_object(object, desc)				\
>> +do {								\
>> +	extern char object##__start[];				\
>> +	extern char object##__end[];				\
>> +	print_string("[");					\
>> +	print_ulong_hex((unsigned long)object##__start);	\
>> +	print_string("..");					\
>> +	print_ulong_hex((unsigned long)object##__end);		\
>> +	print_string("] => " desc "\r\n");			\
>> +} while (0)
>> +
>> +static void announce_objects(void)
>> +{
>> +	print_string("Memory layout:\r\n");
>> +	announce_object(text, "boot-wrapper");
>> +	announce_object(mbox, "mbox");
>> +	announce_object(kernel, "kernel");
>> +#ifdef XEN
>> +	announce_object(xen, "xen");
>> +#endif
>> +	announce_object(dtb, "dtb");
>> +#ifdef USE_INITRD
>> +	announce_object(filesystem, "initrd");
>> +#endif
>> +}
>> +
>>   void announce_arch(void);
>>   
>>   void cpu_init_bootwrapper(void)
>> @@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
>>   		init_uart();
>>   		announce_bootwrapper();
>>   		announce_arch();
>> +		announce_objects();
>>   		print_string("\r\n");
>>   		init_platform();
>>   	}
>> diff --git a/common/platform.c b/common/platform.c
>> index 80d0562..26e5944 100644
>> --- a/common/platform.c
>> +++ b/common/platform.c
>> @@ -52,6 +52,19 @@ void print_string(const char *str)
>>   		print_char(*str++);
>>   }
>>   
>> +#define HEX_CHARS_PER_LONG (2 * sizeof(long))
>> +
>> +void print_ulong_hex(unsigned long val)
>> +{
>> +	const char hex_chars[16] = "0123456789abcdef";
> 
> This breaks the build for me (I guess because of the const?):
> -------------------
> ld --gc-sections arch/aarch64/boot.o arch/aarch64/stack.o arch/aarch64/utils.o arch/aarch64/init.o arch/aarch64/psci.o common/boot.o common/bakery_lock.o common/platform.o common/lib.o common/init.o common/psci.o common/gic-v3.o -o linux-system.axf --script=model.lds
> ld: common/platform.o: in function `print_ulong_hex':
> /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> ld: /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> ld: /src/boot-wrapper-aarch64.git/common/platform.c:66: undefined reference to `__stack_chk_fail'
> /src/boot-wrapper-aarch64.git/common/platform.c:66:(.text.print_ulong_hex+0xa0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `__stack_chk_fail'
> make: *** [Makefile:684: linux-system.axf] Error 1
> ------------------

I got curious and tried a quick test compiling this function in 
isolation, and indeed for some reason GCC (9.3.0 at -O2) seems to end up 
allocating 80 bytes of stack, which is apparently large enough to 
trigger insertion of a stack check, and laboriously copying the string 
from static data into it. FWIW either making hex_chars static const, or 
simply '#define hex_chars "01234567abcdef"', not only avoids a stack 
check but also leads to notably nicer code.

Of course, something like "print_char(v + (v > 9 ? 'a' : '0'));" is best 
of all in terms of code/data, but risks venturing into "too clever" 
territory.

Robin.

> Adding -fno-stack-protector fixes it again.
> 
> I am still checking on each one of those compiler options, shall I send a
> smaller version of that patch 3/9 of mine, meanwhile, just carrying the
> uncontested -ffreestanding and -nostdlib, plus -fno-stack-protector?
> 
> Cheers,
> Andre
> 
>> +	int i;
>> +
>> +	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
>> +		int v = (val >> (4 * i)) & 0xf;
>> +		print_char(hex_chars[v]);
>> +	}
>> +}
>> +
>>   void init_uart(void)
>>   {
>>   	/*
>> diff --git a/include/platform.h b/include/platform.h
>> index 237b481..c88e124 100644
>> --- a/include/platform.h
>> +++ b/include/platform.h
>> @@ -11,6 +11,8 @@
>>   
>>   void print_char(char c);
>>   void print_string(const char *str);
>> +void print_ulong_hex(unsigned long val);
>> +
>>   void init_uart(void);
>>   
>>   void init_platform(void);
>> diff --git a/model.lds.S b/model.lds.S
>> index d4e7e13..dacaa25 100644
>> --- a/model.lds.S
>> +++ b/model.lds.S
>> @@ -35,46 +35,54 @@ SECTIONS
>>   	 * the boot section's *(.data)
>>   	 */
>>   	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
>> -		kernel = .;
>> +		kernel__start = .;
>>   		KERNEL
>> +		kernel__end = .;
>>   	}
>>   
>>   #ifdef XEN
>>   	.xen (PHYS_OFFSET + XEN_OFFSET): {
>> -		xen = .;
>> +		xen__start = .;
>>   		XEN
>> +		xen__end = .;
>>   	}
>>   
>> -	entrypoint = xen;
>> +	entrypoint = xen__start;
>>   #else
>> -	entrypoint = kernel;
>> +	entrypoint = kernel__start;
>>   #endif
>>   
>>   	.dtb (PHYS_OFFSET + FDT_OFFSET): {
>> +		dtb__start = .;
>>   		dtb = .;
>>   		./fdt.dtb
>> +		dtb__end = .;
>>   	}
>>   
>>   #ifdef USE_INITRD
>>   	.filesystem (PHYS_OFFSET + FS_OFFSET): {
>> -		filesystem = .;
>> +		filesystem__start = .;
>>   		FILESYSTEM
>> -		fs_size = . - filesystem;
>> +		filesystem__end = .;
>>   	}
>>   #endif
>>   
>>   	.boot PHYS_OFFSET: {
>> +		text__start = .;
>>   		*(.init)
>>   		*(.text*)
>>   		*(.data* .rodata* .bss* COMMON)
>>   		*(.vectors)
>>   		*(.stack)
>>   		PROVIDE(etext = .);
>> +		text__end = .;
>>   	}
>>   
>>   	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
>> +		mbox__start = .;
>>   		mbox = .;
>>   		QUAD(0x0)
>> +		mbox__end = .;
>>   	}
>>   
>>   	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
> 


From matthias.bgg at gmail.com  Fri Jan 14 08:08:13 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 17:08:13 +0100
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186
 SoC
In-Reply-To: <20220107104633.7500-2-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
Message-ID: <58601613-9aac-97ef-265f-fb27e5d6b2e4@gmail.com>

Hi Johnson,

It looks like my review from a few minutes got lost, so here again:

On 07/01/2022 11:46, Johnson Wang wrote:
> MT8186 are highly integrated SoC and use PMIC_MT6366 for
> power management. This patch adds pwrap master driver to
> access PMIC_MT6366.
> 
> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>   drivers/soc/mediatek/mtk-pmic-wrap.c | 72 ++++++++++++++++++++++++++++
>   1 file changed, 72 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
> index 952bc554f443..78866ebf7f04 100644
> --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> @@ -30,6 +30,7 @@
>   #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) & 0x00000001)
>   #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
>   #define PWRAP_STATE_INIT_DONE0		BIT(21)
> +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)

This name is rather strange. Is the reason that the datasheet names it like this?

>   #define PWRAP_STATE_INIT_DONE1		BIT(15)
>   
>   /* macro for WACS FSM */
> @@ -77,6 +78,8 @@
>   #define PWRAP_CAP_INT1_EN	BIT(3)
>   #define PWRAP_CAP_WDT_SRC1	BIT(4)
>   #define PWRAP_CAP_ARB		BIT(5)
> +#define PWRAP_CAP_MONITOR_V2	BIT(6)

Not used capability, please drop.

Regards,
Matthias

> +#define PWRAP_CAP_ARB_V2	BIT(8)
>   
>   /* defines for slave device wrapper registers */
>   enum dew_regs {
> @@ -1063,6 +1066,55 @@ static int mt8516_regs[] = {
>   	[PWRAP_MSB_FIRST] =		0x170,
>   };
>   
> +static int mt8186_regs[] = {
> +	[PWRAP_MUX_SEL] =		0x0,
> +	[PWRAP_WRAP_EN] =		0x4,
> +	[PWRAP_DIO_EN] =		0x8,
> +	[PWRAP_RDDMY] =			0x20,
> +	[PWRAP_CSHEXT_WRITE] =		0x24,
> +	[PWRAP_CSHEXT_READ] =		0x28,
> +	[PWRAP_CSLEXT_WRITE] =		0x2C,
> +	[PWRAP_CSLEXT_READ] =		0x30,
> +	[PWRAP_EXT_CK_WRITE] =		0x34,
> +	[PWRAP_STAUPD_CTRL] =		0x3C,
> +	[PWRAP_STAUPD_GRPEN] =		0x40,
> +	[PWRAP_EINT_STA0_ADR] =		0x44,
> +	[PWRAP_EINT_STA1_ADR] =		0x48,
> +	[PWRAP_INT_CLR] =		0xC8,
> +	[PWRAP_INT_FLG] =		0xC4,
> +	[PWRAP_MAN_EN] =		0x7C,
> +	[PWRAP_MAN_CMD] =		0x80,
> +	[PWRAP_WACS0_EN] =		0x8C,
> +	[PWRAP_WACS1_EN] =		0x94,
> +	[PWRAP_WACS2_EN] =		0x9C,
> +	[PWRAP_INIT_DONE0] =		0x90,
> +	[PWRAP_INIT_DONE1] =		0x98,
> +	[PWRAP_INIT_DONE2] =		0xA0,
> +	[PWRAP_INT_EN] =		0xBC,
> +	[PWRAP_INT1_EN] =		0xCC,
> +	[PWRAP_INT1_FLG] =		0xD4,
> +	[PWRAP_INT1_CLR] =		0xD8,
> +	[PWRAP_TIMER_EN] =		0xF0,
> +	[PWRAP_WDT_UNIT] =		0xF8,
> +	[PWRAP_WDT_SRC_EN] =		0xFC,
> +	[PWRAP_WDT_SRC_EN_1] =		0x100,
> +	[PWRAP_WDT_FLG] =		0x104,
> +	[PWRAP_SPMINF_STA] =		0x1B4,
> +	[PWRAP_DCM_EN] =		0x1EC,
> +	[PWRAP_DCM_DBC_PRD] =		0x1F0,
> +	[PWRAP_GPSINF_0_STA] =		0x204,
> +	[PWRAP_GPSINF_1_STA] =		0x208,
> +	[PWRAP_WACS0_CMD] =		0xC00,
> +	[PWRAP_WACS0_RDATA] =		0xC04,
> +	[PWRAP_WACS0_VLDCLR] =		0xC08,
> +	[PWRAP_WACS1_CMD] =		0xC10,
> +	[PWRAP_WACS1_RDATA] =		0xC14,
> +	[PWRAP_WACS1_VLDCLR] =		0xC18,
> +	[PWRAP_WACS2_CMD] =		0xC20,
> +	[PWRAP_WACS2_RDATA] =		0xC24,
> +	[PWRAP_WACS2_VLDCLR] =		0xC28,
> +};
> +
>   enum pmic_type {
>   	PMIC_MT6323,
>   	PMIC_MT6351,
> @@ -1083,6 +1135,7 @@ enum pwrap_type {
>   	PWRAP_MT8135,
>   	PWRAP_MT8173,
>   	PWRAP_MT8183,
> +	PWRAP_MT8186,
>   	PWRAP_MT8195,
>   	PWRAP_MT8516,
>   };
> @@ -1535,6 +1588,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp)
>   	case PWRAP_MT6779:
>   	case PWRAP_MT6797:
>   	case PWRAP_MT8173:
> +	case PWRAP_MT8186:
>   	case PWRAP_MT8516:
>   		pwrap_writel(wrp, 1, PWRAP_CIPHER_EN);
>   		break;
> @@ -2069,6 +2123,19 @@ static struct pmic_wrapper_type pwrap_mt8516 = {
>   	.init_soc_specific = NULL,
>   };
>   
> +static struct pmic_wrapper_type pwrap_mt8186 = {
> +	.regs = mt8186_regs,
> +	.type = PWRAP_MT8186,
> +	.arb_en_all = 0xfb27f,
> +	.int_en_all = 0xfffffffe, /* disable WatchDog Timeout for bit 1 */
> +	.int1_en_all =  0x000017ff, /* disable Matching interrupt for bit 13 */
> +	.spi_w = PWRAP_MAN_CMD_SPI_WRITE,
> +	.wdt_src = PWRAP_WDT_SRC_MASK_ALL,
> +	.caps = PWRAP_CAP_INT1_EN | PWRAP_CAP_MONITOR_V2 | PWRAP_CAP_ARB_V2,
> +	.init_reg_clock = pwrap_common_init_reg_clock,
> +	.init_soc_specific = NULL,
> +};
> +
>   static const struct of_device_id of_pwrap_match_tbl[] = {
>   	{
>   		.compatible = "mediatek,mt2701-pwrap",
> @@ -2097,6 +2164,9 @@ static const struct of_device_id of_pwrap_match_tbl[] = {
>   	}, {
>   		.compatible = "mediatek,mt8183-pwrap",
>   		.data = &pwrap_mt8183,
> +	}, {
> +		.compatible = "mediatek,mt8186-pwrap",
> +		.data = &pwrap_mt8186,
>   	}, {
>   		.compatible = "mediatek,mt8195-pwrap",
>   		.data = &pwrap_mt8195,
> @@ -2209,6 +2279,8 @@ static int pwrap_probe(struct platform_device *pdev)
>   
>   	if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB))
>   		mask_done = PWRAP_STATE_INIT_DONE1;
> +	else if (HAS_CAP(wrp->master->caps, PWRAP_CAP_ARB_V2))
> +		mask_done = PWRAP_STATE_INIT_DONE0_V2;
>   	else
>   		mask_done = PWRAP_STATE_INIT_DONE0;
>   
> 


From semen.protsenko at linaro.org  Fri Jan 14 08:13:27 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:13:27 +0200
Subject: [PATCH v3 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220112100046.68068-5-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-5-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4mRY7diuP8Ts_pnY6M0TeK9OmxPe+fh_K0YBBzvitRNbw@mail.gmail.com>

On Wed, 12 Jan 2022 at 12:00, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The Samsung SoC SPI driver requires to provide controller-data node
> for each of SPI peripheral device nodes.  Make this controller-data node
> optional, so DTS could be simpler.
>
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  drivers/spi/spi-s3c64xx.c | 14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 8755cd85e83c..769d958a2f86 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
>                 return ERR_PTR(-EINVAL);
>         }
>
> -       data_np = of_get_child_by_name(slave_np, "controller-data");
> -       if (!data_np) {
> -               dev_err(&spi->dev, "child node 'controller-data' not found\n");
> -               return ERR_PTR(-EINVAL);
> -       }
> -
>         cs = kzalloc(sizeof(*cs), GFP_KERNEL);
> -       if (!cs) {
> -               of_node_put(data_np);
> +       if (!cs)
>                 return ERR_PTR(-ENOMEM);
> +
> +       data_np = of_get_child_by_name(slave_np, "controller-data");
> +       if (!data_np) {
> +               dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");
> +               return cs;
>         }
>
>         of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
> --
> 2.32.0
>


From mark.rutland at arm.com  Fri Jan 14 08:21:11 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 16:21:11 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <20220114153053.658a5ffa@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-12-mark.rutland@arm.com>
 <20220114153053.658a5ffa@donnerap.cambridge.arm.com>
Message-ID: <YeGi9yAAWEaoieWU@FVFF77S0Q05N>

On Fri, Jan 14, 2022 at 03:30:53PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:51 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> > To make it easier to debug boot failures, log the location of memory
> > objects at boot time.
> > 
> > This is logged to the serial console as:
> > 
> > | Boot-wrapper v0.2
> > | Entered at EL3
> > | Memory layout:
> > | [0000000080000000..0000000080001f90] => boot-wrapper
> > | [000000008000fff8..0000000080010000] => mbox
> > | [0000000080200000..00000000822af200] => kernel
> > | [0000000088000000..0000000088002857] => dtb
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---

> > +void print_ulong_hex(unsigned long val)
> > +{
> > +	const char hex_chars[16] = "0123456789abcdef";
> 
> This breaks the build for me (I guess because of the const?):
> -------------------
> ld --gc-sections arch/aarch64/boot.o arch/aarch64/stack.o arch/aarch64/utils.o arch/aarch64/init.o arch/aarch64/psci.o common/boot.o common/bakery_lock.o common/platform.o common/lib.o common/init.o common/psci.o common/gic-v3.o -o linux-system.axf --script=model.lds
> ld: common/platform.o: in function `print_ulong_hex':
> /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> ld: /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> ld: /src/boot-wrapper-aarch64.git/common/platform.c:66: undefined reference to `__stack_chk_fail'
> /src/boot-wrapper-aarch64.git/common/platform.c:66:(.text.print_ulong_hex+0xa0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `__stack_chk_fail'
> make: *** [Makefile:684: linux-system.axf] Error 1
> ------------------
> 
> Adding -fno-stack-protector fixes it again.
> 
> I am still checking on each one of those compiler options, shall I send a
> smaller version of that patch 3/9 of mine, meanwhile, just carrying the
> uncontested -ffreestanding and -nostdlib, plus -fno-stack-protector?

Yes please!

Thanks,
Mark.


From kuba at kernel.org  Fri Jan 14 08:23:08 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 14 Jan 2022 08:23:08 -0800
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <CAAd53p6rW7PcugY7okKsXybK2O=pS8qAhctMzsa-MEgJrKhEdg@mail.gmail.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
 <20220113203523.310e13d3@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
 <CAAd53p6rW7PcugY7okKsXybK2O=pS8qAhctMzsa-MEgJrKhEdg@mail.gmail.com>
Message-ID: <20220114082308.76a5cca5@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Fri, 14 Jan 2022 14:47:47 +0800 Kai-Heng Feng wrote:
> > Coincidentally the first Marvell flag appears dead, nobody sets it:
> >
> > $ git grep MARVELL_PHY_M1145_FLAGS_RESISTANCE
> > drivers/net/phy/marvell.c:      if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
> > include/linux/marvell_phy.h:#define MARVELL_PHY_M1145_FLAGS_RESISTANCE  0x00000001
> > $
> >
> > unless it's read from DT under different name or something.  
> 
> It was introduced by 95d21ff4c645 without any user. Should we keep it?

Not unless someone explains that it's actually used somehow.

Please post a patch once net-next opens.


From stefan.wahren at i2se.com  Fri Jan 14 08:24:02 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Fri, 14 Jan 2022 17:24:02 +0100
Subject: [PATCH v1 05/14] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <0d9e38ad27cf0bebc73e104d8ea462e7cf319e40.camel@toradex.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-6-marcel@ziswiler.com>
 <06d3ff4c-3c82-1b04-3dc7-3a6effe4cc3e@i2se.com>
 <0d9e38ad27cf0bebc73e104d8ea462e7cf319e40.camel@toradex.com>
Message-ID: <d2666a27-a420-5808-6b78-ae77468dae3d@i2se.com>

Hi Marcel,

Am 14.01.22 um 14:39 schrieb Marcel Ziswiler:
> Hi Stefan
>
> On Thu, 2022-01-13 at 19:42 +0100, Stefan Wahren wrote:
>> Hi Marcel,
>>
>> Am 07.01.22 um 19:03 schrieb Marcel Ziswiler:
>>> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>>
>>> This avoids firmware load error and sysfs fallback reported as follows:
>>>
>>> [??? 0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
>>> ?for imx/sdma/sdma-imx7d.bin failed with error -2
>>> [??? 0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
>>> ?fallback for: imx/sdma/sdma-imx7d.bin
>> unfortunately this isn't an explanation why this solve the issue. It
>> looks like that the SDMA firmware is not available for the kernel. Build
>> the driver as a module hide the issue and just load it if the rootfs is
>> available.
> Well, it seems to default to some built-in firmware which, unfortunately, might have some severe known errata
> anyway.
can you please explain what you mean with built-in firmware? AFAIK there
is a firmware in the SoC ROM, but there is also the option to append
firmware files to the kernel image (regardless of initramfs and so on).
For instance the NXP vendor kernel of the i.MX6ULL (uses the same driver
with a different firmware file) appended the necessary firmware per
default. But yes, the external firmware should be preferred.
>
>> What makes you sure that the driver is not critical for other boards
>> during boot?
> That is a good question. I remember that there was some more discussion back when I proposed the same change
> for imx_v6_v7_defconfig in the 32-bit Arm world. While nobody was able to fully answer it all it did get
> accepted by the i.MX maintainer back in the day [1]. I will mention that in v2.

Okay, in this case the change should be fine.

Thanks

>
> [1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/
>
> Thanks for your review.
>
>> Best regards
>>
>>> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>> ---
>>>
>>> ?arch/arm64/configs/defconfig | 2 +-
>>> ?1 file changed, 1 insertion(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
>>> index 3c8106c5776a..a18785a827dc 100644
>>> --- a/arch/arm64/configs/defconfig
>>> +++ b/arch/arm64/configs/defconfig
>>> @@ -915,7 +915,7 @@ CONFIG_DMADEVICES=y
>>> ?CONFIG_DMA_BCM2835=y
>>> ?CONFIG_DMA_SUN6I=m
>>> ?CONFIG_FSL_EDMA=y
>>> -CONFIG_IMX_SDMA=y
>>> +CONFIG_IMX_SDMA=m
>>> ?CONFIG_K3_DMA=y
>>> ?CONFIG_MV_XOR=y
>>> ?CONFIG_MV_XOR_V2=y
> Cheers
>
> Marcel
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From piotr.oniszczuk at gmail.com  Fri Jan 14 08:25:35 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Fri, 14 Jan 2022 17:25:35 +0100
Subject: [PATCH 4/4] arm64: dts: rockchip: Enable the GPU on Quartz64
 Model A
In-Reply-To: <20211126151729.1026566-5-knaerzche@gmail.com>
References: <20211126151729.1026566-1-knaerzche@gmail.com>
 <20211126151729.1026566-5-knaerzche@gmail.com>
Message-ID: <EB2E04F1-BACA-4A4F-97F9-0257F29D57B5@gmail.com>



> Wiadomo?? napisana przez Alex Bee <knaerzche at gmail.com> w dniu 26.11.2021, o godz. 16:17:
> 
> From: Ezequiel Garcia <ezequiel at collabora.com>
> 
> Enable the GPU core on the Pine64 Quartz64 Model A.
> 
> Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
> Signed-off-by: Alex Bee <knaerzche at gmail.com>
> ---
> arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 5 +++++
> 1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> index 4d4b2a301b1a..625489c60622 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> @@ -205,6 +205,11 @@ &gmac1m0_clkinout
> 	status = "okay";
> };
> 
> +&gpu {
> +	mali-supply = <&vdd_gpu>;
> +	status = "okay";
> +};
> +
> &i2c0 {
> 	status = "okay";
> 
> -- 
> 

Alex, Ezequiel

I'm playing with 5.16 mainline on rk3566 based tvbox (x96-x6)

Box boots and I have working SD card, Eth, HDMI.

I applied this series as I want to get GPU working but I'm getting:

[    3.169144] panfrost fde60000.gpu: get clock failed -517
[    3.169646] panfrost fde60000.gpu: clk init failed -517
[    3.213653] panfrost fde60000.gpu: get clock failed -517
[    3.214156] panfrost fde60000.gpu: clk init failed -517
[    3.230505] panfrost fde60000.gpu: get clock failed -517
[    3.231006] panfrost fde60000.gpu: clk init failed -517
[    3.258072] panfrost fde60000.gpu: get clock failed -517
[    3.258575] panfrost fde60000.gpu: clk init failed -517

Maybe you have some hints here?




From marcel.ziswiler at toradex.com  Fri Jan 14 08:30:44 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Fri, 14 Jan 2022 16:30:44 +0000
Subject: [PATCH v1 05/14] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <d2666a27-a420-5808-6b78-ae77468dae3d@i2se.com>
References: <20220107180314.1816515-1-marcel@ziswiler.com>
 <20220107180314.1816515-6-marcel@ziswiler.com>
 <06d3ff4c-3c82-1b04-3dc7-3a6effe4cc3e@i2se.com>
 <0d9e38ad27cf0bebc73e104d8ea462e7cf319e40.camel@toradex.com>
 <d2666a27-a420-5808-6b78-ae77468dae3d@i2se.com>
Message-ID: <13b010060c0b182d7a2c2c09e74805503e6093ee.camel@toradex.com>

Hi Stefan

On Fri, 2022-01-14 at 17:24 +0100, Stefan Wahren wrote:
> Hi Marcel,
> 
> Am 14.01.22 um 14:39 schrieb Marcel Ziswiler:
> > Hi Stefan
> > 
> > On Thu, 2022-01-13 at 19:42 +0100, Stefan Wahren wrote:
> > > Hi Marcel,
> > > 
> > > Am 07.01.22 um 19:03 schrieb Marcel Ziswiler:
> > > > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > > > 
> > > > This avoids firmware load error and sysfs fallback reported as follows:
> > > > 
> > > > [??? 0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
> > > > ?for imx/sdma/sdma-imx7d.bin failed with error -2
> > > > [??? 0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
> > > > ?fallback for: imx/sdma/sdma-imx7d.bin
> > > unfortunately this isn't an explanation why this solve the issue. It
> > > looks like that the SDMA firmware is not available for the kernel. Build
> > > the driver as a module hide the issue and just load it if the rootfs is
> > > available.
> > Well, it seems to default to some built-in firmware which, unfortunately, might have some severe known
> > errata
> > anyway.
> can you please explain what you mean with built-in firmware? AFAIK there
> is a firmware in the SoC ROM, but there is also the option to append
> firmware files to the kernel image (regardless of initramfs and so on).

Yes, sorry. I should have worded it differently. I really meant the one that comes with the SoC ROM.

And yes, it may be appended to the kernel image but that would require changes to how one goes about building
it which, at that time, one could simply also change that configuration.

However, for a generic case, like I assume this defconfig is supposed to be used, having it as a module seems
much more straight forward.

> For instance the NXP vendor kernel of the i.MX6ULL (uses the same driver
> with a different firmware file) appended the necessary firmware per
> default.

Yes, we know all about those "great" vendor kernels ;-p.

> But yes, the external firmware should be preferred.
> > 
> > > What makes you sure that the driver is not critical for other boards
> > > during boot?
> > That is a good question. I remember that there was some more discussion back when I proposed the same
> > change
> > for imx_v6_v7_defconfig in the 32-bit Arm world. While nobody was able to fully answer it all it did get
> > accepted by the i.MX maintainer back in the day [1]. I will mention that in v2.
> 
> Okay, in this case the change should be fine.
> 
> Thanks

Thank you.

> > [1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/
> > 
> > Thanks for your review.
> > 
> > > Best regards
> > > 
> > > > Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > > > ---
> > > > 
> > > > ?arch/arm64/configs/defconfig | 2 +-
> > > > ?1 file changed, 1 insertion(+), 1 deletion(-)
> > > > 
> > > > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > > > index 3c8106c5776a..a18785a827dc 100644
> > > > --- a/arch/arm64/configs/defconfig
> > > > +++ b/arch/arm64/configs/defconfig
> > > > @@ -915,7 +915,7 @@ CONFIG_DMADEVICES=y
> > > > ?CONFIG_DMA_BCM2835=y
> > > > ?CONFIG_DMA_SUN6I=m
> > > > ?CONFIG_FSL_EDMA=y
> > > > -CONFIG_IMX_SDMA=y
> > > > +CONFIG_IMX_SDMA=m
> > > > ?CONFIG_K3_DMA=y
> > > > ?CONFIG_MV_XOR=y
> > > > ?CONFIG_MV_XOR_V2=y
> > Cheers
> > 
> > Marcel
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Cheers

Marcel

From mark.rutland at arm.com  Fri Jan 14 08:30:47 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 14 Jan 2022 16:30:47 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <f160d7ba-fbd8-8786-9c59-1add009ac5f3@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-12-mark.rutland@arm.com>
 <20220114153053.658a5ffa@donnerap.cambridge.arm.com>
 <f160d7ba-fbd8-8786-9c59-1add009ac5f3@arm.com>
Message-ID: <YeGlN6SwomrURO46@FVFF77S0Q05N>

On Fri, Jan 14, 2022 at 04:04:19PM +0000, Robin Murphy wrote:
> On 2022-01-14 15:30, Andre Przywara wrote:
> > On Fri, 14 Jan 2022 10:56:51 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > > +void print_ulong_hex(unsigned long val)
> > > +{
> > > +	const char hex_chars[16] = "0123456789abcdef";
> > 
> > This breaks the build for me (I guess because of the const?):
> > -------------------
> > ld --gc-sections arch/aarch64/boot.o arch/aarch64/stack.o arch/aarch64/utils.o arch/aarch64/init.o arch/aarch64/psci.o common/boot.o common/bakery_lock.o common/platform.o common/lib.o common/init.o common/psci.o common/gic-v3.o -o linux-system.axf --script=model.lds
> > ld: common/platform.o: in function `print_ulong_hex':
> > /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> > ld: /src/boot-wrapper-aarch64.git/common/platform.c:58: undefined reference to `__stack_chk_guard'
> > ld: /src/boot-wrapper-aarch64.git/common/platform.c:66: undefined reference to `__stack_chk_fail'
> > /src/boot-wrapper-aarch64.git/common/platform.c:66:(.text.print_ulong_hex+0xa0): relocation truncated to fit: R_AARCH64_CALL26 against undefined symbol `__stack_chk_fail'
> > make: *** [Makefile:684: linux-system.axf] Error 1
> > ------------------
> 
> I got curious and tried a quick test compiling this function in isolation,
> and indeed for some reason GCC (9.3.0 at -O2) seems to end up allocating 80
> bytes of stack, which is apparently large enough to trigger insertion of a
> stack check, and laboriously copying the string from static data into it.
> FWIW either making hex_chars static const, or simply '#define hex_chars
> "01234567abcdef"', not only avoids a stack check but also leads to notably
> nicer code.

For the stack check, I think Andre's patch to add -fno-stack-protector is the
correct fix, so I'd like to take that as a prerequisite.

To avoid using the stack unnecessarily and to make the code nicer, I'll also
take your suggestion with the fixup below.

Thanks,
Mark.

---->8----
-#define HEX_CHARS_PER_LONG (2 * sizeof(long))
+#define HEX_CHARS_PER_LONG     (2 * sizeof(long))
+#define HEX_CHARS              "0123456789abcdef"
 
 void print_ulong_hex(unsigned long val)
 {
-       const char hex_chars[16] = "0123456789abcdef";
        int i;
 
        for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
                int v = (val >> (4 * i)) & 0xf;
-               print_char(hex_chars[v]);
+               print_char(HEX_CHARS[v]);
        }
 }


From semen.protsenko at linaro.org  Fri Jan 14 08:31:11 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:31:11 +0200
Subject: [PATCH v2 28/28] arm64: dts: exynos: use dedicated wake-up
 pinctrl compatible in ExynosAutov9
In-Reply-To: <20220111201722.327219-22-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-22-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4=t0z-aMhCSp4K3L8EqH_BzinsLuRcopbCQr_xzgFCYVA@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:19, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
> Exynos5, Exynos5433) with external wake-up interrupts, expected to have
> one interrupt for multiplexing these wake-up interrupts.  Also they
> expected to have exactly one pin controller capable of external wake-up
> interrupts.
>
> It seems however that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences:
> 1. No multiplexed external wake-up interrupt, only direct,
> 2. More than one pin controller capable of external wake-up interrupts.
>
> Use dedicated ExynosAutov9 compatible for its external wake-up interrupts
> controller to indicate the differences.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  arch/arm64/boot/dts/exynos/exynosautov9.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
> index de8fcb82eaec..807d500d6022 100644
> --- a/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynosautov9.dtsi
> @@ -208,7 +208,7 @@ pinctrl_alive: pinctrl at 10450000 {
>                         reg = <0x10450000 0x1000>;
>
>                         wakeup-interrupt-controller {
> -                               compatible = "samsung,exynos7-wakeup-eint";
> +                               compatible = "samsung,exynosautov9-wakeup-eint";
>                         };
>                 };
>
> --
> 2.32.0
>


From conleylee at foxmail.com  Fri Jan 14 08:31:47 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Sat, 15 Jan 2022 00:31:47 +0800
Subject: [PATCH v4 1/2] arm: dts: sun7i: Add A20-Marsboard
In-Reply-To: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
Message-ID: <tencent_C2E26D0935C9157CB3597BA4BD3316E8940A@qq.com>

The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.

Signed-off-by: Conley Lee <conleylee at foxmail.com>
---
Change since v1.
  - Spearate biddings and dts as two patches.
  - use SPDX tag

Change since v2.
  - reformat patch
  - dual-license with GPL and MIT
  - rename dts filename to sun7i-a20-haoyu-marsboard.dts
Change since v3.
  - reformat patch
  - order dtb alphabetically
  - add gmac_txerr node and remove gmac_mii_pins node in
    sun7i-a20-marsboard.dts
---
 arch/arm/boot/dts/Makefile                    |   1 +
 .../boot/dts/sun7i-a20-haoyu-marsboard.dts    | 183 ++++++++++++++++++
 2 files changed, 184 insertions(+)
 create mode 100644 arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..1850ff7c9006 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1213,6 +1213,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \
 	sun7i-a20-bananapro.dtb \
 	sun7i-a20-cubieboard2.dtb \
 	sun7i-a20-cubietruck.dtb \
+	sun7i-a20-haoyu-marsboard.dtb \
 	sun7i-a20-hummingbird.dtb \
 	sun7i-a20-itead-ibox.dtb \
 	sun7i-a20-i12-tvbox.dtb \
diff --git a/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
new file mode 100644
index 000000000000..056dbc415de7
--- /dev/null
+++ b/arch/arm/boot/dts/sun7i-a20-haoyu-marsboard.dts
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Conley Lee
+ * Conley Lee <conleylee at foxmail.com>
+ */
+
+/dts-v1/;
+#include "sun7i-a20.dtsi"
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+	model = "HAOYU Electronics Marsboard A20";
+	compatible = "haoyu,a20-marsboard", "allwinner,sun7i-a20";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+};
+
+&ahci {
+	target-supply = <&reg_ahci_5v>;
+	status = "okay";
+};
+
+&codec {
+	status = "okay";
+};
+
+&cpu0 {
+	cpu-supply = <&reg_dcdc2>;
+};
+
+&de {
+	status = "okay";
+};
+
+&ehci0 {
+	status = "okay";
+};
+
+&ehci1 {
+	status = "okay";
+};
+
+&gmac {
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac_mii_pins>, <&gmac_txerr>;
+	phy-handle = <&phy0>;
+	phy-mode = "mii";
+	status = "okay";
+};
+
+&hdmi {
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&i2c0 {
+	status = "okay";
+
+	axp209: pmic at 34 {
+		reg = <0x34>;
+		interrupt-parent = <&nmi_intc>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+	};
+};
+
+&mmc0 {
+	vmmc-supply = <&reg_vcc3v3>;
+	bus-width = <4>;
+	cd-gpios = <&pio 7 10 GPIO_ACTIVE_LOW>; /* PH10 */
+	status = "okay";
+};
+
+&gmac_mdio {
+	phy0: ethernet-phy at 0 {
+		reg = <0>;
+	};
+};
+
+&ohci0 {
+	status = "okay";
+};
+
+&ohci1 {
+	status = "okay";
+};
+
+&otg_sram {
+	status = "okay";
+};
+
+&pio {
+	gmac_txerr: gmac-txerr-pin {
+		pins = "PA17";
+		function = "gmac";
+	};
+};
+
+
+&reg_ahci_5v {
+	status = "okay";
+};
+
+#include "axp209.dtsi"
+
+&ac_power_supply {
+	status = "okay";
+};
+
+&reg_dcdc2 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1450000>;
+	regulator-name = "vdd-cpu";
+};
+
+&reg_dcdc3 {
+	regulator-always-on;
+	regulator-min-microvolt = <1000000>;
+	regulator-max-microvolt = <1400000>;
+	regulator-name = "vdd-int-dll";
+};
+
+&reg_ldo1 {
+	regulator-name = "vdd-rtc";
+};
+
+&reg_ldo2 {
+	regulator-always-on;
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+	regulator-name = "avcc";
+};
+
+&reg_usb1_vbus {
+	status = "okay";
+};
+
+&reg_usb2_vbus {
+	status = "okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pb_pins>;
+	status = "okay";
+};
+
+&usb_otg {
+	dr_mode = "otg";
+	status = "okay";
+};
+
+&usbphy {
+	usb0_id_det-gpios = <&pio 7 4 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PH4 */
+	usb1_vbus-supply = <&reg_usb1_vbus>;
+	usb2_vbus-supply = <&reg_usb2_vbus>;
+	status = "okay";
+};
-- 
2.31.1



From conleylee at foxmail.com  Fri Jan 14 08:31:48 2022
From: conleylee at foxmail.com (Conley Lee)
Date: Sat, 15 Jan 2022 00:31:48 +0800
Subject: [PATCH v4 2/2] dt-bindings: arm: sunxi: add haoyu,a20-marsboard
In-Reply-To: <20220114163148.2854265-1-conleylee@foxmail.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220114163148.2854265-1-conleylee@foxmail.com>
Message-ID: <tencent_B6059C6C031E46EFCB05D5A5015B1C4DE608@qq.com>

From: conley <conleylee at foxmail.com>

add haoyu,a20-marsboard dt-bindings

Signed-off-by: conley <conleylee at foxmail.com>
---
 Documentation/devicetree/bindings/arm/sunxi.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml
index 889128acf49a..4bd93ae26bd1 100644
--- a/Documentation/devicetree/bindings/arm/sunxi.yaml
+++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -444,6 +444,11 @@ properties:
           - const: haoyu,a10-marsboard
           - const: allwinner,sun4i-a10
 
+      - description: HAOYU Electronics Marsboard A20
+        items:
+          - const: haoyu,a20-marsboard
+          - const: allwinner,sun7i-a20
+
       - description: MapleBoard MP130
         items:
           - const: mapleboard,mp130
-- 
2.31.1



From semen.protsenko at linaro.org  Fri Jan 14 08:38:37 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:38:37 +0200
Subject: [PATCH v2 01/28] pinctrl: samsung: drop pin banks references on
 error paths
In-Reply-To: <20220111201426.326777-2-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201426.326777-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4k18Gz8-CEX_YjgS9tOxMq8xHk9GaUvfHWnPXkOnkinqw@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:15, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The driver iterates over its devicetree children with
> for_each_child_of_node() and stores for later found node pointer.  This
> has to be put in error paths to avoid leak during re-probing.
>
> Fixes: ab663789d697 ("pinctrl: samsung: Match pin banks with their device nodes")
> Cc: <stable at vger.kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  drivers/pinctrl/samsung/pinctrl-samsung.c | 30 +++++++++++++++++------
>  1 file changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index 8941f658e7f1..b19ebc43d886 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1002,6 +1002,16 @@ samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)
>         return &(of_data->ctrl[id]);
>  }
>
> +static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
> +{
> +       struct samsung_pin_bank *bank;
> +       unsigned int i;
> +
> +       bank = d->pin_banks;
> +       for (i = 0; i < d->nr_banks; ++i, ++bank)
> +               of_node_put(bank->of_node);
> +}
> +
>  /* retrieve the soc specific data */
>  static const struct samsung_pin_ctrl *
>  samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
> @@ -1116,19 +1126,19 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
>         if (ctrl->retention_data) {
>                 drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,
>                                                           ctrl->retention_data);
> -               if (IS_ERR(drvdata->retention_ctrl))
> -                       return PTR_ERR(drvdata->retention_ctrl);
> +               if (IS_ERR(drvdata->retention_ctrl)) {
> +                       ret = PTR_ERR(drvdata->retention_ctrl);
> +                       goto err_put_banks;
> +               }
>         }
>
>         ret = samsung_pinctrl_register(pdev, drvdata);
>         if (ret)
> -               return ret;
> +               goto err_put_banks;
>
>         ret = samsung_gpiolib_register(pdev, drvdata);
> -       if (ret) {
> -               samsung_pinctrl_unregister(pdev, drvdata);
> -               return ret;
> -       }
> +       if (ret)
> +               goto err_unregister;
>
>         if (ctrl->eint_gpio_init)
>                 ctrl->eint_gpio_init(drvdata);
> @@ -1138,6 +1148,12 @@ static int samsung_pinctrl_probe(struct platform_device *pdev)
>         platform_set_drvdata(pdev, drvdata);
>
>         return 0;
> +
> +err_unregister:
> +       samsung_pinctrl_unregister(pdev, drvdata);
> +err_put_banks:
> +       samsung_banks_of_node_put(drvdata);
> +       return ret;
>  }
>
>  /*
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Fri Jan 14 08:39:13 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:39:13 +0200
Subject: [PATCH v2 26/28] pinctrl: samsung: add support for Exynos850 and
 ExynosAutov9 wake-ups
In-Reply-To: <20220111201722.327219-20-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-20-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4k3Pypn6t-hHVtxg216oj=LMtchdRtsJmKBANN639oRgQ@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:18, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> It seems that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences of their pin controller node capable of
> external wake-up interrupts:
> 1. No multiplexed external wake-up interrupt, only direct,
> 2. More than one pin controller capable of external wake-up interrupts.
>
> Add support for dedicated Exynos850 and ExynosAutov9 compatibles.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  drivers/pinctrl/samsung/pinctrl-exynos.c | 4 ++++
>  1 file changed, 4 insertions(+)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
> index 0489c899b401..a158d587814e 100644
> --- a/drivers/pinctrl/samsung/pinctrl-exynos.c
> +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
> @@ -465,6 +465,10 @@ static const struct of_device_id exynos_wkup_irq_ids[] = {
>                         .data = &exynos4210_wkup_irq_chip },
>         { .compatible = "samsung,exynos7-wakeup-eint",
>                         .data = &exynos7_wkup_irq_chip },
> +       { .compatible = "samsung,exynos850-wakeup-eint",
> +                       .data = &exynos7_wkup_irq_chip },
> +       { .compatible = "samsung,exynosautov9-wakeup-eint",
> +                       .data = &exynos7_wkup_irq_chip },
>         { }
>  };
>
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Fri Jan 14 08:40:15 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:40:15 +0200
Subject: [PATCH v2 20/28] arm64: dts: exynos: align pinctrl with dtschema
 in ExynosAutov9
In-Reply-To: <20220111201722.327219-14-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-14-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4ny15Jf4+6vFaTUa2thc5cHyHQtC9pyzspwO7Vahi30Hw@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:18, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the pin controller related nodes with dtschema.  No functional
> change expected.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  .../boot/dts/exynos/exynosautov9-pinctrl.dtsi | 50 +++++++++----------
>  1 file changed, 25 insertions(+), 25 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
> index 2407b03b5404..ef0349d1c3d0 100644
> --- a/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynosautov9-pinctrl.dtsi
> @@ -11,7 +11,7 @@
>  #include <dt-bindings/pinctrl/samsung.h>
>
>  &pinctrl_alive {
> -       gpa0: gpa0 {
> +       gpa0: gpa0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>                 interrupt-controller;
> @@ -27,7 +27,7 @@ gpa0: gpa0 {
>                              <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa1: gpa1 {
> +       gpa1: gpa1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>                 interrupt-controller;
> @@ -47,7 +47,7 @@ dp1_hpd: dp1-hpd-pins {
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>         };
>
> -       gpq0: gpq0 {
> +       gpq0: gpq0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -69,7 +69,7 @@ speedy1_bus: speedy1-bus-pins {
>  };
>
>  &pinctrl_aud {
> -       gpb0: gpb0 {
> +       gpb0: gpb0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -77,7 +77,7 @@ gpb0: gpb0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpb1: gpb1 {
> +       gpb1: gpb1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -85,7 +85,7 @@ gpb1: gpb1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpb2: gpb2 {
> +       gpb2: gpb2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -93,7 +93,7 @@ gpb2: gpb2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpb3: gpb3 {
> +       gpb3: gpb3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -199,7 +199,7 @@ aud_i2s6_idle: aaud-i2s6-idle-pins {
>  };
>
>  &pinctrl_fsys0 {
> -       gpf0: gpf0 {
> +       gpf0: gpf0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -207,7 +207,7 @@ gpf0: gpf0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf1: gpf1 {
> +       gpf1: gpf1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -355,7 +355,7 @@ pcie_perst5_in: pcie-perst5-in-pins {
>  };
>
>  &pinctrl_fsys1 {
> -       gpf8: gpf8 {
> +       gpf8: gpf8-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -393,7 +393,7 @@ sd2_bus4: sd2-bus-width4-pins {
>  };
>
>  &pinctrl_fsys2 {
> -       gpf2: gpf2 {
> +       gpf2: gpf2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -401,7 +401,7 @@ gpf2: gpf2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf3: gpf3 {
> +       gpf3: gpf3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -409,7 +409,7 @@ gpf3: gpf3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf4: gpf4 {
> +       gpf4: gpf4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -417,7 +417,7 @@ gpf4: gpf4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf5: gpf5 {
> +       gpf5: gpf5-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -425,7 +425,7 @@ gpf5: gpf5 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf6: gpf6 {
> +       gpf6: gpf6-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -499,7 +499,7 @@ eth1_pps_out: eth1-pps-out-pins {
>  };
>
>  &pinctrl_peric0 {
> -       gpp0: gpp0 {
> +       gpp0: gpp0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -507,7 +507,7 @@ gpp0: gpp0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp1: gpp1 {
> +       gpp1: gpp1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -515,7 +515,7 @@ gpp1: gpp1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp2: gpp2 {
> +       gpp2: gpp2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -523,7 +523,7 @@ gpp2: gpp2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg0: gpg0 {
> +       gpg0: gpg0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -833,7 +833,7 @@ uart5_bus_dual: uart5-bus-dual-pins {
>  };
>
>  &pinctrl_peric1 {
> -       gpp3: gpp3 {
> +       gpp3: gpp3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -841,7 +841,7 @@ gpp3: gpp3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp4: gpp4 {
> +       gpp4: gpp4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -849,7 +849,7 @@ gpp4: gpp4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpp5: gpp5 {
> +       gpp5: gpp5-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -857,7 +857,7 @@ gpp5: gpp5 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg1: gpg1 {
> +       gpg1: gpg1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -865,7 +865,7 @@ gpg1: gpg1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg2: gpg2 {
> +       gpg2: gpg2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -873,7 +873,7 @@ gpg2: gpg2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg3: gpg3 {
> +       gpg3: gpg3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> --
> 2.32.0
>


From robin.murphy at arm.com  Fri Jan 14 08:42:06 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 14 Jan 2022 16:42:06 +0000
Subject: [PATCH 4/4] arm64: dts: rockchip: Enable the GPU on Quartz64
 Model A
In-Reply-To: <EB2E04F1-BACA-4A4F-97F9-0257F29D57B5@gmail.com>
References: <20211126151729.1026566-1-knaerzche@gmail.com>
 <20211126151729.1026566-5-knaerzche@gmail.com>
 <EB2E04F1-BACA-4A4F-97F9-0257F29D57B5@gmail.com>
Message-ID: <d2d54776-b4ee-2cda-334d-f868a6bbdf8b@arm.com>

On 2022-01-14 16:25, Piotr Oniszczuk wrote:
> 
> 
>> Wiadomo?? napisana przez Alex Bee <knaerzche at gmail.com> w dniu 26.11.2021, o godz. 16:17:
>>
>> From: Ezequiel Garcia <ezequiel at collabora.com>
>>
>> Enable the GPU core on the Pine64 Quartz64 Model A.
>>
>> Signed-off-by: Ezequiel Garcia <ezequiel at collabora.com>
>> Signed-off-by: Alex Bee <knaerzche at gmail.com>
>> ---
>> arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
>> index 4d4b2a301b1a..625489c60622 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
>> +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
>> @@ -205,6 +205,11 @@ &gmac1m0_clkinout
>> 	status = "okay";
>> };
>>
>> +&gpu {
>> +	mali-supply = <&vdd_gpu>;
>> +	status = "okay";
>> +};
>> +
>> &i2c0 {
>> 	status = "okay";
>>
>> -- 
>>
> 
> Alex, Ezequiel
> 
> I'm playing with 5.16 mainline on rk3566 based tvbox (x96-x6)
> 
> Box boots and I have working SD card, Eth, HDMI.
> 
> I applied this series as I want to get GPU working but I'm getting:
> 
> [    3.169144] panfrost fde60000.gpu: get clock failed -517
> [    3.169646] panfrost fde60000.gpu: clk init failed -517
> [    3.213653] panfrost fde60000.gpu: get clock failed -517
> [    3.214156] panfrost fde60000.gpu: clk init failed -517
> [    3.230505] panfrost fde60000.gpu: get clock failed -517
> [    3.231006] panfrost fde60000.gpu: clk init failed -517
> [    3.258072] panfrost fde60000.gpu: get clock failed -517
> [    3.258575] panfrost fde60000.gpu: clk init failed -517
> 
> Maybe you have some hints here?

517 is EPROBE_DEFER, which implies it's waiting for the relevant clock 
provider to show up. I see from patch #2 that SCMI is involved, so I'd 
check that that's working and you have CONFIG_COMMON_CLOCK_SCMI enabled.

Robin.


From semen.protsenko at linaro.org  Fri Jan 14 08:45:32 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 18:45:32 +0200
Subject: [PATCH v2 3/4] spi: dt-bindings: samsung: allow controller-data
 to be optional
In-Reply-To: <20220111101338.58630-4-krzysztof.kozlowski@canonical.com>
References: <20220111101338.58630-1-krzysztof.kozlowski@canonical.com>
 <20220111101338.58630-4-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4m5+BXD0vDi6YxvE7XYWZ5ej+QdL3OzzSCWG=mqX_sTqA@mail.gmail.com>

On Tue, 11 Jan 2022 at 12:13, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> The Samsung SoC SPI bindings requires to provide controller-data node
> for each of SPI peripheral device nodes.  Make this controller-data node
> optional, so DTS could be simpler.
>
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  .../devicetree/bindings/spi/samsung,spi-peripheral-props.yaml  | 1 +
>  Documentation/devicetree/bindings/spi/samsung,spi.yaml         | 3 ---
>  2 files changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> index aa5a1f48494b..cadc8a5f061f 100644
> --- a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> @@ -28,6 +28,7 @@ properties:
>             - 3: 270 degree phase shift sampling.
>          $ref: /schemas/types.yaml#/definitions/uint32
>          enum: [0, 1, 2, 3]
> +        default: 0
>
>      required:
>        - samsung,spi-feedback-delay
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> index da4533feb946..322558818a43 100644
> --- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -75,9 +75,6 @@ patternProperties:
>      allOf:
>        - $ref: spi-peripheral-props.yaml
>
> -    required:
> -      - controller-data
> -
>      unevaluatedProperties: false
>
>  required:
> --
> 2.32.0
>


From cujomalainey at google.com  Fri Jan 14 08:57:58 2022
From: cujomalainey at google.com (Curtis Malainey)
Date: Fri, 14 Jan 2022 08:57:58 -0800
Subject: [PATCH v14 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220114114633.742-3-allen-kh.cheng@mediatek.com>
References: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
 <20220114114633.742-3-allen-kh.cheng@mediatek.com>
Message-ID: <CAOReqxiSAhrSjXVW=D+ndXko95qLuHGkkNs5Wf-yVEcv1YompQ@mail.gmail.com>

> +
> +static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
> +{
> +       return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
> +}

this could probably be inline


> +
> +static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
> +                                            const struct of_phandle_args *sp)
> +{
> +       return mbox->chans;
> +}

also could probably benefit from inline


From alim.akhtar at samsung.com  Fri Jan 14 08:57:59 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 14 Jan 2022 22:27:59 +0530
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
Message-ID: <085801d80967$e4b8fe00$ae2afa00$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:03 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add device tree bindings for the Tesla FSD ARM SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  .../devicetree/bindings/arm/tesla.yaml        | 25 +++++++++++++++++++
>>  1 file changed, 25 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml
>> b/Documentation/devicetree/bindings/arm/tesla.yaml
>> new file mode 100644
>> index 000000000000..9f89cde76c85
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/arm/tesla.yaml
>> @@ -0,0 +1,25 @@
>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
>> +---
>> +$id:
>> +https://protect2.fireeye.com/v1/url?k=2f0fac44-70949546-2f0e270b-0cc4
>> +7a312ab0-50c826f7b1999a5f&q=1&e=bcbf277f-4e93-4705-8f6a-
>2beaa7eb31e2&
>> +u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Farm%2Ftesla.yaml%23
>> +$schema:
>> +https://protect2.fireeye.com/v1/url?k=d8493fe2-87d206e0-d848b4ad-0cc4
>> +7a312ab0-f4e5046adc7da972&q=1&e=bcbf277f-4e93-4705-8f6a-
>2beaa7eb31e2&
>> +u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>> +
>> +title: Tesla Full Self Driving(FSD) platforms device tree bindings
>> +
>> +maintainers:
>> +  - Alim Akhtar <alim.akhtar at samsung.com>
>> +  - linux-fsd at tesla.com
>> +
>> +properties:
>> +  $nodename:
>> +    const: '/'
>> +  compatible:
>> +    oneOf:
>> +
>> +      - description: FSD SoC board
>> +        items:
>> +          - const: tesla,fsd
>
>Either this is a SoC or a board compatible... Cannot be both.
>
Actually we call this as fsd board, so let me add accordingly compatible (fsd-baord) for board.
Thanks
>> +
>> +additionalProperties: true
>> +
>> +...
>>
>
>
>Best regards,
>Krzysztof



From semen.protsenko at linaro.org  Fri Jan 14 09:00:39 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 19:00:39 +0200
Subject: [PATCH v2 02/28] pinctrl: samsung: accept GPIO bank nodes with a
 suffix
In-Reply-To: <20220111201426.326777-3-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201426.326777-3-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4=TMyytDPO0t4c0Kayy9HAAja6dVq9L8_ic3vf_1LpSRA@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:15, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Existing dt-bindings expected that each GPIO/pin bank within pin
> controller has its own node with name matching the bank (e.g. gpa0,
> gpx2) and "gpio-controller" property.  The node name is then used for
> matching between driver data and DTS.
>
> Newly introduced dtschema expects to have nodes ending with "-gpio-bank"
> suffix, so rewrite bank-devicetree matching to look for old and new
> style of naming.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  drivers/pinctrl/samsung/pinctrl-samsung.c | 57 ++++++++++++++++++-----
>  1 file changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
> index b19ebc43d886..b3a5bc473841 100644
> --- a/drivers/pinctrl/samsung/pinctrl-samsung.c
> +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
> @@ -1012,13 +1012,56 @@ static void samsung_banks_of_node_put(struct samsung_pinctrl_drv_data *d)
>                 of_node_put(bank->of_node);
>  }
>
> +/*
> + * Iterate over all driver pin banks to find one matching the name of node,
> + * skipping optional "-gpio" node suffix. When found, assign node to the bank.
> + */
> +static void samsung_banks_of_node_get(struct device *dev,
> +                                     struct samsung_pinctrl_drv_data *d,
> +                                     struct device_node *node)
> +{
> +       const char *suffix = "-gpio-bank";
> +       struct samsung_pin_bank *bank;
> +       struct device_node *child;
> +       /* Pin bank names are up to 4 characters */
> +       char node_name[20];
> +       unsigned int i;
> +       size_t len;
> +
> +       bank = d->pin_banks;
> +       for (i = 0; i < d->nr_banks; ++i, ++bank) {
> +               strscpy(node_name, bank->name, sizeof(node_name));
> +               len = strlcat(node_name, suffix, sizeof(node_name));
> +               if (len >= sizeof(node_name)) {
> +                       dev_err(dev, "Too long pin bank name '%s', ignoring\n",
> +                               bank->name);
> +                       continue;
> +               }
> +
> +               for_each_child_of_node(node, child) {
> +                       if (!of_find_property(child, "gpio-controller", NULL))
> +                               continue;
> +                       if (of_node_name_eq(child, node_name))
> +                               break;
> +                       else if (of_node_name_eq(child, bank->name))
> +                               break;
> +               }
> +
> +               if (child)
> +                       bank->of_node = child;
> +               else
> +                       dev_warn(dev, "Missing node for bank %s - invalid DTB\n",
> +                                bank->name);
> +               /* child reference dropped in samsung_drop_banks_of_node() */
> +       }
> +}
> +
>  /* retrieve the soc specific data */
>  static const struct samsung_pin_ctrl *
>  samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
>                              struct platform_device *pdev)
>  {
>         struct device_node *node = pdev->dev.of_node;
> -       struct device_node *np;
>         const struct samsung_pin_bank_data *bdata;
>         const struct samsung_pin_ctrl *ctrl;
>         struct samsung_pin_bank *bank;
> @@ -1082,17 +1125,7 @@ samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,
>          */
>         d->virt_base = virt_base[0];
>
> -       for_each_child_of_node(node, np) {
> -               if (!of_find_property(np, "gpio-controller", NULL))
> -                       continue;
> -               bank = d->pin_banks;
> -               for (i = 0; i < d->nr_banks; ++i, ++bank) {
> -                       if (of_node_name_eq(np, bank->name)) {
> -                               bank->of_node = np;
> -                               break;
> -                       }
> -               }
> -       }
> +       samsung_banks_of_node_get(&pdev->dev, d, node);
>
>         d->pin_base = pin_base;
>         pin_base += d->nr_pins;
> --
> 2.32.0
>


From andrew at lunn.ch  Fri Jan 14 09:25:41 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Fri, 14 Jan 2022 18:25:41 +0100
Subject: [PATCH 2/2] stmmac: intel: Honor phy LED set by system firmware
 on a Dell hardware
In-Reply-To: <CAAd53p5R2y-2JhWx3wp2=aBypJO=iV7fFS99eAgk6q7KBZMFMA@mail.gmail.com>
References: <20220114040755.1314349-1-kai.heng.feng@canonical.com>
 <20220114040755.1314349-2-kai.heng.feng@canonical.com>
 <YeF18mxKuO4/4G0V@lunn.ch>
 <CAAd53p5R2y-2JhWx3wp2=aBypJO=iV7fFS99eAgk6q7KBZMFMA@mail.gmail.com>
Message-ID: <YeGyFabsBAfzvnU+@lunn.ch>

> > This is a PHY property. Why is the MAC involved?
> 
> This is inspired by commit a93f7fe13454 ("net: phy: marvell: add new
> default led configure for m88e151x") which passes the flag from MAC to
> PHY.

But in this case, the MAC does not care what the LEDs are. The
platform wants them left alone, not the MAC.

> > Please also think about how to make this generic, so any ACPI based
> > system can use it, with any PHY.

...

> So the only approach I can think of is to use DMI match directly in PHY driver.

In the phylib core. And the core then asks the specific PHY driver to
not touch the LED configuration. It is then generic.

      Andrew


From krzysztof.kozlowski at canonical.com  Fri Jan 14 09:29:55 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 14 Jan 2022 18:29:55 +0100
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
 <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
Message-ID: <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>

On 14/01/2022 17:57, Alim Akhtar wrote:
> 
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>> Sent: Thursday, January 13, 2022 6:03 PM
>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>> olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>> Subject: Re: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
>>
>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>> Add device tree bindings for the Tesla FSD ARM SoC.
>>>
>>> Cc: linux-fsd at tesla.com
>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>> ---
>>>  .../devicetree/bindings/arm/tesla.yaml        | 25 +++++++++++++++++++
>>>  1 file changed, 25 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml
>>> b/Documentation/devicetree/bindings/arm/tesla.yaml
>>> new file mode 100644
>>> index 000000000000..9f89cde76c85
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/arm/tesla.yaml
>>> @@ -0,0 +1,25 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
>>> +---
>>> +$id:
>>> +https://protect2.fireeye.com/v1/url?k=2f0fac44-70949546-2f0e270b-0cc4
>>> +7a312ab0-50c826f7b1999a5f&q=1&e=bcbf277f-4e93-4705-8f6a-
>> 2beaa7eb31e2&
>>> +u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Farm%2Ftesla.yaml%23
>>> +$schema:
>>> +https://protect2.fireeye.com/v1/url?k=d8493fe2-87d206e0-d848b4ad-0cc4
>>> +7a312ab0-f4e5046adc7da972&q=1&e=bcbf277f-4e93-4705-8f6a-
>> 2beaa7eb31e2&
>>> +u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>> +
>>> +title: Tesla Full Self Driving(FSD) platforms device tree bindings
>>> +
>>> +maintainers:
>>> +  - Alim Akhtar <alim.akhtar at samsung.com>
>>> +  - linux-fsd at tesla.com
>>> +
>>> +properties:
>>> +  $nodename:
>>> +    const: '/'
>>> +  compatible:
>>> +    oneOf:
>>> +
>>> +      - description: FSD SoC board
>>> +        items:
>>> +          - const: tesla,fsd
>>
>> Either this is a SoC or a board compatible... Cannot be both.
>>
> Actually we call this as fsd board, so let me add accordingly compatible (fsd-baord) for board.
> Thanks

It's confusing and probably not accurate. In your series fsd is three
things in the same time: an architecture, a SoC and a board (DTS). The
last two should definitely be different. You probably have some eval
board (how it is called also in Tesla open source git) or some specific
product board.

I cannot judge how different this is from Exynos subarchitecture -
looking at patches it is not different - so I could understand a FSD
sub-arch with only one SoC.


Best regards,
Krzysztof


From james.clark at arm.com  Fri Jan 14 09:32:53 2022
From: james.clark at arm.com (James Clark)
Date: Fri, 14 Jan 2022 17:32:53 +0000
Subject: [PATCH 0/1] coresight: Fix TRCCONFIGR.QE sysfs interface
Message-ID: <20220114173254.1876151-1-james.clark@arm.com>

I was working on refactoring some of the magic numbers for the register
accesses and I saw this issue with programming one of the values.

I don't have any evidence that someone encountered it not working, probably
there is no hardware where QSUPP==0b10, or it just didn't get used yet.
But the issue is that this silently writes a reserved value even if the
user provided one was correct so it might ruin someones day if it ever
comes up.

It's a small change so I didn't see the harm in fixing it.

Applies to coresight/next f9809d565135

James Clark (1):
  coresight: Fix TRCCONFIGR.QE sysfs interface

 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.17.1



From james.clark at arm.com  Fri Jan 14 09:32:54 2022
From: james.clark at arm.com (James Clark)
Date: Fri, 14 Jan 2022 17:32:54 +0000
Subject: [PATCH 1/1] coresight: Fix TRCCONFIGR.QE sysfs interface
In-Reply-To: <20220114173254.1876151-1-james.clark@arm.com>
References: <20220114173254.1876151-1-james.clark@arm.com>
Message-ID: <20220114173254.1876151-2-james.clark@arm.com>

It's impossible to program a valid value for TRCCONFIGR.QE
when TRCIDR0.QSUPP==0b10. In that case the following is true:

  Q element support is implemented, and only supports Q elements without
  instruction counts. TRCCONFIGR.QE can only take the values 0b00 or 0b11.

Currently the low bit of QSUPP is checked to see if the low bit of QE can
be written to, but as you can see when QSUPP==0b10 the low bit is cleared
making it impossible to ever write the only valid value of 0b11 to QE.
0b10 would be written instead, which is a reserved QE value even for all
values of QSUPP.

The fix is to allow writing the low bit of QE for any non zero value of
QSUPP.

This change doesn't go any further to validate if the user supplied value
is valid, because none of the other parts this function do, but it does fix
the case where it was impossible to ever set a valid value.

Signed-off-by: James Clark <james.clark at arm.com>
---
 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a0640fa5c55b..a99bb537ea23 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -368,7 +368,7 @@ static ssize_t mode_store(struct device *dev,
 	/* start by clearing QE bits */
 	config->cfg &= ~(BIT(13) | BIT(14));
 	/* if supported, Q elements with instruction counts are enabled */
-	if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
+	if ((mode & BIT(0)) && drvdata->q_support)
 		config->cfg |= BIT(13);
 	/*
 	 * if supported, Q elements with and without instruction
-- 
2.17.1



From alexandru.elisei at arm.com  Fri Jan 14 09:42:04 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Fri, 14 Jan 2022 17:42:04 +0000
Subject: [PATCH v5 11/69] KVM: arm64: nv: Add nested virt VCPU primitives
 for vEL2 VCPU state
In-Reply-To: <20211129200150.351436-12-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-12-maz@kernel.org>
Message-ID: <YeG17OWrvFPQjgjS@monolith.localdoman>

Hi Marc,

Bunch of bikeshedding regarding names below, which can be safely ignored.

On Mon, Nov 29, 2021 at 08:00:52PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> When running a nested hypervisor we commonly have to figure out if
> the VCPU mode is running in the context of a guest hypervisor or guest
> guest, or just a normal guest.
> 
> Add convenient primitives for this.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_emulate.h | 55 ++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index f4871e47b2d0..f4b079945d0f 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -176,6 +176,61 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
>  		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
>  }
>  
> +static inline bool vcpu_mode_el2_ctxt(const struct kvm_cpu_context *ctxt)

"The Armv8-A architecture defines a set of Exception levels, EL0 to EL3" (ARM
DDI 0487G.a, page G1-5941).

"AArch64 state does not support modes. Modes are a concept that is specific to
AArch32 state." (ARM DDI 0487G.a, page G1-5944).

Wouldn't it be better to use the same terminology as the architecture?

> +{
> +	unsigned long cpsr = ctxt->regs.pstate;

CPSR is an AArch32 register. Why not name the variable pstate?

> +
> +	switch (cpsr & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
> +	case PSR_MODE_EL2h:
> +	case PSR_MODE_EL2t:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
> +{
> +	return vcpu_mode_el2_ctxt(&vcpu->arch.ctxt);
> +}
> +
> +static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
> +{
> +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
> +}
> +
> +static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
> +{
> +	return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
> +}
> +
> +static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
> +{
> +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
> +}
> +
> +static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)

This is confusing. What does the exception level have to do with the HCR_EL2.TGE
bit being set? Wouldn't vcpu_hcr_tge_is_set() be better?

> +{
> +	return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
> +}
> +
> +static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
> +{
> +	/*
> +	 * We are in a hypervisor context if the vcpu mode is EL2 or
> +	 * E2H and TGE bits are set. The latter means we are in the user space
> +	 * of the VHE kernel. ARMv8.1 ARM describes this as 'InHost'

So why not call the function vcpu_is_inhost() or something along those lines to
match the architecture?

Thanks,
Alex

> +	 */
> +	return vcpu_mode_el2_ctxt(ctxt) ||
> +		(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
> +		WARN_ON(__vcpu_el2_tge_is_set(ctxt));
> +}
> +
> +static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
> +{
> +	return __is_hyp_ctxt(&vcpu->arch.ctxt);
> +}
> +
>  /*
>   * The layout of SPSR for an AArch32 state is different when observed from an
>   * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
> -- 
> 2.30.2
> 


From piotr.oniszczuk at gmail.com  Fri Jan 14 09:56:03 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Fri, 14 Jan 2022 18:56:03 +0100
Subject: [PATCH 4/4] arm64: dts: rockchip: Enable the GPU on Quartz64
 Model A
In-Reply-To: <d2d54776-b4ee-2cda-334d-f868a6bbdf8b@arm.com>
References: <20211126151729.1026566-1-knaerzche@gmail.com>
 <20211126151729.1026566-5-knaerzche@gmail.com>
 <EB2E04F1-BACA-4A4F-97F9-0257F29D57B5@gmail.com>
 <d2d54776-b4ee-2cda-334d-f868a6bbdf8b@arm.com>
Message-ID: <37D4623A-2DEA-4CA6-8DD8-1E3E88CBB250@gmail.com>



> Wiadomo?? napisana przez Robin Murphy <robin.murphy at arm.com> w dniu 14.01.2022, o godz. 17:42:
> 
>> 
> 
> 517 is EPROBE_DEFER, which implies it's waiting for the relevant clock provider to show up. I see from patch #2 that SCMI is involved, so I'd check that that's working and you have CONFIG_COMMON_CLOCK_SCMI enabled.
> 
> Robin.

Robin,

Many thx!
Indeed issue was with SCMi CLK.
Now i see:

[    3.092350] panfrost fde60000.gpu: clock rate = 594000000
[    3.092906] panfrost fde60000.gpu: bus_clock rate = 500000000
[    3.138340] panfrost fde60000.gpu: clock rate = 594000000
[    3.138904] panfrost fde60000.gpu: bus_clock rate = 500000000
[    3.171244] panfrost fde60000.gpu: clock rate = 594000000
[    3.171888] panfrost fde60000.gpu: bus_clock rate = 500000000

good.

(unfortunately mesa 21.3.4 still goes with llvmpipe but this seems to be other issue i need to investigate)

thx again!





From andre.przywara at arm.com  Fri Jan 14 10:12:47 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 18:12:47 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220114105653.3003399-7-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
Message-ID: <20220114181247.7b366f45@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:46 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> The SCTLR_ELx registers contain fields which are UNKNOWN or
> IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
> defines the endianness of memory accesses (e.g. reads from literal
> pools). Due to this, portions of boot-wrapper code are not guaranteed
> to work correctly.
> 
> Rework the startup code to explicitly initialize SCTLR_ELx for the
> exception level the boot-wrapper was entered at. When entered at EL2
> it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
> behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
> which would break the initialization performed in jump_kernel.
> 
> As we plan to eventually support the highest implemented EL being any of
> EL3/EL2/EL1, code is added to handle all of these exception levels, even
> though we do not currently support starting at EL1.
> 
> We'll initialize other registers in subsequent patches.

So the idea of initialising each EL and the respective code below looks
good to me, however I have some questions about the SCTLR reset values
below:

> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
>  arch/aarch64/include/asm/cpu.h | 27 ++++++++++++-
>  2 files changed, 85 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 900b9f8..45a0367 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -26,26 +26,26 @@
>  	 *   PSCI is not supported when entered in this exception level.
>  	 */
>  ASM_FUNC(_start)
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	cmp	x0, #MPIDR_INVALID
> -	beq	err_invalid_id
> -	bl	setup_stack
> -
> -	/*
> -	 * EL3 initialisation
> -	 */
>  	mrs	x0, CurrentEL
>  	cmp	x0, #CURRENTEL_EL3
> -	b.eq	1f
> +	b.eq	reset_at_el3
> +	cmp	x0, #CURRENTEL_EL2
> +	b.eq	reset_at_el2
> +	cmp	x0, #CURRENTEL_EL1
> +	b.eq	reset_at_el1
>  
> -	mov	w0, #1
> -	ldr	x1, =flag_no_el3
> -	str	w0, [x1]
> +	/* Booting at EL0 is not supported */
> +	b	.
>  
> -	b	start_no_el3
> +	/*
> +	 * EL3 initialisation
> +	 */
> +reset_at_el3:
> +	mov_64	x0, SCTLR_EL3_RESET
> +	msr	sctlr_el3, x0
> +	isb
>  
> -1:	mov	x0, #0x30			// RES1
> +	mov	x0, #0x30			// RES1
>  	orr	x0, x0, #(1 << 0)		// Non-secure EL1
>  	orr	x0, x0, #(1 << 8)		// HVC enable
>  
> @@ -135,10 +135,54 @@ ASM_FUNC(_start)
>  	ldr	x0, =COUNTER_FREQ
>  	msr	cntfrq_el0, x0
>  
> +	cpuid	x0, x1
> +	bl	find_logical_id
> +	cmp	x0, #MPIDR_INVALID
> +	b.eq	err_invalid_id
> +	bl	setup_stack
> +
>  	bl	gic_secure_init
>  
>  	b	start_el3
>  
> +	/*
> +	 * EL2 initialization
> +	 */
> +reset_at_el2:
> +	// Ensure E2H is not in use
> +	mov_64	x0, HCR_EL2_RESET
> +	msr	hcr_el2, x0
> +	isb
> +
> +	mov_64	x0, SCTLR_EL2_RESET
> +	msr	sctlr_el2, x0
> +	isb
> +
> +	b	reset_no_el3
> +
> +	/*
> +	 * EL1 initialization
> +	 */
> +reset_at_el1:
> +	mov_64	x0, SCTLR_EL1_RESET
> +	msr	sctlr_el1, x0
> +	isb
> +
> +	b	reset_no_el3
> +
> +reset_no_el3:
> +	cpuid	x0, x1
> +	bl	find_logical_id
> +	cmp	x0, #MPIDR_INVALID
> +	b.eq	err_invalid_id
> +	bl	setup_stack
> +
> +	mov	w0, #1
> +	ldr	x1, =flag_no_el3
> +	str	w0, [x1]
> +
> +	b	start_no_el3
> +
>  err_invalid_id:
>  	b	.
>  
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 1053414..1e9141a 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -14,6 +14,32 @@
>  #define MPIDR_ID_BITS		0xff00ffffff
>  
>  #define CURRENTEL_EL3		(3 << 2)
> +#define CURRENTEL_EL2		(2 << 2)
> +#define CURRENTEL_EL1		(1 << 2)
> +
> +/*
> + * RES1 bit definitions definitions as of ARM DDI 0487G.b
> + *
> + * These includes bits which are RES1 in some configurations.
> + */
> +#define SCTLR_EL3_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> +				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))
> +
> +#define SCTLR_EL2_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> +				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))

I compared all bits against the ARM ARM and the kernel version for EL2,
that looks correct to me.

> +
> +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))

- The kernel sets TSCXT(bit[20]), and the ARM ARM says that the value
should be RES1 if FEAT_CSV2_* is not implemented. Should we copy this?
- The kernel clears ITD(bit[7]), and the ARM ARM says it's *Otherwise* RES1
(no AArch32 in EL0). I feel like we should not disable IT instructions in
EL0 needlessly?
- I also feel like we should set CP15BEN(bit[5]), for similar reasons.

Granted those bits affect only EL0 execution, which we don't care about in
the boot-wrapper, but I was wondering if we should change those anyway? At
least bit 20?

> +
> +#define HCR_EL2_RES1		(BIT(1))

Should we set RW(bit[31]), just to be safe? Not sure this is explicitly
mentioned somewhere, but is the boot flow when we are entered in EL2 to
stay in EL2 and launch the kernel in there as well?

> +
> +/*
> + * Initial register values required for the boot-wrapper to run out-of-reset.
> + */
> +#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
> +#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
> +#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
> +#define HCR_EL2_RESET		HCR_EL2_RES1
>  
>  #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
>  
> @@ -43,7 +69,6 @@
>  #define ZCR_EL3_LEN_MASK	0x1ff
>  
>  #define SCTLR_EL1_CP15BEN	(1 << 5)
> -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
>  
>  #ifdef KERNEL_32
>  /* 32-bit kernel decompressor uses CP15 barriers */
> #define SCTLR_EL1_KERNEL        (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)

So I wonder if this actually works? The ARMv7 version of SCTLR
differs in some bits from both the ARMv8 AArch32 version and more
importantly the AArch64 version. I had troubles the other day running the
arm32 Linux kernel decompressor with some ARMv8 SCTLR_EL1 reset value. The
decompressor code does only read-modify-write of SCTLR (probably to
cover multiple architecture revisions), so some bits might stay wrong. In
particular I think having bits 28 and 29 set caused problems.
By looking at the ARMv7 ARM and with experimentation I came up
with 0x00c00878 as a safe and working value.
Shall we have a separate reset value for 32bit?

Cheers,
Andre



From andre.przywara at arm.com  Fri Jan 14 10:13:17 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Fri, 14 Jan 2022 18:13:17 +0000
Subject: [bootwrapper PATCH 02/13] Add bit-field macros
In-Reply-To: <Yd7itXaf30d3Nv+x@FVFF77S0Q05N>
References: <20220111130653.2331827-1-mark.rutland@arm.com>
 <20220111130653.2331827-3-mark.rutland@arm.com>
 <20220111144048.2675076e@donnerap.cambridge.arm.com>
 <Yd7itXaf30d3Nv+x@FVFF77S0Q05N>
Message-ID: <20220114181317.5742b91a@donnerap.cambridge.arm.com>

On Wed, 12 Jan 2022 14:16:21 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> On Tue, Jan 11, 2022 at 02:40:48PM +0000, Andre Przywara wrote:
> > On Tue, 11 Jan 2022 13:06:42 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi Mark,
> >   
> > > Arm architectural documentation typically defines bit-fields as
> > > `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> > > helpful if we could define fields in the same way.
> > > 
> > > Add helpers so that we can do so, along with helper to extract/insert
> > > bit-field values.
> > > 
> > > There should be no functional change as a result of this patch.
> > > 
> > > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > > ---
> > >  include/bits.h | 33 +++++++++++++++++++++++++++++++++
> > >  1 file changed, 33 insertions(+)
> > >  create mode 100644 include/bits.h
> > > 
> > > diff --git a/include/bits.h b/include/bits.h
> > > new file mode 100644
> > > index 0000000..8824a38
> > > --- /dev/null
> > > +++ b/include/bits.h
> > > @@ -0,0 +1,33 @@
> > > +/*
> > > + * include/bits.h - helpers for bit-field definitions.
> > > + *
> > > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > > + *
> > > + * Use of this source code is governed by a BSD-style license that can be
> > > + * found in the LICENSE.txt file.
> > > + */
> > > +#ifndef __BITS_H
> > > +#define __BITS_H
> > > +
> > > +#ifdef __ASSEMBLY__
> > > +#define UL(x)	x
> > > +#define ULL(x)	x
> > > +#else
> > > +#define UL(x)	x##UL
> > > +#define ULL(x)	x##ULL
> > > +#endif
> > > +
> > > +#define BITS(msb, lsb) \  
> > 
> > The kernel uses GENMASK() for this, should we follow suit here? Both
> > U-Boot and Trusted Firmware decided to do so, so I consider this some kind
> > of agreed naming for bitmask generation these days.  
> 
> TBH, I always forget the naming of GENMASK(), and chose `BITS()` to more
> clearly align with `BIT()`, and also the way the architecture documentation
> speaks about "bits [msb:lsb]".
> 
> I'm not wedded to the naming, but IMO `GENMASK()` isn't any better, even if
> that's what linux uses. Regardless of the specific names, I'd like the
> single-bit and multi-bit helpers to clearly align naming-wise.
> 
> For now I'd prefer to stick with `BIT()` and `BITS()`.

Fair enough, seeing that in the code in later patches looked alright, I
guess having two arguments sets it apart enough from just BIT.

Cheers,
Andre

> > > +((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
> > > +
> > > +#define BIT(b)	BITS(b, b)
> > > +
> > > +#define BITS_LSB(bits)	(__builtin_ffsll(bits) - 1)  
> > 
> > Shall there be some comment explaining the functionality and arguments? Or
> > maybe use "mask" instead of the more ambiguous "bits" name here?
> > TBH I needed to read the implementation of the next macro to understand
> > what it does.  
> 
> If there's any confusion here I think we need comments regardless, since
> neither `bits` nor `mask` imply contiguity, which is the important factor. I'll
> add some comments with examples.
> 
> I'm happy to also rename the `bits` parameter to `mask`.
> 
> > > +
> > > +#define BITS_EXTRACT(val, bits) \  
> > 
> > Same here, having BITS_EXTRACT(val, mask) looks more readable to me.  
> 
> I'll do as above hree, and likewise for the cases below.
> 
> Thanks,
> Mark.
> 
> > 
> > Cheers,
> > Andre
> >   
> > > +	(((val) & (bits)) >> BITS_LSB(bits))
> > > +
> > > +#define BITS_INSERT(bits, val) \
> > > +	(((val) << BITS_LSB(bits)) & (bits))
> > > +
> > > +#endif  
> >   



From semen.protsenko at linaro.org  Fri Jan 14 10:31:52 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 20:31:52 +0200
Subject: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to
 dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4k3VNuQGfi_mnAWYUSXYaPmoFj1D55pHH0ByUsNu9kSyQ@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:15, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Hi,
>
> Changes since v1
> ================
> 1. Patch #1: add missing pin assignment (Alim).
> 2. Patch #2: correct double sizeof() (Alim).
> 3. Patch #7, #8: put label-override in proper patch (Alim).
> 4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
> 5. New patches: #25 - #28.
>    Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
>    handling, so they need their own compatibles.
>    Please kindly review and provide feedback on these as I do not have
>    details.
> 6. Add review tags.
>
> Dependencies
> ============
> 1. Patch #2 ("pinctrl: samsung: accept GPIO bank nodes with a suffix") is
>    necessary for DTS patches.
>
> 2. Last patches #27 and #28 depend on patch #26 adding the compatibles.
>
> Best regards,
> Krzysztof
>
> Krzysztof Kozlowski (28):
>   pinctrl: samsung: drop pin banks references on error paths
>   pinctrl: samsung: accept GPIO bank nodes with a suffix
>   ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
>   ARM: dts: exynos: override pins by label in Peach Pit
>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
>   ARM: dts: exynos: override pins by label in Peach Pi
>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
>   ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
>   ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
>   arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
>   arm64: dts: exynos: align pinctrl with dtschema in Exynos7
>   arm64: dts: exynos: align pinctrl with dtschema in Exynos850
>   arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
>   ARM: dts: s3c24xx: align pinctrl with dtschema
>   ARM: dts: s3c64xx: align pinctrl with dtschema
>   ARM: dts: s5pv210: align pinctrl with dtschema
>   dt-bindings: pinctrl: samsung: convert to dtschema
>   dt-bindings: pinctrl: samsung: describe Exynos850 and ExynosAutov9
>     wake-ups
>   pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups
>   arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
>     Exynos850
>   arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
>     ExynosAutov9
>

Maybe it makes sense to include my patch [1] for gpm6/gpm7 in this series?

[1] https://lore.kernel.org/linux-arm-kernel/20220103181826.2136-1-semen.protsenko at linaro.org/T/

>  .../pinctrl/samsung,pinctrl-gpio-bank.yaml    |  52 +++
>  .../pinctrl/samsung,pinctrl-pins-cfg.yaml     |  81 ++++
>  .../samsung,pinctrl-wakeup-interrupt.yaml     | 106 +++++
>  .../bindings/pinctrl/samsung,pinctrl.yaml     | 392 ++++++++++++++++++
>  .../bindings/pinctrl/samsung-pinctrl.txt      | 383 -----------------
>  MAINTAINERS                                   |   2 +-
>  arch/arm/boot/dts/exynos3250-artik5.dtsi      |  10 +-
>  arch/arm/boot/dts/exynos3250-pinctrl.dtsi     | 165 ++++----
>  arch/arm/boot/dts/exynos4210-i9100.dts        |  30 +-
>  arch/arm/boot/dts/exynos4210-origen.dts       |   2 +-
>  arch/arm/boot/dts/exynos4210-pinctrl.dtsi     | 226 +++++-----
>  arch/arm/boot/dts/exynos4210-smdkv310.dts     |   4 +-
>  arch/arm/boot/dts/exynos4210-trats.dts        |   6 +-
>  .../boot/dts/exynos4210-universal_c210.dts    |  12 +-
>  arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi   |   4 +-
>  arch/arm/boot/dts/exynos4412-itop-elite.dts   |   2 +-
>  .../boot/dts/exynos4412-itop-scp-core.dtsi    |   2 +-
>  arch/arm/boot/dts/exynos4412-midas.dtsi       |  30 +-
>  .../boot/dts/exynos4412-odroid-common.dtsi    |   8 +-
>  arch/arm/boot/dts/exynos4412-odroidx.dts      |   2 +-
>  arch/arm/boot/dts/exynos4412-origen.dts       |   4 +-
>  arch/arm/boot/dts/exynos4412-p4note.dtsi      |  44 +-
>  arch/arm/boot/dts/exynos4412-pinctrl.dtsi     | 252 +++++------
>  arch/arm/boot/dts/exynos4412-smdk4412.dts     |   4 +-
>  arch/arm/boot/dts/exynos5250-arndale.dts      |   2 +-
>  arch/arm/boot/dts/exynos5250-pinctrl.dtsi     | 220 +++++-----
>  arch/arm/boot/dts/exynos5250-smdk5250.dts     |   2 +-
>  arch/arm/boot/dts/exynos5250-snow-common.dtsi |  22 +-
>  arch/arm/boot/dts/exynos5250-snow-rev5.dts    |   2 +-
>  arch/arm/boot/dts/exynos5250-snow.dts         |   2 +-
>  arch/arm/boot/dts/exynos5250-spring.dts       |  20 +-
>  arch/arm/boot/dts/exynos5260-pinctrl.dtsi     | 148 +++----
>  arch/arm/boot/dts/exynos5260-xyref5260.dts    |   2 +-
>  arch/arm/boot/dts/exynos5410-odroidxu.dts     |  22 +-
>  arch/arm/boot/dts/exynos5410-pinctrl.dtsi     | 170 ++++----
>  arch/arm/boot/dts/exynos5410-smdk5410.dts     |   4 +-
>  arch/arm/boot/dts/exynos5420-arndale-octa.dts |   2 +-
>  arch/arm/boot/dts/exynos5420-peach-pit.dts    |  89 ++--
>  arch/arm/boot/dts/exynos5420-pinctrl.dtsi     | 194 ++++-----
>  arch/arm/boot/dts/exynos5420-smdk5420.dts     |   6 +-
>  arch/arm/boot/dts/exynos5422-odroid-core.dtsi |   2 +-
>  .../boot/dts/exynos5422-odroidxu3-common.dtsi |   6 +-
>  arch/arm/boot/dts/exynos5800-peach-pi.dts     |  89 ++--
>  arch/arm/boot/dts/s3c2416-pinctrl.dtsi        |  60 +--
>  arch/arm/boot/dts/s3c6410-mini6410.dts        |   4 +-
>  arch/arm/boot/dts/s3c64xx-pinctrl.dtsi        | 210 +++++-----
>  arch/arm/boot/dts/s3c64xx.dtsi                |  16 +-
>  arch/arm/boot/dts/s5pv210-aquila.dts          |   2 +-
>  arch/arm/boot/dts/s5pv210-aries.dtsi          |  40 +-
>  arch/arm/boot/dts/s5pv210-fascinate4g.dts     |  12 +-
>  arch/arm/boot/dts/s5pv210-galaxys.dts         |  16 +-
>  arch/arm/boot/dts/s5pv210-pinctrl.dtsi        | 226 +++++-----
>  .../boot/dts/exynos/exynos5433-pinctrl.dtsi   | 211 +++++-----
>  .../dts/exynos/exynos5433-tm2-common.dtsi     | 259 ++++++------
>  .../boot/dts/exynos/exynos7-espresso.dts      |   6 +-
>  .../boot/dts/exynos/exynos7-pinctrl.dtsi      | 176 ++++----
>  .../boot/dts/exynos/exynos850-pinctrl.dtsi    |  52 +--
>  arch/arm64/boot/dts/exynos/exynos850.dtsi     |   4 +-
>  .../boot/dts/exynos/exynosautov9-pinctrl.dtsi |  50 +--
>  arch/arm64/boot/dts/exynos/exynosautov9.dtsi  |   2 +-
>  drivers/pinctrl/samsung/pinctrl-exynos.c      |   4 +
>  drivers/pinctrl/samsung/pinctrl-samsung.c     |  87 +++-
>  62 files changed, 2261 insertions(+), 2003 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
>  create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
>  delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
>
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Fri Jan 14 10:34:17 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 20:34:17 +0200
Subject: [PATCH v2 27/28] arm64: dts: exynos: use dedicated wake-up
 pinctrl compatible in Exynos850
In-Reply-To: <20220111201722.327219-21-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-21-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4m-_GSPFAOOaxkBQ7z5M6KcCm9jDKnfgCvgsKfLKKoM+g@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:19, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
> Exynos5, Exynos5433) with external wake-up interrupts, expected to have
> one interrupt for multiplexing these wake-up interrupts.  Also they
> expected to have exactly one pin controller capable of external wake-up
> interrupts.
>
> It seems however that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences:
> 1. No multiplexed external wake-up interrupt, only direct,
> 2. More than one pin controller capable of external wake-up interrupts.
>
> Use dedicated Exynos850 compatible for its external wake-up interrupts
> controller to indicate the differences.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  arch/arm64/boot/dts/exynos/exynos850.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> index 4f0a40de5e67..bcae772e8d91 100644
> --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
> @@ -346,7 +346,7 @@ pinctrl_alive: pinctrl at 11850000 {
>                         reg = <0x11850000 0x1000>;
>
>                         wakeup-interrupt-controller {
> -                               compatible = "samsung,exynos7-wakeup-eint";
> +                               compatible = "samsung,exynos850-wakeup-eint";
>                         };
>                 };
>
> @@ -355,7 +355,7 @@ pinctrl_cmgp: pinctrl at 11c30000 {
>                         reg = <0x11c30000 0x1000>;
>
>                         wakeup-interrupt-controller {
> -                               compatible = "samsung,exynos7-wakeup-eint";
> +                               compatible = "samsung,exynos850-wakeup-eint";
>                         };
>                 };
>
> --
> 2.32.0
>


From semen.protsenko at linaro.org  Fri Jan 14 11:43:07 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 21:43:07 +0200
Subject: [PATCH] arm64: dts: exynos: Add missing gpm6 and gpm7 nodes to
 Exynos850
In-Reply-To: <b40fedf8-73d7-6f4e-d26e-2f274b15228a@canonical.com>
References: <20220103181826.2136-1-semen.protsenko@linaro.org>
 <b40fedf8-73d7-6f4e-d26e-2f274b15228a@canonical.com>
Message-ID: <CAPLW+4k7VEh0E312Cw=AjufOo_OisJ5yrLm1QdhAcHFqayVv+w@mail.gmail.com>

On Fri, 7 Jan 2022 at 10:05, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 03/01/2022 19:18, Sam Protsenko wrote:
> > gpm6 and gpm7 nodes are missing in Exynos850 device tree. Next errors
> > are reported because of that:
> >
> >     Missing node for bank gpm6 - invalid DTB
> >     Missing node for bank gpm7 - invalid DTB
> >
> > Add missing nodes to make those available to use, and to fix boot
> > errors.
> >
> > Fixes: e3493220fd3e ("arm64: dts: exynos: Add initial Exynos850 SoC support")
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> > NOTES:
> >   - Recommend to apply this patch after "arm64: dts: exynos: align
> >     pinctrl with dtschema in Exynos850"
> >   - This patch also brings back two interrupts removed in "arm64:
> >     dts: exynos: drop incorrectly placed wakeup interrupts in Exynos850"
>
> I'll take it after the merge window and apply it before my series (so
> without -gpio-bank suffix).
>

Sure, whatever you think is best.

> >
> >  .../boot/dts/exynos/exynos850-pinctrl.dtsi    | 20 +++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > index a71acf358d2d..f43e4a206282 100644
> > --- a/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > +++ b/arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
> > @@ -194,6 +194,26 @@ gpm5: gpm5-gpio-bank {
> >               interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
> >       };
> >
> > +     gpm6: gpm6-gpio-bank {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> > +     gpm7: gpm7-gpio-bank {
> > +             gpio-controller;
> > +             #gpio-cells = <2>;
> > +
> > +             interrupt-controller;
> > +             #interrupt-cells = <2>;
> > +             interrupt-parent = <&gic>;
> > +             interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
> > +     };
> > +
> >       /* USI_CMGP0: HSI2C function */
> >       hsi2c3_pins: hsi2c3-pins {
> >               samsung,pins = "gpm0-0", "gpm1-0";
> >
>
>
> Best regards,
> Krzysztof


From semen.protsenko at linaro.org  Fri Jan 14 11:44:00 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 21:44:00 +0200
Subject: [PATCH v2 25/28] dt-bindings: pinctrl: samsung: describe
 Exynos850 and ExynosAutov9 wake-ups
In-Reply-To: <20220111201722.327219-19-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-19-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4=FGEuaMYWXewkhzsPz1GgCsPJQAg5WKm_OOSxNmP-Uxg@mail.gmail.com>

On Tue, 11 Jan 2022 at 22:18, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Older Samsung Exynos SoC pin controller nodes (Exynos3250, Exynos4,
> Exynos5, Exynos5433) with external wake-up interrupts, expected to have
> one interrupt for multiplexing these wake-up interrupts.  Also they
> expected to have exactly one pin controller capable of external wake-up
> interrupts.
>
> It seems however that newer ARMv8 Exynos SoC like Exynos850 and
> ExynosAutov9 have differences of their pin controller node capable of
> external wake-up interrupts:
> 1. No multiplexed external wake-up interrupt, only direct,
> 2. More than one pin controller capable of external wake-up interrupts.
>
> Add dedicated Exynos850 and ExynosAutov9 compatibles.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---

Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

>  .../samsung,pinctrl-wakeup-interrupt.yaml     | 27 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
> index 6b684a53119b..a822f70f5702 100644
> --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
> +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
> @@ -16,9 +16,12 @@ description: |
>    controller.
>
>    External wake-up interrupts for Samsung S3C/S5P/Exynos SoC pin controller.
> -  Only one pin-controller device node can include external wake-up interrupts
> -  child node (in other words, only one External wake-up interrupts
> +  For S3C24xx, S3C64xx, S5PV210 and Exynos4210 compatible wake-up interrupt
> +  controllers, only one pin-controller device node can include external wake-up
> +  interrupts child node (in other words, only one External wake-up interrupts
>    pin-controller is supported).
> +  For newer controllers, multiple pin-controller device node can include
> +  external wake-up interrupts child node.
>
>    See also Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml for
>    additional information and example.
> @@ -32,6 +35,8 @@ properties:
>        - samsung,s5pv210-wakeup-eint
>        - samsung,exynos4210-wakeup-eint
>        - samsung,exynos7-wakeup-eint
> +      - samsung,exynos850-wakeup-eint
> +      - samsung,exynosautov9-wakeup-eint
>
>    interrupts:
>      description:
> @@ -41,7 +46,6 @@ properties:
>
>  required:
>    - compatible
> -  - interrupts
>
>  allOf:
>    - if:
> @@ -56,6 +60,8 @@ allOf:
>          interrupts:
>            minItems: 6
>            maxItems: 6
> +      required:
> +        - interrupts
>
>    - if:
>        properties:
> @@ -67,6 +73,8 @@ allOf:
>          interrupts:
>            minItems: 4
>            maxItems: 4
> +      required:
> +        - interrupts
>
>    - if:
>        properties:
> @@ -81,5 +89,18 @@ allOf:
>          interrupts:
>            minItems: 1
>            maxItems: 1
> +      required:
> +        - interrupts
> +
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - samsung,exynos850-wakeup-eint
> +              - samsung,exynosautov9-wakeup-eint
> +    then:
> +      properties:
> +        interrupts: false
>
>  additionalProperties: false
> --
> 2.32.0
>


From briannorris at chromium.org  Fri Jan 14 12:16:49 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 12:16:49 -0800
Subject: [PATCH 0/3] (Re)enable DP/HDMI audio for RK3399 Gru
Message-ID: <20220114201652.3875838-1-briannorris@chromium.org>

This series fixes DP/HDMI audio for RK3399 Gru systems.

First, there was a regression with the switch to SPDIF. Patch 1 can be
taken separately as a regression fix if desired. But it's not quite so
useful (at least on Chrome OS systems) without the second part.

Second, jack detection was never upstreamed, because the hdmi-codec
dependencies were still being worked out when this platform was first
supported.

Patches cover a few subsystems. Perhaps this is something for arm-soc?


Brian Norris (3):
  arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
  drm/rockchip: cdn-dp: Support HDMI codec plug-change callback
  ASoC: rk3399_gru_sound: Wire up DP jack detection

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 10 +++----
 drivers/gpu/drm/rockchip/cdn-dp-core.c       | 28 ++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-core.h       |  4 +++
 sound/soc/rockchip/rk3399_gru_sound.c        | 20 ++++++++++++++
 4 files changed, 57 insertions(+), 5 deletions(-)

-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 12:16:50 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 12:16:50 -0800
Subject: [PATCH 1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
In-Reply-To: <20220114201652.3875838-1-briannorris@chromium.org>
References: <20220114201652.3875838-1-briannorris@chromium.org>
Message-ID: <20220114121515.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>

Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
switched the platform to SPDIF, but we didn't fix up the device tree.

Fixes: b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 45a5ae5d2027..21ec073f4d51 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -286,7 +286,7 @@ max98357a: max98357a {
 
 	sound: sound {
 		compatible = "rockchip,rk3399-gru-sound";
-		rockchip,cpu = <&i2s0 &i2s2>;
+		rockchip,cpu = <&i2s0 &spdif>;
 	};
 };
 
@@ -437,10 +437,6 @@ &i2s0 {
 	status = "okay";
 };
 
-&i2s2 {
-	status = "okay";
-};
-
 &io_domains {
 	status = "okay";
 
@@ -537,6 +533,10 @@ &sdmmc {
 	vqmmc-supply = <&ppvar_sd_card_io>;
 };
 
+&spdif {
+	status = "okay";
+};
+
 &spi1 {
 	status = "okay";
 
-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 12:16:51 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 12:16:51 -0800
Subject: [PATCH 2/3] drm/rockchip: cdn-dp: Support HDMI codec plug-change
 callback
In-Reply-To: <20220114201652.3875838-1-briannorris@chromium.org>
References: <20220114201652.3875838-1-briannorris@chromium.org>
Message-ID: <20220114121515.2.I20d754a1228aa5c51a18c8eb15a2c60dec25b639@changeid>

Some audio servers like to monitor a jack device (perhaps combined with
EDID, for audio-presence info) to determine DP/HDMI audio presence.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 28 ++++++++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  4 ++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 16497c31d9f9..edd6a1fc46cd 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -586,6 +586,13 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
 }
 
+static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
+					       bool plugged)
+{
+	if (dp->codec_dev)
+		dp->plugged_cb(dp->codec_dev, plugged);
+}
+
 static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 {
 	struct cdn_dp_device *dp = encoder_to_dp(encoder);
@@ -641,6 +648,9 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 		DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
 		goto out;
 	}
+
+	cdn_dp_audio_handle_plugged_change(dp, true);
+
 out:
 	mutex_unlock(&dp->lock);
 }
@@ -651,6 +661,8 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
 	int ret;
 
 	mutex_lock(&dp->lock);
+	cdn_dp_audio_handle_plugged_change(dp, false);
+
 	if (dp->active) {
 		ret = cdn_dp_disable(dp);
 		if (ret) {
@@ -846,11 +858,27 @@ static int cdn_dp_audio_get_eld(struct device *dev, void *data,
 	return 0;
 }
 
+static int cdn_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct cdn_dp_device *dp = dev_get_drvdata(dev);
+
+	mutex_lock(&dp->lock);
+	dp->plugged_cb = fn;
+	dp->codec_dev = codec_dev;
+	cdn_dp_audio_handle_plugged_change(dp, dp->connected);
+	mutex_unlock(&dp->lock);
+
+	return 0;
+}
+
 static const struct hdmi_codec_ops audio_codec_ops = {
 	.hw_params = cdn_dp_audio_hw_params,
 	.audio_shutdown = cdn_dp_audio_shutdown,
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
+	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
 	.no_capture_mute = 1,
 };
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 81ac9b658a70..d808a9de45ed 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -10,6 +10,7 @@
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <sound/hdmi-codec.h>
 
 #include "rockchip_drm_drv.h"
 
@@ -101,5 +102,8 @@ struct cdn_dp_device {
 
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	bool sink_has_audio;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
 };
 #endif  /* _CDN_DP_CORE_H */
-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 12:16:52 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 12:16:52 -0800
Subject: [PATCH 3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
In-Reply-To: <20220114201652.3875838-1-briannorris@chromium.org>
References: <20220114201652.3875838-1-briannorris@chromium.org>
Message-ID: <20220114121515.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>

Now that the cdn-dp driver supports plug-change callbacks, let's wire it
up.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

 sound/soc/rockchip/rk3399_gru_sound.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index e2d52d8d0ff9..eeef3ed70037 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -164,6 +164,25 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static struct snd_soc_jack cdn_dp_card_jack;
+
+static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+	struct snd_soc_card *card = rtd->card;
+	int ret;
+
+	/* Enable jack detection. */
+	ret = snd_soc_card_jack_new(card, "DP Jack", SND_JACK_LINEOUT,
+				    &cdn_dp_card_jack, NULL, 0);
+	if (ret) {
+		dev_err(card->dev, "Can't create DP Jack %d\n", ret);
+		return ret;
+	}
+
+	return snd_soc_component_set_jack(component, &cdn_dp_card_jack, NULL);
+}
+
 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
@@ -315,6 +334,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
 	[DAILINK_CDNDP] = {
 		.name = "DP",
 		.stream_name = "DP PCM",
+		.init = rockchip_sound_cdndp_init,
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 			SND_SOC_DAIFMT_CBS_CFS,
 		SND_SOC_DAILINK_REG(cdndp),
-- 
2.34.1.703.g22d0c6ccf7-goog



From semen.protsenko at linaro.org  Fri Jan 14 12:37:57 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 14 Jan 2022 22:37:57 +0200
Subject: [PATCH] pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and
 CMGP gpios
Message-ID: <20220114203757.4860-1-semen.protsenko@linaro.org>

GPIO_ALIVE and GPIO_CMGP blocks in Exynos850 SoC don't have EINT
capabilities (like EINT_SVC register), and there are no corresponding
interrupts wired to GIC. Instead those blocks have wake-up interrupts
for each pin. The ".eint_gpio_init" callbacks were specified by mistake
for these blocks, when porting pinctrl code from downstream kernel. That
leads to error messages like this:

    samsung-pinctrl 11850000.pinctrl: irq number not available

Remove ".eint_gpio_init" for pinctrl_alive and pinctrl_gpmc to fix this
error. This change doesn't affect proper interrupt handling for related
pins, as all those pins are handled in ".eint_wkup_init".

Fixes: cdd3d945dcec ("pinctrl: samsung: Add Exynos850 SoC specific data")
Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/pinctrl/samsung/pinctrl-exynos-arm64.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 2e490e7696f4..4102ce955bd7 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -585,13 +585,11 @@ static const struct samsung_pin_ctrl exynos850_pin_ctrl[] __initconst = {
 		/* pin-controller instance 0 ALIVE data */
 		.pin_banks	= exynos850_pin_banks0,
 		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks0),
-		.eint_gpio_init = exynos_eint_gpio_init,
 		.eint_wkup_init = exynos_eint_wkup_init,
 	}, {
 		/* pin-controller instance 1 CMGP data */
 		.pin_banks	= exynos850_pin_banks1,
 		.nr_banks	= ARRAY_SIZE(exynos850_pin_banks1),
-		.eint_gpio_init = exynos_eint_gpio_init,
 		.eint_wkup_init = exynos_eint_wkup_init,
 	}, {
 		/* pin-controller instance 2 AUD data */
-- 
2.30.2



From briannorris at chromium.org  Fri Jan 14 13:01:22 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 13:01:22 -0800
Subject: [PATCH 1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF
 output
In-Reply-To: <20220114121515.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>
References: <20220114201652.3875838-1-briannorris@chromium.org>
 <20220114121515.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>
Message-ID: <CA+ASDXMO3sPta-vhMCqAPRFFkNa-nmY+wK6PXJaSUEXBHETG+A@mail.gmail.com>

Sorry to send a self-reply so quickly, but I noticed an error and want
to make sure this doesn't get merged _too_ quickly before I get to
send a revision! See below:

On Fri, Jan 14, 2022 at 12:17 PM Brian Norris <briannorris at chromium.org> wrote:
>
> Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> switched the platform to SPDIF, but we didn't fix up the device tree.
>
> Fixes: b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
>
>  arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
> index 45a5ae5d2027..21ec073f4d51 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi

> +&spdif {
> +       status = "okay";

I need to fix up the pinctrl settings here. rk3399.dtsi has a default
that is incorrect. That's OK for several variants (Kevin and Bob,
where the pin is actually unconnected), but it breaks Scarlet (where
the pin in question is actually connected to something else).

I'll send a v2 after waiting a bit, in case there are other comments
worth addressing at the same time.

Brian

> +};


From reijiw at google.com  Fri Jan 14 13:51:07 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Fri, 14 Jan 2022 13:51:07 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YeBfj89mIf8SezfD@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
Message-ID: <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>

On Thu, Jan 13, 2022 at 9:21 AM Sean Christopherson <seanjc at google.com> wrote:
>
> On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> > On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
> > > Perhaps it would help if you explained *why* you are doing this. It
> > > sounds like you are either trying to protect against a malicious
> > > userspace, or you are trying to keep userspace from doing something
> > > stupid. In general, kvm only enforces constraints that are necessary
> > > to protect the host. If that's what you're doing, I don't understand
> > > why live migration doesn't provide an end-run around your protections.
> > It's mainly to safeguard the guests. With respect to migration, KVM
> > and the userspace are collectively playing a role here. It's up to the
> > userspace to ensure that the registers are configured the same across
> > migrations and KVM ensures that the userspace doesn't modify the
> > registers after KVM_RUN so that they don't see features turned OFF/ON
> > during execution. I'm not sure if it falls into the definition of
> > protecting the host. Do you see a value in adding this extra
> > protection from KVM?
>
> Short answer: probably not?
>
> There is precedent for disallowing userspace from doing stupid things, but that's
> either for KVM's protection (as Jim pointed out), or because KVM can't honor the
> change, e.g. x86 is currently in the process of disallowing most CPUID changes
> after KVM_RUN because KVM itself consumes the CPUID information and KVM doesn't
> support updating some of it's own internal state (because removing features like
> GB hugepage support is nonsensical and would require a large pile of complicated,
> messy code).
>
> Restricing CPUID changes does offer some "protection" to the guest, but that's
> not the goal.  E.g. KVM won't detect CPUID misconfiguration in the migration
> case, and trying to do so is a fool's errand.
>
> If restricting updates in the arm64 is necessary to ensure KVM provides sane
> behavior, then it could be justified.  But if it's purely a sanity check on
> behalf of the guest, then it's not justified.

The pseudo firmware hvc registers, which this series are adding, are
used by KVM to identify available hvc features for the guest, and not
directly exposed to the guest as registers.
The ways the KVM code in the series consumes the registers' values are
very limited, and no KVM data/state is created based on their values.
But, as the code that consumes the registers grows in the future,
I wouldn't be surprised if KVM consumes them differently than it does
now (e.g. create another data structure based on the register values).
I'm not sure though :)

The restriction, with which KVM doesn't need to worry about the changes
in the registers after KVM_RUN, could potentially protect or be useful
to protect KVM and simplify future changes/maintenance of the KVM codes
that consumes the values.
I thought this was one of the reasons for having the restriction.

Thanks,
Reiji


From sboyd at kernel.org  Fri Jan 14 14:19:28 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:19:28 -0800
Subject: [PATCH 3/3] clk: mediatek: support COMMON_CLK_MT8192 module build
In-Reply-To: <20220114083511.18906-1-miles.chen@mediatek.com>
References: <20220114021131.1F7C9C36AEA@smtp.kernel.org>
 <20220114083511.18906-1-miles.chen@mediatek.com>
Message-ID: <20220114221930.660B5C36AE9@smtp.kernel.org>

Quoting Miles Chen (2022-01-14 00:35:10)
> Hi,
> 
> >Have you tried removing the modules? And then reloading them? I also see
> 
> Thanks for the comment.
> I did not try it because we do not unload our clk modules.
> After testing I understand that the clock driver does not unregister clks so 
> we cannot remove then unload it.
> 
> I think I have to add some unregister logic to these drivers.

Yes

> 
> >that mtk_clk_simple_probe() doesn't actually unregister anything, it
> >just frees some allocations. Please fix this before making these
> >modules.
> 
> You meant that mtk_clk_simple_probe() has no unregister logic in error path?
> 

Yes


From sboyd at kernel.org  Fri Jan 14 14:20:12 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:20:12 -0800
Subject: [PATCH] clk: zynqmp: warn always when a clock op fails
In-Reply-To: <20220114081442.GR26783@pengutronix.de>
References: <20220112141229.700708-1-m.tretter@pengutronix.de>
 <20220112202937.034D9C36AE5@smtp.kernel.org>
 <20220114081442.GR26783@pengutronix.de>
Message-ID: <20220114222013.F35AAC36AE7@smtp.kernel.org>

Quoting Michael Tretter (2022-01-14 00:14:42)
> On Wed, 12 Jan 2022 12:29:35 -0800, Stephen Boyd wrote:
> > Quoting Michael Tretter (2022-01-12 06:12:29)
> > > The warning that a clock operation failed is only printed once. However,
> > > the function is called for various different clocks. The limit hides
> > > warnings if different clock are affected by the failures.
> > > 
> > > Print the warning every time when a clock operation fails.
> > > 
> > > Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> > > ---
> > >  drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
> > >  drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
> > >  drivers/clk/zynqmp/divider.c         | 12 +++++------
> > >  drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
> > >  4 files changed, 32 insertions(+), 32 deletions(-)
> > > 
> > > diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > > index 565ed67a0430..0d9a39110f29 100644
> > > --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > > +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> > > @@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
> > >         ret = zynqmp_pm_clock_enable(clk_id);
> > >  
> > >         if (ret)
> > > -               pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
> > > -                            __func__, clk_name, ret);
> > > +               pr_warn("%s() clock enable failed for %s (id %d), ret = %d\n",
> > > +                       __func__, clk_name, clk_id, ret);
> > 
> > Can we just remove these prints entirely? The driver that calls
> > clk_enable() should be checking the return value and taking proper
> > action. What is the user going to do with these messages?
> > 
> 
> The clocks are handled by a firmware, which checks if the Linux system has the
> permission to change certain clocks. The warnings help users to identify an
> unexpected configuration of the firmware. However, I guess it would make sense
> to change the warnings to pr_debug.
> 

Sure pr_debug() sounds fine.


From sboyd at kernel.org  Fri Jan 14 14:55:30 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:55:30 -0800
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>
Message-ID: <20220114225532.B0C6DC36AEA@smtp.kernel.org>

Quoting Robin Murphy (2022-01-14 05:23:51)
> On 2022-01-10 18:13, Alyssa Rosenzweig wrote:
> > Set a mysterious chicken bit in the MT8192 clock driver (!) to get the
> > Mali GPU on MT8192 to work. This workaround is from the downstream Mali
> > driver shipped in ChromeOS. The change there is unsuitable for mainline
> > but good as a reference for the hardware behaviour:
> > 
> > https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5
> > 
> > That links to an internal Google issue tracker which I assume has more
> > information on the bug. I would appreciate if someone from Google or
> > MediaTek could explain what this change actually does and why it's
> > necessary on MT8192.
> > 
> > At any rate, this register logically belongs to the MT8192 "infra" clock
> > device, so it makes sense to set it there too. This avoids adding any
> > platform-specific hacks to the 3D driver, either mainline (Panfrost) or
> > legacy (kbase).
> 
> Does this really have anything to do with clocks? My (uninformed) 
> impression is that the infracfg blocks are general amalgamations of 
> configuration registers that simply happen to contain clock and reset 
> controls among other functionality. In particular, "ACP" usually refers 
> to the Accelerator Coherency Port of a CPU cluster or DSU, and given the 
> stated symptom of the issue affected by it, my first guess would be that 
> this bit might indeed control routing of GPU traffic either to the ACP 
> or the (presumably non-coherent) main interconnect.
> 
> If that is the case, I think this would logically belong as a 
> SoC-specific quirk in panfrost, where we'd need to retrieve the syscon 
> regmap for ourselves (see around line 800 of drivers/iommu/mtk_iommu.c 
> for a similar example).

What's the benefit of putting this into the GPU driver? Is it going to
be runtime managed? It seems most logically related to the SoC or
interconnect, for which there isn't any device driver but there could
be.


From sboyd at kernel.org  Fri Jan 14 14:56:58 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:56:58 -0800
Subject: [PATCH v7 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20220114105100.im6gmkt6fjl2aiwl@pali>
References: <20210930095838.28145-1-pali@kernel.org>
 <20211103214209.azo2z3z4gy7aj5hu@pali> <87ee6bm9hn.fsf@BL-laptop>
 <20220114105100.im6gmkt6fjl2aiwl@pali>
Message-ID: <20220114225659.D5D79C36AE9@smtp.kernel.org>

Quoting Pali Roh?r (2022-01-14 02:51:00)
> Hello Stephen!
> 
> On Friday 17 December 2021 18:23:00 Gregory CLEMENT wrote:
> > Hello Pali,
> > 
> > > On Thursday 30 September 2021 11:58:32 Pali Roh?r wrote:
> > >> This patch series add support for baudrates higher than 230400 on
> > >> Marvell Armada 37xx boards.
> > >
> > > Stephen, Gregory, are there any issues with this patch series?
> > 
> > I am not found of these changes but let's apply it as I didn't take time
> > to do a better review.
> > 
> > However I can't apply the dt part if the driver is not merged.
> 
> Stephen, are there any issues with driver (non-DT) part changes in this
> patch series? If not, could you please merge them? This patch series is
> here on the list since September without any request for change...

Oh I missed this thread. I thought it was going to be resent.

> 
> We would really like to see support for higher baudrates for Armada 3720
> platforms in mainline kernel.

If we're adding new support why can't we break with backwards
compatibility for the binding and do it a different way?


From sboyd at kernel.org  Fri Jan 14 14:59:55 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 14:59:55 -0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
Message-ID: <20220114225957.285ADC36AE7@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 19:06:07)
> Hi Stephen,
> 
> Thanks for your quick response.
> 
> On 2022/1/14 5:29, Stephen Boyd wrote:
> > [ EXTERNAL EMAIL ]
> > 
> > Quoting Liang Yang (2022-01-13 03:57:44)
> >> Document the MMC sub clock controller driver, the potential consumer
> >> of this driver is MMC or NAND. Also add four clock bindings IDs which
> >> provided by this driver.
> >>
> >> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> >> ---
> >>   .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
> >>   include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
> >>   2 files changed, 78 insertions(+)
> >>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> >>
> >> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >> new file mode 100644
> >> index 000000000000..a274c3d5fc2e
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
> >> @@ -0,0 +1,64 @@
> >> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
> >> +
> >> +maintainers:
> >> +  - jianxin.pan at amlogic.com
> >> +  - liang.yang at amlogic.com
> >> +
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - "amlogic,axg-mmc-clkc", "syscon"
> > 
> > Why is it a syscon?
> 
> The register documented by reg is shared with SD/eMMC controller port C, 
> and it need to be ops on NFC driver.
> 

Is this the case where the clk is inside the SD/eMMC controller? Can the
mmc driver register the clk controller from there and pass it an iomem
pointer to poke clks?


From sboyd at kernel.org  Fri Jan 14 15:01:28 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 15:01:28 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
Message-ID: <20220114230130.35EAAC36AE7@smtp.kernel.org>

Quoting Liang Yang (2022-01-13 21:14:46)
> On 2022/1/14 5:35, Stephen Boyd wrote:
> > Quoting Liang Yang (2022-01-13 03:57:45)
> >> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> >> new file mode 100644
> >> index 000000000000..f53977f61390
> >> --- /dev/null
> >> +++ b/drivers/clk/meson/mmc-clkc.c
> >> @@ -0,0 +1,300 @@
[..]
> >> +
> >> +static int mmc_clkc_probe(struct platform_device *pdev)
> >> +{
> >> +       struct clk_hw_onecell_data *onecell_data;
> >> +       struct device *dev = &pdev->dev;
> >> +       struct mmc_clkc_data *data;
> >> +       struct regmap *map;
> >> +       struct clk_regmap *clk, *core;
> >> +       struct meson_sclk_div_data *div_data;
> >> +
> >> +       /*cast to drop the const in match->data*/
> > 
> > Space after *, also why do we need to cast away const? The user of this
> > pointer passes it all the way down to mmc_clkc_register_clk() which
> > could take the data as const void pointer and decide to cast away const
> > there.
> 
> if use 'const' here, it will report a warning:
> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const? 
> qualifier from pointer targe
> t type [-Werror=discarded-qualifiers] 
> 
>    data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);

Of course. The type declaration up above needs const added to it.


From briannorris at chromium.org  Fri Jan 14 15:02:06 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 15:02:06 -0800
Subject: [PATCH v2 0/3] (Re)enable DP/HDMI audio for RK3399 Gru
Message-ID: <20220114230209.4091727-1-briannorris@chromium.org>

This series fixes DP/HDMI audio for RK3399 Gru systems.

First, there was a regression with the switch to SPDIF. Patch 1 can be
taken separately as a regression fix if desired. But it's not quite so
useful (at least on Chrome OS systems) without the second part.

Second, jack detection was never upstreamed, because the hdmi-codec
dependencies were still being worked out when this platform was first
supported.

Patches cover a few subsystems. Perhaps this is something for arm-soc?

Changes in v2:
 - (Un)set pinctrl, because the default assumes we're routing out to
   external pins

Brian Norris (3):
  arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
  drm/rockchip: cdn-dp: Support HDMI codec plug-change callback
  ASoC: rk3399_gru_sound: Wire up DP jack detection

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 17 ++++++++----
 drivers/gpu/drm/rockchip/cdn-dp-core.c       | 28 ++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-core.h       |  4 +++
 sound/soc/rockchip/rk3399_gru_sound.c        | 20 ++++++++++++++
 4 files changed, 64 insertions(+), 5 deletions(-)

-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 15:02:07 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 15:02:07 -0800
Subject: [PATCH v2 1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF
 output
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>
References: <20220114230209.4091727-1-briannorris@chromium.org>
Message-ID: <20220114150129.v2.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>

Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
switched the platform to SPDIF, but we didn't fix up the device tree.

Drop the pinctrl settings, because the 'spdif_bus' pins are either:
 * unused (on kevin, bob), so the settings is ~harmless
 * used by a different function (on scarlet), which causes probe
   failures (!!)

Fixes: b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - (Un)set pinctrl, because the default assumes we're routing out to
   external pins

 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 45a5ae5d2027..162f08bca0d4 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -286,7 +286,7 @@ max98357a: max98357a {
 
 	sound: sound {
 		compatible = "rockchip,rk3399-gru-sound";
-		rockchip,cpu = <&i2s0 &i2s2>;
+		rockchip,cpu = <&i2s0 &spdif>;
 	};
 };
 
@@ -437,10 +437,6 @@ &i2s0 {
 	status = "okay";
 };
 
-&i2s2 {
-	status = "okay";
-};
-
 &io_domains {
 	status = "okay";
 
@@ -537,6 +533,17 @@ &sdmmc {
 	vqmmc-supply = <&ppvar_sd_card_io>;
 };
 
+&spdif {
+	status = "okay";
+
+	/*
+	 * SPDIF is routed internally to DP; we either don't use these pins, or
+	 * mux them to something else.
+	 */
+	/delete-property/ pinctrl-0;
+	/delete-property/ pinctrl-names;
+};
+
 &spi1 {
 	status = "okay";
 
-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 15:02:08 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 15:02:08 -0800
Subject: [PATCH v2 2/3] drm/rockchip: cdn-dp: Support HDMI codec plug-change
 callback
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>
References: <20220114230209.4091727-1-briannorris@chromium.org>
Message-ID: <20220114150129.v2.2.I20d754a1228aa5c51a18c8eb15a2c60dec25b639@changeid>

Some audio servers like to monitor a jack device (perhaps combined with
EDID, for audio-presence info) to determine DP/HDMI audio presence.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 drivers/gpu/drm/rockchip/cdn-dp-core.c | 28 ++++++++++++++++++++++++++
 drivers/gpu/drm/rockchip/cdn-dp-core.h |  4 ++++
 2 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 16497c31d9f9..edd6a1fc46cd 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -586,6 +586,13 @@ static bool cdn_dp_check_link_status(struct cdn_dp_device *dp)
 	return drm_dp_channel_eq_ok(link_status, min(port->lanes, sink_lanes));
 }
 
+static void cdn_dp_audio_handle_plugged_change(struct cdn_dp_device *dp,
+					       bool plugged)
+{
+	if (dp->codec_dev)
+		dp->plugged_cb(dp->codec_dev, plugged);
+}
+
 static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 {
 	struct cdn_dp_device *dp = encoder_to_dp(encoder);
@@ -641,6 +648,9 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
 		DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
 		goto out;
 	}
+
+	cdn_dp_audio_handle_plugged_change(dp, true);
+
 out:
 	mutex_unlock(&dp->lock);
 }
@@ -651,6 +661,8 @@ static void cdn_dp_encoder_disable(struct drm_encoder *encoder)
 	int ret;
 
 	mutex_lock(&dp->lock);
+	cdn_dp_audio_handle_plugged_change(dp, false);
+
 	if (dp->active) {
 		ret = cdn_dp_disable(dp);
 		if (ret) {
@@ -846,11 +858,27 @@ static int cdn_dp_audio_get_eld(struct device *dev, void *data,
 	return 0;
 }
 
+static int cdn_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+					hdmi_codec_plugged_cb fn,
+					struct device *codec_dev)
+{
+	struct cdn_dp_device *dp = dev_get_drvdata(dev);
+
+	mutex_lock(&dp->lock);
+	dp->plugged_cb = fn;
+	dp->codec_dev = codec_dev;
+	cdn_dp_audio_handle_plugged_change(dp, dp->connected);
+	mutex_unlock(&dp->lock);
+
+	return 0;
+}
+
 static const struct hdmi_codec_ops audio_codec_ops = {
 	.hw_params = cdn_dp_audio_hw_params,
 	.audio_shutdown = cdn_dp_audio_shutdown,
 	.mute_stream = cdn_dp_audio_mute_stream,
 	.get_eld = cdn_dp_audio_get_eld,
+	.hook_plugged_cb = cdn_dp_audio_hook_plugged_cb,
 	.no_capture_mute = 1,
 };
 
diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
index 81ac9b658a70..d808a9de45ed 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
@@ -10,6 +10,7 @@
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_panel.h>
 #include <drm/drm_probe_helper.h>
+#include <sound/hdmi-codec.h>
 
 #include "rockchip_drm_drv.h"
 
@@ -101,5 +102,8 @@ struct cdn_dp_device {
 
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	bool sink_has_audio;
+
+	hdmi_codec_plugged_cb plugged_cb;
+	struct device *codec_dev;
 };
 #endif  /* _CDN_DP_CORE_H */
-- 
2.34.1.703.g22d0c6ccf7-goog



From briannorris at chromium.org  Fri Jan 14 15:02:09 2022
From: briannorris at chromium.org (Brian Norris)
Date: Fri, 14 Jan 2022 15:02:09 -0800
Subject: [PATCH v2 3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>
References: <20220114230209.4091727-1-briannorris@chromium.org>
Message-ID: <20220114150129.v2.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>

Now that the cdn-dp driver supports plug-change callbacks, let's wire it
up.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 sound/soc/rockchip/rk3399_gru_sound.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index e2d52d8d0ff9..eeef3ed70037 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -164,6 +164,25 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
 	return 0;
 }
 
+static struct snd_soc_jack cdn_dp_card_jack;
+
+static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+	struct snd_soc_card *card = rtd->card;
+	int ret;
+
+	/* Enable jack detection. */
+	ret = snd_soc_card_jack_new(card, "DP Jack", SND_JACK_LINEOUT,
+				    &cdn_dp_card_jack, NULL, 0);
+	if (ret) {
+		dev_err(card->dev, "Can't create DP Jack %d\n", ret);
+		return ret;
+	}
+
+	return snd_soc_component_set_jack(component, &cdn_dp_card_jack, NULL);
+}
+
 static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
@@ -315,6 +334,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
 	[DAILINK_CDNDP] = {
 		.name = "DP",
 		.stream_name = "DP PCM",
+		.init = rockchip_sound_cdndp_init,
 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 			SND_SOC_DAIFMT_CBS_CFS,
 		SND_SOC_DAILINK_REG(cdndp),
-- 
2.34.1.703.g22d0c6ccf7-goog



From pali at kernel.org  Fri Jan 14 15:05:49 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 15 Jan 2022 00:05:49 +0100
Subject: [PATCH v7 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20220114225659.D5D79C36AE9@smtp.kernel.org>
References: <20210930095838.28145-1-pali@kernel.org>
 <20211103214209.azo2z3z4gy7aj5hu@pali> <87ee6bm9hn.fsf@BL-laptop>
 <20220114105100.im6gmkt6fjl2aiwl@pali>
 <20220114225659.D5D79C36AE9@smtp.kernel.org>
Message-ID: <20220114230549.56co4qcpnq32muwj@pali>

On Friday 14 January 2022 14:56:58 Stephen Boyd wrote:
> Quoting Pali Roh?r (2022-01-14 02:51:00)
> > Hello Stephen!
> > 
> > On Friday 17 December 2021 18:23:00 Gregory CLEMENT wrote:
> > > Hello Pali,
> > > 
> > > > On Thursday 30 September 2021 11:58:32 Pali Roh?r wrote:
> > > >> This patch series add support for baudrates higher than 230400 on
> > > >> Marvell Armada 37xx boards.
> > > >
> > > > Stephen, Gregory, are there any issues with this patch series?
> > > 
> > > I am not found of these changes but let's apply it as I didn't take time
> > > to do a better review.
> > > 
> > > However I can't apply the dt part if the driver is not merged.
> > 
> > Stephen, are there any issues with driver (non-DT) part changes in this
> > patch series? If not, could you please merge them? This patch series is
> > here on the list since September without any request for change...
> 
> Oh I missed this thread. I thought it was going to be resent.
> 
> > 
> > We would really like to see support for higher baudrates for Armada 3720
> > platforms in mainline kernel.
> 
> If we're adding new support why can't we break with backwards
> compatibility for the binding and do it a different way?

Because DTS are backwards compatible. I was told more times that kernel
drivers should work correctly with older DTS files. On some boards are
DTB files provided by bootloader and they do not use in-kernel DTS
files.


From sboyd at kernel.org  Fri Jan 14 15:08:37 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 15:08:37 -0800
Subject: [PATCH v8 11/11] clk: scmi: Support atomic clock enable/disable
 API
In-Reply-To: <20211220195646.44498-12-cristian.marussi@arm.com>
References: <20211220195646.44498-1-cristian.marussi@arm.com>
 <20211220195646.44498-12-cristian.marussi@arm.com>
Message-ID: <20220114230839.ABD63C36AE9@smtp.kernel.org>

Quoting Cristian Marussi (2021-12-20 11:56:46)
> Support also atomic enable/disable clk_ops beside the bare non-atomic one
> (prepare/unprepare) when the underlying SCMI transport is configured to
> support atomic transactions for synchronous commands.
> 
> Cc: Michael Turquette <mturquette at baylibre.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
> NOTE THAT STILL THERE'S NO FINE GRAIN CONTROL OVER SELECTION
> OF WHICH CLOCK DEVICES CAN SUPPORT ATOMIC AND WHICH SHOULD NOT
> BASED ON CLOCK DEVICES ENABLE LATENCY.
> THIS HAS STILL TO BE ADDED IN SCMI PROTOCOL SPEC.

Why are you yelling on the internet? :-) I guess I need to ack this.

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Fri Jan 14 15:16:55 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Fri, 14 Jan 2022 15:16:55 -0800
Subject: [PATCH v7 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20220114230549.56co4qcpnq32muwj@pali>
References: <20210930095838.28145-1-pali@kernel.org>
 <20211103214209.azo2z3z4gy7aj5hu@pali> <87ee6bm9hn.fsf@BL-laptop>
 <20220114105100.im6gmkt6fjl2aiwl@pali>
 <20220114225659.D5D79C36AE9@smtp.kernel.org>
 <20220114230549.56co4qcpnq32muwj@pali>
Message-ID: <20220114231657.AB353C36AE7@smtp.kernel.org>

Quoting Pali Roh?r (2022-01-14 15:05:49)
> On Friday 14 January 2022 14:56:58 Stephen Boyd wrote:
> > 
> > If we're adding new support why can't we break with backwards
> > compatibility for the binding and do it a different way?
> 
> Because DTS are backwards compatible. I was told more times that kernel
> drivers should work correctly with older DTS files. On some boards are
> DTB files provided by bootloader and they do not use in-kernel DTS
> files.

I'm not suggesting to break the kernel driver when used with older DTBs.
New features are fair game to change the compatible string and do
something different. If the user wants the new feature they update their
DTB. We shouldn't be constrained by backwards compatibility here.


From pali at kernel.org  Fri Jan 14 15:20:46 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 15 Jan 2022 00:20:46 +0100
Subject: [PATCH v7 0/6] serial: mvebu-uart: Support for higher baudrates
In-Reply-To: <20220114231657.AB353C36AE7@smtp.kernel.org>
References: <20210930095838.28145-1-pali@kernel.org>
 <20211103214209.azo2z3z4gy7aj5hu@pali> <87ee6bm9hn.fsf@BL-laptop>
 <20220114105100.im6gmkt6fjl2aiwl@pali>
 <20220114225659.D5D79C36AE9@smtp.kernel.org>
 <20220114230549.56co4qcpnq32muwj@pali>
 <20220114231657.AB353C36AE7@smtp.kernel.org>
Message-ID: <20220114232046.ucpxsdiitow5huwj@pali>

On Friday 14 January 2022 15:16:55 Stephen Boyd wrote:
> Quoting Pali Roh?r (2022-01-14 15:05:49)
> > On Friday 14 January 2022 14:56:58 Stephen Boyd wrote:
> > > 
> > > If we're adding new support why can't we break with backwards
> > > compatibility for the binding and do it a different way?
> > 
> > Because DTS are backwards compatible. I was told more times that kernel
> > drivers should work correctly with older DTS files. On some boards are
> > DTB files provided by bootloader and they do not use in-kernel DTS
> > files.
> 
> I'm not suggesting to break the kernel driver when used with older DTBs.
> New features are fair game to change the compatible string and do
> something different. If the user wants the new feature they update their
> DTB. We shouldn't be constrained by backwards compatibility here.

And what do you suggest to do? Separate UART0 and UART1 nodes are still
needed because as Mark wrote stdin-path and stdout-patch could be
different.


From fllinden at amazon.com  Fri Jan 14 15:27:29 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Fri, 14 Jan 2022 23:27:29 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <YeBiV8fuCCLWyHYb@kernel.org>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com> <Yd1cnquQFZoNE7FP@kernel.org>
 <20220111204441.GA36458@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
 <YeBiV8fuCCLWyHYb@kernel.org>
Message-ID: <20220114232729.GA35066@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>

On Thu, Jan 13, 2022 at 07:33:11PM +0200, Mike Rapoport wrote:
> On Tue, Jan 11, 2022 at 08:44:41PM +0000, Frank van der Linden wrote:
> > On Tue, Jan 11, 2022 at 12:31:58PM +0200, Mike Rapoport wrote:
> > > > --- a/include/linux/memblock.h
> > > > +++ b/include/linux/memblock.h
> > > > @@ -481,6 +481,8 @@ phys_addr_t memblock_reserved_size(void);
> > > >  phys_addr_t memblock_start_of_DRAM(void);
> > > >  phys_addr_t memblock_end_of_DRAM(void);
> > > >  void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > > > +void memblock_set_usable_range(phys_addr_t base, phys_addr_t size);
> > > > +void memblock_enforce_usable_range(void);
> > > >  void memblock_cap_memory_range(phys_addr_t base, phys_addr_t size);
> > > >  void memblock_mem_limit_remove_map(phys_addr_t limit);
> > >
> > > We already have 3 very similar interfaces that deal with memory capping.
> > > Now you suggest to add fourth that will "generically" solve a single use
> > > case of DT, EFI and kdump interaction on arm64.
> > >
> > > Looks like a workaround for a fundamental issue of incompatibility between
> > > DT and EFI wrt memory registration.
> >
> > Yep, I figured this would be the main argument against this - arm64
> > already added several other more-or-less special cased interfaces over
> > time.
> >
> > I'm more than happy to solve this in a different way.
> >
> > What would you suggest:
> >
> > 1) Try to merge the similar interfaces in to one.
> > 2) Just deal with it at a lower (arm64) level?
> > 3) Some other way?
> 
> We've discussed this with Ard on IRC, and our conclusion was that on arm64
> kdump kernel should have memblock.memory exactly the same as the normal
> kernel. Then, the memory outside usable-memory-range should be reserved so
> that kdump kernel won't step over it.
> 
> With that, simple (untested) patch below could be what we need:
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index bdca35284ceb..371418dffaf1 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -1275,7 +1275,8 @@ void __init early_init_dt_scan_nodes(void)
>         of_scan_flat_dt(early_init_dt_scan_memory, NULL);
> 
>         /* Handle linux,usable-memory-range property */
> -       memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
> +       memblock_reserve(0, cap_mem_addr);
> +       memblock_reserve(cap_mem_addr + cap_mem_size, PHYS_ADDR_MAX);
>  }
> 
>  bool __init early_init_dt_scan(void *params)

Ok, tested this on 5.17-rc, and it's working OK there. Main kernel has
32G, crash kernel gets 512M:

Main kernel:

[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000040000000-0x00000000ffffffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   [mem 0x0000000100000000-0x0000000b96ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000040000000-0x00000000786effff]
[    0.000000]   node   0: [mem 0x00000000786f0000-0x000000007872ffff]
[    0.000000]   node   0: [mem 0x0000000078730000-0x000000007bbfffff]
[    0.000000]   node   0: [mem 0x000000007bc00000-0x000000007bfdffff]
[    0.000000]   node   0: [mem 0x000000007bfe0000-0x000000007fffffff]
[    0.000000]   node   0: [mem 0x0000000400000000-0x0000000b96ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000040000000-0x0000000b96ffffff]
[    0.000000] On node 0, zone Normal: 4096 pages in unavailable ranges
[    0.000000] cma: Reserved 64 MiB at 0x000000007c000000
[    0.000000] crashkernel reserved: 0x0000000054400000 - 0x0000000074400000 (512 MB)


Crash kernel:

[    0.000000] Zone ranges:
[    0.000000]   DMA      [mem 0x0000000054400000-0x000000007bfdffff]
[    0.000000]   DMA32    empty
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000054400000-0x00000000743fffff]
[    0.000000]   node   0: [mem 0x00000000786f0000-0x000000007872ffff]
[    0.000000]   node   0: [mem 0x000000007bc00000-0x000000007bfdffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000054400000-0x000000007bfdffff]
[    0.000000] On node 0, zone DMA: 17408 pages in unavailable ranges
[    0.000000] On node 0, zone DMA: 17136 pages in unavailable ranges
[    0.000000] On node 0, zone DMA: 13520 pages in unavailable ranges
[    0.000000] On node 0, zone DMA: 16416 pages in unavailable ranges

Not sure why I had trouble with the same on 5.15, I'll have to look
at that again. But this seems fine for 5.16+

Thanks,

- Frank


From sean.anderson at seco.com  Fri Jan 14 15:38:58 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Fri, 14 Jan 2022 18:38:58 -0500
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
Message-ID: <20220114233904.907918-1-sean.anderson@seco.com>

This is a rework of patches 3-5 of [1]. It attempts to correctly program
REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
we no longer need a special property duplicating this configuration,
snps,ref-clock-period-ns is deprecated.

Please test this! Patches 3/4 in this series have the effect of
programming REFCLKPER and REFCLK_FLADJ on boards which already configure
the "ref" clock. I have build tested, but not much else.

[1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/


Sean Anderson (6):
  dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
  usb: dwc3: Get clocks individually
  usb: dwc3: Calculate REFCLKPER based on reference clock
  usb: dwc3: Handle fractional reference clocks
  arm64: dts: zynqmp: Move USB clocks to dwc3 node
  arm64: dts: ipq6018: Use reference clock to set dwc3 period

 .../devicetree/bindings/usb/snps,dwc3.yaml    |  7 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  3 +-
 .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  4 +-
 drivers/usb/dwc3/core.c                       | 98 ++++++++++++++++---
 drivers/usb/dwc3/core.h                       |  6 +-
 6 files changed, 98 insertions(+), 24 deletions(-)

-- 
2.25.1



From sean.anderson at seco.com  Fri Jan 14 15:39:03 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Fri, 14 Jan 2022 18:39:03 -0500
Subject: [PATCH 5/6] arm64: dts: zynqmp: Move USB clocks to dwc3 node
In-Reply-To: <20220114233904.907918-1-sean.anderson@seco.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
Message-ID: <20220114233904.907918-6-sean.anderson@seco.com>

These clocks are not used by the dwc3-xilinx driver except to
enable/disable them. Move them to the dwc3 node so its driver can use
them to configure the reference clock period.

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
---

 arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 4 ++--
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
index 1e0b1bca7c94..8493dd7d5f1f 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -223,11 +223,11 @@ &uart1 {
 	clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
 };
 
-&usb0 {
+&dwc3_0 {
 	clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
-&usb1 {
+&dwc3_1 {
 	clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 74e66443e4ce..ba68fb8529ee 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -811,7 +811,6 @@ usb0: usb at ff9d0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9d0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_0>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
@@ -825,6 +824,7 @@ dwc3_0: usb at fe200000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 65 4>, <0 69 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x860>;
 				snps,quirk-frame-length-adjustment = <0x20>;
@@ -838,7 +838,6 @@ usb1: usb at ff9e0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9e0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_1>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
@@ -852,6 +851,7 @@ dwc3_1: usb at fe300000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 70 4>, <0 74 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x861>;
 				snps,quirk-frame-length-adjustment = <0x20>;
-- 
2.25.1



From martin.blumenstingl at googlemail.com  Fri Jan 14 16:09:11 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Sat, 15 Jan 2022 01:09:11 +0100
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
Message-ID: <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>

Hi Liang,

On Fri, Jan 14, 2022 at 4:06 AM Liang Yang <liang.yang at amlogic.com> wrote:
[...]
> >> +properties:
> >> +  compatible:
> >> +    enum:
> >> +      - "amlogic,axg-mmc-clkc", "syscon"
> >
> > Why is it a syscon?
>
> The register documented by reg is shared with SD/eMMC controller port C,
> and it need to be ops on NFC driver.
Can you please share an example how the .dts would look like in the
end for two example cases:
1) using the sd_emmc_c MMC interface
2) not using the MMC interface of sd_emmc_c but only using it's clocks
for the NFC

Initially I wanted to suggest the usage of a sub-node with compatible
= "mmc-slot" (see
Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt for an
example) to decide whether the MMC controller is registered or whether
just the clock controller is registered.
However, the mmc-slot compatible string is not documented in
Documentation/devicetree/bindings/mmc/mmc-controller.yaml currently.
Maybe the MMC maintainers have any suggestions if other IPs have
similar requirements (for IPs with shared parts).


Best regards,
Martin


From john.stultz at linaro.org  Fri Jan 14 17:17:39 2022
From: john.stultz at linaro.org (John Stultz)
Date: Fri, 14 Jan 2022 17:17:39 -0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <82faa62f1bc946cf2f9ee2f7d15c567162238eab.camel@mediatek.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
 <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
 <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>
 <82faa62f1bc946cf2f9ee2f7d15c567162238eab.camel@mediatek.com>
Message-ID: <CALAqxLUSjHoLpgFLcvqmDfv7Uip2VwHS5d_5x2nzw=P3rA2NDA@mail.gmail.com>

On Fri, Jan 14, 2022 at 4:04 AM Guangming.Cao
<guangming.cao at mediatek.com> wrote:
>
> On Fri, 2022-01-14 at 08:16 +0100, Christian K?nig wrote:
> > Am 14.01.22 um 00:26 schrieb John Stultz:
> > > On Thu, Jan 13, 2022 at 5:05 AM Christian K?nig
> > > <christian.koenig at amd.com> wrote:
> > > > Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
> > > > > > -----Original Message-----
> > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org> On
> > > > > > Behalf Of
> > > > > > Ruhl, Michael J
> > > > > > > -----Original Message-----
> > > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org>
> > > > > > > On Behalf Of
> > > > > > > guangming.cao at mediatek.com
> > > > > > > +   /*
> > > > > > > +    * Invalid size check. The "len" should be less than
> > > > > > > totalram.
> > > > > > > +    *
> > > > > > > +    * Without this check, once the invalid size allocation
> > > > > > > runs on a process
> > > > > > > that
> > > > > > > +    * can't be killed by OOM flow(such as "gralloc" on
> > > > > > > Android devices), it
> > > > > > > will
> > > > > > > +    * cause a kernel exception, and to make matters worse,
> > > > > > > we can't find
> > > > > > > who are using
> > > > > > > +    * so many memory with "dma_buf_debug_show" since the
> > > > > > > relevant
> > > > > > > dma-buf hasn't exported.
> > > > > > > +    */
> > > > > > > +   if (len >> PAGE_SHIFT > totalram_pages())
> > > > > >
> > > > > > If your "heap" is from cma, is this still a valid check?
> > > > >
> > > > > And thinking a bit further, if I create a heap from something
> > > > > else (say device memory),
> > > > > you will need to be able to figure out the maximum allowable
> > > > > check for the specific
> > > > > heap.
> > > > >
> > > > > Maybe the heap needs a callback for max size?
> Yes, I agree with this solution.
> If dma-heap framework support this via adding a callback to support it,
> seems it's more clear than adding a limitation in dma-heap framework
> since each heap maybe has different limitation.
> If you prefer adding callback, I can update this patch and add totalram
> limitation to system dma-heap.

If the max value is per-heap, why not enforce that value in the
per-heap allocation function?

Moving the check to the heap alloc to me seems simpler to me than
adding complexity to the infrastructure to add a heap max_size
callback. Is there some other use for the callback that you envision?

thanks
-john


From prabhakar.csengg at gmail.com  Fri Jan 14 17:40:16 2022
From: prabhakar.csengg at gmail.com (Lad, Prabhakar)
Date: Sat, 15 Jan 2022 01:40:16 +0000
Subject: [PATCH 2/5] drm/exynos: mixer: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <a95b74fd-7118-b0fe-26b9-4665c719f1a0@samsung.com>
References: <20211222190134.24866-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <CGME20211222190203epcas1p2a7647eb2c09c29587b70982744c1a912@epcas1p2.samsung.com>
 <20211222190134.24866-3-prabhakar.mahadev-lad.rj@bp.renesas.com>
 <a95b74fd-7118-b0fe-26b9-4665c719f1a0@samsung.com>
Message-ID: <CA+V-a8tDqLWQXtZbjh=XwKaen1T-iXy=pP-Rn8GF9j_YA-8wdQ@mail.gmail.com>

Hi Inki,

On Fri, Jan 14, 2022 at 11:08 AM Inki Dae <inki.dae at samsung.com> wrote:
>
> Hi Lad Prabhakar,
>
> 21. 12. 23. ?? 4:01? Lad Prabhakar ?(?) ? ?:
> > platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> > allocation of IRQ resources in DT core code, this causes an issue
> > when using hierarchical interrupt domains using "interrupts" property
> > in the node as this bypassed the hierarchical setup and messed up the
> > irq chaining.
> >
> > In preparation for removal of static setup of IRQ resource from DT core
> > code use platform_get_irq().
> >
> > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> > ---
> > Hi,
> >
> > Ideally I would expect the mixer_resources_init() to be called from probe
> > instead from the bind callback. If platform_get_irq() returns -EPROBE_DEFER
> > the bind callback will fail :(
>
> If the bind callback failed then probe function of exynos drm driver will call -EPROBE_DEFER like below so it must be no problem :),
> --------------------------------------------
> in exynos_drm_platform_probe function
>     component_master_add_with_match()
>
> in component_master_add_with_match function
>     try_to_bring_up_master()
>
Thank you for the clarification.

Cheers,
Prabhakar


From lkp at intel.com  Fri Jan 14 21:49:47 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 15 Jan 2022 13:49:47 +0800
Subject: [xilinx-xlnx:master 10/326]
 drivers/media/i2c/adv7511-v4l2.c:2102:63: sparse: sparse: incorrect type in
 argument 1 (different base types)
Message-ID: <202201151359.AyphE74l-lkp@intel.com>

Hi Quanyang,

First bad commit (maybe != root cause):

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6a698dbaaf0e6caa053476c2f661b36885a0ce30
commit: bd76b5963aee700d5e6ff0cd29834bfdaf05532e [10/326] media: adv7511-v4l2: fix compile error
config: alpha-randconfig-s031-20220113 (https://download.01.org/0day-ci/archive/20220115/202201151359.AyphE74l-lkp at intel.com/config)
compiler: alpha-linux-gcc (GCC) 11.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.4-dirty
        # https://github.com/Xilinx/linux-xlnx/commit/bd76b5963aee700d5e6ff0cd29834bfdaf05532e
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout bd76b5963aee700d5e6ff0cd29834bfdaf05532e
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=alpha SHELL=/bin/bash drivers/media/i2c/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


sparse warnings: (new ones prefixed by >>)
>> drivers/media/i2c/adv7511-v4l2.c:2102:63: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2102:63: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2102:63: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2106:65: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2106:65: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2106:65: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2110:62: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2110:62: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2110:62: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2117:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2117:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2117:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2121:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2121:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2121:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2125:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2125:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2125:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2129:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2129:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2129:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2133:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2133:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2133:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2137:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2137:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2137:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2141:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2141:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2141:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2151:42: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2151:42: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2151:42: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2157:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2157:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2157:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2161:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2161:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2161:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2165:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2165:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2165:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2169:55: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2169:55: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2169:55: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2174:63: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2174:63: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2174:63: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2181:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2181:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2181:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2186:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2186:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2186:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2191:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2191:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2191:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2196:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2196:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2196:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2201:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2201:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2201:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2206:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2206:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2206:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2211:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2211:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2211:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2216:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2216:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2216:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2221:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2221:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2221:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2226:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2226:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2226:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2231:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2231:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2231:72: sparse:     got unsigned int const [usertype] *[assigned] prop
   drivers/media/i2c/adv7511-v4l2.c:2236:72: sparse: sparse: incorrect type in argument 1 (different base types) @@     expected restricted __be32 const [usertype] *p @@     got unsigned int const [usertype] *[assigned] prop @@
   drivers/media/i2c/adv7511-v4l2.c:2236:72: sparse:     expected restricted __be32 const [usertype] *p
   drivers/media/i2c/adv7511-v4l2.c:2236:72: sparse:     got unsigned int const [usertype] *[assigned] prop

vim +2102 drivers/media/i2c/adv7511-v4l2.c

5a544cce2177fe drivers/media/i2c/adv7511.c      Hans Verkuil        2013-08-23  2086  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2087  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2088  static void adv7511_get_ofdt_config(struct i2c_client *client,
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2089  	struct adv7511_state *state)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2090  {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2091  	struct device_node *dn = client->dev.of_node;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2092  	struct device_node *np;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2093  	struct adv7511_config *config = &state->cfg;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2094  	u32 const *prop;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2095  	int size;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2096  	bool vin_loaded, vout_loaded;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2097  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2098  	vin_loaded = vout_loaded = false;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2099  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2100  	prop = of_get_property(dn, "edid-addr", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2101  	if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15 @2102  		state->pdata.i2c_edid = (uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2103  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2104  	prop = of_get_property(dn, "pktmem-addr", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2105  	if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2106  		state->pdata.i2c_pktmem = (uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2107  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2108  	prop = of_get_property(dn, "cec-addr", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2109  	if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2110  		state->pdata.i2c_cec = (uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2111  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2112  	np = of_find_node_by_name(dn, "video-input");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2113  	if (np) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2114  		prop = of_get_property(np, "input-id", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2115  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2116  			config->in_params.input_id =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2117  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2118  		prop = of_get_property(np, "input-style", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2119  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2120  			config->in_params.input_style =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2121  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2122  		prop = of_get_property(np, "input-color-depth", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2123  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2124  			config->in_params.input_color_depth =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2125  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2126  		prop = of_get_property(np, "bit-justification", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2127  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2128  			config->in_params.bit_justification =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2129  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2130  		prop = of_get_property(np, "hsync-polarity", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2131  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2132  			config->in_params.hsync_polarity =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2133  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2134  		prop = of_get_property(np, "vsync-polarity", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2135  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2136  			config->in_params.vsync_polarity =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2137  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2138  		prop = of_get_property(np, "clock-delay", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2139  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2140  			config->in_params.clock_delay =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2141  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2142  		vin_loaded = true;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2143  	} else {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2144  		pr_info("No video input configuration, using device default\n");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2145  	}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2146  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2147  	np = of_find_node_by_name(dn, "video-output");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2148  	if (np) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2149  		prop = of_get_property(np, "hdmi-mode", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2150  		if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2151  			if (be32_to_cpup(prop) == 1)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2152  				config->out_params.hdmi_mode = true;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2153  		}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2154  		prop = of_get_property(np, "output-format", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2155  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2156  			config->out_params.output_format =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2157  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2158  		prop = of_get_property(np, "output-color-space", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2159  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2160  			config->out_params.output_color_space =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2161  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2162  		prop = of_get_property(np, "up-conversion", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2163  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2164  			config->out_params.up_conversion =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2165  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2166  		prop = of_get_property(np, "csc-enable", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2167  		if (prop)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2168  			config->out_params.csc_enable =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2169  				(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2170  		if (config->out_params.csc_enable) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2171  			prop = of_get_property(np, "csc-scaling-factor", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2172  			if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2173  				config->out_params.csc_scaling_factor =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2174  					(uint8_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2175  			}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2176  			np = of_find_node_by_name(dn, "csc-coefficients");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2177  			if (np) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2178  				prop = of_get_property(np, "a1", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2179  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2180  					config->out_params.csc_coeff.a1 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2181  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2182  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2183  				prop = of_get_property(np, "a2", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2184  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2185  					config->out_params.csc_coeff.a2 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2186  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2187  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2188  				prop = of_get_property(np, "a3", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2189  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2190  					config->out_params.csc_coeff.a3 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2191  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2192  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2193  				prop = of_get_property(np, "a4", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2194  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2195  					config->out_params.csc_coeff.a4 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2196  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2197  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2198  				prop = of_get_property(np, "b1", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2199  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2200  					config->out_params.csc_coeff.b1 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2201  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2202  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2203  				prop = of_get_property(np, "b2", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2204  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2205  					config->out_params.csc_coeff.b2 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2206  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2207  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2208  				prop = of_get_property(np, "b3", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2209  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2210  					config->out_params.csc_coeff.b3 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2211  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2212  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2213  				prop = of_get_property(np, "b4", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2214  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2215  					config->out_params.csc_coeff.b4 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2216  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2217  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2218  				prop = of_get_property(np, "c1", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2219  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2220  					config->out_params.csc_coeff.c1 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2221  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2222  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2223  				prop = of_get_property(np, "c2", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2224  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2225  					config->out_params.csc_coeff.c2 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2226  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2227  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2228  				prop = of_get_property(np, "c3", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2229  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2230  					config->out_params.csc_coeff.c3 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2231  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2232  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2233  				prop = of_get_property(np, "c4", &size);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2234  				if (prop) {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2235  					config->out_params.csc_coeff.c4 =
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2236  						(uint16_t)be32_to_cpup(prop);
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2237  				}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2238  			} else {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2239  				pr_info("No CSC coefficients, using default\n");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2240  			}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2241  		}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2242  		vout_loaded = true;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2243  	} else {
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2244  		pr_info("No video output configuration, using device default\n");
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2245  	}
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2246  
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2247  	if (vin_loaded && vout_loaded)
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2248  		config->loaded = true;
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2249  }
c2644339194bd7 drivers/media/i2c/adv7511-v4l2.c Radhey Shyam Pandey 2014-01-15  2250  

:::::: The code at line 2102 was first introduced by commit
:::::: c2644339194bd7be4ce6023d72f5e7a03f55ef6b drivers: media: Customized adv7511 for Xylon LogiCVC (deprecated)

:::::: TO: Radhey Shyam Pandey <radhey.shyam.pandey at xilinx.com>
:::::: CC: Michal Simek <michal.simek at xilinx.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From christophe.jaillet at wanadoo.fr  Fri Jan 14 23:35:20 2022
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 15 Jan 2022 08:35:20 +0100
Subject: [PATCH v2] dmaengine: qcom_hidma: Remove useless DMA-32 fallback
 configuration
Message-ID: <4deb32b0c7838da66608022c584326eb01d0da03.1642232106.git.christophe.jaillet@wanadoo.fr>

As stated in [1], dma_set_mask() with a 64-bit mask never fails if
dev->dma_mask is non-NULL.
So, if it fails, the 32 bits case will also fail for the same reason.

Simplify code and remove some dead code accordingly.

[1]: https://lore.kernel.org/linux-kernel/YL3vSPK5DXTNvgdx at infradead.org/#t

Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
v2: have the subject and updated driver match
---
 drivers/dma/qcom/hidma.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
index 65d054bb11aa..51587cf8196b 100644
--- a/drivers/dma/qcom/hidma.c
+++ b/drivers/dma/qcom/hidma.c
@@ -838,9 +838,7 @@ static int hidma_probe(struct platform_device *pdev)
 	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 	if (rc) {
 		dev_warn(&pdev->dev, "unable to set coherent mask to 64");
-		rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
-		if (rc)
-			goto dmafree;
+		goto dmafree;
 	}
 
 	dmadev->lldev = hidma_ll_init(dmadev->ddev.dev,
-- 
2.32.0



From sboyd at kernel.org  Sat Jan 15 00:02:11 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Sat, 15 Jan 2022 00:02:11 -0800
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20211016064210.7ahqfqcvf66wtt66@pali>
References: <20210930095838.28145-1-pali@kernel.org>
 <20210930095838.28145-4-pali@kernel.org>
 <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali> <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
Message-ID: <20220115080213.0CCAFC36AE3@smtp.kernel.org>

Quoting Pali Roh?r (2021-10-15 23:42:10)
> 
> If I was designing this driver and DTS bindings I would have choose
> something like this:
> 
> uart at 0x12000 {

Drop the 0x

>     reg = <0x12000 0x18>, <0x12200 0x30>;
>     clock-controller {
>         ...
>     };

Drop this node and put whatever properties are inside into the parent
node.

>     serial1 {
>         ...
>         status = "disabled";
>     };
>     serial2 {
>         ...
>         status = "disabled";
>     };
> };
> 
> Meaning that 0x12000 node would be 3 subnodes and all registers would be
> defined in top level nodes and would be handled by one driver.
> 
> This is really how hardware block looks like. But it is not backward
> compatible...

Sounds good to me. I presume we need the serial child nodes so we can
reference them from the stdout-path?


From clabbe at baylibre.com  Sat Jan 15 02:04:44 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Sat, 15 Jan 2022 10:04:44 +0000
Subject: [PATCH 2/2] ARM: dts: gemini: ssi1328: permit to use gigabit
In-Reply-To: <20220115100444.3014823-1-clabbe@baylibre.com>
References: <20220115100444.3014823-1-clabbe@baylibre.com>
Message-ID: <20220115100444.3014823-2-clabbe@baylibre.com>

I believed that gigabit was not working due to unknown missing GPIO.
But the problem was due to Marvell PHY incorrectly setting delay.
Now it is fixed, gigabit works.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 arch/arm/boot/dts/gemini-ssi1328.dts | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm/boot/dts/gemini-ssi1328.dts b/arch/arm/boot/dts/gemini-ssi1328.dts
index 113feb1c4922..bb85f1febe9d 100644
--- a/arch/arm/boot/dts/gemini-ssi1328.dts
+++ b/arch/arm/boot/dts/gemini-ssi1328.dts
@@ -40,10 +40,6 @@ mdio0: mdio {
 		phy0: ethernet-phy at 1 {
 			reg = <1>;
 			device_type = "ethernet-phy";
-			/* We lack the knowledge of necessary GPIO to achieve
-			 * Gigabit
-			 */
-			max-speed = <100>;
 		};
 		/* WAN ICPlus IP101A */
 		phy1: ethernet-phy at 2 {
-- 
2.34.1



From clabbe at baylibre.com  Sat Jan 15 02:04:43 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Sat, 15 Jan 2022 10:04:43 +0000
Subject: [PATCH 1/2] ARM: dts: gemini: ns2502: permit to use gigabit
Message-ID: <20220115100444.3014823-1-clabbe@baylibre.com>

I believed that gigabit was not working due to some unknown missing GPIO.
In fact, gigabit worked when REALTEK_PHY was compiled out.
So the problem was due to PHY delay and we need to use rgmii-id.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 arch/arm/boot/dts/gemini-ns2502.dts | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/arm/boot/dts/gemini-ns2502.dts b/arch/arm/boot/dts/gemini-ns2502.dts
index 37e5debb693c..c759c4c732ab 100644
--- a/arch/arm/boot/dts/gemini-ns2502.dts
+++ b/arch/arm/boot/dts/gemini-ns2502.dts
@@ -39,10 +39,6 @@ mdio0: mdio {
 		phy0: ethernet-phy at 1 {
 			reg = <1>;
 			device_type = "ethernet-phy";
-			/* We lack the knowledge of necessary GPIO to achieve
-			 * Gigabit
-			 */
-			max-speed = <100>;
 		};
 	};
 };
@@ -50,7 +46,7 @@ phy0: ethernet-phy at 1 {
 &ethernet {
 	status = "okay";
 	ethernet-port at 0 {
-		phy-mode = "rgmii";
+		phy-mode = "rgmii-id";
 		phy-handle = <&phy0>;
 		mac-address = [00 1F 1F 8E 65 E2];
 	};
-- 
2.34.1



From christophe.leroy at csgroup.eu  Sat Jan 15 02:05:55 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:05:55 +0000
Subject: [PATCH v2 2/3] arm64: Support huge vmalloc mappings
In-Reply-To: <20211227145903.187152-3-wangkefeng.wang@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-3-wangkefeng.wang@huawei.com>
Message-ID: <41f715ce-5597-b66a-e708-26d102668cf5@csgroup.eu>



Le 27/12/2021 ? 15:59, Kefeng Wang a ?crit?:
> This patch select HAVE_ARCH_HUGE_VMALLOC to let arm64 support huge
> vmalloc mappings.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>   Documentation/admin-guide/kernel-parameters.txt | 4 ++--
>   arch/arm64/Kconfig                              | 1 +
>   arch/arm64/kernel/module.c                      | 5 +++--
>   3 files changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 7b2f900fd243..e3f9fd7ec106 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1639,7 +1639,7 @@
>   			precedence over memory_hotplug.memmap_on_memory.
>   
>   
> -	hugevmalloc=	[PPC] Reguires CONFIG_HAVE_ARCH_HUGE_VMALLOC
> +	hugevmalloc=	[KNL,PPC,ARM64] Reguires CONFIG_HAVE_ARCH_HUGE_VMALLOC
>   			Format: { on | off }
>   			Default set by CONFIG_HUGE_VMALLOC_DEFAULT_ENABLED.
>   
> @@ -3424,7 +3424,7 @@
>   
>   	nohugeiomap	[KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings.
>   
> -	nohugevmalloc	[PPC] Disable kernel huge vmalloc mappings.
> +	nohugevmalloc	[KNL,PPC,ARM64] Disable kernel huge vmalloc mappings.
>   
>   	nosmt		[KNL,S390] Disable symmetric multithreading (SMT).
>   			Equivalent to smt=1.
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 3bb0b67292b5..c34bbb4482b0 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -142,6 +142,7 @@ config ARM64
>   	select HAVE_ARCH_AUDITSYSCALL
>   	select HAVE_ARCH_BITREVERSE
>   	select HAVE_ARCH_COMPILER_H
> +	select HAVE_ARCH_HUGE_VMALLOC
>   	select HAVE_ARCH_HUGE_VMAP
>   	select HAVE_ARCH_JUMP_LABEL
>   	select HAVE_ARCH_JUMP_LABEL_RELATIVE
> diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
> index 309a27553c87..af7b4cbace2b 100644
> --- a/arch/arm64/kernel/module.c
> +++ b/arch/arm64/kernel/module.c
> @@ -36,7 +36,8 @@ void *module_alloc(unsigned long size)
>   		module_alloc_end = MODULES_END;
>   
>   	p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
> -				module_alloc_end, gfp_mask, PAGE_KERNEL, VM_DEFER_KMEMLEAK,
> +				module_alloc_end, gfp_mask, PAGE_KERNEL,
> +				VM_DEFER_KMEMLEAK | VM_NO_HUGE_VMAP,

you should add a comment like powerpc (commit 8abddd968a30 
("powerpc/64s/radix: Enable huge vmalloc mappings")) to explain why this 
requires VM_NO_HUGE_VMAP

>   				NUMA_NO_NODE, __builtin_return_address(0));
>   
>   	if (!p && IS_ENABLED(CONFIG_ARM64_MODULE_PLTS) &&
> @@ -55,7 +56,7 @@ void *module_alloc(unsigned long size)
>   		 */
>   		p = __vmalloc_node_range(size, MODULE_ALIGN, module_alloc_base,
>   				module_alloc_base + SZ_2G, GFP_KERNEL,
> -				PAGE_KERNEL, 0, NUMA_NO_NODE,
> +				PAGE_KERNEL, VM_NO_HUGE_VMAP, NUMA_NO_NODE,

Same

>   				__builtin_return_address(0));
>   
>   	if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {

From christophe.leroy at csgroup.eu  Sat Jan 15 02:06:18 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:06:18 +0000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <20211227145903.187152-4-wangkefeng.wang@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
Message-ID: <0b9dd629-6a2b-0bad-11e4-c49ea1abd223@csgroup.eu>



Le 27/12/2021 ? 15:59, Kefeng Wang a ?crit?:
> This patch select HAVE_ARCH_HUGE_VMALLOC to let X86_64 and X86_PAE
> support huge vmalloc mappings.
> 
> Cc: Thomas Gleixner <tglx at linutronix.de>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Borislav Petkov <bp at alien8.de>
> Cc: Dave Hansen <dave.hansen at linux.intel.com>
> Cc: "H. Peter Anvin" <hpa at zytor.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang at huawei.com>
> ---
>   Documentation/admin-guide/kernel-parameters.txt | 4 ++--
>   arch/x86/Kconfig                                | 1 +
>   arch/x86/kernel/module.c                        | 4 ++--
>   3 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index e3f9fd7ec106..ffce6591ae64 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -1639,7 +1639,7 @@
>   			precedence over memory_hotplug.memmap_on_memory.
>   
>   
> -	hugevmalloc=	[KNL,PPC,ARM64] Reguires CONFIG_HAVE_ARCH_HUGE_VMALLOC
> +	hugevmalloc=	[KNL,PPC,ARM64,X86] Reguires CONFIG_HAVE_ARCH_HUGE_VMALLOC
>   			Format: { on | off }
>   			Default set by CONFIG_HUGE_VMALLOC_DEFAULT_ENABLED.
>   
> @@ -3424,7 +3424,7 @@
>   
>   	nohugeiomap	[KNL,X86,PPC,ARM64] Disable kernel huge I/O mappings.
>   
> -	nohugevmalloc	[KNL,PPC,ARM64] Disable kernel huge vmalloc mappings.
> +	nohugevmalloc	[KNL,PPC,ARM64,X86] Disable kernel huge vmalloc mappings.
>   
>   	nosmt		[KNL,S390] Disable symmetric multithreading (SMT).
>   			Equivalent to smt=1.
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index ebe8fc76949a..f6bf6675bbe7 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -157,6 +157,7 @@ config X86
>   	select HAVE_ACPI_APEI_NMI		if ACPI
>   	select HAVE_ALIGNED_STRUCT_PAGE		if SLUB
>   	select HAVE_ARCH_AUDITSYSCALL
> +	select HAVE_ARCH_HUGE_VMALLOC		if HAVE_ARCH_HUGE_VMAP
>   	select HAVE_ARCH_HUGE_VMAP		if X86_64 || X86_PAE
>   	select HAVE_ARCH_JUMP_LABEL
>   	select HAVE_ARCH_JUMP_LABEL_RELATIVE
> diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
> index 95fa745e310a..6bf5cb7d876a 100644
> --- a/arch/x86/kernel/module.c
> +++ b/arch/x86/kernel/module.c
> @@ -75,8 +75,8 @@ void *module_alloc(unsigned long size)
>   
>   	p = __vmalloc_node_range(size, MODULE_ALIGN,
>   				    MODULES_VADDR + get_module_load_offset(),
> -				    MODULES_END, gfp_mask,
> -				    PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
> +				    MODULES_END, gfp_mask, PAGE_KERNEL,
> +				    VM_DEFER_KMEMLEAK | VM_NO_HUGE_VMAP, NUMA_NO_NODE,

you should add a comment like powerpc (commit 8abddd968a30 
("powerpc/64s/radix: Enable huge vmalloc mappings")) to explain why this 
requires VM_NO_HUGE_VMAP

>   				    __builtin_return_address(0));
>   	if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
>   		vfree(p);

From clabbe at baylibre.com  Sat Jan 15 02:07:14 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Sat, 15 Jan 2022 10:07:14 +0000
Subject: [PATCH] crypto: sun8i-ss: really disable hash on A80
Message-ID: <20220115100714.3016838-1-clabbe@baylibre.com>

When adding hashes support to sun8i-ss, I have added them only on A83T.
But I forgot that 0 is a valid algorithm ID, so hashes are enabled on A80 but
with an incorrect ID.
Anyway, even with correct IDs, hashes do not work on A80 and I cannot
find why.
So let's disable all of them on A80.

Fixes: d9b45418a917 ("crypto: sun8i-ss - support hash algorithms")
Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 80e89066dbd1..319fe3279a71 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -30,6 +30,8 @@
 static const struct ss_variant ss_a80_variant = {
 	.alg_cipher = { SS_ALG_AES, SS_ALG_DES, SS_ALG_3DES,
 	},
+	.alg_hash = { SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP, SS_ID_NOTSUPP,
+	},
 	.op_mode = { SS_OP_ECB, SS_OP_CBC,
 	},
 	.ss_clks = {
-- 
2.34.1



From christophe.leroy at csgroup.eu  Sat Jan 15 02:07:26 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:07:26 +0000
Subject: [PATCH v2 0/3] mm: support huge vmalloc mapping on arm64/x86
In-Reply-To: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
Message-ID: <c2ca11b4-2802-3353-a9d4-a3108bfc9708@csgroup.eu>



Le 27/12/2021 ? 15:59, Kefeng Wang a ?crit?:
> Huge vmalloc mappings is supported on PPC[1], but this feature should
> be not only used on PPC, it could be used on arch support HAVE_ARCH_HUGE_VMAP
> and PMD sized vmap mappings. this patchset is to enable this feature
> on arm64/x86.
> 
> There are some disadvantages about this feature[2], one of the main

There are some disadvantage, ok, so are there advantages as well ?

> concerns is the possible memory fragmentation/waste in some scenarios,
> also archs must ensure that any arch specific vmalloc allocations that
> require PAGE_SIZE mappings(eg, module alloc with STRICT_MODULE_RWX)
> use the VM_NO_HUGE_VMAP flag to inhibit larger mappings.
> 
> Based on the above considerations, we add the first patch is to let
> user to control huge vmalloc mapping default behavior.  Meanwhile,
> add new kernel parameter hugevmalloc=on/off to enable/disable this
> feature at boot time, nohugevmalloc parameter is still supported.
> 
> The later two patches to enable this feature on arm64/x86, select
> HAVE_ARCH_HUGE_VMALLOC and mark VM_NO_HUGE_VMAP in arch's module_alloc().
> 
> This patchset based on next-20211224.
> 
> v2:
> - Default y for HUGE_VMALLOC_DEFAULT_ENABLED, not only select it on PPC
> - Fix copy/type error
> - Mark VM_NO_HUGE_VMAP in module_alloc() on arm64/x86
> 
> [1] https://lore.kernel.org/linux-mm/20210317062402.533919-1-npiggin at gmail.com/
> [2] https://lore.kernel.org/linux-mm/1616036421.amjz2efujj.astroid at bobo.none/
> 
> Kefeng Wang (3):
>    mm: vmalloc: Let user to control huge vmalloc default behavior
>    arm64: Support huge vmalloc mappings
>    x86: Support huge vmalloc mappings
> 
>   .../admin-guide/kernel-parameters.txt          | 14 +++++++++++++-
>   arch/arm64/Kconfig                             |  1 +
>   arch/arm64/kernel/module.c                     |  5 +++--
>   arch/x86/Kconfig                               |  1 +
>   arch/x86/kernel/module.c                       |  4 ++--
>   mm/Kconfig                                     |  8 ++++++++
>   mm/vmalloc.c                                   | 18 +++++++++++++++++-
>   7 files changed, 45 insertions(+), 6 deletions(-)
> 

From christophe.leroy at csgroup.eu  Sat Jan 15 02:11:18 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:11:18 +0000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
Message-ID: <21d6fc65-d9d1-66bb-9bea-a4bad78c7aac@csgroup.eu>



Le 28/12/2021 ? 11:26, Kefeng Wang a ?crit?:
> 
> On 2021/12/27 23:56, Dave Hansen wrote:
>> On 12/27/21 6:59 AM, Kefeng Wang wrote:
>>> This patch select HAVE_ARCH_HUGE_VMALLOC to let X86_64 and X86_PAE
>>> support huge vmalloc mappings.
>> In general, this seems interesting and the diff is simple.? But, I don't
>> see _any_ x86-specific data.? I think the bare minimum here would be a
>> few kernel compiles and some 'perf stat' data for some TLB events.
> 
> When the feature supported on ppc,
> 
> commit 8abddd968a303db75e4debe77a3df484164f1f33
> Author: Nicholas Piggin <npiggin at gmail.com>
> Date:?? Mon May 3 19:17:55 2021 +1000
> 
>  ??? powerpc/64s/radix: Enable huge vmalloc mappings
> 
>  ??? This reduces TLB misses by nearly 30x on a `git diff` workload on a
>  ??? 2-node POWER9 (59,800 -> 2,100) and reduces CPU cycles by 0.54%, due
>  ??? to vfs hashes being allocated with 2MB pages.
> 
> But the data could be different on different machine/arch.
> 
>>> diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
>>> index 95fa745e310a..6bf5cb7d876a 100644
>>> --- a/arch/x86/kernel/module.c
>>> +++ b/arch/x86/kernel/module.c
>>> @@ -75,8 +75,8 @@ void *module_alloc(unsigned long size)
>>> ????? p = __vmalloc_node_range(size, MODULE_ALIGN,
>>> ????????????????????? MODULES_VADDR + get_module_load_offset(),
>>> -??????????????????? MODULES_END, gfp_mask,
>>> -??????????????????? PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
>>> +??????????????????? MODULES_END, gfp_mask, PAGE_KERNEL,
>>> +??????????????????? VM_DEFER_KMEMLEAK | VM_NO_HUGE_VMAP, NUMA_NO_NODE,
>>> ????????????????????? __builtin_return_address(0));
>>> ????? if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
>>> ????????? vfree(p);
>> To figure out what's going on in this hunk, I had to look at the cover
>> letter (which I wasn't cc'd on).? That's not great and it means that
>> somebody who stumbles upon this in the code is going to have a really
>> hard time figuring out what is going on.? Cover letters don't make it
>> into git history.
> Sorry for that, will add more into arch's patch changelog.
>> This desperately needs a comment and some changelog material in *this*
>> patch.
>>
>> But, even the description from the cover letter is sparse:
>>
>>> There are some disadvantages about this feature[2], one of the main
>>> concerns is the possible memory fragmentation/waste in some scenarios,
>>> also archs must ensure that any arch specific vmalloc allocations that
>>> require PAGE_SIZE mappings(eg, module alloc with STRICT_MODULE_RWX)
>>> use the VM_NO_HUGE_VMAP flag to inhibit larger mappings.
>> That just says that x86 *needs* PAGE_SIZE allocations.? But, what
>> happens if VM_NO_HUGE_VMAP is not passed (like it was in v1)?? Will the
>> subsequent permission changes just fragment the 2M mapping?
>> .
> 
> Yes, without VM_NO_HUGE_VMAP, it could fragment the 2M mapping.
> 
> When module alloc with STRICT_MODULE_RWX on x86, it calls 
> __change_page_attr()
> 
> from set_memory_ro/rw/nx which will split large page, so there is no 
> need to make
> 
> module alloc with HUGE_VMALLOC.
> 

Maybe there is no need to perform the module alloc with HUGE_VMALLOC, 
but it least it would still work if you do so.

Powerpc did add VM_NO_HUGE_VMAP temporarily and for some reason which is 
  explained in a comment.

If x86 already has the necessary logic to handle it, why add 
VM_NO_HUGE_VMAP ?

Christophe

From christophe.leroy at csgroup.eu  Sat Jan 15 02:15:34 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:15:34 +0000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
Message-ID: <0ffb59f0-3ce9-99f3-8184-44dc2d56d57f@csgroup.eu>



Le 28/12/2021 ? 17:14, Dave Hansen a ?crit?:
> On 12/28/21 2:26 AM, Kefeng Wang wrote:
>>>> There are some disadvantages about this feature[2], one of the main
>>>> concerns is the possible memory fragmentation/waste in some scenarios,
>>>> also archs must ensure that any arch specific vmalloc allocations that
>>>> require PAGE_SIZE mappings(eg, module alloc with STRICT_MODULE_RWX)
>>>> use the VM_NO_HUGE_VMAP flag to inhibit larger mappings.
>>> That just says that x86 *needs* PAGE_SIZE allocations.? But, what
>>> happens if VM_NO_HUGE_VMAP is not passed (like it was in v1)?? Will the
>>> subsequent permission changes just fragment the 2M mapping?
>>
>> Yes, without VM_NO_HUGE_VMAP, it could fragment the 2M mapping.
>>
>> When module alloc with STRICT_MODULE_RWX on x86, it calls
>> __change_page_attr()
>>
>> from set_memory_ro/rw/nx which will split large page, so there is no
>> need to make
>>
>> module alloc with HUGE_VMALLOC.
> 
> This all sounds very fragile to me.  Every time a new architecture would
> get added for huge vmalloc() support, the developer needs to know to go
> find that architecture's module_alloc() and add this flag.  They next
> guy is going to forget, just like you did.

That's not correct from my point of view.

When powerpc added that, a clear comment explains why:


+	/*
+	 * Don't do huge page allocations for modules yet until more testing
+	 * is done. STRICT_MODULE_RWX may require extra work to support this
+	 * too.
+	 */

So as you can see, this is something specific to powerpc and temporary.

> 
> Considering that this is not a hot path, a weak function would be a nice
> choice:
> 
> /* vmalloc() flags used for all module allocations. */
> unsigned long __weak arch_module_vm_flags()
> {
> 	/*
> 	 * Modules use a single, large vmalloc().  Different
> 	 * permissions are applied later and will fragment
> 	 * huge mappings.  Avoid using huge pages for modules.
> 	 */

Why ? Not everybody use STRICT_MODULES_RWX.
Even if you do so, you can still benefit from huge pages for modules.

Why make what was initially a temporary precaution for powerpc become a 
definitive default limitation for all ?

> 	return VM_NO_HUGE_VMAP;
> }
> 
> Stick that in some the common module code, next to:
> 
>> void * __weak module_alloc(unsigned long size)
>> {
>>          return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
> ...
> 
> Then, put arch_module_vm_flags() in *all* of the module_alloc()
> implementations, including the generic one.  That way (even with a new
> architecture) whoever copies-and-pastes their module_alloc()
> implementation is likely to get it right.  The next guy who just does a
> "select HAVE_ARCH_HUGE_VMALLOC" will hopefully just work.
> 
> VM_FLUSH_RESET_PERMS could probably be dealt with in the same way.

From christophe.leroy at csgroup.eu  Sat Jan 15 02:17:48 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Sat, 15 Jan 2022 10:17:48 +0000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <6cd5deb3-b71d-1058-f992-1c2f93c16ea4@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
 <6cd5deb3-b71d-1058-f992-1c2f93c16ea4@huawei.com>
Message-ID: <a4f4c4d7-4f53-d0fd-9db3-0e67335428a6@csgroup.eu>



Le 29/12/2021 ? 12:01, Kefeng Wang a ?crit?:
> 
> On 2021/12/29 0:14, Dave Hansen wrote:
>> On 12/28/21 2:26 AM, Kefeng Wang wrote:
>>>>> There are some disadvantages about this feature[2], one of the main
>>>>> concerns is the possible memory fragmentation/waste in some scenarios,
>>>>> also archs must ensure that any arch specific vmalloc allocations that
>>>>> require PAGE_SIZE mappings(eg, module alloc with STRICT_MODULE_RWX)
>>>>> use the VM_NO_HUGE_VMAP flag to inhibit larger mappings.
>>>> That just says that x86 *needs* PAGE_SIZE allocations.? But, what
>>>> happens if VM_NO_HUGE_VMAP is not passed (like it was in v1)?? Will the
>>>> subsequent permission changes just fragment the 2M mapping?
>>> Yes, without VM_NO_HUGE_VMAP, it could fragment the 2M mapping.
>>>
>>> When module alloc with STRICT_MODULE_RWX on x86, it calls
>>> __change_page_attr()
>>>
>>> from set_memory_ro/rw/nx which will split large page, so there is no
>>> need to make
>>>
>>> module alloc with HUGE_VMALLOC.
>> This all sounds very fragile to me.? Every time a new architecture would
>> get added for huge vmalloc() support, the developer needs to know to go
>> find that architecture's module_alloc() and add this flag.? They next
>> guy is going to forget, just like you did.
>>
>> Considering that this is not a hot path, a weak function would be a nice
>> choice:
>>
>> /* vmalloc() flags used for all module allocations. */
>> unsigned long __weak arch_module_vm_flags()
>> {
>> ????/*
>> ???? * Modules use a single, large vmalloc().? Different
>> ???? * permissions are applied later and will fragment
>> ???? * huge mappings.? Avoid using huge pages for modules.
>> ???? */
>> ????return VM_NO_HUGE_VMAP;
> 
> For x86, it only fragment, but for arm64, due to apply_to_page_range() in
> 
> set_memory_*, without this flag maybe crash. Whatever, we need this
> 
> flag for module.

I see no reason to have this flag by default.

Only ARM should have it if necessary, with a comment explaining why just 
like powerpc.

And maybe the flag should be there only when STRICT_MODULE_RWX is selected.

> 
>> }
>>
>> Stick that in some the common module code, next to:
>>
>>> void * __weak module_alloc(unsigned long size)
>>> {
>>> ???????? return __vmalloc_node_range(size, 1, VMALLOC_START, 
>>> VMALLOC_END,
>> ...
>>
>> Then, put arch_module_vm_flags() in *all* of the module_alloc()
>> implementations, including the generic one.? That way (even with a new
>> architecture) whoever copies-and-pastes their module_alloc()
>> implementation is likely to get it right.? The next guy who just does a
>> "select HAVE_ARCH_HUGE_VMALLOC" will hopefully just work.
> 
> OK? Let me check the VM_FLUSH_RESET_PERMS and try about this way.
> 
> Thanks.
> 
>>
>> VM_FLUSH_RESET_PERMS could probably be dealt with in the same way.
>> .

From pali at kernel.org  Sat Jan 15 03:50:18 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 15 Jan 2022 12:50:18 +0100
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <20220115080213.0CCAFC36AE3@smtp.kernel.org>
References: <20210930095838.28145-1-pali@kernel.org>
 <20210930095838.28145-4-pali@kernel.org>
 <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali>
 <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
Message-ID: <20220115115018.he4hnnhlvrb6kann@pali>

On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> Quoting Pali Roh?r (2021-10-15 23:42:10)
> > 
> > If I was designing this driver and DTS bindings I would have choose
> > something like this:
> > 
> > uart at 0x12000 {
> 
> Drop the 0x
> 
> >     reg = <0x12000 0x18>, <0x12200 0x30>;
> >     clock-controller {
> >         ...
> >     };
> 
> Drop this node and put whatever properties are inside into the parent
> node.
> 
> >     serial1 {
> >         ...
> >         status = "disabled";
> >     };
> >     serial2 {
> >         ...
> >         status = "disabled";
> >     };
> > };
> > 
> > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > defined in top level nodes and would be handled by one driver.
> > 
> > This is really how hardware block looks like. But it is not backward
> > compatible...
> 
> Sounds good to me. I presume we need the serial child nodes so we can
> reference them from the stdout-path?

Yes, exactly, separate nodes for serial1 and serial2 are still required.

But dropping clock controller is not possible as for higher baudrates we
need to use and configure uart clock controller. Without it we just get
comparable feature support which is already present in driver.

But, I do not fully understand now, why to change this DTS bindings in
this incompatible way? What it brings? Because for me now it looks like
that this change does not bring anything useful, only breaks current DTS
bindings.

Driver changes would still look in the similar / same way like it is in
current patch series because bindings already contains separate nodes,
just they are children of top level node which represents in internal
registers.


From kabel at kernel.org  Sat Jan 15 04:05:09 2022
From: kabel at kernel.org (Marek =?UTF-8?B?QmVow7pu?=)
Date: Sat, 15 Jan 2022 13:05:09 +0100
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings
 for marvell,armada-3700-uart-clock
In-Reply-To: <20220115115018.he4hnnhlvrb6kann@pali>
References: <20210930095838.28145-1-pali@kernel.org>
 <20210930095838.28145-4-pali@kernel.org>
 <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali>
 <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali>
Message-ID: <20220115130509.4a240730@thinkpad>

On Sat, 15 Jan 2022 12:50:18 +0100
Pali Roh?r <pali at kernel.org> wrote:

> On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > 
> > > If I was designing this driver and DTS bindings I would have choose
> > > something like this:
> > > 
> > > uart at 0x12000 {  
> > 
> > Drop the 0x
> >   
> > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > >     clock-controller {
> > >         ...
> > >     };  
> > 
> > Drop this node and put whatever properties are inside into the parent
> > node.
> >   
> > >     serial1 {
> > >         ...
> > >         status = "disabled";
> > >     };
> > >     serial2 {
> > >         ...
> > >         status = "disabled";
> > >     };
> > > };
> > > 
> > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > defined in top level nodes and would be handled by one driver.
> > > 
> > > This is really how hardware block looks like. But it is not backward
> > > compatible...  
> > 
> > Sounds good to me. I presume we need the serial child nodes so we can
> > reference them from the stdout-path?  
> 
> Yes, exactly, separate nodes for serial1 and serial2 are still required.
> 
> But dropping clock controller is not possible as for higher baudrates we
> need to use and configure uart clock controller. Without it we just get
> comparable feature support which is already present in driver.

What Stephen means is making clock controller out of the uart node
directly. No need to add separate subnode just for clock controller.

Marek


From maz at kernel.org  Sat Jan 15 04:19:16 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 15 Jan 2022 12:19:16 +0000
Subject: [PATCH v5 11/69] KVM: arm64: nv: Add nested virt VCPU primitives
 for vEL2 VCPU state
In-Reply-To: <YeG17OWrvFPQjgjS@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-12-maz@kernel.org>
 <YeG17OWrvFPQjgjS@monolith.localdoman>
Message-ID: <87lezh8a4b.wl-maz@kernel.org>

On Fri, 14 Jan 2022 17:42:04 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> Bunch of bikeshedding regarding names below, which can be safely ignored.
> 
> On Mon, Nov 29, 2021 at 08:00:52PM +0000, Marc Zyngier wrote:
> > From: Christoffer Dall <christoffer.dall at arm.com>
> > 
> > When running a nested hypervisor we commonly have to figure out if
> > the VCPU mode is running in the context of a guest hypervisor or guest
> > guest, or just a normal guest.
> > 
> > Add convenient primitives for this.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/kvm_emulate.h | 55 ++++++++++++++++++++++++++++
> >  1 file changed, 55 insertions(+)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index f4871e47b2d0..f4b079945d0f 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -176,6 +176,61 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
> >  		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
> >  }
> >  
> > +static inline bool vcpu_mode_el2_ctxt(const struct kvm_cpu_context *ctxt)
> 
> "The Armv8-A architecture defines a set of Exception levels, EL0 to EL3" (ARM
> DDI 0487G.a, page G1-5941).
> 
> "AArch64 state does not support modes. Modes are a concept that is specific to
> AArch32 state." (ARM DDI 0487G.a, page G1-5944).
> 
> Wouldn't it be better to use the same terminology as the architecture?

Probably. I'll see how invasive it is to repaint this. It still
remains that the 'mode' term is used all over the shop (for example,
PSR_MODE_*).

> > +{
> > +	unsigned long cpsr = ctxt->regs.pstate;
> 
> CPSR is an AArch32 register. Why not name the variable pstate?

Because we have *a ton* of existing CPSR references all over the shop
(more than references to pstate, actually), owing to the AArch32
heritage of KVM/arm64. Yes, I can change this locally without any
damage. But repainting the whole of KVM would be fairly pointless
(same with hsr/esr, hfar/far_el2...).

> 
> > +
> > +	switch (cpsr & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
> > +	case PSR_MODE_EL2h:
> > +	case PSR_MODE_EL2t:
> > +		return true;
> > +	default:
> > +		return false;
> > +	}
> > +}
> > +
> > +static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
> > +{
> > +	return vcpu_mode_el2_ctxt(&vcpu->arch.ctxt);
> > +}
> > +
> > +static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
> > +{
> > +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
> > +}
> > +
> > +static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
> > +{
> > +	return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
> > +}
> > +
> > +static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
> > +{
> > +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
> > +}
> > +
> > +static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
> 
> This is confusing. What does the exception level have to do with the
> HCR_EL2.TGE bit being set? Wouldn't vcpu_hcr_tge_is_set() be better?

Sure, why not. Again, I'll see how invasive such a repainting is
across 70 patches.

> 
> > +{
> > +	return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
> > +}
> > +
> > +static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
> > +{
> > +	/*
> > +	 * We are in a hypervisor context if the vcpu mode is EL2 or
> > +	 * E2H and TGE bits are set. The latter means we are in the user space
> > +	 * of the VHE kernel. ARMv8.1 ARM describes this as 'InHost'
> 
> So why not call the function vcpu_is_inhost() or something along
> those lines to match the architecture?

Because this is not the architectural 'InHost' primitive, which
returns 'false' if HCR_EL2.E2H==0. The second term of the expression
could be written in terms of an InHost primitive, but that's about it.

> 
> Thanks,
> Alex
> 
> > +	 */
> > +	return vcpu_mode_el2_ctxt(ctxt) ||
> > +		(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
> > +		WARN_ON(__vcpu_el2_tge_is_set(ctxt));
> > +}
> > +
> > +static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
> > +{
> > +	return __is_hyp_ctxt(&vcpu->arch.ctxt);
> > +}
> > +
> >  /*
> >   * The layout of SPSR for an AArch32 state is different when observed from an
> >   * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From pali at kernel.org  Sat Jan 15 04:26:18 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Sat, 15 Jan 2022 13:26:18 +0100
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <20220115130509.4a240730@thinkpad>
References: <20210930095838.28145-1-pali@kernel.org>
 <20210930095838.28145-4-pali@kernel.org>
 <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali>
 <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali>
 <20220115130509.4a240730@thinkpad>
Message-ID: <20220115122618.plhiqnjh2755bv5h@pali>

On Saturday 15 January 2022 13:05:09 Marek Beh?n wrote:
> On Sat, 15 Jan 2022 12:50:18 +0100
> Pali Roh?r <pali at kernel.org> wrote:
> 
> > On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > > 
> > > > If I was designing this driver and DTS bindings I would have choose
> > > > something like this:
> > > > 
> > > > uart at 0x12000 {  
> > > 
> > > Drop the 0x
> > >   
> > > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > > >     clock-controller {
> > > >         ...
> > > >     };  
> > > 
> > > Drop this node and put whatever properties are inside into the parent
> > > node.
> > >   
> > > >     serial1 {
> > > >         ...
> > > >         status = "disabled";
> > > >     };
> > > >     serial2 {
> > > >         ...
> > > >         status = "disabled";
> > > >     };
> > > > };
> > > > 
> > > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > > defined in top level nodes and would be handled by one driver.
> > > > 
> > > > This is really how hardware block looks like. But it is not backward
> > > > compatible...  
> > > 
> > > Sounds good to me. I presume we need the serial child nodes so we can
> > > reference them from the stdout-path?  
> > 
> > Yes, exactly, separate nodes for serial1 and serial2 are still required.
> > 
> > But dropping clock controller is not possible as for higher baudrates we
> > need to use and configure uart clock controller. Without it we just get
> > comparable feature support which is already present in driver.
> 
> What Stephen means is making clock controller out of the uart node
> directly. No need to add separate subnode just for clock controller.

This is already implemented in v7 patch series. Clock controller is
already outside of uart nodes.


From christophe.jaillet at wanadoo.fr  Sat Jan 15 04:45:03 2022
From: christophe.jaillet at wanadoo.fr (Christophe JAILLET)
Date: Sat, 15 Jan 2022 13:45:03 +0100
Subject: [PATCH] net: ethernet: sun4i-emac: Fix an error handling path in
 emac_probe()
Message-ID: <aa2344da574f58aeba869a9219b3549dbd65d8e4.1642250684.git.christophe.jaillet@wanadoo.fr>

A dma_request_chan() call is hidden in emac_configure_dma().
It must be released in the probe if an error occurs, as already done in
the remove function.

Add the corresponding dma_release_channel() call.

Fixes: 47869e82c8b8 ("sun4i-emac.c: add dma support")
Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 74635a6fa8ca..621ce742ad21 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -1072,6 +1072,7 @@ static int emac_probe(struct platform_device *pdev)
 	clk_disable_unprepare(db->clk);
 out_dispose_mapping:
 	irq_dispose_mapping(ndev->irq);
+	dma_release_channel(db->rx_chan);
 out_iounmap:
 	iounmap(db->membase);
 out:
-- 
2.32.0



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:50 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:50 +0530
Subject: [PATCHv7 0/5] lib/rwmmio/arm64: Add support to trace register
 reads/writes
Message-ID: <cover.1642233364.git.quic_saipraka@quicinc.com>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

This series is a follow-up for the series [1] and a recent series [2] making use
of both.

[1] https://lore.kernel.org/lkml/cover.1536430404.git.saiprakash.ranjan at codeaurora.org/
[2] https://lore.kernel.org/lkml/1604631386-178312-1-git-send-email-psodagud at codeaurora.org/

Note in previous v4 version, Arnd suggested to benchmark and compare size with callback
based implementation, please see [3] for more details on that with brief comparison below.


**Inline version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
   text           data             bss     dec             hex         filename
 23884219        14284468         532568 38701255        24e88c7        vmlinux

**Callback version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
    text          data             bss     dec             hex        filename
 24108179        14279596         532568 38920343        251e097       vmlinux

$ ./scripts/bloat-o-meter inline-vmlinux callback-vmlinux
add/remove: 8/3 grow/shrink: 4889/89 up/down: 242244/-11564 (230680)
Total: Before=25812612, After=26043292, chg +0.89%

[3] https://lore.kernel.org/lkml/466449a1-36da-aaa9-7e4f-477f36b52c9e at quicinc.com/

Changes in v7:
 * Use lib/ instead of kernel/trace/ based on review comment by Steven Rostedt.

Changes in v6:
 * Implemented suggestions by Arnd Bergmann:
   - Use arch independent IO barriers in arm64/asm
   - Add ARCH_HAVE_TRACE_MMIO_ACCESS
   - Add post read and post write logging support
   - Remove tracepoint_active check
 * Fix build error reported by kernel test robot.

Changes in v5:
 * Move arm64 to use asm-generic provided high level MMIO accessors (Arnd).
 * Add inline logging for MMIO relaxed and non-relaxed accessors.
 * Move nVHE KVM comment to makefile (Marc).
 * Fix overflow warning due to switch to inline accessors instead of macro.
 * Modify trace event field to include caller and parent details for more detailed logs.

Changes in v4:
 * Drop dynamic debug based filter support since that will be developed later with
   the help from Steven (Ftrace maintainer).
 * Drop value passed to writel as it is causing hangs when tracing is enabled.
 * Code cleanup for trace event as suggested by Steven for earlier version.
 * Fixed some build errors reported by 0-day bot.

Changes in v3:
 * Create a generic mmio header for instrumented version (Earlier suggested in [1]
   by Will Deacon and recently [2] by Greg to have a generic version first).
 * Add dynamic debug support to filter out traces which can be very useful for targeted
   debugging specific to subsystems or drivers.
 * Few modifications to the rwmmio trace event fields to include the mmio width and print
   addresses in hex.
 * Rewrote commit msg to explain some more about usecases.

Prasad Sodagudi (1):
  lib: Add register read/write tracing support

Sai Prakash Ranjan (4):
  arm64: io: Use asm-generic high level MMIO accessors
  irqchip/tegra: Fix overflow implicit truncation warnings
  drm/meson: Fix overflow implicit truncation warnings
  asm-generic/io: Add logging support for MMIO accessors

 arch/Kconfig                      |   3 +
 arch/arm64/Kconfig                |   1 +
 arch/arm64/include/asm/io.h       |  41 +++--------
 arch/arm64/kvm/hyp/nvhe/Makefile  |   7 +-
 drivers/gpu/drm/meson/meson_viu.c |  22 +++---
 drivers/irqchip/irq-tegra.c       |  10 +--
 include/asm-generic/io.h          |  81 +++++++++++++++++++--
 include/trace/events/rwmmio.h     | 112 ++++++++++++++++++++++++++++++
 lib/Kconfig                       |   7 ++
 lib/Makefile                      |   2 +
 lib/trace_readwrite.c             |  47 +++++++++++++
 11 files changed, 279 insertions(+), 54 deletions(-)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c

-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:51 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:51 +0530
Subject: [PATCHv7 1/5] arm64: io: Use asm-generic high level MMIO accessors
In-Reply-To: <cover.1642233364.git.quic_saipraka@quicinc.com>
References: <cover.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <bd7e24709080c665312a519227fbd57ac9633eec.1642233364.git.quic_saipraka@quicinc.com>

Remove custom arm64 MMIO accessors read{b,w,l,q} and their relaxed
versions in support to use asm-generic defined accessors. Also define
one set of IO barriers (ar/bw version) used by asm-generic code to
override the arm64 specific variants.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/include/asm/io.h | 41 ++++++++-----------------------------
 1 file changed, 8 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7fd836bea7eb..1b436810d779 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -91,7 +91,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 }
 
 /* IO barriers */
-#define __iormb(v)							\
+#define __io_ar(v)							\
 ({									\
 	unsigned long tmp;						\
 									\
@@ -108,39 +108,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 		     : "memory");					\
 })
 
-#define __io_par(v)		__iormb(v)
-#define __iowmb()		dma_wmb()
-#define __iomb()		dma_mb()
-
-/*
- * Relaxed I/O memory access primitives. These follow the Device memory
- * ordering rules but do not guarantee any ordering relative to Normal memory
- * accesses.
- */
-#define readb_relaxed(c)	({ u8  __r = __raw_readb(c); __r; })
-#define readw_relaxed(c)	({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
-#define readl_relaxed(c)	({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
-#define readq_relaxed(c)	({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
+#define __io_bw()		dma_wmb()
+#define __io_br(v)
+#define __io_aw(v)
 
-#define writeb_relaxed(v,c)	((void)__raw_writeb((v),(c)))
-#define writew_relaxed(v,c)	((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
-#define writel_relaxed(v,c)	((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
-#define writeq_relaxed(v,c)	((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
-
-/*
- * I/O memory access primitives. Reads are ordered relative to any
- * following Normal memory access. Writes are ordered relative to any prior
- * Normal memory access.
- */
-#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(__v); __v; })
-#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(__v); __v; })
-#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(__v); __v; })
-#define readq(c)		({ u64 __v = readq_relaxed(c); __iormb(__v); __v; })
-
-#define writeb(v,c)		({ __iowmb(); writeb_relaxed((v),(c)); })
-#define writew(v,c)		({ __iowmb(); writew_relaxed((v),(c)); })
-#define writel(v,c)		({ __iowmb(); writel_relaxed((v),(c)); })
-#define writeq(v,c)		({ __iowmb(); writeq_relaxed((v),(c)); })
+/* arm64-specific, don't use in portable drivers */
+#define __iormb(v)		__io_ar(v)
+#define __iowmb()		__io_bw()
+#define __iomb()		dma_mb()
 
 /*
  *  I/O port access primitives.
-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:53 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:53 +0530
Subject: [PATCHv7 3/5] drm/meson: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642233364.git.quic_saipraka@quicinc.com>
References: <cover.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <28080ab6447e5daf775ba0af2f20b5ea68f20739.1642233364.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for drm/meson driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/gpu/drm/meson/meson_viu.c: In function ?meson_viu_init?:
drivers/gpu/drm/meson/meson_registers.h:1826:48: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
 #define  VIU_OSD_BLEND_REORDER(dest, src)      ((src) << (dest * 4))
                                                ^
drivers/gpu/drm/meson/meson_viu.c:472:18: note: in expansion of macro ?VIU_OSD_BLEND_REORDER?
   writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
                  ^~~~~~~~~~~~~~~~~~~~~

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/gpu/drm/meson/meson_viu.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 259f3e6bec90..bb7e109534de 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -469,17 +469,17 @@ void meson_viu_init(struct meson_drm *priv)
 			priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
 
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
-		writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
-			       VIU_OSD_BLEND_REORDER(1, 0) |
-			       VIU_OSD_BLEND_REORDER(2, 0) |
-			       VIU_OSD_BLEND_REORDER(3, 0) |
-			       VIU_OSD_BLEND_DIN_EN(1) |
-			       VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
-			       VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
-			       VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
-			       VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
-			       VIU_OSD_BLEND_HOLD_LINES(4),
-			       priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
+		u32 val = (u32)VIU_OSD_BLEND_REORDER(0, 1) |
+			  (u32)VIU_OSD_BLEND_REORDER(1, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(2, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(3, 0) |
+			  (u32)VIU_OSD_BLEND_DIN_EN(1) |
+			  (u32)VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
+			  (u32)VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
+			  (u32)VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
+			  (u32)VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
+			  (u32)VIU_OSD_BLEND_HOLD_LINES(4);
+		writel_relaxed(val, priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
 
 		writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
 			       priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:52 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:52 +0530
Subject: [PATCHv7 2/5] irqchip/tegra: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642233364.git.quic_saipraka@quicinc.com>
References: <cover.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <9b9be40178e4b1677e8d19df45f4bc59ba86ba0f.1642233364.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for tegra irqchip driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/irqchip/irq-tegra.c: In function ?tegra_ictlr_suspend?:
drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
                  ^

Cc: Marc Zyngier <maz at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/irqchip/irq-tegra.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
index e1f771c72fc4..9e4e5b39c701 100644
--- a/drivers/irqchip/irq-tegra.c
+++ b/drivers/irqchip/irq-tegra.c
@@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void)
 		lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
 
 		/* Disable COP interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 
 		/* Disable CPU interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 
 		/* Enable the wakeup sources of ictlr */
 		writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
@@ -172,12 +172,12 @@ static void tegra_ictlr_resume(void)
 
 		writel_relaxed(lic->cpu_iep[i],
 			       ictlr + ICTLR_CPU_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 		writel_relaxed(lic->cpu_ier[i],
 			       ictlr + ICTLR_CPU_IER_SET);
 		writel_relaxed(lic->cop_iep[i],
 			       ictlr + ICTLR_COP_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 		writel_relaxed(lic->cop_ier[i],
 			       ictlr + ICTLR_COP_IER_SET);
 	}
@@ -312,7 +312,7 @@ static int __init tegra_ictlr_init(struct device_node *node,
 		lic->base[i] = base;
 
 		/* Disable all interrupts */
-		writel_relaxed(~0UL, base + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0U, base + ICTLR_CPU_IER_CLR);
 		/* All interrupts target IRQ */
 		writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS);
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:54 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:54 +0530
Subject: [PATCHv7 4/5] lib: Add register read/write tracing support
In-Reply-To: <cover.1642233364.git.quic_saipraka@quicinc.com>
References: <cover.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <a46bbf7fc82df6639367174cf6cadac48ac2e60f.1642233364.git.quic_saipraka@quicinc.com>

From: Prasad Sodagudi <psodagud at codeaurora.org>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following few
cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

Signed-off-by: Prasad Sodagudi <psodagud at codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/Kconfig                  |   3 +
 arch/arm64/Kconfig            |   1 +
 include/trace/events/rwmmio.h | 112 ++++++++++++++++++++++++++++++++++
 lib/Kconfig                   |   7 +++
 lib/Makefile                  |   2 +
 lib/trace_readwrite.c         |  47 ++++++++++++++
 6 files changed, 172 insertions(+)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c

diff --git a/arch/Kconfig b/arch/Kconfig
index fdba59052abc..54dd42db882d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1322,6 +1322,9 @@ config ARCH_HAS_ELFCORE_COMPAT
 config ARCH_HAS_PARANOID_L1D_FLUSH
 	bool
 
+config ARCH_HAVE_TRACE_MMIO_ACCESS
+	bool
+
 config DYNAMIC_SIGFRAME
 	bool
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3bb0b67292b5..eaa48df2c3bd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -46,6 +46,7 @@ config ARM64
 	select ARCH_HAS_ZONE_DMA_SET if EXPERT
 	select ARCH_HAVE_ELF_PROT
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select ARCH_HAVE_TRACE_MMIO_ACCESS
 	select ARCH_INLINE_READ_LOCK if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION
diff --git a/include/trace/events/rwmmio.h b/include/trace/events/rwmmio.h
new file mode 100644
index 000000000000..f66397007258
--- /dev/null
+++ b/include/trace/events/rwmmio.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rwmmio
+
+#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RWMMIO_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(rwmmio_write,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		(void *)(unsigned long)__entry->caller, __entry->width,
+		__entry->val, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_post_write,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		(void *)(unsigned long)__entry->caller, __entry->width,
+		__entry->val, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_read,
+
+	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_post_read,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width,
+		 __entry->val, __entry->addr)
+);
+
+#endif /* _TRACE_RWMMIO_H */
+
+#include <trace/define_trace.h>
diff --git a/lib/Kconfig b/lib/Kconfig
index c80fde816a7e..ea520c315c0f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
 	  mmio accesses when the IO memory address is not a registered
 	  emulated region.
 
+config TRACE_MMIO_ACCESS
+	bool "Register read/write tracing"
+	depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
+	help
+	  Create tracepoints for MMIO read/write operations. These trace events
+	  can be used for logging all MMIO read/write operations.
+
 source "lib/crypto/Kconfig"
 
 config CRC_CCITT
diff --git a/lib/Makefile b/lib/Makefile
index 300f569c626b..43813b0061cd 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -152,6 +152,8 @@ lib-y += logic_pio.o
 
 lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
 
+obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
+
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
 obj-$(CONFIG_BTREE) += btree.o
diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
new file mode 100644
index 000000000000..88637038b30c
--- /dev/null
+++ b/lib/trace_readwrite.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Register read and write tracepoints
+ *
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <asm-generic/io.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/rwmmio.h>
+
+#ifdef CONFIG_TRACE_MMIO_ACCESS
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr)
+{
+	trace_rwmmio_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
+
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr)
+{
+	trace_rwmmio_post_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
+
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr)
+{
+	trace_rwmmio_read(caller_addr, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
+
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr)
+{
+	trace_rwmmio_post_read(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:14:55 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:44:55 +0530
Subject: [PATCHv7 5/5] asm-generic/io: Add logging support for MMIO accessors
In-Reply-To: <cover.1642233364.git.quic_saipraka@quicinc.com>
References: <cover.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <8085e36ca19787ae111e4cfbb5c555e65bd34be6.1642233364.git.quic_saipraka@quicinc.com>

Add logging support for MMIO high level accessors such as read{b,w,l,q}
and their relaxed versions to aid in debugging unexpected crashes/hangs
caused by the corresponding MMIO operation. Also add a generic flag
(__DISABLE_TRACE_MMIO__) which is used to disable MMIO tracing in nVHE KVM
and if required can be used to disable MMIO tracing for specific drivers.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---

Used _THIS_IP_ instead of CALLER_ADDR0 in MMIO accessors as using CALLER_ADDR0
was resulting in parent caller information which was not accurate such as below,

rwmmio_read: raw_notifier_call_chain+0x50/0x70 width=32 addr=0xffff800010040000

Use of _THIS_IP_ also helps in keeping ftrace.h away from asm-generic/io.h which
would have resulted in tons of header inclusion issues.

---
 arch/arm64/kvm/hyp/nvhe/Makefile |  7 ++-
 include/asm-generic/io.h         | 81 ++++++++++++++++++++++++++++++--
 2 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 24b2c2425b38..228d1f8921c3 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -4,7 +4,12 @@
 #
 
 asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
-ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
+
+# Tracepoint and MMIO logging symbols should not be visible at nVHE KVM as
+# there is no way to execute them and any such MMIO access from nVHE KVM
+# will explode instantly (Words of Marc Zyngier). So introduce a generic flag
+# __DISABLE_TRACE_MMIO__ to disable MMIO tracing for nVHE KVM.
+ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__
 
 hostprogs := gen-hyprel
 HOST_EXTRACFLAGS += -I$(objtree)/include
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 7ce93aaf69f8..96d144d3a26f 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -61,6 +61,35 @@
 #define __io_par(v)     __io_ar(v)
 #endif
 
+#if IS_ENABLED(CONFIG_TRACE_MMIO_ACCESS) && !(defined(__DISABLE_TRACE_MMIO__))
+#include <linux/tracepoint-defs.h>
+
+DECLARE_TRACEPOINT(rwmmio_write);
+DECLARE_TRACEPOINT(rwmmio_post_write);
+DECLARE_TRACEPOINT(rwmmio_read);
+DECLARE_TRACEPOINT(rwmmio_post_read);
+
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr);
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr);
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr);
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr);
+
+#else
+
+static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				  unsigned long caller_addr) {}
+static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				       unsigned long caller_addr) {}
+static inline void log_read_mmio(u8 width, const volatile void __iomem *addr,
+				 unsigned long caller_addr) {}
+static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+				      unsigned long caller_addr) {}
+
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
 
 /*
  * __raw_{read,write}{b,w,l,q}() access memory in native endianness.
@@ -149,9 +178,11 @@ static inline u8 readb(const volatile void __iomem *addr)
 {
 	u8 val;
 
+	log_read_mmio(8, addr, _THIS_IP_);
 	__io_br();
 	val = __raw_readb(addr);
 	__io_ar(val);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -162,9 +193,11 @@ static inline u16 readw(const volatile void __iomem *addr)
 {
 	u16 val;
 
+	log_read_mmio(16, addr, _THIS_IP_);
 	__io_br();
 	val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -175,9 +208,11 @@ static inline u32 readl(const volatile void __iomem *addr)
 {
 	u32 val;
 
+	log_read_mmio(32, addr, _THIS_IP_);
 	__io_br();
 	val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -189,9 +224,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 {
 	u64 val;
 
+	log_read_mmio(64, addr, _THIS_IP_);
 	__io_br();
 	val = __le64_to_cpu(__raw_readq(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -201,9 +238,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 #define writeb writeb
 static inline void writeb(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeb(value, addr);
 	__io_aw();
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -211,9 +250,11 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
 #define writew writew
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writew((u16 __force)cpu_to_le16(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -221,9 +262,11 @@ static inline void writew(u16 value, volatile void __iomem *addr)
 #define writel writel
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writel((u32 __force)__cpu_to_le32(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -232,9 +275,11 @@ static inline void writel(u32 value, volatile void __iomem *addr)
 #define writeq writeq
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeq(__cpu_to_le64(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 #endif /* CONFIG_64BIT */
@@ -248,7 +293,12 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
 #define readb_relaxed readb_relaxed
 static inline u8 readb_relaxed(const volatile void __iomem *addr)
 {
-	return __raw_readb(addr);
+	u8 val;
+
+	log_read_mmio(8, addr, _THIS_IP_);
+	val = __raw_readb(addr);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -256,7 +306,12 @@ static inline u8 readb_relaxed(const volatile void __iomem *addr)
 #define readw_relaxed readw_relaxed
 static inline u16 readw_relaxed(const volatile void __iomem *addr)
 {
-	return __le16_to_cpu(__raw_readw(addr));
+	u16 val;
+
+	log_read_mmio(16, addr, _THIS_IP_);
+	val = __le16_to_cpu(__raw_readw(addr));
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -264,7 +319,12 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
 #define readl_relaxed readl_relaxed
 static inline u32 readl_relaxed(const volatile void __iomem *addr)
 {
-	return __le32_to_cpu(__raw_readl(addr));
+	u32 val;
+
+	log_read_mmio(32, addr, _THIS_IP_);
+	val = __le32_to_cpu(__raw_readl(addr));
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -272,7 +332,12 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
 #define readq_relaxed readq_relaxed
 static inline u64 readq_relaxed(const volatile void __iomem *addr)
 {
-	return __le64_to_cpu(__raw_readq(addr));
+	u64 val;
+
+	log_read_mmio(64, addr, _THIS_IP_);
+	val =__le64_to_cpu(__raw_readq(addr));
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -280,7 +345,9 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
 #define writeb_relaxed writeb_relaxed
 static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__raw_writeb(value, addr);
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -288,7 +355,9 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 #define writew_relaxed writew_relaxed
 static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__raw_writew(cpu_to_le16(value), addr);
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -296,7 +365,9 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 #define writel_relaxed writel_relaxed
 static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__raw_writel(__cpu_to_le32(value), addr);
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -304,7 +375,9 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 #define writeq_relaxed writeq_relaxed
 static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__raw_writeq(__cpu_to_le64(value), addr);
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Sat Jan 15 05:18:00 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Sat, 15 Jan 2022 18:48:00 +0530
Subject: [PATCHv6 4/5] tracing: Add register read/write tracing support
In-Reply-To: <b36d92de-ae0b-243d-f2de-e12fe730f6c4@quicinc.com>
References: <cover.1638858746.git.quic_saipraka@quicinc.com>
 <76983c26d889df7252a17017a48754163fb6b0d5.1638858747.git.quic_saipraka@quicinc.com>
 <20220106131824.073fbe5c@gandalf.local.home>
 <df9b5a82-5f00-f3ec-14cf-0b212be2a7a7@quicinc.com>
 <20220107095638.7d81c1b9@gandalf.local.home>
 <b36d92de-ae0b-243d-f2de-e12fe730f6c4@quicinc.com>
Message-ID: <65fa7fdb-1af9-152b-32a2-8388921be565@quicinc.com>

On 1/8/2022 11:04 AM, Sai Prakash Ranjan wrote:
> Hi,
>
> On 1/7/2022 8:26 PM, Steven Rostedt wrote:
>> On Fri, 7 Jan 2022 10:40:05 +0530
>> Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
>>
>>> Hi Steve,
>>>
>>> On 1/6/2022 11:48 PM, Steven Rostedt wrote:
>>>> This should not be in the kernel/trace directory. It should be in the
>>> Hmm these are called from low level generic io header file
>>> (include/asm-generic/) where
>>> we wouldn't have any Kconfig to control this feature flexibly and as we
>>> can have this as
>>> a generic feature selectable by other architectures, wouldn't this be
>>> suited in kernel/trace?
>> Isn't there a place for generic rwmmio code?
>
> I am thinking of moving it to lib/ similar to an interface of 
> logic_iomem.c which
> Arnd had initially suggested to look at.
>
>>> I thought you were ok with the folder structure in the initial versions
>>> of the series?
>> Sorry, I missed the C file in kernel/trace. The files in kernel/trace 
>> tend
>> to be specific for the internals of tracing. This C file is more to hold
>> helper functions for mmio, which to me should be someplace for mmio 
>> code.
>> Perhaps in mm/ ?
>>
>
> Oh ok, mm would not be the right fit as it is memory management and 
> this is about
> memory mapped IO, let me try and move it to lib/ as done for 
> logic_iomem.c
>
> Thanks,
> Sai

Posted v7 - 
https://lore.kernel.org/lkml/cover.1642233364.git.quic_saipraka at quicinc.com/

Thanks,
Sai


From jic23 at jic23.retrosnub.co.uk  Sat Jan 15 07:02:08 2022
From: jic23 at jic23.retrosnub.co.uk (Jonathan Cameron)
Date: Sat, 15 Jan 2022 15:02:08 +0000
Subject: [PATCH v1 2/2] iio: adc: mt8186: Add compatible node for mt8186
In-Reply-To: <292950d7-d057-4e66-5d0d-a5144f50f2ce@collabora.com>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
 <20220110084841.575-2-guodong.liu@mediatek.com>
 <292950d7-d057-4e66-5d0d-a5144f50f2ce@collabora.com>
Message-ID: <20220115150208.15fb6284@jic23-huawei>

On Mon, 10 Jan 2022 11:01:28 +0100
AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> wrote:

> Il 10/01/22 09:48, Guodong Liu ha scritto:
> > This commit adds mt8186 compatible node.
> > 
> > Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>  
> 
> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Applied with a slight tweak to patch 2 as an earlier tidyup added
a bracket before the } in the table so make this line match as well.

Applied to the togreg branch of iio.git and pushed out as testing for
0-day to poke at it for us.  I'll be rebasing the tree after rc1 is out.

Thanks,
Jonathan

> 
> > ---
> >   drivers/iio/adc/mt6577_auxadc.c | 6 ++++++
> >   1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
> > index d4fccd52ef08..fb08d761589a 100644
> > --- a/drivers/iio/adc/mt6577_auxadc.c
> > +++ b/drivers/iio/adc/mt6577_auxadc.c
> > @@ -46,6 +46,11 @@ struct mt6577_auxadc_device {
> >   	const struct mtk_auxadc_compatible *dev_comp;
> >   };
> >   
> > +static const struct mtk_auxadc_compatible mt8186_compat = {
> > +	.sample_data_cali = false,
> > +	.check_global_idle = false,
> > +};
> > +
> >   static const struct mtk_auxadc_compatible mt8173_compat = {
> >   	.sample_data_cali = false,
> >   	.check_global_idle = true,
> > @@ -334,6 +339,7 @@ static const struct of_device_id mt6577_auxadc_of_match[] = {
> >   	{ .compatible = "mediatek,mt2712-auxadc", .data = &mt8173_compat},
> >   	{ .compatible = "mediatek,mt7622-auxadc", .data = &mt8173_compat},
> >   	{ .compatible = "mediatek,mt8173-auxadc", .data = &mt8173_compat},
> > +	{ .compatible = "mediatek,mt8186-auxadc", .data = &mt8186_compat},
> >   	{ .compatible = "mediatek,mt6765-auxadc", .data = &mt6765_compat},
> >   	{ }
> >   };
> >   



From alim.akhtar at samsung.com  Sat Jan 15 07:31:24 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sat, 15 Jan 2022 21:01:24 +0530
Subject: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <CAL_JsqKDbzy8y61Oj8Ey++atoMn1HYPyDZRc_cJQCe_tfkDGxQ@mail.gmail.com>
References: <CGME20220113122413epcas5p46cb2cafb73936c423017240f98f72845@epcas5p4.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220113121143.22280-15-alim.akhtar@samsung.com>
 <CAL_JsqKDbzy8y61Oj8Ey++atoMn1HYPyDZRc_cJQCe_tfkDGxQ@mail.gmail.com>
Message-ID: <08ba01d80a24$f79a88f0$e6cf9ad0$@samsung.com>



>-----Original Message-----
>From: Rob Herring [mailto:robh+dt at kernel.org]
>Sent: Friday, January 14, 2022 8:16 AM
>To: Alim Akhtar <alim.akhtar at samsung.com>
>Cc: linux-arm-kernel <linux-arm-kernel at lists.infradead.org>; linux-
>kernel at vger.kernel.org; SoC Team <soc at kernel.org>; linux-clk <linux-
>clk at vger.kernel.org>; devicetree at vger.kernel.org; Olof Johansson
><olof at lixom.net>; Linus Walleij <linus.walleij at linaro.org>; Catalin Marinas
><catalin.marinas at arm.com>; Krzysztof Kozlowski
><krzysztof.kozlowski at canonical.com>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; linux-samsung-soc <linux-samsung-
>soc at vger.kernel.org>; Pankaj Dubey <pankaj.dubey at samsung.com>; linux-
>fsd at tesla.com; Arjun K V <arjun.kv at samsung.com>; Aswani Reddy
><aswani.reddy at samsung.com>; Ajay Kumar <ajaykumar.rs at samsung.com>;
>Sriranjani P <sriranjani.p at samsung.com>; Chandrasekar R
><rcsekar at samsung.com>; Shashank Prashar <s.prashar at samsung.com>
>Subject: Re: [PATCH 14/23] arm64: dts: fsd: Add initial device tree support
>
>On Thu, Jan 13, 2022 at 6:24 AM Alim Akhtar <alim.akhtar at samsung.com>
>wrote:
>>
>> Add initial device tree support for "Full Self-Driving" (FSD) SoC This
>> SoC contain three clusters of four cortex-a72 CPUs and various
>> peripheral IPs.
>
>Please make sure you run this thru 'make dtbs_check'. Fix schema warnings as
>much as possible and all dtc warnings. If shared with Samsung, there's
>probably a bit still missing. I see several warnings so I won't bother manually
>reporting them here.
>
Thanks Rob for review, let me fix them in patch set v2.

>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
>> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
>> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
>> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  MAINTAINERS                        |   8 +
>>  arch/arm64/Kconfig.platforms       |   6 +
>>  arch/arm64/boot/dts/Makefile       |   1 +
>>  arch/arm64/boot/dts/tesla/Makefile |   3 +
>>  arch/arm64/boot/dts/tesla/fsd.dts  | 140 ++++++
>> arch/arm64/boot/dts/tesla/fsd.dtsi | 715
>+++++++++++++++++++++++++++++
>>  6 files changed, 873 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dts  create mode
>> 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS index
>> fb18ce7168aa..02d56909c5e2 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -2726,6 +2726,14 @@ S:       Maintained
>>  F:     Documentation/devicetree/bindings/media/tegra-cec.txt
>>  F:     drivers/media/cec/platform/tegra/
>>
>> +ARM/TESLA FSD SoC SUPPORT
>> +M:     Alim Akhtar <alim.akhtar at samsung.com>
>> +M:     linux-fsd at tesla.com
>> +L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>> +L:     linux-samsung-soc at vger.kernel.org
>> +S:     Maintained
>> +F:     arch/arm64/boot/dts/tesla*
>> +
>>  ARM/TETON BGA MACHINE SUPPORT
>>  M:     "Mark F. Brown" <mark.brown314 at gmail.com>
>>  L:     linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>> diff --git a/arch/arm64/Kconfig.platforms
>> b/arch/arm64/Kconfig.platforms index 54e3910e8b9b..bb8a047c2359 100644
>> --- a/arch/arm64/Kconfig.platforms
>> +++ b/arch/arm64/Kconfig.platforms
>> @@ -267,6 +267,12 @@ config ARCH_TEGRA
>>         help
>>           This enables support for the NVIDIA Tegra SoC family.
>>
>> +config ARCH_TESLA_FSD
>> +       bool "ARMv8 based Tesla platform"
>> +       select ARCH_EXYNOS
>> +       help
>> +         Support for ARMv8 based Tesla platforms.
>> +
>>  config ARCH_SPRD
>>         bool "Spreadtrum SoC platform"
>>         help
>> diff --git a/arch/arm64/boot/dts/Makefile
>> b/arch/arm64/boot/dts/Makefile index 639e01a4d855..1ba04e31a438
>100644
>> --- a/arch/arm64/boot/dts/Makefile
>> +++ b/arch/arm64/boot/dts/Makefile
>> @@ -27,6 +27,7 @@ subdir-y += rockchip  subdir-y += socionext
>> subdir-y += sprd  subdir-y += synaptics
>> +subdir-y += tesla
>>  subdir-y += ti
>>  subdir-y += toshiba
>>  subdir-y += xilinx
>> diff --git a/arch/arm64/boot/dts/tesla/Makefile
>> b/arch/arm64/boot/dts/tesla/Makefile
>> new file mode 100644
>> index 000000000000..a9818cda6b08
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/tesla/Makefile
>> @@ -0,0 +1,3 @@
>> +# SPDX-License-Identifier: GPL-2.0
>> +dtb-$(CONFIG_ARCH_TESLA_FSD) += \
>> +       fsd.dtb
>> diff --git a/arch/arm64/boot/dts/tesla/fsd.dts
>> b/arch/arm64/boot/dts/tesla/fsd.dts
>> new file mode 100644
>> index 000000000000..e9bbd3284de9
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/tesla/fsd.dts
>> @@ -0,0 +1,140 @@
>> +// SPDX-License-Identifier: GPL-2.0
>
>Dual license dts files please.
>
>> +/*
>> + * Tesla FSD board device tree source
>> + *
>> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
>> + *             https://www.samsung.com
>> + * Copyright (c) 2017-2021 Tesla, Inc.
>> + *             https://www.tesla.com
>> + */
>> +
>> +/dts-v1/;
>> +#include "fsd.dtsi"
>> +
>> +/ {
>> +       model = "Tesla Full Self-Driving (FSD) SoC";
>> +       compatible = "tesla,fsd";
>> +
>> +       aliases {
>> +               serial0 = &serial_0;
>> +               serial1 = &serial_1;
>> +       };
>> +
>> +       chosen {
>> +               stdout-path = &serial_0;
>
>> +               linux,initrd-start = <0xE0000000>;
>> +               linux,initrd-end = <0xE4F00000>;
>
>Bootloaders set these.
>
>> +               bootargs = "console=ttySAC0,115200n8
>
>Not needed with stdout-path.
>
>> +                       earlycon=exynos4210,0x14180000 root=/dev/ram0
>
>earlycon is a debug option.
>
>> +                       init=/linuxrc";
>
>init and rootfs are user settings.
>
>> +       };
>> +
>> +       memory at 80000000 {
>> +               device_type = "memory";
>> +               reg = <0x0 0x80000000 0x2 0x00000000>;
>> +       };
>> +};
>> +
>> +&fin_pll {
>> +       clock-frequency = <24000000>;
>> +};
>> +
>> +&serial_0 {
>> +       status = "okay";
>> +};
>> +
>> +&serial_1 {
>> +       status = "okay";
>> +};
>> +
>> +&clock_cmu {
>> +       status = "okay";
>> +};
>> +
>> +&clock_imem {
>> +       status = "okay";
>> +};
>> +
>> +&clock_peric {
>> +       status = "okay";
>> +};
>> +
>> +&smmu_isp {
>> +       status = "okay";
>> +};
>> +
>> +&clock_fsys0 {
>> +       status = "okay";
>> +};
>> +
>> +&clock_fsys1 {
>> +       status = "okay";
>> +};
>> +
>> +&smmu_peric {
>> +       status = "okay";
>> +};
>> +
>> +&smmu_imem {
>> +       status = "okay";
>> +};
>> +
>> +&smmu_fsys0 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_0 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_1 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_2 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_3 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_4 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_5 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_6 {
>> +       status = "okay";
>> +};
>> +
>> +&hsi2c_7 {
>> +       status = "okay";
>> +};
>> +
>> +&pwm_0 {
>> +       status = "okay";
>> +};
>> +
>> +&pwm_1 {
>> +       status = "okay";
>> +};
>> +
>> +&mdma0 {
>> +       status = "okay";
>> +};
>> +
>> +&mdma1 {
>> +       status = "okay";
>> +};
>> +
>> +&pdma0 {
>> +       status = "okay";
>> +};
>> +
>> +&pdma1 {
>> +       status = "okay";
>> +};
>> diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi
>> b/arch/arm64/boot/dts/tesla/fsd.dtsi
>> new file mode 100644
>> index 000000000000..47cd9f20566e
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
>> @@ -0,0 +1,715 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Tesla Full Self-Driving SoC device tree source
>> + *
>> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
>> + *             https://www.samsung.com
>> + * Copyright (c) 2017-2022 Tesla, Inc.
>> + *             https://www.tesla.com
>> + */
>> +
>> +#include <dt-bindings/clock/fsd-clk.h> #include
>> +<dt-bindings/interrupt-controller/arm-gic.h>
>> +
>> +/ {
>> +       compatible = "tesla,fsd";
>> +       interrupt-parent = <&gic>;
>> +       #address-cells = <2>;
>> +       #size-cells = <2>;
>> +
>> +       aliases {
>> +               watchdog0 = &watchdog_0;
>> +               watchdog1 = &watchdog_1;
>> +               watchdog2 = &watchdog_2;
>> +               hsi2c0 = &hsi2c_0;
>> +               hsi2c1 = &hsi2c_1;
>> +               hsi2c2 = &hsi2c_2;
>> +               hsi2c3 = &hsi2c_3;
>> +               hsi2c4 = &hsi2c_4;
>> +               hsi2c5 = &hsi2c_5;
>> +               hsi2c6 = &hsi2c_6;
>> +               hsi2c7 = &hsi2c_7;
>
>Drop all these non-standard aliases.
>
>> +       };
>> +
>> +       cpus {
>> +               #address-cells = <2>;
>> +               #size-cells = <0>;
>> +
>> +               cpu-map {
>> +                       cluster0 {
>> +                               core0 {
>> +                                       cpu = <&cpucl0_0>;
>> +                               };
>> +                               core1 {
>> +                                       cpu = <&cpucl0_1>;
>> +                               };
>> +                               core2 {
>> +                                       cpu = <&cpucl0_2>;
>> +                               };
>> +                               core3 {
>> +                                       cpu = <&cpucl0_3>;
>> +                               };
>> +                       };
>> +
>> +                       cluster1 {
>> +                               core0 {
>> +                                       cpu = <&cpucl1_0>;
>> +                               };
>> +                               core1 {
>> +                                       cpu = <&cpucl1_1>;
>> +                               };
>> +                               core2 {
>> +                                       cpu = <&cpucl1_2>;
>> +                               };
>> +                               core3 {
>> +                                       cpu = <&cpucl1_3>;
>> +                               };
>> +                       };
>> +
>> +                       cluster2 {
>> +                               core0 {
>> +                                       cpu = <&cpucl2_0>;
>> +                               };
>> +                               core1 {
>> +                                       cpu = <&cpucl2_1>;
>> +                               };
>> +                               core2 {
>> +                                       cpu = <&cpucl2_2>;
>> +                               };
>> +                               core3 {
>> +                                       cpu = <&cpucl2_3>;
>> +                               };
>> +                       };
>> +               };
>> +
>> +               /* Cluster 0 */
>> +               cpucl0_0: cpu at 0 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x000>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl0_1: cpu at 1 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x001>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl0_2: cpu at 2 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x002>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl0_3: cpu at 3 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x003>;
>> +                               enable-method = "psci";
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               /* Cluster 1 */
>> +               cpucl1_0: cpu at 100 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x100>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl1_1: cpu at 101 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x101>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl1_2: cpu at 102 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x102>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl1_3: cpu at 103 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x103>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               /* Cluster 2 */
>> +               cpucl2_0: cpu at 200 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x200>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl2_1: cpu at 201 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x201>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl2_2: cpu at 202 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x202>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               cpucl2_3: cpu at 203 {
>> +                               device_type = "cpu";
>> +                               compatible = "arm,cortex-a72";
>> +                               reg = <0x0 0x203>;
>> +                               enable-method = "psci";
>> +                               clock-frequency = <2400000000>;
>> +                               cpu-idle-states = <&CPU_SLEEP>;
>> +                               next-level-cache = <&L2_0>;
>> +               };
>> +
>> +               idle-states {
>> +                       entry-method = "arm,psci";
>> +
>> +                       CPU_SLEEP: cpu-sleep {
>> +                               idle-state-name = "c2";
>> +                               compatible = "arm,idle-state";
>> +                               local-timer-stop;
>> +                               arm,psci-suspend-param = <0x0010000>;
>> +                               entry-latency-us = <30>;
>> +                               exit-latency-us = <75>;
>> +                               min-residency-us = <300>;
>> +                               status = "okay";
>> +                       };
>> +               };
>> +
>> +               L2_0: l2-cache0 {
>> +                       compatible = "cache";
>> +               };
>> +       };
>> +
>> +       arm-pmu {
>> +               compatible = "arm,armv8-pmuv3";
>> +               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
>> +                            <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
>> +               interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
>> +                                    <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
>> +                                    <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
>> +                                    <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
>> +       };
>> +
>> +       psci {
>> +               compatible = "arm,psci";
>> +               method = "smc";
>
>> +               cpu_on = <0xC4000003>;
>> +               cpu_suspend = <0xC4000001>;
>> +               cpu_off = <0x84000002>;
>
>These codes are standardized since forever. Fix your firmware.
>
>> +       };
>> +
>> +       timer {
>> +               compatible = "arm,armv8-timer";
>> +               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
>> +                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
>> +                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
>> +                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
>> +       };
>> +
>> +       fin_pll: clock {
>> +               compatible = "fixed-clock";
>> +               clock-output-names = "fin_pll";
>> +               #clock-cells = <0>;
>> +       };
>> +
>> +       soc: soc {
>
>soc at 0
>
>You should see a warning for this.
>
>> +               compatible = "simple-bus";
>> +               #address-cells = <2>;
>> +               #size-cells = <2>;
>> +               ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
>> +               dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
>> +
>> +               gic: interrupt-controller at 10400000 {
>> +                       compatible = "arm,gic-v3";
>> +                       #interrupt-cells = <3>;
>> +                       interrupt-controller;
>> +                       reg =   <0x0 0x10400000 0x0 0x10000>, /* GICD */
>> +                               <0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
>> +               };
>> +
>> +               smmu_isp: iommu at 12100000 {
>> +                       compatible = "arm,mmu-500";
>> +                       reg = <0x0 0x12100000 0x0 0x10000>;
>> +                       #iommu-cells = <2>;
>> +                       #global-interrupts = <11>;
>> +                       interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global
>secure fault */
>> +                                    <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-
>secure fault */
>> +                                    <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>secure interrupt */
>> +                                    <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>non-secure interrupt */
>> +                                    /* Performance counter interrupts */
>> +                                    <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI
>*/
>> +                                    <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0
>*/
>> +                                    <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1
>*/
>> +                                    <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for
>CAM_ISP_0 */
>> +                                    <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for
>CAM_ISP_1 */
>> +                                    <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for
>CAM_MFC_0 */
>> +                                    <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for
>CAM_MFC_1 */
>> +                                    /* Per context non-secure context interrupts, 0-7
>interrupts */
>> +                                    <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_0 */
>> +                                    <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_1 */
>> +                                    <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_2 */
>> +                                    <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_3 */
>> +                                    <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_4 */
>> +                                    <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_5 */
>> +                                    <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_6 */
>> +                                    <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for
>CONTEXT_7 */
>> +                       status = "disabled";
>
>IOMMU isn't really board specific, should it really be disabled?
>
>> +               };
>> +
>> +               smmu_imem: iommu at 10200000 {
>> +                       compatible = "arm,mmu-500";
>> +                       reg = <0x0 0x10200000 0x0 0x10000>;
>> +                       #iommu-cells = <2>;
>> +                       #global-interrupts = <7>;
>> +                       interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global
>secure fault */
>> +                                    <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-
>secure fault */
>> +                                    <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>secure interrupt */
>> +                                    <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>non-secure interrupt */
>> +                                    /* Performance counter interrupts */
>> +                                    <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
>> +                                    <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
>> +                                    <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0
>*/
>> +                                    /* Per context non-secure context interrupts, 0-3
>interrupts */
>> +                                    <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_0 */
>> +                                    <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_1 */
>> +                                    <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_2 */
>> +                                    <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for
>CONTEXT_3 */
>> +                       status = "disabled";
>> +               };
>> +
>> +               smmu_peric: iommu at 14900000 {
>> +                       compatible = "arm,mmu-500";
>> +                       reg = <0x0 0x14900000 0x0 0x10000>;
>> +                       #iommu-cells = <2>;
>> +                       #global-interrupts = <5>;
>> +                       interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global
>secure fault */
>> +                                    <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-
>secure fault */
>> +                                    <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>secure interrupt */
>> +                                    <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>non-secure interrupt */
>> +                                    /* Performance counter interrupts */
>> +                                    <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
>> +                                    /* Per context non-secure context interrupts, 0-1
>interrupts */
>> +                                    <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for
>CONTEXT_0 */
>> +                                    <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for
>CONTEXT_1 */
>> +                       status = "disabled";
>> +               };
>> +
>> +               smmu_fsys0: iommu at 15450000 {
>> +                       compatible = "arm,mmu-500";
>> +                       reg = <0x0 0x15450000 0x0 0x10000>;
>> +                       #iommu-cells = <2>;
>> +                       #global-interrupts = <5>;
>> +                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global
>secure fault */
>> +                                    <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-
>secure fault */
>> +                                    <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined
>secure interrupt */
>> +                                    <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-
>secure interrupt */
>> +                                    /* Performance counter interrupts */
>> +                                    <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
>> +                                    /* Per context non-secure context interrupts, 0-1
>interrupts */
>> +                                    <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0
>*/
>> +                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1
>*/
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_cmu: clock-controller at 11C10000 {
>
>Lowercase hex for unit-addresses.
>
>Also, arrange nodes in address order.
>
>> +                       compatible = "tesla,fsd-clock-cmu";
>> +                       reg = <0x0 0x11C10000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "fin_pll";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_imem: clock-controller at 10010000 {
>> +                       compatible = "tesla,fsd-clock-imem";
>> +                       reg = <0x0 0x10010000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>,
>> +                               <&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
>> +                               <&clock_cmu DOUT_CMU_IMEM_ACLK>,
>> +                               <&clock_cmu DOUT_CMU_IMEM_DMACLK>;
>> +                       clock-names = "fin_pll",
>> +                               "dout_cmu_imem_tcuclk",
>> +                               "dout_cmu_imem_aclk",
>> +                               "dout_cmu_imem_dmaclk";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_peric: clock-controller at 14010000 {
>> +                       compatible = "tesla,fsd-clock-peric";
>> +                       reg = <0x0 0x14010000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>,
>> +                               <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
>> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
>> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
>> +                               <&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
>> +                               <&clock_cmu
>DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
>> +                       clock-names = "fin_pll",
>> +                               "dout_cmu_pll_shared0_div4",
>> +                               "dout_cmu_peric_shared1div36",
>> +                               "dout_cmu_peric_shared0div3_tbuclk",
>> +                               "dout_cmu_peric_shared0div20",
>> +                               "dout_cmu_peric_shared1div4_dmaclk";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_fsys0: clock-controller at 15010000 {
>> +                       compatible = "tesla,fsd-clock-fsys0";
>> +                       reg = <0x0 0x15010000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>,
>> +                               <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
>> +                               <&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
>> +                               <&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
>> +                       clock-names = "fin_pll",
>> +                               "dout_cmu_pll_shared0_div6",
>> +                               "dout_cmu_fsys0_shared1div4",
>> +                               "dout_cmu_fsys0_shared0div4";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_fsys1: clock-controller at 16810000 {
>> +                       compatible = "tesla,fsd-clock-fsys1";
>> +                       reg = <0x0 0x16810000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>,
>> +                               <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
>> +                               <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
>> +                       clock-names = "fin_pll",
>> +                               "dout_cmu_fsys1_shared0div8",
>> +                               "dout_cmu_fsys1_shared0div4";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_mfc: clock-controller at 12810000 {
>> +                       compatible = "tesla,fsd-clock-mfc";
>> +                       reg = <0x0 0x12810000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "fin_pll";
>> +                       status = "disabled";
>> +               };
>> +
>> +               clock_csi: clock-controller at 12610000 {
>> +                       compatible = "tesla,fsd-clock-cam_csi";
>> +                       reg = <0x0 0x12610000 0x0 0x3000>;
>> +                       #clock-cells = <1>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "fin_pll";
>> +                       status = "disabled";
>> +               };
>> +
>> +               mdma0: mdma at 10100000 {
>> +                       compatible = "arm,pl330", "arm,primecell";
>> +                       reg = <0x0 0x10100000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #dma-cells = <1>;
>> +                       #dma-channels = <8>;
>> +                       #dma-requests = <32>;
>> +                       clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
>> +                       clock-names = "apb_pclk";
>> +                       iommus = <&smmu_imem 0x800 0x0>;
>> +                       status = "disabled";
>> +               };
>> +
>> +               mdma1: mdma at 10110000 {
>> +                       compatible = "arm,pl330", "arm,primecell";
>> +                       reg = <0x0 0x10110000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #dma-cells = <1>;
>> +                       #dma-channels = <8>;
>> +                       #dma-requests = <32>;
>> +                       clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
>> +                       clock-names = "apb_pclk";
>> +                       iommus = <&smmu_imem 0x801 0x0>;
>> +                       status = "disabled";
>> +               };
>> +
>> +               pdma0: pdma at 14280000 {
>> +                       compatible = "arm,pl330", "arm,primecell";
>> +                       reg = <0x0 0x14280000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #dma-cells = <1>;
>> +                       #dma-channels = <8>;
>> +                       #dma-requests = <32>;
>> +                       clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
>> +                       clock-names = "apb_pclk";
>> +                       iommus = <&smmu_peric 0x2 0x0>;
>> +                       status = "disabled";
>> +               };
>> +
>> +               pdma1: pdma at 14290000 {
>> +                       compatible = "arm,pl330", "arm,primecell";
>> +                       reg = <0x0 0x14290000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #dma-cells = <1>;
>> +                       #dma-channels = <8>;
>> +                       #dma-requests = <32>;
>> +                       clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
>> +                       clock-names = "apb_pclk";
>> +                       iommus = <&smmu_peric 0x1 0x0>;
>> +                       status = "disabled";
>> +               };
>> +
>> +               mct: mct at 10040000 {
>> +                       compatible = "samsung,exynos4210-mct";
>> +                       reg = <0x0 0x10040000 0x0 0x800>;
>> +                       interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
>> +                               <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
>> +                       clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>;
>> +                       clock-names = "fin_pll", "mct";
>> +               };
>> +
>> +               serial_0: serial at 14180000 {
>> +                       compatible = "samsung,exynos4210-uart";
>> +                       reg = <0x0 0x14180000 0x0 0x100>;
>> +                       interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
>> +                       dmas = <&pdma1 0>, <&pdma1 1>;
>> +                       dma-names = "tx", "rx";
>> +                       clocks = <&clock_peric PERIC_PCLK_UART0>,
>> +                                <&clock_peric PERIC_SCLK_UART0>;
>> +                       clock-names = "uart", "clk_uart_baud0";
>> +                       status = "disabled";
>> +               };
>> +
>> +               serial_1: serial at 14190000 {
>> +                       compatible = "samsung,exynos4210-uart";
>> +                       reg = <0x0 0x14190000 0x0 0x100>;
>> +                       interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
>> +                       dmas = <&pdma1 2>, <&pdma1 3>;
>> +                       dma-names = "tx", "rx";
>> +                       clocks = <&clock_peric PERIC_PCLK_UART1>,
>> +                                <&clock_peric PERIC_SCLK_UART1>;
>> +                       clock-names = "uart", "clk_uart_baud0";
>> +                       status = "disabled";
>> +               };
>> +
>> +               pmu_system_controller: system-controller at 11400000 {
>> +                       compatible = "samsung,exynos7-pmu", "syscon";
>> +                       reg = <0x0 0x11400000 0x0 0x5000>;
>> +               };
>> +
>> +               watchdog_0: watchdog at 100A0000 {
>> +                       compatible = "samsung,exynos7-wdt";
>> +                       reg = <0x0 0x100A0000 0x0 0x100>;
>> +                       interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
>> +                       samsung,syscon-phandle = <&pmu_system_controller>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "watchdog";
>> +                       interrupt-mode = <1>;
>> +               };
>> +
>> +               watchdog_1: watchdog at 100B0000 {
>> +                       compatible = "samsung,exynos7-wdt";
>> +                       reg = <0x0 0x100B0000 0x0 0x100>;
>> +                       interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
>> +                       samsung,syscon-phandle = <&pmu_system_controller>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "watchdog";
>> +                       interrupt-mode = <1>;
>> +               };
>> +
>> +               watchdog_2: watchdog at 100C0000 {
>> +                       compatible = "samsung,exynos7-wdt";
>> +                       reg = <0x0 0x100C0000 0x0 0x100>;
>> +                       interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
>> +                       samsung,syscon-phandle = <&pmu_system_controller>;
>> +                       clocks = <&fin_pll>;
>> +                       clock-names = "watchdog";
>> +                       interrupt-mode = <1>;
>> +               };
>> +
>> +               pwm_0: pwm at 14100000 {
>> +                       compatible = "samsung,exynos4210-pwm";
>> +                       reg = <0x0 0x14100000 0x0 0x100>;
>> +                       samsung,pwm-outputs = <0>, <1>, <2>, <3>;
>> +                       #pwm-cells = <3>;
>> +                       clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
>> +                       clock-names = "timers";
>> +                       status = "disabled";
>> +               };
>> +
>> +               pwm_1: pwm at 14110000 {
>> +                       compatible = "samsung,exynos4210-pwm";
>> +                       reg = <0x0 0x14110000 0x0 0x100>;
>> +                       samsung,pwm-outputs = <0>, <1>, <2>, <3>;
>> +                       #pwm-cells = <3>;
>> +                       clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
>> +                       clock-names = "timers";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_0: hsi2c at 14200000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14200000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c0_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_1: hsi2c at 14210000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14210000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c1_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_2: hsi2c at 14220000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14220000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c2_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_3: hsi2c at 14230000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14230000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c3_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_4: hsi2c at 14240000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14240000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c4_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_5: hsi2c at 14250000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14250000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c5_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_6: hsi2c at 14260000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14260000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c6_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +
>> +               hsi2c_7: hsi2c at 14270000 {
>> +                       compatible = "samsung,exynos7-hsi2c";
>> +                       reg = <0x0 0x14270000 0x0 0x1000>;
>> +                       interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +                       pinctrl-names = "default";
>> +                       pinctrl-0 = <&hs_i2c7_bus>;
>> +                       clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
>> +                       clock-names = "hsi2c";
>> +                       status = "disabled";
>> +               };
>> +       };
>> +};
>> --
>> 2.17.1
>>



From jic23 at kernel.org  Sat Jan 15 07:41:07 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 15 Jan 2022 15:41:07 +0000
Subject: [PATCH 1/3] iio: adc: sun4i-gpadc-iio: no temp sensor on R40
In-Reply-To: <85db7e8a-2b9a-7e44-ec96-b804201a3491@wirenboard.com>
References: <20211119191456.510435-1-boger@wirenboard.com>
 <20211119191456.510435-2-boger@wirenboard.com>
 <20211122091132.yjudzei3bdqmnxq6@gilmour>
 <20211122124115.00005186@Huawei.com>
 <85db7e8a-2b9a-7e44-ec96-b804201a3491@wirenboard.com>
Message-ID: <20220115154052.51634f37@jic23-huawei>

On Tue, 11 Jan 2022 16:13:02 +0300
Evgeny Boger <boger at wirenboard.com> wrote:

> 22.11.2021 15:41, Jonathan Cameron ?????:
> > On Mon, 22 Nov 2021 10:11:32 +0100
> > Maxime Ripard <maxime at cerno.tech> wrote:
> >  
> >> On Fri, Nov 19, 2021 at 10:14:54PM +0300, Evgeny Boger wrote:  
> >>> R40 SoC has touchscreen controller also serving as general-purpose ADC.
> >>> The hardware is very similar to A31, except that R40 has separate
> >>> calibrated thermal sensor IP (handled by sun8i_thermal).
> >>>
> >>> Despite the temperature sensor in the RTP is never mentioned in
> >>> the R40 family user manuals, it appears to be working. However,
> >>> it's not very useful as it lacks calibration data and there is another
> >>> fully functioning temperature sensor anyway.
> >>>
> >>> This patch disables the temperature sensor in RTP/GPADC IP on R40.
> >>>
> >>> The reason for disabling the temperature sensor is that the IP
> >>> needs to be switched back and forth between RTP and GPADC modes for
> >>> temperature measurements. Not only this introduces delays, but it also
> >>> disturbs external circuitry by injecting current into ADC inputs.
> >>>
> >>> Signed-off-by: Evgeny Boger <boger at wirenboard.com>  
> >> Acked-by: Maxime Ripard <maxime at cerno.tech>  
> > +Cc linux-iio at vger.kernel.org
> >
> > I'm fine with this and assuming Lee is happy to pick it up + send
> > me an immutable branch in case anything crosses with it this cycle..
> >
> > Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>  
> 
> Hi Jonathan!
> 
> Is there anything else I should do to make this patch series accepted?

Perhaps try a resend to Lee Jones, making sure to cc linux-iio
Chances are it just got missed in the deluge!

Jonathan


> 
> 
> > Thanks,
> >
> > Jonathan
> >  
> >> Maxime
> >>  
> 



From krzysztof.kozlowski at canonical.com  Sat Jan 15 07:46:56 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 16:46:56 +0100
Subject: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to
 dtschema
In-Reply-To: <CAPLW+4k3VNuQGfi_mnAWYUSXYaPmoFj1D55pHH0ByUsNu9kSyQ@mail.gmail.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4k3VNuQGfi_mnAWYUSXYaPmoFj1D55pHH0ByUsNu9kSyQ@mail.gmail.com>
Message-ID: <cced7901-a855-c733-e716-f4a7f822b213@canonical.com>

On 14/01/2022 19:31, Sam Protsenko wrote:
> On Tue, 11 Jan 2022 at 22:15, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Hi,
>>
>> Changes since v1
>> ================
>> 1. Patch #1: add missing pin assignment (Alim).
>> 2. Patch #2: correct double sizeof() (Alim).
>> 3. Patch #7, #8: put label-override in proper patch (Alim).
>> 4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
>> 5. New patches: #25 - #28.
>>    Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
>>    handling, so they need their own compatibles.
>>    Please kindly review and provide feedback on these as I do not have
>>    details.
>> 6. Add review tags.
>>
>> Dependencies
>> ============
>> 1. Patch #2 ("pinctrl: samsung: accept GPIO bank nodes with a suffix") is
>>    necessary for DTS patches.
>>
>> 2. Last patches #27 and #28 depend on patch #26 adding the compatibles.
>>
>> Best regards,
>> Krzysztof
>>
>> Krzysztof Kozlowski (28):
>>   pinctrl: samsung: drop pin banks references on error paths
>>   pinctrl: samsung: accept GPIO bank nodes with a suffix
>>   ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
>>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
>>   ARM: dts: exynos: override pins by label in Peach Pit
>>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
>>   ARM: dts: exynos: override pins by label in Peach Pi
>>   ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
>>   ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
>>   ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
>>   arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
>>   arm64: dts: exynos: align pinctrl with dtschema in Exynos7
>>   arm64: dts: exynos: align pinctrl with dtschema in Exynos850
>>   arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
>>   ARM: dts: s3c24xx: align pinctrl with dtschema
>>   ARM: dts: s3c64xx: align pinctrl with dtschema
>>   ARM: dts: s5pv210: align pinctrl with dtschema
>>   dt-bindings: pinctrl: samsung: convert to dtschema
>>   dt-bindings: pinctrl: samsung: describe Exynos850 and ExynosAutov9
>>     wake-ups
>>   pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups
>>   arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
>>     Exynos850
>>   arm64: dts: exynos: use dedicated wake-up pinctrl compatible in
>>     ExynosAutov9
>>
> 
> Maybe it makes sense to include my patch [1] for gpm6/gpm7 in this series?
> 
> [1] https://lore.kernel.org/linux-arm-kernel/20220103181826.2136-1-semen.protsenko at linaro.org/T/
> 

Yes, if I am going to resend, I'll include yours. Otherwise, I will try
to remember when applying.


Best regards,
Krzysztof


From robh at kernel.org  Sat Jan 15 08:02:00 2022
From: robh at kernel.org (Rob Herring)
Date: Sat, 15 Jan 2022 10:02:00 -0600
Subject: [PATCH 1/2] PCI: dra7xx: Fix link removal on probe error
In-Reply-To: <4579940c-27dc-733e-4022-ebea4671c839@lucaceresoli.net>
References: <20211214221450.589884-1-luca@lucaceresoli.net>
 <CAL_Jsq+GQTcx1EGKHug2ZcDZufrKM-4k6PB0vQeTCTG42MHzvA@mail.gmail.com>
 <59a23c89-0810-eb28-acd9-7051ac34d438@lucaceresoli.net>
 <4579940c-27dc-733e-4022-ebea4671c839@lucaceresoli.net>
Message-ID: <CAL_JsqJ5nr6xJoTv3A6UPMMDXhWKcwSEUA3ux3kK8OMWQxdc6w@mail.gmail.com>

+Saravana

On Tue, Jan 11, 2022 at 4:35 AM Luca Ceresoli <luca at lucaceresoli.net> wrote:
>
> Hi Rob,
>
> On 16/12/21 10:08, Luca Ceresoli wrote:
> > Hi Rob,
> >
> > thanks for the quick feedback!
> >
> > On 14/12/21 23:42, Rob Herring wrote:
> >> On Tue, Dec 14, 2021 at 4:15 PM Luca Ceresoli <luca at lucaceresoli.net> wrote:
> >>>
> >>> If a devm_phy_get() calls fails with phy_count==N (N > 0), then N links
> >>> have already been added by device_link_add() and won't be deleted by
> >>> device_link_del() because the code calls 'return' and not 'goto err_link'.
> >>>
> >>> Fix in a very simple way by doing all the devm_phy_get() calls before all
> >>> the device_link_add() calls.
> >>>
> >>> Fixes: 7a4db656a635 ("PCI: dra7xx: Create functional dependency between PCIe and PHY")
> >>> Signed-off-by: Luca Ceresoli <luca at lucaceresoli.net>
> >>> ---
> >>>  drivers/pci/controller/dwc/pci-dra7xx.c | 2 ++
> >>>  1 file changed, 2 insertions(+)
> >>>
> >>> diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
> >>> index f7f1490e7beb..2ccc53869e13 100644
> >>> --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> >>> +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> >>> @@ -757,7 +757,9 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
> >>>                 phy[i] = devm_phy_get(dev, name);
> >>>                 if (IS_ERR(phy[i]))
> >>>                         return PTR_ERR(phy[i]);
> >>> +       }
> >>>
> >>> +       for (i = 0; i < phy_count; i++) {
> >>>                 link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
> >>
> >> I think this should happen automatically now with fw_devlink being
> >> enabled by default. Can you try?
> >
> > Do you mean removal should be done automatically? I think they are not
> > due to the DL_FLAG_STATELESS flag.
>
> I would love to have feedback because, as said, I think my patch is
> correct, but if I'm wrong (which might well be) I have to drop patch 1
> and rewrite patch 2 in a slightly more complex form.

I mean that why do you need explicit dependency tracking here when
dependencies on a PHY should happen automatically now. IOW, what is
special about this driver and dependency?

Rob


From henrik at grimler.se  Sat Jan 15 08:27:00 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat, 15 Jan 2022 17:27:00 +0100
Subject: [PATCH v2 0/3] Add initial support for exynos5420-chagallwifi
Message-ID: <20220115162703.699347-1-henrik@grimler.se>

Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename chagallwifi
and is one of several tablets released in 2013 - 2014 based on Exynos
5420.  This initial devicetree adds support for accessing device over
USB or UART, and allows using a rootfs in either the internal eMMC or
an external sdcard.  4 out of 8 CPUs are brought up when device boots,
which is the same as on the somewhat similar device
exynos5420-arndale-octa.

Patch 2 is necessary after a secure-firmware node is added, otherwise
device hangs during the CPU1BOOT secure monitor call. Without the
secure-firmware node we are not able to bring up any secondary CPUs.

Changes since v1
================

Fix mmc_0 and usbdrd in patch 3: 
* Remove extra, non supported, options from mmc_0 node 
* Do not set usbdrd supplies. Usb networking does not work with them 
  specified, but it works fine with dummy regulators

Henrik Grimler (3):
  dt-bindings: arm: samsung: document chagallwifi board binding
  ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
  ARM: dts: Add support for Samsung Chagallwifi

 .../bindings/arm/samsung/samsung-boards.yaml  |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagallwifi.dts  |  57 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 633 ++++++++++++++++++
 arch/arm/mach-exynos/firmware.c               |   4 +-
 5 files changed, 695 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagallwifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

-- 
2.34.1



From henrik at grimler.se  Sat Jan 15 08:27:01 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat, 15 Jan 2022 17:27:01 +0100
Subject: [PATCH v2 1/3] dt-bindings: arm: samsung: document chagallwifi board
 binding
In-Reply-To: <20220115162703.699347-1-henrik@grimler.se>
References: <20220115162703.699347-1-henrik@grimler.se>
Message-ID: <20220115162703.699347-2-henrik@grimler.se>

Add binding for Samsung Galaxy Tab S 10.5", based on Exynos 5420 with
codename chagallwifi. It was released in 2014 and has several siblings
with similar hardware.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 052cd94113d4..3f2ffb0d7b46 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -140,6 +140,7 @@ properties:
         items:
           - enum:
               - insignal,arndale-octa           # Insignal Arndale Octa
+              - samsung,chagallwifi             # Samsung SM-T800
               - samsung,smdk5420                # Samsung SMDK5420 eval
           - const: samsung,exynos5420
           - const: samsung,exynos5
-- 
2.34.1



From henrik at grimler.se  Sat Jan 15 08:27:02 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat, 15 Jan 2022 17:27:02 +0100
Subject: [PATCH v2 2/3] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
In-Reply-To: <20220115162703.699347-1-henrik@grimler.se>
References: <20220115162703.699347-1-henrik@grimler.se>
Message-ID: <20220115162703.699347-3-henrik@grimler.se>

On Exynos5 the call is simply ignored by most variants of the
trustzone firmware.  However, on some devices it instead causes the
device to hang, so let's avoid the call for the SoCs where it should
not be needed.

To see that the call is ignored, we can look into sboot/tzsw.  On most
of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
the secure monitor calls is quite easy to recognise, the SMC number is
compared to known ones, and if equal it branches to the relevant
function.  In assembly this looks something like:

;-- handle_smc:
0x00000514      650070e3       cmn r0, 0x65
0x00000518      0a00000a       beq loc.smc_cmd_reg
0x0000051c      010070e3       cmn r0, 1
0x00000520      6c00000a       beq loc.smc_cmd_init
0x00000524      020070e3       cmn r0, 2
0x00000528      6b00000a       beq loc.smc_cmd_info
0x0000052c      030070e3       cmn r0, 3
0x00000530      6e00000a       beq loc.smc_cmd_sleep
0x00000534      060070e3       cmn r0, 6
0x00000538      ae00000a       beq loc.smc_cmd_save_state
0x0000053c      070070e3       cmn r0, 7
0x00000540      b400000a       beq loc.smc_cmd_standby
0x00000544      2b01001a       bne loc.smc_return_minus1

where above example is from exynos5420-arndale-octa.  As can be seen
the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
annotations are taken from github.com/hsnaves/exynos5410-firmware,
where a large part of the exynos5410 trustzone firmware has been
reverse-engineered.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
Sent previously as RFC
---
 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
 	/*
 	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
 	 * because Exynos3250 removes WFE in secure mode.
+	 *
+	 * On Exynos5 devices the call is ignored by trustzone firmware.
 	 */
-	if (soc_is_exynos3250())
+	if (!soc_is_exynos4210() && !soc_is_exynos4412())
 		return 0;
 
 	/*
-- 
2.34.1



From henrik at grimler.se  Sat Jan 15 08:27:03 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat, 15 Jan 2022 17:27:03 +0100
Subject: [PATCH v2 3/3] ARM: dts: Add support for Samsung Chagallwifi
In-Reply-To: <20220115162703.699347-1-henrik@grimler.se>
References: <20220115162703.699347-1-henrik@grimler.se>
Message-ID: <20220115162703.699347-4-henrik@grimler.se>

Chagallwifi, with product name Samsung Galaxy Tab S 10.5", is based on
Exynos 5420. This device is one of several tablet models released in
2013 - 2014 based on Exynos 5420.

The device tree added here contains support for:

- UART
- eMMC
- SD card
- USB

CCI has been disabled in the hardware, enabling it would require
(de-)soldering a resistor on the board.  Trying to boot with it
enabled in kernel makes the device hang when CCI is probed.
Exynos5420-arndale-octa also has had CCI disabled due to issues [1].

To successfully boot the mainline kernel with the stock bootloader
(SBOOT), an additional hack is needed [2]. The same hack is also
needed to boot exynos4412-i9300 with stock bootloader, and probably
other Samsung devices of similar age.

[1] https://marc.info/?l=linux-arm-kernel&m=141718639200624
[2] https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com/

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagallwifi.dts  |  57 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 633 ++++++++++++++++++
 3 files changed, 691 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagallwifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..be7a493ff1a1 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-arndale-octa.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5420-smdk5420.dtb \
+	exynos5420-chagallwifi.dtb \
 	exynos5422-odroidhc1.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
diff --git a/arch/arm/boot/dts/exynos5420-chagallwifi.dts b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
new file mode 100644
index 000000000000..51eb2bbe6bf6
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Chagallwifi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+	model = "Samsung Chagallwifi based on exynos5420";
+	compatible = "samsung,chagallwifi", "samsung,exynos5420", \
+		     "samsung,exynos5";
+};
+
+&s2mps11 {
+	regulators {
+		ldo15_reg: LDO15 {
+			/* Unused */
+			regulator-name = "VDD_LDO15";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		ldo17_reg: LDO17 {
+			regulator-name = "VDD_IRLED_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3350000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo28_reg: LDO28 {
+			/* Unused */
+			regulator-name = "VDD_LDO28";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+		};
+
+		ldo29_reg: LDO29 {
+			regulator-name = "VDD_TCON_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
new file mode 100644
index 000000000000..408d0f1d4b44
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
@@ -0,0 +1,633 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base DT for Samsung's family of tablets based on Exynos5420.
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include "exynos5420-cpus.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/samsung,s2mps11.h>
+
+/ {
+	compatible = "samsung,exynos5420", "samsung,exynos5";
+	chassis-type = "tablet";
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x20000000 0xc0000000>;
+	};
+
+	firmware at 2073000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x02073000 0x1000>;
+	};
+
+	fixed-rate-clocks {
+		oscclk {
+			compatible = "samsung,exynos5420-oscclk";
+			clock-frequency = <24000000>;
+		};
+
+		xxti {
+			compatible = "samsung,clock-xxti";
+			clock-frequency = <24000000>;
+		};
+
+		xusbxti {
+			compatible = "samsung,clock-xusbxti";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+
+		power {
+			debounce-interval = <10>;
+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+
+		home {
+			debounce-interval = <10>;
+			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
+			label = "Home";
+			linux,code = <KEY_HOME>;
+			wakeup-source;
+		};
+
+		volume-up {
+			debounce-interval = <10>;
+			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		volume-down {
+			debounce-interval = <10>;
+			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+};
+
+&cci {
+	/* CCI is disabled in hardware */
+	status = "disabled";
+};
+
+&cpu0 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&buck6_reg>;
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&buck4_reg>;
+};
+
+&hsi2c_7 {
+	status = "okay";
+
+	s2mps11: pmic at 66 {
+		compatible = "samsung,s2mps11-pmic";
+		reg = <0x66>;
+
+		interrupt-parent = <&gpx3>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&s2mps11_irq>;
+
+		s2mps11_osc: clocks {
+			compatible = "samsung,s2mps11-clk";
+			#clock-cells = <1>;
+			clock-output-names = "s2mps11_ap", "s2mps11_cp",
+					     "s2mps11_bt";
+		};
+
+		buck1_reg: BUCK1 {
+			regulator-name = "VDD_MIF_1V1";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+				regulator-suspend-microvolt = <1100000>;
+			};
+		};
+
+		buck2_reg: BUCK2 {
+			regulator-name = "VDD_ARM_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-ramp-delay = <12500>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck3_reg: BUCK3 {
+			regulator-name = "VDD_INT_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+				regulator-suspend-microvolt = <1100000>;
+			};
+		};
+
+		buck4_reg: BUCK4 {
+			regulator-name = "VDD_G3D_1V0";
+			regulator-min-microvolt = <700000>;
+			regulator-max-microvolt = <1400000>;
+			regulator-always-on;
+			regulator-boot-on;
+			regulator-ramp-delay = <12500>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck5_reg: BUCK5 {
+			regulator-name = "VDD_MEM_1V2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		buck6_reg: BUCK6 {
+			regulator-name = "VDD_KFC_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		buck7_reg: BUCK7 {
+			regulator-name = "VIN_LLDO_1V4";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1500000>;
+			regulator-always-on;
+		};
+
+		buck8_reg: BUCK8 {
+			regulator-name = "VIN_MLDO_2V0";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2100000>;
+			regulator-always-on;
+		};
+
+		buck9_reg: BUCK9 {
+			regulator-name = "VIN_HLDO_3V5";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3500000>;
+			regulator-always-on;
+		};
+
+		buck10_reg: BUCK10 {
+			regulator-name = "VDD_CAM_ISP_1V0";
+			regulator-min-microvolt = <750000>;
+			regulator-max-microvolt = <3550000>;
+		};
+
+		ldo1_reg: LDO1 {
+			regulator-name = "VDD_ALIVE_1.0V";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+		};
+
+		ldo2_reg: LDO2 {
+			regulator-name = "VDD_APIO_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo3_reg: LDO3 {
+			regulator-name = "VDD_APIO_MMC2_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo4_reg: LDO4 {
+			regulator-name = "VDD_ADC_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo5_reg: LDO5 {
+			/* Unused */
+			regulato-name = "VDD_LDO5";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		ldo6_reg: LDO6 {
+			regulator-name = "VDD_MIPI_1V0";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo7_reg: LDO7 {
+			regulator-name = "VDD_MIPI_PLL_ABB1_18V";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo8_reg: LDO8 {
+			/* Unused */
+			regulator-name = "VDD_LDO8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+		ldo9_reg: LDO9 {
+			regulator-name = "VDD_UOTG_3V0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo10_reg: LDO10 {
+			regulator-name = "VDDQ_PRE_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo11_reg: LDO11 {
+			regulator-name = "VDD_HSIC_1V0";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo12_reg: LDO12 {
+			regulator-name = "VDD_HSIC_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		ldo13_reg: LDO13 {
+			regulator-name = "VDD_APIO_MMC2_2V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo14_reg: LDO14 {
+			regulator-name = "VDD_MOTOR_3V0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO15 varies between devices and is
+		 * specified in the device dts
+		 */
+
+		ldo16_reg: LDO16 {
+			regulator-name = "VDD_AP_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO17 varies between devices and is
+		 * specified in the device dts
+		 */
+
+		ldo18_reg: LDO18 {
+			/* Unused */
+			regulator-name = "VDD_LDO18";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+		};
+
+
+		ldo19_reg: LDO19 {
+			regulator-name = "VDD_VTF_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo20_reg: LDO20 {
+			regulator-name = "VDD_CAM1_CAM_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo21_reg: LDO21 {
+			regulator-name = "VDD_CAM_IO_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo22_reg: LDO22 {
+			regulator-name = "VDD_CAM0_S_CORE_1V1";
+			regulator-min-microvolt = <1050000>;
+			regulator-max-microvolt = <1200000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo23_reg: LDO23 {
+			regulator-name = "VDD_MIFS_1V1";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		ldo24_reg: LDO24 {
+			regulator-name = "VDD_TSP_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo25_reg: LDO25 {
+			/* Unused */
+			regulator-name = "VDD_LDO25";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo26_reg: LDO26 {
+			regulator-name = "VDD_CAM0_AF_2V8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo27_reg: LDO27 {
+			regulator-name = "VDD_G3DS_1V0";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-always-on;
+
+			regulator-state-mem {
+				regulator-on-in-suspend;
+			};
+		};
+
+		/*
+		 * LDO28 and LDO29 varies between devices and
+		 * are specified in the device dts
+		 */
+
+		ldo30_reg: LDO30 {
+			regulator-name = "VDD_TOUCH_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo31_reg: LDO31 {
+			regulator-name = "VDD_GRIP_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-always-on;
+			regulator-boot-on;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo32_reg: LDO32 {
+			regulator-name = "VDD_TSP_1V8";
+			regulator-min-microvolt = <1900000>;
+			regulator-max-microvolt = <1900000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo33_reg: LDO33 {
+			regulator-name = "VDD_MHL_1V8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo34_reg: LDO34 {
+			regulator-name = "VDD_MHL_3V3";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo35_reg: LDO35 {
+			regulator-name = "VDD_SIL_1V2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+
+		ldo36_reg: LDO36 {
+			/* Unused */
+			regulator-name = "VDD_LDO36";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo37_reg: LDO37 {
+			/* Unused */
+			regulator-name = "VDD_LDO37";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <3950000>;
+		};
+
+		ldo38_reg: LDO38 {
+			regulator-name = "VDD_KEY_LED_3V3";
+			regulator-min-microvolt = <2500000>;
+			regulator-max-microvolt = <3300000>;
+
+			regulator-state-mem {
+				regulator-off-in-suspend;
+			};
+		};
+	};
+};
+
+&mixer {
+	status = "okay";
+};
+
+/* Internal storage */
+&mmc_0 {
+	status = "okay";
+	non-removable;
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	mmc-hs200-1_8v;
+};
+
+/* External sdcard */
+&mmc_2 {
+	status = "okay";
+	card-detect-delay = <200>;
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	bus-width = <4>;
+	cap-sd-highspeed;
+	sd-uhs-sdr50;
+};
+
+&pinctrl_0 {
+	s2mps11_irq: s2mps11-irq-pins {
+		samsung,pins = "gpx3-2";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&tmu_cpu0 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu1 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu2 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu3 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_gpu {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "peripheral";
+};
-- 
2.34.1



From lkp at intel.com  Sat Jan 15 08:33:33 2022
From: lkp at intel.com (kernel test robot)
Date: Sun, 16 Jan 2022 00:33:33 +0800
Subject: [PATCHv7 5/5] asm-generic/io: Add logging support for MMIO
 accessors
In-Reply-To: <8085e36ca19787ae111e4cfbb5c555e65bd34be6.1642233364.git.quic_saipraka@quicinc.com>
References: <8085e36ca19787ae111e4cfbb5c555e65bd34be6.1642233364.git.quic_saipraka@quicinc.com>
Message-ID: <202201160019.hrsMYj6V-lkp@intel.com>

Hi Sai,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on next-20220115]
[cannot apply to arm64/for-next/core arnd-asm-generic/master arm-perf/for-next/perf linus/master v5.16 v5.16-rc8 v5.16-rc7 v5.16]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Sai-Prakash-Ranjan/lib-rwmmio-arm64-Add-support-to-trace-register-reads-writes/20220115-211708
base:    bd8d9cef2a7932e688ca267ea1adf5ea6557c777
config: nios2-defconfig (https://download.01.org/0day-ci/archive/20220116/202201160019.hrsMYj6V-lkp at intel.com/config)
compiler: nios2-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/0757812bba83a756f73ce1a84c86ded3e276cd0f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Sai-Prakash-Ranjan/lib-rwmmio-arm64-Add-support-to-trace-register-reads-writes/20220115-211708
        git checkout 0757812bba83a756f73ce1a84c86ded3e276cd0f
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nios2 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from arch/nios2/include/asm/io.h:41,
                    from include/linux/io.h:13,
                    from arch/nios2/include/asm/pgtable.h:18,
                    from include/linux/pgtable.h:6,
                    from arch/nios2/kernel/nios2_ksyms.c:11:
   include/asm-generic/io.h: In function 'readb':
>> include/asm-generic/io.h:181:32: error: '_THIS_IP_' undeclared (first use in this function)
     181 |         log_read_mmio(8, addr, _THIS_IP_);
         |                                ^~~~~~~~~
   include/asm-generic/io.h:181:32: note: each undeclared identifier is reported only once for each function it appears in
   include/asm-generic/io.h: In function 'readw':
   include/asm-generic/io.h:196:33: error: '_THIS_IP_' undeclared (first use in this function)
     196 |         log_read_mmio(16, addr, _THIS_IP_);
         |                                 ^~~~~~~~~
   include/asm-generic/io.h: In function 'readl':
   include/asm-generic/io.h:211:33: error: '_THIS_IP_' undeclared (first use in this function)
     211 |         log_read_mmio(32, addr, _THIS_IP_);
         |                                 ^~~~~~~~~
   include/asm-generic/io.h: In function 'writeb':
   include/asm-generic/io.h:241:40: error: '_THIS_IP_' undeclared (first use in this function)
     241 |         log_write_mmio(value, 8, addr, _THIS_IP_);
         |                                        ^~~~~~~~~
   include/asm-generic/io.h: In function 'writew':
   include/asm-generic/io.h:253:41: error: '_THIS_IP_' undeclared (first use in this function)
     253 |         log_write_mmio(value, 16, addr, _THIS_IP_);
         |                                         ^~~~~~~~~
   include/asm-generic/io.h: In function 'writel':
   include/asm-generic/io.h:265:41: error: '_THIS_IP_' undeclared (first use in this function)
     265 |         log_write_mmio(value, 32, addr, _THIS_IP_);
         |                                         ^~~~~~~~~


vim +/_THIS_IP_ +181 include/asm-generic/io.h

   169	
   170	/*
   171	 * {read,write}{b,w,l,q}() access little endian memory and return result in
   172	 * native endianness.
   173	 */
   174	
   175	#ifndef readb
   176	#define readb readb
   177	static inline u8 readb(const volatile void __iomem *addr)
   178	{
   179		u8 val;
   180	
 > 181		log_read_mmio(8, addr, _THIS_IP_);
   182		__io_br();
   183		val = __raw_readb(addr);
   184		__io_ar(val);
   185		log_post_read_mmio(val, 8, addr, _THIS_IP_);
   186		return val;
   187	}
   188	#endif
   189	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:34:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:34:28 +0100
Subject: [PATCH 3/3] ARM: dts: Add support for Samsung Chagallwifi
In-Reply-To: <20220113154019.74434-4-henrik@grimler.se>
References: <20220113154019.74434-1-henrik@grimler.se>
 <20220113154019.74434-4-henrik@grimler.se>
Message-ID: <99e33cde-1304-a098-cd7b-8da8408d8052@canonical.com>

On 13/01/2022 16:40, Henrik Grimler wrote:
> Chagallwifi, with product name Samsung Galaxy Tab S 10.5", is based on
> Exynos 5420. This device is one of several tablet models released in
> 2013 - 2014 based on Exynos 5420.
> 
> The device tree added here contains support for:
> 
> - UART
> - eMMC
> - SD card
> - USB
> 

Thanks for the patches. It is a really nice work, good job!

Some comments below.

> CCI has been disabled in the hardware, enabling it would require
> (de-)soldering a resistor on the board.  Trying to boot with it
> enabled in kernel makes the device hang when CCI is probed.
> Exynos5420-arndale-octa also has had CCI disabled due to issues [1].
> 
> To successfully boot the mainline kernel with the stock bootloader
> (SBOOT), an additional hack is needed [2]. The same hack is also
> needed to boot exynos4412-i9300 with stock bootloader, and probably
> other Samsung devices of similar age.
> 
> [1] https://marc.info/?l=linux-arm-kernel&m=141718639200624

Commits should use 'commit SHA_12char ("subject")' format instead of
links to mailing lists.

> [2] https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com/
> 
> Signed-off-by: Henrik Grimler <henrik at grimler.se>
> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  arch/arm/boot/dts/exynos5420-chagallwifi.dts  |  57 ++
>  .../dts/exynos5420-galaxy-tab-common.dtsi     | 647 ++++++++++++++++++
>  3 files changed, 705 insertions(+)
>  create mode 100644 arch/arm/boot/dts/exynos5420-chagallwifi.dts
>  create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..be7a493ff1a1 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
>  	exynos5420-arndale-octa.dtb \
>  	exynos5420-peach-pit.dtb \
>  	exynos5420-smdk5420.dtb \
> +	exynos5420-chagallwifi.dtb \

The name is something like Chagall WiFi, Chagall-WiFi or other
variations, because the device family name is Chagall and WiFi is variant.
Therefore here, patch 1/3, the compatible and all names, please make:
 - exynos5420-chagall-wifi.dtb
 - "samsung,chagall-wifi"
etc.

>  	exynos5422-odroidhc1.dtb \
>  	exynos5422-odroidxu3.dtb \
>  	exynos5422-odroidxu3-lite.dtb \
> diff --git a/arch/arm/boot/dts/exynos5420-chagallwifi.dts b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
> new file mode 100644
> index 000000000000..51eb2bbe6bf6
> --- /dev/null
> +++ b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
> @@ -0,0 +1,57 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Samsung's Exynos5420 Chagallwifi board device tree source
> + *
> + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Copyright (c) 2022 Henrik Grimler
> + */
> +
> +/dts-v1/;
> +#include "exynos5420-galaxy-tab-common.dtsi"

Do you plan to have more Galaxy Tab versions?

> +
> +/ {
> +	model = "Samsung Chagallwifi based on exynos5420";

"Chagall WiFi"?

> +	compatible = "samsung,chagallwifi", "samsung,exynos5420", \
> +		     "samsung,exynos5";
> +};
> +
> +&s2mps11 {
> +	regulators {
> +		ldo15_reg: LDO15 {

Please define these regulator nodes in DTSI (only name needed and
comment like you have there) and override them by label (&ldo15_reg { ...).

> +			/* Unused */
> +			regulator-name = "VDD_LDO15";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +		};
> +
> +		ldo17_reg: LDO17 {
> +			regulator-name = "VDD_IRLED_3V3";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3350000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo28_reg: LDO28 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO28";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +		};
> +
> +		ldo29_reg: LDO29 {
> +			regulator-name = "VDD_TCON_1V8";
> +			regulator-min-microvolt = <1900000>;
> +			regulator-max-microvolt = <1900000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +	};
> +};
> diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> new file mode 100644
> index 000000000000..cbcf1c117b67
> --- /dev/null
> +++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> @@ -0,0 +1,647 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Base DT for Samsung's family of tablets based on Exynos5420.
> + *
> + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Copyright (c) 2022 Henrik Grimler
> + */
> +
> +/dts-v1/;
> +#include "exynos5420.dtsi"
> +#include "exynos5420-cpus.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clock/samsung,s2mps11.h>
> +
> +/ {
> +	compatible = "samsung,exynos5420", "samsung,exynos5";

Skip the compatible. It duplicates exynos5420.dtsi and does not bring
any more information here.

> +	chassis-type = "tablet";
> +
> +	chosen {
> +		stdout-path = "serial2:115200n8";
> +	};
> +
> +	memory at 20000000 {
> +		device_type = "memory";
> +		reg = <0x20000000 0xc0000000>;
> +	};
> +
> +	firmware at 2073000 {
> +		compatible = "samsung,secure-firmware";
> +		reg = <0x02073000 0x1000>;
> +	};
> +
> +	fixed-rate-clocks {
> +		oscclk {
> +			compatible = "samsung,exynos5420-oscclk";
> +			clock-frequency = <24000000>;
> +		};
> +
> +		xxti {
> +			compatible = "samsung,clock-xxti";
> +			clock-frequency = <24000000>;
> +		};
> +
> +		xusbxti {
> +			compatible = "samsung,clock-xusbxti";
> +			clock-frequency = <24000000>;
> +		};

Just keep one clock - oscclk. We treat it as alias of xxti, even though
it might not be exactly alias. I am not sure about real differences, but
anyway the driver does not care about xxti and xusbxti. xusbxti appears
in Exynos5420 only partially, e.g. not in all places like ballmap. Other
boards have only oscclk, so let's do the same.

> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +
> +		power {

key-power and so on.

> +			debounce-interval = <10>;
> +			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
> +			label = "Power";
> +			linux,code = <KEY_POWER>;
> +			wakeup-source;
> +		};
> +
> +		home {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
> +			label = "Home";
> +			linux,code = <KEY_HOME>;
> +			wakeup-source;
> +		};
> +
> +		volume-up {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
> +			label = "Volume Up";
> +			linux,code = <KEY_VOLUMEUP>;
> +		};
> +
> +		volume-down {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
> +			label = "Volume Down";
> +			linux,code = <KEY_VOLUMEDOWN>;
> +		};
> +	};
> +};
> +
> +&cci {
> +	/* CCI is disabled in hardware */
> +	status = "disabled";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&buck2_reg>;
> +};
> +
> +&cpu4 {
> +	cpu-supply = <&buck6_reg>;
> +};
> +
> +&gpu {
> +	status = "okay";
> +	mali-supply = <&buck4_reg>;
> +};
> +
> +&hsi2c_7 {
> +	status = "okay";
> +
> +	s2mps11: pmic at 66 {
> +		compatible = "samsung,s2mps11-pmic";
> +		reg = <0x66>;
> +
> +		interrupt-parent = <&gpx3>;
> +		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&s2mps11_irq>;
> +
> +		s2mps11_osc: clocks {
> +			compatible = "samsung,s2mps11-clk";
> +			#clock-cells = <1>;
> +			clock-output-names = "s2mps11_ap", "s2mps11_cp",
> +					     "s2mps11_bt";
> +		};
> +
> +		buck1_reg: BUCK1 {

All regulators should be under node "regulators". It should not work
properly without it, e.g. check
/sys/kernel/debug/regulator/regulator_summary if values match ones you
define.

> +			regulator-name = "VDD_MIF_1V1";
> +			regulator-min-microvolt = <700000>;
> +			regulator-max-microvolt = <1300000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +				regulator-suspend-microvolt = <1100000>;

Property is deprecated and I am not sure what is it's purpose since, the
regulator is off in suspend.

> +			};
> +		};
> +
> +		buck2_reg: BUCK2 {
> +			regulator-name = "VDD_ARM_1V0";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <1500000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			regulator-ramp-delay = <12500>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		buck3_reg: BUCK3 {
> +			regulator-name = "VDD_INT_1V0";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <1400000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +				regulator-suspend-microvolt = <1100000>;

Same.

> +			};
> +		};
> +
> +		buck4_reg: BUCK4 {
> +			regulator-name = "VDD_G3D_1V0";
> +			regulator-min-microvolt = <700000>;
> +			regulator-max-microvolt = <1400000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +			regulator-ramp-delay = <12500>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		buck5_reg: BUCK5 {
> +			regulator-name = "VDD_MEM_1V2";
> +			regulator-min-microvolt = <1200000>;
> +			regulator-max-microvolt = <1200000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		buck6_reg: BUCK6 {
> +			regulator-name = "VDD_KFC_1V0";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <1500000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		buck7_reg: BUCK7 {
> +			regulator-name = "VIN_LLDO_1V4";
> +			regulator-min-microvolt = <1200000>;
> +			regulator-max-microvolt = <1500000>;
> +			regulator-always-on;
> +		};
> +
> +		buck8_reg: BUCK8 {
> +			regulator-name = "VIN_MLDO_2V0";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <2100000>;
> +			regulator-always-on;
> +		};
> +
> +		buck9_reg: BUCK9 {
> +			regulator-name = "VIN_HLDO_3V5";
> +			regulator-min-microvolt = <3000000>;
> +			regulator-max-microvolt = <3500000>;
> +			regulator-always-on;
> +		};
> +
> +		buck10_reg: BUCK10 {
> +			regulator-name = "VDD_CAM_ISP_1V0";
> +			regulator-min-microvolt = <750000>;
> +			regulator-max-microvolt = <3550000>;
> +		};
> +
> +		ldo1_reg: LDO1 {
> +			regulator-name = "VDD_ALIVE_1.0V";
> +			regulator-min-microvolt = <1000000>;
> +			regulator-max-microvolt = <1000000>;
> +			regulator-always-on;
> +		};
> +
> +		ldo2_reg: LDO2 {
> +			regulator-name = "VDD_APIO_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo3_reg: LDO3 {
> +			regulator-name = "VDD_APIO_MMC2_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo4_reg: LDO4 {
> +			regulator-name = "VDD_ADC_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo5_reg: LDO5 {
> +			/* Unused */
> +			regulato-name = "VDD_LDO5";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +		};
> +
> +		ldo6_reg: LDO6 {
> +			regulator-name = "VDD_MIPI_1V0";
> +			regulator-min-microvolt = <1000000>;
> +			regulator-max-microvolt = <1000000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo7_reg: LDO7 {
> +			regulator-name = "VDD_MIPI_PLL_ABB1_18V";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo8_reg: LDO8 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +		};
> +
> +		ldo9_reg: LDO9 {
> +			regulator-name = "VDD_UOTG_3V0";
> +			regulator-min-microvolt = <3000000>;
> +			regulator-max-microvolt = <3000000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo10_reg: LDO10 {
> +			regulator-name = "VDDQ_PRE_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo11_reg: LDO11 {
> +			regulator-name = "VDD_HSIC_1V0";
> +			regulator-min-microvolt = <1000000>;
> +			regulator-max-microvolt = <1000000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo12_reg: LDO12 {
> +			regulator-name = "VDD_HSIC_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +		};
> +
> +		ldo13_reg: LDO13 {
> +			regulator-name = "VDD_APIO_MMC2_2V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <2800000>;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo14_reg: LDO14 {
> +			regulator-name = "VDD_MOTOR_3V0";
> +			regulator-min-microvolt = <3000000>;
> +			regulator-max-microvolt = <3000000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		/*
> +		 * LDO15 varies between devices and is
> +		 * specified in the device dts
> +		 */

Do it like ldo25 in arch/arm/boot/dts/exynos4412-midas.dtsi. Comment is
good.

> +
> +		ldo16_reg: LDO16 {
> +			regulator-name = "VDD_AP_2V8";
> +			regulator-min-microvolt = <2800000>;
> +			regulator-max-microvolt = <2800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};
> +		};
> +
> +		/*
> +		 * LDO17 varies between devices and is
> +		 * specified in the device dts
> +		 */
> +
> +		ldo18_reg: LDO18 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO18";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +		};
> +
> +
> +		ldo19_reg: LDO19 {
> +			regulator-name = "VDD_VTF_2V8";
> +			regulator-min-microvolt = <2800000>;
> +			regulator-max-microvolt = <2800000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo20_reg: LDO20 {
> +			regulator-name = "VDD_CAM1_CAM_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo21_reg: LDO21 {
> +			regulator-name = "VDD_CAM_IO_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo22_reg: LDO22 {
> +			regulator-name = "VDD_CAM0_S_CORE_1V1";
> +			regulator-min-microvolt = <1050000>;
> +			regulator-max-microvolt = <1200000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo23_reg: LDO23 {
> +			regulator-name = "VDD_MIFS_1V1";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <1100000>;
> +			regulator-always-on;
> +
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};
> +		};
> +
> +		ldo24_reg: LDO24 {
> +			regulator-name = "VDD_TSP_3V3";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo25_reg: LDO25 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO25";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <3950000>;
> +		};
> +
> +		ldo26_reg: LDO26 {
> +			regulator-name = "VDD_CAM0_AF_2V8";
> +			regulator-min-microvolt = <2800000>;
> +			regulator-max-microvolt = <2800000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo27_reg: LDO27 {
> +			regulator-name = "VDD_G3DS_1V0";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <1000000>;
> +			regulator-always-on;
> +
> +			regulator-state-mem {
> +				regulator-on-in-suspend;
> +			};
> +		};
> +
> +		/*
> +		 * LDO28 and LDO29 varies between devices and
> +		 * are specified in the device dts
> +		 */
> +
> +		ldo30_reg: LDO30 {
> +			regulator-name = "VDD_TOUCH_1V8";
> +			regulator-min-microvolt = <1900000>;
> +			regulator-max-microvolt = <1900000>;

Name is 1.8V, voltage is 1.9V. Double check this one :)

> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo31_reg: LDO31 {
> +			regulator-name = "VDD_GRIP_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +			regulator-always-on;
> +			regulator-boot-on;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo32_reg: LDO32 {
> +			regulator-name = "VDD_TSP_1V8";
> +			regulator-min-microvolt = <1900000>;
> +			regulator-max-microvolt = <1900000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo33_reg: LDO33 {
> +			regulator-name = "VDD_MHL_1V8";
> +			regulator-min-microvolt = <1800000>;
> +			regulator-max-microvolt = <1800000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo34_reg: LDO34 {
> +			regulator-name = "VDD_MHL_3V3";
> +			regulator-min-microvolt = <3300000>;
> +			regulator-max-microvolt = <3300000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo35_reg: LDO35 {
> +			regulator-name = "VDD_SIL_1V2";
> +			regulator-min-microvolt = <1200000>;
> +			regulator-max-microvolt = <1200000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +
> +		ldo36_reg: LDO36 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO36";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <3950000>;
> +		};
> +
> +		ldo37_reg: LDO37 {
> +			/* Unused */
> +			regulator-name = "VDD_LDO37";
> +			regulator-min-microvolt = <800000>;
> +			regulator-max-microvolt = <3950000>;
> +		};
> +
> +		ldo38_reg: LDO38 {
> +			regulator-name = "VDD_KEY_LED_3V3";
> +			regulator-min-microvolt = <2500000>;
> +			regulator-max-microvolt = <3300000>;
> +
> +			regulator-state-mem {
> +				regulator-off-in-suspend;
> +			};
> +		};
> +	};
> +};
> +
> +&mixer {
> +	status = "okay";
> +};
> +
> +/* Internal storage */
> +&mmc_0 {
> +	status = "okay";
> +	non-removable;
> +	card-detect-delay = <200>;
> +	samsung,dw-mshc-ciu-div = <3>;
> +	samsung,dw-mshc-sdr-timing = <0 4>;
> +	samsung,dw-mshc-ddr-timing = <0 2>;
> +	pinctrl-names = "default", "output";
> +	clk_pin = &sd0_clk;
> +	clk_val = <0x3>;

I think these two are not supported properties.

> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
> +	vmmc-supply = <&ldo3_reg>;
> +	vqmmc-supply = <&ldo13_reg>;
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	mmc-hs200-1_8v;
> +};
> +
> +/* External sdcard */
> +&mmc_2 {
> +	status = "okay";
> +	card-detect-delay = <200>;
> +	samsung,dw-mshc-ciu-div = <3>;
> +	samsung,dw-mshc-sdr-timing = <0 4>;
> +	samsung,dw-mshc-ddr-timing = <0 2>;
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	sd-uhs-sdr50;

You should define here also pins, something like Arndale Octa has.

> +};
> +
> +&pinctrl_0 {
> +	s2mps11_irq: s2mps11-irq-pins {
> +		samsung,pins = "gpx3-2";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> +		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> +	};
> +};
> +


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:35:10 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:35:10 +0100
Subject: [PATCH 1/3] dt-bindings: arm: samsung: document chagallwifi board
 binding
In-Reply-To: <20220113154019.74434-2-henrik@grimler.se>
References: <20220113154019.74434-1-henrik@grimler.se>
 <20220113154019.74434-2-henrik@grimler.se>
Message-ID: <9d3cb398-56fa-a07e-1932-baf6f75cf81f@canonical.com>

On 13/01/2022 16:40, Henrik Grimler wrote:
> Add binding for Samsung Galaxy Tab S 10.5", based on Exynos 5420 with
> codename chagallwifi. It was released in 2014 and has several siblings
> with similar hardware.
> 
> Signed-off-by: Henrik Grimler <henrik at grimler.se>
> ---
>  .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
> index 052cd94113d4..3f2ffb0d7b46 100644
> --- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
> +++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
> @@ -140,6 +140,7 @@ properties:
>          items:
>            - enum:
>                - insignal,arndale-octa           # Insignal Arndale Octa
> +              - samsung,chagallwifi             # Samsung SM-T800

"samsung,chagall-wifi"
(reason given in patch #3)

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:37:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:37:33 +0100
Subject: [PATCH v2 0/3] Add initial support for exynos5420-chagallwifi
In-Reply-To: <20220115162703.699347-1-henrik@grimler.se>
References: <20220115162703.699347-1-henrik@grimler.se>
Message-ID: <763b84a1-4cf0-505e-f678-3474058059e2@canonical.com>

On 15/01/2022 17:27, Henrik Grimler wrote:
> Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename chagallwifi
> and is one of several tablets released in 2013 - 2014 based on Exynos
> 5420.  This initial devicetree adds support for accessing device over
> USB or UART, and allows using a rootfs in either the internal eMMC or
> an external sdcard.  4 out of 8 CPUs are brought up when device boots,
> which is the same as on the somewhat similar device
> exynos5420-arndale-octa.
> 
> Patch 2 is necessary after a secure-firmware node is added, otherwise
> device hangs during the CPU1BOOT secure monitor call. Without the
> secure-firmware node we are not able to bring up any secondary CPUs.
> 
> Changes since v1
> ================
> 
> Fix mmc_0 and usbdrd in patch 3: 
> * Remove extra, non supported, options from mmc_0 node 
> * Do not set usbdrd supplies. Usb networking does not work with them 
>   specified, but it works fine with dummy regulators

Re-try with supplies after fixing the regulators (my comment to v1).
These should work, unless your regulators are wrongly configured or you
used wrong supplies.

I just sent a review for v1, so please go through it.

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:42:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:42:45 +0100
Subject: [PATCH v2 03/11] arm64: defconfig: enable taskstats configuration
In-Reply-To: <20220114141507.395271-4-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-4-marcel@ziswiler.com>
Message-ID: <be69a1e6-f044-2382-fb30-7b281d16ed9a@canonical.com>

On 14/01/2022 15:14, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Enable CONFIG_TASKSTATS which is required for CONFIG_TASK_XACCT (and
> subsequently CONFIG_TASK_IO_ACCOUNTING). Previously, taskstats got
> pulled in by KVM but that got changed in commit 63b3f96e1a98
> ("kvm: Select SCHED_INFO instead of TASK_DELAY_ACCT").
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - New patch following full defconfig analysis as requested by Krzysztof.
> 

Nice!

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:45:16 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:45:16 +0100
Subject: [PATCH v2 04/11] arm64: defconfig: enable pcieaer configuration
In-Reply-To: <20220114141507.395271-5-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-5-marcel@ziswiler.com>
Message-ID: <a03f3240-0e68-1451-0d97-109c024f784a@canonical.com>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Enable CONFIG_PCIEAER which is required for CONFIG_ACPI_APEI_PCIEAER.
> Commit 8c8ff55b4da7 ("PCI/AER: Don't select CONFIG_PCIEAER by default")
> changed it to no longer being enabled by default.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - New patch following full defconfig analysis as requested by Krzysztof.
> 

Good finding! The question is whether we actually need PCIe AER...

Best regards,
Krzysztof


From krzk at kernel.org  Sat Jan 15 08:47:07 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:47:07 +0100
Subject: [PATCH v2 06/11] arm64: defconfig: enable bpf/cgroup firewalling
In-Reply-To: <20220114141507.395271-7-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-7-marcel@ziswiler.com>
Message-ID: <a23661a4-0f49-858d-811c-0b9bfbeff4ad@kernel.org>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> This avoids the following systemd warning:
> 
> [    2.618538] systemd[1]: system-getty.slice: unit configures an IP
>  firewall, but the local system does not support BPF/cgroup firewalling.
> [    2.630916] systemd[1]: (This warning is only shown for the first
>  unit using IP firewalling.)
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Acked-by: Song Liu <songliubraving at fb.com>
> 
> ---
> 
> Changes in v2:
> - Add Song's acked-by tag.
> 
>  arch/arm64/configs/defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 

Make sense.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzk at kernel.org  Sat Jan 15 08:47:30 2022
From: krzk at kernel.org (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:47:30 +0100
Subject: [PATCH v2 08/11] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220114141507.395271-9-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-9-marcel@ziswiler.com>
Message-ID: <90f2e35d-db4c-fb43-f2ba-a634649889ed@kernel.org>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Build Realtek Gigabit Ethernet driver as a module.
> 
> Network cards based on chipsets this driver supports are ubiquitous both
> in regular PCIe as well as mini-PCIe and nowadays even various M.2
> formats. It is therefore a suitable card to be used for any kind of PCIe
> and/or Gigabit Ethernet testing. As it is not designed in, just enabling
> it as a module seems most suitable.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - Explain why enabling it may be a good idea as requested by Krzysztof.
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:47:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:47:35 +0100
Subject: [PATCH v2 08/11] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220114141507.395271-9-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-9-marcel@ziswiler.com>
Message-ID: <95d9a962-3b31-eb19-8297-11e33a3d78cc@canonical.com>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Build Realtek Gigabit Ethernet driver as a module.
> 
> Network cards based on chipsets this driver supports are ubiquitous both
> in regular PCIe as well as mini-PCIe and nowadays even various M.2
> formats. It is therefore a suitable card to be used for any kind of PCIe
> and/or Gigabit Ethernet testing. As it is not designed in, just enabling
> it as a module seems most suitable.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - Explain why enabling it may be a good idea as requested by Krzysztof.
> 
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:48:16 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:48:16 +0100
Subject: [PATCH v2 09/11] arm64: defconfig: enable verdin-imx8mm relevant
 drivers as modules
In-Reply-To: <20220114141507.395271-10-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-10-marcel@ziswiler.com>
Message-ID: <030de58b-e2c8-b0f2-9756-df21eccf52ff@canonical.com>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Enable various drivers which support peripherals as found on the
> Verdin iMX8M Mini et al. computer/system on modules:
> 
> - CONFIG_CAN_MCP251XFD
> At least one Microchip MCP2518FDT SPI CAN controller which this driver
> also supports may be found on the Verdin iMX8M Mini computer/system on
> module.
> 
> - CONFIG_BT_HCIUART_MRVL, CONFIG_BT_MRVL, CONFIG_BT_MRVL_SDIO and
>   CONFIG_MWIFIEX_SDIO
> The AzureWave AW-CM276NF which these Bluetooth and Wi-Fi drivers also
> support may be found on the Verdin iMX8M Mini (as well as the Apalis
> iMX8, Colibri iMX8X and Verdin iMX8M Plus for that matter) computer/
> system on module.
> 
> - CONFIG_SENSORS_LM75
> The TI TMP75C temperature sensor which this driver also supports may be
> found on the Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for
> that matter) computer/system on module.
> 
> - CONFIG_SND_SOC_NAU8822
> The Nuvoton Technology Corporation (NTC) NAU88C22YG which this driver
> also supports may be found on the Verdin Development Board a carrier
> board for the Verdin family of computer/system on module which the
> Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
> may be mated in.
> 
> - CONFIG_TI_ADS1015
> The TLA2024 ADC which this driver also supports may be found on the
> Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
> computer/system on module.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - Explain why enabling these may make sense and squash them relevant
>   changes as requested by Krzysztof.
> 

Thanks, this is a nice explanation.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 08:50:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 17:50:30 +0100
Subject: [PATCH v2 11/11] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <20220114141507.395271-12-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-12-marcel@ziswiler.com>
Message-ID: <da5c9727-45c6-f2be-5a31-2214d0d1e9c0@canonical.com>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> This patch adds the device tree to support Toradex Verdin iMX8M Mini a
> computer on module which can be used on different carrier boards.
> 
> The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
> Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
> 1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
> RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
> Wi-Fi module.
> 
> Anything that is not self-contained on the module is disabled by
> default.
> 
> The device tree for the Dahlia includes the module's device tree and
> enables the supported peripherals of the carrier board.
> 
> The device tree for the Verdin Development Board includes the module's
> device tree as well as the Dahlia one as it is a superset and supports
> almost all peripherals available.
> 
> So far there is no display functionality supported at all but basic
> console UART, USB host, eMMC and Ethernet and PCIe functionality work
> fine.
> 
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> ---
> 
> Changes in v2:
> - Remove bootargs which will be filled in by the bootloader as requested
>   by Krzysztof.
> - Remove the previously #ifdefed-out spi-nor as requested by Krzysztof.
> - Fix capitalisation in cover-letter.
> 

Thanks for the changes.

Looks, good but I did not perform review thorough enough to give a
Reviewed-by tag, so let it be just:

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Sat Jan 15 09:02:18 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 15 Jan 2022 18:02:18 +0100
Subject: [PATCH v2 05/11] arm64: defconfig: rebuild default configuration
In-Reply-To: <20220114141507.395271-6-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-6-marcel@ziswiler.com>
Message-ID: <060a9f66-fc00-2247-46f2-1c700d0e9bf3@canonical.com>

On 14/01/2022 15:15, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Run "make defconfig; make savedefconfig" to rebuild defconfig.
> 
> This re-ordered the following configuration options:
> 
> CONFIG_BPF_JIT=y
> CONFIG_ARM_SCMI_PROTOCOL=y
> CONFIG_ARM_SCPI_PROTOCOL=y
> CONFIG_RASPBERRYPI_FIRMWARE=y
> CONFIG_INTEL_STRATIX10_SERVICE=y
> CONFIG_INTEL_STRATIX10_RSU=m
> CONFIG_EFI_CAPSULE_LOADER=y
> CONFIG_IMX_SCU=y
> CONFIG_IMX_SCU_PD=y
> CONFIG_CAN_FLEXCAN=m
> CONFIG_PCIE_LAYERSCAPE_GEN4=y
> CONFIG_MTK_DEVAPC=m
> CONFIG_SPI_CADENCE_QUADSPI=y
> CONFIG_MDIO_BUS_MUX_MMIOREG=y
> CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
> CONFIG_MESON_GXL_PHY=m
> CONFIG_QCOM_CPR=y
> CONFIG_ROCKCHIP_IODOMAIN=y
> CONFIG_SENSORS_ARM_SCMI=y
> CONFIG_QORIQ_THERMAL=m
> CONFIG_SUN8I_THERMAL=y
> CONFIG_TEGRA_BPMP_THERMAL=m
> CONFIG_ARM_SMC_WATCHDOG=y
> CONFIG_VIDEO_QCOM_CAMSS=m
> CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
> CONFIG_DRM_NWL_MIPI_DSI=m
> CONFIG_DRM_LONTIUM_LT9611UXC=m
> CONFIG_SND_SOC_IMX_AUDMIX=m
> CONFIG_TYPEC_HD3SS3220=m
> CONFIG_COMMON_CLK_SCMI=y
> CONFIG_IPQ_GCC_8074=y
> CONFIG_SM_DISPCC_8250=y
> CONFIG_QCOM_WCNSS_CTRL=m
> CONFIG_ARCH_R8A774A1=y
> CONFIG_ARCH_R8A774B1=y
> CONFIG_ARCH_R8A774C0=y
> CONFIG_ARCH_R8A774E1=y
> CONFIG_ARCH_R8A77995=y
> CONFIG_ARCH_R8A77990=y
> CONFIG_ARCH_R8A77965=y
> CONFIG_ARCH_R8A77970=y
> CONFIG_HISI_PMU=y
> CONFIG_QCOM_QFPROM=y
> CONFIG_MUX_MMIO=y

Thanks for the changes.
The best would be to have a separate patch only for re-ordering.

> 
> And dropped the following configuration options which are nowaday's
> already enabled (resp. disabled) by default:
> 
> CONFIG_MEMCG_SWAP=y
> CONFIG_SECCOMP=y

Is it? I tried now on next-20220114 and it is still user-selectable and
not chosen by anything.

> CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
> CONFIG_QCOM_SCM=y
> # CONFIG_BT_HS is not set
> CONFIG_FSL_MC_BUS=y
> CONFIG_MEDIA_CONTROLLER=y
> CONFIG_VIDEO_V4L2_SUBDEV_API=y
> CONFIG_SND_SOC_FSL_SAI=m
> CONFIG_USB_CONN_GPIO=m
> CONFIG_USB_XHCI_PCI=m
> CONFIG_MFD_CROS_EC_DEV=y
> CONFIG_COMMON_CLK_ZYNQMP=y
> CONFIG_SDM_GCC_845=y
> CONFIG_SM_GCC_8150=y
> CONFIG_SM_GCC_8250=y
> CONFIG_SLIMBUS=m
> CONFIG_INTERCONNECT=y
> CONFIG_CONFIGFS_FS=y

All three above are still user-selectable, so please leave them. It is
redundant, but there is no guarantee that something selecting a
user-visible symbol will stop selecting it. IOW, user-visible symbols
should be still chosen by defconfigs if they really want them.

See for example commit a2315d3aea59 ("ARM: exynos_defconfig: Restore
debugfs support") for rationale why we need to keep them.


Best regards,
Krzysztof


From trix at redhat.com  Sat Jan 15 09:49:18 2022
From: trix at redhat.com (trix at redhat.com)
Date: Sat, 15 Jan 2022 09:49:18 -0800
Subject: [PATCH v2] net: ethernet: mtk_eth_soc: fix error checking in
 mtk_mac_config()
Message-ID: <20220115174918.297002-1-trix@redhat.com>

From: Tom Rix <trix at redhat.com>

Clang static analysis reports this problem
mtk_eth_soc.c:394:7: warning: Branch condition evaluates
  to a garbage value
                if (err)
                    ^~~

err is not initialized and only conditionally set.
So intitialize err.

Fixes: 7e538372694b ("net: ethernet: mediatek: Re-add support SGMII")
Signed-off-by: Tom Rix <trix at redhat.com>
---
v2: change to initializing

drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index b67b4323cff08..f02d07ec5ccbf 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -267,7 +267,7 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 					   phylink_config);
 	struct mtk_eth *eth = mac->hw;
 	u32 mcr_cur, mcr_new, sid, i;
-	int val, ge_mode, err;
+	int val, ge_mode, err = 0;
 
 	/* MT76x8 has no hardware settings between for the MAC */
 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-- 
2.26.3



From henrik at grimler.se  Sat Jan 15 12:28:16 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sat, 15 Jan 2022 21:28:16 +0100
Subject: [PATCH 3/3] ARM: dts: Add support for Samsung Chagallwifi
In-Reply-To: <99e33cde-1304-a098-cd7b-8da8408d8052@canonical.com>
References: <20220113154019.74434-1-henrik@grimler.se>
 <20220113154019.74434-4-henrik@grimler.se>
 <99e33cde-1304-a098-cd7b-8da8408d8052@canonical.com>
Message-ID: <YeMuO6a1f0R48Fgl@L14.lan>

Hi Krzysztof,

Thanks for the feedback!

On Sat, Jan 15, 2022 at 05:34:28PM +0100, Krzysztof Kozlowski wrote:
> On 13/01/2022 16:40, Henrik Grimler wrote:
> > Chagallwifi, with product name Samsung Galaxy Tab S 10.5", is based on
> > Exynos 5420. This device is one of several tablet models released in
> > 2013 - 2014 based on Exynos 5420.
> > 
> > The device tree added here contains support for:
> > 
> > - UART
> > - eMMC
> > - SD card
> > - USB
> > 
> 
> Thanks for the patches. It is a really nice work, good job!
> 
> Some comments below.
> 
> > CCI has been disabled in the hardware, enabling it would require
> > (de-)soldering a resistor on the board.  Trying to boot with it
> > enabled in kernel makes the device hang when CCI is probed.
> > Exynos5420-arndale-octa also has had CCI disabled due to issues [1].
> > 
> > To successfully boot the mainline kernel with the stock bootloader
> > (SBOOT), an additional hack is needed [2]. The same hack is also
> > needed to boot exynos4412-i9300 with stock bootloader, and probably
> > other Samsung devices of similar age.
> > 
> > [1] https://marc.info/?l=linux-arm-kernel&m=141718639200624
> 
> Commits should use 'commit SHA_12char ("subject")' format instead of
> links to mailing lists.

Will fix in v3.

[ ... ]

> > diff --git a/arch/arm/boot/dts/exynos5420-chagallwifi.dts b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
> > new file mode 100644
> > index 000000000000..51eb2bbe6bf6
> > --- /dev/null
> > +++ b/arch/arm/boot/dts/exynos5420-chagallwifi.dts
> > @@ -0,0 +1,57 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Samsung's Exynos5420 Chagallwifi board device tree source
> > + *
> > + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
> > + *		http://www.samsung.com
> > + * Copyright (c) 2022 Henrik Grimler
> > + */
> > +
> > +/dts-v1/;
> > +#include "exynos5420-galaxy-tab-common.dtsi"
> 
> Do you plan to have more Galaxy Tab versions?

Yes. One more ("klimt-wifi") as soon as issues here have been ironed
out, and possibly LTE-version(s) later if I actually bring it up
to a point where the hardware differences matter for the kernel.

I am also hoping that someone else with access to other tablet
variants wants to work on addng support for additional models, through
the PostmarketOS project.

> > +
> > +/ {
> > +	model = "Samsung Chagallwifi based on exynos5420";
> 
> "Chagall WiFi"?

Will change filename and descriptions to something like that.

> > +	compatible = "samsung,chagallwifi", "samsung,exynos5420", \
> > +		     "samsung,exynos5";
> > +};
> > +
> > +&s2mps11 {
> > +	regulators {
> > +		ldo15_reg: LDO15 {
> 
> Please define these regulator nodes in DTSI (only name needed and
> comment like you have there) and override them by label (&ldo15_reg { ...).

Will do.

[ ... ]

> > +/dts-v1/;
> > +#include "exynos5420.dtsi"
> > +#include "exynos5420-cpus.dtsi"
> > +#include <dt-bindings/input/input.h>
> > +#include <dt-bindings/gpio/gpio.h>
> > +#include <dt-bindings/clock/samsung,s2mps11.h>
> > +
> > +/ {
> > +	compatible = "samsung,exynos5420", "samsung,exynos5";

> Skip the compatible. It duplicates exynos5420.dtsi and does not bring
> any more information here.

Will do.

[ ... ]

> > +	fixed-rate-clocks {
> > +		oscclk {
> > +			compatible = "samsung,exynos5420-oscclk";
> > +			clock-frequency = <24000000>;
> > +		};
> > +
> > +		xxti {
> > +			compatible = "samsung,clock-xxti";
> > +			clock-frequency = <24000000>;
> > +		};
> > +
> > +		xusbxti {
> > +			compatible = "samsung,clock-xusbxti";
> > +			clock-frequency = <24000000>;
> > +		};
> 
> Just keep one clock - oscclk. We treat it as alias of xxti, even though
> it might not be exactly alias. I am not sure about real differences, but
> anyway the driver does not care about xxti and xusbxti. xusbxti appears
> in Exynos5420 only partially, e.g. not in all places like ballmap. Other
> boards have only oscclk, so let's do the same.

Will do.

> > +	};
> > +
> > +	gpio-keys {
> > +		compatible = "gpio-keys";
> > +		pinctrl-names = "default";
> > +
> > +		power {
> 
> key-power and so on.

Will do.

> > +			debounce-interval = <10>;
> > +			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
> > +			label = "Power";
> > +			linux,code = <KEY_POWER>;
> > +			wakeup-source;
> > +		};
> > +
> > +		home {
> > +			debounce-interval = <10>;
> > +			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
> > +			label = "Home";
> > +			linux,code = <KEY_HOME>;
> > +			wakeup-source;
> > +		};
> > +
> > +		volume-up {
> > +			debounce-interval = <10>;
> > +			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
> > +			label = "Volume Up";
> > +			linux,code = <KEY_VOLUMEUP>;
> > +		};
> > +
> > +		volume-down {
> > +			debounce-interval = <10>;
> > +			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
> > +			label = "Volume Down";
> > +			linux,code = <KEY_VOLUMEDOWN>;
> > +		};
> > +	};
> > +};

[ ... ]

> > +&hsi2c_7 {
> > +	status = "okay";
> > +
> > +	s2mps11: pmic at 66 {
> > +		compatible = "samsung,s2mps11-pmic";
> > +		reg = <0x66>;
> > +
> > +		interrupt-parent = <&gpx3>;
> > +		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
> > +		pinctrl-names = "default";
> > +		pinctrl-0 = <&s2mps11_irq>;
> > +
> > +		s2mps11_osc: clocks {
> > +			compatible = "samsung,s2mps11-clk";
> > +			#clock-cells = <1>;
> > +			clock-output-names = "s2mps11_ap", "s2mps11_cp",
> > +					     "s2mps11_bt";
> > +		};
> > +
> > +		buck1_reg: BUCK1 {
> 
> All regulators should be under node "regulators". It should not work
> properly without it, e.g. check
> /sys/kernel/debug/regulator/regulator_summary if values match ones you
> define.

Error on my part when re-arranging, will fix, and investigate issue
with usbdrd supplies.

> > +			regulator-name = "VDD_MIF_1V1";
> > +			regulator-min-microvolt = <700000>;
> > +			regulator-max-microvolt = <1300000>;
> > +			regulator-always-on;
> > +			regulator-boot-on;
> > +
> > +			regulator-state-mem {
> > +				regulator-off-in-suspend;
> > +				regulator-suspend-microvolt = <1100000>;
> 
> Property is deprecated and I am not sure what is it's purpose since, the
> regulator is off in suspend.

Will remove it in v3.

> > +			};
> > +		};
> > +
> > +		buck2_reg: BUCK2 {
> > +			regulator-name = "VDD_ARM_1V0";
> > +			regulator-min-microvolt = <800000>;
> > +			regulator-max-microvolt = <1500000>;
> > +			regulator-always-on;
> > +			regulator-boot-on;
> > +			regulator-ramp-delay = <12500>;
> > +
> > +			regulator-state-mem {
> > +				regulator-off-in-suspend;
> > +			};
> > +		};
> > +
> > +		buck3_reg: BUCK3 {
> > +			regulator-name = "VDD_INT_1V0";
> > +			regulator-min-microvolt = <800000>;
> > +			regulator-max-microvolt = <1400000>;
> > +			regulator-always-on;
> > +			regulator-boot-on;
> > +
> > +			regulator-state-mem {
> > +				regulator-off-in-suspend;
> > +				regulator-suspend-microvolt = <1100000>;
> 
> Same.

[ ... ]

> > +		/*
> > +		 * LDO15 varies between devices and is
> > +		 * specified in the device dts
> > +		 */
> 
> Do it like ldo25 in arch/arm/boot/dts/exynos4412-midas.dtsi. Comment is
> good.

Will do.

[ ... ]

> > +
> > +		ldo30_reg: LDO30 {
> > +			regulator-name = "VDD_TOUCH_1V8";
> > +			regulator-min-microvolt = <1900000>;
> > +			regulator-max-microvolt = <1900000>;
> 
> Name is 1.8V, voltage is 1.9V. Double check this one :)

It does indeed look a bit strange. In Samsung's vendor kernel, two
tablet variants uses 1900000, and two 1800000.  The two I have access
to both uses 1900000.

> > +
> > +			regulator-state-mem {
> > +				regulator-off-in-suspend;
> > +			};
> > +		};
> > +

[ ... ]

> > +/* Internal storage */
> > +&mmc_0 {
> > +	status = "okay";
> > +	non-removable;
> > +	card-detect-delay = <200>;
> > +	samsung,dw-mshc-ciu-div = <3>;
> > +	samsung,dw-mshc-sdr-timing = <0 4>;
> > +	samsung,dw-mshc-ddr-timing = <0 2>;
> > +	pinctrl-names = "default", "output";
> > +	clk_pin = &sd0_clk;
> > +	clk_val = <0x3>;
> 
> I think these two are not supported properties.

Indeed, fixed in next version.

> > +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
> > +	vmmc-supply = <&ldo3_reg>;
> > +	vqmmc-supply = <&ldo13_reg>;
> > +	bus-width = <8>;
> > +	cap-mmc-highspeed;
> > +	mmc-hs200-1_8v;
> > +};
> > +
> > +/* External sdcard */
> > +&mmc_2 {
> > +	status = "okay";
> > +	card-detect-delay = <200>;
> > +	samsung,dw-mshc-ciu-div = <3>;
> > +	samsung,dw-mshc-sdr-timing = <0 4>;
> > +	samsung,dw-mshc-ddr-timing = <0 2>;
> > +	bus-width = <4>;
> > +	cap-sd-highspeed;
> > +	sd-uhs-sdr50;
> 
> You should define here also pins, something like Arndale Octa has.

Will do.

> > +};
> > +
> > +&pinctrl_0 {
> > +	s2mps11_irq: s2mps11-irq-pins {
> > +		samsung,pins = "gpx3-2";
> > +		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
> > +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> > +		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
> > +	};
> > +};
> > +
> 
> 
> Best regards,
> Krzysztof

Best regards,
Henrik Grimler


From michael at walle.cc  Sat Jan 15 13:04:32 2022
From: michael at walle.cc (Michael Walle)
Date: Sat, 15 Jan 2022 22:04:32 +0100
Subject: [PATCH] arm64: dts: ls1028a: sl28: re-enable ftm_alarm0
Message-ID: <20220115210432.449968-1-michael@walle.cc>

Commit dd3d936a1b17 ("arm64: dts: ls1028a: add ftm_alarm1 node to be
used as wakeup source") disables ftm_alarm0 in the SoC dtsi but doesn't
enable it on the board which is still using it. Re-enable it on the sl28
board.

Fixes: dd3d936a1b17 ("arm64: dts: ls1028a: add ftm_alarm1 node to be used as wakeup source")
Reported-by: Guillaume Tucker <guillaume.tucker at collabora.com>
Reported-by: "kernelci.org bot" <bot at kernelci.org>
Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
index dd4773d1cf03..5dc85d088ec2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts
@@ -190,6 +190,10 @@ base_mac_address: base-mac-address at 17 {
 	};
 };
 
+&ftm_alarm0 {
+	status = "okay";
+};
+
 &gpio1 {
 	gpio-line-names =
 		"", "", "", "", "", "", "", "",
-- 
2.30.2



From michael at walle.cc  Sat Jan 15 13:09:06 2022
From: michael at walle.cc (Michael Walle)
Date: Sat, 15 Jan 2022 22:09:06 +0100
Subject: [PATCH 1/2] Revert "arm64: dts: ls1028a-rdb: enable pwm0"
Message-ID: <20220115210907.451189-1-michael@walle.cc>

We need to revert commit 71799672ea24d ("arm64: dts: ls1028a: add
flextimer based pwm nodes"). To not break the LS1028A-RDB board dts, we
also need to revert this commit.

This reverts commit b2e2d3e02fb60f4d45843ceebef0465c59c8d392.

Fixes: b2e2d3e02fb6 ("arm64: dts: ls1028a-rdb: enable pwm0")
Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
index 68c31cb8eead..6d26b010187c 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
@@ -286,10 +286,6 @@ &optee {
 	status = "okay";
 };
 
-&pwm0 {
-	status = "okay";
-};
-
 &sai4 {
 	status = "okay";
 };
-- 
2.30.2



From michael at walle.cc  Sat Jan 15 13:09:07 2022
From: michael at walle.cc (Michael Walle)
Date: Sat, 15 Jan 2022 22:09:07 +0100
Subject: [PATCH 2/2] Revert "arm64: dts: ls1028a: add flextimer based pwm
 nodes"
In-Reply-To: <20220115210907.451189-1-michael@walle.cc>
References: <20220115210907.451189-1-michael@walle.cc>
Message-ID: <20220115210907.451189-2-michael@walle.cc>

The changes to the device tree look very wrong. There are now two
devices with the same base address: pwm0 and ftm_alarm0. Both are using
the Flex Timer Module. It seems like this should either be one driver or
and MFD driver. Either way, there should only be one node in the device
tree. Revert the offending changes to avoid getting a broken device tree
in circulation.

This reverts commit 71799672ea24d2935322d655d2407c1ccd7db9ff.

Fixes: 71799672ea24 ("arm64: dts: ls1028a: add flextimer based pwm nodes")
Signed-off-by: Michael Walle <michael at walle.cc>
---

Btw, the nodes are also not sorted by the address. Otherwise it should have
been spotted easily.

 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 95 -------------------
 1 file changed, 95 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 1ef26cbc79cb..d3cc8cbaf768 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -66,13 +66,6 @@ CPU_PW20: cpu-pw20 {
 		};
 	};
 
-	rtc_clk: rtc-clk {
-		compatible = "fixed-clock";
-		#clock-cells = <0>;
-		clock-frequency = <32768>;
-		clock-output-names = "rtc_clk";
-	};
-
 	sysclk: sysclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -1245,94 +1238,6 @@ ierb at 1f0800000 {
 			reg = <0x01 0xf0800000 0x0 0x10000>;
 		};
 
-		pwm0: pwm at 2800000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2800000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm1: pwm at 2810000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2810000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm2: pwm at 2820000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2820000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm3: pwm at 2830000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2830000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm4: pwm at 2840000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2840000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm5: pwm at 2850000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2850000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm6: pwm at 2860000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2860000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
-		pwm7: pwm at 2870000 {
-			compatible = "fsl,vf610-ftm-pwm";
-			#pwm-cells = <3>;
-			reg = <0x0 0x2870000 0x0 0x10000>;
-			clock-names = "ftm_sys", "ftm_ext",
-				      "ftm_fix", "ftm_cnt_clk_en";
-			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
-				 <&rtc_clk>, <&clockgen 4 1>;
-			status = "disabled";
-		};
-
 		rcpm: power-controller at 1e34040 {
 			compatible = "fsl,ls1028a-rcpm", "fsl,qoriq-rcpm-2.1+";
 			reg = <0x0 0x1e34040 0x0 0x1c>;
-- 
2.30.2



From patchwork-bot+netdevbpf at kernel.org  Sat Jan 15 14:40:09 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 15 Jan 2022 22:40:09 +0000
Subject: [PATCH v2] net: ethernet: mtk_eth_soc: fix error checking in
 mtk_mac_config()
In-Reply-To: <20220115174918.297002-1-trix@redhat.com>
References: <20220115174918.297002-1-trix@redhat.com>
Message-ID: <164228640961.24744.3226248987693729352.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Sat, 15 Jan 2022 09:49:18 -0800 you wrote:
> From: Tom Rix <trix at redhat.com>
> 
> Clang static analysis reports this problem
> mtk_eth_soc.c:394:7: warning: Branch condition evaluates
>   to a garbage value
>                 if (err)
>                     ^~~
> 
> [...]

Here is the summary with links:
  - [v2] net: ethernet: mtk_eth_soc: fix error checking in mtk_mac_config()
    https://git.kernel.org/netdev/net/c/214b3369ab9b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Sat Jan 15 14:40:09 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Sat, 15 Jan 2022 22:40:09 +0000
Subject: [PATCH] net: ethernet: sun4i-emac: Fix an error handling path in
 emac_probe()
In-Reply-To: <aa2344da574f58aeba869a9219b3549dbd65d8e4.1642250684.git.christophe.jaillet@wanadoo.fr>
References: <aa2344da574f58aeba869a9219b3549dbd65d8e4.1642250684.git.christophe.jaillet@wanadoo.fr>
Message-ID: <164228640957.24744.13688338637735089336.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Sat, 15 Jan 2022 13:45:03 +0100 you wrote:
> A dma_request_chan() call is hidden in emac_configure_dma().
> It must be released in the probe if an error occurs, as already done in
> the remove function.
> 
> Add the corresponding dma_release_channel() call.
> 
> Fixes: 47869e82c8b8 ("sun4i-emac.c: add dma support")
> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> 
> [...]

Here is the summary with links:
  - net: ethernet: sun4i-emac: Fix an error handling path in emac_probe()
    https://git.kernel.org/netdev/net/c/9a9acdccdfa4

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From linus.walleij at linaro.org  Sat Jan 15 15:59:26 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 00:59:26 +0100
Subject: [PATCH 1/3] pinctrl: mediatek: pinctrl-moore: Simplify with
 dev_err_probe()
In-Reply-To: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
References: <20220103101855.17350-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CACRpkdZhxEc0iFYkUJmPVc1ydDVtRd6-gqwcELyLb1ZRLe5STA@mail.gmail.com>

On Mon, Jan 3, 2022 at 11:19 AM AngeloGioacchino Del Regno
<angelogioacchino.delregno at collabora.com> wrote:

> Use the dev_err_probe() helper to simplify error handling during probe.
>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

This patch set seems in nice shape, sadly we missed the v5.17 merge
window but please resend it as v2 once v5.17-rc1 is out with Chen-Yu's
review tags and minor fixes folded in.

Thanks!
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:00:53 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:00:53 +0100
Subject: [PATCH v2] pinctrl: at91-pio4: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CACRpkdaPVQ4jph5mWca9-ubAZjV6tpSpUfjJrsK+0+Si6yqtwQ@mail.gmail.com>

On Tue, Jan 4, 2022 at 3:10 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:

> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
>
> While at it, replace the dev_err() with dev_dbg() as platform_get_irq()
> prints an error message upon error.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>
> ---
> v1->v2
> * Switched using platform_get_irq()
> * Replaced dev_err() with dev_dbg()

Looks good to me but I'd like some ACK from a Microchip person
before I merge this (for v5.18).

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:34:29 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:34:29 +0100
Subject: [PATCH v5 2/4] dt-bindings: input: Add Cypress TT2100 touchscreen
 controller
In-Reply-To: <20220109115331.388633-3-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
 <20220109115331.388633-3-alistair@alistair23.me>
Message-ID: <CACRpkdYQEBiSsnwrV1jMks3UYcbnwZLtN8dnUPdsKB3rLcwDjg@mail.gmail.com>

On Sun, Jan 9, 2022 at 12:53 PM Alistair Francis <alistair at alistair23.me> wrote:

> From: Myl?ne Josserand <mylene.josserand at free-electrons.com>
>
> Add the Cypress TrueTouch Generation 5 touchscreen device tree bindings
> documentation. It can use I2C or SPI bus.
> This touchscreen can handle some defined zone that are designed and
> sent as button. To be able to customize the keycode sent, the
> "linux,code" property in a "button" sub-node can be used.
>
> Signed-off-by: Myl?ne Josserand <mylene.josserand at free-electrons.com>
> Signed-off-by: Alistair Francis <alistair at alistair23.me>

Looks good to me!
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:40:06 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:40:06 +0100
Subject: [PATCH] drivers/pinctrl: remove redundant ret variable
In-Reply-To: <20220110012730.643927-1-chi.minghao@zte.com.cn>
References: <20220110012730.643927-1-chi.minghao@zte.com.cn>
Message-ID: <CACRpkdbquo5mypt25FDKt_tbm3CFh1j1FwvzkvmD8bB1t=O58Q@mail.gmail.com>

On Mon, Jan 10, 2022 at 2:27 AM <cgel.zte at gmail.com> wrote:

> From: Minghao Chi <chi.minghao at zte.com.cn>
>
> Return value from pxa2xx_pinctrl_init() directly instead
> of taking this in another redundant variable.
>
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: Minghao Chi <chi.minghao at zte.com.cn>
> Signed-off-by: CGEL ZTE <cgel.zte at gmail.com>

Patch applied.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:49:10 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:49:10 +0100
Subject: [PATCH 0/7] pinctrl: mediatek: Fixes and minor improvements
In-Reply-To: <20220111112244.1483783-1-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
Message-ID: <CACRpkdZCtEwZiVwoW+QNL4nTf-10fBDRfGkwVJavf1n_w-8q_Q@mail.gmail.com>

On Tue, Jan 11, 2022 at 12:22 PM Chen-Yu Tsai <wenst at chromium.org> wrote:

> Here are some fixes and minor improvements to generic pinconf and the
> Mediatek Paris pinctrl driver.

Looks good to me, can you rebase this on v5.17-rc1 once it is out
and I will queue it!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:51:29 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:51:29 +0100
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic function
 groups
In-Reply-To: <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com>
 <Yd2jcfXqqKHK/NaG@archlinux-ax161>
 <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
Message-ID: <CACRpkdYCpbE6Yuxd8Z97-WV5Mi2MSBppi7KidCAB18uoLK+8JQ@mail.gmail.com>

On Tue, Jan 11, 2022 at 5:51 PM Rafa? Mi?ecki <zajec5 at gmail.com> wrote:

> > Looks like something like the third patch of the series is needed for
> > the Thunderbay driver, which it appears was in development at the same
> > time as this series.
>
> Correct, this driver didn't exist in Linus's tree when I developed my changes.
>
> Too bad thunderbay copies that old & complex logic that I just fixed in the keembay driver. I'll have to redo my changes for the thunderbay now.
>
> I don't agree with the idea of reverting my patchset and working on V3 though. It's a relatively simple thing we need to fix, it just be just a follow-up commit.

Yeah this kind of things happens, we just deal with it throughout the -rc:s
no big deal. Release candidates exist for a reason. Let's make a fixup patch.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 16:55:03 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 01:55:03 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
Message-ID: <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>

On Tue, Jan 11, 2022 at 9:18 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:

> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) pin
> controller bindings to DT schema format.  Parts of description and DTS
> example was copied from existing sources, so keep the license as
> GPL-2.0-only.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> Reviewed-by: Rob Herring <robh at kernel.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

I expect that you will merge this into ARM SoC with the rest
of the DTS fixes?

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 17:03:18 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 02:03:18 +0100
Subject: [PATCH 1/3] pinctrl: meson-g12a: add more pwm_f options
In-Reply-To: <20220103154616.308376-2-gary.bisson@boundarydevices.com>
References: <20220103154616.308376-1-gary.bisson@boundarydevices.com>
 <20220103154616.308376-2-gary.bisson@boundarydevices.com>
Message-ID: <CACRpkdZRL8VuY5K_d69VHE6eXCmUb18ZRs5v9shExe4ipmw90Q@mail.gmail.com>

On Mon, Jan 3, 2022 at 4:46 PM Gary Bisson
<gary.bisson at boundarydevices.com> wrote:

> Add missing PWM_F pin muxing for GPIOA_11 and GPIOZ_12.
>
> Signed-off-by: Gary Bisson <gary.bisson at boundarydevices.com>

This patch 1/3 applied for v5.18.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 15 17:05:26 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 02:05:26 +0100
Subject: [PATCH] pinctrl: sunxi: Fix H616 I2S3 pin data
In-Reply-To: <20220105172952.23347-1-andre.przywara@arm.com>
References: <20220105172952.23347-1-andre.przywara@arm.com>
Message-ID: <CACRpkdZ528B4b9XzBpfGAwPbDaDH12LQ8rTce9AsDuKF+v5A=A@mail.gmail.com>

On Wed, Jan 5, 2022 at 6:30 PM Andre Przywara <andre.przywara at arm.com> wrote:

> Two bugs have sneaked in the H616 pinctrl data:
> - PH9 uses the mux value of 0x3 twice (one should be 0x5 instead)
> - PH8 and PH9 use the "i2s3" function name twice in each pin
>
> For the double pin name we use the same trick we pulled for i2s0: append
> the pin function to the group name to designate the special function.
>
> Fixes: 25adc29407fb ("pinctrl: sunxi: Add support for the Allwinner H616 pin controller")
> Reported-by: SASANO Takayoshi <uaa at mx5.nisiq.net>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>

Patch applied for fixes.

Yours,
Linus Walleij


From xkernel.wang at foxmail.com  Sat Jan 15 21:34:50 2022
From: xkernel.wang at foxmail.com (xkernel.wang at foxmail.com)
Date: Sun, 16 Jan 2022 13:34:50 +0800
Subject: [PATCH] nvmem: meson-mx-efuse: check the return value of
 devm_kstrdup()
Message-ID: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>

From: Xiaoke Wang <xkernel.wang at foxmail.com>

devm_kstrdup() returns pointer to allocated string on success,
NULL on failure. So it is better to check the return value of it.

Signed-off-by: Xiaoke Wang <xkernel.wang at foxmail.com>
---
 drivers/nvmem/meson-mx-efuse.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
index 07c9f38..38e6a5f 100644
--- a/drivers/nvmem/meson-mx-efuse.c
+++ b/drivers/nvmem/meson-mx-efuse.c
@@ -211,6 +211,9 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
 
 	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
 					  GFP_KERNEL);
+	if (!efuse->config.name)
+		return -ENOMEM;
+
 	efuse->config.owner = THIS_MODULE;
 	efuse->config.dev = &pdev->dev;
 	efuse->config.priv = efuse;
-- 


From xueshuai at linux.alibaba.com  Sun Jan 16 00:43:10 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Sun, 16 Jan 2022 16:43:10 +0800
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
References: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
Message-ID: <20220116084310.57465-1-xueshuai@linux.alibaba.com>

On an ACPI system, ACPI is initialised very early from a
subsys_initcall(), while SDEI is not ready until a
subsys_initcall_sync(). This patch is to reduce the time before GHES
initialization.

The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
apei_sdei_unregister_ghes()) to register or unregister event callback
for dispatcher in firmware. When the GHES driver probing, it registers
the corresponding callback according to the notification type specified
by GHES. If the GHES notification type is SDEI, the GHES driver will
call apei_sdei_register_ghes() to register event call.

When the firmware emits an event, it migrates the handling of the event
into the kernel at the registered entry-point __sdei_asm_handler. And
finally, the kernel will call the registered event callback and return
status_code to indicate the status of event handling. SDEI_EV_FAILED
indicates that the kernel failed to handle the event.

Consequently, when an error occurs during kernel booting, the kernel is
unable to handle and report errors until the GHES driver is initialized
by device_initcall(), in which the event callback is registered.  For
example, when the kernel booting, the console logs many times from
firmware before GHES drivers init in our platform:

	Trip in MM PCIe RAS handle(Intr:910)
  	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
	Find RP(98:1.0)
	--Walk dev(98:1.0) CE:0 UCE:4000
	...
	ERROR:   sdei_dispatch_event(32a) ret:-1
	--handler(910) end

This is because the callback function has not been registered yet.  Due
to the poor design of firmware, previously reported errors will be
overwritten by new ones. Therefore, all errors that occurred before GHES
initialization are missed and there is no chance to report and find them
again.

>From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
the estatus memory pool. On the other hand, ghes_init() relies on
sdei_init() to detect the SDEI version and the framework for registering
and unregistering events. The dependencies are as follows

	ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
	ghes_init() => sdei_init()

Based on above, move sdei_init and ghes_init as far ahead as possible,
right after acpi_iort_init() in acpi_init(). After this patch, there are
still errors missing, but we have to tolerate it until the software
reporting capability is built. And this patch merely reduce the time
before GHES initialization. The boot dmesg before this patch:

	[    3.688586] HEST: Table parsing has been initialized.
	...
	[   33.204340] calling  sdei_init+0x0/0x120 @ 1
	[   33.208645] sdei: SDEIv1.0 (0x0) detected in firmware.
	...
	[   36.005390] calling  ghes_init+0x0/0x11c @ 1
	[   36.190021] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.

After this patch, the boot dmesg like bellow:

	[    3.688664] HEST: Table parsing has been initialized.
	[    3.688691] sdei: SDEIv1.0 (0x0) detected in firmware.
	[    3.694557] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.

As we can see, the initialization of GHES is advanced by 33 seconds.
(It should be noted that the effect of optimization varies with the
platform.)

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
---
 drivers/acpi/apei/ghes.c    | 18 ++++++++----------
 drivers/acpi/bus.c          |  4 ++++
 drivers/acpi/pci_root.c     |  4 ++--
 drivers/firmware/arm_sdei.c | 13 ++-----------
 include/acpi/apei.h         |  2 ++
 include/linux/arm_sdei.h    |  2 ++
 6 files changed, 20 insertions(+), 23 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0c5c9acc6254..64f24a9f213f 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1457,27 +1457,26 @@ static struct platform_driver ghes_platform_driver = {
 	.remove		= ghes_remove,
 };
 
-static int __init ghes_init(void)
+void __init ghes_init(void)
 {
 	int rc;
 
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 
 	switch (hest_disable) {
 	case HEST_NOT_FOUND:
-		return -ENODEV;
+		pr_info(GHES_PFX "HEST is not found!\n");
+		return;
 	case HEST_DISABLED:
 		pr_info(GHES_PFX "HEST is not enabled!\n");
-		return -EINVAL;
+		return;
 	default:
 		break;
 	}
 
-	if (ghes_disable) {
+	if (ghes_disable)
 		pr_info(GHES_PFX "GHES is not enabled!\n");
-		return -EINVAL;
-	}
 
 	ghes_nmi_init_cxt();
 
@@ -1495,8 +1494,7 @@ static int __init ghes_init(void)
 	else
 		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
 
-	return 0;
+	return;
 err:
-	return rc;
+	ghes_disable = 1;
 }
-device_initcall(ghes_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 07f604832fd6..1dcd71df2cd5 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -30,6 +30,7 @@
 #include <linux/acpi_viot.h>
 #include <linux/pci.h>
 #include <acpi/apei.h>
+#include <linux/arm_sdei.h>
 #include <linux/suspend.h>
 #include <linux/prmt.h>
 
@@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
 
 	pci_mmcfg_late_init();
 	acpi_iort_init();
+	acpi_hest_init();
+	sdei_init();
+	ghes_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b76db99cced3..14e20af44627 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -23,7 +23,7 @@
 #include <linux/dmi.h>
 #include <linux/platform_data/x86/apple.h>
 #include <acpi/apei.h>	/* for acpi_hest_init() */
-
+#include <linux/arm_sdei.h> /* for sdei_init() */
 #include "internal.h"
 
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
@@ -943,7 +943,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 void __init acpi_pci_root_init(void)
 {
-	acpi_hest_init();
+
 	if (acpi_pci_disabled)
 		return;
 
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
index a7e762c352f9..1e1a51510e83 100644
--- a/drivers/firmware/arm_sdei.c
+++ b/drivers/firmware/arm_sdei.c
@@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
 	return true;
 }
 
-static int __init sdei_init(void)
+void __init sdei_init(void)
 {
 	struct platform_device *pdev;
 	int ret;
 
 	ret = platform_driver_register(&sdei_driver);
 	if (ret || !sdei_present_acpi())
-		return ret;
+		return;
 
 	pdev = platform_device_register_simple(sdei_driver.driver.name,
 					       0, NULL, 0);
@@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
 		pr_info("Failed to register ACPI:SDEI platform device %d\n",
 			ret);
 	}
-
-	return ret;
 }
 
-/*
- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
- * by device_initcall(). We want to be called in the middle.
- */
-subsys_initcall_sync(sdei_init);
-
 int sdei_event_handler(struct pt_regs *regs,
 		       struct sdei_registered_event *arg)
 {
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index ece0a8af2bae..7dbd6363fda7 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -27,8 +27,10 @@ extern int hest_disable;
 extern int erst_disable;
 #ifdef CONFIG_ACPI_APEI_GHES
 extern bool ghes_disable;
+void __init ghes_init(void);
 #else
 #define ghes_disable 1
+static inline void ghes_init(void) { return; }
 #endif
 
 #ifdef CONFIG_ACPI_APEI
diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
index 0a241c5c911d..9c987188b692 100644
--- a/include/linux/arm_sdei.h
+++ b/include/linux/arm_sdei.h
@@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
 /* For use by arch code when CPU hotplug notifiers are not appropriate. */
 int sdei_mask_local_cpu(void);
 int sdei_unmask_local_cpu(void);
+void __init sdei_init(void);
 #else
 static inline int sdei_mask_local_cpu(void) { return 0; }
 static inline int sdei_unmask_local_cpu(void) { return 0; }
+static inline void sdei_init(void) { return ; }
 #endif /* CONFIG_ARM_SDE_INTERFACE */
 
 
-- 
2.20.1.12.g72788fdb



From pavel at ucw.cz  Sun Jan 16 01:23:26 2022
From: pavel at ucw.cz (Pavel Machek)
Date: Sun, 16 Jan 2022 10:23:26 +0100
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <20220113121143.22280-1-alim.akhtar@samsung.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
Message-ID: <20220116092325.GA30745@amd>

Hi!

> This patch set adds basic support for the Tesla Full Self-Driving (FSD)
> SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> as well as several IPs.

I'm not thrilled by their naming. Intel does not produce "Intel
Fastest in world SoC", and this chip is not actually suitable for
autonomous driving :-(.

								Pavel
-- 
http://www.livejournal.com/~pavelmachek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220116/1ff5f504/attachment.sig>

From jianhua.ljh at gmail.com  Sun Jan 16 01:38:26 2022
From: jianhua.ljh at gmail.com (Jianhua Liu)
Date: Sun, 16 Jan 2022 17:38:26 +0800
Subject: [PATCH v2 2/2] arm64: kprobes: add support for KPROBES_ON_FTRACE
In-Reply-To: <20220107212046.13e55368664b31c2b41b7e94@kernel.org>
References: <1635858706-27320-1-git-send-email-jianhua.ljh@gmail.com>
 <1635858706-27320-2-git-send-email-jianhua.ljh@gmail.com>
 <20211217164019.7d5d9848f350fef4f709c62f@kernel.org>
 <CAAgTQPXi_cmi27upcLHgen3PotOtcu64oAxjYp559g6fYgkCvQ@mail.gmail.com>
 <20220107212046.13e55368664b31c2b41b7e94@kernel.org>
Message-ID: <CAAgTQPWs0x_Hczc6ha5Cf2sVOYhAO91g-=79abi_+DWs9v-1kA@mail.gmail.com>

On Fri, Jan 7, 2022 at 8:20 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
>
> On Fri, 7 Jan 2022 01:34:16 +0800
> Jianhua Liu <jianhua.ljh at gmail.com> wrote:
>
> > On Fri, Dec 17, 2021 at 3:40 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> > >
> > > Hi,
> > >
> > > On Tue,  2 Nov 2021 21:11:46 +0800
> > > Janet Liu <jianhua.ljh at gmail.com> wrote:
> > >
> > > > From: Janet Liu <janet.liu at unisoc.com>
> > > >
> > > > This patch allow kprobes on ftrace call sites. This optimization
> > > > avoids use of a trap with regular kprobes.
> > > >
> > > > This depends on HAVE_DYNAMIC_FTRACE_WITH_REGS which depends on
> > > > "patchable-function-entry" options which is only implemented with newer
> > > > toolchains.
> > > >
> > > > Signed-off-by: Janet Liu <janet.liu at unisoc.com>
> > > > ---
> > > >  arch/arm64/Kconfig                 |  1 +
> > > >  arch/arm64/kernel/probes/Makefile  |  1 +
> > > >  arch/arm64/kernel/probes/ftrace.c  | 73 ++++++++++++++++++++++++++++++
> > > >  arch/arm64/kernel/probes/kprobes.c | 27 +++++++++++
> > > >  4 files changed, 102 insertions(+)
> > > >  create mode 100644 arch/arm64/kernel/probes/ftrace.c
> > > >
> > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > > index 339130712093..f59005608976 100644
> > > > --- a/arch/arm64/Kconfig
> > > > +++ b/arch/arm64/Kconfig
> > > > @@ -200,6 +200,7 @@ config ARM64
> > > >       select HAVE_SYSCALL_TRACEPOINTS
> > > >       select HAVE_KPROBES
> > > >       select HAVE_OPTPROBES
> > > > +     select HAVE_KPROBES_ON_FTRACE
> > > >       select HAVE_KRETPROBES
> > > >       select HAVE_GENERIC_VDSO
> > > >       select IOMMU_DMA if IOMMU_SUPPORT
> > > > diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> > > > index c77c92ac95fd..d9b204f4795a 100644
> > > > --- a/arch/arm64/kernel/probes/Makefile
> > > > +++ b/arch/arm64/kernel/probes/Makefile
> > > > @@ -3,5 +3,6 @@ obj-$(CONFIG_KPROBES)         += kprobes.o decode-insn.o      \
> > > >                                  kprobes_trampoline.o         \
> > > >                                  simulate-insn.o
> > > >  obj-$(CONFIG_OPTPROBES)      += opt.o opt_head.o
> > > > +obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
> > > >  obj-$(CONFIG_UPROBES)                += uprobes.o decode-insn.o      \
> > > >                                  simulate-insn.o
> > > > diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
> > > > new file mode 100644
> > > > index 000000000000..46ea92eb552f
> > > > --- /dev/null
> > > > +++ b/arch/arm64/kernel/probes/ftrace.c
> > > > @@ -0,0 +1,73 @@
> > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > +//
> > > > +// Dynamic Ftrace based Kprobes Optimization
> > > > +//
> > > > +// Copyright (C) 2021, Unisoc Inc.
> > > > +// Author: Janet Liu <janet.liu at unisoc.com>
> > > > +#include <linux/kprobes.h>
> > > > +#include <linux/ptrace.h>
> > > > +#include <linux/hardirq.h>
> > > > +#include <linux/preempt.h>
> > > > +#include <linux/ftrace.h>
> > > > +
> > > > +
> > > > +/* Ftrace callback handler for kprobes*/
> > > > +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > > > +                        struct ftrace_ops *ops, struct ftrace_regs *fregs)
> > > > +{
> > > > +     struct kprobe *p;
> > > > +     struct kprobe_ctlblk *kcb;
> > > > +     struct pt_regs *regs = ftrace_get_regs(fregs);
> > > > +     int bit;
> > > > +
> > > > +     bit = ftrace_test_recursion_trylock(ip, parent_ip);
> > > > +     if (bit < 0)
> > > > +             return;
> > > > +
> > > > +     preempt_disable_notrace();
> > >
> > > This already has been done in ftrace side.
> >
> > Hi Masami,
> >
> > Got it by reading code, will fix this.
> >
> > >
> > > > +     p = get_kprobe((kprobe_opcode_t *)ip);
> > > > +     if (unlikely(!p) || kprobe_disabled(p))
> > > > +             goto end;
> > > > +
> > > > +     kcb = get_kprobe_ctlblk();
> > > > +     if (kprobe_running()) {
> > > > +             kprobes_inc_nmissed_count(p);
> > > > +     } else {
> > > > +             unsigned long orig_ip = instruction_pointer(regs);
> > > > +
> > > > +             instruction_pointer_set(regs, ip);
> > >
> > > The 'ip' is the address of the 'bl' instruction, which must be
> > > p->addr + AARCH64_INSN_SIZE * 2. But this is a bit strange.
> > >
> > > On aarch64, if the user probe callback is called from breakpoint handler,
> > > regs->pc == kp->addr. But in this case, it is not the same.
> > >
> > > So, what about this?
> > >
> > >  instruction_pointer_set(regs, ip - AARCH64_INSN_SIZE);
> > >
> >
> > I got what you said.
> >
> > But p->addr is changed when KPROBES_ON_FTRACE enable.
> > I implemented kprobe_lookup_name for arm64 to do the change in this patch.
>
> Hmm, that is no good, because printk("%pS\n", p->addr) does not show
> what the user set by p->symbol_name. This may confuse user.
> Moreover, if user doesn't set symbol_name but addr directly (this
> happens when you use 'perf probe' command, which will pass the address
> from '_text', not the function entry.
>

Hi Masami,

Thanks for your explanation,if user doesn't set p->addr will not
kprobe on ftrace entry.
This also confuse me.

> > because kernel/kprobe.c:check_ftrace_location check,
> > if p->addr != ftrace_addr, don't kprobe on ftrace entry.
> > so p->addr is equal to ftrace addr(the second nop), is equal to 'ip'.
> > here should be instruction_pointer_set(regs, ip);
>
> Hmm, OK. this is a special case for the arm64 (and maybe other
> architectures except for x86). Let's fix the check_ftrace_location().
> We already know that 2 instructions at the beginning of function will
> be used for ftrace on arm64. Thus arm64 version of check_ftrace_location()
> will check the given address + 1 is ftrace location or not.
>
> >
> > > > +
> > > > +             __this_cpu_write(current_kprobe, p);
> > > > +             kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> > > > +             if (!p->pre_handler || !p->pre_handler(p, regs)) {
> > > > +                     /*
> > > > +                      *Emulate singlestep (and also recover regs->pc)
> > > > +                      *as if there is a nop
> > > > +                      */
> > > > +                     instruction_pointer_set(regs,
> > > > +                                     (unsigned long)p->addr + MCOUNT_INSN_SIZE);
> > >
> > > And then, this will be
> > >
> > >                         instruction_pointer_set(regs,
> > >                                         (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
> > >
> > > So basically, kprobes on ftrace will skips 2 NOP instructions (the compiler installed
> > > 2 nops) and call post handler. This means we have a virtual big NOP instruction there.
> > >
> > Ditto, skip two nop instructions should
> > instruction_pointer_set(regs,
> >                         (unsigned long)p->addr + AARCH64_INSN_SIZE);
> >
> >
> > > > +                     if (unlikely(p->post_handler)) {
> > > > +                             kcb->kprobe_status = KPROBE_HIT_SSDONE;
> > > > +                             p->post_handler(p, regs, 0);
> > > > +                     }
> > > > +                     instruction_pointer_set(regs, orig_ip);
> > > > +             }
> > > > +
> > > > +             /*
> > > > +              * If pre_handler returns !0,it changes regs->pc. We have to
> > > > +              * skip emulating post_handler.
> > > > +              */
> > > > +             __this_cpu_write(current_kprobe, NULL);
> > > > +     }
> > > > +end:
> > > > +     preempt_enable_notrace();
> > > > +     ftrace_test_recursion_unlock(bit);
> > > > +}
> > > > +NOKPROBE_SYMBOL(kprobe_ftrace_handler);
> > > > +
> > > > +int arch_prepare_kprobe_ftrace(struct kprobe *p)
> > > > +{
> > > > +     p->ainsn.api.insn = NULL;
> > > > +     p->ainsn.api.restore = 0;
> > > > +     return 0;
> > > > +}
> > > > diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> > > > index 6dbcc89f6662..3d371d3e4dfa 100644
> > > > --- a/arch/arm64/kernel/probes/kprobes.c
> > > > +++ b/arch/arm64/kernel/probes/kprobes.c
> > > > @@ -417,6 +417,33 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
> > > >       return 0;
> > > >  }
> > > >
> > > > +kprobe_opcode_t __kprobes *kprobe_lookup_name(const char *name, unsigned int offset)
> > > > +{
> > > > +     kprobe_opcode_t *addr;
> > > > +
> > > > +     addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
> > > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > > +     if (addr && !offset) {
> > > > +             unsigned long faddr;
> > > > +
> > > > +             faddr = ftrace_location_range((unsigned long)addr,
> > > > +                                           (unsigned long)addr + 8);
> > >
> > > this '8' must be (AARCH64_INSN_SIZE * 2). And here you may need to add
> > > a comment why search the 2 instructions. (it is because arm64 uses
> > > -fpatchable-function-entry=2.)
> > >
> > Got it , will fix it.
> > > > +             if (faddr)
> > > > +                     addr = (kprobe_opcode_t *)faddr;
> > > > +     }
> > This change the p->addr to ftrace_addr.
>
> Ah, OK. Please forgot above. What we have to do is to change the
> check_ftrace_location(), not this conversion.

I don't do this conversion, and try to implement arm64 special
check_ftrace_location as following.
but register kprobe fail.

diff --git a/arch/arm64/kernel/probes/kprobes.c
b/arch/arm64/kernel/probes/kprobes.c
index d9dfa82c1f18..609f3f103a89 100644
--- a/arch/arm64/kernel/probes/kprobes.c
+++ b/arch/arm64/kernel/probes/kprobes.c
+int __kprobes check_ftrace_location(struct kprobe *p)
+{
+        unsigned long ftrace_addr;
+
+        ftrace_addr = ftrace_location_range((unsigned long)p->addr,
+                               (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
+        if (ftrace_addr) {
+#ifdef CONFIG_KPROBES_ON_FTRACE
+                /* Given address is not on the instruction boundary */
+                if ((unsigned long)p->addr > ftrace_addr)
+                        return -EILSEQ;
+               if (p->offset <= AARCH64_INSN_SIZE * 2)
+                       p->flags |= KPROBE_FLAG_FTRACE;
+#else   /* !CONFIG_KPROBES_ON_FTRACE */
+                return -EINVAL;
+#endif
+        }
+        return 0;
+}
+
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 21eccc961bba..91c95ba4eed0 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1539,7 +1539,7 @@ static inline int warn_kprobe_rereg(struct kprobe *p)
        return ret;
 }

-static int check_ftrace_location(struct kprobe *p)
+int __weak check_ftrace_location(struct kprobe *p)
 {
        unsigned long ftrace_addr;


__arm_kprobe_ftrace print fail info:
[   38.286515] Failed to arm kprobe-ftrace at kernel_clone+0x0/0x440 (error -22)
[   38.286606] WARNING: CPU: 3 PID: 341 at kernel/kprobes.c:1062
arm_kprobe+0x114/0x14c

__arm_kprobe_ftrace calls ftrace_set_filter_ip,
ftrace_set_filter_ip use p->addr, but failed.

Thanks
Jianhua

>
> Thank you,
>
> >
> > > > +#endif
> > > > +     return addr;
> > > > +}
> > > > +
> > > > +bool __kprobes arch_kprobe_on_func_entry(unsigned long offset)
> > > > +{
> > > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > > +     return offset <= 8;
> > >
> > > Ditto.
> > Got it, will add comment.
> >
> > Thanks
> >
> > Jianhua
> > >
> > > > +#else
> > > > +     return !offset;
> > > > +#endif
> > > > +}
> > > > +
> > > >  int __init arch_init_kprobes(void)
> > > >  {
> > > >       register_kernel_break_hook(&kprobes_break_hook);
> > > > --
> > > > 2.25.1
> > > >
> > >
> > > Thank you,
> > >
> > >
> > > --
> > > Masami Hiramatsu <mhiramat at kernel.org>
>
>
> --
> Masami Hiramatsu <mhiramat at kernel.org>


From jic23 at kernel.org  Sun Jan 16 03:19:39 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 16 Jan 2022 11:19:39 +0000
Subject: [PATCH 21/23] iio: adc: exynos-adc: Add support for ADC V3
 controller
In-Reply-To: <20220113121143.22280-22-alim.akhtar@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122452epcas5p201a3a87d0e9c0e9f449a90ed62de1f1c@epcas5p2.samsung.com>
 <20220113121143.22280-22-alim.akhtar@samsung.com>
Message-ID: <20220116111939.413ece7e@jic23-huawei>

On Thu, 13 Jan 2022 17:41:41 +0530
Alim Akhtar <alim.akhtar at samsung.com> wrote:

> Exynos's ADC-V3 has some difference in registers set, number of
> programmable channels (16 channel) etc. This patch adds support for ADC-V3
> controller version.
> 
> Cc: linux-fsd at tesla.com
> Cc: jic23 at kernel.org
> Cc: linux-iio at vger.kernel.org
> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Hi Alim,

A few minor suggestions below.  I'm not seeing a binding update though...

I'd also suggest that it would be more appropriate to break this out as
a separate mini series from the main support so that it can be reviewed
and merge separately. It's not ideal when a list just gets patch 21 of
23 with no cover letter etc sent to it.

Jonathan

> ---
>  drivers/iio/adc/exynos_adc.c | 74 +++++++++++++++++++++++++++++++++++-
>  1 file changed, 72 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c
> index 3b3868aa2533..61752e798fd6 100644
> --- a/drivers/iio/adc/exynos_adc.c
> +++ b/drivers/iio/adc/exynos_adc.c
> @@ -55,6 +55,11 @@
>  #define ADC_V2_INT_ST(x)	((x) + 0x14)
>  #define ADC_V2_VER(x)		((x) + 0x20)
>  
> +/* ADC_V3 register definitions */
> +#define ADC_V3_DAT(x)			((x) + 0x08)
> +#define ADC_V3_DAT_SUM(x)		((x) + 0x0C)
> +#define ADC_V3_DBG_DATA(x)		((x) + 0x1C)
> +
>  /* Bit definitions for ADC_V1 */
>  #define ADC_V1_CON_RES		(1u << 16)
>  #define ADC_V1_CON_PRSCEN	(1u << 14)
> @@ -92,6 +97,7 @@
>  
>  /* Bit definitions for ADC_V2 */
>  #define ADC_V2_CON1_SOFT_RESET	(1u << 2)
> +#define ADC_V2_CON1_SOFT_NON_RESET	(1u << 1)
>  
>  #define ADC_V2_CON2_OSEL	(1u << 10)
>  #define ADC_V2_CON2_ESEL	(1u << 9)
> @@ -100,6 +106,7 @@
>  #define ADC_V2_CON2_ACH_SEL(x)	(((x) & 0xF) << 0)
>  #define ADC_V2_CON2_ACH_MASK	0xF
>  
> +#define MAX_ADC_V3_CHANNELS		16
>  #define MAX_ADC_V2_CHANNELS		10
>  #define MAX_ADC_V1_CHANNELS		8
>  #define MAX_EXYNOS3250_ADC_CHANNELS	2

Given we have a mixture of required an unrequired elements in this structure
it might be a good idea to add some documentation.  Kernel-doc for the whole
structure preferred.  Note this isn't necessarily something that needs to be
in this patch given the lack of docs predates this and with the change to make
adc_isr() required that I suggest below things aren't made worse by this patch.

> @@ -164,6 +171,7 @@ struct exynos_adc_data {
>  	void (*exit_hw)(struct exynos_adc *info);
>  	void (*clear_irq)(struct exynos_adc *info);
>  	void (*start_conv)(struct exynos_adc *info, unsigned long addr);
> +	irqreturn_t (*adc_isr)(int irq, void *dev_id);
>  };
>  
>  static void exynos_adc_unprepare_clk(struct exynos_adc *info)
> @@ -484,6 +492,59 @@ static const struct exynos_adc_data exynos7_adc_data = {
>  	.start_conv	= exynos_adc_v2_start_conv,
>  };
>  
> +static void exynos_adc_v3_init_hw(struct exynos_adc *info)
> +{
> +	u32 con2;
> +
> +	writel(ADC_V2_CON1_SOFT_RESET, ADC_V2_CON1(info->regs));
> +
> +	writel(ADC_V2_CON1_SOFT_NON_RESET, ADC_V2_CON1(info->regs));
> +
> +	con2 = ADC_V2_CON2_C_TIME(6);
> +	writel(con2, ADC_V2_CON2(info->regs));
> +
> +	/* Enable interrupts */
> +	writel(1, ADC_V2_INT_EN(info->regs));
> +}
> +
> +static void exynos_adc_v3_exit_hw(struct exynos_adc *info)
> +{
> +	u32 con2;
> +
> +	con2 = readl(ADC_V2_CON2(info->regs));
> +	con2 &= ~ADC_V2_CON2_C_TIME(7);
> +	writel(con2, ADC_V2_CON2(info->regs));
> +
> +	/* Disable interrupts */
> +	writel(0, ADC_V2_INT_EN(info->regs));
> +}
> +
> +static irqreturn_t exynos_adc_v3_isr(int irq, void *dev_id)
> +{
> +	struct exynos_adc *info = (struct exynos_adc *)dev_id;

Shouldn't need the cast as cast from void * to another pointer
is always valid in C without the explicit cast.

> +	u32 mask = info->data->mask;
> +
> +	info->value = readl(ADC_V3_DAT(info->regs)) & mask;
> +
> +	if (info->data->clear_irq)
> +		info->data->clear_irq(info);

Don't need this currently as v3_isr() is always matched
with clear_isr() being provided.  Having the check implies
otherwise which is probably not a good thing to do until some future
device support (maybe) needs it.

> +
> +	complete(&info->completion);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static const struct exynos_adc_data exynos_adc_v3_adc_data = {
> +	.num_channels	= MAX_ADC_V3_CHANNELS,
> +	.mask		= ADC_DATX_MASK, /* 12 bit ADC resolution */
> +
> +	.init_hw	= exynos_adc_v3_init_hw,
> +	.exit_hw	= exynos_adc_v3_exit_hw,
> +	.clear_irq	= exynos_adc_v2_clear_irq,
> +	.start_conv	= exynos_adc_v2_start_conv,
> +	.adc_isr	= exynos_adc_v3_isr,
> +};
> +
>  static const struct of_device_id exynos_adc_match[] = {
>  	{
>  		.compatible = "samsung,s3c2410-adc",
> @@ -518,6 +579,9 @@ static const struct of_device_id exynos_adc_match[] = {
>  	}, {
>  		.compatible = "samsung,exynos7-adc",
>  		.data = &exynos7_adc_data,
> +	}, {
> +		.compatible = "samsung,exynos-adc-v3",
> +		.data = &exynos_adc_v3_adc_data,
>  	},
>  	{},
>  };
> @@ -719,6 +783,12 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = {
>  	ADC_CHANNEL(7, "adc7"),
>  	ADC_CHANNEL(8, "adc8"),
>  	ADC_CHANNEL(9, "adc9"),
> +	ADC_CHANNEL(10, "adc10"),
> +	ADC_CHANNEL(11, "adc11"),
> +	ADC_CHANNEL(12, "adc12"),
> +	ADC_CHANNEL(13, "adc13"),
> +	ADC_CHANNEL(14, "adc14"),
> +	ADC_CHANNEL(15, "adc15"),
>  };
>  
>  static int exynos_adc_remove_devices(struct device *dev, void *c)
> @@ -885,8 +955,8 @@ static int exynos_adc_probe(struct platform_device *pdev)
>  
>  	mutex_init(&info->lock);
>  
> -	ret = request_irq(info->irq, exynos_adc_isr,
> -					0, dev_name(&pdev->dev), info);
> +	ret = request_irq(info->irq, info->data->adc_isr ? info->data->adc_isr :
> +				exynos_adc_isr, 0, dev_name(&pdev->dev), info);

I'd rather see the slightly larger change of providing adc_isr for existing
parts and the conditional part here going away.

Jonathan


>  	if (ret < 0) {
>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
>  							info->irq);



From linus.walleij at linaro.org  Sun Jan 16 04:05:57 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 13:05:57 +0100
Subject: [PATCH 11/23] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220113121143.22280-12-alim.akhtar@samsung.com>
References: <CGME20220113122400epcas5p34363ba8f477b4c273d601d0b64324afa@epcas5p3.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220113121143.22280-12-alim.akhtar@samsung.com>
Message-ID: <CACRpkdaRshgkwrAgF-zhpsDxjPPC9GTOYXvnXL927GyjDhbu=g@mail.gmail.com>

On Thu, Jan 13, 2022 at 1:24 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:

> This patch adds Tesla FSD SoC specific data to enable pinctrl.
> FSD SoC has similar pinctrl controller as found in the most
> samsung/exynos SoCs.
>
> Cc: linux-fsd at tesla.com
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Looks good to me once Krysztof is happy with this I expect to get the
pin control portions from him by a pull request.
FWIW
Acked-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sun Jan 16 04:09:05 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 13:09:05 +0100
Subject: [PATCH 12/23] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220113121143.22280-13-alim.akhtar@samsung.com>
References: <CGME20220113122404epcas5p4aa1c3ac09510eb55cce5fdd0791993a6@epcas5p4.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220113121143.22280-13-alim.akhtar@samsung.com>
Message-ID: <CACRpkdZkc9ShabhKoVnXMfQp3M7siYUYirBFVBP8y3dLEw5azA@mail.gmail.com>

On Thu, Jan 13, 2022 at 1:24 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:

> Add vendor prefix for the Tesla (https://www.tesla.com)
>
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

That's an interesting new SoC vendor...
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sun Jan 16 04:12:21 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 13:12:21 +0100
Subject: [PATCH 18/23] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220113121143.22280-19-alim.akhtar@samsung.com>
References: <CGME20220113122435epcas5p18e6a2699f193b9e1287588278a570235@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220113121143.22280-19-alim.akhtar@samsung.com>
Message-ID: <CACRpkdYSR5hiVKoZTffxudNOUQCNFqX-yuys-xgeocn2vG_ecg@mail.gmail.com>

On Thu, Jan 13, 2022 at 1:24 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:

> This patch adds compatible and port configuration for
> spi controller for Tesla Full Self-Driving SoC.
>
> Cc: linux-fsd at tesla.com
> Cc: broonie at kernel.org
> Cc: linux-spi at vger.kernel.org
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Note to self: now that I see that the Samsung "S3C" SPI controller,
which I was thinking of as "some kind of early 2000s legacy" is used
by the very latest silicon I bumped up fixing it to use GPIO descriptors
a bit on my TODO list.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sun Jan 16 04:13:34 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 13:13:34 +0100
Subject: [PATCH v2 02/11] dt-bindings: gpio: fix gpio-hog example
In-Reply-To: <20220114141507.395271-3-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-3-marcel@ziswiler.com>
Message-ID: <CACRpkdb+62jojDXTjEXjgMrpo6XkZy8AZg+jDdhqt-7w6nVQig@mail.gmail.com>

On Fri, Jan 14, 2022 at 3:15 PM Marcel Ziswiler <marcel at ziswiler.com> wrote:

> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>
> Even if this is no yaml yet at least fix the example to be compliant to
> later schema as e.g. found in gpio-pca95xx.yaml, fairchild,74hc595.yaml
> and gpio/fsl-imx-gpio.yaml.
>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Acked-by: Rob Herring <robh at kernel.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linux at fw-web.de  Sun Jan 16 04:49:08 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 16 Jan 2022 13:49:08 +0100
Subject: [PATCH v1 0/3] Add BananaPi R2 Pro board
Message-ID: <20220116124911.65203-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This Series adds RK3568 based Bananapi R2 Board.

While testing new dts with dtbs_check we've found an issue with
mainline gmac0 node in rk3568.dtsi which breaks dtbs_check. So first
Patch fixes this problem.

Frank Wunderlich (3):
  dts64: rk3568: drop pclk_xpcs from gmac0
  dt-bindings: rockchip: Add BananaPi R2 Pro Board
  dts64: rockchip: Add Bananapi R2 Pro

 .../devicetree/bindings/arm/rockchip.yaml     |   5 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-bpi-r2-pro.dts   | 428 ++++++++++++++++++
 arch/arm64/boot/dts/rockchip/rk3568.dtsi      |   6 +-
 4 files changed, 436 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts

-- 
2.25.1



From linux at fw-web.de  Sun Jan 16 04:49:10 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 16 Jan 2022 13:49:10 +0100
Subject: [PATCH v1 2/3] dt-bindings: rockchip: Add BananaPi R2 Pro Board
In-Reply-To: <20220116124911.65203-1-linux@fw-web.de>
References: <20220116124911.65203-1-linux@fw-web.de>
Message-ID: <20220116124911.65203-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add Devicetree Binding for Bananapi R2 Pro Board based on rk3568 SoC

Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 4aed16176434..33d6423fe6c3 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -651,6 +651,11 @@ properties:
           - const: rockchip,rk3568-evb1-v10
           - const: rockchip,rk3568
 
+      - description: Rockchip RK3568 Banana Pi R2 Pro
+        items:
+          - const: rockchip,rk3568-bpi-r2pro
+          - const: rockchip,rk3568
+
 additionalProperties: true
 
 ...
-- 
2.25.1



From linux at fw-web.de  Sun Jan 16 04:49:09 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 16 Jan 2022 13:49:09 +0100
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <20220116124911.65203-1-linux@fw-web.de>
References: <20220116124911.65203-1-linux@fw-web.de>
Message-ID: <20220116124911.65203-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

pclk_xpcs is not supported and breaks dtbs_check, so remove it

following warnings occour, and many more

rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
    [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
    [15, 389], [15, 185], [15, 172]] is too long
	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
    ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
    'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml

after removing the clock the other warnings are also gone.

Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8..d91df1cde736 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -32,13 +32,11 @@ gmac0: ethernet at fe2a0000 {
 		clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
 			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
 			 <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
-			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
-			 <&cru PCLK_XPCS>;
+			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
 		clock-names = "stmmaceth", "mac_clk_rx",
 			      "mac_clk_tx", "clk_mac_refout",
 			      "aclk_mac", "pclk_mac",
-			      "clk_mac_speed", "ptp_ref",
-			      "pclk_xpcs";
+			      "clk_mac_speed", "ptp_ref";
 		resets = <&cru SRST_A_GMAC0>;
 		reset-names = "stmmaceth";
 		rockchip,grf = <&grf>;
-- 
2.25.1



From linux at fw-web.de  Sun Jan 16 04:49:11 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 16 Jan 2022 13:49:11 +0100
Subject: [PATCH v1 3/3] dts64: rockchip: Add Bananapi R2 Pro
In-Reply-To: <20220116124911.65203-1-linux@fw-web.de>
References: <20220116124911.65203-1-linux@fw-web.de>
Message-ID: <20220116124911.65203-4-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This patch add rk3568-bpi-r2-pro.dts for Bananapi R2 Pro based on RK3568.
Add uart/emmc/i2c/rk809/tsadc node for basic function.
Gmac0 is directly connected to wan-port so usable without additional
driver.
On gmac1 there is a switch (rtl8367rb) is connected which have not yet a
driver in mainline. A DSA driver for it is about to be merged.

Patch also prepares nodes for GPIO header.

Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-bpi-r2-pro.dts   | 428 ++++++++++++++++++
 2 files changed, 429 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3ad7b..70007b370d87 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -58,3 +58,4 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
new file mode 100644
index 000000000000..3455980dd393
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Author: Frank Wunderlich <frank-w at public-files.de>
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "Bananapi-R2 Pro (RK3568) DDR4 V00 Board";
+	compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
+
+	aliases {
+		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
+		mmc0 = &sdmmc0;
+		mmc1 = &sdhci;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial2:1500000n8";
+		bootargs = "earlycon=uart8250,mmio32,0xfe660000";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		led-green {
+			label = "gpio-green";
+			gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+
+		led-blue {
+			label = "gpio-blue";
+			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+		};
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_sys: vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+	clock_in_out = "input";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+
+	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	/* Reset time is 20ms, 100ms for rtl8211f */
+	snps,reset-delays-us = <0 20000 100000>;
+
+	tx_delay = <0x3c>;
+	rx_delay = <0x2f>;
+
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&i2c5 {
+	/* pin 3 + 4 of header con2 */
+	status = "disabled";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+	};
+};
+
+&pinctrl {
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_3v3>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&pwm10 {
+	/* pin 7 of header con2 */
+	status = "disabled";
+};
+
+&pwm11 {
+	/* pin 15 of header con2 */
+	status = "disabled";
+};
+
+&pwm12 {
+	/* pin 21 of header con2 */
+	status = "disabled";
+};
+
+&pwm13 {
+	/* pin 24 of header con2 */
+	status = "disabled";
+};
+
+&pwm14 {
+	/* pin 23 of header con2 */
+	status = "disabled";
+};
+
+&pwm15 {
+	/* pin 19 of header con2 */
+	status = "disabled";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&spi3 {
+	/* pin 19 + 21 + 23 of header con2 */
+	status = "disabled";
+};
+
+&tsadc {
+	status = "okay";
+};
+
+&uart0 {
+	/* pin 8 + 10 (RTS:16, CTS: 18) of header con2 */
+	status = "disabled";
+};
+
+&uart2 {
+	/* debug-uart */
+	status = "okay";
+};
+
+&uart7 {
+	/* pin 11 + 13 of header con2 */
+	status = "disabled";
+};
+
+&uart9 {
+	/* pin 21 + 24 of header con2 */
+	status = "disabled";
+};
-- 
2.25.1



From bhe at redhat.com  Sun Jan 16 05:38:47 2022
From: bhe at redhat.com (Baoquan He)
Date: Sun, 16 Jan 2022 21:38:47 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <20211206160514.2000-1-jszhang@kernel.org>
References: <20211206160514.2000-1-jszhang@kernel.org>
Message-ID: <20220116133847.GE2388@MiWiFi-R3L-srv>

Hi Jisheng,

On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> and increase compile coverage.

I go through this patchset, You mention the benefits it brings are
1) simplity the code;
2) increase compile coverage;

For benefit 1), it mainly removes the dummy function in x86, arm and
arm64, right?

For benefit 2), increasing compile coverage, could you tell more how it
achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
purpose? Please forgive my poor compiling knowledge.

Thanks
Baoquan



From wellslutw at gmail.com  Sun Jan 16 06:52:12 2022
From: wellslutw at gmail.com (Wells Lu)
Date: Sun, 16 Jan 2022 22:52:12 +0800
Subject: [PATCH v6 0/2] This is a patch series for pinctrl driver of Sunplus
 SP7021 SoC.
Message-ID: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>

Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates
many peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and
etc.) into a single chip. It is designed for industrial control
applications.

Refer to:
https://sunplus.atlassian.net/wiki/spaces/doc/overview
https://tibbo.com/store/plus1.html

Wells Lu (2):
  dt-bindings: pinctrl: Add dt-bindings for Sunplus SP7021
  pinctrl: Add driver for Sunplus SP7021

 .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   |  374 +++++++
 MAINTAINERS                                        |   10 +
 drivers/pinctrl/Kconfig                            |    1 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/sunplus/Kconfig                    |   22 +
 drivers/pinctrl/sunplus/Makefile                   |    6 +
 drivers/pinctrl/sunplus/sppctl.c                   | 1118 ++++++++++++++++++++
 drivers/pinctrl/sunplus/sppctl.h                   |  170 +++
 drivers/pinctrl/sunplus/sppctl_sp7021.c            |  583 ++++++++++
 include/dt-bindings/pinctrl/sppctl-sp7021.h        |  179 ++++
 include/dt-bindings/pinctrl/sppctl.h               |   31 +
 11 files changed, 2495 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
 create mode 100644 drivers/pinctrl/sunplus/Kconfig
 create mode 100644 drivers/pinctrl/sunplus/Makefile
 create mode 100644 drivers/pinctrl/sunplus/sppctl.c
 create mode 100644 drivers/pinctrl/sunplus/sppctl.h
 create mode 100644 drivers/pinctrl/sunplus/sppctl_sp7021.c
 create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
 create mode 100644 include/dt-bindings/pinctrl/sppctl.h

-- 
2.7.4



From wellslutw at gmail.com  Sun Jan 16 06:52:13 2022
From: wellslutw at gmail.com (Wells Lu)
Date: Sun, 16 Jan 2022 22:52:13 +0800
Subject: [PATCH v6 1/2] dt-bindings: pinctrl: Add dt-bindings for Sunplus
 SP7021
In-Reply-To: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
References: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
Message-ID: <1642344734-27229-2-git-send-email-wellslutw@gmail.com>

Add dt-bindings header files and documentation for Sunplus SP7021 SoC.

Signed-off-by: Wells Lu <wellslutw at gmail.com>
---
Changes in V6
  - Addressed comments of Mr. Rob Herring.
    - Added $ref: "pinmux-node.yaml#" for patternProperties '-pins$'.
    - Changed name of vendor property: sunplus,zero_func --> sunplus,zerofunc
  - Fixed wrong comment style of multi-line in dt-binding header files.

 .../bindings/pinctrl/sunplus,sp7021-pinctrl.yaml   | 374 +++++++++++++++++++++
 MAINTAINERS                                        |   9 +
 include/dt-bindings/pinctrl/sppctl-sp7021.h        | 179 ++++++++++
 include/dt-bindings/pinctrl/sppctl.h               |  31 ++
 4 files changed, 593 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
 create mode 100644 include/dt-bindings/pinctrl/sppctl-sp7021.h
 create mode 100644 include/dt-bindings/pinctrl/sppctl.h

diff --git a/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
new file mode 100644
index 0000000..d8e75b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/sunplus,sp7021-pinctrl.yaml
@@ -0,0 +1,374 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/sunplus,sp7021-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 Pin Controller Device Tree Bindings
+
+maintainers:
+  - Dvorkin Dmitry <dvorkin at tibbo.com>
+  - Wells Lu <wellslutw at gmail.com>
+
+description: |
+  The Sunplus SP7021 pin controller is used to control SoC pins. Please
+  refer to pinctrl-bindings.txt in this directory for details of the common
+  pinctrl bindings used by client devices.
+
+  SP7021 has 99 digital GPIO pins which are numbered from GPIO 0 to 98. All
+  are multiplexed with some special function pins. SP7021 has 3 types of
+  special function pins:
+
+  (1) function-group pins:
+      Ex 1 (SPI-NOR flash):
+        If control-field SPI_FLASH_SEL is set to 1, GPIO 83, 84, 86 and 87
+        will be pins of SPI-NOR flash. If it is set to 2, GPIO 76, 78, 79
+        and 81 will be pins of SPI-NOR flash.
+
+      Ex 2 (UART_0):
+        If control-bit UA0_SEL is set to 1, GPIO 88 and 89 will be TX and
+        RX pins of UART_0 (UART channel 0).
+
+      Ex 3 (eMMC):
+        If control-bit EMMC_SEL is set to 1, GPIO 72, 73, 74, 75, 76, 77,
+        78, 79, 80, 81 will be pins of an eMMC device.
+
+      Properties "function" and "groups" are used to select function-group
+      pins.
+
+  (2) fully pin-mux (like phone exchange mux) pins:
+      GPIO 8 to 71 are 'fully pin-mux' pins. Any pins of peripherals of
+      SP7021 (ex: UART_1, UART_2, UART_3, UART_4, I2C_0, I2C_1, and etc.)
+      can be routed to any pins of fully pin-mux pins.
+
+      Ex 1 (UART channel 1):
+        If control-field UA1_TX_SEL is set to 3, TX pin of UART_1 will be
+        routed to GPIO 10 (3 - 1 + 8 = 10).
+        If control-field UA1_RX_SEL is set to 4, RX pin of UART_1 will be
+        routed to GPIO 11 (4 - 1 + 8 = 11).
+        If control-field UA1_RTS_SEL is set to 5, RTS pin of UART_1 will
+        be routed to GPIO 12 (5 - 1 + 8 = 12).
+        If control-field UA1_CTS_SEL is set to 6, CTS pin of UART_1 will
+        be routed to GPIO 13 (6 - 1 + 8 = 13).
+
+      Ex 2 (I2C channel 0):
+        If control-field I2C0_CLK_SEL is set to 20, CLK pin of I2C_0 will
+        be routed to GPIO 27 (20 - 1 + 8 = 27).
+        If control-field I2C0_DATA_SEL is set to 21, DATA pin of I2C_0
+        will be routed to GPIO 28 (21 - 1 + 9 = 28).
+
+      Totally, SP7021 has 120 peripheral pins. The peripheral pins can be
+      routed to any of 64 'fully pin-mux' pins.
+
+  (3) I/O processor pins
+      SP7021 has a built-in I/O processor.
+      Any GPIO pins (GPIO 0 to 98) can be set to pins of I/O processor.
+
+  Vendor property "sunplus,pins" is used to select "fully pin-mux" pins,
+  "I/O processor pins" and "digital GPIO" pins.
+
+  The device node of pin controller of Sunplus SP7021 has following
+  properties.
+
+properties:
+  compatible:
+    const: sunplus,sp7021-pctl
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    const: 2
+
+  reg:
+    items:
+      - description: the MOON2 registers
+      - description: the GPIOXT registers
+      - description: the FIRST registers
+      - description: the MOON1 registers
+
+  reg-names:
+    items:
+      - const: moon2
+      - const: gpioxt
+      - const: first
+      - const: moon1
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+patternProperties:
+  '-pins$':
+    type: object
+    description: |
+      A pinctrl node should contain at least one subnodes representing the
+      pins or function-pins group available on the machine. Each subnode
+      will list the pins it needs, and how they should be configured.
+
+      Pinctrl node's client devices use subnodes for desired pin
+      configuration. Client device subnodes use below standard properties.
+    $ref: pinmux-node.yaml#
+
+    properties:
+      sunplus,pins:
+        description: |
+          Define 'sunplus,pins' which are used by pinctrl node's client
+          device.
+
+          It consists of one or more integers which represents the config
+          setting for corresponding pin. Each integer defines a individual
+          pin in which:
+
+          Bit 32~24: defines GPIO number. Its range is 0 ~ 98.
+          Bit 23~16: defines types: (1) fully pin-mux pins
+                                    (2) IO processor pins
+                                    (3) digital GPIO pins
+          Bit 15~8:  defines pins of peripherals (which are defined in
+                     'include/dt-binging/pinctrl/sppctl.h').
+          Bit 7~0:   defines types or initial-state of digital GPIO pins.
+
+          Please use macro SPPCTL_IOPAD to define the integers for pins.
+
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+
+      function:
+        description: |
+          Define pin-function which is used by pinctrl node's client device.
+          The name should be one of string in the following enumeration.
+        $ref: "/schemas/types.yaml#/definitions/string"
+        enum: [ SPI_FLASH, SPI_FLASH_4BIT, SPI_NAND, CARD0_EMMC, SD_CARD,
+                UA0, FPGA_IFX, HDMI_TX, LCDIF, USB0_OTG, USB1_OTG ]
+
+      groups:
+        description: |
+          Define pin-group in a specified pin-function.
+          The name should be one of string in the following enumeration.
+        $ref: "/schemas/types.yaml#/definitions/string"
+        enum: [ SPI_FLASH1, SPI_FLASH2, SPI_FLASH_4BIT1, SPI_FLASH_4BIT2,
+                SPI_NAND, CARD0_EMMC, SD_CARD, UA0, FPGA_IFX, HDMI_TX1,
+                HDMI_TX2, HDMI_TX3, LCDIF, USB0_OTG, USB1_OTG ]
+
+      sunplus,zerofunc:
+        description: |
+          This is a vendor specific property. It is used to disable pins
+          which are not used by pinctrl node's client device.
+          Some pins may be enabled by boot-loader. We can use this
+          property to disable them.
+        $ref: /schemas/types.yaml#/definitions/uint32-array
+
+    additionalProperties: false
+
+    allOf:
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_FLASH
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_FLASH1
+                - SPI_FLASH2
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_FLASH_4BIT
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_FLASH_4BIT1
+                - SPI_FLASH_4BIT2
+      - if:
+          properties:
+            function:
+              enum:
+                - SPI_NAND
+        then:
+          properties:
+            groups:
+              enum:
+                - SPI_NAND
+      - if:
+          properties:
+            function:
+              enum:
+                - CARD0_EMMC
+        then:
+          properties:
+            groups:
+              enum:
+                - CARD0_EMMC
+      - if:
+          properties:
+            function:
+              enum:
+                - SD_CARD
+        then:
+          properties:
+            groups:
+              enum:
+                - SD_CARD
+      - if:
+          properties:
+            function:
+              enum:
+                - UA0
+        then:
+          properties:
+            groups:
+              enum:
+                - UA0
+      - if:
+          properties:
+            function:
+              enum:
+                - FPGA_IFX
+        then:
+          properties:
+            groups:
+              enum:
+                - FPGA_IFX
+      - if:
+          properties:
+            function:
+              enum:
+                - HDMI_TX
+        then:
+          properties:
+            groups:
+              enum:
+                - HDMI_TX1
+                - HDMI_TX2
+                - HDMI_TX3
+      - if:
+          properties:
+            function:
+              enum:
+                - LCDIF
+        then:
+          properties:
+            groups:
+              enum:
+                - LCDIF
+      - if:
+          properties:
+            function:
+              enum:
+                - USB0_OTG
+        then:
+          properties:
+            groups:
+              enum:
+                - USB0_OTG
+      - if:
+          properties:
+            function:
+              enum:
+                - USB1_OTG
+        then:
+          properties:
+            groups:
+              enum:
+                - USB1_OTG
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#gpio-cells"
+  - gpio-controller
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/sppctl-sp7021.h>
+
+    pinctl at 9c000100 {
+        compatible = "sunplus,sp7021-pctl";
+        reg = <0x9c000100 0x100>, <0x9c000300 0x100>,
+              <0x9c0032e4 0x1c>, <0x9c000080 0x20>;
+        reg-names = "moon2", "gpioxt", "first", "moon1";
+        gpio-controller;
+        #gpio-cells = <2>;
+        clocks = <&clkc 0x83>;
+        resets = <&rstc 0x73>;
+
+        uart0-pins {
+            function = "UA0";
+            groups = "UA0";
+        };
+
+        spinand0-pins {
+            function = "SPI_NAND";
+            groups = "SPI_NAND";
+        };
+
+        uart1-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(11, SPPCTL_PCTL_G_PMUX, MUXF_UA1_TX, 0)
+                SPPCTL_IOPAD(10, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RX, 0)
+            >;
+        };
+
+        uart2-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(20, SPPCTL_PCTL_G_PMUX, MUXF_UA1_TX, 0)
+                SPPCTL_IOPAD(21, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RX, 0)
+                SPPCTL_IOPAD(22, SPPCTL_PCTL_G_PMUX, MUXF_UA1_RTS, 0)
+                SPPCTL_IOPAD(23, SPPCTL_PCTL_G_PMUX, MUXF_UA1_CTS, 0)
+            >;
+        };
+
+        emmc-pins {
+            function = "CARD0_EMMC";
+            groups = "CARD0_EMMC";
+        };
+
+        sdcard-pins {
+            function = "SD_CARD";
+            groups = "SD_CARD";
+            sunplus,pins = < SPPCTL_IOPAD(91, SPPCTL_PCTL_G_GPIO, 0, 0) >;
+        };
+
+        hdmi_A_tx1-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX1";
+        };
+        hdmi_A_tx2-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX2";
+        };
+        hdmi_A_tx3-pins {
+            function = "HDMI_TX";
+            groups = "HDMI_TX3";
+        };
+
+        ethernet-pins {
+            sunplus,pins = <
+                SPPCTL_IOPAD(49,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_CLK_OUT,0)
+                SPPCTL_IOPAD(44,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDC,0)
+                SPPCTL_IOPAD(43,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_MAC_SMI_MDIO,0)
+                SPPCTL_IOPAD(52,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXEN,0)
+                SPPCTL_IOPAD(50,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD0,0)
+                SPPCTL_IOPAD(51,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_TXD1,0)
+                SPPCTL_IOPAD(46,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_CRSDV,0)
+                SPPCTL_IOPAD(47,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD0,0)
+                SPPCTL_IOPAD(48,SPPCTL_PCTL_G_PMUX,MUXF_L2SW_P0_MAC_RMII_RXD1,0)
+            >;
+            sunplus,zerofunc = <
+                MUXF_L2SW_LED_FLASH0
+                MUXF_L2SW_LED_ON0
+                MUXF_L2SW_P0_MAC_RMII_RXER
+            >;
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index fbc29cd..3aef4ce 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15308,6 +15308,15 @@ M:	Lakshmi Sowjanya D <lakshmi.sowjanya.d at intel.com>
 S:	Supported
 F:	drivers/pinctrl/pinctrl-thunderbay.c
 
+PIN CONTROLLER - SUNPLUS / TIBBO
+M:	Dvorkin Dmitry <dvorkin at tibbo.com>
+M:	Wells Lu <wellslutw at gmail.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+W:	https://sunplus.atlassian.net/wiki/spaces/doc/overview
+F:	Documentation/devicetree/bindings/pinctrl/sunplus,*
+F:	include/dt-bindings/pinctrl/sppctl*.h
+
 PKTCDVD DRIVER
 M:	linux-block at vger.kernel.org
 S:	Orphan
diff --git a/include/dt-bindings/pinctrl/sppctl-sp7021.h b/include/dt-bindings/pinctrl/sppctl-sp7021.h
new file mode 100644
index 0000000..629aa9b
--- /dev/null
+++ b/include/dt-bindings/pinctrl/sppctl-sp7021.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Sunplus SP7021 dt-bindings Pinctrl header file
+ * Copyright (C) Sunplus Tech/Tibbo Tech.
+ * Author: Dvorkin Dmitry <dvorkin at tibbo.com>
+ */
+
+#ifndef	__DT_BINDINGS_PINCTRL_SPPCTL_SP7021_H__
+#define	__DT_BINDINGS_PINCTRL_SPPCTL_SP7021_H__
+
+#include <dt-bindings/pinctrl/sppctl.h>
+
+/*
+ * Please don't change the order of the following defines.
+ * They are based on order of 'hardware' control register
+ * defined in MOON2 ~ MOON3 registers.
+ */
+#define MUXF_GPIO                       0
+#define MUXF_IOP                        1
+#define MUXF_L2SW_CLK_OUT               2
+#define MUXF_L2SW_MAC_SMI_MDC           3
+#define MUXF_L2SW_LED_FLASH0            4
+#define MUXF_L2SW_LED_FLASH1            5
+#define MUXF_L2SW_LED_ON0               6
+#define MUXF_L2SW_LED_ON1               7
+#define MUXF_L2SW_MAC_SMI_MDIO          8
+#define MUXF_L2SW_P0_MAC_RMII_TXEN      9
+#define MUXF_L2SW_P0_MAC_RMII_TXD0      10
+#define MUXF_L2SW_P0_MAC_RMII_TXD1      11
+#define MUXF_L2SW_P0_MAC_RMII_CRSDV     12
+#define MUXF_L2SW_P0_MAC_RMII_RXD0      13
+#define MUXF_L2SW_P0_MAC_RMII_RXD1      14
+#define MUXF_L2SW_P0_MAC_RMII_RXER      15
+#define MUXF_L2SW_P1_MAC_RMII_TXEN      16
+#define MUXF_L2SW_P1_MAC_RMII_TXD0      17
+#define MUXF_L2SW_P1_MAC_RMII_TXD1      18
+#define MUXF_L2SW_P1_MAC_RMII_CRSDV     19
+#define MUXF_L2SW_P1_MAC_RMII_RXD0      20
+#define MUXF_L2SW_P1_MAC_RMII_RXD1      21
+#define MUXF_L2SW_P1_MAC_RMII_RXER      22
+#define MUXF_DAISY_MODE                 23
+#define MUXF_SDIO_CLK                   24
+#define MUXF_SDIO_CMD                   25
+#define MUXF_SDIO_D0                    26
+#define MUXF_SDIO_D1                    27
+#define MUXF_SDIO_D2                    28
+#define MUXF_SDIO_D3                    29
+#define MUXF_PWM0                       30
+#define MUXF_PWM1                       31
+#define MUXF_PWM2                       32
+#define MUXF_PWM3                       33
+#define MUXF_PWM4                       34
+#define MUXF_PWM5                       35
+#define MUXF_PWM6                       36
+#define MUXF_PWM7                       37
+#define MUXF_ICM0_D                     38
+#define MUXF_ICM1_D                     39
+#define MUXF_ICM2_D                     40
+#define MUXF_ICM3_D                     41
+#define MUXF_ICM0_CLK                   42
+#define MUXF_ICM1_CLK                   43
+#define MUXF_ICM2_CLK                   44
+#define MUXF_ICM3_CLK                   45
+#define MUXF_SPIM0_INT                  46
+#define MUXF_SPIM0_CLK                  47
+#define MUXF_SPIM0_EN                   48
+#define MUXF_SPIM0_DO                   49
+#define MUXF_SPIM0_DI                   50
+#define MUXF_SPIM1_INT                  51
+#define MUXF_SPIM1_CLK                  52
+#define MUXF_SPIM1_EN                   53
+#define MUXF_SPIM1_DO                   54
+#define MUXF_SPIM1_DI                   55
+#define MUXF_SPIM2_INT                  56
+#define MUXF_SPIM2_CLK                  57
+#define MUXF_SPIM2_EN                   58
+#define MUXF_SPIM2_DO                   59
+#define MUXF_SPIM2_DI                   60
+#define MUXF_SPIM3_INT                  61
+#define MUXF_SPIM3_CLK                  62
+#define MUXF_SPIM3_EN                   63
+#define MUXF_SPIM3_DO                   64
+#define MUXF_SPIM3_DI                   65
+#define MUXF_SPI0S_INT                  66
+#define MUXF_SPI0S_CLK                  67
+#define MUXF_SPI0S_EN                   68
+#define MUXF_SPI0S_DO                   69
+#define MUXF_SPI0S_DI                   70
+#define MUXF_SPI1S_INT                  71
+#define MUXF_SPI1S_CLK                  72
+#define MUXF_SPI1S_EN                   73
+#define MUXF_SPI1S_DO                   74
+#define MUXF_SPI1S_DI                   75
+#define MUXF_SPI2S_INT                  76
+#define MUXF_SPI2S_CLK                  77
+#define MUXF_SPI2S_EN                   78
+#define MUXF_SPI2S_DO                   79
+#define MUXF_SPI2S_DI                   80
+#define MUXF_SPI3S_INT                  81
+#define MUXF_SPI3S_CLK                  82
+#define MUXF_SPI3S_EN                   83
+#define MUXF_SPI3S_DO                   84
+#define MUXF_SPI3S_DI                   85
+#define MUXF_I2CM0_CLK                  86
+#define MUXF_I2CM0_DAT                  87
+#define MUXF_I2CM1_CLK                  88
+#define MUXF_I2CM1_DAT                  89
+#define MUXF_I2CM2_CLK                  90
+#define MUXF_I2CM2_DAT                  91
+#define MUXF_I2CM3_CLK                  92
+#define MUXF_I2CM3_DAT                  93
+#define MUXF_UA1_TX                     94
+#define MUXF_UA1_RX                     95
+#define MUXF_UA1_CTS                    96
+#define MUXF_UA1_RTS                    97
+#define MUXF_UA2_TX                     98
+#define MUXF_UA2_RX                     99
+#define MUXF_UA2_CTS                    100
+#define MUXF_UA2_RTS                    101
+#define MUXF_UA3_TX                     102
+#define MUXF_UA3_RX                     103
+#define MUXF_UA3_CTS                    104
+#define MUXF_UA3_RTS                    105
+#define MUXF_UA4_TX                     106
+#define MUXF_UA4_RX                     107
+#define MUXF_UA4_CTS                    108
+#define MUXF_UA4_RTS                    109
+#define MUXF_TIMER0_INT                 110
+#define MUXF_TIMER1_INT                 111
+#define MUXF_TIMER2_INT                 112
+#define MUXF_TIMER3_INT                 113
+#define MUXF_GPIO_INT0                  114
+#define MUXF_GPIO_INT1                  115
+#define MUXF_GPIO_INT2                  116
+#define MUXF_GPIO_INT3                  117
+#define MUXF_GPIO_INT4                  118
+#define MUXF_GPIO_INT5                  119
+#define MUXF_GPIO_INT6                  120
+#define MUXF_GPIO_INT7                  121
+
+/*
+ * Please don't change the order of the following defines.
+ * They are based on order of items in array 'sppctl_list_funcs'
+ * in Sunplus pinctrl driver.
+ */
+#define GROP_SPI_FLASH                  122
+#define GROP_SPI_FLASH_4BIT             123
+#define GROP_SPI_NAND                   124
+#define GROP_CARD0_EMMC                 125
+#define GROP_SD_CARD                    126
+#define GROP_UA0                        127
+#define GROP_ACHIP_DEBUG                128
+#define GROP_ACHIP_UA2AXI               129
+#define GROP_FPGA_IFX                   130
+#define GROP_HDMI_TX                    131
+#define GROP_AUD_EXT_ADC_IFX0           132
+#define GROP_AUD_EXT_DAC_IFX0           133
+#define GROP_SPDIF_RX                   134
+#define GROP_SPDIF_TX                   135
+#define GROP_TDMTX_IFX0                 136
+#define GROP_TDMRX_IFX0                 137
+#define GROP_PDMRX_IFX0                 138
+#define GROP_PCM_IEC_TX                 139
+#define GROP_LCDIF                      140
+#define GROP_DVD_DSP_DEBUG              141
+#define GROP_I2C_DEBUG                  142
+#define GROP_I2C_SLAVE                  143
+#define GROP_WAKEUP                     144
+#define GROP_UART2AXI                   145
+#define GROP_USB0_I2C                   146
+#define GROP_USB1_I2C                   147
+#define GROP_USB0_OTG                   148
+#define GROP_USB1_OTG                   149
+#define GROP_UPHY0_DEBUG                150
+#define GROP_UPHY1_DEBUG                151
+#define GROP_UPHY0_EXT                  152
+#define GROP_PROBE_PORT                 153
+
+#endif
diff --git a/include/dt-bindings/pinctrl/sppctl.h b/include/dt-bindings/pinctrl/sppctl.h
new file mode 100644
index 0000000..5055726
--- /dev/null
+++ b/include/dt-bindings/pinctrl/sppctl.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Sunplus dt-bindings Pinctrl header file
+ * Copyright (C) Sunplus Tech / Tibbo Tech.
+ * Author: Dvorkin Dmitry <dvorkin at tibbo.com>
+ */
+
+#ifndef __DT_BINDINGS_PINCTRL_SPPCTL_H__
+#define __DT_BINDINGS_PINCTRL_SPPCTL_H__
+
+#define IOP_G_MASTE		(0x01 << 0)
+#define IOP_G_FIRST		(0x01 << 1)
+
+#define SPPCTL_PCTL_G_PMUX	(0x00        | IOP_G_MASTE)
+#define SPPCTL_PCTL_G_GPIO	(IOP_G_FIRST | IOP_G_MASTE)
+#define SPPCTL_PCTL_G_IOPP	(IOP_G_FIRST | 0x00)
+
+#define SPPCTL_PCTL_L_OUT	(0x01 << 0)	/* Output LOW        */
+#define SPPCTL_PCTL_L_OU1	(0x01 << 1)	/* Output HIGH       */
+#define SPPCTL_PCTL_L_INV	(0x01 << 2)	/* Input Invert      */
+#define SPPCTL_PCTL_L_ONV	(0x01 << 3)	/* Output Invert     */
+#define SPPCTL_PCTL_L_ODR	(0x01 << 4)	/* Output Open Drain */
+
+/*
+ * pack into 32-bit value:
+ * pin# (8bit), typ (8bit), function (8bit), flag (8bit)
+ */
+#define SPPCTL_IOPAD(pin, typ, fun, flg)	(((pin) << 24) | ((typ) << 16) | \
+						((fun) << 8) | (flg))
+
+#endif
-- 
2.7.4



From wellslutw at gmail.com  Sun Jan 16 06:52:14 2022
From: wellslutw at gmail.com (Wells Lu)
Date: Sun, 16 Jan 2022 22:52:14 +0800
Subject: [PATCH v6 2/2] pinctrl: Add driver for Sunplus SP7021
In-Reply-To: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
References: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
Message-ID: <1642344734-27229-3-git-send-email-wellslutw@gmail.com>

Add driver for Sunplus SP7021 SoC.

Signed-off-by: Wells Lu <wellslutw at gmail.com>
---
Changes in V6
  - Addressed comments of Mr. Rob Herring.
    - Changed name of vendor property: sunplus,zero_func --> sunplus,zerofunc
  - Addedssed comments of Mr. Andy Shevchenko
    - Modified Kconfig (bool -> tristate) and Makefile to support 'compile as module'.
    - Re-ordered some header files.
    - Removed some useless comments.
    - Added some inline functions to simplify coding.
    - Removed checking existing of property "gpio-controller".
    - Removed redundant 'check_mul_overflow()' after a devm_kcalloc() function.
    - Added include <linux/types.h> in 'sppctl.h'
    - Modified and added some kernel-doc comments.
    - Fixed some wrong comment style of multi-line.
    - Moved struct sppctl_gpio_chip { ... }; to 'sppctl.c'.
    - Others

 MAINTAINERS                             |    1 +
 drivers/pinctrl/Kconfig                 |    1 +
 drivers/pinctrl/Makefile                |    1 +
 drivers/pinctrl/sunplus/Kconfig         |   22 +
 drivers/pinctrl/sunplus/Makefile        |    6 +
 drivers/pinctrl/sunplus/sppctl.c        | 1118 +++++++++++++++++++++++++++++++
 drivers/pinctrl/sunplus/sppctl.h        |  170 +++++
 drivers/pinctrl/sunplus/sppctl_sp7021.c |  583 ++++++++++++++++
 8 files changed, 1902 insertions(+)
 create mode 100644 drivers/pinctrl/sunplus/Kconfig
 create mode 100644 drivers/pinctrl/sunplus/Makefile
 create mode 100644 drivers/pinctrl/sunplus/sppctl.c
 create mode 100644 drivers/pinctrl/sunplus/sppctl.h
 create mode 100644 drivers/pinctrl/sunplus/sppctl_sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 3aef4ce..9019cb2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15315,6 +15315,7 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 W:	https://sunplus.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/pinctrl/sunplus,*
+F:	drivers/pinctrl/sunplus/
 F:	include/dt-bindings/pinctrl/sppctl*.h
 
 PKTCDVD DRIVER
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 6fc56d6..f52960d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -527,6 +527,7 @@ source "drivers/pinctrl/samsung/Kconfig"
 source "drivers/pinctrl/spear/Kconfig"
 source "drivers/pinctrl/sprd/Kconfig"
 source "drivers/pinctrl/stm32/Kconfig"
+source "drivers/pinctrl/sunplus/Kconfig"
 source "drivers/pinctrl/sunxi/Kconfig"
 source "drivers/pinctrl/tegra/Kconfig"
 source "drivers/pinctrl/ti/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 08c364d..b09c534 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
 obj-$(CONFIG_PINCTRL_SPEAR)	+= spear/
 obj-y				+= sprd/
 obj-$(CONFIG_PINCTRL_STM32)	+= stm32/
+obj-y				+= sunplus/
 obj-$(CONFIG_PINCTRL_SUNXI)	+= sunxi/
 obj-$(CONFIG_ARCH_TEGRA)	+= tegra/
 obj-y				+= ti/
diff --git a/drivers/pinctrl/sunplus/Kconfig b/drivers/pinctrl/sunplus/Kconfig
new file mode 100644
index 0000000..4b5c47c
--- /dev/null
+++ b/drivers/pinctrl/sunplus/Kconfig
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Sunplus Pin control driver configuration
+#
+
+config PINCTRL_SPPCTL
+	tristate "Sunplus SP7021 PinMux and GPIO driver"
+	depends on SOC_SP7021
+	depends on OF && HAS_IOMEM
+	select GENERIC_PINCTRL_GROUPS
+	select GENERIC_PINMUX_FUNCTIONS
+	select GENERIC_PINCONF
+	select PINCONF
+	select PINMUX
+	select GPIOLIB
+	select OF_GPIO
+	help
+	  Say Y here to support Sunplus SP7021 pinmux controller.
+	  This driver requires the pinctrl framework.
+	  GPIO is provided by the same driver.
+	  To compile this driver as a module, choose M here.
+	  The module will be called sppinctrl.
diff --git a/drivers/pinctrl/sunplus/Makefile b/drivers/pinctrl/sunplus/Makefile
new file mode 100644
index 0000000..a26952c
--- /dev/null
+++ b/drivers/pinctrl/sunplus/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the Sunplus Pin control drivers.
+#
+obj-$(CONFIG_PINCTRL_SPPCTL) += sppinctrl.o
+sppinctrl-objs := sppctl.o sppctl_sp7021.o
diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c
new file mode 100644
index 0000000..3ba4704
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl.c
@@ -0,0 +1,1118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech / Tibbo Tech.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/overflow.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/pinctrl/pinmux.h>
+
+#include <dt-bindings/pinctrl/sppctl-sp7021.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+
+#include "sppctl.h"
+
+struct sppctl_gpio_chip {
+	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN, I_INV, O_INV, OD */
+	void __iomem *first_base;	/* GPIO_FIRST                            */
+
+	struct gpio_chip chip;
+	spinlock_t lock;		/* lock for accessing OE register        */
+};
+
+static inline u32 sppctl_first_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off);
+}
+
+static inline void sppctl_first_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off)
+{
+	writel(val, spp_gchip->first_base + SPPCTL_GPIO_OFF_FIRST + off);
+}
+
+static inline u32 sppctl_gpio_master_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off);
+}
+
+static inline void sppctl_gpio_master_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,
+					     u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_MASTER + off);
+}
+
+static inline u32 sppctl_gpio_oe_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off);
+}
+
+static inline void sppctl_gpio_oe_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OE + off);
+}
+
+static inline void sppctl_gpio_out_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OUT + off);
+}
+
+static inline u32 sppctl_gpio_in_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IN + off);
+}
+
+static inline u32 sppctl_gpio_iinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off);
+}
+
+static inline void sppctl_gpio_iinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,
+					   u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_IINV + off);
+}
+
+static inline u32 sppctl_gpio_oinv_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off);
+}
+
+static inline void sppctl_gpio_oinv_writel(struct sppctl_gpio_chip *spp_gchip, u32 val,
+					   u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OINV + off);
+}
+
+static inline u32 sppctl_gpio_od_readl(struct sppctl_gpio_chip *spp_gchip, u32 off)
+{
+	return readl(spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off);
+}
+
+static inline void sppctl_gpio_od_writel(struct sppctl_gpio_chip *spp_gchip, u32 val, u32 off)
+{
+	writel(val, spp_gchip->gpioxt_base + SPPCTL_GPIO_OFF_OD + off);
+}
+
+static inline u32 sppctl_get_reg_and_bit_offset(unsigned int offset, u32 *reg_off)
+{
+	u32 bit_off;
+
+	/* Each register has 32 bits. */
+	*reg_off = (offset / 32) * 4;
+	bit_off = offset % 32;
+
+	return bit_off;
+}
+
+static inline u32 sppctl_get_moon_reg_and_bit_offset(unsigned int offset, u32 *reg_off)
+{
+	u32 bit_off;
+
+	/*
+	 * Each MOON register has 32 bits. Upper 16-bit word are mask-fields.
+	 * The lower 16-bit word are the control-fields. The corresponding
+	 * bits in mask-field should be set then you can write something to
+	 * control-field.
+	 */
+	*reg_off = (offset / 16) * 4;
+	bit_off = offset % 16;
+
+	return bit_off;
+}
+
+static inline u32 sppctl_prep_moon_reg_and_offset(unsigned int offset, u32 *reg_off, int val)
+{
+	u32 bit_off;
+
+	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, reg_off);
+	if (val)
+		return SPPCTL_SET_MOON_REG_BIT(bit_off);
+	else
+		return SPPCTL_CLR_MOON_REG_BIT(bit_off);
+}
+
+/**
+ * sppctl_func_set() - Set pin of fully-pinmux function.
+ *
+ * Mask-fields and control-fields of fully-pinmux function of SP7021 are
+ * arranged as shown below:
+ *
+ *  func# | register |  mask-field  | control-field
+ * -------+----------+--------------+---------------
+ *    0   | base[0]  |  (22 : 16)   |   ( 6 : 0)
+ *    1   | base[0]  |  (30 : 24)   |   (14 : 8)
+ *    2   | base[1]  |  (22 : 16)   |   ( 6 : 0)
+ *    3   | baeg[1]  |  (30 : 24)   |   (14 : 8)
+ *    :   |    :     |      :       |       :
+ *
+ * where mask-fields are used to protect control-fields from write-in
+ * accidentally. Set the corresponding bits in the mask-field before
+ * you write a value into a control-field.
+ *
+ * Control-fields are used to set where the function pin is going to
+ * be routed to.
+ *
+ * Note that mask-fields and control-fields of even number of 'func'
+ * are located at bits (22:16) and (6:0), while odd number of 'func's
+ * are located at bits (30:24) and (14:8).
+ */
+static void sppctl_func_set(struct sppctl_pdata *pctl, u8 func, u8 val)
+{
+	u32 reg, offset;
+
+	/*
+	 * Note that upper 16-bit word are mask-fields and lower 16-bit
+	 * word are the control-fields. Set corresponding bits in mask-
+	 * field before write to a control-field.
+	 */
+	reg = SPPCTL_FULLY_PINMUX_MASK_MASK | val;
+
+	/*
+	 * MUXF_L2SW_CLK_OUT is the first fully-pinmux pin
+	 * and its register offset is 0.
+	 */
+	func -= MUXF_L2SW_CLK_OUT;
+
+	/*
+	 * Check if 'func' is an odd number or not. Mask and control-
+	 * fields of odd number 'func' is located at upper portion of
+	 * a register. Extra shift is needed.
+	 */
+	if (func & BIT(0))
+		reg <<= SPPCTL_FULLY_PINMUX_UPPER_SHIFT;
+
+	/* Convert func# to register offset w.r.t. base register. */
+	offset = func * 2;
+	offset &= GENMASK(31, 2);
+
+	writel(reg, pctl->moon2_base + offset);
+}
+
+/**
+ * sppctl_gmx_set() - Set pin of group-pinmux.
+ *
+ * Mask-fields and control-fields of group-pinmux function of SP7021 are
+ * arranged as shown below:
+ *
+ *  register |  mask-fields | control-fields
+ * ----------+--------------+----------------
+ *  base[0]  |  (31 : 16)   |   (15 : 0)
+ *  base[1]  |  (31 : 24)   |   (15 : 0)
+ *  base[2]  |  (31 : 24)   |   (15 : 0)
+ *     :     |      :       |       :
+ *
+ * where mask-fields are used to protect control-fields from write-in
+ * accidentally. Set the corresponding bits in the mask-field before
+ * you write a value into a control-field.
+ *
+ * Control-fields are used to set where the function pin is going to
+ * be routed to. A control-field consists of one or more bits.
+ */
+static void sppctl_gmx_set(struct sppctl_pdata *pctl, u8 reg_off, u8 bit_off, u8 bit_sz,
+			   u8 val)
+{
+	u32 mask, reg;
+
+	/*
+	 * Note that upper 16-bit word are mask-fields and lower 16-bit
+	 * word are the control-fields. Set corresponding bits in mask-
+	 * field before write to a control-field.
+	 */
+	mask = GENMASK(bit_sz - 1, 0) << SPPCTL_MOON_REG_MASK_SHIFT;
+	reg = (mask | val) << bit_off;
+
+	writel(reg, pctl->moon1_base + reg_off * 4);
+}
+
+/**
+ * sppctl_first_get() - get bit of FIRST register.
+ *
+ * There are 4 FIRST registers. Each has 32 control-bits.
+ * Totally, there are 4 * 32 = 128 control-bits.
+ * Control-bits are arranged as shown below:
+ *
+ *  registers | control-bits
+ * -----------+--------------
+ *  first[0]  |  (31 :  0)
+ *  first[1]  |  (63 : 32)
+ *  first[2]  |  (95 : 64)
+ *  first[3]  | (127 : 96)
+ *
+ * Each control-bit sets type of a GPIO pin.
+ *   0: a fully-pinmux pin
+ *   1: a GPIO or IOP pin
+ */
+static int sppctl_first_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);
+	reg = sppctl_first_readl(spp_gchip, reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+/**
+ * sppctl_master_get() - get bit of MASTER register.
+ *
+ * There are 8 MASTER registers. Each has 16 mask-bits and 16 control-bits.
+ * Upper 16-bit of MASTER registers are mask-bits while lower 16-bit are
+ * control-bits. Totally, there are 128 mask-bits and 128 control-bits.
+ * They are arranged as shown below:
+ *
+ *  register  |  mask-bits  | control-bits
+ * -----------+-------------+--------------
+ *  master[0] |  (15 :   0) |  (15 :   0)
+ *  master[1] |  (31 :  16) |  (31 :  16)
+ *  master[2] |  (47 :  32) |  (47 :  32)
+ *     :      |      :      |      :
+ *  master[7] | (127 : 112) | (127 : 112)
+ *
+ * where mask-bits are used to protect control-bits from write-in
+ * accidentally. Set the corresponding mask-bit before you write
+ * a value into a control-bit.
+ *
+ * Each control-bit sets type of a GPIO pin when FIRST bit is 1.
+ *   0: a IOP pin
+ *   1: a GPIO pin
+ */
+static int sppctl_master_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);
+	reg = sppctl_gpio_master_readl(spp_gchip, reg_off);
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static void sppctl_first_master_set(struct gpio_chip *chip, unsigned int offset,
+				    enum mux_first_reg first, enum mux_master_reg master)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+	enum mux_first_reg val;
+
+	/* FIRST register */
+	if (first != mux_f_keep) {
+		bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);
+		reg = sppctl_first_readl(spp_gchip, reg_off);
+		val = (reg & BIT(bit_off)) ? mux_f_gpio : mux_f_mux;
+
+		if (first != val)
+			switch (first) {
+			case mux_f_gpio:
+				reg |= BIT(bit_off);
+				sppctl_first_writel(spp_gchip, reg, reg_off);
+				break;
+
+			case mux_f_mux:
+				reg &= ~BIT(bit_off);
+				sppctl_first_writel(spp_gchip, reg, reg_off);
+				break;
+
+			case mux_f_keep:
+				break;
+			}
+	}
+
+	/* MASTER register */
+	if (master != mux_m_keep) {
+		reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, (master == mux_m_gpio));
+		sppctl_gpio_master_writel(spp_gchip, reg, reg_off);
+	}
+}
+
+static void sppctl_gpio_input_inv_set(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);
+	sppctl_gpio_iinv_writel(spp_gchip, reg, reg_off);
+}
+
+static void sppctl_gpio_output_inv_set(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);
+	sppctl_gpio_oinv_writel(spp_gchip, reg, reg_off);
+}
+
+static int sppctl_gpio_output_od_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);
+	reg = sppctl_gpio_od_readl(spp_gchip, reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static void sppctl_gpio_output_od_set(struct gpio_chip *chip, unsigned int offset,
+				      unsigned int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);
+	sppctl_gpio_od_writel(spp_gchip, reg, reg_off);
+}
+
+static int sppctl_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);
+	reg = sppctl_gpio_oe_readl(spp_gchip, reg_off);
+
+	return (reg & BIT(bit_off)) ? 0 : 1;
+}
+
+static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+	unsigned long flags;
+
+	bit_off = sppctl_get_moon_reg_and_bit_offset(offset, &reg_off);
+
+	spin_lock_irqsave(&spp_gchip->lock, flags);
+
+	if (sppctl_gpio_get_direction(chip, offset))
+		reg = sppctl_gpio_iinv_readl(spp_gchip, reg_off);
+	else
+		reg = sppctl_gpio_oinv_readl(spp_gchip, reg_off);
+
+	spin_unlock_irqrestore(&spp_gchip->lock, flags);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static int sppctl_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	unsigned long flags;
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 0);
+
+	spin_lock_irqsave(&spp_gchip->lock, flags);
+
+	sppctl_gpio_oe_writel(spp_gchip, reg, reg_off);
+
+	spin_unlock_irqrestore(&spp_gchip->lock, flags);
+	return 0;
+}
+
+static int sppctl_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	unsigned long flags;
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);
+
+	spin_lock_irqsave(&spp_gchip->lock, flags);
+
+	sppctl_gpio_oe_writel(spp_gchip, reg, reg_off);
+
+	if (val < 0) {
+		spin_unlock_irqrestore(&spp_gchip->lock, flags);
+		return 0;
+	}
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);
+	sppctl_gpio_out_writel(spp_gchip, reg, reg_off);
+
+	spin_unlock_irqrestore(&spp_gchip->lock, flags);
+	return 0;
+}
+
+static int sppctl_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, bit_off, reg;
+
+	bit_off = sppctl_get_reg_and_bit_offset(offset, &reg_off);
+	reg = sppctl_gpio_in_readl(spp_gchip, reg_off);
+
+	return (reg & BIT(bit_off)) ? 1 : 0;
+}
+
+static void sppctl_gpio_set(struct gpio_chip *chip, unsigned int offset, int val)
+{
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, reg;
+
+	reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, val);
+	sppctl_gpio_out_writel(spp_gchip, reg, reg_off);
+}
+
+static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+				  unsigned long config)
+{
+	enum pin_config_param param = pinconf_to_config_param(config);
+	struct sppctl_gpio_chip *spp_gchip = gpiochip_get_data(chip);
+	u32 reg_off, reg;
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		reg = sppctl_prep_moon_reg_and_offset(offset, &reg_off, 1);
+		sppctl_gpio_od_writel(spp_gchip, reg, reg_off);
+		break;
+
+	case PIN_CONFIG_INPUT_ENABLE:
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		return sppctl_gpio_direction_output(chip, offset, 0);
+
+	case PIN_CONFIG_PERSIST_STATE:
+		return -ENOTSUPP;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	const char *label;
+	int i;
+
+	for (i = 0; i < chip->ngpio; i++) {
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			label = "";
+
+		seq_printf(s, " gpio-%03d (%-16.16s | %-16.16s)", i + chip->base,
+			   chip->names[i], label);
+		seq_printf(s, " %c", sppctl_gpio_get_direction(chip, i) ? 'I' : 'O');
+		seq_printf(s, ":%d", sppctl_gpio_get(chip, i));
+		seq_printf(s, " %s", sppctl_first_get(chip, i) ? "gpi" : "mux");
+		seq_printf(s, " %s", sppctl_master_get(chip, i) ? "gpi" : "iop");
+		seq_printf(s, " %s", sppctl_gpio_inv_get(chip, i) ? "inv" : "   ");
+		seq_printf(s, " %s", sppctl_gpio_output_od_get(chip, i) ? "oDr" : "");
+		seq_puts(s, "\n");
+	}
+}
+#endif
+
+static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pctl)
+{
+	struct sppctl_gpio_chip *spp_gchip;
+	struct gpio_chip *gchip;
+	int err;
+
+	spp_gchip = devm_kzalloc(&pdev->dev, sizeof(*spp_gchip), GFP_KERNEL);
+	if (!spp_gchip)
+		return -ENOMEM;
+	pctl->spp_gchip = spp_gchip;
+
+	spp_gchip->gpioxt_base  = pctl->gpioxt_base;
+	spp_gchip->first_base   = pctl->first_base;
+	spin_lock_init(&spp_gchip->lock);
+
+	gchip                   = &spp_gchip->chip;
+	gchip->label            = SPPCTL_MODULE_NAME;
+	gchip->parent           = &pdev->dev;
+	gchip->owner            = THIS_MODULE;
+	gchip->request          = gpiochip_generic_request;
+	gchip->free             = gpiochip_generic_free;
+	gchip->get_direction    = sppctl_gpio_get_direction;
+	gchip->direction_input  = sppctl_gpio_direction_input;
+	gchip->direction_output = sppctl_gpio_direction_output;
+	gchip->get              = sppctl_gpio_get;
+	gchip->set              = sppctl_gpio_set;
+	gchip->set_config       = sppctl_gpio_set_config;
+#ifdef CONFIG_DEBUG_FS
+	gchip->dbg_show         = sppctl_gpio_dbg_show;
+#endif
+	gchip->base             = -1;
+	gchip->ngpio            = sppctl_gpio_list_sz;
+	gchip->names            = sppctl_gpio_list_s;
+	gchip->of_gpio_n_cells  = 2;
+
+	pctl->pctl_grange.npins = gchip->ngpio;
+	pctl->pctl_grange.name  = gchip->label;
+	pctl->pctl_grange.gc    = gchip;
+
+	err = devm_gpiochip_add_data(&pdev->dev, gchip, spp_gchip);
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to add gpiochip!\n");
+
+	return 0;
+}
+
+static int sppctl_pin_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
+				 unsigned long *config)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	unsigned int param = pinconf_to_config_param(*config);
+	unsigned int arg;
+
+	switch (param) {
+	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+		if (!sppctl_gpio_output_od_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		arg = 0;
+		break;
+
+	case PIN_CONFIG_OUTPUT:
+		if (!sppctl_first_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		if (!sppctl_master_get(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		if (sppctl_gpio_get_direction(&pctl->spp_gchip->chip, pin))
+			return -EINVAL;
+		arg = sppctl_gpio_get(&pctl->spp_gchip->chip, pin);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	*config = pinconf_to_config_packed(param, arg);
+
+	return 0;
+}
+
+static int sppctl_pin_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
+				 unsigned long *configs, unsigned int num_configs)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int i;
+
+	/* Special handling for IOP pins */
+	if (configs[0] == SPPCTL_IOP_CONFIGS) {
+		sppctl_first_master_set(&pctl->spp_gchip->chip, pin, mux_f_gpio, mux_m_iop);
+		return 0;
+	}
+
+	for (i = 0; i < num_configs; i++) {
+		if (configs[i] & SPPCTL_PCTL_L_OUT)
+			sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 0);
+		if (configs[i] & SPPCTL_PCTL_L_OU1)
+			sppctl_gpio_direction_output(&pctl->spp_gchip->chip, pin, 1);
+		if (configs[i] & SPPCTL_PCTL_L_INV)
+			sppctl_gpio_input_inv_set(&pctl->spp_gchip->chip, pin);
+		if (configs[i] & SPPCTL_PCTL_L_ONV)
+			sppctl_gpio_output_inv_set(&pctl->spp_gchip->chip, pin);
+		if (configs[i] & SPPCTL_PCTL_L_ODR)
+			sppctl_gpio_output_od_set(&pctl->spp_gchip->chip, pin, 1);
+	}
+
+	return 0;
+}
+
+static const struct pinconf_ops sppctl_pconf_ops = {
+	.is_generic     = true,
+	.pin_config_get = sppctl_pin_config_get,
+	.pin_config_set = sppctl_pin_config_set,
+};
+
+static int sppctl_get_functions_count(struct pinctrl_dev *pctldev)
+{
+	return sppctl_list_funcs_sz;
+}
+
+static const char *sppctl_get_function_name(struct pinctrl_dev *pctldev,
+					    unsigned int selector)
+{
+	return sppctl_list_funcs[selector].name;
+}
+
+static int sppctl_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector,
+				      const char * const **groups, unsigned int *num_groups)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const struct sppctl_func *f = &sppctl_list_funcs[selector];
+	int i;
+
+	*num_groups = 0;
+	switch (f->type) {
+	case pinmux_type_fpmx:
+		*num_groups = sppctl_pmux_list_sz;
+		*groups = sppctl_pmux_list_s;
+		break;
+
+	case pinmux_type_grp:
+		if (!f->grps)
+			break;
+
+		*num_groups = f->gnum;
+		for (i = 0; i < pctl->unq_grps_sz; i++)
+			if (pctl->g2fp_maps[i].f_idx == selector)
+				break;
+		*groups = &pctl->unq_grps[i];
+		break;
+
+	default:
+		dev_err(pctldev->dev, "Unknown pinmux (selector: %d, type: %d)\n",
+			selector, f->type);
+		break;
+	}
+
+	return 0;
+}
+
+/**
+ * sppctl_fully_pinmux_conv - Convert GPIO# to fully-pinmux control-field setting
+ *
+ * Each fully-pinmux function can be mapped to any of GPIO 8 ~ 71 by
+ * settings its control-field. Refer to following table:
+ *
+ * control-field |  GPIO
+ * --------------+--------
+ *        0      |  No map
+ *        1      |    8
+ *        2      |    9
+ *        3      |   10
+ *        :      |    :
+ *       65      |   71
+ */
+static inline int sppctl_fully_pinmux_conv(unsigned int offset)
+{
+	return (offset < 8) ? 0 : offset - 7;
+}
+
+static int sppctl_set_mux(struct pinctrl_dev *pctldev, unsigned int func_selector,
+			  unsigned int group_selector)
+{
+	const struct sppctl_func *f = &sppctl_list_funcs[func_selector];
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct grp2fp_map g2fpm = pctl->g2fp_maps[group_selector];
+	int i;
+
+	switch (f->type) {
+	case pinmux_type_fpmx:
+		sppctl_first_master_set(&pctl->spp_gchip->chip, group_selector,
+					mux_f_mux, mux_m_keep);
+		sppctl_func_set(pctl, func_selector, sppctl_fully_pinmux_conv(group_selector));
+		break;
+
+	case pinmux_type_grp:
+		for (i = 0; i < f->grps[g2fpm.g_idx].pnum; i++)
+			sppctl_first_master_set(&pctl->spp_gchip->chip,
+						f->grps[g2fpm.g_idx].pins[i],
+						mux_f_mux, mux_m_keep);
+		sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, f->grps[g2fpm.g_idx].gval);
+		break;
+
+	default:
+		dev_err(pctldev->dev, "Unknown pinmux type (func_selector: %d, type: %d)\n",
+			func_selector, f->type);
+		break;
+	}
+
+	return 0;
+}
+
+static int sppctl_gpio_request_enable(struct pinctrl_dev *pctldev,
+				      struct pinctrl_gpio_range *range, unsigned int offset)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int g_f, g_m;
+
+	g_f = sppctl_first_get(&pctl->spp_gchip->chip, offset);
+	g_m = sppctl_master_get(&pctl->spp_gchip->chip, offset);
+	if (g_f == mux_f_gpio && g_m == mux_m_gpio)
+		return 0;
+
+	sppctl_first_master_set(&pctl->spp_gchip->chip, offset, mux_f_gpio, mux_m_gpio);
+	return 0;
+}
+
+static const struct pinmux_ops sppctl_pinmux_ops = {
+	.get_functions_count = sppctl_get_functions_count,
+	.get_function_name   = sppctl_get_function_name,
+	.get_function_groups = sppctl_get_function_groups,
+	.set_mux             = sppctl_set_mux,
+	.gpio_request_enable = sppctl_gpio_request_enable,
+	.strict              = true,
+};
+
+static int sppctl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->unq_grps_sz;
+}
+
+static const char *sppctl_get_group_name(struct pinctrl_dev *pctldev, unsigned int selector)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+
+	return pctl->unq_grps[selector];
+}
+
+static int sppctl_get_group_pins(struct pinctrl_dev *pctldev, unsigned int selector,
+				 const unsigned int **pins, unsigned int *num_pins)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	struct grp2fp_map g2fpm = pctl->g2fp_maps[selector];
+	const struct sppctl_func *f;
+
+	f = &sppctl_list_funcs[g2fpm.f_idx];
+	*num_pins = 0;
+
+	/* Except group-pinmux, each group has 1 pin. */
+	if (f->type != pinmux_type_grp) {
+		*num_pins = 1;
+		*pins = &sppctl_pins_gpio[selector];
+		return 0;
+	}
+
+	/* Group-pinmux may have more than one pin. */
+	if (!f->grps)
+		return 0;
+
+	if (f->gnum < 1)
+		return 0;
+
+	*num_pins = f->grps[g2fpm.g_idx].pnum;
+	*pins = f->grps[g2fpm.g_idx].pins;
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static void sppctl_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
+				unsigned int offset)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	const char *pin_type;
+	u8 first, master;
+
+	first = sppctl_first_get(&pctl->spp_gchip->chip, offset);
+	master = sppctl_master_get(&pctl->spp_gchip->chip, offset);
+	if (first)
+		if (master)
+			pin_type = "GPIO";
+		else
+			pin_type = " IOP";
+	else
+		pin_type = " MUX";
+	seq_printf(s, " %s", pin_type);
+}
+#endif
+
+static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np_config,
+				 struct pinctrl_map **map, unsigned int *num_maps)
+{
+	struct sppctl_pdata *pctl = pinctrl_dev_get_drvdata(pctldev);
+	int nmG = of_property_count_strings(np_config, "groups");
+	const struct sppctl_func *f = NULL;
+	u8 pin_num, pin_type, pin_func;
+	struct device_node *parent;
+	unsigned long *configs;
+	struct property *prop;
+	const char *s_f, *s_g;
+
+	const __be32 *list;
+	u32 dt_pin, dt_fun;
+	int i, size = 0;
+
+	list = of_get_property(np_config, "sunplus,pins", &size);
+
+	if (nmG <= 0)
+		nmG = 0;
+
+	parent = of_get_parent(np_config);
+	*num_maps = size / sizeof(*list);
+
+	/*
+	 * Process property:
+	 *     sunplus,pins = < u32 u32 u32 ... >;
+	 *
+	 * Each 32-bit integer defines a individual pin in which:
+	 *
+	 *   Bit 32~24: defines GPIO pin number. Its range is 0 ~ 98.
+	 *   Bit 23~16: defines types: (1) fully-pinmux pins
+	 *                             (2) IO processor pins
+	 *                             (3) digital GPIO pins
+	 *   Bit 15~8:  defines pins of peripherals (which are defined in
+	 *              'include/dt-binging/pinctrl/sppctl.h').
+	 *   Bit 7~0:   defines types or initial-state of digital GPIO pins.
+	 */
+	for (i = 0; i < (*num_maps); i++) {
+		dt_pin = be32_to_cpu(list[i]);
+		pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
+
+		if (pin_num >= sppctl_pins_all_sz) {
+			dev_err(pctldev->dev, "Invalid pin property at index %d (0x%08x)\n",
+				i, dt_pin);
+			return -EINVAL;
+		}
+	}
+
+	*map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL);
+	for (i = 0; i < (*num_maps); i++) {
+		dt_pin = be32_to_cpu(list[i]);
+		pin_num = FIELD_GET(GENMASK(31, 24), dt_pin);
+		pin_type = FIELD_GET(GENMASK(23, 16), dt_pin);
+		pin_func = FIELD_GET(GENMASK(15, 8), dt_pin);
+		(*map)[i].name = parent->name;
+
+		if (pin_type == SPPCTL_PCTL_G_GPIO) {
+			/* A digital GPIO pin */
+			(*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+			(*map)[i].data.configs.num_configs = 1;
+			(*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num);
+			configs = kmalloc(sizeof(*configs), GFP_KERNEL);
+			*configs = FIELD_GET(GENMASK(7, 0), dt_pin);
+			(*map)[i].data.configs.configs = configs;
+
+			dev_dbg(pctldev->dev, "%s: GPIO (%s)\n",
+				(*map)[i].data.configs.group_or_pin,
+				(*configs & (SPPCTL_PCTL_L_OUT | SPPCTL_PCTL_L_OU1)) ?
+				"OUT" : "IN");
+		} else if (pin_type == SPPCTL_PCTL_G_IOPP) {
+			/* A IO Processor (IOP) pin */
+			(*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN;
+			(*map)[i].data.configs.num_configs = 1;
+			(*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num);
+			configs = kmalloc(sizeof(*configs), GFP_KERNEL);
+			*configs = SPPCTL_IOP_CONFIGS;
+			(*map)[i].data.configs.configs = configs;
+
+			dev_dbg(pctldev->dev, "%s: IOP\n",
+				(*map)[i].data.configs.group_or_pin);
+		} else {
+			/* A fully-pinmux pin */
+			(*map)[i].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[i].data.mux.function = sppctl_list_funcs[pin_func].name;
+			(*map)[i].data.mux.group = pin_get_name(pctldev, pin_num);
+
+			dev_dbg(pctldev->dev, "%s: %s\n", (*map)[i].data.mux.group,
+				(*map)[i].data.mux.function);
+		}
+	}
+
+	/*
+	 * Process properties:
+	 *     function = "xxx";
+	 *     groups = "yyy";
+	 */
+	if (nmG > 0 && of_property_read_string(np_config, "function", &s_f) == 0) {
+		of_property_for_each_string(np_config, "groups", prop, s_g) {
+			(*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;
+			(*map)[*num_maps].data.mux.function = s_f;
+			(*map)[*num_maps].data.mux.group = s_g;
+			(*num_maps)++;
+
+			dev_dbg(pctldev->dev, "%s: %s\n", s_f, s_g);
+		}
+	}
+
+	/*
+	 * Process property:
+	 *     sunplus,zerofunc = < u32 u32 u32 ...>
+	 */
+	list = of_get_property(np_config, "sunplus,zerofunc", &size);
+	if (list) {
+		for (i = 0; i < (size / sizeof(*list)); i++) {
+			dt_fun = be32_to_cpu(list[i]);
+			if (dt_fun >= sppctl_list_funcs_sz) {
+				dev_err(pctldev->dev, "Zero-func %d out of range!\n",
+					dt_fun);
+				continue;
+			}
+
+			f = &sppctl_list_funcs[dt_fun];
+			switch (f->type) {
+			case pinmux_type_fpmx:
+				sppctl_func_set(pctl, dt_fun, 0);
+				dev_dbg(pctldev->dev, "%s: No map\n", f->name);
+				break;
+
+			case pinmux_type_grp:
+				sppctl_gmx_set(pctl, f->roff, f->boff, f->blen, 0);
+				dev_dbg(pctldev->dev, "%s: No map\n", f->name);
+				break;
+
+			default:
+				dev_err(pctldev->dev, "Wrong zero-group: %d (%s)\n",
+					dt_fun, f->name);
+				break;
+			}
+		}
+	}
+
+	of_node_put(parent);
+	dev_dbg(pctldev->dev, "%d pins mapped\n", *num_maps);
+	return 0;
+}
+
+static const struct pinctrl_ops sppctl_pctl_ops = {
+	.get_groups_count = sppctl_get_groups_count,
+	.get_group_name   = sppctl_get_group_name,
+	.get_group_pins   = sppctl_get_group_pins,
+#ifdef CONFIG_DEBUG_FS
+	.pin_dbg_show     = sppctl_pin_dbg_show,
+#endif
+	.dt_node_to_map   = sppctl_dt_node_to_map,
+	.dt_free_map      = pinctrl_utils_free_map,
+};
+
+static int sppctl_group_groups(struct platform_device *pdev)
+{
+	struct sppctl_pdata *sppctl = platform_get_drvdata(pdev);
+	int i, k, j;
+
+	/* Calculate number of total group (GPIO + group-pinmux group). */
+	sppctl->unq_grps_sz = sppctl_gpio_list_sz;
+	for (i = 0; i < sppctl_list_funcs_sz; i++)
+		if (sppctl_list_funcs[i].type == pinmux_type_grp)
+			sppctl->unq_grps_sz += sppctl_list_funcs[i].gnum;
+
+	sppctl->unq_grps = devm_kcalloc(&pdev->dev, sppctl->unq_grps_sz + 1,
+					sizeof(*sppctl->unq_grps), GFP_KERNEL);
+	if (!sppctl->unq_grps)
+		return -ENOMEM;
+
+	sppctl->g2fp_maps = devm_kcalloc(&pdev->dev, sppctl->unq_grps_sz + 1,
+					 sizeof(*sppctl->g2fp_maps), GFP_KERNEL);
+	if (!sppctl->g2fp_maps)
+		return -ENOMEM;
+
+	/* Add GPIO pins. */
+	for (i = 0; i < sppctl_gpio_list_sz; i++) {
+		sppctl->unq_grps[i] = sppctl_gpio_list_s[i];
+		sppctl->g2fp_maps[i].f_idx = 0;
+		sppctl->g2fp_maps[i].g_idx = i;
+	}
+
+	/* Add group-pinmux to end of GPIO pins. */
+	j = sppctl_gpio_list_sz;
+	for (i = 0; i < sppctl_list_funcs_sz; i++) {
+		if (sppctl_list_funcs[i].type != pinmux_type_grp)
+			continue;
+
+		for (k = 0; k < sppctl_list_funcs[i].gnum; k++) {
+			sppctl->unq_grps[j] = sppctl_list_funcs[i].grps[k].name;
+			sppctl->g2fp_maps[j].f_idx = i;
+			sppctl->g2fp_maps[j].g_idx = k;
+			j++;
+		}
+	}
+
+	return 0;
+}
+
+static int sppctl_pinctrl_init(struct platform_device *pdev)
+{
+	struct sppctl_pdata *sppctl = platform_get_drvdata(pdev);
+	int err;
+
+	sppctl->pctl_desc.owner   = THIS_MODULE;
+	sppctl->pctl_desc.name    = dev_name(&pdev->dev);
+	sppctl->pctl_desc.pins    = sppctl_pins_all;
+	sppctl->pctl_desc.npins   = sppctl_pins_all_sz;
+	sppctl->pctl_desc.pctlops = &sppctl_pctl_ops;
+	sppctl->pctl_desc.confops = &sppctl_pconf_ops;
+	sppctl->pctl_desc.pmxops  = &sppctl_pinmux_ops;
+
+	err = sppctl_group_groups(pdev);
+	if (err)
+		return err;
+
+	err = devm_pinctrl_register_and_init(&pdev->dev, &sppctl->pctl_desc,
+					     sppctl, &sppctl->pctl_dev);
+	if (err)
+		return dev_err_probe(&pdev->dev, err, "Failed to register pinctrl!\n");
+
+	pinctrl_enable(sppctl->pctl_dev);
+	return 0;
+}
+
+static int sppctl_resource_map(struct platform_device *pdev, struct sppctl_pdata *sppctl)
+{
+	sppctl->moon2_base = devm_platform_ioremap_resource_byname(pdev, "moon2");
+	if (IS_ERR(sppctl->moon2_base))
+		return PTR_ERR(sppctl->moon2_base);
+
+	sppctl->gpioxt_base = devm_platform_ioremap_resource_byname(pdev, "gpioxt");
+	if (IS_ERR(sppctl->gpioxt_base))
+		return PTR_ERR(sppctl->gpioxt_base);
+
+	sppctl->first_base = devm_platform_ioremap_resource_byname(pdev, "first");
+	if (IS_ERR(sppctl->first_base))
+		return PTR_ERR(sppctl->first_base);
+
+	sppctl->moon1_base = devm_platform_ioremap_resource_byname(pdev, "moon1");
+	if (IS_ERR(sppctl->moon1_base))
+		return PTR_ERR(sppctl->moon1_base);
+
+	return 0;
+}
+
+static int sppctl_probe(struct platform_device *pdev)
+{
+	struct sppctl_pdata *sppctl;
+	int ret;
+
+	sppctl = devm_kzalloc(&pdev->dev, sizeof(*sppctl), GFP_KERNEL);
+	if (!sppctl)
+		return -ENOMEM;
+	platform_set_drvdata(pdev, sppctl);
+
+	ret = sppctl_resource_map(pdev, sppctl);
+	if (ret)
+		return ret;
+
+	ret = sppctl_gpio_new(pdev, sppctl);
+	if (ret)
+		return ret;
+
+	ret = sppctl_pinctrl_init(pdev);
+	if (ret)
+		return ret;
+
+	pinctrl_add_gpio_range(sppctl->pctl_dev, &sppctl->pctl_grange);
+
+	return 0;
+}
+
+static const struct of_device_id sppctl_match_table[] = {
+	{ .compatible = "sunplus,sp7021-pctl" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver sppctl_pinctrl_driver = {
+	.driver = {
+		.name           = SPPCTL_MODULE_NAME,
+		.of_match_table = sppctl_match_table,
+	},
+	.probe  = sppctl_probe,
+};
+builtin_platform_driver(sppctl_pinctrl_driver)
+
+MODULE_AUTHOR("Dvorkin Dmitry <dvorkin at tibbo.com>");
+MODULE_AUTHOR("Wells Lu <wellslutw at gmail.com>");
+MODULE_DESCRIPTION("Sunplus SP7021 Pin Control and GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/sunplus/sppctl.h b/drivers/pinctrl/sunplus/sppctl.h
new file mode 100644
index 0000000..6210f22
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl.h
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech / Tibbo Tech.
+ */
+
+#ifndef __SPPCTL_H__
+#define __SPPCTL_H__
+
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#define SPPCTL_MODULE_NAME		"sppctl_sp7021"
+
+#define SPPCTL_GPIO_OFF_FIRST		0x00
+#define SPPCTL_GPIO_OFF_MASTER		0x00
+#define SPPCTL_GPIO_OFF_OE		0x20
+#define SPPCTL_GPIO_OFF_OUT		0x40
+#define SPPCTL_GPIO_OFF_IN		0x60
+#define SPPCTL_GPIO_OFF_IINV		0x80
+#define SPPCTL_GPIO_OFF_OINV		0xa0
+#define SPPCTL_GPIO_OFF_OD		0xc0
+
+#define SPPCTL_FULLY_PINMUX_MASK_MASK	GENMASK(22, 16)
+#define SPPCTL_FULLY_PINMUX_SEL_MASK	GENMASK(6, 0)
+#define SPPCTL_FULLY_PINMUX_UPPER_SHIFT	8
+
+/*
+ * Mask-fields and control-fields of MOON registers of SP7021 are
+ * arranged as shown below:
+ *
+ *  register |  mask-fields | control-fields
+ * ----------+--------------+----------------
+ *  base[0]  |  (31 : 16)   |   (15 : 0)
+ *  base[1]  |  (31 : 24)   |   (15 : 0)
+ *  base[2]  |  (31 : 24)   |   (15 : 0)
+ *     :     |      :       |       :
+ *
+ * where mask-fields are used to protect control-fields from write-in
+ * accidentally. Set the corresponding bits in the mask-field before
+ * you write a value into a control-field.
+ */
+#define SPPCTL_MOON_REG_MASK_SHIFT	16
+#define SPPCTL_SET_MOON_REG_BIT(bit)	(BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT) | BIT(bit))
+#define SPPCTL_CLR_MOON_REG_BIT(bit)	BIT((bit) + SPPCTL_MOON_REG_MASK_SHIFT)
+
+#define SPPCTL_IOP_CONFIGS		0xff
+
+#define FNCE(n, r, o, bo, bl, g) { \
+	.name = n, \
+	.type = r, \
+	.roff = o, \
+	.boff = bo, \
+	.blen = bl, \
+	.grps = (g), \
+	.gnum = ARRAY_SIZE(g), \
+}
+
+#define FNCN(n, r, o, bo, bl) { \
+	.name = n, \
+	.type = r, \
+	.roff = o, \
+	.boff = bo, \
+	.blen = bl, \
+	.grps = NULL, \
+	.gnum = 0, \
+}
+
+#define EGRP(n, v, p) { \
+	.name = n, \
+	.gval = (v), \
+	.pins = (p), \
+	.pnum = ARRAY_SIZE(p), \
+}
+
+/**
+ * enum mux_first_reg - Define modes of access of FIRST register
+ * @mux_f_mux:  Set the corresponding pin to a fully-pinmux pin
+ * @mux_f_gpio: Set the corresponding pin to a GPIO or IOP pin
+ * @mux_f_keep: Don't change (keep intact)
+ */
+enum mux_first_reg {
+	mux_f_mux = 0,
+	mux_f_gpio = 1,
+	mux_f_keep = 2,
+};
+
+/**
+ * enum mux_master_reg - Define modes of access of MASTER register
+ * @mux_m_iop:  Set the corresponding pin to an IO processor (IOP) pin
+ * @mux_m_gpio: Set the corresponding pin to a digital GPIO pin
+ * @mux_m_keep: Don't change (keep intact)
+ */
+enum mux_master_reg {
+	mux_m_iop = 0,
+	mux_m_gpio = 1,
+	mux_m_keep = 2,
+};
+
+/**
+ * enum pinmux_type - Define types of pinmux pins
+ * @pinmux_type_fpmx: A fully-pinmux pin
+ * @pinmux_type_grp:  A group-pinmux pin
+ */
+enum pinmux_type {
+	pinmux_type_fpmx,
+	pinmux_type_grp,
+};
+
+/**
+ * struct grp2fp_map - A map storing indexes
+ * @f_idx: an index to function table
+ * @g_idx: an index to group table
+ */
+struct grp2fp_map {
+	u16 f_idx;
+	u16 g_idx;
+};
+
+struct sppctl_gpio_chip;
+
+struct sppctl_pdata {
+	void __iomem *moon2_base;	/* MOON2                                 */
+	void __iomem *gpioxt_base;	/* MASTER, OE, OUT, IN, I_INV, O_INV, OD */
+	void __iomem *first_base;	/* FIRST                                 */
+	void __iomem *moon1_base;	/* MOON1               */
+
+	struct pinctrl_desc pctl_desc;
+	struct pinctrl_dev *pctl_dev;
+	struct pinctrl_gpio_range pctl_grange;
+	struct sppctl_gpio_chip *spp_gchip;
+
+	char const **unq_grps;
+	size_t unq_grps_sz;
+	struct grp2fp_map *g2fp_maps;
+};
+
+struct sppctl_grp {
+	const char * const name;
+	const u8 gval;                  /* group number   */
+	const unsigned * const pins;    /* list of pins   */
+	const unsigned int pnum;        /* number of pins */
+};
+
+struct sppctl_func {
+	const char * const name;
+	const enum pinmux_type type;    /* function type          */
+	const u8 roff;                  /* register offset        */
+	const u8 boff;                  /* bit offset             */
+	const u8 blen;                  /* bit length             */
+	const struct sppctl_grp * const grps; /* list of groups   */
+	const unsigned int gnum;        /* number of groups       */
+};
+
+extern const struct sppctl_func sppctl_list_funcs[];
+extern const char * const sppctl_pmux_list_s[];
+extern const char * const sppctl_gpio_list_s[];
+extern const struct pinctrl_pin_desc sppctl_pins_all[];
+extern const unsigned int sppctl_pins_gpio[];
+
+extern const size_t sppctl_list_funcs_sz;
+extern const size_t sppctl_pmux_list_sz;
+extern const size_t sppctl_gpio_list_sz;
+extern const size_t sppctl_pins_all_sz;
+
+#endif
diff --git a/drivers/pinctrl/sunplus/sppctl_sp7021.c b/drivers/pinctrl/sunplus/sppctl_sp7021.c
new file mode 100644
index 0000000..9748345
--- /dev/null
+++ b/drivers/pinctrl/sunplus/sppctl_sp7021.c
@@ -0,0 +1,583 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SP7021 Pin Controller Driver.
+ * Copyright (C) Sunplus Tech / Tibbo Tech.
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/kernel.h>
+#include <linux/pinctrl/pinctrl.h>
+
+#include "sppctl.h"
+
+#define D_PIS(x, y)	"P" __stringify(x) "_0" __stringify(y)
+#define D(x, y)		((x) * 8 + (y))
+#define P(x, y)		PINCTRL_PIN(D(x, y), D_PIS(x, y))
+
+const char * const sppctl_gpio_list_s[] = {
+	D_PIS(0, 0),  D_PIS(0, 1),  D_PIS(0, 2),  D_PIS(0, 3),
+	D_PIS(0, 4),  D_PIS(0, 5),  D_PIS(0, 6),  D_PIS(0, 7),
+	D_PIS(1, 0),  D_PIS(1, 1),  D_PIS(1, 2),  D_PIS(1, 3),
+	D_PIS(1, 4),  D_PIS(1, 5),  D_PIS(1, 6),  D_PIS(1, 7),
+	D_PIS(2, 0),  D_PIS(2, 1),  D_PIS(2, 2),  D_PIS(2, 3),
+	D_PIS(2, 4),  D_PIS(2, 5),  D_PIS(2, 6),  D_PIS(2, 7),
+	D_PIS(3, 0),  D_PIS(3, 1),  D_PIS(3, 2),  D_PIS(3, 3),
+	D_PIS(3, 4),  D_PIS(3, 5),  D_PIS(3, 6),  D_PIS(3, 7),
+	D_PIS(4, 0),  D_PIS(4, 1),  D_PIS(4, 2),  D_PIS(4, 3),
+	D_PIS(4, 4),  D_PIS(4, 5),  D_PIS(4, 6),  D_PIS(4, 7),
+	D_PIS(5, 0),  D_PIS(5, 1),  D_PIS(5, 2),  D_PIS(5, 3),
+	D_PIS(5, 4),  D_PIS(5, 5),  D_PIS(5, 6),  D_PIS(5, 7),
+	D_PIS(6, 0),  D_PIS(6, 1),  D_PIS(6, 2),  D_PIS(6, 3),
+	D_PIS(6, 4),  D_PIS(6, 5),  D_PIS(6, 6),  D_PIS(6, 7),
+	D_PIS(7, 0),  D_PIS(7, 1),  D_PIS(7, 2),  D_PIS(7, 3),
+	D_PIS(7, 4),  D_PIS(7, 5),  D_PIS(7, 6),  D_PIS(7, 7),
+	D_PIS(8, 0),  D_PIS(8, 1),  D_PIS(8, 2),  D_PIS(8, 3),
+	D_PIS(8, 4),  D_PIS(8, 5),  D_PIS(8, 6),  D_PIS(8, 7),
+	D_PIS(9, 0),  D_PIS(9, 1),  D_PIS(9, 2),  D_PIS(9, 3),
+	D_PIS(9, 4),  D_PIS(9, 5),  D_PIS(9, 6),  D_PIS(9, 7),
+	D_PIS(10, 0), D_PIS(10, 1), D_PIS(10, 2), D_PIS(10, 3),
+	D_PIS(10, 4), D_PIS(10, 5), D_PIS(10, 6), D_PIS(10, 7),
+	D_PIS(11, 0), D_PIS(11, 1), D_PIS(11, 2), D_PIS(11, 3),
+	D_PIS(11, 4), D_PIS(11, 5), D_PIS(11, 6), D_PIS(11, 7),
+	D_PIS(12, 0), D_PIS(12, 1), D_PIS(12, 2),
+};
+
+const size_t sppctl_gpio_list_sz = ARRAY_SIZE(sppctl_gpio_list_s);
+
+const unsigned int sppctl_pins_gpio[] = {
+	D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7),
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7),
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7),
+	D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7),
+	D(11, 0), D(11, 1), D(11, 2), D(11, 3), D(11, 4), D(11, 5), D(11, 6), D(11, 7),
+	D(12, 0), D(12, 1), D(12, 2),
+};
+
+const struct pinctrl_pin_desc sppctl_pins_all[] = {
+	/* gpio and iop only */
+	P(0, 0), P(0, 1), P(0, 2), P(0, 3), P(0, 4), P(0, 5), P(0, 6), P(0, 7),
+	/* gpio, iop, muxable */
+	P(1, 0), P(1, 1), P(1, 2), P(1, 3), P(1, 4), P(1, 5), P(1, 6), P(1, 7),
+	P(2, 0), P(2, 1), P(2, 2), P(2, 3), P(2, 4), P(2, 5), P(2, 6), P(2, 7),
+	P(3, 0), P(3, 1), P(3, 2), P(3, 3), P(3, 4), P(3, 5), P(3, 6), P(3, 7),
+	P(4, 0), P(4, 1), P(4, 2), P(4, 3), P(4, 4), P(4, 5), P(4, 6), P(4, 7),
+	P(5, 0), P(5, 1), P(5, 2), P(5, 3), P(5, 4), P(5, 5), P(5, 6), P(5, 7),
+	P(6, 0), P(6, 1), P(6, 2), P(6, 3), P(6, 4), P(6, 5), P(6, 6), P(6, 7),
+	P(7, 0), P(7, 1), P(7, 2), P(7, 3), P(7, 4), P(7, 5), P(7, 6), P(7, 7),
+	P(8, 0), P(8, 1), P(8, 2), P(8, 3), P(8, 4), P(8, 5), P(8, 6), P(8, 7),
+	/* gpio and iop only */
+	P(9, 0),  P(9, 1),  P(9, 2),  P(9, 3),  P(9, 4),  P(9, 5),  P(9, 6),  P(9, 7),
+	P(10, 0), P(10, 1), P(10, 2), P(10, 3), P(10, 4), P(10, 5), P(10, 6), P(10, 7),
+	P(11, 0), P(11, 1), P(11, 2), P(11, 3), P(11, 4), P(11, 5), P(11, 6), P(11, 7),
+	P(12, 0), P(12, 1), P(12, 2),
+};
+
+const size_t sppctl_pins_all_sz = ARRAY_SIZE(sppctl_pins_all);
+
+const char * const sppctl_pmux_list_s[] = {
+	D_PIS(0, 0),
+	D_PIS(1, 0), D_PIS(1, 1), D_PIS(1, 2), D_PIS(1, 3),
+	D_PIS(1, 4), D_PIS(1, 5), D_PIS(1, 6), D_PIS(1, 7),
+	D_PIS(2, 0), D_PIS(2, 1), D_PIS(2, 2), D_PIS(2, 3),
+	D_PIS(2, 4), D_PIS(2, 5), D_PIS(2, 6), D_PIS(2, 7),
+	D_PIS(3, 0), D_PIS(3, 1), D_PIS(3, 2), D_PIS(3, 3),
+	D_PIS(3, 4), D_PIS(3, 5), D_PIS(3, 6), D_PIS(3, 7),
+	D_PIS(4, 0), D_PIS(4, 1), D_PIS(4, 2), D_PIS(4, 3),
+	D_PIS(4, 4), D_PIS(4, 5), D_PIS(4, 6), D_PIS(4, 7),
+	D_PIS(5, 0), D_PIS(5, 1), D_PIS(5, 2), D_PIS(5, 3),
+	D_PIS(5, 4), D_PIS(5, 5), D_PIS(5, 6), D_PIS(5, 7),
+	D_PIS(6, 0), D_PIS(6, 1), D_PIS(6, 2), D_PIS(6, 3),
+	D_PIS(6, 4), D_PIS(6, 5), D_PIS(6, 6), D_PIS(6, 7),
+	D_PIS(7, 0), D_PIS(7, 1), D_PIS(7, 2), D_PIS(7, 3),
+	D_PIS(7, 4), D_PIS(7, 5), D_PIS(7, 6), D_PIS(7, 7),
+	D_PIS(8, 0), D_PIS(8, 1), D_PIS(8, 2), D_PIS(8, 3),
+	D_PIS(8, 4), D_PIS(8, 5), D_PIS(8, 6), D_PIS(8, 7),
+};
+
+const size_t sppctl_pmux_list_sz = ARRAY_SIZE(sppctl_pmux_list_s);
+
+static const unsigned int pins_spif1[] = {
+	D(10, 3), D(10, 4), D(10, 6), D(10, 7),
+};
+
+static const unsigned int pins_spif2[] = {
+	D(9, 4), D(9, 6), D(9, 7), D(10, 1),
+};
+
+static const struct sppctl_grp sp7021grps_spif[] = {
+	EGRP("SPI_FLASH1", 1, pins_spif1),
+	EGRP("SPI_FLASH2", 2, pins_spif2),
+};
+
+static const unsigned int pins_spi41[] = {
+	D(10, 2), D(10, 5),
+};
+
+static const unsigned int pins_spi42[] = {
+	D(9, 5), D(9, 8),
+};
+
+static const struct sppctl_grp sp7021grps_spi4[] = {
+	EGRP("SPI_FLASH_4BIT1", 1, pins_spi41),
+	EGRP("SPI_FLASH_4BIT2", 2, pins_spi42),
+};
+
+static const unsigned int pins_snan[] = {
+	D(9, 4), D(9, 5), D(9, 6), D(9, 7), D(10, 0), D(10, 1),
+};
+
+static const struct sppctl_grp sp7021grps_snan[] = {
+	EGRP("SPI_NAND", 1, pins_snan),
+};
+
+static const unsigned int pins_emmc[] = {
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5),
+	D(9, 6), D(9, 7), D(10, 0), D(10, 1),
+};
+
+static const struct sppctl_grp sp7021grps_emmc[] = {
+	EGRP("CARD0_EMMC", 1, pins_emmc),
+};
+
+static const unsigned int pins_sdsd[] = {
+	D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6),
+};
+
+static const struct sppctl_grp sp7021grps_sdsd[] = {
+	EGRP("SD_CARD", 1, pins_sdsd),
+};
+
+static const unsigned int pins_uar0[] = {
+	D(11, 0), D(11, 1),
+};
+
+static const struct sppctl_grp sp7021grps_uar0[] = {
+	EGRP("UA0", 1, pins_uar0),
+};
+
+static const unsigned int pins_adbg1[] = {
+	D(10, 2), D(10, 3),
+};
+
+static const unsigned int pins_adbg2[] = {
+	D(7, 1), D(7, 2),
+};
+
+static const struct sppctl_grp sp7021grps_adbg[] = {
+	EGRP("ACHIP_DEBUG1", 1, pins_adbg1),
+	EGRP("ACHIP_DEBUG2", 2, pins_adbg2),
+};
+
+static const unsigned int pins_aua2axi1[] = {
+	D(2, 0), D(2, 1), D(2, 2),
+};
+
+static const unsigned int pins_aua2axi2[] = {
+	D(1, 0), D(1, 1), D(1, 2),
+};
+
+static const struct sppctl_grp sp7021grps_au2x[] = {
+	EGRP("ACHIP_UA2AXI1", 1, pins_aua2axi1),
+	EGRP("ACHIP_UA2AXI2", 2, pins_aua2axi2),
+};
+
+static const unsigned int pins_fpga[] = {
+	D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5),
+	D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3),
+	D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1),
+	D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5),
+	D(4, 6), D(4, 7), D(5, 0), D(5, 1), D(5, 2),
+};
+
+static const struct sppctl_grp sp7021grps_fpga[] = {
+	EGRP("FPGA_IFX", 1, pins_fpga),
+};
+
+static const unsigned int pins_hdmi1[] = {
+	D(10, 6), D(12, 2), D(12, 1),
+};
+
+static const unsigned int pins_hdmi2[] = {
+	D(8, 3), D(8, 5), D(8, 6),
+};
+
+static const unsigned int pins_hdmi3[] = {
+	D(7, 4), D(7, 6), D(7, 7),
+};
+
+static const struct sppctl_grp sp7021grps_hdmi[] = {
+	EGRP("HDMI_TX1", 1, pins_hdmi1),
+	EGRP("HDMI_TX2", 2, pins_hdmi2),
+	EGRP("HDMI_TX3", 3, pins_hdmi3),
+};
+
+static const unsigned int pins_eadc[] = {
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6),
+};
+
+static const struct sppctl_grp sp7021grps_eadc[] = {
+	EGRP("AUD_EXT_ADC_IFX0", 1, pins_eadc),
+};
+
+static const unsigned int pins_edac[] = {
+	D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), D(3, 4),
+};
+
+static const struct sppctl_grp sp7021grps_edac[] = {
+	EGRP("AUD_EXT_DAC_IFX0", 1, pins_edac),
+};
+
+static const unsigned int pins_spdi[] = {
+	D(2, 4),
+};
+
+static const struct sppctl_grp sp7021grps_spdi[] = {
+	EGRP("AUD_IEC_RX0", 1, pins_spdi),
+};
+
+static const unsigned int pins_spdo[] = {
+	D(3, 6),
+};
+
+static const struct sppctl_grp sp7021grps_spdo[] = {
+	EGRP("AUD_IEC_TX0", 1, pins_spdo),
+};
+
+static const unsigned int pins_tdmt[] = {
+	D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2),
+};
+
+static const struct sppctl_grp sp7021grps_tdmt[] = {
+	EGRP("TDMTX_IFX0", 1, pins_tdmt),
+};
+
+static const unsigned int pins_tdmr[] = {
+	D(1, 7), D(2, 0), D(2, 1), D(2, 2),
+};
+
+static const struct sppctl_grp sp7021grps_tdmr[] = {
+	EGRP("TDMRX_IFX0", 1, pins_tdmr),
+};
+
+static const unsigned int pins_pdmr[] = {
+	D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3),
+};
+
+static const struct sppctl_grp sp7021grps_pdmr[] = {
+	EGRP("PDMRX_IFX0", 1, pins_pdmr),
+};
+
+static const unsigned int pins_pcmt[] = {
+	D(3, 7), D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4),
+};
+
+static const struct sppctl_grp sp7021grps_pcmt[] = {
+	EGRP("PCM_IEC_TX", 1, pins_pcmt),
+};
+
+static const unsigned int pins_lcdi[] = {
+	D(1, 4), D(1, 5), D(1, 6), D(1, 7), D(2, 0), D(2, 1), D(2, 2), D(2, 3),
+	D(2, 4), D(2, 5), D(2, 6), D(2, 7), D(3, 0), D(3, 1), D(3, 2), D(3, 3),
+	D(3, 4), D(3, 5), D(3, 6), D(3, 7), D(4, 0), D(4, 1), D(4, 2), D(4, 3),
+	D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+};
+
+static const struct sppctl_grp sp7021grps_lcdi[] = {
+	EGRP("LCDIF", 1, pins_lcdi),
+};
+
+static const unsigned int pins_dvdd[] = {
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5),
+};
+
+static const struct sppctl_grp sp7021grps_dvdd[] = {
+	EGRP("DVD_DSP_DEBUG", 1, pins_dvdd),
+};
+
+static const unsigned int pins_i2cd[] = {
+	D(1, 0), D(1, 1),
+};
+
+static const struct sppctl_grp sp7021grps_i2cd[] = {
+	EGRP("I2C_DEBUG", 1, pins_i2cd),
+};
+
+static const unsigned int pins_i2cs[] = {
+	D(0, 0), D(0, 1),
+};
+
+static const struct sppctl_grp sp7021grps_i2cs[] = {
+	EGRP("I2C_SLAVE", 1, pins_i2cs),
+};
+
+static const unsigned int pins_wakp[] = {
+	D(10, 5),
+};
+
+static const struct sppctl_grp sp7021grps_wakp[] = {
+	EGRP("WAKEUP", 1, pins_wakp),
+};
+
+static const unsigned int pins_u2ax[] = {
+	D(2, 0), D(2, 1), D(3, 0), D(3, 1),
+};
+
+static const struct sppctl_grp sp7021grps_u2ax[] = {
+	EGRP("UART2AXI", 1, pins_u2ax),
+};
+
+static const unsigned int pins_u0ic[] = {
+	D(0, 0), D(0, 1), D(0, 4), D(0, 5), D(1, 0), D(1, 1),
+};
+
+static const struct sppctl_grp sp7021grps_u0ic[] = {
+	EGRP("USB0_I2C", 1, pins_u0ic),
+};
+
+static const unsigned int pins_u1ic[] = {
+	D(0, 2), D(0, 3), D(0, 6), D(0, 7), D(1, 2), D(1, 3),
+};
+
+static const struct sppctl_grp sp7021grps_u1ic[] = {
+	EGRP("USB1_I2C", 1, pins_u1ic),
+};
+
+static const unsigned int pins_u0ot[] = {
+	D(11, 2),
+};
+
+static const struct sppctl_grp sp7021grps_u0ot[] = {
+	EGRP("USB0_OTG", 1, pins_u0ot),
+};
+
+static const unsigned int pins_u1ot[] = {
+	D(11, 3),
+};
+
+static const struct sppctl_grp sp7021grps_u1ot[] = {
+	EGRP("USB1_OTG", 1, pins_u1ot),
+};
+
+static const unsigned int pins_uphd[] = {
+	D(0, 1), D(0, 2), D(0, 3), D(7, 4), D(7, 5), D(7, 6),
+	D(7, 7), D(8, 0), D(8, 1), D(8, 2), D(8, 3),
+	D(9, 7), D(10, 2), D(10, 3), D(10, 4),
+};
+
+static const struct sppctl_grp sp7021grps_up0d[] = {
+	EGRP("UPHY0_DEBUG", 1, pins_uphd),
+};
+
+static const struct sppctl_grp sp7021grps_up1d[] = {
+	EGRP("UPHY1_DEBUG", 1, pins_uphd),
+};
+
+static const unsigned int pins_upex[] = {
+	D(0, 0), D(0, 1), D(0, 2), D(0, 3), D(0, 4), D(0, 5), D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 0), D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2), D(3, 3), D(3, 4), D(3, 5), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 0), D(6, 1), D(6, 2), D(6, 3), D(6, 4), D(6, 5), D(6, 6), D(6, 7),
+	D(7, 0), D(7, 1), D(7, 2), D(7, 3), D(7, 4), D(7, 5), D(7, 6), D(7, 7),
+	D(8, 0), D(8, 1), D(8, 2), D(8, 3), D(8, 4), D(8, 5), D(8, 6), D(8, 7),
+	D(9, 0), D(9, 1), D(9, 2), D(9, 3), D(9, 4), D(9, 5), D(9, 6), D(9, 7),
+	D(10, 0), D(10, 1), D(10, 2), D(10, 3), D(10, 4), D(10, 5), D(10, 6), D(10, 7),
+};
+
+static const struct sppctl_grp sp7021grps_upex[] = {
+	EGRP("UPHY0_EXT", 1, pins_upex),
+};
+
+static const unsigned int pins_prp1[] = {
+	D(0, 6), D(0, 7),
+	D(1, 0), D(1, 1), D(1, 2), D(1, 3), D(1, 4), D(1, 5), D(1, 6), D(1, 7),
+	D(2, 1), D(2, 2), D(2, 3), D(2, 4), D(2, 5), D(2, 6), D(2, 7),
+	D(3, 0), D(3, 1), D(3, 2),
+};
+
+static const unsigned int pins_prp2[] = {
+	D(3, 4), D(3, 6), D(3, 7),
+	D(4, 0), D(4, 1), D(4, 2), D(4, 3), D(4, 4), D(4, 5), D(4, 6), D(4, 7),
+	D(5, 0), D(5, 1), D(5, 2), D(5, 3), D(5, 4), D(5, 5), D(5, 6), D(5, 7),
+	D(6, 4),
+};
+
+static const struct sppctl_grp sp7021grps_prbp[] = {
+	EGRP("PROBE_PORT1", 1, pins_prp1),
+	EGRP("PROBE_PORT2", 2, pins_prp2),
+};
+
+const struct sppctl_func sppctl_list_funcs[] = {
+	FNCN("L2SW_CLK_OUT",        pinmux_type_fpmx, 0x00, 0, 7),
+	FNCN("L2SW_MAC_SMI_MDC",    pinmux_type_fpmx, 0x00, 8, 7),
+	FNCN("L2SW_LED_FLASH0",     pinmux_type_fpmx, 0x01, 0, 7),
+	FNCN("L2SW_LED_FLASH1",     pinmux_type_fpmx, 0x01, 8, 7),
+	FNCN("L2SW_LED_ON0",        pinmux_type_fpmx, 0x02, 0, 7),
+	FNCN("L2SW_LED_ON1",        pinmux_type_fpmx, 0x02, 8, 7),
+	FNCN("L2SW_MAC_SMI_MDIO",   pinmux_type_fpmx, 0x03, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXEN",   pinmux_type_fpmx, 0x03, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXD0",   pinmux_type_fpmx, 0x04, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_TXD1",   pinmux_type_fpmx, 0x04, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_CRSDV",  pinmux_type_fpmx, 0x05, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXD0",   pinmux_type_fpmx, 0x05, 8, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXD1",   pinmux_type_fpmx, 0x06, 0, 7),
+	FNCN("L2SW_P0_MAC_RMII_RXER",   pinmux_type_fpmx, 0x06, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXEN",   pinmux_type_fpmx, 0x07, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXD0",   pinmux_type_fpmx, 0x07, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_TXD1",   pinmux_type_fpmx, 0x08, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_CRSDV",  pinmux_type_fpmx, 0x08, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXD0",   pinmux_type_fpmx, 0x09, 0, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXD1",   pinmux_type_fpmx, 0x09, 8, 7),
+	FNCN("L2SW_P1_MAC_RMII_RXER",   pinmux_type_fpmx, 0x0A, 0, 7),
+	FNCN("DAISY_MODE",      pinmux_type_fpmx, 0x0A, 8, 7),
+	FNCN("SDIO_CLK",        pinmux_type_fpmx, 0x0B, 0, 7),    /* 1x SDIO */
+	FNCN("SDIO_CMD",        pinmux_type_fpmx, 0x0B, 8, 7),
+	FNCN("SDIO_D0",         pinmux_type_fpmx, 0x0C, 0, 7),
+	FNCN("SDIO_D1",         pinmux_type_fpmx, 0x0C, 8, 7),
+	FNCN("SDIO_D2",         pinmux_type_fpmx, 0x0D, 0, 7),
+	FNCN("SDIO_D3",         pinmux_type_fpmx, 0x0D, 8, 7),
+	FNCN("PWM0",            pinmux_type_fpmx, 0x0E, 0, 7),    /* 8x PWM */
+	FNCN("PWM1",            pinmux_type_fpmx, 0x0E, 8, 7),
+	FNCN("PWM2",            pinmux_type_fpmx, 0x0F, 0, 7),
+	FNCN("PWM3",            pinmux_type_fpmx, 0x0F, 8, 7),
+
+	FNCN("PWM4",            pinmux_type_fpmx, 0x10, 0, 7),
+	FNCN("PWM5",            pinmux_type_fpmx, 0x10, 8, 7),
+	FNCN("PWM6",            pinmux_type_fpmx, 0x11, 0, 7),
+	FNCN("PWM7",            pinmux_type_fpmx, 0x11, 8, 7),
+	FNCN("ICM0_D",          pinmux_type_fpmx, 0x12, 0, 7),    /* 4x Input captures */
+	FNCN("ICM1_D",          pinmux_type_fpmx, 0x12, 8, 7),
+	FNCN("ICM2_D",          pinmux_type_fpmx, 0x13, 0, 7),
+	FNCN("ICM3_D",          pinmux_type_fpmx, 0x13, 8, 7),
+	FNCN("ICM0_CLK",        pinmux_type_fpmx, 0x14, 0, 7),
+	FNCN("ICM1_CLK",        pinmux_type_fpmx, 0x14, 8, 7),
+	FNCN("ICM2_CLK",        pinmux_type_fpmx, 0x15, 0, 7),
+	FNCN("ICM3_CLK",        pinmux_type_fpmx, 0x15, 8, 7),
+	FNCN("SPIM0_INT",       pinmux_type_fpmx, 0x16, 0, 7),    /* 4x SPI masters */
+	FNCN("SPIM0_CLK",       pinmux_type_fpmx, 0x16, 8, 7),
+	FNCN("SPIM0_EN",        pinmux_type_fpmx, 0x17, 0, 7),
+	FNCN("SPIM0_DO",        pinmux_type_fpmx, 0x17, 8, 7),
+	FNCN("SPIM0_DI",        pinmux_type_fpmx, 0x18, 0, 7),
+	FNCN("SPIM1_INT",       pinmux_type_fpmx, 0x18, 8, 7),
+	FNCN("SPIM1_CLK",       pinmux_type_fpmx, 0x19, 0, 7),
+	FNCN("SPIM1_EN",        pinmux_type_fpmx, 0x19, 8, 7),
+	FNCN("SPIM1_DO",        pinmux_type_fpmx, 0x1A, 0, 7),
+	FNCN("SPIM1_DI",        pinmux_type_fpmx, 0x1A, 8, 7),
+	FNCN("SPIM2_INT",       pinmux_type_fpmx, 0x1B, 0, 7),
+	FNCN("SPIM2_CLK",       pinmux_type_fpmx, 0x1B, 8, 7),
+	FNCN("SPIM2_EN",        pinmux_type_fpmx, 0x1C, 0, 7),
+	FNCN("SPIM2_DO",        pinmux_type_fpmx, 0x1C, 8, 7),
+	FNCN("SPIM2_DI",        pinmux_type_fpmx, 0x1D, 0, 7),
+	FNCN("SPIM3_INT",       pinmux_type_fpmx, 0x1D, 8, 7),
+	FNCN("SPIM3_CLK",       pinmux_type_fpmx, 0x1E, 0, 7),
+	FNCN("SPIM3_EN",        pinmux_type_fpmx, 0x1E, 8, 7),
+	FNCN("SPIM3_DO",        pinmux_type_fpmx, 0x1F, 0, 7),
+	FNCN("SPIM3_DI",        pinmux_type_fpmx, 0x1F, 8, 7),
+
+	FNCN("SPI0S_INT",       pinmux_type_fpmx, 0x20, 0, 7),    /* 4x SPI slaves */
+	FNCN("SPI0S_CLK",       pinmux_type_fpmx, 0x20, 8, 7),
+	FNCN("SPI0S_EN",        pinmux_type_fpmx, 0x21, 0, 7),
+	FNCN("SPI0S_DO",        pinmux_type_fpmx, 0x21, 8, 7),
+	FNCN("SPI0S_DI",        pinmux_type_fpmx, 0x22, 0, 7),
+	FNCN("SPI1S_INT",       pinmux_type_fpmx, 0x22, 8, 7),
+	FNCN("SPI1S_CLK",       pinmux_type_fpmx, 0x23, 0, 7),
+	FNCN("SPI1S_EN",        pinmux_type_fpmx, 0x23, 8, 7),
+	FNCN("SPI1S_DO",        pinmux_type_fpmx, 0x24, 0, 7),
+	FNCN("SPI1S_DI",        pinmux_type_fpmx, 0x24, 8, 7),
+	FNCN("SPI2S_INT",       pinmux_type_fpmx, 0x25, 0, 7),
+	FNCN("SPI2S_CLK",       pinmux_type_fpmx, 0x25, 8, 7),
+	FNCN("SPI2S_EN",        pinmux_type_fpmx, 0x26, 0, 7),
+	FNCN("SPI2S_DO",        pinmux_type_fpmx, 0x26, 8, 7),
+	FNCN("SPI2S_DI",        pinmux_type_fpmx, 0x27, 0, 7),
+	FNCN("SPI3S_INT",       pinmux_type_fpmx, 0x27, 8, 7),
+	FNCN("SPI3S_CLK",       pinmux_type_fpmx, 0x28, 0, 7),
+	FNCN("SPI3S_EN",        pinmux_type_fpmx, 0x28, 8, 7),
+	FNCN("SPI3S_DO",        pinmux_type_fpmx, 0x29, 0, 7),
+	FNCN("SPI3S_DI",        pinmux_type_fpmx, 0x29, 8, 7),
+	FNCN("I2CM0_CLK",       pinmux_type_fpmx, 0x2A, 0, 7),    /* 4x I2C masters */
+	FNCN("I2CM0_DAT",       pinmux_type_fpmx, 0x2A, 8, 7),
+	FNCN("I2CM1_CLK",       pinmux_type_fpmx, 0x2B, 0, 7),
+	FNCN("I2CM1_DAT",       pinmux_type_fpmx, 0x2B, 8, 7),
+	FNCN("I2CM2_CLK",       pinmux_type_fpmx, 0x2C, 0, 7),
+	FNCN("I2CM2_DAT",       pinmux_type_fpmx, 0x2C, 8, 7),
+	FNCN("I2CM3_CLK",       pinmux_type_fpmx, 0x2D, 0, 7),
+	FNCN("I2CM3_DAT",       pinmux_type_fpmx, 0x2D, 8, 7),
+	FNCN("UA1_TX",          pinmux_type_fpmx, 0x2E, 0, 7),    /* 4x UARTS */
+	FNCN("UA1_RX",          pinmux_type_fpmx, 0x2E, 8, 7),
+	FNCN("UA1_CTS",         pinmux_type_fpmx, 0x2F, 0, 7),
+	FNCN("UA1_RTS",         pinmux_type_fpmx, 0x2F, 8, 7),
+
+	FNCN("UA2_TX",          pinmux_type_fpmx, 0x30, 0, 7),
+	FNCN("UA2_RX",          pinmux_type_fpmx, 0x30, 8, 7),
+	FNCN("UA2_CTS",         pinmux_type_fpmx, 0x31, 0, 7),
+	FNCN("UA2_RTS",         pinmux_type_fpmx, 0x31, 8, 7),
+	FNCN("UA3_TX",          pinmux_type_fpmx, 0x32, 0, 7),
+	FNCN("UA3_RX",          pinmux_type_fpmx, 0x32, 8, 7),
+	FNCN("UA3_CTS",         pinmux_type_fpmx, 0x33, 0, 7),
+	FNCN("UA3_RTS",         pinmux_type_fpmx, 0x33, 8, 7),
+	FNCN("UA4_TX",          pinmux_type_fpmx, 0x34, 0, 7),
+	FNCN("UA4_RX",          pinmux_type_fpmx, 0x34, 8, 7),
+	FNCN("UA4_CTS",         pinmux_type_fpmx, 0x35, 0, 7),
+	FNCN("UA4_RTS",         pinmux_type_fpmx, 0x35, 8, 7),
+	FNCN("TIMER0_INT",      pinmux_type_fpmx, 0x36, 0, 7),    /* 4x timer int. */
+	FNCN("TIMER1_INT",      pinmux_type_fpmx, 0x36, 8, 7),
+	FNCN("TIMER2_INT",      pinmux_type_fpmx, 0x37, 0, 7),
+	FNCN("TIMER3_INT",      pinmux_type_fpmx, 0x37, 8, 7),
+	FNCN("GPIO_INT0",       pinmux_type_fpmx, 0x38, 0, 7),    /* 8x GPIO int. */
+	FNCN("GPIO_INT1",       pinmux_type_fpmx, 0x38, 8, 7),
+	FNCN("GPIO_INT2",       pinmux_type_fpmx, 0x39, 0, 7),
+	FNCN("GPIO_INT3",       pinmux_type_fpmx, 0x39, 8, 7),
+	FNCN("GPIO_INT4",       pinmux_type_fpmx, 0x3A, 0, 7),
+	FNCN("GPIO_INT5",       pinmux_type_fpmx, 0x3A, 8, 7),
+	FNCN("GPIO_INT6",       pinmux_type_fpmx, 0x3B, 0, 7),
+	FNCN("GPIO_INT7",       pinmux_type_fpmx, 0x3B, 8, 7),
+
+	/* MOON1 register */
+	FNCE("SPI_FLASH",       pinmux_type_grp, 0x01,  0, 2, sp7021grps_spif),
+	FNCE("SPI_FLASH_4BIT",  pinmux_type_grp, 0x01,  2, 2, sp7021grps_spi4),
+	FNCE("SPI_NAND",        pinmux_type_grp, 0x01,  4, 1, sp7021grps_snan),
+	FNCE("CARD0_EMMC",      pinmux_type_grp, 0x01,  5, 1, sp7021grps_emmc),
+	FNCE("SD_CARD",         pinmux_type_grp, 0x01,  6, 1, sp7021grps_sdsd),
+	FNCE("UA0",             pinmux_type_grp, 0x01,  7, 1, sp7021grps_uar0),
+	FNCE("ACHIP_DEBUG",     pinmux_type_grp, 0x01,  8, 2, sp7021grps_adbg),
+	FNCE("ACHIP_UA2AXI",    pinmux_type_grp, 0x01, 10, 2, sp7021grps_au2x),
+	FNCE("FPGA_IFX",        pinmux_type_grp, 0x01, 12, 1, sp7021grps_fpga),
+	FNCE("HDMI_TX",         pinmux_type_grp, 0x01, 13, 2, sp7021grps_hdmi),
+
+	FNCE("AUD_EXT_ADC_IFX0", pinmux_type_grp, 0x01, 15, 1, sp7021grps_eadc),
+	FNCE("AUD_EXT_DAC_IFX0", pinmux_type_grp, 0x02,  0, 1, sp7021grps_edac),
+	FNCE("SPDIF_RX",        pinmux_type_grp, 0x02,  2, 1, sp7021grps_spdi),
+	FNCE("SPDIF_TX",        pinmux_type_grp, 0x02,  3, 1, sp7021grps_spdo),
+	FNCE("TDMTX_IFX0",      pinmux_type_grp, 0x02,  4, 1, sp7021grps_tdmt),
+	FNCE("TDMRX_IFX0",      pinmux_type_grp, 0x02,  5, 1, sp7021grps_tdmr),
+	FNCE("PDMRX_IFX0",      pinmux_type_grp, 0x02,  6, 1, sp7021grps_pdmr),
+	FNCE("PCM_IEC_TX",      pinmux_type_grp, 0x02,  7, 1, sp7021grps_pcmt),
+	FNCE("LCDIF",           pinmux_type_grp, 0x04,  6, 1, sp7021grps_lcdi),
+	FNCE("DVD_DSP_DEBUG",   pinmux_type_grp, 0x02,  8, 1, sp7021grps_dvdd),
+	FNCE("I2C_DEBUG",       pinmux_type_grp, 0x02,  9, 1, sp7021grps_i2cd),
+	FNCE("I2C_SLAVE",       pinmux_type_grp, 0x02, 10, 1, sp7021grps_i2cs),
+	FNCE("WAKEUP",          pinmux_type_grp, 0x02, 11, 1, sp7021grps_wakp),
+	FNCE("UART2AXI",        pinmux_type_grp, 0x02, 12, 2, sp7021grps_u2ax),
+	FNCE("USB0_I2C",        pinmux_type_grp, 0x02, 14, 2, sp7021grps_u0ic),
+	FNCE("USB1_I2C",        pinmux_type_grp, 0x03,  0, 2, sp7021grps_u1ic),
+	FNCE("USB0_OTG",        pinmux_type_grp, 0x03,  2, 1, sp7021grps_u0ot),
+	FNCE("USB1_OTG",        pinmux_type_grp, 0x03,  3, 1, sp7021grps_u1ot),
+	FNCE("UPHY0_DEBUG",     pinmux_type_grp, 0x03,  4, 1, sp7021grps_up0d),
+	FNCE("UPHY1_DEBUG",     pinmux_type_grp, 0x03,  5, 1, sp7021grps_up1d),
+	FNCE("UPHY0_EXT",       pinmux_type_grp, 0x03,  6, 1, sp7021grps_upex),
+	FNCE("PROBE_PORT",      pinmux_type_grp, 0x03,  7, 2, sp7021grps_prbp),
+};
+
+const size_t sppctl_list_funcs_sz = ARRAY_SIZE(sppctl_list_funcs);
-- 
2.7.4



From mhiramat at kernel.org  Sun Jan 16 07:12:30 2022
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Mon, 17 Jan 2022 00:12:30 +0900
Subject: [PATCH v2 2/2] arm64: kprobes: add support for KPROBES_ON_FTRACE
In-Reply-To: <CAAgTQPWs0x_Hczc6ha5Cf2sVOYhAO91g-=79abi_+DWs9v-1kA@mail.gmail.com>
References: <1635858706-27320-1-git-send-email-jianhua.ljh@gmail.com>
 <1635858706-27320-2-git-send-email-jianhua.ljh@gmail.com>
 <20211217164019.7d5d9848f350fef4f709c62f@kernel.org>
 <CAAgTQPXi_cmi27upcLHgen3PotOtcu64oAxjYp559g6fYgkCvQ@mail.gmail.com>
 <20220107212046.13e55368664b31c2b41b7e94@kernel.org>
 <CAAgTQPWs0x_Hczc6ha5Cf2sVOYhAO91g-=79abi_+DWs9v-1kA@mail.gmail.com>
Message-ID: <20220117001230.4165178edfd2dcf5bdd8c4df@kernel.org>

On Sun, 16 Jan 2022 17:38:26 +0800
Jianhua Liu <jianhua.ljh at gmail.com> wrote:

> On Fri, Jan 7, 2022 at 8:20 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> >
> > On Fri, 7 Jan 2022 01:34:16 +0800
> > Jianhua Liu <jianhua.ljh at gmail.com> wrote:
> >
> > > On Fri, Dec 17, 2021 at 3:40 PM Masami Hiramatsu <mhiramat at kernel.org> wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Tue,  2 Nov 2021 21:11:46 +0800
> > > > Janet Liu <jianhua.ljh at gmail.com> wrote:
> > > >
> > > > > From: Janet Liu <janet.liu at unisoc.com>
> > > > >
> > > > > This patch allow kprobes on ftrace call sites. This optimization
> > > > > avoids use of a trap with regular kprobes.
> > > > >
> > > > > This depends on HAVE_DYNAMIC_FTRACE_WITH_REGS which depends on
> > > > > "patchable-function-entry" options which is only implemented with newer
> > > > > toolchains.
> > > > >
> > > > > Signed-off-by: Janet Liu <janet.liu at unisoc.com>
> > > > > ---
> > > > >  arch/arm64/Kconfig                 |  1 +
> > > > >  arch/arm64/kernel/probes/Makefile  |  1 +
> > > > >  arch/arm64/kernel/probes/ftrace.c  | 73 ++++++++++++++++++++++++++++++
> > > > >  arch/arm64/kernel/probes/kprobes.c | 27 +++++++++++
> > > > >  4 files changed, 102 insertions(+)
> > > > >  create mode 100644 arch/arm64/kernel/probes/ftrace.c
> > > > >
> > > > > diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> > > > > index 339130712093..f59005608976 100644
> > > > > --- a/arch/arm64/Kconfig
> > > > > +++ b/arch/arm64/Kconfig
> > > > > @@ -200,6 +200,7 @@ config ARM64
> > > > >       select HAVE_SYSCALL_TRACEPOINTS
> > > > >       select HAVE_KPROBES
> > > > >       select HAVE_OPTPROBES
> > > > > +     select HAVE_KPROBES_ON_FTRACE
> > > > >       select HAVE_KRETPROBES
> > > > >       select HAVE_GENERIC_VDSO
> > > > >       select IOMMU_DMA if IOMMU_SUPPORT
> > > > > diff --git a/arch/arm64/kernel/probes/Makefile b/arch/arm64/kernel/probes/Makefile
> > > > > index c77c92ac95fd..d9b204f4795a 100644
> > > > > --- a/arch/arm64/kernel/probes/Makefile
> > > > > +++ b/arch/arm64/kernel/probes/Makefile
> > > > > @@ -3,5 +3,6 @@ obj-$(CONFIG_KPROBES)         += kprobes.o decode-insn.o      \
> > > > >                                  kprobes_trampoline.o         \
> > > > >                                  simulate-insn.o
> > > > >  obj-$(CONFIG_OPTPROBES)      += opt.o opt_head.o
> > > > > +obj-$(CONFIG_KPROBES_ON_FTRACE) += ftrace.o
> > > > >  obj-$(CONFIG_UPROBES)                += uprobes.o decode-insn.o      \
> > > > >                                  simulate-insn.o
> > > > > diff --git a/arch/arm64/kernel/probes/ftrace.c b/arch/arm64/kernel/probes/ftrace.c
> > > > > new file mode 100644
> > > > > index 000000000000..46ea92eb552f
> > > > > --- /dev/null
> > > > > +++ b/arch/arm64/kernel/probes/ftrace.c
> > > > > @@ -0,0 +1,73 @@
> > > > > +// SPDX-License-Identifier: GPL-2.0-only
> > > > > +//
> > > > > +// Dynamic Ftrace based Kprobes Optimization
> > > > > +//
> > > > > +// Copyright (C) 2021, Unisoc Inc.
> > > > > +// Author: Janet Liu <janet.liu at unisoc.com>
> > > > > +#include <linux/kprobes.h>
> > > > > +#include <linux/ptrace.h>
> > > > > +#include <linux/hardirq.h>
> > > > > +#include <linux/preempt.h>
> > > > > +#include <linux/ftrace.h>
> > > > > +
> > > > > +
> > > > > +/* Ftrace callback handler for kprobes*/
> > > > > +void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > > > > +                        struct ftrace_ops *ops, struct ftrace_regs *fregs)
> > > > > +{
> > > > > +     struct kprobe *p;
> > > > > +     struct kprobe_ctlblk *kcb;
> > > > > +     struct pt_regs *regs = ftrace_get_regs(fregs);
> > > > > +     int bit;
> > > > > +
> > > > > +     bit = ftrace_test_recursion_trylock(ip, parent_ip);
> > > > > +     if (bit < 0)
> > > > > +             return;
> > > > > +
> > > > > +     preempt_disable_notrace();
> > > >
> > > > This already has been done in ftrace side.
> > >
> > > Hi Masami,
> > >
> > > Got it by reading code, will fix this.
> > >
> > > >
> > > > > +     p = get_kprobe((kprobe_opcode_t *)ip);
> > > > > +     if (unlikely(!p) || kprobe_disabled(p))
> > > > > +             goto end;
> > > > > +
> > > > > +     kcb = get_kprobe_ctlblk();
> > > > > +     if (kprobe_running()) {
> > > > > +             kprobes_inc_nmissed_count(p);
> > > > > +     } else {
> > > > > +             unsigned long orig_ip = instruction_pointer(regs);
> > > > > +
> > > > > +             instruction_pointer_set(regs, ip);
> > > >
> > > > The 'ip' is the address of the 'bl' instruction, which must be
> > > > p->addr + AARCH64_INSN_SIZE * 2. But this is a bit strange.
> > > >
> > > > On aarch64, if the user probe callback is called from breakpoint handler,
> > > > regs->pc == kp->addr. But in this case, it is not the same.
> > > >
> > > > So, what about this?
> > > >
> > > >  instruction_pointer_set(regs, ip - AARCH64_INSN_SIZE);
> > > >
> > >
> > > I got what you said.
> > >
> > > But p->addr is changed when KPROBES_ON_FTRACE enable.
> > > I implemented kprobe_lookup_name for arm64 to do the change in this patch.
> >
> > Hmm, that is no good, because printk("%pS\n", p->addr) does not show
> > what the user set by p->symbol_name. This may confuse user.
> > Moreover, if user doesn't set symbol_name but addr directly (this
> > happens when you use 'perf probe' command, which will pass the address
> > from '_text', not the function entry.
> >
> 
> Hi Masami,
> 
> Thanks for your explanation,if user doesn't set p->addr will not
> kprobe on ftrace entry.
> This also confuse me.

Yes, that's a headache point. This is because kprobes has two sides.
Kprobes itself should be the abstraction layer of software breakpoint,
but it also treated as an abstraction layer of flexible instrumentation.
KPROBE_ON_FTRACE feature had been introduced just for covering the
non-probable location because of ftrace. As you may know, x86 gcc
supports 'fentry' option for the ftrace, that made kprobes hard to
probe on the function entry address. To avoid this issue, I introduced
KPROBE_ON_FTRACE feature. But it also reduced overhead of the probing,
it was misunderstood as an optimization feature... (But NO, that is
just a side effect.)

Recently I started to make a 'fprobe' for function entry and exit
based on ftrace[1], thus I would like to recommend you to use it if
you intend to probe only on function entry and exit. That will
optimized for such use case.

[1] https://lore.kernel.org/all/164199616622.1247129.783024987490980883.stgit at devnote2/T/#u

And I want to keep KPROBE_ON_FTRACE as a user-nonvisible feature
for probing the ftrace location for kprobes. In this case, kprobe::addr
and kprobe::symbol_name always match. If kprobe user puts a probe on
function entry on arm64, it will keep using software breakpoint, but
if puts it on 'symbol+8', it will use ftrace to probe. That is my idea.

> 
> > > because kernel/kprobe.c:check_ftrace_location check,
> > > if p->addr != ftrace_addr, don't kprobe on ftrace entry.
> > > so p->addr is equal to ftrace addr(the second nop), is equal to 'ip'.
> > > here should be instruction_pointer_set(regs, ip);
> >
> > Hmm, OK. this is a special case for the arm64 (and maybe other
> > architectures except for x86). Let's fix the check_ftrace_location().
> > We already know that 2 instructions at the beginning of function will
> > be used for ftrace on arm64. Thus arm64 version of check_ftrace_location()
> > will check the given address + 1 is ftrace location or not.
> >
> > >
> > > > > +
> > > > > +             __this_cpu_write(current_kprobe, p);
> > > > > +             kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> > > > > +             if (!p->pre_handler || !p->pre_handler(p, regs)) {
> > > > > +                     /*
> > > > > +                      *Emulate singlestep (and also recover regs->pc)
> > > > > +                      *as if there is a nop
> > > > > +                      */
> > > > > +                     instruction_pointer_set(regs,
> > > > > +                                     (unsigned long)p->addr + MCOUNT_INSN_SIZE);
> > > >
> > > > And then, this will be
> > > >
> > > >                         instruction_pointer_set(regs,
> > > >                                         (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
> > > >
> > > > So basically, kprobes on ftrace will skips 2 NOP instructions (the compiler installed
> > > > 2 nops) and call post handler. This means we have a virtual big NOP instruction there.
> > > >
> > > Ditto, skip two nop instructions should
> > > instruction_pointer_set(regs,
> > >                         (unsigned long)p->addr + AARCH64_INSN_SIZE);
> > >
> > >
> > > > > +                     if (unlikely(p->post_handler)) {
> > > > > +                             kcb->kprobe_status = KPROBE_HIT_SSDONE;
> > > > > +                             p->post_handler(p, regs, 0);
> > > > > +                     }
> > > > > +                     instruction_pointer_set(regs, orig_ip);
> > > > > +             }
> > > > > +
> > > > > +             /*
> > > > > +              * If pre_handler returns !0,it changes regs->pc. We have to
> > > > > +              * skip emulating post_handler.
> > > > > +              */
> > > > > +             __this_cpu_write(current_kprobe, NULL);
> > > > > +     }
> > > > > +end:
> > > > > +     preempt_enable_notrace();
> > > > > +     ftrace_test_recursion_unlock(bit);
> > > > > +}
> > > > > +NOKPROBE_SYMBOL(kprobe_ftrace_handler);
> > > > > +
> > > > > +int arch_prepare_kprobe_ftrace(struct kprobe *p)
> > > > > +{
> > > > > +     p->ainsn.api.insn = NULL;
> > > > > +     p->ainsn.api.restore = 0;
> > > > > +     return 0;
> > > > > +}
> > > > > diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> > > > > index 6dbcc89f6662..3d371d3e4dfa 100644
> > > > > --- a/arch/arm64/kernel/probes/kprobes.c
> > > > > +++ b/arch/arm64/kernel/probes/kprobes.c
> > > > > @@ -417,6 +417,33 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
> > > > >       return 0;
> > > > >  }
> > > > >
> > > > > +kprobe_opcode_t __kprobes *kprobe_lookup_name(const char *name, unsigned int offset)
> > > > > +{
> > > > > +     kprobe_opcode_t *addr;
> > > > > +
> > > > > +     addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
> > > > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > > > +     if (addr && !offset) {
> > > > > +             unsigned long faddr;
> > > > > +
> > > > > +             faddr = ftrace_location_range((unsigned long)addr,
> > > > > +                                           (unsigned long)addr + 8);
> > > >
> > > > this '8' must be (AARCH64_INSN_SIZE * 2). And here you may need to add
> > > > a comment why search the 2 instructions. (it is because arm64 uses
> > > > -fpatchable-function-entry=2.)
> > > >
> > > Got it , will fix it.
> > > > > +             if (faddr)
> > > > > +                     addr = (kprobe_opcode_t *)faddr;
> > > > > +     }
> > > This change the p->addr to ftrace_addr.
> >
> > Ah, OK. Please forgot above. What we have to do is to change the
> > check_ftrace_location(), not this conversion.
> 
> I don't do this conversion, and try to implement arm64 special
> check_ftrace_location as following.
> but register kprobe fail.

Yes, it was not a good solution. Sorry.

Thank you,

> 
> diff --git a/arch/arm64/kernel/probes/kprobes.c
> b/arch/arm64/kernel/probes/kprobes.c
> index d9dfa82c1f18..609f3f103a89 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> +int __kprobes check_ftrace_location(struct kprobe *p)
> +{
> +        unsigned long ftrace_addr;
> +
> +        ftrace_addr = ftrace_location_range((unsigned long)p->addr,
> +                               (unsigned long)p->addr + AARCH64_INSN_SIZE * 2);
> +        if (ftrace_addr) {
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> +                /* Given address is not on the instruction boundary */
> +                if ((unsigned long)p->addr > ftrace_addr)
> +                        return -EILSEQ;
> +               if (p->offset <= AARCH64_INSN_SIZE * 2)
> +                       p->flags |= KPROBE_FLAG_FTRACE;
> +#else   /* !CONFIG_KPROBES_ON_FTRACE */
> +                return -EINVAL;
> +#endif
> +        }
> +        return 0;
> +}
> +
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 21eccc961bba..91c95ba4eed0 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1539,7 +1539,7 @@ static inline int warn_kprobe_rereg(struct kprobe *p)
>         return ret;
>  }
> 
> -static int check_ftrace_location(struct kprobe *p)
> +int __weak check_ftrace_location(struct kprobe *p)
>  {
>         unsigned long ftrace_addr;
> 
> 
> __arm_kprobe_ftrace print fail info:
> [   38.286515] Failed to arm kprobe-ftrace at kernel_clone+0x0/0x440 (error -22)
> [   38.286606] WARNING: CPU: 3 PID: 341 at kernel/kprobes.c:1062
> arm_kprobe+0x114/0x14c
> 
> __arm_kprobe_ftrace calls ftrace_set_filter_ip,
> ftrace_set_filter_ip use p->addr, but failed.
> 
> Thanks
> Jianhua
> 
> >
> > Thank you,
> >
> > >
> > > > > +#endif
> > > > > +     return addr;
> > > > > +}
> > > > > +
> > > > > +bool __kprobes arch_kprobe_on_func_entry(unsigned long offset)
> > > > > +{
> > > > > +#ifdef CONFIG_KPROBES_ON_FTRACE
> > > > > +     return offset <= 8;
> > > >
> > > > Ditto.
> > > Got it, will add comment.
> > >
> > > Thanks
> > >
> > > Jianhua
> > > >
> > > > > +#else
> > > > > +     return !offset;
> > > > > +#endif
> > > > > +}
> > > > > +
> > > > >  int __init arch_init_kprobes(void)
> > > > >  {
> > > > >       register_kernel_break_hook(&kprobes_break_hook);
> > > > > --
> > > > > 2.25.1
> > > > >
> > > >
> > > > Thank you,
> > > >
> > > >
> > > > --
> > > > Masami Hiramatsu <mhiramat at kernel.org>
> >
> >
> > --
> > Masami Hiramatsu <mhiramat at kernel.org>


-- 
Masami Hiramatsu <mhiramat at kernel.org>


From alim.akhtar at gmail.com  Sun Jan 16 07:28:16 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Sun, 16 Jan 2022 20:58:16 +0530
Subject: [PATCH v3 1/4] ARM: dts: exynos: split dmas into array of
 phandles in Exynos5250
In-Reply-To: <20220112100046.68068-2-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ521MhOb+rv+NPCOJq60+CrpsmRR6boWUK5tc_H5wXDmFw@mail.gmail.com>

On Thu, Jan 13, 2022 at 4:19 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> "dmas" property should be rather an array of phandles, as dtschema
> points.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Andi Shyti <andi at etezian.org>
> ---

 Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
> index 139778928b93..102bb57bf704 100644
> --- a/arch/arm/boot/dts/exynos5250.dtsi
> +++ b/arch/arm/boot/dts/exynos5250.dtsi
> @@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
>                         status = "disabled";
>                         reg = <0x12d20000 0x100>;
>                         interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
> -                       dmas = <&pdma0 5
> -                               &pdma0 4>;
> +                       dmas = <&pdma0 5>, <&pdma0 4>;
>                         dma-names = "tx", "rx";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> @@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
>                         status = "disabled";
>                         reg = <0x12d30000 0x100>;
>                         interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
> -                       dmas = <&pdma1 5
> -                               &pdma1 4>;
> +                       dmas = <&pdma1 5>, <&pdma1 4>;
>                         dma-names = "tx", "rx";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> @@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
>                         status = "disabled";
>                         reg = <0x12d40000 0x100>;
>                         interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
> -                       dmas = <&pdma0 7
> -                               &pdma0 6>;
> +                       dmas = <&pdma0 7>, <&pdma0 6>;
>                         dma-names = "tx", "rx";
>                         #address-cells = <1>;
>                         #size-cells = <0>;
> --
> 2.32.0
>


-- 
Regards,
Alim


From alim.akhtar at gmail.com  Sun Jan 16 07:34:49 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Sun, 16 Jan 2022 21:04:49 +0530
Subject: [PATCH v2 18/28] arm64: dts: exynos: align pinctrl with dtschema
 in Exynos7
In-Reply-To: <20220111201722.327219-12-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-12-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ53ebXqs0BO_CpFHEab5=GgD1hDER9zX7P3dhM7Z9fJGMA@mail.gmail.com>

Hi Krzystof

On Wed, Jan 12, 2022 at 1:48 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Align the pin controller related nodes with dtschema.  No functional
> change expected.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

>  .../boot/dts/exynos/exynos7-espresso.dts      |   6 +-
>  .../boot/dts/exynos/exynos7-pinctrl.dtsi      | 176 +++++++++---------
>  2 files changed, 91 insertions(+), 91 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> index 125c03f351d9..2826bafade8a 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> @@ -354,7 +354,7 @@ buck10_reg: BUCK10 {
>  };
>
>  &pinctrl_alive {
> -       pmic_irq: pmic-irq {
> +       pmic_irq: pmic-irq-pins {
>                 samsung,pins = "gpa0-2";
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
> @@ -393,14 +393,14 @@ &mmc_2 {
>  };
>
>  &pinctrl_bus1 {
> -       usb30_vbus_en: usb30-vbus-en {
> +       usb30_vbus_en: usb30-vbus-en-pins {
>                 samsung,pins = "gph1-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       usb3drd_boost_en: usb3drd-boost-en {
> +       usb3drd_boost_en: usb3drd-boost-en-pins {
>                 samsung,pins = "gpf4-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_OUTPUT>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> index 472dd649aa7e..be9b971f3697 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi
> @@ -12,7 +12,7 @@
>  #include <dt-bindings/pinctrl/samsung.h>
>
>  &pinctrl_alive {
> -       gpa0: gpa0 {
> +       gpa0: gpa0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -29,7 +29,7 @@ gpa0: gpa0 {
>                              <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa1: gpa1 {
> +       gpa1: gpa1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -46,7 +46,7 @@ gpa1: gpa1 {
>                              <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
>         };
>
> -       gpa2: gpa2 {
> +       gpa2: gpa2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -54,7 +54,7 @@ gpa2: gpa2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpa3: gpa3 {
> +       gpa3: gpa3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -64,7 +64,7 @@ gpa3: gpa3 {
>  };
>
>  &pinctrl_bus0 {
> -       gpb0: gpb0 {
> +       gpb0: gpb0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -72,7 +72,7 @@ gpb0: gpb0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpc0: gpc0 {
> +       gpc0: gpc0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -80,7 +80,7 @@ gpc0: gpc0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpc1: gpc1 {
> +       gpc1: gpc1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -88,7 +88,7 @@ gpc1: gpc1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpc2: gpc2 {
> +       gpc2: gpc2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -96,7 +96,7 @@ gpc2: gpc2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpc3: gpc3 {
> +       gpc3: gpc3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -104,7 +104,7 @@ gpc3: gpc3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd0: gpd0 {
> +       gpd0: gpd0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -112,7 +112,7 @@ gpd0: gpd0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd1: gpd1 {
> +       gpd1: gpd1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -120,7 +120,7 @@ gpd1: gpd1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd2: gpd2 {
> +       gpd2: gpd2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -128,7 +128,7 @@ gpd2: gpd2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd4: gpd4 {
> +       gpd4: gpd4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -136,7 +136,7 @@ gpd4: gpd4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd5: gpd5 {
> +       gpd5: gpd5-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -144,7 +144,7 @@ gpd5: gpd5 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd6: gpd6 {
> +       gpd6: gpd6-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -152,7 +152,7 @@ gpd6: gpd6 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd7: gpd7 {
> +       gpd7: gpd7-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -160,7 +160,7 @@ gpd7: gpd7 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpd8: gpd8 {
> +       gpd8: gpd8-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -168,7 +168,7 @@ gpd8: gpd8 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg0: gpg0 {
> +       gpg0: gpg0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -176,7 +176,7 @@ gpg0: gpg0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg3: gpg3 {
> +       gpg3: gpg3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -184,161 +184,161 @@ gpg3: gpg3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       hs_i2c10_bus: hs-i2c10-bus {
> +       hs_i2c10_bus: hs-i2c10-bus-pins {
>                 samsung,pins = "gpb0-1", "gpb0-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c11_bus: hs-i2c11-bus {
> +       hs_i2c11_bus: hs-i2c11-bus-pins {
>                 samsung,pins = "gpb0-3", "gpb0-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c2_bus: hs-i2c2-bus {
> +       hs_i2c2_bus: hs-i2c2-bus-pins {
>                 samsung,pins = "gpd0-3", "gpd0-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart0_data: uart0-data {
> +       uart0_data: uart0-data-pins {
>                 samsung,pins = "gpd0-0", "gpd0-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart0_fctl: uart0-fctl {
> +       uart0_fctl: uart0-fctl-pins {
>                 samsung,pins = "gpd0-2", "gpd0-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart2_data: uart2-data {
> +       uart2_data: uart2-data-pins {
>                 samsung,pins = "gpd1-4", "gpd1-5";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c3_bus: hs-i2c3-bus {
> +       hs_i2c3_bus: hs-i2c3-bus-pins {
>                 samsung,pins = "gpd1-3", "gpd1-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart1_data: uart1-data {
> +       uart1_data: uart1-data-pins {
>                 samsung,pins = "gpd1-0", "gpd1-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart1_fctl: uart1-fctl {
> +       uart1_fctl: uart1-fctl-pins {
>                 samsung,pins = "gpd1-2", "gpd1-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c0_bus: hs-i2c0-bus {
> +       hs_i2c0_bus: hs-i2c0-bus-pins {
>                 samsung,pins = "gpd2-1", "gpd2-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c1_bus: hs-i2c1-bus {
> +       hs_i2c1_bus: hs-i2c1-bus-pins {
>                 samsung,pins = "gpd2-3", "gpd2-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c9_bus: hs-i2c9-bus {
> +       hs_i2c9_bus: hs-i2c9-bus-pins {
>                 samsung,pins = "gpd2-7", "gpd2-6";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       pwm0_out: pwm0-out {
> +       pwm0_out: pwm0-out-pins {
>                 samsung,pins = "gpd2-4";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       pwm1_out: pwm1-out {
> +       pwm1_out: pwm1-out-pins {
>                 samsung,pins = "gpd2-5";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       pwm2_out: pwm2-out {
> +       pwm2_out: pwm2-out-pins {
>                 samsung,pins = "gpd2-6";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       pwm3_out: pwm3-out {
> +       pwm3_out: pwm3-out-pins {
>                 samsung,pins = "gpd2-7";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c8_bus: hs-i2c8-bus {
> +       hs_i2c8_bus: hs-i2c8-bus-pins {
>                 samsung,pins = "gpd5-3", "gpd5-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       uart3_data: uart3-data {
> +       uart3_data: uart3-data-pins {
>                 samsung,pins = "gpd5-0", "gpd5-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_3>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       spi2_bus: spi2-bus {
> +       spi2_bus: spi2-bus-pins {
>                 samsung,pins = "gpd5-0", "gpd5-1", "gpd5-2", "gpd5-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       spi1_bus: spi1-bus {
> +       spi1_bus: spi1-bus-pins {
>                 samsung,pins = "gpd6-2", "gpd6-3", "gpd6-4", "gpd6-5";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       spi0_bus: spi0-bus {
> +       spi0_bus: spi0-bus-pins {
>                 samsung,pins = "gpd8-0", "gpd8-1", "gpd6-0", "gpd6-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c4_bus: hs-i2c4-bus {
> +       hs_i2c4_bus: hs-i2c4-bus-pins {
>                 samsung,pins = "gpg3-1", "gpg3-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       hs_i2c5_bus: hs-i2c5-bus {
> +       hs_i2c5_bus: hs-i2c5-bus-pins {
>                 samsung,pins = "gpg3-3", "gpg3-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -347,7 +347,7 @@ hs_i2c5_bus: hs-i2c5-bus {
>  };
>
>  &pinctrl_nfc {
> -       gpj0: gpj0 {
> +       gpj0: gpj0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -355,7 +355,7 @@ gpj0: gpj0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       hs_i2c6_bus: hs-i2c6-bus {
> +       hs_i2c6_bus: hs-i2c6-bus-pins {
>                 samsung,pins = "gpj0-1", "gpj0-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -364,7 +364,7 @@ hs_i2c6_bus: hs-i2c6-bus {
>  };
>
>  &pinctrl_touch {
> -       gpj1: gpj1 {
> +       gpj1: gpj1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -372,7 +372,7 @@ gpj1: gpj1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       hs_i2c7_bus: hs-i2c7-bus {
> +       hs_i2c7_bus: hs-i2c7-bus-pins {
>                 samsung,pins = "gpj1-1", "gpj1-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -381,7 +381,7 @@ hs_i2c7_bus: hs-i2c7-bus {
>  };
>
>  &pinctrl_ff {
> -       gpg4: gpg4 {
> +       gpg4: gpg4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -389,7 +389,7 @@ gpg4: gpg4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       spi3_bus: spi3-bus {
> +       spi3_bus: spi3-bus-pins {
>                 samsung,pins = "gpg4-0", "gpg4-1", "gpg4-2", "gpg4-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -398,7 +398,7 @@ spi3_bus: spi3-bus {
>  };
>
>  &pinctrl_ese {
> -       gpv7: gpv7 {
> +       gpv7: gpv7-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -406,7 +406,7 @@ gpv7: gpv7 {
>                 #interrupt-cells = <2>;
>         };
>
> -       spi4_bus: spi4-bus {
> +       spi4_bus: spi4-bus-pins {
>                 samsung,pins = "gpv7-0", "gpv7-1", "gpv7-2", "gpv7-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -415,7 +415,7 @@ spi4_bus: spi4-bus {
>  };
>
>  &pinctrl_fsys0 {
> -       gpr4: gpr4 {
> +       gpr4: gpr4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -423,35 +423,35 @@ gpr4: gpr4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       sd2_clk: sd2-clk {
> +       sd2_clk: sd2-clk-pins {
>                 samsung,pins = "gpr4-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
>         };
>
> -       sd2_cmd: sd2-cmd {
> +       sd2_cmd: sd2-cmd-pins {
>                 samsung,pins = "gpr4-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
>         };
>
> -       sd2_cd: sd2-cd {
> +       sd2_cd: sd2-cd-pins {
>                 samsung,pins = "gpr4-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
>         };
>
> -       sd2_bus1: sd2-bus-width1 {
> +       sd2_bus1: sd2-bus-width1-pins {
>                 samsung,pins = "gpr4-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV4>;
>         };
>
> -       sd2_bus4: sd2-bus-width4 {
> +       sd2_bus4: sd2-bus-width4-pins {
>                 samsung,pins = "gpr4-4", "gpr4-5", "gpr4-6";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -460,7 +460,7 @@ sd2_bus4: sd2-bus-width4 {
>  };
>
>  &pinctrl_fsys1 {
> -       gpr0: gpr0 {
> +       gpr0: gpr0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -468,7 +468,7 @@ gpr0: gpr0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpr1: gpr1 {
> +       gpr1: gpr1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -476,7 +476,7 @@ gpr1: gpr1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpr2: gpr2 {
> +       gpr2: gpr2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -484,7 +484,7 @@ gpr2: gpr2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpr3: gpr3 {
> +       gpr3: gpr3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -492,105 +492,105 @@ gpr3: gpr3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       sd0_clk: sd0-clk {
> +       sd0_clk: sd0-clk-pins {
>                 samsung,pins = "gpr0-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_cmd: sd0-cmd {
> +       sd0_cmd: sd0-cmd-pins {
>                 samsung,pins = "gpr0-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_ds: sd0-ds {
> +       sd0_ds: sd0-ds-pins {
>                 samsung,pins = "gpr0-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_qrdy: sd0-qrdy {
> +       sd0_qrdy: sd0-qrdy-pins {
>                 samsung,pins = "gpr0-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_bus1: sd0-bus-width1 {
> +       sd0_bus1: sd0-bus-width1-pins {
>                 samsung,pins = "gpr1-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_bus4: sd0-bus-width4 {
> +       sd0_bus4: sd0-bus-width4-pins {
>                 samsung,pins = "gpr1-1", "gpr1-2", "gpr1-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd0_bus8: sd0-bus-width8 {
> +       sd0_bus8: sd0-bus-width8-pins {
>                 samsung,pins = "gpr1-4", "gpr1-5", "gpr1-6", "gpr1-7";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV2>;
>         };
>
> -       sd1_clk: sd1-clk {
> +       sd1_clk: sd1-clk-pins {
>                 samsung,pins = "gpr2-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
>         };
>
> -       sd1_cmd: sd1-cmd {
> +       sd1_cmd: sd1-cmd-pins {
>                 samsung,pins = "gpr2-1";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
>         };
>
> -       sd1_ds: sd1-ds {
> +       sd1_ds: sd1-ds-pins {
>                 samsung,pins = "gpr2-2";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
>         };
>
> -       sd1_qrdy: sd1-qrdy {
> +       sd1_qrdy: sd1-qrdy-pins {
>                 samsung,pins = "gpr2-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
>         };
>
> -       sd1_int: sd1-int {
> +       sd1_int: sd1-int-pins {
>                 samsung,pins = "gpr2-4";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_DOWN>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV4>;
>         };
>
> -       sd1_bus1: sd1-bus-width1 {
> +       sd1_bus1: sd1-bus-width1-pins {
>                 samsung,pins = "gpr3-0";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
>         };
>
> -       sd1_bus4: sd1-bus-width4 {
> +       sd1_bus4: sd1-bus-width4-pins {
>                 samsung,pins = "gpr3-1", "gpr3-2", "gpr3-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS7_FSYS1_PIN_DRV_LV3>;
>         };
>
> -       sd1_bus8: sd1-bus-width8 {
> +       sd1_bus8: sd1-bus-width8-pins {
>                 samsung,pins = "gpr3-4", "gpr3-5", "gpr3-6", "gpr3-7";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> @@ -599,7 +599,7 @@ sd1_bus8: sd1-bus-width8 {
>  };
>
>  &pinctrl_bus1 {
> -       gpf0: gpf0 {
> +       gpf0: gpf0-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -607,7 +607,7 @@ gpf0: gpf0 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf1: gpf1 {
> +       gpf1: gpf1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -615,7 +615,7 @@ gpf1: gpf1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf2: gpf2 {
> +       gpf2: gpf2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -623,7 +623,7 @@ gpf2: gpf2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf3: gpf3 {
> +       gpf3: gpf3-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -631,7 +631,7 @@ gpf3: gpf3 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf4: gpf4 {
> +       gpf4: gpf4-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -639,7 +639,7 @@ gpf4: gpf4 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpf5: gpf5 {
> +       gpf5: gpf5-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -647,7 +647,7 @@ gpf5: gpf5 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg1: gpg1 {
> +       gpg1: gpg1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -655,7 +655,7 @@ gpg1: gpg1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpg2: gpg2 {
> +       gpg2: gpg2-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -663,7 +663,7 @@ gpg2: gpg2 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gph1: gph1 {
> +       gph1: gph1-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -671,7 +671,7 @@ gph1: gph1 {
>                 #interrupt-cells = <2>;
>         };
>
> -       gpv6: gpv6 {
> +       gpv6: gpv6-gpio-bank {
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> @@ -679,21 +679,21 @@ gpv6: gpv6 {
>                 #interrupt-cells = <2>;
>         };
>
> -       spi5_bus: spi5-bus {
> +       spi5_bus: spi5-bus-pins {
>                 samsung,pins = "gpf2-0", "gpf2-1", "gpf2-2", "gpf2-3";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>         };
>
> -       ufs_refclk_out: ufs-refclk-out {
> +       ufs_refclk_out: ufs-refclk-out-pins {
>                 samsung,pins = "gpg2-4";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>                 samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
>         };
>
> -       ufs_rst_n: ufs-rst-n {
> +       ufs_rst_n: ufs-rst-n-pins {
>                 samsung,pins = "gph1-5";
>                 samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>                 samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> --
> 2.32.0
>


-- 
Regards,
Alim


From henrik at grimler.se  Sun Jan 16 08:50:32 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 16 Jan 2022 17:50:32 +0100
Subject: [PATCH v3 0/3] Add initial support for exynos5420-chagall-wifi
Message-ID: <20220116165035.437274-1-henrik@grimler.se>

Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename Chagall WiFi
and is one of several tablets released in 2014 based on Exynos 5420.
This initial devicetree adds support for accessing device over USB or
UART, and allows using a rootfs in either the internal eMMC or an
external sdcard.  4 out of 8 CPUs are brought up when device boots,
which is the same as on the somewhat similar board
exynos5420-arndale-octa.

Patch 2 is necessary after a secure-firmware node is added, otherwise
device hangs during the CPU1BOOT secure monitor call. Without the
secure-firmware node we are not able to bring up any secondary CPUs.

Changes since v2
================

Addressing Krzysztof's feedback:
* chagallwifi -> chagall-wifi and Chagall WiFi in messages and comments
* Re-write commit message for patch 3, use commit hash and ("subject"),
  move hint about bootloader issue to galaxy-tab-common.dtsi
* Fix s2mps11 regulator nodes, use &ldoXX_reg handle for device customisation
* Re-add usbdrd supplies (works after fixing regulator nodes)
* Remove unnecessary, duplicate, compatible in galaxy-tab-common.dtsi
* Remove extra clocks xxti and xusbxti
* Prefix key- to gpio-keys
* Add pinctrl pins to mmc_2. card-detect pin is different than for other
  Exynos 5420 devices, so define and use mmc2_cd node under pinctrl_0

Additional changes:
* Add/fix supplies of mmc_0 and mmc_2 (vmmc-supply for mmc0 is unknown)
* Sort mmc_X properties alphabetically
* Fix IRQ pin for s2mps11, it was wrong (gpx3-2 -> gpx3-0)
* Mark LDO31 as varying between devices as well, it differs between WiFi
  and LTE tablet versions
* Fix typo for LDO5 (regulato-name -> regulator-name)
* Remove regulator-ramp-delay from buck regulators, based on
  exynos5420-arndale-octa there should be no need to set it

Changes since v1
================

Fix mmc_0 and usbdrd in patch 3:
* Remove extra, non supported, options from mmc_0 node
* Do not set usbdrd supplies. Usb networking does not work with them
  specified, but it works fine with dummy regulators


Henrik Grimler (3):
  dt-bindings: arm: samsung: document Chagall WiFi board binding
  ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
  ARM: dts: Add support for Samsung Chagall WiFi

 .../bindings/arm/samsung/samsung-boards.yaml  |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  65 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 666 ++++++++++++++++++
 arch/arm/mach-exynos/firmware.c               |   4 +-
 5 files changed, 736 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

-- 
2.34.1



From henrik at grimler.se  Sun Jan 16 08:50:33 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 16 Jan 2022 17:50:33 +0100
Subject: [PATCH v3 1/3] dt-bindings: arm: samsung: document Chagall WiFi board
 binding
In-Reply-To: <20220116165035.437274-1-henrik@grimler.se>
References: <20220116165035.437274-1-henrik@grimler.se>
Message-ID: <20220116165035.437274-2-henrik@grimler.se>

Add binding for Samsung Galaxy Tab S 10.5", based on Exynos 5420 with
codename chagall-wifi. It was released in 2014 and has several siblings
with similar hardware.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 052cd94113d4..a2a8bf44fe9b 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -140,6 +140,7 @@ properties:
         items:
           - enum:
               - insignal,arndale-octa           # Insignal Arndale Octa
+              - samsung,chagall-wifi            # Samsung SM-T800
               - samsung,smdk5420                # Samsung SMDK5420 eval
           - const: samsung,exynos5420
           - const: samsung,exynos5
-- 
2.34.1



From henrik at grimler.se  Sun Jan 16 08:50:34 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 16 Jan 2022 17:50:34 +0100
Subject: [PATCH v3 2/3] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
In-Reply-To: <20220116165035.437274-1-henrik@grimler.se>
References: <20220116165035.437274-1-henrik@grimler.se>
Message-ID: <20220116165035.437274-3-henrik@grimler.se>

On Exynos5 the call is simply ignored by most variants of the
trustzone firmware.  However, on some devices it instead causes the
device to hang, so let's avoid the call for the SoCs where it should
not be needed.

To see that the call is ignored, we can look into sboot/tzsw.  On most
of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
the secure monitor calls is quite easy to recognise, the SMC number is
compared to known ones, and if equal it branches to the relevant
function.  In assembly this looks something like:

;-- handle_smc:
0x00000514      650070e3       cmn r0, 0x65
0x00000518      0a00000a       beq loc.smc_cmd_reg
0x0000051c      010070e3       cmn r0, 1
0x00000520      6c00000a       beq loc.smc_cmd_init
0x00000524      020070e3       cmn r0, 2
0x00000528      6b00000a       beq loc.smc_cmd_info
0x0000052c      030070e3       cmn r0, 3
0x00000530      6e00000a       beq loc.smc_cmd_sleep
0x00000534      060070e3       cmn r0, 6
0x00000538      ae00000a       beq loc.smc_cmd_save_state
0x0000053c      070070e3       cmn r0, 7
0x00000540      b400000a       beq loc.smc_cmd_standby
0x00000544      2b01001a       bne loc.smc_return_minus1

where above example is from exynos5420-arndale-octa.  As can be seen
the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
annotations are taken from github.com/hsnaves/exynos5410-firmware,
where a large part of the exynos5410 trustzone firmware has been
reverse-engineered.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
Sent previously as RFC
---
 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
 	/*
 	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
 	 * because Exynos3250 removes WFE in secure mode.
+	 *
+	 * On Exynos5 devices the call is ignored by trustzone firmware.
 	 */
-	if (soc_is_exynos3250())
+	if (!soc_is_exynos4210() && !soc_is_exynos4412())
 		return 0;
 
 	/*
-- 
2.34.1



From henrik at grimler.se  Sun Jan 16 08:50:35 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 16 Jan 2022 17:50:35 +0100
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <20220116165035.437274-1-henrik@grimler.se>
References: <20220116165035.437274-1-henrik@grimler.se>
Message-ID: <20220116165035.437274-4-henrik@grimler.se>

Chagall WiFi, with product name Samsung Galaxy Tab S 10.5", is based
on Exynos 5420.  This device is one of several tablet models released
in 2014 based on Exynos 5420.

The device tree added here contains support for:

- UART
- eMMC
- SD card
- USB

CCI has been disabled in the hardware, enabling it would require
(de-)soldering a resistor on the board.  Trying to boot with it
enabled in kernel makes the device hang when CCI is probed.
Exynos5420-arndale-octa also has had CCI disabled due to issues, see
commit 25217fef3551 ("ARM: dts: disable CCI on exynos5420 based
arndale-octa").

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  65 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 666 ++++++++++++++++++
 3 files changed, 732 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..088fcedb3212 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-arndale-octa.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5420-smdk5420.dtb \
+	exynos5420-chagall-wifi.dtb \
 	exynos5422-odroidhc1.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
diff --git a/arch/arm/boot/dts/exynos5420-chagall-wifi.dts b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
new file mode 100644
index 000000000000..2cc5cd01e8c6
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Chagall WiFi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+	model = "Samsung Chagall WiFi based on Exynos5420";
+	compatible = "samsung,chagall-wifi", "samsung,exynos5420", \
+		     "samsung,exynos5";
+};
+
+&ldo15_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO15";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&ldo17_reg {
+	regulator-name = "VDD_IRLED_3V3";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3350000>;
+	regulator-always-on;
+	regulator-boot-on;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo28_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO28";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&ldo29_reg {
+	regulator-name = "VDD_TCON_1V8";
+	regulator-min-microvolt = <1900000>;
+	regulator-max-microvolt = <1900000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo31_reg {
+	regulator-name = "VDD_GRIP_1V8";
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-always-on;
+	regulator-boot-on;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
new file mode 100644
index 000000000000..119e4e7a8328
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
@@ -0,0 +1,666 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base DT for Samsung's family of tablets based on Exynos5420.
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include "exynos5420-cpus.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/samsung,s2mps11.h>
+
+/ {
+	chassis-type = "tablet";
+
+	/*
+	 * To successfully boot the mainline kernel with the stock
+	 * bootloader (SBOOT), the tlb needs to be flushed after the
+	 * page table pointer has been updated in __common_mmu_cache_on.
+	 * The same hack is also needed to boot exynos4412-i9300 with
+	 * stock bootloader, and probably other Samsung devices of
+	 * similar age.  See
+	 * https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com
+	 * for more details.
+	 */
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x20000000 0xc0000000>;
+	};
+
+	firmware at 2073000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x02073000 0x1000>;
+	};
+
+	fixed-rate-clocks {
+		oscclk {
+			compatible = "samsung,exynos5420-oscclk";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+
+		key-power {
+			debounce-interval = <10>;
+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+
+		key-home {
+			debounce-interval = <10>;
+			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
+			label = "Home";
+			linux,code = <KEY_HOME>;
+			wakeup-source;
+		};
+
+		key-volume-up {
+			debounce-interval = <10>;
+			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		key-volume-down {
+			debounce-interval = <10>;
+			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+};
+
+&cci {
+	/* CCI is disabled in hardware */
+	status = "disabled";
+};
+
+&cpu0 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&buck6_reg>;
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&buck4_reg>;
+};
+
+&hsi2c_7 {
+	status = "okay";
+
+	pmic at 66 {
+		compatible = "samsung,s2mps11-pmic";
+		reg = <0x66>;
+
+		interrupt-parent = <&gpx3>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&s2mps11_irq>;
+
+		s2mps11_osc: clocks {
+			compatible = "samsung,s2mps11-clk";
+			#clock-cells = <1>;
+			clock-output-names = "s2mps11_ap", "s2mps11_cp",
+					     "s2mps11_bt";
+		};
+
+		regulators {
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_MIF_1V1";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck2_reg: BUCK2 {
+				regulator-name = "VDD_ARM_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck3_reg: BUCK3 {
+				regulator-name = "VDD_INT_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck4_reg: BUCK4 {
+				regulator-name = "VDD_G3D_1V0";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck5_reg: BUCK5 {
+				regulator-name = "VDD_MEM_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			buck6_reg: BUCK6 {
+				regulator-name = "VDD_KFC_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck7_reg: BUCK7 {
+				regulator-name = "VIN_LLDO_1V4";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+			};
+
+			buck8_reg: BUCK8 {
+				regulator-name = "VIN_MLDO_2V0";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-always-on;
+			};
+
+			buck9_reg: BUCK9 {
+				regulator-name = "VIN_HLDO_3V5";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3500000>;
+				regulator-always-on;
+			};
+
+			buck10_reg: BUCK10 {
+				regulator-name = "VDD_CAM_ISP_1V0";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <3550000>;
+			};
+
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ALIVE_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_APIO_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo3_reg: LDO3 {
+				regulator-name = "VDD_APIO_MMC01_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo4_reg: LDO4 {
+				regulator-name = "VDD_ADC_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo5_reg: LDO5 {
+				/* Unused */
+				regulator-name = "VDD_LDO5";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo6_reg: LDO6 {
+				regulator-name = "VDD_MIPI_1V0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo7_reg: LDO7 {
+				regulator-name = "VDD_MIPI_PLL_ABB1_18V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo8_reg: LDO8 {
+				/* Unused */
+				regulator-name = "VDD_LDO8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo9_reg: LDO9 {
+				regulator-name = "VDD_UOTG_3V0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo10_reg: LDO10 {
+				regulator-name = "VDDQ_PRE_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo11_reg: LDO11 {
+				regulator-name = "VDD_HSIC_1V0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo12_reg: LDO12 {
+				regulator-name = "VDD_HSIC_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+			};
+
+			ldo13_reg: LDO13 {
+				regulator-name = "VDD_APIO_MMC2_2V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo14_reg: LDO14 {
+				regulator-name = "VDD_MOTOR_3V0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo15_reg: LDO15 {
+				regulator-name = "LDO15";
+				/*
+				 * LDO15 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo16_reg: LDO16 {
+				regulator-name = "VDD_AP_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo17_reg: LDO17 {
+				regulator-name = "LDO17";
+				/*
+				 * LDO17 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo18_reg: LDO18 {
+				/* Unused */
+				regulator-name = "VDD_LDO18";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+
+			ldo19_reg: LDO19 {
+				regulator-name = "VDD_VTF_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo20_reg: LDO20 {
+				regulator-name = "VDD_CAM1_CAM_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo21_reg: LDO21 {
+				regulator-name = "VDD_CAM_IO_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo22_reg: LDO22 {
+				regulator-name = "VDD_CAM0_S_CORE_1V1";
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo23_reg: LDO23 {
+				regulator-name = "VDD_MIFS_1V1";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo24_reg: LDO24 {
+				regulator-name = "VDD_TSP_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo25_reg: LDO25 {
+				/* Unused */
+				regulator-name = "VDD_LDO25";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo26_reg: LDO26 {
+				regulator-name = "VDD_CAM0_AF_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo27_reg: LDO27 {
+				regulator-name = "VDD_G3DS_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo28_reg: LDO28 {
+				regulator-name = "LDO28";
+				/*
+				 * LDO28 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo29_reg: LDO29 {
+				regulator-name = "LDO29";
+				/*
+				 * LDO29 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo30_reg: LDO30 {
+				regulator-name = "VDD_TOUCH_1V8";
+				regulator-min-microvolt = <1900000>;
+				regulator-max-microvolt = <1900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo31_reg: LDO31 {
+				regulator-name = "LDO31";
+				/*
+				 * LDO31 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo32_reg: LDO32 {
+				regulator-name = "VDD_TSP_1V8";
+				regulator-min-microvolt = <1900000>;
+				regulator-max-microvolt = <1900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo33_reg: LDO33 {
+				regulator-name = "VDD_MHL_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo34_reg: LDO34 {
+				regulator-name = "VDD_MHL_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo35_reg: LDO35 {
+				regulator-name = "VDD_SIL_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo36_reg: LDO36 {
+				/* Unused */
+				regulator-name = "VDD_LDO36";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo37_reg: LDO37 {
+				/* Unused */
+				regulator-name = "VDD_LDO37";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo38_reg: LDO38 {
+				regulator-name = "VDD_KEY_LED_3V3";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&mixer {
+	status = "okay";
+};
+
+/* Internal storage */
+&mmc_0 {
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	card-detect-delay = <200>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+	pinctrl-names = "default";
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	vqmmc-supply = <&ldo3_reg>;
+};
+
+/* External sdcard */
+&mmc_2 {
+	status = "okay";
+	bus-width = <4>;
+	cap-sd-highspeed;
+	card-detect-delay = <200>;
+	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
+	pinctrl-names = "default";
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	sd-uhs-sdr50;
+	vmmc-supply = <&ldo19_reg>;
+	vqmmc-supply = <&ldo13_reg>;
+};
+
+&pinctrl_0 {
+	mmc2_cd: sd2-cd-pins {
+		samsung,pins = "gpx2-4";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV4>;
+	};
+
+	s2mps11_irq: s2mps11-irq-pins {
+		samsung,pins = "gpx3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&tmu_cpu0 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu1 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu2 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu3 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_gpu {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd3_0 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
+
+&usbdrd3_1 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
-- 
2.34.1



From krzysztof.kozlowski at canonical.com  Sun Jan 16 09:10:10 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 16 Jan 2022 18:10:10 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
 <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
Message-ID: <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>

On 16/01/2022 01:55, Linus Walleij wrote:
> On Tue, Jan 11, 2022 at 9:18 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
> 
>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) pin
>> controller bindings to DT schema format.  Parts of description and DTS
>> example was copied from existing sources, so keep the license as
>> GPL-2.0-only.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
>> Reviewed-by: Rob Herring <robh at kernel.org>
> 
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> 
> I expect that you will merge this into ARM SoC with the rest
> of the DTS fixes?

Yes, that would be the most clean approach, although there is no strict
dependency requirement between bindings and DTS. If they go via two
separate trees (ARM SoC and pinctrl), there will be a branch when
dtschema complains about DTS, which is not nice, but also not fatal.

Anyway DTS and dtschema will have to wait for one release, because they
depend on samsung pinctrl driver change (patch #2).


Best regards,
Krzysztof


From stefan.wahren at i2se.com  Sun Jan 16 09:26:58 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun, 16 Jan 2022 18:26:58 +0100
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
Message-ID: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>

Hi,

recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
Aarch64 with Arch Linux. I'm able to reproduce this issue on my
Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
the connected HDMI monitor off and on again.

Kernel output is the following:

[15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
unhandled: 0
[15053.295440] ->handle_irq():? 00000000b28cf1d1,
brcmstb_l2_intc_irq_handle+0x0/0x1e0
[15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
[15053.315233] ->action(): 00000000236e815e
[15053.322022] ->action->handler(): 0000000013023289,
bad_chained_irq+0x0/0x50
[15053.331909]????? IRQ_LEVEL set
[15053.337822]??? IRQ_NOPROBE set
[15053.343715]? IRQ_NOREQUEST set
[15053.349585]?? IRQ_NOTHREAD set

Content of /proc/interrupts after the issue occured:

?????????? CPU0?????? CPU1?????? CPU2?????? CPU3??????
? 9:????????? 0????????? 0????????? 0????????? 0???? GICv2? 25 Level????
vgic
?10:????????? 1????????? 0????????? 0????????? 0???? GICv2 128 Level????
(null)
?12:???? 130322????? 26028????? 27670???? 135225???? GICv2? 30 Level????
arch_timer
?13:????????? 0????????? 0????????? 0????????? 0???? GICv2? 27 Level????
kvm guest vtimer
?19:????????? 0????????? 0????????? 0????????? 0???? GICv2 107 Level????
fe004000.txp
?20:?????? 7450????????? 0????????? 0????????? 0???? GICv2? 65 Level????
fe00b880.mailbox
?25:?????? 6525????????? 0????????? 0????????? 0???? GICv2 153 Level????
uart-pl011
?26:????????? 0????????? 0????????? 0????????? 0???? GICv2 149 Level????
fe205000.i2c, fe804000.i2c
?27:????????? 9????????? 0????????? 0????????? 0???? GICv2 125 Level????
ttyS1
?28:????? 36999????????? 0????????? 0????????? 0???? GICv2 158 Level????
mmc0, mmc1
?29:????????? 1????????? 0????????? 0????????? 0???? GICv2 129 Level????
vc4 hvs
?30:????????? 0????????? 0????????? 0????????? 0???? GICv2 105 Level????
fe980000.usb, fe980000.usb
?31:????????? 0????????? 0????????? 0????????? 0???? GICv2 112 Level????
DMA IRQ
?33:????????? 0????????? 0????????? 0????????? 0???? GICv2 114 Level????
DMA IRQ
?40:????????? 0????????? 0????????? 0????????? 0???? GICv2 141 Level????
vc4 crtc
?41:????????? 0????????? 0????????? 0????????? 0???? GICv2 142 Level????
vc4 crtc, vc4 crtc
?42:???????? 10????????? 0????????? 0????????? 0???? GICv2 133 Level????
vc4 crtc
?43:????????? 1????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
?44:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
?47:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
?48:????????? 1????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
?49:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
?50:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
?53:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
?54:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
?55:????????? 7????????? 0????????? 0????????? 0???? GICv2? 66 Level????
VCHIQ doorbell
?56:????????? 0????????? 0????????? 0????????? 0???? GICv2? 48 Level????
arm-pmu
?57:????????? 0????????? 0????????? 0????????? 0???? GICv2? 49 Level????
arm-pmu
?58:????????? 0????????? 0????????? 0????????? 0???? GICv2? 50 Level????
arm-pmu
?59:????????? 0????????? 0????????? 0????????? 0???? GICv2? 51 Level????
arm-pmu
?62:????? 47599????????? 0????????? 0????????? 0???? GICv2 189 Level????
eth0
?63:?????? 4681????????? 0????????? 0????????? 0???? GICv2 190 Level????
eth0
?64:????????? 0????????? 0????????? 0????????? 0???? GICv2 175 Level????
PCIe PME, aerdrv
?65:??????? 326????????? 0????????? 0????????? 0? BRCM STB PCIe MSI
524288 Edge????? xhci_hcd
IPI0:????? 2442?????? 5185?????? 7195????? 18290?????? Rescheduling
interrupts
IPI1:?????? 481??????? 383??????? 518??????? 533?????? Function call
interrupts
IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop interrupts
IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for
crash dump) interrupts
IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast
interrupts
IPI5:???????? 1????????? 0????????? 0????????? 0?????? IRQ work interrupts
IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up
interrupts
Err:????????? 1

Comparing the vendor & mainline DTS, i noticed differences at hdmi0/1.
The vendor DTS has an additional register to access the same space as
aon_intr (interrupt parent), which looks ugly [2].

Additionally i noted that bcm2711.dtsi uses the compatible
"brcm,bcm2711-l2-intc" with a level high interrupt, but according to
irq-brcmstb-l2.c [3] the compatible is not defined and would fallback to
"brcm,l2-intc" with brcmstb_l2_edge_intc_of_init. This looks fishy.

I didn't try to reproduce this with Raspberry Pi OS & mainline kernel,
but i hope these are enough information so far.

[1] - https://archlinuxarm.org/forum/viewtopic.php?f=65&t=15791

[2] -
https://github.com/raspberrypi/linux/blob/rpi-5.15.y/arch/arm/boot/dts/bcm2711.dtsi#L339

[3] -
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/irqchip/irq-brcmstb-l2.c?h=v5.15.15#n278


From krzysztof.kozlowski at canonical.com  Sun Jan 16 09:37:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 16 Jan 2022 18:37:15 +0100
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <20220116165035.437274-4-henrik@grimler.se>
References: <20220116165035.437274-1-henrik@grimler.se>
 <20220116165035.437274-4-henrik@grimler.se>
Message-ID: <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>

On 16/01/2022 17:50, Henrik Grimler wrote:
> Chagall WiFi, with product name Samsung Galaxy Tab S 10.5", is based
> on Exynos 5420.  This device is one of several tablet models released
> in 2014 based on Exynos 5420.
> 
> The device tree added here contains support for:
> 
> - UART
> - eMMC
> - SD card
> - USB
> 
> CCI has been disabled in the hardware, enabling it would require
> (de-)soldering a resistor on the board.  Trying to boot with it
> enabled in kernel makes the device hang when CCI is probed.
> Exynos5420-arndale-octa also has had CCI disabled due to issues, see
> commit 25217fef3551 ("ARM: dts: disable CCI on exynos5420 based
> arndale-octa").
> 
> Signed-off-by: Henrik Grimler <henrik at grimler.se>
> ---
>  arch/arm/boot/dts/Makefile                    |   1 +
>  arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  65 ++
>  .../dts/exynos5420-galaxy-tab-common.dtsi     | 666 ++++++++++++++++++
>  3 files changed, 732 insertions(+)
>  create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
>  create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..088fcedb3212 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
>  	exynos5420-arndale-octa.dtb \
>  	exynos5420-peach-pit.dtb \
>  	exynos5420-smdk5420.dtb \
> +	exynos5420-chagall-wifi.dtb \
>  	exynos5422-odroidhc1.dtb \
>  	exynos5422-odroidxu3.dtb \
>  	exynos5422-odroidxu3-lite.dtb \
> diff --git a/arch/arm/boot/dts/exynos5420-chagall-wifi.dts b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
> new file mode 100644
> index 000000000000..2cc5cd01e8c6
> --- /dev/null
> +++ b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
> @@ -0,0 +1,65 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Samsung's Exynos5420 Chagall WiFi board device tree source
> + *
> + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Copyright (c) 2022 Henrik Grimler
> + */
> +
> +/dts-v1/;
> +#include "exynos5420-galaxy-tab-common.dtsi"
> +
> +/ {
> +	model = "Samsung Chagall WiFi based on Exynos5420";
> +	compatible = "samsung,chagall-wifi", "samsung,exynos5420", \
> +		     "samsung,exynos5";
> +};
> +
> +&ldo15_reg {
> +	/* Unused */
> +	regulator-name = "VDD_LDO15";
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +};
> +
> +&ldo17_reg {
> +	regulator-name = "VDD_IRLED_3V3";
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3350000>;
> +	regulator-always-on;
> +	regulator-boot-on;
> +
> +	regulator-state-mem {
> +		regulator-off-in-suspend;
> +	};
> +};
> +
> +&ldo28_reg {
> +	/* Unused */
> +	regulator-name = "VDD_LDO28";
> +	regulator-min-microvolt = <3300000>;
> +	regulator-max-microvolt = <3300000>;
> +};
> +
> +&ldo29_reg {
> +	regulator-name = "VDD_TCON_1V8";
> +	regulator-min-microvolt = <1900000>;
> +	regulator-max-microvolt = <1900000>;
> +
> +	regulator-state-mem {
> +		regulator-off-in-suspend;
> +	};
> +};
> +
> +&ldo31_reg {
> +	regulator-name = "VDD_GRIP_1V8";
> +	regulator-min-microvolt = <1800000>;
> +	regulator-max-microvolt = <1800000>;
> +	regulator-always-on;
> +	regulator-boot-on;
> +
> +	regulator-state-mem {
> +		regulator-off-in-suspend;
> +	};
> +};
> diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> new file mode 100644
> index 000000000000..119e4e7a8328
> --- /dev/null
> +++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
> @@ -0,0 +1,666 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Base DT for Samsung's family of tablets based on Exynos5420.
> + *
> + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
> + *		http://www.samsung.com
> + * Copyright (c) 2022 Henrik Grimler
> + */
> +
> +/dts-v1/;
> +#include "exynos5420.dtsi"
> +#include "exynos5420-cpus.dtsi"
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/clock/samsung,s2mps11.h>
> +
> +/ {
> +	chassis-type = "tablet";
> +
> +	/*
> +	 * To successfully boot the mainline kernel with the stock
> +	 * bootloader (SBOOT), the tlb needs to be flushed after the
> +	 * page table pointer has been updated in __common_mmu_cache_on.
> +	 * The same hack is also needed to boot exynos4412-i9300 with
> +	 * stock bootloader, and probably other Samsung devices of
> +	 * similar age.  See
> +	 * https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com
> +	 * for more details.
> +	 */
> +
> +	chosen {
> +		stdout-path = "serial2:115200n8";
> +	};
> +
> +	memory at 20000000 {
> +		device_type = "memory";
> +		reg = <0x20000000 0xc0000000>;
> +	};
> +
> +	firmware at 2073000 {
> +		compatible = "samsung,secure-firmware";
> +		reg = <0x02073000 0x1000>;
> +	};
> +
> +	fixed-rate-clocks {
> +		oscclk {
> +			compatible = "samsung,exynos5420-oscclk";
> +			clock-frequency = <24000000>;
> +		};
> +	};
> +
> +	gpio-keys {
> +		compatible = "gpio-keys";
> +		pinctrl-names = "default";
> +
> +		key-power {
> +			debounce-interval = <10>;
> +			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
> +			label = "Power";
> +			linux,code = <KEY_POWER>;
> +			wakeup-source;
> +		};
> +
> +		key-home {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
> +			label = "Home";
> +			linux,code = <KEY_HOME>;
> +			wakeup-source;
> +		};
> +
> +		key-volume-up {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
> +			label = "Volume Up";
> +			linux,code = <KEY_VOLUMEUP>;
> +		};
> +
> +		key-volume-down {
> +			debounce-interval = <10>;
> +			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
> +			label = "Volume Down";
> +			linux,code = <KEY_VOLUMEDOWN>;
> +		};
> +	};
> +};
> +
> +&cci {
> +	/* CCI is disabled in hardware */
> +	status = "disabled";
> +};
> +
> +&cpu0 {
> +	cpu-supply = <&buck2_reg>;
> +};
> +
> +&cpu4 {
> +	cpu-supply = <&buck6_reg>;
> +};
> +
> +&gpu {
> +	status = "okay";
> +	mali-supply = <&buck4_reg>;
> +};
> +
> +&hsi2c_7 {
> +	status = "okay";
> +
> +	pmic at 66 {
> +		compatible = "samsung,s2mps11-pmic";
> +		reg = <0x66>;
> +
> +		interrupt-parent = <&gpx3>;
> +		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&s2mps11_irq>;
> +
> +		s2mps11_osc: clocks {
> +			compatible = "samsung,s2mps11-clk";
> +			#clock-cells = <1>;
> +			clock-output-names = "s2mps11_ap", "s2mps11_cp",
> +					     "s2mps11_bt";
> +		};
> +
> +		regulators {
> +			buck1_reg: BUCK1 {
> +				regulator-name = "VDD_MIF_1V1";
> +				regulator-min-microvolt = <700000>;
> +				regulator-max-microvolt = <1300000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			buck2_reg: BUCK2 {
> +				regulator-name = "VDD_ARM_1V0";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1500000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			buck3_reg: BUCK3 {
> +				regulator-name = "VDD_INT_1V0";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1400000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			buck4_reg: BUCK4 {
> +				regulator-name = "VDD_G3D_1V0";
> +				regulator-min-microvolt = <700000>;
> +				regulator-max-microvolt = <1400000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			buck5_reg: BUCK5 {
> +				regulator-name = "VDD_MEM_1V2";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <1200000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			buck6_reg: BUCK6 {
> +				regulator-name = "VDD_KFC_1V0";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1500000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			buck7_reg: BUCK7 {
> +				regulator-name = "VIN_LLDO_1V4";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <1500000>;
> +				regulator-always-on;
> +			};
> +
> +			buck8_reg: BUCK8 {
> +				regulator-name = "VIN_MLDO_2V0";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <2100000>;
> +				regulator-always-on;
> +			};
> +
> +			buck9_reg: BUCK9 {
> +				regulator-name = "VIN_HLDO_3V5";
> +				regulator-min-microvolt = <3000000>;
> +				regulator-max-microvolt = <3500000>;
> +				regulator-always-on;
> +			};
> +
> +			buck10_reg: BUCK10 {
> +				regulator-name = "VDD_CAM_ISP_1V0";
> +				regulator-min-microvolt = <750000>;
> +				regulator-max-microvolt = <3550000>;
> +			};
> +
> +			ldo1_reg: LDO1 {
> +				regulator-name = "VDD_ALIVE_1.0V";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +			};
> +
> +			ldo2_reg: LDO2 {
> +				regulator-name = "VDD_APIO_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo3_reg: LDO3 {
> +				regulator-name = "VDD_APIO_MMC01_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo4_reg: LDO4 {
> +				regulator-name = "VDD_ADC_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo5_reg: LDO5 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO5";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +			};
> +
> +			ldo6_reg: LDO6 {
> +				regulator-name = "VDD_MIPI_1V0";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo7_reg: LDO7 {
> +				regulator-name = "VDD_MIPI_PLL_ABB1_18V";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo8_reg: LDO8 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +			};
> +
> +			ldo9_reg: LDO9 {
> +				regulator-name = "VDD_UOTG_3V0";
> +				regulator-min-microvolt = <3000000>;
> +				regulator-max-microvolt = <3000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo10_reg: LDO10 {
> +				regulator-name = "VDDQ_PRE_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo11_reg: LDO11 {
> +				regulator-name = "VDD_HSIC_1V0";
> +				regulator-min-microvolt = <1000000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo12_reg: LDO12 {
> +				regulator-name = "VDD_HSIC_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +			};
> +
> +			ldo13_reg: LDO13 {
> +				regulator-name = "VDD_APIO_MMC2_2V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <2800000>;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo14_reg: LDO14 {
> +				regulator-name = "VDD_MOTOR_3V0";
> +				regulator-min-microvolt = <3000000>;
> +				regulator-max-microvolt = <3000000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo15_reg: LDO15 {
> +				regulator-name = "LDO15";
> +				/*
> +				 * LDO15 varies between devices and is
> +				 * specified in the device dts
> +				 */
> +			};
> +
> +			ldo16_reg: LDO16 {
> +				regulator-name = "VDD_AP_2V8";
> +				regulator-min-microvolt = <2800000>;
> +				regulator-max-microvolt = <2800000>;
> +				regulator-always-on;
> +				regulator-boot-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			ldo17_reg: LDO17 {
> +				regulator-name = "LDO17";
> +				/*
> +				 * LDO17 varies between devices and is
> +				 * specified in the device dts
> +				 */
> +			};
> +
> +			ldo18_reg: LDO18 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO18";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +			};
> +
> +
> +			ldo19_reg: LDO19 {
> +				regulator-name = "VDD_VTF_2V8";
> +				regulator-min-microvolt = <2800000>;
> +				regulator-max-microvolt = <2800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo20_reg: LDO20 {
> +				regulator-name = "VDD_CAM1_CAM_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo21_reg: LDO21 {
> +				regulator-name = "VDD_CAM_IO_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo22_reg: LDO22 {
> +				regulator-name = "VDD_CAM0_S_CORE_1V1";
> +				regulator-min-microvolt = <1050000>;
> +				regulator-max-microvolt = <1200000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo23_reg: LDO23 {
> +				regulator-name = "VDD_MIFS_1V1";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-always-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			ldo24_reg: LDO24 {
> +				regulator-name = "VDD_TSP_3V3";
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo25_reg: LDO25 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO25";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <3950000>;
> +			};
> +
> +			ldo26_reg: LDO26 {
> +				regulator-name = "VDD_CAM0_AF_2V8";
> +				regulator-min-microvolt = <2800000>;
> +				regulator-max-microvolt = <2800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo27_reg: LDO27 {
> +				regulator-name = "VDD_G3DS_1V0";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <1000000>;
> +				regulator-always-on;
> +
> +				regulator-state-mem {
> +					regulator-on-in-suspend;
> +				};
> +			};
> +
> +			ldo28_reg: LDO28 {
> +				regulator-name = "LDO28";
> +				/*
> +				 * LDO28 varies between devices and is
> +				 * specified in the device dts
> +				 */
> +			};
> +
> +			ldo29_reg: LDO29 {
> +				regulator-name = "LDO29";
> +				/*
> +				 * LDO29 varies between devices and is
> +				 * specified in the device dts
> +				 */
> +			};
> +
> +			ldo30_reg: LDO30 {
> +				regulator-name = "VDD_TOUCH_1V8";
> +				regulator-min-microvolt = <1900000>;
> +				regulator-max-microvolt = <1900000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo31_reg: LDO31 {
> +				regulator-name = "LDO31";
> +				/*
> +				 * LDO31 varies between devices and is
> +				 * specified in the device dts
> +				 */
> +			};
> +
> +			ldo32_reg: LDO32 {
> +				regulator-name = "VDD_TSP_1V8";
> +				regulator-min-microvolt = <1900000>;
> +				regulator-max-microvolt = <1900000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo33_reg: LDO33 {
> +				regulator-name = "VDD_MHL_1V8";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo34_reg: LDO34 {
> +				regulator-name = "VDD_MHL_3V3";
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo35_reg: LDO35 {
> +				regulator-name = "VDD_SIL_1V2";
> +				regulator-min-microvolt = <1200000>;
> +				regulator-max-microvolt = <1200000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +
> +			ldo36_reg: LDO36 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO36";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <3950000>;
> +			};
> +
> +			ldo37_reg: LDO37 {
> +				/* Unused */
> +				regulator-name = "VDD_LDO37";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <3950000>;
> +			};
> +
> +			ldo38_reg: LDO38 {
> +				regulator-name = "VDD_KEY_LED_3V3";
> +				regulator-min-microvolt = <2500000>;
> +				regulator-max-microvolt = <3300000>;
> +
> +				regulator-state-mem {
> +					regulator-off-in-suspend;
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&mixer {
> +	status = "okay";
> +};
> +
> +/* Internal storage */
> +&mmc_0 {
> +	status = "okay";
> +	bus-width = <8>;
> +	cap-mmc-highspeed;
> +	card-detect-delay = <200>;
> +	mmc-hs200-1_8v;
> +	non-removable;
> +	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
> +	pinctrl-names = "default";
> +	samsung,dw-mshc-ciu-div = <3>;
> +	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-sdr-timing = <0 4>;
> +	vqmmc-supply = <&ldo3_reg>;
> +};
> +
> +/* External sdcard */
> +&mmc_2 {
> +	status = "okay";
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	card-detect-delay = <200>;
> +	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
> +	pinctrl-names = "default";
> +	samsung,dw-mshc-ciu-div = <3>;
> +	samsung,dw-mshc-ddr-timing = <0 2>;
> +	samsung,dw-mshc-sdr-timing = <0 4>;
> +	sd-uhs-sdr50;
> +	vmmc-supply = <&ldo19_reg>;
> +	vqmmc-supply = <&ldo13_reg>;
> +};
> +
> +&pinctrl_0 {
> +	mmc2_cd: sd2-cd-pins {
> +		samsung,pins = "gpx2-4";

Interesting... I looked at vendor sources to board-chagall and standard
pin gpc2-2 is mentioned as PULL down and not-connected comment.

gpx2-4 seems not mentioned at all, unless other board files are actually
used.

Anyway, if it works for you, it's good.

Rest looks ok, I'll apply after the merge window.

Best regards,
Krzysztof


From f.fainelli at gmail.com  Sun Jan 16 12:15:53 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 16 Jan 2022 12:15:53 -0800
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
Message-ID: <31f2cd8f-32b6-beca-0cae-66c23b73ece0@gmail.com>

Hi Stefan,

On 1/16/2022 9:26 AM, Stefan Wahren wrote:
> Hi,
> 
> recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
> Aarch64 with Arch Linux. I'm able to reproduce this issue on my
> Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
> the connected HDMI monitor off and on again.
> 
> Kernel output is the following:
> 
> [15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
> unhandled: 0
> [15053.295440] ->handle_irq():? 00000000b28cf1d1,
> brcmstb_l2_intc_irq_handle+0x0/0x1e0
> [15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
> [15053.315233] ->action(): 00000000236e815e
> [15053.322022] ->action->handler(): 0000000013023289,
> bad_chained_irq+0x0/0x50
> [15053.331909]????? IRQ_LEVEL set
> [15053.337822]??? IRQ_NOPROBE set
> [15053.343715]? IRQ_NOREQUEST set
> [15053.349585]?? IRQ_NOTHREAD set

OK, so those should have been cleared during the call to 
irq_alloc_domain_generic_chips(), any clues why they are set here?

> 
> Content of /proc/interrupts after the issue occured:
> 
>  ?????????? CPU0?????? CPU1?????? CPU2?????? CPU3
>  ? 9:????????? 0????????? 0????????? 0????????? 0???? GICv2? 25 Level
> vgic
>  ?10:????????? 1????????? 0????????? 0????????? 0???? GICv2 128 Level
> (null)

This is suspicious, we should not have an interrupt registered here at 
all since we call irq_set_chained_handler_and_data, this is a L2 
interrupt controller, not a leaf interrupt with a descriptor. On all 
Broadcom STB systems where this interrupt controller is used, I 
definitively don't see any entries for the L2 output to the GIC in 
/proc/interrupts because no interrupt descriptor is allocated.

This makes me wonder where this is coming from but the message about irq 
10 being bad would make sense then.

>  ?12:???? 130322????? 26028????? 27670???? 135225???? GICv2? 30 Level
> arch_timer
>  ?13:????????? 0????????? 0????????? 0????????? 0???? GICv2? 27 Level
> kvm guest vtimer
>  ?19:????????? 0????????? 0????????? 0????????? 0???? GICv2 107 Level
> fe004000.txp
>  ?20:?????? 7450????????? 0????????? 0????????? 0???? GICv2? 65 Level
> fe00b880.mailbox
>  ?25:?????? 6525????????? 0????????? 0????????? 0???? GICv2 153 Level
> uart-pl011
>  ?26:????????? 0????????? 0????????? 0????????? 0???? GICv2 149 Level
> fe205000.i2c, fe804000.i2c
>  ?27:????????? 9????????? 0????????? 0????????? 0???? GICv2 125 Level
> ttyS1
>  ?28:????? 36999????????? 0????????? 0????????? 0???? GICv2 158 Level
> mmc0, mmc1
>  ?29:????????? 1????????? 0????????? 0????????? 0???? GICv2 129 Level
> vc4 hvs
>  ?30:????????? 0????????? 0????????? 0????????? 0???? GICv2 105 Level
> fe980000.usb, fe980000.usb
>  ?31:????????? 0????????? 0????????? 0????????? 0???? GICv2 112 Level
> DMA IRQ
>  ?33:????????? 0????????? 0????????? 0????????? 0???? GICv2 114 Level
> DMA IRQ
>  ?40:????????? 0????????? 0????????? 0????????? 0???? GICv2 141 Level
> vc4 crtc
>  ?41:????????? 0????????? 0????????? 0????????? 0???? GICv2 142 Level
> vc4 crtc, vc4 crtc
>  ?42:???????? 10????????? 0????????? 0????????? 0???? GICv2 133 Level
> vc4 crtc
>  ?43:????????? 1????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
>  ?44:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
>  ?47:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
>  ?48:????????? 1????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
>  ?49:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
>  ?50:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
>  ?53:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
>  ?54:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
>  ?55:????????? 7????????? 0????????? 0????????? 0???? GICv2? 66 Level
> VCHIQ doorbell
>  ?56:????????? 0????????? 0????????? 0????????? 0???? GICv2? 48 Level
> arm-pmu
>  ?57:????????? 0????????? 0????????? 0????????? 0???? GICv2? 49 Level
> arm-pmu
>  ?58:????????? 0????????? 0????????? 0????????? 0???? GICv2? 50 Level
> arm-pmu
>  ?59:????????? 0????????? 0????????? 0????????? 0???? GICv2? 51 Level
> arm-pmu
>  ?62:????? 47599????????? 0????????? 0????????? 0???? GICv2 189 Level
> eth0
>  ?63:?????? 4681????????? 0????????? 0????????? 0???? GICv2 190 Level
> eth0
>  ?64:????????? 0????????? 0????????? 0????????? 0???? GICv2 175 Level
> PCIe PME, aerdrv
>  ?65:??????? 326????????? 0????????? 0????????? 0? BRCM STB PCIe MSI
> 524288 Edge????? xhci_hcd
> IPI0:????? 2442?????? 5185?????? 7195????? 18290?????? Rescheduling
> interrupts
> IPI1:?????? 481??????? 383??????? 518??????? 533?????? Function call
> interrupts
> IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop interrupts
> IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for
> crash dump) interrupts
> IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast
> interrupts
> IPI5:???????? 1????????? 0????????? 0????????? 0?????? IRQ work interrupts
> IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up
> interrupts
> Err:????????? 1
> 
> Comparing the vendor & mainline DTS, i noticed differences at hdmi0/1.
> The vendor DTS has an additional register to access the same space as
> aon_intr (interrupt parent), which looks ugly [2].

OK, so while I do see how we set external_irq_controller to let the 
interrupt be managed externally from vc4_hdmi.c else do it internally, I 
don't see the code that tries to map the "intr2" register space, let 
alone fetch its resource, do you know where that is?

> 
> Additionally i noted that bcm2711.dtsi uses the compatible
> "brcm,bcm2711-l2-intc" with a level high interrupt, but according to
> irq-brcmstb-l2.c [3] the compatible is not defined and would fallback to
> "brcm,l2-intc" with brcmstb_l2_edge_intc_of_init. This looks fishy.

The hardware level 2 controller at 0x7ef00100 is definitively the same 
kind that supports edge interrupt flows since it has the CPU_STATUS, 
CPU_CLEAR, CPU_MASK_STATUS, CPU_MASK_SET and CPU_MASK_CLEAR registers, 
so it seems to me like declaring the interrupt controller of the kind 
"brcm,l2-intc" and using the edge interrupt handling is not necessarily 
a problem.

> 
> I didn't try to reproduce this with Raspberry Pi OS & mainline kernel,
> but i hope these are enough information so far.
> 
> [1] - https://archlinuxarm.org/forum/viewtopic.php?f=65&t=15791
> 
> [2] -
> https://github.com/raspberrypi/linux/blob/rpi-5.15.y/arch/arm/boot/dts/bcm2711.dtsi#L339
> 
> [3] -
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/irqchip/irq-brcmstb-l2.c?h=v5.15.15#n278
> 

-- 
Florian


From henrik at grimler.se  Sun Jan 16 12:59:32 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Sun, 16 Jan 2022 21:59:32 +0100
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>
References: <20220116165035.437274-1-henrik@grimler.se>
 <20220116165035.437274-4-henrik@grimler.se>
 <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>
Message-ID: <YeSHNCywXhp8gHC7@L14.lan>

Hi Krzysztof,

> > +/* External sdcard */
> > +&mmc_2 {
> > +	status = "okay";
> > +	bus-width = <4>;
> > +	cap-sd-highspeed;
> > +	card-detect-delay = <200>;
> > +	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
> > +	pinctrl-names = "default";
> > +	samsung,dw-mshc-ciu-div = <3>;
> > +	samsung,dw-mshc-ddr-timing = <0 2>;
> > +	samsung,dw-mshc-sdr-timing = <0 4>;
> > +	sd-uhs-sdr50;
> > +	vmmc-supply = <&ldo19_reg>;
> > +	vqmmc-supply = <&ldo13_reg>;
> > +};
> > +
> > +&pinctrl_0 {
> > +	mmc2_cd: sd2-cd-pins {
> > +		samsung,pins = "gpx2-4";
> 
> Interesting... I looked at vendor sources to board-chagall and standard
> pin gpc2-2 is mentioned as PULL down and not-connected comment.
> 
> gpx2-4 seems not mentioned at all, unless other board files are actually
> used.

Gpio seems to be spread out. GPIO_T_FLASH_DETECT is defined as gpx2-4
in board-universal5420-mmc.c, and then used for card detection.
(Looking at it now again I see that write protection through sd2_wp
should also be supported for mmc_2, can add that in next patch set.)

> Anyway, if it works for you, it's good.
> 
> Rest looks ok, I'll apply after the merge window.

Thanks!

> Best regards,
> Krzysztof

Best regards,
Henrik Grimler


From linus.walleij at linaro.org  Sun Jan 16 13:38:16 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 16 Jan 2022 22:38:16 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
 <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
 <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>
Message-ID: <CACRpkdbhmJ91EW395C5F2WYjWJQdJ-SBHaDm7XnQsxMuyoMmLg@mail.gmail.com>

On Sun, Jan 16, 2022 at 6:10 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:

> Anyway DTS and dtschema will have to wait for one release, because they
> depend on samsung pinctrl driver change (patch #2).

What about I put that (and maybe this schema) on an immutable
branch so you can pull the commit into your for-arm-soc branch and
put the DTS changes on top?

Yours,
Linus Walleij


From martin.blumenstingl at googlemail.com  Sun Jan 16 15:01:27 2022
From: martin.blumenstingl at googlemail.com (Martin Blumenstingl)
Date: Mon, 17 Jan 2022 00:01:27 +0100
Subject: [PATCH] nvmem: meson-mx-efuse: check the return value of
 devm_kstrdup()
In-Reply-To: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>
References: <tencent_0F8E090AA07050A5857F1E9067E6B9DC0C07@qq.com>
Message-ID: <CAFBinCDigiSYT+AkRmCgEB6u_v2uJLg49aNrt8ddxq97FkEMxw@mail.gmail.com>

Hello,

First of all: thank you for this patch!

On Sun, Jan 16, 2022 at 6:37 AM <xkernel.wang at foxmail.com> wrote:
[...]
> @@ -211,6 +211,9 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
>
>         efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
>                                           GFP_KERNEL);
> +       if (!efuse->config.name)
> +               return -ENOMEM;
Looking at other drivers and also at drivers/nvmem/core.c I believe
that the whole devm_kstrdup is unnecessary.
Instead I think the code can be simplified as:
    efuse->config.name = drvdata->name;

What do you think?


Best regards,
Martin


From chiawei_wang at aspeedtech.com  Sun Jan 16 16:05:48 2022
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Mon, 17 Jan 2022 00:05:48 +0000
Subject: [PATCH] soc: aspeed: Fix IRQ check in aspeed_lpc_snoop_config_irq
In-Reply-To: <20220114064357.18562-1-linmq006@gmail.com>
References: <20220114064357.18562-1-linmq006@gmail.com>
Message-ID: <HK0PR06MB377975CCF8230EB9FE35EC6A91579@HK0PR06MB3779.apcprd06.prod.outlook.com>

> From: Miaoqian Lin <linmq006 at gmail.com>
> Sent: Friday, January 14, 2022 2:44 PM
> 
> platform_get_irq() returns negative error number instead 0 on failure.
> And the doc of platform_get_irq() provides a usage example:
> 
>     int irq = platform_get_irq(pdev, 0);
>     if (irq < 0)
>         return irq;
> 
> Fix the check of return value to catch errors correctly.
> 
> Fixes: 524feb799408 ("soc: add aspeed folder and misc drivers")
> Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>

Reviewed-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>

Thanks.

From lkp at intel.com  Sun Jan 16 17:41:58 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 09:41:58 +0800
Subject: [PATCH] power: supply_core: fix noderef.cocci warnings
In-Reply-To: <202201170953.yxBdZqTf-lkp@intel.com>
References: <202201170953.yxBdZqTf-lkp@intel.com>
Message-ID: <20220117014158.GA3685@07889aeafbfc>

From: kernel test robot <lkp at intel.com>

drivers/power/supply/cw2015_battery.c:692:12-18: ERROR: application of sizeof to pointer

 sizeof when applied to a pointer typed expression gives the size of
 the pointer

Generated by: scripts/coccinelle/misc/noderef.cocci

Fixes: 0839e7a54fc2 ("power: supply_core: Pass pointer to battery info")
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: kernel test robot <lkp at intel.com>
---

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
head:   1e846b0b60ac01cac4f283975a1bc395ff73d995
commit: 0839e7a54fc2233ea74b21651d022b981c124f78 [32/58] power: supply_core: Pass pointer to battery info
:::::: branch date: 2 days ago
:::::: commit date: 4 weeks ago

 cw2015_battery.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/power/supply/cw2015_battery.c
+++ b/drivers/power/supply/cw2015_battery.c
@@ -689,7 +689,7 @@ static int cw_bat_probe(struct i2c_clien
 	if (ret) {
 		/* Allocate an empty battery */
 		cw_bat->battery = devm_kzalloc(&client->dev,
-					       sizeof(cw_bat->battery),
+					       sizeof(*cw_bat->battery),
 					       GFP_KERNEL);
 		if (!cw_bat->battery)
 			return -ENOMEM;


From lkp at intel.com  Sun Jan 16 17:48:48 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 09:48:48 +0800
Subject: [linusw-nomadik:ux500-href-charging-v5.16-rc1 32/58]
 drivers/power/supply/cw2015_battery.c:692:12-18: ERROR: application of
 sizeof to pointer
Message-ID: <202201170953.yxBdZqTf-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
head:   1e846b0b60ac01cac4f283975a1bc395ff73d995
commit: 0839e7a54fc2233ea74b21651d022b981c124f78 [32/58] power: supply_core: Pass pointer to battery info
config: xtensa-randconfig-c004-20220116 (https://download.01.org/0day-ci/archive/20220117/202201170953.yxBdZqTf-lkp at intel.com/config)
compiler: xtensa-linux-gcc (GCC) 11.2.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


cocci warnings: (new ones prefixed by >>)
>> drivers/power/supply/cw2015_battery.c:692:12-18: ERROR: application of sizeof to pointer

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From huangguangbin2 at huawei.com  Sun Jan 16 17:52:20 2022
From: huangguangbin2 at huawei.com (Guangbin Huang)
Date: Mon, 17 Jan 2022 09:52:20 +0800
Subject: [RESEND PATCH 0/2] drivers/perf: hisi: Add driver for HNS3 PMU
Message-ID: <20220117015222.9617-1-huangguangbin2@huawei.com>

This patch-set adds driver for HNS3(HiSilicon network system version 3)
PMU and doc to descript it.

Guangbin Huang (2):
  drivers/perf: hisi: Add description for HNS3 PMU driver
  drivers/perf: hisi: add driver for HNS3 PMU

 Documentation/admin-guide/perf/hns3-pmu.rst |  122 ++
 MAINTAINERS                                 |    6 +
 drivers/perf/hisilicon/Kconfig              |    9 +
 drivers/perf/hisilicon/Makefile             |    1 +
 drivers/perf/hisilicon/hns3_pmu.c           | 1631 +++++++++++++++++++
 include/linux/cpuhotplug.h                  |    1 +
 6 files changed, 1770 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hns3-pmu.rst
 create mode 100644 drivers/perf/hisilicon/hns3_pmu.c

-- 
2.33.0



From huangguangbin2 at huawei.com  Sun Jan 16 17:52:21 2022
From: huangguangbin2 at huawei.com (Guangbin Huang)
Date: Mon, 17 Jan 2022 09:52:21 +0800
Subject: [RESEND PATCH 1/2] drivers/perf: hisi: Add description for HNS3 PMU
 driver
In-Reply-To: <20220117015222.9617-1-huangguangbin2@huawei.com>
References: <20220117015222.9617-1-huangguangbin2@huawei.com>
Message-ID: <20220117015222.9617-2-huangguangbin2@huawei.com>

HNS3 PMU End Point device is supported on HiSilicon HIP09 platform, so
add document hns3-pmu.rst to provide guidance on how to use it.

Signed-off-by: Guangbin Huang <huangguangbin2 at huawei.com>
---
 Documentation/admin-guide/perf/hns3-pmu.rst | 122 ++++++++++++++++++++
 1 file changed, 122 insertions(+)
 create mode 100644 Documentation/admin-guide/perf/hns3-pmu.rst

diff --git a/Documentation/admin-guide/perf/hns3-pmu.rst b/Documentation/admin-guide/perf/hns3-pmu.rst
new file mode 100644
index 000000000000..1fe3d549d074
--- /dev/null
+++ b/Documentation/admin-guide/perf/hns3-pmu.rst
@@ -0,0 +1,122 @@
+======================================
+HNS3 Performance Monitoring Unit (PMU)
+======================================
+
+HNS3(HiSilicon network system 3) Performance Monitoring Unit (PMU) is an
+End Point device to collect performance statistics of HiSilicon SoC NIC.
+On Hip09, each SICL(Super I/O cluster) has one PMU device.
+
+HNS3 PMU supports collection of performance statistics such as bandwidth,
+latency, packet rate and interrupt rate.
+
+Each HNS3 PMU supports 8 hardware events.
+
+HNS3 PMU driver
+===============
+
+The HNS3 PMU driver registers a perf PMU with the name of its device id.::
+
+  /sys/devices/hns3_pmu_<device_id>
+
+The device_id is read from hardware register, it contains information of
+chip_id(bit 31:2) and SICL_ID(bit 1:0). One chip may have one or more SICL.
+
+PMU driver provides description of available events, filter modes, format,
+identifier and cpumask in sysfs.
+
+The "events" directory describes the event code and subevent code of all
+supported events shown in perf list.
+
+The "filtermode" directory describes the supported filter modes of each
+event.
+
+The "format" directory describes all formats of the config (events) and
+config1 (filter options) fields of the perf_event_attr structure.
+
+The "identifier" file shows version of PMU hardware device.
+
+Example usage of checking event code and subevent code::
+
+  $# cat /sys/devices/hns3_pmu_0/events/pps_ssu_rpu
+  config=0x0102
+
+The upper 8 bits of config (here 0x01) are the event code. The lower 8 bits
+of config (here 0x02) are the subevent code.
+
+Example usage of checking supported filter mode::
+
+  $# cat /sys/devices/hns3_pmu_0/filtermode/bw_igu_ssu
+  filter mode supported: global/port/port-tc/
+
+Example usage of perf::
+
+  $# perf list
+  hns3_pmu_0/bw_igu_ssu/ [kernel PMU event]
+  ------------------------------------------
+
+  $# perf stat -a -e hns3_pmu_0/bw_igu_ssu,global=1/ -I 1000
+  or
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,global=1/ -I 1000
+
+The current driver does not support sampling, so "perf record" is unsupported.
+Also attach to a task is unsupported for HNS3 PMU.
+
+Filter modes
+--------------
+
+1. global mode
+PMU collect performance statistics for all HNS3 PCIe functions of IO DIE.
+Set the "global" filter option to 1 will enable this mode.
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,global=1/ -I 1000
+
+2. port mode
+PMU collect performance statistic of one whole physical port. The port id
+is same as mac id. The "tc" filter option must be set to 0xF in this mode,
+here tc stands for traffic class.
+
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,port=0,tc=0xF/ -I 1000
+
+3. port-tc mode
+PMU collect performance statistic of one tc of physical port. The port id
+is same as mac id. The "tc" filter option must be set to 0 ~ 7 in this
+mode.
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,port=0,tc=0/ -I 1000
+
+4. func mode
+PMU collect performance statistic of one PF/VF. The function id is BDF of
+PF/VF, its conversion formula::
+
+  func = (bus << 8) + (device << 3) + (function)
+
+for example:
+  BDF         func
+  35:00.0    0x3500
+  35:00.1    0x3501
+  35:01.0    0x3508
+
+In this mode, the "queue" filter option must be set to 0xFFFF.
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,bdf=0x3500,queue=0xFFFF/ -I 1000
+
+5. func-queue mode
+PMU collect performance statistic of one queue of PF/VF. The function id
+is BDF of PF/VF, the "queue" filter option must be set to the exact queue
+id of function.
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,bdf=0x3500,queue=0/ -I 1000
+
+6. func-intr mode
+PMU collect performance statistic of one interrupt of PF/VF. The function
+id is BDF of PF/VF, the "intr" filter option must be set to the exact
+interrupt id of function.
+Example usage of perf::
+
+  $# perf stat -a -e hns3_pmu_0/event=0,subevent=0,bdf=0x3500,intr=0/ -I 1000
-- 
2.33.0



From huangguangbin2 at huawei.com  Sun Jan 16 17:52:22 2022
From: huangguangbin2 at huawei.com (Guangbin Huang)
Date: Mon, 17 Jan 2022 09:52:22 +0800
Subject: [RESEND PATCH 2/2] drivers/perf: hisi: add driver for HNS3 PMU
In-Reply-To: <20220117015222.9617-1-huangguangbin2@huawei.com>
References: <20220117015222.9617-1-huangguangbin2@huawei.com>
Message-ID: <20220117015222.9617-3-huangguangbin2@huawei.com>

HNS3 PMU End Point device supports to collect performance statistics
of bandwidth, latency, packet rate, interrupt rate in HiSilicon SoC
NIC.

NIC of each IO DIE has one PMU device for it. Driver registers each
PMU device to perf, and exports information of supported events,
filter mode of each event, identifier and so on via sysfs.

Each PMU device has its own control, counter and interrupt registers,
and supports up to 8 events by hardware.

Filter options contains:
event        - select event
subevent     - select subevent
port         - select physical port of nic
tc           - select tc(must be used with port)
func         - select PF/VF
queue        - select queue of PF/VF(must be used with func)
intr         - select interrupt number(must be used with func)
global       - select all functions of IO DIE

Signed-off-by: Guangbin Huang <huangguangbin2 at huawei.com>
---
 MAINTAINERS                       |    6 +
 drivers/perf/hisilicon/Kconfig    |    9 +
 drivers/perf/hisilicon/Makefile   |    1 +
 drivers/perf/hisilicon/hns3_pmu.c | 1631 +++++++++++++++++++++++++++++
 include/linux/cpuhotplug.h        |    1 +
 5 files changed, 1648 insertions(+)
 create mode 100644 drivers/perf/hisilicon/hns3_pmu.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90a7d7b21982..e8e258bb8f8d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8614,6 +8614,12 @@ F:	Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 F:	Documentation/admin-guide/perf/hisi-pmu.rst
 F:	drivers/perf/hisilicon
 
+HISILICON HNS3 PMU DRIVER
+M:	Guangbin Huang <huangguangbin2 at huawei.com>
+S:	Supported
+F:	Documentation/admin-guide/perf/hns3-pmu.rst
+F:	drivers/perf/hisilicon/hns3_pmu.c
+
 HISILICON QM AND ZIP Controller DRIVER
 M:	Zhou Wang <wangzhou1 at hisilicon.com>
 L:	linux-crypto at vger.kernel.org
diff --git a/drivers/perf/hisilicon/Kconfig b/drivers/perf/hisilicon/Kconfig
index 5546218b5598..8a9661c97ec8 100644
--- a/drivers/perf/hisilicon/Kconfig
+++ b/drivers/perf/hisilicon/Kconfig
@@ -14,3 +14,12 @@ config HISI_PCIE_PMU
 	  RCiEP devices.
 	  Adds the PCIe PMU into perf events system for monitoring latency,
 	  bandwidth etc.
+
+config HNS3_PMU
+	tristate "HNS3 PERF PMU"
+	depends on ARM64 && PCI
+	help
+	  Provide support for HNS3 performance monitoring unit (PMU) IEP
+	  devices.
+	  Adds the HNS3 PMU into perf events system for monitoring latency,
+	  bandwidth etc.
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
index 506ed39e3266..13297ec2798f 100644
--- a/drivers/perf/hisilicon/Makefile
+++ b/drivers/perf/hisilicon/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
 			  hisi_uncore_pa_pmu.o
 
 obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
+obj-$(CONFIG_HNS3_PMU) += hns3_pmu.o
diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
new file mode 100644
index 000000000000..075b7eefe8d6
--- /dev/null
+++ b/drivers/perf/hisilicon/hns3_pmu.c
@@ -0,0 +1,1631 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This driver adds support for HNS3 PMU iEP device. Related perf events are
+ * bandwidth, latency, packet rate, interrupt rate etc.
+ *
+ * Copyright (C) 2021 HiSilicon Limited
+ */
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bug.h>
+#include <linux/cpuhotplug.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/iopoll.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/perf_event.h>
+#include <linux/smp.h>
+
+/* registers offset address */
+#define HNS3_PMU_REG_GLOBAL_CTRL		0x0000
+#define HNS3_PMU_REG_CLOCK_FREQ			0x0020
+#define HNS3_PMU_REG_BDF			0x0FE0
+#define HNS3_PMU_REG_VERSION			0x0FE4
+#define HNS3_PMU_REG_DEVICE_ID			0x0FE8
+
+#define HNS3_PMU_REG_EVENT_OFFSET		0x1000
+#define HNS3_PMU_REG_EVENT_SIZE			0x1000
+#define HNS3_PMU_REG_EVENT_CTRL_LOW		0x00
+#define HNS3_PMU_REG_EVENT_CTRL_HIGH		0x04
+#define HNS3_PMU_REG_EVENT_INTR_STATUS		0x08
+#define HNS3_PMU_REG_EVENT_INTR_MASK		0x0C
+#define HNS3_PMU_REG_EVENT_COUNTER		0x10
+#define HNS3_PMU_REG_EVENT_EXT_COUNTER		0x18
+#define HNS3_PMU_REG_EVENT_QID_CTRL		0x28
+#define HNS3_PMU_REG_EVENT_QID_PARA		0x2C
+
+#define HNS3_PMU_FILTER_SUPPORT_GLOBAL		BIT(0)
+#define HNS3_PMU_FILTER_SUPPORT_PORT		BIT(1)
+#define HNS3_PMU_FILTER_SUPPORT_PORT_TC		BIT(2)
+#define HNS3_PMU_FILTER_SUPPORT_FUNC		BIT(3)
+#define HNS3_PMU_FILTER_SUPPORT_FUNC_QUEUE	BIT(4)
+#define HNS3_PMU_FILTER_SUPPORT_FUNC_INTR	BIT(5)
+
+#define HNS3_PMU_FILTER_ALL_TC			0xF
+#define HNS3_PMU_FILTER_ALL_QUEUE		0xFFFF
+
+#define HNS3_PMU_CTRL_SUBEVENT_S		4
+#define HNS3_PMU_CTRL_FILTER_MODE_S		24
+
+#define HNS3_PMU_GLOBAL_START			BIT(0)
+
+#define HNS3_PMU_EVENT_STATUS_RESET		BIT(11)
+#define HNS3_PMU_EVENT_EN			BIT(12)
+#define HNS3_PMU_EVENT_OVERFLOW_RESTART		BIT(15)
+
+#define HNS3_PMU_QID_PARA_FUNC_S		0
+#define HNS3_PMU_QID_PARA_QUEUE_S		16
+
+#define HNS3_PMU_QID_CTRL_REQ_ENABLE		BIT(0)
+#define HNS3_PMU_QID_CTRL_DONE			BIT(1)
+#define HNS3_PMU_QID_CTRL_MISS			BIT(2)
+
+#define HNS3_PMU_INTR_MASK_OVERFLOW		BIT(1)
+
+#define HNS3_PMU_MAX_COUNTERS			8
+
+#define HNS3_PMU_INVALID_CPU_ID			(-1)
+
+enum hns3_pmu_event_type {
+	HNS3_PMU_EVENT_TYPE_BANDWIDTH,
+	HNS3_PMU_EVENT_TYPE_PACKET_RATE,
+	HNS3_PMU_EVENT_TYPE_LATENCY,
+	HNS3_PMU_EVENT_TYPE_INTR_RATE,
+};
+
+enum hns3_pmu_bandwidth_subevent_code {
+	HNS3_PMU_SUBEVT_BW_SSU_EGU = 1,
+	HNS3_PMU_SUBEVT_BW_SSU_RPU = 2,
+	HNS3_PMU_SUBEVT_BW_SSU_ROCE = 3,
+	HNS3_PMU_SUBEVT_BW_ROCE_SSU = 4,
+	HNS3_PMU_SUBEVT_BW_TPU_SSU = 5,
+	HNS3_PMU_SUBEVT_BW_RPU_RCBRX = 6,
+	HNS3_PMU_SUBEVT_BW_RCBTX_TXSCH = 8,
+	HNS3_PMU_SUBEVT_BW_WR_FBD = 9,
+	HNS3_PMU_SUBEVT_BW_WR_EBD = 10,
+	HNS3_PMU_SUBEVT_BW_RD_FBD = 11,
+	HNS3_PMU_SUBEVT_BW_RD_EBD = 12,
+	HNS3_PMU_SUBEVT_BW_RD_PAY_M0 = 13,
+	HNS3_PMU_SUBEVT_BW_RD_PAY_M1 = 14,
+	HNS3_PMU_SUBEVT_BW_WR_PAY_M0 = 15,
+	HNS3_PMU_SUBEVT_BW_WR_PAY_M1 = 16,
+};
+
+enum hns3_pmu_packet_rate_subevent_code {
+	HNS3_PMU_SUBEVT_PPS_IGU_SSU = 0,
+	HNS3_PMU_SUBEVT_PPS_SSU_EGU = 1,
+	HNS3_PMU_SUBEVT_PPS_SSU_RPU = 2,
+	HNS3_PMU_SUBEVT_PPS_SSU_ROCE = 3,
+	HNS3_PMU_SUBEVT_PPS_ROCE_SSU = 4,
+	HNS3_PMU_SUBEVT_PPS_TPU_SSU = 5,
+	HNS3_PMU_SUBEVT_PPS_RPU_RCBRX = 6,
+	HNS3_PMU_SUBEVT_PPS_RCBTX_TPU = 7,
+	HNS3_PMU_SUBEVT_PPS_RCBTX_TXSCH = 8,
+	HNS3_PMU_SUBEVT_PPS_WR_FBD = 9,
+	HNS3_PMU_SUBEVT_PPS_WR_EBD = 10,
+	HNS3_PMU_SUBEVT_PPS_RD_FBD = 11,
+	HNS3_PMU_SUBEVT_PPS_RD_EBD = 12,
+	HNS3_PMU_SUBEVT_PPS_RD_PAY_M0 = 13,
+	HNS3_PMU_SUBEVT_PPS_RD_PAY_M1 = 14,
+	HNS3_PMU_SUBEVT_PPS_WR_PAY_M0 = 15,
+	HNS3_PMU_SUBEVT_PPS_WR_PAY_M1 = 16,
+	HNS3_PMU_SUBEVT_PPS_NICROH_TX_PRE = 17,
+	HNS3_PMU_SUBEVT_PPS_NICROH_RX_PRE = 18,
+};
+
+enum hns3_pmu_latency_subevent_code {
+	HNS3_PMU_SUBEVT_DLY_TX_PUSH = 2,
+	HNS3_PMU_SUBEVT_DLY_TX = 4,
+	HNS3_PMU_SUBEVT_DLY_SSU_TX_NIC = 6,
+	HNS3_PMU_SUBEVT_DLY_SSU_TX_ROCE = 7,
+	HNS3_PMU_SUBEVT_DLY_SSU_RX_NIC = 8,
+	HNS3_PMU_SUBEVT_DLY_SSU_RX_ROCE = 9,
+	HNS3_PMU_SUBEVT_DLY_RPU = 14,
+	HNS3_PMU_SUBEVT_DLY_TPU = 15,
+	HNS3_PMU_SUBEVT_DLY_RPE = 16,
+	HNS3_PMU_SUBEVT_DLY_TPE = 17,
+	HNS3_PMU_SUBEVT_DLY_TPE_PUSH = 18,
+	HNS3_PMU_SUBEVT_DLY_WR_FBD = 19,
+	HNS3_PMU_SUBEVT_DLY_WR_EBD = 20,
+	HNS3_PMU_SUBEVT_DLY_RD_FBD = 21,
+	HNS3_PMU_SUBEVT_DLY_RD_EBD = 22,
+	HNS3_PMU_SUBEVT_DLY_RD_PAY_M0 = 23,
+	HNS3_PMU_SUBEVT_DLY_RD_PAY_M1 = 24,
+	HNS3_PMU_SUBEVT_DLY_WR_PAY_M0 = 25,
+	HNS3_PMU_SUBEVT_DLY_WR_PAY_M1 = 26,
+	HNS3_PMU_SUBEVT_DLY_MSIX_WRITE = 28,
+};
+
+enum hns3_pmu_interrupt_rate_subevent_code {
+	HNS3_PMU_SUBEVT_INTR_MSIX_NIC = 0,
+	HNS3_PMU_SUBEVT_INTR_MSIX_ROH = 1,
+};
+
+/* filter mode supported by each bandwidth subevent code */
+#define HNS3_PMU_FILTER_BW_SSU_EGU		0x07
+#define HNS3_PMU_FILTER_BW_SSU_RPU		0x1F
+#define HNS3_PMU_FILTER_BW_SSU_ROCE		0x0F
+#define HNS3_PMU_FILTER_BW_ROCE_SSU		0x0F
+#define HNS3_PMU_FILTER_BW_TPU_SSU		0x1F
+#define HNS3_PMU_FILTER_BW_RPU_RCBRX		0x11
+#define HNS3_PMU_FILTER_BW_RCBTX_TXSCH		0x11
+#define HNS3_PMU_FILTER_BW_WR_FBD		0x1B
+#define HNS3_PMU_FILTER_BW_WR_EBD		0x11
+#define HNS3_PMU_FILTER_BW_RD_FBD		0x01
+#define HNS3_PMU_FILTER_BW_RD_EBD		0x1B
+#define HNS3_PMU_FILTER_BW_RD_PAY_M0		0x01
+#define HNS3_PMU_FILTER_BW_RD_PAY_M1		0x01
+#define HNS3_PMU_FILTER_BW_WR_PAY_M0		0x01
+#define HNS3_PMU_FILTER_BW_WR_PAY_M1		0x01
+
+/* filter mode supported by each packet rate subevent code */
+#define HNS3_PMU_FILTER_PPS_IGU_SSU		0x07
+#define HNS3_PMU_FILTER_PPS_SSU_EGU		0x07
+#define HNS3_PMU_FILTER_PPS_SSU_RPU		0x1F
+#define HNS3_PMU_FILTER_PPS_SSU_ROCE		0x0F
+#define HNS3_PMU_FILTER_PPS_ROCE_SSU		0x0F
+#define HNS3_PMU_FILTER_PPS_TPU_SSU		0x1F
+#define HNS3_PMU_FILTER_PPS_RPU_RCBRX		0x11
+#define HNS3_PMU_FILTER_PPS_RCBTX_TPU		0x1F
+#define HNS3_PMU_FILTER_PPS_RCBTX_TXSCH		0x11
+#define HNS3_PMU_FILTER_PPS_WR_FBD		0x1B
+#define HNS3_PMU_FILTER_PPS_WR_EBD		0x11
+#define HNS3_PMU_FILTER_PPS_RD_FBD		0x01
+#define HNS3_PMU_FILTER_PPS_RD_EBD		0x1B
+#define HNS3_PMU_FILTER_PPS_RD_PAY_M0		0x01
+#define HNS3_PMU_FILTER_PPS_RD_PAY_M1		0x01
+#define HNS3_PMU_FILTER_PPS_WR_PAY_M0		0x01
+#define HNS3_PMU_FILTER_PPS_WR_PAY_M1		0x01
+#define HNS3_PMU_FILTER_PPS_NICROH_TX_PRE	0x01
+#define HNS3_PMU_FILTER_PPS_NICROH_RX_PRE	0x01
+
+/* filter mode supported by each latency subevent code */
+#define HNS3_PMU_FILTER_DLY_TX_PUSH		0x01
+#define HNS3_PMU_FILTER_DLY_TX			0x01
+#define HNS3_PMU_FILTER_DLY_SSU_TX_NIC		0x07
+#define HNS3_PMU_FILTER_DLY_SSU_TX_ROCE		0x07
+#define HNS3_PMU_FILTER_DLY_SSU_RX_NIC		0x07
+#define HNS3_PMU_FILTER_DLY_SSU_RX_ROCE		0x07
+#define HNS3_PMU_FILTER_DLY_RPU			0x11
+#define HNS3_PMU_FILTER_DLY_TPU			0x1F
+#define HNS3_PMU_FILTER_DLY_RPE			0x01
+#define HNS3_PMU_FILTER_DLY_TPE			0x0B
+#define HNS3_PMU_FILTER_DLY_TPE_PUSH		0x1B
+#define HNS3_PMU_FILTER_DLY_WR_FBD		0x1B
+#define HNS3_PMU_FILTER_DLY_WR_EBD		0x11
+#define HNS3_PMU_FILTER_DLY_RD_FBD		0x01
+#define HNS3_PMU_FILTER_DLY_RD_EBD		0x1B
+#define HNS3_PMU_FILTER_DLY_RD_PAY_M0		0x01
+#define HNS3_PMU_FILTER_DLY_RD_PAY_M1		0x01
+#define HNS3_PMU_FILTER_DLY_WR_PAY_M0		0x01
+#define HNS3_PMU_FILTER_DLY_WR_PAY_M1		0x01
+#define HNS3_PMU_FILTER_DLY_MSIX_WRITE		0x01
+
+/* filter mode supported by each interrupt rate subevent code */
+#define HNS3_PMU_FILTER_INTR_MSIX_NIC		0x01
+#define HNS3_PMU_FILTER_INTR_MSIX_ROH		0x01
+
+enum hns3_pmu_hw_filter_mode {
+	HNS3_PMU_HW_FILTER_GLOBAL,
+	HNS3_PMU_HW_FILTER_PORT,
+	HNS3_PMU_HW_FILTER_PORT_TC,
+	HNS3_PMU_HW_FILTER_FUNC,
+	HNS3_PMU_HW_FILTER_FUNC_QUEUE,
+	HNS3_PMU_HW_FILTER_FUNC_INTR,
+};
+
+struct hns3_pmu_event_attr {
+	u8 event;
+	u8 subevent;
+	u16 filter_support;
+};
+
+struct hns3_pmu {
+	struct perf_event *hw_events[HNS3_PMU_MAX_COUNTERS];
+	struct hlist_node node;
+	struct pci_dev *pdev;
+	struct pmu pmu;
+	void __iomem *base;
+	int irq;
+	int on_cpu;
+	u32 identifier;
+	u32 hw_clk_freq; /* hardware clock frequency of PMU */
+	/* maximum and minimun bdf allowed by PMU */
+	u16 bdf_min;
+	u16 bdf_max;
+};
+
+#define to_hns3_pmu(p)  (container_of((p), struct hns3_pmu, pmu))
+#define attr_to_dattr(a) (container_of((a), struct device_attribute, attr))
+#define dattr_to_eattr(d) (container_of((d), struct dev_ext_attribute, attr))
+
+#define GET_PCI_DEVFN(bdf)  ((bdf) & 0xFF)
+
+#define FILTER_CONDITION_PORT(port) ((1 << (port)) & 0xFF)
+#define FILTER_CONDITION_PORT_TC(port, tc) (((port) << 3) | ((tc) & 0x07))
+#define FILTER_CONDITION_FUNC_INTR(func, intr) (((intr) << 8) | (func))
+
+#define BYTES_TO_BITS(bytes)		((bytes) * 8)
+
+#define HNS3_PMU_FILTER_ATTR(_name, _config, _start, _end)            \
+	static inline u64 hns3_get_##_name(struct perf_event *event)  \
+	{                                                             \
+		return FIELD_GET(GENMASK_ULL(_end, _start),           \
+				 event->attr._config);                \
+	}
+
+HNS3_PMU_FILTER_ATTR(event, config, 0, 7);
+HNS3_PMU_FILTER_ATTR(subevent, config, 8, 15);
+HNS3_PMU_FILTER_ATTR(port, config1, 0, 3);
+HNS3_PMU_FILTER_ATTR(tc, config1, 4, 7);
+HNS3_PMU_FILTER_ATTR(bdf, config1, 8, 23);
+HNS3_PMU_FILTER_ATTR(queue, config1, 24, 39);
+HNS3_PMU_FILTER_ATTR(intr, config1, 40, 51);
+HNS3_PMU_FILTER_ATTR(global, config1, 52, 52);
+
+#define HNS3_CONSTRUCT_BW_EVENT(_name)                                    \
+	(&(struct hns3_pmu_event_attr) {HNS3_PMU_EVENT_TYPE_BANDWIDTH,    \
+					HNS3_PMU_SUBEVT_BW_##_name,       \
+					HNS3_PMU_FILTER_BW_##_name})
+#define HNS3_CONSTRUCT_PPS_EVENT(_name)                                   \
+	(&(struct hns3_pmu_event_attr) {HNS3_PMU_EVENT_TYPE_PACKET_RATE,  \
+					HNS3_PMU_SUBEVT_PPS_##_name,      \
+					HNS3_PMU_FILTER_PPS_##_name})
+#define HNS3_CONSTRUCT_DLY_EVENT(_name)                                   \
+	(&(struct hns3_pmu_event_attr) {HNS3_PMU_EVENT_TYPE_LATENCY,      \
+					HNS3_PMU_SUBEVT_DLY_##_name,      \
+					HNS3_PMU_FILTER_DLY_##_name})
+#define HNS3_CONSTRUCT_INTR_EVENT(_name)                                  \
+	(&(struct hns3_pmu_event_attr) {HNS3_PMU_EVENT_TYPE_INTR_RATE,    \
+					HNS3_PMU_SUBEVT_INTR_##_name,     \
+					HNS3_PMU_FILTER_INTR_##_name})
+
+static ssize_t hns3_pmu_format_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct dev_ext_attribute *eattr;
+
+	eattr = container_of(attr, struct dev_ext_attribute, attr);
+
+	return sysfs_emit(buf, "%s\n", (char *)eattr->var);
+}
+
+static ssize_t hns3_pmu_event_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct hns3_pmu_event_attr *event;
+	struct dev_ext_attribute *eattr;
+	u16 config;
+
+	eattr = container_of(attr, struct dev_ext_attribute, attr);
+	event = (struct hns3_pmu_event_attr *)eattr->var;
+	config = event->event << 8 | event->subevent;
+
+	return sysfs_emit(buf, "config=0x%04x\n", config);
+}
+
+static ssize_t hns3_pmu_filter_mode_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct hns3_pmu_event_attr *event;
+	struct dev_ext_attribute *eattr;
+	int len;
+
+	eattr = container_of(attr, struct dev_ext_attribute, attr);
+	event = (struct hns3_pmu_event_attr *)eattr->var;
+
+	len = sysfs_emit_at(buf, 0, "filter mode supported: ");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_GLOBAL)
+		len += sysfs_emit_at(buf, len, "global/");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_PORT)
+		len += sysfs_emit_at(buf, len, "port/");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_PORT_TC)
+		len += sysfs_emit_at(buf, len, "port-tc/");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC)
+		len += sysfs_emit_at(buf, len, "func/");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC_QUEUE)
+		len += sysfs_emit_at(buf, len, "func-queue/");
+	if (event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC_INTR)
+		len += sysfs_emit_at(buf, len, "func-intr/");
+
+	len += sysfs_emit_at(buf, len, "\n");
+
+	return len;
+}
+
+#define HNS3_PMU_ATTR(_name, _func, _config)				\
+	(&((struct dev_ext_attribute[]) {				\
+		{ __ATTR(_name, 0444, _func, NULL), (void *)_config }	\
+	})[0].attr.attr)
+
+#define HNS3_PMU_FORMAT_ATTR(_name, _format) \
+	HNS3_PMU_ATTR(_name, hns3_pmu_format_show, (void *)_format)
+#define HNS3_PMU_EVENT_ATTR(_name, _event) \
+	HNS3_PMU_ATTR(_name, hns3_pmu_event_show, (void *)_event)
+
+static u8 hns3_pmu_hw_filter_modes[] = {
+	HNS3_PMU_HW_FILTER_GLOBAL,
+	HNS3_PMU_HW_FILTER_PORT,
+	HNS3_PMU_HW_FILTER_PORT_TC,
+	HNS3_PMU_HW_FILTER_FUNC,
+	HNS3_PMU_HW_FILTER_FUNC_QUEUE,
+	HNS3_PMU_HW_FILTER_FUNC_INTR
+};
+
+#define HNS3_PMU_SET_HW_FILTER(_hwc, _mode) \
+	((_hwc)->addr_filters = (void *)&hns3_pmu_hw_filter_modes[(_mode)])
+
+static ssize_t identifier_show(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct hns3_pmu *hns3_pmu;
+
+	hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "0x%x\n", hns3_pmu->identifier);
+}
+static DEVICE_ATTR_RO(identifier);
+
+static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "%d\n", hns3_pmu->on_cpu);
+}
+static DEVICE_ATTR_RO(cpumask);
+
+static ssize_t bdf_min_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "0x%4x\n", hns3_pmu->bdf_min);
+}
+static DEVICE_ATTR_RO(bdf_min);
+
+static ssize_t bdf_max_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
+
+	return sysfs_emit(buf, "0x%4x\n", hns3_pmu->bdf_max);
+}
+static DEVICE_ATTR_RO(bdf_max);
+
+static struct attribute *hns3_pmu_events_attr[] = {
+	/* bandwidth events */
+	HNS3_PMU_EVENT_ATTR(bw_ssu_egu,
+			    HNS3_CONSTRUCT_BW_EVENT(SSU_EGU)),
+	HNS3_PMU_EVENT_ATTR(bw_ssu_rpu,
+			    HNS3_CONSTRUCT_BW_EVENT(SSU_RPU)),
+	HNS3_PMU_EVENT_ATTR(bw_ssu_roce,
+			    HNS3_CONSTRUCT_BW_EVENT(SSU_ROCE)),
+	HNS3_PMU_EVENT_ATTR(bw_roce_ssu,
+			    HNS3_CONSTRUCT_BW_EVENT(ROCE_SSU)),
+	HNS3_PMU_EVENT_ATTR(bw_tpu_ssu,
+			    HNS3_CONSTRUCT_BW_EVENT(TPU_SSU)),
+	HNS3_PMU_EVENT_ATTR(bw_rpu_rcbrx,
+			    HNS3_CONSTRUCT_BW_EVENT(RPU_RCBRX)),
+	HNS3_PMU_EVENT_ATTR(bw_rcbtx_txsch,
+			    HNS3_CONSTRUCT_BW_EVENT(RCBTX_TXSCH)),
+	HNS3_PMU_EVENT_ATTR(bw_wr_fbd,
+			    HNS3_CONSTRUCT_BW_EVENT(WR_FBD)),
+	HNS3_PMU_EVENT_ATTR(bw_wr_ebd,
+			    HNS3_CONSTRUCT_BW_EVENT(WR_EBD)),
+	HNS3_PMU_EVENT_ATTR(bw_rd_fbd,
+			    HNS3_CONSTRUCT_BW_EVENT(RD_FBD)),
+	HNS3_PMU_EVENT_ATTR(bw_rd_ebd,
+			    HNS3_CONSTRUCT_BW_EVENT(RD_EBD)),
+	HNS3_PMU_EVENT_ATTR(bw_rd_pay_m0,
+			    HNS3_CONSTRUCT_BW_EVENT(RD_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(bw_rd_pay_m1,
+			    HNS3_CONSTRUCT_BW_EVENT(RD_PAY_M1)),
+	HNS3_PMU_EVENT_ATTR(bw_wr_pay_m0,
+			    HNS3_CONSTRUCT_BW_EVENT(WR_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(bw_wr_pay_m1,
+			    HNS3_CONSTRUCT_BW_EVENT(WR_PAY_M1)),
+
+	/* packet rate events */
+	HNS3_PMU_EVENT_ATTR(pps_igu_ssu,
+			    HNS3_CONSTRUCT_PPS_EVENT(IGU_SSU)),
+	HNS3_PMU_EVENT_ATTR(pps_ssu_egu,
+			    HNS3_CONSTRUCT_PPS_EVENT(SSU_EGU)),
+	HNS3_PMU_EVENT_ATTR(pps_ssu_rpu,
+			    HNS3_CONSTRUCT_PPS_EVENT(SSU_RPU)),
+	HNS3_PMU_EVENT_ATTR(pps_ssu_roce,
+			    HNS3_CONSTRUCT_PPS_EVENT(SSU_ROCE)),
+	HNS3_PMU_EVENT_ATTR(pps_roce_ssu,
+			    HNS3_CONSTRUCT_PPS_EVENT(ROCE_SSU)),
+	HNS3_PMU_EVENT_ATTR(pps_tpu_ssu,
+			    HNS3_CONSTRUCT_PPS_EVENT(TPU_SSU)),
+	HNS3_PMU_EVENT_ATTR(pps_rpu_rcbrx,
+			    HNS3_CONSTRUCT_PPS_EVENT(RPU_RCBRX)),
+	HNS3_PMU_EVENT_ATTR(pps_rcbtx_tpu,
+			    HNS3_CONSTRUCT_PPS_EVENT(RCBTX_TPU)),
+	HNS3_PMU_EVENT_ATTR(pps_rcbtx_txsch,
+			    HNS3_CONSTRUCT_PPS_EVENT(RCBTX_TXSCH)),
+	HNS3_PMU_EVENT_ATTR(pps_wr_fbd,
+			    HNS3_CONSTRUCT_PPS_EVENT(WR_FBD)),
+	HNS3_PMU_EVENT_ATTR(pps_wr_ebd,
+			    HNS3_CONSTRUCT_PPS_EVENT(WR_EBD)),
+	HNS3_PMU_EVENT_ATTR(pps_rd_fbd,
+			    HNS3_CONSTRUCT_PPS_EVENT(RD_FBD)),
+	HNS3_PMU_EVENT_ATTR(pps_rd_ebd,
+			    HNS3_CONSTRUCT_PPS_EVENT(RD_EBD)),
+	HNS3_PMU_EVENT_ATTR(pps_rd_pay_m0,
+			    HNS3_CONSTRUCT_PPS_EVENT(RD_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(pps_rd_pay_m1,
+			    HNS3_CONSTRUCT_PPS_EVENT(RD_PAY_M1)),
+	HNS3_PMU_EVENT_ATTR(pps_wr_pay_m0,
+			    HNS3_CONSTRUCT_PPS_EVENT(WR_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(pps_wr_pay_m1,
+			    HNS3_CONSTRUCT_PPS_EVENT(WR_PAY_M1)),
+	HNS3_PMU_EVENT_ATTR(pps_intr_nicroh_tx_pre,
+			    HNS3_CONSTRUCT_PPS_EVENT(NICROH_TX_PRE)),
+	HNS3_PMU_EVENT_ATTR(pps_intr_nicroh_rx_pre,
+			    HNS3_CONSTRUCT_PPS_EVENT(NICROH_RX_PRE)),
+
+	/* latency events */
+	HNS3_PMU_EVENT_ATTR(dly_tx_push_to_mac,
+			    HNS3_CONSTRUCT_DLY_EVENT(TX_PUSH)),
+	HNS3_PMU_EVENT_ATTR(dly_tx_normal_to_mac,
+			    HNS3_CONSTRUCT_DLY_EVENT(TX)),
+	HNS3_PMU_EVENT_ATTR(dly_ssu_tx_th_nic,
+			    HNS3_CONSTRUCT_DLY_EVENT(SSU_TX_NIC)),
+	HNS3_PMU_EVENT_ATTR(dly_ssu_tx_th_roce,
+			    HNS3_CONSTRUCT_DLY_EVENT(SSU_TX_ROCE)),
+	HNS3_PMU_EVENT_ATTR(dly_ssu_rx_th_nic,
+			    HNS3_CONSTRUCT_DLY_EVENT(SSU_RX_NIC)),
+	HNS3_PMU_EVENT_ATTR(dly_ssu_rx_th_roce,
+			    HNS3_CONSTRUCT_DLY_EVENT(SSU_RX_ROCE)),
+	HNS3_PMU_EVENT_ATTR(dly_rpu,
+			    HNS3_CONSTRUCT_DLY_EVENT(RPU)),
+	HNS3_PMU_EVENT_ATTR(dly_tpu,
+			    HNS3_CONSTRUCT_DLY_EVENT(TPU)),
+	HNS3_PMU_EVENT_ATTR(dly_rpe,
+			    HNS3_CONSTRUCT_DLY_EVENT(RPE)),
+	HNS3_PMU_EVENT_ATTR(dly_tpe_normal,
+			    HNS3_CONSTRUCT_DLY_EVENT(TPE)),
+	HNS3_PMU_EVENT_ATTR(dly_tpe_push,
+			    HNS3_CONSTRUCT_DLY_EVENT(TPE_PUSH)),
+	HNS3_PMU_EVENT_ATTR(dly_wr_fbd,
+			    HNS3_CONSTRUCT_DLY_EVENT(WR_FBD)),
+	HNS3_PMU_EVENT_ATTR(dly_wr_ebd,
+			    HNS3_CONSTRUCT_DLY_EVENT(WR_EBD)),
+	HNS3_PMU_EVENT_ATTR(dly_rd_fbd,
+			    HNS3_CONSTRUCT_DLY_EVENT(RD_FBD)),
+	HNS3_PMU_EVENT_ATTR(dly_rd_ebd,
+			    HNS3_CONSTRUCT_DLY_EVENT(RD_EBD)),
+	HNS3_PMU_EVENT_ATTR(dly_rd_pay_m0,
+			    HNS3_CONSTRUCT_DLY_EVENT(RD_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(dly_rd_pay_m1,
+			    HNS3_CONSTRUCT_DLY_EVENT(RD_PAY_M1)),
+	HNS3_PMU_EVENT_ATTR(dly_wr_pay_m0,
+			    HNS3_CONSTRUCT_DLY_EVENT(WR_PAY_M0)),
+	HNS3_PMU_EVENT_ATTR(dly_wr_pay_m1,
+			    HNS3_CONSTRUCT_DLY_EVENT(WR_PAY_M1)),
+	HNS3_PMU_EVENT_ATTR(dly_msix_write,
+			    HNS3_CONSTRUCT_DLY_EVENT(MSIX_WRITE)),
+
+	/* interrupt rate events */
+	HNS3_PMU_EVENT_ATTR(pps_intr_msix_nic,
+			    HNS3_CONSTRUCT_INTR_EVENT(MSIX_NIC)),
+	HNS3_PMU_EVENT_ATTR(pps_intr_msix_roh,
+			    HNS3_CONSTRUCT_INTR_EVENT(MSIX_ROH)),
+	NULL
+};
+
+static struct attribute_group hns3_pmu_events_group = {
+	.name = "events",
+	.attrs = hns3_pmu_events_attr,
+};
+
+static struct attribute_group hns3_pmu_filter_mode_group = {
+	.name = "filtermode",
+};
+
+static struct attribute *hns3_pmu_format_attr[] = {
+	HNS3_PMU_FORMAT_ATTR(event, "config:0-7"),
+	HNS3_PMU_FORMAT_ATTR(subevent, "config:8-15"),
+	HNS3_PMU_FORMAT_ATTR(port, "config1:0-3"),
+	HNS3_PMU_FORMAT_ATTR(tc, "config1:4-7"),
+	HNS3_PMU_FORMAT_ATTR(bdf, "config1:8-23"),
+	HNS3_PMU_FORMAT_ATTR(queue, "config1:24-39"),
+	HNS3_PMU_FORMAT_ATTR(intr, "config1:40-51"),
+	HNS3_PMU_FORMAT_ATTR(global, "config1:52-52"),
+	NULL
+};
+
+static struct attribute_group hns3_pmu_format_group = {
+	.name = "format",
+	.attrs = hns3_pmu_format_attr,
+};
+
+static struct attribute *hns3_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL
+};
+
+static struct attribute_group hns3_pmu_cpumask_attr_group = {
+	.attrs = hns3_pmu_cpumask_attrs,
+};
+
+static struct attribute *hns3_pmu_identifier_attrs[] = {
+	&dev_attr_identifier.attr,
+	NULL
+};
+
+static struct attribute_group hns3_pmu_identifier_attr_group = {
+	.attrs = hns3_pmu_identifier_attrs,
+};
+
+static struct attribute *hns3_pmu_bdf_range_attrs[] = {
+	&dev_attr_bdf_min.attr,
+	&dev_attr_bdf_max.attr,
+	NULL
+};
+
+static struct attribute_group hns3_pmu_bdf_range_attr_group = {
+	.attrs = hns3_pmu_bdf_range_attrs,
+};
+
+static const struct attribute_group *hns3_pmu_attr_groups[] = {
+	&hns3_pmu_events_group,
+	&hns3_pmu_filter_mode_group,
+	&hns3_pmu_format_group,
+	&hns3_pmu_cpumask_attr_group,
+	&hns3_pmu_identifier_attr_group,
+	&hns3_pmu_bdf_range_attr_group,
+	NULL
+};
+
+static int hns3_pmu_init_filter_mode_group(void)
+{
+	u32 group_size = ARRAY_SIZE(hns3_pmu_events_attr);
+	struct dev_ext_attribute *eattr_filter;
+	struct dev_ext_attribute *eattr_event;
+	struct device_attribute *dattr_event;
+	struct attribute **attr_filter;
+	struct attribute *attr_event;
+	u32 i;
+
+	attr_filter = kcalloc(group_size, sizeof(struct attribute *),
+			      GFP_KERNEL);
+	if (!attr_filter)
+		return -ENOMEM;
+
+	eattr_filter = kcalloc(group_size - 1, sizeof(struct dev_ext_attribute),
+			       GFP_KERNEL);
+	if (!eattr_filter) {
+		kfree(attr_filter);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < group_size - 1; i++) {
+		attr_event = hns3_pmu_events_attr[i];
+		dattr_event = attr_to_dattr(attr_event);
+		eattr_event = dattr_to_eattr(dattr_event);
+
+		memcpy(&eattr_filter[i], eattr_event,
+		       sizeof(struct dev_ext_attribute));
+		eattr_filter[i].attr.show = hns3_pmu_filter_mode_show;
+
+		attr_filter[i] = &eattr_filter[i].attr.attr;
+	}
+
+	hns3_pmu_filter_mode_group.attrs = attr_filter;
+
+	return 0;
+}
+
+static void hns3_pmu_uinit_filter_mode_group(void)
+{
+	struct dev_ext_attribute *eattr;
+	struct device_attribute *dattr;
+	struct attribute **attrs;
+
+	attrs = hns3_pmu_filter_mode_group.attrs;
+	dattr = attr_to_dattr(attrs[0]);
+	eattr = dattr_to_eattr(dattr);
+
+	kfree(eattr);
+	kfree(attrs);
+
+	hns3_pmu_filter_mode_group.attrs = NULL;
+}
+
+static u32 hns3_pmu_get_offset(u32 offset, u32 idx)
+{
+	return offset + HNS3_PMU_REG_EVENT_OFFSET +
+	       HNS3_PMU_REG_EVENT_SIZE * idx;
+}
+
+static u32 hns3_pmu_readl(struct hns3_pmu *hns3_pmu, u32 reg_offset, u32 idx)
+{
+	u32 offset = hns3_pmu_get_offset(reg_offset, idx);
+
+	return readl(hns3_pmu->base + offset);
+}
+
+static void hns3_pmu_writel(struct hns3_pmu *hns3_pmu, u32 reg_offset, u32 idx,
+			    u32 val)
+{
+	u32 offset = hns3_pmu_get_offset(reg_offset, idx);
+
+	writel(val, hns3_pmu->base + offset);
+}
+
+static u64 hns3_pmu_readq(struct hns3_pmu *hns3_pmu, u32 reg_offset, u32 idx)
+{
+	u32 offset = hns3_pmu_get_offset(reg_offset, idx);
+
+	return readq(hns3_pmu->base + offset);
+}
+
+static void hns3_pmu_writeq(struct hns3_pmu *hns3_pmu, u32 reg_offset, u32 idx,
+			    u64 val)
+{
+	u32 offset = hns3_pmu_get_offset(reg_offset, idx);
+
+	writeq(val, hns3_pmu->base + offset);
+}
+
+static int hns3_pmu_get_event_idx(struct hns3_pmu *hns3_pmu)
+{
+	int idx;
+
+	for (idx = 0; idx < HNS3_PMU_MAX_COUNTERS; idx++)
+		if (!hns3_pmu->hw_events[idx])
+			return idx;
+
+	return -EBUSY;
+}
+
+static bool hns3_pmu_valid_bdf(struct hns3_pmu *hns3_pmu, u16 bdf)
+{
+	struct pci_dev *pdev;
+
+	if (bdf < hns3_pmu->bdf_min || bdf > hns3_pmu->bdf_max) {
+		pci_err(hns3_pmu->pdev, "Invalid EP device: %#x!\n", bdf);
+		return false;
+	}
+
+	pdev = pci_get_domain_bus_and_slot(pci_domain_nr(hns3_pmu->pdev->bus),
+					   PCI_BUS_NUM(bdf),
+					   GET_PCI_DEVFN(bdf));
+	if (!pdev) {
+		pci_err(hns3_pmu->pdev, "Nonexistent EP device: %#x!\n", bdf);
+		return false;
+	}
+
+	pci_dev_put(pdev);
+	return true;
+}
+
+static void hns3_pmu_set_qid_para(struct hns3_pmu *hns3_pmu, u32 idx, u16 bdf,
+				  u16 queue)
+{
+	u32 val;
+
+	val = GET_PCI_DEVFN(bdf);
+	val |= (u32)queue << HNS3_PMU_QID_PARA_QUEUE_S;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_QID_PARA, idx, val);
+}
+
+static bool hns3_pmu_qid_req_start(struct hns3_pmu *hns3_pmu, u32 idx)
+{
+	bool queue_id_valid = false;
+	u32 reg_qid_ctrl, val;
+	int err;
+
+	/* enable queue id request */
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_QID_CTRL, idx,
+			HNS3_PMU_QID_CTRL_REQ_ENABLE);
+
+	reg_qid_ctrl = hns3_pmu_get_offset(HNS3_PMU_REG_EVENT_QID_CTRL, idx);
+	err = readl_poll_timeout(hns3_pmu->base + reg_qid_ctrl, val,
+				 val & HNS3_PMU_QID_CTRL_DONE, 1, 1000);
+	if (err == -ETIMEDOUT) {
+		pci_err(hns3_pmu->pdev, "QID request timeout!\n");
+		goto out;
+	}
+
+	queue_id_valid = (val & HNS3_PMU_QID_CTRL_MISS) == 0;
+
+out:
+	/* disable qid request and clear status */
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_QID_CTRL, idx, 0);
+
+	return queue_id_valid;
+}
+
+static bool hns3_pmu_valid_queue(struct hns3_pmu *hns3_pmu, u32 idx, u16 bdf,
+				 u16 queue)
+{
+	hns3_pmu_set_qid_para(hns3_pmu, idx, bdf, queue);
+
+	return hns3_pmu_qid_req_start(hns3_pmu, idx);
+}
+
+static struct hns3_pmu_event_attr *hns3_pmu_get_pmu_event(u8 event, u8 subevent)
+{
+	struct hns3_pmu_event_attr *pmu_event;
+	struct dev_ext_attribute *eattr;
+	struct device_attribute *dattr;
+	struct attribute *attr;
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(hns3_pmu_events_attr) - 1; i++) {
+		attr = hns3_pmu_events_attr[i];
+		dattr = container_of(attr, struct device_attribute, attr);
+		eattr = container_of(dattr, struct dev_ext_attribute, attr);
+		pmu_event = (struct hns3_pmu_event_attr *)eattr->var;
+
+		if (event == pmu_event->event &&
+		    subevent == pmu_event->subevent)
+			return pmu_event;
+	}
+
+	return NULL;
+}
+
+static int hns3_pmu_set_func_mode(struct perf_event *event,
+				  struct hns3_pmu *hns3_pmu)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u16 bdf = hns3_get_bdf(event);
+
+	if (!hns3_pmu_valid_bdf(hns3_pmu, bdf))
+		return -ENOENT;
+
+	HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_FUNC);
+
+	return 0;
+}
+
+static int hns3_pmu_set_func_queue_mode(struct perf_event *event,
+					struct hns3_pmu *hns3_pmu)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u16 queue_id = hns3_get_queue(event);
+	u16 bdf = hns3_get_bdf(event);
+
+	if (!hns3_pmu_valid_bdf(hns3_pmu, bdf))
+		return -ENOENT;
+
+	if (!hns3_pmu_valid_queue(hns3_pmu, hwc->idx, bdf, queue_id)) {
+		pci_err(hns3_pmu->pdev, "Invalid queue: %u\n", queue_id);
+		return -ENOENT;
+	}
+
+	HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_FUNC_QUEUE);
+
+	return 0;
+}
+
+static bool
+hns3_pmu_is_enabled_global_mode(struct perf_event *event,
+				struct hns3_pmu_event_attr *pmu_event)
+{
+	u8 global = hns3_get_global(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_GLOBAL &&
+	       !!global;
+}
+
+static bool hns3_pmu_is_enabled_func_mode(struct perf_event *event,
+					  struct hns3_pmu_event_attr *pmu_event)
+{
+	u16 queue_id = hns3_get_queue(event);
+	u16 bdf = hns3_get_bdf(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC &&
+	       queue_id == HNS3_PMU_FILTER_ALL_QUEUE && !!bdf;
+}
+
+static bool
+hns3_pmu_is_enabled_func_queue_mode(struct perf_event *event,
+				    struct hns3_pmu_event_attr *pmu_event)
+{
+	u16 queue_id = hns3_get_queue(event);
+	u16 bdf = hns3_get_bdf(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC_QUEUE &&
+	       queue_id != HNS3_PMU_FILTER_ALL_QUEUE && !!bdf;
+}
+
+static bool hns3_pmu_is_enabled_port_mode(struct perf_event *event,
+					  struct hns3_pmu_event_attr *pmu_event)
+{
+	u8 tc_id = hns3_get_tc(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_PORT &&
+	       tc_id == HNS3_PMU_FILTER_ALL_TC;
+}
+
+static bool
+hns3_pmu_is_enabled_port_tc_mode(struct perf_event *event,
+				 struct hns3_pmu_event_attr *pmu_event)
+{
+	u8 tc_id = hns3_get_tc(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_PORT_TC &&
+	       tc_id != HNS3_PMU_FILTER_ALL_TC;
+}
+
+static bool
+hns3_pmu_is_enabled_func_intr_mode(struct perf_event *event,
+				   struct hns3_pmu *hns3_pmu,
+				   struct hns3_pmu_event_attr *pmu_event)
+{
+	u16 bdf = hns3_get_bdf(event);
+
+	return pmu_event->filter_support & HNS3_PMU_FILTER_SUPPORT_FUNC_INTR &&
+	       hns3_pmu_valid_bdf(hns3_pmu, bdf);
+}
+
+static int hns3_pmu_select_filter_mode(struct perf_event *event,
+				       struct hns3_pmu *hns3_pmu)
+{
+	struct hns3_pmu_event_attr *pmu_event;
+	struct hw_perf_event *hwc = &event->hw;
+	u8 subevent_id = hns3_get_subevent(event);
+	u8 event_id = hns3_get_event(event);
+
+	pmu_event = hns3_pmu_get_pmu_event(event_id, subevent_id);
+	if (!pmu_event) {
+		pci_err(hns3_pmu->pdev, "Invalid pmu event\n");
+		return -ENOENT;
+	}
+
+	if (hns3_pmu_is_enabled_global_mode(event, pmu_event)) {
+		HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_GLOBAL);
+		return 0;
+	}
+
+	if (hns3_pmu_is_enabled_func_mode(event, pmu_event))
+		return hns3_pmu_set_func_mode(event, hns3_pmu);
+
+	if (hns3_pmu_is_enabled_func_queue_mode(event, pmu_event))
+		return hns3_pmu_set_func_queue_mode(event, hns3_pmu);
+
+	if (hns3_pmu_is_enabled_port_mode(event, pmu_event)) {
+		HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_PORT);
+		return 0;
+	}
+
+	if (hns3_pmu_is_enabled_port_tc_mode(event, pmu_event)) {
+		HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_PORT_TC);
+		return 0;
+	}
+
+	if (hns3_pmu_is_enabled_func_intr_mode(event, hns3_pmu, pmu_event)) {
+		HNS3_PMU_SET_HW_FILTER(hwc, HNS3_PMU_HW_FILTER_FUNC_INTR);
+		return 0;
+	}
+
+	return -ENOENT;
+}
+
+static bool hns3_pmu_validate_event_group(struct perf_event *event)
+{
+	struct perf_event *leader = event->group_leader;
+	struct perf_event *sibling;
+	int counters = 1;
+
+	if (!is_software_event(leader)) {
+		/*
+		 * We must NOT create groups containing mixed PMUs, although
+		 * software events are acceptable
+		 */
+		if (leader->pmu != event->pmu)
+			return false;
+
+		/* Increase counter for the leader */
+		if (leader != event)
+			counters++;
+	}
+
+	for_each_sibling_event(sibling, event->group_leader) {
+		if (is_software_event(sibling))
+			continue;
+
+		if (sibling->pmu != event->pmu)
+			return false;
+
+		/* Increase counter for each sibling */
+		counters++;
+	}
+
+	return counters <= HNS3_PMU_MAX_COUNTERS;
+}
+
+static u32 hns3_pmu_get_filter_condition(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u16 intr_id = hns3_get_intr(event);
+	u8 port_id = hns3_get_port(event);
+	u16 bdf = hns3_get_bdf(event);
+	u8 tc_id = hns3_get_tc(event);
+	u8 filter_mode;
+	u32 filter = 0;
+
+	filter_mode = *(u8 *)hwc->addr_filters;
+	switch (filter_mode) {
+	case HNS3_PMU_HW_FILTER_PORT:
+		filter = FILTER_CONDITION_PORT(port_id);
+		break;
+	case HNS3_PMU_HW_FILTER_PORT_TC:
+		filter = FILTER_CONDITION_PORT_TC(port_id, tc_id);
+		break;
+	case HNS3_PMU_HW_FILTER_FUNC:
+	case HNS3_PMU_HW_FILTER_FUNC_QUEUE:
+		filter = GET_PCI_DEVFN(bdf);
+		break;
+	case HNS3_PMU_HW_FILTER_FUNC_INTR:
+		filter = FILTER_CONDITION_FUNC_INTR(GET_PCI_DEVFN(bdf),
+						    intr_id);
+		break;
+	default:
+		break;
+	}
+
+	return filter;
+}
+
+static void hns3_pmu_config_filter(struct perf_event *event)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	u8 filter_mode = *(u8 *)hwc->addr_filters;
+	u8 subevent_id = hns3_get_subevent(event);
+	u16 queue_id = hns3_get_queue(event);
+	u8 event_id = hns3_get_event(event);
+	u16 bdf = hns3_get_bdf(event);
+	u32 idx = hwc->idx;
+	u32 val;
+
+	val = event_id;
+	val |= subevent_id << HNS3_PMU_CTRL_SUBEVENT_S;
+	val |= filter_mode << HNS3_PMU_CTRL_FILTER_MODE_S;
+	val |= HNS3_PMU_EVENT_OVERFLOW_RESTART;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx, val);
+
+	val = hns3_pmu_get_filter_condition(event);
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_HIGH, idx, val);
+
+	if (filter_mode == HNS3_PMU_HW_FILTER_FUNC_QUEUE)
+		hns3_pmu_set_qid_para(hns3_pmu, idx, bdf, queue_id);
+}
+
+static void hns3_pmu_enable_counter(struct hns3_pmu *hns3_pmu,
+				    struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u32 val;
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx);
+	val |= HNS3_PMU_EVENT_EN;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx, val);
+}
+
+static void hns3_pmu_disable_counter(struct hns3_pmu *hns3_pmu,
+				     struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u32 val;
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx);
+	val &= ~HNS3_PMU_EVENT_EN;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx, val);
+}
+
+static void hns3_pmu_enable_intr(struct hns3_pmu *hns3_pmu,
+				 struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u32 val;
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_INTR_MASK, idx);
+	val &= ~HNS3_PMU_INTR_MASK_OVERFLOW;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_INTR_MASK, idx, val);
+}
+
+static void hns3_pmu_disable_intr(struct hns3_pmu *hns3_pmu,
+				  struct hw_perf_event *hwc)
+{
+	u32 idx = hwc->idx;
+	u32 val;
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_INTR_MASK, idx);
+	val |= HNS3_PMU_INTR_MASK_OVERFLOW;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_INTR_MASK, idx, val);
+}
+
+static void hns3_pmu_clear_intr_status(struct hns3_pmu *hns3_pmu, u32 idx)
+{
+	u32 val;
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx);
+	val |= HNS3_PMU_EVENT_STATUS_RESET;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx, val);
+
+	val = hns3_pmu_readl(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx);
+	val &= ~HNS3_PMU_EVENT_STATUS_RESET;
+	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_CTRL_LOW, idx, val);
+}
+
+static void hns3_pmu_read_counter(struct perf_event *event, u64 *cnt,
+				  u64 *cnt_ext)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	u32 idx = event->hw.idx;
+
+	*cnt = hns3_pmu_readq(hns3_pmu, HNS3_PMU_REG_EVENT_COUNTER, idx);
+	*cnt_ext = hns3_pmu_readq(hns3_pmu, HNS3_PMU_REG_EVENT_EXT_COUNTER,
+				  idx);
+}
+
+static void hns3_pmu_write_counter(struct perf_event *event, u64 cnt,
+				   u64 cnt_ext)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	u32 idx = event->hw.idx;
+
+	hns3_pmu_writeq(hns3_pmu, HNS3_PMU_REG_EVENT_COUNTER, idx, cnt);
+	hns3_pmu_writeq(hns3_pmu, HNS3_PMU_REG_EVENT_EXT_COUNTER, idx, cnt_ext);
+}
+
+static void hns3_pmu_init_counter(struct perf_event *event)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *hwc_ext;
+
+	hwc_ext = &hwc->extra_reg;
+	local64_set(&hwc->prev_count, 0);
+	hwc_ext->config = 0;
+	hns3_pmu_write_counter(event, 0, 0);
+}
+
+static u64 hns3_pmu_tick_to_ms(u32 hw_clk_freq, u64 ticks)
+{
+	u64 time_ms = ticks / (hw_clk_freq / 1000);
+
+	if (!time_ms)
+		time_ms = 1;
+
+	return time_ms;
+}
+
+/*
+ * The performance calculation formula of all types of event is
+ *                 performance = data / data_ext.
+ * The arguments data and data_ext have different meanings for different types
+ * of events as follow:
+ * event_type             data                     data_ext
+ * bandwidth              byte number              cycles number
+ * packet rate            packet number            cycles number
+ * interrupt rate         interrupt number         cycles number
+ * latency                cycles number            packet number
+ */
+static u64 hns3_pmu_get_performance(u8 event_type, u32 hw_clk_freq, u64 data,
+				    u64 data_ext)
+{
+	u64 result;
+
+	if (!hw_clk_freq || !data || !data_ext)
+		return 0;
+
+	switch (event_type) {
+	case HNS3_PMU_EVENT_TYPE_BANDWIDTH:
+		/* process data to set unit of bandwidth as "KBits/s" */
+		result = data / hns3_pmu_tick_to_ms(hw_clk_freq, data_ext);
+		result = BYTES_TO_BITS(result);
+		break;
+
+	case HNS3_PMU_EVENT_TYPE_PACKET_RATE:
+	case HNS3_PMU_EVENT_TYPE_INTR_RATE:
+		/* process data to set unit as "pps" */
+		result = data * 1000 /
+			 hns3_pmu_tick_to_ms(hw_clk_freq, data_ext);
+		break;
+
+	case HNS3_PMU_EVENT_TYPE_LATENCY:
+		/* process data to set unit of latency as "ns" */
+		result = data / data_ext;
+		result = result * 1000000000 / hw_clk_freq;
+		break;
+
+	default:
+		result = data / data_ext;
+		break;
+	}
+
+	return result;
+}
+
+static int hns3_pmu_event_init(struct perf_event *event)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+	int ret;
+
+	if (event->attr.type != event->pmu->type)
+		return -ENOENT;
+
+	/* Sampling is not supported */
+	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
+		return -EOPNOTSUPP;
+
+	event->cpu = hns3_pmu->on_cpu;
+
+	idx = hns3_pmu_get_event_idx(hns3_pmu);
+	if (idx < 0) {
+		pci_err(hns3_pmu->pdev, "Up to %u events are supported!\n",
+			HNS3_PMU_MAX_COUNTERS);
+		return -EBUSY;
+	}
+
+	hwc->idx = idx;
+
+	ret = hns3_pmu_select_filter_mode(event, hns3_pmu);
+	if (ret) {
+		pci_err(hns3_pmu->pdev, "Invalid filter, ret = %d.\n", ret);
+		return ret;
+	}
+
+	if (!hns3_pmu_validate_event_group(event)) {
+		pci_err(hns3_pmu->pdev, "Invalid event group.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void hns3_pmu_read(struct perf_event *event)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	struct hw_perf_event_extra *hwc_ext;
+	u64 new_cnt_ext, prev_cnt_ext;
+	u64 new_cnt, prev_cnt, delta;
+
+	hwc_ext = &hwc->extra_reg;
+	do {
+		prev_cnt = local64_read(&hwc->prev_count);
+		prev_cnt_ext = hwc_ext->config;
+		hns3_pmu_read_counter(event, &new_cnt, &new_cnt_ext);
+	} while (local64_cmpxchg(&hwc->prev_count, prev_cnt, new_cnt) !=
+		 prev_cnt);
+
+	hwc_ext->config = new_cnt_ext;
+
+	delta = hns3_pmu_get_performance(hns3_get_event(event),
+					 hns3_pmu->hw_clk_freq,
+					 new_cnt - prev_cnt,
+					 new_cnt_ext - prev_cnt_ext);
+
+	local64_add(delta, &event->count);
+}
+
+static void hns3_pmu_start(struct perf_event *event, int flags)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
+		return;
+
+	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
+	hwc->state = 0;
+
+	hns3_pmu_config_filter(event);
+	hns3_pmu_init_counter(event);
+	hns3_pmu_enable_intr(hns3_pmu, hwc);
+	hns3_pmu_enable_counter(hns3_pmu, hwc);
+
+	perf_event_update_userpage(event);
+}
+
+static void hns3_pmu_stop(struct perf_event *event, int flags)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	hns3_pmu_disable_counter(hns3_pmu, hwc);
+	hns3_pmu_disable_intr(hns3_pmu, hwc);
+
+	WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED);
+	hwc->state |= PERF_HES_STOPPED;
+
+	if (hwc->state & PERF_HES_UPTODATE)
+		return;
+
+	/* Read hardware counter and update the perf counter statistics */
+	hns3_pmu_read(event);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int hns3_pmu_add(struct perf_event *event, int flags)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx;
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	/* Get an available counter index for counting */
+	idx = hns3_pmu_get_event_idx(hns3_pmu);
+	if (idx < 0)
+		return idx;
+
+	hwc->idx = idx;
+	hns3_pmu->hw_events[idx] = event;
+
+	if (flags & PERF_EF_START)
+		hns3_pmu_start(event, PERF_EF_RELOAD);
+
+	return 0;
+}
+
+static void hns3_pmu_del(struct perf_event *event, int flags)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	hns3_pmu_stop(event, PERF_EF_UPDATE);
+	hns3_pmu->hw_events[hwc->idx] = NULL;
+	perf_event_update_userpage(event);
+}
+
+static void hns3_pmu_enable(struct pmu *pmu)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(pmu);
+	u32 val;
+
+	val = readl(hns3_pmu->base + HNS3_PMU_REG_GLOBAL_CTRL);
+	val |= HNS3_PMU_GLOBAL_START;
+	writel(val, hns3_pmu->base + HNS3_PMU_REG_GLOBAL_CTRL);
+}
+
+static void hns3_pmu_disable(struct pmu *pmu)
+{
+	struct hns3_pmu *hns3_pmu = to_hns3_pmu(pmu);
+	u32 val;
+
+	val = readl(hns3_pmu->base + HNS3_PMU_REG_GLOBAL_CTRL);
+	val &= ~HNS3_PMU_GLOBAL_START;
+	writel(val, hns3_pmu->base + HNS3_PMU_REG_GLOBAL_CTRL);
+}
+
+static int hns3_pmu_alloc_pmu(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
+{
+	u16 device_id;
+	char *name;
+	u32 val;
+	int ret;
+
+	hns3_pmu->base = pci_ioremap_bar(pdev, 2);
+	if (!hns3_pmu->base) {
+		pci_err(pdev, "ioremap failed for hns3_pmu resource\n");
+		ret = -ENOMEM;
+		goto err_ioremap_bar;
+	}
+
+	hns3_pmu->hw_clk_freq = readl(hns3_pmu->base + HNS3_PMU_REG_CLOCK_FREQ);
+
+	val = readl(hns3_pmu->base + HNS3_PMU_REG_BDF);
+	hns3_pmu->bdf_min = val & 0xffff;
+	hns3_pmu->bdf_max = val >> 16;
+
+	val = readl(hns3_pmu->base + HNS3_PMU_REG_DEVICE_ID);
+	device_id = val & 0xffff;
+	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hns3_pmu_%u", device_id);
+	if (!name) {
+		pci_err(pdev, "failed to allocate name for HNS3 PMU.\n");
+		ret = -ENOMEM;
+		goto err_alloc_dev_name;
+	}
+
+	hns3_pmu->pdev = pdev;
+	hns3_pmu->on_cpu = HNS3_PMU_INVALID_CPU_ID;
+	hns3_pmu->identifier = readl(hns3_pmu->base + HNS3_PMU_REG_VERSION);
+	hns3_pmu->pmu = (struct pmu) {
+		.name		= name,
+		.module		= THIS_MODULE,
+		.event_init	= hns3_pmu_event_init,
+		.pmu_enable	= hns3_pmu_enable,
+		.pmu_disable	= hns3_pmu_disable,
+		.add		= hns3_pmu_add,
+		.del		= hns3_pmu_del,
+		.start		= hns3_pmu_start,
+		.stop		= hns3_pmu_stop,
+		.read		= hns3_pmu_read,
+		.task_ctx_nr	= perf_invalid_context,
+		.attr_groups	= hns3_pmu_attr_groups,
+		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
+	};
+
+	return 0;
+
+err_alloc_dev_name:
+	iounmap(hns3_pmu->base);
+err_ioremap_bar:
+	pci_release_regions(pdev);
+
+	return ret;
+}
+
+static irqreturn_t hns3_pmu_irq(int irq, void *data)
+{
+	struct hns3_pmu *hns3_pmu = data;
+	u32 intr_status, idx;
+
+	for (idx = 0; idx < HNS3_PMU_MAX_COUNTERS; idx++) {
+		intr_status = hns3_pmu_readl(hns3_pmu,
+					     HNS3_PMU_REG_EVENT_INTR_STATUS,
+					     idx);
+
+		/*
+		 * As each counter will restart from 0 when it is overflowed,
+		 * extra processing is no need, just clear interrupt status.
+		 */
+		if (intr_status)
+			hns3_pmu_clear_intr_status(hns3_pmu, idx);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int hns3_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct hns3_pmu *hns3_pmu;
+
+	hns3_pmu = hlist_entry_safe(node, struct hns3_pmu, node);
+	if (!hns3_pmu)
+		return -ENODEV;
+
+	if (hns3_pmu->on_cpu == HNS3_PMU_INVALID_CPU_ID) {
+		hns3_pmu->on_cpu = cpu;
+		irq_set_affinity_hint(hns3_pmu->irq, cpumask_of(cpu));
+	}
+
+	return 0;
+}
+
+static int hns3_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
+{
+	struct hns3_pmu *hns3_pmu;
+	unsigned int target;
+
+	hns3_pmu = hlist_entry_safe(node, struct hns3_pmu, node);
+	if (!hns3_pmu)
+		return -ENODEV;
+
+	/* Nothing to do if this CPU doesn't own the PMU */
+	if (hns3_pmu->on_cpu != cpu)
+		return 0;
+
+	/* Choose a new CPU from all online cpus */
+	target = cpumask_any_but(cpu_online_mask, cpu);
+	if (target >= nr_cpu_ids)
+		return 0;
+
+	perf_pmu_migrate_context(&hns3_pmu->pmu, cpu, target);
+	hns3_pmu->on_cpu = target;
+	irq_set_affinity_hint(hns3_pmu->irq, cpumask_of(target));
+
+	return 0;
+}
+
+static int hns3_pmu_irq_register(struct pci_dev *pdev,
+				 struct hns3_pmu *hns3_pmu)
+{
+	int irq, ret;
+
+	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+	if (ret < 0) {
+		pci_err(pdev, "failed to enable MSI vectors, ret = %d.\n", ret);
+		return ret;
+	}
+
+	irq = pci_irq_vector(pdev, 0);
+	ret = request_irq(irq, hns3_pmu_irq, 0, hns3_pmu->pmu.name, hns3_pmu);
+	if (ret) {
+		pci_err(pdev, "failed to register irq, ret = %d.\n", ret);
+		pci_free_irq_vectors(pdev);
+		return ret;
+	}
+
+	hns3_pmu->irq = irq;
+
+	return 0;
+}
+
+static void hns3_pmu_irq_unregister(struct pci_dev *pdev,
+				    struct hns3_pmu *hns3_pmu)
+{
+	free_irq(hns3_pmu->irq, hns3_pmu);
+	pci_free_irq_vectors(pdev);
+}
+
+static int hns3_pmu_init(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
+{
+	int ret;
+
+	ret = hns3_pmu_alloc_pmu(pdev, hns3_pmu);
+	if (ret)
+		return ret;
+
+	ret = hns3_pmu_irq_register(pdev, hns3_pmu);
+	if (ret)
+		goto err_irq_register;
+
+	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+				       &hns3_pmu->node);
+	if (ret) {
+		pci_err(pdev, "failed to register hotplug, ret = %d.\n", ret);
+		goto err_register_hotplug;
+	}
+
+	ret = perf_pmu_register(&hns3_pmu->pmu, hns3_pmu->pmu.name, -1);
+	if (ret) {
+		pci_err(pdev, "failed to register HNS3 PMU, ret = %d.\n", ret);
+		goto err_register_pmu;
+	}
+
+	return ret;
+
+err_register_pmu:
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+				    &hns3_pmu->node);
+	irq_set_affinity_hint(hns3_pmu->irq, NULL);
+
+err_register_hotplug:
+	hns3_pmu_irq_unregister(pdev, hns3_pmu);
+
+err_irq_register:
+	iounmap(hns3_pmu->base);
+
+	return ret;
+}
+
+static void hns3_pmu_uninit(struct pci_dev *pdev)
+{
+	struct hns3_pmu *hns3_pmu = (struct hns3_pmu *)pci_get_drvdata(pdev);
+
+	perf_pmu_unregister(&hns3_pmu->pmu);
+	cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+				    &hns3_pmu->node);
+	irq_set_affinity_hint(hns3_pmu->irq, NULL);
+	hns3_pmu_irq_unregister(pdev, hns3_pmu);
+	iounmap(hns3_pmu->base);
+}
+
+static int hns3_pmu_init_dev(struct pci_dev *pdev)
+{
+	int ret;
+
+	ret = pci_enable_device(pdev);
+	if (ret) {
+		pci_err(pdev, "failed to enable pci device, ret = %d.\n", ret);
+		return ret;
+	}
+
+	ret = pci_request_mem_regions(pdev, "hns3_pmu");
+	if (ret < 0) {
+		pci_err(pdev, "failed to request pci mem regions, ret = %d.\n",
+			ret);
+		pci_disable_device(pdev);
+		return ret;
+	}
+
+	pci_set_master(pdev);
+
+	return 0;
+}
+
+static void hns3_pmu_uninit_dev(struct pci_dev *pdev)
+{
+	pci_clear_master(pdev);
+	pci_release_mem_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+static int hns3_pmu_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct hns3_pmu *hns3_pmu;
+	int ret;
+
+	hns3_pmu = devm_kzalloc(&pdev->dev, sizeof(*hns3_pmu), GFP_KERNEL);
+	if (!hns3_pmu)
+		return -ENOMEM;
+
+	ret = hns3_pmu_init_dev(pdev);
+	if (ret)
+		return ret;
+
+	ret = hns3_pmu_init(pdev, hns3_pmu);
+	if (ret) {
+		hns3_pmu_uninit_dev(pdev);
+		return ret;
+	}
+
+	pci_set_drvdata(pdev, hns3_pmu);
+
+	return ret;
+}
+
+static void hns3_pmu_remove(struct pci_dev *pdev)
+{
+	hns3_pmu_uninit(pdev);
+	hns3_pmu_uninit_dev(pdev);
+	pci_set_drvdata(pdev, NULL);
+}
+
+static const struct pci_device_id hns3_pmu_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xA22B) },
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, hns3_pmu_ids);
+
+static struct pci_driver hns3_pmu_driver = {
+	.name = "hns3_pmu",
+	.id_table = hns3_pmu_ids,
+	.probe = hns3_pmu_probe,
+	.remove = hns3_pmu_remove,
+};
+
+static int __init hns3_pmu_module_init(void)
+{
+	int ret;
+
+	ret = hns3_pmu_init_filter_mode_group();
+	if (ret)
+		return ret;
+
+	ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
+				      "AP_PERF_ARM_HNS3_PMU_ONLINE",
+				      hns3_pmu_online_cpu,
+				      hns3_pmu_offline_cpu);
+	if (ret) {
+		pr_err("failed to setup HNS3 PMU hotplug, ret = %d.\n", ret);
+		goto err_init;
+	}
+
+	ret = pci_register_driver(&hns3_pmu_driver);
+	if (ret) {
+		pr_err("failed to register pci driver, ret = %d.\n", ret);
+		goto err_hp;
+	}
+
+	return 0;
+
+err_hp:
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE);
+err_init:
+	hns3_pmu_uinit_filter_mode_group();
+	return ret;
+}
+module_init(hns3_pmu_module_init);
+
+static void __exit hns3_pmu_module_exit(void)
+{
+	pci_unregister_driver(&hns3_pmu_driver);
+	cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE);
+	hns3_pmu_uinit_filter_mode_group();
+}
+module_exit(hns3_pmu_module_exit);
+
+MODULE_DESCRIPTION("HNS3 PMU driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 411a428ace4d..9c2cb0600740 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -226,6 +226,7 @@ enum cpuhp_state {
 	CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
 	CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
 	CPUHP_AP_PERF_ARM_HISI_PCIE_PMU_ONLINE,
+	CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
 	CPUHP_AP_PERF_ARM_L2X0_ONLINE,
 	CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
 	CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
-- 
2.33.0



From jammy_huang at aspeedtech.com  Sun Jan 16 17:59:58 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 17 Jan 2022 09:59:58 +0800
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
 <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
Message-ID: <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>

Hi Hans,

On 2022/1/14 ?? 04:11, Hans Verkuil wrote:
> On 24/12/2021 02:27, Jammy Huang wrote:
>> This introduces support for the Aspeed JPEG format, where the new frame
>> can refer to previous frame to reduce the amount of compressed data. The
>> concept is similar to I/P frame of video compression. It will compare the
>> new frame with previous one to decide which macroblock's data is
>> changed, and only the changed macroblocks will be compressed.
>>
>> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
>> which is generally adapted for remote KVM.
>>
>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>> ---
>> v8:
>>    - Add decoder information for aspeed-jpeg
>> v7:
>>    - Add more information for aspeed-jpeg
>> v6:
>>    - Update description for new format, aspeed-jpeg, in Documentation.
>> v5:
>>    - no update
>> v4:
>>    - new
>> ---
>>   .../media/uapi/v4l/pixfmt-reserved.rst          | 17 +++++++++++++++++
>>   drivers/media/v4l2-core/v4l2-ioctl.c            |  1 +
>>   include/uapi/linux/videodev2.h                  |  1 +
>>   3 files changed, 19 insertions(+)
>>
>> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> This is the wrong file! It should be:
>
> Documentation/userspace-api/media/v4l/pixfmt-reserved.rst

Thanks, I just used git format-patch to generate the cover-letter and 
didn't notice this.

It looks like the file, pixfmt-reserved.rst, has different path in 
different Linux kernel,

* 5.4:?????????? Documentation/media/uapi/v4l/pixfmt-reserved.rst

* 5.10/5.15: Documentation/userspace-api/media/v4l/pixfmt-reserved.rst

5.4 is the one I based to submit the patches.

Could you suggest the kernel that I should based to submit these patches??

I will need to change the number of V4L2_CID_USER_ASPEED_BASE per different

linux kernel as well.

>
> Regards,
>
> 	Hans
>
>> index b2cd155e691b..1d0dc8d86ed7 100644
>> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
>>   	of tiles, resulting in 32-aligned resolutions for the luminance plane
>>   	and 16-aligned resolutions for the chrominance plane (with 2x2
>>   	subsampling).
>> +    * .. _V4L2-PIX-FMT-AJPG:
>> +
>> +      - ``V4L2_PIX_FMT_AJPG``
>> +      - 'AJPG'
>> +      - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
>> +        which is generally adapted for remote KVM.
>> +        On each frame compression, I will compare the new frame with previous
>> +        one to decide which macroblock's data is changed, and only the changed
>> +        macroblocks will be compressed.
>> +
>> +        The implementation is based on AST2600 A3 datasheet, revision 0.9, which
>> +        is not publicly available. Or you can reference Video stream data format
>> +        ? ASPEED mode compression of SDK_User_Guide which available on
>> +        AspeedTech-BMC/openbmc/releases.
>> +
>> +        Decoder's implementation can be found here,
>> +        `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
>>   
>>   .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>>   
>> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
>> index 24db33f803c0..00dde01d2f97 100644
>> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
>> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
>> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>>   		case V4L2_PIX_FMT_S5C_UYVY_JPG:	descr = "S5C73MX interleaved UYVY/JPEG"; break;
>>   		case V4L2_PIX_FMT_MT21C:	descr = "Mediatek Compressed Format"; break;
>>   		case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
>> +		case V4L2_PIX_FMT_AJPG:		descr = "Aspeed JPEG"; break;
>>   		default:
>>   			if (fmt->description[0])
>>   				return;
>> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
>> index 3210b3c82a4a..994eb6155ea9 100644
>> --- a/include/uapi/linux/videodev2.h
>> +++ b/include/uapi/linux/videodev2.h
>> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
>>   #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
>>   #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
>>   #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
>> +#define V4L2_PIX_FMT_AJPG     v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
>>   
>>   /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
>>   #define V4L2_PIX_FMT_IPU3_SBGGR10	v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */

-- 
Best Regards
Jammy



From joel at jms.id.au  Sun Jan 16 18:24:38 2022
From: joel at jms.id.au (Joel Stanley)
Date: Mon, 17 Jan 2022 02:24:38 +0000
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
 <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
 <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>
Message-ID: <CACPK8XeJQHLWfVbBjArxV_QMDDnRXfccOeXdsn6aBEG7gd8yvw@mail.gmail.com>

On Mon, 17 Jan 2022 at 02:00, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>
> Hi Hans,
>
> On 2022/1/14 ?? 04:11, Hans Verkuil wrote:
> > On 24/12/2021 02:27, Jammy Huang wrote:
> >> This introduces support for the Aspeed JPEG format, where the new frame
> >> can refer to previous frame to reduce the amount of compressed data. The
> >> concept is similar to I/P frame of video compression. It will compare the
> >> new frame with previous one to decide which macroblock's data is
> >> changed, and only the changed macroblocks will be compressed.
> >>
> >> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
> >> which is generally adapted for remote KVM.
> >>
> >> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
> >> ---
> >> v8:
> >>    - Add decoder information for aspeed-jpeg
> >> v7:
> >>    - Add more information for aspeed-jpeg
> >> v6:
> >>    - Update description for new format, aspeed-jpeg, in Documentation.
> >> v5:
> >>    - no update
> >> v4:
> >>    - new
> >> ---
> >>   .../media/uapi/v4l/pixfmt-reserved.rst          | 17 +++++++++++++++++
> >>   drivers/media/v4l2-core/v4l2-ioctl.c            |  1 +
> >>   include/uapi/linux/videodev2.h                  |  1 +
> >>   3 files changed, 19 insertions(+)
> >>
> >> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> > This is the wrong file! It should be:
> >
> > Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>
> Thanks, I just used git format-patch to generate the cover-letter and
> didn't notice this.
>
> It looks like the file, pixfmt-reserved.rst, has different path in
> different Linux kernel,
>
> * 5.4:           Documentation/media/uapi/v4l/pixfmt-reserved.rst
>
> * 5.10/5.15: Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>
> 5.4 is the one I based to submit the patches.
>
> Could you suggest the kernel that I should based to submit these patches??

You should always submit based on the latest release.

There are sometimes exceptions where you will base your patches on
something even newer, but generally you should grab the latest.

Be sure to re-test on the latest kernel before submitting.

Cheers,

Joel

>
> I will need to change the number of V4L2_CID_USER_ASPEED_BASE per different
>
> linux kernel as well.
>
> >
> > Regards,
> >
> >       Hans
> >
> >> index b2cd155e691b..1d0dc8d86ed7 100644
> >> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> >> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
> >> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
> >>      of tiles, resulting in 32-aligned resolutions for the luminance plane
> >>      and 16-aligned resolutions for the chrominance plane (with 2x2
> >>      subsampling).
> >> +    * .. _V4L2-PIX-FMT-AJPG:
> >> +
> >> +      - ``V4L2_PIX_FMT_AJPG``
> >> +      - 'AJPG'
> >> +      - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
> >> +        which is generally adapted for remote KVM.
> >> +        On each frame compression, I will compare the new frame with previous
> >> +        one to decide which macroblock's data is changed, and only the changed
> >> +        macroblocks will be compressed.
> >> +
> >> +        The implementation is based on AST2600 A3 datasheet, revision 0.9, which
> >> +        is not publicly available. Or you can reference Video stream data format
> >> +        ? ASPEED mode compression of SDK_User_Guide which available on
> >> +        AspeedTech-BMC/openbmc/releases.
> >> +
> >> +        Decoder's implementation can be found here,
> >> +        `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
> >>
> >>   .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
> >>
> >> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
> >> index 24db33f803c0..00dde01d2f97 100644
> >> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
> >> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
> >> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
> >>              case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
> >>              case V4L2_PIX_FMT_MT21C:        descr = "Mediatek Compressed Format"; break;
> >>              case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
> >> +            case V4L2_PIX_FMT_AJPG:         descr = "Aspeed JPEG"; break;
> >>              default:
> >>                      if (fmt->description[0])
> >>                              return;
> >> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
> >> index 3210b3c82a4a..994eb6155ea9 100644
> >> --- a/include/uapi/linux/videodev2.h
> >> +++ b/include/uapi/linux/videodev2.h
> >> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
> >>   #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
> >>   #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
> >>   #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
> >> +#define V4L2_PIX_FMT_AJPG     v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
> >>
> >>   /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
> >>   #define V4L2_PIX_FMT_IPU3_SBGGR10  v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
>
> --
> Best Regards
> Jammy
>


From lkp at intel.com  Sun Jan 16 18:29:25 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 10:29:25 +0800
Subject: [linusw-nomadik:ux500-href-charging-v5.16-rc1 47/58]
 drivers/power/supply/ab8500_chargalg.c:822:13: warning: variable
 'delta_i_ua' set but not used
Message-ID: <202201171004.E3chM4HB-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
head:   1e846b0b60ac01cac4f283975a1bc395ff73d995
commit: e067307b004b5f2699464dd37d10817677ce9bf3 [47/58] power: supply: ab8500_chargalg: Drop charging step
config: arm-allyesconfig (https://download.01.org/0day-ci/archive/20220117/202201171004.E3chM4HB-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?id=e067307b004b5f2699464dd37d10817677ce9bf3
        git remote add linusw-nomadik https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
        git fetch --no-tags linusw-nomadik ux500-href-charging-v5.16-rc1
        git checkout e067307b004b5f2699464dd37d10817677ce9bf3
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/power/supply/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/power/supply/ab8500_chargalg.c: In function 'ab8500_chargalg_chg_curr_maxim':
>> drivers/power/supply/ab8500_chargalg.c:822:13: warning: variable 'delta_i_ua' set but not used [-Wunused-but-set-variable]
     822 |         int delta_i_ua;
         |             ^~~~~~~~~~


vim +/delta_i_ua +822 drivers/power/supply/ab8500_chargalg.c

1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  810  
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  811  /**
c5b64a990e7f3b drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-07-13  812   * ab8500_chargalg_chg_curr_maxim - increases the charger current to
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  813   *			compensate for the system load
c5b64a990e7f3b drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-07-13  814   * @di		pointer to the ab8500_chargalg structure
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  815   *
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  816   * This maximization function is used to raise the charger current to get the
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  817   * battery current as close to the optimal value as possible. The battery
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  818   * current during charging is affected by the system load
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  819   */
c5b64a990e7f3b drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-07-13  820  static enum maxim_ret ab8500_chargalg_chg_curr_maxim(struct ab8500_chargalg *di)
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  821  {
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13 @822  	int delta_i_ua;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  823  
b0284de05e07d5 drivers/power/abx500_chargalg.c        Lee Jones     2012-11-30  824  	if (!di->bm->maxi->ena_maxi)
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  825  		return MAXIM_RET_NOACTION;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  826  
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  827  	delta_i_ua = di->ccm.original_iset_ua - di->batt_data.inst_curr_ua;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  828  
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  829  	if (di->events.vbus_collapsed) {
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  830  		dev_dbg(di->dev, "Charger voltage has collapsed %d\n",
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  831  				di->ccm.wait_cnt);
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  832  		if (di->ccm.wait_cnt == 0) {
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  833  			dev_dbg(di->dev, "lowering current\n");
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  834  			di->ccm.wait_cnt++;
b0284de05e07d5 drivers/power/abx500_chargalg.c        Lee Jones     2012-11-30  835  			di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
e067307b004b5f drivers/power/supply/ab8500_chargalg.c Linus Walleij 2022-01-04  836  			di->ccm.max_current_ua = di->ccm.current_iset_ua;
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  837  			di->ccm.current_iset_ua = di->ccm.max_current_ua;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  838  			di->ccm.level--;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  839  			return MAXIM_RET_CHANGE;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  840  		} else {
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  841  			dev_dbg(di->dev, "waiting\n");
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  842  			/* Let's go in here twice before lowering curr again */
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  843  			di->ccm.wait_cnt = (di->ccm.wait_cnt + 1) % 3;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  844  			return MAXIM_RET_NOACTION;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  845  		}
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  846  	}
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  847  
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  848  	di->ccm.wait_cnt = 0;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  849  
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  850  	if (di->batt_data.inst_curr_ua > di->ccm.original_iset_ua) {
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  851  		dev_dbg(di->dev, " Maximization Ibat (%duA) too high"
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  852  			" (limit %duA) (current iset: %duA)!\n",
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  853  			di->batt_data.inst_curr_ua, di->ccm.original_iset_ua,
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  854  			di->ccm.current_iset_ua);
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  855  
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  856  		if (di->ccm.current_iset_ua == di->ccm.original_iset_ua)
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  857  			return MAXIM_RET_NOACTION;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  858  
b0284de05e07d5 drivers/power/abx500_chargalg.c        Lee Jones     2012-11-30  859  		di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
d3e41d1547389a drivers/power/supply/ab8500_chargalg.c Linus Walleij 2021-11-13  860  		di->ccm.current_iset_ua = di->ccm.original_iset_ua;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  861  		di->ccm.level = 0;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  862  
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  863  		return MAXIM_RET_IBAT_TOO_HIGH;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  864  	}
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  865  
b0284de05e07d5 drivers/power/abx500_chargalg.c        Lee Jones     2012-11-30  866  	di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  867  	return MAXIM_RET_NOACTION;
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  868  }
1668f81159fb72 drivers/power/abx500_chargalg.c        Arun Murthy   2012-02-29  869  

:::::: The code at line 822 was first introduced by commit
:::::: d3e41d1547389a87ac7b6c311ed8243d0fc9fa7b power: supply: ab8500: Standardize CC current

:::::: TO: Linus Walleij <linus.walleij at linaro.org>
:::::: CC: Linus Walleij <linus.walleij at linaro.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From liang.yang at amlogic.com  Sun Jan 16 18:43:01 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 10:43:01 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220114225957.285ADC36AE7@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
 <20220114225957.285ADC36AE7@smtp.kernel.org>
Message-ID: <d6933fd7-ec4c-aee1-5cf4-9cbcf881a33d@amlogic.com>



On 2022/1/15 6:59, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 19:06:07)
>> Hi Stephen,
>>
>> Thanks for your quick response.
>>
>> On 2022/1/14 5:29, Stephen Boyd wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> Quoting Liang Yang (2022-01-13 03:57:44)
>>>> Document the MMC sub clock controller driver, the potential consumer
>>>> of this driver is MMC or NAND. Also add four clock bindings IDs which
>>>> provided by this driver.
>>>>
>>>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>>>> ---
>>>>    .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
>>>>    include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
>>>>    2 files changed, 78 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>>    create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>> new file mode 100644
>>>> index 000000000000..a274c3d5fc2e
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>> @@ -0,0 +1,64 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
>>>> +
>>>> +maintainers:
>>>> +  - jianxin.pan at amlogic.com
>>>> +  - liang.yang at amlogic.com
>>>> +
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - "amlogic,axg-mmc-clkc", "syscon"
>>>
>>> Why is it a syscon?
>>
>> The register documented by reg is shared with SD/eMMC controller port C,
>> and it need to be ops on NFC driver.
>>
> 
> Is this the case where the clk is inside the SD/eMMC controller? Can the
yes.
> mmc driver register the clk controller from there and pass it an iomem
> pointer to poke clks?
we can't do that since EMMC and NAND is mutually exclusivem. both of 
them share the same data pins.
> 
> .


From xkernel.wang at foxmail.com  Sun Jan 16 18:56:21 2022
From: xkernel.wang at foxmail.com (xkernel.wang at foxmail.com)
Date: Mon, 17 Jan 2022 10:56:21 +0800
Subject: [PATCH v2] nvmem: meson-mx-efuse: replace unnecessary devm_kstrdup()
Message-ID: <tencent_0589E3FF08A4905922F78BC38602361C5505@qq.com>

From: Xiaoke Wang <xkernel.wang at foxmail.com>

Replace unnecessary devm_kstrdup() so to avoid redundant memory allocation.

Suggested-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Xiaoke Wang <xkernel.wang at foxmail.com>
---
Changelogs:
Simplify the patch to replace unnecessary devm_kstrdup().
 drivers/nvmem/meson-mx-efuse.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c
index 07c9f38..13eb143 100644
--- a/drivers/nvmem/meson-mx-efuse.c
+++ b/drivers/nvmem/meson-mx-efuse.c
@@ -209,8 +209,7 @@ static int meson_mx_efuse_probe(struct platform_device *pdev)
 	if (IS_ERR(efuse->base))
 		return PTR_ERR(efuse->base);
 
-	efuse->config.name = devm_kstrdup(&pdev->dev, drvdata->name,
-					  GFP_KERNEL);
+	efuse->config.name = drvdata->name;
 	efuse->config.owner = THIS_MODULE;
 	efuse->config.dev = &pdev->dev;
 	efuse->config.priv = efuse;
-- 


From quic_saipraka at quicinc.com  Sun Jan 16 19:32:49 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:49 +0530
Subject: [PATCHv8 0/5] lib/rwmmio/arm64: Add support to trace register
 reads/writes
Message-ID: <cover.1642309054.git.quic_saipraka@quicinc.com>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

This series is a follow-up for the series [1] and a recent series [2] making use
of both.

[1] https://lore.kernel.org/lkml/cover.1536430404.git.saiprakash.ranjan at codeaurora.org/
[2] https://lore.kernel.org/lkml/1604631386-178312-1-git-send-email-psodagud at codeaurora.org/

Note in previous v4 version, Arnd suggested to benchmark and compare size with callback
based implementation, please see [3] for more details on that with brief comparison below.


**Inline version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
   text           data             bss     dec             hex         filename
 23884219        14284468         532568 38701255        24e88c7        vmlinux

**Callback version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
    text          data             bss     dec             hex        filename
 24108179        14279596         532568 38920343        251e097       vmlinux

$ ./scripts/bloat-o-meter inline-vmlinux callback-vmlinux
add/remove: 8/3 grow/shrink: 4889/89 up/down: 242244/-11564 (230680)
Total: Before=25812612, After=26043292, chg +0.89%

[3] https://lore.kernel.org/lkml/466449a1-36da-aaa9-7e4f-477f36b52c9e at quicinc.com/

Changes in v8:
 * Fix build error reported by kernel test robot.

Changes in v7:
 * Use lib/ instead of kernel/trace/ based on review comment by Steven Rostedt.

Changes in v6:
 * Implemented suggestions by Arnd Bergmann:
   - Use arch independent IO barriers in arm64/asm
   - Add ARCH_HAVE_TRACE_MMIO_ACCESS
   - Add post read and post write logging support
   - Remove tracepoint_active check
 * Fix build error reported by kernel test robot.

Changes in v5:
 * Move arm64 to use asm-generic provided high level MMIO accessors (Arnd).
 * Add inline logging for MMIO relaxed and non-relaxed accessors.
 * Move nVHE KVM comment to makefile (Marc).
 * Fix overflow warning due to switch to inline accessors instead of macro.
 * Modify trace event field to include caller and parent details for more detailed logs.

Changes in v4:
 * Drop dynamic debug based filter support since that will be developed later with
   the help from Steven (Ftrace maintainer).
 * Drop value passed to writel as it is causing hangs when tracing is enabled.
 * Code cleanup for trace event as suggested by Steven for earlier version.
 * Fixed some build errors reported by 0-day bot.

Changes in v3:
 * Create a generic mmio header for instrumented version (Earlier suggested in [1]
   by Will Deacon and recently [2] by Greg to have a generic version first).
 * Add dynamic debug support to filter out traces which can be very useful for targeted
   debugging specific to subsystems or drivers.
 * Few modifications to the rwmmio trace event fields to include the mmio width and print
   addresses in hex.
 * Rewrote commit msg to explain some more about usecases.

Prasad Sodagudi (1):
  lib: Add register read/write tracing support

Sai Prakash Ranjan (4):
  arm64: io: Use asm-generic high level MMIO accessors
  irqchip/tegra: Fix overflow implicit truncation warnings
  drm/meson: Fix overflow implicit truncation warnings
  asm-generic/io: Add logging support for MMIO accessors

 arch/Kconfig                      |   3 +
 arch/arm64/Kconfig                |   1 +
 arch/arm64/include/asm/io.h       |  41 +++--------
 arch/arm64/kvm/hyp/nvhe/Makefile  |   7 +-
 drivers/gpu/drm/meson/meson_viu.c |  22 +++---
 drivers/irqchip/irq-tegra.c       |  10 +--
 include/asm-generic/io.h          |  82 ++++++++++++++++++++--
 include/trace/events/rwmmio.h     | 112 ++++++++++++++++++++++++++++++
 lib/Kconfig                       |   7 ++
 lib/Makefile                      |   2 +
 lib/trace_readwrite.c             |  47 +++++++++++++
 11 files changed, 280 insertions(+), 54 deletions(-)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c


base-commit: bd8d9cef2a7932e688ca267ea1adf5ea6557c777
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:32:50 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:50 +0530
Subject: [PATCHv8 1/5] arm64: io: Use asm-generic high level MMIO accessors
In-Reply-To: <cover.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <87926437f2f9e72dd94f0b30c8784c2da5508644.1642309054.git.quic_saipraka@quicinc.com>

Remove custom arm64 MMIO accessors read{b,w,l,q} and their relaxed
versions in support to use asm-generic defined accessors. Also define
one set of IO barriers (ar/bw version) used by asm-generic code to
override the arm64 specific variants.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/include/asm/io.h | 41 ++++++++-----------------------------
 1 file changed, 8 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7fd836bea7eb..1b436810d779 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -91,7 +91,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 }
 
 /* IO barriers */
-#define __iormb(v)							\
+#define __io_ar(v)							\
 ({									\
 	unsigned long tmp;						\
 									\
@@ -108,39 +108,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 		     : "memory");					\
 })
 
-#define __io_par(v)		__iormb(v)
-#define __iowmb()		dma_wmb()
-#define __iomb()		dma_mb()
-
-/*
- * Relaxed I/O memory access primitives. These follow the Device memory
- * ordering rules but do not guarantee any ordering relative to Normal memory
- * accesses.
- */
-#define readb_relaxed(c)	({ u8  __r = __raw_readb(c); __r; })
-#define readw_relaxed(c)	({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
-#define readl_relaxed(c)	({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
-#define readq_relaxed(c)	({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
+#define __io_bw()		dma_wmb()
+#define __io_br(v)
+#define __io_aw(v)
 
-#define writeb_relaxed(v,c)	((void)__raw_writeb((v),(c)))
-#define writew_relaxed(v,c)	((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
-#define writel_relaxed(v,c)	((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
-#define writeq_relaxed(v,c)	((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
-
-/*
- * I/O memory access primitives. Reads are ordered relative to any
- * following Normal memory access. Writes are ordered relative to any prior
- * Normal memory access.
- */
-#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(__v); __v; })
-#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(__v); __v; })
-#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(__v); __v; })
-#define readq(c)		({ u64 __v = readq_relaxed(c); __iormb(__v); __v; })
-
-#define writeb(v,c)		({ __iowmb(); writeb_relaxed((v),(c)); })
-#define writew(v,c)		({ __iowmb(); writew_relaxed((v),(c)); })
-#define writel(v,c)		({ __iowmb(); writel_relaxed((v),(c)); })
-#define writeq(v,c)		({ __iowmb(); writeq_relaxed((v),(c)); })
+/* arm64-specific, don't use in portable drivers */
+#define __iormb(v)		__io_ar(v)
+#define __iowmb()		__io_bw()
+#define __iomb()		dma_mb()
 
 /*
  *  I/O port access primitives.
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:32:51 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:51 +0530
Subject: [PATCHv8 2/5] irqchip/tegra: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <2cd67f7eee96e062ea479b7406799f7a2daa5b1b.1642309054.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for tegra irqchip driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/irqchip/irq-tegra.c: In function ?tegra_ictlr_suspend?:
drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
                  ^

Cc: Marc Zyngier <maz at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/irqchip/irq-tegra.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
index e1f771c72fc4..9e4e5b39c701 100644
--- a/drivers/irqchip/irq-tegra.c
+++ b/drivers/irqchip/irq-tegra.c
@@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void)
 		lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
 
 		/* Disable COP interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 
 		/* Disable CPU interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 
 		/* Enable the wakeup sources of ictlr */
 		writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
@@ -172,12 +172,12 @@ static void tegra_ictlr_resume(void)
 
 		writel_relaxed(lic->cpu_iep[i],
 			       ictlr + ICTLR_CPU_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 		writel_relaxed(lic->cpu_ier[i],
 			       ictlr + ICTLR_CPU_IER_SET);
 		writel_relaxed(lic->cop_iep[i],
 			       ictlr + ICTLR_COP_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 		writel_relaxed(lic->cop_ier[i],
 			       ictlr + ICTLR_COP_IER_SET);
 	}
@@ -312,7 +312,7 @@ static int __init tegra_ictlr_init(struct device_node *node,
 		lic->base[i] = base;
 
 		/* Disable all interrupts */
-		writel_relaxed(~0UL, base + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0U, base + ICTLR_CPU_IER_CLR);
 		/* All interrupts target IRQ */
 		writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS);
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:32:52 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:52 +0530
Subject: [PATCHv8 3/5] drm/meson: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <b5e5b45bcb7b022147dc0036daf35d72d102e946.1642309054.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for drm/meson driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/gpu/drm/meson/meson_viu.c: In function ?meson_viu_init?:
drivers/gpu/drm/meson/meson_registers.h:1826:48: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
 #define  VIU_OSD_BLEND_REORDER(dest, src)      ((src) << (dest * 4))
                                                ^
drivers/gpu/drm/meson/meson_viu.c:472:18: note: in expansion of macro ?VIU_OSD_BLEND_REORDER?
   writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
                  ^~~~~~~~~~~~~~~~~~~~~

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/gpu/drm/meson/meson_viu.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 259f3e6bec90..bb7e109534de 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -469,17 +469,17 @@ void meson_viu_init(struct meson_drm *priv)
 			priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
 
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
-		writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
-			       VIU_OSD_BLEND_REORDER(1, 0) |
-			       VIU_OSD_BLEND_REORDER(2, 0) |
-			       VIU_OSD_BLEND_REORDER(3, 0) |
-			       VIU_OSD_BLEND_DIN_EN(1) |
-			       VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
-			       VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
-			       VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
-			       VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
-			       VIU_OSD_BLEND_HOLD_LINES(4),
-			       priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
+		u32 val = (u32)VIU_OSD_BLEND_REORDER(0, 1) |
+			  (u32)VIU_OSD_BLEND_REORDER(1, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(2, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(3, 0) |
+			  (u32)VIU_OSD_BLEND_DIN_EN(1) |
+			  (u32)VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
+			  (u32)VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
+			  (u32)VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
+			  (u32)VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
+			  (u32)VIU_OSD_BLEND_HOLD_LINES(4);
+		writel_relaxed(val, priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
 
 		writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
 			       priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:32:53 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:53 +0530
Subject: [PATCHv8 4/5] lib: Add register read/write tracing support
In-Reply-To: <cover.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <8ad60797d6d8f40c3bdba20b1678fa9014bc1a20.1642309054.git.quic_saipraka@quicinc.com>

From: Prasad Sodagudi <psodagud at codeaurora.org>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following few
cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

Signed-off-by: Prasad Sodagudi <psodagud at codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/Kconfig                  |   3 +
 arch/arm64/Kconfig            |   1 +
 include/trace/events/rwmmio.h | 112 ++++++++++++++++++++++++++++++++++
 lib/Kconfig                   |   7 +++
 lib/Makefile                  |   2 +
 lib/trace_readwrite.c         |  47 ++++++++++++++
 6 files changed, 172 insertions(+)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c

diff --git a/arch/Kconfig b/arch/Kconfig
index fdba59052abc..54dd42db882d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1322,6 +1322,9 @@ config ARCH_HAS_ELFCORE_COMPAT
 config ARCH_HAS_PARANOID_L1D_FLUSH
 	bool
 
+config ARCH_HAVE_TRACE_MMIO_ACCESS
+	bool
+
 config DYNAMIC_SIGFRAME
 	bool
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3bb0b67292b5..eaa48df2c3bd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -46,6 +46,7 @@ config ARM64
 	select ARCH_HAS_ZONE_DMA_SET if EXPERT
 	select ARCH_HAVE_ELF_PROT
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select ARCH_HAVE_TRACE_MMIO_ACCESS
 	select ARCH_INLINE_READ_LOCK if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION
diff --git a/include/trace/events/rwmmio.h b/include/trace/events/rwmmio.h
new file mode 100644
index 000000000000..798fbe1ac9f9
--- /dev/null
+++ b/include/trace/events/rwmmio.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rwmmio
+
+#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RWMMIO_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(rwmmio_write,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		(void *)(unsigned long)__entry->caller, __entry->width,
+		__entry->val, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_post_write,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		(void *)(unsigned long)__entry->caller, __entry->width,
+		__entry->val, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_read,
+
+	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_post_read,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width,
+		 __entry->val, __entry->addr)
+);
+
+#endif /* _TRACE_RWMMIO_H */
+
+#include <trace/define_trace.h>
diff --git a/lib/Kconfig b/lib/Kconfig
index c80fde816a7e..ea520c315c0f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
 	  mmio accesses when the IO memory address is not a registered
 	  emulated region.
 
+config TRACE_MMIO_ACCESS
+	bool "Register read/write tracing"
+	depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
+	help
+	  Create tracepoints for MMIO read/write operations. These trace events
+	  can be used for logging all MMIO read/write operations.
+
 source "lib/crypto/Kconfig"
 
 config CRC_CCITT
diff --git a/lib/Makefile b/lib/Makefile
index 300f569c626b..43813b0061cd 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -152,6 +152,8 @@ lib-y += logic_pio.o
 
 lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
 
+obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
+
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
 obj-$(CONFIG_BTREE) += btree.o
diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
new file mode 100644
index 000000000000..88637038b30c
--- /dev/null
+++ b/lib/trace_readwrite.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Register read and write tracepoints
+ *
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <asm-generic/io.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/rwmmio.h>
+
+#ifdef CONFIG_TRACE_MMIO_ACCESS
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr)
+{
+	trace_rwmmio_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
+
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr)
+{
+	trace_rwmmio_post_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
+
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr)
+{
+	trace_rwmmio_read(caller_addr, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
+
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr)
+{
+	trace_rwmmio_post_read(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:32:54 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:02:54 +0530
Subject: [PATCHv8 5/5] asm-generic/io: Add logging support for MMIO accessors
In-Reply-To: <cover.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <14ebf1ce34f3186a45bc6c93675295acd28b8f05.1642309054.git.quic_saipraka@quicinc.com>

Add logging support for MMIO high level accessors such as read{b,w,l,q}
and their relaxed versions to aid in debugging unexpected crashes/hangs
caused by the corresponding MMIO operation. Also add a generic flag
(__DISABLE_TRACE_MMIO__) which is used to disable MMIO tracing in nVHE KVM
and if required can be used to disable MMIO tracing for specific drivers.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/kvm/hyp/nvhe/Makefile |  7 ++-
 include/asm-generic/io.h         | 82 ++++++++++++++++++++++++++++++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 24b2c2425b38..228d1f8921c3 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -4,7 +4,12 @@
 #
 
 asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
-ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
+
+# Tracepoint and MMIO logging symbols should not be visible at nVHE KVM as
+# there is no way to execute them and any such MMIO access from nVHE KVM
+# will explode instantly (Words of Marc Zyngier). So introduce a generic flag
+# __DISABLE_TRACE_MMIO__ to disable MMIO tracing for nVHE KVM.
+ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__
 
 hostprogs := gen-hyprel
 HOST_EXTRACFLAGS += -I$(objtree)/include
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 7ce93aaf69f8..c9b428657760 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -10,6 +10,7 @@
 #include <asm/page.h> /* I/O is all done through memory accesses */
 #include <linux/string.h> /* for memset() and memcpy() */
 #include <linux/types.h>
+#include <linux/instruction_pointer.h>
 
 #ifdef CONFIG_GENERIC_IOMAP
 #include <asm-generic/iomap.h>
@@ -61,6 +62,35 @@
 #define __io_par(v)     __io_ar(v)
 #endif
 
+#if IS_ENABLED(CONFIG_TRACE_MMIO_ACCESS) && !(defined(__DISABLE_TRACE_MMIO__))
+#include <linux/tracepoint-defs.h>
+
+DECLARE_TRACEPOINT(rwmmio_write);
+DECLARE_TRACEPOINT(rwmmio_post_write);
+DECLARE_TRACEPOINT(rwmmio_read);
+DECLARE_TRACEPOINT(rwmmio_post_read);
+
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr);
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr);
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr);
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr);
+
+#else
+
+static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				  unsigned long caller_addr) {}
+static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				       unsigned long caller_addr) {}
+static inline void log_read_mmio(u8 width, const volatile void __iomem *addr,
+				 unsigned long caller_addr) {}
+static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+				      unsigned long caller_addr) {}
+
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
 
 /*
  * __raw_{read,write}{b,w,l,q}() access memory in native endianness.
@@ -149,9 +179,11 @@ static inline u8 readb(const volatile void __iomem *addr)
 {
 	u8 val;
 
+	log_read_mmio(8, addr, _THIS_IP_);
 	__io_br();
 	val = __raw_readb(addr);
 	__io_ar(val);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -162,9 +194,11 @@ static inline u16 readw(const volatile void __iomem *addr)
 {
 	u16 val;
 
+	log_read_mmio(16, addr, _THIS_IP_);
 	__io_br();
 	val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -175,9 +209,11 @@ static inline u32 readl(const volatile void __iomem *addr)
 {
 	u32 val;
 
+	log_read_mmio(32, addr, _THIS_IP_);
 	__io_br();
 	val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -189,9 +225,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 {
 	u64 val;
 
+	log_read_mmio(64, addr, _THIS_IP_);
 	__io_br();
 	val = __le64_to_cpu(__raw_readq(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -201,9 +239,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 #define writeb writeb
 static inline void writeb(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeb(value, addr);
 	__io_aw();
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -211,9 +251,11 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
 #define writew writew
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writew((u16 __force)cpu_to_le16(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -221,9 +263,11 @@ static inline void writew(u16 value, volatile void __iomem *addr)
 #define writel writel
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writel((u32 __force)__cpu_to_le32(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -232,9 +276,11 @@ static inline void writel(u32 value, volatile void __iomem *addr)
 #define writeq writeq
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeq(__cpu_to_le64(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 #endif /* CONFIG_64BIT */
@@ -248,7 +294,12 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
 #define readb_relaxed readb_relaxed
 static inline u8 readb_relaxed(const volatile void __iomem *addr)
 {
-	return __raw_readb(addr);
+	u8 val;
+
+	log_read_mmio(8, addr, _THIS_IP_);
+	val = __raw_readb(addr);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -256,7 +307,12 @@ static inline u8 readb_relaxed(const volatile void __iomem *addr)
 #define readw_relaxed readw_relaxed
 static inline u16 readw_relaxed(const volatile void __iomem *addr)
 {
-	return __le16_to_cpu(__raw_readw(addr));
+	u16 val;
+
+	log_read_mmio(16, addr, _THIS_IP_);
+	val = __le16_to_cpu(__raw_readw(addr));
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -264,7 +320,12 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
 #define readl_relaxed readl_relaxed
 static inline u32 readl_relaxed(const volatile void __iomem *addr)
 {
-	return __le32_to_cpu(__raw_readl(addr));
+	u32 val;
+
+	log_read_mmio(32, addr, _THIS_IP_);
+	val = __le32_to_cpu(__raw_readl(addr));
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -272,7 +333,12 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
 #define readq_relaxed readq_relaxed
 static inline u64 readq_relaxed(const volatile void __iomem *addr)
 {
-	return __le64_to_cpu(__raw_readq(addr));
+	u64 val;
+
+	log_read_mmio(64, addr, _THIS_IP_);
+	val =__le64_to_cpu(__raw_readq(addr));
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -280,7 +346,9 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
 #define writeb_relaxed writeb_relaxed
 static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__raw_writeb(value, addr);
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -288,7 +356,9 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 #define writew_relaxed writew_relaxed
 static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__raw_writew(cpu_to_le16(value), addr);
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -296,7 +366,9 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 #define writel_relaxed writel_relaxed
 static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__raw_writel(__cpu_to_le32(value), addr);
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -304,7 +376,9 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 #define writeq_relaxed writeq_relaxed
 static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__raw_writeq(__cpu_to_le64(value), addr);
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 16 19:36:48 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 09:06:48 +0530
Subject: [PATCHv7 5/5] asm-generic/io: Add logging support for MMIO
 accessors
In-Reply-To: <202201160019.hrsMYj6V-lkp@intel.com>
References: <8085e36ca19787ae111e4cfbb5c555e65bd34be6.1642233364.git.quic_saipraka@quicinc.com>
 <202201160019.hrsMYj6V-lkp@intel.com>
Message-ID: <c441e4f1-02e6-058e-3d53-549afc9d960b@quicinc.com>

On 1/15/2022 10:03 PM, kernel test robot wrote:
> Hi Sai,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on next-20220115]
> [cannot apply to arm64/for-next/core arnd-asm-generic/master arm-perf/for-next/perf linus/master v5.16 v5.16-rc8 v5.16-rc7 v5.16]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
>
> url:    https://github.com/0day-ci/linux/commits/Sai-Prakash-Ranjan/lib-rwmmio-arm64-Add-support-to-trace-register-reads-writes/20220115-211708
> base:    bd8d9cef2a7932e688ca267ea1adf5ea6557c777
> config: nios2-defconfig (https://download.01.org/0day-ci/archive/20220116/202201160019.hrsMYj6V-lkp at intel.com/config)
> compiler: nios2-linux-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>          wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          # https://github.com/0day-ci/linux/commit/0757812bba83a756f73ce1a84c86ded3e276cd0f
>          git remote add linux-review https://github.com/0day-ci/linux
>          git fetch --no-tags linux-review Sai-Prakash-Ranjan/lib-rwmmio-arm64-Add-support-to-trace-register-reads-writes/20220115-211708
>          git checkout 0757812bba83a756f73ce1a84c86ded3e276cd0f
>          # save the config file to linux build tree
>          mkdir build_dir
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=nios2 SHELL=/bin/bash
>
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
>
> All errors (new ones prefixed by >>):
>
>     In file included from arch/nios2/include/asm/io.h:41,
>                      from include/linux/io.h:13,
>                      from arch/nios2/include/asm/pgtable.h:18,
>                      from include/linux/pgtable.h:6,
>                      from arch/nios2/kernel/nios2_ksyms.c:11:
>     include/asm-generic/io.h: In function 'readb':
>>> include/asm-generic/io.h:181:32: error: '_THIS_IP_' undeclared (first use in this function)
>       181 |         log_read_mmio(8, addr, _THIS_IP_);
>           |                                ^~~~~~~~~
>     include/asm-generic/io.h:181:32: note: each undeclared identifier is reported only once for each function it appears in
>     include/asm-generic/io.h: In function 'readw':
>     include/asm-generic/io.h:196:33: error: '_THIS_IP_' undeclared (first use in this function)
>       196 |         log_read_mmio(16, addr, _THIS_IP_);
>           |                                 ^~~~~~~~~
>     include/asm-generic/io.h: In function 'readl':
>     include/asm-generic/io.h:211:33: error: '_THIS_IP_' undeclared (first use in this function)
>       211 |         log_read_mmio(32, addr, _THIS_IP_);
>           |                                 ^~~~~~~~~
>     include/asm-generic/io.h: In function 'writeb':
>     include/asm-generic/io.h:241:40: error: '_THIS_IP_' undeclared (first use in this function)
>       241 |         log_write_mmio(value, 8, addr, _THIS_IP_);
>           |                                        ^~~~~~~~~
>     include/asm-generic/io.h: In function 'writew':
>     include/asm-generic/io.h:253:41: error: '_THIS_IP_' undeclared (first use in this function)
>       253 |         log_write_mmio(value, 16, addr, _THIS_IP_);
>           |                                         ^~~~~~~~~
>     include/asm-generic/io.h: In function 'writel':
>     include/asm-generic/io.h:265:41: error: '_THIS_IP_' undeclared (first use in this function)
>       265 |         log_write_mmio(value, 32, addr, _THIS_IP_);
>           |                                         ^~~~~~~~~

Hmm I need to include <linux/instruction_pointer.h> for this, although 
arm64 build doesn't
throw this warning. Now posted v8 with this fix - 
https://lore.kernel.org/lkml/cover.1642309054.git.quic_saipraka at quicinc.com/

>
> vim +/_THIS_IP_ +181 include/asm-generic/io.h
>
>     169	
>     170	/*
>     171	 * {read,write}{b,w,l,q}() access little endian memory and return result in
>     172	 * native endianness.
>     173	 */
>     174	
>     175	#ifndef readb
>     176	#define readb readb
>     177	static inline u8 readb(const volatile void __iomem *addr)
>     178	{
>     179		u8 val;
>     180	
>   > 181		log_read_mmio(8, addr, _THIS_IP_);
>     182		__io_br();
>     183		val = __raw_readb(addr);
>     184		__io_ar(val);
>     185		log_post_read_mmio(val, 8, addr, _THIS_IP_);
>     186		return val;
>     187	}
>     188	#endif
>     189	
>
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From julianbraha at gmail.com  Sun Jan 16 20:09:40 2022
From: julianbraha at gmail.com (Julian Braha)
Date: Sun, 16 Jan 2022 23:09:40 -0500
Subject: [PATCH v2 RESEND] ARM: fix unmet dependency on BITREVERSE for
 HAVE_ARCH_BITREVERSE
Message-ID: <20220117040940.59557-1-julianbraha@gmail.com>

Resending this to properly add it to the patch tracker - thanks for letting
me know, Arnd :)

When ARM is enabled, and BITREVERSE is disabled,
Kbuild gives the following warning:

WARNING: unmet direct dependencies detected for HAVE_ARCH_BITREVERSE
  Depends on [n]: BITREVERSE [=n]
  Selected by [y]:
  - ARM [=y] && (CPU_32v7M [=n] || CPU_32v7 [=y]) && !CPU_32v6 [=n]

This is because ARM selects HAVE_ARCH_BITREVERSE
without selecting BITREVERSE, despite
HAVE_ARCH_BITREVERSE depending on BITREVERSE.

This unmet dependency bug was found by Kismet,
a static analysis tool for Kconfig. Please advise if this
is not the appropriate solution.

Signed-off-by: Julian Braha <julianbraha at gmail.com>
---
v2:
Changed this fix to remove the dependency on BITREVERSE from
HAVE_ARCH_BITREVERSE, since it isn't actually necessary.

v1 link:
https://lore.kernel.org/linux-arm-kernel/20211029203110.8343-1-julianbraha at gmail.com/

KernelVersion: v5.16-rc5

 lib/Kconfig | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/Kconfig b/lib/Kconfig
index c80fde816a7e..9b5a692ce00c 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -45,7 +45,6 @@ config BITREVERSE
 config HAVE_ARCH_BITREVERSE
 	bool
 	default n
-	depends on BITREVERSE
 	help
 	  This option enables the use of hardware bit-reversal instructions on
 	  architectures which support such operations.
--
2.32.0


From f.fainelli at gmail.com  Sun Jan 16 20:59:15 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 16 Jan 2022 20:59:15 -0800
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <31f2cd8f-32b6-beca-0cae-66c23b73ece0@gmail.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <31f2cd8f-32b6-beca-0cae-66c23b73ece0@gmail.com>
Message-ID: <bdda31f0-7ec0-50e8-dfaa-d8536a3219e5@gmail.com>



On 1/16/2022 12:15 PM, Florian Fainelli wrote:
> Hi Stefan,
> 
> On 1/16/2022 9:26 AM, Stefan Wahren wrote:
>> Hi,
>>
>> recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
>> Aarch64 with Arch Linux. I'm able to reproduce this issue on my
>> Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
>> the connected HDMI monitor off and on again.
>>
>> Kernel output is the following:
>>
>> [15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
>> unhandled: 0
>> [15053.295440] ->handle_irq():? 00000000b28cf1d1,
>> brcmstb_l2_intc_irq_handle+0x0/0x1e0
>> [15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
>> [15053.315233] ->action(): 00000000236e815e
>> [15053.322022] ->action->handler(): 0000000013023289,
>> bad_chained_irq+0x0/0x50
>> [15053.331909]????? IRQ_LEVEL set
>> [15053.337822]??? IRQ_NOPROBE set
>> [15053.343715]? IRQ_NOREQUEST set
>> [15053.349585]?? IRQ_NOTHREAD set
> 
> OK, so those should have been cleared during the call to 
> irq_alloc_domain_generic_chips(), any clues why they are set here?
> 
>>
>> Content of /proc/interrupts after the issue occured:
>>
>> ??????????? CPU0?????? CPU1?????? CPU2?????? CPU3
>> ?? 9:????????? 0????????? 0????????? 0????????? 0???? GICv2? 25 Level
>> vgic
>> ??10:????????? 1????????? 0????????? 0????????? 0???? GICv2 128 Level
>> (null)
> 
> This is suspicious, we should not have an interrupt registered here at 
> all since we call irq_set_chained_handler_and_data, this is a L2 
> interrupt controller, not a leaf interrupt with a descriptor. On all 
> Broadcom STB systems where this interrupt controller is used, I 
> definitively don't see any entries for the L2 output to the GIC in 
> /proc/interrupts because no interrupt descriptor is allocated.
> 
> This makes me wonder where this is coming from but the message about irq 
> 10 being bad would make sense then.
> 
>> ??12:???? 130322????? 26028????? 27670???? 135225???? GICv2? 30 Level
>> arch_timer
>> ??13:????????? 0????????? 0????????? 0????????? 0???? GICv2? 27 Level
>> kvm guest vtimer
>> ??19:????????? 0????????? 0????????? 0????????? 0???? GICv2 107 Level
>> fe004000.txp
>> ??20:?????? 7450????????? 0????????? 0????????? 0???? GICv2? 65 Level
>> fe00b880.mailbox
>> ??25:?????? 6525????????? 0????????? 0????????? 0???? GICv2 153 Level
>> uart-pl011
>> ??26:????????? 0????????? 0????????? 0????????? 0???? GICv2 149 Level
>> fe205000.i2c, fe804000.i2c
>> ??27:????????? 9????????? 0????????? 0????????? 0???? GICv2 125 Level
>> ttyS1
>> ??28:????? 36999????????? 0????????? 0????????? 0???? GICv2 158 Level
>> mmc0, mmc1
>> ??29:????????? 1????????? 0????????? 0????????? 0???? GICv2 129 Level
>> vc4 hvs
>> ??30:????????? 0????????? 0????????? 0????????? 0???? GICv2 105 Level
>> fe980000.usb, fe980000.usb
>> ??31:????????? 0????????? 0????????? 0????????? 0???? GICv2 112 Level
>> DMA IRQ
>> ??33:????????? 0????????? 0????????? 0????????? 0???? GICv2 114 Level
>> DMA IRQ
>> ??40:????????? 0????????? 0????????? 0????????? 0???? GICv2 141 Level
>> vc4 crtc
>> ??41:????????? 0????????? 0????????? 0????????? 0???? GICv2 142 Level
>> vc4 crtc, vc4 crtc
>> ??42:???????? 10????????? 0????????? 0????????? 0???? GICv2 133 Level
>> vc4 crtc
>> ??43:????????? 1????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
>> ??44:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
>> ??47:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
>> ??48:????????? 1????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
>> ??49:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
>> ??50:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
>> ??53:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
>> ??54:????????? 0????????? 0????????? 0????????? 0
>> interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
>> ??55:????????? 7????????? 0????????? 0????????? 0???? GICv2? 66 Level
>> VCHIQ doorbell
>> ??56:????????? 0????????? 0????????? 0????????? 0???? GICv2? 48 Level
>> arm-pmu
>> ??57:????????? 0????????? 0????????? 0????????? 0???? GICv2? 49 Level
>> arm-pmu
>> ??58:????????? 0????????? 0????????? 0????????? 0???? GICv2? 50 Level
>> arm-pmu
>> ??59:????????? 0????????? 0????????? 0????????? 0???? GICv2? 51 Level
>> arm-pmu
>> ??62:????? 47599????????? 0????????? 0????????? 0???? GICv2 189 Level
>> eth0
>> ??63:?????? 4681????????? 0????????? 0????????? 0???? GICv2 190 Level
>> eth0
>> ??64:????????? 0????????? 0????????? 0????????? 0???? GICv2 175 Level
>> PCIe PME, aerdrv
>> ??65:??????? 326????????? 0????????? 0????????? 0? BRCM STB PCIe MSI
>> 524288 Edge????? xhci_hcd
>> IPI0:????? 2442?????? 5185?????? 7195????? 18290?????? Rescheduling
>> interrupts
>> IPI1:?????? 481??????? 383??????? 518??????? 533?????? Function call
>> interrupts
>> IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop 
>> interrupts
>> IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for
>> crash dump) interrupts
>> IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast
>> interrupts
>> IPI5:???????? 1????????? 0????????? 0????????? 0?????? IRQ work 
>> interrupts
>> IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up
>> interrupts
>> Err:????????? 1
>>
>> Comparing the vendor & mainline DTS, i noticed differences at hdmi0/1.
>> The vendor DTS has an additional register to access the same space as
>> aon_intr (interrupt parent), which looks ugly [2].
> 
> OK, so while I do see how we set external_irq_controller to let the 
> interrupt be managed externally from vc4_hdmi.c else do it internally, I 
> don't see the code that tries to map the "intr2" register space, let 
> alone fetch its resource, do you know where that is?

Downstream appears to be setting the 'aon_intr' Device Tree node with a 
status = disabled property, still leaves me wondering whether the 
"intr2" register space is used.

I think it would be prudent to change the hpd_con, hpd_rm variables in 
vc4_hdmi.c to be signed integers instead of unsigned integers, if 
nothing else such that -EPROBE_DEFER might be returned.

Also, in 5.16, we can finally build irq-brcmstb-l2 as a module, so 
dealing with -EPROBE_DEFER might be necessary.

I am still lost as to why GIC_SPI 96 was allowed to show up as leaf 
interrupt, unless there is something modification of the Device Tree 
being used by the VPU firmware?

> 
>>
>> Additionally i noted that bcm2711.dtsi uses the compatible
>> "brcm,bcm2711-l2-intc" with a level high interrupt, but according to
>> irq-brcmstb-l2.c [3] the compatible is not defined and would fallback to
>> "brcm,l2-intc" with brcmstb_l2_edge_intc_of_init. This looks fishy.
> 
> The hardware level 2 controller at 0x7ef00100 is definitively the same 
> kind that supports edge interrupt flows since it has the CPU_STATUS, 
> CPU_CLEAR, CPU_MASK_STATUS, CPU_MASK_SET and CPU_MASK_CLEAR registers, 
> so it seems to me like declaring the interrupt controller of the kind 
> "brcm,l2-intc" and using the edge interrupt handling is not necessarily 
> a problem.



> 
>>
>> I didn't try to reproduce this with Raspberry Pi OS & mainline kernel,
>> but i hope these are enough information so far.
>>
>> [1] - https://archlinuxarm.org/forum/viewtopic.php?f=65&t=15791
>>
>> [2] -
>> https://github.com/raspberrypi/linux/blob/rpi-5.15.y/arch/arm/boot/dts/bcm2711.dtsi#L339 
>>
>>
>> [3] -
>> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/irqchip/irq-brcmstb-l2.c?h=v5.15.15#n278 
>>
>>
> 

-- 
Florian


From julianbraha at gmail.com  Sun Jan 16 21:03:24 2022
From: julianbraha at gmail.com (Julian Braha)
Date: Mon, 17 Jan 2022 00:03:24 -0500
Subject: [PATCH] ASoC: mediatek: fix unmet dependency on GPIOLIB for
 SND_SOC_DMIC
Message-ID: <20220117050324.68371-1-julianbraha@gmail.com>

When SND_SOC_MT8195_MT6359_RT1011_RT5682 is selected,
and GPIOLIB is not selected,
Kbuild gives the following warning:

WARNING: unmet direct dependencies detected for SND_SOC_DMIC
  Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && GPIOLIB [=n]
  Selected by [y]:
  - SND_SOC_MT8195_MT6359_RT1011_RT5682 [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=y] && SND_SOC_MT8195 [=y] && MTK_PMIC_WRAP [=y]

This is because SND_SOC_MT8195_MT6359_RT1011_RT5682
selects SND_SOC_DMIC without selecting or depending on
GPIOLIB, depsite SND_SOC_DMIC depending on GPIOLIB.

This unmet dependency bug was detected by Kismet,
a static analysis tool for Kconfig. Please advise
if this is not the appropriate solution.

Signed-off-by: Julian Braha <julianbraha at gmail.com>
---
 sound/soc/mediatek/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 9306b7ca2644..0d154350f180 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -216,7 +216,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682
 
 config SND_SOC_MT8195_MT6359_RT1011_RT5682
 	tristate "ASoC Audio driver for MT8195 with MT6359 RT1011 RT5682 codec"
-	depends on I2C
+	depends on I2C && GPIOLIB
 	depends on SND_SOC_MT8195 && MTK_PMIC_WRAP
 	select SND_SOC_MT6359
 	select SND_SOC_RT1011
-- 
2.32.0



From julianbraha at gmail.com  Sun Jan 16 21:10:02 2022
From: julianbraha at gmail.com (Julian Braha)
Date: Mon, 17 Jan 2022 00:10:02 -0500
Subject: [PATCH] ASoC: stm32: fix unmet dependency on GPIOLIB for SND_SOC_DMIC
Message-ID: <20220117051002.70270-1-julianbraha@gmail.com>

When SND_SOC_STM32_DFSDM is selected,
and GPIOLIB is not selected,
Kbuild gives the following warning:

WARNING: unmet direct dependencies detected for SND_SOC_DMIC
  Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && GPIOLIB [=n]
  Selected by [y]:
  - SND_SOC_STM32_DFSDM [=y] && SOUND [=y] && !UML && SND [=y] && (ARCH_STM32 || COMPILE_TEST [=y]) && SND_SOC [=y] && STM32_DFSDM_ADC [=y]

This is because SND_SOC_STM32_DFSDM selects
SND_SOC_DMIC without selecting or depending on
GPIOLIB, despite SND_SOC_DMIC depending on GPIOLIB.

This unmet dependency bug was detected by Kismet,
a static analysis tool for Kconfig. Please advise
if this is not the appropriate solution.

Signed-off-by: Julian Braha <julianbraha at gmail.com>
---
 sound/soc/stm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig
index da1f7a16605b..bfc11b606bbd 100644
--- a/sound/soc/stm/Kconfig
+++ b/sound/soc/stm/Kconfig
@@ -37,6 +37,7 @@ config SND_SOC_STM32_DFSDM
 	depends on ARCH_STM32 || COMPILE_TEST
 	depends on SND_SOC
 	depends on STM32_DFSDM_ADC
+	depends on GPIOLIB
 	select SND_SOC_GENERIC_DMAENGINE_PCM
 	select SND_SOC_DMIC
 	select IIO_BUFFER_CB
-- 
2.32.0



From allen-kh.cheng at mediatek.com  Sun Jan 16 21:45:00 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 17 Jan 2022 13:45:00 +0800
Subject: [PATCH v14 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <CAOReqxiSAhrSjXVW=D+ndXko95qLuHGkkNs5Wf-yVEcv1YompQ@mail.gmail.com>
References: <20220114114633.742-1-allen-kh.cheng@mediatek.com>
 <20220114114633.742-3-allen-kh.cheng@mediatek.com>
 <CAOReqxiSAhrSjXVW=D+ndXko95qLuHGkkNs5Wf-yVEcv1YompQ@mail.gmail.com>
Message-ID: <73221aee8a6144384309c1b2e01acdb8c1531c5c.camel@mediatek.com>

On Fri, 2022-01-14 at 08:57 -0800, Curtis Malainey wrote:
> > +
> > +static struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct
> > mbox_controller *mbox)
> > +{
> > +       return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
> > +}
> 
> this could probably be inline
> 

Hi Curtis,

I check the symbol table of kernel.

get_mtk_adsp_mbox_priv is decided to inline by compiler.

I think it's ok use inline this function.

on other hand, compile will not use inline definition of
mtk_adsp_mbox_xlate for the mbox_controller's implement 
(I also check the symbole of kernel)

I will update next version for get_mtk_adsp_mbox_priv.

Thank.

> 
> > +
> > +static struct mbox_chan *mtk_adsp_mbox_xlate(struct
> > mbox_controller *mbox,
> > +                                            const struct
> > of_phandle_args *sp)
> > +{
> > +       return mbox->chans;
> > +}
> 
> also could probably benefit from inline



From quic_schowdhu at quicinc.com  Sun Jan 16 21:49:43 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Mon, 17 Jan 2022 11:19:43 +0530
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data Capture
 and Compare unit(DCC)
In-Reply-To: <Ydhi1/SH5ySDLNfI@ripper>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <YbzvD+FFHuDWzCtZ@yoga> <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
 <YdeC456prDBG7tBA@ripper> <77a2ef02-384d-ce67-ae84-02c385eccd60@quicinc.com>
 <Ydhi1/SH5ySDLNfI@ripper>
Message-ID: <c0f792f4-522e-f1fd-5b58-579389c2c48d@quicinc.com>


On 1/7/2022 9:27 PM, Bjorn Andersson wrote:
> On Fri 07 Jan 07:27 PST 2022, Souradeep Chowdhury wrote:
>
>> On 1/7/2022 5:31 AM, Bjorn Andersson wrote:
>>> On Wed 05 Jan 23:57 PST 2022, Souradeep Chowdhury wrote:
>>>
>>>> On 12/18/2021 1:41 AM, Bjorn Andersson wrote:
>>>>> On Tue 10 Aug 12:54 CDT 2021, Souradeep Chowdhury wrote:
>>>>>
>>>>>> The DCC is a DMA Engine designed to capture and store data
>>>>>> during system crash or software triggers.The DCC operates
>>>>> Please include a space after '.'
>>>> Ack
>>>>>> based on user inputs via the sysfs interface.The user gives
>>>>>> addresses as inputs and these addresses are stored in the
>>>>>> form of linkedlists.In case of a system crash or a manual
>>>>> I think the user configures the DCC hardware with "a sequence of
>>>>> operations to be performed as DCC is triggered".
>>>>>
>>>>> Afaict the sequence is stored just as a sequence of operations in SRAM,
>>>>> there's no linked list involved - except in your intermediate
>>>>> implementation.
>>>> The user just enters the addresses as input whereas the sequence of
>>>> operations takes
>>>>
>>>> place as per configuration code inside the driver. The end result is storage
>>>> of these
>>>>
>>>> addresses inside the DCC SRAM. The DCC hardware will capture the value at
>>>> these
>>>>
>>>> addresses on a crash or manual trigger by the user.
>>>>
>>>>>> software trigger by the user through the sysfs interface,
>>>>>> the dcc captures and stores the values at these addresses.
>>>>>> This patch contains the driver which has all the methods
>>>>>> pertaining to the sysfs interface, auxiliary functions to
>>>>>> support all the four fundamental operations of dcc namely
>>>>>> read, write, first read then write and loop.The probe method
>>>>> "first read then write" is called "read/modify/write"
>>>> Ack
>>>>>> here instantiates all the resources necessary for dcc to
>>>>>> operate mainly the dedicated dcc sram where it stores the
>>>>>> values.The DCC driver can be used for debugging purposes
>>>>>> without going for a reboot since it can perform manual
>>>>>> triggers.
>>>>>>
>>>>>> Also added the documentation for sysfs entries
>>>>>> and explained the functionalities of each sysfs file that
>>>>>> has been created for dcc.
>>>>>>
>>>>>> The following is the justification of using sysfs interface
>>>>>> over the other alternatives like ioctls
>>>>>>
>>>>>> i) As can be seen from the sysfs attribute descriptions,
>>>>>> most of it does basic hardware manipulations like dcc_enable,
>>>>>> dcc_disable, config reset etc. As a result sysfs is preferred
>>>>>> over ioctl as we just need to enter a 0 or 1.
>>>>>>
>>>>> As I mentioned in our chat, using sysfs allows us to operate the
>>>>> interface using the shell without additional tools.
>>>>>
>>>>> But I don't think that it's easy to implement enable/disable/reset using
>>>>> sysfs is a strong argument. The difficult part of this ABI is the
>>>>> operations to manipulate the sequence of operations, so that's what you
>>>>> need to have a solid plan for.
>>>> The sysfs interface is being used to get the addresses values entered by the
>>>> user
>>>>
>>>> and to also go for manual triggers. The sequence of operations are kept as a
>>>> part of
>>>>
>>>> fixed driver code which is called when the user enters the data.
>>>>
>>> But does the hardware really just operate on "addresses values entered
>>> by the user". Given the various types of operations: read, write,
>>> read-modify-write and loop I get the feeling that the hardware
>>> "executes" a series of actions.
>>>
>>> I'm don't think the proposed sysfs interface best exposes this to the
>>> user and I don't think that "it's easy to implement enable/disable
>>> attributes in sysfs" is reason enough to go with that approach.
>> So the sysfs interface here has been introduced keeping in mind how the
>> DCC_SRAM needs to be
>>
>> programmed for the dcc hardware to work. We are maintaining a list here
>> based on the address
>>
>> entry. The 4 cases for the type of addresses are as follows-:
>>
>> i) READ ADDRESSES
>>
>> user enters something like "echo <addr> <len> > config"
>>
>> DCC driver stores the <addr> along with the length information in the
>> DCC_SRAM.
>>
>> ii) WRITE ADDRESSES
>>
>> User enters something like "echo <addr> <write_val> 1? > config_write"
>>
>> DCC stores the <addr> first in sram followed by <write_val>.
>>
>> For the above 2 type of addresses there won't be much difference if we use
>> IOCTL.
>>
>> However, for the next 2 type of addresses
>>
>> iii) LOOP ADDRESSES
>>
>> user has to enter something like below
>>
>> echo 9 > loop
>> echo 0x01741010 1 > config
>> echo 0x01741014 1 > config
>> echo 1 > loop
>>
>> The DCC SRAM will be programmed precisely like the above entries where the
>> loop count will be stored first
>>
>> followed by loop addresses and then again a "echo 1 > loop " marks the end
>> of loop addresses.
>>
>> in DCC_SRAM.
>>
>> iv) READ_WRITE ADDRESSES
>>
>> User has to enter something like below
>>
>> echo <addr> > /sys/bus/platform/devices/../config
>>
>> echo <mask> <val> > /sys/bus/platform/devices/../rd_mod_wr
>>
>> Here first the? <addr> is stored in DCC_SRAM followed by <mask> and then the
>> <val>.
>>
>> The above representation to the user space is consistent with the dcc
>> hardware in terms of
>>
>> the way the sequence of values are programmed in the DCC SRAM . Moving to
>> IOCTL will
>>
>> only change the way the READ_WRITE address is represented although user will
>> have to enter
>>
>> multiple parameters at once, let me know if we still need to go for the
>> same.
>>
> So if I understand correctly, my concern is that if I would like to
> perform something like (in pseudo code):
>
> readl(X)
> write(1, Y)
> readl(Z) 5 times
>
> then I will do this as:
>
> echo X > config
> echo Y 1 > config_write
> echo 5 > loop
> echo Z > config
> echo 1 > loop
>
> And the DCC driver will then write this to SRAM as something like:
>
> read X
> write Y, 1
> loop 5
> read Z
> loop
>
>
> In other words, my mind and the DCC has the same representation of this
> sequence of operations, but I have to shuffle the information into 4
> different sysfs attributes to get there.
>
> The design guideline for sysfs is that each attribute should hold one
> value per attribute, but in your model the attributes are tangled and
> writing things to them depends on what has been written in that or other
> attributes previously.
>
> I simply don't think that's a good ABI.

Ack.

Should I change this to have separate sysfs files dealing with separate 
type of instructions?

For example I can have separate files like config_read, 
config_write(already exists), config_loop

and config_read_write to handle 4 different type of instructions with 
inputs like

echo <loop_offset> <loop_address_numbers> <loop_address_1> 
<loop_address_2>.. > config_loop

echo <address> <mask> <val> > config_read_write

and so on

>
> [..]
>>>>>> +		The address argument should
>>>>>> +		be given of the form <mask> <value>.For debugging
>>>>>> +		purposes sometimes we need to first read from a register
>>>>>> +		and then set some values to the register.
>>>>>> +		Example:
>>>>>> +		echo 0x80000000 > /sys/bus/platform/devices/.../config
>>>>>> +		(Set the address in config file)
>>>>>> +		echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
>>>>>> +		(Provide the mask and the value to write)
>>>>>> +
>>>>>> +What:           /sys/bus/platform/devices/.../ready
>>>>>> +Date:           March 2021
>>>>>> +Contact:        Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>>>> +Description:
>>>>>> +		This file is used to check the status of the dcc
>>>>>> +		hardware if it's ready to take the inputs.
>>>>> When will this read "false"?
>>>> This will give false if the DCC hardware is not in an operational state.
>>>>
>>>> Will update accordingly.
>>>>
>>>>>> +		Example:
>>>>>> +		cat /sys/bus/platform/devices/.../ready
>>>>>> +
>>>>>> +What:		/sys/bus/platform/devices/.../curr_list
>>>>>> +Date:		February 2021
>>>>>> +Contact:	Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>>>> +Description:
>>>>>> +		This attribute is used to enter the linklist to be
>>>>> I think it would be more appropriate to use the verb "select" here and
>>>>> afaict it's a "list" as the "linked" part only relates to your
>>>>> implementation).
>>>>>
>>>>> But that said, I don't like this ABI. I think it would be cleaner if you
>>>>> had specific attributes for each of the lists. That way it would be
>>>>> clear that you have N lists and they can be configured and enabled
>>>>> independently, and there's no possible race conditions.
>>>> So we do have attributes for independent lists in this case. The user is
>>>> given the option
>>>>
>>>> to configure multiple lists at one go. For example I can do
>>>>
>>>> echo 1 > curr_list
>>>>
>>>> echo 0x18000010 1 > config
>>>> echo 0x18000024 1 > config
>>>>
>>>> Then followed by
>>>>
>>>> echo 2 > curr_list
>>>>
>>>> echo 0x18010038 6 > config
>>>> echo 0x18020010 1 > config
>>>>
>>>> We will get the output in terms of two separate list of registers values.
>>>>
>>> I understand that this will define two lists of operations and that we
>>> will get 2 and 7 registers dumped, respectively. Perhaps unlikely, but
>>> what happens if you try to do these two operations concurrently?
>>>
>>>
>>> What I'm suggesting here is that if you have N contexts, you should have
>>> N interfaces to modify each one independently - simply because that's
>>> generally a very good thing.
>> Not sure if there will ever be a concurrency issue in this case.
>> This is just about programming the DCC SRAM from the user entries
>> sequentially.
> So you've decided that two such sequences must not happen at the same
> time. (I know it's unlikely, but there's nothing preventing me from
> running the two snippets of echos concurrently and the outcome will be
> unexpected)

So as per the dcc hardware configuration document, parallel programming 
of lists are not

supported for dcc. We program the lists sequentially one after the other.

>
>> The curr_list number is nothing but some register writes
>> done in the dcc so that the dcc_hardware knows the beginning and end
>> of a particular list and can dump the captured data according. Even if
>> an user chooses multiple curr_list entries, it will be programmed
>> sequentially in DCC_SRAM.
>>
> So there's no separation between the lists in the hardware?
>
> Looking at the driver I get a sense that we have N lists that can be
> configured independently and will be run "independently" upon a trigger.
>
> If this isn't the case, what's the purpose of the multiple lists?

Lists are programmed sequentially from the driver perspective.

We have multiple lists in case of dcc because multiple software 
components may be using

dcc hardware at once in which case there are individual lists allotted 
for each individual components.

For example kernel might have a few lists to access whereas the rest 
maybe used by SDI which is a

separate component. Each list is of arbitrary length as entered by the 
user and one list can be updated

with it's base address after the previous list has been programmed in 
DCC_SRAM like below :-

 ??????????????? ret = __dcc_ll_cfg(drvdata, list);
 ??????????????? if (ret) {
 ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
 ??????????????????????? goto err;
 ??????????????? }

 ??????????????? /* 3. program DCC_RAM_CFG reg */
 ??????????????? dcc_writel(drvdata, ram_cfg_base +
 ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
  

>
>>>>>> +		used while appending addresses.The range of values
>>>>>> +		for this can be from 0 to 3.This feature is given in
>>>>>> +		order to use certain linkedlist for certain debugging
>>>>>> +		purposes.
>>>>>> +		Example:
>>>>>> +		echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
>>>>>> +
>>> [..]
>>>>>> diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
>>> [..]
>>>>>> +static int dcc_valid_list(struct dcc_drvdata *drvdata, int curr_list)
>>>>>> +{
>>>>>> +	u32 lock_reg;
>>>>>> +
>>>>>> +	if (list_empty(&drvdata->cfg_head[curr_list]))
>>>>>> +		return -EINVAL;
>>>>>> +
>>>>>> +	if (drvdata->enable[curr_list]) {
>>>>>> +		dev_err(drvdata->dev, "List %d is already enabled\n",
>>>>>> +				curr_list);
>>>>>> +		return -EINVAL;
>>>>>> +	}
>>>>>> +
>>>>>> +	lock_reg = dcc_readl(drvdata, DCC_LL_LOCK(curr_list));
>>>>> Under what circumstances would this differ from
>>>>> drvdata->enable[curr_list}?
>>>> So locking the list is done on the register as soon as the user enters the
>>>> curr_list entry whereas
>>>>
>>>> the list is marked as enabled only on successfully programming the SRAM
>>>> contents. So a list can
>>>>
>>>> be locked and not marked enabled in certain cases. The first is used so that
>>>> the user doesn't
>>>>
>>>> mistakenly enter the same curr_list twice whereas the later is used to mark
>>>> that the list has been
>>>>
>>>> successfully configured.
>>>>
>>> So this will mark the list as "actively in use, but disabled"? Why is
>>> this kept in the hardware? When is this not the same as the list of
>>> operations for that list being non-empty?
>> So this is in accordance with the dcc hardware configuration
>> requirement. We have to lock the list first and after that proceed
>> with the subsequent writes.
> But what does this mean? What happens when I lock a list?
>
> Afacit we have a "lock" bit and an "enable" bit. So in what circumstance
> does the hardware care about a list being locked? Wouldn't it be
> sufficient to just have the enable bit?

As explained above multiple software components might be using DCC 
hardware for which lock bit is

necessary. From only kernel perspective enable bit alone suffices for 
the operation.

>
>> As per the driver code below
>>
>>  ?????????????? /* 1. Take ownership of the list */
>>  ??????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
>>
>>  ??????????????? /* 2. Program linked-list in the SRAM */
>>  ??????????????? ram_cfg_base = drvdata->ram_cfg;
>>  ??????????????? ret = __dcc_ll_cfg(drvdata, list);
>>  ??????????????? if (ret) {
>>  ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
>>  ??????????????????????? goto err;
>>  ??????????????? }
>>
>>  ??????????????? /* 3. program DCC_RAM_CFG reg */
>>  ??????????????? dcc_writel(drvdata, ram_cfg_base +
>>  ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
>>  ??????????????? dcc_writel(drvdata, drvdata->ram_start +
>>  ??????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
>>  ??????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
>>
>>  ??????????????? /* 4. Clears interrupt status register */
>>  ??????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
>>  ??????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
>>  ??????????????????????????????????????? DCC_LL_INT_STATUS(list));
>>
>> In case of any errors we again unlock the list before exiting.
>>
> So it needs to be locked while SRAM contains a valid sequence of
> operations?
>
> Or does it need to be locked while we write to SRAM? If so, why is that?

So it needs to be locked while SRAM contains a valid sequence of operations.

The reason has been explained as above.

> Regards,
> Bjorn


From alim.akhtar at samsung.com  Sun Jan 16 21:50:08 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 17 Jan 2022 11:20:08 +0530
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <YeSHNCywXhp8gHC7@L14.lan>
References: <20220116165035.437274-1-henrik@grimler.se>
 <20220116165035.437274-4-henrik@grimler.se>
 <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>
 <CGME20220116205940epcas5p3dbab01fb6bb7a4af76169231e6d94469@epcas5p3.samsung.com>
 <YeSHNCywXhp8gHC7@L14.lan>
Message-ID: <001301d80b66$190901a0$4b1b04e0$@samsung.com>

Hi Henrik,

>-----Original Message-----
>From: Henrik Grimler [mailto:henrik at grimler.se]
>Sent: Monday, January 17, 2022 2:30 AM
>To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>Cc: semen.protsenko at linaro.org; virag.david003 at gmail.com;
>martin.juecker at gmail.com; cw00.choi at samsung.com;
>m.szyprowski at samsung.com; alim.akhtar at samsung.com;
>robh+dt at kernel.org; devicetree at vger.kernel.org; linux-samsung-
>soc at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>kernel at vger.kernel.org; ~postmarketos/upstreaming at lists.sr.ht
>Subject: Re: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
>
>Hi Krzysztof,
>
>> > +/* External sdcard */
>> > +&mmc_2 {
>> > +	status = "okay";
>> > +	bus-width = <4>;
>> > +	cap-sd-highspeed;
>> > +	card-detect-delay = <200>;
>> > +	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
>> > +	pinctrl-names = "default";
>> > +	samsung,dw-mshc-ciu-div = <3>;
>> > +	samsung,dw-mshc-ddr-timing = <0 2>;
>> > +	samsung,dw-mshc-sdr-timing = <0 4>;
>> > +	sd-uhs-sdr50;
>> > +	vmmc-supply = <&ldo19_reg>;
>> > +	vqmmc-supply = <&ldo13_reg>;
>> > +};
>> > +
>> > +&pinctrl_0 {
>> > +	mmc2_cd: sd2-cd-pins {
>> > +		samsung,pins = "gpx2-4";
>>
>> Interesting... I looked at vendor sources to board-chagall and
>> standard pin gpc2-2 is mentioned as PULL down and not-connected
>comment.
>>
>> gpx2-4 seems not mentioned at all, unless other board files are
>> actually used.
>
>Gpio seems to be spread out. GPIO_T_FLASH_DETECT is defined as gpx2-4 in
>board-universal5420-mmc.c, and then used for card detection.
>(Looking at it now again I see that write protection through sd2_wp should
>also be supported for mmc_2, can add that in next patch set.)
>
Card detect pin is generally a special function (dedicated pin) pin,
directly connected from SoC to card external slot.
And for exynos5420 it is gpc2-2 as pointed by Krzysztof.
Also PIN_FUNC_2 for gpx2-4 indicate that it is wakeup_int2 function.
Do you get a card detect interrupt when removing and inserting the card to
the card slot?
Also to avoid confusion, probably you can change the node name as "mmc2_cd:
mmc2-cd-pins" 
(as sd2-cd-pins is gpc2-2 for this SoC)


>> Anyway, if it works for you, it's good.
>>
>> Rest looks ok, I'll apply after the merge window.
>
>Thanks!
>
>> Best regards,
>> Krzysztof
>
>Best regards,
>Henrik Grimler



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:51 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:51 +0800
Subject: [PATCH v1 11/14] media: platform: mtk-mdp3: Revise frame change
 criteria
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-12-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

frame_change will trigger MDP SCP to re-calculate path and parameter.
MDP fails when it doesn't get correct parameters to process frame,
and it will activate by the following conditions:

1. first frame
2. Scenario changes (single/dual pipe)
3. input size changes
4. input format changes
5. output size changes (crop included)

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |  2 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    | 22 +++++++++++++++----
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   | 19 ++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  9 ++++++++
 4 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index 0fb932ad3560..0eb08ce69781 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -11,6 +11,7 @@
 #include <media/v4l2-mem2mem.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/soc/mediatek/mtk-mutex.h>
+#include "mtk-mdp3-regs.h"
 #include "mtk-mdp3-comp.h"
 #include "mtk-mdp3-vpu.h"
 
@@ -96,6 +97,7 @@ struct mdp_dev {
 	atomic_t				suspended;
 	atomic_t				job_count;
 	atomic_t				cmdq_count[MDP_CMDQ_NUM];
+	struct mdp_framechange_param		prev_image;
 };
 
 struct mdp_pipe_info {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
index 72a1864d880c..9afe56882208 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
@@ -77,6 +77,7 @@ static void mdp_m2m_worker(struct work_struct *work)
 	struct vb2_v4l2_buffer *src_vb, *dst_vb;
 	struct img_ipi_frameparam param = {0};
 	struct mdp_cmdq_param task = {0};
+	struct mdp_framechange_param cur_frame = {0};
 	enum vb2_buffer_state vb_state = VB2_BUF_STATE_ERROR;
 	int ret;
 
@@ -90,20 +91,33 @@ static void mdp_m2m_worker(struct work_struct *work)
 	param.type = ctx->curr_param.type;
 	param.num_inputs = 1;
 	param.num_outputs = 1;
-	param.frame_change = (ctx->frame_count[MDP_M2M_SRC] == 0);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
 	mdp_set_src_config(&param.inputs[0], frame, &src_vb->vb2_buf);
 	mdp_set_scenario(ctx->mdp_dev, &param, frame);
-	if (param.frame_change)
-		dev_info(&ctx->mdp_dev->pdev->dev,
-			 "MDP Scenario: %d\n", param.type);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
 	mdp_set_dst_config(&param.outputs[0], frame, &dst_vb->vb2_buf);
 
+	cur_frame.scenario = param.type;
+	cur_frame.frame_count = ctx->frame_count[MDP_M2M_SRC];
+	memcpy(&cur_frame.in, &param.inputs[0], sizeof(cur_frame.in));
+	memcpy(&cur_frame.out, &param.outputs[0], sizeof(cur_frame.out));
+
+	if (mdp_is_framechange(&ctx->mdp_dev->prev_image, &cur_frame)) {
+		memcpy(&ctx->mdp_dev->prev_image, &cur_frame,
+		       sizeof(struct mdp_framechange_param));
+		param.frame_change = true;
+	} else {
+		param.frame_change = false;
+	}
+
+	if (param.frame_change)
+		dev_dbg(&ctx->mdp_dev->pdev->dev,
+			"MDP Scenario: %d\n", param.type);
+
 	param.timestamp = src_vb->vb2_buf.timestamp;
 
 	ret = mdp_vpu_process(&ctx->vpu, &param);
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
index c0a7e3569853..ccd9c338ff49 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
@@ -429,6 +429,25 @@ static u32 mdp_fmt_get_plane_size(const struct mdp_format *fmt,
 	return 0;
 }
 
+bool mdp_is_framechange(struct mdp_framechange_param *prev,
+			struct mdp_framechange_param *cur)
+{
+	if (cur->frame_count == 0 ||
+	    prev->scenario != cur->scenario ||
+	    prev->in.buffer.format.colorformat != cur->in.buffer.format.colorformat ||
+	    prev->in.buffer.format.width != cur->in.buffer.format.width ||
+	    prev->in.buffer.format.height != cur->in.buffer.format.height ||
+	    prev->out.buffer.format.width != cur->out.buffer.format.width ||
+	    prev->out.buffer.format.height != cur->out.buffer.format.height ||
+	    prev->out.crop.left != cur->out.crop.left ||
+	    prev->out.crop.top != cur->out.crop.top ||
+	    prev->out.crop.width != cur->out.crop.width ||
+	    prev->out.crop.height != cur->out.crop.height)
+		return true;
+
+	return false;
+}
+
 void mdp_set_scenario(struct mdp_dev *mdp,
 		      struct img_ipi_frameparam *param,
 		      struct mdp_frame *frame)
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 3547ce10948f..436d5c899bc5 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -397,6 +397,13 @@ struct mdp_frameparam {
 	enum v4l2_quantization		quant;
 };
 
+struct mdp_framechange_param {
+	u8 scenario;
+	u32 frame_count;
+	struct img_input in;
+	struct img_output out;
+};
+
 int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f);
 const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
 					    struct mdp_frameparam *param,
@@ -408,6 +415,8 @@ int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
 int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
 			    const struct v4l2_rect *compose, s32 rotation,
 	const struct mdp_limit *limit);
+bool mdp_is_framechange(struct mdp_framechange_param *prev,
+			struct mdp_framechange_param *cur);
 void mdp_set_scenario(struct mdp_dev *mdp,
 		      struct img_ipi_frameparam *param,
 		      struct mdp_frame *frame);
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:44 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:44 +0800
Subject: [PATCH v1 04/14] soc: mediatek: mutex: support mt8195 vppsys0/1
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-5-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add mt8195 mdp mutex info to driver data of mtk-mutex

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 53 ++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 7da0f44b6f9a..dd6ef45b582a 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -186,6 +186,23 @@
 #define MT8183_MDP_PIPE_WPEI                   (MT8183_MUTEX_MDP_START + 2)
 #define MT8183_MDP_PIPE_WPEI2                  (MT8183_MUTEX_MDP_START + 3)
 
+#define MT8195_MUTEX_MDP_MOD_MASK		0xFFFFFFFF
+#define MT8195_MUTEX_MDP_MOD1_MASK		0x000000FF
+#define MT8195_MUTEX_MDP_SOF_MASK		0x00000007
+
+#define	MT8195_MDP_PIPE_WPEI			0
+#define	MT8195_MDP_PIPE_WPEI2			1
+#define	MT8195_MDP_PIPE_RDMA0			2
+#define	MT8195_MDP_PIPE_VPP1_SOUT		3
+
+#define	MT8195_MDP_PIPE_RDMA1			1
+#define	MT8195_MDP_PIPE_RDMA2			2
+#define	MT8195_MDP_PIPE_RDMA3			3
+
+#define	MT8195_MDP_PIPE_SPLIT			2
+#define	MT8195_MDP_PIPE_SPLIT2			3
+#define	MT8195_MDP_PIPE_VPP0_SOUT		4
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -388,6 +405,22 @@ static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
 };
 
+static const unsigned int mt8195_mutex_vpp0_offset[MDP_PIPE_MAX] = {
+	[MDP_PIPE_WPEI] = MT8195_MDP_PIPE_WPEI,
+	[MDP_PIPE_WPEI2] = MT8195_MDP_PIPE_WPEI2,
+	[MDP_PIPE_RDMA0] = MT8195_MDP_PIPE_RDMA0,
+	[MDP_PIPE_VPP1_SOUT] = MT8195_MDP_PIPE_VPP1_SOUT,
+};
+
+static const unsigned int mt8195_mutex_vpp1_offset[MDP_PIPE_MAX] = {
+	[MDP_PIPE_SPLIT] = MT8195_MDP_PIPE_SPLIT,
+	[MDP_PIPE_SPLIT2] = MT8195_MDP_PIPE_SPLIT2,
+	[MDP_PIPE_RDMA1] = MT8195_MDP_PIPE_RDMA1,
+	[MDP_PIPE_RDMA2] = MT8195_MDP_PIPE_RDMA2,
+	[MDP_PIPE_RDMA3] = MT8195_MDP_PIPE_RDMA3,
+	[MDP_PIPE_VPP0_SOUT] = MT8195_MDP_PIPE_SPLIT,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -444,6 +477,22 @@ static const struct mtk_mutex_data mt8195_mutex_driver_data = {
 	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
 };
 
+static const struct mtk_mutex_data mt8195_vpp0_mutex_driver_data = {
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+	.mutex_mdp_offset = mt8195_mutex_vpp0_offset,
+	.mutex_mdp_mod_mask = MT8195_MUTEX_MDP_MOD_MASK,
+	.mutex_mdp_sof_mask = MT8195_MUTEX_MDP_SOF_MASK,
+};
+
+static const struct mtk_mutex_data mt8195_vpp1_mutex_driver_data = {
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+	.mutex_mdp_offset = mt8195_mutex_vpp1_offset,
+	.mutex_mdp_mod_mask = MT8195_MUTEX_MDP_MOD_MASK,
+	.mutex_mdp_sof_mask = MT8195_MUTEX_MDP_SOF_MASK,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -777,6 +826,10 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8192_mutex_driver_data},
 	{ .compatible = "mediatek,mt8195-disp-mutex",
 	  .data = &mt8195_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-vpp0-mutex",
+	  .data = &mt8195_vpp0_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-vpp1-mutex",
+	  .data = &mt8195_vpp1_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:54 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:54 +0800
Subject: [PATCH v1 14/14] dt-bindings: media: mediatek: mdp3: add yaml for new
 modules added in mt8195
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-15-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add yaml for new modules added in mt8195

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
This patch is base on [1]
[1] dt-bindings: arm: mediatek: move out common module from display folder
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220107101425.6917-8-jason-jh.lin at mediatek.com/
---
 .../bindings/arm/mediatek/mediatek,mmsys.yaml |  2 +
 .../bindings/media/mediatek,mdp3-aal.yaml     | 56 +++++++++++++++++
 .../bindings/media/mediatek,mdp3-color.yaml   | 56 +++++++++++++++++
 .../bindings/media/mediatek,mdp3-fg.yaml      | 55 +++++++++++++++++
 .../bindings/media/mediatek,mdp3-hdr.yaml     | 55 +++++++++++++++++
 .../bindings/media/mediatek,mdp3-merge.yaml   | 54 ++++++++++++++++
 .../bindings/media/mediatek,mdp3-ovl.yaml     | 53 ++++++++++++++++
 .../bindings/media/mediatek,mdp3-pad.yaml     | 56 +++++++++++++++++
 .../bindings/media/mediatek,mdp3-rdma.yaml    | 28 +++++++++
 .../bindings/media/mediatek,mdp3-rsz.yaml     |  2 +
 .../bindings/media/mediatek,mdp3-split.yaml   | 58 ++++++++++++++++++
 .../bindings/media/mediatek,mdp3-stitch.yaml  | 53 ++++++++++++++++
 .../bindings/media/mediatek,mdp3-tcc.yaml     | 54 ++++++++++++++++
 .../bindings/media/mediatek,mdp3-tdshp.yaml   | 61 +++++++++++++++++++
 .../bindings/media/mediatek,mdp3-wrot.yaml    |  3 +
 .../bindings/soc/mediatek/mediatek,mutex.yaml |  6 ++
 16 files changed, 652 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 763c62323a74..9e59c8b738bb 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -31,6 +31,8 @@ properties:
               - mediatek,mt8183-mmsys
               - mediatek,mt8192-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vppsys0
+              - mediatek,mt8195-vppsys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml
new file mode 100644
index 000000000000..ba4590031f34
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 AAL Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components is responsible for backlight power saving
+  and sunlight visibility improving.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-aal0
+        - mediatek,mt8195-mdp3-aal1
+        - mediatek,mt8195-mdp3-aal2
+        - mediatek,mt8195-mdp3-aal3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_aal0: mdp_aal0 at 14005000 {
+      compatible = "mediatek,mt8195-mdp3-aal0";
+      reg = <0 0x14005000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x5000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_AAL>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml
new file mode 100644
index 000000000000..5c0d8e686909
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 COLOR Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to adjust hue, luma and saturation
+  to get better picture quality.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-color0
+        - mediatek,mt8195-mdp3-color1
+        - mediatek,mt8195-mdp3-color2
+        - mediatek,mt8195-mdp3-color3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_color0: mdp_color0 at 14008000 {
+      compatible = "mediatek,mt8195-mdp3-color0";
+      reg = <0 0x14008000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x8000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_COLOR>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
new file mode 100644
index 000000000000..d9cb1cb966e6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-fg.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 FG Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to add film grain according to AV1 spec.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-fg0
+        - mediatek,mt8195-mdp3-fg1
+        - mediatek,mt8195-mdp3-fg2
+        - mediatek,mt8195-mdp3-fg3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_fg0: mdp_fg0 at 14002000 {
+      compatible = "mediatek,mt8195-mdp3-fg0";
+      reg = <0 0x14002000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x2000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_FG>;
+    };
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
new file mode 100644
index 000000000000..fbb2af5f5b25
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-hdr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 HDR Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to perform HDR to SDR
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-hdr0
+        - mediatek,mt8195-mdp3-hdr1
+        - mediatek,mt8195-mdp3-hdr2
+        - mediatek,mt8195-mdp3-hdr3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_hdr0: mdp_hdr0 at 14004000
+      compatible = "mediatek,mt8195-mdp3-hdr0";
+      reg = <0 0x14004000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x4000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_HDR>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml
new file mode 100644
index 000000000000..4e37cb0abe46
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 MERGE Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to merge
+  two slice-per-line inputs into one side-by-side output.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-merge2
+        - mediatek,mt8195-mdp3-merge3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    svpp2_mdp3_merge: svpp2_mdp_merge at 14f1a000 {
+      compatible = "mediatek,mt8195-mdp3-merge2";
+      reg = <0 0x14f1a000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_14f1XXXX 0xa000 0x1000>;
+      clocks = <&vppsys1 CLK_VPP1_SVPP2_VPP_MERGE>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml
new file mode 100644
index 000000000000..6be6da6b159b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 OVL Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to perform alpha blending from the memory.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-ovl0
+        - mediatek,mt8195-mdp3-ovl1
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_ovl0: mdp_ovl0 at 14009000 {
+      compatible = "mediatek,mt8195-mdp3-ovl0";
+      reg = <0 0x14009000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x9000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_OVL>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml
new file mode 100644
index 000000000000..883963a4861f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-pad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 PADDING Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to insert
+  pre-defined color or alpha value to arbitrary side of image.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-pad0
+        - mediatek,mt8195-mdp3-pad1
+        - mediatek,mt8195-mdp3-pad2
+        - mediatek,mt8195-mdp3-pad3
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_pad0: mdp_pad0 at 1400a000 {
+      compatible = "mediatek,mt8195-mdp3-pad0";
+      reg = <0 0x1400a000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0xa000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_PADDING>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
index 002503383934..3b0779e8bfc2 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
@@ -26,6 +26,18 @@ properties:
           # MDP3 controller node
           - const: mediatek,mt8183-mdp3
           - const: mediatek,mt8183-mdp3-rdma0
+          # MDP3 controller node
+          - const: mediatek,mt8195-mdp3
+          - const: mediatek,mt8183-mdp3-rdma0
+          # MDP3 controller node
+          - const: mediatek,mt8195-mdp3
+          - const: mediatek,mt8195-mdp3-rdma1
+          # MDP3 controller node
+          - const: mediatek,mt8195-mdp3
+          - const: mediatek,mt8195-mdp3-rdma2
+          # MDP3 controller node
+          - const: mediatek,mt8195-mdp3
+          - const: mediatek,mt8195-mdp3-rdma3
       - items:
           # normal RDMA conponent
           - const: mediatek,mt8183-mdp3-rdma0
@@ -46,12 +58,28 @@ properties:
           - mediatek,mt8183-mdp3-dl1
       - enum:
           - mediatek,mt8183-mdp3-dl2
+      - enum:
+          - mediatek,mt8195-mdp3-dl1
+      - enum:
+          - mediatek,mt8195-mdp3-dl2
       - enum:
           # MDP direct-link output path selection, create a
           # component for path connectedness of HW pipe control
           - mediatek,mt8183-mdp3-path1
       - enum:
           - mediatek,mt8183-mdp3-path2
+      - enum:
+          - mediatek,mt8195-mdp3-path1
+      - enum:
+          - mediatek,mt8195-mdp3-path2
+      - enum:
+          - mediatek,mt8195-mdp3-path3
+      - enum:
+          - mediatek,mt8195-mdp3-path4
+      - enum:
+          - mediatek,mt8195-mdp3-path5
+      - enum:
+          - mediatek,mt8195-mdp3-path6
       - enum:
           # Input DMA of ISP PASS2 (DIP) module for raw image input
           - mediatek,mt8183-mdp3-imgi
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
index cd4cf1531535..714038c9bab9 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
@@ -18,6 +18,8 @@ properties:
       - enum:
           - mediatek,mt8183-mdp3-rsz0
           - mediatek,mt8183-mdp3-rsz1
+          - mediatek,mt8195-mdp3-rsz2
+          - mediatek,mt8195-mdp3-rsz3
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml
new file mode 100644
index 000000000000..f3eb9cc92fd9
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-solit.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 SPLIT Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to split hdmi rx into two stream
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-split
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    vpp_split0: vpp_split0 at 14f06000 {
+      compatible = "mediatek,mt8195-mdp3-split";
+      reg = <0 0x14f06000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_14f0XXXX 0x6000 0x1000>;
+      clocks = <&vppsys1 CLK_VPP1_VPP_SPLIT>,
+               <&vppsys1 CLK_VPP1_HDMI_META>,
+               <&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>,
+               <&vppsys1 CLK_VPP1_DGI_IN>,
+               <&vppsys1 CLK_VPP1_DGI_OUT>,
+               <&vppsys1 CLK_VPP1_VPP_SPLIT_DGI>,
+               <&vppsys1 CLK_VPP1_VPP_SPLIT_26M>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
new file mode 100644
index 000000000000..31cf3592c16f
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-stitch.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 STITCH Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to combine multiple video frame
+  with overlapping fields of view to produce a segmented panorame.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-stitch
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_stitch0: mdp_stich0 at 14003000 {
+      compatible = "mediatek,mt8195-mdp3-stitch";
+      reg = <0 0x14003000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x3000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_STITCH>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
new file mode 100644
index 000000000000..b5d6b0214fe0
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-tcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 TCC Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to support
+  HDR gamma curve conversion HDR displays.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-tcc0
+        - mediatek,mt8195-mdp3-tcc1
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_tcc0: mdp_tcc0 at 1400b000 {
+      compatible = "mediatek,mt8195-mdp3-tcc0";
+      reg = <0 0x1400b000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0xb000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_TCC>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
new file mode 100644
index 000000000000..d967abd5fb7d
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/mediatek,mdp3-tdshp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Media Data Path 3 TDSHP Device Tree Bindings
+
+maintainers:
+  - Matthias Brugger <matthias.bgg at gmail.com>
+
+description: |
+  One of Media Data Path 3 (MDP3) components used to improve image sharpness and contrast.
+
+properties:
+  compatible:
+    items:
+      - enum:
+        - mediatek,mt8195-mdp3-tdshp0
+        - mediatek,mt8195-mdp3-tdshp1
+        - mediatek,mt8195-mdp3-tdshp2
+        - mediatek,mt8195-mdp3-tdshp3
+
+  mediatek,mdp3-id:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    maxItems: 1
+    description: |
+      HW index to distinguish same functionality modules.
+
+  reg:
+    maxItems: 1
+
+  mediatek,gce-client-reg:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: |
+      sub-system id corresponding to the global command engine (GCE)
+      register address.
+      $ref: /schemas/mailbox/mtk-gce.txt
+
+  clocks:
+    minItems: 1
+
+required:
+  - compatible
+  - reg
+  - mediatek,gce-client-reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/gce/mt8195-gce.h>
+
+    mdp3_tdshp0: mdp_tdshp0 at 14007000 {
+      compatible = "mediatek,mt8195-mdp3-tdshp0";
+      reg = <0 0x14007000 0 0x1000>;
+      mediatek,gce-client-reg = <&gce0 SUBSYS_1400XXXX 0x7000 0x1000>;
+      clocks = <&vppsys0 CLK_VPP0_MDP_TDSHP>;
+    };
diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
index 7b0f9c4fffd7..d2e015bc09a2 100644
--- a/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
@@ -17,6 +17,9 @@ properties:
     items:
       - enum:
           - mediatek,mt8183-mdp3-wrot0
+          - mediatek,mt8195-mdp3-wrot1
+          - mediatek,mt8195-mdp3-wrot2
+          - mediatek,mt8195-mdp3-wrot3
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
index a7ba7ebb9c53..26d69e0320ab 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
@@ -31,6 +31,12 @@ properties:
           - const: mediatek,mt8183-disp-mutex
       - items:
           - const: mediatek,mt8192-disp-mutex
+      - items:
+          - const: mediatek,mt8192-disp-mutex
+      - items:
+          - const: mediatek,mt8195-vpp0-mutex
+      - items:
+          - const: mediatek,mt8195-vpp1-mutex
 
   reg:
     maxItems: 1
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:41 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:41 +0800
Subject: [PATCH v1 01/14] soc: mediatek: mmsys: expand MDP enum for chip
 independence architecture
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-2-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Expand mdp related enum for chip independence architecture

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
This patch is base on [1]
[1] soc: mediatek: mmsys: add support for ISP control
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220104091712.25670-3-moudy.ho at mediatek.com/
---
 include/linux/soc/mediatek/mtk-mmsys.h | 88 ++++++++++++++++++++------
 1 file changed, 70 insertions(+), 18 deletions(-)

diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index c0ba22ad7229..a772e53af9b5 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -79,33 +79,85 @@ enum mtk_mdp_comp_id {
 	/* MDP */
 	MDP_COMP_CAMIN,		/* 9 */
 	MDP_COMP_CAMIN2,	/* 10 */
-	MDP_COMP_RDMA0,		/* 11 */
-	MDP_COMP_AAL0,		/* 12 */
-	MDP_COMP_CCORR0,	/* 13 */
-	MDP_COMP_RSZ0,		/* 14 */
-	MDP_COMP_RSZ1,		/* 15 */
-	MDP_COMP_TDSHP0,	/* 16 */
-	MDP_COMP_COLOR0,	/* 17 */
-	MDP_COMP_PATH0_SOUT,	/* 18 */
-	MDP_COMP_PATH1_SOUT,	/* 19 */
-	MDP_COMP_WROT0,		/* 20 */
-	MDP_COMP_WDMA,		/* 21 */
-
-	/* Dummy Engine */
-	MDP_COMP_RDMA1,		/* 22 */
-	MDP_COMP_RSZ2,		/* 23 */
-	MDP_COMP_TDSHP1,	/* 24 */
-	MDP_COMP_WROT1,		/* 25 */
+	MDP_COMP_SPLIT,           /* 11 */
+	MDP_COMP_SPLIT2,          /* 12 */
+	MDP_COMP_RDMA0,           /* 13 */
+	MDP_COMP_RDMA1,           /* 14 */
+	MDP_COMP_RDMA2,           /* 15 */
+	MDP_COMP_RDMA3,           /* 16 */
+	MDP_COMP_STITCH,          /* 17 */
+	MDP_COMP_FG0,             /* 18 */
+	MDP_COMP_FG1,             /* 19 */
+	MDP_COMP_FG2,             /* 20 */
+	MDP_COMP_FG3,             /* 21 */
+	MDP_COMP_TO_SVPP2MOUT,    /* 22 */
+	MDP_COMP_TO_SVPP3MOUT,    /* 23 */
+	MDP_COMP_TO_WARP0MOUT,    /* 24 */
+	MDP_COMP_TO_WARP1MOUT,    /* 25 */
+	MDP_COMP_VPP0_SOUT,       /* 26 */
+	MDP_COMP_VPP1_SOUT,       /* 27 */
+	MDP_COMP_PQ0_SOUT,        /* 28 */
+	MDP_COMP_PQ1_SOUT,        /* 29 */
+	MDP_COMP_HDR0,            /* 30 */
+	MDP_COMP_HDR1,            /* 31 */
+	MDP_COMP_HDR2,            /* 32 */
+	MDP_COMP_HDR3,            /* 33 */
+	MDP_COMP_AAL0,            /* 34 */
+	MDP_COMP_AAL1,            /* 35 */
+	MDP_COMP_AAL2,            /* 36 */
+	MDP_COMP_AAL3,            /* 37 */
+	MDP_COMP_CCORR0,          /* 38 */
+	MDP_COMP_RSZ0,            /* 39 */
+	MDP_COMP_RSZ1,            /* 40 */
+	MDP_COMP_RSZ2,            /* 41 */
+	MDP_COMP_RSZ3,            /* 42 */
+	MDP_COMP_TDSHP0,          /* 43 */
+	MDP_COMP_TDSHP1,          /* 44 */
+	MDP_COMP_TDSHP2,          /* 45 */
+	MDP_COMP_TDSHP3,          /* 46 */
+	MDP_COMP_COLOR0,          /* 47 */
+	MDP_COMP_COLOR1,          /* 48 */
+	MDP_COMP_COLOR2,          /* 49 */
+	MDP_COMP_COLOR3,          /* 50 */
+	MDP_COMP_OVL0,            /* 51 */
+	MDP_COMP_OVL1,            /* 52 */
+	MDP_COMP_PAD0,            /* 53 */
+	MDP_COMP_PAD1,            /* 54 */
+	MDP_COMP_PAD2,            /* 55 */
+	MDP_COMP_PAD3,            /* 56 */
+	MDP_COMP_TCC0,            /* 57 */
+	MDP_COMP_TCC1,            /* 58 */
+	MDP_COMP_WROT0,           /* 59 */
+	MDP_COMP_WROT1,           /* 60 */
+	MDP_COMP_WROT2,           /* 61 */
+	MDP_COMP_WROT3,           /* 62 */
+	MDP_COMP_WDMA,            /* 63 */
+	MDP_COMP_MERGE2,          /* 64 */
+	MDP_COMP_MERGE3,          /* 65 */
+	MDP_COMP_PATH0_SOUT,      /* 66 */
+	MDP_COMP_PATH1_SOUT,      /* 67 */
+	MDP_COMP_VDO0DL0,         /* 68 */
+	MDP_COMP_VDO1DL0,         /* 69 */
+	MDP_COMP_VDO0DL1,         /* 70 */
+	MDP_COMP_VDO1DL1,         /* 71 */
 
 	MDP_MAX_COMP_COUNT	/* ALWAYS keep at the end */
 };
 
 enum mtk_mdp_pipe_id {
+	MDP_PIPE_NONE = -1,
 	MDP_PIPE_RDMA0,
 	MDP_PIPE_IMGI,
 	MDP_PIPE_WPEI,
 	MDP_PIPE_WPEI2,
-	MDP_PIPE_MAX
+	MDP_PIPE_RDMA1,
+	MDP_PIPE_RDMA2,
+	MDP_PIPE_RDMA3,
+	MDP_PIPE_SPLIT,
+	MDP_PIPE_SPLIT2,
+	MDP_PIPE_VPP0_SOUT,
+	MDP_PIPE_VPP1_SOUT,
+	MDP_PIPE_MAX,
 };
 
 enum mtk_isp_ctrl {
-- 
2.18.0



From tzungbi at google.com  Sun Jan 16 21:59:28 2022
From: tzungbi at google.com (Tzung-Bi Shih)
Date: Mon, 17 Jan 2022 13:59:28 +0800
Subject: [PATCH] ASoC: mediatek: fix unmet dependency on GPIOLIB for
 SND_SOC_DMIC
In-Reply-To: <20220117050324.68371-1-julianbraha@gmail.com>
References: <20220117050324.68371-1-julianbraha@gmail.com>
Message-ID: <YeUFwPHyAfe2ex+0@google.com>

On Mon, Jan 17, 2022 at 12:03:24AM -0500, Julian Braha wrote:
> This is because SND_SOC_MT8195_MT6359_RT1011_RT5682
> selects SND_SOC_DMIC without selecting or depending on
> GPIOLIB, depsite SND_SOC_DMIC depending on GPIOLIB.
> 
> This unmet dependency bug was detected by Kismet,
> a static analysis tool for Kconfig. Please advise
> if this is not the appropriate solution.
> 
> Signed-off-by: Julian Braha <julianbraha at gmail.com>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>


From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:40 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:40 +0800
Subject: [PATCH v1 00/14] Add mdp support for mt8195
Message-ID: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add a chip independence architecture to make
mt8195 mdp driver compatible with previous soc.

Add dual-pipe feature and memory reconfiguration
to increase mdp performance.

Add below patch to support MDP driver on MT8195
  [PATCH v1 1/14] soc: mediatek: mmsys: expand MDP enum for chip independence
    architecture
  [PATCH v1 2/14] soc: mediatek: mutex: expand parameter for mdp mutex function
  [PATCH v1 3/14] soc: mediatek: mmsys: support mt8195 vppsys0/1
  [PATCH v1 4/14] soc: mediatek: mutex: support mt8195 vppsys0/1
  [PATCH v1 5/14] media: platform: mtk-mdp3: add chip independence architecture
  [PATCH v1 6/14] media: platform: mtk-mdp3: Modify mtk-img-ipi.h for MT8195 SCP
  [PATCH v1 7/14] media: platform: mtk-mdp3: Add platform configuration for MT8195
  [PATCH v1 8/14] media: platform: mtk-mdp3: Add engine setting for MT8195
  [PATCH v1 9/14] media: platform: mtk-mdp3: Add support MT8195
  [PATCH v1 10/14] media: platform: mtk-mdp3: Add dual pipe feature support
  [PATCH v1 11/14] media: platform: mtk-mdp3: Revise frame change criteria
  [PATCH v1 12/14] media: platform: mtk-mdp3: Reconfigure shared memory
  [PATCH v1 13/14] arm64: dts: mt8195: add mdp3 node
  [PATCH v1 14/14] dt-bindings: media: mediatek: mdp3: add yaml for new modules added in
    mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |    2 +
 .../bindings/media/mediatek,mdp3-aal.yaml     |   56 +
 .../bindings/media/mediatek,mdp3-color.yaml   |   56 +
 .../bindings/media/mediatek,mdp3-fg.yaml      |   55 +
 .../bindings/media/mediatek,mdp3-hdr.yaml     |   55 +
 .../bindings/media/mediatek,mdp3-merge.yaml   |   54 +
 .../bindings/media/mediatek,mdp3-ovl.yaml     |   53 +
 .../bindings/media/mediatek,mdp3-pad.yaml     |   56 +
 .../bindings/media/mediatek,mdp3-rdma.yaml    |   28 +
 .../bindings/media/mediatek,mdp3-rsz.yaml     |    2 +
 .../bindings/media/mediatek,mdp3-split.yaml   |   58 +
 .../bindings/media/mediatek,mdp3-stitch.yaml  |   53 +
 .../bindings/media/mediatek,mdp3-tcc.yaml     |   54 +
 .../bindings/media/mediatek,mdp3-tdshp.yaml   |   61 +
 .../bindings/media/mediatek,mdp3-wrot.yaml    |    3 +
 .../bindings/soc/mediatek/mediatek,mutex.yaml |    6 +
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      |  633 +++++++
 drivers/media/platform/mtk-mdp3/mdp_reg_aal.h |   24 +
 .../media/platform/mtk-mdp3/mdp_reg_color.h   |   29 +
 drivers/media/platform/mtk-mdp3/mdp_reg_fg.h  |   23 +
 drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h |   31 +
 .../media/platform/mtk-mdp3/mdp_reg_merge.h   |   23 +
 drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h |   24 +
 drivers/media/platform/mtk-mdp3/mdp_reg_pad.h |   20 +
 .../media/platform/mtk-mdp3/mdp_reg_rdma.h    |   31 +
 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h |    2 +
 .../media/platform/mtk-mdp3/mdp_reg_tdshp.h   |  116 ++
 .../media/platform/mtk-mdp3/mdp_reg_wrot.h    |   18 +
 drivers/media/platform/mtk-mdp3/mt8183_mdp.h  |  411 +++++
 drivers/media/platform/mtk-mdp3/mt8195_mdp.h  |  683 ++++++++
 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h |  219 ++-
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   |  782 +++++++--
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.h   |    4 +
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 1453 +++++++++++++++--
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |   90 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  118 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |   42 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |   27 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  356 ++--
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  292 ++--
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    |  106 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |    9 +
 drivers/soc/mediatek/mt8195-mmsys.h           |   23 +
 drivers/soc/mediatek/mtk-mmsys.c              |   22 +
 drivers/soc/mediatek/mtk-mmsys.h              |    3 +
 drivers/soc/mediatek/mtk-mutex.c              |   79 +-
 include/linux/soc/mediatek/mtk-mmsys.h        |   92 +-
 include/linux/soc/mediatek/mtk-mutex.h        |    2 +-
 48 files changed, 5648 insertions(+), 791 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_aal.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_color.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_fg.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_merge.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_pad.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_tdshp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mt8183_mdp.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mt8195_mdp.h

-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:46 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:46 +0800
Subject: [PATCH v1 06/14] media: platform: mtk-mdp3: Modify mtk-img-ipi.h for
 MT8195 SCP
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-7-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

1. Modify struct member to 4 byte-alignment for MT8195 SCP limitation
2. Add new struct for hw engine adding in MT8195

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/media/platform/mtk-mdp3/mtk-img-ipi.h | 219 +++++++++++++++---
 1 file changed, 181 insertions(+), 38 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-img-ipi.h b/drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
index f8560dad87da..8dd0bcdee431 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-img-ipi.h
@@ -42,14 +42,14 @@ struct img_sw_addr {
 
 struct img_plane_format {
 	u32 size;
-	u16 stride;
+	u32 stride;
 } __packed;
 
 struct img_pix_format {
-	u16 width;
-	u16 height;
+	u32 width;
+	u32 height;
 	u32 colorformat; /* enum mdp_color */
-	u16 ycbcr_prof; /* enum mdp_ycbcr_profile */
+	u32 ycbcr_prof; /* enum mdp_ycbcr_profile */
 	struct img_plane_format plane_fmt[IMG_MAX_PLANES];
 } __packed;
 
@@ -63,10 +63,10 @@ struct img_image_buffer {
 #define IMG_SUBPIXEL_SHIFT	20
 
 struct img_crop {
-	s16 left;
-	s16 top;
-	u16 width;
-	u16 height;
+	s32 left;
+	s32 top;
+	u32 width;
+	u32 height;
 	u32 left_subpix;
 	u32 top_subpix;
 	u32 width_subpix;
@@ -78,27 +78,29 @@ struct img_crop {
 #define IMG_CTRL_FLAG_SHARPNESS	BIT(4)
 #define IMG_CTRL_FLAG_HDR	BIT(5)
 #define IMG_CTRL_FLAG_DRE	BIT(6)
+#define IMG_CTRL_FLAG_RSZ	BIT(7)
 
 struct img_input {
 	struct img_image_buffer buffer;
-	u16 flags; /* HDR, DRE, dither */
+	u32 flags; /* HDR, DRE, dither */
 } __packed;
 
 struct img_output {
 	struct img_image_buffer buffer;
 	struct img_crop crop;
-	s16 rotation;
-	u16 flags; /* H-flip, sharpness, dither */
+	s32 rotation;
+	u32 flags; /* H-flip, sharpness, dither */
+	u64 pqid;
 } __packed;
 
 struct img_ipi_frameparam {
 	u32 index;
 	u32 frame_no;
 	u64 timestamp;
-	u8 type; /* enum mdp_stream_type */
-	u8 state;
-	u8 num_inputs;
-	u8 num_outputs;
+	u32 type; /* enum mdp_stream_type */
+	u32 state;
+	u32 num_inputs;
+	u32 num_outputs;
 	u64 drv_data;
 	struct img_input inputs[IMG_MAX_HW_INPUTS];
 	struct img_output outputs[IMG_MAX_HW_OUTPUTS];
@@ -106,6 +108,7 @@ struct img_ipi_frameparam {
 	struct img_addr subfrm_data;
 	struct img_sw_addr config_data;
 	struct img_sw_addr self_data;
+	u32 frame_change;
 } __packed;
 
 struct img_sw_buffer {
@@ -114,51 +117,51 @@ struct img_sw_buffer {
 } __packed;
 
 struct img_ipi_param {
-	u8 usage;
+	u32 usage;
 	struct img_sw_buffer frm_param;
 } __packed;
 
 struct img_frameparam {
 	struct list_head list_entry;
 	struct img_ipi_frameparam frameparam;
-};
+} __packed;
 
 /* ISP-MDP generic output information */
 
 struct img_comp_frame {
-	u32 output_disable:1;
-	u32 bypass:1;
-	u16 in_width;
-	u16 in_height;
-	u16 out_width;
-	u16 out_height;
+	u32 output_disable;
+	u32 bypass;
+	u32 in_width;
+	u32 in_height;
+	u32 out_width;
+	u32 out_height;
 	struct img_crop crop;
-	u16 in_total_width;
-	u16 out_total_width;
+	u32 in_total_width;
+	u32 out_total_width;
 } __packed;
 
 struct img_region {
-	s16 left;
-	s16 right;
-	s16 top;
-	s16 bottom;
+	s32 left;
+	s32 right;
+	s32 top;
+	s32 bottom;
 } __packed;
 
 struct img_offset {
-	s16 left;
-	s16 top;
+	s32 left;
+	s32 top;
 	u32 left_subpix;
 	u32 top_subpix;
 } __packed;
 
 struct img_comp_subfrm {
-	u32 tile_disable:1;
+	u32 tile_disable;
 	struct img_region in;
 	struct img_region out;
 	struct img_offset luma;
 	struct img_offset chroma;
-	s16 out_vertical; /* Output vertical index */
-	s16 out_horizontal; /* Output horizontal index */
+	s32 out_vertical; /* Output vertical index */
+	s32 out_horizontal; /* Output horizontal index */
 } __packed;
 
 #define IMG_MAX_SUBFRAMES	14
@@ -169,10 +172,13 @@ struct mdp_rdma_subfrm {
 	u32 src;
 	u32 clip;
 	u32 clip_ofst;
+	u32 in_tile_xleft;
+	u32 in_tile_ytop;
 } __packed;
 
 struct mdp_rdma_data {
 	u32 src_ctrl;
+	u32 comp_ctrl;
 	u32 control;
 	u32 iova[IMG_MAX_PLANES];
 	u32 iova_end[IMG_MAX_PLANES];
@@ -182,13 +188,72 @@ struct mdp_rdma_data {
 	u32 ufo_dec_y;
 	u32 ufo_dec_c;
 	u32 transform;
+	u32 dmabuf_con0;
+	u32 ultra_th_high_con0;
+	u32 ultra_th_low_con0;
+	u32 dmabuf_con1;
+	u32 ultra_th_high_con1;
+	u32 ultra_th_low_con1;
+	u32 dmabuf_con2;
+	u32 ultra_th_high_con2;
+	u32 ultra_th_low_con2;
+	u32 dmabuf_con3;
 	struct mdp_rdma_subfrm subfrms[IMG_MAX_SUBFRAMES];
 } __packed;
 
+struct mdp_fg_subfrm {
+	u32 info_0;
+	u32 info_1;
+} __packed;
+
+struct mdp_fg_data {
+	u32 ctrl_0;
+	u32 ck_en;
+	struct mdp_fg_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_hdr_subfrm {
+	u32 win_size;
+	u32 src;
+	u32 clip_ofst0;
+	u32 clip_ofst1;
+	u32 hist_ctrl_0;
+	u32 hist_ctrl_1;
+	u32 hdr_top;
+	u32 hist_addr;
+} __packed;
+
+struct mdp_hdr_data {
+	u32 top;
+	u32 relay;
+	struct mdp_hdr_subfrm   subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_aal_subfrm {
+	u32 src;
+	u32 clip;
+	u32 clip_ofst;
+} __packed;
+
+struct mdp_aal_data {
+	u32 cfg_main;
+	u32 cfg;
+	struct mdp_aal_subfrm   subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
 struct mdp_rsz_subfrm {
 	u32 control2;
 	u32 src;
 	u32 clip;
+	u32 hdmirx_en;
+	u32 luma_h_int_ofst;
+	u32 luma_h_sub_ofst;
+	u32 luma_v_int_ofst;
+	u32 luma_v_sub_ofst;
+	u32 chroma_h_int_ofst;
+	u32 chroma_h_sub_ofst;
+	u32 rsz_switch;
+	u32 merge_cfg;
 } __packed;
 
 struct mdp_rsz_data {
@@ -196,9 +261,70 @@ struct mdp_rsz_data {
 	u32 coeff_step_y;
 	u32 control1;
 	u32 control2;
+	u32 etc_control;
+	u32 prz_enable;
+	u32 ibse_softclip;
+	u32 tap_adapt;
+	u32 ibse_gaincontrol1;
+	u32 ibse_gaincontrol2;
+	u32 ibse_ylevel_1;
+	u32 ibse_ylevel_2;
+	u32 ibse_ylevel_3;
+	u32 ibse_ylevel_4;
+	u32 ibse_ylevel_5;
 	struct mdp_rsz_subfrm subfrms[IMG_MAX_SUBFRAMES];
 } __packed;
 
+struct mdp_tdshp_subfrm {
+	u32 src;
+	u32 clip;
+	u32 clip_ofst;
+	u32 hist_cfg_0;
+	u32 hist_cfg_1;
+} __packed;
+
+struct mdp_tdshp_data {
+	u32 cfg;
+	struct mdp_tdshp_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_color_subfrm {
+	u32 in_hsize;
+	u32 in_vsize;
+} __packed;
+
+struct mdp_color_data {
+	u32 start;
+	struct mdp_color_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_ovl_subfrm {
+	u32 L0_src_size;
+	u32 roi_size;
+} __packed;
+
+struct mdp_ovl_data {
+	u32 L0_con;
+	u32 src_con;
+	struct mdp_ovl_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_pad_subfrm {
+	u32 pic_size;
+} __packed;
+
+struct mdp_pad_data {
+	struct mdp_pad_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
+struct mdp_tcc_subfrm {
+	u32 pic_size;
+} __packed;
+
+struct mdp_tcc_data {
+	struct mdp_tcc_subfrm subfrms[IMG_MAX_SUBFRAMES];
+} __packed;
+
 struct mdp_wrot_subfrm {
 	u32 offset[IMG_MAX_PLANES];
 	u32 src;
@@ -214,6 +340,14 @@ struct mdp_wrot_data {
 	u32 mat_ctrl;
 	u32 fifo_test;
 	u32 filter;
+	u32 pre_ultra;
+	u32 framesize;
+	u32 afbc_yuvtrans;
+	u32 scan_10bit;
+	u32 pending_zero;
+	u32 bit_number;
+	u32 pvric;
+	u32 vpp02vpp1;
 	struct mdp_wrot_subfrm subfrms[IMG_MAX_SUBFRAMES];
 } __packed;
 
@@ -241,8 +375,8 @@ struct isp_data {
 } __packed;
 
 struct img_compparam {
-	u16 type; /* enum mdp_comp_type */
-	u16 id; /* enum mtk_mdp_comp_id */
+	u32 type; /* enum mdp_comp_id */
+	u32 id; /* engine alias_id */
 	u32 input;
 	u32 outputs[IMG_MAX_HW_OUTPUTS];
 	u32 num_outputs;
@@ -251,7 +385,15 @@ struct img_compparam {
 	u32 num_subfrms;
 	union {
 		struct mdp_rdma_data rdma;
+		struct mdp_fg_data fg;
+		struct mdp_hdr_data hdr;
+		struct mdp_aal_data aal;
 		struct mdp_rsz_data rsz;
+		struct mdp_tdshp_data tdshp;
+		struct mdp_color_data color;
+		struct mdp_ovl_data ovl;
+		struct mdp_pad_data pad;
+		struct mdp_tcc_data tcc;
 		struct mdp_wrot_data wrot;
 		struct mdp_wdma_data wdma;
 		struct isp_data isp;
@@ -263,12 +405,13 @@ struct img_compparam {
 struct img_mux {
 	u32 reg;
 	u32 value;
-};
+	u32 vpp_id;
+} __packed;
 
 struct img_mmsys_ctrl {
 	struct img_mux sets[IMG_MAX_COMPONENTS * 2];
 	u32 num_sets;
-};
+} __packed;
 
 struct img_config {
 	struct img_compparam components[IMG_MAX_COMPONENTS];
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:42 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:42 +0800
Subject: [PATCH v1 02/14] soc: mediatek: mutex: expand parameter for mdp mutex
 function
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-3-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Expand parameter for mdp mutex function

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
This patch is base on [1][2]
[1] soc: mediatek: mutex: add functions that operate registers by CMDQ
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220104091712.25670-5-moudy.ho at mediatek.com/
[2] media: platform: mtk-mdp3: add Mediatek MDP3 driver
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220105093758.6850-4-moudy.ho at mediatek.com/
---
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   |  3 ++-
 drivers/soc/mediatek/mtk-mutex.c              | 26 +++++++++++++------
 include/linux/soc/mediatek/mtk-mutex.h        |  2 +-
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
index 4a08502952d6..87751f0e2513 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
@@ -101,7 +101,8 @@ static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
 	}
 
 	if (subfrm->mutex_mod)
-		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id], subfrm->mutex_mod, cmd);
+		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id], subfrm->mutex_mod,
+					  0, 0, cmd);
 
 	/* Set SOF */
 	for (index = 0; index < config->num_components; index++) {
diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 89daab7e6863..7da0f44b6f9a 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -27,8 +27,9 @@
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
-#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n)	(mutex_mod_reg + 0x20 * (n))
-#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n)	(mutex_sof_reg + 0x20 * (n))
+#define DISP_REG_MUTEX_MOD(mutex_mod_reg, n)	((mutex_mod_reg) + 0x20 * (n))
+#define DISP_REG_MUTEX_MOD1(mutex_mod_reg, n)	((mutex_mod_reg) + 0x20 * (n) + 0x4)
+#define DISP_REG_MUTEX_SOF(mutex_sof_reg, n)	((mutex_sof_reg) + 0x20 * (n))
 #define DISP_REG_MUTEX_MOD2(n)			(0x34 + 0x20 * (n))
 
 #define INT_MUTEX				BIT(1)
@@ -180,6 +181,11 @@
 #define MT8183_MUTEX_MOD_MDP_AAL0		BIT(23)
 #define MT8183_MUTEX_MOD_MDP_CCORR0		BIT(24)
 
+#define MT8183_MDP_PIPE_IMGI                   MT8183_MUTEX_MDP_START
+#define MT8183_MDP_PIPE_RDMA0                  (MT8183_MUTEX_MDP_START + 1)
+#define MT8183_MDP_PIPE_WPEI                   (MT8183_MUTEX_MDP_START + 2)
+#define MT8183_MDP_PIPE_WPEI2                  (MT8183_MUTEX_MDP_START + 3)
+
 struct mtk_mutex {
 	int id;
 	bool claimed;
@@ -364,10 +370,10 @@ static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 
 /* indicate which mutex is used by each pipepline */
 static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
-	[MDP_PIPE_IMGI] = MT8183_MUTEX_MDP_START,
-	[MDP_PIPE_RDMA0] = MT8183_MUTEX_MDP_START + 1,
-	[MDP_PIPE_WPEI] = MT8183_MUTEX_MDP_START + 2,
-	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
+	[MDP_PIPE_IMGI] = MT8183_MDP_PIPE_IMGI,
+	[MDP_PIPE_RDMA0] = MT8183_MDP_PIPE_RDMA0,
+	[MDP_PIPE_WPEI] = MT8183_MDP_PIPE_WPEI,
+	[MDP_PIPE_WPEI2] = MT8183_MDP_PIPE_WPEI2,
 };
 
 static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
@@ -606,7 +612,7 @@ u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id)
 EXPORT_SYMBOL_GPL(mtk_mutex_get_mdp_mod);
 
 void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod,
-			       struct mmsys_cmdq_cmd *cmd)
+			       u32 mod1, u32 sof, struct mmsys_cmdq_cmd *cmd)
 {
 	struct mtk_mutex_ctx *mtx = container_of(mutex, struct mtk_mutex_ctx,
 						 mutex[mutex->id]);
@@ -618,9 +624,13 @@ void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod,
 	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset,
 			    mod, mtx->data->mutex_mdp_mod_mask);
 
+	offset = DISP_REG_MUTEX_MOD1(mtx->data->mutex_mod_reg, mutex->id);
+	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset,
+			    mod1, mtx->data->mutex_mdp_mod_mask);
+
 	offset = DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg, mutex->id);
 	cmdq_pkt_write_mask(cmd->pkt, mtx->cmdq_reg.subsys, mtx->addr + offset,
-			    0, mtx->data->mutex_mdp_sof_mask);
+			    sof, mtx->data->mutex_mdp_sof_mask);
 }
 EXPORT_SYMBOL_GPL(mtk_mutex_add_mod_by_cmdq);
 
diff --git a/include/linux/soc/mediatek/mtk-mutex.h b/include/linux/soc/mediatek/mtk-mutex.h
index 05de7ad4a124..dbb7324c12d9 100644
--- a/include/linux/soc/mediatek/mtk-mutex.h
+++ b/include/linux/soc/mediatek/mtk-mutex.h
@@ -18,7 +18,7 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 			enum mtk_ddp_comp_id id);
 u32 mtk_mutex_get_mdp_mod(struct mtk_mutex *mutex, enum mtk_mdp_comp_id id);
 void mtk_mutex_add_mod_by_cmdq(struct mtk_mutex *mutex, u32 mod,
-			       struct mmsys_cmdq_cmd *cmd);
+			       u32 mod1, u32 sof, struct mmsys_cmdq_cmd *cmd);
 void mtk_mutex_enable(struct mtk_mutex *mutex);
 void mtk_mutex_enable_by_cmdq(struct mtk_mutex *mutex,
 			      struct mmsys_cmdq_cmd *cmd);
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:43 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:43 +0800
Subject: [PATCH v1 03/14] soc: mediatek: mmsys: support mt8195 vppsys0/1
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-4-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add mt8195 vppsys driver data
Add interface for mdp to set config table

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 23 +++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       | 22 ++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.h       |  3 +++
 include/linux/soc/mediatek/mtk-mmsys.h |  4 ++++
 4 files changed, 52 insertions(+)

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
index e04cabdfa2dc..460d55e3ef86 100644
--- a/drivers/soc/mediatek/mt8195-mmsys.h
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -165,6 +165,18 @@
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		BIT(17)
 #define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(BIT(17) | BIT(16))
 
+/* VPPSYS0 */
+#define VPPSYS0_HW_DCM_1ST_DIS0					0x050
+
+/* VPPSYS1 */
+#define VPPSYS1_HW_DCM_1ST_DIS0					0x150
+#define VPPSYS1_HW_DCM_1ST_DIS1					0x160
+#define VPPSYS1_HW_DCM_2ND_DIS0					0x1a0
+#define VPPSYS1_HW_DCM_2ND_DIS1					0x1b0
+#define VPP0_DL_IRELAY_WR					0x920
+#define SVPP2_BUF_BF_RSZ_SWITCH					0xf48
+#define SVPP3_BUF_BF_RSZ_SWITCH					0xf74
+
 static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	{
 		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
@@ -217,4 +229,15 @@ static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
 	}
 };
 
+static const u32 mmsys_mt8195_mdp_vppsys_config_table[] = {
+	VPPSYS0_HW_DCM_1ST_DIS0,
+	VPP0_DL_IRELAY_WR,
+	VPPSYS1_HW_DCM_1ST_DIS0,
+	VPPSYS1_HW_DCM_1ST_DIS1,
+	VPPSYS1_HW_DCM_2ND_DIS0,
+	VPPSYS1_HW_DCM_2ND_DIS1,
+	SVPP2_BUF_BF_RSZ_SWITCH,
+	SVPP3_BUF_BF_RSZ_SWITCH,
+};
+
 #endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index a6ae10946eb6..c7beaa61ad64 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -79,10 +79,16 @@ static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
 
 static const struct mtk_mmsys_driver_data mt8195_vppsys0_driver_data = {
 	.clk_driver = "clk-mt8195-vpp0",
+	.mdp_mmsys_configs = mmsys_mt8195_mdp_vppsys_config_table,
+	.mdp_num_mmsys_configs = ARRAY_SIZE(mmsys_mt8195_mdp_vppsys_config_table),
+	.vppsys = true,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vppsys1_driver_data = {
 	.clk_driver = "clk-mt8195-vpp1",
+	.mdp_mmsys_configs = mmsys_mt8195_mdp_vppsys_config_table,
+	.mdp_num_mmsys_configs = ARRAY_SIZE(mmsys_mt8195_mdp_vppsys_config_table),
+	.vppsys = true,
 };
 
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
@@ -137,6 +143,18 @@ void mtk_mmsys_ddp_disconnect(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
 
+void mtk_mmsys_mdp_write_config(struct device *dev,
+				struct mmsys_cmdq_cmd *cmd,
+				u32 alias_id, u32 value, u32 mask)
+{
+	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
+	const u32 *configs = mmsys->data->mdp_mmsys_configs;
+
+	cmdq_pkt_write_mask(cmd->pkt, mmsys->cmdq_base.subsys,
+			    mmsys->addr + configs[alias_id], value, mask);
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_mdp_write_config);
+
 void mtk_mmsys_write_reg_by_cmdq(struct device *dev,
 				 struct mmsys_cmdq_cmd *cmd,
 				 u32 offset, u32 value, u32 mask)
@@ -367,6 +385,9 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 	if (IS_ERR(clks))
 		return PTR_ERR(clks);
 
+	if (mmsys->data->vppsys)
+		goto EXIT;
+
 	drm = platform_device_register_data(&pdev->dev, "mediatek-drm",
 					    PLATFORM_DEVID_AUTO, NULL, 0);
 	if (IS_ERR(drm)) {
@@ -374,6 +395,7 @@ static int mtk_mmsys_probe(struct platform_device *pdev)
 		return PTR_ERR(drm);
 	}
 
+EXIT:
 	return 0;
 }
 
diff --git a/drivers/soc/mediatek/mtk-mmsys.h b/drivers/soc/mediatek/mtk-mmsys.h
index ad8b92389b54..909713a28c14 100644
--- a/drivers/soc/mediatek/mtk-mmsys.h
+++ b/drivers/soc/mediatek/mtk-mmsys.h
@@ -94,6 +94,9 @@ struct mtk_mmsys_driver_data {
 	const unsigned int num_routes;
 	bool has_gce_client_reg;
 	const unsigned int *mdp_isp_ctrl;
+	const u32 *mdp_mmsys_configs;
+	const unsigned int mdp_num_mmsys_configs;
+	bool vppsys;
 };
 
 /*
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index a772e53af9b5..946d161c8937 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -194,4 +194,8 @@ void mtk_mmsys_mdp_camin_ctrl(struct device *dev, struct mmsys_cmdq_cmd *cmd,
 			      enum mtk_mdp_comp_id id,
 			      u32 camin_w, u32 camin_h);
 
+void mtk_mmsys_mdp_write_config(struct device *dev,
+				struct mmsys_cmdq_cmd *cmd,
+				u32 alias_id, u32 value, u32 mask);
+
 #endif /* __MTK_MMSYS_H */
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:52 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:52 +0800
Subject: [PATCH v1 12/14] media: platform: mtk-mdp3: Reconfigure shared memory
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-13-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

MDP communicates with SCP through shared memory.
SCP is responsible for calculating information that MDP needed,
however SCP has poor performance.

In order to improve performance,
shared memory is reconfigured into three buffer
to make more logical sense.

The third buffer - path buffer
which allocated in scp before is used for scp calculation.
This buffer need to be clear when frame_change occurs,
but it costs lot of time for scp doing memset which decreases performance.

Thus we move this buffer to kernel,
do memset in ap side to accelerate frame processing.

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    | 106 +++++++++---------
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |   8 ++
 2 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
index 035fa3e55335..73da786b5270 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
@@ -10,7 +10,7 @@
 #include "mtk-mdp3-core.h"
 
 #define MDP_VPU_MESSAGE_TIMEOUT 500U
-#define vpu_alloc_size         0x7F8000
+#define MDP_VPU_PATH_SIZE	0x78000
 
 static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
 {
@@ -19,23 +19,46 @@ static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
 
 static int mdp_vpu_shared_mem_alloc(struct mdp_vpu_dev *vpu)
 {
-	if (vpu->work && vpu->work_addr)
-		return 0;
+	vpu->work = dma_alloc_wc(scp_get_device(vpu->scp), vpu->work_size,
+				 &vpu->work_addr, GFP_KERNEL);
+	if (!vpu->work)
+		goto err_return;
 
-	vpu->work = dma_alloc_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
-				       &vpu->work_addr, GFP_KERNEL);
+	vpu->config = dma_alloc_wc(scp_get_device(vpu->scp), vpu->config_size,
+				   &vpu->config_addr, GFP_KERNEL);
+	if (!vpu->config)
+		goto err_free_work;
 
-	if (!vpu->work)
-		return -ENOMEM;
-	else
-		return 0;
+	vpu->path = dma_alloc_wc(scp_get_device(vpu->scp), vpu->path_size,
+				 &vpu->path_addr, GFP_KERNEL);
+	if (!vpu->path)
+		goto err_free_config;
+
+	return 0;
+
+err_free_config:
+	dma_free_wc(scp_get_device(vpu->scp), vpu->config_size,
+		    vpu->config, vpu->config_addr);
+err_free_work:
+	dma_free_wc(scp_get_device(vpu->scp), vpu->work_size,
+		    vpu->work, vpu->work_addr);
+err_return:
+	return -ENOMEM;
 }
 
 void mdp_vpu_shared_mem_free(struct mdp_vpu_dev *vpu)
 {
 	if (vpu->work && vpu->work_addr)
-		dma_free_coherent(scp_get_device(vpu->scp), vpu_alloc_size,
-				  vpu->work, vpu->work_addr);
+		dma_free_wc(scp_get_device(vpu->scp), vpu->work_size,
+			    vpu->work, vpu->work_addr);
+
+	if (vpu->config && vpu->config_addr)
+		dma_free_wc(scp_get_device(vpu->scp), vpu->config_size,
+			    vpu->config, vpu->config_addr);
+
+	if (vpu->path && vpu->path_addr)
+		dma_free_wc(scp_get_device(vpu->scp), vpu->path_size,
+			    vpu->path, vpu->path_addr);
 }
 
 static void mdp_vpu_ipi_handle_init_ack(void *data, unsigned int len,
@@ -156,9 +179,6 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
 	struct mdp_ipi_init_msg msg = {
 		.drv_data = (unsigned long)vpu,
 	};
-	size_t mem_size;
-	phys_addr_t pool;
-	const size_t pool_size = sizeof(struct mdp_config_pool);
 	struct mdp_dev *mdp = vpu_to_mdp(vpu);
 	int err;
 
@@ -171,33 +191,20 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
 		goto err_work_size;
 	/* vpu work_size was set in mdp_vpu_ipi_handle_init_ack */
 
-	mem_size = vpu_alloc_size;
-	if (mdp_vpu_shared_mem_alloc(vpu)) {
+	vpu->config_size = MDP_DUAL_PIPE * sizeof(struct img_config);
+	vpu->path_size = MDP_VPU_PATH_SIZE;
+	err = mdp_vpu_shared_mem_alloc(vpu);
+	if (err) {
 		dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
 		goto err_mem_alloc;
 	}
 
-	pool = ALIGN((uintptr_t)vpu->work + vpu->work_size, 8);
-	if (pool + pool_size - (uintptr_t)vpu->work > mem_size) {
-		dev_err(&mdp->pdev->dev,
-			"VPU memory insufficient: %zx + %zx > %zx",
-			vpu->work_size, pool_size, mem_size);
-		err = -ENOMEM;
-		goto err_mem_size;
-	}
-
-	dev_dbg(&mdp->pdev->dev,
-		"VPU work:%pK pa:%pad sz:%zx pool:%pa sz:%zx (mem sz:%zx)",
-		vpu->work, &vpu->work_addr, vpu->work_size,
-		&pool, pool_size, mem_size);
-	vpu->pool = (struct mdp_config_pool *)(uintptr_t)pool;
 	msg.work_addr = vpu->work_addr;
 	msg.work_size = vpu->work_size;
 	err = mdp_vpu_sendmsg(vpu, SCP_IPI_MDP_INIT, &msg, sizeof(msg));
 	if (err)
 		goto err_work_size;
 
-	memset(vpu->pool, 0, sizeof(*vpu->pool));
 	return 0;
 
 err_work_size:
@@ -210,7 +217,6 @@ int mdp_vpu_dev_init(struct mdp_vpu_dev *vpu, struct mtk_scp *scp,
 		break;
 	}
 	return err;
-err_mem_size:
 err_mem_alloc:
 	return err;
 }
@@ -233,11 +239,8 @@ static struct img_config *mdp_config_get(struct mdp_vpu_dev *vpu,
 	if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
 		return ERR_PTR(-EINVAL);
 
-	mutex_lock(vpu->lock);
-	vpu->pool->cfg_count[id]++;
-	config = &vpu->pool->configs[id];
-	*addr = vpu->work_addr + ((uintptr_t)config - (uintptr_t)vpu->work);
-	mutex_unlock(vpu->lock);
+	config = vpu->config;
+	*addr = vpu->config_addr;
 
 	return config;
 }
@@ -250,14 +253,7 @@ static int mdp_config_put(struct mdp_vpu_dev *vpu,
 
 	if (id < 0 || id >= MDP_CONFIG_POOL_SIZE)
 		return -EINVAL;
-	if (vpu->lock)
-		mutex_lock(vpu->lock);
-	if (!vpu->pool->cfg_count[id] || config != &vpu->pool->configs[id])
-		err = -EINVAL;
-	else
-		vpu->pool->cfg_count[id]--;
-	if (vpu->lock)
-		mutex_unlock(vpu->lock);
+
 	return err;
 }
 
@@ -288,25 +284,23 @@ int mdp_vpu_ctx_deinit(struct mdp_vpu_ctx *ctx)
 
 int mdp_vpu_process(struct mdp_vpu_ctx *ctx, struct img_ipi_frameparam *param)
 {
-	struct mdp_vpu_dev *vpu = ctx->vpu_dev;
-	struct mdp_dev *mdp = vpu_to_mdp(vpu);
 	struct img_sw_addr addr;
 
-	if (!ctx->vpu_dev->work || !ctx->vpu_dev->work_addr) {
-		if (mdp_vpu_shared_mem_alloc(vpu)) {
-			dev_err(&mdp->pdev->dev, "VPU memory alloc fail!");
-			return -ENOMEM;
-		}
-	}
 	memset((void *)ctx->vpu_dev->work, 0, ctx->vpu_dev->work_size);
-	memset(ctx->config, 0, sizeof(*ctx->config));
-	param->config_data.va = (unsigned long)ctx->config;
+
+	if (param->frame_change)
+		memset((void *)ctx->vpu_dev->path, 0, ctx->vpu_dev->path_size);
+	param->self_data.pa = ctx->vpu_dev->path_addr;
+	param->self_data.va = (u64)ctx->vpu_dev->path;
+
+	memset(ctx->config, 0, ctx->vpu_dev->config_size);
+	param->config_data.va = (u64)ctx->config;
 	param->config_data.pa = ctx->inst_addr;
 	param->drv_data = (unsigned long)ctx;
 
 	memcpy((void *)ctx->vpu_dev->work, param, sizeof(*param));
 	addr.pa = ctx->vpu_dev->work_addr;
-	addr.va = (uintptr_t)ctx->vpu_dev->work;
+	addr.va = (u64)ctx->vpu_dev->work;
 	return mdp_vpu_sendmsg(ctx->vpu_dev, SCP_IPI_MDP_FRAME,
 		&addr, sizeof(addr));
 }
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
index 3140d2925a1a..597589c73266 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
@@ -58,6 +58,14 @@ struct mdp_vpu_dev {
 	size_t			work_size;
 	struct mdp_config_pool	*pool;
 	u32			status;
+
+	void			*config;
+	dma_addr_t		config_addr;
+	size_t			config_size;
+
+	void			*path;
+	dma_addr_t		path_addr;
+	size_t			path_size;
 };
 
 struct mdp_vpu_ctx {
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:50 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:50 +0800
Subject: [PATCH v1 10/14] media: platform: mtk-mdp3: Add dual pipe feature
 support
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-11-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add dual pipe feature which uses two svpp to execute dma

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/media/platform/mtk-mdp3/mt8195_mdp.h  |   1 +
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   | 245 +++++++++++-------
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.h   |   4 +
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  21 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |  11 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |   5 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  18 ++
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |   4 +
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.c    |   2 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-vpu.h    |   1 +
 10 files changed, 214 insertions(+), 98 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mt8195_mdp.h b/drivers/media/platform/mtk-mdp3/mt8195_mdp.h
index f69bc86bcd1e..dc9454cfd33a 100644
--- a/drivers/media/platform/mtk-mdp3/mt8195_mdp.h
+++ b/drivers/media/platform/mtk-mdp3/mt8195_mdp.h
@@ -24,6 +24,7 @@ static const struct mdp_platform_config mt8195_plat_cfg = {
 	.mdp_version_6885               = true,
 	.gce_event_offset               = 0,
 	.support_multi_larb		= true,
+	.support_dual_pipe              = true,
 };
 
 enum mt8195_mdp_comp_id {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
index ce9326cc790f..86b7d83be22c 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
@@ -29,6 +29,9 @@ struct mdp_path {
 	((ctx)->comp->ops && (ctx)->comp->ops->op)
 #define call_op(ctx, op, ...) \
 	(has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)
+#define get_pipe_num(scenario) \
+	((scenario) == MDP_STREAM_TYPE_DUAL_BITBLT ? 2 : 1)
+
 struct mdp_path_subfrm {
 	s32	mutex_id;
 	u32	mutex_mod;
@@ -707,25 +710,31 @@ static void mdp_auto_release_work(struct work_struct *work)
 	struct mdp_cmdq_cb_param *cb_param;
 	struct mdp_dev *mdp;
 	int i;
+	bool finalize;
 
 	cb_param = container_of(work, struct mdp_cmdq_cb_param,
 				auto_release_work);
 	mdp = cb_param->mdp;
+	finalize = cb_param->finalize;
 
-	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
-	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
+	if (finalize) {
+		i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+		mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 
-	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
-	if (i >= 0)
-		mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
+		i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
+		if (i >= 0)
+			mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
+	}
 	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 			    cb_param->num_comps);
 
 	kfree(cb_param->comps);
 	kfree(cb_param);
 
-	atomic_dec(&mdp->job_count);
-	wake_up(&mdp->callback_wq);
+	if (finalize) {
+		atomic_dec(&mdp->job_count);
+		wake_up(&mdp->callback_wq);
+	}
 }
 
 static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
@@ -744,7 +753,13 @@ static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
 	mdp = cb_param->mdp;
 	dev = &mdp->pdev->dev;
 
-	if (cb_param->mdp_ctx)
+	if (cb_param->dualpipe)
+		cb_param->finalize =
+			(atomic_dec_and_test(&mdp->cmdq_count[cb_param->cmdq_user]));
+	else
+		cb_param->finalize = true;
+
+	if (cb_param->finalize && cb_param->mdp_ctx)
 		mdp_m2m_job_finish(cb_param->mdp_ctx);
 
 	if (cb_param->user_cmdq_cb) {
@@ -779,52 +794,62 @@ static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
 
 int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 {
-	struct mmsys_cmdq_cmd cmd;
-	struct mdp_path *path = NULL;
-	struct mdp_cmdq_cb_param *cb_param = NULL;
-	struct mdp_comp *comps = NULL;
+	struct mmsys_cmdq_cmd cmd[MDP_DUAL_PIPE];
+	struct mdp_path *paths[MDP_DUAL_PIPE] = {NULL};
+	struct mdp_cmdq_cb_param *cb_param[MDP_DUAL_PIPE] = {NULL};
+	struct mdp_comp *comps[MDP_DUAL_PIPE] = {NULL};
 	struct device *dev = &mdp->pdev->dev;
-	int i, ret;
+
+	enum mdp_stream_type scenario = param->param->type;
+	int i, j, ret;
 
 	if (atomic_read(&mdp->suspended))
 		return -ECANCELED;
 
 	atomic_inc(&mdp->job_count);
 
-	cmd.pkt = cmdq_pkt_create(mdp->cmdq_clt, SZ_16K);
-	if (IS_ERR(cmd.pkt)) {
-		atomic_dec(&mdp->job_count);
-		wake_up(&mdp->callback_wq);
-		return PTR_ERR(cmd.pkt);
+	/* Prepare cmdq pkt */
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		cmd[i].pkt = cmdq_pkt_create(mdp->cmdq_clt[i], SZ_16K);
+		if (IS_ERR(cmd[i].pkt)) {
+			ret = PTR_ERR(cmd[i].pkt);
+			dev_err(dev, "%s path %d cmdq_pkt_create error\n", __func__, i);
+			goto err_destroy_pkt;
+		}
+		cmd[i].event = &mdp->event[0];
 	}
-	cmd.event = &mdp->event[0];
 
-	path = kzalloc(sizeof(*path), GFP_KERNEL);
-	if (!path) {
-		ret = -ENOMEM;
-		goto err_destroy_pkt;
-	}
+	/* Prepare path info */
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		paths[i] = kzalloc(sizeof(*paths[i]), GFP_KERNEL);
+		if (!paths[i]) {
+			ret = -ENOMEM;
+			dev_err(dev, "%s alloc paths error\n", __func__);
+			goto err_destroy_paths;
+		}
 
-	path->mdp_dev = mdp;
-	path->config = param->config;
-	path->param = param->param;
-	for (i = 0; i < param->param->num_outputs; i++) {
-		path->bounds[i].left = 0;
-		path->bounds[i].top = 0;
-		path->bounds[i].width =
-			param->param->outputs[i].buffer.format.width;
-		path->bounds[i].height =
-			param->param->outputs[i].buffer.format.height;
-		path->composes[i] = param->composes[i] ?
-			param->composes[i] : &path->bounds[i];
-	}
+		paths[i]->mdp_dev = mdp;
+		paths[i]->config = &param->config[i];
+		paths[i]->param = param->param;
+		for (j = 0; j < param->param->num_outputs; j++) {
+			paths[i]->bounds[j].left = 0;
+			paths[i]->bounds[j].top = 0;
+			paths[i]->bounds[j].width =
+				param->param->outputs[j].buffer.format.width;
+			paths[i]->bounds[j].height =
+				param->param->outputs[j].buffer.format.height;
+			paths[i]->composes[j] = param->composes[j] ?
+				param->composes[j] : &paths[i]->bounds[j];
+		}
 
-	ret = mdp_path_ctx_init(mdp, path);
-	if (ret) {
-		dev_err(dev, "mdp_path_ctx_init error\n");
-		goto err_destroy_pkt;
+		ret = mdp_path_ctx_init(mdp, paths[i]);
+		if (ret) {
+			dev_err(dev, "%s mdp_path_ctx_init error at path %d\n", __func__, i);
+			goto err_destroy_paths;
+		}
 	}
 
+	/* Setup clock and cmdq buffer */
 	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 	mtk_mutex_prepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 
@@ -832,64 +857,94 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 	if (i >= 0)
 		mtk_mutex_prepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
 
-	for (i = 0; i < param->config->num_components; i++) {
-		if (is_dummy_engine(mdp, path->config->components[i].type))
-			continue;
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		for (j = 0; j < param->config[i].num_components; j++) {
+			if (is_dummy_engine(mdp, paths[i]->config->components[j].type))
+				continue;
 
-		mdp_comp_clock_on(&mdp->pdev->dev, path->comps[i].comp);
+			mdp_comp_clock_on(&mdp->pdev->dev, paths[i]->comps[j].comp);
+		}
 	}
 
 	if (mdp->mdp_data->mdp_cfg->mdp_version_8195) {
-		ret = mdp_hyfbc_config(mdp, &cmd, path, param);
-		if (ret)
-			goto err_destroy_pkt;
+		ret = mdp_hyfbc_config(mdp, &cmd[0], paths[0], param);
+		if (ret) {
+			dev_err(dev, "%s mdp_hyfbc_config error\n", __func__);
+			goto err_clock_off;
+		}
 	}
 
-	ret = mdp_path_config(mdp, &cmd, path);
-	if (ret) {
-		dev_err(dev, "mdp_path_config error\n");
-		goto err_destroy_pkt;
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		ret = mdp_path_config(mdp, &cmd[i], paths[i]);
+		if (ret) {
+			dev_err(dev, "path %d mdp_path_config error\n", i);
+			goto err_clock_off;
+		}
 	}
 
-	cb_param = kzalloc(sizeof(*cb_param), GFP_KERNEL);
-	if (!cb_param) {
-		ret = -ENOMEM;
-		goto err_destroy_pkt;
-	}
+	/* Prepare cmdq callback info */
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		cb_param[i] = kzalloc(sizeof(*cb_param[i]), GFP_KERNEL);
+		if (!cb_param[i]) {
+			ret = -ENOMEM;
+			dev_err(dev, "%s path %d alloc cb_param error\n", __func__, i);
+			goto err_destroy_cb_param;
+		}
 
-	comps = kcalloc(param->config->num_components, sizeof(*comps),
-			GFP_KERNEL);
-	if (!comps) {
-		ret = -ENOMEM;
-		goto err_destroy_pkt;
-	}
+		comps[i] = kcalloc(param->config[i].num_components,
+				   sizeof(struct mdp_comp), GFP_KERNEL);
+		if (!comps[i]) {
+			ret = -ENOMEM;
+			dev_err(dev, "%s path %d alloc comps error\n", __func__, i);
+			goto err_destroy_cb_param;
+		}
 
-	for (i = 0; i < param->config->num_components; i++) {
-		if (is_dummy_engine(mdp, path->config->components[i].type))
-			continue;
+		for (j = 0; j < param->config[i].num_components; j++) {
+			if (is_dummy_engine(mdp, paths[i]->config->components[j].type))
+				continue;
 
-		memcpy(&comps[i], path->comps[i].comp,
-		       sizeof(struct mdp_comp));
-	}
-	cb_param->mdp = mdp;
-	cb_param->user_cmdq_cb = param->cmdq_cb;
-	cb_param->user_cb_data = param->cb_data;
-	cb_param->pkt = cmd.pkt;
-	cb_param->comps = comps;
-	cb_param->num_comps = param->config->num_components;
-	cb_param->mdp_ctx = param->mdp_ctx;
-
-	cmdq_pkt_finalize(cmd.pkt);
-	ret = cmdq_pkt_flush_async(cmd.pkt,
-				   mdp_handle_cmdq_callback,
-				   (void *)cb_param);
-	if (ret) {
-		dev_err(dev, "cmdq_pkt_flush_async fail!\n");
-		goto err_clock_off;
+			memcpy(&comps[i][j], paths[i]->comps[j].comp,
+			       sizeof(struct mdp_comp));
+		}
+		cb_param[i]->mdp = mdp;
+		cb_param[i]->user_cmdq_cb = param->cmdq_cb;
+		cb_param[i]->user_cb_data = param->cb_data;
+		cb_param[i]->pkt = cmd[i].pkt;
+		cb_param[i]->comps = comps[i];
+		cb_param[i]->num_comps = param->config[i].num_components;
+		cb_param[i]->mdp_ctx = param->mdp_ctx;
+		cb_param[i]->cmdq_user = param->cmdq_user;
+		cb_param[i]->dualpipe = (get_pipe_num(scenario) > 1 ? true : false);
+	}
+
+	/* Flush cmdq */
+	if (atomic_read(&mdp->cmdq_count[param->cmdq_user]))
+		dev_dbg(dev, "%s: Warning: cmdq_count:%d !\n", __func__,
+			atomic_read(&mdp->cmdq_count[param->cmdq_user]));
+
+	atomic_set(&mdp->cmdq_count[param->cmdq_user], get_pipe_num(scenario));
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		cmdq_pkt_finalize(cmd[i].pkt);
+
+		ret = cmdq_pkt_flush_async(cmd[i].pkt,
+					   mdp_handle_cmdq_callback,
+					   (void *)cb_param[i]);
+		if (ret) {
+			dev_err(dev, "pkt %d cmdq_pkt_flush_async fail!\n", i);
+			goto err_destroy_cmdq_request;
+		}
+		kfree(paths[i]);
 	}
-	kfree(path);
+
 	return 0;
 
+err_destroy_cmdq_request:
+	atomic_set(&mdp->cmdq_count[param->cmdq_user], 0);
+err_destroy_cb_param:
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		kfree(comps[i]);
+		kfree(cb_param[i]);
+	}
 err_clock_off:
 	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
@@ -898,15 +953,22 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 	if (i >= 0)
 		mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
 
-	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
-			    cb_param->num_comps);
+	for (i = 0; i < get_pipe_num(scenario); i++) {
+		for (j = 0; j < param->config[i].num_components; j++) {
+			if (is_dummy_engine(mdp, paths[i]->config->components[j].type) == false)
+				mdp_comp_clock_off(&mdp->pdev->dev, paths[i]->comps[j].comp);
+		}
+	}
+err_destroy_paths:
+	for (i = 0; i < get_pipe_num(scenario); i++)
+		kfree(paths[i]);
 err_destroy_pkt:
-	cmdq_pkt_destroy(cmd.pkt);
+	for (i = 0; i < get_pipe_num(scenario); i++)
+		if (!IS_ERR(cmd[i].pkt))
+			cmdq_pkt_destroy(cmd[i].pkt);
+
 	atomic_dec(&mdp->job_count);
 	wake_up(&mdp->callback_wq);
-	kfree(comps);
-	kfree(cb_param);
-	kfree(path);
 
 	return ret;
 }
@@ -923,6 +985,7 @@ int mdp_cmdq_sendtask(struct platform_device *pdev, struct img_config *config,
 		.composes[0] = compose,
 		.cmdq_cb = cmdq_cb,
 		.cb_data = cb_data,
+		.cmdq_user = MDP_CMDQ_DL,
 	};
 
 	return mdp_cmdq_send(mdp, &task);
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
index 16933507333b..7e6ad3760677 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.h
@@ -26,6 +26,7 @@ struct mdp_cmdq_param {
 	void (*cmdq_cb)(struct cmdq_cb_data data);
 	void *cb_data;
 	void *mdp_ctx;
+	u32 cmdq_user;
 };
 
 struct mdp_cmdq_cb_param {
@@ -37,6 +38,9 @@ struct mdp_cmdq_cb_param {
 	struct mdp_comp *comps;
 	u8 num_comps;
 	void *mdp_ctx;
+	u32 cmdq_user;
+	bool finalize;
+	bool dualpipe;
 };
 
 struct mdp_dev;
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
index d8161be8c556..495a6aa3a759 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
@@ -292,12 +292,20 @@ static int mdp_probe(struct platform_device *pdev)
 	mutex_init(&mdp->vpu_lock);
 	mutex_init(&mdp->m2m_lock);
 
-	mdp->cmdq_clt = cmdq_mbox_create(dev, 0);
-	if (IS_ERR(mdp->cmdq_clt)) {
-		ret = PTR_ERR(mdp->cmdq_clt);
+	mdp->cmdq_clt[0] = cmdq_mbox_create(dev, 0);
+	if (IS_ERR(mdp->cmdq_clt[0])) {
+		ret = PTR_ERR(mdp->cmdq_clt[0]);
 		goto err_put_scp;
 	}
 
+	if (mdp->mdp_data->mdp_cfg->support_dual_pipe) {
+		mdp->cmdq_clt[1] = cmdq_mbox_create(dev, 1);
+		if (IS_ERR(mdp->cmdq_clt[1])) {
+			ret = PTR_ERR(mdp->cmdq_clt[1]);
+			goto err_mbox_destroy;
+		}
+	}
+
 	init_waitqueue_head(&mdp->callback_wq);
 	ida_init(&mdp->mdp_ida);
 	platform_set_drvdata(pdev, mdp);
@@ -308,7 +316,7 @@ static int mdp_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(dev, "Failed to register v4l2 device\n");
 		ret = -EINVAL;
-		goto err_mbox_destroy;
+		goto err_dual_mbox_destroy;
 	}
 
 	ret = mdp_m2m_device_register(mdp);
@@ -323,8 +331,11 @@ static int mdp_probe(struct platform_device *pdev)
 
 err_unregister_device:
 	v4l2_device_unregister(&mdp->v4l2_dev);
+err_dual_mbox_destroy:
+	if (mdp->mdp_data->mdp_cfg->support_dual_pipe)
+		cmdq_mbox_destroy(mdp->cmdq_clt[1]);
 err_mbox_destroy:
-	cmdq_mbox_destroy(mdp->cmdq_clt);
+	cmdq_mbox_destroy(mdp->cmdq_clt[0]);
 err_put_scp:
 	scp_put(mdp->scp);
 err_destroy_clock_wq:
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index 8ee70763a18f..0fb932ad3560 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -15,6 +15,7 @@
 #include "mtk-mdp3-vpu.h"
 
 #define MDP_MODULE_NAME	"mtk-mdp3"
+#define MDP_DUAL_PIPE       2
 
 enum mdp_buffer_usage {
 	MDP_BUFFER_USAGE_HW_READ,
@@ -24,6 +25,12 @@ enum mdp_buffer_usage {
 	MDP_BUFFER_USAGE_WPE,
 };
 
+enum mdp_cmdq_usage {
+	MDP_CMDQ_V4L2,
+	MDP_CMDQ_DL,
+	MDP_CMDQ_NUM
+};
+
 struct mdp_platform_config {
 	bool	rdma_support_10bit;
 	bool	rdma_rsz1_sram_sharing;
@@ -43,6 +50,7 @@ struct mdp_platform_config {
 	u8	tdshp_dyn_contrast_version;
 	u32	gce_event_offset;
 	bool	support_multi_larb;
+	bool	support_dual_pipe;
 };
 
 struct mtk_mdp_driver_data {
@@ -77,7 +85,7 @@ struct mdp_dev {
 	s32					vpu_count;
 	u32					id_count;
 	struct ida				mdp_ida;
-	struct cmdq_client			*cmdq_clt;
+	struct cmdq_client			*cmdq_clt[MDP_DUAL_PIPE];
 	wait_queue_head_t			callback_wq;
 
 	struct v4l2_device			v4l2_dev;
@@ -87,6 +95,7 @@ struct mdp_dev {
 	struct mutex				m2m_lock;
 	atomic_t				suspended;
 	atomic_t				job_count;
+	atomic_t				cmdq_count[MDP_CMDQ_NUM];
 };
 
 struct mdp_pipe_info {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
index 1e749bb2b338..72a1864d880c 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
@@ -95,6 +95,10 @@ static void mdp_m2m_worker(struct work_struct *work)
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
 	mdp_set_src_config(&param.inputs[0], frame, &src_vb->vb2_buf);
+	mdp_set_scenario(ctx->mdp_dev, &param, frame);
+	if (param.frame_change)
+		dev_info(&ctx->mdp_dev->pdev->dev,
+			 "MDP Scenario: %d\n", param.type);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
 	dst_vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
@@ -115,6 +119,7 @@ static void mdp_m2m_worker(struct work_struct *work)
 	task.cmdq_cb = NULL;
 	task.cb_data = NULL;
 	task.mdp_ctx = ctx;
+	task.cmdq_user = MDP_CMDQ_V4L2;
 
 	ret = mdp_cmdq_send(ctx->mdp_dev, &task);
 	if (ret) {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
index 8c2b74c67273..c0a7e3569853 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
@@ -11,6 +11,8 @@
 #include "mtk-mdp3-regs.h"
 #include "mtk-mdp3-m2m.h"
 
+#define FHD (1920 * 1080)
+
 static const struct mdp_format *mdp_formats;
 static u32 format_len;
 
@@ -427,6 +429,22 @@ static u32 mdp_fmt_get_plane_size(const struct mdp_format *fmt,
 	return 0;
 }
 
+void mdp_set_scenario(struct mdp_dev *mdp,
+		      struct img_ipi_frameparam *param,
+		      struct mdp_frame *frame)
+{
+	u32 width = frame->format.fmt.pix_mp.width;
+	u32 height = frame->format.fmt.pix_mp.height;
+
+	if (!mdp)
+		return;
+
+	if (mdp->mdp_data->mdp_cfg->support_dual_pipe) {
+		if ((width * height) >= FHD)
+			param->type = MDP_STREAM_TYPE_DUAL_BITBLT;
+	}
+}
+
 static void mdp_prepare_buffer(struct img_image_buffer *b,
 			       struct mdp_frame *frame, struct vb2_buffer *vb)
 {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 1ef32b747233..3547ce10948f 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -10,6 +10,7 @@
 #include <linux/videodev2.h>
 #include <media/videobuf2-core.h>
 #include "mtk-img-ipi.h"
+#include "mtk-mdp3-cmdq.h"
 
 /*
  * MDP native color code
@@ -407,6 +408,9 @@ int mdp_try_crop(struct mdp_m2m_ctx *ctx, struct v4l2_rect *r,
 int mdp_check_scaling_ratio(const struct v4l2_rect *crop,
 			    const struct v4l2_rect *compose, s32 rotation,
 	const struct mdp_limit *limit);
+void mdp_set_scenario(struct mdp_dev *mdp,
+		      struct img_ipi_frameparam *param,
+		      struct mdp_frame *frame);
 void mdp_set_src_config(struct img_input *in,
 			struct mdp_frame *frame, struct vb2_buffer *vb);
 void mdp_set_dst_config(struct img_output *out,
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
index fc008d96c7c0..035fa3e55335 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.c
@@ -10,7 +10,7 @@
 #include "mtk-mdp3-core.h"
 
 #define MDP_VPU_MESSAGE_TIMEOUT 500U
-#define vpu_alloc_size		0x600000
+#define vpu_alloc_size         0x7F8000
 
 static inline struct mdp_dev *vpu_to_mdp(struct mdp_vpu_dev *vpu)
 {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
index e831070b44d0..3140d2925a1a 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-vpu.h
@@ -39,6 +39,7 @@ struct mdp_ipi_deinit_msg {
 
 enum mdp_config_id {
 	MDP_DEV_M2M = 0,
+	MDP_DEV_M2M_2ND = 1,
 	MDP_CONFIG_POOL_SIZE	/* ALWAYS keep at the end */
 };
 
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:47 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:47 +0800
Subject: [PATCH v1 07/14] media: platform: mtk-mdp3: Add platform
 configuration for MT8195
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-8-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add platform configuration for MT8195

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/media/platform/mtk-mdp3/mt8195_mdp.h  | 682 ++++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 144 ++++
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |  22 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  13 +
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |  11 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |  67 ++
 6 files changed, 933 insertions(+), 6 deletions(-)
 create mode 100644 drivers/media/platform/mtk-mdp3/mt8195_mdp.h

diff --git a/drivers/media/platform/mtk-mdp3/mt8195_mdp.h b/drivers/media/platform/mtk-mdp3/mt8195_mdp.h
new file mode 100644
index 000000000000..f69bc86bcd1e
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mt8195_mdp.h
@@ -0,0 +1,682 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MT8195_MDP_H__
+#define __MT8195_MDP_H__
+
+static const struct mdp_platform_config mt8195_plat_cfg = {
+	.rdma_support_10bit             = true,
+	.rdma_support_extend_ufo        = true,
+	.rdma_support_hyfbc             = true,
+	.rdma_support_afbc              = true,
+	.rdma_esl_setting               = true,
+	.rdma_rsz1_sram_sharing         = false,
+	.rdma_upsample_repeat_only      = false,
+	.rsz_disable_dcm_small_sample   = false,
+	.rsz_etc_control                = true,
+	.wrot_filter_constraint         = false,
+	.tdshp_1_1                      = true,
+	.tdshp_dyn_contrast_version     = 2,
+	.mdp_version_8195               = true,
+	.mdp_version_6885               = true,
+	.gce_event_offset               = 0,
+	.support_multi_larb		= true,
+};
+
+enum mt8195_mdp_comp_id {
+	/* MT8195 Comp id */
+	/* ISP */
+	MT8195_MDP_COMP_WPEI = 0,
+	MT8195_MDP_COMP_WPEO,           /* 1 */
+	MT8195_MDP_COMP_WPEI2,          /* 2 */
+	MT8195_MDP_COMP_WPEO2,          /* 3 */
+
+	/* MDP */
+	MT8195_MDP_COMP_CAMIN,          /* 4 */
+	MT8195_MDP_COMP_CAMIN2,         /* 5 */
+	MT8195_MDP_COMP_SPLIT,          /* 6 */
+	MT8195_MDP_COMP_SPLIT2,         /* 7 */
+	MT8195_MDP_COMP_RDMA0,          /* 8 */
+	MT8195_MDP_COMP_RDMA1,          /* 9 */
+	MT8195_MDP_COMP_RDMA2,          /* 10 */
+	MT8195_MDP_COMP_RDMA3,          /* 11 */
+	MT8195_MDP_COMP_STITCH,         /* 12 */
+	MT8195_MDP_COMP_FG0,            /* 13 */
+	MT8195_MDP_COMP_FG1,            /* 14 */
+	MT8195_MDP_COMP_FG2,            /* 15 */
+	MT8195_MDP_COMP_FG3,            /* 16 */
+	MT8195_MDP_COMP_TO_SVPP2MOUT,   /* 17 */
+	MT8195_MDP_COMP_TO_SVPP3MOUT,   /* 18 */
+	MT8195_MDP_COMP_TO_WARP0MOUT,   /* 19 */
+	MT8195_MDP_COMP_TO_WARP1MOUT,   /* 20 */
+	MT8195_MDP_COMP_VPP0_SOUT,      /* 21 */
+	MT8195_MDP_COMP_VPP1_SOUT,      /* 22 */
+	MT8195_MDP_COMP_PQ0_SOUT,       /* 23 */
+	MT8195_MDP_COMP_PQ1_SOUT,       /* 24 */
+	MT8195_MDP_COMP_HDR0,           /* 25 */
+	MT8195_MDP_COMP_HDR1,           /* 26 */
+	MT8195_MDP_COMP_HDR2,           /* 27 */
+	MT8195_MDP_COMP_HDR3,           /* 28 */
+	MT8195_MDP_COMP_AAL0,           /* 29 */
+	MT8195_MDP_COMP_AAL1,           /* 30 */
+	MT8195_MDP_COMP_AAL2,           /* 31 */
+	MT8195_MDP_COMP_AAL3,           /* 32 */
+	MT8195_MDP_COMP_RSZ0,           /* 33 */
+	MT8195_MDP_COMP_RSZ1,           /* 34 */
+	MT8195_MDP_COMP_RSZ2,           /* 35 */
+	MT8195_MDP_COMP_RSZ3,           /* 36 */
+	MT8195_MDP_COMP_TDSHP0,         /* 37 */
+	MT8195_MDP_COMP_TDSHP1,         /* 38 */
+	MT8195_MDP_COMP_TDSHP2,         /* 39 */
+	MT8195_MDP_COMP_TDSHP3,         /* 40 */
+	MT8195_MDP_COMP_COLOR0,         /* 41 */
+	MT8195_MDP_COMP_COLOR1,         /* 42 */
+	MT8195_MDP_COMP_COLOR2,         /* 43 */
+	MT8195_MDP_COMP_COLOR3,         /* 44 */
+	MT8195_MDP_COMP_OVL0,           /* 45 */
+	MT8195_MDP_COMP_OVL1,           /* 46 */
+	MT8195_MDP_COMP_PAD0,           /* 47 */
+	MT8195_MDP_COMP_PAD1,           /* 48 */
+	MT8195_MDP_COMP_PAD2,           /* 49 */
+	MT8195_MDP_COMP_PAD3,           /* 50 */
+	MT8195_MDP_COMP_TCC0,           /* 51 */
+	MT8195_MDP_COMP_TCC1,           /* 52 */
+	MT8195_MDP_COMP_WROT0,          /* 53 */
+	MT8195_MDP_COMP_WROT1,          /* 54 */
+	MT8195_MDP_COMP_WROT2,          /* 55 */
+	MT8195_MDP_COMP_WROT3,          /* 56 */
+	MT8195_MDP_COMP_MERGE2,         /* 57 */
+	MT8195_MDP_COMP_MERGE3,         /* 58 */
+
+	MT8195_MDP_COMP_VDO0DL0,        /* 59 */
+	MT8195_MDP_COMP_VDO1DL0,        /* 60 */
+	MT8195_MDP_COMP_VDO0DL1,        /* 61 */
+	MT8195_MDP_COMP_VDO1DL1,        /* 62 */
+};
+
+static const struct mdp_comp_data mt8195_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
+	[MDP_COMP_WPEI] = {
+		{MDP_COMP_TYPE_WPEI, 0, MT8195_MDP_COMP_WPEI},
+		{0, 0, 0},
+		{0, BIT(13), 0}
+	},
+	[MDP_COMP_WPEO] = {
+		{MDP_COMP_TYPE_EXTO, 2, MT8195_MDP_COMP_WPEO},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_WPEI2] = {
+		{MDP_COMP_TYPE_WPEI, 1, MT8195_MDP_COMP_WPEI2},
+		{0, 0, 0},
+		{0, BIT(14), 0}
+	},
+	[MDP_COMP_WPEO2] = {
+		{MDP_COMP_TYPE_EXTO, 3, MT8195_MDP_COMP_WPEO2},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_CAMIN] = {
+		{MDP_COMP_TYPE_DL_PATH1, 0, MT8195_MDP_COMP_CAMIN},
+		{3, 3, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_CAMIN2] = {
+		{MDP_COMP_TYPE_DL_PATH2, 1, MT8195_MDP_COMP_CAMIN2},
+		{3, 6, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_SPLIT] = {
+		{MDP_COMP_TYPE_SPLIT, 0, MT8195_MDP_COMP_SPLIT},
+		{7, 0, 0},
+		{1, BIT(2), 0}
+	},
+	[MDP_COMP_SPLIT2] = {
+		{MDP_COMP_TYPE_SPLIT, 1, MT8195_MDP_COMP_SPLIT2},
+		{7, 0, 0},
+		{1, BIT(2), 0}
+	},
+	[MDP_COMP_RDMA0] = {
+		{MDP_COMP_TYPE_RDMA, 0, MT8195_MDP_COMP_RDMA0},
+		{3, 0, 0},
+		{0, BIT(0), 0}
+	},
+	[MDP_COMP_RDMA1] = {
+		{MDP_COMP_TYPE_RDMA, 1, MT8195_MDP_COMP_RDMA1},
+		{3, 0, 0},
+		{1, BIT(4), 0}
+	},
+	[MDP_COMP_RDMA2] = {
+		{MDP_COMP_TYPE_RDMA, 2, MT8195_MDP_COMP_RDMA2},
+		{3, 0, 0},
+		{1, BIT(5), 0}
+	},
+	[MDP_COMP_RDMA3] = {
+		{MDP_COMP_TYPE_RDMA, 3, MT8195_MDP_COMP_RDMA3},
+		{3, 0, 0},
+		{1, BIT(6), 0}
+	},
+	[MDP_COMP_STITCH] = {
+		{MDP_COMP_TYPE_STITCH, 0, MT8195_MDP_COMP_STITCH},
+		{1, 0, 0},
+		{0, BIT(2), 0}
+	},
+	[MDP_COMP_FG0] = {
+		{MDP_COMP_TYPE_FG, 0, MT8195_MDP_COMP_FG0},
+		{1, 0, 0},
+		{0, BIT(1), 0}
+	},
+	[MDP_COMP_FG1] = {
+		{MDP_COMP_TYPE_FG, 1, MT8195_MDP_COMP_FG1},
+		{1, 0, 0},
+		{1, BIT(7), 0}
+	},
+	[MDP_COMP_FG2] = {
+		{MDP_COMP_TYPE_FG, 2, MT8195_MDP_COMP_FG2},
+		{1, 0, 0},
+		{1, BIT(8), 0}
+	},
+	[MDP_COMP_FG3] = {
+		{MDP_COMP_TYPE_FG, 3, MT8195_MDP_COMP_FG3},
+		{1, 0, 0},
+		{1, BIT(9), 0}
+	},
+	[MDP_COMP_HDR0] = {
+		{MDP_COMP_TYPE_HDR, 0, MT8195_MDP_COMP_HDR0},
+		{1, 0, 0},
+		{0, BIT(3), 0}
+	},
+	[MDP_COMP_HDR1] = {
+		{MDP_COMP_TYPE_HDR, 1, MT8195_MDP_COMP_HDR1},
+		{1, 0, 0},
+		{1, BIT(10), 0}
+	},
+	[MDP_COMP_HDR2] = {
+		{MDP_COMP_TYPE_HDR, 2, MT8195_MDP_COMP_HDR2},
+		{1, 0, 0},
+		{1, BIT(11), 0}
+	},
+	[MDP_COMP_HDR3] = {
+		{MDP_COMP_TYPE_HDR, 3, MT8195_MDP_COMP_HDR3},
+		{1, 0, 0},
+		{1, BIT(12), 0}
+	},
+	[MDP_COMP_AAL0] = {
+		{MDP_COMP_TYPE_AAL, 0, MT8195_MDP_COMP_AAL0},
+		{1, 0, 0},
+		{0, BIT(4), 0}
+	},
+	[MDP_COMP_AAL1] = {
+		{MDP_COMP_TYPE_AAL, 1, MT8195_MDP_COMP_AAL1},
+		{1, 0, 0},
+		{1, BIT(13), 0}
+	},
+	[MDP_COMP_AAL2] = {
+		{MDP_COMP_TYPE_AAL, 2, MT8195_MDP_COMP_AAL2},
+		{1, 0, 0},
+		{1, BIT(14), 0}
+	},
+	[MDP_COMP_AAL3] = {
+		{MDP_COMP_TYPE_AAL, 3, MT8195_MDP_COMP_AAL3},
+		{1, 0, 0},
+		{1, BIT(15), 0}
+	},
+	[MDP_COMP_RSZ0] = {
+		{MDP_COMP_TYPE_RSZ, 0, MT8195_MDP_COMP_RSZ0},
+		{1, 0, 0},
+		{0, BIT(5), 0}
+	},
+	[MDP_COMP_RSZ1] = {
+		{MDP_COMP_TYPE_RSZ, 1, MT8195_MDP_COMP_RSZ1},
+		{1, 0, 0},
+		{1, BIT(16), 0}
+	},
+	[MDP_COMP_RSZ2] = {
+		{MDP_COMP_TYPE_RSZ, 2, MT8195_MDP_COMP_RSZ2},
+		{2, 0, 0},
+		{1, BIT(17) | BIT(22), 0}
+	},
+	[MDP_COMP_RSZ3] = {
+		{MDP_COMP_TYPE_RSZ, 3, MT8195_MDP_COMP_RSZ3},
+		{2, 0, 0},
+		{1, BIT(18) | BIT(23), 0}
+	},
+	[MDP_COMP_TDSHP0] = {
+		{MDP_COMP_TYPE_TDSHP, 0, MT8195_MDP_COMP_TDSHP0},
+		{1, 0, 0},
+		{0, BIT(6), 0}
+	},
+	[MDP_COMP_TDSHP1] = {
+		{MDP_COMP_TYPE_TDSHP, 1, MT8195_MDP_COMP_TDSHP1},
+		{1, 0, 0},
+		{1, BIT(19), 0}
+	},
+	[MDP_COMP_TDSHP2] = {
+		{MDP_COMP_TYPE_TDSHP, 2, MT8195_MDP_COMP_TDSHP2},
+		{1, 0, 0},
+		{1, BIT(20), 0}
+	},
+	[MDP_COMP_TDSHP3] = {
+		{MDP_COMP_TYPE_TDSHP, 3, MT8195_MDP_COMP_TDSHP3},
+		{1, 0, 0},
+		{1, BIT(21), 0}
+	},
+	[MDP_COMP_COLOR0] = {
+		{MDP_COMP_TYPE_COLOR, 0, MT8195_MDP_COMP_COLOR0},
+		{1, 0, 0},
+		{0, BIT(7), 0}
+	},
+	[MDP_COMP_COLOR1] = {
+		{MDP_COMP_TYPE_COLOR, 1, MT8195_MDP_COMP_COLOR1},
+		{1, 0, 0},
+		{1, BIT(24), 0}
+	},
+	[MDP_COMP_COLOR2] = {
+		{MDP_COMP_TYPE_COLOR, 2, MT8195_MDP_COMP_COLOR2},
+		{1, 0, 0},
+		{1, BIT(25), 0}
+	},
+	[MDP_COMP_COLOR3] = {
+		{MDP_COMP_TYPE_COLOR, 3, MT8195_MDP_COMP_COLOR3},
+		{1, 0, 0},
+		{1, BIT(26), 0}
+	},
+	[MDP_COMP_OVL0] = {
+		{MDP_COMP_TYPE_OVL, 0, MT8195_MDP_COMP_OVL0},
+		{1, 0, 0},
+		{0, BIT(8), 0}
+	},
+	[MDP_COMP_OVL1] = {
+		{MDP_COMP_TYPE_OVL, 1, MT8195_MDP_COMP_OVL1},
+		{1, 0, 0},
+		{1, BIT(27), 0}
+	},
+	[MDP_COMP_PAD0] = {
+		{MDP_COMP_TYPE_PAD, 0, MT8195_MDP_COMP_PAD0},
+		{1, 0, 0},
+		{0, BIT(9), 0}
+	},
+	[MDP_COMP_PAD1] = {
+		{MDP_COMP_TYPE_PAD, 1, MT8195_MDP_COMP_PAD1},
+		{1, 0, 0},
+		{1, BIT(28), 0}
+	},
+	[MDP_COMP_PAD2] = {
+		{MDP_COMP_TYPE_PAD, 2, MT8195_MDP_COMP_PAD2},
+		{1, 0, 0},
+		{1, BIT(29), 0}
+	},
+	[MDP_COMP_PAD3] = {
+		{MDP_COMP_TYPE_PAD, 3, MT8195_MDP_COMP_PAD3},
+		{1, 0, 0},
+		{1, BIT(30), 0}
+	},
+	[MDP_COMP_TCC0] = {
+		{MDP_COMP_TYPE_TCC, 0, MT8195_MDP_COMP_TCC0},
+		{1, 0, 0},
+		{0, BIT(10), 0}
+	},
+	[MDP_COMP_TCC1] = {
+		{MDP_COMP_TYPE_TCC, 1, MT8195_MDP_COMP_TCC1},
+		{1, 0, 0},
+		{1, BIT(3), 0}
+	},
+	[MDP_COMP_WROT0] = {
+		{MDP_COMP_TYPE_WROT, 0, MT8195_MDP_COMP_WROT0},
+		{1, 0, 0},
+		{0, BIT(11), 0}
+	},
+	[MDP_COMP_WROT1] = {
+		{MDP_COMP_TYPE_WROT, 1, MT8195_MDP_COMP_WROT1},
+		{1, 0, 0},
+		{1, BIT(31), 0}
+	},
+	[MDP_COMP_WROT2] = {
+		{MDP_COMP_TYPE_WROT, 2, MT8195_MDP_COMP_WROT2},
+		{1, 0, 0},
+		{1, 0, BIT(0)}
+	},
+	[MDP_COMP_WROT3] = {
+		{MDP_COMP_TYPE_WROT, 3, MT8195_MDP_COMP_WROT3},
+		{1, 0, 0},
+		{1, 0, BIT(1)}
+	},
+	[MDP_COMP_MERGE2] = {
+		{MDP_COMP_TYPE_MERGE, 2, MT8195_MDP_COMP_MERGE2},
+		{1, 0, 0},
+		{1, 0, 0}
+	},
+	[MDP_COMP_MERGE3] = {
+		{MDP_COMP_TYPE_MERGE, 3, MT8195_MDP_COMP_MERGE2},
+		{1, 0, 0},
+		{1, 0, 0}
+	},
+	[MDP_COMP_PQ0_SOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 0, MT8195_MDP_COMP_PQ0_SOUT},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_PQ1_SOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 1, MT8195_MDP_COMP_PQ1_SOUT},
+		{0, 0, 0},
+		{1, 0, 0}
+	},
+	[MDP_COMP_TO_WARP0MOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 2, MT8195_MDP_COMP_TO_WARP0MOUT},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_TO_WARP1MOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 3, MT8195_MDP_COMP_TO_WARP1MOUT},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_TO_SVPP2MOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 4, MT8195_MDP_COMP_TO_SVPP2MOUT},
+		{0, 0, 0},
+		{1, 0, 0}
+	},
+	[MDP_COMP_TO_SVPP3MOUT] = {
+		{MDP_COMP_TYPE_DUMMY, 5, MT8195_MDP_COMP_TO_SVPP3MOUT},
+		{0, 0, 0},
+		{1, 0, 0}
+	},
+	[MDP_COMP_VPP0_SOUT] = {
+		{MDP_COMP_TYPE_PATH1, 0, MT8195_MDP_COMP_VPP0_SOUT},
+		{4, 9, 0},
+		{0, BIT(15), BIT(2)}
+	},
+	[MDP_COMP_VPP1_SOUT] = {
+		{MDP_COMP_TYPE_PATH2, 1, MT8195_MDP_COMP_VPP1_SOUT},
+		{2, 13, 0},
+		{1, BIT(16), BIT(3)}
+	},
+	[MDP_COMP_VDO0DL0] = {
+		{MDP_COMP_TYPE_DL_PATH3, 0, MT8195_MDP_COMP_VDO0DL0},
+		{1, 15, 0},
+		{1, 0, BIT(4)}
+	},
+	[MDP_COMP_VDO1DL0] = {
+		{MDP_COMP_TYPE_DL_PATH4, 0, MT8195_MDP_COMP_VDO1DL0},
+		{1, 17, 0},
+		{1, 0, BIT(6)}
+	},
+	[MDP_COMP_VDO0DL1] = {
+		{MDP_COMP_TYPE_DL_PATH5, 0, MT8195_MDP_COMP_VDO0DL1},
+		{1, 18, 0},
+		{1, 0, BIT(5)}
+	},
+	[MDP_COMP_VDO1DL1] = {
+		{MDP_COMP_TYPE_DL_PATH6, 0, MT8195_MDP_COMP_VDO1DL1},
+		{1, 16, 0},
+		{1, 0, BIT(7)}
+	},
+};
+
+static const enum mdp_comp_event mt8195_mdp_event[] = {
+	RDMA0_SOF,
+	WROT0_SOF,
+	RDMA0_DONE,
+	WROT0_DONE,
+	RDMA1_SOF,
+	RDMA2_SOF,
+	RDMA3_SOF,
+	WROT1_SOF,
+	WROT2_SOF,
+	WROT3_SOF,
+	RDMA1_DONE,
+	RDMA2_DONE,
+	RDMA3_DONE,
+	WROT1_DONE,
+	WROT2_DONE,
+	WROT3_DONE
+};
+
+static const struct mdp_pipe_info mt8195_pipe_info[] = {
+	{MDP_PIPE_WPEI, 0, 0},
+	{MDP_PIPE_WPEI2, 0, 1},
+	{MDP_PIPE_RDMA0, 0, 2},
+	{MDP_PIPE_VPP1_SOUT, 0, 3},
+	{MDP_PIPE_SPLIT, 1, 2, 0x387},
+	{MDP_PIPE_SPLIT2, 1, 3, 0x387},
+	{MDP_PIPE_RDMA1, 1, 1},
+	{MDP_PIPE_RDMA2, 1, 2},
+	{MDP_PIPE_RDMA3, 1, 3},
+	{MDP_PIPE_VPP0_SOUT, 1, 4},
+};
+
+static const struct mdp_format mt8195_formats[] = {
+	{
+		.pixelformat	= V4L2_PIX_FMT_GREY,
+		.mdp_color	= MDP_COLOR_GREY,
+		.depth		= { 8 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB565X,
+		.mdp_color	= MDP_COLOR_RGB565,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB565,
+		.mdp_color	= MDP_COLOR_BGR565,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB24,
+		.mdp_color	= MDP_COLOR_RGB888,
+		.depth		= { 24 },
+		.row_depth	= { 24 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_BGR24,
+		.mdp_color	= MDP_COLOR_BGR888,
+		.depth		= { 24 },
+		.row_depth	= { 24 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_ABGR32,
+		.mdp_color	= MDP_COLOR_BGRA8888,
+		.depth		= { 32 },
+		.row_depth	= { 32 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_ARGB32,
+		.mdp_color	= MDP_COLOR_ARGB8888,
+		.depth		= { 32 },
+		.row_depth	= { 32 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_UYVY,
+		.mdp_color	= MDP_COLOR_UYVY,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_VYUY,
+		.mdp_color	= MDP_COLOR_VYUY,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUYV,
+		.mdp_color	= MDP_COLOR_YUYV,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVYU,
+		.mdp_color	= MDP_COLOR_YVYU,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUV420,
+		.mdp_color	= MDP_COLOR_I420,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVU420,
+		.mdp_color	= MDP_COLOR_YV12,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV12,
+		.mdp_color	= MDP_COLOR_NV12,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV21,
+		.mdp_color	= MDP_COLOR_NV21,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV16,
+		.mdp_color	= MDP_COLOR_NV16,
+		.depth		= { 16 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV61,
+		.mdp_color	= MDP_COLOR_NV61,
+		.depth		= { 16 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV24,
+		.mdp_color	= MDP_COLOR_NV24,
+		.depth		= { 24 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV42,
+		.mdp_color	= MDP_COLOR_NV42,
+		.depth		= { 24 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_MT21C,
+		.mdp_color	= MDP_COLOR_NV12_HYFBC,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 1,
+		.walign		= 4,
+		.halign		= 4,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_MM21,
+		.mdp_color	= MDP_COLOR_420_BLKP,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 4,
+		.halign		= 5,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV12M,
+		.mdp_color	= MDP_COLOR_NV12,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV21M,
+		.mdp_color	= MDP_COLOR_NV21,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV16M,
+		.mdp_color	= MDP_COLOR_NV16,
+		.depth		= { 8, 8 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV61M,
+		.mdp_color	= MDP_COLOR_NV61,
+		.depth		= { 8, 8 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUV420M,
+		.mdp_color	= MDP_COLOR_I420,
+		.depth		= { 8, 2, 2 },
+		.row_depth	= { 8, 4, 4 },
+		.num_planes	= 3,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVU420M,
+		.mdp_color	= MDP_COLOR_YV12,
+		.depth		= { 8, 2, 2 },
+		.row_depth	= { 8, 4, 4 },
+		.num_planes	= 3,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}
+};
+
+static const u32 mt8195_mdp_mmsys_config_table[] = {
+	[CONFIG_VPP0_HW_DCM_1ST_DIS0]    = 0,
+	[CONFIG_VPP0_DL_IRELAY_WR]       = 1,
+	[CONFIG_VPP1_HW_DCM_1ST_DIS0]    = 2,
+	[CONFIG_VPP1_HW_DCM_1ST_DIS1]    = 3,
+	[CONFIG_VPP1_HW_DCM_2ND_DIS0]    = 4,
+	[CONFIG_VPP1_HW_DCM_2ND_DIS1]    = 5,
+	[CONFIG_SVPP2_BUF_BF_RSZ_SWITCH] = 6,
+	[CONFIG_SVPP3_BUF_BF_RSZ_SWITCH] = 7,
+};
+
+#endif  // __MT8195_MDP_H__
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
index 9073ddc19775..fdf072e48238 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
@@ -919,6 +919,126 @@ static const struct of_device_id mdp_comp_dt_ids[] = {
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-wdma",
 		.data = (void *)MDP_COMP_WDMA,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-rdma1",
+		.data = (void *)MDP_COMP_RDMA1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-rdma2",
+		.data = (void *)MDP_COMP_RDMA2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-rdma3",
+		.data = (void *)MDP_COMP_RDMA3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-wrot1",
+		.data = (void *)MDP_COMP_WROT1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-wrot2",
+		.data = (void *)MDP_COMP_WROT2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-wrot3",
+		.data = (void *)MDP_COMP_WROT3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-split",
+		.data = (void *)MDP_COMP_SPLIT,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-stitch",
+		.data = (void *)MDP_COMP_STITCH,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-fg0",
+		.data = (void *)MDP_COMP_FG0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-fg1",
+		.data = (void *)MDP_COMP_FG1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-fg2",
+		.data = (void *)MDP_COMP_FG2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-fg3",
+		.data = (void *)MDP_COMP_FG3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-hdr0",
+		.data = (void *)MDP_COMP_HDR0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-hdr1",
+		.data = (void *)MDP_COMP_HDR1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-hdr2",
+		.data = (void *)MDP_COMP_HDR2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-hdr3",
+		.data = (void *)MDP_COMP_HDR3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-aal0",
+		.data = (void *)MDP_COMP_AAL0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-aal1",
+		.data = (void *)MDP_COMP_AAL1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-aal2",
+		.data = (void *)MDP_COMP_AAL2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-aal3",
+		.data = (void *)MDP_COMP_AAL3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-rsz2",
+		.data = (void *)MDP_COMP_RSZ2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-rsz3",
+		.data = (void *)MDP_COMP_RSZ3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-merge2",
+		.data = (void *)MDP_COMP_MERGE2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-merge3",
+		.data = (void *)MDP_COMP_MERGE3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tdshp0",
+		.data = (void *)MDP_COMP_TDSHP0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tdshp1",
+		.data = (void *)MDP_COMP_TDSHP1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tdshp2",
+		.data = (void *)MDP_COMP_TDSHP2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tdshp3",
+		.data = (void *)MDP_COMP_TDSHP3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-color0",
+		.data = (void *)MDP_COMP_COLOR0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-color1",
+		.data = (void *)MDP_COMP_COLOR1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-color2",
+		.data = (void *)MDP_COMP_COLOR2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-color3",
+		.data = (void *)MDP_COMP_COLOR3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-ovl0",
+		.data = (void *)MDP_COMP_OVL0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-ovl1",
+		.data = (void *)MDP_COMP_OVL1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-pad0",
+		.data = (void *)MDP_COMP_PAD0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-pad1",
+		.data = (void *)MDP_COMP_PAD1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-pad2",
+		.data = (void *)MDP_COMP_PAD2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-pad3",
+		.data = (void *)MDP_COMP_PAD3,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tcc0",
+		.data = (void *)MDP_COMP_TCC0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-tcc1",
+		.data = (void *)MDP_COMP_TCC1,
 	},
 	{}
 };
@@ -936,12 +1056,36 @@ static const struct of_device_id mdp_sub_comp_dt_ids[] = {
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-exto",
 		.data = (void *)MDP_COMP_ISP_IMGO,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path1",
+		.data = (void *)MDP_COMP_VPP0_SOUT,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path2",
+		.data = (void *)MDP_COMP_VPP1_SOUT,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path3",
+		.data = (void *)MDP_COMP_VDO0DL0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path4",
+		.data = (void *)MDP_COMP_VDO1DL0,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path5",
+		.data = (void *)MDP_COMP_VDO0DL1,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-path6",
+		.data = (void *)MDP_COMP_VDO1DL1,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-dl1",
 		.data = (void *)MDP_COMP_CAMIN,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-dl2",
 		.data = (void *)MDP_COMP_CAMIN2,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-dl1",
+		.data = (void *)MDP_COMP_CAMIN,
+	}, {
+		.compatible = "mediatek,mt8195-mdp3-dl2",
+		.data = (void *)MDP_COMP_CAMIN2,
 	},
 	{}
 };
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
index 57f5ca3052ba..05a60771d4bc 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
@@ -93,12 +93,12 @@ enum mdp_comp_event {
 	WROT1_SOF,
 	WROT2_SOF,
 	WROT3_SOF,
-	RDMA1_FRAME_DONE,
-	RDMA2_FRAME_DONE,
-	RDMA3_FRAME_DONE,
-	WROT1_FRAME_DONE,
-	WROT2_FRAME_DONE,
-	WROT3_FRAME_DONE,
+	RDMA1_DONE,
+	RDMA2_DONE,
+	RDMA3_DONE,
+	WROT1_DONE,
+	WROT2_DONE,
+	WROT3_DONE,
 
 	ISP_P2_0_DONE,
 	ISP_P2_1_DONE,
@@ -159,6 +159,16 @@ struct mdp_comp_data {
 	struct mdp_mutex_info mutex;
 };
 
+struct hyfbc_init_info {
+	bool is10b;
+	u32 width_in_mb;
+	u32 height_in_mb;
+	u32 w_stride_in_mb;
+	u32 h_stride_in_mb;
+	u32 byte_per_mb;
+	u32 pa_base;
+};
+
 struct mdp_comp_ops;
 
 struct mdp_comp {
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
index a646e99e410f..bef8da6fff1c 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
@@ -15,6 +15,7 @@
 #include "mtk-mdp3-core.h"
 #include "mtk-mdp3-m2m.h"
 #include "mt8183_mdp.h"
+#include "mt8195_mdp.h"
 
 static const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
 	.mdp_cfg = &mt8183_plat_cfg,
@@ -27,6 +28,18 @@ static const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
 	.format_len = ARRAY_SIZE(mt8183_formats),
 };
 
+static const struct mtk_mdp_driver_data mt8195_mdp_driver_data = {
+	.mdp_cfg = &mt8195_plat_cfg,
+	.event = mt8195_mdp_event,
+	.event_len = ARRAY_SIZE(mt8195_mdp_event),
+	.comp_data = mt8195_mdp_comp_data,
+	.pipe_info = mt8195_pipe_info,
+	.pipe_info_len = ARRAY_SIZE(mt8195_pipe_info),
+	.format = mt8195_formats,
+	.format_len = ARRAY_SIZE(mt8195_formats),
+	.config_table = mt8195_mdp_mmsys_config_table,
+};
+
 static const struct of_device_id mdp_of_ids[] = {
 	{ .compatible = "mediatek,mt8183-mdp3",
 	  .data = &mt8183_mdp_driver_data,
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index 119af7666b59..c668e317f947 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -28,8 +28,19 @@ struct mdp_platform_config {
 	bool	rdma_support_10bit;
 	bool	rdma_rsz1_sram_sharing;
 	bool	rdma_upsample_repeat_only;
+	bool	rdma_support_extend_ufo;
+	bool	rdma_support_hyfbc;
+	bool	rdma_support_afbc;
+	bool	rdma_esl_setting;
 	bool	rsz_disable_dcm_small_sample;
+	bool	rsz_etc_control;
+	bool	tdshp_1_1;
 	bool	wrot_filter_constraint;
+	bool	wrot_support_afbc;
+	bool	wrot_support_10bit;
+	bool	mdp_version_6885;
+	bool	mdp_version_8195;
+	u8	tdshp_dyn_contrast_version;
 	u32	gce_event_offset;
 	bool	support_multi_larb;
 };
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 0fdc1b228227..4a25f86bfaa5 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -51,6 +51,73 @@
 enum mdp_color {
 	MDP_COLOR_UNKNOWN	= 0,
 
+	//MDP_COLOR_FULLG8,
+	MDP_COLOR_FULLG8_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0,  8, 2,  0, 21),
+	MDP_COLOR_FULLG8_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1,  8, 2,  0, 21),
+	MDP_COLOR_FULLG8_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0,  8, 2,  0, 21),
+	MDP_COLOR_FULLG8_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1,  8, 2,  0, 21),
+	MDP_COLOR_FULLG8	= MDP_COLOR_FULLG8_BGGR,
+
+	//MDP_COLOR_FULLG10,
+	MDP_COLOR_FULLG10_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 10, 2,  0, 21),
+	MDP_COLOR_FULLG10_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 10, 2,  0, 21),
+	MDP_COLOR_FULLG10_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 10, 2,  0, 21),
+	MDP_COLOR_FULLG10_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 10, 2,  0, 21),
+	MDP_COLOR_FULLG10	= MDP_COLOR_FULLG10_BGGR,
+
+	//MDP_COLOR_FULLG12,
+	MDP_COLOR_FULLG12_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 12, 2,  0, 21),
+	MDP_COLOR_FULLG12_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 12, 2,  0, 21),
+	MDP_COLOR_FULLG12_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 12, 2,  0, 21),
+	MDP_COLOR_FULLG12_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 12, 2,  0, 21),
+	MDP_COLOR_FULLG12	= MDP_COLOR_FULLG12_BGGR,
+
+	//MDP_COLOR_FULLG14,
+	MDP_COLOR_FULLG14_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 14, 2,  0, 21),
+	MDP_COLOR_FULLG14_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 14, 2,  0, 21),
+	MDP_COLOR_FULLG14_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 14, 2,  0, 21),
+	MDP_COLOR_FULLG14_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 14, 2,  0, 21),
+	MDP_COLOR_FULLG14	= MDP_COLOR_FULLG14_BGGR,
+
+	MDP_COLOR_UFO10		= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 10, 2,  0, 24),
+
+	//MDP_COLOR_BAYER8,
+	MDP_COLOR_BAYER8_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0,  8, 2,  0, 20),
+	MDP_COLOR_BAYER8_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1,  8, 2,  0, 20),
+	MDP_COLOR_BAYER8_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0,  8, 2,  0, 20),
+	MDP_COLOR_BAYER8_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1,  8, 2,  0, 20),
+	MDP_COLOR_BAYER8	= MDP_COLOR_BAYER8_BGGR,
+
+	//MDP_COLOR_BAYER10,
+	MDP_COLOR_BAYER10_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 10, 2,  0, 20),
+	MDP_COLOR_BAYER10_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 10, 2,  0, 20),
+	MDP_COLOR_BAYER10_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 10, 2,  0, 20),
+	MDP_COLOR_BAYER10_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 10, 2,  0, 20),
+	MDP_COLOR_BAYER10	= MDP_COLOR_BAYER10_BGGR,
+
+	//MDP_COLOR_BAYER12,
+	MDP_COLOR_BAYER12_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 12, 2,  0, 20),
+	MDP_COLOR_BAYER12_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 12, 2,  0, 20),
+	MDP_COLOR_BAYER12_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 12, 2,  0, 20),
+	MDP_COLOR_BAYER12_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 12, 2,  0, 20),
+	MDP_COLOR_BAYER12	= MDP_COLOR_BAYER12_BGGR,
+
+	//MDP_COLOR_BAYER14,
+	MDP_COLOR_BAYER14_RGGB	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 14, 2,  0, 20),
+	MDP_COLOR_BAYER14_GRBG	= MDP_COLOR(0, 0, 0, 0, 1, 0, 1, 14, 2,  0, 20),
+	MDP_COLOR_BAYER14_GBRG	= MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 14, 2,  0, 20),
+	MDP_COLOR_BAYER14_BGGR	= MDP_COLOR(0, 0, 0, 0, 1, 1, 1, 14, 2,  0, 20),
+	MDP_COLOR_BAYER14	= MDP_COLOR_BAYER14_BGGR,
+
+	MDP_COLOR_RGB48		= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 48, 0,  0, 23),
+	/* For bayer+mono raw-16 */
+	MDP_COLOR_RGB565_RAW	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 16, 2,  0, 0),
+
+	MDP_COLOR_BAYER8_UNPAK	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0,  8, 2,  0, 22),
+	MDP_COLOR_BAYER10_UNPAK	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 10, 2,  0, 22),
+	MDP_COLOR_BAYER12_UNPAK	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 12, 2,  0, 22),
+	MDP_COLOR_BAYER14_UNPAK	= MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 14, 2,  0, 22),
+
 	// Unified format
 	MDP_COLOR_GREY           = MDP_COLOR(0, 0, 0, 0, 1, 0, 0,  8, 1,  0, 7),
 
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:53 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:53 +0800
Subject: [PATCH v1 13/14] arm64: dts: mt8195: add mdp3 node
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-14-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add mdp3 node.

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 633 +++++++++++++++++++++++
 1 file changed, 633 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index ded98ff7b724..89600116ff26 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1245,9 +1245,261 @@
 		vppsys0: syscon at 14000000 {
 			compatible = "mediatek,mt8195-vppsys0", "syscon";
 			reg = <0 0x14000000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		mdp3_rdma0: mdp_rdma0 at 14001000 {
+			compatible = "mediatek,mt8195-mdp3",
+						"mediatek,mt8183-mdp3-rdma0";
+			mediatek,scp = <&scp>;
+			mdp3-comps = "mediatek,mt8195-mdp3-path1", "mediatek,mt8195-mdp3-path2",
+				     "mediatek,mt8195-mdp3-path3", "mediatek,mt8195-mdp3-path4",
+				     "mediatek,mt8195-mdp3-path5", "mediatek,mt8195-mdp3-path6",
+				     "mediatek,mt8195-mdp3-dl1", "mediatek,mt8195-mdp3-dl2";
+			reg = <0 0x14001000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x1000 0x1000>;
+			interrupts = <GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>,
+							<&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+			iommus = <&iommu_vpp M4U_PORT_L4_MDP_RDMA>,
+				 <&iommu_vpp M4U_PORT_L4_MDP_WROT>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			dma-ranges = <0x2 0x0 0x0 0x40000000 0x1 0x0>; /* 8G - 12G IOVA*/
+			clocks = <&vppsys0 CLK_VPP0_MDP_RDMA>,
+					<&topckgen CLK_TOP_CFG_VPP0>,
+					<&topckgen CLK_TOP_CFG_26M_VPP0>,
+					<&vppsys0 CLK_VPP0_WARP0_ASYNC_TX>,
+					<&vppsys0 CLK_VPP0_WARP0_RELAY>,
+					<&vppsys0 CLK_VPP0_WARP0_MDP_DL_ASYNC>,
+					<&vppsys0 CLK_VPP0_WARP1_ASYNC_TX>,
+					<&vppsys0 CLK_VPP0_WARP1_RELAY>,
+					<&vppsys0 CLK_VPP0_WARP1_MDP_DL_ASYNC>,
+					<&vppsys0 CLK_VPP0_VPP02VPP1_RELAY>,
+					<&vppsys1 CLK_VPP1_DL_ASYNC>,
+					<&vppsys1 CLK_VPP1_VPP0_DL_ASYNC>,
+					<&vppsys1 CLK_VPP1_VPP0_DL_RELAY>,
+					<&vppsys0 CLK_VPP0_VPP12VPP0_ASYNC>,
+					<&vppsys1 CLK_VPP1_VPP0_DL1_RELAY>,
+					<&vppsys1 CLK_VPP1_SVPP2_VDO0_DL_RELAY>,
+					<&vppsys1 CLK_VPP1_SVPP3_VDO1_DL_RELAY>,
+					<&vppsys1 CLK_VPP1_SVPP2_VDO1_DL_RELAY>,
+					<&vppsys1 CLK_VPP1_SVPP3_VDO0_DL_RELAY>;
+			clock-names = "MDP_RDMA0",
+						"TOP_CFG_VPP0",
+						"TOP_CFG_26M_VPP0",
+						"WARP0_ASYNC_TX",
+						"WARP0_RELAY",
+						"WARP0_MDP_DL_ASYNC",
+						"WARP1_ASYNC_TX",
+						"WARP1_RELAY",
+						"WARP1_MDP_DL_ASYNC",
+						"VPP02VPP1_RELAY",
+						"VPP0_DL_ASYNC_VPP1",
+						"VPP0_DL_ASYNC_VPP0",
+						"VPP0_DL_RELAY",
+						"VPP12VPP0_ASYNC",
+						"VPP0_DL1_RELAY",
+						"SVPP2_VDO0_DL_RELAY",
+						"SVPP3_VDO1_DL_RELAY",
+						"SVPP2_VDO1_DL_RELAY",
+						"SVPP3_VDO0_DL_RELAY";
+			mediatek,mmsys2 = <&vppsys1>;
+			mediatek,mm-mutex2 = <&vpp1_mutex>;
+			mediatek,mmsys = <&vppsys0>;
+			mediatek,mm-mutex   = <&vpp0_mutex>;
+			mboxes =
+				<&gce1 12 CMDQ_THR_PRIO_1>,
+				<&gce1 13 CMDQ_THR_PRIO_1>,
+				<&gce1 14 CMDQ_THR_PRIO_1>,
+				<&gce1 21 CMDQ_THR_PRIO_1>,
+				<&gce1 22 CMDQ_THR_PRIO_1>;
+			mdp3-rdma0  = <&mdp3_rdma0>;
+			mdp3-rdma1  = <&svpp1_mdp3_rdma>;
+			mdp3-rdma2  = <&svpp2_mdp3_rdma>;
+			mdp3-rdma3  = <&svpp3_mdp3_rdma>;
+			mdp3-stitch = <&mdp3_stitch0>;
+			mdp3-rsz0   = <&mdp3_rsz0>;
+			mdp3-rsz1   = <&svpp1_mdp3_rsz>;
+			mdp3-rsz2   = <&svpp2_mdp3_rsz>;
+			mdp3-rsz3   = <&svpp3_mdp3_rsz>;
+			mdp3-wrot0  = <&mdp3_wrot0>;
+			mdp3-wrot1  = <&svpp1_mdp3_wrot>;
+			mdp3-wrot2  = <&svpp2_mdp3_wrot>;
+			mdp3-wrot3  = <&svpp3_mdp3_wrot>;
+			mdp3-tdshp0 = <&mdp3_tdshp0>;
+			mdp3-tdshp1 = <&svpp1_mdp3_tdshp>;
+			mdp3-tdshp2 = <&svpp2_mdp3_tdshp>;
+			mdp3-tdshp3 = <&svpp3_mdp3_tdshp>;
+			mdp3-aal0   = <&mdp3_aal0>;
+			mdp3-aal1   = <&svpp1_mdp3_aal>;
+			mdp3-aal2   = <&svpp2_mdp3_aal>;
+			mdp3-aal3   = <&svpp3_mdp3_aal>;
+			mdp3-color0 = <&mdp3_color0>;
+			mdp3-color1 = <&svpp1_mdp3_color>;
+			mdp3-color2 = <&svpp2_mdp3_color>;
+			mdp3-color3 = <&svpp3_mdp3_color>;
+			mdp3-hdr0   = <&mdp3_hdr0>;
+			mdp3-hdr1   = <&svpp1_mdp3_hdr>;
+			mdp3-hdr2   = <&svpp2_mdp3_hdr>;
+			mdp3-hdr3   = <&svpp3_mdp3_hdr>;
+			mdp3-fg0    = <&mdp3_fg0>;
+			mdp3-fg1    = <&svpp1_mdp3_fg>;
+			mdp3-fg2    = <&svpp2_mdp3_fg>;
+			mdp3-fg3    = <&svpp3_mdp3_fg>;
+			mdp3-tcc0   = <&mdp3_tcc0>;
+			mdp3-tcc1   = <&svpp1_mdp3_tcc>;
+			mdp3-ovl0   = <&mdp3_ovl0>;
+			mdp3-ovl1   = <&svpp1_mdp3_ovl>;
+			mdp3-pad0   = <&mdp3_pad0>;
+			mdp3-pad1   = <&svpp1_mdp3_pad>;
+			mdp3-pad2   = <&svpp2_mdp3_pad>;
+			mdp3-pad3   = <&svpp3_mdp3_pad>;
+			mdp3-split  = <&vpp_split0>;
+			mdp3-merge2 = <&svpp2_mdp3_merge>;
+			mdp3-merge3 = <&svpp3_mdp3_merge>;
+		};
+
+		mdp3_fg0: mdp_fg0 at 14002000 {
+			compatible = "mediatek,mt8195-mdp3-fg0";
+			reg = <0 0x14002000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x2000 0x1000>;
+			interrupts = <GIC_SPI 579 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_FG>;
+			clock-names = "MDP_FG0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_stitch0: mdp_stich0 at 14003000 {
+			compatible = "mediatek,mt8195-mdp3-stitch";
+			reg = <0 0x14003000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x3000 0x1000>;
+			interrupts = <GIC_SPI 580 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_STITCH>;
+			clock-names = "MDP_STITCH";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_hdr0: mdp_hdr0 at 14004000 {
+			compatible = "mediatek,mt8195-mdp3-hdr0";
+			reg = <0 0x14004000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x4000 0x1000>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_HDR>;
+			clock-names = "MDP_HDR0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_aal0: mdp_aal0 at 14005000 {
+			compatible = "mediatek,mt8195-mdp3-aal0";
+			reg = <0 0x14005000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x5000 0x1000>;
+			interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_AAL>;
+			clock-names = "MDP_AAL0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_rsz0: mdp_rsz0 at 14006000 {
+			compatible = "mediatek,mt8183-mdp3-rsz0";
+			reg = <0 0x14006000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x6000 0x1000>;
+			interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_RSZ>;
+			clock-names = "MDP_RSZ0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_tdshp0: mdp_tdshp0 at 14007000 {
+			compatible = "mediatek,mt8195-mdp3-tdshp0";
+			reg = <0 0x14007000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x7000 0x1000>;
+			interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_TDSHP>;
+			clock-names = "MDP_TDSHP0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_color0: mdp_color0 at 14008000 {
+			compatible = "mediatek,mt8195-mdp3-color0";
+			reg = <0 0x14008000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x8000 0x1000>;
+			interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_COLOR>;
+			clock-names = "MDP_COLOR0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_ovl0: mdp_ovl0 at 14009000 {
+			compatible = "mediatek,mt8195-mdp3-ovl0";
+			reg = <0 0x14009000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0x9000 0x1000>;
+			interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_OVL>;
+			clock-names = "MDP_OVL0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_pad0: mdp_pad0 at 1400a000 {
+			compatible = "mediatek,mt8195-mdp3-pad0";
+			reg = <0 0x1400a000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xa000 0x1000>;
+			interrupts = <GIC_SPI 588 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_PADDING>;
+			clock-names = "MDP_PAD0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_tcc0: mdp_tcc0 at 1400b000 {
+			compatible = "mediatek,mt8195-mdp3-tcc0";
+			reg = <0 0x1400b000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xb000 0x1000>;
+			interrupts = <GIC_SPI 589 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_TCC>;
+			clock-names = "MDP_TCC0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		mdp3_wrot0: mdp_wrot0 at 1400c000 {
+			compatible = "mediatek,mt8183-mdp3-wrot0";
+			reg = <0 0x1400c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xc000 0x1000>;
+			interrupts = <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys0 CLK_VPP0_MDP_WROT>;
+			clock-names = "MDP_WROT0";
+			iommus = <&iommu_vpp M4U_PORT_L4_MDP_WROT>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+		};
+
+		vpp0_mutex: vpp0_mutex at 1400f000 {
+			compatible = "mediatek,mt8195-vpp0-mutex";
+			reg = <0 0x1400f000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0xf000 0x1000>;
+			interrupts = <GIC_SPI 592 IRQ_TYPE_LEVEL_HIGH 0>;
+			#clocks = <&vppsys0 CLK_VPP0_MUTEX>;
+			#clock-names = "MDP_MUTEX0";
+			clocks = <&vppsys0 CLK_VPP0_MUTEX>;
+			clock-names = "MDP_MUTEX0";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS0>;
+			mediatek,gce-events = <CMDQ_EVENT_VPP0_MDP_RDMA_SOF>,
+					<CMDQ_EVENT_VPP0_MDP_WROT_SOF>,
+					<CMDQ_EVENT_VPP0_MDP_RDMA_FRAME_DONE>,
+					<CMDQ_EVENT_VPP0_MDP_WROT_VIDO_WDONE>,
+					<CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_SOF>,
+					<CMDQ_EVENT_VPP1_SVPP1_MDP_RDMA_FRAME_DONE>,
+					<CMDQ_EVENT_VPP1_SVPP2_MDP_RDMA_FRAME_DONE>,
+					<CMDQ_EVENT_VPP1_SVPP3_MDP_RDMA_FRAME_DONE>,
+					<CMDQ_EVENT_VPP1_SVPP1_MDP_WROT_FRAME_DONE>,
+					<CMDQ_EVENT_VPP1_SVPP2_MDP_WROT_FRAME_DONE>,
+					<CMDQ_EVENT_VPP1_SVPP3_MDP_WROT_FRAME_DONE>;
+		};
+
 		wpesys: clock-controller at 14e00000 {
 			compatible = "mediatek,mt8195-wpesys";
 			reg = <0 0x14e00000 0 0x1000>;
@@ -1269,9 +1521,390 @@
 		vppsys1: syscon at 14f00000 {
 			compatible = "mediatek,mt8195-vppsys1", "syscon";
 			reg = <0 0x14f00000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0 0x1000>;
 			#clock-cells = <1>;
 		};
 
+		vpp1_mutex: vpp1_mutex at 14f01000 {
+			compatible = "mediatek,mt8195-vpp1-mutex";
+			reg = <0 0x14f01000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x1000 0x1000>;
+			interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+			#clocks = <&vppsys1 CLK_VPP1_DISP_MUTEX>;
+			#clock-names = "DISP_MUTEX";
+			clocks = <&vppsys1 CLK_VPP1_DISP_MUTEX>;
+			clock-names = "DISP_MUTEX";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		vpp_split0: vpp_split0 at 14f06000 {
+			compatible = "mediatek,mt8195-mdp3-split";
+			reg = <0 0x14f06000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x6000 0x1000>;
+			interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH 0>,
+				<GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_VPP_SPLIT>,
+					<&vppsys1 CLK_VPP1_HDMI_META>,
+					<&vppsys1 CLK_VPP1_VPP_SPLIT_HDMI>,
+					<&vppsys1 CLK_VPP1_DGI_IN>,
+					<&vppsys1 CLK_VPP1_DGI_OUT>,
+					<&vppsys1 CLK_VPP1_VPP_SPLIT_DGI>,
+					<&vppsys1 CLK_VPP1_VPP_SPLIT_26M>;
+			clock-names = "MDP_SPLIT",
+						"HDMI_META",
+						"SPLIT_HDMI",
+						"DGI_IN",
+						"DGI_OUT",
+						"SPLIT_DGI",
+						"VPP_SPLIT_26M";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_tcc: svpp1_mdp_tcc at 14f07000 {
+			compatible = "mediatek,mt8195-mdp3-tcc1";
+			reg = <0 0x14f07000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x7000 0x1000>;
+			interrupts = <GIC_SPI 607 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_TCC>;
+			clock-names = "MDP_TCC1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_rdma: svpp1_mdp_rdma at 14f08000 {
+			compatible = "mediatek,mt8195-mdp3",
+				 "mediatek,mt8195-mdp3-rdma1";
+			reg = <0 0x14f08000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x8000 0x1000>;
+			interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_RDMA>,
+					<&topckgen CLK_TOP_CFG_VPP1>,
+					<&topckgen CLK_TOP_CFG_26M_VPP1>;
+			clock-names = "MDP_RDMA1",
+						"TOP_CFG_VPP1",
+						"TOP_CFG_26M_VPP1";
+			iommus = <&iommu_vdo M4U_PORT_L5_SVPP1_MDP_RDMA>,
+				 <&iommu_vdo M4U_PORT_L5_SVPP1_MDP_WROT>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			dma-ranges = <0x2 0x0 0x0 0x40000000 0x1 0x0>; /* 8G - 12G IOVA*/
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_rdma: svpp2_mdp_rdma at 14f09000 {
+			compatible = "mediatek,mt8195-mdp3",
+				 "mediatek,mt8195-mdp3-rdma2";
+			reg = <0 0x14f09000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0x9000 0x1000>;
+			interrupts = <GIC_SPI 609 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_RDMA>,
+					<&topckgen CLK_TOP_CFG_VPP1>,
+					<&topckgen CLK_TOP_CFG_26M_VPP1>;
+			clock-names = "MDP_RDMA2",
+						"TOP_CFG_VPP1",
+						"TOP_CFG_26M_VPP1";
+			iommus = <&iommu_vdo M4U_PORT_L5_SVPP2_MDP_RDMA>,
+				 <&iommu_vdo M4U_PORT_L5_SVPP2_MDP_WROT>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			dma-ranges = <0x2 0x0 0x0 0x40000000 0x1 0x0>; /* 8G - 12G IOVA*/
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_rdma: svpp3_mdp_rdma at 14f0a000 {
+			compatible = "mediatek,mt8195-mdp3",
+				 "mediatek,mt8195-mdp3-rdma3";
+			reg = <0 0x14f0a000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xa000 0x1000>;
+			interrupts = <GIC_SPI 610 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_RDMA>,
+					<&topckgen CLK_TOP_CFG_VPP1>,
+					<&topckgen CLK_TOP_CFG_26M_VPP1>;
+			clock-names = "MDP_RDMA3",
+						"TOP_CFG_VPP1",
+						"TOP_CFG_26M_VPP1";
+			iommus = <&iommu_vpp M4U_PORT_L6_SVPP3_MDP_RDMA>,
+				 <&iommu_vpp M4U_PORT_L6_SVPP3_MDP_WROT>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			dma-ranges = <0x2 0x0 0x0 0x40000000 0x1 0x0>; /* 8G - 12G IOVA*/
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_fg: svpp1_mdp_fg at 14f0b000 {
+			compatible = "mediatek,mt8195-mdp3-fg1";
+			reg = <0 0x14f0b000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xb000 0x1000>;
+			interrupts = <GIC_SPI 611 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_FG>;
+			clock-names = "MDP_FG1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_fg: svpp2_mdp_fg at 14f0c000 {
+			compatible = "mediatek,mt8195-mdp3-fg2";
+			reg = <0 0x14f0c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xc000 0x1000>;
+			interrupts = <GIC_SPI 612 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_FG>;
+			clock-names = "MDP_FG2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_fg: svpp3_mdp_fg at 14f0d000 {
+			compatible = "mediatek,mt8195-mdp3-fg3";
+			reg = <0 0x14f0d000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xd000 0x1000>;
+			interrupts = <GIC_SPI 613 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_FG>;
+			clock-names = "MDP_FG3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_hdr: svpp1_mdp_hdr at 14f0e000 {
+			compatible = "mediatek,mt8195-mdp3-hdr1";
+			reg = <0 0x14f0e000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xe000 0x1000>;
+			interrupts = <GIC_SPI 614 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_HDR>;
+			clock-names = "MDP_HDR1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_hdr: svpp2_mdp_hdr at 14f0f000 {
+			compatible = "mediatek,mt8195-mdp3-hdr2";
+			reg = <0 0x14f0f000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0xf000 0x1000>;
+			interrupts = <GIC_SPI 615 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_HDR>;
+			clock-names = "MDP_HDR2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_hdr: svpp3_mdp_hdr at 14f10000 {
+			compatible = "mediatek,mt8195-mdp3-hdr3";
+			reg = <0 0x14f10000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0 0x1000>;
+			interrupts = <GIC_SPI 616 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_HDR>;
+			clock-names = "MDP_HDR3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_aal: svpp1_mdp_aal at 14f11000 {
+			compatible = "mediatek,mt8195-mdp3-aal1";
+			reg = <0 0x14f11000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x1000 0x1000>;
+			interrupts = <GIC_SPI 617 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_AAL>;
+			clock-names = "MDP_AAL1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_aal: svpp2_mdp_aal at 14f12000 {
+			compatible = "mediatek,mt8195-mdp3-aal2";
+			reg = <0 0x14f12000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x2000 0x1000>;
+			interrupts = <GIC_SPI 618 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_AAL>;
+			clock-names = "MDP_AAL2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_aal: svpp3_mdp_aal at 14f13000 {
+			compatible = "mediatek,mt8195-mdp3-aal3";
+			reg = <0 0x14f13000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x3000 0x1000>;
+			interrupts = <GIC_SPI 619 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_AAL>;
+			clock-names = "MDP_AAL3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_rsz: svpp1_mdp_rsz at 14f14000 {
+			compatible = "mediatek,mt8183-mdp3-rsz1";
+			reg = <0 0x14f14000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x4000 0x1000>;
+			interrupts = <GIC_SPI 620 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_RSZ>;
+			clock-names = "MDP_RSZ1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_rsz: svpp2_mdp_rsz at 14f15000 {
+			compatible = "mediatek,mt8195-mdp3-rsz2";
+			reg = <0 0x14f15000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x5000 0x1000>;
+			interrupts = <GIC_SPI 621 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_RSZ>,
+					<&vppsys1 CLK_VPP1_SVPP2_VPP_MERGE>;
+			clock-names = "MDP_RSZ2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_rsz: svpp3_mdp_rsz at 14f16000 {
+			compatible = "mediatek,mt8195-mdp3-rsz3";
+			reg = <0 0x14f16000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x6000 0x1000>;
+			interrupts = <GIC_SPI 622 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_RSZ>,
+					<&vppsys1 CLK_VPP1_SVPP3_VPP_MERGE>;
+			clock-names = "MDP_RSZ3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_tdshp: svpp1_mdp_tdshp at 14f17000 {
+			compatible = "mediatek,mt8195-mdp3-tdshp1";
+			reg = <0 0x14f17000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x7000 0x1000>;
+			interrupts = <GIC_SPI 623 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_TDSHP>;
+			clock-names = "MDP_TDSHP1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_tdshp: svpp2_mdp_tdshp at 14f18000 {
+			compatible = "mediatek,mt8195-mdp3-tdshp2";
+			reg = <0 0x14f18000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x8000 0x1000>;
+			interrupts = <GIC_SPI 624 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_TDSHP>;
+			clock-names = "MDP_TDSHP2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_tdshp: svpp3_mdp_tdshp at 14f19000 {
+			compatible = "mediatek,mt8195-mdp3-tdshp3";
+			reg = <0 0x14f19000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0x9000 0x1000>;
+			interrupts = <GIC_SPI 625 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_TDSHP>;
+			clock-names = "MDP_TDSHP3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_merge: svpp2_mdp_merge at 14f1a000 {
+			compatible = "mediatek,mt8195-mdp3-merge2";
+			reg = <0 0x14f1a000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xa000 0x1000>;
+			interrupts = <GIC_SPI 626 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_VPP_MERGE>;
+			clock-names = "MDP_MERGE2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_merge: svpp3_mdp_merge at 14f1b000 {
+			compatible = "mediatek,mt8195-mdp3-merge3";
+			reg = <0 0x14f1b000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xb000 0x1000>;
+			interrupts = <GIC_SPI 627 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_VPP_MERGE>;
+			clock-names = "MDP_MERGE3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_color: svpp1_mdp_color at 14f1c000 {
+			compatible = "mediatek,mt8195-mdp3-color1";
+			reg = <0 0x14f1c000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xc000 0x1000>;
+			interrupts = <GIC_SPI 628 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_COLOR>;
+			clock-names = "MDP_COLOR1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_color: svpp2_mdp_color at 14f1d000 {
+			compatible = "mediatek,mt8195-mdp3-color2";
+			reg = <0 0x14f1d000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xd000 0x1000>;
+			interrupts = <GIC_SPI 629 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_COLOR>;
+			clock-names = "MDP_COLOR2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_color: svpp3_mdp_color at 14f1e000 {
+			compatible = "mediatek,mt8195-mdp3-color3";
+			reg = <0 0x14f1e000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xe000 0x1000>;
+			interrupts = <GIC_SPI 630 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_COLOR>;
+			clock-names = "MDP_COLOR3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_ovl: svpp1_mdp_ovl at 14f1f000 {
+			compatible = "mediatek,mt8195-mdp3-ovl1";
+			reg = <0 0x14f1f000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f1XXXX 0xf000 0x1000>;
+			interrupts = <GIC_SPI 631 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_OVL>;
+			clock-names = "MDP_OVL1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_pad: svpp1_mdp_pad at 14f20000 {
+			compatible = "mediatek,mt8195-mdp3-pad1";
+			reg = <0 0x14f20000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0 0x1000>;
+			interrupts = <GIC_SPI 632 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_VPP_PAD>;
+			clock-names = "MDP_PAD1";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_pad: svpp2_mdp_pad at 14f21000 {
+			compatible = "mediatek,mt8195-mdp3-pad2";
+			reg = <0 0x14f21000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x1000 0x1000>;
+			interrupts = <GIC_SPI 633 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_VPP_PAD>;
+			clock-names = "MDP_PAD2";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_pad: svpp3_mdp_pad at 14f22000 {
+			compatible = "mediatek,mt8195-mdp3-pad3";
+			reg = <0 0x14f22000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x2000 0x1000>;
+			interrupts = <GIC_SPI 634 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_VPP_PAD>;
+			clock-names = "MDP_PAD3";
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp1_mdp3_wrot: svpp1_mdp_wrot at 14f23000 {
+			compatible = "mediatek,mt8195-mdp3-wrot1";
+			reg = <0 0x14f23000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x3000 0x1000>;
+			interrupts = <GIC_SPI 635 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP1_MDP_WROT>;
+			clock-names = "MDP_WROT1";
+			iommus = <&iommu_vdo M4U_PORT_L5_SVPP1_MDP_WROT>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp2_mdp3_wrot: svpp2_mdp_wrot at 14f24000 {
+			compatible = "mediatek,mt8195-mdp3-wrot2";
+			reg = <0 0x14f24000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x4000 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP2_MDP_WROT>;
+			clock-names = "MDP_WROT2";
+			iommus = <&iommu_vdo M4U_PORT_L5_SVPP2_MDP_WROT>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
+		svpp3_mdp3_wrot: svpp3_mdp_wrot at 14f25000 {
+			compatible = "mediatek,mt8195-mdp3-wrot3";
+			reg = <0 0x14f25000 0 0x1000>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f2XXXX 0x5000 0x1000>;
+			interrupts = <GIC_SPI 637 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&vppsys1 CLK_VPP1_SVPP3_MDP_WROT>;
+			clock-names = "MDP_WROT3";
+			iommus = <&iommu_vpp M4U_PORT_L6_SVPP3_MDP_WROT>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VPPSYS1>;
+		};
+
 		imgsys: clock-controller at 15000000 {
 			compatible = "mediatek,mt8195-imgsys";
 			reg = <0 0x15000000 0 0x1000>;
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:49 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:49 +0800
Subject: [PATCH v1 09/14] media: platform: mtk-mdp3: Add support MT8195
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-10-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add support MT8195

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   | 438 ++++++++++++++++--
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 345 +++++++++++++-
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |   3 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  67 ++-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |   2 +
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |   6 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   |  86 +++-
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   |   2 +
 8 files changed, 883 insertions(+), 66 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
index 879a120f78d9..ce9326cc790f 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
@@ -5,12 +5,15 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/kernel.h>
 #include "mtk-mdp3-cmdq.h"
 #include "mtk-mdp3-comp.h"
 #include "mtk-mdp3-core.h"
 #include "mtk-mdp3-m2m.h"
 
 #define MDP_PATH_MAX_COMPS	IMG_MAX_COMPONENTS
+#define BYTE_PER_MB_Y				(4)
+#define BYTE_PER_MB_C				(2)
 
 struct mdp_path {
 	struct mdp_dev		*mdp_dev;
@@ -26,12 +29,18 @@ struct mdp_path {
 	((ctx)->comp->ops && (ctx)->comp->ops->op)
 #define call_op(ctx, op, ...) \
 	(has_op(ctx, op) ? (ctx)->comp->ops->op(ctx, ##__VA_ARGS__) : 0)
-
 struct mdp_path_subfrm {
 	s32	mutex_id;
 	u32	mutex_mod;
+	u32	mutex_mod2;
 	s32	sofs[MDP_PATH_MAX_COMPS];
 	u32	num_sofs;
+
+	s32	mutex2_id;
+	u32	mutex2_mod;
+	u32	mutex2_mod2;
+	s32	sof2s[MDP_PATH_MAX_COMPS];
+	u32	num_sof2s;
 };
 
 static bool is_output_disable(const struct img_compparam *param, u32 count)
@@ -76,8 +85,11 @@ static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
 	const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
 	struct device *dev = &path->mdp_dev->pdev->dev;
 	struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
-	s32 mutex_id = -1;
+	struct mtk_mutex **mutex2 = path->mdp_dev->mdp_mutex2;
+	s32 mutex_id = MDP_PIPE_NONE;
+	s32 mutex2_id = MDP_PIPE_NONE;
 	u32 mutex_sof = 0;
+	u32 mutex2_sof = 0;
 	int index, j;
 	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
 
@@ -85,57 +97,225 @@ static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
 	memset(subfrm, 0, sizeof(*subfrm));
 
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(path->mdp_dev, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		if (is_output_disable(ctx->param, count))
 			continue;
 
 		public_id = path->comps[index].comp->public_id;
 		switch (public_id) {
-		case MDP_COMP_AAL0:
+		case MDP_COMP_ISP_IMGI:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_IMGI);
+			mutex_id = data->pipe_info[j].mutex_id;
+			break;
+		case MDP_COMP_WPEI:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI);
+			mutex_id = data->pipe_info[j].mutex_id;
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			break;
-		case MDP_COMP_CCORR0:
+		case MDP_COMP_WPEI2:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI2);
+			mutex_id = data->pipe_info[j].mutex_id;
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			break;
-		case MDP_COMP_WDMA:
+		case MDP_COMP_RDMA0:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA0);
+			mutex_id = data->pipe_info[j].mutex_id;
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
-			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WDMA;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RDMA0;
 			break;
-		case MDP_COMP_WROT0:
+		case MDP_COMP_VPP1_SOUT:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_VPP1_SOUT);
+			mutex_id = data->pipe_info[j].mutex_id;
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
-			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WROT0;
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
 			break;
-		case MDP_COMP_TDSHP0:
+		case MDP_COMP_FG0:
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
-			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_TDSHP0;
 			break;
-		case MDP_COMP_RSZ1:
+		case MDP_COMP_STITCH:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_HDR0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_AAL0:
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
-			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RSZ1;
 			break;
 		case MDP_COMP_RSZ0:
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RSZ0;
 			break;
-		case MDP_COMP_RDMA0:
-			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA0);
-			mutex_id = data->pipe_info[j].mutex_id;
+		case MDP_COMP_TDSHP0:
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
-			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RDMA0;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_TDSHP0;
 			break;
-		case MDP_COMP_ISP_IMGI:
-			j = mdp_get_mutex_idx(data, MDP_PIPE_IMGI);
-			mutex_id = data->pipe_info[j].mutex_id;
+		case MDP_COMP_COLOR0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			break;
-		case MDP_COMP_WPEI:
-			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI);
-			mutex_id = data->pipe_info[j].mutex_id;
+		case MDP_COMP_OVL0:
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			break;
-		case MDP_COMP_WPEI2:
-			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI2);
-			mutex_id = data->pipe_info[j].mutex_id;
+		case MDP_COMP_PAD0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_TCC0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_CCORR0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_WDMA:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WDMA;
+			break;
+		case MDP_COMP_WROT0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WROT0;
+			break;
+		case MDP_COMP_SPLIT:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_SPLIT);
+			mutex2_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_SPLIT;
+			mutex2_sof = data->pipe_info[j].sof;
+			break;
+		case MDP_COMP_SPLIT2:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_SPLIT2);
+			mutex2_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_SPLIT2;
+			mutex2_sof = data->pipe_info[j].sof;
+			break;
+		case MDP_COMP_RDMA1:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA1);
+			mutex2_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RDMA1;
+			break;
+		case MDP_COMP_RDMA2:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA2);
+			mutex2_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RDMA2;
+			break;
+		case MDP_COMP_RDMA3:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA3);
+			mutex2_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RDMA3;
+			break;
+		case MDP_COMP_VPP0_SOUT:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_VPP0_SOUT);
+			mutex2_id = data->pipe_info[j].mutex_id;
 			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			break;
+		case MDP_COMP_TCC1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_FG1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_FG2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_FG3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_HDR1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_HDR2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_HDR3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_AAL1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_AAL2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_AAL3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_RSZ1:
+			if (data->comp_data[public_id].mutex.mmsys_id) {
+				subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+				subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RSZ1;
+			} else {
+				subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+				subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RSZ1;
+			}
+			break;
+		case MDP_COMP_RSZ2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RSZ2;
+			break;
+		case MDP_COMP_RSZ3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_RSZ3;
+			break;
+		case MDP_COMP_TDSHP1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_TDSHP1;
+			break;
+		case MDP_COMP_TDSHP2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_TDSHP2;
+			break;
+		case MDP_COMP_TDSHP3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_TDSHP3;
+			break;
+		case MDP_COMP_COLOR1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_COLOR2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_COLOR3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_OVL1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_PAD1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_PAD2:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_PAD3:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_WROT1:
+			subfrm->mutex2_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_WROT1;
+			break;
+		case MDP_COMP_WROT2:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_WROT2;
+			break;
+		case MDP_COMP_WROT3:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			subfrm->sof2s[subfrm->num_sof2s++] = MDP_COMP_WROT3;
+			break;
+		case MDP_COMP_VDO0DL0:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			break;
+		case MDP_COMP_VDO1DL0:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			break;
+		case MDP_COMP_VDO0DL1:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
+			break;
+		case MDP_COMP_VDO1DL1:
+			subfrm->mutex2_mod2 |= data->comp_data[public_id].mutex.mod2;
 			break;
 		default:
 			break;
@@ -143,17 +323,23 @@ static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
 	}
 
 	subfrm->mutex_id = mutex_id;
-	if (-1 == mutex_id) {
+	subfrm->mutex2_id = mutex2_id;
+
+	if (mutex_id == MDP_PIPE_NONE && mutex2_id == MDP_PIPE_NONE) {
 		dev_err(dev, "No mutex assigned");
 		return -EINVAL;
 	}
 
 	/* Set mutex modules */
-	if (subfrm->mutex_mod) {
+	if (subfrm->mutex_mod || subfrm->mutex_mod2) {
 		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id], subfrm->mutex_mod,
-					  0, mutex_sof, cmd);
+					  subfrm->mutex_mod2, mutex_sof, cmd);
 	}
 
+	if (subfrm->mutex2_mod || subfrm->mutex2_mod2) {
+		mtk_mutex_add_mod_by_cmdq(mutex2[mutex2_id], subfrm->mutex2_mod,
+					  subfrm->mutex2_mod2, mutex2_sof, cmd);
+	}
 	return 0;
 }
 
@@ -163,14 +349,16 @@ static int mdp_path_subfrm_run(const struct mdp_path_subfrm *subfrm,
 {
 	struct device *dev = &path->mdp_dev->pdev->dev;
 	struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
+	struct mtk_mutex **mutex2 = path->mdp_dev->mdp_mutex2;
 	s32 mutex_id = subfrm->mutex_id;
+	s32 mutex2_id = subfrm->mutex2_id;
 
-	if (-1 == mutex_id) {
+	if (mutex_id == MDP_PIPE_NONE && mutex2_id == MDP_PIPE_NONE) {
 		dev_err(dev, "Incorrect mutex id");
 		return -EINVAL;
 	}
 
-	if (subfrm->mutex_mod) {
+	if (subfrm->mutex_mod || subfrm->mutex_mod2) {
 		int index, evt;
 
 		/* Wait WROT SRAM shared to DISP RDMA */
@@ -235,6 +423,71 @@ static int mdp_path_subfrm_run(const struct mdp_path_subfrm *subfrm,
 				MM_REG_WAIT(cmd, evt);
 		}
 	}
+
+	if (subfrm->mutex2_mod || subfrm->mutex2_mod2) {
+		int index, evt;
+
+		/* Clear SOF event for each engine */
+		for (index = 0; index < subfrm->num_sof2s; index++) {
+			switch (subfrm->sof2s[index]) {
+			case MDP_COMP_RDMA1:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA1_SOF);
+				break;
+			case MDP_COMP_RDMA2:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA2_SOF);
+				break;
+			case MDP_COMP_RDMA3:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA3_SOF);
+				break;
+			case MDP_COMP_WROT1:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT1_SOF);
+				break;
+			case MDP_COMP_WROT2:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT2_SOF);
+				break;
+			case MDP_COMP_WROT3:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT3_SOF);
+				break;
+			default:
+				evt = -1;
+				break;
+			}
+			if (evt > 0)
+				MM_REG_CLEAR(cmd, evt);
+		}
+
+		/* Enable the mutex */
+		mtk_mutex_enable_by_cmdq(mutex2[mutex2_id], cmd);
+
+		/* Wait SOF events and clear mutex modules (optional) */
+		for (index = 0; index < subfrm->num_sof2s; index++) {
+			switch (subfrm->sof2s[index]) {
+			case MDP_COMP_RDMA1:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA1_SOF);
+				break;
+			case MDP_COMP_RDMA2:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA2_SOF);
+				break;
+			case MDP_COMP_RDMA3:
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA3_SOF);
+				break;
+			case MDP_COMP_WROT1:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT1_SOF);
+				break;
+			case MDP_COMP_WROT2:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT2_SOF);
+				break;
+			case MDP_COMP_WROT3:
+				evt = mdp_get_event_idx(path->mdp_dev, WROT3_SOF);
+				break;
+			default:
+				evt = -1;
+				break;
+			}
+			if (evt > 0)
+				MM_REG_WAIT(cmd, evt);
+		}
+	}
 	return 0;
 }
 
@@ -247,6 +500,9 @@ static int mdp_path_ctx_init(struct mdp_dev *mdp, struct mdp_path *path)
 		return -EINVAL;
 
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(mdp, config->components[index].type))
+			continue;
+
 		ret = mdp_comp_ctx_init(mdp, &path->comps[index],
 					&config->components[index],
 					path->param);
@@ -276,13 +532,21 @@ static int mdp_path_config_subfrm(struct mmsys_cmdq_cmd *cmd,
 	/* Enable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
 		set = &ctrl->sets[index];
-		mmsys_dev = path->mdp_dev->mdp_mmsys;
+		if (data->mdp_cfg->mdp_version_8195) {
+			if (set->vpp_id)
+				mmsys_dev = path->mdp_dev->mdp_mmsys2;
+			else
+				mmsys_dev = path->mdp_dev->mdp_mmsys;
+		}
 
 		mtk_mmsys_write_reg_by_cmdq(mmsys_dev, cmd,
 					    set->reg, set->value, 0xFFFFFFFF);
 	}
 	/* Config sub-frame information */
 	for (index = (config->num_components - 1); index >= 0; index--) {
+		if (is_dummy_engine(path->mdp_dev, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		if (is_output_disable(ctx->param, count))
 			continue;
@@ -296,6 +560,9 @@ static int mdp_path_config_subfrm(struct mmsys_cmdq_cmd *cmd,
 		return ret;
 	/* Wait components done */
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(path->mdp_dev, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		if (is_output_disable(ctx->param, count))
 			continue;
@@ -305,6 +572,9 @@ static int mdp_path_config_subfrm(struct mmsys_cmdq_cmd *cmd,
 	}
 	/* Advance to the next sub-frame */
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(path->mdp_dev, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		ret = call_op(ctx, advance_subfrm, cmd, count);
 		if (ret)
@@ -313,7 +583,12 @@ static int mdp_path_config_subfrm(struct mmsys_cmdq_cmd *cmd,
 	/* Disable mux settings */
 	for (index = 0; index < ctrl->num_sets; index++) {
 		set = &ctrl->sets[index];
-		mmsys_dev = path->mdp_dev->mdp_mmsys;
+		if (data->mdp_cfg->mdp_version_8195) {
+			if (set->vpp_id)
+				mmsys_dev = path->mdp_dev->mdp_mmsys2;
+			else
+				mmsys_dev = path->mdp_dev->mdp_mmsys;
+		}
 
 		mtk_mmsys_write_reg_by_cmdq(mmsys_dev, cmd,
 					    set->reg, 0, 0xFFFFFFFF);
@@ -332,6 +607,9 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
 	/* Config path frame */
 	/* Reset components */
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(mdp, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		ret = call_op(ctx, init_comp, cmd);
 		if (ret)
@@ -342,6 +620,9 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
 		const struct v4l2_rect *compose =
 			path->composes[ctx->param->outputs[0]];
 
+		if (is_dummy_engine(mdp, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		ret = call_op(ctx, config_frame, cmd, compose);
 		if (ret)
@@ -356,6 +637,9 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
 	}
 	/* Post processing information */
 	for (index = 0; index < config->num_components; index++) {
+		if (is_dummy_engine(mdp, config->components[index].type))
+			continue;
+
 		ctx = &path->comps[index];
 		ret = call_op(ctx, post_process, cmd);
 		if (ret)
@@ -364,6 +648,60 @@ static int mdp_path_config(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
 	return 0;
 }
 
+static int mdp_hyfbc_config(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
+			    struct mdp_path *path, struct mdp_cmdq_param *param)
+{
+	struct device *dev = &mdp->pdev->dev;
+	const struct img_config *config = path->config;
+	struct mdp_m2m_ctx *ctx;
+	struct mdp_comp_ctx *comp_ctx = &path->comps[0];
+	const struct mdp_rdma_data *rdma = &comp_ctx->param->rdma;
+	struct hyfbc_init_info hyfbc;
+	struct mdp_frame *frame;
+	u32 wrot_id;
+	int ret;
+
+	ctx = (struct mdp_m2m_ctx *)param->mdp_ctx;
+	frame = &ctx->curr_param.output;
+
+	if (!MDP_COLOR_IS_HYFBC_COMPRESS(frame->mdp_fmt->mdp_color) ||
+	    frame->format.fmt.pix_mp.width % 32 == 0)
+		return 0;
+
+	// First engine should be rdma engine
+	if (!is_rdma(mdp, config->components[0].type)) {
+		dev_dbg(dev, "Not RDMA engine id, end patch.");
+		return 0;
+	}
+
+	wrot_id = config->components[(config->num_components - 1)].type;
+
+	hyfbc.is10b = (MDP_COLOR_IS_10BIT(frame->mdp_fmt->mdp_color));
+	hyfbc.width_in_mb = DIV_ROUND_UP(frame->format.fmt.pix_mp.width, 16);
+	hyfbc.height_in_mb = DIV_ROUND_UP(frame->format.fmt.pix_mp.height, 16);
+	hyfbc.w_stride_in_mb = DIV_ROUND_UP(ALIGN(frame->stride.width, 32), 16);
+	hyfbc.h_stride_in_mb = DIV_ROUND_UP(ALIGN(frame->stride.height, 32), 16);
+	hyfbc.byte_per_mb = BYTE_PER_MB_Y;
+	hyfbc.pa_base = rdma->ufo_dec_y;
+
+	ret = mdp_hyfbc_init(mdp, cmd, &hyfbc, wrot_id);
+	if (ret) {
+		dev_err(dev, "mdp_hyfbc_init: y patch fail.");
+		return ret;
+	}
+
+	hyfbc.byte_per_mb = BYTE_PER_MB_C;
+	hyfbc.pa_base = rdma->ufo_dec_c;
+
+	ret = mdp_hyfbc_init(mdp, cmd, &hyfbc, wrot_id);
+	if (ret) {
+		dev_err(dev, "mdp_hyfbc_init: c patch fail.");
+		return ret;
+	}
+
+	return 0;
+}
+
 static void mdp_auto_release_work(struct work_struct *work)
 {
 	struct mdp_cmdq_cb_param *cb_param;
@@ -376,6 +714,10 @@ static void mdp_auto_release_work(struct work_struct *work)
 
 	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
+
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
+	if (i >= 0)
+		mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
 	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 			    cb_param->num_comps);
 
@@ -419,6 +761,11 @@ static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
 		dev_err(dev, "%s:queue_work fail!\n", __func__);
 		i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 		mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
+
+		i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
+		if (i >= 0)
+			mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
+
 		mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 				    cb_param->num_comps);
 
@@ -481,8 +828,22 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 	mtk_mutex_prepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 
-	for (i = 0; i < param->config->num_components; i++)
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
+	if (i >= 0)
+		mtk_mutex_prepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
+
+	for (i = 0; i < param->config->num_components; i++) {
+		if (is_dummy_engine(mdp, path->config->components[i].type))
+			continue;
+
 		mdp_comp_clock_on(&mdp->pdev->dev, path->comps[i].comp);
+	}
+
+	if (mdp->mdp_data->mdp_cfg->mdp_version_8195) {
+		ret = mdp_hyfbc_config(mdp, &cmd, path, param);
+		if (ret)
+			goto err_destroy_pkt;
+	}
 
 	ret = mdp_path_config(mdp, &cmd, path);
 	if (ret) {
@@ -503,9 +864,13 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 		goto err_destroy_pkt;
 	}
 
-	for (i = 0; i < param->config->num_components; i++)
+	for (i = 0; i < param->config->num_components; i++) {
+		if (is_dummy_engine(mdp, path->config->components[i].type))
+			continue;
+
 		memcpy(&comps[i], path->comps[i].comp,
 		       sizeof(struct mdp_comp));
+	}
 	cb_param->mdp = mdp;
 	cb_param->user_cmdq_cb = param->cmdq_cb;
 	cb_param->user_cb_data = param->cb_data;
@@ -528,6 +893,11 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 err_clock_off:
 	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
 	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
+
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA1);
+	if (i >= 0)
+		mtk_mutex_unprepare(mdp->mdp_mutex2[mdp->mdp_data->pipe_info[i].mutex_id]);
+
 	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 			    cb_param->num_comps);
 err_destroy_pkt:
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
index 8ca9c7e325e1..3d5cbd0e3805 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
@@ -27,6 +27,10 @@
 #include "mdp_reg_wdma.h"
 #include "mdp_reg_isp.h"
 
+#define is_wrot(id) \
+	((mdp)->mdp_data->comp_data[id].match.type == MDP_COMP_TYPE_WROT)
+#define byte2pixel(byte) ((byte) / 2)
+
 s32 get_comp_inner_id(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id)
 {
 	if (!mdp_dev)
@@ -57,6 +61,20 @@ enum mtk_mdp_comp_id get_comp_public_id(struct mdp_dev *mdp_dev, s32 inner_id)
 	return public_id;
 }
 
+bool is_dummy_engine(struct mdp_dev *mdp_dev, s32 inner_id)
+{
+	enum mtk_mdp_comp_id public_id = get_comp_public_id(mdp_dev, inner_id);
+
+	return (mdp_dev->mdp_data->comp_data[public_id].match.type == MDP_COMP_TYPE_DUMMY);
+}
+
+bool is_rdma(struct mdp_dev *mdp_dev, s32 inner_id)
+{
+	enum mtk_mdp_comp_id public_id = get_comp_public_id(mdp_dev, inner_id);
+
+	return (mdp_dev->mdp_data->comp_data[public_id].match.type == MDP_COMP_TYPE_RDMA);
+}
+
 static const struct mdp_platform_config *__get_plat_cfg(const struct mdp_comp_ctx *ctx)
 {
 	if (!ctx)
@@ -423,14 +441,40 @@ static const struct mdp_comp_ops fg_ops = {
 
 static int init_rsz(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
+	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	u32 value, mask, alias_id;
 
 	/* Reset RSZ */
 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x10000, BIT(16));
 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(16));
 	/* Enable RSZ */
 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, BIT(0), BIT(0));
+
+	if (mdp_cfg && mdp_cfg->mdp_version_8195) {
+		const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data;
+
+		value = (1 << 25);
+		mask = (1 << 25);
+		alias_id = data->config_table[CONFIG_VPP1_HW_DCM_1ST_DIS0];
+		mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+					   cmd, alias_id, value, mask);
+
+		alias_id = data->config_table[CONFIG_VPP1_HW_DCM_2ND_DIS0];
+		mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+					   cmd, alias_id, value, mask);
+
+		value = (1 << 4 | 1 << 5);
+		mask = (1 << 4 | 1 << 5);
+		alias_id = data->config_table[CONFIG_VPP1_HW_DCM_1ST_DIS1];
+		mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+					   cmd, alias_id, value, mask);
+
+		alias_id = data->config_table[CONFIG_VPP1_HW_DCM_2ND_DIS1];
+		mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+					   cmd, alias_id, value, mask);
+	}
 	return 0;
 }
 
@@ -501,6 +545,48 @@ static int config_rsz_subfrm(struct mdp_comp_ctx *ctx,
 	MM_REG_WRITE(cmd, subsys_id, base, PRZ_OUTPUT_IMAGE, subfrm->clip,
 		     0xFFFFFFFF);
 
+	if (mdp_cfg && mdp_cfg->mdp_version_8195) {
+		struct mdp_comp *merge;
+		const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data;
+		enum mtk_mdp_comp_id id = ctx->comp->public_id;
+		u32 alias_id;
+
+		switch (id) {
+		case MDP_COMP_RSZ2:
+			merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE2];
+
+			alias_id = data->config_table[CONFIG_SVPP2_BUF_BF_RSZ_SWITCH];
+			mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+						   cmd, alias_id,
+						   subfrm->rsz_switch, 0xFFFFFFFF);
+			break;
+		case MDP_COMP_RSZ3:
+			merge = ctx->comp->mdp_dev->comp[MDP_COMP_MERGE3];
+
+			alias_id = data->config_table[CONFIG_SVPP3_BUF_BF_RSZ_SWITCH];
+			mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+						   cmd, alias_id,
+						   subfrm->rsz_switch, 0xFFFFFFFF);
+			break;
+		default:
+			goto subfrm_done;
+		}
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_CFG_0, subfrm->merge_cfg, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_CFG_4, subfrm->merge_cfg, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_CFG_24, subfrm->merge_cfg, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_CFG_25, subfrm->merge_cfg, 0xFFFFFFFF);
+
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_CFG_12, 0x1, 0xFFFFFFFF); // bypass mode
+		MM_REG_WRITE(cmd, merge->subsys_id, merge->reg_base,
+			     VPP_MERGE_ENABLE, 0x1, 0xFFFFFFFF);
+	}
+
+subfrm_done:
 	return 0;
 }
 
@@ -1020,10 +1106,12 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx,
 {
 	const struct mdp_wrot_data *wrot = &ctx->param->wrot;
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+	const struct mtk_mdp_driver_data *data = ctx->comp->mdp_dev->mdp_data;
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
 	bool comp;
 	u32 colorformat = ctx->outputs[0]->buffer.format.colorformat;
+	u32 alias_id;
 
 	/* Write frame base address */
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, wrot->iova[0],
@@ -1084,11 +1172,36 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx,
 	if (wrot->fifo_test != 0)
 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
 			     wrot->fifo_test, 0xFFF);
-	/* Filter enable */
-	if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
-		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
-			     wrot->filter, 0x77);
-
+	if (mdp_cfg) {
+		/* Filter enable */
+		if (mdp_cfg->wrot_filter_constraint)
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
+				     wrot->filter, 0x77);
+
+		if (mdp_cfg->mdp_version_8195) {
+			/* Turn off WROT dma dcm */
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN,
+				     (0x1 << 23) + (0x1 << 20), 0x900000);
+
+			if (wrot->vpp02vpp1) {
+				// Disable DCM (VPP02VPP1_RELAY)
+				alias_id = data->config_table[CONFIG_VPP0_HW_DCM_1ST_DIS0];
+				mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys,
+							   cmd, alias_id, 0x4000,
+							   0xFFFFFFFF);
+				// Set default size
+				alias_id = data->config_table[CONFIG_VPP0_DL_IRELAY_WR];
+				mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys2,
+							   cmd, alias_id, 0x0,
+							   0xFFFFFFFF);
+			} else {
+				alias_id = data->config_table[CONFIG_VPP0_HW_DCM_1ST_DIS0];
+				mtk_mmsys_mdp_write_config(ctx->comp->mdp_dev->mdp_mmsys,
+							   cmd, alias_id, 0x0,
+							   0xFFFFFFFF);
+			}
+		}
+	}
 	return 0;
 }
 
@@ -1566,17 +1679,30 @@ static const struct mdp_comp_ops camin_ops = {
 };
 
 static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
-	[MDP_COMP_TYPE_RDMA] =		&rdma_ops,
-	[MDP_COMP_TYPE_RSZ] =		&rsz_ops,
-	[MDP_COMP_TYPE_WROT] =		&wrot_ops,
-	[MDP_COMP_TYPE_WDMA] =		&wdma_ops,
-	[MDP_COMP_TYPE_PATH1] =		NULL,
-	[MDP_COMP_TYPE_PATH2] =		NULL,
-	[MDP_COMP_TYPE_CCORR] =		&ccorr_ops,
-	[MDP_COMP_TYPE_IMGI] =		&imgi_ops,
-	[MDP_COMP_TYPE_EXTO] =		NULL,
-	[MDP_COMP_TYPE_DL_PATH1] =	&camin_ops,
-	[MDP_COMP_TYPE_DL_PATH2] =	&camin_ops,
+	[MDP_COMP_TYPE_WPEI]     = &camin_ops,
+	[MDP_COMP_TYPE_SPLIT]    = &split_ops,
+	[MDP_COMP_TYPE_STITCH]   = &stitch_ops,
+	[MDP_COMP_TYPE_RDMA]     = &rdma_ops,
+	[MDP_COMP_TYPE_FG]       = &fg_ops,
+	[MDP_COMP_TYPE_HDR]      = &hdr_ops,
+	[MDP_COMP_TYPE_AAL]      = &aal_ops,
+	[MDP_COMP_TYPE_RSZ]      = &rsz_ops,
+	[MDP_COMP_TYPE_TDSHP]    = &tdshp_ops,
+	[MDP_COMP_TYPE_COLOR]    = &color_ops,
+	[MDP_COMP_TYPE_OVL]      = &ovl_ops,
+	[MDP_COMP_TYPE_PAD]      = &pad_ops,
+	[MDP_COMP_TYPE_TCC]      = &tcc_ops,
+	[MDP_COMP_TYPE_WROT]     = &wrot_ops,
+	[MDP_COMP_TYPE_WDMA]     = &wdma_ops,
+	[MDP_COMP_TYPE_MERGE]    = NULL,
+	[MDP_COMP_TYPE_PATH1]    = NULL,
+	[MDP_COMP_TYPE_PATH2]    = NULL,
+	[MDP_COMP_TYPE_CCORR]    = &ccorr_ops,
+	[MDP_COMP_TYPE_IMGI]     = &imgi_ops,
+	[MDP_COMP_TYPE_EXTO]     = NULL,
+	[MDP_COMP_TYPE_DL_PATH1] = &camin_ops,
+	[MDP_COMP_TYPE_DL_PATH2] = &camin_ops,
+	[MDP_COMP_TYPE_DUMMY]    = NULL,
 };
 
 static const struct of_device_id mdp_comp_dt_ids[] = {
@@ -2070,3 +2196,190 @@ int mdp_comp_ctx_init(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
 		ctx->outputs[i] = &frame->outputs[param->outputs[i]];
 	return 0;
 }
+
+int mdp_hyfbc_init(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
+		   struct hyfbc_init_info *hyfbc, u32 wrot)
+{
+	struct mtk_mutex **mutex = mdp->mdp_mutex;
+	struct mtk_mutex **mutex2 = mdp->mdp_mutex2;
+	enum mtk_mdp_comp_id mtk_wrot = MDP_COMP_NONE;
+	phys_addr_t base;
+	u16 subsys_id;
+	u32 offset;
+	u32 mutex_id;
+	u32 mutex2_id;
+	u32 alias_id;
+	int evt;
+
+	mtk_wrot = get_comp_public_id(mdp, wrot);
+	if (!is_wrot(mtk_wrot)) {
+		dev_err(&mdp->pdev->dev, "Invalid wrot inner id %d", wrot);
+		return -EINVAL;
+	}
+
+	base = mdp->comp[mtk_wrot]->reg_base;
+	subsys_id = mdp->comp[mtk_wrot]->subsys_id;
+	offset = hyfbc->width_in_mb * hyfbc->byte_per_mb;
+
+	/* Reset WROT */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST,
+		     0x01, 0x00000001);
+	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT,
+		    0x01, 0x00000001);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST,
+		     0x00, 0x00000001);
+	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT,
+		    0x00, 0x00000001);
+
+	/* Write frame base address */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR,
+		     (hyfbc->pa_base + offset), 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_C,
+		     0x0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V,
+		     0x0, 0xFFFFFFFF);
+
+	/* Write frame related registers */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL,
+		     0x5020, 0xF131512F);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BKGD,
+		     ((hyfbc->is10b) ? 0xC8E438 : 0x18f4f8), 0xFFFFFFFF);
+
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT,
+		     0x0, 0x0000000F);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO,
+		     0x0, 0x04000000);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2,
+		     0x0, 0x00000007);
+
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_PVRIC,
+		     0x0, 0x03);
+	/* Write pre-ultra threshold */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA,
+		     0x8804c, 0x00FFFFFF);
+	/* Write frame Y pitch */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE,
+		     (hyfbc->w_stride_in_mb * hyfbc->byte_per_mb), 0x0000FFFF);
+	/* Write frame UV pitch */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_C,
+		     0x0, 0x0000FFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE_V,
+		     0x0, 0x0000FFFF);
+	/* Write matrix control */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAT_CTRL,
+		     0x60, 0x000000F3);
+
+	/* Set the fixed ALPHA as 0xFF */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_DITHER,
+		     0xFF000000, 0xFF000000);
+	/* Set VIDO_EOL_SEL */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_RSV_1,
+		     0x80000000, 0x80000000);
+	/* Set VIDO_FIFO_TEST */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_FIFO_TEST,
+		     0x200, 0x00000FFF);
+
+	/* Filter enable */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
+		     0x0, 0x00000077);
+
+	/* Turn off WROT dma dcm */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN,
+		     (0x1 << 23) + (0x1 << 20), 0x00900000);
+
+	alias_id = mdp->mdp_data->config_table[CONFIG_VPP0_HW_DCM_1ST_DIS0];
+	mtk_mmsys_mdp_write_config(mdp->mdp_mmsys, cmd,
+				   alias_id, 0x0, 0xFFFFFFFF);
+
+	/* Set mutex modules */
+	switch (mtk_wrot) {
+	case MDP_COMP_WROT0:
+		mutex_id = 2;
+		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id],
+					  0x800, 0x0, 0x0, cmd);
+		break;
+	case MDP_COMP_WROT1:
+		mutex2_id = 1;
+		mtk_mutex_add_mod_by_cmdq(mutex2[mutex2_id],
+					  0x80000000, 0x0, 0x0, cmd);
+		break;
+	case MDP_COMP_WROT2:
+		mutex2_id = 2;
+		mtk_mutex_add_mod_by_cmdq(mutex2[mutex2_id],
+					  0x0, 0x1, 0x0, cmd);
+		break;
+	case MDP_COMP_WROT3:
+		mutex2_id = 3;
+		mtk_mutex_add_mod_by_cmdq(mutex2[mutex2_id],
+					  0x0, 0x2, 0x0, cmd);
+		break;
+	default:
+		break;
+	}
+
+	/* Write Y pixel offset */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR,
+		     0x0, 0x0FFFFFFF);
+	/* Write U pixel offset */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_C,
+		     0x0, 0x0FFFFFFF);
+	/* Write V pixel offset */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_OFST_ADDR_V,
+		     0x0, 0x0FFFFFFF);
+	/* Write source size */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_IN_SIZE,
+		     (hyfbc->height_in_mb << 16) | byte2pixel(hyfbc->byte_per_mb), 0xFFFFFFFF);
+	/* Write target size */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_TAR_SIZE,
+		     (hyfbc->height_in_mb << 16) | byte2pixel(hyfbc->byte_per_mb), 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, 0x0,
+		     0xFFFFFFFF);
+
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
+		     ((byte2pixel(hyfbc->byte_per_mb) << 16) | 0x400), 0xFFFF7F00);
+
+	/* Enable WROT */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x01, 0x00000001);
+
+	switch (mtk_wrot) {
+	case MDP_COMP_WROT0:
+		evt = mdp_get_event_idx(mdp, WROT0_SOF);
+		MM_REG_CLEAR(cmd, evt);
+		mtk_mutex_enable_by_cmdq(mutex[mutex_id], cmd);
+		MM_REG_WAIT(cmd, evt);
+		evt = mdp_get_event_idx(mdp, WROT0_DONE);
+		MM_REG_WAIT(cmd, evt);
+		break;
+	case MDP_COMP_WROT1:
+		evt = mdp_get_event_idx(mdp, WROT1_SOF);
+		MM_REG_CLEAR(cmd, evt);
+		mtk_mutex_enable_by_cmdq(mutex2[mutex2_id], cmd);
+		MM_REG_WAIT(cmd, evt);
+		evt = mdp_get_event_idx(mdp, WROT1_DONE);
+		MM_REG_WAIT(cmd, evt);
+		break;
+	case MDP_COMP_WROT2:
+		evt = mdp_get_event_idx(mdp, WROT2_SOF);
+		MM_REG_CLEAR(cmd, evt);
+		mtk_mutex_enable_by_cmdq(mutex2[mutex2_id], cmd);
+		MM_REG_WAIT(cmd, evt);
+		evt = mdp_get_event_idx(mdp, WROT2_DONE);
+		MM_REG_WAIT(cmd, evt);
+		break;
+	case MDP_COMP_WROT3:
+		evt = mdp_get_event_idx(mdp, WROT3_SOF);
+		MM_REG_CLEAR(cmd, evt);
+		mtk_mutex_enable_by_cmdq(mutex2[mutex2_id], cmd);
+		MM_REG_WAIT(cmd, evt);
+		evt = mdp_get_event_idx(mdp, WROT3_DONE);
+		MM_REG_WAIT(cmd, evt);
+		break;
+	default:
+		break;
+	}
+
+	/* Disable WROT */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_ROT_EN, 0x00, 0x00000001);
+
+	return 0;
+}
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
index 05a60771d4bc..391e9014dc99 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
@@ -222,7 +222,8 @@ void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num);
 int mdp_comp_ctx_init(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
 		      const struct img_compparam *param,
 		      const struct img_ipi_frameparam *frame);
-
+int mdp_hyfbc_init(struct mdp_dev *mdp, struct mmsys_cmdq_cmd *cmd,
+		   struct hyfbc_init_info *hyfbc, u32 wrot);
 int mdp_get_event_idx(struct mdp_dev *mdp, enum mdp_comp_event event);
 
 #endif  /* __MTK_MDP3_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
index bef8da6fff1c..d8161be8c556 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
@@ -44,6 +44,9 @@ static const struct of_device_id mdp_of_ids[] = {
 	{ .compatible = "mediatek,mt8183-mdp3",
 	  .data = &mt8183_mdp_driver_data,
 	},
+	{ .compatible = "mediatek,mt8195-mdp3",
+	  .data = &mt8195_mdp_driver_data,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mdp_of_ids);
@@ -150,7 +153,7 @@ static int mdp_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct mdp_dev *mdp;
 	struct device_node *mdp_node;
-	struct platform_device *mm_pdev;
+	struct platform_device *mm_pdev, *mm_pdev2;
 	u32 event_ofst;
 	int ret, i, mutex_id;
 
@@ -162,13 +165,28 @@ static int mdp_probe(struct platform_device *pdev)
 
 	mdp->pdev = pdev;
 	mdp->mdp_data = of_device_get_match_data(&pdev->dev);
+
+	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
+
 	mm_pdev = __get_pdev_by_name(pdev, "mediatek,mmsys");
 	if (!mm_pdev) {
-		ret = -ENODEV;
-		goto err_return;
+		if (mdp->mdp_data->mdp_cfg->support_multi_larb) {
+			platform_set_drvdata(pdev, mdp);
+			goto success_return;
+		} else {
+			ret = -ENODEV;
+			goto err_return;
+		}
 	}
 	mdp->mdp_mmsys = &mm_pdev->dev;
 
+	mm_pdev2 = __get_pdev_by_name(pdev, "mediatek,mmsys2");
+	if (!mm_pdev2)
+		dev_err(dev, "Failed to get mdp mmsys2\n");
+	else
+		mdp->mdp_mmsys2 = &mm_pdev2->dev;
+
 	mdp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,mm-mutex", 0);
 	if (!mdp_node) {
 		ret = -ENODEV;
@@ -200,17 +218,43 @@ static int mdp_probe(struct platform_device *pdev)
 		goto err_return;
 	}
 
+	mdp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,mm-mutex2", 0);
+	if (!mdp_node) {
+		dev_err(dev, "Failed to get mdp mm-mutex2\n");
+	} else {
+		mm_pdev2 = of_find_device_by_node(mdp_node);
+		of_node_put(mdp_node);
+		if (WARN_ON(!mm_pdev2)) {
+			ret = -ENODEV;
+			goto err_return;
+		}
+	}
+
 	for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
 		mutex_id = mdp->mdp_data->pipe_info[i].mutex_id;
-		if (mdp->mdp_mutex[mutex_id])
-			continue;
-
-		mdp->mdp_mutex[mutex_id] =
-			mtk_mutex_mdp_get(&mm_pdev->dev, mdp->mdp_data->pipe_info[i].pipe_id);
 
-		if (!mdp->mdp_mutex[mutex_id]) {
-			ret = -ENODEV;
-			goto err_return;
+		if (mdp->mdp_data->pipe_info[i].mmsys_id != 0) {
+			if (mdp->mdp_mutex2[mutex_id])
+				continue;
+			mdp->mdp_mutex2[mutex_id] =
+				mtk_mutex_mdp_get(&mm_pdev2->dev,
+						  mdp->mdp_data->pipe_info[i].pipe_id);
+
+			if (!mdp->mdp_mutex2[mutex_id]) {
+				ret = -ENODEV;
+				goto err_return;
+			}
+		} else {
+			if (mdp->mdp_mutex[mutex_id])
+				continue;
+			mdp->mdp_mutex[mutex_id] =
+				mtk_mutex_mdp_get(&mm_pdev->dev,
+						  mdp->mdp_data->pipe_info[i].pipe_id);
+
+			if (!mdp->mdp_mutex[mutex_id]) {
+				ret = -ENODEV;
+				goto err_return;
+			}
 		}
 	}
 
@@ -273,6 +317,7 @@ static int mdp_probe(struct platform_device *pdev)
 		goto err_unregister_device;
 	}
 
+success_return:
 	dev_dbg(dev, "mdp-%d registered successfully\n", pdev->id);
 	return 0;
 
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index c668e317f947..8ee70763a18f 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -60,7 +60,9 @@ struct mtk_mdp_driver_data {
 struct mdp_dev {
 	struct platform_device			*pdev;
 	struct device				*mdp_mmsys;
+	struct device				*mdp_mmsys2;
 	struct mtk_mutex			*mdp_mutex[MDP_PIPE_MAX];
+	struct mtk_mutex			*mdp_mutex2[MDP_PIPE_MAX];
 	struct mdp_comp				*comp[MDP_MAX_COMP_COUNT];
 	const struct mtk_mdp_driver_data	*mdp_data;
 	s32					event[MDP_MAX_EVENT_COUNT];
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
index ca1c19c41950..1e749bb2b338 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
@@ -90,6 +90,7 @@ static void mdp_m2m_worker(struct work_struct *work)
 	param.type = ctx->curr_param.type;
 	param.num_inputs = 1;
 	param.num_outputs = 1;
+	param.frame_change = (ctx->frame_count[MDP_M2M_SRC] == 0);
 
 	frame = ctx_get_frame(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 	src_vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
@@ -328,6 +329,11 @@ static int mdp_m2m_s_fmt_mplane(struct file *file, void *fh,
 		ctx->curr_param.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
 		ctx->curr_param.quant = f->fmt.pix_mp.quantization;
 		ctx->curr_param.xfer_func = f->fmt.pix_mp.xfer_func;
+
+		if (MDP_COLOR_IS_HYFBC_COMPRESS(fmt->mdp_color)) {
+			frame->stride.width = ((f->fmt.pix_mp.width + 63) >> 6) << 6;
+			frame->stride.height = ((f->fmt.pix_mp.height + 31) >> 5) << 5;
+		}
 	} else {
 		capture->compose.left = 0;
 		capture->compose.top = 0;
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
index 83e91735202b..8c2b74c67273 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
@@ -147,6 +147,47 @@ int mdp_enum_fmt_mplane(struct v4l2_fmtdesc *f)
 	return 0;
 }
 
+static u32 mdp_fmt_get_hyfbc_plane_size(u32 width,
+					u32 height, u32 color, unsigned int plane)
+{
+	u32 y_data_size = 0;
+	u32 c_data_size = 0;
+	u32 y_header_size = 0;
+	u32 c_header_size = 0;
+	u32 y_data_ofst = 0;
+	u32 c_data_ofst = 0;
+	u32 c_header_ofst = 0;
+
+	y_data_size = (((width + 63) >> 6) << 6) * (((height + 63) >> 6) << 6);
+	y_header_size = y_data_size >> 6;
+	if (MDP_COLOR_IS_10BIT_PACKED(color))
+		y_data_size = (y_data_size * 6) >> 2;
+
+	c_data_size = y_data_size >> 1;
+	c_header_size = (((y_header_size >> 1) + 63) >> 6) << 6;
+
+	// Setup source buffer base
+	y_data_ofst = ((y_header_size + 4095) >> 12) << 12; // align 4k
+	c_data_ofst = ((y_data_ofst + y_data_size + c_header_size + 4095) >> 12) << 12; // align 4k
+	c_header_ofst = c_data_ofst - c_header_size;
+
+	if (plane == 0)
+		return c_header_ofst;
+	else
+		return (c_data_ofst + c_data_size);
+}
+
+static u32 mdp_fmt_get_afbc_plane_size(u32 width, u32 height, u32 color)
+{
+	u32 align_w = ((width + 31) >> 5) << 5;
+	u32 align_h = ((height + 31) >> 5) << 5;
+
+	if (MDP_COLOR_IS_10BIT_PACKED(color))
+		return ((align_w >> 4) * (align_h >> 4) * (16 + 512));
+	else
+		return ((align_w >> 4) * (align_h >> 4) * (16 + 384));
+}
+
 const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
 					    struct mdp_frameparam *param,
 					    u32 ctx_id)
@@ -211,11 +252,17 @@ const struct mdp_format *mdp_try_fmt_mplane(struct v4l2_format *f,
 			bpl = min_bpl;
 		si = (bpl * pix_mp->height * fmt->depth[i]) / fmt->row_depth[i];
 
+		if (MDP_COLOR_IS_HYFBC_COMPRESS(fmt->mdp_color)) {
+			si = mdp_fmt_get_hyfbc_plane_size(pix_mp->width,
+							  pix_mp->height, fmt->mdp_color, i);
+		} else if (MDP_COLOR_IS_COMPRESS(fmt->mdp_color)) {
+			si = mdp_fmt_get_afbc_plane_size(pix_mp->width,
+							 pix_mp->height, fmt->mdp_color);
+		}
+
 		pix_mp->plane_fmt[i].bytesperline = bpl;
 		if (pix_mp->plane_fmt[i].sizeimage < si)
 			pix_mp->plane_fmt[i].sizeimage = si;
-		dev_dbg(dev, "%d: p%u, bpl:%u (%u), sizeimage:%u (%u)", ctx_id,
-			i, bpl, min_bpl, pix_mp->plane_fmt[i].sizeimage, si);
 	}
 
 	return fmt;
@@ -324,8 +371,14 @@ static u32 mdp_fmt_get_stride(const struct mdp_format *fmt,
 	enum mdp_color c = fmt->mdp_color;
 	u32 stride;
 
-	stride = (bytesperline * MDP_COLOR_BITS_PER_PIXEL(c))
-		/ fmt->row_depth[0];
+	if (MDP_COLOR_IS_COMPRESS(c)) {
+		bytesperline = ((bytesperline + 31) >> 5) << 5;
+		stride = (bytesperline * MDP_COLOR_BITS_PER_PIXEL(c))
+			/ fmt->row_depth[0];
+	} else {
+		stride = (bytesperline * MDP_COLOR_BITS_PER_PIXEL(c))
+			/ fmt->row_depth[0];
+	}
 	if (plane == 0)
 		return stride;
 	if (plane < MDP_COLOR_GET_PLANE_COUNT(c)) {
@@ -398,6 +451,19 @@ static void mdp_prepare_buffer(struct img_image_buffer *b,
 			mdp_fmt_get_plane_size(frame->mdp_fmt, stride,
 					       pix_mp->height, i) -
 					       vb->planes[i].data_offset;
+
+		if (MDP_COLOR_IS_HYFBC_COMPRESS(b->format.colorformat)) {
+			b->format.plane_fmt[i].size =
+				mdp_fmt_get_hyfbc_plane_size(pix_mp->width,
+							     pix_mp->height,
+							     b->format.colorformat, i);
+		} else if (MDP_COLOR_IS_COMPRESS(b->format.colorformat)) {
+			b->format.plane_fmt[i].size =
+				mdp_fmt_get_afbc_plane_size(pix_mp->width,
+							    pix_mp->height,
+							    b->format.colorformat);
+		}
+
 		b->iova[i] = vb2_dma_contig_plane_dma_addr(vb, i) +
 			     vb->planes[i].data_offset;
 	}
@@ -409,6 +475,18 @@ static void mdp_prepare_buffer(struct img_image_buffer *b,
 		b->format.plane_fmt[i].size =
 			mdp_fmt_get_plane_size(frame->mdp_fmt, stride,
 					       pix_mp->height, i);
+
+		if (MDP_COLOR_IS_HYFBC_COMPRESS(b->format.colorformat)) {
+			b->format.plane_fmt[i].size =
+				mdp_fmt_get_hyfbc_plane_size(pix_mp->width,
+							     pix_mp->height,
+							     b->format.colorformat, i);
+		} else if (MDP_COLOR_IS_COMPRESS(b->format.colorformat)) {
+			b->format.plane_fmt[i].size =
+				mdp_fmt_get_afbc_plane_size(pix_mp->width,
+							    pix_mp->height,
+							    b->format.colorformat);
+		}
 		b->iova[i] = b->iova[i - 1] + b->format.plane_fmt[i - 1].size;
 	}
 	b->usage = frame->usage;
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 4a25f86bfaa5..1ef32b747233 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -355,6 +355,8 @@ struct mdp_frame {
 	u32			dre:1;
 	u32			sharpness:1;
 	u32			dither:1;
+	/* H and V stride, only for HYFBC format */
+	struct v4l2_rect	stride;
 };
 
 static inline bool mdp_target_is_crop(u32 target)
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:48 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:48 +0800
Subject: [PATCH v1 08/14] media: platform: mtk-mdp3: Add engine setting for
 MT8195
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-9-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add engine setting and related header files for MT8195

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/media/platform/mtk-mdp3/mdp_reg_aal.h |  24 +
 .../media/platform/mtk-mdp3/mdp_reg_color.h   |  29 +
 drivers/media/platform/mtk-mdp3/mdp_reg_fg.h  |  23 +
 drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h |  31 +
 .../media/platform/mtk-mdp3/mdp_reg_merge.h   |  23 +
 drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h |  24 +
 drivers/media/platform/mtk-mdp3/mdp_reg_pad.h |  20 +
 .../media/platform/mtk-mdp3/mdp_reg_rdma.h    |  31 +
 drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h |   2 +
 .../media/platform/mtk-mdp3/mdp_reg_tdshp.h   | 116 +++
 .../media/platform/mtk-mdp3/mdp_reg_wrot.h    |  18 +
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 705 +++++++++++++++++-
 12 files changed, 1033 insertions(+), 13 deletions(-)
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_aal.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_color.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_fg.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_merge.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_pad.h
 create mode 100644 drivers/media/platform/mtk-mdp3/mdp_reg_tdshp.h

diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_aal.h b/drivers/media/platform/mtk-mdp3/mdp_reg_aal.h
new file mode 100644
index 000000000000..2275a06fbdf9
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_aal.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_AAL_H__
+#define __MDP_REG_AAL_H__
+
+#define MDP_AAL_EN                            (0x000)
+#define MDP_AAL_CFG                           (0x020)
+#define MDP_AAL_SIZE                          (0x030)
+#define MDP_AAL_OUTPUT_SIZE                   (0x034)
+#define MDP_AAL_OUTPUT_OFFSET                 (0x038)
+#define MDP_AAL_CFG_MAIN                      (0x200)
+
+#define MDP_AAL_EN_MASK                       (0x01)
+#define MDP_AAL_CFG_MASK                      (0x70FF00B3)
+#define MDP_AAL_SIZE_MASK                     (0x1FFF1FFF)
+#define MDP_AAL_OUTPUT_SIZE_MASK              (0x1FFF1FFF)
+#define MDP_AAL_OUTPUT_OFFSET_MASK            (0x0FF00FF)
+#define MDP_AAL_CFG_MAIN_MASK                 (0x0FE)
+
+#endif  // __MDP_REG_AAL_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_color.h b/drivers/media/platform/mtk-mdp3/mdp_reg_color.h
new file mode 100644
index 000000000000..54d917a20362
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_color.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_COLOR_H__
+#define __MDP_REG_COLOR_H__
+
+#define DISP_COLOR_WIN_X_MAIN                (0x40C)
+#define DISP_COLOR_WIN_Y_MAIN                (0x410)
+#define DISP_COLOR_START                     (0xC00)
+#define DISP_COLOR_INTEN                     (0xC04)
+#define DISP_COLOR_OUT_SEL                   (0xC0C)
+#define DISP_COLOR_INTERNAL_IP_WIDTH         (0xC50)
+#define DISP_COLOR_INTERNAL_IP_HEIGHT        (0xC54)
+#define DISP_COLOR_CM1_EN                    (0xC60)
+#define DISP_COLOR_CM2_EN                    (0xCA0)
+// MASK
+#define DISP_COLOR_WIN_X_MAIN_MASK           (0xFFFFFFFF)
+#define DISP_COLOR_WIN_Y_MAIN_MASK           (0xFFFFFFFF)
+#define DISP_COLOR_START_MASK                (0x0FF013F)
+#define DISP_COLOR_INTEN_MASK                (0x07)
+#define DISP_COLOR_OUT_SEL_MASK              (0x0777)
+#define DISP_COLOR_INTERNAL_IP_WIDTH_MASK    (0x03FFF)
+#define DISP_COLOR_INTERNAL_IP_HEIGHT_MASK   (0x03FFF)
+#define DISP_COLOR_CM1_EN_MASK               (0x03)
+#define DISP_COLOR_CM2_EN_MASK               (0x017)
+#endif  // __MDP_REG_COLOR_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_fg.h b/drivers/media/platform/mtk-mdp3/mdp_reg_fg.h
new file mode 100644
index 000000000000..34f68554c0bb
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_fg.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_FG_H__
+#define __MDP_REG_FG_H__
+
+#define MDP_FG_TRIGGER          (0x0)
+#define MDP_FG_FG_CTRL_0        (0x20)
+#define MDP_FG_FG_CK_EN         (0x24)
+#define MDP_FG_TILE_INFO_0      (0x418)
+#define MDP_FG_TILE_INFO_1      (0x41c)
+
+/* MASK */
+#define MDP_FG_TRIGGER_MASK          (0x00000007)
+#define MDP_FG_FG_CTRL_0_MASK        (0x00000033)
+#define MDP_FG_FG_CK_EN_MASK         (0x0000000F)
+#define MDP_FG_TILE_INFO_0_MASK      (0xFFFFFFFF)
+#define MDP_FG_TILE_INFO_1_MASK      (0xFFFFFFFF)
+
+#endif  //__MDP_REG_FG_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h b/drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h
new file mode 100644
index 000000000000..06d0d3a6a139
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_hdr.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_HDR_H__
+#define __MDP_REG_HDR_H__
+
+#define MDP_HDR_TOP                 (0x000)
+#define MDP_HDR_RELAY               (0x004)
+#define MDP_HDR_SIZE_0              (0x014)
+#define MDP_HDR_SIZE_1              (0x018)
+#define MDP_HDR_SIZE_2              (0x01C)
+#define MDP_HDR_HIST_CTRL_0         (0x020)
+#define MDP_HDR_HIST_CTRL_1         (0x024)
+#define MDP_HDR_HIST_ADDR           (0x0DC)
+#define MDP_HDR_TILE_POS            (0x118)
+
+// MASK
+#define MDP_HDR_RELAY_MASK          (0x01)
+#define MDP_HDR_TOP_MASK            (0xFF0FEB6D)
+#define MDP_HDR_SIZE_0_MASK         (0x1FFF1FFF)
+#define MDP_HDR_SIZE_1_MASK         (0x1FFF1FFF)
+#define MDP_HDR_SIZE_2_MASK         (0x1FFF1FFF)
+#define MDP_HDR_HIST_CTRL_0_MASK    (0x1FFF1FFF)
+#define MDP_HDR_HIST_CTRL_1_MASK    (0x1FFF1FFF)
+#define MDP_HDR_HIST_ADDR_MASK      (0xBF3F2F3F)
+#define MDP_HDR_TILE_POS_MASK       (0x1FFF1FFF)
+
+#endif // __MDP_REG_HDR_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_merge.h b/drivers/media/platform/mtk-mdp3/mdp_reg_merge.h
new file mode 100644
index 000000000000..d53d58d4ea05
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_merge.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_MERGE_H__
+#define __MDP_REG_MERGE_H__
+
+#define VPP_MERGE_ENABLE	(0x000)
+#define VPP_MERGE_CFG_0		(0x010)
+#define VPP_MERGE_CFG_4		(0x020)
+#define VPP_MERGE_CFG_12	(0x040)
+#define VPP_MERGE_CFG_24	(0x070)
+#define VPP_MERGE_CFG_25	(0x074)
+
+#define VPP_MERGE_ENABLE_MASK	(0xFFFFFFFF)
+#define VPP_MERGE_CFG_0_MASK	(0xFFFFFFFF)
+#define VPP_MERGE_CFG_4_MASK	(0xFFFFFFFF)
+#define VPP_MERGE_CFG_12_MASK	(0xFFFFFFFF)
+#define VPP_MERGE_CFG_24_MASK	(0xFFFFFFFF)
+#define VPP_MERGE_CFG_25_MASK	(0xFFFFFFFF)
+#endif
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h b/drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h
new file mode 100644
index 000000000000..35aa10c763bd
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_ovl.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_OVL_H__
+#define __MDP_REG_OVL_H__
+
+#define OVL_EN                          (0x00c)
+#define OVL_ROI_SIZE                    (0x020)
+#define OVL_DATAPATH_CON                (0x024)
+#define OVL_SRC_CON                     (0x02c)
+#define OVL_L0_CON                      (0x030)
+#define OVL_L0_SRC_SIZE                 (0x038)
+
+#define OVL_DATAPATH_CON_MASK           (0x0FFFFFFF)
+#define OVL_EN_MASK                     (0xB07D07B1)
+#define OVL_L0_CON_MASK                 (0xFFFFFFFF)
+#define OVL_L0_SRC_SIZE_MASK            (0x1FFF1FFF)
+#define OVL_ROI_SIZE_MASK               (0x1FFF1FFF)
+#define OVL_SRC_CON_MASK                (0x0000031F)
+
+#endif  //__MDP_REG_OVL_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_pad.h b/drivers/media/platform/mtk-mdp3/mdp_reg_pad.h
new file mode 100644
index 000000000000..f4d6d06a74be
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_pad.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_PAD_H__
+#define __MDP_REG_PAD_H__
+
+#define VPP_PADDING0_PADDING_CON        (0x000)
+#define VPP_PADDING0_PADDING_PIC_SIZE   (0x004)
+#define VPP_PADDING0_W_PADDING_SIZE     (0x008)
+#define VPP_PADDING0_H_PADDING_SIZE     (0x00c)
+
+#define VPP_PADDING0_PADDING_CON_MASK      (0x00000007)
+#define VPP_PADDING0_PADDING_PIC_SIZE_MASK (0xFFFFFFFF)
+#define VPP_PADDING0_W_PADDING_SIZE_MASK   (0x1FFF1FFF)
+#define VPP_PADDING0_H_PADDING_SIZE_MASK   (0x1FFF1FFF)
+
+#endif  // __MDP_REG_PAD_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h b/drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
index 59d9aae40be6..06dea03ae029 100644
--- a/drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_rdma.h
@@ -12,12 +12,14 @@
 #define MDP_RDMA_CON                    0x020
 #define MDP_RDMA_GMCIF_CON              0x028
 #define MDP_RDMA_SRC_CON                0x030
+#define MDP_RDMA_COMP_CON               0x038
 #define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE   0x060
 #define MDP_RDMA_MF_BKGD_SIZE_IN_PXL    0x068
 #define MDP_RDMA_MF_SRC_SIZE            0x070
 #define MDP_RDMA_MF_CLIP_SIZE           0x078
 #define MDP_RDMA_MF_OFFSET_1            0x080
 #define MDP_RDMA_SF_BKGD_SIZE_IN_BYTE   0x090
+#define MDP_RDMA_MF_BKGD_H_SIZE_IN_PXL  0x098
 #define MDP_RDMA_SRC_END_0              0x100
 #define MDP_RDMA_SRC_END_1              0x108
 #define MDP_RDMA_SRC_END_2              0x110
@@ -25,7 +27,20 @@
 #define MDP_RDMA_SRC_OFFSET_1           0x120
 #define MDP_RDMA_SRC_OFFSET_2           0x128
 #define MDP_RDMA_SRC_OFFSET_0_P         0x148
+#define MDP_RDMA_SRC_OFFSET_HP          0x150
 #define MDP_RDMA_TRANSFORM_0            0x200
+#define MDP_RDMA_DMABUF_CON_0           0x240
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_0    0x248
+#define MDP_RDMA_ULTRA_TH_LOW_CON_0     0x250
+#define MDP_RDMA_DMABUF_CON_1           0x258
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_1    0x260
+#define MDP_RDMA_ULTRA_TH_LOW_CON_1     0x268
+#define MDP_RDMA_DMABUF_CON_2           0x270
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_2    0x278
+#define MDP_RDMA_ULTRA_TH_LOW_CON_2     0x280
+#define MDP_RDMA_DMABUF_CON_3           0x288
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_3    0x290
+#define MDP_RDMA_ULTRA_TH_LOW_CON_3     0x298
 #define MDP_RDMA_RESV_DUMMY_0           0x2a0
 #define MDP_RDMA_MON_STA_1              0x408
 #define MDP_RDMA_SRC_BASE_0             0xf00
@@ -40,12 +55,14 @@
 #define MDP_RDMA_CON_MASK                   0x00001110
 #define MDP_RDMA_GMCIF_CON_MASK             0xfffb3771
 #define MDP_RDMA_SRC_CON_MASK               0xf3ffffff
+#define MDP_RDMA_COMP_CON_MASK              0xffffc000
 #define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE_MASK  0x001fffff
 #define MDP_RDMA_MF_BKGD_SIZE_IN_PXL_MASK   0x001fffff
 #define MDP_RDMA_MF_SRC_SIZE_MASK           0x1fff1fff
 #define MDP_RDMA_MF_CLIP_SIZE_MASK          0x1fff1fff
 #define MDP_RDMA_MF_OFFSET_1_MASK           0x003f001f
 #define MDP_RDMA_SF_BKGD_SIZE_IN_BYTE_MASK  0x001fffff
+#define MDP_RDMA_MF_BKGD_H_SIZE_IN_PXL_MASK 0x007fffff
 #define MDP_RDMA_SRC_END_0_MASK             0xffffffff
 #define MDP_RDMA_SRC_END_1_MASK             0xffffffff
 #define MDP_RDMA_SRC_END_2_MASK             0xffffffff
@@ -53,7 +70,21 @@
 #define MDP_RDMA_SRC_OFFSET_1_MASK          0xffffffff
 #define MDP_RDMA_SRC_OFFSET_2_MASK          0xffffffff
 #define MDP_RDMA_SRC_OFFSET_0_P_MASK        0xffffffff
+#define MDP_RDMA_SRC_OFFSET_HP_MASK         0xffffffff
 #define MDP_RDMA_TRANSFORM_0_MASK           0xff110777
+#define MDP_RDMA_DMABUF_CON_0_MASK          0x0fff00ff
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_0_MASK   0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_0_MASK    0x3fffffff
+#define MDP_RDMA_DMABUF_CON_1_MASK          0x0f7f007f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_1_MASK   0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_1_MASK    0x3fffffff
+#define MDP_RDMA_DMABUF_CON_2_MASK          0x0f3f003f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_2_MASK   0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_2_MASK    0x3fffffff
+#define MDP_RDMA_DMABUF_CON_3_MASK          0x0f3f003f
+#define MDP_RDMA_ULTRA_TH_HIGH_CON_3_MASK   0x3fffffff
+#define MDP_RDMA_ULTRA_TH_LOW_CON_3_MASK    0x3fffffff
+
 #define MDP_RDMA_RESV_DUMMY_0_MASK          0xffffffff
 #define MDP_RDMA_MON_STA_1_MASK             0xffffffff
 #define MDP_RDMA_SRC_BASE_0_MASK            0xffffffff
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h b/drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
index 051fdb020741..942fd4393eba 100644
--- a/drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_rsz.h
@@ -20,6 +20,7 @@
 #define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET                 0x02c
 #define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET              0x030
 #define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET             0x034
+#define RSZ_ETC_CONTROL                                   0x22c
 
 /* MASK */
 #define PRZ_ENABLE_MASK                                   0x00010001
@@ -35,5 +36,6 @@
 #define PRZ_LUMA_VERTICAL_SUBPIXEL_OFFSET_MASK            0x001fffff
 #define PRZ_CHROMA_HORIZONTAL_INTEGER_OFFSET_MASK         0x0000ffff
 #define PRZ_CHROMA_HORIZONTAL_SUBPIXEL_OFFSET_MASK        0x001fffff
+#define RSZ_ETC_CONTROL_MASK                              0xff770000
 
 #endif // __MDP_REG_RSZ_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_tdshp.h b/drivers/media/platform/mtk-mdp3/mdp_reg_tdshp.h
new file mode 100644
index 000000000000..7907266ac7c7
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_tdshp.h
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MDP_REG_TDSHP_H__
+#define __MDP_REG_TDSHP_H__
+
+#define MDP_HIST_CFG_00              (0x064)
+#define MDP_HIST_CFG_01              (0x068)
+#define MDP_TDSHP_CTRL               (0x100)
+#define MDP_TDSHP_CFG                (0x110)
+#define MDP_TDSHP_INPUT_SIZE         (0x120)
+#define MDP_TDSHP_OUTPUT_OFFSET      (0x124)
+#define MDP_TDSHP_OUTPUT_SIZE        (0x128)
+#define MDP_LUMA_HIST_INIT_00        (0x200)
+#define MDP_LUMA_HIST_INIT_01        (0x204)
+#define MDP_LUMA_HIST_INIT_02        (0x208)
+#define MDP_LUMA_HIST_INIT_03        (0x20C)
+#define MDP_LUMA_HIST_INIT_04        (0x210)
+#define MDP_LUMA_HIST_INIT_05        (0x214)
+#define MDP_LUMA_HIST_INIT_06        (0x218)
+#define MDP_LUMA_HIST_INIT_07        (0x21C)
+#define MDP_LUMA_HIST_INIT_08        (0x220)
+#define MDP_LUMA_HIST_INIT_09        (0x224)
+#define MDP_LUMA_HIST_INIT_10        (0x228)
+#define MDP_LUMA_HIST_INIT_11        (0x22C)
+#define MDP_LUMA_HIST_INIT_12        (0x230)
+#define MDP_LUMA_HIST_INIT_13        (0x234)
+#define MDP_LUMA_HIST_INIT_14        (0x238)
+#define MDP_LUMA_HIST_INIT_15        (0x23C)
+#define MDP_LUMA_HIST_INIT_16        (0x240)
+#define MDP_LUMA_SUM_INIT            (0x244)
+#define MDP_DC_TWO_D_W1_RESULT_INIT  (0x260)
+#define MDP_CONTOUR_HIST_INIT_00     (0x398)
+#define MDP_CONTOUR_HIST_INIT_01     (0x39C)
+#define MDP_CONTOUR_HIST_INIT_02     (0x3A0)
+#define MDP_CONTOUR_HIST_INIT_03     (0x3A4)
+#define MDP_CONTOUR_HIST_INIT_04     (0x3A8)
+#define MDP_CONTOUR_HIST_INIT_05     (0x3AC)
+#define MDP_CONTOUR_HIST_INIT_06     (0x3B0)
+#define MDP_CONTOUR_HIST_INIT_07     (0x3B4)
+#define MDP_CONTOUR_HIST_INIT_08     (0x3B8)
+#define MDP_CONTOUR_HIST_INIT_09     (0x3BC)
+#define MDP_CONTOUR_HIST_INIT_10     (0x3C0)
+#define MDP_CONTOUR_HIST_INIT_11     (0x3C4)
+#define MDP_CONTOUR_HIST_INIT_12     (0x3C8)
+#define MDP_CONTOUR_HIST_INIT_13     (0x3CC)
+#define MDP_CONTOUR_HIST_INIT_14     (0x3D0)
+#define MDP_CONTOUR_HIST_INIT_15     (0x3D4)
+#define MDP_CONTOUR_HIST_INIT_16     (0x3D8)
+
+// MASK
+#define MDP_HIST_CFG_00_MASK            (0xFFFFFFFF)
+#define MDP_HIST_CFG_01_MASK            (0xFFFFFFFF)
+#define MDP_LUMA_HIST_00_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_01_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_02_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_03_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_04_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_05_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_06_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_07_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_08_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_09_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_10_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_11_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_12_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_13_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_14_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_15_MASK           (0x07FFFFFF)
+#define MDP_LUMA_HIST_16_MASK           (0x07FFFFFF)
+#define MDP_TDSHP_CTRL_MASK             (0x07)
+#define MDP_TDSHP_CFG_MASK              (0x03F7)
+#define MDP_TDSHP_INPUT_SIZE_MASK       (0x1FFF1FFF)
+#define MDP_TDSHP_OUTPUT_OFFSET_MASK    (0x0FF00FF)
+#define MDP_TDSHP_OUTPUT_SIZE_MASK      (0x1FFF1FFF)
+#define MDP_LUMA_HIST_INIT_00_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_01_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_02_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_03_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_04_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_05_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_06_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_07_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_08_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_09_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_10_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_11_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_12_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_13_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_14_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_15_MASK      (0x07FFFFFF)
+#define MDP_LUMA_HIST_INIT_16_MASK      (0x07FFFFFF)
+#define MDP_LUMA_SUM_INIT_MASK          (0xFFFFFFFF)
+#define MDP_DC_TWO_D_W1_RESULT_INIT_MASK   (0x007FFFFF)
+#define MDP_CONTOUR_HIST_INIT_00_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_01_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_02_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_03_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_04_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_05_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_06_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_07_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_08_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_09_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_10_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_11_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_12_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_13_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_14_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_15_MASK      (0x07FFFFFF)
+#define MDP_CONTOUR_HIST_INIT_16_MASK      (0x07FFFFFF)
+
+#endif  // __MDP_REG_TDSHP_H__
diff --git a/drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h b/drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
index 39b8785f89eb..81a7c46c1aef 100644
--- a/drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
+++ b/drivers/media/platform/mtk-mdp3/mdp_reg_wrot.h
@@ -11,23 +11,32 @@
 #define VIDO_MAIN_BUF_SIZE          0x008
 #define VIDO_SOFT_RST               0x010
 #define VIDO_SOFT_RST_STAT          0x014
+#define VIDO_INT                    0x01c
 #define VIDO_CROP_OFST              0x020
 #define VIDO_TAR_SIZE               0x024
+#define VIDO_FRAME_SIZE             0x028
 #define VIDO_OFST_ADDR              0x02c
 #define VIDO_STRIDE                 0x030
+#define VIDO_BKGD                   0x034
 #define VIDO_OFST_ADDR_C            0x038
 #define VIDO_STRIDE_C               0x03c
+#define VIDO_CTRL_2                 0x048
 #define VIDO_DITHER                 0x054
 #define VIDO_STRIDE_V               0x06c
 #define VIDO_OFST_ADDR_V            0x068
 #define VIDO_RSV_1                  0x070
+#define VIDO_DMA_PREULTRA           0x074
 #define VIDO_IN_SIZE                0x078
 #define VIDO_ROT_EN                 0x07c
 #define VIDO_FIFO_TEST              0x080
 #define VIDO_MAT_CTRL               0x084
+#define VIDO_PVRIC                  0x0d8
+#define VIDO_SCAN_10BIT             0x0dc
+#define VIDO_PENDING_ZERO           0x0e0
 #define VIDO_BASE_ADDR              0xf00
 #define VIDO_BASE_ADDR_C            0xf04
 #define VIDO_BASE_ADDR_V            0xf08
+#define VIDO_AFBC_YUVTRANS          0xf2c
 
 /* MASK */
 #define VIDO_CTRL_MASK                  0xf530711f
@@ -36,6 +45,7 @@
 #define VIDO_SOFT_RST_STAT_MASK         0x00000001
 #define VIDO_TAR_SIZE_MASK              0x1fff1fff
 #define VIDO_CROP_OFST_MASK             0x1fff1fff
+#define VIDO_INT_MASK                   0x00000007
 #define VIDO_OFST_ADDR_MASK             0x0fffffff
 #define VIDO_STRIDE_MASK                0x0000ffff
 #define VIDO_OFST_ADDR_C_MASK           0x0fffffff
@@ -51,5 +61,13 @@
 #define VIDO_BASE_ADDR_MASK             0xffffffff
 #define VIDO_BASE_ADDR_C_MASK           0xffffffff
 #define VIDO_BASE_ADDR_V_MASK           0xffffffff
+#define VIDO_DMA_PREULTRA_MASK          0x00ffffff
+#define VIDO_FRAME_SIZE_MASK            0xffffffff
+#define VIDO_BKGD_MASK                  0xffffffff
+#define VIDO_CTRL_2_MASK                0x0000000f
+#define VIDO_PVRIC_MASK                 0x00000003
+#define VIDO_SCAN_10BIT_MASK            0x0000000f
+#define VIDO_PENDING_ZERO_MASK          0x07ffffff
+#define VIDO_AFBC_YUVTRANS_MASK         0x00000001
 
 #endif  // __MDP_REG_WROT_H__
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
index fdf072e48238..8ca9c7e325e1 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
@@ -15,6 +15,14 @@
 #include "mdp_reg_rdma.h"
 #include "mdp_reg_ccorr.h"
 #include "mdp_reg_rsz.h"
+#include "mdp_reg_fg.h"
+#include "mdp_reg_aal.h"
+#include "mdp_reg_tdshp.h"
+#include "mdp_reg_hdr.h"
+#include "mdp_reg_color.h"
+#include "mdp_reg_ovl.h"
+#include "mdp_reg_pad.h"
+#include "mdp_reg_merge.h"
 #include "mdp_reg_wrot.h"
 #include "mdp_reg_wdma.h"
 #include "mdp_reg_isp.h"
@@ -107,7 +115,10 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
 {
 	const struct mdp_rdma_data *rdma = &ctx->param->rdma;
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+	u32 width = ctx->input->buffer.format.width;
+	u32 height = ctx->input->buffer.format.height;
 	u32 colorformat = ctx->input->buffer.format.colorformat;
+	u32 write_mask = 0;
 	bool block10bit = MDP_COLOR_IS_10BIT_PACKED(colorformat);
 	bool en_ufo = MDP_COLOR_IS_UFP(colorformat);
 	phys_addr_t base = ctx->comp->reg_base;
@@ -132,7 +143,7 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_CON, rdma->src_ctrl,
 		     0x03C8FE0F);
 
-	if (mdp_cfg)
+	if (mdp_cfg) {
 		if (mdp_cfg->rdma_support_10bit && en_ufo) {
 			/* Setup source buffer base */
 			MM_REG_WRITE(cmd, subsys_id,
@@ -148,8 +159,47 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
 					     rdma->mf_bkgd_in_pxl, 0x001FFFFF);
 		}
 
-	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON, rdma->control,
-		     0x1110);
+		if (mdp_cfg->rdma_support_extend_ufo)
+			write_mask |= 0xB0000000;
+
+		if (mdp_cfg->rdma_support_afbc)
+			write_mask |= 0x0603000;
+
+		if (mdp_cfg->rdma_support_hyfbc &&
+		    (MDP_COLOR_IS_HYFBC_COMPRESS(colorformat))) {
+			/* Setup source buffer base */
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_UFO_DEC_LENGTH_BASE_Y,
+				     rdma->ufo_dec_y, 0xFFFFFFFF);
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_UFO_DEC_LENGTH_BASE_C,
+				     rdma->ufo_dec_c, 0xFFFFFFFF);
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
+				     ((width + 31) >> 5) << 5, 0x1FFFFF);
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_H_SIZE_IN_PXL,
+				     ((height + 7) >> 3) << 3, 0x1FFFFF);
+
+			/* Setup Compression Control */
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_COMP_CON,
+				     rdma->comp_ctrl, write_mask);
+		} else if (mdp_cfg->rdma_support_afbc &&
+		    (MDP_COLOR_IS_COMPRESS(colorformat))) {
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_SIZE_IN_PXL,
+				     ((width + 31) >> 5) << 5, 0x1FFFFF);
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_MF_BKGD_H_SIZE_IN_PXL,
+				     ((height + 7) >> 3) << 3, 0x1FFFFF);
+
+			/* Setup Compression Control */
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_COMP_CON,
+				     rdma->comp_ctrl, write_mask);
+		} else {
+			/* Setup Compression Control */
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_COMP_CON,
+				     rdma->comp_ctrl, write_mask);
+		}
+	}
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_CON,
+		     rdma->control, 0x1130);
+
 	/* Setup source buffer base */
 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_BASE_0, rdma->iova[0],
 		     0xFFFFFFFF);
@@ -173,6 +223,29 @@ static int config_rdma_frame(struct mdp_comp_ctx *ctx,
 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_TRANSFORM_0,
 		     rdma->transform, 0x0F110000);
 
+	if (mdp_cfg->rdma_esl_setting) {
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_0,
+			     rdma->dmabuf_con0, 0x0FFF00FF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_0,
+			     rdma->ultra_th_high_con0, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_0,
+			     rdma->ultra_th_low_con0, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_1,
+			     rdma->dmabuf_con1, 0x0F7F007F);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_1,
+			     rdma->ultra_th_high_con1, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_1,
+			     rdma->ultra_th_low_con1, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_2,
+			     rdma->dmabuf_con2, 0x0F3F003F);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_HIGH_CON_2,
+			     rdma->ultra_th_high_con2, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_ULTRA_TH_LOW_CON_2,
+			     rdma->ultra_th_low_con2, 0x3FFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_DMABUF_CON_3,
+			     rdma->dmabuf_con3, 0x0F3F003F);
+	}
+
 	return 0;
 }
 
@@ -189,7 +262,18 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
 	u8 subsys_id = ctx->comp->subsys_id;
 
 	/* Enable RDMA */
-	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
+	MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, BIT(0), BIT(0));
+
+	if (mdp_cfg->rdma_support_afbc ||
+	    mdp_cfg->rdma_support_hyfbc) {
+		if (MDP_COLOR_IS_COMPRESS(colorformat) ||
+		    MDP_COLOR_IS_HYFBC_COMPRESS(colorformat)) {
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0_P,
+				     subfrm->in_tile_xleft, 0xFFFFFFFF);
+			MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_HP,
+				     subfrm->in_tile_ytop, 0xFFFFFFFF);
+		}
+	}
 
 	/* Set Y pixel offset */
 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_SRC_OFFSET_0,
@@ -234,15 +318,27 @@ static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 	u8 subsys_id = ctx->comp->subsys_id;
 	int evt = -1;
 
-	if (id == MDP_COMP_RDMA0)
+	switch (id) {
+	case MDP_COMP_RDMA0:
 		evt = mdp_get_event_idx(ctx->comp->mdp_dev, RDMA0_DONE);
-	else
-		dev_err(dev, "Do not support RDMA1_DONE event\n");
+		break;
+	case MDP_COMP_RDMA1:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, RDMA1_DONE);
+		break;
+	case MDP_COMP_RDMA2:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, RDMA2_DONE);
+		break;
+	case MDP_COMP_RDMA3:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, RDMA3_DONE);
+		break;
+	default:
+		dev_err(dev, "Invalid Engine!\n");
+	}
 
 	if (evt > 0)
 		MM_REG_WAIT(cmd, evt);
 	/* Disable RDMA */
-	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
+	MM_REG_WRITE_MASK(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
 	return 0;
 }
 
@@ -256,6 +352,75 @@ static const struct mdp_comp_ops rdma_ops = {
 	.post_process = NULL,
 };
 
+static const struct mdp_comp_ops split_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = NULL,
+	.config_frame = NULL,
+	.config_subfrm = NULL,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static const struct mdp_comp_ops stitch_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = NULL,
+	.config_frame = NULL,
+	.config_subfrm = NULL,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_fg(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER,
+		     (0x00000001 << 2), 0x00000004);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TRIGGER,
+		     0x00000000, 0x00000004);
+
+	return 0;
+}
+
+static int config_fg_frame(struct mdp_comp_ctx *ctx,
+			   struct mmsys_cmdq_cmd *cmd,
+			   const struct v4l2_rect *compose)
+{
+	const struct mdp_fg_data *fg = &ctx->param->fg;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CTRL_0, fg->ctrl_0, 0x1);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_FG_CK_EN, fg->ck_en, 0x7);
+	return 0;
+}
+
+static int config_fg_subfrm(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_fg_subfrm *subfrm = &ctx->param->fg.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_0, subfrm->info_0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_FG_TILE_INFO_1, subfrm->info_1, 0xFFFFFFFF);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops fg_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_fg,
+	.config_frame = config_fg_frame,
+	.config_subfrm = config_fg_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
 static int init_rsz(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	phys_addr_t base = ctx->comp->reg_base;
@@ -274,9 +439,13 @@ static int config_rsz_frame(struct mdp_comp_ctx *ctx,
 			    const struct v4l2_rect *compose)
 {
 	const struct mdp_rsz_data *rsz = &ctx->param->rsz;
+	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
 
+	if (mdp_cfg && mdp_cfg->rsz_etc_control)
+		MM_REG_WRITE(cmd, subsys_id, base, RSZ_ETC_CONTROL, 0x0, 0xFFFFFFFF);
+
 	if (ctx->param->frame.bypass) {
 		/* Disable RSZ */
 		MM_REG_WRITE(cmd, subsys_id, base, PRZ_ENABLE, 0x0, BIT(0));
@@ -363,6 +532,473 @@ static const struct mdp_comp_ops rsz_ops = {
 	.post_process = NULL,
 };
 
+static int init_aal(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	// Always set MDP_AAL enable to 1
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_EN, 0x1, 0x1);
+
+	return 0;
+}
+
+static int config_aal_frame(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd,
+			    const struct v4l2_rect *compose)
+{
+	const struct mdp_aal_data *aal = &ctx->param->aal;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG_MAIN, aal->cfg_main, 0x80);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_CFG, aal->cfg, 0x1);
+
+	return 0;
+}
+
+static int config_aal_subfrm(struct mdp_comp_ctx *ctx,
+			     struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_aal_subfrm *subfrm = &ctx->param->aal.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_SIZE,
+		     subfrm->src, MDP_AAL_SIZE_MASK);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_OFFSET,
+		     subfrm->clip_ofst, 0x00FF00FF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_AAL_OUTPUT_SIZE,
+		     subfrm->clip, MDP_AAL_OUTPUT_SIZE_MASK);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops aal_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_aal,
+	.config_frame = config_aal_frame,
+	.config_subfrm = config_aal_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_hdr(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	// Always set MDP_HDR enable to 1
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP, 1, 0x1);
+
+	return 0;
+}
+
+static int config_hdr_frame(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd,
+			    const struct v4l2_rect *compose)
+{
+	const struct mdp_hdr_data *hdr = &ctx->param->hdr;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP,
+		     hdr->top, 0x30000000);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_RELAY,
+		     hdr->relay, 0x1);
+
+	return 0;
+}
+
+static int config_hdr_subfrm(struct mdp_comp_ctx *ctx,
+			     struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_hdr_subfrm *subfrm = &ctx->param->hdr.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TILE_POS,
+		     subfrm->win_size, MDP_HDR_TILE_POS_MASK);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_0,
+		     subfrm->src, 0x1FFF1FFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_1,
+		     subfrm->clip_ofst0, 0x1FFF1FFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_SIZE_2,
+		     subfrm->clip_ofst1, 0x1FFF1FFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_0,
+		     subfrm->hist_ctrl_0, 0x00003FFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_CTRL_1,
+		     subfrm->hist_ctrl_1, 0x00003FFF);
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_TOP,
+		     subfrm->hdr_top, 0x00000060);
+	// enable hist_clr_en
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HDR_HIST_ADDR,
+		     subfrm->hist_addr, 0x00000200);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops hdr_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_hdr,
+	.config_frame = config_hdr_frame,
+	.config_subfrm = config_hdr_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static void reset_luma_hist(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	// reset LUMA HIST
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_00, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_01, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_02, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_03, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_04, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_05, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_06, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_07, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_08, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_09, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_10, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_11, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_12, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_13, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_14, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_15, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_HIST_INIT_16, 0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     MDP_LUMA_SUM_INIT, 0, 0xFFFFFFFF);
+
+	if (mdp_cfg && mdp_cfg->tdshp_1_1) {
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_DC_TWO_D_W1_RESULT_INIT, 0, 0xFFFFFFFF);
+	}
+
+	if (mdp_cfg && mdp_cfg->tdshp_dyn_contrast_version == 2) {
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_00, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_01, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_02, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_03, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_04, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_05, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_06, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_07, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_08, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_09, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_10, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_11, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_12, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_13, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_14, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_15, 0, 0xFFFFFFFF);
+		MM_REG_WRITE(cmd, subsys_id, base,
+			     MDP_CONTOUR_HIST_INIT_16, 0, 0xFFFFFFFF);
+	}
+}
+
+static int init_tdshp(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CTRL, 0x00000001,
+		     0x00000001);
+	// Enable fifo
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, 0x00000002,
+		     0x00000002);
+	reset_luma_hist(ctx, cmd);
+
+	return 0;
+}
+
+static int config_tdshp_frame(struct mdp_comp_ctx *ctx,
+			      struct mmsys_cmdq_cmd *cmd,
+			      const struct v4l2_rect *compose)
+{
+	const struct mdp_tdshp_data *tdshp = &ctx->param->tdshp;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_CFG, tdshp->cfg, 0x00000001);
+
+	return 0;
+}
+
+static int config_tdshp_subfrm(struct mdp_comp_ctx *ctx,
+			       struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_tdshp_subfrm *subfrm = &ctx->param->tdshp.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_INPUT_SIZE,
+		     subfrm->src, MDP_TDSHP_INPUT_SIZE_MASK);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_OFFSET,
+		     subfrm->clip_ofst, 0x00FF00FF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_TDSHP_OUTPUT_SIZE,
+		     subfrm->clip, MDP_TDSHP_OUTPUT_SIZE_MASK);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_00,
+		     subfrm->hist_cfg_0, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base, MDP_HIST_CFG_01,
+		     subfrm->hist_cfg_1, 0xFFFFFFFF);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops tdshp_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_tdshp,
+	.config_frame = config_tdshp_frame,
+	.config_subfrm = config_tdshp_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_color(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_START, 0x1, 0x3);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_WIN_X_MAIN, 0xFFFF0000, 0xFFFFFFFF);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_WIN_Y_MAIN, 0xFFFF0000, 0xFFFFFFFF);
+
+	// R2Y/Y2R are disabled in MDP
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_CM1_EN, 0x0, 0x1);
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_CM2_EN, 0x0, 0x1);
+
+	//enable interrupt
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_INTEN, 0x00000007, 0x00000007);
+
+	//Set 10bit->8bit Rounding
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_OUT_SEL, 0x333, 0x333);
+
+	return 0;
+}
+
+static int config_color_frame(struct mdp_comp_ctx *ctx,
+			      struct mmsys_cmdq_cmd *cmd,
+			      const struct v4l2_rect *compose)
+{
+	const struct mdp_color_data *color = &ctx->param->color;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base,
+		     DISP_COLOR_START, color->start, DISP_COLOR_START_MASK);
+
+	return 0;
+}
+
+static int config_color_subfrm(struct mdp_comp_ctx *ctx,
+			       struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_color_subfrm *subfrm = &ctx->param->color.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, DISP_COLOR_INTERNAL_IP_WIDTH,
+		     subfrm->in_hsize, 0x00003FFF);
+	MM_REG_WRITE(cmd, subsys_id, base, DISP_COLOR_INTERNAL_IP_HEIGHT,
+		     subfrm->in_vsize, 0x00003FFF);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops color_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_color,
+	.config_frame = config_color_frame,
+	.config_subfrm = config_color_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_ovl(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_EN,
+		     0x1, OVL_EN_MASK);
+	//Relay Mode
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_SRC_CON,
+		     0x200, OVL_SRC_CON_MASK);
+	//Connect OVL, enable smi_id mode
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_DATAPATH_CON,
+		     0x1, OVL_DATAPATH_CON_MASK);
+
+	return 0;
+}
+
+static int config_ovl_frame(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd,
+			    const struct v4l2_rect *compose)
+{
+	const struct mdp_ovl_data *ovl = &ctx->param->ovl;
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	//Layer0 for PQ-direct-in
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_L0_CON,
+		     ovl->L0_con, 0x30000000);
+	//Enable Layer0
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_SRC_CON,
+		     ovl->src_con, 0x1);
+
+	return 0;
+}
+
+static int config_ovl_subfrm(struct mdp_comp_ctx *ctx,
+			     struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_ovl_subfrm *subfrm = &ctx->param->ovl.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	//Setup Layer0 source size
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_L0_SRC_SIZE,
+		     subfrm->L0_src_size, OVL_L0_SRC_SIZE_MASK);
+	//Setup ROI size (output size)
+	MM_REG_WRITE(cmd, subsys_id, base, OVL_ROI_SIZE,
+		     subfrm->roi_size, OVL_ROI_SIZE_MASK);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops ovl_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_ovl,
+	.config_frame = config_ovl_frame,
+	.config_subfrm = config_ovl_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_pad(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, VPP_PADDING0_PADDING_CON,
+		     0x2, VPP_PADDING0_PADDING_CON_MASK);
+	//Clear padding area
+	MM_REG_WRITE(cmd, subsys_id, base, VPP_PADDING0_W_PADDING_SIZE,
+		     0x0, VPP_PADDING0_W_PADDING_SIZE_MASK);
+	MM_REG_WRITE(cmd, subsys_id, base, VPP_PADDING0_H_PADDING_SIZE,
+		     0x0, VPP_PADDING0_H_PADDING_SIZE_MASK);
+
+	return 0;
+}
+
+static int config_pad_frame(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd,
+			    const struct v4l2_rect *compose)
+{
+	return 0;
+}
+
+static int config_pad_subfrm(struct mdp_comp_ctx *ctx,
+			     struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	const struct mdp_pad_subfrm *subfrm = &ctx->param->pad.subfrms[index];
+	phys_addr_t base = ctx->comp->reg_base;
+	u16 subsys_id = ctx->comp->subsys_id;
+
+	MM_REG_WRITE(cmd, subsys_id, base, VPP_PADDING0_PADDING_PIC_SIZE,
+		     subfrm->pic_size, VPP_PADDING0_PADDING_CON_MASK);
+
+	return 0;
+}
+
+static const struct mdp_comp_ops pad_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_pad,
+	.config_frame = config_pad_frame,
+	.config_subfrm = config_pad_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
+
+static int init_tcc(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
+{
+	return 0;
+}
+
+static int config_tcc_frame(struct mdp_comp_ctx *ctx,
+			    struct mmsys_cmdq_cmd *cmd,
+			    const struct v4l2_rect *compose)
+{
+	return 0;
+}
+
+static int config_tcc_subfrm(struct mdp_comp_ctx *ctx,
+			     struct mmsys_cmdq_cmd *cmd, u32 index)
+{
+	return 0;
+}
+
+static const struct mdp_comp_ops tcc_ops = {
+	.get_comp_flag = get_comp_flag,
+	.init_comp = init_tcc,
+	.config_frame = config_tcc_frame,
+	.config_subfrm = config_tcc_subfrm,
+	.wait_comp_event = NULL,
+	.advance_subfrm = NULL,
+	.post_process = NULL,
+};
 static int init_wrot(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	phys_addr_t base = ctx->comp->reg_base;
@@ -371,6 +1007,8 @@ static int init_wrot(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 	/* Reset WROT */
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, BIT(0), BIT(0));
 	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, BIT(0), BIT(0));
+	/* Reset setting */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, 0x0, 0xFFFFFFFF);
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_SOFT_RST, 0x0, BIT(0));
 	MM_REG_POLL(cmd, subsys_id, base, VIDO_SOFT_RST_STAT, 0x0, BIT(0));
 	return 0;
@@ -384,6 +1022,8 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx,
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	bool comp;
+	u32 colorformat = ctx->outputs[0]->buffer.format.colorformat;
 
 	/* Write frame base address */
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR, wrot->iova[0],
@@ -392,9 +1032,38 @@ static int config_wrot_frame(struct mdp_comp_ctx *ctx,
 		     0xFFFFFFFF);
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_BASE_ADDR_V, wrot->iova[2],
 		     0xFFFFFFFF);
+
+	if (mdp_cfg) {
+		if (mdp_cfg->wrot_support_afbc) {
+			comp = MDP_COLOR_IS_COMPRESS(colorformat);
+			if (comp) {
+				MM_REG_WRITE(cmd, subsys_id, base, VIDO_FRAME_SIZE,
+					     wrot->framesize, 0xFFFFFFFF);
+				MM_REG_WRITE(cmd, subsys_id, base, VIDO_AFBC_YUVTRANS,
+					     wrot->afbc_yuvtrans, 0x1);
+			}
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_PVRIC,  wrot->pvric, 0x03);
+		}
+
+		if (mdp_cfg->wrot_support_10bit) {
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_SCAN_10BIT,
+				     wrot->scan_10bit, 0x0000000F);
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_PENDING_ZERO,
+				     wrot->pending_zero, 0x04000000);
+		}
+		if (mdp_cfg->mdp_version_6885)
+			MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL_2,
+				     wrot->bit_number, 0x00000007);
+	}
+
 	/* Write frame related registers */
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CTRL, wrot->control,
 		     0xF131510F);
+
+	/* Write pre-ultra threshold */
+	MM_REG_WRITE(cmd, subsys_id, base, VIDO_DMA_PREULTRA, wrot->pre_ultra,
+		     0x00FFFFFF);
+
 	/* Write frame Y pitch */
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_STRIDE, wrot->stride[0],
 		     0x0000FFFF);
@@ -447,7 +1116,6 @@ static int config_wrot_subfrm(struct mdp_comp_ctx *ctx,
 		     0x1FFF1FFF);
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_CROP_OFST, subfrm->clip_ofst,
 		     0x1FFF1FFF);
-
 	MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE,
 		     subfrm->main_buf, 0x1FFF7F00);
 
@@ -466,11 +1134,22 @@ static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 	u8 subsys_id = ctx->comp->subsys_id;
 	int evt = -1;
 
-	if (id == MDP_COMP_WROT0)
+	switch (id) {
+	case MDP_COMP_WROT0:
 		evt = mdp_get_event_idx(ctx->comp->mdp_dev, WROT0_DONE);
-	else
-		dev_err(dev, "Do not support WROT1_DONE event\n");
-
+		break;
+	case MDP_COMP_WROT1:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, WROT1_DONE);
+		break;
+	case MDP_COMP_WROT2:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, WROT2_DONE);
+		break;
+	case MDP_COMP_WROT3:
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, WROT3_DONE);
+		break;
+	default:
+		dev_err(dev, "Invalid Engine!\n");
+	}
 	if (evt > 0)
 		MM_REG_WAIT(cmd, evt);
 
-- 
2.18.0



From roy-cw.yeh at mediatek.com  Sun Jan 16 21:52:45 2022
From: roy-cw.yeh at mediatek.com (roy-cw.yeh)
Date: Mon, 17 Jan 2022 13:52:45 +0800
Subject: [PATCH v1 05/14] media: platform: mtk-mdp3: add chip independence
 architecture
In-Reply-To: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
Message-ID: <20220117055254.9777-6-roy-cw.yeh@mediatek.com>

From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>

Add chip independence architecture
- Add hal architecture for mt8183
- Add driver data to adapt other soc

Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
---
 drivers/media/platform/mtk-mdp3/mt8183_mdp.h  | 411 ++++++++++++++++++
 .../media/platform/mtk-mdp3/mtk-mdp3-cmdq.c   | 174 +++++---
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.c   | 265 +++++------
 .../media/platform/mtk-mdp3/mtk-mdp3-comp.h   |  79 +++-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.c   |  33 +-
 .../media/platform/mtk-mdp3/mtk-mdp3-core.h   |  16 +
 .../media/platform/mtk-mdp3/mtk-mdp3-m2m.c    |   2 +
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.c   | 233 +---------
 .../media/platform/mtk-mdp3/mtk-mdp3-regs.h   | 262 +++++------
 9 files changed, 905 insertions(+), 570 deletions(-)
 create mode 100644 drivers/media/platform/mtk-mdp3/mt8183_mdp.h

diff --git a/drivers/media/platform/mtk-mdp3/mt8183_mdp.h b/drivers/media/platform/mtk-mdp3/mt8183_mdp.h
new file mode 100644
index 000000000000..9d30d87f5773
--- /dev/null
+++ b/drivers/media/platform/mtk-mdp3/mt8183_mdp.h
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Ping-Hsun Wu <ping-hsun.wu at mediatek.com>
+ */
+
+#ifndef __MT8183_MDP_H__
+#define __MT8183_MDP_H__
+
+static const struct mdp_platform_config mt8183_plat_cfg = {
+	.rdma_support_10bit             = true,
+	.rdma_rsz1_sram_sharing         = true,
+	.rdma_upsample_repeat_only      = true,
+	.rsz_disable_dcm_small_sample   = false,
+	.wrot_filter_constraint         = false,
+	.gce_event_offset               = 2,
+};
+
+enum mt8183_mdp_comp_id {
+	/* MT8183 Comp id */
+	/* ISP */
+	MT8183_MDP_COMP_WPEI = 0,
+	MT8183_MDP_COMP_WPEO,           /* 1 */
+	MT8183_MDP_COMP_WPEI2,          /* 2 */
+	MT8183_MDP_COMP_WPEO2,          /* 3 */
+	MT8183_MDP_COMP_ISP_IMGI,       /* 4 */
+	MT8183_MDP_COMP_ISP_IMGO,       /* 5 */
+	MT8183_MDP_COMP_ISP_IMG2O,      /* 6 */
+
+	/* IPU */
+	MT8183_MDP_COMP_IPUI,           /* 7 */
+	MT8183_MDP_COMP_IPUO,           /* 8 */
+
+	/* MDP */
+	MT8183_MDP_COMP_CAMIN,          /* 9 */
+	MT8183_MDP_COMP_CAMIN2,         /* 10 */
+	MT8183_MDP_COMP_RDMA0,          /* 11 */
+	MT8183_MDP_COMP_AAL0,           /* 12 */
+	MT8183_MDP_COMP_CCORR0,         /* 13 */
+	MT8183_MDP_COMP_RSZ0,           /* 14 */
+	MT8183_MDP_COMP_RSZ1,           /* 15 */
+	MT8183_MDP_COMP_TDSHP0,         /* 16 */
+	MT8183_MDP_COMP_COLOR0,         /* 17 */
+	MT8183_MDP_COMP_PATH0_SOUT,     /* 18 */
+	MT8183_MDP_COMP_PATH1_SOUT,     /* 19 */
+	MT8183_MDP_COMP_WROT0,          /* 20 */
+	MT8183_MDP_COMP_WDMA,           /* 21 */
+
+	/* Dummy Engine */
+	MT8183_MDP_COMP_RDMA1,          /* 22 */
+	MT8183_MDP_COMP_RSZ2,           /* 23 */
+	MT8183_MDP_COMP_TDSHP1,         /* 24 */
+	MT8183_MDP_COMP_WROT1,          /* 25 */
+};
+
+static const struct mdp_comp_data mt8183_mdp_comp_data[MDP_MAX_COMP_COUNT] = {
+	[MDP_COMP_WPEI] = {
+		{MDP_COMP_TYPE_WPEI, 0, MT8183_MDP_COMP_WPEI},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_WPEO] = {
+		{MDP_COMP_TYPE_EXTO, 2, MT8183_MDP_COMP_WPEO},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_WPEI2] = {
+		{MDP_COMP_TYPE_WPEI, 1, MT8183_MDP_COMP_WPEI2},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_WPEO2] = {
+		{MDP_COMP_TYPE_EXTO, 3, MT8183_MDP_COMP_WPEO2},
+		{0, 0, 0},
+		{0, 0, 0},
+	},
+	[MDP_COMP_ISP_IMGI] = {
+		{MDP_COMP_TYPE_IMGI, 0, MT8183_MDP_COMP_ISP_IMGI},
+		{0, 0, 4},
+		{0, 0, 0}
+	},
+	[MDP_COMP_ISP_IMGO] = {
+		{MDP_COMP_TYPE_EXTO, 0, MT8183_MDP_COMP_ISP_IMGO},
+		{0, 0, 4},
+		{0, 0, 0}
+	},
+	[MDP_COMP_ISP_IMG2O] = {
+		{MDP_COMP_TYPE_EXTO, 1, MT8183_MDP_COMP_ISP_IMG2O},
+		{0, 0, 0},
+		{0, 0, 0}
+	},
+	[MDP_COMP_CAMIN] = {
+		{MDP_COMP_TYPE_DL_PATH1, 0, MT8183_MDP_COMP_CAMIN},
+		{2, 2, 1},
+		{0, 0, 0}
+	},
+	[MDP_COMP_CAMIN2] = {
+		{MDP_COMP_TYPE_DL_PATH2, 1, MT8183_MDP_COMP_CAMIN2},
+		{2, 4, 1},
+		{0, 0, 0}
+	},
+	[MDP_COMP_RDMA0] = {
+		{MDP_COMP_TYPE_RDMA, 0, MT8183_MDP_COMP_RDMA0},
+		{2, 0, 0},
+		{0, BIT(2), 0},
+	},
+	[MDP_COMP_AAL0] = {
+		{MDP_COMP_TYPE_AAL, 0, MT8183_MDP_COMP_AAL0},
+		{0, 0, 0},
+		{0, BIT(23), 0},
+	},
+	[MDP_COMP_CCORR0] = {
+		{MDP_COMP_TYPE_CCORR, 0, MT8183_MDP_COMP_CCORR0},
+		{1, 0, 0},
+		{0, BIT(24), 0}
+	},
+	[MDP_COMP_RSZ0] = {
+		{MDP_COMP_TYPE_RSZ, 0, MT8183_MDP_COMP_RSZ0},
+		{1, 0, 0},
+		{0, BIT(4), 0}
+	},
+	[MDP_COMP_RSZ1] = {
+		{MDP_COMP_TYPE_RSZ, 1, MT8183_MDP_COMP_RSZ1},
+		{1, 0, 0},
+		{0, BIT(5), 0}
+	},
+	[MDP_COMP_TDSHP0] = {
+		{MDP_COMP_TYPE_TDSHP, 0, MT8183_MDP_COMP_TDSHP0},
+		{0, 0, 0},
+		{0, BIT(6), 0}
+	},
+	[MDP_COMP_PATH0_SOUT] = {
+		{MDP_COMP_TYPE_PATH1, 0, MT8183_MDP_COMP_PATH0_SOUT},
+		{0, 0, 2},
+		{0, 0, 0}
+	},
+	[MDP_COMP_PATH1_SOUT] = {
+		{MDP_COMP_TYPE_PATH2, 1, MT8183_MDP_COMP_PATH1_SOUT},
+		{0, 0, 3},
+		{0, 0, 0}
+	},
+	[MDP_COMP_WROT0] = {
+		{MDP_COMP_TYPE_WROT, 0, MT8183_MDP_COMP_WROT0},
+		{1, 0, 0},
+		{0, BIT(7), 0}
+	},
+	[MDP_COMP_WDMA] = {
+		{MDP_COMP_TYPE_WDMA, 0, MT8183_MDP_COMP_WDMA},
+		{1, 0, 0},
+		{0, BIT(8), 0}
+	},
+};
+
+static const enum mdp_comp_event mt8183_mdp_event[] = {
+	RDMA0_SOF,
+	RDMA0_DONE,
+	RSZ0_SOF,
+	RSZ1_SOF,
+	TDSHP0_SOF,
+	WROT0_SOF,
+	WROT0_DONE,
+	WDMA0_SOF,
+	WDMA0_DONE,
+	ISP_P2_0_DONE,
+	ISP_P2_1_DONE,
+	ISP_P2_2_DONE,
+	ISP_P2_3_DONE,
+	ISP_P2_4_DONE,
+	ISP_P2_5_DONE,
+	ISP_P2_6_DONE,
+	ISP_P2_7_DONE,
+	ISP_P2_8_DONE,
+	ISP_P2_9_DONE,
+	ISP_P2_10_DONE,
+	ISP_P2_11_DONE,
+	ISP_P2_12_DONE,
+	ISP_P2_13_DONE,
+	ISP_P2_14_DONE,
+	WPE_DONE,
+	WPE_B_DONE
+};
+
+static const struct mdp_pipe_info mt8183_pipe_info[] = {
+	{MDP_PIPE_IMGI, 0, 0},
+	{MDP_PIPE_RDMA0, 0, 1},
+	{MDP_PIPE_WPEI, 0, 2},
+	{MDP_PIPE_WPEI2, 0, 3}
+};
+
+static const struct mdp_format mt8183_formats[] = {
+	{
+		.pixelformat	= V4L2_PIX_FMT_GREY,
+		.mdp_color	= MDP_COLOR_GREY,
+		.depth		= { 8 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB565X,
+		.mdp_color	= MDP_COLOR_RGB565,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB565,
+		.mdp_color	= MDP_COLOR_BGR565,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_RGB24,
+		.mdp_color	= MDP_COLOR_RGB888,
+		.depth		= { 24 },
+		.row_depth	= { 24 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_BGR24,
+		.mdp_color	= MDP_COLOR_BGR888,
+		.depth		= { 24 },
+		.row_depth	= { 24 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_ABGR32,
+		.mdp_color	= MDP_COLOR_BGRA8888,
+		.depth		= { 32 },
+		.row_depth	= { 32 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_ARGB32,
+		.mdp_color	= MDP_COLOR_ARGB8888,
+		.depth		= { 32 },
+		.row_depth	= { 32 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_UYVY,
+		.mdp_color	= MDP_COLOR_UYVY,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_VYUY,
+		.mdp_color	= MDP_COLOR_VYUY,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUYV,
+		.mdp_color	= MDP_COLOR_YUYV,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVYU,
+		.mdp_color	= MDP_COLOR_YVYU,
+		.depth		= { 16 },
+		.row_depth	= { 16 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUV420,
+		.mdp_color	= MDP_COLOR_I420,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVU420,
+		.mdp_color	= MDP_COLOR_YV12,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV12,
+		.mdp_color	= MDP_COLOR_NV12,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV21,
+		.mdp_color	= MDP_COLOR_NV21,
+		.depth		= { 12 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV16,
+		.mdp_color	= MDP_COLOR_NV16,
+		.depth		= { 16 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV61,
+		.mdp_color	= MDP_COLOR_NV61,
+		.depth		= { 16 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV24,
+		.mdp_color	= MDP_COLOR_NV24,
+		.depth		= { 24 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV42,
+		.mdp_color	= MDP_COLOR_NV42,
+		.depth		= { 24 },
+		.row_depth	= { 8 },
+		.num_planes	= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_MT21C,
+		.mdp_color	= MDP_COLOR_420_BLKP_UFO,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 4,
+		.halign		= 5,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_MM21,
+		.mdp_color	= MDP_COLOR_420_BLKP,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 4,
+		.halign		= 5,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV12M,
+		.mdp_color	= MDP_COLOR_NV12,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV21M,
+		.mdp_color	= MDP_COLOR_NV21,
+		.depth		= { 8, 4 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV16M,
+		.mdp_color	= MDP_COLOR_NV16,
+		.depth		= { 8, 8 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_NV61M,
+		.mdp_color	= MDP_COLOR_NV61,
+		.depth		= { 8, 8 },
+		.row_depth	= { 8, 8 },
+		.num_planes	= 2,
+		.walign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YUV420M,
+		.mdp_color	= MDP_COLOR_I420,
+		.depth		= { 8, 2, 2 },
+		.row_depth	= { 8, 4, 4 },
+		.num_planes	= 3,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}, {
+		.pixelformat	= V4L2_PIX_FMT_YVU420M,
+		.mdp_color	= MDP_COLOR_YV12,
+		.depth		= { 8, 2, 2 },
+		.row_depth	= { 8, 4, 4 },
+		.num_planes	= 3,
+		.walign		= 1,
+		.halign		= 1,
+		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
+	}
+};
+
+#endif  // __MT8183_MDP_H__
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
index 87751f0e2513..879a120f78d9 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-cmdq.c
@@ -42,86 +42,116 @@ static bool is_output_disable(const struct img_compparam *param, u32 count)
 		true;
 }
 
+static int mdp_get_mutex_idx(const struct mtk_mdp_driver_data *data,
+			     enum mtk_mdp_pipe_id pipe_id)
+{
+	int i = 0;
+
+	for (i = 0; i < data->pipe_info_len; i++) {
+		if (pipe_id == data->pipe_info[i].pipe_id)
+			return i;
+	}
+
+	return -ENODEV;
+}
+
+int mdp_get_event_idx(struct mdp_dev *mdp, enum mdp_comp_event event)
+{
+	int i = 0;
+
+	for (i = 0; i < mdp->mdp_data->event_len; i++) {
+		if (event == mdp->mdp_data->event[i])
+			return i;
+	}
+
+	return -ENODEV;
+}
+
 static int mdp_path_subfrm_require(struct mdp_path_subfrm *subfrm,
 				   const struct mdp_path *path,
 				   struct mmsys_cmdq_cmd *cmd, u32 count)
 {
 	const struct img_config *config = path->config;
 	const struct mdp_comp_ctx *ctx;
+	const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
 	struct device *dev = &path->mdp_dev->pdev->dev;
 	struct mtk_mutex **mutex = path->mdp_dev->mdp_mutex;
 	s32 mutex_id = -1;
-	u32 mutex_bit = 0;
-	int index, id;
+	u32 mutex_sof = 0;
+	int index, j;
+	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
 
 	/* Default value */
 	memset(subfrm, 0, sizeof(*subfrm));
 
-	/* Decide which mutex to use based on the current pipeline */
-	switch (path->comps[0].comp->id) {
-	case MDP_COMP_RDMA0:
-		mutex_id = MDP_PIPE_RDMA0;
-		break;
-	case MDP_COMP_ISP_IMGI:
-		mutex_id = MDP_PIPE_IMGI;
-		break;
-	case MDP_COMP_WPEI:
-		mutex_id = MDP_PIPE_WPEI;
-		break;
-	case MDP_COMP_WPEI2:
-		mutex_id = MDP_PIPE_WPEI2;
-		break;
-	default:
-		dev_err(dev, "Unknown pipeline and no mutex is assigned");
-		return -EINVAL;
-	}
-	subfrm->mutex_id = mutex_id;
-
-	/* Set mutex mod */
 	for (index = 0; index < config->num_components; index++) {
 		ctx = &path->comps[index];
 		if (is_output_disable(ctx->param, count))
 			continue;
-		id = ctx->comp->id;
-		switch (id) {
+
+		public_id = path->comps[index].comp->public_id;
+		switch (public_id) {
 		case MDP_COMP_AAL0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
 		case MDP_COMP_CCORR0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
 		case MDP_COMP_WDMA:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WDMA;
+			break;
 		case MDP_COMP_WROT0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_WROT0;
+			break;
 		case MDP_COMP_TDSHP0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_TDSHP0;
+			break;
 		case MDP_COMP_RSZ1:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RSZ1;
+			break;
 		case MDP_COMP_RSZ0:
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RSZ0;
+			break;
 		case MDP_COMP_RDMA0:
-			mutex_bit = mtk_mutex_get_mdp_mod(mutex[mutex_id], id);
-			subfrm->mutex_mod |= mutex_bit;
+			j = mdp_get_mutex_idx(data, MDP_PIPE_RDMA0);
+			mutex_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			subfrm->sofs[subfrm->num_sofs++] = MDP_COMP_RDMA0;
+			break;
+		case MDP_COMP_ISP_IMGI:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_IMGI);
+			mutex_id = data->pipe_info[j].mutex_id;
+			break;
+		case MDP_COMP_WPEI:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI);
+			mutex_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
+			break;
+		case MDP_COMP_WPEI2:
+			j = mdp_get_mutex_idx(data, MDP_PIPE_WPEI2);
+			mutex_id = data->pipe_info[j].mutex_id;
+			subfrm->mutex_mod |= data->comp_data[public_id].mutex.mod;
 			break;
 		default:
 			break;
 		}
 	}
 
-	if (subfrm->mutex_mod)
-		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id], subfrm->mutex_mod,
-					  0, 0, cmd);
+	subfrm->mutex_id = mutex_id;
+	if (-1 == mutex_id) {
+		dev_err(dev, "No mutex assigned");
+		return -EINVAL;
+	}
 
-	/* Set SOF */
-	for (index = 0; index < config->num_components; index++) {
-		ctx = &path->comps[index];
-		if (is_output_disable(ctx->param, count))
-			continue;
-		id = ctx->comp->id;
-		switch (id) {
-		case MDP_COMP_WDMA:
-		case MDP_COMP_WROT0:
-		case MDP_COMP_TDSHP0:
-		case MDP_COMP_RSZ1:
-		case MDP_COMP_RSZ0:
-		case MDP_COMP_RDMA0:
-			subfrm->sofs[subfrm->num_sofs++] = id;
-			break;
-		default:
-			break;
-		}
+	/* Set mutex modules */
+	if (subfrm->mutex_mod) {
+		mtk_mutex_add_mod_by_cmdq(mutex[mutex_id], subfrm->mutex_mod,
+					  0, mutex_sof, cmd);
 	}
 
 	return 0;
@@ -141,33 +171,36 @@ static int mdp_path_subfrm_run(const struct mdp_path_subfrm *subfrm,
 	}
 
 	if (subfrm->mutex_mod) {
-		int index;
+		int index, evt;
 
 		/* Wait WROT SRAM shared to DISP RDMA */
 		/* Clear SOF event for each engine */
 		for (index = 0; index < subfrm->num_sofs; index++) {
 			switch (subfrm->sofs[index]) {
 			case MDP_COMP_RDMA0:
-				MM_REG_CLEAR(cmd, RDMA0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA0_SOF);
 				break;
 			case MDP_COMP_TDSHP0:
-				MM_REG_CLEAR(cmd, TDSHP0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, TDSHP0_SOF);
 				break;
 			case MDP_COMP_RSZ0:
-				MM_REG_CLEAR(cmd, RSZ0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RSZ0_SOF);
 				break;
 			case MDP_COMP_RSZ1:
-				MM_REG_CLEAR(cmd, RSZ1_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RSZ1_SOF);
 				break;
 			case MDP_COMP_WDMA:
-				MM_REG_CLEAR(cmd, WDMA0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, WDMA0_SOF);
 				break;
 			case MDP_COMP_WROT0:
-				MM_REG_CLEAR(cmd, WROT0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, WROT0_SOF);
 				break;
 			default:
+				evt = -1;
 				break;
 			}
+			if (evt > 0)
+				MM_REG_CLEAR(cmd, evt);
 		}
 
 		/* Enable the mutex */
@@ -177,26 +210,29 @@ static int mdp_path_subfrm_run(const struct mdp_path_subfrm *subfrm,
 		for (index = 0; index < subfrm->num_sofs; index++) {
 			switch (subfrm->sofs[index]) {
 			case MDP_COMP_RDMA0:
-				MM_REG_WAIT(cmd, RDMA0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RDMA0_SOF);
 				break;
 			case MDP_COMP_TDSHP0:
-				MM_REG_WAIT(cmd, TDSHP0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, TDSHP0_SOF);
 				break;
 			case MDP_COMP_RSZ0:
-				MM_REG_WAIT(cmd, RSZ0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RSZ0_SOF);
 				break;
 			case MDP_COMP_RSZ1:
-				MM_REG_WAIT(cmd, RSZ1_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, RSZ1_SOF);
 				break;
 			case MDP_COMP_WDMA:
-				MM_REG_WAIT(cmd, WDMA0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, WDMA0_SOF);
 				break;
 			case MDP_COMP_WROT0:
-				MM_REG_WAIT(cmd, WROT0_SOF);
+				evt = mdp_get_event_idx(path->mdp_dev, WROT0_SOF);
 				break;
 			default:
+				evt = -1;
 				break;
 			}
+			if (evt > 0)
+				MM_REG_WAIT(cmd, evt);
 		}
 	}
 	return 0;
@@ -229,6 +265,7 @@ static int mdp_path_config_subfrm(struct mmsys_cmdq_cmd *cmd,
 	const struct img_mmsys_ctrl *ctrl = &config->ctrls[count];
 	const struct img_mux *set;
 	struct device *mmsys_dev = path->mdp_dev->mdp_mmsys;
+	const struct mtk_mdp_driver_data *data = path->mdp_dev->mdp_data;
 	struct mdp_comp_ctx *ctx;
 	int index, ret;
 
@@ -331,12 +368,14 @@ static void mdp_auto_release_work(struct work_struct *work)
 {
 	struct mdp_cmdq_cb_param *cb_param;
 	struct mdp_dev *mdp;
+	int i;
 
 	cb_param = container_of(work, struct mdp_cmdq_cb_param,
 				auto_release_work);
 	mdp = cb_param->mdp;
 
-	mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 			    cb_param->num_comps);
 
@@ -352,6 +391,7 @@ static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
 	struct mdp_cmdq_cb_param *cb_param;
 	struct mdp_dev *mdp;
 	struct device *dev;
+	int i;
 
 	if (!data.data) {
 		pr_info("%s:no callback data\n", __func__);
@@ -377,7 +417,8 @@ static void mdp_handle_cmdq_callback(struct cmdq_cb_data data)
 	INIT_WORK(&cb_param->auto_release_work, mdp_auto_release_work);
 	if (!queue_work(mdp->clock_wq, &cb_param->auto_release_work)) {
 		dev_err(dev, "%s:queue_work fail!\n", __func__);
-		mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+		i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+		mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 		mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 				    cb_param->num_comps);
 
@@ -437,7 +478,9 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 		goto err_destroy_pkt;
 	}
 
-	mtk_mutex_prepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+	mtk_mutex_prepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
+
 	for (i = 0; i < param->config->num_components; i++)
 		mdp_comp_clock_on(&mdp->pdev->dev, path->comps[i].comp);
 
@@ -483,7 +526,8 @@ int mdp_cmdq_send(struct mdp_dev *mdp, struct mdp_cmdq_param *param)
 	return 0;
 
 err_clock_off:
-	mtk_mutex_unprepare(mdp->mdp_mutex[MDP_PIPE_RDMA0]);
+	i = mdp_get_mutex_idx(mdp->mdp_data, MDP_PIPE_RDMA0);
+	mtk_mutex_unprepare(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].mutex_id]);
 	mdp_comp_clocks_off(&mdp->pdev->dev, cb_param->comps,
 			    cb_param->num_comps);
 err_destroy_pkt:
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
index 622900d2152c..9073ddc19775 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.c
@@ -19,6 +19,36 @@
 #include "mdp_reg_wdma.h"
 #include "mdp_reg_isp.h"
 
+s32 get_comp_inner_id(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id)
+{
+	if (!mdp_dev)
+		return MDP_COMP_NONE;
+	if (id <= MDP_COMP_NONE || id >= MDP_MAX_COMP_COUNT)
+		return MDP_COMP_NONE;
+
+	return mdp_dev->mdp_data->comp_data[id].match.inner_id;
+}
+
+enum mtk_mdp_comp_id get_comp_public_id(struct mdp_dev *mdp_dev, s32 inner_id)
+{
+	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
+	u32 i;
+
+	if (IS_ERR(mdp_dev) || !inner_id)
+		goto err_public_id;
+
+	for (i = 0; i < MDP_MAX_COMP_COUNT; i++) {
+		if (mdp_dev->mdp_data->comp_data[i].match.inner_id == inner_id) {
+			public_id = i;
+			return public_id;
+		}
+	}
+
+err_public_id:
+	dev_err(&mdp_dev->pdev->dev, "Unmapped inner id %d", inner_id);
+	return public_id;
+}
+
 static const struct mdp_platform_config *__get_plat_cfg(const struct mdp_comp_ctx *ctx)
 {
 	if (!ctx)
@@ -30,12 +60,18 @@ static const struct mdp_platform_config *__get_plat_cfg(const struct mdp_comp_ct
 static s64 get_comp_flag(const struct mdp_comp_ctx *ctx)
 {
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
+	u32 rdma0, rsz1;
+
+	rdma0 = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
+	rsz1 = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_RSZ1);
+	if (!rdma0 || !rsz1)
+		return MDP_COMP_NONE;
 
 	if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing)
-		if (ctx->comp->id == MDP_COMP_RDMA0)
-			return BIT(MDP_COMP_RDMA0) | BIT(MDP_COMP_RSZ1);
+		if (ctx->comp->inner_id == rdma0)
+			return BIT(rdma0) | BIT(rsz1);
 
-	return BIT(ctx->comp->id);
+	return BIT(ctx->comp->inner_id);
 }
 
 static int init_rdma(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
@@ -43,12 +79,17 @@ static int init_rdma(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	s32 rdma0;
 
-	if (mdp_cfg && mdp_cfg->rdma_support_10bit) {
+	rdma0 = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_RDMA0);
+	if (!rdma0)
+		return -EINVAL;
+
+	if (mdp_cfg && mdp_cfg->rdma_rsz1_sram_sharing) {
 		struct mdp_comp *prz1 = ctx->comp->mdp_dev->comp[MDP_COMP_RSZ1];
 
 		/* Disable RSZ1 */
-		if (ctx->comp->id == MDP_COMP_RDMA0 && prz1)
+		if (ctx->comp->inner_id == rdma0 && prz1)
 			MM_REG_WRITE(cmd, subsys_id, prz1->reg_base, PRZ_ENABLE,
 				     0x0, BIT(0));
 	}
@@ -188,14 +229,18 @@ static int config_rdma_subfrm(struct mdp_comp_ctx *ctx,
 static int wait_rdma_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
+	enum mtk_mdp_comp_id id = ctx->comp->public_id;
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	int evt = -1;
 
-	if (ctx->comp->alias_id == 0)
-		MM_REG_WAIT(cmd, RDMA0_DONE);
+	if (id == MDP_COMP_RDMA0)
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, RDMA0_DONE);
 	else
 		dev_err(dev, "Do not support RDMA1_DONE event\n");
 
+	if (evt > 0)
+		MM_REG_WAIT(cmd, evt);
 	/* Disable RDMA */
 	MM_REG_WRITE(cmd, subsys_id, base, MDP_RDMA_EN, 0x0, BIT(0));
 	return 0;
@@ -416,14 +461,19 @@ static int wait_wrot_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	const struct mdp_platform_config *mdp_cfg = __get_plat_cfg(ctx);
 	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
+	enum mtk_mdp_comp_id id = ctx->comp->public_id;
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	int evt = -1;
 
-	if (ctx->comp->alias_id == 0)
-		MM_REG_WAIT(cmd, WROT0_DONE);
+	if (id == MDP_COMP_WROT0)
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, WROT0_DONE);
 	else
 		dev_err(dev, "Do not support WROT1_DONE event\n");
 
+	if (evt > 0)
+		MM_REG_WAIT(cmd, evt);
+
 	if (mdp_cfg && mdp_cfg->wrot_filter_constraint)
 		MM_REG_WRITE(cmd, subsys_id, base, VIDO_MAIN_BUF_SIZE, 0x0,
 			     0x77);
@@ -526,8 +576,11 @@ static int wait_wdma_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	int evt;
 
-	MM_REG_WAIT(cmd, WDMA0_DONE);
+	evt = mdp_get_event_idx(ctx->comp->mdp_dev, WDMA0_DONE);
+	if (evt > 0)
+		MM_REG_WAIT(cmd, evt);
 	/* Disable WDMA */
 	MM_REG_WRITE(cmd, subsys_id, base, WDMA_EN, 0x0, BIT(0));
 	return 0;
@@ -592,14 +645,20 @@ static int init_isp(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 {
 	struct device *dev = ctx->comp->mdp_dev->mdp_mmsys;
 	const struct isp_data *isp = &ctx->param->isp;
+	s32 camin, camin2;
+
+	camin = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_CAMIN);
+	camin2 = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_CAMIN2);
+	if (!camin || !camin2)
+		return -EINVAL;
 
 	/* Direct link */
-	if (isp->dl_flags & BIT(MDP_COMP_CAMIN)) {
+	if (isp->dl_flags & BIT(camin)) {
 		dev_dbg(dev, "SW_RST ASYNC");
 		mtk_mmsys_mdp_isp_ctrl(dev, cmd, MDP_COMP_CAMIN);
 	}
 
-	if (isp->dl_flags & BIT(MDP_COMP_CAMIN2)) {
+	if (isp->dl_flags & BIT(camin2)) {
 		dev_dbg(dev, "SW_RST ASYNC2");
 		mtk_mmsys_mdp_isp_ctrl(dev, cmd, MDP_COMP_CAMIN2);
 	}
@@ -711,69 +770,78 @@ static int wait_isp_event(struct mdp_comp_ctx *ctx, struct mmsys_cmdq_cmd *cmd)
 	struct device *dev = &ctx->comp->mdp_dev->pdev->dev;
 	phys_addr_t base = ctx->comp->reg_base;
 	u8 subsys_id = ctx->comp->subsys_id;
+	int evt;
+	s32 camin, camin2;
+
+	camin = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_CAMIN);
+	camin2 = get_comp_inner_id(ctx->comp->mdp_dev, MDP_COMP_CAMIN2);
+	if (!camin || !camin2)
+		return MDP_COMP_NONE;
 
 	/* MDP_DL_SEL: select MDP_CROP */
-	if (isp->dl_flags & BIT(MDP_COMP_CAMIN))
+	if (isp->dl_flags & BIT(camin))
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0, BIT(9));
 	/* MDP2_DL_SEL: select MDP_CROP2 */
-	if (isp->dl_flags & BIT(MDP_COMP_CAMIN2))
+	if (isp->dl_flags & BIT(camin2))
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x30, 0x0,
 				  BIT(10) | BIT(11));
 
 	switch (isp->cq_idx) {
 	case ISP_DRV_DIP_CQ_THRE0:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(0), BIT(0));
-		MM_REG_WAIT(cmd, ISP_P2_0_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_0_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE1:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(1), BIT(1));
-		MM_REG_WAIT(cmd, ISP_P2_1_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_1_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE2:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(2), BIT(2));
-		MM_REG_WAIT(cmd, ISP_P2_2_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_2_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE3:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(3), BIT(3));
-		MM_REG_WAIT(cmd, ISP_P2_3_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_3_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE4:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(4), BIT(4));
-		MM_REG_WAIT(cmd, ISP_P2_4_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_4_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE5:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(5), BIT(5));
-		MM_REG_WAIT(cmd, ISP_P2_5_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_5_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE6:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(6), BIT(6));
-		MM_REG_WAIT(cmd, ISP_P2_6_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_6_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE7:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(7), BIT(7));
-		MM_REG_WAIT(cmd, ISP_P2_7_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_7_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE8:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(8), BIT(8));
-		MM_REG_WAIT(cmd, ISP_P2_8_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_8_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE9:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(9), BIT(9));
-		MM_REG_WAIT(cmd, ISP_P2_9_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_9_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE10:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(10), BIT(10));
-		MM_REG_WAIT(cmd, ISP_P2_10_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_10_DONE);
 		break;
 	case ISP_DRV_DIP_CQ_THRE11:
 		MM_REG_WRITE_MASK(cmd, subsys_id, base, 0x2000, BIT(11), BIT(11));
-		MM_REG_WAIT(cmd, ISP_P2_11_DONE);
+		evt = mdp_get_event_idx(ctx->comp->mdp_dev, ISP_P2_11_DONE);
 		break;
 	default:
 		dev_err(dev, "Do not support this cq (%d)", isp->cq_idx);
 		return -EINVAL;
 	}
 
+	MM_REG_WAIT(cmd, evt);
+
 	return 0;
 }
 
@@ -832,52 +900,25 @@ static const struct mdp_comp_ops *mdp_comp_ops[MDP_COMP_TYPE_COUNT] = {
 	[MDP_COMP_TYPE_DL_PATH2] =	&camin_ops,
 };
 
-struct mdp_comp_match {
-	enum mtk_mdp_comp_id id;
-	enum mdp_comp_type	type;
-	u32			alias_id;
-};
-
-static const struct mdp_comp_match mdp_comp_matches[MDP_MAX_COMP_COUNT] = {
-	[MDP_COMP_WPEI] =	{ MDP_COMP_WPEI, MDP_COMP_TYPE_WPEI, 0 },
-	[MDP_COMP_WPEO] =	{ MDP_COMP_WPEO, MDP_COMP_TYPE_EXTO, 2 },
-	[MDP_COMP_WPEI2] =	{ MDP_COMP_WPEI2, MDP_COMP_TYPE_WPEI, 1 },
-	[MDP_COMP_WPEO2] =	{ MDP_COMP_WPEO2, MDP_COMP_TYPE_EXTO, 3 },
-	[MDP_COMP_ISP_IMGI] =	{ MDP_COMP_ISP_IMGI, MDP_COMP_TYPE_IMGI, 0 },
-	[MDP_COMP_ISP_IMGO] =	{ MDP_COMP_ISP_IMGO, MDP_COMP_TYPE_EXTO, 0 },
-	[MDP_COMP_ISP_IMG2O] =	{ MDP_COMP_ISP_IMG2O, MDP_COMP_TYPE_EXTO, 1 },
-
-	[MDP_COMP_CAMIN] =	{ MDP_COMP_CAMIN, MDP_COMP_TYPE_DL_PATH1, 0 },
-	[MDP_COMP_CAMIN2] =	{ MDP_COMP_CAMIN2, MDP_COMP_TYPE_DL_PATH2, 1 },
-	[MDP_COMP_RDMA0] =	{ MDP_COMP_RDMA0, MDP_COMP_TYPE_RDMA, 0 },
-	[MDP_COMP_CCORR0] =	{ MDP_COMP_CCORR0, MDP_COMP_TYPE_CCORR, 0 },
-	[MDP_COMP_RSZ0] =	{ MDP_COMP_RSZ0, MDP_COMP_TYPE_RSZ, 0 },
-	[MDP_COMP_RSZ1] =	{ MDP_COMP_RSZ1, MDP_COMP_TYPE_RSZ, 1 },
-	[MDP_COMP_PATH0_SOUT] =	{ MDP_COMP_PATH0_SOUT, MDP_COMP_TYPE_PATH1, 0 },
-	[MDP_COMP_PATH1_SOUT] =	{ MDP_COMP_PATH1_SOUT, MDP_COMP_TYPE_PATH2, 1 },
-	[MDP_COMP_WROT0] =	{ MDP_COMP_WROT0, MDP_COMP_TYPE_WROT, 0 },
-	[MDP_COMP_WDMA] =	{ MDP_COMP_WDMA, MDP_COMP_TYPE_WDMA, 0 },
-};
-
 static const struct of_device_id mdp_comp_dt_ids[] = {
 	{
 		.compatible = "mediatek,mt8183-mdp3-rdma0",
-		.data = &mdp_comp_matches[MDP_COMP_RDMA0],
+		.data = (void *)MDP_COMP_RDMA0,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-ccorr",
-		.data = &mdp_comp_matches[MDP_COMP_CCORR0],
+		.data = (void *)MDP_COMP_CCORR0,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-rsz0",
-		.data = &mdp_comp_matches[MDP_COMP_RSZ0],
+		.data = (void *)MDP_COMP_RSZ0,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-rsz1",
-		.data = &mdp_comp_matches[MDP_COMP_RSZ1],
+		.data = (void *)MDP_COMP_RSZ1,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-wrot0",
-		.data = &mdp_comp_matches[MDP_COMP_WROT0],
+		.data = (void *)MDP_COMP_WROT0,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-wdma",
-		.data = &mdp_comp_matches[MDP_COMP_WDMA],
+		.data = (void *)MDP_COMP_WDMA,
 	},
 	{}
 };
@@ -885,47 +926,26 @@ static const struct of_device_id mdp_comp_dt_ids[] = {
 static const struct of_device_id mdp_sub_comp_dt_ids[] = {
 	{
 		.compatible = "mediatek,mt8183-mdp3-path1",
-		.data = &mdp_comp_matches[MDP_COMP_PATH0_SOUT],
+		.data = (void *)MDP_COMP_PATH0_SOUT,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-path2",
-		.data = &mdp_comp_matches[MDP_COMP_PATH1_SOUT],
+		.data = (void *)MDP_COMP_PATH1_SOUT,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-imgi",
-		.data = &mdp_comp_matches[MDP_COMP_ISP_IMGI],
+		.data = (void *)MDP_COMP_ISP_IMGI,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-exto",
-		.data = &mdp_comp_matches[MDP_COMP_ISP_IMGO],
+		.data = (void *)MDP_COMP_ISP_IMGO,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-dl1",
-		.data = &mdp_comp_matches[MDP_COMP_CAMIN],
+		.data = (void *)MDP_COMP_CAMIN,
 	}, {
 		.compatible = "mediatek,mt8183-mdp3-dl2",
-		.data = &mdp_comp_matches[MDP_COMP_CAMIN2],
+		.data = (void *)MDP_COMP_CAMIN2,
 	},
 	{}
 };
 
-/* Used to describe the item order in MDP property */
-struct mdp_comp_info {
-	u32	clk_num;
-	u32	clk_ofst;
-	u32	dts_reg_ofst;
-};
-
-static const struct mdp_comp_info mdp_comp_dt_info[MDP_COMP_TYPE_COUNT] = {
-	[MDP_COMP_TYPE_RDMA]		= {2, 0, 0},
-	[MDP_COMP_TYPE_RSZ]		= {1, 0, 0},
-	[MDP_COMP_TYPE_WROT]		= {1, 0, 0},
-	[MDP_COMP_TYPE_WDMA]		= {1, 0, 0},
-	[MDP_COMP_TYPE_PATH1]		= {0, 0, 2},
-	[MDP_COMP_TYPE_PATH2]		= {0, 0, 3},
-	[MDP_COMP_TYPE_CCORR]		= {1, 0, 0},
-	[MDP_COMP_TYPE_IMGI]		= {0, 0, 4},
-	[MDP_COMP_TYPE_EXTO]		= {0, 0, 4},
-	[MDP_COMP_TYPE_DL_PATH1]	= {2, 2, 1},
-	[MDP_COMP_TYPE_DL_PATH2]	= {2, 4, 1},
-};
-
 void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
 {
 	int i, err;
@@ -935,7 +955,7 @@ void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
 		if (err < 0)
 			dev_err(dev,
 				"Failed to get power, err %d. type:%d id:%d\n",
-				err, comp->type, comp->id);
+				err, comp->type, comp->inner_id);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(comp->clks); i++) {
@@ -945,7 +965,7 @@ void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp)
 		if (err)
 			dev_err(dev,
 				"Failed to enable clk %d. type:%d id:%d\n",
-				i, comp->type, comp->id);
+				i, comp->type, comp->inner_id);
 	}
 }
 
@@ -979,7 +999,7 @@ void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num)
 		mdp_comp_clock_off(dev, &comps[i]);
 }
 
-static int mdp_get_subsys_id(struct device *dev, struct device_node *node,
+static int mdp_get_subsys_id(struct mdp_dev *mdp, struct device *dev, struct device_node *node,
 			     struct mdp_comp *comp)
 {
 	struct platform_device *comp_pdev;
@@ -993,12 +1013,12 @@ static int mdp_get_subsys_id(struct device *dev, struct device_node *node,
 	comp_pdev = of_find_device_by_node(node);
 
 	if (!comp_pdev) {
-		dev_err(dev, "get comp_pdev fail! comp id=%d type=%d\n",
-			comp->id, comp->type);
+		dev_err(dev, "get comp_pdev fail! comp public id=%d, inner id = %d, type=%d\n",
+			comp->public_id, comp->inner_id, comp->type);
 		return -ENODEV;
 	}
 
-	index = mdp_comp_dt_info[comp->type].dts_reg_ofst;
+	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
 	ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index);
 	if (ret != 0) {
 		dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n");
@@ -1016,8 +1036,9 @@ static void __mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
 {
 	struct resource res;
 	phys_addr_t base;
-	int index = mdp_comp_dt_info[comp->type].dts_reg_ofst;
+	int index;
 
+	index = mdp->mdp_data->comp_data[comp->public_id].info.dts_reg_ofst;
 	if (of_address_to_resource(node, index, &res) < 0)
 		base = 0L;
 	else
@@ -1041,14 +1062,15 @@ static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
 		return -EINVAL;
 	}
 
-	comp->type = mdp_comp_matches[id].type;
-	comp->id = mdp_comp_matches[id].id;
-	comp->alias_id = mdp_comp_matches[id].alias_id;
+	comp->public_id = id;
+	comp->type = mdp->mdp_data->comp_data[id].match.type;
+	comp->inner_id = mdp->mdp_data->comp_data[id].match.inner_id;
+	comp->alias_id = mdp->mdp_data->comp_data[id].match.alias_id;
 	comp->ops = mdp_comp_ops[comp->type];
 	__mdp_comp_init(mdp, node, comp);
 
-	clk_num = mdp_comp_dt_info[comp->type].clk_num;
-	clk_ofst = mdp_comp_dt_info[comp->type].clk_ofst;
+	clk_num = mdp->mdp_data->comp_data[id].info.clk_num;
+	clk_ofst = mdp->mdp_data->comp_data[id].info.clk_ofst;
 
 	for (i = 0; i < clk_num; i++) {
 		comp->clks[i] = of_clk_get(node, i + clk_ofst);
@@ -1056,14 +1078,14 @@ static int mdp_comp_init(struct mdp_dev *mdp, struct device_node *node,
 			break;
 	}
 
-	mdp_get_subsys_id(dev, node, comp);
+	mdp_get_subsys_id(mdp, dev, node, comp);
 
 	return 0;
 }
 
 static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
 					struct device_node *node,
-					enum mtk_mdp_comp_id id)
+					enum mtk_mdp_comp_id  id)
 {
 	struct device *dev = &mdp->pdev->dev;
 	struct mdp_comp *comp;
@@ -1084,8 +1106,8 @@ static struct mdp_comp *mdp_comp_create(struct mdp_dev *mdp,
 	mdp->comp[id] = comp;
 	mdp->comp[id]->mdp_dev = mdp;
 
-	dev_info(dev, "%s type:%d alias:%d id:%d base:%#x regs:%p\n",
-		 dev->of_node->name, comp->type, comp->alias_id, id,
+	dev_info(dev, "%s type:%d alias:%d public id:%d inner_id:%d base:%#x regs:%p\n",
+		 dev->of_node->name, comp->type, comp->alias_id, id, comp->inner_id,
 		 (u32)comp->reg_base, comp->regs);
 	return comp;
 }
@@ -1097,21 +1119,22 @@ static int mdp_sub_comps_create(struct mdp_dev *mdp, struct device_node *node)
 	int index = 0;
 
 	of_property_for_each_string(node, "mediatek,mdp3-comps", prop, name) {
-		const struct of_device_id *list = mdp_sub_comp_dt_ids;
-		struct mdp_comp_match *match = NULL;
+		const struct of_device_id *matches = mdp_sub_comp_dt_ids;
+		enum mtk_mdp_comp_id id = MDP_COMP_NONE;
 		struct mdp_comp *comp;
 
-		for (; list->compatible[0]; list++) {
-			if (of_compat_cmp(name, list->compatible,
-					  strlen(list->compatible)) == 0) {
-				match = (struct mdp_comp_match *)list->data;
+		for (; matches->compatible[0]; matches++) {
+			if (of_compat_cmp(name, matches->compatible,
+					  strlen(matches->compatible)) == 0) {
+				id = (enum mtk_mdp_comp_id)matches->data;
 				break;
 			}
 		}
 
-		if (match)
-			comp = mdp_comp_create(mdp, node, match->id);
+		if (id == MDP_COMP_NONE)
+			return -ENODEV;
 
+		comp = mdp_comp_create(mdp, node, id);
 		if (IS_ERR(comp))
 			return PTR_ERR(comp);
 
@@ -1133,8 +1156,8 @@ void mdp_component_deinit(struct mdp_dev *mdp)
 {
 	int i;
 
-	for (i = 0; i < MDP_PIPE_MAX; i++)
-		mtk_mutex_put(mdp->mdp_mutex[i]);
+	for (i = 0; i < mdp->mdp_data->pipe_info_len; i++)
+		mtk_mutex_put(mdp->mdp_mutex[mdp->mdp_data->pipe_info[i].pipe_id]);
 
 	for (i = 0; i < ARRAY_SIZE(mdp->comp); i++) {
 		if (mdp->comp[i]) {
@@ -1156,7 +1179,7 @@ int mdp_component_init(struct mdp_dev *mdp)
 	/* Iterate over sibling MDP function blocks */
 	for_each_child_of_node(parent, node) {
 		const struct of_device_id *of_id;
-		struct mdp_comp_match *match;
+		enum mtk_mdp_comp_id id;
 		struct mdp_comp *comp;
 
 		of_id = of_match_node(mdp_comp_dt_ids, node);
@@ -1168,9 +1191,8 @@ int mdp_component_init(struct mdp_dev *mdp)
 			continue;
 		}
 
-		match = (struct mdp_comp_match *)of_id->data;
-
-		comp = mdp_comp_create(mdp, node, match->id);
+		id = (enum mtk_mdp_comp_id)of_id->data;
+		comp = mdp_comp_create(mdp, node, id);
 		if (IS_ERR(comp))
 			goto err_init_comps;
 
@@ -1207,16 +1229,15 @@ int mdp_comp_ctx_init(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
 	const struct img_ipi_frameparam *frame)
 {
 	struct device *dev = &mdp->pdev->dev;
+	enum mtk_mdp_comp_id public_id = MDP_COMP_NONE;
 	int i;
 
-	if (param->type < 0 || param->type >= MDP_MAX_COMP_COUNT) {
-		dev_err(dev, "Invalid component id %d", param->type);
+	public_id = get_comp_public_id(mdp, param->type);
+	if (!public_id)
 		return -EINVAL;
-	}
-
-	ctx->comp = mdp->comp[param->type];
+	ctx->comp = mdp->comp[public_id];
 	if (!ctx->comp) {
-		dev_err(dev, "Uninit component id %d", param->type);
+		dev_err(dev, "Uninit component inner id %d", param->type);
 		return -EINVAL;
 	}
 
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
index 7b34f9c42410..57f5ca3052ba 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-comp.h
@@ -41,24 +41,38 @@
 enum mdp_comp_type {
 	MDP_COMP_TYPE_INVALID = 0,
 
+	MDP_COMP_TYPE_IMGI,
+	MDP_COMP_TYPE_WPEI,
+
 	MDP_COMP_TYPE_RDMA,
 	MDP_COMP_TYPE_RSZ,
 	MDP_COMP_TYPE_WROT,
 	MDP_COMP_TYPE_WDMA,
 	MDP_COMP_TYPE_PATH1,
 	MDP_COMP_TYPE_PATH2,
+	MDP_COMP_TYPE_SPLIT,
+	MDP_COMP_TYPE_STITCH,
+	MDP_COMP_TYPE_FG,
+	MDP_COMP_TYPE_OVL,
+	MDP_COMP_TYPE_PAD,
+	MDP_COMP_TYPE_MERGE,
 
 	MDP_COMP_TYPE_TDSHP,
 	MDP_COMP_TYPE_COLOR,
 	MDP_COMP_TYPE_DRE,
 	MDP_COMP_TYPE_CCORR,
 	MDP_COMP_TYPE_HDR,
+	MDP_COMP_TYPE_AAL,
+	MDP_COMP_TYPE_TCC,
 
-	MDP_COMP_TYPE_IMGI,
-	MDP_COMP_TYPE_WPEI,
 	MDP_COMP_TYPE_EXTO,	/* External path */
 	MDP_COMP_TYPE_DL_PATH1, /* Direct-link path1 */
 	MDP_COMP_TYPE_DL_PATH2, /* Direct-link path2 */
+	MDP_COMP_TYPE_DL_PATH3, /* Direct-link path3 */
+	MDP_COMP_TYPE_DL_PATH4, /* Direct-link path4 */
+	MDP_COMP_TYPE_DL_PATH5, /* Direct-link path5 */
+	MDP_COMP_TYPE_DL_PATH6, /* Direct-link path6 */
+	MDP_COMP_TYPE_DUMMY,
 
 	MDP_COMP_TYPE_COUNT	/* ALWAYS keep at the end */
 };
@@ -73,6 +87,18 @@ enum mdp_comp_event {
 	WROT0_DONE,
 	WDMA0_SOF,
 	WDMA0_DONE,
+	RDMA1_SOF,
+	RDMA2_SOF,
+	RDMA3_SOF,
+	WROT1_SOF,
+	WROT2_SOF,
+	WROT3_SOF,
+	RDMA1_FRAME_DONE,
+	RDMA2_FRAME_DONE,
+	RDMA3_FRAME_DONE,
+	WROT1_FRAME_DONE,
+	WROT2_FRAME_DONE,
+	WROT3_FRAME_DONE,
 
 	ISP_P2_0_DONE,
 	ISP_P2_1_DONE,
@@ -96,6 +122,43 @@ enum mdp_comp_event {
 	MDP_MAX_EVENT_COUNT	/* ALWAYS keep at the end */
 };
 
+enum mdp_mmsys_config_id {
+	CONFIG_VPP0_HW_DCM_1ST_DIS0,
+	CONFIG_VPP0_DL_IRELAY_WR,
+	CONFIG_VPP1_HW_DCM_1ST_DIS0,
+	CONFIG_VPP1_HW_DCM_1ST_DIS1,
+	CONFIG_VPP1_HW_DCM_2ND_DIS0,
+	CONFIG_VPP1_HW_DCM_2ND_DIS1,
+	CONFIG_SVPP2_BUF_BF_RSZ_SWITCH,
+	CONFIG_SVPP3_BUF_BF_RSZ_SWITCH,
+	MDP_MAX_CONFIG_COUNT
+};
+
+struct mdp_comp_match {
+	enum mdp_comp_type type;
+	u32 alias_id;
+	s32 inner_id;
+};
+
+/* Used to describe the item order in MDP property */
+struct mdp_comp_info {
+	u32 clk_num;
+	u32 clk_ofst;
+	u32 dts_reg_ofst;
+};
+
+struct mdp_mutex_info {
+	u32 mmsys_id;
+	u32 mod;
+	u32 mod2;
+};
+
+struct mdp_comp_data {
+	struct mdp_comp_match match;
+	struct mdp_comp_info info;
+	struct mdp_mutex_info mutex;
+};
+
 struct mdp_comp_ops;
 
 struct mdp_comp {
@@ -106,8 +169,9 @@ struct mdp_comp {
 	struct clk			*clks[6];
 	struct device			*comp_dev;
 	enum mdp_comp_type		type;
-	enum mtk_mdp_comp_id		id;
+	enum mtk_mdp_comp_id		public_id;
 	u32				alias_id;
+	s32				inner_id;
 	const struct mdp_comp_ops	*ops;
 };
 
@@ -134,6 +198,11 @@ struct mdp_comp_ops {
 
 struct mdp_dev;
 
+s32 get_comp_inner_id(struct mdp_dev *mdp_dev, enum mtk_mdp_comp_id id);
+enum mtk_mdp_comp_id get_comp_public_id(struct mdp_dev *mdp_dev, s32 id);
+bool is_dummy_engine(struct mdp_dev *mdp_dev, s32 inner_id);
+bool is_rdma(struct mdp_dev *mdp_dev, s32 inner_id);
+
 int mdp_component_init(struct mdp_dev *mdp);
 void mdp_component_deinit(struct mdp_dev *mdp);
 void mdp_comp_clock_on(struct device *dev, struct mdp_comp *comp);
@@ -142,6 +211,8 @@ void mdp_comp_clocks_on(struct device *dev, struct mdp_comp *comps, int num);
 void mdp_comp_clocks_off(struct device *dev, struct mdp_comp *comps, int num);
 int mdp_comp_ctx_init(struct mdp_dev *mdp, struct mdp_comp_ctx *ctx,
 		      const struct img_compparam *param,
-	const struct img_ipi_frameparam *frame);
+		      const struct img_ipi_frameparam *frame);
+
+int mdp_get_event_idx(struct mdp_dev *mdp, enum mdp_comp_event event);
 
 #endif  /* __MTK_MDP3_COMP_H__ */
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
index 535a9b51ee88..a646e99e410f 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.c
@@ -14,18 +14,17 @@
 #include <media/videobuf2-dma-contig.h>
 #include "mtk-mdp3-core.h"
 #include "mtk-mdp3-m2m.h"
-
-static const struct mdp_platform_config mt8183_plat_cfg = {
-	.rdma_support_10bit		= true,
-	.rdma_rsz1_sram_sharing		= true,
-	.rdma_upsample_repeat_only	= true,
-	.rsz_disable_dcm_small_sample	= false,
-	.wrot_filter_constraint		= false,
-	.gce_event_offset		= 2,
-};
+#include "mt8183_mdp.h"
 
 static const struct mtk_mdp_driver_data mt8183_mdp_driver_data = {
 	.mdp_cfg = &mt8183_plat_cfg,
+	.event = mt8183_mdp_event,
+	.event_len = ARRAY_SIZE(mt8183_mdp_event),
+	.comp_data = mt8183_mdp_comp_data,
+	.pipe_info = mt8183_pipe_info,
+	.pipe_info_len = ARRAY_SIZE(mt8183_pipe_info),
+	.format = mt8183_formats,
+	.format_len = ARRAY_SIZE(mt8183_formats),
 };
 
 static const struct of_device_id mdp_of_ids[] = {
@@ -140,7 +139,7 @@ static int mdp_probe(struct platform_device *pdev)
 	struct device_node *mdp_node;
 	struct platform_device *mm_pdev;
 	u32 event_ofst;
-	int ret, i;
+	int ret, i, mutex_id;
 
 	mdp = kzalloc(sizeof(*mdp), GFP_KERNEL);
 	if (!mdp) {
@@ -164,7 +163,7 @@ static int mdp_probe(struct platform_device *pdev)
 	}
 
 	event_ofst = mdp->mdp_data->mdp_cfg->gce_event_offset;
-	for (i = RDMA0_SOF; i < MDP_MAX_EVENT_COUNT; i++) {
+	for (i = 0; i < mdp->mdp_data->event_len; i++) {
 		s32 event_id;
 
 		if (!dev)
@@ -188,9 +187,15 @@ static int mdp_probe(struct platform_device *pdev)
 		goto err_return;
 	}
 
-	for (i = 0; i < MDP_PIPE_MAX; i++) {
-		mdp->mdp_mutex[i] = mtk_mutex_mdp_get(&mm_pdev->dev, i);
-		if (!mdp->mdp_mutex[i]) {
+	for (i = 0; i < mdp->mdp_data->pipe_info_len; i++) {
+		mutex_id = mdp->mdp_data->pipe_info[i].mutex_id;
+		if (mdp->mdp_mutex[mutex_id])
+			continue;
+
+		mdp->mdp_mutex[mutex_id] =
+			mtk_mutex_mdp_get(&mm_pdev->dev, mdp->mdp_data->pipe_info[i].pipe_id);
+
+		if (!mdp->mdp_mutex[mutex_id]) {
 			ret = -ENODEV;
 			goto err_return;
 		}
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
index d688071b0bf1..119af7666b59 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-core.h
@@ -31,10 +31,19 @@ struct mdp_platform_config {
 	bool	rsz_disable_dcm_small_sample;
 	bool	wrot_filter_constraint;
 	u32	gce_event_offset;
+	bool	support_multi_larb;
 };
 
 struct mtk_mdp_driver_data {
 	const struct mdp_platform_config *mdp_cfg;
+	const enum mdp_comp_event *event;
+	unsigned int event_len;
+	const struct mdp_comp_data *comp_data;
+	const struct mdp_pipe_info *pipe_info;
+	unsigned int pipe_info_len;
+	const struct mdp_format *format;
+	unsigned int format_len;
+	const enum mdp_mmsys_config_id *config_table;
 };
 
 struct mdp_dev {
@@ -67,6 +76,13 @@ struct mdp_dev {
 	atomic_t				job_count;
 };
 
+struct mdp_pipe_info {
+	enum mtk_mdp_pipe_id pipe_id;
+	u32 mmsys_id;
+	u32 mutex_id;
+	u32 sof;
+};
+
 int mdp_vpu_get_locked(struct mdp_dev *mdp);
 void mdp_vpu_put_locked(struct mdp_dev *mdp);
 int mdp_vpu_register(struct mdp_dev *mdp);
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
index 9b3d9a59ae48..ca1c19c41950 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-m2m.c
@@ -617,6 +617,8 @@ static int mdp_m2m_open(struct file *file)
 	int ret;
 	struct v4l2_format default_format;
 
+	mdp_format_init(mdp->mdp_data->format, mdp->mdp_data->format_len);
+
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
 		return -ENOMEM;
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
index 439711298867..83e91735202b 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.c
@@ -11,226 +11,8 @@
 #include "mtk-mdp3-regs.h"
 #include "mtk-mdp3-m2m.h"
 
-static const struct mdp_format mdp_formats[] = {
-	{
-		.pixelformat	= V4L2_PIX_FMT_GREY,
-		.mdp_color	= MDP_COLOR_GREY,
-		.depth		= { 8 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_RGB565X,
-		.mdp_color	= MDP_COLOR_RGB565,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_RGB565,
-		.mdp_color	= MDP_COLOR_BGR565,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_RGB24,
-		.mdp_color	= MDP_COLOR_RGB888,
-		.depth		= { 24 },
-		.row_depth	= { 24 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_BGR24,
-		.mdp_color	= MDP_COLOR_BGR888,
-		.depth		= { 24 },
-		.row_depth	= { 24 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_ABGR32,
-		.mdp_color	= MDP_COLOR_BGRA8888,
-		.depth		= { 32 },
-		.row_depth	= { 32 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_ARGB32,
-		.mdp_color	= MDP_COLOR_ARGB8888,
-		.depth		= { 32 },
-		.row_depth	= { 32 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_UYVY,
-		.mdp_color	= MDP_COLOR_UYVY,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_VYUY,
-		.mdp_color	= MDP_COLOR_VYUY,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YUYV,
-		.mdp_color	= MDP_COLOR_YUYV,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YVYU,
-		.mdp_color	= MDP_COLOR_YVYU,
-		.depth		= { 16 },
-		.row_depth	= { 16 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YUV420,
-		.mdp_color	= MDP_COLOR_I420,
-		.depth		= { 12 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YVU420,
-		.mdp_color	= MDP_COLOR_YV12,
-		.depth		= { 12 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV12,
-		.mdp_color	= MDP_COLOR_NV12,
-		.depth		= { 12 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV21,
-		.mdp_color	= MDP_COLOR_NV21,
-		.depth		= { 12 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV16,
-		.mdp_color	= MDP_COLOR_NV16,
-		.depth		= { 16 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV61,
-		.mdp_color	= MDP_COLOR_NV61,
-		.depth		= { 16 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV24,
-		.mdp_color	= MDP_COLOR_NV24,
-		.depth		= { 24 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV42,
-		.mdp_color	= MDP_COLOR_NV42,
-		.depth		= { 24 },
-		.row_depth	= { 8 },
-		.num_planes	= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_MT21C,
-		.mdp_color	= MDP_COLOR_420_BLK_UFO,
-		.depth		= { 8, 4 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 4,
-		.halign		= 5,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_MM21,
-		.mdp_color	= MDP_COLOR_420_BLK,
-		.depth		= { 8, 4 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 4,
-		.halign		= 5,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV12M,
-		.mdp_color	= MDP_COLOR_NV12,
-		.depth		= { 8, 4 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV21M,
-		.mdp_color	= MDP_COLOR_NV21,
-		.depth		= { 8, 4 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV16M,
-		.mdp_color	= MDP_COLOR_NV16,
-		.depth		= { 8, 8 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_NV61M,
-		.mdp_color	= MDP_COLOR_NV61,
-		.depth		= { 8, 8 },
-		.row_depth	= { 8, 8 },
-		.num_planes	= 2,
-		.walign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YUV420M,
-		.mdp_color	= MDP_COLOR_I420,
-		.depth		= { 8, 2, 2 },
-		.row_depth	= { 8, 4, 4 },
-		.num_planes	= 3,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}, {
-		.pixelformat	= V4L2_PIX_FMT_YVU420M,
-		.mdp_color	= MDP_COLOR_YV12,
-		.depth		= { 8, 2, 2 },
-		.row_depth	= { 8, 4, 4 },
-		.num_planes	= 3,
-		.walign		= 1,
-		.halign		= 1,
-		.flags		= MDP_FMT_FLAG_OUTPUT | MDP_FMT_FLAG_CAPTURE,
-	}
-};
+static const struct mdp_format *mdp_formats;
+static u32 format_len;
 
 static const struct mdp_limit mdp_def_limit = {
 	.out_limit = {
@@ -257,7 +39,7 @@ static const struct mdp_format *mdp_find_fmt(u32 pixelformat, u32 type)
 
 	flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT :
 					MDP_FMT_FLAG_CAPTURE;
-	for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) {
+	for (i = 0; i < format_len; ++i) {
 		if (!(mdp_formats[i].flags & flag))
 			continue;
 		if (mdp_formats[i].pixelformat == pixelformat)
@@ -272,7 +54,7 @@ static const struct mdp_format *mdp_find_fmt_by_index(u32 index, u32 type)
 
 	flag = V4L2_TYPE_IS_OUTPUT(type) ? MDP_FMT_FLAG_OUTPUT :
 					MDP_FMT_FLAG_CAPTURE;
-	for (i = 0; i < ARRAY_SIZE(mdp_formats); ++i) {
+	for (i = 0; i < format_len; ++i) {
 		if (!(mdp_formats[i].flags & flag))
 			continue;
 		if (index == num)
@@ -735,3 +517,10 @@ int mdp_frameparam_init(struct mdp_frameparam *param)
 
 	return 0;
 }
+
+void mdp_format_init(const struct mdp_format *format, u32 length)
+{
+	mdp_formats = format;
+	format_len = length;
+}
+
diff --git a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
index 3ff784aa372b..0fdc1b228227 100644
--- a/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
+++ b/drivers/media/platform/mtk-mdp3/mtk-mdp3-regs.h
@@ -18,14 +18,17 @@
  * V-subsample: 0, 1
  * Color group: 0-RGB, 1-YUV, 2-raw
  */
-#define MDP_COLOR(PACKED, LOOSE, VIDEO, PLANE, HF, VF, BITS, GROUP, SWAP, ID)\
-	(((PACKED) << 27) | ((LOOSE) << 26) | ((VIDEO) << 23) |\
+#define MDP_COLOR(COMPRESS, PACKED, LOOSE, VIDEO, PLANE, HF, VF, BITS, GROUP, SWAP, ID)\
+	(((COMPRESS) << 29) | ((PACKED) << 28) | ((LOOSE) << 27) | ((VIDEO) << 23) |\
 	 ((PLANE) << 21) | ((HF) << 19) | ((VF) << 18) | ((BITS) << 8) |\
 	 ((GROUP) << 6) | ((SWAP) << 5) | ((ID) << 0))
 
-#define MDP_COLOR_IS_10BIT_PACKED(c)	((0x08000000 & (c)) >> 27)
-#define MDP_COLOR_IS_10BIT_LOOSE(c)	(((0x0c000000 & (c)) >> 26) == 1)
-#define MDP_COLOR_IS_10BIT_TILE(c)	(((0x0c000000 & (c)) >> 26) == 3)
+#define MDP_COLOR_IS_HYFBC_COMPRESS(c)  ((0x40000000 & (c)) >> 30)
+#define MDP_COLOR_IS_COMPRESS(c)        ((0x20000000 & (c)) >> 29)
+#define MDP_COLOR_IS_10BIT_PACKED(c)    ((0x10000000 & (c)) >> 28)
+#define MDP_COLOR_IS_10BIT_LOOSE(c)     (((0x18000000 & (c)) >> 27) == 1)
+#define MDP_COLOR_IS_10BIT_TILE(c)      (((0x18000000 & (c)) >> 27) == 3)
+#define MDP_COLOR_IS_10BIT_JUMP(c)      ((0x04000000 & (c)) >> 26)
 #define MDP_COLOR_IS_UFP(c)		((0x02000000 & (c)) >> 25)
 #define MDP_COLOR_IS_INTERLACED(c)	((0x01000000 & (c)) >> 24)
 #define MDP_COLOR_IS_BLOCK_MODE(c)	((0x00800000 & (c)) >> 23)
@@ -42,148 +45,120 @@
 #define MDP_COLOR_IS_YUV(c)		(MDP_COLOR_GET_GROUP(c) == 1)
 #define MDP_COLOR_IS_UV_COPLANE(c)	((MDP_COLOR_GET_PLANE_COUNT(c) == 2) &&\
 					 MDP_COLOR_IS_YUV(c))
+#define MDP_COLOR_IS_10BIT(c)            (((0x18000000 & (c)) >> 27) != 0)
+#define MDP_COLOR_GET_AUO_MODE(c)        (MDP_COLOR_IS_10BIT_JUMP(c))
 
 enum mdp_color {
 	MDP_COLOR_UNKNOWN	= 0,
 
-	//MDP_COLOR_FULLG8,
-	MDP_COLOR_FULLG8_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0,  8, 2,  0, 21),
-	MDP_COLOR_FULLG8_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1,  8, 2,  0, 21),
-	MDP_COLOR_FULLG8_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0,  8, 2,  0, 21),
-	MDP_COLOR_FULLG8_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1,  8, 2,  0, 21),
-	MDP_COLOR_FULLG8	= MDP_COLOR_FULLG8_BGGR,
-
-	//MDP_COLOR_FULLG10,
-	MDP_COLOR_FULLG10_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2,  0, 21),
-	MDP_COLOR_FULLG10_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 10, 2,  0, 21),
-	MDP_COLOR_FULLG10_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 10, 2,  0, 21),
-	MDP_COLOR_FULLG10_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 10, 2,  0, 21),
-	MDP_COLOR_FULLG10	= MDP_COLOR_FULLG10_BGGR,
-
-	//MDP_COLOR_FULLG12,
-	MDP_COLOR_FULLG12_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2,  0, 21),
-	MDP_COLOR_FULLG12_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 12, 2,  0, 21),
-	MDP_COLOR_FULLG12_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 12, 2,  0, 21),
-	MDP_COLOR_FULLG12_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 12, 2,  0, 21),
-	MDP_COLOR_FULLG12	= MDP_COLOR_FULLG12_BGGR,
-
-	//MDP_COLOR_FULLG14,
-	MDP_COLOR_FULLG14_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2,  0, 21),
-	MDP_COLOR_FULLG14_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 14, 2,  0, 21),
-	MDP_COLOR_FULLG14_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 14, 2,  0, 21),
-	MDP_COLOR_FULLG14_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 14, 2,  0, 21),
-	MDP_COLOR_FULLG14	= MDP_COLOR_FULLG14_BGGR,
-
-	MDP_COLOR_UFO10		= MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2,  0, 24),
-
-	//MDP_COLOR_BAYER8,
-	MDP_COLOR_BAYER8_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0,  8, 2,  0, 20),
-	MDP_COLOR_BAYER8_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1,  8, 2,  0, 20),
-	MDP_COLOR_BAYER8_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0,  8, 2,  0, 20),
-	MDP_COLOR_BAYER8_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1,  8, 2,  0, 20),
-	MDP_COLOR_BAYER8	= MDP_COLOR_BAYER8_BGGR,
-
-	//MDP_COLOR_BAYER10,
-	MDP_COLOR_BAYER10_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2,  0, 20),
-	MDP_COLOR_BAYER10_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 10, 2,  0, 20),
-	MDP_COLOR_BAYER10_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 10, 2,  0, 20),
-	MDP_COLOR_BAYER10_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 10, 2,  0, 20),
-	MDP_COLOR_BAYER10	= MDP_COLOR_BAYER10_BGGR,
-
-	//MDP_COLOR_BAYER12,
-	MDP_COLOR_BAYER12_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2,  0, 20),
-	MDP_COLOR_BAYER12_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 12, 2,  0, 20),
-	MDP_COLOR_BAYER12_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 12, 2,  0, 20),
-	MDP_COLOR_BAYER12_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 12, 2,  0, 20),
-	MDP_COLOR_BAYER12	= MDP_COLOR_BAYER12_BGGR,
-
-	//MDP_COLOR_BAYER14,
-	MDP_COLOR_BAYER14_RGGB	= MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2,  0, 20),
-	MDP_COLOR_BAYER14_GRBG	= MDP_COLOR(0, 0, 0, 1, 0, 1, 14, 2,  0, 20),
-	MDP_COLOR_BAYER14_GBRG	= MDP_COLOR(0, 0, 0, 1, 1, 0, 14, 2,  0, 20),
-	MDP_COLOR_BAYER14_BGGR	= MDP_COLOR(0, 0, 0, 1, 1, 1, 14, 2,  0, 20),
-	MDP_COLOR_BAYER14	= MDP_COLOR_BAYER14_BGGR,
-
-	MDP_COLOR_RGB48		= MDP_COLOR(0, 0, 0, 1, 0, 0, 48, 0,  0, 23),
-	/* For bayer+mono raw-16 */
-	MDP_COLOR_RGB565_RAW	= MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 2,  0, 0),
-
-	MDP_COLOR_BAYER8_UNPAK	= MDP_COLOR(0, 0, 0, 1, 0, 0,  8, 2,  0, 22),
-	MDP_COLOR_BAYER10_UNPAK	= MDP_COLOR(0, 0, 0, 1, 0, 0, 10, 2,  0, 22),
-	MDP_COLOR_BAYER12_UNPAK	= MDP_COLOR(0, 0, 0, 1, 0, 0, 12, 2,  0, 22),
-	MDP_COLOR_BAYER14_UNPAK	= MDP_COLOR(0, 0, 0, 1, 0, 0, 14, 2,  0, 22),
-
-	/* Unified formats */
-	MDP_COLOR_GREY		= MDP_COLOR(0, 0, 0, 1, 0, 0,  8, 1,  0, 7),
-
-	MDP_COLOR_RGB565	= MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 0,  0, 0),
-	MDP_COLOR_BGR565	= MDP_COLOR(0, 0, 0, 1, 0, 0, 16, 0,  1, 0),
-	MDP_COLOR_RGB888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 0,  1, 1),
-	MDP_COLOR_BGR888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 24, 0,  0, 1),
-	MDP_COLOR_RGBA8888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0,  1, 2),
-	MDP_COLOR_BGRA8888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0,  0, 2),
-	MDP_COLOR_ARGB8888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0,  1, 3),
-	MDP_COLOR_ABGR8888	= MDP_COLOR(0, 0, 0, 1, 0, 0, 32, 0,  0, 3),
-
-	MDP_COLOR_UYVY		= MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1,  0, 4),
-	MDP_COLOR_VYUY		= MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1,  1, 4),
-	MDP_COLOR_YUYV		= MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1,  0, 5),
-	MDP_COLOR_YVYU		= MDP_COLOR(0, 0, 0, 1, 1, 0, 16, 1,  1, 5),
-
-	MDP_COLOR_I420		= MDP_COLOR(0, 0, 0, 3, 1, 1,  8, 1,  0, 8),
-	MDP_COLOR_YV12		= MDP_COLOR(0, 0, 0, 3, 1, 1,  8, 1,  1, 8),
-	MDP_COLOR_I422		= MDP_COLOR(0, 0, 0, 3, 1, 0,  8, 1,  0, 9),
-	MDP_COLOR_YV16		= MDP_COLOR(0, 0, 0, 3, 1, 0,  8, 1,  1, 9),
-	MDP_COLOR_I444		= MDP_COLOR(0, 0, 0, 3, 0, 0,  8, 1,  0, 10),
-	MDP_COLOR_YV24		= MDP_COLOR(0, 0, 0, 3, 0, 0,  8, 1,  1, 10),
-
-	MDP_COLOR_NV12		= MDP_COLOR(0, 0, 0, 2, 1, 1,  8, 1,  0, 12),
-	MDP_COLOR_NV21		= MDP_COLOR(0, 0, 0, 2, 1, 1,  8, 1,  1, 12),
-	MDP_COLOR_NV16		= MDP_COLOR(0, 0, 0, 2, 1, 0,  8, 1,  0, 13),
-	MDP_COLOR_NV61		= MDP_COLOR(0, 0, 0, 2, 1, 0,  8, 1,  1, 13),
-	MDP_COLOR_NV24		= MDP_COLOR(0, 0, 0, 2, 0, 0,  8, 1,  0, 14),
-	MDP_COLOR_NV42		= MDP_COLOR(0, 0, 0, 2, 0, 0,  8, 1,  1, 14),
-
-	/* Mediatek proprietary formats */
-	/* UFO encoded block mode */
-	MDP_COLOR_420_BLK_UFO	= MDP_COLOR(0, 0, 5, 2, 1, 1, 256, 1, 0, 12),
-	/* Block mode */
-	MDP_COLOR_420_BLK	= MDP_COLOR(0, 0, 1, 2, 1, 1, 256, 1, 0, 12),
-	/* Block mode + field mode */
-	MDP_COLOR_420_BLKI	= MDP_COLOR(0, 0, 3, 2, 1, 1, 256, 1, 0, 12),
-	/* Block mode */
-	MDP_COLOR_422_BLK	= MDP_COLOR(0, 0, 1, 1, 1, 0, 512, 1, 0, 4),
-
-	MDP_COLOR_IYU2		= MDP_COLOR(0, 0, 0, 1, 0, 0, 24,  1, 0, 25),
-	MDP_COLOR_YUV444	= MDP_COLOR(0, 0, 0, 1, 0, 0, 24,  1, 0, 30),
-
-	/* Packed 10-bit formats */
-	MDP_COLOR_RGBA1010102	= MDP_COLOR(1, 0, 0, 1, 0, 0, 32,  0, 1, 2),
-	MDP_COLOR_BGRA1010102	= MDP_COLOR(1, 0, 0, 1, 0, 0, 32,  0, 0, 2),
-	/* Packed 10-bit UYVY */
-	MDP_COLOR_UYVY_10P	= MDP_COLOR(1, 0, 0, 1, 1, 0, 20,  1, 0, 4),
-	/* Packed 10-bit NV21 */
-	MDP_COLOR_NV21_10P	= MDP_COLOR(1, 0, 0, 2, 1, 1, 10,  1, 1, 12),
-	/* 10-bit block mode */
-	MDP_COLOR_420_BLK_10_H	= MDP_COLOR(1, 0, 1, 2, 1, 1, 320, 1, 0, 12),
-	/* 10-bit HEVC tile mode */
-	MDP_COLOR_420_BLK_10_V	= MDP_COLOR(1, 1, 1, 2, 1, 1, 320, 1, 0, 12),
-	/* UFO encoded 10-bit block mode */
-	MDP_COLOR_420_BLK_U10_H	= MDP_COLOR(1, 0, 5, 2, 1, 1, 320, 1, 0, 12),
-	/* UFO encoded 10-bit HEVC tile mode */
-	MDP_COLOR_420_BLK_U10_V	= MDP_COLOR(1, 1, 5, 2, 1, 1, 320, 1, 0, 12),
-
-	/* Loose 10-bit formats */
-	MDP_COLOR_UYVY_10L	= MDP_COLOR(0, 1, 0, 1, 1, 0, 20,  1, 0, 4),
-	MDP_COLOR_VYUY_10L	= MDP_COLOR(0, 1, 0, 1, 1, 0, 20,  1, 1, 4),
-	MDP_COLOR_YUYV_10L	= MDP_COLOR(0, 1, 0, 1, 1, 0, 20,  1, 0, 5),
-	MDP_COLOR_YVYU_10L	= MDP_COLOR(0, 1, 0, 1, 1, 0, 20,  1, 1, 5),
-	MDP_COLOR_NV12_10L	= MDP_COLOR(0, 1, 0, 2, 1, 1, 10,  1, 0, 12),
-	MDP_COLOR_NV21_10L	= MDP_COLOR(0, 1, 0, 2, 1, 1, 10,  1, 1, 12),
-	MDP_COLOR_NV16_10L	= MDP_COLOR(0, 1, 0, 2, 1, 0, 10,  1, 0, 13),
-	MDP_COLOR_NV61_10L	= MDP_COLOR(0, 1, 0, 2, 1, 0, 10,  1, 1, 13),
-	MDP_COLOR_YV12_10L	= MDP_COLOR(0, 1, 0, 3, 1, 1, 10,  1, 1, 8),
-	MDP_COLOR_I420_10L	= MDP_COLOR(0, 1, 0, 3, 1, 1, 10,  1, 0, 8),
+	// Unified format
+	MDP_COLOR_GREY           = MDP_COLOR(0, 0, 0, 0, 1, 0, 0,  8, 1,  0, 7),
+
+	MDP_COLOR_RGB565         = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 16, 0,  0, 0),
+	MDP_COLOR_BGR565         = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 16, 0,  1, 0),
+	MDP_COLOR_RGB888         = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 24, 0,  1, 1),
+	MDP_COLOR_BGR888         = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 24, 0,  0, 1),
+	MDP_COLOR_RGBA8888       = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 32, 0,  1, 2),
+	MDP_COLOR_BGRA8888       = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 32, 0,  0, 2),
+	MDP_COLOR_ARGB8888       = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 32, 0,  1, 3),
+	MDP_COLOR_ABGR8888       = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 32, 0,  0, 3),
+
+	MDP_COLOR_UYVY           = MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 16, 1,  0, 4),
+	MDP_COLOR_VYUY           = MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 16, 1,  1, 4),
+	MDP_COLOR_YUYV           = MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 16, 1,  0, 5),
+	MDP_COLOR_YVYU           = MDP_COLOR(0, 0, 0, 0, 1, 1, 0, 16, 1,  1, 5),
+
+	MDP_COLOR_I420           = MDP_COLOR(0, 0, 0, 0, 3, 1, 1,  8, 1,  0, 8),
+	MDP_COLOR_YV12           = MDP_COLOR(0, 0, 0, 0, 3, 1, 1,  8, 1,  1, 8),
+	MDP_COLOR_I422           = MDP_COLOR(0, 0, 0, 0, 3, 1, 0,  8, 1,  0, 9),
+	MDP_COLOR_YV16           = MDP_COLOR(0, 0, 0, 0, 3, 1, 0,  8, 1,  1, 9),
+	MDP_COLOR_I444           = MDP_COLOR(0, 0, 0, 0, 3, 0, 0,  8, 1,  0, 10),
+	MDP_COLOR_YV24           = MDP_COLOR(0, 0, 0, 0, 3, 0, 0,  8, 1,  1, 10),
+
+	MDP_COLOR_NV12           = MDP_COLOR(0, 0, 0, 0, 2, 1, 1,  8, 1,  0, 12),
+	MDP_COLOR_NV21           = MDP_COLOR(0, 0, 0, 0, 2, 1, 1,  8, 1,  1, 12),
+	MDP_COLOR_NV16           = MDP_COLOR(0, 0, 0, 0, 2, 1, 0,  8, 1,  0, 13),
+	MDP_COLOR_NV61           = MDP_COLOR(0, 0, 0, 0, 2, 1, 0,  8, 1,  1, 13),
+	MDP_COLOR_NV24           = MDP_COLOR(0, 0, 0, 0, 2, 0, 0,  8, 1,  0, 14),
+	MDP_COLOR_NV42           = MDP_COLOR(0, 0, 0, 0, 2, 0, 0,  8, 1,  1, 14),
+
+	// Mediatek proprietary format
+	//Frame mode + Block mode + UFO
+	MDP_COLOR_420_BLKP_UFO   = MDP_COLOR(0, 0, 0, 5, 2, 1, 1, 256, 1, 0, 12),
+	//Frame mode + Block mode + UFO AUO
+	MDP_COLOR_420_BLKP_UFO_AUO   = MDP_COLOR(0, 0, 0, 13, 2, 1, 1, 256, 1, 0, 12),
+	//Frame mode + Block mode
+	MDP_COLOR_420_BLKP       = MDP_COLOR(0, 0, 0, 1, 2, 1, 1, 256, 1, 0, 12),
+	//Field mode + Block mode
+	MDP_COLOR_420_BLKI       = MDP_COLOR(0, 0, 0, 3, 2, 1, 1, 256, 1, 0, 12),
+	//Frame mode
+	MDP_COLOR_422_BLKP       = MDP_COLOR(0, 0, 0, 1, 1, 1, 0, 512, 1, 0, 4),
+
+	MDP_COLOR_IYU2           = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 24,  1, 0, 25),
+	MDP_COLOR_YUV444         = MDP_COLOR(0, 0, 0, 0, 1, 0, 0, 24,  1, 0, 30),
+
+	// Mediatek proprietary 10bit format
+	MDP_COLOR_RGBA1010102    = MDP_COLOR(0, 1, 0, 0, 1, 0, 0, 32,  0, 1, 2),
+	MDP_COLOR_BGRA1010102    = MDP_COLOR(0, 1, 0, 0, 1, 0, 0, 32,  0, 0, 2),
+	MDP_COLOR_ARGB1010102    = MDP_COLOR(0, 1, 0, 0, 1, 0, 0, 32,  0, 1, 3),
+	MDP_COLOR_ABGR1010102    = MDP_COLOR(0, 1, 0, 0, 1, 0, 0, 32,  0, 0, 3),
+	//Packed 10bit UYVY
+	MDP_COLOR_UYVY_10P       = MDP_COLOR(0, 1, 0, 0, 1, 1, 0, 20,  1, 0, 4),
+	//Packed 10bit NV21
+	MDP_COLOR_NV12_10P       = MDP_COLOR(0, 1, 0, 0, 2, 1, 1, 10,  1, 0, 12),
+	MDP_COLOR_NV21_10P       = MDP_COLOR(0, 1, 0, 0, 2, 1, 1, 10,  1, 1, 12),
+	//Frame mode + Block mode
+	MDP_COLOR_420_BLKP_10_H          = MDP_COLOR(0, 1, 0, 1, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + HEVC tile mode
+	MDP_COLOR_420_BLKP_10_V          = MDP_COLOR(0, 1, 1, 1, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + Block mode + Jump
+	MDP_COLOR_420_BLKP_10_H_JUMP     = MDP_COLOR(0, 1, 0, 9, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + HEVC tile mode + Jump
+	MDP_COLOR_420_BLKP_10_V_JUMP     = MDP_COLOR(0, 1, 1, 9, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + Block mode
+	MDP_COLOR_420_BLKP_UFO_10_H      = MDP_COLOR(0, 1, 0, 5, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + HEVC tile mode
+	MDP_COLOR_420_BLKP_UFO_10_V      = MDP_COLOR(0, 1, 1, 5, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + Block mode + Jump
+	MDP_COLOR_420_BLKP_UFO_10_H_JUMP = MDP_COLOR(0, 1, 0, 13, 2, 1, 1, 320, 1, 0, 12),
+	//Frame mode + HEVC tile mode + Jump
+	MDP_COLOR_420_BLKP_UFO_10_V_JUMP = MDP_COLOR(0, 1, 1, 13, 2, 1, 1, 320, 1, 0, 12),
+
+	// Loose 10bit format
+	MDP_COLOR_UYVY_10L       = MDP_COLOR(0, 0, 1, 0, 1, 1, 0, 20,  1, 0, 4),
+	MDP_COLOR_VYUY_10L       = MDP_COLOR(0, 0, 1, 0, 1, 1, 0, 20,  1, 1, 4),
+	MDP_COLOR_YUYV_10L       = MDP_COLOR(0, 0, 1, 0, 1, 1, 0, 20,  1, 0, 5),
+	MDP_COLOR_YVYU_10L       = MDP_COLOR(0, 0, 1, 0, 1, 1, 0, 20,  1, 1, 5),
+	MDP_COLOR_NV12_10L       = MDP_COLOR(0, 0, 1, 0, 2, 1, 1, 16,  1, 0, 12),
+	MDP_COLOR_NV21_10L       = MDP_COLOR(0, 0, 1, 0, 2, 1, 1, 16,  1, 1, 12),
+	MDP_COLOR_NV16_10L       = MDP_COLOR(0, 0, 1, 0, 2, 1, 0, 16,  1, 0, 13),
+	MDP_COLOR_NV61_10L       = MDP_COLOR(0, 0, 1, 0, 2, 1, 0, 16,  1, 1, 13),
+	MDP_COLOR_YV12_10L       = MDP_COLOR(0, 0, 1, 0, 3, 1, 1, 16,  1, 1, 8),
+	MDP_COLOR_I420_10L       = MDP_COLOR(0, 0, 1, 0, 3, 1, 1, 16,  1, 0, 8),
+
+	MDP_COLOR_YV12_10P       = MDP_COLOR(0, 1, 0, 0, 3, 1, 1, 10,  1, 1, 8),
+	MDP_COLOR_I422_10P       = MDP_COLOR(0, 1, 0, 0, 3, 1, 0, 10,  1, 0, 9),
+	MDP_COLOR_NV16_10P       = MDP_COLOR(0, 1, 0, 0, 2, 1, 0, 10,  1, 0, 13),
+	MDP_COLOR_NV61_10P       = MDP_COLOR(0, 1, 0, 0, 2, 1, 0, 10,  1, 1, 13),
+
+	MDP_COLOR_I422_10L       = MDP_COLOR(0, 0, 1, 0, 3, 1, 0, 16,  1, 0, 9),
+
+	MDP_COLOR_RGBA8888_AFBC       = MDP_COLOR(1, 0, 0, 0, 1, 0, 0, 32, 0, 1, 2),
+	MDP_COLOR_BGRA8888_AFBC       = MDP_COLOR(1, 0, 0, 0, 1, 0, 0, 32, 0, 0, 2),
+	MDP_COLOR_ARGB8888_AFBC       = MDP_COLOR(1, 0, 0, 0, 1, 0, 0, 32, 0, 1, 3),
+	MDP_COLOR_ABGR8888_AFBC       = MDP_COLOR(1, 0, 0, 0, 1, 0, 0, 32, 0, 0, 3),
+	MDP_COLOR_RGBA1010102_AFBC    = MDP_COLOR(1, 1, 0, 0, 1, 0, 0, 32, 0, 1, 2),
+	MDP_COLOR_BGRA1010102_AFBC    = MDP_COLOR(1, 1, 0, 0, 1, 0, 0, 32, 0, 0, 2),
+	MDP_COLOR_ARGB1010102_AFBC    = MDP_COLOR(1, 1, 0, 0, 1, 0, 0, 32, 0, 1, 3),
+	MDP_COLOR_ABGR1010102_AFBC    = MDP_COLOR(1, 1, 0, 0, 1, 0, 0, 32, 0, 0, 3),
+
+	MDP_COLOR_NV12_AFBC          = MDP_COLOR(1, 0, 0, 0, 2, 1, 1,  12,  1, 0, 12),
+	MDP_COLOR_P010_AFBC          = MDP_COLOR(1, 1, 0, 0, 2, 1, 1,  10,  1, 0, 12),
+
+	MDP_COLOR_NV12_HYFBC          = MDP_COLOR(2, 0, 0, 0, 2, 1, 1,  8,  1, 0, 12),
+	MDP_COLOR_NV21_HYFBC          = MDP_COLOR(2, 0, 0, 0, 2, 1, 1,  8,  1, 1, 12),
+	MDP_COLOR_NV12_10P_HYFBC      = MDP_COLOR(2, 1, 0, 0, 2, 1, 1, 10,  1, 0, 12),
+	MDP_COLOR_NV21_10P_HYFBC      = MDP_COLOR(2, 1, 0, 0, 2, 1, 1, 10,  1, 1, 12),
 };
 
 /* Minimum Y stride that is accepted by MDP HW */
@@ -368,5 +343,6 @@ void mdp_set_src_config(struct img_input *in,
 void mdp_set_dst_config(struct img_output *out,
 			struct mdp_frame *frame, struct vb2_buffer *vb);
 int mdp_frameparam_init(struct mdp_frameparam *param);
+void mdp_format_init(const struct mdp_format *format, u32 length);
 
 #endif  /* __MTK_MDP3_REGS_H__ */
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Sun Jan 16 22:21:43 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 17 Jan 2022 14:21:43 +0800
Subject: [PATCH v15 0/2] mtk: add ADSP mailbox controller support for MT8195
Message-ID: <20220117062145.9929-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message between processors with dsp.?

It will place the message to the share buffer and will access the ADSP mailbox registers to kick dsp.

Two mailboxes used to send notification or short message between processors with dsp

changes since v14:
- add inline for get_mtk_adsp_mbox_priv

changes since v13:
- rebase on v5.16-rc8
- add back ptr check from of_device_get_match_data

changes since v12:
- remove of_device_get_match_data ptr check:
  of_device_get_match_data(dev) will never going to return NULL.
  driver probe with compatible mediatek,mt8195-adsp-mbox.

changes since v11:
- remove unuseful MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions
  https://patchwork.kernel.org/project/linux-mediatek/patch/20220111071011.5964-1-allen-kh.cheng at mediatek.com/

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error


Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   7 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 175 ++++++++++++++++++
 4 files changed, 236 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From liang.yang at amlogic.com  Sun Jan 16 22:24:28 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 14:24:28 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220114230130.35EAAC36AE7@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
Message-ID: <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>



On 2022/1/15 7:01, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-13 21:14:46)
>> On 2022/1/14 5:35, Stephen Boyd wrote:
>>> Quoting Liang Yang (2022-01-13 03:57:45)
>>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>>>> new file mode 100644
>>>> index 000000000000..f53977f61390
>>>> --- /dev/null
>>>> +++ b/drivers/clk/meson/mmc-clkc.c
>>>> @@ -0,0 +1,300 @@
> [..]
>>>> +
>>>> +static int mmc_clkc_probe(struct platform_device *pdev)
>>>> +{
>>>> +       struct clk_hw_onecell_data *onecell_data;
>>>> +       struct device *dev = &pdev->dev;
>>>> +       struct mmc_clkc_data *data;
>>>> +       struct regmap *map;
>>>> +       struct clk_regmap *clk, *core;
>>>> +       struct meson_sclk_div_data *div_data;
>>>> +
>>>> +       /*cast to drop the const in match->data*/
>>>
>>> Space after *, also why do we need to cast away const? The user of this
>>> pointer passes it all the way down to mmc_clkc_register_clk() which
>>> could take the data as const void pointer and decide to cast away const
>>> there.
>>
>> if use 'const' here, it  will report a warning:
>> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
>> qualifier from pointer targe
>> t type [-Werror=discarded-qualifiers]
>>
>>     data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
> 
> Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not 
have 'const', so make the type declaration cause a further 'const' cast 
warning. Could i copy these infos just like below:

struct mmc_clkc_data *data_clkc;
......
data = of_device_get_match_data(dev);
data_clkc = devm_kmalloc(dev, sizeof(*data_clkc), GFP_KERNEL);
memcpy(data_clkc, data, sizeof(*data_clkc));
......
clk = mmc_clkc_register_clk_with_parent(...., &data_clkc->rx);

> 
> .


From allen-kh.cheng at mediatek.com  Sun Jan 16 22:21:45 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 17 Jan 2022 14:21:45 +0800
Subject: [PATCH v15 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220117062145.9929-1-allen-kh.cheng@mediatek.com>
References: <20220117062145.9929-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220117062145.9929-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   7 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 175 +++++++++++++++++++++++++++++
 3 files changed, 184 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..3e5bb745437d 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,13 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+	  Say yes here to add support for MediaTek ADSP mailbox controller
+	  driver. It is used to send short messages between processors with dsp.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..60bf10c38348
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static inline struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Sun Jan 16 22:21:44 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Mon, 17 Jan 2022 14:21:44 +0800
Subject: [PATCH v15 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220117062145.9929-1-allen-kh.cheng@mediatek.com>
References: <20220117062145.9929-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220117062145.9929-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From joel at jms.id.au  Sun Jan 16 22:38:48 2022
From: joel at jms.id.au (Joel Stanley)
Date: Mon, 17 Jan 2022 06:38:48 +0000
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
In-Reply-To: <e62fba0b-ebb9-934a-d7cf-6da33ecc4335@linux.alibaba.com>
References: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
 <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>
 <CACPK8XcYp9iAD3fjBQCax41C-1UpA+1AQW3epyEooYzNLt7R5g@mail.gmail.com>
 <e62fba0b-ebb9-934a-d7cf-6da33ecc4335@linux.alibaba.com>
Message-ID: <CACPK8Xc+v132vM-ytdAUFhywFXGpPF+uPSBWi68ROf_PLD4VQQ@mail.gmail.com>

On Fri, 14 Jan 2022 at 14:01, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
>
> Hi Joel,
>
>
> ? 2022/1/11 ??6:51, Joel Stanley ??:
> > On Tue, 11 Jan 2022 at 07:52, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
> >> Hi all,
> >>
> >> Any comments?
> >>
> >> Thanks,
> >>
> >> Heyi
> >>
> >> ? 2022/1/9 ??9:26, Heyi Guo ??:
> >>> The memory will be freed by the caller if transfer timeout occurs,
> >>> then it would trigger kernel panic if the peer device responds with
> >>> something after timeout and triggers the interrupt handler of aspeed
> >>> i2c driver.
> >>>
> >>> Set the msgs pointer to NULL to avoid invalid memory reference after
> >>> timeout to fix this potential kernel panic.
> > Thanks for the patch. How did you discover this issue? Do you have a
> > test I can run to reproduce the crash?
>
> We are using one i2c channel to communicate with another MCU by
> implementing user space SSIF protocol, and the MCU may not respond in
> time if it is busy. If it responds after timeout occurs, it will trigger
> below kernel panic:
>

Thanks for the details. It looks like you've done some testing of
this, which is good.

> After applying this patch, we'll get below warning instead:
>
> "bus in unknown state. irq_status: 0x%x\n"

Given we get to here in the irq handler, we've done these two tests:

 - aspeed_i2c_is_irq_error()
 - the state is not INACTIVE or PENDING

but there's no buffer ready for us to use. So what has triggered the
IRQ in this case? Do you have a record of the irq status bits?

I am wondering if the driver should know that the transaction has
timed out, instead of detecting this unknown state.


> > Can you provide a Fixes tag?
>
> I think the bug was introduced by the first commit of this file :(
>
> f327c686d3ba44eda79a2d9e02a6a242e0b75787
>
>
> >
> > Do other i2c master drivers do this? I took a quick look at the meson
> > driver and it doesn't appear to clear it's pointer to msgs.
>
> It is hard to say. It seems other drivers have some recover scheme like
> aborting the transfer, or loop each messages in process context and
> don't do much in IRQ handler, which may disable interrupts or not retain
> the buffer pointer before returning timeout.

I think your change is okay to go in as it fixes the crash, but first
I want to work out if there's some missing handling of a timeout
condition that we should add as well.


>
> Thanks,
>
> Heyi
>
>
> >
> >>> Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>
> >>>
> >>> -------
> >>>
> >>> Cc: Brendan Higgins <brendanhiggins at google.com>
> >>> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
> >>> Cc: Joel Stanley <joel at jms.id.au>
> >>> Cc: Andrew Jeffery <andrew at aj.id.au>
> >>> Cc: Philipp Zabel <p.zabel at pengutronix.de>
> >>> Cc: linux-i2c at vger.kernel.org
> >>> Cc: openbmc at lists.ozlabs.org
> >>> Cc: linux-arm-kernel at lists.infradead.org
> >>> Cc: linux-aspeed at lists.ozlabs.org
> >>> ---
> >>>    drivers/i2c/busses/i2c-aspeed.c | 5 +++++
> >>>    1 file changed, 5 insertions(+)
> >>>
> >>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
> >>> index 67e8b97c0c950..3ab0396168680 100644
> >>> --- a/drivers/i2c/busses/i2c-aspeed.c
> >>> +++ b/drivers/i2c/busses/i2c-aspeed.c
> >>> @@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
> >>>                spin_lock_irqsave(&bus->lock, flags);
> >>>                if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
> >>>                        bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
> >>> +             /*
> >>> +              * All the buffers may be freed after returning to caller, so
> >>> +              * set msgs to NULL to avoid memory reference after freeing.
> >>> +              */
> >>> +             bus->msgs = NULL;
> >>>                spin_unlock_irqrestore(&bus->lock, flags);
> >>>
> >>>                return -ETIMEDOUT;


From michael.riesch at wolfvision.net  Sun Jan 16 22:54:23 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Mon, 17 Jan 2022 07:54:23 +0100
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <20220116124911.65203-2-linux@fw-web.de>
References: <20220116124911.65203-1-linux@fw-web.de>
 <20220116124911.65203-2-linux@fw-web.de>
Message-ID: <cf821d43-6f9c-f05e-c479-7970aeda9986@wolfvision.net>

Hello Frank,

On 1/16/22 13:49, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> pclk_xpcs is not supported and breaks dtbs_check, so remove it
> 
> following warnings occour, and many more
> 
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
>     [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
>     [15, 389], [15, 185], [15, 172]] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
>     ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
>     'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> 
> after removing the clock the other warnings are also gone.
> 
> Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> index 2fd313a295f8..d91df1cde736 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> @@ -32,13 +32,11 @@ gmac0: ethernet at fe2a0000 {
>  		clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
>  			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
>  			 <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
> -			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
> -			 <&cru PCLK_XPCS>;
> +			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
>  		clock-names = "stmmaceth", "mac_clk_rx",
>  			      "mac_clk_tx", "clk_mac_refout",
>  			      "aclk_mac", "pclk_mac",
> -			      "clk_mac_speed", "ptp_ref",
> -			      "pclk_xpcs";
> +			      "clk_mac_speed", "ptp_ref";
>  		resets = <&cru SRST_A_GMAC0>;
>  		reset-names = "stmmaceth";
>  		rockchip,grf = <&grf>;

This has been on my TODO list for a while, but I never found the time to
submit this cleanup. As far as I am concerned:

Acked-by: Michael Riesch <michael.riesch at wolfvision.net>

Thanks and best regards,
Michael


From liang.yang at amlogic.com  Sun Jan 16 23:03:47 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Mon, 17 Jan 2022 15:03:47 +0800
Subject: [PATCH v9 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-4-liang.yang@amlogic.com>
 <20220113212957.768FFC36AE3@smtp.kernel.org>
 <5d99ac02-a246-5bcc-2ecb-371b0d193537@amlogic.com>
 <CAFBinCDkNk+Ba340vshhL2rE76U9qb_dZ5ZsgWnMgFYpL6i1jA@mail.gmail.com>
Message-ID: <8783eb66-16ee-3b8b-5d55-73b49deab3a2@amlogic.com>

Hi Martin,

On 2022/1/15 8:09, Martin Blumenstingl wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> On Fri, Jan 14, 2022 at 4:06 AM Liang Yang <liang.yang at amlogic.com> wrote:
> [...]
>>>> +properties:
>>>> +  compatible:
>>>> +    enum:
>>>> +      - "amlogic,axg-mmc-clkc", "syscon"
>>>
>>> Why is it a syscon?
>>
>> The register documented by reg is shared with SD/eMMC controller port C,
>> and it need to be ops on NFC driver.
> Can you please share an example how the .dts would look like in the
> end for two example cases:
> 1) using the sd_emmc_c MMC interface > 2) not using the MMC interface of sd_emmc_c but only using it's clocks
> for the NFC
I think both EMMC(although it is not implemented by 'axg-mmc-clkc'  yet) 
and NAND clock have the same way in dts:
		......
		clocks = <&clkc CLKID_SD_EMMC_C>,
			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
		clock-names = "core", "device", "rx", "tx";
		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
		......

> 
> Initially I wanted to suggest the usage of a sub-node with compatible
> = "mmc-slot" (see
> Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdio.txt for an
> example) to decide whether the MMC controller is registered or whether
> just the clock controller is registered.
> However, the mmc-slot compatible string is not documented in
> Documentation/devicetree/bindings/mmc/mmc-controller.yaml currently.
> Maybe the MMC maintainers have any suggestions if other IPs have
> similar requirements (for IPs with shared parts).
> 
> 
> Best regards,
> Martin
> 
> .


From yong.wu at mediatek.com  Sun Jan 16 23:04:57 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:04:57 +0800
Subject: [PATCH v10 00/13] Clean up "mediatek,larb"
Message-ID: <20220117070510.17642-1-yong.wu@mediatek.com>

MediaTek IOMMU block diagram always like below:

        M4U
         |
    smi-common
         |
  -------------
  |         |  ...
  |         |
larb1     larb2
  |         |
vdec       venc

All the consumer connect with smi-larb, then connect with smi-common.

When the consumer works, it should enable the smi-larb's power which also
need enable the smi-common's power firstly.

Thus, Firstly, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

After adding the device_link, then "mediatek,larb" property can be removed.
the iommu consumer don't need call the mtk_smi_larb_get/put to enable
the power and clock of smi-larb and smi-common.

Base on the media branch [1] and a jpeg dtbinding patchset[2] that already got
the necessary R-b.

[1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d
[2] https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsinyi at chromium.org/

Change notes:
v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches.     
     b) Add Joerg's Ack for iommu patches.

v9: https://lore.kernel.org/linux-mediatek/20211112105509.12010-1-yong.wu at mediatek.com/
    1) Add return -ENODEV when the dev is null.
    2) Add more strict about the case that a iommu consume device use the ports in
    different larbs. Don't allow this case.
    3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it only has one
    line now.

v8: https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong.wu at mediatek.com/
    1) Rebase on v5.15-rc1.
    2) Don't rebase the below mdp patchset that may still need more discuss.
    https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-eizan at chromium.org/
    3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested.

v7: https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong.wu at mediatek.com/
    1) Fix a arm32 boot fail issue. reported from Frank.
    2) Add a return fail in the mtk drm. suggested by Dafna.

v6: https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong.wu at mediatek.com/
    1) rebase on v5.14-rc1.
    2) Fix the issue commented in v5 from Dafna and Hsin-Yi.
    3) Remove the patches about using pm_runtime_resume_and_get since they have
       already been merged by other patches.

v5: https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong.wu at mediatek.com/
    1) Base v5.12-rc2.
    2) Remove changing the mtk-iommu to module_platform_driver patch, It have already been a
    independent patch.

v4: https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong.wu at mediatek.com/ 
    base on v5.7-rc1.
  1) Move drm PM patch before smi patchs.
  2) Change builtin_platform_driver to module_platform_driver since we may need
     build as module.
  3) Rebase many patchset as above.

v3: https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong.wu at mediatek.com/
    1) rebase on v5.3-rc1 and the latest mt8183 patchset.
    2) Use device_is_bound to check whether the driver is ready from Matthias.    
    3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
   reason in the commit message[3/14].
    4) Add a display patch[12/14] into this series. otherwise it may affect
   display HW fastlogo even though it don't happen in mt8183.
   
v2: https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong.wu at mediatek.com/
   1) rebase on v5.2-rc1.
   2) Move adding device_link between the consumer and smi-larb into
iommu_add_device from Robin.
   3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
   4) Remove the shutdown callback in iommu.   

v1: https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong.wu at mediatek.com/

Yong Wu (12):
  dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
  iommu/mediatek-v1: Free the existed fwspec if the master dev already
    has
  iommu/mediatek: Return ENODEV if the device is NULL
  iommu/mediatek: Add probe_defer for smi-larb
  iommu/mediatek: Add device_link between the consumer and the larb
    devices
  media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
  media: mtk-mdp: Get rid of mtk_smi_larb_get/put
  drm/mediatek: Get rid of mtk_smi_larb_get/put
  media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
  memory: mtk-smi: Get rid of mtk_smi_larb_get/put
  arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
  arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes

Yongqiang Niu (1):
  drm/mediatek: Add pm runtime support for ovl and rdma

 .../display/mediatek/mediatek,disp.txt        |  9 ----
 .../media/mediatek,vcodec-decoder.yaml        |  7 ---
 .../media/mediatek,vcodec-encoder.yaml        |  8 ----
 .../bindings/media/mediatek-jpeg-decoder.yaml |  9 ----
 .../bindings/media/mediatek-jpeg-encoder.yaml |  9 ----
 .../bindings/media/mediatek-mdp.txt           |  8 ----
 arch/arm/boot/dts/mt2701.dtsi                 |  2 -
 arch/arm/boot/dts/mt7623n.dtsi                |  5 ---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi      | 16 -------
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  6 ---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c       |  8 +++-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |  9 +++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 15 ++++---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 36 +--------------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  5 +--
 drivers/iommu/mtk_iommu.c                     | 34 ++++++++++++++
 drivers/iommu/mtk_iommu_v1.c                  | 42 ++++++++++++++++-
 .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 45 +------------------
 .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 -----------------
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  2 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 41 +++--------------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 --
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  2 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 45 +++----------------
 drivers/memory/mtk-smi.c                      | 14 ------
 include/soc/mediatek/smi.h                    | 20 ---------
 32 files changed, 115 insertions(+), 333 deletions(-)

-- 
2.18.0




From yong.wu at mediatek.com  Sun Jan 16 23:05:00 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:00 +0800
Subject: [PATCH v10 03/13] iommu/mediatek: Return ENODEV if the device is NULL
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-4-yong.wu@mediatek.com>

The platform device is created at:
of_platform_default_populate_init:  arch_initcall_sync
  ->of_platform_populate
        ->of_platform_device_create_pdata

When entering our probe, all the devices should be already created.
if it is null, means NODEV. Currently we don't get the fail case.
It's a minor fix, no need add fixes tags.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Joerg Roedel <jroedel at suse.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c    | 2 +-
 drivers/iommu/mtk_iommu_v1.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 25b834104790..77ae20ff9b35 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -848,7 +848,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		plarbdev = of_find_device_by_node(larbnode);
 		if (!plarbdev) {
 			of_node_put(larbnode);
-			return -EPROBE_DEFER;
+			return -ENODEV;
 		}
 		data->larb_imu[id].dev = &plarbdev->dev;
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 1467ba1e4417..68bf02f87cfd 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -604,7 +604,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		plarbdev = of_find_device_by_node(larbnode);
 		if (!plarbdev) {
 			of_node_put(larbnode);
-			return -EPROBE_DEFER;
+			return -ENODEV;
 		}
 		data->larb_imu[i].dev = &plarbdev->dev;
 
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:04:58 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:04:58 +0800
Subject: [PATCH v10 01/13] dt-binding: mediatek: Get rid of mediatek,
 larb for multimedia HW
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-2-yong.wu@mediatek.com>

After adding device_link between the consumer with the smi-larbs,
if the consumer call its owner pm_runtime_get(_sync), the
pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. Thus, the consumer don't need this property.

And IOMMU also know which larb this consumer connects with from
iommu id in the "iommus=" property.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Evan Green <evgreen at chromium.org>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../bindings/display/mediatek/mediatek,disp.txt          | 9 ---------
 .../bindings/media/mediatek,vcodec-decoder.yaml          | 7 -------
 .../bindings/media/mediatek,vcodec-encoder.yaml          | 8 --------
 .../devicetree/bindings/media/mediatek-jpeg-decoder.yaml | 9 ---------
 .../devicetree/bindings/media/mediatek-jpeg-encoder.yaml | 9 ---------
 Documentation/devicetree/bindings/media/mediatek-mdp.txt | 8 --------
 6 files changed, 50 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
index 78044c340e20..8b575e11bcec 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
@@ -61,8 +61,6 @@ Required properties (DMA function blocks):
 	"mediatek,<chip>-disp-rdma"
 	"mediatek,<chip>-disp-wdma"
   the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
 - iommus: Should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
   for details.
@@ -91,7 +89,6 @@ ovl0: ovl at 1400c000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_OVL0>;
 	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
 };
 
 ovl1: ovl at 1400d000 {
@@ -101,7 +98,6 @@ ovl1: ovl at 1400d000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_OVL1>;
 	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
 };
 
 rdma0: rdma at 1400e000 {
@@ -111,7 +107,6 @@ rdma0: rdma at 1400e000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
 	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
 	mediatek,rdma-fifosize = <8192>;
 };
 
@@ -122,7 +117,6 @@ rdma1: rdma at 1400f000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
 	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
 };
 
 rdma2: rdma at 14010000 {
@@ -132,7 +126,6 @@ rdma2: rdma at 14010000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
 	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
 };
 
 wdma0: wdma at 14011000 {
@@ -142,7 +135,6 @@ wdma0: wdma at 14011000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
 	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
 };
 
 wdma1: wdma at 14012000 {
@@ -152,7 +144,6 @@ wdma1: wdma at 14012000 {
 	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
 	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
 };
 
 color0: color at 14013000 {
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
index df1d677098fd..9b179bb44dfb 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml
@@ -61,12 +61,6 @@ properties:
     description: |
       Describes the physical address space of IOMMU maps to memory.
 
-  mediatek,larb:
-    $ref: /schemas/types.yaml#/definitions/phandle
-    maxItems: 1
-    description: |
-      Must contain the local arbiters in the current Socs.
-
   mediatek,vpu:
     $ref: /schemas/types.yaml#/definitions/phandle
     maxItems: 1
@@ -137,7 +131,6 @@ examples:
           <0x16027800 0x800>,   /*VP8_VL*/
           <0x16028400 0x400>;   /*VP9_VD*/
       interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-      mediatek,larb = <&larb1>;
       iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
              <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
              <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
index b72c1a50e89e..e7b65a91c92c 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml
@@ -53,12 +53,6 @@ properties:
     description: |
       Describes the physical address space of IOMMU maps to memory.
 
-  mediatek,larb:
-    $ref: /schemas/types.yaml#/definitions/phandle
-    maxItems: 1
-    description: |
-      Must contain the local arbiters in the current Socs.
-
   mediatek,vpu:
     $ref: /schemas/types.yaml#/definitions/phandle
     maxItems: 1
@@ -157,7 +151,6 @@ examples:
              <&iommu M4U_PORT_VENC_REF_CHROMA>,
              <&iommu M4U_PORT_VENC_NBM_RDMA>,
              <&iommu M4U_PORT_VENC_NBM_WDMA>;
-      mediatek,larb = <&larb3>;
       mediatek,vpu = <&vpu>;
       clocks = <&topckgen CLK_TOP_VENC_SEL>;
       clock-names = "venc_sel";
@@ -178,7 +171,6 @@ examples:
              <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
              <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
              <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-      mediatek,larb = <&larb5>;
       mediatek,vpu = <&vpu>;
       clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
       clock-names = "venc_lt_sel";
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
index 9b87f036f178..052e752157b4 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
@@ -42,13 +42,6 @@ properties:
   power-domains:
     maxItems: 1
 
-  mediatek,larb:
-    $ref: '/schemas/types.yaml#/definitions/phandle'
-    description: |
-      Must contain the local arbiters in the current Socs, see
-      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-      for details.
-
   iommus:
     maxItems: 2
     description: |
@@ -63,7 +56,6 @@ required:
   - clocks
   - clock-names
   - power-domains
-  - mediatek,larb
   - iommus
 
 additionalProperties: false
@@ -83,7 +75,6 @@ examples:
       clock-names = "jpgdec-smi",
                     "jpgdec";
       power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
-      mediatek,larb = <&larb2>;
       iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
                <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
     };
diff --git a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
index fcd9b829e036..8bfdfdfaba59 100644
--- a/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml
@@ -35,13 +35,6 @@ properties:
   power-domains:
     maxItems: 1
 
-  mediatek,larb:
-    $ref: '/schemas/types.yaml#/definitions/phandle'
-    description: |
-      Must contain the local arbiters in the current Socs, see
-      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-      for details.
-
   iommus:
     maxItems: 2
     description: |
@@ -56,7 +49,6 @@ required:
   - clocks
   - clock-names
   - power-domains
-  - mediatek,larb
   - iommus
 
 additionalProperties: false
@@ -75,7 +67,6 @@ examples:
       clocks =  <&imgsys CLK_IMG_VENC>;
       clock-names = "jpgenc";
       power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
-      mediatek,larb = <&larb2>;
       iommus = <&iommu MT2701_M4U_PORT_JPGENC_RDMA>,
                <&iommu MT2701_M4U_PORT_JPGENC_BSDMA>;
     };
diff --git a/Documentation/devicetree/bindings/media/mediatek-mdp.txt b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
index caa24943da33..53ef26e2c857 100644
--- a/Documentation/devicetree/bindings/media/mediatek-mdp.txt
+++ b/Documentation/devicetree/bindings/media/mediatek-mdp.txt
@@ -27,9 +27,6 @@ Required properties (DMA function blocks, child node):
 - iommus: should point to the respective IOMMU block with master port as
   argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
   for details.
-- mediatek,larb: must contain the local arbiters in the current Socs, see
-  Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-  for details.
 
 Example:
 	mdp_rdma0: rdma at 14001000 {
@@ -40,7 +37,6 @@ Example:
 			 <&mmsys CLK_MM_MUTEX_32K>;
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_RDMA0>;
-		mediatek,larb = <&larb0>;
 		mediatek,vpu = <&vpu>;
 	};
 
@@ -51,7 +47,6 @@ Example:
 			 <&mmsys CLK_MM_MUTEX_32K>;
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_RDMA1>;
-		mediatek,larb = <&larb4>;
 	};
 
 	mdp_rsz0: rsz at 14003000 {
@@ -81,7 +76,6 @@ Example:
 		clocks = <&mmsys CLK_MM_MDP_WDMA>;
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_WDMA>;
-		mediatek,larb = <&larb0>;
 	};
 
 	mdp_wrot0: wrot at 14007000 {
@@ -90,7 +84,6 @@ Example:
 		clocks = <&mmsys CLK_MM_MDP_WROT0>;
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_WROT0>;
-		mediatek,larb = <&larb0>;
 	};
 
 	mdp_wrot1: wrot at 14008000 {
@@ -99,5 +92,4 @@ Example:
 		clocks = <&mmsys CLK_MM_MDP_WROT1>;
 		power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
 		iommus = <&iommu M4U_PORT_MDP_WROT1>;
-		mediatek,larb = <&larb4>;
 	};
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:07 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:07 +0800
Subject: [PATCH v10 10/13] media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-11-yong.wu@mediatek.com>

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the vcodec devices call the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Tiffany Lin <tiffany.lin at mediatek.com>
CC: Irui Wang <irui.wang at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Acked-by: Tiffany Lin <tiffany.lin at mediatek.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  2 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 41 +++--------------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 --
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  2 -
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 45 +++----------------
 7 files changed, 12 insertions(+), 83 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 86b639d82be8..8d11510e441e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -450,7 +450,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		destroy_workqueue(dev->core_workqueue);
 err_res:
 	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
 err_dec_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -494,7 +493,6 @@ static int mtk_vcodec_dec_remove(struct platform_device *pdev)
 
 	v4l2_device_unregister(&dev->v4l2_dev);
 	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvdec);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 7b5da3e4cac2..8d2a641d92f1 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -184,7 +184,6 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 	return 0;
 err:
 	pm_runtime_disable(subdev_dev->pm.dev);
-	put_device(subdev_dev->pm.larbvdec);
 	return ret;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 44035a50e335..7e0c2644bf7b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -9,7 +9,6 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>
 
 #include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_dec_pm.h"
@@ -17,25 +16,11 @@
 
 int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm)
 {
-	struct device_node *node;
-	struct platform_device *larb_pdev;
 	struct mtk_vcodec_clk *dec_clk;
 	struct mtk_vcodec_clk_info *clk_info;
-	int i = 0, ret = 0;
+	int i = 0, ret;
 
 	dec_clk = &pm->vdec_clk;
-	node = of_parse_phandle(pdev->dev.of_node, "mediatek,larb", 0);
-	if (!node) {
-		mtk_v4l2_err("of_parse_phandle mediatek,larb fail!");
-		return -1;
-	}
-
-	larb_pdev = of_find_device_by_node(node);
-	of_node_put(node);
-	if (WARN_ON(!larb_pdev))
-		return -1;
-
-	pm->larbvdec = &larb_pdev->dev;
 	pm->dev = &pdev->dev;
 
 	dec_clk->clk_num =
@@ -44,14 +29,11 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *
 		dec_clk->clk_info = devm_kcalloc(&pdev->dev,
 			dec_clk->clk_num, sizeof(*clk_info),
 			GFP_KERNEL);
-		if (!dec_clk->clk_info) {
-			ret = -ENOMEM;
-			goto put_device;
-		}
+		if (!dec_clk->clk_info)
+			return -ENOMEM;
 	} else {
 		mtk_v4l2_err("Failed to get vdec clock count");
-		ret = -EINVAL;
-		goto put_device;
+		return -EINVAL;
 	}
 
 	for (i = 0; i < dec_clk->clk_num; i++) {
@@ -60,22 +42,18 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *
 			"clock-names", i, &clk_info->clk_name);
 		if (ret) {
 			mtk_v4l2_err("Failed to get clock name id = %d", i);
-			goto put_device;
+			return ret;
 		}
 		clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
 			clk_info->clk_name);
 		if (IS_ERR(clk_info->vcodec_clk)) {
 			mtk_v4l2_err("devm_clk_get (%d)%s fail", i,
 				clk_info->clk_name);
-			ret = PTR_ERR(clk_info->vcodec_clk);
-			goto put_device;
+			return PTR_ERR(clk_info->vcodec_clk);
 		}
 	}
 
 	return 0;
-put_device:
-	put_device(pm->larbvdec);
-	return ret;
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
@@ -157,13 +135,7 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 		}
 	}
 
-	ret = mtk_smi_larb_get(pm->larbvdec);
-	if (ret) {
-		mtk_v4l2_err("mtk_smi_larb_get larbvdec fail %d", ret);
-		goto error;
-	}
 	return;
-
 error:
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
@@ -191,7 +163,6 @@ void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 	}
 
 	dec_clk = &pm->vdec_clk;
-	mtk_smi_larb_put(pm->larbvdec);
 	for (i = dec_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 94b47b7c912b..813901c4be5e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -214,10 +214,7 @@ struct mtk_vcodec_clk {
  */
 struct mtk_vcodec_pm {
 	struct mtk_vcodec_clk	vdec_clk;
-	struct device	*larbvdec;
-
 	struct mtk_vcodec_clk	venc_clk;
-	struct device	*larbvenc;
 	struct device	*dev;
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 7457451ebff0..8998244ea671 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -8,7 +8,6 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>
 #include <linux/pm_runtime.h>
 
 #include "mtk_vcodec_drv.h"
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index fc40a02af942..dbb0134e8cc0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -371,7 +371,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
 	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvenc);
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -461,7 +460,6 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 
 	v4l2_device_unregister(&dev->v4l2_dev);
 	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvenc);
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 0825c6ec4eb7..7055954eb2af 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -8,57 +8,35 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
-#include <soc/mediatek/smi.h>
 
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
 int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 {
-	struct device_node *node;
 	struct platform_device *pdev;
 	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *enc_clk;
 	struct mtk_vcodec_clk_info *clk_info;
-	int ret = 0, i = 0;
-	struct device *dev;
+	int ret, i;
 
 	pdev = mtkdev->plat_dev;
 	pm = &mtkdev->pm;
 	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
 	pm->dev = &pdev->dev;
-	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
 
-	node = of_parse_phandle(dev->of_node, "mediatek,larb", 0);
-	if (!node) {
-		mtk_v4l2_err("no mediatek,larb found");
-		return -ENODEV;
-	}
-	pdev = of_find_device_by_node(node);
-	of_node_put(node);
-	if (!pdev) {
-		mtk_v4l2_err("no mediatek,larb device found");
-		return -ENODEV;
-	}
-	pm->larbvenc = &pdev->dev;
-	pdev = mtkdev->plat_dev;
-	pm->dev = &pdev->dev;
-
 	enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
 		"clock-names");
 	if (enc_clk->clk_num > 0) {
 		enc_clk->clk_info = devm_kcalloc(&pdev->dev,
 			enc_clk->clk_num, sizeof(*clk_info),
 			GFP_KERNEL);
-		if (!enc_clk->clk_info) {
-			ret = -ENOMEM;
-			goto put_larbvenc;
-		}
+		if (!enc_clk->clk_info)
+			return -ENOMEM;
 	} else {
 		mtk_v4l2_err("Failed to get venc clock count");
-		ret = -EINVAL;
-		goto put_larbvenc;
+		return -EINVAL;
 	}
 
 	for (i = 0; i < enc_clk->clk_num; i++) {
@@ -67,23 +45,18 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 			"clock-names", i, &clk_info->clk_name);
 		if (ret) {
 			mtk_v4l2_err("venc failed to get clk name %d", i);
-			goto put_larbvenc;
+			return ret;
 		}
 		clk_info->vcodec_clk = devm_clk_get(&pdev->dev,
 			clk_info->clk_name);
 		if (IS_ERR(clk_info->vcodec_clk)) {
 			mtk_v4l2_err("venc devm_clk_get (%d)%s fail", i,
 				clk_info->clk_name);
-			ret = PTR_ERR(clk_info->vcodec_clk);
-			goto put_larbvenc;
+			return PTR_ERR(clk_info->vcodec_clk);
 		}
 	}
 
 	return 0;
-
-put_larbvenc:
-	put_device(pm->larbvenc);
-	return ret;
 }
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
@@ -100,11 +73,6 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 		}
 	}
 
-	ret = mtk_smi_larb_get(pm->larbvenc);
-	if (ret) {
-		mtk_v4l2_err("mtk_smi_larb_get larb3 fail %d", ret);
-		goto clkerr;
-	}
 	return;
 
 clkerr:
@@ -117,7 +85,6 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
 	int i = 0;
 
-	mtk_smi_larb_put(pm->larbvenc);
 	for (i = enc_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:03 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:03 +0800
Subject: [PATCH v10 06/13] media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-7-yong.wu@mediatek.com>

MediaTek IOMMU has already added device_link between the consumer
and smi-larb device. If the jpg device calls the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

After removing the larb_get operations, then mtk_jpeg_clk_init is
also unnecessary. Remove it too.

CC: Rick Chang <rick.chang at mediatek.com>
CC: Xia Jiang <xia.jiang at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Acked-by: Rick Chang <rick.chang at mediatek.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 45 +------------------
 .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
 2 files changed, 2 insertions(+), 45 deletions(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index af994b9913a6..1e29ca0aad77 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -22,7 +22,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/videobuf2-core.h>
 #include <media/videobuf2-dma-contig.h>
-#include <soc/mediatek/smi.h>
 
 #include "mtk_jpeg_enc_hw.h"
 #include "mtk_jpeg_dec_hw.h"
@@ -1055,10 +1054,6 @@ static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg)
 {
 	int ret;
 
-	ret = mtk_smi_larb_get(jpeg->larb);
-	if (ret)
-		dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret);
-
 	ret = clk_bulk_prepare_enable(jpeg->variant->num_clks,
 				      jpeg->variant->clks);
 	if (ret)
@@ -1069,7 +1064,6 @@ static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg)
 {
 	clk_bulk_disable_unprepare(jpeg->variant->num_clks,
 				   jpeg->variant->clks);
-	mtk_smi_larb_put(jpeg->larb);
 }
 
 static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
@@ -1284,35 +1278,6 @@ static struct clk_bulk_data mtk_jpeg_clocks[] = {
 	{ .id = "jpgenc" },
 };
 
-static int mtk_jpeg_clk_init(struct mtk_jpeg_dev *jpeg)
-{
-	struct device_node *node;
-	struct platform_device *pdev;
-	int ret;
-
-	node = of_parse_phandle(jpeg->dev->of_node, "mediatek,larb", 0);
-	if (!node)
-		return -EINVAL;
-	pdev = of_find_device_by_node(node);
-	if (WARN_ON(!pdev)) {
-		of_node_put(node);
-		return -EINVAL;
-	}
-	of_node_put(node);
-
-	jpeg->larb = &pdev->dev;
-
-	ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
-				jpeg->variant->clks);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to get jpeg clock:%d\n", ret);
-		put_device(&pdev->dev);
-		return ret;
-	}
-
-	return 0;
-}
-
 static void mtk_jpeg_job_timeout_work(struct work_struct *work)
 {
 	struct mtk_jpeg_dev *jpeg = container_of(work, struct mtk_jpeg_dev,
@@ -1333,11 +1298,6 @@ static void mtk_jpeg_job_timeout_work(struct work_struct *work)
 	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
 }
 
-static inline void mtk_jpeg_clk_release(struct mtk_jpeg_dev *jpeg)
-{
-	put_device(jpeg->larb);
-}
-
 static int mtk_jpeg_probe(struct platform_device *pdev)
 {
 	struct mtk_jpeg_dev *jpeg;
@@ -1374,7 +1334,8 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
 		goto err_req_irq;
 	}
 
-	ret = mtk_jpeg_clk_init(jpeg);
+	ret = devm_clk_bulk_get(jpeg->dev, jpeg->variant->num_clks,
+				jpeg->variant->clks);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to init clk, err %d\n", ret);
 		goto err_clk_init;
@@ -1440,7 +1401,6 @@ static int mtk_jpeg_probe(struct platform_device *pdev)
 	v4l2_device_unregister(&jpeg->v4l2_dev);
 
 err_dev_register:
-	mtk_jpeg_clk_release(jpeg);
 
 err_clk_init:
 
@@ -1458,7 +1418,6 @@ static int mtk_jpeg_remove(struct platform_device *pdev)
 	video_device_release(jpeg->vdev);
 	v4l2_m2m_release(jpeg->m2m_dev);
 	v4l2_device_unregister(&jpeg->v4l2_dev);
-	mtk_jpeg_clk_release(jpeg);
 
 	return 0;
 }
diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
index 595f7f10c9fd..3e4811a41ba2 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h
@@ -85,7 +85,6 @@ struct mtk_jpeg_variant {
  * @alloc_ctx:		videobuf2 memory allocator's context
  * @vdev:		video device node for jpeg mem2mem mode
  * @reg_base:		JPEG registers mapping
- * @larb:		SMI device
  * @job_timeout_work:	IRQ timeout structure
  * @variant:		driver variant to be used
  */
@@ -99,7 +98,6 @@ struct mtk_jpeg_dev {
 	void			*alloc_ctx;
 	struct video_device	*vdev;
 	void __iomem		*reg_base;
-	struct device		*larb;
 	struct delayed_work job_timeout_work;
 	const struct mtk_jpeg_variant *variant;
 };
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:02 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:02 +0800
Subject: [PATCH v10 05/13] iommu/mediatek: Add device_link between the
 consumer and the larb devices
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-6-yong.wu@mediatek.com>

MediaTek IOMMU-SMI diagram is like below. all the consumer connect with
smi-larb, then connect with smi-common.

        M4U
         |
    smi-common
         |
  -------------
  |         |    ...
  |         |
larb1     larb2
  |         |
vdec       venc

When the consumer works, it should enable the smi-larb's power which
also need enable the smi-common's power firstly.

Thus, First of all, use the device link connect the consumer and the
smi-larbs. then add device link between the smi-larb and smi-common.

This patch adds device_link between the consumer and the larbs.

When device_link_add, I add the flag DL_FLAG_STATELESS to avoid calling
pm_runtime_xx to keep the original status of clocks. It can avoid two
issues:
1) Display HW show fastlogo abnormally reported in [1]. At the beggining,
all the clocks are enabled before entering kernel, but the clocks for
display HW(always in larb0) will be gated after clk_enable and clk_disable
called from device_link_add(->pm_runtime_resume) and rpm_idle. The clock
operation happened before display driver probe. At that time, the display
HW will be abnormal.

2) A deadlock issue reported in [2]. Use DL_FLAG_STATELESS to skip
pm_runtime_xx to avoid the deadlock.

Corresponding, DL_FLAG_AUTOREMOVE_CONSUMER can't be added, then
device_link_removed should be added explicitly.

Meanwhile, Currently we don't have a device connect with 2 larbs at the
same time. Disallow this case, print the error log.

[1] https://lore.kernel.org/linux-mediatek/1564213888.22908.4.camel at mhfsdcap03/
[2] https://lore.kernel.org/patchwork/patch/1086569/

Suggested-by: Tomasz Figa <tfiga at chromium.org>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Acked-by: Joerg Roedel <jroedel at suse.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c    | 30 ++++++++++++++++++++++++++++++
 drivers/iommu/mtk_iommu_v1.c | 29 ++++++++++++++++++++++++++++-
 2 files changed, 58 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 5cff5bc556d4..77df61092be3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -562,22 +562,52 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct mtk_iommu_data *data;
+	struct device_link *link;
+	struct device *larbdev;
+	unsigned int larbid, larbidx, i;
 
 	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
 		return ERR_PTR(-ENODEV); /* Not a iommu client device */
 
 	data = dev_iommu_priv_get(dev);
 
+	/*
+	 * Link the consumer device with the smi-larb device(supplier).
+	 * The device that connects with each a larb is a independent HW.
+	 * All the ports in each a device should be in the same larbs.
+	 */
+	larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+	for (i = 1; i < fwspec->num_ids; i++) {
+		larbidx = MTK_M4U_TO_LARB(fwspec->ids[i]);
+		if (larbid != larbidx) {
+			dev_err(dev, "Can only use one larb. Fail at larb%d-%d.\n",
+				larbid, larbidx);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+	larbdev = data->larb_imu[larbid].dev;
+	link = device_link_add(dev, larbdev,
+			       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+	if (!link)
+		dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
 	return &data->iommu;
 }
 
 static void mtk_iommu_release_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct mtk_iommu_data *data;
+	struct device *larbdev;
+	unsigned int larbid;
 
 	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
 		return;
 
+	data = dev_iommu_priv_get(dev);
+	larbid = MTK_M4U_TO_LARB(fwspec->ids[0]);
+	larbdev = data->larb_imu[larbid].dev;
+	device_link_remove(dev, larbdev);
+
 	iommu_fwspec_free(dev);
 }
 
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 4089077256f4..4052aad75a81 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -423,7 +423,9 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct of_phandle_args iommu_spec;
 	struct mtk_iommu_data *data;
-	int err, idx = 0;
+	int err, idx = 0, larbid, larbidx;
+	struct device_link *link;
+	struct device *larbdev;
 
 	/*
 	 * In the deferred case, free the existed fwspec.
@@ -453,6 +455,23 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 
 	data = dev_iommu_priv_get(dev);
 
+	/* Link the consumer device with the smi-larb device(supplier) */
+	larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
+	for (idx = 1; idx < fwspec->num_ids; idx++) {
+		larbidx = mt2701_m4u_to_larb(fwspec->ids[idx]);
+		if (larbid != larbidx) {
+			dev_err(dev, "Can only use one larb. Fail at larb%d-%d.\n",
+				larbid, larbidx);
+			return ERR_PTR(-EINVAL);
+		}
+	}
+
+	larbdev = data->larb_imu[larbid].dev;
+	link = device_link_add(dev, larbdev,
+			       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+	if (!link)
+		dev_err(dev, "Unable to link %s\n", dev_name(larbdev));
+
 	return &data->iommu;
 }
 
@@ -473,10 +492,18 @@ static void mtk_iommu_probe_finalize(struct device *dev)
 static void mtk_iommu_release_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct mtk_iommu_data *data;
+	struct device *larbdev;
+	unsigned int larbid;
 
 	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
 		return;
 
+	data = dev_iommu_priv_get(dev);
+	larbid = mt2701_m4u_to_larb(fwspec->ids[0]);
+	larbdev = data->larb_imu[larbid].dev;
+	device_link_remove(dev, larbdev);
+
 	iommu_fwspec_free(dev);
 }
 
-- 
2.18.0



From biao.huang at mediatek.com  Sun Jan 16 23:07:06 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:06 +0800
Subject: [PATCH net-next v12 7/7] net: dt-bindings: dwmac: add support for
 mt8195
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-8-biao.huang@mediatek.com>

Add binding document for the ethernet on mt8195.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 .../bindings/net/mediatek-dwmac.yaml          | 28 ++++++++++++++++---
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
index 8ad6e19661b8..901944683322 100644
--- a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
@@ -19,6 +19,7 @@ select:
       contains:
         enum:
           - mediatek,mt2712-gmac
+          - mediatek,mt8195-gmac
   required:
     - compatible
 
@@ -27,26 +28,35 @@ allOf:
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt2712-gmac
-      - const: snps,dwmac-4.20a
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt2712-gmac
+          - const: snps,dwmac-4.20a
+      - items:
+          - enum:
+              - mediatek,mt8195-gmac
+          - const: snps,dwmac-5.10a
 
   clocks:
+    minItems: 5
     items:
       - description: AXI clock
       - description: APB clock
       - description: MAC Main clock
       - description: PTP clock
       - description: RMII reference clock provided by MAC
+      - description: MAC clock gate
 
   clock-names:
+    minItems: 5
     items:
       - const: axi
       - const: apb
       - const: mac_main
       - const: ptp_ref
       - const: rmii_internal
+      - const: mac_cg
 
   mediatek,pericfg:
     $ref: /schemas/types.yaml#/definitions/phandle
@@ -61,6 +71,8 @@ properties:
       or will round down. Range 0~31*170.
       For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
       or will round down. Range 0~31*550.
+      For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple of 290,
+      or will round down. Range 0~31*290.
 
   mediatek,rx-delay-ps:
     description:
@@ -69,6 +81,8 @@ properties:
       or will round down. Range 0~31*170.
       For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
       or will round down. Range 0~31*550.
+      For MT8195 RGMII/RMII/MII interface, Allowed value need to be a multiple
+      of 290, or will round down. Range 0~31*290.
 
   mediatek,rmii-rxc:
     type: boolean
@@ -102,6 +116,12 @@ properties:
       3. the inside clock, which be sent to MAC, will be inversed in RMII case when
          the reference clock is from MAC.
 
+  mediatek,mac-wol:
+    type: boolean
+    description:
+      If present, indicates that MAC supports WOL(Wake-On-LAN), and MAC WOL will be enabled.
+      Otherwise, PHY WOL is perferred.
+
 required:
   - compatible
   - reg
-- 
2.25.1



From yong.wu at mediatek.com  Sun Jan 16 23:05:06 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:06 +0800
Subject: [PATCH v10 09/13] drm/mediatek: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-10-yong.wu@mediatek.com>

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the drm device calls the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: CK Hu <ck.hu at mediatek.com>
CC: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 10 ------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 36 ++-------------------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |  5 +--
 4 files changed, 3 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index ce5bbd6918cf..12c6a2097142 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -10,7 +10,6 @@
 #include <linux/soc/mediatek/mtk-mutex.h>
 
 #include <asm/barrier.h>
-#include <soc/mediatek/smi.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -548,22 +547,14 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 
 	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 
-	ret = mtk_smi_larb_get(comp->larb_dev);
-	if (ret) {
-		DRM_ERROR("Failed to get larb: %d\n", ret);
-		return;
-	}
-
 	ret = pm_runtime_resume_and_get(comp->dev);
 	if (ret < 0) {
-		mtk_smi_larb_put(comp->larb_dev);
 		DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
 		return;
 	}
 
 	ret = mtk_crtc_ddp_hw_init(mtk_crtc);
 	if (ret) {
-		mtk_smi_larb_put(comp->larb_dev);
 		pm_runtime_put(comp->dev);
 		return;
 	}
@@ -600,7 +591,6 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 
 	drm_crtc_vblank_off(crtc);
 	mtk_crtc_ddp_hw_fini(mtk_crtc);
-	mtk_smi_larb_put(comp->larb_dev);
 	ret = pm_runtime_put(comp->dev);
 	if (ret < 0)
 		DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 99cbf44463e4..48642e814370 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -414,37 +414,15 @@ unsigned int mtk_drm_find_possible_crtc_by_comp(struct drm_device *drm,
 	return ret;
 }
 
-static int mtk_ddp_get_larb_dev(struct device_node *node, struct mtk_ddp_comp *comp,
-				struct device *dev)
-{
-	struct device_node *larb_node;
-	struct platform_device *larb_pdev;
-
-	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
-	if (!larb_node) {
-		dev_err(dev, "Missing mediadek,larb phandle in %pOF node\n", node);
-		return -EINVAL;
-	}
-
-	larb_pdev = of_find_device_by_node(larb_node);
-	if (!larb_pdev) {
-		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
-		of_node_put(larb_node);
-		return -EPROBE_DEFER;
-	}
-	of_node_put(larb_node);
-	comp->larb_dev = &larb_pdev->dev;
-
-	return 0;
-}
-
 int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 		      enum mtk_ddp_comp_id comp_id)
 {
 	struct platform_device *comp_pdev;
 	enum mtk_ddp_comp_type type;
 	struct mtk_ddp_comp_dev *priv;
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	int ret;
+#endif
 
 	if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
 		return -EINVAL;
@@ -460,16 +438,6 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	}
 	comp->dev = &comp_pdev->dev;
 
-	/* Only DMA capable components need the LARB property */
-	if (type == MTK_DISP_OVL ||
-	    type == MTK_DISP_OVL_2L ||
-	    type == MTK_DISP_RDMA ||
-	    type == MTK_DISP_WDMA) {
-		ret = mtk_ddp_get_larb_dev(node, comp, comp->dev);
-		if (ret)
-			return ret;
-	}
-
 	if (type == MTK_DISP_AAL ||
 	    type == MTK_DISP_BLS ||
 	    type == MTK_DISP_CCORR ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index bb914d976cf5..1b582262b682 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -70,7 +70,6 @@ struct mtk_ddp_comp_funcs {
 struct mtk_ddp_comp {
 	struct device *dev;
 	int irq;
-	struct device *larb_dev;
 	enum mtk_ddp_comp_id id;
 	const struct mtk_ddp_comp_funcs *funcs;
 };
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index aec39724ebeb..c234293fc2c3 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -603,11 +603,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 err_node:
 	of_node_put(private->mutex_node);
-	for (i = 0; i < DDP_COMPONENT_ID_MAX; i++) {
+	for (i = 0; i < DDP_COMPONENT_ID_MAX; i++)
 		of_node_put(private->comp_node[i]);
-		if (private->ddp_comp[i].larb_dev)
-			put_device(private->ddp_comp[i].larb_dev);
-	}
 	return ret;
 }
 
-- 
2.18.0



From biao.huang at mediatek.com  Sun Jan 16 23:07:05 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:05 +0800
Subject: [PATCH net-next v12 6/7] stmmac: dwmac-mediatek: add support for
 mt8195
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-7-biao.huang@mediatek.com>

Add Ethernet support for MediaTek SoCs from the mt8195 family.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 278 +++++++++++++++++-
 1 file changed, 268 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 2678d2deb26a..3b12434fdb24 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -39,6 +39,33 @@
 #define ETH_FINE_DLY_GTXC	BIT(1)
 #define ETH_FINE_DLY_RXC	BIT(0)
 
+/* Peri Configuration register for mt8195 */
+#define MT8195_PERI_ETH_CTRL0		0xFD0
+#define MT8195_RMII_CLK_SRC_INTERNAL	BIT(28)
+#define MT8195_RMII_CLK_SRC_RXC		BIT(27)
+#define MT8195_ETH_INTF_SEL		GENMASK(26, 24)
+#define MT8195_RGMII_TXC_PHASE_CTRL	BIT(22)
+#define MT8195_EXT_PHY_MODE		BIT(21)
+#define MT8195_DLY_GTXC_INV		BIT(12)
+#define MT8195_DLY_GTXC_ENABLE		BIT(5)
+#define MT8195_DLY_GTXC_STAGES		GENMASK(4, 0)
+
+#define MT8195_PERI_ETH_CTRL1		0xFD4
+#define MT8195_DLY_RXC_INV		BIT(25)
+#define MT8195_DLY_RXC_ENABLE		BIT(18)
+#define MT8195_DLY_RXC_STAGES		GENMASK(17, 13)
+#define MT8195_DLY_TXC_INV		BIT(12)
+#define MT8195_DLY_TXC_ENABLE		BIT(5)
+#define MT8195_DLY_TXC_STAGES		GENMASK(4, 0)
+
+#define MT8195_PERI_ETH_CTRL2		0xFD8
+#define MT8195_DLY_RMII_RXC_INV		BIT(25)
+#define MT8195_DLY_RMII_RXC_ENABLE	BIT(18)
+#define MT8195_DLY_RMII_RXC_STAGES	GENMASK(17, 13)
+#define MT8195_DLY_RMII_TXC_INV		BIT(12)
+#define MT8195_DLY_RMII_TXC_ENABLE	BIT(5)
+#define MT8195_DLY_RMII_TXC_STAGES	GENMASK(4, 0)
+
 struct mac_delay_struct {
 	u32 tx_delay;
 	u32 rx_delay;
@@ -57,12 +84,14 @@ struct mediatek_dwmac_plat_data {
 	phy_interface_t phy_mode;
 	bool rmii_clk_from_mac;
 	bool rmii_rxc;
+	bool mac_wol;
 	int num_clks;
 };
 
 struct mediatek_dwmac_variant {
 	int (*dwmac_set_phy_interface)(struct mediatek_dwmac_plat_data *plat);
 	int (*dwmac_set_delay)(struct mediatek_dwmac_plat_data *plat);
+	void (*dwmac_fix_mac_speed)(void *priv, unsigned int speed);
 
 	/* clock ids to be requested */
 	const char * const *clk_list;
@@ -78,6 +107,10 @@ static const char * const mt2712_dwmac_clk_l[] = {
 	"axi", "apb", "mac_main", "ptp_ref"
 };
 
+static const char * const mt8195_dwmac_clk_l[] = {
+	"axi", "apb", "mac_cg", "mac_main", "ptp_ref"
+};
+
 static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
 {
 	int rmii_clk_from_mac = plat->rmii_clk_from_mac ? RMII_CLK_SRC_INTERNAL : 0;
@@ -257,6 +290,193 @@ static const struct mediatek_dwmac_variant mt2712_gmac_variant = {
 		.tx_delay_max = 17600,
 };
 
+static int mt8195_set_interface(struct mediatek_dwmac_plat_data *plat)
+{
+	int rmii_clk_from_mac = plat->rmii_clk_from_mac ? MT8195_RMII_CLK_SRC_INTERNAL : 0;
+	int rmii_rxc = plat->rmii_rxc ? MT8195_RMII_CLK_SRC_RXC : 0;
+	u32 intf_val = 0;
+
+	/* select phy interface in top control domain */
+	switch (plat->phy_mode) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_MII);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val |= (rmii_rxc | rmii_clk_from_mac);
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RMII);
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		intf_val |= FIELD_PREP(MT8195_ETH_INTF_SEL, PHY_INTF_RGMII);
+		break;
+	default:
+		dev_err(plat->dev, "phy interface not supported\n");
+		return -EINVAL;
+	}
+
+	/* MT8195 only support external PHY */
+	intf_val |= MT8195_EXT_PHY_MODE;
+
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL0, intf_val);
+
+	return 0;
+}
+
+static void mt8195_delay_ps2stage(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+
+	/* 290ps per stage */
+	mac_delay->tx_delay /= 290;
+	mac_delay->rx_delay /= 290;
+}
+
+static void mt8195_delay_stage2ps(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+
+	/* 290ps per stage */
+	mac_delay->tx_delay *= 290;
+	mac_delay->rx_delay *= 290;
+}
+
+static int mt8195_set_delay(struct mediatek_dwmac_plat_data *plat)
+{
+	struct mac_delay_struct *mac_delay = &plat->mac_delay;
+	u32 gtxc_delay_val = 0, delay_val = 0, rmii_delay_val = 0;
+
+	mt8195_delay_ps2stage(plat);
+
+	switch (plat->phy_mode) {
+	case PHY_INTERFACE_MODE_MII:
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE, !!mac_delay->tx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES, mac_delay->tx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV, mac_delay->tx_inv);
+
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES, mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay->rx_inv);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (plat->rmii_clk_from_mac) {
+			/* case 1: mac provides the rmii reference clock,
+			 * and the clock output to TXC pin.
+			 * The egress timing can be adjusted by RMII_TXC delay macro circuit.
+			 * The ingress timing can be adjusted by RMII_RXC delay macro circuit.
+			 */
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_ENABLE,
+						     !!mac_delay->tx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_STAGES,
+						     mac_delay->tx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_TXC_INV,
+						     mac_delay->tx_inv);
+
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_ENABLE,
+						     !!mac_delay->rx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_STAGES,
+						     mac_delay->rx_delay);
+			rmii_delay_val |= FIELD_PREP(MT8195_DLY_RMII_RXC_INV,
+						     mac_delay->rx_inv);
+		} else {
+			/* case 2: the rmii reference clock is from external phy,
+			 * and the property "rmii_rxc" indicates which pin(TXC/RXC)
+			 * the reference clk is connected to. The reference clock is a
+			 * received signal, so rx_delay/rx_inv are used to indicate
+			 * the reference clock timing adjustment
+			 */
+			if (plat->rmii_rxc) {
+				/* the rmii reference clock from outside is connected
+				 * to RXC pin, the reference clock will be adjusted
+				 * by RXC delay macro circuit.
+				 */
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE,
+							!!mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES,
+							mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV,
+							mac_delay->rx_inv);
+			} else {
+				/* the rmii reference clock from outside is connected
+				 * to TXC pin, the reference clock will be adjusted
+				 * by TXC delay macro circuit.
+				 */
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_ENABLE,
+							!!mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_STAGES,
+							mac_delay->rx_delay);
+				delay_val |= FIELD_PREP(MT8195_DLY_TXC_INV,
+							mac_delay->rx_inv);
+			}
+		}
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_ENABLE, !!mac_delay->tx_delay);
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_STAGES, mac_delay->tx_delay);
+		gtxc_delay_val |= FIELD_PREP(MT8195_DLY_GTXC_INV, mac_delay->tx_inv);
+
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_ENABLE, !!mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_STAGES, mac_delay->rx_delay);
+		delay_val |= FIELD_PREP(MT8195_DLY_RXC_INV, mac_delay->rx_inv);
+
+		break;
+	default:
+		dev_err(plat->dev, "phy interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_update_bits(plat->peri_regmap,
+			   MT8195_PERI_ETH_CTRL0,
+			   MT8195_RGMII_TXC_PHASE_CTRL |
+			   MT8195_DLY_GTXC_INV |
+			   MT8195_DLY_GTXC_ENABLE |
+			   MT8195_DLY_GTXC_STAGES,
+			   gtxc_delay_val);
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL1, delay_val);
+	regmap_write(plat->peri_regmap, MT8195_PERI_ETH_CTRL2, rmii_delay_val);
+
+	mt8195_delay_stage2ps(plat);
+
+	return 0;
+}
+
+static void mt8195_fix_mac_speed(void *priv, unsigned int speed)
+{
+	struct mediatek_dwmac_plat_data *priv_plat = priv;
+
+	if ((phy_interface_mode_is_rgmii(priv_plat->phy_mode))) {
+		/* prefer 2ns fixed delay which is controlled by TXC_PHASE_CTRL,
+		 * when link speed is 1Gbps with RGMII interface,
+		 * Fall back to delay macro circuit for 10/100Mbps link speed.
+		 */
+		if (speed == SPEED_1000)
+			regmap_update_bits(priv_plat->peri_regmap,
+					   MT8195_PERI_ETH_CTRL0,
+					   MT8195_RGMII_TXC_PHASE_CTRL |
+					   MT8195_DLY_GTXC_ENABLE |
+					   MT8195_DLY_GTXC_INV |
+					   MT8195_DLY_GTXC_STAGES,
+					   MT8195_RGMII_TXC_PHASE_CTRL);
+		else
+			mt8195_set_delay(priv_plat);
+	}
+}
+
+static const struct mediatek_dwmac_variant mt8195_gmac_variant = {
+	.dwmac_set_phy_interface = mt8195_set_interface,
+	.dwmac_set_delay = mt8195_set_delay,
+	.dwmac_fix_mac_speed = mt8195_fix_mac_speed,
+	.clk_list = mt8195_dwmac_clk_l,
+	.num_clks = ARRAY_SIZE(mt8195_dwmac_clk_l),
+	.dma_bit_mask = 35,
+	.rx_delay_max = 9280,
+	.tx_delay_max = 9280,
+};
+
 static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
 {
 	struct mac_delay_struct *mac_delay = &plat->mac_delay;
@@ -297,6 +517,7 @@ static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
 	mac_delay->rx_inv = of_property_read_bool(plat->np, "mediatek,rxc-inverse");
 	plat->rmii_rxc = of_property_read_bool(plat->np, "mediatek,rmii-rxc");
 	plat->rmii_clk_from_mac = of_property_read_bool(plat->np, "mediatek,rmii-clk-from-mac");
+	plat->mac_wol = of_property_read_bool(plat->np, "mediatek,mac-wol");
 
 	return 0;
 }
@@ -409,6 +630,50 @@ static int mediatek_dwmac_clks_config(void *priv, bool enabled)
 
 	return ret;
 }
+
+static int mediatek_dwmac_common_data(struct platform_device *pdev,
+			   struct plat_stmmacenet_data *plat,
+			   struct mediatek_dwmac_plat_data *priv_plat)
+{
+	int i;
+
+	plat->interface = priv_plat->phy_mode;
+	plat->use_phy_wol = priv_plat->mac_wol ? 0 : 1;
+	plat->riwt_off = 1;
+	plat->maxmtu = ETH_DATA_LEN;
+	plat->addr64 = priv_plat->variant->dma_bit_mask;
+	plat->bsp_priv = priv_plat;
+	plat->init = mediatek_dwmac_init;
+	plat->exit = mediatek_dwmac_exit;
+	plat->clks_config = mediatek_dwmac_clks_config;
+	if (priv_plat->variant->dwmac_fix_mac_speed)
+		plat->fix_mac_speed = priv_plat->variant->dwmac_fix_mac_speed;
+
+	plat->safety_feat_cfg = devm_kzalloc(&pdev->dev,
+					     sizeof(*plat->safety_feat_cfg),
+					     GFP_KERNEL);
+	if (!plat->safety_feat_cfg)
+		return -ENOMEM;
+
+	plat->safety_feat_cfg->tsoee = 1;
+	plat->safety_feat_cfg->mrxpee = 0;
+	plat->safety_feat_cfg->mestee = 1;
+	plat->safety_feat_cfg->mrxee = 1;
+	plat->safety_feat_cfg->mtxee = 1;
+	plat->safety_feat_cfg->epsi = 0;
+	plat->safety_feat_cfg->edpp = 1;
+	plat->safety_feat_cfg->prtyen = 1;
+	plat->safety_feat_cfg->tmouten = 1;
+
+	for (i = 0; i < plat->tx_queues_to_use; i++) {
+		/* Default TX Q0 to use TSO and rest TXQ for TBS */
+		if (i > 0)
+			plat->tx_queues_cfg[i].tbs_en = 1;
+	}
+
+	return 0;
+}
+
 static int mediatek_dwmac_probe(struct platform_device *pdev)
 {
 	struct mediatek_dwmac_plat_data *priv_plat;
@@ -445,16 +710,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	if (IS_ERR(plat_dat))
 		return PTR_ERR(plat_dat);
 
-	plat_dat->interface = priv_plat->phy_mode;
-	plat_dat->use_phy_wol = 1;
-	plat_dat->riwt_off = 1;
-	plat_dat->maxmtu = ETH_DATA_LEN;
-	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
-	plat_dat->bsp_priv = priv_plat;
-	plat_dat->init = mediatek_dwmac_init;
-	plat_dat->exit = mediatek_dwmac_exit;
-	plat_dat->clks_config = mediatek_dwmac_clks_config;
-
+	mediatek_dwmac_common_data(pdev, plat_dat, priv_plat);
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
@@ -469,6 +725,8 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 static const struct of_device_id mediatek_dwmac_match[] = {
 	{ .compatible = "mediatek,mt2712-gmac",
 	  .data = &mt2712_gmac_variant },
+	{ .compatible = "mediatek,mt8195-gmac",
+	  .data = &mt8195_gmac_variant },
 	{ }
 };
 
-- 
2.25.1



From biao.huang at mediatek.com  Sun Jan 16 23:07:00 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:00 +0800
Subject: [PATCH net-next v12 1/7] stmmac: dwmac-mediatek: add platform level
 clocks management
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-2-biao.huang@mediatek.com>

This patch implements clks_config callback for dwmac-mediatek platform,
which could support platform level clocks management.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 25 +++++++++++++------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 58c0feaa8131..0ff57c268dca 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -9,7 +9,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_net.h>
-#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/stmmac.h>
 
@@ -359,9 +358,6 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
 		return ret;
 	}
 
-	pm_runtime_enable(&pdev->dev);
-	pm_runtime_get_sync(&pdev->dev);
-
 	return 0;
 }
 
@@ -370,11 +366,25 @@ static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
 	struct mediatek_dwmac_plat_data *plat = priv;
 
 	clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
-
-	pm_runtime_put_sync(&pdev->dev);
-	pm_runtime_disable(&pdev->dev);
 }
 
+static int mediatek_dwmac_clks_config(void *priv, bool enabled)
+{
+	struct mediatek_dwmac_plat_data *plat = priv;
+	int ret = 0;
+
+	if (enabled) {
+		ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
+		if (ret) {
+			dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
+			return ret;
+		}
+	} else {
+		clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
+	}
+
+	return ret;
+}
 static int mediatek_dwmac_probe(struct platform_device *pdev)
 {
 	struct mediatek_dwmac_plat_data *priv_plat;
@@ -420,6 +430,7 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 	plat_dat->bsp_priv = priv_plat;
 	plat_dat->init = mediatek_dwmac_init;
 	plat_dat->exit = mediatek_dwmac_exit;
+	plat_dat->clks_config = mediatek_dwmac_clks_config;
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-- 
2.25.1



From axe.yang at mediatek.com  Sun Jan 16 23:12:17 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 15:12:17 +0800
Subject: [PATCH v3 0/3]mmc: mediatek: add support for SDIO async IRQ 
Message-ID: <20220117071220.17330-1-axe.yang@mediatek.com>


Changes in v3:
- correct abbreviations with capital letters in commit message
- replace copyright year with 2022 in mtk-sd.c
- remove unnessary pointer casting
- adjust variable order to reversed xmas tree
- remove a redundant blank line
- refine if statement, following standard pattern

Axe Yang (3):
  dt-bindings: mmc: add cap-sdio-async-irq flag
  mmc: core: Add support for SDIO async interrupt
  mmc: mediatek: add support for SDIO eint IRQ

 .../bindings/mmc/mmc-controller.yaml          |   5 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/sdio.c                       |  17 +++
 drivers/mmc/host/mtk-sd.c                     | 125 ++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +-
 include/linux/mmc/host.h                      |   1 +
 include/linux/mmc/sdio.h                      |   5 +
 7 files changed, 149 insertions(+), 9 deletions(-)

-- 
2.25.1



From biao.huang at mediatek.com  Sun Jan 16 23:06:59 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:06:59 +0800
Subject: [PATCH net-next v12 0/7] MediaTek Ethernet Patches on MT8195
Message-ID: <20220117070706.17853-1-biao.huang@mediatek.com>

Changes in v12:
1. add a new patch "stmmac: dwmac-mediatek: re-arrange clock setting" to
   this series, to simplify clock handling in driver, which benefits to
   binding file mediatek-dwmac.yaml.
2. modify dt-binding description in patch "net: dt-bindings: dwmac: add
   support for mt8195" as Rob's comments in v10 series, put mac_cg to the
   end of clock list.
3. there are small changes in patch "stmmac: dwmac-mediatek: add support
   for mt8195", @AngeloGioacchino, please review it kindly.

Changes in v11:
1. add reivewed-by in "net: dt-bindings: dwmac: Convert mediatek-dwmac to
   DT schema" as Rob's comments.
2. fall back "net: dt-bindings: dwmac: add support for mt8195" to v8 version
   as mentioned in previous reply(https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20211216055328.15953-7-biao.huang at mediatek.com/):
   2.1 there is already a special clock named "rmii_internal", which need to
       be put to the end of the clock list(driver special handling),
       so we can't simply put new "mac_cg" for mt8195 to the end of the clock
       list.
   2.2 we prefer the if-then schema, which will make mt8195 clock list clearer
       with some duplicated information.
   2.3 we expect the future IC will follow mt2712 or mt8195, so we only need
       add new IC name to compatible list for future IC, and will not make the
       clock list binding files worse.

Changes in v10:
1. add detailed description in "arm64: dts: mt2712: update ethernet
   device node" to make the modifications clearer as Matthias's comments.
2. modify dt-binding description as Rob's comments, and "make dtbs_check" runs
   pass locally with "arm64: dts: mt2712: update ethernet device node"
   in this series.

Changes in v9:
1. remove oneOf for 1 entry as Rob's comments.
2. add new clocks to the end of existing clocks to simplify
   the binding as Rob's comments.

Changes in v8:
1. add acked-by in "stmmac: dwmac-mediatek: add platform level clocks
   management" patch

Changes in v7:
1. fix uninitialized warning as Jakub's comments.

Changes in v6:
1. update commit message as Jakub's comments.
2. split mt8195 eth dts patch("arm64: dts: mt8195: add ethernet device
   node") from this series, since mt8195 dtsi/dts basic patches is still
   under reviewing.
   https://patchwork.kernel.org/project/linux-mediatek/list/?series=579071
   we'll resend mt8195 eth dts patch once all the dependent patches are
   accepted.

Changes in v5:
1. remove useless inclusion in dwmac-mediatek.c as Angelo's comments.
2. add acked-by in "net-next: stmmac: dwmac-mediatek: add support for
   mt8195" patch

Changes in v4:
1. add changes in commit message in "net-next: dt-bindings: dwmac:
   Convert mediatek-dwmac to DT schema" patch.
2. remove ethernet-controller.yaml since snps,dwmac.yaml already include it.

Changes in v3:
1. Add prefix "net-next" to support new IC as Denis's suggestion.
2. Split dt-bindings to two patches, one for conversion, and the other for
   new IC.
3. add a new patch to update device node in mt2712-evb.dts to accommodate to
   changes in driver.
4. remove unnecessary wrapper as Angelo's suggestion.
5. Add acked-by in "net-next: stmmac: dwmac-mediatek: Reuse more common
   features" patch.

Changes in v2:
1. fix errors/warnings in mediatek-dwmac.yaml with upgraded dtschema tools

Changes in v1:
This series include 5 patches:
1. add platform level clocks management for dwmac-mediatek
2. resue more common features defined in stmmac_platform.c
3. add ethernet entry for mt8195

Biao Huang (7):
  stmmac: dwmac-mediatek: add platform level clocks management
  stmmac: dwmac-mediatek: Reuse more common features
  stmmac: dwmac-mediatek: re-arrange clock setting
  arm64: dts: mt2712: update ethernet device node
  net: dt-bindings: dwmac: Convert mediatek-dwmac to DT schema
  stmmac: dwmac-mediatek: add support for mt8195
  net: dt-bindings: dwmac: add support for mt8195

 .../bindings/net/mediatek-dwmac.txt           |  91 ----
 .../bindings/net/mediatek-dwmac.yaml          | 175 ++++++++
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts   |   1 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi     |  14 +-
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 389 +++++++++++++++---
 5 files changed, 526 insertions(+), 144 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
 create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.yaml

--
2.18.0




From yong.wu at mediatek.com  Sun Jan 16 23:04:59 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:04:59 +0800
Subject: [PATCH v10 02/13] iommu/mediatek-v1: Free the existed fwspec if the
 master dev already has
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-3-yong.wu@mediatek.com>

When the iommu master device enters of_iommu_xlate, the ops may be
NULL(iommu dev is defered), then it will initialize the fwspec here:

[<c0c9c5bc>] (dev_iommu_fwspec_set) from [<c06bda80>]
(iommu_fwspec_init+0xbc/0xd4)
[<c06bd9c4>] (iommu_fwspec_init) from [<c06c0db4>]
(of_iommu_xlate+0x7c/0x12c)
[<c06c0d38>] (of_iommu_xlate) from [<c06c10e8>]
(of_iommu_configure+0x144/0x1e8)

BUT the mtk_iommu_v1.c only supports arm32, the probing flow still is a bit
weird. We always expect create the fwspec internally. otherwise it will
enter here and return fail.

static int mtk_iommu_create_mapping(struct device *dev,
				    struct of_phandle_args *args)
{
        ...
	if (!fwspec) {
	        ....
	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {
                >>>>>>>>>>Enter here. return fail.<<<<<<<<<<<<
		return -EINVAL;
	}
	...
}

Thus, Free the existed fwspec if the master device already has fwspec.

This issue is reported at:
https://lore.kernel.org/linux-mediatek/trinity-7d9ebdc9-4849-4d93-bfb5-429dcb4ee449-1626253158870 at 3c-app-gmx-bs01/

Reported-by: Frank Wunderlich <frank-w at public-files.de>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Joerg Roedel <jroedel at suse.de>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu_v1.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index be22fcf988ce..1467ba1e4417 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -425,6 +425,15 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 	struct mtk_iommu_data *data;
 	int err, idx = 0;
 
+	/*
+	 * In the deferred case, free the existed fwspec.
+	 * Always initialize the fwspec internally.
+	 */
+	if (fwspec) {
+		iommu_fwspec_free(dev);
+		fwspec = dev_iommu_fwspec_get(dev);
+	}
+
 	while (!of_parse_phandle_with_args(dev->of_node, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
-- 
2.18.0



From axe.yang at mediatek.com  Sun Jan 16 23:12:19 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 15:12:19 +0800
Subject: [PATCH 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20220117071220.17330-1-axe.yang@mediatek.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
Message-ID: <20220117071220.17330-3-axe.yang@mediatek.com>

If cap-sdio-async-irq flag is set in host dts node, parse EAI
information from SDIO CCCR interrupt externsion segment. If async
interrupt is supported by SDIO card then send command to card to
enable it and set enable_async_irq flag in sdio_cccr structure to 1.
The parse flow is implemented in sdio_read_cccr().

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
 include/linux/mmc/card.h |  3 ++-
 include/linux/mmc/host.h |  1 +
 include/linux/mmc/sdio.h |  5 +++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf140f4ec864..a972241548b4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -410,6 +410,8 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "no-mmc-hs400"))
 		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
 				 MMC_CAP2_HS400_ES);
+	if (device_property_read_bool(dev, "cap-sdio-async-irq"))
+		host->caps2 |= MMC_CAP2_SDIO_ASYNC_IRQ;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 41164748723d..771fb5d18585 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
 			if (data & SDIO_DRIVE_SDTD)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ) {
+				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
+						       &data);
+				if (ret)
+					goto out;
+
+				if (data & SDIO_INTERRUPT_EXT_SAI) {
+					data |= SDIO_INTERRUPT_EXT_EAI;
+					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+							       data, NULL);
+					if (ret)
+						goto out;
+
+					card->cccr.enable_async_irq = 1;
+				}
+			}
 		}
 
 		/* if no uhs mode ensure we check for high speed */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 37f975875102..4df9182bc0e6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,8 @@ struct sdio_cccr {
 				wide_bus:1,
 				high_power:1,
 				high_speed:1,
-				disable_cd:1;
+				disable_cd:1,
+				enable_async_irq:1;
 };
 
 struct sdio_cis {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7afb57cab00b..502a5418264c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -402,6 +402,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SDIO_ASYNC_IRQ	(1 << 29)	/* SDIO host supports asynchronous interrupt */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 2a05d1ac4f0e..1ef400f28642 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -159,6 +159,11 @@
 #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT	0x16
+#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
-- 
2.25.1



From yong.wu at mediatek.com  Sun Jan 16 23:05:04 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:04 +0800
Subject: [PATCH v10 07/13] media: mtk-mdp: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-8-yong.wu@mediatek.com>

MediaTek IOMMU has already added the device_link between the consumer
and smi-larb device. If the mdp device calls the pm_runtime_get_sync,
the smi-larb's pm_runtime_get_sync also be called automatically.

CC: Minghsiu Tsai <minghsiu.tsai at mediatek.com>
CC: Houlong Wei <houlong.wei at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Reviewed-by: Houlong Wei <houlong.wei at mediatek.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 -------------------
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
 3 files changed, 43 deletions(-)

diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
index b3426a551bea..1e3833f1c9ae 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.c
@@ -9,7 +9,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
-#include <soc/mediatek/smi.h>
 
 #include "mtk_mdp_comp.h"
 
@@ -18,14 +17,6 @@ void mtk_mdp_comp_clock_on(struct device *dev, struct mtk_mdp_comp *comp)
 {
 	int i, err;
 
-	if (comp->larb_dev) {
-		err = mtk_smi_larb_get(comp->larb_dev);
-		if (err)
-			dev_err(dev,
-				"failed to get larb, err %d. type:%d\n",
-				err, comp->type);
-	}
-
 	for (i = 0; i < ARRAY_SIZE(comp->clk); i++) {
 		if (IS_ERR(comp->clk[i]))
 			continue;
@@ -46,17 +37,12 @@ void mtk_mdp_comp_clock_off(struct device *dev, struct mtk_mdp_comp *comp)
 			continue;
 		clk_disable_unprepare(comp->clk[i]);
 	}
-
-	if (comp->larb_dev)
-		mtk_smi_larb_put(comp->larb_dev);
 }
 
 int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 		      struct mtk_mdp_comp *comp,
 		      enum mtk_mdp_comp_type comp_type)
 {
-	struct device_node *larb_node;
-	struct platform_device *larb_pdev;
 	int ret;
 	int i;
 
@@ -77,32 +63,6 @@ int mtk_mdp_comp_init(struct device *dev, struct device_node *node,
 			break;
 	}
 
-	/* Only DMA capable components need the LARB property */
-	comp->larb_dev = NULL;
-	if (comp->type != MTK_MDP_RDMA &&
-	    comp->type != MTK_MDP_WDMA &&
-	    comp->type != MTK_MDP_WROT)
-		return 0;
-
-	larb_node = of_parse_phandle(node, "mediatek,larb", 0);
-	if (!larb_node) {
-		dev_err(dev,
-			"Missing mediadek,larb phandle in %pOF node\n", node);
-		ret = -EINVAL;
-		goto put_dev;
-	}
-
-	larb_pdev = of_find_device_by_node(larb_node);
-	if (!larb_pdev) {
-		dev_warn(dev, "Waiting for larb device %pOF\n", larb_node);
-		of_node_put(larb_node);
-		ret = -EPROBE_DEFER;
-		goto put_dev;
-	}
-	of_node_put(larb_node);
-
-	comp->larb_dev = &larb_pdev->dev;
-
 	return 0;
 
 put_dev:
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
index 7897766c96bb..ae41dd3cd72a 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_comp.h
@@ -26,14 +26,12 @@ enum mtk_mdp_comp_type {
  * @node:	list node to track sibing MDP components
  * @dev_node:	component device node
  * @clk:	clocks required for component
- * @larb_dev:	SMI device required for component
  * @type:	component type
  */
 struct mtk_mdp_comp {
 	struct list_head	node;
 	struct device_node	*dev_node;
 	struct clk		*clk[2];
-	struct device		*larb_dev;
 	enum mtk_mdp_comp_type	type;
 };
 
diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
index 976aa1f4829b..70a8eab16863 100644
--- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
+++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c
@@ -17,7 +17,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/workqueue.h>
-#include <soc/mediatek/smi.h>
 
 #include "mtk_mdp_core.h"
 #include "mtk_mdp_m2m.h"
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:08 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:08 +0800
Subject: [PATCH v10 11/13] memory: mtk-smi: Get rid of mtk_smi_larb_get/put
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-12-yong.wu@mediatek.com>

After adding device_link between the iommu consumer and smi-larb,
the pm_runtime_get(_sync) of smi-larb and smi-common will be called
automatically. we can get rid of mtk_smi_larb_get/put.

CC: Matthias Brugger <matthias.bgg at gmail.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Acked-by: Matthias Brugger <matthias.bgg at gmail.com>
Reviewed-by: Dafna Hirschfeld <dafna.hirschfeld at collabora.com>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/memory/mtk-smi.c   | 14 --------------
 include/soc/mediatek/smi.h | 20 --------------------
 2 files changed, 34 deletions(-)

diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index b883dcc0bbfa..1b348bb93f0b 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -149,20 +149,6 @@ struct mtk_smi_larb { /* larb: local arbiter */
 	unsigned char			*bank;
 };
 
-int mtk_smi_larb_get(struct device *larbdev)
-{
-	int ret = pm_runtime_resume_and_get(larbdev);
-
-	return (ret < 0) ? ret : 0;
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
-
-void mtk_smi_larb_put(struct device *larbdev)
-{
-	pm_runtime_put_sync(larbdev);
-}
-EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
-
 static int
 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
 {
diff --git a/include/soc/mediatek/smi.h b/include/soc/mediatek/smi.h
index 15e3397cec58..11f7d6b59642 100644
--- a/include/soc/mediatek/smi.h
+++ b/include/soc/mediatek/smi.h
@@ -19,26 +19,6 @@ struct mtk_smi_larb_iommu {
 	unsigned char  bank[32];
 };
 
-/*
- * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter.
- *                   It also initialize some basic setting(like iommu).
- * mtk_smi_larb_put: Disable the power domain and clocks for this local arbiter.
- * Both should be called in non-atomic context.
- *
- * Returns 0 if successful, negative on failure.
- */
-int mtk_smi_larb_get(struct device *larbdev);
-void mtk_smi_larb_put(struct device *larbdev);
-
-#else
-
-static inline int mtk_smi_larb_get(struct device *larbdev)
-{
-	return 0;
-}
-
-static inline void mtk_smi_larb_put(struct device *larbdev) { }
-
 #endif
 
 #endif
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:09 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:09 +0800
Subject: [PATCH v10 12/13] arm: dts: mediatek: Get rid of mediatek,
 larb for MM nodes
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-13-yong.wu@mediatek.com>

After adding device_link between the IOMMU consumer and smi, the
mediatek,larb is unnecessary now.

CC: Matthias Brugger <matthias.bgg at gmail.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
---
 arch/arm/boot/dts/mt2701.dtsi  | 2 --
 arch/arm/boot/dts/mt7623n.dtsi | 5 -----
 2 files changed, 7 deletions(-)

diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 4776f85d6d5b..ef583cfd3baf 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -564,7 +564,6 @@
 		clock-names = "jpgdec-smi",
 			      "jpgdec";
 		power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
-		mediatek,larb = <&larb2>;
 		iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
 			 <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
 	};
@@ -577,7 +576,6 @@
 		clocks =  <&imgsys CLK_IMG_VENC>;
 		clock-names = "jpgenc";
 		power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
-		mediatek,larb = <&larb2>;
 		iommus = <&iommu MT2701_M4U_PORT_JPGENC_RDMA>,
 			 <&iommu MT2701_M4U_PORT_JPGENC_BSDMA>;
 	};
diff --git a/arch/arm/boot/dts/mt7623n.dtsi b/arch/arm/boot/dts/mt7623n.dtsi
index bcb0846e29fd..3adab5cd1fef 100644
--- a/arch/arm/boot/dts/mt7623n.dtsi
+++ b/arch/arm/boot/dts/mt7623n.dtsi
@@ -121,7 +121,6 @@
 		clock-names = "jpgdec-smi",
 			      "jpgdec";
 		power-domains = <&scpsys MT2701_POWER_DOMAIN_ISP>;
-		mediatek,larb = <&larb2>;
 		iommus = <&iommu MT2701_M4U_PORT_JPGDEC_WDMA>,
 			 <&iommu MT2701_M4U_PORT_JPGDEC_BSDMA>;
 	};
@@ -144,7 +143,6 @@
 		interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&mmsys CLK_MM_DISP_OVL>;
 		iommus = <&iommu MT2701_M4U_PORT_DISP_OVL_0>;
-		mediatek,larb = <&larb0>;
 	};
 
 	rdma0: rdma at 14008000 {
@@ -154,7 +152,6 @@
 		interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&mmsys CLK_MM_DISP_RDMA>;
 		iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA>;
-		mediatek,larb = <&larb0>;
 	};
 
 	wdma at 14009000 {
@@ -164,7 +161,6 @@
 		interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&mmsys CLK_MM_DISP_WDMA>;
 		iommus = <&iommu MT2701_M4U_PORT_DISP_WDMA>;
-		mediatek,larb = <&larb0>;
 	};
 
 	bls: pwm at 1400a000 {
@@ -215,7 +211,6 @@
 		interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_LOW>;
 		clocks = <&mmsys CLK_MM_DISP_RDMA1>;
 		iommus = <&iommu MT2701_M4U_PORT_DISP_RDMA1>;
-		mediatek,larb = <&larb0>;
 	};
 
 	dpi0: dpi at 14014000 {
-- 
2.18.0



From axe.yang at mediatek.com  Sun Jan 16 23:12:18 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 15:12:18 +0800
Subject: [PATCH v3 1/3] dt-bindings: mmc: add cap-sdio-async-irq flag
In-Reply-To: <20220117071220.17330-1-axe.yang@mediatek.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
Message-ID: <20220117071220.17330-2-axe.yang@mediatek.com>

Asynchronous interrupt is a mechanism that allow SDIO devices alarm
interrupt when host stop providing clock to card. Add a DT flag to
enable this feature if it is supported by SDIO card.

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index 513f3c8758aa..16fb06f88471 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -165,6 +165,11 @@ properties:
     description:
       eMMC hardware reset is supported
 
+  cap-sdio-async-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO async interrupt is supported.
+
   cap-sdio-irq:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.25.1



From yong.wu at mediatek.com  Sun Jan 16 23:05:10 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:10 +0800
Subject: [PATCH v10 13/13] arm64: dts: mediatek: Get rid of mediatek,
 larb for MM nodes
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-14-yong.wu@mediatek.com>

After adding device_link between the IOMMU consumer and smi,
the mediatek,larb is unnecessary now.

CC: Matthias Brugger <matthias.bgg at gmail.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: Evan Green <evgreen at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8173.dtsi | 16 ----------------
 arch/arm64/boot/dts/mediatek/mt8183.dtsi |  6 ------
 2 files changed, 22 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index dee66e5f054c..417e82891a70 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -1010,7 +1010,6 @@
 				 <&mmsys CLK_MM_MUTEX_32K>;
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
-			mediatek,larb = <&larb0>;
 			mediatek,vpu = <&vpu>;
 		};
 
@@ -1021,7 +1020,6 @@
 				 <&mmsys CLK_MM_MUTEX_32K>;
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_RDMA1>;
-			mediatek,larb = <&larb4>;
 		};
 
 		mdp_rsz0: rsz at 14003000 {
@@ -1051,7 +1049,6 @@
 			clocks = <&mmsys CLK_MM_MDP_WDMA>;
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_WDMA>;
-			mediatek,larb = <&larb0>;
 		};
 
 		mdp_wrot0: wrot at 14007000 {
@@ -1060,7 +1057,6 @@
 			clocks = <&mmsys CLK_MM_MDP_WROT0>;
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_WROT0>;
-			mediatek,larb = <&larb0>;
 		};
 
 		mdp_wrot1: wrot at 14008000 {
@@ -1069,7 +1065,6 @@
 			clocks = <&mmsys CLK_MM_MDP_WROT1>;
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			iommus = <&iommu M4U_PORT_MDP_WROT1>;
-			mediatek,larb = <&larb4>;
 		};
 
 		ovl0: ovl at 1400c000 {
@@ -1079,7 +1074,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_OVL0>;
 			iommus = <&iommu M4U_PORT_DISP_OVL0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
 		};
 
@@ -1090,7 +1084,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_OVL1>;
 			iommus = <&iommu M4U_PORT_DISP_OVL1>;
-			mediatek,larb = <&larb4>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
 		};
 
@@ -1101,7 +1094,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_RDMA0>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
 		};
 
@@ -1112,7 +1104,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_RDMA1>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-			mediatek,larb = <&larb4>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
 		};
 
@@ -1123,7 +1114,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_RDMA2>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-			mediatek,larb = <&larb4>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0 0x1000>;
 		};
 
@@ -1134,7 +1124,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_WDMA0>;
 			iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
 		};
 
@@ -1145,7 +1134,6 @@
 			power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
 			clocks = <&mmsys CLK_MM_DISP_WDMA1>;
 			iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-			mediatek,larb = <&larb4>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
 		};
 
@@ -1397,7 +1385,6 @@
 			      <0 0x16027800 0 0x800>,	/* VDEC_HWB */
 			      <0 0x16028400 0 0x400>;	/* VDEC_HWG */
 			interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_LOW>;
-			mediatek,larb = <&larb1>;
 			iommus = <&iommu M4U_PORT_HW_VDEC_MC_EXT>,
 				 <&iommu M4U_PORT_HW_VDEC_PP_EXT>,
 				 <&iommu M4U_PORT_HW_VDEC_AVC_MV_EXT>,
@@ -1465,7 +1452,6 @@
 			compatible = "mediatek,mt8173-vcodec-enc";
 			reg = <0 0x18002000 0 0x1000>;	/* VENC_SYS */
 			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
-			mediatek,larb = <&larb3>;
 			iommus = <&iommu M4U_PORT_VENC_RCPU>,
 				 <&iommu M4U_PORT_VENC_REC>,
 				 <&iommu M4U_PORT_VENC_BSDMA>,
@@ -1493,7 +1479,6 @@
 			clock-names = "jpgdec-smi",
 				      "jpgdec";
 			power-domains = <&spm MT8173_POWER_DOMAIN_VENC>;
-			mediatek,larb = <&larb3>;
 			iommus = <&iommu M4U_PORT_JPGDEC_WDMA>,
 				 <&iommu M4U_PORT_JPGDEC_BSDMA>;
 		};
@@ -1527,7 +1512,6 @@
 				 <&iommu M4U_PORT_VENC_CUR_CHROMA_SET2>,
 				 <&iommu M4U_PORT_VENC_REF_LUMA_SET2>,
 				 <&iommu M4U_PORT_VENC_REC_CHROMA_SET2>;
-			mediatek,larb = <&larb5>;
 			mediatek,vpu = <&vpu>;
 			clocks = <&topckgen CLK_TOP_VENC_LT_SEL>;
 			clock-names = "venc_lt_sel";
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index ac6b0c12d3b3..452102c4904a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1332,7 +1332,6 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			clocks = <&mmsys CLK_MM_DISP_OVL0>;
 			iommus = <&iommu M4U_PORT_DISP_OVL0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x8000 0x1000>;
 		};
 
@@ -1343,7 +1342,6 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
 			iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
 		};
 
@@ -1354,7 +1352,6 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			clocks = <&mmsys CLK_MM_DISP_OVL1_2L>;
 			iommus = <&iommu M4U_PORT_DISP_2L_OVL1_LARB0>;
-			mediatek,larb = <&larb0>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xa000 0x1000>;
 		};
 
@@ -1365,7 +1362,6 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			clocks = <&mmsys CLK_MM_DISP_RDMA0>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-			mediatek,larb = <&larb0>;
 			mediatek,rdma-fifo-size = <5120>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xb000 0x1000>;
 		};
@@ -1377,7 +1373,6 @@
 			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
 			clocks = <&mmsys CLK_MM_DISP_RDMA1>;
 			iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-			mediatek,larb = <&larb0>;
 			mediatek,rdma-fifo-size = <2048>;
 			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
 		};
@@ -1534,7 +1529,6 @@
 			compatible = "mediatek,mt8183-jpgenc", "mediatek,mtk-jpgenc";
 			reg = <0 0x17030000 0 0x1000>;
 			interrupts = <GIC_SPI 249 IRQ_TYPE_LEVEL_LOW>;
-			mediatek,larb = <&larb4>;
 			iommus = <&iommu M4U_PORT_JPGENC_RDMA>,
 				 <&iommu M4U_PORT_JPGENC_BSDMA>;
 			power-domains = <&spm MT8183_POWER_DOMAIN_VENC>;
-- 
2.18.0



From biao.huang at mediatek.com  Sun Jan 16 23:07:02 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:02 +0800
Subject: [PATCH net-next v12 3/7] stmmac: dwmac-mediatek: re-arrange clock
 setting
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-4-biao.huang@mediatek.com>

The rmii_internal clock is needed only when PHY
interface is RMII, and reference clock is from MAC.

Re-arrange the clock setting as following:
1. the optional "rmii_internal" is controlled by devm_clk_get(),
2. other clocks still be configured by devm_clk_bulk_get().

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 72 +++++++++++++------
 1 file changed, 49 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 8747aa4403e8..2678d2deb26a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -49,14 +49,15 @@ struct mac_delay_struct {
 struct mediatek_dwmac_plat_data {
 	const struct mediatek_dwmac_variant *variant;
 	struct mac_delay_struct mac_delay;
+	struct clk *rmii_internal_clk;
 	struct clk_bulk_data *clks;
-	struct device_node *np;
 	struct regmap *peri_regmap;
+	struct device_node *np;
 	struct device *dev;
 	phy_interface_t phy_mode;
-	int num_clks_to_config;
 	bool rmii_clk_from_mac;
 	bool rmii_rxc;
+	int num_clks;
 };
 
 struct mediatek_dwmac_variant {
@@ -74,7 +75,7 @@ struct mediatek_dwmac_variant {
 
 /* list of clocks required for mac */
 static const char * const mt2712_dwmac_clk_l[] = {
-	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal"
+	"axi", "apb", "mac_main", "ptp_ref"
 };
 
 static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
@@ -83,23 +84,12 @@ static int mt2712_set_interface(struct mediatek_dwmac_plat_data *plat)
 	int rmii_rxc = plat->rmii_rxc ? RMII_CLK_SRC_RXC : 0;
 	u32 intf_val = 0;
 
-	/* The clock labeled as "rmii_internal" in mt2712_dwmac_clk_l is needed
-	 * only in RMII(when MAC provides the reference clock), and useless for
-	 * RGMII/MII/RMII(when PHY provides the reference clock).
-	 * num_clks_to_config indicates the real number of clocks should be
-	 * configured, equals to (plat->variant->num_clks - 1) in default for all the case,
-	 * then +1 for rmii_clk_from_mac case.
-	 */
-	plat->num_clks_to_config = plat->variant->num_clks - 1;
-
 	/* select phy interface in top control domain */
 	switch (plat->phy_mode) {
 	case PHY_INTERFACE_MODE_MII:
 		intf_val |= PHY_INTF_MII;
 		break;
 	case PHY_INTERFACE_MODE_RMII:
-		if (plat->rmii_clk_from_mac)
-			plat->num_clks_to_config++;
 		intf_val |= (PHY_INTF_RMII | rmii_rxc | rmii_clk_from_mac);
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
@@ -314,18 +304,36 @@ static int mediatek_dwmac_config_dt(struct mediatek_dwmac_plat_data *plat)
 static int mediatek_dwmac_clk_init(struct mediatek_dwmac_plat_data *plat)
 {
 	const struct mediatek_dwmac_variant *variant = plat->variant;
-	int i, num = variant->num_clks;
+	int i, ret;
+
+	plat->num_clks = variant->num_clks;
 
-	plat->clks = devm_kcalloc(plat->dev, num, sizeof(*plat->clks), GFP_KERNEL);
+	plat->clks = devm_kcalloc(plat->dev, plat->num_clks, sizeof(*plat->clks), GFP_KERNEL);
 	if (!plat->clks)
 		return -ENOMEM;
 
-	for (i = 0; i < num; i++)
+	for (i = 0; i < plat->num_clks; i++)
 		plat->clks[i].id = variant->clk_list[i];
 
-	plat->num_clks_to_config = variant->num_clks;
+	ret = devm_clk_bulk_get(plat->dev, plat->num_clks, plat->clks);
+	if (ret)
+		return ret;
+
+	/* The clock labeled as "rmii_internal" is needed only in RMII(when
+	 * MAC provides the reference clock), and useless for RGMII/MII or
+	 * RMII(when PHY provides the reference clock).
+	 * So, "rmii_internal" clock is got and configured only when
+	 * reference clock of RMII is from MAC.
+	 */
+	if (plat->rmii_clk_from_mac) {
+		plat->rmii_internal_clk = devm_clk_get(plat->dev, "rmii_internal");
+		if (IS_ERR(plat->rmii_internal_clk))
+			ret = PTR_ERR(plat->rmii_internal_clk);
+	} else {
+		plat->rmii_internal_clk = NULL;
+	}
 
-	return devm_clk_bulk_get(plat->dev, num, plat->clks);
+	return ret;
 }
 
 static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
@@ -350,20 +358,31 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
 		}
 	}
 
-	ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
+	ret = clk_bulk_prepare_enable(plat->num_clks, plat->clks);
 	if (ret) {
 		dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
 		return ret;
 	}
 
+	ret = clk_prepare_enable(plat->rmii_internal_clk);
+	if (ret) {
+		dev_err(plat->dev, "failed to enable rmii internal clk, err = %d\n", ret);
+		goto err_clk;
+	}
+
 	return 0;
+
+err_clk:
+	clk_bulk_disable_unprepare(plat->num_clks, plat->clks);
+	return ret;
 }
 
 static void mediatek_dwmac_exit(struct platform_device *pdev, void *priv)
 {
 	struct mediatek_dwmac_plat_data *plat = priv;
 
-	clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
+	clk_disable_unprepare(plat->rmii_internal_clk);
+	clk_bulk_disable_unprepare(plat->num_clks, plat->clks);
 }
 
 static int mediatek_dwmac_clks_config(void *priv, bool enabled)
@@ -372,13 +391,20 @@ static int mediatek_dwmac_clks_config(void *priv, bool enabled)
 	int ret = 0;
 
 	if (enabled) {
-		ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
+		ret = clk_bulk_prepare_enable(plat->num_clks, plat->clks);
 		if (ret) {
 			dev_err(plat->dev, "failed to enable clks, err = %d\n", ret);
 			return ret;
 		}
+
+		ret = clk_prepare_enable(plat->rmii_internal_clk);
+		if (ret) {
+			dev_err(plat->dev, "failed to enable rmii internal clk, err = %d\n", ret);
+			return ret;
+		}
 	} else {
-		clk_bulk_disable_unprepare(plat->num_clks_to_config, plat->clks);
+		clk_disable_unprepare(plat->rmii_internal_clk);
+		clk_bulk_disable_unprepare(plat->num_clks, plat->clks);
 	}
 
 	return ret;
-- 
2.25.1



From biao.huang at mediatek.com  Sun Jan 16 23:07:03 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:03 +0800
Subject: [PATCH net-next v12 4/7] arm64: dts: mt2712: update ethernet device
 node
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-5-biao.huang@mediatek.com>

Since there are some changes in ethernet driver:
update ethernet device node in dts to accommodate to it.

1. stmmac_probe_config_dt() in stmmac_platform.c will initialize specified
   parameters according to compatible string "snps,dwmac-4.20a", then,
   dwmac-mediatek.c can skip the initialization if add compatible string
   "snps,dwmac-4.20a" in eth device node.
2. commit 882007ed7832 ("net-next: dt-binding: dwmac-mediatek: add more
   description for RMII") added rmii internal support, we should add
   corresponding clocks/clocks-names in eth device node.
3. add "snps,reset-delays-us = <0 10000 10000>;" to ensure reset delay
   can meet PHY requirement.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt2712-evb.dts |  1 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi   | 14 +++++++++-----
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
index 7d369fdd3117..11aa135aa0f3 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -110,6 +110,7 @@ &eth {
 	phy-handle = <&ethernet_phy0>;
 	mediatek,tx-delay-ps = <1530>;
 	snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+	snps,reset-delays-us = <0 10000 10000>;
 	pinctrl-names = "default", "sleep";
 	pinctrl-0 = <&eth_default>;
 	pinctrl-1 = <&eth_sleep>;
diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index a9cca9c146fd..9e850e04fffb 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -726,7 +726,7 @@ queue2 {
 	};
 
 	eth: ethernet at 1101c000 {
-		compatible = "mediatek,mt2712-gmac";
+		compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
 		reg = <0 0x1101c000 0 0x1300>;
 		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
 		interrupt-names = "macirq";
@@ -734,15 +734,19 @@ eth: ethernet at 1101c000 {
 		clock-names = "axi",
 			      "apb",
 			      "mac_main",
-			      "ptp_ref";
+			      "ptp_ref",
+			      "rmii_internal";
 		clocks = <&pericfg CLK_PERI_GMAC>,
 			 <&pericfg CLK_PERI_GMAC_PCLK>,
 			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_SEL>;
+			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
+			 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
 		assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_SEL>;
+				  <&topckgen CLK_TOP_ETHER_50M_SEL>,
+				  <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
 		assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
-					 <&topckgen CLK_TOP_APLL1_D3>;
+					 <&topckgen CLK_TOP_APLL1_D3>,
+					 <&topckgen CLK_TOP_ETHERPLL_50M>;
 		power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
 		mediatek,pericfg = <&pericfg>;
 		snps,axi-config = <&stmmac_axi_setup>;
-- 
2.25.1



From biao.huang at mediatek.com  Sun Jan 16 23:07:01 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:01 +0800
Subject: [PATCH net-next v12 2/7] stmmac: dwmac-mediatek: Reuse more common
 features
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-3-biao.huang@mediatek.com>

This patch makes dwmac-mediatek reuse more features
supported by stmmac_platform.c.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 32 +++++++++----------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
index 0ff57c268dca..8747aa4403e8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -334,22 +334,20 @@ static int mediatek_dwmac_init(struct platform_device *pdev, void *priv)
 	const struct mediatek_dwmac_variant *variant = plat->variant;
 	int ret;
 
-	ret = dma_set_mask_and_coherent(plat->dev, DMA_BIT_MASK(variant->dma_bit_mask));
-	if (ret) {
-		dev_err(plat->dev, "No suitable DMA available, err = %d\n", ret);
-		return ret;
-	}
-
-	ret = variant->dwmac_set_phy_interface(plat);
-	if (ret) {
-		dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
-		return ret;
+	if (variant->dwmac_set_phy_interface) {
+		ret = variant->dwmac_set_phy_interface(plat);
+		if (ret) {
+			dev_err(plat->dev, "failed to set phy interface, err = %d\n", ret);
+			return ret;
+		}
 	}
 
-	ret = variant->dwmac_set_delay(plat);
-	if (ret) {
-		dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
-		return ret;
+	if (variant->dwmac_set_delay) {
+		ret = variant->dwmac_set_delay(plat);
+		if (ret) {
+			dev_err(plat->dev, "failed to set delay value, err = %d\n", ret);
+			return ret;
+		}
 	}
 
 	ret = clk_bulk_prepare_enable(plat->num_clks_to_config, plat->clks);
@@ -422,15 +420,15 @@ static int mediatek_dwmac_probe(struct platform_device *pdev)
 		return PTR_ERR(plat_dat);
 
 	plat_dat->interface = priv_plat->phy_mode;
-	plat_dat->has_gmac4 = 1;
-	plat_dat->has_gmac = 0;
-	plat_dat->pmt = 0;
+	plat_dat->use_phy_wol = 1;
 	plat_dat->riwt_off = 1;
 	plat_dat->maxmtu = ETH_DATA_LEN;
+	plat_dat->addr64 = priv_plat->variant->dma_bit_mask;
 	plat_dat->bsp_priv = priv_plat;
 	plat_dat->init = mediatek_dwmac_init;
 	plat_dat->exit = mediatek_dwmac_exit;
 	plat_dat->clks_config = mediatek_dwmac_clks_config;
+
 	mediatek_dwmac_init(pdev, priv_plat);
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-- 
2.25.1



From yong.wu at mediatek.com  Sun Jan 16 23:05:05 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:05 +0800
Subject: [PATCH v10 08/13] drm/mediatek: Add pm runtime support for ovl and
 rdma
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-9-yong.wu@mediatek.com>

From: Yongqiang Niu <yongqiang.niu at mediatek.com>

Prepare for smi cleaning up "mediatek,larb".

Display use the dispsys device to call pm_rumtime_get_sync before.
This patch add pm_runtime_xx with ovl and rdma device whose nodes has
"iommus" property, then display could help pm_runtime_get for smi via
ovl or rdma device.

CC: CK Hu <ck.hu at mediatek.com>
Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
(Yong: Use pm_runtime_resume_and_get instead of pm_runtime_get_sync)
Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c  |  8 +++++++-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  9 ++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c  | 13 ++++++++++++-
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
index 5326989d5206..716eac6831f2 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -11,6 +11,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
@@ -414,9 +415,13 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	pm_runtime_enable(dev);
+
 	ret = component_add(dev, &mtk_disp_ovl_component_ops);
-	if (ret)
+	if (ret) {
+		pm_runtime_disable(dev);
 		dev_err(dev, "Failed to add component: %d\n", ret);
+	}
 
 	return ret;
 }
@@ -424,6 +429,7 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
 static int mtk_disp_ovl_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
+	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index 75d7f45579e2..251f034acb09 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -9,6 +9,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 
 #include "mtk_disp_drv.h"
@@ -327,9 +328,13 @@ static int mtk_disp_rdma_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
+	pm_runtime_enable(dev);
+
 	ret = component_add(dev, &mtk_disp_rdma_component_ops);
-	if (ret)
+	if (ret) {
+		pm_runtime_disable(dev);
 		dev_err(dev, "Failed to add component: %d\n", ret);
+	}
 
 	return ret;
 }
@@ -338,6 +343,8 @@ static int mtk_disp_rdma_remove(struct platform_device *pdev)
 {
 	component_del(&pdev->dev, &mtk_disp_rdma_component_ops);
 
+	pm_runtime_disable(&pdev->dev);
+
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index a4e80e499674..ce5bbd6918cf 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -554,9 +554,17 @@ static void mtk_drm_crtc_atomic_enable(struct drm_crtc *crtc,
 		return;
 	}
 
+	ret = pm_runtime_resume_and_get(comp->dev);
+	if (ret < 0) {
+		mtk_smi_larb_put(comp->larb_dev);
+		DRM_DEV_ERROR(comp->dev, "Failed to enable power domain: %d\n", ret);
+		return;
+	}
+
 	ret = mtk_crtc_ddp_hw_init(mtk_crtc);
 	if (ret) {
 		mtk_smi_larb_put(comp->larb_dev);
+		pm_runtime_put(comp->dev);
 		return;
 	}
 
@@ -569,7 +577,7 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 {
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
-	int i;
+	int i, ret;
 
 	DRM_DEBUG_DRIVER("%s %d\n", __func__, crtc->base.id);
 	if (!mtk_crtc->enabled)
@@ -593,6 +601,9 @@ static void mtk_drm_crtc_atomic_disable(struct drm_crtc *crtc,
 	drm_crtc_vblank_off(crtc);
 	mtk_crtc_ddp_hw_fini(mtk_crtc);
 	mtk_smi_larb_put(comp->larb_dev);
+	ret = pm_runtime_put(comp->dev);
+	if (ret < 0)
+		DRM_DEV_ERROR(comp->dev, "Failed to disable power domain: %d\n", ret);
 
 	mtk_crtc->enabled = false;
 }
-- 
2.18.0



From yong.wu at mediatek.com  Sun Jan 16 23:05:01 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 15:05:01 +0800
Subject: [PATCH v10 04/13] iommu/mediatek: Add probe_defer for smi-larb
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <20220117070510.17642-5-yong.wu@mediatek.com>

Prepare for adding device_link.

The iommu consumer should use device_link to connect with the
smi-larb(supplier). then the smi-larb should run before the iommu
consumer. Here we delay the iommu driver until the smi driver is ready,
then all the iommu consumers always are after the smi driver.

When there is no this patch, if some consumer drivers run before
smi-larb, the supplier link_status is DL_DEV_NO_DRIVER(0) in the
device_link_add, then device_links_driver_bound will use WARN_ON
to complain that the link_status of supplier is not right.

device_is_bound may be more elegant here. but it is not allowed to
EXPORT from https://lore.kernel.org/patchwork/patch/1334670/.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
Acked-by: Joerg Roedel <jroedel at suse.de>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c    | 4 ++++
 drivers/iommu/mtk_iommu_v1.c | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 77ae20ff9b35..5cff5bc556d4 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -850,6 +850,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			of_node_put(larbnode);
 			return -ENODEV;
 		}
+		if (!plarbdev->dev.driver) {
+			of_node_put(larbnode);
+			return -EPROBE_DEFER;
+		}
 		data->larb_imu[id].dev = &plarbdev->dev;
 
 		component_match_add_release(dev, &match, release_of,
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 68bf02f87cfd..4089077256f4 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -606,6 +606,10 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			of_node_put(larbnode);
 			return -ENODEV;
 		}
+		if (!plarbdev->dev.driver) {
+			of_node_put(larbnode);
+			return -EPROBE_DEFER;
+		}
 		data->larb_imu[i].dev = &plarbdev->dev;
 
 		component_match_add_release(dev, &match, release_of,
-- 
2.18.0



From axe.yang at mediatek.com  Sun Jan 16 23:12:20 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 15:12:20 +0800
Subject: [PATCH 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220117071220.17330-1-axe.yang@mediatek.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
Message-ID: <20220117071220.17330-4-axe.yang@mediatek.com>

Add support for eint IRQ when MSDC is used as an SDIO host. This
feature requires SDIO device support async IRQ function. With this
feature, SDIO host can be awakened by SDIO card in suspend state,
without additional pin.

MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
resume, switch GPIO function back to DAT1 mode then turn on clock.

Some device tree property should be added or modified in MSDC node
to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
are mandatory. And cap-sdio-async-irq flag is necessary since this
feature depends on asynchronous interrupt:
        &mmcX {
                ...
                pinctrl-names = "default", "state_uhs", "state_eint",
                                "state_dat1";
                ...
                pinctrl-2 = <&mmc2_pins_eint>;
                pinctrl-3 = <&mmc2_pins_dat1>;
                ...
                cap-sdio-async-irq;
                ...
        };

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
Signed-off-by: Yong Mao <yong.mao at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 125 +++++++++++++++++++++++++++++++++++---
 1 file changed, 117 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 65037e1d7723..cbdbcce99fd9 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2015 MediaTek Inc.
+ * Copyright (c) 2022 MediaTek Inc.
  * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
  */
 
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -440,8 +441,12 @@ struct msdc_host {
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
+	struct pinctrl_state *pins_eint;
+	struct pinctrl_state *pins_dat1;
 	struct delayed_work req_timeout;
 	int irq;		/* host interrupt */
+	int eint_irq;		/* device interrupt */
+	int sdio_irq_cnt;	/* irq enable cnt */
 	struct reset_control *reset;
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -465,6 +470,7 @@ struct msdc_host {
 	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
+	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 	struct msdc_tune_para def_tune_para; /* default tune setting */
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
@@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	__msdc_enable_sdio_irq(host, enb);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (enb)
-		pm_runtime_get_noresume(host->dev);
-	else
-		pm_runtime_put_noidle(host->dev);
+	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
+		if (enb)
+			pm_runtime_get_noresume(host->dev);
+		else
+			pm_runtime_put_noidle(host->dev);
+	}
 }
 
 static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
@@ -2461,6 +2469,50 @@ static const struct mmc_host_ops mt_msdc_ops = {
 	.hw_reset = msdc_hw_reset,
 };
 
+static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
+{
+	struct msdc_host *host = dev_id;
+	struct mmc_host *mmc = mmc_from_priv(host);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (likely(host->sdio_irq_cnt > 0)) {
+		disable_irq_nosync(host->eint_irq);
+		disable_irq_wake(host->eint_irq);
+		host->sdio_irq_cnt--;
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	sdio_signal_irq(mmc);
+
+	return IRQ_HANDLED;
+}
+
+static int msdc_request_dat1_eint_irq(struct msdc_host *host)
+{
+	struct gpio_desc *desc;
+	int irq, ret;
+
+	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	ret = gpiod_to_irq(desc);
+	if (ret < 0)
+		return ret;
+
+	irq = ret;
+	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					"sdio-eint", host);
+	if (ret)
+		return ret;
+
+	host->eint_irq = irq;
+
+	return 0;
+}
+
 static const struct cqhci_host_ops msdc_cmdq_ops = {
 	.enable         = msdc_cqe_enable,
 	.disable        = msdc_cqe_disable,
@@ -2631,6 +2683,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO)) {
+		/* Support for SDIO eint irq */
+		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+		if (IS_ERR(host->pins_eint)) {
+			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
+		} else {
+			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
+			if (IS_ERR(host->pins_dat1)) {
+				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
+						    "Cannot find pinctrl dat1!\n");
+				goto host_free;
+			}
+
+			host->sdio_eint_ready = true;
+		}
+	}
+
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
@@ -2722,6 +2791,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto release;
 
+	if (host->sdio_eint_ready) {
+		ret = msdc_request_dat1_eint_irq(host);
+		if (ret) {
+			dev_err(host->dev, "Failed to register data1 eint irq!\n");
+			goto release;
+		}
+
+		pinctrl_select_state(host->pinctrl, host->pins_dat1);
+	}
+
 	pm_runtime_set_active(host->dev);
 	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(host->dev);
@@ -2841,16 +2920,31 @@ static void msdc_restore_reg(struct msdc_host *host)
 
 static int __maybe_unused msdc_runtime_suspend(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 
 	msdc_save_reg(host);
+
+	if (host->sdio_eint_ready) {
+		disable_irq(host->irq);
+		pinctrl_select_state(host->pinctrl, host->pins_eint);
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt == 0) {
+			enable_irq(host->eint_irq);
+			enable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt++;
+		}
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 	msdc_gate_clock(host);
 	return 0;
 }
 
 static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
@@ -2860,10 +2954,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 		return ret;
 
 	msdc_restore_reg(host);
+
+	if (host->sdio_eint_ready) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt > 0) {
+			disable_irq_nosync(host->eint_irq);
+			disable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt--;
+			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		} else {
+			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+		enable_irq(host->irq);
+	}
 	return 0;
 }
 
-static int __maybe_unused msdc_suspend(struct device *dev)
+static int __maybe_unused msdc_suspend_noirq(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret;
@@ -2877,13 +2986,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int __maybe_unused msdc_resume(struct device *dev)
+static int __maybe_unused msdc_resume_noirq(struct device *dev)
 {
 	return pm_runtime_force_resume(dev);
 }
 
 static const struct dev_pm_ops msdc_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-- 
2.25.1



From biao.huang at mediatek.com  Sun Jan 16 23:07:04 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Mon, 17 Jan 2022 15:07:04 +0800
Subject: [PATCH net-next v12 5/7] net: dt-bindings: dwmac: Convert
 mediatek-dwmac to DT schema
In-Reply-To: <20220117070706.17853-1-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
Message-ID: <20220117070706.17853-6-biao.huang@mediatek.com>

Convert mediatek-dwmac to DT schema, and delete old mediatek-dwmac.txt.
And there are some changes in .yaml than .txt, others almost keep the same:
  1. compatible "const: snps,dwmac-4.20".
  2. delete "snps,reset-active-low;" in example, since driver remove this
     property long ago.
  3. add "snps,reset-delay-us = <0 10000 10000>" in example.
  4. the example is for rgmii interface, keep related properties only.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/net/mediatek-dwmac.txt           |  91 ----------
 .../bindings/net/mediatek-dwmac.yaml          | 155 ++++++++++++++++++
 2 files changed, 155 insertions(+), 91 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.txt
 create mode 100644 Documentation/devicetree/bindings/net/mediatek-dwmac.yaml

diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt b/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
deleted file mode 100644
index afbcaebf062e..000000000000
--- a/Documentation/devicetree/bindings/net/mediatek-dwmac.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-MediaTek DWMAC glue layer controller
-
-This file documents platform glue layer for stmmac.
-Please see stmmac.txt for the other unchanged properties.
-
-The device node has following properties.
-
-Required properties:
-- compatible:  Should be "mediatek,mt2712-gmac" for MT2712 SoC
-- reg:  Address and length of the register set for the device
-- interrupts:  Should contain the MAC interrupts
-- interrupt-names: Should contain a list of interrupt names corresponding to
-	the interrupts in the interrupts property, if available.
-	Should be "macirq" for the main MAC IRQ
-- clocks: Must contain a phandle for each entry in clock-names.
-- clock-names: The name of the clock listed in the clocks property. These are
-	"axi", "apb", "mac_main", "ptp_ref", "rmii_internal" for MT2712 SoC.
-- mac-address: See ethernet.txt in the same directory
-- phy-mode: See ethernet.txt in the same directory
-- mediatek,pericfg: A phandle to the syscon node that control ethernet
-	interface and timing delay.
-
-Optional properties:
-- mediatek,tx-delay-ps: TX clock delay macro value. Default is 0.
-	It should be defined for RGMII/MII interface.
-	It should be defined for RMII interface when the reference clock is from MT2712 SoC.
-- mediatek,rx-delay-ps: RX clock delay macro value. Default is 0.
-	It should be defined for RGMII/MII interface.
-	It should be defined for RMII interface.
-Both delay properties need to be a multiple of 170 for RGMII interface,
-or will round down. Range 0~31*170.
-Both delay properties need to be a multiple of 550 for MII/RMII interface,
-or will round down. Range 0~31*550.
-
-- mediatek,rmii-rxc: boolean property, if present indicates that the RMII
-	reference clock, which is from external PHYs, is connected to RXC pin
-	on MT2712 SoC.
-	Otherwise, is connected to TXC pin.
-- mediatek,rmii-clk-from-mac: boolean property, if present indicates that
-	MT2712 SoC provides the RMII reference clock, which outputs to TXC pin only.
-- mediatek,txc-inverse: boolean property, if present indicates that
-	1. tx clock will be inversed in MII/RGMII case,
-	2. tx clock inside MAC will be inversed relative to reference clock
-	   which is from external PHYs in RMII case, and it rarely happen.
-	3. the reference clock, which outputs to TXC pin will be inversed in RMII case
-	   when the reference clock is from MT2712 SoC.
-- mediatek,rxc-inverse: boolean property, if present indicates that
-	1. rx clock will be inversed in MII/RGMII case.
-	2. reference clock will be inversed when arrived at MAC in RMII case, when
-	   the reference clock is from external PHYs.
-	3. the inside clock, which be sent to MAC, will be inversed in RMII case when
-	   the reference clock is from MT2712 SoC.
-- assigned-clocks: mac_main and ptp_ref clocks
-- assigned-clock-parents: parent clocks of the assigned clocks
-
-Example:
-	eth: ethernet at 1101c000 {
-		compatible = "mediatek,mt2712-gmac";
-		reg = <0 0x1101c000 0 0x1300>;
-		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
-		interrupt-names = "macirq";
-		phy-mode ="rgmii-rxid";
-		mac-address = [00 55 7b b5 7d f7];
-		clock-names = "axi",
-			      "apb",
-			      "mac_main",
-			      "ptp_ref",
-			      "rmii_internal";
-		clocks = <&pericfg CLK_PERI_GMAC>,
-			 <&pericfg CLK_PERI_GMAC_PCLK>,
-			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
-			 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
-		assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_SEL>,
-				  <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
-		assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
-					 <&topckgen CLK_TOP_APLL1_D3>,
-					 <&topckgen CLK_TOP_ETHERPLL_50M>;
-		power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
-		mediatek,pericfg = <&pericfg>;
-		mediatek,tx-delay-ps = <1530>;
-		mediatek,rx-delay-ps = <1530>;
-		mediatek,rmii-rxc;
-		mediatek,txc-inverse;
-		mediatek,rxc-inverse;
-		snps,txpbl = <1>;
-		snps,rxpbl = <1>;
-		snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
-		snps,reset-active-low;
-	};
diff --git a/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
new file mode 100644
index 000000000000..8ad6e19661b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/mediatek-dwmac.yaml
@@ -0,0 +1,155 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/mediatek-dwmac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek DWMAC glue layer controller
+
+maintainers:
+  - Biao Huang <biao.huang at mediatek.com>
+
+description:
+  This file documents platform glue layer for stmmac.
+
+# We need a select here so we don't match all nodes with 'snps,dwmac'
+select:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - mediatek,mt2712-gmac
+  required:
+    - compatible
+
+allOf:
+  - $ref: "snps,dwmac.yaml#"
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - mediatek,mt2712-gmac
+      - const: snps,dwmac-4.20a
+
+  clocks:
+    items:
+      - description: AXI clock
+      - description: APB clock
+      - description: MAC Main clock
+      - description: PTP clock
+      - description: RMII reference clock provided by MAC
+
+  clock-names:
+    items:
+      - const: axi
+      - const: apb
+      - const: mac_main
+      - const: ptp_ref
+      - const: rmii_internal
+
+  mediatek,pericfg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      The phandle to the syscon node that control ethernet
+      interface and timing delay.
+
+  mediatek,tx-delay-ps:
+    description:
+      The internal TX clock delay (provided by this driver) in nanoseconds.
+      For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+      or will round down. Range 0~31*170.
+      For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+      or will round down. Range 0~31*550.
+
+  mediatek,rx-delay-ps:
+    description:
+      The internal RX clock delay (provided by this driver) in nanoseconds.
+      For MT2712 RGMII interface, Allowed value need to be a multiple of 170,
+      or will round down. Range 0~31*170.
+      For MT2712 RMII/MII interface, Allowed value need to be a multiple of 550,
+      or will round down. Range 0~31*550.
+
+  mediatek,rmii-rxc:
+    type: boolean
+    description:
+      If present, indicates that the RMII reference clock, which is from external
+      PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+  mediatek,rmii-clk-from-mac:
+    type: boolean
+    description:
+      If present, indicates that MAC provides the RMII reference clock, which
+      outputs to TXC pin only.
+
+  mediatek,txc-inverse:
+    type: boolean
+    description:
+      If present, indicates that
+      1. tx clock will be inversed in MII/RGMII case,
+      2. tx clock inside MAC will be inversed relative to reference clock
+         which is from external PHYs in RMII case, and it rarely happen.
+      3. the reference clock, which outputs to TXC pin will be inversed in RMII case
+         when the reference clock is from MAC.
+
+  mediatek,rxc-inverse:
+    type: boolean
+    description:
+      If present, indicates that
+      1. rx clock will be inversed in MII/RGMII case.
+      2. reference clock will be inversed when arrived at MAC in RMII case, when
+         the reference clock is from external PHYs.
+      3. the inside clock, which be sent to MAC, will be inversed in RMII case when
+         the reference clock is from MAC.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - clocks
+  - clock-names
+  - phy-mode
+  - mediatek,pericfg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2712-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/power/mt2712-power.h>
+
+    eth: ethernet at 1101c000 {
+        compatible = "mediatek,mt2712-gmac", "snps,dwmac-4.20a";
+        reg = <0x1101c000 0x1300>;
+        interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
+        interrupt-names = "macirq";
+        phy-mode ="rgmii-rxid";
+        mac-address = [00 55 7b b5 7d f7];
+        clock-names = "axi",
+                      "apb",
+                      "mac_main",
+                      "ptp_ref",
+                      "rmii_internal";
+        clocks = <&pericfg CLK_PERI_GMAC>,
+                 <&pericfg CLK_PERI_GMAC_PCLK>,
+                 <&topckgen CLK_TOP_ETHER_125M_SEL>,
+                 <&topckgen CLK_TOP_ETHER_50M_SEL>,
+                 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+        assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
+                          <&topckgen CLK_TOP_ETHER_50M_SEL>,
+                          <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
+        assigned-clock-parents = <&topckgen CLK_TOP_ETHERPLL_125M>,
+                                 <&topckgen CLK_TOP_APLL1_D3>,
+                                 <&topckgen CLK_TOP_ETHERPLL_50M>;
+        power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
+        mediatek,pericfg = <&pericfg>;
+        mediatek,tx-delay-ps = <1530>;
+        snps,txpbl = <1>;
+        snps,rxpbl = <1>;
+        snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
+        snps,reset-delays-us = <0 10000 10000>;
+    };
-- 
2.25.1



From jammy_huang at aspeedtech.com  Sun Jan 16 23:18:22 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 17 Jan 2022 15:18:22 +0800
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <CACPK8XeJQHLWfVbBjArxV_QMDDnRXfccOeXdsn6aBEG7gd8yvw@mail.gmail.com>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
 <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
 <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>
 <CACPK8XeJQHLWfVbBjArxV_QMDDnRXfccOeXdsn6aBEG7gd8yvw@mail.gmail.com>
Message-ID: <98096e97-68cc-18fd-d2b6-3477f57f05bd@aspeedtech.com>

On 2022/1/17 ?? 10:24, Joel Stanley wrote:
> On Mon, 17 Jan 2022 at 02:00, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>> Hi Hans,
>>
>> On 2022/1/14 ?? 04:11, Hans Verkuil wrote:
>>> On 24/12/2021 02:27, Jammy Huang wrote:
>>>> This introduces support for the Aspeed JPEG format, where the new frame
>>>> can refer to previous frame to reduce the amount of compressed data. The
>>>> concept is similar to I/P frame of video compression. It will compare the
>>>> new frame with previous one to decide which macroblock's data is
>>>> changed, and only the changed macroblocks will be compressed.
>>>>
>>>> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
>>>> which is generally adapted for remote KVM.
>>>>
>>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>>> ---
>>>> v8:
>>>>     - Add decoder information for aspeed-jpeg
>>>> v7:
>>>>     - Add more information for aspeed-jpeg
>>>> v6:
>>>>     - Update description for new format, aspeed-jpeg, in Documentation.
>>>> v5:
>>>>     - no update
>>>> v4:
>>>>     - new
>>>> ---
>>>>    .../media/uapi/v4l/pixfmt-reserved.rst          | 17 +++++++++++++++++
>>>>    drivers/media/v4l2-core/v4l2-ioctl.c            |  1 +
>>>>    include/uapi/linux/videodev2.h                  |  1 +
>>>>    3 files changed, 19 insertions(+)
>>>>
>>>> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>> This is the wrong file! It should be:
>>>
>>> Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>> Thanks, I just used git format-patch to generate the cover-letter and
>> didn't notice this.
>>
>> It looks like the file, pixfmt-reserved.rst, has different path in
>> different Linux kernel,
>>
>> * 5.4:           Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>
>> * 5.10/5.15: Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>>
>> 5.4 is the one I based to submit the patches.
>>
>> Could you suggest the kernel that I should based to submit these patches??
> You should always submit based on the latest release.
>
> There are sometimes exceptions where you will base your patches on
> something even newer, but generally you should grab the latest.
>
> Be sure to re-test on the latest kernel before submitting.
OK, thank you.
>
> Cheers,
>
> Joel
>
>> I will need to change the number of V4L2_CID_USER_ASPEED_BASE per different
>>
>> linux kernel as well.
>>
>>> Regards,
>>>
>>>        Hans
>>>
>>>> index b2cd155e691b..1d0dc8d86ed7 100644
>>>> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
>>>>       of tiles, resulting in 32-aligned resolutions for the luminance plane
>>>>       and 16-aligned resolutions for the chrominance plane (with 2x2
>>>>       subsampling).
>>>> +    * .. _V4L2-PIX-FMT-AJPG:
>>>> +
>>>> +      - ``V4L2_PIX_FMT_AJPG``
>>>> +      - 'AJPG'
>>>> +      - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
>>>> +        which is generally adapted for remote KVM.
>>>> +        On each frame compression, I will compare the new frame with previous
>>>> +        one to decide which macroblock's data is changed, and only the changed
>>>> +        macroblocks will be compressed.
>>>> +
>>>> +        The implementation is based on AST2600 A3 datasheet, revision 0.9, which
>>>> +        is not publicly available. Or you can reference Video stream data format
>>>> +        ? ASPEED mode compression of SDK_User_Guide which available on
>>>> +        AspeedTech-BMC/openbmc/releases.
>>>> +
>>>> +        Decoder's implementation can be found here,
>>>> +        `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
>>>>
>>>>    .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>>>>
>>>> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>> index 24db33f803c0..00dde01d2f97 100644
>>>> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
>>>> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>>>>               case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
>>>>               case V4L2_PIX_FMT_MT21C:        descr = "Mediatek Compressed Format"; break;
>>>>               case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
>>>> +            case V4L2_PIX_FMT_AJPG:         descr = "Aspeed JPEG"; break;
>>>>               default:
>>>>                       if (fmt->description[0])
>>>>                               return;
>>>> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
>>>> index 3210b3c82a4a..994eb6155ea9 100644
>>>> --- a/include/uapi/linux/videodev2.h
>>>> +++ b/include/uapi/linux/videodev2.h
>>>> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
>>>>    #define V4L2_PIX_FMT_INZI     v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
>>>>    #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
>>>>    #define V4L2_PIX_FMT_CNF4     v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
>>>> +#define V4L2_PIX_FMT_AJPG     v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
>>>>
>>>>    /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
>>>>    #define V4L2_PIX_FMT_IPU3_SBGGR10  v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
>> --
>> Best Regards
>> Jammy
>>
-- 
Best Regards
Jammy



From axe.yang at mediatek.com  Sun Jan 16 23:35:53 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 15:35:53 +0800
Subject: [PATCH v2 3/3] mmc: mediatek: add support for SDIO eint irq
In-Reply-To: <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
References: <20220111014046.5864-1-axe.yang@mediatek.com>
 <20220111014046.5864-4-axe.yang@mediatek.com>
 <Yd1uJ+dX2CTEJfYY@smile.fi.intel.com>
Message-ID: <2205eedc9ecd10f83994138974b261baa0aee55a.camel@mediatek.com>

Andy, patchset v3 is uploaded. I fixed most of the defect you pointed
out.
And in msdc_sdio_eint_irq(), you asked why do we need flags, the flags
is for spin lock irq save/restore, so I keep it.

On Tue, 2022-01-11 at 13:46 +0200, Andy Shevchenko wrote:
> On Tue, Jan 11, 2022 at 09:40:46AM +0800, Axe Yang wrote:
> > Add support for eint irq when MSDC is used as an SDIO host. This
> 
> IRQ
> 
> > feature requires SDIO device support async irq function. With this
> 
> IRQ
> 
> > feature,SDIO host can be awakened by SDIO card in suspend state,
> 
> feature, SDIO
> 
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in msdc node
> 
> MSDC
> 
> > to support SDIO eint irq. Pinctrls named state_dat1 and state_eint
> 
> IRQ
> 
> > are mandatory. And cap-sdio-async-irq flag is necessary since this
> > feature depends on asynchronous interrupt:
> >         &mmcX {
> >                 ...
> >                 pinctrl-names = "default", "state_uhs",
> > "state_eint",
> >                                 "state_dat1";
> >                 ...
> >                 pinctrl-2 = <&mmc2_pins_eint>;
> >                 pinctrl-3 = <&mmc2_pins_dat1>;
> >                 ...
> >                 cap-sdio-async-irq;
> >                 ...
> >         };
> 
> ...
> 
> > - * Copyright (c) 2014-2015 MediaTek Inc.
> > + * Copyright (c) 2014-2022 MediaTek Inc.
> 
> Shouldn't it be rather like
> 
>  * Copyright (c) 2014-2015,2022 MediaTek Inc.
> 
> ?
> 
> ...
> 
> > +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> > +{
> > +	unsigned long flags;
> > +	struct msdc_host *host = (struct msdc_host *)dev_id;
> 
> No casting is needed.
> 
> > +	struct mmc_host *mmc = mmc_from_priv(host);
> 
> Perhaps reversed xmas tree order
> 
> 	struct msdc_host *host = dev_id;
> 	struct mmc_host *mmc = mmc_from_priv(host);
> 	unsigned long flags;
> 
> ?
> 
> But hey, why do you need flags?

falgs is for spin lock irq save/restore. 

> 
> > +	spin_lock_irqsave(&host->lock, flags);
> > +	if (likely(host->sdio_irq_cnt > 0)) {
> > +		disable_irq_nosync(host->eint_irq);
> > +		disable_irq_wake(host->eint_irq);
> > +		host->sdio_irq_cnt--;
> > +	}
> > +	spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +	sdio_signal_irq(mmc);
> > +
> > +	return IRQ_HANDLED;
> > +}
> 
> ...
> 
> > +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> > +{
> > +	struct gpio_desc *desc;
> > +	int irq, ret;
> > +
> > +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> > +	if (IS_ERR(desc))
> > +		return PTR_ERR(desc);
> > +
> > +	ret = gpiod_to_irq(desc);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	irq = ret;
> > +	ret = devm_request_threaded_irq(host->dev, irq, NULL,
> > msdc_sdio_eint_irq,
> > +					IRQF_TRIGGER_LOW | IRQF_ONESHOT
> > | IRQF_NO_AUTOEN,
> > +					"sdio-eint", host);
> > +
> 
> Redundant blank line.
> 
> > +	if (!ret)
> > +		host->eint_irq = irq;
> > +
> > +	return ret;
> 
> I guess I have already commented on this, i.e. use standard pattern
> 
> 	if (ret)
> 		return ret;
> 
> 	...
> 	return 0;
> 
> > +}
> 
> ...
> 
> > +		host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> > "state_eint");
> > +		if (IS_ERR(host->pins_eint)) {
> > +			dev_dbg(&pdev->dev, "Cannot find pinctrl
> > eint!\n");
> 
> In debug mode of pin control this will bring a duplicate message.
> 
> > +		} else {
> > +			host->pins_dat1 = pinctrl_lookup_state(host-
> > >pinctrl, "state_dat1");
> > +			if (IS_ERR(host->pins_dat1)) {
> > +				ret = dev_err_probe(&pdev->dev,
> > PTR_ERR(host->pins_dat1),
> > +						    "Cannot find
> > pinctrl dat1!\n");
> > +				goto host_free;
> > +			}
> > +
> > +			host->sdio_eint_ready = true;
> > +		}
> > +	}
> 
> 

From patrice.chotard at foss.st.com  Sun Jan 16 23:37:45 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 17 Jan 2022 08:37:45 +0100
Subject: [PATCH v2] spi: stm32-qspi: Update spi registering
In-Reply-To: <20220116125205.GA18267@wunner.de>
References: <20220112144424.5278-1-patrice.chotard@foss.st.com>
 <20220116125205.GA18267@wunner.de>
Message-ID: <b07ba47f-2709-6b10-2332-7a0d163401bc@foss.st.com>

Hi Lukas

On 1/16/22 1:52 PM, Lukas Wunner wrote:
> On Wed, Jan 12, 2022 at 03:44:24PM +0100, patrice.chotard at foss.st.com wrote:
>> diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
>> index 514337c86d2c..09839a3dbb26 100644
>> --- a/drivers/spi/spi-stm32-qspi.c
>> +++ b/drivers/spi/spi-stm32-qspi.c
>> @@ -688,7 +688,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
>>  	struct resource *res;
>>  	int ret, irq;
>>  
>> -	ctrl = spi_alloc_master(dev, sizeof(*qspi));
>> +	ctrl = devm_spi_alloc_master(dev, sizeof(*qspi));
>>  	if (!ctrl)
>>  		return -ENOMEM;
>>  
>> @@ -784,7 +784,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
>>  	pm_runtime_enable(dev);
>>  	pm_runtime_get_noresume(dev);
>>  
>> -	ret = devm_spi_register_master(dev, ctrl);
>> +	ret = spi_register_master(ctrl);
>>  	if (ret)
>>  		goto err_pm_runtime_free;
>>
> 
> Unfortunately this patch is still not correct:  It introduces a
> double free in the probe error path.

Argh yes, my bad.

> 
> You need to remove this...
> 
> err_master_put:
> 	spi_master_put(qspi->ctrl);
> 
> ...and replace all the gotos in stm32_qspi_probe() which jump
> to the err_master_put label with a return statement.
> 
> Thanks,
> 
> Lukas
> 
Thanks 
Patrice


From wenst at chromium.org  Sun Jan 16 23:44:37 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 17 Jan 2022 15:44:37 +0800
Subject: [PATCH v2 1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to
 SPDIF output
In-Reply-To: <20220114150129.v2.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>
Message-ID: <CAGXv+5H0-dM28YQj_orS1_14NLcJve8VtO6oLcBiRpJFjaf5KA@mail.gmail.com>

On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
>
> Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> switched the platform to SPDIF, but we didn't fix up the device tree.
>
> Drop the pinctrl settings, because the 'spdif_bus' pins are either:
>  * unused (on kevin, bob), so the settings is ~harmless
>  * used by a different function (on scarlet), which causes probe
>    failures (!!)

I suppose that means the default pinctrl should be dropped? Or maybe this
use case is the outlier. Up to Heiko?

> Fixes: b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> Signed-off-by: Brian Norris <briannorris at chromium.org>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From wenst at chromium.org  Sun Jan 16 23:45:09 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 17 Jan 2022 15:45:09 +0800
Subject: [PATCH v2 2/3] drm/rockchip: cdn-dp: Support HDMI codec
 plug-change callback
In-Reply-To: <20220114150129.v2.2.I20d754a1228aa5c51a18c8eb15a2c60dec25b639@changeid>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.2.I20d754a1228aa5c51a18c8eb15a2c60dec25b639@changeid>
Message-ID: <CAGXv+5Gm4ru8m5bZV_zm10U+FQRBSw7qq1eiL+hh+Z=5pZ7pYQ@mail.gmail.com>

On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
>
> Some audio servers like to monitor a jack device (perhaps combined with
> EDID, for audio-presence info) to determine DP/HDMI audio presence.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


From krzysztof.kozlowski at canonical.com  Sun Jan 16 23:45:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 08:45:35 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <CACRpkdbhmJ91EW395C5F2WYjWJQdJ-SBHaDm7XnQsxMuyoMmLg@mail.gmail.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
 <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
 <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>
 <CACRpkdbhmJ91EW395C5F2WYjWJQdJ-SBHaDm7XnQsxMuyoMmLg@mail.gmail.com>
Message-ID: <77bd8fa4-2b35-352c-da07-ef91fcbed454@canonical.com>

On 16/01/2022 22:38, Linus Walleij wrote:
> On Sun, Jan 16, 2022 at 6:10 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
> 
>> Anyway DTS and dtschema will have to wait for one release, because they
>> depend on samsung pinctrl driver change (patch #2).
> 
> What about I put that (and maybe this schema) on an immutable
> branch so you can pull the commit into your for-arm-soc branch and
> put the DTS changes on top?

That would be a solution if not a policy for arm-soc of keeping DTS
separate. Arnd and Olof since some time are not happy when DTS branch
receives any driver updates.

Arnd, Olof,
This is a set of dtschema conversion + DTS alignment with new schema:
1. Driver change necessary to accept new DTS (driver depends on node
names and this has to change because of dtschema),
2. DTS commits depending on above, which convert node name to new format,
3. Finally dtschema requiring new naming of the GPIO nodes.

If I got correctly, the policy of not mixing drivers and DTS requires
that #2 above (DTS changes) will wait for one more release. During the
time, if dtschema (#3 above) is applied, there will be new warnings
about non-compliant DTS.

Do you see any chance of merging driver + DTS + dtschema via same tree
in same release?


Best regards,
Krzysztof


From Tudor.Ambarus at microchip.com  Mon Jan 17 00:00:34 2022
From: Tudor.Ambarus at microchip.com (Tudor.Ambarus at microchip.com)
Date: Mon, 17 Jan 2022 08:00:34 +0000
Subject: [PATCH v2] pinctrl: at91-pio4: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <241bd054-ea30-ffc9-fb36-c30c8e06db7f@microchip.com>

On 1/4/22 4:09 PM, Lad Prabhakar wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
> 
> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
> 
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
> 
> While at it, replace the dev_err() with dev_dbg() as platform_get_irq()
> prints an error message upon error.
> 
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Reviewed-by: Tudor Ambarus <tudor.ambarus at microchip.com>
Tested-by: Tudor Ambarus <tudor.ambarus at microchip.com>

thanks,
ta
> ---
> v1->v2
> * Switched using platform_get_irq()
> * Replaced dev_err() with dev_dbg()
> 
> v1: https://lore.kernel.org/lkml/20211224145748.18754-3-prabhakar.mahadev-lad.rj at bp.renesas.com/
> ---
>  drivers/pinctrl/pinctrl-at91-pio4.c | 16 +++++++---------
>  1 file changed, 7 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c
> index fafd1f55cba7..517f2a6330ad 100644
> --- a/drivers/pinctrl/pinctrl-at91-pio4.c
> +++ b/drivers/pinctrl/pinctrl-at91-pio4.c
> @@ -1045,7 +1045,6 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
>         const char **group_names;
>         const struct of_device_id *match;
>         int i, ret;
> -       struct resource *res;
>         struct atmel_pioctrl *atmel_pioctrl;
>         const struct atmel_pioctrl_data *atmel_pioctrl_data;
> 
> @@ -1164,16 +1163,15 @@ static int atmel_pinctrl_probe(struct platform_device *pdev)
> 
>         /* There is one controller but each bank has its own irq line. */
>         for (i = 0; i < atmel_pioctrl->nbanks; i++) {
> -               res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
> -               if (!res) {
> -                       dev_err(dev, "missing irq resource for group %c\n",
> +               ret = platform_get_irq(pdev, i);
> +               if (ret < 0) {
> +                       dev_dbg(dev, "missing irq resource for group %c\n",
>                                 'A' + i);
> -                       return -EINVAL;
> +                       return ret;
>                 }
> -               atmel_pioctrl->irqs[i] = res->start;
> -               irq_set_chained_handler_and_data(res->start,
> -                       atmel_gpio_irq_handler, atmel_pioctrl);
> -               dev_dbg(dev, "bank %i: irq=%pr\n", i, res);
> +               atmel_pioctrl->irqs[i] = ret;
> +               irq_set_chained_handler_and_data(ret, atmel_gpio_irq_handler, atmel_pioctrl);
> +               dev_dbg(dev, "bank %i: irq=%d\n", i, ret);
>         }
> 
>         atmel_pioctrl->irq_domain = irq_domain_add_linear(dev->of_node,
> --
> 2.17.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From lkp at intel.com  Mon Jan 17 00:08:46 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 16:08:46 +0800
Subject: [linusw-nomadik:ux500-href-charging-v5.16-rc1 51/58]
 (.text.power_supply_get_battery_info+0xc8): undefined reference to
 `samsung_sdi_battery_get_info'
Message-ID: <202201171553.GzhBBn9Q-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
head:   1e846b0b60ac01cac4f283975a1bc395ff73d995
commit: b2618832497f01a095daeab65ff9a81a96b0de42 [51/58] power: supply: Static data for Samsung batteries
config: mips-allmodconfig (https://download.01.org/0day-ci/archive/20220117/202201171553.GzhBBn9Q-lkp at intel.com/config)
compiler: mips-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?id=b2618832497f01a095daeab65ff9a81a96b0de42
        git remote add linusw-nomadik https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
        git fetch --no-tags linusw-nomadik ux500-href-charging-v5.16-rc1
        git checkout b2618832497f01a095daeab65ff9a81a96b0de42
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=mips SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   mips-linux-ld: drivers/power/supply/power_supply_core.o: in function `power_supply_get_battery_info':
>> (.text.power_supply_get_battery_info+0xc8): undefined reference to `samsung_sdi_battery_get_info'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From jbrunet at baylibre.com  Mon Jan 17 00:26:40 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Mon, 17 Jan 2022 09:26:40 +0100
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
 <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
Message-ID: <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>


On Tue 11 Jan 2022 at 15:04, Yu Tu <yu.tu at amlogic.com> wrote:

> Hi Jerome,
> 	Thank you very much for your reply.
>
> On 2022/1/10 22:29, Jerome Brunet wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
>> Title is bad (like several other patches in this series) - Please fix it
>> Ok.
>>> Using the common Clock code to describe the UART baud rate clock
>>> makes it easier for the UART driver to be compatible with the
>>> baud rate requirements of the UART IP on different meson chips.
>>>
>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>> ---
>>>   drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>>   1 file changed, 163 insertions(+), 61 deletions(-)
>>>
>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>> index 7570958d010c..1004fd0b0c9e 100644
>>> --- a/drivers/tty/serial/meson_uart.c
>>> +++ b/drivers/tty/serial/meson_uart.c
>>> @@ -6,6 +6,7 @@
>>>    */
>>>     #include <linux/clk.h>
>>> +#include <linux/clk-provider.h>
>>>   #include <linux/console.h>
>>>   #include <linux/delay.h>
>>>   #include <linux/init.h>
>>> @@ -65,9 +66,7 @@
>>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>     /* AML_UART_REG5 bits */
>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>   #define AML_UART_BAUD_USE		BIT(23)
>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>     #define AML_UART_PORT_NUM		12
>>>   #define AML_UART_PORT_OFFSET		6
>>> @@ -76,6 +75,13 @@
>>>   #define AML_UART_POLL_USEC		5
>>>   #define AML_UART_TIMEOUT_USEC		10000
>>>   +struct meson_uart_data {
>>> +	struct uart_port	port;
>>> +	struct clk		*pclk;
>>> +	struct clk		*baud_clk;
>>> +	bool			use_xtal_clk;
>>> +};
>>> +
>>>   static struct uart_driver meson_uart_driver;
>>>     static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>   static int meson_uart_startup(struct uart_port *port)
>>>   {
>>>   	u32 val;
>>> -	int ret = 0;
>>> +	int ret;
>>>   -	val = readl(port->membase + AML_UART_CONTROL);
>>> -	val |= AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> -	val &= ~AML_UART_CLEAR_ERR;
>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>> +	meson_uart_reset(port);
>>>   +	val = readl(port->membase + AML_UART_CONTROL);
>>>   	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>   	writel(val, port->membase + AML_UART_CONTROL);
>>>   @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port
>>> *port)
>>>     static void meson_uart_change_speed(struct uart_port *port, unsigned
>>> long baud)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>>   	u32 val;
>>>     	while (!meson_uart_tx_empty(port))
>>>   		cpu_relax();
>>>   -	if (port->uartclk == 24000000) {
>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>> -		val |= AML_UART_BAUD_XTAL;
>>> -	} else {
>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>> -	}
>>> +	val = readl(port->membase + AML_UART_REG5);
>>>   	val |= AML_UART_BAUD_USE;
>>>   	writel(val, port->membase + AML_UART_REG5);
>>> +
>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>   }
>>>     static void meson_uart_set_termios(struct uart_port *port,
>>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>     static void meson_uart_release_port(struct uart_port *port)
>>>   {
>>> -	/* nothing to do */
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +
>>> +	clk_disable_unprepare(private_data->baud_clk);
>>> +	clk_disable_unprepare(private_data->pclk);
>>>   }
>>>     static int meson_uart_request_port(struct uart_port *port)
>>>   {
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	int ret;
>>> +
>>> +	ret = clk_prepare_enable(private_data->pclk);
>>> +	if (ret)
>>> +		return ret;
>> In the previous version of the series, you already been asked to the
>> enable of pclk in the probe. Optimization should not be mixed with this
>> series
>> Please make sure all comments are addressed before re-posting
>> 
> I'm sorry. I misunderstood you earlier. I'm going to move into the probe
> function.
>>> +
>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>> +	if (ret) {
>>> +		clk_disable_unprepare(private_data->pclk);
>>> +		return ret;
>>> +	}
>>> +
>>>   	return 0;
>>>   }
>>>   @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>>   	.cons		= MESON_SERIAL_CONSOLE,
>>>   };
>>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>> -						 const char *id)
>>> +#define CLK_NAME(name) \
>>> +({\
>>> +	char clk_name[32];\
>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>>> +	clk_name;\
>>> +})
>> 1) This result in some ugly code being inlined
>> 2) You return a pointer a local variable which is not gurantee to exist
>> anymore  outside of this ...
>> Please do this simply in the related function.
> I've overdone it. I'll move it to the meson_uart_probe_clocks function as
> you suggested.
>> 
>>> +
>>> +static struct clk_div_table xtal_div_table[] = {
>>> +	{ 0, 3  },
>>> +	{ 1, 1  },
>>> +	{ 2, 2  },
>>> +	{ 3, 2  },
>>> +};
>>> +
>>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>>   {
>>> -	struct clk *clk = NULL;
>>> -	int ret;
>>> +	struct meson_uart_data *private_data = port->private_data;
>>> +	struct clk *clk_baud, *clk_xtal;
>>> +	struct clk_hw *hw;
>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>> +		{ .index = -1, },
>>> +		{ .index = -1, },
>>> +	};
>>>   -	clk = devm_clk_get(dev, id);
>>> -	if (IS_ERR(clk))
>>> -		return clk;
>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>> +	if (IS_ERR(private_data->pclk))
>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>> +				     "Failed to get the 'pclk' clock\n");
>>>   -	ret = clk_prepare_enable(clk);
>>> -	if (ret) {
>>> -		dev_err(dev, "couldn't enable clk\n");
>>> -		return ERR_PTR(ret);
>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>> +	if (IS_ERR(clk_baud)) {
>>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>>> +		return PTR_ERR(clk_baud);
>>>   	}
>>>   -	devm_add_action_or_reset(dev,
>>> -			(void(*)(void *))clk_disable_unprepare,
>>> -			clk);
>>> -
>>> -	return clk;
>>> -}
>>> -
>>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>> -				   struct uart_port *port)
>>> -{
>>> -	struct clk *clk_xtal = NULL;
>>> -	struct clk *clk_pclk = NULL;
>>> -	struct clk *clk_baud = NULL;
>>> -
>>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>> -	if (IS_ERR(clk_pclk))
>>> -		return PTR_ERR(clk_pclk);
>>> -
>>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>   	if (IS_ERR(clk_xtal))
>>> -		return PTR_ERR(clk_xtal);
>>> -
>>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>> -	if (IS_ERR(clk_baud))
>>> -		return PTR_ERR(clk_baud);
>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>> +				     "Failed to get the 'xtal' clock\n");
>>> +
>>> +	if (private_data->use_xtal_clk) {
>>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>>> +							CLK_NAME(xtal_div),
>>> +							__clk_get_name(clk_baud),
>>> +							CLK_SET_RATE_NO_REPARENT,
>>> +							port->membase + AML_UART_REG5,
>>> +							26, 2,
>>> +							CLK_DIVIDER_READ_ONLY,
>>> +							xtal_div_table, NULL);
>>> +		if (IS_ERR(hw))
>>> +			return PTR_ERR(hw);
>>> +
>>> +		use_xtal_mux_parents[1].hw = hw;
>>> +	} else {
>>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>>> +						       CLK_NAME(clk81_div4),
>>> +						       __clk_get_name(clk_baud),
>>> +						       CLK_SET_RATE_NO_REPARENT,
>>> +						       1, 4);
>>> +		if (IS_ERR(hw))
>>> +			return PTR_ERR(hw);
>>> +
>>> +		use_xtal_mux_parents[0].hw = hw;
>>> +	}
>> Contradiction with previous series.
>> In the previous series we could clearly see that gxbb did not have the
>> /4 divider. It did not have bits 26 and 27 either.
>> Now gxbb get the /4 divider. It operated correctly without it so far, so
>> this is rather suspicious. Could you please comment on this ?
>> 
> As Martin and I discussed earlier.
> meson6 and meson8b SoC.There are not have bits 26 and 27 either.
> CLK81 is recommended for this part of SOC.
>
> GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
> UART_EE_A_REG5[26]:
> - 0x0: divide the input clock by 3 (meaning: this internally works
> with an 8MHz clock)
> - 0x1: use the input clock directly without further division (meaning:
> this internally work with an 24MHz clock)
> 8MHz is recommended for this part of SOC. Their UART IP configuration is
> the same.
>
> G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
> UART_EE_A_REG5[27]:
> - 0x0: use the clock as configured in UART_EE_A_REG5[26]
> - 0x1: divide the input clock by 2 (meaning: this internally works
> with an 12MHz clock)
> 12MHz is recommended for this part of SOC.
>
> NOTE:
> 1. clk81 /4 divider.
> There is a 4 divider inside, this is what the internal SOC designer told
> me. But they forgot to document it. So it makes people feel suspicious.
>
> 2.The UART_EE_A_REG5 default value is 0,except for the console port(set in
> romcode).All the baud rate clocks supported by UART can work, but different
> chip usage scenarios suggest using that clock to reduce jitter.
>
> In summary, I would like to know your suggestions, including how to change
> compatible.
> Thank you so much!

>From your comment, gxbb should have "true" instead of false, isn't it ?

>
>  >>
>>> -	port->uartclk = clk_get_rate(clk_baud);
>>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>>> +					CLK_NAME(use_xtal),
>>> +					ARRAY_SIZE(use_xtal_mux_parents),
>>> +					NULL, NULL,
>>> +					use_xtal_mux_parents,
>>> +					CLK_SET_RATE_PARENT,
>>> +					port->membase + AML_UART_REG5,
>>> +					24, 0x1,
>>> +					CLK_MUX_READ_ONLY,
>>> +					NULL, NULL);
>>> +	if (IS_ERR(hw))
>>> +		return PTR_ERR(hw);
>>> +
>>> +	port->uartclk = clk_hw_get_rate(hw);
>>> +
>>> +	hw = devm_clk_hw_register_divider(port->dev,
>>> +					  CLK_NAME(baud_div),
>>> +					  clk_hw_get_name(hw),
>>> +					  CLK_SET_RATE_PARENT,
>>> +					  port->membase + AML_UART_REG5,
>>> +					  0, 23,
>>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>>> +					  NULL);
>>> +	if (IS_ERR(hw))
>>> +		return PTR_ERR(hw);
>>> +
>>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>> I have already commented on the use of this function in the previous
>> version.
>> Please make sure all comments are addressed before re-posting
>> 
> I'm sorry. I misunderstood you earlier. I will be changed to
> "private_data->baud_clk = hw->clk;".What do you think?

yes

>>>     	return 0;
>>>   }
>>>     static int meson_uart_probe(struct platform_device *pdev)
>>>   {
>>> +	struct meson_uart_data *private_data;
>>>   	struct resource *res_mem;
>>>   	struct uart_port *port;
>>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   		return -EBUSY;
>>>   	}
>>>   -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>> GFP_KERNEL);
>>> -	if (!port)
>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>> +				    GFP_KERNEL);
>>> +	if (!private_data)
>>>   		return -ENOMEM;
>>>   +	if (device_get_match_data(&pdev->dev))
>>> +		private_data->use_xtal_clk = true;
>>> +
>>> +	port = &private_data->port;
>>> +
>>>   	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>   	if (IS_ERR(port->membase))
>>>   		return PTR_ERR(port->membase);
>>>   -	ret = meson_uart_probe_clocks(pdev, port);
>>> -	if (ret)
>>> -		return ret;
>>> -
>>>   	port->iotype = UPIO_MEM;
>>>   	port->mapbase = res_mem->start;
>>>   	port->mapsize = resource_size(res_mem);
>>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>   	port->x_char = 0;
>>>   	port->ops = &meson_uart_ops;
>>>   	port->fifosize = fifosize;
>>> +	port->private_data = private_data;
>> port has private_data
>> private_data has port
>> Is it really necessary to have both ... looks to me that port in
>> private_data is overkill
>> 
> It's very thoughtful of you. I'll delete it as you suggested.
>>>   +	ret = meson_uart_probe_clocks(port);
>>> +	if (ret)
>>> +		return ret;
>>>   	meson_ports[pdev->id] = port;
>>>   	platform_set_drvdata(pdev, port);
>>>   @@ -766,10 +839,39 @@ static int meson_uart_remove(struct
>>> platform_device *pdev)
>>>   }
>>>     static const struct of_device_id meson_uart_dt_match[] = {
>>> -	{ .compatible = "amlogic,meson6-uart" },
>>> -	{ .compatible = "amlogic,meson8-uart" },
>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>> +	{
>>> +		.compatible = "amlogic,meson6-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson8b-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>> +		.data = (void *)false,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-gxl-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	{
>>> +		.compatible = "amlogic,meson-g12a-uart",
>>> +		.data = (void *)true,
>>> +	},
>>> +	/*
>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>> +	 * between GXBB, GXL and G12A which have different revisions
>>> +	 * of the UART IP.
>>> +	 */
>>> +	{
>>> +		.compatible = "amlogic,meson-gx-uart",
>>> +		.data = (void *)false,
>>> +	},
>>>   	{ /* sentinel */ },
>>>   };
>>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>> 
>
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic



From axe.yang at mediatek.com  Mon Jan 17 00:30:25 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 16:30:25 +0800
Subject: [PATCH 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <60f3d381-1af4-d002-e179-9550672dae5b@mediatek.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
 <20220117071220.17330-3-axe.yang@mediatek.com>
 <60f3d381-1af4-d002-e179-9550672dae5b@mediatek.com>
Message-ID: <efc06609571d7b6a1d5327fa37661af8ddce8675.camel@mediatek.com>

On Mon, 2022-01-17 at 16:14 +0800, Macpaul Lin wrote:
> On 1/17/22 3:12 PM, Axe Yang wrote:
> > If cap-sdio-async-irq flag is set in host dts node, parse EAI
> > information from SDIO CCCR interrupt externsion segment. If async
> > interrupt is supported by SDIO card then send command to card to
> > enable it and set enable_async_irq flag in sdio_cccr structure to
> > 1.
> > The parse flow is implemented in sdio_read_cccr().
> > 
> > Acked-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> 
> [deleted...]
> 
> It seems the prefix "[PATCH v3]" didn't applied to subject of each
> patch 
> in v3 series. Please remember to keep the version aligned in the
> same 
> patch set. Use "git format-patch --subject-prefix=[PATCH v3]" to
> help 
> you to keep the version number aligned is suggested.
> 
> Thanks!
> Macpaul Lin

Patches have been resent. Thanks.

From axe.yang at mediatek.com  Mon Jan 17 00:25:39 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 16:25:39 +0800
Subject: [RESEND v3 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220117082539.18713-1-axe.yang@mediatek.com>
References: <20220117082539.18713-1-axe.yang@mediatek.com>
Message-ID: <20220117082539.18713-4-axe.yang@mediatek.com>

Add support for eint IRQ when MSDC is used as an SDIO host. This
feature requires SDIO device support async IRQ function. With this
feature, SDIO host can be awakened by SDIO card in suspend state,
without additional pin.

MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
resume, switch GPIO function back to DAT1 mode then turn on clock.

Some device tree property should be added or modified in MSDC node
to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
are mandatory. And cap-sdio-async-irq flag is necessary since this
feature depends on asynchronous interrupt:
        &mmcX {
                ...
                pinctrl-names = "default", "state_uhs", "state_eint",
                                "state_dat1";
                ...
                pinctrl-2 = <&mmc2_pins_eint>;
                pinctrl-3 = <&mmc2_pins_dat1>;
                ...
                cap-sdio-async-irq;
                ...
        };

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
Signed-off-by: Yong Mao <yong.mao at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 125 +++++++++++++++++++++++++++++++++++---
 1 file changed, 117 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 65037e1d7723..cbdbcce99fd9 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2015 MediaTek Inc.
+ * Copyright (c) 2022 MediaTek Inc.
  * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
  */
 
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -440,8 +441,12 @@ struct msdc_host {
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
+	struct pinctrl_state *pins_eint;
+	struct pinctrl_state *pins_dat1;
 	struct delayed_work req_timeout;
 	int irq;		/* host interrupt */
+	int eint_irq;		/* device interrupt */
+	int sdio_irq_cnt;	/* irq enable cnt */
 	struct reset_control *reset;
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -465,6 +470,7 @@ struct msdc_host {
 	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
+	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 	struct msdc_tune_para def_tune_para; /* default tune setting */
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
@@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	__msdc_enable_sdio_irq(host, enb);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (enb)
-		pm_runtime_get_noresume(host->dev);
-	else
-		pm_runtime_put_noidle(host->dev);
+	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
+		if (enb)
+			pm_runtime_get_noresume(host->dev);
+		else
+			pm_runtime_put_noidle(host->dev);
+	}
 }
 
 static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
@@ -2461,6 +2469,50 @@ static const struct mmc_host_ops mt_msdc_ops = {
 	.hw_reset = msdc_hw_reset,
 };
 
+static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
+{
+	struct msdc_host *host = dev_id;
+	struct mmc_host *mmc = mmc_from_priv(host);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (likely(host->sdio_irq_cnt > 0)) {
+		disable_irq_nosync(host->eint_irq);
+		disable_irq_wake(host->eint_irq);
+		host->sdio_irq_cnt--;
+	}
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	sdio_signal_irq(mmc);
+
+	return IRQ_HANDLED;
+}
+
+static int msdc_request_dat1_eint_irq(struct msdc_host *host)
+{
+	struct gpio_desc *desc;
+	int irq, ret;
+
+	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	ret = gpiod_to_irq(desc);
+	if (ret < 0)
+		return ret;
+
+	irq = ret;
+	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					"sdio-eint", host);
+	if (ret)
+		return ret;
+
+	host->eint_irq = irq;
+
+	return 0;
+}
+
 static const struct cqhci_host_ops msdc_cmdq_ops = {
 	.enable         = msdc_cqe_enable,
 	.disable        = msdc_cqe_disable,
@@ -2631,6 +2683,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO)) {
+		/* Support for SDIO eint irq */
+		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+		if (IS_ERR(host->pins_eint)) {
+			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
+		} else {
+			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
+			if (IS_ERR(host->pins_dat1)) {
+				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
+						    "Cannot find pinctrl dat1!\n");
+				goto host_free;
+			}
+
+			host->sdio_eint_ready = true;
+		}
+	}
+
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
@@ -2722,6 +2791,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto release;
 
+	if (host->sdio_eint_ready) {
+		ret = msdc_request_dat1_eint_irq(host);
+		if (ret) {
+			dev_err(host->dev, "Failed to register data1 eint irq!\n");
+			goto release;
+		}
+
+		pinctrl_select_state(host->pinctrl, host->pins_dat1);
+	}
+
 	pm_runtime_set_active(host->dev);
 	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(host->dev);
@@ -2841,16 +2920,31 @@ static void msdc_restore_reg(struct msdc_host *host)
 
 static int __maybe_unused msdc_runtime_suspend(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 
 	msdc_save_reg(host);
+
+	if (host->sdio_eint_ready) {
+		disable_irq(host->irq);
+		pinctrl_select_state(host->pinctrl, host->pins_eint);
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt == 0) {
+			enable_irq(host->eint_irq);
+			enable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt++;
+		}
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 	msdc_gate_clock(host);
 	return 0;
 }
 
 static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
@@ -2860,10 +2954,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 		return ret;
 
 	msdc_restore_reg(host);
+
+	if (host->sdio_eint_ready) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt > 0) {
+			disable_irq_nosync(host->eint_irq);
+			disable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt--;
+			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		} else {
+			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+		enable_irq(host->irq);
+	}
 	return 0;
 }
 
-static int __maybe_unused msdc_suspend(struct device *dev)
+static int __maybe_unused msdc_suspend_noirq(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret;
@@ -2877,13 +2986,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int __maybe_unused msdc_resume(struct device *dev)
+static int __maybe_unused msdc_resume_noirq(struct device *dev)
 {
 	return pm_runtime_force_resume(dev);
 }
 
 static const struct dev_pm_ops msdc_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-- 
2.25.1



From axe.yang at mediatek.com  Mon Jan 17 00:25:36 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 16:25:36 +0800
Subject: [RESEND v3 0/3] mmc: mediatek: add support for SDIO eint IRQ 
Message-ID: <20220117082539.18713-1-axe.yang@mediatek.com>


Changes in v3:
- correct abbreviations with capital letters in commit message
- replace copyright year with 2022 in mtk-sd.c
- remove unnessary pointer casting
- adjust variable order to reversed xmas tree
- remove a redundant blank line
- refine if statement, following standard pattern

Axe Yang (3):
  dt-bindings: mmc: add cap-sdio-async-irq flag
  mmc: core: Add support for SDIO async interrupt
  mmc: mediatek: add support for SDIO eint IRQ

 .../bindings/mmc/mmc-controller.yaml          |   5 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/sdio.c                       |  17 +++
 drivers/mmc/host/mtk-sd.c                     | 125 ++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +-
 include/linux/mmc/host.h                      |   1 +
 include/linux/mmc/sdio.h                      |   5 +
 7 files changed, 149 insertions(+), 9 deletions(-)

-- 
2.25.1



From axe.yang at mediatek.com  Mon Jan 17 00:25:37 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 16:25:37 +0800
Subject: [RESEND v3 1/3] dt-bindings: mmc: add cap-sdio-async-irq flag
In-Reply-To: <20220117082539.18713-1-axe.yang@mediatek.com>
References: <20220117082539.18713-1-axe.yang@mediatek.com>
Message-ID: <20220117082539.18713-2-axe.yang@mediatek.com>

Asynchronous interrupt is a mechanism that allow SDIO devices alarm
interrupt when host stop providing clock to card. Add a DT flag to
enable this feature if it is supported by SDIO card.

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index 513f3c8758aa..16fb06f88471 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -165,6 +165,11 @@ properties:
     description:
       eMMC hardware reset is supported
 
+  cap-sdio-async-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO async interrupt is supported.
+
   cap-sdio-irq:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.25.1



From axe.yang at mediatek.com  Mon Jan 17 00:25:38 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Mon, 17 Jan 2022 16:25:38 +0800
Subject: [RESEND v3 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20220117082539.18713-1-axe.yang@mediatek.com>
References: <20220117082539.18713-1-axe.yang@mediatek.com>
Message-ID: <20220117082539.18713-3-axe.yang@mediatek.com>

If cap-sdio-async-irq flag is set in host dts node, parse EAI
information from SDIO CCCR interrupt externsion segment. If async
interrupt is supported by SDIO card then send command to card to
enable it and set enable_async_irq flag in sdio_cccr structure to 1.
The parse flow is implemented in sdio_read_cccr().

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
 include/linux/mmc/card.h |  3 ++-
 include/linux/mmc/host.h |  1 +
 include/linux/mmc/sdio.h |  5 +++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf140f4ec864..a972241548b4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -410,6 +410,8 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "no-mmc-hs400"))
 		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
 				 MMC_CAP2_HS400_ES);
+	if (device_property_read_bool(dev, "cap-sdio-async-irq"))
+		host->caps2 |= MMC_CAP2_SDIO_ASYNC_IRQ;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 41164748723d..771fb5d18585 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
 			if (data & SDIO_DRIVE_SDTD)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ) {
+				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
+						       &data);
+				if (ret)
+					goto out;
+
+				if (data & SDIO_INTERRUPT_EXT_SAI) {
+					data |= SDIO_INTERRUPT_EXT_EAI;
+					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+							       data, NULL);
+					if (ret)
+						goto out;
+
+					card->cccr.enable_async_irq = 1;
+				}
+			}
 		}
 
 		/* if no uhs mode ensure we check for high speed */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 37f975875102..4df9182bc0e6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,8 @@ struct sdio_cccr {
 				wide_bus:1,
 				high_power:1,
 				high_speed:1,
-				disable_cd:1;
+				disable_cd:1,
+				enable_async_irq:1;
 };
 
 struct sdio_cis {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7afb57cab00b..502a5418264c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -402,6 +402,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SDIO_ASYNC_IRQ	(1 << 29)	/* SDIO host supports asynchronous interrupt */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 2a05d1ac4f0e..1ef400f28642 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -159,6 +159,11 @@
 #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT	0x16
+#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
-- 
2.25.1



From lkp at intel.com  Mon Jan 17 00:39:12 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 16:39:12 +0800
Subject: [linusw-nomadik:ux500-href-charging-v5.16-rc1 51/58] undefined
 reference to `samsung_sdi_battery_get_info'
Message-ID: <202201171658.RcGVrgup-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
head:   1e846b0b60ac01cac4f283975a1bc395ff73d995
commit: b2618832497f01a095daeab65ff9a81a96b0de42 [51/58] power: supply: Static data for Samsung batteries
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20220117/202201171658.RcGVrgup-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?id=b2618832497f01a095daeab65ff9a81a96b0de42
        git remote add linusw-nomadik https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
        git fetch --no-tags linusw-nomadik ux500-href-charging-v5.16-rc1
        git checkout b2618832497f01a095daeab65ff9a81a96b0de42
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   m68k-linux-ld: drivers/power/supply/power_supply_core.o: in function `power_supply_get_battery_info':
>> (.text+0x1b5e): undefined reference to `samsung_sdi_battery_get_info'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From heiko at sntech.de  Mon Jan 17 00:40:54 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 17 Jan 2022 09:40:54 +0100
Subject: [PATCH v2 1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to
 SPDIF output
In-Reply-To: <CAGXv+5H0-dM28YQj_orS1_14NLcJve8VtO6oLcBiRpJFjaf5KA@mail.gmail.com>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.1.I46f64b00508d9dff34abe1c3e8d2defdab4ea1e5@changeid>
 <CAGXv+5H0-dM28YQj_orS1_14NLcJve8VtO6oLcBiRpJFjaf5KA@mail.gmail.com>
Message-ID: <3970568.xje1Q9F24u@diego>

Am Montag, 17. Januar 2022, 08:44:37 CET schrieb Chen-Yu Tsai:
> On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
> >
> > Commit b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> > switched the platform to SPDIF, but we didn't fix up the device tree.
> >
> > Drop the pinctrl settings, because the 'spdif_bus' pins are either:
> >  * unused (on kevin, bob), so the settings is ~harmless
> >  * used by a different function (on scarlet), which causes probe
> >    failures (!!)
> 
> I suppose that means the default pinctrl should be dropped? Or maybe this
> use case is the outlier. Up to Heiko?

Interesting question. Right now it looks like Gru is the only one using spdif
in that way, so I'd think dropping the pinctrl here is the "saner" option
at this time ;-)

I guess we can reevaluate if this becomes more widespread

> > Fixes: b18c6c3c7768 ("ASoC: rockchip: cdn-dp sound output use spdif")
> > Signed-off-by: Brian Norris <briannorris at chromium.org>
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
> 






From piotr.oniszczuk at gmail.com  Mon Jan 17 00:43:49 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Mon, 17 Jan 2022 09:43:49 +0100
Subject: [PATCH 5/9] arm64: dts: rockchip: add rk3568 tsadc nodes
In-Reply-To: <20210728135534.703028-6-pgwipeout@gmail.com>
References: <20210728135534.703028-1-pgwipeout@gmail.com>
 <20210728135534.703028-6-pgwipeout@gmail.com>
Message-ID: <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>



> Wiadomo?? napisana przez Peter Geis <pgwipeout at gmail.com> w dniu 28.07.2021, o godz. 15:55:
> 
> Add the thermal and tsadc nodes to the rk3568 device tree.
> There are two sensors, one for the cpu, one for the gpu.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
> .../boot/dts/rockchip/rk3568-pinctrl.dtsi     |  6 ++
> arch/arm64/boot/dts/rockchip/rk356x.dtsi      | 71 +++++++++++++++++++
> 2 files changed, 77 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> index a588ca95ace2..b464c7bda1f7 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> @@ -2420,6 +2420,12 @@ spi3m1_cs1: spi3m1-cs1 {
> 	};
> 
> 	tsadc {
> +		/omit-if-no-ref/
> +		tsadc_gpio: tsadc-gpio {
> +			rockchip,pins =
> +				<0 RK_PA1 0 &pcfg_pull_none>;
> +		};
> +
> 		/omit-if-no-ref/
> 		tsadcm0_shut: tsadcm0-shut {
> 			rockchip,pins =
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 77c679304916..0905fac0726a 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -51,6 +51,7 @@ cpu0: cpu at 0 {
> 			compatible = "arm,cortex-a55";
> 			reg = <0x0 0x0>;
> 			clocks = <&scmi_clk 0>;
> +			#cooling-cells = <2>;
> 			enable-method = "psci";
> 			operating-points-v2 = <&cpu0_opp_table>;
> 		};
> @@ -59,6 +60,7 @@ cpu1: cpu at 100 {
> 			device_type = "cpu";
> 			compatible = "arm,cortex-a55";
> 			reg = <0x0 0x100>;
> +			#cooling-cells = <2>;
> 			enable-method = "psci";
> 			operating-points-v2 = <&cpu0_opp_table>;
> 		};
> @@ -67,6 +69,7 @@ cpu2: cpu at 200 {
> 			device_type = "cpu";
> 			compatible = "arm,cortex-a55";
> 			reg = <0x0 0x200>;
> +			#cooling-cells = <2>;
> 			enable-method = "psci";
> 			operating-points-v2 = <&cpu0_opp_table>;
> 		};
> @@ -75,6 +78,7 @@ cpu3: cpu at 300 {
> 			device_type = "cpu";
> 			compatible = "arm,cortex-a55";
> 			reg = <0x0 0x300>;
> +			#cooling-cells = <2>;
> 			enable-method = "psci";
> 			operating-points-v2 = <&cpu0_opp_table>;
> 		};
> @@ -774,6 +778,73 @@ uart9: serial at fe6d0000 {
> 		status = "disabled";
> 	};
> 
> +	thermal_zones: thermal-zones {
> +		cpu_thermal: cpu-thermal {
> +			polling-delay-passive = <100>;
> +			polling-delay = <1000>;
> +
> +			thermal-sensors = <&tsadc 0>;
> +
> +			trips {
> +				cpu_alert0: cpu_alert0 {
> +					temperature = <70000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};
> +				cpu_alert1: cpu_alert1 {
> +					temperature = <75000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};
> +				cpu_crit: cpu_crit {
> +					temperature = <95000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +
> +			cooling-maps {
> +				map0 {
> +					trip = <&cpu_alert0>;
> +					cooling-device =
> +						<&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +						<&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +				};
> +			};
> +		};
> +
> +		gpu_thermal: gpu-thermal {
> +			polling-delay-passive = <20>; /* milliseconds */
> +			polling-delay = <1000>; /* milliseconds */
> +
> +			thermal-sensors = <&tsadc 1>;
> +		};
> +	};
> +
> +	tsadc: tsadc at fe710000 {
> +		compatible = "rockchip,rk3568-tsadc";
> +		reg = <0x0 0xfe710000 0x0 0x100>;
> +		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
> +		assigned-clocks = <&cru CLK_TSADC_TSEN>, <&cru CLK_TSADC>;
> +		assigned-clock-rates = <17000000>, <700000>;
> +		clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
> +		clock-names = "tsadc", "apb_pclk";
> +		resets = <&cru SRST_TSADC>, <&cru SRST_P_TSADC>,
> +			 <&cru SRST_TSADCPHY>;
> +		reset-names = "tsadc", "tsadc-apb", "tsadc-phy";
> +		rockchip,grf = <&grf>;
> +		rockchip,hw-tshut-temp = <95000>;
> +		rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
> +		rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
> +		pinctrl-names = "gpio", "otpout";
> +		pinctrl-0 = <&tsadc_gpio>;
> +		pinctrl-1 = <&tsadc_shutorg>;
> +		#thermal-sensor-cells = <1>;
> +		status = "disabled";
> +	};
> +
> 	saradc: saradc at fe720000 {
> 		compatible = "rockchip,rk3568-saradc", "rockchip,rk3399-saradc";
> 		reg = <0x0 0xfe720000 0x0 0x100>;
> -- 
> 2.25.1
> 
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip

Peter,

I'm trying to use this series to get thermal on rk3566 based tvbox (x96-x6).
Driver loads but i'm getting following error:

[  132.873979] rockchip-thermal fe710000.tsadc: failed to register sensor 0: -517
[  132.874650] rockchip-thermal fe710000.tsadc: failed to register sensor[0] : error = -517

Maybe you have some hints here?




From lee.jones at linaro.org  Mon Jan 17 01:00:49 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 17 Jan 2022 09:00:49 +0000
Subject: [PATCH 1/3] iio: adc: sun4i-gpadc-iio: no temp sensor on R40
In-Reply-To: <20211119191456.510435-2-boger@wirenboard.com>
References: <20211119191456.510435-1-boger@wirenboard.com>
 <20211119191456.510435-2-boger@wirenboard.com>
Message-ID: <YeUwQfkdWbEZlnh2@google.com>

On Fri, 19 Nov 2021, Evgeny Boger wrote:

> R40 SoC has touchscreen controller also serving as general-purpose ADC.
> The hardware is very similar to A31, except that R40 has separate
> calibrated thermal sensor IP (handled by sun8i_thermal).
> 
> Despite the temperature sensor in the RTP is never mentioned in
> the R40 family user manuals, it appears to be working. However,
> it's not very useful as it lacks calibration data and there is another
> fully functioning temperature sensor anyway.
> 
> This patch disables the temperature sensor in RTP/GPADC IP on R40.
> 
> The reason for disabling the temperature sensor is that the IP
> needs to be switched back and forth between RTP and GPADC modes for
> temperature measurements. Not only this introduces delays, but it also
> disturbs external circuitry by injecting current into ADC inputs.
> 
> Signed-off-by: Evgeny Boger <boger at wirenboard.com>
> ---
>  drivers/iio/adc/sun4i-gpadc-iio.c | 32 +++++++++++++++++++++++--------
>  drivers/mfd/sun4i-gpadc.c         | 17 ++++++++++++++++

Please split these out.

They don't *need* to go in via a single tree.

>  2 files changed, 41 insertions(+), 8 deletions(-)

-- 
Lee Jones [???]
Principal Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From wenst at chromium.org  Mon Jan 17 01:01:52 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 17 Jan 2022 17:01:52 +0800
Subject: [PATCH v2 3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
In-Reply-To: <20220114150129.v2.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>
Message-ID: <CAGXv+5HC00YU6ARtGDahxWLqivvUCowh7wDq5H5OzoGO9htB+g@mail.gmail.com>

Hi,

On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
>
> Now that the cdn-dp driver supports plug-change callbacks, let's wire it
> up.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
>
> (no changes since v1)
>
>  sound/soc/rockchip/rk3399_gru_sound.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
>
> diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
> index e2d52d8d0ff9..eeef3ed70037 100644
> --- a/sound/soc/rockchip/rk3399_gru_sound.c
> +++ b/sound/soc/rockchip/rk3399_gru_sound.c
> @@ -164,6 +164,25 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
>         return 0;
>  }
>
> +static struct snd_soc_jack cdn_dp_card_jack;
> +
> +static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +       struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;

Using snd_soc_card_get_codec_dai() might be a better choice throughout this
driver. While it will work for the cdn_dp case, because it is the first DAI
in |rockchip_dais[]|, all the invocations for the other codecs are likely
returning the wrong DAI.

For this particular patch it works either way, so

Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>


> +       struct snd_soc_card *card = rtd->card;
> +       int ret;
> +
> +       /* Enable jack detection. */
> +       ret = snd_soc_card_jack_new(card, "DP Jack", SND_JACK_LINEOUT,
> +                                   &cdn_dp_card_jack, NULL, 0);
> +       if (ret) {
> +               dev_err(card->dev, "Can't create DP Jack %d\n", ret);
> +               return ret;
> +       }
> +
> +       return snd_soc_component_set_jack(component, &cdn_dp_card_jack, NULL);
> +}
> +
>  static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
>  {
>         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
> @@ -315,6 +334,7 @@ static const struct snd_soc_dai_link rockchip_dais[] = {
>         [DAILINK_CDNDP] = {
>                 .name = "DP",
>                 .stream_name = "DP PCM",
> +               .init = rockchip_sound_cdndp_init,
>                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
>                         SND_SOC_DAIFMT_CBS_CFS,
>                 SND_SOC_DAILINK_REG(cdndp),
> --
> 2.34.1.703.g22d0c6ccf7-goog
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From yu.tu at amlogic.com  Mon Jan 17 01:03:31 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Mon, 17 Jan 2022 17:03:31 +0800
Subject: [PATCH V4 3/5] tty: serial: meson: The UART baud rate
In-Reply-To: <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>
References: <20220110085604.18042-1-yu.tu@amlogic.com>
 <20220110085604.18042-4-yu.tu@amlogic.com>
 <1j8rvnps11.fsf@starbuckisacylon.baylibre.com>
 <c9bb2f8f-6169-b4ab-5637-56c185dbf254@amlogic.com>
 <1j7dayn4vh.fsf@starbuckisacylon.baylibre.com>
Message-ID: <70307ecc-b251-6adc-66c2-f7600d237f08@amlogic.com>

  Hi Jerome,
	Thank you very much for your reply.

On 2022/1/17 16:26, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 11 Jan 2022 at 15:04, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Hi Jerome,
>> 	Thank you very much for your reply.
>>
>> On 2022/1/10 22:29, Jerome Brunet wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> On Mon 10 Jan 2022 at 16:56, Yu Tu <yu.tu at amlogic.com> wrote:
>>> Title is bad (like several other patches in this series) - Please fix it
>>> Ok.
>>>> Using the common Clock code to describe the UART baud rate clock
>>>> makes it easier for the UART driver to be compatible with the
>>>> baud rate requirements of the UART IP on different meson chips.
>>>>
>>>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>>>> ---
>>>>    drivers/tty/serial/meson_uart.c | 224 +++++++++++++++++++++++---------
>>>>    1 file changed, 163 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>>>> index 7570958d010c..1004fd0b0c9e 100644
>>>> --- a/drivers/tty/serial/meson_uart.c
>>>> +++ b/drivers/tty/serial/meson_uart.c
>>>> @@ -6,6 +6,7 @@
>>>>     */
>>>>      #include <linux/clk.h>
>>>> +#include <linux/clk-provider.h>
>>>>    #include <linux/console.h>
>>>>    #include <linux/delay.h>
>>>>    #include <linux/init.h>
>>>> @@ -65,9 +66,7 @@
>>>>    #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>>>      /* AML_UART_REG5 bits */
>>>> -#define AML_UART_BAUD_MASK		0x7fffff
>>>>    #define AML_UART_BAUD_USE		BIT(23)
>>>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>>>      #define AML_UART_PORT_NUM		12
>>>>    #define AML_UART_PORT_OFFSET		6
>>>> @@ -76,6 +75,13 @@
>>>>    #define AML_UART_POLL_USEC		5
>>>>    #define AML_UART_TIMEOUT_USEC		10000
>>>>    +struct meson_uart_data {
>>>> +	struct uart_port	port;
>>>> +	struct clk		*pclk;
>>>> +	struct clk		*baud_clk;
>>>> +	bool			use_xtal_clk;
>>>> +};
>>>> +
>>>>    static struct uart_driver meson_uart_driver;
>>>>      static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>>>> @@ -268,14 +274,11 @@ static void meson_uart_reset(struct uart_port *port)
>>>>    static int meson_uart_startup(struct uart_port *port)
>>>>    {
>>>>    	u32 val;
>>>> -	int ret = 0;
>>>> +	int ret;
>>>>    -	val = readl(port->membase + AML_UART_CONTROL);
>>>> -	val |= AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> -	val &= ~AML_UART_CLEAR_ERR;
>>>> -	writel(val, port->membase + AML_UART_CONTROL);
>>>> +	meson_uart_reset(port);
>>>>    +	val = readl(port->membase + AML_UART_CONTROL);
>>>>    	val |= (AML_UART_RX_EN | AML_UART_TX_EN);
>>>>    	writel(val, port->membase + AML_UART_CONTROL);
>>>>    @@ -293,19 +296,17 @@ static int meson_uart_startup(struct uart_port
>>>> *port)
>>>>      static void meson_uart_change_speed(struct uart_port *port, unsigned
>>>> long baud)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>>    	u32 val;
>>>>      	while (!meson_uart_tx_empty(port))
>>>>    		cpu_relax();
>>>>    -	if (port->uartclk == 24000000) {
>>>> -		val = ((port->uartclk / 3) / baud) - 1;
>>>> -		val |= AML_UART_BAUD_XTAL;
>>>> -	} else {
>>>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>>>> -	}
>>>> +	val = readl(port->membase + AML_UART_REG5);
>>>>    	val |= AML_UART_BAUD_USE;
>>>>    	writel(val, port->membase + AML_UART_REG5);
>>>> +
>>>> +	clk_set_rate(private_data->baud_clk, baud);
>>>>    }
>>>>      static void meson_uart_set_termios(struct uart_port *port,
>>>> @@ -395,11 +396,27 @@ static int meson_uart_verify_port(struct uart_port *port,
>>>>      static void meson_uart_release_port(struct uart_port *port)
>>>>    {
>>>> -	/* nothing to do */
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +
>>>> +	clk_disable_unprepare(private_data->baud_clk);
>>>> +	clk_disable_unprepare(private_data->pclk);
>>>>    }
>>>>      static int meson_uart_request_port(struct uart_port *port)
>>>>    {
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	int ret;
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->pclk);
>>>> +	if (ret)
>>>> +		return ret;
>>> In the previous version of the series, you already been asked to the
>>> enable of pclk in the probe. Optimization should not be mixed with this
>>> series
>>> Please make sure all comments are addressed before re-posting
>>>
>> I'm sorry. I misunderstood you earlier. I'm going to move into the probe
>> function.
>>>> +
>>>> +	ret = clk_prepare_enable(private_data->baud_clk);
>>>> +	if (ret) {
>>>> +		clk_disable_unprepare(private_data->pclk);
>>>> +		return ret;
>>>> +	}
>>>> +
>>>>    	return 0;
>>>>    }
>>>>    @@ -629,55 +646,105 @@ static struct uart_driver meson_uart_driver = {
>>>>    	.cons		= MESON_SERIAL_CONSOLE,
>>>>    };
>>>>    -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>>>> -						 const char *id)
>>>> +#define CLK_NAME(name) \
>>>> +({\
>>>> +	char clk_name[32];\
>>>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev), #name);\
>>>> +	clk_name;\
>>>> +})
>>> 1) This result in some ugly code being inlined
>>> 2) You return a pointer a local variable which is not gurantee to exist
>>> anymore  outside of this ...
>>> Please do this simply in the related function.
>> I've overdone it. I'll move it to the meson_uart_probe_clocks function as
>> you suggested.
>>>
>>>> +
>>>> +static struct clk_div_table xtal_div_table[] = {
>>>> +	{ 0, 3  },
>>>> +	{ 1, 1  },
>>>> +	{ 2, 2  },
>>>> +	{ 3, 2  },
>>>> +};
>>>> +
>>>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>>>    {
>>>> -	struct clk *clk = NULL;
>>>> -	int ret;
>>>> +	struct meson_uart_data *private_data = port->private_data;
>>>> +	struct clk *clk_baud, *clk_xtal;
>>>> +	struct clk_hw *hw;
>>>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>>>> +		{ .index = -1, },
>>>> +		{ .index = -1, },
>>>> +	};
>>>>    -	clk = devm_clk_get(dev, id);
>>>> -	if (IS_ERR(clk))
>>>> -		return clk;
>>>> +	private_data->pclk = devm_clk_get(port->dev, "pclk");
>>>> +	if (IS_ERR(private_data->pclk))
>>>> +		return dev_err_probe(port->dev, PTR_ERR(private_data->pclk),
>>>> +				     "Failed to get the 'pclk' clock\n");
>>>>    -	ret = clk_prepare_enable(clk);
>>>> -	if (ret) {
>>>> -		dev_err(dev, "couldn't enable clk\n");
>>>> -		return ERR_PTR(ret);
>>>> +	clk_baud = devm_clk_get(port->dev, "baud");
>>>> +	if (IS_ERR(clk_baud)) {
>>>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>>>> +		return PTR_ERR(clk_baud);
>>>>    	}
>>>>    -	devm_add_action_or_reset(dev,
>>>> -			(void(*)(void *))clk_disable_unprepare,
>>>> -			clk);
>>>> -
>>>> -	return clk;
>>>> -}
>>>> -
>>>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>>>> -				   struct uart_port *port)
>>>> -{
>>>> -	struct clk *clk_xtal = NULL;
>>>> -	struct clk *clk_pclk = NULL;
>>>> -	struct clk *clk_baud = NULL;
>>>> -
>>>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>>>> -	if (IS_ERR(clk_pclk))
>>>> -		return PTR_ERR(clk_pclk);
>>>> -
>>>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>>>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>>>    	if (IS_ERR(clk_xtal))
>>>> -		return PTR_ERR(clk_xtal);
>>>> -
>>>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>>>> -	if (IS_ERR(clk_baud))
>>>> -		return PTR_ERR(clk_baud);
>>>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>>>> +				     "Failed to get the 'xtal' clock\n");
>>>> +
>>>> +	if (private_data->use_xtal_clk) {
>>>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>>>> +							CLK_NAME(xtal_div),
>>>> +							__clk_get_name(clk_baud),
>>>> +							CLK_SET_RATE_NO_REPARENT,
>>>> +							port->membase + AML_UART_REG5,
>>>> +							26, 2,
>>>> +							CLK_DIVIDER_READ_ONLY,
>>>> +							xtal_div_table, NULL);
>>>> +		if (IS_ERR(hw))
>>>> +			return PTR_ERR(hw);
>>>> +
>>>> +		use_xtal_mux_parents[1].hw = hw;
>>>> +	} else {
>>>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>>>> +						       CLK_NAME(clk81_div4),
>>>> +						       __clk_get_name(clk_baud),
>>>> +						       CLK_SET_RATE_NO_REPARENT,
>>>> +						       1, 4);
>>>> +		if (IS_ERR(hw))
>>>> +			return PTR_ERR(hw);
>>>> +
>>>> +		use_xtal_mux_parents[0].hw = hw;
>>>> +	}
>>> Contradiction with previous series.
>>> In the previous series we could clearly see that gxbb did not have the
>>> /4 divider. It did not have bits 26 and 27 either.
>>> Now gxbb get the /4 divider. It operated correctly without it so far, so
>>> this is rather suspicious. Could you please comment on this ?
>>>
>> As Martin and I discussed earlier.
>> meson6 and meson8b SoC.There are not have bits 26 and 27 either.
>> CLK81 is recommended for this part of SOC.
>>
>> GXL,GXM,GXBB and AXG SOC.The UART_EE_A_REG5[26] is added.
>> UART_EE_A_REG5[26]:
>> - 0x0: divide the input clock by 3 (meaning: this internally works
>> with an 8MHz clock)
>> - 0x1: use the input clock directly without further division (meaning:
>> this internally work with an 24MHz clock)
>> 8MHz is recommended for this part of SOC. Their UART IP configuration is
>> the same.
>>
>> G12A/B,,SM1,A1 and S4 SOC.The UART_EE_A_REG5[27] is added.
>> UART_EE_A_REG5[27]:
>> - 0x0: use the clock as configured in UART_EE_A_REG5[26]
>> - 0x1: divide the input clock by 2 (meaning: this internally works
>> with an 12MHz clock)
>> 12MHz is recommended for this part of SOC.
>>
>> NOTE:
>> 1. clk81 /4 divider.
>> There is a 4 divider inside, this is what the internal SOC designer told
>> me. But they forgot to document it. So it makes people feel suspicious.
>>
>> 2.The UART_EE_A_REG5 default value is 0,except for the console port(set in
>> romcode).All the baud rate clocks supported by UART can work, but different
>> chip usage scenarios suggest using that clock to reduce jitter.
>>
>> In summary, I would like to know your suggestions, including how to change
>> compatible.
>> Thank you so much!
> 
>  From your comment, gxbb should have "true" instead of false, isn't it ?
> 
Yes, You are right.
I don't see the need to split "amlogic, meson-gx-uart" compatible right 
now. I think the following change
{
.compatible = "amlogic,meson-gx-uart",
.data = (void *)true,
},
can satisfy all UART IP using XTAL. Because CCF automatically selects an 
appropriate clock source when setting baud rate.

I wonder if you agree with that. Or maybe you have a better idea. I'd 
like to know your opinion
>>
>>   >>
>>>> -	port->uartclk = clk_get_rate(clk_baud);
>>>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>>>> +					CLK_NAME(use_xtal),
>>>> +					ARRAY_SIZE(use_xtal_mux_parents),
>>>> +					NULL, NULL,
>>>> +					use_xtal_mux_parents,
>>>> +					CLK_SET_RATE_PARENT,
>>>> +					port->membase + AML_UART_REG5,
>>>> +					24, 0x1,
>>>> +					CLK_MUX_READ_ONLY,
>>>> +					NULL, NULL);
>>>> +	if (IS_ERR(hw))
>>>> +		return PTR_ERR(hw);
>>>> +
>>>> +	port->uartclk = clk_hw_get_rate(hw);
>>>> +
>>>> +	hw = devm_clk_hw_register_divider(port->dev,
>>>> +					  CLK_NAME(baud_div),
>>>> +					  clk_hw_get_name(hw),
>>>> +					  CLK_SET_RATE_PARENT,
>>>> +					  port->membase + AML_UART_REG5,
>>>> +					  0, 23,
>>>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>>>> +					  NULL);
>>>> +	if (IS_ERR(hw))
>>>> +		return PTR_ERR(hw);
>>>> +
>>>> +	private_data->baud_clk = clk_hw_get_clk(hw, "baud_rate");
>>> I have already commented on the use of this function in the previous
>>> version.
>>> Please make sure all comments are addressed before re-posting
>>>
>> I'm sorry. I misunderstood you earlier. I will be changed to
>> "private_data->baud_clk = hw->clk;".What do you think?
> 
> yes
> 
>>>>      	return 0;
>>>>    }
>>>>      static int meson_uart_probe(struct platform_device *pdev)
>>>>    {
>>>> +	struct meson_uart_data *private_data;
>>>>    	struct resource *res_mem;
>>>>    	struct uart_port *port;
>>>>    	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>>> @@ -716,18 +783,20 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    		return -EBUSY;
>>>>    	}
>>>>    -	port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port),
>>>> GFP_KERNEL);
>>>> -	if (!port)
>>>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>>>> +				    GFP_KERNEL);
>>>> +	if (!private_data)
>>>>    		return -ENOMEM;
>>>>    +	if (device_get_match_data(&pdev->dev))
>>>> +		private_data->use_xtal_clk = true;
>>>> +
>>>> +	port = &private_data->port;
>>>> +
>>>>    	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
>>>>    	if (IS_ERR(port->membase))
>>>>    		return PTR_ERR(port->membase);
>>>>    -	ret = meson_uart_probe_clocks(pdev, port);
>>>> -	if (ret)
>>>> -		return ret;
>>>> -
>>>>    	port->iotype = UPIO_MEM;
>>>>    	port->mapbase = res_mem->start;
>>>>    	port->mapsize = resource_size(res_mem);
>>>> @@ -740,7 +809,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>>>    	port->x_char = 0;
>>>>    	port->ops = &meson_uart_ops;
>>>>    	port->fifosize = fifosize;
>>>> +	port->private_data = private_data;
>>> port has private_data
>>> private_data has port
>>> Is it really necessary to have both ... looks to me that port in
>>> private_data is overkill
>>>
>> It's very thoughtful of you. I'll delete it as you suggested.
>>>>    +	ret = meson_uart_probe_clocks(port);
>>>> +	if (ret)
>>>> +		return ret;
>>>>    	meson_ports[pdev->id] = port;
>>>>    	platform_set_drvdata(pdev, port);
>>>>    @@ -766,10 +839,39 @@ static int meson_uart_remove(struct
>>>> platform_device *pdev)
>>>>    }
>>>>      static const struct of_device_id meson_uart_dt_match[] = {
>>>> -	{ .compatible = "amlogic,meson6-uart" },
>>>> -	{ .compatible = "amlogic,meson8-uart" },
>>>> -	{ .compatible = "amlogic,meson8b-uart" },
>>>> -	{ .compatible = "amlogic,meson-gx-uart" },
>>>> +	{
>>>> +		.compatible = "amlogic,meson6-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson8b-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxbb-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gxl-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	{
>>>> +		.compatible = "amlogic,meson-g12a-uart",
>>>> +		.data = (void *)true,
>>>> +	},
>>>> +	/*
>>>> +	 * deprecated, don't use anymore because it doesn't differentiate
>>>> +	 * between GXBB, GXL and G12A which have different revisions
>>>> +	 * of the UART IP.
>>>> +	 */
>>>> +	{
>>>> +		.compatible = "amlogic,meson-gx-uart",
>>>> +		.data = (void *)false,
>>>> +	},
>>>>    	{ /* sentinel */ },
>>>>    };
>>>>    MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
>>>
>>
>> _______________________________________________
>> linux-amlogic mailing list
>> linux-amlogic at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 


From miles.chen at mediatek.com  Mon Jan 17 01:00:29 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Mon, 17 Jan 2022 17:00:29 +0800
Subject: [PATCH] clk: mediatek: add unregister logic to mtk_clk_simple_probe
 error path
Message-ID: <20220117090030.13064-1-miles.chen@mediatek.com>

Stephen pointed out that there is no unregister logic in
mtk_clk_simple_probe() error path [1].
Fix it by adding unregister logic to mtk_clk_simple_probe().

[1] https://lore.kernel.org/linux-mediatek/20220114221930.660B5C36AE9 at smtp.kernel.org/

Fixes: c58cd0e40ffa ("clk: mediatek: Add mtk_clk_simple_probe() to simplify clock providers")
Cc: Stephen Boyd <sboyd at kernel.org>
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/clk/mediatek/clk-mtk.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 8d5791b3f460..edf21975cb4d 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -161,6 +161,22 @@ int mtk_clk_register_gates(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
 
+static void mtk_clk_unregister_gates(const struct mtk_gate *clks,
+		int num, struct clk_onecell_data *clk_data)
+{
+	int i;
+	const struct mtk_gate *gate;
+	struct clk *clk;
+
+	for (i = 0; i < num; i++) {
+		gate = &clks[i];
+		clk = clk_data->clks[gate->id];
+
+		if (!IS_ERR_OR_NULL(clk))
+			clk_unregister(clk);
+	}
+}
+
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
@@ -320,15 +336,17 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 
 	r = mtk_clk_register_gates(node, mcd->clks, mcd->num_clks, clk_data);
 	if (r)
-		goto free_data;
+		goto err_free_data;
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_data;
+		goto err_unregister_gates;
 
 	return r;
 
-free_data:
+err_unregister_gates:
+	mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
+err_free_data:
 	mtk_free_clk_data(clk_data);
 	return r;
 }
-- 
2.18.0



From amelie.delaunay at foss.st.com  Mon Jan 17 01:17:40 2022
From: amelie.delaunay at foss.st.com (Amelie Delaunay)
Date: Mon, 17 Jan 2022 10:17:40 +0100
Subject: [PATCH] dmaengine: stm32-dma: set dma_device max_sg_burst
Message-ID: <20220117091740.11064-1-amelie.delaunay@foss.st.com>

Some stm32-dma consumers [1] rather use dma_get_slave_caps() to get
max_sg_burst of their DMA channel as dma_get_max_seg_size() is specific to
the DMA controller.
All stm32-dma channels have the same features so, don't need to implement
device_caps ops. Let dma_get_slave_caps() relies on dma_device
configuration.
That's why this patch sets dma_device max_sg_burst to the maximum segment
size, which is the maximum of data items that can be transferred without
software intervention.

[1] https://lore.kernel.org/lkml/20220110103739.118426-1-alain.volmat at foss.st.com/
    "media: stm32: dcmi: create a dma scatterlist based on DMA max_sg_burst value"

Signed-off-by: Amelie Delaunay <amelie.delaunay at foss.st.com>
---
 drivers/dma/stm32-dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 83a37a6955a3..d2365fab1b7a 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -1389,6 +1389,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
 	dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
 	dd->copy_align = DMAENGINE_ALIGN_32_BYTES;
 	dd->max_burst = STM32_DMA_MAX_BURST;
+	dd->max_sg_burst = STM32_DMA_ALIGNED_MAX_DATA_ITEMS;
 	dd->descriptor_reuse = true;
 	dd->dev = &pdev->dev;
 	INIT_LIST_HEAD(&dd->channels);
-- 
2.25.1



From miles.chen at mediatek.com  Mon Jan 17 01:18:04 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Mon, 17 Jan 2022 17:18:04 +0800
Subject: [PATCH 3/3] clk: mediatek: support COMMON_CLK_MT8192 module build
In-Reply-To: <20220114221930.660B5C36AE9@smtp.kernel.org>
References: <20220114221930.660B5C36AE9@smtp.kernel.org>
Message-ID: <20220117091807.13628-1-miles.chen@mediatek.com>

>> I did not try it because we do not unload our clk modules.
>> After testing I understand that the clock driver does not unregister clks
>> we cannot remove then unload it.
>> I think I have to add some unregister logic to these drivers.
>
>Yes

I will do this later.

>
>> >that mtk_clk_simple_probe() doesn't actually unregister anything, it
>> >just frees some allocations. Please fix this before making these
>> >modules.
>> You meant that mtk_clk_simple_probe() has no unregister logic in error pa=
>
>Yes

I post a patch to fix this first:
https://lore.kernel.org/lkml/20220117090030.13064-1-miles.chen at mediatek.com/T/#u

After this, I think that I can use mtk_clk_simple_probe() in other mediatek clk
drivers by submitting some clean up patches.

Miles


From alain.volmat at foss.st.com  Mon Jan 17 01:25:16 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Mon, 17 Jan 2022 10:25:16 +0100
Subject: [PATCH] dmaengine: stm32-dma: set dma_device max_sg_burst
In-Reply-To: <20220117091740.11064-1-amelie.delaunay@foss.st.com>
References: <20220117091740.11064-1-amelie.delaunay@foss.st.com>
Message-ID: <20220117092516.GA431169@gnbcxd0016.gnb.st.com>

Hi,

thanks Amelie.

Tested-by: Alain Volmat <alain.volmat at foss.st.com>

Alain

On Mon, Jan 17, 2022 at 10:17:40AM +0100, Amelie Delaunay wrote:
> Some stm32-dma consumers [1] rather use dma_get_slave_caps() to get
> max_sg_burst of their DMA channel as dma_get_max_seg_size() is specific to
> the DMA controller.
> All stm32-dma channels have the same features so, don't need to implement
> device_caps ops. Let dma_get_slave_caps() relies on dma_device
> configuration.
> That's why this patch sets dma_device max_sg_burst to the maximum segment
> size, which is the maximum of data items that can be transferred without
> software intervention.
> 
> [1] https://lore.kernel.org/lkml/20220110103739.118426-1-alain.volmat at foss.st.com/
>     "media: stm32: dcmi: create a dma scatterlist based on DMA max_sg_burst value"
> 
> Signed-off-by: Amelie Delaunay <amelie.delaunay at foss.st.com>
> ---
>  drivers/dma/stm32-dma.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
> index 83a37a6955a3..d2365fab1b7a 100644
> --- a/drivers/dma/stm32-dma.c
> +++ b/drivers/dma/stm32-dma.c
> @@ -1389,6 +1389,7 @@ static int stm32_dma_probe(struct platform_device *pdev)
>  	dd->residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
>  	dd->copy_align = DMAENGINE_ALIGN_32_BYTES;
>  	dd->max_burst = STM32_DMA_MAX_BURST;
> +	dd->max_sg_burst = STM32_DMA_ALIGNED_MAX_DATA_ITEMS;
>  	dd->descriptor_reuse = true;
>  	dd->dev = &pdev->dev;
>  	INIT_LIST_HEAD(&dd->channels);
> -- 
> 2.25.1
> 


From hverkuil-cisco at xs4all.nl  Mon Jan 17 01:28:38 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Mon, 17 Jan 2022 10:28:38 +0100
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <98096e97-68cc-18fd-d2b6-3477f57f05bd@aspeedtech.com>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
 <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
 <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>
 <CACPK8XeJQHLWfVbBjArxV_QMDDnRXfccOeXdsn6aBEG7gd8yvw@mail.gmail.com>
 <98096e97-68cc-18fd-d2b6-3477f57f05bd@aspeedtech.com>
Message-ID: <d4ccf803-3736-d95d-19a9-f3593465b81e@xs4all.nl>

Hi Jammy,

On 1/17/22 08:18, Jammy Huang wrote:
> On 2022/1/17 ?? 10:24, Joel Stanley wrote:
>> On Mon, 17 Jan 2022 at 02:00, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>>> Hi Hans,
>>>
>>> On 2022/1/14 ?? 04:11, Hans Verkuil wrote:
>>>> On 24/12/2021 02:27, Jammy Huang wrote:
>>>>> This introduces support for the Aspeed JPEG format, where the new frame
>>>>> can refer to previous frame to reduce the amount of compressed data. The
>>>>> concept is similar to I/P frame of video compression. It will compare the
>>>>> new frame with previous one to decide which macroblock's data is
>>>>> changed, and only the changed macroblocks will be compressed.
>>>>>
>>>>> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
>>>>> which is generally adapted for remote KVM.
>>>>>
>>>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>>>> ---
>>>>> v8:
>>>>> ??? - Add decoder information for aspeed-jpeg
>>>>> v7:
>>>>> ??? - Add more information for aspeed-jpeg
>>>>> v6:
>>>>> ??? - Update description for new format, aspeed-jpeg, in Documentation.
>>>>> v5:
>>>>> ??? - no update
>>>>> v4:
>>>>> ??? - new
>>>>> ---
>>>>> ?? .../media/uapi/v4l/pixfmt-reserved.rst????????? | 17 +++++++++++++++++
>>>>> ?? drivers/media/v4l2-core/v4l2-ioctl.c??????????? |? 1 +
>>>>> ?? include/uapi/linux/videodev2.h????????????????? |? 1 +
>>>>> ?? 3 files changed, 19 insertions(+)
>>>>>
>>>>> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>> This is the wrong file! It should be:
>>>>
>>>> Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>>> Thanks, I just used git format-patch to generate the cover-letter and
>>> didn't notice this.
>>>
>>> It looks like the file, pixfmt-reserved.rst, has different path in
>>> different Linux kernel,
>>>
>>> * 5.4:?????????? Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>
>>> * 5.10/5.15: Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>>>
>>> 5.4 is the one I based to submit the patches.
>>>
>>> Could you suggest the kernel that I should based to submit these patches??
>> You should always submit based on the latest release.
>>
>> There are sometimes exceptions where you will base your patches on
>> something even newer, but generally you should grab the latest.
>>
>> Be sure to re-test on the latest kernel before submitting.
> OK, thank you.

I recommend waiting until later this week. I hope to have a PR for other outstanding
aspeed patches ready in a few days. It is easiest if you base your v9 on top of that
series, this to avoid merge conflicts.

Regards,

	Hans

>>
>> Cheers,
>>
>> Joel
>>
>>> I will need to change the number of V4L2_CID_USER_ASPEED_BASE per different
>>>
>>> linux kernel as well.
>>>
>>>> Regards,
>>>>
>>>> ?????? Hans
>>>>
>>>>> index b2cd155e691b..1d0dc8d86ed7 100644
>>>>> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
>>>>> ????? of tiles, resulting in 32-aligned resolutions for the luminance plane
>>>>> ????? and 16-aligned resolutions for the chrominance plane (with 2x2
>>>>> ????? subsampling).
>>>>> +??? * .. _V4L2-PIX-FMT-AJPG:
>>>>> +
>>>>> +????? - ``V4L2_PIX_FMT_AJPG``
>>>>> +????? - 'AJPG'
>>>>> +????? - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
>>>>> +??????? which is generally adapted for remote KVM.
>>>>> +??????? On each frame compression, I will compare the new frame with previous
>>>>> +??????? one to decide which macroblock's data is changed, and only the changed
>>>>> +??????? macroblocks will be compressed.
>>>>> +
>>>>> +??????? The implementation is based on AST2600 A3 datasheet, revision 0.9, which
>>>>> +??????? is not publicly available. Or you can reference Video stream data format
>>>>> +??????? ? ASPEED mode compression of SDK_User_Guide which available on
>>>>> +??????? AspeedTech-BMC/openbmc/releases.
>>>>> +
>>>>> +??????? Decoder's implementation can be found here,
>>>>> +??????? `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
>>>>>
>>>>> ?? .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>>>>>
>>>>> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>> index 24db33f803c0..00dde01d2f97 100644
>>>>> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>>>>> ????????????? case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
>>>>> ????????????? case V4L2_PIX_FMT_MT21C:??????? descr = "Mediatek Compressed Format"; break;
>>>>> ????????????? case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
>>>>> +??????????? case V4L2_PIX_FMT_AJPG:???????? descr = "Aspeed JPEG"; break;
>>>>> ????????????? default:
>>>>> ????????????????????? if (fmt->description[0])
>>>>> ????????????????????????????? return;
>>>>> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
>>>>> index 3210b3c82a4a..994eb6155ea9 100644
>>>>> --- a/include/uapi/linux/videodev2.h
>>>>> +++ b/include/uapi/linux/videodev2.h
>>>>> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
>>>>> ?? #define V4L2_PIX_FMT_INZI???? v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
>>>>> ?? #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
>>>>> ?? #define V4L2_PIX_FMT_CNF4???? v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
>>>>> +#define V4L2_PIX_FMT_AJPG???? v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
>>>>>
>>>>> ?? /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
>>>>> ?? #define V4L2_PIX_FMT_IPU3_SBGGR10? v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
>>> -- 
>>> Best Regards
>>> Jammy
>>>


From jammy_huang at aspeedtech.com  Mon Jan 17 01:37:41 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 17 Jan 2022 17:37:41 +0800
Subject: [PATCH v8 1/4] media: v4l: Add definition for the Aspeed JPEG
 format
In-Reply-To: <d4ccf803-3736-d95d-19a9-f3593465b81e@xs4all.nl>
References: <20211224012738.1551-1-jammy_huang@aspeedtech.com>
 <20211224012738.1551-2-jammy_huang@aspeedtech.com>
 <703ff71e-c76a-9df1-c644-04efed0199ca@xs4all.nl>
 <609cfe9e-2fd8-b31a-9d71-b83d61693f84@aspeedtech.com>
 <CACPK8XeJQHLWfVbBjArxV_QMDDnRXfccOeXdsn6aBEG7gd8yvw@mail.gmail.com>
 <98096e97-68cc-18fd-d2b6-3477f57f05bd@aspeedtech.com>
 <d4ccf803-3736-d95d-19a9-f3593465b81e@xs4all.nl>
Message-ID: <dbfebef8-89e6-c2e1-e81a-57640f6764e7@aspeedtech.com>

Hi Hans,

On 2022/1/17 ?? 05:28, Hans Verkuil wrote:
> Hi Jammy,
>
> On 1/17/22 08:18, Jammy Huang wrote:
>> On 2022/1/17 ?? 10:24, Joel Stanley wrote:
>>> On Mon, 17 Jan 2022 at 02:00, Jammy Huang <jammy_huang at aspeedtech.com> wrote:
>>>> Hi Hans,
>>>>
>>>> On 2022/1/14 ?? 04:11, Hans Verkuil wrote:
>>>>> On 24/12/2021 02:27, Jammy Huang wrote:
>>>>>> This introduces support for the Aspeed JPEG format, where the new frame
>>>>>> can refer to previous frame to reduce the amount of compressed data. The
>>>>>> concept is similar to I/P frame of video compression. It will compare the
>>>>>> new frame with previous one to decide which macroblock's data is
>>>>>> changed, and only the changed macroblocks will be compressed.
>>>>>>
>>>>>> This Aspeed JPEG format is used by the video engine on Aspeed platforms,
>>>>>> which is generally adapted for remote KVM.
>>>>>>
>>>>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>>>>> ---
>>>>>> v8:
>>>>>>  ??? - Add decoder information for aspeed-jpeg
>>>>>> v7:
>>>>>>  ??? - Add more information for aspeed-jpeg
>>>>>> v6:
>>>>>>  ??? - Update description for new format, aspeed-jpeg, in Documentation.
>>>>>> v5:
>>>>>>  ??? - no update
>>>>>> v4:
>>>>>>  ??? - new
>>>>>> ---
>>>>>>  ?? .../media/uapi/v4l/pixfmt-reserved.rst????????? | 17 +++++++++++++++++
>>>>>>  ?? drivers/media/v4l2-core/v4l2-ioctl.c??????????? |? 1 +
>>>>>>  ?? include/uapi/linux/videodev2.h????????????????? |? 1 +
>>>>>>  ?? 3 files changed, 19 insertions(+)
>>>>>>
>>>>>> diff --git a/Documentation/media/uapi/v4l/pixfmt-reserved.rst b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>> This is the wrong file! It should be:
>>>>>
>>>>> Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>>>> Thanks, I just used git format-patch to generate the cover-letter and
>>>> didn't notice this.
>>>>
>>>> It looks like the file, pixfmt-reserved.rst, has different path in
>>>> different Linux kernel,
>>>>
>>>> * 5.4:?????????? Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>
>>>> * 5.10/5.15: Documentation/userspace-api/media/v4l/pixfmt-reserved.rst
>>>>
>>>> 5.4 is the one I based to submit the patches.
>>>>
>>>> Could you suggest the kernel that I should based to submit these patches??
>>> You should always submit based on the latest release.
>>>
>>> There are sometimes exceptions where you will base your patches on
>>> something even newer, but generally you should grab the latest.
>>>
>>> Be sure to re-test on the latest kernel before submitting.
>> OK, thank you.
> I recommend waiting until later this week. I hope to have a PR for other outstanding
> aspeed patches ready in a few days. It is easiest if you base your v9 on top of that
> series, this to avoid merge conflicts.

Sure, no problem. Thanks for your help.


Regards,

Jammy

>
> Regards,
>
> 	Hans
>
>>> Cheers,
>>>
>>> Joel
>>>
>>>> I will need to change the number of V4L2_CID_USER_ASPEED_BASE per different
>>>>
>>>> linux kernel as well.
>>>>
>>>>> Regards,
>>>>>
>>>>>  ?????? Hans
>>>>>
>>>>>> index b2cd155e691b..1d0dc8d86ed7 100644
>>>>>> --- a/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>>> +++ b/Documentation/media/uapi/v4l/pixfmt-reserved.rst
>>>>>> @@ -264,6 +264,23 @@ please make a proposal on the linux-media mailing list.
>>>>>>  ????? of tiles, resulting in 32-aligned resolutions for the luminance plane
>>>>>>  ????? and 16-aligned resolutions for the chrominance plane (with 2x2
>>>>>>  ????? subsampling).
>>>>>> +??? * .. _V4L2-PIX-FMT-AJPG:
>>>>>> +
>>>>>> +????? - ``V4L2_PIX_FMT_AJPG``
>>>>>> +????? - 'AJPG'
>>>>>> +????? - ASPEED JPEG format used by the aspeed-video driver on Aspeed platforms,
>>>>>> +??????? which is generally adapted for remote KVM.
>>>>>> +??????? On each frame compression, I will compare the new frame with previous
>>>>>> +??????? one to decide which macroblock's data is changed, and only the changed
>>>>>> +??????? macroblocks will be compressed.
>>>>>> +
>>>>>> +??????? The implementation is based on AST2600 A3 datasheet, revision 0.9, which
>>>>>> +??????? is not publicly available. Or you can reference Video stream data format
>>>>>> +??????? ? ASPEED mode compression of SDK_User_Guide which available on
>>>>>> +??????? AspeedTech-BMC/openbmc/releases.
>>>>>> +
>>>>>> +??????? Decoder's implementation can be found here,
>>>>>> +??????? `https://github.com/AspeedTech-BMC/aspeed_codec/ <https://github.com/AspeedTech-BMC/aspeed_codec/>`__
>>>>>>
>>>>>>  ?? .. tabularcolumns:: |p{6.6cm}|p{2.2cm}|p{8.7cm}|
>>>>>>
>>>>>> diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>>> index 24db33f803c0..00dde01d2f97 100644
>>>>>> --- a/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>>> +++ b/drivers/media/v4l2-core/v4l2-ioctl.c
>>>>>> @@ -1378,6 +1378,7 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
>>>>>>  ????????????? case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break;
>>>>>>  ????????????? case V4L2_PIX_FMT_MT21C:??????? descr = "Mediatek Compressed Format"; break;
>>>>>>  ????????????? case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break;
>>>>>> +??????????? case V4L2_PIX_FMT_AJPG:???????? descr = "Aspeed JPEG"; break;
>>>>>>  ????????????? default:
>>>>>>  ????????????????????? if (fmt->description[0])
>>>>>>  ????????????????????????????? return;
>>>>>> diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
>>>>>> index 3210b3c82a4a..994eb6155ea9 100644
>>>>>> --- a/include/uapi/linux/videodev2.h
>>>>>> +++ b/include/uapi/linux/videodev2.h
>>>>>> @@ -726,6 +726,7 @@ struct v4l2_pix_format {
>>>>>>  ?? #define V4L2_PIX_FMT_INZI???? v4l2_fourcc('I', 'N', 'Z', 'I') /* Intel Planar Greyscale 10-bit and Depth 16-bit */
>>>>>>  ?? #define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') /* Sunxi Tiled NV12 Format */
>>>>>>  ?? #define V4L2_PIX_FMT_CNF4???? v4l2_fourcc('C', 'N', 'F', '4') /* Intel 4-bit packed depth confidence information */
>>>>>> +#define V4L2_PIX_FMT_AJPG???? v4l2_fourcc('A', 'J', 'P', 'G') /* Aspeed JPEG */
>>>>>>
>>>>>>  ?? /* 10bit raw bayer packed, 32 bytes for every 25 pixels, last LSB 6 bits unused */
>>>>>>  ?? #define V4L2_PIX_FMT_IPU3_SBGGR10? v4l2_fourcc('i', 'p', '3', 'b') /* IPU3 packed 10-bit BGGR bayer */
>>>> -- 
>>>> Best Regards
>>>> Jammy
>>>>


From yunfei.dong at mediatek.com  Mon Jan 17 01:39:46 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:46 +0800
Subject: [PATCH v5, 00/15] media: mtk-vcodec: support for MT8192 decoder
Message-ID: <20220117094001.20049-1-yunfei.dong@mediatek.com>

This series adds support for mt8192 h264/vp8/vp9 decoder drivers. Firstly, refactor
power/clock/interrupt interfaces for mt8192 is lat and core architecture.

Secondly, add new functions to get frame buffer size and resolution according
to decoder capability from scp side. Then add callback function to get/put
capture buffer in order to enable lat and core decoder in parallel. 

Then add to support MT21C compressed mode and fix v4l2-compliance fail.

Next, extract H264 request api driver to let mt8183 and mt8192 use the same
code, and adds mt8192 frame based h264 driver for stateless decoder.

Lastly, add vp8 and vp9 stateless decoder drivers.

Patches 1 refactor power/clock/interrupt interface.
Patches 2~4 get frame buffer size and resolution according to decoder capability.
Patches 5~6 enable lat and core decode in parallel.
Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail.
patch 11 record capture queue format type.
Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder.
Patch 14~15 add vp8 and vp9 stateless decoder drivers.
---
changes compared with v4:
- fix checkpatch.pl fail.
- fix kernel-doc fail.
- rebase to the latest media codec driver.
changes compared with v3:
- remove enum mtk_chip for patch 2.
- add vp8 stateless decoder drivers for patch 14.
- add vp9 stateless decoder drivers for patch 15.
changes compared with v2:
- add new patch 11 to record capture queue format type.
- separate patch 4 according to tzung-bi's suggestion.
- re-write commit message for patch 5 according to tzung-bi's suggestion.
changes compared with v1:
- rewrite commit message for patch 12.
- rewrite cover-letter message.
---
Yunfei Dong (15):
  media: mtk-vcodec: Add vdec enable/disable hardware helpers
  media: mtk-vcodec: Using firmware type to separate different firmware
    architecture
  media: mtk-vcodec: get capture queue buffer size from scp
  media: mtk-vcodec: Read max resolution from dec_capability
  media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer
    buffered
  media: mtk-vcodec: Refactor get and put capture buffer flow
  media: mtk-vcodec: Refactor supported vdec formats and framesizes
  media: mtk-vcodec: Add format to support MT21C
  media: mtk-vcodec: disable vp8 4K capability
  media: mtk-vcodec: Fix v4l2-compliance fail
  media: mtk-vcodec: record capture queue format type
  media: mtk-vcodec: Extract H264 common code
  media: mtk-vcodec: support stateless H.264 decoding for mt8192
  media: mtk-vcodec: support stateless VP8 decoding
  media: mtk-vcodec: support stateless VP9 decoding

 drivers/media/platform/mtk-vcodec/Makefile    |    4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   47 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |    5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  168 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |    6 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   14 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  281 ++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   40 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |    5 -
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |    6 +
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |    1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    |  307 +++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    |  253 +++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  411 +---
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  |  599 +++++
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         |  440 ++++
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 1973 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   36 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    3 +
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |   36 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      |    2 +
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |   53 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   15 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |    2 +-
 include/linux/remoteproc/mtk_scp.h            |    2 +
 25 files changed, 4128 insertions(+), 581 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:47 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:47 +0800
Subject: [PATCH v5,
 01/15] media: mtk-vcodec: Add vdec enable/disable hardware helpers
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-2-yunfei.dong@mediatek.com>

Lock, power and clock are highly coupled operations. Adds vdec
enable/disable hardware helpers and uses them.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 168 +++++++++++-------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |   6 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  20 +--
 .../platform/mtk-vcodec/vdec_msg_queue.c      |   2 +
 5 files changed, 117 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 86b639d82be8..6b52eaeedafa 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -195,9 +195,6 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
-		if (ret < 0)
-			goto err_load_fw;
 		/*
 		 * Does nothing if firmware was already loaded.
 		 */
@@ -254,8 +251,6 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_dec_release(ctx);
 
-	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 44035a50e335..1581a1277473 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -79,74 +79,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return -EINVAL;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int ret, i;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		enable_irq(subdev_dev->dec_irq);
-	} else {
-		pm = &vdec_dev->pm;
-		enable_irq(vdec_dev->dec_irq);
-	}
-
 	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
@@ -168,31 +125,120 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int i;
 
+	dec_clk = &pm->vdec_clk;
+	mtk_smi_larb_put(pm->larbvdec);
+	for (i = dec_clk->clk_num - 1; i >= 0; i--)
+		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+}
+
+static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
 	if (vdec_dev->vdec_pdata->is_subdev_supported) {
 		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
+		if (subdev_dev)
+			enable_irq(subdev_dev->dec_irq);
+		else
+			mtk_v4l2_err("Failed to get hw dev\n");
+	} else {
+		enable_irq(vdec_dev->dec_irq);
+	}
+}
+
+static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			disable_irq(subdev_dev->dec_irq);
+		else
 			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		disable_irq(subdev_dev->dec_irq);
 	} else {
-		pm = &vdec_dev->pm;
 		disable_irq(vdec_dev->dec_irq);
 	}
+}
 
-	dec_clk = &pm->vdec_clk;
-	mtk_smi_larb_put(pm->larbvdec);
-	for (i = dec_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
+						   int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return NULL;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			return &subdev_dev->pm;
+
+		mtk_v4l2_err("Failed to get hw dev\n");
+		return NULL;
+	}
+
+	return &vdec_dev->pm;
+}
+
+static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
+					int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_pw_on(pm);
+		mtk_vcodec_dec_clock_on(pm);
+	}
+}
+
+static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
+					 int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_clock_off(pm);
+		mtk_vcodec_dec_pw_off(pm);
+	}
+}
+
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
+
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+	    hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
+	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
+
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+	    hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_off(ctx->dev, MTK_VDEC_LAT0);
+
+	mutex_unlock(&ctx->dev->dec_mutex[hw_idx]);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_disable_hardware);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 3cc721bbfaf6..dbcf3cabe6f3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -11,9 +11,7 @@
 
 int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 05a5b240e906..c93dd0ea3537 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -38,11 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -70,15 +68,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 	if (!ctx->drv_handle)
 		return -EIO;
 
-	mtk_vdec_lock(ctx);
-
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
-
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -103,11 +97,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return;
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	ctx->drv_handle = NULL;
 }
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index 4b062a8128b4..ae500980ad45 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -212,11 +212,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
 		return;
 
 	ctx = lat_buf->ctx;
+	mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
 	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
 
 	lat_buf->core_decode(lat_buf);
 
 	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
 	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
 
 	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:48 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:48 +0800
Subject: [PATCH v5,
 02/15] media: mtk-vcodec: Using firmware type to separate different
 firmware architecture
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-3-yunfei.dong@mediatek.com>

MT8173 platform use vpu firmware, mt8183/mt8192 will use scp
firmware instead, using chip name is not reasonable to separate
different firmware architecture. Using firmware type is much better.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c   |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c  |  2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h  | 13 -------------
 .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  5 -----
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c   |  6 ++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h   |  1 +
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c     |  4 ++--
 drivers/media/platform/mtk-vcodec/venc_vpu_if.c     |  2 +-
 8 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 04ca43c77e5f..7966c132be8f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -613,7 +613,6 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
-	.chip = MTK_MT8173,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23d997ac114d..5aebf88f997b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -343,7 +343,6 @@ static struct vb2_ops mtk_vdec_request_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
-	.chip = MTK_MT8183,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
@@ -362,7 +361,6 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 
 /* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
-	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 94b47b7c912b..5056abe3d2be 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -335,13 +335,6 @@ struct mtk_vcodec_ctx {
 	struct vdec_msg_queue msg_queue;
 };
 
-enum mtk_chip {
-	MTK_MT8173,
-	MTK_MT8183,
-	MTK_MT8192,
-	MTK_MT8195,
-};
-
 /*
  * enum mtk_vdec_hw_arch - Used to separate different hardware architecture
  */
@@ -367,7 +360,6 @@ enum mtk_vdec_hw_arch {
  * @vdec_framesizes: supported video decoder frame sizes
  * @num_framesizes: count of video decoder frame sizes
  *
- * @chip: chip this decoder is compatible with
  * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
@@ -390,7 +382,6 @@ struct mtk_vcodec_dec_pdata {
 	const struct mtk_codec_framesizes *vdec_framesizes;
 	const int num_framesizes;
 
-	enum mtk_chip chip;
 	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
@@ -400,8 +391,6 @@ struct mtk_vcodec_dec_pdata {
 /**
  * struct mtk_vcodec_enc_pdata - compatible data for each IC
  *
- * @chip: chip this encoder is compatible with
- *
  * @uses_ext: whether the encoder uses the extended firmware messaging format
  * @min_bitrate: minimum supported encoding bitrate
  * @max_bitrate: maximum supported encoding bitrate
@@ -412,8 +401,6 @@ struct mtk_vcodec_dec_pdata {
  * @core_id: stand for h264 or vp8 encode index
  */
 struct mtk_vcodec_enc_pdata {
-	enum mtk_chip chip;
-
 	bool uses_ext;
 	unsigned long min_bitrate;
 	unsigned long max_bitrate;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..3ac6969c54c0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -378,7 +378,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 }
 
 static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
 	.output_formats = mtk_video_formats_output,
@@ -389,7 +388,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_vp8,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_vp8),
 	.output_formats = mtk_video_formats_output,
@@ -400,7 +398,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
-	.chip = MTK_MT8183,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -412,7 +409,6 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
-	.chip = MTK_MT8192,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -424,7 +420,6 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
-	.chip = MTK_MT8195,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
index 94b39ae5c2e1..556e54aadac9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
@@ -65,3 +65,9 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
 	return fw->ops->ipi_send(fw, id, buf, len, wait);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_send);
+
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
+{
+	return fw->type;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
index 539bb626772c..acd355961e3a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
@@ -39,5 +39,6 @@ int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
 			       const char *name, void *priv);
 int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
 			   void *buf, unsigned int len, unsigned int wait);
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
 
 #endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index dd35d2c5f920..7210061c772f 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -33,8 +33,8 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	 */
 	vpu->inst_id = 0xdeadbeef;
 
-	/* Firmware version field does not exist on MT8173. */
-	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
+	/* VPU firmware does not contain a version field. */
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index e7899d8a3e4e..d3570c4c177d 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -18,7 +18,7 @@ static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
 					     msg->vpu_inst_addr);
 
 	/* Firmware version field value is unspecified on MT8173. */
-	if (vpu->ctx->dev->venc_pdata->chip == MTK_MT8173)
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:54 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:54 +0800
Subject: [PATCH v5, 08/15] media: mtk-vcodec: Add format to support MT21C
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-9-yunfei.dong@mediatek.com>

Needs to use mediatek compressed mode for mt8192 decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c   | 7 ++++++-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h         | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 21c97781d50a..0019f8ff614b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,7 +81,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_video_fmt mtk_video_formats[3];
 static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
 
 static struct mtk_video_fmt default_out_format;
@@ -359,6 +359,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 		num_framesizes++;
 		break;
 	case V4L2_PIX_FMT_MM21:
+	case V4L2_PIX_FMT_MT21C:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
 		mtk_video_formats[count_formats].num_planes = 2;
@@ -384,6 +385,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
 		cap_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx);
+		cap_format_count++;
+	}
 	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 13c12de85edf..aa608ab0a247 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,6 +353,7 @@ enum mtk_vdec_hw_arch {
  */
 enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:53 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:53 +0800
Subject: [PATCH v5,
 07/15] media: mtk-vcodec: Refactor supported vdec formats and
 framesizes
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-8-yunfei.dong@mediatek.com>

Supported output and capture format types for mt8192 are different
with mt8183. Needs to get format types according to decoder capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   8 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 116 +++++++++++++-----
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  13 +-
 4 files changed, 106 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 304f5afbd419..bae43938ee37 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -26,7 +26,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	const struct mtk_video_fmt *fmt;
 	unsigned int k;
 
-	for (k = 0; k < dec_pdata->num_formats; k++) {
+	for (k = 0; k < *dec_pdata->num_formats; k++) {
 		fmt = &dec_pdata->vdec_formats[k];
 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
 			return fmt;
@@ -525,7 +525,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	for (i = 0; i < dec_pdata->num_framesizes; ++i) {
+	for (i = 0; i < *dec_pdata->num_framesizes; ++i) {
 		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
 			continue;
 
@@ -564,7 +564,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 	const struct mtk_video_fmt *fmt;
 	int i, j = 0;
 
-	for (i = 0; i < dec_pdata->num_formats; i++) {
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
 		if (output_queue &&
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
 			continue;
@@ -577,7 +577,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		++j;
 	}
 
-	if (i == dec_pdata->num_formats)
+	if (i == *dec_pdata->num_formats)
 		return -EINVAL;
 
 	fmt = &dec_pdata->vdec_formats[i];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 7966c132be8f..3f33beb9c551 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -37,7 +37,9 @@ static const struct mtk_video_fmt mtk_video_formats[] = {
 	},
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+static const unsigned int num_supported_formats =
+	ARRAY_SIZE(mtk_video_formats);
+
 #define DEFAULT_OUT_FMT_IDX 0
 #define DEFAULT_CAP_FMT_IDX 3
 
@@ -59,7 +61,8 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 	},
 };
 
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+static const unsigned int num_supported_framesize =
+	ARRAY_SIZE(mtk_vdec_framesizes);
 
 /*
  * This function tries to clean all display buffers, the buffers will return
@@ -235,7 +238,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
 	unsigned int k;
 
 	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (k = 0; k < NUM_FORMATS; k++) {
+	for (k = 0; k < num_supported_formats; k++) {
 		fmt = &mtk_video_formats[k];
 		if (fmt->fourcc == pixelformat) {
 			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
@@ -617,11 +620,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
+	.num_formats = &num_supported_formats,
 	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
 	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_supported_framesize,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 6d481410bf89..21c97781d50a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,33 +81,23 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static const struct mtk_video_fmt mtk_video_formats[] = {
-	{
-		.fourcc = V4L2_PIX_FMT_H264_SLICE,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_MM21,
-		.type = MTK_FMT_FRAME,
-		.num_planes = 2,
-	},
+static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+
+static struct mtk_video_fmt default_out_format;
+static struct mtk_video_fmt default_cap_format;
+static unsigned int num_formats;
+static unsigned int num_framesizes;
+
+static struct v4l2_frmsize_stepwise stepwise_fhd = {
+	.min_width = MTK_VDEC_MIN_W,
+	.max_width = MTK_VDEC_MAX_W,
+	.step_width = 16,
+	.min_height = MTK_VDEC_MIN_H,
+	.max_height = MTK_VDEC_MAX_H,
+	.step_height = 16
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX    0
-#define DEFAULT_CAP_FMT_IDX    1
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_H264_SLICE,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
 static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
 					   struct mtk_vcodec_mem *bs, int error)
 {
@@ -350,6 +340,62 @@ const struct media_device_ops mtk_vcodec_media_ops = {
 	.req_queue	= v4l2_m2m_request_queue,
 };
 
+static void mtk_vcodec_add_formats(unsigned int fourcc,
+				   struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata;
+	int count_formats = *pdata->num_formats;
+	int count_framesizes = *pdata->num_framesizes;
+
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264_SLICE:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
+		mtk_video_formats[count_formats].num_planes = 1;
+
+		mtk_vdec_framesizes[count_framesizes].fourcc = fourcc;
+		mtk_vdec_framesizes[count_framesizes].stepwise = stepwise_fhd;
+		num_framesizes++;
+		break;
+	case V4L2_PIX_FMT_MM21:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
+		mtk_video_formats[count_formats].num_planes = 2;
+		break;
+	default:
+		mtk_v4l2_err("Can not add unsupported format type");
+		return;
+	}
+
+	num_formats++;
+	mtk_v4l2_debug(3, "num_formats: %d num_frames:%d dec_capability: 0x%x",
+		       count_formats, count_framesizes, ctx->dev->dec_capability);
+}
+
+static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
+{
+	int cap_format_count = 0, out_format_count = 0;
+
+	if (num_formats && num_framesizes)
+		return;
+
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
+		cap_format_count++;
+	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
+		out_format_count++;
+	}
+
+	if (cap_format_count)
+		default_cap_format = mtk_video_formats[cap_format_count - 1];
+	if (out_format_count)
+		default_out_format =
+			mtk_video_formats[cap_format_count + out_format_count - 1];
+}
+
 static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct vb2_queue *src_vq;
@@ -359,6 +405,10 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 
 	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
 		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+	else
+		ctx->dev->dec_capability |=
+			MTK_VDEC_FORMAT_H264_SLICE | MTK_VDEC_FORMAT_MM21;
+	mtk_vcodec_get_supported_formats(ctx);
 
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
@@ -393,11 +443,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
@@ -413,11 +463,11 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e0b7d2fda632..13c12de85edf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -347,6 +347,15 @@ enum mtk_vdec_hw_arch {
 	MTK_VDEC_LAT_SINGLE_CORE,
 };
 
+/*
+ * struct mtk_vdec_format_types - Structure used to get supported
+ *		  format types according to decoder capability
+ */
+enum mtk_vdec_format_types {
+	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -382,12 +391,12 @@ struct mtk_vcodec_dec_pdata {
 	struct vb2_ops *vdec_vb2_ops;
 
 	const struct mtk_video_fmt *vdec_formats;
-	const int num_formats;
+	const int *num_formats;
 	const struct mtk_video_fmt *default_out_fmt;
 	const struct mtk_video_fmt *default_cap_fmt;
 
 	const struct mtk_codec_framesizes *vdec_framesizes;
-	const int num_framesizes;
+	const int *num_framesizes;
 
 	enum mtk_vdec_hw_arch hw_arch;
 
-- 
2.25.1



From Jonathan.Cameron at Huawei.com  Mon Jan 17 01:47:28 2022
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Mon, 17 Jan 2022 09:47:28 +0000
Subject: [PATCH 20/23] dt-bindings: iio: adc: exynos-adc: Add ADC-V3
 variant
In-Reply-To: <75ae8b8c-e416-5007-b995-f1317ef207d4@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122447epcas5p266d44c8df143229d22dfa700c285a786@epcas5p2.samsung.com>
 <20220113121143.22280-21-alim.akhtar@samsung.com>
 <75ae8b8c-e416-5007-b995-f1317ef207d4@canonical.com>
Message-ID: <20220117094728.000051b8@Huawei.com>

On Thu, 13 Jan 2022 14:32:12 +0100
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:

> On 13/01/2022 13:11, Alim Akhtar wrote:
> > This patch adds a new compatible string for exynos's ADC-V3 variant.
> > 
> > Cc: linux-fsd at tesla.com
> > Signed-off-by: Tamseel Shams <m.shams at samsung.com>
> > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Please cc linux-iio at vger.kernel.org for next version...

> > ---
> >  .../devicetree/bindings/iio/adc/samsung,exynos-adc.yaml          | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> > index 81c87295912c..9303053759ca 100644
> > --- a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> > +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
> > @@ -14,6 +14,7 @@ properties:
> >      enum:
> >        - samsung,exynos-adc-v1                 # Exynos5250
> >        - samsung,exynos-adc-v2
> > +      - samsung,exynos-adc-v3  
> 
> Please use SoC-specific compatible. IP block versions are tricky because:
> 1. Documentation/datasheet mentioning which SoC has which block version
> are not public.
> 2. Neither are public the datasheets for ADC blocks.
> 3. The versioning of IP blocks can be inaccurate.
> 
> 
> Best regards,
> Krzysztof
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:50 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:50 +0800
Subject: [PATCH v5,
 04/15] media: mtk-vcodec: Read max resolution from dec_capability
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-5-yunfei.dong@mediatek.com>

Supported max resolution for different platforms are not the same: 2K
or 4K, getting it according to dec_capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 29 +++++++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 130ecef2e766..304f5afbd419 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -152,13 +152,15 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
 	q_data->field = V4L2_FIELD_NONE;
+	ctx->max_width = MTK_VDEC_MAX_W;
+	ctx->max_height = MTK_VDEC_MAX_H;
 
 	v4l_bound_align_image(&q_data->coded_width,
 				MTK_VDEC_MIN_W,
-				MTK_VDEC_MAX_W, 4,
+				ctx->max_width, 4,
 				&q_data->coded_height,
 				MTK_VDEC_MIN_H,
-				MTK_VDEC_MAX_H, 5, 6);
+				ctx->max_height, 5, 6);
 
 	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
 	q_data->bytesperline[0] = q_data->coded_width;
@@ -217,7 +219,7 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
 	}
 }
 
-static int vidioc_try_fmt(struct v4l2_format *f,
+static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
 			  const struct mtk_video_fmt *fmt)
 {
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
@@ -225,9 +227,9 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 	pix_fmt_mp->field = V4L2_FIELD_NONE;
 
 	pix_fmt_mp->width =
-		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
+		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width);
 	pix_fmt_mp->height =
-		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
+		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height);
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		pix_fmt_mp->num_planes = 1;
@@ -245,16 +247,16 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 		tmp_h = pix_fmt_mp->height;
 		v4l_bound_align_image(&pix_fmt_mp->width,
 					MTK_VDEC_MIN_W,
-					MTK_VDEC_MAX_W, 6,
+					ctx->max_width, 6,
 					&pix_fmt_mp->height,
 					MTK_VDEC_MIN_H,
-					MTK_VDEC_MAX_H, 6, 9);
+					ctx->max_height, 6, 9);
 
 		if (pix_fmt_mp->width < tmp_w &&
-			(pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W)
+			(pix_fmt_mp->width + 64) <= ctx->max_width)
 			pix_fmt_mp->width += 64;
 		if (pix_fmt_mp->height < tmp_h &&
-			(pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H)
+			(pix_fmt_mp->height + 64) <= ctx->max_height)
 			pix_fmt_mp->height += 64;
 
 		mtk_v4l2_debug(0,
@@ -294,7 +296,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
@@ -317,7 +319,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 		return -EINVAL;
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -445,7 +447,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		return -EINVAL;
 
 	q_data->fmt = fmt;
-	vidioc_try_fmt(f, q_data->fmt);
+	vidioc_try_fmt(ctx, f, q_data->fmt);
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
 		q_data->coded_width = pix_mp->width;
@@ -545,6 +547,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 				fsize->stepwise.min_height,
 				fsize->stepwise.max_height,
 				fsize->stepwise.step_height);
+
+		ctx->max_width = fsize->stepwise.max_width;
+		ctx->max_height = fsize->stepwise.max_height;
 		return 0;
 	}
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 5056abe3d2be..2d1d878692ca 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -287,6 +287,8 @@ struct vdec_pic_info {
  *	  mtk_video_dec_buf.
  * @hw_id: hardware index used to identify different hardware.
  *
+ * @max_width: hardware supported max width
+ * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
@@ -332,6 +334,8 @@ struct mtk_vcodec_ctx {
 	struct mutex lock;
 	int hw_id;
 
+	unsigned int max_width;
+	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:59 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:59 +0800
Subject: [PATCH  v5,
 13/15] media: mtk-vcodec: support stateless H.264 decoding for mt8192
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-14-yunfei.dong@mediatek.com>

Adds h264 lat and core architecture driver for mt8192,
and the decode mode is frame based for stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 599 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 include/linux/remoteproc/mtk_scp.h            |   2 +
 5 files changed, 610 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 3f41d748eee5..22edb1c86598 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
+		vdec/vdec_h264_req_multi_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
new file mode 100644
index 000000000000..8d3b13976900
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+#include "vdec_h264_req_common.h"
+
+/**
+ * enum vdec_h264_core_dec_err_type  - core decode error type
+ * @TRANS_BUFFER_FULL : trans buffer is full
+ * @SLICE_HEADER_FULL : slice header buffer is full
+ */
+enum vdec_h264_core_dec_err_type {
+	TRANS_BUFFER_FULL = 1,
+	SLICE_HEADER_FULL,
+};
+
+/**
+ * struct vdec_h264_slice_lat_dec_param  - parameters for decode current frame
+ * @sps : h264 sps syntax parameters
+ * @pps : h264 pps syntax parameters
+ * @slice_header: h264 slice header syntax parameters
+ * @scaling_matrix : h264 scaling list parameters
+ * @decode_params : decoder parameters of each frame used for hardware decode
+ * @h264_dpb_info : dpb reference list
+ */
+struct vdec_h264_slice_lat_dec_param {
+	struct mtk_h264_sps_param sps;
+	struct mtk_h264_pps_param pps;
+	struct mtk_h264_slice_hd_param slice_header;
+	struct slice_api_h264_scaling_matrix scaling_matrix;
+	struct slice_api_h264_decode_param decode_params;
+	struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+/**
+ * struct vdec_h264_slice_info - decode information
+ * @nal_info    : nal info of current picture
+ * @timeout     : Decode timeout: 1 timeout, 0 no timeount
+ * @bs_buf_size : bitstream size
+ * @bs_buf_addr : bitstream buffer dma address
+ * @y_fb_dma    : Y frame buffer dma address
+ * @c_fb_dma    : C frame buffer dma address
+ * @vdec_fb_va  : VDEC frame buffer struct virtual address
+ * @crc         : Used to check whether hardware's status is right
+ */
+struct vdec_h264_slice_info {
+	u16 nal_info;
+	u16 timeout;
+	u32 bs_buf_size;
+	u64 bs_buf_addr;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	u64 vdec_fb_va;
+	u32 crc[8];
+};
+
+/**
+ * struct vdec_h264_slice_vsi - shared memory for decode information exchange
+ *        between VPU and Host. The memory is allocated by VPU then mapping to
+ *        Host in vdec_h264_slice_init() and freed in vdec_h264_slice_deinit()
+ *        by VPU. AP-W/R : AP is writer/reader on this item. VPU-W/R: VPU is
+ *        write/reader on this item.
+ * @wdma_err_addr       : wdma error dma address
+ * @wdma_start_addr     : wdma start dma address
+ * @wdma_end_addr       : wdma end dma address
+ * @slice_bc_start_addr : slice bc start dma address
+ * @slice_bc_end_addr   : slice bc end dma address
+ * @row_info_start_addr : row info start dma address
+ * @row_info_end_addr   : row info end dma address
+ * @trans_start         : trans start dma address
+ * @trans_end           : trans end dma address
+ * @wdma_end_addr_offset: wdma end address offset
+ * @mv_buf_dma          : HW working motion vector buffer
+ *                        dma address (AP-W, VPU-R)
+ * @dec                 : decode information (AP-R, VPU-W)
+ * @h264_slice_params   : decode parameters for hw used
+ */
+struct vdec_h264_slice_vsi {
+	/* LAT dec addr */
+	u64 wdma_err_addr;
+	u64 wdma_start_addr;
+	u64 wdma_end_addr;
+	u64 slice_bc_start_addr;
+	u64 slice_bc_end_addr;
+	u64 row_info_start_addr;
+	u64 row_info_end_addr;
+	u64 trans_start;
+	u64 trans_end;
+	u64 wdma_end_addr_offset;
+
+	u64 mv_buf_dma[H264_MAX_MV_NUM];
+	struct vdec_h264_slice_info dec;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+};
+
+/**
+ * struct vdec_h264_slice_share_info - shared information used to exchange
+ *                                     message between lat and core
+ * @sps	              : sequence header information from user space
+ * @dec_params        : decoder params from user space
+ * @h264_slice_params : decoder params used for hardware
+ * @trans_start       : trans start dma address
+ * @trans_end         : trans end dma address
+ * @nal_info          : nal info of current picture
+ */
+struct vdec_h264_slice_share_info {
+	struct v4l2_ctrl_h264_sps sps;
+	struct v4l2_ctrl_h264_decode_params dec_params;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+	u64 trans_start;
+	u64 trans_end;
+	u16 nal_info;
+};
+
+/**
+ * struct vdec_h264_slice_inst - h264 decoder instance
+ * @slice_dec_num        : how many picture be decoded
+ * @ctx                 : point to mtk_vcodec_ctx
+ * @pred_buf            : HW working predication buffer
+ * @mv_buf              : HW working motion vector buffer
+ * @vpu                 : VPU instance
+ * @vsi                 : vsi used for lat
+ * @vsi_core            : vsi used for core
+ *
+ * @resolution_changed  : resolution changed
+ * @realloc_mv_buf      : reallocate mv buffer
+ * @cap_num_planes      : number of capture queue plane
+ *
+ * @dpb : decoded picture buffer used to store reference buffer information
+ */
+struct vdec_h264_slice_inst {
+	unsigned int slice_dec_num;
+	struct mtk_vcodec_ctx *ctx;
+	struct mtk_vcodec_mem pred_buf;
+	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
+	struct vdec_vpu_inst vpu;
+	struct vdec_h264_slice_vsi *vsi;
+	struct vdec_h264_slice_vsi *vsi_core;
+
+	unsigned int resolution_changed;
+	unsigned int realloc_mv_buf;
+	unsigned int cap_num_planes;
+
+	struct v4l2_h264_dpb_entry dpb[16];
+};
+
+static void vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *inst,
+						   struct vdec_h264_slice_share_info *share_info)
+{
+	struct vdec_h264_slice_lat_dec_param *slice_param =
+		&inst->vsi->h264_slice_params;
+	const struct v4l2_ctrl_h264_decode_params *dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+					   V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+					   V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	const struct v4l2_ctrl_h264_sps *sps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+					   V4L2_CID_STATELESS_H264_SPS);
+	const struct v4l2_ctrl_h264_pps *pps =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx,
+					   V4L2_CID_STATELESS_H264_PPS);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, src_matrix);
+
+	memcpy(&share_info->sps, sps, sizeof(*sps));
+	memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params));
+}
+
+static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *inst,
+						struct vdec_h264_slice_lat_dec_param *slice_param,
+						struct vdec_h264_slice_share_info *share_info)
+{
+	struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
+	struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params,
+					 inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+				    slice_param->h264_dpb_info);
+
+	mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt);
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
+				       inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+
+	/* Adapt the built lists to the firmware's expectations */
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+}
+
+static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+					struct vdec_pic_info *pic)
+{
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
+	struct mtk_vcodec_mem *mem;
+	int i, err;
+
+	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+		mem->size = buf_sz;
+		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+		if (err) {
+			mtk_vcodec_err(inst, "failed to allocate mv buf");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst)
+{
+	int i;
+	struct mtk_vcodec_mem *mem;
+
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+	}
+}
+
+static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+	inst->cap_num_planes =
+		ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
+			 ctx->picinfo.fb_sz[1]);
+
+	if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w ||
+	    ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) {
+		inst->resolution_changed = true;
+		if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w ||
+		    ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h)
+			inst->realloc_mv_buf = true;
+
+		mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
+			       inst->resolution_changed,
+			       inst->realloc_mv_buf,
+			       ctx->last_decoded_picinfo.pic_w,
+			       ctx->last_decoded_picinfo.pic_h,
+			       ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+	}
+}
+
+static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
+					  struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->ctx->picinfo.pic_w;
+	cr->height = inst->ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_h264_slice_inst *inst;
+	int err, vsi_size;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), 64);
+	inst->vsi = inst->vpu.vsi;
+	inst->vsi_core =
+		(struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+	inst->resolution_changed = true;
+	inst->realloc_mv_buf = true;
+
+	mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n",
+			 (int)sizeof(struct mtk_h264_sps_param),
+			 (int)sizeof(struct mtk_h264_pps_param),
+			 (int)sizeof(struct vdec_h264_slice_lat_dec_param),
+			 (int)sizeof(struct mtk_h264_dpb_info),
+			 vsi_size);
+	mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x",
+			 inst, inst->vpu.codec_type);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static void vdec_h264_slice_deinit(void *h_vdec)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_h264_slice_free_mv_buf(inst);
+	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
+
+	kfree(inst);
+}
+
+static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_fb *fb;
+	u64 vdec_fb_va;
+	u64 y_fb_dma, c_fb_dma;
+	int err, timeout, i;
+	struct mtk_vcodec_ctx *ctx = lat_buf->ctx;
+	struct vdec_h264_slice_inst *inst = ctx->drv_handle;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
+	struct mtk_vcodec_mem *mem;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+
+	mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode");
+	memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params,
+	       sizeof(share_info->h264_slice_params));
+
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	vdec_fb_va = (unsigned long)fb;
+
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma =
+			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+			 c_fb_dma);
+
+	inst->vsi_core->dec.y_fb_dma = y_fb_dma;
+	inst->vsi_core->dec.c_fb_dma = c_fb_dma;
+	inst->vsi_core->dec.vdec_fb_va = vdec_fb_va;
+	inst->vsi_core->dec.nal_info = share_info->nal_info;
+	inst->vsi_core->wdma_start_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi_core->wdma_end_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+	inst->vsi_core->trans_start = share_info->trans_start;
+	inst->vsi_core->trans_end = share_info->trans_end;
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi_core->mv_buf_dma[i] = mem->dma_addr;
+	}
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	vb2_v4l2->vb2_buf.timestamp = lat_buf->ts_info.vb2_buf.timestamp;
+	vb2_v4l2->timecode = lat_buf->ts_info.timecode;
+	vb2_v4l2->field = lat_buf->ts_info.field;
+	vb2_v4l2->flags = lat_buf->ts_info.flags;
+	vb2_v4l2->vb2_buf.copied_timestamp =
+		lat_buf->ts_info.vb2_buf.copied_timestamp;
+
+	vdec_h264_slice_fill_decode_reflist(inst, &inst->vsi_core->h264_slice_params,
+					    share_info);
+
+	err = vpu_dec_core(vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "core decode err=%d", err);
+		goto vdec_dec_end;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+	if (timeout)
+		mtk_vcodec_err(inst, "core decode timeout: pic_%d",
+			       ctx->decoded_frame_cnt);
+	inst->vsi_core->dec.timeout = !!timeout;
+
+	vpu_dec_core_end(vpu);
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+			 ctx->decoded_frame_cnt,
+			 inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1],
+			 inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3],
+			 inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5],
+			 inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]);
+
+vdec_dec_end:
+	vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue,
+				       share_info->trans_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, !!err);
+	mtk_vcodec_debug(inst, "core decode done err=%d", err);
+	ctx->decoded_frame_cnt++;
+	return 0;
+}
+
+static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				  struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	int nal_start_idx, err, timeout = 0, i;
+	unsigned int data[2];
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_h264_slice_share_info *share_info;
+	unsigned char *buf;
+	struct mtk_vcodec_mem *mem;
+
+	if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
+				vdec_h264_slice_core_decode,
+				sizeof(*share_info)))
+		return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs) {
+		vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue);
+		return vpu_dec_reset(vpu);
+	}
+
+	lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(inst, "failed to get lat buffer");
+		return -EINVAL;
+	}
+	share_info = lat_buf->private_data;
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	buf = (unsigned char *)bs->va;
+	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
+	if (nal_start_idx < 0) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	inst->vsi->dec.nal_info = buf[nal_start_idx];
+	inst->vsi->dec.bs_buf_addr = (u64)bs->dma_addr;
+	inst->vsi->dec.bs_buf_size = bs->size;
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &lat_buf->ts_info, true);
+
+	vdec_h264_slice_fill_decode_parameters(inst, share_info);
+	*res_chg = inst->resolution_changed;
+	if (inst->resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->realloc_mv_buf) {
+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		inst->resolution_changed = false;
+	}
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi->mv_buf_dma[i] = mem->dma_addr;
+	}
+	inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+
+	inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr;
+	inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx)err:0x%llx",
+			 inst->vsi->wdma_start_addr,
+			 inst->vsi->wdma_end_addr,
+			 inst->vsi->wdma_err_addr);
+
+	mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))",
+			 inst->vsi->slice_bc_start_addr,
+			 inst->vsi->slice_bc_end_addr,
+			 inst->vsi->trans_start,
+			 inst->vsi->trans_end);
+	err = vpu_dec_start(vpu, data, 2);
+	if (err) {
+		mtk_vcodec_debug(inst, "lat decode err: %d", err);
+		goto err_free_fb_out;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+	inst->vsi->dec.timeout = !!timeout;
+
+	err = vpu_dec_end(vpu);
+	if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
+				       share_info->trans_end);
+
+	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+	       sizeof(share_info->h264_slice_params));
+	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	inst->slice_dec_num++;
+
+err_free_fb_out:
+	mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);
+	return err;
+}
+
+static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type,
+				     void *out)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_h264_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*(unsigned int *)out = 6;
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_h264_slice_get_crop_info(inst, out);
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+const struct vdec_common_if vdec_h264_slice_lat_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c93dd0ea3537..c17a7815e1bb 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -20,7 +20,13 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
-		ctx->dec_if = &vdec_h264_slice_if;
+		if (ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) {
+			ctx->dec_if = &vdec_h264_slice_if;
+			ctx->hw_id = MTK_VDEC_CORE;
+		} else {
+			ctx->dec_if = &vdec_h264_slice_lat_if;
+			ctx->hw_id = MTK_VDEC_LAT0;
+		}
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index d467e8af4a84..6ce848e74167 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -56,6 +56,7 @@ struct vdec_fb_node {
 
 extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
+extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
diff --git a/include/linux/remoteproc/mtk_scp.h b/include/linux/remoteproc/mtk_scp.h
index b47416f7aeb8..a32ffd736e7b 100644
--- a/include/linux/remoteproc/mtk_scp.h
+++ b/include/linux/remoteproc/mtk_scp.h
@@ -41,6 +41,8 @@ enum scp_ipi_id {
 	SCP_IPI_ISP_FRAME,
 	SCP_IPI_FD_CMD,
 	SCP_IPI_CROS_HOST_CMD,
+	SCP_IPI_VDEC_LAT,
+	SPC_IPI_VDEC_CORE,
 	SCP_IPI_NS_SERVICE = 0xFF,
 	SCP_IPI_MAX = 0x100,
 };
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:40:00 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:40:00 +0800
Subject: [PATCH  v5, 14/15] media: mtk-vcodec: support stateless VP8 decoding
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-15-yunfei.dong@mediatek.com>

Add support for VP8 decoding using the stateless API,
as supported by MT8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  24 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         | 440 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 6 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 22edb1c86598..b457daf2d196 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
+		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 0019f8ff614b..6d7d07dcb435 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -76,13 +76,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
 		},
 		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP8_FRAME,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
 	}
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[3];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+static struct mtk_video_fmt mtk_video_formats[4];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -350,6 +365,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
+	case V4L2_PIX_FMT_VP8_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -393,6 +409,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP8_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index fde79684106d..e16733fbf0c7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -357,6 +357,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
new file mode 100644
index 000000000000..969568b98251
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
@@ -0,0 +1,440 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/slab.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <uapi/linux/v4l2-controls.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* Decoding picture buffer size (3 reference frames plus current frame) */
+#define VP8_DPB_SIZE			4
+
+/* HW working buffer size (bytes) */
+#define VP8_SEG_ID_SZ		(256 * 1024)
+#define VP8_PP_WRAPY_SZ		(64 * 1024)
+#define VP8_PP_WRAPC_SZ		(64 * 1024)
+#define VP8_VLD_PRED_SZ		(64 * 1024)
+
+/**
+ * struct vdec_vp8_slice_info - decode misc information
+ * @vld_wrapper_dma   : vld wrapper dma address
+ * @seg_id_buf_dma    : seg id dma address
+ * @wrap_y_dma        : wrap y dma address
+ * @wrap_c_dma        : wrap y dma address
+ * @cur_y_fb_dma      : current plane Y frame buffer dma address
+ * @cur_c_fb_dma      : current plane C frame buffer dma address
+ * @bs_dma            : bitstream dma address
+ * @bs_sz             : bitstream size
+ * @resolution_changed: resolution change flag 1 - changed,  0 - not change
+ * @frame_header_type : current frame header type
+ * @wait_key_frame    : wait key frame coming
+ * @crc               : used to check whether hardware's status is right
+ * @timeout           : decode timeout: 1 timeout, 0 no timeount
+ * @reserved:         : reserved, currently unused
+ */
+struct vdec_vp8_slice_info {
+	u64 vld_wrapper_dma;
+	u64 seg_id_buf_dma;
+	u64 wrap_y_dma;
+	u64 wrap_c_dma;
+	u64 cur_y_fb_dma;
+	u64 cur_c_fb_dma;
+	u64 bs_dma;
+	u32 bs_sz;
+	u32 resolution_changed;
+	u32 frame_header_type;
+	u32 crc[8];
+	u32 reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_dpb_info  - vp8 reference information
+ * @y_dma_addr    : Y bitstream physical address
+ * @c_dma_addr    : CbCr bitstream physical address
+ * @reference_flag: reference picture flag
+ * @reserved      : 64bit align
+ */
+struct vdec_vp8_slice_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_vsi - VPU shared information
+ * @dec          : decoding information
+ * @pic          : picture information
+ * @vp8_dpb_info : reference buffer information
+ */
+struct vdec_vp8_slice_vsi {
+	struct vdec_vp8_slice_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_vp8_slice_dpb_info vp8_dpb_info[3];
+};
+
+/**
+ * struct vdec_vp8_slice_inst - VP8 decoder instance
+ * @seg_id_buf     : seg buffer
+ * @wrap_y_buf     : wrapper y buffer
+ * @wrap_c_buf     : wrapper c buffer
+ * @vld_wrapper_buf: vld wrapper buffer
+ * @ctx            : V4L2 context
+ * @vpu            : VPU instance for decoder
+ * @vsi            : VPU share information
+ */
+struct vdec_vp8_slice_inst {
+	struct mtk_vcodec_mem seg_id_buf;
+	struct mtk_vcodec_mem wrap_y_buf;
+	struct mtk_vcodec_mem wrap_c_buf;
+	struct mtk_vcodec_mem vld_wrapper_buf;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+	struct vdec_vp8_slice_vsi *vsi;
+};
+
+static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+static void vdec_vp8_slice_get_crop_info(struct vdec_vp8_slice_inst *inst,
+					 struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->vsi->pic.pic_w;
+	cr->height = inst->vsi->pic.pic_h;
+	mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+
+	inst->vsi->pic.pic_w = ctx->picinfo.pic_w;
+	inst->vsi->pic.pic_h = ctx->picinfo.pic_h;
+	inst->vsi->pic.buf_w = ctx->picinfo.buf_w;
+	inst->vsi->pic.buf_h = ctx->picinfo.buf_h;
+	inst->vsi->pic.fb_sz[0] = ctx->picinfo.fb_sz[0];
+	inst->vsi->pic.fb_sz[1] = ctx->picinfo.fb_sz[1];
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+			 ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]);
+}
+
+static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	int err;
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	mem->size = VP8_SEG_ID_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "Cannot allocate working buffer");
+		return err;
+	}
+	inst->vsi->dec.seg_id_buf_dma = (u64)mem->dma_addr;
+
+	mem = &inst->wrap_y_buf;
+	mem->size = VP8_PP_WRAPY_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP Y buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_y_dma = (u64)mem->dma_addr;
+
+	mem = &inst->wrap_c_buf;
+	mem->size = VP8_PP_WRAPC_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP C buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_c_dma = (u64)mem->dma_addr;
+
+	mem = &inst->vld_wrapper_buf;
+	mem->size = VP8_VLD_PRED_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate vld wrapper buffer");
+		return err;
+	}
+	inst->vsi->dec.vld_wrapper_dma = (u64)mem->dma_addr;
+
+	return 0;
+}
+
+static void vdec_vp8_slice_free_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.seg_id_buf_dma = 0;
+
+	mem = &inst->wrap_y_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_y_dma = 0;
+
+	mem = &inst->wrap_c_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_c_dma = 0;
+
+	mem = &inst->vld_wrapper_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.vld_wrapper_dma = 0;
+}
+
+static u64 vdec_vp8_slice_get_ref_by_ts(const struct v4l2_ctrl_vp8_frame *frame_header,
+					int index)
+{
+	switch (index) {
+	case 0:
+		return frame_header->last_frame_ts;
+	case 1:
+		return frame_header->golden_frame_ts;
+	case 2:
+		return frame_header->alt_frame_ts;
+	default:
+		break;
+	}
+
+	return -1;
+}
+
+static void vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst)
+{
+	const struct v4l2_ctrl_vp8_frame *frame_header =
+		vdec_vp8_slice_get_ctrl_ptr(inst->ctx, V4L2_CTRL_TYPE_VP8_FRAME);
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	u64 referenct_ts;
+	int index, vb2_index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	for (index = 0; index < 3; index++) {
+		referenct_ts = vdec_vp8_slice_get_ref_by_ts(frame_header, index);
+		vb2_index = vb2_find_timestamp(vq, referenct_ts, 0);
+		if (vb2_index < 0) {
+			if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header))
+				mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)",
+					       index, referenct_ts);
+			inst->vsi->vp8_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+		inst->vsi->vp8_dpb_info[index].reference_flag = 1;
+
+		vb = vq->bufs[vb2_index];
+		inst->vsi->vp8_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				inst->vsi->vp8_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+
+	inst->vsi->dec.frame_header_type = frame_header->flags >> 1;
+}
+
+static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp8_slice_inst *inst;
+	int err;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	inst->vsi = inst->vpu.vsi;
+	err = vdec_vp8_slice_alloc_working_buf(inst);
+	if (err)
+		goto error_deinit;
+
+	mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n",
+			 (int)sizeof(struct v4l2_ctrl_vp8_frame),
+			 (int)sizeof(struct vdec_vp8_slice_vsi));
+	mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p",
+			 inst, inst->vpu.codec_type, inst->vpu.vsi);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_deinit:
+	vpu_dec_deinit(&inst->vpu);
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				 struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
+	unsigned int data;
+	u64 y_fb_dma, c_fb_dma;
+	int err, timeout;
+
+	/* Resolution changes are never initiated by us */
+	*res_chg = false;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vpu_dec_reset(vpu);
+
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma = y_fb_dma +
+			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	inst->vsi->dec.bs_dma = (unsigned long)bs->dma_addr;
+	inst->vsi->dec.bs_sz = bs->size;
+	inst->vsi->dec.cur_y_fb_dma = y_fb_dma;
+	inst->vsi->dec.cur_c_fb_dma = c_fb_dma;
+
+	mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%lx) y/c(0x%llx 0x%llx)",
+			 inst->ctx->decoded_frame_cnt,
+			 bs->size, (unsigned long)bs->dma_addr,
+			 y_fb_dma, c_fb_dma);
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &dst_buf_info->m2m_buf.vb, true);
+
+	vdec_vp8_slice_get_decode_parameters(inst);
+	err = vpu_dec_start(vpu, &data, 1);
+	if (err) {
+		mtk_vcodec_debug(inst, "vp8 dec start err!");
+		goto error;
+	}
+
+	if (inst->vsi->dec.resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution_changed -");
+		*res_chg = true;
+		return 0;
+	}
+
+	/* wait decode done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       50, MTK_VDEC_CORE);
+
+	err = vpu_dec_end(vpu);
+	if (err || timeout)
+		mtk_vcodec_debug(inst, "vp8 dec error timeout:%d err: %d pic_%d",
+				 timeout, err, inst->ctx->decoded_frame_cnt);
+
+	mtk_vcodec_debug(inst, "y_crc: 0x%x 0x%x 0x%x 0x%x",
+			 inst->vsi->dec.crc[0],
+			 inst->vsi->dec.crc[1],
+			 inst->vsi->dec.crc[2],
+			 inst->vsi->dec.crc[3]);
+
+	mtk_vcodec_debug(inst, "c_crc: 0x%x 0x%x 0x%x 0x%x",
+			 inst->vsi->dec.crc[4],
+			 inst->vsi->dec.crc[5],
+			 inst->vsi->dec.crc[6],
+			 inst->vsi->dec.crc[7]);
+	inst->ctx->decoded_frame_cnt++;
+
+error:
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, !!err);
+	return err;
+}
+
+static int vdec_vp8_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp8_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp8_slice_get_crop_info(inst, out);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*((unsigned int *)out) = VP8_DPB_SIZE;
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void vdec_vp8_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_vp8_slice_free_working_buf(inst);
+	kfree(inst);
+}
+
+const struct vdec_common_if vdec_vp8_slice_if = {
+	.init		= vdec_vp8_slice_init,
+	.decode		= vdec_vp8_slice_decode,
+	.get_param	= vdec_vp8_slice_get_param,
+	.deinit		= vdec_vp8_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c17a7815e1bb..9db9a57da2c1 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -32,6 +32,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_h264_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP8_FRAME:
+		ctx->dec_if = &vdec_vp8_slice_if;
+		ctx->hw_id = MTK_VDEC_CORE;
+		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
 		ctx->hw_id = MTK_VDEC_CORE;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index 6ce848e74167..e3adf8f36342 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -58,6 +58,7 @@ extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
 extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
+extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
 /**
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:40:01 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:40:01 +0800
Subject: [PATCH v5, 15/15] media: mtk-vcodec: support stateless VP9 decoding
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-16-yunfei.dong@mediatek.com>

Add support for VP9 decoding using the stateless API,
as supported by MT8192. And the drivers is lat and core architecture.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Signed-off-by: George Sun <george.sun at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |    1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   26 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |    1 +
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 1973 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |    4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    1 +
 6 files changed, 2003 insertions(+), 3 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index b457daf2d196..93e7a343b5b0 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
+		vdec/vdec_vp9_req_lat_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
 		vdec/vdec_h264_req_multi_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 6d7d07dcb435..26fd97d867e9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -91,13 +91,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
 		},
 		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
-	}
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS,
+			},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP9_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[4];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
+static struct mtk_video_fmt mtk_video_formats[5];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[3];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -366,6 +381,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
 	case V4L2_PIX_FMT_VP8_FRAME:
+	case V4L2_PIX_FMT_VP9_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -413,6 +429,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP9_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP9_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e16733fbf0c7..cd2939b47790 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -358,6 +358,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
+	MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
new file mode 100644
index 000000000000..92cd39f00840
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
@@ -0,0 +1,1973 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: George Sun <george.sun at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* reset_frame_context defined in VP9 spec */
+#define VP9_RESET_FRAME_CONTEXT_NONE0 0
+#define VP9_RESET_FRAME_CONTEXT_NONE1 1
+#define VP9_RESET_FRAME_CONTEXT_SPEC 2
+#define VP9_RESET_FRAME_CONTEXT_ALL 3
+
+#define VP9_TILE_BUF_SIZE 4096
+#define VP9_PROB_BUF_SIZE 2560
+#define VP9_COUNTS_BUF_SIZE 16384
+
+#define HDR_FLAG(x) (!!((hdr)->flags & V4L2_VP9_FRAME_FLAG_##x))
+#define LF_FLAG(x) (!!((lf)->flags & V4L2_VP9_LOOP_FILTER_FLAG_##x))
+#define SEG_FLAG(x) (!!((seg)->flags & V4L2_VP9_SEGMENTATION_FLAG_##x))
+
+/*
+ * struct vdec_vp9_slice_frame_ctx - vp9 prob tables footprint
+ */
+struct vdec_vp9_slice_frame_ctx {
+	struct {
+		u8 probs[6][3];
+		u8 padding[2];
+	} coef_probs[4][2][2][6];
+
+	u8 y_mode_prob[4][16];
+	u8 switch_interp_prob[4][16];
+	u8 seg[32];  /* ignore */
+	u8 comp_inter_prob[16];
+	u8 comp_ref_prob[16];
+	u8 single_ref_prob[5][2];
+	u8 single_ref_prob_padding[6];
+
+	u8 joint[3];
+	u8 joint_padding[13];
+	struct {
+		u8 sign;
+		u8 classes[10];
+		u8 padding[5];
+	} sign_classes[2];
+	struct {
+		u8 class0[1];
+		u8 bits[10];
+		u8 padding[5];
+	} class0_bits[2];
+	struct {
+		u8 class0_fp[2][3];
+		u8 fp[3];
+		u8 class0_hp;
+		u8 hp;
+		u8 padding[5];
+	} class0_fp_hp[2];
+
+	u8 uv_mode_prob[10][16];
+	u8 uv_mode_prob_padding[2][16];
+
+	u8 partition_prob[16][4];
+
+	u8 inter_mode_probs[7][4];
+	u8 skip_probs[4];
+
+	u8 tx_p8x8[2][4];
+	u8 tx_p16x16[2][4];
+	u8 tx_p32x32[2][4];
+	u8 intra_inter_prob[8];
+};
+
+/*
+ * struct vdec_vp9_slice_frame_counts - vp9 counts tables footprint
+ */
+struct vdec_vp9_slice_frame_counts {
+	union {
+		struct {
+			u32 band_0[3];
+			u32 padding0[1];
+			u32 band_1_5[5][6];
+			u32 padding1[2];
+		} eob_branch[4][2][2];
+		u32 eob_branch_space[256 * 4];
+	};
+
+	struct {
+		u32 band_0[3][4];
+		u32 band_1_5[5][6][4];
+	} coef_probs[4][2][2];
+
+	u32 intra_inter[4][2];
+	u32 comp_inter[5][2];
+	u32 comp_inter_padding[2];
+	u32 comp_ref[5][2];
+	u32 comp_ref_padding[2];
+	u32 single_ref[5][2][2];
+	u32 inter_mode[7][4];
+	u32 y_mode[4][12];
+	u32 uv_mode[10][10];
+	u32 partition[16][4];
+	u32 switchable_interp[4][4];
+
+	u32 tx_p8x8[2][2];
+	u32 tx_p16x16[2][4];
+	u32 tx_p32x32[2][4];
+
+	u32 skip[3][4];
+
+	u32 joint[4];
+
+	struct {
+		u32 sign[2];
+		u32 class0[2];
+		u32 classes[12];
+		u32 bits[10][2];
+		u32 padding[4];
+		u32 class0_fp[2][4];
+		u32 fp[4];
+		u32 class0_hp[2];
+		u32 hp[2];
+	} mvcomp[2];
+
+	u32 reserved[126][4];
+};
+
+/*
+ * struct vdec_vp9_slice_uncompressed_header - vp9 uncompressed header syntax
+ *                                             used for decoding
+ */
+struct vdec_vp9_slice_uncompressed_header {
+	u8 profile;
+	u8 last_frame_type;
+	u8 frame_type;
+
+	u8 last_show_frame;
+	u8 show_frame;
+	u8 error_resilient_mode;
+
+	u8 bit_depth;
+	u8 padding0[1];
+	u16 last_frame_width;
+	u16 last_frame_height;
+	u16 frame_width;
+	u16 frame_height;
+
+	u8 intra_only;
+	u8 reset_frame_context;
+	u8 ref_frame_sign_bias[4];
+	u8 allow_high_precision_mv;
+	u8 interpolation_filter;
+
+	u8 refresh_frame_context;
+	u8 frame_parallel_decoding_mode;
+	u8 frame_context_idx;
+
+	/* loop_filter_params */
+	u8 loop_filter_level;
+	u8 loop_filter_sharpness;
+	u8 loop_filter_delta_enabled;
+	s8 loop_filter_ref_deltas[4];
+	s8 loop_filter_mode_deltas[2];
+
+	/* quantization_params */
+	u8 base_q_idx;
+	s8 delta_q_y_dc;
+	s8 delta_q_uv_dc;
+	s8 delta_q_uv_ac;
+
+	/* segmentation_params */
+	u8 segmentation_enabled;
+	u8 segmentation_update_map;
+	u8 segmentation_tree_probs[7];
+	u8 padding1[1];
+	u8 segmentation_temporal_udpate;
+	u8 segmentation_pred_prob[3];
+	u8 segmentation_update_data;
+	u8 segmentation_abs_or_delta_update;
+	u8 feature_enabled[8];
+	s16 feature_value[8][4];
+
+	/* tile_info */
+	u8 tile_cols_log2;
+	u8 tile_rows_log2;
+	u8 padding2[2];
+
+	u16 uncompressed_header_size;
+	u16 header_size_in_bytes;
+
+	/* LAT OUT, CORE IN */
+	u32 dequant[8][4];
+};
+
+/*
+ * struct vdec_vp9_slice_compressed_header - vp9 compressed header syntax
+ *                                           used for decoding.
+ */
+struct vdec_vp9_slice_compressed_header {
+	u8 tx_mode;
+	u8 ref_mode;
+	u8 comp_fixed_ref;
+	u8 comp_var_ref[2];
+	u8 padding[3];
+};
+
+/*
+ * struct vdec_vp9_slice_tiles - vp9 tile syntax
+ */
+struct vdec_vp9_slice_tiles {
+	u32 size[4][64];
+	u32 mi_rows[4];
+	u32 mi_cols[64];
+	u8 actual_rows;
+	u8 padding[7];
+};
+
+/*
+ * struct vdec_vp9_slice_reference - vp9 reference frame information
+ */
+struct vdec_vp9_slice_reference {
+	u16 frame_width;
+	u16 frame_height;
+	u8 bit_depth;
+	u8 subsampling_x;
+	u8 subsampling_y;
+	u8 padding;
+};
+
+/*
+ * struct vdec_vp9_slice_frame - vp9 syntax used for decoding
+ */
+struct vdec_vp9_slice_frame {
+	struct vdec_vp9_slice_uncompressed_header uh;
+	struct vdec_vp9_slice_compressed_header ch;
+	struct vdec_vp9_slice_tiles tiles;
+	struct vdec_vp9_slice_reference ref[3];
+};
+
+/*
+ * struct vdec_vp9_slice_init_vsi - VSI used to initialize instance
+ */
+struct vdec_vp9_slice_init_vsi {
+	unsigned int architecture;
+	unsigned int reserved;
+	u64 core_vsi;
+	/* default frame context's position in MicroP */
+	u64 default_frame_ctx;
+};
+
+/**
+ * struct vdec_vp9_slice_mem - memory address and size
+ */
+struct vdec_vp9_slice_mem {
+	union {
+		u64 buf;
+		dma_addr_t dma_addr;
+	};
+	union {
+		size_t size;
+		dma_addr_t dma_addr_end;
+		u64 padding;
+	};
+};
+
+/**
+ * struct vdec_vp9_slice_bs - input buffer for decoding
+ */
+struct vdec_vp9_slice_bs {
+	struct vdec_vp9_slice_mem buf;
+	struct vdec_vp9_slice_mem frame;
+};
+
+/**
+ * struct vdec_vp9_slice_fb - frame buffer for decoding
+ */
+struct vdec_vp9_slice_fb {
+	struct vdec_vp9_slice_mem y;
+	struct vdec_vp9_slice_mem c;
+};
+
+/**
+ * struct vdec_vp9_slice_state - decoding state
+ */
+struct vdec_vp9_slice_state {
+	int err;
+	unsigned int full;
+	unsigned int timeout;
+	unsigned int perf;
+
+	unsigned int crc[12];
+};
+
+/*
+ * struct vdec_vp9_slice_vsi - exchange decoding information
+ *                             between Main CPU and MicroP
+ * @bs          : input buffer
+ * @fb          : output buffer
+ * @ref         : 3 reference buffers
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @ube         : general buffer
+ * @trans       : trans buffer position in general buffer
+ * @err_map     : error buffer
+ * @row_info    : row info buffer
+ * @frame       : decoding syntax
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_vsi {
+	/* used in LAT stage */
+	struct vdec_vp9_slice_bs bs;
+	/* used in Core stage */
+	struct vdec_vp9_slice_fb fb;
+	struct vdec_vp9_slice_fb ref[3];
+
+	struct vdec_vp9_slice_mem mv[2];
+	struct vdec_vp9_slice_mem seg[2];
+	struct vdec_vp9_slice_mem tile;
+	struct vdec_vp9_slice_mem prob;
+	struct vdec_vp9_slice_mem counts;
+
+	/* LAT stage's output, Core stage's input */
+	struct vdec_vp9_slice_mem ube;
+	struct vdec_vp9_slice_mem trans;
+	struct vdec_vp9_slice_mem err_map;
+	struct vdec_vp9_slice_mem row_info;
+
+	/* decoding parameters */
+	struct vdec_vp9_slice_frame frame;
+
+	struct vdec_vp9_slice_state state;
+};
+
+/**
+ * struct vdec_vp9_slice_pfc - per-frame context that contains a local vsi.
+ *                             pass it from lat to core
+ * @vsi         : local vsi. copy to/from remote vsi before/after decoding
+ * @ref_idx     : reference buffer index
+ * @seq         : picture sequence
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_pfc {
+	struct vdec_vp9_slice_vsi vsi;
+
+	u64 ref_idx[3];
+
+	int seq;
+
+	/* LAT/Core CRC */
+	struct vdec_vp9_slice_state state[2];
+};
+
+/*
+ * enum vdec_vp9_slice_resolution_level
+ */
+enum vdec_vp9_slice_resolution_level {
+	VP9_RES_NONE,
+	VP9_RES_FHD,
+	VP9_RES_4K,
+	VP9_RES_8K,
+};
+
+/*
+ * struct vdec_vp9_slice_ref - picture's width & height should kept
+ *                             for later decoding as reference picture
+ */
+struct vdec_vp9_slice_ref {
+	unsigned int width;
+	unsigned int height;
+};
+
+/**
+ * struct vdec_vp9_slice_instance - represent one vp9 instance
+ * @ctx         : pointer to codec's context
+ * @vpu         : VPU instance
+ * @seq         : global picture sequence
+ * @level       : level of current resolution
+ * @width       : width of last picture
+ * @height      : height of last picture
+ * @frame_type  : frame_type of last picture
+ * @irq         : irq to Main CPU or MicroP
+ * @show_frame  : show_frame of last picture
+ * @dpb         : picture information (width/height) for reference
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @frame_ctx   : 4 frame context according to VP9 Spec
+ * @dirty       : state of each frame context
+ * @init_vsi    : vsi used for initialized VP9 instance
+ * @vsi         : vsi used for decoding/flush ...
+ * @core_vsi    : vsi used for Core stage
+ */
+struct vdec_vp9_slice_instance {
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+
+	int seq;
+
+	enum vdec_vp9_slice_resolution_level level;
+
+	/* for resolution change and get_pic_info */
+	unsigned int width;
+	unsigned int height;
+
+	/* for last_frame_type */
+	unsigned int frame_type;
+	unsigned int irq;
+
+	unsigned int show_frame;
+
+	/* maintain vp9 reference frame state */
+	struct vdec_vp9_slice_ref dpb[VB2_MAX_FRAME];
+
+	/*
+	 * normal working buffers
+	 * mv[0]/seg[0]/tile/prob/counts is used for LAT
+	 * mv[1]/seg[1] is used for CORE
+	 */
+	struct mtk_vcodec_mem mv[2];
+	struct mtk_vcodec_mem seg[2];
+	struct mtk_vcodec_mem tile;
+	struct mtk_vcodec_mem prob;
+	struct mtk_vcodec_mem counts;
+
+	/* 4 prob tables */
+	struct vdec_vp9_slice_frame_ctx frame_ctx[4];
+	unsigned char dirty[4];
+
+	/* MicroP vsi */
+	union {
+		struct vdec_vp9_slice_init_vsi *init_vsi;
+		struct vdec_vp9_slice_vsi *vsi;
+	};
+	struct vdec_vp9_slice_vsi *core_vsi;
+};
+
+/*
+ * (2, (0, (1, 3)))
+ * max level = 2
+ */
+static const signed char vdec_vp9_slice_inter_mode_tree[6] = {
+	-2, 2, 0, 4, -1, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_intra_mode_tree[18] = {
+	0, 2, -9, 4, -1, 6, 8, 12, -2, 10, -4, -5, -3, 14, -8, 16, -6, -7
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_partition_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 1 */
+static const signed char vdec_vp9_slice_switchable_interp_tree[4] = {
+	0, 2, -1, -2
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_joint_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_mv_class_tree[20] = {
+	0, 2, -1, 4, 6, 8, -2, -3, 10, 12,
+	-4, -5, -6, 14, 16, 18, -7, -8, -9, -10
+};
+
+/* max level = 0 */
+static const signed char vdec_vp9_slice_mv_class0_tree[2] = {
+	0, -1
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_fp_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/*
+ * all VP9 instances could share this default frame context.
+ */
+static struct vdec_vp9_slice_frame_ctx *vdec_vp9_slice_default_frame_ctx;
+static DEFINE_MUTEX(vdec_vp9_slice_frame_ctx_lock);
+
+static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf);
+
+static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance *instance)
+{
+	struct vdec_vp9_slice_frame_ctx *remote_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret = 0;
+
+	ctx = instance->ctx;
+	vsi = instance->vpu.vsi;
+	if (!ctx || !vsi)
+		return -EINVAL;
+
+	remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+						     (u32)vsi->default_frame_ctx);
+	if (!remote_frame_ctx) {
+		mtk_vcodec_err(instance, "failed to map default frame ctx\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&vdec_vp9_slice_frame_ctx_lock);
+	if (vdec_vp9_slice_default_frame_ctx)
+		goto out;
+
+	frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_KERNEL);
+	if (!frame_ctx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy_fromio(frame_ctx, remote_frame_ctx, sizeof(*frame_ctx));
+	vdec_vp9_slice_default_frame_ctx = frame_ctx;
+
+out:
+	mutex_unlock(&vdec_vp9_slice_frame_ctx_lock);
+
+	return ret;
+}
+
+static int vdec_vp9_slice_alloc_working_buffer(struct vdec_vp9_slice_instance *instance,
+					       struct vdec_vp9_slice_vsi *vsi)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	enum vdec_vp9_slice_resolution_level level;
+	/* super blocks */
+	unsigned int max_sb_w;
+	unsigned int max_sb_h;
+	unsigned int max_w;
+	unsigned int max_h;
+	unsigned int w;
+	unsigned int h;
+	size_t size;
+	int ret;
+	int i;
+
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+
+	if (w > VCODEC_DEC_4K_CODED_WIDTH ||
+	    h > VCODEC_DEC_4K_CODED_HEIGHT) {
+		/* 8K? */
+		return -EINVAL;
+	} else if (w > MTK_VDEC_MAX_W || h > MTK_VDEC_MAX_H) {
+		/* 4K */
+		level = VP9_RES_4K;
+		max_w = VCODEC_DEC_4K_CODED_WIDTH;
+		max_h = VCODEC_DEC_4K_CODED_HEIGHT;
+	} else {
+		/* FHD */
+		level = VP9_RES_FHD;
+		max_w = MTK_VDEC_MAX_W;
+		max_h = MTK_VDEC_MAX_H;
+	}
+
+	if (level == instance->level)
+		return 0;
+
+	mtk_vcodec_debug(instance, "resolution level changed, from %u to %u, %ux%u",
+			 instance->level, level, w, h);
+
+	max_sb_w = DIV_ROUND_UP(max_w, 64);
+	max_sb_h = DIV_ROUND_UP(max_h, 64);
+	ret = -ENOMEM;
+
+	/*
+	 * Lat-flush must wait core idle, otherwise core will
+	 * use released buffers
+	 */
+
+	size = (max_sb_w * max_sb_h + 2) * 576;
+	for (i = 0; i < 2; i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+		instance->mv[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->mv[i]))
+			goto err;
+	}
+
+	size = (max_sb_w * max_sb_h * 32) + 256;
+	for (i = 0; i < 2; i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+		instance->seg[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->seg[i]))
+			goto err;
+	}
+
+	if (!instance->tile.va) {
+		instance->tile.size = VP9_TILE_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->tile))
+			goto err;
+	}
+
+	if (!instance->prob.va) {
+		instance->prob.size = VP9_PROB_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->prob))
+			goto err;
+	}
+
+	if (!instance->counts.va) {
+		instance->counts.size = VP9_COUNTS_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->counts))
+			goto err;
+	}
+
+	instance->level = level;
+	return 0;
+
+err:
+	instance->level = VP9_RES_NONE;
+	return ret;
+}
+
+static void vdec_vp9_slice_free_working_buffer(struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(instance->mv); i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+	}
+	for (i = 0; i < ARRAY_SIZE(instance->seg); i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+	}
+	if (instance->tile.va)
+		mtk_vcodec_mem_free(ctx, &instance->tile);
+	if (instance->prob.va)
+		mtk_vcodec_mem_free(ctx, &instance->prob);
+	if (instance->counts.va)
+		mtk_vcodec_mem_free(ctx, &instance->counts);
+
+	instance->level = VP9_RES_NONE;
+}
+
+static void vdec_vp9_slice_vsi_from_remote(struct vdec_vp9_slice_vsi *vsi,
+					   struct vdec_vp9_slice_vsi *remote_vsi,
+					   int skip)
+{
+	struct vdec_vp9_slice_frame *rf;
+	struct vdec_vp9_slice_frame *f;
+
+	/*
+	 * compressed header
+	 * dequant
+	 * buffer position
+	 * decode state
+	 */
+	if (!skip) {
+		rf = &remote_vsi->frame;
+		f = &vsi->frame;
+		memcpy_fromio(&f->ch, &rf->ch, sizeof(f->ch));
+		memcpy_fromio(&f->uh.dequant, &rf->uh.dequant, sizeof(f->uh.dequant));
+		memcpy_fromio(&vsi->trans, &remote_vsi->trans, sizeof(vsi->trans));
+	}
+
+	memcpy_fromio(&vsi->state, &remote_vsi->state, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_vsi_to_remote(struct vdec_vp9_slice_vsi *vsi,
+					 struct vdec_vp9_slice_vsi *remote_vsi)
+{
+	memcpy_toio(remote_vsi, vsi, sizeof(*vsi));
+}
+
+static int vdec_vp9_slice_tile_offset(int idx, int mi_num, int tile_log2)
+{
+	int sbs = (mi_num + 7) >> 3;
+	int offset = ((idx * sbs) >> tile_log2) << 3;
+
+	return offset < mi_num ? offset : mi_num;
+}
+
+static int vdec_vp9_slice_setup_lat_from_src_buf(struct vdec_vp9_slice_instance *instance,
+						 struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx);
+	if (!src)
+		return -EINVAL;
+
+	dst = &lat_buf->ts_info;
+	v4l2_m2m_buf_copy_metadata(src, dst, true);
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_hdr(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_vp9_slice_uncompressed_header *uh,
+				     struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int i;
+
+	uh->profile = hdr->profile;
+	uh->last_frame_type = instance->frame_type;
+	uh->frame_type = !HDR_FLAG(KEY_FRAME);
+	uh->last_show_frame = instance->show_frame;
+	uh->show_frame = HDR_FLAG(SHOW_FRAME);
+	uh->error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	uh->bit_depth = hdr->bit_depth;
+	uh->last_frame_width = instance->width;
+	uh->last_frame_height = instance->height;
+	uh->frame_width = hdr->frame_width_minus_1 + 1;
+	uh->frame_height = hdr->frame_height_minus_1 + 1;
+	uh->intra_only = HDR_FLAG(INTRA_ONLY);
+	/* map v4l2 enum to values defined in VP9 spec for firmware */
+	switch (hdr->reset_frame_context) {
+	case V4L2_VP9_RESET_FRAME_CTX_NONE:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_SPEC:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_SPEC;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_ALL:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_ALL;
+		break;
+	default:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	}
+	/*
+	 * ref_frame_sign_bias specifies the intended direction
+	 * of the motion vector in time for each reference frame.
+	 * - INTRA_FRAME = 0,
+	 * - LAST_FRAME = 1,
+	 * - GOLDEN_FRAME = 2,
+	 * - ALTREF_FRAME = 3,
+	 * ref_frame_sign_biases[INTRA_FRAME] is always 0
+	 * and VDA only passes another 3 directions
+	 */
+	uh->ref_frame_sign_bias[0] = 0;
+	for (i = 0; i < 3; i++)
+		uh->ref_frame_sign_bias[i + 1] =
+			!!(hdr->ref_frame_sign_biases & (1 << i));
+	uh->allow_high_precision_mv = HDR_FLAG(ALLOW_HIGH_PREC_MV);
+	uh->interpolation_filter = hdr->interpolation_filter;
+	uh->refresh_frame_context = HDR_FLAG(REFRESH_FRAME_CTX);
+	uh->frame_parallel_decoding_mode = HDR_FLAG(PARALLEL_DEC_MODE);
+	uh->frame_context_idx = hdr->frame_context_idx;
+
+	/* tile info */
+	uh->tile_cols_log2 = hdr->tile_cols_log2;
+	uh->tile_rows_log2 = hdr->tile_rows_log2;
+
+	uh->uncompressed_header_size = hdr->uncompressed_header_size;
+	uh->header_size_in_bytes = hdr->compressed_header_size;
+}
+
+static void vdec_vp9_slice_setup_frame_ctx(struct vdec_vp9_slice_instance *instance,
+					   struct vdec_vp9_slice_uncompressed_header *uh,
+					   struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int error_resilient_mode;
+	int reset_frame_context;
+	int key_frame;
+	int intra_only;
+	int i;
+
+	key_frame = HDR_FLAG(KEY_FRAME);
+	intra_only = HDR_FLAG(INTRA_ONLY);
+	error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	reset_frame_context = uh->reset_frame_context;
+
+	/*
+	 * according to "6.2 Uncompressed header syntax" in
+	 * "VP9 Bitstream & Decoding Process Specification",
+	 * reset @frame_context_idx when (FrameIsIntra || error_resilient_mode)
+	 */
+	if (key_frame || intra_only || error_resilient_mode) {
+		/*
+		 * @reset_frame_context specifies
+		 * whether the frame context should be
+		 * reset to default values:
+		 * 0 or 1 means do not reset any frame context
+		 * 2 resets just the context specified in the frame header
+		 * 3 resets all contexts
+		 */
+		if (key_frame || error_resilient_mode ||
+		    reset_frame_context == 3) {
+			/* use default table */
+			for (i = 0; i < 4; i++)
+				instance->dirty[i] = 0;
+		} else if (reset_frame_context == 2) {
+			instance->dirty[uh->frame_context_idx] = 0;
+		}
+		uh->frame_context_idx = 0;
+	}
+}
+
+static void vdec_vp9_slice_setup_loop_filter(struct vdec_vp9_slice_uncompressed_header *uh,
+					     struct v4l2_vp9_loop_filter *lf)
+{
+	int i;
+
+	uh->loop_filter_level = lf->level;
+	uh->loop_filter_sharpness = lf->sharpness;
+	uh->loop_filter_delta_enabled = LF_FLAG(DELTA_ENABLED);
+	for (i = 0; i < 4; i++)
+		uh->loop_filter_ref_deltas[i] = lf->ref_deltas[i];
+	for (i = 0; i < 2; i++)
+		uh->loop_filter_mode_deltas[i] = lf->mode_deltas[i];
+}
+
+static void vdec_vp9_slice_setup_quantization(struct vdec_vp9_slice_uncompressed_header *uh,
+					      struct v4l2_vp9_quantization *quant)
+{
+	uh->base_q_idx = quant->base_q_idx;
+	uh->delta_q_y_dc = quant->delta_q_y_dc;
+	uh->delta_q_uv_dc = quant->delta_q_uv_dc;
+	uh->delta_q_uv_ac = quant->delta_q_uv_ac;
+}
+
+static void vdec_vp9_slice_setup_segmentation(struct vdec_vp9_slice_uncompressed_header *uh,
+					      struct v4l2_vp9_segmentation *seg)
+{
+	int i;
+	int j;
+
+	uh->segmentation_enabled = SEG_FLAG(ENABLED);
+	uh->segmentation_update_map = SEG_FLAG(UPDATE_MAP);
+	for (i = 0; i < 7; i++)
+		uh->segmentation_tree_probs[i] = seg->tree_probs[i];
+	uh->segmentation_temporal_udpate = SEG_FLAG(TEMPORAL_UPDATE);
+	for (i = 0; i < 3; i++)
+		uh->segmentation_pred_prob[i] = seg->pred_probs[i];
+	uh->segmentation_update_data = SEG_FLAG(UPDATE_DATA);
+	uh->segmentation_abs_or_delta_update = SEG_FLAG(ABS_OR_DELTA_UPDATE);
+	for (i = 0; i < 8; i++) {
+		uh->feature_enabled[i] = seg->feature_enabled[i];
+		for (j = 0; j < 4; j++)
+			uh->feature_value[i][j] = seg->feature_data[i][j];
+	}
+}
+
+static int vdec_vp9_slice_setup_tile(struct vdec_vp9_slice_vsi *vsi,
+				     struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_rows;
+	unsigned int mi_cols;
+	struct vdec_vp9_slice_tiles *tiles;
+	int offset;
+	int start;
+	int end;
+	int i;
+
+	rows_log2 = hdr->tile_rows_log2;
+	cols_log2 = hdr->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+	tiles = &vsi->frame.tiles;
+	tiles->actual_rows = 0;
+
+	if (rows > 4 || cols > 64)
+		return -EINVAL;
+
+	/* setup mi rows/cols information */
+	mi_rows = (hdr->frame_height_minus_1 + 1 + 7) >> 3;
+	mi_cols = (hdr->frame_width_minus_1 + 1 + 7) >> 3;
+
+	for (i = 0; i < rows; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_rows, rows_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_rows, rows_log2);
+		offset = end - start;
+		tiles->mi_rows[i] = (offset + 7) >> 3;
+		if (tiles->mi_rows[i])
+			tiles->actual_rows++;
+	}
+
+	for (i = 0; i < cols; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_cols, cols_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_cols, cols_log2);
+		offset = end - start;
+		tiles->mi_cols[i] = (offset + 7) >> 3;
+	}
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_state(struct vdec_vp9_slice_vsi *vsi)
+{
+	memset(&vsi->state, 0, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_setup_ref_idx(struct vdec_vp9_slice_pfc *pfc,
+					 struct v4l2_ctrl_vp9_frame_decode_params *hdr)
+{
+	int i;
+
+	for (i = 0; i < 3; i++)
+		pfc->ref_idx[i] = hdr->refs[i];
+}
+
+static int vdec_vp9_slice_setup_pfc(struct vdec_vp9_slice_instance *instance,
+				    struct vdec_vp9_slice_pfc *pfc)
+{
+	struct v4l2_ctrl_vp9_frame_decode_params *hdr;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	struct v4l2_ctrl *hdr_ctrl;
+	struct vdec_vp9_slice_vsi *vsi;
+	int ret;
+
+	/* frame header */
+	hdr_ctrl = v4l2_ctrl_find(&instance->ctx->ctrl_hdl,
+				  V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS);
+	if (!hdr_ctrl || !hdr_ctrl->p_cur.p)
+		return -EINVAL;
+
+	hdr = hdr_ctrl->p_cur.p;
+	vsi = &pfc->vsi;
+	uh = &vsi->frame.uh;
+
+	/* setup vsi information */
+	vdec_vp9_slice_setup_hdr(instance, uh, hdr);
+	vdec_vp9_slice_setup_frame_ctx(instance, uh, hdr);
+	vdec_vp9_slice_setup_loop_filter(uh, &hdr->lf);
+	vdec_vp9_slice_setup_quantization(uh, &hdr->quant);
+	vdec_vp9_slice_setup_segmentation(uh, &hdr->seg);
+	ret = vdec_vp9_slice_setup_tile(vsi, hdr);
+	if (ret)
+		return ret;
+	vdec_vp9_slice_setup_state(vsi);
+
+	/* core stage needs buffer index to get ref y/c ... */
+	vdec_vp9_slice_setup_ref_idx(pfc, hdr);
+
+	pfc->seq = instance->seq;
+	instance->seq++;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat_buffer(struct vdec_vp9_slice_instance *instance,
+					   struct vdec_vp9_slice_vsi *vsi,
+					   struct mtk_vcodec_mem *bs,
+					   struct vdec_lat_buf *lat_buf)
+{
+	int i;
+
+	vsi->bs.buf.dma_addr = bs->dma_addr;
+	vsi->bs.buf.size = bs->size;
+	vsi->bs.frame.dma_addr = bs->dma_addr;
+	vsi->bs.frame.size = bs->size;
+
+	for (i = 0; i < 2; i++) {
+		vsi->mv[i].dma_addr = instance->mv[i].dma_addr;
+		vsi->mv[i].size = instance->mv[i].size;
+	}
+	for (i = 0; i < 2; i++) {
+		vsi->seg[i].dma_addr = instance->seg[i].dma_addr;
+		vsi->seg[i].size = instance->seg[i].size;
+	}
+	vsi->tile.dma_addr = instance->tile.dma_addr;
+	vsi->tile.size = instance->tile.size;
+	vsi->prob.dma_addr = instance->prob.dma_addr;
+	vsi->prob.size = instance->prob.size;
+	vsi->counts.dma_addr = instance->counts.dma_addr;
+	vsi->counts.size = instance->counts.size;
+
+	vsi->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	vsi->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
+	vsi->trans.dma_addr = lat_buf->ctx->msg_queue.wdma_wptr_addr;
+	/* used to store trans end */
+	vsi->trans.dma_addr_end = lat_buf->ctx->msg_queue.wdma_rptr_addr;
+	vsi->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
+	vsi->err_map.size = lat_buf->wdma_err_addr.size;
+
+	vsi->row_info.buf = 0;
+	vsi->row_info.size = 0;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+
+	mtk_vcodec_debug(instance, "ctx dirty %u idx %d\n",
+			 instance->dirty[uh->frame_context_idx],
+			 uh->frame_context_idx);
+
+	if (instance->dirty[uh->frame_context_idx])
+		frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	else
+		frame_ctx = vdec_vp9_slice_default_frame_ctx;
+	memcpy(instance->prob.va, frame_ctx, sizeof(*frame_ctx));
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_seg_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct mtk_vcodec_mem *buf)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	/* reset segment buffer */
+	uh = &vsi->frame.uh;
+	if (uh->frame_type == 0 ||
+	    uh->intra_only ||
+	    uh->error_resilient_mode ||
+	    uh->frame_width != instance->width ||
+	    uh->frame_height != instance->height) {
+		mtk_vcodec_debug(instance, "reset seg\n");
+		memset(buf->va, 0, buf->size);
+	}
+}
+
+/*
+ * parse tiles according to `6.4 Decode tiles syntax`
+ * in "vp9-bitstream-specification"
+ *
+ * frame contains uncompress header, compressed header and several tiles.
+ * this function parses tiles' position and size, stores them to tile buffer
+ * for decoding.
+ */
+static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct mtk_vcodec_mem *bs)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_row;
+	unsigned int mi_col;
+	unsigned int offset;
+	unsigned int pa;
+	unsigned int size;
+	struct vdec_vp9_slice_tiles *tiles;
+	unsigned char *pos;
+	unsigned char *end;
+	unsigned char *va;
+	unsigned int *tb;
+	int i;
+	int j;
+
+	uh = &vsi->frame.uh;
+	rows_log2 = uh->tile_rows_log2;
+	cols_log2 = uh->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+
+	if (rows > 4 || cols > 64) {
+		mtk_vcodec_err(instance, "tile_rows %u tile_cols %u\n",
+			       rows, cols);
+		return -EINVAL;
+	}
+
+	offset = uh->uncompressed_header_size +
+		uh->header_size_in_bytes;
+	if (bs->size <= offset) {
+		mtk_vcodec_err(instance, "bs size %zu tile offset %u\n",
+			       bs->size, offset);
+		return -EINVAL;
+	}
+
+	tiles = &vsi->frame.tiles;
+	/* setup tile buffer */
+
+	va = (unsigned char *)bs->va;
+	pos = va + offset;
+	end = va + bs->size;
+	/* truncated */
+	pa = (unsigned int)bs->dma_addr + offset;
+	tb = instance->tile.va;
+	for (i = 0; i < rows; i++) {
+		for (j = 0; j < cols; j++) {
+			if (i == rows - 1 &&
+			    j == cols - 1) {
+				size = (unsigned int)(end - pos);
+			} else {
+				if (end - pos < 4)
+					return -EINVAL;
+
+				size = (pos[0] << 24) | (pos[1] << 16) |
+					(pos[2] << 8) | pos[3];
+				pos += 4;
+				pa += 4;
+				offset += 4;
+				if (end - pos < size)
+					return -EINVAL;
+			}
+			tiles->size[i][j] = size;
+			if (tiles->mi_rows[i]) {
+				*tb++ = (size << 3) + ((offset << 3) & 0x7f);
+				*tb++ = pa & ~0xf;
+				*tb++ = (pa << 3) & 0x7f;
+				mi_row = (tiles->mi_rows[i] - 1) & 0x1ff;
+				mi_col = (tiles->mi_cols[j] - 1) & 0x3f;
+				*tb++ = (mi_row << 6) + mi_col;
+			}
+			pos += size;
+			pa += size;
+			offset += size;
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat(struct vdec_vp9_slice_instance *instance,
+				    struct mtk_vcodec_mem *bs,
+				    struct vdec_lat_buf *lat_buf,
+				    struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	ret = vdec_vp9_slice_setup_lat_from_src_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_pfc(instance, pfc);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_alloc_working_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_lat_buffer(instance, vsi, bs, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]);
+
+	/* setup prob/tile buffers for LAT */
+
+	ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	return ret;
+}
+
+/* implement merge prob process defined in 8.4.1 */
+static unsigned char vdec_vp9_slice_merge_prob(unsigned char pre, unsigned int ct0,
+					       unsigned int ct1, unsigned int cs,
+					       unsigned int uf)
+{
+	unsigned int den;
+	unsigned int prob;
+	unsigned int count;
+	unsigned int factor;
+
+	/*
+	 * The variable den representing the total times
+	 * this boolean has been decoded is set equal to ct0 + ct1.
+	 */
+	den = ct0 + ct1;
+	if (!den)
+		return pre;  /* => count = 0 => factor = 0 */
+	/*
+	 * The variable prob estimating the probability that
+	 * the boolean is decoded as a 0 is set equal to
+	 * (den == 0) ? 128 : Clip3(1, 255, (ct0 * 256 + (den >> 1)) / den).
+	 */
+	prob = ((ct0 << 8) + (den >> 1)) / den;
+	prob = prob < 1 ? 1 : (prob > 255 ? 255 : prob);
+	/* The variable count is set equal to Min(ct0 + ct1, countSat) */
+	count = den < cs ? den : cs;
+	/*
+	 * The variable factor is set equal to
+	 * maxUpdateFactor * count / countSat.
+	 */
+	factor = uf * count / cs;
+	/*
+	 * The return variable outProb is set equal to
+	 * Round2(preProb * (256 - factor) + prob * factor, 8).
+	 */
+	return pre + (((prob - pre) * factor + 128) >> 8);
+}
+
+static inline unsigned char vdec_vp9_slice_adapt_prob(unsigned char pre, unsigned int ct0,
+						      unsigned int ct1)
+{
+	return vdec_vp9_slice_merge_prob(pre, ct0, ct1, 20, 128);
+}
+
+/* implement merge probs process defined in 8.4.2 */
+static unsigned int vdec_vp9_slice_merge_probs(const signed char *tree, int location,
+					       unsigned char *pre_probs, unsigned int *counts,
+					       unsigned char *probs, unsigned int cs,
+					       unsigned int uf)
+{
+	int left = tree[location];
+	int right = tree[location + 1];
+	unsigned int left_count;
+	unsigned int right_count;
+
+	if (left <= 0)
+		left_count = counts[-left];
+	else
+		left_count = vdec_vp9_slice_merge_probs(tree, left, pre_probs, counts,
+							probs, cs, uf);
+
+	if (right <= 0)
+		right_count = counts[-right];
+	else
+		right_count = vdec_vp9_slice_merge_probs(tree, right, pre_probs, counts,
+							 probs, cs, uf);
+
+	/* merge left and right */
+	probs[location >> 1] =
+		vdec_vp9_slice_merge_prob(pre_probs[location >> 1],
+					  left_count, right_count, cs, uf);
+	return left_count + right_count;
+}
+
+static inline void vdec_vp9_slice_adapt_probs(const signed char *tree,
+					      unsigned char *pre_probs,
+					      unsigned int *counts,
+					      unsigned char *probs)
+{
+	vdec_vp9_slice_merge_probs(tree, 0, pre_probs, counts, probs, 20, 128);
+}
+
+/* 8.4 Probability adaptation process */
+static void vdec_vp9_slice_adapt_table(struct vdec_vp9_slice_vsi *vsi,
+				       struct vdec_vp9_slice_frame_ctx *ctx,
+				       struct vdec_vp9_slice_frame_ctx *pre_ctx,
+				       struct vdec_vp9_slice_frame_counts *counts)
+{
+	unsigned char *pp;
+	unsigned char *p;
+	unsigned int *c;
+	unsigned int *e;
+	unsigned int uf;
+	int t, i, j, k, l;
+
+	uf = 128;
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only ||
+	    vsi->frame.uh.last_frame_type)
+		uf = 112;
+
+	p = (unsigned char *)&ctx->coef_probs;
+	pp = (unsigned char *)&pre_ctx->coef_probs;
+	c = (unsigned int *)&counts->coef_probs;
+	e = (unsigned int *)&counts->eob_branch;
+
+	/* 8.4.3 Coefficient probability adaption process */
+	for (t = 0; t < 16; t++) {
+		for (((k) = 0); ((k) < 6); ((k)++)) {
+			for (l = 0; l < (k == 0 ? 3 : 6); l++) {
+				p[0] = vdec_vp9_slice_merge_prob(pp[0], c[3], e[0]
+								 - c[3], 24, uf);
+				p[1] = vdec_vp9_slice_merge_prob(pp[1],	c[0], c[1]
+								 + c[2], 24, uf);
+				p[2] = vdec_vp9_slice_merge_prob(pp[2], c[1],
+								 c[2], 24, uf);
+				p += 3;
+				pp += 3;
+				c += 4;
+				e++;
+			}
+			if (k == 0) {
+				/* 3 * 3 unused values and 2 bytes padding */
+				p += 11;
+				pp += 11;
+				e++;
+			} else {
+				/* extra 2 bytes could make 4 bytes align (3 * 6 + 2) */
+				p += 2;
+				pp += 2;
+				/* 5 * 6=30, extra 2 int */
+				if (k == 5)
+					e += 2;
+			}
+		}
+	}
+
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only)
+		return;
+
+	/* 8.4.4 Non coefficient probability adaption process */
+
+	for (i = 0; i < 4; i++) {
+		ctx->intra_inter_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->intra_inter_prob[i],
+						  counts->intra_inter[i][0],
+						  counts->intra_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_inter_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->comp_inter_prob[i],
+						  counts->comp_inter[i][0],
+						  counts->comp_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_ref_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->comp_ref_prob[i],
+						  counts->comp_ref[i][0],
+						  counts->comp_ref[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		for (j = 0; j < 2; j++) {
+			ctx->single_ref_prob[i][j] =
+				vdec_vp9_slice_adapt_prob(pre_ctx->single_ref_prob[i][j],
+							  counts->single_ref[i][j][0],
+							  counts->single_ref[i][j][1]);
+		}
+	}
+
+	for (i = 0; i < 7; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_inter_mode_tree,
+					   &pre_ctx->inter_mode_probs[i][0],
+					   &counts->inter_mode[i][0],
+					   &ctx->inter_mode_probs[i][0]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+					   &pre_ctx->y_mode_prob[i][0],
+					   &counts->y_mode[i][0],
+					   &ctx->y_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 10; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+					   &pre_ctx->uv_mode_prob[i][0],
+					   &counts->uv_mode[i][0],
+					   &ctx->uv_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 16; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_partition_tree,
+					   &pre_ctx->partition_prob[i][0],
+					   &counts->partition[i][0],
+					   &ctx->partition_prob[i][0]);
+	}
+
+	if (vsi->frame.uh.interpolation_filter == 4) {
+		for (i = 0; i < 4; i++) {
+			vdec_vp9_slice_adapt_probs(vdec_vp9_slice_switchable_interp_tree,
+						   &pre_ctx->switch_interp_prob[i][0],
+						   &counts->switchable_interp[i][0],
+						   &ctx->switch_interp_prob[i][0]);
+		}
+	}
+
+	if (vsi->frame.ch.tx_mode == 4) {
+		for (i = 0; i < 2; i++) {
+			ctx->tx_p8x8[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p8x8[i][0],
+								       counts->tx_p8x8[i][0],
+								       counts->tx_p8x8[i][1]);
+			ctx->tx_p16x16[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p16x16[i][0],
+									 counts->tx_p16x16[i][0],
+									 counts->tx_p16x16[i][1] +
+									 counts->tx_p16x16[i][2]);
+			ctx->tx_p16x16[i][1] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p16x16[i][1],
+									 counts->tx_p16x16[i][1],
+									 counts->tx_p16x16[i][2]);
+			ctx->tx_p32x32[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][0],
+									 counts->tx_p32x32[i][0],
+									 counts->tx_p32x32[i][1] +
+									 counts->tx_p32x32[i][2] +
+									 counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][1] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][1],
+									 counts->tx_p32x32[i][1],
+									 counts->tx_p32x32[i][2] +
+									 counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][2] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][2],
+									 counts->tx_p32x32[i][2],
+									 counts->tx_p32x32[i][3]);
+		}
+	}
+
+	for (i = 0; i < 3; i++) {
+		ctx->skip_probs[i] = vdec_vp9_slice_adapt_prob(pre_ctx->skip_probs[i],
+							       counts->skip[i][0],
+							       counts->skip[i][1]);
+	}
+
+	vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_joint_tree,
+				   &pre_ctx->joint[0],
+				   &counts->joint[0],
+				   &ctx->joint[0]);
+
+	for (i = 0; i < 2; i++) {
+		ctx->sign_classes[i].sign = vdec_vp9_slice_adapt_prob(pre_ctx->sign_classes[i].sign,
+								      counts->mvcomp[i].sign[0],
+								      counts->mvcomp[i].sign[1]);
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class_tree,
+					   &pre_ctx->sign_classes[i].classes[0],
+					   &counts->mvcomp[i].classes[0],
+					   &ctx->sign_classes[i].classes[0]);
+
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class0_tree,
+					   pre_ctx->class0_bits[i].class0,
+					   counts->mvcomp[i].class0,
+					   ctx->class0_bits[i].class0);
+		for (j = 0; j < 10; j++) {
+			ctx->class0_bits[i].bits[j] =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_bits[i].bits[j],
+							  counts->mvcomp[i].bits[j][0],
+							  counts->mvcomp[i].bits[j][1]);
+		}
+
+		for (j = 0; j < 2; ++j) {
+			vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+						   pre_ctx->class0_fp_hp[i].class0_fp[j],
+						   counts->mvcomp[i].class0_fp[j],
+						   ctx->class0_fp_hp[i].class0_fp[j]);
+		}
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+					   pre_ctx->class0_fp_hp[i].fp,
+					   counts->mvcomp[i].fp,
+					   ctx->class0_fp_hp[i].fp);
+		if (vsi->frame.uh.allow_high_precision_mv) {
+			ctx->class0_fp_hp[i].class0_hp =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_fp_hp[i].class0_hp,
+							  counts->mvcomp[i].class0_hp[0],
+							  counts->mvcomp[i].class0_hp[1]);
+			ctx->class0_fp_hp[i].hp =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_fp_hp[i].hp,
+							  counts->mvcomp[i].hp[0],
+							  counts->mvcomp[i].hp[1]);
+		}
+	}
+}
+
+static int vdec_vp9_slice_update_prob(struct vdec_vp9_slice_instance *instance,
+				      struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *pre_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_frame_counts *counts;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+	pre_frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	frame_ctx = (struct vdec_vp9_slice_frame_ctx *)instance->prob.va;
+	counts = (struct vdec_vp9_slice_frame_counts *)instance->counts.va;
+
+	if (!uh->refresh_frame_context)
+		return 0;
+
+	if (!uh->frame_parallel_decoding_mode) {
+		/* uh->error_resilient_mode must be 0 */
+		vdec_vp9_slice_adapt_table(vsi,	frame_ctx,
+					   /* use default frame ctx? */
+					   instance->dirty[uh->frame_context_idx] ?
+					   pre_frame_ctx :
+					   vdec_vp9_slice_default_frame_ctx,
+					   counts);
+	}
+
+	memcpy(pre_frame_ctx, frame_ctx, sizeof(*frame_ctx));
+	instance->dirty[uh->frame_context_idx] = 1;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_update_lat(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_lat_buf *lat_buf,
+				     struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance, "Frame %u LAT CRC 0x%08x\n",
+			 pfc->seq, vsi->state.crc[0]);
+
+	/* buffer full, need to re-decode */
+	if (vsi->state.full) {
+		/* buffer not enough */
+		if (vsi->trans.dma_addr_end - vsi->trans.dma_addr ==
+			vsi->ube.size)
+			return -ENOMEM;
+		return -EAGAIN;
+	}
+
+	vdec_vp9_slice_update_prob(instance, vsi);
+
+	instance->width = vsi->frame.uh.frame_width;
+	instance->height = vsi->frame.uh.frame_height;
+	instance->frame_type = vsi->frame.uh.frame_type;
+	instance->show_frame = vsi->frame.uh.show_frame;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_to_dst_buf(struct vdec_vp9_slice_instance *instance,
+						struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	dst = v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx);
+	if (!dst)
+		return -EINVAL;
+
+	src = &lat_buf->ts_info;
+	dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
+	dst->timecode = src->timecode;
+	dst->field = src->field;
+	dst->flags = src->flags;
+	dst->vb2_buf.copied_timestamp = src->vb2_buf.copied_timestamp;
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_pfc *pfc,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct vdec_fb *fb,
+					    struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_buffer *vb;
+	struct vb2_queue *vq;
+	struct vdec_vp9_slice_reference *ref;
+	int plane;
+	int size;
+	int idx;
+	int w;
+	int h;
+	int i;
+
+	plane = instance->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+	size = ALIGN(w, 64) * ALIGN(h, 64);
+
+	/* frame buffer */
+	vsi->fb.y.dma_addr = fb->base_y.dma_addr;
+	if (plane == 1)
+		vsi->fb.c.dma_addr = fb->base_y.dma_addr + size;
+	else
+		vsi->fb.c.dma_addr = fb->base_c.dma_addr;
+
+	/* reference buffers */
+	vq = v4l2_m2m_get_vq(instance->ctx->m2m_ctx,
+			     V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	if (!vq)
+		return -EINVAL;
+
+	/* get current output buffer */
+	vb = &v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx)->vb2_buf;
+	if (!vb)
+		return -EINVAL;
+
+	/* update internal buffer's width/height */
+	for (i = 0; i < vq->num_buffers; i++) {
+		if (vb == vq->bufs[i]) {
+			instance->dpb[i].width = w;
+			instance->dpb[i].height = h;
+			break;
+		}
+	}
+
+	/*
+	 * get buffer's width/height from instance
+	 * get buffer address from vb2buf
+	 */
+	for (i = 0; i < 3; i++) {
+		ref = &vsi->frame.ref[i];
+		idx = vb2_find_timestamp(vq, pfc->ref_idx[i], 0);
+		if (idx < 0) {
+			ref->frame_width = w;
+			ref->frame_height = h;
+			memset(&vsi->ref[i], 0, sizeof(vsi->ref[i]));
+		} else {
+			ref->frame_width = instance->dpb[idx].width;
+			ref->frame_height = instance->dpb[idx].height;
+			vb = vq->bufs[idx];
+			vsi->ref[i].y.dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 0);
+			if (plane == 1)
+				vsi->ref[i].c.dma_addr =
+					vsi->ref[i].y.dma_addr + size;
+			else
+				vsi->ref[i].c.dma_addr =
+					vb2_dma_contig_plane_dma_addr(vb, 1);
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_fb *fb,
+				     struct vdec_lat_buf *lat_buf,
+				     struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	vdec_vp9_slice_setup_state(vsi);
+
+	ret = vdec_vp9_slice_setup_core_to_dst_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_core_buffer(instance, pfc, vsi, fb, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[1]);
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static int vdec_vp9_slice_update_core(struct vdec_vp9_slice_instance *instance,
+				      struct vdec_lat_buf *lat_buf,
+				      struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[1], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n",
+			 pfc->seq,
+			 vsi->state.crc[0], vsi->state.crc[1],
+			 vsi->state.crc[2], vsi->state.crc[3]);
+	mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n",
+			 pfc->seq,
+			 vsi->state.crc[4], vsi->state.crc[5],
+			 vsi->state.crc[6], vsi->state.crc[7]);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret;
+
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+	if (!instance)
+		return -ENOMEM;
+
+	instance->ctx = ctx;
+	instance->vpu.id = SCP_IPI_VDEC_LAT;
+	instance->vpu.core_id = SCP_IPI_VDEC_CORE;
+	instance->vpu.ctx = ctx;
+	instance->vpu.codec_type = ctx->current_codec;
+
+	ret = vpu_dec_init(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "failed to init vpu dec, ret %d\n", ret);
+		goto error_vpu_init;
+	}
+
+	/* init vsi and global flags */
+
+	vsi = instance->vpu.vsi;
+	if (!vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+	instance->init_vsi = vsi;
+	instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+						       (u32)vsi->core_vsi);
+	if (!instance->core_vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 core vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+
+	instance->irq = 1;
+
+	ret = vdec_vp9_slice_init_default_frame_ctx(instance);
+	if (ret)
+		goto error_default_frame_ctx;
+
+	ctx->drv_handle = instance;
+
+	return 0;
+
+error_default_frame_ctx:
+error_vsi:
+	vpu_dec_deinit(&instance->vpu);
+error_vpu_init:
+	kfree(instance);
+	return ret;
+}
+
+static void vdec_vp9_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	if (!instance)
+		return;
+
+	vpu_dec_deinit(&instance->vpu);
+	vdec_vp9_slice_free_working_buffer(instance);
+	vdec_msg_queue_deinit(&instance->ctx->msg_queue, instance->ctx);
+	kfree(instance);
+}
+
+static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs,
+				struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	mtk_vcodec_debug(instance, "flush ...\n");
+
+	vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue);
+	return vpu_dec_reset(&instance->vpu);
+}
+
+static void vdec_vp9_slice_get_pic_info(struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	unsigned int data[3];
+
+	mtk_vcodec_debug(instance, "w %u h %u\n",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&instance->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = instance->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = instance->vpu.fb_sz[1];
+}
+
+static void vdec_vp9_slice_get_dpb_size(struct vdec_vp9_slice_instance *instance,
+					unsigned int *dpb_sz)
+{
+	/* refer VP9 specification */
+	*dpb_sz = 9;
+}
+
+static void vdec_vp9_slice_get_crop_info(struct vdec_vp9_slice_instance *instance,
+					 struct v4l2_rect *cr)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = ctx->picinfo.pic_w;
+	cr->height = ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(instance, "l=%d, t=%d, w=%d, h=%d\n",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_vp9_slice_get_param(void *h_vdec, vdec_get_param_type type, void *out)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp9_slice_get_pic_info(instance);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		vdec_vp9_slice_get_dpb_size(instance, out);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp9_slice_get_crop_info(instance, out);
+		break;
+	default:
+		mtk_vcodec_err(instance, "invalid get parameter type=%d\n",
+			       type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				     struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct vdec_vp9_slice_vsi *vsi;
+	struct mtk_vcodec_ctx *ctx;
+	int ret;
+
+	if (!instance || !instance->ctx)
+		return -EINVAL;
+	ctx = instance->ctx;
+
+	/* init msgQ for the first time */
+	if (vdec_msg_queue_init(&ctx->msg_queue, ctx,
+				vdec_vp9_slice_core_decode,
+				sizeof(*pfc)))
+		return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vdec_vp9_slice_flush(h_vdec, bs, fb, res_chg);
+
+	lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(instance, "Failed to get VP9 lat buf\n");
+		return -EBUSY;
+	}
+	pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+	if (!pfc)
+		return -EINVAL;
+	vsi = &pfc->vsi;
+
+	ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "Failed to setup VP9 lat ret %d\n", ret);
+		return ret;
+	}
+	vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi);
+
+	ret = vpu_dec_start(&instance->vpu, 0, 0);
+	if (ret) {
+		mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret);
+		return ret;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx,	MTK_INST_IRQ_RECEIVED,
+						   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance, "VP9 decode timeout %d\n", ret);
+			writel(1, &instance->vsi->state.timeout);
+		}
+		vpu_dec_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0);
+	ret = vdec_vp9_slice_update_lat(instance, lat_buf, pfc);
+
+	/* LAT trans full, no more UBE or decode timeout */
+	if (ret) {
+		mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret);
+		return ret;
+	}
+
+	mtk_vcodec_debug(instance, "lat dma 1 0x%llx 0x%llx\n",
+			 pfc->vsi.trans.dma_addr, pfc->vsi.trans.dma_addr_end);
+
+	vdec_msg_queue_update_ube_wptr(&ctx->msg_queue,
+				       vsi->trans.dma_addr_end +
+				       ctx->msg_queue.wdma_addr.dma_addr);
+	vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct mtk_vcodec_ctx *ctx = NULL;
+	struct vdec_fb *fb = NULL;
+	int ret = -EINVAL;
+
+	if (!lat_buf)
+		goto err;
+
+	pfc = lat_buf->private_data;
+	ctx = lat_buf->ctx;
+	if (!pfc || !ctx)
+		goto err;
+
+	instance = ctx->drv_handle;
+	if (!instance)
+		goto err;
+
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	if (!fb) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	ret = vdec_vp9_slice_setup_core(instance, fb, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_setup_core\n");
+		goto err;
+	}
+	vdec_vp9_slice_vsi_to_remote(&pfc->vsi, instance->core_vsi);
+
+	ret = vpu_dec_core(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "vpu_dec_core\n");
+		goto err;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
+						   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance, "VP9 core timeout\n");
+			writel(1, &instance->core_vsi->state.timeout);
+		}
+		vpu_dec_core_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(&pfc->vsi, instance->core_vsi, 1);
+	ret = vdec_vp9_slice_update_core(instance, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_update_core\n");
+		goto err;
+	}
+
+	pfc->vsi.trans.dma_addr_end += ctx->msg_queue.wdma_addr.dma_addr;
+	mtk_vcodec_debug(instance, "core dma_addr_end 0x%llx\n", pfc->vsi.trans.dma_addr_end);
+	vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, pfc->vsi.trans.dma_addr_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 0);
+
+	return 0;
+
+err:
+	if (ctx) {
+		/* always update read pointer */
+		vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, pfc->vsi.trans.dma_addr_end);
+
+		if (fb)
+			ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 1);
+	}
+	return ret;
+}
+
+const struct vdec_common_if vdec_vp9_slice_lat_if = {
+	.init		= vdec_vp9_slice_init,
+	.decode		= vdec_vp9_slice_lat_decode,
+	.get_param	= vdec_vp9_slice_get_param,
+	.deinit		= vdec_vp9_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 9db9a57da2c1..2d3a45781359 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -44,6 +44,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_vp9_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP9_FRAME:
+		ctx->dec_if = &vdec_vp9_slice_lat_if;
+		ctx->hw_id = MTK_VDEC_LAT0;
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index e3adf8f36342..e383a04db7b8 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -60,6 +60,7 @@ extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
+extern const struct vdec_common_if vdec_vp9_slice_lat_if;
 
 /**
  * vdec_if_init() - initialize decode driver
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:51 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:51 +0800
Subject: [PATCH v5,
 05/15] media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set
 capture buffer buffered
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-6-yunfei.dong@mediatek.com>

lat thread: output queue      \
                               -> lat hardware -> lat trans buffer
            lat trans buffer  /

core thread: capture queue     \
                                ->core hardware -> capture queue
             lat trans buffer  /

Lat and core work in different thread, setting capture buffer buffered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 5aebf88f997b..23a154c4e321 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -314,6 +314,9 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 
+	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
+		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
 	src_vq->requires_requests = true;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:55 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:55 +0800
Subject: [PATCH v5, 09/15] media: mtk-vcodec: disable vp8 4K capability
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-10-yunfei.dong@mediatek.com>

For vp8 not support 4K, need to disable it.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index bae43938ee37..ba188d16f0fb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -532,7 +532,8 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
 		if (!(ctx->dev->dec_capability &
-				VCODEC_CAPABILITY_4K_DISABLED)) {
+				VCODEC_CAPABILITY_4K_DISABLED) &&
+				fsize->pixel_format != V4L2_PIX_FMT_VP8_FRAME) {
 			mtk_v4l2_debug(3, "4K is enabled");
 			fsize->stepwise.max_width =
 					VCODEC_DEC_4K_CODED_WIDTH;
-- 
2.25.1



From yong.wu at mediatek.com  Mon Jan 17 01:41:18 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 17:41:18 +0800
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <e940d705-2057-4d5e-0a21-8464ca04caaf@gmail.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
 <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
 <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
 <e940d705-2057-4d5e-0a21-8464ca04caaf@gmail.com>
Message-ID: <ebbe29162688b230aec208a45762f795c850e396.camel@mediatek.com>

On Thu, 2022-01-13 at 17:10 +0100, Matthias Brugger wrote:
> Hi Hans,
> 
> On 13/01/2022 11:15, Hans Verkuil wrote:
> > On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote:
> > > Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
> > > > Il 12/11/21 11:55, Yong Wu ha scritto:
> > > > > After this patchset, mtk_vcodec_release_enc_pm has only one
> > > > > line.
> > > > > then remove that function, use pm_runtime_disable instead.
> > > > > 
> > > > > meanwhile, mtk_vcodec_init_enc_pm only operate for the
> > > > > clocks,
> > > > > rename it from the _pm to _clk.
> > > > > 
> > > > > No functional change.
> > > > > 
> > > > > CC: Tiffany Lin <tiffany.lin at mediatek.com>
> > > > > CC: Irui Wang <irui.wang at mediatek.com>
> > > > > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > > > 
> > > > Reviewed-by: AngeloGioacchino Del Regno <
> > > > angelogioacchino.delregno at collabora.com>
> > > > 
> > > 
> > > Hello Yong,
> > > the mtk-vcodec patches were merged in Yunfei's vcodec patch
> > > series and Hans has
> > > scheduled that for v5.18.
> > > 
> > > Can you please send a v10 and drop patches 10/15, 11/15, 12/15
> > > (all of the
> > > media: mtk-vcodec: *) from this series?

Hi Angelo,

   I have dropped 11/15 and 12/15 in v10 and rebase 10/15 on media tree
manually, thus I didn't keep your A-y for that one.

   Please take a look at that one.
 
   Thanks.

> > > 
> > > For the records, I think that after sending v10 this series is
> > > ready to be merged,
> > > as it was well reviewed and also tested on many MTK platforms.
> > 
> > Good to know. When I have the v10 I'll try to prioritize reviewing
> > it and running
> > my usual tests.

Hi Hans/Matthias,

v10: 
https://patchwork.linuxtv.org/project/linux-media/list/?series=7130

Please help take a look that one.

> > 
> > Yong, please make sure you run 'checkpatch.pl --strict' over the
> > v10 patches and fix
> > any issues (using common sense).

   Have run this on v10.

Thanks.
> > 
> 
> Can you please take me in the look when you take the patches. I'll
> take the DTS 
> related as soon as you queue up the others.
> 
> Thanks!
> Matthias
> 
> > Regards,
> > 
> > 	Hans
> > 
> > > 
> > > Thank you,
> > > - Angelo

From yunfei.dong at mediatek.com  Mon Jan 17 01:39:56 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:56 +0800
Subject: [PATCH v5, 10/15] media: mtk-vcodec: Fix v4l2-compliance fail
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-11-yunfei.dong@mediatek.com>

Need to use default pic info when get pic info fail.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index ba188d16f0fb..5a429ed83ed4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -478,11 +478,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ctx->picinfo.pic_w = pix_mp->width;
 		ctx->picinfo.pic_h = pix_mp->height;
 
+		/*
+		 * If get pic info fail, need to use the default pic info params, or
+		 * v4l2-compliance will fail
+		 */
 		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
 		if (ret) {
 			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
 				     ctx->id);
-			return -EINVAL;
 		}
 
 		ctx->last_decoded_picinfo = ctx->picinfo;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:57 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:57 +0800
Subject: [PATCH v5, 11/15] media: mtk-vcodec: record capture queue format type
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-12-yunfei.dong@mediatek.com>

Capture queue format type is difference for different platform,
need to calculate capture buffer size according to capture queue
format type in scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 5a429ed83ed4..6ad17e69e32d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -468,6 +468,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 			}
 			ctx->state = MTK_STATE_INIT;
 		}
+	} else {
+		ctx->capture_fourcc = fmt->fourcc;
 	}
 
 	/*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index aa608ab0a247..fde79684106d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -277,6 +277,7 @@ struct vdec_pic_info {
  *		     to be used with encoder and stateful decoder.
  * @is_flushing: set to true if flushing is in progress.
  * @current_codec: current set input codec, in V4L2 pixel format
+ * @capture_fourcc: capture queue type in V4L2 pixel format
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -324,6 +325,7 @@ struct mtk_vcodec_ctx {
 	bool is_flushing;
 
 	u32 current_codec;
+	u32 capture_fourcc;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:49 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:49 +0800
Subject: [PATCH v5,
 03/15] media: mtk-vcodec: get capture queue buffer size from scp
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-4-yunfei.dong@mediatek.com>

Different capture buffer format has different buffer size, need to get
real buffer size according to buffer type from scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 36 ++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 49 +++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   | 15 ++++++
 3 files changed, 100 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index bf54d6d9a857..47070be2a991 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -20,6 +20,7 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_RESET = 0xA004,
 	AP_IPIMSG_DEC_CORE = 0xA005,
 	AP_IPIMSG_DEC_CORE_END = 0xA006,
+	AP_IPIMSG_DEC_GET_PARAM = 0xA007,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
@@ -28,6 +29,7 @@ enum vdec_ipi_msgid {
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
 	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
 	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
+	VPU_IPIMSG_DEC_GET_PARAM_ACK = 0xB007,
 };
 
 /**
@@ -114,4 +116,38 @@ struct vdec_vpu_ipi_init_ack {
 	uint32_t inst_id;
 };
 
+/**
+ * struct vdec_ap_ipi_get_param - for AP_IPIMSG_DEC_GET_PARAM
+ * @msg_id	: AP_IPIMSG_DEC_GET_PARAM
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @data	: picture information
+ * @param_type	: get param type
+ * @codec_type	: Codec fourcc
+ */
+struct vdec_ap_ipi_get_param {
+	u32 msg_id;
+	u32 inst_id;
+	u32 data[4];
+	u32 param_type;
+	u32 codec_type;
+};
+
+/**
+ * struct vdec_vpu_ipi_get_param_ack - for VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @msg_id	: VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @status	: VPU execution result
+ * @ap_inst_addr	: AP vcodec_vpu_inst instance address
+ * @data     : picture information from SCP.
+ * @param_type	: get param type
+ * @reserved : reserved param
+ */
+struct vdec_vpu_ipi_get_param_ack {
+	u32 msg_id;
+	s32 status;
+	u64 ap_inst_addr;
+	u32 data[4];
+	u32 param_type;
+	u32 reserved;
+};
+
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 7210061c772f..35f4d5583084 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -6,6 +6,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
+#include "vdec_drv_if.h"
 #include "vdec_ipi_msg.h"
 #include "vdec_vpu_if.h"
 #include "mtk_vcodec_fw.h"
@@ -54,6 +55,26 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	}
 }
 
+static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *msg)
+{
+	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
+					(unsigned long)msg->ap_inst_addr;
+
+	mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr);
+
+	/* param_type is enum vdec_get_param_type */
+	switch (msg->param_type) {
+	case GET_PARAM_PIC_INFO:
+		vpu->fb_sz[0] = msg->data[0];
+		vpu->fb_sz[1] = msg->data[1];
+		break;
+	default:
+		mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type);
+		vpu->failure = 1;
+		break;
+	}
+}
+
 /*
  * vpu_dec_ipi_handler - Handler for VPU ipi message.
  *
@@ -89,6 +110,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
+		case VPU_IPIMSG_DEC_GET_PARAM_ACK:
+			handle_get_param_msg_ack(data);
+			break;
 		default:
 			mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id);
 			break;
@@ -217,6 +241,31 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+		      unsigned int len, unsigned int param_type)
+{
+	struct vdec_ap_ipi_get_param msg;
+	int err;
+
+	mtk_vcodec_debug_enter(vpu);
+
+	if (len > ARRAY_SIZE(msg.data)) {
+		mtk_vcodec_err(vpu, "invalid len = %d\n", len);
+		return -EINVAL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_id = AP_IPIMSG_DEC_GET_PARAM;
+	msg.inst_id = vpu->inst_id;
+	memcpy(msg.data, data, sizeof(unsigned int) * len);
+	msg.param_type = param_type;
+	msg.codec_type = vpu->codec_type;
+
+	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
+	mtk_vcodec_debug(vpu, "- ret=%d", err);
+	return err;
+}
+
 int vpu_dec_core(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 4cb3c7f5a3ad..d1feba41dd39 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -28,6 +28,8 @@ struct mtk_vcodec_ctx;
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
  * @codec_type     : use codec type to separate different codecs
+ * @capture_type    : used capture type to separate different capture format
+ * @fb_sz  : frame buffer size of each plane
  */
 struct vdec_vpu_inst {
 	int id;
@@ -42,6 +44,8 @@ struct vdec_vpu_inst {
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
 	unsigned int codec_type;
+	unsigned int capture_type;
+	unsigned int fb_sz[2];
 };
 
 /**
@@ -104,4 +108,15 @@ int vpu_dec_core(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_get_param - get param from scp
+ *
+ * @vpu : instance for vdec_vpu_inst
+ * @data: meta data to pass bitstream info to VPU decoder
+ * @len : meta data length
+ * @param_type : get param type
+ */
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+		      unsigned int len, unsigned int param_type);
+
 #endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:52 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:52 +0800
Subject: [PATCH v5,
 06/15] media: mtk-vcodec: Refactor get and put capture buffer flow
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-7-yunfei.dong@mediatek.com>

For lat and core decode in parallel, need to get capture buffer
when core start to decode and put capture buffer to display
list when core decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 121 ++++++++++++------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  16 ++-
 3 files changed, 102 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23a154c4e321..6d481410bf89 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -108,37 +108,87 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 
 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
 
-static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
-					       struct vdec_fb *fb)
+static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
+					   struct mtk_vcodec_mem *bs, int error)
 {
-	struct mtk_video_dec_buf *vdec_frame_buf =
-		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
-	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
-	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	struct mtk_video_dec_buf *out_buf;
+	struct vb2_v4l2_buffer *vb;
 
-	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
-	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		unsigned int cap_c_size =
-			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+	if (!bs) {
+		mtk_v4l2_err("Free bitstream buffer fail.");
+		return;
+	}
+	out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	vb = &out_buf->m2m_buf.vb;
 
-		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+	mtk_v4l2_debug(2, "Free bitsteam buffer id = %d to done_list",
+		       vb->vb2_buf.index);
+
+	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+	if (error) {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		if (error == -EIO)
+			out_buf->error = true;
+	} else {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
 	}
 }
 
-static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
-					   struct vb2_v4l2_buffer *vb2_v4l2)
+static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx,
+					   struct vdec_fb *fb, int error)
 {
-	struct mtk_video_dec_buf *framebuf =
-		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
-	struct vdec_fb *pfb = &framebuf->frame_buffer;
-	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+	struct mtk_video_dec_buf *vdec_frame_buf;
+	struct vb2_v4l2_buffer *vb;
+	unsigned int cap_y_size, cap_c_size;
+
+	if (!fb) {
+		mtk_v4l2_err("Free frame buffer fail.");
+		return;
+	}
+	vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf,
+				      frame_buffer);
+	vb = &vdec_frame_buf->m2m_buf.vb;
+
+	cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+
+	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
-	pfb->base_y.va = NULL;
+	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+
+	mtk_v4l2_debug(2, "Free frame buffer id = %d to done_list",
+		       vb->vb2_buf.index);
+	if (error)
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+	else
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+}
+
+static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_video_dec_buf *framebuf;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vb2_buffer *dst_buf;
+	struct vdec_fb *pfb;
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2) {
+		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
+		return NULL;
+	}
+
+	dst_buf = &vb2_v4l2->vb2_buf;
+	framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	pfb = &framebuf->frame_buffer;
+	pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
 	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
 	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
 
 	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		pfb->base_c.va = NULL;
+		pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
 		pfb->base_c.dma_addr =
 			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
 		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
@@ -162,12 +212,11 @@ static void mtk_vdec_worker(struct work_struct *work)
 	struct mtk_vcodec_ctx *ctx =
 		container_of(work, struct mtk_vcodec_ctx, decode_work);
 	struct mtk_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
+	struct vb2_v4l2_buffer *vb2_v4l2_src;
 	struct vb2_buffer *vb2_src;
 	struct mtk_vcodec_mem *bs_src;
 	struct mtk_video_dec_buf *dec_buf_src;
 	struct media_request *src_buf_req;
-	struct vdec_fb *dst_buf;
 	bool res_chg = false;
 	int ret;
 
@@ -178,13 +227,6 @@ static void mtk_vdec_worker(struct work_struct *work)
 		return;
 	}
 
-	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	if (!vb2_v4l2_dst) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
-		return;
-	}
-
 	vb2_src = &vb2_v4l2_src->vb2_buf;
 	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
 				   m2m_buf.vb);
@@ -193,9 +235,15 @@ static void mtk_vdec_worker(struct work_struct *work)
 	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
 		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
 
-	bs_src->va = NULL;
+	bs_src->va = vb2_plane_vaddr(vb2_src, 0);
 	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
 	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
+	if (!bs_src->va) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id,
+			     vb2_src->index);
+		return;
+	}
 
 	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
 		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
@@ -206,9 +254,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 	else
 		mtk_v4l2_err("vb2 buffer media request is NULL");
 
-	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
-	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
-	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+	ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
 	if (ret) {
 		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
 			     ctx->id, vb2_src->index, bs_src->size,
@@ -220,12 +266,9 @@ static void mtk_vdec_worker(struct work_struct *work)
 		}
 	}
 
-	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
-
-	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
-					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
+	mtk_vdec_stateless_out_to_done(ctx, bs_src, ret);
 	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
 static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
@@ -358,6 +401,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = false,
 	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
@@ -376,6 +421,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = true,
 	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 2d1d878692ca..e0b7d2fda632 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,7 +353,8 @@ enum mtk_vdec_hw_arch {
  * @ctrls_setup: init vcodec dec ctrls
  * @worker: worker to start a decode job
  * @flush_decoder: function that flushes the decoder
- *
+ * @get_cap_buffer: get capture buffer from capture queue
+ * @cap_to_disp: put capture buffer to disp list
  * @vdec_vb2_ops: struct vb2_ops
  *
  * @vdec_formats: supported video decoder formats
@@ -375,6 +376,8 @@ struct mtk_vcodec_dec_pdata {
 	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
 	void (*worker)(struct work_struct *work);
 	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
+	struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
+	void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, struct vdec_fb *fb, int error);
 
 	struct vb2_ops *vdec_vb2_ops;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 43542de11e9c..36f3dc1fbe3b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -670,32 +670,42 @@ static void vdec_h264_slice_deinit(void *h_vdec)
 }
 
 static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
-				  struct vdec_fb *fb, bool *res_chg)
+				  struct vdec_fb *unused, bool *res_chg)
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
 		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	struct mtk_video_dec_buf *dst_buf_info;
+	struct vdec_fb *fb;
 	u32 data[2];
 	u64 y_fb_dma;
 	u64 c_fb_dma;
 	int err;
 
+	inst->num_nalu++;
 	/* bs NULL means flush decoder */
 	if (!bs)
 		return vpu_dec_reset(vpu);
 
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
 	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
 	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
 
 	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
-			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+			 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
 
 	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
 	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
 	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
 	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
 
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &dst_buf_info->m2m_buf.vb, true);
 	get_vdec_decode_parameters(inst);
 	data[0] = bs->size;
 	/*
@@ -734,6 +744,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
 	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
+
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, 0);
 	return 0;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Mon Jan 17 01:39:58 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Mon, 17 Jan 2022 17:39:58 +0800
Subject: [PATCH v5, 12/15] media: mtk-vcodec: Extract H264 common code
In-Reply-To: <20220117094001.20049-1-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
Message-ID: <20220117094001.20049-13-yunfei.dong@mediatek.com>

Mt8192 can use some of common code with mt8183. Moves them to
a new file in order to reuse.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 307 ++++++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 253 +++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 395 +-----------------
 4 files changed, 579 insertions(+), 377 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 359619653a0e..3f41d748eee5 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
+		vdec/vdec_h264_req_common.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
new file mode 100644
index 000000000000..90e8c4906e2a
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include "vdec_h264_req_common.h"
+
+/* get used parameters for sps/pps */
+#define GET_MTK_VDEC_FLAG(cond, flag) \
+	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
+#define GET_MTK_VDEC_PARAM(param) \
+	{ dst_param->param = src_param->param; }
+
+/*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
+{
+	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
+}
+
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	return ctrl->p_cur.p;
+}
+
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+				 struct slice_api_h264_decode_param *decode_params,
+				 mtk_h264_dpb_info *h264_dpb_info)
+{
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	int index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
+		const struct slice_h264_dpb_entry *dpb;
+		int vb2_index;
+
+		dpb = &decode_params->dpb[index];
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
+			h264_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+
+		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
+		if (vb2_index < 0) {
+			dev_err(&ctx->dev->plat_dev->dev,
+				"Reference invalid: dpb_index(%d) reference_ts(%lld)",
+				index, dpb->reference_ts);
+			continue;
+		}
+
+		/* 1 for short term reference, 2 for long term reference */
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			h264_dpb_info[index].reference_flag = 1;
+		else
+			h264_dpb_info[index].reference_flag = 2;
+
+		vb = vq->bufs[vb2_index];
+		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
+		h264_dpb_info[index].field = vb2_v4l2->field;
+
+		h264_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			h264_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			h264_dpb_info[index].c_dma_addr =
+				h264_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+}
+
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+				   const struct v4l2_ctrl_h264_sps *src_param)
+{
+	GET_MTK_VDEC_PARAM(chroma_format_idc);
+	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
+	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
+	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
+	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
+	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
+	GET_MTK_VDEC_PARAM(max_num_ref_frames);
+	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
+	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
+
+	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
+			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
+	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
+			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
+			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
+			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
+			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
+			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+}
+
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+				   const struct v4l2_ctrl_h264_pps *src_param)
+{
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
+	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
+	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
+	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
+	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
+
+	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
+			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	GET_MTK_VDEC_FLAG(pic_order_present_flag,
+			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	GET_MTK_VDEC_FLAG(weighted_pred_flag,
+			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
+			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
+			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
+			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
+			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
+			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+}
+
+void mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param *dst_param,
+					const struct v4l2_ctrl_h264_slice_params *src_param,
+					const struct v4l2_ctrl_h264_decode_params *dec_param)
+{
+	int temp;
+
+	GET_MTK_VDEC_PARAM(first_mb_in_slice);
+	GET_MTK_VDEC_PARAM(slice_type);
+	GET_MTK_VDEC_PARAM(cabac_init_idc);
+	GET_MTK_VDEC_PARAM(slice_qp_delta);
+	GET_MTK_VDEC_PARAM(disable_deblocking_filter_idc);
+	GET_MTK_VDEC_PARAM(slice_alpha_c0_offset_div2);
+	GET_MTK_VDEC_PARAM(slice_beta_offset_div2);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_active_minus1);
+
+	dst_param->frame_num = dec_param->frame_num;
+	dst_param->pic_order_cnt_lsb = dec_param->pic_order_cnt_lsb;
+
+	dst_param->delta_pic_order_cnt_bottom =
+		dec_param->delta_pic_order_cnt_bottom;
+	dst_param->delta_pic_order_cnt0 =
+		dec_param->delta_pic_order_cnt0;
+	dst_param->delta_pic_order_cnt1 =
+		dec_param->delta_pic_order_cnt1;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
+	dst_param->field_pic_flag = temp ? 1 : 0;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD;
+	dst_param->bottom_field_flag = temp ? 1 : 0;
+
+	GET_MTK_VDEC_FLAG(direct_spatial_mv_pred_flag,
+			  V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
+}
+
+void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
+				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
+{
+	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
+	       sizeof(dst_matrix->scaling_list_4x4));
+
+	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
+	       sizeof(dst_matrix->scaling_list_8x8));
+}
+
+void
+mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
+				 const struct v4l2_ctrl_h264_decode_params *src_params,
+				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
+		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
+		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
+
+		dst_entry->reference_ts = src_entry->reference_ts;
+		dst_entry->frame_num = src_entry->frame_num;
+		dst_entry->pic_num = src_entry->pic_num;
+		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
+		dst_entry->bottom_field_order_cnt =
+			src_entry->bottom_field_order_cnt;
+		dst_entry->flags = src_entry->flags;
+	}
+
+	/* num_slices is a leftover from the old H.264 support and is ignored
+	 * by the firmware.
+	 */
+	dst_params->num_slices = 0;
+	dst_params->nal_ref_idc = src_params->nal_ref_idc;
+	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
+	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
+	dst_params->flags = src_params->flags;
+}
+
+static bool mtk_vdec_h264_dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
+					  const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+/*
+ * Move DPB entries of dec_param that refer to a frame already existing in dpb
+ * into the already existing slot in dpb, and move other entries into new slots.
+ *
+ * This function is an adaptation of the similarly-named function in
+ * hantro_h264.c.
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+			      struct v4l2_h264_dpb_entry *dpb)
+{
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	/* Disable all entries by default, and mark the ones in use. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			set_bit(i, in_use);
+		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+	}
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries were already used.
+		 */
+		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &dpb[j];
+			if (!mtk_vdec_h264_dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			/* Don't reiterate on this one. */
+			clear_bit(j, in_use);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(dec_param->dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
+			return;
+
+		cdpb = &dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+unsigned int mtk_vdec_h264_get_mv_buf_size(unsigned int width, unsigned int height)
+{
+	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
+
+	return HW_MB_STORE_SZ * unit_size;
+}
+
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz)
+{
+	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
+		return 3;
+
+	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
+	    data[3] == 1)
+		return 4;
+
+	return -1;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
new file mode 100644
index 000000000000..2d731bc777ca
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_H264_REQ_COMMON_H_
+#define _VDEC_H264_REQ_COMMON_H_
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_drv.h"
+
+#define NAL_NON_IDR_SLICE			0x01
+#define NAL_IDR_SLICE				0x05
+#define NAL_TYPE(value)				((value) & 0x1F)
+
+#define BUF_PREDICTION_SZ			(64 * 4096)
+#define MB_UNIT_LEN				16
+
+/* motion vector size (bytes) for every macro block */
+#define HW_MB_STORE_SZ				64
+
+#define H264_MAX_MV_NUM				32
+
+/**
+ * struct mtk_h264_dpb_info  - h264 dpb information
+ * @y_dma_addr: Y bitstream physical address
+ * @c_dma_addr: CbCr bitstream physical address
+ * @reference_flag: reference picture flag (short/long term reference picture)
+ * @field: field picture flag
+ */
+struct mtk_h264_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int field;
+};
+
+/**
+ * struct mtk_h264_sps_param  - parameters for sps
+ */
+struct mtk_h264_sps_param {
+	unsigned char chroma_format_idc;
+	unsigned char bit_depth_luma_minus8;
+	unsigned char bit_depth_chroma_minus8;
+	unsigned char log2_max_frame_num_minus4;
+	unsigned char pic_order_cnt_type;
+	unsigned char log2_max_pic_order_cnt_lsb_minus4;
+	unsigned char max_num_ref_frames;
+	unsigned char separate_colour_plane_flag;
+	unsigned short pic_width_in_mbs_minus1;
+	unsigned short pic_height_in_map_units_minus1;
+	unsigned int max_frame_nums;
+	unsigned char qpprime_y_zero_transform_bypass_flag;
+	unsigned char delta_pic_order_always_zero_flag;
+	unsigned char frame_mbs_only_flag;
+	unsigned char mb_adaptive_frame_field_flag;
+	unsigned char direct_8x8_inference_flag;
+	unsigned char reserved[3];
+};
+
+/**
+ * struct mtk_h264_pps_param  - parameters for pps
+ */
+struct mtk_h264_pps_param {
+	unsigned char num_ref_idx_l0_default_active_minus1;
+	unsigned char num_ref_idx_l1_default_active_minus1;
+	unsigned char weighted_bipred_idc;
+	char pic_init_qp_minus26;
+	char chroma_qp_index_offset;
+	char second_chroma_qp_index_offset;
+	unsigned char entropy_coding_mode_flag;
+	unsigned char pic_order_present_flag;
+	unsigned char deblocking_filter_control_present_flag;
+	unsigned char constrained_intra_pred_flag;
+	unsigned char weighted_pred_flag;
+	unsigned char redundant_pic_cnt_present_flag;
+	unsigned char transform_8x8_mode_flag;
+	unsigned char scaling_matrix_present_flag;
+	unsigned char reserved[2];
+};
+
+/**
+ * struct mtk_h264_slice_hd_param  - parameters for slice header
+ */
+struct mtk_h264_slice_hd_param {
+	unsigned int first_mb_in_slice;
+	unsigned int field_pic_flag;
+	unsigned int slice_type;
+	unsigned int frame_num;
+	int pic_order_cnt_lsb;
+	int delta_pic_order_cnt_bottom;
+	unsigned int bottom_field_flag;
+	unsigned int direct_spatial_mv_pred_flag;
+	int delta_pic_order_cnt0;
+	int delta_pic_order_cnt1;
+	unsigned int cabac_init_idc;
+	int slice_qp_delta;
+	unsigned int disable_deblocking_filter_idc;
+	int slice_alpha_c0_offset_div2;
+	int slice_beta_offset_div2;
+	unsigned int num_ref_idx_l0_active_minus1;
+	unsigned int num_ref_idx_l1_active_minus1;
+	unsigned int reserved;
+};
+
+struct slice_api_h264_scaling_matrix {
+	unsigned char scaling_list_4x4[6][16];
+	unsigned char scaling_list_8x8[6][64];
+};
+
+struct slice_h264_dpb_entry {
+	unsigned long long reference_ts;
+	unsigned short frame_num;
+	unsigned short pic_num;
+	/* Note that field is indicated by v4l2_buffer.field */
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+/**
+ * struct slice_api_h264_decode_param - parameters for decode.
+ */
+struct slice_api_h264_decode_param {
+	struct slice_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
+	unsigned short num_slices;
+	unsigned short nal_ref_idc;
+	unsigned char ref_pic_list_p0[32];
+	unsigned char ref_pic_list_b0[32];
+	unsigned char ref_pic_list_b1[32];
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+};
+
+/**
+ * struct h264_fb - h264 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct h264_fb {
+	u64 vdec_fb_va;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	s32 poc;
+	u32 reserved;
+};
+
+/**
+ * mtk_vdec_h264_fixup_ref_list - fixup unused reference to 0x20.
+ * @ref_list: reference picture list
+ * @num_valid: used reference number
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid);
+
+/**
+ * mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @id: CID control ID
+ */
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id);
+
+/**
+ * mtk_vdec_h264_fill_dpb_info - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @decode_params: slice decode params
+ * @h264_dpb_info: dpb buffer information
+ */
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+				 struct slice_api_h264_decode_param *decode_params,
+				 struct mtk_h264_dpb_info *h264_dpb_info);
+
+/**
+ * mtk_vdec_h264_copy_sps_params - get sps params.
+ * @dst_params: sps params for hw decoder
+ * @src_params: sps params from user driver
+ */
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+				   const struct v4l2_ctrl_h264_sps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_pps_params - get pps params.
+ * @dst_params: pps params for hw decoder
+ * @src_params: pps params from user driver
+ */
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+				   const struct v4l2_ctrl_h264_pps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_slice_hd_params - get slice header params.
+ * @dst_params: slice params for hw decoder
+ * @src_params: slice params from user driver
+ * @dec_param: decode params from user driver
+ */
+void mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param *dst_param,
+					const struct v4l2_ctrl_h264_slice_params *src_param,
+					const struct v4l2_ctrl_h264_decode_params *dec_param);
+
+/**
+ * mtk_vdec_h264_copy_scaling_matrix - get each CID contrl address.
+ * @dst_matrix: scaling list params for hw decoder
+ * @src_matrix: scaling list params from user driver
+ */
+void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
+				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix);
+
+/**
+ * mtk_vdec_h264_copy_decode_params - get decode params.
+ * @dst_params: dst params for hw decoder
+ * @src_params: decode params from user driver
+ * @dpb: dpb information
+ */
+void
+mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
+				 const struct v4l2_ctrl_h264_decode_params *src_params,
+				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);
+
+/**
+ * mtk_vdec_h264_update_dpb - updata dpb list.
+ * @dec_param: v4l2 control decode params
+ * @dpb: dpb entry informaton
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+			      struct v4l2_h264_dpb_entry *dpb);
+
+/**
+ * mtk_vdec_h264_find_start_code - find h264 start code using sofeware.
+ * @data: input buffer address
+ * @data_sz: input buffer size
+ *
+ * Return: returns start code position.
+ */
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz);
+
+/**
+ * mtk_vdec_h264_get_mv_buf_size - get mv buffer size.
+ * @width: picture width
+ * @height: picture height
+ *
+ * Return: returns mv buffer size.
+ */
+unsigned int mtk_vdec_h264_get_mv_buf_size(unsigned int width, unsigned int height);
+
+#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 36f3dc1fbe3b..f0f5872c89cd 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -12,109 +12,7 @@
 #include "../vdec_drv_base.h"
 #include "../vdec_drv_if.h"
 #include "../vdec_vpu_if.h"
-
-#define BUF_PREDICTION_SZ			(64 * 4096)
-#define MB_UNIT_LEN				16
-
-/* get used parameters for sps/pps */
-#define GET_MTK_VDEC_FLAG(cond, flag) \
-	{ dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
-#define GET_MTK_VDEC_PARAM(param) \
-	{ dst_param->param = src_param->param; }
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ				64
-
-#define H264_MAX_FB_NUM				17
-#define H264_MAX_MV_NUM				32
-#define HDR_PARSING_BUF_SZ			1024
-
-/**
- * struct mtk_h264_dpb_info  - h264 dpb information
- * @y_dma_addr: Y bitstream physical address
- * @c_dma_addr: CbCr bitstream physical address
- * @reference_flag: reference picture flag (short/long term reference picture)
- * @field: field picture flag
- */
-struct mtk_h264_dpb_info {
-	dma_addr_t y_dma_addr;
-	dma_addr_t c_dma_addr;
-	int reference_flag;
-	int field;
-};
-
-/*
- * struct mtk_h264_sps_param  - parameters for sps
- */
-struct mtk_h264_sps_param {
-	unsigned char chroma_format_idc;
-	unsigned char bit_depth_luma_minus8;
-	unsigned char bit_depth_chroma_minus8;
-	unsigned char log2_max_frame_num_minus4;
-	unsigned char pic_order_cnt_type;
-	unsigned char log2_max_pic_order_cnt_lsb_minus4;
-	unsigned char max_num_ref_frames;
-	unsigned char separate_colour_plane_flag;
-	unsigned short pic_width_in_mbs_minus1;
-	unsigned short pic_height_in_map_units_minus1;
-	unsigned int max_frame_nums;
-	unsigned char qpprime_y_zero_transform_bypass_flag;
-	unsigned char delta_pic_order_always_zero_flag;
-	unsigned char frame_mbs_only_flag;
-	unsigned char mb_adaptive_frame_field_flag;
-	unsigned char direct_8x8_inference_flag;
-	unsigned char reserved[3];
-};
-
-/*
- * struct mtk_h264_pps_param  - parameters for pps
- */
-struct mtk_h264_pps_param {
-	unsigned char num_ref_idx_l0_default_active_minus1;
-	unsigned char num_ref_idx_l1_default_active_minus1;
-	unsigned char weighted_bipred_idc;
-	char pic_init_qp_minus26;
-	char chroma_qp_index_offset;
-	char second_chroma_qp_index_offset;
-	unsigned char entropy_coding_mode_flag;
-	unsigned char pic_order_present_flag;
-	unsigned char deblocking_filter_control_present_flag;
-	unsigned char constrained_intra_pred_flag;
-	unsigned char weighted_pred_flag;
-	unsigned char redundant_pic_cnt_present_flag;
-	unsigned char transform_8x8_mode_flag;
-	unsigned char scaling_matrix_present_flag;
-	unsigned char reserved[2];
-};
-
-struct slice_api_h264_scaling_matrix {
-	unsigned char scaling_list_4x4[6][16];
-	unsigned char scaling_list_8x8[6][64];
-};
-
-struct slice_h264_dpb_entry {
-	unsigned long long reference_ts;
-	unsigned short frame_num;
-	unsigned short pic_num;
-	/* Note that field is indicated by v4l2_buffer.field */
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
-};
-
-/*
- * struct slice_api_h264_decode_param - parameters for decode.
- */
-struct slice_api_h264_decode_param {
-	struct slice_h264_dpb_entry dpb[16];
-	unsigned short num_slices;
-	unsigned short nal_ref_idc;
-	unsigned char ref_pic_list_p0[32];
-	unsigned char ref_pic_list_b0[32];
-	unsigned char ref_pic_list_b1[32];
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
-};
+#include "vdec_h264_req_common.h"
 
 /*
  * struct mtk_h264_dec_slice_param  - parameters for decode current frame
@@ -127,22 +25,6 @@ struct mtk_h264_dec_slice_param {
 	struct mtk_h264_dpb_info h264_dpb_info[16];
 };
 
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va  : virtual address of struct vdec_fb
- * @y_fb_dma    : dma address of Y frame buffer (luma)
- * @c_fb_dma    : dma address of C frame buffer (chroma)
- * @poc         : picture order count of frame buffer
- * @reserved    : for 8 bytes alignment
- */
-struct h264_fb {
-	u64 vdec_fb_va;
-	u64 y_fb_dma;
-	u64 c_fb_dma;
-	s32 poc;
-	u32 reserved;
-};
-
 /**
  * struct vdec_h264_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
@@ -212,265 +94,31 @@ struct vdec_h264_slice_inst {
 	struct v4l2_h264_dpb_entry dpb[16];
 };
 
-static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
-{
-	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
-
-	return ctrl->p_cur.p;
-}
-
-static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
-			      struct mtk_h264_dec_slice_param *slice_param)
-{
-	struct vb2_queue *vq;
-	struct vb2_buffer *vb;
-	struct vb2_v4l2_buffer *vb2_v4l2;
-	u64 index;
-
-	vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-
-	for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
-		const struct slice_h264_dpb_entry *dpb;
-		int vb2_index;
-
-		dpb = &slice_param->decode_params.dpb[index];
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
-			slice_param->h264_dpb_info[index].reference_flag = 0;
-			continue;
-		}
-
-		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
-		if (vb2_index < 0) {
-			mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
-				       index, dpb->reference_ts);
-			continue;
-		}
-		/* 1 for short term reference, 2 for long term reference */
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
-			slice_param->h264_dpb_info[index].reference_flag = 1;
-		else
-			slice_param->h264_dpb_info[index].reference_flag = 2;
-
-		vb = vq->bufs[vb2_index];
-		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-		slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
-
-		slice_param->h264_dpb_info[index].y_dma_addr =
-			vb2_dma_contig_plane_dma_addr(vb, 0);
-		if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-			slice_param->h264_dpb_info[index].c_dma_addr =
-				vb2_dma_contig_plane_dma_addr(vb, 1);
-		}
-	}
-}
-
-static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
-				    const struct v4l2_ctrl_h264_sps *src_param)
-{
-	GET_MTK_VDEC_PARAM(chroma_format_idc);
-	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
-	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
-	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
-	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
-	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
-	GET_MTK_VDEC_PARAM(max_num_ref_frames);
-	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
-	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
-
-	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
-			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
-	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
-			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
-	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
-			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
-	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
-			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
-	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
-			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
-	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
-			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-}
-
-static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
-				    const struct v4l2_ctrl_h264_pps *src_param)
-{
-	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
-	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
-	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
-	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
-	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
-	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
-
-	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
-			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
-	GET_MTK_VDEC_FLAG(pic_order_present_flag,
-			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
-	GET_MTK_VDEC_FLAG(weighted_pred_flag,
-			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
-	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
-			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
-	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
-			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
-	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
-			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
-	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
-			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
-	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
-			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-}
-
-static void
-get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
-			const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
-{
-	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
-	       sizeof(dst_matrix->scaling_list_4x4));
-
-	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
-	       sizeof(dst_matrix->scaling_list_8x8));
-}
-
-static void
-get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
-			   const struct v4l2_ctrl_h264_decode_params *src_params,
-			   const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
-		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
-		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
-
-		dst_entry->reference_ts = src_entry->reference_ts;
-		dst_entry->frame_num = src_entry->frame_num;
-		dst_entry->pic_num = src_entry->pic_num;
-		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
-		dst_entry->bottom_field_order_cnt =
-			src_entry->bottom_field_order_cnt;
-		dst_entry->flags = src_entry->flags;
-	}
-
-	/*
-	 * num_slices is a leftover from the old H.264 support and is ignored
-	 * by the firmware.
-	 */
-	dst_params->num_slices = 0;
-	dst_params->nal_ref_idc = src_params->nal_ref_idc;
-	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
-	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
-	dst_params->flags = src_params->flags;
-}
-
-static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
-			    const struct v4l2_h264_dpb_entry *b)
-{
-	return a->top_field_order_cnt == b->top_field_order_cnt &&
-	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
-}
-
-/*
- * Move DPB entries of dec_param that refer to a frame already existing in dpb
- * into the already existing slot in dpb, and move other entries into new slots.
- *
- * This function is an adaptation of the similarly-named function in
- * hantro_h264.c.
- */
-static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
-		       struct v4l2_h264_dpb_entry *dpb)
-{
-	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	unsigned int i, j;
-
-	/* Disable all entries by default, and mark the ones in use. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
-			set_bit(i, in_use);
-		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
-	}
-
-	/* Try to match new DPB entries with existing ones by their POCs. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-
-		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-			continue;
-
-		/*
-		 * To cut off some comparisons, iterate only on target DPB
-		 * entries were already used.
-		 */
-		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
-			struct v4l2_h264_dpb_entry *cdpb;
-
-			cdpb = &dpb[j];
-			if (!dpb_entry_match(cdpb, ndpb))
-				continue;
-
-			*cdpb = *ndpb;
-			set_bit(j, used);
-			/* Don't reiterate on this one. */
-			clear_bit(j, in_use);
-			break;
-		}
-
-		if (j == ARRAY_SIZE(dec_param->dpb))
-			set_bit(i, new);
-	}
-
-	/* For entries that could not be matched, use remaining free slots. */
-	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-		struct v4l2_h264_dpb_entry *cdpb;
-
-		/*
-		 * Both arrays are of the same sizes, so there is no way
-		 * we can end up with no space in target array, unless
-		 * something is buggy.
-		 */
-		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
-		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
-			return;
-
-		cdpb = &dpb[j];
-		*cdpb = *ndpb;
-		set_bit(j, used);
-	}
-}
-
-/*
- * The firmware expects unused reflist entries to have the value 0x20.
- */
-static void fixup_ref_list(u8 *ref_list, size_t num_valid)
-{
-	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
-}
-
 static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 {
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	const struct v4l2_ctrl_h264_sps *sps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
 	const struct v4l2_ctrl_h264_pps *pps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
 	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
 	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
 	struct v4l2_h264_reflist_builder reflist_builder;
 	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
 	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
 	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
 
-	update_dpb(dec_params, inst->dpb);
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
 
-	get_h264_sps_parameters(&slice_param->sps, sps);
-	get_h264_pps_parameters(&slice_param->pps, pps);
-	get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
-	get_h264_decode_parameters(&slice_param->decode_params, dec_params,
-				   inst->dpb);
-	get_h264_dpb_list(inst, slice_param);
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params,
+					 dec_params, inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+				    slice_param->h264_dpb_info);
 
 	/* Build the reference lists */
 	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
@@ -478,21 +126,14 @@ static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
 	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
 	/* Adapt the built lists to the firmware's expectations */
-	fixup_ref_list(p0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
 
 	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
 	       sizeof(inst->vsi_ctx.h264_slice_params));
 }
 
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
-	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
-
-	return HW_MB_STORE_SZ * unit_size;
-}
-
 static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
 {
 	int err;
@@ -525,7 +166,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
 	int i;
 	int err;
 	struct mtk_vcodec_mem *mem = NULL;
-	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
 
 	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
 	for (i = 0; i < H264_MAX_MV_NUM; i++) {
@@ -674,7 +315,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
 	struct mtk_video_dec_buf *src_buf_info;
 	struct mtk_video_dec_buf *dst_buf_info;
-- 
2.25.1



From amelie.delaunay at foss.st.com  Mon Jan 17 02:03:00 2022
From: amelie.delaunay at foss.st.com (Amelie Delaunay)
Date: Mon, 17 Jan 2022 11:03:00 +0100
Subject: [PATCH] dmaengine: stm32-mdma: check the channel availability (secure
 or not)
Message-ID: <20220117100300.14150-1-amelie.delaunay@foss.st.com>

STM32_MDMA_CCR bit[8] is used to enable Secure Mode (SM). If this bit is
set, it means that all the channel registers are write-protected. So the
channel is not available for Linux use.

Add stm32_mdma_filter_fn() callback filter and give it to
__dma_request_chan (instead of dma_get_any_slave_channel()), to exclude the
channel if it is marked Secure.

Signed-off-by: Amelie Delaunay <amelie.delaunay at foss.st.com>
---
 drivers/dma/stm32-mdma.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c
index 6f57ff0e7b37..95e5831e490a 100644
--- a/drivers/dma/stm32-mdma.c
+++ b/drivers/dma/stm32-mdma.c
@@ -73,6 +73,7 @@
 #define STM32_MDMA_CCR_WEX		BIT(14)
 #define STM32_MDMA_CCR_HEX		BIT(13)
 #define STM32_MDMA_CCR_BEX		BIT(12)
+#define STM32_MDMA_CCR_SM		BIT(8)
 #define STM32_MDMA_CCR_PL_MASK		GENMASK(7, 6)
 #define STM32_MDMA_CCR_PL(n)		FIELD_PREP(STM32_MDMA_CCR_PL_MASK, (n))
 #define STM32_MDMA_CCR_TCIE		BIT(5)
@@ -248,6 +249,7 @@ struct stm32_mdma_device {
 	u32 nr_channels;
 	u32 nr_requests;
 	u32 nr_ahb_addr_masks;
+	u32 chan_reserved;
 	struct stm32_mdma_chan chan[STM32_MDMA_MAX_CHANNELS];
 	u32 ahb_addr_masks[];
 };
@@ -1456,10 +1458,23 @@ static void stm32_mdma_free_chan_resources(struct dma_chan *c)
 	chan->desc_pool = NULL;
 }
 
+static bool stm32_mdma_filter_fn(struct dma_chan *c, void *fn_param)
+{
+	struct stm32_mdma_chan *chan = to_stm32_mdma_chan(c);
+	struct stm32_mdma_device *dmadev = stm32_mdma_get_dev(chan);
+
+	/* Check if chan is marked Secure */
+	if (dmadev->chan_reserved & BIT(chan->id))
+		return false;
+
+	return true;
+}
+
 static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec,
 					    struct of_dma *ofdma)
 {
 	struct stm32_mdma_device *dmadev = ofdma->of_dma_data;
+	dma_cap_mask_t mask = dmadev->ddev.cap_mask;
 	struct stm32_mdma_chan *chan;
 	struct dma_chan *c;
 	struct stm32_mdma_chan_config config;
@@ -1485,7 +1500,7 @@ static struct dma_chan *stm32_mdma_of_xlate(struct of_phandle_args *dma_spec,
 		return NULL;
 	}
 
-	c = dma_get_any_slave_channel(&dmadev->ddev);
+	c = __dma_request_channel(&mask, stm32_mdma_filter_fn, &config, ofdma->of_node);
 	if (!c) {
 		dev_err(mdma2dev(dmadev), "No more channels available\n");
 		return NULL;
@@ -1615,6 +1630,10 @@ static int stm32_mdma_probe(struct platform_device *pdev)
 	for (i = 0; i < dmadev->nr_channels; i++) {
 		chan = &dmadev->chan[i];
 		chan->id = i;
+
+		if (stm32_mdma_read(dmadev, STM32_MDMA_CCR(i)) & STM32_MDMA_CCR_SM)
+			dmadev->chan_reserved |= BIT(i);
+
 		chan->vchan.desc_free = stm32_mdma_desc_free;
 		vchan_init(&chan->vchan, dd);
 	}
-- 
2.25.1



From narmstrong at baylibre.com  Mon Jan 17 02:08:38 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 11:08:38 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
Message-ID: <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>

Hi again,

On 14/01/2022 15:40, Neil Armstrong wrote:
> Hi,
> 
> On 14/01/2022 15:23, Biju Das wrote:
>>
>>
>>> -----Original Message-----
>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>> Sent: 14 January 2022 13:56
>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>> <festevam at gmail.com>
>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>> callbacks")
>>>
>>> Hi,
>>>
>>> On 14/01/2022 12:08, Biju Das wrote:
>>>> Hi Neil,
>>>>
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>> + renesas-soc
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>> Hi Biju,
>>>>>>>>
>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> Hi All,
>>>>>>>>>
>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>>> till the commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>> fmts
>>>>>>> callbacks").
>>>>>>>>>
>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>> setting it
>>>>>>> into YUV format??).
>>>>>>>>>
>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>> callback
>>>>>>> and set colour as RGB24.
>>>>>>>>>
>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>>> I see
>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>
>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>>
>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>>> the negotiation callbacks.
>>>>>>>
>>>>>>> Let me check the code to see how to fix that.
>>>>>>
>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>
>>>>>> Cheers,
>>>>>> Biju
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>>> shows:
>>>>>>>>
>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>
>>>>>>>> The colors are shown correctly here.
>>>>>>>>
>>>>>>>
>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>
>>>>>>> Anyway thanks for testing
>>>>>>>
>>>>>>> Neil
>>>>>
>>>>> Can you test :
>>>>>
>>>>> ==><===============================
>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>> 100644
>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>> drm_bridge *bridge,
>>>>>         last_bridge_state =
>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>> state,
>>>>>
>>>>> last_bridge);
>>>>>
>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>> +       /*
>>>>> +        * Only negociate with real values if both end of the bridge
>>> chain
>>>>> +        * support negociation callbacks, otherwise you can end in a
>>>>> situation
>>>>> +        * where the selected output format doesn't match with the
>>>>> + first
>>>>> bridge
>>>>> +        * output format.
>>>>> +        */
>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>> last_bridge->funcs;
>>>>>
>>>>>                 /*
>>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>> drm_bridge *bridge,
>>>>>                 if (!out_bus_fmts)
>>>>>                         return -ENOMEM;
>>>>>
>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>> +               /*
>>>>> +                * If first bridge doesn't support negociation, use
>>>>> MEDIA_BUS_FMT_FIXED
>>>>> +                * as a safe value for the whole bridge chain
>>>>> +                */
>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>                     conn->display_info.bus_formats)
>>>>>                         out_bus_fmts[0] = conn-
>>>>>> display_info.bus_formats[0];
>>>>>                 else
>>>>> ==><===============================
>>>>>
>>>>> This should exclude your situation where the first bridge doesn't
>>>>> support negociation.
>>>>
>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>> issue.
>>>>
>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>
>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>
>>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>>> of RGB24.
>>>>
>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>> [    3.473644] ########hdmi_video_sample
>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>
>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>>> encoder.
>>
>> Yep.
>>
>>>
>>> Let me figure that out, no sure I can find a clean solution except putting
>>> back RGB24 before YUV.
>>>
>>> Anyway please test that:
>>
>> It works now after reordering.
>>
>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>
>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
>> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
>>
>> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
>> at least it is fixing the colour issue??
> 
> Yes, it gets back to default behavior before negociation, nevertheless we need to think
> how to handle your use-case correctly at some point.
> 
> I'll post this as a patch ASAP so it gets applied before landing in linus master.
> 
> Neil
> 
>>
>> Regards,
>> Biju
>>
>>>
[...]

I'm not happy with this version since it's merely a hack which makes it work.

Can you test the following change instead, it's correctly handles your situation in a generic manner.

========================><=============================
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 54d8fdad395f..9f2e1cac0ae2 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
        if (!output_fmts)
                return NULL;

-       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
-       if (list_is_singular(&bridge->encoder->bridge_chain)) {
+       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
+       if (list_is_singular(&bridge->encoder->bridge_chain) ||
+           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
                *num_output_fmts = 1;
                output_fmts[0] = MEDIA_BUS_FMT_FIXED;

@@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
        if (!input_fmts)
                return NULL;

+       /* If dw-hdmi is the first bridge fall-back to safe output format */
+       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
+               output_fmt = MEDIA_BUS_FMT_FIXED;
+
        switch (output_fmt) {
        /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
        case MEDIA_BUS_FMT_FIXED:
========================><=============================

Thanks,
Neil


>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>
> 



From alexandru.elisei at arm.com  Mon Jan 17 02:19:15 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 17 Jan 2022 10:19:15 +0000
Subject: [PATCH v5 11/69] KVM: arm64: nv: Add nested virt VCPU primitives
 for vEL2 VCPU state
In-Reply-To: <87lezh8a4b.wl-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-12-maz@kernel.org>
 <YeG17OWrvFPQjgjS@monolith.localdoman>
 <87lezh8a4b.wl-maz@kernel.org>
Message-ID: <YeVCoyiGxXdBwykK@monolith.localdoman>

Hi Marc,

On Sat, Jan 15, 2022 at 12:19:16PM +0000, Marc Zyngier wrote:
> On Fri, 14 Jan 2022 17:42:04 +0000,
> Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> > 
> > Hi Marc,
> > 
> > Bunch of bikeshedding regarding names below, which can be safely ignored.
> > 
> > On Mon, Nov 29, 2021 at 08:00:52PM +0000, Marc Zyngier wrote:
> > > From: Christoffer Dall <christoffer.dall at arm.com>
> > > 
> > > When running a nested hypervisor we commonly have to figure out if
> > > the VCPU mode is running in the context of a guest hypervisor or guest
> > > guest, or just a normal guest.
> > > 
> > > Add convenient primitives for this.
> > > 
> > > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > > ---
> > >  arch/arm64/include/asm/kvm_emulate.h | 55 ++++++++++++++++++++++++++++
> > >  1 file changed, 55 insertions(+)
> > > 
> > > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > > index f4871e47b2d0..f4b079945d0f 100644
> > > --- a/arch/arm64/include/asm/kvm_emulate.h
> > > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > > @@ -176,6 +176,61 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
> > >  		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
> > >  }
> > >  
> > > +static inline bool vcpu_mode_el2_ctxt(const struct kvm_cpu_context *ctxt)
> > 
> > "The Armv8-A architecture defines a set of Exception levels, EL0 to EL3" (ARM
> > DDI 0487G.a, page G1-5941).
> > 
> > "AArch64 state does not support modes. Modes are a concept that is specific to
> > AArch32 state." (ARM DDI 0487G.a, page G1-5944).
> > 
> > Wouldn't it be better to use the same terminology as the architecture?
> 
> Probably. I'll see how invasive it is to repaint this. It still
> remains that the 'mode' term is used all over the shop (for example,
> PSR_MODE_*).

It might be easier if it's a separate patch on top of this series, instead
of renaming the function in (potentially) every patch that follows. I can
write that patch, if it helps.

> 
> > > +{
> > > +	unsigned long cpsr = ctxt->regs.pstate;
> > 
> > CPSR is an AArch32 register. Why not name the variable pstate?
> 
> Because we have *a ton* of existing CPSR references all over the shop
> (more than references to pstate, actually), owing to the AArch32
> heritage of KVM/arm64. Yes, I can change this locally without any
> damage. But repainting the whole of KVM would be fairly pointless
> (same with hsr/esr, hfar/far_el2...).

That's fine, I wasn't suggesting replacing it everywhere, that's too
invasive.

> 
> > 
> > > +
> > > +	switch (cpsr & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
> > > +	case PSR_MODE_EL2h:
> > > +	case PSR_MODE_EL2t:
> > > +		return true;
> > > +	default:
> > > +		return false;
> > > +	}
> > > +}
> > > +
> > > +static inline bool vcpu_mode_el2(const struct kvm_vcpu *vcpu)
> > > +{
> > > +	return vcpu_mode_el2_ctxt(&vcpu->arch.ctxt);
> > > +}
> > > +
> > > +static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
> > > +{
> > > +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
> > > +}
> > > +
> > > +static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
> > > +{
> > > +	return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
> > > +}
> > > +
> > > +static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
> > > +{
> > > +	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
> > > +}
> > > +
> > > +static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
> > 
> > This is confusing. What does the exception level have to do with the
> > HCR_EL2.TGE bit being set? Wouldn't vcpu_hcr_tge_is_set() be better?
> 
> Sure, why not. Again, I'll see how invasive such a repainting is
> across 70 patches.
> 
> > 
> > > +{
> > > +	return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
> > > +}
> > > +
> > > +static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
> > > +{
> > > +	/*
> > > +	 * We are in a hypervisor context if the vcpu mode is EL2 or
> > > +	 * E2H and TGE bits are set. The latter means we are in the user space
> > > +	 * of the VHE kernel. ARMv8.1 ARM describes this as 'InHost'
> > 
> > So why not call the function vcpu_is_inhost() or something along
> > those lines to match the architecture?
> 
> Because this is not the architectural 'InHost' primitive, which
> returns 'false' if HCR_EL2.E2H==0. The second term of the expression
> could be written in terms of an InHost primitive, but that's about it.

That's true, my mistake.

Thanks,
Alex

> 
> > 
> > Thanks,
> > Alex
> > 
> > > +	 */
> > > +	return vcpu_mode_el2_ctxt(ctxt) ||
> > > +		(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
> > > +		WARN_ON(__vcpu_el2_tge_is_set(ctxt));
> > > +}
> > > +
> > > +static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
> > > +{
> > > +	return __is_hyp_ctxt(&vcpu->arch.ctxt);
> > > +}
> > > +
> > >  /*
> > >   * The layout of SPSR for an AArch32 state is different when observed from an
> > >   * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
> 
> Thanks,
> 
> 	M.
> 
> -- 
> Without deviation from the norm, progress is not possible.


From lecopzer.chen at mediatek.com  Mon Jan 17 02:19:10 2022
From: lecopzer.chen at mediatek.com (Lecopzer Chen)
Date: Mon, 17 Jan 2022 18:19:10 +0800
Subject: [PATCHv3 0/4] watchdog_hld cleanup and async model for arm64
In-Reply-To: <20211014024155.15253-1-kernelfans@gmail.com>
References: <20211014024155.15253-1-kernelfans@gmail.com>
Message-ID: <20220117101910.14999-1-lecopzer.chen@mediatek.com>

Hi Pingfan,

Is this thread sill in progress?
We are looking for the upstream solution for ARM64 Hardlockup detector.

I'd appreciate it if someone keep working on it,
if not, I can take over it.



thanks!

-Lecopzer




From xiaolei.wang at windriver.com  Mon Jan 17 02:17:35 2022
From: xiaolei.wang at windriver.com (Xiaolei Wang)
Date: Mon, 17 Jan 2022 18:17:35 +0800
Subject: [PATCH] pci: imx: disable reglator when imx6_pcie_probe fails
Message-ID: <20220117101735.3512039-1-xiaolei.wang@windriver.com>

From: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>

disable reglator when imx6_pcie_probe fails,
otherwise the following calltrace will appear

[ 3.785075] ------------[ cut here ]------------
[ 3.788142] Registering SWP/SWPB emulation handler
[ 3.789853] WARNING: CPU: 0 PID: 7 at drivers/regulator/core.c:2257 _regulator_put.part.0+0x1bc/0x1e0
[ 3.795680] Loading compiled-in X.509 certificates
[ 3.803947] Modules linked in:
[ 3.811922] CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 5.16.0-10645-g3c750c7b6143-dirty #9
[ 3.820393] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[ 3.826945] Workqueue: events_unbound async_run_entry_fn
[ 3.832304] unwind_backtrace from show_stack+0x10/0x14
[ 3.837569] show_stack from dump_stack_lvl+0x58/0x70
[ 3.842663] dump_stack_lvl from __warn+0xd8/0x114
[ 3.847493] __warn from warn_slowpath_fmt+0x5c/0xc4
[ 3.852490] warn_slowpath_fmt from _regulator_put.part.0+0x1bc/0x1e0
[ 3.858968] _regulator_put.part.0 from regulator_put+0x2c/0x3c
[ 3.864918] regulator_put from release_nodes+0x50/0x178
[ 3.870270] release_nodes from devres_release_all+0x80/0xd0
[ 3.875968] devres_release_all from really_probe+0xdc/0x30c
[ 3.881661] really_probe from __driver_probe_device+0x80/0xe4
[ 3.887522] __driver_probe_device from driver_probe_device+0x30/0xd4
[ 3.893991] driver_probe_device from __driver_attach_async_helper+0x20/0x38
[ 3.901068] __driver_attach_async_helper from async_run_entry_fn+0x20/0xb4
[ 3.908059] async_run_entry_fn from process_one_work+0x298/0x7d0
[ 3.914188] process_one_work from worker_thread+0x30/0x510
[ 3.919792] worker_thread from kthread+0x128/0x14c
[ 3.924705] kthread from ret_from_fork+0x14/0x38
[ 3.929443] Exception stack(0xc20cbfb0 to 0xc20cbff8)
[ 3.934521] bfa0: 00000000 00000000 00000000 00000000
[ 3.942722] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 3.950922] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
[ 3.957677] irq event stamp: 1207
[ 3.961024] hardirqs last enabled at (1215): [<c0198270>] __up_console_sem+0x50/0x60
[ 3.968974] hardirqs last disabled at (1224): [<c019825c>] __up_console_sem+0x3c/0x60
[ 3.976911] softirqs last enabled at (1206): [<c010150c>] __do_softirq+0x2ec/0x5a4
[ 3.984669] softirqs last disabled at (1197): [<c012ef08>] irq_exit+0x18c/0x20c
[ 3.992021] ---[ end trace 45a52c023bf8fb33 ]---

Signed-off-by: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6974bd5aa116..f8279a15463b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1216,7 +1216,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 
 	ret = dw_pcie_host_init(&pci->pp);
 	if (ret < 0)
-		return ret;
+		goto err_vpcie;
 
 	if (pci_msi_enabled()) {
 		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
@@ -1226,6 +1226,11 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	}
 
 	return 0;
+
+err_vpcie:
+	regulator_disable(imx6_pcie->vpcie);
+
+	return ret;
 }
 
 static void imx6_pcie_shutdown(struct platform_device *pdev)
-- 
2.25.1



From xiaolei.wang at windriver.com  Mon Jan 17 02:21:37 2022
From: xiaolei.wang at windriver.com (Xiaolei Wang)
Date: Mon, 17 Jan 2022 18:21:37 +0800
Subject: [PATCH] pci: imx: disable reglator when imx6_pcie_probe fails
Message-ID: <20220117102137.3513439-1-xiaolei.wang@windriver.com>

From: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>

disable reglator when imx6_pcie_probe fails,
otherwise the following calltrace will appear

[ 3.785075] ------------[ cut here ]------------
[ 3.788142] Registering SWP/SWPB emulation handler
[ 3.789853] WARNING: CPU: 0 PID: 7 at drivers/regulator/core.c:2257 _regulator_put.part.0+0x1bc/0x1e0
[ 3.795680] Loading compiled-in X.509 certificates
[ 3.803947] Modules linked in:
[ 3.811922] CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 5.16.0-10645-g3c750c7b6143-dirty #9
[ 3.820393] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[ 3.826945] Workqueue: events_unbound async_run_entry_fn
[ 3.832304] unwind_backtrace from show_stack+0x10/0x14
[ 3.837569] show_stack from dump_stack_lvl+0x58/0x70
[ 3.842663] dump_stack_lvl from __warn+0xd8/0x114
[ 3.847493] __warn from warn_slowpath_fmt+0x5c/0xc4
[ 3.852490] warn_slowpath_fmt from _regulator_put.part.0+0x1bc/0x1e0
[ 3.858968] _regulator_put.part.0 from regulator_put+0x2c/0x3c
[ 3.864918] regulator_put from release_nodes+0x50/0x178
[ 3.870270] release_nodes from devres_release_all+0x80/0xd0
[ 3.875968] devres_release_all from really_probe+0xdc/0x30c
[ 3.881661] really_probe from __driver_probe_device+0x80/0xe4
[ 3.887522] __driver_probe_device from driver_probe_device+0x30/0xd4
[ 3.893991] driver_probe_device from __driver_attach_async_helper+0x20/0x38
[ 3.901068] __driver_attach_async_helper from async_run_entry_fn+0x20/0xb4
[ 3.908059] async_run_entry_fn from process_one_work+0x298/0x7d0
[ 3.914188] process_one_work from worker_thread+0x30/0x510
[ 3.919792] worker_thread from kthread+0x128/0x14c
[ 3.924705] kthread from ret_from_fork+0x14/0x38
[ 3.929443] Exception stack(0xc20cbfb0 to 0xc20cbff8)
[ 3.934521] bfa0: 00000000 00000000 00000000 00000000
[ 3.942722] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[ 3.950922] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
[ 3.957677] irq event stamp: 1207
[ 3.961024] hardirqs last enabled at (1215): [<c0198270>] __up_console_sem+0x50/0x60
[ 3.968974] hardirqs last disabled at (1224): [<c019825c>] __up_console_sem+0x3c/0x60
[ 3.976911] softirqs last enabled at (1206): [<c010150c>] __do_softirq+0x2ec/0x5a4
[ 3.984669] softirqs last disabled at (1197): [<c012ef08>] irq_exit+0x18c/0x20c
[ 3.992021] ---[ end trace 45a52c023bf8fb33 ]---

Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6974bd5aa116..f8279a15463b 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -1216,7 +1216,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 
 	ret = dw_pcie_host_init(&pci->pp);
 	if (ret < 0)
-		return ret;
+		goto err_vpcie;
 
 	if (pci_msi_enabled()) {
 		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
@@ -1226,6 +1226,11 @@ static int imx6_pcie_probe(struct platform_device *pdev)
 	}
 
 	return 0;
+
+err_vpcie:
+	regulator_disable(imx6_pcie->vpcie);
+
+	return ret;
 }
 
 static void imx6_pcie_shutdown(struct platform_device *pdev)
-- 
2.25.1



From paul at crapouillou.net  Mon Jan 17 02:25:11 2022
From: paul at crapouillou.net (Paul Cercueil)
Date: Mon, 17 Jan 2022 10:25:11 +0000
Subject: [PATCH 1/2] iio: imu: st_lsm6dsx: Limit requested watermark value to
 hwfifo size
Message-ID: <20220117102512.31725-1-paul@crapouillou.net>

Instead of returning an error if the watermark value is too high, which
the core will silently ignore anyway, limit the value to the hardware
FIFO size; a lower-than-requested value is still better than using the
default, which is usually 1.

Cc: Lorenzo Bianconi <lorenzo.bianconi83 at gmail.com>
Signed-off-by: Paul Cercueil <paul at crapouillou.net>
---
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
index 727b4b6ac696..5fd46bf1a11b 100644
--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
+++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
@@ -54,6 +54,7 @@
 #include <linux/iio/sysfs.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/minmax.h>
 #include <linux/pm.h>
 #include <linux/property.h>
 #include <linux/regmap.h>
@@ -1607,8 +1608,7 @@ int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
 	struct st_lsm6dsx_hw *hw = sensor->hw;
 	int err;
 
-	if (val < 1 || val > hw->settings->fifo_ops.max_size)
-		return -EINVAL;
+	val = clamp_val(val, 1, hw->settings->fifo_ops.max_size);
 
 	mutex_lock(&hw->conf_lock);
 
-- 
2.34.1



From paul at crapouillou.net  Mon Jan 17 02:25:12 2022
From: paul at crapouillou.net (Paul Cercueil)
Date: Mon, 17 Jan 2022 10:25:12 +0000
Subject: [PATCH 2/2] iio: at91-sama5d2: Limit requested watermark value to
 hwfifo size
In-Reply-To: <20220117102512.31725-1-paul@crapouillou.net>
References: <20220117102512.31725-1-paul@crapouillou.net>
Message-ID: <20220117102512.31725-2-paul@crapouillou.net>

Instead of returning an error if the watermark value is too high, which
the core will silently ignore anyway, limit the value to the hardware
FIFO size; a lower-than-requested value is still better than using the
default, which is usually 1.

Cc: Eugen Hristev <eugen.hristev at microchip.com>
Cc: Nicolas Ferre <nicolas.ferre at microchip.com>
Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
Cc: Ludovic Desroches <ludovic.desroches at microchip.com>
Signed-off-by: Paul Cercueil <paul at crapouillou.net>
---
 drivers/iio/adc/at91-sama5d2_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
index 854b1f81d807..5cc84f4a17bb 100644
--- a/drivers/iio/adc/at91-sama5d2_adc.c
+++ b/drivers/iio/adc/at91-sama5d2_adc.c
@@ -1752,7 +1752,7 @@ static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val)
 	int ret;
 
 	if (val > AT91_HWFIFO_MAX_SIZE)
-		return -EINVAL;
+		val = AT91_HWFIFO_MAX_SIZE;
 
 	if (!st->selected_trig->hw_trig) {
 		dev_dbg(&indio_dev->dev, "we need hw trigger for DMA\n");
-- 
2.34.1



From iivanov at suse.de  Mon Jan 17 02:25:04 2022
From: iivanov at suse.de (Ivan T. Ivanov)
Date: Mon, 17 Jan 2022 11:25:04 +0100
Subject: [PATCH] i2c: bcm2835: Set clock-stretch timeout to 35ms
Message-ID: <20220117102504.90585-1-iivanov@suse.de>

From: Phil Elwell <phil at raspberrypi.org>

The BCM2835 I2C blocks have a register to set the clock-stretch
timeout - how long the device is allowed to hold SCL low - in bus
cycles. The current driver doesn't write to the register, therefore
the default value of 64 cycles is being used for all devices.

Set the timeout to the value recommended for SMBus - 35ms.

See: https://github.com/raspberrypi/linux/issues/3064

Signed-off-by: Phil Elwell <phil at raspberrypi.org>
[iivanov at suse.de fix small coding style issue]
Signed-off-by: Ivan T. Ivanov <iivanov at suse.de>
---
 drivers/i2c/busses/i2c-bcm2835.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
index 37443edbf754..9cce0e15da32 100644
--- a/drivers/i2c/busses/i2c-bcm2835.c
+++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -106,6 +106,7 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw);
 	u32 redl, fedl;
+	u32 clk_tout;
 	u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate);
 
 	if (divider == -EINVAL)
@@ -129,6 +130,17 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
 	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL,
 			   (fedl << BCM2835_I2C_FEDL_SHIFT) |
 			   (redl << BCM2835_I2C_REDL_SHIFT));
+
+	/*
+	 * Set the clock stretch timeout to the SMBUs-recommended 35ms.
+	 */
+	if (rate > 0xffff * 1000 / 35)
+		clk_tout = 0xffff;
+	else
+		clk_tout = 35 * rate / 1000;
+
+	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout);
+
 	return 0;
 }
 
-- 
2.26.2



From angelogioacchino.delregno at collabora.com  Mon Jan 17 02:27:51 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 17 Jan 2022 11:27:51 +0100
Subject: [PATCH v10 00/13] Clean up "mediatek,larb"
In-Reply-To: <20220117070510.17642-1-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
Message-ID: <06e5e76c-557a-20a5-b8dd-37b25b3384a3@collabora.com>

Il 17/01/22 08:04, Yong Wu ha scritto:
> MediaTek IOMMU block diagram always like below:
> 
>          M4U
>           |
>      smi-common
>           |
>    -------------
>    |         |  ...
>    |         |
> larb1     larb2
>    |         |
> vdec       venc
> 
> All the consumer connect with smi-larb, then connect with smi-common.
> 
> When the consumer works, it should enable the smi-larb's power which also
> need enable the smi-common's power firstly.
> 
> Thus, Firstly, use the device link connect the consumer and the
> smi-larbs. then add device link between the smi-larb and smi-common.
> 
> After adding the device_link, then "mediatek,larb" property can be removed.
> the iommu consumer don't need call the mtk_smi_larb_get/put to enable
> the power and clock of smi-larb and smi-common.
> 
> Base on the media branch [1] and a jpeg dtbinding patchset[2] that already got
> the necessary R-b.
> 
> [1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d
> [2] https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsinyi at chromium.org/
> 
> Change notes:
> v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches.
>       b) Add Joerg's Ack for iommu patches.
> 
> v9: https://lore.kernel.org/linux-mediatek/20211112105509.12010-1-yong.wu at mediatek.com/
>      1) Add return -ENODEV when the dev is null.
>      2) Add more strict about the case that a iommu consume device use the ports in
>      different larbs. Don't allow this case.
>      3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it only has one
>      line now.
> 
> v8: https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong.wu at mediatek.com/
>      1) Rebase on v5.15-rc1.
>      2) Don't rebase the below mdp patchset that may still need more discuss.
>      https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-eizan at chromium.org/
>      3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested.
> 
> v7: https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong.wu at mediatek.com/
>      1) Fix a arm32 boot fail issue. reported from Frank.
>      2) Add a return fail in the mtk drm. suggested by Dafna.
> 
> v6: https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong.wu at mediatek.com/
>      1) rebase on v5.14-rc1.
>      2) Fix the issue commented in v5 from Dafna and Hsin-Yi.
>      3) Remove the patches about using pm_runtime_resume_and_get since they have
>         already been merged by other patches.
> 
> v5: https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong.wu at mediatek.com/
>      1) Base v5.12-rc2.
>      2) Remove changing the mtk-iommu to module_platform_driver patch, It have already been a
>      independent patch.
> 
> v4: https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong.wu at mediatek.com/
>      base on v5.7-rc1.
>    1) Move drm PM patch before smi patchs.
>    2) Change builtin_platform_driver to module_platform_driver since we may need
>       build as module.
>    3) Rebase many patchset as above.
> 
> v3: https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong.wu at mediatek.com/
>      1) rebase on v5.3-rc1 and the latest mt8183 patchset.
>      2) Use device_is_bound to check whether the driver is ready from Matthias.
>      3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
>     reason in the commit message[3/14].
>      4) Add a display patch[12/14] into this series. otherwise it may affect
>     display HW fastlogo even though it don't happen in mt8183.
>     
> v2: https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong.wu at mediatek.com/
>     1) rebase on v5.2-rc1.
>     2) Move adding device_link between the consumer and smi-larb into
> iommu_add_device from Robin.
>     3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
>     4) Remove the shutdown callback in iommu.
> 
> v1: https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong.wu at mediatek.com/
> 
> Yong Wu (12):
>    dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
>    iommu/mediatek-v1: Free the existed fwspec if the master dev already
>      has
>    iommu/mediatek: Return ENODEV if the device is NULL
>    iommu/mediatek: Add probe_defer for smi-larb
>    iommu/mediatek: Add device_link between the consumer and the larb
>      devices
>    media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
>    media: mtk-mdp: Get rid of mtk_smi_larb_get/put
>    drm/mediatek: Get rid of mtk_smi_larb_get/put
>    media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
>    memory: mtk-smi: Get rid of mtk_smi_larb_get/put
>    arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
>    arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
> 
> Yongqiang Niu (1):
>    drm/mediatek: Add pm runtime support for ovl and rdma
> 
>   .../display/mediatek/mediatek,disp.txt        |  9 ----
>   .../media/mediatek,vcodec-decoder.yaml        |  7 ---
>   .../media/mediatek,vcodec-encoder.yaml        |  8 ----
>   .../bindings/media/mediatek-jpeg-decoder.yaml |  9 ----
>   .../bindings/media/mediatek-jpeg-encoder.yaml |  9 ----
>   .../bindings/media/mediatek-mdp.txt           |  8 ----
>   arch/arm/boot/dts/mt2701.dtsi                 |  2 -
>   arch/arm/boot/dts/mt7623n.dtsi                |  5 ---
>   arch/arm64/boot/dts/mediatek/mt8173.dtsi      | 16 -------
>   arch/arm64/boot/dts/mediatek/mt8183.dtsi      |  6 ---
>   drivers/gpu/drm/mediatek/mtk_disp_ovl.c       |  8 +++-
>   drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |  9 +++-
>   drivers/gpu/drm/mediatek/mtk_drm_crtc.c       | 15 ++++---
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   | 36 +--------------
>   drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |  1 -
>   drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  5 +--
>   drivers/iommu/mtk_iommu.c                     | 34 ++++++++++++++
>   drivers/iommu/mtk_iommu_v1.c                  | 42 ++++++++++++++++-
>   .../media/platform/mtk-jpeg/mtk_jpeg_core.c   | 45 +------------------
>   .../media/platform/mtk-jpeg/mtk_jpeg_core.h   |  2 -
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 -----------------
>   drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |  2 -
>   drivers/media/platform/mtk-mdp/mtk_mdp_core.c |  1 -
>   .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  2 -
>   .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   |  1 -
>   .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 41 +++--------------
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  3 --
>   .../platform/mtk-vcodec/mtk_vcodec_enc.c      |  1 -
>   .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  2 -
>   .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 45 +++----------------
>   drivers/memory/mtk-smi.c                      | 14 ------
>   include/soc/mediatek/smi.h                    | 20 ---------
>   32 files changed, 115 insertions(+), 333 deletions(-)
> 

Hello Hans, Matthias,
on my side, this series is totally ready for merge, hence, green light from here.

Can you please take it for 5.18?

Thank you,
Angelo


From sudeep.holla at arm.com  Mon Jan 17 02:31:00 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 17 Jan 2022 10:31:00 +0000
Subject: [PATCH v8 11/11] clk: scmi: Support atomic clock enable/disable
 API
In-Reply-To: <20220114230839.ABD63C36AE9@smtp.kernel.org>
References: <20211220195646.44498-1-cristian.marussi@arm.com>
 <20211220195646.44498-12-cristian.marussi@arm.com>
 <20220114230839.ABD63C36AE9@smtp.kernel.org>
Message-ID: <20220117103100.c6ltxnz4iqmbc4b5@bogus>

On Fri, Jan 14, 2022 at 03:08:37PM -0800, Stephen Boyd wrote:
> Quoting Cristian Marussi (2021-12-20 11:56:46)
> > Support also atomic enable/disable clk_ops beside the bare non-atomic one
> > (prepare/unprepare) when the underlying SCMI transport is configured to
> > support atomic transactions for synchronous commands.
> > 
> > Cc: Michael Turquette <mturquette at baylibre.com>
> > Cc: Stephen Boyd <sboyd at kernel.org>
> > Cc: linux-clk at vger.kernel.org
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > ---
> > NOTE THAT STILL THERE'S NO FINE GRAIN CONTROL OVER SELECTION
> > OF WHICH CLOCK DEVICES CAN SUPPORT ATOMIC AND WHICH SHOULD NOT
> > BASED ON CLOCK DEVICES ENABLE LATENCY.
> > THIS HAS STILL TO BE ADDED IN SCMI PROTOCOL SPEC.
> 
> Why are you yelling on the internet? :-) I guess I need to ack this.
>

It is for the partners who request such changes. We are trying to prototype
and share the code and ask for feedback before we finalise the specification.

In fact it is other way around for you ?. Not to ack as it is not yet final
?. At least I need to wait until the spec contents are finalised before I
can merge with your ack ?. But I agree RFC would have indicated that along
with the above background instead of *yelling*. Cristian assumed everyone
is aware of the content as quite a few are involved in offline discussions.

> Acked-by: Stephen Boyd <sboyd at kernel.org>

Thanks anyways, will use it if nothing changes.

-- 
Regards,
Sudeep


From matthias.bgg at gmail.com  Fri Jan 14 07:46:41 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Fri, 14 Jan 2022 16:46:41 +0100
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186
 SoC
In-Reply-To: <20220107104633.7500-2-johnson.wang@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
Message-ID: <9949a1f7-1ed5-a137-c7b9-2ef8d8e1caf8@gmail.com>



On 07/01/2022 11:46, Johnson Wang wrote:
> MT8186 are highly integrated SoC and use PMIC_MT6366 for
> power management. This patch adds pwrap master driver to
> access PMIC_MT6366.
> 

It seems this new arbiter is significantly different from the version 1. Please 
explain that in the commit message.

> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> ---
>   drivers/soc/mediatek/mtk-pmic-wrap.c | 72 ++++++++++++++++++++++++++++
>   1 file changed, 72 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c
> index 952bc554f443..78866ebf7f04 100644
> --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> @@ -30,6 +30,7 @@
>   #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) & 0x00000001)
>   #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
>   #define PWRAP_STATE_INIT_DONE0		BIT(21)
> +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)

That's a strange name, does it come from the datasheet description?

>   #define PWRAP_STATE_INIT_DONE1		BIT(15)
>   
>   /* macro for WACS FSM */
> @@ -77,6 +78,8 @@
>   #define PWRAP_CAP_INT1_EN	BIT(3)
>   #define PWRAP_CAP_WDT_SRC1	BIT(4)
>   #define PWRAP_CAP_ARB		BIT(5)
> +#define PWRAP_CAP_MONITOR_V2	BIT(6)

Not used capability, please delete.


Regards,
Matthias


From anshuman.khandual at arm.com  Mon Jan 17 02:36:44 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 17 Jan 2022 16:06:44 +0530
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
In-Reply-To: <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>
References: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
 <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>
Message-ID: <b1ffe762-43e6-b624-2b08-0aaa7ca5f70b@arm.com>



On 1/13/22 3:54 PM, Mark Rutland wrote:
> Hi Anshuman,
> 
> This looks fine structurally, I'm just not sure of a couple of details because
> I can't find the relevant documentation -- more on that below.
> 
> On Thu, Jan 13, 2022 at 03:11:08PM +0530, Anshuman Khandual wrote:
>> MDCR_EL3.SBRBE resets to an UNKNOWN value. Configure it to allow the BRBE
>> buffer usage and direct register access in the non-secure world. But just
>> before that, check AA64DFR0_EL1.BRBE and make sure BRBE is implemented. We
>> still continue to reset MDCR_EL3 register to zero with the exception of
>> MDCR_EL3.NSPB, MDCR_EL3.NSTB and MDCR_EL3.SBRBE.
> 
> I'm struggling to find where the BRBE system register fields are documented.
> 
> I looked at the latest ARM ARM (DDI 0487G.b):
> 
>   https://developer.arm.com/documentation/ddi0487/gb/
> 
> ... and the Armv9 supplement (DDI 0608A.a):
> 
>   https://developer.arm.com/documentation/ddi0608/aa/
> 
> ... but AFAICT, neither of those describe the bit-positions of the relevant
> fields, so I can't check that those are correct. The other extensions (at leat
> TME) describe that in the supplement, so this looks like a bug/oversight. 
> 
> Am I looking at the right documents? If this is meant to be in the supplement,
> could you please raise a bug report to get that fixed?

Please find the MDCR_EL3.SBRBE definition here.

https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/
MDCR-EL3--Monitor-Debug-Configuration-Register--EL3-?lang=en#fieldset_0-33_32-1

> 
>>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/aarch64/boot.S | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
>> index bfbb6ec..ca1b292 100644
>> --- a/arch/aarch64/boot.S
>> +++ b/arch/aarch64/boot.S
>> @@ -103,6 +103,14 @@ ASM_FUNC(_start)
>>  	ldr	x1, =(0x3 << 24)
>>  	orr	x0, x0, x1
>>  
>> +1:	mrs     x1, id_aa64dfr0_el1
>> +	ubfx    x1, x1, #52, #4
>> +	cbz     x1, 1f
>> +
>> +	// Enable BRBE for the non-secure world.
>> +	ldr     x1, =(0x3 << 32)
>> +	orr     x0, x0, x1
>> +
> 
> I assume this is the `SBRBE` field, which naming-wise sounds like it controls
> Secure rather than Non-Secure (e,g. by way of comparison to `NSPB`). Is that

Right, that is some what counter-intuitive.

> correct? What effect does the value 0x3 have?

As per the definition above.

0b11	 This control does not cause any direct accesses to BRBE registers or
         instruction to be trapped, and does not cause any Exception levels to
	 be a prohibited region.

This basically allows BRBE usage in EL2/EL1.

> 
> Thanks,
> Mark.
> 
>>  1:	msr	mdcr_el3, x0			// Disable traps to EL3
>>  
>>  	mrs	x0, id_aa64pfr0_el1
>> -- 
>> 2.7.4
>>


From angelogioacchino.delregno at collabora.com  Mon Jan 17 02:38:14 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 17 Jan 2022 11:38:14 +0100
Subject: [PATCH net-next v12 3/7] stmmac: dwmac-mediatek: re-arrange clock
 setting
In-Reply-To: <20220117070706.17853-4-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
 <20220117070706.17853-4-biao.huang@mediatek.com>
Message-ID: <2c62f337-5eb4-e525-7e3a-289435315c09@collabora.com>

Il 17/01/22 08:07, Biao Huang ha scritto:
> The rmii_internal clock is needed only when PHY
> interface is RMII, and reference clock is from MAC.
> 
> Re-arrange the clock setting as following:
> 1. the optional "rmii_internal" is controlled by devm_clk_get(),
> 2. other clocks still be configured by devm_clk_bulk_get().
> 
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> ---
>   .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 72 +++++++++++++------
>   1 file changed, 49 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> index 8747aa4403e8..2678d2deb26a 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> @@ -49,14 +49,15 @@ struct mac_delay_struct {
>   struct mediatek_dwmac_plat_data {
>   	const struct mediatek_dwmac_variant *variant;
>   	struct mac_delay_struct mac_delay;
> +	struct clk *rmii_internal_clk;
>   	struct clk_bulk_data *clks;
> -	struct device_node *np;
>   	struct regmap *peri_regmap;
> +	struct device_node *np;
>   	struct device *dev;
>   	phy_interface_t phy_mode;
> -	int num_clks_to_config;
>   	bool rmii_clk_from_mac;
>   	bool rmii_rxc;
> +	int num_clks;

I don't see any need to get a num_clks here, at this point: since all functions
reading this are getting passed a pointer to this entire structure, you can
simply always access plat->variant->num_clks.

Please, drop the addition of num_clks in this struct.

Regards,
Angelo



From baruch at tkos.co.il  Mon Jan 17 02:36:25 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 17 Jan 2022 12:36:25 +0200
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <20220114233904.907918-1-sean.anderson@seco.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
Message-ID: <87iluifxy1.fsf@tarshish>

Hi Sean, Thinh,

On Fri, Jan 14 2022, Sean Anderson wrote:
> This is a rework of patches 3-5 of [1]. It attempts to correctly program
> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
> we no longer need a special property duplicating this configuration,
> snps,ref-clock-period-ns is deprecated.
>
> Please test this! Patches 3/4 in this series have the effect of
> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
> the "ref" clock. I have build tested, but not much else.
>
> [1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/

Thinh, you suggested the dedicated DT property for the reference clock:

  https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/

Can you comment on this series?

Thanks,
baruch

> Sean Anderson (6):
>   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>   usb: dwc3: Get clocks individually
>   usb: dwc3: Calculate REFCLKPER based on reference clock
>   usb: dwc3: Handle fractional reference clocks
>   arm64: dts: zynqmp: Move USB clocks to dwc3 node
>   arm64: dts: ipq6018: Use reference clock to set dwc3 period
>
>  .../devicetree/bindings/usb/snps,dwc3.yaml    |  7 +-
>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  3 +-
>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  4 +-
>  drivers/usb/dwc3/core.c                       | 98 ++++++++++++++++---
>  drivers/usb/dwc3/core.h                       |  6 +-
>  6 files changed, 98 insertions(+), 24 deletions(-)


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From jbx6244 at gmail.com  Mon Jan 17 02:47:16 2022
From: jbx6244 at gmail.com (Johan Jonker)
Date: Mon, 17 Jan 2022 11:47:16 +0100
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <20220116124911.65203-2-linux@fw-web.de>
References: <20220116124911.65203-1-linux@fw-web.de>
 <20220116124911.65203-2-linux@fw-web.de>
Message-ID: <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>

Hi Frank,

Despite that the DT is hosted in the kernel tree
DT and mainline kernel driver support are 2 separate things.
PCLK_XPCS might be in use elsewhere.

Given the link below pclk_xpcs is only needed for rk3568.
Maybe gmac1 should have a PCLK_XPCS too, because one can select between
them.

ethernet: stmicro: stmmac: Add SGMII/QSGMII support for RK3568
https://github.com/rockchip-linux/kernel/commit/1fc7cbfe9e227c700c692f1de3137914b3ea6ca6

The original dtsi did have PCLK_XPCS in both nodes.
https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L2121
https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L1492

Maybe fix the document or leave it as it is for now as long the driver
isn't updated and someone has tested it.
That's up to the DT maintainer.

Johan

===

XPCS is also part of PD_PIPE.
See Rockchip RK3568 TRM Part1 V1.0-20210111.pdf page 475.
Please advise if the power-domain at RK3568_PD_PIPE does need a PCLK_XPCS
fix or is PCLK_PIPE enough in combination with a PHY driver?

PD_PIPE:

BIU_PIPE
USB3OTG
PCIE20
PCIE30
SATA
XPCS


	power-domain at RK3568_PD_PIPE {
		reg = <RK3568_PD_PIPE>;
		clocks = <&cru PCLK_PIPE>;
		pm_qos = <&qos_pcie2x1>,
			 <&qos_pcie3x1>,
			 <&qos_pcie3x2>,
			 <&qos_sata0>,
			 <&qos_sata1>,
			 <&qos_sata2>,
			 <&qos_usb3_0>,
			 <&qos_usb3_1>;
		#power-domain-cells = <0>;
	};



On 1/16/22 1:49 PM, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> pclk_xpcs is not supported and breaks dtbs_check, so remove it
> 
> following warnings occour, and many more
> 
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
>     [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
>     [15, 389], [15, 185], [15, 172]] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
>     ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
>     'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> 
> after removing the clock the other warnings are also gone.
> 
> Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> index 2fd313a295f8..d91df1cde736 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> @@ -32,13 +32,11 @@ gmac0: ethernet at fe2a0000 {
>  		clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
>  			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
>  			 <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
> -			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
> -			 <&cru PCLK_XPCS>;
> +			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
>  		clock-names = "stmmaceth", "mac_clk_rx",
>  			      "mac_clk_tx", "clk_mac_refout",
>  			      "aclk_mac", "pclk_mac",
> -			      "clk_mac_speed", "ptp_ref",
> -			      "pclk_xpcs";
> +			      "clk_mac_speed", "ptp_ref";
>  		resets = <&cru SRST_A_GMAC0>;
>  		reset-names = "stmmaceth";
>  		rockchip,grf = <&grf>;
> 


From angelogioacchino.delregno at collabora.com  Mon Jan 17 02:50:33 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 17 Jan 2022 11:50:33 +0100
Subject: [PATCH 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220117071220.17330-4-axe.yang@mediatek.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
 <20220117071220.17330-4-axe.yang@mediatek.com>
Message-ID: <754779eb-71f9-2083-a204-1d98b4a04a08@collabora.com>

Il 17/01/22 08:12, Axe Yang ha scritto:
> Add support for eint IRQ when MSDC is used as an SDIO host. This
> feature requires SDIO device support async IRQ function. With this
> feature, SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in MSDC node
> to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>          &mmcX {
>                  ...
>                  pinctrl-names = "default", "state_uhs", "state_eint",
>                                  "state_dat1";
>                  ...
>                  pinctrl-2 = <&mmc2_pins_eint>;
>                  pinctrl-3 = <&mmc2_pins_dat1>;
>                  ...
>                  cap-sdio-async-irq;
>                  ...
>          };
> 
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> ---
>   drivers/mmc/host/mtk-sd.c | 125 +++++++++++++++++++++++++++++++++++---
>   1 file changed, 117 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 65037e1d7723..cbdbcce99fd9 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -1,6 +1,6 @@
>   // SPDX-License-Identifier: GPL-2.0-only
>   /*
> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2022 MediaTek Inc.
>    * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
>    */
>   
> @@ -9,6 +9,7 @@
>   #include <linux/clk.h>
>   #include <linux/delay.h>
>   #include <linux/dma-mapping.h>
> +#include <linux/gpio/consumer.h>
>   #include <linux/iopoll.h>
>   #include <linux/ioport.h>
>   #include <linux/irq.h>
> @@ -440,8 +441,12 @@ struct msdc_host {
>   	struct pinctrl *pinctrl;
>   	struct pinctrl_state *pins_default;
>   	struct pinctrl_state *pins_uhs;
> +	struct pinctrl_state *pins_eint;
> +	struct pinctrl_state *pins_dat1;
>   	struct delayed_work req_timeout;
>   	int irq;		/* host interrupt */
> +	int eint_irq;		/* device interrupt */
> +	int sdio_irq_cnt;	/* irq enable cnt */
>   	struct reset_control *reset;
>   
>   	struct clk *src_clk;	/* msdc source clock */
> @@ -465,6 +470,7 @@ struct msdc_host {
>   	bool hs400_tuning;	/* hs400 mode online tuning */
>   	bool internal_cd;	/* Use internal card-detect logic */
>   	bool cqhci;		/* support eMMC hw cmdq */
> +	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
>   	struct msdc_save_para save_para; /* used when gate HCLK */
>   	struct msdc_tune_para def_tune_para; /* default tune setting */
>   	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
> @@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
>   	__msdc_enable_sdio_irq(host, enb);
>   	spin_unlock_irqrestore(&host->lock, flags);
>   
> -	if (enb)
> -		pm_runtime_get_noresume(host->dev);
> -	else
> -		pm_runtime_put_noidle(host->dev);
> +	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
> +		if (enb)
> +			pm_runtime_get_noresume(host->dev);
> +		else
> +			pm_runtime_put_noidle(host->dev);
> +	}
>   }
>   
>   static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
> @@ -2461,6 +2469,50 @@ static const struct mmc_host_ops mt_msdc_ops = {
>   	.hw_reset = msdc_hw_reset,
>   };
>   
> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +	struct msdc_host *host = dev_id;
> +	struct mmc_host *mmc = mmc_from_priv(host);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&host->lock, flags);
> +	if (likely(host->sdio_irq_cnt > 0)) {
> +		disable_irq_nosync(host->eint_irq);
> +		disable_irq_wake(host->eint_irq);
> +		host->sdio_irq_cnt--;
> +	}
> +	spin_unlock_irqrestore(&host->lock, flags);
> +
> +	sdio_signal_irq(mmc);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> +{
> +	struct gpio_desc *desc;
> +	int irq, ret;
> +
> +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
> +
> +	ret = gpiod_to_irq(desc);
> +	if (ret < 0)
> +		return ret;
> +
> +	irq = ret;
> +	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +					"sdio-eint", host);
> +	if (ret)
> +		return ret;
> +
> +	host->eint_irq = irq;
> +
> +	return 0;
> +}
> +
>   static const struct cqhci_host_ops msdc_cmdq_ops = {
>   	.enable         = msdc_cqe_enable,
>   	.disable        = msdc_cqe_disable,
> @@ -2631,6 +2683,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   		goto host_free;
>   	}
>   
> +	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO)) {

Please, also check for the async irq capability here:

if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ)) {

...because if we have "state_eint" specified in DT, but we didn't *also* specify
cap-sdio-async-irq, then clearly we don't want to use this functionality - hence
it becomes useless to register the interrupt handler for that because we're never
enabling the CCCR_INTERRUPT_EXT on the card (from drivers/mmc/core/host.c).

Regards,
Angelo

> +		/* Support for SDIO eint irq */
> +		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
> +		if (IS_ERR(host->pins_eint)) {
> +			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
> +		} else {
> +			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
> +			if (IS_ERR(host->pins_dat1)) {
> +				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
> +						    "Cannot find pinctrl dat1!\n");
> +				goto host_free;
> +			}
> +
> +			host->sdio_eint_ready = true;
> +		}
> +	}
> +
>   	msdc_of_property_parse(pdev, host);
>   
>   	host->dev = &pdev->dev;
> @@ -2722,6 +2791,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
>   	if (ret)
>   		goto release;
>   
> +	if (host->sdio_eint_ready) {
> +		ret = msdc_request_dat1_eint_irq(host);
> +		if (ret) {
> +			dev_err(host->dev, "Failed to register data1 eint irq!\n");
> +			goto release;
> +		}
> +
> +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> +	}
> +
>   	pm_runtime_set_active(host->dev);
>   	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
>   	pm_runtime_use_autosuspend(host->dev);
> @@ -2841,16 +2920,31 @@ static void msdc_restore_reg(struct msdc_host *host)
>   
>   static int __maybe_unused msdc_runtime_suspend(struct device *dev)
>   {
> +	unsigned long flags;
>   	struct mmc_host *mmc = dev_get_drvdata(dev);
>   	struct msdc_host *host = mmc_priv(mmc);
>   
>   	msdc_save_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		disable_irq(host->irq);
> +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt == 0) {
> +			enable_irq(host->eint_irq);
> +			enable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt++;
> +		}
> +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
>   	msdc_gate_clock(host);
>   	return 0;
>   }
>   
>   static int __maybe_unused msdc_runtime_resume(struct device *dev)
>   {
> +	unsigned long flags;
>   	struct mmc_host *mmc = dev_get_drvdata(dev);
>   	struct msdc_host *host = mmc_priv(mmc);
>   	int ret;
> @@ -2860,10 +2954,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
>   		return ret;
>   
>   	msdc_restore_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt > 0) {
> +			disable_irq_nosync(host->eint_irq);
> +			disable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt--;
> +			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		} else {
> +			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> +		}
> +		spin_unlock_irqrestore(&host->lock, flags);
> +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> +		enable_irq(host->irq);
> +	}
>   	return 0;
>   }
>   
> -static int __maybe_unused msdc_suspend(struct device *dev)
> +static int __maybe_unused msdc_suspend_noirq(struct device *dev)
>   {
>   	struct mmc_host *mmc = dev_get_drvdata(dev);
>   	int ret;
> @@ -2877,13 +2986,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
>   	return pm_runtime_force_suspend(dev);
>   }
>   
> -static int __maybe_unused msdc_resume(struct device *dev)
> +static int __maybe_unused msdc_resume_noirq(struct device *dev)
>   {
>   	return pm_runtime_force_resume(dev);
>   }
>   
>   static const struct dev_pm_ops msdc_dev_pm_ops = {
> -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
>   	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
>   };
>   
> 




From lorenzo at kernel.org  Mon Jan 17 02:56:07 2022
From: lorenzo at kernel.org (Lorenzo Bianconi)
Date: Mon, 17 Jan 2022 11:56:07 +0100
Subject: [PATCH 1/2] iio: imu: st_lsm6dsx: Limit requested watermark
 value to hwfifo size
In-Reply-To: <20220117102512.31725-1-paul@crapouillou.net>
References: <20220117102512.31725-1-paul@crapouillou.net>
Message-ID: <YeVLRzmUw/U9GRC3@lore-desk>

> Instead of returning an error if the watermark value is too high, which
> the core will silently ignore anyway, limit the value to the hardware
> FIFO size; a lower-than-requested value is still better than using the
> default, which is usually 1.
> 

Acked-by: Lorenzo Bianconi <lorenzo at kernel.org>

> Cc: Lorenzo Bianconi <lorenzo.bianconi83 at gmail.com>
> Signed-off-by: Paul Cercueil <paul at crapouillou.net>
> ---
>  drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> index 727b4b6ac696..5fd46bf1a11b 100644
> --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
> @@ -54,6 +54,7 @@
>  #include <linux/iio/sysfs.h>
>  #include <linux/interrupt.h>
>  #include <linux/irq.h>
> +#include <linux/minmax.h>
>  #include <linux/pm.h>
>  #include <linux/property.h>
>  #include <linux/regmap.h>
> @@ -1607,8 +1608,7 @@ int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
>  	struct st_lsm6dsx_hw *hw = sensor->hw;
>  	int err;
>  
> -	if (val < 1 || val > hw->settings->fifo_ops.max_size)
> -		return -EINVAL;
> +	val = clamp_val(val, 1, hw->settings->fifo_ops.max_size);
>  
>  	mutex_lock(&hw->conf_lock);
>  
> -- 
> 2.34.1
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220117/3494be8e/attachment-0001.sig>

From lkp at intel.com  Mon Jan 17 03:01:28 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 17 Jan 2022 19:01:28 +0800
Subject: [linusw-nomadik:ux500-href-charging-v5.16-rc1] BUILD REGRESSION
 1e846b0b60ac01cac4f283975a1bc395ff73d995
Message-ID: <61e54c88.SZ4l6o178sNXKw9j%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ux500-href-charging-v5.16-rc1
branch HEAD: 1e846b0b60ac01cac4f283975a1bc395ff73d995  pwm: ab8500: Get HW ID from reg value

Error/Warning reports:

https://lore.kernel.org/linux-arm-kernel/202201170953.yxBdZqTf-lkp at intel.com
https://lore.kernel.org/linux-arm-kernel/202201171004.E3chM4HB-lkp at intel.com
https://lore.kernel.org/linux-arm-kernel/202201171553.GzhBBn9Q-lkp at intel.com
https://lore.kernel.org/linux-arm-kernel/202201171658.RcGVrgup-lkp at intel.com

Error/Warning in current branch:

(.text+0x1b5e): undefined reference to `samsung_sdi_battery_get_info'
(.text+0x40b4): undefined reference to `samsung_sdi_battery_get_info'
(.text+0x4af4): undefined reference to `samsung_sdi_battery_get_info'
drivers/power/supply/ab8500_chargalg.c:822:13: warning: variable 'delta_i_ua' set but not used [-Wunused-but-set-variable]

possible Error/Warning in current branch (please contact us if interested):

(.text.power_supply_get_battery_info+0xc8): undefined reference to `samsung_sdi_battery_get_info'

Error/Warning ids grouped by kconfigs:

gcc_recent_errors
|-- arm-allmodconfig
|   `-- (.text):undefined-reference-to-samsung_sdi_battery_get_info
|-- arm-allyesconfig
|   `-- drivers-power-supply-ab8500_chargalg.c:warning:variable-delta_i_ua-set-but-not-used
|-- i386-randconfig-c001
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- m68k-allmodconfig
|   `-- (.text):undefined-reference-to-samsung_sdi_battery_get_info
|-- microblaze-randconfig-c003-20220116
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- mips-allmodconfig
|   `-- (.text.power_supply_get_battery_info):undefined-reference-to-samsung_sdi_battery_get_info
|-- nds32-randconfig-c003-20220116
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- nds32-randconfig-c004-20220116
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- powerpc64-randconfig-c024-20220116
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- s390-allmodconfig
|   `-- (.text):undefined-reference-to-samsung_sdi_battery_get_info
|-- x86_64-randconfig-c002
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
|-- x86_64-randconfig-c022
|   `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer
`-- xtensa-randconfig-c004-20220116
    `-- drivers-power-supply-cw2015_battery.c:ERROR:application-of-sizeof-to-pointer

elapsed time: 722m

configs tested: 125
configs skipped: 3

gcc tested configs:
arm                              allyesconfig
arm                              allmodconfig
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
i386                          randconfig-c001
powerpc                          allyesconfig
s390                             allyesconfig
m68k                             allmodconfig
s390                             allmodconfig
powerpc                          allmodconfig
m68k                             allyesconfig
arm                        clps711x_defconfig
sh                          landisk_defconfig
m68k                        m5272c3_defconfig
sparc64                             defconfig
powerpc                     taishan_defconfig
parisc                           allyesconfig
xtensa                  cadence_csp_defconfig
sh                               alldefconfig
xtensa                  nommu_kc705_defconfig
openrisc                         alldefconfig
mips                     decstation_defconfig
mips                          rb532_defconfig
m68k                           sun3_defconfig
sh                      rts7751r2d1_defconfig
arm                            qcom_defconfig
arm                         at91_dt_defconfig
m68k                         apollo_defconfig
m68k                          sun3x_defconfig
powerpc                      mgcoge_defconfig
mips                           ip32_defconfig
s390                                defconfig
arm                  randconfig-c002-20220116
arm                  randconfig-c002-20220117
ia64                             allmodconfig
ia64                                defconfig
ia64                             allyesconfig
m68k                                defconfig
nds32                             allnoconfig
nios2                               defconfig
arc                              allyesconfig
csky                                defconfig
alpha                               defconfig
alpha                            allyesconfig
nds32                               defconfig
nios2                            allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
xtensa                           allyesconfig
parisc                              defconfig
i386                             allyesconfig
sparc                            allyesconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
sparc                               defconfig
mips                             allyesconfig
mips                             allmodconfig
powerpc                           allnoconfig
i386                          randconfig-a003
i386                          randconfig-a001
i386                          randconfig-a005
x86_64               randconfig-a016-20220117
x86_64               randconfig-a012-20220117
x86_64               randconfig-a013-20220117
x86_64               randconfig-a011-20220117
x86_64               randconfig-a014-20220117
x86_64               randconfig-a015-20220117
i386                          randconfig-a012
i386                          randconfig-a014
i386                          randconfig-a016
i386                 randconfig-a012-20220117
i386                 randconfig-a016-20220117
i386                 randconfig-a014-20220117
i386                 randconfig-a015-20220117
i386                 randconfig-a011-20220117
i386                 randconfig-a013-20220117
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                             i386_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec
x86_64                    rhel-8.3-kselftests

clang tested configs:
arm                  randconfig-c002-20220116
x86_64                        randconfig-c007
riscv                randconfig-c006-20220116
powerpc              randconfig-c003-20220116
i386                          randconfig-c001
mips                 randconfig-c004-20220116
s390                 randconfig-c005-20220116
powerpc                 mpc8313_rdb_defconfig
mips                      bmips_stb_defconfig
powerpc                      acadia_defconfig
arm                                 defconfig
powerpc                      ppc64e_defconfig
arm                       versatile_defconfig
x86_64               randconfig-a004-20220117
x86_64               randconfig-a001-20220117
x86_64               randconfig-a002-20220117
x86_64               randconfig-a003-20220117
x86_64               randconfig-a005-20220117
x86_64               randconfig-a006-20220117
i386                 randconfig-a005-20220117
i386                 randconfig-a001-20220117
i386                 randconfig-a006-20220117
i386                 randconfig-a004-20220117
i386                 randconfig-a002-20220117
i386                 randconfig-a003-20220117
i386                          randconfig-a002
i386                          randconfig-a004
i386                          randconfig-a006
i386                          randconfig-a011
i386                          randconfig-a013
i386                          randconfig-a015
hexagon              randconfig-r045-20220116
riscv                randconfig-r042-20220116
hexagon              randconfig-r041-20220116

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From dario.binacchi at amarulasolutions.com  Mon Jan 17 03:18:24 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Mon, 17 Jan 2022 12:18:24 +0100
Subject: [RFC PATCH v2 0/5] Fix and improve gpmi nand on mx28
Message-ID: <20220117111829.1811997-1-dario.binacchi@amarulasolutions.com>

Starting from [1], the series fixes the timings setting of the gpmi
controller for the mx28 architecture, also adding support for fast
edo mode timings. The whole series has been heavily tested with the
mtd kernel test modules, and with repeated write cycles on nand.

[1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org

Changes in v2:
 - Reparent by device tree instead of code (drivers/clk/mxs/clk-imx28.c).
   Suggested by Stephen Boyd.
- Improve the commit description.
- give examples of frequencies on my setup.
- Add the patch to the series.
- Fix commit description.
- Add an example to the commit description to better understand the
  problem solved by the patch.
- Split the patch.
- Improve the commit message.
- Move the patch to the end of the series.

Dario Binacchi (5):
  ARM: dts: imx28: reparent gpmi clock to ref_gpmi
  mtd: rawnand: gpmi: fix controller timings setting
  mtd: rawnand: gpmi: use a table to get EDO mode setup
  mtd: rawnand: gpmi: validate controller clock rate
  mtd: rawnand: gpmi: support fast edo timings for mx28

 arch/arm/boot/dts/imx28.dtsi               |  2 +
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 70 ++++++++++++++++------
 2 files changed, 55 insertions(+), 17 deletions(-)

-- 
2.32.0



From dario.binacchi at amarulasolutions.com  Mon Jan 17 03:18:25 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Mon, 17 Jan 2022 12:18:25 +0100
Subject: [RFC PATCH v2 1/5] ARM: dts: imx28: reparent gpmi clock to ref_gpmi
In-Reply-To: <20220117111829.1811997-1-dario.binacchi@amarulasolutions.com>
References: <20220117111829.1811997-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20220117111829.1811997-2-dario.binacchi@amarulasolutions.com>

Since ref_gpmi is sourced from pll0 (480MHz), It allows the GPMI
controller to manage High-Speed ??NAND Timing (edo mode 3,4 and 5).

Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>


---

Changes in v2:
 - Reparent by device tree instead of code (drivers/clk/mxs/clk-imx28.c).
   Suggested by Stephen Boyd.

 arch/arm/boot/dts/imx28.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 84d0176d5193..130b4145af82 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -110,6 +110,8 @@ gpmi: nand-controller at 8000c000 {
 				interrupt-names = "bch";
 				clocks = <&clks 50>;
 				clock-names = "gpmi_io";
+				assigned-clocks = <&clks 13>;
+				assigned-clock-parents = <&clks 10>;
 				dmas = <&dma_apbh 4>;
 				dma-names = "rx-tx";
 				status = "disabled";
-- 
2.32.0



From rexnie3 at gmail.com  Mon Jan 17 03:21:24 2022
From: rexnie3 at gmail.com (Rex Nie)
Date: Mon, 17 Jan 2022 19:21:24 +0800
Subject: [PATCH] drm/panel: Add panel-edp: add lcd innolux,n140hca-eac
Message-ID: <20220117112124.2358888-1-rexnie3@gmail.com>

innolux,n140hca-eac is a eDP-based LCD panel. This panel has 1920x1080
resolution in 14-inch TFT panel.

Signed-off-by: Rex Nie <rexnie3 at gmail.com>
---
 .../display/panel/innolux,n140hca-eac.yaml    | 43 +++++++++++++++++++
 drivers/gpu/drm/panel/panel-edp.c             | 26 +++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/innolux,n140hca-eac.yaml

diff --git a/Documentation/devicetree/bindings/display/panel/innolux,n140hca-eac.yaml b/Documentation/devicetree/bindings/display/panel/innolux,n140hca-eac.yaml
new file mode 100644
index 000000000000..5493e383c97c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/innolux,n140hca-eac.yaml
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/innolux,n140hca-eac.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Innolux N140HCA-EAC 14 inch eDP 1080p display panel
+
+maintainers:
+  - Sandeep Panda <spanda at codeaurora.org>
+  - Douglas Anderson <dianders at chromium.org>
+
+allOf:
+  - $ref: panel-common.yaml#
+
+properties:
+  compatible:
+    const: innolux,n140hca-eac
+
+  enable-gpios: true
+  power-supply: true
+  backlight: true
+  no-hpd: true
+
+required:
+  - compatible
+  - power-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    panel_edp: panel-edp {
+        compatible = "innolux,n140hca-eac";
+        enable-gpios = <&pio 96 GPIO_ACTIVE_HIGH>;
+        power-supply = <&pp3300_disp_x>;
+        backlight = <&backlight_lcd0>;
+        no-hpd;
+    };
+
+...
diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c
index 176ef0c3cc1d..3682986608dc 100644
--- a/drivers/gpu/drm/panel/panel-edp.c
+++ b/drivers/gpu/drm/panel/panel-edp.c
@@ -1303,6 +1303,29 @@ static const struct panel_desc innolux_n125hce_gn1 = {
 	},
 };
 
+static const struct display_timing innolux_n140hca_eac_timing = {
+	.pixelclock = { 72600000, 76420000, 80240000 },
+	.hactive = { 1920, 1920, 1920 },
+	.hfront_porch = { 80, 80, 80 },
+	.hback_porch = { 190, 190, 190 },
+	.hsync_len = { 60, 60, 60 },
+	.vactive = { 1080, 1080, 1080 },
+	.vfront_porch = { 6, 6, 6 },
+	.vback_porch = { 38, 38, 38 },
+	.vsync_len = { 8, 8, 8 },
+	.flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW,
+};
+
+static const struct panel_desc innolux_n140hca_eac = {
+	.timings = &innolux_n140hca_eac_timing,
+	.num_timings = 1,
+	.bpc = 6,
+	.size = {
+		.width = 309,
+		.height = 174,
+	},
+};
+
 static const struct drm_display_mode innolux_p120zdg_bf1_mode = {
 	.clock = 206016,
 	.hdisplay = 2160,
@@ -1682,6 +1705,9 @@ static const struct of_device_id platform_of_match[] = {
 	}, {
 		.compatible = "innolux,n125hce-gn1",
 		.data = &innolux_n125hce_gn1,
+	}, {
+		.compatible = "innolux,n140hca-eac",
+		.data = &innolux_n140hca_eac,
 	}, {
 		.compatible = "innolux,p120zdg-bf1",
 		.data = &innolux_p120zdg_bf1,
-- 
2.25.1



From alexandru.elisei at arm.com  Mon Jan 17 03:31:41 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 17 Jan 2022 11:31:41 +0000
Subject: [PATCH v5 12/69] KVM: arm64: nv: Handle HCR_EL2.NV system
 register traps
In-Reply-To: <20211129200150.351436-13-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-13-maz@kernel.org>
Message-ID: <YeVTnZcW82G36cda@monolith.localdoman>

Hi Marc,

Nitpick, but HCR_EL2.NV also traps accesses to *_EL02 and *_EL12 registers,
according to ARM DDI 0487G.a, page D5-2770. The subject could be changed to
"Handle HCR_EL2.NV *_EL2 system register traps" to better match the
content, but doesn't make much a difference overall.

On Mon, Nov 29, 2021 at 08:00:53PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
> this bit is set, accessing EL2 registers in EL1 traps to EL2. In
> addition, executing the following instructions in EL1 will trap to EL2:
> tlbi, at, eret, and msr/mrs instructions to access SP_EL1. Most of the
> instructions that trap to EL2 with the NV bit were undef at EL1 prior to
> ARM v8.3. The only instruction that was not undef is eret.
> 
> This patch sets up a handler for EL2 registers and SP_EL1 register
> accesses at EL1. The host hypervisor keeps those register values in
> memory, and will emulate their behavior.
> 
> This patch doesn't set the NV bit yet. It will be set in a later patch
> once nested virtualization support is completed.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> [maz: added SCTLR_EL2 RES0/RES1 handling]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/sysreg.h |  41 +++++++++++-
>  arch/arm64/kvm/sys_regs.c       | 109 ++++++++++++++++++++++++++++++--
>  2 files changed, 144 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 615dd6278f8b..c77fe5401826 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -531,10 +531,26 @@
>  
>  #define SYS_PMCCFILTR_EL0		sys_reg(3, 3, 14, 15, 7)
>  
> +#define SYS_VPIDR_EL2			sys_reg(3, 4, 0, 0, 0)
> +#define SYS_VMPIDR_EL2			sys_reg(3, 4, 0, 0, 5)
> +
>  #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
> +#define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
> +#define SYS_HCR_EL2			sys_reg(3, 4, 1, 1, 0)
> +#define SYS_MDCR_EL2			sys_reg(3, 4, 1, 1, 1)
> +#define SYS_CPTR_EL2			sys_reg(3, 4, 1, 1, 2)
> +#define SYS_HSTR_EL2			sys_reg(3, 4, 1, 1, 3)
>  #define SYS_HFGRTR_EL2			sys_reg(3, 4, 1, 1, 4)
>  #define SYS_HFGWTR_EL2			sys_reg(3, 4, 1, 1, 5)
>  #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
> +#define SYS_HACR_EL2			sys_reg(3, 4, 1, 1, 7)
> +
> +#define SYS_TTBR0_EL2			sys_reg(3, 4, 2, 0, 0)
> +#define SYS_TTBR1_EL2			sys_reg(3, 4, 2, 0, 1)
> +#define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
> +#define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
> +#define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
> +
>  #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
>  #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
>  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
> @@ -543,14 +559,26 @@
>  #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
>  #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
>  #define SYS_ELR_EL2			sys_reg(3, 4, 4, 0, 1)
> +#define SYS_SP_EL1			sys_reg(3, 4, 4, 1, 0)
>  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> +#define SYS_AFSR0_EL2			sys_reg(3, 4, 5, 1, 0)
> +#define SYS_AFSR1_EL2			sys_reg(3, 4, 5, 1, 1)
>  #define SYS_ESR_EL2			sys_reg(3, 4, 5, 2, 0)
>  #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
>  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
>  #define SYS_TFSR_EL2			sys_reg(3, 4, 5, 6, 0)
>  #define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
>  
> -#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
> +#define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
> +#define SYS_HPFAR_EL2			sys_reg(3, 4, 6, 0, 4)
> +
> +#define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
> +#define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
> +
> +#define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
> +#define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
> +#define SYS_RMR_EL2			sys_reg(3, 4, 12, 0, 2)
> +#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1, 1)
>  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
>  #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
>  #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
> @@ -592,15 +620,24 @@
>  #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
>  #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
>  
> +#define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
> +#define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
> +
> +#define SYS_CNTVOFF_EL2			sys_reg(3, 4, 14, 0, 3)
> +#define SYS_CNTHCTL_EL2			sys_reg(3, 4, 14, 1, 0)
> +
>  /* VHE encodings for architectural EL0/1 system registers */
>  #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
>  #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
>  #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
> +
>  #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
>  #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
>  #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
> +
>  #define SYS_SPSR_EL12			sys_reg(3, 5, 4, 0, 0)
>  #define SYS_ELR_EL12			sys_reg(3, 5, 4, 0, 1)
> +
>  #define SYS_AFSR0_EL12			sys_reg(3, 5, 5, 1, 0)
>  #define SYS_AFSR1_EL12			sys_reg(3, 5, 5, 1, 1)
>  #define SYS_ESR_EL12			sys_reg(3, 5, 5, 2, 0)
> @@ -618,6 +655,8 @@
>  #define SYS_CNTV_CTL_EL02		sys_reg(3, 5, 14, 3, 1)
>  #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
>  
> +#define SYS_SP_EL2			sys_reg(3, 6,  4, 1, 0)

Checked the encoding for the newly added registers, they match.

> +
>  /* Common SCTLR_ELx flags. */
>  #define SCTLR_ELx_DSSBS	(BIT(44))
>  #define SCTLR_ELx_ATA	(BIT(43))
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index e3ec1a44f94d..a23701f29858 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -105,6 +105,46 @@ static u32 get_ccsidr(u32 csselr)
>  	return ccsidr;
>  }
>  
> +static bool access_rw(struct kvm_vcpu *vcpu,
> +		      struct sys_reg_params *p,
> +		      const struct sys_reg_desc *r)
> +{
> +	if (p->is_write)
> +		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
> +	else
> +		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
> +
> +	return true;
> +}
> +
> +static bool access_sctlr_el2(struct kvm_vcpu *vcpu,
> +			     struct sys_reg_params *p,
> +			     const struct sys_reg_desc *r)
> +{
> +	if (p->is_write) {
> +		u64 val = p->regval;
> +
> +		if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)) {
> +			val &= ~(GENMASK_ULL(63,45) | GENMASK_ULL(34, 32) |
> +				 BIT_ULL(17) | BIT_ULL(9));
> +			val |=  SCTLR_EL1_RES1;
> +		} else {
> +			val &= ~(GENMASK_ULL(63,45) | BIT_ULL(42) |
> +				 GENMASK_ULL(39, 38) | GENMASK_ULL(35, 32) |
> +				 BIT_ULL(26) | BIT_ULL(24) | BIT_ULL(20) |
> +				 BIT_ULL(17) | GENMASK_ULL(15, 14) |
> +				 GENMASK(10, 7));
> +			val |=  SCTLR_EL2_RES1;
> +		}

Some bits in SCTLR_EL2 are functional bits when {E2H, TGE} = {1, 1}, otherwise
they are RES0. This is how ARM DDI 0487G.a describes the behaviour of bits which
are RES0 only in some contexts (page Glossary-8529, emphasis added by me):

"For a bit in a read/write register, when the bit is described as RES0:

- An indirect write to the register sets the bit to 0.

- ** A read of the bit must return the value last successfully written to the bit,
  by either a direct or an indirect write, regardless of the use of the register
  when the bit was written **

If the bit has not been successfully written since reset, then the read of the bit returns the reset
value if there is one, or otherwise returns an UNKNOWN value.

- A direct write to the bit must update a storage location associated with the bit.

- While the use of the register is such that the bit is described as RES0, the
  value of the bit must have no effect on the operation of the PE, other than
  determining the value read back from that bit, unless this Manual
  explicitly defines additional properties for the bit."

Let's take bit 24, E0E, as an example. When E2H,TGE != {1,1} (which means the
bit is now RES0), KVM clears the bit on a write, when according to the above
definition, it should save the value.

Thanks,
Alex

> +
> +		vcpu_write_sys_reg(vcpu, val, r->reg);
> +	} else {
> +		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
> +	}
> +
> +	return true;
> +}
> +
>  /*
>   * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
>   */
> @@ -263,6 +303,14 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
>  		return read_zero(vcpu, p);
>  }
>  
> +static bool trap_undef(struct kvm_vcpu *vcpu,
> +		       struct sys_reg_params *p,
> +		       const struct sys_reg_desc *r)
> +{
> +	kvm_inject_undefined(vcpu);
> +	return false;
> +}
> +
>  /*
>   * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
>   * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
> @@ -342,12 +390,9 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
>  			    struct sys_reg_params *p,
>  			    const struct sys_reg_desc *r)
>  {
> -	if (p->is_write) {
> -		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
> +	access_rw(vcpu, p, r);
> +	if (p->is_write)
>  		vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY;
> -	} else {
> -		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
> -	}
>  
>  	trace_trap_reg(__func__, r->reg, p->is_write, p->regval);
>  
> @@ -1411,6 +1456,18 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
>  	.set_user = set_raz_id_reg,		\
>  }
>  
> +static bool access_sp_el1(struct kvm_vcpu *vcpu,
> +			  struct sys_reg_params *p,
> +			  const struct sys_reg_desc *r)
> +{
> +	if (p->is_write)
> +		__vcpu_sys_reg(vcpu, SP_EL1) = p->regval;
> +	else
> +		p->regval = __vcpu_sys_reg(vcpu, SP_EL1);
> +
> +	return true;
> +}
> +
>  /*
>   * Architected system registers.
>   * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
> @@ -1825,9 +1882,51 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
>  	  .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
>  
> +	{ SYS_DESC(SYS_VPIDR_EL2), access_rw, reset_val, VPIDR_EL2, 0 },
> +	{ SYS_DESC(SYS_VMPIDR_EL2), access_rw, reset_val, VMPIDR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_SCTLR_EL2), access_sctlr_el2, reset_val, SCTLR_EL2, SCTLR_EL2_RES1 },
> +	{ SYS_DESC(SYS_ACTLR_EL2), access_rw, reset_val, ACTLR_EL2, 0 },
> +	{ SYS_DESC(SYS_HCR_EL2), access_rw, reset_val, HCR_EL2, 0 },
> +	{ SYS_DESC(SYS_MDCR_EL2), access_rw, reset_val, MDCR_EL2, 0 },
> +	{ SYS_DESC(SYS_CPTR_EL2), access_rw, reset_val, CPTR_EL2, CPTR_EL2_DEFAULT },
> +	{ SYS_DESC(SYS_HSTR_EL2), access_rw, reset_val, HSTR_EL2, 0 },
> +	{ SYS_DESC(SYS_HACR_EL2), access_rw, reset_val, HACR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_TTBR0_EL2), access_rw, reset_val, TTBR0_EL2, 0 },
> +	{ SYS_DESC(SYS_TTBR1_EL2), access_rw, reset_val, TTBR1_EL2, 0 },
> +	{ SYS_DESC(SYS_TCR_EL2), access_rw, reset_val, TCR_EL2, TCR_EL2_RES1 },
> +	{ SYS_DESC(SYS_VTTBR_EL2), access_rw, reset_val, VTTBR_EL2, 0 },
> +	{ SYS_DESC(SYS_VTCR_EL2), access_rw, reset_val, VTCR_EL2, 0 },
> +
>  	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
> +	{ SYS_DESC(SYS_SPSR_EL2), access_rw, reset_val, SPSR_EL2, 0 },
> +	{ SYS_DESC(SYS_ELR_EL2), access_rw, reset_val, ELR_EL2, 0 },
> +	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
> +
>  	{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },
> +	{ SYS_DESC(SYS_AFSR0_EL2), access_rw, reset_val, AFSR0_EL2, 0 },
> +	{ SYS_DESC(SYS_AFSR1_EL2), access_rw, reset_val, AFSR1_EL2, 0 },
> +	{ SYS_DESC(SYS_ESR_EL2), access_rw, reset_val, ESR_EL2, 0 },
>  	{ SYS_DESC(SYS_FPEXC32_EL2), NULL, reset_val, FPEXC32_EL2, 0x700 },
> +
> +	{ SYS_DESC(SYS_FAR_EL2), access_rw, reset_val, FAR_EL2, 0 },
> +	{ SYS_DESC(SYS_HPFAR_EL2), access_rw, reset_val, HPFAR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_MAIR_EL2), access_rw, reset_val, MAIR_EL2, 0 },
> +	{ SYS_DESC(SYS_AMAIR_EL2), access_rw, reset_val, AMAIR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_VBAR_EL2), access_rw, reset_val, VBAR_EL2, 0 },
> +	{ SYS_DESC(SYS_RVBAR_EL2), access_rw, reset_val, RVBAR_EL2, 0 },
> +	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
> +
> +	{ SYS_DESC(SYS_CONTEXTIDR_EL2), access_rw, reset_val, CONTEXTIDR_EL2, 0 },
> +	{ SYS_DESC(SYS_TPIDR_EL2), access_rw, reset_val, TPIDR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_CNTVOFF_EL2), access_rw, reset_val, CNTVOFF_EL2, 0 },
> +	{ SYS_DESC(SYS_CNTHCTL_EL2), access_rw, reset_val, CNTHCTL_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_SP_EL2), NULL, reset_unknown, SP_EL2 },
>  };
>  
>  static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
> -- 
> 2.30.2
> 


From marcel.ziswiler at toradex.com  Mon Jan 17 03:45:45 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Mon, 17 Jan 2022 11:45:45 +0000
Subject: [PATCH v2 04/11] arm64: defconfig: enable pcieaer configuration
In-Reply-To: <a03f3240-0e68-1451-0d97-109c024f784a@canonical.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-5-marcel@ziswiler.com>
 <a03f3240-0e68-1451-0d97-109c024f784a@canonical.com>
Message-ID: <28f9ff53dc1379fa6462bf54c5db556c3474c302.camel@toradex.com>

On Sat, 2022-01-15 at 17:45 +0100, Krzysztof Kozlowski wrote:
> On 14/01/2022 15:15, Marcel Ziswiler wrote:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > Enable CONFIG_PCIEAER which is required for CONFIG_ACPI_APEI_PCIEAER.
> > Commit 8c8ff55b4da7 ("PCI/AER: Don't select CONFIG_PCIEAER by default")
> > changed it to no longer being enabled by default.
> > 
> > Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - New patch following full defconfig analysis as requested by Krzysztof.
> > 
> 
> Good finding! The question is whether we actually need PCIe AER...

Yes, however, why else would we have explicitly enabled CONFIG_ACPI_APEI_PCIEAER?

> Best regards,
> Krzysztof

From krzysztof.kozlowski at canonical.com  Mon Jan 17 03:47:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 12:47:15 +0100
Subject: [PATCH v2 04/11] arm64: defconfig: enable pcieaer configuration
In-Reply-To: <28f9ff53dc1379fa6462bf54c5db556c3474c302.camel@toradex.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-5-marcel@ziswiler.com>
 <a03f3240-0e68-1451-0d97-109c024f784a@canonical.com>
 <28f9ff53dc1379fa6462bf54c5db556c3474c302.camel@toradex.com>
Message-ID: <1116a187-b43e-c139-ebdf-7d27a83c2389@canonical.com>

On 17/01/2022 12:45, Marcel Ziswiler wrote:
> On Sat, 2022-01-15 at 17:45 +0100, Krzysztof Kozlowski wrote:
>> On 14/01/2022 15:15, Marcel Ziswiler wrote:
>>> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>>
>>> Enable CONFIG_PCIEAER which is required for CONFIG_ACPI_APEI_PCIEAER.
>>> Commit 8c8ff55b4da7 ("PCI/AER: Don't select CONFIG_PCIEAER by default")
>>> changed it to no longer being enabled by default.
>>>
>>> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>>
>>> ---
>>>
>>> Changes in v2:
>>> - New patch following full defconfig analysis as requested by Krzysztof.
>>>
>>
>> Good finding! The question is whether we actually need PCIe AER...
> 
> Yes, however, why else would we have explicitly enabled CONFIG_ACPI_APEI_PCIEAER?

Right, I missed that it is mentioned in defconfig.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From matthias.bgg at gmail.com  Mon Jan 17 03:49:56 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Mon, 17 Jan 2022 12:49:56 +0100
Subject: [PATCH v10 00/13] Clean up "mediatek,larb"
In-Reply-To: <06e5e76c-557a-20a5-b8dd-37b25b3384a3@collabora.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
 <06e5e76c-557a-20a5-b8dd-37b25b3384a3@collabora.com>
Message-ID: <c8fc24a2-9ee3-75a2-0928-95a217d9dfdf@gmail.com>



On 17/01/2022 11:27, AngeloGioacchino Del Regno wrote:
> Il 17/01/22 08:04, Yong Wu ha scritto:
>> MediaTek IOMMU block diagram always like below:
>>
>> ???????? M4U
>> ????????? |
>> ???? smi-common
>> ????????? |
>> ?? -------------
>> ?? |???????? |? ...
>> ?? |???????? |
>> larb1???? larb2
>> ?? |???????? |
>> vdec?????? venc
>>
>> All the consumer connect with smi-larb, then connect with smi-common.
>>
>> When the consumer works, it should enable the smi-larb's power which also
>> need enable the smi-common's power firstly.
>>
>> Thus, Firstly, use the device link connect the consumer and the
>> smi-larbs. then add device link between the smi-larb and smi-common.
>>
>> After adding the device_link, then "mediatek,larb" property can be removed.
>> the iommu consumer don't need call the mtk_smi_larb_get/put to enable
>> the power and clock of smi-larb and smi-common.
>>
>> Base on the media branch [1] and a jpeg dtbinding patchset[2] that already got
>> the necessary R-b.
>>
>> [1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d
>> [2] 
>> https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsinyi at chromium.org/ 
>>
>>
>> Change notes:
>> v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches.
>> ????? b) Add Joerg's Ack for iommu patches.
>>
>> v9: 
>> https://lore.kernel.org/linux-mediatek/20211112105509.12010-1-yong.wu at mediatek.com/ 
>>
>> ???? 1) Add return -ENODEV when the dev is null.
>> ???? 2) Add more strict about the case that a iommu consume device use the 
>> ports in
>> ???? different larbs. Don't allow this case.
>> ???? 3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it 
>> only has one
>> ???? line now.
>>
>> v8: 
>> https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong.wu at mediatek.com/ 
>>
>> ???? 1) Rebase on v5.15-rc1.
>> ???? 2) Don't rebase the below mdp patchset that may still need more discuss.
>>      
>> https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-eizan at chromium.org/ 
>>
>> ???? 3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested.
>>
>> v7: 
>> https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong.wu at mediatek.com/ 
>>
>> ???? 1) Fix a arm32 boot fail issue. reported from Frank.
>> ???? 2) Add a return fail in the mtk drm. suggested by Dafna.
>>
>> v6: 
>> https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong.wu at mediatek.com/ 
>>
>> ???? 1) rebase on v5.14-rc1.
>> ???? 2) Fix the issue commented in v5 from Dafna and Hsin-Yi.
>> ???? 3) Remove the patches about using pm_runtime_resume_and_get since they have
>> ??????? already been merged by other patches.
>>
>> v5: 
>> https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong.wu at mediatek.com/ 
>>
>> ???? 1) Base v5.12-rc2.
>> ???? 2) Remove changing the mtk-iommu to module_platform_driver patch, It have 
>> already been a
>> ???? independent patch.
>>
>> v4: 
>> https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong.wu at mediatek.com/ 
>>
>> ???? base on v5.7-rc1.
>> ?? 1) Move drm PM patch before smi patchs.
>> ?? 2) Change builtin_platform_driver to module_platform_driver since we may need
>> ????? build as module.
>> ?? 3) Rebase many patchset as above.
>>
>> v3: 
>> https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong.wu at mediatek.com/ 
>>
>> ???? 1) rebase on v5.3-rc1 and the latest mt8183 patchset.
>> ???? 2) Use device_is_bound to check whether the driver is ready from Matthias.
>> ???? 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
>> ??? reason in the commit message[3/14].
>> ???? 4) Add a display patch[12/14] into this series. otherwise it may affect
>> ??? display HW fastlogo even though it don't happen in mt8183.
>> v2: 
>> https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong.wu at mediatek.com/ 
>>
>> ??? 1) rebase on v5.2-rc1.
>> ??? 2) Move adding device_link between the consumer and smi-larb into
>> iommu_add_device from Robin.
>> ??? 3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
>> ??? 4) Remove the shutdown callback in iommu.
>>
>> v1: 
>> https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong.wu at mediatek.com/ 
>>
>>
>> Yong Wu (12):
>> ?? dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
>> ?? iommu/mediatek-v1: Free the existed fwspec if the master dev already
>> ???? has
>> ?? iommu/mediatek: Return ENODEV if the device is NULL
>> ?? iommu/mediatek: Add probe_defer for smi-larb
>> ?? iommu/mediatek: Add device_link between the consumer and the larb
>> ???? devices
>> ?? media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
>> ?? media: mtk-mdp: Get rid of mtk_smi_larb_get/put
>> ?? drm/mediatek: Get rid of mtk_smi_larb_get/put
>> ?? media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
>> ?? memory: mtk-smi: Get rid of mtk_smi_larb_get/put
>> ?? arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
>> ?? arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
>>
>> Yongqiang Niu (1):
>> ?? drm/mediatek: Add pm runtime support for ovl and rdma
>>
>> ? .../display/mediatek/mediatek,disp.txt??????? |? 9 ----
>> ? .../media/mediatek,vcodec-decoder.yaml??????? |? 7 ---
>> ? .../media/mediatek,vcodec-encoder.yaml??????? |? 8 ----
>> ? .../bindings/media/mediatek-jpeg-decoder.yaml |? 9 ----
>> ? .../bindings/media/mediatek-jpeg-encoder.yaml |? 9 ----
>> ? .../bindings/media/mediatek-mdp.txt?????????? |? 8 ----
>> ? arch/arm/boot/dts/mt2701.dtsi???????????????? |? 2 -
>> ? arch/arm/boot/dts/mt7623n.dtsi??????????????? |? 5 ---
>> ? arch/arm64/boot/dts/mediatek/mt8173.dtsi????? | 16 -------
>> ? arch/arm64/boot/dts/mediatek/mt8183.dtsi????? |? 6 ---
>> ? drivers/gpu/drm/mediatek/mtk_disp_ovl.c?????? |? 8 +++-
>> ? drivers/gpu/drm/mediatek/mtk_disp_rdma.c????? |? 9 +++-
>> ? drivers/gpu/drm/mediatek/mtk_drm_crtc.c?????? | 15 ++++---
>> ? drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c?? | 36 +--------------
>> ? drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h?? |? 1 -
>> ? drivers/gpu/drm/mediatek/mtk_drm_drv.c??????? |? 5 +--
>> ? drivers/iommu/mtk_iommu.c???????????????????? | 34 ++++++++++++++
>> ? drivers/iommu/mtk_iommu_v1.c????????????????? | 42 ++++++++++++++++-
>> ? .../media/platform/mtk-jpeg/mtk_jpeg_core.c?? | 45 +------------------
>> ? .../media/platform/mtk-jpeg/mtk_jpeg_core.h?? |? 2 -
>> ? drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 -----------------
>> ? drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |? 2 -
>> ? drivers/media/platform/mtk-mdp/mtk_mdp_core.c |? 1 -
>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c? |? 2 -
>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c?? |? 1 -
>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c?? | 41 +++--------------
>> ? .../platform/mtk-vcodec/mtk_vcodec_drv.h????? |? 3 --
>> ? .../platform/mtk-vcodec/mtk_vcodec_enc.c????? |? 1 -
>> ? .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c? |? 2 -
>> ? .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c?? | 45 +++----------------
>> ? drivers/memory/mtk-smi.c????????????????????? | 14 ------
>> ? include/soc/mediatek/smi.h??????????????????? | 20 ---------
>> ? 32 files changed, 115 insertions(+), 333 deletions(-)
>>
> 
> Hello Hans, Matthias,
> on my side, this series is totally ready for merge, hence, green light from here.
> 
> Can you please take it for 5.18?
> 

@Hans: I understand you take the series through your tree. Please let me know 
when you do so. I'll take care of patch 12 and 13, which should go through my tree.

Thanks!
Matthias


From heiko at sntech.de  Mon Jan 17 03:51:57 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 17 Jan 2022 12:51:57 +0100
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>
References: <20220116124911.65203-1-linux@fw-web.de>
 <20220116124911.65203-2-linux@fw-web.de>
 <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>
Message-ID: <7013096.8LbZJEEdqx@diego>

Am Montag, 17. Januar 2022, 11:47:16 CET schrieb Johan Jonker:
> Hi Frank,
> 
> Despite that the DT is hosted in the kernel tree
> DT and mainline kernel driver support are 2 separate things.
> PCLK_XPCS might be in use elsewhere.

I've just looked through the rk3568 TRM and I guess the
pclk_xpcs belongs to the QSGMII_PCS block living at
the 0xfda00000 address in the memory map.

>From glancing at the documentation that PCS thingy
can sit in between the dmac and the phy to "optimize" things
like power consumption.

Looking at the PIPE_GRF_XPCS_CON0, we can see that
bit1 decides which mac is to be selected to use the sgmii
interface to that PCS block.

As the QSGMII_PCS block should have its own driver
due to also its own config registers (see above), the pclk_xpcs
also will belong to it and should be modeled there.

Also I guess boards currently in production will use
regular gmii network interfaces?



> Given the link below pclk_xpcs is only needed for rk3568.
> Maybe gmac1 should have a PCLK_XPCS too, because one can select between
> them.
> 
> ethernet: stmicro: stmmac: Add SGMII/QSGMII support for RK3568
> https://github.com/rockchip-linux/kernel/commit/1fc7cbfe9e227c700c692f1de3137914b3ea6ca6
> 
> The original dtsi did have PCLK_XPCS in both nodes.
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L2121
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L1492
> 
> Maybe fix the document or leave it as it is for now as long the driver
> isn't updated and someone has tested it.
> That's up to the DT maintainer.
> 
> Johan
> 
> ===
> 
> XPCS is also part of PD_PIPE.
> See Rockchip RK3568 TRM Part1 V1.0-20210111.pdf page 475.
> Please advise if the power-domain at RK3568_PD_PIPE does need a PCLK_XPCS
> fix or is PCLK_PIPE enough in combination with a PHY driver?
> 
> PD_PIPE:
> 
> BIU_PIPE
> USB3OTG
> PCIE20
> PCIE30
> SATA
> XPCS
> 
> 
> 	power-domain at RK3568_PD_PIPE {
> 		reg = <RK3568_PD_PIPE>;
> 		clocks = <&cru PCLK_PIPE>;
> 		pm_qos = <&qos_pcie2x1>,
> 			 <&qos_pcie3x1>,
> 			 <&qos_pcie3x2>,
> 			 <&qos_sata0>,
> 			 <&qos_sata1>,
> 			 <&qos_sata2>,
> 			 <&qos_usb3_0>,
> 			 <&qos_usb3_1>;
> 		#power-domain-cells = <0>;
> 	};
> 
> 
> 
> On 1/16/22 1:49 PM, Frank Wunderlich wrote:
> > From: Frank Wunderlich <frank-w at public-files.de>
> > 
> > pclk_xpcs is not supported and breaks dtbs_check, so remove it
> > 
> > following warnings occour, and many more
> > 
> > rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
> >     [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
> >     [15, 389], [15, 185], [15, 172]] is too long
> > 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
> >     ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
> >     'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
> > 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > 
> > after removing the clock the other warnings are also gone.
> > 
> > Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
> >  1 file changed, 2 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> > index 2fd313a295f8..d91df1cde736 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
> > @@ -32,13 +32,11 @@ gmac0: ethernet at fe2a0000 {
> >  		clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
> >  			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
> >  			 <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
> > -			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
> > -			 <&cru PCLK_XPCS>;
> > +			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
> >  		clock-names = "stmmaceth", "mac_clk_rx",
> >  			      "mac_clk_tx", "clk_mac_refout",
> >  			      "aclk_mac", "pclk_mac",
> > -			      "clk_mac_speed", "ptp_ref",
> > -			      "pclk_xpcs";
> > +			      "clk_mac_speed", "ptp_ref";
> >  		resets = <&cru SRST_A_GMAC0>;
> >  		reset-names = "stmmaceth";
> >  		rockchip,grf = <&grf>;
> > 
> 






From frank-w at public-files.de  Mon Jan 17 03:59:03 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 17 Jan 2022 12:59:03 +0100
Subject: Aw: Re: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>
References: <20220116124911.65203-1-linux@fw-web.de>
 <20220116124911.65203-2-linux@fw-web.de>
 <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>
Message-ID: <trinity-5a2f356e-2777-4624-b921-f8f56ce282c7-1642420742957@3c-app-gmx-bap64>

Hi

> Gesendet: Montag, 17. Januar 2022 um 11:47 Uhr
> Von: "Johan Jonker" <jbx6244 at gmail.com>
> Hi Frank,
>
> Despite that the DT is hosted in the kernel tree
> DT and mainline kernel driver support are 2 separate things.
> PCLK_XPCS might be in use elsewhere.
>
> Given the link below pclk_xpcs is only needed for rk3568.
> Maybe gmac1 should have a PCLK_XPCS too, because one can select between
> them.
>
> ethernet: stmicro: stmmac: Add SGMII/QSGMII support for RK3568
> https://github.com/rockchip-linux/kernel/commit/1fc7cbfe9e227c700c692f1de3137914b3ea6ca6
>
> The original dtsi did have PCLK_XPCS in both nodes.
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L2121
> https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L1492
>
> Maybe fix the document or leave it as it is for now as long the driver
> isn't updated and someone has tested it.
> That's up to the DT maintainer.
>
> Johan

as far as i understand, the PCLK_XPCS is part of the naneng combphy, which is not yet available in mainline.
Naneng driver needs some changes and imho this should be part of it (including change documentation). That also makes it clear why this clock is added.
But leaving an unused property with sideeffects is imho no good choice.

So this was the easiest way to fix the dtbs_check. Else i got no usable result for it. Maybe adding it to Documentation is also easy, but have not yet looked into it as it currently unused from my POV.

But i leave it as decision for Maintainer to drop this patch as it is not needed for my Board DTS.

> ===
>
> XPCS is also part of PD_PIPE.
> See Rockchip RK3568 TRM Part1 V1.0-20210111.pdf page 475.
> Please advise if the power-domain at RK3568_PD_PIPE does need a PCLK_XPCS
> fix or is PCLK_PIPE enough in combination with a PHY driver?
>
> PD_PIPE:
>
> BIU_PIPE
> USB3OTG
> PCIE20
> PCIE30
> SATA
> XPCS
>
>
> 	power-domain at RK3568_PD_PIPE {
> 		reg = <RK3568_PD_PIPE>;
> 		clocks = <&cru PCLK_PIPE>;
> 		pm_qos = <&qos_pcie2x1>,
> 			 <&qos_pcie3x1>,
> 			 <&qos_pcie3x2>,
> 			 <&qos_sata0>,
> 			 <&qos_sata1>,
> 			 <&qos_sata2>,
> 			 <&qos_usb3_0>,
> 			 <&qos_usb3_1>;
> 		#power-domain-cells = <0>;
> 	};

PD_PIPE is imho also part of Naneng. But more for usage as USB3/SATA/... phy. This is not part of Mainline too.

But thanks for pointing.

regards Frank


From krzysztof.kozlowski at canonical.com  Mon Jan 17 04:01:40 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 13:01:40 +0100
Subject: [PATCH v3 5/7] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <20220113111057.29918-6-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-6-yong.wu@mediatek.com>
Message-ID: <7370f18b-e273-69f2-1cc9-a42495e04874@canonical.com>

On 13/01/2022 12:10, Yong Wu wrote:
> Function clk_bulk_prepare_enable() returns 0 for success or a negative
> number for error. Fix this code style issue.

The message does not really make sense. If negative is returned, then
the check (ret < 0) was correct.

I guess you wanted to say that common code style is to check for any
non-zero return value, just like it's implementation in clk.h does.

I'll adjust the commit msg when applying.

> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/memory/mtk-smi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> index b883dcc0bbfa..e7b1a22b12ea 100644
> --- a/drivers/memory/mtk-smi.c
> +++ b/drivers/memory/mtk-smi.c
> @@ -480,7 +480,7 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
>  	int ret;
>  
>  	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
> -	if (ret < 0)
> +	if (ret)
>  		return ret;
>  
>  	/* Configure the basic setting for this larb */
> 


Best regards,
Krzysztof


From hverkuil at xs4all.nl  Mon Jan 17 04:04:45 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 17 Jan 2022 13:04:45 +0100
Subject: [PATCH v10 00/13] Clean up "mediatek,larb"
In-Reply-To: <c8fc24a2-9ee3-75a2-0928-95a217d9dfdf@gmail.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
 <06e5e76c-557a-20a5-b8dd-37b25b3384a3@collabora.com>
 <c8fc24a2-9ee3-75a2-0928-95a217d9dfdf@gmail.com>
Message-ID: <6044093c-a3e3-135d-9c14-016d64dcef1f@xs4all.nl>

Hi Matthias,

On 1/17/22 12:49, Matthias Brugger wrote:
> 
> 
> On 17/01/2022 11:27, AngeloGioacchino Del Regno wrote:
>> Il 17/01/22 08:04, Yong Wu ha scritto:
>>> MediaTek IOMMU block diagram always like below:
>>>
>>> ???????? M4U
>>> ????????? |
>>> ???? smi-common
>>> ????????? |
>>> ?? -------------
>>> ?? |???????? |? ...
>>> ?? |???????? |
>>> larb1???? larb2
>>> ?? |???????? |
>>> vdec?????? venc
>>>
>>> All the consumer connect with smi-larb, then connect with smi-common.
>>>
>>> When the consumer works, it should enable the smi-larb's power which also
>>> need enable the smi-common's power firstly.
>>>
>>> Thus, Firstly, use the device link connect the consumer and the
>>> smi-larbs. then add device link between the smi-larb and smi-common.
>>>
>>> After adding the device_link, then "mediatek,larb" property can be removed.
>>> the iommu consumer don't need call the mtk_smi_larb_get/put to enable
>>> the power and clock of smi-larb and smi-common.
>>>
>>> Base on the media branch [1] and a jpeg dtbinding patchset[2] that already got
>>> the necessary R-b.
>>>
>>> [1] git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18d
>>> [2] https://lore.kernel.org/linux-mediatek/20211206130425.184420-1-hsinyi at chromium.org/
>>>
>>> Change notes:
>>> v10: a) Rebase on the media tree. Respin the "media: mtk-vcodec:" patches.
>>> ????? b) Add Joerg's Ack for iommu patches.
>>>
>>> v9: https://lore.kernel.org/linux-mediatek/20211112105509.12010-1-yong.wu at mediatek.com/
>>> ???? 1) Add return -ENODEV when the dev is null.
>>> ???? 2) Add more strict about the case that a iommu consume device use the ports in
>>> ???? different larbs. Don't allow this case.
>>> ???? 3) Remove two codec interface: mtk_vcodec_release_enc/dec_pm since it only has one
>>> ???? line now.
>>>
>>> v8: https://lore.kernel.org/linux-mediatek/20210929013719.25120-1-yong.wu at mediatek.com/
>>> ???? 1) Rebase on v5.15-rc1.
>>> ???? 2) Don't rebase the below mdp patchset that may still need more discuss.
>>> ???? https://lore.kernel.org/linux-mediatek/20210709022324.1607884-1-eizan at chromium.org/
>>> ???? 3) Add Frank's Tested-by. Remove Dafna's Tested-by as he requested.
>>>
>>> v7: https://lore.kernel.org/linux-mediatek/20210730025238.22456-1-yong.wu at mediatek.com/
>>> ???? 1) Fix a arm32 boot fail issue. reported from Frank.
>>> ???? 2) Add a return fail in the mtk drm. suggested by Dafna.
>>>
>>> v6: https://lore.kernel.org/linux-mediatek/20210714025626.5528-1-yong.wu at mediatek.com/
>>> ???? 1) rebase on v5.14-rc1.
>>> ???? 2) Fix the issue commented in v5 from Dafna and Hsin-Yi.
>>> ???? 3) Remove the patches about using pm_runtime_resume_and_get since they have
>>> ??????? already been merged by other patches.
>>>
>>> v5: https://lore.kernel.org/linux-mediatek/20210410091128.31823-1-yong.wu at mediatek.com/
>>> ???? 1) Base v5.12-rc2.
>>> ???? 2) Remove changing the mtk-iommu to module_platform_driver patch, It have already been a
>>> ???? independent patch.
>>>
>>> v4: https://lore.kernel.org/linux-mediatek/1590826218-23653-1-git-send-email-yong.wu at mediatek.com/
>>> ???? base on v5.7-rc1.
>>> ?? 1) Move drm PM patch before smi patchs.
>>> ?? 2) Change builtin_platform_driver to module_platform_driver since we may need
>>> ????? build as module.
>>> ?? 3) Rebase many patchset as above.
>>>
>>> v3: https://lore.kernel.org/linux-iommu/1567503456-24725-1-git-send-email-yong.wu at mediatek.com/
>>> ???? 1) rebase on v5.3-rc1 and the latest mt8183 patchset.
>>> ???? 2) Use device_is_bound to check whether the driver is ready from Matthias.
>>> ???? 3) Add DL_FLAG_STATELESS flag when calling device_link_add and explain the
>>> ??? reason in the commit message[3/14].
>>> ???? 4) Add a display patch[12/14] into this series. otherwise it may affect
>>> ??? display HW fastlogo even though it don't happen in mt8183.
>>> v2: https://lore.kernel.org/linux-iommu/1560171313-28299-1-git-send-email-yong.wu at mediatek.com/
>>> ??? 1) rebase on v5.2-rc1.
>>> ??? 2) Move adding device_link between the consumer and smi-larb into
>>> iommu_add_device from Robin.
>>> ??? 3) add DL_FLAG_AUTOREMOVE_CONSUMER even though the smi is built-in from Evan.
>>> ??? 4) Remove the shutdown callback in iommu.
>>>
>>> v1: https://lore.kernel.org/linux-iommu/1546318276-18993-1-git-send-email-yong.wu at mediatek.com/
>>>
>>> Yong Wu (12):
>>> ?? dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
>>> ?? iommu/mediatek-v1: Free the existed fwspec if the master dev already
>>> ???? has
>>> ?? iommu/mediatek: Return ENODEV if the device is NULL
>>> ?? iommu/mediatek: Add probe_defer for smi-larb
>>> ?? iommu/mediatek: Add device_link between the consumer and the larb
>>> ???? devices
>>> ?? media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
>>> ?? media: mtk-mdp: Get rid of mtk_smi_larb_get/put
>>> ?? drm/mediatek: Get rid of mtk_smi_larb_get/put
>>> ?? media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
>>> ?? memory: mtk-smi: Get rid of mtk_smi_larb_get/put
>>> ?? arm: dts: mediatek: Get rid of mediatek,larb for MM nodes
>>> ?? arm64: dts: mediatek: Get rid of mediatek,larb for MM nodes
>>>
>>> Yongqiang Niu (1):
>>> ?? drm/mediatek: Add pm runtime support for ovl and rdma
>>>
>>> ? .../display/mediatek/mediatek,disp.txt??????? |? 9 ----
>>> ? .../media/mediatek,vcodec-decoder.yaml??????? |? 7 ---
>>> ? .../media/mediatek,vcodec-encoder.yaml??????? |? 8 ----
>>> ? .../bindings/media/mediatek-jpeg-decoder.yaml |? 9 ----
>>> ? .../bindings/media/mediatek-jpeg-encoder.yaml |? 9 ----
>>> ? .../bindings/media/mediatek-mdp.txt?????????? |? 8 ----
>>> ? arch/arm/boot/dts/mt2701.dtsi???????????????? |? 2 -
>>> ? arch/arm/boot/dts/mt7623n.dtsi??????????????? |? 5 ---
>>> ? arch/arm64/boot/dts/mediatek/mt8173.dtsi????? | 16 -------
>>> ? arch/arm64/boot/dts/mediatek/mt8183.dtsi????? |? 6 ---
>>> ? drivers/gpu/drm/mediatek/mtk_disp_ovl.c?????? |? 8 +++-
>>> ? drivers/gpu/drm/mediatek/mtk_disp_rdma.c????? |? 9 +++-
>>> ? drivers/gpu/drm/mediatek/mtk_drm_crtc.c?????? | 15 ++++---
>>> ? drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c?? | 36 +--------------
>>> ? drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h?? |? 1 -
>>> ? drivers/gpu/drm/mediatek/mtk_drm_drv.c??????? |? 5 +--
>>> ? drivers/iommu/mtk_iommu.c???????????????????? | 34 ++++++++++++++
>>> ? drivers/iommu/mtk_iommu_v1.c????????????????? | 42 ++++++++++++++++-
>>> ? .../media/platform/mtk-jpeg/mtk_jpeg_core.c?? | 45 +------------------
>>> ? .../media/platform/mtk-jpeg/mtk_jpeg_core.h?? |? 2 -
>>> ? drivers/media/platform/mtk-mdp/mtk_mdp_comp.c | 40 -----------------
>>> ? drivers/media/platform/mtk-mdp/mtk_mdp_comp.h |? 2 -
>>> ? drivers/media/platform/mtk-mdp/mtk_mdp_core.c |? 1 -
>>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c? |? 2 -
>>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c?? |? 1 -
>>> ? .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c?? | 41 +++--------------
>>> ? .../platform/mtk-vcodec/mtk_vcodec_drv.h????? |? 3 --
>>> ? .../platform/mtk-vcodec/mtk_vcodec_enc.c????? |? 1 -
>>> ? .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c? |? 2 -
>>> ? .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c?? | 45 +++----------------
>>> ? drivers/memory/mtk-smi.c????????????????????? | 14 ------
>>> ? include/soc/mediatek/smi.h??????????????????? | 20 ---------
>>> ? 32 files changed, 115 insertions(+), 333 deletions(-)
>>>
>>
>> Hello Hans, Matthias,
>> on my side, this series is totally ready for merge, hence, green light from here.
>>
>> Can you please take it for 5.18?
>>
> 
> @Hans: I understand you take the series through your tree. Please let me know when you do so. I'll take care of patch 12 and 13, which should go through my tree.

Will do. I hope to send the PR in the next few days.

Regards,

	Hans


From marcel.ziswiler at toradex.com  Mon Jan 17 04:05:18 2022
From: marcel.ziswiler at toradex.com (Marcel Ziswiler)
Date: Mon, 17 Jan 2022 12:05:18 +0000
Subject: [PATCH v2 05/11] arm64: defconfig: rebuild default configuration
In-Reply-To: <060a9f66-fc00-2247-46f2-1c700d0e9bf3@canonical.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-6-marcel@ziswiler.com>
 <060a9f66-fc00-2247-46f2-1c700d0e9bf3@canonical.com>
Message-ID: <a5cfdd2ea149490abeb481c7a85d59019ea3c620.camel@toradex.com>

On Sat, 2022-01-15 at 18:02 +0100, Krzysztof Kozlowski wrote:
> On 14/01/2022 15:15, Marcel Ziswiler wrote:
> > From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> > 
> > Run "make defconfig; make savedefconfig" to rebuild defconfig.
> > 
> > This re-ordered the following configuration options:
> > 
> > CONFIG_BPF_JIT=y
> > CONFIG_ARM_SCMI_PROTOCOL=y
> > CONFIG_ARM_SCPI_PROTOCOL=y
> > CONFIG_RASPBERRYPI_FIRMWARE=y
> > CONFIG_INTEL_STRATIX10_SERVICE=y
> > CONFIG_INTEL_STRATIX10_RSU=m
> > CONFIG_EFI_CAPSULE_LOADER=y
> > CONFIG_IMX_SCU=y
> > CONFIG_IMX_SCU_PD=y
> > CONFIG_CAN_FLEXCAN=m
> > CONFIG_PCIE_LAYERSCAPE_GEN4=y
> > CONFIG_MTK_DEVAPC=m
> > CONFIG_SPI_CADENCE_QUADSPI=y
> > CONFIG_MDIO_BUS_MUX_MMIOREG=y
> > CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
> > CONFIG_MESON_GXL_PHY=m
> > CONFIG_QCOM_CPR=y
> > CONFIG_ROCKCHIP_IODOMAIN=y
> > CONFIG_SENSORS_ARM_SCMI=y
> > CONFIG_QORIQ_THERMAL=m
> > CONFIG_SUN8I_THERMAL=y
> > CONFIG_TEGRA_BPMP_THERMAL=m
> > CONFIG_ARM_SMC_WATCHDOG=y
> > CONFIG_VIDEO_QCOM_CAMSS=m
> > CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
> > CONFIG_DRM_NWL_MIPI_DSI=m
> > CONFIG_DRM_LONTIUM_LT9611UXC=m
> > CONFIG_SND_SOC_IMX_AUDMIX=m
> > CONFIG_TYPEC_HD3SS3220=m
> > CONFIG_COMMON_CLK_SCMI=y
> > CONFIG_IPQ_GCC_8074=y
> > CONFIG_SM_DISPCC_8250=y
> > CONFIG_QCOM_WCNSS_CTRL=m
> > CONFIG_ARCH_R8A774A1=y
> > CONFIG_ARCH_R8A774B1=y
> > CONFIG_ARCH_R8A774C0=y
> > CONFIG_ARCH_R8A774E1=y
> > CONFIG_ARCH_R8A77995=y
> > CONFIG_ARCH_R8A77990=y
> > CONFIG_ARCH_R8A77965=y
> > CONFIG_ARCH_R8A77970=y
> > CONFIG_HISI_PMU=y
> > CONFIG_QCOM_QFPROM=y
> > CONFIG_MUX_MMIO=y
> 
> Thanks for the changes.
> The best would be to have a separate patch only for re-ordering.

Yes, from a review perspective that makes sense. Will do so in v3.

> > And dropped the following configuration options which are nowaday's
> > already enabled (resp. disabled) by default:
> > 
> > CONFIG_MEMCG_SWAP=y
> > CONFIG_SECCOMP=y
> 
> Is it? I tried now on next-20220114 and it is still user-selectable and
> not chosen by anything.

Hm, strange. I guess, it is due to this whole patch series, given its i.MX main focus, being based on Shawn's
for-next branch. Maybe for such defconfig changes it would be better to base them on something else? Not sure,
who will ultimately pull such changes. Any suggestion?

> > CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
> > CONFIG_QCOM_SCM=y
> > # CONFIG_BT_HS is not set
> > CONFIG_FSL_MC_BUS=y
> > CONFIG_MEDIA_CONTROLLER=y
> > CONFIG_VIDEO_V4L2_SUBDEV_API=y
> > CONFIG_SND_SOC_FSL_SAI=m
> > CONFIG_USB_CONN_GPIO=m
> > CONFIG_USB_XHCI_PCI=m
> > CONFIG_MFD_CROS_EC_DEV=y
> > CONFIG_COMMON_CLK_ZYNQMP=y
> > CONFIG_SDM_GCC_845=y
> > CONFIG_SM_GCC_8150=y
> > CONFIG_SM_GCC_8250=y
> > CONFIG_SLIMBUS=m
> > CONFIG_INTERCONNECT=y
> > CONFIG_CONFIGFS_FS=y
> 
> All three above are still user-selectable, so please leave them. It is
> redundant, but there is no guarantee that something selecting a
> user-visible symbol will stop selecting it. IOW, user-visible symbols
> should be still chosen by defconfigs if they really want them.

Well, but even if they are already enabled anyway? What is the point of savedefconfig then resp. you are saying
that the commited defconfigs should not be generated using savedefconfig? That sounds rather confusing to me.

> See for example commit a2315d3aea59 ("ARM: exynos_defconfig: Restore
> debugfs support") for rationale why we need to keep them.

Okay, I see what you mean as in relation to above mentioned commit but then any change to Kconfig dependencies
can ultimately change the behaviour of previous configs unless they are complete ones (or were just lucky to
include whatever stuff that changed). But how should one now know which of them zillions of user-selectable
options should be added to such "more robust" defconfigs?

I suggest a better approach might be to have some CI which validates defconfig changes. That way one could
easily track stuff disappearing and could at that point explicitly enable it again.

> Best regards,
> Krzysztof

Cheers

Marcel

From irui.wang at mediatek.com  Mon Jan 17 04:06:05 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:05 +0800
Subject: [PATCH v2, 00/10] Enable two H264 encoder cores on MT8195
Message-ID: <20220117120615.21687-1-irui.wang@mediatek.com>

MT8195 has two H264 encoder cores, they have their own power-domains,
clocks, interrupts, register base. The two H264 encoder cores can work
together to achieve higher performance, it's a core mode called
frame-racing, one core has 4K at 30fps performance, two cores can achieve
4K at 60fps.
The two encoder core encoding process looks like this:

    VENC Core0: frm#0....frm#2....frm#4....
    VENC Core1: ..frm#1....frm#3....frm#5....

This series of patches are used to enable the two H264 encoder cores,
encoding process will be changed:
As-Is: Synchronous
V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> wait encoder IRQ -->
encoding done with result --> job_finish
V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> wait encoder IRQ -->
encoding done with result --> job_finish
...

To-Be: Asynchronous
V4L2_VIDIOC_QBUF#0 --> device_run(triger encoder) --> job_finish
..V4l2_VIDIOC_QBUF#1 --> device_run(triger encoder) --> job_finish
(venc core0 may encode done here, done the encoding result to client)
V4L2_VIDIOC_QBUF#2 --> device_run(triger encoder) --> job_finish.

There is no "wait encoder IRQ" synchronous call during frame-racing mode
encoding process, it can full use the two encoder cores to achieve higher
performance.

---
This series patches dependent on:
[1]: the latest linux stage tree: https://git.linuxtv.org/media_stage.git

mtk decoder patches
[2]: https://patchwork.linuxtv.org/project/linux-media/list/?series=7105
[3]: https://patchwork.linuxtv.org/project/linux-media/list/?series=7131

new yaml included files
[4]:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=551641
[5]:
https://patchwork.kernel.org/project/linux-mediatek/list/?series=580579

---
---
changes compared with v1:
- of_platform_populate was used in place of the component framework.
- new yaml file for venc cores.
- some modifications for patch v1's review comments.
---

Irui Wang (10):
  media: mtk-vcodec: Use core type to indicate h264 and vp8 enc
  media: mtk-vcodec: export encoder functions
  dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings for
    mt8195
  media: mtk-vcodec: Enable venc dual core usage
  media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage interface
  media: mtk-vcodec: Add venc power on/off interface
  media: mtk-vcodec: Rewrite venc clock interface
  media: mtk-vcodec: Add more extra processing for dual-core mode
  media: mtk-vcodec: Add dual core mode encode process
  media: mtk-vcodec: Done encode result to client

 .../media/mediatek,vcodec-encoder-core.yaml   | 214 +++++++++++++++++
 drivers/media/platform/mtk-vcodec/Makefile    |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  44 +++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 109 ++++++---
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |   7 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 187 +++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.h |  36 +++
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 118 ++++++----
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 187 +++++++++++++--
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  11 +-
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 ++
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   5 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 216 +++++++++++++++---
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |   3 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   |  79 +++++--
 .../media/platform/mtk-vcodec/venc_drv_if.h   |   7 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |  10 +-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |   3 +-
 18 files changed, 1097 insertions(+), 162 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h

-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:07 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:07 +0800
Subject: [PATCH v2, 02/10] media: mtk-vcodec: export encoder functions
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-3-irui.wang@mediatek.com>

mtk vcodec is built as a module, export some functions to make them
visible by other modules.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c    | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index ffb046eec610..134dc53e4855 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1432,6 +1432,7 @@ int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
 	mutex_unlock(&dev->enc_mutex);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_venc_unlock);
 
 int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
 {
@@ -1440,6 +1441,7 @@ int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
 	mutex_lock(&dev->enc_mutex);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtk_venc_lock);
 
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 0825c6ec4eb7..7eba1a990ed7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -85,6 +85,7 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 	put_device(pm->larbvenc);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_init_enc_clk);
 
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 {
@@ -111,6 +112,7 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_on);
 
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 {
@@ -121,3 +123,4 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 	for (i = enc_clk->clk_num - 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
+EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:12 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:12 +0800
Subject: [PATCH v2, 07/10] media: mtk-vcodec: Rewrite venc clock interface
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-8-irui.wang@mediatek.com>

Dual core mode need enable the specific core's clk, add an
another param for clock_on/clock_off interface.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 96 ++++++++++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  4 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   | 10 +-
 3 files changed, 86 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index dfaef884e6e3..4e37d68f75dd 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -83,17 +83,42 @@ int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_enc_clk);
 
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
+	struct clk              *clk;
 	int ret, i = 0;
 
-	for (i = 0; i < enc_clk->clk_num; i++) {
-		ret = clk_prepare_enable(enc_clk->clk_info[i].vcodec_clk);
-		if (ret) {
-			mtk_v4l2_err("venc clk_prepare_enable %d %s fail %d", i,
-				enc_clk->clk_info[i].clk_name, ret);
-			goto clkerr;
+	if (dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[core_id];
+		enc_pm = &core->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_enable %d %s fail %d", i,
+					     enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto core_clk_err;
+			}
+		}
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = 0; i < enc_clk->clk_num; i++) {
+			clk = enc_clk->clk_info[i].vcodec_clk;
+			ret = clk_prepare_enable(clk);
+			if (ret) {
+				mtk_v4l2_err("clk_prepare %d %s fail %d",
+					     i, enc_clk->clk_info[i].clk_name,
+					     ret);
+				goto clkerr;
+			}
 		}
 	}
 
@@ -104,27 +129,49 @@ void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm)
 	}
 	return;
 
+core_clk_err:
+	for (i -= 1; i >= 0; i--)
+		clk_disable(enc_clk->clk_info[i].vcodec_clk);
+
+	return;
+
 clkerr:
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_on);
 
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id)
 {
-	struct mtk_vcodec_clk *enc_clk = &pm->venc_clk;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_pm *enc_pm;
+	struct mtk_vcodec_clk *enc_clk;
 	int i = 0;
 
 	mtk_smi_larb_put(pm->larbvenc);
-	for (i = enc_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+
+	if (dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[core_id];
+		enc_pm = &core->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable(enc_clk->clk_info[i].vcodec_clk);
+	} else {
+		enc_pm = &dev->pm;
+		enc_clk = &enc_pm->venc_clk;
+
+		for (i = enc_clk->clk_num - 1; i >= 0; i--)
+			clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
+	}
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
 
 int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 {
-	int i, ret;
+	int i, ret, j = 0;
 	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_clk *clk;
 
 	/* power on all available venc cores */
 	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
@@ -137,12 +184,28 @@ int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
 			goto pw_on_fail;
 		}
+
+		clk = &core->pm.venc_clk;
+		for (j = 0; j < clk->clk_num; j++) {
+			ret = clk_prepare(clk->clk_info[j].vcodec_clk);
+			if (ret) {
+				mtk_v4l2_err("prepare clk [%s] fail %d",
+					     clk->clk_info[j].clk_name,
+					     ret);
+				goto pw_on_fail;
+			}
+		}
 	}
 	return 0;
 
 pw_on_fail:
 	for (i -= 1; i >= 0; i--) {
 		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+
+		clk = &core->pm.venc_clk;
+		for (j -= 1; j >= 0; j--)
+			clk_unprepare(clk->clk_info[j].vcodec_clk);
+
 		pm_runtime_put_sync(&core->plat_dev->dev);
 	}
 	return ret;
@@ -150,8 +213,9 @@ int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
 
 int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
 {
-	int i, ret;
+	int i, ret, j;
 	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_clk *clk;
 
 	/* power off all available venc cores */
 	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
@@ -159,6 +223,10 @@ int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
 		if (!core)
 			return 0;
 
+		clk = &core->pm.venc_clk;
+		for (j = clk->clk_num - 1; j >= 0; j--)
+			clk_unprepare(clk->clk_info[j].vcodec_clk);
+
 		ret = pm_runtime_put_sync(&core->plat_dev->dev);
 		if (ret < 0)
 			mtk_v4l2_err("power off core[%d] fail %d", i, ret);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index 99b6b6e29e35..5113ed8a869e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -11,8 +11,8 @@
 
 int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 			    struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
-void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
+void mtk_vcodec_enc_clock_on(struct mtk_vcodec_dev *dev, int core_id);
+void mtk_vcodec_enc_clock_off(struct mtk_vcodec_dev *dev, int core_id);
 
 int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev);
 int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev);
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index ce0bce811615..6cbdb7e30bb3 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -32,9 +32,7 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	}
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->init(ctx);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -46,9 +44,7 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 	int ret = 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	return ret;
@@ -68,10 +64,10 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 	ctx->dev->curr_ctx = ctx;
 	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_on(ctx->dev, 0);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
+	mtk_vcodec_enc_clock_off(ctx->dev, 0);
 
 	spin_lock_irqsave(&ctx->dev->irqlock, flags);
 	ctx->dev->curr_ctx = NULL;
@@ -89,9 +85,7 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 		return 0;
 
 	mtk_venc_lock(ctx);
-	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_vcodec_enc_clock_off(&ctx->dev->pm);
 	mtk_venc_unlock(ctx);
 
 	ctx->drv_handle = NULL;
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:13 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:13 +0800
Subject: [PATCH v2,
 08/10] media: mtk-vcodec: Add more extra processing for dual-core mode
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-9-irui.wang@mediatek.com>

Dual core mode encoding need more venc working buffers, it
will break the compatibility if we just add venc_vsi in AP-Kernel
but not in firmware, so add more struct definition for it.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_util.c     |  19 ++
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |   4 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 178 +++++++++++++++---
 4 files changed, 177 insertions(+), 25 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 9e4e4290a69a..dc036279c42f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -452,6 +452,7 @@ struct mtk_vcodec_enc_pdata {
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
+#define MTK_ENC_CORE_MODE(ctx) ((ctx)->dev->venc_pdata->core_mode)
 
 /**
  * struct mtk_vcodec_dev - driver data
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
index ace78c4b5b9e..059f665afa96 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.c
@@ -11,6 +11,7 @@
 
 #include "mtk_vcodec_dec_hw.h"
 #include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_util.h"
 
 void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
@@ -26,6 +27,24 @@ void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 }
 EXPORT_SYMBOL(mtk_vcodec_get_reg_addr);
 
+void __iomem *mtk_venc_get_core_reg_addr(struct mtk_vcodec_ctx *ctx,
+					 unsigned int core_id)
+{
+	struct mtk_venc_core_dev *core;
+
+	if (core_id >= MTK_VENC_CORE_MAX) {
+		mtk_v4l2_err("Invalid core_id = %d", core_id);
+		return NULL;
+	}
+
+	core = (struct mtk_venc_core_dev *)ctx->dev->enc_core_dev[core_id];
+	if (!core)
+		return NULL;
+
+	return core->reg_base;
+}
+EXPORT_SYMBOL(mtk_venc_get_core_reg_addr);
+
 int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 			struct mtk_vcodec_mem *mem)
 {
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index 71956627a0e2..de9e18688842 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -50,6 +50,10 @@ struct mtk_vcodec_dev;
 
 void __iomem *mtk_vcodec_get_reg_addr(struct mtk_vcodec_ctx *data,
 				unsigned int reg_idx);
+
+void __iomem *mtk_venc_get_core_reg_addr(struct mtk_vcodec_ctx *data,
+					 unsigned int core_id);
+
 int mtk_vcodec_mem_alloc(struct mtk_vcodec_ctx *data,
 				struct mtk_vcodec_mem *mem);
 void mtk_vcodec_mem_free(struct mtk_vcodec_ctx *data,
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index 4d9b8798dffe..023b6eb8b20c 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -50,6 +50,24 @@ enum venc_h264_vpu_work_buf {
 	VENC_H264_VPU_WORK_BUF_MAX,
 };
 
+/*
+ * enum venc_dual_core_work_buf - h264 dual core encoder buffer index
+ */
+enum venc_dual_core_work_buf {
+	VENC_DUAL_CORE_WORK_BUF_RC_INFO_CORE0,
+	VENC_DUAL_CORE_WORK_BUF_RC_CODE,
+	VENC_DUAL_CORE_WORK_BUF_REC_LUMA,
+	VENC_DUAL_CORE_WORK_BUF_REC_CHROMA,
+	VENC_DUAL_CORE_WORK_BUF_REF_LUMA,
+	VENC_DUAL_CORE_WORK_BUF_REF_CHROMA,
+	VENC_DUAL_CORE_WORK_BUF_MV_INFO_1,
+	VENC_DUAL_CORE_WORK_BUF_MV_INFO_2,
+	VENC_DUAL_CORE_WORK_BUF_SKIP_FRAME,
+	VENC_DUAL_CORE_WORK_BUF_RC_INFO_CORE1,
+	VENC_DUAL_CORE_WORK_BUF_FR_RC_INFO,
+	VENC_DUAL_CORE_WORK_BUF_MAX,
+};
+
 /*
  * enum venc_h264_bs_mode - for bs_mode argument in h264_enc_vpu_encode
  */
@@ -94,6 +112,24 @@ struct venc_h264_vpu_config {
 	u32 wfd;
 };
 
+struct venc_dual_core_config {
+	u32 input_fourcc;
+	u32 bitrate;
+	u32 pic_w;
+	u32 pic_h;
+	u32 buf_w;
+	u32 buf_h;
+	u32 gop_size;
+	u32 intra_period;
+	u32 framerate;
+	u32 profile;
+	u32 level;
+	u32 wfd;
+	u32 max_qp;
+	u32 min_qp;
+	u32 reserved[8];
+};
+
 /*
  * struct venc_h264_vpu_buf - Structure for buffer information
  *                            AP-W/R : AP is writer/reader on this item
@@ -127,6 +163,11 @@ struct venc_h264_vsi {
 	struct venc_h264_vpu_buf work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
 };
 
+struct venc_dual_core_vsi {
+	struct venc_dual_core_config config;
+	struct venc_h264_vpu_buf work_bufs[VENC_DUAL_CORE_WORK_BUF_MAX];
+};
+
 /*
  * struct venc_h264_inst - h264 encoder AP driver instance
  * @hw_base: h264 encoder hardware register base
@@ -143,8 +184,8 @@ struct venc_h264_vsi {
  * @ctx: context for v4l2 layer integration
  */
 struct venc_h264_inst {
-	void __iomem *hw_base;
-	struct mtk_vcodec_mem work_bufs[VENC_H264_VPU_WORK_BUF_MAX];
+	void __iomem *hw_base[MTK_VENC_CORE_MAX];
+	struct mtk_vcodec_mem work_bufs[VENC_DUAL_CORE_WORK_BUF_MAX];
 	struct mtk_vcodec_mem pps_buf;
 	bool work_buf_allocated;
 	unsigned int frm_cnt;
@@ -152,12 +193,13 @@ struct venc_h264_inst {
 	unsigned int prepend_hdr;
 	struct venc_vpu_inst vpu_inst;
 	struct venc_h264_vsi *vsi;
+	struct venc_dual_core_vsi *core_vsi;
 	struct mtk_vcodec_ctx *ctx;
 };
 
 static inline u32 h264_read_reg(struct venc_h264_inst *inst, u32 addr)
 {
-	return readl(inst->hw_base + addr);
+	return readl(inst->hw_base[MTK_VENC_CORE0] + addr);
 }
 
 static unsigned int h264_get_profile(struct venc_h264_inst *inst,
@@ -228,13 +270,21 @@ static unsigned int h264_get_level(struct venc_h264_inst *inst,
 static void h264_enc_free_work_buf(struct venc_h264_inst *inst)
 {
 	int i;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	int max_work_buf;
+	bool is_dual_core = (MTK_ENC_CORE_MODE(ctx) == VENC_DUAL_CORE_MODE);
 
 	mtk_vcodec_debug_enter(inst);
 
+	if (is_dual_core)
+		max_work_buf = VENC_DUAL_CORE_WORK_BUF_MAX;
+	else
+		max_work_buf = VENC_H264_VPU_WORK_BUF_MAX;
+
 	/* Except the SKIP_FRAME buffers,
 	 * other buffers need to be freed by AP.
 	 */
-	for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
+	for (i = 0; i < max_work_buf; i++) {
 		if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
 			mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
 	}
@@ -248,11 +298,22 @@ static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst)
 {
 	int i;
 	int ret = 0;
-	struct venc_h264_vpu_buf *wb = inst->vsi->work_bufs;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	struct venc_h264_vpu_buf *wb;
+	int max_work_buf;
+	bool is_dual_core = (MTK_ENC_CORE_MODE(ctx) == VENC_DUAL_CORE_MODE);
 
 	mtk_vcodec_debug_enter(inst);
 
-	for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
+	if (is_dual_core) {
+		wb = inst->core_vsi->work_bufs;
+		max_work_buf = VENC_DUAL_CORE_WORK_BUF_MAX;
+	} else {
+		wb = inst->vsi->work_bufs;
+		max_work_buf = VENC_H264_VPU_WORK_BUF_MAX;
+	}
+
+	for (i = 0; i < max_work_buf; i++) {
 		/*
 		 * This 'wb' structure is set by VPU side and shared to AP for
 		 * buffer allocation and IO virtual addr mapping. For most of
@@ -358,6 +419,26 @@ static int h264_frame_type(struct venc_h264_inst *inst)
 		return VENC_H264_P_FRM;  /* Note: B frames are not supported */
 	}
 }
+
+static int h264_core_frame_type(struct venc_h264_inst *inst)
+{
+	struct venc_dual_core_vsi *vsi = inst->core_vsi;
+
+	if ((vsi->config.gop_size != 0 &&
+	     (inst->frm_cnt % vsi->config.gop_size) == 0) ||
+	    (inst->frm_cnt == 0 && vsi->config.gop_size == 0)) {
+		/* IDR frame */
+		return VENC_H264_IDR_FRM;
+	} else if ((vsi->config.intra_period != 0 &&
+		    (inst->frm_cnt % vsi->config.intra_period) == 0) ||
+		   (inst->frm_cnt == 0 && vsi->config.intra_period == 0)) {
+		/* I frame */
+		return VENC_H264_I_FRM;
+	} else {
+		return VENC_H264_P_FRM;  /* Note: B frames are not supported */
+	}
+}
+
 static int h264_encode_sps(struct venc_h264_inst *inst,
 			   struct mtk_vcodec_mem *bs_buf,
 			   unsigned int *bs_size)
@@ -440,12 +521,18 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 	int ret = 0;
 	unsigned int irq_status;
 	struct venc_frame_info frame_info;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	bool is_dual_core = (MTK_ENC_CORE_MODE(ctx) == VENC_DUAL_CORE_MODE);
 
 	mtk_vcodec_debug_enter(inst);
 	mtk_vcodec_debug(inst, "frm_cnt = %d\n ", inst->frm_cnt);
 	frame_info.frm_count = inst->frm_cnt;
 	frame_info.skip_frm_count = inst->skip_frm_cnt;
-	frame_info.frm_type = h264_frame_type(inst);
+	if (is_dual_core)
+		frame_info.frm_type = h264_core_frame_type(inst);
+	else
+		frame_info.frm_type = h264_frame_type(inst);
+
 	mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
@@ -501,7 +588,8 @@ static void h264_encode_filler(struct venc_h264_inst *inst, void *buf,
 static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
 {
 	const bool is_ext = MTK_ENC_CTX_IS_EXT(ctx);
-	int ret = 0;
+	bool is_dual_core = (MTK_ENC_CORE_MODE(ctx) == VENC_DUAL_CORE_MODE);
+	int ret, i = 0;
 	struct venc_h264_inst *inst;
 
 	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
@@ -511,13 +599,22 @@ static int h264_enc_init(struct mtk_vcodec_ctx *ctx)
 	inst->ctx = ctx;
 	inst->vpu_inst.ctx = ctx;
 	inst->vpu_inst.id = is_ext ? SCP_IPI_VENC_H264 : IPI_VENC_H264;
-	inst->hw_base = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
 
 	mtk_vcodec_debug_enter(inst);
 
 	ret = vpu_enc_init(&inst->vpu_inst);
 
-	inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
+	if (is_dual_core) {
+		inst->core_vsi =
+			(struct venc_dual_core_vsi *)inst->vpu_inst.vsi;
+		for (i = 0; i < MTK_VENC_CORE_MAX; i++)
+			inst->hw_base[i] =
+				mtk_venc_get_core_reg_addr(inst->ctx, i);
+
+	} else {
+		inst->vsi = (struct venc_h264_vsi *)inst->vpu_inst.vsi;
+		inst->hw_base[0] = mtk_vcodec_get_reg_addr(inst->ctx, VENC_SYS);
+	}
 
 	mtk_vcodec_debug_leave(inst);
 
@@ -624,31 +721,62 @@ static int h264_enc_encode(void *handle,
 	return ret;
 }
 
+static void h264_enc_set_configs(struct venc_h264_inst *inst,
+				 struct venc_enc_param *enc_prm)
+{
+	inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+	inst->vsi->config.bitrate = enc_prm->bitrate;
+	inst->vsi->config.pic_w = enc_prm->width;
+	inst->vsi->config.pic_h = enc_prm->height;
+	inst->vsi->config.buf_w = enc_prm->buf_width;
+	inst->vsi->config.buf_h = enc_prm->buf_height;
+	inst->vsi->config.gop_size = enc_prm->gop_size;
+	inst->vsi->config.framerate = enc_prm->frm_rate;
+	inst->vsi->config.intra_period = enc_prm->intra_period;
+	inst->vsi->config.profile =
+		h264_get_profile(inst, enc_prm->h264_profile);
+	inst->vsi->config.level =
+		h264_get_level(inst, enc_prm->h264_level);
+	inst->vsi->config.wfd = 0;
+}
+
+static void h264_enc_set_core_configs(struct venc_h264_inst *inst,
+				      struct venc_enc_param *enc_prm)
+{
+	inst->core_vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
+	inst->core_vsi->config.bitrate = enc_prm->bitrate;
+	inst->core_vsi->config.pic_w = enc_prm->width;
+	inst->core_vsi->config.pic_h = enc_prm->height;
+	inst->core_vsi->config.buf_w = enc_prm->buf_width;
+	inst->core_vsi->config.buf_h = enc_prm->buf_height;
+	inst->core_vsi->config.gop_size = enc_prm->gop_size;
+	inst->core_vsi->config.framerate = enc_prm->frm_rate;
+	inst->core_vsi->config.intra_period = enc_prm->intra_period;
+	inst->core_vsi->config.profile =
+		h264_get_profile(inst, enc_prm->h264_profile);
+	inst->core_vsi->config.level =
+		h264_get_level(inst, enc_prm->h264_level);
+	inst->core_vsi->config.wfd = 0;
+}
+
 static int h264_enc_set_param(void *handle,
 			      enum venc_set_param_type type,
 			      struct venc_enc_param *enc_prm)
 {
 	int ret = 0;
 	struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	bool is_dual_core = (MTK_ENC_CORE_MODE(ctx) == VENC_DUAL_CORE_MODE);
 
-	mtk_vcodec_debug(inst, "->type=%d", type);
+	mtk_vcodec_debug(inst, "->type=%d, dual_core=%d", type, is_dual_core);
 
 	switch (type) {
 	case VENC_SET_PARAM_ENC:
-		inst->vsi->config.input_fourcc = enc_prm->input_yuv_fmt;
-		inst->vsi->config.bitrate = enc_prm->bitrate;
-		inst->vsi->config.pic_w = enc_prm->width;
-		inst->vsi->config.pic_h = enc_prm->height;
-		inst->vsi->config.buf_w = enc_prm->buf_width;
-		inst->vsi->config.buf_h = enc_prm->buf_height;
-		inst->vsi->config.gop_size = enc_prm->gop_size;
-		inst->vsi->config.framerate = enc_prm->frm_rate;
-		inst->vsi->config.intra_period = enc_prm->intra_period;
-		inst->vsi->config.profile =
-			h264_get_profile(inst, enc_prm->h264_profile);
-		inst->vsi->config.level =
-			h264_get_level(inst, enc_prm->h264_level);
-		inst->vsi->config.wfd = 0;
+		if (is_dual_core)
+			h264_enc_set_core_configs(inst, enc_prm);
+		else
+			h264_enc_set_configs(inst, enc_prm);
+
 		ret = vpu_enc_set_param(&inst->vpu_inst, type, enc_prm);
 		if (ret)
 			break;
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:08 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:08 +0800
Subject: [PATCH v2,
 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings
 for mt8195
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-4-irui.wang@mediatek.com>

Adds encoder cores dt-bindings for mt8195

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../media/mediatek,vcodec-encoder-core.yaml   | 214 ++++++++++++++++++
 1 file changed, 214 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
new file mode 100644
index 000000000000..d1e7bfa50bce
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
@@ -0,0 +1,214 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Mediatek Video Encoder Accelerator With Multi Core
+
+maintainers:
+  - Irui Wang <irui.wang at mediatek.com>
+
+description: |
+  Mediatek Video Encode is the video encode hardware present in Mediatek
+  SoCs which supports high resolution encoding functionalities. Required
+  parent and child device node.
+
+properties:
+  compatible:
+    const: mediatek,mt8195-vcodec-enc
+
+  mediatek,scp:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    maxItems: 1
+    description: |
+      The node of system control processor (SCP), using
+      the remoteproc & rpmsg framework.
+
+  iommus:
+    minItems: 1
+    maxItems: 32
+    description: |
+      List of the hardware port in respective IOMMU block for current Socs.
+      Refer to bindings/iommu/mediatek,iommu.yaml.
+
+  dma-ranges:
+    maxItems: 1
+    description: |
+      Describes the physical address space of IOMMU maps to memory.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+# Required child node:
+patternProperties:
+  "venc_core0 at 1a020000":
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-venc-core0
+
+      reg:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      clock-names:
+        items:
+          - const: MT_CG_VENC0
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - iommus
+      - interrupts
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+  "venc_core1 at 1b020000":
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-venc-core1
+
+      reg:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        maxItems: 1
+
+      clock-names:
+        items:
+          - const: MT_CG_VENC1
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - iommus
+      - interrupts
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - mediatek,scp
+  - iommus
+  - dma-ranges
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/memory/mt8195-memory-port.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mt8195-clk.h>
+    #include <dt-bindings/power/mt8195-power.h>
+
+    venc {
+        compatible = "mediatek,mt8195-vcodec-enc";
+        mediatek,scp = <&scp>;
+        iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>;
+        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        venc_core0 at 1a020000 {
+            compatible = "mediatek,mtk-venc-core0";
+            reg = <0x1a020000 0x10000>;
+            iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_REC>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_BSDMA>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_SV_COMV>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_RD_COMV>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_CUR_LUMA>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_CUR_CHROMA>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
+                     <&iommu_vdo M4U_PORT_L19_VENC_REF_CHROMA>;
+            interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
+            clocks = <&vencsys CLK_VENC_VENC>;
+            clock-names = "MT_CG_VENC0";
+            assigned-clocks = <&topckgen CLK_TOP_VENC>;
+            assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
+            power-domains = <&spm MT8195_POWER_DOMAIN_VENC>;
+        };
+
+        venc_core1 at 1b020000 {
+            compatible = "mediatek,mtk-venc-core1";
+            reg = <0x1b020000 0x10000>;
+            iommus = <&iommu_vpp M4U_PORT_L20_VENC_RCPU>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_REC>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_BSDMA>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_SV_COMV>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_RD_COMV>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_CUR_LUMA>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_CUR_CHROMA>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_REF_LUMA>,
+                     <&iommu_vpp M4U_PORT_L20_VENC_REF_CHROMA>;
+            interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH 0>;
+            clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>;
+            clock-names = "MT_CG_VENC1";
+            assigned-clocks = <&topckgen CLK_TOP_VENC>;
+            assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
+            power-domains = <&spm MT8195_POWER_DOMAIN_VENC_CORE1>;
+        };
+    };
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:11 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:11 +0800
Subject: [PATCH v2, 06/10] media: mtk-vcodec: Add venc power on/off interface
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-7-irui.wang@mediatek.com>

Dual-core mode power on/off all venc available power, pm_runtime_xx
helper is not appropriate called directly, add new power on/off
interface for it.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 20 +----
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  7 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 83 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_pm.h   |  5 ++
 4 files changed, 98 insertions(+), 17 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index 134dc53e4855..df231e67cdb2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -13,6 +13,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_intr.h"
 #include "mtk_vcodec_util.h"
 #include "venc_drv_if.h"
@@ -850,7 +851,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 {
 	struct mtk_vcodec_ctx *ctx = vb2_get_drv_priv(q);
 	struct venc_enc_param param;
-	int ret, pm_ret;
+	int ret;
 	int i;
 
 	/* Once state turn into MTK_STATE_ABORT, we need stop_streaming
@@ -858,7 +859,7 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	  */
 	if ((ctx->state == MTK_STATE_ABORT) || (ctx->state == MTK_STATE_FREE)) {
 		ret = -EIO;
-		goto err_start_stream;
+		goto err_set_param;
 	}
 
 	/* Do the initialization when both start_streaming have been called */
@@ -870,12 +871,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 			return 0;
 	}
 
-	ret = pm_runtime_resume_and_get(&ctx->dev->plat_dev->dev);
-	if (ret < 0) {
-		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
-		goto err_start_stream;
-	}
-
 	mtk_venc_set_param(ctx, &param);
 	ret = venc_if_set_param(ctx, VENC_SET_PARAM_ENC, &param);
 	if (ret) {
@@ -902,11 +897,6 @@ static int vb2ops_venc_start_streaming(struct vb2_queue *q, unsigned int count)
 	return 0;
 
 err_set_param:
-	pm_ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (pm_ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", pm_ret);
-
-err_start_stream:
 	for (i = 0; i < q->num_buffers; ++i) {
 		struct vb2_buffer *buf = vb2_get_buffer(q, i);
 
@@ -989,10 +979,6 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 	if (ret)
 		mtk_v4l2_err("venc_if_deinit failed=%d", ret);
 
-	ret = pm_runtime_put(&ctx->dev->plat_dev->dev);
-	if (ret < 0)
-		mtk_v4l2_err("pm_runtime_put fail %d", ret);
-
 	ctx->state = MTK_STATE_FREE;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index a601d534d26b..cef134bb6e83 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -174,6 +174,12 @@ static int fops_vcodec_open(struct file *file)
 		mtk_v4l2_debug(0, "encoder capability %x", dev->enc_capability);
 	}
 
+	ret = mtk_vcodec_enc_pw_on(dev);
+	if (ret < 0) {
+		mtk_v4l2_err("encoder power on failed %d", ret);
+		goto err_load_fw;
+	}
+
 	mtk_v4l2_debug(2, "Create instance [%d]@%p m2m_ctx=%p ",
 			ctx->id, ctx, ctx->m2m_ctx);
 
@@ -208,6 +214,7 @@ static int fops_vcodec_release(struct file *file)
 
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_enc_release(ctx);
+	mtk_vcodec_enc_pw_off(dev);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index c8a7042d7830..dfaef884e6e3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -10,6 +10,7 @@
 #include <linux/pm_runtime.h>
 #include <soc/mediatek/smi.h>
 
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
@@ -119,3 +120,85 @@ void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm)
 		clk_disable_unprepare(enc_clk->clk_info[i].vcodec_clk);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_enc_clock_off);
+
+int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev)
+{
+	int i, ret;
+	struct mtk_venc_core_dev *core;
+
+	/* power on all available venc cores */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		if (!core)
+			return 0;
+
+		ret = pm_runtime_resume_and_get(&core->plat_dev->dev);
+		if (ret < 0) {
+			mtk_v4l2_err("power on core[%d] fail %d", i, ret);
+			goto pw_on_fail;
+		}
+	}
+	return 0;
+
+pw_on_fail:
+	for (i -= 1; i >= 0; i--) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		pm_runtime_put_sync(&core->plat_dev->dev);
+	}
+	return ret;
+}
+
+int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev)
+{
+	int i, ret;
+	struct mtk_venc_core_dev *core;
+
+	/* power off all available venc cores */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		core = (struct mtk_venc_core_dev *)dev->enc_core_dev[i];
+		if (!core)
+			return 0;
+
+		ret = pm_runtime_put_sync(&core->plat_dev->dev);
+		if (ret < 0)
+			mtk_v4l2_err("power off core[%d] fail %d", i, ret);
+	}
+	return ret;
+}
+
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_dev *dev)
+{
+	int ret;
+
+	if (dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		ret = mtk_venc_core_pw_on(dev);
+		if (ret < 0) {
+			mtk_v4l2_err("venc core power on fail: %d", ret);
+			return ret;
+		}
+	} else {
+		ret = pm_runtime_resume_and_get(&dev->plat_dev->dev);
+		if (ret < 0) {
+			mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
+			return ret;
+		}
+	}
+	return 0;
+}
+
+int mtk_vcodec_enc_pw_off(struct mtk_vcodec_dev *dev)
+{
+	int ret;
+
+	if (dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		ret = mtk_venc_core_pw_off(dev);
+		if (ret < 0)
+			mtk_v4l2_err("venc core power off fail: %d", ret);
+
+	} else {
+		ret = pm_runtime_put_sync(&dev->plat_dev->dev);
+		if (ret < 0)
+			mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
+	}
+	return ret;
+}
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index 97a394c68f4e..99b6b6e29e35 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -14,4 +14,9 @@ int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
 
+int mtk_venc_core_pw_on(struct mtk_vcodec_dev *dev);
+int mtk_venc_core_pw_off(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_dev *dev);
+int mtk_vcodec_enc_pw_off(struct mtk_vcodec_dev *dev);
+
 #endif /* _MTK_VCODEC_ENC_PM_H_ */
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:06 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:06 +0800
Subject: [PATCH v2,
 01/10] media: mtk-vcodec: Use core type to indicate h264 and vp8 enc
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-2-irui.wang@mediatek.com>

use core type variables to indicate h264 and vp8 encoder

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +--
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 30 ++++++++++---------
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cd2939b47790..f78463ff4551 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -419,7 +419,7 @@ struct mtk_vcodec_dec_pdata {
  * @num_capture_formats: number of entries in capture_formats
  * @output_formats: array of supported output formats
  * @num_output_formats: number of entries in output_formats
- * @core_id: stand for h264 or vp8 encode index
+ * @core_type: stand for h264 or vp8 encode
  */
 struct mtk_vcodec_enc_pdata {
 	bool uses_ext;
@@ -429,7 +429,7 @@ struct mtk_vcodec_enc_pdata {
 	size_t num_capture_formats;
 	const struct mtk_video_fmt *output_formats;
 	size_t num_output_formats;
-	int core_id;
+	int core_type;
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 3ac6969c54c0..1f950310a3fb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -95,11 +95,13 @@ static irqreturn_t mtk_vcodec_enc_irq_handler(int irq, void *priv)
 	ctx = dev->curr_ctx;
 	spin_unlock_irqrestore(&dev->irqlock, flags);
 
-	mtk_v4l2_debug(1, "id=%d coreid:%d", ctx->id, dev->venc_pdata->core_id);
-	addr = dev->reg_base[dev->venc_pdata->core_id] +
+	mtk_v4l2_debug(1, "id: %d core type: %d",
+		       ctx->id, dev->venc_pdata->core_type);
+
+	addr = dev->reg_base[dev->venc_pdata->core_type] +
 				MTK_VENC_IRQ_ACK_OFFSET;
 
-	ctx->irq_status = readl(dev->reg_base[dev->venc_pdata->core_id] +
+	ctx->irq_status = readl(dev->reg_base[dev->venc_pdata->core_type] +
 				(MTK_VENC_IRQ_STATUS_OFFSET));
 
 	clean_irq_status(ctx->irq_status, addr);
@@ -266,10 +268,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 	pm_runtime_enable(&pdev->dev);
 
-	dev->reg_base[dev->venc_pdata->core_id] =
+	dev->reg_base[dev->venc_pdata->core_type] =
 		devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_id])) {
-		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_id]);
+	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_type])) {
+		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_type]);
 		goto err_res;
 	}
 
@@ -287,8 +289,8 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 			       0, pdev->name, dev);
 	if (ret) {
 		dev_err(&pdev->dev,
-			"Failed to install dev->enc_irq %d (%d) core_id (%d)",
-			dev->enc_irq, ret, dev->venc_pdata->core_id);
+			"Failed to install dev->enc_irq %d (%d) core_type (%d)",
+			dev->enc_irq, ret, dev->venc_pdata->core_type);
 		ret = -EINVAL;
 		goto err_res;
 	}
@@ -357,7 +359,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	}
 
 	mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
-		       dev->venc_pdata->core_id, vfd_enc->num);
+		       dev->venc_pdata->core_type, vfd_enc->num);
 
 	return 0;
 
@@ -384,7 +386,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 60000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
@@ -394,7 +396,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 9000000,
-	.core_id = VENC_LT_SYS,
+	.core_type = VENC_LT_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
@@ -405,7 +407,7 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 40000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
@@ -416,7 +418,7 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
@@ -427,7 +429,7 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
 	.num_output_formats = ARRAY_SIZE(mtk_video_formats_output),
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
-	.core_id = VENC_SYS,
+	.core_type = VENC_SYS,
 };
 
 static const struct of_device_id mtk_vcodec_enc_match[] = {
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:10 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:10 +0800
Subject: [PATCH v2,
 05/10] media: mtk-vcodec: mtk-vcodec: Rewrite venc power manage
 interface
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-6-irui.wang@mediatek.com>

The args "struct mtk_vcodec_dev *" doesn't appropriate for init_clk
functions because of sub-devices. For main device, it has no "pm/clk"
properties in dtsi, sub-devices will init their own "pm/clk" instead.
So rewrite the pm interface with args "platform_device *" and
"mtk_vcodec_pm*".

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c | 9 +++++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c  | 2 +-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c   | 9 ++-------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h   | 4 ++--
 4 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
index d84914f615a5..3835b9f458bf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -13,6 +13,7 @@
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_enc.h"
 #include "mtk_vcodec_enc_core.h"
+#include "mtk_vcodec_enc_pm.h"
 
 static const struct of_device_id mtk_venc_core_ids[] = {
 	{
@@ -95,6 +96,13 @@ static int mtk_venc_core_probe(struct platform_device *pdev)
 
 	core->plat_dev = pdev;
 
+	ret = mtk_vcodec_init_enc_clk(core->plat_dev, &core->pm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to get venc core clock source!");
+		return ret;
+	}
+	pm_runtime_enable(&pdev->dev);
+
 	core->reg_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(core->reg_base)) {
 		dev_err(&pdev->dev, "Failed to get reg base");
@@ -137,6 +145,7 @@ static int mtk_venc_core_probe(struct platform_device *pdev)
 	return 0;
 
 err:
+	pm_runtime_disable(core->pm.dev);
 	return ret;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 9d48c604bc54..a601d534d26b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -262,7 +262,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	core_type = dev->venc_pdata->core_type;
 
 	if (dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE) {
-		ret = mtk_vcodec_init_enc_clk(dev);
+		ret = mtk_vcodec_init_enc_clk(dev->plat_dev, &dev->pm);
 		if (ret < 0) {
 			dev_err(&pdev->dev,
 				"Failed to get mtk vcodec clock source!");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
index 7eba1a990ed7..c8a7042d7830 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c
@@ -13,19 +13,15 @@
 #include "mtk_vcodec_enc_pm.h"
 #include "mtk_vcodec_util.h"
 
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
+int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
+			    struct mtk_vcodec_pm *pm)
 {
 	struct device_node *node;
-	struct platform_device *pdev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *enc_clk;
 	struct mtk_vcodec_clk_info *clk_info;
 	int ret = 0, i = 0;
 	struct device *dev;
 
-	pdev = mtkdev->plat_dev;
-	pm = &mtkdev->pm;
-	memset(pm, 0, sizeof(struct mtk_vcodec_pm));
 	pm->dev = &pdev->dev;
 	dev = &pdev->dev;
 	enc_clk = &pm->venc_clk;
@@ -42,7 +38,6 @@ int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *mtkdev)
 		return -ENODEV;
 	}
 	pm->larbvenc = &pdev->dev;
-	pdev = mtkdev->plat_dev;
 	pm->dev = &pdev->dev;
 
 	enc_clk->clk_num = of_property_count_strings(pdev->dev.of_node,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
index bc455cefc0cd..97a394c68f4e 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.h
@@ -9,8 +9,8 @@
 
 #include "mtk_vcodec_drv.h"
 
-int mtk_vcodec_init_enc_clk(struct mtk_vcodec_dev *dev);
-
+int mtk_vcodec_init_enc_clk(struct platform_device *pdev,
+			    struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
 
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:15 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:15 +0800
Subject: [PATCH v2, 10/10] media: mtk-vcodec: Done encode result to client
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-11-irui.wang@mediatek.com>

When enable dual core mode encoding, the wait IRQ done synchronous
function should not be called, so the encode result can't return
to client in device_run. device_run called to trigger encoding
process, finish it, so another scheduled job can be ran. When
encoding done, done the encode result to client in IRQ handler.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  6 ++
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 64 ++++++++++++++++++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  3 +
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 27 +++++++-
 .../platform/mtk-vcodec/mtk_vcodec_util.h     |  1 +
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 22 ++++++-
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  2 +
 7 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index c3cf5904b4c6..5faeffd397db 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -311,6 +311,9 @@ struct vdec_pic_info {
  * @q_mutex: src & dst vb2_queue mutex
  * @enc_idx: used to record encoded frame count
  * @core_id: used to reoord used core
+ * @pfrm_buf: used to store current ctx's frame buffer
+ * @pbs_buf: used to store current ctx's bitstream buffer
+ * @hdr_size: used to store prepend header size
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -363,6 +366,9 @@ struct mtk_vcodec_ctx {
 	struct mutex q_mutex;
 	int enc_idx;
 	int core_id;
+	struct vb2_v4l2_buffer *pfrm_buf[MTK_VENC_CORE_MAX];
+	struct vb2_v4l2_buffer *pbs_buf[MTK_VENC_CORE_MAX];
+	unsigned int hdr_size;
 };
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index dc70d328fcd3..3056cbc4b3a3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -924,6 +924,8 @@ static void vb2ops_venc_stop_streaming(struct vb2_queue *q)
 
 	mtk_v4l2_debug(2, "[%d]-> type=%d", ctx->id, q->type);
 
+	mtk_venc_lock_all(ctx);
+
 	if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
 		while ((dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx))) {
 			vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
@@ -1103,10 +1105,13 @@ static int mtk_venc_param_change(struct mtk_vcodec_ctx *ctx)
 				ctx->id,
 				vb2_v4l2->vb2_buf.index,
 				mtk_buf->enc_params.force_intra);
-		if (mtk_buf->enc_params.force_intra)
+		if (mtk_buf->enc_params.force_intra) {
 			ret |= venc_if_set_param(ctx,
 						 VENC_SET_PARAM_FORCE_INTRA,
 						 NULL);
+
+			ctx->enc_idx = 0;
+		}
 	}
 
 	mtk_buf->param_change = MTK_ENCODE_PARAM_NONE;
@@ -1157,6 +1162,7 @@ static void mtk_venc_worker(struct work_struct *work)
 	 * is dequeued.
 	 */
 	if (src_buf == &ctx->empty_flush_buf.vb) {
+		mtk_venc_lock_all(ctx);
 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
 		dst_buf->flags |= V4L2_BUF_FLAG_LAST;
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
@@ -1171,9 +1177,12 @@ static void mtk_venc_worker(struct work_struct *work)
 		frm_buf.fb_addr[i].size =
 				(size_t)src_buf->vb2_buf.planes[i].length;
 	}
+	frm_buf.src_addr = src_buf;
+
 	bs_buf.va = vb2_plane_vaddr(&dst_buf->vb2_buf, 0);
 	bs_buf.dma_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
 	bs_buf.size = (size_t)dst_buf->vb2_buf.planes[0].length;
+	bs_buf.buf = dst_buf;
 
 	mtk_v4l2_debug(2,
 			"Framebuf PA=%llx Size=0x%zx;PA=0x%llx Size=0x%zx;PA=0x%llx Size=%zu",
@@ -1220,6 +1229,8 @@ static void m2mops_venc_device_run(void *priv)
 {
 	struct mtk_vcodec_ctx *ctx = priv;
 
+	mtk_venc_param_change(ctx);
+
 	if ((ctx->q_data[MTK_Q_DATA_DST].fmt->fourcc == V4L2_PIX_FMT_H264) &&
 	    (ctx->state != MTK_STATE_HEADER)) {
 		/* encode h264 sps/pps header */
@@ -1228,7 +1239,6 @@ static void m2mops_venc_device_run(void *priv)
 		return;
 	}
 
-	mtk_venc_param_change(ctx);
 	queue_work(ctx->dev->encode_workqueue, &ctx->encode_work);
 }
 
@@ -1414,6 +1424,34 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	return vb2_queue_init(dst_vq);
 }
 
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame)
+{
+	struct vb2_v4l2_buffer *src_vb2_v4l2 = NULL;
+	struct vb2_v4l2_buffer *dst_vb2_v4l2 = NULL;
+
+	/*
+	 * the frm_buf(src_buf) and bs_buf(dst_buf) can be obtained from ctx,
+	 * then put them to done list, user can get them by dqbuf call
+	 */
+	src_vb2_v4l2 = ctx->pfrm_buf[core_id];
+	dst_vb2_v4l2 = ctx->pbs_buf[core_id];
+
+	if (src_vb2_v4l2 && dst_vb2_v4l2) {
+		dst_vb2_v4l2->vb2_buf.timestamp =
+			src_vb2_v4l2->vb2_buf.timestamp;
+		dst_vb2_v4l2->timecode = src_vb2_v4l2->timecode;
+
+		if (key_frame)
+			dst_vb2_v4l2->flags |= V4L2_BUF_FLAG_KEYFRAME;
+
+		v4l2_m2m_buf_done(src_vb2_v4l2, VB2_BUF_STATE_DONE);
+		vb2_set_plane_payload(&dst_vb2_v4l2->vb2_buf, 0, bs_size);
+		v4l2_m2m_buf_done(dst_vb2_v4l2, VB2_BUF_STATE_DONE);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_venc_buf_done);
+
 int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
@@ -1441,3 +1479,25 @@ void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx)
 
 	ctx->state = MTK_STATE_FREE;
 }
+
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx)
+{
+	unsigned int i;
+	struct mtk_vcodec_dev *dev = ctx->dev;
+
+	/*
+	 * For frame-racing mode encoding, there are may be bufs being encoded
+	 * when get the empty flush buffer or stop streaming, for example, the
+	 * buffer with LAST flag will return to client before the encoding
+	 * buffers, which will cause frame lost.
+	 * The encoder device mutex will be locked during encoding process,
+	 * when encode done, the mutex unlocked. So if all encoder device mutex
+	 * can be locked, which means there are no bufs being encoded at this
+	 * time, then the buffer with LAST flag can return to client properly.
+	 */
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++) {
+		mutex_lock(&dev->enc_mutex[i]);
+		mutex_unlock(&dev->enc_mutex[i]);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_venc_lock_all);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 434d91d36158..1e22c77a2760 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -46,5 +46,8 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
 int mtk_vcodec_enc_ctrls_setup(struct mtk_vcodec_ctx *ctx);
 void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx);
+void mtk_venc_buf_done(struct mtk_vcodec_ctx *ctx, int core_id,
+		       unsigned int bs_size, bool time_out, bool key_frame);
+void mtk_venc_lock_all(struct mtk_vcodec_ctx *ctx);
 
 #endif /* _MTK_VCODEC_ENC_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
index 3835b9f458bf..6140b9bd4dd0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -14,6 +14,11 @@
 #include "mtk_vcodec_enc.h"
 #include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_enc_pm.h"
+#include "mtk_vcodec_intr.h"
+
+#define VENC_PIC_BITSTREAM_BYTE_CNT 0x0098
+#define VENC_PIC_FRM_TYPE	0x0010
+#define VENC_PIC_KEY_FRM	0x2
 
 static const struct of_device_id mtk_venc_core_ids[] = {
 	{
@@ -47,6 +52,7 @@ static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
 
 	if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
 		writel(MTK_VENC_IRQ_STATUS_FRM, addr);
+
 }
 
 static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
@@ -55,6 +61,9 @@ static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
 	struct mtk_vcodec_ctx *ctx;
 	unsigned long flags;
 	void __iomem *addr;
+	unsigned int bs_size;
+	unsigned int frm_type;
+	bool is_key_frame = 0;
 
 	spin_lock_irqsave(&core->main_dev->irqlock, flags);
 	ctx = core->curr_ctx;
@@ -66,9 +75,25 @@ static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
 
 	addr = core->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
 	ctx->irq_status = readl(core->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	bs_size = readl(core->reg_base + VENC_PIC_BITSTREAM_BYTE_CNT);
+	frm_type = readl(core->reg_base + VENC_PIC_FRM_TYPE);
 	clean_irq_status(ctx->irq_status, addr);
 
-	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	if (ctx->irq_status & MTK_VENC_IRQ_STATUS_FRM) {
+		if (ctx->hdr_size != 0) {
+			bs_size += ctx->hdr_size;
+			ctx->hdr_size = 0;
+		}
+		if (frm_type & VENC_PIC_KEY_FRM)
+			is_key_frame = 1;
+
+		mtk_venc_buf_done(ctx, core->core_id, bs_size, 0, is_key_frame);
+		mtk_vcodec_enc_clock_off(core->main_dev, core->core_id);
+		mtk_venc_unlock(ctx, core->core_id);
+	} else {
+		wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	}
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
index de9e18688842..4436d8bc60a0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_util.h
@@ -15,6 +15,7 @@ struct mtk_vcodec_mem {
 	size_t size;
 	void *va;
 	dma_addr_t dma_addr;
+	void *buf;
 };
 
 struct mtk_vcodec_fb {
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index fdecf1d24b25..733dbf431aae 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -558,6 +558,12 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 		return ret;
 	}
 
+	if (is_dual_core) {
+		++inst->frm_cnt;
+		mtk_vcodec_debug(inst, "dual core : frm %d <-", inst->frm_cnt);
+		return ret;
+	}
+
 	irq_status = h264_enc_wait_venc_done(inst);
 	if (irq_status != MTK_VENC_IRQ_STATUS_FRM) {
 		mtk_vcodec_err(inst, "irq_status=%d failed", irq_status);
@@ -639,10 +645,12 @@ static int h264_enc_encode(void *handle,
 	int ret = 0;
 	struct venc_h264_inst *inst = (struct venc_h264_inst *)handle;
 	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	bool is_single_core = (MTK_ENC_CORE_MODE(ctx) == VENC_SINGLE_CORE_MODE);
 
 	mtk_vcodec_debug(inst, "opt %d ->", opt);
 
-	enable_irq(ctx->dev->enc_irq);
+	if (is_single_core)
+		enable_irq(ctx->dev->enc_irq);
 
 	switch (opt) {
 	case VENC_START_OPT_ENCODE_SEQUENCE_HEADER: {
@@ -666,6 +674,13 @@ static int h264_enc_encode(void *handle,
 		unsigned int bs_size_hdr;
 		unsigned int bs_size_frm;
 
+		/*
+		 * the frm_buf and bs_buf need to be recorded into ctx,
+		 * when encoding done, the target buffer can be obtained
+		 */
+		ctx->pfrm_buf[ctx->core_id] = frm_buf->src_addr;
+		ctx->pbs_buf[ctx->core_id] = bs_buf->buf;
+
 		if (!inst->prepend_hdr) {
 			ret = h264_encode_frame(inst, frm_buf, bs_buf,
 						&result->bs_size, ctx->core_id);
@@ -702,6 +717,8 @@ static int h264_enc_encode(void *handle,
 
 		result->bs_size = hdr_sz + filler_sz + bs_size_frm;
 
+		ctx->hdr_size = hdr_sz + filler_sz;
+
 		mtk_vcodec_debug(inst, "hdr %d filler %d frame %d bs %d",
 				 hdr_sz, filler_sz, bs_size_frm,
 				 result->bs_size);
@@ -718,8 +735,9 @@ static int h264_enc_encode(void *handle,
 	}
 
 encode_err:
+	if (is_single_core)
+		disable_irq(ctx->dev->enc_irq);
 
-	disable_irq(ctx->dev->enc_irq);
 	mtk_vcodec_debug(inst, "opt %d <-", opt);
 
 	return ret;
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 15e9a2ab9cda..3ad31abb7290 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -108,9 +108,11 @@ struct venc_frame_info {
 /*
  * struct venc_frm_buf - frame buffer information used in venc_if_encode()
  * @fb_addr: plane frame buffer addresses
+ * @src_addr: vb2_v4l2_buffer src buffer address
  */
 struct venc_frm_buf {
 	struct mtk_vcodec_fb fb_addr[MTK_VCODEC_MAX_PLANES];
+	void *src_addr;
 };
 
 /*
-- 
2.18.0



From irui.wang at mediatek.com  Mon Jan 17 04:06:09 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:09 +0800
Subject: [PATCH v2, 04/10] media: mtk-vcodec: Enable venc dual core usage
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-5-irui.wang@mediatek.com>

Adds new venc core mode to indicate different venc hardware mode:
VENC_SINGLE_CORE_MODE means only one core, the device has its own
power/clk/irq, init_clk/request_irq helper can be used.

VENC_DUAL_CORE_MODE means more than one core inside, the core device
can use the init_clk/request_irq helper to initialize their own
power/clk/irq. And the main device doesn't need use these helper anymore.

MT8195 has two H264 venc cores, enable dual_core_mode for it.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  22 +++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.c | 153 ++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_core.h |  36 +++++
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  88 +++++-----
 5 files changed, 266 insertions(+), 37 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
 create mode 100644 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 93e7a343b5b0..c472b221bd6b 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -3,7 +3,8 @@
 obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 				       mtk-vcodec-enc.o \
 				       mtk-vcodec-common.o \
-				       mtk-vcodec-dec-hw.o
+				       mtk-vcodec-dec-hw.o \
+				       mtk-vcodec-enc-core.o
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
@@ -32,6 +33,7 @@ mtk-vcodec-enc-y := venc/venc_vp8_if.o \
 		venc_drv_if.o \
 		venc_vpu_if.o \
 
+mtk-vcodec-enc-core-y := mtk_vcodec_enc_core.o
 
 mtk-vcodec-common-y := mtk_vcodec_intr.o \
 		mtk_vcodec_util.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index f78463ff4551..9e4e4290a69a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -117,6 +117,23 @@ enum mtk_vdec_hw_count {
 	MTK_VDEC_MAX_HW_COUNT,
 };
 
+/*
+ * enum mtk_venc_core_id -- encoder core id
+ */
+enum mtk_venc_core_id {
+	MTK_VENC_CORE0 = 0,
+	MTK_VENC_CORE1 = 1,
+	MTK_VENC_CORE_MAX,
+};
+
+/**
+ * enmu mtk_venc_core_mode - Used to indicate different encode mode
+ */
+enum mtk_venc_core_mode {
+	VENC_SINGLE_CORE_MODE = 0,
+	VENC_DUAL_CORE_MODE = 1,
+};
+
 /*
  * struct mtk_video_fmt - Structure used to store information about pixelformats
  */
@@ -420,6 +437,7 @@ struct mtk_vcodec_dec_pdata {
  * @output_formats: array of supported output formats
  * @num_output_formats: number of entries in output_formats
  * @core_type: stand for h264 or vp8 encode
+ * @core_mode: indicate encode core mode
  */
 struct mtk_vcodec_enc_pdata {
 	bool uses_ext;
@@ -430,6 +448,7 @@ struct mtk_vcodec_enc_pdata {
 	const struct mtk_video_fmt *output_formats;
 	size_t num_output_formats;
 	int core_type;
+	enum mtk_venc_core_mode core_mode;
 };
 
 #define MTK_ENC_CTX_IS_EXT(ctx) ((ctx)->dev->venc_pdata->uses_ext)
@@ -479,6 +498,7 @@ struct mtk_vcodec_enc_pdata {
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
+ * @enc_core_dev: used to store venc core device
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -524,6 +544,8 @@ struct mtk_vcodec_dev {
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
+
+	void *enc_core_dev[MTK_VENC_CORE_MAX];
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
new file mode 100644
index 000000000000..d84914f615a5
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "mtk_vcodec_drv.h"
+#include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_core.h"
+
+static const struct of_device_id mtk_venc_core_ids[] = {
+	{
+		.compatible = "mediatek,mtk-venc-core0",
+		.data = (void *)MTK_VENC_CORE0,
+	},
+	{
+		.compatible = "mediatek,mtk-venc-core1",
+		.data = (void *)MTK_VENC_CORE1,
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_venc_core_ids);
+
+static void clean_irq_status(unsigned int irq_status, void __iomem *addr)
+{
+	if (irq_status & MTK_VENC_IRQ_STATUS_PAUSE)
+		writel(MTK_VENC_IRQ_STATUS_PAUSE, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SWITCH)
+		writel(MTK_VENC_IRQ_STATUS_SWITCH, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_DRAM)
+		writel(MTK_VENC_IRQ_STATUS_DRAM, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_SPS)
+		writel(MTK_VENC_IRQ_STATUS_SPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_PPS)
+		writel(MTK_VENC_IRQ_STATUS_PPS, addr);
+
+	if (irq_status & MTK_VENC_IRQ_STATUS_FRM)
+		writel(MTK_VENC_IRQ_STATUS_FRM, addr);
+}
+
+static irqreturn_t mtk_enc_core_irq_handler(int irq, void *priv)
+{
+	struct mtk_venc_core_dev *core = priv;
+	struct mtk_vcodec_ctx *ctx;
+	unsigned long flags;
+	void __iomem *addr;
+
+	spin_lock_irqsave(&core->main_dev->irqlock, flags);
+	ctx = core->curr_ctx;
+	spin_unlock_irqrestore(&core->main_dev->irqlock, flags);
+	if (!ctx)
+		return IRQ_HANDLED;
+
+	mtk_v4l2_debug(1, "id=%d core :%d", ctx->id, core->core_id);
+
+	addr = core->reg_base + MTK_VENC_IRQ_ACK_OFFSET;
+	ctx->irq_status = readl(core->reg_base + MTK_VENC_IRQ_STATUS_OFFSET);
+	clean_irq_status(ctx->irq_status, addr);
+
+	wake_up_ctx(ctx, MTK_INST_IRQ_RECEIVED, 0);
+	return IRQ_HANDLED;
+}
+
+static int mtk_venc_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_venc_core_dev *core;
+	struct mtk_vcodec_dev *main_dev;
+	int ret;
+
+	if (!dev->parent) {
+		dev_err(dev, "No parent for venc core device\n");
+		return -ENODEV;
+	}
+
+	main_dev = dev_get_drvdata(dev->parent);
+	if (!main_dev) {
+		dev_err(dev, "Failed to get parent driver data");
+		return -EINVAL;
+	}
+
+	core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->plat_dev = pdev;
+
+	core->reg_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->reg_base)) {
+		dev_err(&pdev->dev, "Failed to get reg base");
+		ret = PTR_ERR(core->reg_base);
+		goto err;
+	}
+
+	core->enc_irq = platform_get_irq(pdev, 0);
+	if (core->enc_irq < 0) {
+		dev_err(&pdev->dev, "Failed to get irq resource");
+		ret = core->enc_irq;
+		goto err;
+	}
+
+	ret = devm_request_irq(&pdev->dev, core->enc_irq,
+			       mtk_enc_core_irq_handler, 0,
+			       pdev->name, core);
+	if (ret) {
+		dev_err(&pdev->dev,
+			"Failed to install core->enc_irq %d (%d)",
+			core->enc_irq, ret);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	core->core_id =
+		(enum mtk_venc_core_id)of_device_get_match_data(&pdev->dev);
+	if (core->core_id < 0 || core->core_id >= MTK_VENC_CORE_MAX) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	main_dev->enc_core_dev[core->core_id] = core;
+	core->main_dev = main_dev;
+
+	platform_set_drvdata(pdev, core);
+
+	dev_info(dev, "Venc core :%d probe done\n", core->core_id);
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static struct platform_driver mtk_venc_core_driver = {
+	.probe  = mtk_venc_core_probe,
+	.driver = {
+		.name	 = "mtk-venc-core",
+		.of_match_table = mtk_venc_core_ids,
+	},
+};
+module_platform_driver(mtk_venc_core_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Mediatek video encoder core driver");
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h
new file mode 100644
index 000000000000..856681989869
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_core.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#ifndef _MTK_VCODEC_ENC_CORE_H_
+#define _MTK_VCODEC_ENC_CORE_H_
+
+#include <linux/platform_device.h>
+#include "mtk_vcodec_drv.h"
+
+/*
+ * struct mtk_venc_core_dev - driver data
+ * @plat_dev: platform_device
+ * @main_dev: main device
+ * @pm: power management data
+ * @curr_ctx: the context that is waiting for venc hardware
+ * @reg_base: mapped address of venc registers
+ * @irq_status: venc core irq status
+ * @enc_irq: venc device irq
+ * @core id: for venc core id: core#0, core#1...
+ */
+struct mtk_venc_core_dev {
+	struct platform_device *plat_dev;
+	struct mtk_vcodec_dev *main_dev;
+
+	struct mtk_vcodec_pm pm;
+	struct mtk_vcodec_ctx *curr_ctx;
+
+	void __iomem *reg_base;
+	unsigned int irq_status;
+	int enc_irq;
+	int core_id;
+};
+
+#endif /* _MTK_VCODEC_ENC_CORE_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 1f950310a3fb..9d48c604bc54 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -231,10 +231,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 {
 	struct mtk_vcodec_dev *dev;
 	struct video_device *vfd_enc;
-	struct resource *res;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret;
+	int ret, core_type;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -260,39 +259,37 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		return PTR_ERR(dev->fw_handler);
 
 	dev->venc_pdata = of_device_get_match_data(&pdev->dev);
-	ret = mtk_vcodec_init_enc_clk(dev);
-	if (ret < 0) {
-		dev_err(&pdev->dev, "Failed to get mtk vcodec clock source!");
-		goto err_enc_pm;
-	}
+	core_type = dev->venc_pdata->core_type;
 
-	pm_runtime_enable(&pdev->dev);
+	if (dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE) {
+		ret = mtk_vcodec_init_enc_clk(dev);
+		if (ret < 0) {
+			dev_err(&pdev->dev,
+				"Failed to get mtk vcodec clock source!");
+			goto err_enc_pm;
+		}
 
-	dev->reg_base[dev->venc_pdata->core_type] =
-		devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dev->reg_base[dev->venc_pdata->core_type])) {
-		ret = PTR_ERR(dev->reg_base[dev->venc_pdata->core_type]);
-		goto err_res;
-	}
+		pm_runtime_enable(&pdev->dev);
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get irq resource");
-		ret = -ENOENT;
-		goto err_res;
-	}
+		dev->reg_base[core_type] =
+			devm_platform_ioremap_resource(pdev, 0);
+		if (IS_ERR(dev->reg_base[core_type])) {
+			ret = PTR_ERR(dev->reg_base[core_type]);
+			goto err_res;
+		}
 
-	dev->enc_irq = platform_get_irq(pdev, 0);
-	irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
-	ret = devm_request_irq(&pdev->dev, dev->enc_irq,
-			       mtk_vcodec_enc_irq_handler,
-			       0, pdev->name, dev);
-	if (ret) {
-		dev_err(&pdev->dev,
-			"Failed to install dev->enc_irq %d (%d) core_type (%d)",
-			dev->enc_irq, ret, dev->venc_pdata->core_type);
-		ret = -EINVAL;
-		goto err_res;
+		dev->enc_irq = platform_get_irq(pdev, 0);
+		irq_set_status_flags(dev->enc_irq, IRQ_NOAUTOEN);
+		ret = devm_request_irq(&pdev->dev, dev->enc_irq,
+				       mtk_vcodec_enc_irq_handler,
+				       0, pdev->name, dev);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"Failed to install irq %d (%d) core_type (%d)",
+				dev->enc_irq, ret, core_type);
+			ret = -EINVAL;
+			goto err_res;
+		}
 	}
 
 	mutex_init(&dev->enc_mutex);
@@ -358,8 +355,17 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		goto err_enc_reg;
 	}
 
+	if (dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		ret = of_platform_populate(pdev->dev.of_node,
+					   NULL, NULL, &pdev->dev);
+		if (ret) {
+			mtk_v4l2_err("Venc main device populate failed");
+			goto err_enc_reg;
+		}
+	}
+
 	mtk_v4l2_debug(0, "encoder %d registered as /dev/video%d",
-		       dev->venc_pdata->core_type, vfd_enc->num);
+		       core_type, vfd_enc->num);
 
 	return 0;
 
@@ -372,8 +378,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 err_enc_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_res:
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvenc);
+	if (dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE) {
+		pm_runtime_disable(dev->pm.dev);
+		put_device(dev->pm.larbvenc);
+	}
 err_enc_pm:
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return ret;
@@ -387,6 +395,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 60000000,
 	.core_type = VENC_SYS,
+	.core_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
@@ -397,6 +406,7 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 9000000,
 	.core_type = VENC_LT_SYS,
+	.core_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
@@ -408,6 +418,7 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 40000000,
 	.core_type = VENC_SYS,
+	.core_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
@@ -419,6 +430,7 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
 	.core_type = VENC_SYS,
+	.core_mode = VENC_SINGLE_CORE_MODE,
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
@@ -430,6 +442,7 @@ static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
 	.min_bitrate = 64,
 	.max_bitrate = 100000000,
 	.core_type = VENC_SYS,
+	.core_mode = VENC_DUAL_CORE_MODE,
 };
 
 static const struct of_device_id mtk_vcodec_enc_match[] = {
@@ -457,8 +470,11 @@ static int mtk_vcodec_enc_remove(struct platform_device *pdev)
 		video_unregister_device(dev->vfd_enc);
 
 	v4l2_device_unregister(&dev->v4l2_dev);
-	pm_runtime_disable(dev->pm.dev);
-	put_device(dev->pm.larbvenc);
+
+	if (dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE) {
+		pm_runtime_disable(dev->pm.dev);
+		put_device(dev->pm.larbvenc);
+	}
 	mtk_vcodec_fw_release(dev->fw_handler);
 	return 0;
 }
-- 
2.18.0



From steven.price at arm.com  Mon Jan 17 04:11:36 2022
From: steven.price at arm.com (Steven Price)
Date: Mon, 17 Jan 2022 12:11:36 +0000
Subject: [bootwrapper PATCH v2 02/13] Add bit-field macros
In-Reply-To: <20220114105653.3003399-3-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-3-mark.rutland@arm.com>
Message-ID: <253b79f8-9c8b-4d8d-4f60-2ac74d763c73@arm.com>

On 14/01/2022 10:56, Mark Rutland wrote:
> Arm architectural documentation typically defines bit-fields as
> `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> helpful if we could define fields in the same way.
> 
> Add helpers so that we can do so, along with helper to extract/insert
> bit-field values.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  include/bits.h | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 79 insertions(+)
>  create mode 100644 include/bits.h
> 
> diff --git a/include/bits.h b/include/bits.h
> new file mode 100644
> index 0000000..0bf2c67
> --- /dev/null
> +++ b/include/bits.h
> @@ -0,0 +1,79 @@
> +/*
> + * include/bits.h - helpers for bit-field definitions.
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __BITS_H
> +#define __BITS_H
> +
> +#ifdef __ASSEMBLY__
> +#define UL(x)	x
> +#define ULL(x)	x
> +#else
> +#define UL(x)	x##UL
> +#define ULL(x)	x##ULL
> +#endif
> +
> +/*
> + * Define a contiguous mask of bits with `msb` as the most significant bit and
> + * `lsb` as the least significant bit. The `msb` value must be greater than or
> + * equal to `lsb`.
> + *
> + * For example:
> + * - BITS(63, 63) is 0x8000000000000000
> + * - BITS(63, 0)  is 0xFFFFFFFFFFFFFFFF
> + * - BITS(0, 0)   is 0x0000000000000001
> + * - BITS(49, 17) is 0x0001FFFFFFFE0000
> + */
> +#define BITS(msb, lsb) \
> +	((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
> +
> +/*
> + * Define a mask of a single set bit `b`.
> + *
> + * For example:
> + * - BIT(63) is 0x8000000000000000
> + * - BIT(0)  is 0x0000000000000001
> + * - BIT(32) is 0x0000000100000000
> + */
> +#define BIT(b)	BITS(b, b)
> +
> +/*
> + * Find the least significant set bit in the contiguous set of bits in `mask`.
> + *
> + * For example:
> + * - BITS_LSB(0x0000000000000001) is 0
> + * - BITS_LSB(0x000000000000ff00) is 8
> + * - BITS_LSB(0x8000000000000000) is 63
> + */
> +#define BITS_LSB(mask)	(__builtin_ffsll(mask) - 1)
> +
> +/*
> + * Extract a bit-field out of `val` described by the contiguous set of bits in
> + * `mask`.
> + *
> + * For example:
> + * - BITS_EXTRACT(0xABCD, BITS(15, 12)) is 0xA
> + * - BITS_EXTRACT(0xABCD, BITS(11, 8))  is 0xB
> + * - BITS_EXTRACT(0xABCD, BIT(7))       is 0x1
> + */
> +#define BITS_EXTRACT(val, mask) \
> +	(((val) & (mask)) >> BITS_LSB(mask))
> +
> +/*
> + * Insert the least significant bits of `val` into the bit-field described by
> + * the contiguous set of bits in `mask`.
> + *
> + * For example:
> + * - BITS_INSERT(BITS(3, 0), 0xA)   is 0x000A
> + * - BITS_INSERT(BITS(15, 12), 0xA) is 0xA000
> + * - BITS_INSERT(BIT(15), 0xF)      is 0x1000

    * - BITS_INSERT(BIT(35), 0x1)      is 0x0

... which might be surprising!

of course BITS_INSERT(BIT(35), ULL(0x1)) works, but I feel either the
description above needs to signpost this gotcha, or a cast is needed below.

AFAICT this macro isn't actually used in your series.

Steve

> + *
> + */
> +#define BITS_INSERT(mask, val) \
> +	(((val) << BITS_LSB(mask)) & (mask))
> +
> +#endif
> 



From biju.das.jz at bp.renesas.com  Mon Jan 17 04:13:36 2022
From: biju.das.jz at bp.renesas.com (Biju Das)
Date: Mon, 17 Jan 2022 12:13:36 +0000
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
Message-ID: <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>

Hi Neil,
> Subject: Re: dw_hdmi is showing wrong colour after commit
> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> callbacks")
> 
> Hi again,
> 
> On 14/01/2022 15:40, Neil Armstrong wrote:
> > Hi,
> >
> > On 14/01/2022 15:23, Biju Das wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: Neil Armstrong <narmstrong at baylibre.com>
> >>> Sent: 14 January 2022 13:56
> >>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
> >>> <festevam at gmail.com>
> >>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
> >>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
> >>> martin.blumenstingl at googlemail.com;
> >>> linux-amlogic at lists.infradead.org;
> >>> linux-arm-kernel at lists.infradead.org;
> >>> dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org;
> >>> linux-renesas-soc at vger.kernel.org
> >>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
> >>> callbacks")
> >>>
> >>> Hi,
> >>>
> >>> On 14/01/2022 12:08, Biju Das wrote:
> >>>> Hi Neil,
> >>>>
> >>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>> fmts
> >>>>> callbacks")
> >>>>>
> >>>>> On 14/01/2022 09:29, Biju Das wrote:
> >>>>>> Hi Neil,
> >>>>>>
> >>>>>> + renesas-soc
> >>>>>>
> >>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
> >>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>>> fmts
> >>>>>>> callbacks")
> >>>>>>>
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
> >>>>>>>> Hi Biju,
> >>>>>>>>
> >>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
> >>>>>>>> <biju.das.jz at bp.renesas.com>
> >>>>>>> wrote:
> >>>>>>>>>
> >>>>>>>>> Hi All,
> >>>>>>>>>
> >>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working
> >>>>>>>>> ok(colour) till the commit
> >>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
> >>>>>>>>> fmts
> >>>>>>> callbacks").
> >>>>>>>>>
> >>>>>>>>> After this patch, the screen becomes greenish(may be it is
> >>>>>>>>> setting it
> >>>>>>> into YUV format??).
> >>>>>>>>>
> >>>>>>>>> By checking the code, previously it used to call get_input_fmt
> >>>>>>>>> callback
> >>>>>>> and set colour as RGB24.
> >>>>>>>>>
> >>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns
> >>>>>>>>> 3 outputformats(YUV16, YUV24 and RGB24) And get_input_fmt
> >>>>>>>>> callback, I see
> >>>>>>> the outputformat as YUV16 instead of RGB24.
> >>>>>>>>>
> >>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI
> driver.
> >>>>>>>
> >>>>>>> This patch was introduced to maintain the bridge color format
> >>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
> >>>>>>> seems it behaves incorrectly if the first bridge doesn't
> >>>>>>> implement the negotiation callbacks.
> >>>>>>>
> >>>>>>> Let me check the code to see how to fix that.
> >>>>>>
> >>>>>> Thanks for the information, I am happy to test the patch/fix.
> >>>>>>
> >>>>>> Cheers,
> >>>>>> Biju
> >>>>>>
> >>>>>>>
> >>>>>>>>
> >>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board,
> >>>>>>>> which
> >>>>> shows:
> >>>>>>>>
> >>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
> >>>>>>>> HDCP (DWC HDMI 3D TX PHY)
> >>>>>>>>
> >>>>>>>> The colors are shown correctly here.
> >>>>>>>>
> >>>>>>>
> >>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
> >>>>>>> negotiation fails and use the RGB fallback input & output format.
> >>>>>>>
> >>>>>>> Anyway thanks for testing
> >>>>>>>
> >>>>>>> Neil
> >>>>>
> >>>>> Can you test :
> >>>>>
> >>>>> ==><===============================
> >>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
> >>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
> >>>>> 100644
> >>>>> --- a/drivers/gpu/drm/drm_bridge.c
> >>>>> +++ b/drivers/gpu/drm/drm_bridge.c
> >>>>> @@ -955,7 +955,14 @@
> >>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
> >>>>> drm_bridge *bridge,
> >>>>>         last_bridge_state =
> >>>>> drm_atomic_get_new_bridge_state(crtc_state-
> >>>>>> state,
> >>>>>
> >>>>> last_bridge);
> >>>>>
> >>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>>>> +       /*
> >>>>> +        * Only negociate with real values if both end of the
> >>>>> + bridge
> >>> chain
> >>>>> +        * support negociation callbacks, otherwise you can end in
> >>>>> + a
> >>>>> situation
> >>>>> +        * where the selected output format doesn't match with the
> >>>>> + first
> >>>>> bridge
> >>>>> +        * output format.
> >>>>> +        */
> >>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
> >>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
> >>>>>                 const struct drm_bridge_funcs *funcs =
> >>>>> last_bridge->funcs;
> >>>>>
> >>>>>                 /*
> >>>>> @@ -980,7 +987,12 @@
> >>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
> >>>>> drm_bridge *bridge,
> >>>>>                 if (!out_bus_fmts)
> >>>>>                         return -ENOMEM;
> >>>>>
> >>>>> -               if (conn->display_info.num_bus_formats &&
> >>>>> +               /*
> >>>>> +                * If first bridge doesn't support negociation,
> >>>>> + use
> >>>>> MEDIA_BUS_FMT_FIXED
> >>>>> +                * as a safe value for the whole bridge chain
> >>>>> +                */
> >>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
> >>>>> +                   conn->display_info.num_bus_formats &&
> >>>>>                     conn->display_info.bus_formats)
> >>>>>                         out_bus_fmts[0] = conn-
> >>>>>> display_info.bus_formats[0];
> >>>>>                 else
> >>>>> ==><===============================
> >>>>>
> >>>>> This should exclude your situation where the first bridge doesn't
> >>>>> support negociation.
> >>>>
> >>>> I have tested this fix with Linux next-20220114. Still I see colour
> >>> issue.
> >>>>
> >>>> It is still negotiating and it is calling get_output_fmt_callbck
> >>>>
> >>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
> >>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_YUV8_1X24=1#########
> >>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> >>> MEDIA_BUS_FMT_RGB888_1X24=2#########
> >>>>
> >>>> And In get_input_fmt callback, I See the outputformat as YUV16
> >>>> instead
> >>> of RGB24.
> >>>>
> >>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> >>> MEDIA_BUS_FMT_UYVY8_1X16#########
> >>>> [    3.473644] ########hdmi_video_sample
> >>> MEDIA_BUS_FMT_UYVY8_1X16#########
> >>>
> >>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to
> >>> the encoder.
> >>
> >> Yep.
> >>
> >>>
> >>> Let me figure that out, no sure I can find a clean solution except
> >>> putting back RGB24 before YUV.
> >>>
> >>> Anyway please test that:
> >>
> >> It works now after reordering.
> >>
> >> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24=0#########
> >> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_YUV8_1X24=1#########
> >> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
> MEDIA_BUS_FMT_UYVY8_1X16=2#########
> >>
> >> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
> MEDIA_BUS_FMT_RGB888_1X24#########
> >> [    3.506797] ########hdmi_video_sample
> MEDIA_BUS_FMT_RGB888_1X24#########
> >>
> >> Is it acceptable solution to the users of dw_hdmi driver? May be it is
> worth to post a patch.
> >> at least it is fixing the colour issue??
> >
> > Yes, it gets back to default behavior before negociation, nevertheless
> > we need to think how to handle your use-case correctly at some point.
> >
> > I'll post this as a patch ASAP so it gets applied before landing in
> linus master.
> >
> > Neil
> >
> >>
> >> Regards,
> >> Biju
> >>
> >>>
> [...]
> 
> I'm not happy with this version since it's merely a hack which makes it
> work.
> 
> Can you test the following change instead, it's correctly handles your
> situation in a generic manner.
> 
> ========================><=============================
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..9f2e1cac0ae2 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2551,8 +2551,9 @@ static u32
> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>         if (!output_fmts)
>                 return NULL;
> 
> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves
> */
> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
> +       /* If dw-hdmi is the first or only bridge, avoid negociating with
> ourselves */
> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
> +           list_is_first(&bridge->chain_node,
> + &bridge->encoder->bridge_chain)) {
>                 *num_output_fmts = 1;
>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
> 
> @@ -2673,6 +2674,10 @@ static u32
> *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>         if (!input_fmts)
>                 return NULL;
> 
> +       /* If dw-hdmi is the first bridge fall-back to safe output format
> */
> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
> >bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> +
>         switch (output_fmt) {
>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>         case MEDIA_BUS_FMT_FIXED:
> ========================><=============================

This patch alone fixes the issue. I have tested with Linux-next.
Do we need below code, as it is already taken care in output_bus_fmt callback.

> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
> >bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;

Cheers,
Biju

From mark.rutland at arm.com  Mon Jan 17 04:15:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 12:15:57 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220114181247.7b366f45@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
 <20220114181247.7b366f45@donnerap.cambridge.arm.com>
Message-ID: <20220117121557.GA87485@C02TD0UTHF1T.local>

On Fri, Jan 14, 2022 at 06:12:47PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:46 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,

Hi Andre,

> > The SCTLR_ELx registers contain fields which are UNKNOWN or
> > IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
> > defines the endianness of memory accesses (e.g. reads from literal
> > pools). Due to this, portions of boot-wrapper code are not guaranteed
> > to work correctly.
> > 
> > Rework the startup code to explicitly initialize SCTLR_ELx for the
> > exception level the boot-wrapper was entered at. When entered at EL2
> > it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
> > behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
> > which would break the initialization performed in jump_kernel.
> > 
> > As we plan to eventually support the highest implemented EL being any of
> > EL3/EL2/EL1, code is added to handle all of these exception levels, even
> > though we do not currently support starting at EL1.
> > 
> > We'll initialize other registers in subsequent patches.
> 
> So the idea of initialising each EL and the respective code below looks
> good to me, however I have some questions about the SCTLR reset values
> below:
> 
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > ---
> >  arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
> >  arch/aarch64/include/asm/cpu.h | 27 ++++++++++++-
> >  2 files changed, 85 insertions(+), 16 deletions(-)
> > 
> > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> > index 900b9f8..45a0367 100644
> > --- a/arch/aarch64/boot.S
> > +++ b/arch/aarch64/boot.S
> > @@ -26,26 +26,26 @@
> >  	 *   PSCI is not supported when entered in this exception level.
> >  	 */
> >  ASM_FUNC(_start)
> > -	cpuid	x0, x1
> > -	bl	find_logical_id
> > -	cmp	x0, #MPIDR_INVALID
> > -	beq	err_invalid_id
> > -	bl	setup_stack
> > -
> > -	/*
> > -	 * EL3 initialisation
> > -	 */
> >  	mrs	x0, CurrentEL
> >  	cmp	x0, #CURRENTEL_EL3
> > -	b.eq	1f
> > +	b.eq	reset_at_el3
> > +	cmp	x0, #CURRENTEL_EL2
> > +	b.eq	reset_at_el2
> > +	cmp	x0, #CURRENTEL_EL1
> > +	b.eq	reset_at_el1
> >  
> > -	mov	w0, #1
> > -	ldr	x1, =flag_no_el3
> > -	str	w0, [x1]
> > +	/* Booting at EL0 is not supported */
> > +	b	.
> >  
> > -	b	start_no_el3
> > +	/*
> > +	 * EL3 initialisation
> > +	 */
> > +reset_at_el3:
> > +	mov_64	x0, SCTLR_EL3_RESET
> > +	msr	sctlr_el3, x0
> > +	isb
> >  
> > -1:	mov	x0, #0x30			// RES1
> > +	mov	x0, #0x30			// RES1
> >  	orr	x0, x0, #(1 << 0)		// Non-secure EL1
> >  	orr	x0, x0, #(1 << 8)		// HVC enable
> >  
> > @@ -135,10 +135,54 @@ ASM_FUNC(_start)
> >  	ldr	x0, =COUNTER_FREQ
> >  	msr	cntfrq_el0, x0
> >  
> > +	cpuid	x0, x1
> > +	bl	find_logical_id
> > +	cmp	x0, #MPIDR_INVALID
> > +	b.eq	err_invalid_id
> > +	bl	setup_stack
> > +
> >  	bl	gic_secure_init
> >  
> >  	b	start_el3
> >  
> > +	/*
> > +	 * EL2 initialization
> > +	 */
> > +reset_at_el2:
> > +	// Ensure E2H is not in use
> > +	mov_64	x0, HCR_EL2_RESET
> > +	msr	hcr_el2, x0
> > +	isb
> > +
> > +	mov_64	x0, SCTLR_EL2_RESET
> > +	msr	sctlr_el2, x0
> > +	isb
> > +
> > +	b	reset_no_el3
> > +
> > +	/*
> > +	 * EL1 initialization
> > +	 */
> > +reset_at_el1:
> > +	mov_64	x0, SCTLR_EL1_RESET
> > +	msr	sctlr_el1, x0
> > +	isb
> > +
> > +	b	reset_no_el3
> > +
> > +reset_no_el3:
> > +	cpuid	x0, x1
> > +	bl	find_logical_id
> > +	cmp	x0, #MPIDR_INVALID
> > +	b.eq	err_invalid_id
> > +	bl	setup_stack
> > +
> > +	mov	w0, #1
> > +	ldr	x1, =flag_no_el3
> > +	str	w0, [x1]
> > +
> > +	b	start_no_el3
> > +
> >  err_invalid_id:
> >  	b	.
> >  
> > diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> > index 1053414..1e9141a 100644
> > --- a/arch/aarch64/include/asm/cpu.h
> > +++ b/arch/aarch64/include/asm/cpu.h
> > @@ -14,6 +14,32 @@
> >  #define MPIDR_ID_BITS		0xff00ffffff
> >  
> >  #define CURRENTEL_EL3		(3 << 2)
> > +#define CURRENTEL_EL2		(2 << 2)
> > +#define CURRENTEL_EL1		(1 << 2)
> > +
> > +/*
> > + * RES1 bit definitions definitions as of ARM DDI 0487G.b
> > + *
> > + * These includes bits which are RES1 in some configurations.
> > + */
> > +#define SCTLR_EL3_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > +				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))
> > +
> > +#define SCTLR_EL2_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > +				 BIT(18) | BIT(16) | BIT(11) | BIT(5) | BIT(4))
> 
> I compared all bits against the ARM ARM and the kernel version for EL2,
> that looks correct to me.
> 
> > +
> > +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))
> 
> - The kernel sets TSCXT(bit[20]), and the ARM ARM says that the value
> should be RES1 if FEAT_CSV2_* is not implemented. Should we copy this?

Yes, we should. I'll go and fold that in.

> - The kernel clears ITD(bit[7]), and the ARM ARM says it's *Otherwise* RES1
> (no AArch32 in EL0). I feel like we should not disable IT instructions in
> EL0 needlessly?

Per the ARM ARM the bit resets to an UNKNOWN value, and so per our usual
policy the kernel must initialize that before it can depend upon it, and
IIUC you say the kernel already does so.

So it shouldn't matter what the boot-wrapper does, and for consitency, I
think the boot-wrapper should set this to 0b1.

> - I also feel like we should set CP15BEN(bit[5]), for similar reasons.

I agree.

> Granted those bits affect only EL0 execution, which we don't care about in
> the boot-wrapper, but I was wondering if we should change those anyway? At
> least bit 20?

I'll set all three of those bits. as above.

> > +#define HCR_EL2_RES1		(BIT(1))
> 
> Should we set RW(bit[31]), just to be safe? Not sure this is explicitly
> mentioned somewhere, but is the boot flow when we are entered in EL2 to
> stay in EL2 and launch the kernel in there as well?

I don't think we need to currently. HCR_EL2.RW is UNKNOWN out-of-reset,
is RAO/WI rather than RES1, and only affects lower ELs, so per usual
policy we leave this to the kernel to initialize. Of the configurations
this could affect:

* BW @ EL3 + {psci,spin}
  Kernel entered at EL2 on all PEs.

* BW @ EL2 + spin-table
  Kernel entered at EL2 on all PEs.

* BW @ EL2 + PSCI
  Kernel entered at EL2 on boot PE.
  BROKEN due to PSCI conduit anyhow.

I'd like to clean up the EL + boot-method combinations, but this
reqiures some more work which I had punted out of this series for now.

For now, I'd prefer to leave this as-is. I would like to fix this as
part of a subsequent boot-method cleanup, configuring HCR_EL2.RW as part
of the kernel handover logic later in the boot flow.

> 
> > +
> > +/*
> > + * Initial register values required for the boot-wrapper to run out-of-reset.
> > + */
> > +#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
> > +#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
> > +#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
> > +#define HCR_EL2_RESET		HCR_EL2_RES1
> >  
> >  #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
> >  
> > @@ -43,7 +69,6 @@
> >  #define ZCR_EL3_LEN_MASK	0x1ff
> >  
> >  #define SCTLR_EL1_CP15BEN	(1 << 5)
> > -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
> >  
> >  #ifdef KERNEL_32
> >  /* 32-bit kernel decompressor uses CP15 barriers */
> > #define SCTLR_EL1_KERNEL        (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
> 
> So I wonder if this actually works? The ARMv7 version of SCTLR
> differs in some bits from both the ARMv8 AArch32 version and more
> importantly the AArch64 version.

Hmm. SCTLR_EL1 is architecturally mapped to SCTLR, and for some reason I
thought that applied field-wise, but IIUC you're saying that applies
bit-wise, right?

The ARM ARM is delightfully unclear about this, which is reather
unfortunate. Per the glossary in ARM DDI 0487G.b:

| Where this manual describes a register as being architecturally mapped
| to another register, this indicates that, in an implementation that
| supports both of the registers, the two registers access the same
| state.

That being the case, we'd need to do likewise for all the other
registers accessible at kernel ELs, right?

> I had troubles the other day running the
> arm32 Linux kernel decompressor with some ARMv8 SCTLR_EL1 reset value. The
> decompressor code does only read-modify-write of SCTLR (probably to
> cover multiple architecture revisions), so some bits might stay wrong. In
> particular I think having bits 28 and 29 set caused problems.
> By looking at the ARMv7 ARM and with experimentation I came up
> with 0x00c00878 as a safe and working value.

Do we have any comments/documentation saying what the 32-bit kernel
actually needs/wants here?

> Shall we have a separate reset value for 32bit?

Currently, the 32-bit side of the boot-wrapper uses:

	(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)

... noting that `1 << 5` and `3 << 4` overlap..

Which is: 
* bit[22]: RES1
* bit[11]: RES1
* bit[5]:  CP15BEN
* bit[4]:  LSMAOE

Per the above, it sounds like you think that's wrong too?

Whatever we do, the 32-bit/64-bit boot-wrapper should program something
functionally equivalent when booting a 32-bit kernel.

Thanks,
Mark.


From irui.wang at mediatek.com  Mon Jan 17 04:06:14 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Mon, 17 Jan 2022 20:06:14 +0800
Subject: [PATCH v2, 09/10] media: mtk-vcodec: Add dual core mode encode process
In-Reply-To: <20220117120615.21687-1-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
Message-ID: <20220117120615.21687-10-irui.wang@mediatek.com>

The dual core mode encoding is tries to uses the two venc cores:
frame#0 uses core#0, frame#1 uses core#1, frame#2 uses core#0...,

Lock the device and enable the clock by used core, for sequence
header encoding, it always uses core#0.

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 11 ++-
 .../platform/mtk-vcodec/mtk_vcodec_enc.c      | 23 +++---
 .../platform/mtk-vcodec/mtk_vcodec_enc.h      |  4 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  7 +-
 .../platform/mtk-vcodec/venc/venc_h264_if.c   | 16 ++--
 .../platform/mtk-vcodec/venc/venc_vp8_if.c    |  3 +-
 .../media/platform/mtk-vcodec/venc_drv_if.c   | 73 ++++++++++++++-----
 .../media/platform/mtk-vcodec/venc_drv_if.h   |  5 ++
 .../media/platform/mtk-vcodec/venc_vpu_if.c   | 10 ++-
 .../media/platform/mtk-vcodec/venc_vpu_if.h   |  3 +-
 10 files changed, 113 insertions(+), 42 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index dc036279c42f..c3cf5904b4c6 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -308,6 +308,9 @@ struct vdec_pic_info {
  * @max_width: hardware supported max width
  * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
+ * @q_mutex: src & dst vb2_queue mutex
+ * @enc_idx: used to record encoded frame count
+ * @core_id: used to reoord used core
  */
 struct mtk_vcodec_ctx {
 	enum mtk_instance_type type;
@@ -356,6 +359,10 @@ struct mtk_vcodec_ctx {
 	unsigned int max_width;
 	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
+
+	struct mutex q_mutex;
+	int enc_idx;
+	int core_id;
 };
 
 /*
@@ -533,7 +540,9 @@ struct mtk_vcodec_dev {
 
 	/* decoder hardware mutex lock */
 	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
-	struct mutex enc_mutex;
+
+	/* encoder core mutex lock */
+	struct mutex enc_mutex[MTK_VENC_CORE_MAX];
 
 	struct mtk_vcodec_pm pm;
 	unsigned int dec_capability;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
index df231e67cdb2..dc70d328fcd3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c
@@ -1198,14 +1198,17 @@ static void mtk_venc_worker(struct work_struct *work)
 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_ERROR);
 		mtk_v4l2_err("venc_if_encode failed=%d", ret);
-	} else {
+	} else if (ctx->dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE) {
 		v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
-		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, enc_result.bs_size);
+		vb2_set_plane_payload(&dst_buf->vb2_buf, 0,
+				      enc_result.bs_size);
 		v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
 		mtk_v4l2_debug(2, "venc_if_encode bs size=%d",
-				 enc_result.bs_size);
+			       enc_result.bs_size);
 	}
 
+	ctx->enc_idx++;
+
 	v4l2_m2m_job_finish(ctx->dev->m2m_dev_enc, ctx->m2m_ctx);
 
 	mtk_v4l2_debug(1, "<=== src_buf[%d] dst_buf[%d] venc_if_encode ret=%d Size=%u===>",
@@ -1259,7 +1262,7 @@ void mtk_vcodec_enc_set_default_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct mtk_q_data *q_data;
 
-	ctx->m2m_ctx->q_lock = &ctx->dev->dev_mutex;
+	ctx->m2m_ctx->q_lock = &ctx->q_mutex;
 	ctx->fh.m2m_ctx = ctx->m2m_ctx;
 	ctx->fh.ctrl_handler = &ctx->ctrl_hdl;
 	INIT_WORK(&ctx->encode_work, mtk_venc_worker);
@@ -1391,7 +1394,7 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	src_vq->ops		= &mtk_venc_vb2_ops;
 	src_vq->mem_ops		= &vb2_dma_contig_memops;
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	src_vq->lock		= &ctx->dev->dev_mutex;
+	src_vq->lock		= &ctx->q_mutex;
 	src_vq->dev		= &ctx->dev->plat_dev->dev;
 
 	ret = vb2_queue_init(src_vq);
@@ -1405,26 +1408,26 @@ int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 	dst_vq->ops		= &mtk_venc_vb2_ops;
 	dst_vq->mem_ops		= &vb2_dma_contig_memops;
 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
-	dst_vq->lock		= &ctx->dev->dev_mutex;
+	dst_vq->lock		= &ctx->q_mutex;
 	dst_vq->dev		= &ctx->dev->plat_dev->dev;
 
 	return vb2_queue_init(dst_vq);
 }
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_unlock(&dev->enc_mutex);
+	mutex_unlock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_venc_unlock);
 
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx)
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id)
 {
 	struct mtk_vcodec_dev *dev = ctx->dev;
 
-	mutex_lock(&dev->enc_mutex);
+	mutex_lock(&dev->enc_mutex[core_id]);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mtk_venc_lock);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
index 513ee7993e34..434d91d36158 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.h
@@ -39,8 +39,8 @@ struct mtk_video_enc_buf {
 extern const struct v4l2_ioctl_ops mtk_venc_ioctl_ops;
 extern const struct v4l2_m2m_ops mtk_venc_m2m_ops;
 
-int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx);
-int mtk_venc_lock(struct mtk_vcodec_ctx *ctx);
+int mtk_venc_unlock(struct mtk_vcodec_ctx *ctx, int core_id);
+int mtk_venc_lock(struct mtk_vcodec_ctx *ctx, int core_id);
 int mtk_vcodec_enc_queue_init(void *priv, struct vb2_queue *src_vq,
 			      struct vb2_queue *dst_vq);
 void mtk_vcodec_enc_release(struct mtk_vcodec_ctx *ctx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index cef134bb6e83..cf42a5930b48 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -133,6 +133,7 @@ static int fops_vcodec_open(struct file *file)
 	INIT_LIST_HEAD(&ctx->list);
 	ctx->dev = dev;
 	init_waitqueue_head(&ctx->queue[0]);
+	mutex_init(&ctx->q_mutex);
 
 	ctx->type = MTK_INST_ENCODER;
 	ret = mtk_vcodec_enc_ctrls_setup(ctx);
@@ -240,7 +241,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	struct video_device *vfd_enc;
 	phandle rproc_phandle;
 	enum mtk_vcodec_fw_type fw_type;
-	int ret, core_type;
+	int ret, core_type, i;
 
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
@@ -299,7 +300,9 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
-	mutex_init(&dev->enc_mutex);
+	for (i = 0; i < MTK_VENC_CORE_MAX; i++)
+		mutex_init(&dev->enc_mutex[i]);
+
 	mutex_init(&dev->dev_mutex);
 	spin_lock_init(&dev->irqlock);
 
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
index 023b6eb8b20c..fdecf1d24b25 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_h264_if.c
@@ -448,7 +448,8 @@ static int h264_encode_sps(struct venc_h264_inst *inst,
 
 	mtk_vcodec_debug_enter(inst);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS, NULL, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_SPS,
+			     NULL, bs_buf, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -474,7 +475,8 @@ static int h264_encode_pps(struct venc_h264_inst *inst,
 
 	mtk_vcodec_debug_enter(inst);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS, NULL, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_PPS,
+			     NULL, bs_buf, NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
@@ -516,7 +518,8 @@ static int h264_encode_header(struct venc_h264_inst *inst,
 static int h264_encode_frame(struct venc_h264_inst *inst,
 			     struct venc_frm_buf *frm_buf,
 			     struct mtk_vcodec_mem *bs_buf,
-			     unsigned int *bs_size)
+			     unsigned int *bs_size,
+			     int core_id)
 {
 	int ret = 0;
 	unsigned int irq_status;
@@ -536,7 +539,8 @@ static int h264_encode_frame(struct venc_h264_inst *inst,
 	mtk_vcodec_debug(inst, "frm_count = %d,skip_frm_count =%d,frm_type=%d.\n",
 			 frame_info.frm_count, frame_info.skip_frm_count,
 			 frame_info.frm_type);
-	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME, frm_buf, bs_buf, &frame_info);
+	ret = vpu_enc_encode(&inst->vpu_inst, H264_BS_MODE_FRAME,
+			     frm_buf, bs_buf, &frame_info, core_id);
 	if (ret)
 		return ret;
 
@@ -664,7 +668,7 @@ static int h264_enc_encode(void *handle,
 
 		if (!inst->prepend_hdr) {
 			ret = h264_encode_frame(inst, frm_buf, bs_buf,
-						&result->bs_size);
+						&result->bs_size, ctx->core_id);
 			if (ret)
 				goto encode_err;
 			result->is_key_frm = inst->vpu_inst.is_key_frm;
@@ -692,7 +696,7 @@ static int h264_enc_encode(void *handle,
 		tmp_bs_buf.size = bs_buf->size - (hdr_sz + filler_sz);
 
 		ret = h264_encode_frame(inst, frm_buf, &tmp_bs_buf,
-					&bs_size_frm);
+					&bs_size_frm, ctx->core_id);
 		if (ret)
 			goto encode_err;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
index 56ce58f761f1..3b3471d90e21 100644
--- a/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc/venc_vp8_if.c
@@ -302,7 +302,8 @@ static int vp8_enc_encode_frame(struct venc_vp8_inst *inst,
 
 	mtk_vcodec_debug(inst, "->frm_cnt=%d", inst->frm_cnt);
 
-	ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf, NULL);
+	ret = vpu_enc_encode(&inst->vpu_inst, 0, frm_buf, bs_buf,
+			     NULL, MTK_VENC_CORE0);
 	if (ret)
 		return ret;
 
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.c b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
index 6cbdb7e30bb3..5c5013d0f32e 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.c
@@ -14,6 +14,7 @@
 #include "venc_drv_if.h"
 
 #include "mtk_vcodec_enc.h"
+#include "mtk_vcodec_enc_core.h"
 #include "mtk_vcodec_enc_pm.h"
 
 int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
@@ -31,9 +32,9 @@ int venc_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->init(ctx);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	return ret;
 }
@@ -43,9 +44,9 @@ int venc_if_set_param(struct mtk_vcodec_ctx *ctx,
 {
 	int ret = 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->set_param(ctx->drv_handle, type, in);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	return ret;
 }
@@ -56,24 +57,14 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct venc_done_result *result)
 {
 	int ret = 0;
-	unsigned long flags;
-
-	mtk_venc_lock(ctx);
 
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = ctx;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+	venc_encode_prepare(ctx, opt);
 
-	mtk_vcodec_enc_clock_on(ctx->dev, 0);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
-	mtk_vcodec_enc_clock_off(ctx->dev, 0);
 
-	spin_lock_irqsave(&ctx->dev->irqlock, flags);
-	ctx->dev->curr_ctx = NULL;
-	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+	venc_encode_unprepare(ctx, opt);
 
-	mtk_venc_unlock(ctx);
 	return ret;
 }
 
@@ -84,11 +75,57 @@ int venc_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return 0;
 
-	mtk_venc_lock(ctx);
+	mtk_venc_lock(ctx, ctx->core_id);
 	ret = ctx->enc_if->deinit(ctx->drv_handle);
-	mtk_venc_unlock(ctx);
+	mtk_venc_unlock(ctx, ctx->core_id);
 
 	ctx->drv_handle = NULL;
 
 	return ret;
 }
+
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt)
+{
+	unsigned long flags;
+	struct mtk_venc_core_dev *core;
+
+	if (ctx->dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		if (ctx->enc_idx & 0x01)
+			ctx->core_id = MTK_VENC_CORE1;
+		else
+			ctx->core_id = MTK_VENC_CORE0;
+	} else {
+		ctx->core_id = MTK_VENC_CORE0;
+	}
+	mtk_venc_lock(ctx, ctx->core_id);
+
+	spin_lock_irqsave(&ctx->dev->irqlock, flags);
+
+	if (ctx->dev->venc_pdata->core_mode == VENC_DUAL_CORE_MODE) {
+		core = ctx->dev->enc_core_dev[ctx->core_id];
+
+		core->curr_ctx = ctx;
+	} else {
+		ctx->dev->curr_ctx = ctx;
+	}
+
+	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+
+	mtk_vcodec_enc_clock_on(ctx->dev, ctx->core_id);
+}
+
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt)
+{
+	unsigned long flags;
+
+	if (ctx->dev->venc_pdata->core_mode == VENC_SINGLE_CORE_MODE ||
+	    opt == VENC_START_OPT_ENCODE_SEQUENCE_HEADER) {
+		mtk_vcodec_enc_clock_off(ctx->dev, ctx->core_id);
+		spin_lock_irqsave(&ctx->dev->irqlock, flags);
+		ctx->dev->curr_ctx = NULL;
+		spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
+		mtk_venc_unlock(ctx, ctx->core_id);
+	}
+}
diff --git a/drivers/media/platform/mtk-vcodec/venc_drv_if.h b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
index 0b04a1020873..15e9a2ab9cda 100644
--- a/drivers/media/platform/mtk-vcodec/venc_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_drv_if.h
@@ -167,4 +167,9 @@ int venc_if_encode(struct mtk_vcodec_ctx *ctx,
 		   struct mtk_vcodec_mem *bs_buf,
 		   struct venc_done_result *result);
 
+void venc_encode_prepare(struct mtk_vcodec_ctx *ctx,
+			 enum venc_start_opt opt);
+void venc_encode_unprepare(struct mtk_vcodec_ctx *ctx,
+			   enum venc_start_opt opt);
+
 #endif /* _VENC_DRV_IF_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index d3570c4c177d..a7219c10013b 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -225,9 +225,11 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
 int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
-		   struct venc_frame_info *frame_info)
+		   struct venc_frame_info *frame_info,
+		   int core_id)
 {
 	const bool is_ext = MTK_ENC_CTX_IS_EXT(vpu->ctx);
+	const int core_mode = MTK_ENC_CORE_MODE(vpu->ctx);
 	size_t msg_size = is_ext ?
 		sizeof(struct venc_ap_ipi_msg_enc_ext) :
 		sizeof(struct venc_ap_ipi_msg_enc);
@@ -261,6 +263,12 @@ int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		out.data[1] = frame_info->skip_frm_count;
 		out.data[2] = frame_info->frm_type;
 	}
+
+	if (core_mode == VENC_DUAL_CORE_MODE) {
+		out.data_item = 4;
+		out.data[3] = core_id;
+	}
+
 	if (vpu_enc_send_msg(vpu, &out, msg_size)) {
 		mtk_vcodec_err(vpu, "AP_IPIMSG_ENC_ENCODE %d fail",
 			       bs_mode);
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
index f83bc1b3f2bf..a8055eb62f7c 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.h
@@ -45,7 +45,8 @@ int vpu_enc_set_param(struct venc_vpu_inst *vpu,
 int vpu_enc_encode(struct venc_vpu_inst *vpu, unsigned int bs_mode,
 		   struct venc_frm_buf *frm_buf,
 		   struct mtk_vcodec_mem *bs_buf,
-		   struct venc_frame_info *frame_info);
+		   struct venc_frame_info *frame_info,
+		   int core_id);
 int vpu_enc_deinit(struct venc_vpu_inst *vpu);
 
 #endif
-- 
2.18.0



From patrice.chotard at foss.st.com  Mon Jan 17 04:17:44 2022
From: patrice.chotard at foss.st.com (patrice.chotard at foss.st.com)
Date: Mon, 17 Jan 2022 13:17:44 +0100
Subject: [PATCH v3] spi: stm32-qspi: Update spi registering
Message-ID: <20220117121744.29729-1-patrice.chotard@foss.st.com>

From: Patrice Chotard <patrice.chotard at foss.st.com>

Some device driver need to communicate to qspi device during the remove
process, qspi controller must be functional when spi_unregister_master()
is called.

To ensure this, replace devm_spi_register_master() by spi_register_master()
and spi_unregister_master() is called directly in .remove callback before
stopping the qspi controller.

This issue was put in evidence using kernel v5.11 and later
with a spi-nor which supports the software reset feature introduced
by commit d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on
shutdown")

Fixes: c530cd1d9d5e ("spi: spi-mem: add stm32 qspi controller")

Signed-off-by: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: <stable at vger.kernel.org> # 5.8.x
---

v3: 
  _ Update error path due to devm_spi_alloc_master() usage

v2: 
  _ update commit message
  _ make usage of devm_spi_alloc_master() instead of spi_alloc_master()

 drivers/spi/spi-stm32-qspi.c | 47 +++++++++++++-----------------------
 1 file changed, 17 insertions(+), 30 deletions(-)

diff --git a/drivers/spi/spi-stm32-qspi.c b/drivers/spi/spi-stm32-qspi.c
index 514337c86d2c..ffdc55f87e82 100644
--- a/drivers/spi/spi-stm32-qspi.c
+++ b/drivers/spi/spi-stm32-qspi.c
@@ -688,7 +688,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	struct resource *res;
 	int ret, irq;
 
-	ctrl = spi_alloc_master(dev, sizeof(*qspi));
+	ctrl = devm_spi_alloc_master(dev, sizeof(*qspi));
 	if (!ctrl)
 		return -ENOMEM;
 
@@ -697,58 +697,46 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi");
 	qspi->io_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(qspi->io_base)) {
-		ret = PTR_ERR(qspi->io_base);
-		goto err_master_put;
-	}
+	if (IS_ERR(qspi->io_base))
+		return PTR_ERR(qspi->io_base);
 
 	qspi->phys_base = res->start;
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qspi_mm");
 	qspi->mm_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(qspi->mm_base)) {
-		ret = PTR_ERR(qspi->mm_base);
-		goto err_master_put;
-	}
+	if (IS_ERR(qspi->mm_base))
+		return PTR_ERR(qspi->mm_base);
 
 	qspi->mm_size = resource_size(res);
-	if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ) {
-		ret = -EINVAL;
-		goto err_master_put;
-	}
+	if (qspi->mm_size > STM32_QSPI_MAX_MMAP_SZ)
+		return -EINVAL;
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		ret = irq;
-		goto err_master_put;
-	}
+	if (irq < 0)
+		return irq;
 
 	ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0,
 			       dev_name(dev), qspi);
 	if (ret) {
 		dev_err(dev, "failed to request irq\n");
-		goto err_master_put;
+		return ret;
 	}
 
 	init_completion(&qspi->data_completion);
 	init_completion(&qspi->match_completion);
 
 	qspi->clk = devm_clk_get(dev, NULL);
-	if (IS_ERR(qspi->clk)) {
-		ret = PTR_ERR(qspi->clk);
-		goto err_master_put;
-	}
+	if (IS_ERR(qspi->clk))
+		return PTR_ERR(qspi->clk);
 
 	qspi->clk_rate = clk_get_rate(qspi->clk);
-	if (!qspi->clk_rate) {
-		ret = -EINVAL;
-		goto err_master_put;
-	}
+	if (!qspi->clk_rate)
+		return -EINVAL;
 
 	ret = clk_prepare_enable(qspi->clk);
 	if (ret) {
 		dev_err(dev, "can not enable the clock\n");
-		goto err_master_put;
+		return ret;
 	}
 
 	rstc = devm_reset_control_get_exclusive(dev, NULL);
@@ -784,7 +772,7 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_noresume(dev);
 
-	ret = devm_spi_register_master(dev, ctrl);
+	ret = spi_register_master(ctrl);
 	if (ret)
 		goto err_pm_runtime_free;
 
@@ -806,8 +794,6 @@ static int stm32_qspi_probe(struct platform_device *pdev)
 	stm32_qspi_dma_free(qspi);
 err_clk_disable:
 	clk_disable_unprepare(qspi->clk);
-err_master_put:
-	spi_master_put(qspi->ctrl);
 
 	return ret;
 }
@@ -817,6 +803,7 @@ static int stm32_qspi_remove(struct platform_device *pdev)
 	struct stm32_qspi *qspi = platform_get_drvdata(pdev);
 
 	pm_runtime_get_sync(qspi->dev);
+	spi_unregister_master(qspi->ctrl);
 	/* disable qspi */
 	writel_relaxed(0, qspi->io_base + QSPI_CR);
 	stm32_qspi_dma_free(qspi);
-- 
2.17.1



From alim.akhtar at samsung.com  Mon Jan 17 04:20:19 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 17 Jan 2022 17:50:19 +0530
Subject: [PATCH 21/23] iio: adc: exynos-adc: Add support for ADC V3
 controller
In-Reply-To: <20220116111939.413ece7e@jic23-huawei>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122452epcas5p201a3a87d0e9c0e9f449a90ed62de1f1c@epcas5p2.samsung.com>
 <20220113121143.22280-22-alim.akhtar@samsung.com>
 <20220116111939.413ece7e@jic23-huawei>
Message-ID: <00b201d80b9c$9a3de160$ceb9a420$@samsung.com>

Hi Jonathan

>-----Original Message-----
>From: Jonathan Cameron [mailto:jic23 at kernel.org]
>Sent: Sunday, January 16, 2022 4:50 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>
>Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; krzysztof.kozlowski at canonical.com;
>s.nawrocki at samsung.com; linux-samsung-soc at vger.kernel.org;
>pankaj.dubey at samsung.com; linux-fsd at tesla.com; linux-
>iio at vger.kernel.org; Tamseel Shams <m.shams at samsung.com>
>Subject: Re: [PATCH 21/23] iio: adc: exynos-adc: Add support for ADC V3
>controller
>
>On Thu, 13 Jan 2022 17:41:41 +0530
>Alim Akhtar <alim.akhtar at samsung.com> wrote:
>
>> Exynos's ADC-V3 has some difference in registers set, number of
>> programmable channels (16 channel) etc. This patch adds support for
>> ADC-V3 controller version.
>>
>> Cc: linux-fsd at tesla.com
>> Cc: jic23 at kernel.org
>> Cc: linux-iio at vger.kernel.org
>> Signed-off-by: Tamseel Shams <m.shams at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>
>Hi Alim,
>
>A few minor suggestions below.  I'm not seeing a binding update though...
>
>I'd also suggest that it would be more appropriate to break this out as a
>separate mini series from the main support so that it can be reviewed and
>merge separately. It's not ideal when a list just gets patch 21 of
>23 with no cover letter etc sent to it.
>
Thanks for the detailed review, I agree, will send as a separate patch set
only related with ADC support.
And addressing rest of your comments in this patch.

>Jonathan
>
>> ---
>>  drivers/iio/adc/exynos_adc.c | 74
>> +++++++++++++++++++++++++++++++++++-
>>  1 file changed, 72 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iio/adc/exynos_adc.c
>> b/drivers/iio/adc/exynos_adc.c index 3b3868aa2533..61752e798fd6 100644
>> --- a/drivers/iio/adc/exynos_adc.c
>> +++ b/drivers/iio/adc/exynos_adc.c
>> @@ -55,6 +55,11 @@
>>  #define ADC_V2_INT_ST(x)	((x) + 0x14)
>>  #define ADC_V2_VER(x)		((x) + 0x20)
>>
>> +/* ADC_V3 register definitions */
>> +#define ADC_V3_DAT(x)			((x) + 0x08)
>> +#define ADC_V3_DAT_SUM(x)		((x) + 0x0C)
>> +#define ADC_V3_DBG_DATA(x)		((x) + 0x1C)
>> +
>>  /* Bit definitions for ADC_V1 */
>>  #define ADC_V1_CON_RES		(1u << 16)
>>  #define ADC_V1_CON_PRSCEN	(1u << 14)
>> @@ -92,6 +97,7 @@
>>
>>  /* Bit definitions for ADC_V2 */
>>  #define ADC_V2_CON1_SOFT_RESET	(1u << 2)
>> +#define ADC_V2_CON1_SOFT_NON_RESET	(1u << 1)
>>
>>  #define ADC_V2_CON2_OSEL	(1u << 10)
>>  #define ADC_V2_CON2_ESEL	(1u << 9)
>> @@ -100,6 +106,7 @@
>>  #define ADC_V2_CON2_ACH_SEL(x)	(((x) & 0xF) << 0)
>>  #define ADC_V2_CON2_ACH_MASK	0xF
>>
>> +#define MAX_ADC_V3_CHANNELS		16
>>  #define MAX_ADC_V2_CHANNELS		10
>>  #define MAX_ADC_V1_CHANNELS		8
>>  #define MAX_EXYNOS3250_ADC_CHANNELS	2
>
>Given we have a mixture of required an unrequired elements in this
structure
>it might be a good idea to add some documentation.  Kernel-doc for the
>whole structure preferred.  Note this isn't necessarily something that
needs
>to be in this patch given the lack of docs predates this and with the
change to
>make
>adc_isr() required that I suggest below things aren't made worse by this
>patch.
>
>> @@ -164,6 +171,7 @@ struct exynos_adc_data {
>>  	void (*exit_hw)(struct exynos_adc *info);
>>  	void (*clear_irq)(struct exynos_adc *info);
>>  	void (*start_conv)(struct exynos_adc *info, unsigned long addr);
>> +	irqreturn_t (*adc_isr)(int irq, void *dev_id);
>>  };
>>
>>  static void exynos_adc_unprepare_clk(struct exynos_adc *info) @@
>> -484,6 +492,59 @@ static const struct exynos_adc_data exynos7_adc_data =
>{
>>  	.start_conv	= exynos_adc_v2_start_conv,
>>  };
>>
>> +static void exynos_adc_v3_init_hw(struct exynos_adc *info) {
>> +	u32 con2;
>> +
>> +	writel(ADC_V2_CON1_SOFT_RESET, ADC_V2_CON1(info->regs));
>> +
>> +	writel(ADC_V2_CON1_SOFT_NON_RESET, ADC_V2_CON1(info-
>>regs));
>> +
>> +	con2 = ADC_V2_CON2_C_TIME(6);
>> +	writel(con2, ADC_V2_CON2(info->regs));
>> +
>> +	/* Enable interrupts */
>> +	writel(1, ADC_V2_INT_EN(info->regs)); }
>> +
>> +static void exynos_adc_v3_exit_hw(struct exynos_adc *info) {
>> +	u32 con2;
>> +
>> +	con2 = readl(ADC_V2_CON2(info->regs));
>> +	con2 &= ~ADC_V2_CON2_C_TIME(7);
>> +	writel(con2, ADC_V2_CON2(info->regs));
>> +
>> +	/* Disable interrupts */
>> +	writel(0, ADC_V2_INT_EN(info->regs)); }
>> +
>> +static irqreturn_t exynos_adc_v3_isr(int irq, void *dev_id) {
>> +	struct exynos_adc *info = (struct exynos_adc *)dev_id;
>
>Shouldn't need the cast as cast from void * to another pointer is always
valid
>in C without the explicit cast.
>
>> +	u32 mask = info->data->mask;
>> +
>> +	info->value = readl(ADC_V3_DAT(info->regs)) & mask;
>> +
>> +	if (info->data->clear_irq)
>> +		info->data->clear_irq(info);
>
>Don't need this currently as v3_isr() is always matched with clear_isr()
being
>provided.  Having the check implies otherwise which is probably not a good
>thing to do until some future device support (maybe) needs it.
>
>> +
>> +	complete(&info->completion);
>> +
>> +	return IRQ_HANDLED;
>> +}
>> +
>> +static const struct exynos_adc_data exynos_adc_v3_adc_data = {
>> +	.num_channels	= MAX_ADC_V3_CHANNELS,
>> +	.mask		= ADC_DATX_MASK, /* 12 bit ADC resolution */
>> +
>> +	.init_hw	= exynos_adc_v3_init_hw,
>> +	.exit_hw	= exynos_adc_v3_exit_hw,
>> +	.clear_irq	= exynos_adc_v2_clear_irq,
>> +	.start_conv	= exynos_adc_v2_start_conv,
>> +	.adc_isr	= exynos_adc_v3_isr,
>> +};
>> +
>>  static const struct of_device_id exynos_adc_match[] = {
>>  	{
>>  		.compatible = "samsung,s3c2410-adc", @@ -518,6 +579,9 @@
>static
>> const struct of_device_id exynos_adc_match[] = {
>>  	}, {
>>  		.compatible = "samsung,exynos7-adc",
>>  		.data = &exynos7_adc_data,
>> +	}, {
>> +		.compatible = "samsung,exynos-adc-v3",
>> +		.data = &exynos_adc_v3_adc_data,
>>  	},
>>  	{},
>>  };
>> @@ -719,6 +783,12 @@ static const struct iio_chan_spec
>exynos_adc_iio_channels[] = {
>>  	ADC_CHANNEL(7, "adc7"),
>>  	ADC_CHANNEL(8, "adc8"),
>>  	ADC_CHANNEL(9, "adc9"),
>> +	ADC_CHANNEL(10, "adc10"),
>> +	ADC_CHANNEL(11, "adc11"),
>> +	ADC_CHANNEL(12, "adc12"),
>> +	ADC_CHANNEL(13, "adc13"),
>> +	ADC_CHANNEL(14, "adc14"),
>> +	ADC_CHANNEL(15, "adc15"),
>>  };
>>
>>  static int exynos_adc_remove_devices(struct device *dev, void *c) @@
>> -885,8 +955,8 @@ static int exynos_adc_probe(struct platform_device
>> *pdev)
>>
>>  	mutex_init(&info->lock);
>>
>> -	ret = request_irq(info->irq, exynos_adc_isr,
>> -					0, dev_name(&pdev->dev), info);
>> +	ret = request_irq(info->irq, info->data->adc_isr ?
info->data->adc_isr
>:
>> +				exynos_adc_isr, 0, dev_name(&pdev->dev),
>info);
>
>I'd rather see the slightly larger change of providing adc_isr for existing
parts
>and the conditional part here going away.
>
>Jonathan
>
>
>>  	if (ret < 0) {
>>  		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n",
>>  							info->irq);




From yong.wu at mediatek.com  Mon Jan 17 04:25:28 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Mon, 17 Jan 2022 20:25:28 +0800
Subject: [PATCH v3 5/7] memory: mtk-smi: Fix the return value for
 clk_bulk_prepare_enable
In-Reply-To: <7370f18b-e273-69f2-1cc9-a42495e04874@canonical.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
 <20220113111057.29918-6-yong.wu@mediatek.com>
 <7370f18b-e273-69f2-1cc9-a42495e04874@canonical.com>
Message-ID: <792f1119b9c848a01e8b8ddd196a1db7acc1f0ae.camel@mediatek.com>

On Mon, 2022-01-17 at 13:01 +0100, Krzysztof Kozlowski wrote:
> On 13/01/2022 12:10, Yong Wu wrote:
> > Function clk_bulk_prepare_enable() returns 0 for success or a
> > negative
> > number for error. Fix this code style issue.
> 
> The message does not really make sense. If negative is returned, then
> the check (ret < 0) was correct.
> 
> I guess you wanted to say that common code style is to check for any
> non-zero return value, just like it's implementation in clk.h does.
> 
> I'll adjust the commit msg when applying.

Thanks for the help.

> 
> > 
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > Reviewed-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > ---
> >  drivers/memory/mtk-smi.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
> > index b883dcc0bbfa..e7b1a22b12ea 100644
> > --- a/drivers/memory/mtk-smi.c
> > +++ b/drivers/memory/mtk-smi.c
> > @@ -480,7 +480,7 @@ static int __maybe_unused
> > mtk_smi_larb_resume(struct device *dev)
> >  	int ret;
> >  
> >  	ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb-
> > >smi.clks);
> > -	if (ret < 0)
> > +	if (ret)
> >  		return ret;
> >  
> >  	/* Configure the basic setting for this larb */
> 
> Best regards,
> Krzysztof

From lijun.kernel at gmail.com  Mon Jan 17 04:30:03 2022
From: lijun.kernel at gmail.com (Jun Li)
Date: Mon, 17 Jan 2022 20:30:03 +0800
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <20220114233904.907918-1-sean.anderson@seco.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
Message-ID: <CAKgpwJUMXk--4EaYOxAAtLJT85mDHRHMihr6n7y1HECN+gmBBw@mail.gmail.com>

Sean Anderson <sean.anderson at seco.com> ?2022?1?15??? 10:11???
>
> This is a rework of patches 3-5 of [1]. It attempts to correctly program
> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
> we no longer need a special property duplicating this configuration,
> snps,ref-clock-period-ns is deprecated.
>
> Please test this! Patches 3/4 in this series have the effect of
> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
> the "ref" clock. I have build tested, but not much else.

DWC3 databook states a *condition* for program those settings:

This field must be programmed to a non-zero value only if
GFLADJ_REFCLK_LPM_SEL is set to '1' or GCTL.SOFITPSYNC is set to '1'.
The value is derived as follows:
FLADJ_REF_CLK_FLADJ=((125000/ref_clk_period_integer)-(125000/ref_clk_period))
* ref_clk_period where
? the ref_clk_period_integer is the integer value of the ref_clk
period got by truncating the decimal (fractional) value that is
programmed in the GUCTL.REF_CLK_PERIOD field.
? the ref_clk_period is the ref_clk period including the fractional value.

So you may need a condition check, with that, only required users
are effected even with "ref" clock specified.

Li Jun

>
> [1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/
>
>
> Sean Anderson (6):
>   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>   usb: dwc3: Get clocks individually
>   usb: dwc3: Calculate REFCLKPER based on reference clock
>   usb: dwc3: Handle fractional reference clocks
>   arm64: dts: zynqmp: Move USB clocks to dwc3 node
>   arm64: dts: ipq6018: Use reference clock to set dwc3 period
>
>  .../devicetree/bindings/usb/snps,dwc3.yaml    |  7 +-
>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  3 +-
>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  4 +-
>  drivers/usb/dwc3/core.c                       | 98 ++++++++++++++++---
>  drivers/usb/dwc3/core.h                       |  6 +-
>  6 files changed, 98 insertions(+), 24 deletions(-)
>
> --
> 2.25.1
>


From krzysztof.adamski at nokia.com  Mon Jan 17 04:31:48 2022
From: krzysztof.adamski at nokia.com (Krzysztof Adamski)
Date: Mon, 17 Jan 2022 13:31:48 +0100
Subject: [PATCH] arm64: move efi_reboot to restart handler
Message-ID: <YeVhtL2gCLkhTPdv@localhost.localdomain>

On EFI enabled arm64 systems, efi_reboot was called before
do_kernel_restart, completely omitting the reset_handlers functionality.
By registering efi_reboot as part of the chain with slightly elevated
priority, we make it run before the default handler but still allow
plugging in other handlers.
Thanks to that, things like gpio_restart, restart handlers in
watchdog_core, mmc or mtds are working on those platforms.

The priority 129 should be high enough as we will likely be the first
one to register on this prio so we will be called before others, like
PSCI handler.

Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>
---
 arch/arm64/kernel/process.c |  7 -------
 arch/arm64/kernel/setup.c   | 21 +++++++++++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..b86ef77bb0c8 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -130,13 +130,6 @@ void machine_restart(char *cmd)
 	local_irq_disable();
 	smp_send_stop();
 
-	/*
-	 * UpdateCapsule() depends on the system being reset via
-	 * ResetSystem().
-	 */
-	if (efi_enabled(EFI_RUNTIME_SERVICES))
-		efi_reboot(reboot_mode, NULL);
-
 	/* Now call the architecture specific reboot code. */
 	do_kernel_restart(cmd);
 
diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f70573928f1b..5fa95980ba73 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -12,6 +12,7 @@
 #include <linux/stddef.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
+#include <linux/reboot.h>
 #include <linux/initrd.h>
 #include <linux/console.h>
 #include <linux/cache.h>
@@ -298,6 +299,24 @@ u64 cpu_logical_map(unsigned int cpu)
 	return __cpu_logical_map[cpu];
 }
 
+static int efi_restart(struct notifier_block *nb, unsigned long action,
+		       void *data)
+{
+	/*
+	 * UpdateCapsule() depends on the system being reset via
+	 * ResetSystem().
+	 */
+	if (efi_enabled(EFI_RUNTIME_SERVICES))
+		efi_reboot(reboot_mode, NULL);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block efi_restart_nb = {
+	.notifier_call = efi_restart,
+	.priority = 129,
+};
+
 void __init __no_sanitize_address setup_arch(char **cmdline_p)
 {
 	setup_initial_init_mm(_stext, _etext, _edata, _end);
@@ -346,6 +365,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
 
 	paging_init();
 
+	register_restart_handler(&efi_restart_nb);
+
 	acpi_table_upgrade();
 
 	/* Parse the ACPI tables for possible boot-time configuration */
-- 
2.34.1



From cristian.marussi at arm.com  Mon Jan 17 04:40:30 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 17 Jan 2022 12:40:30 +0000
Subject: [PATCH v8 11/11] clk: scmi: Support atomic clock enable/disable
 API
In-Reply-To: <20220117103100.c6ltxnz4iqmbc4b5@bogus>
References: <20211220195646.44498-1-cristian.marussi@arm.com>
 <20211220195646.44498-12-cristian.marussi@arm.com>
 <20220114230839.ABD63C36AE9@smtp.kernel.org>
 <20220117103100.c6ltxnz4iqmbc4b5@bogus>
Message-ID: <20220117124029.GD6113@e120937-lin>

On Mon, Jan 17, 2022 at 10:31:00AM +0000, Sudeep Holla wrote:
> On Fri, Jan 14, 2022 at 03:08:37PM -0800, Stephen Boyd wrote:
> > Quoting Cristian Marussi (2021-12-20 11:56:46)
> > > Support also atomic enable/disable clk_ops beside the bare non-atomic one
> > > (prepare/unprepare) when the underlying SCMI transport is configured to
> > > support atomic transactions for synchronous commands.
> > > 

Hi,

> > > Cc: Michael Turquette <mturquette at baylibre.com>
> > > Cc: Stephen Boyd <sboyd at kernel.org>
> > > Cc: linux-clk at vger.kernel.org
> > > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > > ---
> > > NOTE THAT STILL THERE'S NO FINE GRAIN CONTROL OVER SELECTION
> > > OF WHICH CLOCK DEVICES CAN SUPPORT ATOMIC AND WHICH SHOULD NOT
> > > BASED ON CLOCK DEVICES ENABLE LATENCY.
> > > THIS HAS STILL TO BE ADDED IN SCMI PROTOCOL SPEC.
> > 
> > Why are you yelling on the internet? :-) I guess I need to ack this.
> >
> 

Sorry I did not mean to yell really, just to warn partners using this.

> It is for the partners who request such changes. We are trying to prototype
> and share the code and ask for feedback before we finalise the specification.
> 
> In fact it is other way around for you ?. Not to ack as it is not yet final
> ?. At least I need to wait until the spec contents are finalised before I
> can merge with your ack ?. But I agree RFC would have indicated that along
> with the above background instead of *yelling*. Cristian assumed everyone
> is aware of the content as quite a few are involved in offline discussions.
> 
> > Acked-by: Stephen Boyd <sboyd at kernel.org>
> 
> Thanks anyways, will use it if nothing changes.
> 

As Sudeep said, V8 it is indeed not the final version which is going to
be posted soon after the merge-windows (without yelling :D) and which it
will be indeed still marked as RFC since it does include a new protocol
feature which is still under review and not published.

Sorry for the noise.

Thanks,
Cristian


From alim.akhtar at samsung.com  Mon Jan 17 04:42:52 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 17 Jan 2022 18:12:52 +0530
Subject: [PATCH 20/23] dt-bindings: iio: adc: exynos-adc: Add ADC-V3
 variant
In-Reply-To: <20220117094728.000051b8@Huawei.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122447epcas5p266d44c8df143229d22dfa700c285a786@epcas5p2.samsung.com>
 <20220113121143.22280-21-alim.akhtar@samsung.com>
 <75ae8b8c-e416-5007-b995-f1317ef207d4@canonical.com>
 <20220117094728.000051b8@Huawei.com>
Message-ID: <00b301d80b9f$c06304d0$41290e70$@samsung.com>



>-----Original Message-----
>From: Jonathan Cameron [mailto:Jonathan.Cameron at Huawei.com]
>Sent: Monday, January 17, 2022 3:17 PM
>To: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>Cc: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org; soc at kernel.org;
>linux-clk at vger.kernel.org; devicetree at vger.kernel.org; olof at lixom.net;
>linus.walleij at linaro.org; catalin.marinas at arm.com; robh+dt at kernel.org;
>s.nawrocki at samsung.com; linux-samsung-soc at vger.kernel.org;
>pankaj.dubey at samsung.com; linux-fsd at tesla.com; Tamseel Shams
><m.shams at samsung.com>
>Subject: Re: [PATCH 20/23] dt-bindings: iio: adc: exynos-adc: Add ADC-V3
>variant
>
>On Thu, 13 Jan 2022 14:32:12 +0100
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
>
>> On 13/01/2022 13:11, Alim Akhtar wrote:
>> > This patch adds a new compatible string for exynos's ADC-V3 variant.
>> >
>> > Cc: linux-fsd at tesla.com
>> > Signed-off-by: Tamseel Shams <m.shams at samsung.com>
>> > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>
>Please cc linux-iio at vger.kernel.org for next version...
>
Noted, will separate out these patches from the original series and send.
Thanks

>> > ---
>> >  .../devicetree/bindings/iio/adc/samsung,exynos-adc.yaml          | 1 +
>> >  1 file changed, 1 insertion(+)
>> >
>> > diff --git
>> > a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
>> > b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
>> > index 81c87295912c..9303053759ca 100644
>> > ---
>> > a/Documentation/devicetree/bindings/iio/adc/samsung,exynos-adc.yaml
>> > +++ b/Documentation/devicetree/bindings/iio/adc/samsung,exynos-
>adc.y
>> > +++ aml
>> > @@ -14,6 +14,7 @@ properties:
>> >      enum:
>> >        - samsung,exynos-adc-v1                 # Exynos5250
>> >        - samsung,exynos-adc-v2
>> > +      - samsung,exynos-adc-v3
>>
>> Please use SoC-specific compatible. IP block versions are tricky because:
>> 1. Documentation/datasheet mentioning which SoC has which block
>> version are not public.
>> 2. Neither are public the datasheets for ADC blocks.
>> 3. The versioning of IP blocks can be inaccurate.
>>
>>
>> Best regards,
>> Krzysztof
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> https://protect2.fireeye.com/v1/url?k=9dd88c77-fca326ff-9dd90738-74fe4
>> 860018a-343cb1b0388f1560&q=1&e=61045889-dd66-417f-b142-
>9e85b39f1676&u=
>> http%3A%2F%2Flists.infradead.org%2Fmailman%2Flistinfo%2Flinux-arm-
>kern
>> el




From Sergiy_Kibrik at epam.com  Mon Jan 17 04:32:51 2022
From: Sergiy_Kibrik at epam.com (Sergiy Kibrik)
Date: Mon, 17 Jan 2022 12:32:51 +0000
Subject: [PATCH v3 2/2] arm/xen: don't use xen DMA ops when the device is
 protected by an IOMMU
In-Reply-To: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
Message-ID: <20220117123251.140867-3-Sergiy_Kibrik@epam.com>

Only Xen is able to know if a device can safely avoid to use xen-swiotlb.
However since Xen links FDT nodes of protected devices to special dummy
xen-iommu node we can use that information to decide whether
xen-swiotlb is needed.

Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik at epam.com>
---
Changelog:

v3: rebased over master & documented DT binding
    https://lists.xenproject.org/archives/html/xen-devel/2021-12/msg01755.html

v2: re-use common iommu dt bindings to let guests know which devices are protected:
    https://lists.xenproject.org/archives/html/xen-devel/2021-10/msg00073.html

 arch/arm/mm/dma-mapping.c   | 2 +-
 arch/arm/xen/enlighten.c    | 9 +++++++++
 arch/arm64/mm/dma-mapping.c | 2 +-
 include/xen/swiotlb-xen.h   | 1 +
 4 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 4b61541853ea..73495f0b0a4d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2286,7 +2286,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 	set_dma_ops(dev, dma_ops);
 
 #ifdef CONFIG_XEN
-	if (xen_initial_domain())
+	if (xen_initial_domain() && !xen_is_protected_device(dev))
 		dev->dma_ops = &xen_swiotlb_dma_ops;
 #endif
 	dev->archdata.dma_ops_setup = true;
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index 7619fbffcea2..0c2f0b77c8b9 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -63,6 +63,15 @@ static __read_mostly unsigned int xen_events_irq;
 uint32_t xen_start_flags;
 EXPORT_SYMBOL(xen_start_flags);
 
+bool xen_is_protected_device(struct device *dev)
+{
+	struct fwnode_handle *fwnode =
+		fwnode_find_reference(dev_fwnode(dev), "iommus", 0) ;
+	if (IS_ERR(fwnode))
+		return false;
+	return of_device_is_compatible(to_of_node(fwnode), "xen,iommu-el2-v1");
+}
+
 int xen_unmap_domain_gfn_range(struct vm_area_struct *vma,
 			       int nr, struct page **pages)
 {
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 6719f9efea09..2f2b5921bf68 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -53,7 +53,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
 		iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
 
 #ifdef CONFIG_XEN
-	if (xen_swiotlb_detect())
+	if (xen_swiotlb_detect() && !xen_is_protected_device(dev))
 		dev->dma_ops = &xen_swiotlb_dma_ops;
 #endif
 }
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index b3e647f86e3e..f3d805f2246f 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -9,6 +9,7 @@ void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
 			  size_t size, enum dma_data_direction dir);
 void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
 			     size_t size, enum dma_data_direction dir);
+bool xen_is_protected_device(struct device *dev);
 
 int xen_swiotlb_init(void);
 void __init xen_swiotlb_init_early(void);
-- 
2.25.1



From Sergiy_Kibrik at epam.com  Mon Jan 17 04:32:49 2022
From: Sergiy_Kibrik at epam.com (Sergiy Kibrik)
Date: Mon, 17 Jan 2022 12:32:49 +0000
Subject: [PATCH v3 0/2] Avoid using Xen DMA ops when the device is protected
 by an IOMMU
Message-ID: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>

At the moment, dom0 can't distinguish which devices are protected by
IOMMU and which are not. In some cases, this can cause swiotlb bounce
buffer use for DMA addresses above 32 bits, which in turn can lead
to poor performance.

Previous discussions at [1,2] agreed upon passing info about IOMMU via
device tree. This series does that in a way consistent with existing iommu bindings.

[1] https://lore.kernel.org/all/1392913234-25429-1-git-send-email-julien.grall__16109.9684810781$1392913341$gmane$org at linaro.org/
[2] https://lore.kernel.org/all/cover.1633106362.git.roman_skakun at epam.com/

Sergiy Kibrik (2):
  dt-bindings: arm: xen: document Xen iommu device
  arm/xen: don't use xen DMA ops when the device is protected by an
    IOMMU

 Documentation/devicetree/bindings/arm/xen.txt | 26 +++++++++++++++++++
 arch/arm/mm/dma-mapping.c                     |  2 +-
 arch/arm/xen/enlighten.c                      |  9 +++++++
 arch/arm64/mm/dma-mapping.c                   |  2 +-
 include/xen/swiotlb-xen.h                     |  1 +
 5 files changed, 38 insertions(+), 2 deletions(-)

Cc: Stefano Stabellini <sstabellini at kernel.org>
Cc: Julien Grall <julien at xen.org>
Cc: Oleksandr Tyshchenko <olekstysh at gmail.com>
Cc: devicetree at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org

-- 
2.25.1



From Sergiy_Kibrik at epam.com  Mon Jan 17 04:32:50 2022
From: Sergiy_Kibrik at epam.com (Sergiy Kibrik)
Date: Mon, 17 Jan 2022 12:32:50 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu device
In-Reply-To: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
Message-ID: <20220117123251.140867-2-Sergiy_Kibrik@epam.com>

In IOMMU-capable system hypervisor usually takes over IOMMU control.
Generally guest domains don't need to care about IOMMU management and take any
extra actions. Yet in some cases a knowledge about which device is protected
may be useful for privileged domain.

In compliance with iommu bindings this can be achieved with device-level
iommus property specified with dummy Xen iommu device.

Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik at epam.com>
---
 Documentation/devicetree/bindings/arm/xen.txt | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/xen.txt b/Documentation/devicetree/bindings/arm/xen.txt
index db5c56db30ec..98efa95c0d1b 100644
--- a/Documentation/devicetree/bindings/arm/xen.txt
+++ b/Documentation/devicetree/bindings/arm/xen.txt
@@ -58,3 +58,29 @@ Documentation/arm/uefi.rst, which are provided by the regular UEFI stub. However
 they differ because they are provided by the Xen hypervisor, together with a set
 of UEFI runtime services implemented via hypercalls, see
 http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
+
+* XEN IOMMU device
+
+In compliance with iommu bindings Xen virtual IOMMU device node represents
+hypervisor-managed IOMMU [1]. Platform devices specified as IOMMU masters of
+this xen-iommu device are protected by hypervisor-managed platform IOMMU.
+
+Required properties:
+
+- compatible:	Should be "xen,iommu-el2-v1"
+- #iommu-cells: must be 0
+
+Example:
+
+xen-iommu {
+	compatible = "xen,iommu-el2-v1";
+	#iommu-cells = <0>;
+};
+
+video at fe001000 {
+	...
+	/* this platform device is IOMMU-protected by hypervisor */
+	iommus = <&xen-iommu 0x0>;
+};
+
+[1] Documentation/devicetree/bindings/iommu/iommu.txt
-- 
2.25.1



From german.gomez at arm.com  Mon Jan 17 04:44:30 2022
From: german.gomez at arm.com (German Gomez)
Date: Mon, 17 Jan 2022 12:44:30 +0000
Subject: [RFC PATCH 0/2] perf: arm_spe: Fix consistency of CONTEXT packets in
 SPE driver
Message-ID: <20220117124432.3119132-1-german.gomez@arm.com>

Applies a couple of small changes to the arm_spe_pmu driver.

We are seeing context packets in an inconsistent number of SPE records
even  when the perf-tool runs without the needed capabilities. This is
fixed in [1/2].

We're also allowing CONTEXT packets to be collected in per-cpu events in
[2/2].

I'm sending as an RFC because it's the first time I change driver code.
Also I'm not 100% sure of the approach in [2/2] (from a security and/or
implementation standpoint).

Thanks,
German

- [PATCH 1/2] Fixes the consistency issue with the context packets.
- [PATCH 2/2] Enables context packets in per-cpu events.

German Gomez (2):
  perf: arm_spe: Fix consistency of PMSCR register bit CX
  perf: arm_spe: Enable CONTEXT packets in SPE traces if the profiler
    runs in CPU mode.

 drivers/perf/arm_spe_pmu.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

-- 
2.25.1



From german.gomez at arm.com  Mon Jan 17 04:44:31 2022
From: german.gomez at arm.com (German Gomez)
Date: Mon, 17 Jan 2022 12:44:31 +0000
Subject: [RFC PATCH 1/2] perf: arm_spe: Fix consistency of PMSCR register bit
 CX
In-Reply-To: <20220117124432.3119132-1-german.gomez@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
Message-ID: <20220117124432.3119132-2-german.gomez@arm.com>

The arm_spe_pmu driver will enable the CX bit of the PMSCR register in
order to add CONTEXT packets into the traces if the owner of the perf
event runs with capabilities CAP_PERFMON or CAP_SYS_ADMIN.

The value of the bit is computed in the arm_spe_event_to_pmscr function
[1], and the check for capabilities happens in [2] in the pmu init
callback. This suggests that the value of the CX bit should remain
consistent for the duration of the perf session.

However, the function arm_spe_event_to_pmscr may be called later during
the start callback [3] when the "current" process is not the owner of
the perf session, so the CX bit is currently not consistent. Consider
the following example:

  1. Run a process in the background with capability CAP_SYS_ADMIN in CPU0.

    $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
    [3] 3806

  2. Begin a perf session _without_ capabilities (we shouldn't see CONTEXT packets).

    $ perf record -e arm_spe_0// -C0 -- sleep 1
    $ perf report -D | grep CONTEXT
    .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
    [...]

As can be seen, the traces begin showing CONTEXT packets when the pid is
0xedf (3807). This happens because the pmu start callback is run when
the current process is not the owner of the perf session, so the CX
register bit is set.

One way to fix this is by caching the value of the CX bit during the
initialization of the PMU event, so that it remains consistent for the
duration of the session.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/perf/arm_spe_pmu.c?h=v5.16#n275
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/perf/arm_spe_pmu.c?h=v5.16#n713
[3]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/perf/arm_spe_pmu.c?h=v5.16#n751

Signed-off-by: German Gomez <german.gomez at arm.com>
---
 drivers/perf/arm_spe_pmu.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index d44bcc29d..8515bf85c 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -57,6 +57,7 @@ struct arm_spe_pmu {
 	u16					pmsver;
 	u16					min_period;
 	u16					counter_sz;
+	bool					pmscr_cx;
 
 #define SPE_PMU_FEAT_FILT_EVT			(1UL << 0)
 #define SPE_PMU_FEAT_FILT_TYP			(1UL << 1)
@@ -260,6 +261,7 @@ static const struct attribute_group *arm_spe_pmu_attr_groups[] = {
 static u64 arm_spe_event_to_pmscr(struct perf_event *event)
 {
 	struct perf_event_attr *attr = &event->attr;
+	struct arm_spe_pmu *spe_pmu = to_spe_pmu(event->pmu);
 	u64 reg = 0;
 
 	reg |= ATTR_CFG_GET_FLD(attr, ts_enable) << SYS_PMSCR_EL1_TS_SHIFT;
@@ -272,7 +274,7 @@ static u64 arm_spe_event_to_pmscr(struct perf_event *event)
 	if (!attr->exclude_kernel)
 		reg |= BIT(SYS_PMSCR_EL1_E1SPE_SHIFT);
 
-	if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable())
+	if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && spe_pmu->pmscr_cx)
 		reg |= BIT(SYS_PMSCR_EL1_CX_SHIFT);
 
 	return reg;
@@ -709,10 +711,10 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
+	spe_pmu->pmscr_cx = perfmon_capable();
 	reg = arm_spe_event_to_pmscr(event);
 	if (!perfmon_capable() &&
 	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
-		    BIT(SYS_PMSCR_EL1_CX_SHIFT) |
 		    BIT(SYS_PMSCR_EL1_PCT_SHIFT))))
 		return -EACCES;
 
-- 
2.25.1



From german.gomez at arm.com  Mon Jan 17 04:44:32 2022
From: german.gomez at arm.com (German Gomez)
Date: Mon, 17 Jan 2022 12:44:32 +0000
Subject: [RFC PATCH 2/2] perf: arm_spe: Enable CONTEXT packets in SPE traces
 if the profiler runs in CPU mode.
In-Reply-To: <20220117124432.3119132-1-german.gomez@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
Message-ID: <20220117124432.3119132-3-german.gomez@arm.com>

Enable CONTEXT packets in SPE traces if the profiler runs in CPU mode.
This is no less permissive than the existing behavior for the following
reason:

If perf_event_paranoid <= 0, then non perfmon_capable() users can open
a per-CPU event. With a per-CPU event, unpriviledged users are allowed
to profile _all_ processes, even ones owned by root.

Without this change, users could see kernel addresses, root processes,
etc, but not gather the PIDs of those processes. The PID is probably the
least sensitive of all the information.

It would be more idiomatic to check the perf_event_paranoid level with
perf_allow_cpu(), but this function is not exported so cannot be used
from a module. Looking for cpu != -1 is the indirect way of checking
the same thing as it could never get to arm_spe_pmu_event_init() without
perf_event_paranoid <= 0.

Co-authored-by: James Clark <james.clark at arm.com>
Signed-off-by: German Gomez <german.gomez at arm.com>
---
 drivers/perf/arm_spe_pmu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
index 8515bf85c..7d9a7fa4f 100644
--- a/drivers/perf/arm_spe_pmu.c
+++ b/drivers/perf/arm_spe_pmu.c
@@ -711,7 +711,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
 	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
 		return -EOPNOTSUPP;
 
-	spe_pmu->pmscr_cx = perfmon_capable();
+	spe_pmu->pmscr_cx = perfmon_capable() || (event->cpu != -1);
 	reg = arm_spe_event_to_pmscr(event);
 	if (!perfmon_capable() &&
 	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Mon Jan 17 04:49:18 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 13:49:18 +0100
Subject: [PATCH v2 05/11] arm64: defconfig: rebuild default configuration
In-Reply-To: <a5cfdd2ea149490abeb481c7a85d59019ea3c620.camel@toradex.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-6-marcel@ziswiler.com>
 <060a9f66-fc00-2247-46f2-1c700d0e9bf3@canonical.com>
 <a5cfdd2ea149490abeb481c7a85d59019ea3c620.camel@toradex.com>
Message-ID: <e441ee41-485f-b940-76f0-886d2f3ca942@canonical.com>

On 17/01/2022 13:05, Marcel Ziswiler wrote:
> On Sat, 2022-01-15 at 18:02 +0100, Krzysztof Kozlowski wrote:
>> On 14/01/2022 15:15, Marcel Ziswiler wrote:
>>> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>>>
>>> Run "make defconfig; make savedefconfig" to rebuild defconfig.
>>>
>>> This re-ordered the following configuration options:
>>>
>>> CONFIG_BPF_JIT=y
>>> CONFIG_ARM_SCMI_PROTOCOL=y
>>> CONFIG_ARM_SCPI_PROTOCOL=y
>>> CONFIG_RASPBERRYPI_FIRMWARE=y
>>> CONFIG_INTEL_STRATIX10_SERVICE=y
>>> CONFIG_INTEL_STRATIX10_RSU=m
>>> CONFIG_EFI_CAPSULE_LOADER=y
>>> CONFIG_IMX_SCU=y
>>> CONFIG_IMX_SCU_PD=y
>>> CONFIG_CAN_FLEXCAN=m
>>> CONFIG_PCIE_LAYERSCAPE_GEN4=y
>>> CONFIG_MTK_DEVAPC=m
>>> CONFIG_SPI_CADENCE_QUADSPI=y
>>> CONFIG_MDIO_BUS_MUX_MMIOREG=y
>>> CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
>>> CONFIG_MESON_GXL_PHY=m
>>> CONFIG_QCOM_CPR=y
>>> CONFIG_ROCKCHIP_IODOMAIN=y
>>> CONFIG_SENSORS_ARM_SCMI=y
>>> CONFIG_QORIQ_THERMAL=m
>>> CONFIG_SUN8I_THERMAL=y
>>> CONFIG_TEGRA_BPMP_THERMAL=m
>>> CONFIG_ARM_SMC_WATCHDOG=y
>>> CONFIG_VIDEO_QCOM_CAMSS=m
>>> CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
>>> CONFIG_DRM_NWL_MIPI_DSI=m
>>> CONFIG_DRM_LONTIUM_LT9611UXC=m
>>> CONFIG_SND_SOC_IMX_AUDMIX=m
>>> CONFIG_TYPEC_HD3SS3220=m
>>> CONFIG_COMMON_CLK_SCMI=y
>>> CONFIG_IPQ_GCC_8074=y
>>> CONFIG_SM_DISPCC_8250=y
>>> CONFIG_QCOM_WCNSS_CTRL=m
>>> CONFIG_ARCH_R8A774A1=y
>>> CONFIG_ARCH_R8A774B1=y
>>> CONFIG_ARCH_R8A774C0=y
>>> CONFIG_ARCH_R8A774E1=y
>>> CONFIG_ARCH_R8A77995=y
>>> CONFIG_ARCH_R8A77990=y
>>> CONFIG_ARCH_R8A77965=y
>>> CONFIG_ARCH_R8A77970=y
>>> CONFIG_HISI_PMU=y
>>> CONFIG_QCOM_QFPROM=y
>>> CONFIG_MUX_MMIO=y
>>
>> Thanks for the changes.
>> The best would be to have a separate patch only for re-ordering.
> 
> Yes, from a review perspective that makes sense. Will do so in v3.
> 
>>> And dropped the following configuration options which are nowaday's
>>> already enabled (resp. disabled) by default:
>>>
>>> CONFIG_MEMCG_SWAP=y
>>> CONFIG_SECCOMP=y
>>
>> Is it? I tried now on next-20220114 and it is still user-selectable and
>> not chosen by anything.
> 
> Hm, strange. I guess, it is due to this whole patch series, given its i.MX main focus, being based on Shawn's
> for-next branch. Maybe for such defconfig changes it would be better to base them on something else? Not sure,
> who will ultimately pull such changes. Any suggestion?

I don't think there is a one nice solution, fit-for-all.

Consider a defconfig selecting FOO and BAR, plus Kconfig like:
config FOO
	depends on BAR

If you run savedefconfig on arm-soc next branch, there is a chance that
in parallel someone else will adjust the Kconfig in some other tree,
based on Linus' master. That person removes "depends on BAR" above and
notices that FOO is mentioned in defconfig, so no need to update defconfig.

However your savedefconfig commit will exactly remove the FOO from
defconfig, because there is no reason for it to be. After merging to
Linus - FOO is gone from defconfig.

Another approach - you base your savedefconfig on linux-next. This
should solve the problem above, except that such commit might not apply
on the maintainer's tree.

Therefore recommendation is to not run savedefconfig or run it very
carefully, for example explaining why each option is being removed. I
was doing it in the past, but it's quite time consuming:

https://lore.kernel.org/linux-arm-kernel/1500270596-22384-1-git-send-email-krzk at kernel.org/

and earlier set:
https://lore.kernel.org/linux-arm-kernel/20170608161049.12421-1-krzk at kernel.org/

> 
>>> CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
>>> CONFIG_QCOM_SCM=y
>>> # CONFIG_BT_HS is not set
>>> CONFIG_FSL_MC_BUS=y
>>> CONFIG_MEDIA_CONTROLLER=y
>>> CONFIG_VIDEO_V4L2_SUBDEV_API=y
>>> CONFIG_SND_SOC_FSL_SAI=m
>>> CONFIG_USB_CONN_GPIO=m
>>> CONFIG_USB_XHCI_PCI=m
>>> CONFIG_MFD_CROS_EC_DEV=y
>>> CONFIG_COMMON_CLK_ZYNQMP=y
>>> CONFIG_SDM_GCC_845=y
>>> CONFIG_SM_GCC_8150=y
>>> CONFIG_SM_GCC_8250=y
>>> CONFIG_SLIMBUS=m
>>> CONFIG_INTERCONNECT=y
>>> CONFIG_CONFIGFS_FS=y
>>
>> All three above are still user-selectable, so please leave them. It is
>> redundant, but there is no guarantee that something selecting a
>> user-visible symbol will stop selecting it. IOW, user-visible symbols
>> should be still chosen by defconfigs if they really want them.
> 
> Well, but even if they are already enabled anyway? What is the point of savedefconfig then resp. you are saying
> that the commited defconfigs should not be generated using savedefconfig? That sounds rather confusing to me.

Yes, it's confusing. savedefconfig is too aggressive - it strips
everything which is not strictly necessary now. However there is no
guarantee that current select of some option, thus stripped out that
option via savedefconfig, will stay there forever.

If CONFIG_XXX is not user-selectable, then when someone removes the
"select XXX", it *is expected* to modify the defconfigs to add back this
XXX.

However it turns out that some developers assume that there is no such
requirement of re-adding XXX to defconfig, if XXX was user-selectable in
the first place.


> 
>> See for example commit a2315d3aea59 ("ARM: exynos_defconfig: Restore
>> debugfs support") for rationale why we need to keep them.
> 
> Okay, I see what you mean as in relation to above mentioned commit but then any change to Kconfig dependencies
> can ultimately change the behaviour of previous configs unless they are complete ones (or were just lucky to
> include whatever stuff that changed). But how should one now know which of them zillions of user-selectable
> options should be added to such "more robust" defconfigs?

No clue... :) Except maybe do not remove existing ones.

> 
> I suggest a better approach might be to have some CI which validates defconfig changes. That way one could
> easily track stuff disappearing and could at that point explicitly enable it again.

Yes, that makes sense. One defines the expected symbols to have and CI
validates whether they are enabled. We have something like this (called
annotations) in our Ubuntu configs - we store a list of config options
were are interested in and detect when they change.

Another approach is to use specialized fragments.

The benefits of such solutions is that they also document why such
option was chosen in the first place (what I was also asking from your
patches here at beginning and thanks for fixing this).

Best regards,
Krzysztof


From alexander.sverdlin at nokia.com  Mon Jan 17 04:44:41 2022
From: alexander.sverdlin at nokia.com (Alexander Sverdlin)
Date: Mon, 17 Jan 2022 13:44:41 +0100
Subject: [PATCH] arm64: move efi_reboot to restart handler
In-Reply-To: <YeVhtL2gCLkhTPdv@localhost.localdomain>
References: <YeVhtL2gCLkhTPdv@localhost.localdomain>
Message-ID: <c92e2db9-00b4-8800-e800-046d564f52d9@nokia.com>

Hi!

On 17/01/2022 13:31, Krzysztof Adamski wrote:
> On EFI enabled arm64 systems, efi_reboot was called before
> do_kernel_restart, completely omitting the reset_handlers functionality.
> By registering efi_reboot as part of the chain with slightly elevated
> priority, we make it run before the default handler but still allow
> plugging in other handlers.
> Thanks to that, things like gpio_restart, restart handlers in
> watchdog_core, mmc or mtds are working on those platforms.
> 
> The priority 129 should be high enough as we will likely be the first
> one to register on this prio so we will be called before others, like
> PSCI handler.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>

Reviewed-by: Alexander Sverdlin <alexander.sverdlin at nokia.com>

> ---
>  arch/arm64/kernel/process.c |  7 -------
>  arch/arm64/kernel/setup.c   | 21 +++++++++++++++++++++
>  2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..b86ef77bb0c8 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>  	local_irq_disable();
>  	smp_send_stop();
>  
> -	/*
> -	 * UpdateCapsule() depends on the system being reset via
> -	 * ResetSystem().
> -	 */
> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
> -		efi_reboot(reboot_mode, NULL);
> -
>  	/* Now call the architecture specific reboot code. */
>  	do_kernel_restart(cmd);
>  
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index f70573928f1b..5fa95980ba73 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -12,6 +12,7 @@
>  #include <linux/stddef.h>
>  #include <linux/ioport.h>
>  #include <linux/delay.h>
> +#include <linux/reboot.h>
>  #include <linux/initrd.h>
>  #include <linux/console.h>
>  #include <linux/cache.h>
> @@ -298,6 +299,24 @@ u64 cpu_logical_map(unsigned int cpu)
>  	return __cpu_logical_map[cpu];
>  }
>  
> +static int efi_restart(struct notifier_block *nb, unsigned long action,
> +		       void *data)
> +{
> +	/*
> +	 * UpdateCapsule() depends on the system being reset via
> +	 * ResetSystem().
> +	 */
> +	if (efi_enabled(EFI_RUNTIME_SERVICES))
> +		efi_reboot(reboot_mode, NULL);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block efi_restart_nb = {
> +	.notifier_call = efi_restart,
> +	.priority = 129,
> +};
> +
>  void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  {
>  	setup_initial_init_mm(_stext, _etext, _edata, _end);
> @@ -346,6 +365,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  
>  	paging_init();
>  
> +	register_restart_handler(&efi_restart_nb);
> +
>  	acpi_table_upgrade();
>  
>  	/* Parse the ACPI tables for possible boot-time configuration */

-- 
Best regards,
Alexander Sverdlin.


From mark.rutland at arm.com  Mon Jan 17 05:05:54 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 13:05:54 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220117121557.GA87485@C02TD0UTHF1T.local>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
 <20220114181247.7b366f45@donnerap.cambridge.arm.com>
 <20220117121557.GA87485@C02TD0UTHF1T.local>
Message-ID: <20220117130554.GB87485@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 12:15:57PM +0000, Mark Rutland wrote:
> On Fri, Jan 14, 2022 at 06:12:47PM +0000, Andre Przywara wrote:
> > On Fri, 14 Jan 2022 10:56:46 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi Mark,
> 
> Hi Andre,
 
> > > +
> > > +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > > +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))

> > > -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
> > >  
> > >  #ifdef KERNEL_32
> > >  /* 32-bit kernel decompressor uses CP15 barriers */
> > > #define SCTLR_EL1_KERNEL        (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
> > 
> > So I wonder if this actually works? The ARMv7 version of SCTLR
> > differs in some bits from both the ARMv8 AArch32 version and more
> > importantly the AArch64 version.

> > I had troubles the other day running the
> > arm32 Linux kernel decompressor with some ARMv8 SCTLR_EL1 reset value. The
> > decompressor code does only read-modify-write of SCTLR (probably to
> > cover multiple architecture revisions), so some bits might stay wrong. In
> > particular I think having bits 28 and 29 set caused problems.
> > By looking at the ARMv7 ARM and with experimentation I came up
> > with 0x00c00878 as a safe and working value.

Having re-read all of this, I believe you're right; I'll rework the
AArch32-kernel SCTLR_EL1_KERNEL to not use the AArch64 bit definitions,
and I'll add some commentary explaining that we're writing to the AArch32
format.

> > Shall we have a separate reset value for 32bit?

Assuming you meant to alter the SCTLR_ELx_KERNEL definition, yes.

The idea of splitting the SCTLR_ELx_RESET and SCTLR_ELx_KERNEL
definitions was that the former would be whatever the boot-wrapper
needed to run at ELx, and the latter was whatever we must initialize for
the kernel to run at ELx, so I don't want to put the AArch32 kernel bits
into SCTLR_EL1_RESET.

My only remaining concern is exactly what we must initialize. If there's
any documentation we can refer to, that'd be great, otherwise I'll dig
through your prior suggestion.

Thanks,
Mark.


From mark.rutland at arm.com  Mon Jan 17 05:10:56 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 13:10:56 +0000
Subject: [PATCH] arm64: move efi_reboot to restart handler
In-Reply-To: <YeVhtL2gCLkhTPdv@localhost.localdomain>
References: <YeVhtL2gCLkhTPdv@localhost.localdomain>
Message-ID: <20220117131056.GC87485@C02TD0UTHF1T.local>

Hi,

On Mon, Jan 17, 2022 at 01:31:48PM +0100, Krzysztof Adamski wrote:
> On EFI enabled arm64 systems, efi_reboot was called before
> do_kernel_restart, completely omitting the reset_handlers functionality.
> By registering efi_reboot as part of the chain with slightly elevated
> priority, we make it run before the default handler but still allow
> plugging in other handlers.
> Thanks to that, things like gpio_restart, restart handlers in
> watchdog_core, mmc or mtds are working on those platforms.
> 
> The priority 129 should be high enough as we will likely be the first
> one to register on this prio so we will be called before others, like
> PSCI handler.

I apprecaiate that this is kinda nice for consistency, but if adds more
lines and reduces certainty down to "likely", neither of which seem
ideal.

What do we gain by changing this? e.g. does this enable some further
rework?

Do we actually need to change this?

> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>
> ---
>  arch/arm64/kernel/process.c |  7 -------
>  arch/arm64/kernel/setup.c   | 21 +++++++++++++++++++++
>  2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..b86ef77bb0c8 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>  	local_irq_disable();
>  	smp_send_stop();
>  
> -	/*
> -	 * UpdateCapsule() depends on the system being reset via
> -	 * ResetSystem().
> -	 */
> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
> -		efi_reboot(reboot_mode, NULL);
> -
>  	/* Now call the architecture specific reboot code. */
>  	do_kernel_restart(cmd);
>  
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index f70573928f1b..5fa95980ba73 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -12,6 +12,7 @@
>  #include <linux/stddef.h>
>  #include <linux/ioport.h>
>  #include <linux/delay.h>
> +#include <linux/reboot.h>
>  #include <linux/initrd.h>
>  #include <linux/console.h>
>  #include <linux/cache.h>
> @@ -298,6 +299,24 @@ u64 cpu_logical_map(unsigned int cpu)
>  	return __cpu_logical_map[cpu];
>  }
>  
> +static int efi_restart(struct notifier_block *nb, unsigned long action,
> +		       void *data)
> +{
> +	/*
> +	 * UpdateCapsule() depends on the system being reset via
> +	 * ResetSystem().
> +	 */
> +	if (efi_enabled(EFI_RUNTIME_SERVICES))
> +		efi_reboot(reboot_mode, NULL);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block efi_restart_nb = {
> +	.notifier_call = efi_restart,
> +	.priority = 129,
> +};
> +
>  void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  {
>  	setup_initial_init_mm(_stext, _etext, _edata, _end);
> @@ -346,6 +365,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
>  
>  	paging_init();
>  
> +	register_restart_handler(&efi_restart_nb);

If we're going to register this, it'd be nicer to register it
conditionally in the EFI code when we probe EFI, rather than having the
arch setup code unconditionally register a notifier that conditionally
does something.

Thanks,
Mark.

> +
>  	acpi_table_upgrade();
>  
>  	/* Parse the ACPI tables for possible boot-time configuration */
> -- 
> 2.34.1
> 


From mark.rutland at arm.com  Mon Jan 17 05:25:41 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 13:25:41 +0000
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
In-Reply-To: <b1ffe762-43e6-b624-2b08-0aaa7ca5f70b@arm.com>
References: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
 <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>
 <b1ffe762-43e6-b624-2b08-0aaa7ca5f70b@arm.com>
Message-ID: <20220117132541.GD87485@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 04:06:44PM +0530, Anshuman Khandual wrote:
> On 1/13/22 3:54 PM, Mark Rutland wrote:
> > Hi Anshuman,
> > 
> > This looks fine structurally, I'm just not sure of a couple of details because
> > I can't find the relevant documentation -- more on that below.
> > 
> > On Thu, Jan 13, 2022 at 03:11:08PM +0530, Anshuman Khandual wrote:
> >> MDCR_EL3.SBRBE resets to an UNKNOWN value. Configure it to allow the BRBE
> >> buffer usage and direct register access in the non-secure world. But just
> >> before that, check AA64DFR0_EL1.BRBE and make sure BRBE is implemented. We
> >> still continue to reset MDCR_EL3 register to zero with the exception of
> >> MDCR_EL3.NSPB, MDCR_EL3.NSTB and MDCR_EL3.SBRBE.
> > 
> > I'm struggling to find where the BRBE system register fields are documented.
> > 
> > I looked at the latest ARM ARM (DDI 0487G.b):
> > 
> >   https://developer.arm.com/documentation/ddi0487/gb/
> > 
> > ... and the Armv9 supplement (DDI 0608A.a):
> > 
> >   https://developer.arm.com/documentation/ddi0608/aa/
> > 
> > ... but AFAICT, neither of those describe the bit-positions of the relevant
> > fields, so I can't check that those are correct. The other extensions (at leat
> > TME) describe that in the supplement, so this looks like a bug/oversight. 
> > 
> > Am I looking at the right documents? If this is meant to be in the supplement,
> > could you please raise a bug report to get that fixed?
> 
> Please find the MDCR_EL3.SBRBE definition here.
> 
> https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/
> MDCR-EL3--Monitor-Debug-Configuration-Register--EL3-?lang=en#fieldset_0-33_32-1
> 
> > 
> >>
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >>  arch/aarch64/boot.S | 8 ++++++++
> >>  1 file changed, 8 insertions(+)
> >>
> >> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> >> index bfbb6ec..ca1b292 100644
> >> --- a/arch/aarch64/boot.S
> >> +++ b/arch/aarch64/boot.S
> >> @@ -103,6 +103,14 @@ ASM_FUNC(_start)
> >>  	ldr	x1, =(0x3 << 24)
> >>  	orr	x0, x0, x1
> >>  
> >> +1:	mrs     x1, id_aa64dfr0_el1
> >> +	ubfx    x1, x1, #52, #4
> >> +	cbz     x1, 1f
> >> +
> >> +	// Enable BRBE for the non-secure world.
> >> +	ldr     x1, =(0x3 << 32)
> >> +	orr     x0, x0, x1
> >> +
> > 
> > I assume this is the `SBRBE` field, which naming-wise sounds like it controls
> > Secure rather than Non-Secure (e,g. by way of comparison to `NSPB`). Is that
> 
> Right, that is some what counter-intuitive.
> 
> > correct? What effect does the value 0x3 have?
> 
> As per the definition above.
> 
> 0b11	 This control does not cause any direct accesses to BRBE registers or
>          instruction to be trapped, and does not cause any Exception levels to
> 	 be a prohibited region.
> 
> This basically allows BRBE usage in EL2/EL1.

Thanks for this!

Just to check, my understanding, there's nothing else that we need to
initialize to ensure that BRBE won't start recording unexpectedly
out-of-reset, becuase in BRBCR_EL* the E*BRE bits all warm-reset to 0
and hence prevent recording in any of EL0/EL1/EL2 (and BRBE never
records at EL3). Is that right?

Assuming so, I'll take this as-is.

Thanks,
Mark.


From alim.akhtar at samsung.com  Mon Jan 17 05:26:05 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 17 Jan 2022 18:56:05 +0530
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
 <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
 <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>
Message-ID: <00c901d80ba5$c9ae6ab0$5d0b4010$@samsung.com>

Hi Krzysztof

>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Friday, January 14, 2022 11:00 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>Subject: Re: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
>
>On 14/01/2022 17:57, Alim Akhtar wrote:
>>
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>>> Sent: Thursday, January 13, 2022 6:03 PM
>>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>>> Cc: soc at kernel.org; linux-clk at vger.kernel.org;
>>> devicetree at vger.kernel.org; olof at lixom.net; linus.walleij at linaro.org;
>>> catalin.marinas at arm.com;
>>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com
>>> Subject: Re: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
>>>
>>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>>> Add device tree bindings for the Tesla FSD ARM SoC.
>>>>
>>>> Cc: linux-fsd at tesla.com
>>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>>> ---
>>>>  .../devicetree/bindings/arm/tesla.yaml        | 25 +++++++++++++++++++
>>>>  1 file changed, 25 insertions(+)
>>>>  create mode 100644
>Documentation/devicetree/bindings/arm/tesla.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml
>>>> b/Documentation/devicetree/bindings/arm/tesla.yaml
>>>> new file mode 100644
>>>> index 000000000000..9f89cde76c85
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/arm/tesla.yaml
>>>> @@ -0,0 +1,25 @@
>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause %YAML 1.2
>>>> +---
>>>> +$id:
>>>> +https://protect2.fireeye.com/v1/url?k=2f0fac44-70949546-2f0e270b-0c
>>>> +c4
>>>> +7a312ab0-50c826f7b1999a5f&q=1&e=bcbf277f-4e93-4705-8f6a-
>>> 2beaa7eb31e2&
>>>>
>+u=http%3A%2F%2Fdevicetree.org%2Fschemas%2Farm%2Ftesla.yaml%23
>>>> +$schema:
>>>> +https://protect2.fireeye.com/v1/url?k=d8493fe2-87d206e0-d848b4ad-
>0c
>>>> +c4
>>>> +7a312ab0-f4e5046adc7da972&q=1&e=bcbf277f-4e93-4705-8f6a-
>>> 2beaa7eb31e2&
>>>> +u=http%3A%2F%2Fdevicetree.org%2Fmeta-schemas%2Fcore.yaml%23
>>>> +
>>>> +title: Tesla Full Self Driving(FSD) platforms device tree bindings
>>>> +
>>>> +maintainers:
>>>> +  - Alim Akhtar <alim.akhtar at samsung.com>
>>>> +  - linux-fsd at tesla.com
>>>> +
>>>> +properties:
>>>> +  $nodename:
>>>> +    const: '/'
>>>> +  compatible:
>>>> +    oneOf:
>>>> +
>>>> +      - description: FSD SoC board
>>>> +        items:
>>>> +          - const: tesla,fsd
>>>
>>> Either this is a SoC or a board compatible... Cannot be both.
>>>
>> Actually we call this as fsd board, so let me add accordingly compatible (fsd-
>baord) for board.
>> Thanks
>
>It's confusing and probably not accurate. In your series fsd is three things in
>the same time: an architecture, a SoC and a board (DTS). The last two should
>definitely be different. You probably have some eval board (how it is called
>also in Tesla open source git) or some specific product board.
>
Understood, let me clear this confusion in the patchset-2 where fsd board will have its own compatible and 
of course SoC will have its own (shared with fsd architecture) compatible.

>I cannot judge how different this is from Exynos subarchitecture - looking at
>patches it is not different - so I could understand a FSD sub-arch with only one
>SoC.
>
I understand, it is a bit difficult to visualize it with the current patch set.
As discuss on the other thread, FSD is different, more over the vendor is different, internal design is different.
>
>Best regards,
>Krzysztof



From mark.rutland at arm.com  Mon Jan 17 05:28:04 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 13:28:04 +0000
Subject: [bootwrapper PATCH v2 02/13] Add bit-field macros
In-Reply-To: <253b79f8-9c8b-4d8d-4f60-2ac74d763c73@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-3-mark.rutland@arm.com>
 <253b79f8-9c8b-4d8d-4f60-2ac74d763c73@arm.com>
Message-ID: <20220117132804.GE87485@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 12:11:36PM +0000, Steven Price wrote:
> On 14/01/2022 10:56, Mark Rutland wrote:
> > +/*
> > + * Insert the least significant bits of `val` into the bit-field described by
> > + * the contiguous set of bits in `mask`.
> > + *
> > + * For example:
> > + * - BITS_INSERT(BITS(3, 0), 0xA)   is 0x000A
> > + * - BITS_INSERT(BITS(15, 12), 0xA) is 0xA000
> > + * - BITS_INSERT(BIT(15), 0xF)      is 0x1000
> 
>     * - BITS_INSERT(BIT(35), 0x1)      is 0x0
> 
> ... which might be surprising!
> 
> of course BITS_INSERT(BIT(35), ULL(0x1)) works, but I feel either the
> description above needs to signpost this gotcha, or a cast is needed below.
> 
> AFAICT this macro isn't actually used in your series.

Good point; I'll either add the cast or drop that for now.

Thanks,
Mark.


From alim.akhtar at samsung.com  Mon Jan 17 05:44:53 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 17 Jan 2022 19:14:53 +0530
Subject: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <2927c34e-3259-4e9a-a657-aeeebf9089d2@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122417epcas5p47398a5190cdf4c574c6f1762918b549f@epcas5p4.samsung.com>
 <20220113121143.22280-16-alim.akhtar@samsung.com>
 <2927c34e-3259-4e9a-a657-aeeebf9089d2@canonical.com>
Message-ID: <00ca01d80ba8$6b9b9800$42d2c800$@samsung.com>

Hi Krzysztof

>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Thursday, January 13, 2022 6:50 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>Shashank Prashar <s.prashar at samsung.com>; Aswani Reddy
><aswani.reddy at samsung.com>
>Subject: Re: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
>
>On 13/01/2022 13:11, Alim Akhtar wrote:
>> Add initial pin configuration nodes for FSD SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 338
>+++++++++++++++++++++
>>  arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
>>  2 files changed, 360 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>
>> diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>> b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>> new file mode 100644
>> index 000000000000..ec8d944af636
>> --- /dev/null
>> +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>> @@ -0,0 +1,338 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Tesla Full Self-Driving SoC device tree source
>> + *
>> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
>> + *		https://www.samsung.com
>> + * Copyright (c) 2017-2021 Tesla, Inc.
>> + *		https://www.tesla.com
>> + */
>> +
>> +#include <dt-bindings/pinctrl/samsung.h>
>> +
>> +&pinctrl_fsys0 {
>> +
>
>No need for empty line.
>
Noted

>> +	gpf0: gpf0 {
>
>FYI:
>It's ok now, but the nodes will have to be renamed to "xxx-gpio-bank" later.
>
Have rebased my v2 on your pinmux schema update, so these and below comments are addressed.
Thanks

>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf1: gpf1 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf6: gpf6 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf4: gpf4 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf5: gpf5 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +};
>> +
>> +&pinctrl_peric {
>> +
>
>No need for empty line.
>
>> +	gpc8: gpc8 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf2: gpf2 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpf3: gpf3 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpd0: gpd0 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb0: gpb0 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb1: gpb1 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb4: gpb4 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb5: gpb5 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb6: gpb6 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpb7: gpb7 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpd1: gpd1 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpd2: gpd2 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpd3: gpd3 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg0: gpg0 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg1: gpg1 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg2: gpg2 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg3: gpg3 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg4: gpg4 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg5: gpg5 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg6: gpg6 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	gpg7: gpg7 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +
>> +		interrupt-controller;
>> +		#interrupt-cells = <2>;
>> +	};
>> +
>> +	pwm0_out: pwm0-out {
>
>All pin configuretion node names with "-pins" suffix. Upcoming dtschema will
>require this.
>
>> +		samsung,pins = "gpb6-1";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
>> +	};
>> +
>> +	pwm1_out: pwm1-out {
>> +		samsung,pins = "gpb6-5";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
>> +	};
>> +
>> +	hs_i2c0_bus: hs-i2c0-bus {
>> +		samsung,pins = "gpb0-0", "gpb0-1";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c1_bus: hs-i2c1-bus {
>> +		samsung,pins = "gpb0-2", "gpb0-3";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c2_bus: hs-i2c2-bus {
>> +		samsung,pins = "gpb0-4", "gpb0-5";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c3_bus: hs-i2c3-bus {
>> +		samsung,pins = "gpb0-6", "gpb0-7";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c4_bus: hs-i2c4-bus {
>> +		samsung,pins = "gpb1-0", "gpb1-1";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c5_bus: hs-i2c5-bus {
>> +		samsung,pins = "gpb1-2", "gpb1-3";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c6_bus: hs-i2c6-bus {
>> +		samsung,pins = "gpb1-4", "gpb1-5";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	hs_i2c7_bus: hs-i2c7-bus {
>> +		samsung,pins = "gpb1-6", "gpb1-7";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	uart0_data: uart0-data {
>> +		samsung,pins = "gpb7-0", "gpb7-1";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	uart1_data: uart1-data {
>> +		samsung,pins = "gpb7-4", "gpb7-5";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	spi0_bus: spi0-bus {
>> +		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	spi1_bus: spi1-bus {
>> +		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +
>> +	spi2_bus: spi2-bus {
>> +		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
>> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
>> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
>> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
>> +	};
>> +};
>> +
>> +&pinctrl_pmu {
>> +
>
>No need for empty line.
>
>> +	gpq0: gpq0 {
>> +		gpio-controller;
>> +		#gpio-cells = <2>;
>> +	};
>
>
>
>
>Best regards,
>Krzysztof



From pgwipeout at gmail.com  Mon Jan 17 05:49:50 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 17 Jan 2022 08:49:50 -0500
Subject: [PATCH 5/9] arm64: dts: rockchip: add rk3568 tsadc nodes
In-Reply-To: <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>
References: <20210728135534.703028-1-pgwipeout@gmail.com>
 <20210728135534.703028-6-pgwipeout@gmail.com>
 <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>
Message-ID: <CAMdYzYo2gkNvNYjU9_kc4cTwNBFU+kg3bRwaS3yCCAsMdo-Tow@mail.gmail.com>

On Mon, Jan 17, 2022 at 3:43 AM Piotr Oniszczuk
<piotr.oniszczuk at gmail.com> wrote:
>
>
>
> > Wiadomo?? napisana przez Peter Geis <pgwipeout at gmail.com> w dniu 28.07.2021, o godz. 15:55:
> >
> > Add the thermal and tsadc nodes to the rk3568 device tree.
> > There are two sensors, one for the cpu, one for the gpu.
> >
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> > .../boot/dts/rockchip/rk3568-pinctrl.dtsi     |  6 ++
> > arch/arm64/boot/dts/rockchip/rk356x.dtsi      | 71 +++++++++++++++++++
> > 2 files changed, 77 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> > index a588ca95ace2..b464c7bda1f7 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3568-pinctrl.dtsi
> > @@ -2420,6 +2420,12 @@ spi3m1_cs1: spi3m1-cs1 {
> >       };
> >
> >       tsadc {
> > +             /omit-if-no-ref/
> > +             tsadc_gpio: tsadc-gpio {
> > +                     rockchip,pins =
> > +                             <0 RK_PA1 0 &pcfg_pull_none>;
> > +             };
> > +
> >               /omit-if-no-ref/
> >               tsadcm0_shut: tsadcm0-shut {
> >                       rockchip,pins =
> > diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> > index 77c679304916..0905fac0726a 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> > @@ -51,6 +51,7 @@ cpu0: cpu at 0 {
> >                       compatible = "arm,cortex-a55";
> >                       reg = <0x0 0x0>;
> >                       clocks = <&scmi_clk 0>;
> > +                     #cooling-cells = <2>;
> >                       enable-method = "psci";
> >                       operating-points-v2 = <&cpu0_opp_table>;
> >               };
> > @@ -59,6 +60,7 @@ cpu1: cpu at 100 {
> >                       device_type = "cpu";
> >                       compatible = "arm,cortex-a55";
> >                       reg = <0x0 0x100>;
> > +                     #cooling-cells = <2>;
> >                       enable-method = "psci";
> >                       operating-points-v2 = <&cpu0_opp_table>;
> >               };
> > @@ -67,6 +69,7 @@ cpu2: cpu at 200 {
> >                       device_type = "cpu";
> >                       compatible = "arm,cortex-a55";
> >                       reg = <0x0 0x200>;
> > +                     #cooling-cells = <2>;
> >                       enable-method = "psci";
> >                       operating-points-v2 = <&cpu0_opp_table>;
> >               };
> > @@ -75,6 +78,7 @@ cpu3: cpu at 300 {
> >                       device_type = "cpu";
> >                       compatible = "arm,cortex-a55";
> >                       reg = <0x0 0x300>;
> > +                     #cooling-cells = <2>;
> >                       enable-method = "psci";
> >                       operating-points-v2 = <&cpu0_opp_table>;
> >               };
> > @@ -774,6 +778,73 @@ uart9: serial at fe6d0000 {
> >               status = "disabled";
> >       };
> >
> > +     thermal_zones: thermal-zones {
> > +             cpu_thermal: cpu-thermal {
> > +                     polling-delay-passive = <100>;
> > +                     polling-delay = <1000>;
> > +
> > +                     thermal-sensors = <&tsadc 0>;
> > +
> > +                     trips {
> > +                             cpu_alert0: cpu_alert0 {
> > +                                     temperature = <70000>;
> > +                                     hysteresis = <2000>;
> > +                                     type = "passive";
> > +                             };
> > +                             cpu_alert1: cpu_alert1 {
> > +                                     temperature = <75000>;
> > +                                     hysteresis = <2000>;
> > +                                     type = "passive";
> > +                             };
> > +                             cpu_crit: cpu_crit {
> > +                                     temperature = <95000>;
> > +                                     hysteresis = <2000>;
> > +                                     type = "critical";
> > +                             };
> > +                     };
> > +
> > +                     cooling-maps {
> > +                             map0 {
> > +                                     trip = <&cpu_alert0>;
> > +                                     cooling-device =
> > +                                             <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> > +                                             <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> > +                                             <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> > +                                             <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> > +                             };
> > +                     };
> > +             };
> > +
> > +             gpu_thermal: gpu-thermal {
> > +                     polling-delay-passive = <20>; /* milliseconds */
> > +                     polling-delay = <1000>; /* milliseconds */
> > +
> > +                     thermal-sensors = <&tsadc 1>;
> > +             };
> > +     };
> > +
> > +     tsadc: tsadc at fe710000 {
> > +             compatible = "rockchip,rk3568-tsadc";
> > +             reg = <0x0 0xfe710000 0x0 0x100>;
> > +             interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
> > +             assigned-clocks = <&cru CLK_TSADC_TSEN>, <&cru CLK_TSADC>;
> > +             assigned-clock-rates = <17000000>, <700000>;
> > +             clocks = <&cru CLK_TSADC>, <&cru PCLK_TSADC>;
> > +             clock-names = "tsadc", "apb_pclk";
> > +             resets = <&cru SRST_TSADC>, <&cru SRST_P_TSADC>,
> > +                      <&cru SRST_TSADCPHY>;
> > +             reset-names = "tsadc", "tsadc-apb", "tsadc-phy";
> > +             rockchip,grf = <&grf>;
> > +             rockchip,hw-tshut-temp = <95000>;
> > +             rockchip,hw-tshut-mode = <1>; /* tshut mode 0:CRU 1:GPIO */
> > +             rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */
> > +             pinctrl-names = "gpio", "otpout";
> > +             pinctrl-0 = <&tsadc_gpio>;
> > +             pinctrl-1 = <&tsadc_shutorg>;
> > +             #thermal-sensor-cells = <1>;
> > +             status = "disabled";
> > +     };
> > +
> >       saradc: saradc at fe720000 {
> >               compatible = "rockchip,rk3568-saradc", "rockchip,rk3399-saradc";
> >               reg = <0x0 0xfe720000 0x0 0x100>;
> > --
> > 2.25.1
> >
> >
> > _______________________________________________
> > Linux-rockchip mailing list
> > Linux-rockchip at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
> Peter,
>
> I'm trying to use this series to get thermal on rk3566 based tvbox (x96-x6).
> Driver loads but i'm getting following error:
>
> [  132.873979] rockchip-thermal fe710000.tsadc: failed to register sensor 0: -517
> [  132.874650] rockchip-thermal fe710000.tsadc: failed to register sensor[0] : error = -517
>
> Maybe you have some hints here?

Error -517 means -EPROBE_DEFER, a device it relies on hasn't probed.
TSADC doesn't directly rely on anything that shouldn't already be
enabled. (Pinctrl, clocks, and grf all break a lot more than tsadc if
disabled)
Does your kernel config have all of the rockchip elements enabled?

>
>


From krzysztof.kozlowski at canonical.com  Mon Jan 17 05:50:18 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 14:50:18 +0100
Subject: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <00ca01d80ba8$6b9b9800$42d2c800$@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122417epcas5p47398a5190cdf4c574c6f1762918b549f@epcas5p4.samsung.com>
 <20220113121143.22280-16-alim.akhtar@samsung.com>
 <2927c34e-3259-4e9a-a657-aeeebf9089d2@canonical.com>
 <00ca01d80ba8$6b9b9800$42d2c800$@samsung.com>
Message-ID: <b8040d39-cd4d-e5b0-8aec-f03c5257d63e@canonical.com>

On 17/01/2022 14:44, Alim Akhtar wrote:
> Hi Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>> Sent: Thursday, January 13, 2022 6:50 PM
>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>> olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>> Shashank Prashar <s.prashar at samsung.com>; Aswani Reddy
>> <aswani.reddy at samsung.com>
>> Subject: Re: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
>>
>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>> Add initial pin configuration nodes for FSD SoC.
>>>
>>> Cc: linux-fsd at tesla.com
>>> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
>>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>> ---
>>>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 338
>> +++++++++++++++++++++
>>>  arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
>>>  2 files changed, 360 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>>
>>> diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>> b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>> new file mode 100644
>>> index 000000000000..ec8d944af636
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>> @@ -0,0 +1,338 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Tesla Full Self-Driving SoC device tree source
>>> + *
>>> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
>>> + *		https://www.samsung.com
>>> + * Copyright (c) 2017-2021 Tesla, Inc.
>>> + *		https://www.tesla.com
>>> + */
>>> +
>>> +#include <dt-bindings/pinctrl/samsung.h>
>>> +
>>> +&pinctrl_fsys0 {
>>> +
>>
>> No need for empty line.
>>
> Noted
> 
>>> +	gpf0: gpf0 {
>>
>> FYI:
>> It's ok now, but the nodes will have to be renamed to "xxx-gpio-bank" later.
>>
> Have rebased my v2 on your pinmux schema update, so these and below comments are addressed.
> Thanks
> 

OK, but have in mind that -gpio-bank suffix is not needed now. This
depends on support in the pinctrl driver, which will be applied after
the merge window to different tree or branches than DTS is going to.
Therefore if I apply your DTS with "-gpio-bank" to my next/dt64, the
kernel won't find GPIo banks and won't properly boot. The linux-next
will be fine, just my next/dt64 won't be.

If you're fine with it - use "-gpio-bank" suffix. If you prefer my
next/dt64 to have a fully working Tesla SoC DTS, then stick to old node
naming and let's replace it later.

Best regards,
Krzysztof


From narmstrong at baylibre.com  Mon Jan 17 05:52:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 14:52:34 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <OS0PR01MB59224F0F892D6F86DBD5D36286579@OS0PR01MB5922.jpnprd01.prod.outlook.com>
Message-ID: <b52ae1a2-b211-2bca-8d62-482a840787ec@baylibre.com>

On 17/01/2022 13:13, Biju Das wrote:
> Hi Neil,
>> Subject: Re: dw_hdmi is showing wrong colour after commit
>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>> callbacks")
>>
>> Hi again,
>>
>> On 14/01/2022 15:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 14/01/2022 15:23, Biju Das wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Sent: 14 January 2022 13:56
>>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>>>> <festevam at gmail.com>
>>>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>>>> martin.blumenstingl at googlemail.com;
>>>>> linux-amlogic at lists.infradead.org;
>>>>> linux-arm-kernel at lists.infradead.org;
>>>>> dri-devel at lists.freedesktop.org; linux-kernel at vger.kernel.org;
>>>>> linux-renesas-soc at vger.kernel.org
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 14/01/2022 12:08, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>> fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>>>> Hi Neil,
>>>>>>>>
>>>>>>>> + renesas-soc
>>>>>>>>
>>>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>> fmts
>>>>>>>>> callbacks")
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>>>> Hi Biju,
>>>>>>>>>>
>>>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi All,
>>>>>>>>>>>
>>>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working
>>>>>>>>>>> ok(colour) till the commit
>>>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>>>> fmts
>>>>>>>>> callbacks").
>>>>>>>>>>>
>>>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>>>> setting it
>>>>>>>>> into YUV format??).
>>>>>>>>>>>
>>>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>>>> callback
>>>>>>>>> and set colour as RGB24.
>>>>>>>>>>>
>>>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns
>>>>>>>>>>> 3 outputformats(YUV16, YUV24 and RGB24) And get_input_fmt
>>>>>>>>>>> callback, I see
>>>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>>>
>>>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI
>> driver.
>>>>>>>>>
>>>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>>>> seems it behaves incorrectly if the first bridge doesn't
>>>>>>>>> implement the negotiation callbacks.
>>>>>>>>>
>>>>>>>>> Let me check the code to see how to fix that.
>>>>>>>>
>>>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Biju
>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board,
>>>>>>>>>> which
>>>>>>> shows:
>>>>>>>>>>
>>>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>>>
>>>>>>>>>> The colors are shown correctly here.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>>>
>>>>>>>>> Anyway thanks for testing
>>>>>>>>>
>>>>>>>>> Neil
>>>>>>>
>>>>>>> Can you test :
>>>>>>>
>>>>>>> ==><===============================
>>>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>>>> 100644
>>>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>>>> @@ -955,7 +955,14 @@
>>>>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>         last_bridge_state =
>>>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>>>> state,
>>>>>>>
>>>>>>> last_bridge);
>>>>>>>
>>>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>> +       /*
>>>>>>> +        * Only negociate with real values if both end of the
>>>>>>> + bridge
>>>>> chain
>>>>>>> +        * support negociation callbacks, otherwise you can end in
>>>>>>> + a
>>>>>>> situation
>>>>>>> +        * where the selected output format doesn't match with the
>>>>>>> + first
>>>>>>> bridge
>>>>>>> +        * output format.
>>>>>>> +        */
>>>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>>>> last_bridge->funcs;
>>>>>>>
>>>>>>>                 /*
>>>>>>> @@ -980,7 +987,12 @@
>>>>>>> drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>                 if (!out_bus_fmts)
>>>>>>>                         return -ENOMEM;
>>>>>>>
>>>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>>>> +               /*
>>>>>>> +                * If first bridge doesn't support negociation,
>>>>>>> + use
>>>>>>> MEDIA_BUS_FMT_FIXED
>>>>>>> +                * as a safe value for the whole bridge chain
>>>>>>> +                */
>>>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>>>                     conn->display_info.bus_formats)
>>>>>>>                         out_bus_fmts[0] = conn-
>>>>>>>> display_info.bus_formats[0];
>>>>>>>                 else
>>>>>>> ==><===============================
>>>>>>>
>>>>>>> This should exclude your situation where the first bridge doesn't
>>>>>>> support negociation.
>>>>>>
>>>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>>>> issue.
>>>>>>
>>>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>>>
>>>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>>>
>>>>>> And In get_input_fmt callback, I See the outputformat as YUV16
>>>>>> instead
>>>>> of RGB24.
>>>>>>
>>>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>> [    3.473644] ########hdmi_video_sample
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>
>>>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to
>>>>> the encoder.
>>>>
>>>> Yep.
>>>>
>>>>>
>>>>> Let me figure that out, no sure I can find a clean solution except
>>>>> putting back RGB24 before YUV.
>>>>>
>>>>> Anyway please test that:
>>>>
>>>> It works now after reordering.
>>>>
>>>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24=0#########
>>>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>> MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>>>
>>>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>> MEDIA_BUS_FMT_RGB888_1X24#########
>>>> [    3.506797] ########hdmi_video_sample
>> MEDIA_BUS_FMT_RGB888_1X24#########
>>>>
>>>> Is it acceptable solution to the users of dw_hdmi driver? May be it is
>> worth to post a patch.
>>>> at least it is fixing the colour issue??
>>>
>>> Yes, it gets back to default behavior before negociation, nevertheless
>>> we need to think how to handle your use-case correctly at some point.
>>>
>>> I'll post this as a patch ASAP so it gets applied before landing in
>> linus master.
>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>>>>
>> [...]
>>
>> I'm not happy with this version since it's merely a hack which makes it
>> work.
>>
>> Can you test the following change instead, it's correctly handles your
>> situation in a generic manner.
>>
>> ========================><=============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..9f2e1cac0ae2 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2551,8 +2551,9 @@ static u32
>> *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>         if (!output_fmts)
>>                 return NULL;
>>
>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves
>> */
>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with
>> ourselves */
>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>> +           list_is_first(&bridge->chain_node,
>> + &bridge->encoder->bridge_chain)) {
>>                 *num_output_fmts = 1;
>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>
>> @@ -2673,6 +2674,10 @@ static u32
>> *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>         if (!input_fmts)
>>                 return NULL;
>>
>> +       /* If dw-hdmi is the first bridge fall-back to safe output format
>> */
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
>>> bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>> +
>>         switch (output_fmt) {
>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>         case MEDIA_BUS_FMT_FIXED:
>> ========================><=============================
> 
> This patch alone fixes the issue. I have tested with Linux-next.
> Do we need below code, as it is already taken care in output_bus_fmt callback.

You're right in your case the first part is enough.

> 
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder-
>>> bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> 
> Cheers,
> Biju
> 

Thanks for testing,
Neil


From narmstrong at baylibre.com  Mon Jan 17 05:53:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 14:53:47 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <164241711700.10801.9011781958267060147@Monstersaurus>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <CAOMZO5DJiCb5bJN5_nxnYa-FsK-u7QtFghWNzs_-udE42XPDeA@mail.gmail.com>
 <502f3ec4-fea4-8e14-c7a9-39418fc05d6d@baylibre.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <164241711700.10801.9011781958267060147@Monstersaurus>
Message-ID: <4f214ea2-5f9f-1217-6e65-f92e434ed826@baylibre.com>

On 17/01/2022 11:58, Kieran Bingham wrote:
> Hi Neil,
> 
> Quoting Neil Armstrong (2022-01-17 10:08:38)
>> Hi again,
>>
>> On 14/01/2022 15:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 14/01/2022 15:23, Biju Das wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Sent: 14 January 2022 13:56
>>>>> To: Biju Das <biju.das.jz at bp.renesas.com>; Fabio Estevam
>>>>> <festevam at gmail.com>
>>>>> Cc: daniel at ffwll.ch; Laurent.pinchart at ideasonboard.com;
>>>>> robert.foss at linaro.org; jonas at kwiboo.se; jernej.skrabec at gmail.com;
>>>>> martin.blumenstingl at googlemail.com; linux-amlogic at lists.infradead.org;
>>>>> linux-arm-kernel at lists.infradead.org; dri-devel at lists.freedesktop.org;
>>>>> linux-kernel at vger.kernel.org; linux-renesas-soc at vger.kernel.org
>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>> callbacks")
>>>>>
>>>>> Hi,
>>>>>
>>>>> On 14/01/2022 12:08, Biju Das wrote:
>>>>>> Hi Neil,
>>>>>>
>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>> callbacks")
>>>>>>>
>>>>>>> On 14/01/2022 09:29, Biju Das wrote:
>>>>>>>> Hi Neil,
>>>>>>>>
>>>>>>>> + renesas-soc
>>>>>>>>
>>>>>>>>> Subject: Re: dw_hdmi is showing wrong colour after commit
>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
>>>>>>>>> callbacks")
>>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> On 13/01/2022 21:01, Fabio Estevam wrote:
>>>>>>>>>> Hi Biju,
>>>>>>>>>>
>>>>>>>>>> On Thu, Jan 13, 2022 at 2:45 PM Biju Das
>>>>>>>>>> <biju.das.jz at bp.renesas.com>
>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>> Hi All,
>>>>>>>>>>>
>>>>>>>>>>> RZ/G2{H, M, N} SoC has dw_hdmi IP and it was working ok(colour)
>>>>>>>>>>> till the commit
>>>>>>>>>>> 7cd70656d1285b79("drm/bridge: display-connector: implement bus
>>>>>>>>>>> fmts
>>>>>>>>> callbacks").
>>>>>>>>>>>
>>>>>>>>>>> After this patch, the screen becomes greenish(may be it is
>>>>>>>>>>> setting it
>>>>>>>>> into YUV format??).
>>>>>>>>>>>
>>>>>>>>>>> By checking the code, previously it used to call get_input_fmt
>>>>>>>>>>> callback
>>>>>>>>> and set colour as RGB24.
>>>>>>>>>>>
>>>>>>>>>>> After this commit, it calls get_output_fmt_callbck and returns 3
>>>>>>>>>>> outputformats(YUV16, YUV24 and RGB24) And get_input_fmt callback,
>>>>>>>>>>> I see
>>>>>>>>> the outputformat as YUV16 instead of RGB24.
>>>>>>>>>>>
>>>>>>>>>>> Not sure, I am the only one seeing this issue with dw_HDMI driver.
>>>>>>>>>
>>>>>>>>> This patch was introduced to maintain the bridge color format
>>>>>>>>> negotiation after using DRM_BRIDGE_ATTACH_NO_CONNECTOR, but it
>>>>>>>>> seems it behaves incorrectly if the first bridge doesn't implement
>>>>>>>>> the negotiation callbacks.
>>>>>>>>>
>>>>>>>>> Let me check the code to see how to fix that.
>>>>>>>>
>>>>>>>> Thanks for the information, I am happy to test the patch/fix.
>>>>>>>>
>>>>>>>> Cheers,
>>>>>>>> Biju
>>>>>>>>
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> I have tested linux-next 20220112 on a imx6q-sabresd board, which
>>>>>>> shows:
>>>>>>>>>>
>>>>>>>>>> dwhdmi-imx 120000.hdmi: Detected HDMI TX controller v1.30a with
>>>>>>>>>> HDCP (DWC HDMI 3D TX PHY)
>>>>>>>>>>
>>>>>>>>>> The colors are shown correctly here.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The imx doesn't use DRM_BRIDGE_ATTACH_NO_CONNECTOR so the
>>>>>>>>> negotiation fails and use the RGB fallback input & output format.
>>>>>>>>>
>>>>>>>>> Anyway thanks for testing
>>>>>>>>>
>>>>>>>>> Neil
>>>>>>>
>>>>>>> Can you test :
>>>>>>>
>>>>>>> ==><===============================
>>>>>>> diff --git a/drivers/gpu/drm/drm_bridge.c
>>>>>>> b/drivers/gpu/drm/drm_bridge.c index c96847fc0ebc..7019acd37716
>>>>>>> 100644
>>>>>>> --- a/drivers/gpu/drm/drm_bridge.c
>>>>>>> +++ b/drivers/gpu/drm/drm_bridge.c
>>>>>>> @@ -955,7 +955,14 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>         last_bridge_state =
>>>>>>> drm_atomic_get_new_bridge_state(crtc_state-
>>>>>>>> state,
>>>>>>>
>>>>>>> last_bridge);
>>>>>>>
>>>>>>> -       if (last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>> +       /*
>>>>>>> +        * Only negociate with real values if both end of the bridge
>>>>> chain
>>>>>>> +        * support negociation callbacks, otherwise you can end in a
>>>>>>> situation
>>>>>>> +        * where the selected output format doesn't match with the
>>>>>>> + first
>>>>>>> bridge
>>>>>>> +        * output format.
>>>>>>> +        */
>>>>>>> +       if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +           last_bridge->funcs->atomic_get_output_bus_fmts) {
>>>>>>>                 const struct drm_bridge_funcs *funcs =
>>>>>>> last_bridge->funcs;
>>>>>>>
>>>>>>>                 /*
>>>>>>> @@ -980,7 +987,12 @@ drm_atomic_bridge_chain_select_bus_fmts(struct
>>>>>>> drm_bridge *bridge,
>>>>>>>                 if (!out_bus_fmts)
>>>>>>>                         return -ENOMEM;
>>>>>>>
>>>>>>> -               if (conn->display_info.num_bus_formats &&
>>>>>>> +               /*
>>>>>>> +                * If first bridge doesn't support negociation, use
>>>>>>> MEDIA_BUS_FMT_FIXED
>>>>>>> +                * as a safe value for the whole bridge chain
>>>>>>> +                */
>>>>>>> +               if (bridge->funcs->atomic_get_input_bus_fmts &&
>>>>>>> +                   conn->display_info.num_bus_formats &&
>>>>>>>                     conn->display_info.bus_formats)
>>>>>>>                         out_bus_fmts[0] = conn-
>>>>>>>> display_info.bus_formats[0];
>>>>>>>                 else
>>>>>>> ==><===============================
>>>>>>>
>>>>>>> This should exclude your situation where the first bridge doesn't
>>>>>>> support negociation.
> 
> This fixes the issue for me here on an H3 Salvator-XS.
> 
> Could you add...
> 
> Bisected-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> Tested-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
> 
> alongside Biju's Reported-by: tag when posting as a fix please?


Which patch did you test ?

Neil

> 
> 
>>>>>>
>>>>>> I have tested this fix with Linux next-20220114. Still I see colour
>>>>> issue.
>>>>>>
>>>>>> It is still negotiating and it is calling get_output_fmt_callbck
>>>>>>
>>>>>> [    3.460155] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16=0#########
>>>>>> [    3.460180] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>>>> [    3.460202] ########dw_hdmi_bridge_atomic_get_output_bus_fmts
>>>>> MEDIA_BUS_FMT_RGB888_1X24=2#########
>>>>>>
>>>>>> And In get_input_fmt callback, I See the outputformat as YUV16 instead
>>>>> of RGB24.
>>>>>>
>>>>>> [    3.460319] ########dw_hdmi_bridge_atomic_get_input_bus_fmts
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>> [    3.473644] ########hdmi_video_sample
>>>>> MEDIA_BUS_FMT_UYVY8_1X16#########
>>>>>
>>>>> OK, looking at rcar-du, the dw-hdmi bridge is directly connected to the
>>>>> encoder.
>>>>
>>>> Yep.
>>>>
>>>>>
>>>>> Let me figure that out, no sure I can find a clean solution except putting
>>>>> back RGB24 before YUV.
>>>>>
>>>>> Anyway please test that:
>>>>
>>>> It works now after reordering.
>>>>
>>>> [    3.493302] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_RGB888_1X24=0#########
>>>> [    3.493326] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_YUV8_1X24=1#########
>>>> [    3.493348] ########dw_hdmi_bridge_atomic_get_output_bus_fmts MEDIA_BUS_FMT_UYVY8_1X16=2#########
>>>>
>>>> [    3.493463] ########dw_hdmi_bridge_atomic_get_input_bus_fmts MEDIA_BUS_FMT_RGB888_1X24#########
>>>> [    3.506797] ########hdmi_video_sample MEDIA_BUS_FMT_RGB888_1X24#########
>>>>
>>>> Is it acceptable solution to the users of dw_hdmi driver? May be it is worth to post a patch.
>>>> at least it is fixing the colour issue??
>>>
>>> Yes, it gets back to default behavior before negociation, nevertheless we need to think
>>> how to handle your use-case correctly at some point.
>>>
>>> I'll post this as a patch ASAP so it gets applied before landing in linus master.
>>>
>>> Neil
>>>
>>>>
>>>> Regards,
>>>> Biju
>>>>
>>>>>
>> [...]
>>
>> I'm not happy with this version since it's merely a hack which makes it work.
>>
>> Can you test the following change instead, it's correctly handles your situation in a generic manner.
>>
>> ========================><=============================
>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> index 54d8fdad395f..9f2e1cac0ae2 100644
>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>> @@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>         if (!output_fmts)
>>                 return NULL;
>>
>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
>>                 *num_output_fmts = 1;
>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>
>> @@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>         if (!input_fmts)
>>                 return NULL;
>>
>> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>> +
>>         switch (output_fmt) {
>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>         case MEDIA_BUS_FMT_FIXED:
>> ========================><=============================
>>
>> Thanks,
>> Neil
>>
>>
>>>>>
>>>>> Neil
>>>>>
>>>>>>
>>>>>> Regards,
>>>>>> Biju
>>>>>>
>>>>
>>>
>>



From german.gomez at arm.com  Mon Jan 17 06:04:22 2022
From: german.gomez at arm.com (German Gomez)
Date: Mon, 17 Jan 2022 14:04:22 +0000
Subject: [RFC PATCH 2/2] perf: arm_spe: Enable CONTEXT packets in SPE
 traces if the profiler runs in CPU mode.
In-Reply-To: <20220117124432.3119132-3-german.gomez@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-3-german.gomez@arm.com>
Message-ID: <949a8209-4efa-5c4f-8953-ddc53938706d@arm.com>


On 17/01/2022 12:44, German Gomez wrote:
> Enable CONTEXT packets in SPE traces if the profiler runs in CPU mode.
> This is no less permissive than the existing behavior for the following
> reason:
>
> If perf_event_paranoid <= 0, then non perfmon_capable() users can open
> a per-CPU event. With a per-CPU event, unpriviledged users are allowed
> to profile _all_ processes, even ones owned by root.
>
> Without this change, users could see kernel addresses, root processes,
> etc, but not gather the PIDs of those processes. The PID is probably the
> least sensitive of all the information.
>
> It would be more idiomatic to check the perf_event_paranoid level with
> perf_allow_cpu(), but this function is not exported so cannot be used
> from a module. Looking for cpu != -1 is the indirect way of checking
> the same thing as it could never get to arm_spe_pmu_event_init() without

Reconsidering this bit (comment below)

> perf_event_paranoid <= 0.
>
> Co-authored-by: James Clark <james.clark at arm.com>
> Signed-off-by: German Gomez <german.gomez at arm.com>
> ---
>  drivers/perf/arm_spe_pmu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
> index 8515bf85c..7d9a7fa4f 100644
> --- a/drivers/perf/arm_spe_pmu.c
> +++ b/drivers/perf/arm_spe_pmu.c
> @@ -711,7 +711,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
>  	    !(spe_pmu->features & SPE_PMU_FEAT_FILT_LAT))
>  		return -EOPNOTSUPP;
>  
> -	spe_pmu->pmscr_cx = perfmon_capable();
> +	spe_pmu->pmscr_cx = perfmon_capable() || (event->cpu != -1);

The perf_event_open(2) manpage states:

?????? pid == -1 and cpu >= 0
????????????? This measures all processes/threads on the specified CPU.
????????????? This requires CAP_PERFMON (since Linux 5.8) or
????????????? CAP_SYS_ADMIN capability or a
????????????? /proc/sys/kernel/perf_event_paranoid value of less than 1.

So perhaps it's more accurate to (still implicitly) check the paranoid level with "pid == -1 && event->cpu > 0" ?

If so, I think I have to dig deeper into perf_event. I don't immediately see the pid argument. Any hints?

Thanks,
German

>  	reg = arm_spe_event_to_pmscr(event);
>  	if (!perfmon_capable() &&
>  	    (reg & (BIT(SYS_PMSCR_EL1_PA_SHIFT) |


From narmstrong at baylibre.com  Mon Jan 17 06:07:45 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:07:45 +0100
Subject: dw_hdmi is showing wrong colour after commit
 7cd70656d1285b79("drm/bridge: display-connector: implement bus fmts
 callbacks")
In-Reply-To: <164242831905.10801.10615379536917395435@Monstersaurus>
References: <OS0PR01MB59221ED76B74231F5836D5FB86539@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <OS0PR01MB592224EC8F50F41B7FF1DEE286549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <19dd6013-8a31-b2ed-29d5-93fc44193ce4@baylibre.com>
 <OS0PR01MB5922F442759BE6F228EE0B4486549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <538b8da4-1201-5f45-2abf-ecd22c867358@baylibre.com>
 <OS0PR01MB5922BC31FBCF85F99F17737B86549@OS0PR01MB5922.jpnprd01.prod.outlook.com>
 <ebaff694-a2d7-7eb8-5850-980e9d4e1e68@baylibre.com>
 <80fdc5a0-ddb8-5a0f-eb8c-ef7988ced638@baylibre.com>
 <164241711700.10801.9011781958267060147@Monstersaurus>
 <4f214ea2-5f9f-1217-6e65-f92e434ed826@baylibre.com>
 <164242831905.10801.10615379536917395435@Monstersaurus>
Message-ID: <92f37b42-23db-4aab-5262-911d07b6301f@baylibre.com>

On 17/01/2022 15:05, Kieran Bingham wrote:
> Quoting Neil Armstrong (2022-01-17 13:53:47)
>> On 17/01/2022 11:58, Kieran Bingham wrote:
>>> Hi Neil,
> 
> <big snips to clear up contexts>
> 
>>> This fixes the issue for me here on an H3 Salvator-XS.
>>>
>>> Could you add...
>>>
>>> Bisected-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
>>> Tested-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
>>>
>>> alongside Biju's Reported-by: tag when posting as a fix please?
>>
>>
>> Which patch did you test ?
> 
> Ah, yes that's not clear is it - sorry! I replied in the wrong place on
> the thread when I went back to the mail ... see below...
> 
>>>> I'm not happy with this version since it's merely a hack which makes it work.
>>>>
>>>> Can you test the following change instead, it's correctly handles your situation in a generic manner.
>>>>
>>>> ========================><=============================
>>>> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> index 54d8fdad395f..9f2e1cac0ae2 100644
>>>> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
>>>> @@ -2551,8 +2551,9 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>>>>         if (!output_fmts)
>>>>                 return NULL;
>>>>
>>>> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
>>>> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
>>>> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
>>>> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
>>>> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
>>>>                 *num_output_fmts = 1;
>>>>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>>>>
>>>> @@ -2673,6 +2674,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>>>>         if (!input_fmts)
>>>>                 return NULL;
>>>>
>>>> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
>>>> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
>>>> +               output_fmt = MEDIA_BUS_FMT_FIXED;
>>>> +
>>>>         switch (output_fmt) {
>>>>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>>>>         case MEDIA_BUS_FMT_FIXED:
>>>> ========================><=============================
> 
> Sorry, I replied in the wrong part of the thread.
> 
> Here's the direct diff on my local tree:
> 
> 
> diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> index 54d8fdad395f..cac9a87949f1 100644
> --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> @@ -2551,8 +2551,10 @@ static u32 *dw_hdmi_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
>         if (!output_fmts)
>                 return NULL;
>  
> -       /* If dw-hdmi is the only bridge, avoid negociating with ourselves */
> -       if (list_is_singular(&bridge->encoder->bridge_chain)) {
> +       /* If dw-hdmi is the first or only bridge, avoid negociating with ourselves */
> +       if (list_is_singular(&bridge->encoder->bridge_chain) ||
> +           list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain)) {
> +
>                 *num_output_fmts = 1;
>                 output_fmts[0] = MEDIA_BUS_FMT_FIXED;
>  
> @@ -2673,6 +2675,10 @@ static u32 *dw_hdmi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
>         if (!input_fmts)
>                 return NULL;
>  
> +       /* If dw-hdmi is the first bridge fall-back to safe output format */
> +       if (list_is_first(&bridge->chain_node, &bridge->encoder->bridge_chain))
> +               output_fmt = MEDIA_BUS_FMT_FIXED;
> +
>         switch (output_fmt) {
>         /* If MEDIA_BUS_FMT_FIXED is tested, return default bus format */
>         case MEDIA_BUS_FMT_FIXED:
> 
> Which I believe matches the above.

Ok thanks of clarifying !

let me post it asap.

Neil

> 
> --
> Kieran
> 



From piotr.oniszczuk at gmail.com  Mon Jan 17 06:13:14 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Mon, 17 Jan 2022 15:13:14 +0100
Subject: [PATCH 5/9] arm64: dts: rockchip: add rk3568 tsadc nodes
In-Reply-To: <CAMdYzYo2gkNvNYjU9_kc4cTwNBFU+kg3bRwaS3yCCAsMdo-Tow@mail.gmail.com>
References: <20210728135534.703028-1-pgwipeout@gmail.com>
 <20210728135534.703028-6-pgwipeout@gmail.com>
 <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>
 <CAMdYzYo2gkNvNYjU9_kc4cTwNBFU+kg3bRwaS3yCCAsMdo-Tow@mail.gmail.com>
Message-ID: <E3AA167E-1E40-45CD-8CBB-3EB280856604@gmail.com>



> Wiadomo?? napisana przez Peter Geis <pgwipeout at gmail.com> w dniu 17.01.2022, o godz. 14:49:
> 
>> 
>> Peter,
>> 
>> I'm trying to use this series to get thermal on rk3566 based tvbox (x96-x6).
>> Driver loads but i'm getting following error:
>> 
>> [  132.873979] rockchip-thermal fe710000.tsadc: failed to register sensor 0: -517
>> [  132.874650] rockchip-thermal fe710000.tsadc: failed to register sensor[0] : error = -517
>> 
>> Maybe you have some hints here?
> 
> Error -517 means -EPROBE_DEFER, a device it relies on hasn't probed.
> TSADC doesn't directly rely on anything that shouldn't already be
> enabled. (Pinctrl, clocks, and grf all break a lot more than tsadc if
> disabled)
> Does your kernel config have all of the rockchip elements enabled?
> 

Peter,
For sure I can't say 'yes' with 100% confidence.
I'm trying do my best for rk3566 (currently have working: SD/Eth/HDMI/Sound/USB2port0/BT).

Maybe you may point me pls for good reference of rk356x defconfig?

btw: a bit of  context:
In my application (https://github.com/warpme/minimyth2) i have target to have single OS binary for all supported Allwinner/Amlogic/Rockchip/Broadcom devices.
By this kernel config i'm using is painfully assembled to have minimal working kernel for all targets.
It's a painful road....but still want to go this route for: minimal image size; shortest build time & one-for-all binary.
my current config: https://github.com/warpme/minimyth2/blob/master/script/kernel/linux-5.16/files/linux-5.16-arm64-armv8.config

btw2: for rk3566 i'm using majority of your patches! 
Great work of you!
 


  


 

From arnd at arndb.de  Mon Jan 17 06:14:10 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 17 Jan 2022 15:14:10 +0100
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <00c901d80ba5$c9ae6ab0$5d0b4010$@samsung.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
 <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
 <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>
 <00c901d80ba5$c9ae6ab0$5d0b4010$@samsung.com>
Message-ID: <CAK8P3a31bCHNcNWrLX+QW+4RuK=DBpxLA_j5BFKxXxXKCT8PFQ@mail.gmail.com>

On Mon, Jan 17, 2022 at 2:26 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:
>
> >I cannot judge how different this is from Exynos subarchitecture - looking at
> >patches it is not different - so I could understand a FSD sub-arch with only one
> >SoC.
> >
> I understand, it is a bit difficult to visualize it with the current patch set.
> As discuss on the other thread, FSD is different, more over the vendor is different, internal design is different.

Is it based on another SoC design then? Most new SoCs are derived from
some other
one, so it makes sense to put it into the same family. E.g. the Apple
M1 takes bits from
both Exynos and PA-Semi SoCs but has more newly added components than
either one.

I would argue that if this SoC shares the pinctrl, clock, spi, adc,
and timer implementation
with Exynos, we should consider it part of the Exynos family,
regardless of what other
blocks may exist next to those.

       Arnd


From narmstrong at baylibre.com  Mon Jan 17 06:30:39 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:30:39 +0100
Subject: [PATCH 3/3] arm64: dts: meson: remove Broadcom WiFi/BT nodes from
 Khadas VIM1
In-Reply-To: <20220113041746.16040-4-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-4-christianshewitt@gmail.com>
Message-ID: <2236d8a8-77e7-7dc9-fd32-b3ade335a128@baylibre.com>

Hi,

On 13/01/2022 05:17, Christian Hewitt wrote:
> The Broadcom WiFi/BT SDIO nodes are now inherited from the P212 common dtsi
> so we can remove them from the VIM1 board dts.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../amlogic/meson-gxl-s905x-khadas-vim.dts    | 19 -------------------
>  1 file changed, 19 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> index 6ab1cc125b96..108232a5aa2e 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
> @@ -217,25 +217,6 @@
>  	pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
>  };
>  
> -&sd_emmc_a {
> -	max-frequency = <100000000>;

The SDIO freq is marked as 50000000 in the p212 DTSI and was explicitly changes
by Jerome in adc52bf7ef16 ("arm64: dts: meson: fix mmc v2 chips max frequencies")

The change is ok if you change the p212 DTSI to 100000000 aswell.

> -
> -	brcmf: wifi at 1 {
> -		reg = <1>;
> -		compatible = "brcm,bcm4329-fmac";
> -	};
> -};
> -
> -&uart_A {
> -	bluetooth {
> -		compatible = "brcm,bcm43438-bt";
> -		shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
> -		max-speed = <2000000>;
> -		clocks = <&wifi32k>;
> -		clock-names = "lpo";
> -	};
> -};
> -
>  /* This is brought out on the Linux_RX (18) and Linux_TX (19) pins: */
>  &uart_AO {
>  	status = "okay";
> 

With the change in p212 dtsi:

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks,
Neil


From narmstrong at baylibre.com  Mon Jan 17 06:30:47 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:30:47 +0100
Subject: [PATCH 2/3] arm64: dts: meson: move pwm_ef node in P212 dtsi
In-Reply-To: <20220113041746.16040-3-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-3-christianshewitt@gmail.com>
Message-ID: <d82549cf-01cc-68de-8af3-763b94ba6ef6@baylibre.com>

On 13/01/2022 05:17, Christian Hewitt wrote:
> Cosmetic-only change to move/alpha-sort the node.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  .../boot/dts/amlogic/meson-gxl-s905x-p212.dtsi   | 16 ++++++++--------
>  1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> index c635e5858929..b3d7b8613d6d 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> @@ -97,6 +97,14 @@
>  	pinctrl-names = "default";
>  };
>  
> +&pwm_ef {
> +	status = "okay";
> +	pinctrl-0 = <&pwm_e_pins>;
> +	pinctrl-names = "default";
> +	clocks = <&clkc CLKID_FCLK_DIV4>;
> +	clock-names = "clkin0";
> +};
> +
>  &saradc {
>  	status = "okay";
>  	vref-supply = <&vddio_ao18>;
> @@ -170,14 +178,6 @@
>  	vqmmc-supply = <&vddio_boot>;
>  };
>  
> -&pwm_ef {
> -	status = "okay";
> -	pinctrl-0 = <&pwm_e_pins>;
> -	pinctrl-names = "default";
> -	clocks = <&clkc CLKID_FCLK_DIV4>;
> -	clock-names = "clkin0";
> -};
> -
>  /* This is connected to the Bluetooth module: */
>  &uart_A {
>  	status = "okay";
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From andre.przywara at arm.com  Mon Jan 17 06:31:04 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 14:31:04 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220114105653.3003399-10-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-10-mark.rutland@arm.com>
Message-ID: <20220117143104.28db5001@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:49 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> The majority of state that we initialize at EL3 is necessary for code at
> lower ELs to function, but isnt' necessary for the boot-wrapper itself.
> Given that, it would be better to write this in C where it can be
> written mode clearly, and where it will be possible to add logging/debug
> logic.

Ah, thanks, that looks much nicer and easier to read now, also is more
robust, as keeping register values alive for more than a few assembly
lines always scares me.

> This patch migrates the AArch64 EL3 initialization to C.
> 
> There should be no functional change as a result of this patch.

I compared the removed assembly code against to added C code, and also
checked the register bits against the ARM ARM.
Two (and a half) things stood out, see below:

> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  Makefile.am                    |  2 +-
>  arch/aarch64/boot.S            | 92 +---------------------------------
>  arch/aarch64/include/asm/cpu.h | 36 ++++++++++++-
>  arch/aarch64/init.c            | 69 +++++++++++++++++++++++++
>  4 files changed, 107 insertions(+), 92 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 885a77c..a598b95 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -153,7 +153,7 @@ $(COMMON_SRC):
>  %.o: %.S Makefile | $(ARCH_SRC)
>  	$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
>  
> -%.o: %.c Makefile | $(COMMON_SRC)
> +%.o: %.c Makefile | $(ARCH_SRC) $(COMMON_SRC)
>  	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
>  
>  model.lds: $(LD_SCRIPT) Makefile
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 17b4a75..c0ec518 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -45,96 +45,6 @@ reset_at_el3:
>  	msr	sctlr_el3, x0
>  	isb
>  
> -	mov	x0, #0x30			// RES1
> -	orr	x0, x0, #(1 << 0)		// Non-secure EL1
> -	orr	x0, x0, #(1 << 8)		// HVC enable
> -
> -	/* Enable pointer authentication if present */
> -	mrs	x1, id_aa64isar1_el1
> -	/* We check for APA+API and GPA+GPI */
> -	ldr	x2, =((0xff << 24) | (0xff << 4))
> -	and	x1, x1, x2
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 16)		// AP key enable
> -	orr	x0, x0, #(1 << 17)		// AP insn enable
> -1:
> -	/* Enable TME if present */
> -	mrs	x1, id_aa64isar0_el1
> -	ubfx	x1, x1, #24, #4
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 34)		// TME enable
> -1:
> -	/* Enable FGT if present */
> -	mrs	x1, id_aa64mmfr0_el1
> -	ubfx	x1, x1, #56, #4
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 27)		// FGT enable
> -1:
> -	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> -	mrs	x1, id_aa64mmfr0_el1
> -	ubfx	x1, x1, #60, #4
> -	cmp	x1, #2
> -	b.lt	1f
> -
> -	orr	x0, x0, #(1 << 28)		// ECV enable
> -1:
> -	/* Enable MTE if present */
> -	mrs	x10, id_aa64pfr1_el1
> -	ubfx	x10, x10, #8, #4
> -	cmp	x10, #2
> -	b.lt	1f
> -
> -	orr	x0, x0, #(1 << 26)		// ATA enable
> -1:
> -#ifndef KERNEL_32
> -	orr	x0, x0, #(1 << 10)		// 64-bit EL2
> -#endif
> -	msr	scr_el3, x0
> -
> -	msr	cptr_el3, xzr			// Disable copro. traps to EL3
> -
> -	mov	x0, xzr
> -	mrs	x1, id_aa64dfr0_el1
> -	ubfx	x1, x1, #32, #4
> -	cbz	x1, 1f
> -
> -	// Enable SPE for the non-secure world.
> -	orr	x0, x0, #(0x3 << 12)
> -
> -	// Do not trap PMSNEVFR_EL1 if present
> -	cmp	x1, #3
> -	b.lt	1f
> -	orr	x0, x0, #(1 << 36)
> -
> -1:	mrs	x1, id_aa64dfr0_el1
> -	ubfx	x1, x1, #44, #4
> -	cbz	x1, 1f
> -
> -	// Enable TRBE for the non-secure world.
> -	ldr	x1, =(0x3 << 24)
> -	orr	x0, x0, x1
> -
> -1:	msr	mdcr_el3, x0			// Disable traps to EL3
> -
> -	mrs	x0, id_aa64pfr0_el1
> -	ubfx	x0, x0, #32, #4			// SVE present?
> -	cbz	x0, 1f				// Skip SVE init if not
> -
> -	mrs	x0, cptr_el3
> -	orr	x0, x0, #CPTR_EL3_EZ		// enable SVE
> -	msr	cptr_el3, x0
> -	isb
> -
> -	mov	x0, #ZCR_EL3_LEN_MASK		// SVE: Enable full vector len
> -	msr	ZCR_EL3, x0			// for EL2.
> -
> -1:
> -	ldr	x0, =COUNTER_FREQ
> -	msr	cntfrq_el0, x0
> -
>  	cpuid	x0, x1
>  	bl	find_logical_id
>  	cmp	x0, #MPIDR_INVALID
> @@ -143,6 +53,8 @@ reset_at_el3:
>  
>  	bl	cpu_init_bootwrapper
>  
> +	bl	cpu_init_el3
> +
>  	bl	gic_secure_init
>  
>  	b	start_el3
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 1e9141a..e078ae4 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -31,7 +31,41 @@
>  #define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
>  				 BIT(11) | BIT(8) | BIT(7) | BIT(4))
>  
> -#define HCR_EL2_RES1		(BIT(1))
> +#define ZCR_EL3				s3_6_c1_c2_0
> +#define ZCR_EL3_LEN			BITS(3, 1)

The (current) actual length field should be BITS(3, 0), no?

> +
> +#define MDCR_EL3_NSPB_NS_NOTRAP		(UL(3) << 12)
> +#define MDCR_EL3_NSTB_NS_NOTRAP		(UL(3) << 24)
> +#define MDCR_EL3_ENPMSN			BIT(36)
> +
> +#define SCR_EL3_RES1			BITS(5, 4)
> +#define SCR_EL3_NS			BIT(0)
> +#define SCR_EL3_HCE			BIT(8)
> +#define SCR_EL3_RW			BIT(10)
> +#define SCR_EL3_APK			BIT(16)
> +#define SCR_EL3_API			BIT(17)
> +#define SCR_EL3_ATA			BIT(26)
> +#define SCR_EL3_FGTEN			BIT(27)
> +#define SCR_EL3_ECVEN			BIT(28)
> +#define SCR_EL3_TME			BIT(34)
> +
> +#define HCR_EL2_RES1			BIT(1)
> +
> +#define ID_AA64DFR0_EL1_PMSVER		BITS(35, 32)
> +#define ID_AA64DFR0_EL1_TRACEBUFFER	BITS(47, 44)
> +
> +#define ID_AA64ISAR0_EL1_TME		BITS(27, 24)
> +
> +#define ID_AA64ISAR1_EL1_APA		BITS(7, 4)
> +#define ID_AA64ISAR1_EL1_API		BITS(11, 8)
> +#define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
> +#define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
> +
> +#define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
> +#define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
> +
> +#define ID_AA64PFR1_EL1_MTE		BITS(11, 8)
> +#define ID_AA64PFR0_EL1_SVE		BITS(35, 32)
>  
>  /*
>   * Initial register values required for the boot-wrapper to run out-of-reset.
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> index 82816e7..ded9871 100644
> --- a/arch/aarch64/init.c
> +++ b/arch/aarch64/init.c
> @@ -8,6 +8,7 @@
>   */
>  #include <cpu.h>
>  #include <platform.h>
> +#include <stdbool.h>
>  
>  void announce_arch(void)
>  {
> @@ -17,3 +18,71 @@ void announce_arch(void)
>  	print_char('0' + el);
>  	print_string("\r\n");
>  }
> +
> +static inline bool kernel_is_32bit(void)
> +{
> +#ifdef KERNEL_32
> +	return true;
> +#else
> +	return false;
> +#endif
> +}
> +
> +static inline bool cpu_has_pauth(void)
> +{
> +	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
> +				       ID_AA64ISAR1_EL1_API |
> +				       ID_AA64ISAR1_EL1_GPA |
> +				       ID_AA64ISAR1_EL1_GPI;
> +
> +	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
> +}
> +
> +void cpu_init_el3(void)
> +{
> +	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
> +	unsigned long mdcr = 0;
> +	unsigned long cptr = 0;
> +
> +	if (cpu_has_pauth())
> +		scr |= SCR_EL3_APK | SCR_EL3_API;
> +
> +	if (mrs_field(ID_AA64ISAR0_EL1, TME))
> +		scr |= SCR_EL3_TME;
> +
> +	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
> +		scr |= SCR_EL3_FGTEN;
> +
> +	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
> +		scr |= SCR_EL3_ECVEN;
> +
> +	if (mrs_field(ID_AA64PFR1_EL1, MTE))

The assembly code checked for >=2, which seems correct to me, as
SCR_EL3_ATA is about MTE2?

> +		scr |= SCR_EL3_ATA;
> +
> +	if (!kernel_is_32bit())
> +		scr |= SCR_EL3_RW;
> +
> +	msr(SCR_EL3, scr);
> +
> +	msr(CPTR_EL3, cptr);
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, PMSVER))
> +		mdcr |= MDCR_EL3_NSPB_NS_NOTRAP;
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, PMSVER) >= 3)
> +		mdcr |= MDCR_EL3_ENPMSN;
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, TRACEBUFFER))
> +		mdcr |= MDCR_EL3_NSTB_NS_NOTRAP;
> +
> +	msr(MDCR_EL3, mdcr);
> +
> +	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
> +		cptr |= CPTR_EL3_EZ;
> +		msr(CPTR_EL3, cptr);
> +		isb();
> +		msr(ZCR_EL3, ZCR_EL3_LEN);

So when comparing this to the other uses of XXX_EL3_YYY, they typically
describe a mask, but here we seems to abuse this as a value? And apart
from bit 0 missing from it (as noted above), the existing code writes 0x1ff
into that register, presumable to cover future vector length extensions
beyond 2048 bits (which those RAZ/WI fields in bits[8:4] seem to suggest).
So shall we define ZCR_EL3_MAX_VEC_LEN to 0x1ff above, and then use that?
Or ignore the crystal ball, and just stick with 2048 bits, by writing 0xf?

The rest passed the checks.

Cheers,
Andre

> +	}
> +
> +	msr(CNTFRQ_EL0, COUNTER_FREQ);
> +}



From narmstrong at baylibre.com  Mon Jan 17 06:32:04 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:32:04 +0100
Subject: [PATCH 1/3] arm64: dts: meson: add Broadcom WiFi to P212 dtsi
In-Reply-To: <20220113041746.16040-2-christianshewitt@gmail.com>
References: <20220113041746.16040-1-christianshewitt@gmail.com>
 <20220113041746.16040-2-christianshewitt@gmail.com>
Message-ID: <927257db-1338-af1c-3198-3153e122967b@baylibre.com>

On 13/01/2022 05:17, Christian Hewitt wrote:
> The P212 has a combined WiFi/BT module. The BT side is already enabled
> in the dtsi but the WiFi side is not. Let's tweak SDIO speed (in-line
> with other GXL/GXM devices) and enable the WiFi module.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> index 05cb2f5e5c36..c635e5858929 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dtsi
> @@ -113,7 +113,7 @@
>  
>  	bus-width = <4>;
>  	cap-sd-highspeed;
> -	max-frequency = <50000000>;
> +	max-frequency = <100000000>;
>  
>  	non-removable;
>  	disable-wp;
> @@ -125,6 +125,11 @@
>  
>  	vmmc-supply = <&vddao_3v3>;
>  	vqmmc-supply = <&vddio_boot>;
> +
> +	brcmf: wifi at 1 {
> +		reg = <1>;
> +		compatible = "brcm,bcm4329-fmac";
> +	};
>  };
>  
>  /* SD card */
> 

As I commented in patch 3, the 2 changes should be split.

When you resend, you can put my:

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

in both patches.

Neil


From narmstrong at baylibre.com  Mon Jan 17 06:37:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Mon, 17 Jan 2022 15:37:56 +0100
Subject: [PATCH] arm64: dts: meson: add audio playback to P212
In-Reply-To: <20220113044546.16856-1-christianshewitt@gmail.com>
References: <20220113044546.16856-1-christianshewitt@gmail.com>
Message-ID: <aa02e3f7-3f77-4b9c-74a0-987045de0352@baylibre.com>

Hi,

On 13/01/2022 05:45, Christian Hewitt wrote:
> Add initial audio support limited to HDMI i2s.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
> The P212 dts is widely used with Android box devices that follow the
> reference design. The real P212 development board probably has many
> more audio capabilities, but as a minimum we can enable HDMI output
> and help box users too.
> 
>  .../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 40 +++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> index 2602940c2077..a39830379c74 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
> @@ -7,6 +7,7 @@
>  /dts-v1/;
>  
>  #include "meson-gxl-s905x-p212.dtsi"
> +#include <dt-bindings/sound/meson-aiu.h>
>  
>  / {
>  	compatible = "amlogic,p212", "amlogic,s905x", "amlogic,meson-gxl";
> @@ -32,6 +33,45 @@
>  			};
>  		};
>  	};
> +
> +	sound {
> +		compatible = "amlogic,gx-sound-card";
> +		model = "S905X-P212";
> +		assigned-clocks = <&clkc CLKID_MPLL0>,
> +				  <&clkc CLKID_MPLL1>,
> +				  <&clkc CLKID_MPLL2>;
> +		assigned-clock-parents = <0>, <0>, <0>;
> +		assigned-clock-rates = <294912000>,
> +				       <270950400>,
> +				       <393216000>;
> +		status = "okay";
> +
> +		dai-link-0 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_FIFO>;
> +		};
> +
> +		dai-link-1 {
> +			sound-dai = <&aiu AIU_CPU CPU_I2S_ENCODER>;
> +			dai-format = "i2s";
> +			mclk-fs = <256>;
> +
> +			codec-0 {
> +				sound-dai = <&aiu AIU_HDMI CTRL_I2S>;
> +			};
> +		};
> +
> +		dai-link-2 {
> +			sound-dai = <&aiu AIU_HDMI CTRL_OUT>;
> +
> +			codec-0 {
> +				sound-dai = <&hdmi_tx>;
> +			};
> +		};
> +	};
> +};
> +
> +&aiu {
> +	status = "okay";
>  };
>  
>  &cec_AO {
> 

The P212 ref board has an analog audio output with a DIO2133CT14 amplifier unmuted by default with the active high GPIOH_5 to mute.

It's very probable all the STB boxes uses the same scheme, so it'll be safe to add the analog audio output here exactly like libretech-cc.

Neil


From pgwipeout at gmail.com  Mon Jan 17 06:38:50 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 17 Jan 2022 09:38:50 -0500
Subject: [PATCH 5/9] arm64: dts: rockchip: add rk3568 tsadc nodes
In-Reply-To: <E3AA167E-1E40-45CD-8CBB-3EB280856604@gmail.com>
References: <20210728135534.703028-1-pgwipeout@gmail.com>
 <20210728135534.703028-6-pgwipeout@gmail.com>
 <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>
 <CAMdYzYo2gkNvNYjU9_kc4cTwNBFU+kg3bRwaS3yCCAsMdo-Tow@mail.gmail.com>
 <E3AA167E-1E40-45CD-8CBB-3EB280856604@gmail.com>
Message-ID: <CAMdYzYqsPgAbLBt+xwDL2s7ViLDJw5mnzDnupimRVESt0xFksQ@mail.gmail.com>

On Mon, Jan 17, 2022 at 9:13 AM Piotr Oniszczuk
<piotr.oniszczuk at gmail.com> wrote:
>
>
>
> > Wiadomo?? napisana przez Peter Geis <pgwipeout at gmail.com> w dniu 17.01.2022, o godz. 14:49:
> >
> >>
> >> Peter,
> >>
> >> I'm trying to use this series to get thermal on rk3566 based tvbox (x96-x6).
> >> Driver loads but i'm getting following error:
> >>
> >> [  132.873979] rockchip-thermal fe710000.tsadc: failed to register sensor 0: -517
> >> [  132.874650] rockchip-thermal fe710000.tsadc: failed to register sensor[0] : error = -517
> >>
> >> Maybe you have some hints here?
> >
> > Error -517 means -EPROBE_DEFER, a device it relies on hasn't probed.
> > TSADC doesn't directly rely on anything that shouldn't already be
> > enabled. (Pinctrl, clocks, and grf all break a lot more than tsadc if
> > disabled)
> > Does your kernel config have all of the rockchip elements enabled?
> >
>
> Peter,
> For sure I can't say 'yes' with 100% confidence.
> I'm trying do my best for rk3566 (currently have working: SD/Eth/HDMI/Sound/USB2port0/BT).
>
> Maybe you may point me pls for good reference of rk356x defconfig?
>
> btw: a bit of  context:
> In my application (https://github.com/warpme/minimyth2) i have target to have single OS binary for all supported Allwinner/Amlogic/Rockchip/Broadcom devices.
> By this kernel config i'm using is painfully assembled to have minimal working kernel for all targets.
> It's a painful road....but still want to go this route for: minimal image size; shortest build time & one-for-all binary.
> my current config: https://github.com/warpme/minimyth2/blob/master/script/kernel/linux-5.16/files/linux-5.16-arm64-armv8.config

I recommend you use `make savedefconfig`.
It produces a simplified defconfig based on your .config.

Your issue is in your dts.
You have retained the quartz64-a &cpu_thermal active thermal node
without tying in an active thermal control device (a fan).
By default the rk356x dtsi passive thermal trips are hooked up and
will throttle the device in case of overtemp.
If your device has no active thermal control, you don't need to add
the &cpu_thermal node at all to your dts.

>
> btw2: for rk3566 i'm using majority of your patches!
> Great work of you!
>
>
>
>
>
>
>


From andre.przywara at arm.com  Mon Jan 17 06:39:13 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 14:39:13 +0000
Subject: [bootwrapper PATCH v2 08/13] Announce boot-wrapper mode /
 exception level
In-Reply-To: <20220114105653.3003399-9-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-9-mark.rutland@arm.com>
Message-ID: <20220117143913.520a553c@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:48 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> When something goes wrong within the boot-wrapper, it can be very
> helpful to know where we started from. Add an arch_announce() function
> to log this early in the boot process. More information can be added
> here in future.
> 
> This is logged ot the serial console as:
> 
> | Boot-wrapper v0.2
> | Entered at EL3

I like that one, and apart from the (already existing) UART issue below,
this looks fine:

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  Makefile.am                    |  2 +-
>  arch/aarch32/include/asm/cpu.h |  9 +++++++++
>  arch/aarch32/init.c            | 30 ++++++++++++++++++++++++++++++
>  arch/aarch64/init.c            | 19 +++++++++++++++++++
>  common/init.c                  |  6 +++++-
>  common/platform.c              | 24 ++++++++++++++----------
>  include/platform.h             |  1 +
>  7 files changed, 79 insertions(+), 12 deletions(-)
>  create mode 100644 arch/aarch32/init.c
>  create mode 100644 arch/aarch64/init.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index 0651c38..885a77c 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -36,7 +36,7 @@ PSCI_CPU_OFF	:= 0x84000002
>  COMMON_SRC	:= common/
>  COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
>  
> -ARCH_OBJ	:= boot.o stack.o utils.o
> +ARCH_OBJ	:= boot.o stack.o utils.o init.o
>  
>  if BOOTWRAPPER_32
>  CPPFLAGS	+= -DBOOTWRAPPER_32
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index d691c7b..aa72204 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -44,6 +44,15 @@
>  #define sevl()		asm volatile ("sev" : : : "memory")
>  #endif
>  
> +static inline unsigned long read_cpsr(void)
> +{
> +	unsigned long cpsr;
> +	asm volatile ("mrs      %0, cpsr\n" : "=r" (cpsr));
> +	return cpsr;
> +}
> +
> +#define read_cpsr_mode()       (read_cpsr() & PSR_MODE_MASK)
> +
>  #define MPIDR		"p15, 0, %0, c0, c0, 5"
>  #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
>  #define ICIALLU		"p15, 0, %0, c7, c5, 0"
> diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
> new file mode 100644
> index 0000000..b29ebb4
> --- /dev/null
> +++ b/arch/aarch32/init.c
> @@ -0,0 +1,30 @@
> +/*
> + * init.c - common boot-wrapper initialization
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#include <platform.h>
> +
> +#include <asm/cpu.h>
> +
> +static const char *mode_string(void)
> +{
> +	switch (read_cpsr_mode()) {
> +	case PSR_MON:
> +		return "PL1";
> +	case PSR_HYP:
> +		return "PL2 (Non-secure)";
> +	default:
> +		return "<UNKNOWN MODE>";
> +	}
> +}
> +
> +void announce_arch(void)
> +{
> +	print_string("Entered at ");
> +	print_string(mode_string());
> +	print_string("\r\n");
> +}
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> new file mode 100644
> index 0000000..82816e7
> --- /dev/null
> +++ b/arch/aarch64/init.c
> @@ -0,0 +1,19 @@
> +/*
> + * init.c - common boot-wrapper initialization
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#include <cpu.h>
> +#include <platform.h>
> +
> +void announce_arch(void)
> +{
> +	unsigned char el = mrs(CurrentEl) >> 2;
> +
> +	print_string("Entered at EL");
> +	print_char('0' + el);
> +	print_string("\r\n");
> +}
> diff --git a/common/init.c b/common/init.c
> index 9c471c9..2600f73 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -11,14 +11,18 @@
>  
>  static void announce_bootwrapper(void)
>  {
> -	print_string("Boot-wrapper v0.2\r\n\r\n");
> +	print_string("Boot-wrapper v0.2\r\n");
>  }
>  
> +void announce_arch(void);
> +
>  void cpu_init_bootwrapper(void)
>  {
>  	if (this_cpu_logical_id() == 0) {
>  		init_uart();
>  		announce_bootwrapper();
> +		announce_arch();
> +		print_string("\r\n");
>  		init_platform();
>  	}
>  }
> diff --git a/common/platform.c b/common/platform.c
> index 47bf547..80d0562 100644
> --- a/common/platform.c
> +++ b/common/platform.c
> @@ -31,21 +31,25 @@
>  #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
>  #endif
>  
> -void print_string(const char *str)
> +void print_char(char c)
>  {
>  	uint32_t flags;
>  
> -	while (*str) {
> -		do
> -			flags = raw_readl(PL011(UARTFR));
> -		while (flags & PL011_UARTFR_FIFO_FULL);
> +	do {
> +		flags = raw_readl(PL011(UARTFR));
> +	} while (flags & PL011_UARTFR_FIFO_FULL);
> +
> +	raw_writel(c, PL011(UARTDR));
>  
> -		raw_writel(*str++, PL011(UARTDR));
> +	do {
> +		flags = raw_readl(PL011(UARTFR));
> +	} while (flags & PL011_UARTFR_BUSY);

Apologies if that appears to be nitpicking over a totally pointless issue
(given the nature of the *emulated* PL011 in the model), but:

I understand that this code has not changed, but this loop basically
renders the FIFOs ineffective. Is this intended? I mean we explicitly
enable the FIFOs in init_uart(), but then poll here until the transmit
FIFO becomes empty, after *every* character pushed. I see that we probably
want the output to be synchronous, for debug reasons, but I wonder if this
should be achieved via an extra uart_flush() routine, once per line
output? So call uart_flush() just in print_string(), but not in
print_char(), for instance?

Cheers,
Andre

> +}
>  
> -		do
> -			flags = raw_readl(PL011(UARTFR));
> -		while (flags & PL011_UARTFR_BUSY);
> -	}
> +void print_string(const char *str)
> +{
> +	while (*str)
> +		print_char(*str++);
>  }
>  
>  void init_uart(void)
> diff --git a/include/platform.h b/include/platform.h
> index e5248e1..237b481 100644
> --- a/include/platform.h
> +++ b/include/platform.h
> @@ -9,6 +9,7 @@
>  #ifndef __PLATFORM_H
>  #define __PLATFORM_H
>  
> +void print_char(char c);
>  void print_string(const char *str);
>  void init_uart(void);
>  



From arnd at arndb.de  Mon Jan 17 06:51:15 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Mon, 17 Jan 2022 15:51:15 +0100
Subject: [PATCH 3/3] ARM: aspeed: Add secure boot controller support
In-Reply-To: <CACPK8XcSPiOoJZ4jyJySvCiW+EXxSVsxiEcK2eOZjGY9b1vrjA@mail.gmail.com>
References: <20211117035106.321454-1-joel@jms.id.au>
 <20211117035106.321454-4-joel@jms.id.au>
 <CACPK8XcSPiOoJZ4jyJySvCiW+EXxSVsxiEcK2eOZjGY9b1vrjA@mail.gmail.com>
Message-ID: <CAK8P3a3MRf0aGt1drkgsuZyBbeoy+S7Ha18SBM01q+3f33oL+Q@mail.gmail.com>

On Tue, Jan 11, 2022 at 12:29 AM Joel Stanley <joel at jms.id.au> wrote:
> On Wed, 17 Nov 2021 at 03:51, Joel Stanley <joel at jms.id.au> wrote:
> >
> > This reads out the status of the secure boot controller and exposes it
> > in sysfs.
> >
> > An example on a AST2600A3 QEMU model:
> >
> >  # grep . /sys/bus/soc/devices/soc0/*
> >  /sys/bus/soc/devices/soc0/abr_image:0
> >  /sys/bus/soc/devices/soc0/family:AST2600
> >  /sys/bus/soc/devices/soc0/low_security_key:0
> >  /sys/bus/soc/devices/soc0/machine:Rainier 2U
> >  /sys/bus/soc/devices/soc0/otp_protected:0
> >  /sys/bus/soc/devices/soc0/revision:A3
> >  /sys/bus/soc/devices/soc0/secure_boot:1
> >  /sys/bus/soc/devices/soc0/serial_number:888844441234abcd
> >  /sys/bus/soc/devices/soc0/soc_id:05030303
> >  /sys/bus/soc/devices/soc0/uart_boot:1
>
> Quoting from your response to my pull request:
>
> > - I actually want to avoid custom attributes on soc device instances as much
> >   as possible. I have not looked in detail at what you add here, but the
> >   number of custom attributes means we should discuss this properly.
>
> Can you explain the reasoning here?
>
> I am a bit surprised given we have this nice feature in struct
> soc_device_attribute:
>
> struct soc_device_attribute {
> ...
>         const struct attribute_group *custom_attr_group;
> };

I have two main concerns:

- any attribute that makes sense across multiple SoC families should probably be
  part of the standard set of attributes. Ideally this could fit
within the existing
  attributes, but if you can make a reasonable case for adding further
ones, that
  is fine as well. The standard attributes can then also be accessed from within
  the kernel with soc_device_match(), rather than just being available
to user space.

- The attributes should all be used to identify the SoC, not a
particular part of
  the SoC that is better represented as a separate device.

If you are adding five attributes at once, it's likely that these
don't all fit the
constraints, though I had not yet looked at the implementation.

>From what I see in

+static ssize_t abr_image_show(struct device *dev, struct
device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(security_status & ABR_IMAGE_SOURCE));
+}
+
+static ssize_t low_security_key_show(struct device *dev, struct
device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(security_status & LOW_SEC_KEY));
+}
+
+static ssize_t otp_protected_show(struct device *dev, struct
device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(security_status & OTP_PROTECTED));
+}
+
+static ssize_t secure_boot_show(struct device *dev, struct
device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !!(security_status & SECURE_BOOT));
+}
+
+static ssize_t uart_boot_show(struct device *dev, struct
device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !(security_status & UART_BOOT));
+}

it appears that these are related to how the system was started, which doesn't
fit either of the requirements: the same information may be useful for
non-aspeed
systems, so it would be good to have it in a standardized interface rather than
vendor extensions, and it doesn't really identify the SoC but instead provides
information from a device that is inside of the SoC.

Maybe this could be turned into a generalized interface similar to soc_device
that exposes the boot status in sysfs? We have a couple of files that
determine e.g. whether the kernel was booted securely, and those could
all hook up here. It doesn't have to be anything complex, just a node under
/sys/firmware or /sys/power that has a couple of documented attributes
that can be filled by drivers.

          Arnd


From andre.przywara at arm.com  Mon Jan 17 06:52:16 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 14:52:16 +0000
Subject: [bootwrapper PATCH v2 10/13] aarch32: move the bulk of Secure
 PL1 initialization to C
In-Reply-To: <20220114105653.3003399-11-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-11-mark.rutland@arm.com>
Message-ID: <20220117145216.76bc664d@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:50 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> The majority of state that we initialize at Secure PL1 is necessary for
> code at lower PLs to function, but isnt' necessary for the boot-wrapper
> itself.  Given that, it would be better to write this in C where it can
> be written mode clearly, and where it will be possible to add
> logging/debug logic.
> 
> This patch migrates the AArch32 Secure PL1 initialization to C.
> 
> There should be no functional change as a result of this patch.

I compared the removed assembly code against to added C code, and also
checked the register bits against the ARMv7 ARM.
Everything checks out, so:

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch32/boot.S            | 11 +----------
>  arch/aarch32/include/asm/cpu.h |  9 +++++++++
>  arch/aarch32/init.c            | 12 ++++++++++++
>  3 files changed, 22 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index ee073ea..820957b 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -63,16 +63,7 @@ _monitor:
>  	/* Move the stack to Monitor mode*/
>  	mrs	sp, sp_svc
>  
> -	/* Setup secure registers and devices */
> -	mov	r0, #1				@ Non-secure lower level
> -	orr	r0, #(1 << 8)			@ HVC enable
> -	mcr	p15, 0, r0, c1, c1, 0		@ SCR
> -
> -	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
> -	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
> -
> -	ldr	r0, =COUNTER_FREQ
> -	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
> +	bl	cpu_init_secure_pl1
>  
>  	bl	cpu_init_bootwrapper
>  
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index aa72204..c1bce9a 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -30,6 +30,11 @@
>  #define PSR_I			(1 << 7)
>  #define PSR_A			(1 << 8)
>  
> +#define SCR_NS			BIT(0)
> +#define SCR_HCE			BIT(8)
> +
> +#define NSACR_CP10		BIT(10)
> +#define NSACR_CP11		BIT(11)
>  
>  #define SPSR_KERNEL		(PSR_A | PSR_I | PSR_F | PSR_HYP)
>  
> @@ -55,11 +60,15 @@ static inline unsigned long read_cpsr(void)
>  
>  #define MPIDR		"p15, 0, %0, c0, c0, 5"
>  #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
> +#define SCR		"p15, 0, %0, c1, c1, 0"
> +#define NSACR		"p15, 0, %0, c1, c1, 2"
>  #define ICIALLU		"p15, 0, %0, c7, c5, 0"
>  
>  #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
>  #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
>  
> +#define CNTFRQ		"p15, 0, %0, c14, c0, 0"
> +
>  #define mrc(reg)						\
>  ({								\
>  	unsigned long __mrc_val;				\
> diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
> index b29ebb4..5b69dcd 100644
> --- a/arch/aarch32/init.c
> +++ b/arch/aarch32/init.c
> @@ -28,3 +28,15 @@ void announce_arch(void)
>  	print_string(mode_string());
>  	print_string("\r\n");
>  }
> +
> +void cpu_init_secure_pl1(void)
> +{
> +	unsigned long scr = SCR_NS | SCR_HCE;
> +	unsigned long nsacr = NSACR_CP10 | NSACR_CP11;
> +
> +	mcr(SCR, scr);
> +
> +	mcr(NSACR, nsacr);
> +
> +	mcr(CNTFRQ, COUNTER_FREQ);
> +}



From piotr.oniszczuk at gmail.com  Mon Jan 17 06:53:03 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Mon, 17 Jan 2022 15:53:03 +0100
Subject: [PATCH 5/9] arm64: dts: rockchip: add rk3568 tsadc nodes
In-Reply-To: <CAMdYzYqsPgAbLBt+xwDL2s7ViLDJw5mnzDnupimRVESt0xFksQ@mail.gmail.com>
References: <20210728135534.703028-1-pgwipeout@gmail.com>
 <20210728135534.703028-6-pgwipeout@gmail.com>
 <C3AE0A81-A829-4241-A65E-EB28825E3C33@gmail.com>
 <CAMdYzYo2gkNvNYjU9_kc4cTwNBFU+kg3bRwaS3yCCAsMdo-Tow@mail.gmail.com>
 <E3AA167E-1E40-45CD-8CBB-3EB280856604@gmail.com>
 <CAMdYzYqsPgAbLBt+xwDL2s7ViLDJw5mnzDnupimRVESt0xFksQ@mail.gmail.com>
Message-ID: <A6AF0F12-FB41-4C60-96AA-660C1E8B379C@gmail.com>



> Wiadomo?? napisana przez Peter Geis <pgwipeout at gmail.com> w dniu 17.01.2022, o godz. 15:38:
> 
> 
> 
> Your issue is in your dts.
> You have retained the quartz64-a &cpu_thermal active thermal node
> without tying in an active thermal control device (a fan).
> By default the rk356x dtsi passive thermal trips are hooked up and
> will throttle the device in case of overtemp.
> If your device has no active thermal control, you don't need to add
> the &cpu_thermal node at all to your dts.
> 
>> 
>> btw2: for rk3566 i'm using majority of your patches!
>> Great work of you!

Peter,

Many thx!

Now it works nicely:

cpu_thermal-virtual-0
Adapter: Virtual device
temp1:        +33.8?C  (crit = +95.0?C)

gpu_thermal-virtual-0
Adapter: Virtual device
temp1:        +34.4?C  (crit = +95.0?C)

again: many thx!



forgive me unrelated q:
may hint me for script you are using in your gitlab ci for building quartz64 u-boot in ci pipeline?
I'm using yours binaries - but want to add building from sources in my project.... 




From madvenka at linux.microsoft.com  Mon Jan 17 06:55:58 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:55:58 -0600
Subject: [PATCH v13 01/11] arm64: Remove NULL task check from unwind_frame()
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-2-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Currently, there is a check for a NULL task in unwind_frame(). It is not
needed since all current consumers pass a non-NULL task.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/arm64/kernel/stacktrace.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 0fb58fed54cb..5f5bb35b7b41 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -69,9 +69,6 @@ static int notrace unwind_frame(struct task_struct *tsk,
 	unsigned long fp = frame->fp;
 	struct stack_info info;
 
-	if (!tsk)
-		tsk = current;
-
 	/* Final frame; nothing to unwind */
 	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
 		return -ENOENT;
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:55:59 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:55:59 -0600
Subject: [PATCH v13 02/11] arm64: Rename unwinder functions
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-3-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Rename unwinder functions for consistency and better naming.

	- Rename start_backtrace() to unwind_init().
	- Rename unwind_frame() to unwind_next().
	- Rename walk_stackframe() to unwind().

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/arm64/kernel/stacktrace.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 5f5bb35b7b41..b980d96dccfc 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,8 @@
  */
 
 
-static void start_backtrace(struct stackframe *frame, unsigned long fp,
-			    unsigned long pc)
+static void unwind_init(struct stackframe *frame, unsigned long fp,
+			unsigned long pc)
 {
 	frame->fp = fp;
 	frame->pc = pc;
@@ -45,7 +45,7 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
 	/*
 	 * Prime the first unwind.
 	 *
-	 * In unwind_frame() we'll check that the FP points to a valid stack,
+	 * In unwind_next() we'll check that the FP points to a valid stack,
 	 * which can't be STACK_TYPE_UNKNOWN, and the first unwind will be
 	 * treated as a transition to whichever stack that happens to be. The
 	 * prev_fp value won't be used, but we set it to 0 such that it is
@@ -63,8 +63,8 @@ static void start_backtrace(struct stackframe *frame, unsigned long fp,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_frame(struct task_struct *tsk,
-				struct stackframe *frame)
+static int notrace unwind_next(struct task_struct *tsk,
+			       struct stackframe *frame)
 {
 	unsigned long fp = frame->fp;
 	struct stack_info info;
@@ -104,7 +104,7 @@ static int notrace unwind_frame(struct task_struct *tsk,
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
-	 * prev_type are only meaningful to the next unwind_frame() invocation.
+	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
 	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
@@ -137,23 +137,23 @@ static int notrace unwind_frame(struct task_struct *tsk,
 
 	return 0;
 }
-NOKPROBE_SYMBOL(unwind_frame);
+NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace walk_stackframe(struct task_struct *tsk,
-				    struct stackframe *frame,
-				    bool (*fn)(void *, unsigned long), void *data)
+static void notrace unwind(struct task_struct *tsk,
+			   struct stackframe *frame,
+			   bool (*fn)(void *, unsigned long), void *data)
 {
 	while (1) {
 		int ret;
 
 		if (!fn(data, frame->pc))
 			break;
-		ret = unwind_frame(tsk, frame);
+		ret = unwind_next(tsk, frame);
 		if (ret < 0)
 			break;
 	}
 }
-NOKPROBE_SYMBOL(walk_stackframe);
+NOKPROBE_SYMBOL(unwind);
 
 static bool dump_backtrace_entry(void *arg, unsigned long where)
 {
@@ -195,14 +195,14 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 	struct stackframe frame;
 
 	if (regs)
-		start_backtrace(&frame, regs->regs[29], regs->pc);
+		unwind_init(&frame, regs->regs[29], regs->pc);
 	else if (task == current)
-		start_backtrace(&frame,
+		unwind_init(&frame,
 				(unsigned long)__builtin_frame_address(1),
 				(unsigned long)__builtin_return_address(0));
 	else
-		start_backtrace(&frame, thread_saved_fp(task),
+		unwind_init(&frame, thread_saved_fp(task),
 				thread_saved_pc(task));
 
-	walk_stackframe(task, &frame, consume_entry, cookie);
+	unwind(task, &frame, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:00 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:00 -0600
Subject: [PATCH v13 03/11] arm64: Rename stackframe to unwind_state
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-4-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Rename "struct stackframe" to "struct unwind_state" for consistency and
better naming. Accordingly, rename variable/argument "frame" to "state".

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/arm64/include/asm/stacktrace.h |  2 +-
 arch/arm64/kernel/stacktrace.c      | 66 ++++++++++++++---------------
 2 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index e77cdef9ca29..41ec360515f6 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -52,7 +52,7 @@ struct stack_info {
  *               associated with the most recently encountered replacement lr
  *               value.
  */
-struct stackframe {
+struct unwind_state {
 	unsigned long fp;
 	unsigned long pc;
 	DECLARE_BITMAP(stacks_done, __NR_STACK_TYPES);
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b980d96dccfc..a1a7ff93b84f 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,13 +33,13 @@
  */
 
 
-static void unwind_init(struct stackframe *frame, unsigned long fp,
+static void unwind_init(struct unwind_state *state, unsigned long fp,
 			unsigned long pc)
 {
-	frame->fp = fp;
-	frame->pc = pc;
+	state->fp = fp;
+	state->pc = pc;
 #ifdef CONFIG_KRETPROBES
-	frame->kr_cur = NULL;
+	state->kr_cur = NULL;
 #endif
 
 	/*
@@ -51,9 +51,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
 	 * prev_fp value won't be used, but we set it to 0 such that it is
 	 * definitely not an accessible stack address.
 	 */
-	bitmap_zero(frame->stacks_done, __NR_STACK_TYPES);
-	frame->prev_fp = 0;
-	frame->prev_type = STACK_TYPE_UNKNOWN;
+	bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
+	state->prev_fp = 0;
+	state->prev_type = STACK_TYPE_UNKNOWN;
 }
 
 /*
@@ -64,9 +64,9 @@ static void unwind_init(struct stackframe *frame, unsigned long fp,
  * and the location (but not the fp value) of B.
  */
 static int notrace unwind_next(struct task_struct *tsk,
-			       struct stackframe *frame)
+			       struct unwind_state *state)
 {
-	unsigned long fp = frame->fp;
+	unsigned long fp = state->fp;
 	struct stack_info info;
 
 	/* Final frame; nothing to unwind */
@@ -79,7 +79,7 @@ static int notrace unwind_next(struct task_struct *tsk,
 	if (!on_accessible_stack(tsk, fp, 16, &info))
 		return -EINVAL;
 
-	if (test_bit(info.type, frame->stacks_done))
+	if (test_bit(info.type, state->stacks_done))
 		return -EINVAL;
 
 	/*
@@ -95,27 +95,27 @@ static int notrace unwind_next(struct task_struct *tsk,
 	 * stack to another, it's never valid to unwind back to that first
 	 * stack.
 	 */
-	if (info.type == frame->prev_type) {
-		if (fp <= frame->prev_fp)
+	if (info.type == state->prev_type) {
+		if (fp <= state->prev_fp)
 			return -EINVAL;
 	} else {
-		set_bit(frame->prev_type, frame->stacks_done);
+		set_bit(state->prev_type, state->stacks_done);
 	}
 
 	/*
 	 * Record this frame record's values and location. The prev_fp and
 	 * prev_type are only meaningful to the next unwind_next() invocation.
 	 */
-	frame->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
-	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
-	frame->prev_fp = fp;
-	frame->prev_type = info.type;
+	state->fp = READ_ONCE_NOCHECK(*(unsigned long *)(fp));
+	state->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
+	state->prev_fp = fp;
+	state->prev_type = info.type;
 
-	frame->pc = ptrauth_strip_insn_pac(frame->pc);
+	state->pc = ptrauth_strip_insn_pac(state->pc);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	if (tsk->ret_stack &&
-		(frame->pc == (unsigned long)return_to_handler)) {
+		(state->pc == (unsigned long)return_to_handler)) {
 		unsigned long orig_pc;
 		/*
 		 * This is a case where function graph tracer has
@@ -123,16 +123,16 @@ static int notrace unwind_next(struct task_struct *tsk,
 		 * to hook a function return.
 		 * So replace it to an original value.
 		 */
-		orig_pc = ftrace_graph_ret_addr(tsk, NULL, frame->pc,
-						(void *)frame->fp);
-		if (WARN_ON_ONCE(frame->pc == orig_pc))
+		orig_pc = ftrace_graph_ret_addr(tsk, NULL, state->pc,
+						(void *)state->fp);
+		if (WARN_ON_ONCE(state->pc == orig_pc))
 			return -EINVAL;
-		frame->pc = orig_pc;
+		state->pc = orig_pc;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 #ifdef CONFIG_KRETPROBES
-	if (is_kretprobe_trampoline(frame->pc))
-		frame->pc = kretprobe_find_ret_addr(tsk, (void *)frame->fp, &frame->kr_cur);
+	if (is_kretprobe_trampoline(state->pc))
+		state->pc = kretprobe_find_ret_addr(tsk, (void *)state->fp, &state->kr_cur);
 #endif
 
 	return 0;
@@ -140,15 +140,15 @@ static int notrace unwind_next(struct task_struct *tsk,
 NOKPROBE_SYMBOL(unwind_next);
 
 static void notrace unwind(struct task_struct *tsk,
-			   struct stackframe *frame,
+			   struct unwind_state *state,
 			   bool (*fn)(void *, unsigned long), void *data)
 {
 	while (1) {
 		int ret;
 
-		if (!fn(data, frame->pc))
+		if (!fn(data, state->pc))
 			break;
-		ret = unwind_next(tsk, frame);
+		ret = unwind_next(tsk, state);
 		if (ret < 0)
 			break;
 	}
@@ -192,17 +192,17 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 			      void *cookie, struct task_struct *task,
 			      struct pt_regs *regs)
 {
-	struct stackframe frame;
+	struct unwind_state state;
 
 	if (regs)
-		unwind_init(&frame, regs->regs[29], regs->pc);
+		unwind_init(&state, regs->regs[29], regs->pc);
 	else if (task == current)
-		unwind_init(&frame,
+		unwind_init(&state,
 				(unsigned long)__builtin_frame_address(1),
 				(unsigned long)__builtin_return_address(0));
 	else
-		unwind_init(&frame, thread_saved_fp(task),
+		unwind_init(&state, thread_saved_fp(task),
 				thread_saved_pc(task));
 
-	unwind(task, &frame, consume_entry, cookie);
+	unwind(task, &state, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:55:57 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:55:57 -0600
Subject: [PATCH v13 00/11] arm64: Reorganize the unwinder and implement stack
 trace reliability checks
In-Reply-To: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
Message-ID: <20220117145608.6781-1-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

I have rebased this patch series on top of Linus' tree as of Jan 15, 2022.
The base commit is provided at the end of this email.

Remove NULL task check
======================

Currently, there is a check for a NULL task in unwind_frame(). It is not
needed since all current consumers pass a non-NULL task.

Rename unwinder functions
=========================

Rename unwinder functions to unwind*() similar to other architectures
for naming consistency.

	start_backtrace() ==> unwind_init()
	unwind_frame()    ==> unwind_next()
	walk_stackframe() ==> unwind()

Rename struct stackframe
========================

Rename "struct stackframe" to "struct unwind_state" for better naming
and consistency.

Split unwind_init()
===================

Unwind initialization has 3 cases. Accordingly, define 3 separate init
functions as follows:

	- unwind_init_from_regs()
	- unwind_init_from_current()
	- unwind_init_from_task()

This makes it easier to understand and add specialized code to each case
in the future.

Copy task argument
==================

Copy the task argument passed to arch_stack_walk() to unwind_state so that
it can be passed to unwind functions via unwind_state rather than as a
separate argument. The task is a fundamental part of the unwind state.

Use stack_trace_consume_fn
==========================

stack_trace_consume_fn is a typedef already defined. unwind() does not
use this for its consume_entry() argument. Fix this. Also, rename the
arguments to unwind() for better naming consistency.

Redefine the unwinder loop
==========================

Redefine the unwinder loop and make it simple and somewhat similar to other
architectures. Define the following:

	while (unwind_continue(&state, consume_entry, cookie))
		unwind_next(&state);

unwind_continue()
	This new function implements checks to determine whether the
	unwind should continue or terminate.

Reliability checks
==================

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_check_reliability() that will detect
these cases and set a boolean "reliable" in the stackframe. Call
unwind_check_reliability() for every frame.

Introduce the first reliability check in unwind_check_reliability() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code.

Other reliability checks will be added in the future.

Make unwind() return a boolean to indicate reliability of the stack trace.

SYM_CODE check
==============

This is the second reliability check implemented.

SYM_CODE functions do not follow normal calling conventions. They cannot
be unwound reliably using the frame pointer. Collect the address ranges
of these functions in a special section called "sym_code_functions".

In unwind_check_reliability(), check the return PC against these ranges. If
a match is found, then mark the stack trace unreliable.

Last stack frame
================

If a SYM_CODE function occurs in the very last frame in the stack trace,
then the stack trace is not considered unreliable. This is because there
is no more unwinding to do. Examples:

	- EL0 exception stack traces end in the top level EL0 exception
	  handlers.

	- All kernel thread stack traces end in ret_from_fork().

arch_stack_walk_reliable()
==========================

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except that it returns an error if the stack trace is
found to be unreliable.

Until all of the reliability checks are in place in
unwind_check_reliability(), arch_stack_walk_reliable() may not be used by
livepatch. But it may be used by debug and test code.

HAVE_RELIABLE_STACKTRACE
========================

Select this config for arm64. However, make it conditional on
STACK_VALIDATION. When objtool is enhanced to implement stack
validation for arm64, STACK_VALIDATION will be defined.

---
Changelog:
v13:
	From Mark Brown:

	- Reviewed-by for the following:

	[PATCH v12 03/10] arm64: Rename stackframe to unwind_state
	[PATCH v11 05/10] arm64: Copy unwind arguments to unwind_state
	[PATCH v11 07/10] arm64: Introduce stack trace reliability checks
	                  in the unwinder
	[PATCH v11 5/5] arm64: Create a list of SYM_CODE functions, check
	                return PC against list

	From Mark Rutland:

	- Reviewed-by for the following:

	[PATCH v12 01/10] arm64: Remove NULL task check from unwind_frame()
	[PATCH v12 02/10] arm64: Rename unwinder functions
	[PATCH v12 03/10] arm64: Rename stackframe to unwind_state

	- For each of the 3 cases of unwind initialization, have a separate
	  init function. Call the common init from each of these init
	  functions rather than call it separately.

	- Only copy the task argument to arch_stack_walk() into
	  unwind state. Pass the rest of the arguments as arguments to
	  unwind functions.

v12:
	From Mark Brown:

	- Reviewed-by for the following:

	[PATCH v11 1/5] arm64: Call stack_backtrace() only from within
	                walk_stackframe()
	[PATCH v11 2/5] arm64: Rename unwinder functions
	[PATCH v11 3/5] arm64: Make the unwind loop in unwind() similar to
	                other architectures
	[PATCH v11 5/5] arm64: Create a list of SYM_CODE functions, check
	                return PC against list

	- Add an extra patch at the end to select HAVE_RELIABLE_STACKTRACE
	  just as a place holder for the review. I have added it and made
	  it conditional on STACK_VALIDATION which has not yet been
	  implemented.

	- Mark had a concern about the code for the check for the final
	  frame being repeated in two places. I have now added a new
	  field called "final_fp" in struct stackframe which I compute
	  once in stacktrace initialization. I have added an explicit
	  comment that the stacktrace must terminate at the final_fp.

	- Place the implementation of arch_stack_walk_reliable() in a
	  separate patch after all the reliability checks have been
	  implemented.

	From Mark Rutland:

	- Place the removal of the NULL task check in unwind_frame() in
	  a separate patch.

	- Add a task field to struct stackframe so the task pointer can be
	  passed around via the frame instead of as a separate argument. I have
	  taken this a step further by copying all of the arguments to
	  arch_stack_walk() into struct stackframe so that only that
	  struct needs to be passed to unwind functions.

	- Rename start_backtrace() to unwind_init() instead of unwind_start().

	- Acked-by for the following:

	[PATCH v11 2/5] arm64: Rename unwinder functions

	- Rename "struct stackframe" to "struct unwind_state".

	- Define separate inline functions for initializing the starting
	  FP and PC from regs, or caller, or blocked task. Don't merge
	  unwind_init() into unwind().

v11:
	From Mark Rutland:

	- Peter Zijlstra has submitted patches that make ARCH_STACKWALK
	  independent of STACKTRACE. Mark Rutland extracted some of the
	  patches from my v10 series and added his own patches and comments,
	  rebased it on top of Peter's changes and submitted the series.
	  
	  So, I have rebased the rest of the patches from v10 on top of
	  Mark Rutland's changes.

	- Split the renaming of the unwinder functions and annotating them
	  with notrace and NOKPROBE_SYMBOL(). Also, there is currently no
	  need to annotate unwind_start() as its caller is already annotated
	  properly. So, I am removing the annotation patch from the series.
	  This can be done separately later if deemed necessary. Similarly,
	  I have removed the annotations from unwind_check_reliability() and
	  unwind_continue().

	From Nobuta Keiya:

	- unwind_start() should check for final frame and not mark the
	  final frame unreliable.

v9, v10:
	- v9 had a threading problem. So, I resent it as v10.

	From me:

	- Removed the word "RFC" from the subject line as I believe this
	  is mature enough to be a regular patch.

	From Mark Brown, Mark Rutland:

	- Split the patches into smaller, self-contained ones.

	- Always enable STACKTRACE so that arch_stack_walk() is always
	  defined.

	From Mark Rutland:

	- Update callchain_trace() take the return value of
	  perf_callchain_store() into acount.

	- Restore get_wchan() behavior to the original code.

	- Simplify an if statement in dump_backtrace().

	From Mark Brown:

	- Do not abort the stack trace on the first unreliable frame.

	
v8:
	- Synced to v5.14-rc5.

	From Mark Rutland:

	- Make the unwinder loop similar to other architectures.

	- Keep details to within the unwinder functions and return a simple
	  boolean to the caller.

	- Convert some of the current code that contains unwinder logic to
	  simply use arch_stack_walk(). I have converted all of them.

	- Do not copy sym_code_functions[]. Just place it in rodata for now.

	- Have the main loop check for termination conditions rather than
	  having unwind_frame() check for them. In other words, let
	  unwind_frame() assume that the fp is valid.

	- Replace the big comment for SYM_CODE functions with a shorter
	  comment.

		/*
		 * As SYM_CODE functions don't follow the usual calling
		 * conventions, we assume by default that any SYM_CODE function
		 * cannot be unwound reliably.
		 *
		 * Note that this includes:
		 *
		 * - Exception handlers and entry assembly
		 * - Trampoline assembly (e.g., ftrace, kprobes)
		 * - Hypervisor-related assembly
		 * - Hibernation-related assembly
		 * - CPU start-stop, suspend-resume assembly
		 * - Kernel relocation assembly
		 */

v7:
	The Mailer screwed up the threading on this. So, I have resent this
	same series as version 8 with proper threading to avoid confusion.
v6:
	From Mark Rutland:

	- The per-frame reliability concept and flag are acceptable. But more
	  work is needed to make the per-frame checks more accurate and more
	  complete. E.g., some code reorg is being worked on that will help.

	  I have now removed the frame->reliable flag and deleted the whole
	  concept of per-frame status. This is orthogonal to this patch series.
	  Instead, I have improved the unwinder to return proper return codes
	  so a caller can take appropriate action without needing per-frame
	  status.

	- Remove the mention of PLTs and update the comment.

	  I have replaced the comment above the call to __kernel_text_address()
	  with the comment suggested by Mark Rutland.

	Other comments:

	- Other comments on the per-frame stuff are not relevant because
	  that approach is not there anymore.

v5:
	From Keiya Nobuta:
	
	- The term blacklist(ed) is not to be used anymore. I have changed it
	  to unreliable. So, the function unwinder_blacklisted() has been
	  changed to unwinder_is_unreliable().

	From Mark Brown:

	- Add a comment for the "reliable" flag in struct stackframe. The
	  reliability attribute is not complete until all the checks are
	  in place. Added a comment above struct stackframe.

	- Include some of the comments in the cover letter in the actual
	  code so that we can compare it with the reliable stack trace
	  requirements document for completeness. I have added a comment:

	  	- above unwinder_is_unreliable() that lists the requirements
		  that are addressed by the function.

		- above the __kernel_text_address() call about all the cases
		  the call covers.

v4:
	From Mark Brown:

	- I was checking the return PC with __kernel_text_address() before
	  the Function Graph trace handling. Mark Brown felt that all the
	  reliability checks should be performed on the original return PC
	  once that is obtained. So, I have moved all the reliability checks
	  to after the Function Graph Trace handling code in the unwinder.
	  Basically, the unwinder should perform PC translations first (for
	  rhe return trampoline for Function Graph Tracing, Kretprobes, etc).
	  Then, the reliability checks should be applied to the resulting
	  PC.

	- Mark said to improve the naming of the new functions so they don't
	  collide with existing ones. I have used a prefix "unwinder_" for
	  all the new functions.

	From Josh Poimboeuf:

	- In the error scenarios in the unwinder, the reliable flag in the
	  stack frame should be set. Implemented this.

	- Some of the other comments are not relevant to the new code as
	  I have taken a different approach in the new code. That is why
	  I have not made those changes. E.g., Ard wanted me to add the
	  "const" keyword to the global section array. That array does not
	  exist in v4. Similarly, Mark Brown said to use ARRAY_SIZE() for
	  the same array in a for loop.

	Other changes:

	- Add a new definition for SYM_CODE_END() that adds the address
	  range of the function to a special section called
	  "sym_code_functions".

	- Include the new section under initdata in vmlinux.lds.S.

	- Define an early_initcall() to copy the contents of the
	  "sym_code_functions" section to an array by the same name.

	- Define a function unwinder_blacklisted() that compares a return
	  PC against sym_code_sections[]. If there is a match, mark the
	  stack trace unreliable. Call this from unwind_frame().

v3:
	- Implemented a sym_code_ranges[] array to contains sections bounds
	  for text sections that contain SYM_CODE_*() functions. The unwinder
	  checks each return PC against the sections. If it falls in any of
	  the sections, the stack trace is marked unreliable.

	- Moved SYM_CODE functions from .text and .init.text into a new
	  text section called ".code.text". Added this section to
	  vmlinux.lds.S and sym_code_ranges[].

	- Fixed the logic in the unwinder that handles Function Graph
	  Tracer return trampoline.

	- Removed all the previous code that handles:
		- ftrace entry code for traced function
		- special_functions[] array that lists individual functions
		- kretprobe_trampoline() special case

v2
	- Removed the terminating entry { 0, 0 } in special_functions[]
	  and replaced it with the idiom { /* sentinel */ }.

	- Change the ftrace trampoline entry ftrace_graph_call in
	  special_functions[] to ftrace_call + 4 and added explanatory
	  comments.

	- Unnested #ifdefs in special_functions[] for FTRACE.

v1
	- Define a bool field in struct stackframe. This will indicate if
	  a stack trace is reliable.

	- Implement a special_functions[] array that will be populated
	  with special functions in which the stack trace is considered
	  unreliable.
	
	- Using kallsyms_lookup(), get the address ranges for the special
	  functions and record them.

	- Implement an is_reliable_function(pc). This function will check
	  if a given return PC falls in any of the special functions. If
	  it does, the stack trace is unreliable.

	- Implement check_reliability() function that will check if a
	  stack frame is reliable. Call is_reliable_function() from
	  check_reliability().

	- Before a return PC is checked against special_funtions[], it
	  must be validates as a proper kernel text address. Call
	  __kernel_text_address() from check_reliability().

	- Finally, call check_reliability() from unwind_frame() for
	  each stack frame.

	- Add EL1 exception handlers to special_functions[].

		el1_sync();
		el1_irq();
		el1_error();
		el1_sync_invalid();
		el1_irq_invalid();
		el1_fiq_invalid();
		el1_error_invalid();

	- The above functions are currently defined as LOCAL symbols.
	  Make them global so that they can be referenced from the
	  unwinder code.

	- Add FTRACE trampolines to special_functions[]:

		ftrace_graph_call()
		ftrace_graph_caller()
		return_to_handler()

	- Add the kretprobe trampoline to special functions[]:

		kretprobe_trampoline()

Previous versions and discussion
================================

v12: https://lore.kernel.org/linux-arm-kernel/20220103165212.9303-1-madvenka at linux.microsoft.com/T/#m21e86eecb9b8f0831196568f0bf62c3b56f65bf0
v11: https://lore.kernel.org/linux-arm-kernel/20211123193723.12112-1-madvenka at linux.microsoft.com/T/#t
v10: https://lore.kernel.org/linux-arm-kernel/4b3d5552-590c-e6a0-866b-9bc51da7bebf at linux.microsoft.com/T/#t
v9: Mailer screwed up the threading. Sent the same as v10 with proper threading.
v8: https://lore.kernel.org/linux-arm-kernel/20210812190603.25326-1-madvenka at linux.microsoft.com/
v7: Mailer screwed up the threading. Sent the same as v8 with proper threading.
v6: https://lore.kernel.org/linux-arm-kernel/20210630223356.58714-1-madvenka at linux.microsoft.com/
v5: https://lore.kernel.org/linux-arm-kernel/20210526214917.20099-1-madvenka at linux.microsoft.com/
v4: https://lore.kernel.org/linux-arm-kernel/20210516040018.128105-1-madvenka at linux.microsoft.com/
v3: https://lore.kernel.org/linux-arm-kernel/20210503173615.21576-1-madvenka at linux.microsoft.com/
v2: https://lore.kernel.org/linux-arm-kernel/20210405204313.21346-1-madvenka at linux.microsoft.com/
v1: https://lore.kernel.org/linux-arm-kernel/20210330190955.13707-1-madvenka at linux.microsoft.com/

Madhavan T. Venkataraman (11):
  arm64: Remove NULL task check from unwind_frame()
  arm64: Rename unwinder functions
  arm64: Rename stackframe to unwind_state
  arm64: Split unwind_init()
  arm64: Copy the task argument to unwind_state
  arm64: Use stack_trace_consume_fn and rename args to unwind()
  arm64: Make the unwind loop in unwind() similar to other architectures
  arm64: Introduce stack trace reliability checks in the unwinder
  arm64: Create a list of SYM_CODE functions, check return PC against
    list
  arm64: Introduce arch_stack_walk_reliable()
  arm64: Select HAVE_RELIABLE_STACKTRACE

 arch/arm64/Kconfig                  |   1 +
 arch/arm64/include/asm/linkage.h    |  12 ++
 arch/arm64/include/asm/sections.h   |   1 +
 arch/arm64/include/asm/stacktrace.h |  14 +-
 arch/arm64/kernel/stacktrace.c      | 287 +++++++++++++++++++++-------
 arch/arm64/kernel/vmlinux.lds.S     |  10 +
 6 files changed, 258 insertions(+), 67 deletions(-)


base-commit: a33f5c380c4bd3fa5278d690421b72052456d9fe
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:01 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:01 -0600
Subject: [PATCH v13 04/11] arm64: Split unwind_init()
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-5-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

unwind_init() is currently a single function that initializes all of the
unwind state. Split it into the following functions and call them
appropriately:

	- unwind_init_from_regs() - initialize from regs passed by caller.

	- unwind_init_from_current() - initialize for the current task
	  from the caller of arch_stack_walk().

	- unwind_init_from_task() - initialize from the saved state of a
	  task other than the current task. In this case, the other
	  task must not be running.

This is done for two reasons:

	- the different ways of initializing are clear

	- specialized code can be added to each initializer in the future.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/kernel/stacktrace.c | 54 +++++++++++++++++++++++++++-------
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index a1a7ff93b84f..b2b568e5deba 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,11 +33,8 @@
  */
 
 
-static void unwind_init(struct unwind_state *state, unsigned long fp,
-			unsigned long pc)
+static void unwind_init_common(struct unwind_state *state)
 {
-	state->fp = fp;
-	state->pc = pc;
 #ifdef CONFIG_KRETPROBES
 	state->kr_cur = NULL;
 #endif
@@ -56,6 +53,46 @@ static void unwind_init(struct unwind_state *state, unsigned long fp,
 	state->prev_type = STACK_TYPE_UNKNOWN;
 }
 
+/*
+ * TODO: document requirements here.
+ */
+static inline void unwind_init_from_regs(struct unwind_state *state,
+					 struct pt_regs *regs)
+{
+	unwind_init_common(state);
+
+	state->fp = regs->regs[29];
+	state->pc = regs->pc;
+}
+
+/*
+ * TODO: document requirements here.
+ *
+ * Note: this is always inlined, and we expect our caller to be a noinline
+ * function, such that this starts from our caller's caller.
+ */
+static __always_inline void unwind_init_from_current(struct unwind_state *state)
+{
+	unwind_init_common(state);
+
+	state->fp = (unsigned long)__builtin_frame_address(1);
+	state->pc = (unsigned long)__builtin_return_address(0);
+}
+
+/*
+ * TODO: document requirements here.
+ *
+ * The caller guarantees that the task is not running.
+ */
+static inline void unwind_init_from_task(struct unwind_state *state,
+					 struct task_struct *task)
+{
+	unwind_init_common(state);
+
+	state->fp = thread_saved_fp(task);
+	state->pc = thread_saved_pc(task);
+}
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -195,14 +232,11 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 	struct unwind_state state;
 
 	if (regs)
-		unwind_init(&state, regs->regs[29], regs->pc);
+		unwind_init_from_regs(&state, regs);
 	else if (task == current)
-		unwind_init(&state,
-				(unsigned long)__builtin_frame_address(1),
-				(unsigned long)__builtin_return_address(0));
+		unwind_init_from_current(&state);
 	else
-		unwind_init(&state, thread_saved_fp(task),
-				thread_saved_pc(task));
+		unwind_init_from_task(&state, task);
 
 	unwind(task, &state, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:03 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:03 -0600
Subject: [PATCH v13 06/11] arm64: Use stack_trace_consume_fn and rename args
 to unwind()
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-7-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Rename the arguments to unwind() for better consistency. Also, use the
typedef stack_trace_consume_fn for the consume_entry function as it is
already defined in linux/stacktrace.h.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/kernel/stacktrace.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 1b32e55735aa..f772dac78b11 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -181,12 +181,12 @@ static int notrace unwind_next(struct unwind_state *state)
 NOKPROBE_SYMBOL(unwind_next);
 
 static void notrace unwind(struct unwind_state *state,
-			   bool (*fn)(void *, unsigned long), void *data)
+			   stack_trace_consume_fn consume_entry, void *cookie)
 {
 	while (1) {
 		int ret;
 
-		if (!fn(data, state->pc))
+		if (!consume_entry(cookie, state->pc))
 			break;
 		ret = unwind_next(state);
 		if (ret < 0)
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:02 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:02 -0600
Subject: [PATCH v13 05/11] arm64: Copy the task argument to unwind_state
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-6-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Copy the task argument passed to arch_stack_walk() to unwind_state so that
it can be passed to unwind functions via unwind_state rather than as a
separate argument. The task is a fundamental part of the unwind state.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/include/asm/stacktrace.h |  3 +++
 arch/arm64/kernel/stacktrace.c      | 29 ++++++++++++++++-------------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index 41ec360515f6..af423f5d7ad8 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -51,6 +51,8 @@ struct stack_info {
  * @kr_cur:      When KRETPROBES is selected, holds the kretprobe instance
  *               associated with the most recently encountered replacement lr
  *               value.
+ *
+ * @task:        Pointer to the task structure.
  */
 struct unwind_state {
 	unsigned long fp;
@@ -61,6 +63,7 @@ struct unwind_state {
 #ifdef CONFIG_KRETPROBES
 	struct llist_node *kr_cur;
 #endif
+	struct task_struct *task;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index b2b568e5deba..1b32e55735aa 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,8 +33,10 @@
  */
 
 
-static void unwind_init_common(struct unwind_state *state)
+static void unwind_init_common(struct unwind_state *state,
+			       struct task_struct *task)
 {
+	state->task = task;
 #ifdef CONFIG_KRETPROBES
 	state->kr_cur = NULL;
 #endif
@@ -57,9 +59,10 @@ static void unwind_init_common(struct unwind_state *state)
  * TODO: document requirements here.
  */
 static inline void unwind_init_from_regs(struct unwind_state *state,
+					 struct task_struct *task,
 					 struct pt_regs *regs)
 {
-	unwind_init_common(state);
+	unwind_init_common(state, task);
 
 	state->fp = regs->regs[29];
 	state->pc = regs->pc;
@@ -71,9 +74,10 @@ static inline void unwind_init_from_regs(struct unwind_state *state,
  * Note: this is always inlined, and we expect our caller to be a noinline
  * function, such that this starts from our caller's caller.
  */
-static __always_inline void unwind_init_from_current(struct unwind_state *state)
+static __always_inline void unwind_init_from_current(struct unwind_state *state,
+						     struct task_struct *task)
 {
-	unwind_init_common(state);
+	unwind_init_common(state, task);
 
 	state->fp = (unsigned long)__builtin_frame_address(1);
 	state->pc = (unsigned long)__builtin_return_address(0);
@@ -87,7 +91,7 @@ static __always_inline void unwind_init_from_current(struct unwind_state *state)
 static inline void unwind_init_from_task(struct unwind_state *state,
 					 struct task_struct *task)
 {
-	unwind_init_common(state);
+	unwind_init_common(state, task);
 
 	state->fp = thread_saved_fp(task);
 	state->pc = thread_saved_pc(task);
@@ -100,11 +104,11 @@ static inline void unwind_init_from_task(struct unwind_state *state,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_next(struct task_struct *tsk,
-			       struct unwind_state *state)
+static int notrace unwind_next(struct unwind_state *state)
 {
 	unsigned long fp = state->fp;
 	struct stack_info info;
+	struct task_struct *tsk = state->task;
 
 	/* Final frame; nothing to unwind */
 	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
@@ -176,8 +180,7 @@ static int notrace unwind_next(struct task_struct *tsk,
 }
 NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace unwind(struct task_struct *tsk,
-			   struct unwind_state *state,
+static void notrace unwind(struct unwind_state *state,
 			   bool (*fn)(void *, unsigned long), void *data)
 {
 	while (1) {
@@ -185,7 +188,7 @@ static void notrace unwind(struct task_struct *tsk,
 
 		if (!fn(data, state->pc))
 			break;
-		ret = unwind_next(tsk, state);
+		ret = unwind_next(state);
 		if (ret < 0)
 			break;
 	}
@@ -232,11 +235,11 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 	struct unwind_state state;
 
 	if (regs)
-		unwind_init_from_regs(&state, regs);
+		unwind_init_from_regs(&state, task, regs);
 	else if (task == current)
-		unwind_init_from_current(&state);
+		unwind_init_from_current(&state, task);
 	else
 		unwind_init_from_task(&state, task);
 
-	unwind(task, &state, consume_entry, cookie);
+	unwind(&state, consume_entry, cookie);
 }
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:04 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:04 -0600
Subject: [PATCH v13 07/11] arm64: Make the unwind loop in unwind() similar to
 other architectures
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-8-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Change the loop in unwind()
===========================

Change the unwind loop in unwind() to:

	while (unwind_continue(state, consume_entry, cookie))
		unwind_next(state);

This is easy to understand and maintain.

New function unwind_continue()
==============================

Define a new function unwind_continue() that is used in the unwind loop
to check for conditions that terminate a stack trace.

The conditions checked are:

	- If the bottom of the stack (final frame) has been reached,
	  terminate.

	- If the consume_entry() function returns false, the caller of
	  unwind has asked to terminate the stack trace. So, terminate.

	- If unwind_next() failed for some reason (like stack corruption),
	  terminate.

Do not return an error value from unwind_next()
===============================================

We want to check for terminating conditions only in unwind_continue() from
the unwinder loop. So, do not return an error value from unwind_next().
Simply set a flag in unwind_state and check the flag in unwind_continue().

Final FP
========

Introduce a new field "final_fp" in "struct unwind_state". Initialize this
to the final frame of the stack trace:

	task_pt_regs(task)->stackframe

This is where the stacktrace must terminate if it is successful. Add an
explicit comment to that effect.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/stacktrace.h |  6 +++
 arch/arm64/kernel/stacktrace.c      | 72 ++++++++++++++++++-----------
 2 files changed, 52 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index af423f5d7ad8..c11b048ffd0e 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -53,6 +53,10 @@ struct stack_info {
  *               value.
  *
  * @task:        Pointer to the task structure.
+ *
+ * @final_fp	 Pointer to the final frame.
+ *
+ * @failed:      Unwind failed.
  */
 struct unwind_state {
 	unsigned long fp;
@@ -64,6 +68,8 @@ struct unwind_state {
 	struct llist_node *kr_cur;
 #endif
 	struct task_struct *task;
+	unsigned long final_fp;
+	bool failed;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index f772dac78b11..73fc6b5ee6fd 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -53,6 +53,10 @@ static void unwind_init_common(struct unwind_state *state,
 	bitmap_zero(state->stacks_done, __NR_STACK_TYPES);
 	state->prev_fp = 0;
 	state->prev_type = STACK_TYPE_UNKNOWN;
+	state->failed = false;
+
+	/* Stack trace terminates here. */
+	state->final_fp = (unsigned long)task_pt_regs(task)->stackframe;
 }
 
 /*
@@ -97,6 +101,25 @@ static inline void unwind_init_from_task(struct unwind_state *state,
 	state->pc = thread_saved_pc(task);
 }
 
+static bool notrace unwind_continue(struct unwind_state *state,
+				    stack_trace_consume_fn consume_entry,
+				    void *cookie)
+{
+	if (state->failed) {
+		/* PC is suspect. Cannot consume it. */
+		return false;
+	}
+
+	if (!consume_entry(cookie, state->pc)) {
+		/* Caller terminated the unwind. */
+		state->failed = true;
+		return false;
+	}
+
+	return state->fp != state->final_fp;
+}
+NOKPROBE_SYMBOL(unwind_continue);
+
 /*
  * Unwind from one frame record (A) to the next frame record (B).
  *
@@ -104,24 +127,26 @@ static inline void unwind_init_from_task(struct unwind_state *state,
  * records (e.g. a cycle), determined based on the location and fp value of A
  * and the location (but not the fp value) of B.
  */
-static int notrace unwind_next(struct unwind_state *state)
+static void notrace unwind_next(struct unwind_state *state)
 {
 	unsigned long fp = state->fp;
 	struct stack_info info;
 	struct task_struct *tsk = state->task;
 
-	/* Final frame; nothing to unwind */
-	if (fp == (unsigned long)task_pt_regs(tsk)->stackframe)
-		return -ENOENT;
-
-	if (fp & 0x7)
-		return -EINVAL;
+	if (fp & 0x7) {
+		state->failed = true;
+		return;
+	}
 
-	if (!on_accessible_stack(tsk, fp, 16, &info))
-		return -EINVAL;
+	if (!on_accessible_stack(tsk, fp, 16, &info)) {
+		state->failed = true;
+		return;
+	}
 
-	if (test_bit(info.type, state->stacks_done))
-		return -EINVAL;
+	if (test_bit(info.type, state->stacks_done)) {
+		state->failed = true;
+		return;
+	}
 
 	/*
 	 * As stacks grow downward, any valid record on the same stack must be
@@ -137,8 +162,10 @@ static int notrace unwind_next(struct unwind_state *state)
 	 * stack.
 	 */
 	if (info.type == state->prev_type) {
-		if (fp <= state->prev_fp)
-			return -EINVAL;
+		if (fp <= state->prev_fp) {
+			state->failed = true;
+			return;
+		}
 	} else {
 		set_bit(state->prev_type, state->stacks_done);
 	}
@@ -166,8 +193,10 @@ static int notrace unwind_next(struct unwind_state *state)
 		 */
 		orig_pc = ftrace_graph_ret_addr(tsk, NULL, state->pc,
 						(void *)state->fp);
-		if (WARN_ON_ONCE(state->pc == orig_pc))
-			return -EINVAL;
+		if (WARN_ON_ONCE(state->pc == orig_pc)) {
+			state->failed = true;
+			return;
+		}
 		state->pc = orig_pc;
 	}
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
@@ -175,23 +204,14 @@ static int notrace unwind_next(struct unwind_state *state)
 	if (is_kretprobe_trampoline(state->pc))
 		state->pc = kretprobe_find_ret_addr(tsk, (void *)state->fp, &state->kr_cur);
 #endif
-
-	return 0;
 }
 NOKPROBE_SYMBOL(unwind_next);
 
 static void notrace unwind(struct unwind_state *state,
 			   stack_trace_consume_fn consume_entry, void *cookie)
 {
-	while (1) {
-		int ret;
-
-		if (!consume_entry(cookie, state->pc))
-			break;
-		ret = unwind_next(state);
-		if (ret < 0)
-			break;
-	}
+	while (unwind_continue(state, consume_entry, cookie))
+		unwind_next(state);
 }
 NOKPROBE_SYMBOL(unwind);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:05 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:05 -0600
Subject: [PATCH v13 08/11] arm64: Introduce stack trace reliability checks in
 the unwinder
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-9-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

There are some kernel features and conditions that make a stack trace
unreliable. Callers may require the unwinder to detect these cases.
E.g., livepatch.

Introduce a new function called unwind_check_reliability() that will
detect these cases and set a flag in the stack frame. Call
unwind_check_reliability() for every frame in unwind().

Introduce the first reliability check in unwind_check_reliability() - If
a return PC is not a valid kernel text address, consider the stack
trace unreliable. It could be some generated code. Other reliability checks
will be added in the future.

Let unwind() return a boolean to indicate if the stack trace is
reliable.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/stacktrace.h |  3 +++
 arch/arm64/kernel/stacktrace.c      | 28 ++++++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/stacktrace.h b/arch/arm64/include/asm/stacktrace.h
index c11b048ffd0e..26eba9d7e5c7 100644
--- a/arch/arm64/include/asm/stacktrace.h
+++ b/arch/arm64/include/asm/stacktrace.h
@@ -57,6 +57,8 @@ struct stack_info {
  * @final_fp	 Pointer to the final frame.
  *
  * @failed:      Unwind failed.
+ *
+ * @reliable:    Stack trace is reliable.
  */
 struct unwind_state {
 	unsigned long fp;
@@ -70,6 +72,7 @@ struct unwind_state {
 	struct task_struct *task;
 	unsigned long final_fp;
 	bool failed;
+	bool reliable;
 };
 
 extern void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk,
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 73fc6b5ee6fd..3dc0374e83f7 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,6 +18,25 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+/*
+ * Check the stack frame for conditions that make further unwinding unreliable.
+ */
+static void unwind_check_reliability(struct unwind_state *state)
+{
+	if (state->fp == state->final_fp) {
+		/* Final frame; no more unwind, no need to check reliability */
+		return;
+	}
+
+	/*
+	 * If the PC is not a known kernel text address, then we cannot
+	 * be sure that a subsequent unwind will be reliable, as we
+	 * don't know that the code follows our unwind requirements.
+	 */
+	if (!__kernel_text_address(state->pc))
+		state->reliable = false;
+}
+
 /*
  * AArch64 PCS assigns the frame pointer to x29.
  *
@@ -54,6 +73,7 @@ static void unwind_init_common(struct unwind_state *state,
 	state->prev_fp = 0;
 	state->prev_type = STACK_TYPE_UNKNOWN;
 	state->failed = false;
+	state->reliable = true;
 
 	/* Stack trace terminates here. */
 	state->final_fp = (unsigned long)task_pt_regs(task)->stackframe;
@@ -207,11 +227,15 @@ static void notrace unwind_next(struct unwind_state *state)
 }
 NOKPROBE_SYMBOL(unwind_next);
 
-static void notrace unwind(struct unwind_state *state,
+static bool notrace unwind(struct unwind_state *state,
 			   stack_trace_consume_fn consume_entry, void *cookie)
 {
-	while (unwind_continue(state, consume_entry, cookie))
+	unwind_check_reliability(state);
+	while (unwind_continue(state, consume_entry, cookie)) {
 		unwind_next(state);
+		unwind_check_reliability(state);
+	}
+	return !state->failed && state->reliable;
 }
 NOKPROBE_SYMBOL(unwind);
 
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:06 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:06 -0600
Subject: [PATCH v13 09/11] arm64: Create a list of SYM_CODE functions,
 check return PC against list
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-10-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

SYM_CODE functions don't follow the usual calling conventions. Check if the
return PC in a stack frame falls in any of these. If it does, consider the
stack trace unreliable.

Define a special section for unreliable functions
=================================================

Define a SYM_CODE_END() macro for arm64 that adds the function address
range to a new section called "sym_code_functions".

Linker file
===========

Include the "sym_code_functions" section under read-only data in
vmlinux.lds.S.

Initialization
==============

Define an early_initcall() to create a sym_code_functions[] array from
the linker data.

Unwinder check
==============

Add a reliability check in unwind_check_reliability() that compares a
return PC with sym_code_functions[]. If there is a match, then return
failure.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/linkage.h  | 12 +++++++
 arch/arm64/include/asm/sections.h |  1 +
 arch/arm64/kernel/stacktrace.c    | 55 +++++++++++++++++++++++++++++++
 arch/arm64/kernel/vmlinux.lds.S   | 10 ++++++
 4 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index b77e9b3f5371..a47e7914b289 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -63,4 +63,16 @@
 		SYM_FUNC_END_ALIAS(x);		\
 		SYM_FUNC_END_ALIAS(__pi_##x)
 
+/*
+ * Record the address range of each SYM_CODE function in a struct code_range
+ * in a special section.
+ */
+#define SYM_CODE_END(name)				\
+	SYM_END(name, SYM_T_NONE)			;\
+	99:						;\
+	.pushsection "sym_code_functions", "aw"		;\
+	.quad	name					;\
+	.quad	99b					;\
+	.popsection
+
 #endif
diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h
index 152cb35bf9df..ac01189668c5 100644
--- a/arch/arm64/include/asm/sections.h
+++ b/arch/arm64/include/asm/sections.h
@@ -22,5 +22,6 @@ extern char __irqentry_text_start[], __irqentry_text_end[];
 extern char __mmuoff_data_start[], __mmuoff_data_end[];
 extern char __entry_tramp_text_start[], __entry_tramp_text_end[];
 extern char __relocate_new_kernel_start[], __relocate_new_kernel_end[];
+extern char __sym_code_functions_start[], __sym_code_functions_end[];
 
 #endif /* __ASM_SECTIONS_H */
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 3dc0374e83f7..8bfe31cbee46 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -18,11 +18,40 @@
 #include <asm/stack_pointer.h>
 #include <asm/stacktrace.h>
 
+struct code_range {
+	unsigned long	start;
+	unsigned long	end;
+};
+
+static struct code_range	*sym_code_functions;
+static int			num_sym_code_functions;
+
+int __init init_sym_code_functions(void)
+{
+	size_t size = (unsigned long)__sym_code_functions_end -
+		      (unsigned long)__sym_code_functions_start;
+
+	sym_code_functions = (struct code_range *)__sym_code_functions_start;
+	/*
+	 * Order it so that sym_code_functions is not visible before
+	 * num_sym_code_functions.
+	 */
+	smp_mb();
+	num_sym_code_functions = size / sizeof(struct code_range);
+
+	return 0;
+}
+early_initcall(init_sym_code_functions);
+
 /*
  * Check the stack frame for conditions that make further unwinding unreliable.
  */
 static void unwind_check_reliability(struct unwind_state *state)
 {
+	const struct code_range *range;
+	unsigned long pc;
+	int i;
+
 	if (state->fp == state->final_fp) {
 		/* Final frame; no more unwind, no need to check reliability */
 		return;
@@ -35,6 +64,32 @@ static void unwind_check_reliability(struct unwind_state *state)
 	 */
 	if (!__kernel_text_address(state->pc))
 		state->reliable = false;
+
+	/*
+	 * Check the return PC against sym_code_functions[]. If there is a
+	 * match, then the consider the stack frame unreliable.
+	 *
+	 * As SYM_CODE functions don't follow the usual calling conventions,
+	 * we assume by default that any SYM_CODE function cannot be unwound
+	 * reliably.
+	 *
+	 * Note that this includes:
+	 *
+	 * - Exception handlers and entry assembly
+	 * - Trampoline assembly (e.g., ftrace, kprobes)
+	 * - Hypervisor-related assembly
+	 * - Hibernation-related assembly
+	 * - CPU start-stop, suspend-resume assembly
+	 * - Kernel relocation assembly
+	 */
+	pc = state->pc;
+	for (i = 0; i < num_sym_code_functions; i++) {
+		range = &sym_code_functions[i];
+		if (pc >= range->start && pc < range->end) {
+			state->reliable = false;
+			return;
+		}
+	}
 }
 
 /*
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index 50bab186c49b..6381e75e566e 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -122,6 +122,14 @@ jiffies = jiffies_64;
 #define TRAMP_TEXT
 #endif
 
+#define SYM_CODE_FUNCTIONS				\
+	. = ALIGN(16);					\
+	.symcode : AT(ADDR(.symcode) - LOAD_OFFSET) {	\
+		__sym_code_functions_start = .;		\
+		KEEP(*(sym_code_functions))		\
+		__sym_code_functions_end = .;		\
+	}
+
 /*
  * The size of the PE/COFF section that covers the kernel image, which
  * runs from _stext to _edata, must be a round multiple of the PE/COFF
@@ -209,6 +217,8 @@ SECTIONS
 	swapper_pg_dir = .;
 	. += PAGE_SIZE;
 
+	SYM_CODE_FUNCTIONS
+
 	. = ALIGN(SEGMENT_ALIGN);
 	__init_begin = .;
 	__inittext_begin = .;
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:07 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:07 -0600
Subject: [PATCH v13 10/11] arm64: Introduce arch_stack_walk_reliable()
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-11-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Introduce arch_stack_walk_reliable() for ARM64. This works like
arch_stack_walk() except that it returns -EINVAL if the stack trace is not
reliable.

Until all the reliability checks are in place, arch_stack_walk_reliable()
may not be used by livepatch. But it may be used by debug and test code.

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
Reviewed-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/stacktrace.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 8bfe31cbee46..4902fac5745f 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -342,3 +342,25 @@ noinline notrace void arch_stack_walk(stack_trace_consume_fn consume_entry,
 
 	unwind(&state, consume_entry, cookie);
 }
+
+/*
+ * arch_stack_walk_reliable() may not be used for livepatch until all of
+ * the reliability checks are in place in unwind_consume(). However,
+ * debug and test code can choose to use it even if all the checks are not
+ * in place.
+ */
+noinline int notrace arch_stack_walk_reliable(stack_trace_consume_fn consume_fn,
+					      void *cookie,
+					      struct task_struct *task)
+{
+	struct unwind_state state;
+	bool reliable;
+
+	if (task == current)
+		unwind_init_from_current(&state, task);
+	else
+		unwind_init_from_task(&state, task);
+
+	reliable = unwind(&state, consume_fn, cookie);
+	return reliable ? 0 : -EINVAL;
+}
-- 
2.25.1



From madvenka at linux.microsoft.com  Mon Jan 17 06:56:08 2022
From: madvenka at linux.microsoft.com (madvenka at linux.microsoft.com)
Date: Mon, 17 Jan 2022 08:56:08 -0600
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <20220117145608.6781-1-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
Message-ID: <20220117145608.6781-12-madvenka@linux.microsoft.com>

From: "Madhavan T. Venkataraman" <madvenka at linux.microsoft.com>

Select HAVE_RELIABLE_STACKTRACE in arm64/Kconfig to allow
arch_stack_walk_reliable() to be used.

Note that this is conditional upon STACK_VALIDATION which will be added
when frame pointer validation is implemented (say via objtool).

Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
---
 arch/arm64/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f6e333b59314..bc7b3514b563 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -223,6 +223,7 @@ config ARM64
 	select THREAD_INFO_IN_TASK
 	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
 	select TRACE_IRQFLAGS_SUPPORT
+	select HAVE_RELIABLE_STACKTRACE if FRAME_POINTER && STACK_VALIDATION
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
-- 
2.25.1



From andre.przywara at arm.com  Mon Jan 17 06:59:00 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 14:59:00 +0000
Subject: [bootwrapper PATCH v2 11/13] Announce locations of memory objects
In-Reply-To: <20220114105653.3003399-12-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-12-mark.rutland@arm.com>
Message-ID: <20220117145901.483ec044@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:51 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> To make it easier to debug boot failures, log the location of memory
> objects at boot time.
> 
> This is logged to the serial console as:
> 
> | Boot-wrapper v0.2
> | Entered at EL3
> | Memory layout:
> | [0000000080000000..0000000080001f90] => boot-wrapper
> | [000000008000fff8..0000000080010000] => mbox
> | [0000000080200000..00000000822af200] => kernel
> | [0000000088000000..0000000088002857] => dtb

That looks indeed very useful!

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  common/init.c      | 27 +++++++++++++++++++++++++++
>  common/platform.c  | 13 +++++++++++++
>  include/platform.h |  2 ++
>  model.lds.S        | 20 ++++++++++++++------
>  4 files changed, 56 insertions(+), 6 deletions(-)
> 
> diff --git a/common/init.c b/common/init.c
> index 2600f73..fc74b9e 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
>  	print_string("Boot-wrapper v0.2\r\n");
>  }
>  
> +#define announce_object(object, desc)				\
> +do {								\
> +	extern char object##__start[];				\
> +	extern char object##__end[];				\
> +	print_string("[");					\
> +	print_ulong_hex((unsigned long)object##__start);	\
> +	print_string("..");					\
> +	print_ulong_hex((unsigned long)object##__end);		\
> +	print_string("] => " desc "\r\n");			\
> +} while (0)
> +
> +static void announce_objects(void)
> +{
> +	print_string("Memory layout:\r\n");
> +	announce_object(text, "boot-wrapper");
> +	announce_object(mbox, "mbox");
> +	announce_object(kernel, "kernel");
> +#ifdef XEN
> +	announce_object(xen, "xen");
> +#endif
> +	announce_object(dtb, "dtb");
> +#ifdef USE_INITRD
> +	announce_object(filesystem, "initrd");
> +#endif
> +}
> +
>  void announce_arch(void);
>  
>  void cpu_init_bootwrapper(void)
> @@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
>  		init_uart();
>  		announce_bootwrapper();
>  		announce_arch();
> +		announce_objects();
>  		print_string("\r\n");
>  		init_platform();
>  	}
> diff --git a/common/platform.c b/common/platform.c
> index 80d0562..26e5944 100644
> --- a/common/platform.c
> +++ b/common/platform.c
> @@ -52,6 +52,19 @@ void print_string(const char *str)
>  		print_char(*str++);
>  }
>  
> +#define HEX_CHARS_PER_LONG (2 * sizeof(long))
> +
> +void print_ulong_hex(unsigned long val)
> +{
> +	const char hex_chars[16] = "0123456789abcdef";
> +	int i;
> +
> +	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
> +		int v = (val >> (4 * i)) & 0xf;
> +		print_char(hex_chars[v]);
> +	}
> +}
> +
>  void init_uart(void)
>  {
>  	/*
> diff --git a/include/platform.h b/include/platform.h
> index 237b481..c88e124 100644
> --- a/include/platform.h
> +++ b/include/platform.h
> @@ -11,6 +11,8 @@
>  
>  void print_char(char c);
>  void print_string(const char *str);
> +void print_ulong_hex(unsigned long val);
> +
>  void init_uart(void);
>  
>  void init_platform(void);
> diff --git a/model.lds.S b/model.lds.S
> index d4e7e13..dacaa25 100644
> --- a/model.lds.S
> +++ b/model.lds.S
> @@ -35,46 +35,54 @@ SECTIONS
>  	 * the boot section's *(.data)
>  	 */
>  	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
> -		kernel = .;
> +		kernel__start = .;
>  		KERNEL
> +		kernel__end = .;
>  	}
>  
>  #ifdef XEN
>  	.xen (PHYS_OFFSET + XEN_OFFSET): {
> -		xen = .;
> +		xen__start = .;
>  		XEN
> +		xen__end = .;
>  	}
>  
> -	entrypoint = xen;
> +	entrypoint = xen__start;
>  #else
> -	entrypoint = kernel;
> +	entrypoint = kernel__start;
>  #endif
>  
>  	.dtb (PHYS_OFFSET + FDT_OFFSET): {
> +		dtb__start = .;
>  		dtb = .;
>  		./fdt.dtb
> +		dtb__end = .;
>  	}
>  
>  #ifdef USE_INITRD
>  	.filesystem (PHYS_OFFSET + FS_OFFSET): {
> -		filesystem = .;
> +		filesystem__start = .;
>  		FILESYSTEM
> -		fs_size = . - filesystem;
> +		filesystem__end = .;
>  	}
>  #endif
>  
>  	.boot PHYS_OFFSET: {
> +		text__start = .;
>  		*(.init)
>  		*(.text*)
>  		*(.data* .rodata* .bss* COMMON)
>  		*(.vectors)
>  		*(.stack)
>  		PROVIDE(etext = .);
> +		text__end = .;
>  	}
>  
>  	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
> +		mbox__start = .;
>  		mbox = .;
>  		QUAD(0x0)
> +		mbox__end = .;
>  	}
>  
>  	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")



From krzysztof.kozlowski at canonical.com  Mon Jan 17 07:00:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 16:00:44 +0100
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <CAK8P3a31bCHNcNWrLX+QW+4RuK=DBpxLA_j5BFKxXxXKCT8PFQ@mail.gmail.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
 <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
 <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>
 <00c901d80ba5$c9ae6ab0$5d0b4010$@samsung.com>
 <CAK8P3a31bCHNcNWrLX+QW+4RuK=DBpxLA_j5BFKxXxXKCT8PFQ@mail.gmail.com>
Message-ID: <9b98fd89-87b5-5026-fb0c-16bb956801ea@canonical.com>

On 17/01/2022 15:14, Arnd Bergmann wrote:
> On Mon, Jan 17, 2022 at 2:26 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:
>>
>>> I cannot judge how different this is from Exynos subarchitecture - looking at
>>> patches it is not different - so I could understand a FSD sub-arch with only one
>>> SoC.
>>>
>> I understand, it is a bit difficult to visualize it with the current patch set.
>> As discuss on the other thread, FSD is different, more over the vendor is different, internal design is different.
> 
> Is it based on another SoC design then? Most new SoCs are derived from
> some other
> one, so it makes sense to put it into the same family. E.g. the Apple
> M1 takes bits from
> both Exynos and PA-Semi SoCs but has more newly added components than
> either one.

It seems Apple M1 shares only few bits with SoC. I am aware of only UART
driver as directly re-usable.

> 
> I would argue that if this SoC shares the pinctrl, clock, spi, adc,
> and timer implementation

Plus: UART, watchdog, PWM, I2C, I2S, USB PHY, DWC3 USB (in Exynos
flavor), UFS (also in Exynos-looking flavor), MFC (video codec), some
similarities in DW PCIe, TMU (thermal). Looking at DTS there are
differences but just few comparing to most of shared blocks.

Additionally SoC BSP (and maybe SoC itself...) was actually developed or
co-developed by Samsung, judging by copyrights in the BSP code. Even the
original DTSI has:

	TURBO TRAV SoC device tree source
	Copyright (c) 2017 Samsung Electronics Co., Ltd.


Tesla could still customize it a lot, but it is a strong hint that most
of it came from Samsung LSI and shares with existing Samsung designs.

Have in mind that recent Exynos chips are significantly different than
early ARMv7 or ARMv8 designs and we still consider them part of Exynos
family.

> with Exynos, we should consider it part of the Exynos family,
> regardless of what other
> blocks may exist next to those.

Yes. I don't see the benefit of keeping it outside of Exynos. It will
sprinkle "depends on ARCH_EXYNOS || ARCH_FSD" all over (or depend on
Exynos like you suggested).


Best regards,
Krzysztof


From rostedt at goodmis.org  Mon Jan 17 07:03:14 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Mon, 17 Jan 2022 10:03:14 -0500
Subject: [PATCHv8 4/5] lib: Add register read/write tracing support
In-Reply-To: <8ad60797d6d8f40c3bdba20b1678fa9014bc1a20.1642309054.git.quic_saipraka@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
 <8ad60797d6d8f40c3bdba20b1678fa9014bc1a20.1642309054.git.quic_saipraka@quicinc.com>
Message-ID: <20220117100314.416a4d68@rorschach.local.home>

On Mon, 17 Jan 2022 09:02:53 +0530
Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:

> diff --git a/include/trace/events/rwmmio.h b/include/trace/events/rwmmio.h
> new file mode 100644
> index 000000000000..798fbe1ac9f9
> --- /dev/null
> +++ b/include/trace/events/rwmmio.h
> @@ -0,0 +1,112 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +#undef TRACE_SYSTEM
> +#define TRACE_SYSTEM rwmmio
> +
> +#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
> +#define _TRACE_RWMMIO_H
> +
> +#include <linux/tracepoint.h>
> +
> +TRACE_EVENT(rwmmio_write,
> +
> +	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
> +
> +	TP_ARGS(caller, val, width, addr),
> +
> +	TP_STRUCT__entry(
> +		__field(u64, caller)
> +		__field(u64, val)
> +		__field(u64, addr)
> +		__field(u8, width)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->caller = caller;
> +		__entry->val = val;
> +		__entry->addr = (unsigned long)(void *)addr;
> +		__entry->width = width;
> +	),
> +
> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
> +		(void *)(unsigned long)__entry->caller, __entry->width,
> +		__entry->val, __entry->addr)
> +);
> +
> +TRACE_EVENT(rwmmio_post_write,
> +
> +	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
> +
> +	TP_ARGS(caller, val, width, addr),
> +
> +	TP_STRUCT__entry(
> +		__field(u64, caller)
> +		__field(u64, val)
> +		__field(u64, addr)
> +		__field(u8, width)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->caller = caller;
> +		__entry->val = val;
> +		__entry->addr = (unsigned long)(void *)addr;
> +		__entry->width = width;
> +	),
> +
> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
> +		(void *)(unsigned long)__entry->caller, __entry->width,
> +		__entry->val, __entry->addr)
> +);
> +
> +TRACE_EVENT(rwmmio_read,
> +
> +	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
> +
> +	TP_ARGS(caller, width, addr),
> +
> +	TP_STRUCT__entry(
> +		__field(u64, caller)
> +		__field(u64, addr)
> +		__field(u8, width)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->caller = caller;
> +		__entry->addr = (unsigned long)(void *)addr;
> +		__entry->width = width;
> +	),
> +
> +	TP_printk("%pS width=%d addr=%#llx",
> +		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
> +);
> +
> +TRACE_EVENT(rwmmio_post_read,
> +
> +	TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
> +
> +	TP_ARGS(caller, val, width, addr),
> +
> +	TP_STRUCT__entry(
> +		__field(u64, caller)
> +		__field(u64, val)
> +		__field(u64, addr)
> +		__field(u8, width)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->caller = caller;
> +		__entry->val = val;
> +		__entry->addr = (unsigned long)(void *)addr;
> +		__entry->width = width;
> +	),
> +
> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
> +		 (void *)(unsigned long)__entry->caller, __entry->width,
> +		 __entry->val, __entry->addr)
> +);

The above should be replaced with:

DECLARE_EVENT_CLASS(rwmmio_rw_template,

	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),

	TP_ARGS(caller, val, width, addr),

	TP_STRUCT__entry(
		__field(u64, caller)
		__field(u64, val)
		__field(u64, addr)
		__field(u8, width)
	),

	TP_fast_assign(
		__entry->caller = caller;
		__entry->val = val;
		__entry->addr = (unsigned long)(void *)addr;
		__entry->width = width;
	),

	TP_printk("%pS width=%d val=%#llx addr=%#llx",
		(void *)(unsigned long)__entry->caller, __entry->width,
		__entry->val, __entry->addr)
);

DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
	TP_ARGS(caller, val, width, addr)
);

DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
	TP_ARGS(caller, val, width, addr)
);

DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_read,
	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
	TP_ARGS(caller, val, width, addr)
);

It will save around 15k in memory.

And since rwmmio_read doesn't have a val field, it can stay a TRACE_EVENT.

TRACE_EVENT(rwmmio_read,

	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),

	TP_ARGS(caller, width, addr),

	TP_STRUCT__entry(
		__field(u64, caller)
		__field(u64, addr)
		__field(u8, width)
	),

	TP_fast_assign(
		__entry->caller = caller;
		__entry->addr = (unsigned long)(void *)addr;
		__entry->width = width;
	),

	TP_printk("%pS width=%d addr=%#llx",
		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
);

-- Steve

> +
> +#endif /* _TRACE_RWMMIO_H */
> +
> +#include <trace/define_trace.h>
> diff --git a/lib/Kconfig b/lib/Kconfig
> index c80fde816a7e..ea520c315c0f 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
>  	  mmio accesses when the IO memory address is not a registered
>  	  emulated region.
>  
> +config TRACE_MMIO_ACCESS
> +	bool "Register read/write tracing"
> +	depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
> +	help
> +	  Create tracepoints for MMIO read/write operations. These trace events
> +	  can be used for logging all MMIO read/write operations.
> +
>  source "lib/crypto/Kconfig"
>  
>  config CRC_CCITT
> diff --git a/lib/Makefile b/lib/Makefile
> index 300f569c626b..43813b0061cd 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -152,6 +152,8 @@ lib-y += logic_pio.o
>  
>  lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
>  
> +obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
> +
>  obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
>  
>  obj-$(CONFIG_BTREE) += btree.o
> diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
> new file mode 100644
> index 000000000000..88637038b30c
> --- /dev/null
> +++ b/lib/trace_readwrite.c
> @@ -0,0 +1,47 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Register read and write tracepoints
> + *
> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/ftrace.h>
> +#include <linux/module.h>
> +#include <asm-generic/io.h>
> +
> +#define CREATE_TRACE_POINTS
> +#include <trace/events/rwmmio.h>
> +
> +#ifdef CONFIG_TRACE_MMIO_ACCESS
> +void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
> +		    unsigned long caller_addr)
> +{
> +	trace_rwmmio_write(caller_addr, val, width, addr);
> +}
> +EXPORT_SYMBOL_GPL(log_write_mmio);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
> +
> +void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
> +			 unsigned long caller_addr)
> +{
> +	trace_rwmmio_post_write(caller_addr, val, width, addr);
> +}
> +EXPORT_SYMBOL_GPL(log_post_write_mmio);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
> +
> +void log_read_mmio(u8 width, const volatile void __iomem *addr,
> +		   unsigned long caller_addr)
> +{
> +	trace_rwmmio_read(caller_addr, width, addr);
> +}
> +EXPORT_SYMBOL_GPL(log_read_mmio);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
> +
> +void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
> +			unsigned long caller_addr)
> +{
> +	trace_rwmmio_post_read(caller_addr, val, width, addr);
> +}
> +EXPORT_SYMBOL_GPL(log_post_read_mmio);
> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
> +#endif /* CONFIG_TRACE_MMIO_ACCESS */



From quic_saipraka at quicinc.com  Mon Jan 17 07:30:27 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 21:00:27 +0530
Subject: [PATCHv8 4/5] lib: Add register read/write tracing support
In-Reply-To: <20220117100314.416a4d68@rorschach.local.home>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
 <8ad60797d6d8f40c3bdba20b1678fa9014bc1a20.1642309054.git.quic_saipraka@quicinc.com>
 <20220117100314.416a4d68@rorschach.local.home>
Message-ID: <8bbe3552-cd47-c9d4-a296-ba446b7b2f45@quicinc.com>

Hi Steve,

On 1/17/2022 8:33 PM, Steven Rostedt wrote:
> On Mon, 17 Jan 2022 09:02:53 +0530
> Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
>
>> diff --git a/include/trace/events/rwmmio.h b/include/trace/events/rwmmio.h
>> new file mode 100644
>> index 000000000000..798fbe1ac9f9
>> --- /dev/null
>> +++ b/include/trace/events/rwmmio.h
>> @@ -0,0 +1,112 @@
>> +/* SPDX-License-Identifier: GPL-2.0-only */
>> +/*
>> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +#undef TRACE_SYSTEM
>> +#define TRACE_SYSTEM rwmmio
>> +
>> +#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
>> +#define _TRACE_RWMMIO_H
>> +
>> +#include <linux/tracepoint.h>
>> +
>> +TRACE_EVENT(rwmmio_write,
>> +
>> +	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
>> +
>> +	TP_ARGS(caller, val, width, addr),
>> +
>> +	TP_STRUCT__entry(
>> +		__field(u64, caller)
>> +		__field(u64, val)
>> +		__field(u64, addr)
>> +		__field(u8, width)
>> +	),
>> +
>> +	TP_fast_assign(
>> +		__entry->caller = caller;
>> +		__entry->val = val;
>> +		__entry->addr = (unsigned long)(void *)addr;
>> +		__entry->width = width;
>> +	),
>> +
>> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
>> +		(void *)(unsigned long)__entry->caller, __entry->width,
>> +		__entry->val, __entry->addr)
>> +);
>> +
>> +TRACE_EVENT(rwmmio_post_write,
>> +
>> +	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
>> +
>> +	TP_ARGS(caller, val, width, addr),
>> +
>> +	TP_STRUCT__entry(
>> +		__field(u64, caller)
>> +		__field(u64, val)
>> +		__field(u64, addr)
>> +		__field(u8, width)
>> +	),
>> +
>> +	TP_fast_assign(
>> +		__entry->caller = caller;
>> +		__entry->val = val;
>> +		__entry->addr = (unsigned long)(void *)addr;
>> +		__entry->width = width;
>> +	),
>> +
>> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
>> +		(void *)(unsigned long)__entry->caller, __entry->width,
>> +		__entry->val, __entry->addr)
>> +);
>> +
>> +TRACE_EVENT(rwmmio_read,
>> +
>> +	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
>> +
>> +	TP_ARGS(caller, width, addr),
>> +
>> +	TP_STRUCT__entry(
>> +		__field(u64, caller)
>> +		__field(u64, addr)
>> +		__field(u8, width)
>> +	),
>> +
>> +	TP_fast_assign(
>> +		__entry->caller = caller;
>> +		__entry->addr = (unsigned long)(void *)addr;
>> +		__entry->width = width;
>> +	),
>> +
>> +	TP_printk("%pS width=%d addr=%#llx",
>> +		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
>> +);
>> +
>> +TRACE_EVENT(rwmmio_post_read,
>> +
>> +	TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
>> +
>> +	TP_ARGS(caller, val, width, addr),
>> +
>> +	TP_STRUCT__entry(
>> +		__field(u64, caller)
>> +		__field(u64, val)
>> +		__field(u64, addr)
>> +		__field(u8, width)
>> +	),
>> +
>> +	TP_fast_assign(
>> +		__entry->caller = caller;
>> +		__entry->val = val;
>> +		__entry->addr = (unsigned long)(void *)addr;
>> +		__entry->width = width;
>> +	),
>> +
>> +	TP_printk("%pS width=%d val=%#llx addr=%#llx",
>> +		 (void *)(unsigned long)__entry->caller, __entry->width,
>> +		 __entry->val, __entry->addr)
>> +);
> The above should be replaced with:
>
> DECLARE_EVENT_CLASS(rwmmio_rw_template,
>
> 	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
>
> 	TP_ARGS(caller, val, width, addr),
>
> 	TP_STRUCT__entry(
> 		__field(u64, caller)
> 		__field(u64, val)
> 		__field(u64, addr)
> 		__field(u8, width)
> 	),
>
> 	TP_fast_assign(
> 		__entry->caller = caller;
> 		__entry->val = val;
> 		__entry->addr = (unsigned long)(void *)addr;
> 		__entry->width = width;
> 	),
>
> 	TP_printk("%pS width=%d val=%#llx addr=%#llx",
> 		(void *)(unsigned long)__entry->caller, __entry->width,
> 		__entry->val, __entry->addr)
> );
>
> DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
> 	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
> 	TP_ARGS(caller, val, width, addr)
> );
>
> DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
> 	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
> 	TP_ARGS(caller, val, width, addr)
> );
>
> DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_read,
> 	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
> 	TP_ARGS(caller, val, width, addr)
> );
>
> It will save around 15k in memory.
>
> And since rwmmio_read doesn't have a val field, it can stay a TRACE_EVENT.
>
> TRACE_EVENT(rwmmio_read,
>
> 	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
>
> 	TP_ARGS(caller, width, addr),
>
> 	TP_STRUCT__entry(
> 		__field(u64, caller)
> 		__field(u64, addr)
> 		__field(u8, width)
> 	),
>
> 	TP_fast_assign(
> 		__entry->caller = caller;
> 		__entry->addr = (unsigned long)(void *)addr;
> 		__entry->width = width;
> 	),
>
> 	TP_printk("%pS width=%d addr=%#llx",
> 		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
> );
>
> -- Steve

Thanks for the review, will add these changes in next version.

Thanks,
Sai

>> +
>> +#endif /* _TRACE_RWMMIO_H */
>> +
>> +#include <trace/define_trace.h>
>> diff --git a/lib/Kconfig b/lib/Kconfig
>> index c80fde816a7e..ea520c315c0f 100644
>> --- a/lib/Kconfig
>> +++ b/lib/Kconfig
>> @@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
>>   	  mmio accesses when the IO memory address is not a registered
>>   	  emulated region.
>>   
>> +config TRACE_MMIO_ACCESS
>> +	bool "Register read/write tracing"
>> +	depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
>> +	help
>> +	  Create tracepoints for MMIO read/write operations. These trace events
>> +	  can be used for logging all MMIO read/write operations.
>> +
>>   source "lib/crypto/Kconfig"
>>   
>>   config CRC_CCITT
>> diff --git a/lib/Makefile b/lib/Makefile
>> index 300f569c626b..43813b0061cd 100644
>> --- a/lib/Makefile
>> +++ b/lib/Makefile
>> @@ -152,6 +152,8 @@ lib-y += logic_pio.o
>>   
>>   lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
>>   
>> +obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
>> +
>>   obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
>>   
>>   obj-$(CONFIG_BTREE) += btree.o
>> diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
>> new file mode 100644
>> index 000000000000..88637038b30c
>> --- /dev/null
>> +++ b/lib/trace_readwrite.c
>> @@ -0,0 +1,47 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Register read and write tracepoints
>> + *
>> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/ftrace.h>
>> +#include <linux/module.h>
>> +#include <asm-generic/io.h>
>> +
>> +#define CREATE_TRACE_POINTS
>> +#include <trace/events/rwmmio.h>
>> +
>> +#ifdef CONFIG_TRACE_MMIO_ACCESS
>> +void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
>> +		    unsigned long caller_addr)
>> +{
>> +	trace_rwmmio_write(caller_addr, val, width, addr);
>> +}
>> +EXPORT_SYMBOL_GPL(log_write_mmio);
>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
>> +
>> +void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
>> +			 unsigned long caller_addr)
>> +{
>> +	trace_rwmmio_post_write(caller_addr, val, width, addr);
>> +}
>> +EXPORT_SYMBOL_GPL(log_post_write_mmio);
>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
>> +
>> +void log_read_mmio(u8 width, const volatile void __iomem *addr,
>> +		   unsigned long caller_addr)
>> +{
>> +	trace_rwmmio_read(caller_addr, width, addr);
>> +}
>> +EXPORT_SYMBOL_GPL(log_read_mmio);
>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
>> +
>> +void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
>> +			unsigned long caller_addr)
>> +{
>> +	trace_rwmmio_post_read(caller_addr, val, width, addr);
>> +}
>> +EXPORT_SYMBOL_GPL(log_post_read_mmio);
>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
>> +#endif /* CONFIG_TRACE_MMIO_ACCESS */


From robin.murphy at arm.com  Mon Jan 17 07:30:55 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 17 Jan 2022 15:30:55 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu device
In-Reply-To: <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
 <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
Message-ID: <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>

On 2022-01-17 12:32, Sergiy Kibrik wrote:
> In IOMMU-capable system hypervisor usually takes over IOMMU control.
> Generally guest domains don't need to care about IOMMU management and take any
> extra actions. Yet in some cases a knowledge about which device is protected
> may be useful for privileged domain.
> 
> In compliance with iommu bindings this can be achieved with device-level
> iommus property specified with dummy Xen iommu device.

This could break Linux guests, since depending on the deferred probe 
timeout setting it could lead to drivers never probing because the 
"IOMMU" never becomes available.

Unless you intend to expose actual paravirtualised IOMMU translation 
functionality to guests (in which case virtio-iommu would be highly 
preferable anyway), I don't think this is the right approach. If there's 
no better alternative to using DT to communicate Xen-specific policy, 
then at least it should logically be via a Xen-specific DT property.

Thanks,
Robin.

> Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik at epam.com>
> ---
>   Documentation/devicetree/bindings/arm/xen.txt | 26 +++++++++++++++++++
>   1 file changed, 26 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/xen.txt b/Documentation/devicetree/bindings/arm/xen.txt
> index db5c56db30ec..98efa95c0d1b 100644
> --- a/Documentation/devicetree/bindings/arm/xen.txt
> +++ b/Documentation/devicetree/bindings/arm/xen.txt
> @@ -58,3 +58,29 @@ Documentation/arm/uefi.rst, which are provided by the regular UEFI stub. However
>   they differ because they are provided by the Xen hypervisor, together with a set
>   of UEFI runtime services implemented via hypercalls, see
>   http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
> +
> +* XEN IOMMU device
> +
> +In compliance with iommu bindings Xen virtual IOMMU device node represents
> +hypervisor-managed IOMMU [1]. Platform devices specified as IOMMU masters of
> +this xen-iommu device are protected by hypervisor-managed platform IOMMU.
> +
> +Required properties:
> +
> +- compatible:	Should be "xen,iommu-el2-v1"
> +- #iommu-cells: must be 0
> +
> +Example:
> +
> +xen-iommu {
> +	compatible = "xen,iommu-el2-v1";
> +	#iommu-cells = <0>;
> +};
> +
> +video at fe001000 {
> +	...
> +	/* this platform device is IOMMU-protected by hypervisor */
> +	iommus = <&xen-iommu 0x0>;
> +};
> +
> +[1] Documentation/devicetree/bindings/iommu/iommu.txt


From andre.przywara at arm.com  Mon Jan 17 07:33:48 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 15:33:48 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
Message-ID: <20220117153348.2513798-1-andre.przywara@arm.com>

Our GCC invocation does not provide many parameters, which lets the
toolchain fill in its own default setup.
In case of a native build or when using a full-featured cross-compiler,
this probably means Linux userland, which is not what we want for a
bare-metal application like boot-wrapper.

Tell the compiler to forget about those standard settings, and only use
what we explicitly ask for. In particular that means to not use toolchain
provided libraries, since they might pull in more code than we want, and
might not run well in the boot-wrapper environment.

Disable the stack protector, as this adds code that relies on userland:
"If a guard check fails, an error message is printed and the program
exits." (from the gcc manpage).

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
---
Hi,

compared to [PATCH v2 3/9] this drops the more contentious options (for
now, at least), and focuses on what's really needed. Including
-fno-stack-protector, as the need for this showed up in the cleanup series
already.

Cheers,
Andre

 Makefile.am | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index f941b07..581840e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -125,6 +125,8 @@ CHOSEN_NODE	:= chosen {						\
 CPPFLAGS	+= $(INITRD_FLAGS)
 CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
 CFLAGS		+= -Wall -fomit-frame-pointer
+CFLAGS		+= -ffreestanding -nostdlib	# this is not for userland
+CFLAGS		+= -fno-stack-protector		# no terminal to print
 CFLAGS		+= -ffunction-sections -fdata-sections
 CFLAGS		+= -fno-pic -fno-pie
 LDFLAGS		+= --gc-sections
-- 
2.25.1



From robh at kernel.org  Mon Jan 17 07:35:42 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 17 Jan 2022 09:35:42 -0600
Subject: [PATCH v2,
 03/10] dt-bindings: media: mtk-vcodec: Adds encoder cores dt-bindings
 for mt8195
In-Reply-To: <20220117120615.21687-4-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
 <20220117120615.21687-4-irui.wang@mediatek.com>
Message-ID: <1642433742.919482.3923083.nullmailer@robh.at.kernel.org>

On Mon, 17 Jan 2022 20:06:08 +0800, Irui Wang wrote:
> Adds encoder cores dt-bindings for mt8195
> 
> Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> ---
>  .../media/mediatek,vcodec-encoder-core.yaml   | 214 ++++++++++++++++++
>  1 file changed, 214 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.example.dts:20:18: fatal error: dt-bindings/memory/mt8195-memory-port.h: No such file or directory
   20 |         #include <dt-bindings/memory/mt8195-memory-port.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [scripts/Makefile.lib:373: Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1413: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1580741

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Mon Jan 17 07:35:42 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 17 Jan 2022 09:35:42 -0600
Subject: [PATCH net-next v12 7/7] net: dt-bindings: dwmac: add support for
 mt8195
In-Reply-To: <20220117070706.17853-8-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
 <20220117070706.17853-8-biao.huang@mediatek.com>
Message-ID: <1642433742.934070.3923086.nullmailer@robh.at.kernel.org>

On Mon, 17 Jan 2022 15:07:06 +0800, Biao Huang wrote:
> Add binding document for the ethernet on mt8195.
> 
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> ---
>  .../bindings/net/mediatek-dwmac.yaml          | 28 ++++++++++++++++---
>  1 file changed, 24 insertions(+), 4 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/1580608


ethernet at 1101c000: clock-names: ['axi', 'apb', 'mac_main', 'ptp_ref'] is too short
	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml

ethernet at 1101c000: clocks: [[27, 34], [27, 37], [6, 154], [6, 155]] is too short
	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml

ethernet at 1101c000: compatible: ['mediatek,mt2712-gmac'] does not contain items matching the given schema
	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml

ethernet at 1101c000: compatible: 'oneOf' conditional failed, one must be fixed:
	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml

ethernet at 1101c000: Unevaluated properties are not allowed ('compatible', 'reg', 'interrupts', 'interrupt-names', 'mac-address', 'clock-names', 'clocks', 'power-domains', 'snps,axi-config', 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,txpbl', 'snps,rxpbl', 'clk_csr', 'phy-mode', 'phy-handle', 'snps,reset-gpio', 'mdio' were unexpected)
	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml



From linux at armlinux.org.uk  Mon Jan 17 07:36:09 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 15:36:09 +0000
Subject: [PATCH v5 01/69] KVM: arm64: Save PSTATE early on exit
In-Reply-To: <20211129200150.351436-2-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-2-maz@kernel.org>
Message-ID: <YeWM6YtDpmy3BL2j@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:42PM +0000, Marc Zyngier wrote:
> In order to be able to use primitives such as vcpu_mode_is_32bit(),
> we need to synchronize the guest PSTATE. However, this is currently
> done deep into the bowels of the world-switch code, and we do have
> helpers evaluating this much earlier (__vgic_v3_perform_cpuif_access
> and handle_aarch32_guest, for example).
> 
> Move the saving of the guest pstate into the early fixups, which
> cures the first issue. The second one will be addressed separately.
> 
> Tested-by: Fuad Tabba <tabba at google.com>
> Reviewed-by: Fuad Tabba <tabba at google.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Mon Jan 17 07:34:02 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 15:34:02 +0000
Subject: [PATCH v5 02/69] KVM: arm64: Move pkvm's special 32bit handling
 into a generic infrastructure
In-Reply-To: <20211129200150.351436-3-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-3-maz@kernel.org>
Message-ID: <YeWMaj2shSMVXgAE@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:43PM +0000, Marc Zyngier wrote:
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index c0e3fed26d93..d13115a12434 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -233,7 +233,7 @@ static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
>   * Returns false if the guest ran in AArch32 when it shouldn't have, and
>   * thus should exit to the host, or true if a the guest run loop can continue.
>   */
> -static bool handle_aarch32_guest(struct kvm_vcpu *vcpu, u64 *exit_code)
> +static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)

The comment above this function needs fixing up - it talks about the
return value, but this patch changes the return type to be void.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From jagan at amarulasolutions.com  Mon Jan 17 07:38:29 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Mon, 17 Jan 2022 21:08:29 +0530
Subject: [PATCH v6 3/6] drm: sun4i: dsi: Add bridge support
In-Reply-To: <20211213171757.bxu57eaqawmp5kwh@houat>
References: <20211210111711.2072660-1-jagan@amarulasolutions.com>
 <20211210111711.2072660-4-jagan@amarulasolutions.com>
 <20211213171757.bxu57eaqawmp5kwh@houat>
Message-ID: <CAMty3ZBXUart1GZod2v=bMv2xYxuDjkyEw-WZ8bMDsCLU1gVWA@mail.gmail.com>

On Mon, Dec 13, 2021 at 10:48 PM Maxime Ripard <maxime at cerno.tech> wrote:
>
> On Fri, Dec 10, 2021 at 04:47:08PM +0530, Jagan Teki wrote:
> > Some display panels would come up with a non-DSI output, those
> > can have an option to connect the DSI host by means of interface
> > bridge converter.
> >
> > This DSI to non-DSI interface bridge converter would require
> > DSI Host to handle drm bridge functionalities in order to
> > communicate interface bridge.
> >
> > This patch adds support for bridge functionalities in Allwinner
> > DSI controller.
> >
> > Supporting down-stream bridge makes few changes in the driver.
> >
> > - It drops drm_connector and related operations as drm_bridge_attach
> >   creates connector during attachment.
> >
> > - It drop panel pointer and iterate the bridge, so-that it can operate
> >   the normal bridge and panel_bridge in constitutive callbacks.
> >
> > - It uses devm_drm_of_get_bridge for panel or bridge lookup. It uses
> >   port 0 and endpoint 0 to support I2C-based bridges eventhough the
> >   usual Allwinner DSI OF graph doesn't require this for panel and
> >   non-I2C based downstream bridges.
> >
> > Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
> > ---
> > Changes for v6:
> > - support donwstream bridge
> > - drop bridge conversion
> > - devm_drm_of_get_bridge() require child lookup
> > https://patchwork.kernel.org/project/dri-devel/cover/20211207054747.461029-1-jagan at amarulasolutions.com/
> > Changes for v5:
> > - add atomic APIs
> > - find host and device variant DSI devices.
> > Changes for v4, v3:
> > - none
> >
> >  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c | 83 ++++++++++----------------
> >  drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h |  9 +--
> >  2 files changed, 33 insertions(+), 59 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> > index 9cf91dcac3f2..f1d612bf1a0b 100644
> > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c
> > @@ -21,6 +21,7 @@
> >
> >  #include <drm/drm_atomic_helper.h>
> >  #include <drm/drm_mipi_dsi.h>
> > +#include <drm/drm_of.h>
> >  #include <drm/drm_panel.h>
> >  #include <drm/drm_print.h>
> >  #include <drm/drm_probe_helper.h>
> > @@ -720,6 +721,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
> >       struct mipi_dsi_device *device = dsi->device;
> >       union phy_configure_opts opts = { };
> >       struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> > +     struct drm_bridge *iter;
> >       u16 delay;
> >       int err;
> >
> > @@ -769,8 +771,10 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
> >       phy_configure(dsi->dphy, &opts);
> >       phy_power_on(dsi->dphy);
> >
> > -     if (dsi->panel)
> > -             drm_panel_prepare(dsi->panel);
> > +     list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
> > +             if (iter->funcs->pre_enable)
> > +                     iter->funcs->pre_enable(iter);
> > +     }
>
> Like we discussed in the previous version already, this is unnecessary,
> just like the poking at bridge_chain in the encoder.

Unlike previous patch, this patch not doing bridge conversion it is
supporting downstream bridge. Yes, it is possible to use bridge helper
for invoking downstream bridge enable when bridge functions added.

Thanks,
Jagan.


From john.garry at huawei.com  Mon Jan 17 07:39:10 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 17 Jan 2022 15:39:10 +0000
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
Message-ID: <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>

On 16/12/2021 15:48, Marco Elver wrote:

+

> On Thu, 16 Dec 2021 at 16:15, Thomas Richter<tmricht at linux.ibm.com>  wrote:
>> In Linux next kernel
>> Commit 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
>> introduced the new test which uses breakpoint events.
>> These events are not supported on s390 and PowerPC and always fail:
>>
>>   # perf test -F 73
>>   73: Sigtrap                                                         : FAILED!
>>   #
>>
>> Fix it the same way as in the breakpoint tests in file
>> tests/bp_account.c where these type of tests are skipped on
>> s390 and PowerPC platforms.
>>
>> With this patch skip this test on both platforms.
>>
>> Output after:
>>   # ./perf test -F 73
>>   73: Sigtrap
>>
>> Fixes: 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
>>
>> Cc: Marco Elver<elver at google.com>
>> Signed-off-by: Thomas Richter<tmricht at linux.ibm.com>
> Acked-by: Marco Elver<elver at google.com>
> 
> Thanks, and sorry for missing this case!
> 

I am finding that this test hangs on my arm64 machine:

john at debian:~/kernel-dev2/tools/perf$ sudo ./perf test -vvv 73
  73: Sigtrap:
--- start ---
test child forked, pid 45193

And fails on my x86 broadwell machine:

john at localhost:~/kernel-dev2/tools/perf> sudo ./perf test -v 73
73: Sigtrap                                                         :
--- start ---
test child forked, pid 22255
FAILED sys_perf_event_open(): Argument list too long
test child finished with -1
---- end ----
Sigtrap: FAILED!
john at localhost:~/kernel-dev2/tools/perf>

Are there more architectures+platforms for which we need to skip this test?

Thanks,
John


From linux at armlinux.org.uk  Mon Jan 17 07:40:16 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 15:40:16 +0000
Subject: [PATCH v5 03/69] KVM: arm64: Add minimal handling for the
 ARMv8.7 PMU
In-Reply-To: <20211129200150.351436-4-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-4-maz@kernel.org>
Message-ID: <YeWN4JoAB5UqN2/0@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:44PM +0000, Marc Zyngier wrote:
> When running a KVM guest hosted on an ARMv8.7 machine, the host
> kernel complains that it doesn't know about the architected number
> of events.
> 
> Fix it by adding the PMUver code corresponding to PMUv3 for ARMv8.7.
> 
> Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>
> Tested-by: Alexandru Elisei <alexandru.elisei at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> Link: https://lore.kernel.org/r/20211126115533.217903-1-maz at kernel.org

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From jagan at amarulasolutions.com  Mon Jan 17 07:42:37 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Mon, 17 Jan 2022 21:12:37 +0530
Subject: [PATCH v6 1/6] drm: sun4i: dsi: Drop DRM bind race with bridge
 attach
In-Reply-To: <20211213170223.fx5656vjk3fwizbg@houat>
References: <20211210111711.2072660-1-jagan@amarulasolutions.com>
 <20211210111711.2072660-2-jagan@amarulasolutions.com>
 <20211213170223.fx5656vjk3fwizbg@houat>
Message-ID: <CAMty3ZAetcXpcokJ418VGHzbi4ivJg4Rt0OVgh7WaZ6GAJQY1Q@mail.gmail.com>

On Mon, Dec 13, 2021 at 10:32 PM Maxime Ripard <maxime at cerno.tech> wrote:
>
> On Fri, Dec 10, 2021 at 04:47:06PM +0530, Jagan Teki wrote:
> > Existing host driver will keep looking for DRM pointer in
> > sun6i_dsi_attach and defers even if the particular DSI device
> > is found for the first time. Meanwhile it triggers the bind
> > callback and gets the DRM pointer and then continues the
> > sun6i_dsi_attach.
> >
> > This makes a deadlock situation if sun6i_dsi_attach is trying
> > to find the bridge.
>
> I'm not sure what you mean by deadlock here, there's no lock involved?

deadlock parse here for general understanding, where bind is trying to
attach bridge but drm pointer is not available that point and drm
pointer will available only when bind done. This is what I'm calling
as deadlock here.

Anyway, now I'm able to support both panel and bridge to support
hotplug so no need to drop the hotplug support.

Please let me know, if you have any questions so-that I can send next
version series.

Thanks,
Jagan.


From linux at armlinux.org.uk  Mon Jan 17 07:43:34 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 15:43:34 +0000
Subject: [PATCH v5 04/69] KVM: arm64: Rework kvm_pgtable initialisation
In-Reply-To: <20211129200150.351436-5-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-5-maz@kernel.org>
Message-ID: <YeWOpnGxlRC4mCip@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:45PM +0000, Marc Zyngier wrote:
> Ganapatrao reported that the kvm_pgtable->mmu pointer is more or
> less hardcoded to the main S2 mmu structure, while the nested
> code needs it to point to other instances (as we have one instance
> per nested context).
> 
> Rework the initialisation of the kvm_pgtable structure so that
> this assumtion doesn't hold true anymore. This requires some
> minor changes to the order in which things are initialised
> (the mmu->arch pointer being the critical one).
> 
> Reported-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
> Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Looks fairly simple.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mark.rutland at arm.com  Mon Jan 17 07:50:21 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 15:50:21 +0000
Subject: [bootwrapper PATCH v2 08/13] Announce boot-wrapper mode /
 exception level
In-Reply-To: <20220117143913.520a553c@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-9-mark.rutland@arm.com>
 <20220117143913.520a553c@donnerap.cambridge.arm.com>
Message-ID: <20220117155021.GG87485@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 02:39:13PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:48 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > When something goes wrong within the boot-wrapper, it can be very
> > helpful to know where we started from. Add an arch_announce() function
> > to log this early in the boot process. More information can be added
> > here in future.
> > 
> > This is logged ot the serial console as:
> > 
> > | Boot-wrapper v0.2
> > | Entered at EL3
> 
> I like that one, and apart from the (already existing) UART issue below,
> this looks fine:
> 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> 
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks!

> > diff --git a/common/platform.c b/common/platform.c
> > index 47bf547..80d0562 100644
> > --- a/common/platform.c
> > +++ b/common/platform.c
> > @@ -31,21 +31,25 @@
> >  #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
> >  #endif
> >  
> > -void print_string(const char *str)
> > +void print_char(char c)
> >  {
> >  	uint32_t flags;
> >  
> > -	while (*str) {
> > -		do
> > -			flags = raw_readl(PL011(UARTFR));
> > -		while (flags & PL011_UARTFR_FIFO_FULL);
> > +	do {
> > +		flags = raw_readl(PL011(UARTFR));
> > +	} while (flags & PL011_UARTFR_FIFO_FULL);
> > +
> > +	raw_writel(c, PL011(UARTDR));
> >  
> > -		raw_writel(*str++, PL011(UARTDR));
> > +	do {
> > +		flags = raw_readl(PL011(UARTFR));
> > +	} while (flags & PL011_UARTFR_BUSY);
> 
> Apologies if that appears to be nitpicking over a totally pointless issue
> (given the nature of the *emulated* PL011 in the model), but:
> 
> I understand that this code has not changed, but this loop basically
> renders the FIFOs ineffective. Is this intended? 

Hmm... AFAICT, we started to enable the FIFOs in commit:

  26a17ad59544f026 ("bootwrapper: improve UART initialisation")

... but back then the boot-wrapper didn't print anything to the UART, so
that was purely about putting the UART into a sane state for the OS.

We only started to write to the UART in commit:

  7ff3872adb33b068 ("Rewrite platform initialisation in C")

... where we said nothing about the FIFOs.

Therefore, I think there was no intent either way to use/avoid the
FIFOs within the boot-wrapper.

> I mean we explicitly enable the FIFOs in init_uart(), but then poll
> here until the transmit FIFO becomes empty, after *every* character
> pushed. I see that we probably want the output to be synchronous, for
> debug reasons, but I wonder if this should be achieved via an extra
> uart_flush() routine, once per line output? So call uart_flush() just
> in print_string(), but not in print_char(), for instance?

Hmm... we also use print_char() directly from the aarch64 init code when
logging the exception level, so we'd need an explicit sync there, if we
do want that output before other things can go wrong.

Otherwise, I don't have strong feelings either way, but I would like to
have the output completed before print_*() return. We could add an
internal print_char_nosync() that print_{char,string}() use to handle
that.

I'm happy to take a follow-up patch for that, but for now I'm going to
leave this as-is.

Thanks,
Mark.


From quic_saipraka at quicinc.com  Mon Jan 17 07:51:03 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 17 Jan 2022 21:21:03 +0530
Subject: [PATCHv8 4/5] lib: Add register read/write tracing support
In-Reply-To: <8bbe3552-cd47-c9d4-a296-ba446b7b2f45@quicinc.com>
References: <cover.1642309054.git.quic_saipraka@quicinc.com>
 <8ad60797d6d8f40c3bdba20b1678fa9014bc1a20.1642309054.git.quic_saipraka@quicinc.com>
 <20220117100314.416a4d68@rorschach.local.home>
 <8bbe3552-cd47-c9d4-a296-ba446b7b2f45@quicinc.com>
Message-ID: <9f648096-e694-7d4d-859b-ea173d5fb611@quicinc.com>

On 1/17/2022 9:00 PM, Sai Prakash Ranjan wrote:
> Hi Steve,
>
> On 1/17/2022 8:33 PM, Steven Rostedt wrote:
>> On Mon, 17 Jan 2022 09:02:53 +0530
>> Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
>>
>>> diff --git a/include/trace/events/rwmmio.h 
>>> b/include/trace/events/rwmmio.h
>>> new file mode 100644
>>> index 000000000000..798fbe1ac9f9
>>> --- /dev/null
>>> +++ b/include/trace/events/rwmmio.h
>>> @@ -0,0 +1,112 @@
>>> +/* SPDX-License-Identifier: GPL-2.0-only */
>>> +/*
>>> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All 
>>> rights reserved.
>>> + */
>>> +#undef TRACE_SYSTEM
>>> +#define TRACE_SYSTEM rwmmio
>>> +
>>> +#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
>>> +#define _TRACE_RWMMIO_H
>>> +
>>> +#include <linux/tracepoint.h>
>>> +
>>> +TRACE_EVENT(rwmmio_write,
>>> +
>>> +??? TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>>> __iomem *addr),
>>> +
>>> +??? TP_ARGS(caller, val, width, addr),
>>> +
>>> +??? TP_STRUCT__entry(
>>> +??????? __field(u64, caller)
>>> +??????? __field(u64, val)
>>> +??????? __field(u64, addr)
>>> +??????? __field(u8, width)
>>> +??? ),
>>> +
>>> +??? TP_fast_assign(
>>> +??????? __entry->caller = caller;
>>> +??????? __entry->val = val;
>>> +??????? __entry->addr = (unsigned long)(void *)addr;
>>> +??????? __entry->width = width;
>>> +??? ),
>>> +
>>> +??? TP_printk("%pS width=%d val=%#llx addr=%#llx",
>>> +??????? (void *)(unsigned long)__entry->caller, __entry->width,
>>> +??????? __entry->val, __entry->addr)
>>> +);
>>> +
>>> +TRACE_EVENT(rwmmio_post_write,
>>> +
>>> +??? TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>>> __iomem *addr),
>>> +
>>> +??? TP_ARGS(caller, val, width, addr),
>>> +
>>> +??? TP_STRUCT__entry(
>>> +??????? __field(u64, caller)
>>> +??????? __field(u64, val)
>>> +??????? __field(u64, addr)
>>> +??????? __field(u8, width)
>>> +??? ),
>>> +
>>> +??? TP_fast_assign(
>>> +??????? __entry->caller = caller;
>>> +??????? __entry->val = val;
>>> +??????? __entry->addr = (unsigned long)(void *)addr;
>>> +??????? __entry->width = width;
>>> +??? ),
>>> +
>>> +??? TP_printk("%pS width=%d val=%#llx addr=%#llx",
>>> +??????? (void *)(unsigned long)__entry->caller, __entry->width,
>>> +??????? __entry->val, __entry->addr)
>>> +);
>>> +
>>> +TRACE_EVENT(rwmmio_read,
>>> +
>>> +??? TP_PROTO(unsigned long caller, u8 width, const volatile void 
>>> __iomem *addr),
>>> +
>>> +??? TP_ARGS(caller, width, addr),
>>> +
>>> +??? TP_STRUCT__entry(
>>> +??????? __field(u64, caller)
>>> +??????? __field(u64, addr)
>>> +??????? __field(u8, width)
>>> +??? ),
>>> +
>>> +??? TP_fast_assign(
>>> +??????? __entry->caller = caller;
>>> +??????? __entry->addr = (unsigned long)(void *)addr;
>>> +??????? __entry->width = width;
>>> +??? ),
>>> +
>>> +??? TP_printk("%pS width=%d addr=%#llx",
>>> +???????? (void *)(unsigned long)__entry->caller, __entry->width, 
>>> __entry->addr)
>>> +);
>>> +
>>> +TRACE_EVENT(rwmmio_post_read,
>>> +
>>> +??? TP_PROTO(unsigned long caller, u64 val, u8 width, const 
>>> volatile void __iomem *addr),
>>> +
>>> +??? TP_ARGS(caller, val, width, addr),
>>> +
>>> +??? TP_STRUCT__entry(
>>> +??????? __field(u64, caller)
>>> +??????? __field(u64, val)
>>> +??????? __field(u64, addr)
>>> +??????? __field(u8, width)
>>> +??? ),
>>> +
>>> +??? TP_fast_assign(
>>> +??????? __entry->caller = caller;
>>> +??????? __entry->val = val;
>>> +??????? __entry->addr = (unsigned long)(void *)addr;
>>> +??????? __entry->width = width;
>>> +??? ),
>>> +
>>> +??? TP_printk("%pS width=%d val=%#llx addr=%#llx",
>>> +???????? (void *)(unsigned long)__entry->caller, __entry->width,
>>> +???????? __entry->val, __entry->addr)
>>> +);
>> The above should be replaced with:
>>
>> DECLARE_EVENT_CLASS(rwmmio_rw_template,
>>
>> ????TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>> __iomem *addr),
>>
>> ????TP_ARGS(caller, val, width, addr),
>>
>> ????TP_STRUCT__entry(
>> ??????? __field(u64, caller)
>> ??????? __field(u64, val)
>> ??????? __field(u64, addr)
>> ??????? __field(u8, width)
>> ????),
>>
>> ????TP_fast_assign(
>> ??????? __entry->caller = caller;
>> ??????? __entry->val = val;
>> ??????? __entry->addr = (unsigned long)(void *)addr;
>> ??????? __entry->width = width;
>> ????),
>>
>> ????TP_printk("%pS width=%d val=%#llx addr=%#llx",
>> ??????? (void *)(unsigned long)__entry->caller, __entry->width,
>> ??????? __entry->val, __entry->addr)
>> );
>>
>> DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
>> ????TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>> __iomem *addr),
>> ????TP_ARGS(caller, val, width, addr)
>> );
>>
>> DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
>> ????TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>> __iomem *addr),
>> ????TP_ARGS(caller, val, width, addr)
>> );
>>
>> DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_read,
>> ????TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void 
>> __iomem *addr),
>> ????TP_ARGS(caller, val, width, addr)
>> );
>>
>> It will save around 15k in memory.
>>
>> And since rwmmio_read doesn't have a val field, it can stay a 
>> TRACE_EVENT.
>>
>> TRACE_EVENT(rwmmio_read,
>>
>> ????TP_PROTO(unsigned long caller, u8 width, const volatile void 
>> __iomem *addr),
>>
>> ????TP_ARGS(caller, width, addr),
>>
>> ????TP_STRUCT__entry(
>> ??????? __field(u64, caller)
>> ??????? __field(u64, addr)
>> ??????? __field(u8, width)
>> ????),
>>
>> ????TP_fast_assign(
>> ??????? __entry->caller = caller;
>> ??????? __entry->addr = (unsigned long)(void *)addr;
>> ??????? __entry->width = width;
>> ????),
>>
>> ????TP_printk("%pS width=%d addr=%#llx",
>> ???????? (void *)(unsigned long)__entry->caller, __entry->width, 
>> __entry->addr)
>> );
>>
>> -- Steve
>
> Thanks for the review, will add these changes in next version.
>
>

Just one note that I need to keep rwmmio_post_read also as TRACE_EVENT 
because
of const qualifier in post_read resulting in compiler warnings,

lib/trace_readwrite.c:43:50: warning: passing argument 4 of 
?trace_rwmmio_post_read? discards ?const? qualifier from pointer target 
type [-Wdiscarded-qualifiers]

Thanks,
Sai
>>> +
>>> +#endif /* _TRACE_RWMMIO_H */
>>> +
>>> +#include <trace/define_trace.h>
>>> diff --git a/lib/Kconfig b/lib/Kconfig
>>> index c80fde816a7e..ea520c315c0f 100644
>>> --- a/lib/Kconfig
>>> +++ b/lib/Kconfig
>>> @@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
>>> ??????? mmio accesses when the IO memory address is not a registered
>>> ??????? emulated region.
>>> ? +config TRACE_MMIO_ACCESS
>>> +??? bool "Register read/write tracing"
>>> +??? depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
>>> +??? help
>>> +????? Create tracepoints for MMIO read/write operations. These 
>>> trace events
>>> +????? can be used for logging all MMIO read/write operations.
>>> +
>>> ? source "lib/crypto/Kconfig"
>>> ? ? config CRC_CCITT
>>> diff --git a/lib/Makefile b/lib/Makefile
>>> index 300f569c626b..43813b0061cd 100644
>>> --- a/lib/Makefile
>>> +++ b/lib/Makefile
>>> @@ -152,6 +152,8 @@ lib-y += logic_pio.o
>>> ? ? lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
>>> ? +obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
>>> +
>>> ? obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
>>> ? ? obj-$(CONFIG_BTREE) += btree.o
>>> diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
>>> new file mode 100644
>>> index 000000000000..88637038b30c
>>> --- /dev/null
>>> +++ b/lib/trace_readwrite.c
>>> @@ -0,0 +1,47 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Register read and write tracepoints
>>> + *
>>> + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All 
>>> rights reserved.
>>> + */
>>> +
>>> +#include <linux/ftrace.h>
>>> +#include <linux/module.h>
>>> +#include <asm-generic/io.h>
>>> +
>>> +#define CREATE_TRACE_POINTS
>>> +#include <trace/events/rwmmio.h>
>>> +
>>> +#ifdef CONFIG_TRACE_MMIO_ACCESS
>>> +void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
>>> +??????????? unsigned long caller_addr)
>>> +{
>>> +??? trace_rwmmio_write(caller_addr, val, width, addr);
>>> +}
>>> +EXPORT_SYMBOL_GPL(log_write_mmio);
>>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
>>> +
>>> +void log_post_write_mmio(u64 val, u8 width, volatile void __iomem 
>>> *addr,
>>> +???????????? unsigned long caller_addr)
>>> +{
>>> +??? trace_rwmmio_post_write(caller_addr, val, width, addr);
>>> +}
>>> +EXPORT_SYMBOL_GPL(log_post_write_mmio);
>>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
>>> +
>>> +void log_read_mmio(u8 width, const volatile void __iomem *addr,
>>> +?????????? unsigned long caller_addr)
>>> +{
>>> +??? trace_rwmmio_read(caller_addr, width, addr);
>>> +}
>>> +EXPORT_SYMBOL_GPL(log_read_mmio);
>>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
>>> +
>>> +void log_post_read_mmio(u64 val, u8 width, const volatile void 
>>> __iomem *addr,
>>> +??????????? unsigned long caller_addr)
>>> +{
>>> +??? trace_rwmmio_post_read(caller_addr, val, width, addr);
>>> +}
>>> +EXPORT_SYMBOL_GPL(log_post_read_mmio);
>>> +EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
>>> +#endif /* CONFIG_TRACE_MMIO_ACCESS */




From linux at armlinux.org.uk  Mon Jan 17 07:51:48 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 15:51:48 +0000
Subject: [PATCH v5 05/69] KVM: arm64: Allow preservation of the S2 SW bits
In-Reply-To: <20211129200150.351436-6-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-6-maz@kernel.org>
Message-ID: <YeWQlNdI7OvLjeNv@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:46PM +0000, Marc Zyngier wrote:
> The S2 page table code has a limited use the SW bits, but we are about

I think the opening clause needs to be rewritten.

> to need them to encode some guest Stage-2 information (its mapping size
> in the form of the TTL encoding).
> 
> Propagate the SW bits specified by the caller, and store them into
> the corresponding entry.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From arzamas-16 at mail.ee  Mon Jan 17 08:01:12 2022
From: arzamas-16 at mail.ee (Boris Lysov)
Date: Mon, 17 Jan 2022 19:01:12 +0300
Subject: Missing ARM TWD Watchdog driver?
Message-ID: <20220117190112.2b2c2f53@pc>

Hello everyone,

I stumbled upon the ARM TWD Watchdog driver which seems to be missing (or I'm
just blind).

As per commit a33f5c380c4bd3fa5278d690421b72052456d9fe ("Merge tag
'xfs-5.17-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux"), multiple
device trees declare usage of arm-twd:

arch/arm/boot/dts/arm-realview-eb-mp.dtsi
arch/arm/boot/dts/arm-realview-pb11mp.dts
arch/arm/boot/dts/arm-realview-pbx-a9.dts
arch/arm/boot/dts/bcm5301x.dtsi
arch/arm/boot/dts/bcm63138.dtsi
arch/arm/boot/dts/bcm-hr2.dtsi
arch/arm/boot/dts/bcm-nsp.dtsi
arch/arm/boot/dts/berlin2cd.dtsi
arch/arm/boot/dts/highbank.dts
arch/arm/boot/dts/mmp3.dtsi
arch/arm/boot/dts/owl-s500.dtsi
arch/arm/boot/dts/spear13xx.dtsi
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/vexpress-v2p-ca5s.dts
arch/arm/boot/dts/vexpress-v2p-ca9.dts

and it is documented in
Documentation/devicetree/bindings/watchdog/arm,twd-wdt.yaml

However I could not find the driver itself. I tried running case-insensitive
grep and ripgrep to no avail. Does this driver actually exist? Is it gone?

I'm not well experienced with LKML yet and I apologize for if I asked
the question on the inappropriate mailing list. As per 3.3 of [1], I'm kindly
asking to CC me with answers.

Thanks!

[1] The linux-kernel mailing list FAQ http://vger.kernel.org/lkml/


From dario.binacchi at amarulasolutions.com  Mon Jan 17 08:17:51 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Mon, 17 Jan 2022 17:17:51 +0100
Subject: [RFC PATCH v3 0/4] Fix and improve gpmi nand on mx28
Message-ID: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>

Starting from [1], the series fixes the timings setting of the gpmi
controller for the mx28 architecture, also adding support for fast
edo mode timings. The whole series has been heavily tested with the
mtd kernel test modules, and with repeated write cycles on nand.

[1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org

Changes in v3:
- Remove the "mtd: rawnand: gpmi: use a table to get EDO mode setup" patch.
- Simplify the validation logic (suggested by Sascha Hauer <sha at pengutronix.de>).

Changes in v2:
- Reparent by device tree instead of code (drivers/clk/mxs/clk-imx28.c).
  Suggested by Stephen Boyd.
- Improve the commit description.
- give examples of frequencies on my setup.
- Fix commit description.
- Add an example to the commit description to better understand the
  problem solved by the patch.
- Split the patch.
- Improve the commit message.
- Move the patch to the end of the series.

Dario Binacchi (4):
  ARM: dts: imx28: reparent gpmi clock to ref_gpmi
  mtd: rawnand: gpmi: fix controller timings setting
  mtd: rawnand: gpmi: validate controller clock rate
  mtd: rawnand: gpmi: support fast edo timings for mx28

 arch/arm/boot/dts/imx28.dtsi               |  2 ++
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 27 ++++++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)

-- 
2.32.0



From dario.binacchi at amarulasolutions.com  Mon Jan 17 08:17:52 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Mon, 17 Jan 2022 17:17:52 +0100
Subject: [RFC PATCH v3 1/4] ARM: dts: imx28: reparent gpmi clock to ref_gpmi
In-Reply-To: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>
References: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20220117161755.1863579-2-dario.binacchi@amarulasolutions.com>

Since ref_gpmi is sourced from pll0 (480MHz), It allows the GPMI
controller to manage High-Speed ??NAND Timing (edo mode 3,4 and 5).

Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>


---

(no changes since v2)

Changes in v2:
- Reparent by device tree instead of code (drivers/clk/mxs/clk-imx28.c).
  Suggested by Stephen Boyd.

 arch/arm/boot/dts/imx28.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 84d0176d5193..130b4145af82 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -110,6 +110,8 @@ gpmi: nand-controller at 8000c000 {
 				interrupt-names = "bch";
 				clocks = <&clks 50>;
 				clock-names = "gpmi_io";
+				assigned-clocks = <&clks 13>;
+				assigned-clock-parents = <&clks 10>;
 				dmas = <&dma_apbh 4>;
 				dma-names = "rx-tx";
 				status = "disabled";
-- 
2.32.0



From andre.przywara at arm.com  Mon Jan 17 08:23:05 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 16:23:05 +0000
Subject: [bootwrapper PATCH v2 07/13] Rework common init C code
In-Reply-To: <20220114105653.3003399-8-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-8-mark.rutland@arm.com>
Message-ID: <20220117162305.043cb2b3@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:47 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> In init_platform() we initialize a UART and announce the presence of the
> bootwrapper to the world. We do this relatively late in the boot-flow,
> and prior to this will silently ignore errors (e.g. in gic_secure_init).
> 
> To make it possible to provide improved diagnostics, and to allow us to
> move more initialization into C, this patch reworks the init code to
> call a C function earlier, where we can announce the presence of the
> boot-wrapper and perform other initialization.
> 
> In subsequent patches this will be expanded with more CPU
> initialization.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  Makefile.am         |  2 +-
>  arch/aarch32/boot.S |  5 +++++
>  arch/aarch64/boot.S |  4 ++++
>  common/boot.c       |  4 ----
>  common/init.c       | 24 ++++++++++++++++++++++++
>  common/platform.c   | 12 +++++++-----
>  include/platform.h  | 17 +++++++++++++++++
>  7 files changed, 58 insertions(+), 10 deletions(-)
>  create mode 100644 common/init.c
>  create mode 100644 include/platform.h
> 
> diff --git a/Makefile.am b/Makefile.am
> index f941b07..0651c38 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -34,7 +34,7 @@ endif
>  PSCI_CPU_OFF	:= 0x84000002
>  
>  COMMON_SRC	:= common/
> -COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o
> +COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
>  
>  ARCH_OBJ	:= boot.o stack.o utils.o
>  
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 00c432d..ee073ea 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -48,6 +48,9 @@ ASM_FUNC(_start)
>  	mov	r0, #1
>  	ldr	r1, =flag_no_el3
>  	str	r0, [r1]
> +
> +	bl	cpu_init_bootwrapper
> +
>  	b	start_no_el3
>  
>  _switch_monitor:
> @@ -71,6 +74,8 @@ _monitor:
>  	ldr	r0, =COUNTER_FREQ
>  	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
>  
> +	bl	cpu_init_bootwrapper
> +
>  	bl	gic_secure_init
>  
>  	/* Initialise boot method */
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 45a0367..17b4a75 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -141,6 +141,8 @@ reset_at_el3:
>  	b.eq	err_invalid_id
>  	bl	setup_stack
>  
> +	bl	cpu_init_bootwrapper
> +
>  	bl	gic_secure_init
>  
>  	b	start_el3
> @@ -181,6 +183,8 @@ reset_no_el3:
>  	ldr	x1, =flag_no_el3
>  	str	w0, [x1]
>  
> +	bl	cpu_init_bootwrapper
> +
>  	b	start_no_el3
>  
>  err_invalid_id:
> diff --git a/common/boot.c b/common/boot.c
> index c74d34c..29d53a4 100644
> --- a/common/boot.c
> +++ b/common/boot.c
> @@ -12,8 +12,6 @@
>  extern unsigned long entrypoint;
>  extern unsigned long dtb;
>  
> -void init_platform(void);
> -
>  void __noreturn jump_kernel(unsigned long address,
>  			    unsigned long a0,
>  			    unsigned long a1,
> @@ -62,8 +60,6 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
>  			   unsigned long invalid)
>  {
>  	if (cpu == 0) {
> -		init_platform();
> -
>  		*mbox = (unsigned long)&entrypoint;
>  		sevl();
>  		spin(mbox, invalid, 1);
> diff --git a/common/init.c b/common/init.c
> new file mode 100644
> index 0000000..9c471c9
> --- /dev/null
> +++ b/common/init.c
> @@ -0,0 +1,24 @@
> +/*
> + * init.c - common boot-wrapper initialization
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#include <cpu.h>
> +#include <platform.h>
> +
> +static void announce_bootwrapper(void)
> +{
> +	print_string("Boot-wrapper v0.2\r\n\r\n");
> +}
> +
> +void cpu_init_bootwrapper(void)
> +{
> +	if (this_cpu_logical_id() == 0) {
> +		init_uart();
> +		announce_bootwrapper();
> +		init_platform();
> +	}
> +}
> diff --git a/common/platform.c b/common/platform.c
> index d11f568..47bf547 100644
> --- a/common/platform.c
> +++ b/common/platform.c
> @@ -1,5 +1,5 @@
>  /*
> - * platform.c - code to initialise everything required when first booting.
> + * platform.c - Platform initialization and I/O.
>   *
>   * Copyright (C) 2015 ARM Limited. All rights reserved.
>   *
> @@ -7,6 +7,7 @@
>   * found in the LICENSE.txt file.
>   */
>  
> +#include <cpu.h>
>  #include <stdint.h>
>  
>  #include <asm/io.h>
> @@ -30,7 +31,7 @@
>  #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
>  #endif
>  
> -static void print_string(const char *str)
> +void print_string(const char *str)
>  {
>  	uint32_t flags;
>  
> @@ -47,7 +48,7 @@ static void print_string(const char *str)
>  	}
>  }
>  
> -void init_platform(void)
> +void init_uart(void)
>  {
>  	/*
>  	 * UART initialisation (38400 8N1)
> @@ -58,9 +59,10 @@ void init_platform(void)
>  	raw_writel(0x70,	PL011(UART_LCR_H));
>  	/* Enable the UART, TXen and RXen */
>  	raw_writel(0x301,	PL011(UARTCR));
> +}
>  
> -	print_string("Boot-wrapper v0.2\r\n\r\n");
> -
> +void init_platform(void)
> +{
>  #ifdef SYSREGS_BASE
>  	/*
>  	 * CLCD output site MB
> diff --git a/include/platform.h b/include/platform.h
> new file mode 100644
> index 0000000..e5248e1
> --- /dev/null
> +++ b/include/platform.h
> @@ -0,0 +1,17 @@
> +/*
> + * include/platform.h - Platform initialization and I/O.
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __PLATFORM_H
> +#define __PLATFORM_H
> +
> +void print_string(const char *str);
> +void init_uart(void);
> +
> +void init_platform(void);
> +
> +#endif /* __PLATFORM_H */



From linux at roeck-us.net  Mon Jan 17 08:34:57 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 17 Jan 2022 08:34:57 -0800
Subject: Missing ARM TWD Watchdog driver?
In-Reply-To: <20220117190112.2b2c2f53@pc>
References: <20220117190112.2b2c2f53@pc>
Message-ID: <60dceae6-5c7c-9f2d-9fcb-5e849f1d8ce5@roeck-us.net>

On 1/17/22 8:01 AM, Boris Lysov wrote:
> Hello everyone,
> 
> I stumbled upon the ARM TWD Watchdog driver which seems to be missing (or I'm
> just blind).
> 
> As per commit a33f5c380c4bd3fa5278d690421b72052456d9fe ("Merge tag
> 'xfs-5.17-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux"), multiple
> device trees declare usage of arm-twd:
> 
> arch/arm/boot/dts/arm-realview-eb-mp.dtsi
> arch/arm/boot/dts/arm-realview-pb11mp.dts
> arch/arm/boot/dts/arm-realview-pbx-a9.dts
> arch/arm/boot/dts/bcm5301x.dtsi
> arch/arm/boot/dts/bcm63138.dtsi
> arch/arm/boot/dts/bcm-hr2.dtsi
> arch/arm/boot/dts/bcm-nsp.dtsi
> arch/arm/boot/dts/berlin2cd.dtsi
> arch/arm/boot/dts/highbank.dts
> arch/arm/boot/dts/mmp3.dtsi
> arch/arm/boot/dts/owl-s500.dtsi
> arch/arm/boot/dts/spear13xx.dtsi
> arch/arm/boot/dts/ste-dbx5x0.dtsi
> arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> arch/arm/boot/dts/vexpress-v2p-ca9.dts
> 
> and it is documented in
> Documentation/devicetree/bindings/watchdog/arm,twd-wdt.yaml
> 
> However I could not find the driver itself. I tried running case-insensitive
> grep and ripgrep to no avail. Does this driver actually exist? Is it gone?
> 

I may be missing it, but I do not see any evidence that it ever existed.

Guenter


From mark.rutland at arm.com  Mon Jan 17 08:47:20 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 16:47:20 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <20220117153348.2513798-1-andre.przywara@arm.com>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
Message-ID: <20220117164720.GA94025@C02TD0UTHF1T.local>

Hi Andre,

On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> Our GCC invocation does not provide many parameters, which lets the
> toolchain fill in its own default setup.
> In case of a native build or when using a full-featured cross-compiler,
> this probably means Linux userland, which is not what we want for a
> bare-metal application like boot-wrapper.
> 
> Tell the compiler to forget about those standard settings, and only use
> what we explicitly ask for. In particular that means to not use toolchain
> provided libraries, since they might pull in more code than we want, and
> might not run well in the boot-wrapper environment.

Thanks for splitting this out; I'd like to apply this with two minor
fixups (which I'll apply locally if you agree).

> Disable the stack protector, as this adds code that relies on userland:
> "If a guard check fails, an error message is printed and the program
> exits." (from the gcc manpage).

I think we should say:

| Disable the stack protector, as this relies on support code, e.g.
| a __stack_chk_guard variable and __stack_chk_fail function, which the
| boot-wrapper does not implement.

> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
> Hi,
> 
> compared to [PATCH v2 3/9] this drops the more contentious options (for
> now, at least), and focuses on what's really needed. Including
> -fno-stack-protector, as the need for this showed up in the cleanup series
> already.
> 
> Cheers,
> Andre
> 
>  Makefile.am | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Makefile.am b/Makefile.am
> index f941b07..581840e 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -125,6 +125,8 @@ CHOSEN_NODE	:= chosen {						\
>  CPPFLAGS	+= $(INITRD_FLAGS)
>  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
>  CFLAGS		+= -Wall -fomit-frame-pointer
> +CFLAGS		+= -ffreestanding -nostdlib	# this is not for userland
> +CFLAGS		+= -fno-stack-protector		# no terminal to print

For now, I'd like to drop these comments, since I think the "no terminal
to print" comment is a bit confusing, and the "this is not for userland"
comment is arguably the most obvious.

Then as a future follow-up we can reoganise this for clarity:

| # Build code suitable for a bare-metal environment which does not
| # depend on any support libraries
| CFLAGS	+= ffreestanding -nostdlib
| 
| # Disable unnecessary features which require runtime support
| CFLAGS	+= -fno-stack-protector
| CFLAGS	+= ...
|
| # Disable unnecessary features which impact code-size
| CFLAGS	+= -fomit-frame-pointer
| CFLAGS	+= ...
|
| # Allow the linker to remove unused code and data to shrink the
| # resulting binary
| CFLAGS	+= -ffunction-sections -fdata-sections
| LDFLAGS	+= --gc-sections


>  CFLAGS		+= -ffunction-sections -fdata-sections
>  CFLAGS		+= -fno-pic -fno-pie
>  LDFLAGS		+= --gc-sections
> -- 
> 2.25.1
> 


From andre.przywara at arm.com  Mon Jan 17 08:53:10 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 16:53:10 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <20220117164720.GA94025@C02TD0UTHF1T.local>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
 <20220117164720.GA94025@C02TD0UTHF1T.local>
Message-ID: <20220117165310.769a4799@donnerap.cambridge.arm.com>

On Mon, 17 Jan 2022 16:47:20 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> Hi Andre,
> 
> On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> > Our GCC invocation does not provide many parameters, which lets the
> > toolchain fill in its own default setup.
> > In case of a native build or when using a full-featured cross-compiler,
> > this probably means Linux userland, which is not what we want for a
> > bare-metal application like boot-wrapper.
> > 
> > Tell the compiler to forget about those standard settings, and only use
> > what we explicitly ask for. In particular that means to not use toolchain
> > provided libraries, since they might pull in more code than we want, and
> > might not run well in the boot-wrapper environment.  
> 
> Thanks for splitting this out; I'd like to apply this with two minor
> fixups (which I'll apply locally if you agree).

Yes, I am fine with those changes, please go ahead!

> > Disable the stack protector, as this adds code that relies on userland:
> > "If a guard check fails, an error message is printed and the program
> > exits." (from the gcc manpage).  
> 
> I think we should say:
> 
> | Disable the stack protector, as this relies on support code, e.g.
> | a __stack_chk_guard variable and __stack_chk_fail function, which the
> | boot-wrapper does not implement.
> 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> > Hi,
> > 
> > compared to [PATCH v2 3/9] this drops the more contentious options (for
> > now, at least), and focuses on what's really needed. Including
> > -fno-stack-protector, as the need for this showed up in the cleanup series
> > already.
> > 
> > Cheers,
> > Andre
> > 
> >  Makefile.am | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/Makefile.am b/Makefile.am
> > index f941b07..581840e 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -125,6 +125,8 @@ CHOSEN_NODE	:= chosen {						\
> >  CPPFLAGS	+= $(INITRD_FLAGS)
> >  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
> >  CFLAGS		+= -Wall -fomit-frame-pointer
> > +CFLAGS		+= -ffreestanding -nostdlib	# this is not for userland
> > +CFLAGS		+= -fno-stack-protector		# no terminal to print  
> 
> For now, I'd like to drop these comments, since I think the "no terminal
> to print" comment is a bit confusing, and the "this is not for userland"
> comment is arguably the most obvious.
> 
> Then as a future follow-up we can reoganise this for clarity:
> 
> | # Build code suitable for a bare-metal environment which does not
> | # depend on any support libraries
> | CFLAGS	+= ffreestanding -nostdlib
> | 
> | # Disable unnecessary features which require runtime support
> | CFLAGS	+= -fno-stack-protector
> | CFLAGS	+= ...
> |
> | # Disable unnecessary features which impact code-size
> | CFLAGS	+= -fomit-frame-pointer
> | CFLAGS	+= ...
> |
> | # Allow the linker to remove unused code and data to shrink the
> | # resulting binary
> | CFLAGS	+= -ffunction-sections -fdata-sections
> | LDFLAGS	+= --gc-sections

Yes, that looks good to me as a plan. I agree that trying to fit
meaningful comment to the rest of the line was not a great idea.

Cheers,
Andre

> 
> 
> >  CFLAGS		+= -ffunction-sections -fdata-sections
> >  CFLAGS		+= -fno-pic -fno-pie
> >  LDFLAGS		+= --gc-sections
> > -- 
> > 2.25.1
> >   



From linux at armlinux.org.uk  Mon Jan 17 08:57:19 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 16:57:19 +0000
Subject: [PATCH v5 07/69] KVM: arm64: nv: Introduce nested virtualization
 VCPU feature
In-Reply-To: <20211129200150.351436-8-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-8-maz@kernel.org>
Message-ID: <YeWf70AwuTETyvu9@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:48PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> Introduce the feature bit and a primitive that checks if the feature is
> set behind a static key check based on the cpus_have_const_cap check.
> 
> Checking nested_virt_in_use() on systems without nested virt enabled
> should have neglgible overhead.
> 
> We don't yet allow userspace to actually set this feature.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From henrik at grimler.se  Mon Jan 17 08:58:28 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Mon, 17 Jan 2022 17:58:28 +0100
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <001301d80b66$190901a0$4b1b04e0$@samsung.com>
References: <20220116165035.437274-1-henrik@grimler.se>
 <20220116165035.437274-4-henrik@grimler.se>
 <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>
 <CGME20220116205940epcas5p3dbab01fb6bb7a4af76169231e6d94469@epcas5p3.samsung.com>
 <YeSHNCywXhp8gHC7@L14.lan>
 <001301d80b66$190901a0$4b1b04e0$@samsung.com>
Message-ID: <YeWgNJaDHxKROpQs@grimlerstat>

Hi Alim,

> >> > +/* External sdcard */
> >> > +&mmc_2 {
> >> > +	status = "okay";
> >> > +	bus-width = <4>;
> >> > +	cap-sd-highspeed;
> >> > +	card-detect-delay = <200>;
> >> > +	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
> >> > +	pinctrl-names = "default";
> >> > +	samsung,dw-mshc-ciu-div = <3>;
> >> > +	samsung,dw-mshc-ddr-timing = <0 2>;
> >> > +	samsung,dw-mshc-sdr-timing = <0 4>;
> >> > +	sd-uhs-sdr50;
> >> > +	vmmc-supply = <&ldo19_reg>;
> >> > +	vqmmc-supply = <&ldo13_reg>;
> >> > +};
> >> > +
> >> > +&pinctrl_0 {
> >> > +	mmc2_cd: sd2-cd-pins {
> >> > +		samsung,pins = "gpx2-4";
> >>
> >> Interesting... I looked at vendor sources to board-chagall and
> >> standard pin gpc2-2 is mentioned as PULL down and not-connected
> >comment.
> >>
> >> gpx2-4 seems not mentioned at all, unless other board files are
> >> actually used.
> >
> >Gpio seems to be spread out. GPIO_T_FLASH_DETECT is defined as gpx2-4 in
> >board-universal5420-mmc.c, and then used for card detection.
> >(Looking at it now again I see that write protection through sd2_wp should
> >also be supported for mmc_2, can add that in next patch set.)
> >
> Card detect pin is generally a special function (dedicated pin) pin,
> directly connected from SoC to card external slot.
> And for exynos5420 it is gpc2-2 as pointed by Krzysztof.

gpio/pinctrl is still not my area of expertise so your feedback is
greatly appreciated!

gpc2-2 does not seem to be the card-detect pin for these tablets.  If
I add sd2_cd to pinctrl-0 above I am unable to use the sdcard at all,
instead dmesg is filled with repeating messages like:

[  18.669050] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 300000Hz, actual 297619HZ div = 84)
[  18.703711] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 200000Hz, actual 200000HZ div = 125)
[  18.737167] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 100000Hz, actual 100000HZ div = 250)
[  19.058352] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63)
[  19.093037] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 300000Hz, actual 297619HZ div = 84)
[  19.127701] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 200000Hz, actual 200000HZ div = 125)
[  19.162380] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req 100000Hz, actual 100000HZ div = 250)

gpx2-4 on the other hand switches state when an sdcard is inserted or
removed.  After exporting relevant pins I have, with the card
inserted:

# grep -A 2 gpx2 /sys/kernel/debug/gpio
gpiochip3: GPIOs 24-31, parent: platform/13400000.pinctrl, gpx2:
 gpio-26  (                    |Power               ) in  hi IRQ ACTIVE LOW
 gpio-28  (                    |sysfs               ) in  lo 

and when removed gpx2-4 changes to high:

gpiochip3: GPIOs 24-31, parent: platform/13400000.pinctrl, gpx2:
 gpio-26  (                    |Power               ) in  hi IRQ ACTIVE LOW
 gpio-28  (                    |sysfs               ) in  hi 

All the gpc2 pins are low no matter if sdcard is inserted or removed:

gpiochip7: GPIOs 56-62, parent: platform/13410000.pinctrl, gpc2:
 gpio-56  (                    |sysfs               ) in  lo 
 gpio-57  (                    |sysfs               ) in  lo 
 gpio-58  (                    |sysfs               ) in  lo 
 gpio-59  (                    |sysfs               ) in  lo 
 gpio-60  (                    |sysfs               ) in  lo 
 gpio-61  (                    |sysfs               ) in  lo 
 gpio-62  (                    |sysfs               ) in  lo 

That being said, I am not sure if it is working properly:

> Also PIN_FUNC_2 for gpx2-4 indicate that it is wakeup_int2 function.
> Do you get a card detect interrupt when removing and inserting the card to
> the card slot?

(What is the best way to check this?) I don't get any irq related
messages in dmesg, and I don't see any changes in /proc/interrupts if
tracked with something like `watch -n1 "cat /proc/interrupts"` when
card is removed or inserted, so seems likely that pin config is wrong.
All I can find in vendor kernel for this device is that pull config is
set to S3C_GPIO_PULL_NONE [1].  For some of the sibling tablets the
pin is configured as {S3C_GPIO_INPUT, GPIO_LV_N, S3C_GPIO_PULL_NONE}
[2] though, which I think should correspond to having:

mmc2_cd: mmc2-cd-pins {
  samsung,pins = "gpx2-4";
  samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
  samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
  samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>;
};

Changing to that does not seem to change anything though, I don't get
any interrupt, or any messages in dmesg, when inserting or removing
the sdcard.

> Also to avoid confusion, probably you can change the node name as "mmc2_cd:
> mmc2-cd-pins" 
> (as sd2-cd-pins is gpc2-2 for this SoC)

Thanks, will fix in a v4 (after discussions here are settled).

[1] https://github.com/exynos5420/android_kernel_samsung_exynos5420/blob/lineage-17.1/arch/arm/mach-exynos/board-universal5420-mmc.c#L388
[2] https://github.com/exynos5420/android_kernel_samsung_exynos5420/blob/lineage-17.1/arch/arm/mach-exynos/board-n1-gpio.c#L119

Best regards,
Henrik Grimler


From sashal at kernel.org  Mon Jan 17 08:58:02 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:02 -0500
Subject: [PATCH AUTOSEL 5.16 01/52] clk: imx: Use div64_ul instead of do_div
Message-ID: <20220117165853.1470420-1-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 20ee9611ba6e3..eea32f87c60aa 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -247,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -277,7 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -334,7 +334,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:03 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:03 -0500
Subject: [PATCH AUTOSEL 5.16 02/52] clk: samsung: exynos850: Register clocks
 early
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-2-sashal@kernel.org>

From: Sam Protsenko <semen.protsenko at linaro.org>

[ Upstream commit bcda841f9bf2cddcf2f000cba96f2e27f6f2bdbf ]

Some clocks must be registered before init calls. For example MCT clock
(from CMU_PERI) is needed for MCT timer driver, which is registered
with TIMER_OF_DECLARE(). By the time we get to core_initcall() used for
clk-exynos850 platform driver init, it's already too late. Inability to
get "mct" clock in MCT driver leads to kernel panic, as functions
registered with *_OF_DECLARE() can't do deferred calls. MCT timer driver
can't be fixed either, as it's acting as a clock source and it's
essential to register it in start_kernel() -> time_init().

Let's register CMU_PERI clocks early, using CLK_OF_DECLARE(). CMU_TOP
generates clocks needed for CMU_PERI, but it's already registered early.

While at it, let's cleanup the code a bit, by extracting everything
related to CMU initialization and registration to the separate function.

Similar issue was discussed at [1] and addressed in commit 1f7db7bbf031
("clk: renesas: cpg-mssr: Add early clock support"), as well as in
drivers/clk/mediatek/clk-mt2712.c.

[1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/20180829132954.64862-2-chris.brandt at renesas.com/

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Link: https://lore.kernel.org/r/20211122144206.23134-1-semen.protsenko at linaro.org
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/samsung/clk-exynos850.c | 70 ++++++++++++++++++++---------
 1 file changed, 49 insertions(+), 21 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c
index 2294989e244c5..79cce8ba88831 100644
--- a/drivers/clk/samsung/clk-exynos850.c
+++ b/drivers/clk/samsung/clk-exynos850.c
@@ -60,6 +60,43 @@ static void __init exynos850_init_clocks(struct device_node *np,
 	iounmap(reg_base);
 }
 
+/**
+ * exynos850_register_cmu - Register specified Exynos850 CMU domain
+ * @dev:	Device object; may be NULL if this function is not being
+ *		called from platform driver probe function
+ * @np:		CMU device tree node
+ * @cmu:	CMU data
+ *
+ * Register specified CMU domain, which includes next steps:
+ *
+ * 1. Enable parent clock of @cmu CMU
+ * 2. Set initial registers configuration for @cmu CMU clocks
+ * 3. Register @cmu CMU clocks using Samsung clock framework API
+ */
+static void __init exynos850_register_cmu(struct device *dev,
+		struct device_node *np, const struct samsung_cmu_info *cmu)
+{
+	/* Keep CMU parent clock running (needed for CMU registers access) */
+	if (cmu->clk_name) {
+		struct clk *parent_clk;
+
+		if (dev)
+			parent_clk = clk_get(dev, cmu->clk_name);
+		else
+			parent_clk = of_clk_get_by_name(np, cmu->clk_name);
+
+		if (IS_ERR(parent_clk)) {
+			pr_err("%s: could not find bus clock %s; err = %ld\n",
+			       __func__, cmu->clk_name, PTR_ERR(parent_clk));
+		} else {
+			clk_prepare_enable(parent_clk);
+		}
+	}
+
+	exynos850_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
+	samsung_cmu_register_one(np, cmu);
+}
+
 /* ---- CMU_TOP ------------------------------------------------------------- */
 
 /* Register Offset definitions for CMU_TOP (0x120e0000) */
@@ -347,10 +384,10 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
 
 static void __init exynos850_cmu_top_init(struct device_node *np)
 {
-	exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs));
-	samsung_cmu_register_one(np, &top_cmu_info);
+	exynos850_register_cmu(NULL, np, &top_cmu_info);
 }
 
+/* Register CMU_TOP early, as it's a dependency for other early domains */
 CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top",
 	       exynos850_cmu_top_init);
 
@@ -615,6 +652,15 @@ static const struct samsung_cmu_info peri_cmu_info __initconst = {
 	.clk_name		= "dout_peri_bus",
 };
 
+static void __init exynos850_cmu_peri_init(struct device_node *np)
+{
+	exynos850_register_cmu(NULL, np, &peri_cmu_info);
+}
+
+/* Register CMU_PERI early, as it's needed for MCT timer */
+CLK_OF_DECLARE(exynos850_cmu_peri, "samsung,exynos850-cmu-peri",
+	       exynos850_cmu_peri_init);
+
 /* ---- CMU_CORE ------------------------------------------------------------ */
 
 /* Register Offset definitions for CMU_CORE (0x12000000) */
@@ -779,24 +825,9 @@ static int __init exynos850_cmu_probe(struct platform_device *pdev)
 {
 	const struct samsung_cmu_info *info;
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
 
 	info = of_device_get_match_data(dev);
-	exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs);
-	samsung_cmu_register_one(np, info);
-
-	/* Keep bus clock running, so it's possible to access CMU registers */
-	if (info->clk_name) {
-		struct clk *bus_clk;
-
-		bus_clk = clk_get(dev, info->clk_name);
-		if (IS_ERR(bus_clk)) {
-			pr_err("%s: could not find bus clock %s; err = %ld\n",
-			       __func__, info->clk_name, PTR_ERR(bus_clk));
-		} else {
-			clk_prepare_enable(bus_clk);
-		}
-	}
+	exynos850_register_cmu(dev, dev->of_node, info);
 
 	return 0;
 }
@@ -806,9 +837,6 @@ static const struct of_device_id exynos850_cmu_of_match[] = {
 	{
 		.compatible = "samsung,exynos850-cmu-hsi",
 		.data = &hsi_cmu_info,
-	}, {
-		.compatible = "samsung,exynos850-cmu-peri",
-		.data = &peri_cmu_info,
 	}, {
 		.compatible = "samsung,exynos850-cmu-core",
 		.data = &core_cmu_info,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:09 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:09 -0500
Subject: [PATCH AUTOSEL 5.16 08/52] ASoC: imx-hdmi: add put_device() after
 of_find_device_by_node()
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-8-sashal@kernel.org>

From: Ye Guojin <ye.guojin at zte.com.cn>

[ Upstream commit f670b274f7f6f4b2722d7f08d0fddf606a727e92 ]

This was found by coccicheck:
./sound/soc/fsl/imx-hdmi.c,209,1-7,ERROR  missing put_device; call
of_find_device_by_node on line 119, but without a corresponding object
release within this function.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Ye Guojin <ye.guojin at zte.com.cn>
Link: https://lore.kernel.org/r/20211110002910.134915-1-ye.guojin at zte.com.cn
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/fsl/imx-hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
index f10359a288005..929f69b758af4 100644
--- a/sound/soc/fsl/imx-hdmi.c
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -145,6 +145,8 @@ static int imx_hdmi_probe(struct platform_device *pdev)
 	data->dai.capture_only = false;
 	data->dai.init = imx_hdmi_init;
 
+	put_device(&cpu_pdev->dev);
+
 	if (of_node_name_eq(cpu_np, "sai")) {
 		data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
 		data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:13 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:13 -0500
Subject: [PATCH AUTOSEL 5.16 12/52] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-12-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index d6eed760327d0..608e0e8ca49a8 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:44 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:44 -0500
Subject: [PATCH AUTOSEL 5.16 43/52] ASoC: mediatek: mt8192-mt6359: fix
 device_node leak
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-43-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 4e28491a7a198c668437f2be8a91a76aa52f20eb ]

The of_parse_phandle() document:
    >>> Use of_node_put() on it when done.

The driver didn't call of_node_put().  Fixes the leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211214040028.2992627-1-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
index a606133951b70..24a5d0adec1ba 100644
--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
+++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
@@ -1172,7 +1172,11 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:45 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:45 -0500
Subject: [PATCH AUTOSEL 5.16 44/52] phy: phy-mtk-tphy: add support efuse
 setting
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-44-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit 6f2b033cb883f64ad084a75f13634242c7e179a6 ]

Due to some SoCs have a bit shift issue that will drop a bit for usb3
phy or pcie phy, fix it by adding software efuse reading and setting,
but only support it optionally for version 2/3.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218082802.5256-2-chunfeng.yun at mediatek.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 162 ++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdcef865fe9e5..98a942c607a67 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -12,6 +12,7 @@
 #include <linux/iopoll.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
@@ -41,6 +42,9 @@
 #define SSUSB_SIFSLV_V2_U3PHYD		0x200
 #define SSUSB_SIFSLV_V2_U3PHYA		0x400
 
+#define U3P_MISC_REG1		0x04
+#define MR1_EFUSE_AUTO_LOAD_DIS		BIT(6)
+
 #define U3P_USBPHYACR0		0x000
 #define PA0_RG_U2PLL_FORCE_ON		BIT(15)
 #define PA0_USB20_PLL_PREDIV		GENMASK(7, 6)
@@ -133,6 +137,8 @@
 #define P3C_RG_SWRST_U3_PHYD_FORCE_EN	BIT(24)
 
 #define U3P_U3_PHYA_REG0	0x000
+#define P3A_RG_IEXT_INTR		GENMASK(15, 10)
+#define P3A_RG_IEXT_INTR_VAL(x)		((0x3f & (x)) << 10)
 #define P3A_RG_CLKDRV_OFF		GENMASK(3, 2)
 #define P3A_RG_CLKDRV_OFF_VAL(x)	((0x3 & (x)) << 2)
 
@@ -187,6 +193,19 @@
 #define P3D_RG_FWAKE_TH		GENMASK(21, 16)
 #define P3D_RG_FWAKE_TH_VAL(x)	((0x3f & (x)) << 16)
 
+#define U3P_U3_PHYD_IMPCAL0		0x010
+#define P3D_RG_FORCE_TX_IMPEL		BIT(31)
+#define P3D_RG_TX_IMPEL			GENMASK(28, 24)
+#define P3D_RG_TX_IMPEL_VAL(x)		((0x1f & (x)) << 24)
+
+#define U3P_U3_PHYD_IMPCAL1		0x014
+#define P3D_RG_FORCE_RX_IMPEL		BIT(31)
+#define P3D_RG_RX_IMPEL			GENMASK(28, 24)
+#define P3D_RG_RX_IMPEL_VAL(x)		((0x1f & (x)) << 24)
+
+#define U3P_U3_PHYD_RSV			0x054
+#define P3D_RG_EFUSE_AUTO_LOAD_DIS	BIT(12)
+
 #define U3P_U3_PHYD_CDR1		0x05c
 #define P3D_RG_CDR_BIR_LTD1		GENMASK(28, 24)
 #define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
@@ -307,6 +326,11 @@ struct mtk_phy_pdata {
 	 * 48M PLL, fix it by switching PLL to 26M from default 48M
 	 */
 	bool sw_pll_48m_to_26m;
+	/*
+	 * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse,
+	 * support sw way, also support it for v2/v3 optionally.
+	 */
+	bool sw_efuse_supported;
 	enum mtk_phy_version version;
 };
 
@@ -336,6 +360,10 @@ struct mtk_phy_instance {
 	struct regmap *type_sw;
 	u32 type_sw_reg;
 	u32 type_sw_index;
+	u32 efuse_sw_en;
+	u32 efuse_intr;
+	u32 efuse_tx_imp;
+	u32 efuse_rx_imp;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -1040,6 +1068,130 @@ static int phy_type_set(struct mtk_phy_instance *instance)
 	return 0;
 }
 
+static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+	struct device *dev = &instance->phy->dev;
+	int ret = 0;
+
+	/* tphy v1 doesn't support sw efuse, skip it */
+	if (!tphy->pdata->sw_efuse_supported) {
+		instance->efuse_sw_en = 0;
+		return 0;
+	}
+
+	/* software efuse is optional */
+	instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells");
+	if (!instance->efuse_sw_en)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB2:
+		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
+		if (ret) {
+			dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
+			break;
+		}
+
+		/* no efuse, ignore it */
+		if (!instance->efuse_intr) {
+			dev_warn(dev, "no u2 intr efuse, but dts enable it\n");
+			instance->efuse_sw_en = 0;
+			break;
+		}
+
+		dev_dbg(dev, "u2 efuse - intr %x\n", instance->efuse_intr);
+		break;
+
+	case PHY_TYPE_USB3:
+	case PHY_TYPE_PCIE:
+		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
+		if (ret) {
+			dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
+			break;
+		}
+
+		ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp);
+		if (ret) {
+			dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret);
+			break;
+		}
+
+		ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp);
+		if (ret) {
+			dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret);
+			break;
+		}
+
+		/* no efuse, ignore it */
+		if (!instance->efuse_intr &&
+		    !instance->efuse_rx_imp &&
+		    !instance->efuse_rx_imp) {
+			dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
+			instance->efuse_sw_en = 0;
+			break;
+		}
+
+		dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
+			instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp);
+		break;
+	default:
+		dev_err(dev, "no sw efuse for type %d\n", instance->type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void phy_efuse_set(struct mtk_phy_instance *instance)
+{
+	struct device *dev = &instance->phy->dev;
+	struct u2phy_banks *u2_banks = &instance->u2_banks;
+	struct u3phy_banks *u3_banks = &instance->u3_banks;
+	u32 tmp;
+
+	if (!instance->efuse_sw_en)
+		return;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB2:
+		tmp = readl(u2_banks->misc + U3P_MISC_REG1);
+		tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
+		writel(tmp, u2_banks->misc + U3P_MISC_REG1);
+
+		tmp = readl(u2_banks->com + U3P_USBPHYACR1);
+		tmp &= ~PA1_RG_INTR_CAL;
+		tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr);
+		writel(tmp, u2_banks->com + U3P_USBPHYACR1);
+		break;
+	case PHY_TYPE_USB3:
+	case PHY_TYPE_PCIE:
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
+		tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
+
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
+		tmp &= ~P3D_RG_TX_IMPEL;
+		tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
+		tmp |= P3D_RG_FORCE_TX_IMPEL;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
+
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
+		tmp &= ~P3D_RG_RX_IMPEL;
+		tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
+		tmp |= P3D_RG_FORCE_RX_IMPEL;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
+
+		tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_IEXT_INTR;
+		tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
+		writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
+		break;
+	default:
+		dev_warn(dev, "no sw efuse for type %d\n", instance->type);
+		break;
+	}
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1050,6 +1202,8 @@ static int mtk_phy_init(struct phy *phy)
 	if (ret)
 		return ret;
 
+	phy_efuse_set(instance);
+
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
 		u2_phy_instance_init(tphy, instance);
@@ -1134,6 +1288,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	struct mtk_phy_instance *instance = NULL;
 	struct device_node *phy_np = args->np;
 	int index;
+	int ret;
 
 	if (args->args_count != 1) {
 		dev_err(dev, "invalid number of cells in 'phy' property\n");
@@ -1174,6 +1329,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 		return ERR_PTR(-EINVAL);
 	}
 
+	ret = phy_efuse_get(tphy, instance);
+	if (ret)
+		return ERR_PTR(ret);
+
 	phy_parse_property(tphy, instance);
 	phy_type_set(instance);
 
@@ -1196,10 +1355,12 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
 
 static const struct mtk_phy_pdata tphy_v2_pdata = {
 	.avoid_rx_sen_degradation = false,
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V2,
 };
 
 static const struct mtk_phy_pdata tphy_v3_pdata = {
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V3,
 };
 
@@ -1210,6 +1371,7 @@ static const struct mtk_phy_pdata mt8173_pdata = {
 
 static const struct mtk_phy_pdata mt8195_pdata = {
 	.sw_pll_48m_to_26m = true,
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V3,
 };
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:46 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:46 -0500
Subject: [PATCH AUTOSEL 5.16 45/52] ASoC: mediatek: mt8173: fix device_node
 leak
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-45-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index fc94314bfc02f..3bdd4931316cd 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -180,6 +180,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 0f28dc2217c09..390da5bf727eb 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -218,6 +218,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 077c6ee067806..c8e4e85e10575 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 2cbf679f5c74b..d8cf0802813a0 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -323,6 +323,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:47 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:47 -0500
Subject: [PATCH AUTOSEL 5.16 46/52] ASoC: mediatek: mt8183: fix device_node
 leak
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-46-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit cb006006fe6221f092fadaffd3f219288304c9ad ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-3-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c         | 6 +++++-
 sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 7 ++++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
index a4d26a6fc8492..bda103211e0bd 100644
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
@@ -781,7 +781,11 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index aeb1af86047ef..9f0bf15fe465e 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -780,7 +780,12 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
 				 __func__, ret);
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(ec_codec);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 08:58:50 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 11:58:50 -0500
Subject: [PATCH AUTOSEL 5.16 49/52] phy: mediatek: Fix missing check in
 mtk_mipi_tx_probe
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
Message-ID: <20220117165853.1470420-49-sashal@kernel.org>

From: Miaoqian Lin <linmq006 at gmail.com>

[ Upstream commit 399c91c3f30531593e5ff6ca7b53f47092128669 ]

The of_device_get_match_data() function may return NULL.
Add check to prevent potential null dereference.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20211224082103.7658-1-linmq006 at gmail.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 28ad9403c4414..67b005d5b9e35 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -146,6 +146,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
+	if (!mipi_tx->driver_data)
+		return -ENODEV;
 
 	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mipi_tx->regs))
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:00:44 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:00:44 -0500
Subject: [PATCH AUTOSEL 5.15 01/44] clk: imx: Use div64_ul instead of do_div
Message-ID: <20220117170127.1471115-1-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 20ee9611ba6e3..eea32f87c60aa 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -247,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -277,7 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -334,7 +334,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:00:50 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:00:50 -0500
Subject: [PATCH AUTOSEL 5.15 07/44] ASoC: imx-hdmi: add put_device() after
 of_find_device_by_node()
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-7-sashal@kernel.org>

From: Ye Guojin <ye.guojin at zte.com.cn>

[ Upstream commit f670b274f7f6f4b2722d7f08d0fddf606a727e92 ]

This was found by coccicheck:
./sound/soc/fsl/imx-hdmi.c,209,1-7,ERROR  missing put_device; call
of_find_device_by_node on line 119, but without a corresponding object
release within this function.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Ye Guojin <ye.guojin at zte.com.cn>
Link: https://lore.kernel.org/r/20211110002910.134915-1-ye.guojin at zte.com.cn
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/fsl/imx-hdmi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
index 34a0dceae6216..ef8d7a65ebc61 100644
--- a/sound/soc/fsl/imx-hdmi.c
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -145,6 +145,8 @@ static int imx_hdmi_probe(struct platform_device *pdev)
 	data->dai.capture_only = false;
 	data->dai.init = imx_hdmi_init;
 
+	put_device(&cpu_pdev->dev);
+
 	if (of_node_name_eq(cpu_np, "sai")) {
 		data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1;
 		data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:00:54 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:00:54 -0500
Subject: [PATCH AUTOSEL 5.15 11/44] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-11-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index d6eed760327d0..608e0e8ca49a8 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From mark.rutland at arm.com  Mon Jan 17 09:02:25 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 17:02:25 +0000
Subject: Missing ARM TWD Watchdog driver?
In-Reply-To: <60dceae6-5c7c-9f2d-9fcb-5e849f1d8ce5@roeck-us.net>
References: <20220117190112.2b2c2f53@pc>
 <60dceae6-5c7c-9f2d-9fcb-5e849f1d8ce5@roeck-us.net>
Message-ID: <20220117170225.GB94025@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 08:34:57AM -0800, Guenter Roeck wrote:
> On 1/17/22 8:01 AM, Boris Lysov wrote:
> > Hello everyone,
> > 
> > I stumbled upon the ARM TWD Watchdog driver which seems to be missing (or I'm
> > just blind).
> > 
> > As per commit a33f5c380c4bd3fa5278d690421b72052456d9fe ("Merge tag
> > 'xfs-5.17-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux"), multiple
> > device trees declare usage of arm-twd:
> > 
> > arch/arm/boot/dts/arm-realview-eb-mp.dtsi
> > arch/arm/boot/dts/arm-realview-pb11mp.dts
> > arch/arm/boot/dts/arm-realview-pbx-a9.dts
> > arch/arm/boot/dts/bcm5301x.dtsi
> > arch/arm/boot/dts/bcm63138.dtsi
> > arch/arm/boot/dts/bcm-hr2.dtsi
> > arch/arm/boot/dts/bcm-nsp.dtsi
> > arch/arm/boot/dts/berlin2cd.dtsi
> > arch/arm/boot/dts/highbank.dts
> > arch/arm/boot/dts/mmp3.dtsi
> > arch/arm/boot/dts/owl-s500.dtsi
> > arch/arm/boot/dts/spear13xx.dtsi
> > arch/arm/boot/dts/ste-dbx5x0.dtsi
> > arch/arm/boot/dts/vexpress-v2p-ca5s.dts
> > arch/arm/boot/dts/vexpress-v2p-ca9.dts
> > 
> > and it is documented in
> > Documentation/devicetree/bindings/watchdog/arm,twd-wdt.yaml
> > 
> > However I could not find the driver itself. I tried running case-insensitive
> > grep and ripgrep to no avail. Does this driver actually exist? Is it gone?
> > 
> 
> I may be missing it, but I do not see any evidence that it ever existed.

Likewise, AFAICT we added the binding but never the driver.

Looking at the git history, that schema was introduced in commit:

  50e02e9a030a9ae3 ("dt-bindings: timer: arm,twd: Convert to json-schema")

... and replaced Documentation/devicetree/bindings/timer/arm,twd.txt

Per:

  $ git log --follow Documentation/devicetree/bindings/timer/arm,twd.txt

That was introduced alongside a driver in commit:

  d8e0364364d333fe ("ARM: smp_twd: add device tree support")

... which only introduced a driver for the timer, and not the watchdog,
as the commit message notes.

Thanks.
Mark.


From sashal at kernel.org  Mon Jan 17 09:01:20 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:01:20 -0500
Subject: [PATCH AUTOSEL 5.15 37/44] ASoC: mediatek: mt8192-mt6359: fix
 device_node leak
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-37-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 4e28491a7a198c668437f2be8a91a76aa52f20eb ]

The of_parse_phandle() document:
    >>> Use of_node_put() on it when done.

The driver didn't call of_node_put().  Fixes the leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211214040028.2992627-1-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
index a606133951b70..24a5d0adec1ba 100644
--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
+++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c
@@ -1172,7 +1172,11 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:01:21 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:01:21 -0500
Subject: [PATCH AUTOSEL 5.15 38/44] phy: phy-mtk-tphy: add support efuse
 setting
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-38-sashal@kernel.org>

From: Chunfeng Yun <chunfeng.yun at mediatek.com>

[ Upstream commit 6f2b033cb883f64ad084a75f13634242c7e179a6 ]

Due to some SoCs have a bit shift issue that will drop a bit for usb3
phy or pcie phy, fix it by adding software efuse reading and setting,
but only support it optionally for version 2/3.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Link: https://lore.kernel.org/r/20211218082802.5256-2-chunfeng.yun at mediatek.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/phy/mediatek/phy-mtk-tphy.c | 162 ++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c
index cdcef865fe9e5..98a942c607a67 100644
--- a/drivers/phy/mediatek/phy-mtk-tphy.c
+++ b/drivers/phy/mediatek/phy-mtk-tphy.c
@@ -12,6 +12,7 @@
 #include <linux/iopoll.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/nvmem-consumer.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/phy/phy.h>
@@ -41,6 +42,9 @@
 #define SSUSB_SIFSLV_V2_U3PHYD		0x200
 #define SSUSB_SIFSLV_V2_U3PHYA		0x400
 
+#define U3P_MISC_REG1		0x04
+#define MR1_EFUSE_AUTO_LOAD_DIS		BIT(6)
+
 #define U3P_USBPHYACR0		0x000
 #define PA0_RG_U2PLL_FORCE_ON		BIT(15)
 #define PA0_USB20_PLL_PREDIV		GENMASK(7, 6)
@@ -133,6 +137,8 @@
 #define P3C_RG_SWRST_U3_PHYD_FORCE_EN	BIT(24)
 
 #define U3P_U3_PHYA_REG0	0x000
+#define P3A_RG_IEXT_INTR		GENMASK(15, 10)
+#define P3A_RG_IEXT_INTR_VAL(x)		((0x3f & (x)) << 10)
 #define P3A_RG_CLKDRV_OFF		GENMASK(3, 2)
 #define P3A_RG_CLKDRV_OFF_VAL(x)	((0x3 & (x)) << 2)
 
@@ -187,6 +193,19 @@
 #define P3D_RG_FWAKE_TH		GENMASK(21, 16)
 #define P3D_RG_FWAKE_TH_VAL(x)	((0x3f & (x)) << 16)
 
+#define U3P_U3_PHYD_IMPCAL0		0x010
+#define P3D_RG_FORCE_TX_IMPEL		BIT(31)
+#define P3D_RG_TX_IMPEL			GENMASK(28, 24)
+#define P3D_RG_TX_IMPEL_VAL(x)		((0x1f & (x)) << 24)
+
+#define U3P_U3_PHYD_IMPCAL1		0x014
+#define P3D_RG_FORCE_RX_IMPEL		BIT(31)
+#define P3D_RG_RX_IMPEL			GENMASK(28, 24)
+#define P3D_RG_RX_IMPEL_VAL(x)		((0x1f & (x)) << 24)
+
+#define U3P_U3_PHYD_RSV			0x054
+#define P3D_RG_EFUSE_AUTO_LOAD_DIS	BIT(12)
+
 #define U3P_U3_PHYD_CDR1		0x05c
 #define P3D_RG_CDR_BIR_LTD1		GENMASK(28, 24)
 #define P3D_RG_CDR_BIR_LTD1_VAL(x)	((0x1f & (x)) << 24)
@@ -307,6 +326,11 @@ struct mtk_phy_pdata {
 	 * 48M PLL, fix it by switching PLL to 26M from default 48M
 	 */
 	bool sw_pll_48m_to_26m;
+	/*
+	 * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse,
+	 * support sw way, also support it for v2/v3 optionally.
+	 */
+	bool sw_efuse_supported;
 	enum mtk_phy_version version;
 };
 
@@ -336,6 +360,10 @@ struct mtk_phy_instance {
 	struct regmap *type_sw;
 	u32 type_sw_reg;
 	u32 type_sw_index;
+	u32 efuse_sw_en;
+	u32 efuse_intr;
+	u32 efuse_tx_imp;
+	u32 efuse_rx_imp;
 	int eye_src;
 	int eye_vrt;
 	int eye_term;
@@ -1040,6 +1068,130 @@ static int phy_type_set(struct mtk_phy_instance *instance)
 	return 0;
 }
 
+static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance)
+{
+	struct device *dev = &instance->phy->dev;
+	int ret = 0;
+
+	/* tphy v1 doesn't support sw efuse, skip it */
+	if (!tphy->pdata->sw_efuse_supported) {
+		instance->efuse_sw_en = 0;
+		return 0;
+	}
+
+	/* software efuse is optional */
+	instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells");
+	if (!instance->efuse_sw_en)
+		return 0;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB2:
+		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
+		if (ret) {
+			dev_err(dev, "fail to get u2 intr efuse, %d\n", ret);
+			break;
+		}
+
+		/* no efuse, ignore it */
+		if (!instance->efuse_intr) {
+			dev_warn(dev, "no u2 intr efuse, but dts enable it\n");
+			instance->efuse_sw_en = 0;
+			break;
+		}
+
+		dev_dbg(dev, "u2 efuse - intr %x\n", instance->efuse_intr);
+		break;
+
+	case PHY_TYPE_USB3:
+	case PHY_TYPE_PCIE:
+		ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr);
+		if (ret) {
+			dev_err(dev, "fail to get u3 intr efuse, %d\n", ret);
+			break;
+		}
+
+		ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp);
+		if (ret) {
+			dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret);
+			break;
+		}
+
+		ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp);
+		if (ret) {
+			dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret);
+			break;
+		}
+
+		/* no efuse, ignore it */
+		if (!instance->efuse_intr &&
+		    !instance->efuse_rx_imp &&
+		    !instance->efuse_rx_imp) {
+			dev_warn(dev, "no u3 intr efuse, but dts enable it\n");
+			instance->efuse_sw_en = 0;
+			break;
+		}
+
+		dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n",
+			instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp);
+		break;
+	default:
+		dev_err(dev, "no sw efuse for type %d\n", instance->type);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static void phy_efuse_set(struct mtk_phy_instance *instance)
+{
+	struct device *dev = &instance->phy->dev;
+	struct u2phy_banks *u2_banks = &instance->u2_banks;
+	struct u3phy_banks *u3_banks = &instance->u3_banks;
+	u32 tmp;
+
+	if (!instance->efuse_sw_en)
+		return;
+
+	switch (instance->type) {
+	case PHY_TYPE_USB2:
+		tmp = readl(u2_banks->misc + U3P_MISC_REG1);
+		tmp |= MR1_EFUSE_AUTO_LOAD_DIS;
+		writel(tmp, u2_banks->misc + U3P_MISC_REG1);
+
+		tmp = readl(u2_banks->com + U3P_USBPHYACR1);
+		tmp &= ~PA1_RG_INTR_CAL;
+		tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr);
+		writel(tmp, u2_banks->com + U3P_USBPHYACR1);
+		break;
+	case PHY_TYPE_USB3:
+	case PHY_TYPE_PCIE:
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV);
+		tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV);
+
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
+		tmp &= ~P3D_RG_TX_IMPEL;
+		tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp);
+		tmp |= P3D_RG_FORCE_TX_IMPEL;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0);
+
+		tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
+		tmp &= ~P3D_RG_RX_IMPEL;
+		tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp);
+		tmp |= P3D_RG_FORCE_RX_IMPEL;
+		writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1);
+
+		tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0);
+		tmp &= ~P3A_RG_IEXT_INTR;
+		tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr);
+		writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0);
+		break;
+	default:
+		dev_warn(dev, "no sw efuse for type %d\n", instance->type);
+		break;
+	}
+}
+
 static int mtk_phy_init(struct phy *phy)
 {
 	struct mtk_phy_instance *instance = phy_get_drvdata(phy);
@@ -1050,6 +1202,8 @@ static int mtk_phy_init(struct phy *phy)
 	if (ret)
 		return ret;
 
+	phy_efuse_set(instance);
+
 	switch (instance->type) {
 	case PHY_TYPE_USB2:
 		u2_phy_instance_init(tphy, instance);
@@ -1134,6 +1288,7 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 	struct mtk_phy_instance *instance = NULL;
 	struct device_node *phy_np = args->np;
 	int index;
+	int ret;
 
 	if (args->args_count != 1) {
 		dev_err(dev, "invalid number of cells in 'phy' property\n");
@@ -1174,6 +1329,10 @@ static struct phy *mtk_phy_xlate(struct device *dev,
 		return ERR_PTR(-EINVAL);
 	}
 
+	ret = phy_efuse_get(tphy, instance);
+	if (ret)
+		return ERR_PTR(ret);
+
 	phy_parse_property(tphy, instance);
 	phy_type_set(instance);
 
@@ -1196,10 +1355,12 @@ static const struct mtk_phy_pdata tphy_v1_pdata = {
 
 static const struct mtk_phy_pdata tphy_v2_pdata = {
 	.avoid_rx_sen_degradation = false,
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V2,
 };
 
 static const struct mtk_phy_pdata tphy_v3_pdata = {
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V3,
 };
 
@@ -1210,6 +1371,7 @@ static const struct mtk_phy_pdata mt8173_pdata = {
 
 static const struct mtk_phy_pdata mt8195_pdata = {
 	.sw_pll_48m_to_26m = true,
+	.sw_efuse_supported = true,
 	.version = MTK_PHY_V3,
 };
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:01:22 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:01:22 -0500
Subject: [PATCH AUTOSEL 5.15 39/44] ASoC: mediatek: mt8173: fix device_node
 leak
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-39-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index fc94314bfc02f..3bdd4931316cd 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -180,6 +180,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 0f28dc2217c09..390da5bf727eb 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -218,6 +218,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 077c6ee067806..c8e4e85e10575 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index c28ebf891cb05..e168d31f44459 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -323,6 +323,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:01:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:01:23 -0500
Subject: [PATCH AUTOSEL 5.15 40/44] ASoC: mediatek: mt8183: fix device_node
 leak
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-40-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit cb006006fe6221f092fadaffd3f219288304c9ad ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-3-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c         | 6 +++++-
 sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 7 ++++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
index a4d26a6fc8492..bda103211e0bd 100644
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
@@ -781,7 +781,11 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index 94dcbd36c8697..c7b10c48c6c22 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -780,7 +780,12 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
 				 __func__, ret);
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(ec_codec);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:01:25 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:01:25 -0500
Subject: [PATCH AUTOSEL 5.15 42/44] phy: mediatek: Fix missing check in
 mtk_mipi_tx_probe
In-Reply-To: <20220117170127.1471115-1-sashal@kernel.org>
References: <20220117170127.1471115-1-sashal@kernel.org>
Message-ID: <20220117170127.1471115-42-sashal@kernel.org>

From: Miaoqian Lin <linmq006 at gmail.com>

[ Upstream commit 399c91c3f30531593e5ff6ca7b53f47092128669 ]

The of_device_get_match_data() function may return NULL.
Add check to prevent potential null dereference.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20211224082103.7658-1-linmq006 at gmail.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/phy/mediatek/phy-mtk-mipi-dsi.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
index 28ad9403c4414..67b005d5b9e35 100644
--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
+++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c
@@ -146,6 +146,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
+	if (!mipi_tx->driver_data)
+		return -ENODEV;
 
 	mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mipi_tx->regs))
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:02:52 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:02:52 -0500
Subject: [PATCH AUTOSEL 5.10 02/34] clk: imx: Use div64_ul instead of do_div
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-2-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 20ee9611ba6e3..eea32f87c60aa 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -247,7 +247,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -277,7 +277,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -334,7 +334,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:03:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:03:01 -0500
Subject: [PATCH AUTOSEL 5.10 11/34] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-11-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 0a68af6eec3dd..d42551a46ec91 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -712,6 +712,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -748,7 +777,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3043,7 +3081,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3438,7 +3476,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:03:21 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:03:21 -0500
Subject: [PATCH AUTOSEL 5.10 31/34] ASoC: mediatek: mt8173: fix device_node
 leak
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-31-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index fc94314bfc02f..3bdd4931316cd 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -180,6 +180,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 0f28dc2217c09..390da5bf727eb 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -218,6 +218,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 077c6ee067806..c8e4e85e10575 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index c28ebf891cb05..e168d31f44459 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -323,6 +323,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:03:22 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:03:22 -0500
Subject: [PATCH AUTOSEL 5.10 32/34] ASoC: mediatek: mt8183: fix device_node
 leak
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-32-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit cb006006fe6221f092fadaffd3f219288304c9ad ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-3-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c         | 6 +++++-
 sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c | 7 ++++++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
index 20d31b69a5c00..9cc0f26b08fbc 100644
--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c
@@ -787,7 +787,11 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index 79ba2f2d84522..14ce8b93597f3 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -720,7 +720,12 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
 				 __func__, ret);
 	}
 
-	return devm_snd_soc_register_card(&pdev->dev, card);
+	ret = devm_snd_soc_register_card(&pdev->dev, card);
+
+	of_node_put(platform_node);
+	of_node_put(ec_codec);
+	of_node_put(hdmi_codec);
+	return ret;
 }
 
 #ifdef CONFIG_OF
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:03:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:03:23 -0500
Subject: [PATCH AUTOSEL 5.10 33/34] phy: mediatek: Fix missing check in
 mtk_mipi_tx_probe
In-Reply-To: <20220117170326.1471712-1-sashal@kernel.org>
References: <20220117170326.1471712-1-sashal@kernel.org>
Message-ID: <20220117170326.1471712-33-sashal@kernel.org>

From: Miaoqian Lin <linmq006 at gmail.com>

[ Upstream commit 399c91c3f30531593e5ff6ca7b53f47092128669 ]

The of_device_get_match_data() function may return NULL.
Add check to prevent potential null dereference.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20211224082103.7658-1-linmq006 at gmail.com
Signed-off-by: Vinod Koul <vkoul at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpu/drm/mediatek/mtk_mipi_tx.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
index 8cee2591e7284..ccc742dc78bd9 100644
--- a/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
+++ b/drivers/gpu/drm/mediatek/mtk_mipi_tx.c
@@ -147,6 +147,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	mipi_tx->driver_data = of_device_get_match_data(dev);
+	if (!mipi_tx->driver_data)
+		return -ENODEV;
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mipi_tx->regs = devm_ioremap_resource(dev, mem);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:04:33 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:04:33 -0500
Subject: [PATCH AUTOSEL 5.4 01/21] clk: imx: Use div64_ul instead of do_div
Message-ID: <20220117170454.1472347-1-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index df91a8244fb4d..c9929d52402b4 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -250,7 +250,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -280,7 +280,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -337,7 +337,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:04:42 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:04:42 -0500
Subject: [PATCH AUTOSEL 5.4 10/21] clk: meson: gxbb: Fix the SDM_EN bit for
 MPLL0 on GXBB
In-Reply-To: <20220117170454.1472347-1-sashal@kernel.org>
References: <20220117170454.1472347-1-sashal@kernel.org>
Message-ID: <20220117170454.1472347-10-sashal@kernel.org>

From: Martin Blumenstingl <martin.blumenstingl at googlemail.com>

[ Upstream commit ff54938dd190d85f740b9bf9dde59b550936b621 ]

There are reports that 48kHz audio does not work on the WeTek Play 2
(which uses a GXBB SoC), while 44.1kHz audio works fine on the same
board. There are also reports of 48kHz audio working fine on GXL and
GXM SoCs, which are using an (almost) identical AIU (audio controller).

Experimenting has shown that MPLL0 is causing this problem. In the .dts
we have by default:
	assigned-clocks = <&clkc CLKID_MPLL0>,
			  <&clkc CLKID_MPLL1>,
			  <&clkc CLKID_MPLL2>;
	assigned-clock-rates = <294912000>,
			       <270950400>,
			       <393216000>;
The MPLL0 rate is divisible by 48kHz without remainder and the MPLL1
rate is divisible by 44.1kHz without remainder. Swapping these two clock
rates "fixes" 48kHz audio but breaks 44.1kHz audio.

Everything looks normal when looking at the info provided by the common
clock framework while playing 48kHz audio (via I2S with mclk-fs = 256):
        mpll_prediv                 1        1        0  2000000000
           mpll0_div                1        1        0   294909641
              mpll0                 1        1        0   294909641
                 cts_amclk_sel       1        1        0   294909641
                    cts_amclk_div       1        1        0    12287902
                       cts_amclk       1        1        0    12287902

meson-clk-msr however shows that the actual MPLL0 clock is off by more
than 38MHz:
        mp0_out               333322917    +/-10416Hz

The rate seen by meson-clk-msr is very close to what we would get when
SDM (the fractional part) was ignored:
  (2000000000Hz * 16384) / ((16384 * 6) = 333.33MHz
If SDM was considered the we should get close to:
  (2000000000Hz * 16384) / ((16384 * 6) + 12808) = 294.9MHz

Further experimenting shows that HHI_MPLL_CNTL7[15] does not have any
effect on the rate of MPLL0 as seen my meson-clk-msr (regardless of
whether that bit is zero or one the rate is always the same according to
meson-clk-msr). Using HHI_MPLL_CNTL[25] on the other hand as SDM_EN
results in SDM being considered for the rate output by the hardware. The
rate - as seen by meson-clk-msr - matches with what we expect when
SDM_EN is enabled (fractional part is being considered, resulting in a
294.9MHz output) or disable (fractional part being ignored, resulting in
a 333.33MHz output).

Reported-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Christian Hewitt <christianshewitt at gmail.com>
Signed-off-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211031135006.1508796-1-martin.blumenstingl at googlemail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/meson/gxbb.c | 44 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 41 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 1f9c056e684ce..e8e36ec70b27f 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -712,6 +712,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
 };
 
 static struct clk_regmap gxbb_mpll0_div = {
+	.data = &(struct meson_clk_mpll_data){
+		.sdm = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 0,
+			.width   = 14,
+		},
+		.sdm_en = {
+			.reg_off = HHI_MPLL_CNTL,
+			.shift   = 25,
+			.width	 = 1,
+		},
+		.n2 = {
+			.reg_off = HHI_MPLL_CNTL7,
+			.shift   = 16,
+			.width   = 9,
+		},
+		.lock = &meson_clk_lock,
+	},
+	.hw.init = &(struct clk_init_data){
+		.name = "mpll0_div",
+		.ops = &meson_clk_mpll_ops,
+		.parent_hws = (const struct clk_hw *[]) {
+			&gxbb_mpll_prediv.hw
+		},
+		.num_parents = 1,
+	},
+};
+
+static struct clk_regmap gxl_mpll0_div = {
 	.data = &(struct meson_clk_mpll_data){
 		.sdm = {
 			.reg_off = HHI_MPLL_CNTL7,
@@ -748,7 +777,16 @@ static struct clk_regmap gxbb_mpll0 = {
 	.hw.init = &(struct clk_init_data){
 		.name = "mpll0",
 		.ops = &clk_regmap_gate_ops,
-		.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
+		.parent_data = &(const struct clk_parent_data) {
+			/*
+			 * Note:
+			 * GXL and GXBB have different SDM_EN registers. We
+			 * fallback to the global naming string mechanism so
+			 * mpll0_div picks up the appropriate one.
+			 */
+			.name = "mpll0_div",
+			.index = -1,
+		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
 	},
@@ -3036,7 +3074,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
 		[CLKID_VAPB_1]		    = &gxbb_vapb_1.hw,
 		[CLKID_VAPB_SEL]	    = &gxbb_vapb_sel.hw,
 		[CLKID_VAPB]		    = &gxbb_vapb.hw,
-		[CLKID_MPLL0_DIV]	    = &gxbb_mpll0_div.hw,
+		[CLKID_MPLL0_DIV]	    = &gxl_mpll0_div.hw,
 		[CLKID_MPLL1_DIV]	    = &gxbb_mpll1_div.hw,
 		[CLKID_MPLL2_DIV]	    = &gxbb_mpll2_div.hw,
 		[CLKID_MPLL_PREDIV]	    = &gxbb_mpll_prediv.hw,
@@ -3430,7 +3468,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
 	&gxbb_mpll0,
 	&gxbb_mpll1,
 	&gxbb_mpll2,
-	&gxbb_mpll0_div,
+	&gxl_mpll0_div,
 	&gxbb_mpll1_div,
 	&gxbb_mpll2_div,
 	&gxbb_cts_amclk_div,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:04:53 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:04:53 -0500
Subject: [PATCH AUTOSEL 5.4 21/21] ASoC: mediatek: mt8173: fix device_node leak
In-Reply-To: <20220117170454.1472347-1-sashal@kernel.org>
References: <20220117170454.1472347-1-sashal@kernel.org>
Message-ID: <20220117170454.1472347-21-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 22c00600c999f..de1410c2c446f 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -180,6 +180,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 8717e87bfe264..6f8542329bab9 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -218,6 +218,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 9d4dd97211548..727ff0f7f20b1 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index ef6f236752867..21e7d4d3ded5a 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -309,6 +309,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:05:35 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:05:35 -0500
Subject: [PATCH AUTOSEL 4.19 01/17] clk: imx: Use div64_ul instead of do_div
Message-ID: <20220117170551.1472640-1-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 9af62ee8f347a..325a03e89cf8d 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -252,7 +252,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -282,7 +282,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -339,7 +339,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From linux at armlinux.org.uk  Mon Jan 17 09:06:10 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 17:06:10 +0000
Subject: [PATCH v5 08/69] KVM: arm64: nv: Reset VCPU to EL2 registers if
 VCPU nested virt is set
In-Reply-To: <20211129200150.351436-9-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-9-maz@kernel.org>
Message-ID: <YeWiAgWbDhTreD7y@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:49PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
> feature is enabled on the VCPU.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> [maz: rework register reset not to use empty data structures]
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

However, a couple of comments below.

> ---
>  arch/arm64/kvm/reset.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> index 426bd7fbc3fd..38a7182819fb 100644
> --- a/arch/arm64/kvm/reset.c
> +++ b/arch/arm64/kvm/reset.c
> @@ -27,6 +27,7 @@
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/virt.h>
>  
>  /* Maximum phys_shift supported for any VM on this host */
> @@ -38,6 +39,9 @@ static u32 kvm_ipa_limit;
>  #define VCPU_RESET_PSTATE_EL1	(PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
>  				 PSR_F_BIT | PSR_D_BIT)
>  
> +#define VCPU_RESET_PSTATE_EL2	(PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> +				 PSR_F_BIT | PSR_D_BIT)
> +
>  #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
>  				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
>  
> @@ -176,8 +180,8 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
>  	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
>  		return false;
>  
> -	/* MTE is incompatible with AArch32 */
> -	if (kvm_has_mte(vcpu->kvm) && is32bit)
> +	/* MTE and NV are incompatible with AArch32 */
> +	if ((kvm_has_mte(vcpu->kvm) || nested_virt_in_use(vcpu)) && is32bit)
>  		return false;

It seems we have a bunch of:

	if (something && is32bit)
		return false;

tests here - would it make sense to do:

	if (is32bit) {
		if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
			return false;

		/* MTE is incompatible with AArch32 */
		if (kvm_has_mte(vcpu->kvm))
			return false;

		/* NV is incompatible with AArch32 */
		if (nested_virt_in_use(vcpu))
			return false;
	}

in terms of improved readability?

> @@ -255,6 +259,8 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
>  	default:
>  		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
>  			pstate = VCPU_RESET_PSTATE_SVC;
> +		} else if (nested_virt_in_use(vcpu)) {
> +			pstate = VCPU_RESET_PSTATE_EL2;
>  		} else {
>  			pstate = VCPU_RESET_PSTATE_EL1;
>  		}

Not an issue with your patch, but the switch around this looks useless.
The only case is this default case, so it's entirely a no-op.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From sashal at kernel.org  Mon Jan 17 09:05:51 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:05:51 -0500
Subject: [PATCH AUTOSEL 4.19 17/17] ASoC: mediatek: mt8173: fix device_node
 leak
In-Reply-To: <20220117170551.1472640-1-sashal@kernel.org>
References: <20220117170551.1472640-1-sashal@kernel.org>
Message-ID: <20220117170551.1472640-17-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 902d111016d6f..431ba3db17594 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -169,6 +169,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 582174d98c6c9..cdb3940710379 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -217,6 +217,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index b3670c8a5b8de..242f99716c619 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -274,6 +274,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index 7a89b4aad182f..14011a70bcc41 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -301,6 +301,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:06:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:06:23 -0500
Subject: [PATCH AUTOSEL 4.14 01/16] clk: imx: Use div64_ul instead of do_div
Message-ID: <20220117170638.1472900-1-sashal@kernel.org>

From: Changcheng Deng <deng.changcheng at zte.com.cn>

[ Upstream commit c1b6ad9a902539f9c037b6b3c35cb134c5724022 ]

do_div() does a 64-by-32 division. Here the divisor is an unsigned long
which on some platforms is 64 bit wide. So use div64_ul instead of do_div
to avoid a possible truncation.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Changcheng Deng <deng.changcheng at zte.com.cn>
Reviewed-by: Abel Vesa <abel.vesa at nxp.com>
Link: https://lore.kernel.org/r/20211118080634.165275-1-deng.changcheng at zte.com.cn
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/clk/imx/clk-pllv3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
index 9af62ee8f347a..325a03e89cf8d 100644
--- a/drivers/clk/imx/clk-pllv3.c
+++ b/drivers/clk/imx/clk-pllv3.c
@@ -252,7 +252,7 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	temp64 = (u64)parent_rate;
@@ -282,7 +282,7 @@ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
 	div = rate / parent_rate;
 	temp64 = (u64) (rate - div * parent_rate);
 	temp64 *= mfd;
-	do_div(temp64, parent_rate);
+	temp64 = div64_ul(temp64, parent_rate);
 	mfn = temp64;
 
 	val = readl_relaxed(pll->base);
@@ -339,7 +339,7 @@ static struct clk_pllv3_vf610_mf clk_pllv3_vf610_rate_to_mf(
 		/* rate = parent_rate * (mfi + mfn/mfd) */
 		temp64 = rate - parent_rate * mf.mfi;
 		temp64 *= mf.mfd;
-		do_div(temp64, parent_rate);
+		temp64 = div64_ul(temp64, parent_rate);
 		mf.mfn = temp64;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 09:06:38 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:06:38 -0500
Subject: [PATCH AUTOSEL 4.14 16/16] ASoC: mediatek: mt8173: fix device_node
 leak
In-Reply-To: <20220117170638.1472900-1-sashal@kernel.org>
References: <20220117170638.1472900-1-sashal@kernel.org>
Message-ID: <20220117170638.1472900-16-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index e0c2b23ec7118..0adb7ded61e9c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -177,6 +177,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 99c15219dbc81..aa52e2f81760a 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -227,6 +227,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 42de84ca8c844..61b0d8f8678e9 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -284,6 +284,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index e69c141d8ed4c..3492c02f72c1a 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -316,6 +316,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From linux at armlinux.org.uk  Mon Jan 17 09:07:35 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 17:07:35 +0000
Subject: [PATCH v5 09/69] KVM: arm64: nv: Allow userspace to set
 PSR_MODE_EL2x
In-Reply-To: <20211129200150.351436-10-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-10-maz@kernel.org>
Message-ID: <YeWiV4wKZjq+RA/o@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:50PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at linaro.org>
> 
> We were not allowing userspace to set a more privileged mode for the VCPU
> than EL1, but we should allow this when nested virtualization is enabled
> for the VCPU.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From sashal at kernel.org  Mon Jan 17 09:07:21 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 12:07:21 -0500
Subject: [PATCH AUTOSEL 4.9 13/13] ASoC: mediatek: mt8173: fix device_node leak
In-Reply-To: <20220117170722.1473137-1-sashal@kernel.org>
References: <20220117170722.1473137-1-sashal@kernel.org>
Message-ID: <20220117170722.1473137-13-sashal@kernel.org>

From: Tzung-Bi Shih <tzungbi at google.com>

[ Upstream commit 493433785df0075afc0c106ab65f10a605d0b35d ]

Fixes the device_node leak.

Signed-off-by: Tzung-Bi Shih <tzungbi at google.com>
Link: https://lore.kernel.org/r/20211224064719.2031210-2-tzungbi at google.com
Signed-off-by: Mark Brown <broonie at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 sound/soc/mediatek/mt8173/mt8173-max98090.c      | 3 +++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | 2 ++
 sound/soc/mediatek/mt8173/mt8173-rt5650.c        | 2 ++
 4 files changed, 9 insertions(+)

diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c
index 5524a2c727ec7..cab30cb48366d 100644
--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c
+++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c
@@ -183,6 +183,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(codec_node);
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
index 467f7049a2886..52fdd766ee82c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c
@@ -228,6 +228,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
index 1b8b2a7788450..5d75b04f074fe 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c
@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
index ba65f4157a7e0..d02a90201b13b 100644
--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c
+++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c
@@ -317,6 +317,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev)
 	if (ret)
 		dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
 			__func__, ret);
+
+	of_node_put(platform_node);
 	return ret;
 }
 
-- 
2.34.1



From krzysztof.kozlowski at canonical.com  Mon Jan 17 09:11:16 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 17 Jan 2022 18:11:16 +0100
Subject: [PATCH AUTOSEL 5.16 02/52] clk: samsung: exynos850: Register
 clocks early
In-Reply-To: <20220117165853.1470420-2-sashal@kernel.org>
References: <20220117165853.1470420-1-sashal@kernel.org>
 <20220117165853.1470420-2-sashal@kernel.org>
Message-ID: <b75a0bc9-0423-83cc-11e1-d5e08952cc93@canonical.com>

On 17/01/2022 17:58, Sasha Levin wrote:
> From: Sam Protsenko <semen.protsenko at linaro.org>
> 
> [ Upstream commit bcda841f9bf2cddcf2f000cba96f2e27f6f2bdbf ]
> 
> Some clocks must be registered before init calls. For example MCT clock
> (from CMU_PERI) is needed for MCT timer driver, which is registered
> with TIMER_OF_DECLARE(). By the time we get to core_initcall() used for
> clk-exynos850 platform driver init, it's already too late. Inability to
> get "mct" clock in MCT driver leads to kernel panic, as functions
> registered with *_OF_DECLARE() can't do deferred calls. MCT timer driver
> can't be fixed either, as it's acting as a clock source and it's
> essential to register it in start_kernel() -> time_init().
> 
> Let's register CMU_PERI clocks early, using CLK_OF_DECLARE(). CMU_TOP
> generates clocks needed for CMU_PERI, but it's already registered early.
> 
> While at it, let's cleanup the code a bit, by extracting everything
> related to CMU initialization and registration to the separate function.
> 
> Similar issue was discussed at [1] and addressed in commit 1f7db7bbf031
> ("clk: renesas: cpg-mssr: Add early clock support"), as well as in
> drivers/clk/mediatek/clk-mt2712.c.
> 
> [1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/20180829132954.64862-2-chris.brandt at renesas.com/
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Link: https://lore.kernel.org/r/20211122144206.23134-1-semen.protsenko at linaro.org
> Signed-off-by: Sasha Levin <sashal at kernel.org>
> ---
>  drivers/clk/samsung/clk-exynos850.c | 70 ++++++++++++++++++++---------
>  1 file changed, 49 insertions(+), 21 deletions(-)
> 

I propose to skip this one.

Backporting it to v5.16 does not hurt but also does not bring any
benefits for the upstream kernel users. There is no support for
mentioned Exynos850 in v5.16.

It could have only meaning for some downstream, out-of-tree kernels
which apply Exynos850 support on top of v5.16, but then they can just
take this patch as well.


Best regards,
Krzysztof


From linux at armlinux.org.uk  Mon Jan 17 09:14:27 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 17:14:27 +0000
Subject: [PATCH v5 10/69] KVM: arm64: nv: Add EL2 system registers to
 vcpu context
In-Reply-To: <20211129200150.351436-11-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-11-maz@kernel.org>
Message-ID: <YeWj82BipOSA8jIe@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:51PM +0000, Marc Zyngier wrote:
> Add the minimal set of EL2 system registers to the vcpu context.
> Nothing uses them just yet.
> 
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mark.rutland at arm.com  Mon Jan 17 09:24:03 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 17:24:03 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <20220117165310.769a4799@donnerap.cambridge.arm.com>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
 <20220117164720.GA94025@C02TD0UTHF1T.local>
 <20220117165310.769a4799@donnerap.cambridge.arm.com>
Message-ID: <20220117172403.GC94025@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 04:53:10PM +0000, Andre Przywara wrote:
> On Mon, 17 Jan 2022 16:47:20 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> > Hi Andre,
> > 
> > On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> > > Our GCC invocation does not provide many parameters, which lets the
> > > toolchain fill in its own default setup.
> > > In case of a native build or when using a full-featured cross-compiler,
> > > this probably means Linux userland, which is not what we want for a
> > > bare-metal application like boot-wrapper.
> > > 
> > > Tell the compiler to forget about those standard settings, and only use
> > > what we explicitly ask for. In particular that means to not use toolchain
> > > provided libraries, since they might pull in more code than we want, and
> > > might not run well in the boot-wrapper environment.  
> > 
> > Thanks for splitting this out; I'd like to apply this with two minor
> > fixups (which I'll apply locally if you agree).
> 
> Yes, I am fine with those changes, please go ahead!

Thanks; I've applied those and pushed that out.

Mark.


From mathieu.poirier at linaro.org  Mon Jan 17 09:26:37 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 17 Jan 2022 10:26:37 -0700
Subject: [PATCH v4 0/2] Add SCP support for mt8186
In-Reply-To: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
References: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220117172637.GB1119324@p14s>

On Wed, Jan 05, 2022 at 05:41:23PM +0800, allen-kh.cheng wrote:
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> changes since v3:
>  - use rproc-next
> 
> changes since v2:
>  - remove redundant SoB
> 
> changes since v1:
>  - use mt8192_power_on_sram() helper
>  - add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
>  - add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h
> 
> Based on rproc-next
> 
> Allen-KH Cheng (2):
>   dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
>   remoteproc: mediatek: Support mt8186 scp
> 
>  .../bindings/remoteproc/mtk,scp.yaml          |  1 +
>  drivers/remoteproc/mtk_common.h               |  3 ++
>  drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
>  3 files changed, 39 insertions(+)

Both patches in this set are giving me a checkpatch warning that is impossible
to miss.  I deleting this patchset from my queue.   

> 
> -- 
> 2.18.0
> 


From andre.przywara at arm.com  Mon Jan 17 09:43:00 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 17:43:00 +0000
Subject: [bootwrapper PATCH v2 12/13] Rework bootmethod initialization
In-Reply-To: <20220114105653.3003399-13-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-13-mark.rutland@arm.com>
Message-ID: <20220117174300.0a91fcf6@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:52 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> We currently initialize the bootmethod late, in assembly code. This
> requires us to maintain the el3/no_el3 distintion late into the boot
> process, and means we cannot produce any helpful diagnostic when booted
> at an unexpected exception level.
> 
> Rework things so that we initialize the bootmethod early, with a warning
> when things are wrong. The el3/no_el3 distinction is now irrelevant to
> the bootmethod code, and can be removed in subsequent patches.
> 
> When a boot-wrapper configured for PSCI is entered at EL2, a warning is
> looged to the serial console as:
> 
> | Boot-wrapper v0.2
> | Entered at EL2
> | Memory layout:
> | [0000000080000000..0000000080001f90] => boot-wrapper
> | [000000008000fff8..0000000080010000] => mbox
> | [0000000080200000..00000000822af200] => kernel
> | [0000000088000000..0000000088002857] => dtb
> |
> | WARNING: PSCI could not be initialized. Boot may fail
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> ---
>  arch/aarch32/include/asm/cpu.h  |  1 +
>  arch/aarch32/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
>  arch/aarch32/psci.S             |  8 +-------
>  arch/aarch32/utils.S            |  9 ---------
>  arch/aarch64/include/asm/psci.h | 28 ++++++++++++++++++++++++++++
>  arch/aarch64/psci.S             | 21 ++-------------------
>  arch/aarch64/spin.S             |  3 +++
>  arch/aarch64/utils.S            |  9 ---------
>  common/init.c                   |  7 ++++++-
>  common/psci.c                   | 22 +++++++++++++++++++---
>  include/boot.h                  |  2 ++
>  11 files changed, 90 insertions(+), 48 deletions(-)
>  create mode 100644 arch/aarch32/include/asm/psci.h
>  create mode 100644 arch/aarch64/include/asm/psci.h
> 
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index c1bce9a..3426075 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -63,6 +63,7 @@ static inline unsigned long read_cpsr(void)
>  #define SCR		"p15, 0, %0, c1, c1, 0"
>  #define NSACR		"p15, 0, %0, c1, c1, 2"
>  #define ICIALLU		"p15, 0, %0, c7, c5, 0"
> +#define MVBAR		"p15, 0, %0, c12, c0, 1"
>  
>  #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
>  #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
> diff --git a/arch/aarch32/include/asm/psci.h b/arch/aarch32/include/asm/psci.h
> new file mode 100644
> index 0000000..50c7c70
> --- /dev/null
> +++ b/arch/aarch32/include/asm/psci.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/aarch64/include/asm/psci.h
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __ASM_AARCH64_PSCI_H
> +#define __ASM_AARCH64_PSCI_H
> +
> +#include <cpu.h>
> +#include <stdbool.h>
> +
> +extern char psci_vectors[];
> +
> +static inline bool cpu_init_psci_arch(void)
> +{
> +	if (read_cpsr_mode() != PSR_MON)
> +		return false;
> +
> +	mcr(MVBAR, (unsigned long)psci_vectors);
> +	isb();
> +
> +	return true;
> +}
> +
> +#endif
> diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
> index e0d2972..cdc36b0 100644
> --- a/arch/aarch32/psci.S
> +++ b/arch/aarch32/psci.S
> @@ -15,7 +15,7 @@
>  
>  	.section .vectors
>  	.align 6
> -smc_vectors:
> +ASM_DATA(psci_vectors)
>  	b	err_exception			@ Reset
>  	b	err_exception			@ Undef
>  	b	handle_smc			@ SMC
> @@ -39,11 +39,5 @@ handle_smc:
>  	movs	pc, lr
>  
>  ASM_FUNC(start_el3)
> -	ldr	r0, =smc_vectors
> -	blx	setup_vector
> -	/* pass through */
> -
>  ASM_FUNC(start_no_el3)
> -	cpuid	r0, r1
> -	blx	find_logical_id
>  	b	psci_first_spin
> diff --git a/arch/aarch32/utils.S b/arch/aarch32/utils.S
> index 5809f48..58279aa 100644
> --- a/arch/aarch32/utils.S
> +++ b/arch/aarch32/utils.S
> @@ -35,12 +35,3 @@ ASM_FUNC(find_logical_id)
>  	bx	lr
>  3:	mov	r0, #MPIDR_INVALID
>  	bx	lr
> -
> -/*
> - * Setup EL3 vectors.
> - * r0: vector address
> - */
> -ASM_FUNC(setup_vector)
> -	mcr	p15, 0, r0, c12, c0, 1	@ MVBAR
> -	isb
> -	bx	lr
> diff --git a/arch/aarch64/include/asm/psci.h b/arch/aarch64/include/asm/psci.h
> new file mode 100644
> index 0000000..491e685
> --- /dev/null
> +++ b/arch/aarch64/include/asm/psci.h
> @@ -0,0 +1,28 @@
> +/*
> + * arch/aarch64/include/asm/psci.h
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __ASM_AARCH64_PSCI_H
> +#define __ASM_AARCH64_PSCI_H
> +
> +#include <cpu.h>
> +#include <stdbool.h>
> +
> +extern char psci_vectors[];
> +
> +static inline bool cpu_init_psci_arch(void)
> +{
> +	if (mrs(CurrentEL) != CURRENTEL_EL3)
> +		return false;
> +
> +	msr(VBAR_EL3, (unsigned long)psci_vectors);
> +	isb();
> +
> +	return true;
> +}
> +
> +#endif

Is there any particular reason that needs to live as a static inline in a
header file? Can't we have the prototype in, say include/boot.h, and then
have this in a proper C file, for instance arch/aarch<xx>/init.c?

The rest looks alright, though the change is somewhat hard to digest.

Cheers,
Andre

> diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> index 8bd224b..d6ca2eb 100644
> --- a/arch/aarch64/psci.S
> +++ b/arch/aarch64/psci.S
> @@ -19,7 +19,7 @@
>  	.section .vectors, "w"
>  
>  	.align 11
> -vector:
> +ASM_DATA(psci_vectors)
>  	// current EL, SP_EL0
>  	ventry	err_exception	// synchronous
>  	ventry	err_exception	// IRQ
> @@ -80,22 +80,5 @@ smc_exit:
>  	eret
>  
>  ASM_FUNC(start_el3)
> -	ldr	x0, =vector
> -	bl	setup_vector
> -
> -	/* only boot the primary cpu (entry 0 in the table) */
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	b	psci_first_spin
> -
> -/*
> - * This PSCI implementation requires EL3. Without EL3 we'll only boot the
> - * primary cpu, all others will be trapped in an infinite loop.
> - */
>  ASM_FUNC(start_no_el3)
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	cbz	x0, psci_first_spin
> -spin_dead:
> -	wfe
> -	b	spin_dead
> +	b	psci_first_spin
> diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
> index 1ea1c0b..764c532 100644
> --- a/arch/aarch64/spin.S
> +++ b/arch/aarch64/spin.S
> @@ -12,6 +12,9 @@
>  
>  	.text
>  
> +ASM_FUNC(cpu_init_bootmethod)
> +	ret
> +
>  ASM_FUNC(start_el3)
>  ASM_FUNC(start_no_el3)
>  	cpuid	x0, x1
> diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
> index 85c7f8a..32393cc 100644
> --- a/arch/aarch64/utils.S
> +++ b/arch/aarch64/utils.S
> @@ -32,12 +32,3 @@ ASM_FUNC(find_logical_id)
>  	ret
>  3:	mov	x0, #MPIDR_INVALID
>  	ret
> -
> -/*
> - * Setup EL3 vectors
> - * x0: vector address
> - */
> -ASM_FUNC(setup_vector)
> -	msr	VBAR_EL3, x0
> -	isb
> -	ret
> diff --git a/common/init.c b/common/init.c
> index fc74b9e..3c05ac3 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -6,6 +6,7 @@
>   * Use of this source code is governed by a BSD-style license that can be
>   * found in the LICENSE.txt file.
>   */
> +#include <boot.h>
>  #include <cpu.h>
>  #include <platform.h>
>  
> @@ -44,7 +45,9 @@ void announce_arch(void);
>  
>  void cpu_init_bootwrapper(void)
>  {
> -	if (this_cpu_logical_id() == 0) {
> +	unsigned int cpu = this_cpu_logical_id();
> +
> +	if (cpu == 0) {
>  		init_uart();
>  		announce_bootwrapper();
>  		announce_arch();
> @@ -52,4 +55,6 @@ void cpu_init_bootwrapper(void)
>  		print_string("\r\n");
>  		init_platform();
>  	}
> +
> +	cpu_init_bootmethod(cpu);
>  }
> diff --git a/common/psci.c b/common/psci.c
> index a0e8700..8af6870 100644
> --- a/common/psci.c
> +++ b/common/psci.c
> @@ -12,8 +12,11 @@
>  #include <bakery_lock.h>
>  #include <boot.h>
>  #include <cpu.h>
> +#include <platform.h>
>  #include <psci.h>
>  
> +#include <asm/psci.h>
> +
>  #ifndef CPU_IDS
>  #error "No MPIDRs provided"
>  #endif
> @@ -78,12 +81,25 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
>  	}
>  }
>  
> -void __noreturn psci_first_spin(unsigned int cpu)
> +void __noreturn psci_first_spin(void)
>  {
> -	if (cpu == MPIDR_INVALID)
> -		while (1);
> +	unsigned int cpu = this_cpu_logical_id();
>  
>  	first_spin(cpu, branch_table + cpu, PSCI_ADDR_INVALID);
>  
>  	unreachable();
>  }
> +
> +void cpu_init_bootmethod(unsigned int cpu)
> +{
> +	if (cpu_init_psci_arch())
> +		return;
> +
> +	if (cpu == 0) {
> +		print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
> +		return;
> +	}
> +
> +	while (1)
> +		wfe();
> +}
> diff --git a/include/boot.h b/include/boot.h
> index d75e013..10968f8 100644
> --- a/include/boot.h
> +++ b/include/boot.h
> @@ -16,4 +16,6 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
>  void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
>  			   unsigned long invalid_addr);
>  
> +void cpu_init_bootmethod(unsigned int cpu);
> +
>  #endif



From andre.przywara at arm.com  Mon Jan 17 09:43:13 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 17:43:13 +0000
Subject: [bootwrapper PATCH v2 13/13] Unify start_el3 & start_no_el3
In-Reply-To: <20220114105653.3003399-14-mark.rutland@arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-14-mark.rutland@arm.com>
Message-ID: <20220117174313.34e87664@donnerap.cambridge.arm.com>

On Fri, 14 Jan 2022 10:56:53 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> Now that the start_el3 and start_no_el3 labels point at the same place,
> unify them into a start_bootmethod label and update callers.

Nice one.

> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch32/boot.S | 5 ++---
>  arch/aarch32/psci.S | 3 +--
>  arch/aarch64/boot.S | 4 ++--
>  arch/aarch64/psci.S | 3 +--
>  arch/aarch64/spin.S | 3 +--
>  5 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 820957b..4d16c9c 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -51,7 +51,7 @@ ASM_FUNC(_start)
>  
>  	bl	cpu_init_bootwrapper
>  
> -	b	start_no_el3
> +	b	start_bootmethod
>  
>  _switch_monitor:
>  	adr	lr, _monitor
> @@ -69,8 +69,7 @@ _monitor:
>  
>  	bl	gic_secure_init
>  
> -	/* Initialise boot method */
> -	b	start_el3
> +	b	start_bootmethod
>  
>  err_invalid_id:
>  	b	.
> diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
> index cdc36b0..6613b6f 100644
> --- a/arch/aarch32/psci.S
> +++ b/arch/aarch32/psci.S
> @@ -38,6 +38,5 @@ handle_smc:
>  	pop	{r4 - r12, lr}
>  	movs	pc, lr
>  
> -ASM_FUNC(start_el3)
> -ASM_FUNC(start_no_el3)
> +ASM_FUNC(start_bootmethod)
>  	b	psci_first_spin
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index c0ec518..da5fa65 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -57,7 +57,7 @@ reset_at_el3:
>  
>  	bl	gic_secure_init
>  
> -	b	start_el3
> +	b	start_bootmethod
>  
>  	/*
>  	 * EL2 initialization
> @@ -97,7 +97,7 @@ reset_no_el3:
>  
>  	bl	cpu_init_bootwrapper
>  
> -	b	start_no_el3
> +	b	start_bootmethod
>  
>  err_invalid_id:
>  	b	.
> diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> index d6ca2eb..9709dbb 100644
> --- a/arch/aarch64/psci.S
> +++ b/arch/aarch64/psci.S
> @@ -79,6 +79,5 @@ smc_exit:
>  	ldp	x18, x19, [sp], #16
>  	eret
>  
> -ASM_FUNC(start_el3)
> -ASM_FUNC(start_no_el3)
> +ASM_FUNC(start_bootmethod)
>  	b	psci_first_spin
> diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
> index 764c532..375f732 100644
> --- a/arch/aarch64/spin.S
> +++ b/arch/aarch64/spin.S
> @@ -15,8 +15,7 @@
>  ASM_FUNC(cpu_init_bootmethod)
>  	ret
>  
> -ASM_FUNC(start_el3)
> -ASM_FUNC(start_no_el3)
> +ASM_FUNC(start_bootmethod)
>  	cpuid	x0, x1
>  	bl	find_logical_id
>  



From linux at armlinux.org.uk  Mon Jan 17 09:49:43 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 17:49:43 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <20220117153348.2513798-1-andre.przywara@arm.com>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
Message-ID: <YeWsN+/IFkOJCK/S@shell.armlinux.org.uk>

On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> Our GCC invocation does not provide many parameters, which lets the
> toolchain fill in its own default setup.
> In case of a native build or when using a full-featured cross-compiler,
> this probably means Linux userland, which is not what we want for a
> bare-metal application like boot-wrapper.
> 
> Tell the compiler to forget about those standard settings, and only use
> what we explicitly ask for. In particular that means to not use toolchain
> provided libraries, since they might pull in more code than we want, and
> might not run well in the boot-wrapper environment.
> 
> Disable the stack protector, as this adds code that relies on userland:
> "If a guard check fails, an error message is printed and the program
> exits." (from the gcc manpage).
> 
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> ---
> Hi,
> 
> compared to [PATCH v2 3/9] this drops the more contentious options (for
> now, at least), and focuses on what's really needed. Including
> -fno-stack-protector, as the need for this showed up in the cleanup series
> already.

There is history here. -ffreestanding has been tried before. See:

https://patchwork.kernel.org/project/linux-kbuild/patch/20200817220212.338670-5-ndesaulniers at google.com/

Have the issues in that thread been addressed?

If not, -ffreestanding does not belong in the top-level makefile.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From catalin.marinas at arm.com  Mon Jan 17 09:54:14 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Jan 2022 17:54:14 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YdgrjWVxRGRtnf5b@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com>
Message-ID: <YeWtRk0H30q38eM8@arm.com>

On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
> I think we can look at this from two angles:
> 
> 1. Ignoring MDWE, should whoever does the original mmap() also honour
>    PROT_BTI? We do this for static binaries but, for consistency, should
>    we extend it to dynamic executable?
> 
> 2. A 'simple' fix to allow MDWE together with BTI.

Thinking about it, (1) is not that different from the kernel setting
PROT_EXEC on the main executable when the dynamic loader could've done
it as well. There is a case for making this more consistent: whoever
does the mmap() should use the full attributes.

Question for the toolchain people: would the compiler ever generate
relocations in the main executable that the linker needs to resolve via
an mprotect(READ|WRITE) followed by mprotect(READ|EXEC)? If yes, we'd
better go for a proper MDWE implementation in the kernel.

-- 
Catalin


From krzysztof.adamski at nokia.com  Mon Jan 17 09:58:26 2022
From: krzysztof.adamski at nokia.com (Krzysztof Adamski)
Date: Mon, 17 Jan 2022 18:58:26 +0100
Subject: [PATCH] arm64: move efi_reboot to restart handler
In-Reply-To: <20220117131056.GC87485@C02TD0UTHF1T.local>
References: <YeVhtL2gCLkhTPdv@localhost.localdomain>
 <20220117131056.GC87485@C02TD0UTHF1T.local>
Message-ID: <YeWuQh6+OC02nbsg@localhost.localdomain>

Dnia Mon, Jan 17, 2022 at 01:10:56PM +0000, Mark Rutland napisa?(a):
>Hi,
>
>On Mon, Jan 17, 2022 at 01:31:48PM +0100, Krzysztof Adamski wrote:
>> On EFI enabled arm64 systems, efi_reboot was called before
>> do_kernel_restart, completely omitting the reset_handlers functionality.
>> By registering efi_reboot as part of the chain with slightly elevated
>> priority, we make it run before the default handler but still allow
>> plugging in other handlers.
>> Thanks to that, things like gpio_restart, restart handlers in
>> watchdog_core, mmc or mtds are working on those platforms.
>>
>> The priority 129 should be high enough as we will likely be the first
>> one to register on this prio so we will be called before others, like
>> PSCI handler.
>
>I apprecaiate that this is kinda nice for consistency, but if adds more
>lines and reduces certainty down to "likely", neither of which seem
>ideal.

Well, my choosing of the word "likely" might not be ideal. What I meant
is that it is unlikely that anybody would ever add another restart
handler with priority 129 in earlier code, as it would also have to be
done in arch setup.

We can, however, bump the priority to a larger value, of course. I just
wanted to use tha smallest sensible value. Choosing the right priority
is the hardest part of using reset_handlers mechanism, though. The
direct mapping of the previous code to the restart handlers would use
the maximal priority of 255, but this wouldn't make sense as the whole
point of using restart_handler is to be able to register something with
higer priority than default (in this case efi) reset mechanism.

>
>What do we gain by changing this? e.g. does this enable some further
>rework?
>
>Do we actually need to change this?

Well, it is not just nice, it is very useful. Without this change, the
whole mechanism of restart_handlers does not work on a whole class of
systems. We use this mechanism to inject our custom handler that should
run just before restart but this is also used by a handful of mainline
drivers that I mentioned in my commit message - none of them is gonna
work in EFI based ARM64 systems right now - this includes the MTD/MMC
drivers trying to do some work just before restart, gpio_restart driver
that is used in many systems to trigger some external events just before
restart, etc.

So, for everybody who uses restart_handlers mechanism, this change is
needed.

>
>>
>> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>
>> ---
>>  arch/arm64/kernel/process.c |  7 -------
>>  arch/arm64/kernel/setup.c   | 21 +++++++++++++++++++++
>>  2 files changed, 21 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
>> index 5369e649fa79..b86ef77bb0c8 100644
>> --- a/arch/arm64/kernel/process.c
>> +++ b/arch/arm64/kernel/process.c
>> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>>  	local_irq_disable();
>>  	smp_send_stop();
>>
>> -	/*
>> -	 * UpdateCapsule() depends on the system being reset via
>> -	 * ResetSystem().
>> -	 */
>> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
>> -		efi_reboot(reboot_mode, NULL);
>> -
>>  	/* Now call the architecture specific reboot code. */
>>  	do_kernel_restart(cmd);
>>
>> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
>> index f70573928f1b..5fa95980ba73 100644
>> --- a/arch/arm64/kernel/setup.c
>> +++ b/arch/arm64/kernel/setup.c
>> @@ -12,6 +12,7 @@
>>  #include <linux/stddef.h>
>>  #include <linux/ioport.h>
>>  #include <linux/delay.h>
>> +#include <linux/reboot.h>
>>  #include <linux/initrd.h>
>>  #include <linux/console.h>
>>  #include <linux/cache.h>
>> @@ -298,6 +299,24 @@ u64 cpu_logical_map(unsigned int cpu)
>>  	return __cpu_logical_map[cpu];
>>  }
>>
>> +static int efi_restart(struct notifier_block *nb, unsigned long action,
>> +		       void *data)
>> +{
>> +	/*
>> +	 * UpdateCapsule() depends on the system being reset via
>> +	 * ResetSystem().
>> +	 */
>> +	if (efi_enabled(EFI_RUNTIME_SERVICES))
>> +		efi_reboot(reboot_mode, NULL);
>> +
>> +	return NOTIFY_DONE;
>> +}
>> +
>> +static struct notifier_block efi_restart_nb = {
>> +	.notifier_call = efi_restart,
>> +	.priority = 129,
>> +};
>> +
>>  void __init __no_sanitize_address setup_arch(char **cmdline_p)
>>  {
>>  	setup_initial_init_mm(_stext, _etext, _edata, _end);
>> @@ -346,6 +365,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
>>
>>  	paging_init();
>>
>> +	register_restart_handler(&efi_restart_nb);
>
>If we're going to register this, it'd be nicer to register it
>conditionally in the EFI code when we probe EFI, rather than having the
>arch setup code unconditionally register a notifier that conditionally
>does something.
>

You might be right, I did a 1:1 translation of the code, so to say. I
will look at the alternative approach for registering.

Krzysztof


From linux at armlinux.org.uk  Mon Jan 17 10:04:54 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 17 Jan 2022 18:04:54 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <YeWsN+/IFkOJCK/S@shell.armlinux.org.uk>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
 <YeWsN+/IFkOJCK/S@shell.armlinux.org.uk>
Message-ID: <YeWvxtoZqpTNCOhb@shell.armlinux.org.uk>

On Mon, Jan 17, 2022 at 05:49:43PM +0000, Russell King (Oracle) wrote:
> On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> > Our GCC invocation does not provide many parameters, which lets the
> > toolchain fill in its own default setup.
> > In case of a native build or when using a full-featured cross-compiler,
> > this probably means Linux userland, which is not what we want for a
> > bare-metal application like boot-wrapper.
> > 
> > Tell the compiler to forget about those standard settings, and only use
> > what we explicitly ask for. In particular that means to not use toolchain
> > provided libraries, since they might pull in more code than we want, and
> > might not run well in the boot-wrapper environment.
> > 
> > Disable the stack protector, as this adds code that relies on userland:
> > "If a guard check fails, an error message is printed and the program
> > exits." (from the gcc manpage).
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> > Hi,
> > 
> > compared to [PATCH v2 3/9] this drops the more contentious options (for
> > now, at least), and focuses on what's really needed. Including
> > -fno-stack-protector, as the need for this showed up in the cleanup series
> > already.
> 
> There is history here. -ffreestanding has been tried before. See:
> 
> https://patchwork.kernel.org/project/linux-kbuild/patch/20200817220212.338670-5-ndesaulniers at google.com/
> 
> Have the issues in that thread been addressed?
> 
> If not, -ffreestanding does not belong in the top-level makefile.

Oh, this is not the kernel. Please make it clear as you're posting to
the linux-arm-kernel mailing list...

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mark.rutland at arm.com  Mon Jan 17 10:08:13 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Mon, 17 Jan 2022 18:08:13 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220117143104.28db5001@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-10-mark.rutland@arm.com>
 <20220117143104.28db5001@donnerap.cambridge.arm.com>
Message-ID: <20220117180813.GD94025@C02TD0UTHF1T.local>

On Mon, Jan 17, 2022 at 02:31:04PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:49 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > The majority of state that we initialize at EL3 is necessary for code at
> > lower ELs to function, but isnt' necessary for the boot-wrapper itself.
> > Given that, it would be better to write this in C where it can be
> > written mode clearly, and where it will be possible to add logging/debug
> > logic.
> 
> Ah, thanks, that looks much nicer and easier to read now, also is more
> robust, as keeping register values alive for more than a few assembly
> lines always scares me.
> 
> > This patch migrates the AArch64 EL3 initialization to C.
> > 
> > There should be no functional change as a result of this patch.
> 
> I compared the removed assembly code against to added C code, and also
> checked the register bits against the ARM ARM.
> Two (and a half) things stood out, see below:

Thanks for this! I've fixed those as noted below.

[...]

> > -#define HCR_EL2_RES1		(BIT(1))
> > +#define ZCR_EL3				s3_6_c1_c2_0
> > +#define ZCR_EL3_LEN			BITS(3, 1)
> 
> The (current) actual length field should be BITS(3, 0), no?

Yes, it should. I've corrected that to BITS(3, 0) now.

[...]

> > +void cpu_init_el3(void)
> > +{
> > +	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
> > +	unsigned long mdcr = 0;
> > +	unsigned long cptr = 0;
> > +
> > +	if (cpu_has_pauth())
> > +		scr |= SCR_EL3_APK | SCR_EL3_API;
> > +
> > +	if (mrs_field(ID_AA64ISAR0_EL1, TME))
> > +		scr |= SCR_EL3_TME;
> > +
> > +	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
> > +		scr |= SCR_EL3_FGTEN;
> > +
> > +	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
> > +		scr |= SCR_EL3_ECVEN;
> > +
> > +	if (mrs_field(ID_AA64PFR1_EL1, MTE))
> 
> The assembly code checked for >=2, which seems correct to me, as
> SCR_EL3_ATA is about MTE2?

Yes; I botched that when converting to C. SCR_EL3.ATA is RES0 in the
absence of MTE2. I've added `>= 2` to the condition to match that.

> > +		scr |= SCR_EL3_ATA;

[...]

> > +	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
> > +		cptr |= CPTR_EL3_EZ;
> > +		msr(CPTR_EL3, cptr);
> > +		isb();
> > +		msr(ZCR_EL3, ZCR_EL3_LEN);
> 
> So when comparing this to the other uses of XXX_EL3_YYY, they typically
> describe a mask, but here we seems to abuse this as a value?

True; I'll add a separate defintion for the value.

> And apart from bit 0 missing from it (as noted above), the existing
> code writes 0x1ff into that register, presumable to cover future
> vector length extensions beyond 2048 bits (which those RAZ/WI fields
> in bits[8:4] seem to suggest).

Hmm... I went and found the SVE supplement and I can't see any rationale
for what SW *should* do, nor can I find a description of the register
(that seems to have been factored into some XML files I can't convince
anything to load on my machine).

> So shall we define ZCR_EL3_MAX_VEC_LEN to 0x1ff above, and then use that?
> Or ignore the crystal ball, and just stick with 2048 bits, by writing 0xf?

TBH, I'm not sure. In the absence of some documented guidance I'd prefer
to go with 0xf, but given we already use 0x1ff, I want to dig into this
a bit more.

Thanks,
Mark.


From adhemerval.zanella at linaro.org  Mon Jan 17 10:16:39 2022
From: adhemerval.zanella at linaro.org (Adhemerval Zanella)
Date: Mon, 17 Jan 2022 15:16:39 -0300
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YeWtRk0H30q38eM8@arm.com>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com> <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com> <YdcxUZ06f60UQMKM@arm.com>
 <Ydc+AuagOD9GSooP@sirena.org.uk> <YdgrjWVxRGRtnf5b@arm.com>
 <YeWtRk0H30q38eM8@arm.com>
Message-ID: <20ae043b-a013-068d-2d83-16e63f5b4989@linaro.org>



On 17/01/2022 14:54, Catalin Marinas via Libc-alpha wrote:
> On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
>> I think we can look at this from two angles:
>>
>> 1. Ignoring MDWE, should whoever does the original mmap() also honour
>>    PROT_BTI? We do this for static binaries but, for consistency, should
>>    we extend it to dynamic executable?
>>
>> 2. A 'simple' fix to allow MDWE together with BTI.
> 
> Thinking about it, (1) is not that different from the kernel setting
> PROT_EXEC on the main executable when the dynamic loader could've done
> it as well. There is a case for making this more consistent: whoever
> does the mmap() should use the full attributes.
> 
> Question for the toolchain people: would the compiler ever generate
> relocations in the main executable that the linker needs to resolve via
> an mprotect(READ|WRITE) followed by mprotect(READ|EXEC)? If yes, we'd
> better go for a proper MDWE implementation in the kernel.
> 

Yes, text relocations.  However these are deprecated (some libcs even do
not support it) and have a lot of drawbacks.


From pali at kernel.org  Mon Jan 17 10:20:06 2022
From: pali at kernel.org (=?UTF-8?q?Pali=20Roh=C3=A1r?=)
Date: Mon, 17 Jan 2022 19:20:06 +0100
Subject: [PATCH] arm64: dts: armada-3720-turris-mox: Add missing ethernet0
 alias
Message-ID: <20220117182006.31412-1-pali@kernel.org>

U-Boot uses ethernet* aliases for setting MAC addresses. Therefore define
also alias for ethernet0.

Fixes: 7109d817db2e ("arm64: dts: marvell: add DTS for Turris Mox")
Signed-off-by: Pali Roh?r <pali at kernel.org>
---
 arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
index 23e1b07c060a..6581092c2c90 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
@@ -18,6 +18,7 @@
 
 	aliases {
 		spi0 = &spi0;
+		ethernet0 = &eth0;
 		ethernet1 = &eth1;
 		mmc0 = &sdhci0;
 		mmc1 = &sdhci1;
-- 
2.20.1



From andre.przywara at arm.com  Mon Jan 17 10:25:10 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 18:25:10 +0000
Subject: [PATCH v3] Makefile: Tell compiler to generate bare-metal code
In-Reply-To: <YeWsN+/IFkOJCK/S@shell.armlinux.org.uk>
References: <20220117153348.2513798-1-andre.przywara@arm.com>
 <YeWsN+/IFkOJCK/S@shell.armlinux.org.uk>
Message-ID: <20220117182510.61b987d2@donnerap.cambridge.arm.com>

On Mon, 17 Jan 2022 17:49:43 +0000
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:

Hi Russell,

> On Mon, Jan 17, 2022 at 03:33:48PM +0000, Andre Przywara wrote:
> > Our GCC invocation does not provide many parameters, which lets the
> > toolchain fill in its own default setup.
> > In case of a native build or when using a full-featured cross-compiler,
> > this probably means Linux userland, which is not what we want for a
> > bare-metal application like boot-wrapper.
> > 
> > Tell the compiler to forget about those standard settings, and only use
> > what we explicitly ask for. In particular that means to not use toolchain
> > provided libraries, since they might pull in more code than we want, and
> > might not run well in the boot-wrapper environment.
> > 
> > Disable the stack protector, as this adds code that relies on userland:
> > "If a guard check fails, an error message is printed and the program
> > exits." (from the gcc manpage).
> > 
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > ---
> > Hi,
> > 
> > compared to [PATCH v2 3/9] this drops the more contentious options (for
> > now, at least), and focuses on what's really needed. Including
> > -fno-stack-protector, as the need for this showed up in the cleanup series
> > already.  
> 
> There is history here. -ffreestanding has been tried before. See:
> 
> https://patchwork.kernel.org/project/linux-kbuild/patch/20200817220212.338670-5-ndesaulniers at google.com/

Thanks for the link, interesting insight.

> Have the issues in that thread been addressed?

My apologies, I just see that I accidentally dropped the "boot-wrapper"
part from the subject line. So this is not a Linux patch, we just use the
mailing list for boot-wrapper discussion as well.
As the boot-wrapper is a really minimal and small code base, I don't think
we bother too much about lost optimisation opportunities, instead want to
become more robust. At the moment we really don't use any options telling
the compiler to not use the standard library (which caused issues
already), so we'd like to play safe here.

Thanks,
Andre

> If not, -ffreestanding does not belong in the top-level makefile.


From mathieu.poirier at linaro.org  Mon Jan 17 10:25:51 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 17 Jan 2022 11:25:51 -0700
Subject: [PATCH] remoteproc: imx_rproc: validate resource table
In-Reply-To: <20220111033333.403448-2-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-2-peng.fan@oss.nxp.com>
Message-ID: <20220117182551.GC1119324@p14s>

Good morning,

On Tue, Jan 11, 2022 at 11:33:23AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Currently NXP use one device tree to support all NXP released Cortex-M
> demos. There is one simple demo that not need to communicate with
> Linux, thus it will not update the resource table. So there maybe
> garbage data in it. In such case, Linux should directly ignore it.
> 
> It is hard to decide what data is garbage data, NXP released SDK use
> ver(1), reserved(0) in a valid resource table. But in case others
> use different value, so here use 0xff as a max value for ver and num.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 0bd24c937a73..75fde16f80a4 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -490,11 +490,19 @@ static int imx_rproc_attach(struct rproc *rproc)
>  static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>  {
>  	struct imx_rproc *priv = rproc->priv;
> +	struct resource_table *table;
>  
>  	/* The resource table has already been mapped in imx_rproc_addr_init */
>  	if (!priv->rsc_table)
>  		return NULL;
>  
> +	table = priv->rsc_table;
> +	/* Gabage data check */
> +	if (table->ver >= 0xff || table->num >= 0xff || table->reserved[0] || table->reserved[1]) {
> +		dev_err(priv->dev, "Ignore invalid rsc table\n");
> +		return NULL;
> +	}
> +

This seems like the wrong fix to me.  Either use different DTs or update the
resource table for all demos - efficiency should not be a problem since they are
demos.  With the above it is only a matter of time before the pattern
associated with valid resource tables changes, leading to more hacks that will be
impossible to maintain over time.

Thanks,
Mathieu

>  	*table_sz = SZ_1K;
>  	return (struct resource_table *)priv->rsc_table;
>  }
> -- 
> 2.25.1
> 


From pgwipeout at gmail.com  Mon Jan 17 10:26:27 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Mon, 17 Jan 2022 13:26:27 -0500
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <trinity-5a2f356e-2777-4624-b921-f8f56ce282c7-1642420742957@3c-app-gmx-bap64>
References: <20220116124911.65203-1-linux@fw-web.de>
 <20220116124911.65203-2-linux@fw-web.de>
 <8285bea7-559c-5834-78c7-5a062b7d8269@gmail.com>
 <trinity-5a2f356e-2777-4624-b921-f8f56ce282c7-1642420742957@3c-app-gmx-bap64>
Message-ID: <CAMdYzYrNQCcOiLf=jUGtCTM44SU8bUpBBOac6_SGJtqX+hvUuA@mail.gmail.com>

On Mon, Jan 17, 2022 at 6:59 AM Frank Wunderlich
<frank-w at public-files.de> wrote:
>
> Hi
>
> > Gesendet: Montag, 17. Januar 2022 um 11:47 Uhr
> > Von: "Johan Jonker" <jbx6244 at gmail.com>
> > Hi Frank,
> >
> > Despite that the DT is hosted in the kernel tree
> > DT and mainline kernel driver support are 2 separate things.
> > PCLK_XPCS might be in use elsewhere.
> >
> > Given the link below pclk_xpcs is only needed for rk3568.
> > Maybe gmac1 should have a PCLK_XPCS too, because one can select between
> > them.
> >
> > ethernet: stmicro: stmmac: Add SGMII/QSGMII support for RK3568
> > https://github.com/rockchip-linux/kernel/commit/1fc7cbfe9e227c700c692f1de3137914b3ea6ca6
> >
> > The original dtsi did have PCLK_XPCS in both nodes.
> > https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L2121
> > https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L1492
> >
> > Maybe fix the document or leave it as it is for now as long the driver
> > isn't updated and someone has tested it.
> > That's up to the DT maintainer.
> >
> > Johan
>
> as far as i understand, the PCLK_XPCS is part of the naneng combphy, which is not yet available in mainline.
> Naneng driver needs some changes and imho this should be part of it (including change documentation). That also makes it clear why this clock is added.
> But leaving an unused property with sideeffects is imho no good choice.
>
> So this was the easiest way to fix the dtbs_check. Else i got no usable result for it. Maybe adding it to Documentation is also easy, but have not yet looked into it as it currently unused from my POV.
>
> But i leave it as decision for Maintainer to drop this patch as it is not needed for my Board DTS.

As both the current submission of the combophy driver and the gmac
driver do not support xpcs, I elected to remove the clock vice adding
documentation for something which is not currently supported.
This is especially true as it only leaked through for the gmac0 port,
the gmac1 port is modeled to the current support level.

Once xpcs support is introduced, the clock can be added to the
documentation and both controllers as part of the same patch series.

Do you concur, Heiko?

>
> > ===
> >
> > XPCS is also part of PD_PIPE.
> > See Rockchip RK3568 TRM Part1 V1.0-20210111.pdf page 475.
> > Please advise if the power-domain at RK3568_PD_PIPE does need a PCLK_XPCS
> > fix or is PCLK_PIPE enough in combination with a PHY driver?
> >
> > PD_PIPE:
> >
> > BIU_PIPE
> > USB3OTG
> > PCIE20
> > PCIE30
> > SATA
> > XPCS
> >
> >
> >       power-domain at RK3568_PD_PIPE {
> >               reg = <RK3568_PD_PIPE>;
> >               clocks = <&cru PCLK_PIPE>;
> >               pm_qos = <&qos_pcie2x1>,
> >                        <&qos_pcie3x1>,
> >                        <&qos_pcie3x2>,
> >                        <&qos_sata0>,
> >                        <&qos_sata1>,
> >                        <&qos_sata2>,
> >                        <&qos_usb3_0>,
> >                        <&qos_usb3_1>;
> >               #power-domain-cells = <0>;
> >       };
>
> PD_PIPE is imho also part of Naneng. But more for usage as USB3/SATA/... phy. This is not part of Mainline too.
>
> But thanks for pointing.
>
> regards Frank


From andre.przywara at arm.com  Mon Jan 17 10:31:17 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Mon, 17 Jan 2022 18:31:17 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220117180813.GD94025@C02TD0UTHF1T.local>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-10-mark.rutland@arm.com>
 <20220117143104.28db5001@donnerap.cambridge.arm.com>
 <20220117180813.GD94025@C02TD0UTHF1T.local>
Message-ID: <20220117183117.7f29dc66@donnerap.cambridge.arm.com>

On Mon, 17 Jan 2022 18:08:13 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> On Mon, Jan 17, 2022 at 02:31:04PM +0000, Andre Przywara wrote:
> > On Fri, 14 Jan 2022 10:56:49 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi Mark,
> >   
> > > The majority of state that we initialize at EL3 is necessary for code at
> > > lower ELs to function, but isnt' necessary for the boot-wrapper itself.
> > > Given that, it would be better to write this in C where it can be
> > > written mode clearly, and where it will be possible to add logging/debug
> > > logic.  
> > 
> > Ah, thanks, that looks much nicer and easier to read now, also is more
> > robust, as keeping register values alive for more than a few assembly
> > lines always scares me.
> >   
> > > This patch migrates the AArch64 EL3 initialization to C.
> > > 
> > > There should be no functional change as a result of this patch.  
> > 
> > I compared the removed assembly code against to added C code, and also
> > checked the register bits against the ARM ARM.
> > Two (and a half) things stood out, see below:  
> 
> Thanks for this! I've fixed those as noted below.
> 
> [...]
> 
> > > -#define HCR_EL2_RES1		(BIT(1))
> > > +#define ZCR_EL3				s3_6_c1_c2_0
> > > +#define ZCR_EL3_LEN			BITS(3, 1)  
> > 
> > The (current) actual length field should be BITS(3, 0), no?  
> 
> Yes, it should. I've corrected that to BITS(3, 0) now.
> 
> [...]
> 
> > > +void cpu_init_el3(void)
> > > +{
> > > +	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
> > > +	unsigned long mdcr = 0;
> > > +	unsigned long cptr = 0;
> > > +
> > > +	if (cpu_has_pauth())
> > > +		scr |= SCR_EL3_APK | SCR_EL3_API;
> > > +
> > > +	if (mrs_field(ID_AA64ISAR0_EL1, TME))
> > > +		scr |= SCR_EL3_TME;
> > > +
> > > +	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
> > > +		scr |= SCR_EL3_FGTEN;
> > > +
> > > +	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
> > > +		scr |= SCR_EL3_ECVEN;
> > > +
> > > +	if (mrs_field(ID_AA64PFR1_EL1, MTE))  
> > 
> > The assembly code checked for >=2, which seems correct to me, as
> > SCR_EL3_ATA is about MTE2?  
> 
> Yes; I botched that when converting to C. SCR_EL3.ATA is RES0 in the
> absence of MTE2. I've added `>= 2` to the condition to match that.
> 
> > > +		scr |= SCR_EL3_ATA;  
> 
> [...]
> 
> > > +	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
> > > +		cptr |= CPTR_EL3_EZ;
> > > +		msr(CPTR_EL3, cptr);
> > > +		isb();
> > > +		msr(ZCR_EL3, ZCR_EL3_LEN);  
> > 
> > So when comparing this to the other uses of XXX_EL3_YYY, they typically
> > describe a mask, but here we seems to abuse this as a value?  
> 
> True; I'll add a separate defintion for the value.
> 
> > And apart from bit 0 missing from it (as noted above), the existing
> > code writes 0x1ff into that register, presumable to cover future
> > vector length extensions beyond 2048 bits (which those RAZ/WI fields
> > in bits[8:4] seem to suggest).  
> 
> Hmm... I went and found the SVE supplement and I can't see any rationale
> for what SW *should* do, nor can I find a description of the register
> (that seems to have been factored into some XML files I can't convince
> anything to load on my machine).
> 
> > So shall we define ZCR_EL3_MAX_VEC_LEN to 0x1ff above, and then use that?
> > Or ignore the crystal ball, and just stick with 2048 bits, by writing 0xf?  
> 
> TBH, I'm not sure. In the absence of some documented guidance I'd prefer
> to go with 0xf, but given we already use 0x1ff, I want to dig into this
> a bit more.

My impression was that this "[8:4] = RAZ/WI" compared to the "[63:9] =
RES0" fields suggests this is for a potential extension, but I guess there
would be more changes needed if SVE ever goes beyond 2048. So chances are
high we need to adopt the code then anyway, and fixing the number then is
the least of our problems.

So I feel we should stick to what's explicitly documented, and put 0xf in
there.

Cheers,
Andre


From catalin.marinas at arm.com  Mon Jan 17 10:48:10 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 17 Jan 2022 18:48:10 +0000
Subject: [RFCv1 4/4] perf: arm_spe: Dynamically switch PID tracing to
 contextidr
In-Reply-To: <20211210075918.GD622826@leoy-ThinkPad-X240s>
References: <20211021134530.206216-1-leo.yan@linaro.org>
 <20211021134530.206216-5-leo.yan@linaro.org>
 <202110210848.35971643C6@keescook>
 <20211101152835.GB375622@leoy-ThinkPad-X240s>
 <YapEUlcyDZ6TuE6n@arm.com>
 <20211205135103.GA42658@leoy-ThinkPad-X240s>
 <Ya9J8HnMWxBy3MJv@arm.com>
 <20211207123118.GA255238@leoy-ThinkPad-X240s>
 <YbDrhQLeBdn0wqKT@arm.com>
 <20211210075918.GD622826@leoy-ThinkPad-X240s>
Message-ID: <YeW56uyxJ42oEn8L@arm.com>

Hi Leo,

(sorry for the delay, holidays, merging window)

On Fri, Dec 10, 2021 at 03:59:18PM +0800, Leo Yan wrote:
> On Wed, Dec 08, 2021 at 05:29:41PM +0000, Catalin Marinas wrote:
> > On Tue, Dec 07, 2021 at 08:31:18PM +0800, Leo Yan wrote:
> > > On Tue, Dec 07, 2021 at 11:48:00AM +0000, Catalin Marinas wrote:
> > > > On Sun, Dec 05, 2021 at 09:51:03PM +0800, Leo Yan wrote:
> > > > > On Fri, Dec 03, 2021 at 04:22:42PM +0000, Catalin Marinas wrote:
> > > > > > What's the cost of always enabling CONFIG_PID_IN_CONTEXTIDR? If it's
> > > > > > negligible, I'd not bother at all with any of the enabling/disabling.
> > > > > 
> > > > > Yes, I compared performance for PID tracing with always enabling and
> > > > > disabling CONFIG_PID_IN_CONTEXTIDR, and also compared with using
> > > > > static key for enabling/disabling PID tracing.  The result shows the
> > > > > cost is negligible based on the benchmark 'perf bench sched'.
> > > > > 
> > > > > Please see the detailed data in below link (note the testing results
> > > > > came from my Juno board):
> > > > > https://lore.kernel.org/lkml/20211021134530.206216-1-leo.yan at linaro.org/
> > > > 
> > > > The table wasn't entirely clear to me. So the dis/enb benchmarks are
> > > > without this patchset applied.
> > > 
> > > Yes, dis/enb metrics don't apply this patchset.
> > > 
> > > > There seems to be a minor drop but it's
> > > > probably noise. Anyway, do we need this patchset or we just make
> > > > CONFIG_PID_IN_CONTEXTIDR default to y?
> > > 
> > > Good point.  I remembered before we had discussed for making
> > > CONFIG_PID_IN_CONTEXTIDR to 'y', but this approach is not always valid,
> > > especially when the profiling process runs in non-root PID namespace,
> > > in this case, hardware tracing data (e.g. Arm SPE or CoreSight) cannot
> > > trust the PID values from tracing since the PID conflicts between
> > > different PID namespaces.
> > > 
> > > So this patchset is to add the fundamental mechanism for dynamically
> > > enabling and disable PID tracing into CONTEXTIDR.  Based on it, we can
> > > use helpers to dynamically enable PID tracing _only_ when process runs
> > > in root PID namespace.
> > 
> > I don't think your approach fully works. Let's say you are tracing two
> > processes, one in the root PID namespace, the other not. Since the
> > former enables PID in CONTEXTIDR, you automatically get some PID in
> > CONTEXTIDR for the latter whether you requested it explicitly or not.
> 
> The key point is kernel always sets a PID number from the root PID
> namespace into the system register CONTEXTIDR.

So earlier you mentioned that CONFIG_PID_IN_CONTEXTIDR=y is not always
right since a profiled task may run in a non-root PID namespace. But
this series introduces a single knob to turn on PID in CONTEXTIDR for
all CPUs, irrespective of whether they run a task in the root PID
namespace or not. The CPU running a task in the root ns may call
contextidr_enable() but the other CPUs may run tasks in non-root ns.

IIUC, with this patch, to avoid the root ns PID for a non-root ns task,
the SPE driver only sets the SYS_PMSCR_EL1_CX_SHIFT bit for the root ns
tasks. So, in this case, for a non-root ns task, does it matter that
CONTEXTIDR always contain the root ns PID? If it matters, see above why
a single knob is already doing this.

> Let's see a case:
> 
>   # unshare --fork --pid perf record -e cs_etm// -m 64K,64K -a -o perf_test.data -- ./multi_threads_test
> 
> In this case, with command "unshare --fork --pid", perf tool and the
> profiled program multi_threads_test run in the created PID namespace.
> We can see the dumped PID values:
> 
>    <idle>-0       [000] d..2.   331.751681: __switch_to: contextidr_thread_switch: task perf-exec pid 840 ns_pid 2
>    <idle>-0       [002] d..2.   331.755930: __switch_to: contextidr_thread_switch: task multi_threads_t pid 842 ns_pid 4
>    <idle>-0       [003] d..2.   331.755993: __switch_to: contextidr_thread_switch: task multi_threads_t pid 843 ns_pid 5
>   sugov:0-129     [005] d..2.   332.323469: __switch_to: contextidr_thread_switch: task perf pid 841 ns_pid 3
> 
> We can see processes have two different PIDs values, say task
> 'perf-exec', 840 is its PID number from the root PID namespace, and 2
> is its PID from the active namespace the task is belonging to.
> 
> But the register CONTEXTIDR is _only_ used to trace PIDs from the root
> PID namespace and ignores PID values from any other PID namespace.

Would it help if we used task_pid_nr_ns() instead for setting
CONTEXTIDR?

> Come back to your question, if there have two tracing sessions, one
> session runs in the root PID namespace, and another runs in the
> non-root PID namespace.  Since we can gather the PIDs in the root namespace,
> the session in the root PID namespace can work perfectly, and we can
> ensure the PID infos matching well between kernel's PID tracing and user
> space tool (note: perf needs gather process info with process' pid/tid for
> post parsing).
> 
> For the later session in non-root PID name space, we doesn't capture
> any PID tracing data.  This results in the profiled result doesn't
> contain any PID info, although it's painful that the PID info is
> incomplete but we don't deliver any wrong info for users studying
> profiling result and PID is always '-1'.

So what's actually disabling the capture of PID tracing data? Is it the
PMSCR_EL1.CX bit being 0?

> I think the purpose for this patchset is to allow us to dynamically
> enable PID tracing when the tracing session runs in root namespace.

But it doesn't do this with a single global knob for all CPUs. You only
need the SPE patch together with the CONTEXTIDR config set to y.

> Alternatively, if you accept to always set PID to CONTEXTIDR in
> contextidr_thread_switch(), it would be fine for me and we can only
> need to control PID packets in SPE and CoreSight drivers.

Well, we have the config option and infrastructure already, it's up to
Linux distros to turn it on. It doesn't necessarily need to be in
defconfig.

Now, if we removed the CONTEXTIDR setting altogether, is there a way for
perf tools to coordinate the traces with the scheduling events? This
would be a simpler approach from the kernel perspective (i.e. no work).
Alternatively, could we move the CONTEXTIDR setting to a perf driver.
I'm not too familiar with perf but I guess we could add some scheduling
event hooks.

-- 
Catalin


From hjl.tools at gmail.com  Mon Jan 17 11:01:25 2022
From: hjl.tools at gmail.com (H.J. Lu)
Date: Mon, 17 Jan 2022 11:01:25 -0800
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <20ae043b-a013-068d-2d83-16e63f5b4989@linaro.org>
References: <20211115152714.3205552-1-broonie@kernel.org>
 <YbD4LKiaxG2R0XxN@arm.com>
 <20211209111048.GM3294453@arm.com> <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com> <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com> <YdcxUZ06f60UQMKM@arm.com>
 <Ydc+AuagOD9GSooP@sirena.org.uk> <YdgrjWVxRGRtnf5b@arm.com>
 <YeWtRk0H30q38eM8@arm.com> <20ae043b-a013-068d-2d83-16e63f5b4989@linaro.org>
Message-ID: <CAMe9rOo5zWO1BwZGhqGdWuCjsq86YUo4ptqXkFVNSwXbU+ZS-Q@mail.gmail.com>

On Mon, Jan 17, 2022 at 10:17 AM Adhemerval Zanella via Libc-alpha
<libc-alpha at sourceware.org> wrote:
>
>
>
> On 17/01/2022 14:54, Catalin Marinas via Libc-alpha wrote:
> > On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
> >> I think we can look at this from two angles:
> >>
> >> 1. Ignoring MDWE, should whoever does the original mmap() also honour
> >>    PROT_BTI? We do this for static binaries but, for consistency, should
> >>    we extend it to dynamic executable?
> >>
> >> 2. A 'simple' fix to allow MDWE together with BTI.
> >
> > Thinking about it, (1) is not that different from the kernel setting
> > PROT_EXEC on the main executable when the dynamic loader could've done
> > it as well. There is a case for making this more consistent: whoever
> > does the mmap() should use the full attributes.
> >
> > Question for the toolchain people: would the compiler ever generate
> > relocations in the main executable that the linker needs to resolve via
> > an mprotect(READ|WRITE) followed by mprotect(READ|EXEC)? If yes, we'd
> > better go for a proper MDWE implementation in the kernel.
> >
>
> Yes, text relocations.  However these are deprecated (some libcs even do
> not support it) and have a lot of drawbacks.

We are taking a different approach for CET enabling.   CET will be
changed to be enabled from user space:

https://gitlab.com/x86-glibc/glibc/-/tree/users/hjl/cet/enable

and the CET kernel no longer enables CET automatically:

https://github.com/hjl-tools/linux/tree/hjl/cet%2F5.16.0-v4

-- 
H.J.


From semen.protsenko at linaro.org  Mon Jan 17 11:18:43 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 17 Jan 2022 21:18:43 +0200
Subject: [PATCH AUTOSEL 5.16 02/52] clk: samsung: exynos850: Register
 clocks early
In-Reply-To: <b75a0bc9-0423-83cc-11e1-d5e08952cc93@canonical.com>
References: <20220117165853.1470420-1-sashal@kernel.org>
 <20220117165853.1470420-2-sashal@kernel.org>
 <b75a0bc9-0423-83cc-11e1-d5e08952cc93@canonical.com>
Message-ID: <CAPLW+4mPnktJTBeokhbmSGTZTqOa3-rkpThYHZ-Y0=_40bbLtA@mail.gmail.com>

On Mon, 17 Jan 2022 at 19:11, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 17/01/2022 17:58, Sasha Levin wrote:
> > From: Sam Protsenko <semen.protsenko at linaro.org>
> >
> > [ Upstream commit bcda841f9bf2cddcf2f000cba96f2e27f6f2bdbf ]
> >
> > Some clocks must be registered before init calls. For example MCT clock
> > (from CMU_PERI) is needed for MCT timer driver, which is registered
> > with TIMER_OF_DECLARE(). By the time we get to core_initcall() used for
> > clk-exynos850 platform driver init, it's already too late. Inability to
> > get "mct" clock in MCT driver leads to kernel panic, as functions
> > registered with *_OF_DECLARE() can't do deferred calls. MCT timer driver
> > can't be fixed either, as it's acting as a clock source and it's
> > essential to register it in start_kernel() -> time_init().
> >
> > Let's register CMU_PERI clocks early, using CLK_OF_DECLARE(). CMU_TOP
> > generates clocks needed for CMU_PERI, but it's already registered early.
> >
> > While at it, let's cleanup the code a bit, by extracting everything
> > related to CMU initialization and registration to the separate function.
> >
> > Similar issue was discussed at [1] and addressed in commit 1f7db7bbf031
> > ("clk: renesas: cpg-mssr: Add early clock support"), as well as in
> > drivers/clk/mediatek/clk-mt2712.c.
> >
> > [1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/20180829132954.64862-2-chris.brandt at renesas.com/
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > Link: https://lore.kernel.org/r/20211122144206.23134-1-semen.protsenko at linaro.org
> > Signed-off-by: Sasha Levin <sashal at kernel.org>
> > ---
> >  drivers/clk/samsung/clk-exynos850.c | 70 ++++++++++++++++++++---------
> >  1 file changed, 49 insertions(+), 21 deletions(-)
> >
>
> I propose to skip this one.
>
> Backporting it to v5.16 does not hurt but also does not bring any
> benefits for the upstream kernel users. There is no support for
> mentioned Exynos850 in v5.16.
>
> It could have only meaning for some downstream, out-of-tree kernels
> which apply Exynos850 support on top of v5.16, but then they can just
> take this patch as well.
>

Agreed. DTS patches will be merged only in v5.17, hopefully. Till that
time the whole clock driver is floating with no users. That's
historical thing -- I didn't have "Ack" to submit board dts at the
time, and SoC dts couldn't be applied without users (board dts). So I
focused on driver work, isolated. Not much sense to backport something
without having real users.

>
> Best regards,
> Krzysztof


From olof at lixom.net  Mon Jan 17 12:26:04 2022
From: olof at lixom.net (Olof Johansson)
Date: Mon, 17 Jan 2022 12:26:04 -0800
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <77bd8fa4-2b35-352c-da07-ef91fcbed454@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
 <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
 <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>
 <CACRpkdbhmJ91EW395C5F2WYjWJQdJ-SBHaDm7XnQsxMuyoMmLg@mail.gmail.com>
 <77bd8fa4-2b35-352c-da07-ef91fcbed454@canonical.com>
Message-ID: <CAOesGMg2eH1B94h+etPBDW3B1LMeHBytz0v2e0GfVRDv8gU0YA@mail.gmail.com>

On Sun, Jan 16, 2022 at 11:45 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 16/01/2022 22:38, Linus Walleij wrote:
> > On Sun, Jan 16, 2022 at 6:10 PM Krzysztof Kozlowski
> > <krzysztof.kozlowski at canonical.com> wrote:
> >
> >> Anyway DTS and dtschema will have to wait for one release, because they
> >> depend on samsung pinctrl driver change (patch #2).
> >
> > What about I put that (and maybe this schema) on an immutable
> > branch so you can pull the commit into your for-arm-soc branch and
> > put the DTS changes on top?
>
> That would be a solution if not a policy for arm-soc of keeping DTS
> separate. Arnd and Olof since some time are not happy when DTS branch
> receives any driver updates.
>
> Arnd, Olof,
> This is a set of dtschema conversion + DTS alignment with new schema:
> 1. Driver change necessary to accept new DTS (driver depends on node
> names and this has to change because of dtschema),
> 2. DTS commits depending on above, which convert node name to new format,
> 3. Finally dtschema requiring new naming of the GPIO nodes.
>
> If I got correctly, the policy of not mixing drivers and DTS requires
> that #2 above (DTS changes) will wait for one more release. During the
> time, if dtschema (#3 above) is applied, there will be new warnings
> about non-compliant DTS.
>
> Do you see any chance of merging driver + DTS + dtschema via same tree
> in same release?

Our general guidance to separate DTS and driver changes is to avoid
large entangled changes between the two, and to discourage a developer
mentality of "the implementation is the binding".

I think this is a good example of when it makes sense to bring in what
is a fairly small and clean driver change to deal with this. So the
right answer here is to stage such a stable branch and merge into both
arm-soc and the pinctrl subsystem trees as proposed.


-Olof


From olof at lixom.net  Mon Jan 17 12:41:11 2022
From: olof at lixom.net (Olof Johansson)
Date: Mon, 17 Jan 2022 12:41:11 -0800
Subject: [PATCH 13/23] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <9b98fd89-87b5-5026-fb0c-16bb956801ea@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122408epcas5p45053d1bf0acf2d8233a98b6c1abab6eb@epcas5p4.samsung.com>
 <20220113121143.22280-14-alim.akhtar@samsung.com>
 <53c17ddc-a049-72ed-7237-de23db7889da@canonical.com>
 <085801d80967$e4b8fe00$ae2afa00$@samsung.com>
 <5ab62673-8d46-ec1d-1c80-696421ab69ca@canonical.com>
 <00c901d80ba5$c9ae6ab0$5d0b4010$@samsung.com>
 <CAK8P3a31bCHNcNWrLX+QW+4RuK=DBpxLA_j5BFKxXxXKCT8PFQ@mail.gmail.com>
 <9b98fd89-87b5-5026-fb0c-16bb956801ea@canonical.com>
Message-ID: <CAOesGMi8EBFGGj7sQsPZfDh=AhpPCBYFazb9yRYdEVX=MO7tog@mail.gmail.com>

On Mon, Jan 17, 2022 at 7:00 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 17/01/2022 15:14, Arnd Bergmann wrote:
> > On Mon, Jan 17, 2022 at 2:26 PM Alim Akhtar <alim.akhtar at samsung.com> wrote:
> >>
> >>> I cannot judge how different this is from Exynos subarchitecture - looking at
> >>> patches it is not different - so I could understand a FSD sub-arch with only one
> >>> SoC.
> >>>
> >> I understand, it is a bit difficult to visualize it with the current patch set.
> >> As discuss on the other thread, FSD is different, more over the vendor is different, internal design is different.
> >
> > Is it based on another SoC design then? Most new SoCs are derived from
> > some other
> > one, so it makes sense to put it into the same family. E.g. the Apple
> > M1 takes bits from
> > both Exynos and PA-Semi SoCs but has more newly added components than
> > either one.

I think it's a misnomer to call SoCs like these "based on each other".
What often happens is that a manufacturer reuses IPs between designs
since they're there, they're available and they work and there's
little reason to redo it, etc.

For cases such as a vendor building a custom SoC for a specific
customer (which, from the looks of this patchset seems to be the case
-- this is not something I say with insider information :-), it makes
sense to reuse IP blocks in the same way. It's actually a competitive
benefit of the vendor to have silicon-proven IPs in this manner.

Does this mean that this custom-built product is a part of a product
family? I don't think that's the primary conclusion I would make --
it's more complex than that. And it also doesn't make all that much of
a difference whether it's considered a family member or not. I would
be very surprised if this SoC had a Samsung marketing name, since to
my knowledge it's not sold to any other customer.

If all we're arguing here about is a toplevel compatible and a Kconfig
variable, then I don't see a need to spend a whole lot of time on this
-- as long as it's not a change that ends up proliferating the whole
source tree. I.e. if you want to create a new sub-arch, make sure it
selects or depends on EXYNOS so you don't need to sprinkle a lot of
"EXYNOS" -> "EXYNOS || TESLA" edits in the tree (as per below in the
email).

Same with the DT bindings. Can you just augment to make the tesla
vendor prefix an allowed one for the exynos bindings where it makes
sense?  Toplevel board (and SoC) compats can of course still be
independent.

> It seems Apple M1 shares only few bits with SoC. I am aware of only UART
> driver as directly re-usable.
>
> >
> > I would argue that if this SoC shares the pinctrl, clock, spi, adc,
> > and timer implementation
>
> Plus: UART, watchdog, PWM, I2C, I2S, USB PHY, DWC3 USB (in Exynos
> flavor), UFS (also in Exynos-looking flavor), MFC (video codec), some
> similarities in DW PCIe, TMU (thermal). Looking at DTS there are
> differences but just few comparing to most of shared blocks.
>
> Additionally SoC BSP (and maybe SoC itself...) was actually developed or
> co-developed by Samsung, judging by copyrights in the BSP code. Even the
> original DTSI has:
>
>         TURBO TRAV SoC device tree source
>         Copyright (c) 2017 Samsung Electronics Co., Ltd.
>
>
> Tesla could still customize it a lot, but it is a strong hint that most
> of it came from Samsung LSI and shares with existing Samsung designs.
>
> Have in mind that recent Exynos chips are significantly different than
> early ARMv7 or ARMv8 designs and we still consider them part of Exynos
> family.
>
> > with Exynos, we should consider it part of the Exynos family,
> > regardless of what other
> > blocks may exist next to those.
>
> Yes. I don't see the benefit of keeping it outside of Exynos. It will
> sprinkle "depends on ARCH_EXYNOS || ARCH_FSD" all over (or depend on
> Exynos like you suggested).

Depend or select (but select is a slippery slope so might be better
avoided) seems like a pretty good option here to me.


-Olof


From olof at lixom.net  Mon Jan 17 12:53:48 2022
From: olof at lixom.net (Olof Johansson)
Date: Mon, 17 Jan 2022 12:53:48 -0800
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <20220116092325.GA30745@amd>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com> <20220116092325.GA30745@amd>
Message-ID: <CAOesGMhpw7+5Q3MDAFQTr8-sDFgVXOE=v6h8d8pbHiZn8=3h2g@mail.gmail.com>

On Sun, Jan 16, 2022 at 1:23 AM Pavel Machek <pavel at ucw.cz> wrote:
>
> Hi!
>
> > This patch set adds basic support for the Tesla Full Self-Driving (FSD)
> > SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> > as well as several IPs.
>
> I'm not thrilled by their naming. Intel does not produce "Intel
> Fastest in world SoC"

If you say so. :)

> , and this chip is not actually suitable for
> autonomous driving :-(.

And AMD's Infinity Fabric isn't.... infinite. Things have names.

That discussion seems off-topic for this patchset. It references a
marketing name used by the company, and as such it makes sense to be
able to cross-reference:
https://www.tesla.com/support/full-self-driving-computer

Tesla seems to have moved away from the initial "Hardware 3" naming
scheme, so using this naming seems as good as any.


-Olof


From heiko at sntech.de  Mon Jan 17 13:05:29 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Mon, 17 Jan 2022 22:05:29 +0100
Subject: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <CAMdYzYrNQCcOiLf=jUGtCTM44SU8bUpBBOac6_SGJtqX+hvUuA@mail.gmail.com>
References: <20220116124911.65203-1-linux@fw-web.de>
 <trinity-5a2f356e-2777-4624-b921-f8f56ce282c7-1642420742957@3c-app-gmx-bap64>
 <CAMdYzYrNQCcOiLf=jUGtCTM44SU8bUpBBOac6_SGJtqX+hvUuA@mail.gmail.com>
Message-ID: <236548630.RelmrRfzIS@diego>

Am Montag, 17. Januar 2022, 19:26:27 CET schrieb Peter Geis:
> On Mon, Jan 17, 2022 at 6:59 AM Frank Wunderlich
> <frank-w at public-files.de> wrote:
> >
> > Hi
> >
> > > Gesendet: Montag, 17. Januar 2022 um 11:47 Uhr
> > > Von: "Johan Jonker" <jbx6244 at gmail.com>
> > > Hi Frank,
> > >
> > > Despite that the DT is hosted in the kernel tree
> > > DT and mainline kernel driver support are 2 separate things.
> > > PCLK_XPCS might be in use elsewhere.
> > >
> > > Given the link below pclk_xpcs is only needed for rk3568.
> > > Maybe gmac1 should have a PCLK_XPCS too, because one can select between
> > > them.
> > >
> > > ethernet: stmicro: stmmac: Add SGMII/QSGMII support for RK3568
> > > https://github.com/rockchip-linux/kernel/commit/1fc7cbfe9e227c700c692f1de3137914b3ea6ca6
> > >
> > > The original dtsi did have PCLK_XPCS in both nodes.
> > > https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L2121
> > > https://github.com/rockchip-linux/kernel/blob/develop-4.19/arch/arm64/boot/dts/rockchip/rk3568.dtsi#L1492
> > >
> > > Maybe fix the document or leave it as it is for now as long the driver
> > > isn't updated and someone has tested it.
> > > That's up to the DT maintainer.
> > >
> > > Johan
> >
> > as far as i understand, the PCLK_XPCS is part of the naneng combphy, which is not yet available in mainline.
> > Naneng driver needs some changes and imho this should be part of it (including change documentation). That also makes it clear why this clock is added.
> > But leaving an unused property with sideeffects is imho no good choice.
> >
> > So this was the easiest way to fix the dtbs_check. Else i got no usable result for it. Maybe adding it to Documentation is also easy, but have not yet looked into it as it currently unused from my POV.
> >
> > But i leave it as decision for Maintainer to drop this patch as it is not needed for my Board DTS.
> 
> As both the current submission of the combophy driver and the gmac
> driver do not support xpcs, I elected to remove the clock vice adding
> documentation for something which is not currently supported.
> This is especially true as it only leaked through for the gmac0 port,
> the gmac1 port is modeled to the current support level.
> 
> Once xpcs support is introduced, the clock can be added to the
> documentation and both controllers as part of the same patch series.
> 
> Do you concur, Heiko?

Did you see my own reply from some hours ago?
>From looking at the documentation I got the impression that the
pclk_xpcs is related to the separate qsgmii_pcs in the memory map.

So yes, I fully agree to dropping this clock from here and then adding
them to whatever ip block really needs it.


Heiko


> > > ===
> > >
> > > XPCS is also part of PD_PIPE.
> > > See Rockchip RK3568 TRM Part1 V1.0-20210111.pdf page 475.
> > > Please advise if the power-domain at RK3568_PD_PIPE does need a PCLK_XPCS
> > > fix or is PCLK_PIPE enough in combination with a PHY driver?
> > >
> > > PD_PIPE:
> > >
> > > BIU_PIPE
> > > USB3OTG
> > > PCIE20
> > > PCIE30
> > > SATA
> > > XPCS
> > >
> > >
> > >       power-domain at RK3568_PD_PIPE {
> > >               reg = <RK3568_PD_PIPE>;
> > >               clocks = <&cru PCLK_PIPE>;
> > >               pm_qos = <&qos_pcie2x1>,
> > >                        <&qos_pcie3x1>,
> > >                        <&qos_pcie3x2>,
> > >                        <&qos_sata0>,
> > >                        <&qos_sata1>,
> > >                        <&qos_sata2>,
> > >                        <&qos_usb3_0>,
> > >                        <&qos_usb3_1>;
> > >               #power-domain-cells = <0>;
> > >       };
> >
> > PD_PIPE is imho also part of Naneng. But more for usage as USB3/SATA/... phy. This is not part of Mainline too.
> >
> > But thanks for pointing.
> >
> > regards Frank
> 






From jim.cromie at gmail.com  Mon Jan 17 14:33:33 2022
From: jim.cromie at gmail.com (jim.cromie at gmail.com)
Date: Mon, 17 Jan 2022 15:33:33 -0700
Subject: [PATCH v11 01/19] dyndbg: add _DPRINTK_FLAGS_ENABLED
In-Reply-To: <20220114115718.GB23983@axis.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
 <20220107052942.1349447-2-jim.cromie@gmail.com>
 <20220114115718.GB23983@axis.com>
Message-ID: <CAJfuBxw1scH7xS7-RfxZ369wVQ8umP+0MHqz1U_3cW-BLPsDkg@mail.gmail.com>

On Fri, Jan 14, 2022 at 4:57 AM Vincent Whitchurch
<vincent.whitchurch at axis.com> wrote:
>
> On Fri, Jan 07, 2022 at 06:29:24AM +0100, Jim Cromie wrote:
> >  #ifdef CONFIG_JUMP_LABEL
> > -                     if (dp->flags & _DPRINTK_FLAGS_PRINT) {
> > -                             if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
> > +                     if (dp->flags & _DPRINTK_FLAGS_ENABLED) {
> > +                             if (!(modifiers->flags & _DPRINTK_FLAGS_ENABLED))
> >                                       static_branch_disable(&dp->key.dd_key_true);
> > -                     } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
> > +                     } else if (modifiers->flags & _DPRINTK_FLAGS_ENABLED)
> >                               static_branch_enable(&dp->key.dd_key_true);
> >  #endif
> >                       dp->flags = newflags;
> > --
> > 2.33.1
> >
>
> I haven't tested it so I could be mistaken, but when
> _DPRINTK_FLAGS_ENABLED gets two flags in the next patch, it looks like
> this code still has the problem which I mentioned in
> https://lore.kernel.org/lkml/20211209150910.GA23668 at axis.com/?
>

Yes, thanks for noticing.  I missed that detail.
Apriori, I dont know why bit-and of bit-or'd flags doesnt cover it,
but I will take a careful look.

> | I noticed a bug inside the CONFIG_JUMP_LABEL handling (also present
> | in the last version I posted) which should be fixed as part of the
> | diff below (I've added a comment).
> | [...]
> |  #ifdef CONFIG_JUMP_LABEL
> | -                     if (dp->flags & _DPRINTK_FLAGS_PRINT) {
> | -                             if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
> | +                     if (dp->flags & _DPRINTK_FLAGS_ENABLE) {
> | +                             /*
> | +                              * The newflags check is to ensure that the
> | +                              * static branch doesn't get disabled in step
> | +                              * 3:
> | +                              *
> | +                              * (1) +pf
> | +                              * (2) +x
> | +                              * (3) -pf
> | +                              */
> | +                             if (!(modifiers->flags & _DPRINTK_FLAGS_ENABLE) &&
> | +                                 !(newflags & _DPRINTK_FLAGS_ENABLE)) {
> |                                       static_branch_disable(&dp->key.dd_key_true);
> | -                     } else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
> | +                             }
> | +                     } else if (modifiers->flags & _DPRINTK_FLAGS_ENABLE) {
> |                               static_branch_enable(&dp->key.dd_key_true);
> | +                     }
> |  #endif


From hugo at hugovil.com  Mon Jan 17 15:06:39 2022
From: hugo at hugovil.com (Hugo Villeneuve)
Date: Mon, 17 Jan 2022 18:06:39 -0500
Subject: [PATCH] arm64: dts: imx8mp-evk: add PCA6416 interrupt controller mode
Message-ID: <20220117230639.1257549-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve at dimonoff.com>

Add interrupt controller mode for the pca6416 on i.MX8MP EVK board's.

Signed-off-by: Hugo Villeneuve <hvilleneuve at dimonoff.com>
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 66437b659f3a..00e1e1342162 100755
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -526,6 +526,12 @@ pca6416: gpio at 20 {
 		reg = <0x20>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pca6416_int>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
 	};
 
 	codec: wm8960 at 1a {
@@ -1209,6 +1215,12 @@ pinctrl_csi_mclk: csi_mclk_grp {
 			MX8MP_IOMUXC_GPIO1_IO15__CCM_CLKO2	0x59
 		>;
 	};
+
+	pinctrl_pca6416_int: pca6416_int_grp {
+		fsl,pins = <
+			MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12	0x146 /* Input pull-up. */
+		>;
+	};
 };
 
 &vpu_g1 {
-- 
2.30.2



From pavel at ucw.cz  Mon Jan 17 15:10:52 2022
From: pavel at ucw.cz (Pavel Machek)
Date: Tue, 18 Jan 2022 00:10:52 +0100
Subject: [PATCH 00/23] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <CAOesGMhpw7+5Q3MDAFQTr8-sDFgVXOE=v6h8d8pbHiZn8=3h2g@mail.gmail.com>
References: <CGME20220113122302epcas5p1d45c0714fe286f8f91d0f28c3fad86e4@epcas5p1.samsung.com>
 <20220113121143.22280-1-alim.akhtar@samsung.com>
 <20220116092325.GA30745@amd>
 <CAOesGMhpw7+5Q3MDAFQTr8-sDFgVXOE=v6h8d8pbHiZn8=3h2g@mail.gmail.com>
Message-ID: <20220117231052.GC14035@duo.ucw.cz>

On Mon 2022-01-17 12:53:48, Olof Johansson wrote:
> On Sun, Jan 16, 2022 at 1:23 AM Pavel Machek <pavel at ucw.cz> wrote:
> >
> > Hi!
> >
> > > This patch set adds basic support for the Tesla Full Self-Driving (FSD)
> > > SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> > > as well as several IPs.
> >
> > I'm not thrilled by their naming. Intel does not produce "Intel
> > Fastest in world SoC"
> 
> If you say so. :)
> 
> > , and this chip is not actually suitable for
> > autonomous driving :-(.
> 
> And AMD's Infinity Fabric isn't.... infinite. Things have names.
> 
> That discussion seems off-topic for this patchset. It references a
> marketing name used by the company, and as such it makes sense to be
> able to cross-reference:
> https://www.tesla.com/support/full-self-driving-computer
> 
> Tesla seems to have moved away from the initial "Hardware 3" naming
> scheme, so using this naming seems as good as any.

I'd prefer to call it Tesla HW3. Even wikipedia has that name, no need
to do false advertising for Tesla, and we'll have good names for
HW2.5 and HW4 if it comes out. We normally use codenames, not
marketing names.

Best regards,
								Pavel
-- 
http://www.livejournal.com/~pavelmachek
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220118/5ca45f2f/attachment.sig>

From helgaas at kernel.org  Mon Jan 17 15:17:35 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 17 Jan 2022 17:17:35 -0600
Subject: [PATCH] pci: imx: disable reglator when imx6_pcie_probe fails
In-Reply-To: <20220117102137.3513439-1-xiaolei.wang@windriver.com>
Message-ID: <20220117231735.GA813924@bhelgaas>

On Mon, Jan 17, 2022 at 06:21:37PM +0800, Xiaolei Wang wrote:
> From: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>

I got two copies of this.  This one changed:

  - Signed-off-by: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
  + Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>

This looks like a good change.  You should also change the
"From: wrsadmin" line above because that is what "git am" uses in the
commit:

  commit 119fdfb8fb1b ("pci: imx: disable reglator when imx6_pcie_probe fails")
  Author: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
  Date:   Mon Jan 17 18:17:35 2022 +0800

Also, please run "git log --oneline drivers/pci/controller/dwc/pci-imx6.c"
and make your subject line match in capitalization and style.

Also, fix the "s/reglator/regulator" typo in subject and below and add
"()" after the imx6_pcie_probe() function name.

If you include a calltrace, remove timestamps and other non-relevant
stuff from it and indent quoted material two spaces.  But in this
case, I don't think the calltrace is useful.

The reason to do this is not to avoid a warning and the related
calltrace.  The reason is to fix the problem that *caused* the warning
in the first place.  So we should describe the underlying problem and
the fix.

> disable reglator when imx6_pcie_probe fails,
> otherwise the following calltrace will appear
> 
> [ 3.785075] ------------[ cut here ]------------
> [ 3.788142] Registering SWP/SWPB emulation handler
> [ 3.789853] WARNING: CPU: 0 PID: 7 at drivers/regulator/core.c:2257 _regulator_put.part.0+0x1bc/0x1e0
> [ 3.795680] Loading compiled-in X.509 certificates
> [ 3.803947] Modules linked in:
> [ 3.811922] CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 5.16.0-10645-g3c750c7b6143-dirty #9
> [ 3.820393] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> [ 3.826945] Workqueue: events_unbound async_run_entry_fn
> [ 3.832304] unwind_backtrace from show_stack+0x10/0x14
> [ 3.837569] show_stack from dump_stack_lvl+0x58/0x70
> [ 3.842663] dump_stack_lvl from __warn+0xd8/0x114
> [ 3.847493] __warn from warn_slowpath_fmt+0x5c/0xc4
> [ 3.852490] warn_slowpath_fmt from _regulator_put.part.0+0x1bc/0x1e0
> [ 3.858968] _regulator_put.part.0 from regulator_put+0x2c/0x3c
> [ 3.864918] regulator_put from release_nodes+0x50/0x178
> [ 3.870270] release_nodes from devres_release_all+0x80/0xd0
> [ 3.875968] devres_release_all from really_probe+0xdc/0x30c
> [ 3.881661] really_probe from __driver_probe_device+0x80/0xe4
> [ 3.887522] __driver_probe_device from driver_probe_device+0x30/0xd4
> [ 3.893991] driver_probe_device from __driver_attach_async_helper+0x20/0x38
> [ 3.901068] __driver_attach_async_helper from async_run_entry_fn+0x20/0xb4
> [ 3.908059] async_run_entry_fn from process_one_work+0x298/0x7d0
> [ 3.914188] process_one_work from worker_thread+0x30/0x510
> [ 3.919792] worker_thread from kthread+0x128/0x14c
> [ 3.924705] kthread from ret_from_fork+0x14/0x38
> [ 3.929443] Exception stack(0xc20cbfb0 to 0xc20cbff8)
> [ 3.934521] bfa0: 00000000 00000000 00000000 00000000
> [ 3.942722] bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [ 3.950922] bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
> [ 3.957677] irq event stamp: 1207
> [ 3.961024] hardirqs last enabled at (1215): [<c0198270>] __up_console_sem+0x50/0x60
> [ 3.968974] hardirqs last disabled at (1224): [<c019825c>] __up_console_sem+0x3c/0x60
> [ 3.976911] softirqs last enabled at (1206): [<c010150c>] __do_softirq+0x2ec/0x5a4
> [ 3.984669] softirqs last disabled at (1197): [<c012ef08>] irq_exit+0x18c/0x20c
> [ 3.992021] ---[ end trace 45a52c023bf8fb33 ]---
> 
> Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 6974bd5aa116..f8279a15463b 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -1216,7 +1216,7 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  
>  	ret = dw_pcie_host_init(&pci->pp);
>  	if (ret < 0)
> -		return ret;
> +		goto err_vpcie;
>  
>  	if (pci_msi_enabled()) {
>  		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
> @@ -1226,6 +1226,11 @@ static int imx6_pcie_probe(struct platform_device *pdev)
>  	}
>  
>  	return 0;
> +
> +err_vpcie:
> +	regulator_disable(imx6_pcie->vpcie);

I don't know the regulator code and I couldn't figure out how
devm_regulator_get_optional() works because it passes OPTIONAL_GET in
to _devm_regulator_get(), but nothing ever checks for that, and I
couldn't be bothered to figure out what magic makes it work.

But regulator_disable() definitely dereferences its argument, and I'm
pretty sure it's possible to get here with "imx6_pcie->vpcie == NULL".

Also, it looks like the same situation with imx6_pcie->vph, so why
don't you clean that one up, too?

> +	return ret;
>  }
>  
>  static void imx6_pcie_shutdown(struct platform_device *pdev)
> -- 
> 2.25.1
> 


From robert.hancock at calian.com  Mon Jan 17 15:49:35 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Mon, 17 Jan 2022 23:49:35 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <CAKgpwJUMXk--4EaYOxAAtLJT85mDHRHMihr6n7y1HECN+gmBBw@mail.gmail.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <CAKgpwJUMXk--4EaYOxAAtLJT85mDHRHMihr6n7y1HECN+gmBBw@mail.gmail.com>
Message-ID: <79d6057a70dae09bcc30a35f608f51c5a768d097.camel@calian.com>

On Mon, 2022-01-17 at 20:30 +0800, Jun Li wrote:
> Sean Anderson <sean.anderson at seco.com> ?2022?1?15??? 10:11???
> > This is a rework of patches 3-5 of [1]. It attempts to correctly program
> > REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
> > we no longer need a special property duplicating this configuration,
> > snps,ref-clock-period-ns is deprecated.
> > 
> > Please test this! Patches 3/4 in this series have the effect of
> > programming REFCLKPER and REFCLK_FLADJ on boards which already configure
> > the "ref" clock. I have build tested, but not much else.
> 
> DWC3 databook states a *condition* for program those settings:
> 
> This field must be programmed to a non-zero value only if
> GFLADJ_REFCLK_LPM_SEL is set to '1' or GCTL.SOFITPSYNC is set to '1'.
> The value is derived as follows:
> FLADJ_REF_CLK_FLADJ=((125000/ref_clk_period_integer)-(125000/ref_clk_period))
> * ref_clk_period where
> ? the ref_clk_period_integer is the integer value of the ref_clk
> period got by truncating the decimal (fractional) value that is
> programmed in the GUCTL.REF_CLK_PERIOD field.
> ? the ref_clk_period is the ref_clk period including the fractional value.
> 
> So you may need a condition check, with that, only required users
> are effected even with "ref" clock specified.
> 

The Xilinx register documentation for this register in the DWC3 core ( 
https://www.xilinx.com/html_docs/registers/ug1087/usb3_xhci___gfladj.html ) has
the same description, but it is rather confusingly worded. I suspect what they
really mean is that "this field only needs to be programmed if
GFLADJ_REFCLK_LPM_SEL is set to '1' or GCTL.SOFITPSYNC is set to '1'", not
"this field should only be programmed if GFLADJ_REFCLK_LPM_SEL is set to '1' or
GCTL.SOFITPSYNC is set to '1'". I'm not sure if someone can confirm that
interpretation is correct?

However, looking at that description a bit further, it looks like there are
some other fields in that register which are dependent on the reference clock:
GFLADJ_REFCLK_240MHZ_DECR (bits 30:24) and GFLADJ_REFCLK_240MHZDECR_PLS1 (bit
31). It looks like the Xilinx board I am using has those set properly, i.e. to
12 and 0 respectively (I'm guessing by hardware default, since I don't see
anything in the FSBL psu_init code setting those), but it wouldn't hurt to
ensure those fields are also set correctly.

> Li Jun
> 
> > [1] 
> > https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!IOGos0k!387DmPelOIA5Z6ZSfzSF2spWPu3lARlrkdmIRGcPwlWDZGDQzdlEdEKBw1RWG8aRC38$
> >  
> > 
> > 
> > Sean Anderson (6):
> >   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
> >   usb: dwc3: Get clocks individually
> >   usb: dwc3: Calculate REFCLKPER based on reference clock
> >   usb: dwc3: Handle fractional reference clocks
> >   arm64: dts: zynqmp: Move USB clocks to dwc3 node
> >   arm64: dts: ipq6018: Use reference clock to set dwc3 period
> > 
> >  .../devicetree/bindings/usb/snps,dwc3.yaml    |  7 +-
> >  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  3 +-
> >  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +-
> >  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  4 +-
> >  drivers/usb/dwc3/core.c                       | 98 ++++++++++++++++---
> >  drivers/usb/dwc3/core.h                       |  6 +-
> >  6 files changed, 98 insertions(+), 24 deletions(-)
> > 
> > --
> > 2.25.1
> > 
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From hongxing.zhu at nxp.com  Mon Jan 17 17:00:22 2022
From: hongxing.zhu at nxp.com (Hongxing Zhu)
Date: Tue, 18 Jan 2022 01:00:22 +0000
Subject: [PATCH] pci: imx: disable reglator when imx6_pcie_probe fails
In-Reply-To: <20220117231735.GA813924@bhelgaas>
References: <20220117102137.3513439-1-xiaolei.wang@windriver.com>
 <20220117231735.GA813924@bhelgaas>
Message-ID: <AS8PR04MB86764CA226DC42B8F81482DF8C589@AS8PR04MB8676.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Bjorn Helgaas <helgaas at kernel.org>
> Sent: Tuesday, January 18, 2022 7:18 AM
> To: Xiaolei Wang <xiaolei.wang at windriver.com>
> Cc: Hongxing Zhu <hongxing.zhu at nxp.com>; l.stach at pengutronix.de;
> lorenzo.pieralisi at arm.com; robh at kernel.org; kw at linux.com;
> bhelgaas at google.com; shawnguo at kernel.org; s.hauer at pengutronix.de;
> kernel at pengutronix.de; festevam at gmail.com; dl-linux-imx
> <linux-imx at nxp.com>; linux-pci at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH] pci: imx: disable reglator when imx6_pcie_probe
> fails
> 
> On Mon, Jan 17, 2022 at 06:21:37PM +0800, Xiaolei Wang wrote:
> > From: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
> 
> I got two copies of this.  This one changed:
> 
>   - Signed-off-by: wrsadmin
> <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
>   + Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
> 
> This looks like a good change.  You should also change the
> "From: wrsadmin" line above because that is what "git am" uses in the
> commit:
> 
>   commit 119fdfb8fb1b ("pci: imx: disable reglator when
> imx6_pcie_probe fails")
>   Author: wrsadmin <wrsadmin at pek-xwang8-d1.corp.ad.wrs.com>
>   Date:   Mon Jan 17 18:17:35 2022 +0800
> 
> Also, please run "git log --oneline drivers/pci/controller/dwc/pci-imx6.c"
> and make your subject line match in capitalization and style.
> 
> Also, fix the "s/reglator/regulator" typo in subject and below and add "()"
> after the imx6_pcie_probe() function name.
> 
> If you include a calltrace, remove timestamps and other non-relevant
> stuff from it and indent quoted material two spaces.  But in this case, I
> don't think the calltrace is useful.
> 
> The reason to do this is not to avoid a warning and the related calltrace.
> The reason is to fix the problem that *caused* the warning in the first
> place.  So we should describe the underlying problem and the fix.
> 
> > disable reglator when imx6_pcie_probe fails, otherwise the following
> > calltrace will appear
> >
> > [ 3.785075] ------------[ cut here ]------------ [ 3.788142]
> > Registering SWP/SWPB emulation handler [ 3.789853] WARNING: CPU:
> 0
> > PID: 7 at drivers/regulator/core.c:2257
> > _regulator_put.part.0+0x1bc/0x1e0 [ 3.795680] Loading compiled-in
> > X.509 certificates [ 3.803947] Modules linked in:
> > [ 3.811922] CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted
> > 5.16.0-10645-g3c750c7b6143-dirty #9 [ 3.820393] Hardware name:
> > Freescale i.MX6 Quad/DualLite (Device Tree) [ 3.826945] Workqueue:
> > events_unbound async_run_entry_fn [ 3.832304] unwind_backtrace
> from
> > show_stack+0x10/0x14 [ 3.837569] show_stack from
> > dump_stack_lvl+0x58/0x70 [ 3.842663] dump_stack_lvl from
> > __warn+0xd8/0x114 [ 3.847493] __warn from
> warn_slowpath_fmt+0x5c/0xc4
> > [ 3.852490] warn_slowpath_fmt from
> _regulator_put.part.0+0x1bc/0x1e0 [
> > 3.858968] _regulator_put.part.0 from regulator_put+0x2c/0x3c [
> > 3.864918] regulator_put from release_nodes+0x50/0x178 [ 3.870270]
> > release_nodes from devres_release_all+0x80/0xd0 [ 3.875968]
> > devres_release_all from really_probe+0xdc/0x30c [ 3.881661]
> > really_probe from __driver_probe_device+0x80/0xe4 [ 3.887522]
> > __driver_probe_device from driver_probe_device+0x30/0xd4
> [ 3.893991]
> > driver_probe_device from __driver_attach_async_helper+0x20/0x38
> > [ 3.901068] __driver_attach_async_helper from
> > async_run_entry_fn+0x20/0xb4 [ 3.908059] async_run_entry_fn from
> > process_one_work+0x298/0x7d0 [ 3.914188] process_one_work from
> > worker_thread+0x30/0x510 [ 3.919792] worker_thread from
> > kthread+0x128/0x14c [ 3.924705] kthread from
> ret_from_fork+0x14/0x38 [
> > 3.929443] Exception stack(0xc20cbfb0 to 0xc20cbff8) [ 3.934521] bfa0:
> > 00000000 00000000 00000000 00000000 [ 3.942722] bfc0: 00000000
> > 00000000 00000000 00000000 00000000 00000000 00000000
> 00000000 [
> > 3.950922] bfe0: 00000000 00000000 00000000 00000000 00000013
> 00000000
> > [ 3.957677] irq event stamp: 1207 [ 3.961024] hardirqs last enabled at
> > (1215): [<c0198270>] __up_console_sem+0x50/0x60 [ 3.968974]
> hardirqs
> > last disabled at (1224): [<c019825c>] __up_console_sem+0x3c/0x60 [
> > 3.976911] softirqs last enabled at (1206): [<c010150c>]
> > __do_softirq+0x2ec/0x5a4 [ 3.984669] softirqs last disabled at (1197):
> > [<c012ef08>] irq_exit+0x18c/0x20c [ 3.992021] ---[ end trace
> > 45a52c023bf8fb33 ]---
> >
> > Signed-off-by: Xiaolei Wang <xiaolei.wang at windriver.com>
[Richard Zhu] Thanks for Bjorn's kindly help firstly.
Hi Xiaolei:
Thanks for your patch.
There is already a patch issued by Fabio refer to this kernel dump problem.
https://patchwork.kernel.org/project/linux-pci/patch/20220106103645.2790803-1-festevam at gmail.com/
Then, I prefer to update the fix by the following codes refine
 patch-set in next step.
https://patchwork.ozlabs.org/project/linux-pci/cover/1641368602-20401-1-git-send-email-hongxing.zhu at nxp.com/

Best Regards
Richard

> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index 6974bd5aa116..f8279a15463b 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -1216,7 +1216,7 @@ static int imx6_pcie_probe(struct
> > platform_device *pdev)
> >
> >  	ret = dw_pcie_host_init(&pci->pp);
> >  	if (ret < 0)
> > -		return ret;
> > +		goto err_vpcie;
> >
> >  	if (pci_msi_enabled()) {
> >  		u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI); @@
> > -1226,6 +1226,11 @@ static int imx6_pcie_probe(struct
> platform_device *pdev)
> >  	}
> >
> >  	return 0;
> > +
> > +err_vpcie:
> > +	regulator_disable(imx6_pcie->vpcie);
> 
> I don't know the regulator code and I couldn't figure out how
> devm_regulator_get_optional() works because it passes OPTIONAL_GET
> in to _devm_regulator_get(), but nothing ever checks for that, and I
> couldn't be bothered to figure out what magic makes it work.
> 
> But regulator_disable() definitely dereferences its argument, and I'm
> pretty sure it's possible to get here with "imx6_pcie->vpcie == NULL".
> 
> Also, it looks like the same situation with imx6_pcie->vph, so why don't
> you clean that one up, too?
> 
> > +	return ret;
> >  }
> >
> >  static void imx6_pcie_shutdown(struct platform_device *pdev)
> > --
> > 2.25.1
> >


From peng.fan at nxp.com  Mon Jan 17 17:24:38 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 18 Jan 2022 01:24:38 +0000
Subject: [PATCH] remoteproc: imx_rproc: validate resource table
In-Reply-To: <20220117182551.GC1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-2-peng.fan@oss.nxp.com>
 <20220117182551.GC1119324@p14s>
Message-ID: <DU0PR04MB9417BEA67ED9C2185C5C874A88589@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH] remoteproc: imx_rproc: validate resource table
> 
> Good morning,
> 
> On Tue, Jan 11, 2022 at 11:33:23AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Currently NXP use one device tree to support all NXP released Cortex-M
> > demos. There is one simple demo that not need to communicate with
> > Linux, thus it will not update the resource table. So there maybe
> > garbage data in it. In such case, Linux should directly ignore it.
> >
> > It is hard to decide what data is garbage data, NXP released SDK use
> > ver(1), reserved(0) in a valid resource table. But in case others use
> > different value, so here use 0xff as a max value for ver and num.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/imx_rproc.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 0bd24c937a73..75fde16f80a4
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -490,11 +490,19 @@ static int imx_rproc_attach(struct rproc *rproc)
> > static struct resource_table *imx_rproc_get_loaded_rsc_table(struct
> > rproc *rproc, size_t *table_sz)  {
> >  	struct imx_rproc *priv = rproc->priv;
> > +	struct resource_table *table;
> >
> >  	/* The resource table has already been mapped in imx_rproc_addr_init
> */
> >  	if (!priv->rsc_table)
> >  		return NULL;
> >
> > +	table = priv->rsc_table;
> > +	/* Gabage data check */
> > +	if (table->ver >= 0xff || table->num >= 0xff || table->reserved[0] ||
> table->reserved[1]) {
> > +		dev_err(priv->dev, "Ignore invalid rsc table\n");
> > +		return NULL;
> > +	}
> > +
> 
> This seems like the wrong fix to me.  Either use different DTs or update the
> resource table for all demos - efficiency should not be a problem since they
> are demos.  With the above it is only a matter of time before the pattern
> associated with valid resource tables changes, leading to more hacks that will
> be impossible to maintain over time.

I see, drop this patch :)

Thanks,
Peng.

> 
> Thanks,
> Mathieu
> 
> >  	*table_sz = SZ_1K;
> >  	return (struct resource_table *)priv->rsc_table;  }
> > --
> > 2.25.1
> >


From arzamas-16 at mail.ee  Mon Jan 17 17:25:12 2022
From: arzamas-16 at mail.ee (Boris Lysov)
Date: Tue, 18 Jan 2022 04:25:12 +0300
Subject: Missing ARM TWD Watchdog driver?
In-Reply-To: <20220117170225.GB94025@C02TD0UTHF1T.local>
References: <20220117190112.2b2c2f53@pc>
 <60dceae6-5c7c-9f2d-9fcb-5e849f1d8ce5@roeck-us.net>
 <20220117170225.GB94025@C02TD0UTHF1T.local>
Message-ID: <20220118042512.360ee83a@pc>

Hi Mark and Guenter,

On Mon, 17 Jan 2022 17:02:25 +0000,
Mark Rutland <mark.rutland at arm.com> wrote:

> On Mon, Jan 17, 2022 at 08:34:57AM -0800, Guenter Roeck wrote:
> > On 1/17/22 8:01 AM, Boris Lysov wrote:
> > > Hello everyone,
> > > 
> > > I stumbled upon the ARM TWD Watchdog driver which seems to be missing (or
> > > I'm just blind).
> > > 
> > > As per commit a33f5c380c4bd3fa5278d690421b72052456d9fe ("Merge tag
> > > 'xfs-5.17-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux"),
> > > multiple device trees declare usage of arm-twd:
> > > 
> > > (...)
> > > 
> > > and it is documented in
> > > Documentation/devicetree/bindings/watchdog/arm,twd-wdt.yaml
> > > 
> > > However I could not find the driver itself. I tried running
> > > case-insensitive grep and ripgrep to no avail. Does this driver actually
> > > exist? Is it gone?
> > > 
> > 
> > I may be missing it, but I do not see any evidence that it ever existed.
> 
> Likewise, AFAICT we added the binding but never the driver.
> 
> Looking at the git history, that schema was introduced in commit:
> 
>   50e02e9a030a9ae3 ("dt-bindings: timer: arm,twd: Convert to json-schema")
> 
> ... and replaced Documentation/devicetree/bindings/timer/arm,twd.txt
> 
> Per:
> 
>   $ git log --follow Documentation/devicetree/bindings/timer/arm,twd.txt
> 
> That was introduced alongside a driver in commit:
> 
>   d8e0364364d333fe ("ARM: smp_twd: add device tree support")
> 
> ... which only introduced a driver for the timer, and not the watchdog,
> as the commit message notes.
> 
> Thanks.
> Mark.

Now I understand there's no ARM TWD Watchdog driver.
TYVM for your replies!


From allen-kh.cheng at mediatek.com  Mon Jan 17 17:39:15 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 09:39:15 +0800
Subject: [PATCH v4 0/2] Add SCP support for mt8186
In-Reply-To: <20220117172637.GB1119324@p14s>
References: <20220105094125.6917-1-allen-kh.cheng@mediatek.com>
 <20220117172637.GB1119324@p14s>
Message-ID: <5edbd10d7944c496471bb2a6235e42f7c02d2452.camel@mediatek.com>

On Mon, 2022-01-17 at 10:26 -0700, Mathieu Poirier wrote:
> On Wed, Jan 05, 2022 at 05:41:23PM +0800, allen-kh.cheng wrote:
> > From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> > 
> > changes since v3:
> >  - use rproc-next
> > 
> > changes since v2:
> >  - remove redundant SoB
> > 
> > changes since v1:
> >  - use mt8192_power_on_sram() helper
> >  - add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
> >  - add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h
> > 
> > Based on rproc-next
> > 
> > Allen-KH Cheng (2):
> >   dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
> >   remoteproc: mediatek: Support mt8186 scp
> > 
> >  .../bindings/remoteproc/mtk,scp.yaml          |  1 +
> >  drivers/remoteproc/mtk_common.h               |  3 ++
> >  drivers/remoteproc/mtk_scp.c                  | 35
> > +++++++++++++++++++
> >  3 files changed, 39 insertions(+)
> 
> Both patches in this set are giving me a checkpatch warning that is
> impossible
> to miss.  I deleting this patchset from my queue.   

Hi Mathieu,

I find the problem is 'Reviewed-by:' is the preferred signature.

I will correct this in next version.

Thanks.

> 
> > 
> > -- 
> > 2.18.0
> > 



From allen-kh.cheng at mediatek.com  Mon Jan 17 17:49:20 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 09:49:20 +0800
Subject: [PATCH v5 1/2] dt-bindings: remoteproc: mediatek: Add binding for
 mt8186 scp
In-Reply-To: <20220118014921.30146-1-allen-kh.cheng@mediatek.com>
References: <20220118014921.30146-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220118014921.30146-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add mt8186 compatible to binding document.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
index d21a25ee96e6..5b693a2d049c 100644
--- a/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/mtk,scp.yaml
@@ -17,6 +17,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-scp
+      - mediatek,mt8186-scp
       - mediatek,mt8192-scp
       - mediatek,mt8195-scp
 
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 17:49:21 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 09:49:21 +0800
Subject: [PATCH v5 2/2] remoteproc: mediatek: Support mt8186 scp
In-Reply-To: <20220118014921.30146-1-allen-kh.cheng@mediatek.com>
References: <20220118014921.30146-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220118014921.30146-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add SCP support for mt8186

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/remoteproc/mtk_common.h |  3 +++
 drivers/remoteproc/mtk_scp.c    | 35 +++++++++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
index 5ff3867c72f3..71ce4977cb0b 100644
--- a/drivers/remoteproc/mtk_common.h
+++ b/drivers/remoteproc/mtk_common.h
@@ -32,6 +32,9 @@
 #define MT8183_SCP_CACHESIZE_8KB	BIT(8)
 #define MT8183_SCP_CACHE_CON_WAYEN	BIT(10)
 
+#define MT8186_SCP_L1_SRAM_PD_P1	0x40B0
+#define MT8186_SCP_L1_SRAM_PD_p2	0x40B4
+
 #define MT8192_L2TCM_SRAM_PD_0		0x10C0
 #define MT8192_L2TCM_SRAM_PD_1		0x10C4
 #define MT8192_L2TCM_SRAM_PD_2		0x10C8
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..6860ea4d5125 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -383,6 +383,27 @@ static void mt8192_power_off_sram(void __iomem *addr)
 		writel(GENMASK(i, 0), addr);
 }
 
+static int mt8186_scp_before_load(struct mtk_scp *scp)
+{
+	/* Clear SCP to host interrupt */
+	writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+	/* Reset clocks before loading FW */
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+	writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+	/* Turn on the power of SCP's SRAM before using it. Enable 1 block per time*/
+	mt8192_power_on_sram(scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+	/* Initialize TCM before loading FW. */
+	writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_P1);
+	writel(0x0, scp->reg_base + MT8186_SCP_L1_SRAM_PD_p2);
+
+	return 0;
+}
+
 static int mt8192_scp_before_load(struct mtk_scp *scp)
 {
 	/* clear SPM interrupt, SCP2SPM_IPC_CLR */
@@ -887,6 +908,19 @@ static const struct mtk_scp_of_data mt8183_of_data = {
 	.ipi_buf_offset = 0x7bdb0,
 };
 
+static const struct mtk_scp_of_data mt8186_of_data = {
+	.scp_clk_get = mt8195_scp_clk_get,
+	.scp_before_load = mt8186_scp_before_load,
+	.scp_irq_handler = mt8183_scp_irq_handler,
+	.scp_reset_assert = mt8183_scp_reset_assert,
+	.scp_reset_deassert = mt8183_scp_reset_deassert,
+	.scp_stop = mt8183_scp_stop,
+	.scp_da_to_va = mt8183_scp_da_to_va,
+	.host_to_scp_reg = MT8183_HOST_TO_SCP,
+	.host_to_scp_int_bit = MT8183_HOST_IPC_INT_BIT,
+	.ipi_buf_offset = 0x7bdb0,
+};
+
 static const struct mtk_scp_of_data mt8192_of_data = {
 	.scp_clk_get = mt8192_scp_clk_get,
 	.scp_before_load = mt8192_scp_before_load,
@@ -913,6 +947,7 @@ static const struct mtk_scp_of_data mt8195_of_data = {
 
 static const struct of_device_id mtk_scp_of_match[] = {
 	{ .compatible = "mediatek,mt8183-scp", .data = &mt8183_of_data },
+	{ .compatible = "mediatek,mt8186-scp", .data = &mt8186_of_data },
 	{ .compatible = "mediatek,mt8192-scp", .data = &mt8192_of_data },
 	{ .compatible = "mediatek,mt8195-scp", .data = &mt8195_of_data },
 	{},
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 17:49:19 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 09:49:19 +0800
Subject: [PATCH v5 0/2] Add SCP support for mt8186
Message-ID: <20220118014921.30146-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

changes since v4:
 - use 'Reviewed-by:' for the preferred signature

changes since v3:
 - base on rproc-next

changes since v2:
 - remove redundant SoB

changes since v1:
 - use mt8192_power_on_sram() helper
 - add MT8186_SCP_L1_SRAM_PD_P1 in mtk_common.h
 - add MT8186_SCP_L1_SRAM_PD_P2 in mtk_common.h


Allen-KH Cheng (2):
  dt-bindings: remoteproc: mediatek: Add binding for mt8186 scp
  remoteproc: mediatek: Support mt8186 scp

 .../bindings/remoteproc/mtk,scp.yaml          |  1 +
 drivers/remoteproc/mtk_common.h               |  3 ++
 drivers/remoteproc/mtk_scp.c                  | 35 +++++++++++++++++++
 3 files changed, 39 insertions(+)

-- 
2.18.0



From biao.huang at mediatek.com  Mon Jan 17 17:51:45 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Tue, 18 Jan 2022 09:51:45 +0800
Subject: [PATCH net-next v12 3/7] stmmac: dwmac-mediatek: re-arrange
 clock setting
In-Reply-To: <2c62f337-5eb4-e525-7e3a-289435315c09@collabora.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
 <20220117070706.17853-4-biao.huang@mediatek.com>
 <2c62f337-5eb4-e525-7e3a-289435315c09@collabora.com>
Message-ID: <f9e3a862ecdb914a0efb52582989e975a742e918.camel@mediatek.com>

Dear Angelo,
	Thanks for your comments.
On Mon, 2022-01-17 at 11:38 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/01/22 08:07, Biao Huang ha scritto:
> > The rmii_internal clock is needed only when PHY
> > interface is RMII, and reference clock is from MAC.
> > 
> > Re-arrange the clock setting as following:
> > 1. the optional "rmii_internal" is controlled by devm_clk_get(),
> > 2. other clocks still be configured by devm_clk_bulk_get().
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > ---
> >   .../ethernet/stmicro/stmmac/dwmac-mediatek.c  | 72 +++++++++++++-
> > -----
> >   1 file changed, 49 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > index 8747aa4403e8..2678d2deb26a 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
> > @@ -49,14 +49,15 @@ struct mac_delay_struct {
> >   struct mediatek_dwmac_plat_data {
> >   	const struct mediatek_dwmac_variant *variant;
> >   	struct mac_delay_struct mac_delay;
> > +	struct clk *rmii_internal_clk;
> >   	struct clk_bulk_data *clks;
> > -	struct device_node *np;
> >   	struct regmap *peri_regmap;
> > +	struct device_node *np;
> >   	struct device *dev;
> >   	phy_interface_t phy_mode;
> > -	int num_clks_to_config;
> >   	bool rmii_clk_from_mac;
> >   	bool rmii_rxc;
> > +	int num_clks;
> 
> I don't see any need to get a num_clks here, at this point: since all
> functions
> reading this are getting passed a pointer to this entire structure,
> you can
> simply always access plat->variant->num_clks.
> 
> Please, drop the addition of num_clks in this struct.
> 
> Regards,
> Angelo
OK, will remove it in next send.

From sashal at kernel.org  Mon Jan 17 18:16:26 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:16:26 -0500
Subject: [PATCH AUTOSEL 5.16 023/217] ARM: shmobile: rcar-gen2: Add missing
 of_node_put()
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-23-sashal@kernel.org>

From: Wan Jiabing <wanjiabing at vivo.com>

[ Upstream commit 85744f2d938c5f3cfc44cb6533c157469634da93 ]

Fix following coccicheck warning:
./arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c:156:1-33: Function
for_each_matching_node_and_match should have of_node_put() before break
and goto.

Early exits from for_each_matching_node_and_match() should decrement the
node reference counter.

Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
Link: https://lore.kernel.org/r/20211018014503.7598-1-wanjiabing at vivo.com
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index ee949255ced3f..09ef73b99dd86 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void)
 		return -ENODEV;
 
 	for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
-		if (!of_device_is_available(np))
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
 			break;
+		}
 
 		ret = of_property_read_u32(np, "reg", &addr);
 		if (ret)	/* Skip invalid entry and continue */
@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void)
 		quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
 		if (!quirk) {
 			ret = -ENOMEM;
+			of_node_put(np);
 			goto err_mem;
 		}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:16:32 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:16:32 -0500
Subject: [PATCH AUTOSEL 5.16 029/217] usb: dwc3: meson-g12a: fix shared reset
 control use
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-29-sashal@kernel.org>

From: Amjad Ouled-Ameur <aouledameur at baylibre.com>

[ Upstream commit 4ce3b45704d5ef46fb4b28083c8aba6716fabf3b ]

reset_control_(de)assert() calls are called on a shared reset line when
reset_control_reset has been used. This is not allowed by the reset
framework.

Use reset_control_rearm() call in suspend() and remove() as a way to state
that the resource is no longer used, hence the shared reset line
may be triggered again by other devices. Use reset_control_rearm() also in
case probe fails after reset() has been called.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework, use of reset_control_reset() on shared reset line should be
balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211112162827.128319-3-aouledameur at baylibre.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/dwc3/dwc3-meson-g12a.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index d0f9b7c296b0d..bd814df3bf8b8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
 	ret = dwc3_meson_g12a_get_phys(priv);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	ret = priv->drvdata->setup_regmaps(priv, base);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	if (priv->vbus) {
 		ret = regulator_enable(priv->vbus);
 		if (ret)
-			goto err_disable_clks;
+			goto err_rearm;
 	}
 
 	/* Get dr_mode */
@@ -825,6 +825,9 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 	if (priv->vbus)
 		regulator_disable(priv->vbus);
 
+err_rearm:
+	reset_control_rearm(priv->reset);
+
 err_disable_clks:
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
 	pm_runtime_put_noidle(dev);
 	pm_runtime_set_suspended(dev);
 
+	reset_control_rearm(priv->reset);
+
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
 
@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
 		phy_exit(priv->phys[i]);
 	}
 
-	reset_control_assert(priv->reset);
+	reset_control_rearm(priv->reset);
 
 	return 0;
 }
@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
 	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
 	int i, ret;
 
-	reset_control_deassert(priv->reset);
+	ret = reset_control_reset(priv->reset);
+	if (ret)
+		return ret;
 
 	ret = priv->drvdata->usb_init(priv);
 	if (ret)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:16:57 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:16:57 -0500
Subject: [PATCH AUTOSEL 5.16 054/217] EDAC/synopsys: Use the quirk for version
 instead of ddr version
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-54-sashal@kernel.org>

From: Dinh Nguyen <dinguyen at kernel.org>

[ Upstream commit bd1d6da17c296bd005bfa656952710d256e77dd3 ]

Version 2.40a supports DDR_ECC_INTR_SUPPORT for a quirk, so use that
quirk to determine a call to setup_address_map().

Signed-off-by: Dinh Nguyen <dinguyen at kernel.org>
Signed-off-by: Borislav Petkov <bp at suse.de>
Reviewed-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lkml.kernel.org/r/20211012190709.1504152-1-dinguyen at kernel.org
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/edac/synopsys_edac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 7d08627e738b3..a5486d86fdd2f 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1352,8 +1352,7 @@ static int mc_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "xlnx,zynqmp-ddrc-2.40a"))
+	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
 		setup_address_map(priv);
 #endif
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:00 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:00 -0500
Subject: [PATCH AUTOSEL 5.16 057/217] soc: imx: gpcv2: Synchronously suspend
 MIX domains
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-57-sashal@kernel.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit f756f435f7dd823f2d4bd593ce1bf3168def1308 ]

In case the following power domain sequence happens, iMX8M Mini always hangs:
  gpumix:on -> gpu:on -> gpu:off -> gpu:on
This is likely due to another quirk of the GPC block. This situation can be
prevented by always synchronously powering off both the domain and MIX domain.
Make it so. This turns the aforementioned sequence into:
  gpumix:on -> gpu:on -> gpu:off -> gpumix:off -> gpumix:on -> gpu:on

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Frieder Schrempf <frieder.schrempf at kontron.de>
Cc: Lucas Stach <l.stach at pengutronix.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Acked-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/soc/imx/gpcv2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index b8d52d8d29dbb..e757044ab7512 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -377,7 +377,7 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
 		}
 	}
 
-	pm_runtime_put(domain->dev);
+	pm_runtime_put_sync_suspend(domain->dev);
 
 	return 0;
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:01 -0500
Subject: [PATCH AUTOSEL 5.16 058/217] ARM: imx: rename DEBUG_IMX21_IMX27_UART
 to DEBUG_IMX27_UART
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-58-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 98436702e0c7e..644875d73ba15 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -410,12 +410,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1481,7 +1481,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1540,12 +1540,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index c8eb83d4b8964..3edbb3c5b42bf 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -11,13 +11,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -26,6 +19,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -112,10 +112,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:05 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:05 -0500
Subject: [PATCH AUTOSEL 5.16 062/217] soc: ti: pruss: fix referenced node in
 error message
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-62-sashal@kernel.org>

From: Jan Kiszka <jan.kiszka at siemens.com>

[ Upstream commit 8aa35e0bb5eaa42bac415ad0847985daa7b4890c ]

So far, "(null)" is reported for the node that is missing clocks.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Acked-by: Suman Anna <s-anna at ti.com>
Signed-off-by: Nishanth Menon <nm at ti.com>
Link: https://lore.kernel.org/r/d6e24953-ea89-fd1c-6e16-7a0142118054 at siemens.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/soc/ti/pruss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index 49da387d77494..b36779309e49b 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -129,7 +129,7 @@ static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node)
 
 	clks_np = of_get_child_by_name(cfg_node, "clocks");
 	if (!clks_np) {
-		dev_err(dev, "%pOF is missing its 'clocks' node\n", clks_np);
+		dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node);
 		return -ENODEV;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:09 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:09 -0500
Subject: [PATCH AUTOSEL 5.16 066/217] mxser: keep only !tty test in ISR
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-66-sashal@kernel.org>

From: Jiri Slaby <jslaby at suse.cz>

[ Upstream commit 274ab58dc2b460cc474ffc7ccfcede4b2be1a3f5 ]

The others are superfluous with tty refcounting in place now. And they
are racy in fact:
* tty_port_initialized() reports false for a small moment after
  interrupts are enabled.
* closing is 1 while the port is still alive.

The queues are flushed later during close anyway. So there is no need
for this special handling. Actually, the ISR should not flush the
queues. It should behave as every other driver, just queue the chars
into tty buffer and go on. But this will be changed later. There is
still a lot code depending on having tty in ISR (and not only tty_port).

Signed-off-by: Jiri Slaby <jslaby at suse.cz>
Link: https://lore.kernel.org/r/20211118073125.12283-4-jslaby at suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/mxser.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 93a95a135a71a..27caa2f9ba79b 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -262,7 +262,6 @@ struct mxser_port {
 	unsigned int xmit_head;
 	unsigned int xmit_tail;
 	unsigned int xmit_cnt;
-	int closing;
 
 	spinlock_t slock;
 };
@@ -918,7 +917,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 		return;
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
-	info->closing = 1;
 	mutex_lock(&port->mutex);
 	mxser_close_port(port);
 	mxser_flush_buffer(tty);
@@ -927,7 +925,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 	mxser_shutdown_port(port);
 	tty_port_set_initialized(port, 0);
 	mutex_unlock(&port->mutex);
-	info->closing = 0;
 	/* Right now the tty_port set is done outside of the close_end helper
 	   as we don't yet have everyone using refcounts */	
 	tty_port_close_end(port, tty);
@@ -1683,7 +1680,7 @@ static bool mxser_port_isr(struct mxser_port *port)
 
 	iir &= MOXA_MUST_IIR_MASK;
 	tty = tty_port_tty_get(&port->port);
-	if (!tty || port->closing || !tty_port_initialized(&port->port)) {
+	if (!tty) {
 		status = inb(port->ioaddr + UART_LSR);
 		outb(port->FCR | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
 				port->ioaddr + UART_FCR);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:10 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:10 -0500
Subject: [PATCH AUTOSEL 5.16 067/217] mxser: don't throttle manually
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-67-sashal@kernel.org>

From: Jiri Slaby <jslaby at suse.cz>

[ Upstream commit c6693e6e07805f1b7822b13a5b482bf2b6a1f312 ]

First, checking tty->receive_room to signalize whether there is enough space
in the tty buffers does not make much sense. Provided the tty buffers
are in tty_port and those are not checked at all.

Second, if the rx path is throttled, with CRTSCTS, RTS is deasserted,
but is never asserted again. This leads to port "lockup", not accepting
any more input.

So:
1) stty -F /dev/ttyMI0 crtscts # the mxser port
2) stty -F /dev/ttyS6 crtscts # the connected port
3) cat /dev/ttyMI0
4) "write in a loop" to /dev/ttyS6
5) cat from 3) produces the bytes from 4)
6) killall -STOP cat (the 3)'s one)
7) wait for RTS to drop on /dev/ttyMI0
8) killall -CONT cat (again the 3)'s one)

cat erroneously produces no more output now (i.e. no data sent from
ttyS6 to ttyMI can be seen).

Note that the step 7) is performed twice: once from n_tty by
tty_throttle_safe(), once by mxser_stoprx() from the receive path. Then
after step 7), n_tty correctly unthrottles the input, but mxser calls
mxser_stoprx() again as there is still only a little space in n_tty
buffers (tty->receive_room mentioned at the beginning), but the device's
FIFO is/can be already filled.

After this patch, the output is correctly resumed, i.e. n_tty both
throttles and unthrottles without interfering with mxser's attempts.

This allows us to get rid of the non-standard ldisc_stop_rx flag from
struct mxser_port.

Signed-off-by: Jiri Slaby <jslaby at suse.cz>
Link: https://lore.kernel.org/r/20211118073125.12283-15-jslaby at suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/mxser.c | 36 ++++++------------------------------
 1 file changed, 6 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 27caa2f9ba79b..3b5d193b7f245 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -251,8 +251,6 @@ struct mxser_port {
 	u8 MCR;			/* Modem control register */
 	u8 FCR;			/* FIFO control register */
 
-	bool ldisc_stop_rx;
-
 	struct async_icount icount; /* kernel counters for 4 input interrupts */
 	unsigned int timeout;
 
@@ -1323,11 +1321,14 @@ static int mxser_get_icount(struct tty_struct *tty,
 	return 0;
 }
 
-static void mxser_stoprx(struct tty_struct *tty)
+/*
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ */
+static void mxser_throttle(struct tty_struct *tty)
 {
 	struct mxser_port *info = tty->driver_data;
 
-	info->ldisc_stop_rx = true;
 	if (I_IXOFF(tty)) {
 		if (info->board->must_hwid) {
 			info->IER &= ~MOXA_MUST_RECV_ISR;
@@ -1346,21 +1347,11 @@ static void mxser_stoprx(struct tty_struct *tty)
 	}
 }
 
-/*
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- */
-static void mxser_throttle(struct tty_struct *tty)
-{
-	mxser_stoprx(tty);
-}
-
 static void mxser_unthrottle(struct tty_struct *tty)
 {
 	struct mxser_port *info = tty->driver_data;
 
 	/* startrx */
-	info->ldisc_stop_rx = false;
 	if (I_IXOFF(tty)) {
 		if (info->x_char)
 			info->x_char = 0;
@@ -1543,9 +1534,6 @@ static bool mxser_receive_chars_new(struct tty_struct *tty,
 	if (hwid == MOXA_MUST_MU150_HWID)
 		gdl &= MOXA_MUST_GDL_MASK;
 
-	if (gdl >= tty->receive_room && !port->ldisc_stop_rx)
-		mxser_stoprx(tty);
-
 	while (gdl--) {
 		u8 ch = inb(port->ioaddr + UART_RX);
 		tty_insert_flip_char(&port->port, ch, 0);
@@ -1558,10 +1546,8 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
 		                struct mxser_port *port, u8 status)
 {
 	enum mxser_must_hwid hwid = port->board->must_hwid;
-	int recv_room = tty->receive_room;
 	int ignored = 0;
 	int max = 256;
-	int cnt = 0;
 	u8 ch;
 
 	do {
@@ -1596,14 +1582,8 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
 					port->icount.overrun++;
 				}
 			}
-			tty_insert_flip_char(&port->port, ch, flag);
-			cnt++;
-			if (cnt >= recv_room) {
-				if (!port->ldisc_stop_rx)
-					mxser_stoprx(tty);
+			if (!tty_insert_flip_char(&port->port, ch, flag))
 				break;
-			}
-
 		}
 
 		if (hwid)
@@ -1618,9 +1598,6 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
 static u8 mxser_receive_chars(struct tty_struct *tty,
 		struct mxser_port *port, u8 status)
 {
-	if (tty->receive_room == 0 && !port->ldisc_stop_rx)
-		mxser_stoprx(tty);
-
 	if (!mxser_receive_chars_new(tty, port, status))
 		status = mxser_receive_chars_old(tty, port, status);
 
@@ -1833,7 +1810,6 @@ static void mxser_initbrd(struct mxser_board *brd, bool high_baud)
 		tty_port_init(&info->port);
 		info->port.ops = &mxser_port_ops;
 		info->board = brd;
-		info->ldisc_stop_rx = false;
 
 		/* Enhance mode enabled here */
 		if (brd->must_hwid != MOXA_OTHER_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:11 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:11 -0500
Subject: [PATCH AUTOSEL 5.16 068/217] mxser: increase buf_overrun if
 tty_insert_flip_char() fails
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-68-sashal@kernel.org>

From: Jiri Slaby <jslaby at suse.cz>

[ Upstream commit eb68ac0462bffc2ceb63b3a76737d6c9f186e6de ]

mxser doesn't increase port->icount.buf_overrun at all. Do so if overrun
happens, so that it can be read from the stats.

Signed-off-by: Jiri Slaby <jslaby at suse.cz>
Link: https://lore.kernel.org/r/20211118073125.12283-17-jslaby at suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/mxser.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 3b5d193b7f245..39458b42df7b0 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -1536,7 +1536,8 @@ static bool mxser_receive_chars_new(struct tty_struct *tty,
 
 	while (gdl--) {
 		u8 ch = inb(port->ioaddr + UART_RX);
-		tty_insert_flip_char(&port->port, ch, 0);
+		if (!tty_insert_flip_char(&port->port, ch, 0))
+			port->icount.buf_overrun++;
 	}
 
 	return true;
@@ -1582,8 +1583,10 @@ static u8 mxser_receive_chars_old(struct tty_struct *tty,
 					port->icount.overrun++;
 				}
 			}
-			if (!tty_insert_flip_char(&port->port, ch, flag))
+			if (!tty_insert_flip_char(&port->port, ch, flag)) {
+				port->icount.buf_overrun++;
 				break;
+			}
 		}
 
 		if (hwid)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:13 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:13 -0500
Subject: [PATCH AUTOSEL 5.16 070/217] tty: serial: imx: disable UCR4_OREN in
 .stop_rx() instead of .shutdown()
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-70-sashal@kernel.org>

From: Fugang Duan <fugang.duan at nxp.com>

[ Upstream commit 028e083832b06fdeeb290e1e57dc1f6702c4c215 ]

The UCR4_OREN should be disabled before disabling the uart receiver in
.stop_rx() instead of in the .shutdown().

Otherwise, if we have the overrun error during the receiver disable
process, the overrun interrupt will keep trigging until we disable the
OREN interrupt in the .shutdown(), because the ORE status can only be
cleared when read the rx FIFO or reset the controller.  Although the
called time between the receiver disable and OREN disable in .shutdown()
is very short, there is still the risk of endless interrupt during this
short period of time. So here change to disable OREN before the receiver
been disabled in .stop_rx().

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Sherry Sun <sherry.sun at nxp.com>
Link: https://lore.kernel.org/r/20211125020349.4980-1-sherry.sun at nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/serial/imx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 90f82e6c54e46..6f7f382d0b1fa 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
 static void imx_uart_stop_rx(struct uart_port *port)
 {
 	struct imx_port *sport = (struct imx_port *)port;
-	u32 ucr1, ucr2;
+	u32 ucr1, ucr2, ucr4;
 
 	ucr1 = imx_uart_readl(sport, UCR1);
 	ucr2 = imx_uart_readl(sport, UCR2);
+	ucr4 = imx_uart_readl(sport, UCR4);
 
 	if (sport->dma_is_enabled) {
 		ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
 	} else {
 		ucr1 &= ~UCR1_RRDYEN;
 		ucr2 &= ~UCR2_ATEN;
+		ucr4 &= ~UCR4_OREN;
 	}
 	imx_uart_writel(sport, ucr1, UCR1);
+	imx_uart_writel(sport, ucr4, UCR4);
 
 	ucr2 &= ~UCR2_RXEN;
 	imx_uart_writel(sport, ucr2, UCR2);
@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port)
 	imx_uart_writel(sport, ucr1, UCR1);
 
 	ucr4 = imx_uart_readl(sport, UCR4);
-	ucr4 &= ~(UCR4_OREN | UCR4_TCEN);
+	ucr4 &= ~UCR4_TCEN;
 	imx_uart_writel(sport, ucr4, UCR4);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:33 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:33 -0500
Subject: [PATCH AUTOSEL 5.16 090/217] arm64: dts: ti: j7200-main: Fix
 'dtbs_check' serdes_ln_ctrl node
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-90-sashal@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

[ Upstream commit 4d3984906397581dc0ccb6a02bf16b6ff82c9192 ]

Fix 'dtbs_check' in serdes_ln_ctrl (serdes-ln-ctrl at 4080) node by
changing the node name to mux-controller at 4080.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Aswath Govindraju <a-govindraju at ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Link: https://lore.kernel.org/r/20211126084555.17797-2-kishon at ti.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index d60ef4f7dd0b7..05a627ad6cdc4 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -32,7 +32,7 @@ scm_conf: scm-conf at 100000 {
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x00100000 0x1c000>;
 
-		serdes_ln_ctrl: serdes-ln-ctrl at 4080 {
+		serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "mmio-mux";
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:34 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:34 -0500
Subject: [PATCH AUTOSEL 5.16 091/217] arm64: dts: ti: j721e-main: Fix
 'dtbs_check' in serdes_ln_ctrl node
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-91-sashal@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

[ Upstream commit 3f92a5be6084b77f764a8bbb881ac0d12cb9e863 ]

Fix 'dtbs_check' in serdes_ln_ctrl (mux at 4080) node by changing the node
name to mux-controller at 4080.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Aswath Govindraju <a-govindraju at ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Link: https://lore.kernel.org/r/20211126084555.17797-3-kishon at ti.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 08c8d1b47dcd9..e85c89eebfa31 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -42,7 +42,7 @@ scm_conf: scm-conf at 100000 {
 		#size-cells = <1>;
 		ranges = <0x0 0x0 0x00100000 0x1c000>;
 
-		serdes_ln_ctrl: mux at 4080 {
+		serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "mmio-mux";
 			reg = <0x00004080 0x50>;
 			#mux-control-cells = <1>;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:35 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:35 -0500
Subject: [PATCH AUTOSEL 5.16 092/217] usb: uhci: add aspeed ast2600 uhci
 support
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-92-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 70dbd95c3f063..be9e9db7cad10 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:58 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:58 -0500
Subject: [PATCH AUTOSEL 5.16 115/217] gpio: aspeed: Convert aspeed_gpio.lock
 to raw_spinlock
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-115-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit 61a7904b6ace99b1bde0d0e867fa3097f5c8cee2 ]

The gpio-aspeed driver implements an irq_chip which need to be invoked
from hardirq context. Since spin_lock() can sleep with PREEMPT_RT, it is
no longer legal to invoke it while interrupts are disabled.
This also causes lockdep to complain about:
[    0.649797] [ BUG: Invalid wait context ]
because aspeed_gpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed.c | 52 +++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 3c8f20c57695f..318a7d95a1a8b 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -53,7 +53,7 @@ struct aspeed_gpio_config {
 struct aspeed_gpio {
 	struct gpio_chip chip;
 	struct irq_chip irqc;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 	const struct aspeed_gpio_config *config;
@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 	unsigned long flags;
 	bool copro;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	__aspeed_gpio_set(gc, offset, val);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (!have_input(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg &= ~GPIO_BIT(offset);
@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 	if (!have_output(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg |= GPIO_BIT(offset);
@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 	if (!have_output(gpio, offset))
 		return GPIO_LINE_DIRECTION_IN;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
 }
@@ -539,14 +539,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	iowrite32(bit, status_addr);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
@@ -565,7 +565,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	reg = ioread32(addr);
@@ -577,7 +577,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_mask(struct irq_data *d)
@@ -629,7 +629,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
@@ -649,7 +649,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -716,7 +716,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	treg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	val = readl(treg);
@@ -730,7 +730,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -856,7 +856,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 		return rc;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	if (timer_allocation_registered(gpio, offset)) {
 		rc = unregister_allocated_timer(gpio, offset);
@@ -916,7 +916,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 	configure_timer(gpio, offset, i);
 
 out:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -927,13 +927,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
 	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	rc = unregister_allocated_timer(gpio, offset);
 	if (!rc)
 		configure_timer(gpio, offset, 0);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -1015,7 +1015,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0xff) {
@@ -1036,7 +1036,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 	if (bit)
 		*bit = GPIO_OFFSET(offset);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
@@ -1060,7 +1060,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0) {
@@ -1074,7 +1074,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		aspeed_gpio_change_cmd_source(gpio, bank, bindex,
 					      GPIO_CMDSRC_ARM);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);
@@ -1148,7 +1148,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->base))
 		return PTR_ERR(gpio->base);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
 	if (!gpio_id)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:17:59 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:17:59 -0500
Subject: [PATCH AUTOSEL 5.16 116/217] gpio: aspeed-sgpio: Convert
 aspeed_sgpio.lock to raw_spinlock
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-116-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit ab39d6988dd53f354130438d8afa5596a2440fed ]

The gpio-aspeed-sgpio driver implements an irq_chip which need to be
invoked from hardirq context. Since spin_lock() can sleep with
PREEMPT_RT, it is no longer legal to invoke it while interrupts are
disabled.
This also causes lockdep to complain about:
[   25.919465] [ BUG: Invalid wait context ]
because aspeed_sgpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed-sgpio.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
index b3a9b8488f11d..454cefbeecf0e 100644
--- a/drivers/gpio/gpio-aspeed-sgpio.c
+++ b/drivers/gpio/gpio-aspeed-sgpio.c
@@ -31,7 +31,7 @@ struct aspeed_sgpio {
 	struct gpio_chip chip;
 	struct irq_chip intc;
 	struct clk *pclk;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 };
@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
 	enum aspeed_sgpio_reg reg;
 	int rc = 0;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata;
 	rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
 	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
 	unsigned long flags;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	sgpio_set_value(gc, offset, val);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v
 	/* No special action is required for setting the direction; we'll
 	 * error-out in sgpio_set_value if this isn't an output GPIO */
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	rc = sgpio_set_value(gc, offset, val);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	iowrite32(bit, status_addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
 	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	if (set)
@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
 
 	iowrite32(reg, addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_mask(struct irq_data *d)
@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
 	reg = ioread32(addr);
@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
 	reg = (reg & ~bit) | type2;
 	iowrite32(reg, addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
 	reg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = readl(reg);
 
@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
 	writel(val, reg);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev)
 	iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval |
 		  ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio->chip.parent = &pdev->dev;
 	gpio->chip.ngpio = nr_gpios * 2;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:02 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:02 -0500
Subject: [PATCH AUTOSEL 5.16 119/217] arm64: dts: rockchip: Fix Bluetooth on
 ROCK Pi 4 boards
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-119-sashal@kernel.org>

From: Jagan Teki <jagan at amarulasolutions.com>

[ Upstream commit f471b1b2db0819917c54099ab68349ad6a7e9e19 ]

This patch fixes the Bluetooth on ROCK Pi 4 boards.

ROCK Pi 4 boards has BCM4345C5 and now it is supported
on Mainline Linux, brcm,bcm43438-bt still working but
observed the BT Audio issues with latest test.

So, use the BCM4345C5 compatible and its associated
properties like clock-names as lpo and max-speed.

Attach vbat and vddio supply rails as well.

Signed-off-by: Jagan Teki <jagan at amarulasolutions.com>
Link: https://lore.kernel.org/r/20211112142359.320798-1-jagan at amarulasolutions.com
Signed-off-by: Heiko Stuebner <heiko at sntech.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts | 7 +++++--
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts      | 7 +++++--
 arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts      | 7 +++++--
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
index dfad13d2ab249..5bd2b8db3d51a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b-plus.dts
@@ -35,13 +35,16 @@ &uart0 {
 	status = "okay";
 
 	bluetooth {
-		compatible = "brcm,bcm43438-bt";
+		compatible = "brcm,bcm4345c5";
 		clocks = <&rk808 1>;
-		clock-names = "ext_clock";
+		clock-names = "lpo";
 		device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
 		host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
 		shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+		max-speed = <1500000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+		vbat-supply = <&vcc3v3_sys>;
+		vddio-supply = <&vcc_1v8>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
index 6c63e617063c9..cf48746a3ad81 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4b.dts
@@ -34,13 +34,16 @@ &uart0 {
 	status = "okay";
 
 	bluetooth {
-		compatible = "brcm,bcm43438-bt";
+		compatible = "brcm,bcm4345c5";
 		clocks = <&rk808 1>;
-		clock-names = "ext_clock";
+		clock-names = "lpo";
 		device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
 		host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
 		shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+		max-speed = <1500000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+		vbat-supply = <&vcc3v3_sys>;
+		vddio-supply = <&vcc_1v8>;
 	};
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
index 99169bcd51c03..57ddf55ee6930 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4c.dts
@@ -35,14 +35,17 @@ &uart0 {
 	status = "okay";
 
 	bluetooth {
-		compatible = "brcm,bcm43438-bt";
+		compatible = "brcm,bcm4345c5";
 		clocks = <&rk808 1>;
-		clock-names = "ext_clock";
+		clock-names = "lpo";
 		device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
 		host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
 		shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+		max-speed = <1500000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+		vbat-supply = <&vcc3v3_sys>;
+		vddio-supply = <&vcc_1v8>;
 	};
 };
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:18 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:18 -0500
Subject: [PATCH AUTOSEL 5.16 135/217] media: rockchip: rkisp1: use device name
 for debugfs subdir name
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-135-sashal@kernel.org>

From: Mikhail Rudenko <mike.rudenko at gmail.com>

[ Upstream commit c2611e479f5d9b05108270e1ab423955486b4457 ]

While testing Rockchip RK3399 with both ISPs enabled, a dmesg error
was observed:
```
[   15.559141] debugfs: Directory 'rkisp1' with parent '/' already present!
```

Fix it by using the device name for the debugfs subdirectory name
instead of the driver name, thus preventing name collision.

Link: https://lore.kernel.org/linux-media/20211010175457.438627-1-mike.rudenko at gmail.com
Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 50b166c49a03a..3f5cfa7eb9372 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -462,7 +462,7 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
 {
 	struct rkisp1_debug *debug = &rkisp1->debug;
 
-	debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
+	debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL);
 	debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
 			     &debug->data_loss);
 	debugfs_create_ulong("outform_size_err", 0444,  debug->debugfs_dir,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:26 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:26 -0500
Subject: [PATCH AUTOSEL 5.16 143/217] arm64: dts: ls1028a-qds: move rtc node
 to the correct i2c bus
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-143-sashal@kernel.org>

From: Biwen Li <biwen.li at nxp.com>

[ Upstream commit cbe9d948eadfe352ad45495a7cc5bf20a1b29d90 ]

The i2c rtc is on i2c2 bus not i2c1 bus, so fix it in dts.

Signed-off-by: Biwen Li <biwen.li at nxp.com>
Signed-off-by: Li Yang <leoyang.lil at nxp.com>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 6e2a1da662fb4..4597848598df0 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -272,11 +272,6 @@ temperature-sensor at 4c {
 				vcc-supply = <&sb_3v3>;
 			};
 
-			rtc at 51 {
-				compatible = "nxp,pcf2129";
-				reg = <0x51>;
-			};
-
 			eeprom at 56 {
 				compatible = "atmel,24c512";
 				reg = <0x56>;
@@ -318,6 +313,15 @@ mux: mux-controller {
 
 };
 
+&i2c1 {
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf2129";
+		reg = <0x51>;
+	};
+};
+
 &enetc_port1 {
 	phy-handle = <&qds_phy1>;
 	phy-mode = "rgmii-id";
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:35 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:35 -0500
Subject: [PATCH AUTOSEL 5.16 152/217] mt76: mt7615: fix possible deadlock
 while mt7615_register_ext_phy()
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-152-sashal@kernel.org>

From: Peter Chiu <chui-hao.chiu at mediatek.com>

[ Upstream commit 8c55516de3f9b76b9d9444e7890682ec2efc809f ]

ieee80211_register_hw() is called with rtnl_lock held, and this could be
caused lockdep from a work item that's on a workqueue that is flushed
with the rtnl held.

Move mt7615_register_ext_phy() outside the init_work().

Signed-off-by: Peter Chiu <chui-hao.chiu at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
index a2465b49ecd0c..87b4aa52ee0f9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
@@ -28,8 +28,6 @@ static void mt7615_pci_init_work(struct work_struct *work)
 		return;
 
 	mt7615_init_work(dev);
-	if (dev->dbdc_support)
-		mt7615_register_ext_phy(dev);
 }
 
 static int mt7615_init_hardware(struct mt7615_dev *dev)
@@ -160,6 +158,12 @@ int mt7615_register_device(struct mt7615_dev *dev)
 	mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
 	mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
 
+	if (dev->dbdc_support) {
+		ret = mt7615_register_ext_phy(dev);
+		if (ret)
+			return ret;
+	}
+
 	return mt7615_init_debugfs(dev);
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:36 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:36 -0500
Subject: [PATCH AUTOSEL 5.16 153/217] mt76: mt7915: fix SMPS operation fail
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-153-sashal@kernel.org>

From: Ryder Lee <ryder.lee at mediatek.com>

[ Upstream commit 8f05835425ce3f669e4b6d7c2c39a9aa22e1506c ]

TGn fails sending SM power save mode action frame to the AP to switch
from dynamic SMPS mode to static mode.

Reported-by: Fang Zhao <fang.zhao at mediatek.com>
Signed-off-by: Fang Zhao <fang.zhao at mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7915/mcu.c   | 81 ++++++++++++-------
 .../net/wireless/mediatek/mt76/mt7915/mcu.h   |  8 ++
 2 files changed, 61 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index 852d5d97c70b1..8215b3d79bbdc 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -1752,33 +1752,6 @@ int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
 				     true);
 }
 
-int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-			struct ieee80211_sta *sta)
-{
-	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
-	struct wtbl_req_hdr *wtbl_hdr;
-	struct tlv *sta_wtbl;
-	struct sk_buff *skb;
-
-	skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
-				       MT7915_STA_UPDATE_MAX_SIZE);
-	if (IS_ERR(skb))
-		return PTR_ERR(skb);
-
-	sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
-
-	wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
-					     &skb);
-	if (IS_ERR(wtbl_hdr))
-		return PTR_ERR(wtbl_hdr);
-
-	mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
-
-	return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-				     MCU_EXT_CMD(STA_REC_UPDATE), true);
-}
-
 static inline bool
 mt7915_is_ebf_supported(struct mt7915_phy *phy, struct ieee80211_vif *vif,
 			struct ieee80211_sta *sta, bool bfee)
@@ -2049,6 +2022,21 @@ mt7915_mcu_sta_bfee_tlv(struct mt7915_dev *dev, struct sk_buff *skb,
 	bfee->fb_identity_matrix = (nrow == 1 && tx_ant == 2);
 }
 
+static enum mcu_mmps_mode
+mt7915_mcu_get_mmps_mode(enum ieee80211_smps_mode smps)
+{
+	switch (smps) {
+	case IEEE80211_SMPS_OFF:
+		return MCU_MMPS_DISABLE;
+	case IEEE80211_SMPS_STATIC:
+		return MCU_MMPS_STATIC;
+	case IEEE80211_SMPS_DYNAMIC:
+		return MCU_MMPS_DYNAMIC;
+	default:
+		return MCU_MMPS_DISABLE;
+	}
+}
+
 int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
 				   struct ieee80211_vif *vif,
 				   struct ieee80211_sta *sta,
@@ -2076,7 +2064,11 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
 	case RATE_PARAM_FIXED_MCS:
 	case RATE_PARAM_FIXED_GI:
 	case RATE_PARAM_FIXED_HE_LTF:
-		ra->phy = *phy;
+		if (phy)
+			ra->phy = *phy;
+		break;
+	case RATE_PARAM_MMPS_UPDATE:
+		ra->mmps_mode = mt7915_mcu_get_mmps_mode(sta->smps_mode);
 		break;
 	default:
 		break;
@@ -2087,6 +2079,39 @@ int mt7915_mcu_set_fixed_rate_ctrl(struct mt7915_dev *dev,
 				     MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
+int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+			struct ieee80211_sta *sta)
+{
+	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+	struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+	struct wtbl_req_hdr *wtbl_hdr;
+	struct tlv *sta_wtbl;
+	struct sk_buff *skb;
+	int ret;
+
+	skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta,
+				       MT7915_STA_UPDATE_MAX_SIZE);
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	sta_wtbl = mt7915_mcu_add_tlv(skb, STA_REC_WTBL, sizeof(struct tlv));
+
+	wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, sta_wtbl,
+					     &skb);
+	if (IS_ERR(wtbl_hdr))
+		return PTR_ERR(wtbl_hdr);
+
+	mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
+
+	ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+				    MCU_EXT_CMD(STA_REC_UPDATE), true);
+	if (ret)
+		return ret;
+
+	return mt7915_mcu_set_fixed_rate_ctrl(dev, vif, sta, NULL,
+					      RATE_PARAM_MMPS_UPDATE);
+}
+
 static int
 mt7915_mcu_add_rate_ctrl_fixed(struct mt7915_dev *dev,
 			       struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
index 1f5a64ba9b59d..628e90d0c394e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
@@ -365,6 +365,13 @@ enum {
 	MCU_PHY_STATE_OFDMLQ_CNINFO,
 };
 
+enum mcu_mmps_mode {
+	MCU_MMPS_STATIC,
+	MCU_MMPS_DYNAMIC,
+	MCU_MMPS_RSV,
+	MCU_MMPS_DISABLE,
+};
+
 #define STA_TYPE_STA			BIT(0)
 #define STA_TYPE_AP			BIT(1)
 #define STA_TYPE_ADHOC			BIT(2)
@@ -960,6 +967,7 @@ struct sta_rec_ra_fixed {
 
 enum {
 	RATE_PARAM_FIXED = 3,
+	RATE_PARAM_MMPS_UPDATE = 5,
 	RATE_PARAM_FIXED_HE_LTF = 7,
 	RATE_PARAM_FIXED_MCS,
 	RATE_PARAM_FIXED_GI = 11,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:37 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:37 -0500
Subject: [PATCH AUTOSEL 5.16 154/217] mt76: connac: fix a theoretical NULL
 pointer dereference in mt76_connac_get_phy_mode
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-154-sashal@kernel.org>

From: Lorenzo Bianconi <lorenzo at kernel.org>

[ Upstream commit c9dbeac4988f6d4c4211b3747ec9c9c75ea87967 ]

Even if it is not a real bug since mt76_connac_get_phy_mode runs just
for mt7921 where only STA is supported, fix a theoretical NULL pointer
dereference if new added modes do not support HE

Signed-off-by: Lorenzo Bianconi <lorenzo at kernel.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 26b4b875dcc02..bcb596664b3e9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1179,7 +1179,7 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
 		if (ht_cap->ht_supported)
 			mode |= PHY_MODE_GN;
 
-		if (he_cap->has_he)
+		if (he_cap && he_cap->has_he)
 			mode |= PHY_MODE_AX_24G;
 	} else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
 		mode |= PHY_MODE_A;
@@ -1190,7 +1190,7 @@ mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
 		if (vht_cap->vht_supported)
 			mode |= PHY_MODE_AC;
 
-		if (he_cap->has_he) {
+		if (he_cap && he_cap->has_he) {
 			if (band == NL80211_BAND_6GHZ)
 				mode |= PHY_MODE_AX_6G;
 			else
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:38 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:38 -0500
Subject: [PATCH AUTOSEL 5.16 155/217] mt76: do not pass the received frame
 with decryption error
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-155-sashal@kernel.org>

From: Xing Song <xing.song at mediatek.com>

[ Upstream commit dd28dea52ad9376d2b243a8981726646e1f60b1a ]

MAC80211 doesn't care any decryption error in 802.3 path, so received
frame will be dropped if HW tell us that the cipher configuration is not
matched as well as the header has been translated to 802.3. This case only
appears when IEEE80211_FCTL_PROTECTED is 0 and cipher suit is not none in
the corresponding HW entry.

The received frame is only reported to monitor interface if HW decryption
block tell us there is ICV error or CCMP/BIP/WPI MIC error. Note in this
case the reported frame is decrypted 802.11 frame and the payload may be
malformed due to mismatched key.

Signed-off-by: Xing Song <xing.song at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 4 ++++
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 9 ++++++++-
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 ++++++++-
 drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 9 ++++++++-
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index fe03e31989bb1..a9ac61b9f854a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -525,6 +525,10 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_TKIP_MIC_ERR)
 		status->flag |= RX_FLAG_MMIC_ERROR;
 
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
 	    !(rxd2 & (MT_RXD2_NORMAL_CLM | MT_RXD2_NORMAL_CM))) {
 		status->flag |= RX_FLAG_DECRYPTED;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 423f69015e3ec..c79abce543f3b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -286,9 +286,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	unicast = (rxd1 & MT_RXD1_NORMAL_ADDR_TYPE) == MT_RXD1_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2);
-	hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
 	status->wcid = mt7615_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index 809dc18e5083c..38d66411444a1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -426,9 +426,16 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
 	status->wcid = mt7915_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index db3302b1576a0..27550385c35f9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -428,10 +428,17 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3);
 	unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
 	status->wcid = mt7921_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:39 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:39 -0500
Subject: [PATCH AUTOSEL 5.16 156/217] mt76: mt7615: improve wmm index
 allocation
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-156-sashal@kernel.org>

From: Felix Fietkau <nbd at nbd.name>

[ Upstream commit 70fb028707c8871ef9e56b3ffa3d895e14956cc4 ]

Typically all AP interfaces on a PHY will share the same WMM settings, while
sta/mesh interfaces will usually inherit the settings from a remote device.
In order minimize the likelihood of conflicting WMM settings, make all AP
interfaces share one slot, and all non-AP interfaces another one.

This also fixes running multiple AP interfaces on MT7613, which only has 3
WMM slots.

Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/main.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 890d9b07e1563..b308d5ab5f9a6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -211,11 +211,9 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
 	mvif->mt76.omac_idx = idx;
 
 	mvif->mt76.band_idx = ext_phy;
-	if (mt7615_ext_phy(dev))
-		mvif->mt76.wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) +
-				mvif->mt76.idx % (MT7615_MAX_WMM_SETS / 2);
-	else
-		mvif->mt76.wmm_idx = mvif->mt76.idx % MT7615_MAX_WMM_SETS;
+	mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
+	if (ext_phy)
+		mvif->mt76.wmm_idx += 2;
 
 	dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
 	dev->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:18:40 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:18:40 -0500
Subject: [PATCH AUTOSEL 5.16 157/217] mt76: mt7921: fix network buffer leak by
 txs missing
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-157-sashal@kernel.org>

From: Deren Wu <deren.wu at mediatek.com>

[ Upstream commit e0bf699ad8e52330d848144a9624a067ad588bd6 ]

TXS in mt7921 may be forwared to tx_done event. Should try to catch
TXS information in tx_done event as well.

Signed-off-by: Deren Wu <deren.wu at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 .../net/wireless/mediatek/mt76/mt7921/mac.c   |  2 +-
 .../net/wireless/mediatek/mt76/mt7921/mcu.c   | 14 ++++++++++
 .../net/wireless/mediatek/mt76/mt7921/mcu.h   | 27 +++++++++++++++++++
 .../wireless/mediatek/mt76/mt7921/mt7921.h    |  1 +
 4 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 27550385c35f9..4df272f93dd47 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1072,7 +1072,7 @@ mt7921_mac_add_txs_skb(struct mt7921_dev *dev, struct mt76_wcid *wcid, int pid,
 	return !!skb;
 }
 
-static void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)
 {
 	struct mt7921_sta *msta = NULL;
 	struct mt76_wcid *wcid;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 6ada1ebe7d68b..46ec9f713d772 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -418,6 +418,17 @@ mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
 	trace_lp_event(dev, event->state);
 }
 
+static void
+mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
+{
+	struct mt7921_mcu_tx_done_event *event;
+
+	skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
+	event = (struct mt7921_mcu_tx_done_event *)skb->data;
+
+	mt7921_mac_add_txs(dev, event->txs);
+}
+
 static void
 mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
 {
@@ -445,6 +456,9 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
 	case MCU_EVENT_LP_INFO:
 		mt7921_mcu_low_power_event(dev, skb);
 		break;
+	case MCU_EVENT_TX_DONE:
+		mt7921_mcu_tx_done_event(dev, skb);
+		break;
 	default:
 		break;
 	}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
index edc0c73f8c01c..68cb0ce013dbd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.h
@@ -91,6 +91,33 @@ enum {
 	MCU_EVENT_COREDUMP = 0xf0,
 };
 
+struct mt7921_mcu_tx_done_event {
+	u8 pid;
+	u8 status;
+	__le16 seq;
+
+	u8 wlan_idx;
+	u8 tx_cnt;
+	__le16 tx_rate;
+
+	u8 flag;
+	u8 tid;
+	u8 rsp_rate;
+	u8 mcs;
+
+	u8 bw;
+	u8 tx_pwr;
+	u8 reason;
+	u8 rsv0[1];
+
+	__le32 delay;
+	__le32 timestamp;
+	__le32 applied_flag;
+	u8 txs[28];
+
+	u8 rsv1[32];
+} __packed;
+
 /* ext event table */
 enum {
 	MCU_EXT_EVENT_RATE_REPORT = 0x87,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index e9c7c3a195076..7a6c38fbb940a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -463,4 +463,5 @@ int mt7921s_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
 			   struct mt76_tx_info *tx_info);
 void mt7921s_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue_entry *e);
 bool mt7921s_tx_status_data(struct mt76_dev *mdev, u8 *update);
+void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data);
 #endif
-- 
2.34.1



From rex-bc.chen at mediatek.com  Mon Jan 17 18:29:15 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Tue, 18 Jan 2022 10:29:15 +0800
Subject: [v9,2/3] drm/mediatek: implement the DSI hs packets aligned
In-Reply-To: <86b76e9f-96b0-7d54-bd38-449745e30aa2@intel.com>
References: <20220114092110.12137-1-rex-bc.chen@mediatek.com>
 <20220114092110.12137-3-rex-bc.chen@mediatek.com>
 <4076cb55-4546-6bbd-1a1f-19395dcd9ccd@collabora.com>
 <f858dd4aaa35fa3eb969baf887f038c3593232e5.camel@mediatek.com>
 <86b76e9f-96b0-7d54-bd38-449745e30aa2@intel.com>
Message-ID: <1bd816c2f26cd8e42debf066a57e24eb5e2f580d.camel@mediatek.com>

Hello Andrzej,

Thanks for your review.
I will give the explanation for this in next version.

BRs,
Rex-BC hen

On Fri, 2022-01-14 at 12:11 +0100, Andrzej Hajda wrote:
> On 14.01.2022 11:20, Rex-BC Chen wrote:
> > Hello AngeloGioacchino,
> > 
> > Thanks for your review.
> > I will modify this in next version.
> > 
> > BRs,
> > Rex-BC Chen
> > 
> > On Fri, 2022-01-14 at 10:36 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Il 14/01/22 10:21, Rex-BC Chen ha scritto:
> > > > Some DSI RX devices require the packets on all lanes aligned at
> > > > the
> > > > end.
> > > > Otherwise, there will be some issues of shift or scroll for
> > > > screen.
> > > > 
> > > > Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> > > > Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> > > 
> > > Hello,
> > > thanks for the patch! However, there's something to improve...
> > > 
> > > > ---
> > > >    drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
> > > >    1 file changed, 12 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > > b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > > index 5d90d2eb0019..ccdda15f5a66 100644
> > > > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > > > @@ -195,6 +195,8 @@ struct mtk_dsi {
> > > >    	struct clk *hs_clk;
> > > >    
> > > >    	u32 data_rate;
> > > > +	/* force dsi line end without dsi_null data */
> > > > +	bool hs_packet_end_aligned;
> > > 
> > > There's no need to introduce a new variable here...
> > > >    
> > > >    	unsigned long mode_flags;
> > > >    	enum mipi_dsi_pixel_format format;
> > > > @@ -500,6 +502,13 @@ static void
> > > > mtk_dsi_config_vdo_timing(struct
> > > > mtk_dsi *dsi)
> > > >    		DRM_WARN("HFP + HBP less than d-phy, FPS will
> > > > under
> > > > 60Hz\n");
> > > >    	}
> > > >    
> > > > +	if (dsi->hs_packet_end_aligned) {
> > > 
> > > You can simply check mode_flags here:
> > > 	if (dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) {
> > > 
> > > > +		horizontal_sync_active_byte =
> > > > roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> > > > +		horizontal_frontporch_byte =
> > > > roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> > > > +		horizontal_backporch_byte =
> > > > roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> > > > +		horizontal_backporch_byte -= (vm->hactive *
> > > > dsi_tmp_buf_bpp + 2) % dsi->lanes;
> > > > +	}
> > > > +
> 
> 
> And if you could add comment explaining the magic here it would be
> nice.
> 
> 
> Regards
> 
> Andrzej
> 
> 
> > > >    	writel(horizontal_sync_active_byte, dsi->regs +
> > > > DSI_HSA_WC);
> > > >    	writel(horizontal_backporch_byte, dsi->regs +
> > > > DSI_HBP_WC);
> > > >    	writel(horizontal_frontporch_byte, dsi->regs +
> > > > DSI_HFP_WC);
> > > > @@ -794,6 +803,9 @@ static int mtk_dsi_host_attach(struct
> > > > mipi_dsi_host *host,
> > > >    	dsi->lanes = device->lanes;
> > > >    	dsi->format = device->format;
> > > >    	dsi->mode_flags = device->mode_flags;
> > > > +	dsi->hs_packet_end_aligned = (dsi->mode_flags &
> > > > +				      MIPI_DSI_HS_PKT_END_ALIGN
> > > > ED)
> > > > +				     ? true : false;
> > > 
> > > ...so there's no need for this one, either.
> > > 
> > > >    
> > > >    	return 0;
> > > >    }
> > > > 
> > > 
> > > Regards,
> > > - Angelo
> > > 



From sashal at kernel.org  Mon Jan 17 18:19:07 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:19:07 -0500
Subject: [PATCH AUTOSEL 5.16 184/217] mmc: mtk-sd: Use readl_poll_timeout
 instead of open-coded polling
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-184-sashal@kernel.org>

From: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

[ Upstream commit ffaea6ebfe9ce06ebb3a54811a47688f2b0893cd ]

Replace all instances of open-coded while loops for polling registers
with calls to readl_poll_timeout() and, while at it, also fix some
possible infinite loop instances.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20211216125748.179602-1-angelogioacchino.delregno at collabora.com
Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/mmc/host/mtk-sd.c | 64 ++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 632775217d35c..d5a9c269d4926 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -636,12 +636,11 @@ static void msdc_reset_hw(struct msdc_host *host)
 	u32 val;
 
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
-	while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST)
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
 
 	sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
-	while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR)
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_FIFOCS, val,
+			   !(val & MSDC_FIFOCS_CLR), 0, 0);
 
 	val = readl(host->base + MSDC_INT);
 	writel(val, host->base + MSDC_INT);
@@ -814,8 +813,9 @@ static void msdc_gate_clock(struct msdc_host *host)
 	clk_disable_unprepare(host->h_clk);
 }
 
-static void msdc_ungate_clock(struct msdc_host *host)
+static int msdc_ungate_clock(struct msdc_host *host)
 {
+	u32 val;
 	int ret;
 
 	clk_prepare_enable(host->h_clk);
@@ -825,11 +825,11 @@ static void msdc_ungate_clock(struct msdc_host *host)
 	ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
 	if (ret) {
 		dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
-		return;
+		return ret;
 	}
 
-	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
-		cpu_relax();
+	return readl_poll_timeout(host->base + MSDC_CFG, val,
+				  (val & MSDC_CFG_CKSTB), 1, 20000);
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -840,6 +840,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	u32 div;
 	u32 sclk;
 	u32 tune_reg = host->dev_comp->pad_tune_reg;
+	u32 val;
 
 	if (!hz) {
 		dev_dbg(host->dev, "set mclk to 0\n");
@@ -920,8 +921,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	else
 		clk_prepare_enable(clk_get_parent(host->src_clk));
 
-	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_CFG, val, (val & MSDC_CFG_CKSTB), 0, 0);
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	mmc->actual_clock = sclk;
 	host->mclk = hz;
@@ -1231,13 +1231,13 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 static inline bool msdc_cmd_is_ready(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd)
 {
-	/* The max busy time we can endure is 20ms */
-	unsigned long tmo = jiffies + msecs_to_jiffies(20);
+	u32 val;
+	int ret;
 
-	while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
-			time_before(jiffies, tmo))
-		cpu_relax();
-	if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
+	/* The max busy time we can endure is 20ms */
+	ret = readl_poll_timeout_atomic(host->base + SDC_STS, val,
+					!(val & SDC_STS_CMDBUSY), 1, 20000);
+	if (ret) {
 		dev_err(host->dev, "CMD bus busy detected\n");
 		host->error |= REQ_CMD_BUSY;
 		msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
@@ -1245,12 +1245,10 @@ static inline bool msdc_cmd_is_ready(struct msdc_host *host,
 	}
 
 	if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
-		tmo = jiffies + msecs_to_jiffies(20);
 		/* R1B or with data, should check SDCBUSY */
-		while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
-				time_before(jiffies, tmo))
-			cpu_relax();
-		if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
+		ret = readl_poll_timeout_atomic(host->base + SDC_STS, val,
+						!(val & SDC_STS_SDCBUSY), 1, 20000);
+		if (ret) {
 			dev_err(host->dev, "Controller busy detected\n");
 			host->error |= REQ_CMD_BUSY;
 			msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
@@ -1376,6 +1374,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 	    (MSDC_INT_XFER_COMPL | MSDC_INT_DATCRCERR | MSDC_INT_DATTMO
 	     | MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR
 	     | MSDC_INT_DMA_PROTECT);
+	u32 val;
+	int ret;
 
 	spin_lock_irqsave(&host->lock, flags);
 	done = !host->data;
@@ -1392,8 +1392,14 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 				readl(host->base + MSDC_DMA_CFG));
 		sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP,
 				1);
-		while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
-			cpu_relax();
+
+		ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val,
+						!(val & MSDC_DMA_CFG_STS), 1, 20000);
+		if (ret) {
+			dev_dbg(host->dev, "DMA stop timed out\n");
+			return false;
+		}
+
 		sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask);
 		dev_dbg(host->dev, "DMA stop\n");
 
@@ -2674,7 +2680,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	platform_set_drvdata(pdev, mmc);
-	msdc_ungate_clock(host);
+	ret = msdc_ungate_clock(host);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot ungate clocks!\n");
+		goto release_mem;
+	}
 	msdc_init_hw(host);
 
 	if (mmc->caps2 & MMC_CAP2_CQE) {
@@ -2833,8 +2843,12 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
+	int ret;
+
+	ret = msdc_ungate_clock(host);
+	if (ret)
+		return ret;
 
-	msdc_ungate_clock(host);
 	msdc_restore_reg(host);
 	return 0;
 }
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:19:21 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:19:21 -0500
Subject: [PATCH AUTOSEL 5.16 198/217] can: do not increase rx statistics when
 generating a CAN rx error message frame
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-198-sashal@kernel.org>

From: Vincent Mailhol <mailhol.vincent at wanadoo.fr>

[ Upstream commit 676068db69b847f06fe054fca15bf6b107bd24da ]

The CAN error message frames (i.e. error skb) are an interface
specific to socket CAN. The payload of the CAN error message frames
does not correspond to any actual data sent on the wire. Only an error
flag and a delimiter are transmitted when an error occurs (c.f. ISO
11898-1 section 10.4.4.2 "Error flag").

For this reason, it makes no sense to increment the rx_packets and
rx_bytes fields of struct net_device_stats because no actual payload
were transmitted on the wire.

This patch fixes all the CAN drivers.

Link: https://lore.kernel.org/all/20211207121531.42941-2-mailhol.vincent at wanadoo.fr
CC: Marc Kleine-Budde <mkl at pengutronix.de>
CC: Nicolas Ferre <nicolas.ferre at microchip.com>
CC: Alexandre Belloni <alexandre.belloni at bootlin.com>
CC: Ludovic Desroches <ludovic.desroches at microchip.com>
CC: Chandrasekar Ramakrishnan <rcsekar at samsung.com>
CC: Maxime Ripard <mripard at kernel.org>
CC: Chen-Yu Tsai <wens at csie.org>
CC: Jernej Skrabec <jernej.skrabec at gmail.com>
CC: Appana Durga Kedareswara rao <appana.durga.rao at xilinx.com>
CC: Naga Sureshkumar Relli <naga.sureshkumar.relli at xilinx.com>
CC: Michal Simek <michal.simek at xilinx.com>
CC: Stephane Grosjean <s.grosjean at peak-system.com>
Tested-by: Jimmy Assarsson <extja at kvaser.com> # kvaser
Signed-off-by: Vincent Mailhol <mailhol.vincent at wanadoo.fr>
Acked-by: Stefan M?tje <stefan.maetje at esd.eu> # esd_usb2
Tested-by: Stefan M?tje <stefan.maetje at esd.eu> # esd_usb2
Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/can/at91_can.c                        | 6 ------
 drivers/net/can/c_can/c_can_main.c                | 5 -----
 drivers/net/can/cc770/cc770.c                     | 3 ---
 drivers/net/can/dev/dev.c                         | 4 ----
 drivers/net/can/dev/rx-offload.c                  | 6 ++++--
 drivers/net/can/ifi_canfd/ifi_canfd.c             | 5 -----
 drivers/net/can/kvaser_pciefd.c                   | 5 -----
 drivers/net/can/m_can/m_can.c                     | 7 -------
 drivers/net/can/mscan/mscan.c                     | 9 +++++----
 drivers/net/can/pch_can.c                         | 3 ---
 drivers/net/can/peak_canfd/peak_canfd.c           | 4 ----
 drivers/net/can/rcar/rcar_can.c                   | 6 +-----
 drivers/net/can/rcar/rcar_canfd.c                 | 4 ----
 drivers/net/can/sja1000/sja1000.c                 | 2 --
 drivers/net/can/sun4i_can.c                       | 7 ++-----
 drivers/net/can/usb/ems_usb.c                     | 2 --
 drivers/net/can/usb/esd_usb2.c                    | 2 --
 drivers/net/can/usb/etas_es58x/es58x_core.c       | 7 -------
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c  | 2 --
 drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 8 --------
 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c  | 4 ----
 drivers/net/can/usb/peak_usb/pcan_usb.c           | 2 --
 drivers/net/can/usb/peak_usb/pcan_usb_fd.c        | 3 ---
 drivers/net/can/usb/peak_usb/pcan_usb_pro.c       | 2 --
 drivers/net/can/usb/ucan.c                        | 6 ++++--
 drivers/net/can/usb/usb_8dev.c                    | 2 --
 drivers/net/can/xilinx_can.c                      | 9 +--------
 27 files changed, 17 insertions(+), 108 deletions(-)

diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 3aea32c9b108f..3cd872cf9be66 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -553,8 +553,6 @@ static void at91_rx_overflow_err(struct net_device *dev)
 	cf->can_id |= CAN_ERR_CRTL;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_receive_skb(skb);
 }
 
@@ -779,8 +777,6 @@ static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
 
 	at91_poll_err_frame(dev, cf, reg_sr);
 
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += cf->len;
 	netif_receive_skb(skb);
 
 	return 1;
@@ -1037,8 +1033,6 @@ static void at91_irq_err(struct net_device *dev)
 
 	at91_irq_err_state(dev, cf, new_state);
 
-	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += cf->len;
 	netif_rx(skb);
 
 	priv->can.state = new_state;
diff --git a/drivers/net/can/c_can/c_can_main.c b/drivers/net/can/c_can/c_can_main.c
index 52671d1ea17d5..670754a129846 100644
--- a/drivers/net/can/c_can/c_can_main.c
+++ b/drivers/net/can/c_can/c_can_main.c
@@ -920,7 +920,6 @@ static int c_can_handle_state_change(struct net_device *dev,
 	unsigned int reg_err_counter;
 	unsigned int rx_err_passive;
 	struct c_can_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
 	struct can_berr_counter bec;
@@ -996,8 +995,6 @@ static int c_can_handle_state_change(struct net_device *dev,
 		break;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_receive_skb(skb);
 
 	return 1;
@@ -1064,8 +1061,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
 		break;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_receive_skb(skb);
 	return 1;
 }
diff --git a/drivers/net/can/cc770/cc770.c b/drivers/net/can/cc770/cc770.c
index f8a130f594e2e..a5fd8ccedec21 100644
--- a/drivers/net/can/cc770/cc770.c
+++ b/drivers/net/can/cc770/cc770.c
@@ -499,7 +499,6 @@ static void cc770_rx(struct net_device *dev, unsigned int mo, u8 ctrl1)
 static int cc770_err(struct net_device *dev, u8 status)
 {
 	struct cc770_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
 	u8 lec;
@@ -571,8 +570,6 @@ static int cc770_err(struct net_device *dev, u8 status)
 	}
 
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index e3d840b81357d..4845ae6456e19 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -136,7 +136,6 @@ EXPORT_SYMBOL_GPL(can_change_state);
 static void can_restart(struct net_device *dev)
 {
 	struct can_priv *priv = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct sk_buff *skb;
 	struct can_frame *cf;
 	int err;
@@ -155,9 +154,6 @@ static void can_restart(struct net_device *dev)
 
 	cf->can_id |= CAN_ERR_RESTARTED;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
-
 	netif_rx_ni(skb);
 
 restart:
diff --git a/drivers/net/can/dev/rx-offload.c b/drivers/net/can/dev/rx-offload.c
index 37b0cc65237b7..7dbf46b9ca5dd 100644
--- a/drivers/net/can/dev/rx-offload.c
+++ b/drivers/net/can/dev/rx-offload.c
@@ -54,8 +54,10 @@ static int can_rx_offload_napi_poll(struct napi_struct *napi, int quota)
 		struct can_frame *cf = (struct can_frame *)skb->data;
 
 		work_done++;
-		stats->rx_packets++;
-		stats->rx_bytes += cf->len;
+		if (!(cf->can_id & CAN_ERR_FLAG)) {
+			stats->rx_packets++;
+			stats->rx_bytes += cf->len;
+		}
 		netif_receive_skb(skb);
 	}
 
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c
index 5bb957a26bc69..e8318e984bf2f 100644
--- a/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ b/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -430,8 +430,6 @@ static int ifi_canfd_handle_lec_err(struct net_device *ndev)
 	       priv->base + IFI_CANFD_INTERRUPT);
 	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_receive_skb(skb);
 
 	return 1;
@@ -456,7 +454,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
 					 enum can_state new_state)
 {
 	struct ifi_canfd_priv *priv = netdev_priv(ndev);
-	struct net_device_stats *stats = &ndev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
 	struct can_berr_counter bec;
@@ -522,8 +519,6 @@ static int ifi_canfd_handle_state_change(struct net_device *ndev,
 		break;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_receive_skb(skb);
 
 	return 1;
diff --git a/drivers/net/can/kvaser_pciefd.c b/drivers/net/can/kvaser_pciefd.c
index eb74cdf26b88c..ab672c92ab078 100644
--- a/drivers/net/can/kvaser_pciefd.c
+++ b/drivers/net/can/kvaser_pciefd.c
@@ -1310,9 +1310,6 @@ static int kvaser_pciefd_rx_error_frame(struct kvaser_pciefd_can *can,
 	cf->data[6] = bec.txerr;
 	cf->data[7] = bec.rxerr;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
-
 	netif_rx(skb);
 	return 0;
 }
@@ -1510,8 +1507,6 @@ static void kvaser_pciefd_handle_nack_packet(struct kvaser_pciefd_can *can,
 
 	if (skb) {
 		cf->can_id |= CAN_ERR_BUSERROR;
-		stats->rx_bytes += cf->len;
-		stats->rx_packets++;
 		netif_rx(skb);
 	} else {
 		stats->rx_dropped++;
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index c2a8421e7845c..30d94cb43113d 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -647,9 +647,6 @@ static int m_can_handle_lec_err(struct net_device *dev,
 		break;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
-
 	if (cdev->is_peripheral)
 		timestamp = m_can_get_timestamp(cdev);
 
@@ -706,7 +703,6 @@ static int m_can_handle_state_change(struct net_device *dev,
 				     enum can_state new_state)
 {
 	struct m_can_classdev *cdev = netdev_priv(dev);
-	struct net_device_stats *stats = &dev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
 	struct can_berr_counter bec;
@@ -771,9 +767,6 @@ static int m_can_handle_state_change(struct net_device *dev,
 		break;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
-
 	if (cdev->is_peripheral)
 		timestamp = m_can_get_timestamp(cdev);
 
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index fa32e418eb296..9e1cce0260da6 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -401,13 +401,14 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota)
 			continue;
 		}
 
-		if (canrflg & MSCAN_RXF)
+		if (canrflg & MSCAN_RXF) {
 			mscan_get_rx_frame(dev, frame);
-		else if (canrflg & MSCAN_ERR_IF)
+			stats->rx_packets++;
+			stats->rx_bytes += frame->len;
+		} else if (canrflg & MSCAN_ERR_IF) {
 			mscan_get_err_frame(dev, frame, canrflg);
+		}
 
-		stats->rx_packets++;
-		stats->rx_bytes += frame->len;
 		work_done++;
 		netif_receive_skb(skb);
 	}
diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c
index 964c8a09226a9..6b45840db1f9b 100644
--- a/drivers/net/can/pch_can.c
+++ b/drivers/net/can/pch_can.c
@@ -561,9 +561,6 @@ static void pch_can_error(struct net_device *ndev, u32 status)
 
 	priv->can.state = state;
 	netif_receive_skb(skb);
-
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 }
 
 static irqreturn_t pch_can_interrupt(int irq, void *dev_id)
diff --git a/drivers/net/can/peak_canfd/peak_canfd.c b/drivers/net/can/peak_canfd/peak_canfd.c
index d08718e98e110..d5b8bc6d29804 100644
--- a/drivers/net/can/peak_canfd/peak_canfd.c
+++ b/drivers/net/can/peak_canfd/peak_canfd.c
@@ -409,8 +409,6 @@ static int pucan_handle_status(struct peak_canfd_priv *priv,
 		return -ENOMEM;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	pucan_netif_rx(skb, msg->ts_low, msg->ts_high);
 
 	return 0;
@@ -438,8 +436,6 @@ static int pucan_handle_cache_critical(struct peak_canfd_priv *priv)
 	cf->data[6] = priv->bec.txerr;
 	cf->data[7] = priv->bec.rxerr;
 
-	stats->rx_bytes += cf->len;
-	stats->rx_packets++;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/rcar/rcar_can.c b/drivers/net/can/rcar/rcar_can.c
index 8999ec9455ec2..f408ed9a6ccd1 100644
--- a/drivers/net/can/rcar/rcar_can.c
+++ b/drivers/net/can/rcar/rcar_can.c
@@ -223,7 +223,6 @@ static void tx_failure_cleanup(struct net_device *ndev)
 static void rcar_can_error(struct net_device *ndev)
 {
 	struct rcar_can_priv *priv = netdev_priv(ndev);
-	struct net_device_stats *stats = &ndev->stats;
 	struct can_frame *cf;
 	struct sk_buff *skb;
 	u8 eifr, txerr = 0, rxerr = 0;
@@ -362,11 +361,8 @@ static void rcar_can_error(struct net_device *ndev)
 		}
 	}
 
-	if (skb) {
-		stats->rx_packets++;
-		stats->rx_bytes += cf->len;
+	if (skb)
 		netif_rx(skb);
-	}
 }
 
 static void rcar_can_tx_done(struct net_device *ndev)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c
index ff9d0f5ae0dd2..db9d62874e151 100644
--- a/drivers/net/can/rcar/rcar_canfd.c
+++ b/drivers/net/can/rcar/rcar_canfd.c
@@ -1033,8 +1033,6 @@ static void rcar_canfd_error(struct net_device *ndev, u32 cerfl,
 	/* Clear channel error interrupts that are handled */
 	rcar_canfd_write(priv->base, RCANFD_CERFL(ch),
 			 RCANFD_CERFL_ERR(~cerfl));
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
@@ -1174,8 +1172,6 @@ static void rcar_canfd_state_change(struct net_device *ndev,
 		rx_state = txerr <= rxerr ? state : 0;
 
 		can_change_state(ndev, cf, tx_state, rx_state);
-		stats->rx_packets++;
-		stats->rx_bytes += cf->len;
 		netif_rx(skb);
 	}
 }
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 3fad546467461..a65546ca94610 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -487,8 +487,6 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
 			can_bus_off(dev);
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/sun4i_can.c b/drivers/net/can/sun4i_can.c
index 54aa7c25c4de1..599174098883d 100644
--- a/drivers/net/can/sun4i_can.c
+++ b/drivers/net/can/sun4i_can.c
@@ -622,13 +622,10 @@ static int sun4i_can_err(struct net_device *dev, u8 isrc, u8 status)
 			can_bus_off(dev);
 	}
 
-	if (likely(skb)) {
-		stats->rx_packets++;
-		stats->rx_bytes += cf->len;
+	if (likely(skb))
 		netif_rx(skb);
-	} else {
+	else
 		return -ENOMEM;
-	}
 
 	return 0;
 }
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index 2b5302e724353..7cf65936d02e5 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -397,8 +397,6 @@ static void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg)
 		stats->rx_errors++;
 	}
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c
index c6068a251fbed..5f6915a27b3d9 100644
--- a/drivers/net/can/usb/esd_usb2.c
+++ b/drivers/net/can/usb/esd_usb2.c
@@ -293,8 +293,6 @@ static void esd_usb2_rx_event(struct esd_usb2_net_priv *priv,
 		priv->bec.txerr = txerr;
 		priv->bec.rxerr = rxerr;
 
-		stats->rx_packets++;
-		stats->rx_bytes += cf->len;
 		netif_rx(skb);
 	}
 }
diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
index 24627ab146261..fb07c33ba0c3c 100644
--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
+++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
@@ -849,13 +849,6 @@ int es58x_rx_err_msg(struct net_device *netdev, enum es58x_err error,
 		break;
 	}
 
-	/* driver/net/can/dev.c:can_restart() takes in account error
-	 * messages in the RX stats. Doing the same here for
-	 * consistency.
-	 */
-	netdev->stats.rx_packets++;
-	netdev->stats.rx_bytes += CAN_ERR_DLC;
-
 	if (cf) {
 		if (cf->data[1])
 			cf->can_id |= CAN_ERR_CRTL;
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
index 0cc0fc866a2a9..3e682ef43f8ef 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -279,8 +279,6 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev)
 	cf->can_id |= CAN_ERR_CRTL;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
index dcee8dc828ecc..3398da323126c 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c
@@ -869,7 +869,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
 	struct net_device *netdev = priv->netdev;
 	struct can_frame *cf;
 	struct sk_buff *skb;
-	struct net_device_stats *stats;
 	enum can_state new_state, old_state;
 
 	old_state = priv->can.state;
@@ -919,9 +918,6 @@ static void kvaser_usb_hydra_update_state(struct kvaser_usb_net_priv *priv,
 	cf->data[6] = bec->txerr;
 	cf->data[7] = bec->rxerr;
 
-	stats = &netdev->stats;
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
@@ -1074,8 +1070,6 @@ kvaser_usb_hydra_error_frame(struct kvaser_usb_net_priv *priv,
 	cf->data[6] = bec.txerr;
 	cf->data[7] = bec.rxerr;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 
 	priv->bec.txerr = bec.txerr;
@@ -1109,8 +1103,6 @@ static void kvaser_usb_hydra_one_shot_fail(struct kvaser_usb_net_priv *priv,
 	}
 
 	stats->tx_errors++;
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
index f7af1bf5ab46d..5434b7386a51e 100644
--- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
+++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c
@@ -641,8 +641,6 @@ static void kvaser_usb_leaf_tx_acknowledge(const struct kvaser_usb *dev,
 		if (skb) {
 			cf->can_id |= CAN_ERR_RESTARTED;
 
-			stats->rx_packets++;
-			stats->rx_bytes += cf->len;
 			netif_rx(skb);
 		} else {
 			netdev_err(priv->netdev,
@@ -843,8 +841,6 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev,
 	cf->data[6] = es->txerr;
 	cf->data[7] = es->rxerr;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb.c b/drivers/net/can/usb/peak_usb/pcan_usb.c
index 8762187527669..21b06a7385959 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
@@ -520,8 +520,6 @@ static int pcan_usb_decode_error(struct pcan_usb_msg_context *mc, u8 n,
 				     &hwts->hwtstamp);
 	}
 
-	mc->netdev->stats.rx_packets++;
-	mc->netdev->stats.rx_bytes += cf->len;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 6bd12549f1014..185f5a98d2177 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -577,9 +577,6 @@ static int pcan_usb_fd_decode_status(struct pcan_usb_fd_if *usb_if,
 	if (!skb)
 		return -ENOMEM;
 
-	netdev->stats.rx_packets++;
-	netdev->stats.rx_bytes += cf->len;
-
 	peak_usb_netif_rx_64(skb, le32_to_cpu(sm->ts_low),
 			     le32_to_cpu(sm->ts_high));
 
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 858ab22708fcd..f6d19879bf404 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -660,8 +660,6 @@ static int pcan_usb_pro_handle_error(struct pcan_usb_pro_interface *usb_if,
 
 	hwts = skb_hwtstamps(skb);
 	peak_usb_get_ts_time(&usb_if->time_ref, le32_to_cpu(er->ts32), &hwts->hwtstamp);
-	netdev->stats.rx_packets++;
-	netdev->stats.rx_bytes += can_frame->len;
 	netif_rx(skb);
 
 	return 0;
diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c
index 1679cbe45ded2..d582c39fc8d0e 100644
--- a/drivers/net/can/usb/ucan.c
+++ b/drivers/net/can/usb/ucan.c
@@ -621,8 +621,10 @@ static void ucan_rx_can_msg(struct ucan_priv *up, struct ucan_message_in *m)
 		memcpy(cf->data, m->msg.can_msg.data, cf->len);
 
 	/* don't count error frames as real packets */
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
+	if (!(cf->can_id & CAN_ERR_FLAG)) {
+		stats->rx_packets++;
+		stats->rx_bytes += cf->len;
+	}
 
 	/* pass it to Linux */
 	netif_rx(skb);
diff --git a/drivers/net/can/usb/usb_8dev.c b/drivers/net/can/usb/usb_8dev.c
index d1b83bd1b3cb9..040324362b260 100644
--- a/drivers/net/can/usb/usb_8dev.c
+++ b/drivers/net/can/usb/usb_8dev.c
@@ -449,8 +449,6 @@ static void usb_8dev_rx_err_msg(struct usb_8dev_priv *priv,
 	priv->bec.txerr = txerr;
 	priv->bec.rxerr = rxerr;
 
-	stats->rx_packets++;
-	stats->rx_bytes += cf->len;
 	netif_rx(skb);
 }
 
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index e2b15d29d15eb..275e240ab293f 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -965,13 +965,8 @@ static void xcan_update_error_state_after_rxtx(struct net_device *ndev)
 
 		xcan_set_error_state(ndev, new_state, skb ? cf : NULL);
 
-		if (skb) {
-			struct net_device_stats *stats = &ndev->stats;
-
-			stats->rx_packets++;
-			stats->rx_bytes += cf->len;
+		if (skb)
 			netif_rx(skb);
-		}
 	}
 }
 
@@ -1095,8 +1090,6 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
 		if (skb) {
 			skb_cf->can_id |= cf.can_id;
 			memcpy(skb_cf->data, cf.data, CAN_ERR_DLC);
-			stats->rx_packets++;
-			stats->rx_bytes += CAN_ERR_DLC;
 			netif_rx(skb);
 		}
 	}
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:19:25 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:19:25 -0500
Subject: [PATCH AUTOSEL 5.16 202/217] net: gemini: allow any RGMII interface
 mode
In-Reply-To: <20220118021940.1942199-1-sashal@kernel.org>
References: <20220118021940.1942199-1-sashal@kernel.org>
Message-ID: <20220118021940.1942199-202-sashal@kernel.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

[ Upstream commit 4e4f325a0a55907b14f579e6b1a38c53755e3de2 ]

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Link: https://lore.kernel.org/r/E1n4mpT-002PLd-Ha at rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 941f175fb911e..0ff40a9b06cec 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:03 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:03 -0500
Subject: [PATCH AUTOSEL 5.15 019/188] ARM: shmobile: rcar-gen2: Add missing
 of_node_put()
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-19-sashal@kernel.org>

From: Wan Jiabing <wanjiabing at vivo.com>

[ Upstream commit 85744f2d938c5f3cfc44cb6533c157469634da93 ]

Fix following coccicheck warning:
./arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c:156:1-33: Function
for_each_matching_node_and_match should have of_node_put() before break
and goto.

Early exits from for_each_matching_node_and_match() should decrement the
node reference counter.

Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
Link: https://lore.kernel.org/r/20211018014503.7598-1-wanjiabing at vivo.com
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index ee949255ced3f..09ef73b99dd86 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void)
 		return -ENODEV;
 
 	for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
-		if (!of_device_is_available(np))
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
 			break;
+		}
 
 		ret = of_property_read_u32(np, "reg", &addr);
 		if (ret)	/* Skip invalid entry and continue */
@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void)
 		quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
 		if (!quirk) {
 			ret = -ENOMEM;
+			of_node_put(np);
 			goto err_mem;
 		}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:07 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:07 -0500
Subject: [PATCH AUTOSEL 5.15 023/188] usb: dwc3: meson-g12a: fix shared reset
 control use
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-23-sashal@kernel.org>

From: Amjad Ouled-Ameur <aouledameur at baylibre.com>

[ Upstream commit 4ce3b45704d5ef46fb4b28083c8aba6716fabf3b ]

reset_control_(de)assert() calls are called on a shared reset line when
reset_control_reset has been used. This is not allowed by the reset
framework.

Use reset_control_rearm() call in suspend() and remove() as a way to state
that the resource is no longer used, hence the shared reset line
may be triggered again by other devices. Use reset_control_rearm() also in
case probe fails after reset() has been called.

reset_control_rearm() keeps use of triggered_count sane in the reset
framework, use of reset_control_reset() on shared reset line should be
balanced with reset_control_rearm().

Signed-off-by: Amjad Ouled-Ameur <aouledameur at baylibre.com>
Reported-by: Jerome Brunet <jbrunet at baylibre.com>
Link: https://lore.kernel.org/r/20211112162827.128319-3-aouledameur at baylibre.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/dwc3/dwc3-meson-g12a.c | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index d0f9b7c296b0d..bd814df3bf8b8 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
 	ret = dwc3_meson_g12a_get_phys(priv);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	ret = priv->drvdata->setup_regmaps(priv, base);
 	if (ret)
-		goto err_disable_clks;
+		goto err_rearm;
 
 	if (priv->vbus) {
 		ret = regulator_enable(priv->vbus);
 		if (ret)
-			goto err_disable_clks;
+			goto err_rearm;
 	}
 
 	/* Get dr_mode */
@@ -825,6 +825,9 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 	if (priv->vbus)
 		regulator_disable(priv->vbus);
 
+err_rearm:
+	reset_control_rearm(priv->reset);
+
 err_disable_clks:
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev)
 	pm_runtime_put_noidle(dev);
 	pm_runtime_set_suspended(dev);
 
+	reset_control_rearm(priv->reset);
+
 	clk_bulk_disable_unprepare(priv->drvdata->num_clks,
 				   priv->drvdata->clks);
 
@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev)
 		phy_exit(priv->phys[i]);
 	}
 
-	reset_control_assert(priv->reset);
+	reset_control_rearm(priv->reset);
 
 	return 0;
 }
@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev)
 	struct dwc3_meson_g12a *priv = dev_get_drvdata(dev);
 	int i, ret;
 
-	reset_control_deassert(priv->reset);
+	ret = reset_control_reset(priv->reset);
+	if (ret)
+		return ret;
 
 	ret = priv->drvdata->usb_init(priv);
 	if (ret)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:32 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:32 -0500
Subject: [PATCH AUTOSEL 5.15 048/188] EDAC/synopsys: Use the quirk for version
 instead of ddr version
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-48-sashal@kernel.org>

From: Dinh Nguyen <dinguyen at kernel.org>

[ Upstream commit bd1d6da17c296bd005bfa656952710d256e77dd3 ]

Version 2.40a supports DDR_ECC_INTR_SUPPORT for a quirk, so use that
quirk to determine a call to setup_address_map().

Signed-off-by: Dinh Nguyen <dinguyen at kernel.org>
Signed-off-by: Borislav Petkov <bp at suse.de>
Reviewed-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lkml.kernel.org/r/20211012190709.1504152-1-dinguyen at kernel.org
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/edac/synopsys_edac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 7d08627e738b3..a5486d86fdd2f 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1352,8 +1352,7 @@ static int mc_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "xlnx,zynqmp-ddrc-2.40a"))
+	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
 		setup_address_map(priv);
 #endif
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:34 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:34 -0500
Subject: [PATCH AUTOSEL 5.15 050/188] soc: imx: gpcv2: Synchronously suspend
 MIX domains
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-50-sashal@kernel.org>

From: Marek Vasut <marex at denx.de>

[ Upstream commit f756f435f7dd823f2d4bd593ce1bf3168def1308 ]

In case the following power domain sequence happens, iMX8M Mini always hangs:
  gpumix:on -> gpu:on -> gpu:off -> gpu:on
This is likely due to another quirk of the GPC block. This situation can be
prevented by always synchronously powering off both the domain and MIX domain.
Make it so. This turns the aforementioned sequence into:
  gpumix:on -> gpu:on -> gpu:off -> gpumix:off -> gpumix:on -> gpu:on

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Frieder Schrempf <frieder.schrempf at kontron.de>
Cc: Lucas Stach <l.stach at pengutronix.de>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Shawn Guo <shawnguo at kernel.org>
Acked-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/soc/imx/gpcv2.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 8b7a01773aec2..b4aa28420f2a8 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -369,7 +369,7 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
 		}
 	}
 
-	pm_runtime_put(domain->dev);
+	pm_runtime_put_sync_suspend(domain->dev);
 
 	return 0;
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:35 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:35 -0500
Subject: [PATCH AUTOSEL 5.15 051/188] ARM: imx: rename DEBUG_IMX21_IMX27_UART
 to DEBUG_IMX27_UART
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-51-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 98436702e0c7e..644875d73ba15 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -410,12 +410,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1481,7 +1481,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1540,12 +1540,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index c8eb83d4b8964..3edbb3c5b42bf 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -11,13 +11,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -26,6 +19,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -112,10 +112,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:38 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:38 -0500
Subject: [PATCH AUTOSEL 5.15 054/188] soc: ti: pruss: fix referenced node in
 error message
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-54-sashal@kernel.org>

From: Jan Kiszka <jan.kiszka at siemens.com>

[ Upstream commit 8aa35e0bb5eaa42bac415ad0847985daa7b4890c ]

So far, "(null)" is reported for the node that is missing clocks.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Acked-by: Suman Anna <s-anna at ti.com>
Signed-off-by: Nishanth Menon <nm at ti.com>
Link: https://lore.kernel.org/r/d6e24953-ea89-fd1c-6e16-7a0142118054 at siemens.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/soc/ti/pruss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index 49da387d77494..b36779309e49b 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -129,7 +129,7 @@ static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node)
 
 	clks_np = of_get_child_by_name(cfg_node, "clocks");
 	if (!clks_np) {
-		dev_err(dev, "%pOF is missing its 'clocks' node\n", clks_np);
+		dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node);
 		return -ENODEV;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:42 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:42 -0500
Subject: [PATCH AUTOSEL 5.15 058/188] mxser: keep only !tty test in ISR
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-58-sashal@kernel.org>

From: Jiri Slaby <jslaby at suse.cz>

[ Upstream commit 274ab58dc2b460cc474ffc7ccfcede4b2be1a3f5 ]

The others are superfluous with tty refcounting in place now. And they
are racy in fact:
* tty_port_initialized() reports false for a small moment after
  interrupts are enabled.
* closing is 1 while the port is still alive.

The queues are flushed later during close anyway. So there is no need
for this special handling. Actually, the ISR should not flush the
queues. It should behave as every other driver, just queue the chars
into tty buffer and go on. But this will be changed later. There is
still a lot code depending on having tty in ISR (and not only tty_port).

Signed-off-by: Jiri Slaby <jslaby at suse.cz>
Link: https://lore.kernel.org/r/20211118073125.12283-4-jslaby at suse.cz
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/mxser.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index 1216f3985e18e..da375851af4e6 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -261,7 +261,6 @@ struct mxser_port {
 	unsigned int xmit_head;
 	unsigned int xmit_tail;
 	unsigned int xmit_cnt;
-	int closing;
 
 	spinlock_t slock;
 };
@@ -923,7 +922,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 		return;
 	if (tty_port_close_start(port, tty, filp) == 0)
 		return;
-	info->closing = 1;
 	mutex_lock(&port->mutex);
 	mxser_close_port(port);
 	mxser_flush_buffer(tty);
@@ -932,7 +930,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
 	mxser_shutdown_port(port);
 	tty_port_set_initialized(port, 0);
 	mutex_unlock(&port->mutex);
-	info->closing = 0;
 	/* Right now the tty_port set is done outside of the close_end helper
 	   as we don't yet have everyone using refcounts */	
 	tty_port_close_end(port, tty);
@@ -1693,7 +1690,7 @@ static bool mxser_port_isr(struct mxser_port *port)
 
 	iir &= MOXA_MUST_IIR_MASK;
 	tty = tty_port_tty_get(&port->port);
-	if (!tty || port->closing || !tty_port_initialized(&port->port)) {
+	if (!tty) {
 		status = inb(port->ioaddr + UART_LSR);
 		outb(MOXA_MUST_FCR_GDA_MODE_ENABLE | UART_FCR_ENABLE_FIFO |
 				UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:29:43 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:29:43 -0500
Subject: [PATCH AUTOSEL 5.15 059/188] tty: serial: imx: disable UCR4_OREN in
 .stop_rx() instead of .shutdown()
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-59-sashal@kernel.org>

From: Fugang Duan <fugang.duan at nxp.com>

[ Upstream commit 028e083832b06fdeeb290e1e57dc1f6702c4c215 ]

The UCR4_OREN should be disabled before disabling the uart receiver in
.stop_rx() instead of in the .shutdown().

Otherwise, if we have the overrun error during the receiver disable
process, the overrun interrupt will keep trigging until we disable the
OREN interrupt in the .shutdown(), because the ORE status can only be
cleared when read the rx FIFO or reset the controller.  Although the
called time between the receiver disable and OREN disable in .shutdown()
is very short, there is still the risk of endless interrupt during this
short period of time. So here change to disable OREN before the receiver
been disabled in .stop_rx().

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Sherry Sun <sherry.sun at nxp.com>
Link: https://lore.kernel.org/r/20211125020349.4980-1-sherry.sun at nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/serial/imx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 51a9f9423b1a6..7820049aba5af 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
 static void imx_uart_stop_rx(struct uart_port *port)
 {
 	struct imx_port *sport = (struct imx_port *)port;
-	u32 ucr1, ucr2;
+	u32 ucr1, ucr2, ucr4;
 
 	ucr1 = imx_uart_readl(sport, UCR1);
 	ucr2 = imx_uart_readl(sport, UCR2);
+	ucr4 = imx_uart_readl(sport, UCR4);
 
 	if (sport->dma_is_enabled) {
 		ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
 	} else {
 		ucr1 &= ~UCR1_RRDYEN;
 		ucr2 &= ~UCR2_ATEN;
+		ucr4 &= ~UCR4_OREN;
 	}
 	imx_uart_writel(sport, ucr1, UCR1);
+	imx_uart_writel(sport, ucr4, UCR4);
 
 	ucr2 &= ~UCR2_RXEN;
 	imx_uart_writel(sport, ucr2, UCR2);
@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port)
 	imx_uart_writel(sport, ucr1, UCR1);
 
 	ucr4 = imx_uart_readl(sport, UCR4);
-	ucr4 &= ~(UCR4_OREN | UCR4_TCEN);
+	ucr4 &= ~UCR4_TCEN;
 	imx_uart_writel(sport, ucr4, UCR4);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:00 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:00 -0500
Subject: [PATCH AUTOSEL 5.15 076/188] arm64: dts: ti: j7200-main: Fix
 'dtbs_check' serdes_ln_ctrl node
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-76-sashal@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

[ Upstream commit 4d3984906397581dc0ccb6a02bf16b6ff82c9192 ]

Fix 'dtbs_check' in serdes_ln_ctrl (serdes-ln-ctrl at 4080) node by
changing the node name to mux-controller at 4080.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Aswath Govindraju <a-govindraju at ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Link: https://lore.kernel.org/r/20211126084555.17797-2-kishon at ti.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 874cba75e9a5a..7daa280220442 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -32,7 +32,7 @@ scm_conf: scm-conf at 100000 {
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x00100000 0x1c000>;
 
-		serdes_ln_ctrl: serdes-ln-ctrl at 4080 {
+		serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "mmio-mux";
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:01 -0500
Subject: [PATCH AUTOSEL 5.15 077/188] arm64: dts: ti: j721e-main: Fix
 'dtbs_check' in serdes_ln_ctrl node
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-77-sashal@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

[ Upstream commit 3f92a5be6084b77f764a8bbb881ac0d12cb9e863 ]

Fix 'dtbs_check' in serdes_ln_ctrl (mux at 4080) node by changing the node
name to mux-controller at 4080.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Aswath Govindraju <a-govindraju at ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Link: https://lore.kernel.org/r/20211126084555.17797-3-kishon at ti.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
index 08c8d1b47dcd9..e85c89eebfa31 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi
@@ -42,7 +42,7 @@ scm_conf: scm-conf at 100000 {
 		#size-cells = <1>;
 		ranges = <0x0 0x0 0x00100000 0x1c000>;
 
-		serdes_ln_ctrl: mux at 4080 {
+		serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "mmio-mux";
 			reg = <0x00004080 0x50>;
 			#mux-control-cells = <1>;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:02 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:02 -0500
Subject: [PATCH AUTOSEL 5.15 078/188] usb: uhci: add aspeed ast2600 uhci
 support
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-78-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 70dbd95c3f063..be9e9db7cad10 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:22 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:22 -0500
Subject: [PATCH AUTOSEL 5.15 098/188] gpio: aspeed: Convert aspeed_gpio.lock
 to raw_spinlock
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-98-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit 61a7904b6ace99b1bde0d0e867fa3097f5c8cee2 ]

The gpio-aspeed driver implements an irq_chip which need to be invoked
from hardirq context. Since spin_lock() can sleep with PREEMPT_RT, it is
no longer legal to invoke it while interrupts are disabled.
This also causes lockdep to complain about:
[    0.649797] [ BUG: Invalid wait context ]
because aspeed_gpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed.c | 52 +++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 3c8f20c57695f..318a7d95a1a8b 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -53,7 +53,7 @@ struct aspeed_gpio_config {
 struct aspeed_gpio {
 	struct gpio_chip chip;
 	struct irq_chip irqc;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 	const struct aspeed_gpio_config *config;
@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 	unsigned long flags;
 	bool copro;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	__aspeed_gpio_set(gc, offset, val);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (!have_input(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg &= ~GPIO_BIT(offset);
@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 	if (!have_output(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg |= GPIO_BIT(offset);
@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 	if (!have_output(gpio, offset))
 		return GPIO_LINE_DIRECTION_IN;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
 }
@@ -539,14 +539,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	iowrite32(bit, status_addr);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
@@ -565,7 +565,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	reg = ioread32(addr);
@@ -577,7 +577,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_mask(struct irq_data *d)
@@ -629,7 +629,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
@@ -649,7 +649,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -716,7 +716,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	treg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	val = readl(treg);
@@ -730,7 +730,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -856,7 +856,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 		return rc;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	if (timer_allocation_registered(gpio, offset)) {
 		rc = unregister_allocated_timer(gpio, offset);
@@ -916,7 +916,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 	configure_timer(gpio, offset, i);
 
 out:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -927,13 +927,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
 	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	rc = unregister_allocated_timer(gpio, offset);
 	if (!rc)
 		configure_timer(gpio, offset, 0);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -1015,7 +1015,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0xff) {
@@ -1036,7 +1036,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 	if (bit)
 		*bit = GPIO_OFFSET(offset);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
@@ -1060,7 +1060,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0) {
@@ -1074,7 +1074,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		aspeed_gpio_change_cmd_source(gpio, bank, bindex,
 					      GPIO_CMDSRC_ARM);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);
@@ -1148,7 +1148,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->base))
 		return PTR_ERR(gpio->base);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
 	if (!gpio_id)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:23 -0500
Subject: [PATCH AUTOSEL 5.15 099/188] gpio: aspeed-sgpio: Convert
 aspeed_sgpio.lock to raw_spinlock
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-99-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit ab39d6988dd53f354130438d8afa5596a2440fed ]

The gpio-aspeed-sgpio driver implements an irq_chip which need to be
invoked from hardirq context. Since spin_lock() can sleep with
PREEMPT_RT, it is no longer legal to invoke it while interrupts are
disabled.
This also causes lockdep to complain about:
[   25.919465] [ BUG: Invalid wait context ]
because aspeed_sgpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed-sgpio.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c
index b3a9b8488f11d..454cefbeecf0e 100644
--- a/drivers/gpio/gpio-aspeed-sgpio.c
+++ b/drivers/gpio/gpio-aspeed-sgpio.c
@@ -31,7 +31,7 @@ struct aspeed_sgpio {
 	struct gpio_chip chip;
 	struct irq_chip intc;
 	struct clk *pclk;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 };
@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
 	enum aspeed_sgpio_reg reg;
 	int rc = 0;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata;
 	rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
 	struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
 	unsigned long flags;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	sgpio_set_value(gc, offset, val);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v
 	/* No special action is required for setting the direction; we'll
 	 * error-out in sgpio_set_value if this isn't an output GPIO */
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	rc = sgpio_set_value(gc, offset, val);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	iowrite32(bit, status_addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
 	irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	if (set)
@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
 
 	iowrite32(reg, addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_sgpio_irq_mask(struct irq_data *d)
@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
 	reg = ioread32(addr);
@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
 	reg = (reg & ~bit) | type2;
 	iowrite32(reg, addr);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
 	reg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = readl(reg);
 
@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip,
 
 	writel(val, reg);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev)
 	iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval |
 		  ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio->chip.parent = &pdev->dev;
 	gpio->chip.ngpio = nr_gpios * 2;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:39 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:39 -0500
Subject: [PATCH AUTOSEL 5.15 115/188] media: rockchip: rkisp1: use device name
 for debugfs subdir name
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-115-sashal@kernel.org>

From: Mikhail Rudenko <mike.rudenko at gmail.com>

[ Upstream commit c2611e479f5d9b05108270e1ab423955486b4457 ]

While testing Rockchip RK3399 with both ISPs enabled, a dmesg error
was observed:
```
[   15.559141] debugfs: Directory 'rkisp1' with parent '/' already present!
```

Fix it by using the device name for the debugfs subdirectory name
instead of the driver name, thus preventing name collision.

Link: https://lore.kernel.org/linux-media/20211010175457.438627-1-mike.rudenko at gmail.com
Signed-off-by: Mikhail Rudenko <mike.rudenko at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas at ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
index 7474150b94ed3..560f928c37520 100644
--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
+++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c
@@ -426,7 +426,7 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1)
 {
 	struct rkisp1_debug *debug = &rkisp1->debug;
 
-	debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL);
+	debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL);
 	debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir,
 			     &debug->data_loss);
 	debugfs_create_ulong("outform_size_err", 0444,  debug->debugfs_dir,
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:46 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:46 -0500
Subject: [PATCH AUTOSEL 5.15 122/188] arm64: dts: ls1028a-qds: move rtc node
 to the correct i2c bus
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-122-sashal@kernel.org>

From: Biwen Li <biwen.li at nxp.com>

[ Upstream commit cbe9d948eadfe352ad45495a7cc5bf20a1b29d90 ]

The i2c rtc is on i2c2 bus not i2c1 bus, so fix it in dts.

Signed-off-by: Biwen Li <biwen.li at nxp.com>
Signed-off-by: Li Yang <leoyang.lil at nxp.com>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index bfd14b64567e4..2f92e62ecafe9 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -272,11 +272,6 @@ temperature-sensor at 4c {
 				vcc-supply = <&sb_3v3>;
 			};
 
-			rtc at 51 {
-				compatible = "nxp,pcf2129";
-				reg = <0x51>;
-			};
-
 			eeprom at 56 {
 				compatible = "atmel,24c512";
 				reg = <0x56>;
@@ -318,6 +313,15 @@ mux: mux-controller {
 
 };
 
+&i2c1 {
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf2129";
+		reg = <0x51>;
+	};
+};
+
 &enetc_port1 {
 	phy-handle = <&qds_phy1>;
 	phy-connection-type = "rgmii-id";
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:54 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:54 -0500
Subject: [PATCH AUTOSEL 5.15 130/188] mt76: mt7615: fix possible deadlock
 while mt7615_register_ext_phy()
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-130-sashal@kernel.org>

From: Peter Chiu <chui-hao.chiu at mediatek.com>

[ Upstream commit 8c55516de3f9b76b9d9444e7890682ec2efc809f ]

ieee80211_register_hw() is called with rtnl_lock held, and this could be
caused lockdep from a work item that's on a workqueue that is flushed
with the rtnl held.

Move mt7615_register_ext_phy() outside the init_work().

Signed-off-by: Peter Chiu <chui-hao.chiu at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
index a2465b49ecd0c..87b4aa52ee0f9 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c
@@ -28,8 +28,6 @@ static void mt7615_pci_init_work(struct work_struct *work)
 		return;
 
 	mt7615_init_work(dev);
-	if (dev->dbdc_support)
-		mt7615_register_ext_phy(dev);
 }
 
 static int mt7615_init_hardware(struct mt7615_dev *dev)
@@ -160,6 +158,12 @@ int mt7615_register_device(struct mt7615_dev *dev)
 	mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband);
 	mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband);
 
+	if (dev->dbdc_support) {
+		ret = mt7615_register_ext_phy(dev);
+		if (ret)
+			return ret;
+	}
+
 	return mt7615_init_debugfs(dev);
 }
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:55 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:55 -0500
Subject: [PATCH AUTOSEL 5.15 131/188] mt76: do not pass the received frame
 with decryption error
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-131-sashal@kernel.org>

From: Xing Song <xing.song at mediatek.com>

[ Upstream commit dd28dea52ad9376d2b243a8981726646e1f60b1a ]

MAC80211 doesn't care any decryption error in 802.3 path, so received
frame will be dropped if HW tell us that the cipher configuration is not
matched as well as the header has been translated to 802.3. This case only
appears when IEEE80211_FCTL_PROTECTED is 0 and cipher suit is not none in
the corresponding HW entry.

The received frame is only reported to monitor interface if HW decryption
block tell us there is ICV error or CCMP/BIP/WPI MIC error. Note in this
case the reported frame is decrypted 802.11 frame and the payload may be
malformed due to mismatched key.

Signed-off-by: Xing Song <xing.song at mediatek.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 4 ++++
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 9 ++++++++-
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 9 ++++++++-
 drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 9 ++++++++-
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 3972c56136a20..65f1f2bb80835 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -525,6 +525,10 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_TKIP_MIC_ERR)
 		status->flag |= RX_FLAG_MMIC_ERROR;
 
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 &&
 	    !(rxd2 & (MT_RXD2_NORMAL_CLM | MT_RXD2_NORMAL_CM))) {
 		status->flag |= RX_FLAG_DECRYPTED;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
index 5455231f51881..f2704149834a0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c
@@ -286,9 +286,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd2 & MT_RXD2_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	unicast = (rxd1 & MT_RXD1_NORMAL_ADDR_TYPE) == MT_RXD1_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2);
-	hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS;
 	status->wcid = mt7615_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
index bbc996f86b5c3..ff613d7056119 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c
@@ -349,9 +349,16 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
 	status->wcid = mt7915_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 8a16f3f4d5253..04a288029c98e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -383,10 +383,17 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
 	if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR)
 		return -EINVAL;
 
+	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
+	if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM))
+		return -EINVAL;
+
+	/* ICV error or CCMP/BIP/WPI MIC error */
+	if (rxd1 & MT_RXD1_NORMAL_ICV_ERR)
+		status->flag |= RX_FLAG_ONLY_MONITOR;
+
 	chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3);
 	unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M;
 	idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1);
-	hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS;
 	status->wcid = mt7921_rx_get_wcid(dev, idx, unicast);
 
 	if (status->wcid) {
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:30:56 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:30:56 -0500
Subject: [PATCH AUTOSEL 5.15 132/188] mt76: mt7615: improve wmm index
 allocation
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-132-sashal@kernel.org>

From: Felix Fietkau <nbd at nbd.name>

[ Upstream commit 70fb028707c8871ef9e56b3ffa3d895e14956cc4 ]

Typically all AP interfaces on a PHY will share the same WMM settings, while
sta/mesh interfaces will usually inherit the settings from a remote device.
In order minimize the likelihood of conflicting WMM settings, make all AP
interfaces share one slot, and all non-AP interfaces another one.

This also fixes running multiple AP interfaces on MT7613, which only has 3
WMM slots.

Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/wireless/mediatek/mt76/mt7615/main.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
index 51260a669d166..fc266da54fe7b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c
@@ -211,11 +211,9 @@ static int mt7615_add_interface(struct ieee80211_hw *hw,
 	mvif->mt76.omac_idx = idx;
 
 	mvif->mt76.band_idx = ext_phy;
-	if (mt7615_ext_phy(dev))
-		mvif->mt76.wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) +
-				mvif->mt76.idx % (MT7615_MAX_WMM_SETS / 2);
-	else
-		mvif->mt76.wmm_idx = mvif->mt76.idx % MT7615_MAX_WMM_SETS;
+	mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP;
+	if (ext_phy)
+		mvif->mt76.wmm_idx += 2;
 
 	dev->mt76.vif_mask |= BIT(mvif->mt76.idx);
 	dev->omac_mask |= BIT_ULL(mvif->mt76.omac_idx);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:31:21 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:31:21 -0500
Subject: [PATCH AUTOSEL 5.15 157/188] mmc: mtk-sd: Use readl_poll_timeout
 instead of open-coded polling
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-157-sashal@kernel.org>

From: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

[ Upstream commit ffaea6ebfe9ce06ebb3a54811a47688f2b0893cd ]

Replace all instances of open-coded while loops for polling registers
with calls to readl_poll_timeout() and, while at it, also fix some
possible infinite loop instances.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Link: https://lore.kernel.org/r/20211216125748.179602-1-angelogioacchino.delregno at collabora.com
Signed-off-by: Ulf Hansson <ulf.hansson at linaro.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/mmc/host/mtk-sd.c | 64 ++++++++++++++++++++++++---------------
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 9e6dab7e34242..1ac92015992ed 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -628,12 +628,11 @@ static void msdc_reset_hw(struct msdc_host *host)
 	u32 val;
 
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST);
-	while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST)
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0);
 
 	sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR);
-	while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR)
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_FIFOCS, val,
+			   !(val & MSDC_FIFOCS_CLR), 0, 0);
 
 	val = readl(host->base + MSDC_INT);
 	writel(val, host->base + MSDC_INT);
@@ -806,8 +805,9 @@ static void msdc_gate_clock(struct msdc_host *host)
 	clk_disable_unprepare(host->h_clk);
 }
 
-static void msdc_ungate_clock(struct msdc_host *host)
+static int msdc_ungate_clock(struct msdc_host *host)
 {
+	u32 val;
 	int ret;
 
 	clk_prepare_enable(host->h_clk);
@@ -817,11 +817,11 @@ static void msdc_ungate_clock(struct msdc_host *host)
 	ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks);
 	if (ret) {
 		dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n");
-		return;
+		return ret;
 	}
 
-	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
-		cpu_relax();
+	return readl_poll_timeout(host->base + MSDC_CFG, val,
+				  (val & MSDC_CFG_CKSTB), 1, 20000);
 }
 
 static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -832,6 +832,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	u32 div;
 	u32 sclk;
 	u32 tune_reg = host->dev_comp->pad_tune_reg;
+	u32 val;
 
 	if (!hz) {
 		dev_dbg(host->dev, "set mclk to 0\n");
@@ -912,8 +913,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
 	else
 		clk_prepare_enable(clk_get_parent(host->src_clk));
 
-	while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
-		cpu_relax();
+	readl_poll_timeout(host->base + MSDC_CFG, val, (val & MSDC_CFG_CKSTB), 0, 0);
 	sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN);
 	mmc->actual_clock = sclk;
 	host->mclk = hz;
@@ -1223,13 +1223,13 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
 static inline bool msdc_cmd_is_ready(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd)
 {
-	/* The max busy time we can endure is 20ms */
-	unsigned long tmo = jiffies + msecs_to_jiffies(20);
+	u32 val;
+	int ret;
 
-	while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) &&
-			time_before(jiffies, tmo))
-		cpu_relax();
-	if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) {
+	/* The max busy time we can endure is 20ms */
+	ret = readl_poll_timeout_atomic(host->base + SDC_STS, val,
+					!(val & SDC_STS_CMDBUSY), 1, 20000);
+	if (ret) {
 		dev_err(host->dev, "CMD bus busy detected\n");
 		host->error |= REQ_CMD_BUSY;
 		msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
@@ -1237,12 +1237,10 @@ static inline bool msdc_cmd_is_ready(struct msdc_host *host,
 	}
 
 	if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) {
-		tmo = jiffies + msecs_to_jiffies(20);
 		/* R1B or with data, should check SDCBUSY */
-		while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) &&
-				time_before(jiffies, tmo))
-			cpu_relax();
-		if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) {
+		ret = readl_poll_timeout_atomic(host->base + SDC_STS, val,
+						!(val & SDC_STS_SDCBUSY), 1, 20000);
+		if (ret) {
 			dev_err(host->dev, "Controller busy detected\n");
 			host->error |= REQ_CMD_BUSY;
 			msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd);
@@ -1367,6 +1365,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 	    (MSDC_INT_XFER_COMPL | MSDC_INT_DATCRCERR | MSDC_INT_DATTMO
 	     | MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR
 	     | MSDC_INT_DMA_PROTECT);
+	u32 val;
+	int ret;
 
 	spin_lock_irqsave(&host->lock, flags);
 	done = !host->data;
@@ -1383,8 +1383,14 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
 				readl(host->base + MSDC_DMA_CFG));
 		sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP,
 				1);
-		while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
-			cpu_relax();
+
+		ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val,
+						!(val & MSDC_DMA_CFG_STS), 1, 20000);
+		if (ret) {
+			dev_dbg(host->dev, "DMA stop timed out\n");
+			return false;
+		}
+
 		sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask);
 		dev_dbg(host->dev, "DMA stop\n");
 
@@ -2598,7 +2604,11 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	spin_lock_init(&host->lock);
 
 	platform_set_drvdata(pdev, mmc);
-	msdc_ungate_clock(host);
+	ret = msdc_ungate_clock(host);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot ungate clocks!\n");
+		goto release_mem;
+	}
 	msdc_init_hw(host);
 
 	if (mmc->caps2 & MMC_CAP2_CQE) {
@@ -2757,8 +2767,12 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
+	int ret;
+
+	ret = msdc_ungate_clock(host);
+	if (ret)
+		return ret;
 
-	msdc_ungate_clock(host);
 	msdc_restore_reg(host);
 	return 0;
 }
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:31:37 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:31:37 -0500
Subject: [PATCH AUTOSEL 5.15 173/188] net: gemini: allow any RGMII interface
 mode
In-Reply-To: <20220118023152.1948105-1-sashal@kernel.org>
References: <20220118023152.1948105-1-sashal@kernel.org>
Message-ID: <20220118023152.1948105-173-sashal@kernel.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

[ Upstream commit 4e4f325a0a55907b14f579e6b1a38c53755e3de2 ]

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Link: https://lore.kernel.org/r/E1n4mpT-002PLd-Ha at rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 6e745ca4c4333..012ca11a38cc1 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.34.1



From zhiyong.tao at mediatek.com  Mon Jan 17 18:36:47 2022
From: zhiyong.tao at mediatek.com (zhiyong.tao)
Date: Tue, 18 Jan 2022 10:36:47 +0800
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <20220111112244.1483783-8-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-8-wenst@chromium.org>
Message-ID: <b1d5ca006860c85edd971ea9e20880ec8ba7f842.camel@mediatek.com>

On Tue, 2022-01-11 at 19:22 +0800, Chen-Yu Tsai wrote:
> Some of the MediaTek chips that utilize the Paris pinctrl driver
> library
> support a lower drive strength (<= 1mA) than the standard drive
> strength
> settings (2~16 mA) on certain pins. This was previously supported by
> the
> custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
> "mediatek,drive-strength-adv" device tree property.
> 
> The drive strength values for this hardware are 125, 250, 500, and
> 1000 mA,
> and can be readily described by the existing "drive-strength-
> microamp",
> which then gets parsed by the generic pinconf library into the
> parameter
> PIN_CONFIG_DRIVE_STRENGTH_UA.
> 
> Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
> custom parameter around for backward compatibility.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
> 
> The indentation in the switch/case blocks is getting somewhat out of
> control. I also have some cleanup changes to reverse the logic of the
> if/break statements. Not sure if it should be done before or after
> this
> patch though.
> 
> ---
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 84
> ++++++++++++++++++++++++
>  1 file changed, 84 insertions(+)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index 678c8aa33012..5a94903ae372 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = {
>  	"func12", "func13", "func14", "func15",
>  };
>  
> +/*
> + * This section supports converting to/from custom
> MTK_PIN_CONFIG_DRV_ADV
> + * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs.
> + *
> + * The custom value encodes three hardware bits as follows:
> + *
> + *   |           Bits           |
> + *   | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA)
> + *   ------------------------------------------------
> + *   |    x   |    x   |    0   | disabled, use standard drive
> strength
> + *   -------------------------------------
> + *   |    0   |    0   |    1   |  125 uA
> + *   |    0   |    1   |    1   |  250 uA
> + *   |    1   |    0   |    1   |  500 uA
> + *   |    1   |    1   |    1   | 1000 uA
> + */
> +static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 };
> +
> +static int mtk_drv_adv_to_uA(int val)
> +{
> +	/* This should never happen. */
> +	if (WARN_ON_ONCE(val < 0 || val > 7))
> +		return -EINVAL;
> +
> +	/* Bit 0 simply enables this hardware part */
> +	if (!(val & BIT(0)))
> +		return -EINVAL;
> +
> +	return mtk_drv_adv_uA[(val >> 1)];
> +}
> +
> +static int mtk_drv_uA_to_adv(int val)
> +{
> +	switch (val) {
> +	case 125:
> +		return 0x1;
> +	case 250:
> +		return 0x3;
> +	case 500:
> +		return 0x5;
> +	case 1000:
> +		return 0x7;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev
> *pctldev,
>  					  struct pinctrl_gpio_range
> *range,
>  					  unsigned int pin)
> @@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev
> *pctldev,
>  
>  		break;
>  	case PIN_CONFIG_DRIVE_STRENGTH:
> +		if (hw->soc->adv_drive_get) {
> +			err = hw->soc->adv_drive_get(hw, desc, &ret);
> +			if (!err) {
> +				err = mtk_drv_adv_to_uA(ret);
> +				if (err > 0) {
> +					/* PIN_CONFIG_DRIVE_STRENGTH_UA
> used */
> +					err = -EINVAL;
> +					break;
> +				}
> +			}
> +		}
> +
Hi Chen-Yu,

PIN_CONFIG_DRIVE_STRENGTH is seems used for 2/4/6/8ma, it is not used
for 125/250/500/1000ma. why you change here?

Thanks.

>  		if (hw->soc->drive_get)
>  			err = hw->soc->drive_get(hw, desc, &ret);
>  		else
>  			err = -ENOTSUPP;
>  		break;
> +	case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +		if (hw->soc->adv_drive_get) {
> +			err = hw->soc->adv_drive_get(hw, desc, &ret);
> +			if (err)
> +				break;
> +			err = mtk_drv_adv_to_uA(ret);
> +			if (err < 0)
> +				break;
> +
> +			ret = err;
> +			err = 0;
> +		} else {
> +			err = -ENOTSUPP;
> +		}
> +		break;

Hi Chen-Yu,
For PIN_CONFIG_DRIVE_STRENGTH_UA case, How can we use in dts node ?
Thanks.

>  	case MTK_PIN_CONFIG_TDSEL:
>  	case MTK_PIN_CONFIG_RDSEL:
>  		reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> @@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev
> *pctldev, unsigned int pin,
>  		else
>  			err = -ENOTSUPP;
>  		break;
> +	case PIN_CONFIG_DRIVE_STRENGTH_UA:
> +		if (hw->soc->adv_drive_set) {
> +			err = mtk_drv_uA_to_adv(arg);
> +			if (err < 0)
> +				break;
> +			err = hw->soc->adv_drive_set(hw, desc, err);
> +		} else {
> +			err = -ENOTSUPP;
> +		}
> +		break;
>  	case MTK_PIN_CONFIG_TDSEL:
>  	case MTK_PIN_CONFIG_RDSEL:
>  		reg = (param == MTK_PIN_CONFIG_TDSEL) ?

From sashal at kernel.org  Mon Jan 17 18:38:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:23 -0500
Subject: [PATCH AUTOSEL 5.10 012/116] ARM: shmobile: rcar-gen2: Add missing
 of_node_put()
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-12-sashal@kernel.org>

From: Wan Jiabing <wanjiabing at vivo.com>

[ Upstream commit 85744f2d938c5f3cfc44cb6533c157469634da93 ]

Fix following coccicheck warning:
./arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c:156:1-33: Function
for_each_matching_node_and_match should have of_node_put() before break
and goto.

Early exits from for_each_matching_node_and_match() should decrement the
node reference counter.

Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
Link: https://lore.kernel.org/r/20211018014503.7598-1-wanjiabing at vivo.com
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index ee949255ced3f..09ef73b99dd86 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void)
 		return -ENODEV;
 
 	for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
-		if (!of_device_is_available(np))
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
 			break;
+		}
 
 		ret = of_property_read_u32(np, "reg", &addr);
 		if (ret)	/* Skip invalid entry and continue */
@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void)
 		quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
 		if (!quirk) {
 			ret = -ENOMEM;
+			of_node_put(np);
 			goto err_mem;
 		}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:31 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:31 -0500
Subject: [PATCH AUTOSEL 5.10 020/116] EDAC/synopsys: Use the quirk for version
 instead of ddr version
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-20-sashal@kernel.org>

From: Dinh Nguyen <dinguyen at kernel.org>

[ Upstream commit bd1d6da17c296bd005bfa656952710d256e77dd3 ]

Version 2.40a supports DDR_ECC_INTR_SUPPORT for a quirk, so use that
quirk to determine a call to setup_address_map().

Signed-off-by: Dinh Nguyen <dinguyen at kernel.org>
Signed-off-by: Borislav Petkov <bp at suse.de>
Reviewed-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lkml.kernel.org/r/20211012190709.1504152-1-dinguyen at kernel.org
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/edac/synopsys_edac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 1a801a5d3b08b..92906b56b1a2b 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1351,8 +1351,7 @@ static int mc_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "xlnx,zynqmp-ddrc-2.40a"))
+	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
 		setup_address_map(priv);
 #endif
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:32 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:32 -0500
Subject: [PATCH AUTOSEL 5.10 021/116] ARM: imx: rename DEBUG_IMX21_IMX27_UART
 to DEBUG_IMX27_UART
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-21-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 8986a91a6f31b..dd1cf70353986 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -400,12 +400,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1523,7 +1523,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1591,12 +1591,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index c8eb83d4b8964..3edbb3c5b42bf 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -11,13 +11,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -26,6 +19,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -112,10 +112,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:35 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:35 -0500
Subject: [PATCH AUTOSEL 5.10 024/116] soc: ti: pruss: fix referenced node in
 error message
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-24-sashal@kernel.org>

From: Jan Kiszka <jan.kiszka at siemens.com>

[ Upstream commit 8aa35e0bb5eaa42bac415ad0847985daa7b4890c ]

So far, "(null)" is reported for the node that is missing clocks.

Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Acked-by: Suman Anna <s-anna at ti.com>
Signed-off-by: Nishanth Menon <nm at ti.com>
Link: https://lore.kernel.org/r/d6e24953-ea89-fd1c-6e16-7a0142118054 at siemens.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/soc/ti/pruss.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c
index cc0b4ad7a3d34..30695172a508f 100644
--- a/drivers/soc/ti/pruss.c
+++ b/drivers/soc/ti/pruss.c
@@ -131,7 +131,7 @@ static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node)
 
 	clks_np = of_get_child_by_name(cfg_node, "clocks");
 	if (!clks_np) {
-		dev_err(dev, "%pOF is missing its 'clocks' node\n", clks_np);
+		dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node);
 		return -ENODEV;
 	}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:38 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:38 -0500
Subject: [PATCH AUTOSEL 5.10 027/116] tty: serial: imx: disable UCR4_OREN in
 .stop_rx() instead of .shutdown()
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-27-sashal@kernel.org>

From: Fugang Duan <fugang.duan at nxp.com>

[ Upstream commit 028e083832b06fdeeb290e1e57dc1f6702c4c215 ]

The UCR4_OREN should be disabled before disabling the uart receiver in
.stop_rx() instead of in the .shutdown().

Otherwise, if we have the overrun error during the receiver disable
process, the overrun interrupt will keep trigging until we disable the
OREN interrupt in the .shutdown(), because the ORE status can only be
cleared when read the rx FIFO or reset the controller.  Although the
called time between the receiver disable and OREN disable in .shutdown()
is very short, there is still the risk of endless interrupt during this
short period of time. So here change to disable OREN before the receiver
been disabled in .stop_rx().

Signed-off-by: Fugang Duan <fugang.duan at nxp.com>
Signed-off-by: Sherry Sun <sherry.sun at nxp.com>
Link: https://lore.kernel.org/r/20211125020349.4980-1-sherry.sun at nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/tty/serial/imx.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 28cc328ddb6eb..93cd8ad57f385 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -508,18 +508,21 @@ static void imx_uart_stop_tx(struct uart_port *port)
 static void imx_uart_stop_rx(struct uart_port *port)
 {
 	struct imx_port *sport = (struct imx_port *)port;
-	u32 ucr1, ucr2;
+	u32 ucr1, ucr2, ucr4;
 
 	ucr1 = imx_uart_readl(sport, UCR1);
 	ucr2 = imx_uart_readl(sport, UCR2);
+	ucr4 = imx_uart_readl(sport, UCR4);
 
 	if (sport->dma_is_enabled) {
 		ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN);
 	} else {
 		ucr1 &= ~UCR1_RRDYEN;
 		ucr2 &= ~UCR2_ATEN;
+		ucr4 &= ~UCR4_OREN;
 	}
 	imx_uart_writel(sport, ucr1, UCR1);
+	imx_uart_writel(sport, ucr4, UCR4);
 
 	ucr2 &= ~UCR2_RXEN;
 	imx_uart_writel(sport, ucr2, UCR2);
@@ -1576,7 +1579,7 @@ static void imx_uart_shutdown(struct uart_port *port)
 	imx_uart_writel(sport, ucr1, UCR1);
 
 	ucr4 = imx_uart_readl(sport, UCR4);
-	ucr4 &= ~(UCR4_OREN | UCR4_TCEN);
+	ucr4 &= ~UCR4_TCEN;
 	imx_uart_writel(sport, ucr4, UCR4);
 
 	spin_unlock_irqrestore(&sport->port.lock, flags);
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:51 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:51 -0500
Subject: [PATCH AUTOSEL 5.10 040/116] arm64: dts: ti: j7200-main: Fix
 'dtbs_check' serdes_ln_ctrl node
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-40-sashal@kernel.org>

From: Kishon Vijay Abraham I <kishon at ti.com>

[ Upstream commit 4d3984906397581dc0ccb6a02bf16b6ff82c9192 ]

Fix 'dtbs_check' in serdes_ln_ctrl (serdes-ln-ctrl at 4080) node by
changing the node name to mux-controller at 4080.

Signed-off-by: Kishon Vijay Abraham I <kishon at ti.com>
Reviewed-by: Aswath Govindraju <a-govindraju at ti.com>
Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
Link: https://lore.kernel.org/r/20211126084555.17797-2-kishon at ti.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/ti/k3-j7200-main.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
index 5832ad830ed14..1ab9f9604af6c 100644
--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -25,7 +25,7 @@ scm_conf: scm-conf at 100000 {
 		#size-cells = <1>;
 		ranges = <0x00 0x00 0x00100000 0x1c000>;
 
-		serdes_ln_ctrl: serdes-ln-ctrl at 4080 {
+		serdes_ln_ctrl: mux-controller at 4080 {
 			compatible = "mmio-mux";
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:38:52 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:38:52 -0500
Subject: [PATCH AUTOSEL 5.10 041/116] usb: uhci: add aspeed ast2600 uhci
 support
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-41-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 70dbd95c3f063..be9e9db7cad10 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From anshuman.khandual at arm.com  Mon Jan 17 18:42:39 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 18 Jan 2022 08:12:39 +0530
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
In-Reply-To: <20220117132541.GD87485@C02TD0UTHF1T.local>
References: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
 <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>
 <b1ffe762-43e6-b624-2b08-0aaa7ca5f70b@arm.com>
 <20220117132541.GD87485@C02TD0UTHF1T.local>
Message-ID: <b76978f3-4a34-c196-956a-ee95c7f663d2@arm.com>



On 1/17/22 6:55 PM, Mark Rutland wrote:
> On Mon, Jan 17, 2022 at 04:06:44PM +0530, Anshuman Khandual wrote:
>> On 1/13/22 3:54 PM, Mark Rutland wrote:
>>> Hi Anshuman,
>>>
>>> This looks fine structurally, I'm just not sure of a couple of details because
>>> I can't find the relevant documentation -- more on that below.
>>>
>>> On Thu, Jan 13, 2022 at 03:11:08PM +0530, Anshuman Khandual wrote:
>>>> MDCR_EL3.SBRBE resets to an UNKNOWN value. Configure it to allow the BRBE
>>>> buffer usage and direct register access in the non-secure world. But just
>>>> before that, check AA64DFR0_EL1.BRBE and make sure BRBE is implemented. We
>>>> still continue to reset MDCR_EL3 register to zero with the exception of
>>>> MDCR_EL3.NSPB, MDCR_EL3.NSTB and MDCR_EL3.SBRBE.
>>>
>>> I'm struggling to find where the BRBE system register fields are documented.
>>>
>>> I looked at the latest ARM ARM (DDI 0487G.b):
>>>
>>>   https://developer.arm.com/documentation/ddi0487/gb/
>>>
>>> ... and the Armv9 supplement (DDI 0608A.a):
>>>
>>>   https://developer.arm.com/documentation/ddi0608/aa/
>>>
>>> ... but AFAICT, neither of those describe the bit-positions of the relevant
>>> fields, so I can't check that those are correct. The other extensions (at leat
>>> TME) describe that in the supplement, so this looks like a bug/oversight. 
>>>
>>> Am I looking at the right documents? If this is meant to be in the supplement,
>>> could you please raise a bug report to get that fixed?
>>
>> Please find the MDCR_EL3.SBRBE definition here.
>>
>> https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/
>> MDCR-EL3--Monitor-Debug-Configuration-Register--EL3-?lang=en#fieldset_0-33_32-1
>>
>>>
>>>>
>>>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>>>> ---
>>>>  arch/aarch64/boot.S | 8 ++++++++
>>>>  1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
>>>> index bfbb6ec..ca1b292 100644
>>>> --- a/arch/aarch64/boot.S
>>>> +++ b/arch/aarch64/boot.S
>>>> @@ -103,6 +103,14 @@ ASM_FUNC(_start)
>>>>  	ldr	x1, =(0x3 << 24)
>>>>  	orr	x0, x0, x1
>>>>  
>>>> +1:	mrs     x1, id_aa64dfr0_el1
>>>> +	ubfx    x1, x1, #52, #4
>>>> +	cbz     x1, 1f
>>>> +
>>>> +	// Enable BRBE for the non-secure world.
>>>> +	ldr     x1, =(0x3 << 32)
>>>> +	orr     x0, x0, x1
>>>> +
>>>
>>> I assume this is the `SBRBE` field, which naming-wise sounds like it controls
>>> Secure rather than Non-Secure (e,g. by way of comparison to `NSPB`). Is that
>>
>> Right, that is some what counter-intuitive.
>>
>>> correct? What effect does the value 0x3 have?
>>
>> As per the definition above.
>>
>> 0b11	 This control does not cause any direct accesses to BRBE registers or
>>          instruction to be trapped, and does not cause any Exception levels to
>> 	 be a prohibited region.
>>
>> This basically allows BRBE usage in EL2/EL1.
> 
> Thanks for this!
> 
> Just to check, my understanding, there's nothing else that we need to
> initialize to ensure that BRBE won't start recording unexpectedly
> out-of-reset, becuase in BRBCR_EL* the E*BRE bits all warm-reset to 0
> and hence prevent recording in any of EL0/EL1/EL2 (and BRBE never
> records at EL3). Is that right?

Right, that is my understanding as well. Those required bits that start
BRBE recording, always warm-reset to 0.

> 
> Assuming so, I'll take this as-is.
> 
> Thanks,
> Mark.
> 


From sashal at kernel.org  Mon Jan 17 18:39:08 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:39:08 -0500
Subject: [PATCH AUTOSEL 5.10 057/116] gpio: aspeed: Convert aspeed_gpio.lock
 to raw_spinlock
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-57-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit 61a7904b6ace99b1bde0d0e867fa3097f5c8cee2 ]

The gpio-aspeed driver implements an irq_chip which need to be invoked
from hardirq context. Since spin_lock() can sleep with PREEMPT_RT, it is
no longer legal to invoke it while interrupts are disabled.
This also causes lockdep to complain about:
[    0.649797] [ BUG: Invalid wait context ]
because aspeed_gpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed.c | 52 +++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index b966f5e28ebff..e0d5d80ec8e0f 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -53,7 +53,7 @@ struct aspeed_gpio_config {
 struct aspeed_gpio {
 	struct gpio_chip chip;
 	struct irq_chip irqc;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 	const struct aspeed_gpio_config *config;
@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 	unsigned long flags;
 	bool copro;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	__aspeed_gpio_set(gc, offset, val);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (!have_input(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg &= ~GPIO_BIT(offset);
@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 	if (!have_output(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg |= GPIO_BIT(offset);
@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 	if (!have_output(gpio, offset))
 		return GPIO_LINE_DIRECTION_IN;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
 }
@@ -539,14 +539,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	iowrite32(bit, status_addr);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
@@ -565,7 +565,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	reg = ioread32(addr);
@@ -577,7 +577,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_mask(struct irq_data *d)
@@ -629,7 +629,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
@@ -649,7 +649,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -719,7 +719,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	treg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	val = readl(treg);
@@ -733,7 +733,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -859,7 +859,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 		return rc;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	if (timer_allocation_registered(gpio, offset)) {
 		rc = unregister_allocated_timer(gpio, offset);
@@ -919,7 +919,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 	configure_timer(gpio, offset, i);
 
 out:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -930,13 +930,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
 	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	rc = unregister_allocated_timer(gpio, offset);
 	if (!rc)
 		configure_timer(gpio, offset, 0);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -1018,7 +1018,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0xff) {
@@ -1039,7 +1039,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 	if (bit)
 		*bit = GPIO_OFFSET(offset);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
@@ -1063,7 +1063,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0) {
@@ -1077,7 +1077,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		aspeed_gpio_change_cmd_source(gpio, bank, bindex,
 					      GPIO_CMDSRC_ARM);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);
@@ -1151,7 +1151,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->base))
 		return PTR_ERR(gpio->base);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
 	if (!gpio_id)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:39:23 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:39:23 -0500
Subject: [PATCH AUTOSEL 5.10 072/116] arm64: dts: ls1028a-qds: move rtc node
 to the correct i2c bus
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-72-sashal@kernel.org>

From: Biwen Li <biwen.li at nxp.com>

[ Upstream commit cbe9d948eadfe352ad45495a7cc5bf20a1b29d90 ]

The i2c rtc is on i2c2 bus not i2c1 bus, so fix it in dts.

Signed-off-by: Biwen Li <biwen.li at nxp.com>
Signed-off-by: Li Yang <leoyang.lil at nxp.com>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 13cdc958ba3ea..71858c9376c25 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -261,11 +261,6 @@ temperature-sensor at 4c {
 				vcc-supply = <&sb_3v3>;
 			};
 
-			rtc at 51 {
-				compatible = "nxp,pcf2129";
-				reg = <0x51>;
-			};
-
 			eeprom at 56 {
 				compatible = "atmel,24c512";
 				reg = <0x56>;
@@ -307,6 +302,15 @@ mux: mux-controller {
 
 };
 
+&i2c1 {
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf2129";
+		reg = <0x51>;
+	};
+};
+
 &enetc_port1 {
 	phy-handle = <&qds_phy1>;
 	phy-connection-type = "rgmii-id";
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:39:58 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:39:58 -0500
Subject: [PATCH AUTOSEL 5.10 107/116] net: gemini: allow any RGMII interface
 mode
In-Reply-To: <20220118024007.1950576-1-sashal@kernel.org>
References: <20220118024007.1950576-1-sashal@kernel.org>
Message-ID: <20220118024007.1950576-107-sashal@kernel.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

[ Upstream commit 4e4f325a0a55907b14f579e6b1a38c53755e3de2 ]

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Link: https://lore.kernel.org/r/E1n4mpT-002PLd-Ha at rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 8df6f081f2447..d11fcfd927c0b 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:43:26 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:43:26 -0500
Subject: [PATCH AUTOSEL 5.4 07/73] ARM: shmobile: rcar-gen2: Add missing
 of_node_put()
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-7-sashal@kernel.org>

From: Wan Jiabing <wanjiabing at vivo.com>

[ Upstream commit 85744f2d938c5f3cfc44cb6533c157469634da93 ]

Fix following coccicheck warning:
./arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c:156:1-33: Function
for_each_matching_node_and_match should have of_node_put() before break
and goto.

Early exits from for_each_matching_node_and_match() should decrement the
node reference counter.

Signed-off-by: Wan Jiabing <wanjiabing at vivo.com>
Link: https://lore.kernel.org/r/20211018014503.7598-1-wanjiabing at vivo.com
Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
index ee949255ced3f..09ef73b99dd86 100644
--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c
@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void)
 		return -ENODEV;
 
 	for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) {
-		if (!of_device_is_available(np))
+		if (!of_device_is_available(np)) {
+			of_node_put(np);
 			break;
+		}
 
 		ret = of_property_read_u32(np, "reg", &addr);
 		if (ret)	/* Skip invalid entry and continue */
@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void)
 		quirk = kzalloc(sizeof(*quirk), GFP_KERNEL);
 		if (!quirk) {
 			ret = -ENOMEM;
+			of_node_put(np);
 			goto err_mem;
 		}
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:43:32 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:43:32 -0500
Subject: [PATCH AUTOSEL 5.4 13/73] EDAC/synopsys: Use the quirk for version
 instead of ddr version
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-13-sashal@kernel.org>

From: Dinh Nguyen <dinguyen at kernel.org>

[ Upstream commit bd1d6da17c296bd005bfa656952710d256e77dd3 ]

Version 2.40a supports DDR_ECC_INTR_SUPPORT for a quirk, so use that
quirk to determine a call to setup_address_map().

Signed-off-by: Dinh Nguyen <dinguyen at kernel.org>
Signed-off-by: Borislav Petkov <bp at suse.de>
Reviewed-by: Michal Simek <michal.simek at xilinx.com>
Link: https://lkml.kernel.org/r/20211012190709.1504152-1-dinguyen at kernel.org
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/edac/synopsys_edac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 6becf3363ad57..d23a0782fb49c 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -1351,8 +1351,7 @@ static int mc_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "xlnx,zynqmp-ddrc-2.40a"))
+	if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT)
 		setup_address_map(priv);
 #endif
 
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:43:33 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:43:33 -0500
Subject: [PATCH AUTOSEL 5.4 14/73] ARM: imx: rename DEBUG_IMX21_IMX27_UART to
 DEBUG_IMX27_UART
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-14-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 8bcbd0cd739b5..5e2b44a9df18c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -400,12 +400,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1472,7 +1472,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1529,12 +1529,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index c8eb83d4b8964..3edbb3c5b42bf 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -11,13 +11,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -26,6 +19,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -112,10 +112,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:43:41 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:43:41 -0500
Subject: [PATCH AUTOSEL 5.4 22/73] usb: uhci: add aspeed ast2600 uhci support
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-22-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 70dbd95c3f063..be9e9db7cad10 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:43:51 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:43:51 -0500
Subject: [PATCH AUTOSEL 5.4 32/73] gpio: aspeed: Convert aspeed_gpio.lock to
 raw_spinlock
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-32-sashal@kernel.org>

From: Iwona Winiarska <iwona.winiarska at intel.com>

[ Upstream commit 61a7904b6ace99b1bde0d0e867fa3097f5c8cee2 ]

The gpio-aspeed driver implements an irq_chip which need to be invoked
from hardirq context. Since spin_lock() can sleep with PREEMPT_RT, it is
no longer legal to invoke it while interrupts are disabled.
This also causes lockdep to complain about:
[    0.649797] [ BUG: Invalid wait context ]
because aspeed_gpio.lock (spin_lock_t) is taken under irq_desc.lock
(raw_spinlock_t).
Let's use of raw_spinlock_t instead of spinlock_t.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Bartosz Golaszewski <brgl at bgdev.pl>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/gpio/gpio-aspeed.c | 52 +++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 26 deletions(-)

diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c
index 2820c59b5f071..22e0d6fcab1c4 100644
--- a/drivers/gpio/gpio-aspeed.c
+++ b/drivers/gpio/gpio-aspeed.c
@@ -53,7 +53,7 @@ struct aspeed_gpio_config {
 struct aspeed_gpio {
 	struct gpio_chip chip;
 	struct irq_chip irqc;
-	spinlock_t lock;
+	raw_spinlock_t lock;
 	void __iomem *base;
 	int irq;
 	const struct aspeed_gpio_config *config;
@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
 	unsigned long flags;
 	bool copro;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	__aspeed_gpio_set(gc, offset, val);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (!have_input(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg &= ~GPIO_BIT(offset);
@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset)
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 	if (!have_output(gpio, offset))
 		return -ENOTSUPP;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	reg = ioread32(addr);
 	reg |= GPIO_BIT(offset);
@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
 	if (!have_output(gpio, offset))
 		return 1;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return !val;
 
@@ -540,14 +540,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d)
 
 	status_addr = bank_reg(gpio, bank, reg_irq_status);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	iowrite32(bit, status_addr);
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
@@ -566,7 +566,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	addr = bank_reg(gpio, bank, reg_irq_enable);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	reg = ioread32(addr);
@@ -578,7 +578,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 }
 
 static void aspeed_gpio_irq_mask(struct irq_data *d)
@@ -630,7 +630,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 		return -EINVAL;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	addr = bank_reg(gpio, bank, reg_irq_type0);
@@ -650,7 +650,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type)
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	irq_set_handler_locked(d, handler);
 
@@ -720,7 +720,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	treg = bank_reg(gpio, to_bank(offset), reg_tolerance);
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 	copro = aspeed_gpio_copro_request(gpio, offset);
 
 	val = readl(treg);
@@ -734,7 +734,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
 
 	if (copro)
 		aspeed_gpio_copro_release(gpio, offset);
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return 0;
 }
@@ -860,7 +860,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 		return rc;
 	}
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	if (timer_allocation_registered(gpio, offset)) {
 		rc = unregister_allocated_timer(gpio, offset);
@@ -920,7 +920,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset,
 	configure_timer(gpio, offset, i);
 
 out:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -931,13 +931,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset)
 	unsigned long flags;
 	int rc;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	rc = unregister_allocated_timer(gpio, offset);
 	if (!rc)
 		configure_timer(gpio, offset, 0);
 
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 
 	return rc;
 }
@@ -1019,7 +1019,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0xff) {
@@ -1040,7 +1040,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
 	if (bit)
 		*bit = GPIO_OFFSET(offset);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio);
@@ -1064,7 +1064,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		return -EINVAL;
 	bindex = offset >> 3;
 
-	spin_lock_irqsave(&gpio->lock, flags);
+	raw_spin_lock_irqsave(&gpio->lock, flags);
 
 	/* Sanity check, this shouldn't happen */
 	if (gpio->cf_copro_bankmap[bindex] == 0) {
@@ -1078,7 +1078,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
 		aspeed_gpio_change_cmd_source(gpio, bank, bindex,
 					      GPIO_CMDSRC_ARM);
  bail:
-	spin_unlock_irqrestore(&gpio->lock, flags);
+	raw_spin_unlock_irqrestore(&gpio->lock, flags);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio);
@@ -1151,7 +1151,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 	if (IS_ERR(gpio->base))
 		return PTR_ERR(gpio->base);
 
-	spin_lock_init(&gpio->lock);
+	raw_spin_lock_init(&gpio->lock);
 
 	gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node);
 	if (!gpio_id)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:44:03 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:44:03 -0500
Subject: [PATCH AUTOSEL 5.4 44/73] arm64: dts: ls1028a-qds: move rtc node to
 the correct i2c bus
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-44-sashal@kernel.org>

From: Biwen Li <biwen.li at nxp.com>

[ Upstream commit cbe9d948eadfe352ad45495a7cc5bf20a1b29d90 ]

The i2c rtc is on i2c2 bus not i2c1 bus, so fix it in dts.

Signed-off-by: Biwen Li <biwen.li at nxp.com>
Signed-off-by: Li Yang <leoyang.lil at nxp.com>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 078a5010228cd..0b3a93c4155d2 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -161,11 +161,6 @@ temperature-sensor at 4c {
 				vcc-supply = <&sb_3v3>;
 			};
 
-			rtc at 51 {
-				compatible = "nxp,pcf2129";
-				reg = <0x51>;
-			};
-
 			eeprom at 56 {
 				compatible = "atmel,24c512";
 				reg = <0x56>;
@@ -209,6 +204,15 @@ mux: mux-controller {
 
 };
 
+&i2c1 {
+	status = "okay";
+
+	rtc at 51 {
+		compatible = "nxp,pcf2129";
+		reg = <0x51>;
+	};
+};
+
 &enetc_port1 {
 	phy-handle = <&qds_phy1>;
 	phy-connection-type = "rgmii-id";
-- 
2.34.1



From npiggin at gmail.com  Mon Jan 17 18:46:01 2022
From: npiggin at gmail.com (Nicholas Piggin)
Date: Tue, 18 Jan 2022 12:46:01 +1000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
Message-ID: <1642472965.lgfksp6krp.astroid@bobo.none>

Excerpts from Dave Hansen's message of December 29, 2021 2:14 am:
> On 12/28/21 2:26 AM, Kefeng Wang wrote:
>>>> There are some disadvantages about this feature[2], one of the main
>>>> concerns is the possible memory fragmentation/waste in some scenarios,
>>>> also archs must ensure that any arch specific vmalloc allocations that
>>>> require PAGE_SIZE mappings(eg, module alloc with STRICT_MODULE_RWX)
>>>> use the VM_NO_HUGE_VMAP flag to inhibit larger mappings.
>>> That just says that x86 *needs* PAGE_SIZE allocations.? But, what
>>> happens if VM_NO_HUGE_VMAP is not passed (like it was in v1)?? Will the
>>> subsequent permission changes just fragment the 2M mapping?
>> 
>> Yes, without VM_NO_HUGE_VMAP, it could fragment the 2M mapping.
>> 
>> When module alloc with STRICT_MODULE_RWX on x86, it calls
>> __change_page_attr()
>> 
>> from set_memory_ro/rw/nx which will split large page, so there is no
>> need to make
>> 
>> module alloc with HUGE_VMALLOC.
> 
> This all sounds very fragile to me.  Every time a new architecture would
> get added for huge vmalloc() support, the developer needs to know to go
> find that architecture's module_alloc() and add this flag.

This is documented in the Kconfig.

 #
 #  Archs that select this would be capable of PMD-sized vmaps (i.e.,
 #  arch_vmap_pmd_supported() returns true), and they must make no assumptions
 #  that vmalloc memory is mapped with PAGE_SIZE ptes. The VM_NO_HUGE_VMAP flag
 #  can be used to prohibit arch-specific allocations from using hugepages to
 #  help with this (e.g., modules may require it).
 #
 config HAVE_ARCH_HUGE_VMALLOC
         depends on HAVE_ARCH_HUGE_VMAP
         bool

Is it really fair to say it's *very* fragile? Surely it's reasonable to 
read the (not very long) documentation ad understand the consequences for
the arch code before enabling it.

> They next
> guy is going to forget, just like you did.

The miss here could just be a simple oversight or thinko, and caught by 
review, as happens to a lot of things.

> 
> Considering that this is not a hot path, a weak function would be a nice
> choice:
> 
> /* vmalloc() flags used for all module allocations. */
> unsigned long __weak arch_module_vm_flags()
> {
> 	/*
> 	 * Modules use a single, large vmalloc().  Different
> 	 * permissions are applied later and will fragment
> 	 * huge mappings.  Avoid using huge pages for modules.
> 	 */
> 	return VM_NO_HUGE_VMAP;
> }
> 
> Stick that in some the common module code, next to:

Then they have to think about it even less, so I don't know if that's an 
improvement. I don't know what else an arch might be doing with these
allocations, at least modules will blow up pretty quickly, who knows 
what other rare code relies on 4k vmalloc mappings?

The huge vmalloc option is not supposed to be easy to enable. This is 
the same problem Andy was having with the TLB shootdown patches, he 
didn't read the documentation and thought it was supposed to be a 
trivial thing anybody could enable without thinking about it, and was
dutifully pointing out the the nasty "bugs" the feature has in it if
x86 were to enable it improperly.

Thanks,
Nick

> 
>> void * __weak module_alloc(unsigned long size)
>> {
>>         return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
> ...
> 
> Then, put arch_module_vm_flags() in *all* of the module_alloc()
> implementations, including the generic one.  That way (even with a new
> architecture) whoever copies-and-pastes their module_alloc()
> implementation is likely to get it right.  The next guy who just does a
> "select HAVE_ARCH_HUGE_VMALLOC" will hopefully just work.
> 
> VM_FLUSH_RESET_PERMS could probably be dealt with in the same way.
> 


From sashal at kernel.org  Mon Jan 17 18:44:27 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:44:27 -0500
Subject: [PATCH AUTOSEL 5.4 68/73] net: gemini: allow any RGMII interface mode
In-Reply-To: <20220118024432.1952028-1-sashal@kernel.org>
References: <20220118024432.1952028-1-sashal@kernel.org>
Message-ID: <20220118024432.1952028-68-sashal@kernel.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

[ Upstream commit 4e4f325a0a55907b14f579e6b1a38c53755e3de2 ]

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Link: https://lore.kernel.org/r/E1n4mpT-002PLd-Ha at rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index c9fb1ec625d8b..a8a8b77c1611e 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -304,21 +304,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -388,6 +388,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:46:09 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:46:09 -0500
Subject: [PATCH AUTOSEL 4.19 08/59] ARM: imx: rename DEBUG_IMX21_IMX27_UART to
 DEBUG_IMX27_UART
In-Reply-To: <20220118024701.1952911-1-sashal@kernel.org>
References: <20220118024701.1952911-1-sashal@kernel.org>
Message-ID: <20220118024701.1952911-8-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 01c760929c9e4..12a023c542e45 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -405,12 +405,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1454,7 +1454,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1507,12 +1507,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e975ad1f..c750cc9876f6d 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -14,13 +14,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -29,6 +22,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -115,10 +115,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:46:16 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:46:16 -0500
Subject: [PATCH AUTOSEL 4.19 15/59] usb: uhci: add aspeed ast2600 uhci support
In-Reply-To: <20220118024701.1952911-1-sashal@kernel.org>
References: <20220118024701.1952911-1-sashal@kernel.org>
Message-ID: <20220118024701.1952911-15-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 89700e26fb296..813ff3660e9f1 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:46:56 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:46:56 -0500
Subject: [PATCH AUTOSEL 4.19 55/59] net: gemini: allow any RGMII interface mode
In-Reply-To: <20220118024701.1952911-1-sashal@kernel.org>
References: <20220118024701.1952911-1-sashal@kernel.org>
Message-ID: <20220118024701.1952911-55-sashal@kernel.org>

From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>

[ Upstream commit 4e4f325a0a55907b14f579e6b1a38c53755e3de2 ]

The four RGMII interface modes take care of the required RGMII delay
configuration at the PHY and should not be limited by the network MAC
driver. Sadly, gemini was only permitting RGMII mode with no delays,
which would require the required delay to be inserted via PCB tracking
or by the MAC.

However, there are designs that require the PHY to add the delay, which
is impossible without Gemini permitting the other three PHY interface
modes. Fix the driver to allow these.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Link: https://lore.kernel.org/r/E1n4mpT-002PLd-Ha at rmk-PC.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 5242687060b44..f8a3d1fecb0a5 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -304,21 +304,21 @@ static void gmac_speed_set(struct net_device *netdev)
 	switch (phydev->speed) {
 	case 1000:
 		status.bits.speed = GMAC_SPEED_1000;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_1000;
 		netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n",
 			   phydev_name(phydev));
 		break;
 	case 100:
 		status.bits.speed = GMAC_SPEED_100;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n",
 			   phydev_name(phydev));
 		break;
 	case 10:
 		status.bits.speed = GMAC_SPEED_10;
-		if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
+		if (phy_interface_mode_is_rgmii(phydev->interface))
 			status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
 		netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n",
 			   phydev_name(phydev));
@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev)
 		status.bits.mii_rmii = GMAC_PHY_GMII;
 		break;
 	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
 		netdev_dbg(netdev,
 			   "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n");
 		status.bits.mii_rmii = GMAC_PHY_RGMII_100_10;
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:48:28 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:48:28 -0500
Subject: [PATCH AUTOSEL 4.14 16/56] ARM: imx: rename DEBUG_IMX21_IMX27_UART to
 DEBUG_IMX27_UART
In-Reply-To: <20220118024908.1953673-1-sashal@kernel.org>
References: <20220118024908.1953673-1-sashal@kernel.org>
Message-ID: <20220118024908.1953673-16-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index d6cf18a0cb0a9..b70ed4c7691e5 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -363,12 +363,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1398,7 +1398,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1451,12 +1451,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e975ad1f..c750cc9876f6d 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -14,13 +14,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -29,6 +22,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -115,10 +115,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:48:34 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:48:34 -0500
Subject: [PATCH AUTOSEL 4.14 22/56] usb: uhci: add aspeed ast2600 uhci support
In-Reply-To: <20220118024908.1953673-1-sashal@kernel.org>
References: <20220118024908.1953673-1-sashal@kernel.org>
Message-ID: <20220118024908.1953673-22-sashal@kernel.org>

From: Neal Liu <neal_liu at aspeedtech.com>

[ Upstream commit 554abfe2eadec97d12c71d4a69da1518478f69eb ]

Enable ast2600 uhci quirks.

Signed-off-by: Neal Liu <neal_liu at aspeedtech.com>
Link: https://lore.kernel.org/r/20211126100021.2331024-1-neal_liu at aspeedtech.com
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/usb/host/uhci-platform.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c
index 6cb16d4b22578..4e91f7b21a796 100644
--- a/drivers/usb/host/uhci-platform.c
+++ b/drivers/usb/host/uhci-platform.c
@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev)
 				num_ports);
 		}
 		if (of_device_is_compatible(np, "aspeed,ast2400-uhci") ||
-		    of_device_is_compatible(np, "aspeed,ast2500-uhci")) {
+		    of_device_is_compatible(np, "aspeed,ast2500-uhci") ||
+		    of_device_is_compatible(np, "aspeed,ast2600-uhci")) {
 			uhci->is_aspeed = 1;
 			dev_info(&pdev->dev,
 				 "Enabled Aspeed implementation workarounds\n");
-- 
2.34.1



From sashal at kernel.org  Mon Jan 17 18:50:49 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 21:50:49 -0500
Subject: [PATCH AUTOSEL 4.9 07/33] ARM: imx: rename DEBUG_IMX21_IMX27_UART to
 DEBUG_IMX27_UART
In-Reply-To: <20220118025116.1954375-1-sashal@kernel.org>
References: <20220118025116.1954375-1-sashal@kernel.org>
Message-ID: <20220118025116.1954375-7-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index bb8f39fe3a225..8349a171a8f3c 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -341,12 +341,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1350,7 +1350,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1403,12 +1403,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e975ad1f..c750cc9876f6d 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -14,13 +14,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -29,6 +22,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -115,10 +115,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From npiggin at gmail.com  Mon Jan 17 18:52:56 2022
From: npiggin at gmail.com (Nicholas Piggin)
Date: Tue, 18 Jan 2022 12:52:56 +1000
Subject: [PATCH v2 1/3] mm: vmalloc: Let user to control huge vmalloc
 default behavior
In-Reply-To: <20211227145903.187152-2-wangkefeng.wang@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-2-wangkefeng.wang@huawei.com>
Message-ID: <1642473992.qrnqczjfna.astroid@bobo.none>

Excerpts from Kefeng Wang's message of December 28, 2021 12:59 am:
> Introduce HUGE_VMALLOC_DEFAULT_ENABLED and make it default y, this
> let user to choose whether or not enable huge vmalloc mappings by
> default.
> 
> Meanwhile, add new hugevmalloc=on/off parameter to enable or disable
> this feature at boot time, nohugevmalloc is still supported and
> equivalent to hugevmalloc=off.

Runtime options are bad enough, Kconfig and boot options are even worse.

The 'nohugevmalloc' option mirrors 'nohugeiomap' and is not expected to
ever be understood by an administrator unless a kernel developer is 
working with them to hunt down a regression.

IMO there should be no new options. You could switch it off for 
CONFIG_BASE_SMALL perhaps, and otherwise just try to work on heuristics
first. Bring in new options once it's proven they're needed.

Aside from that, thanks for working on these ports, great work.

Thanks,
Nick


From wenst at chromium.org  Mon Jan 17 18:55:05 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 18 Jan 2022 10:55:05 +0800
Subject: [PATCH 7/7] pinctrl: mediatek: paris: Support generic
 PIN_CONFIG_DRIVE_STRENGTH_UA
In-Reply-To: <b1d5ca006860c85edd971ea9e20880ec8ba7f842.camel@mediatek.com>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-8-wenst@chromium.org>
 <b1d5ca006860c85edd971ea9e20880ec8ba7f842.camel@mediatek.com>
Message-ID: <CAGXv+5Egf-XM_Y8+ujYrx9k0UgAkpPj9DVpZEVz2hWdGzws2ZA@mail.gmail.com>

Hi,

On Tue, Jan 18, 2022 at 10:36 AM zhiyong.tao <zhiyong.tao at mediatek.com> wrote:
>
> On Tue, 2022-01-11 at 19:22 +0800, Chen-Yu Tsai wrote:
> > Some of the MediaTek chips that utilize the Paris pinctrl driver
> > library
> > support a lower drive strength (<= 1mA) than the standard drive
> > strength
> > settings (2~16 mA) on certain pins. This was previously supported by
> > the
> > custom MTK_PIN_CONFIG_DRV_ADV parameter along with the
> > "mediatek,drive-strength-adv" device tree property.
> >
> > The drive strength values for this hardware are 125, 250, 500, and
> > 1000 mA,
> > and can be readily described by the existing "drive-strength-
> > microamp",
> > which then gets parsed by the generic pinconf library into the
> > parameter
> > PIN_CONFIG_DRIVE_STRENGTH_UA.
> >
> > Add support for PIN_CONFIG_DRIVE_STRENGTH_UA while keeping the old
> > custom parameter around for backward compatibility.
> >
> > Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> > ---
> >
> > The indentation in the switch/case blocks is getting somewhat out of
> > control. I also have some cleanup changes to reverse the logic of the
> > if/break statements. Not sure if it should be done before or after
> > this
> > patch though.
> >
> > ---
> >  drivers/pinctrl/mediatek/pinctrl-paris.c | 84
> > ++++++++++++++++++++++++
> >  1 file changed, 84 insertions(+)
> >
> > diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c
> > b/drivers/pinctrl/mediatek/pinctrl-paris.c
> > index 678c8aa33012..5a94903ae372 100644
> > --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> > +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> > @@ -48,6 +48,53 @@ static const char * const mtk_gpio_functions[] = {
> >       "func12", "func13", "func14", "func15",
> >  };
> >
> > +/*
> > + * This section supports converting to/from custom
> > MTK_PIN_CONFIG_DRV_ADV
> > + * and standard PIN_CONFIG_DRIVE_STRENGTH_UA pin configs.
> > + *
> > + * The custom value encodes three hardware bits as follows:
> > + *
> > + *   |           Bits           |
> > + *   | 2 (E1) | 1 (E0) | 0 (EN) | drive strength (uA)
> > + *   ------------------------------------------------
> > + *   |    x   |    x   |    0   | disabled, use standard drive
> > strength
> > + *   -------------------------------------
> > + *   |    0   |    0   |    1   |  125 uA
> > + *   |    0   |    1   |    1   |  250 uA
> > + *   |    1   |    0   |    1   |  500 uA
> > + *   |    1   |    1   |    1   | 1000 uA
> > + */
> > +static const int mtk_drv_adv_uA[] = { 125, 250, 500, 1000 };
> > +
> > +static int mtk_drv_adv_to_uA(int val)
> > +{
> > +     /* This should never happen. */
> > +     if (WARN_ON_ONCE(val < 0 || val > 7))
> > +             return -EINVAL;
> > +
> > +     /* Bit 0 simply enables this hardware part */
> > +     if (!(val & BIT(0)))
> > +             return -EINVAL;
> > +
> > +     return mtk_drv_adv_uA[(val >> 1)];
> > +}
> > +
> > +static int mtk_drv_uA_to_adv(int val)
> > +{
> > +     switch (val) {
> > +     case 125:
> > +             return 0x1;
> > +     case 250:
> > +             return 0x3;
> > +     case 500:
> > +             return 0x5;
> > +     case 1000:
> > +             return 0x7;
> > +     }
> > +
> > +     return -EINVAL;
> > +}
> > +
> >  static int mtk_pinmux_gpio_request_enable(struct pinctrl_dev
> > *pctldev,
> >                                         struct pinctrl_gpio_range
> > *range,
> >                                         unsigned int pin)
> > @@ -151,11 +198,38 @@ static int mtk_pinconf_get(struct pinctrl_dev
> > *pctldev,
> >
> >               break;
> >       case PIN_CONFIG_DRIVE_STRENGTH:
> > +             if (hw->soc->adv_drive_get) {
> > +                     err = hw->soc->adv_drive_get(hw, desc, &ret);
> > +                     if (!err) {
> > +                             err = mtk_drv_adv_to_uA(ret);
> > +                             if (err > 0) {
> > +                                     /* PIN_CONFIG_DRIVE_STRENGTH_UA
> > used */
> > +                                     err = -EINVAL;
> > +                                     break;
> > +                             }
> > +                     }
> > +             }
> > +
> Hi Chen-Yu,
>
> PIN_CONFIG_DRIVE_STRENGTH is seems used for 2/4/6/8ma, it is not used
> for 125/250/500/1000ma. why you change here?

If 125/250/500/1000uA is used, that mode takes precedence over 2/4/6/8 mA.
To give a correct readback, if 125/250/500/1000 uA is active, we should
return -EINVAL here to tell the pin config core that PIN_CONFIG_DRIVE_STRENGTH
is not active.

Otherwise when one reads

    /sys/kernel/debug/pinctrl/10005000.pinctrl-pinctrl_paris/pinconf-pins

it would return

    ... output drive strength (X mA), output drive strength (Y uA), ...

where the first "mA" setting isn't actually active in hardware.

> >               if (hw->soc->drive_get)
> >                       err = hw->soc->drive_get(hw, desc, &ret);
> >               else
> >                       err = -ENOTSUPP;
> >               break;
> > +     case PIN_CONFIG_DRIVE_STRENGTH_UA:
> > +             if (hw->soc->adv_drive_get) {
> > +                     err = hw->soc->adv_drive_get(hw, desc, &ret);
> > +                     if (err)
> > +                             break;
> > +                     err = mtk_drv_adv_to_uA(ret);
> > +                     if (err < 0)
> > +                             break;
> > +
> > +                     ret = err;
> > +                     err = 0;
> > +             } else {
> > +                     err = -ENOTSUPP;
> > +             }
> > +             break;
>
> Hi Chen-Yu,
> For PIN_CONFIG_DRIVE_STRENGTH_UA case, How can we use in dts node ?
> Thanks.

My original thought was to have either

    drive-strength = <2/4/6/8>;

or

    drive-strength-microamp = <125/250/500/1000>;

but not both. However I haven't figured out how to write the binding schema
to have the two properties be mutually exclusive. I'm not sure this would
be accepted either.

At the driver level, it should also have a check for the existence of
"drive-strength-microamp" to enable or disable the special mode.

Regards
ChenYu

> >       case MTK_PIN_CONFIG_TDSEL:
> >       case MTK_PIN_CONFIG_RDSEL:
> >               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
> > @@ -271,6 +345,16 @@ static int mtk_pinconf_set(struct pinctrl_dev
> > *pctldev, unsigned int pin,
> >               else
> >                       err = -ENOTSUPP;
> >               break;
> > +     case PIN_CONFIG_DRIVE_STRENGTH_UA:
> > +             if (hw->soc->adv_drive_set) {
> > +                     err = mtk_drv_uA_to_adv(arg);
> > +                     if (err < 0)
> > +                             break;
> > +                     err = hw->soc->adv_drive_set(hw, desc, err);
> > +             } else {
> > +                     err = -ENOTSUPP;
> > +             }
> > +             break;
> >       case MTK_PIN_CONFIG_TDSEL:
> >       case MTK_PIN_CONFIG_RDSEL:
> >               reg = (param == MTK_PIN_CONFIG_TDSEL) ?
>


From victor.liu at nxp.com  Mon Jan 17 18:59:18 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Tue, 18 Jan 2022 10:59:18 +0800
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
Message-ID: <20220118025918.1444288-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
 drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
 include/linux/phy/phy-mipi-dphy.h                | 4 +++-
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..f1fdcdf763ee 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
 }
 
 /*
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..8a818cdb7606 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre,
+				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..67b0a17be7e3 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
+			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
 
 	/*
 	 * The value of counter for HS Tlpx Time
diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..ab1f736fbcd3 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -6,6 +6,8 @@
 #ifndef __PHY_MIPI_DPHY_H_
 #define __PHY_MIPI_DPHY_H_
 
+#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8
+
 /**
  * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
  *
@@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
 	 * the transmitter prior to any associated Data Lane beginning
 	 * the transition from LP to HS mode.
 	 *
-	 * Minimum value: 8 UI
+	 * Minimum value: 8
 	 */
 	unsigned int		clk_pre;
 
-- 
2.25.1



From sashal at kernel.org  Mon Jan 17 19:07:59 2022
From: sashal at kernel.org (Sasha Levin)
Date: Mon, 17 Jan 2022 22:07:59 -0500
Subject: [PATCH AUTOSEL 4.4 06/29] ARM: imx: rename DEBUG_IMX21_IMX27_UART to
 DEBUG_IMX27_UART
In-Reply-To: <20220118030822.1955469-1-sashal@kernel.org>
References: <20220118030822.1955469-1-sashal@kernel.org>
Message-ID: <20220118030822.1955469-6-sashal@kernel.org>

From: Lukas Bulwahn <lukas.bulwahn at gmail.com>

[ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]

Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

So, rename this option to DEBUG_IMX27_UART and adjust dependencies in
Kconfig and rename the definitions to IMX27 as further clean-up.

This issue was discovered with ./scripts/checkkconfigsymbols.py, which
reported that DEBUG_IMX21_IMX27_UART depends on the non-existing config
SOC_IMX21.

Signed-off-by: Lukas Bulwahn <lukas.bulwahn at gmail.com>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Shawn Guo <shawnguo at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 arch/arm/Kconfig.debug            | 14 +++++++-------
 arch/arm/include/debug/imx-uart.h | 18 +++++++++---------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 9c3042da44402..a9ffbaedc9676 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -339,12 +339,12 @@ choice
 		  Say Y here if you want kernel low-level debugging support
 		  on i.MX25.
 
-	config DEBUG_IMX21_IMX27_UART
-		bool "i.MX21 and i.MX27 Debug UART"
-		depends on SOC_IMX21 || SOC_IMX27
+	config DEBUG_IMX27_UART
+		bool "i.MX27 Debug UART"
+		depends on SOC_IMX27
 		help
 		  Say Y here if you want kernel low-level debugging support
-		  on i.MX21 or i.MX27.
+		  on i.MX27.
 
 	config DEBUG_IMX28_UART
 		bool "i.MX28 Debug UART"
@@ -1263,7 +1263,7 @@ config DEBUG_IMX_UART_PORT
 	int "i.MX Debug UART Port Selection"
 	depends on DEBUG_IMX1_UART || \
 		   DEBUG_IMX25_UART || \
-		   DEBUG_IMX21_IMX27_UART || \
+		   DEBUG_IMX27_UART || \
 		   DEBUG_IMX31_UART || \
 		   DEBUG_IMX35_UART || \
 		   DEBUG_IMX50_UART || \
@@ -1314,12 +1314,12 @@ config DEBUG_LL_INCLUDE
 	default "debug/icedcc.S" if DEBUG_ICEDCC
 	default "debug/imx.S" if DEBUG_IMX1_UART || \
 				 DEBUG_IMX25_UART || \
-				 DEBUG_IMX21_IMX27_UART || \
+				 DEBUG_IMX27_UART || \
 				 DEBUG_IMX31_UART || \
 				 DEBUG_IMX35_UART || \
 				 DEBUG_IMX50_UART || \
 				 DEBUG_IMX51_UART || \
-				 DEBUG_IMX53_UART ||\
+				 DEBUG_IMX53_UART || \
 				 DEBUG_IMX6Q_UART || \
 				 DEBUG_IMX6SL_UART || \
 				 DEBUG_IMX6SX_UART || \
diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h
index bce58e975ad1f..c750cc9876f6d 100644
--- a/arch/arm/include/debug/imx-uart.h
+++ b/arch/arm/include/debug/imx-uart.h
@@ -14,13 +14,6 @@
 #define IMX1_UART_BASE_ADDR(n)	IMX1_UART##n##_BASE_ADDR
 #define IMX1_UART_BASE(n)	IMX1_UART_BASE_ADDR(n)
 
-#define IMX21_UART1_BASE_ADDR	0x1000a000
-#define IMX21_UART2_BASE_ADDR	0x1000b000
-#define IMX21_UART3_BASE_ADDR	0x1000c000
-#define IMX21_UART4_BASE_ADDR	0x1000d000
-#define IMX21_UART_BASE_ADDR(n)	IMX21_UART##n##_BASE_ADDR
-#define IMX21_UART_BASE(n)	IMX21_UART_BASE_ADDR(n)
-
 #define IMX25_UART1_BASE_ADDR	0x43f90000
 #define IMX25_UART2_BASE_ADDR	0x43f94000
 #define IMX25_UART3_BASE_ADDR	0x5000c000
@@ -29,6 +22,13 @@
 #define IMX25_UART_BASE_ADDR(n)	IMX25_UART##n##_BASE_ADDR
 #define IMX25_UART_BASE(n)	IMX25_UART_BASE_ADDR(n)
 
+#define IMX27_UART1_BASE_ADDR	0x1000a000
+#define IMX27_UART2_BASE_ADDR	0x1000b000
+#define IMX27_UART3_BASE_ADDR	0x1000c000
+#define IMX27_UART4_BASE_ADDR	0x1000d000
+#define IMX27_UART_BASE_ADDR(n)	IMX27_UART##n##_BASE_ADDR
+#define IMX27_UART_BASE(n)	IMX27_UART_BASE_ADDR(n)
+
 #define IMX31_UART1_BASE_ADDR	0x43f90000
 #define IMX31_UART2_BASE_ADDR	0x43f94000
 #define IMX31_UART3_BASE_ADDR	0x5000c000
@@ -115,10 +115,10 @@
 
 #ifdef CONFIG_DEBUG_IMX1_UART
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX1)
-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART)
-#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX21)
 #elif defined(CONFIG_DEBUG_IMX25_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX25)
+#elif defined(CONFIG_DEBUG_IMX27_UART)
+#define UART_PADDR	IMX_DEBUG_UART_BASE(IMX27)
 #elif defined(CONFIG_DEBUG_IMX31_UART)
 #define UART_PADDR	IMX_DEBUG_UART_BASE(IMX31)
 #elif defined(CONFIG_DEBUG_IMX35_UART)
-- 
2.34.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:06 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:06 +0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
Message-ID: <20220118030911.12815-1-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate
clock makes it easier for the UART driver to be compatible
with the baud rate requirements of the UART IP on different
meson chips. Add Meson S4 SoC compatible.

Yu Tu (5):
  tty: serial: meson: Move request the register region to probe
  tty: serial: meson: Use devm_ioremap_resource to get register mapped
    memory
  tty: serial: meson: Describes the calculation of the UART baud rate
    clock using a clock frame
  tty: serial: meson: Make some bit of the REG5 register writable
  tty: serial: meson: Added S4 SOC compatibility

V5 -> V6: Change error format as discussed in the email.
V4 -> V5: Change error format.
V3 -> V4: Change CCF to describe the UART baud rate clock as discussed
in the email.
V2 -> V3: add compatible = "amlogic,meson-gx-uart". Because it must change
the DTS before it can be deleted
V1 -> V2: Use CCF to describe the UART baud rate clock.Make some changes as
discussed in the email

Link:https://lore.kernel.org/linux-amlogic/20220110104214.25321-4-yu.tu at amlogic.com/

 drivers/tty/serial/meson_uart.c | 217 ++++++++++++++++++++++----------
 1 file changed, 149 insertions(+), 68 deletions(-)


base-commit: 4d66020dcef83314092f2c8c89152a8d122627e2
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:07 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:07 +0800
Subject: [PATCH V6 1/5] tty: serial: meson: Move request the register region
 to probe
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-2-yu.tu@amlogic.com>

This simplifies resetting the UART controller during probe
and will make it easier to integrate the common clock code
which will require the registers at probe time as well.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 45e00d928253..6b80e41b4cc1 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -395,24 +395,11 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	devm_iounmap(port->dev, port->membase);
-	port->membase = NULL;
-	devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
+	/* nothing to do */
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
-	if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
-				     dev_name(port->dev))) {
-		dev_err(port->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(port->dev, port->mapbase,
-					     port->mapsize);
-	if (!port->membase)
-		return -ENOMEM;
-
 	return 0;
 }
 
@@ -733,6 +720,18 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
+	if (!devm_request_mem_region(&pdev->dev, res_mem->start,
+				     resource_size(res_mem),
+				     dev_name(&pdev->dev))) {
+		dev_err(&pdev->dev, "Memory region busy\n");
+		return -EBUSY;
+	}
+
+	port->membase = devm_ioremap(&pdev->dev, res_mem->start,
+				     resource_size(res_mem));
+	if (IS_ERR(port->membase))
+		return PTR_ERR(port->membase);
+
 	ret = meson_uart_probe_clocks(pdev, port);
 	if (ret)
 		return ret;
@@ -754,10 +753,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, port);
 
 	/* reset port before registering (and possibly registering console) */
-	if (meson_uart_request_port(port) >= 0) {
-		meson_uart_reset(port);
-		meson_uart_release_port(port);
-	}
+	meson_uart_reset(port);
 
 	ret = uart_add_one_port(&meson_uart_driver, port);
 	if (ret)
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:08 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:08 +0800
Subject: [PATCH V6 2/5] tty: serial: meson: Use devm_ioremap_resource to get
 register mapped memory
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-3-yu.tu@amlogic.com>

Replace devm_request_mem_region and devm_ioremap with
devm_ioremap_resource to make the code cleaner.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 6b80e41b4cc1..7570958d010c 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -720,15 +720,7 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENOMEM;
 
-	if (!devm_request_mem_region(&pdev->dev, res_mem->start,
-				     resource_size(res_mem),
-				     dev_name(&pdev->dev))) {
-		dev_err(&pdev->dev, "Memory region busy\n");
-		return -EBUSY;
-	}
-
-	port->membase = devm_ioremap(&pdev->dev, res_mem->start,
-				     resource_size(res_mem));
+	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:09 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:09 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of the
 UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-4-yu.tu@amlogic.com>

Using the common Clock code to describe the UART baud rate clock
makes it easier for the UART driver to be compatible with the
baud rate requirements of the UART IP on different meson chips.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
 1 file changed, 142 insertions(+), 53 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 7570958d010c..92fa91c825e6 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/init.h>
@@ -65,9 +66,7 @@
 #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
 
 /* AML_UART_REG5 bits */
-#define AML_UART_BAUD_MASK		0x7fffff
 #define AML_UART_BAUD_USE		BIT(23)
-#define AML_UART_BAUD_XTAL		BIT(24)
 
 #define AML_UART_PORT_NUM		12
 #define AML_UART_PORT_OFFSET		6
@@ -76,6 +75,11 @@
 #define AML_UART_POLL_USEC		5
 #define AML_UART_TIMEOUT_USEC		10000
 
+struct meson_uart_data {
+	struct clk	*baud_clk;
+	bool		use_xtal_clk;
+};
+
 static struct uart_driver meson_uart_driver;
 
 static struct uart_port *meson_ports[AML_UART_PORT_NUM];
@@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
 
 static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
 {
+	struct meson_uart_data *private_data = port->private_data;
 	u32 val;
 
 	while (!meson_uart_tx_empty(port))
 		cpu_relax();
 
-	if (port->uartclk == 24000000) {
-		val = ((port->uartclk / 3) / baud) - 1;
-		val |= AML_UART_BAUD_XTAL;
-	} else {
-		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
-	}
+	val = readl(port->membase + AML_UART_REG5);
 	val |= AML_UART_BAUD_USE;
 	writel(val, port->membase + AML_UART_REG5);
+
+	clk_set_rate(private_data->baud_clk, baud);
 }
 
 static void meson_uart_set_termios(struct uart_port *port,
@@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
 
 static void meson_uart_release_port(struct uart_port *port)
 {
-	/* nothing to do */
+	struct meson_uart_data *private_data = port->private_data;
+
+	clk_disable_unprepare(private_data->baud_clk);
 }
 
 static int meson_uart_request_port(struct uart_port *port)
 {
+	struct meson_uart_data *private_data = port->private_data;
+	int ret;
+
+	ret = clk_prepare_enable(private_data->baud_clk);
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
@@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
 	.cons		= MESON_SERIAL_CONSOLE,
 };
 
-static inline struct clk *meson_uart_probe_clock(struct device *dev,
-						 const char *id)
-{
-	struct clk *clk = NULL;
-	int ret;
-
-	clk = devm_clk_get(dev, id);
-	if (IS_ERR(clk))
-		return clk;
-
-	ret = clk_prepare_enable(clk);
-	if (ret) {
-		dev_err(dev, "couldn't enable clk\n");
-		return ERR_PTR(ret);
-	}
-
-	devm_add_action_or_reset(dev,
-			(void(*)(void *))clk_disable_unprepare,
-			clk);
-
-	return clk;
-}
+static struct clk_div_table xtal_div_table[] = {
+	{0, 3},
+	{1, 1},
+	{2, 2},
+	{3, 2},
+};
 
-static int meson_uart_probe_clocks(struct platform_device *pdev,
-				   struct uart_port *port)
+static int meson_uart_probe_clocks(struct uart_port *port)
 {
-	struct clk *clk_xtal = NULL;
-	struct clk *clk_pclk = NULL;
-	struct clk *clk_baud = NULL;
+	struct meson_uart_data *private_data = port->private_data;
+	struct clk *clk_baud, *clk_xtal;
+	struct clk_hw *hw;
+	char clk_name[32];
+	struct clk_parent_data use_xtal_mux_parents[2] = {
+		{ .index = -1, },
+		{ .index = -1, },
+	};
 
-	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
-	if (IS_ERR(clk_pclk))
-		return PTR_ERR(clk_pclk);
+	clk_baud = devm_clk_get(port->dev, "baud");
+	if (IS_ERR(clk_baud)) {
+		dev_err(port->dev, "Failed to get the 'baud' clock\n");
+		return PTR_ERR(clk_baud);
+	}
 
-	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
+	clk_xtal = devm_clk_get(port->dev, "xtal");
 	if (IS_ERR(clk_xtal))
-		return PTR_ERR(clk_xtal);
-
-	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
-	if (IS_ERR(clk_baud))
-		return PTR_ERR(clk_baud);
+		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
+				     "Failed to get the 'xtal' clock\n");
+
+	if (private_data->use_xtal_clk) {
+		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+			 "xtal_div");
+		hw = devm_clk_hw_register_divider_table(port->dev,
+							clk_name,
+							__clk_get_name(clk_baud),
+							CLK_SET_RATE_NO_REPARENT,
+							port->membase + AML_UART_REG5,
+							26, 2,
+							CLK_DIVIDER_READ_ONLY,
+							xtal_div_table, NULL);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[1].hw = hw;
+	} else {
+		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+			 "clk81_div4");
+		hw = devm_clk_hw_register_fixed_factor(port->dev,
+						       clk_name,
+						       __clk_get_name(clk_baud),
+						       CLK_SET_RATE_NO_REPARENT,
+						       1, 4);
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		use_xtal_mux_parents[0].hw = hw;
+	}
 
-	port->uartclk = clk_get_rate(clk_baud);
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+		 "use_xtal");
+	hw = __devm_clk_hw_register_mux(port->dev, NULL,
+					clk_name,
+					ARRAY_SIZE(use_xtal_mux_parents),
+					NULL, NULL,
+					use_xtal_mux_parents,
+					CLK_SET_RATE_PARENT,
+					port->membase + AML_UART_REG5,
+					24, 0x1,
+					CLK_MUX_READ_ONLY,
+					NULL, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	port->uartclk = clk_hw_get_rate(hw);
+
+	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
+		 "baud_div");
+	hw = devm_clk_hw_register_divider(port->dev,
+					  clk_name,
+					  clk_hw_get_name(hw),
+					  CLK_SET_RATE_PARENT,
+					  port->membase + AML_UART_REG5,
+					  0, 23,
+					  CLK_DIVIDER_ROUND_CLOSEST,
+					  NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	private_data->baud_clk = hw->clk;
 
 	return 0;
 }
 
 static int meson_uart_probe(struct platform_device *pdev)
 {
+	struct meson_uart_data *private_data;
 	struct resource *res_mem;
 	struct uart_port *port;
+	struct clk *pclk;
 	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
 	int ret = 0;
 	int irq;
@@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (!res_mem)
 		return -ENODEV;
 
+	pclk = devm_clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(pclk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
+				     "Failed to get the 'pclk' clock\n");
+
+	ret = clk_prepare_enable(pclk);
+	if (ret)
+		return ret;
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return irq;
@@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
 	if (IS_ERR(port->membase))
 		return PTR_ERR(port->membase);
 
-	ret = meson_uart_probe_clocks(pdev, port);
-	if (ret)
-		return ret;
+	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
+				    GFP_KERNEL);
+	if (!private_data)
+		return -ENOMEM;
+
+	if (device_get_match_data(&pdev->dev))
+		private_data->use_xtal_clk = true;
 
 	port->iotype = UPIO_MEM;
 	port->mapbase = res_mem->start;
@@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
 	port->x_char = 0;
 	port->ops = &meson_uart_ops;
 	port->fifosize = fifosize;
+	port->private_data = private_data;
+
+	ret = meson_uart_probe_clocks(port);
+	if (ret)
+		return ret;
 
 	meson_ports[pdev->id] = port;
 	platform_set_drvdata(pdev, port);
@@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id meson_uart_dt_match[] = {
-	{ .compatible = "amlogic,meson6-uart" },
-	{ .compatible = "amlogic,meson8-uart" },
-	{ .compatible = "amlogic,meson8b-uart" },
-	{ .compatible = "amlogic,meson-gx-uart" },
+	{
+		.compatible = "amlogic,meson6-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson8b-uart",
+		.data = (void *)false,
+	},
+	{
+		.compatible = "amlogic,meson-gx-uart",
+		.data = (void *)true,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:10 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:10 +0800
Subject: [PATCH V6 4/5] tty: serial: meson: Make some bit of the REG5 register
 writable
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-5-yu.tu@amlogic.com>

The UART_REG5 register defaults to 0. The console port is set in
ROMCODE. But other UART ports default to 0, so make bit24 and
bit[26,27] writable so that the UART can choose a more
appropriate clock.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 92fa91c825e6..4e7b2b38ab0a 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -678,7 +678,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 							CLK_SET_RATE_NO_REPARENT,
 							port->membase + AML_UART_REG5,
 							26, 2,
-							CLK_DIVIDER_READ_ONLY,
+							CLK_DIVIDER_ROUND_CLOSEST,
 							xtal_div_table, NULL);
 		if (IS_ERR(hw))
 			return PTR_ERR(hw);
@@ -708,7 +708,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
 					CLK_SET_RATE_PARENT,
 					port->membase + AML_UART_REG5,
 					24, 0x1,
-					CLK_MUX_READ_ONLY,
+					CLK_MUX_ROUND_CLOSEST,
 					NULL, NULL);
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
-- 
2.33.1



From yu.tu at amlogic.com  Mon Jan 17 19:09:11 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Tue, 18 Jan 2022 11:09:11 +0800
Subject: [PATCH V6 5/5] tty: serial: meson: Added S4 SOC compatibility
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <20220118030911.12815-6-yu.tu@amlogic.com>

Make UART driver compatible with S4 SOC UART.

Signed-off-by: Yu Tu <yu.tu at amlogic.com>
---
 drivers/tty/serial/meson_uart.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
index 4e7b2b38ab0a..af95a4676d28 100644
--- a/drivers/tty/serial/meson_uart.c
+++ b/drivers/tty/serial/meson_uart.c
@@ -859,6 +859,10 @@ static const struct of_device_id meson_uart_dt_match[] = {
 		.compatible = "amlogic,meson-gx-uart",
 		.data = (void *)true,
 	},
+	{
+		.compatible = "amlogic,meson-s4-uart",
+		.data = (void *)true,
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
-- 
2.33.1



From wenst at chromium.org  Mon Jan 17 19:47:36 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 18 Jan 2022 11:47:36 +0800
Subject: [PATCH 0/7] pinctrl: mediatek: Fixes and minor improvements
In-Reply-To: <CACRpkdZCtEwZiVwoW+QNL4nTf-10fBDRfGkwVJavf1n_w-8q_Q@mail.gmail.com>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <CACRpkdZCtEwZiVwoW+QNL4nTf-10fBDRfGkwVJavf1n_w-8q_Q@mail.gmail.com>
Message-ID: <CAGXv+5GRqQFHsxZMaK0VT534rQvQTx5-h1U63mFSUQuAHRGmkA@mail.gmail.com>

Hi Linus,

On Sun, Jan 16, 2022 at 8:49 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> On Tue, Jan 11, 2022 at 12:22 PM Chen-Yu Tsai <wenst at chromium.org> wrote:
>
> > Here are some fixes and minor improvements to generic pinconf and the
> > Mediatek Paris pinctrl driver.
>
> Looks good to me, can you rebase this on v5.17-rc1 once it is out
> and I will queue it!

Thanks for the vote of confidence! I think patch 7 still needs some work.
I will likely split that into two parts:
a. pin config readback of the advanced drive strength mode into
   PIN_CONFIG_DRIVE_STRENGTH_UA, and
b. Supporting setting advanced drive strength mode via generic pin config
   properties.

The latter would require modification of the bindings in a way that might
not be describable. More about that is in my reply to patch 7.

In exchange, I will add on a code style rework requested by Angelo.


Regards
ChenYu


From reijiw at google.com  Mon Jan 17 20:19:22 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 17 Jan 2022 20:19:22 -0800
Subject: [PATCH v2 1/2] KVM: arm64: mixed-width check should be skipped for
 uninitialized vCPUs
Message-ID: <20220118041923.3384602-1-reijiw@google.com>

KVM allows userspace to configure either all 32bit or 64bit vCPUs
for a guest.  At vCPU reset, vcpu_allowed_register_width() checks
if the vcpu's register width is consistent with all other vCPUs'.
Since the checking is done even against vCPUs that are not initialized
(KVM_ARM_VCPU_INIT has not been done) yet, the uninitialized vCPUs
are erroneously treated as 64bit vCPU, which causes the function to
incorrectly detect a mixed-width VM.

Introduce a new flag (el1_reg_width) in kvm_arch to indicates that
the guest needs to be configured with all 32bit or 64bit vCPUs,
and initialize it at the first KVM_ARM_VCPU_INIT for the guest.
Check vcpu's register width against the flag at the vcpu's
KVM_ARM_VCPU_INIT (instead of against other vCPUs' register width).

Fixes: 66e94d5cafd4 ("KVM: arm64: Prevent mixed-width VM creation")
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 arch/arm64/include/asm/kvm_host.h | 13 +++++++++++++
 arch/arm64/kvm/arm.c              | 30 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/reset.c            |  8 --------
 3 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2a5f7f38006f..c02b7caf2c82 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -102,6 +102,12 @@ struct kvm_s2_mmu {
 struct kvm_arch_memory_slot {
 };
 
+enum kvm_el1_reg_width {
+	EL1_WIDTH_UNINITIALIZED = 0,
+	EL1_32BIT,
+	EL1_64BIT,
+};
+
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
@@ -137,6 +143,13 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+
+	/*
+	 * EL1 register width for the guest.
+	 * This is set at the first KVM_ARM_VCPU_INIT for the guest based
+	 * on whether the vcpu has KVM_ARM_VCPU_EL1_32BIT or not.
+	 */
+	enum kvm_el1_reg_width el1_reg_width;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index e4727dc771bf..54ae8bf9d187 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1058,6 +1058,32 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_level,
 	return -EINVAL;
 }
 
+/*
+ * A guest can have either all 32bit or 64bit vcpus only.
+ * Either one the guest has is indicated in kvm->arch.el1_reg_width.
+ * Check if the vcpu's register width is consistent with
+ * kvm->arch.el1_reg_width.  If kvm->arch.el1_reg_width is not set yet,
+ * set it based on the vcpu's KVM_ARM_VCPU_EL1_32BIT configuration.
+ */
+static int kvm_register_width_check_or_init(struct kvm_vcpu *vcpu)
+{
+	bool is32bit;
+	bool allowed = true;
+	struct kvm *kvm = vcpu->kvm;
+
+	is32bit = vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT);
+
+	mutex_lock(&kvm->lock);
+
+	if (kvm->arch.el1_reg_width == EL1_WIDTH_UNINITIALIZED)
+		kvm->arch.el1_reg_width = is32bit ? EL1_32BIT : EL1_64BIT;
+	else
+		allowed = (is32bit == (kvm->arch.el1_reg_width == EL1_32BIT));
+
+	mutex_unlock(&kvm->lock);
+	return allowed ? 0 : -EINVAL;
+}
+
 static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 			       const struct kvm_vcpu_init *init)
 {
@@ -1097,6 +1123,10 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 
 	/* Now we know what it is, we can reset it. */
 	ret = kvm_reset_vcpu(vcpu);
+
+	if (!ret)
+		ret = kvm_register_width_check_or_init(vcpu);
+
 	if (ret) {
 		vcpu->arch.target = -1;
 		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 426bd7fbc3fd..dbf2939a6a96 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -168,9 +168,7 @@ static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
 
 static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 {
-	struct kvm_vcpu *tmp;
 	bool is32bit;
-	int i;
 
 	is32bit = vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT);
 	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
@@ -180,12 +178,6 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 	if (kvm_has_mte(vcpu->kvm) && is32bit)
 		return false;
 
-	/* Check that the vcpus are either all 32bit or all 64bit */
-	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
-		if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit)
-			return false;
-	}
-
 	return true;
 }
 

base-commit: 37144b2c855f9311c72f292125061d4a52d02856
-- 
2.34.1.703.g22d0c6ccf7-goog



From reijiw at google.com  Mon Jan 17 20:19:23 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 17 Jan 2022 20:19:23 -0800
Subject: [PATCH v2 2/2] KVM: arm64: selftests: Introduce vcpu_width_config
In-Reply-To: <20220118041923.3384602-1-reijiw@google.com>
References: <20220118041923.3384602-1-reijiw@google.com>
Message-ID: <20220118041923.3384602-2-reijiw@google.com>

Introduce a test for aarch64 that ensures non-mixed-width vCPUs
(all 64bit vCPUs or all 32bit vcPUs) can be configured, and
mixed-width vCPUs cannot be configured.

Reviewed-by: Andrew Jones <drjones at redhat.com>
Signed-off-by: Reiji Watanabe <reijiw at google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/aarch64/vcpu_width_config.c | 125 ++++++++++++++++++
 3 files changed, 127 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/aarch64/vcpu_width_config.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 3cb5ac5da087..8795a83cc382 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -3,6 +3,7 @@
 /aarch64/debug-exceptions
 /aarch64/get-reg-list
 /aarch64/psci_cpu_on_test
+/aarch64/vcpu_width_config
 /aarch64/vgic_init
 /s390x/memop
 /s390x/resets
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 17342b575e85..259e01d0735a 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -95,6 +95,7 @@ TEST_GEN_PROGS_aarch64 += aarch64/arch_timer
 TEST_GEN_PROGS_aarch64 += aarch64/debug-exceptions
 TEST_GEN_PROGS_aarch64 += aarch64/get-reg-list
 TEST_GEN_PROGS_aarch64 += aarch64/psci_cpu_on_test
+TEST_GEN_PROGS_aarch64 += aarch64/vcpu_width_config
 TEST_GEN_PROGS_aarch64 += aarch64/vgic_init
 TEST_GEN_PROGS_aarch64 += demand_paging_test
 TEST_GEN_PROGS_aarch64 += dirty_log_test
diff --git a/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c b/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
new file mode 100644
index 000000000000..cd238e068236
--- /dev/null
+++ b/tools/testing/selftests/kvm/aarch64/vcpu_width_config.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * vcpu_width_config - Test KVM_ARM_VCPU_INIT() with KVM_ARM_VCPU_EL1_32BIT.
+ *
+ * Copyright (c) 2022 Google LLC.
+ *
+ * This is a test that ensures that non-mixed-width vCPUs (all 64bit vCPUs
+ * or all 32bit vcPUs) can be configured and mixed-width vCPUs cannot be
+ * configured.
+ */
+
+#define _GNU_SOURCE
+
+#include "kvm_util.h"
+#include "processor.h"
+#include "test_util.h"
+
+
+/*
+ * Add a vCPU, run KVM_ARM_VCPU_INIT with @init1, and then
+ * add another vCPU, and run KVM_ARM_VCPU_INIT with @init2.
+ */
+int add_init_2vcpus(struct kvm_vcpu_init *init1,
+			 struct kvm_vcpu_init *init2)
+{
+	struct kvm_vm *vm;
+	int ret;
+
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+
+	vm_vcpu_add(vm, 0);
+	ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
+	if (ret)
+		goto free_exit;
+
+	vm_vcpu_add(vm, 1);
+	ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
+
+free_exit:
+	kvm_vm_free(vm);
+	return ret;
+}
+
+/*
+ * Add two vCPUs, then run KVM_ARM_VCPU_INIT for one vCPU with @init1,
+ * and run KVM_ARM_VCPU_INIT for another vCPU with @init2.
+ */
+int add_2vcpus_init_2vcpus(struct kvm_vcpu_init *init1,
+				struct kvm_vcpu_init *init2)
+{
+	struct kvm_vm *vm;
+	int ret;
+
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+
+	vm_vcpu_add(vm, 0);
+	vm_vcpu_add(vm, 1);
+
+	ret = _vcpu_ioctl(vm, 0, KVM_ARM_VCPU_INIT, init1);
+	if (ret)
+		goto free_exit;
+
+	ret = _vcpu_ioctl(vm, 1, KVM_ARM_VCPU_INIT, init2);
+
+free_exit:
+	kvm_vm_free(vm);
+	return ret;
+}
+
+/*
+ * Tests that two 64bit vCPUs can be configured, two 32bit vCPUs can be
+ * configured, and two mixed-witgh vCPUs cannot be configured.
+ * Each of those three cases, configure vCPUs in two different orders.
+ * The one is running KVM_CREATE_VCPU for 2 vCPUs, and then running
+ * KVM_ARM_VCPU_INIT for them.
+ * The other is running KVM_CREATE_VCPU and KVM_ARM_VCPU_INIT for a vCPU,
+ * and then run those commands for another vCPU.
+ */
+int main(void)
+{
+	struct kvm_vcpu_init init1, init2;
+	struct kvm_vm *vm;
+	int ret;
+
+	if (kvm_check_cap(KVM_CAP_ARM_EL1_32BIT) <= 0) {
+		print_skip("KVM_CAP_ARM_EL1_32BIT is not supported");
+		exit(KSFT_SKIP);
+	}
+
+	/* Get the preferred target type and copy that to init2 */
+	vm = vm_create(VM_MODE_DEFAULT, DEFAULT_GUEST_PHY_PAGES, O_RDWR);
+	vm_ioctl(vm, KVM_ARM_PREFERRED_TARGET, &init1);
+	kvm_vm_free(vm);
+	memcpy(&init2, &init1, sizeof(init2));
+
+	/* Test with 64bit vCPUs */
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 64bit EL1 vCPUs failed unexpectedly");
+
+	/* Test with 32bit vCPUs */
+	init1.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	init2.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret == 0,
+		    "Configuring 32bit EL1 vCPUs failed unexpectedly");
+
+	/* Test with mixed-width vCPUs  */
+	init1.features[0] = 0;
+	init2.features[0] = (1 << KVM_ARM_VCPU_EL1_32BIT);
+	ret = add_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret != 0,
+		    "Configuring mixed-width vCPUs worked unexpectedly");
+	ret = add_2vcpus_init_2vcpus(&init1, &init2);
+	TEST_ASSERT(ret != 0,
+		    "Configuring mixed-width vCPUs worked unexpectedly");
+
+	return 0;
+}
-- 
2.34.1.703.g22d0c6ccf7-goog



From reijiw at google.com  Mon Jan 17 20:24:55 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 17 Jan 2022 20:24:55 -0800
Subject: [RFC PATCH v4 00/26] KVM: arm64: Make CPU ID registers writable
 by userspace
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <CAAeT=FyjqC47pHe_G_Z0sVua8A1SEbzQg6UZkQBwkTezA7tLsA@mail.gmail.com>

On Wed, Jan 5, 2022 at 8:27 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> In KVM/arm64, values of ID registers for a guest are mostly same as
> its host's values except for bits for feature that KVM doesn't support
> and for opt-in features that userspace didn't configure.  Userspace
> can use KVM_SET_ONE_REG to a set ID register value, but it fails
> if userspace attempts to modify the register value.
>
> This patch series adds support to allow userspace to modify a value of
> ID registers (as long as KVM can support features that are indicated
> in the registers) so userspace can have more control of configuring
> and unconfiguring features for guests.  We need this because we would
> like to expose a uniform set/level of features for a group of guests on
> systems with different ARM CPUs.  Since some features are not binary
> in nature (e.g. AA64DFR0_EL1.BRPs fields indicate number of
> breakpoints minus 1), using KVM_ARM_VCPU_INIT to control such features
> is inconvenient.
>
> The patch series is for both VHE and non-VHE, except for protected VMs,
> which have a different way of configuring ID registers based on its
> different requirements [1].
> There was a patch series that tried to achieve the same thing [2].
> A few snippets of codes in this series were inspired by or came from [2].
>
> The initial value of ID registers for a vCPU will be the host's value
> with bits cleared for unsupported features and for opt-in features that
> were not configured. So, the initial value userspace can see (via
> KVM_GET_ONE_REG) is the upper limit that can be set for the register.
> Any requests to change the value that conflicts with opt-in features'
> configuration will fail (e.g. if KVM_ARM_VCPU_PMU_V3 is configured by
> KVM_ARM_VCPU_INIT, ID_AA64DFR0_EL1.PMUVER cannot be set to zero.
> Otherwise, the initial value of ID_AA64DFR0_EL1.PMUVER will be zero,
> and cannot be changed from zero).
>
> When a guest tries to use a CPU feature that is not exposed to the guest,
> trapping it (to emulate a real CPU's behavior) would generally be a
> desirable behavior (when it is possible with no or little side effects).
> The later patches in the series add codes for this.  Only features that
> can be trapped independently will be trapped by this series though.
>
> This series adds kunit tests for new functions in sys_regs.c (except for
> trivial ones), and these tests are enabled with a new configuration
> option 'CONFIG_KVM_KUNIT_TEST'.

A gentle ping on this series.

Since KVM/ARM doesn't have any kunit tests yet, the series (patch-16)
introduces .kunitconfig for KVM/ARM in addition to the new configuration
option (The .kunitconfig in the patch includes only the minimum
configuration options needed for the current tests in the patch).

Any feedback on the patch-16 would be appreciated as with other patches.

Thanks,
Reiji








>
> The series is based on v5.16-rc8 with the patch [3] applied.
>
> v4:
>   - Make ID registers storage per VM instead of per vCPU. [Marc]
>   - Implement arm64_check_features() in arch/arm64/kernel/cpufeature.c
>     by using existing codes in the file. [Marc]
>   - Use a configuration function to enable traps for disabled
>     features. [Marc]
>   - Document ID registers become immutable after the first KVM_RUN [Eric]
>   - Update ID_AA64PFR0.GIC at the point where a GICv3 is created. [Marc]
>   - Get TGranX's bit position by substracting 12 from TGranX_2's bit
>     position. [Eric]
>   - Don't validate AArch32 ID registers when the system doesn't support
>     32bit EL0. [Eric]
>   - Add/fixes comments for patches. [Eric]
>   - Made bug fixes/improvements of the selftest. [Eric]
>   - Added .kunitconfig for arm64 KUnit tests
>
> v3: https://lore.kernel.org/all/20211117064359.2362060-1-reijiw at google.com/
>   - Remove ID register consistency checking across vCPUs. [Oliver]
>   - Change KVM_CAP_ARM_ID_REG_WRITABLE to
>     KVM_CAP_ARM_ID_REG_CONFIGURABLE. [Oliver]
>   - Add KUnit testing for ID register validation and trap initialization.
>   - Change read_id_reg() to take care of ID_AA64PFR0_EL1.GIC.
>   - Add a helper of read_id_reg() (__read_id_reg()) and use the helper
>     instead of directly using __vcpu_sys_reg().
>   - Change not to run kvm_id_regs_consistency_check() and
>     kvm_vcpu_init_traps() for protected VMs.
>   - Update selftest to remove test cases for ID register consistency.
>     checking across vCPUs and to add test cases for ID_AA64PFR0_EL1.GIC.
>
> v2: https://lore.kernel.org/all/20211103062520.1445832-1-reijiw at google.com/
>   - Remove unnecessary line breaks. [Andrew]
>   - Use @params for comments. [Andrew]
>   - Move arm64_check_features to arch/arm64/kvm/sys_regs.c and
>     change that KVM specific feature check function.  [Andrew]
>   - Remove unnecessary raz handling from __set_id_reg. [Andrew]
>   - Remove sys_val field from the initial id_reg_info and add it
>     in the later patch. [Andrew]
>   - Call id_reg->init() from id_reg_info_init(). [Andrew]
>   - Fix cpuid_feature_cap_perfmon_field() to convert 0xf to 0x0
>     (and use it in the following patches).
>   - Change kvm_vcpu_first_run_init to set has_run_once to false
>     when kvm_id_regs_consistency_check() fails.
>   - Add a patch to introduce id_reg_info for ID_AA64MMFR0_EL1,
>     which requires special validity checking for TGran*_2 fields.
>   - Add patches to introduce id_reg_info for ID_DFR1_EL1 and
>     ID_MMFR0_EL1, which are required due to arm64_check_features
>     implementation change.
>   - Add a new argument, which is a pointer to id_reg_info, for
>     id_reg_info's validate().
>
> v1: https://lore.kernel.org/all/20211012043535.500493-1-reijiw at google.com/
>
> [1] https://lore.kernel.org/kvmarm/20211010145636.1950948-1-tabba at google.com/
> [2] https://lore.kernel.org/kvm/20201102033422.657391-1-liangpeng10 at huawei.com/
> [3] https://lore.kernel.org/all/20220104194918.373612-2-rananta at google.com/
>
> Reiji Watanabe (26):
>   KVM: arm64: Introduce a validation function for an ID register
>   KVM: arm64: Save ID registers' sanitized value per guest
>   KVM: arm64: Introduce struct id_reg_info
>   KVM: arm64: Make ID_AA64PFR0_EL1 writable
>   KVM: arm64: Make ID_AA64PFR1_EL1 writable
>   KVM: arm64: Make ID_AA64ISAR0_EL1 writable
>   KVM: arm64: Make ID_AA64ISAR1_EL1 writable
>   KVM: arm64: Make ID_AA64MMFR0_EL1 writable
>   KVM: arm64: Hide IMPLEMENTATION DEFINED PMU support for the guest
>   KVM: arm64: Make ID_AA64DFR0_EL1 writable
>   KVM: arm64: Make ID_DFR0_EL1 writable
>   KVM: arm64: Make MVFR1_EL1 writable
>   KVM: arm64: Make ID registers without id_reg_info writable
>   KVM: arm64: Add consistency checking for frac fields of ID registers
>   KVM: arm64: Introduce KVM_CAP_ARM_ID_REG_CONFIGURABLE capability
>   KVM: arm64: Add kunit test for ID register validation
>   KVM: arm64: Use vcpu->arch cptr_el2 to track value of cptr_el2 for VHE
>   KVM: arm64: Use vcpu->arch.mdcr_el2 to track value of mdcr_el2
>   KVM: arm64: Introduce framework to trap disabled features
>   KVM: arm64: Trap disabled features of ID_AA64PFR0_EL1
>   KVM: arm64: Trap disabled features of ID_AA64PFR1_EL1
>   KVM: arm64: Trap disabled features of ID_AA64DFR0_EL1
>   KVM: arm64: Trap disabled features of ID_AA64MMFR1_EL1
>   KVM: arm64: Trap disabled features of ID_AA64ISAR1_EL1
>   KVM: arm64: Add kunit test for trap initialization
>   KVM: arm64: selftests: Introduce id_reg_test
>
>  Documentation/virt/kvm/api.rst                |   12 +
>  arch/arm64/include/asm/cpufeature.h           |    3 +-
>  arch/arm64/include/asm/kvm_arm.h              |   32 +
>  arch/arm64/include/asm/kvm_host.h             |   19 +
>  arch/arm64/include/asm/sysreg.h               |    3 +
>  arch/arm64/kernel/cpufeature.c                |  228 +++
>  arch/arm64/kvm/.kunitconfig                   |    4 +
>  arch/arm64/kvm/Kconfig                        |   11 +
>  arch/arm64/kvm/arm.c                          |   24 +-
>  arch/arm64/kvm/debug.c                        |   13 +-
>  arch/arm64/kvm/hyp/vhe/switch.c               |   14 +-
>  arch/arm64/kvm/sys_regs.c                     | 1329 +++++++++++++++--
>  arch/arm64/kvm/sys_regs_test.c                | 1247 ++++++++++++++++
>  arch/arm64/kvm/vgic/vgic-init.c               |    5 +
>  include/uapi/linux/kvm.h                      |    1 +
>  tools/arch/arm64/include/asm/sysreg.h         |    1 +
>  tools/testing/selftests/kvm/.gitignore        |    1 +
>  tools/testing/selftests/kvm/Makefile          |    1 +
>  .../selftests/kvm/aarch64/id_reg_test.c       | 1239 +++++++++++++++
>  19 files changed, 4041 insertions(+), 146 deletions(-)
>  create mode 100644 arch/arm64/kvm/.kunitconfig
>  create mode 100644 arch/arm64/kvm/sys_regs_test.c
>  create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c
>
>
> base-commit: d399b107ee49bf5ea0391bd7614d512809e927b0
> --
> 2.34.1.448.ga2b2bfdf31-goog
>


From allen-kh.cheng at mediatek.com  Mon Jan 17 20:38:03 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 12:38:03 +0800
Subject: [PATCH v5 0/1] firmware: mtk: add adsp ipc protocol for sof
Message-ID: <20220118043804.800-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch provides mtk adsp ipc support for sof.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

changes since v4:
- add error message for wrong mbox chan

changes since v3:
- rebase on v5.16-rc8
- update reviewers

changes since v2:
- add out tag for two memory free phases

changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove useless MODULE_LICENSE
- change label name to out_free

Allen-KH Cheng (1):
  firmware: mediatek: add adsp ipc protocol interface

 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 20:38:04 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 12:38:04 +0800
Subject: [PATCH v5 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220118043804.800-1-allen-kh.cheng@mediatek.com>
References: <20220118043804.800-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220118043804.800-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 160 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 238 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..683742435d26
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *adsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	adsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(adsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * mbox_send_message returns non-negative value on success,
+	 * return zero for success
+	 */
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "wrong mbox chan %d\n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *adsp_ipc;
+	struct mtk_adsp_chan *adsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+	if (!adsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		adsp_chan = &adsp_ipc->chans[i];
+		cl = &adsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		adsp_chan->ipc = adsp_ipc;
+		adsp_chan->idx = i;
+		adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(adsp_chan->ch)) {
+			ret = PTR_ERR(adsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out_free;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	adsp_ipc->dev = dev;
+	dev_set_drvdata(dev, adsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out_free:
+	kfree(chan_name);
+out:
+	for (j = 0; j < i; j++) {
+		adsp_chan = &adsp_ipc->chans[j];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *adsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		adsp_chan = &adsp_ipc->chans[i];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 20:44:18 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 12:44:18 +0800
Subject: [PATCH v16 1/2] dt-bindings: mediatek: add adsp-mbox document
In-Reply-To: <20220118044419.944-1-allen-kh.cheng@mediatek.com>
References: <20220118044419.944-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220118044419.944-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 20:44:19 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 12:44:19 +0800
Subject: [PATCH v16 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220118044419.944-1-allen-kh.cheng@mediatek.com>
References: <20220118044419.944-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220118044419.944-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   9 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 175 +++++++++++++++++++++++++++++
 3 files changed, 186 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..05d6fae800e3 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,15 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+          Say yes here to add support for "MediaTek ADSP Mailbox Controller.
+          This mailbox driver is used to send notification or short message
+          between processors with ADSP. It will place the message to share
+	  buffer and will access the ipc control.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..60bf10c38348
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static inline struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Mon Jan 17 20:44:17 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Tue, 18 Jan 2022 12:44:17 +0800
Subject: [PATCH v16 0/2] mtk: add ADSP mailbox controller for MT8195
Message-ID: <20220118044419.944-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message 
between processors with dsp. It will place the message to the
share buffer and will access the ADSP mailbox registers to kick
dsp. Two mailboxes used to send notification or short message 
between processors with dsp

changes since v14:
- add paragraphs to describe the config symbols fully

changes since v14:
- add inline for get_mtk_adsp_mbox_priv

changes since v13:
- rebase on v5.16-rc8
- add back ptr check from of_device_get_match_data

changes since v12:
- remove of_device_get_match_data ptr check:
  of_device_get_match_data(dev) will never going to return NULL.
  driver probe with compatible mediatek,mt8195-adsp-mbox.

changes since v11:
- remove useless MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error


Allen-KH Cheng (2):
  dt-bindings: mediatek: add adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   9 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 175 ++++++++++++++++++
 4 files changed, 238 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From yuji2.ishikawa at toshiba.co.jp  Mon Jan 17 21:39:48 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Tue, 18 Jan 2022 14:39:48 +0900
Subject: [PATCH 0/2] net: stmmac: dwmac-visconti: Fix bit definitions and
 clock configuration for RMII mode
Message-ID: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>

Hi,

This series is a fix for RMII/MII operation mode of the dwmac-visconti driver.
It is composed of two parts:

* 1/2: fix constant definitions for cleared bits in ETHER_CLK_SEL register
* 2/2: fix configuration of ETHER_CLK_SEL register for running in RMII operation mode.

Best regards,
  Yuji

Yuji Ishikawa (2):
  net: stmmac: dwmac-visconti: Fix bit definitions for ETHER_CLK_SEL
  net: stmmac: dwmac-visconti: Fix clock configuration for RMII mode

 .../ethernet/stmicro/stmmac/dwmac-visconti.c  | 42 ++++++++++++-------
 1 file changed, 26 insertions(+), 16 deletions(-)

-- 
2.17.1




From yuji2.ishikawa at toshiba.co.jp  Mon Jan 17 21:39:50 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Tue, 18 Jan 2022 14:39:50 +0900
Subject: [PATCH 2/2] net: stmmac: dwmac-visconti: Fix clock configuration for
 RMII mode
In-Reply-To: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220118053950.2605-3-yuji2.ishikawa@toshiba.co.jp>

Bit pattern of the ETHER_CLOCK_SEL register for RMII/MII mode should be fixed.
Also, some control bits should be modified with a specific sequence.

Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 .../ethernet/stmicro/stmmac/dwmac-visconti.c  | 32 ++++++++++++-------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index 43a446cea..dde5b772a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -96,31 +96,41 @@ static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
 	val |= ETHER_CLK_SEL_TX_O_E_N_IN;
 	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 
+	/* Set Clock-Mux, Start clock, Set TX_O direction */
 	switch (dwmac->phy_intf_sel) {
 	case ETHER_CONFIG_INTF_RGMII:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val &= ~ETHER_CLK_SEL_TX_O_E_N_IN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	case ETHER_CONFIG_INTF_RMII:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV |
-			ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN |
+			ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN |
 			ETHER_CLK_SEL_RMII_CLK_SEL_RX_C;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RMII_CLK_RST;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	case ETHER_CONFIG_INTF_MII:
 	default:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC |
-			ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN |
-			ETHER_CLK_SEL_RMII_CLK_EN;
+			ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	}
 
-	/* Start clock */
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-	val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-
-	val &= ~ETHER_CLK_SEL_TX_O_E_N_IN;
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-
 	spin_unlock_irqrestore(&dwmac->lock, flags);
 }
 
-- 
2.17.1




From yuji2.ishikawa at toshiba.co.jp  Mon Jan 17 21:39:49 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Tue, 18 Jan 2022 14:39:49 +0900
Subject: [PATCH 1/2] net: stmmac: dwmac-visconti: Fix bit definitions for
 ETHER_CLK_SEL
In-Reply-To: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220118053950.2605-2-yuji2.ishikawa@toshiba.co.jp>

just 0 should be used to represent cleared bits

* ETHER_CLK_SEL_DIV_SEL_20
* ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN
* ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN
* ETHER_CLK_SEL_TX_CLK_O_TX_I
* ETHER_CLK_SEL_RMII_CLK_SEL_IN

Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index e2e0f9778..43a446cea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -22,21 +22,21 @@
 #define ETHER_CLK_SEL_RMII_CLK_EN BIT(2)
 #define ETHER_CLK_SEL_RMII_CLK_RST BIT(3)
 #define ETHER_CLK_SEL_DIV_SEL_2 BIT(4)
-#define ETHER_CLK_SEL_DIV_SEL_20 BIT(0)
+#define ETHER_CLK_SEL_DIV_SEL_20 0
 #define ETHER_CLK_SEL_FREQ_SEL_125M	(BIT(9) | BIT(8))
 #define ETHER_CLK_SEL_FREQ_SEL_50M	BIT(9)
 #define ETHER_CLK_SEL_FREQ_SEL_25M	BIT(8)
 #define ETHER_CLK_SEL_FREQ_SEL_2P5M	0
-#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN BIT(0)
+#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN 0
 #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC BIT(10)
 #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV BIT(11)
-#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN  BIT(0)
+#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN  0
 #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC BIT(12)
 #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV BIT(13)
-#define ETHER_CLK_SEL_TX_CLK_O_TX_I	 BIT(0)
+#define ETHER_CLK_SEL_TX_CLK_O_TX_I	 0
 #define ETHER_CLK_SEL_TX_CLK_O_RMII_I	 BIT(14)
 #define ETHER_CLK_SEL_TX_O_E_N_IN	 BIT(15)
-#define ETHER_CLK_SEL_RMII_CLK_SEL_IN	 BIT(0)
+#define ETHER_CLK_SEL_RMII_CLK_SEL_IN	 0
 #define ETHER_CLK_SEL_RMII_CLK_SEL_RX_C	 BIT(16)
 
 #define ETHER_CLK_SEL_RX_TX_CLK_EN (ETHER_CLK_SEL_RX_CLK_EN | ETHER_CLK_SEL_TX_CLK_EN)
-- 
2.17.1




From u.kleine-koenig at pengutronix.de  Mon Jan 17 23:02:20 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 18 Jan 2022 08:02:20 +0100
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic
 function groups
In-Reply-To: <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com>
 <Yd2jcfXqqKHK/NaG@archlinux-ax161>
 <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
Message-ID: <20220118070220.5bfgubz4mx2l33jd@pengutronix.de>

On Tue, Jan 11, 2022 at 05:51:44PM +0100, Rafa? Mi?ecki wrote:
> On 11.01.2022 16:34, Nathan Chancellor wrote:
> > On Thu, Dec 16, 2021 at 05:22:06PM +0100, Rafa? Mi?ecki wrote:
> > > From: Rafa? Mi?ecki <rafal at milecki.pl>
> > > 
> > > Generic code doesn't modify those strings and .get_function_groups
> > > callback has that extra "const" as well. This allows more flexibility in
> > > GENERIC_PINMUX_FUNCTIONS users.
> > > 
> > > Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> > > ---
> > >   drivers/pinctrl/pinmux.c | 2 +-
> > >   drivers/pinctrl/pinmux.h | 4 ++--
> > >   2 files changed, 3 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> > > index 6cdbd9ccf2f0..f94d43b082d9 100644
> > > --- a/drivers/pinctrl/pinmux.c
> > > +++ b/drivers/pinctrl/pinmux.c
> > > @@ -875,7 +875,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
> > >    */
> > >   int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
> > >   				const char *name,
> > > -				const char **groups,
> > > +				const char * const *groups,
> > >   				const unsigned int num_groups,
> > >   				void *data)
> > >   {
> > > diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
> > > index 78c3a31be882..72fcf03eaa43 100644
> > > --- a/drivers/pinctrl/pinmux.h
> > > +++ b/drivers/pinctrl/pinmux.h
> > > @@ -129,7 +129,7 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot,
> > >    */
> > >   struct function_desc {
> > >   	const char *name;
> > > -	const char **group_names;
> > > +	const char * const *group_names;
> > >   	int num_group_names;
> > >   	void *data;
> > >   };
> > > @@ -150,7 +150,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
> > >   int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
> > >   				const char *name,
> > > -				const char **groups,
> > > +				const char * const *groups,
> > >   				unsigned const num_groups,
> > >   				void *data);
> > > -- 
> > > 2.31.1
> > > 
> > > 
> > 
> > I have not seen this reported yet, even though it has been broken for a
> > couple of weeks now. I see the following error in -next:
> > 
> > $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig drivers/pinctrl/pinctrl-thunderbay.o
> > drivers/pinctrl/pinctrl-thunderbay.c: In function ?thunderbay_add_functions?:
> > drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]
> >    815 |                         grp = func->group_names;
> >        |                             ^
> > cc1: all warnings being treated as errors
> > 
> > Looks like something like the third patch of the series is needed for
> > the Thunderbay driver, which it appears was in development at the same
> > time as this series.
> 
> Correct, this driver didn't exist in Linus's tree when I developed my changes.

I stumbled above this issue, too. For the record, this patch fixes the
build issue:

diff --git a/drivers/pinctrl/pinctrl-thunderbay.c b/drivers/pinctrl/pinctrl-thunderbay.c
index b5b47f4dd774..a6a9a0cca6bf 100644
--- a/drivers/pinctrl/pinctrl-thunderbay.c
+++ b/drivers/pinctrl/pinctrl-thunderbay.c
@@ -812,7 +812,7 @@ static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct funct
 				}
 			}
 
-			grp = func->group_names;
+			grp = (void *)func->group_names;
 			while (*grp)
 				grp++;
 
(however it's probably not safe for runtime).

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220118/a15b1c42/attachment-0001.sig>

From wenst at chromium.org  Mon Jan 17 23:19:40 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Tue, 18 Jan 2022 15:19:40 +0800
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <YeF/AYZ0DuKGwLLk@maud>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com> <YeF/AYZ0DuKGwLLk@maud>
Message-ID: <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>

Hi,

On Fri, Jan 14, 2022 at 9:47 PM Alyssa Rosenzweig <alyssa at collabora.com> wrote:
>
> > > That links to an internal Google issue tracker which I assume has more
> > > information on the bug. I would appreciate if someone from Google or
> > > MediaTek could explain what this change actually does and why it's
> > > necessary on MT8192.
> > >
> > > At any rate, this register logically belongs to the MT8192 "infra" clock
> > > device, so it makes sense to set it there too. This avoids adding any
> > > platform-specific hacks to the 3D driver, either mainline (Panfrost) or
> > > legacy (kbase).
> >
> > Does this really have anything to do with clocks?
>
> I have no idea. MediaTek, Google, please explain.
>
> > In particular, "ACP" usually refers to the Accelerator Coherency Port
> > of a CPU cluster or DSU, and given the stated symptom of the issue
> > affected by it, my first guess would be that this bit might indeed
> > control routing of GPU traffic either to the ACP or the (presumably
> > non-coherent) main interconnect.
>
> I'd easily believe that.

As Robin guessed, "ACP" here does refer to the Accelerator Coherency Port.
And the bit in infracfg toggles whether ACP is used or not.

Explanation from MediaTek in verbatim:

-------------------------------------------------------------------------
The ACP path on MT8192 is just for experimental only.
We are not intended to enable ACP by design.

But due to an unexpected operation, it was accidently opened by default.
So we need a patch to disable the ACP for MT8192.
-------------------------------------------------------------------------


Regards
ChenYu

> > If that is the case, I think this would logically belong as a SoC-specific
> > quirk in panfrost, where we'd need to retrieve the syscon regmap for
> > ourselves (see around line 800 of drivers/iommu/mtk_iommu.c for a similar
> > example).
>
> Alright. Doing this in panfrost seems ugly but if that's the right place
> for it, that's the right place for it.


From zajec5 at gmail.com  Mon Jan 17 23:21:55 2022
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 18 Jan 2022 08:21:55 +0100
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic function
 groups
In-Reply-To: <20220118070220.5bfgubz4mx2l33jd@pengutronix.de>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com> <Yd2jcfXqqKHK/NaG@archlinux-ax161>
 <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
 <20220118070220.5bfgubz4mx2l33jd@pengutronix.de>
Message-ID: <7cbe1015-a942-4887-7762-7c1dce243958@gmail.com>

On 18.01.2022 08:02, Uwe Kleine-K?nig wrote:
> On Tue, Jan 11, 2022 at 05:51:44PM +0100, Rafa? Mi?ecki wrote:
>> On 11.01.2022 16:34, Nathan Chancellor wrote:
>>> On Thu, Dec 16, 2021 at 05:22:06PM +0100, Rafa? Mi?ecki wrote:
>>>> From: Rafa? Mi?ecki <rafal at milecki.pl>
>>>>
>>>> Generic code doesn't modify those strings and .get_function_groups
>>>> callback has that extra "const" as well. This allows more flexibility in
>>>> GENERIC_PINMUX_FUNCTIONS users.
>>>>
>>>> Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
>>>> ---
>>>>    drivers/pinctrl/pinmux.c | 2 +-
>>>>    drivers/pinctrl/pinmux.h | 4 ++--
>>>>    2 files changed, 3 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
>>>> index 6cdbd9ccf2f0..f94d43b082d9 100644
>>>> --- a/drivers/pinctrl/pinmux.c
>>>> +++ b/drivers/pinctrl/pinmux.c
>>>> @@ -875,7 +875,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
>>>>     */
>>>>    int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>>>>    				const char *name,
>>>> -				const char **groups,
>>>> +				const char * const *groups,
>>>>    				const unsigned int num_groups,
>>>>    				void *data)
>>>>    {
>>>> diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
>>>> index 78c3a31be882..72fcf03eaa43 100644
>>>> --- a/drivers/pinctrl/pinmux.h
>>>> +++ b/drivers/pinctrl/pinmux.h
>>>> @@ -129,7 +129,7 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot,
>>>>     */
>>>>    struct function_desc {
>>>>    	const char *name;
>>>> -	const char **group_names;
>>>> +	const char * const *group_names;
>>>>    	int num_group_names;
>>>>    	void *data;
>>>>    };
>>>> @@ -150,7 +150,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
>>>>    int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
>>>>    				const char *name,
>>>> -				const char **groups,
>>>> +				const char * const *groups,
>>>>    				unsigned const num_groups,
>>>>    				void *data);
>>>> -- 
>>>> 2.31.1
>>>>
>>>>
>>>
>>> I have not seen this reported yet, even though it has been broken for a
>>> couple of weeks now. I see the following error in -next:
>>>
>>> $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig drivers/pinctrl/pinctrl-thunderbay.o
>>> drivers/pinctrl/pinctrl-thunderbay.c: In function ?thunderbay_add_functions?:
>>> drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]
>>>     815 |                         grp = func->group_names;
>>>         |                             ^
>>> cc1: all warnings being treated as errors
>>>
>>> Looks like something like the third patch of the series is needed for
>>> the Thunderbay driver, which it appears was in development at the same
>>> time as this series.
>>
>> Correct, this driver didn't exist in Linus's tree when I developed my changes.
> 
> I stumbled above this issue, too. For the record, this patch fixes the
> build issue:

[PATCH 5.17 1/2] pinctrl: thunderbay: comment process of building functions a bit
[PATCH 5.17 2/2] pinctrl: thunderbay: rework loops looking for groups names
https://patchwork.ozlabs.org/project/linux-gpio/list/?series=280568

Patches already queued in the:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=fixes


From alim.akhtar at samsung.com  Mon Jan 17 23:26:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 12:56:30 +0530
Subject: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <YeWgNJaDHxKROpQs@grimlerstat>
References: <20220116165035.437274-1-henrik@grimler.se>
 <20220116165035.437274-4-henrik@grimler.se>
 <ca8c4613-a058-6cde-f9e6-8530f142a821@canonical.com>
 <CGME20220116205940epcas5p3dbab01fb6bb7a4af76169231e6d94469@epcas5p3.samsung.com>
 <YeSHNCywXhp8gHC7@L14.lan> <001301d80b66$190901a0$4b1b04e0$@samsung.com>
 <YeWgNJaDHxKROpQs@grimlerstat>
Message-ID: <01c501d80c3c$b820fb90$2862f2b0$@samsung.com>

Hi Henrik

>-----Original Message-----
>From: Henrik Grimler [mailto:henrik at grimler.se]
>Sent: Monday, January 17, 2022 10:28 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>
>Cc: 'Krzysztof Kozlowski' <krzysztof.kozlowski at canonical.com>;
>semen.protsenko at linaro.org; virag.david003 at gmail.com;
>martin.juecker at gmail.com; cw00.choi at samsung.com;
>m.szyprowski at samsung.com; robh+dt at kernel.org;
>devicetree at vger.kernel.org; linux-samsung-soc at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>~postmarketos/upstreaming at lists.sr.ht
>Subject: Re: [PATCH v3 3/3] ARM: dts: Add support for Samsung Chagall WiFi
>
>Hi Alim,
>
>> >> > +/* External sdcard */
>> >> > +&mmc_2 {
>> >> > +	status = "okay";
>> >> > +	bus-width = <4>;
>> >> > +	cap-sd-highspeed;
>> >> > +	card-detect-delay = <200>;
>> >> > +	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1
>&sd2_bus4>;
>> >> > +	pinctrl-names = "default";
>> >> > +	samsung,dw-mshc-ciu-div = <3>;
>> >> > +	samsung,dw-mshc-ddr-timing = <0 2>;
>> >> > +	samsung,dw-mshc-sdr-timing = <0 4>;
>> >> > +	sd-uhs-sdr50;
>> >> > +	vmmc-supply = <&ldo19_reg>;
>> >> > +	vqmmc-supply = <&ldo13_reg>;
>> >> > +};
>> >> > +
>> >> > +&pinctrl_0 {
>> >> > +	mmc2_cd: sd2-cd-pins {
>> >> > +		samsung,pins = "gpx2-4";
>> >>
>> >> Interesting... I looked at vendor sources to board-chagall and
>> >> standard pin gpc2-2 is mentioned as PULL down and not-connected
>> >comment.
>> >>
>> >> gpx2-4 seems not mentioned at all, unless other board files are
>> >> actually used.
>> >
>> >Gpio seems to be spread out. GPIO_T_FLASH_DETECT is defined as gpx2-4
>> >in board-universal5420-mmc.c, and then used for card detection.
>> >(Looking at it now again I see that write protection through sd2_wp
>> >should also be supported for mmc_2, can add that in next patch set.)
>> >
>> Card detect pin is generally a special function (dedicated pin) pin,
>> directly connected from SoC to card external slot.
>> And for exynos5420 it is gpc2-2 as pointed by Krzysztof.
>
>gpio/pinctrl is still not my area of expertise so your feedback is greatly
>appreciated!
>
>gpc2-2 does not seem to be the card-detect pin for these tablets.  If I add
>sd2_cd to pinctrl-0 above I am unable to use the sdcard at all, instead
dmesg is
>filled with repeating messages like:
>
>[  18.669050] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req
>300000Hz, actual 297619HZ div = 84) [  18.703711] mmc_host mmc1: Bus speed
>(slot 0) = 50000000Hz (slot req 200000Hz, actual 200000HZ div = 125) [
>18.737167] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req
>100000Hz, actual 100000HZ div = 250) [  19.058352] mmc_host mmc1: Bus
>speed (slot 0) = 50000000Hz (slot req 400000Hz, actual 396825HZ div = 63) [
>19.093037] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req
>300000Hz, actual 297619HZ div = 84) [  19.127701] mmc_host mmc1: Bus speed
>(slot 0) = 50000000Hz (slot req 200000Hz, actual 200000HZ div = 125) [
>19.162380] mmc_host mmc1: Bus speed (slot 0) = 50000000Hz (slot req
>100000Hz, actual 100000HZ div = 250)
>
>gpx2-4 on the other hand switches state when an sdcard is inserted or
>removed.  After exporting relevant pins I have, with the card
>inserted:
>
># grep -A 2 gpx2 /sys/kernel/debug/gpio
>gpiochip3: GPIOs 24-31, parent: platform/13400000.pinctrl, gpx2:
> gpio-26  (                    |Power               ) in  hi IRQ ACTIVE LOW
> gpio-28  (                    |sysfs               ) in  lo
>
>and when removed gpx2-4 changes to high:
>
>gpiochip3: GPIOs 24-31, parent: platform/13400000.pinctrl, gpx2:
> gpio-26  (                    |Power               ) in  hi IRQ ACTIVE LOW
> gpio-28  (                    |sysfs               ) in  hi
>
>All the gpc2 pins are low no matter if sdcard is inserted or removed:
>
>gpiochip7: GPIOs 56-62, parent: platform/13410000.pinctrl, gpc2:
> gpio-56  (                    |sysfs               ) in  lo
> gpio-57  (                    |sysfs               ) in  lo
> gpio-58  (                    |sysfs               ) in  lo
> gpio-59  (                    |sysfs               ) in  lo
> gpio-60  (                    |sysfs               ) in  lo
> gpio-61  (                    |sysfs               ) in  lo
> gpio-62  (                    |sysfs               ) in  lo
>
>That being said, I am not sure if it is working properly:
>
>> Also PIN_FUNC_2 for gpx2-4 indicate that it is wakeup_int2 function.
>> Do you get a card detect interrupt when removing and inserting the
>> card to the card slot?
> 
This is the confirmation that this board does not uses gpc2-2 but gpx2-4. 
Thanks for detailed log.

>(What is the best way to check this?) I don't get any irq related messages
in

Probably if you are interested, you can enable few debug in dw-mmc driver to
check a message like "card is present" etc.

>dmesg, and I don't see any changes in /proc/interrupts if tracked with
>something like `watch -n1 "cat /proc/interrupts"` when card is removed or
>inserted, so seems likely that pin config is wrong.
>All I can find in vendor kernel for this device is that pull config is set
to
>S3C_GPIO_PULL_NONE [1].  For some of the sibling tablets the pin is
>configured as {S3C_GPIO_INPUT, GPIO_LV_N, S3C_GPIO_PULL_NONE} [2]
>though, which I think should correspond to having:
>
>mmc2_cd: mmc2-cd-pins {
>  samsung,pins = "gpx2-4";
>  samsung,pin-function = <EXYNOS_PIN_FUNC_INPUT>;
>  samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>  samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV3>; };
>
>Changing to that does not seem to change anything though, I don't get any
>interrupt, or any messages in dmesg, when inserting or removing the sdcard.
>
>> Also to avoid confusion, probably you can change the node name as
>"mmc2_cd:
>> mmc2-cd-pins"
>> (as sd2-cd-pins is gpc2-2 for this SoC)
>
>Thanks, will fix in a v4 (after discussions here are settled).
>
I am convinced that gpc2-2 is not used for card detect for this board.
So no other query on this patch.
Thanks

>[1] https://protect2.fireeye.com/v1/url?k=bba823ae-dad5cbe9-bba9a8e1-
>74fe485fff30-b4ccbbe9776f501d&q=1&e=9951c78c-16c8-449e-913b-
>d4d1f1f9bb6b&u=https%3A%2F%2Fgithub.com%2Fexynos5420%2Fandroid_k
>ernel_samsung_exynos5420%2Fblob%2Flineage-
>17.1%2Farch%2Farm%2Fmach-exynos%2Fboard-universal5420-
>mmc.c%23L388
>[2] https://protect2.fireeye.com/v1/url?k=97465c6e-f63bb429-9747d721-
>74fe485fff30-4111389a6d2b68b4&q=1&e=9951c78c-16c8-449e-913b-
>d4d1f1f9bb6b&u=https%3A%2F%2Fgithub.com%2Fexynos5420%2Fandroid_k
>ernel_samsung_exynos5420%2Fblob%2Flineage-
>17.1%2Farch%2Farm%2Fmach-exynos%2Fboard-n1-gpio.c%23L119
>
>Best regards,
>Henrik Grimler



From u.kleine-koenig at pengutronix.de  Mon Jan 17 23:31:36 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 18 Jan 2022 08:31:36 +0100
Subject: [PATCH V2 4/4] pinctrl: add one more "const" for generic
 function groups
In-Reply-To: <7cbe1015-a942-4887-7762-7c1dce243958@gmail.com>
References: <20211216162206.8027-1-zajec5@gmail.com>
 <20211216162206.8027-4-zajec5@gmail.com>
 <Yd2jcfXqqKHK/NaG@archlinux-ax161>
 <24a1e92e-51ab-ded5-1a43-682950af1fe9@gmail.com>
 <20220118070220.5bfgubz4mx2l33jd@pengutronix.de>
 <7cbe1015-a942-4887-7762-7c1dce243958@gmail.com>
Message-ID: <20220118073136.wbb4ktivhqaqry4m@pengutronix.de>

On Tue, Jan 18, 2022 at 08:21:55AM +0100, Rafa? Mi?ecki wrote:
> On 18.01.2022 08:02, Uwe Kleine-K?nig wrote:
> > On Tue, Jan 11, 2022 at 05:51:44PM +0100, Rafa? Mi?ecki wrote:
> > > On 11.01.2022 16:34, Nathan Chancellor wrote:
> > > > On Thu, Dec 16, 2021 at 05:22:06PM +0100, Rafa? Mi?ecki wrote:
> > > > > From: Rafa? Mi?ecki <rafal at milecki.pl>
> > > > > 
> > > > > Generic code doesn't modify those strings and .get_function_groups
> > > > > callback has that extra "const" as well. This allows more flexibility in
> > > > > GENERIC_PINMUX_FUNCTIONS users.
> > > > > 
> > > > > Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
> > > > > ---
> > > > >    drivers/pinctrl/pinmux.c | 2 +-
> > > > >    drivers/pinctrl/pinmux.h | 4 ++--
> > > > >    2 files changed, 3 insertions(+), 3 deletions(-)
> > > > > 
> > > > > diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
> > > > > index 6cdbd9ccf2f0..f94d43b082d9 100644
> > > > > --- a/drivers/pinctrl/pinmux.c
> > > > > +++ b/drivers/pinctrl/pinmux.c
> > > > > @@ -875,7 +875,7 @@ EXPORT_SYMBOL_GPL(pinmux_generic_get_function);
> > > > >     */
> > > > >    int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
> > > > >    				const char *name,
> > > > > -				const char **groups,
> > > > > +				const char * const *groups,
> > > > >    				const unsigned int num_groups,
> > > > >    				void *data)
> > > > >    {
> > > > > diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
> > > > > index 78c3a31be882..72fcf03eaa43 100644
> > > > > --- a/drivers/pinctrl/pinmux.h
> > > > > +++ b/drivers/pinctrl/pinmux.h
> > > > > @@ -129,7 +129,7 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot,
> > > > >     */
> > > > >    struct function_desc {
> > > > >    	const char *name;
> > > > > -	const char **group_names;
> > > > > +	const char * const *group_names;
> > > > >    	int num_group_names;
> > > > >    	void *data;
> > > > >    };
> > > > > @@ -150,7 +150,7 @@ struct function_desc *pinmux_generic_get_function(struct pinctrl_dev *pctldev,
> > > > >    int pinmux_generic_add_function(struct pinctrl_dev *pctldev,
> > > > >    				const char *name,
> > > > > -				const char **groups,
> > > > > +				const char * const *groups,
> > > > >    				unsigned const num_groups,
> > > > >    				void *data);
> > > > > -- 
> > > > > 2.31.1
> > > > > 
> > > > > 
> > > > 
> > > > I have not seen this reported yet, even though it has been broken for a
> > > > couple of weeks now. I see the following error in -next:
> > > > 
> > > > $ make -skj"$(nproc)" ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- allmodconfig drivers/pinctrl/pinctrl-thunderbay.o
> > > > drivers/pinctrl/pinctrl-thunderbay.c: In function ?thunderbay_add_functions?:
> > > > drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]
> > > >     815 |                         grp = func->group_names;
> > > >         |                             ^
> > > > cc1: all warnings being treated as errors
> > > > 
> > > > Looks like something like the third patch of the series is needed for
> > > > the Thunderbay driver, which it appears was in development at the same
> > > > time as this series.
> > > 
> > > Correct, this driver didn't exist in Linus's tree when I developed my changes.
> > 
> > I stumbled above this issue, too. For the record, this patch fixes the
> > build issue:
> 
> [PATCH 5.17 1/2] pinctrl: thunderbay: comment process of building functions a bit
> [PATCH 5.17 2/2] pinctrl: thunderbay: rework loops looking for groups names
> https://patchwork.ozlabs.org/project/linux-gpio/list/?series=280568
> 
> Patches already queued in the:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git/log/?h=fixes

Ah great. I hope this makes it into Linus Torvald's tree before -rc1 is
tagged. Having allmodconfig build broken in release candidates is really
annoying.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220118/84de69d8/attachment.sig>

From ardb at kernel.org  Mon Jan 17 23:46:00 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 08:46:00 +0100
Subject: [PATCH v2 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220113165807.2735949-5-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
 <20220113165807.2735949-5-kevin@bracey.fi>
Message-ID: <CAMj1kXEkUE0zpQSj7oDX-GnBJ5q+v_h+a7rco-1wW2mKCvw+xw@mail.gmail.com>

On Thu, 13 Jan 2022 at 17:58, Kevin Bracey <kevin at bracey.fi> wrote:
>
> It makes no sense to leave crc32_be using the generic code while we
> only accelerate the little-endian ops.
>
> Even though the big-endian form doesn't fit as smoothly into the arm64,
> we can speed it up and avoid hitting the D cache.
>
> Tested on Cortex-A53. Without acceleration:
>
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 192240 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21360 nsec
>
> With acceleration:
>
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 53480 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21480 nsec
>
> Signed-off-by: Kevin Bracey <kevin at bracey.fi>
> Tested-by: Ard Biesheuvel <ardb at kernel.org>
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>

Catalin, Will,

We'll need an ack from you so we can take this whole set via Herbert's tree.

Thanks,
Ard.


> ---
>  arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
>  1 file changed, 73 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
> index 0f9e10ecda23..8340dccff46f 100644
> --- a/arch/arm64/lib/crc32.S
> +++ b/arch/arm64/lib/crc32.S
> @@ -11,7 +11,44 @@
>
>         .arch           armv8-a+crc
>
> -       .macro          __crc32, c
> +       .macro          byteorder, reg, be
> +       .if             \be
> +CPU_LE( rev            \reg, \reg      )
> +       .else
> +CPU_BE( rev            \reg, \reg      )
> +       .endif
> +       .endm
> +
> +       .macro          byteorder16, reg, be
> +       .if             \be
> +CPU_LE( rev16          \reg, \reg      )
> +       .else
> +CPU_BE( rev16          \reg, \reg      )
> +       .endif
> +       .endm
> +
> +       .macro          bitorder, reg, be
> +       .if             \be
> +       rbit            \reg, \reg
> +       .endif
> +       .endm
> +
> +       .macro          bitorder16, reg, be
> +       .if             \be
> +       rbit            \reg, \reg
> +       lsr             \reg, \reg, #16
> +       .endif
> +       .endm
> +
> +       .macro          bitorder8, reg, be
> +       .if             \be
> +       rbit            \reg, \reg
> +       lsr             \reg, \reg, #24
> +       .endif
> +       .endm
> +
> +       .macro          __crc32, c, be=0
> +       bitorder        w0, \be
>         cmp             x2, #16
>         b.lt            8f                      // less than 16 bytes
>
> @@ -24,10 +61,14 @@
>         add             x8, x8, x1
>         add             x1, x1, x7
>         ldp             x5, x6, [x8]
> -CPU_BE(        rev             x3, x3          )
> -CPU_BE(        rev             x4, x4          )
> -CPU_BE(        rev             x5, x5          )
> -CPU_BE(        rev             x6, x6          )
> +       byteorder       x3, \be
> +       byteorder       x4, \be
> +       byteorder       x5, \be
> +       byteorder       x6, \be
> +       bitorder        x3, \be
> +       bitorder        x4, \be
> +       bitorder        x5, \be
> +       bitorder        x6, \be
>
>         tst             x7, #8
>         crc32\c\()x     w8, w0, x3
> @@ -55,33 +96,43 @@ CPU_BE(     rev             x6, x6          )
>  32:    ldp             x3, x4, [x1], #32
>         sub             x2, x2, #32
>         ldp             x5, x6, [x1, #-16]
> -CPU_BE(        rev             x3, x3          )
> -CPU_BE(        rev             x4, x4          )
> -CPU_BE(        rev             x5, x5          )
> -CPU_BE(        rev             x6, x6          )
> +       byteorder       x3, \be
> +       byteorder       x4, \be
> +       byteorder       x5, \be
> +       byteorder       x6, \be
> +       bitorder        x3, \be
> +       bitorder        x4, \be
> +       bitorder        x5, \be
> +       bitorder        x6, \be
>         crc32\c\()x     w0, w0, x3
>         crc32\c\()x     w0, w0, x4
>         crc32\c\()x     w0, w0, x5
>         crc32\c\()x     w0, w0, x6
>         cbnz            x2, 32b
> -0:     ret
> +0:     bitorder        w0, \be
> +       ret
>
>  8:     tbz             x2, #3, 4f
>         ldr             x3, [x1], #8
> -CPU_BE(        rev             x3, x3          )
> +       byteorder       x3, \be
> +       bitorder        x3, \be
>         crc32\c\()x     w0, w0, x3
>  4:     tbz             x2, #2, 2f
>         ldr             w3, [x1], #4
> -CPU_BE(        rev             w3, w3          )
> +       byteorder       w3, \be
> +       bitorder        w3, \be
>         crc32\c\()w     w0, w0, w3
>  2:     tbz             x2, #1, 1f
>         ldrh            w3, [x1], #2
> -CPU_BE(        rev16           w3, w3          )
> +       byteorder16     w3, \be
> +       bitorder16      w3, \be
>         crc32\c\()h     w0, w0, w3
>  1:     tbz             x2, #0, 0f
>         ldrb            w3, [x1]
> +       bitorder8       w3, \be
>         crc32\c\()b     w0, w0, w3
> -0:     ret
> +0:     bitorder        w0, \be
> +       ret
>         .endm
>
>         .align          5
> @@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
>  alternative_else_nop_endif
>         __crc32         c
>  SYM_FUNC_END(__crc32c_le)
> +
> +       .align          5
> +SYM_FUNC_START(crc32_be)
> +alternative_if_not ARM64_HAS_CRC32
> +       b               crc32_be_base
> +alternative_else_nop_endif
> +       __crc32         be=1
> +SYM_FUNC_END(crc32_be)
> --
> 2.25.1
>


From krzysztof.kozlowski at canonical.com  Mon Jan 17 23:52:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 08:52:33 +0100
Subject: [PATCH v2 24/28] dt-bindings: pinctrl: samsung: convert to
 dtschema
In-Reply-To: <CAOesGMg2eH1B94h+etPBDW3B1LMeHBytz0v2e0GfVRDv8gU0YA@mail.gmail.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
 <20220111201722.327219-18-krzysztof.kozlowski@canonical.com>
 <CACRpkdYTXSOW+sOX3wVtF4jj6xm0jr-F3HKQPGHOdAVjbasP3A@mail.gmail.com>
 <5047da7c-d3a6-5472-b0ca-7ed3dbe8a5fe@canonical.com>
 <CACRpkdbhmJ91EW395C5F2WYjWJQdJ-SBHaDm7XnQsxMuyoMmLg@mail.gmail.com>
 <77bd8fa4-2b35-352c-da07-ef91fcbed454@canonical.com>
 <CAOesGMg2eH1B94h+etPBDW3B1LMeHBytz0v2e0GfVRDv8gU0YA@mail.gmail.com>
Message-ID: <794f39ed-3436-432c-767d-8fa60779d510@canonical.com>

On 17/01/2022 21:26, Olof Johansson wrote:
> On Sun, Jan 16, 2022 at 11:45 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 16/01/2022 22:38, Linus Walleij wrote:
>>> On Sun, Jan 16, 2022 at 6:10 PM Krzysztof Kozlowski
>>> <krzysztof.kozlowski at canonical.com> wrote:
>>>
>>>> Anyway DTS and dtschema will have to wait for one release, because they
>>>> depend on samsung pinctrl driver change (patch #2).
>>>
>>> What about I put that (and maybe this schema) on an immutable
>>> branch so you can pull the commit into your for-arm-soc branch and
>>> put the DTS changes on top?
>>
>> That would be a solution if not a policy for arm-soc of keeping DTS
>> separate. Arnd and Olof since some time are not happy when DTS branch
>> receives any driver updates.
>>
>> Arnd, Olof,
>> This is a set of dtschema conversion + DTS alignment with new schema:
>> 1. Driver change necessary to accept new DTS (driver depends on node
>> names and this has to change because of dtschema),
>> 2. DTS commits depending on above, which convert node name to new format,
>> 3. Finally dtschema requiring new naming of the GPIO nodes.
>>
>> If I got correctly, the policy of not mixing drivers and DTS requires
>> that #2 above (DTS changes) will wait for one more release. During the
>> time, if dtschema (#3 above) is applied, there will be new warnings
>> about non-compliant DTS.
>>
>> Do you see any chance of merging driver + DTS + dtschema via same tree
>> in same release?
> 
> Our general guidance to separate DTS and driver changes is to avoid
> large entangled changes between the two, and to discourage a developer
> mentality of "the implementation is the binding".
> 
> I think this is a good example of when it makes sense to bring in what
> is a fairly small and clean driver change to deal with this. So the
> right answer here is to stage such a stable branch and merge into both
> arm-soc and the pinctrl subsystem trees as proposed.

Thanks for clarification, I'll go with this approach.

Best regards,
Krzysztof


From clabbe.montjoie at gmail.com  Mon Jan 17 23:52:53 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 18 Jan 2022 08:52:53 +0100
Subject: crypto: BUG: spinlock recursion when doing iperf over ipsec with
 crypto hardware device
In-Reply-To: <YeEiWmkyNwfgQgmn@Red>
References: <Yd1SIHUNdLIvKhzz@Red> <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
 <YeD6vt47+pAl0SxG@gondor.apana.org.au> <YeEiWmkyNwfgQgmn@Red>
Message-ID: <YeZx1aVL0HnT9tCB@Red>

Le Fri, Jan 14, 2022 at 08:12:26AM +0100, Corentin Labbe a ?crit :
> Le Fri, Jan 14, 2022 at 03:23:26PM +1100, Herbert Xu a ?crit :
> > On Fri, Jan 14, 2022 at 03:14:38PM +1100, Herbert Xu wrote:
> > > On Tue, Jan 11, 2022 at 10:47:12AM +0100, Corentin Labbe wrote:
> > > >
> > > > [   44.646050] [<c0100afc>] (__irq_svc) from [<c080b9d4>] (xfrm_replay_advance+0x11c/0x3dc)
> > > > [   44.654143] [<c080b9d4>] (xfrm_replay_advance) from [<c0809388>] (xfrm_input+0x4d0/0x1304)
> > > > [   44.662408] [<c0809388>] (xfrm_input) from [<c03a3d88>] (crypto_finalize_request+0x5c/0xc4)
> > > > [   44.670766] [<c03a3d88>] (crypto_finalize_request) from [<c06a0888>] (sun8i_ce_cipher_run+0x34/0x3c)
> > > > [   44.679900] [<c06a0888>] (sun8i_ce_cipher_run) from [<c03a4264>] (crypto_pump_work+0x1a8/0x330)
> > > 
> > > So did sun8i_ce_cipher_run ensure that BH is disabled before
> > > invoking xfrm_input? If not then this explains the dead-lock.
> > 
> > The issue appears to be with crypto_engine.  It needs to ensure
> > that completion functions are called with BH disabled, not IRQ
> > disabled and definitely not BH enabled.
> > 
> 
> Hello
> 
> This minimal patch fix my issue, does it is the rigth way ?
> 
> Thanks for your help
> Regards
> 
> diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c
> index fb07da9920ee..b3844f6d98a3 100644
> --- a/crypto/crypto_engine.c
> +++ b/crypto/crypto_engine.c
> @@ -7,6 +7,7 @@
>   * Author: Baolin Wang <baolin.wang at linaro.org>
>   */
>  
> +#include <linux/bottom_half.h>
>  #include <linux/err.h>
>  #include <linux/delay.h>
>  #include <linux/device.h>
> @@ -53,7 +54,9 @@ static void crypto_finalize_request(struct crypto_engine *engine,
>                                 dev_err(engine->dev, "failed to unprepare request\n");
>                 }
>         }
> +       local_bh_disable();
>         req->complete(req, err);
> +       local_bh_enable();
>  
>         kthread_queue_work(engine->kworker, &engine->pump_requests);
>  }
> 

Hello

With my patch, I got:
[   38.515668] BUG: sleeping function called from invalid context at crypto/skcipher.c:482
[   38.523708] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 84, name: 1c15000.crypto-
[   38.532176] preempt_count: 200, expected: 0
[   38.536381] CPU: 6 PID: 84 Comm: 1c15000.crypto- Not tainted 5.16.0-next-20220115-00124-g13473e8fac33-dirty #116
[   38.546551] Hardware name: Allwinner A83t board
[   38.551100]  unwind_backtrace from show_stack+0x10/0x14
[   38.556358]  show_stack from dump_stack_lvl+0x40/0x4c
[   38.561428]  dump_stack_lvl from __might_resched+0x118/0x154
[   38.567107]  __might_resched from skcipher_walk_virt+0xe8/0xec
[   38.572955]  skcipher_walk_virt from crypto_cbc_decrypt+0x2c/0x170
[   38.579147]  crypto_cbc_decrypt from crypto_skcipher_decrypt+0x38/0x5c
[   38.585680]  crypto_skcipher_decrypt from authenc_verify_ahash_done+0x18/0x34
[   38.592825]  authenc_verify_ahash_done from crypto_finalize_request+0x6c/0xe4
[   38.599974]  crypto_finalize_request from sun8i_ss_hash_run+0x73c/0xb98
[   38.606602]  sun8i_ss_hash_run from crypto_pump_work+0x1a8/0x330
[   38.612616]  crypto_pump_work from kthread_worker_fn+0xa8/0x1c4
[   38.618550]  kthread_worker_fn from kthread+0xf0/0x110
[   38.623701]  kthread from ret_from_fork+0x14/0x2c
[   38.628414] Exception stack(0xc2247fb0 to 0xc2247ff8)
[   38.633468] 7fa0:                                     00000000 00000000 00000000 00000000
[   38.641640] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[   38.649809] 7fe0:i 00000000 00000000 00000000 00000000 00000013 00000000

This is when testing hmac(sha1) on my crypto driver sun8i-ss and crypto testing authenc(hmac-sha1-sun8i-ss,cbc(aes-generic)).

Do you have any idea to better fix my issue ?

Regards


From ardb at kernel.org  Tue Jan 18 00:28:08 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 09:28:08 +0100
Subject: [PATCH] ARM: uaccess: avoid alignment faults in
 copy_[from|to]_kernel_nofault
Message-ID: <20220118082808.931129-1-ardb@kernel.org>

The helpers that are used to implement copy_from_kernel_nofault() and
copy_to_kernel_nofault() cast a void* to a pointer to a wider type,
which may result in alignment faults on ARM if the compiler decides to
use double-word or multiple-word load/store instructions.

So use the unaligned accessors where needed: when the type's size > 1
and the input was not aligned already by the caller.

Cc: <stable at vger.kernel.org>
Fixes: 2df4c9a741a0 ("ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault")
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/uaccess.h | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 36fbc3329252..32dbfd81f42a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -11,6 +11,7 @@
 #include <linux/string.h>
 #include <asm/memory.h>
 #include <asm/domain.h>
+#include <asm/unaligned.h>
 #include <asm/unified.h>
 #include <asm/compiler.h>
 
@@ -497,7 +498,10 @@ do {									\
 	}								\
 	default: __err = __get_user_bad(); break;			\
 	}								\
-	*(type *)(dst) = __val;						\
+	if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))		\
+		put_unaligned(__val, (type *)(dst));			\
+	else								\
+		*(type *)(dst) = __val; /* aligned by caller */		\
 	if (__err)							\
 		goto err_label;						\
 } while (0)
@@ -507,7 +511,9 @@ do {									\
 	const type *__pk_ptr = (dst);					\
 	unsigned long __dst = (unsigned long)__pk_ptr;			\
 	int __err = 0;							\
-	type __val = *(type *)src;					\
+	type __val = IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)	\
+		     ? get_unaligned((type *)(src))			\
+		     : *(type *)(src);	/* aligned by caller */		\
 	switch (sizeof(type)) {						\
 	case 1: __put_user_asm_byte(__val, __dst, __err, ""); break;	\
 	case 2:	__put_user_asm_half(__val, __dst, __err, ""); break;	\
-- 
2.30.2



From s.hauer at pengutronix.de  Tue Jan 18 00:34:22 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Tue, 18 Jan 2022 09:34:22 +0100
Subject: [RFC PATCH v3 0/4] Fix and improve gpmi nand on mx28
In-Reply-To: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>
References: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>
Message-ID: <YeZ7jjzaLIioOGZo@pengutronix.de>

On Mon, Jan 17, 2022 at 05:17:51PM +0100, Dario Binacchi wrote:
> Starting from [1], the series fixes the timings setting of the gpmi
> controller for the mx28 architecture, also adding support for fast
> edo mode timings. The whole series has been heavily tested with the
> mtd kernel test modules, and with repeated write cycles on nand.
> 
> [1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org
> 
> Changes in v3:
> - Remove the "mtd: rawnand: gpmi: use a table to get EDO mode setup" patch.
> - Simplify the validation logic (suggested by Sascha Hauer <sha at pengutronix.de>).

Thanks Dario. I gave it a test on a custom i.MX28 board and it works as
expected.

For the series:

Tested-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From arnd at arndb.de  Tue Jan 18 00:38:31 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Tue, 18 Jan 2022 09:38:31 +0100
Subject: [PATCH] ARM: uaccess: avoid alignment faults in
 copy_[from|to]_kernel_nofault
In-Reply-To: <20220118082808.931129-1-ardb@kernel.org>
References: <20220118082808.931129-1-ardb@kernel.org>
Message-ID: <CAK8P3a0XGEZSTWy=24fEckPxtLoOt7sF7SYzF+QZEMooiW4BsA@mail.gmail.com>

On Tue, Jan 18, 2022 at 9:28 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> The helpers that are used to implement copy_from_kernel_nofault() and
> copy_to_kernel_nofault() cast a void* to a pointer to a wider type,
> which may result in alignment faults on ARM if the compiler decides to
> use double-word or multiple-word load/store instructions.
>
> So use the unaligned accessors where needed: when the type's size > 1
> and the input was not aligned already by the caller.
>
> Cc: <stable at vger.kernel.org>
> Fixes: 2df4c9a741a0 ("ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault")
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>

It took me a bit to see whythis works, maybe mention commit 2423de2e6f4d
("ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault")
in the description for clarification.

Did you run into actual faults, or did you find this problem by
reading the code?

         Arnd


From ardb at kernel.org  Tue Jan 18 00:41:09 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 09:41:09 +0100
Subject: [PATCH] ARM: uaccess: avoid alignment faults in
 copy_[from|to]_kernel_nofault
In-Reply-To: <CAK8P3a0XGEZSTWy=24fEckPxtLoOt7sF7SYzF+QZEMooiW4BsA@mail.gmail.com>
References: <20220118082808.931129-1-ardb@kernel.org>
 <CAK8P3a0XGEZSTWy=24fEckPxtLoOt7sF7SYzF+QZEMooiW4BsA@mail.gmail.com>
Message-ID: <CAMj1kXGtHoDYzjv8eUg0xbs4aTZVnRDHCne-cJg=9ZLHzYbOgQ@mail.gmail.com>

On Tue, 18 Jan 2022 at 09:38, Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Tue, Jan 18, 2022 at 9:28 AM Ard Biesheuvel <ardb at kernel.org> wrote:
> >
> > The helpers that are used to implement copy_from_kernel_nofault() and
> > copy_to_kernel_nofault() cast a void* to a pointer to a wider type,
> > which may result in alignment faults on ARM if the compiler decides to
> > use double-word or multiple-word load/store instructions.
> >
> > So use the unaligned accessors where needed: when the type's size > 1
> > and the input was not aligned already by the caller.
> >
> > Cc: <stable at vger.kernel.org>
> > Fixes: 2df4c9a741a0 ("ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault")
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
>
> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
>
> It took me a bit to see whythis works, maybe mention commit 2423de2e6f4d
> ("ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault")
> in the description for clarification.
>

Ack.

> Did you run into actual faults, or did you find this problem by
> reading the code?
>

I was seeing actual faults:

[    4.447003]  copy_from_kernel_nofault from prepend+0x3c/0xb4
[    4.453085]  prepend from prepend_path+0x118/0x34c
[    4.457930]  prepend_path from d_path+0x11c/0x184
[    4.462656]  d_path from proc_pid_readlink+0xbc/0x1d4
[    4.467928]  proc_pid_readlink from vfs_readlink+0xfc/0x110
[    4.473740]  vfs_readlink from do_readlinkat+0xb0/0x110
[    4.479024]  do_readlinkat from ret_fast_syscall+0x0/0x54


From leo.yan at linaro.org  Tue Jan 18 01:18:27 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 18 Jan 2022 17:18:27 +0800
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
Message-ID: <20220118091827.GA98966@leoy-ThinkPad-X240s>

On Mon, Jan 17, 2022 at 03:39:10PM +0000, John Garry wrote:
> On 16/12/2021 15:48, Marco Elver wrote:
> 
> +
> 
> > On Thu, 16 Dec 2021 at 16:15, Thomas Richter<tmricht at linux.ibm.com>  wrote:
> > > In Linux next kernel
> > > Commit 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
> > > introduced the new test which uses breakpoint events.
> > > These events are not supported on s390 and PowerPC and always fail:
> > > 
> > >   # perf test -F 73
> > >   73: Sigtrap                                                         : FAILED!
> > >   #
> > > 
> > > Fix it the same way as in the breakpoint tests in file
> > > tests/bp_account.c where these type of tests are skipped on
> > > s390 and PowerPC platforms.
> > > 
> > > With this patch skip this test on both platforms.
> > > 
> > > Output after:
> > >   # ./perf test -F 73
> > >   73: Sigtrap
> > > 
> > > Fixes: 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
> > > 
> > > Cc: Marco Elver<elver at google.com>
> > > Signed-off-by: Thomas Richter<tmricht at linux.ibm.com>
> > Acked-by: Marco Elver<elver at google.com>
> > 
> > Thanks, and sorry for missing this case!
> > 
> 
> I am finding that this test hangs on my arm64 machine:
> 
> john at debian:~/kernel-dev2/tools/perf$ sudo ./perf test -vvv 73
>  73: Sigtrap:
> --- start ---
> test child forked, pid 45193

Both Arm and Arm64 platforms cannot support signal handler with
breakpoint, please see the details in [1].  So I think we need
something like below:

static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
        ...

        if (!BP_SIGNAL_IS_SUPPORTED) {
                pr_debug("Test not supported on this architecture");
                return TEST_SKIP;
        }

        ...
}

Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
here.

[1] https://lore.kernel.org/lkml/157169993406.29376.12473771029179755767.tip-bot2 at tip-bot2/

> And fails on my x86 broadwell machine:
> 
> john at localhost:~/kernel-dev2/tools/perf> sudo ./perf test -v 73
> 73: Sigtrap                                                         :
> --- start ---
> test child forked, pid 22255
> FAILED sys_perf_event_open(): Argument list too long
> test child finished with -1
> ---- end ----
> Sigtrap: FAILED!
> john at localhost:~/kernel-dev2/tools/perf>

It is a bit suprise for the failure on x86, as I remembered x86 platform
can support signal handler with hw breakpoint.  And from the error
"Argument list too long", it should be a different issue from other
archs.

Thanks,
Leo


From andy.shevchenko at gmail.com  Tue Jan 18 01:18:57 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Tue, 18 Jan 2022 11:18:57 +0200
Subject: [RESEND v3 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220117082539.18713-4-axe.yang@mediatek.com>
References: <20220117082539.18713-1-axe.yang@mediatek.com>
 <20220117082539.18713-4-axe.yang@mediatek.com>
Message-ID: <CAHp75VdkKYujGZOdGkLK-tzC9q+RjkX59fFZe5cHajGOnDdL2w@mail.gmail.com>

On Mon, Jan 17, 2022 at 7:33 PM Axe Yang <axe.yang at mediatek.com> wrote:
>
> Add support for eint IRQ when MSDC is used as an SDIO host. This
> feature requires SDIO device support async IRQ function. With this
> feature, SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
>
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
>
> Some device tree property should be added or modified in MSDC node
> to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>         &mmcX {
>                 ...
>                 pinctrl-names = "default", "state_uhs", "state_eint",
>                                 "state_dat1";
>                 ...
>                 pinctrl-2 = <&mmc2_pins_eint>;
>                 pinctrl-3 = <&mmc2_pins_dat1>;
>                 ...
>                 cap-sdio-async-irq;
>                 ...
>         };

...

> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +       struct msdc_host *host = dev_id;
> +       struct mmc_host *mmc = mmc_from_priv(host);

> +       unsigned long flags;

Same Q as per v2. Why do you need this?

Yes, you did the first step to the answer, but I want you to go deeper
and tell me why you need the spin_lock_irqsave() variant.

> +       spin_lock_irqsave(&host->lock, flags);
> +       if (likely(host->sdio_irq_cnt > 0)) {
> +               disable_irq_nosync(host->eint_irq);
> +               disable_irq_wake(host->eint_irq);
> +               host->sdio_irq_cnt--;
> +       }
> +       spin_unlock_irqrestore(&host->lock, flags);
> +
> +       sdio_signal_irq(mmc);
> +
> +       return IRQ_HANDLED;
> +}

-- 
With Best Regards,
Andy Shevchenko


From yuzhao at google.com  Tue Jan 18 01:21:21 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 18 Jan 2022 02:21:21 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <YeaGkZ50n7/mDuJX@google.com>

On Tue, Jan 11, 2022 at 01:41:22AM -0700, Yu Zhao wrote:
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> > On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > > TLDR
> > > ====
> > > The current page reclaim is too expensive in terms of CPU usage and it
> > > often makes poor choices about what to evict. This patchset offers an
> > > alternative solution that is performant, versatile and
> > > straightforward.
> > 
> > <snipped>
> > 
> > > Summery
> > > =======
> > > The facts are:
> > > 1. The independent lab results and the real-world applications
> > >    indicate substantial improvements; there are no known regressions.
> > > 2. Thrashing prevention, working set estimation and proactive reclaim
> > >    work out of the box; there are no equivalent solutions.
> > > 3. There is a lot of new code; nobody has demonstrated smaller changes
> > >    with similar effects.
> > > 
> > > Our options, accordingly, are:
> > > 1. Given the amount of evidence, the reported improvements will likely
> > >    materialize for a wide range of workloads.
> > > 2. Gauging the interest from the past discussions [14][15][16], the
> > >    new features will likely be put to use for both personal computers
> > >    and data centers.
> > > 3. Based on Google's track record, the new code will likely be well
> > >    maintained in the long term. It'd be more difficult if not
> > >    impossible to achieve similar effects on top of the existing
> > >    design.
> > 
> > Hi Andrew, Linus,
> > 
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> > 
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.

My gratitude to Donald who has been helping test MGLRU since v2:

    Donald Carr (d at chaos-reins.com)

    Founder of Chaos Reins (http://chaos-reins.com), an SF based
    consultancy company specializing in designing/creating embedded
    Linux appliances.

Can you please provide your Tested-by tags? This will ensure the credit
for your contributions.

Thanks!


From andrzej.hajda at intel.com  Tue Jan 18 01:24:52 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 18 Jan 2022 10:24:52 +0100
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220118025918.1444288-1-victor.liu@nxp.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
Message-ID: <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>

Hi,

On 18.01.2022 03:59, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
>
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
>
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
>
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
>
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
>   drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
>   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
>   drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
>   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
>   include/linux/phy/phy-mipi-dphy.h                | 4 +++-
>   5 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..f1fdcdf763ee 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>   /*
>    * ui2bc - UI time periods to byte clock cycles
>    */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
>   {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);


I have some doubts here. According to specs:

 ??? UI - duration of any HS state on the Clock Lane,

 ??? TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate

I'd like to emphasize "BIT RATE" above (not clock rate).

In such case I would expect that ui2bc would take into account number of 
lanes:

byte clock cycles = div_round_up(ui * dsi->lanes, 8)

So in case of one lane we need 8 ticks to get byte, and in case of 4 
lanes 2 ticks are enough.

Am I correct, or I've missed sth?


>   }
>   
>   /*
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..8a818cdb7606 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre,
> +				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
>   
>   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>   
>   	cfg->clk_miss = 0;
>   	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>   	cfg->clk_prepare = 38000;
>   	cfg->clk_settle = 95000;
>   	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>   	if (cfg->clk_post < (60000 + 52 * ui))
>   		return -EINVAL;
>   
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>   		return -EINVAL;
>   
>   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..67b0a17be7e3 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   	 * The value of counter for HS Tclk-pre
>   	 * Tclk-pre = Tpin_txbyteclkhs * value
>   	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
> +			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
>   
>   	/*
>   	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..ab1f736fbcd3 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -6,6 +6,8 @@
>   #ifndef __PHY_MIPI_DPHY_H_
>   #define __PHY_MIPI_DPHY_H_
>   
> +#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8


Do we need to define it? I guess it is just BITS_PER_BYTE.


Regards

Andrzej


> +
>   /**
>    * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
>    *
> @@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
>   	 * the transmitter prior to any associated Data Lane beginning
>   	 * the transition from LP to HS mode.
>   	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>   	 */
>   	unsigned int		clk_pre;
>   


From johnson.wang at mediatek.com  Tue Jan 18 01:25:25 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Tue, 18 Jan 2022 17:25:25 +0800
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for
 MT8186 SoC
In-Reply-To: <9949a1f7-1ed5-a137-c7b9-2ef8d8e1caf8@gmail.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
 <9949a1f7-1ed5-a137-c7b9-2ef8d8e1caf8@gmail.com>
Message-ID: <544f5085fc8597ce9ce3eb7dc1b5d08fb1ac8755.camel@mediatek.com>

Hi Matthias,

On Fri, 2022-01-14 at 16:46 +0100, Matthias Brugger wrote:
> 
> On 07/01/2022 11:46, Johnson Wang wrote:
> > MT8186 are highly integrated SoC and use PMIC_MT6366 for
> > power management. This patch adds pwrap master driver to
> > access PMIC_MT6366.
> > 
> 
> It seems this new arbiter is significantly different from the version
> 1. Please 
> explain that in the commit message.
> 
> > Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> > ---
> >   drivers/soc/mediatek/mtk-pmic-wrap.c | 72
> > ++++++++++++++++++++++++++++
> >   1 file changed, 72 insertions(+)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > index 952bc554f443..78866ebf7f04 100644
> > --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > @@ -30,6 +30,7 @@
> >   #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) &
> > 0x00000001)
> >   #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
> >   #define PWRAP_STATE_INIT_DONE0		BIT(21)
> > +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
> 
> That's a strange name, does it come from the datasheet description?

Thanks for your review.

No, there is only PWRAP_STATE_INIT_DONE0 in MT8186 datasheet.
However, it's the 22nd bit in MT8186 and the 21st bit in other SoCs.
So we changed its name to avoid redefinition of PWRAP_STATE_INIT_DONE0.

Could you give us some suggestion on proper definition naming?
Do you think PWRAP_STATE_INIT_DONE0_MT8186 will be a better choice?

> 
> >   #define PWRAP_STATE_INIT_DONE1		BIT(15)
> >   
> >   /* macro for WACS FSM */
> > @@ -77,6 +78,8 @@
> >   #define PWRAP_CAP_INT1_EN	BIT(3)
> >   #define PWRAP_CAP_WDT_SRC1	BIT(4)
> >   #define PWRAP_CAP_ARB		BIT(5)
> > +#define PWRAP_CAP_MONITOR_V2	BIT(6)
> 
> Not used capability, please delete.
> 
> 
> Regards,
> Matthias

PWRAP_CAP_MONITOR_V2 is not used right now.
We can remove it in next version.
But this capability will be added when we need it.

Thanks.



From jirislaby at kernel.org  Tue Jan 18 01:35:51 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:35:51 +0100
Subject: [PATCH V6 1/5] tty: serial: meson: Move request the register
 region to probe
In-Reply-To: <20220118030911.12815-2-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-2-yu.tu@amlogic.com>
Message-ID: <a7267804-1400-c63d-50a0-72423f141317@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> This simplifies resetting the UART controller during probe
> and will make it easier to integrate the common clock code
> which will require the registers at probe time as well.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>

Reviewed-by: Jiri Slaby <jirislaby at kernel.org>

thanks,
-- 
js
suse labs


From d at chaos-reins.com  Tue Jan 18 01:36:01 2022
From: d at chaos-reins.com (Donald Carr)
Date: Tue, 18 Jan 2022 09:36:01 +0000
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <YeaGkZ50n7/mDuJX@google.com>
References: <YeaGkZ50n7/mDuJX@google.com>
 <20220104202227.2903605-1-yuzhao@google.com> <YdSuSHa/Vjl6bPkg@google.com>
 <Yd1Css8+jsspeZHh@google.com>
Message-ID: <e2db335efc02c61f4a4035dd2270e256@chaos-reins.com>

January 18, 2022 1:21 AM, "Yu Zhao" <yuzhao at google.com> wrote:

> On Tue, Jan 11, 2022 at 01:41:22AM -0700, Yu Zhao wrote:
> 
>> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
>> On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
>>> TLDR
>>> ====
>>> The current page reclaim is too expensive in terms of CPU usage and it
>>> often makes poor choices about what to evict. This patchset offers an
>>> alternative solution that is performant, versatile and
>>> straightforward.
>> 
>> <snipped>
>> 
>>> Summery
>>> =======
>>> The facts are:
>>> 1. The independent lab results and the real-world applications
>>> indicate substantial improvements; there are no known regressions.
>>> 2. Thrashing prevention, working set estimation and proactive reclaim
>>> work out of the box; there are no equivalent solutions.
>>> 3. There is a lot of new code; nobody has demonstrated smaller changes
>>> with similar effects.
>>> 
>>> Our options, accordingly, are:
>>> 1. Given the amount of evidence, the reported improvements will likely
>>> materialize for a wide range of workloads.
>>> 2. Gauging the interest from the past discussions [14][15][16], the
>>> new features will likely be put to use for both personal computers
>>> and data centers.
>>> 3. Based on Google's track record, the new code will likely be well
>>> maintained in the long term. It'd be more difficult if not
>>> impossible to achieve similar effects on top of the existing
>>> design.
>> 
>> Hi Andrew, Linus,
>> 
>> Can you please take a look at this patchset and let me know if it's
>> 5.17 material?
>> 
>> My goal is to get it merged asap so that users can reap the benefits
>> and I can push the sequels. Please examine the data provided -- I
>> think the unprecedented coverage and the magnitude of the improvements
>> warrant a green light.
> 
> My gratitude to Donald who has been helping test MGLRU since v2:
> 
> Donald Carr (d at chaos-reins.com)
> 
> Founder of Chaos Reins (http://chaos-reins.com), an SF based
> consultancy company specializing in designing/creating embedded
> Linux appliances.

Tested-by: Donald Carr <d at chaos-reins.com>

> Can you please provide your Tested-by tags? This will ensure the credit
> for your contributions.
> 
> Thanks!


From jirislaby at kernel.org  Tue Jan 18 01:36:10 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:36:10 +0100
Subject: [PATCH V6 2/5] tty: serial: meson: Use devm_ioremap_resource to
 get register mapped memory
In-Reply-To: <20220118030911.12815-3-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-3-yu.tu@amlogic.com>
Message-ID: <97dfc8b2-fded-01df-44e9-b24988a76d54@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> Replace devm_request_mem_region and devm_ioremap with
> devm_ioremap_resource to make the code cleaner.
> 
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>

Reviewed-by: Jiri Slaby <jirislaby at kernel.org>

thanks,
-- 
js


From jirislaby at kernel.org  Tue Jan 18 01:39:25 2022
From: jirislaby at kernel.org (Jiri Slaby)
Date: Tue, 18 Jan 2022 10:39:25 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-4-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
Message-ID: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>

On 18. 01. 22, 4:09, Yu Tu wrote:
> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
...
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
...
> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>   	.cons		= MESON_SERIAL_CONSOLE,
>   };
>   
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> -{
> -	struct clk *clk = NULL;
> -	int ret;
> -
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> -
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> -
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> +static struct clk_div_table xtal_div_table[] = {

This can be const, right?

> +	{0, 3},
> +	{1, 1},
> +	{2, 2},
> +	{3, 2},

Not sure if you didn't remove too much whitespace. I think it should be 
like: "{ 0, 3 },". But I actually don't care, it's a minor thing.

I cannot comment on the rest (clk and OF part) as my knowledge is pretty 
limited there. Leaving up to others.

thanks,
-- 
js
suse labs


From gshan at redhat.com  Tue Jan 18 01:38:20 2022
From: gshan at redhat.com (Gavin Shan)
Date: Tue, 18 Jan 2022 17:38:20 +0800
Subject: [PATCH v2] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <20220118084858.175305-1-gshan@redhat.com>
References: <20220118084858.175305-1-gshan@redhat.com>
Message-ID: <2f0d1a5f-7e75-04b1-f2a1-f52385dae3b5@redhat.com>

On 1/18/22 4:48 PM, Gavin Shan wrote:
> This enables virtio-mem device support by allowing to enable the
> corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
> architecture.
> 
> Signed-off-by: Gavin Shan <gshan at redhat.com>
> Acked-by: David Hildenbrand <david at redhat.com>
> ---
> v2: Improved the comments about the kernel config option (David)
> ---
>   drivers/virtio/Kconfig | 7 ++++---
>   1 file changed, 4 insertions(+), 3 deletions(-)

My git-sendemail should have been broken. A list of receivers are
dropped automatically though they were explicitly specified, but
linux-arm-kernel at lists.infradead.org was missed to be copied.
Fixing all of them through thunderbird :)

Thanks,
Gavin

> 
> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> index 34f80b7a8a64..74c8b0c7bc33 100644
> --- a/drivers/virtio/Kconfig
> +++ b/drivers/virtio/Kconfig
> @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
>   config VIRTIO_MEM
>   	tristate "Virtio mem driver"
>   	default m
> -	depends on X86_64
> +	depends on X86_64 || ARM64
>   	depends on VIRTIO
>   	depends on MEMORY_HOTPLUG
>   	depends on MEMORY_HOTREMOVE
> @@ -116,8 +116,9 @@ config VIRTIO_MEM
>   	 This driver provides access to virtio-mem paravirtualized memory
>   	 devices, allowing to hotplug and hotunplug memory.
>   
> -	 This driver was only tested under x86-64, but should theoretically
> -	 work on all architectures that support memory hotplug and hotremove.
> +	 This driver was only tested under x86-64 and arm64, but should
> +	 theoretically work on all architectures that support memory hotplug
> +	 and hotremove.
>   
>   	 If unsure, say M.
>   
> 



From lecopzer.chen at mediatek.com  Tue Jan 18 01:44:48 2022
From: lecopzer.chen at mediatek.com (Lecopzer Chen)
Date: Tue, 18 Jan 2022 17:44:48 +0800
Subject: [PATCH 0/2] arm: kasan: support CONFIG_KASAN_VMALLOC
Message-ID: <20220118094450.7730-1-lecopzer.chen@mediatek.com>

From: Lecopzer Chen <lecopzer at gmail.com>

Since the framework of KASAN_VMALLOC is well-developed,
It's easy to support for ARM that simply not to map shadow of VMALLOC
area on kasan_init.

This can fix ARM_MODULE_PLTS with KASAN and provide first step
to support CONFIG_VMAP_STACK in ARM.
    

Patch base on v5.16

Test on
1. Qemu with memory 2G and vmalloc=500M for 3G/1G mapping.
2. Qemu with memory 2G and vmalloc=500M for 3G/1G mapping + LPAE.
3. Qemu with memory 2G and vmalloc=500M for 2G/2G mapping.


Lecopzer Chen (2):
  arm: kasan: support CONFIG_KASAN_VMALLOC
  arm: kconfig: fix MODULE_PLTS for KASAN with KASAN_VMALLOC

 arch/arm/Kconfig         | 2 ++
 arch/arm/mm/kasan_init.c | 6 +++++-
 2 files changed, 7 insertions(+), 1 deletion(-)

-- 
2.25.1



From lecopzer.chen at mediatek.com  Tue Jan 18 01:44:50 2022
From: lecopzer.chen at mediatek.com (Lecopzer Chen)
Date: Tue, 18 Jan 2022 17:44:50 +0800
Subject: [PATCH 2/2] arm: kconfig: fix MODULE_PLTS for KASAN with KASAN_VMALLOC
In-Reply-To: <20220118094450.7730-1-lecopzer.chen@mediatek.com>
References: <20220118094450.7730-1-lecopzer.chen@mediatek.com>
Message-ID: <20220118094450.7730-3-lecopzer.chen@mediatek.com>

When we run out of module space address with ko insertion,
and with MODULE_PLTS, module would turn to try to find memory
from VMALLOC address space.

Unfortunately, with KASAN enabled, VMALLOC doesn't work without
KASAN_VMALLOC, thus select KASAN_VMALLOC by default.

8<--- cut here ---
 Unable to handle kernel paging request at virtual address bd300860
 [bd300860] *pgd=41cf1811, *pte=41cf26df, *ppte=41cf265f
 Internal error: Oops: 80f [#1] PREEMPT SMP ARM
 Modules linked in: hello(O+)
 CPU: 0 PID: 89 Comm: insmod Tainted: G           O      5.16.0-rc6+ #19
 Hardware name: Generic DT based system
 PC is at mmioset+0x30/0xa8
 LR is at 0x0
 pc : [<c077ed30>]    lr : [<00000000>]    psr: 20000013
 sp : c451fc18  ip : bd300860  fp : c451fc2c
 r10: f18042cc  r9 : f18042d0  r8 : 00000000
 r7 : 00000001  r6 : 00000003  r5 : 01312d00  r4 : f1804300
 r3 : 00000000  r2 : 00262560  r1 : 00000000  r0 : bd300860
 Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
 Control: 10c5387d  Table: 43e9406a  DAC: 00000051
 Register r0 information: non-paged memory
 Register r1 information: NULL pointer
 Register r2 information: non-paged memory
 Register r3 information: NULL pointer
 Register r4 information: 4887-page vmalloc region starting at 0xf1802000 allocated at load_module+0x14f4/0x32a8
 Register r5 information: non-paged memory
 Register r6 information: non-paged memory
 Register r7 information: non-paged memory
 Register r8 information: NULL pointer
 Register r9 information: 4887-page vmalloc region starting at 0xf1802000 allocated at load_module+0x14f4/0x32a8
 Register r10 information: 4887-page vmalloc region starting at 0xf1802000 allocated at load_module+0x14f4/0x32a8
 Register r11 information: non-slab/vmalloc memory
 Register r12 information: non-paged memory
 Process insmod (pid: 89, stack limit = 0xc451c000)
 Stack: (0xc451fc18 to 0xc4520000)
 fc00:                                                       f18041f0 c04803a4
 fc20: c451fc44 c451fc30 c048053c c0480358 f1804030 01312cff c451fc64 c451fc48
 fc40: c047f330 c0480500 f18040c0 c1b52ccc 00000001 c5be7700 c451fc74 c451fc68
 fc60: f1802098 c047f300 c451fcb4 c451fc78 c026106c f180208c c4880004 00000000
 fc80: c451fcb4 bf001000 c044ff48 c451fec0 f18040c0 00000000 c1b54cc4 00000000
 fca0: c451fdf0 f1804268 c451fe64 c451fcb8 c0264e88 c0260d48 ffff8000 00007fff
 fcc0: f18040c0 c025cd00 c451fd14 00000003 0157f008 f1804258 f180425c f1804174
 fce0: f1804154 f180424c f18041f0 f180414c f1804178 f18041c0 bf0025d4 188a3fa8
 fd00: 0000009e f1804170 f2b18000 c451ff10 c0d92e40 f180416c c451feec 00000001
 fd20: 00000000 c451fec8 c451fe20 c451fed0 f18040cc 00000000 f17ea000 c451fdc0
 fd40: 41b58ab3 c1387729 c0261c28 c047fb5c c451fe2c c451fd60 c0525308 c048033c
 fd60: 188a3fb4 c3ccb090 c451fe00 c3ccb080 00000000 00000000 00016920 00000000
 fd80: c02d0388 c047f55c c02d0388 00000000 c451fddc c451fda0 c02d0388 00000000
 fda0: 41b58ab3 c13a72d0 c0524ff0 c1705f48 c451fdfc c451fdc0 c02d0388 c047f55c
 fdc0: 00016920 00000000 00000003 c1bb2384 c451fdfc c3ccb080 c1bb2384 00000000
 fde0: 00000000 00000000 00000000 00000000 c451fe1c c451fe00 c04e9d70 c1705f48
 fe00: c1b54cc4 c1bbc71c c3ccb080 00000000 c3ccb080 00000000 00000003 c451fec0
 fe20: c451fe64 c451fe30 c0525918 c0524ffc c451feb0 c1705f48 00000000 c1b54cc4
 fe40: b78a3fd0 c451ff60 00000000 0157f008 00000003 c451fec0 c451ffa4 c451fe68
 fe60: c0265480 c0261c34 c451feb0 7fffffff 00000000 00000002 00000000 c4880000
 fe80: 41b58ab3 c138777b c02652cc c04803ec 000a0000 c451ff00 ffffff9c b6ac9f60
 fea0: c451fed4 c1705f48 c04a4a90 b78a3fdc f17ea000 ffffff9c b6ac9f60 c0100244
 fec0: f17ea21a f17ea300 f17ea000 00016920 f1800240 f18000ac f17fb7dc 01316000
 fee0: 013161b0 00002590 01316250 00000000 00000000 00000000 00002580 00000029
 ff00: 0000002a 00000013 00000000 0000000c 00000000 00000000 0157f004 c451ffb0
 ff20: c1719be0 aed6f410 c451ff74 c451ff38 c0c4103c c0c407d0 c451ff84 c451ff48
 ff40: 00000805 c02c8658 c1604230 c1719c30 00000805 0157f004 00000005 c451ffb0
 ff60: c1719be0 aed6f410 c451ffac c451ff78 c0122130 c1705f48 c451ffac 0157f008
 ff80: 00000006 0000005f 0000017b c0100244 c4880000 0000017b 00000000 c451ffa8
 ffa0: c0100060 c02652d8 0157f008 00000006 00000003 0157f008 00000000 b6ac9f60
 ffc0: 0157f008 00000006 0000005f 0000017b 00000000 00000000 aed85f74 00000000
 ffe0: b6ac9cd8 b6ac9cc8 00030200 aecf2d60 a0000010 00000003 00000000 00000000
 Backtrace:
 [<c048034c>] (kasan_poison) from [<c048053c>] (kasan_unpoison+0x48/0x5c)
 [<c04804f4>] (kasan_unpoison) from [<c047f330>] (__asan_register_globals+0x3c/0x64)
  r5:01312cff r4:f1804030
 [<c047f2f4>] (__asan_register_globals) from [<f1802098>] (_sub_I_65535_1+0x18/0xf80 [hello])
  r7:c5be7700 r6:00000001 r5:c1b52ccc r4:f18040c0
 [<f1802080>] (_sub_I_65535_1 [hello]) from [<c026106c>] (do_init_module+0x330/0x72c)
 [<c0260d3c>] (do_init_module) from [<c0264e88>] (load_module+0x3260/0x32a8)
  r10:f1804268 r9:c451fdf0 r8:00000000 r7:c1b54cc4 r6:00000000 r5:f18040c0
  r4:c451fec0
 [<c0261c28>] (load_module) from [<c0265480>] (sys_finit_module+0x1b4/0x1e8)
  r10:c451fec0 r9:00000003 r8:0157f008 r7:00000000 r6:c451ff60 r5:b78a3fd0
  r4:c1b54cc4
 [<c02652cc>] (sys_finit_module) from [<c0100060>] (ret_fast_syscall+0x0/0x1c)
 Exception stack(0xc451ffa8 to 0xc451fff0)
 ffa0:                   0157f008 00000006 00000003 0157f008 00000000 b6ac9f60
 ffc0: 0157f008 00000006 0000005f 0000017b 00000000 00000000 aed85f74 00000000
 ffe0: b6ac9cd8 b6ac9cc8 00030200 aecf2d60
  r10:0000017b r9:c4880000 r8:c0100244 r7:0000017b r6:0000005f r5:00000006
  r4:0157f008
 Code: e92d4100 e1a08001 e1a0e003 e2522040 (a8ac410a)
 ---[ end trace df6e12843197b6f5 ]---

Signed-off-by: Lecopzer Chen <lecopzer.chen at mediatek.com>
---
 arch/arm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f97f2c416be0..d219179d3254 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1514,6 +1514,7 @@ config ARCH_WANT_GENERAL_HUGETLB
 config ARM_MODULE_PLTS
 	bool "Use PLTs to allow module memory to spill over into vmalloc area"
 	depends on MODULES
+	select KASAN_VMALLOC if KASAN
 	default y
 	help
 	  Allocate PLTs when loading modules so that jumps and calls whose
-- 
2.25.1



From lecopzer.chen at mediatek.com  Tue Jan 18 01:44:49 2022
From: lecopzer.chen at mediatek.com (Lecopzer Chen)
Date: Tue, 18 Jan 2022 17:44:49 +0800
Subject: [PATCH 1/2] arm: kasan: support CONFIG_KASAN_VMALLOC
In-Reply-To: <20220118094450.7730-1-lecopzer.chen@mediatek.com>
References: <20220118094450.7730-1-lecopzer.chen@mediatek.com>
Message-ID: <20220118094450.7730-2-lecopzer.chen@mediatek.com>

Simply make shadow of vmalloc area mapped on demand.

This can fix ARM_MODULE_PLTS with KASAN and provide first step
to support CONFIG_VMAP_STACK in ARM.

Signed-off-by: Lecopzer Chen <lecopzer.chen at mediatek.com>
---
 arch/arm/Kconfig         | 1 +
 arch/arm/mm/kasan_init.c | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..f97f2c416be0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -72,6 +72,7 @@ config ARM
 	select HAVE_ARCH_KFENCE if MMU && !XIP_KERNEL
 	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
 	select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
+	select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
 	select HAVE_ARCH_PFN_VALID
 	select HAVE_ARCH_SECCOMP
diff --git a/arch/arm/mm/kasan_init.c b/arch/arm/mm/kasan_init.c
index 5ad0d6c56d56..29caee9c79ce 100644
--- a/arch/arm/mm/kasan_init.c
+++ b/arch/arm/mm/kasan_init.c
@@ -236,7 +236,11 @@ void __init kasan_init(void)
 
 	clear_pgds(KASAN_SHADOW_START, KASAN_SHADOW_END);
 
-	kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START),
+	if (!IS_ENABLED(CONFIG_KASAN_VMALLOC))
+		kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START),
+					    kasan_mem_to_shadow((void *)VMALLOC_END));
+
+	kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_END),
 				    kasan_mem_to_shadow((void *)-1UL) + 1);
 
 	for_each_mem_range(i, &pa_start, &pa_end) {
-- 
2.25.1



From catalin.marinas at arm.com  Tue Jan 18 01:51:41 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 18 Jan 2022 09:51:41 +0000
Subject: [PATCH v2 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220113165807.2735949-5-kevin@bracey.fi>
References: <20220113165807.2735949-1-kevin@bracey.fi>
 <20220113165807.2735949-5-kevin@bracey.fi>
Message-ID: <YeaNrUGYAbW/Jy4m@arm.com>

On Thu, Jan 13, 2022 at 06:58:07PM +0200, Kevin Bracey wrote:
> It makes no sense to leave crc32_be using the generic code while we
> only accelerate the little-endian ops.
> 
> Even though the big-endian form doesn't fit as smoothly into the arm64,
> we can speed it up and avoid hitting the D cache.
> 
> Tested on Cortex-A53. Without acceleration:
> 
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 192240 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21360 nsec
> 
> With acceleration:
> 
>     crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
>     crc32: self tests passed, processed 225944 bytes in 53480 nsec
>     crc32c: CRC_LE_BITS = 64
>     crc32c: self tests passed, processed 112972 bytes in 21480 nsec
> 
> Signed-off-by: Kevin Bracey <kevin at bracey.fi>
> Tested-by: Ard Biesheuvel <ardb at kernel.org>
> Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>

Acked-by: Catalin Marinas <catalin.marinas at arm.com>


From will at kernel.org  Tue Jan 18 01:52:58 2022
From: will at kernel.org (Will Deacon)
Date: Tue, 18 Jan 2022 09:52:58 +0000
Subject: [RFC PATCH 2/2] perf: arm_spe: Enable CONTEXT packets in SPE
 traces if the profiler runs in CPU mode.
In-Reply-To: <20220117124432.3119132-3-german.gomez@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-3-german.gomez@arm.com>
Message-ID: <20220118095258.GA16547@willie-the-truck>

On Mon, Jan 17, 2022 at 12:44:32PM +0000, German Gomez wrote:
> Enable CONTEXT packets in SPE traces if the profiler runs in CPU mode.
> This is no less permissive than the existing behavior for the following
> reason:
> 
> If perf_event_paranoid <= 0, then non perfmon_capable() users can open
> a per-CPU event. With a per-CPU event, unpriviledged users are allowed
> to profile _all_ processes, even ones owned by root.
> 
> Without this change, users could see kernel addresses, root processes,
> etc, but not gather the PIDs of those processes. The PID is probably the
> least sensitive of all the information.
> 
> It would be more idiomatic to check the perf_event_paranoid level with
> perf_allow_cpu(), but this function is not exported so cannot be used
> from a module. Looking for cpu != -1 is the indirect way of checking
> the same thing as it could never get to arm_spe_pmu_event_init() without
> perf_event_paranoid <= 0.

perf_allow_cpu() is a static inline so there's no need to export it. What's
missing?

Will


From dario.binacchi at amarulasolutions.com  Tue Jan 18 01:54:30 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Tue, 18 Jan 2022 10:54:30 +0100
Subject: [PATCH 0/4] Fix and improve gpmi nand on mx28
Message-ID: <20220118095434.35081-1-dario.binacchi@amarulasolutions.com>

Starting from [1], the series fixes the timings setting of the gpmi
controller for the mx28 architecture, also adding support for fast
edo mode timings. The whole series has been heavily tested with the
mtd kernel test modules, and with repeated write cycles on nand.

The whole series has been tested and reviewed by Sascha Hauer <s.hauer at pengutronix.de>,
so I removed the RFC prefix and re-submitted it as a regular patch
set by adding the 'Tested-by' and 'Review-by' tags to every single patch.

[1] https://lore.kernel.org/r/20210702065350.209646-5-ebiggers at kernel.org


Dario Binacchi (4):
  ARM: dts: imx28: reparent gpmi clock to ref_gpmi
  mtd: rawnand: gpmi: fix controller timings setting
  mtd: rawnand: gpmi: validate controller clock rate
  mtd: rawnand: gpmi: support fast edo timings for mx28

 arch/arm/boot/dts/imx28.dtsi               |  2 ++
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 27 ++++++++++++++++++----
 2 files changed, 24 insertions(+), 5 deletions(-)

-- 
2.32.0



From dario.binacchi at amarulasolutions.com  Tue Jan 18 01:54:31 2022
From: dario.binacchi at amarulasolutions.com (Dario Binacchi)
Date: Tue, 18 Jan 2022 10:54:31 +0100
Subject: [PATCH 1/4] ARM: dts: imx28: reparent gpmi clock to ref_gpmi
In-Reply-To: <20220118095434.35081-1-dario.binacchi@amarulasolutions.com>
References: <20220118095434.35081-1-dario.binacchi@amarulasolutions.com>
Message-ID: <20220118095434.35081-2-dario.binacchi@amarulasolutions.com>

Since ref_gpmi is sourced from pll0 (480MHz), It allows the GPMI
controller to manage High-Speed ??NAND Timing (edo mode 3,4 and 5).

Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>
Tested-by: Sascha Hauer <s.hauer at pengutronix.de>
Reviewed-by: Sascha Hauer <s.hauer at pengutronix.de>

---

 arch/arm/boot/dts/imx28.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 84d0176d5193..130b4145af82 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -110,6 +110,8 @@ gpmi: nand-controller at 8000c000 {
 				interrupt-names = "bch";
 				clocks = <&clks 50>;
 				clock-names = "gpmi_io";
+				assigned-clocks = <&clks 13>;
+				assigned-clock-parents = <&clks 10>;
 				dmas = <&dma_apbh 4>;
 				dma-names = "rx-tx";
 				status = "disabled";
-- 
2.32.0



From will at kernel.org  Tue Jan 18 02:07:02 2022
From: will at kernel.org (Will Deacon)
Date: Tue, 18 Jan 2022 10:07:02 +0000
Subject: [RFC PATCH 1/2] perf: arm_spe: Fix consistency of PMSCR register
 bit CX
In-Reply-To: <20220117124432.3119132-2-german.gomez@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-2-german.gomez@arm.com>
Message-ID: <20220118100702.GB16547@willie-the-truck>

On Mon, Jan 17, 2022 at 12:44:31PM +0000, German Gomez wrote:
> The arm_spe_pmu driver will enable the CX bit of the PMSCR register in
> order to add CONTEXT packets into the traces if the owner of the perf
> event runs with capabilities CAP_PERFMON or CAP_SYS_ADMIN.
> 
> The value of the bit is computed in the arm_spe_event_to_pmscr function
> [1], and the check for capabilities happens in [2] in the pmu init
> callback. This suggests that the value of the CX bit should remain
> consistent for the duration of the perf session.
> 
> However, the function arm_spe_event_to_pmscr may be called later during
> the start callback [3] when the "current" process is not the owner of
> the perf session, so the CX bit is currently not consistent. Consider
> the following example:
> 
>   1. Run a process in the background with capability CAP_SYS_ADMIN in CPU0.
> 
>     $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
>     [3] 3806
> 
>   2. Begin a perf session _without_ capabilities (we shouldn't see CONTEXT packets).
> 
>     $ perf record -e arm_spe_0// -C0 -- sleep 1
>     $ perf report -D | grep CONTEXT
>     .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>     .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>     .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>     [...]
> 
> As can be seen, the traces begin showing CONTEXT packets when the pid is
> 0xedf (3807).

So to be clear: we shouldn't be reporting these packets because 'perf'
doesn't have the right capabilities, but we evaluate that in the context of
'dd' (running as root) and so incorrectly grant the permission. Correct?

> This happens because the pmu start callback is run when
> the current process is not the owner of the perf session, so the CX
> register bit is set.

This doesn't really seem SPE-specific to me -- the perf_allow_*() helpers
also operate implicitly on the current task. How do other PMU drivers avoid
falling into this trap?

> One way to fix this is by caching the value of the CX bit during the
> initialization of the PMU event, so that it remains consistent for the
> duration of the session.

It doesn't feel right to stash this in 'struct arm_spe_pmu' during event
initialisation -- wouldn't that allow perf to continue creating new events
with CX set, even if the paranoid sysctl was changed dynamically? Instead,
I think it would be better if the capabilities were stash in the event
itself somehow at initialisation time.

Will


From jammy_huang at aspeedtech.com  Tue Jan 18 02:07:27 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 18:07:27 +0800
Subject: [PATCH v4 0/2] Fix incorrect resolution detected
Message-ID: <20220118100729.7651-1-jammy_huang@aspeedtech.com>

This series fixes incorrect resolution detected.
We found this problem happened occasionally in the switch between bios
and bootloader.

Changes in v4:
 - Correct the subject of patch

Changes in v3:
 - In v2, we tried to increase the min-required-count of stable signal
   to avoid incorrect transient state in timing detection. But it is
   not working for all conditions.
   Thus, we go another way in v3. Use regs, which can represent the
   signal status, to decide if we needs to do detection again.
 
Changes in v2:
 - Separate the patch into two patches

Jammy Huang (2):
  media: aspeed: Add macro for the fields of the mode-detect registers
  media: aspeed: Fix unstable timing detection

 drivers/media/platform/aspeed-video.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 18 02:07:29 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 18:07:29 +0800
Subject: [PATCH v4 2/2] media: aspeed: Fix unstable timing detection
In-Reply-To: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
References: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
Message-ID: <20220118100729.7651-3-jammy_huang@aspeedtech.com>

Using stable-signal in resolution detection, and try detection again
if unstable.

VE_MODE_DETECT_EXTSRC_ADC: 1 if video source is from ADC output.
VE_MODE_DETECT_H_STABLE: 1 if horizontal signal detection is stable.
VE_MODE_DETECT_V_STABLE: 1 if vertical signal detection is stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 5ba4d70c8dab..585ee2997d44 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -165,9 +165,14 @@
 
 #define VE_MODE_DETECT_STATUS		0x098
 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
+#define  VE_MODE_DETECT_EXTSRC_ADC	BIT(12)
+#define  VE_MODE_DETECT_H_STABLE	BIT(13)
+#define  VE_MODE_DETECT_V_STABLE	BIT(14)
 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
+#define  VE_MODE_DETECT_VSYNC_RDY	BIT(30)
+#define  VE_MODE_DETECT_HSYNC_RDY	BIT(31)
 
 #define VE_SYNC_STATUS			0x09c
 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
@@ -971,6 +976,13 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 			return;
 		}
 
+		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
+		// try detection again if current signal isn't stable
+		if (!(mds & VE_MODE_DETECT_H_STABLE) ||
+		    !(mds & VE_MODE_DETECT_V_STABLE) ||
+		    (mds & VE_MODE_DETECT_EXTSRC_ADC))
+			continue;
+
 		aspeed_video_check_and_set_polarity(video);
 
 		aspeed_video_enable_mode_detect(video);
-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 18 02:07:28 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 18:07:28 +0800
Subject: [PATCH v4 1/2] media: aspeed: Add macro for the fields of the
 mode-detect registers
In-Reply-To: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
References: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
Message-ID: <20220118100729.7651-2-jammy_huang@aspeedtech.com>

VE_MODE_DT_HOR_TOLER: the tolerance in detecting for stable horizontal
signal.
VE_MODE_DT_VER_TOLER: the tolerance in detecting for stable vertical
signal.
VE_MODE_DT_HOR_STABLE: the minimum required count in detecting stable
HSYNC signal to set mode detection horizontal signal stable.
VE_MODE_DT_VER_STABLE: the minimum required count in detecting stable
VSYNC signal to set mode detection vertical signal stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 4f5f5dd364ee..5ba4d70c8dab 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -190,6 +190,12 @@
 #define  VE_INTERRUPT_VSYNC_DESC	BIT(11)
 
 #define VE_MODE_DETECT			0x30c
+#define  VE_MODE_DT_HOR_TOLER		GENMASK(31, 28)
+#define  VE_MODE_DT_VER_TOLER		GENMASK(27, 24)
+#define  VE_MODE_DT_HOR_STABLE		GENMASK(23, 20)
+#define  VE_MODE_DT_VER_STABLE		GENMASK(19, 16)
+#define  VE_MODE_DT_EDG_THROD		GENMASK(15, 8)
+
 #define VE_MEM_RESTRICT_START		0x310
 #define VE_MEM_RESTRICT_END		0x314
 
@@ -1238,7 +1244,12 @@ static void aspeed_video_init_regs(struct aspeed_video *video)
 	aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
 
 	/* Set mode detection defaults */
-	aspeed_video_write(video, VE_MODE_DETECT, 0x22666500);
+	aspeed_video_write(video, VE_MODE_DETECT,
+			   FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
 
 	aspeed_video_write(video, VE_BCD_CTRL, 0);
 }
-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 18 00:44:49 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 16:44:49 +0800
Subject: [PATCH v3 2/2] video: aspeed: Fix unstable timing detection
In-Reply-To: <20220118084449.5182-1-jammy_huang@aspeedtech.com>
References: <20220118084449.5182-1-jammy_huang@aspeedtech.com>
Message-ID: <20220118084449.5182-3-jammy_huang@aspeedtech.com>

Using stable-signal in resolution detection, and try detection again
if unstable.

VE_MODE_DETECT_EXTSRC_ADC: 1 if video source is from ADC output.
VE_MODE_DETECT_H_STABLE: 1 if horizontal signal detection is stable.
VE_MODE_DETECT_V_STABLE: 1 if vertical signal detection is stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 5ba4d70c8dab..585ee2997d44 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -165,9 +165,14 @@
 
 #define VE_MODE_DETECT_STATUS		0x098
 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
+#define  VE_MODE_DETECT_EXTSRC_ADC	BIT(12)
+#define  VE_MODE_DETECT_H_STABLE	BIT(13)
+#define  VE_MODE_DETECT_V_STABLE	BIT(14)
 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
+#define  VE_MODE_DETECT_VSYNC_RDY	BIT(30)
+#define  VE_MODE_DETECT_HSYNC_RDY	BIT(31)
 
 #define VE_SYNC_STATUS			0x09c
 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
@@ -971,6 +976,13 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 			return;
 		}
 
+		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
+		// try detection again if current signal isn't stable
+		if (!(mds & VE_MODE_DETECT_H_STABLE) ||
+		    !(mds & VE_MODE_DETECT_V_STABLE) ||
+		    (mds & VE_MODE_DETECT_EXTSRC_ADC))
+			continue;
+
 		aspeed_video_check_and_set_polarity(video);
 
 		aspeed_video_enable_mode_detect(video);
-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 18 00:44:47 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 16:44:47 +0800
Subject: [PATCH v3 0/2] Fix incorrect resolution detected
Message-ID: <20220118084449.5182-1-jammy_huang@aspeedtech.com>

This series fixes incorrect resolution detected.
We found this problem happened occasionally in the switch between bios
and bootloader.

Changes in v3:
 - In v2, we tried to increase the min-required-count of stable signal
   to avoid incorrect transient state in timing detection. But it is
   not working for all conditions.
   Thus, we go another way in v3. Use regs, which can represent the
   signal status, to decide if we needs to do detection again.
 
Changes in v2:
 - Separate the patch into two patches

Jammy Huang (2):
  media: aspeed: Add macro for the fields of the mode-detect registers
  video: aspeed: Fix unstable timing detection

 drivers/media/platform/aspeed-video.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 18 00:44:48 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 18 Jan 2022 16:44:48 +0800
Subject: [PATCH v3 1/2] media: aspeed: Add macro for the fields of the
 mode-detect registers
In-Reply-To: <20220118084449.5182-1-jammy_huang@aspeedtech.com>
References: <20220118084449.5182-1-jammy_huang@aspeedtech.com>
Message-ID: <20220118084449.5182-2-jammy_huang@aspeedtech.com>

VE_MODE_DT_HOR_TOLER: the tolerance in detecting for stable horizontal
signal.
VE_MODE_DT_VER_TOLER: the tolerance in detecting for stable vertical
signal.
VE_MODE_DT_HOR_STABLE: the minimum required count in detecting stable
HSYNC signal to set mode detection horizontal signal stable.
VE_MODE_DT_VER_STABLE: the minimum required count in detecting stable
VSYNC signal to set mode detection vertical signal stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 4f5f5dd364ee..5ba4d70c8dab 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -190,6 +190,12 @@
 #define  VE_INTERRUPT_VSYNC_DESC	BIT(11)
 
 #define VE_MODE_DETECT			0x30c
+#define  VE_MODE_DT_HOR_TOLER		GENMASK(31, 28)
+#define  VE_MODE_DT_VER_TOLER		GENMASK(27, 24)
+#define  VE_MODE_DT_HOR_STABLE		GENMASK(23, 20)
+#define  VE_MODE_DT_VER_STABLE		GENMASK(19, 16)
+#define  VE_MODE_DT_EDG_THROD		GENMASK(15, 8)
+
 #define VE_MEM_RESTRICT_START		0x310
 #define VE_MEM_RESTRICT_END		0x314
 
@@ -1238,7 +1244,12 @@ static void aspeed_video_init_regs(struct aspeed_video *video)
 	aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
 
 	/* Set mode detection defaults */
-	aspeed_video_write(video, VE_MODE_DETECT, 0x22666500);
+	aspeed_video_write(video, VE_MODE_DETECT,
+			   FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
 
 	aspeed_video_write(video, VE_BCD_CTRL, 0);
 }
-- 
2.25.1



From victor.liu at nxp.com  Tue Jan 18 02:14:47 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Tue, 18 Jan 2022 18:14:47 +0800
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
 <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
Message-ID: <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>

Hi Andrzej,

Thanks for your review.

On Tue, 2022-01-18 at 10:24 +0100, Andrzej Hajda wrote:
> Hi,
> 
> On 18.01.2022 03:59, Liu Ying wrote:
> > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > mentions that it should be in UI.  However, the dphy core driver wrongly
> > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > is '8 UI', instead of 8.
> > 
> > So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> > member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> > value according to the D-PHY specification.
> > 
> > I'm assuming that all impacted custom drivers shall program values in
> > TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> > specification mentions that the frequency of TxByteClkHS is exactly 1/8
> > the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> > custom driver code is changed to program those values as
> > DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
> > 
> > Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> > Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> > as I don't have the hardwares.
> > 
> > Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> > Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > Cc: Robert Foss <robert.foss at linaro.org>
> > Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> > Cc: Jonas Karlman <jonas at kwiboo.se>
> > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > Cc: David Airlie <airlied at linux.ie>
> > Cc: Daniel Vetter <daniel at ffwll.ch>
> > Cc: Kishon Vijay Abraham I <kishon at ti.com>
> > Cc: Vinod Koul <vkoul at kernel.org>
> > Cc: Kevin Hilman <khilman at baylibre.com>
> > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > Cc: Heiko Stuebner <heiko at sntech.de>
> > Cc: Maxime Ripard <mripard at kernel.org>
> > Cc: Guido G?nther <agx at sigxcpu.org>
> > Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> > Signed-off-by: Liu Ying <victor.liu at nxp.com>
> > ---
> >   drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
> >   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
> >   drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
> >   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
> >   include/linux/phy/phy-mipi-dphy.h                | 4 +++-
> >   5 files changed, 11 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> > index a7389a0facfb..f1fdcdf763ee 100644
> > --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> > +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> > @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
> >   /*
> >    * ui2bc - UI time periods to byte clock cycles
> >    */
> > -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> > +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
> >   {
> > -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> > -
> > -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> > -				  dsi->mode.clock * 1000 * bpp);
> > +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
> 
> I have some doubts here. According to specs:
> 
>      UI - duration of any HS state on the Clock Lane,
> 
>      TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate
> 
> I'd like to emphasize "BIT RATE" above (not clock rate).
> 
> In such case I would expect that ui2bc would take into account number of 
> lanes:
> 
> byte clock cycles = div_round_up(ui * dsi->lanes, 8)
> 
> So in case of one lane we need 8 ticks to get byte, and in case of 4 
> lanes 2 ticks are enough.
> 
> Am I correct, or I've missed sth?

Sorry, I think you are wrong.

The spec also mentions that it is recommended that all transmitting
Data Lane Modules share one TxByteClkHS signal.  So, usually,
TxByteClkHS has nothing to do with data lane number, but only UI - one
bit period is HS state.  I think the NWL DSI follows the recommended
implementation.

'Table 20 HS Transmitter AC Specifications' in the spec notes
that Applicable when supporting maximum HS bit rates ? 1 Gbps (UI ? 1
ns).  This hints that HS bit rate is 1/UI. 

> 
> 
> >   }
> >   
> >   /*
> > diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > index cd2332bf0e31..8a818cdb7606 100644
> > --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > @@ -250,7 +250,8 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
> >   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
> >   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
> >   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> > -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> > +		     DIV_ROUND_UP(priv->config.clk_pre,
> > +				  MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD));
> >   
> >   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
> >   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> > diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> > index 288c9c67aa74..ccb4045685cd 100644
> > --- a/drivers/phy/phy-core-mipi-dphy.c
> > +++ b/drivers/phy/phy-core-mipi-dphy.c
> > @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
> >   
> >   	cfg->clk_miss = 0;
> >   	cfg->clk_post = 60000 + 52 * ui;
> > -	cfg->clk_pre = 8000;
> > +	cfg->clk_pre = 8;
> >   	cfg->clk_prepare = 38000;
> >   	cfg->clk_settle = 95000;
> >   	cfg->clk_term_en = 0;
> > @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
> >   	if (cfg->clk_post < (60000 + 52 * ui))
> >   		return -EINVAL;
> >   
> > -	if (cfg->clk_pre < 8000)
> > +	if (cfg->clk_pre < 8)
> >   		return -EINVAL;
> >   
> >   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> > diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > index 347dc79a18c1..67b0a17be7e3 100644
> > --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> > @@ -364,7 +364,8 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
> >   	 * The value of counter for HS Tclk-pre
> >   	 * Tclk-pre = Tpin_txbyteclkhs * value
> >   	 */
> > -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> > +	clk_pre = DIV_ROUND_UP(cfg->clk_pre,
> > +			       MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
> >   
> >   	/*
> >   	 * The value of counter for HS Tlpx Time
> > diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> > index a877ffee845d..ab1f736fbcd3 100644
> > --- a/include/linux/phy/phy-mipi-dphy.h
> > +++ b/include/linux/phy/phy-mipi-dphy.h
> > @@ -6,6 +6,8 @@
> >   #ifndef __PHY_MIPI_DPHY_H_
> >   #define __PHY_MIPI_DPHY_H_
> >   
> > +#define MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD	8
> 
> Do we need to define it? I guess it is just BITS_PER_BYTE.

Either way would do I think.  I'll wait for a while to see if others
have comment here.  If no, I may switch to use BITS_PER_BYTE in v2.

Regards,
Liu Ying

> 
> 
> Regards
> 
> Andrzej
> 
> 
> > +
> >   /**
> >    * struct phy_configure_opts_mipi_dphy - MIPI D-PHY configuration set
> >    *
> > @@ -42,7 +44,7 @@ struct phy_configure_opts_mipi_dphy {
> >   	 * the transmitter prior to any associated Data Lane beginning
> >   	 * the transition from LP to HS mode.
> >   	 *
> > -	 * Minimum value: 8 UI
> > +	 * Minimum value: 8
> >   	 */
> >   	unsigned int		clk_pre;
> >   



From abel.vesa at nxp.com  Tue Jan 18 02:16:32 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:16:32 +0200
Subject: [PATCH v8 3/7] dt-bindings: imx: Add clock binding for i.MXRT1050
In-Reply-To: <20220111215415.2075257-4-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-4-Mr.Bossman075@gmail.com>
Message-ID: <YeaTgJ/81SY0utye@abelvesa>

On 22-01-11 16:54:11, Jesse Taube wrote:
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> Add the clock binding doc for i.MXRT1050.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> [Giulio: added all clocks up to IMXRT1050_CLK_USBOH3]
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: added clocks from IMXRT1050_CLK_IPG_PDOF to
> IMXRT1050_CLK_DMA_MUX and moved IMXRT1050_CLK_END on]

Applied, thanks.

> ---
> V1->V2:
> * Nothing done
> V2->V3:
> * Added GPT binding
> V3->V4:
> * Change License to MIT or GPL-2
> V4->V5:
> * Nothing done
> V5->V6:
> * Nothing done
> V6->V7:
> * Fix typo in numbering
> * Remove GPT
> V7->V8:
> * Nothing done
> ---
>  include/dt-bindings/clock/imxrt1050-clock.h | 72 +++++++++++++++++++++
>  1 file changed, 72 insertions(+)
>  create mode 100644 include/dt-bindings/clock/imxrt1050-clock.h
> 
> diff --git a/include/dt-bindings/clock/imxrt1050-clock.h b/include/dt-bindings/clock/imxrt1050-clock.h
> new file mode 100644
> index 000000000000..93bef0832d16
> --- /dev/null
> +++ b/include/dt-bindings/clock/imxrt1050-clock.h
> @@ -0,0 +1,72 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> +/*
> + * Copyright(C) 2019
> + * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
> + */
> +
> +#ifndef __DT_BINDINGS_CLOCK_IMXRT1050_H
> +#define __DT_BINDINGS_CLOCK_IMXRT1050_H
> +
> +#define IMXRT1050_CLK_DUMMY			0
> +#define IMXRT1050_CLK_CKIL			1
> +#define IMXRT1050_CLK_CKIH			2
> +#define IMXRT1050_CLK_OSC			3
> +#define IMXRT1050_CLK_PLL2_PFD0_352M		4
> +#define IMXRT1050_CLK_PLL2_PFD1_594M		5
> +#define IMXRT1050_CLK_PLL2_PFD2_396M		6
> +#define IMXRT1050_CLK_PLL3_PFD0_720M		7
> +#define IMXRT1050_CLK_PLL3_PFD1_664_62M		8
> +#define IMXRT1050_CLK_PLL3_PFD2_508_24M		9
> +#define IMXRT1050_CLK_PLL3_PFD3_454_74M		10
> +#define IMXRT1050_CLK_PLL2_198M			11
> +#define IMXRT1050_CLK_PLL3_120M			12
> +#define IMXRT1050_CLK_PLL3_80M			13
> +#define IMXRT1050_CLK_PLL3_60M			14
> +#define IMXRT1050_CLK_PLL1_BYPASS		15
> +#define IMXRT1050_CLK_PLL2_BYPASS		16
> +#define IMXRT1050_CLK_PLL3_BYPASS		17
> +#define IMXRT1050_CLK_PLL5_BYPASS		19
> +#define IMXRT1050_CLK_PLL1_REF_SEL		20
> +#define IMXRT1050_CLK_PLL2_REF_SEL		21
> +#define IMXRT1050_CLK_PLL3_REF_SEL		22
> +#define IMXRT1050_CLK_PLL5_REF_SEL		23
> +#define IMXRT1050_CLK_PRE_PERIPH_SEL		24
> +#define IMXRT1050_CLK_PERIPH_SEL		25
> +#define IMXRT1050_CLK_SEMC_ALT_SEL		26
> +#define IMXRT1050_CLK_SEMC_SEL			27
> +#define IMXRT1050_CLK_USDHC1_SEL		28
> +#define IMXRT1050_CLK_USDHC2_SEL		29
> +#define IMXRT1050_CLK_LPUART_SEL		30
> +#define IMXRT1050_CLK_LCDIF_SEL			31
> +#define IMXRT1050_CLK_VIDEO_POST_DIV_SEL	32
> +#define IMXRT1050_CLK_VIDEO_DIV			33
> +#define IMXRT1050_CLK_ARM_PODF			34
> +#define IMXRT1050_CLK_LPUART_PODF		35
> +#define IMXRT1050_CLK_USDHC1_PODF		36
> +#define IMXRT1050_CLK_USDHC2_PODF		37
> +#define IMXRT1050_CLK_SEMC_PODF			38
> +#define IMXRT1050_CLK_AHB_PODF			39
> +#define IMXRT1050_CLK_LCDIF_PRED		40
> +#define IMXRT1050_CLK_LCDIF_PODF		41
> +#define IMXRT1050_CLK_USDHC1			42
> +#define IMXRT1050_CLK_USDHC2			43
> +#define IMXRT1050_CLK_LPUART1			44
> +#define IMXRT1050_CLK_SEMC			45
> +#define IMXRT1050_CLK_LCDIF_APB			46
> +#define IMXRT1050_CLK_PLL1_ARM			47
> +#define IMXRT1050_CLK_PLL2_SYS			48
> +#define IMXRT1050_CLK_PLL3_USB_OTG		49
> +#define IMXRT1050_CLK_PLL4_AUDIO		50
> +#define IMXRT1050_CLK_PLL5_VIDEO		51
> +#define IMXRT1050_CLK_PLL6_ENET			52
> +#define IMXRT1050_CLK_PLL7_USB_HOST		53
> +#define IMXRT1050_CLK_LCDIF_PIX			54
> +#define IMXRT1050_CLK_USBOH3			55
> +#define IMXRT1050_CLK_IPG_PDOF			56
> +#define IMXRT1050_CLK_PER_CLK_SEL		57
> +#define IMXRT1050_CLK_PER_PDOF			58
> +#define IMXRT1050_CLK_DMA			59
> +#define IMXRT1050_CLK_DMA_MUX			60
> +#define IMXRT1050_CLK_END			61
> +
> +#endif /* __DT_BINDINGS_CLOCK_IMXRT1050_H */
> -- 
> 2.34.1
>


From abel.vesa at nxp.com  Tue Jan 18 02:16:52 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:16:52 +0200
Subject: [PATCH v8 4/7] dt-bindings: clock: imx: Add documentation for
 i.MXRT1050 clock
In-Reply-To: <20220111215415.2075257-5-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-5-Mr.Bossman075@gmail.com>
Message-ID: <YeaTlE3RZfUIaLih@abelvesa>

On 22-01-11 16:54:12, Jesse Taube wrote:
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add DT binding documentation for i.MXRT1050 clock driver.
> 
> Cc: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>

Applied, thanks.

> ---
> V1->V2:
> * Replace macros with values
> V2->V3:
> * Remove anatop
> * Use lpuart not gpt
> * include imxrt1050-clock.h
> * 2 space tabs to 4
> * Remove oneOf enum
> * Change maxItems to 2
> V3->V4:
> * Nothing done
> V4->V5:
> * Remove extra newline
> * Rename ccm to clock-controller
> * Change minItems to const
> * Change minItems to description
> * Rename file to add 1050
> * Change commit description to just 1050
> V5->V6:
> * Add maxItems for clocks description
> V6->V7:
> * Nothing done
> V7->V8:
> * Nothing done
> ---
>  .../bindings/clock/imxrt1050-clock.yaml       | 67 +++++++++++++++++++
>  1 file changed, 67 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
> new file mode 100644
> index 000000000000..35fd08c143f4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/imxrt1050-clock.yaml
> @@ -0,0 +1,67 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/imxrt1050-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Clock bindings for Freescale i.MXRT
> +
> +maintainers:
> +  - Giulio Benetti <giulio.benetti at benettiengineering.com>
> +  - Jesse Taube <Mr.Bossman075 at gmail.com>
> +
> +description: |
> +  The clock consumer should specify the desired clock by having the clock
> +  ID in its "clocks" phandle cell. See include/dt-bindings/clock/imxrt*-clock.h
> +  for the full list of i.MXRT clock IDs.
> +
> +properties:
> +  compatible:
> +    const: fsl,imxrt1050-ccm
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 2
> +
> +  clocks:
> +    description: 24m osc
> +    maxItems: 1
> +
> +  clock-names:
> +    const: osc
> +
> +  '#clock-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - '#clock-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/imxrt1050-clock.h>
> +
> +    clks: clock-controller at 400fc000 {
> +        compatible = "fsl,imxrt1050-ccm";
> +        reg = <0x400fc000 0x4000>;
> +        interrupts = <95>, <96>;
> +        clocks = <&osc>;
> +        clock-names = "osc";
> +        #clock-cells = <1>;
> +    };
> +
> +    lpuart1: serial at 40184000 {
> +        compatible = "fsl,imxrt1050-lpuart";
> +        reg = <0x40184000 0x4000>;
> +        interrupts = <20>;
> +        clocks = <&clks IMXRT1050_CLK_LPUART1>;
> +        clock-names = "ipg";
> +    };
> -- 
> 2.34.1
>


From abel.vesa at nxp.com  Tue Jan 18 02:17:12 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:17:12 +0200
Subject: [PATCH v8 5/7] clk: imx: Add initial support for i.MXRT1050
 clock driver
In-Reply-To: <20220111215415.2075257-6-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-6-Mr.Bossman075@gmail.com>
Message-ID: <YeaTqBwGxSWzqZqT@abelvesa>

On 22-01-11 16:54:13, Jesse Taube wrote:
> Add clock driver support for i.MXRT1050.
> 
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> Suggested-by: Giulio Benetti <giulio.benetti at benettiengineering.com>

Applied, thanks.

> ---
> V1->V2:
> * Kconfig: Add new line
> * clk-imxrt.c: Remove unused const
> * clk-imxrt.c: Remove set parents
> * clk-imxrt.c: Use fsl,imxrt-anatop for anatop base address
> V2->V3:
> * Remove unused ANATOP_BASE_ADDR
> * Move to hw API
> * Add GPT's own clock
> * Add SEMC clocks to set muxing to CRITICAL
> V3->V4:
> * Rename clk-imxrt.c to clk-imxrt1050.c
> * Rename CONFIG_CLK_IMXRT to CONFIG_CLK_IMXRT1050
> * Make CONFIG_CLK_IMXRT1050 selectable
> V4->V5:
> * Move to platform driver
> V5->V6:
> * Remove "fsl" from platform driver name
> V6->V7:
> * Remove GPT
> * Remove of_match_ptr
> V7->V8:
> * Add help message
> * Change to config to tristate
> * Fix Makefile ordering
> * Remove unused inlcude
> * Remove imxrt_clocks_common_init
> ---
>  drivers/clk/imx/Kconfig         |   7 ++
>  drivers/clk/imx/Makefile        |   1 +
>  drivers/clk/imx/clk-imxrt1050.c | 168 ++++++++++++++++++++++++++++++++
>  3 files changed, 176 insertions(+)
>  create mode 100644 drivers/clk/imx/clk-imxrt1050.c
> 
> diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig
> index c08edbd04d22..45641b8bdc50 100644
> --- a/drivers/clk/imx/Kconfig
> +++ b/drivers/clk/imx/Kconfig
> @@ -105,3 +105,10 @@ config CLK_IMX8ULP
>  	select MXC_CLK
>  	help
>  	    Build the driver for i.MX8ULP CCM Clock Driver
> +
> +config CLK_IMXRT1050
> +	tristate "IMXRT1050 CCM Clock Driver"
> +	depends on SOC_IMXRT
> +	select MXC_CLK
> +	help
> +	    Build the driver for i.MXRT1050 CCM Clock Driver
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index b5e040026dfb..1e13c5cb37d9 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -46,4 +46,5 @@ obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o
>  obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
>  obj-$(CONFIG_CLK_IMX7D)  += clk-imx7d.o
>  obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
> +obj-$(CONFIG_CLK_IMXRT1050)  += clk-imxrt1050.o
>  obj-$(CONFIG_CLK_VF610)  += clk-vf610.o
> diff --git a/drivers/clk/imx/clk-imxrt1050.c b/drivers/clk/imx/clk-imxrt1050.c
> new file mode 100644
> index 000000000000..9539d35588ee
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imxrt1050.c
> @@ -0,0 +1,168 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
> +/*
> + * Copyright (C) 2021
> + * Author(s):
> + * Jesse Taube <Mr.Bossman075 at gmail.com>
> + * Giulio Benetti <giulio.benetti at benettiengineering.com>
> + */
> +#include <linux/clk.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/imxrt1050-clock.h>
> +
> +#include "clk.h"
> +
> +static const char * const pll_ref_sels[] = {"osc", "dummy", };
> +static const char * const per_sels[] = {"ipg_pdof", "osc", };
> +static const char * const pll1_bypass_sels[] = {"pll1_arm", "pll1_arm_ref_sel", };
> +static const char * const pll2_bypass_sels[] = {"pll2_sys", "pll2_sys_ref_sel", };
> +static const char * const pll3_bypass_sels[] = {"pll3_usb_otg", "pll3_usb_otg_ref_sel", };
> +static const char * const pll5_bypass_sels[] = {"pll5_video", "pll5_video_ref_sel", };
> +static const char *const pre_periph_sels[] = {
> +	"pll2_sys", "pll2_pfd2_396m", "pll2_pfd0_352m", "arm_podf", };
> +static const char *const periph_sels[] = { "pre_periph_sel", "todo", };
> +static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
> +static const char *const lpuart_sels[] = { "pll3_80m", "osc", };
> +static const char *const lcdif_sels[] = {
> +	"pll2_sys", "pll3_pfd3_454_74m", "pll5_video", "pll2_pfd0_352m",
> +	"pll2_pfd1_594m", "pll3_pfd1_664_62m", };
> +static const char *const semc_alt_sels[] = { "pll2_pfd2_396m", "pll3_pfd1_664_62m", };
> +static const char *const semc_sels[] = { "periph_sel", "semc_alt_sel", };
> +
> +static struct clk_hw **hws;
> +static struct clk_hw_onecell_data *clk_hw_data;
> +
> +static int imxrt1050_clocks_probe(struct platform_device *pdev)
> +{
> +	void __iomem *ccm_base;
> +	void __iomem *pll_base;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct device_node *anp;
> +	int ret;
> +
> +	clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
> +					  IMXRT1050_CLK_END), GFP_KERNEL);
> +	if (WARN_ON(!clk_hw_data))
> +		return -ENOMEM;
> +
> +	clk_hw_data->num = IMXRT1050_CLK_END;
> +	hws = clk_hw_data->hws;
> +
> +	hws[IMXRT1050_CLK_OSC] = imx_obtain_fixed_clk_hw(np, "osc");
> +
> +	anp = of_find_compatible_node(NULL, NULL, "fsl,imxrt-anatop");
> +	pll_base = of_iomap(anp, 0);
> +	of_node_put(anp);
> +	if (WARN_ON(!pll_base))
> +		return -ENOMEM;
> +
> +	/* Anatop clocks */
> +	hws[IMXRT1050_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0UL);
> +
> +	hws[IMXRT1050_CLK_PLL1_REF_SEL] = imx_clk_hw_mux("pll1_arm_ref_sel",
> +		pll_base + 0x0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +	hws[IMXRT1050_CLK_PLL2_REF_SEL] = imx_clk_hw_mux("pll2_sys_ref_sel",
> +		pll_base + 0x30, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +	hws[IMXRT1050_CLK_PLL3_REF_SEL] = imx_clk_hw_mux("pll3_usb_otg_ref_sel",
> +		pll_base + 0x10, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +	hws[IMXRT1050_CLK_PLL5_REF_SEL] = imx_clk_hw_mux("pll5_video_ref_sel",
> +		pll_base + 0xa0, 14, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
> +
> +	hws[IMXRT1050_CLK_PLL1_ARM] = imx_clk_hw_pllv3(IMX_PLLV3_SYS, "pll1_arm",
> +		"pll1_arm_ref_sel", pll_base + 0x0, 0x7f);
> +	hws[IMXRT1050_CLK_PLL2_SYS] = imx_clk_hw_pllv3(IMX_PLLV3_GENERIC, "pll2_sys",
> +		"pll2_sys_ref_sel", pll_base + 0x30, 0x1);
> +	hws[IMXRT1050_CLK_PLL3_USB_OTG] = imx_clk_hw_pllv3(IMX_PLLV3_USB, "pll3_usb_otg",
> +		"pll3_usb_otg_ref_sel", pll_base + 0x10, 0x1);
> +	hws[IMXRT1050_CLK_PLL5_VIDEO] = imx_clk_hw_pllv3(IMX_PLLV3_AV, "pll5_video",
> +		"pll5_video_ref_sel", pll_base + 0xa0, 0x7f);
> +
> +	/* PLL bypass out */
> +	hws[IMXRT1050_CLK_PLL1_BYPASS] = imx_clk_hw_mux_flags("pll1_bypass", pll_base + 0x0, 16, 1,
> +		pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT);
> +	hws[IMXRT1050_CLK_PLL2_BYPASS] = imx_clk_hw_mux_flags("pll2_bypass", pll_base + 0x30, 16, 1,
> +		pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT);
> +	hws[IMXRT1050_CLK_PLL3_BYPASS] = imx_clk_hw_mux_flags("pll3_bypass", pll_base + 0x10, 16, 1,
> +		pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT);
> +	hws[IMXRT1050_CLK_PLL5_BYPASS] = imx_clk_hw_mux_flags("pll5_bypass", pll_base + 0xa0, 16, 1,
> +		pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT);
> +
> +	hws[IMXRT1050_CLK_VIDEO_POST_DIV_SEL] = imx_clk_hw_divider("video_post_div_sel",
> +		"pll5_video", pll_base + 0xa0, 19, 2);
> +	hws[IMXRT1050_CLK_VIDEO_DIV] = imx_clk_hw_divider("video_div",
> +		"video_post_div_sel", pll_base + 0x170, 30, 2);
> +
> +	hws[IMXRT1050_CLK_PLL3_80M] = imx_clk_hw_fixed_factor("pll3_80m",  "pll3_usb_otg", 1, 6);
> +
> +	hws[IMXRT1050_CLK_PLL2_PFD0_352M] = imx_clk_hw_pfd("pll2_pfd0_352m", "pll2_sys", pll_base + 0x100, 0);
> +	hws[IMXRT1050_CLK_PLL2_PFD1_594M] = imx_clk_hw_pfd("pll2_pfd1_594m", "pll2_sys", pll_base + 0x100, 1);
> +	hws[IMXRT1050_CLK_PLL2_PFD2_396M] = imx_clk_hw_pfd("pll2_pfd2_396m", "pll2_sys", pll_base + 0x100, 2);
> +	hws[IMXRT1050_CLK_PLL3_PFD1_664_62M] = imx_clk_hw_pfd("pll3_pfd1_664_62m", "pll3_usb_otg", pll_base + 0xf0, 1);
> +	hws[IMXRT1050_CLK_PLL3_PFD3_454_74M] = imx_clk_hw_pfd("pll3_pfd3_454_74m", "pll3_usb_otg", pll_base + 0xf0, 3);
> +
> +	/* CCM clocks */
> +	ccm_base = devm_platform_ioremap_resource(pdev, 0);
> +	if (WARN_ON(IS_ERR(ccm_base)))
> +		return PTR_ERR(ccm_base);
> +
> +	hws[IMXRT1050_CLK_ARM_PODF] = imx_clk_hw_divider("arm_podf", "pll1_arm", ccm_base + 0x10, 0, 3);
> +	hws[IMXRT1050_CLK_PRE_PERIPH_SEL] = imx_clk_hw_mux("pre_periph_sel", ccm_base + 0x18, 18, 2,
> +		pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
> +	hws[IMXRT1050_CLK_PERIPH_SEL] = imx_clk_hw_mux("periph_sel", ccm_base + 0x14, 25, 1,
> +		periph_sels, ARRAY_SIZE(periph_sels));
> +	hws[IMXRT1050_CLK_USDHC1_SEL] = imx_clk_hw_mux("usdhc1_sel", ccm_base + 0x1c, 16, 1,
> +		usdhc_sels, ARRAY_SIZE(usdhc_sels));
> +	hws[IMXRT1050_CLK_USDHC2_SEL] = imx_clk_hw_mux("usdhc2_sel", ccm_base + 0x1c, 17, 1,
> +		usdhc_sels, ARRAY_SIZE(usdhc_sels));
> +	hws[IMXRT1050_CLK_LPUART_SEL] = imx_clk_hw_mux("lpuart_sel", ccm_base + 0x24, 6, 1,
> +		lpuart_sels, ARRAY_SIZE(lpuart_sels));
> +	hws[IMXRT1050_CLK_LCDIF_SEL] = imx_clk_hw_mux("lcdif_sel", ccm_base + 0x38, 15, 3,
> +		lcdif_sels, ARRAY_SIZE(lcdif_sels));
> +	hws[IMXRT1050_CLK_PER_CLK_SEL] = imx_clk_hw_mux("per_sel", ccm_base + 0x1C, 6, 1,
> +		per_sels, ARRAY_SIZE(per_sels));
> +	hws[IMXRT1050_CLK_SEMC_ALT_SEL] = imx_clk_hw_mux("semc_alt_sel", ccm_base + 0x14, 7, 1,
> +		semc_alt_sels, ARRAY_SIZE(semc_alt_sels));
> +	hws[IMXRT1050_CLK_SEMC_SEL] = imx_clk_hw_mux_flags("semc_sel", ccm_base + 0x14, 6, 1,
> +		semc_sels, ARRAY_SIZE(semc_sels), CLK_IS_CRITICAL);
> +
> +	hws[IMXRT1050_CLK_AHB_PODF] = imx_clk_hw_divider("ahb", "periph_sel", ccm_base + 0x14, 10, 3);
> +	hws[IMXRT1050_CLK_IPG_PDOF] = imx_clk_hw_divider("ipg", "ahb", ccm_base + 0x14, 8, 2);
> +	hws[IMXRT1050_CLK_PER_PDOF] = imx_clk_hw_divider("per", "per_sel", ccm_base + 0x1C, 0, 5);
> +
> +	hws[IMXRT1050_CLK_USDHC1_PODF] = imx_clk_hw_divider("usdhc1_podf", "usdhc1_sel", ccm_base + 0x24, 11, 3);
> +	hws[IMXRT1050_CLK_USDHC2_PODF] = imx_clk_hw_divider("usdhc2_podf", "usdhc2_sel", ccm_base + 0x24, 16, 3);
> +	hws[IMXRT1050_CLK_LPUART_PODF] = imx_clk_hw_divider("lpuart_podf", "lpuart_sel", ccm_base + 0x24, 0, 6);
> +	hws[IMXRT1050_CLK_LCDIF_PRED] = imx_clk_hw_divider("lcdif_pred", "lcdif_sel", ccm_base + 0x38, 12, 3);
> +	hws[IMXRT1050_CLK_LCDIF_PODF] = imx_clk_hw_divider("lcdif_podf", "lcdif_pred", ccm_base + 0x18, 23, 3);
> +
> +	hws[IMXRT1050_CLK_USDHC1] = imx_clk_hw_gate2("usdhc1", "usdhc1_podf", ccm_base + 0x80, 2);
> +	hws[IMXRT1050_CLK_USDHC2] = imx_clk_hw_gate2("usdhc2", "usdhc2_podf", ccm_base + 0x80, 4);
> +	hws[IMXRT1050_CLK_LPUART1] = imx_clk_hw_gate2("lpuart1", "lpuart_podf", ccm_base + 0x7c, 24);
> +	hws[IMXRT1050_CLK_LCDIF_APB] = imx_clk_hw_gate2("lcdif", "lcdif_podf", ccm_base + 0x74, 10);
> +	hws[IMXRT1050_CLK_DMA] = imx_clk_hw_gate("dma", "ipg", ccm_base + 0x7C, 6);
> +	hws[IMXRT1050_CLK_DMA_MUX] = imx_clk_hw_gate("dmamux0", "ipg", ccm_base + 0x7C, 7);
> +	imx_check_clk_hws(hws, IMXRT1050_CLK_END);
> +
> +	ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
> +	if (ret < 0) {
> +		dev_err(dev, "Failed to register clks for i.MXRT1050.\n");
> +		imx_unregister_hw_clocks(hws, IMXRT1050_CLK_END);
> +	}
> +	return ret;
> +}
> +static const struct of_device_id imxrt1050_clk_of_match[] = {
> +	{ .compatible = "fsl,imxrt1050-ccm" },
> +	{ /* Sentinel */ }
> +};
> +MODULE_DEVICE_TABLE(of, imxrt1050_clk_of_match);
> +
> +static struct platform_driver imxrt1050_clk_driver = {
> +	.probe = imxrt1050_clocks_probe,
> +	.driver = {
> +		.name = "imxrt1050-ccm",
> +		.of_match_table = imxrt1050_clk_of_match,
> +	},
> +};
> +module_platform_driver(imxrt1050_clk_driver);
> -- 
> 2.34.1
>


From abel.vesa at nxp.com  Tue Jan 18 02:18:18 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:18:18 +0200
Subject: [PATCH] clk: imx: Add imx8dxl clk driver
In-Reply-To: <20211216185024.7DE53C36AE2@smtp.kernel.org>
References: <1636567000-24145-1-git-send-email-abel.vesa@nxp.com>
 <20211216185024.7DE53C36AE2@smtp.kernel.org>
Message-ID: <YeaT6pGCo2wUGEFf@abelvesa>

On 21-12-16 10:50:23, Stephen Boyd wrote:
> Quoting Abel Vesa (2021-11-10 09:56:40)
> > diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
> > index c53a688d8ccc..7f4893706cc2 100644
> > --- a/drivers/clk/imx/clk-imx8qxp.c
> > +++ b/drivers/clk/imx/clk-imx8qxp.c
> > @@ -297,6 +297,7 @@ static const struct of_device_id imx8qxp_match[] = {
> >         { .compatible = "fsl,scu-clk", },
> >         { .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, },
> >         { .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
> > +       { .compatible = "fsl,imx8dxl-clk", &imx_clk_scu_rsrc_imx8dxl, },
> 
> Can you keep this sorted on compatible string? Then we don't have to
> worry about conflicts as much.
> 

Yep. Will resend.

> >         { /* sentinel */ }
> >  };
> >


From john.garry at huawei.com  Tue Jan 18 02:20:37 2022
From: john.garry at huawei.com (John Garry)
Date: Tue, 18 Jan 2022 10:20:37 +0000
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <20220118091827.GA98966@leoy-ThinkPad-X240s>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
 <20220118091827.GA98966@leoy-ThinkPad-X240s>
Message-ID: <46d27f58-7732-3359-e0aa-090468a1cb22@huawei.com>

Hi Leo,

>> test child forked, pid 45193
> Both Arm and Arm64 platforms cannot support signal handler with
> breakpoint, please see the details in [1].  

Thanks for the info.

>So I think we need
> something like below:
> 

ok

> static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
> {
>          ...
> 
>          if (!BP_SIGNAL_IS_SUPPORTED) {
>                  pr_debug("Test not supported on this architecture");
>                  return TEST_SKIP;
>          }
> 
>          ...
> }
> 
> Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
> here.


Do you know any other architectures which would have this issue? Or a 
generic way to check for support?

It's better to not have to add to this list arch-by-arch..

> 
> [1]https://lore.kernel.org/lkml/157169993406.29376.12473771029179755767.tip-bot2 at tip-bot2/
> 
>> And fails on my x86 broadwell machine:
>>
>> john at localhost:~/kernel-dev2/tools/perf> sudo ./perf test -v 73
>> 73: Sigtrap                                                         :
>> --- start ---
>> test child forked, pid 22255
>> FAILED sys_perf_event_open(): Argument list too long
>> test child finished with -1
>> ---- end ----
>> Sigtrap: FAILED!
>> john at localhost:~/kernel-dev2/tools/perf>
> It is a bit suprise for the failure on x86, as I remembered x86 platform
> can support signal handler with hw breakpoint.  And from the error
> "Argument list too long", it should be a different issue from other
> archs.

Yeah, I don't know what's going on here.

Thanks,
John


From abel.vesa at nxp.com  Tue Jan 18 02:23:43 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:23:43 +0200
Subject: [PATCH] clk: imx: Add imx8dxl clk driver
In-Reply-To: <YeaT6pGCo2wUGEFf@abelvesa>
References: <1636567000-24145-1-git-send-email-abel.vesa@nxp.com>
 <20211216185024.7DE53C36AE2@smtp.kernel.org>
 <YeaT6pGCo2wUGEFf@abelvesa>
Message-ID: <YeaVL33SMFHc8pZ3@abelvesa>

On 22-01-18 12:18:18, Abel Vesa wrote:
> On 21-12-16 10:50:23, Stephen Boyd wrote:
> > Quoting Abel Vesa (2021-11-10 09:56:40)
> > > diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
> > > index c53a688d8ccc..7f4893706cc2 100644
> > > --- a/drivers/clk/imx/clk-imx8qxp.c
> > > +++ b/drivers/clk/imx/clk-imx8qxp.c
> > > @@ -297,6 +297,7 @@ static const struct of_device_id imx8qxp_match[] = {
> > >         { .compatible = "fsl,scu-clk", },
> > >         { .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, },
> > >         { .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
> > > +       { .compatible = "fsl,imx8dxl-clk", &imx_clk_scu_rsrc_imx8dxl, },
> > 
> > Can you keep this sorted on compatible string? Then we don't have to
> > worry about conflicts as much.
> > 
> 
> Yep. Will resend.

Actually, v2 is right here:

https://lore.kernel.org/linux-arm-kernel/1639747533-9778-1-git-send-email-abel.vesa at nxp.com/

You ACK'ed it already. And it adds the dxl compatible in the right spot.

> 
> > >         { /* sentinel */ }
> > >  };
> > >


From kevin at bracey.fi  Tue Jan 18 02:23:50 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Tue, 18 Jan 2022 12:23:50 +0200
Subject: [PATCH v3 3/4] lib/crc32test.c: correct printed bytes count
In-Reply-To: <20220118102351.3356105-1-kevin@bracey.fi>
References: <20220118102351.3356105-1-kevin@bracey.fi>
Message-ID: <20220118102351.3356105-4-kevin@bracey.fi>

crc32c_le self test had a stray multiply by two inherited from
the crc32_le+crc32_be test loop.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/crc32test.c b/lib/crc32test.c
index 61ddce2cff77..9b4af79412c4 100644
--- a/lib/crc32test.c
+++ b/lib/crc32test.c
@@ -675,7 +675,7 @@ static int __init crc32c_test(void)
 
 	/* pre-warm the cache */
 	for (i = 0; i < 100; i++) {
-		bytes += 2*test[i].length;
+		bytes += test[i].length;
 
 		crc ^= __crc32c_le(test[i].crc, test_buf +
 		    test[i].start, test[i].length);
-- 
2.25.1



From kevin at bracey.fi  Tue Jan 18 02:23:47 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Tue, 18 Jan 2022 12:23:47 +0200
Subject: [PATCH v3 0/4] arm64: accelerate crc32_be
Message-ID: <20220118102351.3356105-1-kevin@bracey.fi>

Originally sent only to the arm-linux list - now including linux-crypto.
Ard suggested that Herbert take the series.

This series completes the arm64 crc32 helper acceleration by adding crc32_be.

There are plenty of users, for example OF.

To compensate for the extra supporting cruft in lib/crc32.c, a couple of minor
tidies.

changes since v2:
- no code change, but sent to Herbert+crypto with Catalin's ack for arm64

changes since v1:
- assembler style fixes from Ard's review

Kevin Bracey (4):
  lib/crc32.c: remove unneeded casts
  lib/crc32.c: Make crc32_be weak for arch override
  lib/crc32test.c: correct printed bytes count
  arm64: accelerate crc32_be

 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 lib/crc32.c            | 14 +++----
 lib/crc32test.c        |  2 +-
 3 files changed, 80 insertions(+), 23 deletions(-)

-- 
2.25.1



From kevin at bracey.fi  Tue Jan 18 02:23:48 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Tue, 18 Jan 2022 12:23:48 +0200
Subject: [PATCH v3 1/4] lib/crc32.c: remove unneeded casts
In-Reply-To: <20220118102351.3356105-1-kevin@bracey.fi>
References: <20220118102351.3356105-1-kevin@bracey.fi>
Message-ID: <20220118102351.3356105-2-kevin@bracey.fi>

Casts were added in commit 8f243af42ade ("sections: fix const sections
for crc32 table") to cope with the tables not being const. They are no
longer required since commit f5e38b9284e1 ("lib: crc32: constify crc32
lookup table").

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 2a68dfd3b96c..7f062a2639df 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -194,13 +194,11 @@ u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure __weak crc32_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_le, CRC32_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32table_le, CRC32_POLY_LE);
 }
 u32 __pure __weak __crc32c_le(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_le_generic(crc, p, len,
-			(const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
+	return crc32_le_generic(crc, p, len, crc32ctable_le, CRC32C_POLY_LE);
 }
 #endif
 EXPORT_SYMBOL(crc32_le);
@@ -339,8 +337,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 #else
 u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
-	return crc32_be_generic(crc, p, len,
-			(const u32 (*)[256])crc32table_be, CRC32_POLY_BE);
+	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
 #endif
 EXPORT_SYMBOL(crc32_be);
-- 
2.25.1



From kevin at bracey.fi  Tue Jan 18 02:23:51 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Tue, 18 Jan 2022 12:23:51 +0200
Subject: [PATCH v3 4/4] arm64: accelerate crc32_be
In-Reply-To: <20220118102351.3356105-1-kevin@bracey.fi>
References: <20220118102351.3356105-1-kevin@bracey.fi>
Message-ID: <20220118102351.3356105-5-kevin@bracey.fi>

It makes no sense to leave crc32_be using the generic code while we
only accelerate the little-endian ops.

Even though the big-endian form doesn't fit as smoothly into the arm64,
we can speed it up and avoid hitting the D cache.

Tested on Cortex-A53. Without acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 192240 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21360 nsec

With acceleration:

    crc32: CRC_LE_BITS = 64, CRC_BE BITS = 64
    crc32: self tests passed, processed 225944 bytes in 53480 nsec
    crc32c: CRC_LE_BITS = 64
    crc32c: self tests passed, processed 112972 bytes in 21480 nsec

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
Tested-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 73 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/lib/crc32.S b/arch/arm64/lib/crc32.S
index 0f9e10ecda23..8340dccff46f 100644
--- a/arch/arm64/lib/crc32.S
+++ b/arch/arm64/lib/crc32.S
@@ -11,7 +11,44 @@
 
 	.arch		armv8-a+crc
 
-	.macro		__crc32, c
+	.macro		byteorder, reg, be
+	.if		\be
+CPU_LE( rev		\reg, \reg	)
+	.else
+CPU_BE( rev		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		byteorder16, reg, be
+	.if		\be
+CPU_LE( rev16		\reg, \reg	)
+	.else
+CPU_BE( rev16		\reg, \reg	)
+	.endif
+	.endm
+
+	.macro		bitorder, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	.endif
+	.endm
+
+	.macro		bitorder16, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #16
+	.endif
+	.endm
+
+	.macro		bitorder8, reg, be
+	.if		\be
+	rbit		\reg, \reg
+	lsr		\reg, \reg, #24
+	.endif
+	.endm
+
+	.macro		__crc32, c, be=0
+	bitorder	w0, \be
 	cmp		x2, #16
 	b.lt		8f			// less than 16 bytes
 
@@ -24,10 +61,14 @@
 	add		x8, x8, x1
 	add		x1, x1, x7
 	ldp		x5, x6, [x8]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 
 	tst		x7, #8
 	crc32\c\()x	w8, w0, x3
@@ -55,33 +96,43 @@ CPU_BE(	rev		x6, x6		)
 32:	ldp		x3, x4, [x1], #32
 	sub		x2, x2, #32
 	ldp		x5, x6, [x1, #-16]
-CPU_BE(	rev		x3, x3		)
-CPU_BE(	rev		x4, x4		)
-CPU_BE(	rev		x5, x5		)
-CPU_BE(	rev		x6, x6		)
+	byteorder	x3, \be
+	byteorder	x4, \be
+	byteorder	x5, \be
+	byteorder	x6, \be
+	bitorder	x3, \be
+	bitorder	x4, \be
+	bitorder	x5, \be
+	bitorder	x6, \be
 	crc32\c\()x	w0, w0, x3
 	crc32\c\()x	w0, w0, x4
 	crc32\c\()x	w0, w0, x5
 	crc32\c\()x	w0, w0, x6
 	cbnz		x2, 32b
-0:	ret
+0:	bitorder	w0, \be
+	ret
 
 8:	tbz		x2, #3, 4f
 	ldr		x3, [x1], #8
-CPU_BE(	rev		x3, x3		)
+	byteorder	x3, \be
+	bitorder	x3, \be
 	crc32\c\()x	w0, w0, x3
 4:	tbz		x2, #2, 2f
 	ldr		w3, [x1], #4
-CPU_BE(	rev		w3, w3		)
+	byteorder	w3, \be
+	bitorder	w3, \be
 	crc32\c\()w	w0, w0, w3
 2:	tbz		x2, #1, 1f
 	ldrh		w3, [x1], #2
-CPU_BE(	rev16		w3, w3		)
+	byteorder16	w3, \be
+	bitorder16	w3, \be
 	crc32\c\()h	w0, w0, w3
 1:	tbz		x2, #0, 0f
 	ldrb		w3, [x1]
+	bitorder8	w3, \be
 	crc32\c\()b	w0, w0, w3
-0:	ret
+0:	bitorder	w0, \be
+	ret
 	.endm
 
 	.align		5
@@ -99,3 +150,11 @@ alternative_if_not ARM64_HAS_CRC32
 alternative_else_nop_endif
 	__crc32		c
 SYM_FUNC_END(__crc32c_le)
+
+	.align		5
+SYM_FUNC_START(crc32_be)
+alternative_if_not ARM64_HAS_CRC32
+	b		crc32_be_base
+alternative_else_nop_endif
+	__crc32		be=1
+SYM_FUNC_END(crc32_be)
-- 
2.25.1



From kevin at bracey.fi  Tue Jan 18 02:23:49 2022
From: kevin at bracey.fi (Kevin Bracey)
Date: Tue, 18 Jan 2022 12:23:49 +0200
Subject: [PATCH v3 2/4] lib/crc32.c: Make crc32_be weak for arch override
In-Reply-To: <20220118102351.3356105-1-kevin@bracey.fi>
References: <20220118102351.3356105-1-kevin@bracey.fi>
Message-ID: <20220118102351.3356105-3-kevin@bracey.fi>

crc32_le and __crc32c_le can be overridden - extend this to crc32_be.

Signed-off-by: Kevin Bracey <kevin at bracey.fi>
---
 lib/crc32.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/crc32.c b/lib/crc32.c
index 7f062a2639df..5649847d0a8d 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -206,6 +206,7 @@ EXPORT_SYMBOL(__crc32c_le);
 
 u32 __pure crc32_le_base(u32, unsigned char const *, size_t) __alias(crc32_le);
 u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le);
+u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be);
 
 /*
  * This multiplies the polynomials x and y modulo the given modulus.
@@ -330,12 +331,12 @@ static inline u32 __pure crc32_be_generic(u32 crc, unsigned char const *p,
 }
 
 #if CRC_BE_BITS == 1
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, NULL, CRC32_POLY_BE);
 }
 #else
-u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len)
+u32 __pure __weak crc32_be(u32 crc, unsigned char const *p, size_t len)
 {
 	return crc32_be_generic(crc, p, len, crc32table_be, CRC32_POLY_BE);
 }
-- 
2.25.1



From abel.vesa at nxp.com  Tue Jan 18 02:26:55 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 12:26:55 +0200
Subject: [PATCH v2] clk: imx: Add imx8dxl clk driver
In-Reply-To: <1639747533-9778-1-git-send-email-abel.vesa@nxp.com>
References: <1639747533-9778-1-git-send-email-abel.vesa@nxp.com>
Message-ID: <YeaV7+nx2pDWlfiO@abelvesa>

On 21-12-17 15:25:33, Abel Vesa wrote:
> From: Jacky Bai <ping.bai at nxp.com>
> 
> Add files for imx8dxl clk driver which is based on imx8qxp clock driver.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>

Applied.

> ---
> 
> Changes since v1:
>  * Moved the dxl compatible and rsrc table to be sorted alphabetically.
> 
>  drivers/clk/imx/Makefile           |  3 +-
>  drivers/clk/imx/clk-imx8dxl-rsrc.c | 66 ++++++++++++++++++++++++++++++
>  drivers/clk/imx/clk-imx8qxp.c      |  1 +
>  drivers/clk/imx/clk-scu.h          |  1 +
>  4 files changed, 70 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/clk/imx/clk-imx8dxl-rsrc.c
> 
> diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> index b5e040026dfb..f8a44c4ca94a 100644
> --- a/drivers/clk/imx/Makefile
> +++ b/drivers/clk/imx/Makefile
> @@ -28,7 +28,8 @@ obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
>  
>  obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
>  clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o \
> -				     clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o
> +				     clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o \
> +				     clk-imx8dxl-rsrc.o
>  clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
>  
>  obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o
> diff --git a/drivers/clk/imx/clk-imx8dxl-rsrc.c b/drivers/clk/imx/clk-imx8dxl-rsrc.c
> new file mode 100644
> index 000000000000..69b7aa34fff5
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imx8dxl-rsrc.c
> @@ -0,0 +1,66 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2019~2020 NXP
> + */
> +
> +#include <dt-bindings/firmware/imx/rsrc.h>
> +
> +#include "clk-scu.h"
> +
> +/* Keep sorted in the ascending order */
> +static u32 imx8dxl_clk_scu_rsrc_table[] = {
> +	IMX_SC_R_SPI_0,
> +	IMX_SC_R_SPI_1,
> +	IMX_SC_R_SPI_2,
> +	IMX_SC_R_SPI_3,
> +	IMX_SC_R_UART_0,
> +	IMX_SC_R_UART_1,
> +	IMX_SC_R_UART_2,
> +	IMX_SC_R_UART_3,
> +	IMX_SC_R_I2C_0,
> +	IMX_SC_R_I2C_1,
> +	IMX_SC_R_I2C_2,
> +	IMX_SC_R_I2C_3,
> +	IMX_SC_R_ADC_0,
> +	IMX_SC_R_FTM_0,
> +	IMX_SC_R_FTM_1,
> +	IMX_SC_R_CAN_0,
> +	IMX_SC_R_LCD_0,
> +	IMX_SC_R_LCD_0_PWM_0,
> +	IMX_SC_R_PWM_0,
> +	IMX_SC_R_PWM_1,
> +	IMX_SC_R_PWM_2,
> +	IMX_SC_R_PWM_3,
> +	IMX_SC_R_PWM_4,
> +	IMX_SC_R_PWM_5,
> +	IMX_SC_R_PWM_6,
> +	IMX_SC_R_PWM_7,
> +	IMX_SC_R_GPT_0,
> +	IMX_SC_R_GPT_1,
> +	IMX_SC_R_GPT_2,
> +	IMX_SC_R_GPT_3,
> +	IMX_SC_R_GPT_4,
> +	IMX_SC_R_FSPI_0,
> +	IMX_SC_R_FSPI_1,
> +	IMX_SC_R_SDHC_0,
> +	IMX_SC_R_SDHC_1,
> +	IMX_SC_R_SDHC_2,
> +	IMX_SC_R_ENET_0,
> +	IMX_SC_R_ENET_1,
> +	IMX_SC_R_MLB_0,
> +	IMX_SC_R_USB_1,
> +	IMX_SC_R_NAND,
> +	IMX_SC_R_M4_0_I2C,
> +	IMX_SC_R_M4_0_UART,
> +	IMX_SC_R_ELCDIF_PLL,
> +	IMX_SC_R_AUDIO_PLL_0,
> +	IMX_SC_R_AUDIO_PLL_1,
> +	IMX_SC_R_AUDIO_CLK_0,
> +	IMX_SC_R_AUDIO_CLK_1,
> +	IMX_SC_R_A35
> +};
> +
> +const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl = {
> +	.rsrc = imx8dxl_clk_scu_rsrc_table,
> +	.num = ARRAY_SIZE(imx8dxl_clk_scu_rsrc_table),
> +};
> diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c
> index 40a2efb1329b..546a3703bfeb 100644
> --- a/drivers/clk/imx/clk-imx8qxp.c
> +++ b/drivers/clk/imx/clk-imx8qxp.c
> @@ -295,6 +295,7 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
>  
>  static const struct of_device_id imx8qxp_match[] = {
>  	{ .compatible = "fsl,scu-clk", },
> +	{ .compatible = "fsl,imx8dxl-clk", &imx_clk_scu_rsrc_imx8dxl, },
>  	{ .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, },
>  	{ .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
>  	{ /* sentinel */ }
> diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h
> index 22156e93b85d..af7b697f51ca 100644
> --- a/drivers/clk/imx/clk-scu.h
> +++ b/drivers/clk/imx/clk-scu.h
> @@ -21,6 +21,7 @@ struct imx_clk_scu_rsrc_table {
>  
>  extern struct list_head imx_scu_clks[];
>  extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops;
> +extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl;
>  extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp;
>  extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
>  
> -- 
> 2.31.1
>


From ardb at kernel.org  Tue Jan 18 02:27:56 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 11:27:56 +0100
Subject: [PATCH] ARM: Thumb2: align ALT_UP() sections sufficiently
Message-ID: <20220118102756.1259149-1-ardb@kernel.org>

When building for Thumb2, the .alt.smp.init sections that are emitted by
the ALT_UP() patching code may not be 32-bit aligned, even though the
fixup_smp_on_up() routine expects that. This results in alignment faults
at module load time, which need to be fixed up by the fault handler.

So let's align those sections explicitly, and avoid this from occurring.

Cc: <stable at vger.kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/assembler.h | 2 ++
 arch/arm/include/asm/processor.h | 1 +
 2 files changed, 3 insertions(+)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 5a530e25ea1a..51ae4674ca49 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -261,6 +261,7 @@ THUMB(	fpreg	.req	r7	)
  */
 #define ALT_UP(instr...)					\
 	.pushsection ".alt.smp.init", "a"			;\
+	.align	2						;\
 	.long	9998b - .					;\
 9997:	instr							;\
 	.if . - 9997b == 2					;\
@@ -272,6 +273,7 @@ THUMB(	fpreg	.req	r7	)
 	.popsection
 #define ALT_UP_B(label)					\
 	.pushsection ".alt.smp.init", "a"			;\
+	.align	2						;\
 	.long	9998b - .					;\
 	W(b)	. + (label - 9998b)					;\
 	.popsection
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 6af68edfa53a..bdc35c0e8dfb 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -96,6 +96,7 @@ unsigned long __get_wchan(struct task_struct *p);
 #define __ALT_SMP_ASM(smp, up)						\
 	"9998:	" smp "\n"						\
 	"	.pushsection \".alt.smp.init\", \"a\"\n"		\
+	"	.align	2\n"						\
 	"	.long	9998b - .\n"					\
 	"	" up "\n"						\
 	"	.popsection\n"
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 18 02:34:29 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 18 Jan 2022 10:34:29 +0000
Subject: [bootwrapper PATCH] aarch64: Enable BRBE for the non-secure world
In-Reply-To: <b76978f3-4a34-c196-956a-ee95c7f663d2@arm.com>
References: <1642066868-23151-1-git-send-email-anshuman.khandual@arm.com>
 <Yd/9x5t/4BMjZX3t@FVFF77S0Q05N>
 <b1ffe762-43e6-b624-2b08-0aaa7ca5f70b@arm.com>
 <20220117132541.GD87485@C02TD0UTHF1T.local>
 <b76978f3-4a34-c196-956a-ee95c7f663d2@arm.com>
Message-ID: <20220118103429.GA16043@C02TD0UTHF1T.local>

On Tue, Jan 18, 2022 at 08:12:39AM +0530, Anshuman Khandual wrote:
> On 1/17/22 6:55 PM, Mark Rutland wrote:
> > On Mon, Jan 17, 2022 at 04:06:44PM +0530, Anshuman Khandual wrote:
> >> On 1/13/22 3:54 PM, Mark Rutland wrote:
> >>> On Thu, Jan 13, 2022 at 03:11:08PM +0530, Anshuman Khandual wrote:
> >>>> +1:	mrs     x1, id_aa64dfr0_el1
> >>>> +	ubfx    x1, x1, #52, #4
> >>>> +	cbz     x1, 1f
> >>>> +
> >>>> +	// Enable BRBE for the non-secure world.
> >>>> +	ldr     x1, =(0x3 << 32)
> >>>> +	orr     x0, x0, x1
> >>>> +
> >>>
> >>> I assume this is the `SBRBE` field, which naming-wise sounds like it controls
> >>> Secure rather than Non-Secure (e,g. by way of comparison to `NSPB`). Is that
> >>
> >> Right, that is some what counter-intuitive.
> >>
> >>> correct? What effect does the value 0x3 have?
> >>
> >> As per the definition above.
> >>
> >> 0b11	 This control does not cause any direct accesses to BRBE registers or
> >>          instruction to be trapped, and does not cause any Exception levels to
> >> 	 be a prohibited region.
> >>
> >> This basically allows BRBE usage in EL2/EL1.
> > 
> > Thanks for this!
> > 
> > Just to check, my understanding, there's nothing else that we need to
> > initialize to ensure that BRBE won't start recording unexpectedly
> > out-of-reset, becuase in BRBCR_EL* the E*BRE bits all warm-reset to 0
> > and hence prevent recording in any of EL0/EL1/EL2 (and BRBE never
> > records at EL3). Is that right?
> 
> Right, that is my understanding as well. Those required bits that start
> BRBE recording, always warm-reset to 0.

Thanks for confirming!

I've applied this and pushed it out.

Mark.


From andrzej.hajda at intel.com  Tue Jan 18 02:44:20 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Tue, 18 Jan 2022 11:44:20 +0100
Subject: [PATCH] phy: dphy: Correct clk_pre parameter
In-Reply-To: <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>
References: <20220118025918.1444288-1-victor.liu@nxp.com>
 <96cd66cd-8e90-5f68-6009-f48015400aae@intel.com>
 <1d945988f774732c204f9dabdb8fa5795f0eca24.camel@nxp.com>
Message-ID: <51eda14f-5c37-c3af-84de-b591b8762a63@intel.com>


On 18.01.2022 11:14, Liu Ying wrote:
> Hi Andrzej,
>
> Thanks for your review.
>
> On Tue, 2022-01-18 at 10:24 +0100, Andrzej Hajda wrote:
>> Hi,
>>
>> On 18.01.2022 03:59, Liu Ying wrote:
>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>> is '8 UI', instead of 8.
>>>
>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>> value according to the D-PHY specification.
>>>
>>> I'm assuming that all impacted custom drivers shall program values in
>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>> custom driver code is changed to program those values as
>>> DIV_ROUND_UP(cfg->clk_pre, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD), then.
>>>
>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>> as I don't have the hardwares.
>>>
>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>> Cc: Robert Foss <robert.foss at linaro.org>
>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>> Cc: David Airlie <airlied at linux.ie>
>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>> Cc: Vinod Koul <vkoul at kernel.org>
>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>> Cc: Maxime Ripard <mripard at kernel.org>
>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>> ---
>>>    drivers/gpu/drm/bridge/nwl-dsi.c                 | 7 ++-----
>>>    drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    | 3 ++-
>>>    drivers/phy/phy-core-mipi-dphy.c                 | 4 ++--
>>>    drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c | 3 ++-
>>>    include/linux/phy/phy-mipi-dphy.h                | 4 +++-
>>>    5 files changed, 11 insertions(+), 10 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
>>> index a7389a0facfb..f1fdcdf763ee 100644
>>> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
>>> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
>>> @@ -196,12 +196,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>>>    /*
>>>     * ui2bc - UI time periods to byte clock cycles
>>>     */
>>> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
>>> +static u32 ui2bc(struct nwl_dsi *dsi, unsigned int ui)
>>>    {
>>> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
>>> -
>>> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
>>> -				  dsi->mode.clock * 1000 * bpp);
>>> +	return DIV_ROUND_UP(ui, MIPI_DPHY_UI_PER_TXBYTECLKHS_PERIOD);
>> I have some doubts here. According to specs:
>>
>>       UI - duration of any HS state on the Clock Lane,
>>
>>       TxByteClkHS - exactly 1/8 the High-Speed(HS) bit rate
>>
>> I'd like to emphasize "BIT RATE" above (not clock rate).
>>
>> In such case I would expect that ui2bc would take into account number of
>> lanes:
>>
>> byte clock cycles = div_round_up(ui * dsi->lanes, 8)
>>
>> So in case of one lane we need 8 ticks to get byte, and in case of 4
>> lanes 2 ticks are enough.
>>
>> Am I correct, or I've missed sth?
> Sorry, I think you are wrong.
>
> The spec also mentions that it is recommended that all transmitting
> Data Lane Modules share one TxByteClkHS signal.  So, usually,
> TxByteClkHS has nothing to do with data lane number, but only UI - one
> bit period is HS state.  I think the NWL DSI follows the recommended
> implementation.
>
> 'Table 20 HS Transmitter AC Specifications' in the spec notes
> that Applicable when supporting maximum HS bit rates ? 1 Gbps (UI ? 1
> ns).  This hints that HS bit rate is 1/UI.


OK, apparently "bit rate" in case of PHYs usually means "bit rate per lane".


Regards

Andrzej




From szabolcs.nagy at arm.com  Tue Jan 18 03:02:55 2022
From: szabolcs.nagy at arm.com (Szabolcs Nagy)
Date: Tue, 18 Jan 2022 11:02:55 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YeWtRk0H30q38eM8@arm.com>
References: <YbD4LKiaxG2R0XxN@arm.com> <20211209111048.GM3294453@arm.com>
 <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com> <YeWtRk0H30q38eM8@arm.com>
Message-ID: <20220118110255.GC3294453@arm.com>

The 01/17/2022 17:54, Catalin Marinas wrote:
> On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
> > I think we can look at this from two angles:
> > 
> > 1. Ignoring MDWE, should whoever does the original mmap() also honour
> >    PROT_BTI? We do this for static binaries but, for consistency, should
> >    we extend it to dynamic executable?
> > 
> > 2. A 'simple' fix to allow MDWE together with BTI.
> 
> Thinking about it, (1) is not that different from the kernel setting
> PROT_EXEC on the main executable when the dynamic loader could've done
> it as well. There is a case for making this more consistent: whoever
> does the mmap() should use the full attributes.
> 

Yeah that was my original idea that it should be consistent.
One caveat is that protection flags are normally specified
in the program header, but the BTI marking is in
PT_GNU_PROPERTY which is harder to get to, so glibc does not
try to get it right for the initial mapping either: it has
to re-mmap or mprotect. (In principle we could use read
syscalls to parse the ELF headers and notes before mmap,
but that's more complicated with additional failure modes.)

i.e. if (2) is fixed then mprotect can be used for library
mapping too which is simpler than re-mmap.

> Question for the toolchain people: would the compiler ever generate
> relocations in the main executable that the linker needs to resolve via
> an mprotect(READ|WRITE) followed by mprotect(READ|EXEC)? If yes, we'd
> better go for a proper MDWE implementation in the kernel.

There is some support for text relocations in glibc, but it's not
expected to be common (e.g. it is a bug if a distro binary has it).

For static PIE we made -z text ldflag the default so text relocs
are rejected (i think glibc cannot self-relocate those, so ld.so
cannot have them either), but otherwise certain text relocs work
(static relocations are not supported).

$ cat a.c
int x = 42;
__attribute__((section(".text")))
int *y = &x;
int main(){ return *y; }
$ gcc a.c
/tmp/ccOrpMPD.s: Assembler messages:
/tmp/ccOrpMPD.s:12: Warning: ignoring changed section attributes for .text
$ readelf -aW ./a.out |grep TEXTREL
 0x0000000000000016 (TEXTREL)            0x0
 0x000000000000001e (FLAGS)              TEXTREL BIND_NOW
$ strace -e mprotect ./a.out
mprotect(0xffff839ee000, 65536, PROT_NONE) = 0
mprotect(0xffff839fe000, 12288, PROT_READ) = 0
mprotect(0xaaaac2096000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC) = 0
mprotect(0xaaaac2096000, 4096, PROT_READ|PROT_EXEC) = 0
mprotect(0xaaaac20a6000, 4096, PROT_READ) = 0
mprotect(0xffff83a55000, 4096, PROT_READ) = 0
+++ exited with 42 +++


From leo.yan at linaro.org  Tue Jan 18 03:18:49 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 18 Jan 2022 19:18:49 +0800
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <46d27f58-7732-3359-e0aa-090468a1cb22@huawei.com>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
 <20220118091827.GA98966@leoy-ThinkPad-X240s>
 <46d27f58-7732-3359-e0aa-090468a1cb22@huawei.com>
Message-ID: <20220118111849.GB98966@leoy-ThinkPad-X240s>

Hi John,

On Tue, Jan 18, 2022 at 10:20:37AM +0000, John Garry wrote:

[...]

> > static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
> > {
> >          ...
> > 
> >          if (!BP_SIGNAL_IS_SUPPORTED) {
> >                  pr_debug("Test not supported on this architecture");
> >                  return TEST_SKIP;
> >          }
> > 
> >          ...
> > }
> > 
> > Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
> > here.
> 
> 
> Do you know any other architectures which would have this issue? Or a
> generic way to check for support?
> 
> It's better to not have to add to this list arch-by-arch..

Yeah, it's ugly to add archs one by one.  But I don't find an ABI can
be used to make decision if an arch supports signal handler for
breakpoint.  Usually, it's architecture specific operations for signal
handling, see the code [1]; simply to say, architecture needs to disable
single step when call signal handler and restore single step after
return from signal handler.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/kernel/signal.c#n830

> > > And fails on my x86 broadwell machine:
> > > 
> > > john at localhost:~/kernel-dev2/tools/perf> sudo ./perf test -v 73
> > > 73: Sigtrap                                                         :
> > > --- start ---
> > > test child forked, pid 22255
> > > FAILED sys_perf_event_open(): Argument list too long
> > > test child finished with -1
> > > ---- end ----
> > > Sigtrap: FAILED!
> > > john at localhost:~/kernel-dev2/tools/perf>
> > It is a bit suprise for the failure on x86, as I remembered x86 platform
> > can support signal handler with hw breakpoint.  And from the error
> > "Argument list too long", it should be a different issue from other
> > archs.
> 
> Yeah, I don't know what's going on here.

Seems to there have incompatible issue.
Maybe you could cleanup with "make clean" and then rebuild perf.

Thanks,
Leo


From linux at armlinux.org.uk  Tue Jan 18 03:21:20 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 11:21:20 +0000
Subject: [PATCH] ARM: Thumb2: align ALT_UP() sections sufficiently
In-Reply-To: <20220118102756.1259149-1-ardb@kernel.org>
References: <20220118102756.1259149-1-ardb@kernel.org>
Message-ID: <YeaisFN1ru7suF1Y@shell.armlinux.org.uk>

On Tue, Jan 18, 2022 at 11:27:56AM +0100, Ard Biesheuvel wrote:
> When building for Thumb2, the .alt.smp.init sections that are emitted by
> the ALT_UP() patching code may not be 32-bit aligned, even though the
> fixup_smp_on_up() routine expects that. This results in alignment faults
> at module load time, which need to be fixed up by the fault handler.
> 
> So let's align those sections explicitly, and avoid this from occurring.

Are you seeing a problem that this patch fixes?

This really should not matter. .alt.smp.init contents are always a whole
number of 32-bit words. These are gathered by the linker into the
.init.smpalt section, so the contents should always be a whole number
of 32-bit words.

This follows the .init.tagtable section, which is also a 32-bit word
aligned structure built by the linker... which follows the
.init.arch.info section and .init.proc.info sections which all have
32-bit alignment requirements.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From szabolcs.nagy at arm.com  Tue Jan 18 03:22:11 2022
From: szabolcs.nagy at arm.com (Szabolcs Nagy)
Date: Tue, 18 Jan 2022 11:22:11 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <CAMe9rOo5zWO1BwZGhqGdWuCjsq86YUo4ptqXkFVNSwXbU+ZS-Q@mail.gmail.com>
References: <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com> <YeWtRk0H30q38eM8@arm.com>
 <20ae043b-a013-068d-2d83-16e63f5b4989@linaro.org>
 <CAMe9rOo5zWO1BwZGhqGdWuCjsq86YUo4ptqXkFVNSwXbU+ZS-Q@mail.gmail.com>
Message-ID: <20220118112211.GD3294453@arm.com>

The 01/17/2022 11:01, H.J. Lu via Libc-alpha wrote:
> We are taking a different approach for CET enabling.   CET will be
> changed to be enabled from user space:
> 
> https://gitlab.com/x86-glibc/glibc/-/tree/users/hjl/cet/enable
> 
> and the CET kernel no longer enables CET automatically:
> 
> https://github.com/hjl-tools/linux/tree/hjl/cet%2F5.16.0-v4

we considered userspace handling of BTI in static exe
and ld.so too. at the time we wanted the protection to
be on whenever BTI marked code is executed, so it has
to be enabled at program entry.

i no longer think that the entry code protection is very
important, but delaying mprotect for static exe does
not fix our mprotect(*|PROT_EXEC) problem with systemd.

i also don't immediately see where you deal with shadow
stack allocation for the main stack if it is userspace
enabled, i expected that to require kernel assistance
if you want the main stack protected all the way up.


From gankulkarni at os.amperecomputing.com  Tue Jan 18 03:24:04 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 18 Jan 2022 16:54:04 +0530
Subject: [PATCH v5 38/69] KVM: arm64: nv: Support multiple nested Stage-2
 mmu structures
In-Reply-To: <20211129200150.351436-39-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-39-maz@kernel.org>
Message-ID: <21b0fca8-6b31-dc63-7637-2f80c4b3a272@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> Add Stage-2 mmu data structures for virtual EL2 and for nested guests.
> We don't yet populate shadow Stage-2 page tables, but we now have a
> framework for getting to a shadow Stage-2 pgd.
> 
> We allocate twice the number of vcpus as Stage-2 mmu structures because
> that's sufficient for each vcpu running two translation regimes without
> having to flush the Stage-2 page tables.
> 
> Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_host.h   |  29 +++++
>   arch/arm64/include/asm/kvm_mmu.h    |   9 ++
>   arch/arm64/include/asm/kvm_nested.h |   7 +
>   arch/arm64/kvm/arm.c                |  16 ++-
>   arch/arm64/kvm/mmu.c                |  29 +++--
>   arch/arm64/kvm/nested.c             | 195 ++++++++++++++++++++++++++++
>   6 files changed, 275 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 6a7b13edc5cb..00c3366129b8 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -102,14 +102,43 @@ struct kvm_s2_mmu {
>   	int __percpu *last_vcpu_ran;
>   
>   	struct kvm_arch *arch;
> +
> +	/*
> +	 * For a shadow stage-2 MMU, the virtual vttbr programmed by the guest
> +	 * hypervisor.  Unused for kvm_arch->mmu. Set to 1 when the structure
> +	 * contains no valid information.
> +	 */
> +	u64	vttbr;
> +
> +	/* true when this represents a nested context where virtual HCR_EL2.VM == 1 */
> +	bool	nested_stage2_enabled;
> +
> +	/*
> +	 *  0: Nobody is currently using this, check vttbr for validity
> +	 * >0: Somebody is actively using this.
> +	 */
> +	atomic_t refcnt;
>   };
>   
> +static inline bool kvm_s2_mmu_valid(struct kvm_s2_mmu *mmu)
> +{
> +	return !(mmu->vttbr & 1);
> +}
> +
>   struct kvm_arch_memory_slot {
>   };
>   
>   struct kvm_arch {
>   	struct kvm_s2_mmu mmu;
>   
> +	/*
> +	 * Stage 2 paging stage for VMs with nested virtual using a virtual
> +	 * VMID.
> +	 */
> +	struct kvm_s2_mmu *nested_mmus;
> +	size_t nested_mmus_size;
> +	int nested_mmus_next;
> +
>   	/* VTCR_EL2 value for this VM */
>   	u64    vtcr;
>   
> diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> index c018c7b40761..7250594e3d68 100644
> --- a/arch/arm64/include/asm/kvm_mmu.h
> +++ b/arch/arm64/include/asm/kvm_mmu.h
> @@ -116,6 +116,7 @@ alternative_cb_end
>   #include <asm/cacheflush.h>
>   #include <asm/mmu_context.h>
>   #include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
>   
>   void kvm_update_va_mask(struct alt_instr *alt,
>   			__le32 *origptr, __le32 *updptr, int nr_inst);
> @@ -159,6 +160,7 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
>   			     void **haddr);
>   void free_hyp_pgds(void);
>   
> +void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size);
>   void stage2_unmap_vm(struct kvm *kvm);
>   int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu);
>   void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
> @@ -294,5 +296,12 @@ static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
>   {
>   	return container_of(mmu->arch, struct kvm, arch);
>   }
> +
> +static inline u64 get_vmid(u64 vttbr)
> +{
> +	return (vttbr & VTTBR_VMID_MASK(kvm_get_vmid_bits())) >>
> +		VTTBR_VMID_SHIFT;
> +}
> +
>   #endif /* __ASSEMBLY__ */
>   #endif /* __ARM64_KVM_MMU_H__ */
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 026ddaad972c..473ecd1d60d0 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -61,6 +61,13 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
>   		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));
>   }
>   
> +extern void kvm_init_nested(struct kvm *kvm);
> +extern int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu);
> +extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
> +extern struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr);
> +extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
> +extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
> +
>   int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
>   extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
>   			    u64 control_bit);
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 68da54d58cd0..1dbf63319b99 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -37,6 +37,7 @@
>   #include <asm/kvm_arm.h>
>   #include <asm/kvm_asm.h>
>   #include <asm/kvm_mmu.h>
> +#include <asm/kvm_nested.h>
>   #include <asm/kvm_emulate.h>
>   #include <asm/sections.h>
>   
> @@ -146,6 +147,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>   	if (ret)
>   		return ret;
>   
> +	kvm_init_nested(kvm);
> +
>   	ret = create_hyp_mappings(kvm, kvm + 1, PAGE_HYP);
>   	if (ret)
>   		goto out_free_stage2_pgd;
> @@ -389,6 +392,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
>   	struct kvm_s2_mmu *mmu;
>   	int *last_ran;
>   
> +	if (nested_virt_in_use(vcpu))
> +		kvm_vcpu_load_hw_mmu(vcpu);
> +
>   	mmu = vcpu->arch.hw_mmu;
>   	last_ran = this_cpu_ptr(mmu->last_vcpu_ran);
>   
> @@ -437,6 +443,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
>   	kvm_vgic_put(vcpu);
>   	kvm_vcpu_pmu_restore_host(vcpu);
>   
> +	if (nested_virt_in_use(vcpu))
> +		kvm_vcpu_put_hw_mmu(vcpu);
> +
>   	vcpu->cpu = -1;
>   }
>   
> @@ -1088,8 +1097,13 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
>   
>   	vcpu->arch.target = phys_target;
>   
> +	/* Prepare for nested if required */
> +	ret = kvm_vcpu_init_nested(vcpu);
> +
>   	/* Now we know what it is, we can reset it. */
> -	ret = kvm_reset_vcpu(vcpu);
> +	if (!ret)
> +		ret = kvm_reset_vcpu(vcpu);
> +
>   	if (ret) {
>   		vcpu->arch.target = -1;
>   		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 9eec548fccd1..ab1653b8e601 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -162,7 +162,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
>    * does.
>    */
>   /**
> - * unmap_stage2_range -- Clear stage2 page table entries to unmap a range
> + * __unmap_stage2_range -- Clear stage2 page table entries to unmap a range
>    * @mmu:   The KVM stage-2 MMU pointer
>    * @start: The intermediate physical base address of the range to unmap
>    * @size:  The size of the area to unmap
> @@ -185,7 +185,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
>   				   may_block));
>   }
>   
> -static void unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
> +void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
>   {
>   	__unmap_stage2_range(mmu, start, size, true);
>   }
> @@ -507,7 +507,20 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
>   	int cpu, err;
>   	struct kvm_pgtable *pgt;
>   
> +	/*
> +	 * If we already have our page tables in place, and that the
> +	 * MMU context is the canonical one, we have a bug somewhere,
> +	 * as this is only supposed to ever happen once per VM.
> +	 *
> +	 * Otherwise, we're building nested page tables, and that's
> +	 * probably because userspace called KVM_ARM_VCPU_INIT more
> +	 * than once on the same vcpu. Since that's actually legal,
> +	 * don't kick a fuss and leave gracefully.
> +	 */
>   	if (mmu->pgt != NULL) {
> +		if (&kvm->arch.mmu != mmu)
> +			return 0;
> +
>   		kvm_err("kvm_arch already initialized?\n");
>   		return -EINVAL;
>   	}
> @@ -533,6 +546,9 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
>   	mmu->pgt = pgt;
>   	mmu->pgd_phys = __pa(pgt->pgd);
>   	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
> +
> +	kvm_init_nested_s2_mmu(mmu);
> +
>   	return 0;
>   
>   out_destroy_pgtable:
> @@ -578,7 +594,7 @@ static void stage2_unmap_memslot(struct kvm *kvm,
>   
>   		if (!(vma->vm_flags & VM_PFNMAP)) {
>   			gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
> -			unmap_stage2_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
> +			kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
>   		}
>   		hva = vm_end;
>   	} while (hva < reg_end);
> @@ -1556,11 +1572,6 @@ void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen)
>   {
>   }
>   
> -void kvm_arch_flush_shadow_all(struct kvm *kvm)
> -{
> -	kvm_free_stage2_pgd(&kvm->arch.mmu);
> -}
> -
>   void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
>   				   struct kvm_memory_slot *slot)
>   {
> @@ -1568,7 +1579,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
>   	phys_addr_t size = slot->npages << PAGE_SHIFT;
>   
>   	spin_lock(&kvm->mmu_lock);
> -	unmap_stage2_range(&kvm->arch.mmu, gpa, size);
> +	kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, size);
>   	spin_unlock(&kvm->mmu_lock);
>   }
>   
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 19b674983e13..b034a2343374 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -19,12 +19,189 @@
>   #include <linux/kvm.h>
>   #include <linux/kvm_host.h>
>   
> +#include <asm/kvm_arm.h>
>   #include <asm/kvm_emulate.h>
> +#include <asm/kvm_mmu.h>
>   #include <asm/kvm_nested.h>
>   #include <asm/sysreg.h>
>   
>   #include "sys_regs.h"
>   
> +void kvm_init_nested(struct kvm *kvm)
> +{
> +	kvm->arch.nested_mmus = NULL;
> +	kvm->arch.nested_mmus_size = 0;
> +}
> +
> +int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	struct kvm_s2_mmu *tmp;
> +	int num_mmus;
> +	int ret = -ENOMEM;
> +
> +	if (!test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features))
> +		return 0;
> +
> +	if (!cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
> +		return -EINVAL;
> +
> +	mutex_lock(&kvm->lock);
> +
> +	/*
> +	 * Let's treat memory allocation failures as benign: If we fail to
> +	 * allocate anything, return an error and keep the allocated array
> +	 * alive. Userspace may try to recover by intializing the vcpu
> +	 * again, and there is no reason to affect the whole VM for this.
> +	 */
> +	num_mmus = atomic_read(&kvm->online_vcpus) * 2;
> +	tmp = krealloc(kvm->arch.nested_mmus,
> +		       num_mmus * sizeof(*kvm->arch.nested_mmus),
> +		       GFP_KERNEL_ACCOUNT | __GFP_ZERO);
> +	if (tmp) {
> +		/*
> +		 * If we went through a realocation, adjust the MMU
> +		 * back-pointers in the previously initialised
> +		 * pg_table structures.
> +		 */
> +		if (kvm->arch.nested_mmus != tmp) {
> +			int i;
> +
> +			for (i = 0; i < num_mmus - 2; i++)
> +				tmp[i].pgt->mmu = &tmp[i];
> +		}
> +
> +		if (kvm_init_stage2_mmu(kvm, &tmp[num_mmus - 1]) ||
> +		    kvm_init_stage2_mmu(kvm, &tmp[num_mmus - 2])) {
> +			kvm_free_stage2_pgd(&tmp[num_mmus - 1]);
> +			kvm_free_stage2_pgd(&tmp[num_mmus - 2]);
> +		} else {
> +			kvm->arch.nested_mmus_size = num_mmus;
> +			ret = 0;
> +		}
> +
> +		kvm->arch.nested_mmus = tmp;
> +	}
> +
> +	mutex_unlock(&kvm->lock);
> +	return ret;
> +}
> +
> +/* Must be called with kvm->lock held */
> +struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
> +{
> +	bool nested_stage2_enabled = hcr & HCR_VM;
> +	int i;
> +
> +	/* Don't consider the CnP bit for the vttbr match */
> +	vttbr = vttbr & ~VTTBR_CNP_BIT;
> +
> +	/*
> +	 * Two possibilities when looking up a S2 MMU context:
> +	 *
> +	 * - either S2 is enabled in the guest, and we need a context that
> +         *   is S2-enabled and matches the full VTTBR (VMID+BADDR), which
> +         *   makes it safe from a TLB conflict perspective (a broken guest
> +         *   won't be able to generate them),
> +	 *
> +	 * - or S2 is disabled, and we need a context that is S2-disabled
> +         *   and matches the VMID only, as all TLBs are tagged by VMID even
> +         *   if S2 translation is enabled.

I think you were intended to say "if S2 translation is disabled".
> +	 */
> +	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
> +		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
> +
> +		if (!kvm_s2_mmu_valid(mmu))
> +			continue;
> +
> +		if (nested_stage2_enabled &&
> +		    mmu->nested_stage2_enabled &&
> +		    vttbr == mmu->vttbr)
> +			return mmu;
> +
> +		if (!nested_stage2_enabled &&
> +		    !mmu->nested_stage2_enabled &&
> +		    get_vmid(vttbr) == get_vmid(mmu->vttbr))
> +			return mmu;
> +	}
> +	return NULL;
> +}
> +
> +static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
> +	u64 hcr= vcpu_read_sys_reg(vcpu, HCR_EL2);
> +	struct kvm_s2_mmu *s2_mmu;
> +	int i;
> +
> +	s2_mmu = lookup_s2_mmu(kvm, vttbr, hcr);
> +	if (s2_mmu)
> +		goto out;
> +
> +	/*
> +	 * Make sure we don't always search from the same point, or we
> +	 * will always reuse a potentially active context, leaving
> +	 * free contexts unused.
> +	 */
> +	for (i = kvm->arch.nested_mmus_next;
> +	     i < (kvm->arch.nested_mmus_size + kvm->arch.nested_mmus_next);
> +	     i++) {
> +		s2_mmu = &kvm->arch.nested_mmus[i % kvm->arch.nested_mmus_size];
> +
> +		if (atomic_read(&s2_mmu->refcnt) == 0)
> +			break;
> +	}
> +	BUG_ON(atomic_read(&s2_mmu->refcnt)); /* We have struct MMUs to spare */
> +
> +	/* Set the scene for the next search */
> +	kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
> +
> +	if (kvm_s2_mmu_valid(s2_mmu)) {
> +		/* Clear the old state */
> +		kvm_unmap_stage2_range(s2_mmu, 0, kvm_phys_size(kvm));
> +		if (s2_mmu->vmid.vmid_gen)
> +			kvm_call_hyp(__kvm_tlb_flush_vmid, s2_mmu);
> +	}
> +
> +	/*
> +	 * The virtual VMID (modulo CnP) will be used as a key when matching
> +	 * an existing kvm_s2_mmu.
> +	 */
> +	s2_mmu->vttbr = vttbr & ~VTTBR_CNP_BIT;
> +	s2_mmu->nested_stage2_enabled = hcr & HCR_VM;
> +
> +out:
> +	atomic_inc(&s2_mmu->refcnt);
> +	return s2_mmu;
> +}
> +
> +void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
> +{
> +	mmu->vttbr = 1;
> +	mmu->nested_stage2_enabled = false;
> +	atomic_set(&mmu->refcnt, 0);
> +}
> +
> +void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
> +{
> +	if (is_hyp_ctxt(vcpu)) {
> +		vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
> +	} else {
> +		spin_lock(&vcpu->kvm->mmu_lock);
> +		vcpu->arch.hw_mmu = get_s2_mmu_nested(vcpu);
> +		spin_unlock(&vcpu->kvm->mmu_lock);
> +	}
> +}
> +
> +void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
> +{
> +	if (vcpu->arch.hw_mmu != &vcpu->kvm->arch.mmu) {
> +		atomic_dec(&vcpu->arch.hw_mmu->refcnt);
> +		vcpu->arch.hw_mmu = NULL;
> +	}
> +}
> +
>   /*
>    * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
>    * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
> @@ -43,6 +220,24 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
>   	return -EINVAL;
>   }
>   
> +void kvm_arch_flush_shadow_all(struct kvm *kvm)
> +{
> +	int i;
> +
> +	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
> +		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
> +
> +		WARN_ON(atomic_read(&mmu->refcnt));
> +
> +		if (!atomic_read(&mmu->refcnt))
> +			kvm_free_stage2_pgd(mmu);
> +	}
> +	kfree(kvm->arch.nested_mmus);
> +	kvm->arch.nested_mmus = NULL;
> +	kvm->arch.nested_mmus_size = 0;
> +	kvm_free_stage2_pgd(&kvm->arch.mmu);
> +}
> +
>   /*
>    * Our emulated CPU doesn't support all the possible features. For the
>    * sake of simplicity (and probably mental sanity), wipe out a number

It looks good to me, please feel free to add.
Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>

Thanks,
Ganapat


From gankulkarni at os.amperecomputing.com  Tue Jan 18 03:29:00 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 18 Jan 2022 16:59:00 +0530
Subject: [PATCH v5 44/69] KVM: arm64: nv: Set a handler for the system
 instruction traps
In-Reply-To: <20211129200150.351436-45-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-45-maz@kernel.org>
Message-ID: <a70a4d4a-c036-615c-4076-fe0753bcd810@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> When HCR.NV bit is set, execution of the EL2 translation regime address
> aranslation instructions and TLB maintenance instructions are trapped to
Typo: translation

> EL2. In addition, execution of the EL1 translation regime address
> aranslation instructions and TLB maintenance instructions that are only
Typo: translation

> accessible from EL2 and above are trapped to EL2. In these cases,
> ESR_EL2.EC will be set to 0x18.
> 
> Rework the system instruction emulation framework to handle potentially
> all system instruction traps other than MSR/MRS instructions. Those
> system instructions would be AT and TLBI instructions controlled by
> HCR_EL2.NV, AT, and TTLB bits.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> [maz: squashed two patches together, redispatched various bits around]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_host.h |  4 +--
>   arch/arm64/kvm/handle_exit.c      |  2 +-
>   arch/arm64/kvm/sys_regs.c         | 48 +++++++++++++++++++++++++------
>   3 files changed, 42 insertions(+), 12 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 00c3366129b8..35f3d7939484 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -411,7 +411,7 @@ struct kvm_vcpu_arch {
>   	/*
>   	 * Guest registers we preserve during guest debugging.
>   	 *
> -	 * These shadow registers are updated by the kvm_handle_sys_reg
> +	 * These shadow registers are updated by the kvm_handle_sys
>   	 * trap handler if the guest accesses or updates them while we
>   	 * are using guest debug.
>   	 */
> @@ -729,7 +729,7 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu);
>   int kvm_handle_cp14_64(struct kvm_vcpu *vcpu);
>   int kvm_handle_cp15_32(struct kvm_vcpu *vcpu);
>   int kvm_handle_cp15_64(struct kvm_vcpu *vcpu);
> -int kvm_handle_sys_reg(struct kvm_vcpu *vcpu);
> +int kvm_handle_sys(struct kvm_vcpu *vcpu);
>   
>   void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
>   
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 6ff709c124d0..8b3b758e674e 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -234,7 +234,7 @@ static exit_handle_fn arm_exit_handlers[] = {
>   	[ESR_ELx_EC_SMC32]	= handle_smc,
>   	[ESR_ELx_EC_HVC64]	= handle_hvc,
>   	[ESR_ELx_EC_SMC64]	= handle_smc,
> -	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
> +	[ESR_ELx_EC_SYS64]	= kvm_handle_sys,
>   	[ESR_ELx_EC_SVE]	= handle_sve,
>   	[ESR_ELx_EC_ERET]	= kvm_handle_eret,
>   	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 77f07f960d84..222f8c6f1d7e 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -1770,10 +1770,6 @@ static bool access_spsr_el2(struct kvm_vcpu *vcpu,
>    * more demanding guest...
>    */
>   static const struct sys_reg_desc sys_reg_descs[] = {
> -	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
> -	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
> -	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
> -
>   	DBG_BCR_BVR_WCR_WVR_EL1(0),
>   	DBG_BCR_BVR_WCR_WVR_EL1(1),
>   	{ SYS_DESC(SYS_MDCCINT_EL1), trap_debug_regs, reset_val, MDCCINT_EL1, 0 },
> @@ -2240,6 +2236,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>   	{ SYS_DESC(SYS_SP_EL2), NULL, reset_unknown, SP_EL2 },
>   };
>   
> +#define SYS_INSN_TO_DESC(insn, access_fn, forward_fn)	\
> +	{ SYS_DESC((insn)), (access_fn), NULL, 0, 0, NULL, NULL, (forward_fn) }
> +static struct sys_reg_desc sys_insn_descs[] = {
> +	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
> +	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
> +	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
> +};
> +
>   static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
>   			struct sys_reg_params *p,
>   			const struct sys_reg_desc *r)
> @@ -2794,6 +2798,24 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
>   	return 1;
>   }
>   
> +static int emulate_sys_instr(struct kvm_vcpu *vcpu, struct sys_reg_params *p)
> +{
> +	const struct sys_reg_desc *r;
> +
> +	/* Search from the system instruction table. */
> +	r = find_reg(p, sys_insn_descs, ARRAY_SIZE(sys_insn_descs));
> +
> +	if (likely(r)) {
> +		perform_access(vcpu, p, r);
> +	} else {
> +		kvm_err("Unsupported guest sys instruction at: %lx\n",
> +			*vcpu_pc(vcpu));
> +		print_sys_reg_instr(p);
> +		kvm_inject_undefined(vcpu);
> +	}
> +	return 1;
> +}
> +
>   /**
>    * kvm_reset_sys_regs - sets system registers to reset value
>    * @vcpu: The VCPU pointer
> @@ -2811,10 +2833,11 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
>   }
>   
>   /**
> - * kvm_handle_sys_reg -- handles a mrs/msr trap on a guest sys_reg access
> + * kvm_handle_sys-- handles a system instruction or mrs/msr instruction trap
> +		    on a guest execution
>    * @vcpu: The VCPU pointer
>    */
> -int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
> +int kvm_handle_sys(struct kvm_vcpu *vcpu)
>   {
>   	struct sys_reg_params params;
>   	unsigned long esr = kvm_vcpu_get_esr(vcpu);
> @@ -2826,10 +2849,16 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
>   	params = esr_sys64_to_params(esr);
>   	params.regval = vcpu_get_reg(vcpu, Rt);
>   
> -	ret = emulate_sys_reg(vcpu, &params);
> +	if (params.Op0 == 1) {
> +		/* System instructions */
> +		ret = emulate_sys_instr(vcpu, &params);
> +	} else {
> +		/* MRS/MSR instructions */
> +		ret = emulate_sys_reg(vcpu, &params);
> +		if (!params.is_write)
> +			vcpu_set_reg(vcpu, Rt, params.regval);
> +	}
>   
> -	if (!params.is_write)
> -		vcpu_set_reg(vcpu, Rt, params.regval);
>   	return ret;
>   }
>   
> @@ -3245,6 +3274,7 @@ void kvm_sys_reg_table_init(void)
>   	BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true));
>   	BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true));
>   	BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs), false));
> +	BUG_ON(check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false));
>   
>   	/* We abuse the reset function to overwrite the table itself. */
>   	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)

It looks good to me, please feel free to add.
Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>

Thanks,
Ganapat


From ardb at kernel.org  Tue Jan 18 03:32:55 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 12:32:55 +0100
Subject: [PATCH] ARM: Thumb2: align ALT_UP() sections sufficiently
In-Reply-To: <YeaisFN1ru7suF1Y@shell.armlinux.org.uk>
References: <20220118102756.1259149-1-ardb@kernel.org>
 <YeaisFN1ru7suF1Y@shell.armlinux.org.uk>
Message-ID: <CAMj1kXHTXeLPWbnQpkEen2uy6ameVL27QfeN2MZpdBB21Wj14w@mail.gmail.com>

On Tue, 18 Jan 2022 at 12:21, Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
>
> On Tue, Jan 18, 2022 at 11:27:56AM +0100, Ard Biesheuvel wrote:
> > When building for Thumb2, the .alt.smp.init sections that are emitted by
> > the ALT_UP() patching code may not be 32-bit aligned, even though the
> > fixup_smp_on_up() routine expects that. This results in alignment faults
> > at module load time, which need to be fixed up by the fault handler.
> >
> > So let's align those sections explicitly, and avoid this from occurring.
>
> Are you seeing a problem that this patch fixes?
>
> This really should not matter. .alt.smp.init contents are always a whole
> number of 32-bit words. These are gathered by the linker into the
> .init.smpalt section, so the contents should always be a whole number
> of 32-bit words.
>
> This follows the .init.tagtable section, which is also a 32-bit word
> aligned structure built by the linker... which follows the
> .init.arch.info section and .init.proc.info sections which all have
> 32-bit alignment requirements.
>

This only affects modules, not the core kernel. The .alt.smp.init
section in a module is visible to the module loader, which means the
module loader will make no attempt to position it at a 32-bit aligned
address if the ELF alignment is only 16 bits, which appears to be the
default in my Thumb2 build [gcc version 10.3.1 20211117 (Debian
10.3.0-13)]

I only spotted this because do_fixup_smp_on_up() was shown as the most
recent in-kernel fixup location in /proc/cpu/alignment.


From linux at armlinux.org.uk  Tue Jan 18 03:35:22 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 11:35:22 +0000
Subject: [PATCH] ARM: Thumb2: align ALT_UP() sections sufficiently
In-Reply-To: <CAMj1kXHTXeLPWbnQpkEen2uy6ameVL27QfeN2MZpdBB21Wj14w@mail.gmail.com>
References: <20220118102756.1259149-1-ardb@kernel.org>
 <YeaisFN1ru7suF1Y@shell.armlinux.org.uk>
 <CAMj1kXHTXeLPWbnQpkEen2uy6ameVL27QfeN2MZpdBB21Wj14w@mail.gmail.com>
Message-ID: <Yeal+oNFCvj911nt@shell.armlinux.org.uk>

On Tue, Jan 18, 2022 at 12:32:55PM +0100, Ard Biesheuvel wrote:
> On Tue, 18 Jan 2022 at 12:21, Russell King (Oracle)
> <linux at armlinux.org.uk> wrote:
> >
> > On Tue, Jan 18, 2022 at 11:27:56AM +0100, Ard Biesheuvel wrote:
> > > When building for Thumb2, the .alt.smp.init sections that are emitted by
> > > the ALT_UP() patching code may not be 32-bit aligned, even though the
> > > fixup_smp_on_up() routine expects that. This results in alignment faults
> > > at module load time, which need to be fixed up by the fault handler.
> > >
> > > So let's align those sections explicitly, and avoid this from occurring.
> >
> > Are you seeing a problem that this patch fixes?
> >
> > This really should not matter. .alt.smp.init contents are always a whole
> > number of 32-bit words. These are gathered by the linker into the
> > .init.smpalt section, so the contents should always be a whole number
> > of 32-bit words.
> >
> > This follows the .init.tagtable section, which is also a 32-bit word
> > aligned structure built by the linker... which follows the
> > .init.arch.info section and .init.proc.info sections which all have
> > 32-bit alignment requirements.
> >
> 
> This only affects modules, not the core kernel. The .alt.smp.init
> section in a module is visible to the module loader, which means the
> module loader will make no attempt to position it at a 32-bit aligned
> address if the ELF alignment is only 16 bits, which appears to be the
> default in my Thumb2 build [gcc version 10.3.1 20211117 (Debian
> 10.3.0-13)]
> 
> I only spotted this because do_fixup_smp_on_up() was shown as the most
> recent in-kernel fixup location in /proc/cpu/alignment.

Ok, thanks for the explanation.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From gankulkarni at os.amperecomputing.com  Tue Jan 18 03:35:48 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 18 Jan 2022 17:05:48 +0530
Subject: [PATCH v5 58/69] KVM: arm64: nv: Add handling of ARMv8.4-TTL TLB
 invalidation
In-Reply-To: <20211129200150.351436-59-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-59-maz@kernel.org>
Message-ID: <3e161689-1f04-8baf-201c-e14d453be2c9@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> Support guest-provided information information to find out about

Typo: information written twice.

> the range of required invalidation.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_nested.h |  1 +
>   arch/arm64/kvm/nested.c             | 57 +++++++++++++++++++++
>   arch/arm64/kvm/sys_regs.c           | 78 ++++++++++++++++++-----------
>   3 files changed, 108 insertions(+), 28 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 5fa3c634c8e1..7c47ad655e2e 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -123,6 +123,7 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
>   			    u64 control_bit);
>   extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
>   extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
> +unsigned int ttl_to_size(u8 ttl);
>   
>   struct sys_reg_params;
>   struct sys_reg_desc;
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 198169648c3c..6f738b5f57dd 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -363,6 +363,63 @@ int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
>   	return ret;
>   }
>   
> +
> +unsigned int ttl_to_size(u8 ttl)
> +{
> +	int level = ttl & 3;
> +	int gran = (ttl >> 2) & 3;
> +	unsigned int max_size = 0;
> +
> +	switch (gran) {
> +	case TLBI_TTL_TG_4K:
> +		switch (level) {
> +		case 0:
			/* No 52bit IPA support */
> +			break;
> +		case 1:
> +			max_size = SZ_1G;
> +			break;
> +		case 2:
> +			max_size = SZ_2M;
> +			break;
> +		case 3:
> +			max_size = SZ_4K;
> +			break;
> +		}
> +		break;
> +	case TLBI_TTL_TG_16K:
> +		switch (level) {
> +		case 0:
> +		case 1:
			/* No 52bit IPA support */
> +			break;
> +		case 2:
> +			max_size = SZ_32M;
> +			break;
> +		case 3:
> +			max_size = SZ_16K;
> +			break;
> +		}
> +		break;
> +	case TLBI_TTL_TG_64K:
> +		switch (level) {
> +		case 0:
> +		case 1:
> +			/* No 52bit IPA support */
> +			break;
> +		case 2:
> +			max_size = SZ_512M;
> +			break;
> +		case 3:
> +			max_size = SZ_64K;
> +			break;
> +		}
> +		break;
> +	default:			/* No size information */
> +		break;
> +	}
> +
> +	return max_size;
> +}
> +
>   /* Must be called with kvm->lock held */
>   struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
>   {
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 55f3e94c24f1..e0f088de2cad 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -2699,59 +2699,81 @@ static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>   	return true;
>   }
>   
> +static unsigned long compute_tlb_inval_range(struct kvm_vcpu *vcpu,
> +					     struct kvm_s2_mmu *mmu,
> +					     u64 val)
> +{
> +	unsigned long max_size;
> +	u8 ttl = 0;
> +
> +	if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL)) {
> +		ttl = FIELD_GET(GENMASK_ULL(47, 44), val);
> +	}
> +
> +	max_size = ttl_to_size(ttl);
> +
> +	if (!max_size) {
> +		u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
> +
> +		/* Compute the maximum extent of the invalidation */
> +		switch ((vtcr & VTCR_EL2_TG0_MASK)) {
> +		case VTCR_EL2_TG0_4K:
> +			max_size = SZ_1G;
> +			break;
> +		case VTCR_EL2_TG0_16K:
> +			max_size = SZ_32M;
> +			break;
> +		case VTCR_EL2_TG0_64K:
> +			/*
> +			 * No, we do not support 52bit IPA in nested yet. Once
> +			 * we do, this should be 4TB.
> +			 */
> +			/* FIXME: remove the 52bit PA support from the IDregs */
> +			max_size = SZ_512M;
> +			break;
> +		default:
> +			BUG();
> +		}
> +	}
> +
> +	WARN_ON(!max_size);
> +	return max_size;
> +}
> +
>   static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
>   			     const struct sys_reg_desc *r)
>   {
>   	u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
> -	u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
>   	struct kvm_s2_mmu *mmu;
>   	u64 base_addr;
> -	int max_size;
> +	unsigned long max_size;
>   
>   	/*
>   	 * We drop a number of things from the supplied value:
>   	 *
>   	 * - NS bit: we're non-secure only.
>   	 *
> -	 * - TTL field: We already have the granule size from the
> -	 *   VTCR_EL2.TG0 field, and the level is only relevant to the
> -	 *   guest's S2PT.
> -	 *
>   	 * - IPA[51:48]: We don't support 52bit IPA just yet...
>   	 *
>   	 * And of course, adjust the IPA to be on an actual address.
>   	 */
>   	base_addr = (p->regval & GENMASK_ULL(35, 0)) << 12;
>   
> -	/* Compute the maximum extent of the invalidation */
> -	switch ((vtcr & VTCR_EL2_TG0_MASK)) {
> -	case VTCR_EL2_TG0_4K:
> -		max_size = SZ_1G;
> -		break;
> -	case VTCR_EL2_TG0_16K:
> -		max_size = SZ_32M;
> -		break;
> -	case VTCR_EL2_TG0_64K:
> -		/*
> -		 * No, we do not support 52bit IPA in nested yet. Once
> -		 * we do, this should be 4TB.
> -		 */
> -		/* FIXME: remove the 52bit PA support from the IDregs */
> -		max_size = SZ_512M;
> -		break;
> -	default:
> -		BUG();
> -	}
> -
>   	spin_lock(&vcpu->kvm->mmu_lock);
>   
>   	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, HCR_VM);
> -	if (mmu)
> +	if (mmu) {
> +		max_size = compute_tlb_inval_range(vcpu, mmu, p->regval);
> +		base_addr &= ~(max_size - 1);
>   		kvm_unmap_stage2_range(mmu, base_addr, max_size);
> +	}
>   
>   	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, 0);
> -	if (mmu)
> +	if (mmu) {
> +		max_size = compute_tlb_inval_range(vcpu, mmu, p->regval);
> +		base_addr &= ~(max_size - 1);
>   		kvm_unmap_stage2_range(mmu, base_addr, max_size);
> +	}
>   
>   	spin_unlock(&vcpu->kvm->mmu_lock);
>   

It looks good to me, please feel free to add.
Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>

Thanks,
Ganapat


From elver at google.com  Tue Jan 18 03:40:04 2022
From: elver at google.com (Marco Elver)
Date: Tue, 18 Jan 2022 12:40:04 +0100
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <20220118091827.GA98966@leoy-ThinkPad-X240s>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
 <20220118091827.GA98966@leoy-ThinkPad-X240s>
Message-ID: <CANpmjNMPoU+1b1fKFuYDYwisW2YfjQHxGt5hgLp1tioG7C2jmg@mail.gmail.com>

On Tue, 18 Jan 2022 at 10:18, Leo Yan <leo.yan at linaro.org> wrote:
>
> On Mon, Jan 17, 2022 at 03:39:10PM +0000, John Garry wrote:
> > On 16/12/2021 15:48, Marco Elver wrote:
> >
> > +
> >
> > > On Thu, 16 Dec 2021 at 16:15, Thomas Richter<tmricht at linux.ibm.com>  wrote:
> > > > In Linux next kernel
> > > > Commit 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
> > > > introduced the new test which uses breakpoint events.
> > > > These events are not supported on s390 and PowerPC and always fail:
> > > >
> > > >   # perf test -F 73
> > > >   73: Sigtrap                                                         : FAILED!
> > > >   #
> > > >
> > > > Fix it the same way as in the breakpoint tests in file
> > > > tests/bp_account.c where these type of tests are skipped on
> > > > s390 and PowerPC platforms.
> > > >
> > > > With this patch skip this test on both platforms.
> > > >
> > > > Output after:
> > > >   # ./perf test -F 73
> > > >   73: Sigtrap
> > > >
> > > > Fixes: 5504f67944484 ("perf test sigtrap: Add basic stress test for sigtrap handling")
> > > >
> > > > Cc: Marco Elver<elver at google.com>
> > > > Signed-off-by: Thomas Richter<tmricht at linux.ibm.com>
> > > Acked-by: Marco Elver<elver at google.com>
> > >
> > > Thanks, and sorry for missing this case!
> > >
> >
> > I am finding that this test hangs on my arm64 machine:
> >
> > john at debian:~/kernel-dev2/tools/perf$ sudo ./perf test -vvv 73
> >  73: Sigtrap:
> > --- start ---
> > test child forked, pid 45193
>
> Both Arm and Arm64 platforms cannot support signal handler with
> breakpoint, please see the details in [1].  So I think we need
> something like below:
>
> static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
> {
>         ...
>
>         if (!BP_SIGNAL_IS_SUPPORTED) {
>                 pr_debug("Test not supported on this architecture");
>                 return TEST_SKIP;
>         }
>
>         ...
> }
>
> Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
> here.
>
> [1] https://lore.kernel.org/lkml/157169993406.29376.12473771029179755767.tip-bot2 at tip-bot2/

Does this limitation also exist for address watchpoints? The sigtrap
test does not make use of instruction breakpoints, but instead just
sets up a watchpoint on access to a data address.

Thanks,
-- Marco


From gankulkarni at os.amperecomputing.com  Tue Jan 18 03:50:18 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Tue, 18 Jan 2022 17:20:18 +0530
Subject: [PATCH v5 67/69] KVM: arm64: nv: Enable ARMv8.4-NV support
In-Reply-To: <20211129200150.351436-68-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-68-maz@kernel.org>
Message-ID: <7fe1ce9e-1b86-ed57-a0e5-117d1b9011b4@os.amperecomputing.com>



On 30-11-2021 01:31 am, Marc Zyngier wrote:
> As all the VNCR-capable system registers are nicely separated
> from the rest of the crowd, let's set HCR_EL2.NV2 on and let
> the ball rolling.
> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>   arch/arm64/include/asm/kvm_arm.h     |  1 +
>   arch/arm64/include/asm/kvm_emulate.h | 23 +++++++++++++----------
>   arch/arm64/include/asm/sysreg.h      |  1 +
>   arch/arm64/kvm/hyp/vhe/switch.c      | 14 +++++++++++++-
>   4 files changed, 28 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index b603466803d2..18c35446249f 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -20,6 +20,7 @@
>   #define HCR_AMVOFFEN	(UL(1) << 51)
>   #define HCR_FIEN	(UL(1) << 47)
>   #define HCR_FWB		(UL(1) << 46)
> +#define HCR_NV2		(UL(1) << 45)
>   #define HCR_AT		(UL(1) << 44)
>   #define HCR_NV1		(UL(1) << 43)
>   #define HCR_NV		(UL(1) << 42)
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 1664430be698..f282997e4a4c 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -245,21 +245,24 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
>   
>   static inline u64 __fixup_spsr_el2_write(struct kvm_cpu_context *ctxt, u64 val)
>   {
> -	if (!__vcpu_el2_e2h_is_set(ctxt)) {
> -		/*
> -		 * Clear the .M field when writing SPSR to the CPU, so that we
> -		 * can detect when the CPU clobbered our SPSR copy during a
> -		 * local exception.
> -		 */
> -		val &= ~0xc;
> -	}
> +	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
> +
> +	if (enhanced_nested_virt_in_use(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
> +		return val;
>   
> -	return val;
> +	/*
> +	 * Clear the .M field when writing SPSR to the CPU, so that we
> +	 * can detect when the CPU clobbered our SPSR copy during a
> +	 * local exception.
> +	 */
> +	return val &= ~0xc;
>   }
>   
>   static inline u64 __fixup_spsr_el2_read(const struct kvm_cpu_context *ctxt, u64 val)
>   {
> -	if (__vcpu_el2_e2h_is_set(ctxt))
> +	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
> +
> +	if (enhanced_nested_virt_in_use(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
>   		return val;
>   
>   	/*
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 71e6a0410e7c..5de90138d0a4 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -550,6 +550,7 @@
>   #define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
>   #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
>   #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
> +#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
>   
>   #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
>   #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
> diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> index ef4488db6dc1..5cadda79089a 100644
> --- a/arch/arm64/kvm/hyp/vhe/switch.c
> +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> @@ -45,7 +45,13 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>   			 * the EL1 virtual memory control register accesses
>   			 * as well as the AT S1 operations.
>   			 */
> -			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_TTLB | HCR_NV1;
> +			if (enhanced_nested_virt_in_use(vcpu)) {
> +				hcr &= ~HCR_TVM;

I think, we should clear TRVM also?
				hcr &= ~(HCR_TVM | HCR_TRVM);

> +			} else {
> +				hcr |= HCR_TVM | HCR_TRVM | HCR_TTLB;
> +			}
> +
> +			hcr |= HCR_AT | HCR_NV1;
>   		} else {
>   			/*
>   			 * For a guest hypervisor on v8.1 (VHE), allow to
> @@ -79,6 +85,12 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>   			if (!vcpu_el2_tge_is_set(vcpu))
>   				hcr |= HCR_AT | HCR_TTLB;
>   		}
> +
> +		if (enhanced_nested_virt_in_use(vcpu)) {
> +			hcr |= HCR_AT | HCR_TTLB | HCR_NV2;
> +			write_sysreg_s(vcpu->arch.ctxt.vncr_array,
> +				       SYS_VNCR_EL2);
> +		}
>   	} else if (nested_virt_in_use(vcpu)) {
>   		u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
>   


Thanks,
Ganapat


From catalin.marinas at arm.com  Tue Jan 18 04:32:55 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Tue, 18 Jan 2022 12:32:55 +0000
Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
In-Reply-To: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <Yeazd1lLuYm4k3lH@arm.com>

Hi Shameer,

On Mon, Nov 22, 2021 at 12:18:40PM +0000, Shameer Kolothum wrote:
> ?-TLA+ model. Modified the asidalloc model to incorporate the new
>   VMID algo. The main differences are,
> ? -flush_tlb_all() instead of local_tlb_flush_all() on rollover.
> ? -Introduced INVALID_VMID and vCPU Sched Out logic.
> ? -No CnP (Removed UniqueASIDAllCPUs & UniqueASIDActiveTask invariants).
> ? -Removed ?UniqueVMIDPerCPU invariant for now as it looks like
>    because of the speculative fetching with flush_tlb_all() there
>    is a small window where this gets triggered. If I change the
>    logic back to local_flush_tlb_all(), UniqueVMIDPerCPU seems to
>    be fine. With my limited knowledge on TLA+ model, it is not
>    clear to me whether this is a problem with the above logic
>    or the VMID model implementation. Really appreciate any help
>    with the model.
>    The initial VMID TLA+ model is here,
>    https://github.com/shamiali2008/kernel-tla/tree/private-vmidalloc-v1

I only had a brief look at the TLA+ model and I don't understand why you
have a separate 'shed_out' process. It would run in parallel with the
'sched' but AFAICT you can't really schedule a guest out while you are
in the middle of scheduling it in. I'd rather use the same 'sched'
process and either schedule in an inactive task or schedule out an
active one for a given CPU.

Also active_vmids[] for example is defined on the CPUS domain but you
call vcpu_sched_out() from a process that's not in the CPUS domain but
the SCHED_OUT one.

Regarding UniqueVMIDPerCPU, I think we need to figure out why it
happens. The fact that flush_tlb_all() was made to simulate the
speculative TLB loads is not relevant. In a different spec I have,
arm64kpti.tla, I just used another process that invokes an update_tlbs()
macro so that it can happen at any time. I didn't bother to update the
ASID spec in a similar way but it may be useful. The corresponding
UniqueASIDPerCPU meant that for any two TLB entries on a single CPU, if
they correspond to different tasks (pgd), they should have different
ASIDs. That's a strong requirement, otherwise we end up with the wrong
translation.

Why did you remove the CnP? Do we have this disabled for KVM guests?

-- 
Catalin


From andre.przywara at arm.com  Tue Jan 18 04:37:41 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 18 Jan 2022 12:37:41 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220117130554.GB87485@C02TD0UTHF1T.local>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
 <20220114181247.7b366f45@donnerap.cambridge.arm.com>
 <20220117121557.GA87485@C02TD0UTHF1T.local>
 <20220117130554.GB87485@C02TD0UTHF1T.local>
Message-ID: <20220118123741.5f367d1f@donnerap.cambridge.arm.com>

On Mon, 17 Jan 2022 13:05:54 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> On Mon, Jan 17, 2022 at 12:15:57PM +0000, Mark Rutland wrote:
> > On Fri, Jan 14, 2022 at 06:12:47PM +0000, Andre Przywara wrote:  
> > > On Fri, 14 Jan 2022 10:56:46 +0000
> > > Mark Rutland <mark.rutland at arm.com> wrote:
> > > 
> > > Hi Mark,  
> > 
> > Hi Andre,  
>  
> > > > +
> > > > +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > > > +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))  
> 
> > > > -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
> > > >  
> > > >  #ifdef KERNEL_32
> > > >  /* 32-bit kernel decompressor uses CP15 barriers */
> > > > #define SCTLR_EL1_KERNEL        (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)  
> > > 
> > > So I wonder if this actually works? The ARMv7 version of SCTLR
> > > differs in some bits from both the ARMv8 AArch32 version and more
> > > importantly the AArch64 version.  
> 
> > > I had troubles the other day running the
> > > arm32 Linux kernel decompressor with some ARMv8 SCTLR_EL1 reset value. The
> > > decompressor code does only read-modify-write of SCTLR (probably to
> > > cover multiple architecture revisions), so some bits might stay wrong. In
> > > particular I think having bits 28 and 29 set caused problems.
> > > By looking at the ARMv7 ARM and with experimentation I came up
> > > with 0x00c00878 as a safe and working value.  
> 
> Having re-read all of this, I believe you're right; I'll rework the
> AArch32-kernel SCTLR_EL1_KERNEL to not use the AArch64 bit definitions,
> and I'll add some commentary explaining that we're writing to the AArch32
> format.
> 
> > > Shall we have a separate reset value for 32bit?  
> 
> Assuming you meant to alter the SCTLR_ELx_KERNEL definition, yes.
> 
> The idea of splitting the SCTLR_ELx_RESET and SCTLR_ELx_KERNEL
> definitions was that the former would be whatever the boot-wrapper
> needed to run at ELx, and the latter was whatever we must initialize for
> the kernel to run at ELx, so I don't want to put the AArch32 kernel bits
> into SCTLR_EL1_RESET.
> 
> My only remaining concern is exactly what we must initialize. If there's
> any documentation we can refer to, that'd be great, otherwise I'll dig
> through your prior suggestion.

I don't know of any recommendation what to initialise, though the ARMv7
ARM speaks a bit about reset values.
So the SCTLR_KERNEL value we use in arch/aarch32/include/asm/cpu.h seems
to work (although it's not perfect), but we should use the same in the
KERNEL_32 case in arch/aarch64/include/asm/cpu.h.

Going through the SCTLR description in the ARMv8 *and* ARMv7 ARM again,
I think a safe and sane init value would be to set bits
[23,22,18,16,11,5,4,3] to one. This differs slightly from the value I told
you above, which I think was what I observed on an Cortex-A7 when dumping
SCTLR in the decompressor code.

I became aware of the issue when I tried to start an ARM kernel on a
Cortex-A53 board, with U-Boot dropping from AArch64-EL2 to AArch32-EL1.
SCTLR_EL1 there got initialised according to the ARMv8 ARM (bits
[29,28,23,22,20,11] set), but this made the kernel decompressor hang as
soon as the MMU got enabled. I *think* I bisected it down to bits 28 and
29, which are RES1 in AArch64, but enable TEX remap and the Access Flag in
v7, and both reset to 0 there. I haven't tried that on the model with the
boot-wrapper, but I guess we see the same problem there.

In any case it seems to be already broken, so a fix or discussion doesn't
need to block this series.

Cheers,
Andre


From leo.yan at linaro.org  Tue Jan 18 04:43:43 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 18 Jan 2022 20:43:43 +0800
Subject: [PATCH] perf test: Test 73 Sig_trap fails on s390
In-Reply-To: <CANpmjNMPoU+1b1fKFuYDYwisW2YfjQHxGt5hgLp1tioG7C2jmg@mail.gmail.com>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
 <20220118091827.GA98966@leoy-ThinkPad-X240s>
 <CANpmjNMPoU+1b1fKFuYDYwisW2YfjQHxGt5hgLp1tioG7C2jmg@mail.gmail.com>
Message-ID: <20220118124343.GC98966@leoy-ThinkPad-X240s>

On Tue, Jan 18, 2022 at 12:40:04PM +0100, Marco Elver wrote:

[...]

> > Both Arm and Arm64 platforms cannot support signal handler with
> > breakpoint, please see the details in [1].  So I think we need
> > something like below:
> >
> > static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
> > {
> >         ...
> >
> >         if (!BP_SIGNAL_IS_SUPPORTED) {
> >                 pr_debug("Test not supported on this architecture");
> >                 return TEST_SKIP;
> >         }
> >
> >         ...
> > }
> >
> > Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
> > here.
> >
> > [1] https://lore.kernel.org/lkml/157169993406.29376.12473771029179755767.tip-bot2 at tip-bot2/
> 
> Does this limitation also exist for address watchpoints? The sigtrap
> test does not make use of instruction breakpoints, but instead just
> sets up a watchpoint on access to a data address.

Yes, after reading the code, the flow for either instrution breakpoint
or watchpoint both use the single step [1], thus the signal handler will
take the single step execution and lead to the infinite loop.

I am not the best person to answer this question; @Will, could you
confirm for this?  Thanks!

Leo

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/hw_breakpoint.c


From clabbe.montjoie at gmail.com  Tue Jan 18 04:50:52 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Tue, 18 Jan 2022 13:50:52 +0100
Subject: [BUG] pinctrl: reg-fixed-voltage usb0-vbus: error -EINVAL: can't get
 GPIO
Message-ID: <Yea3rBmY+MO4AhhV@Red>

Hello

As reported on old googlegroup sunxi mainling list, on linux-next-20220118, USB storage fail to bring up on orangepiPC.
We can see some error logs in dmesg:
reg-fixed-voltage usb0-vbus: error -EINVAL: can't get GPIO
reg-fixed-voltage: probe of usb0-vbus failed with error -22

This is bisected to: 8df89a7cbc63c7598c00611ad17b67e8d5b4fad3 pinctrl-sunxi: don't call pinctrl_gpio_direction()

Reverting this commit lead to a working USB storage being setuped.

Regards


From andre.przywara at arm.com  Tue Jan 18 04:52:03 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Tue, 18 Jan 2022 12:52:03 +0000
Subject: [boot-wrapper PATCH v2 3/9] Makefile: Tell compiler to generate
 bare-metal code
In-Reply-To: <Yd1qSjmu61hXGZgd@FVFF77S0Q05N>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-4-andre.przywara@arm.com>
 <YdhF7kluP5vwzDf4@FVFF77S0Q05N>
 <20220107143811.3d193704@donnerap.cambridge.arm.com>
 <Yd1qSjmu61hXGZgd@FVFF77S0Q05N>
Message-ID: <20220118125203.272ccf8c@donnerap.cambridge.arm.com>

On Tue, 11 Jan 2022 11:30:18 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> On Fri, Jan 07, 2022 at 02:38:11PM +0000, Andre Przywara wrote:
> > On Fri, 7 Jan 2022 13:53:50 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > 
> > Hi Mark,
> >   
> > > On Wed, Dec 22, 2021 at 06:16:01PM +0000, Andre Przywara wrote:  
> > > > Our GCC invocation does not provide many parameters, which lets the
> > > > toolchain fill in its own default setup.
> > > > In case of a native build or when using a full-featured cross-compiler,
> > > > this probably means Linux userland, which is not what we want for a
> > > > bare-metal application like boot-wrapper.
> > > > 
> > > > Tell the compiler to forget about those standard settings, and only use
> > > > what we explicitly ask for. In particular that means to not use toolchain
> > > > provided libraries and headers, since they might pull in more code than
> > > > we want, and might not run well in the boot-wrapper environment.
> > > > 
> > > > This also enables optimisation, since it produces much better code and
> > > > tends to avoid problems due to missing inlining, for instance.    
> > > 
> > > I'd appreciate if we could add some explanation for these (just in the commit
> > > message is fine), as e.g. it's not clear to me why -fno-toplevel-reorder is
> > > necessary.  
> > 
> > Yeah, I was expecting some discussion about this. I went over most options
> > from the manpage a while ago (for some unrelated baremetal code project),
> > and decided for each option whether it would make sense or not. TBH I
> > don't remember every detail from that, but I can certainly just drop the
> > less critical options from that list.  
> 
> Yes please.
> 
> To be clear, I'm only suggesting dropping a few of these, and I think the
> others just needs some explanation.
> 
> I'm certain we *should* add:
> 
> 	-ffreestanding
> 	-nostdlib
> 
> ... and I'd be happy to take a patch adding just those as an immediate fix.
> 
> I think the folllowing are reasonable but need some explanation:
> 
> 	-Wstrict-prototypes		// Just to catch accidents

Agreed.

> 	-fno-stack-protector		// Because we dont have any init/support code

... and it breaks the link, as we learned.

> 	-fno-strict-aliasing		// Do we rely on type punning today?

I don't know for sure, but it seems like that's what this kind of low level
software would like to do? Plus the kernel uses it also.

> 	-fno-unwind-tables		// Because we don't consume the result
> 	-fno-asynchronous-unwind-tables	// Because we don't consume the result

Plus those two prevent sections of rather pointless data to be emitted
into the ELF file. This blew up my own bare metal code considerably, though
I don't see it in the boot-wrapper.

> I don't understand why we need:
> 
> 	-fno-common

I think most projects use that to put uninitialised global variables in
.BSS, to save space in .data and thus the image file. I see it used in all
of Linux, U-Boot and TF-A. With the kernel image absolutely dwarfing any
actual boot-wrapper code in our ELF file, I think we are not particularly
sensitive about code/file size, though, are we?

> 	-fno-toplevel-reorder

Yeah, this one is nonsense, I think I had this as a workaround to one
particular problem. Will drop it.

> 	-Os

AFAICT we don't use any optimisation at the moment, which typically
generates horrible code. And IIRC at the least the kernel relies on
some optimisation (due to some inlining tricks?), I wonder if we sooner or
later inherit this requirement?

> ... and I suspect we can drop those unless we have some rationale.
> 
> I'm torn over:
> 
> 	-nostdinc
> 
> ... as IIUC that's just to catch accidental includes, but necessitates the
> prior patch adding copies of some headers. We could arguably leave that as-is
> and just be careful.

Yeah, I see the point, this probably drops too much. I am just concerned
that the standard header files these days pull in far too much *code* even,
and then create some dependencies on libraries? For certain division
operations, for instance?
So looking at the *current* code, I see only stdint.h and stddef.h from
the standard headers to be included. I'd say we can live with these coming
from the toolchain.
The only problem I see is when this gets extended, and someone pulls in
string.h, for instance. IIUC modern toolchains put in quite some
optimisation in the string routines, which might not go well in the
boot-wrapper environment (NEON?).

But for now we should indeed keep the standard headers, and drop our own
stdint.h.
I will send a patch with the remaining flags, plus some rationale as
comments, similar to what you sketched already.

Cheers,
Andre

> > And I would be happy to add some rationale for each of them, but wonder
> > what the best place would be? I'd rather do this in a file than in a
> > commit message, would you prefer comments in Makefile.am, or in README or
> > a separate file, with a pointer from Makefile.am. Or in a commit message
> > anyway?  
> 
> I think within the Makefile would be best if you're happy to organise it, e.g.
> 
> 	# The boot-wrapper is a non-hosted environment and isn't linked
> 	# with standard libraries.
> 	CFLAGS += -ffreestanding -nostdlib
> 
> 	# Avoid the pointless creation og a GOT
> 	CFLAGS += -fno-pic -fno-pie
> 
> ... does that work for you?
> 
> Thanks,
> Mark.
> 
> > 
> > Cheers,
> > Andre
> >   
> > > > 
> > > > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > > ---
> > > >  Makefile.am | 7 ++++++-
> > > >  1 file changed, 6 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/Makefile.am b/Makefile.am
> > > > index 3e970a3..d9ad6d1 100644
> > > > --- a/Makefile.am
> > > > +++ b/Makefile.am
> > > > @@ -124,9 +124,14 @@ CHOSEN_NODE	:= chosen {						\
> > > >  
> > > >  CPPFLAGS	+= $(INITRD_FLAGS)
> > > >  CFLAGS		+= -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
> > > > -CFLAGS		+= -Wall -fomit-frame-pointer
> > > > +CFLAGS		+= -Wall -Wstrict-prototypes -fomit-frame-pointer
> > > > +CFLAGS		+= -ffreestanding -nostdinc -nostdlib
> > > > +CFLAGS		+= -fno-common -fno-strict-aliasing -fno-stack-protector
> > > > +CFLAGS		+= -fno-toplevel-reorder
> > > > +CFLAGS		+= -fno-unwind-tables -fno-asynchronous-unwind-tables
> > > >  CFLAGS		+= -ffunction-sections -fdata-sections
> > > >  CFLAGS		+= -fno-pic -fno-pie
> > > > +CFLAGS		+= -Os
> > > >  LDFLAGS		+= --gc-sections
> > > >  
> > > >  OBJ		:= $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
> > > > -- 
> > > > 2.25.1
> > > >     
> >   



From hjl.tools at gmail.com  Tue Jan 18 04:55:21 2022
From: hjl.tools at gmail.com (H.J. Lu)
Date: Tue, 18 Jan 2022 04:55:21 -0800
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <20220118112211.GD3294453@arm.com>
References: <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com> <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com> <YeWtRk0H30q38eM8@arm.com>
 <20ae043b-a013-068d-2d83-16e63f5b4989@linaro.org>
 <CAMe9rOo5zWO1BwZGhqGdWuCjsq86YUo4ptqXkFVNSwXbU+ZS-Q@mail.gmail.com>
 <20220118112211.GD3294453@arm.com>
Message-ID: <CAMe9rOoY5itEcPQs+ejX=aowkEA8ZSYwJzS7ZqEnSMnaneq6hg@mail.gmail.com>

On Tue, Jan 18, 2022 at 3:22 AM Szabolcs Nagy <szabolcs.nagy at arm.com> wrote:
>
> The 01/17/2022 11:01, H.J. Lu via Libc-alpha wrote:
> > We are taking a different approach for CET enabling.   CET will be
> > changed to be enabled from user space:
> >
> > https://gitlab.com/x86-glibc/glibc/-/tree/users/hjl/cet/enable
> >
> > and the CET kernel no longer enables CET automatically:
> >
> > https://github.com/hjl-tools/linux/tree/hjl/cet%2F5.16.0-v4
>
> we considered userspace handling of BTI in static exe
> and ld.so too. at the time we wanted the protection to
> be on whenever BTI marked code is executed, so it has
> to be enabled at program entry.
>
> i no longer think that the entry code protection is very
> important, but delaying mprotect for static exe does
> not fix our mprotect(*|PROT_EXEC) problem with systemd.
>
> i also don't immediately see where you deal with shadow
> stack allocation for the main stack if it is userspace
> enabled, i expected that to require kernel assistance
> if you want the main stack protected all the way up.

We enable shadow stack in user space as soon as possible:

https://gitlab.com/x86-glibc/glibc/-/commit/211abce607a9f6e4cd1cadefb87561413dd8fae9

-- 
H.J.


From ardb at kernel.org  Tue Jan 18 05:00:34 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 14:00:34 +0100
Subject: [PATCH] ARM: uaccess: avoid alignment faults in
 copy_[from|to]_kernel_nofault
In-Reply-To: <CAMj1kXGtHoDYzjv8eUg0xbs4aTZVnRDHCne-cJg=9ZLHzYbOgQ@mail.gmail.com>
References: <20220118082808.931129-1-ardb@kernel.org>
 <CAK8P3a0XGEZSTWy=24fEckPxtLoOt7sF7SYzF+QZEMooiW4BsA@mail.gmail.com>
 <CAMj1kXGtHoDYzjv8eUg0xbs4aTZVnRDHCne-cJg=9ZLHzYbOgQ@mail.gmail.com>
Message-ID: <CAMj1kXFh-XFr8tBrYcobrR1G9YBwV-BvAyBtVQPUqDOe+Dw7fw@mail.gmail.com>

On Tue, 18 Jan 2022 at 09:41, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> On Tue, 18 Jan 2022 at 09:38, Arnd Bergmann <arnd at arndb.de> wrote:
> >
> > On Tue, Jan 18, 2022 at 9:28 AM Ard Biesheuvel <ardb at kernel.org> wrote:
> > >
> > > The helpers that are used to implement copy_from_kernel_nofault() and
> > > copy_to_kernel_nofault() cast a void* to a pointer to a wider type,
> > > which may result in alignment faults on ARM if the compiler decides to
> > > use double-word or multiple-word load/store instructions.
> > >
> > > So use the unaligned accessors where needed: when the type's size > 1
> > > and the input was not aligned already by the caller.
> > >
> > > Cc: <stable at vger.kernel.org>
> > > Fixes: 2df4c9a741a0 ("ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault")
> > > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> >
> > Reviewed-by: Arnd Bergmann <arnd at arndb.de>
> >
> > It took me a bit to see whythis works, maybe mention commit 2423de2e6f4d
> > ("ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault")
> > in the description for clarification.
> >
>
> Ack.
>

I've dropped this into the patch system as #9719/1, with the above
suggestions incorporated into the commit log.

Thanks,
> > Did you run into actual faults, or did you find this problem by
> > reading the code?
> >
>
> I was seeing actual faults:
>
> [    4.447003]  copy_from_kernel_nofault from prepend+0x3c/0xb4
> [    4.453085]  prepend from prepend_path+0x118/0x34c
> [    4.457930]  prepend_path from d_path+0x11c/0x184
> [    4.462656]  d_path from proc_pid_readlink+0xbc/0x1d4
> [    4.467928]  proc_pid_readlink from vfs_readlink+0xfc/0x110
> [    4.473740]  vfs_readlink from do_readlinkat+0xb0/0x110
> [    4.479024]  do_readlinkat from ret_fast_syscall+0x0/0x54


From alexander.stein at ew.tq-group.com  Tue Jan 18 05:16:22 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 18 Jan 2022 14:16:22 +0100
Subject: [PATCH v3 0/4] i.MX8MP: more USB3 glue layer feature support
Message-ID: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>

Thanks everyone for the rfeedback on v2 [1].

This patchset aims to support flags for e.g. over-current active low or port
permanantly attached which are provided in the USB3 glue layer.

In v3 the implementation is moved from USB PHY driver to USB DWC3 glue for
i.MX8MP. The confusing part is that the existing dwc3-imx8mp.c driver references
glue everywhere but is actually using HSIO BLK_CTL, which is a different
hardware block.
The implementation is still backward compatible and be used with device trees
where neither PHY clock nor (new) glue layer base address is provided.

Changes in v3:
* Rename existing member for clarity
* Moved feature implementation from phy-fsl-imx8mq-usb.c to dwc3-imx8mp.c

[1] https://lore.kernel.org/linux-arm-kernel/2245006.irdbgypaU6 at steina-w/T/

Alexander Stein (4):
  usb: dwc3: imx8mp: rename iomem base pointer
  dt-bindings: usb: dwc3-imx8mp: Add imx8mp specific flags
  usb: dwc3: imx8mp: Add support for setting SOC specific flags
  arm64: dts: imx8mp: Add memory for USB3 glue layer to usb3 nodes

 .../bindings/usb/fsl,imx8mp-dwc3.yaml         | 38 ++++++--
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 20 ++--
 drivers/usb/dwc3/dwc3-imx8mp.c                | 95 +++++++++++++++++--
 3 files changed, 134 insertions(+), 19 deletions(-)

-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 18 05:16:23 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 18 Jan 2022 14:16:23 +0100
Subject: [PATCH v3 1/4] usb: dwc3: imx8mp: rename iomem base pointer
In-Reply-To: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220118131626.926394-2-alexander.stein@ew.tq-group.com>

Until now the iomem used is not USB glue as the name suggests, but
HSIO BLK_CTL. Rename the struct member accordingly. This is a preparing
patch for when USB glue is actually used.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index d328d20abfbc..1c8fe657b3a9 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -39,7 +39,7 @@
 struct dwc3_imx8mp {
 	struct device			*dev;
 	struct platform_device		*dwc3;
-	void __iomem			*glue_base;
+	void __iomem			*hsio_blk_base;
 	struct clk			*hsio_clk;
 	struct clk			*suspend_clk;
 	int				irq;
@@ -55,7 +55,7 @@ static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 	if (!dwc3)
 		return;
 
-	val = readl(dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 
 	if ((dwc3->current_dr_role == DWC3_GCTL_PRTCAP_HOST) && dwc3->xhci)
 		val |= USB_WAKEUP_EN | USB_WAKEUP_SS_CONN |
@@ -64,16 +64,16 @@ static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 		val |= USB_WAKEUP_EN | USB_WAKEUP_VBUS_EN |
 		       USB_WAKEUP_VBUS_SRC_SESS_VAL;
 
-	writel(val, dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 }
 
 static void dwc3_imx8mp_wakeup_disable(struct dwc3_imx8mp *dwc3_imx)
 {
 	u32 val;
 
-	val = readl(dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 	val &= ~(USB_WAKEUP_EN | USB_WAKEUP_EN_MASK);
-	writel(val, dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 }
 
 static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
@@ -115,9 +115,9 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 
 	dwc3_imx->dev = dev;
 
-	dwc3_imx->glue_base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dwc3_imx->glue_base))
-		return PTR_ERR(dwc3_imx->glue_base);
+	dwc3_imx->hsio_blk_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(dwc3_imx->hsio_blk_base))
+		return PTR_ERR(dwc3_imx->hsio_blk_base);
 
 	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
 	if (IS_ERR(dwc3_imx->hsio_clk)) {
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 18 05:16:24 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 18 Jan 2022 14:16:24 +0100
Subject: [PATCH v3 2/4] dt-bindings: usb: dwc3-imx8mp: Add imx8mp specific
 flags
In-Reply-To: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220118131626.926394-3-alexander.stein@ew.tq-group.com>

This adds bindings for features in the USB glue block. They allow
setting polarity of PWR and OC as well as disabling port power control.
Also permanently attached can be annotated as well.
Additional IO address and clock are needed.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 .../bindings/usb/fsl,imx8mp-dwc3.yaml         | 38 ++++++++++++++++---
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
index 974032b1fda0..ff48b4e8427d 100644
--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
@@ -15,9 +15,9 @@ properties:
     const: fsl,imx8mp-dwc3
 
   reg:
-    maxItems: 1
-    description: Address and length of the register set for the wrapper of
-      dwc3 core on the SOC.
+    items:
+      - description: Address and length of the register set for HSIO Block Control
+      - description: Address and length of the register set for the wrapper of dwc3 core on the SOC.
 
   "#address-cells":
     enum: [ 1, 2 ]
@@ -43,11 +43,35 @@ properties:
     items:
       - description: system hsio root clock.
       - description: suspend clock, used for usb wakeup logic.
+      - description: clock for the USB glue block
 
   clock-names:
     items:
       - const: hsio
       - const: suspend
+      - const: phy
+
+  fsl,permanently-attached:
+    type: boolean
+    description:
+      Indicates if the device atached to a downstream port is
+      permanently attached.
+
+  fsl,disable-port-power-control:
+    type: boolean
+    description:
+      Indicates whether the host controller implementation includes port
+      power control. Defines Bit 3 in capability register (HCCPARAMS).
+
+  fsl,over-current-active-low:
+    type: boolean
+    description:
+      Over current signal polarity is active low.
+
+  fsl,power-active-low:
+    type: boolean
+    description:
+      Power pad (PWR) polarity is active low.
 
 # Required child node:
 
@@ -74,10 +98,12 @@ examples:
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     usb3_0: usb at 32f10100 {
       compatible = "fsl,imx8mp-dwc3";
-      reg = <0x32f10100 0x8>;
+      reg = <0x32f10100 0x8>,
+            <0x381f0000 0x20>;
       clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
-               <&clk IMX8MP_CLK_USB_ROOT>;
-      clock-names = "hsio", "suspend";
+               <&clk IMX8MP_CLK_USB_ROOT>,
+               <&clk IMX8MP_CLK_USB_PHY_ROOT>;
+      clock-names = "hsio", "suspend", "phy";
       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
       #address-cells = <1>;
       #size-cells = <1>;
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 18 05:16:25 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 18 Jan 2022 14:16:25 +0100
Subject: [PATCH v3 3/4] usb: dwc3: imx8mp: Add support for setting SOC
 specific flags
In-Reply-To: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220118131626.926394-4-alexander.stein@ew.tq-group.com>

The i.MX8MP glue layer has support for the following flags:
* over-current polarity
* PWR pad polarity
* controlling PPC flag in HCCPARAMS register
* permanent port attach for usb2 & usb3 port

Allow setting these flags by supporting specific flags in the glue node.
In order to get this to work an additional IORESOURCE_MEM and clock is
necessary. For backward compatibility this is purely optional.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 81 ++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index 1c8fe657b3a9..3df4313b3740 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -36,17 +36,66 @@
 
 #define USB_WAKEUP_EN_MASK		GENMASK(5, 0)
 
+/* USB glue registers */
+#define USB_CTRL0		0x00
+#define USB_CTRL1		0x04
+
+#define USB_CTRL0_PORTPWR_EN	BIT(12) /* 1 - PPC enabled (default) */
+#define USB_CTRL0_USB3_FIXED	BIT(22) /* 1 - USB3 permanent attached */
+#define USB_CTRL0_USB2_FIXED	BIT(23) /* 1 - USB2 permanent attached */
+
+#define USB_CTRL1_OC_POLARITY	BIT(16) /* 0 - HIGH / 1 - LOW */
+#define USB_CTRL1_PWR_POLARITY	BIT(17) /* 0 - HIGH / 1 - LOW */
+
 struct dwc3_imx8mp {
 	struct device			*dev;
 	struct platform_device		*dwc3;
 	void __iomem			*hsio_blk_base;
+	void __iomem			*glue_base;
 	struct clk			*hsio_clk;
 	struct clk			*suspend_clk;
+	struct clk			*phy_clk;
 	int				irq;
 	bool				pm_suspended;
 	bool				wakeup_pending;
 };
 
+static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx)
+{
+	struct device *dev = dwc3_imx->dev;
+	u32 value;
+
+	if ((!dwc3_imx->glue_base) || (!dwc3_imx->phy_clk))
+		return;
+
+	value = readl(dwc3_imx->glue_base + USB_CTRL0);
+
+	if (device_property_read_bool(dev, "fsl,permanently-attached"))
+		value |= (USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
+	else
+		value &= ~(USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
+
+	if (device_property_read_bool(dev, "fsl,disable-port-power-control"))
+		value &= ~(USB_CTRL0_PORTPWR_EN);
+	else
+		value |= USB_CTRL0_PORTPWR_EN;
+
+	writel(value, dwc3_imx->glue_base + USB_CTRL0);
+
+	value = readl(dwc3_imx->glue_base + USB_CTRL1);
+	if (device_property_read_bool(dev, "fsl,over-current-active-low"))
+		value |= USB_CTRL1_OC_POLARITY;
+	else
+		value &= ~USB_CTRL1_OC_POLARITY;
+
+	if (device_property_read_bool(dev, "fsl,power-active-low"))
+		value |= USB_CTRL1_PWR_POLARITY;
+	else
+		value &= ~USB_CTRL1_PWR_POLARITY;
+
+	writel(value, dwc3_imx->glue_base + USB_CTRL1);
+}
+
 static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 {
 	struct dwc3	*dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
@@ -100,6 +149,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	struct device		*dev = &pdev->dev;
 	struct device_node	*dwc3_np, *node = dev->of_node;
 	struct dwc3_imx8mp	*dwc3_imx;
+	struct resource		*res;
 	int			err, irq;
 
 	if (!node) {
@@ -119,6 +169,15 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	if (IS_ERR(dwc3_imx->hsio_blk_base))
 		return PTR_ERR(dwc3_imx->hsio_blk_base);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_warn(dev, "Base address for glue layer missing. Continuing without, some features are missing though.");
+	} else {
+		dwc3_imx->glue_base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(dwc3_imx->glue_base))
+			return PTR_ERR(dwc3_imx->glue_base);
+	}
+
 	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
 	if (IS_ERR(dwc3_imx->hsio_clk)) {
 		err = PTR_ERR(dwc3_imx->hsio_clk);
@@ -145,6 +204,24 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 		goto disable_hsio_clk;
 	}
 
+	dwc3_imx->phy_clk = devm_clk_get(dev, "phy");
+	if (PTR_ERR(dwc3_imx->phy_clk) == -ENOENT) {
+		dev_warn(dev, "PHY clock missing. Continuing without, some features are missing though.");
+		dwc3_imx->phy_clk = NULL;
+	} else if (IS_ERR(dwc3_imx->phy_clk)) {
+		err = PTR_ERR(dwc3_imx->phy_clk);
+		dev_err(dev, "Failed to get phy clk, err=%d\n", err);
+		goto disable_suspend_clk;
+	}
+
+	if (dwc3_imx->phy_clk) {
+		err = clk_prepare_enable(dwc3_imx->phy_clk);
+		if (err) {
+			dev_err(dev, "Failed to enable phy clk, err=%d\n", err);
+			goto disable_suspend_clk;
+		}
+	}
+
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		err = irq;
@@ -152,6 +229,8 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	}
 	dwc3_imx->irq = irq;
 
+	imx8mp_configure_glue(dwc3_imx);
+
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	err = pm_runtime_get_sync(dev);
@@ -199,6 +278,8 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	pm_runtime_disable(dev);
 	pm_runtime_put_noidle(dev);
 disable_clks:
+	clk_disable_unprepare(dwc3_imx->phy_clk);
+disable_suspend_clk:
 	clk_disable_unprepare(dwc3_imx->suspend_clk);
 disable_hsio_clk:
 	clk_disable_unprepare(dwc3_imx->hsio_clk);
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 18 05:16:26 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 18 Jan 2022 14:16:26 +0100
Subject: [PATCH v3 4/4] arm64: dts: imx8mp: Add memory for USB3 glue layer to
 usb3 nodes
In-Reply-To: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220118131626.926394-5-alexander.stein@ew.tq-group.com>

The USB3 glue layer has 2 areas in the register set, see RM Rev.1
section 11.2.5.2.1 GLUE_usb3 memory map:
* USB3 control/status
* PHY control/status

Provide the memory area to the usb3 nodes for accessing the features
in the USB3 control area.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 6b840c05dd77..baaa49b419fa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -921,10 +921,14 @@ usb3_phy0: usb-phy at 381f0040 {
 
 		usb3_0: usb at 32f10100 {
 			compatible = "fsl,imx8mp-dwc3";
-			reg = <0x32f10100 0x8>;
+			reg = <0x32f10100 0x8>,
+			      <0x381f0000 0x20>;
 			clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
-				 <&clk IMX8MP_CLK_USB_ROOT>;
-			clock-names = "hsio", "suspend";
+				 <&clk IMX8MP_CLK_USB_ROOT>,
+				 <&clk IMX8MP_CLK_USB_PHY_ROOT>;
+			clock-names = "hsio", "suspend", "phy";
+			assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
+			assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
 			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <1>;
@@ -962,10 +966,14 @@ usb3_phy1: usb-phy at 382f0040 {
 
 		usb3_1: usb at 32f10108 {
 			compatible = "fsl,imx8mp-dwc3";
-			reg = <0x32f10108 0x8>;
+			reg = <0x32f10108 0x8>,
+			      <0x382f0000 0x20>;
 			clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
-				 <&clk IMX8MP_CLK_USB_ROOT>;
-			clock-names = "hsio", "suspend";
+				 <&clk IMX8MP_CLK_USB_ROOT>,
+				 <&clk IMX8MP_CLK_USB_PHY_ROOT>;
+			clock-names = "hsio", "suspend", "phy";
+			assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
+			assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
 			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.25.1



From matthias.bgg at gmail.com  Tue Jan 18 05:17:37 2022
From: matthias.bgg at gmail.com (Matthias Brugger)
Date: Tue, 18 Jan 2022 14:17:37 +0100
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for MT8186
 SoC
In-Reply-To: <544f5085fc8597ce9ce3eb7dc1b5d08fb1ac8755.camel@mediatek.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
 <9949a1f7-1ed5-a137-c7b9-2ef8d8e1caf8@gmail.com>
 <544f5085fc8597ce9ce3eb7dc1b5d08fb1ac8755.camel@mediatek.com>
Message-ID: <f5486d12-b048-c062-e571-cf39da7e4c1b@gmail.com>



On 18/01/2022 10:25, Johnson Wang wrote:
> Hi Matthias,
> 
> On Fri, 2022-01-14 at 16:46 +0100, Matthias Brugger wrote:
>>
>> On 07/01/2022 11:46, Johnson Wang wrote:
>>> MT8186 are highly integrated SoC and use PMIC_MT6366 for
>>> power management. This patch adds pwrap master driver to
>>> access PMIC_MT6366.
>>>
>>
>> It seems this new arbiter is significantly different from the version
>> 1. Please
>> explain that in the commit message.
>>
>>> Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
>>> ---
>>>    drivers/soc/mediatek/mtk-pmic-wrap.c | 72
>>> ++++++++++++++++++++++++++++
>>>    1 file changed, 72 insertions(+)
>>>
>>> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c
>>> b/drivers/soc/mediatek/mtk-pmic-wrap.c
>>> index 952bc554f443..78866ebf7f04 100644
>>> --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
>>> +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
>>> @@ -30,6 +30,7 @@
>>>    #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) &
>>> 0x00000001)
>>>    #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
>>>    #define PWRAP_STATE_INIT_DONE0		BIT(21)
>>> +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
>>
>> That's a strange name, does it come from the datasheet description?
> 
> Thanks for your review.
> 
> No, there is only PWRAP_STATE_INIT_DONE0 in MT8186 datasheet.
> However, it's the 22nd bit in MT8186 and the 21st bit in other SoCs.
> So we changed its name to avoid redefinition of PWRAP_STATE_INIT_DONE0.
> 
> Could you give us some suggestion on proper definition naming?
> Do you think PWRAP_STATE_INIT_DONE0_MT8186 will be a better choice?
> 

Is this a difference that only will show up on the PMIC-wrapper of MT8186 or 
will other SoCs include the same IP? If not, then PWRAP_STATE_INIT_DONE0_MT8186 
should be fine. Otherwise we would need a better name.

>>
>>>    #define PWRAP_STATE_INIT_DONE1		BIT(15)
>>>    
>>>    /* macro for WACS FSM */
>>> @@ -77,6 +78,8 @@
>>>    #define PWRAP_CAP_INT1_EN	BIT(3)
>>>    #define PWRAP_CAP_WDT_SRC1	BIT(4)
>>>    #define PWRAP_CAP_ARB		BIT(5)
>>> +#define PWRAP_CAP_MONITOR_V2	BIT(6)
>>
>> Not used capability, please delete.
>>
>>
>> Regards,
>> Matthias
> 
> PWRAP_CAP_MONITOR_V2 is not used right now.
> We can remove it in next version.
> But this capability will be added when we need it.
> 

That's OK, we should add capability definitions once they are added to the 
driver, not before that.

Thanks,
Matthias


From angelogioacchino.delregno at collabora.com  Tue Jan 18 05:33:48 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 18 Jan 2022 14:33:48 +0100
Subject: [PATCH] usb: host: xhci-mtk: Simplify supplies handling with
 regulator_bulk
Message-ID: <20220118133348.111860-1-angelogioacchino.delregno@collabora.com>

Remove the custom functions xhci_mtk_ldos_{enable,disable}() by
switching to using regulator_bulk to perform the very same thing,
as the regulators are always either both enabled or both disabled.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/usb/host/xhci-mtk.c | 56 ++++++++++++-------------------------
 drivers/usb/host/xhci-mtk.h |  4 +--
 2 files changed, 20 insertions(+), 40 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 62c835d446be..3b81931e5b77 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -395,31 +395,6 @@ static int xhci_mtk_clks_get(struct xhci_hcd_mtk *mtk)
 	return devm_clk_bulk_get_optional(mtk->dev, BULK_CLKS_NUM, clks);
 }
 
-static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
-{
-	int ret;
-
-	ret = regulator_enable(mtk->vbus);
-	if (ret) {
-		dev_err(mtk->dev, "failed to enable vbus\n");
-		return ret;
-	}
-
-	ret = regulator_enable(mtk->vusb33);
-	if (ret) {
-		dev_err(mtk->dev, "failed to enable vusb33\n");
-		regulator_disable(mtk->vbus);
-		return ret;
-	}
-	return 0;
-}
-
-static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
-{
-	regulator_disable(mtk->vbus);
-	regulator_disable(mtk->vusb33);
-}
-
 static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd *xhci)
 {
 	struct usb_hcd *hcd = xhci_to_hcd(xhci);
@@ -475,6 +450,10 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
 	return ret;
 }
 
+static const char * const xhci_mtk_supply_names[] = {
+	"vusb33", "vbus",
+};
+
 static const struct xhci_driver_overrides xhci_mtk_overrides __initconst = {
 	.reset = xhci_mtk_setup,
 	.add_endpoint = xhci_mtk_add_ep,
@@ -507,17 +486,18 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	mtk->dev = dev;
-	mtk->vbus = devm_regulator_get(dev, "vbus");
-	if (IS_ERR(mtk->vbus)) {
-		dev_err(dev, "fail to get vbus\n");
-		return PTR_ERR(mtk->vbus);
-	}
+	mtk->num_supplies = ARRAY_SIZE(xhci_mtk_supply_names);
+	mtk->supplies = devm_kcalloc(dev, mtk->num_supplies,
+				     sizeof(*mtk->supplies), GFP_KERNEL);
+	if (!mtk->supplies)
+		return -ENOMEM;
 
-	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
-	if (IS_ERR(mtk->vusb33)) {
-		dev_err(dev, "fail to get vusb33\n");
-		return PTR_ERR(mtk->vusb33);
-	}
+	regulator_bulk_set_supply_names(mtk->supplies, xhci_mtk_supply_names,
+					mtk->num_supplies);
+
+	ret = devm_regulator_bulk_get(dev, mtk->num_supplies, mtk->supplies);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get regulators\n");
 
 	ret = xhci_mtk_clks_get(mtk);
 	if (ret)
@@ -558,7 +538,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
-	ret = xhci_mtk_ldos_enable(mtk);
+	ret = regulator_bulk_enable(mtk->num_supplies, mtk->supplies);
 	if (ret)
 		goto disable_pm;
 
@@ -667,7 +647,7 @@ static int xhci_mtk_probe(struct platform_device *pdev)
 	clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks);
 
 disable_ldos:
-	xhci_mtk_ldos_disable(mtk);
+	regulator_bulk_disable(mtk->num_supplies, mtk->supplies);
 
 disable_pm:
 	pm_runtime_put_noidle(dev);
@@ -695,7 +675,7 @@ static int xhci_mtk_remove(struct platform_device *pdev)
 	usb_put_hcd(hcd);
 	xhci_mtk_sch_exit(mtk);
 	clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks);
-	xhci_mtk_ldos_disable(mtk);
+	regulator_bulk_disable(mtk->num_supplies, mtk->supplies);
 
 	pm_runtime_disable(dev);
 	pm_runtime_put_noidle(dev);
diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
index 4b1ea89f959a..9b78cd2ba0ac 100644
--- a/drivers/usb/host/xhci-mtk.h
+++ b/drivers/usb/host/xhci-mtk.h
@@ -150,9 +150,9 @@ struct xhci_hcd_mtk {
 	int num_u3_ports;
 	int u2p_dis_msk;
 	int u3p_dis_msk;
-	struct regulator *vusb33;
-	struct regulator *vbus;
 	struct clk_bulk_data clks[BULK_CLKS_NUM];
+	struct regulator_bulk_data *supplies;
+	u8 num_supplies;
 	unsigned int has_ippc:1;
 	unsigned int lpm_support:1;
 	unsigned int u2_lpm_disable:1;
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Tue Jan 18 05:33:58 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 18 Jan 2022 14:33:58 +0100
Subject: [PATCH] i2c: busses: i2c-mt65xx: Simplify with clk-bulk
Message-ID: <20220118133358.111886-1-angelogioacchino.delregno@collabora.com>

Since depending on the SoC or specific bus functionality some clocks
may be optional, we cannot get the benefit of using devm_clk_bulk_get()
but, by migrating to clk-bulk, we are able to remove the custom functions
mtk_i2c_clock_enable() and mtk_i2c_clock_disable(), increasing common
APIs usage, hence (lightly) decreasing kernel footprint.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 127 +++++++++++++-------------------
 1 file changed, 51 insertions(+), 76 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9ea427f53083..541b7be88375 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -85,6 +85,27 @@
 
 #define I2C_DRV_NAME		"i2c-mt65xx"
 
+/**
+ * enum i2c_mt65xx_clks - Clocks enumeration for MT65XX I2C
+ *
+ * @I2C_MT65XX_CLK_MAIN: main clock for i2c bus
+ * @I2C_MT65XX_CLK_DMA:  DMA clock for i2c via DMA
+ * @I2C_MT65XX_CLK_PMIC: PMIC clock for i2c from PMIC
+ * @I2C_MT65XX_CLK_ARB:  Arbitrator clock for i2c
+ * @I2C_MT65XX_CLK_MAX:  Number of supported clocks
+ */
+enum i2c_mt65xx_clks {
+	I2C_MT65XX_CLK_MAIN = 0,
+	I2C_MT65XX_CLK_DMA,
+	I2C_MT65XX_CLK_PMIC,
+	I2C_MT65XX_CLK_ARB,
+	I2C_MT65XX_CLK_MAX
+};
+
+static const char * const i2c_mt65xx_clk_ids[I2C_MT65XX_CLK_MAX] = {
+	"main", "dma", "pmic", "arb"
+};
+
 enum DMA_REGS_OFFSET {
 	OFFSET_INT_FLAG = 0x0,
 	OFFSET_INT_EN = 0x04,
@@ -243,10 +264,7 @@ struct mtk_i2c {
 	/* set in i2c probe */
 	void __iomem *base;		/* i2c base addr */
 	void __iomem *pdmabase;		/* dma base address*/
-	struct clk *clk_main;		/* main clock for i2c bus */
-	struct clk *clk_dma;		/* DMA clock for i2c via DMA */
-	struct clk *clk_pmic;		/* PMIC clock for i2c from PMIC */
-	struct clk *clk_arb;		/* Arbitrator clock for i2c */
+	struct clk_bulk_data clocks[I2C_MT65XX_CLK_MAX]; /* clocks for i2c */
 	bool have_pmic;			/* can use i2c pins from PMIC */
 	bool use_push_pull;		/* IO config push-pull mode */
 
@@ -434,55 +452,6 @@ static void mtk_i2c_writew(struct mtk_i2c *i2c, u16 val,
 	writew(val, i2c->base + i2c->dev_comp->regs[reg]);
 }
 
-static int mtk_i2c_clock_enable(struct mtk_i2c *i2c)
-{
-	int ret;
-
-	ret = clk_prepare_enable(i2c->clk_dma);
-	if (ret)
-		return ret;
-
-	ret = clk_prepare_enable(i2c->clk_main);
-	if (ret)
-		goto err_main;
-
-	if (i2c->have_pmic) {
-		ret = clk_prepare_enable(i2c->clk_pmic);
-		if (ret)
-			goto err_pmic;
-	}
-
-	if (i2c->clk_arb) {
-		ret = clk_prepare_enable(i2c->clk_arb);
-		if (ret)
-			goto err_arb;
-	}
-
-	return 0;
-
-err_arb:
-	if (i2c->have_pmic)
-		clk_disable_unprepare(i2c->clk_pmic);
-err_pmic:
-	clk_disable_unprepare(i2c->clk_main);
-err_main:
-	clk_disable_unprepare(i2c->clk_dma);
-
-	return ret;
-}
-
-static void mtk_i2c_clock_disable(struct mtk_i2c *i2c)
-{
-	if (i2c->clk_arb)
-		clk_disable_unprepare(i2c->clk_arb);
-
-	if (i2c->have_pmic)
-		clk_disable_unprepare(i2c->clk_pmic);
-
-	clk_disable_unprepare(i2c->clk_main);
-	clk_disable_unprepare(i2c->clk_dma);
-}
-
 static void mtk_i2c_init_hw(struct mtk_i2c *i2c)
 {
 	u16 control_reg;
@@ -1149,7 +1118,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
 	int left_num = num;
 	struct mtk_i2c *i2c = i2c_get_adapdata(adap);
 
-	ret = mtk_i2c_clock_enable(i2c);
+	ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
 	if (ret)
 		return ret;
 
@@ -1203,7 +1172,7 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap,
 	ret = num;
 
 err_exit:
-	mtk_i2c_clock_disable(i2c);
+	clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
 	return ret;
 }
 
@@ -1281,9 +1250,8 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 	struct mtk_i2c *i2c;
-	struct clk *clk;
 	struct resource *res;
-	int irq;
+	int i, irq, speed_clk;
 
 	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
 	if (!i2c)
@@ -1329,35 +1297,42 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 	if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c)
 		return -EINVAL;
 
-	i2c->clk_main = devm_clk_get(&pdev->dev, "main");
-	if (IS_ERR(i2c->clk_main)) {
+	/* Fill in clk-bulk IDs */
+	for (i = 0; i < I2C_MT65XX_CLK_MAX; i++)
+		i2c->clocks[i].id = i2c_mt65xx_clk_ids[i];
+
+	/* Get clocks one by one, some may be optional */
+	i2c->clocks[I2C_MT65XX_CLK_MAIN].clk = devm_clk_get(&pdev->dev, "main");
+	if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk)) {
 		dev_err(&pdev->dev, "cannot get main clock\n");
-		return PTR_ERR(i2c->clk_main);
+		return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_MAIN].clk);
 	}
 
-	i2c->clk_dma = devm_clk_get(&pdev->dev, "dma");
-	if (IS_ERR(i2c->clk_dma)) {
+	i2c->clocks[I2C_MT65XX_CLK_DMA].clk = devm_clk_get(&pdev->dev, "dma");
+	if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk)) {
 		dev_err(&pdev->dev, "cannot get dma clock\n");
-		return PTR_ERR(i2c->clk_dma);
+		return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_DMA].clk);
 	}
 
-	i2c->clk_arb = devm_clk_get(&pdev->dev, "arb");
-	if (IS_ERR(i2c->clk_arb))
-		i2c->clk_arb = NULL;
+	i2c->clocks[I2C_MT65XX_CLK_ARB].clk = devm_clk_get_optional(&pdev->dev, "arb");
+	if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk))
+		return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_ARB].clk);
 
-	clk = i2c->clk_main;
 	if (i2c->have_pmic) {
-		i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic");
-		if (IS_ERR(i2c->clk_pmic)) {
+		i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = devm_clk_get(&pdev->dev, "pmic");
+		if (IS_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk)) {
 			dev_err(&pdev->dev, "cannot get pmic clock\n");
-			return PTR_ERR(i2c->clk_pmic);
+			return PTR_ERR(i2c->clocks[I2C_MT65XX_CLK_PMIC].clk);
 		}
-		clk = i2c->clk_pmic;
+		speed_clk = I2C_MT65XX_CLK_PMIC;
+	} else {
+		i2c->clocks[I2C_MT65XX_CLK_PMIC].clk = NULL;
+		speed_clk = I2C_MT65XX_CLK_MAIN;
 	}
 
 	strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name));
 
-	ret = mtk_i2c_set_speed(i2c, clk_get_rate(clk));
+	ret = mtk_i2c_set_speed(i2c, clk_get_rate(i2c->clocks[speed_clk].clk));
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to set the speed.\n");
 		return -EINVAL;
@@ -1372,13 +1347,13 @@ static int mtk_i2c_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = mtk_i2c_clock_enable(i2c);
+	ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
 	if (ret) {
 		dev_err(&pdev->dev, "clock enable failed!\n");
 		return ret;
 	}
 	mtk_i2c_init_hw(i2c);
-	mtk_i2c_clock_disable(i2c);
+	clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
 
 	ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq,
 			       IRQF_NO_SUSPEND | IRQF_TRIGGER_NONE,
@@ -1423,7 +1398,7 @@ static int mtk_i2c_resume_noirq(struct device *dev)
 	int ret;
 	struct mtk_i2c *i2c = dev_get_drvdata(dev);
 
-	ret = mtk_i2c_clock_enable(i2c);
+	ret = clk_bulk_prepare_enable(I2C_MT65XX_CLK_MAX, i2c->clocks);
 	if (ret) {
 		dev_err(dev, "clock enable failed!\n");
 		return ret;
@@ -1431,7 +1406,7 @@ static int mtk_i2c_resume_noirq(struct device *dev)
 
 	mtk_i2c_init_hw(i2c);
 
-	mtk_i2c_clock_disable(i2c);
+	clk_bulk_disable_unprepare(I2C_MT65XX_CLK_MAX, i2c->clocks);
 
 	i2c_mark_adapter_resumed(&i2c->adap);
 
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Tue Jan 18 05:37:58 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 18 Jan 2022 14:37:58 +0100
Subject: [PATCH 1/2] drm: mediatek: mtk_drm_plane: Use kmalloc in
 mtk_plane_duplicate_state
Message-ID: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>

There is no need to zero out the newly allocated memory because we are
duplicating all members of struct mtk_plane_state: switch to kmalloc
to save some overhead.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
index c74cb94e445e..39cb9a80d976 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -57,7 +57,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane
 	struct mtk_plane_state *old_state = to_mtk_plane_state(plane->state);
 	struct mtk_plane_state *state;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Tue Jan 18 05:37:59 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Tue, 18 Jan 2022 14:37:59 +0100
Subject: [PATCH 2/2] drm: mediatek: mtk_drm_crtc: Use kmalloc in
 mtk_drm_crtc_duplicate_state
In-Reply-To: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>
References: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220118133759.112458-2-angelogioacchino.delregno@collabora.com>

Optimize mtk_drm_crtc_duplicate_state() by switching from kzalloc() to
kmalloc(): the only variable of this struct that gets checked in other
functions is `pending_config`, but if that's set to false, then all of
the remaining variables will only ever be set, but not read - so, also
set `pending_config` to false.
This saves us some small overhead.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
index 09fc9ad02c7a..f536a0a927e4 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -185,7 +185,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
 {
 	struct mtk_crtc_state *state;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	state = kmalloc(sizeof(*state), GFP_KERNEL);
 	if (!state)
 		return NULL;
 
@@ -193,6 +193,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
 
 	WARN_ON(state->base.crtc != crtc);
 	state->base.crtc = crtc;
+	state->pending_config = false;
 
 	return &state->base;
 }
-- 
2.33.1



From abel.vesa at nxp.com  Tue Jan 18 05:59:17 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 15:59:17 +0200
Subject: [PATCH 1/2] dt-bindings: serial: fsl-lpuart: Drop i.MX8QXP backwards
 compatibility
Message-ID: <20220118135918.2126010-1-abel.vesa@nxp.com>

Drop the i.MX8QXP backwards compatibility with i.MX7ULP since they
differ from clocks handling point of view.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 Documentation/devicetree/bindings/serial/fsl-lpuart.yaml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
index aa83cbf56d59..ff364bd0fbac 100644
--- a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
+++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
@@ -20,11 +20,10 @@ properties:
           - fsl,ls1021a-lpuart
           - fsl,ls1028a-lpuart
           - fsl,imx7ulp-lpuart
+          - fsl,imx8qxp-lpuart
           - fsl,imxrt1050-lpuart
       - items:
-          - enum:
-              - fsl,imx8qxp-lpuart
-              - fsl,imx8ulp-lpuart
+          - const: fsl,imx8ulp-lpuart
           - const: fsl,imx7ulp-lpuart
       - items:
           - enum:
-- 
2.31.1



From abel.vesa at nxp.com  Tue Jan 18 05:59:18 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Tue, 18 Jan 2022 15:59:18 +0200
Subject: [PATCH 2/2] arm64: dts: imx8qxp-ss-adma: Drop fsl,
 imx7ulp-lpuart comaptible
In-Reply-To: <20220118135918.2126010-1-abel.vesa@nxp.com>
References: <20220118135918.2126010-1-abel.vesa@nxp.com>
Message-ID: <20220118135918.2126010-2-abel.vesa@nxp.com>

The driver differs from clocks point of view, so the i.MX8QXP
is not backwards compatible with i.MX7ULP.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
index dc1daa8dc72f..7bae516004bf 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
@@ -5,19 +5,19 @@
  */
 
 &lpuart0 {
-	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+	compatible = "fsl,imx8qxp-lpuart";
 };
 
 &lpuart1 {
-	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+	compatible = "fsl,imx8qxp-lpuart";
 };
 
 &lpuart2 {
-	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+	compatible = "fsl,imx8qxp-lpuart";
 };
 
 &lpuart3 {
-	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
+	compatible = "fsl,imx8qxp-lpuart";
 };
 
 &i2c0 {
-- 
2.31.1



From german.gomez at arm.com  Tue Jan 18 06:04:14 2022
From: german.gomez at arm.com (German Gomez)
Date: Tue, 18 Jan 2022 14:04:14 +0000
Subject: [RFC PATCH 1/2] perf: arm_spe: Fix consistency of PMSCR register
 bit CX
In-Reply-To: <20220118100702.GB16547@willie-the-truck>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-2-german.gomez@arm.com>
 <20220118100702.GB16547@willie-the-truck>
Message-ID: <2cb1baab-fd9c-ea20-2a09-4cd60d9d5531@arm.com>

Hi Will,

Many thanks for your comments

On 18/01/2022 10:07, Will Deacon wrote:
> On Mon, Jan 17, 2022 at 12:44:31PM +0000, German Gomez wrote:
>> [...]
>>
>>   1. Run a process in the background with capability CAP_SYS_ADMIN in CPU0.
>>
>>     $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
>>     [3] 3806
>>
>>   2. Begin a perf session _without_ capabilities (we shouldn't see CONTEXT packets).
>>
>>     $ perf record -e arm_spe_0// -C0 -- sleep 1
>>     $ perf report -D | grep CONTEXT
>>     .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     [...]
>>
>> As can be seen, the traces begin showing CONTEXT packets when the pid is
>> 0xedf (3807).
> So to be clear: we shouldn't be reporting these packets because 'perf'
> doesn't have the right capabilities, but we evaluate that in the context of
> 'dd' (running as root) and so incorrectly grant the permission. Correct?

Yes, correct. My guess was that "perfmon_capable()" was being called
under the assumption that it would always be evaluated in the context of
'perf'. Is that correct?

>
>> This happens because the pmu start callback is run when
>> the current process is not the owner of the perf session, so the CX
>> register bit is set.
> This doesn't really seem SPE-specific to me -- the perf_allow_*() helpers
> also operate implicitly on the current task. How do other PMU drivers avoid
> falling into this trap?

I'm not as familiar with the other PMU drivers. I quickly tried grepping
something related in the cs_etm drivers as they use CONTEXTIDR as well,
but couldn't find references to perfmon_capable() or similar checks.

Grepping for "perf_allow_" inside of drivers doesn't yield results.
There's some gpu driver that has similar perfmon_capable() checks but
unlike spe, they error out if they don't pass (drivers/gpu/drm/i915/i915_perf.c).

>
>> One way to fix this is by caching the value of the CX bit during the
>> initialization of the PMU event, so that it remains consistent for the
>> duration of the session.
> It doesn't feel right to stash this in 'struct arm_spe_pmu' during event
> initialisation -- wouldn't that allow perf to continue creating new events
> with CX set, even if the paranoid sysctl was changed dynamically? Instead,
> I think it would be better if the capabilities were stash in the event
> itself somehow at initialisation time.

I hadn't considered this. Makes more sense to store in the perf_event
or via some type of mapping in the struct spe_pmu if not possible. Do
you have any idea for the former? Or an idiomatic structure from the
kernel for the later?

Thanks,
German

>
> Will


From ardb at kernel.org  Tue Jan 18 06:10:50 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 18 Jan 2022 15:10:50 +0100
Subject: [boot-wrapper PATCH v2 3/9] Makefile: Tell compiler to generate
 bare-metal code
In-Reply-To: <20220118125203.272ccf8c@donnerap.cambridge.arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-4-andre.przywara@arm.com>
 <YdhF7kluP5vwzDf4@FVFF77S0Q05N>
 <20220107143811.3d193704@donnerap.cambridge.arm.com>
 <Yd1qSjmu61hXGZgd@FVFF77S0Q05N>
 <20220118125203.272ccf8c@donnerap.cambridge.arm.com>
Message-ID: <CAMj1kXG0wBW3WxE__mmZH7PdVkizCvCnCNuOoURER7zYJO4YcQ@mail.gmail.com>

On Tue, 18 Jan 2022 at 13:53, Andre Przywara <andre.przywara at arm.com> wrote:
>
> On Tue, 11 Jan 2022 11:30:18 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
>
> > I don't understand why we need:
> >
> >       -fno-common
>
> I think most projects use that to put uninitialised global variables in
> .BSS, to save space in .data and thus the image file. I see it used in all
> of Linux, U-Boot and TF-A. With the kernel image absolutely dwarfing any
> actual boot-wrapper code in our ELF file, I think we are not particularly
> sensitive about code/file size, though, are we?
>

I'd keep this for correctness, otherwise unrelated uninitialized
globals with external linkage that happen to have the same name will
be merged into a single variable, instead of causing a duplicate
symbol error at link time (which is usually the preferred result)


From alexandru.elisei at arm.com  Tue Jan 18 06:11:09 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 18 Jan 2022 14:11:09 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <20211129200150.351436-15-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
Message-ID: <YebKfXhj08h9PoXb@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> Support injecting exceptions and performing exception returns to and
> from virtual EL2.  This must be done entirely in software except when
> taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
> == {1,1}  (a VHE guest hypervisor).

Might be useful to explain why emulation shouldn't (or can't) be done in
software in that particular case.

It looks to me like kvm_inject_nested() and kvm_emulate_nested_eret()
handles the above case, so why does does it say that emulation must not be
done entirely in software?

> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> [maz: switch to common exception injection framework]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  .mailmap                             |   1 +
>  arch/arm64/include/asm/kvm_arm.h     |  17 +++
>  arch/arm64/include/asm/kvm_emulate.h |  10 ++
>  arch/arm64/include/asm/kvm_host.h    |   1 +
>  arch/arm64/kvm/Makefile              |   2 +-
>  arch/arm64/kvm/emulate-nested.c      | 176 +++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/exception.c       |  49 ++++++--
>  arch/arm64/kvm/inject_fault.c        |  68 +++++++++--
>  arch/arm64/kvm/trace_arm.h           |  59 +++++++++
>  9 files changed, 362 insertions(+), 21 deletions(-)
>  create mode 100644 arch/arm64/kvm/emulate-nested.c
> 
> diff --git a/.mailmap b/.mailmap
> index 14314e3c5d5e..491238a888cb 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -167,6 +167,7 @@ Jeff Layton <jlayton at kernel.org> <jlayton at redhat.com>
>  Jens Axboe <axboe at suse.de>
>  Jens Osterkamp <Jens.Osterkamp at de.ibm.com>
>  Jernej Skrabec <jernej.skrabec at gmail.com> <jernej.skrabec at siol.net>
> +<jintack at cs.columbia.edu> <jintack.lim at linaro.org>
>  Jiri Slaby <jirislaby at kernel.org> <jirislaby at gmail.com>
>  Jiri Slaby <jirislaby at kernel.org> <jslaby at novell.com>
>  Jiri Slaby <jirislaby at kernel.org> <jslaby at suse.com>
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index a39fcf318c77..589a6b92d741 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -359,4 +359,21 @@
>  #define CPACR_EL1_TTA		(1 << 28)
>  #define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
>  
> +#define kvm_mode_names				\
> +	{ PSR_MODE_EL0t,	"EL0t" },	\
> +	{ PSR_MODE_EL1t,	"EL1t" },	\
> +	{ PSR_MODE_EL1h,	"EL1h" },	\
> +	{ PSR_MODE_EL2t,	"EL2t" },	\
> +	{ PSR_MODE_EL2h,	"EL2h" },	\
> +	{ PSR_MODE_EL3t,	"EL3t" },	\
> +	{ PSR_MODE_EL3h,	"EL3h" },	\
> +	{ PSR_AA32_MODE_USR,	"32-bit USR" },	\
> +	{ PSR_AA32_MODE_FIQ,	"32-bit FIQ" },	\
> +	{ PSR_AA32_MODE_IRQ,	"32-bit IRQ" },	\
> +	{ PSR_AA32_MODE_SVC,	"32-bit SVC" },	\
> +	{ PSR_AA32_MODE_ABT,	"32-bit ABT" },	\
> +	{ PSR_AA32_MODE_HYP,	"32-bit HYP" },	\
> +	{ PSR_AA32_MODE_UND,	"32-bit UND" },	\
> +	{ PSR_AA32_MODE_SYS,	"32-bit SYS" }
> +
>  #endif /* __ARM64_KVM_ARM_H__ */
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index f4b079945d0f..46c849ba281e 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -33,6 +33,12 @@ enum exception_type {
>  	except_type_serror	= 0x180,
>  };
>  
> +#define kvm_exception_type_names		\
> +	{ except_type_sync,	"SYNC"   },	\
> +	{ except_type_irq,	"IRQ"    },	\
> +	{ except_type_fiq,	"FIQ"    },	\
> +	{ except_type_serror,	"SERROR" }
> +
>  bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
>  void kvm_skip_instr32(struct kvm_vcpu *vcpu);
>  
> @@ -41,6 +47,10 @@ void kvm_inject_vabt(struct kvm_vcpu *vcpu);
>  void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
>  void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
>  
> +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
> +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
> +int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
> +
>  static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
>  {
>  	return !(vcpu->arch.hcr_el2 & HCR_RW);
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 4f642a2e9c34..7b6fe18ee450 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -477,6 +477,7 @@ struct kvm_vcpu_arch {
>  #define KVM_ARM64_EXCEPT_AA64_ELx_SERR	(3 << 9)
>  #define KVM_ARM64_EXCEPT_AA64_EL1	(0 << 11)
>  #define KVM_ARM64_EXCEPT_AA64_EL2	(1 << 11)
> +#define KVM_ARM64_EXCEPT_AA64_EL_MASK	(1 << 11)
>  
>  /*
>   * Overlaps with KVM_ARM64_EXCEPT_MASK on purpose so that it can't be
> diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> index 989bb5dad2c8..1f602526e9a2 100644
> --- a/arch/arm64/kvm/Makefile
> +++ b/arch/arm64/kvm/Makefile
> @@ -16,7 +16,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
>  	 inject_fault.o va_layout.o handle_exit.o \
>  	 guest.o debug.o reset.o sys_regs.o \
>  	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
> -	 arch_timer.o trng.o\
> +	 arch_timer.o trng.o emulate-nested.o \
>  	 vgic/vgic.o vgic/vgic-init.o \
>  	 vgic/vgic-irqfd.o vgic/vgic-v2.o \
>  	 vgic/vgic-v3.o vgic/vgic-v4.o \
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> new file mode 100644
> index 000000000000..339e8272b01e
> --- /dev/null
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (C) 2016 - Linaro and Columbia University
> + * Author: Jintack Lim <jintack.lim at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.

Wouldn't an SPDX license identifier be better here?

> + */
> +
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
> +
> +#include "hyp/include/hyp/adjust_pc.h"
> +
> +#include "trace.h"
> +
> +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> +{
> +	u64 spsr, elr, mode;
> +	bool direct_eret;
> +
> +	/*
> +	 * Going through the whole put/load motions is a waste of time
> +	 * if this is a VHE guest hypervisor returning to its own
> +	 * userspace, or the hypervisor performing a local exception
> +	 * return. No need to save/restore registers, no need to
> +	 * switch S2 MMU. Just do the canonical ERET.
> +	 */
> +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +
> +	direct_eret  = (mode == PSR_MODE_EL0t &&
> +			vcpu_el2_e2h_is_set(vcpu) &&
> +			vcpu_el2_tge_is_set(vcpu));
> +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> +
> +	if (direct_eret) {
> +		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
> +		*vcpu_cpsr(vcpu) = spsr;
> +		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
> +		return;
> +	}
> +
> +	preempt_disable();
> +	kvm_arch_vcpu_put(vcpu);
> +
> +	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
> +
> +	trace_kvm_nested_eret(vcpu, elr, spsr);
> +
> +	/*
> +	 * Note that the current exception level is always the virtual EL2,
> +	 * since we set HCR_EL2.NV bit only when entering the virtual EL2.
> +	 */
> +	*vcpu_pc(vcpu) = elr;
> +	*vcpu_cpsr(vcpu) = spsr;
> +
> +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> +	preempt_enable();
> +}
> +
> +static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2,
> +				     enum exception_type type)
> +{
> +	trace_kvm_inject_nested_exception(vcpu, esr_el2, type);
> +
> +	switch (type) {
> +	case except_type_sync:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_SYNC;
> +		break;
> +	case except_type_irq:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_IRQ;
> +		break;
> +	default:
> +		WARN_ONCE(1, "Unsupported EL2 exception injection %d\n", type);
> +	}
> +
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL2		|
> +			     KVM_ARM64_PENDING_EXCEPTION);
> +
> +	vcpu_write_sys_reg(vcpu, esr_el2, ESR_EL2);
> +}
> +
> +/*
> + * Emulate taking an exception to EL2.
> + * See ARM ARM J8.1.2 AArch64.TakeException()
> + */
> +static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
> +			     enum exception_type type)
> +{
> +	u64 pstate, mode;
> +	bool direct_inject;
> +
> +	if (!nested_virt_in_use(vcpu)) {
> +		kvm_err("Unexpected call to %s for the non-nesting configuration\n",
> +				__func__);
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * As for ERET, we can avoid doing too much on the injection path by
> +	 * checking that we either took the exception from a VHE host
> +	 * userspace or from vEL2. In these cases, there is no change in
> +	 * translation regime (or anything else), so let's do as little as
> +	 * possible.
> +	 */
> +	pstate = *vcpu_cpsr(vcpu);
> +	mode = pstate & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +
> +	direct_inject  = (mode == PSR_MODE_EL0t &&
> +			  vcpu_el2_e2h_is_set(vcpu) &&
> +			  vcpu_el2_tge_is_set(vcpu));
> +	direct_inject |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> +
> +	if (direct_inject) {
> +		kvm_inject_el2_exception(vcpu, esr_el2, type);
> +		return 1;
> +	}
> +
> +	preempt_disable();
> +	kvm_arch_vcpu_put(vcpu);
> +
> +	kvm_inject_el2_exception(vcpu, esr_el2, type);
> +
> +	/*
> +	 * A hard requirement is that a switch between EL1 and EL2
> +	 * contexts has to happen between a put/load, so that we can
> +	 * pick the correct timer and interrupt configuration, among
> +	 * other things.
> +	 *
> +	 * Make sure the exception actually took place before we load
> +	 * the new context.
> +	 */
> +	__kvm_adjust_pc(vcpu);
> +
> +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> +	preempt_enable();
> +
> +	return 1;
> +}
> +
> +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
> +{
> +	return kvm_inject_nested(vcpu, esr_el2, except_type_sync);
> +}
> +
> +int kvm_inject_nested_irq(struct kvm_vcpu *vcpu)

I assume this is actually injecting an IRQ to the guest's virtual EL2, not
a nested interrupt, right?

> +{
> +	/*
> +	 * Do not inject an irq if the:
> +	 *  - Current exception level is EL2, and
> +	 *  - virtual HCR_EL2.TGE == 0
> +	 *  - virtual HCR_EL2.IMO == 0
> +	 *
> +	 * See Table D1-17 "Physical interrupt target and masking when EL3 is
> +	 * not implemented and EL2 is implemented" in ARM DDI 0487C.a.

That's now Table D1-13 in ARM DDI 0487G.a, the latest Arm ARM as of now, in
case you want to update the comment. The table name isn't unchanged, so
that can be used to find it in newer versions, so I don't think the update
is strictly necessary.

I assume the comment refers to the first line of the table, as that's the
only case when an interrupt is unconditionally not taken when asserted.
But according to the table, the interrupt is not taken when the *target* EL
is EL1 and the CPU is executing at EL2. Which makes me very confused. Isn't
this function supposed to inject an interrupt to virtual EL2? If this
function also injects interrupts to virtual EL1, why doesn't it also check
that the target EL is EL1 before returning?

> +	 */
> +
> +	if (vcpu_mode_el2(vcpu) && !vcpu_el2_tge_is_set(vcpu) &&
> +	    !(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_IMO))
> +		return 1;
> +
> +	/* esr_el2 value doesn't matter for exits due to irqs. */
> +	return kvm_inject_nested(vcpu, 0, except_type_irq);
> +}
> diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> index 0418399e0a20..4ef5e86efd8b 100644
> --- a/arch/arm64/kvm/hyp/exception.c
> +++ b/arch/arm64/kvm/hyp/exception.c
> @@ -13,6 +13,7 @@
>  #include <hyp/adjust_pc.h>
>  #include <linux/kvm_host.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
>  
>  #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__)
>  #error Hypervisor code only!
> @@ -22,7 +23,9 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
>  {
>  	u64 val;
>  
> -	if (__vcpu_read_sys_reg_from_cpu(reg, &val))
> +	if (unlikely(nested_virt_in_use(vcpu)))
> +		return vcpu_read_sys_reg(vcpu, reg);
> +	else if (__vcpu_read_sys_reg_from_cpu(reg, &val))
>  		return val;

I find the above unintuitive. The original code duplicated the
functionality from sys_regs.c::vcpu_read_sys_reg() in order to be able to
run the code at EL2 in the protected KVM case. So why are we now adding
back the dependency to the EL1 code? Yes, the call to vcpu_read_sys_reg()
is never compiled because of how nested_virt_in_use() is defined, but still
looks unconsistent with the purpose of the function (and this file).

After careful digging, I realized why this change is needed:
kvm_inject_nested() calls __kvm_adjust_pc() after a vcpu_put(), so the
function needs to check vcpu->arch.sysregs_loaded_on_cpu, which now can be
false. Why not copy the body of vcpu_read_sys_reg(), which is what
__vcpu_read_sys_reg is supposed to do? With a comment explaining why
sysregs_loaded_on_cpu can be false, I think the code would be a lot more
understandable.

Or is it that you want all VCPU register accesses to be done with
vcpu_read_sys_reg() when the VCPU has the EL2 feature?

>  
>  	return __vcpu_sys_reg(vcpu, reg);
> @@ -30,14 +33,24 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
>  
>  static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
>  {
> -	if (__vcpu_write_sys_reg_to_cpu(val, reg))
> -		return;
> -
> -	 __vcpu_sys_reg(vcpu, reg) = val;
> +	if (unlikely(nested_virt_in_use(vcpu)))
> +		vcpu_write_sys_reg(vcpu, val, reg);
> +	else if (!__vcpu_write_sys_reg_to_cpu(val, reg))
> +		__vcpu_sys_reg(vcpu, reg) = val;
>  }
>  
> -static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
> +static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
> +			      u64 val)
>  {
> +	if (unlikely(nested_virt_in_use(vcpu))) {
> +		if (target_mode == PSR_MODE_EL1h)
> +			vcpu_write_sys_reg(vcpu, val, SPSR_EL1);
> +		else
> +			vcpu_write_sys_reg(vcpu, val, SPSR_EL2);
> +
> +		return;
> +	}
> +
>  	write_sysreg_el1(val, SYS_SPSR);
>  }
>  
> @@ -97,6 +110,11 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
>  		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
>  		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
>  		break;
> +	case PSR_MODE_EL2h:
> +		vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
> +		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
> +		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
> +		break;
>  	default:
>  		/* Don't do that */
>  		BUG();
> @@ -149,7 +167,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
>  	new |= target_mode;
>  
>  	*vcpu_cpsr(vcpu) = new;
> -	__vcpu_write_spsr(vcpu, old);
> +	__vcpu_write_spsr(vcpu, target_mode, old);
>  }
>  
>  /*
> @@ -320,11 +338,22 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
>  		      KVM_ARM64_EXCEPT_AA64_EL1):
>  			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync);
>  			break;
> +
> +		case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> +		      KVM_ARM64_EXCEPT_AA64_EL2):
> +			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_sync);
> +			break;
> +
> +		case (KVM_ARM64_EXCEPT_AA64_ELx_IRQ |
> +		      KVM_ARM64_EXCEPT_AA64_EL2):
> +			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_irq);
> +			break;
> +
>  		default:
>  			/*
> -			 * Only EL1_SYNC makes sense so far, EL2_{SYNC,IRQ}
> -			 * will be implemented at some point. Everything
> -			 * else gets silently ignored.
> +			 * Only EL1_SYNC and EL2_{SYNC,IRQ} makes
> +			 * sense so far. Everything else gets silently
> +			 * ignored.
>  			 */
>  			break;
>  		}
> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> index b47df73e98d7..5dcf3f8b08b8 100644
> --- a/arch/arm64/kvm/inject_fault.c
> +++ b/arch/arm64/kvm/inject_fault.c
> @@ -12,19 +12,58 @@
>  
>  #include <linux/kvm_host.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/esr.h>
>  
> +static void pend_sync_exception(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
> +			     KVM_ARM64_PENDING_EXCEPTION);
> +
> +	/* If not nesting, EL1 is the only possible exception target */
> +	if (likely(!nested_virt_in_use(vcpu))) {
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		return;
> +	}
> +
> +	/*
> +	 * With NV, we need to pick between EL1 and EL2. Note that we
> +	 * never deal with a nesting exception here, hence never

I don't understand what "a nesting exception" refers to. In emulate_nested.c,
the comment for kvm_inject_nested() says that it emulates taking an exception to
EL2, so I assume a *nested* exception is an exception injected to guest virtual
EL2. But what is a *nesting* exception? Am I misunderstanding something?

> +	 * changing context, and the exception itself can be delayed
> +	 * until the next entry.
> +	 */
> +	switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
> +	case PSR_MODE_EL2h:
> +	case PSR_MODE_EL2t:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> +		break;
> +	case PSR_MODE_EL1h:
> +	case PSR_MODE_EL1t:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		break;
> +	case PSR_MODE_EL0t:
> +		if (vcpu_el2_tge_is_set(vcpu) & HCR_TGE)

Doesn't vcpu_el2_tge_is_set() already return true if HCR_TGE is set?

> +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> +		else
> +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		break;
> +	default:
> +		BUG();
> +	}
> +}
> +
> +static bool match_target_el(struct kvm_vcpu *vcpu, unsigned long target)
> +{
> +	return (vcpu->arch.flags & KVM_ARM64_EXCEPT_AA64_EL_MASK) == target;
> +}
> +
>  static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
>  {
>  	unsigned long cpsr = *vcpu_cpsr(vcpu);
>  	bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
>  	u32 esr = 0;
>  
> -	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1		|
> -			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
> -			     KVM_ARM64_PENDING_EXCEPTION);
> -
> -	vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
> +	pend_sync_exception(vcpu);
>  
>  	/*
>  	 * Build an {i,d}abort, depending on the level and the
> @@ -45,16 +84,22 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
>  	if (!is_iabt)
>  		esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
>  
> -	vcpu_write_sys_reg(vcpu, esr | ESR_ELx_FSC_EXTABT, ESR_EL1);
> +	esr |= ESR_ELx_FSC_EXTABT;
> +
> +	if (match_target_el(vcpu, KVM_ARM64_EXCEPT_AA64_EL1)) {
> +		vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
> +		vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
> +	} else {
> +		vcpu_write_sys_reg(vcpu, addr, FAR_EL2);
> +		vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
> +	}
>  }
>  
>  static void inject_undef64(struct kvm_vcpu *vcpu)
>  {
>  	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
>  
> -	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1		|
> -			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
> -			     KVM_ARM64_PENDING_EXCEPTION);
> +	pend_sync_exception(vcpu);
>  
>  	/*
>  	 * Build an unknown exception, depending on the instruction
> @@ -63,7 +108,10 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
>  	if (kvm_vcpu_trap_il_is32bit(vcpu))
>  		esr |= ESR_ELx_IL;
>  
> -	vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
> +	if (match_target_el(vcpu, KVM_ARM64_EXCEPT_AA64_EL1))
> +		vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
> +	else
> +		vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
>  }
>  
>  #define DFSR_FSC_EXTABT_LPAE	0x10
> diff --git a/arch/arm64/kvm/trace_arm.h b/arch/arm64/kvm/trace_arm.h
> index 33e4e7dd2719..f3e46a976125 100644
> --- a/arch/arm64/kvm/trace_arm.h
> +++ b/arch/arm64/kvm/trace_arm.h
> @@ -2,6 +2,7 @@
>  #if !defined(_TRACE_ARM_ARM64_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
>  #define _TRACE_ARM_ARM64_KVM_H
>  
> +#include <asm/kvm_emulate.h>
>  #include <kvm/arm_arch_timer.h>
>  #include <linux/tracepoint.h>
>  
> @@ -301,6 +302,64 @@ TRACE_EVENT(kvm_timer_emulate,
>  		  __entry->timer_idx, __entry->should_fire)
>  );
>  
> +TRACE_EVENT(kvm_nested_eret,
> +	TP_PROTO(struct kvm_vcpu *vcpu, unsigned long elr_el2,
> +		 unsigned long spsr_el2),
> +	TP_ARGS(vcpu, elr_el2, spsr_el2),
> +
> +	TP_STRUCT__entry(
> +		__field(struct kvm_vcpu *,	vcpu)
> +		__field(unsigned long,		elr_el2)
> +		__field(unsigned long,		spsr_el2)
> +		__field(unsigned long,		target_mode)
> +		__field(unsigned long,		hcr_el2)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->vcpu = vcpu;
> +		__entry->elr_el2 = elr_el2;
> +		__entry->spsr_el2 = spsr_el2;
> +		__entry->target_mode = spsr_el2 & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +		__entry->hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
> +	),
> +
> +	TP_printk("elr_el2: 0x%lx spsr_el2: 0x%08lx (M: %s) hcr_el2: %lx",
> +		  __entry->elr_el2, __entry->spsr_el2,
> +		  __print_symbolic(__entry->target_mode, kvm_mode_names),
> +		  __entry->hcr_el2)
> +);
> +
> +TRACE_EVENT(kvm_inject_nested_exception,
> +	TP_PROTO(struct kvm_vcpu *vcpu, u64 esr_el2, int type),
> +	TP_ARGS(vcpu, esr_el2, type),
> +
> +	TP_STRUCT__entry(
> +		__field(struct kvm_vcpu *,		vcpu)
> +		__field(unsigned long,			esr_el2)
> +		__field(int,				type)
> +		__field(unsigned long,			spsr_el2)
> +		__field(unsigned long,			pc)
> +		__field(unsigned long,			source_mode)
> +		__field(unsigned long,			hcr_el2)
> +	),
> +
> +	TP_fast_assign(
> +		__entry->vcpu = vcpu;
> +		__entry->esr_el2 = esr_el2;
> +		__entry->type = type;
> +		__entry->spsr_el2 = *vcpu_cpsr(vcpu);
> +		__entry->pc = *vcpu_pc(vcpu);
> +		__entry->source_mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +		__entry->hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
> +	),
> +
> +	TP_printk("%s: esr_el2 0x%lx elr_el2: 0x%lx spsr_el2: 0x%08lx (M: %s) hcr_el2: %lx",
> +		  __print_symbolic(__entry->type, kvm_exception_type_names),
> +		  __entry->esr_el2, __entry->pc, __entry->spsr_el2,
> +		  __print_symbolic(__entry->source_mode, kvm_mode_names),
> +		  __entry->hcr_el2)
> +);
> +
>  #endif /* _TRACE_ARM_ARM64_KVM_H */
>  
>  #undef TRACE_INCLUDE_PATH
> -- 
> 2.30.2
> 


From hverkuil-cisco at xs4all.nl  Tue Jan 18 06:13:20 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 18 Jan 2022 15:13:20 +0100
Subject: [BUG] pinctrl: reg-fixed-voltage usb0-vbus: error -EINVAL: can't
 get GPIO
In-Reply-To: <Yea3rBmY+MO4AhhV@Red>
References: <Yea3rBmY+MO4AhhV@Red>
Message-ID: <2f82dbe8-50d6-d905-9065-d3869948aa06@xs4all.nl>

On 1/18/22 13:50, Corentin Labbe wrote:
> Hello
> 
> As reported on old googlegroup sunxi mainling list, on linux-next-20220118, USB storage fail to bring up on orangepiPC.
> We can see some error logs in dmesg:
> reg-fixed-voltage usb0-vbus: error -EINVAL: can't get GPIO
> reg-fixed-voltage: probe of usb0-vbus failed with error -22
> 
> This is bisected to: 8df89a7cbc63c7598c00611ad17b67e8d5b4fad3 pinctrl-sunxi: don't call pinctrl_gpio_direction()
> 
> Reverting this commit lead to a working USB storage being setuped.

Hmm, I'll bet it's EPROBE_DEFER related.

The original call (pre that commit) of pinctrl_gpio_direction_output() checks
if the pin controller could find the pin (pinctrl_get_device_gpio_range()).

That doesn't happen in the new code.

The sunxi appears to have two pincontrollers in the device tree (&pio and &r_pio),
that might be part of the reason this is an issue here.

Linus, should there be a check somewhere for a missing pincontroller in
gpiod_get_index()? I suspect that before my commit it was the gpiod_configure_flags
call in that function that returned -EPROBE_DEFER, but I'm not completely certain.

If someone can give me a hint about what should be done, then I can make a patch.

The alternative is to revert this sunxi patch, but perhaps this is a deeper
problem with these pincontroller drivers that set the direction directly
instead of going through pinctrl_gpio_direction_output().

Corentin, it would help me if you can figure out where the EPROBE_DEFER is
returned (pre-commit) in drivers/pinctrl/core.c. Probably pinctrl_get_device_gpio_range().

And I'd love to have the WARN_ON(1) output from just before the 'return -EPROBE_DEFER'.

Regards,

	Hans

> 
> Regards


From german.gomez at arm.com  Tue Jan 18 06:13:42 2022
From: german.gomez at arm.com (German Gomez)
Date: Tue, 18 Jan 2022 14:13:42 +0000
Subject: [RFC PATCH 2/2] perf: arm_spe: Enable CONTEXT packets in SPE
 traces if the profiler runs in CPU mode.
In-Reply-To: <20220118095258.GA16547@willie-the-truck>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-3-german.gomez@arm.com>
 <20220118095258.GA16547@willie-the-truck>
Message-ID: <a5bc60d9-fff0-abf9-c268-dcb75b790bfb@arm.com>


On 18/01/2022 09:52, Will Deacon wrote:
> On Mon, Jan 17, 2022 at 12:44:32PM +0000, German Gomez wrote:
>> Enable CONTEXT packets in SPE traces if the profiler runs in CPU mode.
>> This is no less permissive than the existing behavior for the following
>> reason:
>>
>> If perf_event_paranoid <= 0, then non perfmon_capable() users can open
>> a per-CPU event. With a per-CPU event, unpriviledged users are allowed
>> to profile _all_ processes, even ones owned by root.
>>
>> Without this change, users could see kernel addresses, root processes,
>> etc, but not gather the PIDs of those processes. The PID is probably the
>> least sensitive of all the information.
>>
>> It would be more idiomatic to check the perf_event_paranoid level with
>> perf_allow_cpu(), but this function is not exported so cannot be used
>> from a module. Looking for cpu != -1 is the indirect way of checking
>> the same thing as it could never get to arm_spe_pmu_event_init() without
>> perf_event_paranoid <= 0.
> perf_allow_cpu() is a static inline so there's no need to export it. What's
> missing?

We were still running into build errors:

ERROR: modpost: "security_perf_event_open" [drivers/perf/arm_spe_pmu.ko] undefined!
ERROR: modpost: "sysctl_perf_event_paranoid" [drivers/perf/arm_spe_pmu.ko] undefined

>
> Will


From jszhang at kernel.org  Tue Jan 18 06:13:03 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Tue, 18 Jan 2022 22:13:03 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <20220116133847.GE2388@MiWiFi-R3L-srv>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv>
Message-ID: <YebK70Sx4w8zLfj/@xhacker>

On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> Hi Jisheng,

Hi Baoquan,

> 
> On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > and increase compile coverage.
> 
> I go through this patchset, You mention the benefits it brings are
> 1) simplity the code;
> 2) increase compile coverage;
> 
> For benefit 1), it mainly removes the dummy function in x86, arm and
> arm64, right?

Another benefit: remove those #ifdef #else #endif usage. Recently, I
fixed a bug due to lots of "#ifdefs":
http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html

> 
> For benefit 2), increasing compile coverage, could you tell more how it
> achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> purpose? Please forgive my poor compiling knowledge.

Just my humble opinion, let's compare the code::

#ifdef CONFIG_KEXEC_CORE

code block A;

#endif

If KEXEC_CORE is disabled, code block A won't be compiled at all, the
preprocessor will remove code block A;

If we convert the code to:

if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
	code block A;
}

Even if KEXEC_CORE is disabled, code block A is still compiled.

Thanks


From peter.hilber at opensynergy.com  Tue Jan 18 06:20:42 2022
From: peter.hilber at opensynergy.com (Peter Hilber)
Date: Tue, 18 Jan 2022 15:20:42 +0100
Subject: [PATCH v7 14/16] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20211220213042.GL6207@e120937-lin>
References: <20211129191156.29322-1-cristian.marussi@arm.com>
 <20211129191156.29322-15-cristian.marussi@arm.com>
 <75e651e9-a273-5bd1-c7f7-37a072ad6608@opensynergy.com>
 <20211220213042.GL6207@e120937-lin>
Message-ID: <25455ab7-344c-10ec-318f-0681b88776ca@opensynergy.com>

On 20.12.21 22:30, Cristian Marussi wrote:
> On Fri, Dec 10, 2021 at 01:12:18PM +0100, Peter Hilber wrote:
>> On 29.11.21 20:11, Cristian Marussi wrote:
<snip>
>>> @@ -65,12 +69,22 @@ struct scmi_vio_channel {
>>>   * @input: SDU used for (delayed) responses and notifications
>>>   * @list: List which scmi_vio_msg may be part of
>>>   * @rx_len: Input SDU size in bytes, once input has been received
>>> + * @poll_idx: Last used index registered for polling purposes if this message
>>> + *	      transaction reply was configured for polling.
>>> + *	      Note that virtqueue used index is an unsigned 16-bit.
>>> + * @poll_lock: Protect access to @poll_idx.
>>>   */
>>>  struct scmi_vio_msg {
>>>  	struct scmi_msg_payld *request;
>>>  	struct scmi_msg_payld *input;
>>>  	struct list_head list;
>>>  	unsigned int rx_len;
>>> +#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
>>> +#define VIO_MSG_POLL_DONE	0xffffffffUL
>>
>> virtqueue_enable_cb_prepare() returns an "opaque unsigned value", so
>> this special value should not be used for .poll_idx.
>>
> 
> Yes you are right, but looking at comments in virtqueue_enable_cb_prepare()
> and virtqueue_poll()
> 
> /**
>  * virtqueue_enable_cb_prepare - restart callbacks after disable_cb
>  *
>  * This re-enables callbacks; it returns current queue state
>  * in an opaque unsigned value. This value should be later tested by
>  * virtqueue_poll, to detect a possible race between the driver
>  * checking for more work, and enabling callbacks.
> 
> 
> /**
>  * virtqueue_poll - query pending used buffers
>  * @_vq: the struct virtqueue we're talking about.
>  * @last_used_idx: virtqueue state (from call to virtqueue_enable_cb_prepare).
> 
> ... it seems to me that is exactly how I'm using it, and moreover I
> don't see any other way via the VirtIO API to grab that last_used_idx
> that I need for virtqueu_poll.
> 

I meant to say that the VIO_MSG_POLL_DONE special value should best not be put
into the .poll_idx (since the special value might in theory overlap with an
opaque value). Another variable could hold the special states VIO_MSG_POLL_DONE
and VIO_MSG_NOT_POLLED.


From peter.hilber at opensynergy.com  Tue Jan 18 06:21:03 2022
From: peter.hilber at opensynergy.com (Peter Hilber)
Date: Tue, 18 Jan 2022 15:21:03 +0100
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20211221140027.41524-1-cristian.marussi@arm.com>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
Message-ID: <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>

On 21.12.21 15:00, Cristian Marussi wrote:
> Add support for .mark_txdone and .poll_done transport operations to SCMI
> VirtIO transport as pre-requisites to enable atomic operations.
> 
> Add a Kernel configuration option to enable SCMI VirtIO transport polling
> and atomic mode for selected SCMI transactions while leaving it default
> disabled.
> 

Hi Cristian,

thanks for the update. I have some more remarks inline below.

My impression is that the virtio core does not expose helper functions suitable
to busy-poll for used buffers. But changing this might not be difficult. Maybe
more_used() from virtio_ring.c could be exposed via a wrapper?

Best regards,

Peter

> Cc: "Michael S. Tsirkin" <mst at redhat.com>
> Cc: Igor Skalkin <igor.skalkin at opensynergy.com>
> Cc: Peter Hilber <peter.hilber at opensynergy.com>
> Cc: virtualization at lists.linux-foundation.org
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
> v8 --> v9
> - check for deferred_wq existence before queueing work to avoid
>   race at driver removal time
> ---
>  drivers/firmware/arm_scmi/Kconfig  |  15 ++
>  drivers/firmware/arm_scmi/virtio.c | 298 ++++++++++++++++++++++++++---
>  2 files changed, 287 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index d429326433d1..7794bd41eaa0 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -118,6 +118,21 @@ config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
>  	  the ones implemented by kvmtool) and let the core Kernel VirtIO layer
>  	  take care of the needed conversions, say N.
>  
> +config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
> +	bool "Enable atomic mode for SCMI VirtIO transport"
> +	depends on ARM_SCMI_TRANSPORT_VIRTIO
> +	help
> +	  Enable support of atomic operation for SCMI VirtIO based transport.
> +
> +	  If you want the SCMI VirtIO based transport to operate in atomic
> +	  mode, avoiding any kind of sleeping behaviour for selected
> +	  transactions on the TX path, answer Y.
> +
> +	  Enabling atomic mode operations allows any SCMI driver using this
> +	  transport to optionally ask for atomic SCMI transactions and operate
> +	  in atomic context too, at the price of using a number of busy-waiting
> +	  primitives all over instead. If unsure say N.
> +
>  endif #ARM_SCMI_PROTOCOL
>  
>  config ARM_SCMI_POWER_DOMAIN
> diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
> index fd0f6f91fc0b..e54d14971c07 100644
> --- a/drivers/firmware/arm_scmi/virtio.c
> +++ b/drivers/firmware/arm_scmi/virtio.c
> @@ -3,8 +3,8 @@
>   * Virtio Transport driver for Arm System Control and Management Interface
>   * (SCMI).
>   *
> - * Copyright (C) 2020-2021 OpenSynergy.
> - * Copyright (C) 2021 ARM Ltd.
> + * Copyright (C) 2020-2022 OpenSynergy.
> + * Copyright (C) 2021-2022 ARM Ltd.
>   */
>  
>  /**
> @@ -38,6 +38,9 @@
>   * @vqueue: Associated virtqueue
>   * @cinfo: SCMI Tx or Rx channel
>   * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
> + * @deferred_tx_work: Worker for TX deferred replies processing
> + * @deferred_tx_wq: Workqueue for TX deferred replies
> + * @pending_cmds_list: List of pre-fetched commands queueud for later processing
>   * @is_rx: Whether channel is an Rx channel
>   * @ready: Whether transport user is ready to hear about channel
>   * @max_msg: Maximum number of pending messages for this channel.
> @@ -49,6 +52,9 @@ struct scmi_vio_channel {
>  	struct virtqueue *vqueue;
>  	struct scmi_chan_info *cinfo;
>  	struct list_head free_list;
> +	struct list_head pending_cmds_list;
> +	struct work_struct deferred_tx_work;
> +	struct workqueue_struct *deferred_tx_wq;
>  	bool is_rx;
>  	bool ready;
>  	unsigned int max_msg;
> @@ -65,12 +71,22 @@ struct scmi_vio_channel {
>   * @input: SDU used for (delayed) responses and notifications
>   * @list: List which scmi_vio_msg may be part of
>   * @rx_len: Input SDU size in bytes, once input has been received
> + * @poll_idx: Last used index registered for polling purposes if this message
> + *	      transaction reply was configured for polling.
> + *	      Note that since virtqueue used index is an unsigned 16-bit we can
> + *	      use some out-of-scale values to signify particular conditions.
> + * @poll_lock: Protect access to @poll_idx.
>   */
>  struct scmi_vio_msg {
>  	struct scmi_msg_payld *request;
>  	struct scmi_msg_payld *input;
>  	struct list_head list;
>  	unsigned int rx_len;
> +#define VIO_MSG_NOT_POLLED	0xeeeeeeeeUL
> +#define VIO_MSG_POLL_DONE	0xffffffffUL
> +	unsigned int poll_idx;
> +	/* lock to protect access to poll_idx. */
> +	spinlock_t poll_lock;
>  };
>  
>  /* Only one SCMI VirtIO device can possibly exist */
> @@ -81,40 +97,43 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
>  	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
>  }
>  
> +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
>  static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
>  			       struct scmi_vio_msg *msg,
>  			       struct device *dev)
>  {
>  	struct scatterlist sg_in;
>  	int rc;
> -	unsigned long flags;
>  
>  	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
>  
> -	spin_lock_irqsave(&vioch->lock, flags);
> -
>  	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
>  	if (rc)
>  		dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
>  	else
>  		virtqueue_kick(vioch->vqueue);
>  
> -	spin_unlock_irqrestore(&vioch->lock, flags);
> -
>  	return rc;
>  }
>  
> +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
> +static inline void scmi_vio_feed_vq_tx(struct scmi_vio_channel *vioch,
> +				       struct scmi_vio_msg *msg)
> +{
> +	spin_lock(&msg->poll_lock);
> +	msg->poll_idx = VIO_MSG_NOT_POLLED;
> +	spin_unlock(&msg->poll_lock);
> +
> +	list_add(&msg->list, &vioch->free_list);
> +}
> +
>  static void scmi_finalize_message(struct scmi_vio_channel *vioch,
>  				  struct scmi_vio_msg *msg)
>  {
> -	if (vioch->is_rx) {
> +	if (vioch->is_rx)
>  		scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
> -	} else {
> -		/* Here IRQs are assumed to be already disabled by the caller */
> -		spin_lock(&vioch->lock);
> -		list_add(&msg->list, &vioch->free_list);
> -		spin_unlock(&vioch->lock);
> -	}
> +	else
> +		scmi_vio_feed_vq_tx(vioch, msg);
>  }
>  
>  static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> @@ -144,6 +163,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  			virtqueue_disable_cb(vqueue);
>  			cb_enabled = false;
>  		}
> +
>  		msg = virtqueue_get_buf(vqueue, &length);
>  		if (!msg) {
>  			if (virtqueue_enable_cb(vqueue))
> @@ -157,7 +177,9 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  			scmi_rx_callback(vioch->cinfo,
>  					 msg_read_header(msg->input), msg);
>  
> +			spin_lock(&vioch->lock);
>  			scmi_finalize_message(vioch, msg);
> +			spin_unlock(&vioch->lock);
>  		}
>  
>  		/*
> @@ -176,6 +198,34 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  	spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
>  }
>  
> +static void scmi_vio_deferred_tx_worker(struct work_struct *work)
> +{
> +	unsigned long flags;
> +	struct scmi_vio_channel *vioch;
> +	struct scmi_vio_msg *msg, *tmp;
> +
> +	vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
> +
> +	/* Process pre-fetched messages */
> +	spin_lock_irqsave(&vioch->lock, flags);
> +
> +	/* Scan the list of possibly pre-fetched messages during polling. */
> +	list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
> +		list_del(&msg->list);
> +
> +		scmi_rx_callback(vioch->cinfo,
> +				 msg_read_header(msg->input), msg);
> +
> +		/* Free the processed message once done */
> +		scmi_vio_feed_vq_tx(vioch, msg);
> +	}
> +
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	/* Process possibly still pending messages */
> +	scmi_vio_complete_cb(vioch->vqueue);
> +}
> +
>  static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
>  
>  static vq_callback_t *scmi_vio_complete_callbacks[] = {
> @@ -244,6 +294,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  
>  	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
>  
> +	/* Setup a deferred worker for polling. */
> +	if (tx && !vioch->deferred_tx_wq) {
> +		vioch->deferred_tx_wq =
> +			alloc_workqueue(dev_name(&scmi_vdev->dev),
> +					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
> +					0);
> +		if (!vioch->deferred_tx_wq)
> +			return -ENOMEM;
> +
> +		INIT_WORK(&vioch->deferred_tx_work,
> +			  scmi_vio_deferred_tx_worker);
> +	}
> +
>  	for (i = 0; i < vioch->max_msg; i++) {
>  		struct scmi_vio_msg *msg;
>  
> @@ -257,6 +320,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  						    GFP_KERNEL);
>  			if (!msg->request)
>  				return -ENOMEM;
> +			spin_lock_init(&msg->poll_lock);
>  		}
>  
>  		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
> @@ -264,13 +328,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  		if (!msg->input)
>  			return -ENOMEM;
>  
> -		if (tx) {
> -			spin_lock_irqsave(&vioch->lock, flags);
> -			list_add_tail(&msg->list, &vioch->free_list);
> -			spin_unlock_irqrestore(&vioch->lock, flags);
> -		} else {
> +		spin_lock_irqsave(&vioch->lock, flags);
> +		if (tx)
> +			scmi_vio_feed_vq_tx(vioch, msg);
> +		else
>  			scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
> -		}
> +		spin_unlock_irqrestore(&vioch->lock, flags);
>  	}
>  
>  	spin_lock_irqsave(&vioch->lock, flags);
> @@ -291,11 +354,22 @@ static int virtio_chan_free(int id, void *p, void *data)
>  	unsigned long flags;
>  	struct scmi_chan_info *cinfo = p;
>  	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +	void *deferred_wq = NULL;
>  
>  	spin_lock_irqsave(&vioch->ready_lock, flags);
>  	vioch->ready = false;
>  	spin_unlock_irqrestore(&vioch->ready_lock, flags);
>  
> +	spin_lock_irqsave(&vioch->lock, flags);
> +	if (!vioch->is_rx && vioch->deferred_tx_wq) {
> +		deferred_wq = vioch->deferred_tx_wq;
> +		vioch->deferred_tx_wq = NULL;
> +	}
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	if (deferred_wq)
> +		destroy_workqueue(deferred_wq);
> +
>  	scmi_free_channel(cinfo, data, id);
>  
>  	spin_lock_irqsave(&vioch->lock, flags);
> @@ -324,7 +398,8 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
>  	}
>  
>  	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
> -	list_del(&msg->list);
> +	/* Re-init element so we can discern anytime if it is still in-flight */
> +	list_del_init(&msg->list);
>  
>  	msg_tx_prepare(msg->request, xfer);
>  
> @@ -337,6 +412,19 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
>  		dev_err(vioch->cinfo->dev,
>  			"failed to add to TX virtqueue (%d)\n", rc);
>  	} else {
> +		/*
> +		 * If polling was requested for this transaction:
> +		 *  - retrieve last used index (will be used as polling reference)

The virtqueue_add_sgs() called before already exposed the message to the virtio
device, so a fast response might have arrived already, so the reference value
might unexpectedly correspond to the current message.

> +		 *  - bind the polled message to the xfer via .priv
> +		 */
> +		if (xfer->hdr.poll_completion) {
> +			spin_lock(&msg->poll_lock);
> +			msg->poll_idx =
> +				virtqueue_enable_cb_prepare(vioch->vqueue);
> +			spin_unlock(&msg->poll_lock);
> +			/* Ensure initialized msg is visibly bound to xfer */
> +			smp_store_mb(xfer->priv, msg);
> +		}
>  		virtqueue_kick(vioch->vqueue);
>  	}
>  
> @@ -350,10 +438,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo,
>  {
>  	struct scmi_vio_msg *msg = xfer->priv;
>  
> -	if (msg) {
> +	if (msg)
>  		msg_fetch_response(msg->input, msg->rx_len, xfer);
> -		xfer->priv = NULL;
> -	}
>  }
>  
>  static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
> @@ -361,10 +447,166 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
>  {
>  	struct scmi_vio_msg *msg = xfer->priv;
>  
> -	if (msg) {
> +	if (msg)
>  		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
> -		xfer->priv = NULL;
> +}
> +
> +/**
> + * virtio_mark_txdone  - Mark transmission done
> + *
> + * Free only successfully completed polling transfer messages.
> + *
> + * Note that in the SCMI VirtIO transport we never explicitly release timed-out
> + * messages by forcibly re-adding them to the free-list, even on timeout, inside
> + * the TX code path; we instead let IRQ/RX callbacks eventually clean up such
> + * messages once, finally, a late reply is received and discarded (if ever).
> + *
> + * This approach was deemed preferable since those pending timed-out buffers are
> + * still effectively owned by the SCMI platform VirtIO device even after timeout
> + * expiration: forcibly freeing and reusing them before they had been returned
> + * explicitly by the SCMI platform could lead to subtle bugs due to message
> + * corruption.
> + * An SCMI platform VirtIO device which never returns message buffers is
> + * anyway broken and it will quickly lead to exhaustion of available messages.
> + *
> + * For this same reason, here, we take care to free only the successfully
> + * completed polled messages, since they won't be freed elsewhere; late replies
> + * to timed-out polled messages would be anyway freed by RX callbacks instead.
> + *
> + * @cinfo: SCMI channel info
> + * @ret: Transmission return code
> + * @xfer: Transfer descriptor
> + */
> +static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
> +			       struct scmi_xfer *xfer)
> +{
> +	unsigned long flags;
> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +	struct scmi_vio_msg *msg = xfer->priv;
> +
> +	if (!msg)
> +		return;
> +
> +	/* Ensure msg is unbound from xfer before pushing onto the free list  */
> +	smp_store_mb(xfer->priv, NULL);
> +
> +	/* Is a successfully completed polled message still to be finalized ? */
> +	spin_lock_irqsave(&vioch->lock, flags);
> +	if (!ret && xfer->hdr.poll_completion && list_empty(&msg->list))

Could this not also be a message which was already finalized and then
immediately reused for another polling xfer?

> +		scmi_vio_feed_vq_tx(vioch, msg);
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +}
> +
> +/**
> + * virtio_poll_done  - Provide polling support for VirtIO transport
> + *
> + * @cinfo: SCMI channel info
> + * @xfer: Reference to the transfer being poll for.
> + *
> + * VirtIO core provides a polling mechanism based only on last used indexes:
> + * this means that it is possible to poll the virtqueues waiting for something
> + * new to arrive from the host side but the only way to check if the freshly
> + * arrived buffer was what we were waiting for is to compare the newly arrived
> + * message descriptors with the one we are polling on.
> + *
> + * As a consequence it can happen to dequeue something different from the buffer
> + * we were poll-waiting for: if that is the case such early fetched buffers are
> + * then added to a the @pending_cmds_list list for later processing by a
> + * dedicated deferred worker.
> + *
> + * So, basically, once something new is spotted we proceed to de-queue all the
> + * freshly received used buffers until we found the one we were polling on, or,
> + * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
> + * in the vqueue at the end of the polling loop (possible due to inherent races
> + * in virtqueues handling mechanisms), we similarly kick the deferred worker
> + * and let it process those, to avoid indefinitely looping in the .poll_done
> + * helper.
> + *
> + * Note that we do NOT suppress notification with VIRTQ_USED_F_NO_NOTIFY even
> + * when polling since such flag is per-virtqueues and we do not want to
> + * suppress notifications as a whole: so, if the message we are polling for is
> + * delivered via usual IRQs callbacks, on another core which are IRQs-on, it
> + * will be handled as such by scmi_rx_callback() and the polling loop in the
> + * SCMI Core TX path will be transparently terminated anyway.

Why is VIRTQ_USED_F_NO_NOTIFY mentioned? It is a flag associated with only one
of two buffer notification suppression methods, which are transparently handled
by the virtio core. Cf. `Driver Requirements: Used Buffer Notification
Suppression' in the virtio spec.

> + *
> + * Return: True once polling has successfully completed.
> + */
> +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> +			     struct scmi_xfer *xfer)
> +{
> +	bool pending, ret = false;
> +	unsigned int length, any_prefetched = 0;
> +	unsigned long flags;
> +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +
> +	if (!msg)
> +		return true;
> +
> +	spin_lock_irqsave(&msg->poll_lock, flags);
> +	/* Processed already by other polling loop on another CPU ? */
> +	if (msg->poll_idx == VIO_MSG_POLL_DONE) {
> +		spin_unlock_irqrestore(&msg->poll_lock, flags);
> +		return true;
> +	}
> +
> +	/* Has cmdq index moved at all ? */
> +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);

In my understanding, the polling comparison could still be subject to the ABA
problem when exactly 2**16 messages have been marked as used since
msg->poll_idx was set (unlikely scenario, granted).

I think this would be a lot simpler if the virtio core exported some
concurrency-safe helper function for such polling (similar to more_used() from
virtio_ring.c), as discussed at the top.

> +	spin_unlock_irqrestore(&msg->poll_lock, flags);
> +	if (!pending)
> +		return false;
> +
> +	spin_lock_irqsave(&vioch->lock, flags);
> +	virtqueue_disable_cb(vioch->vqueue);
> +
> +	/*
> +	 * If something arrived we cannot be sure, without dequeueing, if it
> +	 * was the reply to the xfer we are polling for, or, to other, even
> +	 * possibly non-polling, pending xfers: process all new messages
> +	 * till the polled-for message is found OR the vqueue is empty.
> +	 */
> +	while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
> +		next_msg->rx_len = length;
> +		/* Is the message we were polling for ? */
> +		if (next_msg == msg) {
> +			ret = true;
> +			break;
> +		}
> +
> +		spin_lock(&next_msg->poll_lock);
> +		if (next_msg->poll_idx == VIO_MSG_NOT_POLLED) {
> +			any_prefetched++;
> +			list_add_tail(&next_msg->list,
> +				      &vioch->pending_cmds_list);
> +		} else {
> +			next_msg->poll_idx = VIO_MSG_POLL_DONE;
> +		}
> +		spin_unlock(&next_msg->poll_lock);
>  	}
> +
> +	/*
> +	 * When the polling loop has successfully terminated if something
> +	 * else was queued in the meantime, it will be served by a deferred
> +	 * worker OR by the normal IRQ/callback OR by other poll loops.
> +	 *
> +	 * If we are still looking for the polled reply, the polling index has
> +	 * to be updated to the current vqueue last used index.
> +	 */
> +	if (ret) {
> +		pending = !virtqueue_enable_cb(vioch->vqueue);
> +	} else {
> +		spin_lock(&msg->poll_lock);
> +		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
> +		pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> +		spin_unlock(&msg->poll_lock);
> +	}
> +
> +	if (vioch->deferred_tx_wq && (any_prefetched || pending))
> +		queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);

What if queue_work() returns false because the single work item for the channel
was already pending? Couldn't it then happen that the worker CPU will not yet
see the updates implied by `any_prefetched || pending'?

> +
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	return ret;
>  }
>  
>  static const struct scmi_transport_ops scmi_virtio_ops = {
> @@ -376,6 +618,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = {
>  	.send_message = virtio_send_message,
>  	.fetch_response = virtio_fetch_response,
>  	.fetch_notification = virtio_fetch_notification,
> +	.mark_txdone = virtio_mark_txdone,
> +	.poll_done = virtio_poll_done,
>  };
>  
>  static int scmi_vio_probe(struct virtio_device *vdev)
> @@ -418,6 +662,7 @@ static int scmi_vio_probe(struct virtio_device *vdev)
>  		spin_lock_init(&channels[i].lock);
>  		spin_lock_init(&channels[i].ready_lock);
>  		INIT_LIST_HEAD(&channels[i].free_list);
> +		INIT_LIST_HEAD(&channels[i].pending_cmds_list);
>  		channels[i].vqueue = vqs[i];
>  
>  		sz = virtqueue_get_vring_size(channels[i].vqueue);
> @@ -506,4 +751,5 @@ const struct scmi_desc scmi_virtio_desc = {
>  	.max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
>  	.max_msg = 0, /* overridden by virtio_get_max_msg() */
>  	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
> +	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
>  };
>


From lyz_cs at pku.edu.cn  Tue Jan 18 06:51:03 2022
From: lyz_cs at pku.edu.cn (Yongzhi Liu)
Date: Tue, 18 Jan 2022 06:51:03 -0800
Subject: [PATCH] drm/rockchip: Fix runtime PM imbalance on error
Message-ID: <1642517463-19769-1-git-send-email-lyz_cs@pku.edu.cn>

pm_runtime_get_sync() will increase the rumtime PM counter
even it returns an error. Thus a pairing decrement is needed
to prevent refcount leak. Fix this by replacing this API with
pm_runtime_resume_and_get(), which will not change the runtime
PM counter on error.

Signed-off-by: Yongzhi Liu <lyz_cs at pku.edu.cn>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 3e8d9e2..9fb83b6 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -1930,7 +1930,7 @@ static int vop_initial(struct vop *vop)
 		return PTR_ERR(vop->dclk);
 	}
 
-	ret = pm_runtime_get_sync(vop->dev);
+	ret = pm_runtime_resume_get(vop->dev);
 	if (ret < 0) {
 		DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
 		return ret;
-- 
2.7.4



From alim.akhtar at samsung.com  Tue Jan 18 06:58:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:28:37 +0530
Subject: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <b8040d39-cd4d-e5b0-8aec-f03c5257d63e@canonical.com>
References: <20220113121143.22280-1-alim.akhtar@samsung.com>
 <CGME20220113122417epcas5p47398a5190cdf4c574c6f1762918b549f@epcas5p4.samsung.com>
 <20220113121143.22280-16-alim.akhtar@samsung.com>
 <2927c34e-3259-4e9a-a657-aeeebf9089d2@canonical.com>
 <00ca01d80ba8$6b9b9800$42d2c800$@samsung.com>
 <b8040d39-cd4d-e5b0-8aec-f03c5257d63e@canonical.com>
Message-ID: <023d01d80c7b$e14d4d40$a3e7e7c0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Monday, January 17, 2022 7:20 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; linus.walleij at linaro.org; catalin.marinas at arm.com;
>robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>'Shashank Prashar' <s.prashar at samsung.com>; 'Aswani Reddy'
><aswani.reddy at samsung.com>
>Subject: Re: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl support
>
>On 17/01/2022 14:44, Alim Akhtar wrote:
>> Hi Krzysztof
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>>> Sent: Thursday, January 13, 2022 6:50 PM
>>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>>> Cc: soc at kernel.org; linux-clk at vger.kernel.org;
>>> devicetree at vger.kernel.org; olof at lixom.net; linus.walleij at linaro.org;
>>> catalin.marinas at arm.com;
>>> robh+dt at kernel.org; s.nawrocki at samsung.com; linux-samsung-
>>> soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-fsd at tesla.com;
>>> Shashank Prashar <s.prashar at samsung.com>; Aswani Reddy
>>> <aswani.reddy at samsung.com>
>>> Subject: Re: [PATCH 15/23] arm64: dts: fsd: Add initial pinctrl
>>> support
>>>
>>> On 13/01/2022 13:11, Alim Akhtar wrote:
>>>> Add initial pin configuration nodes for FSD SoC.
>>>>
>>>> Cc: linux-fsd at tesla.com
>>>> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
>>>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>>>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>>>> ---
>>>>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 338
>>> +++++++++++++++++++++
>>>>  arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
>>>>  2 files changed, 360 insertions(+)
>>>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>>>
>>>> diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>>> b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>>> new file mode 100644
>>>> index 000000000000..ec8d944af636
>>>> --- /dev/null
>>>> +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
>>>> @@ -0,0 +1,338 @@
>>>> +// SPDX-License-Identifier: GPL-2.0
>>>> +/*
>>>> + * Tesla Full Self-Driving SoC device tree source
>>>> + *
>>>> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
>>>> + *		https://www.samsung.com
>>>> + * Copyright (c) 2017-2021 Tesla, Inc.
>>>> + *		https://www.tesla.com
>>>> + */
>>>> +
>>>> +#include <dt-bindings/pinctrl/samsung.h>
>>>> +
>>>> +&pinctrl_fsys0 {
>>>> +
>>>
>>> No need for empty line.
>>>
>> Noted
>>
>>>> +	gpf0: gpf0 {
>>>
>>> FYI:
>>> It's ok now, but the nodes will have to be renamed to "xxx-gpio-bank"
>later.
>>>
>> Have rebased my v2 on your pinmux schema update, so these and below
>comments are addressed.
>> Thanks
>>
>
>OK, but have in mind that -gpio-bank suffix is not needed now. This depends
>on support in the pinctrl driver, which will be applied after the merge window
>to different tree or branches than DTS is going to.
>Therefore if I apply your DTS with "-gpio-bank" to my next/dt64, the kernel
>won't find GPIo banks and won't properly boot. The linux-next will be fine,
>just my next/dt64 won't be.
>
Thanks, got it, for now let me send v2 on linux-next (as of today).
As required I will rebase to your next/dt64 and send again.
Which also means that my v2 will not be based on your new pinmux schema.
Probably we will move to that after the merge window.

>If you're fine with it - use "-gpio-bank" suffix. If you prefer my
>next/dt64 to have a fully working Tesla SoC DTS, then stick to old node naming
>and let's replace it later.
>
>Best regards,
>Krzysztof



From alim.akhtar at samsung.com  Tue Jan 18 06:48:35 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:35 +0530
Subject: [PATCH v2 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
References: <CGME20220118150008epcas5p40d1c79616bb17797e79e1769f5e2c19c@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-1-alim.akhtar@samsung.com>

Adds basic support for the Tesla Full Self-Driving (FSD)
SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
as well as several IPs.

Patches 1 to 9 provide support for the clock controller
(which is designed similarly to Exynos SoCs).

The remaining changes provide pinmux support, initial device tree support.

- Changes since v1
* fixed make dt_binding_check error as pointed by Rob
* Addressed Krzysztof's and Rob's review comments
* Added Reviewed-by and Acked-by tags
* Reordered the patches
* Dropped SPI, MCT and ADC from this series (to be posted in small sets)

NOTE: These patches are based on next-20220118

Alim Akhtar (16):
  dt-bindings: add vendor prefix for Tesla
  dt-bindings: clock: Add bindings definitions for FSD CMU blocks
  dt-bindings: clock: Document FSD CMU bindings
  clk: samsung: fsd: Add initial clock support
  clk: samsung: fsd: Add cmu_peric block clock information
  clk: samsung: fsd: Add cmu_fsys0 clock information
  clk: samsung: fsd: Add cmu_fsys1 clock information
  clk: samsung: fsd: Add cmu_imem block clock information
  clk: samsung: fsd: Add cmu_mfc block clock information
  clk: samsung: fsd: Add cam_csi block clock information
  dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
  pinctrl: samsung: add FSD SoC specific data
  dt-bindings: arm: add Tesla FSD ARM SoC
  arm64: dts: fsd: Add initial device tree support
  arm64: dts: fsd: Add initial pinctrl support
  arm64: defconfig: Enable Tesla FSD SoC

 .../devicetree/bindings/arm/tesla.yaml        |   27 +
 .../bindings/clock/tesla,fsd-clock.yaml       |  198 ++
 .../bindings/pinctrl/samsung-pinctrl.txt      |    1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    8 +
 arch/arm64/Kconfig.platforms                  |    7 +
 arch/arm64/boot/dts/Makefile                  |    1 +
 arch/arm64/boot/dts/tesla/Makefile            |    3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts         |   39 +
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  335 +++
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  673 ++++++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/clk/samsung/Kconfig                   |    7 +
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-fsd.c                 | 1801 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |    1 +
 drivers/clk/samsung/clk-pll.h                 |    1 +
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    |   71 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |    1 +
 include/dt-bindings/clock/fsd-clk.h           |  149 ++
 21 files changed, 3329 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
 create mode 100644 drivers/clk/samsung/clk-fsd.c
 create mode 100644 include/dt-bindings/clock/fsd-clk.h


base-commit: 6f59bc242877fcb9c9a5136ea62d383fce5615df
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:36 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:36 +0530
Subject: [PATCH v2 01/16] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150014epcas5p2ac07759961be616d01de76026e58d4f5@epcas5p2.samsung.com>
Message-ID: <20220118144851.69537-2-alim.akhtar@samsung.com>

Add vendor prefix for the Tesla (https://www.tesla.com)

Cc: linux-fsd at tesla.com
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 64c604752052..09fbef521394 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1209,6 +1209,8 @@ patternProperties:
     description: Shenzhen Techstar Electronics Co., Ltd.
   "^terasic,.*":
     description: Terasic Inc.
+  "^tesla,.*":
+    description: Tesla, Inc.
   "^tfc,.*":
     description: Three Five Corp
   "^thead,.*":
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:37 +0530
Subject: [PATCH v2 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150018epcas5p32642af7af63869d08a861d00d97e3b68@epcas5p3.samsung.com>
Message-ID: <20220118144851.69537-3-alim.akhtar@samsung.com>

Clock controller driver of FSD platform is designed to have separate
instances for each particular CMU. So clock IDs in this bindings header
also start from 1 for each CMU block.

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
[robot: reported missing #endif]
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 include/dt-bindings/clock/fsd-clk.h | 149 ++++++++++++++++++++++++++++
 1 file changed, 149 insertions(+)
 create mode 100644 include/dt-bindings/clock/fsd-clk.h

diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
new file mode 100644
index 000000000000..8cf45d2430b0
--- /dev/null
+++ b/include/dt-bindings/clock/fsd-clk.h
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * The constants defined in this header are being used in dts
+ * and fsd platform driver.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_FSD_H
+#define _DT_BINDINGS_CLOCK_FSD_H
+
+/* CMU */
+#define DOUT_CMU_PLL_SHARED0_DIV4		1
+#define DOUT_CMU_PERIC_SHARED1DIV36		2
+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
+#define DOUT_CMU_PERIC_SHARED0DIV20		4
+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
+#define DOUT_CMU_PLL_SHARED0_DIV6		6
+#define DOUT_CMU_FSYS0_SHARED1DIV4		7
+#define DOUT_CMU_FSYS0_SHARED0DIV4		8
+#define DOUT_CMU_FSYS1_SHARED0DIV8		9
+#define DOUT_CMU_FSYS1_SHARED0DIV4		10
+#define CMU_CPUCL_SWITCH_GATE			11
+#define DOUT_CMU_IMEM_TCUCLK			12
+#define DOUT_CMU_IMEM_ACLK			13
+#define DOUT_CMU_IMEM_DMACLK			14
+#define GAT_CMU_FSYS0_SHARED0DIV4		15
+#define CMU_NR_CLK				16
+
+/* PERIC */
+#define PERIC_SCLK_UART0			1
+#define PERIC_PCLK_UART0			2
+#define PERIC_SCLK_UART1			3
+#define PERIC_PCLK_UART1			4
+#define PERIC_DMA0_IPCLKPORT_ACLK		5
+#define PERIC_DMA1_IPCLKPORT_ACLK		6
+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
+#define PERIC_PCLK_SPI0                         9
+#define PERIC_SCLK_SPI0                         10
+#define PERIC_PCLK_SPI1                         11
+#define PERIC_SCLK_SPI1                         12
+#define PERIC_PCLK_SPI2                         13
+#define PERIC_SCLK_SPI2                         14
+#define PERIC_PCLK_TDM0                         15
+#define PERIC_PCLK_HSI2C0			16
+#define PERIC_PCLK_HSI2C1			17
+#define PERIC_PCLK_HSI2C2			18
+#define PERIC_PCLK_HSI2C3			19
+#define PERIC_PCLK_HSI2C4			20
+#define PERIC_PCLK_HSI2C5			21
+#define PERIC_PCLK_HSI2C6			22
+#define PERIC_PCLK_HSI2C7			23
+#define PERIC_MCAN0_IPCLKPORT_CCLK		24
+#define PERIC_MCAN0_IPCLKPORT_PCLK		25
+#define PERIC_MCAN1_IPCLKPORT_CCLK		26
+#define PERIC_MCAN1_IPCLKPORT_PCLK		27
+#define PERIC_MCAN2_IPCLKPORT_CCLK		28
+#define PERIC_MCAN2_IPCLKPORT_PCLK		29
+#define PERIC_MCAN3_IPCLKPORT_CCLK		30
+#define PERIC_MCAN3_IPCLKPORT_PCLK		31
+#define PERIC_PCLK_ADCIF			32
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
+#define PERIC_HCLK_TDM0				40
+#define PERIC_PCLK_TDM1				41
+#define PERIC_HCLK_TDM1				42
+#define PERIC_EQOS_PHYRXCLK_MUX			43
+#define PERIC_EQOS_PHYRXCLK			44
+#define PERIC_DOUT_RGMII_CLK			45
+#define PERIC_NR_CLK				46
+
+/* FSYS0 */
+#define UFS0_MPHY_REFCLK_IXTAL24		1
+#define UFS0_MPHY_REFCLK_IXTAL26		2
+#define UFS1_MPHY_REFCLK_IXTAL24		3
+#define UFS1_MPHY_REFCLK_IXTAL26		4
+#define UFS0_TOP0_HCLK_BUS			5
+#define UFS0_TOP0_ACLK				6
+#define UFS0_TOP0_CLK_UNIPRO			7
+#define UFS0_TOP0_FMP_CLK			8
+#define UFS1_TOP1_HCLK_BUS			9
+#define UFS1_TOP1_ACLK				10
+#define UFS1_TOP1_CLK_UNIPRO			11
+#define UFS1_TOP1_FMP_CLK			12
+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
+#define FSYS0_NR_CLK				23
+
+/* FSYS1 */
+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
+#define FSYS1_NR_CLK				9
+
+/* IMEM */
+#define IMEM_DMA0_IPCLKPORT_ACLK		1
+#define IMEM_DMA1_IPCLKPORT_ACLK		2
+#define IMEM_WDT0_IPCLKPORT_PCLK		3
+#define IMEM_WDT1_IPCLKPORT_PCLK		4
+#define IMEM_WDT2_IPCLKPORT_PCLK		5
+#define IMEM_MCT_PCLK				6
+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
+#define IMEM_NR_CLK				12
+
+/* MFC */
+#define MFC_MFC_IPCLKPORT_ACLK			1
+#define MFC_NR_CLK				2
+
+/* CAM_CSI */
+#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
+#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
+#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
+#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
+#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
+#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
+#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
+#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
+#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
+#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
+#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
+#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
+#define CAM_CSI_NR_CLK				13
+#endif /*_DT_BINDINGS_CLOCK_FSD_H */
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:38 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:38 +0530
Subject: [PATCH v2 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150022epcas5p21912423606220552a78c7e22e4133a05@epcas5p2.samsung.com>
Message-ID: <20220118144851.69537-4-alim.akhtar@samsung.com>

Add dt-schema documentation for Tesla FSD SoC clock controller.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../bindings/clock/tesla,fsd-clock.yaml       | 198 ++++++++++++++++++
 1 file changed, 198 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..dc808e2f8327
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+description: |
+  FSD clock controller consist of several clock management unit
+  (CMU), which generates clocks for various inteernal SoC blocks.
+  The root clock comes from external OSC clock (24 MHz).
+
+  All available clocks are defined as preprocessor macros in
+  'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+  compatible:
+    enum:
+      - tesla,fsd-clock-cmu
+      - tesla,fsd-clock-imem
+      - tesla,fsd-clock-peric
+      - tesla,fsd-clock-fsys0
+      - tesla,fsd-clock-fsys1
+      - tesla,fsd-clock-mfc
+      - tesla,fsd-clock-cam_csi
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  clock-names:
+    minItems: 1
+    maxItems: 6
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cmu
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-imem
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: IMEM TCU clock (from CMU_CMU)
+            - description: IMEM bus clock (from CMU_CMU)
+            - description: IMEM DMA clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_imem_tcuclk
+            - const: dout_cmu_imem_aclk
+            - const: dout_cmu_imem_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-peric
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div4 clock (from CMU_CMU)
+            - description: PERIC shared1 div36 clock (from CMU_CMU)
+            - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+            - description: PERIC shared0 div20 clock (from CMU_CMU)
+            - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div4
+            - const: dout_cmu_peric_shared1div36
+            - const: dout_cmu_peric_shared0div3_tbuclk
+            - const: dout_cmu_peric_shared0div20
+            - const: dout_cmu_peric_shared1div4_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys0
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div6 clock (from CMU_CMU)
+            - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+            - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div6
+            - const: dout_cmu_fsys0_shared1div4
+            - const: dout_cmu_fsys0_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys1
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+            - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_fsys1_shared0div8
+            - const: dout_cmu_fsys1_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-mfc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cam_csi
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_FSYS1
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+
+    clock_fsys1: clock-controller at 16810000 {
+          compatible = "tesla,fsd-clock-fsys1";
+          reg = <0x16810000 0x3000>;
+          #clock-cells = <1>;
+
+          clocks = <&fin_pll>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+          clock-names = "fin_pll",
+                        "dout_cmu_fsys1_shared0div8",
+                        "dout_cmu_fsys1_shared0div4";
+    };
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:39 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:39 +0530
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
Message-ID: <20220118144851.69537-5-alim.akhtar@samsung.com>

Add initial clock support for FSD (Full Self-Driving) SoC
which is required to bring-up platforms based on this SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/Kconfig   |   7 +
 drivers/clk/samsung/Makefile  |   1 +
 drivers/clk/samsung/clk-fsd.c | 308 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c |   1 +
 drivers/clk/samsung/clk-pll.h |   1 +
 5 files changed, 318 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-fsd.c

diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 0e18d6ff2916..11587eb87fc4 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -124,3 +124,10 @@ config S3C2443_COMMON_CLK
 	help
 	  Support for the clock controller present on the Samsung
 	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+
+config TESLA_FSD_COMMON_CLK
+	bool "Tesla FSD clock controller support" if COMPILE_TEST
+	depends on COMMON_CLK_SAMSUNG
+	help
+	  Support for the clock controller present on the Tesla FSD SoC.
+	  Choose Y here only if you build for this SoC.
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 0df74916a895..17e5d1cb9da2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_S3C64XX_COMMON_CLK)	+= clk-s3c64xx.o
 obj-$(CONFIG_S5PV210_COMMON_CLK)	+= clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_TESLA_FSD_COMMON_CLK)	+= clk-fsd.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..2669396d81b9
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * Common Clock Framework support for FSD SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/fsd-clk.h>
+
+#include "clk.h"
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0			0x0
+#define PLL_LOCKTIME_PLL_SHARED1			0x4
+#define PLL_LOCKTIME_PLL_SHARED2			0x8
+#define PLL_LOCKTIME_PLL_SHARED3			0xc
+#define PLL_CON0_PLL_SHARED0				0x100
+#define PLL_CON0_PLL_SHARED1				0x120
+#define PLL_CON0_PLL_SHARED2				0x140
+#define PLL_CON0_PLL_SHARED3				0x160
+#define MUX_CMU_CIS0_CLKMUX				0x1000
+#define MUX_CMU_CIS1_CLKMUX				0x1004
+#define MUX_CMU_CIS2_CLKMUX				0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX				0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX				0x1014
+#define MUX_PLL_SHARED0_MUX				0x1020
+#define MUX_PLL_SHARED1_MUX				0x1024
+#define DIV_CMU_CIS0_CLK				0x1800
+#define DIV_CMU_CIS1_CLK				0x1804
+#define DIV_CMU_CIS2_CLK				0x1808
+#define DIV_CMU_CMU_ACLK				0x180c
+#define DIV_CMU_CPUCL_SWITCH				0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4			0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3			0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4			0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4			0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8			0x182c
+#define DIV_CMU_IMEM_ACLK				0x1834
+#define DIV_CMU_IMEM_DMACLK				0x1838
+#define DIV_CMU_IMEM_TCUCLK				0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20			0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK		0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36			0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK		0x1850
+#define DIV_PLL_SHARED0_DIV2				0x1858
+#define DIV_PLL_SHARED0_DIV3				0x185c
+#define DIV_PLL_SHARED0_DIV4				0x1860
+#define DIV_PLL_SHARED0_DIV6				0x1864
+#define DIV_PLL_SHARED1_DIV3				0x1868
+#define DIV_PLL_SHARED1_DIV36				0x186c
+#define DIV_PLL_SHARED1_DIV4				0x1870
+#define DIV_PLL_SHARED1_DIV9				0x1874
+#define GAT_CMU_CIS0_CLKGATE				0x2000
+#define GAT_CMU_CIS1_CLKGATE				0x2004
+#define GAT_CMU_CIS2_CLKGATE				0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE			0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE			0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK			0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE			0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE			0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE			0x2028
+#define GAT_CMU_IMEM_ACLK_GATE				0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE			0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE			0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE		0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE			0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE		0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE			0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK			0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK		0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU	0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK		0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_CON0_PLL_SHARED0,
+	PLL_CON0_PLL_SHARED1,
+	PLL_CON0_PLL_SHARED2,
+	PLL_CON0_PLL_SHARED3,
+	MUX_CMU_CIS0_CLKMUX,
+	MUX_CMU_CIS1_CLKMUX,
+	MUX_CMU_CIS2_CLKMUX,
+	MUX_CMU_CPUCL_SWITCHMUX,
+	MUX_CMU_FSYS1_ACLK_MUX,
+	MUX_PLL_SHARED0_MUX,
+	MUX_PLL_SHARED1_MUX,
+	DIV_CMU_CIS0_CLK,
+	DIV_CMU_CIS1_CLK,
+	DIV_CMU_CIS2_CLK,
+	DIV_CMU_CMU_ACLK,
+	DIV_CMU_CPUCL_SWITCH,
+	DIV_CMU_FSYS0_SHARED0DIV4,
+	DIV_CMU_FSYS0_SHARED1DIV3,
+	DIV_CMU_FSYS0_SHARED1DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV8,
+	DIV_CMU_IMEM_ACLK,
+	DIV_CMU_IMEM_DMACLK,
+	DIV_CMU_IMEM_TCUCLK,
+	DIV_CMU_PERIC_SHARED0DIV20,
+	DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+	DIV_CMU_PERIC_SHARED1DIV36,
+	DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+	DIV_PLL_SHARED0_DIV2,
+	DIV_PLL_SHARED0_DIV3,
+	DIV_PLL_SHARED0_DIV4,
+	DIV_PLL_SHARED0_DIV6,
+	DIV_PLL_SHARED1_DIV3,
+	DIV_PLL_SHARED1_DIV36,
+	DIV_PLL_SHARED1_DIV4,
+	DIV_PLL_SHARED1_DIV9,
+	GAT_CMU_CIS0_CLKGATE,
+	GAT_CMU_CIS1_CLKGATE,
+	GAT_CMU_CIS2_CLKGATE,
+	GAT_CMU_CPUCL_SWITCH_GATE,
+	GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+	GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+	GAT_CMU_IMEM_ACLK_GATE,
+	GAT_CMU_IMEM_DMACLK_GATE,
+	GAT_CMU_IMEM_TCUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+	GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+	GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+	GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+	GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+	GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+	GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2000000000, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1800000000, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+	    PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+	    PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+	    PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+	    PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+	MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+	MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+	MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+	    MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+	MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+	DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+	DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+	DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+	    DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+	DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+	    DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+	    DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+	DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+	    DIV_CMU_IMEM_ACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+	    DIV_CMU_IMEM_DMACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+	    DIV_CMU_IMEM_TCUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+	    "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+	    "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+	    "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+	    "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV2, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV3, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+	    DIV_PLL_SHARED0_DIV4, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+	    DIV_PLL_SHARED0_DIV6, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV3, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+	    DIV_PLL_SHARED1_DIV36, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV4, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+	    DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+	GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+	     GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+	     GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+	     GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+	     GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+	     GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+	     GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+	     GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+	.pll_clks		= cmu_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cmu_pll_clks),
+	.mux_clks		= cmu_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cmu_mux_clks),
+	.div_clks		= cmu_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cmu_div_clks),
+	.gate_clks		= cmu_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cmu_gate_clks),
+	.nr_clk_ids		= CMU_NR_CLK,
+	.clk_regs		= cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 70cdc87f714e..fe383471c5f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_1450x:
 	case pll_1451x:
 	case pll_1452x:
+	case pll_142xx:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c83a20195f6d..a9892c2d1f57 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -39,6 +39,7 @@ enum samsung_pll_type {
 	pll_1460x,
 	pll_0822x,
 	pll_0831x,
+	pll_142xx,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:40 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:40 +0530
Subject: [PATCH v2 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150033epcas5p15b88d4f0c695fc515f20d8dffe15202e@epcas5p1.samsung.com>
Message-ID: <20220118144851.69537-6-alim.akhtar@samsung.com>

Add CMU_PERIC block clock information needed for various IPs
functions found in this block.

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 405 ++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 2669396d81b9..02ea8d977f1a 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -8,12 +8,17 @@
  * Common Clock Framework support for FSD SoC.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/clock/fsd-clk.h>
 
 #include "clk.h"
+#include "clk-exynos-arm64.h"
 
 /* Register Offset definitions for CMU_CMU (0x11c10000) */
 #define PLL_LOCKTIME_PLL_SHARED0			0x0
@@ -306,3 +311,403 @@ static void __init fsd_clk_cmu_init(struct device_node *np)
 }
 
 CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX		0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX		0x120
+#define PLL_CON0_PERIC_PCLK_MUX			0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX		0x160
+#define PLL_CON0_SPI_CLK			0x180
+#define PLL_CON0_SPI_PCLK			0x1a0
+#define PLL_CON0_UART_CLK			0x1c0
+#define PLL_CON0_UART_PCLK			0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK			0x1000
+#define DIV_EQOS_BUSCLK				0x1800
+#define DIV_PERIC_MCAN_CLK			0x1804
+#define DIV_RGMII_CLK				0x1808
+#define DIV_RII_CLK				0x180c
+#define DIV_RMII_CLK				0x1810
+#define DIV_SPI_CLK				0x1814
+#define DIV_UART_CLK				0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I	0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK		0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK	0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK	0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK	0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK	0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM	0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS	0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM	0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS	0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK	0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK	0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK	0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK	0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK	0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK	0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK	0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK	0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK	0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I		0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I		0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I		0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I	0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I	0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK		0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D	0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P	0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0	0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK		0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK		0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK		0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK		0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK		0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK		0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK		0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK		0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK		0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK		0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK		0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK		0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK		0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK		0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK		0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK		0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK		0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK		0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0	0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0	0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK		0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK	0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK		0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI	0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK		0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI	0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK		0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI	0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M		0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK		0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M		0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK		0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART	0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK		0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART	0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK		0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK		0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+	PLL_CON0_PERIC_DMACLK_MUX,
+	PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+	PLL_CON0_PERIC_PCLK_MUX,
+	PLL_CON0_PERIC_TBUCLK_MUX,
+	PLL_CON0_SPI_CLK,
+	PLL_CON0_SPI_PCLK,
+	PLL_CON0_UART_CLK,
+	PLL_CON0_UART_PCLK,
+	MUX_PERIC_EQOS_PHYRXCLK,
+	DIV_EQOS_BUSCLK,
+	DIV_PERIC_MCAN_CLK,
+	DIV_RGMII_CLK,
+	DIV_RII_CLK,
+	DIV_RMII_CLK,
+	DIV_SPI_CLK,
+	DIV_UART_CLK,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+	GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+	GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+	GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+	GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+	GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+	GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+	GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+	GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+	GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+	GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+	GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART0_IPCLKPORT_PCLK,
+	GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART1_IPCLKPORT_PCLK,
+	GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+	FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+	MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+	MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+	    PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+	MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+	MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+	MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+	MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+		MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+	DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+	DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+	DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+		DIV_RGMII_CLK, 0, 4),
+	DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+	DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+	DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+	DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+	     GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+	     "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+	     "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+	.mux_clks		= peric_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric_mux_clks),
+	.div_clks		= peric_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric_div_clks),
+	.gate_clks		= peric_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric_gate_clks),
+	.fixed_clks		= peric_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(peric_fixed_clks),
+	.nr_clk_ids		= PERIC_NR_CLK,
+	.clk_regs		= peric_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric_clk_regs),
+	.clk_name		= "dout_cmu_pll_shared0_div4",
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+	{
+		.compatible = "tesla,fsd-clock-peric",
+		.data = &peric_cmu_info,
+	}, {
+	},
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+	.driver	= {
+		.name = "fsd-cmu",
+		.of_match_table = fsd_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+	return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:41 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:41 +0530
Subject: [PATCH v2 06/16] clk: samsung: fsd: Add cmu_fsys0 clock information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150037epcas5p1624361eb48fa14cdf9ed88de6f890db4@epcas5p1.samsung.com>
Message-ID: <20220118144851.69537-7-alim.akhtar@samsung.com>

CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
the related clock information for the same.

Cc: linux-fsd at tesla.com
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 02ea8d977f1a..9ae0a86ae762 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -671,6 +671,305 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_pll_shared0_div4",
 };
 
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO		0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK		0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1		0x160
+#define DIV_CLK_UNIPRO				0x1800
+#define DIV_EQS_RGMII_CLK_125			0x1804
+#define DIV_PERIBUS_GRP				0x1808
+#define DIV_EQOS_RII_CLK2O5			0x180c
+#define DIV_EQOS_RMIICLK_25			0x1810
+#define DIV_PCIE_PHY_OSCCLK			0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I	0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK	0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK	0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO	0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK	0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC	0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK	0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK	0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK	0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK	0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK	0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK		0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I	0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I	0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK	0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D	0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1	0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P	0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S	0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK	0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL	0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0	0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC	0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK	0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC	0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC	0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK	0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK	0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK	0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS	0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK	0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO	0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK	0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS	0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK	0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO	0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK	0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE			0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+	PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+	PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+	PLL_CON0_EQOS_RGMII_125_MUX1,
+	DIV_CLK_UNIPRO,
+	DIV_EQS_RGMII_CLK_125,
+	DIV_PERIBUS_GRP,
+	DIV_EQOS_RII_CLK2O5,
+	DIV_EQOS_RMIICLK_25,
+	DIV_PCIE_PHY_OSCCLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+	GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+	GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+	GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+	GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+	FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+	FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+	FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+	    PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+	MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+	    PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+	MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+	    PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+	DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+	DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQS_RGMII_CLK_125, 0, 4),
+	DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+	    "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQOS_RMIICLK_25, 0, 5),
+	DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+	     "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+	     "xtal_clk_pcie_phy",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+	      "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+	      CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+	     "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+	     "dout_fsys0_pcie_phy_oscclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+	.mux_clks		= fsys0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys0_mux_clks),
+	.div_clks		= fsys0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys0_div_clks),
+	.gate_clks		= fsys0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys0_gate_clks),
+	.fixed_clks		= fsys0_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys0_fixed_clks),
+	.nr_clk_ids		= FSYS0_NR_CLK,
+	.clk_regs		= fsys0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys0_clk_regs),
+	.clk_name		= "dout_cmu_fsys0_shared1div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -693,6 +992,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	{
 		.compatible = "tesla,fsd-clock-peric",
 		.data = &peric_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys0",
+		.data = &fsys0_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:42 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:42 +0530
Subject: [PATCH v2 07/16] clk: samsung: fsd: Add cmu_fsys1 clock information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150041epcas5p2634381919d0e9f60867d6087162fa134@epcas5p2.samsung.com>
Message-ID: <20220118144851.69537-8-alim.akhtar@samsung.com>

Adds cmu_fsys1 block clock information which are needed
for PCIe IPs in block FSYS1.

Cc: linux-fsd at tesla.com
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 9ae0a86ae762..97973a629453 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -970,6 +970,178 @@ static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys0_shared1div4",
 };
 
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX			0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX			0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK			0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK			0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK	0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK		0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK	0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK		0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL	0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK				0x2034
+#define GAT_FSYS1_PHY1_OSCCLK				0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK		0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK	0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK	0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK		0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0	0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0	0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK		0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK	0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK	0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK	0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK		0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK		0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK	0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK	0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK		0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK		0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL	0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK		0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK		0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+	PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+	PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+	DIV_CLK_FSYS1_PHY0_OSCCLK,
+	DIV_CLK_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+	GAT_FSYS1_PHY0_OSCCLLK,
+	GAT_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+	GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+	FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+	FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+	    PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+	MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+	    PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+	DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+	    DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+	DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+	    DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+	GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+	.mux_clks		= fsys1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys1_mux_clks),
+	.div_clks		= fsys1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys1_div_clks),
+	.gate_clks		= fsys1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys1_gate_clks),
+	.fixed_clks		= fsys1_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys1_fixed_clks),
+	.nr_clk_ids		= FSYS1_NR_CLK,
+	.clk_regs		= fsys1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys1_clk_regs),
+	.clk_name		= "dout_cmu_fsys1_shared0div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -995,6 +1167,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys0",
 		.data = &fsys0_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys1",
+		.data = &fsys1_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:43 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:43 +0530
Subject: [PATCH v2 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150045epcas5p4e54922758fb7922b1fd8de0995d2127e@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-9-alim.akhtar@samsung.com>

Adds cmu_imem clock related code, imem block contains IPs
like WDT, DMA, TMU etc, these clocks are required for such
IP function.

Cc: linux-fsd at tesla.com
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 97973a629453..8c879f7cb6a9 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1142,6 +1142,289 @@ static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys1_shared0div4",
 };
 
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK				0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK			0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK			0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK			0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK		0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO		0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK		0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK		0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS		0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK		0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS		0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK		0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK			0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK		0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK			0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK			0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK			0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM	0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM	0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM	0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS	0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS	0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS	0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM		0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS		0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM		0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS		0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK		0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK		0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK		0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK		0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK		0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK		0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK			0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK			0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK	0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK			0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK			0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK	0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK	0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK			0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D	0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU	0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P	0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK		0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK		0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK	0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK		0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK		0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK		0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK		0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK		0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK			0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK			0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK			0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK			0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+	PLL_CON0_CLK_IMEM_ACLK,
+	PLL_CON0_CLK_IMEM_INTMEMCLK,
+	PLL_CON0_CLK_IMEM_TCUCLK,
+	DIV_OSCCLK_IMEM_TMUTSCLK,
+	GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_WDT0_IPCLKPORT_CLK,
+	GAT_IMEM_WDT1_IPCLKPORT_CLK,
+	GAT_IMEM_WDT2_IPCLKPORT_CLK,
+	GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+	GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+	GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+	GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+	GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+	GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+	GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+	GAT_IMEM_GIC_IPCLKPORT_CLK,
+	GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_PCLK,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+	GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+	GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_TCU_IPCLKPORT_ACLK,
+	GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+	MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+	    PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+	    PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+	DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+	GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+	     GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+	.mux_clks		= imem_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(imem_mux_clks),
+	.div_clks		= imem_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(imem_div_clks),
+	.gate_clks		= imem_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(imem_gate_clks),
+	.nr_clk_ids		= IMEM_NR_CLK,
+	.clk_regs		= imem_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:44 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:44 +0530
Subject: [PATCH v2 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150048epcas5p3449136cf0dbc2186d91c4472e9df68e0@epcas5p3.samsung.com>
Message-ID: <20220118144851.69537-10-alim.akhtar@samsung.com>

Adds cmu_mfc clock related code, these clocks are
required for MFC IP.

Cc: linux-fsd at tesla.com
Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 8c879f7cb6a9..72a2b38524a1 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1425,6 +1425,124 @@ static void __init fsd_clk_imem_init(struct device_node *np)
 
 CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
 
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC					0x0
+#define PLL_CON0_PLL_MFC					0x100
+#define MUX_MFC_BUSD						0x1000
+#define MUX_MFC_BUSP						0x1008
+#define DIV_MFC_BUSD_DIV4					0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK				0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM			0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS			0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK			0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK				0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D	0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P	0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK			0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK			0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK			0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK			0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK			0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK				0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK				0x2040
+#define GAT_MFC_BUSD_DIV4_GATE					0x2044
+#define GAT_MFC_BUSD_GATE					0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_MFC,
+	PLL_CON0_PLL_MFC,
+	MUX_MFC_BUSD,
+	MUX_MFC_BUSP,
+	DIV_MFC_BUSD_DIV4,
+	GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+	GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+	GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+	GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+	GAT_MFC_BUSD_DIV4_GATE,
+	GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 666000000, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+	    PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+	MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+	MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+	MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+	DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+	GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+	     GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+	     GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+	.pll_clks		= mfc_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(mfc_pll_clks),
+	.mux_clks		= mfc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mfc_mux_clks),
+	.div_clks		= mfc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mfc_div_clks),
+	.gate_clks		= mfc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mfc_gate_clks),
+	.nr_clk_ids		= MFC_NR_CLK,
+	.clk_regs		= mfc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1453,6 +1571,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys1",
 		.data = &fsys1_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-mfc",
+		.data = &mfc_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:46 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:46 +0530
Subject: [PATCH v2 11/16] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150056epcas5p4825077a17b8c37b0e7cea60c4dced3c8@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-12-alim.akhtar@samsung.com>

Add compatible for Tesla Full Self-Driving SoC. The
pinctrl hardware IP is similar to what found on most of the
exynos series of SoC, so this new compatible is added in
samsung pinctrl binding.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 9e70edceb21b..81747b88b718 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -25,6 +25,7 @@ Required Properties:
   - "samsung,exynos7885-pinctrl": for Exynos7885 compatible pin-controller.
   - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
   - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
+  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:45 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:45 +0530
Subject: [PATCH v2 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150052epcas5p12efa399d1a59fc2fb0595eef128ffdf9@epcas5p1.samsung.com>
Message-ID: <20220118144851.69537-11-alim.akhtar@samsung.com>

Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.

Cc: linux-fsd at tesla.com
Signed-off-by: Sathyakam M <sathya at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 72a2b38524a1..afac8760ebe1 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1543,6 +1543,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
 	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
 };
 
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI		0x0
+#define PLL_CON0_PLL_CAM_CSI			0x100
+#define DIV_CAM_CSI0_ACLK			0x1800
+#define DIV_CAM_CSI1_ACLK			0x1804
+#define DIV_CAM_CSI2_ACLK			0x1808
+#define DIV_CAM_CSI_BUSD			0x180c
+#define DIV_CAM_CSI_BUSP			0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK	0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK	0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0	0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1	0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2	0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC	0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC		0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK		0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK		0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK		0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK		0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK		0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK		0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK		0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK		0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK		0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK		0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK		0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK		0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK		0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK		0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK		0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK		0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK		0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK		0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK		0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK		0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK		0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK		0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK		0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK		0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D	0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P	0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK	0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK	0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CAM_CSI,
+	PLL_CON0_PLL_CAM_CSI,
+	DIV_CAM_CSI0_ACLK,
+	DIV_CAM_CSI1_ACLK,
+	DIV_CAM_CSI2_ACLK,
+	DIV_CAM_CSI_BUSD,
+	DIV_CAM_CSI_BUSP,
+	GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+	GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1066000000, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+	    PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+	MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+	DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+	DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+	GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+	     GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+	     "dout_cam_csi_busd",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+	     "dout_cam_csi_busp",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+	     GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+	.pll_clks		= cam_csi_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cam_csi_pll_clks),
+	.mux_clks		= cam_csi_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cam_csi_mux_clks),
+	.div_clks		= cam_csi_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cam_csi_div_clks),
+	.gate_clks		= cam_csi_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cam_csi_gate_clks),
+	.nr_clk_ids		= CAM_CSI_NR_CLK,
+	.clk_regs		= cam_csi_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cam_csi_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1574,6 +1778,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-mfc",
 		.data = &mfc_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-cam_csi",
+		.data = &cam_csi_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:47 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:47 +0530
Subject: [PATCH v2 12/16] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150100epcas5p3b7cf28e13fd177336dc9b06875d94f43@epcas5p3.samsung.com>
Message-ID: <20220118144851.69537-13-alim.akhtar@samsung.com>

Adds Tesla FSD SoC specific data to enable pinctrl.
FSD SoC has similar pinctrl controller as found in the most
samsung/exynos SoCs.

Cc: linux-fsd at tesla.com
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
 3 files changed, 74 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 2e490e7696f4..6fd06a6ee131 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -727,3 +727,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
 	.ctrl		= exynosautov9_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
 };
+
+/*
+ * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
+ * gpio/pin-mux/pinconfig controllers.
+ */
+
+/* pin banks of FSD pin-controller 0 (FSYS) */
+static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
+};
+
+/* pin banks of FSD pin-controller 1 (PERIC) */
+static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
+};
+
+/* pin banks of FSD pin-controller 2 (PMU) */
+static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
+};
+
+const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 FSYS0 data */
+		.pin_banks	= fsd_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 1 PERIC data */
+		.pin_banks	= fsd_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 2 PMU data */
+		.pin_banks	= fsd_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks2),
+	},
+};
+
+const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
+	.ctrl		= fsd_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 0f6e9305fec5..c542c8ed8fe7 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1271,6 +1271,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos850_of_data },
 	{ .compatible = "samsung,exynosautov9-pinctrl",
 		.data = &exynosautov9_of_data },
+	{ .compatible = "tesla,fsd-pinctrl",
+		.data = &fsd_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 1f8d30ba05af..5b32d3f30fcd 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -342,6 +342,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
+extern const struct samsung_pinctrl_of_match_data fsd_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:48 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:48 +0530
Subject: [PATCH v2 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150104epcas5p4ac6fdc739d21c7d7eb2e53e469466487@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-14-alim.akhtar@samsung.com>

Add device tree bindings for the Tesla FSD ARM SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml

diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..09856da657dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: FSD SoC board
+        items:
+          - enum:
+              - tesla,fsd-evb   # Tesla FSD Evaluation
+          - const: tesla,fsd
+
+additionalProperties: true
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:49 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:49 +0530
Subject: [PATCH v2 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150108epcas5p2d9cd4db7cb368c2bfbd7d058eba4107c@epcas5p2.samsung.com>
Message-ID: <20220118144851.69537-15-alim.akhtar@samsung.com>

Add initial device tree support for "Full Self-Driving" (FSD) SoC
This SoC contain three clusters of four cortex-a72 CPUs and various
peripheral IPs.

Cc: linux-fsd at tesla.com
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 MAINTAINERS                           |   8 +
 arch/arm64/Kconfig.platforms          |   7 +
 arch/arm64/boot/dts/Makefile          |   1 +
 arch/arm64/boot/dts/tesla/Makefile    |   3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi    | 651 ++++++++++++++++++++++++++
 6 files changed, 709 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 4e828542b089..2671b04fcfcc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2753,6 +2753,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/tegra-cec.txt
 F:	drivers/media/cec/platform/tegra/
 
+ARM/TESLA FSD SoC SUPPORT
+M:	Alim Akhtar <alim.akhtar at samsung.com>
+M:	linux-fsd at tesla.com
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	arch/arm64/boot/dts/tesla*
+
 ARM/TETON BGA MACHINE SUPPORT
 M:	"Mark F. Brown" <mark.brown314 at gmail.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..ed4417f52f9f 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -268,6 +268,13 @@ config ARCH_TEGRA
 	help
 	  This enables support for the NVIDIA Tegra SoC family.
 
+config ARCH_TESLA_FSD
+	bool "ARMv8 based Tesla platform"
+	depends on ARCH_EXYNOS
+	select TESLA_FSD_COMMON_CLK
+	help
+	  Support for ARMv8 based Tesla platforms.
+
 config ARCH_SPRD
 	bool "Spreadtrum SoC platform"
 	help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += tesla
 subdir-y += ti
 subdir-y += toshiba
 subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a1ee50e2fd06
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+	fsd-evb.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
new file mode 100644
index 000000000000..5af560c1b5e6
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+	model = "Tesla Full Self-Driving (FSD) Evaluation board";
+	compatible = "tesla,fsd-evb", "tesla,fsd";
+
+	aliases {
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
+
+&serial_0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..9a2b88f58c13
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "tesla,fsd";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &hsi2c_0;
+		i2c1 = &hsi2c_1;
+		i2c2 = &hsi2c_2;
+		i2c3 = &hsi2c_3;
+		i2c4 = &hsi2c_4;
+		i2c5 = &hsi2c_5;
+		i2c6 = &hsi2c_6;
+		i2c7 = &hsi2c_7;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpucl0_0>;
+				};
+				core1 {
+					cpu = <&cpucl0_1>;
+				};
+				core2 {
+					cpu = <&cpucl0_2>;
+				};
+				core3 {
+					cpu = <&cpucl0_3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpucl1_0>;
+				};
+				core1 {
+					cpu = <&cpucl1_1>;
+				};
+				core2 {
+					cpu = <&cpucl1_2>;
+				};
+				core3 {
+					cpu = <&cpucl1_3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpucl2_0>;
+				};
+				core1 {
+					cpu = <&cpucl2_1>;
+				};
+				core2 {
+					cpu = <&cpucl2_2>;
+				};
+				core3 {
+					cpu = <&cpucl2_3>;
+				};
+			};
+		};
+
+		/* Cluster 0 */
+		cpucl0_0: cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x000>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_1: cpu at 1 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x001>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_2: cpu at 2 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x002>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_3: cpu at 3 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x003>;
+				enable-method = "psci";
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 1 */
+		cpucl1_0: cpu at 100 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x100>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_1: cpu at 101 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x101>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_2: cpu at 102 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x102>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_3: cpu at 103 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x103>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 2 */
+		cpucl2_0: cpu at 200 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x200>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_1: cpu at 201 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x201>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_2: cpu at 202 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x202>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_3: cpu at 203 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x203>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP: cpu-sleep {
+				idle-state-name = "c2";
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <30>;
+				exit-latency-us = <75>;
+				min-residency-us = <300>;
+			};
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	fin_pll: clock {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		#clock-cells = <0>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+		gic: interrupt-controller at 10400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
+				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+		};
+
+		smmu_imem: iommu at 10200000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x10200000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <7>;
+			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
+				     /* Per context non-secure context interrupts, 0-3 interrupts */
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+		};
+
+		smmu_isp: iommu at 12100000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x12100000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <11>;
+			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+				     /* Per context non-secure context interrupts, 0-7 interrupts */
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+		};
+
+		smmu_peric: iommu at 14900000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x14900000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		smmu_fsys0: iommu at 15450000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x15450000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		clock_imem: clock-controller at 10010000 {
+			compatible = "tesla,fsd-clock-imem";
+			reg = <0x0 0x10010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
+				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_imem_tcuclk",
+				"dout_cmu_imem_aclk",
+				"dout_cmu_imem_dmaclk";
+		};
+
+		clock_cmu: clock-controller at 11c10000 {
+			compatible = "tesla,fsd-clock-cmu";
+			reg = <0x0 0x11c10000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_csi: clock-controller at 12610000 {
+			compatible = "tesla,fsd-clock-cam_csi";
+			reg = <0x0 0x12610000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_mfc: clock-controller at 12810000 {
+			compatible = "tesla,fsd-clock-mfc";
+			reg = <0x0 0x12810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_peric: clock-controller at 14010000 {
+			compatible = "tesla,fsd-clock-peric";
+			reg = <0x0 0x14010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div4",
+				"dout_cmu_peric_shared1div36",
+				"dout_cmu_peric_shared0div3_tbuclk",
+				"dout_cmu_peric_shared0div20",
+				"dout_cmu_peric_shared1div4_dmaclk";
+		};
+
+		clock_fsys0: clock-controller at 15010000 {
+			compatible = "tesla,fsd-clock-fsys0";
+			reg = <0x0 0x15010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div6",
+				"dout_cmu_fsys0_shared1div4",
+				"dout_cmu_fsys0_shared0div4";
+		};
+
+		clock_fsys1: clock-controller at 16810000 {
+			compatible = "tesla,fsd-clock-fsys1";
+			reg = <0x0 0x16810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_fsys1_shared0div8",
+				"dout_cmu_fsys1_shared0div4";
+		};
+
+		mdma0: mdma at 10100000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10100000 0x0 0x1000>;
+			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x800 0x0>;
+		};
+
+		mdma1: mdma at 10110000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10110000 0x0 0x1000>;
+			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x801 0x0>;
+		};
+
+		pdma0: pdma at 14280000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x2 0x0>;
+		};
+
+		pdma1: pdma at 14290000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x1 0x0>;
+		};
+
+		serial_0: serial at 14180000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14180000 0x0 0x100>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 0>, <&pdma1 1>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART0>,
+				 <&clock_peric PERIC_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		serial_1: serial at 14190000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14190000 0x0 0x100>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 2>, <&pdma1 3>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART1>,
+				 <&clock_peric PERIC_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller at 11400000 {
+			compatible = "samsung,exynos7-pmu", "syscon";
+			reg = <0x0 0x11400000 0x0 0x5000>;
+		};
+
+		watchdog_0: watchdog at 100a0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100a0000 0x0 0x100>;
+			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_1: watchdog at 100b0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100b0000 0x0 0x100>;
+			interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_2: watchdog at 100c0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100c0000 0x0 0x100>;
+			interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		pwm_0: pwm at 14100000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14100000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		pwm_1: pwm at 14110000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14110000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		hsi2c_0: hsi2c at 14200000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14200000 0x0 0x1000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: hsi2c at 14210000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14210000 0x0 0x1000>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: hsi2c at 14220000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14220000 0x0 0x1000>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: hsi2c at 14230000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14230000 0x0 0x1000>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: hsi2c at 14240000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14240000 0x0 0x1000>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: hsi2c at 14250000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14250000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: hsi2c at 14260000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: hsi2c at 14270000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+	};
+};
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:50 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:50 +0530
Subject: [PATCH v2 15/16] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150112epcas5p4b63030d9bf136b4a91468b0d02e75cae@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-16-alim.akhtar@samsung.com>

Add initial pin configuration nodes for FSD SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 335 +++++++++++++++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
 2 files changed, 357 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi

diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..371344e446f3
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf6: gpf6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric {
+	gpc8: gpc8 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb4: gpb4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb5: gpb5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb6: gpb6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb7: gpb7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd3: gpd3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg4: gpg4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg5: gpg5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg6: gpg6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg7: gpg7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	pwm0_out: pwm0-out {
+		samsung,pins = "gpb6-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	pwm1_out: pwm1-out {
+		samsung,pins = "gpb6-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	hs_i2c0_bus: hs-i2c0-bus {
+		samsung,pins = "gpb0-0", "gpb0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus {
+		samsung,pins = "gpb0-2", "gpb0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus {
+		samsung,pins = "gpb0-4", "gpb0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus {
+		samsung,pins = "gpb0-6", "gpb0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus {
+		samsung,pins = "gpb1-0", "gpb1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus {
+		samsung,pins = "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus {
+		samsung,pins = "gpb1-4", "gpb1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus {
+		samsung,pins = "gpb1-6", "gpb1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_data: uart0-data {
+		samsung,pins = "gpb7-0", "gpb7-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data {
+		samsung,pins = "gpb7-4", "gpb7-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus {
+		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus {
+		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus {
+		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_pmu {
+	gpq0: gpq0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 9a2b88f58c13..bab63c9f79dc 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -26,6 +26,9 @@ aliases {
 		i2c5 = &hsi2c_5;
 		i2c6 = &hsi2c_6;
 		i2c7 = &hsi2c_7;
+		pinctrl0 = &pinctrl_fsys0;
+		pinctrl1 = &pinctrl_peric;
+		pinctrl2 = &pinctrl_pmu;
 	};
 
 	cpus {
@@ -647,5 +650,24 @@ hsi2c_7: hsi2c at 14270000 {
 			clock-names = "hsi2c";
 			status = "disabled";
 		};
+
+		pinctrl_pmu: pinctrl at 114f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x114f0000 0x0 0x1000>;
+		};
+
+		pinctrl_peric: pinctrl at 141f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x141f0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys0: pinctrl at 15020000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x15020000 0x0 0x1000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
+
+#include "fsd-pinctrl.dtsi"
-- 
2.25.1



From alim.akhtar at samsung.com  Tue Jan 18 06:48:51 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 18 Jan 2022 20:18:51 +0530
Subject: [PATCH v2 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220118144851.69537-1-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150116epcas5p415b4b658b3ca3fe5e52e11a33546b926@epcas5p4.samsung.com>
Message-ID: <20220118144851.69537-17-alim.akhtar@samsung.com>

This patch enables the Tesla FSD SoC in arm64 defconfig.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index ee4bd7710a0d..7dd0693a233e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -54,6 +54,7 @@ CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_INTEL_SOCFPGA=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
-- 
2.25.1



From robin.murphy at arm.com  Tue Jan 18 07:01:46 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 18 Jan 2022 15:01:46 +0000
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com> <YeF/AYZ0DuKGwLLk@maud>
 <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>
Message-ID: <69525223-7d90-5714-bbe9-4d7f0b9a293d@arm.com>

On 2022-01-18 07:19, Chen-Yu Tsai wrote:
> Hi,
> 
> On Fri, Jan 14, 2022 at 9:47 PM Alyssa Rosenzweig <alyssa at collabora.com> wrote:
>>
>>>> That links to an internal Google issue tracker which I assume has more
>>>> information on the bug. I would appreciate if someone from Google or
>>>> MediaTek could explain what this change actually does and why it's
>>>> necessary on MT8192.
>>>>
>>>> At any rate, this register logically belongs to the MT8192 "infra" clock
>>>> device, so it makes sense to set it there too. This avoids adding any
>>>> platform-specific hacks to the 3D driver, either mainline (Panfrost) or
>>>> legacy (kbase).
>>>
>>> Does this really have anything to do with clocks?
>>
>> I have no idea. MediaTek, Google, please explain.
>>
>>> In particular, "ACP" usually refers to the Accelerator Coherency Port
>>> of a CPU cluster or DSU, and given the stated symptom of the issue
>>> affected by it, my first guess would be that this bit might indeed
>>> control routing of GPU traffic either to the ACP or the (presumably
>>> non-coherent) main interconnect.
>>
>> I'd easily believe that.
> 
> As Robin guessed, "ACP" here does refer to the Accelerator Coherency Port.
> And the bit in infracfg toggles whether ACP is used or not.
> 
> Explanation from MediaTek in verbatim:
> 
> -------------------------------------------------------------------------
> The ACP path on MT8192 is just for experimental only.
> We are not intended to enable ACP by design.
> 
> But due to an unexpected operation, it was accidently opened by default.
> So we need a patch to disable the ACP for MT8192.
> -------------------------------------------------------------------------

Aha! That's great, thanks ChenYu!

Stephen, my thinking here is that if this feature controls the GPU 
interconnect, and only matters when the GPU is going to be used (as 
strongly implied by the downstream implementation), then the GPU driver 
is the only interested party and may as well take responsibility if 
there's no better alternative.

I'd agree that if there was already a "base" infracfg driver doing 
general system-wide set-and-forget configuration then it would equally 
well fit in there, but that doesn't seem to be the case. Short of trying 
to abuse the bp_infracfg data in the mtk-pm-domains driver (which 
doesn't seem like a particularly pleasant idea), the code to poke a bit 
into a syscon regmap is going to be pretty much the same wherever we add 
it. There's already a bit of a pattern for MTK drivers to look up and 
poke their own infracfg bits directly as needed, so between that and the 
downstream implementation for this particular bit, leaving it to 
Panfrost seems like the least surprising option.

Cheers,
Robin.


From benjamin.gaignard at collabora.com  Tue Jan 18 07:07:17 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Tue, 18 Jan 2022 16:07:17 +0100
Subject: [PATCH] media: platform: mtk-vcodec: Do not force /dev/videoX node
 number
Message-ID: <20220118150717.706074-1-benjamin.gaignard@collabora.com>

Let's v4l2 framework use a free /dev/videoX node for decode and encoder.
For the decoder call video_register_device() before register the media
controller device so the mapping between ins correctly done.
Since the registering sequence has changed rework exiting errors case too.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 27 +++++++++----------
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  2 +-
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 86b639d82be8..a4a3f9631d04 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -374,7 +374,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
 		mtk_v4l2_err("Failed to init mem2mem dec device");
 		ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
-		goto err_dec_mem_init;
+		goto err_dec_alloc;
 	}
 
 	dev->decode_workqueue =
@@ -391,10 +391,16 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 					   &pdev->dev);
 		if (ret) {
 			mtk_v4l2_err("Main device of_platform_populate failed.");
-			goto err_event_workq;
+			goto err_reg_cont;
 		}
 	}
 
+	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		mtk_v4l2_err("Failed to register video device");
+		goto err_reg_cont;
+	}
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
@@ -408,7 +414,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 							 MEDIA_ENT_F_PROC_VIDEO_DECODER);
 		if (ret) {
 			mtk_v4l2_err("Failed to register media controller");
-			goto err_reg_cont;
+			goto err_dec_mem_init;
 		}
 
 		ret = media_device_register(&dev->mdev_dec);
@@ -419,30 +425,21 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 		mtk_v4l2_debug(0, "media registered as /dev/media%d", vfd_dec->minor);
 	}
-	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
-	if (ret) {
-		mtk_v4l2_err("Failed to register video device");
-		goto err_dec_reg;
-	}
 
 	mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor);
 
 	return 0;
 
-err_dec_reg:
-	if (dev->vdec_pdata->uses_stateless_api)
-		media_device_unregister(&dev->mdev_dec);
 err_media_reg:
-	if (dev->vdec_pdata->uses_stateless_api)
-		v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+	v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+err_dec_mem_init:
+	video_unregister_device(vfd_dec);
 err_reg_cont:
 	if (dev->vdec_pdata->uses_stateless_api)
 		media_device_cleanup(&dev->mdev_dec);
 	destroy_workqueue(dev->decode_workqueue);
 err_event_workq:
 	v4l2_m2m_release(dev->m2m_dev_dec);
-err_dec_mem_init:
-	video_unregister_device(vfd_dec);
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_core_workq:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..3975613b75b3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -350,7 +350,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
 		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
 
-	ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, 1);
+	ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, -1);
 	if (ret) {
 		mtk_v4l2_err("Failed to register video device");
 		goto err_enc_reg;
-- 
2.30.2



From heiko at sntech.de  Tue Jan 18 07:18:54 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Tue, 18 Jan 2022 16:18:54 +0100
Subject: [PATCH 0/4] add GPU for RK356x SoCs
In-Reply-To: <20211126151729.1026566-1-knaerzche@gmail.com>
References: <20211126151729.1026566-1-knaerzche@gmail.com>
Message-ID: <6645896.O1m7UbTlE4@diego>

Hi Alex,

Am Freitag, 26. November 2021, 16:17:25 CET schrieb Alex Bee:
> This is a respin of Ezequiel's series which adds GPU for RK3568 [0]:
> 
> > I've decided to split the GPU off previous series:

do you plan on a respin for Rob's comments?

Thanks
Heiko

> >
> > https://lore.kernel.org/linux-rockchip/2147216.TLkxdtWsSY at diego/
> >
> > This series now contains only the GPU support, as the VPU
> > needs a tiny rework.
> >
> > This is compiled tested only, in this case. Similar patches
> > have been tested on a v5.10-based kernel, so I'd say it's good
> > to go.
> >
> > The mesa side is merged https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10771
> > and can be tested without a display, using something like weston --backend=headless-backend.so,
> > which provides an environment for GL to work.
> 
> I hope to have resolved all DT-binding issues and added cooling map and trip points
> which can make the GPU a cooling device.
> 
> Tested with mesa 21.3.0 on quartz64-a board.
> 
> [0] https://patchwork.kernel.org/project/linux-rockchip/list/?series=526661
> 
> Alex Bee (2):
>   dt-bindings: gpu: mali-bifrost: Allow up to two clocks
>   arm64: dts: rockchip: Add cooling map / trip points for RK356x' GPU
> 
> Ezequiel Garcia (2):
>   arm64: dts: rockchip: Add GPU node for rk3568
>   arm64: dts: rockchip: Enable the GPU on Quartz64 Model A
> 
>  .../bindings/gpu/arm,mali-bifrost.yaml        | 20 ++++-
>  .../boot/dts/rockchip/rk3566-quartz64-a.dts   |  5 ++
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi      | 77 +++++++++++++++++++
>  3 files changed, 101 insertions(+), 1 deletion(-)
> 
> 






From linux at armlinux.org.uk  Tue Jan 18 07:45:55 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 15:45:55 +0000
Subject: [PATCH v5 11/69] KVM: arm64: nv: Add nested virt VCPU primitives
 for vEL2 VCPU state
In-Reply-To: <20211129200150.351436-12-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-12-maz@kernel.org>
Message-ID: <Yebgs/vsczGLfLqP@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:52PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> When running a nested hypervisor we commonly have to figure out if
> the VCPU mode is running in the context of a guest hypervisor or guest
> guest, or just a normal guest.
> 
> Add convenient primitives for this.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan 18 07:51:30 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 15:51:30 +0000
Subject: [PATCH v5 12/69] KVM: arm64: nv: Handle HCR_EL2.NV system
 register traps
In-Reply-To: <20211129200150.351436-13-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-13-maz@kernel.org>
Message-ID: <YebiAjUTzVECLOun@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:53PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
> this bit is set, accessing EL2 registers in EL1 traps to EL2. In
> addition, executing the following instructions in EL1 will trap to EL2:
> tlbi, at, eret, and msr/mrs instructions to access SP_EL1. Most of the
> instructions that trap to EL2 with the NV bit were undef at EL1 prior to
> ARM v8.3. The only instruction that was not undef is eret.
> 
> This patch sets up a handler for EL2 registers and SP_EL1 register
> accesses at EL1. The host hypervisor keeps those register values in
> memory, and will emulate their behavior.
> 
> This patch doesn't set the NV bit yet. It will be set in a later patch
> once nested virtualization support is completed.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> [maz: added SCTLR_EL2 RES0/RES1 handling]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
...
> @@ -1825,9 +1882,51 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
>  	  .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
>  
> +	{ SYS_DESC(SYS_VPIDR_EL2), access_rw, reset_val, VPIDR_EL2, 0 },
> +	{ SYS_DESC(SYS_VMPIDR_EL2), access_rw, reset_val, VMPIDR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_SCTLR_EL2), access_sctlr_el2, reset_val, SCTLR_EL2, SCTLR_EL2_RES1 },
> +	{ SYS_DESC(SYS_ACTLR_EL2), access_rw, reset_val, ACTLR_EL2, 0 },
> +	{ SYS_DESC(SYS_HCR_EL2), access_rw, reset_val, HCR_EL2, 0 },
> +	{ SYS_DESC(SYS_MDCR_EL2), access_rw, reset_val, MDCR_EL2, 0 },
> +	{ SYS_DESC(SYS_CPTR_EL2), access_rw, reset_val, CPTR_EL2, CPTR_EL2_DEFAULT },
> +	{ SYS_DESC(SYS_HSTR_EL2), access_rw, reset_val, HSTR_EL2, 0 },
> +	{ SYS_DESC(SYS_HACR_EL2), access_rw, reset_val, HACR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_TTBR0_EL2), access_rw, reset_val, TTBR0_EL2, 0 },
> +	{ SYS_DESC(SYS_TTBR1_EL2), access_rw, reset_val, TTBR1_EL2, 0 },
> +	{ SYS_DESC(SYS_TCR_EL2), access_rw, reset_val, TCR_EL2, TCR_EL2_RES1 },
> +	{ SYS_DESC(SYS_VTTBR_EL2), access_rw, reset_val, VTTBR_EL2, 0 },
> +	{ SYS_DESC(SYS_VTCR_EL2), access_rw, reset_val, VTCR_EL2, 0 },
> +
>  	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
> +	{ SYS_DESC(SYS_SPSR_EL2), access_rw, reset_val, SPSR_EL2, 0 },
> +	{ SYS_DESC(SYS_ELR_EL2), access_rw, reset_val, ELR_EL2, 0 },
> +	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
> +
>  	{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },
> +	{ SYS_DESC(SYS_AFSR0_EL2), access_rw, reset_val, AFSR0_EL2, 0 },
> +	{ SYS_DESC(SYS_AFSR1_EL2), access_rw, reset_val, AFSR1_EL2, 0 },
> +	{ SYS_DESC(SYS_ESR_EL2), access_rw, reset_val, ESR_EL2, 0 },
>  	{ SYS_DESC(SYS_FPEXC32_EL2), NULL, reset_val, FPEXC32_EL2, 0x700 },
> +
> +	{ SYS_DESC(SYS_FAR_EL2), access_rw, reset_val, FAR_EL2, 0 },
> +	{ SYS_DESC(SYS_HPFAR_EL2), access_rw, reset_val, HPFAR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_MAIR_EL2), access_rw, reset_val, MAIR_EL2, 0 },
> +	{ SYS_DESC(SYS_AMAIR_EL2), access_rw, reset_val, AMAIR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_VBAR_EL2), access_rw, reset_val, VBAR_EL2, 0 },
> +	{ SYS_DESC(SYS_RVBAR_EL2), access_rw, reset_val, RVBAR_EL2, 0 },
> +	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
> +
> +	{ SYS_DESC(SYS_CONTEXTIDR_EL2), access_rw, reset_val, CONTEXTIDR_EL2, 0 },
> +	{ SYS_DESC(SYS_TPIDR_EL2), access_rw, reset_val, TPIDR_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_CNTVOFF_EL2), access_rw, reset_val, CNTVOFF_EL2, 0 },
> +	{ SYS_DESC(SYS_CNTHCTL_EL2), access_rw, reset_val, CNTHCTL_EL2, 0 },
> +
> +	{ SYS_DESC(SYS_SP_EL2), NULL, reset_unknown, SP_EL2 },

Doesn't this have an effect on the ability to migrate guests between
identical hardware but running kernels with vs without this patch?
>From what I remember, QEMU fails a migration if the migration target
has less system registers than the migration source.

If so, this should at the very least be spelt out in the commit
message - it's a user experience breaking change. Maybe also preventing
the exposure of these when NV is disabled would be a good idea?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan 18 07:52:46 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 15:52:46 +0000
Subject: [PATCH v5 13/69] KVM: arm64: nv: Reset VMPIDR_EL2 and VPIDR_EL2
 to sane values
In-Reply-To: <20211129200150.351436-14-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-14-maz@kernel.org>
Message-ID: <YebiThx2+EoaFEeP@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:54PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> The VMPIDR_EL2 and VPIDR_EL2 are architecturally UNKNOWN at reset, but
> let's be nice to a guest hypervisor behaving foolishly and reset these
> to something reasonable anyway.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan 18 08:02:28 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 16:02:28 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <20211129200150.351436-15-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
Message-ID: <YebklBdMSwOplyrJ@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> Support injecting exceptions and performing exception returns to and
> from virtual EL2.  This must be done entirely in software except when
> taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
> == {1,1}  (a VHE guest hypervisor).
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> [maz: switch to common exception injection framework]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
...
> +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> +{
> +	u64 spsr, elr, mode;
> +	bool direct_eret;
> +
> +	/*
> +	 * Going through the whole put/load motions is a waste of time
> +	 * if this is a VHE guest hypervisor returning to its own
> +	 * userspace, or the hypervisor performing a local exception
> +	 * return. No need to save/restore registers, no need to
> +	 * switch S2 MMU. Just do the canonical ERET.
> +	 */
> +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +
> +	direct_eret  = (mode == PSR_MODE_EL0t &&
> +			vcpu_el2_e2h_is_set(vcpu) &&
> +			vcpu_el2_tge_is_set(vcpu));
> +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);

There are excessive parens on the RHS of the above two.

> +static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2,
> +				     enum exception_type type)
> +{
> +	trace_kvm_inject_nested_exception(vcpu, esr_el2, type);
> +
> +	switch (type) {
> +	case except_type_sync:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_SYNC;
> +		break;
> +	case except_type_irq:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_IRQ;
> +		break;
> +	default:
> +		WARN_ONCE(1, "Unsupported EL2 exception injection %d\n", type);
> +	}
> +
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL2		|
> +			     KVM_ARM64_PENDING_EXCEPTION);

Ditto, and the "|" has too much white space before it with no good
reason.

> +/*
> + * Emulate taking an exception to EL2.
> + * See ARM ARM J8.1.2 AArch64.TakeException()
> + */
> +static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
> +			     enum exception_type type)
> +{
> +	u64 pstate, mode;
> +	bool direct_inject;
> +
> +	if (!nested_virt_in_use(vcpu)) {
> +		kvm_err("Unexpected call to %s for the non-nesting configuration\n",
> +				__func__);

Too much indentation. I'm guessing this "unexpected" condition isn't
something that can be caused by a rogue guest? If it can, doesn't this
need to be rate limited?

> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * As for ERET, we can avoid doing too much on the injection path by
> +	 * checking that we either took the exception from a VHE host
> +	 * userspace or from vEL2. In these cases, there is no change in
> +	 * translation regime (or anything else), so let's do as little as
> +	 * possible.
> +	 */
> +	pstate = *vcpu_cpsr(vcpu);
> +	mode = pstate & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +
> +	direct_inject  = (mode == PSR_MODE_EL0t &&
> +			  vcpu_el2_e2h_is_set(vcpu) &&
> +			  vcpu_el2_tge_is_set(vcpu));
> +	direct_inject |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);

Too many parens again...

> diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> index 0418399e0a20..4ef5e86efd8b 100644
> --- a/arch/arm64/kvm/hyp/exception.c
> +++ b/arch/arm64/kvm/hyp/exception.c
...
> @@ -149,7 +167,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
>  	new |= target_mode;
>  
>  	*vcpu_cpsr(vcpu) = new;
> -	__vcpu_write_spsr(vcpu, old);
> +	__vcpu_write_spsr(vcpu, target_mode, old);
>  }
>  
>  /*
> @@ -320,11 +338,22 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
>  		      KVM_ARM64_EXCEPT_AA64_EL1):
>  			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync);
>  			break;
> +
> +		case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> +		      KVM_ARM64_EXCEPT_AA64_EL2):

Too many parens...

> +			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_sync);
> +			break;
> +
> +		case (KVM_ARM64_EXCEPT_AA64_ELx_IRQ |
> +		      KVM_ARM64_EXCEPT_AA64_EL2):

Too many parens...

> diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> index b47df73e98d7..5dcf3f8b08b8 100644
> --- a/arch/arm64/kvm/inject_fault.c
> +++ b/arch/arm64/kvm/inject_fault.c
> @@ -12,19 +12,58 @@
>  
>  #include <linux/kvm_host.h>
>  #include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/esr.h>
>  
> +static void pend_sync_exception(struct kvm_vcpu *vcpu)
> +{
> +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
> +			     KVM_ARM64_PENDING_EXCEPTION);

Too many parens...

> +
> +	/* If not nesting, EL1 is the only possible exception target */
> +	if (likely(!nested_virt_in_use(vcpu))) {
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		return;
> +	}
> +
> +	/*
> +	 * With NV, we need to pick between EL1 and EL2. Note that we
> +	 * never deal with a nesting exception here, hence never
> +	 * changing context, and the exception itself can be delayed
> +	 * until the next entry.
> +	 */
> +	switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
> +	case PSR_MODE_EL2h:
> +	case PSR_MODE_EL2t:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> +		break;
> +	case PSR_MODE_EL1h:
> +	case PSR_MODE_EL1t:
> +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		break;
> +	case PSR_MODE_EL0t:
> +		if (vcpu_el2_tge_is_set(vcpu) & HCR_TGE)
> +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> +		else
> +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> +		break;
> +	default:
> +		BUG();

Is taking out the host really appropriate here? Is this something a
rogue guest could trigger?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan 18 08:04:21 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 16:04:21 +0000
Subject: [PATCH v5 15/69] KVM: arm64: nv: Inject HVC exceptions to the
 virtual EL2
In-Reply-To: <20211129200150.351436-16-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-16-maz@kernel.org>
Message-ID: <YeblBbmkvD7XwmIt@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:56PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> As we expect all PSCI calls from the L1 hypervisor to be performed
> using SMC when nested virtualization is enabled, it is clear that
> all HVC instruction from the VM (including from the virtual EL2)
> are supposed to handled in the virtual EL2.
> 
> Forward these to EL2 as required.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> [maz: add handling of HCR_EL2.HCD]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/handle_exit.c | 11 +++++++++++

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Tue Jan 18 08:05:13 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 18 Jan 2022 16:05:13 +0000
Subject: [PATCH v5 16/69] KVM: arm64: nv: Handle trapped ERET from
 virtual EL2
In-Reply-To: <20211129200150.351436-17-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-17-maz@kernel.org>
Message-ID: <YeblObUkkBeWy079@shell.armlinux.org.uk>

On Mon, Nov 29, 2021 at 08:00:57PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> When a guest hypervisor running virtual EL2 in EL1 executes an ERET
> instruction, we will have set HCR_EL2.NV which traps ERET to EL2, so
> that we can emulate the exception return in software.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mst at redhat.com  Tue Jan 18 08:05:29 2022
From: mst at redhat.com (Michael S. Tsirkin)
Date: Tue, 18 Jan 2022 11:05:29 -0500
Subject: [PATCH v2] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <2f0d1a5f-7e75-04b1-f2a1-f52385dae3b5@redhat.com>
References: <20220118084858.175305-1-gshan@redhat.com>
 <2f0d1a5f-7e75-04b1-f2a1-f52385dae3b5@redhat.com>
Message-ID: <20220118110512-mutt-send-email-mst@kernel.org>

On Tue, Jan 18, 2022 at 05:38:20PM +0800, Gavin Shan wrote:
> On 1/18/22 4:48 PM, Gavin Shan wrote:
> > This enables virtio-mem device support by allowing to enable the
> > corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
> > architecture.
> > 
> > Signed-off-by: Gavin Shan <gshan at redhat.com>
> > Acked-by: David Hildenbrand <david at redhat.com>
> > ---
> > v2: Improved the comments about the kernel config option (David)
> > ---
> >   drivers/virtio/Kconfig | 7 ++++---
> >   1 file changed, 4 insertions(+), 3 deletions(-)
> 
> My git-sendemail should have been broken. A list of receivers are
> dropped automatically though they were explicitly specified, but
> linux-arm-kernel at lists.infradead.org was missed to be copied.
> Fixing all of them through thunderbird :)
> 
> Thanks,
> Gavin

Pls bounce the original patch to me so I can queue it.


> > diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> > index 34f80b7a8a64..74c8b0c7bc33 100644
> > --- a/drivers/virtio/Kconfig
> > +++ b/drivers/virtio/Kconfig
> > @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
> >   config VIRTIO_MEM
> >   	tristate "Virtio mem driver"
> >   	default m
> > -	depends on X86_64
> > +	depends on X86_64 || ARM64
> >   	depends on VIRTIO
> >   	depends on MEMORY_HOTPLUG
> >   	depends on MEMORY_HOTREMOVE
> > @@ -116,8 +116,9 @@ config VIRTIO_MEM
> >   	 This driver provides access to virtio-mem paravirtualized memory
> >   	 devices, allowing to hotplug and hotunplug memory.
> > -	 This driver was only tested under x86-64, but should theoretically
> > -	 work on all architectures that support memory hotplug and hotremove.
> > +	 This driver was only tested under x86-64 and arm64, but should
> > +	 theoretically work on all architectures that support memory hotplug
> > +	 and hotremove.
> >   	 If unsure, say M.
> > 



From krzysztof.kozlowski at canonical.com  Tue Jan 18 08:18:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 17:18:28 +0100
Subject: [PATCH v2 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220118144851.69537-3-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150018epcas5p32642af7af63869d08a861d00d97e3b68@epcas5p3.samsung.com>
 <20220118144851.69537-3-alim.akhtar@samsung.com>
Message-ID: <a7677638-8108-0bd7-19ca-0cfff5fcf534@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Clock controller driver of FSD platform is designed to have separate
> instances for each particular CMU. So clock IDs in this bindings header
> also start from 1 for each CMU block.
> 
> Cc: linux-fsd at tesla.com
> Reported-by: kernel test robot <lkp at intel.com>
> [robot: reported missing #endif]
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  include/dt-bindings/clock/fsd-clk.h | 149 ++++++++++++++++++++++++++++
>  1 file changed, 149 insertions(+)
>  create mode 100644 include/dt-bindings/clock/fsd-clk.h
> 
> diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
> new file mode 100644
> index 000000000000..8cf45d2430b0
> --- /dev/null
> +++ b/include/dt-bindings/clock/fsd-clk.h
> @@ -0,0 +1,149 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
> + *             https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *             https://www.tesla.com
> + *
> + * The constants defined in this header are being used in dts
> + * and fsd platform driver.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_FSD_H
> +#define _DT_BINDINGS_CLOCK_FSD_H
> +
> +/* CMU */
> +#define DOUT_CMU_PLL_SHARED0_DIV4		1
> +#define DOUT_CMU_PERIC_SHARED1DIV36		2
> +#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
> +#define DOUT_CMU_PERIC_SHARED0DIV20		4
> +#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
> +#define DOUT_CMU_PLL_SHARED0_DIV6		6
> +#define DOUT_CMU_FSYS0_SHARED1DIV4		7
> +#define DOUT_CMU_FSYS0_SHARED0DIV4		8
> +#define DOUT_CMU_FSYS1_SHARED0DIV8		9
> +#define DOUT_CMU_FSYS1_SHARED0DIV4		10
> +#define CMU_CPUCL_SWITCH_GATE			11
> +#define DOUT_CMU_IMEM_TCUCLK			12
> +#define DOUT_CMU_IMEM_ACLK			13
> +#define DOUT_CMU_IMEM_DMACLK			14
> +#define GAT_CMU_FSYS0_SHARED0DIV4		15
> +#define CMU_NR_CLK				16
> +
> +/* PERIC */
> +#define PERIC_SCLK_UART0			1
> +#define PERIC_PCLK_UART0			2
> +#define PERIC_SCLK_UART1			3
> +#define PERIC_PCLK_UART1			4
> +#define PERIC_DMA0_IPCLKPORT_ACLK		5
> +#define PERIC_DMA1_IPCLKPORT_ACLK		6
> +#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
> +#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
> +#define PERIC_PCLK_SPI0                         9
> +#define PERIC_SCLK_SPI0                         10
> +#define PERIC_PCLK_SPI1                         11
> +#define PERIC_SCLK_SPI1                         12
> +#define PERIC_PCLK_SPI2                         13
> +#define PERIC_SCLK_SPI2                         14
> +#define PERIC_PCLK_TDM0                         15
> +#define PERIC_PCLK_HSI2C0			16
> +#define PERIC_PCLK_HSI2C1			17
> +#define PERIC_PCLK_HSI2C2			18
> +#define PERIC_PCLK_HSI2C3			19
> +#define PERIC_PCLK_HSI2C4			20
> +#define PERIC_PCLK_HSI2C5			21
> +#define PERIC_PCLK_HSI2C6			22
> +#define PERIC_PCLK_HSI2C7			23
> +#define PERIC_MCAN0_IPCLKPORT_CCLK		24
> +#define PERIC_MCAN0_IPCLKPORT_PCLK		25
> +#define PERIC_MCAN1_IPCLKPORT_CCLK		26
> +#define PERIC_MCAN1_IPCLKPORT_PCLK		27
> +#define PERIC_MCAN2_IPCLKPORT_CCLK		28
> +#define PERIC_MCAN2_IPCLKPORT_PCLK		29
> +#define PERIC_MCAN3_IPCLKPORT_CCLK		30
> +#define PERIC_MCAN3_IPCLKPORT_PCLK		31
> +#define PERIC_PCLK_ADCIF			32
> +#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
> +#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
> +#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
> +#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
> +#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
> +#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
> +#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
> +#define PERIC_HCLK_TDM0				40
> +#define PERIC_PCLK_TDM1				41
> +#define PERIC_HCLK_TDM1				42
> +#define PERIC_EQOS_PHYRXCLK_MUX			43
> +#define PERIC_EQOS_PHYRXCLK			44
> +#define PERIC_DOUT_RGMII_CLK			45
> +#define PERIC_NR_CLK				46
> +
> +/* FSYS0 */
> +#define UFS0_MPHY_REFCLK_IXTAL24		1
> +#define UFS0_MPHY_REFCLK_IXTAL26		2
> +#define UFS1_MPHY_REFCLK_IXTAL24		3
> +#define UFS1_MPHY_REFCLK_IXTAL26		4
> +#define UFS0_TOP0_HCLK_BUS			5
> +#define UFS0_TOP0_ACLK				6
> +#define UFS0_TOP0_CLK_UNIPRO			7
> +#define UFS0_TOP0_FMP_CLK			8
> +#define UFS1_TOP1_HCLK_BUS			9
> +#define UFS1_TOP1_ACLK				10
> +#define UFS1_TOP1_CLK_UNIPRO			11
> +#define UFS1_TOP1_FMP_CLK			12
> +#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
> +#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
> +#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
> +#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
> +#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
> +#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
> +#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
> +#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
> +#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
> +#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
> +#define FSYS0_NR_CLK				23
> +
> +/* FSYS1 */
> +#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
> +#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
> +#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
> +#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
> +#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
> +#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
> +#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
> +#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
> +#define FSYS1_NR_CLK				9
> +
> +/* IMEM */
> +#define IMEM_DMA0_IPCLKPORT_ACLK		1
> +#define IMEM_DMA1_IPCLKPORT_ACLK		2
> +#define IMEM_WDT0_IPCLKPORT_PCLK		3
> +#define IMEM_WDT1_IPCLKPORT_PCLK		4
> +#define IMEM_WDT2_IPCLKPORT_PCLK		5
> +#define IMEM_MCT_PCLK				6
> +#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
> +#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
> +#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
> +#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
> +#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
> +#define IMEM_NR_CLK				12
> +
> +/* MFC */
> +#define MFC_MFC_IPCLKPORT_ACLK			1
> +#define MFC_NR_CLK				2
> +
> +/* CAM_CSI */
> +#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
> +#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
> +#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
> +#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
> +#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
> +#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
> +#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
> +#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
> +#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
> +#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
> +#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
> +#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
> +#define CAM_CSI_NR_CLK				13

One empty line would be nice here.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

> +#endif /*_DT_BINDINGS_CLOCK_FSD_H */
> 


Best regards,
Krzysztof


From james.clark at arm.com  Tue Jan 18 08:28:29 2022
From: james.clark at arm.com (James Clark)
Date: Tue, 18 Jan 2022 16:28:29 +0000
Subject: [RFC PATCH 1/2] perf: arm_spe: Fix consistency of PMSCR register
 bit CX
In-Reply-To: <20220118100702.GB16547@willie-the-truck>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-2-german.gomez@arm.com>
 <20220118100702.GB16547@willie-the-truck>
Message-ID: <0afb1f94-8f35-72af-cead-f3a0d18e0dbc@arm.com>



On 18/01/2022 10:07, Will Deacon wrote:
> On Mon, Jan 17, 2022 at 12:44:31PM +0000, German Gomez wrote:
>> The arm_spe_pmu driver will enable the CX bit of the PMSCR register in
>> order to add CONTEXT packets into the traces if the owner of the perf
>> event runs with capabilities CAP_PERFMON or CAP_SYS_ADMIN.
>>
>> The value of the bit is computed in the arm_spe_event_to_pmscr function
>> [1], and the check for capabilities happens in [2] in the pmu init
>> callback. This suggests that the value of the CX bit should remain
>> consistent for the duration of the perf session.
>>
>> However, the function arm_spe_event_to_pmscr may be called later during
>> the start callback [3] when the "current" process is not the owner of
>> the perf session, so the CX bit is currently not consistent. Consider
>> the following example:
>>
>>   1. Run a process in the background with capability CAP_SYS_ADMIN in CPU0.
>>
>>     $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
>>     [3] 3806
>>
>>   2. Begin a perf session _without_ capabilities (we shouldn't see CONTEXT packets).
>>
>>     $ perf record -e arm_spe_0// -C0 -- sleep 1
>>     $ perf report -D | grep CONTEXT
>>     .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>     [...]
>>
>> As can be seen, the traces begin showing CONTEXT packets when the pid is
>> 0xedf (3807).
> 
> So to be clear: we shouldn't be reporting these packets because 'perf'
> doesn't have the right capabilities, but we evaluate that in the context of
> 'dd' (running as root) and so incorrectly grant the permission. Correct?

In my opinion we should be reporting context packets in this case. The only reason
a normal user is allowed to profile a root process is if they have
perf_event_paranoid <= 0. So from that perspective perf does have the right
capabilities. But a call to only perfmon_capable() doesn't look at the paranoid
value, only CAP_SYS_ADMIN and CAP_SYS_ADMIN.

> 
>> This happens because the pmu start callback is run when
>> the current process is not the owner of the perf session, so the CX
>> register bit is set.
> 
> This doesn't really seem SPE-specific to me -- the perf_allow_*() helpers
> also operate implicitly on the current task. How do other PMU drivers avoid
> falling into this trap?> 
>> One way to fix this is by caching the value of the CX bit during the
>> initialization of the PMU event, so that it remains consistent for the
>> duration of the session.
> 
> It doesn't feel right to stash this in 'struct arm_spe_pmu' during event
> initialisation -- wouldn't that allow perf to continue creating new events
> with CX set, even if the paranoid sysctl was changed dynamically? Instead,
> I think it would be better if the capabilities were stash in the event
> itself somehow at initialisation time.

If stashing is the issue then the change could be to check the right thing
every time, as in do something like the second patch in this set which
also checks perf_event_paranoid <= 0 (indirectly).

James

> 
> Will
> 


From alexandru.elisei at arm.com  Tue Jan 18 08:35:26 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 18 Jan 2022 16:35:26 +0000
Subject: [PATCH v5 15/69] KVM: arm64: nv: Inject HVC exceptions to the
 virtual EL2
In-Reply-To: <20211129200150.351436-16-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-16-maz@kernel.org>
Message-ID: <YebsTgBggC8YcCOm@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:56PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> As we expect all PSCI calls from the L1 hypervisor to be performed
> using SMC when nested virtualization is enabled, it is clear that
> all HVC instruction from the VM (including from the virtual EL2)
> are supposed to handled in the virtual EL2.
> 
> Forward these to EL2 as required.
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> [maz: add handling of HCR_EL2.HCD]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/handle_exit.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 275a27368a04..1fd1c6dfd6a0 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -16,6 +16,7 @@
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_mmu.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/debug-monitors.h>
>  #include <asm/traps.h>
>  
> @@ -40,6 +41,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
>  			    kvm_vcpu_hvc_get_imm(vcpu));
>  	vcpu->stat.hvc_exit_stat++;
>  
> +	/* Forward hvc instructions to the virtual EL2 if the guest has EL2. */
> +	if (nested_virt_in_use(vcpu)) {
> +		if (vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_HCD)
> +			kvm_inject_undefined(vcpu);
> +		else
> +			kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
> +
> +		return 1;
> +	}

Looks good to me:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,
Alex

> +
>  	ret = kvm_hvc_call_handler(vcpu);
>  	if (ret < 0) {
>  		vcpu_set_reg(vcpu, 0, ~0UL);
> -- 
> 2.30.2
> 


From alexandru.elisei at arm.com  Tue Jan 18 08:36:59 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Tue, 18 Jan 2022 16:36:59 +0000
Subject: [PATCH v5 16/69] KVM: arm64: nv: Handle trapped ERET from
 virtual EL2
In-Reply-To: <20211129200150.351436-17-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-17-maz@kernel.org>
Message-ID: <Yebsq0wWHO5mWZjx@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:57PM +0000, Marc Zyngier wrote:
> From: Christoffer Dall <christoffer.dall at arm.com>
> 
> When a guest hypervisor running virtual EL2 in EL1 executes an ERET
> instruction, we will have set HCR_EL2.NV which traps ERET to EL2, so
> that we can emulate the exception return in software.
> 
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/esr.h     |  5 +++++
>  arch/arm64/include/asm/kvm_arm.h |  2 +-
>  arch/arm64/kvm/handle_exit.c     | 10 ++++++++++
>  3 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index d52a0b269ee8..6835e4231119 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -257,6 +257,11 @@
>  		(((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >>		\
>  		 ESR_ELx_SYS64_ISS_OP2_SHIFT))
>  
> +/* ISS field definitions for ERET/ERETAA/ERETAB trapping */
> +
> +#define ESR_ELx_ERET_ISS_ERET_ERETAx	0x2
> +#define ESR_ELx_ERET_ISS_ERETA_ERATAB	0x1
                            ^^^^^
Shouldn't that be ERETAA?

Other than that, the patch looks good to me, although I'm unfamiliar with
PAuth:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,
Alex

> +
>  /*
>   * ISS field definitions for floating-point exception traps
>   * (FP_EXC_32/FP_EXC_64).
> diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> index 589a6b92d741..0a0ee998ec5a 100644
> --- a/arch/arm64/include/asm/kvm_arm.h
> +++ b/arch/arm64/include/asm/kvm_arm.h
> @@ -353,7 +353,7 @@
>  	ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
>  	ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
>  	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
> -	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
> +	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
>  
>  #define CPACR_EL1_FPEN		(3 << 20)
>  #define CPACR_EL1_TTA		(1 << 28)
> diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
> index 1fd1c6dfd6a0..95ae624d6aa8 100644
> --- a/arch/arm64/kvm/handle_exit.c
> +++ b/arch/arm64/kvm/handle_exit.c
> @@ -169,6 +169,15 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
>  	return 1;
>  }
>  
> +static int kvm_handle_eret(struct kvm_vcpu *vcpu)
> +{
> +	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET_ERETAx)
> +		return kvm_handle_ptrauth(vcpu);
> +
> +	kvm_emulate_nested_eret(vcpu);
> +	return 1;
> +}
> +
>  static exit_handle_fn arm_exit_handlers[] = {
>  	[0 ... ESR_ELx_EC_MAX]	= kvm_handle_unknown_ec,
>  	[ESR_ELx_EC_WFx]	= kvm_handle_wfx,
> @@ -183,6 +192,7 @@ static exit_handle_fn arm_exit_handlers[] = {
>  	[ESR_ELx_EC_SMC64]	= handle_smc,
>  	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
>  	[ESR_ELx_EC_SVE]	= handle_sve,
> +	[ESR_ELx_EC_ERET]	= kvm_handle_eret,
>  	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
>  	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
>  	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
> -- 
> 2.30.2
> 


From mike.leach at linaro.org  Tue Jan 18 08:38:40 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Tue, 18 Jan 2022 16:38:40 +0000
Subject: [PATCH v2 4/6] coresight: samples: Add an example config writer
 for configfs load
In-Reply-To: <20220113175636.GA967130@p14s>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-5-mike.leach@linaro.org>
 <20220113175636.GA967130@p14s>
Message-ID: <CAJ9a7Vjz7XnEMq5ZzBTkkUQOaOm9Pkoa-77hC3prtdSVoHP-pg@mail.gmail.com>

HI Mathieu,

On Thu, 13 Jan 2022 at 17:56, Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
>
> Good morning Mike,
>
> On Tue, Nov 30, 2021 at 10:00:58PM +0000, Mike Leach wrote:
> > Add an example file generator to test loading configurations via a
> > binary attribute in configfs.
> >
> > Provides a file buffer writer function that can be re-used in other
> > userspace programs.
> >
> > Buffer write format matches that expected by the corresponding reader
> > in the configfs driver code.
> >
>
> Despite trying quite hard I haven't found a single bug in this patchset, which
> is a feat for user space code.
>
> Please see comments below...
>
> > Signed-off-by: Mike Leach <mike.leach at linaro.org>
> > ---
> >  samples/coresight/Makefile                |   7 +
> >  samples/coresight/coresight-cfg-bufw.c    | 302 ++++++++++++++++++++++
> >  samples/coresight/coresight-cfg-bufw.h    |  24 ++
> >  samples/coresight/coresight-cfg-filegen.c |  89 +++++++
> >  4 files changed, 422 insertions(+)
> >  create mode 100644 samples/coresight/coresight-cfg-bufw.c
> >  create mode 100644 samples/coresight/coresight-cfg-bufw.h
> >  create mode 100644 samples/coresight/coresight-cfg-filegen.c
> >
> > diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile
> > index b3fce4af2347..07bfd99d7a68 100644
> > --- a/samples/coresight/Makefile
> > +++ b/samples/coresight/Makefile
> > @@ -1,4 +1,11 @@
> >  # SPDX-License-Identifier: GPL-2.0-only
> >
> > +# coresight config - loadable module configuration.
> >  obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o
> >  ccflags-y += -I$(srctree)/drivers/hwtracing/coresight
> > +
> > +# coresight config - configfs loadable binary config generator
> > +userprogs-always-y += coresight-cfg-filegen
> > +
> > +coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o
> > +userccflags += -I$(srctree)/drivers/hwtracing/coresight
> > diff --git a/samples/coresight/coresight-cfg-bufw.c b/samples/coresight/coresight-cfg-bufw.c
> > new file mode 100644
> > index 000000000000..8c32a8509eef
> > --- /dev/null
> > +++ b/samples/coresight/coresight-cfg-bufw.c
> > @@ -0,0 +1,302 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 Linaro Limited, All rights reserved.
>
> Are you sure you want to keep this to 2020?  Here and in all other files.
>

Given the lenght of legal copyright - not a major issue - but if
respinning will address.

> > + * Author: Mike Leach <mike.leach at linaro.org>
> > + */
> > +
> > +#include <string.h>
> > +
> > +#include "coresight-cfg-bufw.h"
> > +
> > +/*
> > + * Set of macros to make writing the buffer code easier.
> > + *.
>
> Extra '.'
>
> > + * Uses naming convention as 'buffer' for the buffer pointer and
> > + * 'used' as the current bytes used by the encosing function.
> > + */
> > +#define cscfg_write_u64(val64) {     \
> > +     *(u64 *)(buffer + used) = val64; \
> > +     used += sizeof(u64); \
> > +     }
> > +
> > +#define cscfg_write_u32(val32) { \
> > +     *(u32 *)(buffer + used) = val32;        \
> > +     used += sizeof(u32); \
> > +     }
> > +
> > +#define cscfg_write_u16(val16) { \
> > +     *(u16 *)(buffer + used) = val16;        \
> > +     used += sizeof(u16); \
> > +     }
> > +
> > +#define cscfg_write_u8(val8) { \
> > +     *(buffer + used) = val8;        \
> > +     used++; \
> > +     }
> > +
> > +#define CHECK_WRET(rval) { \
> > +     if (rval < 0) \
> > +             return rval;       \
> > +     used += rval;              \
> > +     }
> > +
> > +/* write the header at the start of the buffer */
> > +static int cscfg_file_write_fhdr(u8 *buffer, const int buflen,
> > +                              const struct cscfg_file_header *fhdr)
> > +{
> > +     int used = 0;
> > +
> > +     cscfg_write_u32(fhdr->magic_version);
> > +     cscfg_write_u16(fhdr->length);
> > +     cscfg_write_u16(fhdr->nr_features);
> > +     return used;
> > +}
> > +
> > +static int cscfg_file_write_string(u8 *buffer, const int buflen, const char *string)
> > +{
> > +     int len, used = 0;
> > +
> > +     len = strlen(string);
> > +     if (len > CSCFG_FILE_STR_MAXSIZE)
> > +             return -EINVAL;
> > +
> > +     if (buflen < (len + 1 + sizeof(u16)))
> > +             return -EINVAL;
> > +
> > +     cscfg_write_u16((u16)(len + 1));
> > +     strcpy((char *)(buffer + used), string);
> > +     used += (len + 1);
> > +
> > +     return used;
> > +}
> > +
> > +static int cscfg_file_write_elem_hdr(u8 *buffer, const int buflen,
> > +                                  struct cscfg_file_elem_header *ehdr)
> > +{
> > +     int used = 0;
> > +
> > +     if (buflen < (sizeof(u16) + sizeof(u8)))
> > +             return -EINVAL;
> > +
> > +     cscfg_write_u16(ehdr->elem_length);
> > +     cscfg_write_u8(ehdr->elem_type);
> > +
> > +     return used;
> > +}
> > +
> > +
>
> Extra newline
>
> > +static int cscfg_file_write_config(u8 *buffer, const int buflen,
> > +                                struct cscfg_config_desc *config_desc)
> > +{
> > +     int used = 0, bytes_w, space_req, preset_bytes, i;
> > +     struct cscfg_file_elem_header ehdr;
> > +
> > +     ehdr.elem_length = 0;
> > +     ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_CFG;
> > +
> > +     /* write element header at current buffer location */
> > +     bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /* write out the configuration name */
> > +     bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                       config_desc->name);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /* write out the description string */
> > +     bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                       config_desc->description);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /*
> > +      * calculate the space needed for variables + presets
> > +      * [u16 value - nr_presets]
> > +      * [u32 value - nr_total_params]
> > +      * [u16 value - nr_feat_refs]
> > +      * [u64 values] * (nr_presets * nr_total_params)
> > +      */
> > +     preset_bytes = sizeof(u64) * config_desc->nr_presets * config_desc->nr_total_params;
> > +     space_req = (sizeof(u16) * 2) + sizeof(u32) + preset_bytes;
> > +
> > +     if ((buflen - used) < space_req)
> > +             return -EINVAL;
> > +
> > +     cscfg_write_u16((u16)config_desc->nr_presets);
> > +     cscfg_write_u32((u32)config_desc->nr_total_params);
> > +     cscfg_write_u16((u16)config_desc->nr_feat_refs);
> > +     if (preset_bytes) {
> > +             memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes);
> > +             used += preset_bytes;
> > +     }
> > +
> > +     /* now write the feature ref names */
> > +     for (i = 0; i < config_desc->nr_feat_refs; i++) {
> > +             bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                               config_desc->feat_ref_names[i]);
> > +             CHECK_WRET(bytes_w);
> > +     }
> > +
> > +     /* rewrite the element header with the correct length */
> > +     ehdr.elem_length = used;
> > +     bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> > +     /* no CHECK_WRET as used must not be updated */
> > +     if (bytes_w < 0)
> > +             return bytes_w;
> > +
> > +     return used;
> > +}
> > +
> > +/*
> > + * write a parameter structure into the buffer in following format:
> > + * [cscfg_file_elem_str]    - parameter name.
> > + * [u64 value: param_value] - initial value.
> > + */
> > +static int cscfg_file_write_param(u8 *buffer, const int buflen,
> > +                               struct cscfg_parameter_desc *param_desc)
> > +{
> > +     int used = 0, bytes_w;
> > +
> > +     bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                       param_desc->name);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     if ((buflen - used) < sizeof(u64))
> > +             return -EINVAL;
> > +
> > +     cscfg_write_u64(param_desc->value);
> > +     return used;
> > +}
> > +/*
> > + * Write a feature element from cscfg_feature_desc in following format:
> > + *
> > + * [cscfg_file_elem_header] - header length is total bytes to end of param structures.
> > + * [cscfg_file_elem_str]    - feature name.
> > + * [cscfg_file_elem_str]    - feature description.
> > + * [u32 value: match_flags]
> > + * [u16 value: nr_regs]          - number of registers.
> > + * [u16 value: nr_params]   - number of parameters.
> > + * [cscfg_regval_desc struct] * nr_regs
> > + * [PARAM_ELEM] * nr_params
> > + *
> > + *
>
> Extra newlines
>

Will sort these.

> > + */
> > +static int cscfg_file_write_feat(u8 *buffer, const int buflen,
> > +                              struct cscfg_feature_desc *feat_desc)
> > +{
> > +     struct cscfg_file_elem_header ehdr;
> > +     struct cscfg_regval_desc *p_reg_desc;
> > +     int used = 0, bytes_w, i, space_req;
> > +     u32 val32;
> > +
> > +     ehdr.elem_length = 0;
> > +     ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_FEAT;
> > +
> > +     /* write element header at current buffer location */
> > +     bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /* write out the name string */
> > +     bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                       feat_desc->name);
> > +     CHECK_WRET(bytes_w)
> > +
> > +     /* write out the description string */
> > +     bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> > +                                       feat_desc->description);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /* check for space for variables and register structures */
> > +     space_req = (sizeof(u16) * 2) + sizeof(u32) +
> > +             (sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs);
> > +     if ((buflen - used) < space_req)
> > +             return -EINVAL;
> > +
> > +     /* write the variables */
> > +     cscfg_write_u32((u32)feat_desc->match_flags);
> > +     cscfg_write_u16((u16)feat_desc->nr_regs);
> > +     cscfg_write_u16((u16)feat_desc->nr_params);
> > +
> > +     /*write the registers */
> > +     for (i = 0; i < feat_desc->nr_regs; i++) {
> > +             p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
> > +             CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_reg_desc);
> > +             cscfg_write_u32(val32);
> > +             cscfg_write_u64(feat_desc->regs_desc[i].val64);
> > +     }
> > +
> > +     /* write any parameters */
> > +     for (i = 0; i < feat_desc->nr_params; i++) {
> > +             bytes_w = cscfg_file_write_param(buffer + used, buflen - used,
> > +                                              &feat_desc->params_desc[i]);
> > +             CHECK_WRET(bytes_w);
> > +     }
> > +
> > +     /*
> > +      * rewrite the element header at the start of the buffer block
> > +      * with the correct length
> > +      */
> > +     ehdr.elem_length = used;
> > +     bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> > +     /* no CHECK_WRET as used must not be updated */
> > +     if (bytes_w < 0)
> > +             return bytes_w;
> > +
> > +     return used;
> > +}
> > +
> > +/*
> > + * write a buffer from the configuration and feature
> > + * descriptors to write into a file for configfs.
> > + *
> > + * Will only write one config, and/or a number of features,
> > + * per the file standard.
> > + */
> > +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> > +                         struct cscfg_config_desc *config_desc,
> > +                         struct cscfg_feature_desc **feat_descs)
> > +{
> > +     struct cscfg_file_header fhdr;
> > +     int used = 0,  bytes_w, i;
> > +
> > +     /* init the file header */
> > +     fhdr.magic_version = CSCFG_FILE_MAGIC_VERSION;
> > +     fhdr.length = 0;
> > +     fhdr.nr_features = 0;
> > +
> > +     /* count the features */
> > +     if (feat_descs) {
> > +             while (feat_descs[fhdr.nr_features])
> > +                     fhdr.nr_features++;
> > +     }
> > +
> > +     /* need a buffer and at least one config or feature */
> > +     if ((!config_desc && !fhdr.nr_features) ||
> > +         !buffer || (buflen > CSCFG_FILE_MAXSIZE))
> > +             return -EINVAL;
> > +
> > +     /* write a header at the start to get the length of the header */
> > +     bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> > +     CHECK_WRET(bytes_w);
> > +
> > +     /* write a single config */
> > +     if (config_desc) {
> > +             bytes_w = cscfg_file_write_config(buffer + used, buflen - used,
> > +                                               config_desc);
> > +             CHECK_WRET(bytes_w);
> > +     }
> > +
> > +     /* write any features */
> > +     for (i = 0; i < fhdr.nr_features; i++) {
> > +             bytes_w = cscfg_file_write_feat(buffer + used, buflen - used,
> > +                                             feat_descs[i]);
> > +             CHECK_WRET(bytes_w);
> > +     }
> > +
> > +     /* finally re-write the header at the buffer start with the correct length */
> > +     fhdr.length = (u16)used;
> > +     bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> > +     /* no CHECK_WRET as used must not be updated */
> > +     if (bytes_w < 0)
> > +             return bytes_w;
> > +     return used;
> > +}
> > diff --git a/samples/coresight/coresight-cfg-bufw.h b/samples/coresight/coresight-cfg-bufw.h
> > new file mode 100644
> > index 000000000000..00b16c583cad
> > --- /dev/null
> > +++ b/samples/coresight/coresight-cfg-bufw.h
> > @@ -0,0 +1,24 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> > + * Author: Mike Leach <mike.leach at linaro.org>
> > + */
> > +
> > +#ifndef _CORESIGHT_CFG_BUFW_H
> > +#define _CORESIGHT_CFG_BUFW_H
> > +
> > +#include "coresight-config-file.h"
> > +
> > +/*
> > + * Function to take coresight configurations and features and
> > + * write them into a supplied memory buffer for serialisation
> > + * into a file.
> > + *
> > + * Resulting file can then be loaded into the coresight
> > + * infrastructure via configfs.
> > + */
> > +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> > +                         struct cscfg_config_desc *config_desc,
> > +                         struct cscfg_feature_desc **feat_descs);
> > +
> > +#endif /* _CORESIGHT_CFG_BUFW_H */
> > diff --git a/samples/coresight/coresight-cfg-filegen.c b/samples/coresight/coresight-cfg-filegen.c
> > new file mode 100644
> > index 000000000000..c8be18ee97b6
> > --- /dev/null
> > +++ b/samples/coresight/coresight-cfg-filegen.c
> > @@ -0,0 +1,89 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> > + * Author: Mike Leach <mike.leach at linaro.org>
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <linux/unistd.h>
> > +#include <stdio.h>
> > +#include <unistd.h>
> > +
> > +#include "coresight-cfg-bufw.h"
> > +
> > +/*
> > + * generate example binary coresight configuration files for loading
> > + * into the coresight subsystem via configfs
> > + */
> > +
> > +/* create a similar configuration example as the coresight-cfg-sample.c file. */
> > +
> > +/* we will provide 4 sets of preset parameter values */
> > +#define AFDO2_NR_PRESETS     4
> > +/* the total number of parameters in used features - strobing has 2 */
> > +#define AFDO2_NR_PARAM_SUM   2
> > +
> > +static const char *afdo2_ref_names[] = {
> > +     "strobing",
> > +};
> > +
> > +/*
> > + * set of presets leaves strobing window constant while varying period to allow
> > + * experimentation with mark / space ratios for various workloads
> > + */
> > +static u64 afdo2_presets[AFDO2_NR_PRESETS][AFDO2_NR_PARAM_SUM] = {
> > +     { 2000, 100 },
> > +     { 2000, 1000 },
> > +     { 2000, 5000 },
> > +     { 2000, 10000 },
> > +};
> > +
> > +struct cscfg_config_desc afdo3 = {
> > +     .name = "autofdo3",
> > +     .description = "Setup ETMs with strobing for autofdo\n"
> > +     "Supplied presets allow experimentation with mark-space ratio for various loads\n",
> > +     .nr_feat_refs = ARRAY_SIZE(afdo2_ref_names),
> > +     .feat_ref_names = afdo2_ref_names,
> > +     .nr_presets = AFDO2_NR_PRESETS,
> > +     .nr_total_params = AFDO2_NR_PARAM_SUM,
> > +     .presets = &afdo2_presets[0][0],
> > +};
> > +
> > +static struct cscfg_feature_desc *sample_feats[] = {
> > +     NULL
> > +};
>
> For completeness there would be value in providing an example that requires
> features.
>

Agreed but given this patchset has been split into multiple ones this
has dropped som eof the context between patches.
The next set - which adds ETMv4 resource management also contains
multiple additional examples showing features.
These cannot appear here as they use the new resource IDs introduced
in the next set.

> > +
> > +static struct cscfg_config_desc *sample_cfgs[] = {
> > +     &afdo3,
> > +     NULL
> > +};
>
> Any reason to declare sample_cfgs[] when there can only be one configuration?
>

The API defined requires a NULL terminated list.

> Lastly I get the following [1] when compiling this set - I have not investigated
> further.
>

Looks like there is a failure to copy the coresight_config_file.c
source from the kernel into the sample working directory.
This is compiled into the user space reader tool. Not sure why it
would be copying in my environment and not yours.

It seems like we have been here before in a previous patchset that
contained the samples - I think then it was something to do with
directtory definitions - but I never really understood why the fix we
found worked.

The sampel can be compiled natively (x86). In the samples directory run:-
make -f Makefile.host
This will do the same copy and build, but create x86 versions of the
tools. Perhaps this will highlight the differences.

As an aside, the output files from coresight-cfg-filegen can be
subsequently transferred across to the ARM base target and used.

Thanks

Mike

> Thanks,
> Mathieu
>
> [1]. https://pastebin.com/Nw2DTqTC
>
> > +
> > +
> > +#define CSCFG_BIN_FILENAME "example1.cscfg"
> > +
> > +int main(int argc, char **argv)
> > +{
> > +     u8 buffer[CSCFG_FILE_MAXSIZE];
> > +     int used;
> > +     FILE *fp;
> > +
> > +     printf("Coresight Configuration file Generator\n\n");
> > +
> > +     used = cscfg_file_write_buffer(buffer, CSCFG_FILE_MAXSIZE,
> > +                                    sample_cfgs[0], sample_feats);
> > +
> > +     if (used < 0) {
> > +             printf("Error %d writing configuration %s into buffer\n",
> > +                    used, sample_cfgs[0]->name);
> > +             return used;
> > +     }
> > +
> > +     fp = fopen(CSCFG_BIN_FILENAME, "wb");
> > +     if (fp == NULL) {
> > +             printf("Error opening file %s\n", CSCFG_BIN_FILENAME);
> > +             return -1;
> > +     }
> > +     fwrite(buffer, used, sizeof(u8), fp);
> > +     fclose(fp);
> > +     return 0;
> > +}
> > --
> > 2.17.1
> >



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Tue Jan 18 08:41:15 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Tue, 18 Jan 2022 16:41:15 +0000
Subject: [PATCH v2 6/6] Documentation: coresight: docs for config load via
 configfs
In-Reply-To: <20220113181557.GB967130@p14s>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-7-mike.leach@linaro.org>
 <20220113181557.GB967130@p14s>
Message-ID: <CAJ9a7VhP9jfmH8FTxDizo5g=xBs02coLgTRd7XX2buHgrJoVOQ@mail.gmail.com>

Hi Mathieu,

On Thu, 13 Jan 2022 at 18:16, Mathieu Poirier
<mathieu.poirier at linaro.org> wrote:
>
> More comments...
>
> On Tue, Nov 30, 2021 at 10:01:00PM +0000, Mike Leach wrote:
> > Add documentation covering the configfs updates that allow
> > binary configuration files to be loaded and unloaded via configfs,
> > along with the demonstration programs in samples.
> >
> > Signed-off-by: Mike Leach <mike.leach at linaro.org>
> > ---
> >  .../trace/coresight/coresight-config.rst      | 151 +++++++++++++++++-
> >  1 file changed, 145 insertions(+), 6 deletions(-)
> >
> > diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst
> > index 6d5ffa6f7347..f11def230fab 100644
> > --- a/Documentation/trace/coresight/coresight-config.rst
> > +++ b/Documentation/trace/coresight/coresight-config.rst
> > @@ -152,7 +152,7 @@ follows::
> >
> >      $ cd configurations/
> >      $ ls
> > -    autofdo
> > +    autofdo last_load_status  load  unload
> >      $ cd autofdo/
> >      $ ls
> >      description  feature_refs  preset1  preset3  preset5  preset7  preset9
> > @@ -278,9 +278,19 @@ Creating and Loading Custom Configurations
> >  ==========================================
> >
> >  Custom configurations and / or features can be dynamically loaded into the
> > -system by using a loadable module.
> > +system by using a loadable module, or by loading a binary configuration
> > +file in configfs.
> > +
> > +Loaded configurations can use previously loaded features. The system will
> > +ensure that it is not possible to unload a feature that is currently in
> > +use, by enforcing the unload order as the strict reverse of the load order.
> > +
> > +An example of a custom configuration module, and generators for binary
> > +configuration files are found in './samples/coresight'.
> >
> > -An example of a custom configuration is found in ./samples/coresight.
> > +
> > +Using a Loadable Module
> > +-----------------------
> >
> >  This creates a new configuration that uses the existing built in
> >  strobing feature, but provides a different set of presets.
> > @@ -289,6 +299,135 @@ When the module is loaded, then the configuration appears in the configfs
> >  file system and is selectable in the same way as the built in configuration
> >  described above.
> >
> > -Configurations can use previously loaded features. The system will ensure
> > -that it is not possible to unload a feature that is currently in use, by
> > -enforcing the unload order as the strict reverse of the load order.
> > +The file 'coresight-cfg-sample.c' contains the configuration and module
> > +initialisation code needed to create the loadable module.
> > +
> > +This will be built alongside the kernel modules if select in KConfig.
> > +
> > +
> > +Using a Binary Configuration File
> > +---------------------------------
> > +
> > +Building the samples creates the 'coresight-cfg-filegen' program that will
> > +generate a configuration binary 'example1.cscfg' that can be loaded into the
> > +system using configfs. The configuration declared in the source file
> > +'coresight-cfg-filegen.c' is named 'autofdo3' - the name that will be used
> > +once loaded.
> > +
> > +The source files 'coresight-cfg-bufw.h' and 'coresight-cfg-bufw.c' provide a
> > +standard function to convert a configuration declared in 'C' into the correct
> > +binary buffer format. These files can be re-used to create new custom
> > +configurations.
> > +
> > +The program  'coresight-cfg-file-read' can read back and print a configuration
> > +binary. This is built using the reader from the driver code.
> > +
> > +There are additional attributes in the configurations directory - load, unload
> > +and last_load_status that can be used to load and unload configuration
> > +binary files. To load, 'cat' the binary config into the load attribute::
> > +
> > +    $ ls /config/cs-syscfg/configurations/
> > +    autofdo last_load_status  load  unload
> > +    $ cat example1.cscfg > /config/cs-syscfg/configurations/load
> > +    $ ls /config/cs-syscfg/configurations/
> > +    autofdo  autofdo3  last_load_status  load  unload
> > +    $ cat /config/cs-syscfg/configurations/last_load_status
> > +    OK: configuration file loaded (autofdo3).
> > +
> > +To unload, use the same file in the unload attribute::
> > +
> > +    $ cat example1.cscfg > /config/cs-syscfg/configurations/unload
> > +    $ cat /config/cs-syscfg/configurations/last_load_status
> > +    OK: configuration file unloaded (autofdo3).
> > +    ls /config/cs-syscfg/configurations/
> > +    autofdo  last_load_status  load  unload
>
> I'm not certain that "last_load_status" is needed.  To me seeing the name of a
> newly added configuration should be enough to confirm a successful status.  The
> same applies to unload.
>

Again - this makes more sense after the next ETM patchset that uses
resource management - this status is more useful when features or
configurations fail to load - as this can be due to insufficient
resources on the system.
When we have portable binary configuration files, loading via
configfs, then this information is important to users.

Thanks

Mike


> Thanks,
> Mathieu
>
> > +
> > +The generator and reader programs can also be built directly, separately from
> > +the kernel build by using the 'Makefile.host' file. This allows native binaries
> > +to be created on the host machine rather than cross compiled version for the
> > +target.
> > +
> > +
> > +Binary Configuration File Format
> > +--------------------------------
> > +
> > +The file format is defined in the source file **coresight-config-file.h**
> > +
> > +The source reader and generator examples produce a binary of this format.
> > +
> > +This arrangement is reproduced below:-
> > +
> > +Overall File structure
> > +~~~~~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_header]   // Mandatory
> > +   [CONFIG_ELEM]         // Optional - one per file, if present, first element in file.
> > +   [FEATURE_ELEM]*       // Optional - multiple, defined by cscfg_file_header.nr_features
> > +
> > +File is invalid if both [CONFIG_ELEM] and [FEATURE_ELEM] are omitted.
> > +
> > +A file that contains only [FEATURE_ELEM] may be loaded, and the features used
> > +by subsequently loaded files with [CONFIG_ELEM] elements.
> > +
> > +Where [CONFIG_ELEM] is present, then **cscfg_file_header.nr_features** and
> > +**CONFIG_ELEM.nr_feat_refs** must have the same value.
> > +
> > +CONFIG_ELEM element
> > +~~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_header]                // header length value to end of feature strings.
> > +   [cscfg_file_elem_str]                   // name of the configuration.
> > +   [cscfg_file_elem_str]                   // description of configuration.
> > +   [u16 value](nr_presets)                 // number of defined presets.
> > +   [u32 value](nr_total_params)            // total parameters defined by all used features.
> > +   [u16 value](nr_feat_refs)               // number of features referenced by the configuration
> > +   [u64 values] * (nr_presets * nr_total_params)     // the preset values.
> > +   [cscfg_file_elem_str] * (nr_feat_refs)  // the features used in the configurations.
> > +
> > +FEATURE_ELEM element
> > +~~~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_header]                // header length is total bytes to end of param structures.
> > +   [cscfg_file_elem_str]                   // feature name.
> > +   [cscfg_file_elem_str]                   // feature description.
> > +   [u32 value](match_flags)                // flags to associate the feature with a device.
> > +   [u16 value](nr_regs)                    // number of registers.
> > +   [u16 value](nr_params)                  // number of parameters.
> > +   [cscfg_regval_desc struct] * (nr_regs)  // register definitions
> > +   [PARAM_ELEM] * (nr_params)              // parameters definitions
> > +
> > +PARAM_ELEM element
> > +~~~~~~~~~~~~~~~~~~
> > +
> > +::
> > +
> > +   [cscfg_file_elem_str]         // parameter name.
> > +   [u64 value](param_value]      // initial value.
> > +
> > +Additional definitions.
> > +~~~~~~~~~~~~~~~~~~~~~~~
> > +
> > +The following structures are defined in **coresight-config-file.h**
> > +
> > + * **struct cscfg_file_header** : This structure contains an initial magic number, the total
> > +   length of the file, and the number of features in the file.
> > + * **struct cscfg_file_elem_header**: This defines the total length and type of a CONFIG_ELEM
> > +   or a FEATURE_ELEM.
> > + * **struct cscfg_file_elem_str**: This defines a string and its length.
> > +
> > +The magic number in cscfg_file_header is defined as two bitfields::
> > +
> > +   [31:8] Fixed magic number to identify file type.
> > +   [7:0]  Current file format version.
> > +
> > +The following defines determine the maximum overall file size and maximum individual
> > +string size::
> > +
> > +   CSCFG_FILE_MAXSIZE       // maximum overall file size.
> > +   CSCFG_FILE_STR_MAXSIZE   // maximum individual string size.
> > --
> > 2.17.1
> >



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From geert+renesas at glider.be  Tue Jan 18 08:48:31 2022
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Tue, 18 Jan 2022 17:48:31 +0100
Subject: [PATCH] arm64: dts: renesas: Miscellaneous whitespace fixes
Message-ID: <3f2bcae1253c7a31d3eb6755185092a1f2b99b09.1642524439.git.geert+renesas@glider.be>

Make whitespace and indentation more consistent.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v5.18.

 .../dts/renesas/beacon-renesom-baseboard.dtsi |  9 ++++-----
 arch/arm64/boot/dts/renesas/r8a774a1.dtsi     | 14 ++++++-------
 .../dts/renesas/r8a774b1-beacon-rzg2n-kit.dts |  2 +-
 arch/arm64/boot/dts/renesas/r8a774b1.dtsi     |  4 ++--
 arch/arm64/boot/dts/renesas/r8a774c0.dtsi     | 10 +++++-----
 .../dts/renesas/r8a774e1-beacon-rzg2h-kit.dts |  2 +-
 arch/arm64/boot/dts/renesas/r8a774e1.dtsi     |  4 ++--
 arch/arm64/boot/dts/renesas/r8a77951.dtsi     | 14 ++++++-------
 arch/arm64/boot/dts/renesas/r8a77960.dtsi     | 14 ++++++-------
 arch/arm64/boot/dts/renesas/r8a77961.dtsi     |  4 ++--
 arch/arm64/boot/dts/renesas/r8a77965.dtsi     | 14 ++++++-------
 arch/arm64/boot/dts/renesas/r8a77990.dtsi     | 12 +++++------
 arch/arm64/boot/dts/renesas/r8a77995.dtsi     | 12 +++++------
 arch/arm64/boot/dts/renesas/r8a779a0.dtsi     | 20 +++++++++----------
 14 files changed, 67 insertions(+), 68 deletions(-)

diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
index 2692cc64bff61e61..5ad6cd1864c10442 100644
--- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
+++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
@@ -359,11 +359,10 @@ versaclock6_bb: clock-controller at 6a {
 		clocks = <&x304_clk>;
 		clock-names = "xin";
 
-		assigned-clocks = <&versaclock6_bb 1>,
-				   <&versaclock6_bb 2>,
-				   <&versaclock6_bb 3>,
-				   <&versaclock6_bb 4>;
-		assigned-clock-rates =	<24000000>, <24000000>, <24000000>, <24576000>;
+		assigned-clocks = <&versaclock6_bb 1>, <&versaclock6_bb 2>,
+				  <&versaclock6_bb 3>, <&versaclock6_bb 4>;
+		assigned-clock-rates = <24000000>, <24000000>, <24000000>,
+				       <24576000>;
 
 		OUT1 {
 			idt,mode = <VC5_CMOS>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
index eda6a840371a8c15..12846125a4c983df 100644
--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -1698,12 +1698,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a774a1", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a774a1", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
@@ -2010,7 +2010,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts b/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
index 3c0d59def8ee5342..89d708346ba8176d 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774b1-beacon-rzg2n-kit.dts
@@ -11,7 +11,7 @@
 
 / {
 	model = "Beacon Embedded Works RZ/G2N Development Kit";
-	compatible =	"beacon,beacon-rzg2n", "renesas,r8a774b1";
+	compatible = "beacon,beacon-rzg2n", "renesas,r8a774b1";
 
 	aliases {
 		serial0 = &scif2;
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
index 44f79fbd75dc9e48..a4b406a346f9c380 100644
--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -1571,7 +1571,7 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a774b1", "renesas,rcar_sound-gen3";
+			compatible = "renesas,rcar_sound-r8a774b1", "renesas,rcar_sound-gen3";
 			reg = <0 0xec500000 0 0x1000>, /* SCU */
 			      <0 0xec5a0000 0 0x100>,  /* ADG */
 			      <0 0xec540000 0 0x1000>, /* SSIU */
@@ -1883,7 +1883,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
index b8dcbbbf3db5397f..e123c8d1bab93752 100644
--- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -1328,11 +1328,11 @@ rcar_sound: sound at ec500000 {
 			 */
 			compatible = "renesas,rcar_sound-r8a774c0",
 				     "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts b/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
index 7b6649a3ded0299e..3e9ced3b2d334999 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
+++ b/arch/arm64/boot/dts/renesas/r8a774e1-beacon-rzg2h-kit.dts
@@ -11,7 +11,7 @@
 
 / {
 	model = "Beacon Embedded Works RZ/G2H Development Kit";
-	compatible =	"beacon,beacon-rzg2h", "renesas,r8a774e1";
+	compatible = "beacon,beacon-rzg2h", "renesas,r8a774e1";
 
 	aliases {
 		serial0 = &scif2;
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
index e6d8610730a84ab8..989c1c00dcdcb393 100644
--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -1784,7 +1784,7 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a774e1", "renesas,rcar_sound-gen3";
+			compatible = "renesas,rcar_sound-r8a774e1", "renesas,rcar_sound-gen3";
 			reg = <0 0xec500000 0 0x1000>, /* SCU */
 			      <0 0xec5a0000 0 0x100>,  /* ADG */
 			      <0 0xec540000 0 0x1000>, /* SSIU */
@@ -2043,7 +2043,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
index f1b1aa7e2adbe578..d792bf14d18dd418 100644
--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -2018,12 +2018,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a7795", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
@@ -2277,7 +2277,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
index e9e18873b05ca2f6..56b91411a16b4604 100644
--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -1890,12 +1890,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a7796", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a7796", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
@@ -2202,7 +2202,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
index 4252cbcf34fb490a..6eac95b986e6737a 100644
--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -1734,7 +1734,7 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a77961", "renesas,rcar_sound-gen3";
+			compatible = "renesas,rcar_sound-r8a77961", "renesas,rcar_sound-gen3";
 			reg = <0 0xec500000 0 0x1000>, /* SCU */
 			      <0 0xec5a0000 0 0x100>,  /* ADG */
 			      <0 0xec540000 0 0x1000>, /* SSIU */
@@ -2046,7 +2046,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
index 363f7f513f5a1c43..8429133650655146 100644
--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -1753,12 +1753,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a77965", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a77965", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
@@ -2012,7 +2012,7 @@ ssiu37: ssiu-31 {
 					dma-names = "rx", "tx";
 				};
 				ssiu40: ssiu-32 {
-					dmas =	<&audma0 0x71>, <&audma1 0x72>;
+					dmas = <&audma0 0x71>, <&audma1 0x72>;
 					dma-names = "rx", "tx";
 				};
 				ssiu41: ssiu-33 {
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
index 1a497a7ba09168dd..f2bb829e8d0aa7f0 100644
--- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -1489,12 +1489,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a77990", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a77990", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
index ea03a6f9a8abc84d..9326344db8eec147 100644
--- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -1046,12 +1046,12 @@ rcar_sound: sound at ec500000 {
 			 * clkout	: #clock-cells = <0>;	<&rcar_sound>;
 			 * clkout0/1/2/3: #clock-cells = <1>;	<&rcar_sound N>;
 			 */
-			compatible =  "renesas,rcar_sound-r8a77995", "renesas,rcar_sound-gen3";
-			reg =	<0 0xec500000 0 0x1000>, /* SCU */
-				<0 0xec5a0000 0 0x100>,  /* ADG */
-				<0 0xec540000 0 0x1000>, /* SSIU */
-				<0 0xec541000 0 0x280>,  /* SSI */
-				<0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+			compatible = "renesas,rcar_sound-r8a77995", "renesas,rcar_sound-gen3";
+			reg = <0 0xec500000 0 0x1000>, /* SCU */
+			      <0 0xec5a0000 0 0x100>,  /* ADG */
+			      <0 0xec540000 0 0x1000>, /* SSIU */
+			      <0 0xec541000 0 0x280>,  /* SSI */
+			      <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
 			reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
 			clocks = <&cpg CPG_MOD 1005>,
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
index 65d0ddb42f611213..c80f4584035e79e1 100644
--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -109,7 +109,7 @@ gpio0: gpio at e6058180 {
 			interrupts = <GIC_SPI 832 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 916>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 916>;
+			resets = <&cpg 916>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 0 28>;
@@ -123,7 +123,7 @@ gpio1: gpio at e6050180 {
 			interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 915>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 915>;
+			resets = <&cpg 915>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 32 31>;
@@ -137,7 +137,7 @@ gpio2: gpio at e6050980 {
 			interrupts = <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 915>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 915>;
+			resets = <&cpg 915>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 64 25>;
@@ -151,7 +151,7 @@ gpio3: gpio at e6058980 {
 			interrupts = <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 916>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 916>;
+			resets = <&cpg 916>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 96 17>;
@@ -165,7 +165,7 @@ gpio4: gpio at e6060180 {
 			interrupts = <GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 917>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 917>;
+			resets = <&cpg 917>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 128 27>;
@@ -179,7 +179,7 @@ gpio5: gpio at e6060980 {
 			interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 917>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 917>;
+			resets = <&cpg 917>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 160 21>;
@@ -193,7 +193,7 @@ gpio6: gpio at e6068180 {
 			interrupts = <GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 918>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 918>;
+			resets = <&cpg 918>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 192 21>;
@@ -207,7 +207,7 @@ gpio7: gpio at e6068980 {
 			interrupts = <GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 918>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 918>;
+			resets = <&cpg 918>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 224 21>;
@@ -221,7 +221,7 @@ gpio8: gpio at e6069180 {
 			interrupts = <GIC_SPI 864 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 918>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 918>;
+			resets = <&cpg 918>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 256 21>;
@@ -235,7 +235,7 @@ gpio9: gpio at e6069980 {
 			interrupts = <GIC_SPI 868 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 918>;
 			power-domains = <&sysc R8A779A0_PD_ALWAYS_ON>;
-			resets =  <&cpg 918>;
+			resets = <&cpg 918>;
 			gpio-controller;
 			#gpio-cells = <2>;
 			gpio-ranges = <&pfc 0 288 21>;
-- 
2.25.1



From broonie at kernel.org  Tue Jan 18 08:50:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 18 Jan 2022 16:50:12 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220117183117.7f29dc66@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-10-mark.rutland@arm.com>
 <20220117143104.28db5001@donnerap.cambridge.arm.com>
 <20220117180813.GD94025@C02TD0UTHF1T.local>
 <20220117183117.7f29dc66@donnerap.cambridge.arm.com>
Message-ID: <YebvxEI+cnYMDu1j@sirena.org.uk>

On Mon, Jan 17, 2022 at 06:31:17PM +0000, Andre Przywara wrote:
> Mark Rutland <mark.rutland at arm.com> wrote:
> > On Mon, Jan 17, 2022 at 02:31:04PM +0000, Andre Przywara wrote:
> > > On Fri, 14 Jan 2022 10:56:49 +0000
> > > Mark Rutland <mark.rutland at arm.com> wrote:

[Out of office this week so replies might be intermittent]

> > > And apart from bit 0 missing from it (as noted above), the existing
> > > code writes 0x1ff into that register, presumable to cover future
> > > vector length extensions beyond 2048 bits (which those RAZ/WI fields
> > > in bits[8:4] seem to suggest).  

> > Hmm... I went and found the SVE supplement and I can't see any rationale
> > for what SW *should* do, nor can I find a description of the register
> > (that seems to have been factored into some XML files I can't convince
> > anything to load on my machine).

...

> > TBH, I'm not sure. In the absence of some documented guidance I'd prefer
> > to go with 0xf, but given we already use 0x1ff, I want to dig into this
> > a bit more.

I'm fairly sure I've seen some explicit discussion of this lurking
somewhere, though I couldn't tell you where - DDI0584 A.i doesn't spell
out the enumeration algorithm unfortunately AFAICT.  The theory is that
the extra bits are reserved for any future extension of the vector
length if needed since it'd be inconvenient to have to split the vector
length field up.

> My impression was that this "[8:4] = RAZ/WI" compared to the "[63:9] =
> RES0" fields suggests this is for a potential extension, but I guess there
> would be more changes needed if SVE ever goes beyond 2048. So chances are
> high we need to adopt the code then anyway, and fixing the number then is
> the least of our problems.

> So I feel we should stick to what's explicitly documented, and put 0xf in
> there.

We shouldn't need particularly many changes if the size of the field
ever gets raised, with everything being dynamically sized already and
the existing code starting off setting the WI bits to 1 the updates that
are needed should just be on input validation.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220118/e7004054/attachment.sig>

From john.garry at huawei.com  Tue Jan 18 09:14:07 2022
From: john.garry at huawei.com (John Garry)
Date: Tue, 18 Jan 2022 17:14:07 +0000
Subject: [RESEND PATCH 2/2] drivers/perf: hisi: add driver for HNS3 PMU
In-Reply-To: <20220117015222.9617-3-huangguangbin2@huawei.com>
References: <20220117015222.9617-1-huangguangbin2@huawei.com>
 <20220117015222.9617-3-huangguangbin2@huawei.com>
Message-ID: <271e4b5c-7dc4-058f-9299-d940a0fb79e0@huawei.com>

On 17/01/2022 01:52, Guangbin Huang wrote:

+linuxarm

> HNS3 PMU End Point device supports to collect performance statistics
> of bandwidth, latency, packet rate, interrupt rate in HiSilicon SoC
> NIC.
> 
> NIC of each IO DIE has one PMU device for it. Driver registers each
> PMU device to perf, and exports information of supported events,
> filter mode of each event, identifier and so on via sysfs.
> 
> Each PMU device has its own control, counter and interrupt registers,
> and supports up to 8 events by hardware.
> 
> Filter options contains:
> event        - select event
> subevent     - select subevent
> port         - select physical port of nic
> tc           - select tc(must be used with port)
> func         - select PF/VF
> queue        - select queue of PF/VF(must be used with func)
> intr         - select interrupt number(must be used with func)
> global       - select all functions of IO DIE
> 
> Signed-off-by: Guangbin Huang <huangguangbin2 at huawei.com>
> ---
>   MAINTAINERS                       |    6 +
>   drivers/perf/hisilicon/Kconfig    |    9 +
>   drivers/perf/hisilicon/Makefile   |    1 +
>   drivers/perf/hisilicon/hns3_pmu.c | 1631 +++++++++++++++++++++++++++++
>   include/linux/cpuhotplug.h        |    1 +
>   5 files changed, 1648 insertions(+)
>   create mode 100644 drivers/perf/hisilicon/hns3_pmu.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 90a7d7b21982..e8e258bb8f8d 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8614,6 +8614,12 @@ F:	Documentation/admin-guide/perf/hisi-pcie-pmu.rst
>   F:	Documentation/admin-guide/perf/hisi-pmu.rst
>   F:	drivers/perf/hisilicon
>   
> +HISILICON HNS3 PMU DRIVER
> +M:	Guangbin Huang <huangguangbin2 at huawei.com>
> +S:	Supported
> +F:	Documentation/admin-guide/perf/hns3-pmu.rst
> +F:	drivers/perf/hisilicon/hns3_pmu.c
> +
>   HISILICON QM AND ZIP Controller DRIVER
>   M:	Zhou Wang <wangzhou1 at hisilicon.com>
>   L:	linux-crypto at vger.kernel.org
> diff --git a/drivers/perf/hisilicon/Kconfig b/drivers/perf/hisilicon/Kconfig
> index 5546218b5598..8a9661c97ec8 100644
> --- a/drivers/perf/hisilicon/Kconfig
> +++ b/drivers/perf/hisilicon/Kconfig
> @@ -14,3 +14,12 @@ config HISI_PCIE_PMU
>   	  RCiEP devices.
>   	  Adds the PCIe PMU into perf events system for monitoring latency,
>   	  bandwidth etc.
> +
> +config HNS3_PMU
> +	tristate "HNS3 PERF PMU"
> +	depends on ARM64 && PCI

Any reason not to add COMPILE_TEST, like:
	depends on ARM64 || COMPILE_TEST
	depends on PCI


> +	help
> +	  Provide support for HNS3 performance monitoring unit (PMU) IEP
> +	  devices.
> +	  Adds the HNS3 PMU into perf events system for monitoring latency,
> +	  bandwidth etc.
> diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
> index 506ed39e3266..13297ec2798f 100644
> --- a/drivers/perf/hisilicon/Makefile
> +++ b/drivers/perf/hisilicon/Makefile
> @@ -4,3 +4,4 @@ obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
>   			  hisi_uncore_pa_pmu.o
>   
>   obj-$(CONFIG_HISI_PCIE_PMU) += hisi_pcie_pmu.o
> +obj-$(CONFIG_HNS3_PMU) += hns3_pmu.o
> diff --git a/drivers/perf/hisilicon/hns3_pmu.c b/drivers/perf/hisilicon/hns3_pmu.c
> new file mode 100644
> index 000000000000..075b7eefe8d6
> --- /dev/null
> +++ b/drivers/perf/hisilicon/hns3_pmu.c
> @@ -0,0 +1,1631 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * This driver adds support for HNS3 PMU iEP device.


> Related perf events are
> + * bandwidth, latency, packet rate, interrupt rate etc.

I don't think that this is relevant here

> + *
> + * Copyright (C) 2021 HiSilicon Limited
> + */

2022, I suppose now...

> +};
> +
> +#define HNS3_PMU_SET_HW_FILTER(_hwc, _mode) \
> +	((_hwc)->addr_filters = (void *)&hns3_pmu_hw_filter_modes[(_mode)])
> +
> +static ssize_t identifier_show(struct device *dev,
> +			       struct device_attribute *attr, char *buf)
> +{
> +	struct hns3_pmu *hns3_pmu;
> +
> +	hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));

Can the declaration and assignment be on the same line?

> +
> +	return sysfs_emit(buf, "0x%x\n", hns3_pmu->identifier);
> +}
> +static DEVICE_ATTR_RO(identifier);
> +
> +static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
> +
> +	return sysfs_emit(buf, "%d\n", hns3_pmu->on_cpu);
> +}
> +static DEVICE_ATTR_RO(cpumask);
> +
> +static ssize_t bdf_min_show(struct device *dev, struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
> +
> +	return sysfs_emit(buf, "0x%4x\n", hns3_pmu->bdf_min);
> +}
> +static DEVICE_ATTR_RO(bdf_min);
> +
> +static ssize_t bdf_max_show(struct device *dev, struct device_attribute *attr,
> +			    char *buf)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(dev_get_drvdata(dev));
> +
> +	return sysfs_emit(buf, "0x%4x\n", hns3_pmu->bdf_max);

are these same files as in HISI PCI PMU driver?

> +}
> +static DEVICE_ATTR_RO(bdf_max);
> +
> +static struct attribute *hns3_pmu_events_attr[] = {
> +	/* bandwidth events */


> +
> +static struct attribute_group hns3_pmu_events_group = {
> +	.name = "events",
> +	.attrs = hns3_pmu_events_attr,
> +};
> +
> +static struct attribute_group hns3_pmu_filter_mode_group = {
> +	.name = "filtermode",
> +};
> +

> +}
> +
> +static bool hns3_pmu_valid_bdf(struct hns3_pmu *hns3_pmu, u16 bdf)
> +{
> +	struct pci_dev *pdev;
> +
> +	if (bdf < hns3_pmu->bdf_min || bdf > hns3_pmu->bdf_max) {
> +		pci_err(hns3_pmu->pdev, "Invalid EP device: %#x!\n", bdf);
> +		return false;
> +	}
> +
> +	pdev = pci_get_domain_bus_and_slot(pci_domain_nr(hns3_pmu->pdev->bus),
> +					   PCI_BUS_NUM(bdf),
> +					   GET_PCI_DEVFN(bdf));
> +	if (!pdev) {
> +		pci_err(hns3_pmu->pdev, "Nonexistent EP device: %#x!\n", bdf);
> +		return false;
> +	}
> +
> +	pci_dev_put(pdev);
> +	return true;
> +}

if any of this code is same as hisi pci pmu driver then please put in a 
common lib

> +
> +static void hns3_pmu_set_qid_para(struct hns3_pmu *hns3_pmu, u32 idx, u16 bdf,
> +				  u16 queue)
> +{
> +	u32 val;
> +
> +	val = GET_PCI_DEVFN(bdf);
> +	val |= (u32)queue << HNS3_PMU_QID_PARA_QUEUE_S;
> +	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_QID_PARA, idx, val);
> +}
> +
> +static bool hns3_pmu_qid_req_start(struct hns3_pmu *hns3_pmu, u32 idx)
> +{
> +	bool queue_id_valid = false;
> +	u32 reg_qid_ctrl, val;
> +	int err;
> +
> +	/* enable queue id request */
> +	hns3_pmu_writel(hns3_pmu, HNS3_PMU_REG_EVENT_QID_CTRL, idx,
> +			HNS3_PMU_QID_CTRL_REQ_ENABLE);
> +

...

> +}
> +
> +static bool hns3_pmu_validate_event_group(struct perf_event *event)
> +{
> +	struct perf_event *leader = event->group_leader;
> +	struct perf_event *sibling;
> +	int counters = 1;
> +
> +	if (!is_software_event(leader)) {
> +		/*
> +		 * We must NOT create groups containing mixed PMUs, although
> +		 * software events are acceptable
> +		 */
> +		if (leader->pmu != event->pmu)
> +			return false;
> +
> +		/* Increase counter for the leader */
> +		if (leader != event)
> +			counters++;
> +	}
> +
> +	for_each_sibling_event(sibling, event->group_leader) {
> +		if (is_software_event(sibling))
> +			continue;
> +
> +		if (sibling->pmu != event->pmu)
> +			return false;
> +
> +		/* Increase counter for each sibling */
> +		counters++;
> +	}
> +
> +	return counters <= HNS3_PMU_MAX_COUNTERS;
> +}
> +

This is exact same effectively as hisi_validate_event_group(), apart from:

return counters <= HNS3_PMU_MAX_COUNTERS;

vs

return counters <= hisi_pmu->num_counters;


Can we factor all this out? Less code to review makes reviewing easier 
and quicker and less daunting ...

> +}
> +
> +/*
> + * The performance calculation formula of all types of event is
> + *                 performance = data / data_ext.
> + * The arguments data and data_ext have different meanings for different types
> + * of events as follow:
> + * event_type             data                     data_ext
> + * bandwidth              byte number              cycles number
> + * packet rate            packet number            cycles number
> + * interrupt rate         interrupt number         cycles number
> + * latency                cycles number            packet number
> + */
> +static u64 hns3_pmu_get_performance(u8 event_type, u32 hw_clk_freq, u64 data,
> +				    u64 data_ext)
> +{
> +	u64 result;
> +
> +	if (!hw_clk_freq || !data || !data_ext)
> +		return 0;
> +
> +	switch (event_type) {
> +	case HNS3_PMU_EVENT_TYPE_BANDWIDTH:
> +		/* process data to set unit of bandwidth as "KBits/s" */
> +		result = data / hns3_pmu_tick_to_ms(hw_clk_freq, data_ext);
> +		result = BYTES_TO_BITS(result);
> +		break;
> +
> +	case HNS3_PMU_EVENT_TYPE_PACKET_RATE:
> +	case HNS3_PMU_EVENT_TYPE_INTR_RATE:
> +		/* process data to set unit as "pps" */
> +		result = data * 1000 /
> +			 hns3_pmu_tick_to_ms(hw_clk_freq, data_ext);
> +		break;
> +
> +	case HNS3_PMU_EVENT_TYPE_LATENCY:
> +		/* process data to set unit of latency as "ns" */
> +		result = data / data_ext;
> +		result = result * 1000000000 / hw_clk_freq;
> +		break;
> +
> +	default:
> +		result = data / data_ext;
> +		break;
> +	}
> +
> +	return result;
> +}
> +
> +static int hns3_pmu_event_init(struct perf_event *event)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	int idx;
> +	int ret;
> +
> +	if (event->attr.type != event->pmu->type)
> +		return -ENOENT;
> +
> +	/* Sampling is not supported */
> +	if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
> +		return -EOPNOTSUPP;
> +
> +	event->cpu = hns3_pmu->on_cpu;
> +
> +	idx = hns3_pmu_get_event_idx(hns3_pmu);
> +	if (idx < 0) {
> +		pci_err(hns3_pmu->pdev, "Up to %u events are supported!\n",
> +			HNS3_PMU_MAX_COUNTERS);
> +		return -EBUSY;
> +	}
> +
> +	hwc->idx = idx;
> +
> +	ret = hns3_pmu_select_filter_mode(event, hns3_pmu);
> +	if (ret) {
> +		pci_err(hns3_pmu->pdev, "Invalid filter, ret = %d.\n", ret);
> +		return ret;
> +	}
> +
> +	if (!hns3_pmu_validate_event_group(event)) {
> +		pci_err(hns3_pmu->pdev, "Invalid event group.\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static void hns3_pmu_read(struct perf_event *event)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +	struct hw_perf_event_extra *hwc_ext;
> +	u64 new_cnt_ext, prev_cnt_ext;
> +	u64 new_cnt, prev_cnt, delta;
> +
> +	hwc_ext = &hwc->extra_reg;
> +	do {
> +		prev_cnt = local64_read(&hwc->prev_count);
> +		prev_cnt_ext = hwc_ext->config;
> +		hns3_pmu_read_counter(event, &new_cnt, &new_cnt_ext);
> +	} while (local64_cmpxchg(&hwc->prev_count, prev_cnt, new_cnt) !=
> +		 prev_cnt);
> +
> +	hwc_ext->config = new_cnt_ext;
> +
> +	delta = hns3_pmu_get_performance(hns3_get_event(event),
> +					 hns3_pmu->hw_clk_freq,
> +					 new_cnt - prev_cnt,
> +					 new_cnt_ext - prev_cnt_ext);

This looks very much like what was originally had in the hisi PCI PMU 
driver:

https://lore.kernel.org/linux-arm-kernel/20210616134257.GA22905 at willie-the-truck/

https://lore.kernel.org/linux-arm-kernel/20210617175704.GF24813 at willie-the-truck/

Please consult with liuqi

If it is, I figure that we're going to need to expose the 2x values and 
do the calculation in userspace.

> +
> +	local64_add(delta, &event->count);
> +}
> +
> +static void hns3_pmu_start(struct perf_event *event, int flags)
> +{
> +	struct hns3_pmu *hns3_pmu = to_hns3_pmu(event->pmu);
> +	struct hw_perf_event *hwc = &event->hw;
> +
> +	if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
> +		return;
> +
> +	WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));

...

> +
> +	val = readl(hns3_pmu->base + HNS3_PMU_REG_DEVICE_ID);
> +	device_id = val & 0xffff;
> +	name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hns3_pmu_%u", device_id);

would adding sccl to the name help it make it more clear that this is 
per sccl, like hns3_pmu_sccl%u?

> +	if (!name) {
> +		pci_err(pdev, "failed to allocate name for HNS3 PMU.\n");

I don't think that you need this -ENOMEM messages

> +		ret = -ENOMEM;
> +		goto err_alloc_dev_name;
> +	}
> +
> +	hns3_pmu->pdev = pdev;
> +	hns3_pmu->on_cpu = HNS3_PMU_INVALID_CPU_ID;

can you possibly just initially target the probe CPU?

> +	hns3_pmu->identifier = readl(hns3_pmu->base + HNS3_PMU_REG_VERSION);
> +	hns3_pmu->pmu = (struct pmu) {
> +		.name		= name,
> +		.module		= THIS_MODULE,
> +		.event_init	= hns3_pmu_event_init,
> +		.pmu_enable	= hns3_pmu_enable,
> +		.pmu_disable	= hns3_pmu_disable,
> +		.add		= hns3_pmu_add,
> +		.del		= hns3_pmu_del,
> +		.start		= hns3_pmu_start,
> +		.stop		= hns3_pmu_stop,
> +		.read		= hns3_pmu_read,
> +		.task_ctx_nr	= perf_invalid_context,
> +		.attr_groups	= hns3_pmu_attr_groups,
> +		.capabilities	= PERF_PMU_CAP_NO_EXCLUDE,
> +	};
> +
> +	return 0;
> +
> +err_alloc_dev_name:
> +	iounmap(hns3_pmu->base);
> +err_ioremap_bar:
> +	pci_release_regions(pdev);
> +
> +	return ret;
> +}
> +
> +static irqreturn_t hns3_pmu_irq(int irq, void *data)
> +{
> +	struct hns3_pmu *hns3_pmu = data;
> +	u32 intr_status, idx;
> +
> +	for (idx = 0; idx < HNS3_PMU_MAX_COUNTERS; idx++) {
> +		intr_status = hns3_pmu_readl(hns3_pmu,
> +					     HNS3_PMU_REG_EVENT_INTR_STATUS,
> +					     idx);
> +
> +		/*
> +		 * As each counter will restart from 0 when it is overflowed,
> +		 * extra processing is no need, just clear interrupt status.
> +		 */
> +		if (intr_status)
> +			hns3_pmu_clear_intr_status(hns3_pmu, idx);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int hns3_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
> +{
> +	struct hns3_pmu *hns3_pmu;
> +
> +	hns3_pmu = hlist_entry_safe(node, struct hns3_pmu, node);
> +	if (!hns3_pmu)
> +		return -ENODEV;
> +
> +	if (hns3_pmu->on_cpu == HNS3_PMU_INVALID_CPU_ID) {
> +		hns3_pmu->on_cpu = cpu;
> +		irq_set_affinity_hint(hns3_pmu->irq, cpumask_of(cpu));
> +	}
> +
> +	return 0;
> +}
> +
> +static int hns3_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
> +{
> +	struct hns3_pmu *hns3_pmu;
> +	unsigned int target;
> +
> +	hns3_pmu = hlist_entry_safe(node, struct hns3_pmu, node);
> +	if (!hns3_pmu)
> +		return -ENODEV;
> +
> +	/* Nothing to do if this CPU doesn't own the PMU */
> +	if (hns3_pmu->on_cpu != cpu)
> +		return 0;
> +
> +	/* Choose a new CPU from all online cpus */
> +	target = cpumask_any_but(cpu_online_mask, cpu);
> +	if (target >= nr_cpu_ids)
> +		return 0;
> +
> +	perf_pmu_migrate_context(&hns3_pmu->pmu, cpu, target);
> +	hns3_pmu->on_cpu = target;
> +	irq_set_affinity_hint(hns3_pmu->irq, cpumask_of(target));
> +
> +	return 0;
> +}
> +
> +static int hns3_pmu_irq_register(struct pci_dev *pdev,
> +				 struct hns3_pmu *hns3_pmu)
> +{
> +	int irq, ret;
> +
> +	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);

I don't think that a pcim exists here, so can use devm_add_action() to 
free them [maybe the name is wrong I mentioned]

> +	if (ret < 0) {
> +		pci_err(pdev, "failed to enable MSI vectors, ret = %d.\n", ret);
> +		return ret;
> +	}
> +
> +	irq = pci_irq_vector(pdev, 0);
> +	ret = request_irq(irq, hns3_pmu_irq, 0, hns3_pmu->pmu.name, hns3_pmu);

devm_request_irq()

> +	if (ret) {
> +		pci_err(pdev, "failed to register irq, ret = %d.\n", ret);
> +		pci_free_irq_vectors(pdev);
> +		return ret;
> +	}
> +
> +	hns3_pmu->irq = irq;
> +
> +	return 0;
> +}
> +
> +static void hns3_pmu_irq_unregister(struct pci_dev *pdev,
> +				    struct hns3_pmu *hns3_pmu)
> +{
> +	free_irq(hns3_pmu->irq, hns3_pmu);
> +	pci_free_irq_vectors(pdev);
> +}
> +
> +static int hns3_pmu_init(struct pci_dev *pdev, struct hns3_pmu *hns3_pmu)
> +{
> +	int ret;
> +
> +	ret = hns3_pmu_alloc_pmu(pdev, hns3_pmu);
> +	if (ret)
> +		return ret;
> +
> +	ret = hns3_pmu_irq_register(pdev, hns3_pmu);
> +	if (ret)
> +		goto err_irq_register;
> +
> +	ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
> +				       &hns3_pmu->node);
> +	if (ret) {
> +		pci_err(pdev, "failed to register hotplug, ret = %d.\n", ret);
> +		goto err_register_hotplug;
> +	}
> +
> +	ret = perf_pmu_register(&hns3_pmu->pmu, hns3_pmu->pmu.name, -1);
> +	if (ret) {
> +		pci_err(pdev, "failed to register HNS3 PMU, ret = %d.\n", ret);

do you need to mention "HNS3 PMU", since pdev is passed

> +		goto err_register_pmu;
> +	}
> +
> +	return ret;
> +
> +err_register_pmu:
> +	cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
> +				    &hns3_pmu->node);
> +	irq_set_affinity_hint(hns3_pmu->irq, NULL);
> +
> +err_register_hotplug:
> +	hns3_pmu_irq_unregister(pdev, hns3_pmu);
> +
> +err_irq_register:
> +	iounmap(hns3_pmu->base);
> +
> +	return ret;
> +}
> +
> +static void hns3_pmu_uninit(struct pci_dev *pdev)
> +{
> +	struct hns3_pmu *hns3_pmu = (struct hns3_pmu *)pci_get_drvdata(pdev);

no need to cast a void ptr

> +
> +	perf_pmu_unregister(&hns3_pmu->pmu);
> +	cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HNS3_PMU_ONLINE,
> +				    &hns3_pmu->node);
> +	irq_set_affinity_hint(hns3_pmu->irq, NULL);
> +	hns3_pmu_irq_unregister(pdev, hns3_pmu);
> +	iounmap(hns3_pmu->base);
> +}
> +
> +static int hns3_pmu_init_dev(struct pci_dev *pdev)
> +{
> +	int ret;
> +
> +	ret = pci_enable_device(pdev);

isn't there pci-managed versions of this so that you don't need worry 
about undo'ing this manually?

> +	if (ret) {
> +		pci_err(pdev, "failed to enable pci device, ret = %d.\n", ret);
> +		return ret;
> +	}
> +
> +	ret = pci_request_mem_regions(pdev, "hns3_pmu");
> +	if (ret < 0) {
> +		pci_err(pdev, "failed to request pci mem regions, ret = %d.\n",
> +			ret);
> +		pci_disable_device(pdev);
> +		return ret;
> +	}
> +
> +	pci_set_master(pdev);
> +
> +	return 0;
> +}
> +
> +static void hns3_pmu_uninit_dev(struct pci_dev *pdev)
> +{
> +	pci_clear_master(pdev);
> +	pci_release_mem_regions(pdev);
> +	pci_disable_device(pdev);
> +}
> +


From dave.hansen at intel.com  Tue Jan 18 09:28:45 2022
From: dave.hansen at intel.com (Dave Hansen)
Date: Tue, 18 Jan 2022 09:28:45 -0800
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <1642472965.lgfksp6krp.astroid@bobo.none>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
 <1642472965.lgfksp6krp.astroid@bobo.none>
Message-ID: <4488d39f-0698-7bfd-b81c-1e609821818f@intel.com>

On 1/17/22 6:46 PM, Nicholas Piggin wrote:
>> This all sounds very fragile to me.  Every time a new architecture would
>> get added for huge vmalloc() support, the developer needs to know to go
>> find that architecture's module_alloc() and add this flag.
> This is documented in the Kconfig.
> 
>  #
>  #  Archs that select this would be capable of PMD-sized vmaps (i.e.,
>  #  arch_vmap_pmd_supported() returns true), and they must make no assumptions
>  #  that vmalloc memory is mapped with PAGE_SIZE ptes. The VM_NO_HUGE_VMAP flag
>  #  can be used to prohibit arch-specific allocations from using hugepages to
>  #  help with this (e.g., modules may require it).
>  #
>  config HAVE_ARCH_HUGE_VMALLOC
>          depends on HAVE_ARCH_HUGE_VMAP
>          bool
> 
> Is it really fair to say it's *very* fragile? Surely it's reasonable to 
> read the (not very long) documentation ad understand the consequences for
> the arch code before enabling it.

Very fragile or not, I think folks are likely to get it wrong.  It would
be nice to have it default *everyone* to safe and slow and make *sure*
they go look at the architecture modules code itself before enabling
this for modules.

Just from that Kconfig text, I don't think I'd know off the top of my
head what do do for x86, or what code I needed to go touch.


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:24:11 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:24:11 +0100
Subject: [PATCH v2 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220118144851.69537-4-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150022epcas5p21912423606220552a78c7e22e4133a05@epcas5p2.samsung.com>
 <20220118144851.69537-4-alim.akhtar@samsung.com>
Message-ID: <735d1001-abcb-67d1-75a6-17db11cdec40@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add dt-schema documentation for Tesla FSD SoC clock controller.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../bindings/clock/tesla,fsd-clock.yaml       | 198 ++++++++++++++++++
>  1 file changed, 198 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> new file mode 100644
> index 000000000000..dc808e2f8327
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
> @@ -0,0 +1,198 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Tesla FSD (Full Self-Driving) SoC clock controller
> +
> +maintainers:
> +  - Alim Akhtar <alim.akhtar at samsung.com>
> +  - linux-fsd at tesla.com
> +
> +description: |
> +  FSD clock controller consist of several clock management unit
> +  (CMU), which generates clocks for various inteernal SoC blocks.
> +  The root clock comes from external OSC clock (24 MHz).
> +
> +  All available clocks are defined as preprocessor macros in
> +  'dt-bindings/clock/fsd-clk.h' header.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - tesla,fsd-clock-cmu
> +      - tesla,fsd-clock-imem
> +      - tesla,fsd-clock-peric
> +      - tesla,fsd-clock-fsys0
> +      - tesla,fsd-clock-fsys1
> +      - tesla,fsd-clock-mfc
> +      - tesla,fsd-clock-cam_csi
> +

I am not particularly happy about FSD naming (so SoC name, sub-arch
name), but Olof was fine with it, so I won't oppose. Bindings look ok.


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:31:05 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:31:05 +0100
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220118144851.69537-5-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
 <20220118144851.69537-5-alim.akhtar@samsung.com>
Message-ID: <b35fa0ff-18a0-2a9d-5a1b-378ef2fef66f@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add initial clock support for FSD (Full Self-Driving) SoC
> which is required to bring-up platforms based on this SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/Kconfig   |   7 +
>  drivers/clk/samsung/Makefile  |   1 +
>  drivers/clk/samsung/clk-fsd.c | 308 ++++++++++++++++++++++++++++++++++
>  drivers/clk/samsung/clk-pll.c |   1 +
>  drivers/clk/samsung/clk-pll.h |   1 +
>  5 files changed, 318 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-fsd.c
> 
> diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
> index 0e18d6ff2916..11587eb87fc4 100644
> --- a/drivers/clk/samsung/Kconfig
> +++ b/drivers/clk/samsung/Kconfig
> @@ -124,3 +124,10 @@ config S3C2443_COMMON_CLK
>  	help
>  	  Support for the clock controller present on the Samsung
>  	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
> +
> +config TESLA_FSD_COMMON_CLK
> +	bool "Tesla FSD clock controller support" if COMPILE_TEST
> +	depends on COMMON_CLK_SAMSUNG
> +	help
> +	  Support for the clock controller present on the Tesla FSD SoC.
> +	  Choose Y here only if you build for this SoC.

The clock drivers Kconfig is organized in a way, that platform should
select only COMMON_CLK_SAMSUNG (first comment in a file), so let's keep
it consistent also for FSD. "select TESLA_FSD_COMMON_CLK if ARM64 &&
ARCH_TESLA_FSD" and skip the select in Kconfig.platform in following patch.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:34:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:34:07 +0100
Subject: [PATCH v2 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220118144851.69537-6-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150033epcas5p15b88d4f0c695fc515f20d8dffe15202e@epcas5p1.samsung.com>
 <20220118144851.69537-6-alim.akhtar@samsung.com>
Message-ID: <d61c2cef-4f59-53ba-7135-b9acc2defeee@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add CMU_PERIC block clock information needed for various IPs
> functions found in this block.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 405 ++++++++++++++++++++++++++++++++++
>  1 file changed, 405 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:34:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:34:30 +0100
Subject: [PATCH v2 06/16] clk: samsung: fsd: Add cmu_fsys0 clock
 information
In-Reply-To: <20220118144851.69537-7-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150037epcas5p1624361eb48fa14cdf9ed88de6f890db4@epcas5p1.samsung.com>
 <20220118144851.69537-7-alim.akhtar@samsung.com>
Message-ID: <3c400f9f-9d02-050e-cf21-c3376bf15127@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
> the related clock information for the same.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
>  1 file changed, 302 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:34:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:34:54 +0100
Subject: [PATCH v2 07/16] clk: samsung: fsd: Add cmu_fsys1 clock
 information
In-Reply-To: <20220118144851.69537-8-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150041epcas5p2634381919d0e9f60867d6087162fa134@epcas5p2.samsung.com>
 <20220118144851.69537-8-alim.akhtar@samsung.com>
Message-ID: <ea4d5b07-c14c-4558-9ddf-c55e9a6ff657@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Adds cmu_fsys1 block clock information which are needed
> for PCIe IPs in block FSYS1.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
>  1 file changed, 175 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:36:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:36:01 +0100
Subject: [PATCH v2 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220118144851.69537-9-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150045epcas5p4e54922758fb7922b1fd8de0995d2127e@epcas5p4.samsung.com>
 <20220118144851.69537-9-alim.akhtar@samsung.com>
Message-ID: <4606bf04-154f-97bb-9b8b-1103c6308004@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Adds cmu_imem clock related code, imem block contains IPs
> like WDT, DMA, TMU etc, these clocks are required for such
> IP function.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
>  1 file changed, 283 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:36:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:36:28 +0100
Subject: [PATCH v2 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220118144851.69537-10-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150048epcas5p3449136cf0dbc2186d91c4472e9df68e0@epcas5p3.samsung.com>
 <20220118144851.69537-10-alim.akhtar@samsung.com>
Message-ID: <c64aef61-ae6b-8483-5f9f-7bbace0d2690@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Adds cmu_mfc clock related code, these clocks are
> required for MFC IP.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
>  1 file changed, 121 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:36:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:36:45 +0100
Subject: [PATCH v2 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220118144851.69537-11-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150052epcas5p12efa399d1a59fc2fb0595eef128ffdf9@epcas5p1.samsung.com>
 <20220118144851.69537-11-alim.akhtar@samsung.com>
Message-ID: <ad954b04-9df9-6675-18b8-8cda01467ce8@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Sathyakam M <sathya at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
>  1 file changed, 207 insertions(+)
> 
> diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
> index 72a2b38524a1..afac8760ebe1 100644
> --- a/drivers/clk/samsung/clk-fsd.c
> +++ b/drivers/clk/samsung/clk-fsd.c
> @@ -1543,6 +1543,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
>  	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
>  };
>  


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:38:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:38:42 +0100
Subject: [PATCH v2 11/16] dt-bindings: pinctrl: samsung: Add compatible
 for Tesla FSD SoC
In-Reply-To: <20220118144851.69537-12-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150056epcas5p4825077a17b8c37b0e7cea60c4dced3c8@epcas5p4.samsung.com>
 <20220118144851.69537-12-alim.akhtar@samsung.com>
Message-ID: <b165825c-a04f-d5bd-6bce-8725acdc461d@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add compatible for Tesla Full Self-Driving SoC. The
> pinctrl hardware IP is similar to what found on most of the
> exynos series of SoC, so this new compatible is added in

s/exynos/Exynos/

> samsung pinctrl binding.

s/samsung/Samsung/

> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
>  1 file changed, 1 insertion(+)
> 

It seems that I will take my dtschema patch (together with pinctrl
driver changes) after merge window, so this will have to be rebased on
new dtschema.

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:40:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:40:01 +0100
Subject: [PATCH v2 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220118144851.69537-14-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150104epcas5p4ac6fdc739d21c7d7eb2e53e469466487@epcas5p4.samsung.com>
 <20220118144851.69537-14-alim.akhtar@samsung.com>
Message-ID: <b1bf4b43-639d-c09c-2fb2-0ac58a6eb858@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add device tree bindings for the Tesla FSD ARM SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
>  1 file changed, 27 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
> 

Looks good to me. I'll take it via Samsung-SoC after the merge window
unless there are some comments/discussion.


Best regards,
Krzysztof


From mathieu.poirier at linaro.org  Tue Jan 18 10:41:23 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 18 Jan 2022 11:41:23 -0700
Subject: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QXP
In-Reply-To: <20220111033333.403448-4-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-4-peng.fan@oss.nxp.com>
Message-ID: <20220118184123.GD1119324@p14s>

On Tue, Jan 11, 2022 at 11:33:25AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add i.MX8QXP compatible
> 
> Add a new property rsrc-id for SoC which supports SCFW. This rsrc-id

You are introducing an acronym that doesn't have a definition - I have to grep
the kernel tree to have an idea of what SCFW is.  That consumes time that I
don't have to review your code or someone else's. 

> is used to check whether remote process is under control of Linux or

s/process/processor

> not.
> 
> To i.MX8QM/QXP, when M4 is in the same hardware partition with Cortex-A
> cores, need power up M4 through SCFW, then M4 could start. So introduce
> power-domains property
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml  | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> index fc16d903353e..ed1bcb3046a9 100644
> --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> @@ -19,6 +19,7 @@ properties:
>        - fsl,imx8mm-cm4
>        - fsl,imx8mn-cm7
>        - fsl,imx8mp-cm7
> +      - fsl,imx8qxp-cm4
>        - fsl,imx8ulp-cm33
>        - fsl,imx7d-cm4
>        - fsl,imx7ulp-cm4
> @@ -59,6 +60,15 @@ properties:
>        Indicate whether need to load the default firmware and start the remote
>        processor automatically.
>  
> +  power-domains:
> +    maxItems: 8
> +
> +  rsrc-id:
> +    description:
> +      This property is to specify the resource id of the remote processor in SoC
> +      which supports SCFW
> +    maxItems: 1
> +
>  required:
>    - compatible
>  
> -- 
> 2.25.1
> 


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:41:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:41:28 +0100
Subject: [PATCH v2 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <b1bf4b43-639d-c09c-2fb2-0ac58a6eb858@canonical.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150104epcas5p4ac6fdc739d21c7d7eb2e53e469466487@epcas5p4.samsung.com>
 <20220118144851.69537-14-alim.akhtar@samsung.com>
 <b1bf4b43-639d-c09c-2fb2-0ac58a6eb858@canonical.com>
Message-ID: <25795f7e-8e04-aaae-db47-05e5016a1890@canonical.com>

On 18/01/2022 19:40, Krzysztof Kozlowski wrote:
> On 18/01/2022 15:48, Alim Akhtar wrote:
>> Add device tree bindings for the Tesla FSD ARM SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
>>  1 file changed, 27 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
>>
> 
> Looks good to me. I'll take it via Samsung-SoC after the merge window
> unless there are some comments/discussion.

Wait, no, I won't take it, it's not Samsung Exynos. :) I guess this
could go via arm-soc directly...

Anyway:

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From mathieu.poirier at linaro.org  Tue Jan 18 10:44:53 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 18 Jan 2022 11:44:53 -0700
Subject: [PATCH 3/9] remoteproc: support self recovery after rproc crash
In-Reply-To: <20220111033333.403448-6-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-6-peng.fan@oss.nxp.com>
Message-ID: <20220118184453.GE1119324@p14s>

On Tue, Jan 11, 2022 at 11:33:27AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Current logic only support main processor to stop/start the remote
> processor after rproc crash. However to SoC, such as i.MX8QM/QXP, the
> remote processor could do self recovery after crash and trigger watchdog
> reboot. It does not need main processor to load image, stop/start M4
> core.
> 
> This patch add a new flag to indicate whether the SoC has self recovery
> capability. And introduce two functions: rproc_self_recovery,
> rproc_assisted_recovery for the two cases. Assisted recovery is as
> before, let main processor to help recovery, while self recovery is
> recover itself withou help. To self recovery, we only do detach and
> attach.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/remoteproc_core.c | 66 ++++++++++++++++++++--------
>  include/linux/remoteproc.h           |  2 +
>  2 files changed, 49 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
> index 69f51acf235e..4bd5544dab8f 100644
> --- a/drivers/remoteproc/remoteproc_core.c
> +++ b/drivers/remoteproc/remoteproc_core.c
> @@ -1887,6 +1887,49 @@ static int __rproc_detach(struct rproc *rproc)
>  	return 0;
>  }
>  
> +static int rproc_self_recovery(struct rproc *rproc)
> +{
> +	int ret;
> +
> +	mutex_unlock(&rproc->lock);
> +	ret = rproc_detach(rproc);
> +	mutex_lock(&rproc->lock);
> +	if (ret)
> +		return ret;
> +
> +	if (atomic_inc_return(&rproc->power) > 1)
> +		return 0;
> +	return rproc_attach(rproc);
> +}
> +
> +static int rproc_assisted_recovery(struct rproc *rproc)
> +{
> +	const struct firmware *firmware_p;
> +	struct device *dev = &rproc->dev;
> +	int ret;
> +
> +	ret = rproc_stop(rproc, true);
> +	if (ret)
> +		return ret;
> +
> +	/* generate coredump */
> +	rproc->ops->coredump(rproc);
> +
> +	/* load firmware */
> +	ret = request_firmware(&firmware_p, rproc->firmware, dev);
> +	if (ret < 0) {
> +		dev_err(dev, "request_firmware failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	/* boot the remote processor up again */
> +	ret = rproc_start(rproc, firmware_p);
> +
> +	release_firmware(firmware_p);
> +
> +	return ret;
> +}
> +
>  /**
>   * rproc_trigger_recovery() - recover a remoteproc
>   * @rproc: the remote processor
> @@ -1901,7 +1944,6 @@ static int __rproc_detach(struct rproc *rproc)
>   */
>  int rproc_trigger_recovery(struct rproc *rproc)
>  {
> -	const struct firmware *firmware_p;
>  	struct device *dev = &rproc->dev;
>  	int ret;
>  
> @@ -1915,24 +1957,10 @@ int rproc_trigger_recovery(struct rproc *rproc)
>  
>  	dev_err(dev, "recovering %s\n", rproc->name);
>  
> -	ret = rproc_stop(rproc, true);
> -	if (ret)
> -		goto unlock_mutex;
> -
> -	/* generate coredump */
> -	rproc->ops->coredump(rproc);
> -
> -	/* load firmware */
> -	ret = request_firmware(&firmware_p, rproc->firmware, dev);
> -	if (ret < 0) {
> -		dev_err(dev, "request_firmware failed: %d\n", ret);
> -		goto unlock_mutex;
> -	}
> -
> -	/* boot the remote processor up again */
> -	ret = rproc_start(rproc, firmware_p);
> -
> -	release_firmware(firmware_p);
> +	if (rproc->self_recovery)
> +		ret = rproc_self_recovery(rproc);
> +	else
> +		ret = rproc_assisted_recovery(rproc);

The problem of how to handle crash recoveries for processors that have been
attached to is difficult.  Finding a solution for that should be on a patchset
of its own so that people can provide input.

>  
>  unlock_mutex:
>  	mutex_unlock(&rproc->lock);
> diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> index e0600e1e5c17..b32ef46f8aa4 100644
> --- a/include/linux/remoteproc.h
> +++ b/include/linux/remoteproc.h
> @@ -529,6 +529,7 @@ struct rproc_dump_segment {
>   * @elf_machine: firmware ELF machine
>   * @cdev: character device of the rproc
>   * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release
> + * @self_recovery: flag to indicate if remoteproc support self recovery
>   */
>  struct rproc {
>  	struct list_head node;
> @@ -568,6 +569,7 @@ struct rproc {
>  	u16 elf_machine;
>  	struct cdev cdev;
>  	bool cdev_put_on_release;
> +	bool self_recovery;
>  };
>  
>  /**
> -- 
> 2.25.1
> 


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:45:11 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:45:11 +0100
Subject: [PATCH v2 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220118144851.69537-15-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150108epcas5p2d9cd4db7cb368c2bfbd7d058eba4107c@epcas5p2.samsung.com>
 <20220118144851.69537-15-alim.akhtar@samsung.com>
Message-ID: <43e72d34-0e11-9ff6-6924-0cab62b51891@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add initial device tree support for "Full Self-Driving" (FSD) SoC
> This SoC contain three clusters of four cortex-a72 CPUs and various
> peripheral IPs.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  MAINTAINERS                           |   8 +
>  arch/arm64/Kconfig.platforms          |   7 +
>  arch/arm64/boot/dts/Makefile          |   1 +
>  arch/arm64/boot/dts/tesla/Makefile    |   3 +
>  arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
>  arch/arm64/boot/dts/tesla/fsd.dtsi    | 651 ++++++++++++++++++++++++++
>  6 files changed, 709 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
> 

I saw you dropped the MCT timer from DTSI. I wonder why?

Not very happy with FSD naming (as discussed before), but board
compatible looks reasonable. Code looks good to me:
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Similarly to previous vendor-prefix patch, please let me know if it's
expected me to take it. I assume no. :)


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:46:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:46:43 +0100
Subject: [PATCH v2 15/16] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220118144851.69537-16-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150112epcas5p4b63030d9bf136b4a91468b0d02e75cae@epcas5p4.samsung.com>
 <20220118144851.69537-16-alim.akhtar@samsung.com>
Message-ID: <581732d1-8d86-f7c6-ebbf-795b48e5e67f@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Add initial pin configuration nodes for FSD SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 335 +++++++++++++++++++++
>  arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
>  2 files changed, 357 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> 
> diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> new file mode 100644
> index 000000000000..371344e446f3
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla Full Self-Driving SoC device tree source
> + *
> + * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
> + *		https://www.samsung.com
> + * Copyright (c) 2017-2021 Tesla, Inc.
> + *		https://www.tesla.com
> + */
> +
> +#include <dt-bindings/pinctrl/samsung.h>
> +
> +&pinctrl_fsys0 {
> +	gpf0: gpf0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf1: gpf1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf6: gpf6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf4: gpf4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf5: gpf5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +};
> +
> +&pinctrl_peric {
> +	gpc8: gpc8 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf2: gpf2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpf3: gpf3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd0: gpd0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb0: gpb0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb1: gpb1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb4: gpb4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb5: gpb5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb6: gpb6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpb7: gpb7 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd1: gpd1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd2: gpd2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpd3: gpd3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg0: gpg0 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg1: gpg1 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg2: gpg2 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg3: gpg3 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg4: gpg4 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg5: gpg5 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg6: gpg6 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	gpg7: gpg7 {
> +		gpio-controller;
> +		#gpio-cells = <2>;
> +
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +	};
> +
> +	pwm0_out: pwm0-out {
> +		samsung,pins = "gpb6-1";
> +		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
> +		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
> +		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
> +	};

All pin configuration nodes with "-pins" suffix, even though current
bindings do not mandate it. Less changes in the future.


Best regards,
Krzysztof


From mathieu.poirier at linaro.org  Tue Jan 18 10:47:10 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 18 Jan 2022 11:47:10 -0700
Subject: [PATCH 4/9] remoteproc: imx_rproc: ignore create mem entry for
 resource table
In-Reply-To: <20220111033333.403448-7-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-7-peng.fan@oss.nxp.com>
Message-ID: <20220118184710.GF1119324@p14s>

On Tue, Jan 11, 2022 at 11:33:28AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
>

The "ignore" in the title should have a capital 'I'.

> resource table will not be used for memory allocation, no need to create

s/resource/Resource

> rproc mem entry.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 75fde16f80a4..7b2578177ea8 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -423,6 +423,9 @@ static int imx_rproc_prepare(struct rproc *rproc)
>  		if (!strcmp(it.node->name, "vdev0buffer"))
>  			continue;
>  
> +		if (!strncmp(it.node->name, "rsc-table", strlen("rsc-table")))
> +			continue;
> +

This is a bug fix that should be in a separate patch with a "Fixes:" tag.

>  		rmem = of_reserved_mem_lookup(it.node);
>  		if (!rmem) {
>  			dev_err(priv->dev, "unable to acquire memory-region\n");
> -- 
> 2.25.1
> 


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:47:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:47:15 +0100
Subject: [PATCH v2 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220118144851.69537-17-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150116epcas5p415b4b658b3ca3fe5e52e11a33546b926@epcas5p4.samsung.com>
 <20220118144851.69537-17-alim.akhtar@samsung.com>
Message-ID: <ed1f3bd3-b17c-8c6e-35c6-c996cf0facfa@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> This patch enables the Tesla FSD SoC in arm64 defconfig.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  arch/arm64/configs/defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Tue Jan 18 10:48:47 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 18 Jan 2022 19:48:47 +0100
Subject: [PATCH v2 12/16] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220118144851.69537-13-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150100epcas5p3b7cf28e13fd177336dc9b06875d94f43@epcas5p3.samsung.com>
 <20220118144851.69537-13-alim.akhtar@samsung.com>
Message-ID: <a1ca1ad2-5e24-0cd4-cbf2-bdf867cccbd7@canonical.com>

On 18/01/2022 15:48, Alim Akhtar wrote:
> Adds Tesla FSD SoC specific data to enable pinctrl.
> FSD SoC has similar pinctrl controller as found in the most
> samsung/exynos SoCs.

s/samsung/Samsung/
s/exynos/Exynos/

> 
> Cc: linux-fsd at tesla.com
> Acked-by: Linus Walleij <linus.walleij at linaro.org>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
>  drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
>  drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
>  3 files changed, 74 insertions(+)
> 

Looks good to me. I'll take it via Samsung pinctrl tree after the merge
window.

Best regards,
Krzysztof


From mathieu.poirier at linaro.org  Tue Jan 18 10:50:19 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 18 Jan 2022 11:50:19 -0700
Subject: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
In-Reply-To: <20220111033333.403448-8-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-8-peng.fan@oss.nxp.com>
Message-ID: <20220118185019.GG1119324@p14s>

On Tue, Jan 11, 2022 at 11:33:29AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> To i.MX8QXP/QM/ULP and i.MX7ULP, Mcore maybe out of control of Linux.
> And in such case, no need clk, so make clk optional with has_clk.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 7b2578177ea8..0e99a3ca6fbc 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -89,6 +89,7 @@ struct imx_rproc {
>  	struct work_struct		rproc_work;
>  	struct workqueue_struct		*workqueue;
>  	void __iomem			*rsc_table;
> +	bool				has_clk;

I am usually weary of bloating structures with flags.  I suggest achieving the
same functionality with a macro that compares priv->dcfg with the right
imx_rproc_dcfg structure. 

>  };
>  
>  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
> @@ -724,6 +725,9 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
>  	if (dcfg->method == IMX_RPROC_NONE)
>  		return 0;
>  
> +	if (!priv->has_clk)
> +		return 0;
> +
>  	priv->clk = devm_clk_get(dev, NULL);
>  	if (IS_ERR(priv->clk)) {
>  		dev_err(dev, "Failed to get clock\n");
> @@ -768,6 +772,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
>  	priv->rproc = rproc;
>  	priv->dcfg = dcfg;
>  	priv->dev = dev;
> +	priv->has_clk = true;
>  
>  	dev_set_drvdata(dev, rproc);
>  	priv->workqueue = create_workqueue(dev_name(dev));
> -- 
> 2.25.1
> 


From yury.norov at gmail.com  Tue Jan 18 10:53:54 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 18 Jan 2022 10:53:54 -0800
Subject: [RFC PATCH] arm64: don't vmap() invalid page
Message-ID: <20220118185354.464517-1-yury.norov@gmail.com>

vmap() takes struct page *pages as one of arguments, and user may provide
an invalid pointer, which would lead to DABT at address translation later.
Currently, kernel checks the pages against NULL. In my case, however, the
address was not NULL, and was big enough so that the hardware generated
Address Size Abort.

Interestingly, this abort happens even if copy_from_kernel_nofault() is used,
which is quite inconvenient for debugging purposes. 

This patch adds an arch_vmap_page_valid() helper into vmap() path, so that
architectures may add arch-specific checks of the pointer passed into vmap.

For arm64, if the page passed to vmap() corresponds to a physical address
greater than maximum possible value as described in TCR_EL1.IPS register, the
following table walk would generate Address Size Abort. Instead of creating
the invalid mapping, kernel will return ERANGE in such situation.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 arch/arm64/include/asm/vmalloc.h | 41 ++++++++++++++++++++++++++++++++
 include/linux/vmalloc.h          |  7 ++++++
 mm/vmalloc.c                     |  8 +++++--
 3 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h
index b9185503feae..e9d43ee019ad 100644
--- a/arch/arm64/include/asm/vmalloc.h
+++ b/arch/arm64/include/asm/vmalloc.h
@@ -4,6 +4,47 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
+static inline u64 pa_size(u64 ips)
+{
+	switch (ips) {
+	case 0b000:
+		return 1UL << 32;
+	case 0b001:
+		return 1UL << 36;
+	case 0b010:
+		return 1UL << 40;
+	case 0b011:
+		return 1UL << 42;
+	case 0b100:
+		return 1UL << 44;
+	case 0b101:
+		return 1UL << 48;
+	case 0b110:
+		return 1UL << 52;
+	/* All other values */
+	default:
+		return 1UL << 52;
+	}
+}
+
+#define arch_vmap_page_valid arch_vmap_page_valid
+static inline int arch_vmap_page_valid(struct page *page)
+{
+	u64 tcr, ips, paddr_size;
+
+	if (!page)
+		return -ENOMEM;
+
+	tcr = read_sysreg_s(SYS_TCR_EL1);
+	ips = (tcr & TCR_IPS_MASK) >> TCR_IPS_SHIFT;
+
+	paddr_size = pa_size(ips);
+	if (page_to_phys(page) >= paddr_size)
+		return -ERANGE;
+
+	return 0;
+}
+
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
 
 #define arch_vmap_pud_supported arch_vmap_pud_supported
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 6e022cc712e6..08b567d8bafc 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -119,6 +119,13 @@ static inline int arch_vmap_pte_supported_shift(unsigned long size)
 }
 #endif
 
+#ifndef arch_vmap_page_valid
+static inline int arch_vmap_page_valid(struct page *page)
+{
+	return page ? 0 : -ENOMEM;
+}
+#endif
+
 /*
  *	Highlevel APIs for driver use
  */
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d2a00ad4e1dd..ee0384405cdd 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -472,11 +472,15 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
 		return -ENOMEM;
 	do {
 		struct page *page = pages[*nr];
+		int ret;
 
 		if (WARN_ON(!pte_none(*pte)))
 			return -EBUSY;
-		if (WARN_ON(!page))
-			return -ENOMEM;
+
+		ret = arch_vmap_page_valid(page);
+		if (WARN_ON(ret))
+			return ret;
+
 		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
 		(*nr)++;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
-- 
2.30.2



From willy at infradead.org  Tue Jan 18 10:56:12 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Tue, 18 Jan 2022 18:56:12 +0000
Subject: [RFC PATCH] arm64: don't vmap() invalid page
In-Reply-To: <20220118185354.464517-1-yury.norov@gmail.com>
References: <20220118185354.464517-1-yury.norov@gmail.com>
Message-ID: <YecNTJNIfAd/D9GG@casper.infradead.org>

On Tue, Jan 18, 2022 at 10:53:54AM -0800, Yury Norov wrote:
> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer, which would lead to DABT at address translation later.
> Currently, kernel checks the pages against NULL. In my case, however, the
> address was not NULL, and was big enough so that the hardware generated
> Address Size Abort.
> 
> Interestingly, this abort happens even if copy_from_kernel_nofault() is used,
> which is quite inconvenient for debugging purposes. 
> 
> This patch adds an arch_vmap_page_valid() helper into vmap() path, so that
> architectures may add arch-specific checks of the pointer passed into vmap.
> 
> For arm64, if the page passed to vmap() corresponds to a physical address
> greater than maximum possible value as described in TCR_EL1.IPS register, the
> following table walk would generate Address Size Abort. Instead of creating
> the invalid mapping, kernel will return ERANGE in such situation.

This seems like a very elaborate way of spelling:

	pfn_valid(page_to_pfn(page));

which doesn't require any architecture hook.  No?


From mathieu.poirier at linaro.org  Tue Jan 18 10:57:29 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 18 Jan 2022 11:57:29 -0700
Subject: [PATCH 6/9] remoteproc: imx_rproc: support attaching to i.MX8QXP
 M4
In-Reply-To: <20220111033333.403448-9-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-9-peng.fan@oss.nxp.com>
Message-ID: <20220118185729.GH1119324@p14s>

On Tue, Jan 11, 2022 at 11:33:30AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> When M4 is kicked by SCFW, M4 runs in its own hardware partition, Linux
> could only do IPC with M4, it could not start, stop, update image.
> 
> When M4 crash reboot, it could notify Linux, so Linux could prepare to
> reattach to M4 after M4 recovery.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 96 ++++++++++++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 0e99a3ca6fbc..5f04aea2f6a1 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -6,6 +6,7 @@
>  #include <linux/arm-smccc.h>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> +#include <linux/firmware/imx/sci.h>
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
>  #include <linux/mailbox_client.h>
> @@ -59,6 +60,8 @@
>  #define IMX_SIP_RPROC_STARTED		0x01
>  #define IMX_SIP_RPROC_STOP		0x02
>  
> +#define	IMX_SC_IRQ_GROUP_REBOOTED	5
> +
>  /**
>   * struct imx_rproc_mem - slim internal memory structure
>   * @cpu_addr: MPU virtual address of the memory region
> @@ -90,6 +93,23 @@ struct imx_rproc {
>  	struct workqueue_struct		*workqueue;
>  	void __iomem			*rsc_table;
>  	bool				has_clk;
> +	struct imx_sc_ipc		*ipc_handle;
> +	struct notifier_block		proc_nb;
> +	u32				rproc_pt;
> +	u32				rsrc;

There is no documentation for the above two fields and I have to guess what they
do.

> +};
> +
> +static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> +	/* TCML/U */
> +	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
> +	/* OCRAM(Low 96KB) */
> +	{ 0x21000000, 0x00100000, 0x00018000, 0},
> +	/* OCRAM */
> +	{ 0x21100000, 0x00100000, 0x00040000, 0},
> +	/* DDR (Data) */
> +	{ 0x80000000, 0x80000000, 0x60000000, 0 },
>  };
>  
>  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
> @@ -236,6 +256,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
>  	.method		= IMX_RPROC_NONE,
>  };
>  
> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
> +	.att		= imx_rproc_att_imx8qxp,
> +	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> +	.method		= IMX_RPROC_SCU_API,
> +};
> +
>  static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
>  	.att		= imx_rproc_att_imx7ulp,
>  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
> @@ -491,6 +517,11 @@ static int imx_rproc_attach(struct rproc *rproc)
>  	return 0;
>  }
>  
> +static int imx_rproc_detach(struct rproc *rproc)
> +{
> +	return 0;

Is it possible to detach the remote processor from the application core?  If not
please write a comment that says so.  And shouldn't this return some kind of
error so that users don't think the operation was carried out successfully?

I am out of time for today and as such will continue with this set tomorrow.

Thanks,
Mathieu

> +}
> +
>  static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>  {
>  	struct imx_rproc *priv = rproc->priv;
> @@ -525,6 +556,7 @@ imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *
>  static const struct rproc_ops imx_rproc_ops = {
>  	.prepare	= imx_rproc_prepare,
>  	.attach		= imx_rproc_attach,
> +	.detach		= imx_rproc_detach,
>  	.start		= imx_rproc_start,
>  	.stop		= imx_rproc_stop,
>  	.kick		= imx_rproc_kick,
> @@ -671,6 +703,22 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
>  	mbox_free_channel(priv->rx_ch);
>  }
>  
> +static int imx_rproc_partition_notify(struct notifier_block *nb,
> +				      unsigned long event, void *group)
> +{
> +	struct imx_rproc *priv = container_of(nb, struct imx_rproc, proc_nb);
> +
> +	/* Ignore other irqs */
> +	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
> +		return 0;
> +
> +	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
> +
> +	pr_info("Patition%d reset!\n", priv->rproc_pt);
> +
> +	return 0;
> +}
> +
>  static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  {
>  	struct regmap_config config = { .name = "imx-rproc" };
> @@ -680,6 +728,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  	struct arm_smccc_res res;
>  	int ret;
>  	u32 val;
> +	u8 pt;
>  
>  	switch (dcfg->method) {
>  	case IMX_RPROC_NONE:
> @@ -690,6 +739,52 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  		if (res.a0)
>  			priv->rproc->state = RPROC_DETACHED;
>  		return 0;
> +	case IMX_RPROC_SCU_API:
> +		ret = imx_scu_get_handle(&priv->ipc_handle);
> +		if (ret)
> +			return ret;
> +		ret = of_property_read_u32(dev->of_node, "rsrc-id", &priv->rsrc);
> +		if (ret) {
> +			dev_err(dev, "no rsrc-id\n");
> +			return ret;
> +		}
> +
> +		/*
> +		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
> +		 * and Linux could only do IPC with Mcore and nothing else.
> +		 */
> +		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
> +
> +			priv->has_clk = false;
> +			priv->rproc->self_recovery = true;
> +			priv->rproc->state = RPROC_DETACHED;
> +
> +			/* Get partition id and enable irq in SCFW */
> +			ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc, &pt);
> +			if (ret) {
> +				dev_err(dev, "not able to get resource owner\n");
> +				return ret;
> +			}
> +
> +			priv->rproc_pt = pt;
> +			priv->proc_nb.notifier_call = imx_rproc_partition_notify;
> +
> +			ret = imx_scu_irq_register_notifier(&priv->proc_nb);
> +			if (ret) {
> +				dev_warn(dev, "register scu notifier failed.\n");
> +				return ret;
> +			}
> +
> +			ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED,
> +						       BIT(priv->rproc_pt), true);
> +			if (ret) {
> +				imx_scu_irq_unregister_notifier(&priv->proc_nb);
> +				dev_warn(dev, "Enable irq failed.\n");
> +				return ret;
> +			}
> +		}
> +
> +		return 0;
>  	default:
>  		break;
>  	}
> @@ -847,6 +942,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
>  	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
>  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
>  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
> +	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
>  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
>  	{},
>  };
> -- 
> 2.25.1
> 


From henrik at grimler.se  Tue Jan 18 10:57:43 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Tue, 18 Jan 2022 19:57:43 +0100
Subject: [PATCH v3 0/3] Add initial support for exynos5420-chagall-wifi
Message-ID: <20220118185746.299832-1-henrik@grimler.se>

Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename Chagall WiFi
and is one of several tablets released in 2014 based on Exynos 5420.
This initial devicetree adds support for accessing device over USB or
UART, and allows using a rootfs in either the internal eMMC or an
external sdcard.  4 out of 8 CPUs are brought up when device boots,
which is the same as on the somewhat similar board
exynos5420-arndale-octa.

Patch 2 is necessary after a secure-firmware node is added, otherwise
device hangs during the CPU1BOOT secure monitor call. Without the
secure-firmware node we are not able to bring up any secondary CPUs.

Changes since v3:
=================

* Rename device specific regulators LDOx -> VDD_LDOx for consistency
* Make LDO32 vary with device and add on/off-in-suspend to a couple
  of more regulators, to match vendor kernel
* Fix mmc2 card-detect, with cd-gpios defined and pin config
  pin-pud=pin_pull_none sdcard insertion is detected and seen in dmesg
* Rename sd2-cd-pins -> mmc2-cd-pins

Changes since v2
================

Addressing Krzysztof's feedback:
* chagallwifi -> chagall-wifi and Chagall WiFi in messages and comments
* Re-write commit message for patch 3, use commit hash and ("subject"),
  move hint about bootloader issue to galaxy-tab-common.dtsi
* Fix s2mps11 regulator nodes, use &ldoXX_reg handle for device customisation
* Re-add usbdrd supplies (works after fixing regulator nodes)
* Remove unnecessary, duplicate, compatible in galaxy-tab-common.dtsi
* Remove extra clocks xxti and xusbxti
* Prefix key- to gpio-keys
* Add pinctrl pins to mmc_2. card-detect pin is different than for other
  Exynos 5420 devices, so define and use mmc2_cd node under pinctrl_0

Additional changes:
* Add/fix supplies of mmc_0 and mmc_2 (vmmc-supply for mmc0 is unknown)
* Sort mmc_X properties alphabetically
* Fix IRQ pin for s2mps11, it was wrong (gpx3-2 -> gpx3-0)
* Mark LDO31 as varying between devices as well, it differs between WiFi
  and LTE tablet versions
* Fix typo for LDO5 (regulato-name -> regulator-name)
* Remove regulator-ramp-delay from buck regulators, based on
  exynos5420-arndale-octa there should be no need to set it

Changes since v1
================

Fix mmc_0 and usbdrd in patch 3:
* Remove extra, non supported, options from mmc_0 node
* Do not set usbdrd supplies. Usb networking does not work with them
  specified, but it works fine with dummy regulators


Henrik Grimler (3):
  dt-bindings: arm: samsung: document Chagall WiFi board binding
  ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
  ARM: dts: Add support for Samsung Chagall WiFi

 .../bindings/arm/samsung/samsung-boards.yaml  |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  75 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 692 ++++++++++++++++++
 arch/arm/mach-exynos/firmware.c               |   4 +-
 5 files changed, 772 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

-- 
2.34.1



From henrik at grimler.se  Tue Jan 18 10:57:44 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Tue, 18 Jan 2022 19:57:44 +0100
Subject: [PATCH v4 1/3] dt-bindings: arm: samsung: document Chagall WiFi board
 binding
In-Reply-To: <20220118185746.299832-1-henrik@grimler.se>
References: <20220118185746.299832-1-henrik@grimler.se>
Message-ID: <20220118185746.299832-2-henrik@grimler.se>

Add binding for Samsung Galaxy Tab S 10.5", based on Exynos 5420 with
codename chagall-wifi. It was released in 2014 and has several siblings
with similar hardware.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index 052cd94113d4..a2a8bf44fe9b 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -140,6 +140,7 @@ properties:
         items:
           - enum:
               - insignal,arndale-octa           # Insignal Arndale Octa
+              - samsung,chagall-wifi            # Samsung SM-T800
               - samsung,smdk5420                # Samsung SMDK5420 eval
           - const: samsung,exynos5420
           - const: samsung,exynos5
-- 
2.34.1



From henrik at grimler.se  Tue Jan 18 10:57:45 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Tue, 18 Jan 2022 19:57:45 +0100
Subject: [PATCH v4 2/3] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
In-Reply-To: <20220118185746.299832-1-henrik@grimler.se>
References: <20220118185746.299832-1-henrik@grimler.se>
Message-ID: <20220118185746.299832-3-henrik@grimler.se>

On Exynos5 the call is simply ignored by most variants of the
trustzone firmware.  However, on some devices it instead causes the
device to hang, so let's avoid the call for the SoCs where it should
not be needed.

To see that the call is ignored, we can look into sboot/tzsw.  On most
of the Exynos{4,5} devices the part of sboot/tzsw that seem to handle
the secure monitor calls is quite easy to recognise, the SMC number is
compared to known ones, and if equal it branches to the relevant
function.  In assembly this looks something like:

;-- handle_smc:
0x00000514      650070e3       cmn r0, 0x65
0x00000518      0a00000a       beq loc.smc_cmd_reg
0x0000051c      010070e3       cmn r0, 1
0x00000520      6c00000a       beq loc.smc_cmd_init
0x00000524      020070e3       cmn r0, 2
0x00000528      6b00000a       beq loc.smc_cmd_info
0x0000052c      030070e3       cmn r0, 3
0x00000530      6e00000a       beq loc.smc_cmd_sleep
0x00000534      060070e3       cmn r0, 6
0x00000538      ae00000a       beq loc.smc_cmd_save_state
0x0000053c      070070e3       cmn r0, 7
0x00000540      b400000a       beq loc.smc_cmd_standby
0x00000544      2b01001a       bne loc.smc_return_minus1

where above example is from exynos5420-arndale-octa.  As can be seen
the case where r0 is 4 (i.e. SMC_CMD_CPU1BOOT) is not handled.  The
annotations are taken from github.com/hsnaves/exynos5410-firmware,
where a large part of the exynos5410 trustzone firmware has been
reverse-engineered.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
Tested-by: Marek Szyprowski <m.szyprowski at samsung.com>
---
Sent previously as RFC
---
 arch/arm/mach-exynos/firmware.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 2eaf2dbb8e81..2da5b60b59e2 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -60,8 +60,10 @@ static int exynos_cpu_boot(int cpu)
 	/*
 	 * Exynos3250 doesn't need to send smc command for secondary CPU boot
 	 * because Exynos3250 removes WFE in secure mode.
+	 *
+	 * On Exynos5 devices the call is ignored by trustzone firmware.
 	 */
-	if (soc_is_exynos3250())
+	if (!soc_is_exynos4210() && !soc_is_exynos4412())
 		return 0;
 
 	/*
-- 
2.34.1



From henrik at grimler.se  Tue Jan 18 10:57:46 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Tue, 18 Jan 2022 19:57:46 +0100
Subject: [PATCH v4 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <20220118185746.299832-1-henrik@grimler.se>
References: <20220118185746.299832-1-henrik@grimler.se>
Message-ID: <20220118185746.299832-4-henrik@grimler.se>

Chagall WiFi, with product name Samsung Galaxy Tab S 10.5", is based
on Exynos 5420.  This device is one of several tablet models released
in 2014 based on Exynos 5420.

The device tree added here contains support for:

- UART
- eMMC
- SD card
- USB

CCI has been disabled in the hardware, enabling it would require
(de-)soldering a resistor on the board.  Trying to boot with it
enabled in kernel makes the device hang when CCI is probed.
Exynos5420-arndale-octa also has had CCI disabled due to issues, see
commit 25217fef3551 ("ARM: dts: disable CCI on exynos5420 based
arndale-octa").

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  75 ++
 .../dts/exynos5420-galaxy-tab-common.dtsi     | 692 ++++++++++++++++++
 3 files changed, 768 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
 create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 0de64f237cd8..088fcedb3212 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-arndale-octa.dtb \
 	exynos5420-peach-pit.dtb \
 	exynos5420-smdk5420.dtb \
+	exynos5420-chagall-wifi.dtb \
 	exynos5422-odroidhc1.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
diff --git a/arch/arm/boot/dts/exynos5420-chagall-wifi.dts b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
new file mode 100644
index 000000000000..1319344a2c74
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Chagall WiFi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+	model = "Samsung Chagall WiFi based on Exynos5420";
+	compatible = "samsung,chagall-wifi", "samsung,exynos5420", \
+		     "samsung,exynos5";
+};
+
+&ldo15_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO15";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&ldo17_reg {
+	regulator-name = "VDD_IRLED_3V3";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3350000>;
+	regulator-always-on;
+	regulator-boot-on;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo28_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO28";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&ldo29_reg {
+	regulator-name = "VDD_TCON_1V8";
+	regulator-min-microvolt = <1900000>;
+	regulator-max-microvolt = <1900000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo31_reg {
+	regulator-name = "VDD_GRIP_1V8";
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+	regulator-always-on;
+	regulator-boot-on;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo32_reg {
+	regulator-name = "VDD_TSP_1V8";
+	regulator-min-microvolt = <1900000>;
+	regulator-max-microvolt = <1900000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
new file mode 100644
index 000000000000..e4ed0fd153f4
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
@@ -0,0 +1,692 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Base DT for Samsung's family of tablets based on Exynos5420.
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420.dtsi"
+#include "exynos5420-cpus.dtsi"
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/samsung,s2mps11.h>
+
+/ {
+	chassis-type = "tablet";
+
+	/*
+	 * To successfully boot the mainline kernel with the stock
+	 * bootloader (SBOOT), the tlb needs to be flushed after the
+	 * page table pointer has been updated in __common_mmu_cache_on.
+	 * The same hack is also needed to boot exynos4412-i9300 with
+	 * stock bootloader, and probably other Samsung devices of
+	 * similar age.  See
+	 * https://lore.kernel.org/all/1355276466-18295-1-git-send-email-arve at android.com
+	 * for more details.
+	 */
+
+	chosen {
+		stdout-path = "serial2:115200n8";
+	};
+
+	memory at 20000000 {
+		device_type = "memory";
+		reg = <0x20000000 0xc0000000>;
+	};
+
+	firmware at 2073000 {
+		compatible = "samsung,secure-firmware";
+		reg = <0x02073000 0x1000>;
+	};
+
+	fixed-rate-clocks {
+		oscclk {
+			compatible = "samsung,exynos5420-oscclk";
+			clock-frequency = <24000000>;
+		};
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+
+		key-power {
+			debounce-interval = <10>;
+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
+			label = "Power";
+			linux,code = <KEY_POWER>;
+			wakeup-source;
+		};
+
+		key-home {
+			debounce-interval = <10>;
+			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
+			label = "Home";
+			linux,code = <KEY_HOME>;
+			wakeup-source;
+		};
+
+		key-volume-up {
+			debounce-interval = <10>;
+			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+		};
+
+		key-volume-down {
+			debounce-interval = <10>;
+			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
+			label = "Volume Down";
+			linux,code = <KEY_VOLUMEDOWN>;
+		};
+	};
+};
+
+&cci {
+	/* CCI is disabled in hardware */
+	status = "disabled";
+};
+
+&cpu0 {
+	cpu-supply = <&buck2_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&buck6_reg>;
+};
+
+&gpu {
+	status = "okay";
+	mali-supply = <&buck4_reg>;
+};
+
+&hsi2c_7 {
+	status = "okay";
+
+	pmic at 66 {
+		compatible = "samsung,s2mps11-pmic";
+		reg = <0x66>;
+
+		interrupt-parent = <&gpx3>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&s2mps11_irq>;
+
+		s2mps11_osc: clocks {
+			compatible = "samsung,s2mps11-clk";
+			#clock-cells = <1>;
+			clock-output-names = "s2mps11_ap", "s2mps11_cp",
+					     "s2mps11_bt";
+		};
+
+		regulators {
+			buck1_reg: BUCK1 {
+				regulator-name = "VDD_MIF_1V1";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1300000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck2_reg: BUCK2 {
+				regulator-name = "VDD_ARM_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck3_reg: BUCK3 {
+				regulator-name = "VDD_INT_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck4_reg: BUCK4 {
+				regulator-name = "VDD_G3D_1V0";
+				regulator-min-microvolt = <700000>;
+				regulator-max-microvolt = <1400000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck5_reg: BUCK5 {
+				regulator-name = "VDD_MEM_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+
+			};
+
+			buck6_reg: BUCK6 {
+				regulator-name = "VDD_KFC_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			buck7_reg: BUCK7 {
+				regulator-name = "VIN_LLDO_1V4";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-always-on;
+			};
+
+			buck8_reg: BUCK8 {
+				regulator-name = "VIN_MLDO_2V0";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <2100000>;
+				regulator-always-on;
+			};
+
+			buck9_reg: BUCK9 {
+				regulator-name = "VIN_HLDO_3V5";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3500000>;
+				regulator-always-on;
+			};
+
+			buck10_reg: BUCK10 {
+				regulator-name = "VDD_CAM_ISP_1V0";
+				regulator-min-microvolt = <750000>;
+				regulator-max-microvolt = <3550000>;
+			};
+
+			ldo1_reg: LDO1 {
+				regulator-name = "VDD_ALIVE_1.0V";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+			};
+
+			ldo2_reg: LDO2 {
+				regulator-name = "VDD_APIO_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo3_reg: LDO3 {
+				regulator-name = "VDD_APIO_MMC01_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo4_reg: LDO4 {
+				regulator-name = "VDD_ADC_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo5_reg: LDO5 {
+				/* Unused */
+				regulator-name = "VDD_LDO5";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo6_reg: LDO6 {
+				regulator-name = "VDD_MIPI_1V0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo7_reg: LDO7 {
+				regulator-name = "VDD_MIPI_PLL_ABB1_18V";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo8_reg: LDO8 {
+				/* Unused */
+				regulator-name = "VDD_LDO8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+			ldo9_reg: LDO9 {
+				regulator-name = "VDD_UOTG_3V0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo10_reg: LDO10 {
+				regulator-name = "VDDQ_PRE_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo11_reg: LDO11 {
+				regulator-name = "VDD_HSIC_1V0";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo12_reg: LDO12 {
+				regulator-name = "VDD_HSIC_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo13_reg: LDO13 {
+				regulator-name = "VDD_APIO_MMC2_2V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo14_reg: LDO14 {
+				regulator-name = "VDD_MOTOR_3V0";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3000000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo15_reg: LDO15 {
+				regulator-name = "VDD_LDO15";
+				/*
+				 * LDO15 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo16_reg: LDO16 {
+				regulator-name = "VDD_AP_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo17_reg: LDO17 {
+				regulator-name = "VDD_LDO17";
+				/*
+				 * LDO17 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo18_reg: LDO18 {
+				/* Unused */
+				regulator-name = "VDD_LDO18";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+			};
+
+
+			ldo19_reg: LDO19 {
+				regulator-name = "VDD_VTF_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo20_reg: LDO20 {
+				regulator-name = "VDD_CAM1_CAM_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo21_reg: LDO21 {
+				regulator-name = "VDD_CAM_IO_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo22_reg: LDO22 {
+				regulator-name = "VDD_CAM0_S_CORE_1V1";
+				regulator-min-microvolt = <1050000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo23_reg: LDO23 {
+				regulator-name = "VDD_MIFS_1V1";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1100000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo24_reg: LDO24 {
+				regulator-name = "VDD_TSP_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo25_reg: LDO25 {
+				/* Unused */
+				regulator-name = "VDD_LDO25";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo26_reg: LDO26 {
+				regulator-name = "VDD_CAM0_AF_2V8";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo27_reg: LDO27 {
+				regulator-name = "VDD_G3DS_1V0";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <1000000>;
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			ldo28_reg: LDO28 {
+				regulator-name = "VDD_LDO28";
+				/*
+				 * LDO28 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo29_reg: LDO29 {
+				regulator-name = "VDD_LDO29";
+				/*
+				 * LDO29 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo30_reg: LDO30 {
+				regulator-name = "VDD_TOUCH_1V8";
+				regulator-min-microvolt = <1900000>;
+				regulator-max-microvolt = <1900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo31_reg: LDO31 {
+				regulator-name = "VDD_LDO31";
+				/*
+				 * LDO31 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo32_reg: LDO32 {
+				regulator-name = "VDD_LDO32";
+				/*
+				 * LDO32 varies between devices and is
+				 * specified in the device dts
+				 */
+			};
+
+			ldo33_reg: LDO33 {
+				regulator-name = "VDD_MHL_1V8";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo34_reg: LDO34 {
+				regulator-name = "VDD_MHL_3V3";
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo35_reg: LDO35 {
+				regulator-name = "VDD_SIL_1V2";
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <1200000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			ldo36_reg: LDO36 {
+				/* Unused */
+				regulator-name = "VDD_LDO36";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo37_reg: LDO37 {
+				/* Unused */
+				regulator-name = "VDD_LDO37";
+				regulator-min-microvolt = <800000>;
+				regulator-max-microvolt = <3950000>;
+			};
+
+			ldo38_reg: LDO38 {
+				regulator-name = "VDD_KEY_LED_3V3";
+				regulator-min-microvolt = <2500000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&mixer {
+	status = "okay";
+};
+
+/* Internal storage */
+&mmc_0 {
+	status = "okay";
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	card-detect-delay = <200>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
+	pinctrl-names = "default";
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	vqmmc-supply = <&ldo3_reg>;
+};
+
+/* External sdcard */
+&mmc_2 {
+	status = "okay";
+	bus-width = <4>;
+	cap-sd-highspeed;
+	card-detect-delay = <200>;
+	cd-gpios = <&gpx2 4 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
+	pinctrl-names = "default";
+	samsung,dw-mshc-ciu-div = <3>;
+	samsung,dw-mshc-ddr-timing = <0 2>;
+	samsung,dw-mshc-sdr-timing = <0 4>;
+	sd-uhs-sdr50;
+	vmmc-supply = <&ldo19_reg>;
+	vqmmc-supply = <&ldo13_reg>;
+};
+
+&pinctrl_0 {
+	mmc2_cd: mmc2-cd-pins {
+		samsung,pins = "gpx2-4";
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+	};
+
+	s2mps11_irq: s2mps11-irq-pins {
+		samsung,pins = "gpx3-0";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
+	};
+};
+
+&rtc {
+	status = "okay";
+	clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
+	clock-names = "rtc", "rtc_src";
+};
+
+&tmu_cpu0 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu1 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu2 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_cpu3 {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&tmu_gpu {
+	vtmu-supply = <&ldo10_reg>;
+};
+
+&usbdrd_dwc3_0 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd_dwc3_1 {
+	dr_mode = "peripheral";
+};
+
+&usbdrd3_0 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
+
+&usbdrd3_1 {
+	vdd33-supply = <&ldo9_reg>;
+	vdd10-supply = <&ldo11_reg>;
+};
-- 
2.34.1



From yury.norov at gmail.com  Tue Jan 18 11:04:00 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 18 Jan 2022 11:04:00 -0800
Subject: [RFC PATCH] arm64: don't vmap() invalid page
In-Reply-To: <YecNTJNIfAd/D9GG@casper.infradead.org>
References: <20220118185354.464517-1-yury.norov@gmail.com>
 <YecNTJNIfAd/D9GG@casper.infradead.org>
Message-ID: <CAAH8bW-L+goex5Rn1MVpAjeDKqXF8MG3Ou4h65n7ugStHQEJbg@mail.gmail.com>

On Tue, Jan 18, 2022 at 10:56 AM Matthew Wilcox <willy at infradead.org> wrote:
>
> On Tue, Jan 18, 2022 at 10:53:54AM -0800, Yury Norov wrote:
> > vmap() takes struct page *pages as one of arguments, and user may provide
> > an invalid pointer, which would lead to DABT at address translation later.
> > Currently, kernel checks the pages against NULL. In my case, however, the
> > address was not NULL, and was big enough so that the hardware generated
> > Address Size Abort.
> >
> > Interestingly, this abort happens even if copy_from_kernel_nofault() is used,
> > which is quite inconvenient for debugging purposes.
> >
> > This patch adds an arch_vmap_page_valid() helper into vmap() path, so that
> > architectures may add arch-specific checks of the pointer passed into vmap.
> >
> > For arm64, if the page passed to vmap() corresponds to a physical address
> > greater than maximum possible value as described in TCR_EL1.IPS register, the
> > following table walk would generate Address Size Abort. Instead of creating
> > the invalid mapping, kernel will return ERANGE in such situation.
>
> This seems like a very elaborate way of spelling:
>
>         pfn_valid(page_to_pfn(page));
>
> which doesn't require any architecture hook.  No?

Looks like yes. I'll resend later today if there are no other
comments. Thank you
for the hint.


From jim.cromie at gmail.com  Tue Jan 18 11:18:33 2022
From: jim.cromie at gmail.com (jim.cromie at gmail.com)
Date: Tue, 18 Jan 2022 12:18:33 -0700
Subject: [PATCH v11 03/19] dyndbg: add write-to-tracefs code
In-Reply-To: <20220114114654.GA23983@axis.com>
References: <20220107052942.1349447-1-jim.cromie@gmail.com>
 <20220107052942.1349447-4-jim.cromie@gmail.com>
 <20220114114654.GA23983@axis.com>
Message-ID: <CAJfuBxxKQK+X-5LW=ysPU-4mP25BnuCNxvo4xg-SgPwQsr7kXw@mail.gmail.com>

On Fri, Jan 14, 2022 at 4:46 AM Vincent Whitchurch
<vincent.whitchurch at axis.com> wrote:
>
> On Fri, Jan 07, 2022 at 06:29:26AM +0100, Jim Cromie wrote:
> >

> > Enabling debug-to-tracefs is 2 steps:
> >
> >   # event enable
> >   echo 1 > /sys/kernel/tracing/events/dyndbg/enable
> >   # callsite enable
> >   echo module foo +T > /proc/dynamic_debug/control
> >
> > This patch,~1,~2 are based upon:
> >   https://lore.kernel.org/lkml/20200825153338.17061-1-vincent.whitchurch at axis.com/
> >
> > .. with simplification of temporarily reusing trace_console() rather
> > than adding a new printk:dyndbg event.  Soon, add 2 new events
> > capturing the pr_debug & dev_dbg() args.
>
> The example above does not match the code in this patch since the
> dyndbg:* events are only added in a later patch.  Perhaps you could
> reorder this patch stack so that you don't use trace_console() in this
> patch just to replace it with the new events in the next patch?
>

good catch, thanks.
Ive just dropped the example, it seemed the simplest fix.
It seemed proper to commit your code as pristine as practical,
so that subsequent mistakes receive the blame.

and Ive fixed the spurious whitespace change you noted.


From jeanmichel.hautbois at ideasonboard.com  Tue Jan 18 11:45:04 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Tue, 18 Jan 2022 20:45:04 +0100
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <20211231115109.94626-1-uwe@kleine-koenig.org>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
Message-ID: <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>

Hi Uwe,

Thanks for the patch !

On 31/12/2021 12:51, Uwe Kleine-K?nig wrote:
> The cm4-io board comes with an PCF85063. Add it to the device tree to make
> it usable. The i2c0 bus can use two different pinmux settings to use
> different pins. To keep the bus appearing on the usual pin pair (gpio0 +
> gpio1) use a pinctrl-muxed setting as the vendor dts does.
> 
> Note that if you modified the dts before to add devices to the i2c bus
> appearing on pins gpio0 + gpio1 (either directly in the dts or using an
> overlay), you have to put these into the i2c at 0 node introduced here now.
> 
> Reviewed-by: Maxime Ripard <maxime at cerno.tech>
> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
> ---
> Hello,
> 
> changes since v2 (20211216212948.nrfmm4jpbhoknfr5 at pengutronix.de):
> 
>   - add Maxime's R-b tag
>   - change the commit log wording to say vendor dts instead of upstream
>     dts
>   - Add a paragraph to the commit log about breakage this commits
>     introduces.
> 
> Best regards
> Uwe
> 
>   arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 35 ++++++++++++++++++++++++
>   1 file changed, 35 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> index 19600b629be5..5ddad146b541 100644
> --- a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> +++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> @@ -18,6 +18,41 @@ led-pwr {
>   			linux,default-trigger = "default-on";
>   		};
>   	};
> +
> +	i2c0mux {
> +		compatible = "i2c-mux-pinctrl";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		i2c-parent = <&i2c0>;
> +
> +		pinctrl-names = "i2c0", "i2c0-vc";
> +		pinctrl-0 = <&i2c0_gpio0>;
> +		pinctrl-1 = <&i2c0_gpio44>;
> +
> +		i2c at 0 {
> +			reg = <0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c at 1 {
> +			reg = <1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			rtc at 51 {
> +				/* Attention: An alarm resets the machine */
> +				compatible = "nxp,pcf85063";
> +				reg = <0x51>;
> +			};
> +		};
> +	};
> +};

This is also needed for camera and display support.
I tested it successfully with imx219 + unicam on mainline.

> +
> +&i2c0 {
> +	/delete-property/ pinctrl-names;
> +	/delete-property/ pinctrl-0;
>   };
>   
>   &ddc0 {
> 
> base-commit: fc74e0a40e4f9fd0468e34045b0c45bba11dcbb2
> 


From Thinh.Nguyen at synopsys.com  Tue Jan 18 11:46:19 2022
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Tue, 18 Jan 2022 19:46:19 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <87iluifxy1.fsf@tarshish>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish>
Message-ID: <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>

Hi Sean,

Baruch Siach wrote:
> Hi Sean, Thinh,
> 
> On Fri, Jan 14 2022, Sean Anderson wrote:
>> This is a rework of patches 3-5 of [1]. It attempts to correctly program
>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>> we no longer need a special property duplicating this configuration,
>> snps,ref-clock-period-ns is deprecated.
>>
>> Please test this! Patches 3/4 in this series have the effect of
>> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>> the "ref" clock. I have build tested, but not much else.
>>
>> [1] https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$ 
> 
> Thinh, you suggested the dedicated DT property for the reference clock:
> 
>   https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$ 
> 
> Can you comment on this series?
> 

Unless there's a good way to pass this information for PCI devices, my
opinion hasn't changed. (Btw, I don't think creating a dummy clock
provider and its dummy ops is a good solution as seems to complicate and
bloat the PCI glue drivers).

Please help come up with a solution before deprecating the ref clock
property.

Thanks,
Thinh

> 
>> Sean Anderson (6):
>>   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>>   usb: dwc3: Get clocks individually
>>   usb: dwc3: Calculate REFCLKPER based on reference clock
>>   usb: dwc3: Handle fractional reference clocks
>>   arm64: dts: zynqmp: Move USB clocks to dwc3 node
>>   arm64: dts: ipq6018: Use reference clock to set dwc3 period
>>
>>  .../devicetree/bindings/usb/snps,dwc3.yaml    |  7 +-
>>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |  3 +-
>>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +-
>>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |  4 +-
>>  drivers/usb/dwc3/core.c                       | 98 ++++++++++++++++---
>>  drivers/usb/dwc3/core.h                       |  6 +-
>>  6 files changed, 98 insertions(+), 24 deletions(-)
> 
> 


From sean.anderson at seco.com  Tue Jan 18 11:53:34 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 18 Jan 2022 14:53:34 -0500
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish> <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
Message-ID: <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>

Hi Thinh,

On 1/18/22 2:46 PM, Thinh Nguyen wrote:
> Hi Sean,
>
> Baruch Siach wrote:
>> Hi Sean, Thinh,
>>
>> On Fri, Jan 14 2022, Sean Anderson wrote:
>>> This is a rework of patches 3-5 of [1]. It attempts to correctly program
>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>>> we no longer need a special property duplicating this configuration,
>>> snps,ref-clock-period-ns is deprecated.
>>>
>>> Please test this! Patches 3/4 in this series have the effect of
>>> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>>> the "ref" clock. I have build tested, but not much else.
>>>
>>> [1] https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
>>
>> Thinh, you suggested the dedicated DT property for the reference clock:
>>
>>   https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
>>
>> Can you comment on this series?
>>
>
> Unless there's a good way to pass this information for PCI devices, my
> opinion hasn't changed. (Btw, I don't think creating a dummy clock
> provider and its dummy ops is a good solution as seems to complicate and
> bloat the PCI glue drivers).

Can you explain your situation a bit more? I'm not sure how you can
access a device tree property but not add a fixed-rate clock.

--Sean


From f.fainelli at gmail.com  Tue Jan 18 12:00:50 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 18 Jan 2022 12:00:50 -0800
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
Message-ID: <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>

On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
> Hi Uwe,
> 
> Thanks for the patch !
> 
> On 31/12/2021 12:51, Uwe Kleine-K?nig wrote:
>> The cm4-io board comes with an PCF85063. Add it to the device tree to
>> make
>> it usable. The i2c0 bus can use two different pinmux settings to use
>> different pins. To keep the bus appearing on the usual pin pair (gpio0 +
>> gpio1) use a pinctrl-muxed setting as the vendor dts does.
>>
>> Note that if you modified the dts before to add devices to the i2c bus
>> appearing on pins gpio0 + gpio1 (either directly in the dts or using an
>> overlay), you have to put these into the i2c at 0 node introduced here now.
>>
>> Reviewed-by: Maxime Ripard <maxime at cerno.tech>
>> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
>> ---
>> Hello,
>>
>> changes since v2 (20211216212948.nrfmm4jpbhoknfr5 at pengutronix.de):
>>
>> ? - add Maxime's R-b tag
>> ? - change the commit log wording to say vendor dts instead of upstream
>> ??? dts
>> ? - Add a paragraph to the commit log about breakage this commits
>> ??? introduces.
>>
>> Best regards
>> Uwe
>>
>> ? arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 35 ++++++++++++++++++++++++
>> ? 1 file changed, 35 insertions(+)
>>
>> diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>> b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>> index 19600b629be5..5ddad146b541 100644
>> --- a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>> +++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>> @@ -18,6 +18,41 @@ led-pwr {
>> ????????????? linux,default-trigger = "default-on";
>> ????????? };
>> ????? };
>> +
>> +??? i2c0mux {
>> +??????? compatible = "i2c-mux-pinctrl";
>> +??????? #address-cells = <1>;
>> +??????? #size-cells = <0>;
>> +
>> +??????? i2c-parent = <&i2c0>;
>> +
>> +??????? pinctrl-names = "i2c0", "i2c0-vc";
>> +??????? pinctrl-0 = <&i2c0_gpio0>;
>> +??????? pinctrl-1 = <&i2c0_gpio44>;
>> +
>> +??????? i2c at 0 {
>> +??????????? reg = <0>;
>> +??????????? #address-cells = <1>;
>> +??????????? #size-cells = <0>;
>> +??????? };
>> +
>> +??????? i2c at 1 {
>> +??????????? reg = <1>;
>> +??????????? #address-cells = <1>;
>> +??????????? #size-cells = <0>;
>> +
>> +??????????? rtc at 51 {
>> +??????????????? /* Attention: An alarm resets the machine */
>> +??????????????? compatible = "nxp,pcf85063";
>> +??????????????? reg = <0x51>;
>> +??????????? };
>> +??????? };
>> +??? };
>> +};
> 
> This is also needed for camera and display support.
> I tested it successfully with imx219 + unicam on mainline.

Thanks for testing, can you reply with a Tested-by tag so it could be
applied to the commit message when this gets picked up?
-- 
Florian


From Thinh.Nguyen at synopsys.com  Tue Jan 18 12:00:44 2022
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Tue, 18 Jan 2022 20:00:44 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish> <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
Message-ID: <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>

Sean Anderson wrote:
> Hi Thinh,
> 
> On 1/18/22 2:46 PM, Thinh Nguyen wrote:
>> Hi Sean,
>>
>> Baruch Siach wrote:
>>> Hi Sean, Thinh,
>>>
>>> On Fri, Jan 14 2022, Sean Anderson wrote:
>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly
>>>> program
>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
>>>> Since
>>>> we no longer need a special property duplicating this configuration,
>>>> snps,ref-clock-period-ns is deprecated.
>>>>
>>>> Please test this! Patches 3/4 in this series have the effect of
>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already
>>>> configure
>>>> the "ref" clock. I have build tested, but not much else.
>>>>
>>>> [1]
>>>> https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
>>>>
>>>
>>> Thinh, you suggested the dedicated DT property for the reference clock:
>>>
>>> ?
>>> https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
>>>
>>>
>>> Can you comment on this series?
>>>
>>
>> Unless there's a good way to pass this information for PCI devices, my
>> opinion hasn't changed. (Btw, I don't think creating a dummy clock
>> provider and its dummy ops is a good solution as seems to complicate and
>> bloat the PCI glue drivers).
> 
> Can you explain your situation a bit more? I'm not sure how you can
> access a device tree property but not add a fixed-rate clock.
> 
> --Sean

Currently for dwc3 pci devices, we have glue drivers that create a
platform_device with specific properties to pass to the dwc3 core
driver. Without a ref clock property, we would need another way to pass
this information to the core driver or another way for the dwc3 core
driver to check for specific pci device's properties and quirks.

BR,
Thinh

From jeanmichel.hautbois at ideasonboard.com  Tue Jan 18 12:02:12 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Tue, 18 Jan 2022 21:02:12 +0100
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
 <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
Message-ID: <051e93dc-0c9f-44a3-634e-6610833fd385@ideasonboard.com>

On 18/01/2022 21:00, Florian Fainelli wrote:
> On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
>> Hi Uwe,
>>
>> Thanks for the patch !
>>
>> On 31/12/2021 12:51, Uwe Kleine-K?nig wrote:
>>> The cm4-io board comes with an PCF85063. Add it to the device tree to
>>> make
>>> it usable. The i2c0 bus can use two different pinmux settings to use
>>> different pins. To keep the bus appearing on the usual pin pair (gpio0 +
>>> gpio1) use a pinctrl-muxed setting as the vendor dts does.
>>>
>>> Note that if you modified the dts before to add devices to the i2c bus
>>> appearing on pins gpio0 + gpio1 (either directly in the dts or using an
>>> overlay), you have to put these into the i2c at 0 node introduced here now.
>>>
>>> Reviewed-by: Maxime Ripard <maxime at cerno.tech>
>>> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
>>> ---
>>> Hello,
>>>
>>> changes since v2 (20211216212948.nrfmm4jpbhoknfr5 at pengutronix.de):
>>>
>>>  ? - add Maxime's R-b tag
>>>  ? - change the commit log wording to say vendor dts instead of upstream
>>>  ??? dts
>>>  ? - Add a paragraph to the commit log about breakage this commits
>>>  ??? introduces.
>>>
>>> Best regards
>>> Uwe
>>>
>>>  ? arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 35 ++++++++++++++++++++++++
>>>  ? 1 file changed, 35 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>>> b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>>> index 19600b629be5..5ddad146b541 100644
>>> --- a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>>> +++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
>>> @@ -18,6 +18,41 @@ led-pwr {
>>>  ????????????? linux,default-trigger = "default-on";
>>>  ????????? };
>>>  ????? };
>>> +
>>> +??? i2c0mux {
>>> +??????? compatible = "i2c-mux-pinctrl";
>>> +??????? #address-cells = <1>;
>>> +??????? #size-cells = <0>;
>>> +
>>> +??????? i2c-parent = <&i2c0>;
>>> +
>>> +??????? pinctrl-names = "i2c0", "i2c0-vc";
>>> +??????? pinctrl-0 = <&i2c0_gpio0>;
>>> +??????? pinctrl-1 = <&i2c0_gpio44>;
>>> +
>>> +??????? i2c at 0 {
>>> +??????????? reg = <0>;
>>> +??????????? #address-cells = <1>;
>>> +??????????? #size-cells = <0>;
>>> +??????? };
>>> +
>>> +??????? i2c at 1 {
>>> +??????????? reg = <1>;
>>> +??????????? #address-cells = <1>;
>>> +??????????? #size-cells = <0>;
>>> +
>>> +??????????? rtc at 51 {
>>> +??????????????? /* Attention: An alarm resets the machine */
>>> +??????????????? compatible = "nxp,pcf85063";
>>> +??????????????? reg = <0x51>;
>>> +??????????? };
>>> +??????? };
>>> +??? };
>>> +};
>>
>> This is also needed for camera and display support.
>> I tested it successfully with imx219 + unicam on mainline.
> 
> Thanks for testing, can you reply with a Tested-by tag so it could be
> applied to the commit message when this gets picked up?
> 

Oh, missed this, sorry:
Tested-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>


From briannorris at chromium.org  Tue Jan 18 12:17:55 2022
From: briannorris at chromium.org (Brian Norris)
Date: Tue, 18 Jan 2022 12:17:55 -0800
Subject: [PATCH v2 3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
In-Reply-To: <CAGXv+5HC00YU6ARtGDahxWLqivvUCowh7wDq5H5OzoGO9htB+g@mail.gmail.com>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>
 <CAGXv+5HC00YU6ARtGDahxWLqivvUCowh7wDq5H5OzoGO9htB+g@mail.gmail.com>
Message-ID: <YecgcwXrQNzCesMN@google.com>

Hi Chen-Yu,

On Mon, Jan 17, 2022 at 05:01:52PM +0800, Chen-Yu Tsai wrote:
> On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
> >
> > Now that the cdn-dp driver supports plug-change callbacks, let's wire it
> > up.
> >
> > Signed-off-by: Brian Norris <briannorris at chromium.org>
> > ---
> >
> > (no changes since v1)
> >
> >  sound/soc/rockchip/rk3399_gru_sound.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
> > index e2d52d8d0ff9..eeef3ed70037 100644
> > --- a/sound/soc/rockchip/rk3399_gru_sound.c
> > +++ b/sound/soc/rockchip/rk3399_gru_sound.c
> > @@ -164,6 +164,25 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
> >         return 0;
> >  }
> >
> > +static struct snd_soc_jack cdn_dp_card_jack;
> > +
> > +static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
> > +{
> > +       struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
> 
> Using snd_soc_card_get_codec_dai() might be a better choice throughout this
> driver. While it will work for the cdn_dp case, because it is the first DAI
> in |rockchip_dais[]|, all the invocations for the other codecs are likely
> returning the wrong DAI.

I'll admit, I'm not very familiar with the ASoC object model, so you may
well be correct that there's something fishy in here. But I did trace
through the objects involved here, and we *are* getting the correct DAI
for both this case and the DA7219 case (preexisting code).

It looks like we actually have a new runtime for each of our static
dai_links:

devm_snd_soc_register_card()
  ...
  for_each_card_prelinks()
    snd_soc_add_pcm_runtime()

So I think this is valid to keep as-is.

> For this particular patch it works either way, so
> 
> Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>

Thanks for looking!

Brian


From marex at denx.de  Tue Jan 18 12:29:54 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 21:29:54 +0100
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and GATE
 clock
Message-ID: <20220118202958.1840431-1-marex@denx.de>

The ETHCK_K are modeled as composite clock of MUX and GATE, however per
STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
clock distribution for Ethernet, ETHPTPDIV divider is attached past the
ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
in use, ETHCKEN gate can be turned off. Current driver does not permit
that, fix it.

This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
ETHPTP_K remain functional as before.

[1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
    Figure 83. Peripheral clock distribution for Ethernet
    https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christophe Roullier <christophe.roullier at foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 drivers/clk/clk-stm32mp1.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 863274aa50e38..23a34ab459a3b 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -2008,7 +2008,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
 	KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
 	KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
 	KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
-	KCLK(ETHCK_K, "ethck_k", eth_src, 0, G_ETHCK, M_ETHCK),
 
 	/* Particulary Kernel Clocks (no mux or no gate) */
 	MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
@@ -2017,11 +2016,16 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
 	MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
 	MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
 
-	COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE |
+	COMPOSITE(NO_ID, "ck_ker_eth", eth_src, CLK_OPS_PARENT_ENABLE |
 		  CLK_SET_RATE_NO_REPARENT,
 		  _NO_GATE,
 		  _MMUX(M_ETHCK),
-		  _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
+		  _NO_DIV),
+
+	MGATE_MP1(ETHCK_K, "ethck_k", "ck_ker_eth", 0, G_ETHCK),
+
+	DIV(ETHPTP_K, "ethptp_k", "ck_ker_eth", CLK_OPS_PARENT_ENABLE |
+	    CLK_SET_RATE_NO_REPARENT, RCC_ETHCKSELR, 4, 4, 0),
 
 	/* RTC clock */
 	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE,
-- 
2.34.1



From marex at denx.de  Tue Jan 18 12:29:55 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 21:29:55 +0100
Subject: [PATCH 2/5] clk: stm32mp1: Add parent_data to ETHRX clock
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220118202958.1840431-2-marex@denx.de>

Pass parent_data to ETHRX clock with new fw_name = "ETH_RX_CLK/ETH_REF_CLK".
By default, this change has no impact on the operation of the clock driver.
However, due to the fw_name, it permits DT to override ETHRX clock parent,
which might be needed in case the ETHRX clock are supplied by external clock
source.

Example of MCO2 supplying clock to ETH_RX_CLK via external pad-to-pad wire:
&rcc {
         clocks = <&rcc CK_MCO2>;
         clock-names = "ETH_RX_CLK/ETH_REF_CLK";
};

Note that while this patch permits to implement this rare usecase, the issue
with ethernet RX and TX input clock modeling on MP1 is far more complex and
requires more core plumbing.

[1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
    Figure 83. Peripheral clock distribution for Ethernet
    https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christophe Roullier <christophe.roullier at foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 drivers/clk/clk-stm32mp1.c | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 23a34ab459a3b..7ad2e6203baef 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -155,6 +155,10 @@ static const char * const eth_src[] = {
 	"pll4_p", "pll3_q"
 };
 
+const struct clk_parent_data ethrx_src[] = {
+	{ .name = "ethck_k", .fw_name = "ETH_RX_CLK/ETH_REF_CLK" },
+};
+
 static const char * const rng_src[] = {
 	"ck_csi", "pll4_r", "ck_lse", "ck_lsi"
 };
@@ -317,6 +321,7 @@ struct clock_config {
 	const char *name;
 	const char *parent_name;
 	const char * const *parent_names;
+	const struct clk_parent_data *parent_data;
 	int num_parents;
 	unsigned long flags;
 	void *cfg;
@@ -576,6 +581,7 @@ static struct clk_hw *
 clk_stm32_register_gate_ops(struct device *dev,
 			    const char *name,
 			    const char *parent_name,
+			    const struct clk_parent_data *parent_data,
 			    unsigned long flags,
 			    void __iomem *base,
 			    const struct stm32_gate_cfg *cfg,
@@ -586,7 +592,10 @@ clk_stm32_register_gate_ops(struct device *dev,
 	int ret;
 
 	init.name = name;
-	init.parent_names = &parent_name;
+	if (parent_name)
+		init.parent_names = &parent_name;
+	if (parent_data)
+		init.parent_data = parent_data;
 	init.num_parents = 1;
 	init.flags = flags;
 
@@ -611,6 +620,7 @@ clk_stm32_register_gate_ops(struct device *dev,
 static struct clk_hw *
 clk_stm32_register_composite(struct device *dev,
 			     const char *name, const char * const *parent_names,
+			     const struct clk_parent_data *parent_data,
 			     int num_parents, void __iomem *base,
 			     const struct stm32_composite_cfg *cfg,
 			     unsigned long flags, spinlock_t *lock)
@@ -1135,6 +1145,7 @@ _clk_stm32_register_gate(struct device *dev,
 	return clk_stm32_register_gate_ops(dev,
 				    cfg->name,
 				    cfg->parent_name,
+				    cfg->parent_data,
 				    cfg->flags,
 				    base,
 				    cfg->cfg,
@@ -1148,8 +1159,8 @@ _clk_stm32_register_composite(struct device *dev,
 			      const struct clock_config *cfg)
 {
 	return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
-					    cfg->num_parents, base, cfg->cfg,
-					    cfg->flags, lock);
+					    cfg->parent_data, cfg->num_parents,
+					    base, cfg->cfg, cfg->flags, lock);
 }
 
 #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
@@ -1258,6 +1269,16 @@ _clk_stm32_register_composite(struct device *dev,
 	.func		= _clk_stm32_register_gate,\
 }
 
+#define STM32_GATE_PDATA(_id, _name, _parent, _flags, _gate)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_data	= _parent,\
+	.flags		= _flags,\
+	.cfg		= (struct stm32_gate_cfg *) {_gate},\
+	.func		= _clk_stm32_register_gate,\
+}
+
 #define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _mgate, _ops)\
 	(&(struct stm32_gate_cfg) {\
 		&(struct gate_cfg) {\
@@ -1291,6 +1312,10 @@ _clk_stm32_register_composite(struct device *dev,
 	STM32_GATE(_id, _name, _parent, _flags,\
 		   _STM32_MGATE(_mgate))
 
+#define MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)\
+	STM32_GATE_PDATA(_id, _name, _parent, _flags,\
+		   _STM32_MGATE(_mgate))
+
 #define _STM32_DIV(_div_offset, _div_shift, _div_width,\
 		   _div_flags, _div_table, _ops)\
 	.div = &(struct stm32_div_cfg) {\
@@ -1354,6 +1379,9 @@ _clk_stm32_register_composite(struct device *dev,
 #define PCLK(_id, _name, _parent, _flags, _mgate)\
 	MGATE_MP1(_id, _name, _parent, _flags, _mgate)
 
+#define PCLK_PDATA(_id, _name, _parent, _flags, _mgate)\
+	MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)
+
 #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
 	     COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
 		       CLK_SET_RATE_NO_REPARENT | _flags,\
@@ -1951,7 +1979,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
 	PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
 	PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
 	PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
-	PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX),
+	PCLK_PDATA(ETHRX, "ethrx", ethrx_src, 0, G_ETHRX),
 	PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
 	PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
 	PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
-- 
2.34.1



From marex at denx.de  Tue Jan 18 12:29:56 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 21:29:56 +0100
Subject: [PATCH 3/5] ARM: dts: stm32: Add alternate pinmux for ethernet0 pins
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220118202958.1840431-3-marex@denx.de>

Add another mux option for ethernet0 pins, this is used on DHCOM when
the ethernet PHY 50 MHz clock is generated by the MCO2 on PG2 pin and
then fed back via PA1 pin.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christophe Roullier <christophe.roullier at foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 34 ++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 3b65130affec8..2cd2ac9beaf20 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -338,6 +338,40 @@ pins1 {
 		};
 	};
 
+	ethernet0_rmii_pins_b: rmii-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */
+				 <STM32_PINMUX('G', 14, AF11)>, /* ETH1_RMII_TXD1 */
+				 <STM32_PINMUX('B', 11, AF11)>, /* ETH1_RMII_TX_EN */
+				 <STM32_PINMUX('A', 1, AF11)>,  /* ETH1_RMII_REF_CLK */
+				 <STM32_PINMUX('A', 2, AF11)>,  /* ETH1_MDIO */
+				 <STM32_PINMUX('C', 1, AF11)>;  /* ETH1_MDC */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <2>;
+		};
+		pins2 {
+			pinmux = <STM32_PINMUX('C', 4, AF11)>,  /* ETH1_RMII_RXD0 */
+				 <STM32_PINMUX('C', 5, AF11)>,  /* ETH1_RMII_RXD1 */
+				 <STM32_PINMUX('A', 7, AF11)>;  /* ETH1_RMII_CRS_DV */
+			bias-disable;
+		};
+	};
+
+	ethernet0_rmii_sleep_pins_b: rmii-sleep-1 {
+		pins1 {
+			pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_RMII_TXD0 */
+				 <STM32_PINMUX('G', 14, ANALOG)>, /* ETH1_RMII_TXD1 */
+				 <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_RMII_TX_EN */
+				 <STM32_PINMUX('A', 2, ANALOG)>,  /* ETH1_MDIO */
+				 <STM32_PINMUX('C', 1, ANALOG)>,  /* ETH1_MDC */
+				 <STM32_PINMUX('C', 4, ANALOG)>,  /* ETH1_RMII_RXD0 */
+				 <STM32_PINMUX('C', 5, ANALOG)>,  /* ETH1_RMII_RXD1 */
+				 <STM32_PINMUX('A', 1, ANALOG)>,  /* ETH1_RMII_REF_CLK */
+				 <STM32_PINMUX('A', 7, ANALOG)>;  /* ETH1_RMII_CRS_DV */
+		};
+	};
+
 	fmc_pins_a: fmc-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
-- 
2.34.1



From marex at denx.de  Tue Jan 18 12:29:57 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 21:29:57 +0100
Subject: [PATCH 4/5] ARM: dts: stm32: Add alternate pinmux for mco2 pins
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220118202958.1840431-4-marex@denx.de>

Add pinmux option for MCO2 pin. This is used on DHCOM when the
ethernet PHY 50 MHz clock is generated by the MCO2 on PG2 pin.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christophe Roullier <christophe.roullier at foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 2cd2ac9beaf20..6da84e3f05ea3 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -882,6 +882,21 @@ pins {
 		};
 	};
 
+	mco2_pins_a: mco2-0 {
+		pins {
+			pinmux = <STM32_PINMUX('G', 2, AF1)>; /* MCO2 */
+			bias-disable;
+			drive-push-pull;
+			slew-rate = <2>;
+		};
+	};
+
+	mco2_sleep_pins_a: mco2-sleep-0 {
+		pins {
+			pinmux = <STM32_PINMUX('G', 2, ANALOG)>; /* MCO2 */
+		};
+	};
+
 	m_can1_pins_a: m-can1-0 {
 		pins1 {
 			pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
-- 
2.34.1



From marex at denx.de  Tue Jan 18 12:29:58 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 21:29:58 +0100
Subject: [PATCH 5/5] ARM: dts: stm32: Switch DWMAC RMII clock to MCO2 on DHCOM
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220118202958.1840431-5-marex@denx.de>

The DHCOM SoM has two options for supplying ETHRX clock to the DWMAC
block and PHY. Either (1) ETHCK_K generates 50 MHz clock on ETH_CLK
pad for the PHY and the same 50 MHz clock are fed back to ETHRX via
internal eth_clk_fb clock connection OR (2) ETH_CLK is not used at
all, MCO2 generates 50 MHz clock on MCO2 output pad for the PHY and
the same MCO2 clock are fed back into ETHRX via ETH_RX_CLK input pad
using external pad-to-pad connection.

Option (1) has two downsides. ETHCK_K is supplied directly from either
PLL3_Q or PLL4_P, hence the PLL output is limited to exactly 50 MHz and
since the same PLL output is also used to supply SDMMC blocks, the
performance of SD and eMMC access is affected. The second downside is
that using this option, the EMI of the SoM is higher.

Option (2) solves both of those problems, so implement it here. In this
case, the PLL4_P is no longer limited and can be operated faster, at
100 MHz, which improves SDMMC performance (read performance is improved
from ~41 MiB/s to ~57 MiB/s with dd if=/dev/mmcblk1 of=/dev/null bs=64M
count=1). The EMI interference also decreases.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Christophe Roullier <christophe.roullier at foss.st.com>
Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
Cc: Patrice Chotard <patrice.chotard at foss.st.com>
Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-arm-kernel at lists.infradead.org
---
 arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 22 ++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
index 8c41f819f7769..b091d9901e976 100644
--- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
+++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
@@ -116,15 +116,29 @@ &dts {
 	status = "okay";
 };
 
+&rcc {
+	/* Connect MCO2 output to ETH_RX_CLK input via pad-pad connection */
+	clocks = <&rcc CK_MCO2>;
+	clock-names = "ETH_RX_CLK/ETH_REF_CLK";
+
+	/*
+	 * Set PLL4P output to 100 MHz to supply SDMMC with faster clock,
+	 * set MCO2 output to 50 MHz to supply ETHRX clock with PLL4P/2,
+	 * so that MCO2 behaves as a divider for the ETHRX clock here.
+	 */
+	assigned-clocks = <&rcc CK_MCO2>, <&rcc PLL4_P>;
+	assigned-clock-parents = <&rcc PLL4_P>;
+	assigned-clock-rates = <50000000>, <100000000>;
+};
+
 &ethernet0 {
 	status = "okay";
-	pinctrl-0 = <&ethernet0_rmii_pins_a>;
-	pinctrl-1 = <&ethernet0_rmii_sleep_pins_a>;
+	pinctrl-0 = <&ethernet0_rmii_pins_b &mco2_pins_a>;
+	pinctrl-1 = <&ethernet0_rmii_sleep_pins_b &mco2_sleep_pins_a>;
 	pinctrl-names = "default", "sleep";
 	phy-mode = "rmii";
 	max-speed = <100>;
 	phy-handle = <&phy0>;
-	st,eth-ref-clk-sel;
 
 	mdio0 {
 		#address-cells = <1>;
@@ -136,7 +150,7 @@ phy0: ethernet-phy at 1 {
 			/* LAN8710Ai */
 			compatible = "ethernet-phy-id0007.c0f0",
 				     "ethernet-phy-ieee802.3-c22";
-			clocks = <&rcc ETHCK_K>;
+			clocks = <&rcc CK_MCO2>;
 			reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <500>;
 			reset-deassert-us = <500>;
-- 
2.34.1



From robert.hancock at calian.com  Tue Jan 18 12:39:24 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 20:39:24 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish>
 <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
 <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
Message-ID: <eb3ba4b54d09dbe413907adb86669096110bbd0d.camel@calian.com>

On Tue, 2022-01-18 at 20:00 +0000, Thinh Nguyen wrote:
> Sean Anderson wrote:
> > Hi Thinh,
> > 
> > On 1/18/22 2:46 PM, Thinh Nguyen wrote:
> > > Hi Sean,
> > > 
> > > Baruch Siach wrote:
> > > > Hi Sean, Thinh,
> > > > 
> > > > On Fri, Jan 14 2022, Sean Anderson wrote:
> > > > > This is a rework of patches 3-5 of [1]. It attempts to correctly
> > > > > program
> > > > > REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
> > > > > Since
> > > > > we no longer need a special property duplicating this configuration,
> > > > > snps,ref-clock-period-ns is deprecated.
> > > > > 
> > > > > Please test this! Patches 3/4 in this series have the effect of
> > > > > programming REFCLKPER and REFCLK_FLADJ on boards which already
> > > > > configure
> > > > > the "ref" clock. I have build tested, but not much else.
> > > > > 
> > > > > [1]
> > > > > https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
> > > > > 
> > > > 
> > > > Thinh, you suggested the dedicated DT property for the reference clock:
> > > > 
> > > >  
> > > > https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
> > > > 
> > > > 
> > > > Can you comment on this series?
> > > > 
> > > 
> > > Unless there's a good way to pass this information for PCI devices, my
> > > opinion hasn't changed. (Btw, I don't think creating a dummy clock
> > > provider and its dummy ops is a good solution as seems to complicate and
> > > bloat the PCI glue drivers).
> > 
> > Can you explain your situation a bit more? I'm not sure how you can
> > access a device tree property but not add a fixed-rate clock.
> > 
> > --Sean
> 
> Currently for dwc3 pci devices, we have glue drivers that create a
> platform_device with specific properties to pass to the dwc3 core
> driver. Without a ref clock property, we would need another way to pass
> this information to the core driver or another way for the dwc3 core
> driver to check for specific pci device's properties and quirks.

We've used the device tree to instantiate/configure devices inside of a PCI
device, though obviously that only works on DT-based platforms, and for
hardware that's part of the board itself, not an add-in card.

We've also used the MFD infrastructure to instantiate devices and device
properties inside a PCI device on x86, which can be used if the driver you are
instantiating uses the generic device property accessors and not the DT-
specific ones. That gets a bit dirty however - I don't think there's an easy
way to create properties that are references to other nodes, or more than a
single level deep heirarchy of nodes.

For a use case like you're describing, it sounds like it would be better to
abstract away some of the core DWC3 code from reading the settings from DT
directly, so that the PCI devices can instantiate it and set the configuration
however they want, without having to worry about creating fake properties for
the core to read. I think that pattern has been used with some other drivers
such as AHCI?

> 
> BR,
> Thinh
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From robert.hancock at calian.com  Tue Jan 18 12:45:31 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 20:45:31 +0000
Subject: [PATCH net v2 0/9] Xilinx axienet fixes
In-Reply-To: <20220112173700.873002-1-robert.hancock@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
Message-ID: <5a5b1c7d58b81b2a6ab738650964ea7a1c2cf99b.camel@calian.com>

On Wed, 2022-01-12 at 11:36 -0600, Robert Hancock wrote:
> Various fixes for the Xilinx AXI Ethernet driver.
> 
> Changed since v1:
> -corrected a Fixes tag to point to mainline commit
> -split up reset changes into 3 patches
> -added ratelimit on netdev_warn in TX busy case
> 
> Robert Hancock (9):
>   net: axienet: increase reset timeout
>   net: axienet: Wait for PhyRstCmplt after core reset
>   net: axienet: reset core on initialization prior to MDIO access
>   net: axienet: add missing memory barriers
>   net: axienet: limit minimum TX ring size
>   net: axienet: Fix TX ring slot available check
>   net: axienet: fix number of TX ring slots for available check
>   net: axienet: fix for TX busy handling
>   net: axienet: increase default TX ring size to 128
> 
>  .../net/ethernet/xilinx/xilinx_axienet_main.c | 135 +++++++++++-------
>  1 file changed, 84 insertions(+), 51 deletions(-)
> 

Hi all,

Any other comments/reviews on this patch set? It's marked as Changes Requested
in Patchwork, but I don't think I saw any discussions that ended up with any
changes being asked for?

-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From laurent.pinchart at ideasonboard.com  Tue Jan 18 12:47:53 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Tue, 18 Jan 2022 22:47:53 +0200
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
 <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
Message-ID: <YecnebByrBplFEsU@pendragon.ideasonboard.com>

Hi Florian,

On Tue, Jan 18, 2022 at 12:00:50PM -0800, Florian Fainelli wrote:
> On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
> > On 31/12/2021 12:51, Uwe Kleine-K?nig wrote:
> >> The cm4-io board comes with an PCF85063. Add it to the device tree to
> >> make
> >> it usable. The i2c0 bus can use two different pinmux settings to use
> >> different pins. To keep the bus appearing on the usual pin pair (gpio0 +
> >> gpio1) use a pinctrl-muxed setting as the vendor dts does.
> >>
> >> Note that if you modified the dts before to add devices to the i2c bus
> >> appearing on pins gpio0 + gpio1 (either directly in the dts or using an
> >> overlay), you have to put these into the i2c at 0 node introduced here now.
> >>
> >> Reviewed-by: Maxime Ripard <maxime at cerno.tech>
> >> Signed-off-by: Uwe Kleine-K?nig <uwe at kleine-koenig.org>
> >> ---
> >> Hello,
> >>
> >> changes since v2 (20211216212948.nrfmm4jpbhoknfr5 at pengutronix.de):
> >>
> >> ? - add Maxime's R-b tag
> >> ? - change the commit log wording to say vendor dts instead of upstream
> >> ??? dts
> >> ? - Add a paragraph to the commit log about breakage this commits
> >> ??? introduces.
> >>
> >> Best regards
> >> Uwe
> >>
> >> ? arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts | 35 ++++++++++++++++++++++++
> >> ? 1 file changed, 35 insertions(+)
> >>
> >> diff --git a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> >> b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> >> index 19600b629be5..5ddad146b541 100644
> >> --- a/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> >> +++ b/arch/arm/boot/dts/bcm2711-rpi-cm4-io.dts
> >> @@ -18,6 +18,41 @@ led-pwr {
> >> ????????????? linux,default-trigger = "default-on";
> >> ????????? };
> >> ????? };
> >> +
> >> +??? i2c0mux {
> >> +??????? compatible = "i2c-mux-pinctrl";
> >> +??????? #address-cells = <1>;
> >> +??????? #size-cells = <0>;
> >> +
> >> +??????? i2c-parent = <&i2c0>;
> >> +
> >> +??????? pinctrl-names = "i2c0", "i2c0-vc";
> >> +??????? pinctrl-0 = <&i2c0_gpio0>;
> >> +??????? pinctrl-1 = <&i2c0_gpio44>;
> >> +
> >> +??????? i2c at 0 {
> >> +??????????? reg = <0>;
> >> +??????????? #address-cells = <1>;
> >> +??????????? #size-cells = <0>;
> >> +??????? };
> >> +
> >> +??????? i2c at 1 {
> >> +??????????? reg = <1>;
> >> +??????????? #address-cells = <1>;
> >> +??????????? #size-cells = <0>;
> >> +
> >> +??????????? rtc at 51 {
> >> +??????????????? /* Attention: An alarm resets the machine */
> >> +??????????????? compatible = "nxp,pcf85063";
> >> +??????????????? reg = <0x51>;
> >> +??????????? };
> >> +??????? };
> >> +??? };
> >> +};
> > 
> > This is also needed for camera and display support.
> > I tested it successfully with imx219 + unicam on mainline.
> 
> Thanks for testing, can you reply with a Tested-by tag so it could be
> applied to the commit message when this gets picked up?

Well, this also points out that there's an issue: if the mux is needed
for other devices, it shouldn't be in bcm2711-rpi-cm4-io.dts :-) We
could move it to bcm2711-rpi.dtsi (so far all bcm2711-based boards use
either I/O pins 0+1 or 44+45), or move it to per-board files. In the
latter case, instead of duplicating the same block everywhere, it could
be moved to a .dtsi included in those board files. This is what the
downstream kernel does.

-- 
Regards,

Laurent Pinchart


From Thinh.Nguyen at synopsys.com  Tue Jan 18 12:54:08 2022
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Tue, 18 Jan 2022 20:54:08 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <eb3ba4b54d09dbe413907adb86669096110bbd0d.camel@calian.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish> <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
 <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
 <eb3ba4b54d09dbe413907adb86669096110bbd0d.camel@calian.com>
Message-ID: <076fae75-d6e7-41bf-d9e6-c77d08aa51c4@synopsys.com>

Robert Hancock wrote:
> On Tue, 2022-01-18 at 20:00 +0000, Thinh Nguyen wrote:
>> Sean Anderson wrote:
>>> Hi Thinh,
>>>
>>> On 1/18/22 2:46 PM, Thinh Nguyen wrote:
>>>> Hi Sean,
>>>>
>>>> Baruch Siach wrote:
>>>>> Hi Sean, Thinh,
>>>>>
>>>>> On Fri, Jan 14 2022, Sean Anderson wrote:
>>>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly
>>>>>> program
>>>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
>>>>>> Since
>>>>>> we no longer need a special property duplicating this configuration,
>>>>>> snps,ref-clock-period-ns is deprecated.
>>>>>>
>>>>>> Please test this! Patches 3/4 in this series have the effect of
>>>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already
>>>>>> configure
>>>>>> the "ref" clock. I have build tested, but not much else.
>>>>>>
>>>>>> [1]
>>>>>> https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
>>>>>>
>>>>>
>>>>> Thinh, you suggested the dedicated DT property for the reference clock:
>>>>>
>>>>>  
>>>>> https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
>>>>>
>>>>>
>>>>> Can you comment on this series?
>>>>>
>>>>
>>>> Unless there's a good way to pass this information for PCI devices, my
>>>> opinion hasn't changed. (Btw, I don't think creating a dummy clock
>>>> provider and its dummy ops is a good solution as seems to complicate and
>>>> bloat the PCI glue drivers).
>>>
>>> Can you explain your situation a bit more? I'm not sure how you can
>>> access a device tree property but not add a fixed-rate clock.
>>>
>>> --Sean
>>
>> Currently for dwc3 pci devices, we have glue drivers that create a
>> platform_device with specific properties to pass to the dwc3 core
>> driver. Without a ref clock property, we would need another way to pass
>> this information to the core driver or another way for the dwc3 core
>> driver to check for specific pci device's properties and quirks.
> 
> We've used the device tree to instantiate/configure devices inside of a PCI
> device, though obviously that only works on DT-based platforms, and for
> hardware that's part of the board itself, not an add-in card.
> 
> We've also used the MFD infrastructure to instantiate devices and device
> properties inside a PCI device on x86, which can be used if the driver you are
> instantiating uses the generic device property accessors and not the DT-
> specific ones. That gets a bit dirty however - I don't think there's an easy
> way to create properties that are references to other nodes, or more than a
> single level deep heirarchy of nodes.
> 
> For a use case like you're describing, it sounds like it would be better to
> abstract away some of the core DWC3 code from reading the settings from DT
> directly, so that the PCI devices can instantiate it and set the configuration
> however they want, without having to worry about creating fake properties for
> the core to read. I think that pattern has been used with some other drivers
> such as AHCI?
> 

Yes. It would be great if we can rework and abstract this. I'd need to
review how AHCI handles it. It doesn't seem like a small task as it
touches on multiple drivers. But if anyone can start this off, I can
help further contribute/review.

Thanks,
Thinh


From sean.anderson at seco.com  Tue Jan 18 12:59:16 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 18 Jan 2022 15:59:16 -0500
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish> <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
 <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
Message-ID: <0aaeb0e3-1e10-df41-0b61-c10249ea5faa@seco.com>

Hi Thinh,

On 1/18/22 3:00 PM, Thinh Nguyen wrote:
> Sean Anderson wrote:
>> Hi Thinh,
>>
>> On 1/18/22 2:46 PM, Thinh Nguyen wrote:
>>> Hi Sean,
>>>
>>> Baruch Siach wrote:
>>>> Hi Sean, Thinh,
>>>>
>>>> On Fri, Jan 14 2022, Sean Anderson wrote:
>>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly
>>>>> program
>>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
>>>>> Since
>>>>> we no longer need a special property duplicating this configuration,
>>>>> snps,ref-clock-period-ns is deprecated.
>>>>>
>>>>> Please test this! Patches 3/4 in this series have the effect of
>>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already
>>>>> configure
>>>>> the "ref" clock. I have build tested, but not much else.
>>>>>
>>>>> [1]
>>>>> https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
>>>>>
>>>>
>>>> Thinh, you suggested the dedicated DT property for the reference clock:
>>>>
>>>>
>>>> https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
>>>>
>>>>
>>>> Can you comment on this series?
>>>>
>>>
>>> Unless there's a good way to pass this information for PCI devices, my
>>> opinion hasn't changed. (Btw, I don't think creating a dummy clock
>>> provider and its dummy ops is a good solution as seems to complicate and
>>> bloat the PCI glue drivers).
>>
>> Can you explain your situation a bit more? I'm not sure how you can
>> access a device tree property but not add a fixed-rate clock.
>>
>> --Sean
>
> Currently for dwc3 pci devices, we have glue drivers that create a
> platform_device with specific properties to pass to the dwc3 core
> driver. Without a ref clock property, we would need another way to pass
> this information to the core driver or another way for the dwc3 core
> driver to check for specific pci device's properties and quirks.

The primary problem with the existing binding is that it does not
contain enough information to calculate the fractional period. With the
frequency, we can calculate the correct values for the registers without
needing an additional binding. So we need to transition to some kind of
frequency-based system. So perhaps we should add a "ref-clock-frequency"
property and use that as a default for when the clock is missing.

--Sean


From kuba at kernel.org  Tue Jan 18 13:00:15 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 18 Jan 2022 13:00:15 -0800
Subject: [PATCH net v2 0/9] Xilinx axienet fixes
In-Reply-To: <5a5b1c7d58b81b2a6ab738650964ea7a1c2cf99b.camel@calian.com>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <5a5b1c7d58b81b2a6ab738650964ea7a1c2cf99b.camel@calian.com>
Message-ID: <20220118130015.3118e0de@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Tue, 18 Jan 2022 20:45:31 +0000 Robert Hancock wrote:
> On Wed, 2022-01-12 at 11:36 -0600, Robert Hancock wrote:
> > Various fixes for the Xilinx AXI Ethernet driver.
> > 
> > Changed since v1:
> > -corrected a Fixes tag to point to mainline commit
> > -split up reset changes into 3 patches
> > -added ratelimit on netdev_warn in TX busy case
> > 
> > Robert Hancock (9):
> >   net: axienet: increase reset timeout
> >   net: axienet: Wait for PhyRstCmplt after core reset
> >   net: axienet: reset core on initialization prior to MDIO access
> >   net: axienet: add missing memory barriers
> >   net: axienet: limit minimum TX ring size
> >   net: axienet: Fix TX ring slot available check
> >   net: axienet: fix number of TX ring slots for available check
> >   net: axienet: fix for TX busy handling
> >   net: axienet: increase default TX ring size to 128
> 
> Any other comments/reviews on this patch set? It's marked as Changes Requested
> in Patchwork, but I don't think I saw any discussions that ended up with any
> changes being asked for?

Perhaps it was done in anticipation to follow up to Radhey's or
Andrew's question but seems like you answered those. Or maybe because
of the missing CC on of hancock at sedsystems.ca on patch 5?
Not sure.

Could you fold some of the explanations into commit messages, add
Andrew's Acks and post a v3? 

We could probably apply as is but since it was marked as Changes
Requested I can't be sure someone hasn't stopped reviewing in
anticipation of v3.

Thanks!


From robert.hancock at calian.com  Tue Jan 18 13:04:23 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 21:04:23 +0000
Subject: [PATCH net v2 0/9] Xilinx axienet fixes
In-Reply-To: <20220118130015.3118e0de@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220112173700.873002-1-robert.hancock@calian.com>
 <5a5b1c7d58b81b2a6ab738650964ea7a1c2cf99b.camel@calian.com>
 <20220118130015.3118e0de@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <233168d4cd7aef88d4da17570bc2f87da10337c1.camel@calian.com>

On Tue, 2022-01-18 at 13:00 -0800, Jakub Kicinski wrote:
> On Tue, 18 Jan 2022 20:45:31 +0000 Robert Hancock wrote:
> > On Wed, 2022-01-12 at 11:36 -0600, Robert Hancock wrote:
> > > Various fixes for the Xilinx AXI Ethernet driver.
> > > 
> > > Changed since v1:
> > > -corrected a Fixes tag to point to mainline commit
> > > -split up reset changes into 3 patches
> > > -added ratelimit on netdev_warn in TX busy case
> > > 
> > > Robert Hancock (9):
> > >   net: axienet: increase reset timeout
> > >   net: axienet: Wait for PhyRstCmplt after core reset
> > >   net: axienet: reset core on initialization prior to MDIO access
> > >   net: axienet: add missing memory barriers
> > >   net: axienet: limit minimum TX ring size
> > >   net: axienet: Fix TX ring slot available check
> > >   net: axienet: fix number of TX ring slots for available check
> > >   net: axienet: fix for TX busy handling
> > >   net: axienet: increase default TX ring size to 128
> > 
> > Any other comments/reviews on this patch set? It's marked as Changes
> > Requested
> > in Patchwork, but I don't think I saw any discussions that ended up with
> > any
> > changes being asked for?
> 
> Perhaps it was done in anticipation to follow up to Radhey's or
> Andrew's question but seems like you answered those. Or maybe because
> of the missing CC on of hancock at sedsystems.ca on patch 5?

That's actually my old email address (before the renaming from SED Systems to
Calian AT). I think get_maintainer.pl picks that up as I had some past commits
to the driver with that email.

> Not sure.
> 
> Could you fold some of the explanations into commit messages, add
> Andrew's Acks and post a v3? 
> 
> We could probably apply as is but since it was marked as Changes
> Requested I can't be sure someone hasn't stopped reviewing in
> anticipation of v3.

Can do.

> 
> Thanks!
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From Thinh.Nguyen at synopsys.com  Tue Jan 18 13:10:24 2022
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Tue, 18 Jan 2022 21:10:24 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <0aaeb0e3-1e10-df41-0b61-c10249ea5faa@seco.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish> <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
 <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
 <0aaeb0e3-1e10-df41-0b61-c10249ea5faa@seco.com>
Message-ID: <9b4f6122-a044-fac6-c5ba-e786cb1fc584@synopsys.com>

Hi Sean,

Sean Anderson wrote:
> Hi Thinh,
> 
> On 1/18/22 3:00 PM, Thinh Nguyen wrote:
>> Sean Anderson wrote:
>>> Hi Thinh,
>>>
>>> On 1/18/22 2:46 PM, Thinh Nguyen wrote:
>>>> Hi Sean,
>>>>
>>>> Baruch Siach wrote:
>>>>> Hi Sean, Thinh,
>>>>>
>>>>> On Fri, Jan 14 2022, Sean Anderson wrote:
>>>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly
>>>>>> program
>>>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
>>>>>> Since
>>>>>> we no longer need a special property duplicating this configuration,
>>>>>> snps,ref-clock-period-ns is deprecated.
>>>>>>
>>>>>> Please test this! Patches 3/4 in this series have the effect of
>>>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already
>>>>>> configure
>>>>>> the "ref" clock. I have build tested, but not much else.
>>>>>>
>>>>>> [1]
>>>>>> https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
>>>>>>
>>>>>>
>>>>>
>>>>> Thinh, you suggested the dedicated DT property for the reference
>>>>> clock:
>>>>>
>>>>>
>>>>> https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
>>>>>
>>>>>
>>>>>
>>>>> Can you comment on this series?
>>>>>
>>>>
>>>> Unless there's a good way to pass this information for PCI devices, my
>>>> opinion hasn't changed. (Btw, I don't think creating a dummy clock
>>>> provider and its dummy ops is a good solution as seems to complicate
>>>> and
>>>> bloat the PCI glue drivers).
>>>
>>> Can you explain your situation a bit more? I'm not sure how you can
>>> access a device tree property but not add a fixed-rate clock.
>>>
>>> --Sean
>>
>> Currently for dwc3 pci devices, we have glue drivers that create a
>> platform_device with specific properties to pass to the dwc3 core
>> driver. Without a ref clock property, we would need another way to pass
>> this information to the core driver or another way for the dwc3 core
>> driver to check for specific pci device's properties and quirks.
> 
> The primary problem with the existing binding is that it does not
> contain enough information to calculate the fractional period. With the
> frequency, we can calculate the correct values for the registers without
> needing an additional binding. So we need to transition to some kind of
> frequency-based system. So perhaps we should add a "ref-clock-frequency"
> property and use that as a default for when the clock is missing.
> 

Not sure about others, but that's fine with me. The other solution is to
rework the dwc3 drivers as Robert noted, but that requires some work.

Thanks,
Thinh


From robert.hancock at calian.com  Tue Jan 18 13:41:23 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:23 -0600
Subject: [PATCH net v3 0/9] Xilinx axienet fixes
Message-ID: <20220118214132.357349-1-robert.hancock@calian.com>

Various fixes for the Xilinx AXI Ethernet driver.

Changed since v2:
-added Reviewed-by tags, added some explanation to commit
messages, no code changes

Changed since v1:
-corrected a Fixes tag to point to mainline commit
-split up reset changes into 3 patches
-added ratelimit on netdev_warn in TX busy case

Robert Hancock (9):
  net: axienet: increase reset timeout
  net: axienet: Wait for PhyRstCmplt after core reset
  net: axienet: reset core on initialization prior to MDIO access
  net: axienet: add missing memory barriers
  net: axienet: limit minimum TX ring size
  net: axienet: Fix TX ring slot available check
  net: axienet: fix number of TX ring slots for available check
  net: axienet: fix for TX busy handling
  net: axienet: increase default TX ring size to 128

 .../net/ethernet/xilinx/xilinx_axienet_main.c | 135 +++++++++++-------
 1 file changed, 84 insertions(+), 51 deletions(-)

-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:24 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:24 -0600
Subject: [PATCH net v3 1/9] net: axienet: increase reset timeout
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-2-robert.hancock@calian.com>

The previous timeout of 1ms was too short to handle some cases where the
core is reset just after the input clocks were started, which will
be introduced in an upcoming patch. Increase the timeout to 50ms. Also
simplify the reset timeout checking to use read_poll_timeout.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 23ac353b35fe..9c5b24af61fa 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -496,7 +496,8 @@ static void axienet_setoptions(struct net_device *ndev, u32 options)
 
 static int __axienet_device_reset(struct axienet_local *lp)
 {
-	u32 timeout;
+	u32 value;
+	int ret;
 
 	/* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset
 	 * process of Axi DMA takes a while to complete as all pending
@@ -506,15 +507,13 @@ static int __axienet_device_reset(struct axienet_local *lp)
 	 * they both reset the entire DMA core, so only one needs to be used.
 	 */
 	axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, XAXIDMA_CR_RESET_MASK);
-	timeout = DELAY_OF_ONE_MILLISEC;
-	while (axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET) &
-				XAXIDMA_CR_RESET_MASK) {
-		udelay(1);
-		if (--timeout == 0) {
-			netdev_err(lp->ndev, "%s: DMA reset timeout!\n",
-				   __func__);
-			return -ETIMEDOUT;
-		}
+	ret = read_poll_timeout(axienet_dma_in32, value,
+				!(value & XAXIDMA_CR_RESET_MASK),
+				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
+				XAXIDMA_TX_CR_OFFSET);
+	if (ret) {
+		dev_err(lp->dev, "%s: DMA reset timeout!\n", __func__);
+		return ret;
 	}
 
 	return 0;
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:26 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:26 -0600
Subject: [PATCH net v3 3/9] net: axienet: reset core on initialization prior
 to MDIO access
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-4-robert.hancock@calian.com>

In some cases where the Xilinx Ethernet core was used in 1000Base-X or
SGMII modes, which use the internal PCS/PMA PHY, and the MGT
transceiver clock source for the PCS was not running at the time the
FPGA logic was loaded, the core would come up in a state where the
PCS could not be found on the MDIO bus. To fix this, the Ethernet core
(including the PCS) should be reset after enabling the clocks, prior to
attempting to access the PCS using of_mdio_find_device.

Fixes: 1a02556086fc (net: axienet: Properly handle PCS/PMA PHY for 1000BaseX mode)
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 3a2d7e8c3f66..53ff38cbc37b 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -2036,6 +2036,11 @@ static int axienet_probe(struct platform_device *pdev)
 	lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD;
 	lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD;
 
+	/* Reset core now that clocks are enabled, prior to accessing MDIO */
+	ret = __axienet_device_reset(lp);
+	if (ret)
+		goto cleanup_clk;
+
 	lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
 	if (lp->phy_node) {
 		ret = axienet_mdio_setup(lp);
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:25 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:25 -0600
Subject: [PATCH net v3 2/9] net: axienet: Wait for PhyRstCmplt after core reset
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-3-robert.hancock@calian.com>

When resetting the device, wait for the PhyRstCmplt bit to be set
in the interrupt status register before continuing initialization, to
ensure that the core is actually ready. When using an external PHY, this
also ensures we do not start trying to access the PHY while it is still
in reset. The PHY reset is initiated by the core reset which is
triggered just above, but remains asserted for 5ms after the core is
reset according to the documentation.

The MgtRdy bit could also be waited for, but unfortunately when using
7-series devices, the bit does not appear to work as documented (it
seems to behave as some sort of link state indication and not just an
indication the transceiver is ready) so it can't really be relied on for
this purpose.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
Reviewed-by: Andrew Lunn <andrew at lunn.ch>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 9c5b24af61fa..3a2d7e8c3f66 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -516,6 +516,16 @@ static int __axienet_device_reset(struct axienet_local *lp)
 		return ret;
 	}
 
+	/* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has finished */
+	ret = read_poll_timeout(axienet_ior, value,
+				value & XAE_INT_PHYRSTCMPLT_MASK,
+				DELAY_OF_ONE_MILLISEC, 50000, false, lp,
+				XAE_IS_OFFSET);
+	if (ret) {
+		dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n", __func__);
+		return ret;
+	}
+
 	return 0;
 }
 
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:28 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:28 -0600
Subject: [PATCH net v3 5/9] net: axienet: limit minimum TX ring size
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-6-robert.hancock@calian.com>

The driver will not work properly if the TX ring size is set to below
MAX_SKB_FRAGS + 1 since it needs to hold at least one full maximally
fragmented packet in the TX ring. Limit setting the ring size to below
this value.

Fixes: 8b09ca823ffb4 ("net: axienet: Make RX/TX ring sizes configurable")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index fb486a457c76..3f92001bacaf 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -43,6 +43,7 @@
 /* Descriptors defines for Tx and Rx DMA */
 #define TX_BD_NUM_DEFAULT		64
 #define RX_BD_NUM_DEFAULT		1024
+#define TX_BD_NUM_MIN			(MAX_SKB_FRAGS + 1)
 #define TX_BD_NUM_MAX			4096
 #define RX_BD_NUM_MAX			4096
 
@@ -1370,7 +1371,8 @@ axienet_ethtools_set_ringparam(struct net_device *ndev,
 	if (ering->rx_pending > RX_BD_NUM_MAX ||
 	    ering->rx_mini_pending ||
 	    ering->rx_jumbo_pending ||
-	    ering->rx_pending > TX_BD_NUM_MAX)
+	    ering->tx_pending < TX_BD_NUM_MIN ||
+	    ering->tx_pending > TX_BD_NUM_MAX)
 		return -EINVAL;
 
 	if (netif_running(ndev))
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:27 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:27 -0600
Subject: [PATCH net v3 4/9] net: axienet: add missing memory barriers
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-5-robert.hancock@calian.com>

This driver was missing some required memory barriers:

Use dma_rmb to ensure we see all updates to the descriptor after we see
that an entry has been completed.

Use wmb and rmb to avoid stale descriptor status between the TX path and
TX complete IRQ path.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 53ff38cbc37b..fb486a457c76 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -632,6 +632,8 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		if (nr_bds == -1 && !(status & XAXIDMA_BD_STS_COMPLETE_MASK))
 			break;
 
+		/* Ensure we see complete descriptor update */
+		dma_rmb();
 		phys = desc_get_phys_addr(lp, cur_p);
 		dma_unmap_single(ndev->dev.parent, phys,
 				 (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
@@ -645,8 +647,10 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		cur_p->app1 = 0;
 		cur_p->app2 = 0;
 		cur_p->app4 = 0;
-		cur_p->status = 0;
 		cur_p->skb = NULL;
+		/* ensure our transmit path and device don't prematurely see status cleared */
+		wmb();
+		cur_p->status = 0;
 
 		if (sizep)
 			*sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
@@ -704,6 +708,9 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
 					    int num_frag)
 {
 	struct axidma_bd *cur_p;
+
+	/* Ensure we see all descriptor updates from device or TX IRQ path */
+	rmb();
 	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
 	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
 		return NETDEV_TX_BUSY;
@@ -843,6 +850,8 @@ static void axienet_recv(struct net_device *ndev)
 
 		tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
 
+		/* Ensure we see complete descriptor update */
+		dma_rmb();
 		phys = desc_get_phys_addr(lp, cur_p);
 		dma_unmap_single(ndev->dev.parent, phys, lp->max_frm_size,
 				 DMA_FROM_DEVICE);
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:29 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:29 -0600
Subject: [PATCH net v3 6/9] net: axienet: Fix TX ring slot available check
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-7-robert.hancock@calian.com>

The check for whether a TX ring slot was available was incorrect,
since a slot which had been loaded with transmit data but the device had
not started transmitting would be treated as available, potentially
causing non-transmitted slots to be overwritten. The control field in
the descriptor should be checked, rather than the status field (which may
only be updated when the device completes the entry).

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 3f92001bacaf..85fe2b3bd37a 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -643,7 +643,6 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK))
 			dev_consume_skb_irq(cur_p->skb);
 
-		cur_p->cntrl = 0;
 		cur_p->app0 = 0;
 		cur_p->app1 = 0;
 		cur_p->app2 = 0;
@@ -651,6 +650,7 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 		cur_p->skb = NULL;
 		/* ensure our transmit path and device don't prematurely see status cleared */
 		wmb();
+		cur_p->cntrl = 0;
 		cur_p->status = 0;
 
 		if (sizep)
@@ -713,7 +713,7 @@ static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
 	/* Ensure we see all descriptor updates from device or TX IRQ path */
 	rmb();
 	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
-	if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK)
+	if (cur_p->cntrl)
 		return NETDEV_TX_BUSY;
 	return 0;
 }
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:30 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:30 -0600
Subject: [PATCH net v3 7/9] net: axienet: fix number of TX ring slots for
 available check
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-8-robert.hancock@calian.com>

The check for the number of available TX ring slots was off by 1 since a
slot is required for the skb header as well as each fragment. This could
result in overwriting a TX ring slot that was still in use.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 85fe2b3bd37a..8dc9e92e05d2 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -747,7 +747,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	num_frag = skb_shinfo(skb)->nr_frags;
 	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
-	if (axienet_check_tx_bd_space(lp, num_frag)) {
+	if (axienet_check_tx_bd_space(lp, num_frag + 1)) {
 		if (netif_queue_stopped(ndev))
 			return NETDEV_TX_BUSY;
 
@@ -757,7 +757,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 		smp_mb();
 
 		/* Space might have just been freed - check again */
-		if (axienet_check_tx_bd_space(lp, num_frag))
+		if (axienet_check_tx_bd_space(lp, num_frag + 1))
 			return NETDEV_TX_BUSY;
 
 		netif_wake_queue(ndev);
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:32 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:32 -0600
Subject: [PATCH net v3 9/9] net: axienet: increase default TX ring size to 128
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-10-robert.hancock@calian.com>

With previous changes to make the driver handle the TX ring size more
correctly, the default TX ring size of 64 appears to significantly
bottleneck TX performance to around 600 Mbps on a 1 Gbps link on ZynqMP.
Increasing this to 128 seems to bring performance up to near line rate and
shouldn't cause excess bufferbloat (this driver doesn't yet support modern
byte-based queue management).

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index b4f42ee9b75d..377c94ec2486 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -41,7 +41,7 @@
 #include "xilinx_axienet.h"
 
 /* Descriptors defines for Tx and Rx DMA */
-#define TX_BD_NUM_DEFAULT		64
+#define TX_BD_NUM_DEFAULT		128
 #define RX_BD_NUM_DEFAULT		1024
 #define TX_BD_NUM_MIN			(MAX_SKB_FRAGS + 1)
 #define TX_BD_NUM_MAX			4096
-- 
2.31.1



From robert.hancock at calian.com  Tue Jan 18 13:41:31 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 15:41:31 -0600
Subject: [PATCH net v3 8/9] net: axienet: fix for TX busy handling
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <20220118214132.357349-9-robert.hancock@calian.com>

Network driver documentation indicates we should be avoiding returning
NETDEV_TX_BUSY from ndo_start_xmit in normal cases, since it requires
the packets to be requeued. Instead the queue should be stopped after
a packet is added to the TX ring when there may not be enough room for an
additional one. Also, when TX ring entries are completed, we should only
wake the queue if we know there is room for another full maximally
fragmented packet.

Print a warning if there is insufficient space at the start of start_xmit,
since this should no longer happen.

Combined with increasing the default TX ring size (in a subsequent
patch), this appears to recover the TX performance lost by previous changes
to actually manage the TX ring state properly.

Fixes: 8a3b7a252dca9 ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 86 ++++++++++---------
 1 file changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 8dc9e92e05d2..b4f42ee9b75d 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -660,6 +660,32 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd,
 	return i;
 }
 
+/**
+ * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy
+ * @lp:		Pointer to the axienet_local structure
+ * @num_frag:	The number of BDs to check for
+ *
+ * Return: 0, on success
+ *	    NETDEV_TX_BUSY, if any of the descriptors are not free
+ *
+ * This function is invoked before BDs are allocated and transmission starts.
+ * This function returns 0 if a BD or group of BDs can be allocated for
+ * transmission. If the BD or any of the BDs are not free the function
+ * returns a busy status. This is invoked from axienet_start_xmit.
+ */
+static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
+					    int num_frag)
+{
+	struct axidma_bd *cur_p;
+
+	/* Ensure we see all descriptor updates from device or TX IRQ path */
+	rmb();
+	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
+	if (cur_p->cntrl)
+		return NETDEV_TX_BUSY;
+	return 0;
+}
+
 /**
  * axienet_start_xmit_done - Invoked once a transmit is completed by the
  * Axi DMA Tx channel.
@@ -689,33 +715,8 @@ static void axienet_start_xmit_done(struct net_device *ndev)
 	/* Matches barrier in axienet_start_xmit */
 	smp_mb();
 
-	netif_wake_queue(ndev);
-}
-
-/**
- * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy
- * @lp:		Pointer to the axienet_local structure
- * @num_frag:	The number of BDs to check for
- *
- * Return: 0, on success
- *	    NETDEV_TX_BUSY, if any of the descriptors are not free
- *
- * This function is invoked before BDs are allocated and transmission starts.
- * This function returns 0 if a BD or group of BDs can be allocated for
- * transmission. If the BD or any of the BDs are not free the function
- * returns a busy status. This is invoked from axienet_start_xmit.
- */
-static inline int axienet_check_tx_bd_space(struct axienet_local *lp,
-					    int num_frag)
-{
-	struct axidma_bd *cur_p;
-
-	/* Ensure we see all descriptor updates from device or TX IRQ path */
-	rmb();
-	cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num];
-	if (cur_p->cntrl)
-		return NETDEV_TX_BUSY;
-	return 0;
+	if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
+		netif_wake_queue(ndev);
 }
 
 /**
@@ -748,19 +749,14 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
 	if (axienet_check_tx_bd_space(lp, num_frag + 1)) {
-		if (netif_queue_stopped(ndev))
-			return NETDEV_TX_BUSY;
-
+		/* Should not happen as last start_xmit call should have
+		 * checked for sufficient space and queue should only be
+		 * woken when sufficient space is available.
+		 */
 		netif_stop_queue(ndev);
-
-		/* Matches barrier in axienet_start_xmit_done */
-		smp_mb();
-
-		/* Space might have just been freed - check again */
-		if (axienet_check_tx_bd_space(lp, num_frag + 1))
-			return NETDEV_TX_BUSY;
-
-		netif_wake_queue(ndev);
+		if (net_ratelimit())
+			netdev_warn(ndev, "TX ring unexpectedly full\n");
+		return NETDEV_TX_BUSY;
 	}
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -821,6 +817,18 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 	if (++lp->tx_bd_tail >= lp->tx_bd_num)
 		lp->tx_bd_tail = 0;
 
+	/* Stop queue if next transmit may not have space */
+	if (axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) {
+		netif_stop_queue(ndev);
+
+		/* Matches barrier in axienet_start_xmit_done */
+		smp_mb();
+
+		/* Space might have just been freed - check again */
+		if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1))
+			netif_wake_queue(ndev);
+	}
+
 	return NETDEV_TX_OK;
 }
 
-- 
2.31.1



From marex at denx.de  Tue Jan 18 14:11:00 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 18 Jan 2022 23:11:00 +0100
Subject: [PATCH 1/7] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <8481872c-9ee0-c759-3ab0-5209165ad9b2@foss.st.com>
References: <20210408185731.135511-1-marex@denx.de>
 <20210408185731.135511-2-marex@denx.de>
 <2b10f5d9-54cb-ce83-b7aa-f4ec8e67c001@foss.st.com>
 <92dd5798-8f5a-66e4-06bc-e3beb16690f5@denx.de>
 <d168aed8-aebd-1bee-aa72-3a3601718cad@foss.st.com>
 <e27dbccd-518f-7718-8cf7-cc9c8adb8a56@denx.de>
 <6416577a-ea06-a014-543a-9ef86aae603d@foss.st.com>
 <2281af74-33a0-df45-968b-baa1ddd9d6e0@denx.de>
 <8481872c-9ee0-c759-3ab0-5209165ad9b2@foss.st.com>
Message-ID: <8d02eb84-704e-ea67-0050-78c40f930094@denx.de>

On 4/19/21 09:46, gabriel.fernandez at foss.st.com wrote:

Hello again,

[...]

I sent out an rebased (and much shorter) patch series now:

https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=606380

-- 
Best regards,
Marek Vasut


From sstabellini at kernel.org  Tue Jan 18 14:32:33 2022
From: sstabellini at kernel.org (Stefano Stabellini)
Date: Tue, 18 Jan 2022 14:32:33 -0800 (PST)
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu
 device
In-Reply-To: <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
 <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
 <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
Message-ID: <alpine.DEB.2.22.394.2201181317570.19362@ubuntu-linux-20-04-desktop>

On Mon, 17 Jan 2022, Robin Murphy wrote:
> On 2022-01-17 12:32, Sergiy Kibrik wrote:
> > In IOMMU-capable system hypervisor usually takes over IOMMU control.
> > Generally guest domains don't need to care about IOMMU management and take
> > any
> > extra actions. Yet in some cases a knowledge about which device is protected
> > may be useful for privileged domain.
> > 
> > In compliance with iommu bindings this can be achieved with device-level
> > iommus property specified with dummy Xen iommu device.
> 
> This could break Linux guests, since depending on the deferred probe timeout
> setting it could lead to drivers never probing because the "IOMMU" never
> becomes available.
> 
> Unless you intend to expose actual paravirtualised IOMMU translation
> functionality to guests (in which case virtio-iommu would be highly preferable
> anyway), I don't think this is the right approach. If there's no better
> alternative to using DT to communicate Xen-specific policy, then at least it
> should logically be via a Xen-specific DT property.

Hi Robin,

Let me explain why this is useful and how it differs from something like
virtio-iommu.

When Linux is running as dom0 it uses a swiotlb-based driver to ensure
that DMA operations involving foreign (foreign == owned by other VMs)
pages can work successfully. The driver is drivers/xen/swiotlb-xen.c.
For this discussion the interesting thing about swiotlb-xen is that it
is complex, it can be slow, and it is not actually always needed. You
can imagine that somebody might want to disable swiotlb-xen whenever
possible.

Specifically, if a DMA-capable device is behind an IOMMU, then there is
no need for Linux to use swiotlb-xen.

The problem is that Linux doesn't know when a device is protected by an
IOMMU because the IOMMU is used by Xen and not exposed to Linux.

This bindings is a way for Xen to provide information to Linux, so that
Linux knows when to safely skip swiotlb-xen. It is telling Linux that
the device is protected by an IOMMU, even if Linux is not expected to
use it or do anything with it.

The initial idea was actually to write a Xen-specific DT property for
this. Then a member of the community suggested to re-use the IOMMU
bindings given that after all this is an IOMMU; the only thing special
about it is that the Linux driver is not supposed to do anything with
it. In my mind there should actually be a driver for "xen,iommu-el2-v1"
in Linux, it is just that the driver would "return 0" without doing
anything. (Note that the current patch series doesn't do this as it
turned out not to be currently necessary.)

This is a long way to say that:

1) from my point of view it is also OK to introduce a Xen-specific
   property for this if you think it is best (it doesn't look like it
   would make the code more complex either)
2) at the same time I think that reusing the IOMMU bindings seems fit
   for purpose


In regards to the "deferred probe timeout", I take it wouldn't be an
issue if we use a Xen-specific property instead? Also, would the
presence of an empty IOMMU driver for it (one that just return success
from the probing function without doing anything) solve the problem too?

Thanks for taking a look.

Cheers,

Stefano


> > Signed-off-by: Sergiy Kibrik <Sergiy_Kibrik at epam.com>
> > ---
> >   Documentation/devicetree/bindings/arm/xen.txt | 26 +++++++++++++++++++
> >   1 file changed, 26 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/arm/xen.txt
> > b/Documentation/devicetree/bindings/arm/xen.txt
> > index db5c56db30ec..98efa95c0d1b 100644
> > --- a/Documentation/devicetree/bindings/arm/xen.txt
> > +++ b/Documentation/devicetree/bindings/arm/xen.txt
> > @@ -58,3 +58,29 @@ Documentation/arm/uefi.rst, which are provided by the
> > regular UEFI stub. However
> >   they differ because they are provided by the Xen hypervisor, together with
> > a set
> >   of UEFI runtime services implemented via hypercalls, see
> >   http://xenbits.xen.org/docs/unstable/hypercall/x86_64/include,public,platform.h.html.
> > +
> > +* XEN IOMMU device
> > +
> > +In compliance with iommu bindings Xen virtual IOMMU device node represents
> > +hypervisor-managed IOMMU [1]. Platform devices specified as IOMMU masters
> > of
> > +this xen-iommu device are protected by hypervisor-managed platform IOMMU.
> > +
> > +Required properties:
> > +
> > +- compatible:	Should be "xen,iommu-el2-v1"
> > +- #iommu-cells: must be 0
> > +
> > +Example:
> > +
> > +xen-iommu {
> > +	compatible = "xen,iommu-el2-v1";
> > +	#iommu-cells = <0>;
> > +};
> > +
> > +video at fe001000 {
> > +	...
> > +	/* this platform device is IOMMU-protected by hypervisor */
> > +	iommus = <&xen-iommu 0x0>;
> > +};
> > +
> > +[1] Documentation/devicetree/bindings/iommu/iommu.txt
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From uwe at kleine-koenig.org  Tue Jan 18 14:41:19 2022
From: uwe at kleine-koenig.org (=?UTF-8?Q?Uwe_Kleine-K=c3=b6nig?=)
Date: Tue, 18 Jan 2022 23:41:19 +0100
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <YecnebByrBplFEsU@pendragon.ideasonboard.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
 <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
 <YecnebByrBplFEsU@pendragon.ideasonboard.com>
Message-ID: <41d2ff4a-79eb-5071-3a35-efa8cccec074@kleine-koenig.org>

Hello,

On 1/18/22 21:47, Laurent Pinchart wrote:
> On Tue, Jan 18, 2022 at 12:00:50PM -0800, Florian Fainelli wrote:
>> On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
>>> This is also needed for camera and display support.
>>> I tested it successfully with imx219 + unicam on mainline.
>>
>> Thanks for testing, can you reply with a Tested-by tag so it could be
>> applied to the commit message when this gets picked up?
> 
> Well, this also points out that there's an issue: if the mux is needed
> for other devices, it shouldn't be in bcm2711-rpi-cm4-io.dts :-) We
> could move it to bcm2711-rpi.dtsi (so far all bcm2711-based boards use
> either I/O pins 0+1 or 44+45)

If I understand correctly it's not used on rpi-4-b, so bcm2711-rpi.dtsi 
would be wrong.

> , or move it to per-board files.

It is in an board file now?! So I don't understand your suggestion here.

> In the
> latter case, instead of duplicating the same block everywhere, it could
> be moved to a .dtsi included in those board files. This is what the
> downstream kernel does.

How does it call the dtsi file? I wonder if that is sensible expecting 
that the devices on the bus are different for different boards?!

Best regards
Uwe

-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220118/f0bde140/attachment.sig>

From helgaas at kernel.org  Tue Jan 18 14:49:35 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 18 Jan 2022 16:49:35 -0600
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <20220116084310.57465-1-xueshuai@linux.alibaba.com>
Message-ID: <20220118224935.GA903617@bhelgaas>

On Sun, Jan 16, 2022 at 04:43:10PM +0800, Shuai Xue wrote:
> On an ACPI system, ACPI is initialised very early from a
> subsys_initcall(), while SDEI is not ready until a
> subsys_initcall_sync(). This patch is to reduce the time before GHES
> initialization.
> 
> The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
> apei_sdei_unregister_ghes()) to register or unregister event callback
> for dispatcher in firmware. When the GHES driver probing, it registers
> the corresponding callback according to the notification type specified
> by GHES. If the GHES notification type is SDEI, the GHES driver will
> call apei_sdei_register_ghes() to register event call.
> 
> When the firmware emits an event, it migrates the handling of the event
> into the kernel at the registered entry-point __sdei_asm_handler. And
> finally, the kernel will call the registered event callback and return
> status_code to indicate the status of event handling. SDEI_EV_FAILED
> indicates that the kernel failed to handle the event.
> 
> Consequently, when an error occurs during kernel booting, the kernel is
> unable to handle and report errors until the GHES driver is initialized
> by device_initcall(), in which the event callback is registered.  For
> example, when the kernel booting, the console logs many times from
> firmware before GHES drivers init in our platform:
> 
> 	Trip in MM PCIe RAS handle(Intr:910)
>   	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
> 	Find RP(98:1.0)
> 	--Walk dev(98:1.0) CE:0 UCE:4000
> 	...
> 	ERROR:   sdei_dispatch_event(32a) ret:-1
> 	--handler(910) end

If I understand correctly, the firmware noticed an error, tried to
report it to the kernel, and is complaining because the kernel isn't
ready to handle it yet.  And the reason for this patch is to reduce
these complaints from the firmware.

That doesn't seem like a very good reason for this patch.  There is
*always* a window before the kernel is ready to handle events from the
firmware.

Why is the firmware noticing these errors in the first place?  If
you're seeing these complaints regularly, my guess is that either you
have some terrible hardware or (more likely) the firmware isn't
clearing some expected error condition correctly.  For example, maybe
the Unsupported Request errors that happen while enumerating PCIe
devices are being reported.

If you register the callback function, the kernel will now start
seeing these error reports.  What happens then?  Does the kernel log
the errors somewhere?  Is that better than the current situation where
the firmware logs them?

However, I DO think that:

  - Removing acpi_hest_init() from acpi_pci_root_init(), and

  - Converting ghes_init() and sdei_init() from initcalls to explicit
    calls

are very good reasons to do something like this patch because HEST is
not PCI-specific, and IMO, explicit calls are better than initcalls
because initcall ordering is implicit and not well-defined within a
level.

> This is because the callback function has not been registered yet.  Due
> to the poor design of firmware, previously reported errors will be
> overwritten by new ones. Therefore, all errors that occurred before GHES
> initialization are missed and there is no chance to report and find them
> again.
> 
> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
> the estatus memory pool. On the other hand, ghes_init() relies on
> sdei_init() to detect the SDEI version and the framework for registering
> and unregistering events. The dependencies are as follows
> 
> 	ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
> 	ghes_init() => sdei_init()
> 
> Based on above, move sdei_init and ghes_init as far ahead as possible,
> right after acpi_iort_init() in acpi_init(). After this patch, there are
> still errors missing, but we have to tolerate it until the software
> reporting capability is built. And this patch merely reduce the time
> before GHES initialization. The boot dmesg before this patch:
> 
> 	[    3.688586] HEST: Table parsing has been initialized.
> 	...
> 	[   33.204340] calling  sdei_init+0x0/0x120 @ 1
> 	[   33.208645] sdei: SDEIv1.0 (0x0) detected in firmware.
> 	...
> 	[   36.005390] calling  ghes_init+0x0/0x11c @ 1
> 	[   36.190021] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
> 
> After this patch, the boot dmesg like bellow:
> 
> 	[    3.688664] HEST: Table parsing has been initialized.
> 	[    3.688691] sdei: SDEIv1.0 (0x0) detected in firmware.
> 	[    3.694557] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
> 
> As we can see, the initialization of GHES is advanced by 33 seconds.
> (It should be noted that the effect of optimization varies with the
> platform.)
> 
> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> ---
>  drivers/acpi/apei/ghes.c    | 18 ++++++++----------
>  drivers/acpi/bus.c          |  4 ++++
>  drivers/acpi/pci_root.c     |  4 ++--
>  drivers/firmware/arm_sdei.c | 13 ++-----------
>  include/acpi/apei.h         |  2 ++
>  include/linux/arm_sdei.h    |  2 ++
>  6 files changed, 20 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 0c5c9acc6254..64f24a9f213f 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -1457,27 +1457,26 @@ static struct platform_driver ghes_platform_driver = {
>  	.remove		= ghes_remove,
>  };
>  
> -static int __init ghes_init(void)
> +void __init ghes_init(void)
>  {
>  	int rc;
>  
>  	if (acpi_disabled)
> -		return -ENODEV;
> +		return;
>  
>  	switch (hest_disable) {
>  	case HEST_NOT_FOUND:
> -		return -ENODEV;
> +		pr_info(GHES_PFX "HEST is not found!\n");

I don't know whether this "HEST is not found" message is worthwhile or
not.  I don't think lack of an HEST is an error, and users may be
alarmed.  But this is an ACPI thing, so up to you and Rafael.

> +		return;
>  	case HEST_DISABLED:
>  		pr_info(GHES_PFX "HEST is not enabled!\n");
> -		return -EINVAL;
> +		return;
>  	default:
>  		break;
>  	}
>  
> -	if (ghes_disable) {
> +	if (ghes_disable)
>  		pr_info(GHES_PFX "GHES is not enabled!\n");
> -		return -EINVAL;
> -	}
>  
>  	ghes_nmi_init_cxt();

Previously, if "ghes_disable", we returned immediately.  After this
patch, if "ghes_disable", we print "GHES is not enabled!\n", but then
we go on to call ghes_nmi_init_cxt() and register the
&ghes_platform_driver.  That looks wrong.  Maybe you meant to keep a
"return" here?

> @@ -1495,8 +1494,7 @@ static int __init ghes_init(void)
>  	else
>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
>  
> -	return 0;
> +	return;
>  err:
> -	return rc;
> +	ghes_disable = 1;

Why do you set ghes_disable here?  As far as I can tell, we will never
look at it again.  The places we do look at it are:

  - ghes_init(): earlier in this function, so we've already done that,

  - acpi_hest_init(): we've already called that, too, and

  - acpi_bus_osc_negotiate_platform_control(): called from
    acpi_bus_init(), which we've already called.

>  }
> -device_initcall(ghes_init);
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 07f604832fd6..1dcd71df2cd5 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -30,6 +30,7 @@
>  #include <linux/acpi_viot.h>
>  #include <linux/pci.h>
>  #include <acpi/apei.h>
> +#include <linux/arm_sdei.h>
>  #include <linux/suspend.h>
>  #include <linux/prmt.h>
>  
> @@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
>  
>  	pci_mmcfg_late_init();
>  	acpi_iort_init();
> +	acpi_hest_init();
> +	sdei_init();
> +	ghes_init();

sdei_init() and ghes_init() stick out here because they're the only
functions without an "acpi_" prefix.  Maybe a separate patch to rename
them?

>  	acpi_scan_init();
>  	acpi_ec_init();
>  	acpi_debugfs_init();
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index b76db99cced3..14e20af44627 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -23,7 +23,7 @@
>  #include <linux/dmi.h>
>  #include <linux/platform_data/x86/apple.h>
>  #include <acpi/apei.h>	/* for acpi_hest_init() */

This #include looks like it may no longer be necessary.

> -
> +#include <linux/arm_sdei.h> /* for sdei_init() */

I don't think this #include is necessary.

>  #include "internal.h"
>  
>  #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
> @@ -943,7 +943,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>  
>  void __init acpi_pci_root_init(void)
>  {
> -	acpi_hest_init();
> +

Drop the blank line here.

>  	if (acpi_pci_disabled)
>  		return;
>  
> diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
> index a7e762c352f9..1e1a51510e83 100644
> --- a/drivers/firmware/arm_sdei.c
> +++ b/drivers/firmware/arm_sdei.c
> @@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
>  	return true;
>  }
>  
> -static int __init sdei_init(void)
> +void __init sdei_init(void)
>  {
>  	struct platform_device *pdev;
>  	int ret;
>  
>  	ret = platform_driver_register(&sdei_driver);
>  	if (ret || !sdei_present_acpi())
> -		return ret;
> +		return;
>  
>  	pdev = platform_device_register_simple(sdei_driver.driver.name,
>  					       0, NULL, 0);
> @@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
>  		pr_info("Failed to register ACPI:SDEI platform device %d\n",
>  			ret);
>  	}
> -
> -	return ret;
>  }
>  
> -/*
> - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
> - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
> - * by device_initcall(). We want to be called in the middle.
> - */
> -subsys_initcall_sync(sdei_init);
> -
>  int sdei_event_handler(struct pt_regs *regs,
>  		       struct sdei_registered_event *arg)
>  {
> diff --git a/include/acpi/apei.h b/include/acpi/apei.h
> index ece0a8af2bae..7dbd6363fda7 100644
> --- a/include/acpi/apei.h
> +++ b/include/acpi/apei.h
> @@ -27,8 +27,10 @@ extern int hest_disable;
>  extern int erst_disable;
>  #ifdef CONFIG_ACPI_APEI_GHES
>  extern bool ghes_disable;
> +void __init ghes_init(void);
>  #else
>  #define ghes_disable 1
> +static inline void ghes_init(void) { return; }

"return" is unnecessary here.

>  #endif
>  
>  #ifdef CONFIG_ACPI_APEI
> diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
> index 0a241c5c911d..9c987188b692 100644
> --- a/include/linux/arm_sdei.h
> +++ b/include/linux/arm_sdei.h
> @@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
>  /* For use by arch code when CPU hotplug notifiers are not appropriate. */
>  int sdei_mask_local_cpu(void);
>  int sdei_unmask_local_cpu(void);
> +void __init sdei_init(void);
>  #else
>  static inline int sdei_mask_local_cpu(void) { return 0; }
>  static inline int sdei_unmask_local_cpu(void) { return 0; }
> +static inline void sdei_init(void) { return ; }

"return" is unnecessary here.

>  #endif /* CONFIG_ARM_SDE_INTERFACE */
>  
>  
> -- 
> 2.20.1.12.g72788fdb
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From rananta at google.com  Tue Jan 18 14:54:13 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Tue, 18 Jan 2022 14:54:13 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
Message-ID: <CAJHc60zcwNskA7JCg9nQc4YhmLdziHVauf1gQQ48GHYtby_aYg@mail.gmail.com>

On Fri, Jan 14, 2022 at 1:51 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> On Thu, Jan 13, 2022 at 9:21 AM Sean Christopherson <seanjc at google.com> wrote:
> >
> > On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> > > On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
> > > > Perhaps it would help if you explained *why* you are doing this. It
> > > > sounds like you are either trying to protect against a malicious
> > > > userspace, or you are trying to keep userspace from doing something
> > > > stupid. In general, kvm only enforces constraints that are necessary
> > > > to protect the host. If that's what you're doing, I don't understand
> > > > why live migration doesn't provide an end-run around your protections.
> > > It's mainly to safeguard the guests. With respect to migration, KVM
> > > and the userspace are collectively playing a role here. It's up to the
> > > userspace to ensure that the registers are configured the same across
> > > migrations and KVM ensures that the userspace doesn't modify the
> > > registers after KVM_RUN so that they don't see features turned OFF/ON
> > > during execution. I'm not sure if it falls into the definition of
> > > protecting the host. Do you see a value in adding this extra
> > > protection from KVM?
> >
> > Short answer: probably not?
> >
> > There is precedent for disallowing userspace from doing stupid things, but that's
> > either for KVM's protection (as Jim pointed out), or because KVM can't honor the
> > change, e.g. x86 is currently in the process of disallowing most CPUID changes
> > after KVM_RUN because KVM itself consumes the CPUID information and KVM doesn't
> > support updating some of it's own internal state (because removing features like
> > GB hugepage support is nonsensical and would require a large pile of complicated,
> > messy code).
> >
> > Restricing CPUID changes does offer some "protection" to the guest, but that's
> > not the goal.  E.g. KVM won't detect CPUID misconfiguration in the migration
> > case, and trying to do so is a fool's errand.
> >
> > If restricting updates in the arm64 is necessary to ensure KVM provides sane
> > behavior, then it could be justified.  But if it's purely a sanity check on
> > behalf of the guest, then it's not justified.
>
> The pseudo firmware hvc registers, which this series are adding, are
> used by KVM to identify available hvc features for the guest, and not
> directly exposed to the guest as registers.
> The ways the KVM code in the series consumes the registers' values are
> very limited, and no KVM data/state is created based on their values.
> But, as the code that consumes the registers grows in the future,
> I wouldn't be surprised if KVM consumes them differently than it does
> now (e.g. create another data structure based on the register values).
> I'm not sure though :)
>
> The restriction, with which KVM doesn't need to worry about the changes
> in the registers after KVM_RUN, could potentially protect or be useful
> to protect KVM and simplify future changes/maintenance of the KVM codes
> that consumes the values.
> I thought this was one of the reasons for having the restriction.
>
Well, that wasn't the original intention of the patch, but just to
protect the guests from the userspace's dynamic updates. Having said
that, and based on what Sean mentioned in his last reply, it could be
inconsistent from what KVM has been doing so far and would be
difficult to cover all the scenarios that userspace can mess things up
for guests.
I'll plan to drop this patch in the next version, and bring it back
back to arm64 if we really need it.

Thanks Sean, Jim, and Reiji for the comments and discussion.

Regards,
Raghavendra
> Thanks,
> Reiji


From laurent.pinchart at ideasonboard.com  Tue Jan 18 14:59:32 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 19 Jan 2022 00:59:32 +0200
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <41d2ff4a-79eb-5071-3a35-efa8cccec074@kleine-koenig.org>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
 <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
 <YecnebByrBplFEsU@pendragon.ideasonboard.com>
 <41d2ff4a-79eb-5071-3a35-efa8cccec074@kleine-koenig.org>
Message-ID: <YedGVE6Ow+VLpaoS@pendragon.ideasonboard.com>

Hi Uwe,

On Tue, Jan 18, 2022 at 11:41:19PM +0100, Uwe Kleine-K?nig wrote:
> On 1/18/22 21:47, Laurent Pinchart wrote:
> > On Tue, Jan 18, 2022 at 12:00:50PM -0800, Florian Fainelli wrote:
> >> On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
> >>> This is also needed for camera and display support.
> >>> I tested it successfully with imx219 + unicam on mainline.
> >>
> >> Thanks for testing, can you reply with a Tested-by tag so it could be
> >> applied to the commit message when this gets picked up?
> > 
> > Well, this also points out that there's an issue: if the mux is needed
> > for other devices, it shouldn't be in bcm2711-rpi-cm4-io.dts :-) We
> > could move it to bcm2711-rpi.dtsi (so far all bcm2711-based boards use
> > either I/O pins 0+1 or 44+45)
> 
> If I understand correctly it's not used on rpi-4-b, so bcm2711-rpi.dtsi 
> would be wrong.

rpi-4-b muxes I2C0 on pins 0+1 and 44+45. The latter is wired to the
camera connector, and used for the camera sensor. Same thing on rpi-cm4.
rpi-400 has no camera connector, but I believe the display I2C bus is
also on pins 44+45 (at least according to the downstream DT sources,
rpi-400 muxes I2C0 on 0+1 and 44+45 too).

> > , or move it to per-board files.
> 
> It is in an board file now?! So I don't understand your suggestion here.

Sorry, I meant have it in per-board files, not more it there.

> > In the
> > latter case, instead of duplicating the same block everywhere, it could
> > be moved to a .dtsi included in those board files. This is what the
> > downstream kernel does.
> 
> How does it call the dtsi file? I wonder if that is sensible expecting 
> that the devices on the bus are different for different boards?!

Downstream has a bcm283x-rpi-i2c0mux_0_44.dtsi that just contains

&i2c0mux {
	pinctrl-0 = <&i2c0_gpio0>;
	pinctrl-1 = <&i2c0_gpio44>;
};

with i2c0mux defined in bcm283x.dtsi as

	i2c0mux: i2c0mux {
		compatible = "i2c-mux-pinctrl";
		#address-cells = <1>;
		#size-cells = <0>;

		i2c-parent = <&i2c0if>;

		pinctrl-names = "i2c0", "i2c_csi_dsi";

		status = "disabled";

		i2c0: i2c at 0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;
		};

		i2c_csi_dsi: i2c at 1 {
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <0>;
		};
	};

The following board files #include "bcm283x-rpi-i2c0mux_0_44.dtsi":

- bcm2710-rpi-3-b.dts
- bcm2710-rpi-3-b-plus.dts
- bcm2710-rpi-zero-2-w.dts
- bcm2711-rpi-400.dts
- bcm2711-rpi-4-b.dts
- bcm2711-rpi-4-b.dts.orig
- bcm2711-rpi-cm4.dts

We don't have to replicate the exact same mechanism and use the same
names, but for rpi-4-b and rpi-cm4, to enable camera support (which
we're working on, Jean-Michel has posted a driver for the Unicam CSI-2
receiver to the linux-media mailing list, the ISP will follow), we need
the mux. Given that those two boards have a camera connector, I think it
makes sense to define the mux in a different file than
bcm2711-rpi-cm4-io.dts. The RTC node can stay in bcm2711-rpi-cm4-io.dts.

-- 
Regards,

Laurent Pinchart


From robert.hancock at calian.com  Tue Jan 18 15:05:14 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 23:05:14 +0000
Subject: [PATCH net v3 0/9] Xilinx axienet fixes
In-Reply-To: <20220118214132.357349-1-robert.hancock@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
Message-ID: <993dcdd75d3839b5952e8632ae278f723273df03.camel@calian.com>

On Tue, 2022-01-18 at 15:41 -0600, Robert Hancock wrote:
> Various fixes for the Xilinx AXI Ethernet driver.
> 
> Changed since v2:
> -added Reviewed-by tags, added some explanation to commit
> messages, no code changes
> 
> Changed since v1:
> -corrected a Fixes tag to point to mainline commit
> -split up reset changes into 3 patches
> -added ratelimit on netdev_warn in TX busy case
> 
> Robert Hancock (9):
>   net: axienet: increase reset timeout
>   net: axienet: Wait for PhyRstCmplt after core reset
>   net: axienet: reset core on initialization prior to MDIO access
>   net: axienet: add missing memory barriers
>   net: axienet: limit minimum TX ring size
>   net: axienet: Fix TX ring slot available check
>   net: axienet: fix number of TX ring slots for available check
>   net: axienet: fix for TX busy handling
>   net: axienet: increase default TX ring size to 128
> 
>  .../net/ethernet/xilinx/xilinx_axienet_main.c | 135 +++++++++++-------
>  1 file changed, 84 insertions(+), 51 deletions(-)
> 

FYI, for the netdev/cc_maintainers Patchwork check, I dropped Ariane Keller <
ariane.keller at tik.ee.ethz.ch> from the CC list as their mail was bouncing.

-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From sean.anderson at seco.com  Tue Jan 18 15:15:16 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 18 Jan 2022 18:15:16 -0500
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <79d6057a70dae09bcc30a35f608f51c5a768d097.camel@calian.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <CAKgpwJUMXk--4EaYOxAAtLJT85mDHRHMihr6n7y1HECN+gmBBw@mail.gmail.com>
 <79d6057a70dae09bcc30a35f608f51c5a768d097.camel@calian.com>
Message-ID: <4dd8aced-174c-03b9-87f3-70026c963f6e@seco.com>



On 1/17/22 6:49 PM, Robert Hancock wrote:
> On Mon, 2022-01-17 at 20:30 +0800, Jun Li wrote:
>> Sean Anderson <sean.anderson at seco.com> ?2022?1?15??? 10:11???
>> > This is a rework of patches 3-5 of [1]. It attempts to correctly program
>> > REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>> > we no longer need a special property duplicating this configuration,
>> > snps,ref-clock-period-ns is deprecated.
>> >
>> > Please test this! Patches 3/4 in this series have the effect of
>> > programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>> > the "ref" clock. I have build tested, but not much else.
>>
>> DWC3 databook states a *condition* for program those settings:
>>
>> This field must be programmed to a non-zero value only if
>> GFLADJ_REFCLK_LPM_SEL is set to '1' or GCTL.SOFITPSYNC is set to '1'.
>> The value is derived as follows:
>> FLADJ_REF_CLK_FLADJ=((125000/ref_clk_period_integer)-(125000/ref_clk_period))
>> * ref_clk_period where
>> ? the ref_clk_period_integer is the integer value of the ref_clk
>> period got by truncating the decimal (fractional) value that is
>> programmed in the GUCTL.REF_CLK_PERIOD field.
>> ? the ref_clk_period is the ref_clk period including the fractional value.
>>
>> So you may need a condition check, with that, only required users
>> are effected even with "ref" clock specified.
>>
>
> The Xilinx register documentation for this register in the DWC3 core (
> https://www.xilinx.com/html_docs/registers/ug1087/usb3_xhci___gfladj.html ) has
> the same description, but it is rather confusingly worded. I suspect what they
> really mean is that "this field only needs to be programmed if
> GFLADJ_REFCLK_LPM_SEL is set to '1' or GCTL.SOFITPSYNC is set to '1'", not
> "this field should only be programmed if GFLADJ_REFCLK_LPM_SEL is set to '1' or
> GCTL.SOFITPSYNC is set to '1'". I'm not sure if someone can confirm that
> interpretation is correct?

This is the interpretation I was using as well, since GUCTL.REFCLKPER
has similar documentation and it was always programmed before this
series.

> However, looking at that description a bit further, it looks like there are
> some other fields in that register which are dependent on the reference clock:
> GFLADJ_REFCLK_240MHZ_DECR (bits 30:24) and GFLADJ_REFCLK_240MHZDECR_PLS1 (bit
> 31). It looks like the Xilinx board I am using has those set properly, i.e. to
> 12 and 0 respectively (I'm guessing by hardware default, since I don't see
> anything in the FSBL psu_init code setting those), but it wouldn't hurt to
> ensure those fields are also set correctly.

I'll add those in v2.

--Sean


From robert.hancock at calian.com  Tue Jan 18 15:21:55 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 18 Jan 2022 23:21:55 +0000
Subject: [PATCH 0/6] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
In-Reply-To: <9b4f6122-a044-fac6-c5ba-e786cb1fc584@synopsys.com>
References: <20220114233904.907918-1-sean.anderson@seco.com>
 <87iluifxy1.fsf@tarshish>
 <7831a4f7-7c3f-4a2a-be73-38f2c40a123c@synopsys.com>
 <f28052d9-5dea-a05b-8745-09e4d237b539@seco.com>
 <f53ba815-f2ee-a558-73f3-06c5a43f5c5e@synopsys.com>
 <0aaeb0e3-1e10-df41-0b61-c10249ea5faa@seco.com>
 <9b4f6122-a044-fac6-c5ba-e786cb1fc584@synopsys.com>
Message-ID: <8e8094f148920388b81a2a58bd7cd85cd4316d92.camel@calian.com>

On Tue, 2022-01-18 at 21:10 +0000, Thinh Nguyen wrote:
> Hi Sean,
> 
> Sean Anderson wrote:
> > Hi Thinh,
> > 
> > On 1/18/22 3:00 PM, Thinh Nguyen wrote:
> > > Sean Anderson wrote:
> > > > Hi Thinh,
> > > > 
> > > > On 1/18/22 2:46 PM, Thinh Nguyen wrote:
> > > > > Hi Sean,
> > > > > 
> > > > > Baruch Siach wrote:
> > > > > > Hi Sean, Thinh,
> > > > > > 
> > > > > > On Fri, Jan 14 2022, Sean Anderson wrote:
> > > > > > > This is a rework of patches 3-5 of [1]. It attempts to correctly
> > > > > > > program
> > > > > > > REFCLKPER and REFCLK_FLADJ based on the reference clock
> > > > > > > frequency.
> > > > > > > Since
> > > > > > > we no longer need a special property duplicating this
> > > > > > > configuration,
> > > > > > > snps,ref-clock-period-ns is deprecated.
> > > > > > > 
> > > > > > > Please test this! Patches 3/4 in this series have the effect of
> > > > > > > programming REFCLKPER and REFCLK_FLADJ on boards which already
> > > > > > > configure
> > > > > > > the "ref" clock. I have build tested, but not much else.
> > > > > > > 
> > > > > > > [1]
> > > > > > > https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbdC4d2R$
> > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > > Thinh, you suggested the dedicated DT property for the reference
> > > > > > clock:
> > > > > > 
> > > > > > 
> > > > > > https://urldefense.com/v3/__https://lore.kernel.org/all/d5acb192-80b9-36f7-43f5-81f21c4e6ba0 at synopsys.com/__;!!A4F2R9G_pg!M3zKxDZC9a_etqzXo7GSEMTHRWfc1wR_84wwM4-fShiA35CsGcxcTEffHPbprbpOFmvX$
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > Can you comment on this series?
> > > > > > 
> > > > > 
> > > > > Unless there's a good way to pass this information for PCI devices,
> > > > > my
> > > > > opinion hasn't changed. (Btw, I don't think creating a dummy clock
> > > > > provider and its dummy ops is a good solution as seems to complicate
> > > > > and
> > > > > bloat the PCI glue drivers).
> > > > 
> > > > Can you explain your situation a bit more? I'm not sure how you can
> > > > access a device tree property but not add a fixed-rate clock.
> > > > 
> > > > --Sean
> > > 
> > > Currently for dwc3 pci devices, we have glue drivers that create a
> > > platform_device with specific properties to pass to the dwc3 core
> > > driver. Without a ref clock property, we would need another way to pass
> > > this information to the core driver or another way for the dwc3 core
> > > driver to check for specific pci device's properties and quirks.
> > 
> > The primary problem with the existing binding is that it does not
> > contain enough information to calculate the fractional period. With the
> > frequency, we can calculate the correct values for the registers without
> > needing an additional binding. So we need to transition to some kind of
> > frequency-based system. So perhaps we should add a "ref-clock-frequency"
> > property and use that as a default for when the clock is missing.
> > 
> 
> Not sure about others, but that's fine with me. The other solution is to
> rework the dwc3 drivers as Robert noted, but that requires some work.
> 

Seems reasonable enough for a short-term fix anyway.

> Thanks,
> Thinh
> 
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From yury.norov at gmail.com  Tue Jan 18 15:52:44 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 18 Jan 2022 15:52:44 -0800
Subject: [PATCH] vmap(): don't allow invalid pages
Message-ID: <20220118235244.540103-1-yury.norov@gmail.com>

vmap() takes struct page *pages as one of arguments, and user may provide
an invalid pointer which would lead to DABT at address translation later.

Currently, kernel checks the pages against NULL. In my case, however, the
address was not NULL, and was big enough so that the hardware generated
Address Size Abort on arm64.

Interestingly, this abort happens even if copy_from_kernel_nofault() is
used, which is quite inconvenient for debugging purposes. 

This patch adds a pfn_valid() check into vmap() path, so that invalid
mapping will not be created.

RFC: https://lkml.org/lkml/2022/1/18/815
v1: use pfn_valid() instead of adding an arch-specific
    arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 mm/vmalloc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d2a00ad4e1dd..a4134ee56b10 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
 			return -EBUSY;
 		if (WARN_ON(!page))
 			return -ENOMEM;
+		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
+			return -EINVAL;
 		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
 		(*nr)++;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
-- 
2.30.2



From seanjc at google.com  Tue Jan 18 16:07:44 2022
From: seanjc at google.com (Sean Christopherson)
Date: Wed, 19 Jan 2022 00:07:44 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
References: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
Message-ID: <YedWUJNnQK3HFrWC@google.com>

On Fri, Jan 14, 2022, Reiji Watanabe wrote:
> The restriction, with which KVM doesn't need to worry about the changes
> in the registers after KVM_RUN, could potentially protect or be useful
> to protect KVM and simplify future changes/maintenance of the KVM codes
> that consumes the values.

That sort of protection is definitely welcome, the previously mentioned CPUID mess
on x86 would have benefit greatly by KVM being restrictive in the past.  That said,
hooking KVM_RUN is likely the wrong way to go about implementing any restrictions.
Running a vCPU is where much of the vCPU's state is explicitly consumed, but it's
all too easy for KVM to implicity/indirectly consume state via a different ioctl(),
e.g. if there are side effects that are visible in other registers, than an update
can also be visible to userspace via KVM_{G,S}ET_{S,}REGS, at which point disallowing
modifying state after KVM_RUN but not after reading/writing regs is arbitrary and
inconsitent.

If possible, preventing modification if kvm->created_vcpus > 0 is ideal as it's
a relatively common pattern in KVM, and provides a clear boundary to userpace
regarding what is/isn't allowed.


From sean.anderson at seco.com  Tue Jan 18 16:24:30 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 18 Jan 2022 19:24:30 -0500
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
Message-ID: <20220119002438.106079-1-sean.anderson@seco.com>

This is a rework of patches 3-5 of [1]. It attempts to correctly program
REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
we no longer need a special property duplicating this configuration,
snps,ref-clock-period-ns is deprecated.

Please test this! Patches 3/4 in this series have the effect of
programming REFCLKPER and REFCLK_FLADJ on boards which already configure
the "ref" clock. I have build tested, but not much else.

[1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/

Changes in v2:
- Document clock members
- Also program GFLADJ.240MHZDECR
- Don't program GFLADJ if the version is < 2.50a
- Add snps,ref-clock-frequency-hz property for ACPI

Sean Anderson (7):
  dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
  usb: dwc3: Get clocks individually
  usb: dwc3: Calculate REFCLKPER based on reference clock
  usb: dwc3: Program GFLADJ
  usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
  arm64: dts: zynqmp: Move USB clocks to dwc3 node
  arm64: dts: ipq6018: Use reference clock to set dwc3 period

 .../devicetree/bindings/usb/snps,dwc3.yaml    |   7 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi         |   3 +-
 .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |   4 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |   4 +-
 drivers/usb/dwc3/core.c                       | 112 +++++++++++++++---
 drivers/usb/dwc3/core.h                       |  17 ++-
 6 files changed, 120 insertions(+), 27 deletions(-)

-- 
2.25.1



From sean.anderson at seco.com  Tue Jan 18 16:24:36 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Tue, 18 Jan 2022 19:24:36 -0500
Subject: [PATCH v2 6/7] arm64: dts: zynqmp: Move USB clocks to dwc3 node
In-Reply-To: <20220119002438.106079-1-sean.anderson@seco.com>
References: <20220119002438.106079-1-sean.anderson@seco.com>
Message-ID: <20220119002438.106079-7-sean.anderson@seco.com>

These clocks are not used by the dwc3-xilinx driver except to
enable/disable them. Move them to the dwc3 node so its driver can use
them to configure the reference clock period.

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
---

(no changes since v1)

 arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 4 ++--
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
index 1e0b1bca7c94..8493dd7d5f1f 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -223,11 +223,11 @@ &uart1 {
 	clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
 };
 
-&usb0 {
+&dwc3_0 {
 	clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
-&usb1 {
+&dwc3_1 {
 	clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 74e66443e4ce..ba68fb8529ee 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -811,7 +811,6 @@ usb0: usb at ff9d0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9d0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_0>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
@@ -825,6 +824,7 @@ dwc3_0: usb at fe200000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 65 4>, <0 69 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x860>;
 				snps,quirk-frame-length-adjustment = <0x20>;
@@ -838,7 +838,6 @@ usb1: usb at ff9e0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9e0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_1>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
@@ -852,6 +851,7 @@ dwc3_1: usb at fe300000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 70 4>, <0 74 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x861>;
 				snps,quirk-frame-length-adjustment = <0x20>;
-- 
2.25.1



From kuba at kernel.org  Tue Jan 18 16:50:23 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 18 Jan 2022 16:50:23 -0800
Subject: [PATCH 0/2] net: stmmac: dwmac-visconti: Fix bit definitions
 and clock configuration for RMII mode
In-Reply-To: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220118165023.559dfe3b@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Tue, 18 Jan 2022 14:39:48 +0900 Yuji Ishikawa wrote:
> This series is a fix for RMII/MII operation mode of the dwmac-visconti driver.
> It is composed of two parts:
> 
> * 1/2: fix constant definitions for cleared bits in ETHER_CLK_SEL register
> * 2/2: fix configuration of ETHER_CLK_SEL register for running in RMII operation mode.

Please add appropriate Fixes tag pointing to the commits where the
buggy code was introduced, even if it's the initial commit adding 
the driver.


From willy at infradead.org  Tue Jan 18 16:51:27 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 00:51:27 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <20220118235244.540103-1-yury.norov@gmail.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
Message-ID: <Yedgj+Lo2eru8197@casper.infradead.org>

On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer which would lead to DABT at address translation later.

Could we spell out 'DABT'?  Presumably that's an ARM-specific thing.
Just like we don't say #PF for Intel page faults, I think this is
probably a 'data abort'?

> Currently, kernel checks the pages against NULL. In my case, however, the
> address was not NULL, and was big enough so that the hardware generated
> Address Size Abort on arm64.
> 
> Interestingly, this abort happens even if copy_from_kernel_nofault() is
> used, which is quite inconvenient for debugging purposes. 
> 
> This patch adds a pfn_valid() check into vmap() path, so that invalid
> mapping will not be created.
> 
> RFC: https://lkml.org/lkml/2022/1/18/815
> v1: use pfn_valid() instead of adding an arch-specific
>     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
> 
> Signed-off-by: Yury Norov <yury.norov at gmail.com>

Suggested-by: Matthew Wilcox (Oracle) <willy at infradead.org>

> ---
>  mm/vmalloc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d2a00ad4e1dd..a4134ee56b10 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
>  			return -EBUSY;
>  		if (WARN_ON(!page))
>  			return -ENOMEM;
> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> +			return -EINVAL;
>  		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
>  		(*nr)++;
>  	} while (pte++, addr += PAGE_SIZE, addr != end);
> -- 
> 2.30.2
> 


From gshan at redhat.com  Tue Jan 18 17:05:51 2022
From: gshan at redhat.com (Gavin Shan)
Date: Wed, 19 Jan 2022 09:05:51 +0800
Subject: [PATCH v3] drivers/virtio: Enable virtio mem for ARM64
Message-ID: <20220119010551.181405-1-gshan@redhat.com>

This enables virtio-mem device support by allowing to enable the
corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
architecture.

Signed-off-by: Gavin Shan <gshan at redhat.com>
Acked-by: David Hildenbrand <david at redhat.com>
Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Acked-by: Michael S. Tsirkin <mst at redhat.com>
---
v3: Pick ack-by tags from Jonathan and Michael
---
 drivers/virtio/Kconfig | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index 34f80b7a8a64..74c8b0c7bc33 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -106,7 +106,7 @@ config VIRTIO_BALLOON
 config VIRTIO_MEM
 	tristate "Virtio mem driver"
 	default m
-	depends on X86_64
+	depends on X86_64 || ARM64
 	depends on VIRTIO
 	depends on MEMORY_HOTPLUG
 	depends on MEMORY_HOTREMOVE
@@ -116,8 +116,9 @@ config VIRTIO_MEM
 	 This driver provides access to virtio-mem paravirtualized memory
 	 devices, allowing to hotplug and hotunplug memory.
 
-	 This driver was only tested under x86-64, but should theoretically
-	 work on all architectures that support memory hotplug and hotremove.
+	 This driver was only tested under x86-64 and arm64, but should
+	 theoretically work on all architectures that support memory hotplug
+	 and hotremove.
 
 	 If unsure, say M.
 
-- 
2.23.0



From gshan at redhat.com  Tue Jan 18 17:08:08 2022
From: gshan at redhat.com (Gavin Shan)
Date: Wed, 19 Jan 2022 09:08:08 +0800
Subject: [PATCH v2] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <20220118110512-mutt-send-email-mst@kernel.org>
References: <20220118084858.175305-1-gshan@redhat.com>
 <2f0d1a5f-7e75-04b1-f2a1-f52385dae3b5@redhat.com>
 <20220118110512-mutt-send-email-mst@kernel.org>
Message-ID: <883104a2-02a9-fc39-3898-9abdfb4490e1@redhat.com>

On 1/19/22 12:05 AM, Michael S. Tsirkin wrote:
> On Tue, Jan 18, 2022 at 05:38:20PM +0800, Gavin Shan wrote:
>> On 1/18/22 4:48 PM, Gavin Shan wrote:
>>> This enables virtio-mem device support by allowing to enable the
>>> corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
>>> architecture.
>>>
>>> Signed-off-by: Gavin Shan <gshan at redhat.com>
>>> Acked-by: David Hildenbrand <david at redhat.com>
>>> ---
>>> v2: Improved the comments about the kernel config option (David)
>>> ---
>>>    drivers/virtio/Kconfig | 7 ++++---
>>>    1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> My git-sendemail should have been broken. A list of receivers are
>> dropped automatically though they were explicitly specified, but
>> linux-arm-kernel at lists.infradead.org was missed to be copied.
>> Fixing all of them through thunderbird :)
>>
>> Thanks,
>> Gavin
> 
> Pls bounce the original patch to me so I can queue it.
> 

Yes, Please merge the following one, which was just posted. The ack-by
tags from Jonathan and you are also added to v3.

[PATCH v3] drivers/virtio: Enable virtio mem for ARM64

Thanks,
Gavin

> 
>>> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
>>> index 34f80b7a8a64..74c8b0c7bc33 100644
>>> --- a/drivers/virtio/Kconfig
>>> +++ b/drivers/virtio/Kconfig
>>> @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
>>>    config VIRTIO_MEM
>>>    	tristate "Virtio mem driver"
>>>    	default m
>>> -	depends on X86_64
>>> +	depends on X86_64 || ARM64
>>>    	depends on VIRTIO
>>>    	depends on MEMORY_HOTPLUG
>>>    	depends on MEMORY_HOTREMOVE
>>> @@ -116,8 +116,9 @@ config VIRTIO_MEM
>>>    	 This driver provides access to virtio-mem paravirtualized memory
>>>    	 devices, allowing to hotplug and hotunplug memory.
>>> -	 This driver was only tested under x86-64, but should theoretically
>>> -	 work on all architectures that support memory hotplug and hotremove.
>>> +	 This driver was only tested under x86-64 and arm64, but should
>>> +	 theoretically work on all architectures that support memory hotplug
>>> +	 and hotremove.
>>>    	 If unsure, say M.
>>>
> 



From yury.norov at gmail.com  Tue Jan 18 17:21:09 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 18 Jan 2022 17:21:09 -0800
Subject: [PATCH v2] vmap(): don't allow invalid pages
Message-ID: <20220119012109.551931-1-yury.norov@gmail.com>

vmap() takes struct page *pages as one of arguments, and user may provide
an invalid pointer which would lead to data abort at address translation
later.

Currently, kernel checks the pages against NULL. In my case, however, the
address was not NULL, and was big enough so that the hardware generated
Address Size Abort on arm64.

Interestingly, this abort happens even if copy_from_kernel_nofault() is
used, which is quite inconvenient for debugging purposes. 

This patch adds a pfn_valid() check into vmap() path, so that invalid
mapping will not be created.

RFC: https://lkml.org/lkml/2022/1/18/815
v1:  https://lkml.org/lkml/2022/1/18/1026
v2:  Patch description changed.

Suggested-by: Matthew Wilcox (Oracle) <willy at infradead.org>
Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 mm/vmalloc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d2a00ad4e1dd..a4134ee56b10 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
 			return -EBUSY;
 		if (WARN_ON(!page))
 			return -ENOMEM;
+		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
+			return -EINVAL;
 		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
 		(*nr)++;
 	} while (pte++, addr += PAGE_SIZE, addr != end);
-- 
2.30.2



From biao.huang at mediatek.com  Tue Jan 18 17:21:15 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Wed, 19 Jan 2022 09:21:15 +0800
Subject: [PATCH net-next v12 7/7] net: dt-bindings: dwmac: add support
 for mt8195
In-Reply-To: <1642433742.934070.3923086.nullmailer@robh.at.kernel.org>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
 <20220117070706.17853-8-biao.huang@mediatek.com>
 <1642433742.934070.3923086.nullmailer@robh.at.kernel.org>
Message-ID: <c6f990fdf047eb90acaeb29f9f9b2941d6b7bf30.camel@mediatek.com>

Dear Rob,
	Thanks for your comments.

	If patch "[PATCH net-next v12 4/7] arm64: dts: mt2712: update
ethernet device node" is applied with dt-binding patches, "make
dtbs_check" will not report 
such warnings.
	Please review it kindly, thanks.

On Mon, 2022-01-17 at 09:35 -0600, Rob Herring wrote:
> On Mon, 17 Jan 2022 15:07:06 +0800, Biao Huang wrote:
> > Add binding document for the ethernet on mt8195.
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > ---
> >  .../bindings/net/mediatek-dwmac.yaml          | 28
> > ++++++++++++++++---
> >  1 file changed, 24 insertions(+), 4 deletions(-)
> > 
> 
> Running 'make dtbs_check' with the schema in this patch gives the
> following warnings. Consider if they are expected or the schema is
> incorrect. These may not be new warnings.
> 
> Note that it is not yet a requirement to have 0 warnings for
> dtbs_check.
> This will change in the future.
> 
> Full log is available here: 
> https://patchwork.ozlabs.org/patch/1580608
> 
> 
> ethernet at 1101c000: clock-names: ['axi', 'apb', 'mac_main', 'ptp_ref']
> is too short
> 	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml
> 
> ethernet at 1101c000: clocks: [[27, 34], [27, 37], [6, 154], [6, 155]]
> is too short
> 	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml
> 
> ethernet at 1101c000: compatible: ['mediatek,mt2712-gmac'] does not
> contain items matching the given schema
> 	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml
> 
> ethernet at 1101c000: compatible: 'oneOf' conditional failed, one must
> be fixed:
> 	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml
> 
> ethernet at 1101c000: Unevaluated properties are not allowed
> ('compatible', 'reg', 'interrupts', 'interrupt-names', 'mac-address', 
> 'clock-names', 'clocks', 'power-domains', 'snps,axi-config',
> 'snps,mtl-rx-config', 'snps,mtl-tx-config', 'snps,txpbl',
> 'snps,rxpbl', 'clk_csr', 'phy-mode', 'phy-handle', 'snps,reset-gpio', 
> 'mdio' were unexpected)
> 	arch/arm64/boot/dts/mediatek/mt2712-evb.dt.yaml
> 

From pgwipeout at gmail.com  Tue Jan 18 17:26:37 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Tue, 18 Jan 2022 20:26:37 -0500
Subject: [PATCH v5 1/4] Input: Add driver for Cypress Generation 5
 touchscreen
In-Reply-To: <20220109115331.388633-2-alistair@alistair23.me>
References: <20220109115331.388633-2-alistair@alistair23.me>
Message-ID: <20220119012637.1713748-1-pgwipeout@gmail.com>

Good Evening,

I tried using this with a cypress tma448 and thought there was an issue
with the driver.
Further investigation found the tma448 in question had no configuration
burned into it, thus max size and pressure are zero.

I've added the patch below to extend the driver with device tree
overrides.
Unfortunately device_property_read_u16 is broken on arm64 currently, as
it returns zero.

Also, with this patch, the driver works spectacularly on my broken touch
screen.
As such-
Tested-by: Peter Geis <pgwipeout at gmail.com>

[PATCH] Input: cyttsp5: support touchscreen device tree overrides

It is possible for the cyttsp5 chip to not have a configuration burned
to it.
This leads to a sitatuion where all calibration values return zero,
leading to a broken touchscreen configuration.

The current driver does not support utilizing overrides from the device
tree.
Extend the driver to support this, and permit it to do some basic sanity
checking of the values for the touchscreen and abort if they are
invalid.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 drivers/input/touchscreen/cyttsp5.c | 62 ++++++++++++++++++++++++++---
 1 file changed, 57 insertions(+), 5 deletions(-)

diff --git a/drivers/input/touchscreen/cyttsp5.c b/drivers/input/touchscreen/cyttsp5.c
index 3ac45108090c..e837985d199a 100644
--- a/drivers/input/touchscreen/cyttsp5.c
+++ b/drivers/input/touchscreen/cyttsp5.c
@@ -507,15 +507,66 @@ static int cyttsp5_get_sysinfo_regs(struct cyttsp5 *ts)
 	struct cyttsp5_sensing_conf_data_dev *scd_dev =
 		(struct cyttsp5_sensing_conf_data_dev *)
 		&ts->response_buf[HID_SYSINFO_SENSING_OFFSET];
+	u32 tmp;
 
 	cyttsp5_si_get_btn_data(ts);
 
 	scd->max_tch = scd_dev->max_num_of_tch_per_refresh_cycle;
-	scd->res_x = get_unaligned_le16(&scd_dev->res_x);
-	scd->res_y = get_unaligned_le16(&scd_dev->res_y);
-	scd->max_z = get_unaligned_le16(&scd_dev->max_z);
-	scd->len_x = get_unaligned_le16(&scd_dev->len_x);
-	scd->len_y = get_unaligned_le16(&scd_dev->len_y);
+
+	if (scd->max_tch == 0) {
+		dev_dbg(ts->dev, "Max touch points cannot be zero\n");
+		scd->max_tch = 2;
+	}
+
+	if(device_property_read_u32(ts->dev, "touchscreen-size-x", &tmp))
+		scd->res_x = get_unaligned_le16(&scd_dev->res_x);
+	else
+		scd->res_x = tmp;
+
+	if (scd->res_x == 0) {
+		dev_err(ts->dev, "ABS_X cannot be zero\n");
+		return -ENODATA;
+	}
+
+	if(device_property_read_u32(ts->dev, "touchscreen-size-y", &tmp))
+		scd->res_y = get_unaligned_le16(&scd_dev->res_y);
+	else
+		scd->res_y = tmp;
+
+	if (scd->res_y == 0) {
+		dev_err(ts->dev, "ABS_Y cannot be zero\n");
+		return -ENODATA;
+	}
+
+	if(device_property_read_u32(ts->dev, "touchscreen-max-pressure", &tmp))
+		scd->max_z = get_unaligned_le16(&scd_dev->max_z);
+	else
+		scd->max_z = tmp;
+
+	if (scd->max_z == 0) {
+		dev_err(ts->dev, "ABS_PRESSURE cannot be zero\n");
+		return -ENODATA;
+	}
+
+	if(device_property_read_u32(ts->dev, "touchscreen-x-mm", &tmp))
+		scd->len_x = get_unaligned_le16(&scd_dev->len_x);
+	else
+		scd->len_x = tmp;
+
+	if (scd->len_x == 0) {
+		dev_dbg(ts->dev, "Touchscreen size x cannot be zero\n");
+		scd->len_x = scd->res_x + 1;
+	}
+
+	if(device_property_read_u32(ts->dev, "touchscreen-y-mm", &tmp))
+		scd->len_y = get_unaligned_le16(&scd_dev->len_y);
+	else
+		scd->len_y = tmp;
+
+	if (scd->len_y == 0) {
+		dev_dbg(ts->dev, "Touchscreen size y cannot be zero\n");
+		scd->len_y = scd->res_y + 1;
+	}
 
 	return 0;
 }
@@ -877,6 +928,7 @@ static int cyttsp5_i2c_probe(struct i2c_client *client,
 
 static const struct of_device_id cyttsp5_of_match[] = {
 	{ .compatible = "cypress,tt21000", },
+	{ .compatible = "cypress,tma448", },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, cyttsp5_of_match);
-- 
2.25.1



From biao.huang at mediatek.com  Tue Jan 18 17:24:28 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Wed, 19 Jan 2022 09:24:28 +0800
Subject: [PATCH net-next v12 4/7] arm64: dts: mt2712: update ethernet
 device node
In-Reply-To: <20220117070706.17853-5-biao.huang@mediatek.com>
References: <20220117070706.17853-1-biao.huang@mediatek.com>
 <20220117070706.17853-5-biao.huang@mediatek.com>
Message-ID: <6d9edd18e64a973265b92d98395f8ce7470e59e6.camel@mediatek.com>

Dear Matthias,

	Any comments about this dts patch?
	Thanks in advance.

Regards!
Biao

On Mon, 2022-01-17 at 15:07 +0800, Biao Huang wrote:
> Since there are some changes in ethernet driver:
> update ethernet device node in dts to accommodate to it.
> 
> 1. stmmac_probe_config_dt() in stmmac_platform.c will initialize
> specified
>    parameters according to compatible string "snps,dwmac-4.20a",
> then,
>    dwmac-mediatek.c can skip the initialization if add compatible
> string
>    "snps,dwmac-4.20a" in eth device node.
> 2. commit 882007ed7832 ("net-next: dt-binding: dwmac-mediatek: add
> more
>    description for RMII") added rmii internal support, we should add
>    corresponding clocks/clocks-names in eth device node.
> 3. add "snps,reset-delays-us = <0 10000 10000>;" to ensure reset
> delay
>    can meet PHY requirement.
> 
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/mt2712-evb.dts |  1 +
>  arch/arm64/boot/dts/mediatek/mt2712e.dtsi   | 14 +++++++++-----
>  2 files changed, 10 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> index 7d369fdd3117..11aa135aa0f3 100644
> --- a/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> +++ b/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
> @@ -110,6 +110,7 @@ &eth {
>  	phy-handle = <&ethernet_phy0>;
>  	mediatek,tx-delay-ps = <1530>;
>  	snps,reset-gpio = <&pio 87 GPIO_ACTIVE_LOW>;
> +	snps,reset-delays-us = <0 10000 10000>;
>  	pinctrl-names = "default", "sleep";
>  	pinctrl-0 = <&eth_default>;
>  	pinctrl-1 = <&eth_sleep>;
> diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> index a9cca9c146fd..9e850e04fffb 100644
> --- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
> @@ -726,7 +726,7 @@ queue2 {
>  	};
>  
>  	eth: ethernet at 1101c000 {
> -		compatible = "mediatek,mt2712-gmac";
> +		compatible = "mediatek,mt2712-gmac", "snps,dwmac-
> 4.20a";
>  		reg = <0 0x1101c000 0 0x1300>;
>  		interrupts = <GIC_SPI 237 IRQ_TYPE_LEVEL_LOW>;
>  		interrupt-names = "macirq";
> @@ -734,15 +734,19 @@ eth: ethernet at 1101c000 {
>  		clock-names = "axi",
>  			      "apb",
>  			      "mac_main",
> -			      "ptp_ref";
> +			      "ptp_ref",
> +			      "rmii_internal";
>  		clocks = <&pericfg CLK_PERI_GMAC>,
>  			 <&pericfg CLK_PERI_GMAC_PCLK>,
>  			 <&topckgen CLK_TOP_ETHER_125M_SEL>,
> -			 <&topckgen CLK_TOP_ETHER_50M_SEL>;
> +			 <&topckgen CLK_TOP_ETHER_50M_SEL>,
> +			 <&topckgen CLK_TOP_ETHER_50M_RMII_SEL>;
>  		assigned-clocks = <&topckgen CLK_TOP_ETHER_125M_SEL>,
> -				  <&topckgen CLK_TOP_ETHER_50M_SEL>;
> +				  <&topckgen CLK_TOP_ETHER_50M_SEL>,
> +				  <&topckgen
> CLK_TOP_ETHER_50M_RMII_SEL>;
>  		assigned-clock-parents = <&topckgen
> CLK_TOP_ETHERPLL_125M>,
> -					 <&topckgen CLK_TOP_APLL1_D3>;
> +					 <&topckgen CLK_TOP_APLL1_D3>,
> +					 <&topckgen
> CLK_TOP_ETHERPLL_50M>;
>  		power-domains = <&scpsys MT2712_POWER_DOMAIN_AUDIO>;
>  		mediatek,pericfg = <&pericfg>;
>  		snps,axi-config = <&stmmac_axi_setup>;

From peng.fan at nxp.com  Tue Jan 18 17:50:44 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 01:50:44 +0000
Subject: [PATCH 1/2] dt-bindings: serial: fsl-lpuart: Drop i.MX8QXP
 backwards compatibility
In-Reply-To: <20220118135918.2126010-1-abel.vesa@nxp.com>
References: <20220118135918.2126010-1-abel.vesa@nxp.com>
Message-ID: <DU0PR04MB9417F3799FB34E7838E9741688599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 1/2] dt-bindings: serial: fsl-lpuart: Drop i.MX8QXP backwards
> compatibility
> 
> Drop the i.MX8QXP backwards compatibility with i.MX7ULP since they differ
> from clocks handling point of view.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>

Reviewed-by: Peng Fan <peng.fan at nxp.com>

> ---
>  Documentation/devicetree/bindings/serial/fsl-lpuart.yaml | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
> b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
> index aa83cbf56d59..ff364bd0fbac 100644
> --- a/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
> +++ b/Documentation/devicetree/bindings/serial/fsl-lpuart.yaml
> @@ -20,11 +20,10 @@ properties:
>            - fsl,ls1021a-lpuart
>            - fsl,ls1028a-lpuart
>            - fsl,imx7ulp-lpuart
> +          - fsl,imx8qxp-lpuart
>            - fsl,imxrt1050-lpuart
>        - items:
> -          - enum:
> -              - fsl,imx8qxp-lpuart
> -              - fsl,imx8ulp-lpuart
> +          - const: fsl,imx8ulp-lpuart
>            - const: fsl,imx7ulp-lpuart
>        - items:
>            - enum:
> --
> 2.31.1



From guodong.liu at mediatek.com  Tue Jan 18 17:42:46 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Wed, 19 Jan 2022 09:42:46 +0800
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix
 PIN_CONFIG_BIAS_DISABLE readback
In-Reply-To: <20220111112244.1483783-3-wenst@chromium.org>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-3-wenst@chromium.org>
Message-ID: <eca4a0c18fe75536c8276410628b9459c040dce2.camel@mediatek.com>

-----Original Message-----
From: Chen-Yu Tsai <wenst at chromium.org>
To: Sean Wang <sean.wang at kernel.org>, Linus Walleij <
linus.walleij at linaro.org>, Matthias Brugger <matthias.bgg at gmail.com>
Cc: Chen-Yu Tsai <wenst at chromium.org>, 
linux-mediatek at lists.infradead.org, linux-gpio at vger.kernel.org, 
linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
Zhiyong Tao <zhiyong.tao at mediatek.com>, Guodong Liu <
guodong.liu at mediatek.com>
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix
PIN_CONFIG_BIAS_DISABLE readback
Date: Tue, 11 Jan 2022 19:22:39 +0800

When reading back pin bias settings, if the pin is not in a
bias-disabled state, the function should return -EINVAL.

Fix this in the mediatek-paris pinctrl library so that the read back
state is not littered with bogus a "input bias disabled" combined with
"pull up" or "pull down" states.

Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that
implements the vendor dt-bindings")
Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/pinctrl/mediatek/pinctrl-paris.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c
b/drivers/pinctrl/mediatek/pinctrl-paris.c
index f9f9110f2107..1ca598ea7ba7 100644
--- a/drivers/pinctrl/mediatek/pinctrl-paris.c
+++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
@@ -97,8 +97,8 @@ static int mtk_pinconf_get(struct pinctrl_dev
*pctldev,
 			if (err)
 				goto out;
 			if (param == PIN_CONFIG_BIAS_DISABLE) {
-				if (ret == MTK_PUPD_SET_R1R0_00)
-					ret = MTK_DISABLE;
+				if (ret != MTK_PUPD_SET_R1R0_00)
+					err = -EINVAL;
Hi Chen-Yu

When tht API "hw->soc->bias_get_combo(hw, desc, &pullup, &ret)" is
called,
The ret vaule of may be MTK_DISABLE OR MTK_PUPD_SET_R1R0_00 or  (pullen
== 0),  All those cases are expected to be as "bias-disable".
We advices to keep original code,

+				if (ret == MTK_PUPD_SET_R1R0_00)
+	
				ret = MTK_DISABLE;
+				if (ret != MTK_DISABLE)
+					err = -EINVAL;

Thanks
 			} else if (param == PIN_CONFIG_BIAS_PULL_UP) {
 				/* When desire to get pull-up value,
return
 				 *  error if current setting is pull-
down

From peng.fan at nxp.com  Tue Jan 18 17:50:57 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 01:50:57 +0000
Subject: [PATCH 2/2] arm64: dts: imx8qxp-ss-adma: Drop fsl, imx7ulp-lpuart
 comaptible
In-Reply-To: <20220118135918.2126010-2-abel.vesa@nxp.com>
References: <20220118135918.2126010-1-abel.vesa@nxp.com>
 <20220118135918.2126010-2-abel.vesa@nxp.com>
Message-ID: <DU0PR04MB941710BD11CD7BA2EC25667888599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 2/2] arm64: dts: imx8qxp-ss-adma: Drop fsl,imx7ulp-lpuart
> comaptible
> 
> The driver differs from clocks point of view, so the i.MX8QXP is not backwards
> compatible with i.MX7ULP.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>

Reviewed-by: Peng Fan <peng.fan at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
> b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
> index dc1daa8dc72f..7bae516004bf 100644
> --- a/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8qxp-ss-adma.dtsi
> @@ -5,19 +5,19 @@
>   */
> 
>  &lpuart0 {
> -	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	compatible = "fsl,imx8qxp-lpuart";
>  };
> 
>  &lpuart1 {
> -	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	compatible = "fsl,imx8qxp-lpuart";
>  };
> 
>  &lpuart2 {
> -	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	compatible = "fsl,imx8qxp-lpuart";
>  };
> 
>  &lpuart3 {
> -	compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	compatible = "fsl,imx8qxp-lpuart";
>  };
> 
>  &i2c0 {
> --
> 2.31.1



From robh at kernel.org  Tue Jan 18 17:52:53 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 18 Jan 2022 19:52:53 -0600
Subject: [PATCH] dt-bindings: i2c: imx: Make each example a separate entry
Message-ID: <20220119015253.2437352-1-robh@kernel.org>

Each independent example should be a separate entry. This allows for
'interrupts' to have different cell sizes.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/i2c/i2c-imx.yaml | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
index c167958ae2a9..01720e338b4c 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
+++ b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
@@ -88,9 +88,7 @@ unevaluatedProperties: false
 examples:
   - |
     #include <dt-bindings/clock/imx5-clock.h>
-    #include <dt-bindings/clock/vf610-clock.h>
-    #include <dt-bindings/gpio/gpio.h>
-    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
 
     i2c at 83fc4000 {
         compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
@@ -99,6 +97,9 @@ examples:
         clocks = <&clks IMX5_CLK_I2C2_GATE>;
     };
 
+  - |
+    #include <dt-bindings/clock/vf610-clock.h>
+
     i2c at 40066000 {
         compatible = "fsl,vf610-i2c";
         reg = <0x40066000 0x1000>;
-- 
2.32.0



From robh at kernel.org  Tue Jan 18 17:53:25 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 18 Jan 2022 19:53:25 -0600
Subject: [PATCH] dt-bindings: Drop unnecessary pinctrl properties
Message-ID: <20220119015325.2438277-1-robh@kernel.org>

For a single pinctrl mode, it is not necessary to define pinctrl
properties as the tools always allow pinctrl properties.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../display/rockchip/rockchip,rk3066-hdmi.yaml         |  8 --------
 Documentation/devicetree/bindings/input/gpio-keys.yaml |  6 ------
 .../devicetree/bindings/pinctrl/cirrus,lochnagar.yaml  |  9 ---------
 .../devicetree/bindings/pinctrl/cirrus,madera.yaml     | 10 ----------
 .../devicetree/bindings/sound/samsung-i2s.yaml         |  6 ------
 5 files changed, 39 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml
index 008c144257cb..1a68a940d165 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,rk3066-hdmi.yaml
@@ -26,14 +26,6 @@ properties:
   clock-names:
     const: hclk
 
-  pinctrl-0:
-    maxItems: 2
-
-  pinctrl-names:
-    const: default
-    description:
-      Switch the iomux for the HPD/I2C pins to HDMI function.
-
   power-domains:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/input/gpio-keys.yaml b/Documentation/devicetree/bindings/input/gpio-keys.yaml
index dbe7ecc19ccb..7fe1966ea28a 100644
--- a/Documentation/devicetree/bindings/input/gpio-keys.yaml
+++ b/Documentation/devicetree/bindings/input/gpio-keys.yaml
@@ -88,12 +88,6 @@ patternProperties:
             which can be disabled to suppress events from the button.
           type: boolean
 
-        pinctrl-0:
-          maxItems: 1
-
-        pinctrl-names:
-          maxItems: 1
-
       required:
         - linux,code
 
diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,lochnagar.yaml b/Documentation/devicetree/bindings/pinctrl/cirrus,lochnagar.yaml
index 80020539c3bb..5cd512b7d5ba 100644
--- a/Documentation/devicetree/bindings/pinctrl/cirrus,lochnagar.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,lochnagar.yaml
@@ -51,15 +51,6 @@ properties:
       appropriate of the LOCHNAGARx_PIN_NUM_GPIOS define, see [3].
     maxItems: 1
 
-  pinctrl-0:
-    description:
-      A phandle to the default pinctrl state.
-
-  pinctrl-names:
-    description:
-      A pinctrl state named "default" must be defined.
-    const: default
-
   pin-settings:
     type: object
     patternProperties:
diff --git a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
index e50d7ad5c229..c85f759ae5a3 100644
--- a/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera.yaml
@@ -30,16 +30,6 @@ description: |
     Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
 
 properties:
-  pinctrl-0:
-    description:
-      A phandle to the node containing the subnodes containing default
-      configurations.
-
-  pinctrl-names:
-    description:
-      A pinctrl state named "default" must be defined.
-    const: default
-
   pin-settings:
     description:
       One subnode is required to contain the default settings. It
diff --git a/Documentation/devicetree/bindings/sound/samsung-i2s.yaml b/Documentation/devicetree/bindings/sound/samsung-i2s.yaml
index 2e3628ef48df..84c4d6cba521 100644
--- a/Documentation/devicetree/bindings/sound/samsung-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/samsung-i2s.yaml
@@ -110,12 +110,6 @@ properties:
       Internal DMA register base address of the audio
       subsystem (used in secondary sound source).
 
-  pinctrl-0:
-    description: Should specify pin control groups used for this controller.
-
-  pinctrl-names:
-    const: default
-
   power-domains:
     maxItems: 1
 
-- 
2.32.0



From robh at kernel.org  Tue Jan 18 17:56:26 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 18 Jan 2022 19:56:26 -0600
Subject: [PATCH] dt-bindings: Fix array schemas encoded as matrices
Message-ID: <20220119015627.2443334-1-robh@kernel.org>

The YAML DT encoding has leaked into some array properties. Properties
which are defined as an array should have a schema that's just an array.
That means there should only be a single level of 'minItems',
'maxItems', and/or 'items'.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../bindings/media/nxp,imx7-mipi-csi2.yaml    | 12 ++--
 .../bindings/media/nxp,imx8mq-mipi-csi2.yaml  | 12 ++--
 .../bindings/net/can/bosch,m_can.yaml         | 52 ++++++++--------
 .../bindings/net/ethernet-controller.yaml     | 59 +++++++++----------
 4 files changed, 62 insertions(+), 73 deletions(-)

diff --git a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
index 1ef849dc74d7..e2e6e9aa0fe6 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx7-mipi-csi2.yaml
@@ -81,14 +81,12 @@ properties:
               data-lanes:
                 description:
                   Note that 'fsl,imx7-mipi-csi2' only supports up to 2 data lines.
+                minItems: 1
                 items:
-                  minItems: 1
-                  maxItems: 4
-                  items:
-                    - const: 1
-                    - const: 2
-                    - const: 3
-                    - const: 4
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
 
             required:
               - data-lanes
diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
index d13c9233a7c8..2a14e3b0e004 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-mipi-csi2.yaml
@@ -87,14 +87,12 @@ properties:
 
             properties:
               data-lanes:
+                minItems: 1
                 items:
-                  minItems: 1
-                  maxItems: 4
-                  items:
-                    - const: 1
-                    - const: 2
-                    - const: 3
-                    - const: 4
+                  - const: 1
+                  - const: 2
+                  - const: 3
+                  - const: 4
 
             required:
               - data-lanes
diff --git a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
index fb547e26c676..401ab7cdb379 100644
--- a/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
+++ b/Documentation/devicetree/bindings/net/can/bosch,m_can.yaml
@@ -76,33 +76,31 @@ properties:
       M_CAN user manual for details.
     $ref: /schemas/types.yaml#/definitions/int32-array
     items:
-      items:
-        - description: The 'offset' is an address offset of the Message RAM where
-            the following elements start from. This is usually set to 0x0 if
-            you're using a private Message RAM.
-          default: 0
-        - description: 11-bit Filter 0-128 elements / 0-128 words
-          minimum: 0
-          maximum: 128
-        - description: 29-bit Filter 0-64 elements / 0-128 words
-          minimum: 0
-          maximum: 64
-        - description: Rx FIFO 0 0-64 elements / 0-1152 words
-          minimum: 0
-          maximum: 64
-        - description: Rx FIFO 1 0-64 elements / 0-1152 words
-          minimum: 0
-          maximum: 64
-        - description: Rx Buffers 0-64 elements / 0-1152 words
-          minimum: 0
-          maximum: 64
-        - description: Tx Event FIFO 0-32 elements / 0-64 words
-          minimum: 0
-          maximum: 32
-        - description: Tx Buffers 0-32 elements / 0-576 words
-          minimum: 0
-          maximum: 32
-    maxItems: 1
+      - description: The 'offset' is an address offset of the Message RAM where
+          the following elements start from. This is usually set to 0x0 if
+          you're using a private Message RAM.
+        default: 0
+      - description: 11-bit Filter 0-128 elements / 0-128 words
+        minimum: 0
+        maximum: 128
+      - description: 29-bit Filter 0-64 elements / 0-128 words
+        minimum: 0
+        maximum: 64
+      - description: Rx FIFO 0 0-64 elements / 0-1152 words
+        minimum: 0
+        maximum: 64
+      - description: Rx FIFO 1 0-64 elements / 0-1152 words
+        minimum: 0
+        maximum: 64
+      - description: Rx Buffers 0-64 elements / 0-1152 words
+        minimum: 0
+        maximum: 64
+      - description: Tx Event FIFO 0-32 elements / 0-64 words
+        minimum: 0
+        maximum: 32
+      - description: Tx Buffers 0-32 elements / 0-576 words
+        minimum: 0
+        maximum: 32
 
   power-domains:
     description:
diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
index 47b5f728701d..34c5463abcec 100644
--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
@@ -17,9 +17,8 @@ properties:
     description:
       Specifies the MAC address that was assigned to the network device.
     $ref: /schemas/types.yaml#/definitions/uint8-array
-    items:
-      - minItems: 6
-        maxItems: 6
+    minItems: 6
+    maxItems: 6
 
   mac-address:
     description:
@@ -28,9 +27,8 @@ properties:
       to the device by the boot program is different from the
       local-mac-address property.
     $ref: /schemas/types.yaml#/definitions/uint8-array
-    items:
-      - minItems: 6
-        maxItems: 6
+    minItems: 6
+    maxItems: 6
 
   max-frame-size:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -164,33 +162,30 @@ properties:
           type: array
         then:
           deprecated: true
-          minItems: 1
-          maxItems: 1
           items:
-            items:
-              - minimum: 0
-                maximum: 31
-                description:
-                  Emulated PHY ID, choose any but unique to the all
-                  specified fixed-links
-
-              - enum: [0, 1]
-                description:
-                  Duplex configuration. 0 for half duplex or 1 for
-                  full duplex
-
-              - enum: [10, 100, 1000, 2500, 10000]
-                description:
-                  Link speed in Mbits/sec.
-
-              - enum: [0, 1]
-                description:
-                  Pause configuration. 0 for no pause, 1 for pause
-
-              - enum: [0, 1]
-                description:
-                  Asymmetric pause configuration. 0 for no asymmetric
-                  pause, 1 for asymmetric pause
+            - minimum: 0
+              maximum: 31
+              description:
+                Emulated PHY ID, choose any but unique to the all
+                specified fixed-links
+
+            - enum: [0, 1]
+              description:
+                Duplex configuration. 0 for half duplex or 1 for
+                full duplex
+
+            - enum: [10, 100, 1000, 2500, 10000]
+              description:
+                Link speed in Mbits/sec.
+
+            - enum: [0, 1]
+              description:
+                Pause configuration. 0 for no pause, 1 for pause
+
+            - enum: [0, 1]
+              description:
+                Asymmetric pause configuration. 0 for no asymmetric
+                pause, 1 for asymmetric pause
 
 
       - if:
-- 
2.32.0



From miles.chen at mediatek.com  Tue Jan 18 18:08:49 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 10:08:49 +0800
Subject: [PATCH] usb: gadget: at91_udc: fix incorrect print type
Message-ID: <20220119020849.25732-1-miles.chen@mediatek.com>

Fix a build error observed with ARCH=arm DEFCONFIG=allmodconfig build.

drivers/usb/gadget/udc/at91_udc.h:174:42: error: format '%d' expects argument of type 'int', but argument 3 has type 'struct gpio_desc *' [-Werror=format=]

Fixes: 4a555f2b8d31 ("usb: gadget: at91_udc: Convert to GPIO descriptors")
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/usb/gadget/udc/at91_udc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c
index dd0819df096e..9040a0561466 100644
--- a/drivers/usb/gadget/udc/at91_udc.c
+++ b/drivers/usb/gadget/udc/at91_udc.c
@@ -1895,7 +1895,7 @@ static int at91udc_probe(struct platform_device *pdev)
 					at91_vbus_irq, 0, driver_name, udc);
 			if (retval) {
 				DBG("request vbus irq %d failed\n",
-				    udc->board.vbus_pin);
+				    desc_to_gpio(udc->board.vbus_pin));
 				goto err_unprepare_iclk;
 			}
 		}
-- 
2.18.0



From sboyd at kernel.org  Tue Jan 18 18:18:42 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 18 Jan 2022 18:18:42 -0800
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <69525223-7d90-5714-bbe9-4d7f0b9a293d@arm.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com> <YeF/AYZ0DuKGwLLk@maud>
 <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>
 <69525223-7d90-5714-bbe9-4d7f0b9a293d@arm.com>
Message-ID: <20220119021844.3C225C340E5@smtp.kernel.org>

Quoting Robin Murphy (2022-01-18 07:01:46)
> On 2022-01-18 07:19, Chen-Yu Tsai wrote:
> > Hi,
> > 
> > On Fri, Jan 14, 2022 at 9:47 PM Alyssa Rosenzweig <alyssa at collabora.com> wrote:
> >>
> >>>> That links to an internal Google issue tracker which I assume has more
> >>>> information on the bug. I would appreciate if someone from Google or
> >>>> MediaTek could explain what this change actually does and why it's
> >>>> necessary on MT8192.
> >>>>
> >>>> At any rate, this register logically belongs to the MT8192 "infra" clock
> >>>> device, so it makes sense to set it there too. This avoids adding any
> >>>> platform-specific hacks to the 3D driver, either mainline (Panfrost) or
> >>>> legacy (kbase).
> >>>
> >>> Does this really have anything to do with clocks?
> >>
> >> I have no idea. MediaTek, Google, please explain.
> >>
> >>> In particular, "ACP" usually refers to the Accelerator Coherency Port
> >>> of a CPU cluster or DSU, and given the stated symptom of the issue
> >>> affected by it, my first guess would be that this bit might indeed
> >>> control routing of GPU traffic either to the ACP or the (presumably
> >>> non-coherent) main interconnect.
> >>
> >> I'd easily believe that.
> > 
> > As Robin guessed, "ACP" here does refer to the Accelerator Coherency Port.
> > And the bit in infracfg toggles whether ACP is used or not.
> > 
> > Explanation from MediaTek in verbatim:
> > 
> > -------------------------------------------------------------------------
> > The ACP path on MT8192 is just for experimental only.
> > We are not intended to enable ACP by design.
> > 
> > But due to an unexpected operation, it was accidently opened by default.
> > So we need a patch to disable the ACP for MT8192.
> > -------------------------------------------------------------------------
> 
> Aha! That's great, thanks ChenYu!
> 
> Stephen, my thinking here is that if this feature controls the GPU 
> interconnect, and only matters when the GPU is going to be used (as 
> strongly implied by the downstream implementation), then the GPU driver 
> is the only interested party and may as well take responsibility if 
> there's no better alternative.
> 
> I'd agree that if there was already a "base" infracfg driver doing 
> general system-wide set-and-forget configuration then it would equally 
> well fit in there, but that doesn't seem to be the case.

Wouldn't this first set-and-forget configuration fit that bill? We can't
have a "base" driver because why?

> Short of trying 
> to abuse the bp_infracfg data in the mtk-pm-domains driver (which 
> doesn't seem like a particularly pleasant idea), the code to poke a bit 
> into a syscon regmap is going to be pretty much the same wherever we add 
> it. There's already a bit of a pattern for MTK drivers to look up and 
> poke their own infracfg bits directly as needed, so between that and the 
> downstream implementation for this particular bit, leaving it to 
> Panfrost seems like the least surprising option.
> 

I'd prefer we leave the SoC glue out of device drivers for subsystems
that really don't want to or need to know about the SoC level details.
The GPU driver wants to live life drawing triangles! :) It doesn't want
to know that the ACP path didn't work out on some SoC it got plopped
down into. And of course GPU is the only interested party, because the
SoC glue for the GPU is all messed up so GPU can't operate properly
without this bit toggled. I wonder where the fix would end up if this
port was shared by more than one driver. Probably back here in the
closest thing there is to the SoC driver.

It's not as simple as poking bits in some SoC glue IO space
unconditionally either. The GPU driver will need to know which SoC is
being used and then only poke the bits if the affected SoC is in use. Or
we'll have some DT binding update to poke the bit if some syscon
property is present in the DT node. Either way, it's a set-and-forget
thing, so the GPU driver will now have some set-and-forget logic for one
SoC out of many that it supports; do it once at boot, grab a regmap,
parse some more stuff to make sure it's needed, poke the bit, release
the regmap, finally start drawing.

Of course, I won't oppose the mess being moved somewhere outside of the
subsystem I maintain ;-) I was mainly curious to understand why the
regmap path is proposed.


From peng.fan at nxp.com  Tue Jan 18 18:20:30 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 02:20:30 +0000
Subject: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support i.MX8QXP
In-Reply-To: <20220118184123.GD1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-4-peng.fan@oss.nxp.com>
 <20220118184123.GD1119324@p14s>
Message-ID: <DU0PR04MB9417338F4E1E7F6866AFF16888599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 1/9] dt-bindings: remoteproc: imx_rproc: support
> i.MX8QXP
> 
> On Tue, Jan 11, 2022 at 11:33:25AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Add i.MX8QXP compatible
> >
> > Add a new property rsrc-id for SoC which supports SCFW. This rsrc-id
> 
> You are introducing an acronym that doesn't have a definition - I have to grep
> the kernel tree to have an idea of what SCFW is.  That consumes time that I
> don't have to review your code or someone else's.

Sorry. SCFW(System controller Unit Firmware).

> 
> > is used to check whether remote process is under control of Linux or
> 
> s/process/processor

Fix in v2.

Thanks,
Peng.

> 
> > not.
> >
> > To i.MX8QM/QXP, when M4 is in the same hardware partition with
> > Cortex-A cores, need power up M4 through SCFW, then M4 could start. So
> > introduce power-domains property
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  .../devicetree/bindings/remoteproc/fsl,imx-rproc.yaml  | 10
> > ++++++++++
> >  1 file changed, 10 insertions(+)
> >
> > diff --git
> > a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> > b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> > index fc16d903353e..ed1bcb3046a9 100644
> > --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> > +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml
> > @@ -19,6 +19,7 @@ properties:
> >        - fsl,imx8mm-cm4
> >        - fsl,imx8mn-cm7
> >        - fsl,imx8mp-cm7
> > +      - fsl,imx8qxp-cm4
> >        - fsl,imx8ulp-cm33
> >        - fsl,imx7d-cm4
> >        - fsl,imx7ulp-cm4
> > @@ -59,6 +60,15 @@ properties:
> >        Indicate whether need to load the default firmware and start the
> remote
> >        processor automatically.
> >
> > +  power-domains:
> > +    maxItems: 8
> > +
> > +  rsrc-id:
> > +    description:
> > +      This property is to specify the resource id of the remote processor
> in SoC
> > +      which supports SCFW
> > +    maxItems: 1
> > +
> >  required:
> >    - compatible
> >
> > --
> > 2.25.1
> >


From peng.fan at nxp.com  Tue Jan 18 18:21:50 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 02:21:50 +0000
Subject: [PATCH 3/9] remoteproc: support self recovery after rproc crash
In-Reply-To: <20220118184453.GE1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-6-peng.fan@oss.nxp.com>
 <20220118184453.GE1119324@p14s>
Message-ID: <DU0PR04MB941748388F7BF5DF9CA0C4AE88599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 3/9] remoteproc: support self recovery after rproc crash
> 
> On Tue, Jan 11, 2022 at 11:33:27AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Current logic only support main processor to stop/start the remote
> > processor after rproc crash. However to SoC, such as i.MX8QM/QXP, the
> > remote processor could do self recovery after crash and trigger
> > watchdog reboot. It does not need main processor to load image,
> > stop/start M4 core.
> >
> > This patch add a new flag to indicate whether the SoC has self
> > recovery capability. And introduce two functions: rproc_self_recovery,
> > rproc_assisted_recovery for the two cases. Assisted recovery is as
> > before, let main processor to help recovery, while self recovery is
> > recover itself withou help. To self recovery, we only do detach and
> > attach.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/remoteproc_core.c | 66
> ++++++++++++++++++++--------
> >  include/linux/remoteproc.h           |  2 +
> >  2 files changed, 49 insertions(+), 19 deletions(-)
> >
> > diff --git a/drivers/remoteproc/remoteproc_core.c
> > b/drivers/remoteproc/remoteproc_core.c
> > index 69f51acf235e..4bd5544dab8f 100644
> > --- a/drivers/remoteproc/remoteproc_core.c
> > +++ b/drivers/remoteproc/remoteproc_core.c
> > @@ -1887,6 +1887,49 @@ static int __rproc_detach(struct rproc *rproc)
> >  	return 0;
> >  }
> >
> > +static int rproc_self_recovery(struct rproc *rproc) {
> > +	int ret;
> > +
> > +	mutex_unlock(&rproc->lock);
> > +	ret = rproc_detach(rproc);
> > +	mutex_lock(&rproc->lock);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (atomic_inc_return(&rproc->power) > 1)
> > +		return 0;
> > +	return rproc_attach(rproc);
> > +}
> > +
> > +static int rproc_assisted_recovery(struct rproc *rproc) {
> > +	const struct firmware *firmware_p;
> > +	struct device *dev = &rproc->dev;
> > +	int ret;
> > +
> > +	ret = rproc_stop(rproc, true);
> > +	if (ret)
> > +		return ret;
> > +
> > +	/* generate coredump */
> > +	rproc->ops->coredump(rproc);
> > +
> > +	/* load firmware */
> > +	ret = request_firmware(&firmware_p, rproc->firmware, dev);
> > +	if (ret < 0) {
> > +		dev_err(dev, "request_firmware failed: %d\n", ret);
> > +		return ret;
> > +	}
> > +
> > +	/* boot the remote processor up again */
> > +	ret = rproc_start(rproc, firmware_p);
> > +
> > +	release_firmware(firmware_p);
> > +
> > +	return ret;
> > +}
> > +
> >  /**
> >   * rproc_trigger_recovery() - recover a remoteproc
> >   * @rproc: the remote processor
> > @@ -1901,7 +1944,6 @@ static int __rproc_detach(struct rproc *rproc)
> >   */
> >  int rproc_trigger_recovery(struct rproc *rproc)  {
> > -	const struct firmware *firmware_p;
> >  	struct device *dev = &rproc->dev;
> >  	int ret;
> >
> > @@ -1915,24 +1957,10 @@ int rproc_trigger_recovery(struct rproc
> > *rproc)
> >
> >  	dev_err(dev, "recovering %s\n", rproc->name);
> >
> > -	ret = rproc_stop(rproc, true);
> > -	if (ret)
> > -		goto unlock_mutex;
> > -
> > -	/* generate coredump */
> > -	rproc->ops->coredump(rproc);
> > -
> > -	/* load firmware */
> > -	ret = request_firmware(&firmware_p, rproc->firmware, dev);
> > -	if (ret < 0) {
> > -		dev_err(dev, "request_firmware failed: %d\n", ret);
> > -		goto unlock_mutex;
> > -	}
> > -
> > -	/* boot the remote processor up again */
> > -	ret = rproc_start(rproc, firmware_p);
> > -
> > -	release_firmware(firmware_p);
> > +	if (rproc->self_recovery)
> > +		ret = rproc_self_recovery(rproc);
> > +	else
> > +		ret = rproc_assisted_recovery(rproc);
> 
> The problem of how to handle crash recoveries for processors that have been
> attached to is difficult.  Finding a solution for that should be on a patchset of
> its own so that people can provide input.

ok, will move this patch out from the patchset.

Thanks,
Peng.

> 
> >
> >  unlock_mutex:
> >  	mutex_unlock(&rproc->lock);
> > diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
> > index e0600e1e5c17..b32ef46f8aa4 100644
> > --- a/include/linux/remoteproc.h
> > +++ b/include/linux/remoteproc.h
> > @@ -529,6 +529,7 @@ struct rproc_dump_segment {
> >   * @elf_machine: firmware ELF machine
> >   * @cdev: character device of the rproc
> >   * @cdev_put_on_release: flag to indicate if remoteproc should be
> > shutdown on @char_dev release
> > + * @self_recovery: flag to indicate if remoteproc support self
> > + recovery
> >   */
> >  struct rproc {
> >  	struct list_head node;
> > @@ -568,6 +569,7 @@ struct rproc {
> >  	u16 elf_machine;
> >  	struct cdev cdev;
> >  	bool cdev_put_on_release;
> > +	bool self_recovery;
> >  };
> >
> >  /**
> > --
> > 2.25.1
> >


From sboyd at kernel.org  Tue Jan 18 18:22:19 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 18 Jan 2022 18:22:19 -0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
 <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
Message-ID: <20220119022221.3AF83C340E0@smtp.kernel.org>

Quoting Liang Yang (2022-01-16 22:24:28)
> 
> 
> On 2022/1/15 7:01, Stephen Boyd wrote:
> > [ EXTERNAL EMAIL ]
> > 
> > Quoting Liang Yang (2022-01-13 21:14:46)
> >> On 2022/1/14 5:35, Stephen Boyd wrote:
> >>> Quoting Liang Yang (2022-01-13 03:57:45)
> >>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
> >>>> new file mode 100644
> >>>> index 000000000000..f53977f61390
> >>>> --- /dev/null
> >>>> +++ b/drivers/clk/meson/mmc-clkc.c
> >>>> @@ -0,0 +1,300 @@
> > [..]
> >>>> +
> >>>> +static int mmc_clkc_probe(struct platform_device *pdev)
> >>>> +{
> >>>> +       struct clk_hw_onecell_data *onecell_data;
> >>>> +       struct device *dev = &pdev->dev;
> >>>> +       struct mmc_clkc_data *data;
> >>>> +       struct regmap *map;
> >>>> +       struct clk_regmap *clk, *core;
> >>>> +       struct meson_sclk_div_data *div_data;
> >>>> +
> >>>> +       /*cast to drop the const in match->data*/
> >>>
> >>> Space after *, also why do we need to cast away const? The user of this
> >>> pointer passes it all the way down to mmc_clkc_register_clk() which
> >>> could take the data as const void pointer and decide to cast away const
> >>> there.
> >>
> >> if use 'const' here, it  will report a warning:
> >> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
> >> qualifier from pointer targe
> >> t type [-Werror=discarded-qualifiers]
> >>
> >>     data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
> > 
> > Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not 
> have 'const', so make the type declaration cause a further 'const' cast 
> warning. Could i copy these infos just like below:

Why can't you push const down to the function that really cares to
remove const?


From peng.fan at nxp.com  Tue Jan 18 18:23:48 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 02:23:48 +0000
Subject: [PATCH 4/9] remoteproc: imx_rproc: ignore create mem entry for
 resource table
In-Reply-To: <20220118184710.GF1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-7-peng.fan@oss.nxp.com>
 <20220118184710.GF1119324@p14s>
Message-ID: <DU0PR04MB94170EA5A17F44FC7F9F124588599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 4/9] remoteproc: imx_rproc: ignore create mem entry for
> resource table
> 
> On Tue, Jan 11, 2022 at 11:33:28AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> 
> The "ignore" in the title should have a capital 'I'.

Fix in V2

> 
> > resource table will not be used for memory allocation, no need to
> > create
> 
> s/resource/Resource

Fix in V2.

> 
> > rproc mem entry.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/imx_rproc.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 75fde16f80a4..7b2578177ea8
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -423,6 +423,9 @@ static int imx_rproc_prepare(struct rproc *rproc)
> >  		if (!strcmp(it.node->name, "vdev0buffer"))
> >  			continue;
> >
> > +		if (!strncmp(it.node->name, "rsc-table", strlen("rsc-table")))
> > +			continue;
> > +
> 
> This is a bug fix that should be in a separate patch with a "Fixes:" tag.

ok.

Thanks,
Peng.

> 
> >  		rmem = of_reserved_mem_lookup(it.node);
> >  		if (!rmem) {
> >  			dev_err(priv->dev, "unable to acquire memory-region\n");
> > --
> > 2.25.1
> >


From peng.fan at nxp.com  Tue Jan 18 18:25:48 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 02:25:48 +0000
Subject: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
In-Reply-To: <20220118185019.GG1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-8-peng.fan@oss.nxp.com>
 <20220118185019.GG1119324@p14s>
Message-ID: <DU0PR04MB9417B0AC80F41D425F43277C88599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
> 
> On Tue, Jan 11, 2022 at 11:33:29AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > To i.MX8QXP/QM/ULP and i.MX7ULP, Mcore maybe out of control of Linux.
> > And in such case, no need clk, so make clk optional with has_clk.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/imx_rproc.c | 5 +++++
> >  1 file changed, 5 insertions(+)
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 7b2578177ea8..0e99a3ca6fbc
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -89,6 +89,7 @@ struct imx_rproc {
> >  	struct work_struct		rproc_work;
> >  	struct workqueue_struct		*workqueue;
> >  	void __iomem			*rsc_table;
> > +	bool				has_clk;
> 
> I am usually weary of bloating structures with flags.  I suggest achieving the
> same functionality with a macro that compares priv->dcfg with the right
> imx_rproc_dcfg structure.

priv->dcfg is some kind fixed settings, however has_clk could be runtime changed,
because i.MX platform M-core support multiple booting method and it
could work w/o clk handled by Linux depending on some pre-configuration
such as moving M-core in an separate hardware partition.

Thanks,
Peng. 

> 
> >  };
> >
> >  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { @@
> > -724,6 +725,9 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
> >  	if (dcfg->method == IMX_RPROC_NONE)
> >  		return 0;
> >
> > +	if (!priv->has_clk)
> > +		return 0;
> > +
> >  	priv->clk = devm_clk_get(dev, NULL);
> >  	if (IS_ERR(priv->clk)) {
> >  		dev_err(dev, "Failed to get clock\n"); @@ -768,6 +772,7 @@ static
> > int imx_rproc_probe(struct platform_device *pdev)
> >  	priv->rproc = rproc;
> >  	priv->dcfg = dcfg;
> >  	priv->dev = dev;
> > +	priv->has_clk = true;
> >
> >  	dev_set_drvdata(dev, rproc);
> >  	priv->workqueue = create_workqueue(dev_name(dev));
> > --
> > 2.25.1
> >


From rex-bc.chen at mediatek.com  Tue Jan 18 18:25:40 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 19 Jan 2022 10:25:40 +0800
Subject: [v10,
 0/3] force hsa hbp hfp packets multiple of lanenum to avoid screen
 shift
Message-ID: <20220119022543.26093-1-rex-bc.chen@mediatek.com>

Changes since v9:
 - Change description of "MIPI_DSI_HS_PKT_END_ALIGNED".
 - Use mode_flags directly instead of another variable on patch [2/3].
 - Add explanation of implementation in mtk_dsi.c on commit message of [2/3].

Changes since v8:
 - Use mode_flags to control this limitation instead of "hs_packet_end_aligned".
 - Add new bit definition "MIPI_DSI_HS_PKT_END_ALIGNED" for mode_flags.

Changes since v7:
 - Rebase to kernel 5.16
 - Add tags of reviewed-by and acked-by.
 - Add detailed commit message for flag "hs_packet_end_aligned" in DSI common driver.

Changes since v6:
 - Add "bool hs_packet_end_aligned" in "struct mipi_dsi_device" to control the dsi aligned.
 - Config the "hs_packet_end_aligned" in ANX7725 .attach().

Changes since v5:
 - Search the anx7625 compatible as flag to control dsi output aligned.

Changes since v4:
 - Move "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null" before
   "drm/mediatek: force hsa hbp hfp packets multiple of lanenum to avoid".
 - Retitle "dt-bindings: drm/bridge: anx7625: add force_dsi_end_without_null".

Rex-BC Chen (3):
  drm/dsi: transfer DSI HS packets ending at the same time
  drm/mediatek: implement the DSI HS packets aligned
  drm/bridge: anx7625: config hs packets end aligned to avoid screen shift

 drivers/gpu/drm/bridge/analogix/anx7625.c |  3 ++-
 drivers/gpu/drm/mediatek/mtk_dsi.c        | 12 ++++++++++++
 include/drm/drm_mipi_dsi.h                |  2 ++
 3 files changed, 16 insertions(+), 1 deletion(-)

-- 
2.18.0



From rex-bc.chen at mediatek.com  Tue Jan 18 18:25:41 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 19 Jan 2022 10:25:41 +0800
Subject: [v10,1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
Message-ID: <20220119022543.26093-2-rex-bc.chen@mediatek.com>

Since a HS transmission is composed of an arbitrary number
of bytes that may not be an integer multiple of lanes, some
lanes may run out of data before others.
(Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)

However, for some DSI RX devices (for example, anx7625),
there is a limitation that packet number should be the same
on all DSI lanes. In other words, they need to end a HS at
the same time.

Because this limitation is for some specific DSI RX devices,
it is more reasonable to put the enable control in these
DSI RX drivers. If DSI TX driver knows the information,
they can adjust the setting for this situation.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 include/drm/drm_mipi_dsi.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 147e51b6d241..51e09a1a106a 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -137,6 +137,8 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
 #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
 /* transmit data in low power */
 #define MIPI_DSI_MODE_LPM		BIT(11)
+/* transmit data ending at the same time for all lanes within one hsync */
+#define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
 
 enum mipi_dsi_pixel_format {
 	MIPI_DSI_FMT_RGB888,
-- 
2.18.0



From rex-bc.chen at mediatek.com  Tue Jan 18 18:25:43 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 19 Jan 2022 10:25:43 +0800
Subject: [v10, 3/3] drm/bridge: anx7625: config hs packets end aligned to avoid
 screen shift
In-Reply-To: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
Message-ID: <20220119022543.26093-4-rex-bc.chen@mediatek.com>

This device requires the packets on lanes aligned at the end to fix
screen shift or scroll.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Xin Ji <xji at analogixsemi.com>
---
 drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
index 2346dbcc505f..fe32ab0878ae 100644
--- a/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1673,7 +1673,8 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
 	dsi->format = MIPI_DSI_FMT_RGB888;
 	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
 		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
-		MIPI_DSI_MODE_VIDEO_HSE;
+		MIPI_DSI_MODE_VIDEO_HSE	|
+		MIPI_DSI_HS_PKT_END_ALIGNED;
 
 	ret = devm_mipi_dsi_attach(dev, dsi);
 	if (ret) {
-- 
2.18.0



From rex-bc.chen at mediatek.com  Tue Jan 18 18:25:42 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Wed, 19 Jan 2022 10:25:42 +0800
Subject: [v10,2/3] drm/mediatek: implement the DSI HS packets aligned
In-Reply-To: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
Message-ID: <20220119022543.26093-3-rex-bc.chen@mediatek.com>

Some DSI RX devices (for example, anx7625) require last alignment of
packets on all lanes after each row of data is sent.
Otherwise, there will be some issues of shift or scroll for screen.

Take horizontal_sync_active_byte for a example,
we roundup the HSA packet data to lane number, and the subtraction of 2
is the packet data value added by the roundup operation, making the
long packets are integer multiples of lane number.
This value (2) varies with the lane number, and that is the reason we
do this operation when the lane number is 4.

In the previous operation of function "mtk_dsi_config_vdo_timing",
the length of HSA and HFP data packets has been adjusted to an
integration multiple of lane number.
Since the number of RGB data packets cannot be guaranteed to be an
integer multiple of lane number, we modify the data packet length of
HBP so that the number of HBP + RGB is equal to the lane number.
So after sending a line of data (HSA + HBP + RGB + HFP), the data
lanes are aligned.

Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..e91b3fff4342 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -500,6 +500,18 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
 	}
 
+	if ((dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) &&
+	    (dsi->lanes == 4)) {
+		horizontal_sync_active_byte =
+			roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
+		horizontal_frontporch_byte =
+			roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte =
+			roundup(horizontal_backporch_byte, dsi->lanes) - 2;
+		horizontal_backporch_byte -=
+			(vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
+	}
+
 	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
 	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
 	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
-- 
2.18.0



From victor.liu at nxp.com  Tue Jan 18 18:37:14 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 19 Jan 2022 10:37:14 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
Message-ID: <20220119023714.1498508-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 include/linux/phy/phy-mipi-dphy.h                |  2 +-
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
index a877ffee845d..59a5e77ab409 100644
--- a/include/linux/phy/phy-mipi-dphy.h
+++ b/include/linux/phy/phy-mipi-dphy.h
@@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
 	 * the transmitter prior to any associated Data Lane beginning
 	 * the transition from LP to HS mode.
 	 *
-	 * Minimum value: 8 UI
+	 * Minimum value: 8
 	 */
 	unsigned int		clk_pre;
 
-- 
2.25.1



From peng.fan at nxp.com  Tue Jan 18 18:28:31 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 19 Jan 2022 02:28:31 +0000
Subject: [PATCH 6/9] remoteproc: imx_rproc: support attaching to i.MX8QXP
 M4
In-Reply-To: <20220118185729.GH1119324@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-9-peng.fan@oss.nxp.com>
 <20220118185729.GH1119324@p14s>
Message-ID: <DU0PR04MB9417335FFEBEB5CE91A5A67888599@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 6/9] remoteproc: imx_rproc: support attaching to
> i.MX8QXP M4
> 
> On Tue, Jan 11, 2022 at 11:33:30AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > When M4 is kicked by SCFW, M4 runs in its own hardware partition,
> > Linux could only do IPC with M4, it could not start, stop, update image.
> >
> > When M4 crash reboot, it could notify Linux, so Linux could prepare to
> > reattach to M4 after M4 recovery.
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/imx_rproc.c | 96
> > ++++++++++++++++++++++++++++++++++
> >  1 file changed, 96 insertions(+)
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 0e99a3ca6fbc..5f04aea2f6a1
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -6,6 +6,7 @@
> >  #include <linux/arm-smccc.h>
> >  #include <linux/clk.h>
> >  #include <linux/err.h>
> > +#include <linux/firmware/imx/sci.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/kernel.h>
> >  #include <linux/mailbox_client.h>
> > @@ -59,6 +60,8 @@
> >  #define IMX_SIP_RPROC_STARTED		0x01
> >  #define IMX_SIP_RPROC_STOP		0x02
> >
> > +#define	IMX_SC_IRQ_GROUP_REBOOTED	5
> > +
> >  /**
> >   * struct imx_rproc_mem - slim internal memory structure
> >   * @cpu_addr: MPU virtual address of the memory region @@ -90,6
> > +93,23 @@ struct imx_rproc {
> >  	struct workqueue_struct		*workqueue;
> >  	void __iomem			*rsc_table;
> >  	bool				has_clk;
> > +	struct imx_sc_ipc		*ipc_handle;
> > +	struct notifier_block		proc_nb;
> > +	u32				rproc_pt;
> > +	u32				rsrc;
> 
> There is no documentation for the above two fields and I have to guess what
> they do.

Fix in V2.

> 
> > +};
> > +
> > +static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> > +	/* dev addr , sys addr  , size	    , flags */
> > +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> > +	/* TCML/U */
> > +	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
> > +	/* OCRAM(Low 96KB) */
> > +	{ 0x21000000, 0x00100000, 0x00018000, 0},
> > +	/* OCRAM */
> > +	{ 0x21100000, 0x00100000, 0x00040000, 0},
> > +	/* DDR (Data) */
> > +	{ 0x80000000, 0x80000000, 0x60000000, 0 },
> >  };
> >
> >  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { @@
> > -236,6 +256,12 @@ static const struct imx_rproc_dcfg
> imx_rproc_cfg_imx8ulp = {
> >  	.method		= IMX_RPROC_NONE,
> >  };
> >
> > +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
> > +	.att		= imx_rproc_att_imx8qxp,
> > +	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> > +	.method		= IMX_RPROC_SCU_API,
> > +};
> > +
> >  static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
> >  	.att		= imx_rproc_att_imx7ulp,
> >  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
> > @@ -491,6 +517,11 @@ static int imx_rproc_attach(struct rproc *rproc)
> >  	return 0;
> >  }
> >
> > +static int imx_rproc_detach(struct rproc *rproc) {
> > +	return 0;
> 
> Is it possible to detach the remote processor from the application core?  If
> not please write a comment that says so.

No from my understanding.

  And shouldn't this return some
> kind of error so that users don't think the operation was carried out
> successfully?

No. This is to match patch 3/9 to support M-core self recovery. After M-core
crash reboot, remoteproc framework just detach and re-attach.

> 
> I am out of time for today and as such will continue with this set tomorrow.

Thanks for you reviewing the patchset.

Thanks,
Peng.

> 
> Thanks,
> Mathieu
> 
> > +}
> > +
> >  static struct resource_table *imx_rproc_get_loaded_rsc_table(struct
> > rproc *rproc, size_t *table_sz)  {
> >  	struct imx_rproc *priv = rproc->priv; @@ -525,6 +556,7 @@
> > imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct
> > firmware *  static const struct rproc_ops imx_rproc_ops = {
> >  	.prepare	= imx_rproc_prepare,
> >  	.attach		= imx_rproc_attach,
> > +	.detach		= imx_rproc_detach,
> >  	.start		= imx_rproc_start,
> >  	.stop		= imx_rproc_stop,
> >  	.kick		= imx_rproc_kick,
> > @@ -671,6 +703,22 @@ static void imx_rproc_free_mbox(struct rproc
> *rproc)
> >  	mbox_free_channel(priv->rx_ch);
> >  }
> >
> > +static int imx_rproc_partition_notify(struct notifier_block *nb,
> > +				      unsigned long event, void *group) {
> > +	struct imx_rproc *priv = container_of(nb, struct imx_rproc,
> > +proc_nb);
> > +
> > +	/* Ignore other irqs */
> > +	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group ==
> IMX_SC_IRQ_GROUP_REBOOTED)))
> > +		return 0;
> > +
> > +	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
> > +
> > +	pr_info("Patition%d reset!\n", priv->rproc_pt);
> > +
> > +	return 0;
> > +}
> > +
> >  static int imx_rproc_detect_mode(struct imx_rproc *priv)  {
> >  	struct regmap_config config = { .name = "imx-rproc" }; @@ -680,6
> > +728,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
> >  	struct arm_smccc_res res;
> >  	int ret;
> >  	u32 val;
> > +	u8 pt;
> >
> >  	switch (dcfg->method) {
> >  	case IMX_RPROC_NONE:
> > @@ -690,6 +739,52 @@ static int imx_rproc_detect_mode(struct
> imx_rproc *priv)
> >  		if (res.a0)
> >  			priv->rproc->state = RPROC_DETACHED;
> >  		return 0;
> > +	case IMX_RPROC_SCU_API:
> > +		ret = imx_scu_get_handle(&priv->ipc_handle);
> > +		if (ret)
> > +			return ret;
> > +		ret = of_property_read_u32(dev->of_node, "rsrc-id", &priv->rsrc);
> > +		if (ret) {
> > +			dev_err(dev, "no rsrc-id\n");
> > +			return ret;
> > +		}
> > +
> > +		/*
> > +		 * If Mcore resource is not owned by Acore partition, It is kicked by
> ROM,
> > +		 * and Linux could only do IPC with Mcore and nothing else.
> > +		 */
> > +		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
> > +
> > +			priv->has_clk = false;
> > +			priv->rproc->self_recovery = true;
> > +			priv->rproc->state = RPROC_DETACHED;
> > +
> > +			/* Get partition id and enable irq in SCFW */
> > +			ret = imx_sc_rm_get_resource_owner(priv->ipc_handle,
> priv->rsrc, &pt);
> > +			if (ret) {
> > +				dev_err(dev, "not able to get resource owner\n");
> > +				return ret;
> > +			}
> > +
> > +			priv->rproc_pt = pt;
> > +			priv->proc_nb.notifier_call = imx_rproc_partition_notify;
> > +
> > +			ret = imx_scu_irq_register_notifier(&priv->proc_nb);
> > +			if (ret) {
> > +				dev_warn(dev, "register scu notifier failed.\n");
> > +				return ret;
> > +			}
> > +
> > +			ret =
> imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED,
> > +						       BIT(priv->rproc_pt), true);
> > +			if (ret) {
> > +				imx_scu_irq_unregister_notifier(&priv->proc_nb);
> > +				dev_warn(dev, "Enable irq failed.\n");
> > +				return ret;
> > +			}
> > +		}
> > +
> > +		return 0;
> >  	default:
> >  		break;
> >  	}
> > @@ -847,6 +942,7 @@ static const struct of_device_id
> imx_rproc_of_match[] = {
> >  	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
> >  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
> >  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
> > +	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
> >  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
> >  	{},
> >  };
> > --
> > 2.25.1
> >


From yuji2.ishikawa at toshiba.co.jp  Tue Jan 18 18:49:40 2022
From: yuji2.ishikawa at toshiba.co.jp (yuji2.ishikawa at toshiba.co.jp)
Date: Wed, 19 Jan 2022 02:49:40 +0000
Subject: [PATCH 0/2] net: stmmac: dwmac-visconti: Fix bit definitions and
 clock configuration for RMII mode
In-Reply-To: <20220118165023.559dfe3b@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220118053950.2605-1-yuji2.ishikawa@toshiba.co.jp>
 <20220118165023.559dfe3b@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <TYAPR01MB6201E26CD93F6BCE0F0E76B892599@TYAPR01MB6201.jpnprd01.prod.outlook.com>

Hi Jakub,

Thank you for your comment. I will add Fixed tags to commit messages.

-----Original Message-----
From: Jakub Kicinski <kuba at kernel.org> 
Sent: Wednesday, January 19, 2022 9:50 AM
To: ishikawa yuji(?? ?? ?????????????) <yuji2.ishikawa at toshiba.co.jp>
Cc: David S . Miller <davem at davemloft.net>; Giuseppe Cavallaro <peppe.cavallaro at st.com>; Alexandre Torgue <alexandre.torgue at st.com>; Jose Abreu <joabreu at synopsys.com>; netdev at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org; iwamatsu nobuhiro(?? ?? ????????) <nobuhiro1.iwamatsu at toshiba.co.jp>
Subject: Re: [PATCH 0/2] net: stmmac: dwmac-visconti: Fix bit definitions and clock configuration for RMII mode

> On Tue, 18 Jan 2022 14:39:48 +0900 Yuji Ishikawa wrote:
> > This series is a fix for RMII/MII operation mode of the dwmac-visconti driver.
> > It is composed of two parts:
> > 
> > * 1/2: fix constant definitions for cleared bits in ETHER_CLK_SEL 
> > register
> > * 2/2: fix configuration of ETHER_CLK_SEL register for running in RMII operation mode.
>
> Please add appropriate Fixes tag pointing to the commits where the buggy code was introduced, even if it's the initial commit adding the driver.

Best regards,
Yuji Ishikawa



From liang.yang at amlogic.com  Tue Jan 18 18:55:38 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 19 Jan 2022 10:55:38 +0800
Subject: [PATCH v9 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220119022221.3AF83C340E0@smtp.kernel.org>
References: <20220113115745.45826-1-liang.yang@amlogic.com>
 <20220113115745.45826-5-liang.yang@amlogic.com>
 <20220113213513.9819AC36AEA@smtp.kernel.org>
 <09ff9044-9abc-d1ad-26c1-5e6ece56d30c@amlogic.com>
 <20220114230130.35EAAC36AE7@smtp.kernel.org>
 <fe77fd6b-788f-1694-f260-f95e54cf4ef3@amlogic.com>
 <20220119022221.3AF83C340E0@smtp.kernel.org>
Message-ID: <f8f1c6c6-3805-6371-87ea-06fc14862625@amlogic.com>

Hi Stephen,

On 2022/1/19 10:22, Stephen Boyd wrote:
> [ EXTERNAL EMAIL ]
> 
> Quoting Liang Yang (2022-01-16 22:24:28)
>>
>>
>> On 2022/1/15 7:01, Stephen Boyd wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> Quoting Liang Yang (2022-01-13 21:14:46)
>>>> On 2022/1/14 5:35, Stephen Boyd wrote:
>>>>> Quoting Liang Yang (2022-01-13 03:57:45)
>>>>>> diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
>>>>>> new file mode 100644
>>>>>> index 000000000000..f53977f61390
>>>>>> --- /dev/null
>>>>>> +++ b/drivers/clk/meson/mmc-clkc.c
>>>>>> @@ -0,0 +1,300 @@
>>> [..]
>>>>>> +
>>>>>> +static int mmc_clkc_probe(struct platform_device *pdev)
>>>>>> +{
>>>>>> +       struct clk_hw_onecell_data *onecell_data;
>>>>>> +       struct device *dev = &pdev->dev;
>>>>>> +       struct mmc_clkc_data *data;
>>>>>> +       struct regmap *map;
>>>>>> +       struct clk_regmap *clk, *core;
>>>>>> +       struct meson_sclk_div_data *div_data;
>>>>>> +
>>>>>> +       /*cast to drop the const in match->data*/
>>>>>
>>>>> Space after *, also why do we need to cast away const? The user of this
>>>>> pointer passes it all the way down to mmc_clkc_register_clk() which
>>>>> could take the data as const void pointer and decide to cast away const
>>>>> there.
>>>>
>>>> if use 'const' here, it  will report a warning:
>>>> drivers/clk/meson/mmc-clkc.c:224:7: error: assignment discards ?const?
>>>> qualifier from pointer targe
>>>> t type [-Werror=discarded-qualifiers]
>>>>
>>>>      data = (const struct mmc_clkc_data *)of_device_get_match_data(dev);
>>>
>>> Of course. The type declaration up above needs const added to it.The parm of mmc_clkc_register_clk_with_parent(...., void *data) does not
>> have 'const', so make the type declaration cause a further 'const' cast
>> warning. Could i copy these infos just like below:
> 
> Why can't you push const down to the function that really cares to
> remove const?
em, it is really ok to me. i will fix it next version.
> 
> .


From guoheyi at linux.alibaba.com  Tue Jan 18 18:59:32 2022
From: guoheyi at linux.alibaba.com (Heyi Guo)
Date: Wed, 19 Jan 2022 10:59:32 +0800
Subject: [PATCH] drivers/i2c-aspeed: avoid invalid memory reference after
 timeout
In-Reply-To: <CACPK8Xc+v132vM-ytdAUFhywFXGpPF+uPSBWi68ROf_PLD4VQQ@mail.gmail.com>
References: <20220109132613.122912-1-guoheyi@linux.alibaba.com>
 <ad5e5438-4a3f-2447-4af3-7caa91e7252a@linux.alibaba.com>
 <CACPK8XcYp9iAD3fjBQCax41C-1UpA+1AQW3epyEooYzNLt7R5g@mail.gmail.com>
 <e62fba0b-ebb9-934a-d7cf-6da33ecc4335@linux.alibaba.com>
 <CACPK8Xc+v132vM-ytdAUFhywFXGpPF+uPSBWi68ROf_PLD4VQQ@mail.gmail.com>
Message-ID: <0f5cd773-2d0a-b782-b967-ecbcec3de7b1@linux.alibaba.com>


? 2022/1/17 ??2:38, Joel Stanley ??:
> On Fri, 14 Jan 2022 at 14:01, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
>> Hi Joel,
>>
>>
>> ? 2022/1/11 ??6:51, Joel Stanley ??:
>>> On Tue, 11 Jan 2022 at 07:52, Heyi Guo <guoheyi at linux.alibaba.com> wrote:
>>>> Hi all,
>>>>
>>>> Any comments?
>>>>
>>>> Thanks,
>>>>
>>>> Heyi
>>>>
>>>> ? 2022/1/9 ??9:26, Heyi Guo ??:
>>>>> The memory will be freed by the caller if transfer timeout occurs,
>>>>> then it would trigger kernel panic if the peer device responds with
>>>>> something after timeout and triggers the interrupt handler of aspeed
>>>>> i2c driver.
>>>>>
>>>>> Set the msgs pointer to NULL to avoid invalid memory reference after
>>>>> timeout to fix this potential kernel panic.
>>> Thanks for the patch. How did you discover this issue? Do you have a
>>> test I can run to reproduce the crash?
>> We are using one i2c channel to communicate with another MCU by
>> implementing user space SSIF protocol, and the MCU may not respond in
>> time if it is busy. If it responds after timeout occurs, it will trigger
>> below kernel panic:
>>
> Thanks for the details. It looks like you've done some testing of
> this, which is good.
>
>> After applying this patch, we'll get below warning instead:
>>
>> "bus in unknown state. irq_status: 0x%x\n"
> Given we get to here in the irq handler, we've done these two tests:
>
>   - aspeed_i2c_is_irq_error()
>   - the state is not INACTIVE or PENDING
>
> but there's no buffer ready for us to use. So what has triggered the
> IRQ in this case? Do you have a record of the irq status bits?
>
> I am wondering if the driver should know that the transaction has
> timed out, instead of detecting this unknown state.

Yes, some drivers will try to abort the transaction before returning to 
the caller, if timeout happens.

The irq status bits are not always the same; searching from the history 
logs, I found some messages like below:

[? 495.289499] aspeed-i2c-bus 1e78a680.i2c-bus: bus in unknown state. 
irq_status: 0x2
[? 495.298003] aspeed-i2c-bus 1e78a680.i2c-bus: bus in unknown state. 
irq_status: 0x10

[?? 65.176761] aspeed-i2c-bus 1e78a680.i2c-bus: bus in unknown state. 
irq_status: 0x15

Thanks,

Heyi

>
>
>>> Can you provide a Fixes tag?
>> I think the bug was introduced by the first commit of this file :(
>>
>> f327c686d3ba44eda79a2d9e02a6a242e0b75787
>>
>>
>>> Do other i2c master drivers do this? I took a quick look at the meson
>>> driver and it doesn't appear to clear it's pointer to msgs.
>> It is hard to say. It seems other drivers have some recover scheme like
>> aborting the transfer, or loop each messages in process context and
>> don't do much in IRQ handler, which may disable interrupts or not retain
>> the buffer pointer before returning timeout.
> I think your change is okay to go in as it fixes the crash, but first
> I want to work out if there's some missing handling of a timeout
> condition that we should add as well.
>
>
>> Thanks,
>>
>> Heyi
>>
>>
>>>>> Signed-off-by: Heyi Guo <guoheyi at linux.alibaba.com>
>>>>>
>>>>> -------
>>>>>
>>>>> Cc: Brendan Higgins <brendanhiggins at google.com>
>>>>> Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
>>>>> Cc: Joel Stanley <joel at jms.id.au>
>>>>> Cc: Andrew Jeffery <andrew at aj.id.au>
>>>>> Cc: Philipp Zabel <p.zabel at pengutronix.de>
>>>>> Cc: linux-i2c at vger.kernel.org
>>>>> Cc: openbmc at lists.ozlabs.org
>>>>> Cc: linux-arm-kernel at lists.infradead.org
>>>>> Cc: linux-aspeed at lists.ozlabs.org
>>>>> ---
>>>>>     drivers/i2c/busses/i2c-aspeed.c | 5 +++++
>>>>>     1 file changed, 5 insertions(+)
>>>>>
>>>>> diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c
>>>>> index 67e8b97c0c950..3ab0396168680 100644
>>>>> --- a/drivers/i2c/busses/i2c-aspeed.c
>>>>> +++ b/drivers/i2c/busses/i2c-aspeed.c
>>>>> @@ -708,6 +708,11 @@ static int aspeed_i2c_master_xfer(struct i2c_adapter *adap,
>>>>>                 spin_lock_irqsave(&bus->lock, flags);
>>>>>                 if (bus->master_state == ASPEED_I2C_MASTER_PENDING)
>>>>>                         bus->master_state = ASPEED_I2C_MASTER_INACTIVE;
>>>>> +             /*
>>>>> +              * All the buffers may be freed after returning to caller, so
>>>>> +              * set msgs to NULL to avoid memory reference after freeing.
>>>>> +              */
>>>>> +             bus->msgs = NULL;
>>>>>                 spin_unlock_irqrestore(&bus->lock, flags);
>>>>>
>>>>>                 return -ETIMEDOUT;


From martin.petersen at oracle.com  Tue Jan 18 20:06:13 2022
From: martin.petersen at oracle.com (Martin K. Petersen)
Date: Tue, 18 Jan 2022 23:06:13 -0500
Subject: [PATCH v2] scsi: ufs: ufs-mediatek : Fix NULL vs IS_ERR checking
 in ufs_mtk_init_va09_pwr_ctrl
In-Reply-To: <20211222070930.9449-1-linmq006@gmail.com>
References: <CAGXv+5GF1WOeXVtnknAa4GYXE3Hd-UzcCBCyQzT6KY3tJCrVGA@mail.gmail.com>
 <20211222070930.9449-1-linmq006@gmail.com>
Message-ID: <164256513503.31841.2498520978130234851.b4-ty@oracle.com>

On Wed, 22 Dec 2021 07:09:30 +0000, Miaoqian Lin wrote:

> The function regulator_get() return error pointer,
> use IS_ERR() to check if has error.
> 
> 

Applied to 5.17/scsi-queue, thanks!

[1/1] scsi: ufs: ufs-mediatek : Fix NULL vs IS_ERR checking in ufs_mtk_init_va09_pwr_ctrl
      https://git.kernel.org/mkp/scsi/c/3ba880a12df5

-- 
Martin K. Petersen	Oracle Linux Engineering


From npiggin at gmail.com  Tue Jan 18 20:17:37 2022
From: npiggin at gmail.com (Nicholas Piggin)
Date: Wed, 19 Jan 2022 14:17:37 +1000
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <4488d39f-0698-7bfd-b81c-1e609821818f@intel.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
 <1642472965.lgfksp6krp.astroid@bobo.none>
 <4488d39f-0698-7bfd-b81c-1e609821818f@intel.com>
Message-ID: <1642565468.c0jax91tvn.astroid@bobo.none>

Excerpts from Dave Hansen's message of January 19, 2022 3:28 am:
> On 1/17/22 6:46 PM, Nicholas Piggin wrote:
>>> This all sounds very fragile to me.  Every time a new architecture would
>>> get added for huge vmalloc() support, the developer needs to know to go
>>> find that architecture's module_alloc() and add this flag.
>> This is documented in the Kconfig.
>> 
>>  #
>>  #  Archs that select this would be capable of PMD-sized vmaps (i.e.,
>>  #  arch_vmap_pmd_supported() returns true), and they must make no assumptions
>>  #  that vmalloc memory is mapped with PAGE_SIZE ptes. The VM_NO_HUGE_VMAP flag
>>  #  can be used to prohibit arch-specific allocations from using hugepages to
>>  #  help with this (e.g., modules may require it).
>>  #
>>  config HAVE_ARCH_HUGE_VMALLOC
>>          depends on HAVE_ARCH_HUGE_VMAP
>>          bool
>> 
>> Is it really fair to say it's *very* fragile? Surely it's reasonable to 
>> read the (not very long) documentation ad understand the consequences for
>> the arch code before enabling it.
> 
> Very fragile or not, I think folks are likely to get it wrong.  It would
> be nice to have it default *everyone* to safe and slow and make *sure*

It's not safe to enable though. That's the problem. If it was just 
modules then you'd have a point but it could be anything.

> they go look at the architecture modules code itself before enabling
> this for modules.

This is required not just for modules for the whole arch code, it
has to be looked at and decided this will work.

> Just from that Kconfig text, I don't think I'd know off the top of my
> head what do do for x86, or what code I needed to go touch.

You have to make sure arch/x86 makes no assumptions that vmalloc memory
is backed by PAGE_SIZE ptes. If you can't do that then you shouldn't 
enable the option. The option can not explain it any more because any
arch could do anything with its mappings. The module code is an example,
not the recipe.

Thanks,
Nick


From lyz_cs at pku.edu.cn  Tue Jan 18 20:27:19 2022
From: lyz_cs at pku.edu.cn (Yongzhi Liu)
Date: Tue, 18 Jan 2022 20:27:19 -0800
Subject: [PATCH] drm/rockchip: Fix runtime PM imbalance on error
Message-ID: <1642566439-25560-1-git-send-email-lyz_cs@pku.edu.cn>

pm_runtime_get_sync() will increase the rumtime PM counter
even it returns an error. Thus a pairing decrement is needed
to prevent refcount leak. Fix this by replacing this API with
pm_runtime_resume_and_get(), which will not change the runtime
PM counter on error.

Signed-off-by: Yongzhi Liu <lyz_cs at pku.edu.cn>
---
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 9fb83b6..e0c48f1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -588,7 +588,7 @@ static int vop_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
 	struct vop *vop = to_vop(crtc);
 	int ret, i;
 
-	ret = pm_runtime_get_sync(vop->dev);
+	ret = pm_runtime_resume_and_get(vop->dev);
 	if (ret < 0) {
 		DRM_DEV_ERROR(vop->dev, "failed to get pm runtime: %d\n", ret);
 		return ret;
-- 
2.7.4



From lyz_cs at pku.edu.cn  Tue Jan 18 20:37:53 2022
From: lyz_cs at pku.edu.cn (Yongzhi Liu)
Date: Tue, 18 Jan 2022 20:37:53 -0800
Subject: [PATCH] drm/rockchip: Fix runtime PM imbalance on error
Message-ID: <1642567073-25784-1-git-send-email-lyz_cs@pku.edu.cn>

pm_runtime_get_sync() will increase the rumtime PM counter
even it returns an error. Thus a pairing decrement is needed
to prevent refcount leak. Fix this by replacing this API with
pm_runtime_resume_and_get(), which will not change the runtime
PM counter on error.

Signed-off-by: Yongzhi Liu <lyz_cs at pku.edu.cn>
---
 drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
index 4ed7a68..9cf53f0 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
@@ -1188,7 +1188,7 @@ static int dw_mipi_dsi_dphy_power_on(struct phy *phy)
 		return i;
 	}
 
-	ret = pm_runtime_get_sync(dsi->dev);
+	ret = pm_runtime_resume_and_get(dsi->dev);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dsi->dev, "failed to enable device: %d\n", ret);
 		return ret;
-- 
2.7.4



From yuji2.ishikawa at toshiba.co.jp  Tue Jan 18 20:46:47 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Wed, 19 Jan 2022 13:46:47 +0900
Subject: [PATCH v2 1/2] net: stmmac: dwmac-visconti: Fix bit definitions for
 ETHER_CLK_SEL
In-Reply-To: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220119044648.18094-2-yuji2.ishikawa@toshiba.co.jp>

just 0 should be used to represent cleared bits

* ETHER_CLK_SEL_DIV_SEL_20
* ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN
* ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN
* ETHER_CLK_SEL_TX_CLK_O_TX_I
* ETHER_CLK_SEL_RMII_CLK_SEL_IN

Fixes: b38dd98ff8d0 ("net: stmmac: Add Toshiba Visconti SoCs glue driver")
Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index e2e0f9778..43a446cea 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -22,21 +22,21 @@
 #define ETHER_CLK_SEL_RMII_CLK_EN BIT(2)
 #define ETHER_CLK_SEL_RMII_CLK_RST BIT(3)
 #define ETHER_CLK_SEL_DIV_SEL_2 BIT(4)
-#define ETHER_CLK_SEL_DIV_SEL_20 BIT(0)
+#define ETHER_CLK_SEL_DIV_SEL_20 0
 #define ETHER_CLK_SEL_FREQ_SEL_125M	(BIT(9) | BIT(8))
 #define ETHER_CLK_SEL_FREQ_SEL_50M	BIT(9)
 #define ETHER_CLK_SEL_FREQ_SEL_25M	BIT(8)
 #define ETHER_CLK_SEL_FREQ_SEL_2P5M	0
-#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN BIT(0)
+#define ETHER_CLK_SEL_TX_CLK_EXT_SEL_IN 0
 #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC BIT(10)
 #define ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV BIT(11)
-#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN  BIT(0)
+#define ETHER_CLK_SEL_RX_CLK_EXT_SEL_IN  0
 #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC BIT(12)
 #define ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV BIT(13)
-#define ETHER_CLK_SEL_TX_CLK_O_TX_I	 BIT(0)
+#define ETHER_CLK_SEL_TX_CLK_O_TX_I	 0
 #define ETHER_CLK_SEL_TX_CLK_O_RMII_I	 BIT(14)
 #define ETHER_CLK_SEL_TX_O_E_N_IN	 BIT(15)
-#define ETHER_CLK_SEL_RMII_CLK_SEL_IN	 BIT(0)
+#define ETHER_CLK_SEL_RMII_CLK_SEL_IN	 0
 #define ETHER_CLK_SEL_RMII_CLK_SEL_RX_C	 BIT(16)
 
 #define ETHER_CLK_SEL_RX_TX_CLK_EN (ETHER_CLK_SEL_RX_CLK_EN | ETHER_CLK_SEL_TX_CLK_EN)
-- 
2.17.1




From yuji2.ishikawa at toshiba.co.jp  Tue Jan 18 20:46:46 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Wed, 19 Jan 2022 13:46:46 +0900
Subject: [PATCH v2 0/2] net: stmmac: dwmac-visconti: Fix bit definitions and
 clock configuration for RMII mode
Message-ID: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>

Hi,

This series is a fix for RMII/MII operation mode of the dwmac-visconti driver.
It is composed of two parts:

* 1/2: fix constant definitions for cleared bits in ETHER_CLK_SEL register
* 2/2: fix configuration of ETHER_CLK_SEL register for running in RMII operation mode.

Best regards,
  Yuji

  net: stmmac: dwmac-visconti: Fix bit definitions for ETHER_CLK_SEL
    v1 -> v2:
      - added Fixes tag to commit message

  net: stmmac: dwmac-visconti: Fix clock configuration for RMII mode
    v1 -> v2:
      - added Fixes tag to commit message

Yuji Ishikawa (2):
  net: stmmac: dwmac-visconti: Fix bit definitions for ETHER_CLK_SEL
  net: stmmac: dwmac-visconti: Fix clock configuration for RMII mode

 .../ethernet/stmicro/stmmac/dwmac-visconti.c  | 42 ++++++++++++-------
 1 file changed, 26 insertions(+), 16 deletions(-)

-- 
2.17.1




From yuji2.ishikawa at toshiba.co.jp  Tue Jan 18 20:46:48 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Wed, 19 Jan 2022 13:46:48 +0900
Subject: [PATCH v2 2/2] net: stmmac: dwmac-visconti: Fix clock configuration
 for RMII mode
In-Reply-To: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220119044648.18094-3-yuji2.ishikawa@toshiba.co.jp>

Bit pattern of the ETHER_CLOCK_SEL register for RMII/MII mode should be fixed.
Also, some control bits should be modified with a specific sequence.

Fixes: b38dd98ff8d0 ("net: stmmac: Add Toshiba Visconti SoCs glue driver")
Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 .../ethernet/stmicro/stmmac/dwmac-visconti.c  | 32 ++++++++++++-------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index 43a446cea..dde5b772a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -96,31 +96,41 @@ static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
 	val |= ETHER_CLK_SEL_TX_O_E_N_IN;
 	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 
+	/* Set Clock-Mux, Start clock, Set TX_O direction */
 	switch (dwmac->phy_intf_sel) {
 	case ETHER_CONFIG_INTF_RGMII:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val &= ~ETHER_CLK_SEL_TX_O_E_N_IN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	case ETHER_CONFIG_INTF_RMII:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV |
-			ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN |
+			ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN |
 			ETHER_CLK_SEL_RMII_CLK_SEL_RX_C;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RMII_CLK_RST;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	case ETHER_CONFIG_INTF_MII:
 	default:
 		val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC |
-			ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN |
-			ETHER_CLK_SEL_RMII_CLK_EN;
+			ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
+
+		val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
+		writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
 		break;
 	}
 
-	/* Start clock */
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-	val |= ETHER_CLK_SEL_RX_TX_CLK_EN;
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-
-	val &= ~ETHER_CLK_SEL_TX_O_E_N_IN;
-	writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL);
-
 	spin_unlock_irqrestore(&dwmac->lock, flags);
 }
 
-- 
2.17.1




From lyz_cs at pku.edu.cn  Tue Jan 18 20:53:14 2022
From: lyz_cs at pku.edu.cn (Yongzhi Liu)
Date: Tue, 18 Jan 2022 20:53:14 -0800
Subject: [PATCH] drm/rockchip: Fix runtime PM imbalance on error
Message-ID: <1642567994-26165-1-git-send-email-lyz_cs@pku.edu.cn>

pm_runtime_get_sync() will increase the rumtime PM counter
even it returns an error. Thus a pairing decrement is needed
to prevent refcount leak. Fix this by replacing this API with
pm_runtime_resume_and_get(), which will not change the runtime
PM counter on error.

Signed-off-by: Yongzhi Liu <lyz_cs at pku.edu.cn>
---
 drivers/gpu/drm/rockchip/cdn-dp-core.c   | 2 +-
 drivers/gpu/drm/rockchip/rockchip_lvds.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
index 4740cc1..05c6abf 100644
--- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -100,7 +100,7 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp)
 		goto err_core_clk;
 	}
 
-	ret = pm_runtime_get_sync(dp->dev);
+	ret = pm_runtime_resume_and_get(dp->dev);
 	if (ret < 0) {
 		DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret);
 		goto err_pm_runtime_get;
diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c
index 0b97241..721ee0f 100644
--- a/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -146,7 +146,7 @@ static int rk3288_lvds_poweron(struct rockchip_lvds *lvds)
 		DRM_DEV_ERROR(lvds->dev, "failed to enable lvds pclk %d\n", ret);
 		return ret;
 	}
-	ret = pm_runtime_get_sync(lvds->dev);
+	ret = pm_runtime_resume_and_get(lvds->dev);
 	if (ret < 0) {
 		DRM_DEV_ERROR(lvds->dev, "failed to get pm runtime: %d\n", ret);
 		clk_disable(lvds->pclk);
-- 
2.7.4



From wenst at chromium.org  Tue Jan 18 21:57:18 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 19 Jan 2022 13:57:18 +0800
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_DISABLE
 readback
In-Reply-To: <eca4a0c18fe75536c8276410628b9459c040dce2.camel@mediatek.com>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-3-wenst@chromium.org>
 <eca4a0c18fe75536c8276410628b9459c040dce2.camel@mediatek.com>
Message-ID: <CAGXv+5GHVtCO9tN7B0O2c5V_Bk61-LL79LvbE1CRbyBfnvKSGQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 9:42 AM Guodong Liu <guodong.liu at mediatek.com> wrote:
>
> -----Original Message-----
> From: Chen-Yu Tsai <wenst at chromium.org>
> To: Sean Wang <sean.wang at kernel.org>, Linus Walleij <
> linus.walleij at linaro.org>, Matthias Brugger <matthias.bgg at gmail.com>
> Cc: Chen-Yu Tsai <wenst at chromium.org>,
> linux-mediatek at lists.infradead.org, linux-gpio at vger.kernel.org,
> linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
> Zhiyong Tao <zhiyong.tao at mediatek.com>, Guodong Liu <
> guodong.liu at mediatek.com>
> Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix
> PIN_CONFIG_BIAS_DISABLE readback
> Date: Tue, 11 Jan 2022 19:22:39 +0800
>
> When reading back pin bias settings, if the pin is not in a
> bias-disabled state, the function should return -EINVAL.
>
> Fix this in the mediatek-paris pinctrl library so that the read back
> state is not littered with bogus a "input bias disabled" combined with
> "pull up" or "pull down" states.
>
> Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that
> implements the vendor dt-bindings")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index f9f9110f2107..1ca598ea7ba7 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -97,8 +97,8 @@ static int mtk_pinconf_get(struct pinctrl_dev
> *pctldev,
>                         if (err)
>                                 goto out;
>                         if (param == PIN_CONFIG_BIAS_DISABLE) {
> -                               if (ret == MTK_PUPD_SET_R1R0_00)
> -                                       ret = MTK_DISABLE;
> +                               if (ret != MTK_PUPD_SET_R1R0_00)
> +                                       err = -EINVAL;
> Hi Chen-Yu
>
> When tht API "hw->soc->bias_get_combo(hw, desc, &pullup, &ret)" is
> called,
> The ret vaule of may be MTK_DISABLE OR MTK_PUPD_SET_R1R0_00 or  (pullen
> == 0),  All those cases are expected to be as "bias-disable".
> We advices to keep original code,
> +                               if (ret == MTK_PUPD_SET_R1R0_00)
> +
>                                 ret = MTK_DISABLE;
> +                               if (ret != MTK_DISABLE)
> +                                       err = -EINVAL;

IIUC you are suggesting to assign MTK_DISABLE to ret in the other two cases,
and then check if ret == MTK_DISABLE.

Thanks for pointing that out.

ChenYu

> Thanks
>                         } else if (param == PIN_CONFIG_BIAS_PULL_UP) {
>                                 /* When desire to get pull-up value,
> return
>                                  *  error if current setting is pull-
> down
>


From wenst at chromium.org  Tue Jan 18 21:59:29 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 19 Jan 2022 13:59:29 +0800
Subject: [PATCH v2 3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
In-Reply-To: <YecgcwXrQNzCesMN@google.com>
References: <20220114230209.4091727-1-briannorris@chromium.org>
 <20220114150129.v2.3.I3c79b1466c14b02980071221e5b99283cd26ec77@changeid>
 <CAGXv+5HC00YU6ARtGDahxWLqivvUCowh7wDq5H5OzoGO9htB+g@mail.gmail.com>
 <YecgcwXrQNzCesMN@google.com>
Message-ID: <CAGXv+5HANAorgJhSupH96V_n01VzvO5mY6LXf=bzzMi3ek089w@mail.gmail.com>

On Wed, Jan 19, 2022 at 4:18 AM Brian Norris <briannorris at chromium.org> wrote:
>
> Hi Chen-Yu,
>
> On Mon, Jan 17, 2022 at 05:01:52PM +0800, Chen-Yu Tsai wrote:
> > On Sat, Jan 15, 2022 at 7:03 AM Brian Norris <briannorris at chromium.org> wrote:
> > >
> > > Now that the cdn-dp driver supports plug-change callbacks, let's wire it
> > > up.
> > >
> > > Signed-off-by: Brian Norris <briannorris at chromium.org>
> > > ---
> > >
> > > (no changes since v1)
> > >
> > >  sound/soc/rockchip/rk3399_gru_sound.c | 20 ++++++++++++++++++++
> > >  1 file changed, 20 insertions(+)
> > >
> > > diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
> > > index e2d52d8d0ff9..eeef3ed70037 100644
> > > --- a/sound/soc/rockchip/rk3399_gru_sound.c
> > > +++ b/sound/soc/rockchip/rk3399_gru_sound.c
> > > @@ -164,6 +164,25 @@ static int rockchip_sound_da7219_hw_params(struct snd_pcm_substream *substream,
> > >         return 0;
> > >  }
> > >
> > > +static struct snd_soc_jack cdn_dp_card_jack;
> > > +
> > > +static int rockchip_sound_cdndp_init(struct snd_soc_pcm_runtime *rtd)
> > > +{
> > > +       struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
> >
> > Using snd_soc_card_get_codec_dai() might be a better choice throughout this
> > driver. While it will work for the cdn_dp case, because it is the first DAI
> > in |rockchip_dais[]|, all the invocations for the other codecs are likely
> > returning the wrong DAI.
>
> I'll admit, I'm not very familiar with the ASoC object model, so you may
> well be correct that there's something fishy in here. But I did trace
> through the objects involved here, and we *are* getting the correct DAI
> for both this case and the DA7219 case (preexisting code).

Neither am I, so ...

> It looks like we actually have a new runtime for each of our static
> dai_links:
>
> devm_snd_soc_register_card()
>   ...
>   for_each_card_prelinks()
>     snd_soc_add_pcm_runtime()
>
> So I think this is valid to keep as-is.

I missed this bit. As you say, things are good.

> > For this particular patch it works either way, so
> >
> > Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
>
> Thanks for looking!

And thanks for double checking!


From yu.tu at amlogic.com  Tue Jan 18 22:00:44 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Wed, 19 Jan 2022 14:00:44 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
Message-ID: <21eea0cd-5bf1-dec6-a776-f417aefa5bda@amlogic.com>

Hi Jiri,
	Thank you very much for your patient reply.I learned a lot from your 
response.

On 2022/1/18 17:39, Jiri Slaby wrote:
> [ EXTERNAL EMAIL ]
> 
> On 18. 01. 22, 4:09, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> ...
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
> ...
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>> ????? .cons??????? = MESON_SERIAL_CONSOLE,
>> ? };
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -???????????????????????? const char *id)
>> -{
>> -??? struct clk *clk = NULL;
>> -??? int ret;
>> -
>> -??? clk = devm_clk_get(dev, id);
>> -??? if (IS_ERR(clk))
>> -??????? return clk;
>> -
>> -??? ret = clk_prepare_enable(clk);
>> -??? if (ret) {
>> -??????? dev_err(dev, "couldn't enable clk\n");
>> -??????? return ERR_PTR(ret);
>> -??? }
>> -
>> -??? devm_add_action_or_reset(dev,
>> -??????????? (void(*)(void *))clk_disable_unprepare,
>> -??????????? clk);
>> -
>> -??? return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
> 
> This can be const, right?
You are right.
> 
>> +??? {0, 3},
>> +??? {1, 1},
>> +??? {2, 2},
>> +??? {3, 2},
> 
> Not sure if you didn't remove too much whitespace. I think it should be 
> like: "{ 0, 3 },". But I actually don't care, it's a minor thing.
> 
Ok, I will correct it if it needs to be changed.
> I cannot comment on the rest (clk and OF part) as my knowledge is pretty 
> limited there. Leaving up to others.
> 
Anyway, thanks for your reply.
> thanks,


From anshuman.khandual at arm.com  Tue Jan 18 22:17:18 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 19 Jan 2022 11:47:18 +0530
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <Yedgj+Lo2eru8197@casper.infradead.org>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <Yedgj+Lo2eru8197@casper.infradead.org>
Message-ID: <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>



On 1/19/22 6:21 AM, Matthew Wilcox wrote:
> On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
>> vmap() takes struct page *pages as one of arguments, and user may provide
>> an invalid pointer which would lead to DABT at address translation later.
> 
> Could we spell out 'DABT'?  Presumably that's an ARM-specific thing.
> Just like we don't say #PF for Intel page faults, I think this is
> probably a 'data abort'?

Right, it is data abort.

> 
>> Currently, kernel checks the pages against NULL. In my case, however, the
>> address was not NULL, and was big enough so that the hardware generated
>> Address Size Abort on arm64.

Could you please provide the actual abort stack here with details.

>>
>> Interestingly, this abort happens even if copy_from_kernel_nofault() is
>> used, which is quite inconvenient for debugging purposes. 
>>
>> This patch adds a pfn_valid() check into vmap() path, so that invalid
>> mapping will not be created.
>>
>> RFC: https://lkml.org/lkml/2022/1/18/815
>> v1: use pfn_valid() instead of adding an arch-specific
>>     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.

This should be after the '---' below.

>>
>> Signed-off-by: Yury Norov <yury.norov at gmail.com>
> 
> Suggested-by: Matthew Wilcox (Oracle) <willy at infradead.org>
> 
>> ---
>>  mm/vmalloc.c | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
>> index d2a00ad4e1dd..a4134ee56b10 100644
>> --- a/mm/vmalloc.c
>> +++ b/mm/vmalloc.c
>> @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
>>  			return -EBUSY;
>>  		if (WARN_ON(!page))
>>  			return -ENOMEM;
>> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
>> +			return -EINVAL;
>>  		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
>>  		(*nr)++;
>>  	} while (pte++, addr += PAGE_SIZE, addr != end);
>> -- 
>> 2.30.2
>>

Why should not this just scan over the entire user provided struct page
array and make sure that all pages there in are valid via above method,
but in vmap() itself before calling vmap_pages_range(). Because seems
like a single invalid page detected in vmap_pages_pte_range() will
anyways abort the entire vmap(). This will also enable us to drop the
existing NULL check above.


From yuzhao at google.com  Tue Jan 18 22:31:07 2022
From: yuzhao at google.com (Yu Zhao)
Date: Tue, 18 Jan 2022 23:31:07 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YeAU0n1puxyr4N6Y@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
 <Yduuyrk/AZG717Hs@google.com> <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>
 <Yd/0Sgxy+jLm5cqd@google.com> <YeAU0n1puxyr4N6Y@dhcp22.suse.cz>
Message-ID: <YeewK/cYG4MXV4f3@google.com>

On Thu, Jan 13, 2022 at 01:02:26PM +0100, Michal Hocko wrote:
> On Thu 13-01-22 02:43:38, Yu Zhao wrote:
> [...]
> > > > The bottom line is I can try various optimizations, e.g., preallocate
> > > > a few buffers for a limited number of page walkers and if this number
> > > > has been reached, fallback to the rmap-based function. But I have yet
> > > > to see evidence that calls for additional complexity.
> > > 
> > > I would disagree here. This is not an optimization. You should be
> > > avoiding allocations from the memory reclaim because any allocation just
> > > add a runtime behavior complexity and potential corner cases.
> > 
> > Would __GFP_NOMEMALLOC address your concern? It prevents allocations
> > from accessing the reserves even under PF_MEMALLOC.
> 
> __GFP_NOMEMALLOC would deal with the complete memory depletion concern
> for sure but I am not sure how any of these allocations would succeed
> when called from the direct reclaim. Some access to memory reserves is
> necessary if you insist on allocating from the reclaim process.
> 
> You can have a look at the limited memory reserves access by oom victims
> for an example of how this can be done.

Thanks. I'll change GFP_KERNEL to __GFP_HIGH | __GFP_NOMEMALLOC.
__GFP_HIGH allows some access to memory reserves and __GFP_NOMEMALLOC
prevents the complete depletion. Basically the combination lower the
min watermark by 1/2, and we have been using them for
add_to_swap_cache().


From xueshuai at linux.alibaba.com  Tue Jan 18 22:40:11 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Wed, 19 Jan 2022 14:40:11 +0800
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <20220118224935.GA903617@bhelgaas>
References: <20220118224935.GA903617@bhelgaas>
Message-ID: <e57cc874-dacd-912d-4282-3cb6b1b77323@linux.alibaba.com>

[+to Rafael, question about HEST/GHES/SDEI init]

Hi, Bjorn,

Thank you for your comments and quick reply.

? 2022/1/19 AM6:49, Bjorn Helgaas ??:
> On Sun, Jan 16, 2022 at 04:43:10PM +0800, Shuai Xue wrote:
>> On an ACPI system, ACPI is initialised very early from a
>> subsys_initcall(), while SDEI is not ready until a
>> subsys_initcall_sync(). This patch is to reduce the time before GHES
>> initialization.
>>
>> The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
>> apei_sdei_unregister_ghes()) to register or unregister event callback
>> for dispatcher in firmware. When the GHES driver probing, it registers
>> the corresponding callback according to the notification type specified
>> by GHES. If the GHES notification type is SDEI, the GHES driver will
>> call apei_sdei_register_ghes() to register event call.
>>
>> When the firmware emits an event, it migrates the handling of the event
>> into the kernel at the registered entry-point __sdei_asm_handler. And
>> finally, the kernel will call the registered event callback and return
>> status_code to indicate the status of event handling. SDEI_EV_FAILED
>> indicates that the kernel failed to handle the event.
>>
>> Consequently, when an error occurs during kernel booting, the kernel is
>> unable to handle and report errors until the GHES driver is initialized
>> by device_initcall(), in which the event callback is registered.  For
>> example, when the kernel booting, the console logs many times from
>> firmware before GHES drivers init in our platform:
>>
>> 	Trip in MM PCIe RAS handle(Intr:910)
>>   	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
>> 	Find RP(98:1.0)
>> 	--Walk dev(98:1.0) CE:0 UCE:4000
>> 	...
>> 	ERROR:   sdei_dispatch_event(32a) ret:-1
>> 	--handler(910) end
> 
> If I understand correctly, the firmware noticed an error, tried to
> report it to the kernel, and is complaining because the kernel isn't
> ready to handle it yet.  And the reason for this patch is to reduce
> these complaints from the firmware.

My thoughts exactly :)

> That doesn't seem like a very good reason for this patch.  There is
> *always* a window before the kernel is ready to handle events from the
> firmware.

Yes, there is always a window. But if we could do better in kernel that
reduces the window by 90% (from 33 seconds to 3 second), why not?

> Why is the firmware noticing these errors in the first place?  If
> you're seeing these complaints regularly, my guess is that either you
> have some terrible hardware or (more likely) the firmware isn't
> clearing some expected error condition correctly.  For example, maybe
> the Unsupported Request errors that happen while enumerating PCIe
> devices are being reported.
>
> If you register the callback function, the kernel will now start
> seeing these error reports.  What happens then?  Does the kernel log
> the errors somewhere?  Is that better than the current situation where
> the firmware logs them?

Yep, it is a hardware issue. The firmware only logs in console (ttyAMA0) and
we can not see it in kernel side. After the kernel starts seeing these error
reports, we could see EDAC/ghes and efi/cper detailed logs in dmesg. We did not
notice the problem until we check the console log, which inspired us to reduce
the window when kernel startup, so that we can see the message clearly and
properly. I think the intuition is to check the log of dmesg, not the console.

> However, I DO think that:
> 
>   - Removing acpi_hest_init() from acpi_pci_root_init(), and
> 
>   - Converting ghes_init() and sdei_init() from initcalls to explicit
>     calls
> 
> are very good reasons to do something like this patch because HEST is
> not PCI-specific, and IMO, explicit calls are better than initcalls
> because initcall ordering is implicit and not well-defined within a
> level.

Haha, if the above reasons still don't convince you, I would like to accept yours :)
Should we do it in one patch or separate it into two patches?

>> This is because the callback function has not been registered yet.  Due
>> to the poor design of firmware, previously reported errors will be
>> overwritten by new ones. Therefore, all errors that occurred before GHES
>> initialization are missed and there is no chance to report and find them
>> again.
>>
>> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
>> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
>> the estatus memory pool. On the other hand, ghes_init() relies on
>> sdei_init() to detect the SDEI version and the framework for registering
>> and unregistering events. The dependencies are as follows
>>
>> 	ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
>> 	ghes_init() => sdei_init()
>>
>> Based on above, move sdei_init and ghes_init as far ahead as possible,
>> right after acpi_iort_init() in acpi_init(). After this patch, there are
>> still errors missing, but we have to tolerate it until the software
>> reporting capability is built. And this patch merely reduce the time
>> before GHES initialization. The boot dmesg before this patch:
>>
>> 	[    3.688586] HEST: Table parsing has been initialized.
>> 	...
>> 	[   33.204340] calling  sdei_init+0x0/0x120 @ 1
>> 	[   33.208645] sdei: SDEIv1.0 (0x0) detected in firmware.
>> 	...
>> 	[   36.005390] calling  ghes_init+0x0/0x11c @ 1
>> 	[   36.190021] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
>>
>> After this patch, the boot dmesg like bellow:
>>
>> 	[    3.688664] HEST: Table parsing has been initialized.
>> 	[    3.688691] sdei: SDEIv1.0 (0x0) detected in firmware.
>> 	[    3.694557] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.
>>
>> As we can see, the initialization of GHES is advanced by 33 seconds.
>> (It should be noted that the effect of optimization varies with the
>> platform.)
>>
>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
>> ---
>>  drivers/acpi/apei/ghes.c    | 18 ++++++++----------
>>  drivers/acpi/bus.c          |  4 ++++
>>  drivers/acpi/pci_root.c     |  4 ++--
>>  drivers/firmware/arm_sdei.c | 13 ++-----------
>>  include/acpi/apei.h         |  2 ++
>>  include/linux/arm_sdei.h    |  2 ++
>>  6 files changed, 20 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 0c5c9acc6254..64f24a9f213f 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -1457,27 +1457,26 @@ static struct platform_driver ghes_platform_driver = {
>>  	.remove		= ghes_remove,
>>  };
>>  
>> -static int __init ghes_init(void)
>> +void __init ghes_init(void)
>>  {
>>  	int rc;
>>  
>>  	if (acpi_disabled)
>> -		return -ENODEV;
>> +		return;
>>  
>>  	switch (hest_disable) {
>>  	case HEST_NOT_FOUND:
>> -		return -ENODEV;
>> +		pr_info(GHES_PFX "HEST is not found!\n");
> 
> I don't know whether this "HEST is not found" message is worthwhile or
> not.  I don't think lack of an HEST is an error, and users may be
> alarmed.  But this is an ACPI thing, so up to you and Rafael.

If we explicit call ghes_init(), we can't tell if ghes is initialized
successfully based on the return value of initcall. So I add a info message.
What's your opinion, Rafeal?

>> +		return;
>>  	case HEST_DISABLED:
>>  		pr_info(GHES_PFX "HEST is not enabled!\n");
>> -		return -EINVAL;
>> +		return;
>>  	default:
>>  		break;
>>  	}
>>  
>> -	if (ghes_disable) {
>> +	if (ghes_disable)
>>  		pr_info(GHES_PFX "GHES is not enabled!\n");
>> -		return -EINVAL;
>> -	}
>>  
>>  	ghes_nmi_init_cxt();
> 
> Previously, if "ghes_disable", we returned immediately.  After this
> patch, if "ghes_disable", we print "GHES is not enabled!\n", but then
> we go on to call ghes_nmi_init_cxt() and register the
> &ghes_platform_driver.  That looks wrong.  Maybe you meant to keep a
> "return" here?

Sorry, it's my wrong. I will fix it in next version.

>> @@ -1495,8 +1494,7 @@ static int __init ghes_init(void)
>>  	else
>>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
>>  
>> -	return 0;
>> +	return;
>>  err:
>> -	return rc;
>> +	ghes_disable = 1;
> 
> Why do you set ghes_disable here?  As far as I can tell, we will never
> look at it again.  The places we do look at it are:
> 
>   - ghes_init(): earlier in this function, so we've already done that,
> 
>   - acpi_hest_init(): we've already called that, too, and
> 
>   - acpi_bus_osc_negotiate_platform_control(): called from
>     acpi_bus_init(), which we've already called.

I add it for future potential usage. Thank you for pointing it out.
If you think it is not necessary, I will delete it in next version.


>>  }
>> -device_initcall(ghes_init);
>> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
>> index 07f604832fd6..1dcd71df2cd5 100644
>> --- a/drivers/acpi/bus.c
>> +++ b/drivers/acpi/bus.c
>> @@ -30,6 +30,7 @@
>>  #include <linux/acpi_viot.h>
>>  #include <linux/pci.h>
>>  #include <acpi/apei.h>
>> +#include <linux/arm_sdei.h>
>>  #include <linux/suspend.h>
>>  #include <linux/prmt.h>
>>  
>> @@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
>>  
>>  	pci_mmcfg_late_init();
>>  	acpi_iort_init();
>> +	acpi_hest_init();
>> +	sdei_init();
>> +	ghes_init();
> 
> sdei_init() and ghes_init() stick out here because they're the only
> functions without an "acpi_" prefix.  Maybe a separate patch to rename
> them?

Great idea. I will add a patch to rename them with "acpi_" prefix

>>  	acpi_scan_init();
>>  	acpi_ec_init();
>>  	acpi_debugfs_init();
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index b76db99cced3..14e20af44627 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -23,7 +23,7 @@
>>  #include <linux/dmi.h>
>>  #include <linux/platform_data/x86/apple.h>
>>  #include <acpi/apei.h>	/* for acpi_hest_init() */
> 
> This #include looks like it may no longer be necessary.
>
>> -
>> +#include <linux/arm_sdei.h> /* for sdei_init() */
> 
> I don't think this #include is necessary.

Thank you for pointing it out. I will delete it in next version.

> 
>>  #include "internal.h"
>>  
>>  #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
>> @@ -943,7 +943,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>>  
>>  void __init acpi_pci_root_init(void)
>>  {
>> -	acpi_hest_init();
>> +
> 
> Drop the blank line here.

Got it. Will fix it.

> 
>>  	if (acpi_pci_disabled)
>>  		return;
>>  
>> diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
>> index a7e762c352f9..1e1a51510e83 100644
>> --- a/drivers/firmware/arm_sdei.c
>> +++ b/drivers/firmware/arm_sdei.c
>> @@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
>>  	return true;
>>  }
>>  
>> -static int __init sdei_init(void)
>> +void __init sdei_init(void)
>>  {
>>  	struct platform_device *pdev;
>>  	int ret;
>>  
>>  	ret = platform_driver_register(&sdei_driver);
>>  	if (ret || !sdei_present_acpi())
>> -		return ret;
>> +		return;
>>  
>>  	pdev = platform_device_register_simple(sdei_driver.driver.name,
>>  					       0, NULL, 0);
>> @@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
>>  		pr_info("Failed to register ACPI:SDEI platform device %d\n",
>>  			ret);
>>  	}
>> -
>> -	return ret;
>>  }
>>  
>> -/*
>> - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
>> - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
>> - * by device_initcall(). We want to be called in the middle.
>> - */
>> -subsys_initcall_sync(sdei_init);
>> -
>>  int sdei_event_handler(struct pt_regs *regs,
>>  		       struct sdei_registered_event *arg)
>>  {
>> diff --git a/include/acpi/apei.h b/include/acpi/apei.h
>> index ece0a8af2bae..7dbd6363fda7 100644
>> --- a/include/acpi/apei.h
>> +++ b/include/acpi/apei.h
>> @@ -27,8 +27,10 @@ extern int hest_disable;
>>  extern int erst_disable;
>>  #ifdef CONFIG_ACPI_APEI_GHES
>>  extern bool ghes_disable;
>> +void __init ghes_init(void);
>>  #else
>>  #define ghes_disable 1
>> +static inline void ghes_init(void) { return; }
> 
> "return" is unnecessary here.
>
>>  #endif
>>  
>>  #ifdef CONFIG_ACPI_APEI
>> diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
>> index 0a241c5c911d..9c987188b692 100644
>> --- a/include/linux/arm_sdei.h
>> +++ b/include/linux/arm_sdei.h
>> @@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
>>  /* For use by arch code when CPU hotplug notifiers are not appropriate. */
>>  int sdei_mask_local_cpu(void);
>>  int sdei_unmask_local_cpu(void);
>> +void __init sdei_init(void);
>>  #else
>>  static inline int sdei_mask_local_cpu(void) { return 0; }
>>  static inline int sdei_unmask_local_cpu(void) { return 0; }
>> +static inline void sdei_init(void) { return ; }
> 
> "return" is unnecessary here.

Got it. Will delete "return" in ghes_init(), sdei_init() and acpi_hest_init().

>>  #endif /* CONFIG_ARM_SDE_INTERFACE */
>>  
>>  
>> -- 
>> 2.20.1.12.g72788fdb
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From heying24 at huawei.com  Tue Jan 18 22:40:58 2022
From: heying24 at huawei.com (He Ying)
Date: Wed, 19 Jan 2022 14:40:58 +0800
Subject: [PATCH] arm64: entry: Save some nops when CONFIG_ARM64_PSEUDO_NMI
 is not set
In-Reply-To: <20220112032410.29231-1-heying24@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
 <20220112032410.29231-1-heying24@huawei.com>
Message-ID: <e6293ec4-7c56-194a-95f9-98b102d80b31@huawei.com>

Hi all,

Ping. Any comments?

? 2022/1/12 11:24, He Ying ??:
> Arm64 pseudo-NMI feature code brings some additional nops
> when CONFIG_ARM64_PSEUDO_NMI is not set, which is not
> necessary. So add necessary ifdeffery to avoid it.
>
> Signed-off-by: He Ying <heying24 at huawei.com>
> ---
>   arch/arm64/kernel/entry.S | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> index 2f69ae43941d..ffc32d3d909a 100644
> --- a/arch/arm64/kernel/entry.S
> +++ b/arch/arm64/kernel/entry.S
> @@ -300,6 +300,7 @@ alternative_else_nop_endif
>   	str	w21, [sp, #S_SYSCALLNO]
>   	.endif
>   
> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>   	/* Save pmr */
>   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>   	mrs_s	x20, SYS_ICC_PMR_EL1
> @@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>   	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
>   	msr_s	SYS_ICC_PMR_EL1, x20
>   alternative_else_nop_endif
> +#endif
>   
>   	/* Re-enable tag checking (TCO set on exception entry) */
>   #ifdef CONFIG_ARM64_MTE
> @@ -330,6 +332,7 @@ alternative_else_nop_endif
>   	disable_daif
>   	.endif
>   
> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>   	/* Restore pmr */
>   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>   	ldr	x20, [sp, #S_PMR_SAVE]
> @@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>   	dsb	sy				// Ensure priority change is seen by redistributor
>   .L__skip_pmr_sync\@:
>   alternative_else_nop_endif
> +#endif
>   
>   	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
>   


From jasowang at redhat.com  Tue Jan 18 22:42:15 2022
From: jasowang at redhat.com (Jason Wang)
Date: Wed, 19 Jan 2022 14:42:15 +0800
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <20220104194918.373612-5-rananta@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
Message-ID: <960d4166-1718-55ef-d324-507a8add7e3e@redhat.com>


? 2022/1/5 ??3:49, Raghavendra Rao Ananta ??:
> KVM regularly introduces new hypercall services to the guests without
> any consent from the Virtual Machine Manager (VMM). This means, the
> guests can observe hypercall services in and out as they migrate
> across various host kernel versions. This could be a major problem
> if the guest discovered a hypercall, started using it, and after
> getting migrated to an older kernel realizes that it's no longer
> available. Depending on how the guest handles the change, there's
> a potential chance that the guest would just panic.
>
> As a result, there's a need for the VMM to elect the services that
> it wishes the guest to discover. VMM can elect these services based
> on the kernels spread across its (migration) fleet. To remedy this,
> extend the existing firmware psuedo-registers, such as
> KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.



Haven't gone through the series but I wonder whether it's better to have 
a (e)BPF filter for this like seccomp.

Thanks


>
> These firmware registers are categorized based on the service call
> owners, and unlike the existing firmware psuedo-registers, they hold
> the features supported in the form of a bitmap.
>
> The capability, KVM_CAP_ARM_HVC_FW_REG_BMAP, is used to announce
> this extension, which returns the number of psuedo-firmware
> registers supported. During the VM initialization, the registers
> holds an upper-limit of the features supported by the corresponding
> registers. It's expected that the VMMs discover the features
> provided by each register via GET_ONE_REG, and writeback the
> desired values using SET_ONE_REG. KVM allows this modification
> only until the VM has started.
>
> Older VMMs can simply ignore the capability and the hypercall services
> will be exposed unconditionally to the guests, thus ensuring backward
> compatibility.
>
> In this patch, the framework adds the register only for ARM's standard
> secure services (owner value 4). Currently, this includes support only
> for ARM True Random Number Generator (TRNG) service, with bit-0 of the
> register representing mandatory features of v1.0. Other services are
> momentarily added in the upcoming patches.
>
> Signed-off-by: Raghavendra Rao Ananta<rananta at google.com>



From anshuman.khandual at arm.com  Tue Jan 18 22:44:23 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Wed, 19 Jan 2022 12:14:23 +0530
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <CAK8P3a2Q+iN1O6FEdUJRt=0bQu=6fkWAD3RCECfdhu4DKHq0pg@mail.gmail.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
 <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
 <00e28671-8d3a-f789-91c4-109814792a07@arm.com>
 <CAK8P3a2Q+iN1O6FEdUJRt=0bQu=6fkWAD3RCECfdhu4DKHq0pg@mail.gmail.com>
Message-ID: <519f3b4e-e790-c051-3cb1-3fd229a3e498@arm.com>



On 1/13/22 5:17 PM, Arnd Bergmann wrote:
> On Thu, Jan 13, 2022 at 4:03 AM Anshuman Khandual
> <anshuman.khandual at arm.com> wrote:
>> On 1/12/22 4:20 PM, Arnd Bergmann wrote:
>>> On Wed, Jan 12, 2022 at 10:34 AM Anshuman Khandual <anshuman.khandual at arm.com> wrote:
>>>> Add the CPU Partnumbers for the new Arm designs.
>>>> @@ -74,6 +74,7 @@
>>>>  #define ARM_CPU_PART_NEOVERSE_N1       0xD0C
>>>>  #define ARM_CPU_PART_CORTEX_A77                0xD0D
>>>>  #define ARM_CPU_PART_CORTEX_A710       0xD47
>>>> +#define ARM_CPU_PART_CORTEX_X2         0xD48
>>>>  #define ARM_CPU_PART_NEOVERSE_N2       0xD49
>>>
>>> No objections to the patch, but would it be possible to just add all the missing
>>> ones here to the degree that they are known already? I don't see any entries for
>>> Cortex-A34, Cortex-A65AE, Cortex-A78, Cortex-A78C, Cortex-A78AE,
>>> Neoverse-E1, Neoverse-V1, Cortex-X1, Cortex-X2, Cortex-A510, Cortex-A710
>>> and Cortex-R82 among the Arm-designed cores that can run Linux, and there
>>> are probably others that I missed going through the list.
>>
>> Hi Arnd,
>>
>> IIUC the part numbers are enumerated here only if there is an errata
>> applicable for them which needs to be detected at boot. I am not sure
>> whether all cpu versions that can run Linux, needs to be defined here.
>> But then I might be missing something.
> 
> They clearly don't need to be defined here, and for other constants such
> as the system registers we may not want to list them all, but I think for
> the CPU IDs it makes sense to just list them all here rather than adding
> them one at a time, as we tend to need them sooner or later anyway.
> 
> It also helps me personally to have a known place to look up the names
> by value rather than chasing through reference manuals.

IIUC the purpose here would be a quick CPU ID documentation reference check ?
I will wait for other opinions here and add the remaining in a separate patch
probably.

> 
>       Arnd
> 


From herbert at gondor.apana.org.au  Tue Jan 18 22:58:40 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Wed, 19 Jan 2022 17:58:40 +1100
Subject: [PATCH] crypto: authenc - Fix sleep in atomic context in decrypt_tail
In-Reply-To: <YeZx1aVL0HnT9tCB@Red>
References: <Yd1SIHUNdLIvKhzz@Red> <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
 <YeD6vt47+pAl0SxG@gondor.apana.org.au> <YeEiWmkyNwfgQgmn@Red>
 <YeZx1aVL0HnT9tCB@Red>
Message-ID: <Yee2oKxPSLaYY31N@gondor.apana.org.au>

On Tue, Jan 18, 2022 at 08:52:53AM +0100, Corentin Labbe wrote:
>
> With my patch, I got:
> [   38.515668] BUG: sleeping function called from invalid context at crypto/skcipher.c:482
> [   38.523708] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 84, name: 1c15000.crypto-
> [   38.532176] preempt_count: 200, expected: 0
> [   38.536381] CPU: 6 PID: 84 Comm: 1c15000.crypto- Not tainted 5.16.0-next-20220115-00124-g13473e8fac33-dirty #116
> [   38.546551] Hardware name: Allwinner A83t board
> [   38.551100]  unwind_backtrace from show_stack+0x10/0x14
> [   38.556358]  show_stack from dump_stack_lvl+0x40/0x4c
> [   38.561428]  dump_stack_lvl from __might_resched+0x118/0x154
> [   38.567107]  __might_resched from skcipher_walk_virt+0xe8/0xec
> [   38.572955]  skcipher_walk_virt from crypto_cbc_decrypt+0x2c/0x170
> [   38.579147]  crypto_cbc_decrypt from crypto_skcipher_decrypt+0x38/0x5c
> [   38.585680]  crypto_skcipher_decrypt from authenc_verify_ahash_done+0x18/0x34
> [   38.592825]  authenc_verify_ahash_done from crypto_finalize_request+0x6c/0xe4
> [   38.599974]  crypto_finalize_request from sun8i_ss_hash_run+0x73c/0xb98
> [   38.606602]  sun8i_ss_hash_run from crypto_pump_work+0x1a8/0x330
> [   38.612616]  crypto_pump_work from kthread_worker_fn+0xa8/0x1c4
> [   38.618550]  kthread_worker_fn from kthread+0xf0/0x110
> [   38.623701]  kthread from ret_from_fork+0x14/0x2c
> [   38.628414] Exception stack(0xc2247fb0 to 0xc2247ff8)
> [   38.633468] 7fa0:                                     00000000 00000000 00000000 00000000
> [   38.641640] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [   38.649809] 7fe0:i 00000000 00000000 00000000 00000000 00000013 00000000
> 
> This is when testing hmac(sha1) on my crypto driver sun8i-ss and crypto testing authenc(hmac-sha1-sun8i-ss,cbc(aes-generic)).
> 
> Do you have any idea to better fix my issue ?

This backtrace is caused by a bug in authenc:

---8<---
The function crypto_authenc_decrypt_tail discards its flags
argument and always relies on the flags from the original request
when starting its sub-request.

This is clearly wrong as it may cause the SLEEPABLE flag to be
set when it shouldn't.

Fixes: 92d95ba91772 ("crypto: authenc - Convert to new AEAD interface")
Reported-by: Corentin Labbe <clabbe.montjoie at gmail.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>

diff --git a/crypto/authenc.c b/crypto/authenc.c
index 670bf1a01d00..17f674a7cdff 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -253,7 +253,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req,
 		dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
 
 	skcipher_request_set_tfm(skreq, ctx->enc);
-	skcipher_request_set_callback(skreq, aead_request_flags(req),
+	skcipher_request_set_callback(skreq, flags,
 				      req->base.complete, req->base.data);
 	skcipher_request_set_crypt(skreq, src, dst,
 				   req->cryptlen - authsize, req->iv);
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From yuzhao at google.com  Tue Jan 18 23:04:10 2022
From: yuzhao at google.com (Yu Zhao)
Date: Wed, 19 Jan 2022 00:04:10 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz> <Ydu6fXg2FmrseQOn@google.com>
 <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz>
Message-ID: <Yee36hPfWSs+jR0m@google.com>

On Mon, Jan 10, 2022 at 11:54:42AM +0100, Michal Hocko wrote:
> On Sun 09-01-22 21:47:57, Yu Zhao wrote:
> > On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > [...]
> > > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > > +{
> > > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > > +		.test_walk = should_skip_vma,
> > > > +		.p4d_entry = walk_pud_range,
> > > > +	};
> > > > +
> > > > +	int err;
> > > > +#ifdef CONFIG_MEMCG
> > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > +#endif
> > > > +
> > > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > > +
> > > > +	do {
> > > > +		unsigned long start = walk->next_addr;
> > > > +		unsigned long end = mm->highest_vm_end;
> > > > +
> > > > +		err = -EBUSY;
> > > > +
> > > > +		rcu_read_lock();
> > > > +#ifdef CONFIG_MEMCG
> > > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > > +			goto contended;
> > > > +#endif
> > > > +		if (!mmap_read_trylock(mm))
> > > > +			goto contended;
> > > 
> > > Have you evaluated the behavior under mmap_sem contention? I mean what
> > > would be an effect of some mms being excluded from the walk? This path
> > > is called from direct reclaim and we do allocate with exclusive mmap_sem
> > > IIRC and the trylock can fail in a presence of pending writer if I am
> > > not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> > > can bypass the walk.
> > 
> > You are right. Here it must be a trylock; otherwise it can deadlock.
> 
> Yeah, this is clear.
> 
> > I think there might be a misunderstanding: the aging doesn't
> > exclusively rely on page table walks to gather the accessed bit. It
> > prefers page table walks but it can also fallback to the rmap-based
> > function, i.e., lru_gen_look_around(), which only gathers the accessed
> > bit from at most 64 PTEs and therefore is less efficient. But it still
> > retains about 80% of the performance gains.
> 
> I have to say that I really have hard time to understand the runtime
> behavior depending on that interaction. How does the reclaim behave when
> the virtual scan is enabled, partially enabled and almost completely
> disabled due to different constrains? I do not see any such an
> evaluation described in changelogs and I consider this to be a rather
> important information to judge the overall behavior.

It doesn't have (partially) enabled/disabled states nor does its
behavior change with different reclaim constraints. Having either
would make its design too complex to implement or benchmark.

There is feedback loop connecting page table walks and rmap walks by
Bloom filters. The Bloom filters hold dense hot areas. Page table walks
test whether virtual areas are in the Bloom filters and scan those that
were tested positive. Anything they miss will be caught by rmap walks
later (shrink_page_list()). And when rmap walks find new dense hot
areas, they add those area to the Bloom filters.

A dense hot area means it has many accessed pages belonging to the
reclaim domain, and clearing the accessed bit in all PTEs within this
area by one page table walk is more efficient than doing it one by one
by many rmap walks, in terms of cacheline utilization.

> > > Or is this considered statistically insignificant thus a theoretical
> > > problem?
> > 
> > Yes. People who work on the maple tree and SPF at Google expressed the
> > same concern during the design review meeting (all stakeholders on the
> > mailing list were also invited). So we had a counter to monitor the
> > contention in previous versions, i.e., MM_LOCK_CONTENTION in v4 here:
> > https://lore.kernel.org/lkml/20210818063107.2696454-8-yuzhao at google.com/
> > 
> > And we also combined this patchset with the SPF patchset to see if the
> > latter makes any difference. Our conclusion was the contention is
> > statistically insignificant to the performance under memory pressure.
> > 
> > This can be explained by how often we create a new generation. (We
> > only walk page tables when we create a new generation. And it's
> > similar to the low inactive condition for the active/inactive lru.)
> > 
> > Usually we only do so every few seconds. We'd run into problems with
> > other parts of the kernel, e.g., lru lock contention, i/o congestion,
> > etc. if we create more than a few generation every second.
> 
> This would be a very good information to have in changelogs. Ideally
> with some numbers and analysis.

Will do. Thanks.


From radheys at xilinx.com  Tue Jan 18 23:07:37 2022
From: radheys at xilinx.com (Radhey Shyam Pandey)
Date: Wed, 19 Jan 2022 07:07:37 +0000
Subject: [PATCH net v3 0/9] Xilinx axienet fixes
In-Reply-To: <993dcdd75d3839b5952e8632ae278f723273df03.camel@calian.com>
References: <20220118214132.357349-1-robert.hancock@calian.com>
 <993dcdd75d3839b5952e8632ae278f723273df03.camel@calian.com>
Message-ID: <SA1PR02MB85601DA6A4009BA3FDAF256BC7599@SA1PR02MB8560.namprd02.prod.outlook.com>

> -----Original Message-----
> From: Robert Hancock <robert.hancock at calian.com>
> Sent: Wednesday, January 19, 2022 4:35 AM
> To: netdev at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org; davem at davemloft.net;
> kuba at kernel.org; Michal Simek <michals at xilinx.com>; Radhey Shyam Pandey
> <radheys at xilinx.com>; daniel at iogearbox.net; andrew at lunn.ch
> Subject: Re: [PATCH net v3 0/9] Xilinx axienet fixes
> 
> On Tue, 2022-01-18 at 15:41 -0600, Robert Hancock wrote:
> > Various fixes for the Xilinx AXI Ethernet driver.
> >
> > Changed since v2:
> > -added Reviewed-by tags, added some explanation to commit messages, no
> > code changes
> >
> > Changed since v1:
> > -corrected a Fixes tag to point to mainline commit -split up reset
> > changes into 3 patches -added ratelimit on netdev_warn in TX busy case
> >
> > Robert Hancock (9):
> >   net: axienet: increase reset timeout
> >   net: axienet: Wait for PhyRstCmplt after core reset
> >   net: axienet: reset core on initialization prior to MDIO access
> >   net: axienet: add missing memory barriers
> >   net: axienet: limit minimum TX ring size
> >   net: axienet: Fix TX ring slot available check
> >   net: axienet: fix number of TX ring slots for available check
> >   net: axienet: fix for TX busy handling
> >   net: axienet: increase default TX ring size to 128
> >
> >  .../net/ethernet/xilinx/xilinx_axienet_main.c | 135
> > +++++++++++-------
> >  1 file changed, 84 insertions(+), 51 deletions(-)
> >
> 
> FYI, for the netdev/cc_maintainers Patchwork check, I dropped Ariane Keller <
> ariane.keller at tik.ee.ethz.ch> from the CC list as their mail was bouncing.

Thanks for the series. I have added Harini to this thread to also review
and add her Tested-by tag. Just FYI- We are in feature freeze so plan is
to close on this series by next week. Hope that's fine.

> 
> --
> Robert Hancock
> Senior Hardware Designer, Calian Advanced Technologies www.calian.com

From qianggui.song at amlogic.com  Tue Jan 18 23:08:05 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:05 +0800
Subject: [PATCH v2 0/4] irqchip/meson-gpio: Add support for Meson-S4 SoC
Message-ID: <20220119070809.15563-1-qianggui.song@amlogic.com>

This patchset add support for GPIO interrupt controller of Meson-S4 SoC
Which has something different with current other meson chips. To
support the new chips, current gpio irqchip driver need to rework as
below:
1. support more than 8 gpio irq lines.
2. add a set trigger type callback function.

With above work, add support for S4 gpio irqchip

Changes since v1 at [0]:
- fix leaking issue
- fix some typos
- change implementation of new feature.

[0] https://lore.kernel.org/linux-amlogic/20220108084218.31877-1-qianggui.song at amlogic.com/

Qianggui Song (4):
  dt-bindings: interrupt-controller: New binding for Meson-S4 SoCs
  irqchip/meson-gpio: support more than 8 channels gpio irq line
  irqchip/meson-gpio: add select trigger type callback
  irqchip/meson-gpio: Add support for meson s4 SoCs

 .../amlogic,meson-gpio-intc.txt               |   1 +
 drivers/irqchip/irq-meson-gpio.c              | 105 ++++++++++++++++--
 2 files changed, 97 insertions(+), 9 deletions(-)

-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:06 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:06 +0800
Subject: [PATCH v2 1/4] dt-bindings: interrupt-controller: New binding for
 Meson-S4 SoCs
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-2-qianggui.song@amlogic.com>

Update dt-binding document for GPIO interrupt controller of Meson-S4 SoCs

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 .../bindings/interrupt-controller/amlogic,meson-gpio-intc.txt    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
index 23b18b92c558..bde63f8f090e 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
+++ b/Documentation/devicetree/bindings/interrupt-controller/amlogic,meson-gpio-intc.txt
@@ -18,6 +18,7 @@ Required properties:
     "amlogic,meson-g12a-gpio-intc" for G12A SoCs (S905D2, S905X2, S905Y2)
     "amlogic,meson-sm1-gpio-intc" for SM1 SoCs (S905D3, S905X3, S905Y3)
     "amlogic,meson-a1-gpio-intc" for A1 SoCs (A113L)
+    "amlogic,meson-s4-gpio-intc" for S4 SoCs (S802X2, S905Y4, S805X2G, S905W2)
 - reg : Specifies base physical address and size of the registers.
 - interrupt-controller : Identifies the node as an interrupt controller.
 - #interrupt-cells : Specifies the number of cells needed to encode an
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:07 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:07 +0800
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels gpio
 irq line
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-3-qianggui.song@amlogic.com>

Current meson gpio irqchip driver only support 8 channels for gpio irq
line, later chips may have more then 8 channels, so need to modify code
to support more.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index d90ff0b92480..eefe15e1b3a6 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -16,7 +16,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#define NUM_CHANNEL 8
 #define MAX_INPUT_MUX 256
 
 #define REG_EDGE_POL	0x00
@@ -60,6 +59,7 @@ struct irq_ctl_ops {
 
 struct meson_gpio_irq_params {
 	unsigned int nr_hwirq;
+	unsigned int nr_channels;
 	bool support_edge_both;
 	unsigned int edge_both_offset;
 	unsigned int edge_single_offset;
@@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 0,				\
 	.pol_low_offset = 16,					\
 	.pin_sel_mask = 0xff,					\
+	.nr_channels = 8,					\
 
 #define INIT_MESON_A1_COMMON_DATA(irqs)				\
 	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
@@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
 	.edge_single_offset = 8,				\
 	.pol_low_offset = 0,					\
 	.pin_sel_mask = 0x7f,					\
+	.nr_channels = 8,					\
 
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
@@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 struct meson_gpio_irq_controller {
 	const struct meson_gpio_irq_params *params;
 	void __iomem *base;
-	u32 channel_irqs[NUM_CHANNEL];
-	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
+	u32 *channel_irqs;
+	unsigned long *channel_map;
 	spinlock_t lock;
 };
 
@@ -207,8 +209,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 	spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
-	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
-	if (idx >= NUM_CHANNEL) {
+	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
+	if (idx >= ctl->params->nr_channels) {
 		spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
@@ -447,13 +449,26 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
 
 	ctl->params = match->data;
 
+	ctl->channel_irqs = kcalloc(ctl->params->nr_channels, sizeof(*ctl->channel_irqs),
+				    GFP_KERNEL);
+	if (!ctl->channel_irqs)
+		return -ENOMEM;
+
+	ctl->channel_map = bitmap_zalloc(ctl->params->nr_channels, GFP_KERNEL);
+	if (!ctl->channel_map) {
+		kfree(ctl->channel_irqs);
+		return -ENOMEM;
+	}
+
 	ret = of_property_read_variable_u32_array(node,
 						  "amlogic,channel-interrupts",
 						  ctl->channel_irqs,
-						  NUM_CHANNEL,
-						  NUM_CHANNEL);
+						  ctl->params->nr_channels,
+						  ctl->params->nr_channels);
 	if (ret < 0) {
-		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
+		pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
+		kfree(ctl->channel_map);
+		kfree(ctl->channel_irqs);
 		return ret;
 	}
 
@@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
 	}
 
 	pr_info("%d to %d gpio interrupt mux initialized\n",
-		ctl->params->nr_hwirq, NUM_CHANNEL);
+		ctl->params->nr_hwirq, ctl->params->nr_channels);
 
 	return 0;
 
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:08 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:08 +0800
Subject: [PATCH v2 3/4] irqchip/meson-gpio: add select trigger type callback
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-4-qianggui.song@amlogic.com>

Due to some chips may use different registers and offset, provide
a set trigger type call back.

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index eefe15e1b3a6..b511f9532adc 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -55,6 +55,8 @@ struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
 				 unsigned int channel, unsigned long hwirq);
 	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
+	void (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
+				  unsigned int idx, u32 val);
 };
 
 struct meson_gpio_irq_params {
@@ -278,6 +280,12 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
 	 */
 	type &= IRQ_TYPE_SENSE_MASK;
 
+	/* Some controllers may have different calculation method*/
+	if (params->ops.gpio_irq_sel_type) {
+		params->ops.gpio_irq_sel_type(ctl, idx, type);
+		return 0;
+	}
+
 	/*
 	 * New controller support EDGE_BOTH trigger. This setting takes
 	 * precedence over the other edge/polarity settings
-- 
2.34.1



From qianggui.song at amlogic.com  Tue Jan 18 23:08:09 2022
From: qianggui.song at amlogic.com (Qianggui Song)
Date: Wed, 19 Jan 2022 15:08:09 +0800
Subject: [PATCH v2 4/4] irqchip/meson-gpio: Add support for meson s4 SoCs
In-Reply-To: <20220119070809.15563-1-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
Message-ID: <20220119070809.15563-5-qianggui.song@amlogic.com>

The meson s4 SoCs support 12 gpio irq lines compared with previous
serial chips and have something different, details are as below.

IRQ Number:
- 80:68 13 pins on bank Z
- 67:48 20 pins on bank X
- 47:36 12 pins on bank H
- 35:24 12 pins on bank D
- 23:22 2  pins on bank E
- 21:14 8  pins on bank C
- 13:0  13 pins on bank B

Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
---
 drivers/irqchip/irq-meson-gpio.c | 64 ++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
index b511f9532adc..896201d2f01f 100644
--- a/drivers/irqchip/irq-meson-gpio.c
+++ b/drivers/irqchip/irq-meson-gpio.c
@@ -42,6 +42,9 @@
 #define REG_PIN_SEL_SHIFT(x)	(((x) % 4) * 8)
 #define REG_FILTER_SEL_SHIFT(x)	((x) * 4)
 
+/* Used for s4 chips */
+#define REG_EDGE_POL_S4	0x1c
+
 struct meson_gpio_irq_controller;
 static void meson8_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				    unsigned int channel, unsigned long hwirq);
@@ -50,6 +53,8 @@ static void meson_a1_gpio_irq_sel_pin(struct meson_gpio_irq_controller *ctl,
 				      unsigned int channel,
 				      unsigned long hwirq);
 static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl);
+static void meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+				       unsigned int idx, u32 val);
 
 struct irq_ctl_ops {
 	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
@@ -95,6 +100,20 @@ struct meson_gpio_irq_params {
 	.pin_sel_mask = 0x7f,					\
 	.nr_channels = 8,					\
 
+#define INIT_MESON_S4_COMMON_DATA(irqs)				\
+	.nr_hwirq = irqs,					\
+	.ops = {						\
+		.gpio_irq_init = meson_a1_gpio_irq_init,	\
+		.gpio_irq_sel_pin = meson_a1_gpio_irq_sel_pin,	\
+		.gpio_irq_sel_type = meson_s4_gpio_irq_sel_type,\
+	},							\
+	.support_edge_both = true,				\
+	.edge_both_offset = 0,					\
+	.edge_single_offset = 12,				\
+	.pol_low_offset = 0,					\
+	.pin_sel_mask = 0xff,					\
+	.nr_channels = 12,					\
+
 static const struct meson_gpio_irq_params meson8_params = {
 	INIT_MESON8_COMMON_DATA(134)
 };
@@ -125,6 +144,10 @@ static const struct meson_gpio_irq_params a1_params = {
 	INIT_MESON_A1_COMMON_DATA(62)
 };
 
+static const struct meson_gpio_irq_params s4_params = {
+	INIT_MESON_S4_COMMON_DATA(82)
+};
+
 static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson8-gpio-intc", .data = &meson8_params },
 	{ .compatible = "amlogic,meson8b-gpio-intc", .data = &meson8b_params },
@@ -134,6 +157,7 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
 	{ .compatible = "amlogic,meson-g12a-gpio-intc", .data = &axg_params },
 	{ .compatible = "amlogic,meson-sm1-gpio-intc", .data = &sm1_params },
 	{ .compatible = "amlogic,meson-a1-gpio-intc", .data = &a1_params },
+	{ .compatible = "amlogic,meson-s4-gpio-intc", .data = &s4_params },
 	{ }
 };
 
@@ -200,6 +224,46 @@ static void meson_a1_gpio_irq_init(struct meson_gpio_irq_controller *ctl)
 	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL, BIT(31), BIT(31));
 }
 
+/*
+ * gpio irq relative registers for s4
+ * -PADCTRL_GPIO_IRQ_CTRL0
+ * bit[31]:    enable/disable all the irq lines
+ * bit[12-23]: single edge trigger
+ * bit[0-11]:  polarity trigger
+ *
+ * -PADCTRL_GPIO_IRQ_CTRL[X]
+ * bit[0-16]: 7 bits to choose gpio source for irq line 2*[X] - 2
+ * bit[16-22]:7 bits to choose gpio source for irq line 2*[X] - 1
+ * where X = 1-6
+ *
+ * -PADCTRL_GPIO_IRQ_CTRL[7]
+ * bit[0-11]: both edge trigger
+ */
+static void
+meson_s4_gpio_irq_sel_type(struct meson_gpio_irq_controller *ctl,
+			   unsigned int idx, unsigned int type)
+{
+	unsigned int val = 0;
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4, BIT(idx), 0);
+
+	if (type == IRQ_TYPE_EDGE_BOTH) {
+		val |= BIT(ctl->params->edge_both_offset + idx);
+		meson_gpio_irq_update_bits(ctl, REG_EDGE_POL_S4,
+					   BIT(ctl->params->edge_both_offset + idx), val);
+		return;
+	}
+
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->pol_low_offset + idx);
+
+	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
+		val |= BIT(ctl->params->edge_single_offset + idx);
+
+	meson_gpio_irq_update_bits(ctl, REG_EDGE_POL,
+				   BIT(idx) | BIT(12 + idx), val);
+};
+
 static int
 meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
 			       unsigned long  hwirq,
-- 
2.34.1



From giulio.benetti at benettiengineering.com  Tue Jan 18 23:18:16 2022
From: giulio.benetti at benettiengineering.com (Giulio Benetti)
Date: Wed, 19 Jan 2022 08:18:16 +0100
Subject: [PATCH 0/7] Fix wrong static ip autoconf in some dts and defconfig
In-Reply-To: <20211102235456.710617-1-giulio.benetti@benettiengineering.com>
References: <20211102235456.710617-1-giulio.benetti@benettiengineering.com>
Message-ID: <15227efe-0a85-b36d-41dd-28b93e3d35b3@benettiengineering.com>

Hello All,

kindly ping,

On 03/11/21 00:54, Giulio Benetti wrote:
> While trying to have a working nfsroot through RNDIS on sunxi I've found
> that in bootargs <autoconf> must be set to 'off' to use a static ip setup,
> but I've also found that the following boards have it set to 'on' that is
> not the <autoconf> setting for static ip as stated here:
> https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt

the documentantion states "<autoconf> must be set to 'off' to use a 
static ip setup"...

> And most of all on sunxi RNDIS it doesn't work as static ip nfsroot.
> 
> Unfortunately I don't have such boards to give a build and a test, so if
> there is someone who could give a try it would be great.

...so I don't even think it really deserves a test IMHO.

Best regards
-- 
Giulio Benetti
Benetti Engineering sas

> Best regards
> ---
> Giulio Benetti
> Benetti Engineering sas
> 
> Giulio Benetti (7):
>    ARM: dts: mmp2-brownstone: fix wrong static ip autoconf
>    ARM: dts: pxa168-aspenite: fix wrong static ip autoconf
>    ARM: dts: pxa910-dkb: fix wrong static ip autoconf
>    ARM: mmp2: update mmp2_defconfig to fix wrong static ip autoconf
>    ARM: pxa168: update pxa168_defconfig to fix wrong static ip autoconf
>    ARM: pxa3xx: update pxa3xx_defconfig to fix wrong static ip autoconf
>    ARM: pxa910: update pxa910_defconfig to fix wrong static ip autoconf
> 
>   arch/arm/boot/dts/mmp2-brownstone.dts | 2 +-
>   arch/arm/boot/dts/pxa168-aspenite.dts | 2 +-
>   arch/arm/boot/dts/pxa910-dkb.dts      | 2 +-
>   arch/arm/configs/mmp2_defconfig       | 2 +-
>   arch/arm/configs/pxa168_defconfig     | 2 +-
>   arch/arm/configs/pxa3xx_defconfig     | 2 +-
>   arch/arm/configs/pxa910_defconfig     | 2 +-
>   7 files changed, 7 insertions(+), 7 deletions(-)
> 



From krzysztof.kozlowski at canonical.com  Tue Jan 18 23:35:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 08:35:42 +0100
Subject: [PATCH] dt-bindings: Drop unnecessary pinctrl properties
In-Reply-To: <20220119015325.2438277-1-robh@kernel.org>
References: <20220119015325.2438277-1-robh@kernel.org>
Message-ID: <b303e38e-109b-e049-f536-c5b00830249b@canonical.com>

On 19/01/2022 02:53, Rob Herring wrote:
> For a single pinctrl mode, it is not necessary to define pinctrl
> properties as the tools always allow pinctrl properties.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../display/rockchip/rockchip,rk3066-hdmi.yaml         |  8 --------
>  Documentation/devicetree/bindings/input/gpio-keys.yaml |  6 ------
>  .../devicetree/bindings/pinctrl/cirrus,lochnagar.yaml  |  9 ---------
>  .../devicetree/bindings/pinctrl/cirrus,madera.yaml     | 10 ----------
>  .../devicetree/bindings/sound/samsung-i2s.yaml         |  6 ------
>  5 files changed, 39 deletions(-)
> 


Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From andrzej.hajda at intel.com  Tue Jan 18 23:35:52 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Wed, 19 Jan 2022 08:35:52 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <667a64ef-5121-ba92-964e-a9c075fc2375@intel.com>


On 19.01.2022 03:37, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
>
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
>
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
>
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Regards

Andrzej

> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>
>   drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>   drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>   drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>   drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>   include/linux/phy/phy-mipi-dphy.h                |  2 +-
>   5 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>    */
>   
>   #include <linux/bitfield.h>
> +#include <linux/bits.h>
>   #include <linux/clk.h>
>   #include <linux/irq.h>
>   #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>   /*
>    * ui2bc - UI time periods to byte clock cycles
>    */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>   {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>   }
>   
>   /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>   	}
>   
>   	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>   	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>   	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>   	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>   	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>   	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>   
>   #include <linux/bitfield.h>
>   #include <linux/bitops.h>
> +#include <linux/bits.h>
>   #include <linux/clk.h>
>   #include <linux/delay.h>
>   #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>   		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>   		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>   	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>   
>   	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>   		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>   
>   	cfg->clk_miss = 0;
>   	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>   	cfg->clk_prepare = 38000;
>   	cfg->clk_settle = 95000;
>   	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>   	if (cfg->clk_post < (60000 + 52 * ui))
>   		return -EINVAL;
>   
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>   		return -EINVAL;
>   
>   	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>    * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>    */
>   
> +#include <linux/bits.h>
>   #include <linux/kernel.h>
>   #include <linux/clk.h>
>   #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>   	 * The value of counter for HS Tclk-pre
>   	 * Tclk-pre = Tpin_txbyteclkhs * value
>   	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>   
>   	/*
>   	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>   	 * the transmitter prior to any associated Data Lane beginning
>   	 * the transition from LP to HS mode.
>   	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>   	 */
>   	unsigned int		clk_pre;
>   


From mst at redhat.com  Tue Jan 18 23:39:46 2022
From: mst at redhat.com (Michael S. Tsirkin)
Date: Wed, 19 Jan 2022 02:39:46 -0500
Subject: [PATCH v3] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <20220119010551.181405-1-gshan@redhat.com>
References: <20220119010551.181405-1-gshan@redhat.com>
Message-ID: <20220119022611-mutt-send-email-mst@kernel.org>

On Wed, Jan 19, 2022 at 09:05:51AM +0800, Gavin Shan wrote:
> This enables virtio-mem device support by allowing to enable the
> corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
> architecture.
> 
> Signed-off-by: Gavin Shan <gshan at redhat.com>
> Acked-by: David Hildenbrand <david at redhat.com>
> Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
> Acked-by: Michael S. Tsirkin <mst at redhat.com>
> ---
> v3: Pick ack-by tags from Jonathan and Michael
> ---
>  drivers/virtio/Kconfig | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> index 34f80b7a8a64..74c8b0c7bc33 100644
> --- a/drivers/virtio/Kconfig
> +++ b/drivers/virtio/Kconfig
> @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
>  config VIRTIO_MEM
>  	tristate "Virtio mem driver"
>  	default m
> -	depends on X86_64
> +	depends on X86_64 || ARM64
>  	depends on VIRTIO
>  	depends on MEMORY_HOTPLUG
>  	depends on MEMORY_HOTREMOVE
> @@ -116,8 +116,9 @@ config VIRTIO_MEM
>  	 This driver provides access to virtio-mem paravirtualized memory
>  	 devices, allowing to hotplug and hotunplug memory.
>  
> -	 This driver was only tested under x86-64, but should theoretically
> -	 work on all architectures that support memory hotplug and hotremove.
> +	 This driver was only tested under x86-64 and arm64, but should
> +	 theoretically work on all architectures that support memory hotplug
> +	 and hotremove.
>  

BTW isn't there a symbol saying "memory hotplug" that we can depend on?


>  	 If unsure, say M.
>  
> -- 
> 2.23.0



From arnd at arndb.de  Tue Jan 18 23:44:54 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 19 Jan 2022 08:44:54 +0100
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <519f3b4e-e790-c051-3cb1-3fd229a3e498@arm.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
 <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
 <00e28671-8d3a-f789-91c4-109814792a07@arm.com>
 <CAK8P3a2Q+iN1O6FEdUJRt=0bQu=6fkWAD3RCECfdhu4DKHq0pg@mail.gmail.com>
 <519f3b4e-e790-c051-3cb1-3fd229a3e498@arm.com>
Message-ID: <CAK8P3a1t5N_vW3rcMD_e+UMy5EQDrTrE4QqPDo7nM_s1-Bf0XQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 7:44 AM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
> On 1/13/22 5:17 PM, Arnd Bergmann wrote:
> >
> > It also helps me personally to have a known place to look up the names
> > by value rather than chasing through reference manuals.
>
> IIUC the purpose here would be a quick CPU ID documentation reference check ?
> I will wait for other opinions here and add the remaining in a separate patch
> probably.

The purpose would be to do what is obviously the right thing, and to avoid
more patches getting sent the next time someone needs to add a workaround
for another core that is already known.

If you can't do this without more discussion, then just use your
current version and
let the next person do it.

        Arnd


From gshan at redhat.com  Tue Jan 18 23:46:25 2022
From: gshan at redhat.com (Gavin Shan)
Date: Wed, 19 Jan 2022 15:46:25 +0800
Subject: [PATCH v3] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <20220119022611-mutt-send-email-mst@kernel.org>
References: <20220119010551.181405-1-gshan@redhat.com>
 <20220119022611-mutt-send-email-mst@kernel.org>
Message-ID: <d8cedad1-bbb6-b7ea-57b2-f3832776fe1e@redhat.com>

Hi Michael,

On 1/19/22 3:39 PM, Michael S. Tsirkin wrote:
> On Wed, Jan 19, 2022 at 09:05:51AM +0800, Gavin Shan wrote:
>> This enables virtio-mem device support by allowing to enable the
>> corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
>> architecture.
>>
>> Signed-off-by: Gavin Shan <gshan at redhat.com>
>> Acked-by: David Hildenbrand <david at redhat.com>
>> Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>> Acked-by: Michael S. Tsirkin <mst at redhat.com>
>> ---
>> v3: Pick ack-by tags from Jonathan and Michael
>> ---
>>   drivers/virtio/Kconfig | 7 ++++---
>>   1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
>> index 34f80b7a8a64..74c8b0c7bc33 100644
>> --- a/drivers/virtio/Kconfig
>> +++ b/drivers/virtio/Kconfig
>> @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
>>   config VIRTIO_MEM
>>   	tristate "Virtio mem driver"
>>   	default m
>> -	depends on X86_64
>> +	depends on X86_64 || ARM64
>>   	depends on VIRTIO
>>   	depends on MEMORY_HOTPLUG
>>   	depends on MEMORY_HOTREMOVE
>> @@ -116,8 +116,9 @@ config VIRTIO_MEM
>>   	 This driver provides access to virtio-mem paravirtualized memory
>>   	 devices, allowing to hotplug and hotunplug memory.
>>   
>> -	 This driver was only tested under x86-64, but should theoretically
>> -	 work on all architectures that support memory hotplug and hotremove.
>> +	 This driver was only tested under x86-64 and arm64, but should
>> +	 theoretically work on all architectures that support memory hotplug
>> +	 and hotremove.
>>   
> 
> BTW isn't there a symbol saying "memory hotplug" that we can depend on?
> 

You mean to change it like below? Actually, both looks good
to me :)

  +	 This driver was only tested under x86-64 and arm64, but should
  +	 theoretically work on all architectures.
  
>>   	 If unsure, say M.
>>   

Thanks,
Gavin



From reijiw at google.com  Tue Jan 18 23:47:13 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Tue, 18 Jan 2022 23:47:13 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YedWUJNnQK3HFrWC@google.com>
References: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
 <YedWUJNnQK3HFrWC@google.com>
Message-ID: <CAAeT=FyJAG1dEFLvrQ4UXrwUqBUhY0AKkjzFpyi74zCJZUEYVg@mail.gmail.com>

On Tue, Jan 18, 2022 at 4:07 PM Sean Christopherson <seanjc at google.com> wrote:
>
> On Fri, Jan 14, 2022, Reiji Watanabe wrote:
> > The restriction, with which KVM doesn't need to worry about the changes
> > in the registers after KVM_RUN, could potentially protect or be useful
> > to protect KVM and simplify future changes/maintenance of the KVM codes
> > that consumes the values.
>
> That sort of protection is definitely welcome, the previously mentioned CPUID mess
> on x86 would have benefit greatly by KVM being restrictive in the past.  That said,
> hooking KVM_RUN is likely the wrong way to go about implementing any restrictions.
> Running a vCPU is where much of the vCPU's state is explicitly consumed, but it's
> all too easy for KVM to implicity/indirectly consume state via a different ioctl(),
> e.g. if there are side effects that are visible in other registers, than an update
> can also be visible to userspace via KVM_{G,S}ET_{S,}REGS, at which point disallowing
> modifying state after KVM_RUN but not after reading/writing regs is arbitrary and
> inconsitent.

Thank you for your comments !
I think I understand your concern, and that's a great point.
That's not the case for those pseudo registers though at least for now :)
BTW, is this concern specific to hooking KVM_RUN ? (Wouldn't it be the
same for the option with "if kvm->created_vcpus > 0" ?)


> If possible, preventing modification if kvm->created_vcpus > 0 is ideal as it's
> a relatively common pattern in KVM, and provides a clear boundary to userpace
> regarding what is/isn't allowed.

Yes, I agree that would be better in general.  For (pseudo) registers,
I would think preventing modification if kvm->created_vcpus > 0 might
not be a very good option for KVM/ARM though considering usage of
KVM_GET_REG_LIST and KVM_{G,S}ET_ONE_REG.

Thanks,
Reiji


From bhe at redhat.com  Wed Jan 19 00:08:59 2022
From: bhe at redhat.com (Baoquan He)
Date: Wed, 19 Jan 2022 16:08:59 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <YebK70Sx4w8zLfj/@xhacker>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv> <YebK70Sx4w8zLfj/@xhacker>
Message-ID: <20220119080859.GB4977@MiWiFi-R3L-srv>

On 01/18/22 at 10:13pm, Jisheng Zhang wrote:
> On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> > Hi Jisheng,
> 
> Hi Baoquan,
> 
> > 
> > On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > > and increase compile coverage.
> > 
> > I go through this patchset, You mention the benefits it brings are
> > 1) simplity the code;
> > 2) increase compile coverage;
> > 
> > For benefit 1), it mainly removes the dummy function in x86, arm and
> > arm64, right?
> 
> Another benefit: remove those #ifdef #else #endif usage. Recently, I
> fixed a bug due to lots of "#ifdefs":
> http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html

Glad to know the fix. While, sometime the ifdeffery is necessary. I am
sorry about the one in riscv and you have fixed, it's truly a bug . But,
the increasing compile coverage at below you tried to make, it may cause
issue. Please see below my comment.

> 
> > 
> > For benefit 2), increasing compile coverage, could you tell more how it
> > achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> > purpose? Please forgive my poor compiling knowledge.
> 
> Just my humble opinion, let's compare the code::
> 
> #ifdef CONFIG_KEXEC_CORE
> 
> code block A;
> 
> #endif
> 
> If KEXEC_CORE is disabled, code block A won't be compiled at all, the
> preprocessor will remove code block A;
> 
> If we convert the code to:
> 
> if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
> 	code block A;
> }
> 
> Even if KEXEC_CORE is disabled, code block A is still compiled.

This is what I am worried about. Before, if CONFIG_KEXEC_CORE is
unset, those relevant codes are not compiled in. I can't see what
benefit is brought in if compiled in the unneeded code block. Do I miss
anything?



From miles.chen at mediatek.com  Wed Jan 19 00:24:46 2022
From: miles.chen at mediatek.com (miles.chen at mediatek.com)
Date: Wed, 19 Jan 2022 16:24:46 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
Message-ID: <20220119082447.1675-1-miles.chen@mediatek.com>

From: Miles Chen <miles.chen at mediatek.com>

With CONFIG_CFI_CLANG=y, we observe a CFI failure of
blake2s_compress_generic.

Reverting commit 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
is a solution for this problem. So I looked into the patch
and I think it is caused by the weak symbols use by blake2s_compress().

To fix it, remove the weak symbol and use CRYPTO_ARCH_HAVE_LIB_BLAKE2S
to select blake2s_compress_arch/blake2s_compress_generic.

log:
[    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
[    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
[    0.000000][    T0] Hardware name: MT6873 (DT)
[    0.000000][    T0] Call trace:
[    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
[    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
[    0.000000][    T0]  panic+0x194/0x464
[    0.000000][    T0]  __cfi_check_fail+0x54/0x58
[    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
[    0.000000][    T0]  blake2s_update+0x14c/0x178
[    0.000000][    T0]  _extract_entropy+0xf4/0x29c
[    0.000000][    T0]  crng_initialize_primary+0x24/0x94
[    0.000000][    T0]  rand_initialize+0x2c/0x6c
[    0.000000][    T0]  start_kernel+0x2f8/0x65c
[    0.000000][    T0]  __primary_switched+0xc4/0x7be4
[    0.000000][    T0] Rebooting in 5 seconds..

Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 lib/crypto/blake2s-generic.c | 3 +--
 lib/crypto/blake2s.c         | 6 ++++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/crypto/blake2s-generic.c b/lib/crypto/blake2s-generic.c
index 75ccb3e633e6..22fa3ea1689e 100644
--- a/lib/crypto/blake2s-generic.c
+++ b/lib/crypto/blake2s-generic.c
@@ -38,8 +38,7 @@ static inline void blake2s_increment_counter(struct blake2s_state *state,
 }
 
 void blake2s_compress(struct blake2s_state *state, const u8 *block,
-		      size_t nblocks, const u32 inc)
-		      __weak __alias(blake2s_compress_generic);
+		      size_t nblocks, const u32 inc);
 
 void blake2s_compress_generic(struct blake2s_state *state, const u8 *block,
 			      size_t nblocks, const u32 inc)
diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 93f2ae051370..4055aa593ec4 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -16,6 +16,12 @@
 #include <linux/init.h>
 #include <linux/bug.h>
 
+#if IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S)
+#  define blake2s_compress blake2s_compress_arch
+#else
+#  define blake2s_compress blake2s_compress_generic
+#endif
+
 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 {
 	__blake2s_update(state, in, inlen, blake2s_compress);
-- 
2.18.0



From andrzej.hajda at intel.com  Wed Jan 19 00:34:43 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Wed, 19 Jan 2022 09:34:43 +0100
Subject: [v10,1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <20220119022543.26093-2-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-2-rex-bc.chen@mediatek.com>
Message-ID: <dd84f8d4-097e-45b9-aa75-812b1fc524ff@intel.com>


On 19.01.2022 03:25, Rex-BC Chen wrote:
> Since a HS transmission is composed of an arbitrary number
> of bytes that may not be an integer multiple of lanes, some
> lanes may run out of data before others.
> (Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)
>
> However, for some DSI RX devices (for example, anx7625),
> there is a limitation that packet number should be the same
> on all DSI lanes. In other words, they need to end a HS at
> the same time.
>
> Because this limitation is for some specific DSI RX devices,
> it is more reasonable to put the enable control in these
> DSI RX drivers. If DSI TX driver knows the information,
> they can adjust the setting for this situation.
>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Regards

Andrzej

> ---
>   include/drm/drm_mipi_dsi.h | 2 ++
>   1 file changed, 2 insertions(+)
>
> diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
> index 147e51b6d241..51e09a1a106a 100644
> --- a/include/drm/drm_mipi_dsi.h
> +++ b/include/drm/drm_mipi_dsi.h
> @@ -137,6 +137,8 @@ struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node);
>   #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
>   /* transmit data in low power */
>   #define MIPI_DSI_MODE_LPM		BIT(11)
> +/* transmit data ending at the same time for all lanes within one hsync */
> +#define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
>   
>   enum mipi_dsi_pixel_format {
>   	MIPI_DSI_FMT_RGB888,


From david at redhat.com  Wed Jan 19 00:35:05 2022
From: david at redhat.com (David Hildenbrand)
Date: Wed, 19 Jan 2022 09:35:05 +0100
Subject: [PATCH v3] drivers/virtio: Enable virtio mem for ARM64
In-Reply-To: <d8cedad1-bbb6-b7ea-57b2-f3832776fe1e@redhat.com>
References: <20220119010551.181405-1-gshan@redhat.com>
 <20220119022611-mutt-send-email-mst@kernel.org>
 <d8cedad1-bbb6-b7ea-57b2-f3832776fe1e@redhat.com>
Message-ID: <50422908-1917-bda9-ead5-40b02d57c545@redhat.com>

On 19.01.22 08:46, Gavin Shan wrote:
> Hi Michael,
> 
> On 1/19/22 3:39 PM, Michael S. Tsirkin wrote:
>> On Wed, Jan 19, 2022 at 09:05:51AM +0800, Gavin Shan wrote:
>>> This enables virtio-mem device support by allowing to enable the
>>> corresponding kernel config option (CONFIG_VIRTIO_MEM) on the
>>> architecture.
>>>
>>> Signed-off-by: Gavin Shan <gshan at redhat.com>
>>> Acked-by: David Hildenbrand <david at redhat.com>
>>> Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
>>> Acked-by: Michael S. Tsirkin <mst at redhat.com>
>>> ---
>>> v3: Pick ack-by tags from Jonathan and Michael
>>> ---
>>>   drivers/virtio/Kconfig | 7 ++++---
>>>   1 file changed, 4 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
>>> index 34f80b7a8a64..74c8b0c7bc33 100644
>>> --- a/drivers/virtio/Kconfig
>>> +++ b/drivers/virtio/Kconfig
>>> @@ -106,7 +106,7 @@ config VIRTIO_BALLOON
>>>   config VIRTIO_MEM
>>>   	tristate "Virtio mem driver"
>>>   	default m
>>> -	depends on X86_64
>>> +	depends on X86_64 || ARM64
>>>   	depends on VIRTIO
>>>   	depends on MEMORY_HOTPLUG
>>>   	depends on MEMORY_HOTREMOVE
>>> @@ -116,8 +116,9 @@ config VIRTIO_MEM
>>>   	 This driver provides access to virtio-mem paravirtualized memory
>>>   	 devices, allowing to hotplug and hotunplug memory.
>>>   
>>> -	 This driver was only tested under x86-64, but should theoretically
>>> -	 work on all architectures that support memory hotplug and hotremove.
>>> +	 This driver was only tested under x86-64 and arm64, but should
>>> +	 theoretically work on all architectures that support memory hotplug
>>> +	 and hotremove.
>>>   
>>
>> BTW isn't there a symbol saying "memory hotplug" that we can depend on?
>>

You mean

 	depends on MEMORY_HOTPLUG
 	depends on MEMORY_HOTREMOVE

We still need a manual opt-in from architectures, because devil's in the
detail. (e.g., memblock stuff we had to adjust)

-- 
Thanks,

David / dhildenb



From andrzej.hajda at intel.com  Wed Jan 19 00:35:01 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Wed, 19 Jan 2022 09:35:01 +0100
Subject: [v10,2/3] drm/mediatek: implement the DSI HS packets aligned
In-Reply-To: <20220119022543.26093-3-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-3-rex-bc.chen@mediatek.com>
Message-ID: <4abe1f96-aafd-71bc-5f5e-bfcc4320c8c4@intel.com>


On 19.01.2022 03:25, Rex-BC Chen wrote:
> Some DSI RX devices (for example, anx7625) require last alignment of
> packets on all lanes after each row of data is sent.
> Otherwise, there will be some issues of shift or scroll for screen.
>
> Take horizontal_sync_active_byte for a example,
> we roundup the HSA packet data to lane number, and the subtraction of 2
> is the packet data value added by the roundup operation, making the
> long packets are integer multiples of lane number.
> This value (2) varies with the lane number, and that is the reason we
> do this operation when the lane number is 4.
>
> In the previous operation of function "mtk_dsi_config_vdo_timing",
> the length of HSA and HFP data packets has been adjusted to an
> integration multiple of lane number.
> Since the number of RGB data packets cannot be guaranteed to be an
> integer multiple of lane number, we modify the data packet length of
> HBP so that the number of HBP + RGB is equal to the lane number.
> So after sending a line of data (HSA + HBP + RGB + HFP), the data
> lanes are aligned.
>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Regards

Andrzej

> ---
>   drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
>   1 file changed, 12 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..e91b3fff4342 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -500,6 +500,18 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>   		DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
>   	}
>   
> +	if ((dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) &&
> +	    (dsi->lanes == 4)) {
> +		horizontal_sync_active_byte =
> +			roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> +		horizontal_frontporch_byte =
> +			roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> +		horizontal_backporch_byte =
> +			roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> +		horizontal_backporch_byte -=
> +			(vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
> +	}
> +
>   	writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>   	writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>   	writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);


From andrzej.hajda at intel.com  Wed Jan 19 00:35:20 2022
From: andrzej.hajda at intel.com (Andrzej Hajda)
Date: Wed, 19 Jan 2022 09:35:20 +0100
Subject: [v10,3/3] drm/bridge: anx7625: config hs packets end aligned to
 avoid screen shift
In-Reply-To: <20220119022543.26093-4-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-4-rex-bc.chen@mediatek.com>
Message-ID: <7a8852b8-c108-f48d-172e-fa2e7605db9f@intel.com>


On 19.01.2022 03:25, Rex-BC Chen wrote:
> This device requires the packets on lanes aligned at the end to fix
> screen shift or scroll.
>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Xin Ji <xji at analogixsemi.com>

Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Regards

Andrzej

> ---
>   drivers/gpu/drm/bridge/analogix/anx7625.c | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c
> index 2346dbcc505f..fe32ab0878ae 100644
> --- a/drivers/gpu/drm/bridge/analogix/anx7625.c
> +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c
> @@ -1673,7 +1673,8 @@ static int anx7625_attach_dsi(struct anx7625_data *ctx)
>   	dsi->format = MIPI_DSI_FMT_RGB888;
>   	dsi->mode_flags = MIPI_DSI_MODE_VIDEO	|
>   		MIPI_DSI_MODE_VIDEO_SYNC_PULSE	|
> -		MIPI_DSI_MODE_VIDEO_HSE;
> +		MIPI_DSI_MODE_VIDEO_HSE	|
> +		MIPI_DSI_HS_PKT_END_ALIGNED;
>   
>   	ret = devm_mipi_dsi_attach(dev, dsi);
>   	if (ret) {


From narmstrong at baylibre.com  Wed Jan 19 00:40:02 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:40:02 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>

Hi,

On 19/01/2022 03:37, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |

I'll try to run a test, currently the calculation gives 2, so this would give 1.

Neil

> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  
> 



From angelogioacchino.delregno at collabora.com  Wed Jan 19 00:43:10 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 19 Jan 2022 09:43:10 +0100
Subject: [v10,2/3] drm/mediatek: implement the DSI HS packets aligned
In-Reply-To: <4abe1f96-aafd-71bc-5f5e-bfcc4320c8c4@intel.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-3-rex-bc.chen@mediatek.com>
 <4abe1f96-aafd-71bc-5f5e-bfcc4320c8c4@intel.com>
Message-ID: <35821437-8f62-e4f3-0614-2a6a59668938@collabora.com>

Il 19/01/22 09:35, Andrzej Hajda ha scritto:
> 
> On 19.01.2022 03:25, Rex-BC Chen wrote:
>> Some DSI RX devices (for example, anx7625) require last alignment of
>> packets on all lanes after each row of data is sent.
>> Otherwise, there will be some issues of shift or scroll for screen.
>>
>> Take horizontal_sync_active_byte for a example,
>> we roundup the HSA packet data to lane number, and the subtraction of 2
>> is the packet data value added by the roundup operation, making the
>> long packets are integer multiples of lane number.
>> This value (2) varies with the lane number, and that is the reason we
>> do this operation when the lane number is 4.
>>
>> In the previous operation of function "mtk_dsi_config_vdo_timing",
>> the length of HSA and HFP data packets has been adjusted to an
>> integration multiple of lane number.
>> Since the number of RGB data packets cannot be guaranteed to be an
>> integer multiple of lane number, we modify the data packet length of
>> HBP so that the number of HBP + RGB is equal to the lane number.
>> So after sending a line of data (HSA + HBP + RGB + HFP), the data
>> lanes are aligned.
>>
>> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
>> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
>> Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
> 
> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> 
> Regards
> 
> Andrzej
> 
>> ---
>> ? drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
>> ? 1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..e91b3fff4342 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -500,6 +500,18 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>> ????????? DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
>> ????? }
>> +??? if ((dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) &&
>> +??????? (dsi->lanes == 4)) {
>> +??????? horizontal_sync_active_byte =
>> +??????????? roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
>> +??????? horizontal_frontporch_byte =
>> +??????????? roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
>> +??????? horizontal_backporch_byte =
>> +??????????? roundup(horizontal_backporch_byte, dsi->lanes) - 2;
>> +??????? horizontal_backporch_byte -=
>> +??????????? (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
>> +??? }
>> +
>> ????? writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>> ????? writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>> ????? writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);


From narmstrong at baylibre.com  Wed Jan 19 00:52:27 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:52:27 +0100
Subject: [PATCH v2 3/4] irqchip/meson-gpio: add select trigger type
 callback
In-Reply-To: <20220119070809.15563-4-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-4-qianggui.song@amlogic.com>
Message-ID: <fb7db50f-866a-233b-1c9b-093cd50473c8@baylibre.com>

Hi,

On 19/01/2022 08:08, Qianggui Song wrote:
> Due to some chips may use different registers and offset, provide
> a set trigger type call back.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index eefe15e1b3a6..b511f9532adc 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -55,6 +55,8 @@ struct irq_ctl_ops {
>  	void (*gpio_irq_sel_pin)(struct meson_gpio_irq_controller *ctl,
>  				 unsigned int channel, unsigned long hwirq);
>  	void (*gpio_irq_init)(struct meson_gpio_irq_controller *ctl);
> +	void (*gpio_irq_sel_type)(struct meson_gpio_irq_controller *ctl,
> +				  unsigned int idx, u32 val);
>  };
>  
>  struct meson_gpio_irq_params {
> @@ -278,6 +280,12 @@ static int meson_gpio_irq_type_setup(struct meson_gpio_irq_controller *ctl,
>  	 */
>  	type &= IRQ_TYPE_SENSE_MASK;
>  
> +	/* Some controllers may have different calculation method*/
> +	if (params->ops.gpio_irq_sel_type) {
> +		params->ops.gpio_irq_sel_type(ctl, idx, type);
> +		return 0;
> +	}
> +
>  	/*
>  	 * New controller support EDGE_BOTH trigger. This setting takes
>  	 * precedence over the other edge/polarity settings
> 

The comment on v1 hasn't been addresses here, it was asked to move the old controllers
sel_type to a callback and introduce an S4 callback instead of doing this.

Neil


From alexandre.ghiti at canonical.com  Wed Jan 19 00:52:16 2022
From: alexandre.ghiti at canonical.com (Alexandre Ghiti)
Date: Wed, 19 Jan 2022 09:52:16 +0100
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <20220119080859.GB4977@MiWiFi-R3L-srv>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv>
 <YebK70Sx4w8zLfj/@xhacker> <20220119080859.GB4977@MiWiFi-R3L-srv>
Message-ID: <CA+zEjCvqYAWaWW9hVbHqYm_GbV-BaiOM4c77WHnxDNh+SRDUuw@mail.gmail.com>

Hi Baoquan,

On Wed, Jan 19, 2022 at 9:11 AM Baoquan He <bhe at redhat.com> wrote:
>
> On 01/18/22 at 10:13pm, Jisheng Zhang wrote:
> > On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> > > Hi Jisheng,
> >
> > Hi Baoquan,
> >
> > >
> > > On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > > > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > > > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > > > and increase compile coverage.
> > >
> > > I go through this patchset, You mention the benefits it brings are
> > > 1) simplity the code;
> > > 2) increase compile coverage;
> > >
> > > For benefit 1), it mainly removes the dummy function in x86, arm and
> > > arm64, right?
> >
> > Another benefit: remove those #ifdef #else #endif usage. Recently, I
> > fixed a bug due to lots of "#ifdefs":
> > http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html
>
> Glad to know the fix. While, sometime the ifdeffery is necessary. I am
> sorry about the one in riscv and you have fixed, it's truly a bug . But,
> the increasing compile coverage at below you tried to make, it may cause
> issue. Please see below my comment.
>
> >
> > >
> > > For benefit 2), increasing compile coverage, could you tell more how it
> > > achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> > > purpose? Please forgive my poor compiling knowledge.
> >
> > Just my humble opinion, let's compare the code::
> >
> > #ifdef CONFIG_KEXEC_CORE
> >
> > code block A;
> >
> > #endif
> >
> > If KEXEC_CORE is disabled, code block A won't be compiled at all, the
> > preprocessor will remove code block A;
> >
> > If we convert the code to:
> >
> > if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
> >       code block A;
> > }
> >
> > Even if KEXEC_CORE is disabled, code block A is still compiled.
>
> This is what I am worried about. Before, if CONFIG_KEXEC_CORE is
> unset, those relevant codes are not compiled in. I can't see what
> benefit is brought in if compiled in the unneeded code block. Do I miss
> anything?
>

This is explained in Documentation/process/coding-style.rst "21)
Conditional Compilation".

Alex

>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


From narmstrong at baylibre.com  Wed Jan 19 00:53:00 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 09:53:00 +0100
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels
 gpio irq line
In-Reply-To: <20220119070809.15563-3-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-3-qianggui.song@amlogic.com>
Message-ID: <4c6b7f6b-b9a2-c08d-7ac4-f5132808b1c5@baylibre.com>

On 19/01/2022 08:08, Qianggui Song wrote:
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..eefe15e1b3a6 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int nr_channels;
>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.nr_channels = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.nr_channels = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;
>  	spinlock_t lock;
>  };
>  
> @@ -207,8 +209,8 @@ meson_gpio_irq_request_channel(struct meson_gpio_irq_controller *ctl,
>  	spin_lock_irqsave(&ctl->lock, flags);
>  
>  	/* Find a free channel */
> -	idx = find_first_zero_bit(ctl->channel_map, NUM_CHANNEL);
> -	if (idx >= NUM_CHANNEL) {
> +	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
> +	if (idx >= ctl->params->nr_channels) {
>  		spin_unlock_irqrestore(&ctl->lock, flags);
>  		pr_err("No channel available\n");
>  		return -ENOSPC;
> @@ -447,13 +449,26 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i
>  
>  	ctl->params = match->data;
>  
> +	ctl->channel_irqs = kcalloc(ctl->params->nr_channels, sizeof(*ctl->channel_irqs),
> +				    GFP_KERNEL);
> +	if (!ctl->channel_irqs)
> +		return -ENOMEM;
> +
> +	ctl->channel_map = bitmap_zalloc(ctl->params->nr_channels, GFP_KERNEL);
> +	if (!ctl->channel_map) {
> +		kfree(ctl->channel_irqs);
> +		return -ENOMEM;
> +	}
> +
>  	ret = of_property_read_variable_u32_array(node,
>  						  "amlogic,channel-interrupts",
>  						  ctl->channel_irqs,
> -						  NUM_CHANNEL,
> -						  NUM_CHANNEL);
> +						  ctl->params->nr_channels,
> +						  ctl->params->nr_channels);
>  	if (ret < 0) {
> -		pr_err("can't get %d channel interrupts\n", NUM_CHANNEL);
> +		pr_err("can't get %d channel interrupts\n", ctl->params->nr_channels);
> +		kfree(ctl->channel_map);
> +		kfree(ctl->channel_irqs);
>  		return ret;
>  	}
>  
> @@ -507,7 +522,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *
>  	}
>  
>  	pr_info("%d to %d gpio interrupt mux initialized\n",
> -		ctl->params->nr_hwirq, NUM_CHANNEL);
> +		ctl->params->nr_hwirq, ctl->params->nr_channels);
>  
>  	return 0;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From daniel.lezcano at linaro.org  Wed Jan 19 00:57:19 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 19 Jan 2022 09:57:19 +0100
Subject: [PATCH v6 5/5] rockchip/soc/drivers: Add DTPM description for rk3399
In-Reply-To: <20220119085719.1357874-1-daniel.lezcano@linaro.org>
References: <20220119085719.1357874-1-daniel.lezcano@linaro.org>
Message-ID: <20220119085719.1357874-6-daniel.lezcano@linaro.org>

The DTPM framework does support now the hierarchy description.

The platform specific code can call the hierarchy creation function
with an array of struct dtpm_node pointing to their parent.

This patch provides a description of the big / Little CPUs and the
GPU and tie them together under a virtual 'package' name. Only rk3399 is
described now.

The description could be extended in the future with the memory
controller with devfreq.

The description is always a module and it describes the soft
dependencies. The userspace has to load the softdeps module in the
right order.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/soc/rockchip/Kconfig  |  8 +++++
 drivers/soc/rockchip/Makefile |  1 +
 drivers/soc/rockchip/dtpm.c   | 59 +++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 drivers/soc/rockchip/dtpm.c

diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
index 25eb2c1e31bb..6dc017f02431 100644
--- a/drivers/soc/rockchip/Kconfig
+++ b/drivers/soc/rockchip/Kconfig
@@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS
 
           If unsure, say N.
 
+config ROCKCHIP_DTPM
+	tristate "Rockchip DTPM hierarchy"
+	depends on DTPM && DRM_PANFROST && m
+	help
+	 Describe the hierarchy for the Dynamic Thermal Power
+	 Management tree on this platform. That will create all the
+	 power capping capable devices.
+
 endif
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
index 875032f7344e..05f31a4e743c 100644
--- a/drivers/soc/rockchip/Makefile
+++ b/drivers/soc/rockchip/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
 obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
 obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
+obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
new file mode 100644
index 000000000000..0b73a9cba954
--- /dev/null
+++ b/drivers/soc/rockchip/dtpm.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2021 Linaro Limited
+ *
+ * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
+ *
+ * DTPM hierarchy description
+ */
+#include <linux/dtpm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static struct dtpm_node __initdata rk3399_hierarchy[] = {
+	[0]{ .name = "rk3399",
+	     .type = DTPM_NODE_VIRTUAL },
+	[1]{ .name = "package",
+	     .type = DTPM_NODE_VIRTUAL,
+	     .parent = &rk3399_hierarchy[0] },
+	[2]{ .name = "/cpus/cpu at 0",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[3]{ .name = "/cpus/cpu at 1",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[4]{ .name = "/cpus/cpu at 2",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[5]{ .name = "/cpus/cpu at 3",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[6]{ .name = "/cpus/cpu at 100",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[7]{ .name = "/cpus/cpu at 101",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[8]{ .name = "/gpu at ff9a0000",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[9]{ },
+};
+
+static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
+        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
+        {},
+};
+
+static int __init rockchip_dtpm_init(void)
+{
+	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
+}
+module_init(rockchip_dtpm_init);
+
+MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
+MODULE_DESCRIPTION("Rockchip DTPM driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dtpm");
+MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano at kernel.org");
-- 
2.25.1



From maxime at cerno.tech  Wed Jan 19 00:59:58 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 19 Jan 2022 09:59:58 +0100
Subject: (subset) [PATCH v4 1/2] arm: dts: sun7i: Add A20-Marsboard
In-Reply-To: <tencent_C2E26D0935C9157CB3597BA4BD3316E8940A@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <tencent_C2E26D0935C9157CB3597BA4BD3316E8940A@qq.com>
Message-ID: <164258279605.29285.8984289239298980655.b4-ty@cerno.tech>

On Sat, 15 Jan 2022 00:31:47 +0800, Conley Lee wrote:
> The Marsboard A20 is a A20 based SBC with 1G RAM, 8G Flash, micro SD
> card slot , SATA socketm 10/100 ethernet, HDMI port, 4 USB2.0 ports, 2
> USB2.0 OTG, USB WIFI(RTL8188EU) with antenna.
> 
> 

Applied to local tree (sunxi/dt-for-5.18).

Thanks!
Maxime


From maxime at cerno.tech  Wed Jan 19 00:59:59 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 19 Jan 2022 09:59:59 +0100
Subject: (subset) [PATCH v4 2/2] dt-bindings: arm: sunxi: add haoyu,
 a20-marsboard
In-Reply-To: <tencent_B6059C6C031E46EFCB05D5A5015B1C4DE608@qq.com>
References: <tencent_DC7B4D416B69D6D6789356010B5B9647C606@qq.com>
 <20220114163148.2854265-1-conleylee@foxmail.com>
 <tencent_B6059C6C031E46EFCB05D5A5015B1C4DE608@qq.com>
Message-ID: <164258279605.29285.6847365560924211664.b4-ty@cerno.tech>

On Sat, 15 Jan 2022 00:31:48 +0800, Conley Lee wrote:
> From: conley <conleylee at foxmail.com>
> 
> add haoyu,a20-marsboard dt-bindings
> 
> 

Applied to local tree (sunxi/dt-for-5.18).

Thanks!
Maxime


From Jason at zx2c4.com  Wed Jan 19 01:00:30 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 10:00:30 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <20220119082447.1675-1-miles.chen@mediatek.com>
References: <20220119082447.1675-1-miles.chen@mediatek.com>
Message-ID: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>

Hi Miles,

Thanks for the patch. Could you let me know which architecture and
compiler this was broken on? If I had to guess, I'd wager arm32, and
you hit this by enabling optimized blake2s?

If so, I'm not sure the problem is with weak symbols. Why should CFI
break weak symbols? Rather, perhaps the issue is that the function is
defined in blake2s-core.S? Are there some CFI macros we need for that
definition?

Jason


From Jason at zx2c4.com  Wed Jan 19 01:09:00 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 10:09:00 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
References: <20220119082447.1675-1-miles.chen@mediatek.com>
 <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
Message-ID: <CAHmME9rWs_w_dMfDLFuD-tr79cnVyuny4fLn9Wh0+bs76Nt0MA@mail.gmail.com>

Hey again,

Actually... It looks like the issue is that in this file:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/crypto/internal/blake2s.h

this line

typedef void (*blake2s_compress_t)(struct blake2s_state *state,
				   const u8 *block, size_t nblocks, u32 inc);

should become

typedef void (*blake2s_compress_t)(struct blake2s_state *state,
				   const u8 *block, size_t nblocks, const u32 inc);

Does making that change fix things for you?

Thanks,
Jason


From javierm at redhat.com  Wed Jan 19 01:09:51 2022
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 19 Jan 2022 10:09:51 +0100
Subject: [PATCH v3 00/10] drm: Make drivers to honour the nomodeset
 parameter
In-Reply-To: <20211222082831.196562-1-javierm@redhat.com>
References: <20211222082831.196562-1-javierm@redhat.com>
Message-ID: <e956363f-d62a-3c73-6dae-6c691c63dedc@redhat.com>

On 12/22/21 09:28, Javier Martinez Canillas wrote:
> The nomodeset kernel command line parameter is used to prevent the KMS/DRM
> drivers to be registered/probed. But only a few drivers implement support
> for this and most DRM drivers just ignore it.
> 
> This patch series is a v3 to make DRM drivers to honour nomodeset. It is
> posted as separate patches to make easier for drivers maintainers to ack
> or pick them independently at their own pace.
> 

[snip]

> 
> Thomas Zimmermann (5):
>   drm: Provide PCI module-init macros
>   drm/ast: Replace module-init boiler-plate code with DRM helpers
>   drm/bochs: Replace module-init boiler-plate code with DRM helpers
>   drm/cirrus: Replace module-init boiler-plate code with DRM helpers
>   drm/hisilicon/hibmc: Replace module initialization with DRM helpers
>

For Thomas' patches (1-5)

Reviewed-by: Javier Martinez Canillas <javierm at redhat.com>

Best regards,
-- 
Javier Martinez Canillas
Linux Engineering
Red Hat



From ardb at kernel.org  Wed Jan 19 01:09:59 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 19 Jan 2022 10:09:59 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
References: <20220119082447.1675-1-miles.chen@mediatek.com>
 <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
Message-ID: <CAMj1kXEuWRUbCqDBnxiWRaERt6OGL8ufQ1Q7naAGHqKK1oQB1w@mail.gmail.com>

(+ Sami, Eric)

On Wed, 19 Jan 2022 at 10:00, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> Hi Miles,
>
> Thanks for the patch. Could you let me know which architecture and
> compiler this was broken on? If I had to guess, I'd wager arm32, and
> you hit this by enabling optimized blake2s?
>
> If so, I'm not sure the problem is with weak symbols. Why should CFI
> break weak symbols? Rather, perhaps the issue is that the function is
> defined in blake2s-core.S? Are there some CFI macros we need for that
> definition?
>

We should try to understand why CFI thinks the prototypes of the two
symbols are different. There are still a number of issues with CFI, so
papering over them by reverting stuff that we want for good reasons is
not the way to go imo.

In the short term, you can work around it by avoiding the indirect
call to blake2s_compress, e.g.,

diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 93f2ae051370..fef2ff678431 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -16,9 +16,15 @@
 #include <linux/init.h>
 #include <linux/bug.h>

+static void __blake2s_compress(struct blake2s_state *state, const u8 *block,
+                              size_t nblocks, const u32 inc)
+{
+       return blake2s_compress(state, block, nblocks, inc);
+}
+
 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 {
-       __blake2s_update(state, in, inlen, blake2s_compress);
+       __blake2s_update(state, in, inlen, __blake2s_compress);
 }
 EXPORT_SYMBOL(blake2s_update);


From angelogioacchino.delregno at collabora.com  Wed Jan 19 01:10:42 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 19 Jan 2022 10:10:42 +0100
Subject: [PATCH] media: platform: mtk-vcodec: Do not force /dev/videoX
 node number
In-Reply-To: <20220118150717.706074-1-benjamin.gaignard@collabora.com>
References: <20220118150717.706074-1-benjamin.gaignard@collabora.com>
Message-ID: <72ac959b-ad5f-8f4e-38d1-3da9d9866290@collabora.com>

Il 18/01/22 16:07, Benjamin Gaignard ha scritto:
> Let's v4l2 framework use a free /dev/videoX node for decode and encoder.
> For the decoder call video_register_device() before register the media
> controller device so the mapping between ins correctly done.
> Since the registering sequence has changed rework exiting errors case too.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Hello Benjamin,
please add the following Fixes tags to this commit:

Fixes: 590577a4e525 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Decoder 
Driver")

Fixes: 4e855a6efa54 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Encoder 
Driver")

After that..

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From narmstrong at baylibre.com  Wed Jan 19 01:11:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 10:11:51 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
Message-ID: <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>

On 19/01/2022 09:40, Neil Armstrong wrote:
> Hi,
> 
> On 19/01/2022 03:37, Liu Ying wrote:
>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>> mentions that it should be in UI.  However, the dphy core driver wrongly
>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>> is '8 UI', instead of 8.
>>
>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>> value according to the D-PHY specification.
>>
>> I'm assuming that all impacted custom drivers shall program values in
>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>> custom driver code is changed to program those values as
>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>
>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>> as I don't have the hardwares.
>>
>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>> Cc: Robert Foss <robert.foss at linaro.org>
>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>> Cc: Jonas Karlman <jonas at kwiboo.se>
>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>> Cc: David Airlie <airlied at linux.ie>
>> Cc: Daniel Vetter <daniel at ffwll.ch>
>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>> Cc: Vinod Koul <vkoul at kernel.org>
>> Cc: Kevin Hilman <khilman at baylibre.com>
>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>> Cc: Heiko Stuebner <heiko at sntech.de>
>> Cc: Maxime Ripard <mripard at kernel.org>
>> Cc: Guido G?nther <agx at sigxcpu.org>
>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>> ---
>> v1->v2:
>> * Use BITS_PER_BYTE macro. (Andrzej)
>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>
>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>
[...]

>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> index cd2332bf0e31..fdbd64c03e12 100644
>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>> @@ -9,6 +9,7 @@
>>  
>>  #include <linux/bitfield.h>
>>  #include <linux/bitops.h>
>> +#include <linux/bits.h>
>>  #include <linux/clk.h>
>>  #include <linux/delay.h>
>>  #include <linux/io.h>
>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>  
>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> 
> I'll try to run a test, currently the calculation gives 2, so this would give 1.

The Amlogic vendor code does:

/* >8*ui */
#define DPHY_TIME_CLK_PRE(ui)       (10 * ui)

t_ui = lcd_timing.bit_rate

t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
temp = t_ui * 8; /* lane_byte cycle time */

dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;

PHY Registers only says:
MIPI_DSI_CLK_TIM1	[31:0]
7:0 	R/W	0	 tCLK_PRE

> 
> Neil
> 

[...]


From ardb at kernel.org  Wed Jan 19 01:13:51 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 19 Jan 2022 10:13:51 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXEuWRUbCqDBnxiWRaERt6OGL8ufQ1Q7naAGHqKK1oQB1w@mail.gmail.com>
References: <20220119082447.1675-1-miles.chen@mediatek.com>
 <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
 <CAMj1kXEuWRUbCqDBnxiWRaERt6OGL8ufQ1Q7naAGHqKK1oQB1w@mail.gmail.com>
Message-ID: <CAMj1kXGUtg1BOauCjxB+S7yMTPArQrPnHf5jnfhOihL-FHrFZA@mail.gmail.com>

On Wed, 19 Jan 2022 at 10:09, Ard Biesheuvel <ardb at kernel.org> wrote:
>
> (+ Sami, Eric)
>
> On Wed, 19 Jan 2022 at 10:00, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> >
> > Hi Miles,
> >
> > Thanks for the patch. Could you let me know which architecture and
> > compiler this was broken on? If I had to guess, I'd wager arm32, and
> > you hit this by enabling optimized blake2s?
> >
> > If so, I'm not sure the problem is with weak symbols. Why should CFI
> > break weak symbols? Rather, perhaps the issue is that the function is
> > defined in blake2s-core.S? Are there some CFI macros we need for that
> > definition?
> >
>
> We should try to understand why CFI thinks the prototypes of the two
> symbols are different. There are still a number of issues with CFI, so
> papering over them by reverting stuff that we want for good reasons is
> not the way to go imo.
>
> In the short term, you can work around it by avoiding the indirect
> call to blake2s_compress, e.g.,
>
> diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
> index 93f2ae051370..fef2ff678431 100644
> --- a/lib/crypto/blake2s.c
> +++ b/lib/crypto/blake2s.c
> @@ -16,9 +16,15 @@
>  #include <linux/init.h>
>  #include <linux/bug.h>
>
> +static void __blake2s_compress(struct blake2s_state *state, const u8 *block,
> +                              size_t nblocks, const u32 inc)
> +{
> +       return blake2s_compress(state, block, nblocks, inc);
> +}
> +
>  void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
>  {
> -       __blake2s_update(state, in, inlen, blake2s_compress);
> +       __blake2s_update(state, in, inlen, __blake2s_compress);
>  }
>  EXPORT_SYMBOL(blake2s_update);

Ehm, maybe not. As Jason points out, the typedef does not have quite
the right type, so that is most likely the culprit, and this
workaround would trigger CFI in exactly the same way.

Interestingly, the compiler does not seem to mind, right? Or are you
seeing any build time warnings on the reference to blake2s_compress in
the call to __blake2s_update() ?


From ck.hu at mediatek.com  Wed Jan 19 01:15:31 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Wed, 19 Jan 2022 17:15:31 +0800
Subject: [PATCH v7 5/8] drm/mediatek: dpi: Add dpintf support
In-Reply-To: <20211217150854.2081-6-granquet@baylibre.com>
References: <20211217150854.2081-1-granquet@baylibre.com>
 <20211217150854.2081-6-granquet@baylibre.com>
Message-ID: <d94c32869633e1341e5fd17ab17f5b5358f590e8.camel@mediatek.com>

Hi, Guillaume:

On Fri, 2021-12-17 at 16:08 +0100, Guillaume Ranquet wrote:
> From: Markus Schneider-Pargmann <msp at baylibre.com>
> 
> dpintf is the displayport interface hardware unit. This unit is
> similar
> to dpi and can reuse most of the code.
> 
> This patch adds support for mt8195-dpintf to this dpi driver. Main
> differences are:
>  - Some features/functional components are not available for dpintf
>    which are now excluded from code execution once is_dpintf is set
>  - dpintf can and needs to choose between different clockdividers
> based
>    on the clockspeed. This is done by choosing a different clock
> parent.
>  - There are two additional clocks that need to be managed. These are
>    only set for dpintf and will be set to NULL if not supplied. The
>    clk_* calls handle these as normal clocks then.
>  - Some register contents differ slightly between the two components.
> To
>    work around this I added register bits/masks with a DPINTF_ prefix
>    and use them where different.
> 
> Based on a separate driver for dpintf created by
> Jason-JH.Lin <jason-jh.lin at mediatek.com>.
> 
> Signed-off-by: Markus Schneider-Pargmann <msp at baylibre.com>
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dpi.c          | 304 ++++++++++++++++
> ----
>  drivers/gpu/drm/mediatek/mtk_dpi_regs.h     |  38 +++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |   4 +
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   5 +-
>  include/linux/soc/mediatek/mtk-mmsys.h      |   2 +
>  6 files changed, 299 insertions(+), 55 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c
> b/drivers/gpu/drm/mediatek/mtk_dpi.c
> index 4554e2de14309..fbc43ea4049b9 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dpi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c
> @@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format {
>  	MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL
>  };
>  
> +enum TVDPLL_CLK {
> +	TVDPLL_PLL = 0,
> +	TVDPLL_D2 = 2,
> +	TVDPLL_D4 = 4,
> +	TVDPLL_D8 = 8,
> +	TVDPLL_D16 = 16,
> +};
> +
>  struct mtk_dpi {
>  	struct drm_encoder encoder;
>  	struct drm_bridge bridge;
> @@ -71,8 +79,10 @@ struct mtk_dpi {
>  	void __iomem *regs;
>  	struct device *dev;
>  	struct clk *engine_clk;
> +	struct clk *dpi_ck_cg;
>  	struct clk *pixel_clk;
>  	struct clk *tvd_clk;
> +	struct clk *pclk_src[5];
>  	int irq;
>  	struct drm_display_mode mode;
>  	const struct mtk_dpi_conf *conf;
> @@ -125,6 +135,18 @@ struct mtk_dpi_conf {
>  	bool edge_sel_en;
>  	const u32 *output_fmts;
>  	u32 num_output_fmts;
> +	bool is_ck_de_pol;

Seperate is_ck_de_pol to an independent patch.

> +	bool is_dpintf;

Ditto for is_dpintf. And I would like change the name to what this
actually do.

> +	bool csc_support;

Ditto for csc_support.

> +	bool swap_input_support;

Ditto for swap_input_support.

> +	// Mask used for HWIDTH, HPORCH, VSYNC_WIDTH and VSYNC_PORCH 

/* ... */

> (no shift)
> +	u32 dimension_mask;

Ditto for dimension_mask.

> +	// Mask used for HSIZE and VSIZE (no shift)
> +	u32 hvsize_mask;

Ditto for hvsize_mask.

> +	u32 channel_swap_shift;

Ditto for channel_swap_shift.

> +	u32 yuv422_en_bit;

Ditto for yuv422_en_bit.

> +	u32 csc_enable_bit;

Ditto for csc_enable_bit.

> +	const struct mtk_dpi_yc_limit *limit;

Ditto for limit.

>  };
>  
>  
> +
> +static const struct mtk_dpi_conf mt8195_dpintf_conf = {
> +	.cal_factor = mt8195_dpintf_calculate_factor,
> +	.output_fmts = mt8195_output_fmts,
> +	.num_output_fmts = ARRAY_SIZE(mt8195_output_fmts),
> +	.is_dpintf = true,
> +	.csc_support = true,

For every SoC, csc_support is true. Why do we need csc_support?

Regards,
CK

> +	.dimension_mask = DPINTF_HPW_MASK,
> +	.hvsize_mask = DPINTF_HSIZE_MASK,
> +	.channel_swap_shift = DPINTF_CH_SWAP,
> +	.yuv422_en_bit = DPINTF_YUV422_EN,
> +	.csc_enable_bit = DPINTF_CSC_ENABLE,
> +	.limit = &mtk_dpintf_limit,
>  };
>  
>  



From miles.chen at mediatek.com  Wed Jan 19 01:16:23 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 17:16:23 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9rWs_w_dMfDLFuD-tr79cnVyuny4fLn9Wh0+bs76Nt0MA@mail.gmail.com>
References: <CAHmME9rWs_w_dMfDLFuD-tr79cnVyuny4fLn9Wh0+bs76Nt0MA@mail.gmail.com>
Message-ID: <20220119091626.3636-1-miles.chen@mediatek.com>

>typedef void (*blake2s_compress_t)(struct blake2s_state *state,
>				   const u8 *block, size_t nblocks, u32 inc);
>
>should become
>
>typedef void (*blake2s_compress_t)(struct blake2s_state *state,
>				   const u8 *block, size_t nblocks, const u32 inc);
>
>Does making that change fix things for you?
>
>Thanks,
>Jason

Thanks for your fast response.
It does not work. I tried this before reverting the commit 6048fdcc5f26.

Miles


From shameerali.kolothum.thodi at huawei.com  Wed Jan 19 01:23:31 2022
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Wed, 19 Jan 2022 09:23:31 +0000
Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
In-Reply-To: <Yeazd1lLuYm4k3lH@arm.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
 <Yeazd1lLuYm4k3lH@arm.com>
Message-ID: <207f800d1a67427a9771ffb06086365b@huawei.com>

Hi Catalin,

> -----Original Message-----
> From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> Sent: 18 January 2022 12:33
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; will at kernel.org;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Jonathan Cameron
> <jonathan.cameron at huawei.com>; Linuxarm <linuxarm at huawei.com>
> Subject: Re: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
> 
> Hi Shameer,
> 
> On Mon, Nov 22, 2021 at 12:18:40PM +0000, Shameer Kolothum wrote:
> > ?-TLA+ model. Modified the asidalloc model to incorporate the new
> >   VMID algo. The main differences are,
> > ? -flush_tlb_all() instead of local_tlb_flush_all() on rollover.
> > ? -Introduced INVALID_VMID and vCPU Sched Out logic.
> > ? -No CnP (Removed UniqueASIDAllCPUs & UniqueASIDActiveTask
> invariants).
> > ? -Removed ?UniqueVMIDPerCPU invariant for now as it looks like
> >    because of the speculative fetching with flush_tlb_all() there
> >    is a small window where this gets triggered. If I change the
> >    logic back to local_flush_tlb_all(), UniqueVMIDPerCPU seems to
> >    be fine. With my limited knowledge on TLA+ model, it is not
> >    clear to me whether this is a problem with the above logic
> >    or the VMID model implementation. Really appreciate any help
> >    with the model.
> >    The initial VMID TLA+ model is here,
> >    https://github.com/shamiali2008/kernel-tla/tree/private-vmidalloc-v1
> 
> I only had a brief look at the TLA+ model and I don't understand why you
> have a separate 'shed_out' process. It would run in parallel with the
> 'sched' but AFAICT you can't really schedule a guest out while you are
> in the middle of scheduling it in. I'd rather use the same 'sched'
> process and either schedule in an inactive task or schedule out an
> active one for a given CPU.
> 
> Also active_vmids[] for example is defined on the CPUS domain but you
> call vcpu_sched_out() from a process that's not in the CPUS domain but
> the SCHED_OUT one.

Many thanks for taking a look. My bad!. The 'sched_out' would indeed run in parallel
and defeat the purpose. I must say I was really confused by the TLA+ syntax and
is still not very confident about it.

Based on the above suggestion, I have modified it as below,

\* vCPU is scheduled out by KVM
macro vcpu_sched_out() {
        active_kvm[self].task := 0;
        active_vmids[self] := INVALID_VMID;
}
....

\* About to run a Guest VM
process (sched \in CPUS)
{
sched_loop:
        while (TRUE) {
                with (t \in TASKS) {
                        if (t # ActiveTask(self))
                                call kvm_arm_vmid_update(t);
                        else
                                vcpu_sched_out();
                }
        }
}

Please let me know if this is ok.

> Regarding UniqueVMIDPerCPU, I think we need to figure out why it
> happens. The fact that flush_tlb_all() was made to simulate the
> speculative TLB loads is not relevant. In a different spec I have,
> arm64kpti.tla, I just used another process that invokes an update_tlbs()
> macro so that it can happen at any time. I didn't bother to update the
> ASID spec in a similar way but it may be useful.

Ok. I will take a look at that and try that.

 The corresponding
> UniqueASIDPerCPU meant that for any two TLB entries on a single CPU, if
> they correspond to different tasks (pgd), they should have different
> ASIDs. That's a strong requirement, otherwise we end up with the wrong
> translation.

Yes, I understand that it is a strong requirement. Also, I thought this is something
that will trigger easily with the test setup I had with the real hardware. But testing
stayed on for days, so I was not sure it is a problem with the TLA+ implementation
or not.  

> 
> Why did you remove the CnP? Do we have this disabled for KVM guests?

I removed CnP related Invariants to simplify things for the first version. Also not sure
what specific changes we need to do for CnP here. Do we still need that switching to 
global pg_dir to prevent any speculative reading? I didn't see that being done in KVM 
anywhere at the moment. Maybe I am missing something.

On a side note, In my setup, the CnP=TRUE case for asidalloc.tla now fails with,
"Error: Invariant TLBEmptyInvalPTE is violated.". Please check.

Thanks,
Shameer 

> --
> Catalin


From mark.rutland at arm.com  Wed Jan 19 01:29:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 09:29:50 +0000
Subject: [PATCH 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <CAK8P3a1t5N_vW3rcMD_e+UMy5EQDrTrE4QqPDo7nM_s1-Bf0XQ@mail.gmail.com>
References: <1641980099-20315-1-git-send-email-anshuman.khandual@arm.com>
 <1641980099-20315-2-git-send-email-anshuman.khandual@arm.com>
 <CAK8P3a1cDF=jEVGchU8LNBdjdtROmHHHpebOASreR=WOuZ4Z1A@mail.gmail.com>
 <00e28671-8d3a-f789-91c4-109814792a07@arm.com>
 <CAK8P3a2Q+iN1O6FEdUJRt=0bQu=6fkWAD3RCECfdhu4DKHq0pg@mail.gmail.com>
 <519f3b4e-e790-c051-3cb1-3fd229a3e498@arm.com>
 <CAK8P3a1t5N_vW3rcMD_e+UMy5EQDrTrE4QqPDo7nM_s1-Bf0XQ@mail.gmail.com>
Message-ID: <20220119092950.GA42546@C02TD0UTHF1T.local>

Hi Arnd,

On Wed, Jan 19, 2022 at 08:44:54AM +0100, Arnd Bergmann wrote:
> On Wed, Jan 19, 2022 at 7:44 AM Anshuman Khandual
> <anshuman.khandual at arm.com> wrote:
> > On 1/13/22 5:17 PM, Arnd Bergmann wrote:
> > >
> > > It also helps me personally to have a known place to look up the names
> > > by value rather than chasing through reference manuals.
> >
> > IIUC the purpose here would be a quick CPU ID documentation reference check ?
> > I will wait for other opinions here and add the remaining in a separate patch
> > probably.
> 
> The purpose would be to do what is obviously the right thing, and to avoid
> more patches getting sent the next time someone needs to add a workaround
> for another core that is already known.

The general policy we've taken is to only add part definitions as and
when they're required (e.g. alongside an errata workaround that needs to
identify the part), since the kernel doesn't otherwise need to know, and
it keeps the errata workaround patches self-contained (and ensures the
MIDR definitions get tested as they're added).

So per usual policy I don't think we should add the other part
definitions here. If and when errata appear that requires us to identify
those parts we can add corresponding MIDR definitions.

> If you can't do this without more discussion, then just use your
> current version and let the next person do it.

As above, for now I think we should leave this as-is, and only add the
Cortex-X2 part definition.

Thanks,
Mark.


From alain.volmat at foss.st.com  Wed Jan 19 01:32:45 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Wed, 19 Jan 2022 10:32:45 +0100
Subject: [PATCH 2/2] spi: stm32: make SPI_MASTER_MUST_TX flags only specific
 to STM32F4
In-Reply-To: <20220119093245.624878-1-alain.volmat@foss.st.com>
References: <20220119093245.624878-1-alain.volmat@foss.st.com>
Message-ID: <20220119093245.624878-3-alain.volmat@foss.st.com>

Commit 61367d0b8f5e ("spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4")
allowed to properly communicate with the st-gyro-spi even when
there is no tx_buf provided by setting the flag SPI_MASTER_MUST_TX and
thus forcing a dummy TX buffer to work in Full Duplex.
This behavior should kept only for the STM32F4 and not for other
compatible since the STM32H7 do support SIMPLEX_RX and SIMPLEX_TX.
Add the flags variable within the struct stm32_spi_cfg so that flags
used at master registration time are compatible specific.

Fixes: 61367d0b8f5e ("spi: stm32: Add 'SPI_SIMPLEX_RX', 'SPI_3WIRE_RX' support for stm32f4")

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/spi/spi-stm32.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index b5ef2470cefe..7fc24505a72c 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -231,6 +231,7 @@ struct stm32_spi;
  * @baud_rate_div_min: minimum baud rate divisor
  * @baud_rate_div_max: maximum baud rate divisor
  * @has_fifo: boolean to know if fifo is used for driver
+ * @flags: compatible specific SPI controller flags used at registration time
  */
 struct stm32_spi_cfg {
 	const struct stm32_spi_regspec *regs;
@@ -251,6 +252,7 @@ struct stm32_spi_cfg {
 	unsigned int baud_rate_div_min;
 	unsigned int baud_rate_div_max;
 	bool has_fifo;
+	u16 flags;
 };
 
 /**
@@ -1720,6 +1722,7 @@ static const struct stm32_spi_cfg stm32f4_spi_cfg = {
 	.baud_rate_div_min = STM32F4_SPI_BR_DIV_MIN,
 	.baud_rate_div_max = STM32F4_SPI_BR_DIV_MAX,
 	.has_fifo = false,
+	.flags = SPI_MASTER_MUST_TX,
 };
 
 static const struct stm32_spi_cfg stm32h7_spi_cfg = {
@@ -1852,7 +1855,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
 	master->prepare_message = stm32_spi_prepare_msg;
 	master->transfer_one = stm32_spi_transfer_one;
 	master->unprepare_message = stm32_spi_unprepare_msg;
-	master->flags = SPI_MASTER_MUST_TX;
+	master->flags = spi->cfg->flags;
 
 	spi->dma_tx = dma_request_chan(spi->dev, "tx");
 	if (IS_ERR(spi->dma_tx)) {
-- 
2.25.1



From alain.volmat at foss.st.com  Wed Jan 19 01:32:43 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Wed, 19 Jan 2022 10:32:43 +0100
Subject: [PATCH 0/2] spi: stm32: comments & SIMPLEX_RX fixes
Message-ID: <20220119093245.624878-1-alain.volmat@foss.st.com>

This series contains 2 fixes within the spi-stm32.c driver.  One is
removing comments regarding struct variables that do not exist and the
second one correct a previous STM32F4 related commit for SIMPLEX_RX which
happens to break SIMPLEX_RX for H7 since it enforces MUST_TX flags.

Alain Volmat (2):
  spi: stm32: remove inexistant variables in struct stm32_spi_cfg
    comment
  spi: stm32: make SPI_MASTER_MUST_TX flags only specific to STM32F4

 drivers/spi/spi-stm32.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

-- 
2.25.1



From alain.volmat at foss.st.com  Wed Jan 19 01:32:44 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Wed, 19 Jan 2022 10:32:44 +0100
Subject: [PATCH 1/2] spi: stm32: remove inexistant variables in struct
 stm32_spi_cfg comment
In-Reply-To: <20220119093245.624878-1-alain.volmat@foss.st.com>
References: <20220119093245.624878-1-alain.volmat@foss.st.com>
Message-ID: <20220119093245.624878-2-alain.volmat@foss.st.com>

Variables 'can_dma' and 'has_startbit' are described within the
struct stm32_spi_cfg comment but have never existed in this structure
so remove them.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
 drivers/spi/spi-stm32.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index 9bd3fd1652f7..b5ef2470cefe 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -221,7 +221,6 @@ struct stm32_spi;
  * time between frames (if driver has this functionality)
  * @set_number_of_data: optional routine to configure registers to desired
  * number of data (if driver has this functionality)
- * @can_dma: routine to determine if the transfer is eligible for DMA use
  * @transfer_one_dma_start: routine to start transfer a single spi_transfer
  * using DMA
  * @dma_rx_cb: routine to call after DMA RX channel operation is complete
@@ -232,7 +231,6 @@ struct stm32_spi;
  * @baud_rate_div_min: minimum baud rate divisor
  * @baud_rate_div_max: maximum baud rate divisor
  * @has_fifo: boolean to know if fifo is used for driver
- * @has_startbit: boolean to know if start bit is used to start transfer
  */
 struct stm32_spi_cfg {
 	const struct stm32_spi_regspec *regs;
-- 
2.25.1



From bhe at redhat.com  Wed Jan 19 01:33:22 2022
From: bhe at redhat.com (Baoquan He)
Date: Wed, 19 Jan 2022 17:33:22 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <CA+zEjCvqYAWaWW9hVbHqYm_GbV-BaiOM4c77WHnxDNh+SRDUuw@mail.gmail.com>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv> <YebK70Sx4w8zLfj/@xhacker>
 <20220119080859.GB4977@MiWiFi-R3L-srv>
 <CA+zEjCvqYAWaWW9hVbHqYm_GbV-BaiOM4c77WHnxDNh+SRDUuw@mail.gmail.com>
Message-ID: <20220119093322.GC4977@MiWiFi-R3L-srv>

On 01/19/22 at 09:52am, Alexandre Ghiti wrote:
> Hi Baoquan,
> 
> On Wed, Jan 19, 2022 at 9:11 AM Baoquan He <bhe at redhat.com> wrote:
> >
> > On 01/18/22 at 10:13pm, Jisheng Zhang wrote:
> > > On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> > > > Hi Jisheng,
> > >
> > > Hi Baoquan,
> > >
> > > >
> > > > On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > > > > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > > > > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > > > > and increase compile coverage.
> > > >
> > > > I go through this patchset, You mention the benefits it brings are
> > > > 1) simplity the code;
> > > > 2) increase compile coverage;
> > > >
> > > > For benefit 1), it mainly removes the dummy function in x86, arm and
> > > > arm64, right?
> > >
> > > Another benefit: remove those #ifdef #else #endif usage. Recently, I
> > > fixed a bug due to lots of "#ifdefs":
> > > http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html
> >
> > Glad to know the fix. While, sometime the ifdeffery is necessary. I am
> > sorry about the one in riscv and you have fixed, it's truly a bug . But,
> > the increasing compile coverage at below you tried to make, it may cause
> > issue. Please see below my comment.
> >
> > >
> > > >
> > > > For benefit 2), increasing compile coverage, could you tell more how it
> > > > achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> > > > purpose? Please forgive my poor compiling knowledge.
> > >
> > > Just my humble opinion, let's compare the code::
> > >
> > > #ifdef CONFIG_KEXEC_CORE
> > >
> > > code block A;
> > >
> > > #endif
> > >
> > > If KEXEC_CORE is disabled, code block A won't be compiled at all, the
> > > preprocessor will remove code block A;
> > >
> > > If we convert the code to:
> > >
> > > if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
> > >       code block A;
> > > }
> > >
> > > Even if KEXEC_CORE is disabled, code block A is still compiled.
> >
> > This is what I am worried about. Before, if CONFIG_KEXEC_CORE is
> > unset, those relevant codes are not compiled in. I can't see what
> > benefit is brought in if compiled in the unneeded code block. Do I miss
> > anything?
> >
> 
> This is explained in Documentation/process/coding-style.rst "21)
> Conditional Compilation".

Thanks for the pointer, Alex.

I read that part, while my confusion isn't gone. With the current code,
CONFIG_KEXEC_CORE is set,
  - reserve_crashkernel_low() and reserve_crashkernel() compiled in. 
CONFIG_KEXEC_CORE is unset,
  - reserve_crashkernel_low() and reserve_crashkernel() compiled out. 

After this patch applied, does it have the same effect as the old code?

arch/x86/kernel/setup.c:

before
======
#ifdef CONFIG_KEXEC_CORE
static int __init reserve_crashkernel_low(void)
{
	......
}
static void __init reserve_crashkernel(void)
{
	......
}
#else
static void __init reserve_crashkernel(void)
{
}
#endif

after
=======
static int __init reserve_crashkernel_low(void)
{
	......
}
static void __init reserve_crashkernel(void)
{
	......
	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
                return;
	......
}



From miles.chen at mediatek.com  Wed Jan 19 01:24:40 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 17:24:40 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
References: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
Message-ID: <20220119092440.4045-1-miles.chen@mediatek.com>

hi,

>Thanks for the patch. Could you let me know which architecture and
>compiler this was broken on? If I had to guess, I'd wager arm32, and
>you hit this by enabling optimized blake2s?

Actually, I am merging android-common tree and test our device.
I use arm64 and clang-r437112b.

I'm not sure which option is the right one, grep 'BLAKE' .config shows:

CONFIG_CRYPTO_BLAKE2B=y
# CONFIG_CRYPTO_BLAKE2S is not set
# CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y

and... I found that my patch breaks arm32 build, sorry for that.

>If so, I'm not sure the problem is with weak symbols. Why should CFI
>break weak symbols? Rather, perhaps the issue is that the function is
>defined in blake2s-core.S? Are there some CFI macros we need for that
>definition?



From mark.rutland at arm.com  Wed Jan 19 01:35:25 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 09:35:25 +0000
Subject: [PATCH] arm64: entry: Save some nops when
 CONFIG_ARM64_PSEUDO_NMI is not set
In-Reply-To: <e6293ec4-7c56-194a-95f9-98b102d80b31@huawei.com>
References: <20220107085536.214501-1-heying24@huawei.com>
 <20220112032410.29231-1-heying24@huawei.com>
 <e6293ec4-7c56-194a-95f9-98b102d80b31@huawei.com>
Message-ID: <20220119093525.GB42546@C02TD0UTHF1T.local>

On Wed, Jan 19, 2022 at 02:40:58PM +0800, He Ying wrote:
> Hi all,
> 
> Ping. Any comments?

The patch looks fine, but as it's the middle of the merge window people
are busy and unlikely to look at this for the next few days.

Generally it's a good idea to wait until rc1 or rc2, rebase atop that,
and post the updated patch. Stuff like this usually gets queued around
rc3/rc4 time.

> ??? 2022/1/12 11:24, He Ying ????:
> > Arm64 pseudo-NMI feature code brings some additional nops
> > when CONFIG_ARM64_PSEUDO_NMI is not set, which is not
> > necessary. So add necessary ifdeffery to avoid it.
> > 
> > Signed-off-by: He Ying <heying24 at huawei.com>

FWIW:

Acked-by: Mark Rutland <mark.rutland at arm.com>

Mark.

> > ---
> >   arch/arm64/kernel/entry.S | 4 ++++
> >   1 file changed, 4 insertions(+)
> > 
> > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > index 2f69ae43941d..ffc32d3d909a 100644
> > --- a/arch/arm64/kernel/entry.S
> > +++ b/arch/arm64/kernel/entry.S
> > @@ -300,6 +300,7 @@ alternative_else_nop_endif
> >   	str	w21, [sp, #S_SYSCALLNO]
> >   	.endif
> > +#ifdef CONFIG_ARM64_PSEUDO_NMI
> >   	/* Save pmr */
> >   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
> >   	mrs_s	x20, SYS_ICC_PMR_EL1
> > @@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
> >   	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
> >   	msr_s	SYS_ICC_PMR_EL1, x20
> >   alternative_else_nop_endif
> > +#endif
> >   	/* Re-enable tag checking (TCO set on exception entry) */
> >   #ifdef CONFIG_ARM64_MTE
> > @@ -330,6 +332,7 @@ alternative_else_nop_endif
> >   	disable_daif
> >   	.endif
> > +#ifdef CONFIG_ARM64_PSEUDO_NMI
> >   	/* Restore pmr */
> >   alternative_if ARM64_HAS_IRQ_PRIO_MASKING
> >   	ldr	x20, [sp, #S_PMR_SAVE]
> > @@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
> >   	dsb	sy				// Ensure priority change is seen by redistributor
> >   .L__skip_pmr_sync\@:
> >   alternative_else_nop_endif
> > +#endif
> >   	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR


From mhocko at suse.com  Wed Jan 19 01:42:47 2022
From: mhocko at suse.com (Michal Hocko)
Date: Wed, 19 Jan 2022 10:42:47 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Yee36hPfWSs+jR0m@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz> <Ydu6fXg2FmrseQOn@google.com>
 <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz> <Yee36hPfWSs+jR0m@google.com>
Message-ID: <YefdFwcoX4+ZcDSY@dhcp22.suse.cz>

On Wed 19-01-22 00:04:10, Yu Zhao wrote:
> On Mon, Jan 10, 2022 at 11:54:42AM +0100, Michal Hocko wrote:
> > On Sun 09-01-22 21:47:57, Yu Zhao wrote:
> > > On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> > > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > [...]
> > > > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > > > +{
> > > > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > > > +		.test_walk = should_skip_vma,
> > > > > +		.p4d_entry = walk_pud_range,
> > > > > +	};
> > > > > +
> > > > > +	int err;
> > > > > +#ifdef CONFIG_MEMCG
> > > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > > +#endif
> > > > > +
> > > > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > > > +
> > > > > +	do {
> > > > > +		unsigned long start = walk->next_addr;
> > > > > +		unsigned long end = mm->highest_vm_end;
> > > > > +
> > > > > +		err = -EBUSY;
> > > > > +
> > > > > +		rcu_read_lock();
> > > > > +#ifdef CONFIG_MEMCG
> > > > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > > > +			goto contended;
> > > > > +#endif
> > > > > +		if (!mmap_read_trylock(mm))
> > > > > +			goto contended;
> > > > 
> > > > Have you evaluated the behavior under mmap_sem contention? I mean what
> > > > would be an effect of some mms being excluded from the walk? This path
> > > > is called from direct reclaim and we do allocate with exclusive mmap_sem
> > > > IIRC and the trylock can fail in a presence of pending writer if I am
> > > > not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> > > > can bypass the walk.
> > > 
> > > You are right. Here it must be a trylock; otherwise it can deadlock.
> > 
> > Yeah, this is clear.
> > 
> > > I think there might be a misunderstanding: the aging doesn't
> > > exclusively rely on page table walks to gather the accessed bit. It
> > > prefers page table walks but it can also fallback to the rmap-based
> > > function, i.e., lru_gen_look_around(), which only gathers the accessed
> > > bit from at most 64 PTEs and therefore is less efficient. But it still
> > > retains about 80% of the performance gains.
> > 
> > I have to say that I really have hard time to understand the runtime
> > behavior depending on that interaction. How does the reclaim behave when
> > the virtual scan is enabled, partially enabled and almost completely
> > disabled due to different constrains? I do not see any such an
> > evaluation described in changelogs and I consider this to be a rather
> > important information to judge the overall behavior.
> 
> It doesn't have (partially) enabled/disabled states nor does its
> behavior change with different reclaim constraints. Having either
> would make its design too complex to implement or benchmark.

Let me clarify. By "partially enabled" I really meant behavior depedning
on runtime conditions. Say mmap_sem cannot be locked for half of scanned
tasks and/or allocation for the mm walker fails due to lack of memory.
How does this going to affect reclaim efficiency. How does a user/admin
know that the memory reclaim is in a "degraded" mode because of the
contention?
-- 
Michal Hocko
SUSE Labs


From miles.chen at mediatek.com  Wed Jan 19 01:43:42 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 17:43:42 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXGUtg1BOauCjxB+S7yMTPArQrPnHf5jnfhOihL-FHrFZA@mail.gmail.com>
References: <CAMj1kXGUtg1BOauCjxB+S7yMTPArQrPnHf5jnfhOihL-FHrFZA@mail.gmail.com>
Message-ID: <20220119094342.4515-1-miles.chen@mediatek.com>

>Ehm, maybe not. As Jason points out, the typedef does not have quite
>the right type, so that is most likely the culprit, and this
>workaround would trigger CFI in exactly the same way.
>
>Interestingly, the compiler does not seem to mind, right? Or are you
>seeing any build time warnings on the reference to blake2s_compress in
>the call to __blake2s_update() ?

No, no warnings as the -Wcast-function-type is globally enabled.
I cleaned some cast-function-type errors but no warnings in
__blake2s_update.


Miles


From mhocko at suse.com  Wed Jan 19 01:44:21 2022
From: mhocko at suse.com (Michal Hocko)
Date: Wed, 19 Jan 2022 10:44:21 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YeewK/cYG4MXV4f3@google.com>
References: <20220104202227.2903605-7-yuzhao@google.com>
 <YdcU4P+XWkbDUUoO@dhcp22.suse.cz> <Yddh+APQGg8dKRgw@google.com>
 <Ydf/7DDu94fMs0CG@dhcp22.suse.cz> <YdgBL1dRk1KmyXJS@dhcp22.suse.cz>
 <Yduuyrk/AZG717Hs@google.com> <YdxEqFPLDf+wI0xX@dhcp22.suse.cz>
 <Yd/0Sgxy+jLm5cqd@google.com> <YeAU0n1puxyr4N6Y@dhcp22.suse.cz>
 <YeewK/cYG4MXV4f3@google.com>
Message-ID: <YefddYm8FAfJalNa@dhcp22.suse.cz>

On Tue 18-01-22 23:31:07, Yu Zhao wrote:
> On Thu, Jan 13, 2022 at 01:02:26PM +0100, Michal Hocko wrote:
> > On Thu 13-01-22 02:43:38, Yu Zhao wrote:
> > [...]
> > > > > The bottom line is I can try various optimizations, e.g., preallocate
> > > > > a few buffers for a limited number of page walkers and if this number
> > > > > has been reached, fallback to the rmap-based function. But I have yet
> > > > > to see evidence that calls for additional complexity.
> > > > 
> > > > I would disagree here. This is not an optimization. You should be
> > > > avoiding allocations from the memory reclaim because any allocation just
> > > > add a runtime behavior complexity and potential corner cases.
> > > 
> > > Would __GFP_NOMEMALLOC address your concern? It prevents allocations
> > > from accessing the reserves even under PF_MEMALLOC.
> > 
> > __GFP_NOMEMALLOC would deal with the complete memory depletion concern
> > for sure but I am not sure how any of these allocations would succeed
> > when called from the direct reclaim. Some access to memory reserves is
> > necessary if you insist on allocating from the reclaim process.
> > 
> > You can have a look at the limited memory reserves access by oom victims
> > for an example of how this can be done.
> 
> Thanks. I'll change GFP_KERNEL to __GFP_HIGH | __GFP_NOMEMALLOC.
> __GFP_HIGH allows some access to memory reserves and __GFP_NOMEMALLOC
> prevents the complete depletion. Basically the combination lower the
> min watermark by 1/2, and we have been using them for
> add_to_swap_cache().

Yes this will prevent the complete memory depletion. There are other
users of this portion of memory reserves so the reclaim might be out of
luck. How this turns out in practice remains to be seen though but it
certainly is an opportunity for corner cases and hard to test behavior.

-- 
Michal Hocko
SUSE Labs


From dave.stevenson at raspberrypi.com  Wed Jan 19 01:44:27 2022
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Wed, 19 Jan 2022 09:44:27 +0000
Subject: [PATCH v3] ARM: dts: bcm2711-rpi-cm4-io: Add rtc on a
 pinctrl-muxed i2c bus
In-Reply-To: <YedGVE6Ow+VLpaoS@pendragon.ideasonboard.com>
References: <20211231115109.94626-1-uwe@kleine-koenig.org>
 <2540edbe-084e-802f-3533-0aa66ddc20ec@ideasonboard.com>
 <397bf7c2-da9f-a993-f8bb-5d6cbc6e87eb@gmail.com>
 <YecnebByrBplFEsU@pendragon.ideasonboard.com>
 <41d2ff4a-79eb-5071-3a35-efa8cccec074@kleine-koenig.org>
 <YedGVE6Ow+VLpaoS@pendragon.ideasonboard.com>
Message-ID: <CAPY8ntBzd+JTOfKOT1_65XbHgKBCRPqc2=fPm-2WFFM8vsYJWQ@mail.gmail.com>

Hi Laurent and Uwe.

On Tue, 18 Jan 2022 at 22:59, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi Uwe,
>
> On Tue, Jan 18, 2022 at 11:41:19PM +0100, Uwe Kleine-K?nig wrote:
> > On 1/18/22 21:47, Laurent Pinchart wrote:
> > > On Tue, Jan 18, 2022 at 12:00:50PM -0800, Florian Fainelli wrote:
> > >> On 1/18/22 11:45 AM, Jean-Michel Hautbois wrote:
> > >>> This is also needed for camera and display support.
> > >>> I tested it successfully with imx219 + unicam on mainline.
> > >>
> > >> Thanks for testing, can you reply with a Tested-by tag so it could be
> > >> applied to the commit message when this gets picked up?
> > >
> > > Well, this also points out that there's an issue: if the mux is needed
> > > for other devices, it shouldn't be in bcm2711-rpi-cm4-io.dts :-) We
> > > could move it to bcm2711-rpi.dtsi (so far all bcm2711-based boards use
> > > either I/O pins 0+1 or 44+45)
> >
> > If I understand correctly it's not used on rpi-4-b, so bcm2711-rpi.dtsi
> > would be wrong.
>
> rpi-4-b muxes I2C0 on pins 0+1 and 44+45. The latter is wired to the
> camera connector, and used for the camera sensor. Same thing on rpi-cm4.
> rpi-400 has no camera connector, but I believe the display I2C bus is
> also on pins 44+45 (at least according to the downstream DT sources,
> rpi-400 muxes I2C0 on 0+1 and 44+45 too).

Minor correction - Pi 400 has no camera or display connector.
I'm double checking with the hardware folk, but AFAIK 44&45 aren't
used for any other purpose, so leaving the i2c0mux defined to them
doesn't cause any issues.

Camera and DSI display connectors on all Raspberry Pi regular boards
share the same I2C GPIOs muxing. (The original Pi model A & B didn't
route I2C to the display).
On a CMIO board, CAM0 & DISP0 connectors share an I2C muxing (normally
0&1), and CAM1 & DISP1 connectors share a muxing (either 28&29, or
44&45).

> > > , or move it to per-board files.
> >
> > It is in an board file now?! So I don't understand your suggestion here.
>
> Sorry, I meant have it in per-board files, not more it there.
>
> > > In the
> > > latter case, instead of duplicating the same block everywhere, it could
> > > be moved to a .dtsi included in those board files. This is what the
> > > downstream kernel does.
> >
> > How does it call the dtsi file? I wonder if that is sensible expecting
> > that the devices on the bus are different for different boards?!
>
> Downstream has a bcm283x-rpi-i2c0mux_0_44.dtsi that just contains
>
> &i2c0mux {
>         pinctrl-0 = <&i2c0_gpio0>;
>         pinctrl-1 = <&i2c0_gpio44>;
> };
>
> with i2c0mux defined in bcm283x.dtsi as
>
>         i2c0mux: i2c0mux {
>                 compatible = "i2c-mux-pinctrl";
>                 #address-cells = <1>;
>                 #size-cells = <0>;
>
>                 i2c-parent = <&i2c0if>;
>
>                 pinctrl-names = "i2c0", "i2c_csi_dsi";
>
>                 status = "disabled";
>
>                 i2c0: i2c at 0 {
>                         reg = <0>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                 };
>
>                 i2c_csi_dsi: i2c at 1 {
>                         reg = <1>;
>                         #address-cells = <1>;
>                         #size-cells = <0>;
>                 };
>         };
>
> The following board files #include "bcm283x-rpi-i2c0mux_0_44.dtsi":
>
> - bcm2710-rpi-3-b.dts
> - bcm2710-rpi-3-b-plus.dts
> - bcm2710-rpi-zero-2-w.dts
> - bcm2711-rpi-400.dts
> - bcm2711-rpi-4-b.dts
> - bcm2711-rpi-4-b.dts.orig
> - bcm2711-rpi-cm4.dts

For completeness, the earlier boards use a
bcm283x-rpi-i2c0mux_0_28.dtsi file as they use GPIOs 28&29 for the
camera & display I2C. If my memory serves correctly, it had to move to
allow connecting the SDIO interface to the Wifi chip on the boards you
list above.
The one awkward one is the very original rev1 256MB Model B (and 128MB
model A?) which routed GPIOs 2&3 and BSC1 to the camera connector.
Life's never easy!

  Dave

> We don't have to replicate the exact same mechanism and use the same
> names, but for rpi-4-b and rpi-cm4, to enable camera support (which
> we're working on, Jean-Michel has posted a driver for the Unicam CSI-2
> receiver to the linux-media mailing list, the ISP will follow), we need
> the mux. Given that those two boards have a camera connector, I think it
> makes sense to define the mux in a different file than
> bcm2711-rpi-cm4-io.dts. The RTC node can stay in bcm2711-rpi-cm4-io.dts.
>
> --
> Regards,
>
> Laurent Pinchart


From heying24 at huawei.com  Wed Jan 19 01:47:09 2022
From: heying24 at huawei.com (He Ying)
Date: Wed, 19 Jan 2022 17:47:09 +0800
Subject: [PATCH] arm64: entry: Save some nops when CONFIG_ARM64_PSEUDO_NMI
 is not set
In-Reply-To: <20220119093525.GB42546@C02TD0UTHF1T.local>
References: <20220107085536.214501-1-heying24@huawei.com>
 <20220112032410.29231-1-heying24@huawei.com>
 <e6293ec4-7c56-194a-95f9-98b102d80b31@huawei.com>
 <20220119093525.GB42546@C02TD0UTHF1T.local>
Message-ID: <784a864e-e7e5-4ce5-ec78-850b523c23b0@huawei.com>


? 2022/1/19 17:35, Mark Rutland ??:
> On Wed, Jan 19, 2022 at 02:40:58PM +0800, He Ying wrote:
>> Hi all,
>>
>> Ping. Any comments?
> The patch looks fine, but as it's the middle of the merge window people
> are busy and unlikely to look at this for the next few days.
>
> Generally it's a good idea to wait until rc1 or rc2, rebase atop that,
> and post the updated patch. Stuff like this usually gets queued around
> rc3/rc4 time.
OK. Thanks for your comment.
>
>> ??? 2022/1/12 11:24, He Ying ????:
>>> Arm64 pseudo-NMI feature code brings some additional nops
>>> when CONFIG_ARM64_PSEUDO_NMI is not set, which is not
>>> necessary. So add necessary ifdeffery to avoid it.
>>>
>>> Signed-off-by: He Ying <heying24 at huawei.com>
> FWIW:
>
> Acked-by: Mark Rutland <mark.rutland at arm.com>
>
> Mark.
>
>>> ---
>>>    arch/arm64/kernel/entry.S | 4 ++++
>>>    1 file changed, 4 insertions(+)
>>>
>>> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
>>> index 2f69ae43941d..ffc32d3d909a 100644
>>> --- a/arch/arm64/kernel/entry.S
>>> +++ b/arch/arm64/kernel/entry.S
>>> @@ -300,6 +300,7 @@ alternative_else_nop_endif
>>>    	str	w21, [sp, #S_SYSCALLNO]
>>>    	.endif
>>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>>    	/* Save pmr */
>>>    alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>>    	mrs_s	x20, SYS_ICC_PMR_EL1
>>> @@ -307,6 +308,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>>    	mov	x20, #GIC_PRIO_IRQON | GIC_PRIO_PSR_I_SET
>>>    	msr_s	SYS_ICC_PMR_EL1, x20
>>>    alternative_else_nop_endif
>>> +#endif
>>>    	/* Re-enable tag checking (TCO set on exception entry) */
>>>    #ifdef CONFIG_ARM64_MTE
>>> @@ -330,6 +332,7 @@ alternative_else_nop_endif
>>>    	disable_daif
>>>    	.endif
>>> +#ifdef CONFIG_ARM64_PSEUDO_NMI
>>>    	/* Restore pmr */
>>>    alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>>    	ldr	x20, [sp, #S_PMR_SAVE]
>>> @@ -339,6 +342,7 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
>>>    	dsb	sy				// Ensure priority change is seen by redistributor
>>>    .L__skip_pmr_sync\@:
>>>    alternative_else_nop_endif
>>> +#endif
>>>    	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
> .


From mark.rutland at arm.com  Wed Jan 19 01:55:14 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 09:55:14 +0000
Subject: [RFC PATCH] arm64: don't vmap() invalid page
In-Reply-To: <20220118185354.464517-1-yury.norov@gmail.com>
References: <20220118185354.464517-1-yury.norov@gmail.com>
Message-ID: <20220119095514.GA42995@C02TD0UTHF1T.local>

On Tue, Jan 18, 2022 at 10:53:54AM -0800, Yury Norov wrote:
> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer, which would lead to DABT at address translation later.
> Currently, kernel checks the pages against NULL. In my case, however, the
> address was not NULL, and was big enough so that the hardware generated
> Address Size Abort.

Can you give an example of when this might happen? It sounds like you're
actually hitting this, so a backtrace would be nice.

I'm a bit confused as to when why we'd try to vmap() pages that we
didn't have a legitimate struct page for -- where did these addresses
come from?

It sounds like this is going wrong at a higher level, and we're passing
entirely bogus struct page pointers around. This seems like the sort of
thing DEBUG_VIRTUAL or similar should check when we initially generate
the struct page pointer.

Thanks,
Mark.

> Interestingly, this abort happens even if copy_from_kernel_nofault() is used,
> which is quite inconvenient for debugging purposes. 
> 
> This patch adds an arch_vmap_page_valid() helper into vmap() path, so that
> architectures may add arch-specific checks of the pointer passed into vmap.
> 
> For arm64, if the page passed to vmap() corresponds to a physical address
> greater than maximum possible value as described in TCR_EL1.IPS register, the
> following table walk would generate Address Size Abort. Instead of creating
> the invalid mapping, kernel will return ERANGE in such situation.
> 
> Signed-off-by: Yury Norov <yury.norov at gmail.com>
> ---
>  arch/arm64/include/asm/vmalloc.h | 41 ++++++++++++++++++++++++++++++++
>  include/linux/vmalloc.h          |  7 ++++++
>  mm/vmalloc.c                     |  8 +++++--
>  3 files changed, 54 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h
> index b9185503feae..e9d43ee019ad 100644
> --- a/arch/arm64/include/asm/vmalloc.h
> +++ b/arch/arm64/include/asm/vmalloc.h
> @@ -4,6 +4,47 @@
>  #include <asm/page.h>
>  #include <asm/pgtable.h>
>  
> +static inline u64 pa_size(u64 ips)
> +{
> +	switch (ips) {
> +	case 0b000:
> +		return 1UL << 32;
> +	case 0b001:
> +		return 1UL << 36;
> +	case 0b010:
> +		return 1UL << 40;
> +	case 0b011:
> +		return 1UL << 42;
> +	case 0b100:
> +		return 1UL << 44;
> +	case 0b101:
> +		return 1UL << 48;
> +	case 0b110:
> +		return 1UL << 52;
> +	/* All other values */
> +	default:
> +		return 1UL << 52;
> +	}
> +}
> +
> +#define arch_vmap_page_valid arch_vmap_page_valid
> +static inline int arch_vmap_page_valid(struct page *page)
> +{
> +	u64 tcr, ips, paddr_size;
> +
> +	if (!page)
> +		return -ENOMEM;
> +
> +	tcr = read_sysreg_s(SYS_TCR_EL1);
> +	ips = (tcr & TCR_IPS_MASK) >> TCR_IPS_SHIFT;
> +
> +	paddr_size = pa_size(ips);
> +	if (page_to_phys(page) >= paddr_size)
> +		return -ERANGE;
> +
> +	return 0;
> +}
> +
>  #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
>  
>  #define arch_vmap_pud_supported arch_vmap_pud_supported
> diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
> index 6e022cc712e6..08b567d8bafc 100644
> --- a/include/linux/vmalloc.h
> +++ b/include/linux/vmalloc.h
> @@ -119,6 +119,13 @@ static inline int arch_vmap_pte_supported_shift(unsigned long size)
>  }
>  #endif
>  
> +#ifndef arch_vmap_page_valid
> +static inline int arch_vmap_page_valid(struct page *page)
> +{
> +	return page ? 0 : -ENOMEM;
> +}
> +#endif
> +
>  /*
>   *	Highlevel APIs for driver use
>   */
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d2a00ad4e1dd..ee0384405cdd 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -472,11 +472,15 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
>  		return -ENOMEM;
>  	do {
>  		struct page *page = pages[*nr];
> +		int ret;
>  
>  		if (WARN_ON(!pte_none(*pte)))
>  			return -EBUSY;
> -		if (WARN_ON(!page))
> -			return -ENOMEM;
> +
> +		ret = arch_vmap_page_valid(page);
> +		if (WARN_ON(ret))
> +			return ret;
> +
>  		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
>  		(*nr)++;
>  	} while (pte++, addr += PAGE_SIZE, addr != end);
> -- 
> 2.30.2
> 


From Jason at zx2c4.com  Wed Jan 19 01:55:47 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 10:55:47 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <20220119092440.4045-1-miles.chen@mediatek.com>
References: <CAHmME9pv4WWATjdqZgwrtHDmq3sX4ABfB9PoNT9Z4tSEduR2Lw@mail.gmail.com>
 <20220119092440.4045-1-miles.chen@mediatek.com>
Message-ID: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>

Hi Miles,

I'm actually not able to reproduce your oops. I'm using vanilla clang
13, cross compiling for arm64, with thin LTO enabled and CFI enabled.
Kernel seems to run fine.

Are there other settings that are needed to trigger this? Do you see
it in upstream clang or just the Android fork of clang?

Jason


From guangming.cao at mediatek.com  Wed Jan 19 01:59:07 2022
From: guangming.cao at mediatek.com (Guangming.Cao)
Date: Wed, 19 Jan 2022 17:59:07 +0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <CALAqxLUSjHoLpgFLcvqmDfv7Uip2VwHS5d_5x2nzw=P3rA2NDA@mail.gmail.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
 <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
 <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>
 <82faa62f1bc946cf2f9ee2f7d15c567162238eab.camel@mediatek.com>
 <CALAqxLUSjHoLpgFLcvqmDfv7Uip2VwHS5d_5x2nzw=P3rA2NDA@mail.gmail.com>
Message-ID: <f09938519f1fcf51f20a0de5eb4063b0ff1a1e87.camel@mediatek.com>

On Fri, 2022-01-14 at 17:17 -0800, John Stultz wrote:
> On Fri, Jan 14, 2022 at 4:04 AM Guangming.Cao
> <guangming.cao at mediatek.com> wrote:
> > 
> > On Fri, 2022-01-14 at 08:16 +0100, Christian K?nig wrote:
> > > Am 14.01.22 um 00:26 schrieb John Stultz:
> > > > On Thu, Jan 13, 2022 at 5:05 AM Christian K?nig
> > > > <christian.koenig at amd.com> wrote:
> > > > > Am 13.01.22 um 14:00 schrieb Ruhl, Michael J:
> > > > > > > -----Original Message-----
> > > > > > > From: dri-devel <dri-devel-bounces at lists.freedesktop.org>
> > > > > > > On
> > > > > > > Behalf Of
> > > > > > > Ruhl, Michael J
> > > > > > > > -----Original Message-----
> > > > > > > > From: dri-devel <
> > > > > > > > dri-devel-bounces at lists.freedesktop.org>
> > > > > > > > On Behalf Of
> > > > > > > > guangming.cao at mediatek.com
> > > > > > > > +   /*
> > > > > > > > +    * Invalid size check. The "len" should be less
> > > > > > > > than
> > > > > > > > totalram.
> > > > > > > > +    *
> > > > > > > > +    * Without this check, once the invalid size
> > > > > > > > allocation
> > > > > > > > runs on a process
> > > > > > > > that
> > > > > > > > +    * can't be killed by OOM flow(such as "gralloc" on
> > > > > > > > Android devices), it
> > > > > > > > will
> > > > > > > > +    * cause a kernel exception, and to make matters
> > > > > > > > worse,
> > > > > > > > we can't find
> > > > > > > > who are using
> > > > > > > > +    * so many memory with "dma_buf_debug_show" since
> > > > > > > > the
> > > > > > > > relevant
> > > > > > > > dma-buf hasn't exported.
> > > > > > > > +    */
> > > > > > > > +   if (len >> PAGE_SHIFT > totalram_pages())
> > > > > > > 
> > > > > > > If your "heap" is from cma, is this still a valid check?
> > > > > > 
> > > > > > And thinking a bit further, if I create a heap from
> > > > > > something
> > > > > > else (say device memory),
> > > > > > you will need to be able to figure out the maximum
> > > > > > allowable
> > > > > > check for the specific
> > > > > > heap.
> > > > > > 
> > > > > > Maybe the heap needs a callback for max size?
> > 
> > Yes, I agree with this solution.
> > If dma-heap framework support this via adding a callback to support
> > it,
> > seems it's more clear than adding a limitation in dma-heap
> > framework
> > since each heap maybe has different limitation.
> > If you prefer adding callback, I can update this patch and add
> > totalram
> > limitation to system dma-heap.
> 
> If the max value is per-heap, why not enforce that value in the
> per-heap allocation function?
> 
> Moving the check to the heap alloc to me seems simpler to me than
> adding complexity to the infrastructure to add a heap max_size
> callback. Is there some other use for the callback that you envision?
> 
> thanks
> -john

Thanks for your comment.

If you think max the value is per-heap, why not add an optional
callback for dma-heap to solve this issue(prevent consuming too much
time for a doomed to fail allocation), if the dma-heap doesn't have a
special size check, just use the default value(totalram) in dma-heap 
framework to do the size check.

Yes, for linux dma-heaps, only system-heap needs it, so adding it in
system heap is the simplest. However, there are many vendor dma-heaps
like system-heap which won't be uploaded to linux codebase, and maybe
have same limitation, all these heaps need to add the same limitation.
I just think it's boring. However, If you think discussing these absent
cases based on current linux code is meaningless, I also agree to it.

So, to summarize, if you still think adding it in system_heap.c is
better, I also agree and I will update the patch to add it in
system_heap.c

Thanks~
Guangming

> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

From victor.liu at nxp.com  Wed Jan 19 02:01:08 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Wed, 19 Jan 2022 18:01:08 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
Message-ID: <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>

Hi Neil,

On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
> On 19/01/2022 09:40, Neil Armstrong wrote:
> > Hi,
> > 
> > On 19/01/2022 03:37, Liu Ying wrote:
> > > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > > mentions that it should be in UI.  However, the dphy core driver wrongly
> > > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > > is '8 UI', instead of 8.
> > > 
> > > So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> > > member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> > > value according to the D-PHY specification.
> > > 
> > > I'm assuming that all impacted custom drivers shall program values in
> > > TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> > > specification mentions that the frequency of TxByteClkHS is exactly 1/8
> > > the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> > > custom driver code is changed to program those values as
> > > DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> > > 
> > > Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> > > Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> > > as I don't have the hardwares.
> > > 
> > > Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> > > Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> > > Cc: Neil Armstrong <narmstrong at baylibre.com>
> > > Cc: Robert Foss <robert.foss at linaro.org>
> > > Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> > > Cc: Jonas Karlman <jonas at kwiboo.se>
> > > Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> > > Cc: David Airlie <airlied at linux.ie>
> > > Cc: Daniel Vetter <daniel at ffwll.ch>
> > > Cc: Kishon Vijay Abraham I <kishon at ti.com>
> > > Cc: Vinod Koul <vkoul at kernel.org>
> > > Cc: Kevin Hilman <khilman at baylibre.com>
> > > Cc: Jerome Brunet <jbrunet at baylibre.com>
> > > Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> > > Cc: Heiko Stuebner <heiko at sntech.de>
> > > Cc: Maxime Ripard <mripard at kernel.org>
> > > Cc: Guido G?nther <agx at sigxcpu.org>
> > > Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> > > Signed-off-by: Liu Ying <victor.liu at nxp.com>
> > > ---
> > > v1->v2:
> > > * Use BITS_PER_BYTE macro. (Andrzej)
> > > * Drop dsi argument from ui2bc() in nwl-dsi.c.
> > > 
> > >  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
> > >  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
> > >  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
> > >  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
> > >  include/linux/phy/phy-mipi-dphy.h                |  2 +-
> > >  5 files changed, 12 insertions(+), 12 deletions(-)
> > > 
> [...]
> 
> > > diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > index cd2332bf0e31..fdbd64c03e12 100644
> > > --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> > > @@ -9,6 +9,7 @@
> > >  
> > >  #include <linux/bitfield.h>
> > >  #include <linux/bitops.h>
> > > +#include <linux/bits.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/delay.h>
> > >  #include <linux/io.h>
> > > @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
> > >  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
> > >  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
> > >  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> > > -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> > > +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
> > >  
> > >  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
> > >  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> > 
> > I'll try to run a test, currently the calculation gives 2, so this would give 1.
> 
> The Amlogic vendor code does:
> 
> /* >8*ui */
> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)

This looks like clk_pre time is 10 * ui, which matches the comment
'>8*ui' - longer time 8 * ui.

> 
> t_ui = lcd_timing.bit_rate
> 
> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
> temp = t_ui * 8; /* lane_byte cycle time */

If I read correctly, this temp in vendor code is TxByteClkHS period
time in picoseconds. So...

> 
> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;

IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
* ui, temp), that is, the time for dphy->clk_pre is no less than 
10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
spec.

However, the vendor code doesn't seem to match the current meson driver
implementation.  The temp in driver code is also TxByteClkHS period
time in picoseconds. And, without this patch, I'm assuming that
priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
'10 * ui'.

So, 3 choices for meson, up to you:
1) If meson really requires the time for clk_pre no less than
10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
2) If meson follows the spec's minimum value, then the patch does
things right for meson.
3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
DIV_ROUND_UP(8000, temp).

With this patch applied, do you see any display artifacts by visual
check? Or even checked signals through DSI analyzer?

Regards,
Liu Ying

> 
> PHY Registers only says:
> MIPI_DSI_CLK_TIM1	[31:0]
> 7:0 	R/W	0	 tCLK_PRE
> 
> > Neil
> > 
> 
> [...]



From miles.chen at mediatek.com  Wed Jan 19 02:06:15 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 18:06:15 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
Message-ID: <20220119100615.5059-1-miles.chen@mediatek.com>

Hi,

>Hi Miles,
>
>I'm actually not able to reproduce your oops. I'm using vanilla clang
>13, cross compiling for arm64, with thin LTO enabled and CFI enabled.
>Kernel seems to run fine.
>
>
>Are there other settings that are needed to trigger this? Do you see
>it in upstream clang or just the Android fork of clang?
>
I will try another clang (the previous version I use).
I am using Android fork of clang and there is a clang upgrade in this merge.

Miles



From axe.yang at mediatek.com  Wed Jan 19 02:08:54 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:08:54 +0800
Subject: [PATCH 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <754779eb-71f9-2083-a204-1d98b4a04a08@collabora.com>
References: <20220117071220.17330-1-axe.yang@mediatek.com>
 <20220117071220.17330-4-axe.yang@mediatek.com>
 <754779eb-71f9-2083-a204-1d98b4a04a08@collabora.com>
Message-ID: <923906efde997b1ad338c1f5d7748acd078e2438.camel@mediatek.com>

On Mon, 2022-01-17 at 11:50 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/01/22 08:12, Axe Yang ha scritto:
> > Add support for eint IRQ when MSDC is used as an SDIO host. This
> > feature requires SDIO device support async IRQ function. With this
> > feature, SDIO host can be awakened by SDIO card in suspend state,
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in MSDC node
> > to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> > are mandatory. And cap-sdio-async-irq flag is necessary since this
> > feature depends on asynchronous interrupt:
> >          &mmcX {
> >                  ...
> >                  pinctrl-names = "default", "state_uhs",
> > "state_eint",
> >                                  "state_dat1";
> >                  ...
> >                  pinctrl-2 = <&mmc2_pins_eint>;
> >                  pinctrl-3 = <&mmc2_pins_dat1>;
> >                  ...
> >                  cap-sdio-async-irq;
> >                  ...
> >          };
> > 
> > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> > Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> > ---
> >   drivers/mmc/host/mtk-sd.c | 125
> > +++++++++++++++++++++++++++++++++++---
> >   1 file changed, 117 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> > index 65037e1d7723..cbdbcce99fd9 100644
> > --- a/drivers/mmc/host/mtk-sd.c
> > +++ b/drivers/mmc/host/mtk-sd.c
> > @@ -1,6 +1,6 @@
> >   // SPDX-License-Identifier: GPL-2.0-only
> >   /*
> > - * Copyright (c) 2014-2015 MediaTek Inc.
> > + * Copyright (c) 2022 MediaTek Inc.
> >    * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
> >    */
> >   
> > @@ -9,6 +9,7 @@
> >   #include <linux/clk.h>
> >   #include <linux/delay.h>
> >   #include <linux/dma-mapping.h>
> > +#include <linux/gpio/consumer.h>
> >   #include <linux/iopoll.h>
> >   #include <linux/ioport.h>
> >   #include <linux/irq.h>
> > @@ -440,8 +441,12 @@ struct msdc_host {
> >   	struct pinctrl *pinctrl;
> >   	struct pinctrl_state *pins_default;
> >   	struct pinctrl_state *pins_uhs;
> > +	struct pinctrl_state *pins_eint;
> > +	struct pinctrl_state *pins_dat1;
> >   	struct delayed_work req_timeout;
> >   	int irq;		/* host interrupt */
> > +	int eint_irq;		/* device interrupt */
> > +	int sdio_irq_cnt;	/* irq enable cnt */
> >   	struct reset_control *reset;
> >   
> >   	struct clk *src_clk;	/* msdc source clock */
> > @@ -465,6 +470,7 @@ struct msdc_host {
> >   	bool hs400_tuning;	/* hs400 mode online tuning */
> >   	bool internal_cd;	/* Use internal card-detect logic */
> >   	bool cqhci;		/* support eMMC hw cmdq */
> > +	bool sdio_eint_ready;	/* Ready to support SDIO eint
> > interrupt */
> >   	struct msdc_save_para save_para; /* used when gate HCLK */
> >   	struct msdc_tune_para def_tune_para; /* default tune setting */
> >   	struct msdc_tune_para saved_tune_para; /* tune result of
> > CMD21/CMD19 */
> > @@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct
> > mmc_host *mmc, int enb)
> >   	__msdc_enable_sdio_irq(host, enb);
> >   	spin_unlock_irqrestore(&host->lock, flags);
> >   
> > -	if (enb)
> > -		pm_runtime_get_noresume(host->dev);
> > -	else
> > -		pm_runtime_put_noidle(host->dev);
> > +	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
> > +		if (enb)
> > +			pm_runtime_get_noresume(host->dev);
> > +		else
> > +			pm_runtime_put_noidle(host->dev);
> > +	}
> >   }
> >   
> >   static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32
> > intsts)
> > @@ -2461,6 +2469,50 @@ static const struct mmc_host_ops mt_msdc_ops
> > = {
> >   	.hw_reset = msdc_hw_reset,
> >   };
> >   
> > +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> > +{
> > +	struct msdc_host *host = dev_id;
> > +	struct mmc_host *mmc = mmc_from_priv(host);
> > +	unsigned long flags;
> > +
> > +	spin_lock_irqsave(&host->lock, flags);
> > +	if (likely(host->sdio_irq_cnt > 0)) {
> > +		disable_irq_nosync(host->eint_irq);
> > +		disable_irq_wake(host->eint_irq);
> > +		host->sdio_irq_cnt--;
> > +	}
> > +	spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +	sdio_signal_irq(mmc);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> > +{
> > +	struct gpio_desc *desc;
> > +	int irq, ret;
> > +
> > +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> > +	if (IS_ERR(desc))
> > +		return PTR_ERR(desc);
> > +
> > +	ret = gpiod_to_irq(desc);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	irq = ret;
> > +	ret = devm_request_threaded_irq(host->dev, irq, NULL,
> > msdc_sdio_eint_irq,
> > +					IRQF_TRIGGER_LOW | IRQF_ONESHOT
> > | IRQF_NO_AUTOEN,
> > +					"sdio-eint", host);
> > +	if (ret)
> > +		return ret;
> > +
> > +	host->eint_irq = irq;
> > +
> > +	return 0;
> > +}
> > +
> >   static const struct cqhci_host_ops msdc_cmdq_ops = {
> >   	.enable         = msdc_cqe_enable,
> >   	.disable        = msdc_cqe_disable,
> > @@ -2631,6 +2683,23 @@ static int msdc_drv_probe(struct
> > platform_device *pdev)
> >   		goto host_free;
> >   	}
> >   
> > +	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO)) {
> 
> Please, also check for the async irq capability here:
> 
> if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 &
> MMC_CAP2_SDIO_ASYNC_IRQ)) {
> 
> ...because if we have "state_eint" specified in DT, but we didn't
> *also* specify
> cap-sdio-async-irq, then clearly we don't want to use this
> functionality - hence
> it becomes useless to register the interrupt handler for that because
> we're never
> enabling the CCCR_INTERRUPT_EXT on the card (from
> drivers/mmc/core/host.c).
> 
> Regards,
> Angelo

Thanks, will fix this in next version.

> 
> > +		/* Support for SDIO eint irq */
> > +		host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> > "state_eint");
> > +		if (IS_ERR(host->pins_eint)) {
> > +			dev_dbg(&pdev->dev, "Cannot find pinctrl
> > eint!\n");
> > +		} else {
> > +			host->pins_dat1 = pinctrl_lookup_state(host-
> > >pinctrl, "state_dat1");
> > +			if (IS_ERR(host->pins_dat1)) {
> > +				ret = dev_err_probe(&pdev->dev,
> > PTR_ERR(host->pins_dat1),
> > +						    "Cannot find
> > pinctrl dat1!\n");
> > +				goto host_free;
> > +			}
> > +
> > +			host->sdio_eint_ready = true;
> > +		}
> > +	}
> > +
> >   	msdc_of_property_parse(pdev, host);
> >   
> >   	host->dev = &pdev->dev;
> > @@ -2722,6 +2791,16 @@ static int msdc_drv_probe(struct
> > platform_device *pdev)
> >   	if (ret)
> >   		goto release;
> >   
> > +	if (host->sdio_eint_ready) {
> > +		ret = msdc_request_dat1_eint_irq(host);
> > +		if (ret) {
> > +			dev_err(host->dev, "Failed to register data1
> > eint irq!\n");
> > +			goto release;
> > +		}
> > +
> > +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> > +	}
> > +
> >   	pm_runtime_set_active(host->dev);
> >   	pm_runtime_set_autosuspend_delay(host->dev,
> > MTK_MMC_AUTOSUSPEND_DELAY);
> >   	pm_runtime_use_autosuspend(host->dev);
> > @@ -2841,16 +2920,31 @@ static void msdc_restore_reg(struct
> > msdc_host *host)
> >   
> >   static int __maybe_unused msdc_runtime_suspend(struct device
> > *dev)
> >   {
> > +	unsigned long flags;
> >   	struct mmc_host *mmc = dev_get_drvdata(dev);
> >   	struct msdc_host *host = mmc_priv(mmc);
> >   
> >   	msdc_save_reg(host);
> > +
> > +	if (host->sdio_eint_ready) {
> > +		disable_irq(host->irq);
> > +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> > +		spin_lock_irqsave(&host->lock, flags);
> > +		if (host->sdio_irq_cnt == 0) {
> > +			enable_irq(host->eint_irq);
> > +			enable_irq_wake(host->eint_irq);
> > +			host->sdio_irq_cnt++;
> > +		}
> > +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> > +		spin_unlock_irqrestore(&host->lock, flags);
> > +	}
> >   	msdc_gate_clock(host);
> >   	return 0;
> >   }
> >   
> >   static int __maybe_unused msdc_runtime_resume(struct device *dev)
> >   {
> > +	unsigned long flags;
> >   	struct mmc_host *mmc = dev_get_drvdata(dev);
> >   	struct msdc_host *host = mmc_priv(mmc);
> >   	int ret;
> > @@ -2860,10 +2954,25 @@ static int __maybe_unused
> > msdc_runtime_resume(struct device *dev)
> >   		return ret;
> >   
> >   	msdc_restore_reg(host);
> > +
> > +	if (host->sdio_eint_ready) {
> > +		spin_lock_irqsave(&host->lock, flags);
> > +		if (host->sdio_irq_cnt > 0) {
> > +			disable_irq_nosync(host->eint_irq);
> > +			disable_irq_wake(host->eint_irq);
> > +			host->sdio_irq_cnt--;
> > +			sdr_set_bits(host->base + SDC_CFG,
> > SDC_CFG_SDIOIDE);
> > +		} else {
> > +			sdr_clr_bits(host->base + MSDC_INTEN,
> > MSDC_INTEN_SDIOIRQ);
> > +		}
> > +		spin_unlock_irqrestore(&host->lock, flags);
> > +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> > +		enable_irq(host->irq);
> > +	}
> >   	return 0;
> >   }
> >   
> > -static int __maybe_unused msdc_suspend(struct device *dev)
> > +static int __maybe_unused msdc_suspend_noirq(struct device *dev)
> >   {
> >   	struct mmc_host *mmc = dev_get_drvdata(dev);
> >   	int ret;
> > @@ -2877,13 +2986,13 @@ static int __maybe_unused
> > msdc_suspend(struct device *dev)
> >   	return pm_runtime_force_suspend(dev);
> >   }
> >   
> > -static int __maybe_unused msdc_resume(struct device *dev)
> > +static int __maybe_unused msdc_resume_noirq(struct device *dev)
> >   {
> >   	return pm_runtime_force_resume(dev);
> >   }
> >   
> >   static const struct dev_pm_ops msdc_dev_pm_ops = {
> > -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> > +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq,
> > msdc_resume_noirq)
> >   	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume,
> > NULL)
> >   };
> >   
> > 
> 
> 

From miles.chen at mediatek.com  Wed Jan 19 02:10:22 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 18:10:22 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXEuWRUbCqDBnxiWRaERt6OGL8ufQ1Q7naAGHqKK1oQB1w@mail.gmail.com>
References: <CAMj1kXEuWRUbCqDBnxiWRaERt6OGL8ufQ1Q7naAGHqKK1oQB1w@mail.gmail.com>
Message-ID: <20220119101022.5176-1-miles.chen@mediatek.com>

Hi, 

> We should try to understand why CFI thinks the prototypes of the two
> symbols are different. There are still a number of issues with CFI, so
> papering over them by reverting stuff that we want for good reasons is
> not the way to go imo.
> 
> In the short term, you can work around it by avoiding the indirect
> call to blake2s_compress, e.g.,

Thanks for the patch. I tried it and the issue remains.
As Jason said, he cannot reproduce this issue. I will try another version
of clang next.

Miles


From narmstrong at baylibre.com  Wed Jan 19 02:11:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 11:11:19 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
 <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
Message-ID: <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>

Hi,

On 19/01/2022 11:01, Liu Ying wrote:
> Hi Neil,
> 
> On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
>> On 19/01/2022 09:40, Neil Armstrong wrote:
>>> Hi,
>>>
>>> On 19/01/2022 03:37, Liu Ying wrote:
>>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>>> is '8 UI', instead of 8.
>>>>
>>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>>> value according to the D-PHY specification.
>>>>
>>>> I'm assuming that all impacted custom drivers shall program values in
>>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>>> custom driver code is changed to program those values as
>>>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>>>
>>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>>> as I don't have the hardwares.
>>>>
>>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>>> Cc: Robert Foss <robert.foss at linaro.org>
>>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>>> Cc: David Airlie <airlied at linux.ie>
>>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>>> Cc: Vinod Koul <vkoul at kernel.org>
>>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>>> Cc: Maxime Ripard <mripard at kernel.org>
>>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>> ---
>>>> v1->v2:
>>>> * Use BITS_PER_BYTE macro. (Andrzej)
>>>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>>>
>>>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>>>
>> [...]
>>
>>>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> index cd2332bf0e31..fdbd64c03e12 100644
>>>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>> @@ -9,6 +9,7 @@
>>>>  
>>>>  #include <linux/bitfield.h>
>>>>  #include <linux/bitops.h>
>>>> +#include <linux/bits.h>
>>>>  #include <linux/clk.h>
>>>>  #include <linux/delay.h>
>>>>  #include <linux/io.h>
>>>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>>>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>>>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>>>  
>>>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
>>>
>>> I'll try to run a test, currently the calculation gives 2, so this would give 1.
>>
>> The Amlogic vendor code does:
>>
>> /* >8*ui */
>> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)
> 
> This looks like clk_pre time is 10 * ui, which matches the comment
> '>8*ui' - longer time 8 * ui.
> 
>>
>> t_ui = lcd_timing.bit_rate
>>
>> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
>> temp = t_ui * 8; /* lane_byte cycle time */
> 
> If I read correctly, this temp in vendor code is TxByteClkHS period
> time in picoseconds. So...
> 
>>
>> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;
> 
> IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
> * ui, temp), that is, the time for dphy->clk_pre is no less than 
> 10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
> dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
> spec.
> 
> However, the vendor code doesn't seem to match the current meson driver
> implementation.  The temp in driver code is also TxByteClkHS period
> time in picoseconds. And, without this patch, I'm assuming that
> priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
> set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
> '10 * ui'.
> 
> So, 3 choices for meson, up to you:
> 1) If meson really requires the time for clk_pre no less than
> 10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
> 2) If meson follows the spec's minimum value, then the patch does
> things right for meson.
> 3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
> DIV_ROUND_UP(8000, temp).
> 
> With this patch applied, do you see any display artifacts by visual
> check? Or even checked signals through DSI analyzer?

Thanks for the feedback, I'm currently trying to put the setup back to
run a test with this change.

Neil

> 
> Regards,
> Liu Ying
> 
>>
>> PHY Registers only says:
>> MIPI_DSI_CLK_TIM1	[31:0]
>> 7:0 	R/W	0	 tCLK_PRE
>>
>>> Neil
>>>
>>
>> [...]
> 



From Jason at zx2c4.com  Wed Jan 19 02:11:26 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 11:11:26 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <20220119100615.5059-1-miles.chen@mediatek.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
Message-ID: <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>

Hi Miles,

Okay. Keep me posted.

Just FYI, as mentioned, I'm unable to reproduce this, and you haven't
provided any further minimized guidance on how I might reproduce this,
so it'll sit in the "not a bug" bin until I have another clue on how
to reproduce. Alternatively, Nick and Nathan are now on this thread
and they usually have good luck teasing out compiler issues and such,
so maybe they'll have an idea. But I'm afraid with the information I
currently have, I'm at a dead end.

Jason


From ardb at kernel.org  Wed Jan 19 02:13:35 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 19 Jan 2022 11:13:35 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <20220119100615.5059-1-miles.chen@mediatek.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
Message-ID: <CAMj1kXE_6WboUK0VPbTwzTbMNxv8b4XUp7USQUp=YqcCRMTZig@mail.gmail.com>

On Wed, 19 Jan 2022 at 11:06, Miles Chen <miles.chen at mediatek.com> wrote:
>
> Hi,
>
> >Hi Miles,
> >
> >I'm actually not able to reproduce your oops. I'm using vanilla clang
> >13, cross compiling for arm64, with thin LTO enabled and CFI enabled.
> >Kernel seems to run fine.
> >
> >
> >Are there other settings that are needed to trigger this? Do you see
> >it in upstream clang or just the Android fork of clang?
> >
> I will try another clang (the previous version I use).
> I am using Android fork of clang and there is a clang upgrade in this merge.
>

One thing that could be worth a try is to make __blake2s_update() and
__blake2s_final() __always_inline rather than just inline, which by
itself does not appear to be sufficient for the code to get inlined.
(If it were, the indirect call should have disappeared as well)

Given that indirect calls suck on x86, we should probably apply that
change in any case, regardless of CFI.


From Jason at zx2c4.com  Wed Jan 19 02:20:19 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 11:20:19 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXE_6WboUK0VPbTwzTbMNxv8b4XUp7USQUp=YqcCRMTZig@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAMj1kXE_6WboUK0VPbTwzTbMNxv8b4XUp7USQUp=YqcCRMTZig@mail.gmail.com>
Message-ID: <CAHmME9o-=q6jT6mF3XsfoA17756YVEWdXGHukP=rxWS1gs5irg@mail.gmail.com>

On 1/19/22, Ard Biesheuvel <ardb at kernel.org> wrote:
> On Wed, 19 Jan 2022 at 11:06, Miles Chen <miles.chen at mediatek.com> wrote:
>>
>> Hi,
>>
>> >Hi Miles,
>> >
>> >I'm actually not able to reproduce your oops. I'm using vanilla clang
>> >13, cross compiling for arm64, with thin LTO enabled and CFI enabled.
>> >Kernel seems to run fine.
>> >
>> >
>> >Are there other settings that are needed to trigger this? Do you see
>> >it in upstream clang or just the Android fork of clang?
>> >
>> I will try another clang (the previous version I use).
>> I am using Android fork of clang and there is a clang upgrade in this
>> merge.
>>
>
> One thing that could be worth a try is to make __blake2s_update() and
> __blake2s_final() __always_inline rather than just inline, which by
> itself does not appear to be sufficient for the code to get inlined.
> (If it were, the indirect call should have disappeared as well)
>
> Given that indirect calls suck on x86, we should probably apply that
> change in any case, regardless of CFI.
>

Had the same thought at first, but then looking at the original stack
trace, it looks like the __ function is inlined:

[    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
[    0.000000][    T0]  blake2s_update+0x14c/0x178
[    0.000000][    T0]  _extract_entropy+0xf4/0x29c

So that makes me think that the issue really does involve calling
through the weak alias. But why should weak alias calling trigger CFI?
Compiler bug? Some other subtlety we're missing?

Jason


From maz at kernel.org  Wed Jan 19 02:21:20 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 19 Jan 2022 10:21:20 +0000
Subject: [RFC PATCH v3 04/11] KVM: arm64: Setup a framework for hypercall
 bitmap firmware registers
In-Reply-To: <960d4166-1718-55ef-d324-507a8add7e3e@redhat.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-5-rananta@google.com>
 <960d4166-1718-55ef-d324-507a8add7e3e@redhat.com>
Message-ID: <87ee5481r3.wl-maz@kernel.org>

On Wed, 19 Jan 2022 06:42:15 +0000,
Jason Wang <jasowang at redhat.com> wrote:
> 
> 
> ? 2022/1/5 ??3:49, Raghavendra Rao Ananta ??:
> > KVM regularly introduces new hypercall services to the guests without
> > any consent from the Virtual Machine Manager (VMM). This means, the
> > guests can observe hypercall services in and out as they migrate
> > across various host kernel versions. This could be a major problem
> > if the guest discovered a hypercall, started using it, and after
> > getting migrated to an older kernel realizes that it's no longer
> > available. Depending on how the guest handles the change, there's
> > a potential chance that the guest would just panic.
> > 
> > As a result, there's a need for the VMM to elect the services that
> > it wishes the guest to discover. VMM can elect these services based
> > on the kernels spread across its (migration) fleet. To remedy this,
> > extend the existing firmware psuedo-registers, such as
> > KVM_REG_ARM_PSCI_VERSION, for all the hypercall services available.
> 
> 
> 
> Haven't gone through the series but I wonder whether it's better to
> have a (e)BPF filter for this like seccomp.

No, please. This has to fit in the save/restore model, and should be
under control of the VMM. If you want to filter things using seccomp,
that's fine, but also that's completely orthogonal.

	M.

-- 
Without deviation from the norm, progress is not possible.


From axe.yang at mediatek.com  Wed Jan 19 02:11:43 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:11:43 +0800
Subject: [RESEND v3 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <CAHp75VdkKYujGZOdGkLK-tzC9q+RjkX59fFZe5cHajGOnDdL2w@mail.gmail.com>
References: <20220117082539.18713-1-axe.yang@mediatek.com>
 <20220117082539.18713-4-axe.yang@mediatek.com>
 <CAHp75VdkKYujGZOdGkLK-tzC9q+RjkX59fFZe5cHajGOnDdL2w@mail.gmail.com>
Message-ID: <068c965a0243486f0e1cabbafb8904a6a8ddcc9f.camel@mediatek.com>

On Tue, 2022-01-18 at 11:18 +0200, Andy Shevchenko wrote:
> On Mon, Jan 17, 2022 at 7:33 PM Axe Yang <axe.yang at mediatek.com>
> wrote:
> > 
> > Add support for eint IRQ when MSDC is used as an SDIO host. This
> > feature requires SDIO device support async IRQ function. With this
> > feature, SDIO host can be awakened by SDIO card in suspend state,
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in MSDC node
> > to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> > are mandatory. And cap-sdio-async-irq flag is necessary since this
> > feature depends on asynchronous interrupt:
> >         &mmcX {
> >                 ...
> >                 pinctrl-names = "default", "state_uhs",
> > "state_eint",
> >                                 "state_dat1";
> >                 ...
> >                 pinctrl-2 = <&mmc2_pins_eint>;
> >                 pinctrl-3 = <&mmc2_pins_dat1>;
> >                 ...
> >                 cap-sdio-async-irq;
> >                 ...
> >         };
> 
> ...
> 
> > +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> > +{
> > +       struct msdc_host *host = dev_id;
> > +       struct mmc_host *mmc = mmc_from_priv(host);
> > +       unsigned long flags;
> 
> Same Q as per v2. Why do you need this?
> 
> Yes, you did the first step to the answer, but I want you to go
> deeper
> and tell me why you need the spin_lock_irqsave() variant.

You are right, no need to save/restore flags in irq handler.
Will fix it in new version.
Thanks.

> 
> > +       spin_lock_irqsave(&host->lock, flags);
> > +       if (likely(host->sdio_irq_cnt > 0)) {
> > +               disable_irq_nosync(host->eint_irq);
> > +               disable_irq_wake(host->eint_irq);
> > +               host->sdio_irq_cnt--;
> > +       }
> > +       spin_unlock_irqrestore(&host->lock, flags);
> > +
> > +       sdio_signal_irq(mmc);
> > +
> > +       return IRQ_HANDLED;
> > +}
> 
> 

From axe.yang at mediatek.com  Wed Jan 19 02:32:12 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:32:12 +0800
Subject: [PATCH v4 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220119103212.13158-1-axe.yang@mediatek.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
Message-ID: <20220119103212.13158-4-axe.yang@mediatek.com>

Add support for eint IRQ when MSDC is used as an SDIO host. This
feature requires SDIO device support async IRQ function. With this
feature, SDIO host can be awakened by SDIO card in suspend state,
without additional pin.

MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
resume, switch GPIO function back to DAT1 mode then turn on clock.

Some device tree property should be added or modified in MSDC node
to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
are mandatory. And cap-sdio-async-irq flag is necessary since this
feature depends on asynchronous interrupt:
        &mmcX {
                ...
                pinctrl-names = "default", "state_uhs", "state_eint",
                                "state_dat1";
                ...
                pinctrl-2 = <&mmc2_pins_eint>;
                pinctrl-3 = <&mmc2_pins_dat1>;
                ...
                cap-sdio-async-irq;
                ...
        };

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
Signed-off-by: Yong Mao <yong.mao at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 124 +++++++++++++++++++++++++++++++++++---
 1 file changed, 116 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 65037e1d7723..066616ddc88f 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2015 MediaTek Inc.
+ * Copyright (c) 2022 MediaTek Inc.
  * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
  */
 
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -440,8 +441,12 @@ struct msdc_host {
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
+	struct pinctrl_state *pins_eint;
+	struct pinctrl_state *pins_dat1;
 	struct delayed_work req_timeout;
 	int irq;		/* host interrupt */
+	int eint_irq;		/* device interrupt */
+	int sdio_irq_cnt;	/* irq enable cnt */
 	struct reset_control *reset;
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -465,6 +470,7 @@ struct msdc_host {
 	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
+	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 	struct msdc_tune_para def_tune_para; /* default tune setting */
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
@@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	__msdc_enable_sdio_irq(host, enb);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (enb)
-		pm_runtime_get_noresume(host->dev);
-	else
-		pm_runtime_put_noidle(host->dev);
+	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
+		if (enb)
+			pm_runtime_get_noresume(host->dev);
+		else
+			pm_runtime_put_noidle(host->dev);
+	}
 }
 
 static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
@@ -2461,6 +2469,49 @@ static const struct mmc_host_ops mt_msdc_ops = {
 	.hw_reset = msdc_hw_reset,
 };
 
+static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
+{
+	struct msdc_host *host = dev_id;
+	struct mmc_host *mmc = mmc_from_priv(host);
+
+	spin_lock(&host->lock);
+	if (likely(host->sdio_irq_cnt > 0)) {
+		disable_irq_nosync(host->eint_irq);
+		disable_irq_wake(host->eint_irq);
+		host->sdio_irq_cnt--;
+	}
+	spin_unlock(&host->lock);
+
+	sdio_signal_irq(mmc);
+
+	return IRQ_HANDLED;
+}
+
+static int msdc_request_dat1_eint_irq(struct msdc_host *host)
+{
+	struct gpio_desc *desc;
+	int irq, ret;
+
+	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	ret = gpiod_to_irq(desc);
+	if (ret < 0)
+		return ret;
+
+	irq = ret;
+	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					"sdio-eint", host);
+	if (ret)
+		return ret;
+
+	host->eint_irq = irq;
+
+	return 0;
+}
+
 static const struct cqhci_host_ops msdc_cmdq_ops = {
 	.enable         = msdc_cqe_enable,
 	.disable        = msdc_cqe_disable,
@@ -2631,6 +2682,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ)) {
+		/* Support for SDIO eint irq */
+		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+		if (IS_ERR(host->pins_eint)) {
+			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
+		} else {
+			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
+			if (IS_ERR(host->pins_dat1)) {
+				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
+						    "Cannot find pinctrl dat1!\n");
+				goto host_free;
+			}
+
+			host->sdio_eint_ready = true;
+		}
+	}
+
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
@@ -2722,6 +2790,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto release;
 
+	if (host->sdio_eint_ready) {
+		ret = msdc_request_dat1_eint_irq(host);
+		if (ret) {
+			dev_err(host->dev, "Failed to register data1 eint irq!\n");
+			goto release;
+		}
+
+		pinctrl_select_state(host->pinctrl, host->pins_dat1);
+	}
+
 	pm_runtime_set_active(host->dev);
 	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(host->dev);
@@ -2841,16 +2919,31 @@ static void msdc_restore_reg(struct msdc_host *host)
 
 static int __maybe_unused msdc_runtime_suspend(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 
 	msdc_save_reg(host);
+
+	if (host->sdio_eint_ready) {
+		disable_irq(host->irq);
+		pinctrl_select_state(host->pinctrl, host->pins_eint);
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt == 0) {
+			enable_irq(host->eint_irq);
+			enable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt++;
+		}
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 	msdc_gate_clock(host);
 	return 0;
 }
 
 static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
+	unsigned long flags;
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
 	int ret;
@@ -2860,10 +2953,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 		return ret;
 
 	msdc_restore_reg(host);
+
+	if (host->sdio_eint_ready) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt > 0) {
+			disable_irq_nosync(host->eint_irq);
+			disable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt--;
+			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		} else {
+			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+		enable_irq(host->irq);
+	}
 	return 0;
 }
 
-static int __maybe_unused msdc_suspend(struct device *dev)
+static int __maybe_unused msdc_suspend_noirq(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret;
@@ -2877,13 +2985,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int __maybe_unused msdc_resume(struct device *dev)
+static int __maybe_unused msdc_resume_noirq(struct device *dev)
 {
 	return pm_runtime_force_resume(dev);
 }
 
 static const struct dev_pm_ops msdc_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-- 
2.25.1



From axe.yang at mediatek.com  Wed Jan 19 02:32:11 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:32:11 +0800
Subject: [PATCH v4 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20220119103212.13158-1-axe.yang@mediatek.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
Message-ID: <20220119103212.13158-3-axe.yang@mediatek.com>

If cap-sdio-async-irq flag is set in host dts node, parse EAI
information from SDIO CCCR interrupt externsion segment. If async
interrupt is supported by SDIO card then send command to card to
enable it and set enable_async_irq flag in sdio_cccr structure to 1.
The parse flow is implemented in sdio_read_cccr().

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
 include/linux/mmc/card.h |  3 ++-
 include/linux/mmc/host.h |  1 +
 include/linux/mmc/sdio.h |  5 +++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf140f4ec864..a972241548b4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -410,6 +410,8 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "no-mmc-hs400"))
 		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
 				 MMC_CAP2_HS400_ES);
+	if (device_property_read_bool(dev, "cap-sdio-async-irq"))
+		host->caps2 |= MMC_CAP2_SDIO_ASYNC_IRQ;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 41164748723d..771fb5d18585 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
 			if (data & SDIO_DRIVE_SDTD)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ) {
+				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
+						       &data);
+				if (ret)
+					goto out;
+
+				if (data & SDIO_INTERRUPT_EXT_SAI) {
+					data |= SDIO_INTERRUPT_EXT_EAI;
+					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+							       data, NULL);
+					if (ret)
+						goto out;
+
+					card->cccr.enable_async_irq = 1;
+				}
+			}
 		}
 
 		/* if no uhs mode ensure we check for high speed */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 37f975875102..4df9182bc0e6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,8 @@ struct sdio_cccr {
 				wide_bus:1,
 				high_power:1,
 				high_speed:1,
-				disable_cd:1;
+				disable_cd:1,
+				enable_async_irq:1;
 };
 
 struct sdio_cis {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7afb57cab00b..502a5418264c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -402,6 +402,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SDIO_ASYNC_IRQ	(1 << 29)	/* SDIO host supports asynchronous interrupt */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 2a05d1ac4f0e..1ef400f28642 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -159,6 +159,11 @@
 #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT	0x16
+#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
-- 
2.25.1



From axe.yang at mediatek.com  Wed Jan 19 02:32:09 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:32:09 +0800
Subject: [PATCH v4 0/3] mmc: mediatek: add support for SDIO eint IRQ 
Message-ID: <20220119103212.13158-1-axe.yang@mediatek.com>


Change in v4:
- add MMC_CAP2_SDIO_ASYNC_IRQ judge before lookup eint pinctrl
- replace spin_lock_irqsave() variant with spin_lock() in eint irq handler

Axe Yang (3):
  dt-bindings: mmc: add cap-sdio-async-irq flag
  mmc: core: Add support for SDIO async interrupt
  mmc: mediatek: add support for SDIO eint IRQ

 .../bindings/mmc/mmc-controller.yaml          |   5 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/sdio.c                       |  17 +++
 drivers/mmc/host/mtk-sd.c                     | 124 ++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +-
 include/linux/mmc/host.h                      |   1 +
 include/linux/mmc/sdio.h                      |   5 +
 7 files changed, 148 insertions(+), 9 deletions(-)

-- 
2.25.1




From ardb at kernel.org  Wed Jan 19 02:35:32 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 19 Jan 2022 11:35:32 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9o-=q6jT6mF3XsfoA17756YVEWdXGHukP=rxWS1gs5irg@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAMj1kXE_6WboUK0VPbTwzTbMNxv8b4XUp7USQUp=YqcCRMTZig@mail.gmail.com>
 <CAHmME9o-=q6jT6mF3XsfoA17756YVEWdXGHukP=rxWS1gs5irg@mail.gmail.com>
Message-ID: <CAMj1kXFdgPj7Ky-361QNAOLccr1mq5m9LSsPfbgpwV58fLAxJw@mail.gmail.com>

On Wed, 19 Jan 2022 at 11:20, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> On 1/19/22, Ard Biesheuvel <ardb at kernel.org> wrote:
> > On Wed, 19 Jan 2022 at 11:06, Miles Chen <miles.chen at mediatek.com> wrote:
> >>
> >> Hi,
> >>
> >> >Hi Miles,
> >> >
> >> >I'm actually not able to reproduce your oops. I'm using vanilla clang
> >> >13, cross compiling for arm64, with thin LTO enabled and CFI enabled.
> >> >Kernel seems to run fine.
> >> >
> >> >
> >> >Are there other settings that are needed to trigger this? Do you see
> >> >it in upstream clang or just the Android fork of clang?
> >> >
> >> I will try another clang (the previous version I use).
> >> I am using Android fork of clang and there is a clang upgrade in this
> >> merge.
> >>
> >
> > One thing that could be worth a try is to make __blake2s_update() and
> > __blake2s_final() __always_inline rather than just inline, which by
> > itself does not appear to be sufficient for the code to get inlined.
> > (If it were, the indirect call should have disappeared as well)
> >
> > Given that indirect calls suck on x86, we should probably apply that
> > change in any case, regardless of CFI.
> >
>
> Had the same thought at first, but then looking at the original stack
> trace, it looks like the __ function is inlined:
>
> [    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
> [    0.000000][    T0]  blake2s_update+0x14c/0x178
> [    0.000000][    T0]  _extract_entropy+0xf4/0x29c
>

Indeed. How odd. I hope this doesn't happen with the x86 backend
because that would be plain silly. On arm64, it doesn't actually
matter in terms of performance, it just needs one additional callee
save register to preserve the function pointer across calls.


From axe.yang at mediatek.com  Wed Jan 19 02:32:10 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Wed, 19 Jan 2022 18:32:10 +0800
Subject: [PATCH v4 1/3] dt-bindings: mmc: add cap-sdio-async-irq flag
In-Reply-To: <20220119103212.13158-1-axe.yang@mediatek.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
Message-ID: <20220119103212.13158-2-axe.yang@mediatek.com>

Asynchronous interrupt is a mechanism that allow SDIO devices alarm
interrupt when host stop providing clock to card. Add a DT flag to
enable this feature if it is supported by SDIO card.

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index 513f3c8758aa..16fb06f88471 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -165,6 +165,11 @@ properties:
     description:
       eMMC hardware reset is supported
 
+  cap-sdio-async-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO async interrupt is supported.
+
   cap-sdio-irq:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.25.1



From narmstrong at baylibre.com  Wed Jan 19 02:47:01 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Wed, 19 Jan 2022 11:47:01 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <28e3f723-daf0-b3c5-ee10-519c4cabfe17@baylibre.com>
 <5a638561-c704-49e7-1fed-70e26fedb186@baylibre.com>
 <8ad2cd76e80056192395ca5b73ff514e59881ba3.camel@nxp.com>
 <e02c9226-2dfb-5931-60e3-a22e51172c30@baylibre.com>
Message-ID: <661a7c69-0da6-32f5-ffa0-58426c5825e0@baylibre.com>

Hi,

On 19/01/2022 11:11, Neil Armstrong wrote:
> Hi,
> 
> On 19/01/2022 11:01, Liu Ying wrote:
>> Hi Neil,
>>
>> On Wed, 2022-01-19 at 10:11 +0100, Neil Armstrong wrote:
>>> On 19/01/2022 09:40, Neil Armstrong wrote:
>>>> Hi,
>>>>
>>>> On 19/01/2022 03:37, Liu Ying wrote:
>>>>> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
>>>>> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
>>>>> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
>>>>> mentions that it should be in UI.  However, the dphy core driver wrongly
>>>>> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
>>>>> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
>>>>> is '8 UI', instead of 8.
>>>>>
>>>>> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
>>>>> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
>>>>> value according to the D-PHY specification.
>>>>>
>>>>> I'm assuming that all impacted custom drivers shall program values in
>>>>> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
>>>>> specification mentions that the frequency of TxByteClkHS is exactly 1/8
>>>>> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
>>>>> custom driver code is changed to program those values as
>>>>> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
>>>>>
>>>>> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
>>>>> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
>>>>> as I don't have the hardwares.
>>>>>
>>>>> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
>>>>> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
>>>>> Cc: Neil Armstrong <narmstrong at baylibre.com>
>>>>> Cc: Robert Foss <robert.foss at linaro.org>
>>>>> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
>>>>> Cc: Jonas Karlman <jonas at kwiboo.se>
>>>>> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
>>>>> Cc: David Airlie <airlied at linux.ie>
>>>>> Cc: Daniel Vetter <daniel at ffwll.ch>
>>>>> Cc: Kishon Vijay Abraham I <kishon at ti.com>
>>>>> Cc: Vinod Koul <vkoul at kernel.org>
>>>>> Cc: Kevin Hilman <khilman at baylibre.com>
>>>>> Cc: Jerome Brunet <jbrunet at baylibre.com>
>>>>> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>>>>> Cc: Heiko Stuebner <heiko at sntech.de>
>>>>> Cc: Maxime Ripard <mripard at kernel.org>
>>>>> Cc: Guido G?nther <agx at sigxcpu.org>
>>>>> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
>>>>> Signed-off-by: Liu Ying <victor.liu at nxp.com>
>>>>> ---
>>>>> v1->v2:
>>>>> * Use BITS_PER_BYTE macro. (Andrzej)
>>>>> * Drop dsi argument from ui2bc() in nwl-dsi.c.
>>>>>
>>>>>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>>>>>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>>>>>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>>>>>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>>>>>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>>>>>  5 files changed, 12 insertions(+), 12 deletions(-)
>>>>>
>>> [...]
>>>
>>>>> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> index cd2332bf0e31..fdbd64c03e12 100644
>>>>> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
>>>>> @@ -9,6 +9,7 @@
>>>>>  
>>>>>  #include <linux/bitfield.h>
>>>>>  #include <linux/bitops.h>
>>>>> +#include <linux/bits.h>
>>>>>  #include <linux/clk.h>
>>>>>  #include <linux/delay.h>
>>>>>  #include <linux/io.h>
>>>>> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>>>>>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>>>>>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>>>>>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
>>>>> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
>>>>> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>>>>>  
>>>>>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>>>>>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
>>>>
>>>> I'll try to run a test, currently the calculation gives 2, so this would give 1.
>>>
>>> The Amlogic vendor code does:
>>>
>>> /* >8*ui */
>>> #define DPHY_TIME_CLK_PRE(ui)       (10 * ui)
>>
>> This looks like clk_pre time is 10 * ui, which matches the comment
>> '>8*ui' - longer time 8 * ui.
>>
>>>
>>> t_ui = lcd_timing.bit_rate
>>>
>>> t_ui = (1000000 * 100) / (dsi_ui / 1000); /*100*ns */
>>> temp = t_ui * 8; /* lane_byte cycle time */
>>
>> If I read correctly, this temp in vendor code is TxByteClkHS period
>> time in picoseconds. So...
>>
>>>
>>> dphy->clk_pre = ((DPHY_TIME_CLK_PRE(t_ui) + temp - 1) / temp) & 0xff;
>>
>> IIUC, 'dphy->clk_pre' essentially means dphy->clk_pre = DIV_ROUND_UP(10
>> * ui, temp), that is, the time for dphy->clk_pre is no less than 
>> 10 * ui.  The D-PHY spec (v1.2)'s saying is that the minimum time for
>> dphy->clk_pre is 8 * ui.  So, it looks like meson is stricter than the
>> spec.
>>
>> However, the vendor code doesn't seem to match the current meson driver
>> implementation.  The temp in driver code is also TxByteClkHS period
>> time in picoseconds. And, without this patch, I'm assuming that
>> priv->config.clk_pre is 8000.  So, it looks like MIPI_DSI_CLK_TIM1 is
>> set to DIV_ROUND_UP(8000, temp).  This '8000' does _not_ reflect
>> '10 * ui'.
>>
>> So, 3 choices for meson, up to you:
>> 1) If meson really requires the time for clk_pre no less than
>> 10 * ui, then sth like DIV_ROUND_UP(10, BITS_PER_BYTE) can be used.
>> 2) If meson follows the spec's minimum value, then the patch does
>> things right for meson.
>> 3) Force to use 8000 picoseconds for clk_pre, that is, use sth like
>> DIV_ROUND_UP(8000, temp).
>>
>> With this patch applied, do you see any display artifacts by visual
>> check? Or even checked signals through DSI analyzer?
> 
> Thanks for the feedback, I'm currently trying to put the setup back to
> run a test with this change.

I don't see any visible artifacts.

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c

Thanks,

> 
> Neil
> 
>>
>> Regards,
>> Liu Ying
>>
>>>
>>> PHY Registers only says:
>>> MIPI_DSI_CLK_TIM1	[31:0]
>>> 7:0 	R/W	0	 tCLK_PRE
>>>
>>>> Neil
>>>>
>>>
>>> [...]
>>
> 



From Jason at zx2c4.com  Wed Jan 19 02:56:39 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 11:56:39 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
Message-ID: <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>

On 1/19/22, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
> Hi Miles,
>
> Okay. Keep me posted.
>
> Just FYI, as mentioned, I'm unable to reproduce this, and you haven't
> provided any further minimized guidance on how I might reproduce this,
> so it'll sit in the "not a bug" bin until I have another clue on how
> to reproduce. Alternatively, Nick and Nathan are now on this thread
> and they usually have good luck teasing out compiler issues and such,
> so maybe they'll have an idea. But I'm afraid with the information I
> currently have, I'm at a dead end.
>
> Jason
>

We're back in business! I was able to reproduce this using FullLTO
rather than ThinLTO.


From ckeepax at opensource.cirrus.com  Wed Jan 19 02:57:24 2022
From: ckeepax at opensource.cirrus.com (Charles Keepax)
Date: Wed, 19 Jan 2022 10:57:24 +0000
Subject: [PATCH] dt-bindings: Drop unnecessary pinctrl properties
In-Reply-To: <20220119015325.2438277-1-robh@kernel.org>
References: <20220119015325.2438277-1-robh@kernel.org>
Message-ID: <20220119105724.GQ18506@ediswmail.ad.cirrus.com>

On Tue, Jan 18, 2022 at 07:53:25PM -0600, Rob Herring wrote:
> For a single pinctrl mode, it is not necessary to define pinctrl
> properties as the tools always allow pinctrl properties.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---

Acked-by: Charles Keepax <ckeepax at opensource.cirrus.com>

Thanks,
Charles


From mark.rutland at arm.com  Wed Jan 19 03:16:17 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 11:16:17 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <20220118235244.540103-1-yury.norov@gmail.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
Message-ID: <YefzAQ5LXJk1ytfI@FVFF77S0Q05N>

Hi,

I replied ot the original RFC before spotting this; duplicating those comments
here because I think they apply regardless of the mechanism used to work around
this.

On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer which would lead to DABT at address translation later. 
>
> Currently, kernel checks the pages against NULL. In my case, however, the
> address was not NULL, and was big enough so that the hardware generated
> Address Size Abort on arm64.

Can you give an example of when this might happen? It sounds like you're
actually hitting this, so a backtrace would be nice.

I'm a bit confused as to when why we'd try to vmap() pages that we
didn't have a legitimate struct page for -- where did these addresses
come from?

It sounds like this is going wrong at a higher level, and we're passing
entirely bogus struct page pointers around. This seems like the sort of
thing DEBUG_VIRTUAL or similar should check when we initially generate
the struct page pointer.

> Interestingly, this abort happens even if copy_from_kernel_nofault() is
> used, which is quite inconvenient for debugging purposes. 

I can go take a look at this, but TBH we never expect to take an address size
fault to begin with, so this is arguably correct -- it's an internal
consistency problem.

> This patch adds a pfn_valid() check into vmap() path, so that invalid
> mapping will not be created.
> 
> RFC: https://lkml.org/lkml/2022/1/18/815
> v1: use pfn_valid() instead of adding an arch-specific
>     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
> 
> Signed-off-by: Yury Norov <yury.norov at gmail.com>
> ---
>  mm/vmalloc.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d2a00ad4e1dd..a4134ee56b10 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
>  			return -EBUSY;
>  		if (WARN_ON(!page))
>  			return -ENOMEM;
> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> +			return -EINVAL;

My fear here is that for this to fire, we've already passed a bogus struct page
pointer around the intermediate infrastructure, and any of that might try to
use it in unsafe ways (in future even if we don't use it today).

I think the fundamental issue here is that we generate a bogus struct page
pointer at all, and knowing where that came from would help to fix that.

Thanks,
Mark.

>  		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
>  		(*nr)++;
>  	} while (pte++, addr += PAGE_SIZE, addr != end);
> -- 
> 2.30.2
> 


From german.gomez at arm.com  Wed Jan 19 03:27:50 2022
From: german.gomez at arm.com (German Gomez)
Date: Wed, 19 Jan 2022 11:27:50 +0000
Subject: [RFC PATCH 1/2] perf: arm_spe: Fix consistency of PMSCR register
 bit CX
In-Reply-To: <2cb1baab-fd9c-ea20-2a09-4cd60d9d5531@arm.com>
References: <20220117124432.3119132-1-german.gomez@arm.com>
 <20220117124432.3119132-2-german.gomez@arm.com>
 <20220118100702.GB16547@willie-the-truck>
 <2cb1baab-fd9c-ea20-2a09-4cd60d9d5531@arm.com>
Message-ID: <b417d710-2b45-791b-1707-175dd4398701@arm.com>


On 18/01/2022 14:04, German Gomez wrote:
> Hi Will,
>
> Many thanks for your comments
>
> On 18/01/2022 10:07, Will Deacon wrote:
>> On Mon, Jan 17, 2022 at 12:44:31PM +0000, German Gomez wrote:
>>> [...]
>>>
>>>   1. Run a process in the background with capability CAP_SYS_ADMIN in CPU0.
>>>
>>>     $ taskset --cpu-list 0 sudo dd if=/dev/random of=/dev/null &
>>>     [3] 3806
>>>
>>>   2. Begin a perf session _without_ capabilities (we shouldn't see CONTEXT packets).
>>>
>>>     $ perf record -e arm_spe_0// -C0 -- sleep 1
>>>     $ perf report -D | grep CONTEXT
>>>     .  0000000e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>>     .  0000004e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>>     .  0000008e:  65 df 0e 00 00                                  CONTEXT 0xedf el2
>>>     [...]
>>>
>>> As can be seen, the traces begin showing CONTEXT packets when the pid is
>>> 0xedf (3807).
>> So to be clear: we shouldn't be reporting these packets because 'perf'
>> doesn't have the right capabilities, but we evaluate that in the context of
>> 'dd' (running as root) and so incorrectly grant the permission. Correct?
> Yes, correct. My guess was that "perfmon_capable()" was being called
> under the assumption that it would always be evaluated in the context of
> 'perf'. Is that correct?
>
>>> This happens because the pmu start callback is run when
>>> the current process is not the owner of the perf session, so the CX
>>> register bit is set.
>> This doesn't really seem SPE-specific to me -- the perf_allow_*() helpers
>> also operate implicitly on the current task. How do other PMU drivers avoid
>> falling into this trap?
> I'm not as familiar with the other PMU drivers. I quickly tried grepping
> something related in the cs_etm drivers as they use CONTEXTIDR as well,
> but couldn't find references to perfmon_capable() or similar checks.
>
> Grepping for "perf_allow_" inside of drivers doesn't yield results.
> There's some gpu driver that has similar perfmon_capable() checks but
> unlike spe, they error out if they don't pass (drivers/gpu/drm/i915/i915_perf.c).

Just to expand a bit more on this (I missed grepping the other directories)

./arch/powerpc/perf/imc-pmu.c => perfmon_capable() only called on init
./kernel/events/core.c??????? => perfmon_capable() only called on init
./arch/x86/events/core.c????? => perf_allow_*() function only called on init

As far as I see, currently spe seems to be the only PMU event that
checks capabilities in the start callback. 'perf' may not be the current
task in this callback.

>
>>> One way to fix this is by caching the value of the CX bit during the
>>> initialization of the PMU event, so that it remains consistent for the
>>> duration of the session.
>> It doesn't feel right to stash this in 'struct arm_spe_pmu' during event
>> initialisation -- wouldn't that allow perf to continue creating new events
>> with CX set, even if the paranoid sysctl was changed dynamically? Instead,
>> I think it would be better if the capabilities were stash in the event
>> itself somehow at initialisation time.
> I hadn't considered this. Makes more sense to store in the perf_event
> or via some type of mapping in the struct spe_pmu if not possible. Do
> you have any idea for the former? Or an idiomatic structure from the
> kernel for the later?
>
> Thanks,
> German
>
>> Will


From angelogioacchino.delregno at collabora.com  Wed Jan 19 03:28:09 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 19 Jan 2022 12:28:09 +0100
Subject: [PATCH v5, 15/15] media: mtk-vcodec: support stateless VP9
 decoding
In-Reply-To: <20220117094001.20049-16-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
 <20220117094001.20049-16-yunfei.dong@mediatek.com>
Message-ID: <275affff-12d9-4659-e900-aa9c306e6701@collabora.com>

Il 17/01/22 10:40, Yunfei Dong ha scritto:
> Add support for VP9 decoding using the stateless API,
> as supported by MT8192. And the drivers is lat and core architecture.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> Signed-off-by: George Sun <george.sun at mediatek.com>
> ---
>   drivers/media/platform/mtk-vcodec/Makefile    |    1 +
>   .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   26 +-
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |    1 +
>   .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 1973 +++++++++++++++++
>   .../media/platform/mtk-vcodec/vdec_drv_if.c   |    4 +
>   .../media/platform/mtk-vcodec/vdec_drv_if.h   |    1 +
>   6 files changed, 2003 insertions(+), 3 deletions(-)
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
> 

Hello Yunfei,
this driver is based on an older version of the VP9 stateless decoder uAPI,
hence this is not applicable upstream.

The latest linux-next tag (as of today) already contains the new and
accepted code; can you please rebase over that one?

Thanks,
Angelo


From piotr.oniszczuk at gmail.com  Wed Jan 19 03:29:49 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Wed, 19 Jan 2022 12:29:49 +0100
Subject: [PATCH v3 00/22] drm/rockchip: RK356x VOP2 support
In-Reply-To: <20211220110630.3521121-1-s.hauer@pengutronix.de>
References: <20211220110630.3521121-1-s.hauer@pengutronix.de>
Message-ID: <AA3A26CB-6282-4A6B-99DC-8042DC8926BB@gmail.com>



> Wiadomo?? napisana przez Sascha Hauer <s.hauer at pengutronix.de> w dniu 20.12.2021, o godz. 12:06:
> 
> 
> Third round of patches and last one for this year. I hopefully integrated
> all review feedback. Additionally the driver is now fully converted to
> regmap, so no struct vop_reg necessary anymore.
> 
> Sascha
> 
> Changes since v2:
> - Add pin names to HDMI supply pin description
> - Add hclk support to HDMI driver
> - Dual license rockchip-vop2 binding, update binding
> - Add HDMI connector to board dts files
> - drop unnecessary gamma_lut registers from vop2
> - Update dclk_vop[012] clock handling, no longer hacks needed
> - Complete regmap conversion
> 

Sascha

I'm using you VOP2 code on rk3566 tvbox (x96-x6) with very good results.

I have just few questions:

1. how support for CEC looks/prospects (plans for future, not in this code, expecting others should implement, etc)?

2. VOP2 code works nice for me for x11/glamour and for EGLFS with EGL DMAbuf rendering by Mesa EGL_LINUX_DMA_BUF_EXT.
I have issue however with app. rendering to DRM planes (GUI is DRM plane1, video is DRM pane2). 
My ppp starts/works without any errors in log - but screen stays with kernel messages content.
(it looks to me like i.e. app renders to DRM plane but DRM display driver not pass it to CRTC. just wild guess here...).

3. in kernel dmesg I have many:

"rockchip-drm display-subsystem: [drm] *ERROR* Unsupported format modifier 0x810000000000001".

It comes from MESA i think - but i suspect because VOP2 provides unknown/wrong DRM modifier to mesa?.
I'm not sure how to progress with this (talk to you or involve MESA devs or wait for VOP2 v4)?

Again: great work with VOP2 on rk356x!



From m.tretter at pengutronix.de  Wed Jan 19 03:45:13 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 19 Jan 2022 12:45:13 +0100
Subject: [PATCH] iio: adc: xilinx-ams: Fix num_channels for PS channels
Message-ID: <20220119114513.2035609-1-m.tretter@pengutronix.de>

The IIO channels of the PS are not provided in the sysfs even if the
ams_ps is enabled in the device tree. The reason is that the channels of
the PS are not added to the overall number of IIO channels.

The line somehow got lost between v11 and v12 of the patch series.

Add the number of ams_ps_channels to the number of channels to correctly
register all channels.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
---
 drivers/iio/adc/xilinx-ams.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 8343c5f74121..ede968efb77f 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
 
 		/* add PS channels to iio device channels */
 		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
+		num_channels += ARRAY_SIZE(ams_ps_channels);
 	} else if (fwnode_property_match_string(fwnode, "compatible",
 						"xlnx,zynqmp-ams-pl") == 0) {
 		ams->pl_base = fwnode_iomap(fwnode, 0);
-- 
2.30.2



From agx at sigxcpu.org  Wed Jan 19 03:47:12 2022
From: agx at sigxcpu.org (Guido =?iso-8859-1?Q?G=FCnther?=)
Date: Wed, 19 Jan 2022 12:47:12 +0100
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <Yef6QJMNm1AAabp/@qwark.sigxcpu.org>

Hi,
On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;


Tested on the Librem 5 (imx8mq) with it's rather picky panel:

Tested-by: Guido G?nther <agx at sigxcpu.org>

Cheers
 -- Guido


>  
> -- 
> 2.25.1
> 


From catalin.marinas at arm.com  Wed Jan 19 03:49:58 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 19 Jan 2022 11:49:58 +0000
Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
In-Reply-To: <207f800d1a67427a9771ffb06086365b@huawei.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
 <Yeazd1lLuYm4k3lH@arm.com>
 <207f800d1a67427a9771ffb06086365b@huawei.com>
Message-ID: <Yef65ng6pQK5yZDa@arm.com>

On Wed, Jan 19, 2022 at 09:23:31AM +0000, Shameerali Kolothum Thodi wrote:
> > On Mon, Nov 22, 2021 at 12:18:40PM +0000, Shameer Kolothum wrote:
> > > ?-TLA+ model. Modified the asidalloc model to incorporate the new
> > >   VMID algo. The main differences are,
> > > ? -flush_tlb_all() instead of local_tlb_flush_all() on rollover.
> > > ? -Introduced INVALID_VMID and vCPU Sched Out logic.
> > > ? -No CnP (Removed UniqueASIDAllCPUs & UniqueASIDActiveTask invariants).
> > > ? -Removed ?UniqueVMIDPerCPU invariant for now as it looks like
> > >    because of the speculative fetching with flush_tlb_all() there
> > >    is a small window where this gets triggered. If I change the
> > >    logic back to local_flush_tlb_all(), UniqueVMIDPerCPU seems to
> > >    be fine. With my limited knowledge on TLA+ model, it is not
> > >    clear to me whether this is a problem with the above logic
> > >    or the VMID model implementation. Really appreciate any help
> > >    with the model.
> > >    The initial VMID TLA+ model is here,
> > >    https://github.com/shamiali2008/kernel-tla/tree/private-vmidalloc-v1
> > 
> > I only had a brief look at the TLA+ model and I don't understand why you
> > have a separate 'shed_out' process. It would run in parallel with the
> > 'sched' but AFAICT you can't really schedule a guest out while you are
> > in the middle of scheduling it in. I'd rather use the same 'sched'
> > process and either schedule in an inactive task or schedule out an
> > active one for a given CPU.
> > 
> > Also active_vmids[] for example is defined on the CPUS domain but you
> > call vcpu_sched_out() from a process that's not in the CPUS domain but
> > the SCHED_OUT one.
> 
> Many thanks for taking a look. My bad!. The 'sched_out' would indeed run in parallel
> and defeat the purpose. I must say I was really confused by the TLA+ syntax and
> is still not very confident about it.

Yeah, it can be confusing. If you have time, you could give CBMC a try
and the 'spec' would be pretty close to your C version. Each CPU would
be modelled as a thread with an extra thread that simulates the
speculative TLB look-ups for all CPUS together with the asserts for the
invariants. The spinlocks would be pthread_mutexes.

> Based on the above suggestion, I have modified it as below,
> 
> \* vCPU is scheduled out by KVM
> macro vcpu_sched_out() {
>         active_kvm[self].task := 0;
>         active_vmids[self] := INVALID_VMID;
> }

Could you call cpu_switch_kvm(0, INVALID_VMID) instead? You could do
this directly below and avoid another macro. Well, whatever you find
clearer.

What confuses me is that your INVALID_VMID looks like a valid one: vmid
0, generation 1. Do you ensure that you never allocate VMID 0?

> \* About to run a Guest VM
> process (sched \in CPUS)
> {
> sched_loop:
>         while (TRUE) {
>                 with (t \in TASKS) {
>                         if (t # ActiveTask(self))
>                                 call kvm_arm_vmid_update(t);
>                         else
>                                 vcpu_sched_out();
>                 }
>         }
> }

Yes, that's what I meant.

> > The corresponding
> > UniqueASIDPerCPU meant that for any two TLB entries on a single CPU, if
> > they correspond to different tasks (pgd), they should have different
> > ASIDs. That's a strong requirement, otherwise we end up with the wrong
> > translation.
> 
> Yes, I understand that it is a strong requirement. Also, I thought this is something
> that will trigger easily with the test setup I had with the real hardware. But testing
> stayed on for days, so I was not sure it is a problem with the TLA+ implementation
> or not.  

Well, you'd have to check the TLA+ state trace and see how it got
there, whether the last state would be a valid one. It's either
something missing in the spec that the hardware enforces or the
algorithm is wrong and just hard to hit in practice. If this condition
is violated in hardware for a very brief period, e.g. due to some TLBI,
you'd not notice an issue under normal circumstances. But it's still
incorrect.

> > Why did you remove the CnP? Do we have this disabled for KVM guests?
> 
> I removed CnP related Invariants to simplify things for the first version. Also not sure
> what specific changes we need to do for CnP here. Do we still need that switching to 
> global pg_dir to prevent any speculative reading? I didn't see that being done in KVM 
> anywhere at the moment. Maybe I am missing something.

It make sense to ignore CnP for now. Maybe KVM doesn't even bother and
sets VTTBR_EL2.CnP to 0 (I haven't checked).

> On a side note, In my setup, the CnP=TRUE case for asidalloc.tla now fails with,
> "Error: Invariant TLBEmptyInvalPTE is violated.". Please check.

This was added later as part of try-to-unmap and I only checked this
with CnP = FALSE. I'll need to look into, it's possible that
flush_tlb_all() doesn't take into account that the pte is unmapped (as
cpu_switch_mm() does). I'll add a separate thread for speculative TLB
loads, it's easier to have them in one place. Thanks.

-- 
Catalin


From angelogioacchino.delregno at collabora.com  Wed Jan 19 03:50:43 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Wed, 19 Jan 2022 12:50:43 +0100
Subject: [PATCH v5, 15/15] media: mtk-vcodec: support stateless VP9
 decoding
In-Reply-To: <275affff-12d9-4659-e900-aa9c306e6701@collabora.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
 <20220117094001.20049-16-yunfei.dong@mediatek.com>
 <275affff-12d9-4659-e900-aa9c306e6701@collabora.com>
Message-ID: <eaf4f649-89fc-77ff-dab1-2c837cd8c877@collabora.com>

Il 19/01/22 12:28, AngeloGioacchino Del Regno ha scritto:
> Il 17/01/22 10:40, Yunfei Dong ha scritto:
>> Add support for VP9 decoding using the stateless API,
>> as supported by MT8192. And the drivers is lat and core architecture.
>>
>> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
>> Signed-off-by: George Sun <george.sun at mediatek.com>
>> ---
>> ? drivers/media/platform/mtk-vcodec/Makefile??? |??? 1 +
>> ? .../mtk-vcodec/mtk_vcodec_dec_stateless.c???? |?? 26 +-
>> ? .../platform/mtk-vcodec/mtk_vcodec_drv.h????? |??? 1 +
>> ? .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c???? | 1973 +++++++++++++++++
>> ? .../media/platform/mtk-vcodec/vdec_drv_if.c?? |??? 4 +
>> ? .../media/platform/mtk-vcodec/vdec_drv_if.h?? |??? 1 +
>> ? 6 files changed, 2003 insertions(+), 3 deletions(-)
>> ? create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
>>
> 
> Hello Yunfei,
> this driver is based on an older version of the VP9 stateless decoder uAPI,
> hence this is not applicable upstream.
> 
> The latest linux-next tag (as of today) already contains the new and
> accepted code; can you please rebase over that one?
> 
> Thanks,
> Angelo

While finishing a rebase, I had time to do a fast port of this patch; in hopes
to spare you some time, I'm giving you my (fast) take at this.

Feel free to use it as you wish!


 From 5f329ad271c94bf82d2dd12075372159466c28f9 Mon Sep 17 00:00:00 2001

From: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Date: Wed, 19 Jan 2022 12:45:18 +0100

Subject: [PATCH] media: mtk-vcodec: Port VP9 stateless driver to upstream uAPI



This driver was written based on an old VP9 uAPI, but that code

changed over time: port this over the newest, and upstream accepted,

VP9 uAPI.



Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

---

  .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  2 +-

  .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 29 +++++++------------

  2 files changed, 12 insertions(+), 19 deletions(-)



diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c 
b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

index 26fd97d867e9..7f4baa39bf6c 100644

--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c

@@ -94,7 +94,7 @@ static const struct mtk_stateless_control 
mtk_stateless_controls[] = {

  	},

  	{

  		.cfg = {

-			.id = V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS,

+			.id = V4L2_CID_STATELESS_VP9_FRAME,

  			},

  		.codec_type = V4L2_PIX_FMT_VP9_FRAME,

  	},

diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c 
b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

index 92cd39f00840..8caf4f28db29 100644

--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

@@ -711,7 +711,7 @@ static int vdec_vp9_slice_setup_lat_from_src_buf(struct 
vdec_vp9_slice_instance



  static void vdec_vp9_slice_setup_hdr(struct vdec_vp9_slice_instance *instance,

  				     struct vdec_vp9_slice_uncompressed_header *uh,

-				     struct v4l2_ctrl_vp9_frame_decode_params *hdr)

+				     struct v4l2_ctrl_vp9_frame *hdr)

  {

  	int i;



@@ -749,13 +749,13 @@ static void vdec_vp9_slice_setup_hdr(struct 
vdec_vp9_slice_instance *instance,

  	 * - LAST_FRAME = 1,

  	 * - GOLDEN_FRAME = 2,

  	 * - ALTREF_FRAME = 3,

-	 * ref_frame_sign_biases[INTRA_FRAME] is always 0

+	 * ref_frame_sign_bias[INTRA_FRAME] is always 0

  	 * and VDA only passes another 3 directions

  	 */

  	uh->ref_frame_sign_bias[0] = 0;

  	for (i = 0; i < 3; i++)

  		uh->ref_frame_sign_bias[i + 1] =

-			!!(hdr->ref_frame_sign_biases & (1 << i));

+			!!(hdr->ref_frame_sign_bias & (1 << i));

  	uh->allow_high_precision_mv = HDR_FLAG(ALLOW_HIGH_PREC_MV);

  	uh->interpolation_filter = hdr->interpolation_filter;

  	uh->refresh_frame_context = HDR_FLAG(REFRESH_FRAME_CTX);

@@ -772,7 +772,7 @@ static void vdec_vp9_slice_setup_hdr(struct 
vdec_vp9_slice_instance *instance,



  static void vdec_vp9_slice_setup_frame_ctx(struct vdec_vp9_slice_instance *instance,

  					   struct vdec_vp9_slice_uncompressed_header *uh,

-					   struct v4l2_ctrl_vp9_frame_decode_params *hdr)

+					   struct v4l2_ctrl_vp9_frame *hdr)

  {

  	int error_resilient_mode;

  	int reset_frame_context;

@@ -857,7 +857,7 @@ static void vdec_vp9_slice_setup_segmentation(struct 
vdec_vp9_slice_uncompressed

  }



  static int vdec_vp9_slice_setup_tile(struct vdec_vp9_slice_vsi *vsi,

-				     struct v4l2_ctrl_vp9_frame_decode_params *hdr)

+				     struct v4l2_ctrl_vp9_frame *hdr)

  {

  	unsigned int rows_log2;

  	unsigned int cols_log2;

@@ -909,19 +909,10 @@ static void vdec_vp9_slice_setup_state(struct 
vdec_vp9_slice_vsi *vsi)

  	memset(&vsi->state, 0, sizeof(vsi->state));

  }



-static void vdec_vp9_slice_setup_ref_idx(struct vdec_vp9_slice_pfc *pfc,

-					 struct v4l2_ctrl_vp9_frame_decode_params *hdr)

-{

-	int i;

-

-	for (i = 0; i < 3; i++)

-		pfc->ref_idx[i] = hdr->refs[i];

-}

-

  static int vdec_vp9_slice_setup_pfc(struct vdec_vp9_slice_instance *instance,

  				    struct vdec_vp9_slice_pfc *pfc)

  {

-	struct v4l2_ctrl_vp9_frame_decode_params *hdr;

+	struct v4l2_ctrl_vp9_frame *hdr;

  	struct vdec_vp9_slice_uncompressed_header *uh;

  	struct v4l2_ctrl *hdr_ctrl;

  	struct vdec_vp9_slice_vsi *vsi;

@@ -929,7 +920,7 @@ static int vdec_vp9_slice_setup_pfc(struct 
vdec_vp9_slice_instance *instance,



  	/* frame header */

  	hdr_ctrl = v4l2_ctrl_find(&instance->ctx->ctrl_hdl,

-				  V4L2_CID_MPEG_VIDEO_VP9_FRAME_DECODE_PARAMS);

+				  V4L2_CID_STATELESS_VP9_FRAME);

  	if (!hdr_ctrl || !hdr_ctrl->p_cur.p)

  		return -EINVAL;



@@ -949,7 +940,9 @@ static int vdec_vp9_slice_setup_pfc(struct 
vdec_vp9_slice_instance *instance,

  	vdec_vp9_slice_setup_state(vsi);



  	/* core stage needs buffer index to get ref y/c ... */

-	vdec_vp9_slice_setup_ref_idx(pfc, hdr);

+	pfc->ref_idx[0] = hdr->last_frame_ts;

+	pfc->ref_idx[1] = hdr->golden_frame_ts;

+	pfc->ref_idx[2] = hdr->alt_frame_ts;



  	pfc->seq = instance->seq;

  	instance->seq++;

@@ -1789,7 +1782,7 @@ static void vdec_vp9_slice_get_crop_info(struct 
vdec_vp9_slice_instance *instanc

  			 cr->left, cr->top, cr->width, cr->height);

  }



-static int vdec_vp9_slice_get_param(void *h_vdec, vdec_get_param_type type, void *out)

+static int vdec_vp9_slice_get_param(void *h_vdec, enum vdec_get_param_type type, 
void *out)

  {

  	struct vdec_vp9_slice_instance *instance = h_vdec;



-- 

2.33.1



From jszhang at kernel.org  Wed Jan 19 03:44:35 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Wed, 19 Jan 2022 19:44:35 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <20220119093322.GC4977@MiWiFi-R3L-srv>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv> <YebK70Sx4w8zLfj/@xhacker>
 <20220119080859.GB4977@MiWiFi-R3L-srv>
 <CA+zEjCvqYAWaWW9hVbHqYm_GbV-BaiOM4c77WHnxDNh+SRDUuw@mail.gmail.com>
 <20220119093322.GC4977@MiWiFi-R3L-srv>
Message-ID: <Yef5oz/XiZT/Pxfy@xhacker>

On Wed, Jan 19, 2022 at 05:33:22PM +0800, Baoquan He wrote:
> On 01/19/22 at 09:52am, Alexandre Ghiti wrote:
> > Hi Baoquan,
> > 
> > On Wed, Jan 19, 2022 at 9:11 AM Baoquan He <bhe at redhat.com> wrote:
> > >
> > > On 01/18/22 at 10:13pm, Jisheng Zhang wrote:
> > > > On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> > > > > Hi Jisheng,
> > > >
> > > > Hi Baoquan,
> > > >
> > > > >
> > > > > On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > > > > > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > > > > > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > > > > > and increase compile coverage.
> > > > >
> > > > > I go through this patchset, You mention the benefits it brings are
> > > > > 1) simplity the code;
> > > > > 2) increase compile coverage;
> > > > >
> > > > > For benefit 1), it mainly removes the dummy function in x86, arm and
> > > > > arm64, right?
> > > >
> > > > Another benefit: remove those #ifdef #else #endif usage. Recently, I
> > > > fixed a bug due to lots of "#ifdefs":
> > > > http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html
> > >
> > > Glad to know the fix. While, sometime the ifdeffery is necessary. I am
> > > sorry about the one in riscv and you have fixed, it's truly a bug . But,
> > > the increasing compile coverage at below you tried to make, it may cause
> > > issue. Please see below my comment.
> > >
> > > >
> > > > >
> > > > > For benefit 2), increasing compile coverage, could you tell more how it
> > > > > achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> > > > > purpose? Please forgive my poor compiling knowledge.
> > > >
> > > > Just my humble opinion, let's compare the code::
> > > >
> > > > #ifdef CONFIG_KEXEC_CORE
> > > >
> > > > code block A;
> > > >
> > > > #endif
> > > >
> > > > If KEXEC_CORE is disabled, code block A won't be compiled at all, the
> > > > preprocessor will remove code block A;
> > > >
> > > > If we convert the code to:
> > > >
> > > > if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
> > > >       code block A;
> > > > }
> > > >
> > > > Even if KEXEC_CORE is disabled, code block A is still compiled.
> > >
> > > This is what I am worried about. Before, if CONFIG_KEXEC_CORE is
> > > unset, those relevant codes are not compiled in. I can't see what
> > > benefit is brought in if compiled in the unneeded code block. Do I miss
> > > anything?
> > >
> > 
> > This is explained in Documentation/process/coding-style.rst "21)
> > Conditional Compilation".
> 
> Thanks for the pointer, Alex.
> 
> I read that part, while my confusion isn't gone. With the current code,
> CONFIG_KEXEC_CORE is set,
>   - reserve_crashkernel_low() and reserve_crashkernel() compiled in.

Although the code block will be compiled, but the code block will be
optimized out.

> CONFIG_KEXEC_CORE is unset,
>   - reserve_crashkernel_low() and reserve_crashkernel() compiled out. 
> 
> After this patch applied, does it have the same effect as the old code?

I compared the .o, and can confirm they acchieve the same effect.

> 
> arch/x86/kernel/setup.c:
> 
> before
> ======
> #ifdef CONFIG_KEXEC_CORE
> static int __init reserve_crashkernel_low(void)
> {
> 	......
> }
> static void __init reserve_crashkernel(void)
> {
> 	......
> }
> #else
> static void __init reserve_crashkernel(void)
> {
> }
> #endif
> 
> after
> =======
> static int __init reserve_crashkernel_low(void)
> {
> 	......
> }
> static void __init reserve_crashkernel(void)
> {
> 	......
> 	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
>                 return;
> 	......
> }
> 


From m.tretter at pengutronix.de  Wed Jan 19 03:54:34 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 19 Jan 2022 12:54:34 +0100
Subject: [PATCH v2] clk: zynqmp: replace warn_once with pr_debug for failed
 clock ops
Message-ID: <20220119115434.2042017-1-m.tretter@pengutronix.de>

The warning that a clock operation failed is only printed once. However,
the function is called for various different clocks. The limit hides the
warnings if different clocks are affected by the failures.

The clock ops might fail if the firmware that handles the clocks is
misconfigured. Therefore, replace the pr_warn_once with pr_debug to
allow the user to see all errors if necessary. By default, hide the
error messages and let drivers handle the errors.

Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
This is v2 of the patch to improve the error messages of the ZynqMP
clock driver [0].

[0] https://lore.kernel.org/all/20220112141229.700708-1-m.tretter at pengutronix.de/

Changelog:

v2:

- Update commit message
- Use pr_debug instead of pr_warn
---
 drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
 drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
 drivers/clk/zynqmp/divider.c         | 12 +++++------
 drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
 4 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
index 565ed67a0430..b89e55737198 100644
--- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
@@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_enable(clk_id);
 
 	if (ret)
-		pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock enable failed for %s (id %d), ret = %d\n",
+			 __func__, clk_name, clk_id, ret);
 
 	return ret;
 }
@@ -61,8 +61,8 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_disable(clk_id);
 
 	if (ret)
-		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock disable failed for %s (id %d), ret = %d\n",
+			 __func__, clk_name, clk_id, ret);
 }
 
 /**
@@ -80,8 +80,8 @@ static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_getstate(clk_id, &state);
 	if (ret) {
-		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock get state failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 		return -EIO;
 	}
 
diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
index 17afce594f28..60359333f26d 100644
--- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
+++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
@@ -51,8 +51,8 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
 	ret = zynqmp_pm_clock_getparent(clk_id, &val);
 
 	if (ret) {
-		pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() getparent failed for clock: %s, ret = %d\n",
+			 __func__, clk_name, ret);
 		/*
 		 * clk_core_get_parent_by_index() takes num_parents as incorrect
 		 * index which is exactly what I want to return here
@@ -80,8 +80,8 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
 	ret = zynqmp_pm_clock_setparent(clk_id, index);
 
 	if (ret)
-		pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() set parent failed for clock: %s, ret = %d\n",
+			 __func__, clk_name, ret);
 
 	return ret;
 }
diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
index cb49281f9cf9..422ea79907dd 100644
--- a/drivers/clk/zynqmp/divider.c
+++ b/drivers/clk/zynqmp/divider.c
@@ -89,8 +89,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
 	ret = zynqmp_pm_clock_getdivider(clk_id, &div);
 
 	if (ret)
-		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() get divider failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 
 	if (div_type == TYPE_DIV1)
 		value = div & 0xFFFF;
@@ -177,8 +177,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
 		ret = zynqmp_pm_clock_getdivider(clk_id, &bestdiv);
 
 		if (ret)
-			pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-				     __func__, clk_name, ret);
+			pr_debug("%s() get divider failed for %s, ret = %d\n",
+				 __func__, clk_name, ret);
 		if (div_type == TYPE_DIV1)
 			bestdiv = bestdiv & 0xFFFF;
 		else
@@ -244,8 +244,8 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
 	ret = zynqmp_pm_clock_setdivider(clk_id, div);
 
 	if (ret)
-		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() set divider failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 
 	return ret;
 }
diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
index 036e4ff64a2f..91a6b4cc910e 100644
--- a/drivers/clk/zynqmp/pll.c
+++ b/drivers/clk/zynqmp/pll.c
@@ -56,8 +56,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
 
 	ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
 	if (ret) {
-		pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() PLL get frac mode failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 		return PLL_MODE_ERROR;
 	}
 
@@ -84,8 +84,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
 
 	ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
 	if (ret)
-		pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() PLL set frac mode failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 	else
 		clk->set_pll_mode = true;
 }
@@ -145,8 +145,8 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
 
 	ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
 	if (ret) {
-		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() get divider failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 		return 0ul;
 	}
 
@@ -200,8 +200,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 			WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
 			     clk_name);
 		else if (ret)
-			pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-				     __func__, clk_name, ret);
+			pr_debug("%s() set divider failed for %s, ret = %d\n",
+				 __func__, clk_name, ret);
 		zynqmp_pm_set_pll_frac_data(clk_id, f);
 
 		return rate + frac;
@@ -211,8 +211,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
 	ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
 	if (ret)
-		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() set divider failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 
 	return parent_rate * fbdiv;
 }
@@ -233,8 +233,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_getstate(clk_id, &state);
 	if (ret) {
-		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock get state failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 		return -EIO;
 	}
 
@@ -265,8 +265,8 @@ static int zynqmp_pll_enable(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_enable(clk_id);
 	if (ret)
-		pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock enable failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 
 	return ret;
 }
@@ -287,8 +287,8 @@ static void zynqmp_pll_disable(struct clk_hw *hw)
 
 	ret = zynqmp_pm_clock_disable(clk_id);
 	if (ret)
-		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
-			     __func__, clk_name, ret);
+		pr_debug("%s() clock disable failed for %s, ret = %d\n",
+			 __func__, clk_name, ret);
 }
 
 static const struct clk_ops zynqmp_pll_ops = {
-- 
2.30.2



From mark.rutland at arm.com  Wed Jan 19 04:02:38 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 12:02:38 +0000
Subject: [boot-wrapper PATCH v2 9/9] avoid dtc warnings on re-compiling DTB
In-Reply-To: <20220114120931.36488dfe@donnerap.cambridge.arm.com>
References: <20211222181607.1203191-1-andre.przywara@arm.com>
 <20211222181607.1203191-10-andre.przywara@arm.com>
 <706471d8-a0fd-35fb-4fa0-380bfb1b78e7@arm.com>
 <20220113195051.7100b066@slackpad.fritz.box>
 <9eb63797-b313-a39a-6b9c-0f8ac447b85a@arm.com>
 <YeFUJ+dw22Kmhwjs@FVFF77S0Q05N>
 <20220114120931.36488dfe@donnerap.cambridge.arm.com>
Message-ID: <Yef93qizlD6l/org@FVFF77S0Q05N>

On Fri, Jan 14, 2022 at 12:09:31PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:44:55 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> > On Fri, Jan 14, 2022 at 08:35:06AM +0000, Vladimir Murzin wrote:
> > > Hi Andre,
> > > 
> > > On 1/13/22 7:50 PM, Andre Przywara wrote:  
> > > > On Thu, 13 Jan 2022 18:42:50 +0000
> > > > Vladimir Murzin <vladimir.murzin at arm.com> wrote:
> > > > 
> > > > Hi Vladimir,
> > > >   
> > > >> On 12/22/21 6:16 PM, Andre Przywara wrote:  
> > > >>> When we add the PSCI nodes to the provided DTB, we use dtc to de-compile
> > > >>> the blob first, then re-compile it with our nodes and properties added.
> > > >>>
> > > >>> In our input DTB the proper phandle references have already been lost,
> > > >>> all we see in the DTB is phandle properties in the target node, and some
> > > >>> numbers in the clocks and gpios properties:
> > > >>> ===========
> > > >>> 	clk24mhz {
> > > >>> 		compatible = "fixed-clock";
> > > >>> 		#clock-cells = <0x00>;
> > > >>> 		clock-frequency = <0x16e3600>;
> > > >>> 		clock-output-names = "v2m:clk24mhz";    
> > > >>> ->		phandle = <0x05>;    
> > > >>> 	};
> > > >>> 	...
> > > >>> 	serial at 90000 {
> > > >>> 		compatible = "arm,pl011", "arm,primecell";
> > > >>> 		reg = <0x90000 0x1000>;
> > > >>> 		interrupts = <0x05>;    
> > > >>> ->		clocks = <0x05 0x05>;    
> > > >>> 		clock-names = "uartclk", "apb_pclk";
> > > >>> 	};
> > > >>> ===========
> > > >>> dtc warns that those numbers might be wrong:
> > > >>> =========
> > > >>> <stdin>:177.6-27: Warning (clocks_property):
> > > >>>  /bus at 8000000/motherboard-bus at 8000000/iofpga-bus at 300000000/serial at 90000:
> > > >>>    clocks: cell 0 is not a phandle reference
> > > >>> ....
> > > >>> =========
> > > >>> The proper solution would be to use references (&v2m_clk24mhz) instead,
> > > >>> as there are in the source .dts file, but we don't have that information
> > > >>> anymore, and cannot easily recover it.
> > > >>>
> > > >>> To avoid the lengthy list of warnings, just drop those checks from the
> > > >>> dtc compilation run. This disables more checks than we want or need, but
> > > >>> we somewhat trust in the original DTB to be sane, so that should be
> > > >>> fine.
> > > >>>
> > > >>> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > > >>> ---
> > > >>>  Makefile.am | 2 +-
> > > >>>  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >>>
> > > >>> diff --git a/Makefile.am b/Makefile.am
> > > >>> index 3d8128f..430b4a9 100644
> > > >>> --- a/Makefile.am
> > > >>> +++ b/Makefile.am
> > > >>> @@ -160,7 +160,7 @@ model.lds: $(LD_SCRIPT) Makefile
> > > >>>  	$(CPP) $(CPPFLAGS) -ansi -DPHYS_OFFSET=$(PHYS_OFFSET) -DMBOX_OFFSET=$(MBOX_OFFSET) -DKERNEL_OFFSET=$(KERNEL_OFFSET) -DFDT_OFFSET=$(FDT_OFFSET) -DFS_OFFSET=$(FS_OFFSET) $(XEN) -DXEN_OFFSET=$(XEN_OFFSET) -DKERNEL=$(KERNEL_IMAGE) -DFILESYSTEM=$(FILESYSTEM) -DTEXT_LIMIT=$(TEXT_LIMIT) -P -C -o $@ $<
> > > >>>  
> > > >>>  fdt.dtb: $(KERNEL_DTB) Makefile
> > > >>> -	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -
> > > >>> +	( $(DTC) -O dts -I dtb $(KERNEL_DTB) ; echo "/ { $(CHOSEN_NODE) $(PSCI_NODE) }; $(CPU_NODES)" ) | $(DTC) -O dtb -o $@ -Wno-clocks_property -Wno-gpios_property -
> > > >>>  
> > > >>>  # The filesystem archive might not exist if INITRD is not being used
> > > >>>  .PHONY: all clean $(FILESYSTEM)
> > > >>>     
> > > >>
> > > >> dtc 1.4.1 complains  
> > > > 
> > > > Which distro ships this version? (distrowatch doesn't list dtc)
> > > > 
> > > > tag v1.4.1
> > > > Tagger: David Gibson <david at gibson.dropbear.id.au>
> > > > Date:   Wed Nov 12 14:31:44 2014 +1100
> > > > 
> > > > Any chance it's just you and you can update this? It looks like the
> > > > first version to support it is 1.4.5, as shipped for instance with
> > > > Ubuntu 18.04.  
> > > 
> > > It is shipped as LSF module. I can try to ask for an update, but I thought
> > > that other people may run into it as well...
> > >   
> > > >   
> > > >> FATAL ERROR: Unrecognized check name "clocks_property"  
> > > > 
> > > > Sigh, thanks for the heads up. I don't know if we want to blow up the
> > > > Makefile with a feature test?  
> > > 
> > > I dunno, TBH. It look like warning used to be less evil than error...  
> 
> Yeah, that's what I meant: Either revert it or extend the Makefile.
> 
> > I agree.
> > 
> > My preference would be to revert that for now, and consider the problem afresh.
> > Andre, are you ok with that?
> 
> Sure, I don't want to break the build for people.
> I think kvmtool has some lightweight feature tests in its Makefile, I can
> try to steal some of it, and see how evil it looks. Or wait for half a
> year to see those older dtcs flushed out and try it again ;-)

FWIW, the feature test idea doesn't sound bad, though I beleive that for
licensing reasons we cannot take that from kvmtool and would have to grow our
own.

Another option would be to extend FDT.pm to do the manipulation and drop the
dtc dependency entirely. That would require more work, but might make it easier
to do other DTB manipulation in future.

For now I've applied a revert, with a link to this thread and some wording that
we can reconsider this in future.

Thanks,
Mark.


From Jason at zx2c4.com  Wed Jan 19 04:14:56 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 13:14:56 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
 <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
Message-ID: <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>

The below kludge of a patch fixes the issue. Still unclear whether we
should go with something like this or get clang fixed or what.

diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
index 17c1c3bfe2f5..be8cde5f1719 100644
--- a/arch/arm/crypto/blake2s-shash.c
+++ b/arch/arm/crypto/blake2s-shash.c
@@ -13,12 +13,12 @@
 static int crypto_blake2s_update_arm(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen);
 }

 static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out);
 }

 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
index f9e2fecdb761..c81ffedb4865 100644
--- a/arch/x86/crypto/blake2s-shash.c
+++ b/arch/x86/crypto/blake2s-shash.c
@@ -18,12 +18,12 @@
 static int crypto_blake2s_update_x86(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen);
 }

 static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out);
 }

 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
index 72fe480f9bd6..050874588a84 100644
--- a/crypto/blake2s_generic.c
+++ b/crypto/blake2s_generic.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason at zx2c4.com>. All
Rights Reserved.
  */

+#define FORCE_BLAKE2S_GENERIC
 #include <crypto/internal/blake2s.h>
 #include <crypto/internal/hash.h>

@@ -15,12 +16,12 @@
 static int crypto_blake2s_update_generic(struct shash_desc *desc,
 					 const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
+	return crypto_blake2s_update(desc, in, inlen);
 }

 static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress_generic);
+	return crypto_blake2s_final(desc, out);
 }

 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/include/crypto/internal/blake2s.h
b/include/crypto/internal/blake2s.h
index d39cfa0d333e..fec7eead93fc 100644
--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -24,14 +24,14 @@ static inline void blake2s_set_lastblock(struct
blake2s_state *state)
 	state->f[0] = -1;
 }

-typedef void (*blake2s_compress_t)(struct blake2s_state *state,
-				   const u8 *block, size_t nblocks, u32 inc);
-
 /* Helper functions for BLAKE2s shared by the library and shash APIs */

+#ifdef FORCE_BLAKE2S_GENERIC
+#define blake2s_compress blake2s_compress_generic
+#endif
+
 static inline void __blake2s_update(struct blake2s_state *state,
-				    const u8 *in, size_t inlen,
-				    blake2s_compress_t compress)
+				    const u8 *in, size_t inlen)
 {
 	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;

@@ -39,7 +39,7 @@ static inline void __blake2s_update(struct
blake2s_state *state,
 		return;
 	if (inlen > fill) {
 		memcpy(state->buf + state->buflen, in, fill);
-		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+		blake2s_compress(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
 		state->buflen = 0;
 		in += fill;
 		inlen -= fill;
@@ -47,7 +47,7 @@ static inline void __blake2s_update(struct
blake2s_state *state,
 	if (inlen > BLAKE2S_BLOCK_SIZE) {
 		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
 		/* Hash one less (full) block than strictly possible */
-		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+		blake2s_compress(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
 		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 	}
@@ -55,13 +55,12 @@ static inline void __blake2s_update(struct
blake2s_state *state,
 	state->buflen += inlen;
 }

-static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
-				   blake2s_compress_t compress)
+static inline void __blake2s_final(struct blake2s_state *state, u8 *out)
 {
 	blake2s_set_lastblock(state);
 	memset(state->buf + state->buflen, 0,
 	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-	(*compress)(state, state->buf, 1, state->buflen);
+	blake2s_compress(state, state->buf, 1, state->buflen);
 	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
 	memcpy(out, state->h, state->outlen);
 }
@@ -98,21 +97,19 @@ static inline int crypto_blake2s_init(struct
shash_desc *desc)
 }

 static inline int crypto_blake2s_update(struct shash_desc *desc,
-					const u8 *in, unsigned int inlen,
-					blake2s_compress_t compress)
+					const u8 *in, unsigned int inlen)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);

-	__blake2s_update(state, in, inlen, compress);
+	__blake2s_update(state, in, inlen);
 	return 0;
 }

-static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
-				       blake2s_compress_t compress)
+static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);

-	__blake2s_final(state, out, compress);
+	__blake2s_final(state, out);
 	return 0;
 }

diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 9364f79937b8..a13f01ff53a7 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -18,14 +18,14 @@

 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 {
-	__blake2s_update(state, in, inlen, blake2s_compress);
+	__blake2s_update(state, in, inlen);
 }
 EXPORT_SYMBOL(blake2s_update);

 void blake2s_final(struct blake2s_state *state, u8 *out)
 {
 	WARN_ON(IS_ENABLED(DEBUG) && !out);
-	__blake2s_final(state, out, blake2s_compress);
+	__blake2s_final(state, out);
 	memzero_explicit(state, sizeof(*state));
 }
 EXPORT_SYMBOL(blake2s_final);


From ardb at kernel.org  Wed Jan 19 04:18:40 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 19 Jan 2022 13:18:40 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
 <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
 <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>
Message-ID: <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>

On Wed, 19 Jan 2022 at 13:15, Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> The below kludge of a patch fixes the issue. Still unclear whether we
> should go with something like this or get clang fixed or what.
>
> diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
> index 17c1c3bfe2f5..be8cde5f1719 100644
> --- a/arch/arm/crypto/blake2s-shash.c
> +++ b/arch/arm/crypto/blake2s-shash.c
> @@ -13,12 +13,12 @@
>  static int crypto_blake2s_update_arm(struct shash_desc *desc,
>                                      const u8 *in, unsigned int inlen)
>  {
> -       return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +       return crypto_blake2s_update(desc, in, inlen);
>  }
>
>  static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
>  {
> -       return crypto_blake2s_final(desc, out, blake2s_compress);
> +       return crypto_blake2s_final(desc, out);
>  }
>
>  #define BLAKE2S_ALG(name, driver_name, digest_size)                    \
> diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
> index f9e2fecdb761..c81ffedb4865 100644
> --- a/arch/x86/crypto/blake2s-shash.c
> +++ b/arch/x86/crypto/blake2s-shash.c
> @@ -18,12 +18,12 @@
>  static int crypto_blake2s_update_x86(struct shash_desc *desc,
>                                      const u8 *in, unsigned int inlen)
>  {
> -       return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +       return crypto_blake2s_update(desc, in, inlen);
>  }
>
>  static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
>  {
> -       return crypto_blake2s_final(desc, out, blake2s_compress);
> +       return crypto_blake2s_final(desc, out);
>  }
>
>  #define BLAKE2S_ALG(name, driver_name, digest_size)                    \
> diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
> index 72fe480f9bd6..050874588a84 100644
> --- a/crypto/blake2s_generic.c
> +++ b/crypto/blake2s_generic.c
> @@ -5,6 +5,7 @@
>   * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason at zx2c4.com>. All
> Rights Reserved.
>   */
>
> +#define FORCE_BLAKE2S_GENERIC
>  #include <crypto/internal/blake2s.h>
>  #include <crypto/internal/hash.h>
>

I'd prefer it if we could avoid magic #define's like this. We could
fix it up locally to crypto/internal/blake2s.h just by doing something
like the below.

diff --git a/include/crypto/internal/blake2s.h
b/include/crypto/internal/blake2s.h
index d39cfa0d333e..9e52c07c54cc 100644
--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -39,7 +39,11 @@ static inline void __blake2s_update(struct
blake2s_state *state,
                return;
        if (inlen > fill) {
                memcpy(state->buf + state->buflen, in, fill);
-               (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+               if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
+                       (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+               else
+                       blake2s_compress_generic(state, state->buf, 1,
+                                                BLAKE2S_BLOCK_SIZE);
                state->buflen = 0;
                in += fill;
                inlen -= fill;
@@ -47,7 +51,11 @@ static inline void __blake2s_update(struct
blake2s_state *state,
        if (inlen > BLAKE2S_BLOCK_SIZE) {
                const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
                /* Hash one less (full) block than strictly possible */
-               (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+               if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
+                       (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+               else
+                       blake2s_compress_generic(state, in, nblocks - 1,
+                                                BLAKE2S_BLOCK_SIZE);
                in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
                inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
        }
@@ -61,7 +69,10 @@ static inline void __blake2s_final(struct
blake2s_state *state, u8 *out,
        blake2s_set_lastblock(state);
        memset(state->buf + state->buflen, 0,
               BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-       (*compress)(state, state->buf, 1, state->buflen);
+       if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
+               (*compress)(state, state->buf, 1, state->buflen);
+       else
+               blake2s_compress_generic(state, state->buf, 1, state->buflen);
        cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));


From cristian.marussi at arm.com  Wed Jan 19 04:23:38 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Wed, 19 Jan 2022 12:23:38 +0000
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
Message-ID: <20220119122338.GE6113@e120937-lin>

On Tue, Jan 18, 2022 at 03:21:03PM +0100, Peter Hilber wrote:
> On 21.12.21 15:00, Cristian Marussi wrote:
> > Add support for .mark_txdone and .poll_done transport operations to SCMI
> > VirtIO transport as pre-requisites to enable atomic operations.
> > 
> > Add a Kernel configuration option to enable SCMI VirtIO transport polling
> > and atomic mode for selected SCMI transactions while leaving it default
> > disabled.
> > 
> 
> Hi Cristian,
> 
> thanks for the update. I have some more remarks inline below.
> 

Hi Peter,

thanks for your review, much appreciated, please see my replies online.

> My impression is that the virtio core does not expose helper functions suitable
> to busy-poll for used buffers. But changing this might not be difficult. Maybe
> more_used() from virtio_ring.c could be exposed via a wrapper?
> 

While I definitely agree that the virtio core support for polling is far from
ideal, some support is provided and my point was at first to try implement SCMI
virtio polling leveraging what we have now in the core and see if it was attainable
(indeed I tried early in this series to avoid as a whole to have to support polling
at the SCMI transport layer to attain SCMI cmds atomicity..but that was an ill
attempt that led nowhere good...)

Btw, I was planning to post a new series next week (after merge-windows) with some
fixes I did already, at this point I'll include also some fixes derived
from some of your remarks.

> Best regards,
> 
> Peter
> 
> > Cc: "Michael S. Tsirkin" <mst at redhat.com>
> > Cc: Igor Skalkin <igor.skalkin at opensynergy.com>
> > Cc: Peter Hilber <peter.hilber at opensynergy.com>
> > Cc: virtualization at lists.linux-foundation.org
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > ---
> > v8 --> v9
> > - check for deferred_wq existence before queueing work to avoid
> >   race at driver removal time
> > ---
> >  drivers/firmware/arm_scmi/Kconfig  |  15 ++
> >  drivers/firmware/arm_scmi/virtio.c | 298 ++++++++++++++++++++++++++---
> >  2 files changed, 287 insertions(+), 26 deletions(-)
> > 
> > diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> > index d429326433d1..7794bd41eaa0 100644
> > --- a/drivers/firmware/arm_scmi/Kconfig
> > +++ b/drivers/firmware/arm_scmi/Kconfig
> > @@ -118,6 +118,21 @@ config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
> >  	  the ones implemented by kvmtool) and let the core Kernel VirtIO layer
> >  	  take care of the needed conversions, say N.
> >  
> > +config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
> > +	bool "Enable atomic mode for SCMI VirtIO transport"
> > +	depends on ARM_SCMI_TRANSPORT_VIRTIO
> > +	help
> > +	  Enable support of atomic operation for SCMI VirtIO based transport.
> > +
> > +	  If you want the SCMI VirtIO based transport to operate in atomic
> > +	  mode, avoiding any kind of sleeping behaviour for selected
> > +	  transactions on the TX path, answer Y.
> > +
> > +	  Enabling atomic mode operations allows any SCMI driver using this
> > +	  transport to optionally ask for atomic SCMI transactions and operate
> > +	  in atomic context too, at the price of using a number of busy-waiting
> > +	  primitives all over instead. If unsure say N.
> > +
> >  endif #ARM_SCMI_PROTOCOL
> >  
> >  config ARM_SCMI_POWER_DOMAIN
> > diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
> > index fd0f6f91fc0b..e54d14971c07 100644
> > --- a/drivers/firmware/arm_scmi/virtio.c
> > +++ b/drivers/firmware/arm_scmi/virtio.c
> > @@ -3,8 +3,8 @@
> >   * Virtio Transport driver for Arm System Control and Management Interface
> >   * (SCMI).
> >   *
> > - * Copyright (C) 2020-2021 OpenSynergy.
> > - * Copyright (C) 2021 ARM Ltd.
> > + * Copyright (C) 2020-2022 OpenSynergy.
> > + * Copyright (C) 2021-2022 ARM Ltd.
> >   */
> >  
> >  /**
> > @@ -38,6 +38,9 @@
> >   * @vqueue: Associated virtqueue
> >   * @cinfo: SCMI Tx or Rx channel
> >   * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
> > + * @deferred_tx_work: Worker for TX deferred replies processing
> > + * @deferred_tx_wq: Workqueue for TX deferred replies
> > + * @pending_cmds_list: List of pre-fetched commands queueud for later processing
> >   * @is_rx: Whether channel is an Rx channel
> >   * @ready: Whether transport user is ready to hear about channel
> >   * @max_msg: Maximum number of pending messages for this channel.
> > @@ -49,6 +52,9 @@ struct scmi_vio_channel {
> >  	struct virtqueue *vqueue;
> >  	struct scmi_chan_info *cinfo;
> >  	struct list_head free_list;
> > +	struct list_head pending_cmds_list;
> > +	struct work_struct deferred_tx_work;
> > +	struct workqueue_struct *deferred_tx_wq;
> >  	bool is_rx;
> >  	bool ready;
> >  	unsigned int max_msg;
> > @@ -65,12 +71,22 @@ struct scmi_vio_channel {
> >   * @input: SDU used for (delayed) responses and notifications
> >   * @list: List which scmi_vio_msg may be part of
> >   * @rx_len: Input SDU size in bytes, once input has been received
> > + * @poll_idx: Last used index registered for polling purposes if this message
> > + *	      transaction reply was configured for polling.
> > + *	      Note that since virtqueue used index is an unsigned 16-bit we can
> > + *	      use some out-of-scale values to signify particular conditions.
> > + * @poll_lock: Protect access to @poll_idx.
> >   */
> >  struct scmi_vio_msg {
> >  	struct scmi_msg_payld *request;
> >  	struct scmi_msg_payld *input;
> >  	struct list_head list;
> >  	unsigned int rx_len;
> > +#define VIO_MSG_NOT_POLLED	0xeeeeeeeeUL
> > +#define VIO_MSG_POLL_DONE	0xffffffffUL
> > +	unsigned int poll_idx;
> > +	/* lock to protect access to poll_idx. */
> > +	spinlock_t poll_lock;
> >  };
> >  
> >  /* Only one SCMI VirtIO device can possibly exist */
> > @@ -81,40 +97,43 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
> >  	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
> >  }
> >  
> > +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
> >  static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
> >  			       struct scmi_vio_msg *msg,
> >  			       struct device *dev)
> >  {
> >  	struct scatterlist sg_in;
> >  	int rc;
> > -	unsigned long flags;
> >  
> >  	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
> >  
> > -	spin_lock_irqsave(&vioch->lock, flags);
> > -
> >  	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
> >  	if (rc)
> >  		dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
> >  	else
> >  		virtqueue_kick(vioch->vqueue);
> >  
> > -	spin_unlock_irqrestore(&vioch->lock, flags);
> > -
> >  	return rc;
> >  }
> >  
> > +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
> > +static inline void scmi_vio_feed_vq_tx(struct scmi_vio_channel *vioch,
> > +				       struct scmi_vio_msg *msg)
> > +{
> > +	spin_lock(&msg->poll_lock);
> > +	msg->poll_idx = VIO_MSG_NOT_POLLED;
> > +	spin_unlock(&msg->poll_lock);
> > +
> > +	list_add(&msg->list, &vioch->free_list);
> > +}
> > +
> >  static void scmi_finalize_message(struct scmi_vio_channel *vioch,
> >  				  struct scmi_vio_msg *msg)
> >  {
> > -	if (vioch->is_rx) {
> > +	if (vioch->is_rx)
> >  		scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
> > -	} else {
> > -		/* Here IRQs are assumed to be already disabled by the caller */
> > -		spin_lock(&vioch->lock);
> > -		list_add(&msg->list, &vioch->free_list);
> > -		spin_unlock(&vioch->lock);
> > -	}
> > +	else
> > +		scmi_vio_feed_vq_tx(vioch, msg);
> >  }
> >  
> >  static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> > @@ -144,6 +163,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> >  			virtqueue_disable_cb(vqueue);
> >  			cb_enabled = false;
> >  		}
> > +
> >  		msg = virtqueue_get_buf(vqueue, &length);
> >  		if (!msg) {
> >  			if (virtqueue_enable_cb(vqueue))
> > @@ -157,7 +177,9 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> >  			scmi_rx_callback(vioch->cinfo,
> >  					 msg_read_header(msg->input), msg);
> >  
> > +			spin_lock(&vioch->lock);
> >  			scmi_finalize_message(vioch, msg);
> > +			spin_unlock(&vioch->lock);
> >  		}
> >  
> >  		/*
> > @@ -176,6 +198,34 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> >  	spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
> >  }
> >  
> > +static void scmi_vio_deferred_tx_worker(struct work_struct *work)
> > +{
> > +	unsigned long flags;
> > +	struct scmi_vio_channel *vioch;
> > +	struct scmi_vio_msg *msg, *tmp;
> > +
> > +	vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
> > +
> > +	/* Process pre-fetched messages */
> > +	spin_lock_irqsave(&vioch->lock, flags);
> > +
> > +	/* Scan the list of possibly pre-fetched messages during polling. */
> > +	list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
> > +		list_del(&msg->list);
> > +
> > +		scmi_rx_callback(vioch->cinfo,
> > +				 msg_read_header(msg->input), msg);
> > +
> > +		/* Free the processed message once done */
> > +		scmi_vio_feed_vq_tx(vioch, msg);
> > +	}
> > +
> > +	spin_unlock_irqrestore(&vioch->lock, flags);
> > +
> > +	/* Process possibly still pending messages */
> > +	scmi_vio_complete_cb(vioch->vqueue);
> > +}
> > +
> >  static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
> >  
> >  static vq_callback_t *scmi_vio_complete_callbacks[] = {
> > @@ -244,6 +294,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
> >  
> >  	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
> >  
> > +	/* Setup a deferred worker for polling. */
> > +	if (tx && !vioch->deferred_tx_wq) {
> > +		vioch->deferred_tx_wq =
> > +			alloc_workqueue(dev_name(&scmi_vdev->dev),
> > +					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
> > +					0);
> > +		if (!vioch->deferred_tx_wq)
> > +			return -ENOMEM;
> > +
> > +		INIT_WORK(&vioch->deferred_tx_work,
> > +			  scmi_vio_deferred_tx_worker);
> > +	}
> > +
> >  	for (i = 0; i < vioch->max_msg; i++) {
> >  		struct scmi_vio_msg *msg;
> >  
> > @@ -257,6 +320,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
> >  						    GFP_KERNEL);
> >  			if (!msg->request)
> >  				return -ENOMEM;
> > +			spin_lock_init(&msg->poll_lock);
> >  		}
> >  
> >  		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
> > @@ -264,13 +328,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
> >  		if (!msg->input)
> >  			return -ENOMEM;
> >  
> > -		if (tx) {
> > -			spin_lock_irqsave(&vioch->lock, flags);
> > -			list_add_tail(&msg->list, &vioch->free_list);
> > -			spin_unlock_irqrestore(&vioch->lock, flags);
> > -		} else {
> > +		spin_lock_irqsave(&vioch->lock, flags);
> > +		if (tx)
> > +			scmi_vio_feed_vq_tx(vioch, msg);
> > +		else
> >  			scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
> > -		}
> > +		spin_unlock_irqrestore(&vioch->lock, flags);
> >  	}
> >  
> >  	spin_lock_irqsave(&vioch->lock, flags);
> > @@ -291,11 +354,22 @@ static int virtio_chan_free(int id, void *p, void *data)
> >  	unsigned long flags;
> >  	struct scmi_chan_info *cinfo = p;
> >  	struct scmi_vio_channel *vioch = cinfo->transport_info;
> > +	void *deferred_wq = NULL;
> >  
> >  	spin_lock_irqsave(&vioch->ready_lock, flags);
> >  	vioch->ready = false;
> >  	spin_unlock_irqrestore(&vioch->ready_lock, flags);
> >  
> > +	spin_lock_irqsave(&vioch->lock, flags);
> > +	if (!vioch->is_rx && vioch->deferred_tx_wq) {
> > +		deferred_wq = vioch->deferred_tx_wq;
> > +		vioch->deferred_tx_wq = NULL;
> > +	}
> > +	spin_unlock_irqrestore(&vioch->lock, flags);
> > +
> > +	if (deferred_wq)
> > +		destroy_workqueue(deferred_wq);
> > +
> >  	scmi_free_channel(cinfo, data, id);
> >  
> >  	spin_lock_irqsave(&vioch->lock, flags);
> > @@ -324,7 +398,8 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
> >  	}
> >  
> >  	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
> > -	list_del(&msg->list);
> > +	/* Re-init element so we can discern anytime if it is still in-flight */
> > +	list_del_init(&msg->list);
> >  
> >  	msg_tx_prepare(msg->request, xfer);
> >  
> > @@ -337,6 +412,19 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
> >  		dev_err(vioch->cinfo->dev,
> >  			"failed to add to TX virtqueue (%d)\n", rc);
> >  	} else {
> > +		/*
> > +		 * If polling was requested for this transaction:
> > +		 *  - retrieve last used index (will be used as polling reference)
> 
> The virtqueue_add_sgs() called before already exposed the message to the virtio
> device, so a fast response might have arrived already, so the reference value
> might unexpectedly correspond to the current message.
> 

Good point I have wrongly considered the kick as the only trigger but if
indeed the device was already kicked and processing the queues the scenario
you depicted is possible. I'll move this logic earlier.

> > +		 *  - bind the polled message to the xfer via .priv
> > +		 */
> > +		if (xfer->hdr.poll_completion) {
> > +			spin_lock(&msg->poll_lock);
> > +			msg->poll_idx =
> > +				virtqueue_enable_cb_prepare(vioch->vqueue);
> > +			spin_unlock(&msg->poll_lock);
> > +			/* Ensure initialized msg is visibly bound to xfer */
> > +			smp_store_mb(xfer->priv, msg);
> > +		}
> >  		virtqueue_kick(vioch->vqueue);
> >  	}
> >  
> > @@ -350,10 +438,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo,
> >  {
> >  	struct scmi_vio_msg *msg = xfer->priv;
> >  
> > -	if (msg) {
> > +	if (msg)
> >  		msg_fetch_response(msg->input, msg->rx_len, xfer);
> > -		xfer->priv = NULL;
> > -	}
> >  }
> >  
> >  static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
> > @@ -361,10 +447,166 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
> >  {
> >  	struct scmi_vio_msg *msg = xfer->priv;
> >  
> > -	if (msg) {
> > +	if (msg)
> >  		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
> > -		xfer->priv = NULL;
> > +}
> > +
> > +/**
> > + * virtio_mark_txdone  - Mark transmission done
> > + *
> > + * Free only successfully completed polling transfer messages.
> > + *
> > + * Note that in the SCMI VirtIO transport we never explicitly release timed-out
> > + * messages by forcibly re-adding them to the free-list, even on timeout, inside
> > + * the TX code path; we instead let IRQ/RX callbacks eventually clean up such
> > + * messages once, finally, a late reply is received and discarded (if ever).
> > + *
> > + * This approach was deemed preferable since those pending timed-out buffers are
> > + * still effectively owned by the SCMI platform VirtIO device even after timeout
> > + * expiration: forcibly freeing and reusing them before they had been returned
> > + * explicitly by the SCMI platform could lead to subtle bugs due to message
> > + * corruption.
> > + * An SCMI platform VirtIO device which never returns message buffers is
> > + * anyway broken and it will quickly lead to exhaustion of available messages.
> > + *
> > + * For this same reason, here, we take care to free only the successfully
> > + * completed polled messages, since they won't be freed elsewhere; late replies
> > + * to timed-out polled messages would be anyway freed by RX callbacks instead.
> > + *
> > + * @cinfo: SCMI channel info
> > + * @ret: Transmission return code
> > + * @xfer: Transfer descriptor
> > + */
> > +static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
> > +			       struct scmi_xfer *xfer)
> > +{
> > +	unsigned long flags;
> > +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> > +	struct scmi_vio_msg *msg = xfer->priv;
> > +
> > +	if (!msg)
> > +		return;
> > +
> > +	/* Ensure msg is unbound from xfer before pushing onto the free list  */
> > +	smp_store_mb(xfer->priv, NULL);
> > +
> > +	/* Is a successfully completed polled message still to be finalized ? */
> > +	spin_lock_irqsave(&vioch->lock, flags);
> > +	if (!ret && xfer->hdr.poll_completion && list_empty(&msg->list))
> 
> Could this not also be a message which was already finalized and then
> immediately reused for another polling xfer?
> 

Fist of all, in the upcoming series there is already a fix here, because I do
not want (as in non-polling mode and as stated in the comment above) to forcibly
release -ETIMEOUT xfer here. New check being like:

	if (ret != -ETIMEDOUT && xfer->hdr.poll_completion && list_empty(&msg->list))

BUT, if I understood correctly what you meant you are talking about a polled
message which had been received by chance on the IRQ path and there finalized
already, and so subsequently happily picked up from the free list for another
polled transfer....I think you are right, even if remote, this is a possibility
to account for (and the list_empty() check fails at this): I'll take care to clear
xfer->priv after a command is fetched BUT only if received across the IRQ path,
and drop the list_empty() check above which at this point is redundant: in this
way mark_tx_done will be skip even for polled cmds that have already been
finalized on the IRQ path. (notifications/delayed responses are unaffected
since not handled on this path...)

Thanks for spotting this.

> > +		scmi_vio_feed_vq_tx(vioch, msg);
> > +	spin_unlock_irqrestore(&vioch->lock, flags);
> > +}
> > +
> > +/**
> > + * virtio_poll_done  - Provide polling support for VirtIO transport
> > + *
> > + * @cinfo: SCMI channel info
> > + * @xfer: Reference to the transfer being poll for.
> > + *
> > + * VirtIO core provides a polling mechanism based only on last used indexes:
> > + * this means that it is possible to poll the virtqueues waiting for something
> > + * new to arrive from the host side but the only way to check if the freshly
> > + * arrived buffer was what we were waiting for is to compare the newly arrived
> > + * message descriptors with the one we are polling on.
> > + *
> > + * As a consequence it can happen to dequeue something different from the buffer
> > + * we were poll-waiting for: if that is the case such early fetched buffers are
> > + * then added to a the @pending_cmds_list list for later processing by a
> > + * dedicated deferred worker.
> > + *
> > + * So, basically, once something new is spotted we proceed to de-queue all the
> > + * freshly received used buffers until we found the one we were polling on, or,
> > + * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
> > + * in the vqueue at the end of the polling loop (possible due to inherent races
> > + * in virtqueues handling mechanisms), we similarly kick the deferred worker
> > + * and let it process those, to avoid indefinitely looping in the .poll_done
> > + * helper.
> > + *
> > + * Note that we do NOT suppress notification with VIRTQ_USED_F_NO_NOTIFY even
> > + * when polling since such flag is per-virtqueues and we do not want to
> > + * suppress notifications as a whole: so, if the message we are polling for is
> > + * delivered via usual IRQs callbacks, on another core which are IRQs-on, it
> > + * will be handled as such by scmi_rx_callback() and the polling loop in the
> > + * SCMI Core TX path will be transparently terminated anyway.
> 
> Why is VIRTQ_USED_F_NO_NOTIFY mentioned? It is a flag associated with only one
> of two buffer notification suppression methods, which are transparently handled
> by the virtio core. Cf. `Driver Requirements: Used Buffer Notification
> Suppression' in the virtio spec.
> 

I saw that paragraph on the spec, what I wanted to stress was that we have no
way to implement a per-message notification suppression (and probably neither a
per-channel one since VIRTQ_USED_F_NO_NOTIFY is not really exposed), so that
a polled message could be indeed received instead through the usual IRQ based
callbacks if it happens to be delivered on a different core or if the
current polling core is not running such loops with IRQs off, but such
behaviour is supported and handled.

Anyway it is probably confusing mentioning the presence of the
VIRTQ_USED_F_NO_NOTIFY flag, so I'll drop that mention.

> > + *
> > + * Return: True once polling has successfully completed.
> > + */
> > +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> > +			     struct scmi_xfer *xfer)
> > +{
> > +	bool pending, ret = false;
> > +	unsigned int length, any_prefetched = 0;
> > +	unsigned long flags;
> > +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> > +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> > +
> > +	if (!msg)
> > +		return true;
> > +
> > +	spin_lock_irqsave(&msg->poll_lock, flags);
> > +	/* Processed already by other polling loop on another CPU ? */
> > +	if (msg->poll_idx == VIO_MSG_POLL_DONE) {
> > +		spin_unlock_irqrestore(&msg->poll_lock, flags);
> > +		return true;
> > +	}
> > +
> > +	/* Has cmdq index moved at all ? */
> > +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> 
> In my understanding, the polling comparison could still be subject to the ABA
> problem when exactly 2**16 messages have been marked as used since
> msg->poll_idx was set (unlikely scenario, granted).
> 
> I think this would be a lot simpler if the virtio core exported some
> concurrency-safe helper function for such polling (similar to more_used() from
> virtio_ring.c), as discussed at the top.

So this is the main limitation indeed of the current implementation, I
cannot distinguish if there was an exact full wrap and I'm reading the same
last_idx as before but a whoppying 2**16 messages have instead gone through...

The tricky part seems to me here that even introducing dedicated helpers
for polling in order to account for such wrapping (similar to more_used())
those would be based by current VirtIO spec on a single bit wrap counter,
so how do you discern if 2 whole wraps have happened (even more unlikely..) ?

Maybe I'm missing something though...

I'll have a though about this, but in my opinion this seems something so
unlikely that we could live with it, for the moment at least...

> 
> > +	spin_unlock_irqrestore(&msg->poll_lock, flags);
> > +	if (!pending)
> > +		return false;
> > +
> > +	spin_lock_irqsave(&vioch->lock, flags);
> > +	virtqueue_disable_cb(vioch->vqueue);
> > +
> > +	/*
> > +	 * If something arrived we cannot be sure, without dequeueing, if it
> > +	 * was the reply to the xfer we are polling for, or, to other, even
> > +	 * possibly non-polling, pending xfers: process all new messages
> > +	 * till the polled-for message is found OR the vqueue is empty.
> > +	 */
> > +	while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
> > +		next_msg->rx_len = length;
> > +		/* Is the message we were polling for ? */
> > +		if (next_msg == msg) {
> > +			ret = true;
> > +			break;
> > +		}
> > +
> > +		spin_lock(&next_msg->poll_lock);
> > +		if (next_msg->poll_idx == VIO_MSG_NOT_POLLED) {
> > +			any_prefetched++;
> > +			list_add_tail(&next_msg->list,
> > +				      &vioch->pending_cmds_list);
> > +		} else {
> > +			next_msg->poll_idx = VIO_MSG_POLL_DONE;
> > +		}
> > +		spin_unlock(&next_msg->poll_lock);
> >  	}
> > +
> > +	/*
> > +	 * When the polling loop has successfully terminated if something
> > +	 * else was queued in the meantime, it will be served by a deferred
> > +	 * worker OR by the normal IRQ/callback OR by other poll loops.
> > +	 *
> > +	 * If we are still looking for the polled reply, the polling index has
> > +	 * to be updated to the current vqueue last used index.
> > +	 */
> > +	if (ret) {
> > +		pending = !virtqueue_enable_cb(vioch->vqueue);
> > +	} else {
> > +		spin_lock(&msg->poll_lock);
> > +		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
> > +		pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> > +		spin_unlock(&msg->poll_lock);
> > +	}
> > +
> > +	if (vioch->deferred_tx_wq && (any_prefetched || pending))
> > +		queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);
> 
> What if queue_work() returns false because the single work item for the channel
> was already pending? Couldn't it then happen that the worker CPU will not yet
> see the updates implied by `any_prefetched || pending'?
> 

The short asnwer is, no this can't happen: I had an extensive discussion in the
past around similar concerns about this about SCMI notifs dispatching (which use
workqueues:
https://lore.kernel.org/linux-arm-kernel/0234c256-2e29-69f8-99ae-2599f982961e at arm.com/).

In a nutshell all bails down to how the Kenrel cmwq susbsystem works
internally.

queue_work() does fail if the same work item was already queued recently
and suck work is still marked as WORK_PENDING, BUT that flag happens to be set
only if such queued work is still fully pending in the sense that the worker
thread has still not even being waken by the Kernel cmwq subsystem.

The above flag is indeed cleared right before the related worker
thread is started, roughly:

> kernel/workqueue.c:process_one_work()
> 
> 	set_work_pool_and_clear_pending(work, pool->id);
> 	....
> 	worker->current_func(work);
> 

So queue_work() return false only if a previous work was pending AND the
worker thread was still dormient; it is not possible that the worker
thread was running and, say, had already emptied the above @pending_cmds_list
but was still marked pending since it still has to terminate (that would be
indeed a problem and you would end up with this new work items not seen
till the next worker run is kicked)

Moreover, here the work items are really contained in a spinlocked list
whose spinlock is hold here while filling up the list and in the worker
thread while emptying it, so that it is neither possible to
modify/corrupt the list while the worker is consuming it, in case you
successfully queue more work while the worker is running.

Thanks again for your feedback,
Cristian

P.S: .. from the other thread..
> ... it seems to me that is exactly how I'm using it, and moreover I
> don't see any other way via the VirtIO API to grab that last_used_idx
> that I need for virtqueu_poll.

>> I meant to say that the VIO_MSG_POLL_DONE special value should best not be put
>> into the .poll_idx (since the special value might in theory overlap with an
>> opaque value). Another variable could hold the special states VIO_MSG_POLL_DONE
>> and VIO_MSG_NOT_POLLED.

Yes indeed, I was trying to avoid to keep one more variable ignoring indeed
the opaqueness :D ... I'll find a better way.


From shameerali.kolothum.thodi at huawei.com  Wed Jan 19 04:30:09 2022
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Wed, 19 Jan 2022 12:30:09 +0000
Subject: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
In-Reply-To: <Yef65ng6pQK5yZDa@arm.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
 <Yeazd1lLuYm4k3lH@arm.com> <207f800d1a67427a9771ffb06086365b@huawei.com>
 <Yef65ng6pQK5yZDa@arm.com>
Message-ID: <ab7dc77ee8804f1e958c18cc4dac4a65@huawei.com>



> -----Original Message-----
> From: Catalin Marinas [mailto:catalin.marinas at arm.com]
> Sent: 19 January 2022 11:50
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: linux-arm-kernel at lists.infradead.org; kvmarm at lists.cs.columbia.edu;
> linux-kernel at vger.kernel.org; maz at kernel.org; will at kernel.org;
> james.morse at arm.com; julien.thierry.kdev at gmail.com;
> suzuki.poulose at arm.com; jean-philippe at linaro.org;
> Alexandru.Elisei at arm.com; qperret at google.com; Jonathan Cameron
> <jonathan.cameron at huawei.com>; Linuxarm <linuxarm at huawei.com>
> Subject: Re: [PATCH v4 0/4] kvm/arm: New VMID allocator based on asid
> 
> On Wed, Jan 19, 2022 at 09:23:31AM +0000, Shameerali Kolothum Thodi
> wrote:
> > > On Mon, Nov 22, 2021 at 12:18:40PM +0000, Shameer Kolothum wrote:
> > > > ?-TLA+ model. Modified the asidalloc model to incorporate the new
> > > >   VMID algo. The main differences are,
> > > > ? -flush_tlb_all() instead of local_tlb_flush_all() on rollover.
> > > > ? -Introduced INVALID_VMID and vCPU Sched Out logic.
> > > > ? -No CnP (Removed UniqueASIDAllCPUs & UniqueASIDActiveTask
> invariants).
> > > > ? -Removed ?UniqueVMIDPerCPU invariant for now as it looks like
> > > >    because of the speculative fetching with flush_tlb_all() there
> > > >    is a small window where this gets triggered. If I change the
> > > >    logic back to local_flush_tlb_all(), UniqueVMIDPerCPU seems to
> > > >    be fine. With my limited knowledge on TLA+ model, it is not
> > > >    clear to me whether this is a problem with the above logic
> > > >    or the VMID model implementation. Really appreciate any help
> > > >    with the model.
> > > >    The initial VMID TLA+ model is here,
> > > >
> https://github.com/shamiali2008/kernel-tla/tree/private-vmidalloc-v1
> > >
> > > I only had a brief look at the TLA+ model and I don't understand why you
> > > have a separate 'shed_out' process. It would run in parallel with the
> > > 'sched' but AFAICT you can't really schedule a guest out while you are
> > > in the middle of scheduling it in. I'd rather use the same 'sched'
> > > process and either schedule in an inactive task or schedule out an
> > > active one for a given CPU.
> > >
> > > Also active_vmids[] for example is defined on the CPUS domain but you
> > > call vcpu_sched_out() from a process that's not in the CPUS domain but
> > > the SCHED_OUT one.
> >
> > Many thanks for taking a look. My bad!. The 'sched_out' would indeed run in
> parallel
> > and defeat the purpose. I must say I was really confused by the TLA+ syntax
> and
> > is still not very confident about it.
> 
> Yeah, it can be confusing. If you have time, you could give CBMC a try
> and the 'spec' would be pretty close to your C version. Each CPU would
> be modelled as a thread with an extra thread that simulates the
> speculative TLB look-ups for all CPUS together with the asserts for the
> invariants. The spinlocks would be pthread_mutexes.

Ok, will take a look.

> > Based on the above suggestion, I have modified it as below,
> >
> > \* vCPU is scheduled out by KVM
> > macro vcpu_sched_out() {
> >         active_kvm[self].task := 0;
> >         active_vmids[self] := INVALID_VMID;
> > }
> 
> Could you call cpu_switch_kvm(0, INVALID_VMID) instead? You could do
> this directly below and avoid another macro. Well, whatever you find
> clearer.

Sure, will change that.

> What confuses me is that your INVALID_VMID looks like a valid one: vmid
> 0, generation 1. Do you ensure that you never allocate VMID 0?

This is same as in asidalloc wherein the cur_idx starts at 1 for any new
allocation. I think that guarantees VMID 0 is never allocated.  

> 
> > \* About to run a Guest VM
> > process (sched \in CPUS)
> > {
> > sched_loop:
> >         while (TRUE) {
> >                 with (t \in TASKS) {
> >                         if (t # ActiveTask(self))
> >                                 call kvm_arm_vmid_update(t);
> >                         else
> >                                 vcpu_sched_out();
> >                 }
> >         }
> > }
> 
> Yes, that's what I meant.

Ok.

> 
> > > The corresponding
> > > UniqueASIDPerCPU meant that for any two TLB entries on a single CPU, if
> > > they correspond to different tasks (pgd), they should have different
> > > ASIDs. That's a strong requirement, otherwise we end up with the wrong
> > > translation.
> >
> > Yes, I understand that it is a strong requirement. Also, I thought this is
> something
> > that will trigger easily with the test setup I had with the real hardware. But
> testing
> > stayed on for days, so I was not sure it is a problem with the TLA+
> implementation
> > or not.
> 
> Well, you'd have to check the TLA+ state trace and see how it got
> there, whether the last state would be a valid one. It's either
> something missing in the spec that the hardware enforces or the
> algorithm is wrong and just hard to hit in practice. If this condition
> is violated in hardware for a very brief period, e.g. due to some TLBI,
> you'd not notice an issue under normal circumstances. But it's still
> incorrect.

Hmm..I had a quick implementation with a separate thread for speculative
load as done in the arm64kpti.tla, but still get the UniqueVMIDPerCPU violation
error. I will go through the state trace and see whether I can interpret something :) 
 
> > > Why did you remove the CnP? Do we have this disabled for KVM guests?
> >
> > I removed CnP related Invariants to simplify things for the first version. Also
> not sure
> > what specific changes we need to do for CnP here. Do we still need that
> switching to
> > global pg_dir to prevent any speculative reading? I didn't see that being
> done in KVM
> > anywhere at the moment. Maybe I am missing something.
> 
> It make sense to ignore CnP for now. Maybe KVM doesn't even bother and
> sets VTTBR_EL2.CnP to 0 (I haven't checked).

I think KVM sets the CnP here,
https://elixir.bootlin.com/linux/latest/source/arch/arm64/include/asm/kvm_mmu.h#L264

But I haven't figured out what else we need to do in this new VMID allocator for
CnP case. 

Marc, Will?

> 
> > On a side note, In my setup, the CnP=TRUE case for asidalloc.tla now fails
> with,
> > "Error: Invariant TLBEmptyInvalPTE is violated.". Please check.
> 
> This was added later as part of try-to-unmap and I only checked this
> with CnP = FALSE. I'll need to look into, it's possible that
> flush_tlb_all() doesn't take into account that the pte is unmapped (as
> cpu_switch_mm() does). I'll add a separate thread for speculative TLB
> loads, it's easier to have them in one place. Thanks.

Ok.

Thanks,
Shameer


From sam.shih at mediatek.com  Wed Jan 19 04:36:24 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:36:24 +0800
Subject: [PATCH 1/1] arm64: dts: mediatek: add clock support for mt7986a
In-Reply-To: <20220119123624.10043-1-sam.shih@mediatek.com>
References: <20220119123624.10043-1-sam.shih@mediatek.com>
Message-ID: <20220119123624.10043-2-sam.shih@mediatek.com>

Add clock controller nodes, include 40M clock source, topckgen,
infracfg, apmixedsys and ethernet subsystem.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 68 +++++++++++++++++++++--
 1 file changed, 63 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
index b8da76b6ba47..694acf8f5b70 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -6,16 +6,18 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7986-clk.h>
 
 / {
 	interrupt-parent = <&gic>;
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	system_clk: dummy40m {
+	clk40m: oscillator at 0 {
 		compatible = "fixed-clock";
 		clock-frequency = <40000000>;
 		#clock-cells = <0>;
+		clock-output-names = "clkxtal";
 	};
 
 	cpus {
@@ -98,6 +100,18 @@ gic: interrupt-controller at c000000 {
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		infracfg: infracfg at 10001000 {
+			compatible = "mediatek,mt7986-infracfg", "syscon";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		topckgen: topckgen at 1001b000 {
+			compatible = "mediatek,mt7986-topckgen", "syscon";
+			reg = <0 0x1001B000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
 		watchdog: watchdog at 1001c000 {
 			compatible = "mediatek,mt7986-wdt",
 				     "mediatek,mt6589-wdt";
@@ -107,6 +121,12 @@ watchdog: watchdog at 1001c000 {
 			status = "disabled";
 		};
 
+		apmixedsys: apmixedsys at 1001e000 {
+			compatible = "mediatek,mt7986-apmixedsys";
+			reg = <0 0x1001E000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
 		pio: pinctrl at 1001f000 {
 			compatible = "mediatek,mt7986a-pinctrl";
 			reg = <0 0x1001f000 0 0x1000>,
@@ -128,11 +148,25 @@ pio: pinctrl at 1001f000 {
 			#interrupt-cells = <2>;
 		};
 
+		sgmiisys0: syscon at 10060000 {
+			compatible = "mediatek,mt7986-sgmiisys_0",
+				     "syscon";
+			reg = <0 0x10060000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		sgmiisys1: syscon at 10070000 {
+			compatible = "mediatek,mt7986-sgmiisys_1",
+				     "syscon";
+			reg = <0 0x10070000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
 		trng: trng at 1020f000 {
 			compatible = "mediatek,mt7986-rng",
 				     "mediatek,mt7623-rng";
 			reg = <0 0x1020f000 0 0x100>;
-			clocks = <&system_clk>;
+			clocks = <&infracfg CLK_INFRA_TRNG_CK>;
 			clock-names = "rng";
 			status = "disabled";
 		};
@@ -142,7 +176,13 @@ uart0: serial at 11002000 {
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11002000 0 0x400>;
 			interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&system_clk>;
+			clocks = <&infracfg CLK_INFRA_UART0_SEL>,
+				 <&infracfg CLK_INFRA_UART0_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
+					  <&infracfg CLK_INFRA_UART0_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
+						 <&topckgen CLK_TOP_UART_SEL>;
 			status = "disabled";
 		};
 
@@ -151,7 +191,11 @@ uart1: serial at 11003000 {
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11003000 0 0x400>;
 			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&system_clk>;
+			clocks = <&infracfg CLK_INFRA_UART1_SEL>,
+				 <&infracfg CLK_INFRA_UART1_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART1_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
 			status = "disabled";
 		};
 
@@ -160,10 +204,24 @@ uart2: serial at 11004000 {
 				     "mediatek,mt6577-uart";
 			reg = <0 0x11004000 0 0x400>;
 			interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&system_clk>;
+			clocks = <&infracfg CLK_INFRA_UART2_SEL>,
+				 <&infracfg CLK_INFRA_UART2_CK>;
+			clock-names = "baud", "bus";
+			assigned-clocks = <&infracfg CLK_INFRA_UART2_SEL>;
+			assigned-clock-parents = <&topckgen CLK_TOP_F26M_SEL>;
 			status = "disabled";
 		};
 
+		ethsys: syscon at 15000000 {
+			 #address-cells = <1>;
+			 #size-cells = <1>;
+			 compatible = "mediatek,mt7986-ethsys",
+				      "syscon";
+			 reg = <0 0x15000000 0 0x1000>;
+			 #clock-cells = <1>;
+			 #reset-cells = <1>;
+		};
+
 	};
 
 };
-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan 19 04:36:58 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:36:58 +0800
Subject: [PATCH 1/1] clk: mediatek: relicense mt7986 clock driver to GPL-2.0
In-Reply-To: <20220119123658.10095-1-sam.shih@mediatek.com>
References: <20220119123658.10095-1-sam.shih@mediatek.com>
Message-ID: <20220119123658.10095-2-sam.shih@mediatek.com>

The previous mt7986 clock drivers were incorrectly marked as GPL-1.0.
This patch changes the driver to the standard GPL-2.0 license.

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 drivers/clk/mediatek/clk-mt7986-apmixed.c  | 2 +-
 drivers/clk/mediatek/clk-mt7986-infracfg.c | 2 +-
 drivers/clk/mediatek/clk-mt7986-topckgen.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
index 76c8ebdeae96..98ec3887585f 100644
--- a/drivers/clk/mediatek/clk-mt7986-apmixed.c
+++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-1.0
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2021 MediaTek Inc.
  * Author: Sam Shih <sam.shih at mediatek.com>
diff --git a/drivers/clk/mediatek/clk-mt7986-infracfg.c b/drivers/clk/mediatek/clk-mt7986-infracfg.c
index 3be168c34fc0..f209c559fbc3 100644
--- a/drivers/clk/mediatek/clk-mt7986-infracfg.c
+++ b/drivers/clk/mediatek/clk-mt7986-infracfg.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-1.0
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2021 MediaTek Inc.
  * Author: Sam Shih <sam.shih at mediatek.com>
diff --git a/drivers/clk/mediatek/clk-mt7986-topckgen.c b/drivers/clk/mediatek/clk-mt7986-topckgen.c
index 8550e2be7773..8f6f79b6e31e 100644
--- a/drivers/clk/mediatek/clk-mt7986-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt7986-topckgen.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-1.0
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2021 MediaTek Inc.
  * Author: Sam Shih <sam.shih at mediatek.com>
-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan 19 04:35:36 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:35:36 +0800
Subject: [PATCH 1/2] arm64: dts: mediatek: update mt7986a memory node
In-Reply-To: <20220119123537.9968-1-sam.shih@mediatek.com>
References: <20220119123537.9968-1-sam.shih@mediatek.com>
Message-ID: <20220119123537.9968-2-sam.shih@mediatek.com>

This patch updates the format of memory node in DT based on
maintainer comments in the following thread:
https://lore.kernel.org/all/bc0a9df0-8ba0-76ed-4522-43a3082f42b4 at gmail.com/

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
index 5cd760abff51..21e420829572 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -19,7 +19,8 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory at 40000000 {
+		device_type = "memory";
 		reg = <0 0x40000000 0 0x40000000>;
 	};
 };
-- 
2.29.2



From mark.rutland at arm.com  Wed Jan 19 04:42:34 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 12:42:34 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220117121557.GA87485@C02TD0UTHF1T.local>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
 <20220114181247.7b366f45@donnerap.cambridge.arm.com>
 <20220117121557.GA87485@C02TD0UTHF1T.local>
Message-ID: <YegHOqpe24imKuMN@FVFF77S0Q05N>

On Mon, Jan 17, 2022 at 12:15:57PM +0000, Mark Rutland wrote:
> On Fri, Jan 14, 2022 at 06:12:47PM +0000, Andre Przywara wrote:
> > On Fri, 14 Jan 2022 10:56:46 +0000
> > Mark Rutland <mark.rutland at arm.com> wrote:

> > > +
> > > +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > > +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))
> > 
> > - The kernel sets TSCXT(bit[20]), and the ARM ARM says that the value
> > should be RES1 if FEAT_CSV2_* is not implemented. Should we copy this?
> 
> Yes, we should. I'll go and fold that in.
> 
> > - The kernel clears ITD(bit[7]), and the ARM ARM says it's *Otherwise* RES1
> > (no AArch32 in EL0). I feel like we should not disable IT instructions in
> > EL0 needlessly?
> 
> Per the ARM ARM the bit resets to an UNKNOWN value, and so per our usual
> policy the kernel must initialize that before it can depend upon it, and
> IIUC you say the kernel already does so.
> 
> So it shouldn't matter what the boot-wrapper does, and for consitency, I
> think the boot-wrapper should set this to 0b1.
> 
> > - I also feel like we should set CP15BEN(bit[5]), for similar reasons.
> 
> I agree.

I thought you meant it was also RES1 in the same case as ITD. It's actually
RES0 when there's no AArch32 EL0 support, so I'm not going to add it to
SCTLR_EL1_RES1.

I have added TSCXT (bit[20]) and ITD (bit[7]), as above, as those are RES1 in
some contexts.

THanks,
Mark.


From sam.shih at mediatek.com  Wed Jan 19 04:36:23 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:36:23 +0800
Subject: [PATCH 0/1] Add clock support for mt7986
Message-ID: <20220119123624.10043-1-sam.shih@mediatek.com>

Add clock controller nodes, include 40M clock source, topckgen,
infracfg, apmixedsys and ethernet subsystem.

Sam Shih (1):
  arm64: dts: mediatek: add clock support for mt7986a

 arch/arm64/boot/dts/mediatek/mt7986a.dtsi | 68 +++++++++++++++++++++--
 1 file changed, 63 insertions(+), 5 deletions(-)

-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan 19 04:35:37 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:35:37 +0800
Subject: [PATCH 2/2] arm64: dts: mediatek: update mt7986b memory node
In-Reply-To: <20220119123537.9968-1-sam.shih@mediatek.com>
References: <20220119123537.9968-1-sam.shih@mediatek.com>
Message-ID: <20220119123537.9968-3-sam.shih@mediatek.com>

This patch updates the format of memory node in DT based on
maintainer comments in the following thread:
https://lore.kernel.org/all/bc0a9df0-8ba0-76ed-4522-43a3082f42b4 at gmail.com/

Signed-off-by: Sam Shih <sam.shih at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
index 5fb752edd754..d73467ea3641 100644
--- a/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -19,7 +19,8 @@ chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	memory {
+	memory at 40000000 {
+		device_type = "memory";
 		reg = <0 0x40000000 0 0x40000000>;
 	};
 };
-- 
2.29.2



From sam.shih at mediatek.com  Wed Jan 19 04:35:35 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:35:35 +0800
Subject: [PATCH 0/2] Update mt7986 memory node in DT
Message-ID: <20220119123537.9968-1-sam.shih@mediatek.com>

This patch updates the format of memory node in DT based on
maintainer comments in the following thread:
https://lore.kernel.org/all/bc0a9df0-8ba0-76ed-4522-43a3082f42b4 at gmail.com/

Sam Shih (2):
  arm64: dts: mediatek: update mt7986a memory node
  arm64: dts: mediatek: update mt7986b memory node

 arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts | 3 ++-
 arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

-- 
2.29.2



From miles.chen at mediatek.com  Wed Jan 19 04:34:30 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 20:34:30 +0800
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
References: <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
Message-ID: <20220119123430.9846-1-miles.chen@mediatek.com>

> We're back in business! I was able to reproduce this using FullLTO
> rather than ThinLTO.

Great!

I tried two clang (r437112b/r437112) but the issue remains.


Miles


From sam.shih at mediatek.com  Wed Jan 19 04:36:57 2022
From: sam.shih at mediatek.com (Sam Shih)
Date: Wed, 19 Jan 2022 20:36:57 +0800
Subject: [PATCH 0/1] Relicense mt7986 clock driver to GPL-2.0
Message-ID: <20220119123658.10095-1-sam.shih@mediatek.com>

The previous mt7986 clock drivers were incorrectly marked as GPL-1.0.
This patch changes the driver to the standard GPL-2.0 license.

Sam Shih (1):
  clk: mediatek: relicense mt7986 clock driver to GPL-2.0

 drivers/clk/mediatek/clk-mt7986-apmixed.c  | 2 +-
 drivers/clk/mediatek/clk-mt7986-infracfg.c | 2 +-
 drivers/clk/mediatek/clk-mt7986-topckgen.c | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

-- 
2.29.2



From wangkefeng.wang at huawei.com  Wed Jan 19 04:57:58 2022
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 19 Jan 2022 20:57:58 +0800
Subject: [PATCH v2 1/3] mm: vmalloc: Let user to control huge vmalloc
 default behavior
In-Reply-To: <1642473992.qrnqczjfna.astroid@bobo.none>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-2-wangkefeng.wang@huawei.com>
 <1642473992.qrnqczjfna.astroid@bobo.none>
Message-ID: <f0dd59eb-6eb8-5b60-508d-7f4022f655ec@huawei.com>


On 2022/1/18 10:52, Nicholas Piggin wrote:
> Excerpts from Kefeng Wang's message of December 28, 2021 12:59 am:
>> Introduce HUGE_VMALLOC_DEFAULT_ENABLED and make it default y, this
>> let user to choose whether or not enable huge vmalloc mappings by
>> default.
>>
>> Meanwhile, add new hugevmalloc=on/off parameter to enable or disable
>> this feature at boot time, nohugevmalloc is still supported and
>> equivalent to hugevmalloc=off.
> Runtime options are bad enough, Kconfig and boot options are even worse.

nohugevmalloc is like blacklists, on the other hand, Add a 
HUGE_VMALLOC_DEFAULT_ENABLED

to close hugevmalloc default and enable it only via hugevmalloc=on is 
whiteList.


Only parts of our products wants this feature,? we add some interfaces 
which only

alloc hugevmalloc for them, eg, 
vmap_hugepage/vmalloc_hugepage/remap_vmalloc_hugepage_range..

for our products, but it's not the choice of most products, also add 
nohugevmalloc

for most products is expensive, so this is the reason for adding the patch.

more config/cmdline are more flexible for test/products?

>
> The 'nohugevmalloc' option mirrors 'nohugeiomap' and is not expected to
> ever be understood by an administrator unless a kernel developer is
> working with them to hunt down a regression.
>
> IMO there should be no new options. You could switch it off for
> CONFIG_BASE_SMALL perhaps, and otherwise just try to work on heuristics
> first. Bring in new options once it's proven they're needed.

but yes, this patch is optional? could others give some more comments 
about this way?

Thanks.

> Aside from that, thanks for working on these ports, great work.
>
> Thanks,
> Nick
> .


From willy at infradead.org  Wed Jan 19 05:22:04 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 13:22:04 +0000
Subject: [PATCH v2 1/3] mm: vmalloc: Let user to control huge vmalloc
 default behavior
In-Reply-To: <f0dd59eb-6eb8-5b60-508d-7f4022f655ec@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-2-wangkefeng.wang@huawei.com>
 <1642473992.qrnqczjfna.astroid@bobo.none>
 <f0dd59eb-6eb8-5b60-508d-7f4022f655ec@huawei.com>
Message-ID: <YegQfIQibQi993dp@casper.infradead.org>

On Wed, Jan 19, 2022 at 08:57:58PM +0800, Kefeng Wang wrote:
> Only parts of our products wants this feature,? we add some interfaces which
> only
> 
> alloc hugevmalloc for them, eg,
> vmap_hugepage/vmalloc_hugepage/remap_vmalloc_hugepage_range..
> 
> for our products, but it's not the choice of most products, also add
> nohugevmalloc
> 
> for most products is expensive, so this is the reason for adding the patch.
> 
> more config/cmdline are more flexible for test/products?

But why do only some products want it?  What goes wrong if all products
enable it?  Features should be auto-tuning, not relying on admins to
understand them.


From l.stach at pengutronix.de  Wed Jan 19 05:23:48 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:23:48 +0100
Subject: [PATCH] arm64: dts: imx8mp: disable usb3_phy1
Message-ID: <20220119132348.2093807-1-l.stach@pengutronix.de>

Like usb3_phy0 the default state of the usb3_phy1 should be disabled, so
it is only enabled on boards exposing this USB port.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 04d259de5667..4fa8bf93324f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -925,6 +925,7 @@ usb3_phy1: usb-phy at 382f0040 {
 			assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
 			assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
 			#phy-cells = <0>;
+			status = "disabled";
 		};
 
 		usb3_1: usb at 32f10108 {
-- 
2.30.2



From robin.murphy at arm.com  Wed Jan 19 05:28:14 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 19 Jan 2022 13:28:14 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <20220118235244.540103-1-yury.norov@gmail.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
Message-ID: <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>

On 2022-01-18 23:52, Yury Norov wrote:
> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer which would lead to DABT at address translation later.
> 
> Currently, kernel checks the pages against NULL. In my case, however, the
> address was not NULL, and was big enough so that the hardware generated
> Address Size Abort on arm64.
> 
> Interestingly, this abort happens even if copy_from_kernel_nofault() is
> used, which is quite inconvenient for debugging purposes.
> 
> This patch adds a pfn_valid() check into vmap() path, so that invalid
> mapping will not be created.
> 
> RFC: https://lkml.org/lkml/2022/1/18/815
> v1: use pfn_valid() instead of adding an arch-specific
>      arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
> 
> Signed-off-by: Yury Norov <yury.norov at gmail.com>
> ---
>   mm/vmalloc.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index d2a00ad4e1dd..a4134ee56b10 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
>   			return -EBUSY;
>   		if (WARN_ON(!page))
>   			return -ENOMEM;
> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))

Is it page_to_pfn() guaranteed to work without blowing up if page is 
invalid in the first place? Looking at the CONFIG_SPARSEMEM case I'm not 
sure that's true...

Robin.

> +			return -EINVAL;
>   		set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
>   		(*nr)++;
>   	} while (pte++, addr += PAGE_SIZE, addr != end);


From maz at kernel.org  Wed Jan 19 05:31:58 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 19 Jan 2022 13:31:58 +0000
Subject: [PATCH v2 2/4] irqchip/meson-gpio: support more than 8 channels
 gpio irq line
In-Reply-To: <20220119070809.15563-3-qianggui.song@amlogic.com>
References: <20220119070809.15563-1-qianggui.song@amlogic.com>
 <20220119070809.15563-3-qianggui.song@amlogic.com>
Message-ID: <87czkn97ht.wl-maz@kernel.org>

On Wed, 19 Jan 2022 07:08:07 +0000,
Qianggui Song <qianggui.song at amlogic.com> wrote:
> 
> Current meson gpio irqchip driver only support 8 channels for gpio irq
> line, later chips may have more then 8 channels, so need to modify code
> to support more.
> 
> Signed-off-by: Qianggui Song <qianggui.song at amlogic.com>
> ---
>  drivers/irqchip/irq-meson-gpio.c | 33 +++++++++++++++++++++++---------
>  1 file changed, 24 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c
> index d90ff0b92480..eefe15e1b3a6 100644
> --- a/drivers/irqchip/irq-meson-gpio.c
> +++ b/drivers/irqchip/irq-meson-gpio.c
> @@ -16,7 +16,6 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#define NUM_CHANNEL 8
>  #define MAX_INPUT_MUX 256
>  
>  #define REG_EDGE_POL	0x00
> @@ -60,6 +59,7 @@ struct irq_ctl_ops {
>  
>  struct meson_gpio_irq_params {
>  	unsigned int nr_hwirq;
> +	unsigned int nr_channels;
>  	bool support_edge_both;
>  	unsigned int edge_both_offset;
>  	unsigned int edge_single_offset;
> @@ -81,6 +81,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 0,				\
>  	.pol_low_offset = 16,					\
>  	.pin_sel_mask = 0xff,					\
> +	.nr_channels = 8,					\
>  
>  #define INIT_MESON_A1_COMMON_DATA(irqs)				\
>  	INIT_MESON_COMMON(irqs, meson_a1_gpio_irq_init,		\
> @@ -90,6 +91,7 @@ struct meson_gpio_irq_params {
>  	.edge_single_offset = 8,				\
>  	.pol_low_offset = 0,					\
>  	.pin_sel_mask = 0x7f,					\
> +	.nr_channels = 8,					\
>  
>  static const struct meson_gpio_irq_params meson8_params = {
>  	INIT_MESON8_COMMON_DATA(134)
> @@ -136,8 +138,8 @@ static const struct of_device_id meson_irq_gpio_matches[] = {
>  struct meson_gpio_irq_controller {
>  	const struct meson_gpio_irq_params *params;
>  	void __iomem *base;
> -	u32 channel_irqs[NUM_CHANNEL];
> -	DECLARE_BITMAP(channel_map, NUM_CHANNEL);
> +	u32 *channel_irqs;
> +	unsigned long *channel_map;

This really is over-engineering at its best.

With your new fancy HW, you have at most 12 bits being used in this
bitmap. So why not have a single unsigned long, no dynamic allocation,
and simply an assertion somewhere that checks that nr_channel is never
bigger than BITS_PER_LONG? Less code, less memory wasted, less problems.

	M.

-- 
Without deviation from the norm, progress is not possible.


From wangkefeng.wang at huawei.com  Wed Jan 19 05:32:13 2022
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 19 Jan 2022 21:32:13 +0800
Subject: [PATCH v2 3/3] x86: Support huge vmalloc mappings
In-Reply-To: <1642565468.c0jax91tvn.astroid@bobo.none>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-4-wangkefeng.wang@huawei.com>
 <70ff58bc-3a92-55c2-2da8-c5877af72e44@intel.com>
 <3858de1f-cdbc-ff52-2890-4254d0f48b0a@huawei.com>
 <31a75f95-6e6e-b640-2d95-08a95ea8cf51@intel.com>
 <1642472965.lgfksp6krp.astroid@bobo.none>
 <4488d39f-0698-7bfd-b81c-1e609821818f@intel.com>
 <1642565468.c0jax91tvn.astroid@bobo.none>
Message-ID: <e9961fc7-30c7-1b1f-0b38-d23891c60284@huawei.com>


On 2022/1/19 12:17, Nicholas Piggin wrote:
> Excerpts from Dave Hansen's message of January 19, 2022 3:28 am:
>> On 1/17/22 6:46 PM, Nicholas Piggin wrote:
>>>> This all sounds very fragile to me.  Every time a new architecture would
>>>> get added for huge vmalloc() support, the developer needs to know to go
>>>> find that architecture's module_alloc() and add this flag.
>>> This is documented in the Kconfig.
>>>
>>>   #
>>>   #  Archs that select this would be capable of PMD-sized vmaps (i.e.,
>>>   #  arch_vmap_pmd_supported() returns true), and they must make no assumptions
>>>   #  that vmalloc memory is mapped with PAGE_SIZE ptes. The VM_NO_HUGE_VMAP flag
>>>   #  can be used to prohibit arch-specific allocations from using hugepages to
>>>   #  help with this (e.g., modules may require it).
>>>   #
>>>   config HAVE_ARCH_HUGE_VMALLOC
>>>           depends on HAVE_ARCH_HUGE_VMAP
>>>           bool
>>>
>>> Is it really fair to say it's *very* fragile? Surely it's reasonable to
>>> read the (not very long) documentation ad understand the consequences for
>>> the arch code before enabling it.
>> Very fragile or not, I think folks are likely to get it wrong.  It would
>> be nice to have it default *everyone* to safe and slow and make *sure*
> It's not safe to enable though. That's the problem. If it was just
> modules then you'd have a point but it could be anything.
>
>> they go look at the architecture modules code itself before enabling
>> this for modules.
> This is required not just for modules for the whole arch code, it
> has to be looked at and decided this will work.
>
>> Just from that Kconfig text, I don't think I'd know off the top of my
>> head what do do for x86, or what code I needed to go touch.
> You have to make sure arch/x86 makes no assumptions that vmalloc memory
> is backed by PAGE_SIZE ptes. If you can't do that then you shouldn't
> enable the option. The option can not explain it any more because any
> arch could do anything with its mappings. The module code is an example,
> not the recipe.

Hi Nick, Dave and Christophe?thanks for your review,? a little 
confused,?? I think,

1) for ppc/arm64 module_alloc(),? it must set VM_NO_HUGE_VMAP because the

arch's set_memory_* funcitons can only support PAGE_SIZE mapping, due to the

limit of apply_to_page_range().

2) but for x86's module_alloc(), add VM_NO_HUGE_VMAP is to avoid 
fragmentation,

x86's __change_page_attr functions will split the huge mapping. this 
flags is not a must.


and the behavior above occurred when STRICT_MODULE_RWX enabled, so

1) add a unified function to set vm flags(suggested by Dave ) or

2) add vm flags with some comments to per-arch's module_alloc()

are both acceptable, for the way of unified function ,? we could make 
this a default recipe

with STRICT_MODULE_RWX, also make two more vm flags into it, eg,

+unsigned long module_alloc_vm_flags(bool need_flush_reset_perms)
+{
+?????? unsigned long vm_flags = VM_DEFER_KMEMLEAK;
+
+?????? if (need_flush_reset_perms)
+?????????????? vm_flags |= VM_FLUSH_RESET_PERMS;
+?????? /*
+??????? * Modules use a single, large vmalloc(). Different permissions
+??????? * are applied later and will fragment huge mappings or even
+??????? * fails in set_memory_* on some architectures. Avoid using
+??????? * huge pages for modules.
+??????? */
+?????? if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+?????????????? vm_flags |= VM_NO_HUGE_VMAP;
+
+?????? return vm_flags;
+}

then called each arch's module_alloc().

Any suggestion, many thanks.


>
> Thanks,
> Nick
> .


From Jason at zx2c4.com  Wed Jan 19 05:34:27 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 14:34:27 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
 <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
 <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>
 <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>
Message-ID: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>

On Wed, Jan 19, 2022 at 1:19 PM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> I'd prefer it if we could avoid magic #define's like this.

I'll send something that just replaces it with a simple bool.


From l.stach at pengutronix.de  Wed Jan 19 05:40:18 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:18 +0100
Subject: [PATCH 0/9] i.MX8MP power-domains part 1 and GPU support
Message-ID: <20220119134027.2931945-1-l.stach@pengutronix.de>

Hi all,

this series starts adding the power-domain control for the i.MX8MP
SoC. The GPCv2 support is complete (at least from going over the RM,
TF-A and experience with other i.MX8M* SoCs), but not all
power-domains are usable right now. Currently only the HSIO
(USB and PCIe) and GPU power domains are enabled.

Other power domains (MEDIA, VPU, HDMI, AUDIO) can be added when the
blk-ctrl driver support for those domains is ready, which is still
work in progress at the moment. As my priorities are shifting to
other things for a while, I wanted to push out the part that is
usable now and enables more functionality on the i.MX8MP.

Regards,
Lucas

Lucas Stach (9):
  soc: imx: gpcv2: add PGC control register indirection
  dt-bindings: power: add defines for i.MX8MP power domain
  soc: imx: gpcv2: add support for i.MX8MP power domains
  dt-bindings: power: imx8mp: add defines for HSIO blk-ctrl domains
  dt-bindings: soc: add binding for i.MX8MP HSIO blk-ctrl
  soc: imx: add i.MX8MP HSIO blk-ctrl
  arm64: dts: imx8mp: add HSIO power-domains
  arm64: dts: imx8mp: add GPU power domains
  arm64: dts: imx8mp: add GPU nodes

 .../bindings/power/fsl,imx-gpcv2.yaml         |   2 +
 .../soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml     |  78 +++
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 118 ++++-
 drivers/soc/imx/Makefile                      |   1 +
 drivers/soc/imx/gpcv2.c                       | 430 ++++++++++++++++-
 drivers/soc/imx/imx8mp-blk-ctrl.c             | 444 ++++++++++++++++++
 include/dt-bindings/power/imx8mp-power.h      |  35 ++
 7 files changed, 1090 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
 create mode 100644 drivers/soc/imx/imx8mp-blk-ctrl.c
 create mode 100644 include/dt-bindings/power/imx8mp-power.h

-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:22 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:22 +0100
Subject: [PATCH 4/9] dt-bindings: power: imx8mp: add defines for HSIO blk-ctrl
 domains
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-5-l.stach@pengutronix.de>

This adds the defines for the power domains provided by the HSIO
blk-ctrl on the i.MX8MP.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 include/dt-bindings/power/imx8mp-power.h | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/include/dt-bindings/power/imx8mp-power.h b/include/dt-bindings/power/imx8mp-power.h
index 7c67689e4faf..9f90c40a2c6c 100644
--- a/include/dt-bindings/power/imx8mp-power.h
+++ b/include/dt-bindings/power/imx8mp-power.h
@@ -26,4 +26,10 @@
 #define IMX8MP_POWER_DOMAIN_HSIOMIX			17
 #define IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP		18
 
+#define IMX8MP_HSIOBLK_PD_USB				0
+#define IMX8MP_HSIOBLK_PD_USB_PHY1			1
+#define IMX8MP_HSIOBLK_PD_USB_PHY2			2
+#define IMX8MP_HSIOBLK_PD_PCIE				3
+#define IMX8MP_HSIOBLK_PD_PCIE_PHY			4
+
 #endif
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:19 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:19 +0100
Subject: [PATCH 1/9] soc: imx: gpcv2: add PGC control register indirection
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-2-l.stach@pengutronix.de>

The PGC control registers in the shared (not per-PGC) region of the
GPC address space have different offsets on i.MX8MP to make space for
additional interrupt control registers.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/soc/imx/gpcv2.c | 43 ++++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 11 deletions(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index b8d52d8d29db..03d988b900ce 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -184,9 +184,17 @@
 
 #define GPC_PGC_CTRL_PCR		BIT(0)
 
+struct imx_pgc_regs {
+	u16 map;
+	u16 pup;
+	u16 pdn;
+	u16 hsk;
+};
+
 struct imx_pgc_domain {
 	struct generic_pm_domain genpd;
 	struct regmap *regmap;
+	const struct imx_pgc_regs *regs;
 	struct regulator *regulator;
 	struct reset_control *reset;
 	struct clk_bulk_data *clks;
@@ -210,6 +218,7 @@ struct imx_pgc_domain_data {
 	const struct imx_pgc_domain *domains;
 	size_t domains_num;
 	const struct regmap_access_table *reg_access_table;
+	const struct imx_pgc_regs *pgc_regs;
 };
 
 static inline struct imx_pgc_domain *
@@ -249,14 +258,14 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
 
 	if (domain->bits.pxx) {
 		/* request the domain to power up */
-		regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ,
+		regmap_update_bits(domain->regmap, domain->regs->pup,
 				   domain->bits.pxx, domain->bits.pxx);
 		/*
 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
 		 * for PUP_REQ/PDN_REQ bit to be cleared
 		 */
 		ret = regmap_read_poll_timeout(domain->regmap,
-					       GPC_PU_PGC_SW_PUP_REQ, reg_val,
+					       domain->regs->pup, reg_val,
 					       !(reg_val & domain->bits.pxx),
 					       0, USEC_PER_MSEC);
 		if (ret) {
@@ -278,11 +287,11 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd)
 
 	/* request the ADB400 to power up */
 	if (domain->bits.hskreq) {
-		regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
+		regmap_update_bits(domain->regmap, domain->regs->hsk,
 				   domain->bits.hskreq, domain->bits.hskreq);
 
 		/*
-		 * ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK, reg_val,
+		 * ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk, reg_val,
 		 *				  (reg_val & domain->bits.hskack), 0,
 		 *				  USEC_PER_MSEC);
 		 * Technically we need the commented code to wait handshake. But that needs
@@ -329,10 +338,10 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
 
 	/* request the ADB400 to power down */
 	if (domain->bits.hskreq) {
-		regmap_clear_bits(domain->regmap, GPC_PU_PWRHSK,
+		regmap_clear_bits(domain->regmap, domain->regs->hsk,
 				  domain->bits.hskreq);
 
-		ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK,
+		ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk,
 					       reg_val,
 					       !(reg_val & domain->bits.hskack),
 					       0, USEC_PER_MSEC);
@@ -350,14 +359,14 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
 		}
 
 		/* request the domain to power down */
-		regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ,
+		regmap_update_bits(domain->regmap, domain->regs->pdn,
 				   domain->bits.pxx, domain->bits.pxx);
 		/*
 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
 		 * for PUP_REQ/PDN_REQ bit to be cleared
 		 */
 		ret = regmap_read_poll_timeout(domain->regmap,
-					       GPC_PU_PGC_SW_PDN_REQ, reg_val,
+					       domain->regs->pdn, reg_val,
 					       !(reg_val & domain->bits.pxx),
 					       0, USEC_PER_MSEC);
 		if (ret) {
@@ -441,10 +450,18 @@ static const struct regmap_access_table imx7_access_table = {
 	.n_yes_ranges	= ARRAY_SIZE(imx7_yes_ranges),
 };
 
+static const struct imx_pgc_regs imx7_pgc_regs = {
+	.map = GPC_PGC_CPU_MAPPING,
+	.pup = GPC_PU_PGC_SW_PUP_REQ,
+	.pdn = GPC_PU_PGC_SW_PDN_REQ,
+	.hsk = GPC_PU_PWRHSK,
+};
+
 static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
 	.domains = imx7_pgc_domains,
 	.domains_num = ARRAY_SIZE(imx7_pgc_domains),
 	.reg_access_table = &imx7_access_table,
+	.pgc_regs = &imx7_pgc_regs,
 };
 
 static const struct imx_pgc_domain imx8m_pgc_domains[] = {
@@ -613,6 +630,7 @@ static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
 	.domains = imx8m_pgc_domains,
 	.domains_num = ARRAY_SIZE(imx8m_pgc_domains),
 	.reg_access_table = &imx8m_access_table,
+	.pgc_regs = &imx7_pgc_regs,
 };
 
 static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
@@ -802,6 +820,7 @@ static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
 	.domains = imx8mm_pgc_domains,
 	.domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
 	.reg_access_table = &imx8mm_access_table,
+	.pgc_regs = &imx7_pgc_regs,
 };
 
 static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
@@ -867,6 +886,7 @@ static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = {
 	.domains = imx8mn_pgc_domains,
 	.domains_num = ARRAY_SIZE(imx8mn_pgc_domains),
 	.reg_access_table = &imx8mn_access_table,
+	.pgc_regs = &imx7_pgc_regs,
 };
 
 static int imx_pgc_domain_probe(struct platform_device *pdev)
@@ -899,7 +919,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
 	pm_runtime_enable(domain->dev);
 
 	if (domain->bits.map)
-		regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+		regmap_update_bits(domain->regmap, domain->regs->map,
 				   domain->bits.map, domain->bits.map);
 
 	ret = pm_genpd_init(&domain->genpd, NULL, true);
@@ -925,7 +945,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
 	pm_genpd_remove(&domain->genpd);
 out_domain_unmap:
 	if (domain->bits.map)
-		regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+		regmap_update_bits(domain->regmap, domain->regs->map,
 				   domain->bits.map, 0);
 	pm_runtime_disable(domain->dev);
 
@@ -940,7 +960,7 @@ static int imx_pgc_domain_remove(struct platform_device *pdev)
 	pm_genpd_remove(&domain->genpd);
 
 	if (domain->bits.map)
-		regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
+		regmap_update_bits(domain->regmap, domain->regs->map,
 				   domain->bits.map, 0);
 
 	pm_runtime_disable(domain->dev);
@@ -1071,6 +1091,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 
 		domain = pd_pdev->dev.platform_data;
 		domain->regmap = regmap;
+		domain->regs = domain_data->pgc_regs;
 		domain->genpd.power_on  = imx_pgc_power_up;
 		domain->genpd.power_off = imx_pgc_power_down;
 
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:23 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:23 +0100
Subject: [PATCH 5/9] dt-bindings: soc: add binding for i.MX8MP HSIO blk-ctrl
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-6-l.stach@pengutronix.de>

This adds the binding for the HSIO blk-ctrl on the i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 .../soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml     | 78 +++++++++++++++++++
 1 file changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
new file mode 100644
index 000000000000..e9a9e1676142
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MM DISP blk-ctrl
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+description:
+  The i.MX8MP HSIO blk-ctrl is a top-level peripheral providing access to
+  the NoC and ensuring proper power sequencing of the high-speed IO
+  (USB an PCIe) peripherals located in the HSIO domain of the SoC.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx8mp-hsio-blk-ctrl
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  power-domains:
+    minItems: 6
+    maxItems: 6
+
+  power-domain-names:
+    items:
+      - const: bus
+      - const: usb
+      - const: usb-phy1
+      - const: usb-phy2
+      - const: pcie
+      - const: pcie-phy
+
+  clocks:
+    minItems: 2
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: usb
+      - const: pcie
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - power-domain-names
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mp-clock.h>
+    #include <dt-bindings/power/imx8mp-power.h>
+
+    hsio_blk_ctrl: blk-ctrl at 32f10000 {
+        compatible = "fsl,imx8mp-hsio-blk-ctrl", "syscon";
+        reg = <0x32f10000 0x24>;
+        clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+                 <&clk IMX8MP_CLK_PCIE_ROOT>;
+        clock-names = "usb", "pcie";
+        power-domains = <&pgc_hsiomix>, <&pgc_hsiomix>,
+                        <&pgc_usb1_phy>, <&pgc_usb2_phy>,
+                        <&pgc_hsiomix>, <&pgc_pcie_phy>;
+        power-domain-names = "bus", "usb", "usb-phy1",
+                             "usb-phy2", "pcie", "pcie-phy";
+        #power-domain-cells = <1>;
+    };
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:20 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:20 +0100
Subject: [PATCH 2/9] dt-bindings: power: add defines for i.MX8MP power domain
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-3-l.stach@pengutronix.de>

This adds the DT defines for the GPC power domains found on the
i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 .../bindings/power/fsl,imx-gpcv2.yaml         |  2 ++
 include/dt-bindings/power/imx8mp-power.h      | 29 +++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/power/imx8mp-power.h

diff --git a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
index 01bdda167eef..747622bdc57b 100644
--- a/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
+++ b/Documentation/devicetree/bindings/power/fsl,imx-gpcv2.yaml
@@ -28,6 +28,7 @@ properties:
       - fsl,imx8mn-gpc
       - fsl,imx8mq-gpc
       - fsl,imx8mm-gpc
+      - fsl,imx8mp-gpc
 
   reg:
     maxItems: 1
@@ -57,6 +58,7 @@ properties:
               include/dt-bindings/power/imx7-power.h for fsl,imx7d-gpc and
               include/dt-bindings/power/imx8m-power.h for fsl,imx8mq-gpc
               include/dt-bindings/power/imx8mm-power.h for fsl,imx8mm-gpc
+              include/dt-bindings/power/imx8mp-power.h for fsl,imx8mp-gpc
             maxItems: 1
 
           clocks:
diff --git a/include/dt-bindings/power/imx8mp-power.h b/include/dt-bindings/power/imx8mp-power.h
new file mode 100644
index 000000000000..7c67689e4faf
--- /dev/null
+++ b/include/dt-bindings/power/imx8mp-power.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ *  Copyright (C) 2020 Pengutronix, Sascha Hauer <kernel at pengutronix.de>
+ */
+
+#ifndef __DT_BINDINGS_IMX8MP_POWER_DOMAIN_POWER_H__
+#define __DT_BINDINGS_IMX8MP_POWER_DOMAIN_POWER_H__
+
+#define IMX8MP_POWER_DOMAIN_MIPI_PHY1			0
+#define IMX8MP_POWER_DOMAIN_PCIE_PHY			1
+#define IMX8MP_POWER_DOMAIN_USB1_PHY			2
+#define IMX8MP_POWER_DOMAIN_USB2_PHY			3
+#define IMX8MP_POWER_DOMAIN_MLMIX			4
+#define IMX8MP_POWER_DOMAIN_AUDIOMIX			5
+#define IMX8MP_POWER_DOMAIN_GPU2D			6
+#define IMX8MP_POWER_DOMAIN_GPUMIX			7
+#define IMX8MP_POWER_DOMAIN_VPUMIX			8
+#define IMX8MP_POWER_DOMAIN_GPU3D			9
+#define IMX8MP_POWER_DOMAIN_MEDIAMIX			10
+#define IMX8MP_POWER_DOMAIN_VPU_G1			11
+#define IMX8MP_POWER_DOMAIN_VPU_G2			12
+#define IMX8MP_POWER_DOMAIN_VPU_VC8000E			13
+#define IMX8MP_POWER_DOMAIN_HDMIMIX			14
+#define IMX8MP_POWER_DOMAIN_HDMI_PHY			15
+#define IMX8MP_POWER_DOMAIN_MIPI_PHY2			16
+#define IMX8MP_POWER_DOMAIN_HSIOMIX			17
+#define IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP		18
+
+#endif
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:21 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:21 +0100
Subject: [PATCH 3/9] soc: imx: gpcv2: add support for i.MX8MP power domains
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-4-l.stach@pengutronix.de>

This adds driver support for all the GPC power domains found on
the i.MX8MP SoC.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/soc/imx/gpcv2.c | 387 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 386 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
index 03d988b900ce..736160a7882a 100644
--- a/drivers/soc/imx/gpcv2.c
+++ b/drivers/soc/imx/gpcv2.c
@@ -21,10 +21,12 @@
 #include <dt-bindings/power/imx8mq-power.h>
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
+#include <dt-bindings/power/imx8mp-power.h>
 
 #define GPC_LPCR_A_CORE_BSC			0x000
 
 #define GPC_PGC_CPU_MAPPING		0x0ec
+#define IMX8MP_GPC_PGC_CPU_MAPPING	0x1cc
 
 #define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN		BIT(6)
 #define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN		BIT(5)
@@ -65,6 +67,29 @@
 #define IMX8MN_OTG1_A53_DOMAIN		BIT(4)
 #define IMX8MN_MIPI_A53_DOMAIN		BIT(2)
 
+#define IMX8MP_MEDIA_ISPDWP_A53_DOMAIN	BIT(20)
+#define IMX8MP_HSIOMIX_A53_DOMAIN		BIT(19)
+#define IMX8MP_MIPI_PHY2_A53_DOMAIN		BIT(18)
+#define IMX8MP_HDMI_PHY_A53_DOMAIN		BIT(17)
+#define IMX8MP_HDMIMIX_A53_DOMAIN		BIT(16)
+#define IMX8MP_VPU_VC8000E_A53_DOMAIN		BIT(15)
+#define IMX8MP_VPU_G2_A53_DOMAIN		BIT(14)
+#define IMX8MP_VPU_G1_A53_DOMAIN		BIT(13)
+#define IMX8MP_MEDIAMIX_A53_DOMAIN		BIT(12)
+#define IMX8MP_GPU3D_A53_DOMAIN			BIT(11)
+#define IMX8MP_VPUMIX_A53_DOMAIN		BIT(10)
+#define IMX8MP_GPUMIX_A53_DOMAIN		BIT(9)
+#define IMX8MP_GPU2D_A53_DOMAIN			BIT(8)
+#define IMX8MP_AUDIOMIX_A53_DOMAIN		BIT(7)
+#define IMX8MP_MLMIX_A53_DOMAIN			BIT(6)
+#define IMX8MP_USB2_PHY_A53_DOMAIN		BIT(5)
+#define IMX8MP_USB1_PHY_A53_DOMAIN		BIT(4)
+#define IMX8MP_PCIE_PHY_A53_DOMAIN		BIT(3)
+#define IMX8MP_MIPI_PHY1_A53_DOMAIN		BIT(2)
+
+#define IMX8MP_GPC_PU_PGC_SW_PUP_REQ	0x0d8
+#define IMX8MP_GPC_PU_PGC_SW_PDN_REQ	0x0e4
+
 #define GPC_PU_PGC_SW_PUP_REQ		0x0f8
 #define GPC_PU_PGC_SW_PDN_REQ		0x104
 
@@ -107,8 +132,30 @@
 #define IMX8MN_OTG1_SW_Pxx_REQ		BIT(2)
 #define IMX8MN_MIPI_SW_Pxx_REQ		BIT(0)
 
+#define IMX8MP_DDRMIX_Pxx_REQ			BIT(19)
+#define IMX8MP_MEDIA_ISP_DWP_Pxx_REQ		BIT(18)
+#define IMX8MP_HSIOMIX_Pxx_REQ			BIT(17)
+#define IMX8MP_MIPI_PHY2_Pxx_REQ		BIT(16)
+#define IMX8MP_HDMI_PHY_Pxx_REQ			BIT(15)
+#define IMX8MP_HDMIMIX_Pxx_REQ			BIT(14)
+#define IMX8MP_VPU_VC8K_Pxx_REQ			BIT(13)
+#define IMX8MP_VPU_G2_Pxx_REQ			BIT(12)
+#define IMX8MP_VPU_G1_Pxx_REQ			BIT(11)
+#define IMX8MP_MEDIMIX_Pxx_REQ			BIT(10)
+#define IMX8MP_GPU_3D_Pxx_REQ			BIT(9)
+#define IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ	BIT(8)
+#define IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ		BIT(7)
+#define IMX8MP_GPU_2D_Pxx_REQ			BIT(6)
+#define IMX8MP_AUDIOMIX_Pxx_REQ			BIT(5)
+#define IMX8MP_MLMIX_Pxx_REQ			BIT(4)
+#define IMX8MP_USB2_PHY_Pxx_REQ			BIT(3)
+#define IMX8MP_USB1_PHY_Pxx_REQ			BIT(2)
+#define IMX8MP_PCIE_PHY_SW_Pxx_REQ		BIT(1)
+#define IMX8MP_MIPI_PHY1_SW_Pxx_REQ		BIT(0)
+
 #define GPC_M4_PU_PDN_FLG		0x1bc
 
+#define IMX8MP_GPC_PU_PWRHSK		0x190
 #define GPC_PU_PWRHSK			0x1fc
 
 #define IMX8M_GPU_HSK_PWRDNACKN			BIT(26)
@@ -118,7 +165,6 @@
 #define IMX8M_VPU_HSK_PWRDNREQN			BIT(5)
 #define IMX8M_DISP_HSK_PWRDNREQN		BIT(4)
 
-
 #define IMX8MM_GPUMIX_HSK_PWRDNACKN		BIT(29)
 #define IMX8MM_GPU_HSK_PWRDNACKN		(BIT(27) | BIT(28))
 #define IMX8MM_VPUMIX_HSK_PWRDNACKN		BIT(26)
@@ -137,6 +183,21 @@
 #define IMX8MN_DISPMIX_HSK_PWRDNREQN		BIT(7)
 #define IMX8MN_HSIO_HSK_PWRDNREQN		BIT(5)
 
+#define IMX8MP_MEDIAMIX_PWRDNACKN		BIT(3)
+#define IMX8MP_HDMIMIX_PWRDNACKN		BIT(29)
+#define IMX8MP_HSIOMIX_PWRDNACKN		BIT(28)
+#define IMX8MP_VPUMIX_PWRDNACKN			BIT(26)
+#define IMX8MP_GPUMIX_PWRDNACKN			BIT(25)
+#define IMX8MP_MLMIX_PWRDNACKN			(BIT(23) | BIT(24))
+#define IMX8MP_AUDIOMIX_PWRDNACKN		(BIT(20) | BIT(31))
+#define IMX8MP_MEDIAMIX_PWRDNREQN		BIT(14)
+#define IMX8MP_HDMIMIX_PWRDNREQN		BIT(13)
+#define IMX8MP_HSIOMIX_PWRDNREQN		BIT(12)
+#define IMX8MP_VPUMIX_PWRDNREQN			BIT(10)
+#define IMX8MP_GPUMIX_PWRDNREQN			BIT(9)
+#define IMX8MP_MLMIX_PWRDNREQN			(BIT(7) | BIT(8))
+#define IMX8MP_AUDIOMIX_PWRDNREQN		(BIT(4) | BIT(15))
+
 /*
  * The PGC offset values in Reference Manual
  * (Rev. 1, 01/2018 and the older ones) GPC chapter's
@@ -179,6 +240,28 @@
 #define IMX8MN_PGC_GPUMIX		23
 #define IMX8MN_PGC_DISPMIX		26
 
+#define IMX8MP_PGC_NOC			9
+#define IMX8MP_PGC_MIPI1		12
+#define IMX8MP_PGC_PCIE			13
+#define IMX8MP_PGC_USB1			14
+#define IMX8MP_PGC_USB2			15
+#define IMX8MP_PGC_MLMIX		16
+#define IMX8MP_PGC_AUDIOMIX		17
+#define IMX8MP_PGC_GPU2D		18
+#define IMX8MP_PGC_GPUMIX		19
+#define IMX8MP_PGC_VPUMIX		20
+#define IMX8MP_PGC_GPU3D		21
+#define IMX8MP_PGC_MEDIAMIX		22
+#define IMX8MP_PGC_VPU_G1		23
+#define IMX8MP_PGC_VPU_G2		24
+#define IMX8MP_PGC_VPU_VC8000E		25
+#define IMX8MP_PGC_HDMIMIX		26
+#define IMX8MP_PGC_HDMI			27
+#define IMX8MP_PGC_MIPI2		28
+#define IMX8MP_PGC_HSIOMIX		29
+#define IMX8MP_PGC_MEDIA_ISP_DWP	30
+#define IMX8MP_PGC_DDRMIX		31
+
 #define GPC_PGC_CTRL(n)			(0x800 + (n) * 0x40)
 #define GPC_PGC_SR(n)			(GPC_PGC_CTRL(n) + 0xc)
 
@@ -212,6 +295,9 @@ struct imx_pgc_domain {
 	const int voltage;
 	const bool keep_clocks;
 	struct device *dev;
+
+	unsigned int pgc_sw_pup_reg;
+	unsigned int pgc_sw_pdn_reg;
 };
 
 struct imx_pgc_domain_data {
@@ -823,6 +909,303 @@ static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
 	.pgc_regs = &imx7_pgc_regs,
 };
 
+static const struct imx_pgc_domain imx8mp_pgc_domains[] = {
+	[IMX8MP_POWER_DOMAIN_MIPI_PHY1] = {
+		.genpd = {
+			.name = "mipi-phy1",
+		},
+		.bits = {
+			.pxx = IMX8MP_MIPI_PHY1_SW_Pxx_REQ,
+			.map = IMX8MP_MIPI_PHY1_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_MIPI1),
+	},
+
+	[IMX8MP_POWER_DOMAIN_PCIE_PHY] = {
+		.genpd = {
+			.name = "pcie-phy1",
+		},
+		.bits = {
+			.pxx = IMX8MP_PCIE_PHY_SW_Pxx_REQ,
+			.map = IMX8MP_PCIE_PHY_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_PCIE),
+	},
+
+	[IMX8MP_POWER_DOMAIN_USB1_PHY] = {
+		.genpd = {
+			.name = "usb-otg1",
+		},
+		.bits = {
+			.pxx = IMX8MP_USB1_PHY_Pxx_REQ,
+			.map = IMX8MP_USB1_PHY_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_USB1),
+	},
+
+	[IMX8MP_POWER_DOMAIN_USB2_PHY] = {
+		.genpd = {
+			.name = "usb-otg2",
+		},
+		.bits = {
+			.pxx = IMX8MP_USB2_PHY_Pxx_REQ,
+			.map = IMX8MP_USB2_PHY_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_USB2),
+	},
+
+	[IMX8MP_POWER_DOMAIN_MLMIX] = {
+		.genpd = {
+			.name = "mlmix",
+		},
+		.bits = {
+			.pxx = IMX8MP_MLMIX_Pxx_REQ,
+			.map = IMX8MP_MLMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_MLMIX_PWRDNREQN,
+			.hskack = IMX8MP_MLMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_MLMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_AUDIOMIX] = {
+		.genpd = {
+			.name = "audiomix",
+		},
+		.bits = {
+			.pxx = IMX8MP_AUDIOMIX_Pxx_REQ,
+			.map = IMX8MP_AUDIOMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_AUDIOMIX_PWRDNREQN,
+			.hskack = IMX8MP_AUDIOMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_AUDIOMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_GPU2D] = {
+		.genpd = {
+			.name = "gpu2d",
+		},
+		.bits = {
+			.pxx = IMX8MP_GPU_2D_Pxx_REQ,
+			.map = IMX8MP_GPU2D_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_GPU2D),
+	},
+
+	[IMX8MP_POWER_DOMAIN_GPUMIX] = {
+		.genpd = {
+			.name = "gpumix",
+		},
+		.bits = {
+			.pxx = IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ,
+			.map = IMX8MP_GPUMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_GPUMIX_PWRDNREQN,
+			.hskack = IMX8MP_GPUMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_GPUMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_VPUMIX] = {
+		.genpd = {
+			.name = "vpumix",
+		},
+		.bits = {
+			.pxx = IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ,
+			.map = IMX8MP_VPUMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_VPUMIX_PWRDNREQN,
+			.hskack = IMX8MP_VPUMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_VPUMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_GPU3D] = {
+		.genpd = {
+			.name = "gpu3d",
+		},
+		.bits = {
+			.pxx = IMX8MP_GPU_3D_Pxx_REQ,
+			.map = IMX8MP_GPU3D_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_GPU3D),
+	},
+
+	[IMX8MP_POWER_DOMAIN_MEDIAMIX] = {
+		.genpd = {
+			.name = "mediamix",
+		},
+		.bits = {
+			.pxx = IMX8MP_MEDIMIX_Pxx_REQ,
+			.map = IMX8MP_MEDIAMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_MEDIAMIX_PWRDNREQN,
+			.hskack = IMX8MP_MEDIAMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_MEDIAMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_VPU_G1] = {
+		.genpd = {
+			.name = "vpu-g1",
+		},
+		.bits = {
+			.pxx = IMX8MP_VPU_G1_Pxx_REQ,
+			.map = IMX8MP_VPU_G1_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_VPU_G1),
+	},
+
+	[IMX8MP_POWER_DOMAIN_VPU_G2] = {
+		.genpd = {
+			.name = "vpu-g2",
+		},
+		.bits = {
+			.pxx = IMX8MP_VPU_G2_Pxx_REQ,
+			.map = IMX8MP_VPU_G2_A53_DOMAIN
+		},
+		.pgc = BIT(IMX8MP_PGC_VPU_G2),
+	},
+
+	[IMX8MP_POWER_DOMAIN_VPU_VC8000E] = {
+		.genpd = {
+			.name = "vpu-h1",
+		},
+		.bits = {
+			.pxx = IMX8MP_VPU_VC8K_Pxx_REQ,
+			.map = IMX8MP_VPU_VC8000E_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_VPU_VC8000E),
+	},
+
+	[IMX8MP_POWER_DOMAIN_HDMIMIX] = {
+		.genpd = {
+			.name = "hdmimix",
+		},
+		.bits = {
+			.pxx = IMX8MP_HDMIMIX_Pxx_REQ,
+			.map = IMX8MP_HDMIMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_HDMIMIX_PWRDNREQN,
+			.hskack = IMX8MP_HDMIMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_HDMIMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_HDMI_PHY] = {
+		.genpd = {
+			.name = "hdmi-phy",
+		},
+		.bits = {
+			.pxx = IMX8MP_HDMI_PHY_Pxx_REQ,
+			.map = IMX8MP_HDMI_PHY_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_HDMI),
+	},
+
+	[IMX8MP_POWER_DOMAIN_MIPI_PHY2] = {
+		.genpd = {
+			.name = "mipi-phy2",
+		},
+		.bits = {
+			.pxx = IMX8MP_MIPI_PHY2_Pxx_REQ,
+			.map = IMX8MP_MIPI_PHY2_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_MIPI2),
+	},
+
+	[IMX8MP_POWER_DOMAIN_HSIOMIX] = {
+		.genpd = {
+			.name = "hsiomix",
+		},
+		.bits = {
+			.pxx = IMX8MP_HSIOMIX_Pxx_REQ,
+			.map = IMX8MP_HSIOMIX_A53_DOMAIN,
+			.hskreq = IMX8MP_HSIOMIX_PWRDNREQN,
+			.hskack = IMX8MP_HSIOMIX_PWRDNACKN,
+		},
+		.pgc = BIT(IMX8MP_PGC_HSIOMIX),
+		.keep_clocks = true,
+	},
+
+	[IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP] = {
+		.genpd = {
+			.name = "mediamix-isp-dwp",
+		},
+		.bits = {
+			.pxx = IMX8MP_MEDIA_ISP_DWP_Pxx_REQ,
+			.map = IMX8MP_MEDIA_ISPDWP_A53_DOMAIN,
+		},
+		.pgc = BIT(IMX8MP_PGC_MEDIA_ISP_DWP),
+	},
+};
+
+static const struct regmap_range imx8mp_yes_ranges[] = {
+		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
+				 IMX8MP_GPC_PGC_CPU_MAPPING),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_NOC),
+				 GPC_PGC_SR(IMX8MP_PGC_NOC)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI1),
+				 GPC_PGC_SR(IMX8MP_PGC_MIPI1)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_PCIE),
+				 GPC_PGC_SR(IMX8MP_PGC_PCIE)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB1),
+				 GPC_PGC_SR(IMX8MP_PGC_USB1)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB2),
+				 GPC_PGC_SR(IMX8MP_PGC_USB2)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MLMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_MLMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_AUDIOMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_AUDIOMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU2D),
+				 GPC_PGC_SR(IMX8MP_PGC_GPU2D)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPUMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_GPUMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPUMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_VPUMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU3D),
+				 GPC_PGC_SR(IMX8MP_PGC_GPU3D)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIAMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_MEDIAMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G1),
+				 GPC_PGC_SR(IMX8MP_PGC_VPU_G1)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G2),
+				 GPC_PGC_SR(IMX8MP_PGC_VPU_G2)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_VC8000E),
+				 GPC_PGC_SR(IMX8MP_PGC_VPU_VC8000E)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMIMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_HDMIMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMI),
+				 GPC_PGC_SR(IMX8MP_PGC_HDMI)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI2),
+				 GPC_PGC_SR(IMX8MP_PGC_MIPI2)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HSIOMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_HSIOMIX)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIA_ISP_DWP),
+				 GPC_PGC_SR(IMX8MP_PGC_MEDIA_ISP_DWP)),
+		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_DDRMIX),
+				 GPC_PGC_SR(IMX8MP_PGC_DDRMIX)),
+};
+
+static const struct regmap_access_table imx8mp_access_table = {
+	.yes_ranges	= imx8mp_yes_ranges,
+	.n_yes_ranges	= ARRAY_SIZE(imx8mp_yes_ranges),
+};
+
+static const struct imx_pgc_regs imx8mp_pgc_regs = {
+	.map = IMX8MP_GPC_PGC_CPU_MAPPING,
+	.pup = IMX8MP_GPC_PU_PGC_SW_PUP_REQ,
+	.pdn = IMX8MP_GPC_PU_PGC_SW_PDN_REQ,
+	.hsk = IMX8MP_GPC_PU_PWRHSK,
+};
+static const struct imx_pgc_domain_data imx8mp_pgc_domain_data = {
+	.domains = imx8mp_pgc_domains,
+	.domains_num = ARRAY_SIZE(imx8mp_pgc_domains),
+	.reg_access_table = &imx8mp_access_table,
+	.pgc_regs = &imx8mp_pgc_regs,
+};
+
 static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
 	[IMX8MN_POWER_DOMAIN_HSIOMIX] = {
 		.genpd = {
@@ -1092,6 +1475,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 		domain = pd_pdev->dev.platform_data;
 		domain->regmap = regmap;
 		domain->regs = domain_data->pgc_regs;
+
 		domain->genpd.power_on  = imx_pgc_power_up;
 		domain->genpd.power_off = imx_pgc_power_down;
 
@@ -1113,6 +1497,7 @@ static const struct of_device_id imx_gpcv2_dt_ids[] = {
 	{ .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
 	{ .compatible = "fsl,imx8mm-gpc", .data = &imx8mm_pgc_domain_data, },
 	{ .compatible = "fsl,imx8mn-gpc", .data = &imx8mn_pgc_domain_data, },
+	{ .compatible = "fsl,imx8mp-gpc", .data = &imx8mp_pgc_domain_data, },
 	{ .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
 	{ }
 };
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:27 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:27 +0100
Subject: [PATCH 9/9] arm64: dts: imx8mp: add GPU nodes
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-10-l.stach@pengutronix.de>

Add the DT nodes for both the 3D and 2D GPU cores found on the i.MX8MP.

etnaviv-gpu 38000000.gpu: model: GC7000, revision: 6204
etnaviv-gpu 38008000.gpu: model: GC520, revision: 5341
[drm] Initialized etnaviv 1.3.0 20151214 for etnaviv on minor 0

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 31 +++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index fa9dca7acc94..67cc837058d1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -922,6 +922,37 @@ eqos: ethernet at 30bf0000 {
 			};
 		};
 
+		gpu3d: gpu at 38000000 {
+			compatible = "vivante,gc";
+			reg = <0x38000000 0x8000>;
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MP_CLK_GPU3D_CORE>,
+				 <&clk IMX8MP_CLK_GPU3D_SHADER_CORE>,
+				 <&clk IMX8MP_CLK_GPU_ROOT>,
+				 <&clk IMX8MP_CLK_GPU_AHB>;
+			clock-names = "core", "shader", "bus", "reg";
+			assigned-clocks = <&clk IMX8MP_CLK_GPU3D_CORE>,
+					  <&clk IMX8MP_CLK_GPU3D_SHADER_CORE>;
+			assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+						 <&clk IMX8MP_SYS_PLL1_800M>;
+			assigned-clock-rates = <800000000>, <800000000>;
+			power-domains = <&pgc_gpu3d>;
+		};
+
+		gpu2d: gpu at 38008000 {
+			compatible = "vivante,gc";
+			reg = <0x38008000 0x8000>;
+			interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MP_CLK_GPU2D_CORE>,
+				 <&clk IMX8MP_CLK_GPU_ROOT>,
+				 <&clk IMX8MP_CLK_GPU_AHB>;
+			clock-names = "core", "bus", "reg";
+			assigned-clocks = <&clk IMX8MP_CLK_GPU2D_CORE>;
+			assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>;
+			assigned-clock-rates = <800000000>;
+			power-domains = <&pgc_gpu2d>;
+		};
+
 		gic: interrupt-controller at 38800000 {
 			compatible = "arm,gic-v3";
 			reg = <0x38800000 0x10000>,
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:26 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:26 +0100
Subject: [PATCH 8/9] arm64: dts: imx8mp: add GPU power domains
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-9-l.stach@pengutronix.de>

Add the power domains for the GPUs, which do not require any interaction with
a blk-ctrl, but are simply two PU domains nested inside a MIX domain.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 24 +++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index b76af96b9b5c..fa9dca7acc94 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -471,6 +471,30 @@ pgc_usb2_phy: power-domain at 3 {
 						reg = <IMX8MP_POWER_DOMAIN_USB2_PHY>;
 					};
 
+					pgc_gpu2d: power-domain at 6 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_GPU2D>;
+						power-domains = <&pgc_gpumix>;
+					};
+
+					pgc_gpumix: power-domain at 7 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_GPUMIX>;
+						clocks = <&clk IMX8MP_CLK_GPU_ROOT>,
+							 <&clk IMX8MP_CLK_GPU_AHB>;
+						assigned-clocks = <&clk IMX8MP_CLK_GPU_AXI>,
+								  <&clk IMX8MP_CLK_GPU_AHB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+									 <&clk IMX8MP_SYS_PLL1_800M>;
+						assigned-clock-rates = <800000000>, <400000000>;
+					};
+
+					pgc_gpu3d: power-domain at 9 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_GPU3D>;
+						power-domains = <&pgc_gpumix>;
+					};
+
 					pgc_hsiomix: power-domains at 17 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:25 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:25 +0100
Subject: [PATCH 7/9] arm64: dts: imx8mp: add HSIO power-domains
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-8-l.stach@pengutronix.de>

This adds the GPC and HSIO blk-ctrl nodes providing power control for
the high-speed (USB and PCIe) IOs.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 63 ++++++++++++++++++++---
 1 file changed, 57 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 04d259de5667..b76af96b9b5c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx8mp-clock.h>
+#include <dt-bindings/power/imx8mp-power.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
@@ -443,6 +444,44 @@ src: reset-controller at 30390000 {
 				interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 				#reset-cells = <1>;
 			};
+
+			gpc: gpc at 303a0000 {
+				compatible = "fsl,imx8mp-gpc";
+				reg = <0x303a0000 0x10000>;
+				interrupt-parent = <&gic>;
+				interrupt-controller;
+				#interrupt-cells = <3>;
+
+				pgc {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					pgc_pcie_phy: power-domain at 1 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_PCIE_PHY>;
+					};
+
+					pgc_usb1_phy: power-domain at 2 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_USB1_PHY>;
+					};
+
+					pgc_usb2_phy: power-domain at 3 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_USB2_PHY>;
+					};
+
+					pgc_hsiomix: power-domains at 17 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
+						clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
+							 <&clk IMX8MP_CLK_HSIO_ROOT>;
+						assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+						assigned-clock-rates = <500000000>;
+					};
+				};
+			};
 		};
 
 		aips2: bus at 30400000 {
@@ -875,6 +914,20 @@ ddr-pmu at 3d800000 {
 			interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		hsio_blk_ctrl: blk-ctrl at 32f10000 {
+			compatible = "fsl,imx8mp-hsio-blk-ctrl", "syscon";
+			reg = <0x32f10000 0x24>;
+			clocks = <&clk IMX8MP_CLK_USB_ROOT>,
+				 <&clk IMX8MP_CLK_PCIE_ROOT>;
+			clock-names = "usb", "pcie";
+			power-domains = <&pgc_hsiomix>, <&pgc_hsiomix>,
+					<&pgc_usb1_phy>, <&pgc_usb2_phy>,
+					<&pgc_hsiomix>, <&pgc_pcie_phy>;
+			power-domain-names = "bus", "usb", "usb-phy1",
+					     "usb-phy2", "pcie", "pcie-phy";
+			#power-domain-cells = <1>;
+		};
+
 		usb3_phy0: usb-phy at 381f0040 {
 			compatible = "fsl,imx8mp-usb-phy";
 			reg = <0x381f0040 0x40>;
@@ -882,6 +935,7 @@ usb3_phy0: usb-phy at 381f0040 {
 			clock-names = "phy";
 			assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
 			assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+			power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB_PHY1>;
 			#phy-cells = <0>;
 			status = "disabled";
 		};
@@ -893,6 +947,7 @@ usb3_0: usb at 32f10100 {
 				 <&clk IMX8MP_CLK_USB_ROOT>;
 			clock-names = "hsio", "suspend";
 			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			dma-ranges = <0x40000000 0x40000000 0xc0000000>;
@@ -906,9 +961,6 @@ usb_dwc3_0: usb at 38100000 {
 					 <&clk IMX8MP_CLK_USB_CORE_REF>,
 					 <&clk IMX8MP_CLK_USB_ROOT>;
 				clock-names = "bus_early", "ref", "suspend";
-				assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
-				assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
-				assigned-clock-rates = <500000000>;
 				interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&usb3_phy0>, <&usb3_phy0>;
 				phy-names = "usb2-phy", "usb3-phy";
@@ -924,6 +976,7 @@ usb3_phy1: usb-phy at 382f0040 {
 			clock-names = "phy";
 			assigned-clocks = <&clk IMX8MP_CLK_USB_PHY_REF>;
 			assigned-clock-parents = <&clk IMX8MP_CLK_24M>;
+			power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB_PHY2>;
 			#phy-cells = <0>;
 		};
 
@@ -934,6 +987,7 @@ usb3_1: usb at 32f10108 {
 				 <&clk IMX8MP_CLK_USB_ROOT>;
 			clock-names = "hsio", "suspend";
 			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 			dma-ranges = <0x40000000 0x40000000 0xc0000000>;
@@ -947,9 +1001,6 @@ usb_dwc3_1: usb at 38200000 {
 					 <&clk IMX8MP_CLK_USB_CORE_REF>,
 					 <&clk IMX8MP_CLK_USB_ROOT>;
 				clock-names = "bus_early", "ref", "suspend";
-				assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
-				assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
-				assigned-clock-rates = <500000000>;
 				interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&usb3_phy1>, <&usb3_phy1>;
 				phy-names = "usb2-phy", "usb3-phy";
-- 
2.30.2



From l.stach at pengutronix.de  Wed Jan 19 05:40:24 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 14:40:24 +0100
Subject: [PATCH 6/9] soc: imx: add i.MX8MP HSIO blk-ctrl
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <20220119134027.2931945-7-l.stach@pengutronix.de>

The i.MX8MP added some blk-ctrl peripherals that don't follow the regular
structure of the blk-ctrls in the previous SoCs. Add a new file for those
with currently only the HSIO blk-ctrl being supported. Others will be added
later on.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/soc/imx/Makefile          |   1 +
 drivers/soc/imx/imx8mp-blk-ctrl.c | 444 ++++++++++++++++++++++++++++++
 2 files changed, 445 insertions(+)
 create mode 100644 drivers/soc/imx/imx8mp-blk-ctrl.c

diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 8a707077914c..63cd29f6d4d2 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
 obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
 obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
+obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o
diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c
new file mode 100644
index 000000000000..7f4e1a151d2b
--- /dev/null
+++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/clk.h>
+
+#include <dt-bindings/power/imx8mp-power.h>
+
+#define GPR_REG0		0x0
+#define  PCIE_CLOCK_MODULE_EN	BIT(0)
+#define  USB_CLOCK_MODULE_EN	BIT(1)
+
+struct imx8mp_hsio_blk_ctrl_domain;
+
+struct imx8mp_hsio_blk_ctrl {
+	struct device *dev;
+	struct notifier_block power_nb;
+	struct device *bus_power_dev;
+	struct regmap *regmap;
+	struct imx8mp_hsio_blk_ctrl_domain *domains;
+	struct genpd_onecell_data onecell_data;
+};
+
+struct imx8mp_hsio_blk_ctrl_domain_data {
+	const char *name;
+	const char *clk_name;
+	const char *gpc_name;
+};
+
+struct imx8mp_hsio_blk_ctrl_domain {
+	struct generic_pm_domain genpd;
+	struct clk *clk;
+	struct device *power_dev;
+	struct imx8mp_hsio_blk_ctrl *bc;
+	int id;
+};
+
+static inline struct imx8mp_hsio_blk_ctrl_domain *
+to_imx8mp_hsio_blk_ctrl_domain(struct generic_pm_domain *genpd)
+{
+	return container_of(genpd, struct imx8mp_hsio_blk_ctrl_domain, genpd);
+}
+
+static int imx8mp_hsio_blk_ctrl_power_on(struct generic_pm_domain *genpd)
+{
+	struct imx8mp_hsio_blk_ctrl_domain *domain =
+			to_imx8mp_hsio_blk_ctrl_domain(genpd);
+	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
+	int ret;
+
+	/* make sure bus domain is awake */
+	ret = pm_runtime_get_sync(bc->bus_power_dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(bc->bus_power_dev);
+		dev_err(bc->dev, "failed to power up bus domain\n");
+		return ret;
+	}
+
+	/* enable upstream and blk-ctrl clocks */
+	ret = clk_prepare_enable(domain->clk);
+	if (ret) {
+		dev_err(bc->dev, "failed to enable clocks\n");
+		goto bus_put;
+	}
+
+	switch (domain->id) {
+	case IMX8MP_HSIOBLK_PD_USB:
+		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
+		break;
+	case IMX8MP_HSIOBLK_PD_PCIE:
+		regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
+		break;
+	default:
+		break;
+	}
+
+	/* power up upstream GPC domain */
+	ret = pm_runtime_get_sync(domain->power_dev);
+	if (ret < 0) {
+		dev_err(bc->dev, "failed to power up peripheral domain\n");
+		goto clk_disable;
+	}
+
+	return 0;
+
+clk_disable:
+	clk_disable_unprepare(domain->clk);
+bus_put:
+	pm_runtime_put(bc->bus_power_dev);
+
+	return ret;
+}
+
+static int imx8mp_hsio_blk_ctrl_power_off(struct generic_pm_domain *genpd)
+{
+	struct imx8mp_hsio_blk_ctrl_domain *domain =
+			to_imx8mp_hsio_blk_ctrl_domain(genpd);
+	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
+
+	/* disable clocks */
+	switch (domain->id) {
+	case IMX8MP_HSIOBLK_PD_USB:
+		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
+		break;
+	case IMX8MP_HSIOBLK_PD_PCIE:
+		regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
+		break;
+	default:
+		break;
+	}
+
+	clk_disable_unprepare(domain->clk);
+
+	/* power down upstream GPC domain */
+	pm_runtime_put(domain->power_dev);
+
+	/* allow bus domain to suspend */
+	pm_runtime_put(bc->bus_power_dev);
+
+	return 0;
+}
+
+static struct generic_pm_domain *
+imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
+{
+	struct genpd_onecell_data *onecell_data = data;
+	unsigned int index = args->args[0];
+
+	if (args->args_count != 1 ||
+	    index >= onecell_data->num_domains)
+		return ERR_PTR(-EINVAL);
+
+	return onecell_data->domains[index];
+}
+
+static struct lock_class_key blk_ctrl_genpd_lock_class;
+
+static const struct imx8mp_hsio_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
+	[IMX8MP_HSIOBLK_PD_USB] = {
+		.name = "hsioblk-usb",
+		.clk_name = "usb",
+		.gpc_name = "usb",
+	},
+	[IMX8MP_HSIOBLK_PD_USB_PHY1] = {
+		.name = "hsioblk-ubs-phy1",
+		.gpc_name = "usb-phy1",
+	},
+	[IMX8MP_HSIOBLK_PD_USB_PHY2] = {
+		.name = "hsioblk-ubs-phy2",
+		.gpc_name = "usb-phy2",
+	},
+	[IMX8MP_HSIOBLK_PD_PCIE] = {
+		.name = "hsioblk-pcie",
+		.clk_name = "pcie",
+		.gpc_name = "pcie",
+	},
+	[IMX8MP_HSIOBLK_PD_PCIE_PHY] = {
+		.name = "hsioblk-pcie-phy",
+		.gpc_name = "pcie-phy",
+	},
+};
+
+static int imx8mp_hsio_power_notifier(struct notifier_block *nb,
+				      unsigned long action, void *data)
+{
+	struct imx8mp_hsio_blk_ctrl *bc = container_of(nb, struct imx8mp_hsio_blk_ctrl,
+						 power_nb);
+	struct clk *usb_clk = bc->domains[IMX8MP_HSIOBLK_PD_USB].clk;
+	int ret;
+
+	switch (action) {
+	case GENPD_NOTIFY_ON:
+		/*
+		 * enable USB clock for a moment for the power-on ADB handshake
+		 * to proceed
+		 */
+		ret = clk_prepare_enable(usb_clk);
+		if (ret)
+			return NOTIFY_BAD;
+		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
+
+		udelay(5);
+
+		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
+		clk_disable_unprepare(usb_clk);
+		break;
+	case GENPD_NOTIFY_PRE_OFF:
+		/* enable USB clock for the power-down ADB handshake to work */
+		ret = clk_prepare_enable(usb_clk);
+		if (ret)
+			return NOTIFY_BAD;
+
+		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
+		break;
+	case GENPD_NOTIFY_OFF:
+		clk_disable_unprepare(usb_clk);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static int imx8mp_hsio_blk_ctrl_probe(struct platform_device *pdev)
+{
+	int num_domains = ARRAY_SIZE(imx8mp_hsio_domain_data);
+	struct device *dev = &pdev->dev;
+	struct imx8mp_hsio_blk_ctrl *bc;
+	void __iomem *base;
+	int i, ret;
+
+	struct regmap_config regmap_config = {
+		.reg_bits	= 32,
+		.val_bits	= 32,
+		.reg_stride	= 4,
+		.max_register	= 0x24,
+	};
+
+	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
+	if (!bc)
+		return -ENOMEM;
+
+	bc->dev = dev;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
+	if (IS_ERR(bc->regmap))
+		return dev_err_probe(dev, PTR_ERR(bc->regmap),
+				     "failed to init regmap\n");
+
+	bc->domains = devm_kcalloc(dev, num_domains,
+				   sizeof(struct imx8mp_hsio_blk_ctrl_domain),
+				   GFP_KERNEL);
+	if (!bc->domains)
+		return -ENOMEM;
+
+	bc->onecell_data.num_domains = num_domains;
+	bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
+	bc->onecell_data.domains =
+		devm_kcalloc(dev, num_domains,
+			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
+	if (!bc->onecell_data.domains)
+		return -ENOMEM;
+
+	bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus");
+	if (IS_ERR(bc->bus_power_dev))
+		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
+				     "failed to attach power domain\n");
+
+	for (i = 0; i < num_domains; i++) {
+		const struct imx8mp_hsio_blk_ctrl_domain_data *data =
+				&imx8mp_hsio_domain_data[i];
+		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
+
+		if (data->clk_name) {
+			domain->clk = devm_clk_get(dev, data->clk_name);
+			if (IS_ERR(domain->clk)) {
+				ret = PTR_ERR(domain->clk);
+				dev_err_probe(dev, ret, "failed to get clock\n");
+				goto cleanup_pds;
+			}
+		}
+
+		domain->power_dev =
+			dev_pm_domain_attach_by_name(dev, data->gpc_name);
+		if (IS_ERR(domain->power_dev)) {
+			dev_err_probe(dev, PTR_ERR(domain->power_dev),
+				      "failed to attach power domain\n");
+			ret = PTR_ERR(domain->power_dev);
+			goto cleanup_pds;
+		}
+
+		domain->genpd.name = data->name;
+		domain->genpd.power_on = imx8mp_hsio_blk_ctrl_power_on;
+		domain->genpd.power_off = imx8mp_hsio_blk_ctrl_power_off;
+		domain->bc = bc;
+		domain->id = i;
+
+		ret = pm_genpd_init(&domain->genpd, NULL, true);
+		if (ret) {
+			dev_err_probe(dev, ret, "failed to init power domain\n");
+			dev_pm_domain_detach(domain->power_dev, true);
+			goto cleanup_pds;
+		}
+
+		/*
+		 * We use runtime PM to trigger power on/off of the upstream GPC
+		 * domain, as a strict hierarchical parent/child power domain
+		 * setup doesn't allow us to meet the sequencing requirements.
+		 * This means we have nested locking of genpd locks, without the
+		 * nesting being visible at the genpd level, so we need a
+		 * separate lock class to make lockdep aware of the fact that
+		 * this are separate domain locks that can be nested without a
+		 * self-deadlock.
+		 */
+		lockdep_set_class(&domain->genpd.mlock,
+				  &blk_ctrl_genpd_lock_class);
+
+		bc->onecell_data.domains[i] = &domain->genpd;
+	}
+
+	ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data);
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to add power domain provider\n");
+		goto cleanup_pds;
+	}
+
+	bc->power_nb.notifier_call = imx8mp_hsio_power_notifier;
+	ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb);
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to add power notifier\n");
+		goto cleanup_provider;
+	}
+
+	dev_set_drvdata(dev, bc);
+
+	return 0;
+
+cleanup_provider:
+	of_genpd_del_provider(dev->of_node);
+cleanup_pds:
+	for (i--; i >= 0; i--) {
+		pm_genpd_remove(&bc->domains[i].genpd);
+		dev_pm_domain_detach(bc->domains[i].power_dev, true);
+	}
+
+	dev_pm_domain_detach(bc->bus_power_dev, true);
+
+	return ret;
+}
+
+static int imx8mp_hsio_blk_ctrl_remove(struct platform_device *pdev)
+{
+	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
+	int i;
+
+	of_genpd_del_provider(pdev->dev.of_node);
+
+	for (i = 0; bc->onecell_data.num_domains; i++) {
+		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
+
+		pm_genpd_remove(&domain->genpd);
+		dev_pm_domain_detach(domain->power_dev, true);
+	}
+
+	dev_pm_genpd_remove_notifier(bc->bus_power_dev);
+
+	dev_pm_domain_detach(bc->bus_power_dev, true);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int imx8mp_hsio_blk_ctrl_suspend(struct device *dev)
+{
+	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
+	int ret, i;
+
+	/*
+	 * This may look strange, but is done so the generic PM_SLEEP code
+	 * can power down our domains and more importantly power them up again
+	 * after resume, without tripping over our usage of runtime PM to
+	 * control the upstream GPC domains. Things happen in the right order
+	 * in the system suspend/resume paths due to the device parent/child
+	 * hierarchy.
+	 */
+	ret = pm_runtime_get_sync(bc->bus_power_dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(bc->bus_power_dev);
+		return ret;
+	}
+
+	for (i = 0; i < bc->onecell_data.num_domains; i++) {
+		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
+
+		ret = pm_runtime_get_sync(domain->power_dev);
+		if (ret < 0) {
+			pm_runtime_put_noidle(domain->power_dev);
+			goto out_fail;
+		}
+	}
+
+	return 0;
+
+out_fail:
+	for (i--; i >= 0; i--)
+		pm_runtime_put(bc->domains[i].power_dev);
+
+	pm_runtime_put(bc->bus_power_dev);
+
+	return ret;
+}
+
+static int imx8mp_hsio_blk_ctrl_resume(struct device *dev)
+{
+	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
+	int i;
+
+	for (i = 0; i < bc->onecell_data.num_domains; i++)
+		pm_runtime_put(bc->domains[i].power_dev);
+
+	pm_runtime_put(bc->bus_power_dev);
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops imx8mp_hsio_blk_ctrl_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(imx8mp_hsio_blk_ctrl_suspend,
+				imx8mp_hsio_blk_ctrl_resume)
+};
+
+static const struct of_device_id imx8mp_hsio_blk_ctrl_of_match[] = {
+	{
+		.compatible = "fsl,imx8mp-hsio-blk-ctrl",
+	}, {
+		/* Sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
+
+static struct platform_driver imx8mp_hsio_blk_ctrl_driver = {
+	.probe = imx8mp_hsio_blk_ctrl_probe,
+	.remove = imx8mp_hsio_blk_ctrl_remove,
+	.driver = {
+		.name = "imx8mp-hsio-blk-ctrl",
+		.pm = &imx8mp_hsio_blk_ctrl_pm_ops,
+		.of_match_table = imx8mp_hsio_blk_ctrl_of_match,
+	},
+};
+module_platform_driver(imx8mp_hsio_blk_ctrl_driver);
-- 
2.30.2



From festevam at gmail.com  Wed Jan 19 05:40:32 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 19 Jan 2022 10:40:32 -0300
Subject: [PATCH] arm64: dts: imx8mp: disable usb3_phy1
In-Reply-To: <20220119132348.2093807-1-l.stach@pengutronix.de>
References: <20220119132348.2093807-1-l.stach@pengutronix.de>
Message-ID: <CAOMZO5BwKW1hTHBnRoOwu4Cr7L_FpD6PdN+wP=HFC+hsvDcXXQ@mail.gmail.com>

Hi Lucas,

On Wed, Jan 19, 2022 at 10:23 AM Lucas Stach <l.stach at pengutronix.de> wrote:
>
> Like usb3_phy0 the default state of the usb3_phy1 should be disabled, so
> it is only enabled on boards exposing this USB port.
>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From wangkefeng.wang at huawei.com  Wed Jan 19 05:44:20 2022
From: wangkefeng.wang at huawei.com (Kefeng Wang)
Date: Wed, 19 Jan 2022 21:44:20 +0800
Subject: [PATCH v2 1/3] mm: vmalloc: Let user to control huge vmalloc
 default behavior
In-Reply-To: <YegQfIQibQi993dp@casper.infradead.org>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-2-wangkefeng.wang@huawei.com>
 <1642473992.qrnqczjfna.astroid@bobo.none>
 <f0dd59eb-6eb8-5b60-508d-7f4022f655ec@huawei.com>
 <YegQfIQibQi993dp@casper.infradead.org>
Message-ID: <93db576e-9a62-ee98-5af2-a62f8386212c@huawei.com>


On 2022/1/19 21:22, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 08:57:58PM +0800, Kefeng Wang wrote:
>> Only parts of our products wants this feature,? we add some interfaces which
>> only
>>
>> alloc hugevmalloc for them, eg,
>> vmap_hugepage/vmalloc_hugepage/remap_vmalloc_hugepage_range..
>>
>> for our products, but it's not the choice of most products, also add
>> nohugevmalloc
>>
>> for most products is expensive, so this is the reason for adding the patch.
>>
>> more config/cmdline are more flexible for test/products?
> But why do only some products want it?  What goes wrong if all products
> enable it?  Features should be auto-tuning, not relying on admins to
> understand them.

Because this feature will use more memory for vmalloc/vmap, that's why 
we add some explicit
interfaces as said above in our kernel to control the user.



From robh at kernel.org  Wed Jan 19 05:44:53 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 19 Jan 2022 07:44:53 -0600
Subject: [PATCH v2, 03/10] dt-bindings: media: mtk-vcodec: Adds encoder
 cores dt-bindings for mt8195
In-Reply-To: <20220117120615.21687-4-irui.wang@mediatek.com>
References: <20220117120615.21687-1-irui.wang@mediatek.com>
 <20220117120615.21687-4-irui.wang@mediatek.com>
Message-ID: <YegV1SQ7V/F3GAFL@robh.at.kernel.org>

On Mon, Jan 17, 2022 at 08:06:08PM +0800, Irui Wang wrote:
> Adds encoder cores dt-bindings for mt8195
> 
> Signed-off-by: Irui Wang <irui.wang at mediatek.com>
> ---
>  .../media/mediatek,vcodec-encoder-core.yaml   | 214 ++++++++++++++++++
>  1 file changed, 214 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> new file mode 100644
> index 000000000000..d1e7bfa50bce
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-encoder-core.yaml
> @@ -0,0 +1,214 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/media/mediatek,vcodec-encoder-core.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Mediatek Video Encoder Accelerator With Multi Core
> +
> +maintainers:
> +  - Irui Wang <irui.wang at mediatek.com>
> +
> +description: |
> +  Mediatek Video Encode is the video encode hardware present in Mediatek
> +  SoCs which supports high resolution encoding functionalities. Required
> +  parent and child device node.
> +
> +properties:
> +  compatible:
> +    const: mediatek,mt8195-vcodec-enc
> +
> +  mediatek,scp:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1

'phandle' is already 1 item. Drop.

> +    description: |
> +      The node of system control processor (SCP), using
> +      the remoteproc & rpmsg framework.
> +
> +  iommus:
> +    minItems: 1
> +    maxItems: 32
> +    description: |
> +      List of the hardware port in respective IOMMU block for current Socs.
> +      Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +  dma-ranges:
> +    maxItems: 1
> +    description: |
> +      Describes the physical address space of IOMMU maps to memory.
> +
> +  "#address-cells":
> +    const: 1
> +
> +  "#size-cells":
> +    const: 1
> +
> +  ranges: true
> +
> +# Required child node:
> +patternProperties:
> +  "venc_core0 at 1a020000":

Address should generally not be defined in the node name schema:

'^venc-core0@'

Though I think you should also drop the '0' here. The unit-address is 
enough to distinguish each instance. Then the schemas for each child 
node can be combined.

> +    type: object
> +
> +    properties:
> +      compatible:
> +        const: mediatek,mtk-venc-core0

Is the programming model for each core the same, but just different 
codecs implemented? I'd just add a property to indicate which codec if 
that's not discoverable.

> +
> +      reg:
> +        maxItems: 1
> +
> +      iommus:
> +        minItems: 1
> +        maxItems: 32
> +        description: |
> +          List of the hardware port in respective IOMMU block for current Socs.
> +          Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +      interrupts:
> +        maxItems: 1
> +
> +      clocks:
> +        maxItems: 1
> +
> +      clock-names:
> +        items:
> +          - const: MT_CG_VENC0

The name is supposed to be local to the instance reflecting what the 
clock drives rather than a top-level or clock controller name. Lowercase 
is also the norm. Given there's only 1 clock, I'd just drop the name.

> +
> +      assigned-clocks:
> +        maxItems: 1
> +
> +      assigned-clock-parents:
> +        maxItems: 1

These are always allowed and shouldn't be required.

> +
> +      power-domains:
> +        maxItems: 1
> +
> +    required:
> +      - compatible
> +      - reg
> +      - iommus
> +      - interrupts
> +      - clocks
> +      - clock-names
> +      - assigned-clocks
> +      - assigned-clock-parents
> +      - power-domains
> +
> +    additionalProperties: false
> +
> +  "venc_core1 at 1b020000":
> +    type: object
> +
> +    properties:
> +      compatible:
> +        const: mediatek,mtk-venc-core1
> +
> +      reg:
> +        maxItems: 1
> +
> +      iommus:
> +        minItems: 1
> +        maxItems: 32
> +        description: |
> +          List of the hardware port in respective IOMMU block for current Socs.
> +          Refer to bindings/iommu/mediatek,iommu.yaml.
> +
> +      interrupts:
> +        maxItems: 1
> +
> +      clocks:
> +        maxItems: 1
> +
> +      clock-names:
> +        items:
> +          - const: MT_CG_VENC1
> +
> +      assigned-clocks:
> +        maxItems: 1
> +
> +      assigned-clock-parents:
> +        maxItems: 1
> +
> +      power-domains:
> +        maxItems: 1
> +
> +    required:
> +      - compatible
> +      - reg
> +      - iommus
> +      - interrupts
> +      - clocks
> +      - clock-names
> +      - assigned-clocks
> +      - assigned-clock-parents
> +      - power-domains
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - mediatek,scp
> +  - iommus
> +  - dma-ranges
> +  - ranges
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/memory/mt8195-memory-port.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mt8195-clk.h>
> +    #include <dt-bindings/power/mt8195-power.h>
> +
> +    venc {
> +        compatible = "mediatek,mt8195-vcodec-enc";
> +        mediatek,scp = <&scp>;
> +        iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>;
> +        dma-ranges = <0x1 0x0 0x0 0x40000000 0x0 0xfff00000>;
> +        #address-cells = <1>;
> +        #size-cells = <1>;
> +        ranges;
> +
> +        venc_core0 at 1a020000 {
> +            compatible = "mediatek,mtk-venc-core0";
> +            reg = <0x1a020000 0x10000>;
> +            iommus = <&iommu_vdo M4U_PORT_L19_VENC_RCPU>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_REC>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_BSDMA>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_SV_COMV>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_RD_COMV>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_CUR_LUMA>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_CUR_CHROMA>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_REF_LUMA>,
> +                     <&iommu_vdo M4U_PORT_L19_VENC_REF_CHROMA>;
> +            interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>;
> +            clocks = <&vencsys CLK_VENC_VENC>;
> +            clock-names = "MT_CG_VENC0";
> +            assigned-clocks = <&topckgen CLK_TOP_VENC>;
> +            assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
> +            power-domains = <&spm MT8195_POWER_DOMAIN_VENC>;
> +        };
> +
> +        venc_core1 at 1b020000 {
> +            compatible = "mediatek,mtk-venc-core1";
> +            reg = <0x1b020000 0x10000>;
> +            iommus = <&iommu_vpp M4U_PORT_L20_VENC_RCPU>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_REC>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_BSDMA>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_SV_COMV>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_RD_COMV>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_CUR_LUMA>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_CUR_CHROMA>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_REF_LUMA>,
> +                     <&iommu_vpp M4U_PORT_L20_VENC_REF_CHROMA>;
> +            interrupts = <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH 0>;
> +            clocks = <&vencsys_core1 CLK_VENC_CORE1_VENC>;
> +            clock-names = "MT_CG_VENC1";
> +            assigned-clocks = <&topckgen CLK_TOP_VENC>;
> +            assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
> +            power-domains = <&spm MT8195_POWER_DOMAIN_VENC_CORE1>;
> +        };
> +    };
> -- 
> 2.18.0
> 
> 


From willy at infradead.org  Wed Jan 19 05:48:13 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 13:48:13 +0000
Subject: [PATCH v2 1/3] mm: vmalloc: Let user to control huge vmalloc
 default behavior
In-Reply-To: <93db576e-9a62-ee98-5af2-a62f8386212c@huawei.com>
References: <20211227145903.187152-1-wangkefeng.wang@huawei.com>
 <20211227145903.187152-2-wangkefeng.wang@huawei.com>
 <1642473992.qrnqczjfna.astroid@bobo.none>
 <f0dd59eb-6eb8-5b60-508d-7f4022f655ec@huawei.com>
 <YegQfIQibQi993dp@casper.infradead.org>
 <93db576e-9a62-ee98-5af2-a62f8386212c@huawei.com>
Message-ID: <YegWneON2voE9htO@casper.infradead.org>

On Wed, Jan 19, 2022 at 09:44:20PM +0800, Kefeng Wang wrote:
> 
> On 2022/1/19 21:22, Matthew Wilcox wrote:
> > On Wed, Jan 19, 2022 at 08:57:58PM +0800, Kefeng Wang wrote:
> > > Only parts of our products wants this feature,? we add some interfaces which
> > > only
> > > 
> > > alloc hugevmalloc for them, eg,
> > > vmap_hugepage/vmalloc_hugepage/remap_vmalloc_hugepage_range..
> > > 
> > > for our products, but it's not the choice of most products, also add
> > > nohugevmalloc
> > > 
> > > for most products is expensive, so this is the reason for adding the patch.
> > > 
> > > more config/cmdline are more flexible for test/products?
> > But why do only some products want it?  What goes wrong if all products
> > enable it?  Features should be auto-tuning, not relying on admins to
> > understand them.
> 
> Because this feature will use more memory for vmalloc/vmap, that's why we
> add some explicit
> interfaces as said above in our kernel to control the user.

Have you validated that?  What sort of performance penalty do you see?


From festevam at gmail.com  Wed Jan 19 05:49:16 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Wed, 19 Jan 2022 10:49:16 -0300
Subject: [PATCH 5/9] dt-bindings: soc: add binding for i.MX8MP HSIO
 blk-ctrl
In-Reply-To: <20220119134027.2931945-6-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-6-l.stach@pengutronix.de>
Message-ID: <CAOMZO5DRkVJ++aTB3jtU9u7PqUMjMb96DdJkZjEfmnsHPmfSjA@mail.gmail.com>

Hi Lucas,

On Wed, Jan 19, 2022 at 10:40 AM Lucas Stach <l.stach at pengutronix.de> wrote:

> +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml#

Should be http://devicetree.org/schemas/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml#

> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP i.MX8MM DISP blk-ctrl

Should be NXP i.MX8M HSIO blk-ctrl


From quentin.schulz at theobroma-systems.com  Wed Jan 19 05:49:48 2022
From: quentin.schulz at theobroma-systems.com (quentin.schulz at theobroma-systems.com)
Date: Wed, 19 Jan 2022 14:49:48 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
Message-ID: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>

From: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>

There are signal integrity issues running the eMMC at 200MHz on Puma
RK3399-Q7.

Similar to the work-around found for RK3399 Gru boards, lowering the
frequency to 100MHz made the eMMC much more stable, so let's lower the
frequency to 100MHz.

It might be possible to run at 150MHz as on RK3399 Gru boards but only
100MHz was extensively tested.

Cc: Quentin Schulz <foss+kernel at 0leil.net>
Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---

Note/RFC: as opposed to gru DTSI, max-frequency is used here instead of
assigned-clock-rates.

AFAIU, max-frequency applies to the SD bus rate, while
assigned-clock-rates applies to the clock fed to the SD host controller
inside the SoC. max-frequency does not interact with the clock subsystem
AFAICT. assigned-clock-rates sets the clock rate at probe, regardless of
eMMC tuning.
Technically, the Arasan SDHC IP supports silicon-hardcoded clock
multiplier so I think setting assigned-clock-rates as a way of rate
limiting the eMMC block is incorrect and max-frequency should be used
instead (as done in this patch). Otherwise the SDHC could still potentially
derive a 200MHz clock from a lower rate clock thanks to its multiplier.

 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index fb67db4619ea..a6108578aae0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -425,6 +425,12 @@ vcc5v0_host_en: vcc5v0-host-en {
 };
 
 &sdhci {
+	/*
+	 * Signal integrity isn't great at 200MHz but 100MHz has proven stable
+	 * enough.
+	 */
+	max-frequency = <100000000>;
+
 	bus-width = <8>;
 	mmc-hs400-1_8v;
 	mmc-hs400-enhanced-strobe;
-- 
2.34.1



From Jason at zx2c4.com  Wed Jan 19 05:54:50 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 14:54:50 +0100
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
Message-ID: <20220119135450.564115-1-Jason@zx2c4.com>

blake2s_compress_generic is weakly aliased to blake2s_generic. The
current harness for function selection uses a function pointer, which is
ordinarily inlined and resolved at compile time. But when Clang's CFI is
enabled, CFI still triggers when making an indirect call via a weak
symbol. This seems like a bug in Clang's CFI, as though it's bucketing
weak symbols and strong symbols differently. It also only seems to
trigger when "full LTO" mode is used, rather than "thin LTO".

[    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
[    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
[    0.000000][    T0] Hardware name: MT6873 (DT)
[    0.000000][    T0] Call trace:
[    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
[    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
[    0.000000][    T0]  panic+0x194/0x464
[    0.000000][    T0]  __cfi_check_fail+0x54/0x58
[    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
[    0.000000][    T0]  blake2s_update+0x14c/0x178
[    0.000000][    T0]  _extract_entropy+0xf4/0x29c
[    0.000000][    T0]  crng_initialize_primary+0x24/0x94
[    0.000000][    T0]  rand_initialize+0x2c/0x6c
[    0.000000][    T0]  start_kernel+0x2f8/0x65c
[    0.000000][    T0]  __primary_switched+0xc4/0x7be4
[    0.000000][    T0] Rebooting in 5 seconds..

Nonetheless, the function pointer method isn't so terrific anyway, so
this patch replaces it with a simple boolean, which also gets inlined
away. This successfully works around the Clang bug.

In general, I'm not too keen on all of the indirection involved here; it
clearly does more harm than good. Hopefully the whole thing can get
cleaned up down the road when lib/crypto is overhauled more
comprehensively. But for now, we go with a simple bandaid.

Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
Reported-by: Miles Chen <miles.chen at mediatek.com>
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Sami Tolvanen <samitolvanen at google.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
---
 arch/arm/crypto/blake2s-shash.c   |  4 ++--
 arch/x86/crypto/blake2s-shash.c   |  4 ++--
 crypto/blake2s_generic.c          |  4 ++--
 include/crypto/internal/blake2s.h | 36 ++++++++++++++++++-------------
 lib/crypto/blake2s.c              |  4 ++--
 5 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
index 17c1c3bfe2f5..763c73beea2d 100644
--- a/arch/arm/crypto/blake2s-shash.c
+++ b/arch/arm/crypto/blake2s-shash.c
@@ -13,12 +13,12 @@
 static int crypto_blake2s_update_arm(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen, false);
 }
 
 static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out, false);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
index f9e2fecdb761..59ae28abe35c 100644
--- a/arch/x86/crypto/blake2s-shash.c
+++ b/arch/x86/crypto/blake2s-shash.c
@@ -18,12 +18,12 @@
 static int crypto_blake2s_update_x86(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen, false);
 }
 
 static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out, false);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
index 72fe480f9bd6..5f96a21f8788 100644
--- a/crypto/blake2s_generic.c
+++ b/crypto/blake2s_generic.c
@@ -15,12 +15,12 @@
 static int crypto_blake2s_update_generic(struct shash_desc *desc,
 					 const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
+	return crypto_blake2s_update(desc, in, inlen, true);
 }
 
 static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress_generic);
+	return crypto_blake2s_final(desc, out, true);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/include/crypto/internal/blake2s.h b/include/crypto/internal/blake2s.h
index d39cfa0d333e..e2da9b413d44 100644
--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -24,14 +24,11 @@ static inline void blake2s_set_lastblock(struct blake2s_state *state)
 	state->f[0] = -1;
 }
 
-typedef void (*blake2s_compress_t)(struct blake2s_state *state,
-				   const u8 *block, size_t nblocks, u32 inc);
-
 /* Helper functions for BLAKE2s shared by the library and shash APIs */
 
-static inline void __blake2s_update(struct blake2s_state *state,
-				    const u8 *in, size_t inlen,
-				    blake2s_compress_t compress)
+static __always_inline void __blake2s_update(struct blake2s_state *state,
+					     const u8 *in, size_t inlen,
+					     bool force_generic)
 {
 	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
 
@@ -39,7 +36,10 @@ static inline void __blake2s_update(struct blake2s_state *state,
 		return;
 	if (inlen > fill) {
 		memcpy(state->buf + state->buflen, in, fill);
-		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+		if (force_generic)
+			blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+		else
+			blake2s_compress(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
 		state->buflen = 0;
 		in += fill;
 		inlen -= fill;
@@ -47,7 +47,10 @@ static inline void __blake2s_update(struct blake2s_state *state,
 	if (inlen > BLAKE2S_BLOCK_SIZE) {
 		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
 		/* Hash one less (full) block than strictly possible */
-		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+		if (force_generic)
+			blake2s_compress_generic(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+		else
+			blake2s_compress(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
 		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 	}
@@ -55,13 +58,16 @@ static inline void __blake2s_update(struct blake2s_state *state,
 	state->buflen += inlen;
 }
 
-static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
-				   blake2s_compress_t compress)
+static __always_inline void __blake2s_final(struct blake2s_state *state, u8 *out,
+					    bool force_generic)
 {
 	blake2s_set_lastblock(state);
 	memset(state->buf + state->buflen, 0,
 	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-	(*compress)(state, state->buf, 1, state->buflen);
+	if (force_generic)
+		blake2s_compress_generic(state, state->buf, 1, state->buflen);
+	else
+		blake2s_compress(state, state->buf, 1, state->buflen);
 	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
 	memcpy(out, state->h, state->outlen);
 }
@@ -99,20 +105,20 @@ static inline int crypto_blake2s_init(struct shash_desc *desc)
 
 static inline int crypto_blake2s_update(struct shash_desc *desc,
 					const u8 *in, unsigned int inlen,
-					blake2s_compress_t compress)
+					bool force_generic)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);
 
-	__blake2s_update(state, in, inlen, compress);
+	__blake2s_update(state, in, inlen, force_generic);
 	return 0;
 }
 
 static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
-				       blake2s_compress_t compress)
+				       bool force_generic)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);
 
-	__blake2s_final(state, out, compress);
+	__blake2s_final(state, out, force_generic);
 	return 0;
 }
 
diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 9364f79937b8..c71c09621c09 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -18,14 +18,14 @@
 
 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 {
-	__blake2s_update(state, in, inlen, blake2s_compress);
+	__blake2s_update(state, in, inlen, false);
 }
 EXPORT_SYMBOL(blake2s_update);
 
 void blake2s_final(struct blake2s_state *state, u8 *out)
 {
 	WARN_ON(IS_ENABLED(DEBUG) && !out);
-	__blake2s_final(state, out, blake2s_compress);
+	__blake2s_final(state, out, false);
 	memzero_explicit(state, sizeof(*state));
 }
 EXPORT_SYMBOL(blake2s_final);
-- 
2.34.1



From robh at kernel.org  Wed Jan 19 06:05:27 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 19 Jan 2022 08:05:27 -0600
Subject: [PATCH v8 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding
 header
In-Reply-To: <20220111215415.2075257-3-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-3-Mr.Bossman075@gmail.com>
Message-ID: <YegapycPxDdgTlXQ@robh.at.kernel.org>

On Tue, 11 Jan 2022 16:54:10 -0500, Jesse Taube wrote:
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add binding header for i.MXRT1050 pinctrl device tree.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: move pinfunc from dt-bindings to dts folder]
> ---
> V1->V2:
> * Move pinfunc from dt-binding to dts
> * Change subject and description
> * Change licence to "GPL-2.0+ OR MIT"
> V2->V3:
> * Change License comment style
> V3->V4:
> * Nothing done
> V4->V5:
> * Nothing done
> V5->V6:
> * Nothing done
> V6->V7:
> * Nothing done
> V7->V8:
> * Nothing done
> ---
>  arch/arm/boot/dts/imxrt1050-pinfunc.h | 993 ++++++++++++++++++++++++++
>  1 file changed, 993 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imxrt1050-pinfunc.h
> 

Acked-by: Rob Herring <robh at kernel.org>


From l.stach at pengutronix.de  Wed Jan 19 06:07:49 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 15:07:49 +0100
Subject: [PATCH 5/9] dt-bindings: soc: add binding for i.MX8MP HSIO
 blk-ctrl
In-Reply-To: <CAOMZO5DRkVJ++aTB3jtU9u7PqUMjMb96DdJkZjEfmnsHPmfSjA@mail.gmail.com>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-6-l.stach@pengutronix.de>
 <CAOMZO5DRkVJ++aTB3jtU9u7PqUMjMb96DdJkZjEfmnsHPmfSjA@mail.gmail.com>
Message-ID: <c015be6087309d5533bb05974777907d9e1f2985.camel@pengutronix.de>

Hi Fabio,

Am Mittwoch, dem 19.01.2022 um 10:49 -0300 schrieb Fabio Estevam:
> Hi Lucas,
> 
> On Wed, Jan 19, 2022 at 10:40 AM Lucas Stach <l.stach at pengutronix.de> wrote:
> 
> > +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
> > @@ -0,0 +1,78 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml#
> 
> Should be http://devicetree.org/schemas/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml#
> 
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NXP i.MX8MM DISP blk-ctrl
> 
> Should be NXP i.MX8M HSIO blk-ctrl

Urgh. Thanks, fixed locally.

Regards,
Lucas



From jun.li at nxp.com  Wed Jan 19 06:14:05 2022
From: jun.li at nxp.com (Jun Li)
Date: Wed, 19 Jan 2022 14:14:05 +0000
Subject: [PATCH v3 3/4] usb: dwc3: imx8mp: Add support for setting SOC
 specific flags
In-Reply-To: <20220118131626.926394-4-alexander.stein@ew.tq-group.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
 <20220118131626.926394-4-alexander.stein@ew.tq-group.com>
Message-ID: <VI1PR04MB4333E8AA7C261C0B3084D8A489599@VI1PR04MB4333.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Alexander Stein <alexander.stein at ew.tq-group.com>
> Sent: Tuesday, January 18, 2022 9:16 PM
> To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>; Rob Herring
> <robh+dt at kernel.org>; Shawn Guo <shawnguo at kernel.org>; Sascha Hauer
> <s.hauer at pengutronix.de>; Fabio Estevam <festevam at gmail.com>
> Cc: Alexander Stein <alexander.stein at ew.tq-group.com>; dl-linux-imx
> <linux-imx at nxp.com>; linux-usb at vger.kernel.org;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Jun Li
> <jun.li at nxp.com>
> Subject: [PATCH v3 3/4] usb: dwc3: imx8mp: Add support for setting SOC
> specific flags
> 
> The i.MX8MP glue layer has support for the following flags:
> * over-current polarity
> * PWR pad polarity
> * controlling PPC flag in HCCPARAMS register
> * permanent port attach for usb2 & usb3 port
> 
> Allow setting these flags by supporting specific flags in the glue node.
> In order to get this to work an additional IORESOURCE_MEM and clock is
> necessary. For backward compatibility this is purely optional.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  drivers/usb/dwc3/dwc3-imx8mp.c | 81 ++++++++++++++++++++++++++++++++++
>  1 file changed, 81 insertions(+)
> 
> diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c
> b/drivers/usb/dwc3/dwc3-imx8mp.c index 1c8fe657b3a9..3df4313b3740 100644
> --- a/drivers/usb/dwc3/dwc3-imx8mp.c
> +++ b/drivers/usb/dwc3/dwc3-imx8mp.c
> @@ -36,17 +36,66 @@
> 
>  #define USB_WAKEUP_EN_MASK		GENMASK(5, 0)
> 
> +/* USB glue registers */
> +#define USB_CTRL0		0x00
> +#define USB_CTRL1		0x04
> +
> +#define USB_CTRL0_PORTPWR_EN	BIT(12) /* 1 - PPC enabled (default) */
> +#define USB_CTRL0_USB3_FIXED	BIT(22) /* 1 - USB3 permanent attached */
> +#define USB_CTRL0_USB2_FIXED	BIT(23) /* 1 - USB2 permanent attached */
> +
> +#define USB_CTRL1_OC_POLARITY	BIT(16) /* 0 - HIGH / 1 - LOW */
> +#define USB_CTRL1_PWR_POLARITY	BIT(17) /* 0 - HIGH / 1 - LOW */
> +
>  struct dwc3_imx8mp {
>  	struct device			*dev;
>  	struct platform_device		*dwc3;
>  	void __iomem			*hsio_blk_base;
> +	void __iomem			*glue_base;
>  	struct clk			*hsio_clk;
>  	struct clk			*suspend_clk;
> +	struct clk			*phy_clk;
>  	int				irq;
>  	bool				pm_suspended;
>  	bool				wakeup_pending;
>  };
> 
> +static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx) {
> +	struct device *dev = dwc3_imx->dev;
> +	u32 value;
> +
> +	if ((!dwc3_imx->glue_base) || (!dwc3_imx->phy_clk))
> +		return;
> +
> +	value = readl(dwc3_imx->glue_base + USB_CTRL0);
> +
> +	if (device_property_read_bool(dev, "fsl,permanently-attached"))
> +		value |= (USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
> +	else
> +		value &= ~(USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
> +
> +	if (device_property_read_bool(dev,
> "fsl,disable-port-power-control"))
> +		value &= ~(USB_CTRL0_PORTPWR_EN);
> +	else
> +		value |= USB_CTRL0_PORTPWR_EN;
> +
> +	writel(value, dwc3_imx->glue_base + USB_CTRL0);
> +
> +	value = readl(dwc3_imx->glue_base + USB_CTRL1);
> +	if (device_property_read_bool(dev, "fsl,over-current-active-low"))
> +		value |= USB_CTRL1_OC_POLARITY;
> +	else
> +		value &= ~USB_CTRL1_OC_POLARITY;
> +
> +	if (device_property_read_bool(dev, "fsl,power-active-low"))
> +		value |= USB_CTRL1_PWR_POLARITY;
> +	else
> +		value &= ~USB_CTRL1_PWR_POLARITY;
> +
> +	writel(value, dwc3_imx->glue_base + USB_CTRL1); }
> +
>  static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)  {
>  	struct dwc3	*dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
> @@ -100,6 +149,7 @@ static int dwc3_imx8mp_probe(struct platform_device
> *pdev)
>  	struct device		*dev = &pdev->dev;
>  	struct device_node	*dwc3_np, *node = dev->of_node;
>  	struct dwc3_imx8mp	*dwc3_imx;
> +	struct resource		*res;
>  	int			err, irq;
> 
>  	if (!node) {
> @@ -119,6 +169,15 @@ static int dwc3_imx8mp_probe(struct platform_device
> *pdev)
>  	if (IS_ERR(dwc3_imx->hsio_blk_base))
>  		return PTR_ERR(dwc3_imx->hsio_blk_base);
> 
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> +	if (!res) {
> +		dev_warn(dev, "Base address for glue layer missing. Continuing
> without, some features are missing though.");
> +	} else {
> +		dwc3_imx->glue_base = devm_ioremap_resource(dev, res);
> +		if (IS_ERR(dwc3_imx->glue_base))
> +			return PTR_ERR(dwc3_imx->glue_base);
> +	}
> +
>  	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
>  	if (IS_ERR(dwc3_imx->hsio_clk)) {
>  		err = PTR_ERR(dwc3_imx->hsio_clk);
> @@ -145,6 +204,24 @@ static int dwc3_imx8mp_probe(struct platform_device
> *pdev)
>  		goto disable_hsio_clk;
>  	}
> 
> +	dwc3_imx->phy_clk = devm_clk_get(dev, "phy");
> +	if (PTR_ERR(dwc3_imx->phy_clk) == -ENOENT) {
> +		dev_warn(dev, "PHY clock missing. Continuing without, some features
> are missing though.");

What feature needs phy clock turned on here, why phy driver turns on
this clock is not enough for you?

Thanks
Li Jun

> +		dwc3_imx->phy_clk = NULL;
> +	} else if (IS_ERR(dwc3_imx->phy_clk)) {
> +		err = PTR_ERR(dwc3_imx->phy_clk);
> +		dev_err(dev, "Failed to get phy clk, err=%d\n", err);
> +		goto disable_suspend_clk;
> +	}
> +
> +	if (dwc3_imx->phy_clk) {
> +		err = clk_prepare_enable(dwc3_imx->phy_clk);
> +		if (err) {
> +			dev_err(dev, "Failed to enable phy clk, err=%d\n", err);
> +			goto disable_suspend_clk;
> +		}
> +	}
> +
>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0) {
>  		err = irq;
> @@ -152,6 +229,8 @@ static int dwc3_imx8mp_probe(struct platform_device
> *pdev)
>  	}
>  	dwc3_imx->irq = irq;
> 
> +	imx8mp_configure_glue(dwc3_imx);
> +
>  	pm_runtime_set_active(dev);
>  	pm_runtime_enable(dev);
>  	err = pm_runtime_get_sync(dev);
> @@ -199,6 +278,8 @@ static int dwc3_imx8mp_probe(struct platform_device
> *pdev)
>  	pm_runtime_disable(dev);
>  	pm_runtime_put_noidle(dev);
>  disable_clks:
> +	clk_disable_unprepare(dwc3_imx->phy_clk);
> +disable_suspend_clk:
>  	clk_disable_unprepare(dwc3_imx->suspend_clk);
>  disable_hsio_clk:
>  	clk_disable_unprepare(dwc3_imx->hsio_clk);
> --
> 2.25.1



From alim.akhtar at samsung.com  Wed Jan 19 06:20:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 19 Jan 2022 19:50:30 +0530
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <b35fa0ff-18a0-2a9d-5a1b-378ef2fef66f@canonical.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
 <20220118144851.69537-5-alim.akhtar@samsung.com>
 <b35fa0ff-18a0-2a9d-5a1b-378ef2fef66f@canonical.com>
Message-ID: <000001d80d3f$b8f9a9a0$2aecfce0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Wednesday, January 19, 2022 12:01 AM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-
>fsd at tesla.com; Jayati Sahu <jayati.sahu at samsung.com>; Ajay Kumar
><ajaykumar.rs at samsung.com>
>Subject: Re: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
>
>On 18/01/2022 15:48, Alim Akhtar wrote:
>> Add initial clock support for FSD (Full Self-Driving) SoC which is
>> required to bring-up platforms based on this SoC.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
>> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  drivers/clk/samsung/Kconfig   |   7 +
>>  drivers/clk/samsung/Makefile  |   1 +
>>  drivers/clk/samsung/clk-fsd.c | 308
>++++++++++++++++++++++++++++++++++
>>  drivers/clk/samsung/clk-pll.c |   1 +
>>  drivers/clk/samsung/clk-pll.h |   1 +
>>  5 files changed, 318 insertions(+)
>>  create mode 100644 drivers/clk/samsung/clk-fsd.c
>>
>> diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
>> index 0e18d6ff2916..11587eb87fc4 100644
>> --- a/drivers/clk/samsung/Kconfig
>> +++ b/drivers/clk/samsung/Kconfig
>> @@ -124,3 +124,10 @@ config S3C2443_COMMON_CLK
>>  	help
>>  	  Support for the clock controller present on the Samsung
>>  	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
>> +
>> +config TESLA_FSD_COMMON_CLK
>> +	bool "Tesla FSD clock controller support" if COMPILE_TEST
>> +	depends on COMMON_CLK_SAMSUNG
>> +	help
>> +	  Support for the clock controller present on the Tesla FSD SoC.
>> +	  Choose Y here only if you build for this SoC.
>
>The clock drivers Kconfig is organized in a way, that platform should select only
>COMMON_CLK_SAMSUNG (first comment in a file), so let's keep it consistent
>also for FSD. "select TESLA_FSD_COMMON_CLK if ARM64 &&
>ARCH_TESLA_FSD" and skip the select in Kconfig.platform in following patch.
>
Thanks Krzysztof for a quick review.
Will incorporate above in the next set.

>
>Best regards,
>Krzysztof



From semen.protsenko at linaro.org  Wed Jan 19 06:35:01 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 19 Jan 2022 16:35:01 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4=vEYm6dGSCXtmiXUVe7FT6p=6Uk=MCvEsEgcdTz-R0NA@mail.gmail.com>

On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Hi,
>
> Second pull with DTS for ARM64, on top of previous pull.
>
> Best regards,
> Krzysztof
>
>
> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
>
>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
>
> are available in the Git repository at:
>
>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
>
> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
>
>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
>
> ----------------------------------------------------------------
> Samsung DTS ARM64 changes for v5.17, part two
>
> Add initial Exynos850 support and WinLink E850-96 board using it.
>
> ----------------------------------------------------------------
> Sam Protsenko (2):
>       arm64: dts: exynos: Add initial Exynos850 SoC support
>       arm64: dts: exynos: Add initial E850-96 board support
>

Hi Krzysztof,

Do you know if this series is going to land in v5.17? The prediction
(by phb-crystal-ball) is that MW closes on 23 Jan. I can see those
patches in soc/for-next [1], but want to be sure those are scheduled
for v5.17.

Thanks!

[1] https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/log/?h=for-next


From abel.vesa at nxp.com  Wed Jan 19 06:38:13 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Wed, 19 Jan 2022 16:38:13 +0200
Subject: [PATCH 0/9] i.MX8MP power-domains part 1 and GPU support
In-Reply-To: <20220119134027.2931945-1-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
Message-ID: <YegiVQAVIHmwolwj@abelvesa>

On 22-01-19 14:40:18, Lucas Stach wrote:
> Hi all,
> 
> this series starts adding the power-domain control for the i.MX8MP
> SoC. The GPCv2 support is complete (at least from going over the RM,
> TF-A and experience with other i.MX8M* SoCs), but not all
> power-domains are usable right now. Currently only the HSIO
> (USB and PCIe) and GPU power domains are enabled.
> 
> Other power domains (MEDIA, VPU, HDMI, AUDIO) can be added when the
> blk-ctrl driver support for those domains is ready, which is still
> work in progress at the moment. As my priorities are shifting to
> other things for a while, I wanted to push out the part that is
> usable now and enables more functionality on the i.MX8MP.
> 

Great effort! Thanks for working on this!

I started doing it myself a couple of months ago. I did the media and
hdmi blk-ctrls. The audio blk-ctrl is the one that got me stuck since it
has PLLs in it and they need to be part of the clock tree somehow.

Let me know if you want me to send the hdmi and media blk-ctrls.
I'll try to rebase them on top of this patchset.

> Regards,
> Lucas
> 
> Lucas Stach (9):
>   soc: imx: gpcv2: add PGC control register indirection
>   dt-bindings: power: add defines for i.MX8MP power domain
>   soc: imx: gpcv2: add support for i.MX8MP power domains
>   dt-bindings: power: imx8mp: add defines for HSIO blk-ctrl domains
>   dt-bindings: soc: add binding for i.MX8MP HSIO blk-ctrl
>   soc: imx: add i.MX8MP HSIO blk-ctrl
>   arm64: dts: imx8mp: add HSIO power-domains
>   arm64: dts: imx8mp: add GPU power domains
>   arm64: dts: imx8mp: add GPU nodes
> 
>  .../bindings/power/fsl,imx-gpcv2.yaml         |   2 +
>  .../soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml     |  78 +++
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi     | 118 ++++-
>  drivers/soc/imx/Makefile                      |   1 +
>  drivers/soc/imx/gpcv2.c                       | 430 ++++++++++++++++-
>  drivers/soc/imx/imx8mp-blk-ctrl.c             | 444 ++++++++++++++++++
>  include/dt-bindings/power/imx8mp-power.h      |  35 ++
>  7 files changed, 1090 insertions(+), 18 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
>  create mode 100644 drivers/soc/imx/imx8mp-blk-ctrl.c
>  create mode 100644 include/dt-bindings/power/imx8mp-power.h
> 
> -- 
> 2.30.2
>


From David.Laight at ACULAB.COM  Wed Jan 19 06:40:58 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Wed, 19 Jan 2022 14:40:58 +0000
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
 <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
 <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>
 <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>
Message-ID: <13f9d24879e34914b1135a4d2ae48d73@AcuMS.aculab.com>

From: Ard Biesheuvel
> Sent: 19 January 2022 12:19
...
> -               (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> +               if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
> +                       (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> +               else
> +                       blake2s_compress_generic(state, in, nblocks - 1,
> +                                                BLAKE2S_BLOCK_SIZE);

Isn't that a candidate for a 'static call' ?

And, maybe all these inlined functions should be real functions?
No point having all the bloat on every call site.
Much better to call a real function and used the cached instructions.

Although, having looked at the source and the generated code for
x86-64 and arm64 I'm not sure I'd want to try to generate
optimised assembler for it.
(Unless you can a instruction that does exactly what the code wants.)

Basically the compiler can merge the instructions for 4 of the
G() expansions so that they can execute in parallel on a multi-issue
cpu. Doing that by hand will be error prone.
Each G() expansion is pretty much a register dependency chain,
not much chance of parallel execution.

There are clearly optimisations for the top/bottom of the loop.
But they can be done to the generic C version.

The real problem is lack of registers - the code needs 16 for the
v[] array plus a few extras.
So some have to spill to stack.

The unrolled code is about 1200 instructions on arm64 and x86-64.
Each of the 10 rounds reads all 16 of the u32 input values.
So that is about 8 (1200/160) instructions for each read.
Which means there is plenty of memory bandwidth for other
reads.

So 'rolling up' the rounds - which adds in the blake2s_sigma[]
reads could easily be 'almost free'.
Certainly on x86 where you are just (well should be just) adding an
extra memory uop for each input buffer reads.

I'm not sure the 8 G() calls can be folded into two sets of 4
while still getting the compiler to interleave the generated code.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From houtao1 at huawei.com  Wed Jan 19 06:45:37 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Wed, 19 Jan 2022 22:45:37 +0800
Subject: [PATCH bpf] bpf, arm64: calculate offset as byte-offset for bpf
 line info
In-Reply-To: <2091c1ac-2863-cdd6-5de9-d264ab54c9be@iogearbox.net>
References: <20220104014236.1512639-1-houtao1@huawei.com>
 <2091c1ac-2863-cdd6-5de9-d264ab54c9be@iogearbox.net>
Message-ID: <02963800-ca3d-7b4b-3e4d-b4fb7678a0b1@huawei.com>

Hi,

On 1/7/2022 6:00 AM, Daniel Borkmann wrote:
> On 1/4/22 2:42 AM, Hou Tao wrote:
>> The bpf line info for arm64 is broken due to two reasons:
>> (1) insn_to_jit_off passed to bpf_prog_fill_jited_linfo() is
>> ???? calculated in instruction granularity instead of bytes
>> ???? granularity.
>> (2) insn_to_jit_off only considers the body itself and ignores
>> ???? prologue before the body.
>>
>> So fix it by calculating offset as byte-offset and do build_prologue()
>> first in the first JIT pass.
>>
[snip]
>> -??? /* Fake pass to fill in ctx->offset. */
>> -??? if (build_body(&ctx, extra_pass)) {
>> +??? /*
>> +???? * 1. Initial fake pass to compute ctx->idx and ctx->offset.
>> +???? *
>> +???? * BPF line info needs ctx->offset[i] to be the byte offset
>> +???? * of instruction[i] in jited image, so build prologue first.
>> +???? */
>> +??? if (build_prologue(&ctx, was_classic)) {
>> ????????? prog = orig_prog;
>> ????????? goto out_off;
>> ????? }
>> ? -??? if (build_prologue(&ctx, was_classic)) {
>> +??? if (build_body(&ctx, extra_pass)) {
>> ????????? prog = orig_prog;
>> ????????? goto out_off;
>
> Could you split this into two logical patches? Both 1/2 seem independent
> of each other and should have been rather 2 patches instead of 1.
>
Sorry for the later reply. Splitting into two patches make sense for me. Will do
it in v2.
> Did you check if also other JITs could be affected?
It seems sparc also doesn't represent offset by bytes and I can check other
arches as well,
but it is sad that I don't have the environments for these arches.

> Thanks,
> Daniel
> .



From miles.chen at mediatek.com  Wed Jan 19 06:46:52 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 19 Jan 2022 22:46:52 +0800
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <20220119135450.564115-1-Jason@zx2c4.com>
References: <20220119135450.564115-1-Jason@zx2c4.com>
Message-ID: <20220119144652.12349-1-miles.chen@mediatek.com>

Test-by: Miles Chen <miles.chen at mediatek.com>

Thank Jason & Ard for your help!

Miles


From robh at kernel.org  Wed Jan 19 06:49:01 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 19 Jan 2022 08:49:01 -0600
Subject: [PATCH 5/9] dt-bindings: soc: add binding for i.MX8MP HSIO
 blk-ctrl
In-Reply-To: <20220119134027.2931945-6-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-6-l.stach@pengutronix.de>
Message-ID: <1642603741.780177.3540814.nullmailer@robh.at.kernel.org>

On Wed, 19 Jan 2022 14:40:23 +0100, Lucas Stach wrote:
> This adds the binding for the HSIO blk-ctrl on the i.MX8MP SoC.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  .../soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml     | 78 +++++++++++++++++++
>  1 file changed, 78 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
./Documentation/devicetree/bindings/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml: $id: relative path/filename doesn't match actual path or filename
	expected: http://devicetree.org/schemas/soc/imx/fsl,imx8mp-hsio-blk-ctrl.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml: duplicate '$id' value 'http://devicetree.org/schemas/soc/imx/fsl,imx8mm-disp-blk-ctrl.yaml#'

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1581785

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From krzysztof.kozlowski at canonical.com  Wed Jan 19 06:49:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 15:49:02 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAPLW+4=vEYm6dGSCXtmiXUVe7FT6p=6Uk=MCvEsEgcdTz-R0NA@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4=vEYm6dGSCXtmiXUVe7FT6p=6Uk=MCvEsEgcdTz-R0NA@mail.gmail.com>
Message-ID: <495d7eee-ab87-d330-119c-eaafa6c1dee7@canonical.com>

On 19/01/2022 15:35, Sam Protsenko wrote:
> On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Hi,
>>
>> Second pull with DTS for ARM64, on top of previous pull.
>>
>> Best regards,
>> Krzysztof
>>
>>
>> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
>>
>>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
>>
>> are available in the Git repository at:
>>
>>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
>>
>> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
>>
>>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
>>
>> ----------------------------------------------------------------
>> Samsung DTS ARM64 changes for v5.17, part two
>>
>> Add initial Exynos850 support and WinLink E850-96 board using it.
>>
>> ----------------------------------------------------------------
>> Sam Protsenko (2):
>>       arm64: dts: exynos: Add initial Exynos850 SoC support
>>       arm64: dts: exynos: Add initial E850-96 board support
>>
> 
> Hi Krzysztof,
> 
> Do you know if this series is going to land in v5.17? 

I don't know, did not check.

> The prediction
> (by phb-crystal-ball) is that MW closes on 23 Jan. I can see those
> patches in soc/for-next [1], but want to be sure those are scheduled
> for v5.17.

I don't get how can you be sure that they will be in v5.17. If they are
not going to be pulled - what can you do?


Best regards,
Krzysztof


From houtao1 at huawei.com  Wed Jan 19 06:49:42 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Wed, 19 Jan 2022 22:49:42 +0800
Subject: [PATCH bpf-next] bpf, arm64: enable kfunc call
Message-ID: <20220119144942.305568-1-houtao1@huawei.com>

Since commit b2eed9b58811 ("arm64/kernel: kaslr: reduce module
randomization range to 2 GB"), for arm64 whether KASLR is enabled
or not, the module is placed within 2GB of the kernel region, so
s32 in bpf_kfunc_desc is sufficient to represente the offset of
module function relative to __bpf_call_base. The only thing needed
is to override bpf_jit_supports_kfunc_call().

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e96d4d87291f..74f9a9b6a053 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1143,6 +1143,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	return prog;
 }
 
+bool bpf_jit_supports_kfunc_call(void)
+{
+	return true;
+}
+
 u64 bpf_jit_alloc_exec_limit(void)
 {
 	return VMALLOC_END - VMALLOC_START;
-- 
2.27.0



From hws at denx.de  Wed Jan 19 06:52:03 2022
From: hws at denx.de (Harald Seiler)
Date: Wed, 19 Jan 2022 15:52:03 +0100
Subject: [PATCH] tty: serial: imx: Add fast path when rs485 delays are 0
Message-ID: <20220119145204.238767-1-hws@denx.de>

Right now, even when `delay_rts_before_send` and `delay_rts_after_send`
are 0, the hrtimer is triggered (with timeout 0) which can introduce a
few 100us of additional overhead on slower i.MX platforms.

Implement a fast path when the delays are 0, where the RTS signal is
toggled immediately instead of going through an hrtimer.  This fast path
behaves identical to the code before delay support was implemented.

Signed-off-by: Harald Seiler <hws at denx.de>
---
 drivers/tty/serial/imx.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index df8a0c8b8b29..67bbbb69229d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -455,9 +455,14 @@ static void imx_uart_stop_tx(struct uart_port *port)
 	if (port->rs485.flags & SER_RS485_ENABLED) {
 		if (sport->tx_state == SEND) {
 			sport->tx_state = WAIT_AFTER_SEND;
-			start_hrtimer_ms(&sport->trigger_stop_tx,
+
+			if (port->rs485.delay_rts_after_send > 0) {
+				start_hrtimer_ms(&sport->trigger_stop_tx,
 					 port->rs485.delay_rts_after_send);
-			return;
+				return;
+			}
+
+			/* continue without any delay */
 		}
 
 		if (sport->tx_state == WAIT_AFTER_RTS ||
@@ -698,9 +703,14 @@ static void imx_uart_start_tx(struct uart_port *port)
 				imx_uart_stop_rx(port);
 
 			sport->tx_state = WAIT_AFTER_RTS;
-			start_hrtimer_ms(&sport->trigger_start_tx,
+
+			if (port->rs485.delay_rts_before_send > 0) {
+				start_hrtimer_ms(&sport->trigger_start_tx,
 					 port->rs485.delay_rts_before_send);
-			return;
+				return;
+			}
+
+			/* continue without any delay */
 		}
 
 		if (sport->tx_state == WAIT_AFTER_SEND
-- 
2.34.1



From l.stach at pengutronix.de  Wed Jan 19 07:01:52 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 19 Jan 2022 16:01:52 +0100
Subject: [PATCH 0/9] i.MX8MP power-domains part 1 and GPU support
In-Reply-To: <YegiVQAVIHmwolwj@abelvesa>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <YegiVQAVIHmwolwj@abelvesa>
Message-ID: <5ae0e63af752a8c66fe9a63ad582a76b250178f0.camel@pengutronix.de>

Hi Abel,

Am Mittwoch, dem 19.01.2022 um 16:38 +0200 schrieb Abel Vesa:
> On 22-01-19 14:40:18, Lucas Stach wrote:
> > Hi all,
> > 
> > this series starts adding the power-domain control for the i.MX8MP
> > SoC. The GPCv2 support is complete (at least from going over the RM,
> > TF-A and experience with other i.MX8M* SoCs), but not all
> > power-domains are usable right now. Currently only the HSIO
> > (USB and PCIe) and GPU power domains are enabled.
> > 
> > Other power domains (MEDIA, VPU, HDMI, AUDIO) can be added when the
> > blk-ctrl driver support for those domains is ready, which is still
> > work in progress at the moment. As my priorities are shifting to
> > other things for a while, I wanted to push out the part that is
> > usable now and enables more functionality on the i.MX8MP.
> > 
> 
> Great effort! Thanks for working on this!
> 
> I started doing it myself a couple of months ago. I did the media and
> hdmi blk-ctrls. The audio blk-ctrl is the one that got me stuck since it
> has PLLs in it and they need to be part of the clock tree somehow.
> 
> Let me know if you want me to send the hdmi and media blk-ctrls.
> I'll try to rebase them on top of this patchset.

That would certainly be very helpful!

The HSIO one also has a PLL that can optionally be used as a reference
for the USB and PCIe PHYs. I think it should be doable to integrate
them in the clock tree. We need some additional smarts to save/restore
the clock state when the *MIX domain powers down/up.

Other than that I think we need to add a rule that those blk-ctrl
clocks can only be prepared/enabled when the power domain is already up
to avoid circling back into the clock framework via the GPC, but I
guess that's a reasonable rule for the peripheral drivers to adhere to.
Just always runtime resume the peripheral before enabling any clocks,
or possibly even just enable the clocks in the runtime resume callback
of the driver.

Regards,
Lucas



From Jason at zx2c4.com  Wed Jan 19 07:03:29 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Wed, 19 Jan 2022 16:03:29 +0100
Subject: [PATCH] lib/crypto: blake2s: fix a CFI failure
In-Reply-To: <13f9d24879e34914b1135a4d2ae48d73@AcuMS.aculab.com>
References: <CAHmME9oX+4Ek81xy0nBOegqABH0xYqyONAqinsu7GZ7AaQaqYQ@mail.gmail.com>
 <20220119100615.5059-1-miles.chen@mediatek.com>
 <CAHmME9pQcUxs87EwQwBZNDA4ZzqugTggH+uiNPh=mv5zjp3g3A@mail.gmail.com>
 <CAHmME9pPKjRLmR6zpYFZT7rOOfHsG2ESnDi+QQrDJuGLo1X4JQ@mail.gmail.com>
 <CAHmME9oGTPS-gVyHQ4o=AxvMJrGH44_tyQ2KPQcfAKgcqC2SnA@mail.gmail.com>
 <CAMj1kXEo8kQNeoCdwvBkkW0UeYFQEJwkZ_nj06qjsBDF2Qu2pQ@mail.gmail.com>
 <13f9d24879e34914b1135a4d2ae48d73@AcuMS.aculab.com>
Message-ID: <CAHmME9oON=XwOoMNyO+Uu6pEC5j=JvvfK5g2u7mFcM=Y_LZ3uw@mail.gmail.com>

Hi David,

On Wed, Jan 19, 2022 at 3:41 PM David Laight <David.Laight at aculab.com> wrote:
>
> From: Ard Biesheuvel
> > Sent: 19 January 2022 12:19
> ...
> > -               (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> > +               if (IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S))
> > +                       (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> > +               else
> > +                       blake2s_compress_generic(state, in, nblocks - 1,
> > +                                                BLAKE2S_BLOCK_SIZE);
>
> Isn't that a candidate for a 'static call' ?
>
> And, maybe all these inlined functions should be real functions?
> No point having all the bloat on every call site.
> Much better to call a real function and used the cached instructions.

Not a good candidate for static call, as this doesn't actually need to
change at runtime ever. It's using a function pointer here out of
laziness to keep the same body of the function, like a compile-time
template. You can sort of squint and imagine the C++. Unfortunately,
CFI felt differently and still treats it as an indirect call.

https://lore.kernel.org/linux-crypto/20220119135450.564115-1-Jason at zx2c4.com/
fixes it up to use a boolean instead, which will certainly be inlined
away. So that's definitely an improvement on what's there now.

For 5.18, I think it's probable that all of this stuff goes away
anyway, and we don't need the templated helpers at all. So perhaps my
patch will serve as an okay stop gap. Alternatively, maybe the clang
people will say, "oh no, our bug" and then fix it in their
neighborhood. According to
https://github.com/ClangBuiltLinux/linux/issues/1567 it looks like
that could be the case.

> There are clearly optimisations for the top/bottom of the loop.
> But they can be done to the generic C version.

Optimizing the generic C version would be quite nice, as it'd help all
platforms.

Jason


From semen.protsenko at linaro.org  Wed Jan 19 07:07:32 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 19 Jan 2022 17:07:32 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <495d7eee-ab87-d330-119c-eaafa6c1dee7@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4=vEYm6dGSCXtmiXUVe7FT6p=6Uk=MCvEsEgcdTz-R0NA@mail.gmail.com>
 <495d7eee-ab87-d330-119c-eaafa6c1dee7@canonical.com>
Message-ID: <CAPLW+4nM_8nbf4inP2pGMVbkE+OYwbkPrfjKtPAYPBfUXvF32A@mail.gmail.com>

On Wed, 19 Jan 2022 at 16:49, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 19/01/2022 15:35, Sam Protsenko wrote:
> > On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski
> > <krzysztof.kozlowski at canonical.com> wrote:
> >>
> >> Hi,
> >>
> >> Second pull with DTS for ARM64, on top of previous pull.
> >>
> >> Best regards,
> >> Krzysztof
> >>
> >>
> >> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
> >>
> >>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
> >>
> >> are available in the Git repository at:
> >>
> >>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
> >>
> >> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
> >>
> >>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
> >>
> >> ----------------------------------------------------------------
> >> Samsung DTS ARM64 changes for v5.17, part two
> >>
> >> Add initial Exynos850 support and WinLink E850-96 board using it.
> >>
> >> ----------------------------------------------------------------
> >> Sam Protsenko (2):
> >>       arm64: dts: exynos: Add initial Exynos850 SoC support
> >>       arm64: dts: exynos: Add initial E850-96 board support
> >>
> >
> > Hi Krzysztof,
> >
> > Do you know if this series is going to land in v5.17?
>
> I don't know, did not check.
>
> > The prediction
> > (by phb-crystal-ball) is that MW closes on 23 Jan. I can see those
> > patches in soc/for-next [1], but want to be sure those are scheduled
> > for v5.17.
>
> I don't get how can you be sure that they will be in v5.17. If they are
> not going to be pulled - what can you do?
>

I can't. Just haven't seen corresponding pull request to mainline tree
on ML yet, thought you may know something. Basically I just don't want
those patches to be lost accidentally. And of course it'd nice to see
those in v5.17. Anyway, that question should've been probably directed
to Olof and Arnd, sorry for disturbing.

>
> Best regards,
> Krzysztof


From alim.akhtar at samsung.com  Wed Jan 19 07:07:40 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 19 Jan 2022 20:37:40 +0530
Subject: [PATCH v2 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <43e72d34-0e11-9ff6-6924-0cab62b51891@canonical.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150108epcas5p2d9cd4db7cb368c2bfbd7d058eba4107c@epcas5p2.samsung.com>
 <20220118144851.69537-15-alim.akhtar@samsung.com>
 <43e72d34-0e11-9ff6-6924-0cab62b51891@canonical.com>
Message-ID: <000301d80d46$502ae590$f080b0b0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Wednesday, January 19, 2022 12:15 AM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com; linux-
>fsd at tesla.com; Arjun K V <arjun.kv at samsung.com>; Aswani Reddy
><aswani.reddy at samsung.com>; Ajay Kumar <ajaykumar.rs at samsung.com>;
>Sriranjani P <sriranjani.p at samsung.com>; Chandrasekar R
><rcsekar at samsung.com>; Shashank Prashar <s.prashar at samsung.com>
>Subject: Re: [PATCH v2 14/16] arm64: dts: fsd: Add initial device tree support
>
>On 18/01/2022 15:48, Alim Akhtar wrote:
>> Add initial device tree support for "Full Self-Driving" (FSD) SoC This
>> SoC contain three clusters of four cortex-a72 CPUs and various
>> peripheral IPs.
>>
>> Cc: linux-fsd at tesla.com
>> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
>> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
>> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
>> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>> ---
>>  MAINTAINERS                           |   8 +
>>  arch/arm64/Kconfig.platforms          |   7 +
>>  arch/arm64/boot/dts/Makefile          |   1 +
>>  arch/arm64/boot/dts/tesla/Makefile    |   3 +
>>  arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
>>  arch/arm64/boot/dts/tesla/fsd.dtsi    | 651
>++++++++++++++++++++++++++
>>  6 files changed, 709 insertions(+)
>>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
>>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
>>
>
>I saw you dropped the MCT timer from DTSI. I wonder why?
>
I dropped it intentionally, as you had a comment on MCT driver changes, so will send later along with MCT driver fix.

>Not very happy with FSD naming (as discussed before), but board compatible
>looks reasonable. Code looks good to me:
>Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>
Thanks Krzysztof for all the reviews.

>Similarly to previous vendor-prefix patch, please let me know if it's expected
>me to take it. I assume no. :)
>
I am expecting this will go via your tree, but I am ok either ways. May be you and arm-soc maintainers (Arnd/Olof) can take the call here.

>Best regards,
>Krzysztof



From semen.protsenko at linaro.org  Wed Jan 19 07:11:25 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Wed, 19 Jan 2022 17:11:25 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>

On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Hi,
>
> Second pull with DTS for ARM64, on top of previous pull.
>
> Best regards,
> Krzysztof
>
>
> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
>
>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
>
> are available in the Git repository at:
>
>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
>
> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
>
>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
>
> ----------------------------------------------------------------
> Samsung DTS ARM64 changes for v5.17, part two
>
> Add initial Exynos850 support and WinLink E850-96 board using it.
>
> ----------------------------------------------------------------
> Sam Protsenko (2):
>       arm64: dts: exynos: Add initial Exynos850 SoC support
>       arm64: dts: exynos: Add initial E850-96 board support
>

Hi Olof, Arnd,

Just want to check if it's possible for those patches to be applied in
v5.17? Sorry for the noise, but that's important to me.

>  arch/arm64/boot/dts/exynos/Makefile               |   1 +
>  arch/arm64/boot/dts/exynos/exynos850-e850-96.dts  | 195 ++++++
>  arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi | 643 ++++++++++++++++++
>  arch/arm64/boot/dts/exynos/exynos850.dtsi         | 759 ++++++++++++++++++++++
>  4 files changed, 1598 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-e850-96.dts
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850-pinctrl.dtsi
>  create mode 100644 arch/arm64/boot/dts/exynos/exynos850.dtsi


From u.kleine-koenig at pengutronix.de  Wed Jan 19 07:11:45 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Wed, 19 Jan 2022 16:11:45 +0100
Subject: [PATCH] tty: serial: imx: Add fast path when rs485 delays are 0
In-Reply-To: <20220119145204.238767-1-hws@denx.de>
References: <20220119145204.238767-1-hws@denx.de>
Message-ID: <20220119151145.zft47rzebnabiej2@pengutronix.de>

On Wed, Jan 19, 2022 at 03:52:03PM +0100, Harald Seiler wrote:
> Right now, even when `delay_rts_before_send` and `delay_rts_after_send`
> are 0, the hrtimer is triggered (with timeout 0) which can introduce a
> few 100us of additional overhead on slower i.MX platforms.
> 
> Implement a fast path when the delays are 0, where the RTS signal is
> toggled immediately instead of going through an hrtimer.  This fast path
> behaves identical to the code before delay support was implemented.
> 
> Signed-off-by: Harald Seiler <hws at denx.de>
> ---
>  drivers/tty/serial/imx.c | 18 ++++++++++++++----
>  1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> index df8a0c8b8b29..67bbbb69229d 100644
> --- a/drivers/tty/serial/imx.c
> +++ b/drivers/tty/serial/imx.c
> @@ -455,9 +455,14 @@ static void imx_uart_stop_tx(struct uart_port *port)
>  	if (port->rs485.flags & SER_RS485_ENABLED) {
>  		if (sport->tx_state == SEND) {
>  			sport->tx_state = WAIT_AFTER_SEND;
> -			start_hrtimer_ms(&sport->trigger_stop_tx,
> +
> +			if (port->rs485.delay_rts_after_send > 0) {
> +				start_hrtimer_ms(&sport->trigger_stop_tx,
>  					 port->rs485.delay_rts_after_send);
> -			return;
> +				return;
> +			}
> +
> +			/* continue without any delay */

Is it right to keep the assignment sport->tx_state = WAIT_AFTER_SEND ?

>  		}
>  
>  		if (sport->tx_state == WAIT_AFTER_RTS ||
> @@ -698,9 +703,14 @@ static void imx_uart_start_tx(struct uart_port *port)
>  				imx_uart_stop_rx(port);
>  
>  			sport->tx_state = WAIT_AFTER_RTS;
> -			start_hrtimer_ms(&sport->trigger_start_tx,
> +
> +			if (port->rs485.delay_rts_before_send > 0) {
> +				start_hrtimer_ms(&sport->trigger_start_tx,
>  					 port->rs485.delay_rts_before_send);
> -			return;
> +				return;
> +			}
> +
> +			/* continue without any delay */

Here similar question here about sport->tx_state = WAIT_AFTER_RTS;

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/088d552f/attachment.sig>

From krzysztof.kozlowski at canonical.com  Wed Jan 19 07:11:56 2022
From: krzysztof.kozlowski at canonical.com ('Krzysztof Kozlowski')
Date: Wed, 19 Jan 2022 16:11:56 +0100
Subject: [PATCH v2 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <000301d80d46$502ae590$f080b0b0$@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150108epcas5p2d9cd4db7cb368c2bfbd7d058eba4107c@epcas5p2.samsung.com>
 <20220118144851.69537-15-alim.akhtar@samsung.com>
 <43e72d34-0e11-9ff6-6924-0cab62b51891@canonical.com>
 <000301d80d46$502ae590$f080b0b0$@samsung.com>
Message-ID: <20220119151156.y2rzrk2gpoweiofc@krzk-bin>

On Wed, Jan 19, 2022 at 08:37:40PM +0530, Alim Akhtar wrote:
> >Similarly to previous vendor-prefix patch, please let me know if it's expected
> >me to take it. I assume no. :)
> >
> I am expecting this will go via your tree, but I am ok either ways. May be you and arm-soc maintainers (Arnd/Olof) can take the call here.

I can take it, that would be the easiest, I guess.

Best regards,
Krzysztof



From alim.akhtar at samsung.com  Wed Jan 19 07:15:29 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 19 Jan 2022 20:45:29 +0530
Subject: [PATCH v4 3/3] ARM: dts: Add support for Samsung Chagall WiFi
In-Reply-To: <20220118185746.299832-4-henrik@grimler.se>
References: <20220118185746.299832-1-henrik@grimler.se>
 <CGME20220118185822epcas5p1b40759c9fc7356663bcfb7d66f21d4e1@epcas5p1.samsung.com>
 <20220118185746.299832-4-henrik@grimler.se>
Message-ID: <000401d80d47$6a01c690$3e0553b0$@samsung.com>

Hi Henrik,

>-----Original Message-----
>From: Henrik Grimler [mailto:henrik at grimler.se]
>Sent: Wednesday, January 19, 2022 12:28 AM
>To: semen.protsenko at linaro.org; virag.david003 at gmail.com;
>martin.juecker at gmail.com; cw00.choi at samsung.com;
>m.szyprowski at samsung.com; alim.akhtar at samsung.com;
>krzysztof.kozlowski at canonical.com; robh+dt at kernel.org;
>devicetree at vger.kernel.org; linux-samsung-soc at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>~postmarketos/upstreaming at lists.sr.ht
>Cc: Henrik Grimler <henrik at grimler.se>
>Subject: [PATCH v4 3/3] ARM: dts: Add support for Samsung Chagall WiFi
>
>Chagall WiFi, with product name Samsung Galaxy Tab S 10.5", is based on
>Exynos 5420.  This device is one of several tablet models released in 2014
>based on Exynos 5420.
>
>The device tree added here contains support for:
>
>- UART
>- eMMC
>- SD card
>- USB
>
>CCI has been disabled in the hardware, enabling it would require (de-
>)soldering a resistor on the board.  Trying to boot with it enabled in
kernel
>makes the device hang when CCI is probed.
>Exynos5420-arndale-octa also has had CCI disabled due to issues, see commit
>25217fef3551 ("ARM: dts: disable CCI on exynos5420 based arndale-octa").
>
>Signed-off-by: Henrik Grimler <henrik at grimler.se>
>---
> arch/arm/boot/dts/Makefile                    |   1 +
> arch/arm/boot/dts/exynos5420-chagall-wifi.dts |  75 ++
> .../dts/exynos5420-galaxy-tab-common.dtsi     | 692 ++++++++++++++++++
> 3 files changed, 768 insertions(+)
> create mode 100644 arch/arm/boot/dts/exynos5420-chagall-wifi.dts
> create mode 100644 arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
>
>diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index
>0de64f237cd8..088fcedb3212 100644
>--- a/arch/arm/boot/dts/Makefile
>+++ b/arch/arm/boot/dts/Makefile
>@@ -220,6 +220,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
> 	exynos5420-arndale-octa.dtb \
> 	exynos5420-peach-pit.dtb \
> 	exynos5420-smdk5420.dtb \
>+	exynos5420-chagall-wifi.dtb \
> 	exynos5422-odroidhc1.dtb \
> 	exynos5422-odroidxu3.dtb \
> 	exynos5422-odroidxu3-lite.dtb \
>diff --git a/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
>b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
>new file mode 100644
>index 000000000000..1319344a2c74
>--- /dev/null
>+++ b/arch/arm/boot/dts/exynos5420-chagall-wifi.dts
>@@ -0,0 +1,75 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/*
>+ * Samsung's Exynos5420 Chagall WiFi board device tree source
>+ *
>+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
>+ *		http://www.samsung.com
>+ * Copyright (c) 2022 Henrik Grimler
>+ */
>+
>+/dts-v1/;
>+#include "exynos5420-galaxy-tab-common.dtsi"
>+
>+/ {
>+	model = "Samsung Chagall WiFi based on Exynos5420";
>+	compatible = "samsung,chagall-wifi", "samsung,exynos5420", \
>+		     "samsung,exynos5";
>+};
>+
>+&ldo15_reg {
>+	/* Unused */
>+	regulator-name = "VDD_LDO15";
>+	regulator-min-microvolt = <3300000>;
>+	regulator-max-microvolt = <3300000>;
>+};
>+
>+&ldo17_reg {
>+	regulator-name = "VDD_IRLED_3V3";
>+	regulator-min-microvolt = <3300000>;
>+	regulator-max-microvolt = <3350000>;
>+	regulator-always-on;
>+	regulator-boot-on;
>+
>+	regulator-state-mem {
>+		regulator-off-in-suspend;
>+	};
>+};
>+
>+&ldo28_reg {
>+	/* Unused */
>+	regulator-name = "VDD_LDO28";
>+	regulator-min-microvolt = <3300000>;
>+	regulator-max-microvolt = <3300000>;
>+};
>+
>+&ldo29_reg {
>+	regulator-name = "VDD_TCON_1V8";
>+	regulator-min-microvolt = <1900000>;
>+	regulator-max-microvolt = <1900000>;
>+
>+	regulator-state-mem {
>+		regulator-off-in-suspend;
>+	};
>+};
>+
>+&ldo31_reg {
>+	regulator-name = "VDD_GRIP_1V8";
>+	regulator-min-microvolt = <1800000>;
>+	regulator-max-microvolt = <1800000>;
>+	regulator-always-on;
>+	regulator-boot-on;
>+
>+	regulator-state-mem {
>+		regulator-off-in-suspend;
>+	};
>+};
>+
>+&ldo32_reg {
>+	regulator-name = "VDD_TSP_1V8";
>+	regulator-min-microvolt = <1900000>;
>+	regulator-max-microvolt = <1900000>;
>+
>+	regulator-state-mem {
>+		regulator-off-in-suspend;
>+	};
>+};
>diff --git a/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
>b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
>new file mode 100644
>index 000000000000..e4ed0fd153f4
>--- /dev/null
>+++ b/arch/arm/boot/dts/exynos5420-galaxy-tab-common.dtsi
>@@ -0,0 +1,692 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/*
>+ * Base DT for Samsung's family of tablets based on Exynos5420.
>+ *
>+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
>+ *		http://www.samsung.com
>+ * Copyright (c) 2022 Henrik Grimler
>+ */
>+
>+/dts-v1/;
>+#include "exynos5420.dtsi"
>+#include "exynos5420-cpus.dtsi"
>+#include <dt-bindings/input/input.h>
>+#include <dt-bindings/gpio/gpio.h>
>+#include <dt-bindings/clock/samsung,s2mps11.h>
>+
>+/ {
>+	chassis-type = "tablet";
>+
>+	/*
>+	 * To successfully boot the mainline kernel with the stock
>+	 * bootloader (SBOOT), the tlb needs to be flushed after the
>+	 * page table pointer has been updated in
>__common_mmu_cache_on.
>+	 * The same hack is also needed to boot exynos4412-i9300 with
>+	 * stock bootloader, and probably other Samsung devices of
>+	 * similar age.  See
>+	 * https://lore.kernel.org/all/1355276466-18295-1-git-send-email-
>arve at android.com
>+	 * for more details.
>+	 */
>+
>+	chosen {
>+		stdout-path = "serial2:115200n8";
>+	};
>+
>+	memory at 20000000 {
>+		device_type = "memory";
>+		reg = <0x20000000 0xc0000000>;
>+	};
>+
>+	firmware at 2073000 {
>+		compatible = "samsung,secure-firmware";
>+		reg = <0x02073000 0x1000>;
>+	};
>+
>+	fixed-rate-clocks {
>+		oscclk {
>+			compatible = "samsung,exynos5420-oscclk";
>+			clock-frequency = <24000000>;
>+		};
>+	};
>+
>+	gpio-keys {
>+		compatible = "gpio-keys";
>+		pinctrl-names = "default";
>+
>+		key-power {
>+			debounce-interval = <10>;
>+			gpios = <&gpx2 2 GPIO_ACTIVE_LOW>;
>+			label = "Power";
>+			linux,code = <KEY_POWER>;
>+			wakeup-source;
>+		};
>+
>+		key-home {
>+			debounce-interval = <10>;
>+			gpios = <&gpx0 5 GPIO_ACTIVE_LOW>;
>+			label = "Home";
>+			linux,code = <KEY_HOME>;
>+			wakeup-source;
>+		};
>+
>+		key-volume-up {
>+			debounce-interval = <10>;
>+			gpios = <&gpx0 2 GPIO_ACTIVE_LOW>;
>+			label = "Volume Up";
>+			linux,code = <KEY_VOLUMEUP>;
>+		};
>+
>+		key-volume-down {
>+			debounce-interval = <10>;
>+			gpios = <&gpx0 3 GPIO_ACTIVE_LOW>;
>+			label = "Volume Down";
>+			linux,code = <KEY_VOLUMEDOWN>;
>+		};
>+	};
>+};
>+
>+&cci {
>+	/* CCI is disabled in hardware */
>+	status = "disabled";
>+};
>+
>+&cpu0 {
>+	cpu-supply = <&buck2_reg>;
>+};
>+
>+&cpu4 {
>+	cpu-supply = <&buck6_reg>;
>+};
>+
>+&gpu {
>+	status = "okay";
>+	mali-supply = <&buck4_reg>;
>+};
>+
>+&hsi2c_7 {
>+	status = "okay";
>+
>+	pmic at 66 {
>+		compatible = "samsung,s2mps11-pmic";
>+		reg = <0x66>;
>+
>+		interrupt-parent = <&gpx3>;
>+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
>+		pinctrl-names = "default";
>+		pinctrl-0 = <&s2mps11_irq>;
>+
>+		s2mps11_osc: clocks {
>+			compatible = "samsung,s2mps11-clk";
>+			#clock-cells = <1>;
>+			clock-output-names = "s2mps11_ap", "s2mps11_cp",
>+					     "s2mps11_bt";
>+		};
>+
>+		regulators {
>+			buck1_reg: BUCK1 {
>+				regulator-name = "VDD_MIF_1V1";
>+				regulator-min-microvolt = <700000>;
>+				regulator-max-microvolt = <1300000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			buck2_reg: BUCK2 {
>+				regulator-name = "VDD_ARM_1V0";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <1500000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			buck3_reg: BUCK3 {
>+				regulator-name = "VDD_INT_1V0";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <1400000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			buck4_reg: BUCK4 {
>+				regulator-name = "VDD_G3D_1V0";
>+				regulator-min-microvolt = <700000>;
>+				regulator-max-microvolt = <1400000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			buck5_reg: BUCK5 {
>+				regulator-name = "VDD_MEM_1V2";
>+				regulator-min-microvolt = <1200000>;
>+				regulator-max-microvolt = <1200000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+
>+			};
>+
>+			buck6_reg: BUCK6 {
>+				regulator-name = "VDD_KFC_1V0";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <1500000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			buck7_reg: BUCK7 {
>+				regulator-name = "VIN_LLDO_1V4";
>+				regulator-min-microvolt = <1200000>;
>+				regulator-max-microvolt = <1500000>;
>+				regulator-always-on;
>+			};
>+
>+			buck8_reg: BUCK8 {
>+				regulator-name = "VIN_MLDO_2V0";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <2100000>;
>+				regulator-always-on;
>+			};
>+
>+			buck9_reg: BUCK9 {
>+				regulator-name = "VIN_HLDO_3V5";
>+				regulator-min-microvolt = <3000000>;
>+				regulator-max-microvolt = <3500000>;
>+				regulator-always-on;
>+			};
>+
>+			buck10_reg: BUCK10 {
>+				regulator-name = "VDD_CAM_ISP_1V0";
>+				regulator-min-microvolt = <750000>;
>+				regulator-max-microvolt = <3550000>;
>+			};
>+
>+			ldo1_reg: LDO1 {
>+				regulator-name = "VDD_ALIVE_1.0V";
>+				regulator-min-microvolt = <1000000>;
>+				regulator-max-microvolt = <1000000>;
>+				regulator-always-on;
>+			};
>+
>+			ldo2_reg: LDO2 {
>+				regulator-name = "VDD_APIO_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo3_reg: LDO3 {
>+				regulator-name = "VDD_APIO_MMC01_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo4_reg: LDO4 {
>+				regulator-name = "VDD_ADC_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo5_reg: LDO5 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO5";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+			};
>+
>+			ldo6_reg: LDO6 {
>+				regulator-name = "VDD_MIPI_1V0";
>+				regulator-min-microvolt = <1000000>;
>+				regulator-max-microvolt = <1000000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo7_reg: LDO7 {
>+				regulator-name =
>"VDD_MIPI_PLL_ABB1_18V";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo8_reg: LDO8 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+			};
>+
>+			ldo9_reg: LDO9 {
>+				regulator-name = "VDD_UOTG_3V0";
>+				regulator-min-microvolt = <3000000>;
>+				regulator-max-microvolt = <3000000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo10_reg: LDO10 {
>+				regulator-name = "VDDQ_PRE_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo11_reg: LDO11 {
>+				regulator-name = "VDD_HSIC_1V0";
>+				regulator-min-microvolt = <1000000>;
>+				regulator-max-microvolt = <1000000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo12_reg: LDO12 {
>+				regulator-name = "VDD_HSIC_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo13_reg: LDO13 {
>+				regulator-name = "VDD_APIO_MMC2_2V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <2800000>;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo14_reg: LDO14 {
>+				regulator-name = "VDD_MOTOR_3V0";
>+				regulator-min-microvolt = <3000000>;
>+				regulator-max-microvolt = <3000000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo15_reg: LDO15 {
>+				regulator-name = "VDD_LDO15";
>+				/*
>+				 * LDO15 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo16_reg: LDO16 {
>+				regulator-name = "VDD_AP_2V8";
>+				regulator-min-microvolt = <2800000>;
>+				regulator-max-microvolt = <2800000>;
>+				regulator-always-on;
>+				regulator-boot-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo17_reg: LDO17 {
>+				regulator-name = "VDD_LDO17";
>+				/*
>+				 * LDO17 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo18_reg: LDO18 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO18";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+			};
>+
>+
Nit: remove extra line here
Not sure if you need to re-spin the patch or may be Krzysztof will fix this
will applying
Rest looks fine.
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>


>+			ldo19_reg: LDO19 {
>+				regulator-name = "VDD_VTF_2V8";
>+				regulator-min-microvolt = <2800000>;
>+				regulator-max-microvolt = <2800000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo20_reg: LDO20 {
>+				regulator-name = "VDD_CAM1_CAM_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo21_reg: LDO21 {
>+				regulator-name = "VDD_CAM_IO_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo22_reg: LDO22 {
>+				regulator-name =
>"VDD_CAM0_S_CORE_1V1";
>+				regulator-min-microvolt = <1050000>;
>+				regulator-max-microvolt = <1200000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo23_reg: LDO23 {
>+				regulator-name = "VDD_MIFS_1V1";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <1100000>;
>+				regulator-always-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo24_reg: LDO24 {
>+				regulator-name = "VDD_TSP_3V3";
>+				regulator-min-microvolt = <3300000>;
>+				regulator-max-microvolt = <3300000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo25_reg: LDO25 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO25";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <3950000>;
>+			};
>+
>+			ldo26_reg: LDO26 {
>+				regulator-name = "VDD_CAM0_AF_2V8";
>+				regulator-min-microvolt = <2800000>;
>+				regulator-max-microvolt = <2800000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo27_reg: LDO27 {
>+				regulator-name = "VDD_G3DS_1V0";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <1000000>;
>+				regulator-always-on;
>+
>+				regulator-state-mem {
>+					regulator-on-in-suspend;
>+				};
>+			};
>+
>+			ldo28_reg: LDO28 {
>+				regulator-name = "VDD_LDO28";
>+				/*
>+				 * LDO28 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo29_reg: LDO29 {
>+				regulator-name = "VDD_LDO29";
>+				/*
>+				 * LDO29 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo30_reg: LDO30 {
>+				regulator-name = "VDD_TOUCH_1V8";
>+				regulator-min-microvolt = <1900000>;
>+				regulator-max-microvolt = <1900000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo31_reg: LDO31 {
>+				regulator-name = "VDD_LDO31";
>+				/*
>+				 * LDO31 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo32_reg: LDO32 {
>+				regulator-name = "VDD_LDO32";
>+				/*
>+				 * LDO32 varies between devices and is
>+				 * specified in the device dts
>+				 */
>+			};
>+
>+			ldo33_reg: LDO33 {
>+				regulator-name = "VDD_MHL_1V8";
>+				regulator-min-microvolt = <1800000>;
>+				regulator-max-microvolt = <1800000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo34_reg: LDO34 {
>+				regulator-name = "VDD_MHL_3V3";
>+				regulator-min-microvolt = <3300000>;
>+				regulator-max-microvolt = <3300000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo35_reg: LDO35 {
>+				regulator-name = "VDD_SIL_1V2";
>+				regulator-min-microvolt = <1200000>;
>+				regulator-max-microvolt = <1200000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+
>+			ldo36_reg: LDO36 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO36";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <3950000>;
>+			};
>+
>+			ldo37_reg: LDO37 {
>+				/* Unused */
>+				regulator-name = "VDD_LDO37";
>+				regulator-min-microvolt = <800000>;
>+				regulator-max-microvolt = <3950000>;
>+			};
>+
>+			ldo38_reg: LDO38 {
>+				regulator-name = "VDD_KEY_LED_3V3";
>+				regulator-min-microvolt = <2500000>;
>+				regulator-max-microvolt = <3300000>;
>+
>+				regulator-state-mem {
>+					regulator-off-in-suspend;
>+				};
>+			};
>+		};
>+	};
>+};
>+
>+&mixer {
>+	status = "okay";
>+};
>+
>+/* Internal storage */
>+&mmc_0 {
>+	status = "okay";
>+	bus-width = <8>;
>+	cap-mmc-highspeed;
>+	card-detect-delay = <200>;
>+	mmc-hs200-1_8v;
>+	non-removable;
>+	pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>;
>+	pinctrl-names = "default";
>+	samsung,dw-mshc-ciu-div = <3>;
>+	samsung,dw-mshc-ddr-timing = <0 2>;
>+	samsung,dw-mshc-sdr-timing = <0 4>;
>+	vqmmc-supply = <&ldo3_reg>;
>+};
>+
>+/* External sdcard */
>+&mmc_2 {
>+	status = "okay";
>+	bus-width = <4>;
>+	cap-sd-highspeed;
>+	card-detect-delay = <200>;
>+	cd-gpios = <&gpx2 4 GPIO_ACTIVE_LOW>;
>+	pinctrl-0 = <&sd2_clk &sd2_cmd &mmc2_cd &sd2_bus1 &sd2_bus4>;
>+	pinctrl-names = "default";
>+	samsung,dw-mshc-ciu-div = <3>;
>+	samsung,dw-mshc-ddr-timing = <0 2>;
>+	samsung,dw-mshc-sdr-timing = <0 4>;
>+	sd-uhs-sdr50;
>+	vmmc-supply = <&ldo19_reg>;
>+	vqmmc-supply = <&ldo13_reg>;
>+};
>+
>+&pinctrl_0 {
>+	mmc2_cd: mmc2-cd-pins {
>+		samsung,pins = "gpx2-4";
>+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>+	};
>+
>+	s2mps11_irq: s2mps11-irq-pins {
>+		samsung,pins = "gpx3-0";
>+		samsung,pin-function = <EXYNOS_PIN_FUNC_F>;
>+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
>+		samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>;
>+	};
>+};
>+
>+&rtc {
>+	status = "okay";
>+	clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
>+	clock-names = "rtc", "rtc_src";
>+};
>+
>+&tmu_cpu0 {
>+	vtmu-supply = <&ldo10_reg>;
>+};
>+
>+&tmu_cpu1 {
>+	vtmu-supply = <&ldo10_reg>;
>+};
>+
>+&tmu_cpu2 {
>+	vtmu-supply = <&ldo10_reg>;
>+};
>+
>+&tmu_cpu3 {
>+	vtmu-supply = <&ldo10_reg>;
>+};
>+
>+&tmu_gpu {
>+	vtmu-supply = <&ldo10_reg>;
>+};
>+
>+&usbdrd_dwc3_0 {
>+	dr_mode = "peripheral";
>+};
>+
>+&usbdrd_dwc3_1 {
>+	dr_mode = "peripheral";
>+};
>+
>+&usbdrd3_0 {
>+	vdd33-supply = <&ldo9_reg>;
>+	vdd10-supply = <&ldo11_reg>;
>+};
>+
>+&usbdrd3_1 {
>+	vdd33-supply = <&ldo9_reg>;
>+	vdd10-supply = <&ldo11_reg>;
>+};
>--
>2.34.1




From hws at denx.de  Wed Jan 19 07:20:12 2022
From: hws at denx.de (Harald Seiler)
Date: Wed, 19 Jan 2022 16:20:12 +0100
Subject: [PATCH] tty: serial: imx: Add fast path when rs485 delays are 0
In-Reply-To: <20220119151145.zft47rzebnabiej2@pengutronix.de>
References: <20220119145204.238767-1-hws@denx.de>
 <20220119151145.zft47rzebnabiej2@pengutronix.de>
Message-ID: <0df5d9ea2081f5d798f80297efb973f542dae183.camel@denx.de>

Hi,

On Wed, 2022-01-19 at 16:11 +0100, Uwe Kleine-K?nig wrote:
> On Wed, Jan 19, 2022 at 03:52:03PM +0100, Harald Seiler wrote:
> > Right now, even when `delay_rts_before_send` and `delay_rts_after_send`
> > are 0, the hrtimer is triggered (with timeout 0) which can introduce a
> > few 100us of additional overhead on slower i.MX platforms.
> > 
> > Implement a fast path when the delays are 0, where the RTS signal is
> > toggled immediately instead of going through an hrtimer.  This fast path
> > behaves identical to the code before delay support was implemented.
> > 
> > Signed-off-by: Harald Seiler <hws at denx.de>
> > ---
> >  drivers/tty/serial/imx.c | 18 ++++++++++++++----
> >  1 file changed, 14 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> > index df8a0c8b8b29..67bbbb69229d 100644
> > --- a/drivers/tty/serial/imx.c
> > +++ b/drivers/tty/serial/imx.c
> > @@ -455,9 +455,14 @@ static void imx_uart_stop_tx(struct uart_port *port)
> >  	if (port->rs485.flags & SER_RS485_ENABLED) {
> >  		if (sport->tx_state == SEND) {
> >  			sport->tx_state = WAIT_AFTER_SEND;
> > -			start_hrtimer_ms(&sport->trigger_stop_tx,
> > +
> > +			if (port->rs485.delay_rts_after_send > 0) {
> > +				start_hrtimer_ms(&sport->trigger_stop_tx,
> >  					 port->rs485.delay_rts_after_send);
> > -			return;
> > +				return;
> > +			}
> > +
> > +			/* continue without any delay */
> 
> Is it right to keep the assignment sport->tx_state = WAIT_AFTER_SEND ?

I am keeping the assignment intentionally, to fall into the
if(state == WAIT_AFTER_RTS) below (which then sets the state to OFF).
I originally had the code structured like this:

	if (port->rs485.delay_rts_after_send > 0) {
		sport->tx_state = WAIT_AFTER_SEND;
		start_hrtimer_ms(&sport->trigger_stop_tx,
			 port->rs485.delay_rts_after_send);
		return;
	} else {
		/* continue without any delay */
		sport->tx_state = WAIT_AFTER_SEND;
	}

This is functionally identical, but maybe a bit more explicit.

Not sure what is more clear to read?

> >  		}
> >  
> >  		if (sport->tx_state == WAIT_AFTER_RTS ||
> > @@ -698,9 +703,14 @@ static void imx_uart_start_tx(struct uart_port *port)
> >  				imx_uart_stop_rx(port);
> >  
> >  			sport->tx_state = WAIT_AFTER_RTS;
> > -			start_hrtimer_ms(&sport->trigger_start_tx,
> > +
> > +			if (port->rs485.delay_rts_before_send > 0) {
> > +				start_hrtimer_ms(&sport->trigger_start_tx,
> >  					 port->rs485.delay_rts_before_send);
> > -			return;
> > +				return;
> > +			}
> > +
> > +			/* continue without any delay */
> 
> Here similar question here about sport->tx_state = WAIT_AFTER_RTS;

Same as above, but with WAIT_AFTER_RTS of course...

-- 
Harald
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 850 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/7df47c79/attachment.sig>

From mark.rutland at arm.com  Wed Jan 19 07:22:09 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 15:22:09 +0000
Subject: [bootwrapper PATCH v2 09/13] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <YebvxEI+cnYMDu1j@sirena.org.uk>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-10-mark.rutland@arm.com>
 <20220117143104.28db5001@donnerap.cambridge.arm.com>
 <20220117180813.GD94025@C02TD0UTHF1T.local>
 <20220117183117.7f29dc66@donnerap.cambridge.arm.com>
 <YebvxEI+cnYMDu1j@sirena.org.uk>
Message-ID: <20220119152209.GA43919@C02TD0UTHF1T.local>

On Tue, Jan 18, 2022 at 04:50:12PM +0000, Mark Brown wrote:
> On Mon, Jan 17, 2022 at 06:31:17PM +0000, Andre Przywara wrote:
> > Mark Rutland <mark.rutland at arm.com> wrote:
> > > On Mon, Jan 17, 2022 at 02:31:04PM +0000, Andre Przywara wrote:
> > > > On Fri, 14 Jan 2022 10:56:49 +0000
> > > > Mark Rutland <mark.rutland at arm.com> wrote:
> 
> [Out of office this week so replies might be intermittent]
> 
> > > > And apart from bit 0 missing from it (as noted above), the existing
> > > > code writes 0x1ff into that register, presumable to cover future
> > > > vector length extensions beyond 2048 bits (which those RAZ/WI fields
> > > > in bits[8:4] seem to suggest).  
> 
> > > Hmm... I went and found the SVE supplement and I can't see any rationale
> > > for what SW *should* do, nor can I find a description of the register
> > > (that seems to have been factored into some XML files I can't convince
> > > anything to load on my machine).
> 
> ...
> 
> > > TBH, I'm not sure. In the absence of some documented guidance I'd prefer
> > > to go with 0xf, but given we already use 0x1ff, I want to dig into this
> > > a bit more.
> 
> I'm fairly sure I've seen some explicit discussion of this lurking
> somewhere, though I couldn't tell you where - DDI0584 A.i doesn't spell
> out the enumeration algorithm unfortunately AFAICT.  The theory is that
> the extra bits are reserved for any future extension of the vector
> length if needed since it'd be inconvenient to have to split the vector
> length field up.
> 
> > My impression was that this "[8:4] = RAZ/WI" compared to the "[63:9] =
> > RES0" fields suggests this is for a potential extension, but I guess there
> > would be more changes needed if SVE ever goes beyond 2048. So chances are
> > high we need to adopt the code then anyway, and fixing the number then is
> > the least of our problems.
> 
> > So I feel we should stick to what's explicitly documented, and put 0xf in
> > there.
> 
> We shouldn't need particularly many changes if the size of the field
> ever gets raised, with everything being dynamically sized already and
> the existing code starting off setting the WI bits to 1 the updates that
> are needed should just be on input validation.

Taking a look around, TF-A programs 0xf, and for consistency I think
it'd be clearer to only program the currently-allocated LEN bits.

I'll spin a preparatory patch reducing ZCR_EL3_LEN_MASK to 0xf (and
renaming that to ZCR_EL3_LEN_MAX).

If we need to grow it in future it should be trivial to do so.

Thanks,
Mark.


From mike.leach at linaro.org  Wed Jan 19 07:22:17 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Wed, 19 Jan 2022 15:22:17 +0000
Subject: [PATCH 1/1] coresight: Fix TRCCONFIGR.QE sysfs interface
In-Reply-To: <20220114173254.1876151-2-james.clark@arm.com>
References: <20220114173254.1876151-1-james.clark@arm.com>
 <20220114173254.1876151-2-james.clark@arm.com>
Message-ID: <CAJ9a7VhedrLMKfXBqzD_9fFxzKTg63-9wUM38Tw6ukhmSR9aoA@mail.gmail.com>

Hi James

On Fri, 14 Jan 2022 at 17:33, James Clark <james.clark at arm.com> wrote:
>
> It's impossible to program a valid value for TRCCONFIGR.QE
> when TRCIDR0.QSUPP==0b10. In that case the following is true:
>
>   Q element support is implemented, and only supports Q elements without
>   instruction counts. TRCCONFIGR.QE can only take the values 0b00 or 0b11.
>
> Currently the low bit of QSUPP is checked to see if the low bit of QE can
> be written to, but as you can see when QSUPP==0b10 the low bit is cleared
> making it impossible to ever write the only valid value of 0b11 to QE.
> 0b10 would be written instead, which is a reserved QE value even for all
> values of QSUPP.
>
> The fix is to allow writing the low bit of QE for any non zero value of
> QSUPP.
>
> This change doesn't go any further to validate if the user supplied value
> is valid, because none of the other parts this function do, but it does fix
> the case where it was impossible to ever set a valid value.
>

I concur that the input is not checked as valid, However all the other
fields are single bit - with no invalid values - other than the cond
field, which controls tracing of non-branch conditionals -
architecturally unsupported for A profile in ETMv4/.


> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> index a0640fa5c55b..a99bb537ea23 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> @@ -368,7 +368,7 @@ static ssize_t mode_store(struct device *dev,
>         /* start by clearing QE bits */
>         config->cfg &= ~(BIT(13) | BIT(14));
>         /* if supported, Q elements with instruction counts are enabled */
> -       if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
> +       if ((mode & BIT(0)) && drvdata->q_support)
>                 config->cfg |= BIT(13);

This can be trivially changed to

if ((mode)  && drvdata->q_support)
         config->cfg |= BIT(13);

to ensure that any input mode 2'b01, 2'b10, 2'b11 results in output
settings of 2'b01, 2'b11, 2'b11 respectively

With that

Reviewed-by: Mike Leach <mike.leach at linaro.org>

>         /*
>          * if supported, Q elements with and without instruction
> --
> 2.17.1
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From Eugen.Hristev at microchip.com  Wed Jan 19 07:40:38 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Wed, 19 Jan 2022 15:40:38 +0000
Subject: [PATCH v3 17/23] media: atmel: atmel-isc-base: use mutex to lock
 awb workqueue from streaming
In-Reply-To: <20220112085835.twjhxjnigl3uhgqj@uno.localdomain>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-18-eugen.hristev@microchip.com>
 <20220112085835.twjhxjnigl3uhgqj@uno.localdomain>
Message-ID: <f994c64d-b6cf-4302-d734-e422561db0b9@microchip.com>

On 1/12/22 10:58 AM, Jacopo Mondi wrote:
> Hi Eugen
> 
> On Mon, Dec 13, 2021 at 03:49:34PM +0200, Eugen Hristev wrote:
>> The AWB workqueue runs in a kernel thread and needs to be synchronized
>> w.r.t. the streaming status.
>> It is possible that streaming is stopped while the AWB workq is running.
>> In this case it is likely that the check for isc->stop is done at one point
>> in time, but the AWB computations are done later, including a call to
>> isc_update_profile, which requires streaming to be started.
>> Thus , isc_update_profile will fail if during this operation sequence the
>> streaming was stopped.
>> To solve this issue, a mutex is added, that will serialize the awb work and
>> streaming stopping, with the mention that either streaming is stopped
>> completely including termination of the last frame is done, and after that
>> the AWB work can check stream status and stop; either first AWB work is
>> completed and after that the streaming can stop correctly.
>> The awb spin lock cannot be used since this spinlock is taken in the same
>> context and using it in the stop streaming will result in a recursion BUG.
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> ---
>>   drivers/media/platform/atmel/atmel-isc-base.c | 31 ++++++++++++++++---
>>   drivers/media/platform/atmel/atmel-isc.h      |  1 +
>>   2 files changed, 28 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>> index b0c3ed21f372..53cac1aac0fd 100644
>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>> @@ -401,6 +401,7 @@ static void isc_stop_streaming(struct vb2_queue *vq)
>>        struct isc_buffer *buf;
>>        int ret;
>>
>> +     mutex_lock(&isc->awb_mutex);
>>        v4l2_ctrl_activate(isc->do_wb_ctrl, false);
>>
>>        isc->stop = true;
>> @@ -410,6 +411,8 @@ static void isc_stop_streaming(struct vb2_queue *vq)
>>                v4l2_err(&isc->v4l2_dev,
>>                         "Timeout waiting for end of the capture\n");
>>
>> +     mutex_unlock(&isc->awb_mutex);
>> +
>>        /* Disable DMA interrupt */
>>        regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
>>
>> @@ -1416,10 +1419,6 @@ static void isc_awb_work(struct work_struct *w)
>>        u32 min, max;
>>        int ret;
>>
>> -     /* streaming is not active anymore */
>> -     if (isc->stop)
>> -             return;
>> -
>>        if (ctrls->hist_stat != HIST_ENABLED)
>>                return;
>>
>> @@ -1470,7 +1469,24 @@ static void isc_awb_work(struct work_struct *w)
>>        }
>>        regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
>>                     hist_id | baysel | ISC_HIS_CFG_RAR);
> 
> isc_stop_streaming() calls runtime_put and here you access the hw.

Hi Jacopo,

That is correct. However the awb routine will call resume and get here 
(before accessing the hardware) :

https://elixir.bootlin.com/linux/latest/source/drivers/media/platform/atmel/atmel-isc-base.c#L1722

So I think that we are good as we are now

> 
> Feels like it's safer to hold the mutex for the whole duration of the
> AWB routine ?
> 

I prefer to have the critical section as little as possible. As we are 
only synchronizing the 'streaming status' , only this should be under 
the lock.

If you have a different opinion, let me know.

Eugen

>> +
>> +     /*
>> +      * We have to make sure the streaming has not stopped meanwhile.
>> +      * ISC requires a frame to clock the internal profile update.
>> +      * To avoid issues, lock the sequence with a mutex
>> +      */
>> +     mutex_lock(&isc->awb_mutex);
>> +
>> +     /* streaming is not active anymore */
>> +     if (isc->stop) {
>> +             mutex_unlock(&isc->awb_mutex);
>> +             return;
>> +     };
>> +
>>        isc_update_profile(isc);
>> +
>> +     mutex_unlock(&isc->awb_mutex);
>> +
>>        /* if awb has been disabled, we don't need to start another histogram */
>>        if (ctrls->awb)
>>                regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
>> @@ -1549,6 +1565,8 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>
>>                isc_update_awb_ctrls(isc);
>>
>> +             mutex_lock(&isc->awb_mutex);
>> +
>>                if (!isc->stop) {
>>                        /*
>>                         * If we are streaming, we can update profile to
>> @@ -1563,6 +1581,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
>>                         */
>>                        v4l2_ctrl_activate(isc->do_wb_ctrl, false);
>>                }
>> +             mutex_unlock(&isc->awb_mutex);
>>
>>                /* if we have autowhitebalance on, start histogram procedure */
>>                if (ctrls->awb == ISC_WB_AUTO && !isc->stop &&
>> @@ -1754,6 +1773,7 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
>>   {
>>        struct isc_device *isc = container_of(notifier->v4l2_dev,
>>                                              struct isc_device, v4l2_dev);
>> +     mutex_destroy(&isc->awb_mutex);
>>        cancel_work_sync(&isc->awb_work);
>>        video_unregister_device(&isc->video_dev);
>>        v4l2_ctrl_handler_free(&isc->ctrls.handler);
>> @@ -1866,6 +1886,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>        isc->current_subdev = container_of(notifier,
>>                                           struct isc_subdev_entity, notifier);
>>        mutex_init(&isc->lock);
>> +     mutex_init(&isc->awb_mutex);
>> +
>>        init_completion(&isc->comp);
>>
>>        /* Initialize videobuf2 queue */
>> @@ -1941,6 +1963,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
>>        video_unregister_device(vdev);
>>
>>   isc_async_complete_err:
>> +     mutex_destroy(&isc->awb_mutex);
>>        mutex_destroy(&isc->lock);
>>        return ret;
>>   }
>> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
>> index 0b6370d7775f..c2cb805faff3 100644
>> --- a/drivers/media/platform/atmel/atmel-isc.h
>> +++ b/drivers/media/platform/atmel/atmel-isc.h
>> @@ -307,6 +307,7 @@ struct isc_device {
>>        struct work_struct      awb_work;
>>
>>        struct mutex            lock; /* serialize access to file operations */
>> +     struct mutex            awb_mutex; /* serialize access to streaming status from awb work queue */
>>        spinlock_t              awb_lock; /* serialize access to DMA buffers from awb work queue */
>>
>>        struct regmap_field     *pipeline[ISC_PIPE_LINE_NODE_NUM];
>> --
>> 2.25.1
>>


From lkp at intel.com  Wed Jan 19 07:46:18 2022
From: lkp at intel.com (kernel test robot)
Date: Wed, 19 Jan 2022 23:46:18 +0800
Subject: [xilinx-xlnx:master 340/360]
 drivers/phy/xilinx/xilinx_dpgtquadphy.c:49:17: error: implicit declaration
 of function 'FIELD_PREP'
Message-ID: <202201192322.1y7ZM7N6-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   dc405906cdb8a89cd81b6ca4f438fe213c187cb2
commit: a2af060c77e92bff35d0f7176cc5139115ff29b9 [340/360] phy: Add driver for GTQUAD BASE for Displayport
config: parisc-allyesconfig (https://download.01.org/0day-ci/archive/20220119/202201192322.1y7ZM7N6-lkp at intel.com/config)
compiler: hppa-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/a2af060c77e92bff35d0f7176cc5139115ff29b9
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout a2af060c77e92bff35d0f7176cc5139115ff29b9
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=parisc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/phy/xilinx/xilinx_dpgtquadphy.c: In function 'xdpgtquad_init':
>> drivers/phy/xilinx/xilinx_dpgtquadphy.c:49:17: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
      49 |         data |= FIELD_PREP(GT_QUAD_BASE_CH1_CLK_DIV_MASK,
         |                 ^~~~~~~~~~
   cc1: some warnings being treated as errors

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for DRM_PANEL_SIMPLE
   Depends on HAS_IOMEM && DRM && DRM_PANEL && OF && BACKLIGHT_CLASS_DEVICE && PM
   Selected by
   - DRM_XLNX_DSI && HAS_IOMEM && DRM_XLNX


vim +/FIELD_PREP +49 drivers/phy/xilinx/xilinx_dpgtquadphy.c

    34	
    35	static int xdpgtquad_init(struct phy *phy)
    36	{
    37		struct dpgtquadphy_dev *gtquad = phy_get_drvdata(phy);
    38		u32 data;
    39	
    40		/*
    41		 * Unlocking the NPI space so that GT CH1 divider value can be
    42		 * programmed. This will generate a /20 clk
    43		 */
    44		writel(GT_QUAD_BASE_CTL_VALUE,
    45		       gtquad->base + GT_QUAD_BASE_CTL);
    46	
    47		data = readl(gtquad->base + GT_QUAD_BASE_CH1_CLK_DIV_REG);
    48		data &= ~GT_QUAD_BASE_CH1_CLK_DIV_MASK;
  > 49		data |= FIELD_PREP(GT_QUAD_BASE_CH1_CLK_DIV_MASK,
    50				   GT_QUAD_BASE_CH1_CLK_DIV_VALUE);
    51		writel(data, gtquad->base + GT_QUAD_BASE_CH1_CLK_DIV_REG);
    52	
    53		return 0;
    54	}
    55	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From arnd at arndb.de  Wed Jan 19 08:06:51 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 19 Jan 2022 17:06:51 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
Message-ID: <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>

On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
<semen.protsenko at linaro.org> wrote:
> On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
>
> Hi Olof, Arnd,
>
> Just want to check if it's possible for those patches to be applied in
> v5.17? Sorry for the noise, but that's important to me.

I can see that Olof merged merged this into the "arm/late" branch in
the soc tree,
so I assume he still plans to send it in the next few days.

With the timing over Christmas, I sent out the large bulk of the
contents (anything
I merged before Dec 23) last year, and Linus already merged it, the rest ended
up in the "late" branch.

As usual, there is no guarantee that late changes make it in, but I have seen
no indication of any problems so far.

      Arnd


From robh at kernel.org  Wed Jan 19 08:11:53 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 19 Jan 2022 10:11:53 -0600
Subject: [PATCH] dt-bindings: rtc: st,stm32-rtc: Make each example a
 separate entry
In-Reply-To: <20220106182518.1435497-7-robh@kernel.org>
References: <20220106182518.1435497-7-robh@kernel.org>
Message-ID: <Yeg4Sba3eye24+LG@robh.at.kernel.org>

On Thu, 06 Jan 2022 12:25:15 -0600, Rob Herring wrote:
> Each independent example should be a separate entry. This allows for
> 'interrupts' to have different cell sizes.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Applied, thanks!


From linus.walleij at linaro.org  Wed Jan 19 08:12:11 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Wed, 19 Jan 2022 17:12:11 +0100
Subject: [PATCH v2] pinctrl: at91-pio4: Use platform_get_irq() to get the
 interrupt
In-Reply-To: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
References: <20220104140913.29699-1-prabhakar.mahadev-lad.rj@bp.renesas.com>
Message-ID: <CACRpkdY-=7dTn8WosPUmQRPkE_VMoupgupYUHYLkwrRrb=1Tig@mail.gmail.com>

On Tue, Jan 4, 2022 at 3:10 PM Lad Prabhakar
<prabhakar.mahadev-lad.rj at bp.renesas.com> wrote:

> platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static
> allocation of IRQ resources in DT core code, this causes an issue
> when using hierarchical interrupt domains using "interrupts" property
> in the node as this bypasses the hierarchical setup and messes up the
> irq chaining.
>
> In preparation for removal of static setup of IRQ resource from DT core
> code use platform_get_irq().
>
> While at it, replace the dev_err() with dev_dbg() as platform_get_irq()
> prints an error message upon error.
>
> Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj at bp.renesas.com>

Patch applied!

Yours,
Linus Walleij


From u.kleine-koenig at pengutronix.de  Wed Jan 19 08:21:22 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Wed, 19 Jan 2022 17:21:22 +0100
Subject: [PATCH] tty: serial: imx: Add fast path when rs485 delays are 0
In-Reply-To: <0df5d9ea2081f5d798f80297efb973f542dae183.camel@denx.de>
References: <20220119145204.238767-1-hws@denx.de>
 <20220119151145.zft47rzebnabiej2@pengutronix.de>
 <0df5d9ea2081f5d798f80297efb973f542dae183.camel@denx.de>
Message-ID: <20220119162122.jmnz2hxid76p4hli@pengutronix.de>

On Wed, Jan 19, 2022 at 04:20:12PM +0100, Harald Seiler wrote:
> Hi,
> 
> On Wed, 2022-01-19 at 16:11 +0100, Uwe Kleine-K?nig wrote:
> > On Wed, Jan 19, 2022 at 03:52:03PM +0100, Harald Seiler wrote:
> > > Right now, even when `delay_rts_before_send` and `delay_rts_after_send`
> > > are 0, the hrtimer is triggered (with timeout 0) which can introduce a
> > > few 100us of additional overhead on slower i.MX platforms.
> > > 
> > > Implement a fast path when the delays are 0, where the RTS signal is
> > > toggled immediately instead of going through an hrtimer.  This fast path
> > > behaves identical to the code before delay support was implemented.
> > > 
> > > Signed-off-by: Harald Seiler <hws at denx.de>
> > > ---
> > >  drivers/tty/serial/imx.c | 18 ++++++++++++++----
> > >  1 file changed, 14 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> > > index df8a0c8b8b29..67bbbb69229d 100644
> > > --- a/drivers/tty/serial/imx.c
> > > +++ b/drivers/tty/serial/imx.c
> > > @@ -455,9 +455,14 @@ static void imx_uart_stop_tx(struct uart_port *port)
> > >  	if (port->rs485.flags & SER_RS485_ENABLED) {
> > >  		if (sport->tx_state == SEND) {
> > >  			sport->tx_state = WAIT_AFTER_SEND;
> > > -			start_hrtimer_ms(&sport->trigger_stop_tx,
> > > +
> > > +			if (port->rs485.delay_rts_after_send > 0) {
> > > +				start_hrtimer_ms(&sport->trigger_stop_tx,
> > >  					 port->rs485.delay_rts_after_send);
> > > -			return;
> > > +				return;
> > > +			}
> > > +
> > > +			/* continue without any delay */
> > 
> > Is it right to keep the assignment sport->tx_state = WAIT_AFTER_SEND ?
> 
> I am keeping the assignment intentionally, to fall into the
> if(state == WAIT_AFTER_RTS) below (which then sets the state to OFF).
> I originally had the code structured like this:
> 
> 	if (port->rs485.delay_rts_after_send > 0) {
> 		sport->tx_state = WAIT_AFTER_SEND;
> 		start_hrtimer_ms(&sport->trigger_stop_tx,
> 			 port->rs485.delay_rts_after_send);
> 		return;
> 	} else {
> 		/* continue without any delay */
> 		sport->tx_state = WAIT_AFTER_SEND;
> 	}
> 
> This is functionally identical, but maybe a bit more explicit.
> 
> Not sure what is more clear to read?

I didn't oppose to the readability thing. With your patch you skip
starting the stop_tx timer and that would usually care for calling
imx_uart_stop_tx and setting sport->tx_state = OFF. This doesn't happen
with your patch any more.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/8b2bc38a/attachment-0001.sig>

From willy at infradead.org  Wed Jan 19 08:27:32 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 16:27:32 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
Message-ID: <Yeg79CcofyNuVLid@casper.infradead.org>

On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> 
> Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> true...

Even if it does blow up, at least it's blowing up here where someone
can start to debug it, rather than blowing up on first access, where
we no longer have the invlid struct page pointer.

I don't think we have a 'page_valid' function which will tell us whether
a random pointer is actually a struct page or not.


From broonie at kernel.org  Wed Jan 19 08:30:29 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Jan 2022 16:30:29 +0000
Subject: [PATCH] dt-bindings: Drop unnecessary pinctrl properties
In-Reply-To: <20220119015325.2438277-1-robh@kernel.org>
References: <20220119015325.2438277-1-robh@kernel.org>
Message-ID: <Yeg8pWYUwWKqOjhe@sirena.org.uk>

On Tue, Jan 18, 2022 at 07:53:25PM -0600, Rob Herring wrote:
> For a single pinctrl mode, it is not necessary to define pinctrl
> properties as the tools always allow pinctrl properties.

Acked-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/4fff06e3/attachment.sig>

From olof at lixom.net  Wed Jan 19 08:53:05 2022
From: olof at lixom.net (Olof Johansson)
Date: Wed, 19 Jan 2022 08:53:05 -0800
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
Message-ID: <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
> <semen.protsenko at linaro.org> wrote:
> > On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> >
> > Hi Olof, Arnd,
> >
> > Just want to check if it's possible for those patches to be applied in
> > v5.17? Sorry for the noise, but that's important to me.
>
> I can see that Olof merged merged this into the "arm/late" branch in
> the soc tree,
> so I assume he still plans to send it in the next few days.

Yep, will be sent up today most likely.

> With the timing over Christmas, I sent out the large bulk of the
> contents (anything
> I merged before Dec 23) last year, and Linus already merged it, the rest ended
> up in the "late" branch.
>
> As usual, there is no guarantee that late changes make it in, but I have seen
> no indication of any problems so far.

Correct. Been sitting on it for a while in case there were fixes
coming in for the first pieces that got merged, but in traditional
fashion I'm guessing those will start to show up a few days after the
late branch gets merged. :)


-Olof


From hws at denx.de  Wed Jan 19 08:59:46 2022
From: hws at denx.de (Harald Seiler)
Date: Wed, 19 Jan 2022 17:59:46 +0100
Subject: [PATCH] tty: serial: imx: Add fast path when rs485 delays are 0
In-Reply-To: <20220119162122.jmnz2hxid76p4hli@pengutronix.de>
References: <20220119145204.238767-1-hws@denx.de>
 <20220119151145.zft47rzebnabiej2@pengutronix.de>
 <0df5d9ea2081f5d798f80297efb973f542dae183.camel@denx.de>
 <20220119162122.jmnz2hxid76p4hli@pengutronix.de>
Message-ID: <5cab27cab5a39ef5e19992bc54e57c3f6106dafe.camel@denx.de>

Hi,

On Wed, 2022-01-19 at 17:21 +0100, Uwe Kleine-K?nig wrote:
> On Wed, Jan 19, 2022 at 04:20:12PM +0100, Harald Seiler wrote:
> > Hi,
> > 
> > On Wed, 2022-01-19 at 16:11 +0100, Uwe Kleine-K?nig wrote:
> > > On Wed, Jan 19, 2022 at 03:52:03PM +0100, Harald Seiler wrote:
> > > > Right now, even when `delay_rts_before_send` and `delay_rts_after_send`
> > > > are 0, the hrtimer is triggered (with timeout 0) which can introduce a
> > > > few 100us of additional overhead on slower i.MX platforms.
> > > > 
> > > > Implement a fast path when the delays are 0, where the RTS signal is
> > > > toggled immediately instead of going through an hrtimer.  This fast path
> > > > behaves identical to the code before delay support was implemented.
> > > > 
> > > > Signed-off-by: Harald Seiler <hws at denx.de>
> > > > ---
> > > >  drivers/tty/serial/imx.c | 18 ++++++++++++++----
> > > >  1 file changed, 14 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
> > > > index df8a0c8b8b29..67bbbb69229d 100644
> > > > --- a/drivers/tty/serial/imx.c
> > > > +++ b/drivers/tty/serial/imx.c
> > > > @@ -455,9 +455,14 @@ static void imx_uart_stop_tx(struct uart_port *port)
> > > >  	if (port->rs485.flags & SER_RS485_ENABLED) {
> > > >  		if (sport->tx_state == SEND) {
> > > >  			sport->tx_state = WAIT_AFTER_SEND;
> > > > -			start_hrtimer_ms(&sport->trigger_stop_tx,
> > > > +
> > > > +			if (port->rs485.delay_rts_after_send > 0) {
> > > > +				start_hrtimer_ms(&sport->trigger_stop_tx,
> > > >  					 port->rs485.delay_rts_after_send);
> > > > -			return;
> > > > +				return;
> > > > +			}
> > > > +
> > > > +			/* continue without any delay */
> > > 
> > > Is it right to keep the assignment sport->tx_state = WAIT_AFTER_SEND ?
> > 
> > I am keeping the assignment intentionally, to fall into the
> > if(state == WAIT_AFTER_RTS) below (which then sets the state to OFF).
> > I originally had the code structured like this:
> > 
> > 	if (port->rs485.delay_rts_after_send > 0) {
> > 		sport->tx_state = WAIT_AFTER_SEND;
> > 		start_hrtimer_ms(&sport->trigger_stop_tx,
> > 			 port->rs485.delay_rts_after_send);
> > 		return;
> > 	} else {
> > 		/* continue without any delay */
> > 		sport->tx_state = WAIT_AFTER_SEND;
> > 	}
> > 
> > This is functionally identical, but maybe a bit more explicit.
> > 
> > Not sure what is more clear to read?
> 
> I didn't oppose to the readability thing. With your patch you skip
> starting the stop_tx timer and that would usually care for calling
> imx_uart_stop_tx and setting sport->tx_state = OFF. This doesn't happen
> with your patch any more.

Not starting the timer is the entire point of the patch - instead, the
code which would run inside the timer callback now runs immediately. To
do this, I set the tx_state to WAIT_AFTER_SEND and _don't_ do the early
return which leads into the if(tx_state == WAIT_AFTER_SEND) below.  This
is the code-path which normally runs later in the hrtimer callback.

I suppose it would have been good to provide more context lines in the
patch... Here is the relevant bit (in the changed version now):

	if (sport->tx_state == SEND) {
		sport->tx_state = WAIT_AFTER_SEND;

		if (port->rs485.delay_rts_after_send > 0) {
			start_hrtimer_ms(&sport->trigger_stop_tx,
				 port->rs485.delay_rts_after_send);
			return;
		}

		/* continue without any delay */
	}

	if (sport->tx_state == WAIT_AFTER_RTS ||
	    sport->tx_state == WAIT_AFTER_SEND) {
		/* ... actual rts toggling ... */

		sport->tx_state = OFF;
	}

Regards,
-- 
Harald
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 850 bytes
Desc: This is a digitally signed message part
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/093cfa6f/attachment.sig>

From yury.norov at gmail.com  Wed Jan 19 09:00:23 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Wed, 19 Jan 2022 09:00:23 -0800
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YefzAQ5LXJk1ytfI@FVFF77S0Q05N>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <YefzAQ5LXJk1ytfI@FVFF77S0Q05N>
Message-ID: <CAAH8bW-CxxL7DkBdHeZ60ZyPKJ8EOY2rh+hCEiyeH7Kih42EQQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 3:17 AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> Hi,
>
> I replied ot the original RFC before spotting this; duplicating those comments
> here because I think they apply regardless of the mechanism used to work around
> this.
>
> On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
> > vmap() takes struct page *pages as one of arguments, and user may provide
> > an invalid pointer which would lead to DABT at address translation later.
> >
> > Currently, kernel checks the pages against NULL. In my case, however, the
> > address was not NULL, and was big enough so that the hardware generated
> > Address Size Abort on arm64.
>
> Can you give an example of when this might happen? It sounds like you're
> actually hitting this, so a backtrace would be nice.
>
> I'm a bit confused as to when why we'd try to vmap() pages that we
> didn't have a legitimate struct page for -- where did these addresses
> come from?
>
> It sounds like this is going wrong at a higher level, and we're passing
> entirely bogus struct page pointers around. This seems like the sort of
> thing DEBUG_VIRTUAL or similar should check when we initially generate
> the struct page pointer.

Hi Mark,

This is an out-of-tree code that does:

    vaddr1 = dma_alloc_coherent()
    page = virt_to_page() // Wrong here
    ...
    vaddr2 = vmap(page)
    memset(vaddr2) // Fault here

virt_to_page() returns a wrong pointer if vaddr1 is not a linear kernel address.
The problem is that vmap() populates pte with bad pfn successfully, and it's
much harder to debug at memory access time.

> > Interestingly, this abort happens even if copy_from_kernel_nofault() is
> > used, which is quite inconvenient for debugging purposes.
>
> I can go take a look at this, but TBH we never expect to take an address size
> fault to begin with, so this is arguably correct -- it's an internal
> consistency problem.
>
> > This patch adds a pfn_valid() check into vmap() path, so that invalid
> > mapping will not be created.
> >
> > RFC: https://lkml.org/lkml/2022/1/18/815
> > v1: use pfn_valid() instead of adding an arch-specific
> >     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
> >
> > Signed-off-by: Yury Norov <yury.norov at gmail.com>
> > ---
> >  mm/vmalloc.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > index d2a00ad4e1dd..a4134ee56b10 100644
> > --- a/mm/vmalloc.c
> > +++ b/mm/vmalloc.c
> > @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
> >                       return -EBUSY;
> >               if (WARN_ON(!page))
> >                       return -ENOMEM;
> > +             if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > +                     return -EINVAL;
>
> My fear here is that for this to fire, we've already passed a bogus struct page
> pointer around the intermediate infrastructure, and any of that might try to
> use it in unsafe ways (in future even if we don't use it today).
>
> I think the fundamental issue here is that we generate a bogus struct page
> pointer at all, and knowing where that came from would help to fix that.

You're right. That's why WARN_ON() is used for the page == null in the code
above, I believe, - to let client code know that something goes wrong, and it's
not a regular ENOMEM situation.

Thanks,
Yury

> Thanks,
> Mark.
>
> >               set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
> >               (*nr)++;
> >       } while (pte++, addr += PAGE_SIZE, addr != end);
> > --
> > 2.30.2
> >


From krzysztof.kozlowski at canonical.com  Wed Jan 19 09:00:56 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 18:00:56 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
Message-ID: <CA+Eumj5sosSkCCANOVqN8fVUDFaSNtB7+f95o+FAp7w6rM4A=A@mail.gmail.com>

On Wed, 19 Jan 2022 at 17:53, Olof Johansson <olof at lixom.net> wrote:
>
> On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
> >
> > On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
> > <semen.protsenko at linaro.org> wrote:
> > > On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> > >
> > > Hi Olof, Arnd,
> > >
> > > Just want to check if it's possible for those patches to be applied in
> > > v5.17? Sorry for the noise, but that's important to me.
> >
> > I can see that Olof merged merged this into the "arm/late" branch in
> > the soc tree,
> > so I assume he still plans to send it in the next few days.
>
> Yep, will be sent up today most likely.
>
> > With the timing over Christmas, I sent out the large bulk of the
> > contents (anything
> > I merged before Dec 23) last year, and Linus already merged it, the rest ended
> > up in the "late" branch.
> >
> > As usual, there is no guarantee that late changes make it in, but I have seen
> > no indication of any problems so far.
>
> Correct. Been sitting on it for a while in case there were fixes
> coming in for the first pieces that got merged, but in traditional
> fashion I'm guessing those will start to show up a few days after the
> late branch gets merged. :)

Actually I have such, but to prepare a pull with them, I would need to
base it on some random Linus' commit, not on v5.17-rc1. Therefore I
wait for v5.17-rc1. Would you prefer different approach?

Best regards,
Krzysztof


From yury.norov at gmail.com  Wed Jan 19 09:22:58 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Wed, 19 Jan 2022 09:22:58 -0800
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <Yedgj+Lo2eru8197@casper.infradead.org>
 <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>
Message-ID: <CAAH8bW_=KtrwLpg4tx+1tdMjN2mUiuLOoZH6nvbn8qNjU6aB3A@mail.gmail.com>

On Tue, Jan 18, 2022 at 10:17 PM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
>
>
> On 1/19/22 6:21 AM, Matthew Wilcox wrote:
> > On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
> >> vmap() takes struct page *pages as one of arguments, and user may provide
> >> an invalid pointer which would lead to DABT at address translation later.
> >
> > Could we spell out 'DABT'?  Presumably that's an ARM-specific thing.
> > Just like we don't say #PF for Intel page faults, I think this is
> > probably a 'data abort'?
>
> Right, it is data abort.
>
> >
> >> Currently, kernel checks the pages against NULL. In my case, however, the
> >> address was not NULL, and was big enough so that the hardware generated
> >> Address Size Abort on arm64.
>
> Could you please provide the actual abort stack here with details.

[  665.484101] Unhandled fault at 0xffff8000252cd000
[  665.488807] Mem abort info:
[  665.491617]   ESR = 0x96000043
[  665.494675]   EC = 0x25: DABT (current EL), IL = 32 bits
[  665.499985]   SET = 0, FnV = 0
[  665.503039]   EA = 0, S1PTW = 0
[  665.506167] Data abort info:
[  665.509047]   ISV = 0, ISS = 0x00000043
[  665.512882]   CM = 0, WnR = 1
[  665.515851] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000818cb000
[  665.522550] [ffff8000252cd000] pgd=000000affcfff003,
pud=000000affcffe003, pmd=0000008fad8c3003, pte=00688000a5217713
[  665.533160] Internal error: level 3 address size fault: 96000043 [#1] SMP
[  665.539936] Modules linked in: [...]
[  665.616212] CPU: 178 PID: 13199 Comm: test Tainted: P           OE
   5.4.0-84-generic #94~18.04.1-Ubuntu
[  665.626806] Hardware name: HPE Apollo 70             /C01_APACHE_MB
        , BIOS L50_5.13_1.0.6 07/10/2018
[  665.636618] pstate: 80400009 (Nzcv daif +PAN -UAO)
[  665.641407] pc : __memset+0x38/0x188
[  665.645146] lr : test+0xcc/0x3f8
[  665.650184] sp : ffff8000359bb840
[  665.653486] x29: ffff8000359bb840 x28: 0000000000000000
[  665.658785] x27: 0000000000000000 x26: 0000000000231000
[  665.664083] x25: ffff00ae660f6110 x24: ffff00ae668cb800
[  665.669382] x23: 0000000000000001 x22: ffff00af533e5000
[  665.674680] x21: 0000000000001000 x20: 0000000000000000
[  665.679978] x19: ffff00ae66950000 x18: ffffffffffffffff
[  665.685276] x17: 00000000588636a5 x16: 0000000000000013
[  665.690574] x15: ffffffffffffffff x14: 000000000007ffff
[  665.695872] x13: 0000000080000000 x12: 0140000000000000
[  665.701170] x11: 0000000000000041 x10: ffff8000652cd000
[  665.706468] x9 : ffff8000252cf000 x8 : ffff8000252cd000
[  665.711767] x7 : 0303030303030303 x6 : 0000000000001000
[  665.717065] x5 : ffff8000252cd000 x4 : 0000000000000000
[  665.722363] x3 : ffff8000252cdfff x2 : 0000000000000001
[  665.727661] x1 : 0000000000000003 x0 : ffff8000252cd000
[  665.732960] Call trace:
[  665.735395]  __memset+0x38/0x188
[...]

TCR_EL1 is 34b5503510, and so TCR_EL1.IPS is 0b100. The pfn that caused
address size abort has bit#47 set, which is far above 16TB that is allowed by
ips == 100.

> >>
> >> Interestingly, this abort happens even if copy_from_kernel_nofault() is
> >> used, which is quite inconvenient for debugging purposes.
> >>
> >> This patch adds a pfn_valid() check into vmap() path, so that invalid
> >> mapping will not be created.
> >>
> >> RFC: https://lkml.org/lkml/2022/1/18/815
> >> v1: use pfn_valid() instead of adding an arch-specific
> >>     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
>
> This should be after the '---' below.
>
> >>
> >> Signed-off-by: Yury Norov <yury.norov at gmail.com>
> >
> > Suggested-by: Matthew Wilcox (Oracle) <willy at infradead.org>
> >
> >> ---
> >>  mm/vmalloc.c | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> >> index d2a00ad4e1dd..a4134ee56b10 100644
> >> --- a/mm/vmalloc.c
> >> +++ b/mm/vmalloc.c
> >> @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
> >>                      return -EBUSY;
> >>              if (WARN_ON(!page))
> >>                      return -ENOMEM;
> >> +            if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> >> +                    return -EINVAL;
> >>              set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
> >>              (*nr)++;
> >>      } while (pte++, addr += PAGE_SIZE, addr != end);
> >> --
> >> 2.30.2
> >>
>
> Why should not this just scan over the entire user provided struct page
> array and make sure that all pages there in are valid via above method,
> but in vmap() itself before calling vmap_pages_range(). Because seems
> like a single invalid page detected in vmap_pages_pte_range() will
> anyways abort the entire vmap(). This will also enable us to drop the
> existing NULL check above.

I can do this, but why is it any better than the current approach?

Thanks,
Yury


From u.kleine-koenig at pengutronix.de  Wed Jan 19 09:24:39 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Wed, 19 Jan 2022 18:24:39 +0100
Subject: [PATCH v10 1/3] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
References: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
Message-ID: <20220119172439.be4xpaqgwzdy26oh@pengutronix.de>

On Tue, Dec 14, 2021 at 06:27:17PM +0200, Baruch Siach wrote:
> From: Baruch Siach <baruch.siach at siklu.com>
> 
> Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
> driver from downstream Codeaurora kernel tree. Removed support for older
> (V1) variants because I have no access to that hardware.
> 
> Tested on IPQ6010 based hardware.
> 
> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> ---
> v10:
> 
>   Restore round up in pwm_div calculation; otherwise diff is always <=
>   0, so only bingo match works
> 
>   Don't overwrite min_diff on every loop iteration
> 
> v9:
> 
> Address comment from Uwe Kleine-K?nig:
> 
>   Use period_ns*rate in dividers calculation for better accuracy
> 
>   Round down pre_div and pwm_div
> 
>   Add a comment explaining why pwm_div can't underflow
> 
>   Add a comment explaining why pre_div > pwm_div end the search loop
> 
>   Drop 'CFG_' from register macros
> 
>   Rename to_ipq_pwm_chip() to ipq_pwm_from_chip()
> 
>   Change bare 'unsigned' to 'unsigned int'
> 
>   Clarify the comment on separate REG1 write for enable/disable
> 
>   Round up the period value in .get_state
> 
>   Use direct readl/writel so no need to check for regmap errors
> 
> v7:
> 
>   Change 'offset' to 'reg' for the tcsr offset (Rob)
> 
>   Drop clock name; there is only one clock (Bjorn)
> 
>   Simplify probe failure code path (Bjorn)
> 
> v6:
> 
> Address Uwe Kleine-K?nig review comments:
> 
>   Drop IPQ_PWM_MAX_DEVICES
> 
>   Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ
> 
>   Simplify register offset calculation
> 
>   Calculate duty cycle more precisely
> 
>   Refuse to set inverted polarity
> 
>   Drop redundant IPQ_PWM_REG1_ENABLE bit clear
> 
>   Remove x1000 factor in pwm_div calculation, use rate directly, and round up
> 
>   Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV
> 
>   Ensure pre_div <= pwm_div
> 
>   Rename close_ to best_
> 
>   Explain in comment why effective_div doesn't overflow
> 
>   Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle
> 
>   Disable clock only after pwmchip_remove()
> 
>   const pwm_ops
> 
> Other changes:
> 
>   Add missing linux/bitfield.h header include (kernel test robot)
> 
>   Adjust code for PWM device node under TCSR (Rob Herring)
> 
> v5:
> 
> Use &tcsr_q6 syscon to access registers (Bjorn Andersson)
> 
> Address Uwe Kleine-K?nig review comments:
> 
>   Implement .get_state()
> 
>   Add IPQ_PWM_ prefix to local macros
> 
>   Use GENMASK/BIT/FIELD_PREP for register fields access
> 
>   Make type of config_div_and_duty() parameters consistent
> 
>   Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ
> 
>   Integrate enable/disable into config_div_and_duty() to save register read,
>   and reduce frequency glitch on update
> 
>   Use min() instead of min_t()
> 
>   Fix comment format
> 
>   Use dev_err_probe() to indicate probe step failure
> 
>   Add missing clk_disable_unprepare() in .remove
> 
>   Don't set .owner
> 
> v4:
> 
>   Use div64_u64() to fix link for 32-bit targets ((kernel test robot
>   <lkp at intel.com>, Uwe Kleine-K?nig)
> 
> v3:
> 
>   s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> 
>   Fix integer overflow on 32-bit targets (kernel test robot <lkp at intel.com>)
> 
> v2:
> 
> Address Uwe Kleine-K?nig review comments:
> 
>   Fix period calculation when out of range
> 
>   Don't set period larger than requested
> 
>   Remove PWM disable on configuration change
> 
>   Implement .apply instead of non-atomic .config/.enable/.disable
> 
>   Don't modify PWM on .request/.free
> 
>   Check pwm_div underflow
> 
>   Fix various code and comment formatting issues
> 
> Other changes:
> 
>   Use u64 divisor safe division
> 
>   Remove now empty .request/.free
> ---
>  drivers/pwm/Kconfig   |  12 ++
>  drivers/pwm/Makefile  |   1 +
>  drivers/pwm/pwm-ipq.c | 275 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 288 insertions(+)
>  create mode 100644 drivers/pwm/pwm-ipq.c
> 
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 21e3b05a5153..e39718137ecd 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -260,6 +260,18 @@ config PWM_INTEL_LGM
>  	  To compile this driver as a module, choose M here: the module
>  	  will be called pwm-intel-lgm.
>  
> +config PWM_IPQ
> +	tristate "IPQ PWM support"
> +	depends on ARCH_QCOM || COMPILE_TEST
> +	depends on HAVE_CLK && HAS_IOMEM
> +	help
> +	  Generic PWM framework driver for IPQ PWM block which supports
> +	  4 pwm channels. Each of the these channels can be configured
> +	  independent of each other.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-ipq.
> +
>  config PWM_IQS620A
>  	tristate "Azoteq IQS620A PWM support"
>  	depends on MFD_IQS62X || COMPILE_TEST
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 708840b7fba8..7402feae4b36 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
>  obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
>  obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
>  obj-$(CONFIG_PWM_INTEL_LGM)	+= pwm-intel-lgm.o
> +obj-$(CONFIG_PWM_IPQ)		+= pwm-ipq.o
>  obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
>  obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
>  obj-$(CONFIG_PWM_KEEMBAY)	+= pwm-keembay.o
> diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
> new file mode 100644
> index 000000000000..3764010808f0
> --- /dev/null
> +++ b/drivers/pwm/pwm-ipq.c
> @@ -0,0 +1,275 @@
> +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
> +/*
> + * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/math64.h>
> +#include <linux/of_device.h>
> +#include <linux/bitfield.h>
> +
> +/* The frequency range supported is 1 Hz to clock rate */
> +#define IPQ_PWM_MAX_PERIOD_NS	((u64)NSEC_PER_SEC)
> +
> +/*
> + * The max value specified for each field is based on the number of bits
> + * in the pwm control register for that field
> + */
> +#define IPQ_PWM_MAX_DIV		0xFFFF
> +
> +/*
> + * Two 32-bit registers for each PWM: REG0, and REG1.
> + * Base offset for PWM #i is at 8 * #i.
> + */
> +#define IPQ_PWM_REG0			0 /*PWM_DIV PWM_HI*/
> +#define IPQ_PWM_REG0_PWM_DIV		GENMASK(15, 0)
> +#define IPQ_PWM_REG0_HI_DURATION	GENMASK(31, 16)

PWM_HI in the comment of IPQ_PWM_REG0 vs. HI_DURATION? Should this
match? I'd say the comment is redundant.

> +#define IPQ_PWM_REG1			4 /*ENABLE UPDATE PWM_PRE_DIV*/
> +#define IPQ_PWM_REG1_PRE_DIV		GENMASK(15, 0)
> +/*
> + * Enable bit is set to enable output toggling in pwm device.
> + * Update bit is set to reflect the changed divider and high duration
> + * values in register.
> + */
> +#define IPQ_PWM_REG1_UPDATE		BIT(30)
> +#define IPQ_PWM_REG1_ENABLE		BIT(31)
> +
> +
> +struct ipq_pwm_chip {
> +	struct pwm_chip chip;
> +	struct clk *clk;
> +	void __iomem *mem;
> +};
> +
> +static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip)
> +{
> +	return container_of(chip, struct ipq_pwm_chip, chip);
> +}
> +
> +static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg)
> +{
> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
> +	unsigned int off = 8 * pwm->hwpwm + reg;
> +
> +	return readl(ipq_chip->mem + off);
> +}
> +
> +static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg,
> +			      unsigned int val)
> +{
> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
> +	unsigned int off = 8 * pwm->hwpwm + reg;
> +
> +	writel(val, ipq_chip->mem + off);
> +}
> +
> +static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
> +			unsigned int pwm_div, unsigned long rate, u64 duty_ns,
> +			bool enable)
> +{
> +	unsigned long hi_dur;
> +	unsigned long val = 0;
> +
> +	/*
> +	 * high duration = pwm duty * (pwm div + 1)
> +	 * pwm duty = duty_ns / period_ns
> +	 */
> +	hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
> +
> +	val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
> +		FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val);
> +
> +	val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
> +
> +	/* PWM enable toggle needs a separate write to REG1 */
> +	val |= IPQ_PWM_REG1_UPDATE;
> +	if (enable)
> +		val |= IPQ_PWM_REG1_ENABLE;
> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
> +}
> +
> +static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +			 const struct pwm_state *state)
> +{
> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
> +	unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
> +	unsigned long rate = clk_get_rate(ipq_chip->clk);
> +	u64 period_ns, duty_ns, period_rate;
> +	u64 min_diff;
> +
> +	if (state->polarity != PWM_POLARITY_NORMAL)
> +		return -EINVAL;
> +
> +	if (state->period < div64_u64(NSEC_PER_SEC, rate))
> +		return -ERANGE;

NSEC_PER_SEC / rate is the smallest period you can achieve, right?
Consider rate = 33333 (Hz), then the minimal period is
30000.30000300003 ns. So you should refuse a request to configure
state->period = 30000, but as div64_u64(1000000000, 33333) is 30000 you
don't.

> +	period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
> +	duty_ns = min(state->duty_cycle, period_ns);
> +
> +	/*
> +	 * period_ns is 1G or less. As long as rate is less than 16 GHz this
> +	 * does not overflow.

Well, rate cannot be bigger than 4294967295 because an unsigned long
cannot hold a bigger value.

> +	 */
> +	period_rate = period_ns * rate;
> +	best_pre_div = IPQ_PWM_MAX_DIV;
> +	best_pwm_div = IPQ_PWM_MAX_DIV;
> +	/* Initial pre_div value such that pwm_div < IPQ_PWM_MAX_DIV */
> +	pre_div = div64_u64(period_rate,
> +			(u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));

Hmmm, we want 

	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
	-------------------------------------------- <= period_ns
	                  rate

, right? Resolving that for pre_div this gives:

	                period_ns * rate
	pre_div <= ----------------------------
	           NSEC_PER_SEC * (pwm_div + 1)

The term on the right hand side is maximal for pwm_div == 0 so the
possible values for pre_div are

	0 ... min(div64_u64(period_rate / NSEC_PER_SEC), IPQ_PWM_MAX_DIV)

isn't it? If so, your algorithm is wrong as you're iterating over

	div64_u64(period_rate, NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)) ... IPQ_PWM_MAX_DIV

> +	min_diff = period_rate;
> +
> +	for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
> +		long long diff;
> +
> +		pwm_div = DIV64_U64_ROUND_UP(period_rate,
> +				(u64)NSEC_PER_SEC * (pre_div + 1));
> +		/* pwm_div is unsigned; the check below catches underflow */
> +		pwm_div--;

What underflow? DIV64_U64_ROUND_UP returns > 0 assuming period_rate > 0.
So pwm_div - 1 doesn't underflow?!

The task here is to calculate the biggest pwm_div for a given pre_div
such that


	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
	-------------------------------------------- <= period_ns
	                   rate

right?

This is equivalent to:

	                  period_ns * rate
	pre_div <= ---------------------------- - 1
	           (pre_div + 1) * NSEC_PER_SEC

As pre_div is integer, rounding down should be fine?!

> +		/*
> +		 * pre_div and pwm_div values swap produces the same
> +		 * result. This loop goes over all pre_div <= pwm_div
> +		 * combinations. The rest are equivalent.
> +		 */

I'd write:

	/*
	 * Swapping values for pre_div and pwm_div produces the same
	 * period length. So we can skip all settings with pre_div <
	 * pwm_div which results in bigger constraints for selecting the
	 * duty_cycle than with the two values swapped.
	 */

> +		if (pre_div > pwm_div)
> +			break;
> +
> +		/*
> +		 * Make sure we can do 100% duty cycle where
> +		 * hi_dur == pwm_div + 1
> +		 */
> +		if (pwm_div > IPQ_PWM_MAX_DIV - 1)
> +			continue;
> +
> +		diff = ((uint64_t)NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1))
> +			- period_rate;
> +
> +		if (diff < 0) /* period larger than requested */
> +			continue;

This shouldn't happen if the above calculation is correct.

> +		if (diff == 0) { /* bingo */
> +			best_pre_div = pre_div;
> +			best_pwm_div = pwm_div;
> +			break;
> +		}
> +		if (diff < min_diff) {
> +			min_diff = diff;
> +			best_pre_div = pre_div;
> +			best_pwm_div = pwm_div;
> +		}

This can be simplified as:

		if (diff < min_diff) {
			best_pre_div = pre_div;
			best_pwm_div = pwm_div;
			min_diff = diff;

			if (min_diff == 0)
				/* bingo! */
				break;
		}

> +	}
> +
> +	/* config divider values for the closest possible frequency */
> +	config_div_and_duty(pwm, best_pre_div, best_pwm_div,
> +			    rate, duty_ns, state->enabled);
> +
> +	return 0;
> +}
> +
> +static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
> +			      struct pwm_state *state)
> +{
> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
> +	unsigned long rate = clk_get_rate(ipq_chip->clk);
> +	unsigned int pre_div, pwm_div, hi_dur;
> +	u64 effective_div, hi_div;
> +	u32 reg0, reg1;
> +
> +	reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG0);
> +	reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG1);
> +
> +	state->polarity = PWM_POLARITY_NORMAL;
> +	state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
> +
> +	pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
> +	hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
> +	pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
> +
> +	/* No overflow here, both pre_div and pwm_div <= 0xffff */
> +	effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
> +	state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC, rate);
> +
> +	hi_div = hi_dur * (pre_div + 1);
> +	state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate);

This must be round up for the same reasons as for period.

> +}

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220119/928d9d6d/attachment-0001.sig>

From robh at kernel.org  Wed Jan 19 09:44:07 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 19 Jan 2022 11:44:07 -0600
Subject: [PATCH] dt-bindings: i2c: stm32-i2c: Move st,
 syscfg-fmp definition to top level
Message-ID: <20220119174407.3810088-1-robh@kernel.org>

It is preferred to define all properties in the main schema and leave
if/then/else schemas to just be further constraints on properties.

Rework the schema to use be more specific for each cell. Previously,
multiple entries of 3 cells each was allowed.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/i2c/st,stm32-i2c.yaml | 24 ++++++++++---------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
index 46b62e1c9273..dccbb18b6dc0 100644
--- a/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/st,stm32-i2c.yaml
@@ -25,16 +25,9 @@ allOf:
 
         i2c-scl-falling-time-ns:
           default: 10
-
-        st,syscfg-fmp:
-          description: Use to set Fast Mode Plus bit within SYSCFG when
-                       Fast Mode Plus speed is selected by slave.
-                       Format is phandle to syscfg / register offset within
-                       syscfg / register bitmask for FMP bit.
-          $ref: "/schemas/types.yaml#/definitions/phandle-array"
-          items:
-            minItems: 3
-            maxItems: 3
+    else:
+      properties:
+        st,syscfg-fmp: false
 
   - if:
       properties:
@@ -87,6 +80,16 @@ properties:
     minimum: 1
     maximum: 1000000
 
+  st,syscfg-fmp:
+    description: Use to set Fast Mode Plus bit within SYSCFG when Fast Mode
+      Plus speed is selected by slave.
+    $ref: "/schemas/types.yaml#/definitions/phandle-array"
+    items:
+      - items:
+          - description: phandle to syscfg
+          - description: register offset within syscfg
+          - description: register bitmask for FMP bit
+
 required:
   - compatible
   - reg
@@ -147,4 +150,3 @@ examples:
           i2c-scl-falling-time-ns = <20>;
           st,syscfg-fmp = <&syscfg 0x4 0x2>;
       };
-...
-- 
2.32.0



From mathieu.poirier at linaro.org  Wed Jan 19 09:49:47 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 19 Jan 2022 10:49:47 -0700
Subject: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
In-Reply-To: <DU0PR04MB9417B0AC80F41D425F43277C88599@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-8-peng.fan@oss.nxp.com>
 <20220118185019.GG1119324@p14s>
 <DU0PR04MB9417B0AC80F41D425F43277C88599@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <20220119174947.GA1282028@p14s>

On Wed, Jan 19, 2022 at 02:25:48AM +0000, Peng Fan wrote:
> > Subject: Re: [PATCH 5/9] remoteproc: imx_rproc: make clk optional
> > 
> > On Tue, Jan 11, 2022 at 11:33:29AM +0800, Peng Fan (OSS) wrote:
> > > From: Peng Fan <peng.fan at nxp.com>
> > >
> > > To i.MX8QXP/QM/ULP and i.MX7ULP, Mcore maybe out of control of Linux.
> > > And in such case, no need clk, so make clk optional with has_clk.
> > >
> > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > ---
> > >  drivers/remoteproc/imx_rproc.c | 5 +++++
> > >  1 file changed, 5 insertions(+)
> > >
> > > diff --git a/drivers/remoteproc/imx_rproc.c
> > > b/drivers/remoteproc/imx_rproc.c index 7b2578177ea8..0e99a3ca6fbc
> > > 100644
> > > --- a/drivers/remoteproc/imx_rproc.c
> > > +++ b/drivers/remoteproc/imx_rproc.c
> > > @@ -89,6 +89,7 @@ struct imx_rproc {
> > >  	struct work_struct		rproc_work;
> > >  	struct workqueue_struct		*workqueue;
> > >  	void __iomem			*rsc_table;
> > > +	bool				has_clk;
> > 
> > I am usually weary of bloating structures with flags.  I suggest achieving the
> > same functionality with a macro that compares priv->dcfg with the right
> > imx_rproc_dcfg structure.
> 
> priv->dcfg is some kind fixed settings, however has_clk could be runtime changed,
> because i.MX platform M-core support multiple booting method and it
> could work w/o clk handled by Linux depending on some pre-configuration
> such as moving M-core in an separate hardware partition.

Unless there is an FPGA in the mix, clocks and power domains should not change.
Either clocks are handled by the remote processor or the application processor,
regardless of the mode (attached or detached) the platform is booting into.

> 
> Thanks,
> Peng. 
> 
> > 
> > >  };
> > >
> > >  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { @@
> > > -724,6 +725,9 @@ static int imx_rproc_clk_enable(struct imx_rproc *priv)
> > >  	if (dcfg->method == IMX_RPROC_NONE)
> > >  		return 0;
> > >
> > > +	if (!priv->has_clk)
> > > +		return 0;
> > > +
> > >  	priv->clk = devm_clk_get(dev, NULL);
> > >  	if (IS_ERR(priv->clk)) {
> > >  		dev_err(dev, "Failed to get clock\n"); @@ -768,6 +772,7 @@ static
> > > int imx_rproc_probe(struct platform_device *pdev)
> > >  	priv->rproc = rproc;
> > >  	priv->dcfg = dcfg;
> > >  	priv->dev = dev;
> > > +	priv->has_clk = true;
> > >
> > >  	dev_set_drvdata(dev, rproc);
> > >  	priv->workqueue = create_workqueue(dev_name(dev));
> > > --
> > > 2.25.1
> > >


From linux at armlinux.org.uk  Wed Jan 19 09:54:15 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Jan 2022 17:54:15 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <Yeg79CcofyNuVLid@casper.infradead.org>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
Message-ID: <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>

On Wed, Jan 19, 2022 at 04:27:32PM +0000, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > 
> > Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> > in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> > true...
> 
> Even if it does blow up, at least it's blowing up here where someone
> can start to debug it, rather than blowing up on first access, where
> we no longer have the invlid struct page pointer.
> 
> I don't think we have a 'page_valid' function which will tell us whether
> a random pointer is actually a struct page or not.

Isn't it supposed to be:

	if (!pfn_valid(pfn)) {
		handle invalid pfn;
	}

	page = pfn_to_page(pfn);

Anything else - even trying to convert an invalid page back to a pfn,
could well be unreliable (sparsemem or discontigmem). 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From willy at infradead.org  Wed Jan 19 10:01:24 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 18:01:24 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>
Message-ID: <YehR9BiI92q5DSOu@casper.infradead.org>

On Wed, Jan 19, 2022 at 05:54:15PM +0000, Russell King (Oracle) wrote:
> On Wed, Jan 19, 2022 at 04:27:32PM +0000, Matthew Wilcox wrote:
> > On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > > > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > > 
> > > Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> > > in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> > > true...
> > 
> > Even if it does blow up, at least it's blowing up here where someone
> > can start to debug it, rather than blowing up on first access, where
> > we no longer have the invlid struct page pointer.
> > 
> > I don't think we have a 'page_valid' function which will tell us whether
> > a random pointer is actually a struct page or not.
> 
> Isn't it supposed to be:
> 
> 	if (!pfn_valid(pfn)) {
> 		handle invalid pfn;
> 	}
> 
> 	page = pfn_to_page(pfn);
> 
> Anything else - even trying to convert an invalid page back to a pfn,
> could well be unreliable (sparsemem or discontigmem). 

This function is passed an array of pages.  We have no way of doing
what you propose.


From broonie at kernel.org  Wed Jan 19 10:02:32 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Jan 2022 18:02:32 +0000
Subject: [PATCH] ASoC: mediatek: fix unmet dependency on GPIOLIB for
 SND_SOC_DMIC
In-Reply-To: <20220117050324.68371-1-julianbraha@gmail.com>
References: <20220117050324.68371-1-julianbraha@gmail.com>
Message-ID: <164261535273.2816847.12797426159265748718.b4-ty@kernel.org>

On Mon, 17 Jan 2022 00:03:24 -0500, Julian Braha wrote:
> When SND_SOC_MT8195_MT6359_RT1011_RT5682 is selected,
> and GPIOLIB is not selected,
> Kbuild gives the following warning:
> 
> WARNING: unmet direct dependencies detected for SND_SOC_DMIC
>   Depends on [n]: SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && GPIOLIB [=n]
>   Selected by [y]:
>   - SND_SOC_MT8195_MT6359_RT1011_RT5682 [=y] && SOUND [=y] && !UML && SND [=y] && SND_SOC [=y] && I2C [=y] && SND_SOC_MT8195 [=y] && MTK_PMIC_WRAP [=y]
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-linus

Thanks!

[1/1] ASoC: mediatek: fix unmet dependency on GPIOLIB for SND_SOC_DMIC
      commit: 579b2c8f72d974f27d85bbd53846f34675ee3b01

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Wed Jan 19 10:02:46 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Jan 2022 18:02:46 +0000
Subject: [PATCH v3] spi: stm32-qspi: Update spi registering
In-Reply-To: <20220117121744.29729-1-patrice.chotard@foss.st.com>
References: <20220117121744.29729-1-patrice.chotard@foss.st.com>
Message-ID: <164261536622.2816943.17525364866114130985.b4-ty@kernel.org>

On Mon, 17 Jan 2022 13:17:44 +0100, patrice.chotard at foss.st.com wrote:
> From: Patrice Chotard <patrice.chotard at foss.st.com>
> 
> Some device driver need to communicate to qspi device during the remove
> process, qspi controller must be functional when spi_unregister_master()
> is called.
> 
> To ensure this, replace devm_spi_register_master() by spi_register_master()
> and spi_unregister_master() is called directly in .remove callback before
> stopping the qspi controller.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/1] spi: stm32-qspi: Update spi registering
      commit: e4d63473d3110afd170e6e0e48494d3789d26136

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Wed Jan 19 10:02:48 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 19 Jan 2022 18:02:48 +0000
Subject: [PATCH 0/2] spi: stm32: comments & SIMPLEX_RX fixes
In-Reply-To: <20220119093245.624878-1-alain.volmat@foss.st.com>
References: <20220119093245.624878-1-alain.volmat@foss.st.com>
Message-ID: <164261536824.2816943.11806763183667927602.b4-ty@kernel.org>

On Wed, 19 Jan 2022 10:32:43 +0100, Alain Volmat wrote:
> This series contains 2 fixes within the spi-stm32.c driver.  One is
> removing comments regarding struct variables that do not exist and the
> second one correct a previous STM32F4 related commit for SIMPLEX_RX which
> happens to break SIMPLEX_RX for H7 since it enforces MUST_TX flags.
> 
> Alain Volmat (2):
>   spi: stm32: remove inexistant variables in struct stm32_spi_cfg
>     comment
>   spi: stm32: make SPI_MASTER_MUST_TX flags only specific to STM32F4
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/2] spi: stm32: remove inexistant variables in struct stm32_spi_cfg comment
      commit: 3cefddb72f80dc8d49ce605628ceb6525cfd64da
[2/2] spi: stm32: make SPI_MASTER_MUST_TX flags only specific to STM32F4
      commit: 9df15d842a0f77f2b8ee29386f6d714e4220df57

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From mathieu.poirier at linaro.org  Wed Jan 19 10:04:13 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 19 Jan 2022 11:04:13 -0700
Subject: [PATCH 6/9] remoteproc: imx_rproc: support attaching to i.MX8QXP
 M4
In-Reply-To: <DU0PR04MB9417335FFEBEB5CE91A5A67888599@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-9-peng.fan@oss.nxp.com>
 <20220118185729.GH1119324@p14s>
 <DU0PR04MB9417335FFEBEB5CE91A5A67888599@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <20220119180413.GB1282028@p14s>

On Wed, Jan 19, 2022 at 02:28:31AM +0000, Peng Fan wrote:
> > Subject: Re: [PATCH 6/9] remoteproc: imx_rproc: support attaching to
> > i.MX8QXP M4
> > 
> > On Tue, Jan 11, 2022 at 11:33:30AM +0800, Peng Fan (OSS) wrote:
> > > From: Peng Fan <peng.fan at nxp.com>
> > >
> > > When M4 is kicked by SCFW, M4 runs in its own hardware partition,
> > > Linux could only do IPC with M4, it could not start, stop, update image.
> > >
> > > When M4 crash reboot, it could notify Linux, so Linux could prepare to
> > > reattach to M4 after M4 recovery.
> > >
> > > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > > ---
> > >  drivers/remoteproc/imx_rproc.c | 96
> > > ++++++++++++++++++++++++++++++++++
> > >  1 file changed, 96 insertions(+)
> > >
> > > diff --git a/drivers/remoteproc/imx_rproc.c
> > > b/drivers/remoteproc/imx_rproc.c index 0e99a3ca6fbc..5f04aea2f6a1
> > > 100644
> > > --- a/drivers/remoteproc/imx_rproc.c
> > > +++ b/drivers/remoteproc/imx_rproc.c
> > > @@ -6,6 +6,7 @@
> > >  #include <linux/arm-smccc.h>
> > >  #include <linux/clk.h>
> > >  #include <linux/err.h>
> > > +#include <linux/firmware/imx/sci.h>
> > >  #include <linux/interrupt.h>
> > >  #include <linux/kernel.h>
> > >  #include <linux/mailbox_client.h>
> > > @@ -59,6 +60,8 @@
> > >  #define IMX_SIP_RPROC_STARTED		0x01
> > >  #define IMX_SIP_RPROC_STOP		0x02
> > >
> > > +#define	IMX_SC_IRQ_GROUP_REBOOTED	5
> > > +
> > >  /**
> > >   * struct imx_rproc_mem - slim internal memory structure
> > >   * @cpu_addr: MPU virtual address of the memory region @@ -90,6
> > > +93,23 @@ struct imx_rproc {
> > >  	struct workqueue_struct		*workqueue;
> > >  	void __iomem			*rsc_table;
> > >  	bool				has_clk;
> > > +	struct imx_sc_ipc		*ipc_handle;
> > > +	struct notifier_block		proc_nb;
> > > +	u32				rproc_pt;
> > > +	u32				rsrc;
> > 
> > There is no documentation for the above two fields and I have to guess what
> > they do.
> 
> Fix in V2.
> 
> > 
> > > +};
> > > +
> > > +static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> > > +	/* dev addr , sys addr  , size	    , flags */
> > > +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> > > +	/* TCML/U */
> > > +	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
> > > +	/* OCRAM(Low 96KB) */
> > > +	{ 0x21000000, 0x00100000, 0x00018000, 0},
> > > +	/* OCRAM */
> > > +	{ 0x21100000, 0x00100000, 0x00040000, 0},
> > > +	/* DDR (Data) */
> > > +	{ 0x80000000, 0x80000000, 0x60000000, 0 },
> > >  };
> > >
> > >  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = { @@
> > > -236,6 +256,12 @@ static const struct imx_rproc_dcfg
> > imx_rproc_cfg_imx8ulp = {
> > >  	.method		= IMX_RPROC_NONE,
> > >  };
> > >
> > > +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
> > > +	.att		= imx_rproc_att_imx8qxp,
> > > +	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> > > +	.method		= IMX_RPROC_SCU_API,
> > > +};
> > > +
> > >  static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
> > >  	.att		= imx_rproc_att_imx7ulp,
> > >  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
> > > @@ -491,6 +517,11 @@ static int imx_rproc_attach(struct rproc *rproc)
> > >  	return 0;
> > >  }
> > >
> > > +static int imx_rproc_detach(struct rproc *rproc) {
> > > +	return 0;
> > 
> > Is it possible to detach the remote processor from the application core?  If
> > not please write a comment that says so.
> 
> No from my understanding.
> 
>   And shouldn't this return some
> > kind of error so that users don't think the operation was carried out
> > successfully?
> 
> No. This is to match patch 3/9 to support M-core self recovery. After M-core
> crash reboot, remoteproc framework just detach and re-attach.

Right, but by returning 0 in imx_rproc_detach() issueing something like:

        # echo detach > /sys/class/remoteproc/remoteproc0/state

will return without an error message, leading users to believe the remote
processor has been detached.  Returning an error code like -EINVAL would tell
users the operation was not completed successfully. 

More comments to come shortly...

> 
> > 
> > I am out of time for today and as such will continue with this set tomorrow.
> 
> Thanks for you reviewing the patchset.
> 
> Thanks,
> Peng.
> 
> > 
> > Thanks,
> > Mathieu
> > 
> > > +}
> > > +
> > >  static struct resource_table *imx_rproc_get_loaded_rsc_table(struct
> > > rproc *rproc, size_t *table_sz)  {
> > >  	struct imx_rproc *priv = rproc->priv; @@ -525,6 +556,7 @@
> > > imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct
> > > firmware *  static const struct rproc_ops imx_rproc_ops = {
> > >  	.prepare	= imx_rproc_prepare,
> > >  	.attach		= imx_rproc_attach,
> > > +	.detach		= imx_rproc_detach,
> > >  	.start		= imx_rproc_start,
> > >  	.stop		= imx_rproc_stop,
> > >  	.kick		= imx_rproc_kick,
> > > @@ -671,6 +703,22 @@ static void imx_rproc_free_mbox(struct rproc
> > *rproc)
> > >  	mbox_free_channel(priv->rx_ch);
> > >  }
> > >
> > > +static int imx_rproc_partition_notify(struct notifier_block *nb,
> > > +				      unsigned long event, void *group) {
> > > +	struct imx_rproc *priv = container_of(nb, struct imx_rproc,
> > > +proc_nb);
> > > +
> > > +	/* Ignore other irqs */
> > > +	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group ==
> > IMX_SC_IRQ_GROUP_REBOOTED)))
> > > +		return 0;
> > > +
> > > +	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
> > > +
> > > +	pr_info("Patition%d reset!\n", priv->rproc_pt);
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static int imx_rproc_detect_mode(struct imx_rproc *priv)  {
> > >  	struct regmap_config config = { .name = "imx-rproc" }; @@ -680,6
> > > +728,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
> > >  	struct arm_smccc_res res;
> > >  	int ret;
> > >  	u32 val;
> > > +	u8 pt;
> > >
> > >  	switch (dcfg->method) {
> > >  	case IMX_RPROC_NONE:
> > > @@ -690,6 +739,52 @@ static int imx_rproc_detect_mode(struct
> > imx_rproc *priv)
> > >  		if (res.a0)
> > >  			priv->rproc->state = RPROC_DETACHED;
> > >  		return 0;
> > > +	case IMX_RPROC_SCU_API:
> > > +		ret = imx_scu_get_handle(&priv->ipc_handle);
> > > +		if (ret)
> > > +			return ret;
> > > +		ret = of_property_read_u32(dev->of_node, "rsrc-id", &priv->rsrc);
> > > +		if (ret) {
> > > +			dev_err(dev, "no rsrc-id\n");
> > > +			return ret;
> > > +		}
> > > +
> > > +		/*
> > > +		 * If Mcore resource is not owned by Acore partition, It is kicked by
> > ROM,
> > > +		 * and Linux could only do IPC with Mcore and nothing else.
> > > +		 */
> > > +		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
> > > +
> > > +			priv->has_clk = false;
> > > +			priv->rproc->self_recovery = true;
> > > +			priv->rproc->state = RPROC_DETACHED;
> > > +
> > > +			/* Get partition id and enable irq in SCFW */
> > > +			ret = imx_sc_rm_get_resource_owner(priv->ipc_handle,
> > priv->rsrc, &pt);
> > > +			if (ret) {
> > > +				dev_err(dev, "not able to get resource owner\n");
> > > +				return ret;
> > > +			}
> > > +
> > > +			priv->rproc_pt = pt;
> > > +			priv->proc_nb.notifier_call = imx_rproc_partition_notify;
> > > +
> > > +			ret = imx_scu_irq_register_notifier(&priv->proc_nb);
> > > +			if (ret) {
> > > +				dev_warn(dev, "register scu notifier failed.\n");
> > > +				return ret;
> > > +			}
> > > +
> > > +			ret =
> > imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED,
> > > +						       BIT(priv->rproc_pt), true);
> > > +			if (ret) {
> > > +				imx_scu_irq_unregister_notifier(&priv->proc_nb);
> > > +				dev_warn(dev, "Enable irq failed.\n");
> > > +				return ret;
> > > +			}
> > > +		}
> > > +
> > > +		return 0;
> > >  	default:
> > >  		break;
> > >  	}
> > > @@ -847,6 +942,7 @@ static const struct of_device_id
> > imx_rproc_of_match[] = {
> > >  	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
> > >  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
> > >  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
> > > +	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
> > >  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
> > >  	{},
> > >  };
> > > --
> > > 2.25.1
> > >


From mark.rutland at arm.com  Wed Jan 19 10:06:14 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Wed, 19 Jan 2022 18:06:14 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <CAAH8bW-CxxL7DkBdHeZ60ZyPKJ8EOY2rh+hCEiyeH7Kih42EQQ@mail.gmail.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <YefzAQ5LXJk1ytfI@FVFF77S0Q05N>
 <CAAH8bW-CxxL7DkBdHeZ60ZyPKJ8EOY2rh+hCEiyeH7Kih42EQQ@mail.gmail.com>
Message-ID: <20220119180614.GB43919@C02TD0UTHF1T.local>

On Wed, Jan 19, 2022 at 09:00:23AM -0800, Yury Norov wrote:
> On Wed, Jan 19, 2022 at 3:17 AM Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > Hi,
> >
> > I replied ot the original RFC before spotting this; duplicating those comments
> > here because I think they apply regardless of the mechanism used to work around
> > this.
> >
> > On Tue, Jan 18, 2022 at 03:52:44PM -0800, Yury Norov wrote:
> > > vmap() takes struct page *pages as one of arguments, and user may provide
> > > an invalid pointer which would lead to DABT at address translation later.
> > >
> > > Currently, kernel checks the pages against NULL. In my case, however, the
> > > address was not NULL, and was big enough so that the hardware generated
> > > Address Size Abort on arm64.
> >
> > Can you give an example of when this might happen? It sounds like you're
> > actually hitting this, so a backtrace would be nice.
> >
> > I'm a bit confused as to when why we'd try to vmap() pages that we
> > didn't have a legitimate struct page for -- where did these addresses
> > come from?
> >
> > It sounds like this is going wrong at a higher level, and we're passing
> > entirely bogus struct page pointers around. This seems like the sort of
> > thing DEBUG_VIRTUAL or similar should check when we initially generate
> > the struct page pointer.
> 
> Hi Mark,
> 
> This is an out-of-tree code that does:
> 
>     vaddr1 = dma_alloc_coherent()
>     page = virt_to_page() // Wrong here
>     ...
>     vaddr2 = vmap(page)
>     memset(vaddr2) // Fault here
> 
> virt_to_page() returns a wrong pointer if vaddr1 is not a linear kernel address.
> The problem is that vmap() populates pte with bad pfn successfully, and it's
> much harder to debug at memory access time.
 
Ah, ok. FWIW, that case should be caught by DEBUG_VIRTUAL when that's
enabled.

It would be nice to put that within the commit message, since that
clearly indicates this is about catching a mistake in buggy code, and
indicates where to go looking next.

> > > Interestingly, this abort happens even if copy_from_kernel_nofault() is
> > > used, which is quite inconvenient for debugging purposes.
> >
> > I can go take a look at this, but TBH we never expect to take an address size
> > fault to begin with, so this is arguably correct -- it's an internal
> > consistency problem.
> >
> > > This patch adds a pfn_valid() check into vmap() path, so that invalid
> > > mapping will not be created.
> > >
> > > RFC: https://lkml.org/lkml/2022/1/18/815
> > > v1: use pfn_valid() instead of adding an arch-specific
> > >     arch_vmap_page_valid(). Thanks to Matthew Wilcox for the hint.
> > >
> > > Signed-off-by: Yury Norov <yury.norov at gmail.com>
> > > ---
> > >  mm/vmalloc.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> > > index d2a00ad4e1dd..a4134ee56b10 100644
> > > --- a/mm/vmalloc.c
> > > +++ b/mm/vmalloc.c
> > > @@ -477,6 +477,8 @@ static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr,
> > >                       return -EBUSY;
> > >               if (WARN_ON(!page))
> > >                       return -ENOMEM;
> > > +             if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > > +                     return -EINVAL;
> >
> > My fear here is that for this to fire, we've already passed a bogus struct page
> > pointer around the intermediate infrastructure, and any of that might try to
> > use it in unsafe ways (in future even if we don't use it today).
> >
> > I think the fundamental issue here is that we generate a bogus struct page
> > pointer at all, and knowing where that came from would help to fix that.
> 
> You're right. That's why WARN_ON() is used for the page == null in the code
> above, I believe, - to let client code know that something goes wrong, and it's
> not a regular ENOMEM situation.

Sure; with all the above in mind I think it's fine for this to be
best-effort (e.g. as Robin noted page_to_pfn() might consume parts of
the struct page before this), since either way that will indicate
roughly where the problem is.

As above, it would just be nice for the commit message to be a little
more explicit as to that.

Thanks,
Mark.


From baruch at tkos.co.il  Wed Jan 19 10:14:06 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Wed, 19 Jan 2022 20:14:06 +0200
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <20220119002438.106079-1-sean.anderson@seco.com>
References: <20220119002438.106079-1-sean.anderson@seco.com>
Message-ID: <87ee53fv01.fsf@tarshish>

Hi Sean,

On Tue, Jan 18 2022, Sean Anderson wrote:
> This is a rework of patches 3-5 of [1]. It attempts to correctly program
> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
> we no longer need a special property duplicating this configuration,
> snps,ref-clock-period-ns is deprecated.
>
> Please test this! Patches 3/4 in this series have the effect of
> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
> the "ref" clock. I have build tested, but not much else.

Tested here on IPQ6010 based system. USB still works. But the with "ref"
clock at 24MHz, period is calculated as 0x29. Previous
snps,ref-clock-period-ns value used to be 0x32.

Is that expected?

Thanks,
baruch

>
> [1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/
>
> Changes in v2:
> - Document clock members
> - Also program GFLADJ.240MHZDECR
> - Don't program GFLADJ if the version is < 2.50a
> - Add snps,ref-clock-frequency-hz property for ACPI
>
> Sean Anderson (7):
>   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>   usb: dwc3: Get clocks individually
>   usb: dwc3: Calculate REFCLKPER based on reference clock
>   usb: dwc3: Program GFLADJ
>   usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
>   arm64: dts: zynqmp: Move USB clocks to dwc3 node
>   arm64: dts: ipq6018: Use reference clock to set dwc3 period
>
>  .../devicetree/bindings/usb/snps,dwc3.yaml    |   7 +-
>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |   3 +-
>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |   4 +-
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |   4 +-
>  drivers/usb/dwc3/core.c                       | 112 +++++++++++++++---
>  drivers/usb/dwc3/core.h                       |  17 ++-
>  6 files changed, 120 insertions(+), 27 deletions(-)


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From sean.anderson at seco.com  Wed Jan 19 10:23:44 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Wed, 19 Jan 2022 13:23:44 -0500
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <87ee53fv01.fsf@tarshish>
References: <20220119002438.106079-1-sean.anderson@seco.com>
 <87ee53fv01.fsf@tarshish>
Message-ID: <a1932eba-564c-fe32-f220-53aa75250105@seco.com>

Hi Baruch,

On 1/19/22 1:14 PM, Baruch Siach wrote:
> Hi Sean,
>
> On Tue, Jan 18 2022, Sean Anderson wrote:
>> This is a rework of patches 3-5 of [1]. It attempts to correctly program
>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>> we no longer need a special property duplicating this configuration,
>> snps,ref-clock-period-ns is deprecated.
>>
>> Please test this! Patches 3/4 in this series have the effect of
>> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>> the "ref" clock. I have build tested, but not much else.
>
> Tested here on IPQ6010 based system. USB still works. But the with "ref"
> clock at 24MHz, period is calculated as 0x29. Previous
> snps,ref-clock-period-ns value used to be 0x32.
>
> Is that expected?

Yes. From the documentation for GFLADJ_REFCLK_240MHZ_DECR:

> Examples:
> If the ref_clk is 24 MHz then
> - GUCTL.REF_CLK_PERIOD = 41
> - GFLADJ.GFLADJ_REFCLK_240MHZ_DECR = 240/24 = 10

And 41 == 0x29.

--Sean


From mathieu.poirier at linaro.org  Wed Jan 19 10:31:18 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 19 Jan 2022 11:31:18 -0700
Subject: [PATCH 6/9] remoteproc: imx_rproc: support attaching to i.MX8QXP
 M4
In-Reply-To: <20220111033333.403448-9-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-9-peng.fan@oss.nxp.com>
Message-ID: <20220119183118.GA1284752@p14s>

On Tue, Jan 11, 2022 at 11:33:30AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> When M4 is kicked by SCFW, M4 runs in its own hardware partition, Linux
> could only do IPC with M4, it could not start, stop, update image.
> 
> When M4 crash reboot, it could notify Linux, so Linux could prepare to
> reattach to M4 after M4 recovery.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 96 ++++++++++++++++++++++++++++++++++
>  1 file changed, 96 insertions(+)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 0e99a3ca6fbc..5f04aea2f6a1 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -6,6 +6,7 @@
>  #include <linux/arm-smccc.h>
>  #include <linux/clk.h>
>  #include <linux/err.h>
> +#include <linux/firmware/imx/sci.h>
>  #include <linux/interrupt.h>
>  #include <linux/kernel.h>
>  #include <linux/mailbox_client.h>
> @@ -59,6 +60,8 @@
>  #define IMX_SIP_RPROC_STARTED		0x01
>  #define IMX_SIP_RPROC_STOP		0x02
>  
> +#define	IMX_SC_IRQ_GROUP_REBOOTED	5
> +
>  /**
>   * struct imx_rproc_mem - slim internal memory structure
>   * @cpu_addr: MPU virtual address of the memory region
> @@ -90,6 +93,23 @@ struct imx_rproc {
>  	struct workqueue_struct		*workqueue;
>  	void __iomem			*rsc_table;
>  	bool				has_clk;
> +	struct imx_sc_ipc		*ipc_handle;
> +	struct notifier_block		proc_nb;
> +	u32				rproc_pt;
> +	u32				rsrc;
> +};
> +
> +static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> +	/* dev addr , sys addr  , size	    , flags */
> +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> +	/* TCML/U */
> +	{ 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
> +	/* OCRAM(Low 96KB) */
> +	{ 0x21000000, 0x00100000, 0x00018000, 0},
> +	/* OCRAM */
> +	{ 0x21100000, 0x00100000, 0x00040000, 0},
> +	/* DDR (Data) */
> +	{ 0x80000000, 0x80000000, 0x60000000, 0 },
>  };
>  
>  static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
> @@ -236,6 +256,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
>  	.method		= IMX_RPROC_NONE,
>  };
>  
> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
> +	.att		= imx_rproc_att_imx8qxp,
> +	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> +	.method		= IMX_RPROC_SCU_API,
> +};
> +
>  static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
>  	.att		= imx_rproc_att_imx7ulp,
>  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx7ulp),
> @@ -491,6 +517,11 @@ static int imx_rproc_attach(struct rproc *rproc)
>  	return 0;
>  }
>  
> +static int imx_rproc_detach(struct rproc *rproc)
> +{
> +	return 0;
> +}
> +
>  static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
>  {
>  	struct imx_rproc *priv = rproc->priv;
> @@ -525,6 +556,7 @@ imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *
>  static const struct rproc_ops imx_rproc_ops = {
>  	.prepare	= imx_rproc_prepare,
>  	.attach		= imx_rproc_attach,
> +	.detach		= imx_rproc_detach,
>  	.start		= imx_rproc_start,
>  	.stop		= imx_rproc_stop,
>  	.kick		= imx_rproc_kick,
> @@ -671,6 +703,22 @@ static void imx_rproc_free_mbox(struct rproc *rproc)
>  	mbox_free_channel(priv->rx_ch);
>  }
>  
> +static int imx_rproc_partition_notify(struct notifier_block *nb,
> +				      unsigned long event, void *group)
> +{
> +	struct imx_rproc *priv = container_of(nb, struct imx_rproc, proc_nb);
> +
> +	/* Ignore other irqs */
> +	if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
> +		return 0;
> +
> +	rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
> +
> +	pr_info("Patition%d reset!\n", priv->rproc_pt);

s/Patition/Partition

> +
> +	return 0;
> +}
> +
>  static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  {
>  	struct regmap_config config = { .name = "imx-rproc" };
> @@ -680,6 +728,7 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  	struct arm_smccc_res res;
>  	int ret;
>  	u32 val;
> +	u8 pt;
>  
>  	switch (dcfg->method) {
>  	case IMX_RPROC_NONE:
> @@ -690,6 +739,52 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  		if (res.a0)
>  			priv->rproc->state = RPROC_DETACHED;
>  		return 0;
> +	case IMX_RPROC_SCU_API:
> +		ret = imx_scu_get_handle(&priv->ipc_handle);
> +		if (ret)
> +			return ret;
> +		ret = of_property_read_u32(dev->of_node, "rsrc-id", &priv->rsrc);
> +		if (ret) {
> +			dev_err(dev, "no rsrc-id\n");
> +			return ret;
> +		}
> +
> +		/*
> +		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
> +		 * and Linux could only do IPC with Mcore and nothing else.
> +		 */
> +		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {

                if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc))
                        return 0;

> +
> +			priv->has_clk = false;
> +			priv->rproc->self_recovery = true;
> +			priv->rproc->state = RPROC_DETACHED;

This is further proof that information is already available to determine if
clocks should be managed on the application processor or not and that
priv->has_clk carries redundant information.

> +
> +			/* Get partition id and enable irq in SCFW */
> +			ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc, &pt);
> +			if (ret) {
> +				dev_err(dev, "not able to get resource owner\n");
> +				return ret;
> +			}
> +
> +			priv->rproc_pt = pt;
> +			priv->proc_nb.notifier_call = imx_rproc_partition_notify;
> +
> +			ret = imx_scu_irq_register_notifier(&priv->proc_nb);
> +			if (ret) {
> +				dev_warn(dev, "register scu notifier failed.\n");
> +				return ret;
> +			}
> +
> +			ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED,
> +						       BIT(priv->rproc_pt), true);
> +			if (ret) {
> +				imx_scu_irq_unregister_notifier(&priv->proc_nb);
> +				dev_warn(dev, "Enable irq failed.\n");
> +				return ret;
> +			}
> +		}
> +
> +		return 0;
>  	default:
>  		break;
>  	}
> @@ -847,6 +942,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
>  	{ .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
>  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
>  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
> +	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
>  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
>  	{},
>  };
> -- 
> 2.25.1
> 


From robin.murphy at arm.com  Wed Jan 19 10:43:10 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 19 Jan 2022 18:43:10 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <Yeg79CcofyNuVLid@casper.infradead.org>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
Message-ID: <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>

On 2022-01-19 16:27, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
>>> +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
>>
>> Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
>> in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
>> true...
> 
> Even if it does blow up, at least it's blowing up here where someone
> can start to debug it, rather than blowing up on first access, where
> we no longer have the invlid struct page pointer.

But if that were the case then we'd blow up on the following line when 
mk_pte(page, prot) ends up calling it same anyway. Indeed it's arguably 
the best-case scenario since it would also blow up in page_address() if 
we hit the vmap_range loop rather than going down the 
vmap_small_pages_range_noflush() path.

Furthermore, if you *are* lucky enough to take a fault upon accessing a 
bogus mapping, then surely a phys_to_page() calculation on whatever 
ended up in the PTE should get you back the original "pointer" anyway, 
shouldn't it? Sure it's a bit more work to extract the caller out of the 
VMA if necessary, but hey, that's debugging! Maybe vmap() failing means 
you then pass the offending nonsense to __free_pages() and that ruins 
your day anyway...

The implications are infinitely worse if you've mapped something that 
did happen to be a valid page, but wasn't the *right* page, such that 
you don't fault but corrupt things or trigger a fatal system error 
instead. I'd echo Mark's point that if we can't trust a page pointer to 
be correct then we've already lost. In general the proportion of "wrong" 
pointers one can viably attempt to detect is so small that it's rarely 
ever worth trying, and the cases that are so obviously wrong tend to 
show up well enough in normal operation (although NULL-safety is of 
course a bit of a special case when it can simplify API usage).

> I don't think we have a 'page_valid' function which will tell us whether
> a random pointer is actually a struct page or not.

Indeed, my impression is that the only legitimate way to get hold of a 
page pointer without assumed provenance is via pfn_to_page(), which is 
where pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really 
*should* be a tautology.

I guess in this instance it would be technically feasible to implement a 
function which checks "is this a correctly-aligned pointer within memmap 
bounds", but IMO that would be a massive step in the wrong direction. 
We're developers; sometimes we introduce bugs when developing code, and 
it takes effort to debug them, but that still doesn't make it a good 
idea to optimise normal code paths for the expectation of writing new 
catastrophically-bad bugs. Plus logically if such a "page_valid()" check 
could be justified at all then that should rightfully lead to a 
churn-fest of adding it to pretty much every interface which accepts 
page pointers - one half of vmap() is hardly special.

FWIW, If anything I reckon a DEBUG_VM option that made checks within 
page_to_x/x_to_page as appropriate would help Yury's issue just as much, 
while having the potential to be considerably more useful in general.

Cheers,
Robin.


From javierm at redhat.com  Wed Jan 19 10:49:08 2022
From: javierm at redhat.com (Javier Martinez Canillas)
Date: Wed, 19 Jan 2022 19:49:08 +0100
Subject: [PATCH v3 00/10] drm: Make drivers to honour the nomodeset
 parameter
In-Reply-To: <20211222082831.196562-1-javierm@redhat.com>
References: <20211222082831.196562-1-javierm@redhat.com>
Message-ID: <bb01c544-66aa-b470-5b09-18f6e42d941a@redhat.com>

On 12/22/21 09:28, Javier Martinez Canillas wrote:
> The nomodeset kernel command line parameter is used to prevent the KMS/DRM
> drivers to be registered/probed. But only a few drivers implement support
> for this and most DRM drivers just ignore it.
> 
> This patch series is a v3 to make DRM drivers to honour nomodeset. It is
> posted as separate patches to make easier for drivers maintainers to ack
> or pick them independently at their own pace.
> 

I've pushed this series to drm-misc-next.

Best regards,
-- 
Javier Martinez Canillas
Linux Engineering
Red Hat



From linux at armlinux.org.uk  Wed Jan 19 10:57:34 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Jan 2022 18:57:34 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YehR9BiI92q5DSOu@casper.infradead.org>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>
 <YehR9BiI92q5DSOu@casper.infradead.org>
Message-ID: <YehfHsuMzvy//Szi@shell.armlinux.org.uk>

On Wed, Jan 19, 2022 at 06:01:24PM +0000, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 05:54:15PM +0000, Russell King (Oracle) wrote:
> > On Wed, Jan 19, 2022 at 04:27:32PM +0000, Matthew Wilcox wrote:
> > > On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > > > > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > > > 
> > > > Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> > > > in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> > > > true...
> > > 
> > > Even if it does blow up, at least it's blowing up here where someone
> > > can start to debug it, rather than blowing up on first access, where
> > > we no longer have the invlid struct page pointer.
> > > 
> > > I don't think we have a 'page_valid' function which will tell us whether
> > > a random pointer is actually a struct page or not.
> > 
> > Isn't it supposed to be:
> > 
> > 	if (!pfn_valid(pfn)) {
> > 		handle invalid pfn;
> > 	}
> > 
> > 	page = pfn_to_page(pfn);
> > 
> > Anything else - even trying to convert an invalid page back to a pfn,
> > could well be unreliable (sparsemem or discontigmem). 
> 
> This function is passed an array of pages.  We have no way of doing
> what you propose.

You can't go from a struct page to "this is valid", it's too late by the
time you call vmap() - that's my fundamental point.

If the translation from a PFN to a struct page can return pointers to
something that isn't a valid struct page, then it can also (with
sparsemem) return a pointer to _another_ struct page that could well
be valid depending on how the struct page arrays are laid out in
memory.

To repeat: once you have a struct page, it's too late to determine if
the struct page is valid.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From mathieu.poirier at linaro.org  Wed Jan 19 10:58:52 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 19 Jan 2022 11:58:52 -0700
Subject: [PATCH 7/9] remoteproc: imx_rproc: support kicking Mcore from
 Linux for i.MX8QXP
In-Reply-To: <20220111033333.403448-10-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-10-peng.fan@oss.nxp.com>
Message-ID: <20220119185852.GB1284752@p14s>

On Tue, Jan 11, 2022 at 11:33:31AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> When M4 is in the same hardware partition with Cortex-A, it
> could be start/stop by Linux.
> 
> Added power domain to make sure M4 could run, it requires several power
> domains to work. Make clk always optional for i.MX8QXP, because
> SCFW handles it when power up M4 core.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 64 +++++++++++++++++++++++++++++++++-
>  1 file changed, 63 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 5f04aea2f6a1..09d2a06e5ed6 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -16,6 +16,7 @@
>  #include <linux/of_reserved_mem.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
>  #include <linux/regmap.h>
>  #include <linux/remoteproc.h>
>  #include <linux/workqueue.h>
> @@ -97,6 +98,9 @@ struct imx_rproc {
>  	struct notifier_block		proc_nb;
>  	u32				rproc_pt;
>  	u32				rsrc;
> +	int                             num_pd;
> +	struct device                   **pd_dev;
> +	struct device_link              **pd_dev_link;
>  };
>  
>  static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> @@ -305,6 +309,9 @@ static int imx_rproc_start(struct rproc *rproc)
>  		arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
>  		ret = res.a0;
>  		break;
> +	case IMX_RPROC_SCU_API:
> +		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);

Where does the 0x34fe0000 comes from and what happens when the boot address
changes?  This should come from the device tree or some HW register somewhere.

> +		break;
>  	default:
>  		return -EOPNOTSUPP;
>  	}
> @@ -334,6 +341,9 @@ static int imx_rproc_stop(struct rproc *rproc)
>  		if (res.a1)
>  			dev_info(dev, "Not in wfi, force stopped\n");
>  		break;
> +	case IMX_RPROC_SCU_API:
> +		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
> +		break;

Same as above.

>  	default:
>  		return -EOPNOTSUPP;
>  	}
> @@ -719,6 +729,56 @@ static int imx_rproc_partition_notify(struct notifier_block *nb,
>  	return 0;
>  }
>  
> +static int imx_rproc_attach_pd(struct imx_rproc *priv)
> +{
> +	struct device *dev = priv->dev;
> +	int ret, i;
> +
> +	priv->num_pd = of_count_phandle_with_args(dev->of_node, "power-domains",
> +						  "#power-domain-cells");
> +	if (priv->num_pd < 0)
> +		return priv->num_pd;
> +
> +	if (!priv->num_pd)
> +		return 0;
> +
> +	priv->pd_dev = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev), GFP_KERNEL);
> +	if (!priv->pd_dev)
> +		return -ENOMEM;
> +
> +	priv->pd_dev_link = devm_kmalloc_array(dev, priv->num_pd, sizeof(*priv->pd_dev_link),
> +					       GFP_KERNEL);
> +
> +	if (!priv->pd_dev_link)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < priv->num_pd; i++) {
> +		priv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
> +		if (IS_ERR(priv->pd_dev[i])) {
> +			ret = PTR_ERR(priv->pd_dev[i]);
> +			goto detach_pd;
> +		}
> +
> +		priv->pd_dev_link[i] = device_link_add(dev, priv->pd_dev[i], DL_FLAG_STATELESS |
> +						       DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
> +		if (!priv->pd_dev_link[i]) {
> +			dev_pm_domain_detach(priv->pd_dev[i], false);
> +			ret = -EINVAL;
> +			goto detach_pd;
> +		}
> +	}
> +
> +	return 0;
> +
> +detach_pd:
> +	while (--i >= 0) {
> +		device_link_del(priv->pd_dev_link[i]);
> +		dev_pm_domain_detach(priv->pd_dev[i], false);
> +	}
> +
> +	return ret;
> +}
> +
>  static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  {
>  	struct regmap_config config = { .name = "imx-rproc" };
> @@ -749,13 +809,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  			return ret;
>  		}
>  
> +		priv->has_clk = false;

This statement seems to imply that for imx8qxq processors, which is the only one
to use the IMX_RPROC_SCU_API, priv->has_clk is always false.  If so then why
bother with a flag at all?

More comments tomorrow...

>  		/*
>  		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
>  		 * and Linux could only do IPC with Mcore and nothing else.
>  		 */
>  		if (!imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc)) {
>  
> -			priv->has_clk = false;
>  			priv->rproc->self_recovery = true;
>  			priv->rproc->state = RPROC_DETACHED;
>  
> @@ -782,6 +842,8 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  				dev_warn(dev, "Enable irq failed.\n");
>  				return ret;
>  			}
> +		} else {
> +			return imx_rproc_attach_pd(priv);
>  		}
>  
>  		return 0;
> -- 
> 2.25.1
> 


From linux at armlinux.org.uk  Wed Jan 19 11:12:22 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Jan 2022 19:12:22 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
Message-ID: <YehilqRvYLhryUk4@shell.armlinux.org.uk>

On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
> Indeed, my impression is that the only legitimate way to get hold of a page
> pointer without assumed provenance is via pfn_to_page(), which is where
> pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
> tautology.

That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
values of pfn.

Given how pfn_to_page() is defined in the sparsemem case:

#define __pfn_to_page(pfn)                              \
({	unsigned long __pfn = (pfn);                    \
	struct mem_section *__sec = __pfn_to_section(__pfn);    \
	__section_mem_map_addr(__sec) + __pfn;          \
})
#define page_to_pfn __page_to_pfn

that isn't the case, especially when looking at page_to_pfn():

#define __page_to_pfn(pg)                                       \
({      const struct page *__pg = (pg);                         \
        int __sec = page_to_section(__pg);                      \
	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
})

Where:

static inline unsigned long page_to_section(const struct page *page)
{
	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
}

So if page_to_section() returns something that is, e.g. zero for an
invalid page in a non-zero section, you're not going to end up with
the right pfn from page_to_pfn().

As I've said now a couple of times, trying to determine of a struct
page pointer is valid is the wrong question to be asking.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From p.yadav at ti.com  Wed Jan 19 11:31:05 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Thu, 20 Jan 2022 01:01:05 +0530
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119192758.z3lvlkaeyeiqi73a@ti.com>

On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> controller bindings to DT schema format
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
>  MAINTAINERS                                   |   2 +-
>  5 files changed, 224 insertions(+), 123 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> new file mode 100644
> index 000000000000..aa5a1f48494b
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> @@ -0,0 +1,35 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> +
> +maintainers:
> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> +
> +description:
> +  See spi-peripheral-props.yaml for more info.
> +
> +properties:
> +  controller-data:
> +    type: object
> +    additionalProperties: false
> +
> +    properties:
> +      samsung,spi-feedback-delay:
> +        description: |
> +          The sampling phase shift to be applied on the miso line (to account
> +          for any lag in the miso line). Valid values:
> +           - 0: No phase shift.
> +           - 1: 90 degree phase shift sampling.
> +           - 2: 180 degree phase shift sampling.
> +           - 3: 270 degree phase shift sampling.
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        enum: [0, 1, 2, 3]
> +
> +    required:
> +      - samsung,spi-feedback-delay

I am not quite sure if this required would work here. Let's say another 
controller also uses a controller-data node, but it contains a different 
set of properties. Won't this cause an error to be raised for that 
controller since this property is not there?

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From willy at infradead.org  Wed Jan 19 11:35:33 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 19 Jan 2022 19:35:33 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YehfHsuMzvy//Szi@shell.armlinux.org.uk>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>
 <YehR9BiI92q5DSOu@casper.infradead.org>
 <YehfHsuMzvy//Szi@shell.armlinux.org.uk>
Message-ID: <YehoBQZvSmwXjqJ3@casper.infradead.org>

On Wed, Jan 19, 2022 at 06:57:34PM +0000, Russell King (Oracle) wrote:
> On Wed, Jan 19, 2022 at 06:01:24PM +0000, Matthew Wilcox wrote:
> > On Wed, Jan 19, 2022 at 05:54:15PM +0000, Russell King (Oracle) wrote:
> > > On Wed, Jan 19, 2022 at 04:27:32PM +0000, Matthew Wilcox wrote:
> > > > On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > > > > > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > > > > 
> > > > > Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> > > > > in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> > > > > true...
> > > > 
> > > > Even if it does blow up, at least it's blowing up here where someone
> > > > can start to debug it, rather than blowing up on first access, where
> > > > we no longer have the invlid struct page pointer.
> > > > 
> > > > I don't think we have a 'page_valid' function which will tell us whether
> > > > a random pointer is actually a struct page or not.
> > > 
> > > Isn't it supposed to be:
> > > 
> > > 	if (!pfn_valid(pfn)) {
> > > 		handle invalid pfn;
> > > 	}
> > > 
> > > 	page = pfn_to_page(pfn);
> > > 
> > > Anything else - even trying to convert an invalid page back to a pfn,
> > > could well be unreliable (sparsemem or discontigmem). 
> > 
> > This function is passed an array of pages.  We have no way of doing
> > what you propose.
> 
> You can't go from a struct page to "this is valid", it's too late by the
> time you call vmap() - that's my fundamental point.

Yes, and we have debugging code in __virt_to_phys() that would have
caught this, had Yury enabled CONFIG_DEBUG_VIRTUAL.  My point is that
in this instance, page_to_pfn() doesn't crash, which lets vmap() set
up a mapping to a completely bogus physical address.  We're better
off checking pfn_valid() here than not.

> If the translation from a PFN to a struct page can return pointers to
> something that isn't a valid struct page, then it can also (with
> sparsemem) return a pointer to _another_ struct page that could well
> be valid depending on how the struct page arrays are laid out in
> memory.

Sure, it's not going to catch everything.  But I don't think that
letting perfect be the enemy of the good here is the right approach.


From olof at lixom.net  Wed Jan 19 11:43:29 2022
From: olof at lixom.net (Olof Johansson)
Date: Wed, 19 Jan 2022 11:43:29 -0800
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CA+Eumj5sosSkCCANOVqN8fVUDFaSNtB7+f95o+FAp7w6rM4A=A@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
 <CA+Eumj5sosSkCCANOVqN8fVUDFaSNtB7+f95o+FAp7w6rM4A=A@mail.gmail.com>
Message-ID: <CAOesGMiDqBPeNp8u_V0P6z0q+sHWhzwr+FbXrzXCRjnKu59TdQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 9:01 AM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On Wed, 19 Jan 2022 at 17:53, Olof Johansson <olof at lixom.net> wrote:
> >
> > On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
> > >
> > > On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
> > > <semen.protsenko at linaro.org> wrote:
> > > > On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> > > >
> > > > Hi Olof, Arnd,
> > > >
> > > > Just want to check if it's possible for those patches to be applied in
> > > > v5.17? Sorry for the noise, but that's important to me.
> > >
> > > I can see that Olof merged merged this into the "arm/late" branch in
> > > the soc tree,
> > > so I assume he still plans to send it in the next few days.
> >
> > Yep, will be sent up today most likely.
> >
> > > With the timing over Christmas, I sent out the large bulk of the
> > > contents (anything
> > > I merged before Dec 23) last year, and Linus already merged it, the rest ended
> > > up in the "late" branch.
> > >
> > > As usual, there is no guarantee that late changes make it in, but I have seen
> > > no indication of any problems so far.
> >
> > Correct. Been sitting on it for a while in case there were fixes
> > coming in for the first pieces that got merged, but in traditional
> > fashion I'm guessing those will start to show up a few days after the
> > late branch gets merged. :)
>
> Actually I have such, but to prepare a pull with them, I would need to
> base it on some random Linus' commit, not on v5.17-rc1. Therefore I
> wait for v5.17-rc1. Would you prefer different approach?

If needed you can base it on Linus' last merge commit of arm-soc
contents for the first set of fixes (or your topic branch that you
sent the code up on), but it's also OK to wait if they're minor
bugs/fixes.


-Olof


From andriy.shevchenko at linux.intel.com  Wed Jan 19 11:47:56 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Wed, 19 Jan 2022 21:47:56 +0200
Subject: [PATCH v4 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220119103212.13158-4-axe.yang@mediatek.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
 <20220119103212.13158-4-axe.yang@mediatek.com>
Message-ID: <Yehq7L36yfJ8D/j2@smile.fi.intel.com>

On Wed, Jan 19, 2022 at 06:32:12PM +0800, Axe Yang wrote:
> Add support for eint IRQ when MSDC is used as an SDIO host. This
> feature requires SDIO device support async IRQ function. With this
> feature, SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in MSDC node
> to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>         &mmcX {
>                 ...
>                 pinctrl-names = "default", "state_uhs", "state_eint",
>                                 "state_dat1";
>                 ...
>                 pinctrl-2 = <&mmc2_pins_eint>;
>                 pinctrl-3 = <&mmc2_pins_dat1>;
>                 ...
>                 cap-sdio-async-irq;
>                 ...
>         };
> 
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>

The submitters SoB must be last among all SoB tags. Please, read Submitting
Patches document carefully.

> Signed-off-by: Yong Mao <yong.mao at mediatek.com>

Who is they, why their SoB appeared here?

...

>  /*
> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2022 MediaTek Inc.

This doesn't feel right. Why did you remove old years?

>   * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
>   */

...

> +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);

> +	ret = gpiod_to_irq(desc);
> +	if (ret < 0)
> +		return ret;
> +
> +	irq = ret;

Since both of them are local variables and there is no specific use of the
returned value, I believe it's fine just to

	irq = gpiod_to_irq(desc);
	...

Hmm... I was wondering if you can use fwnode_irq_get_byname().
Ah, it's not (yet) in upstream.

...

>  static int __maybe_unused msdc_runtime_suspend(struct device *dev)
>  {
> +	unsigned long flags;

Can you keep reversed xmas tree order?

>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);

(it means to add new variable here)

>  	return 0;
>  }

...

>  static int __maybe_unused msdc_runtime_resume(struct device *dev)
>  {
> +	unsigned long flags;

Ditto.

>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);
>  	int ret;

>  	return 0;
>  }

-- 
With Best Regards,
Andy Shevchenko




From krzysztof.kozlowski at canonical.com  Wed Jan 19 11:49:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 20:49:44 +0100
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220119192758.z3lvlkaeyeiqi73a@ti.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
Message-ID: <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>

On 19/01/2022 20:31, Pratyush Yadav wrote:
> On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
>> controller bindings to DT schema format
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
>> ---
>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
>>  MAINTAINERS                                   |   2 +-
>>  5 files changed, 224 insertions(+), 123 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>>
>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>> new file mode 100644
>> index 000000000000..aa5a1f48494b
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>> @@ -0,0 +1,35 @@
>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
>> +
>> +maintainers:
>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> +
>> +description:
>> +  See spi-peripheral-props.yaml for more info.
>> +
>> +properties:
>> +  controller-data:
>> +    type: object
>> +    additionalProperties: false
>> +
>> +    properties:
>> +      samsung,spi-feedback-delay:
>> +        description: |
>> +          The sampling phase shift to be applied on the miso line (to account
>> +          for any lag in the miso line). Valid values:
>> +           - 0: No phase shift.
>> +           - 1: 90 degree phase shift sampling.
>> +           - 2: 180 degree phase shift sampling.
>> +           - 3: 270 degree phase shift sampling.
>> +        $ref: /schemas/types.yaml#/definitions/uint32
>> +        enum: [0, 1, 2, 3]
>> +
>> +    required:
>> +      - samsung,spi-feedback-delay
> 
> I am not quite sure if this required would work here. Let's say another 
> controller also uses a controller-data node, but it contains a different 
> set of properties. Won't this cause an error to be raised for that 
> controller since this property is not there?

The controller-data is Samsung SPI specific (does not exist in any other
binding), so why would controller-data get added to a different controller?

Best regards,
Krzysztof


From sboyd at kernel.org  Wed Jan 19 12:05:22 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 12:05:22 -0800
Subject: [PATCH 1/1] clk: mediatek: relicense mt7986 clock driver to
 GPL-2.0
In-Reply-To: <20220119123658.10095-2-sam.shih@mediatek.com>
References: <20220119123658.10095-1-sam.shih@mediatek.com>
 <20220119123658.10095-2-sam.shih@mediatek.com>
Message-ID: <20220119200524.15995C004E1@smtp.kernel.org>

Quoting Sam Shih (2022-01-19 04:36:58)
> The previous mt7986 clock drivers were incorrectly marked as GPL-1.0.
> This patch changes the driver to the standard GPL-2.0 license.
> 
> Signed-off-by: Sam Shih <sam.shih at mediatek.com>
> ---

Applied to clk-next


From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:00 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:00 +0100
Subject: [PATCH v4 0/5] spi: dt-bindings: samsung: convert to dtschema
Message-ID: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v3
================
1. Patch 2: correct path in exynos-usi.yaml.
2. Add patch 5.
3. Add tags.

Changes since v2
================
1. Patch 2: drop child device schema, as Rob suggested.

Changes since v1
================
1. Patch 2: describe devices matching compatible, correct issues pointed out by
   Rob, add reviewed-by tag.
2. New patches 3 and 4.

Best regards,
Krzysztof

Krzysztof Kozlowski (5):
  ARM: dts: exynos: split dmas into array of phandles in Exynos5250
  spi: dt-bindings: samsung: convert to dtschema
  spi: dt-bindings: samsung: allow controller-data to be optional
  mfd: dt-bindings: google,cros-ec: reference Samsung SPI bindings
  spi: s3c64xx: allow controller-data to be optional

 .../bindings/mfd/google,cros-ec.yaml          |  29 +--
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  36 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 arch/arm/boot/dts/exynos5250.dtsi             |   9 +-
 drivers/spi/spi-s3c64xx.c                     |  14 +-
 9 files changed, 251 insertions(+), 151 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:01 +0100
Subject: [PATCH v4 1/5] ARM: dts: exynos: split dmas into array of phandles in
 Exynos5250
In-Reply-To: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119201005.13145-2-krzysztof.kozlowski@canonical.com>

"dmas" property should be rather an array of phandles, as dtschema
points.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..102bb57bf704 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
 			status = "disabled";
 			reg = <0x12d20000 0x100>;
 			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 5
-				&pdma0 4>;
+			dmas = <&pdma0 5>, <&pdma0 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
 			status = "disabled";
 			reg = <0x12d30000 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma1 5
-				&pdma1 4>;
+			dmas = <&pdma1 5>, <&pdma1 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
 			status = "disabled";
 			reg = <0x12d40000 0x100>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 7
-				&pdma0 6>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:03 +0100
Subject: [PATCH v4 3/5] spi: dt-bindings: samsung: allow controller-data to be
 optional
In-Reply-To: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119201005.13145-4-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI bindings requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Chanho Park <chanho61.park at samsung.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../devicetree/bindings/spi/samsung,spi-peripheral-props.yaml    | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
index aa5a1f48494b..cadc8a5f061f 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -28,6 +28,7 @@ properties:
            - 3: 270 degree phase shift sampling.
         $ref: /schemas/types.yaml#/definitions/uint32
         enum: [0, 1, 2, 3]
+        default: 0
 
     required:
       - samsung,spi-feedback-delay
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:02 +0100
Subject: [PATCH v4 2/5] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119201005.13145-3-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 6 files changed, 225 insertions(+), 124 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
index 273f2d95a043..e72b6a3fae99 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
@@ -22,7 +22,7 @@ description: |
 
   [1] Documentation/devicetree/bindings/serial/samsung_uart.yaml
   [2] Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
-  [3] Documentation/devicetree/bindings/spi/spi-samsung.txt
+  [3] Documentation/devicetree/bindings/spi/samsung,spi.yaml
 
 properties:
   $nodename:
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..aa5a1f48494b
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  See spi-peripheral-props.yaml for more info.
+
+properties:
+  controller-data:
+    type: object
+    additionalProperties: false
+
+    properties:
+      samsung,spi-feedback-delay:
+        description: |
+          The sampling phase shift to be applied on the miso line (to account
+          for any lag in the miso line). Valid values:
+           - 0: No phase shift.
+           - 1: 90 degree phase shift sampling.
+           - 2: 180 degree phase shift sampling.
+           - 3: 270 degree phase shift sampling.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2, 3]
+
+    required:
+      - samsung,spi-feedback-delay
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..61c77088e8ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi # for S5PV210 and S5PC110
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..df885eeb144f 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -85,5 +85,6 @@ properties:
 # The controller specific properties go here.
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
+  - $ref: samsung,spi-peripheral-props.yaml#
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..1f951bc877f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17054,7 +17054,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:04 +0100
Subject: [PATCH v4 4/5] mfd: dt-bindings: google,
 cros-ec: reference Samsung SPI bindings
In-Reply-To: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119201005.13145-5-krzysztof.kozlowski@canonical.com>

The ChromeOS Embedded Controller appears on boards with Samsung Exynos
SoC, where Exynos SPI bindings expect controller-data node.  Reference
newly added dtschema for this property.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/mfd/google,cros-ec.yaml          | 29 ++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index d793dd0316b7..e9c46430fd8a 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -32,7 +32,7 @@ properties:
 
   controller-data:
     description:
-      SPI controller data, see bindings/spi/spi-samsung.txt
+      SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
     type: object
 
   google,cros-ec-spi-pre-delay:
@@ -149,18 +149,21 @@ patternProperties:
 required:
   - compatible
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - google,cros-ec-i2c
-          - google,cros-ec-rpmsg
-then:
-  properties:
-    google,cros-ec-spi-pre-delay: false
-    google,cros-ec-spi-msg-delay: false
-    spi-max-frequency: false
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - google,cros-ec-i2c
+              - google,cros-ec-rpmsg
+    then:
+      properties:
+        google,cros-ec-spi-pre-delay: false
+        google,cros-ec-spi-msg-delay: false
+        spi-max-frequency: false
+
+  - $ref: /schemas/spi/samsung,spi-peripheral-props.yaml
 
 additionalProperties: false
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Wed Jan 19 12:10:05 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 19 Jan 2022 21:10:05 +0100
Subject: [PATCH v4 5/5] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220119201005.13145-6-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI driver requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/spi/spi-s3c64xx.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..769d958a2f86 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
 		return ERR_PTR(-EINVAL);
 	}
 
-	data_np = of_get_child_by_name(slave_np, "controller-data");
-	if (!data_np) {
-		dev_err(&spi->dev, "child node 'controller-data' not found\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		of_node_put(data_np);
+	if (!cs)
 		return ERR_PTR(-ENOMEM);
+
+	data_np = of_get_child_by_name(slave_np, "controller-data");
+	if (!data_np) {
+		dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");
+		return cs;
 	}
 
 	of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
-- 
2.32.0



From swboyd at chromium.org  Wed Jan 19 12:11:34 2022
From: swboyd at chromium.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 12:11:34 -0800
Subject: [PATCH v2 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220118144851.69537-3-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150018epcas5p32642af7af63869d08a861d00d97e3b68@epcas5p3.samsung.com>
 <20220118144851.69537-3-alim.akhtar@samsung.com>
Message-ID: <CAE-0n51KLEbCsvR7ByzNXxKg7gK4y6UNvg5vfAJ4C87QUweC9Q@mail.gmail.com>

Quoting Alim Akhtar (2022-01-18 06:48:37)
> Clock controller driver of FSD platform is designed to have separate
> instances for each particular CMU. So clock IDs in this bindings header
> also start from 1 for each CMU block.
>
> Cc: linux-fsd at tesla.com
> Reported-by: kernel test robot <lkp at intel.com>
> [robot: reported missing #endif]
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Wed Jan 19 12:12:56 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 12:12:56 -0800
Subject: [PATCH v2 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220118144851.69537-4-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150022epcas5p21912423606220552a78c7e22e4133a05@epcas5p2.samsung.com>
 <20220118144851.69537-4-alim.akhtar@samsung.com>
Message-ID: <20220119201258.1DA67C004E1@smtp.kernel.org>

Quoting Alim Akhtar (2022-01-18 06:48:38)
> Add dt-schema documentation for Tesla FSD SoC clock controller.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---

Acked-by: Stephen Boyd <sboyd at kernel.org>


From sboyd at kernel.org  Wed Jan 19 12:15:07 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 12:15:07 -0800
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220118144851.69537-5-alim.akhtar@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
 <20220118144851.69537-5-alim.akhtar@samsung.com>
Message-ID: <20220119201509.6220FC004E1@smtp.kernel.org>

Quoting Alim Akhtar (2022-01-18 06:48:39)
> diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
> new file mode 100644
> index 000000000000..2669396d81b9
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-fsd.c
> @@ -0,0 +1,308 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> + *             https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *             https://www.tesla.com
> + *
> + * Common Clock Framework support for FSD SoC.
> + */
> +
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>

include init.h for __initconst and kernel.h for ARRAY_SIZE

> +
> +#include <dt-bindings/clock/fsd-clk.h>
> +
> +#include "clk.h"
> +


From steven at liquorix.net  Wed Jan 19 12:19:30 2022
From: steven at liquorix.net (Steven Barrett)
Date: Wed, 19 Jan 2022 14:19:30 -0600
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <9203f79f-7910-4613-a593-aa6fda665b42@www.fastmail.com>

On Tue, Jan 11, 2022, at 2:41 AM, Yu Zhao wrote:
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> > On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > > TLDR
> > > ====
> > > The current page reclaim is too expensive in terms of CPU usage and it
> > > often makes poor choices about what to evict. This patchset offers an
> > > alternative solution that is performant, versatile and
> > > straightforward.
> > 
> > <snipped>
> > 
> > > Summery
> > > =======
> > > The facts are:
> > > 1. The independent lab results and the real-world applications
> > >    indicate substantial improvements; there are no known regressions.
> > > 2. Thrashing prevention, working set estimation and proactive reclaim
> > >    work out of the box; there are no equivalent solutions.
> > > 3. There is a lot of new code; nobody has demonstrated smaller changes
> > >    with similar effects.
> > > 
> > > Our options, accordingly, are:
> > > 1. Given the amount of evidence, the reported improvements will likely
> > >    materialize for a wide range of workloads.
> > > 2. Gauging the interest from the past discussions [14][15][16], the
> > >    new features will likely be put to use for both personal computers
> > >    and data centers.
> > > 3. Based on Google's track record, the new code will likely be well
> > >    maintained in the long term. It'd be more difficult if not
> > >    impossible to achieve similar effects on top of the existing
> > >    design.
> > 
> > Hi Andrew, Linus,
> > 
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> > 
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.
> 
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
> 
> Having this patchset in the mainline will make your job easier :)
> 
>    Alexandre - the XanMod Kernel maintainer
>                https://xanmod.org
>    
>    Brian     - the Chrome OS kernel memory maintainer
>                https://www.chromium.org
>    
>    Jan       - the Arch Linux Zen kernel maintainer
>                https://archlinux.org
>    
>    Steven    - the Liquorix kernel maintainer
>                https://liquorix.net
>    
>    Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                https://chromium.googlesource.com/chromiumos/third_party/kernel
> 
> Also my gratitude to those who have helped test MGLRU:
> 
>    Daniel - researcher at Michigan Tech
>             benchmarked memcached
>    
>    Holger - who has been testing/patching/contributing to various
>             subsystems since ~2008
>    
>    Shuang - researcher at University of Rochester
>             benchmarked fio and provided a report
>    
>    Sofia  - EDI https://www.edi.works
>             benchmarked the top eight memory hogs and provided reports
> 
> Can you please provide your Tested-by tags? This will ensure the credit
> for your contributions.
> 
> Thanks!

This feature has been a huge improvement for desktop linux, system
responsiveness has hit a new level high memory pressure.  Thanks Yu!

Acked-by: Steven Barrett <steven at liquorix.net>


From john.stultz at linaro.org  Wed Jan 19 12:37:27 2022
From: john.stultz at linaro.org (John Stultz)
Date: Wed, 19 Jan 2022 12:37:27 -0800
Subject: [PATCH v3] dma-buf: dma-heap: Add a size check for allocation
In-Reply-To: <f09938519f1fcf51f20a0de5eb4063b0ff1a1e87.camel@mediatek.com>
References: <CAO_48GF=ttKqSOm9GRoA3Mq+-RQOtRjWp449XPcz-wH=kjaTjw@mail.gmail.com>
 <20220113123406.11520-1-guangming.cao@mediatek.com>
 <4f88205c1b344aea8608960e2f85b8f4@intel.com>
 <e657f5257cbf4955817b0bbf037de9f9@intel.com>
 <24157767-dc29-bbdd-5428-d89ecc6b9606@amd.com>
 <CALAqxLXRtYDNQ8y1efVGa4SwUH_oAaHviZFjsOVSNFmUHnCCeQ@mail.gmail.com>
 <6b8182a1-7cdc-7369-5c34-e6d0c24efcca@amd.com>
 <82faa62f1bc946cf2f9ee2f7d15c567162238eab.camel@mediatek.com>
 <CALAqxLUSjHoLpgFLcvqmDfv7Uip2VwHS5d_5x2nzw=P3rA2NDA@mail.gmail.com>
 <f09938519f1fcf51f20a0de5eb4063b0ff1a1e87.camel@mediatek.com>
Message-ID: <CALAqxLUtK8V9LgC-DY+tkzFYyWfzF+JhbrLZk6UhEG57HQBDSA@mail.gmail.com>

On Wed, Jan 19, 2022 at 1:58 AM Guangming.Cao
<guangming.cao at mediatek.com> wrote:
> On Fri, 2022-01-14 at 17:17 -0800, John Stultz wrote:
> > If the max value is per-heap, why not enforce that value in the
> > per-heap allocation function?
> >
> > Moving the check to the heap alloc to me seems simpler to me than
> > adding complexity to the infrastructure to add a heap max_size
> > callback. Is there some other use for the callback that you envision?
> >
>
> If you think max the value is per-heap, why not add an optional
> callback for dma-heap to solve this issue(prevent consuming too much
> time for a doomed to fail allocation), if the dma-heap doesn't have a
> special size check, just use the default value(totalram) in dma-heap
> framework to do the size check.

As the totalram default isn't correct for all heaps (or necessarily
even most heaps), so those heaps would need to implement the callback.

I'm just not sure adding complexity to the framework to address this
is useful. Instead of an additional check in the allocation function,
heap implementers will need to assess if the default logic in a
framework is correct, and then possibly implement the callback.

> Yes, for linux dma-heaps, only system-heap needs it, so adding it in
> system heap is the simplest. However, there are many vendor dma-heaps
> like system-heap which won't be uploaded to linux codebase, and maybe
> have same limitation, all these heaps need to add the same limitation.

My worry is that without seeing these vendor heaps, this is a bit of a
theoretical concern. We don't have the data on how common this is.
I very much hope that vendors can start submitting their heaps
upstream (along with drivers that benefit from the heaps). Then we can
really assess what makes the most sense for the community maintained
code.


> I just think it's boring. However, If you think discussing these absent
> cases based on current linux code is meaningless, I also agree to it.

So, as a rule, the upstream kernel doesn't create/maintain logic to
accommodate out of tree code.

Now, I agree there is the potential for some duplication in the checks
in the allocation logic, but until it affects the upstream kernel,
community maintainers can't really make an appropriate evaluation.

As a contra-example, if the allocation is some extreme hotpath, adding
an extra un-inlinable function pointer traversal for the size callback
may actually have a negative impact. This isn't likely but again, if
we cannot demonstrate it one way or the other against the upstream
tree, we can't figure out what the best solution might be.


> So, to summarize, if you still think adding it in system_heap.c is
> better, I also agree and I will update the patch to add it in
> system_heap.c

I think this is the best solution for now. As this is not part of an
userland ABI, we can always change it in the future once we see the
need.

thanks
-john


From helgaas at kernel.org  Wed Jan 19 12:42:59 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 19 Jan 2022 14:42:59 -0600
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <e57cc874-dacd-912d-4282-3cb6b1b77323@linux.alibaba.com>
Message-ID: <20220119204259.GA962224@bhelgaas>

On Wed, Jan 19, 2022 at 02:40:11PM +0800, Shuai Xue wrote:
> [+to Rafael, question about HEST/GHES/SDEI init]
> 
> Hi, Bjorn,
> 
> Thank you for your comments and quick reply.
> 
> ? 2022/1/19 AM6:49, Bjorn Helgaas ??:
> > On Sun, Jan 16, 2022 at 04:43:10PM +0800, Shuai Xue wrote:
> >> On an ACPI system, ACPI is initialised very early from a
> >> subsys_initcall(), while SDEI is not ready until a
> >> subsys_initcall_sync(). This patch is to reduce the time before GHES
> >> initialization.
> >>
> >> The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
> >> apei_sdei_unregister_ghes()) to register or unregister event callback
> >> for dispatcher in firmware. When the GHES driver probing, it registers
> >> the corresponding callback according to the notification type specified
> >> by GHES. If the GHES notification type is SDEI, the GHES driver will
> >> call apei_sdei_register_ghes() to register event call.
> >>
> >> When the firmware emits an event, it migrates the handling of the event
> >> into the kernel at the registered entry-point __sdei_asm_handler. And
> >> finally, the kernel will call the registered event callback and return
> >> status_code to indicate the status of event handling. SDEI_EV_FAILED
> >> indicates that the kernel failed to handle the event.
> >>
> >> Consequently, when an error occurs during kernel booting, the kernel is
> >> unable to handle and report errors until the GHES driver is initialized
> >> by device_initcall(), in which the event callback is registered.  For
> >> example, when the kernel booting, the console logs many times from
> >> firmware before GHES drivers init in our platform:
> >>
> >> 	Trip in MM PCIe RAS handle(Intr:910)
> >>   	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
> >> 	Find RP(98:1.0)
> >> 	--Walk dev(98:1.0) CE:0 UCE:4000
> >> 	...
> >> 	ERROR:   sdei_dispatch_event(32a) ret:-1
> >> 	--handler(910) end
> > 
> > If I understand correctly, the firmware noticed an error, tried to
> > report it to the kernel, and is complaining because the kernel isn't
> > ready to handle it yet.  And the reason for this patch is to reduce
> > these complaints from the firmware.
> 
> My thoughts exactly :)
> 
> > That doesn't seem like a very good reason for this patch.  There is
> > *always* a window before the kernel is ready to handle events from the
> > firmware.
> 
> Yes, there is always a window. But if we could do better in kernel that
> reduces the window by 90% (from 33 seconds to 3 second), why not?
> 
> > Why is the firmware noticing these errors in the first place?  If
> > you're seeing these complaints regularly, my guess is that either you
> > have some terrible hardware or (more likely) the firmware isn't
> > clearing some expected error condition correctly.  For example, maybe
> > the Unsupported Request errors that happen while enumerating PCIe
> > devices are being reported.
> >
> > If you register the callback function, the kernel will now start
> > seeing these error reports.  What happens then?  Does the kernel log
> > the errors somewhere?  Is that better than the current situation where
> > the firmware logs them?
> 
> Yep, it is a hardware issue. The firmware only logs in console
> (ttyAMA0) and we can not see it in kernel side. After the kernel
> starts seeing these error reports, we could see EDAC/ghes and
> efi/cper detailed logs in dmesg. We did not notice the problem until
> we check the console log, which inspired us to reduce the window
> when kernel startup, so that we can see the message clearly and
> properly. I think the intuition is to check the log of dmesg, not
> the console.

> > However, I DO think that:
> > 
> >   - Removing acpi_hest_init() from acpi_pci_root_init(), and
> > 
> >   - Converting ghes_init() and sdei_init() from initcalls to explicit
> >     calls
> > 
> > are very good reasons to do something like this patch because HEST is
> > not PCI-specific, and IMO, explicit calls are better than initcalls
> > because initcall ordering is implicit and not well-defined within a
> > level.
> 
> Haha, if the above reasons still don't convince you, I would like to
> accept yours :) Should we do it in one patch or separate it into two
> patches?

IMO, this can be done in one patch, but this would probably go via
Rafael.

> >> -static int __init ghes_init(void)
> >> +void __init ghes_init(void)
> >>  {
> >>  	int rc;
> >>  
> >>  	if (acpi_disabled)
> >> -		return -ENODEV;
> >> +		return;
> >>  
> >>  	switch (hest_disable) {
> >>  	case HEST_NOT_FOUND:
> >> -		return -ENODEV;
> >> +		pr_info(GHES_PFX "HEST is not found!\n");
> > 
> > I don't know whether this "HEST is not found" message is
> > worthwhile or not.  I don't think lack of an HEST is an error, and
> > users may be alarmed.  But this is an ACPI thing, so up to you and
> > Rafael.
> 
> If we explicit call ghes_init(), we can't tell if ghes is
> initialized successfully based on the return value of initcall. So I
> add a info message.

When ghes_init() is an initcall and you return -ENODEV for the
HEST_NOT_FOUND case, I don't think we log any message about that, do
we?  do_one_initcall() will capture and return the -ENODEV, but the
caller (do_initcall_level()) just ignores it.

> >> @@ -1495,8 +1494,7 @@ static int __init ghes_init(void)
> >>  	else
> >>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
> >>  
> >> -	return 0;
> >> +	return;
> >>  err:
> >> -	return rc;
> >> +	ghes_disable = 1;
> > 
> > Why do you set ghes_disable here?  As far as I can tell, we will never
> > look at it again.  The places we do look at it are:
> > 
> >   - ghes_init(): earlier in this function, so we've already done that,
> > 
> >   - acpi_hest_init(): we've already called that, too, and
> > 
> >   - acpi_bus_osc_negotiate_platform_control(): called from
> >     acpi_bus_init(), which we've already called.
> 
> I add it for future potential usage. Thank you for pointing it out.
> If you think it is not necessary, I will delete it in next version.

I think it is not necessary to save information that will never be
used.  If you need it in the future, you can add it and the reason
will be obvious.

Bjorn


From andi at etezian.org  Wed Jan 19 12:55:35 2022
From: andi at etezian.org (Andi Shyti)
Date: Wed, 19 Jan 2022 22:55:35 +0200
Subject: [PATCH v4 5/5] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220119201005.13145-6-krzysztof.kozlowski@canonical.com>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
 <20220119201005.13145-6-krzysztof.kozlowski@canonical.com>
Message-ID: <Yeh6x6U3tA7y5gvF@jack.zhora.eu>

Hi Krzysztof,

On Wed, Jan 19, 2022 at 09:10:05PM +0100, Krzysztof Kozlowski wrote:
> The Samsung SoC SPI driver requires to provide controller-data node
> for each of SPI peripheral device nodes.  Make this controller-data node
> optional, so DTS could be simpler.
> 
> Suggested-by: Rob Herring <robh at kernel.org>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/spi/spi-s3c64xx.c | 14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
> index 8755cd85e83c..769d958a2f86 100644
> --- a/drivers/spi/spi-s3c64xx.c
> +++ b/drivers/spi/spi-s3c64xx.c
> @@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> -	data_np = of_get_child_by_name(slave_np, "controller-data");
> -	if (!data_np) {
> -		dev_err(&spi->dev, "child node 'controller-data' not found\n");
> -		return ERR_PTR(-EINVAL);
> -	}
> -
>  	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
> -	if (!cs) {
> -		of_node_put(data_np);
> +	if (!cs)
>  		return ERR_PTR(-ENOMEM);
> +
> +	data_np = of_get_child_by_name(slave_np, "controller-data");
> +	if (!data_np) {
> +		dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");

"not found" sounds like an error; I would just write something
like "feedback delay set to '0' dfault", you also tell that the
default value is '0'.

In any case,

Reviewed-by: Andi Shyti <andi at etezian.org>

Andi


From nathan at kernel.org  Wed Jan 19 14:24:31 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Wed, 19 Jan 2022 15:24:31 -0700
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <20220119135450.564115-1-Jason@zx2c4.com>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com>
Message-ID: <YeiPn8Mo1AM7X9Ud@archlinux-ax161>

On Wed, Jan 19, 2022 at 02:54:50PM +0100, Jason A. Donenfeld wrote:
> blake2s_compress_generic is weakly aliased to blake2s_generic. The

Isn't it the other way around?

> current harness for function selection uses a function pointer, which is
> ordinarily inlined and resolved at compile time. But when Clang's CFI is
> enabled, CFI still triggers when making an indirect call via a weak
> symbol. This seems like a bug in Clang's CFI, as though it's bucketing
> weak symbols and strong symbols differently. It also only seems to
> trigger when "full LTO" mode is used, rather than "thin LTO".
> 
> [    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
> [    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
> [    0.000000][    T0] Hardware name: MT6873 (DT)
> [    0.000000][    T0] Call trace:
> [    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
> [    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
> [    0.000000][    T0]  panic+0x194/0x464
> [    0.000000][    T0]  __cfi_check_fail+0x54/0x58
> [    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
> [    0.000000][    T0]  blake2s_update+0x14c/0x178
> [    0.000000][    T0]  _extract_entropy+0xf4/0x29c
> [    0.000000][    T0]  crng_initialize_primary+0x24/0x94
> [    0.000000][    T0]  rand_initialize+0x2c/0x6c
> [    0.000000][    T0]  start_kernel+0x2f8/0x65c
> [    0.000000][    T0]  __primary_switched+0xc4/0x7be4
> [    0.000000][    T0] Rebooting in 5 seconds..
> 
> Nonetheless, the function pointer method isn't so terrific anyway, so
> this patch replaces it with a simple boolean, which also gets inlined
> away. This successfully works around the Clang bug.
> 
> In general, I'm not too keen on all of the indirection involved here; it
> clearly does more harm than good. Hopefully the whole thing can get
> cleaned up down the road when lib/crypto is overhauled more
> comprehensively. But for now, we go with a simple bandaid.
> 
> Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
> Reported-by: Miles Chen <miles.chen at mediatek.com>
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Cc: Sami Tolvanen <samitolvanen at google.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>

I am not familiar enough with the inner workings of CFI to comment on
what could be going wrong here in LLVM (perhaps Sami can?) but
eliminating the indirect call resolves the issue for me as well.

Tested-by: Nathan Chancellor <nathan at kernel.org>

> ---
>  arch/arm/crypto/blake2s-shash.c   |  4 ++--
>  arch/x86/crypto/blake2s-shash.c   |  4 ++--
>  crypto/blake2s_generic.c          |  4 ++--
>  include/crypto/internal/blake2s.h | 36 ++++++++++++++++++-------------
>  lib/crypto/blake2s.c              |  4 ++--
>  5 files changed, 29 insertions(+), 23 deletions(-)
> 
> diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
> index 17c1c3bfe2f5..763c73beea2d 100644
> --- a/arch/arm/crypto/blake2s-shash.c
> +++ b/arch/arm/crypto/blake2s-shash.c
> @@ -13,12 +13,12 @@
>  static int crypto_blake2s_update_arm(struct shash_desc *desc,
>  				     const u8 *in, unsigned int inlen)
>  {
> -	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +	return crypto_blake2s_update(desc, in, inlen, false);
>  }
>  
>  static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
>  {
> -	return crypto_blake2s_final(desc, out, blake2s_compress);
> +	return crypto_blake2s_final(desc, out, false);
>  }
>  
>  #define BLAKE2S_ALG(name, driver_name, digest_size)			\
> diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
> index f9e2fecdb761..59ae28abe35c 100644
> --- a/arch/x86/crypto/blake2s-shash.c
> +++ b/arch/x86/crypto/blake2s-shash.c
> @@ -18,12 +18,12 @@
>  static int crypto_blake2s_update_x86(struct shash_desc *desc,
>  				     const u8 *in, unsigned int inlen)
>  {
> -	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +	return crypto_blake2s_update(desc, in, inlen, false);
>  }
>  
>  static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
>  {
> -	return crypto_blake2s_final(desc, out, blake2s_compress);
> +	return crypto_blake2s_final(desc, out, false);
>  }
>  
>  #define BLAKE2S_ALG(name, driver_name, digest_size)			\
> diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
> index 72fe480f9bd6..5f96a21f8788 100644
> --- a/crypto/blake2s_generic.c
> +++ b/crypto/blake2s_generic.c
> @@ -15,12 +15,12 @@
>  static int crypto_blake2s_update_generic(struct shash_desc *desc,
>  					 const u8 *in, unsigned int inlen)
>  {
> -	return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
> +	return crypto_blake2s_update(desc, in, inlen, true);
>  }
>  
>  static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
>  {
> -	return crypto_blake2s_final(desc, out, blake2s_compress_generic);
> +	return crypto_blake2s_final(desc, out, true);
>  }
>  
>  #define BLAKE2S_ALG(name, driver_name, digest_size)			\
> diff --git a/include/crypto/internal/blake2s.h b/include/crypto/internal/blake2s.h
> index d39cfa0d333e..e2da9b413d44 100644
> --- a/include/crypto/internal/blake2s.h
> +++ b/include/crypto/internal/blake2s.h
> @@ -24,14 +24,11 @@ static inline void blake2s_set_lastblock(struct blake2s_state *state)
>  	state->f[0] = -1;
>  }
>  
> -typedef void (*blake2s_compress_t)(struct blake2s_state *state,
> -				   const u8 *block, size_t nblocks, u32 inc);
> -
>  /* Helper functions for BLAKE2s shared by the library and shash APIs */
>  
> -static inline void __blake2s_update(struct blake2s_state *state,
> -				    const u8 *in, size_t inlen,
> -				    blake2s_compress_t compress)
> +static __always_inline void __blake2s_update(struct blake2s_state *state,
> +					     const u8 *in, size_t inlen,
> +					     bool force_generic)
>  {
>  	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
>  
> @@ -39,7 +36,10 @@ static inline void __blake2s_update(struct blake2s_state *state,
>  		return;
>  	if (inlen > fill) {
>  		memcpy(state->buf + state->buflen, in, fill);
> -		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
> +		if (force_generic)
> +			blake2s_compress_generic(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
> +		else
> +			blake2s_compress(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
>  		state->buflen = 0;
>  		in += fill;
>  		inlen -= fill;
> @@ -47,7 +47,10 @@ static inline void __blake2s_update(struct blake2s_state *state,
>  	if (inlen > BLAKE2S_BLOCK_SIZE) {
>  		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
>  		/* Hash one less (full) block than strictly possible */
> -		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> +		if (force_generic)
> +			blake2s_compress_generic(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> +		else
> +			blake2s_compress(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
>  		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
>  		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
>  	}
> @@ -55,13 +58,16 @@ static inline void __blake2s_update(struct blake2s_state *state,
>  	state->buflen += inlen;
>  }
>  
> -static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
> -				   blake2s_compress_t compress)
> +static __always_inline void __blake2s_final(struct blake2s_state *state, u8 *out,
> +					    bool force_generic)
>  {
>  	blake2s_set_lastblock(state);
>  	memset(state->buf + state->buflen, 0,
>  	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
> -	(*compress)(state, state->buf, 1, state->buflen);
> +	if (force_generic)
> +		blake2s_compress_generic(state, state->buf, 1, state->buflen);
> +	else
> +		blake2s_compress(state, state->buf, 1, state->buflen);
>  	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
>  	memcpy(out, state->h, state->outlen);
>  }
> @@ -99,20 +105,20 @@ static inline int crypto_blake2s_init(struct shash_desc *desc)
>  
>  static inline int crypto_blake2s_update(struct shash_desc *desc,
>  					const u8 *in, unsigned int inlen,
> -					blake2s_compress_t compress)
> +					bool force_generic)
>  {
>  	struct blake2s_state *state = shash_desc_ctx(desc);
>  
> -	__blake2s_update(state, in, inlen, compress);
> +	__blake2s_update(state, in, inlen, force_generic);
>  	return 0;
>  }
>  
>  static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
> -				       blake2s_compress_t compress)
> +				       bool force_generic)
>  {
>  	struct blake2s_state *state = shash_desc_ctx(desc);
>  
> -	__blake2s_final(state, out, compress);
> +	__blake2s_final(state, out, force_generic);
>  	return 0;
>  }
>  
> diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
> index 9364f79937b8..c71c09621c09 100644
> --- a/lib/crypto/blake2s.c
> +++ b/lib/crypto/blake2s.c
> @@ -18,14 +18,14 @@
>  
>  void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
>  {
> -	__blake2s_update(state, in, inlen, blake2s_compress);
> +	__blake2s_update(state, in, inlen, false);
>  }
>  EXPORT_SYMBOL(blake2s_update);
>  
>  void blake2s_final(struct blake2s_state *state, u8 *out)
>  {
>  	WARN_ON(IS_ENABLED(DEBUG) && !out);
> -	__blake2s_final(state, out, blake2s_compress);
> +	__blake2s_final(state, out, false);
>  	memzero_explicit(state, sizeof(*state));
>  }
>  EXPORT_SYMBOL(blake2s_final);
> -- 
> 2.34.1
> 
> 


From bgeffon at google.com  Wed Jan 19 14:25:16 2022
From: bgeffon at google.com (Brian Geffon)
Date: Wed, 19 Jan 2022 17:25:16 -0500
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Yd1Css8+jsspeZHh@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <YdSuSHa/Vjl6bPkg@google.com> <Yd1Css8+jsspeZHh@google.com>
Message-ID: <CADyq12z9LtDEURaKTY8qx8nb7mqUL5jLnO682DeweFOmw31LDQ@mail.gmail.com>

On Tue, Jan 11, 2022 at 3:41 AM Yu Zhao <yuzhao at google.com> wrote:
>
> On Tue, Jan 04, 2022 at 01:30:00PM -0700, Yu Zhao wrote:
> > On Tue, Jan 04, 2022 at 01:22:19PM -0700, Yu Zhao wrote:
> > > TLDR
> > > ====
> > > The current page reclaim is too expensive in terms of CPU usage and it
> > > often makes poor choices about what to evict. This patchset offers an
> > > alternative solution that is performant, versatile and
> > > straightforward.
> >
> > <snipped>
> >
> > > Summery
> > > =======
> > > The facts are:
> > > 1. The independent lab results and the real-world applications
> > >    indicate substantial improvements; there are no known regressions.
> > > 2. Thrashing prevention, working set estimation and proactive reclaim
> > >    work out of the box; there are no equivalent solutions.
> > > 3. There is a lot of new code; nobody has demonstrated smaller changes
> > >    with similar effects.
> > >
> > > Our options, accordingly, are:
> > > 1. Given the amount of evidence, the reported improvements will likely
> > >    materialize for a wide range of workloads.
> > > 2. Gauging the interest from the past discussions [14][15][16], the
> > >    new features will likely be put to use for both personal computers
> > >    and data centers.
> > > 3. Based on Google's track record, the new code will likely be well
> > >    maintained in the long term. It'd be more difficult if not
> > >    impossible to achieve similar effects on top of the existing
> > >    design.
> >
> > Hi Andrew, Linus,
> >
> > Can you please take a look at this patchset and let me know if it's
> > 5.17 material?
> >
> > My goal is to get it merged asap so that users can reap the benefits
> > and I can push the sequels. Please examine the data provided -- I
> > think the unprecedented coverage and the magnitude of the improvements
> > warrant a green light.
>
> Downstream kernel maintainers who have been carrying MGLRU for more than
> 3 versions, can you please provide your Acked-by tags?
>
> Having this patchset in the mainline will make your job easier :)
>
>    Alexandre - the XanMod Kernel maintainer
>                https://xanmod.org
>
>    Brian     - the Chrome OS kernel memory maintainer
>                https://www.chromium.org

MGLRU has been maturing in ChromeOS for quite some time, we've
maintained it in a number of different kernels between 4.14 and 5.15,
and it's become the default
for tens of millions of users. We've seen substantial improvements in
terms of CPU utilization and memory pressure resulting in fewer OOM
kills and reduced UI latency. I would love to see this make it
upstream so more desktop users can benefit.

Acked-by: Brian Geffon <bgeffon at google.com>


>
>    Jan       - the Arch Linux Zen kernel maintainer
>                https://archlinux.org
>
>    Steven    - the Liquorix kernel maintainer
>                https://liquorix.net
>
>    Suleiman  - the ARCVM (Android downstream) kernel memory maintainer
>                https://chromium.googlesource.com/chromiumos/third_party/kernel
>
> Also my gratitude to those who have helped test MGLRU:
>
>    Daniel - researcher at Michigan Tech
>             benchmarked memcached
>
>    Holger - who has been testing/patching/contributing to various
>             subsystems since ~2008
>
>    Shuang - researcher at University of Rochester
>             benchmarked fio and provided a report
>
>    Sofia  - EDI https://www.edi.works
>             benchmarked the top eight memory hogs and provided reports
>
> Can you please provide your Tested-by tags? This will ensure the credit
> for your contributions.
>
> Thanks!


From khilman at baylibre.com  Wed Jan 19 14:37:00 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Wed, 19 Jan 2022 14:37:00 -0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <20220118030911.12815-1-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
Message-ID: <7hfspjqrn7.fsf@baylibre.com>

Hello,

Yu Tu <yu.tu at amlogic.com> writes:

> Using the common Clock code to describe the UART baud rate
> clock makes it easier for the UART driver to be compatible
> with the baud rate requirements of the UART IP on different
> meson chips. Add Meson S4 SoC compatible.

Could you describe how this was tested and on which SoCs?  There seem to
be some changes in this series that might affect previous SoCs.

Thanks,

Kevin




From linux at armlinux.org.uk  Wed Jan 19 14:38:42 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 19 Jan 2022 22:38:42 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YehoBQZvSmwXjqJ3@casper.infradead.org>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <YehQR7NWKKzcyEq6@shell.armlinux.org.uk>
 <YehR9BiI92q5DSOu@casper.infradead.org>
 <YehfHsuMzvy//Szi@shell.armlinux.org.uk>
 <YehoBQZvSmwXjqJ3@casper.infradead.org>
Message-ID: <YeiS8vDcQ6/B26fG@shell.armlinux.org.uk>

On Wed, Jan 19, 2022 at 07:35:33PM +0000, Matthew Wilcox wrote:
> On Wed, Jan 19, 2022 at 06:57:34PM +0000, Russell King (Oracle) wrote:
> > On Wed, Jan 19, 2022 at 06:01:24PM +0000, Matthew Wilcox wrote:
> > > On Wed, Jan 19, 2022 at 05:54:15PM +0000, Russell King (Oracle) wrote:
> > > > On Wed, Jan 19, 2022 at 04:27:32PM +0000, Matthew Wilcox wrote:
> > > > > On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> > > > > > > +		if (WARN_ON(!pfn_valid(page_to_pfn(page))))
> > > > > > 
> > > > > > Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> > > > > > in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> > > > > > true...
> > > > > 
> > > > > Even if it does blow up, at least it's blowing up here where someone
> > > > > can start to debug it, rather than blowing up on first access, where
> > > > > we no longer have the invlid struct page pointer.
> > > > > 
> > > > > I don't think we have a 'page_valid' function which will tell us whether
> > > > > a random pointer is actually a struct page or not.
> > > > 
> > > > Isn't it supposed to be:
> > > > 
> > > > 	if (!pfn_valid(pfn)) {
> > > > 		handle invalid pfn;
> > > > 	}
> > > > 
> > > > 	page = pfn_to_page(pfn);
> > > > 
> > > > Anything else - even trying to convert an invalid page back to a pfn,
> > > > could well be unreliable (sparsemem or discontigmem). 
> > > 
> > > This function is passed an array of pages.  We have no way of doing
> > > what you propose.
> > 
> > You can't go from a struct page to "this is valid", it's too late by the
> > time you call vmap() - that's my fundamental point.
> 
> Yes, and we have debugging code in __virt_to_phys() that would have
> caught this, had Yury enabled CONFIG_DEBUG_VIRTUAL.  My point is that
> in this instance, page_to_pfn() doesn't crash, which lets vmap() set
> up a mapping to a completely bogus physical address.  We're better
> off checking pfn_valid() here than not.

I don't disagree that pfn_valid() will catch _some_ but it should, no,
must not be a subsitute for ensuring that the proper checks are done
when creating e.g. an array of struct pages.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From sboyd at kernel.org  Wed Jan 19 15:16:54 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 15:16:54 -0800
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20220115122618.plhiqnjh2755bv5h@pali>
References: <20210930095838.28145-1-pali@kernel.org>
 <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali> <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali> <20220115130509.4a240730@thinkpad>
 <20220115122618.plhiqnjh2755bv5h@pali>
Message-ID: <20220119231655.EFFF3C004E1@smtp.kernel.org>

Quoting Pali Roh?r (2022-01-15 04:26:18)
> On Saturday 15 January 2022 13:05:09 Marek Beh?n wrote:
> > On Sat, 15 Jan 2022 12:50:18 +0100
> > Pali Roh?r <pali at kernel.org> wrote:
> > 
> > > On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > > > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > > > 
> > > > > If I was designing this driver and DTS bindings I would have choose
> > > > > something like this:
> > > > > 
> > > > > uart at 0x12000 {  
> > > > 
> > > > Drop the 0x
> > > >   
> > > > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > > > >     clock-controller {
> > > > >         ...
> > > > >     };  
> > > > 
> > > > Drop this node and put whatever properties are inside into the parent
> > > > node.
> > > >   
> > > > >     serial1 {
> > > > >         ...
> > > > >         status = "disabled";
> > > > >     };
> > > > >     serial2 {
> > > > >         ...
> > > > >         status = "disabled";
> > > > >     };
> > > > > };
> > > > > 
> > > > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > > > defined in top level nodes and would be handled by one driver.
> > > > > 
> > > > > This is really how hardware block looks like. But it is not backward
> > > > > compatible...  
> > > > 
> > > > Sounds good to me. I presume we need the serial child nodes so we can
> > > > reference them from the stdout-path?  
> > > 
> > > Yes, exactly, separate nodes for serial1 and serial2 are still required.
> > > 
> > > But dropping clock controller is not possible as for higher baudrates we
> > > need to use and configure uart clock controller. Without it we just get
> > > comparable feature support which is already present in driver.
> > 
> > What Stephen means is making clock controller out of the uart node
> > directly. No need to add separate subnode just for clock controller.
> 
> This is already implemented in v7 patch series. Clock controller is
> already outside of uart nodes.

I mean to combine the uart node and the clock-controller node together

	uart-wrapper {
		reg = <0x12000 0x18>, <0x12200 0x30>;
		#clock-cells ...

		serial1 {
			...
		};

		serial2 {
			...
		};
	};


From chunkuang.hu at kernel.org  Wed Jan 19 15:19:05 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 20 Jan 2022 07:19:05 +0800
Subject: [v10,2/3] drm/mediatek: implement the DSI HS packets aligned
In-Reply-To: <20220119022543.26093-3-rex-bc.chen@mediatek.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-3-rex-bc.chen@mediatek.com>
Message-ID: <CAAOTY__xbhyOaL-4BZP0n_HdvYz3f6SZzh-WSw-gVv=Yufjy8A@mail.gmail.com>

Hi, Rex:

Rex-BC Chen <rex-bc.chen at mediatek.com> ? 2022?1?19? ?? ??10:26???
>
> Some DSI RX devices (for example, anx7625) require last alignment of
> packets on all lanes after each row of data is sent.
> Otherwise, there will be some issues of shift or scroll for screen.
>
> Take horizontal_sync_active_byte for a example,
> we roundup the HSA packet data to lane number, and the subtraction of 2
> is the packet data value added by the roundup operation, making the
> long packets are integer multiples of lane number.
> This value (2) varies with the lane number, and that is the reason we
> do this operation when the lane number is 4.
>
> In the previous operation of function "mtk_dsi_config_vdo_timing",
> the length of HSA and HFP data packets has been adjusted to an
> integration multiple of lane number.
> Since the number of RGB data packets cannot be guaranteed to be an
> integer multiple of lane number, we modify the data packet length of
> HBP so that the number of HBP + RGB is equal to the lane number.
> So after sending a line of data (HSA + HBP + RGB + HFP), the data
> lanes are aligned.

Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..e91b3fff4342 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -500,6 +500,18 @@ static void mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
>                 DRM_WARN("HFP + HBP less than d-phy, FPS will under 60Hz\n");
>         }
>
> +       if ((dsi->mode_flags & MIPI_DSI_HS_PKT_END_ALIGNED) &&
> +           (dsi->lanes == 4)) {
> +               horizontal_sync_active_byte =
> +                       roundup(horizontal_sync_active_byte, dsi->lanes) - 2;
> +               horizontal_frontporch_byte =
> +                       roundup(horizontal_frontporch_byte, dsi->lanes) - 2;
> +               horizontal_backporch_byte =
> +                       roundup(horizontal_backporch_byte, dsi->lanes) - 2;
> +               horizontal_backporch_byte -=
> +                       (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
> +       }
> +
>         writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
>         writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
>         writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
> --
> 2.18.0
>


From pali at kernel.org  Wed Jan 19 16:06:51 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 01:06:51 +0100
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <20220119231655.EFFF3C004E1@smtp.kernel.org>
References: <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015090937.gnt66hgugrhwnkei@pali>
 <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali>
 <20220115130509.4a240730@thinkpad>
 <20220115122618.plhiqnjh2755bv5h@pali>
 <20220119231655.EFFF3C004E1@smtp.kernel.org>
Message-ID: <20220120000651.in7s6nazif5qjkme@pali>

On Wednesday 19 January 2022 15:16:54 Stephen Boyd wrote:
> Quoting Pali Roh?r (2022-01-15 04:26:18)
> > On Saturday 15 January 2022 13:05:09 Marek Beh?n wrote:
> > > On Sat, 15 Jan 2022 12:50:18 +0100
> > > Pali Roh?r <pali at kernel.org> wrote:
> > > 
> > > > On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > > > > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > > > > 
> > > > > > If I was designing this driver and DTS bindings I would have choose
> > > > > > something like this:
> > > > > > 
> > > > > > uart at 0x12000 {  
> > > > > 
> > > > > Drop the 0x
> > > > >   
> > > > > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > > > > >     clock-controller {
> > > > > >         ...
> > > > > >     };  
> > > > > 
> > > > > Drop this node and put whatever properties are inside into the parent
> > > > > node.
> > > > >   
> > > > > >     serial1 {
> > > > > >         ...
> > > > > >         status = "disabled";
> > > > > >     };
> > > > > >     serial2 {
> > > > > >         ...
> > > > > >         status = "disabled";
> > > > > >     };
> > > > > > };
> > > > > > 
> > > > > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > > > > defined in top level nodes and would be handled by one driver.
> > > > > > 
> > > > > > This is really how hardware block looks like. But it is not backward
> > > > > > compatible...  
> > > > > 
> > > > > Sounds good to me. I presume we need the serial child nodes so we can
> > > > > reference them from the stdout-path?  
> > > > 
> > > > Yes, exactly, separate nodes for serial1 and serial2 are still required.
> > > > 
> > > > But dropping clock controller is not possible as for higher baudrates we
> > > > need to use and configure uart clock controller. Without it we just get
> > > > comparable feature support which is already present in driver.
> > > 
> > > What Stephen means is making clock controller out of the uart node
> > > directly. No need to add separate subnode just for clock controller.
> > 
> > This is already implemented in v7 patch series. Clock controller is
> > already outside of uart nodes.
> 
> I mean to combine the uart node and the clock-controller node together
> 
> 	uart-wrapper {
> 		reg = <0x12000 0x18>, <0x12200 0x30>;
> 		#clock-cells ...
> 
> 		serial1 {
> 			...
> 		};
> 
> 		serial2 {
> 			...
> 		};
> 	};

Ok, now I see what you mean.

But problem is that this is not backward compatible change. And would
not work per existing DT bindings definitions, which defines how
bootloader should set configured clocks.

As I wrote in emails 3 months ago, this new "proposed" DTS definition is
something which I would have chosen if I had designed this driver and
bindings in past. But that did not happen and different approach is
already widely in used.

To support existing DTS definitions and bootloaders, it is really
required to have current structure backward compatible like it is
defined in current DT bindings document. And my changes in this patch
series are backward compatible.

To change DTS structure, it would be needed to provide uart nodes in DTS
files two times: once in old style (the current one) and second time in
this new style.

But such thing would even more complicate updating driver and it needs
to be implemented.

Plus this would open a question how to define default stdout-path if
there would be 4 serial nodes, where one pair would describe old style
and second pair new style; meaning that 2 cross nodes would describe
same define.

For me this looks like a more complications and I do not see any benefit
from it.

It is really important to break backward compatibility, just to try
having new cleaner API at the cost of having more complications and
requirement for more development and also important maintenance?


From seanjc at google.com  Wed Jan 19 16:27:16 2022
From: seanjc at google.com (Sean Christopherson)
Date: Thu, 20 Jan 2022 00:27:16 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <CAAeT=FyJAG1dEFLvrQ4UXrwUqBUhY0AKkjzFpyi74zCJZUEYVg@mail.gmail.com>
References: <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
 <YedWUJNnQK3HFrWC@google.com>
 <CAAeT=FyJAG1dEFLvrQ4UXrwUqBUhY0AKkjzFpyi74zCJZUEYVg@mail.gmail.com>
Message-ID: <YeisZCJedWYJPLV5@google.com>

On Tue, Jan 18, 2022, Reiji Watanabe wrote:
> On Tue, Jan 18, 2022 at 4:07 PM Sean Christopherson <seanjc at google.com> wrote:
> >
> > On Fri, Jan 14, 2022, Reiji Watanabe wrote:
> > > The restriction, with which KVM doesn't need to worry about the changes
> > > in the registers after KVM_RUN, could potentially protect or be useful
> > > to protect KVM and simplify future changes/maintenance of the KVM codes
> > > that consumes the values.
> >
> > That sort of protection is definitely welcome, the previously mentioned CPUID mess
> > on x86 would have benefit greatly by KVM being restrictive in the past.  That said,
> > hooking KVM_RUN is likely the wrong way to go about implementing any restrictions.
> > Running a vCPU is where much of the vCPU's state is explicitly consumed, but it's
> > all too easy for KVM to implicity/indirectly consume state via a different ioctl(),
> > e.g. if there are side effects that are visible in other registers, than an update
> > can also be visible to userspace via KVM_{G,S}ET_{S,}REGS, at which point disallowing
> > modifying state after KVM_RUN but not after reading/writing regs is arbitrary and
> > inconsitent.
> 
> Thank you for your comments !
> I think I understand your concern, and that's a great point.
> That's not the case for those pseudo registers though at least for now :)
> BTW, is this concern specific to hooking KVM_RUN ? (Wouldn't it be the
> same for the option with "if kvm->created_vcpus > 0" ?)

Not really?  The goal with created_vcpus is to avoid having inconsistent state in
"struct kvm_vcpu" with respect to the VM as whole.  "struct kvm" obvioulsy can't
be inconsistent with itself, e.g. even if userspace consumes some side effect,
that's simply "the state".  Did that make sense?  Hard to explain in writing :-)

> > If possible, preventing modification if kvm->created_vcpus > 0 is ideal as it's
> > a relatively common pattern in KVM, and provides a clear boundary to userpace
> > regarding what is/isn't allowed.
> 
> Yes, I agree that would be better in general.  For (pseudo) registers,

What exactly are these pseudo registers?  If it's something that's an immutable
property of the (virtual) system, then it might make sense to use a separate,
non-vCPU mechanism for setting/getting their values.  Then you can easily restrict
the <whatever> to pre-created_vcpus, e.g. see x86's KVM_SET_IDENTITY_MAP_ADDR.

> I would think preventing modification if kvm->created_vcpus > 0 might
> not be a very good option for KVM/ARM though considering usage of
> KVM_GET_REG_LIST and KVM_{G,S}ET_ONE_REG.


From robert.hancock at calian.com  Wed Jan 19 17:02:42 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 19 Jan 2022 19:02:42 -0600
Subject: [PATCH 0/4] Xilinx AMS fixes
Message-ID: <20220120010246.3794962-1-robert.hancock@calian.com>

Various fixes for the Xilinx AMS driver, and addition of the required
references in the ZynqMP device tree files to use it.

Robert Hancock (4):
  arm64: dts: zynqmp: add AMS driver to device tree
  iio: adc: xilinx-ams: Fixed missing PS channels
  iio: adc: xilinx-ams: Fixed wrong sequencer register settings
  iio: adc: xilinx-ams: Fix single channel switching sequence

 .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 26 +++++++++++++++++++
 drivers/iio/adc/xilinx-ams.c                  | 15 ++++++++---
 3 files changed, 41 insertions(+), 4 deletions(-)

-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 19 17:02:45 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 19 Jan 2022 19:02:45 -0600
Subject: [PATCH 3/4] iio: adc: xilinx-ams: Fixed wrong sequencer register
 settings
In-Reply-To: <20220120010246.3794962-1-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
Message-ID: <20220120010246.3794962-4-robert.hancock@calian.com>

Register settings used for the sequencer configuration register
were incorrect, causing some inputs to not be read properly.

Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/iio/adc/xilinx-ams.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index b93864362dac..199027c93cdc 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -91,8 +91,8 @@
 
 #define AMS_CONF1_SEQ_MASK		GENMASK(15, 12)
 #define AMS_CONF1_SEQ_DEFAULT		FIELD_PREP(AMS_CONF1_SEQ_MASK, 0)
-#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 1)
-#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
+#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
+#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK, 3)
 
 #define AMS_REG_SEQ0_MASK		GENMASK(15, 0)
 #define AMS_REG_SEQ2_MASK		GENMASK(21, 16)
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 19 17:02:44 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 19 Jan 2022 19:02:44 -0600
Subject: [PATCH 2/4] iio: adc: xilinx-ams: Fixed missing PS channels
In-Reply-To: <20220120010246.3794962-1-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
Message-ID: <20220120010246.3794962-3-robert.hancock@calian.com>

The code forgot to increment num_channels for the PS channel inputs,
resulting in them not being enabled as they should.

Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/iio/adc/xilinx-ams.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 8343c5f74121..b93864362dac 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
 
 		/* add PS channels to iio device channels */
 		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
+		num_channels = ARRAY_SIZE(ams_ps_channels);
 	} else if (fwnode_property_match_string(fwnode, "compatible",
 						"xlnx,zynqmp-ams-pl") == 0) {
 		ams->pl_base = fwnode_iomap(fwnode, 0);
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 19 17:02:43 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 19 Jan 2022 19:02:43 -0600
Subject: [PATCH 1/4] arm64: dts: zynqmp: add AMS driver to device tree
In-Reply-To: <20220120010246.3794962-1-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
Message-ID: <20220120010246.3794962-2-robert.hancock@calian.com>

Add an entry to the ZynqMP device tree to support the AMS device which
now has a driver in mainline.

Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +++
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 26 +++++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
index 1e0b1bca7c94..108592104a1b 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -239,6 +239,10 @@ &lpd_watchdog {
 	clocks = <&zynqmp_clk LPD_WDT>;
 };
 
+&xilinx_ams {
+	clocks = <&zynqmp_clk AMS_REF>;
+};
+
 &zynqmp_dpdma {
 	clocks = <&zynqmp_clk DPDMA_REF>;
 };
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 74e66443e4ce..d1fe1e5b46c1 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -878,6 +878,32 @@ lpd_watchdog: watchdog at ff150000 {
 			timeout-sec = <10>;
 		};
 
+		xilinx_ams: ams at ffa50000 {
+			compatible = "xlnx,zynqmp-ams";
+			status = "disabled";
+			interrupt-parent = <&gic>;
+			interrupts = <0 56 4>;
+			reg = <0x0 0xffa50000 0x0 0x800>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			#io-channel-cells = <1>;
+			ranges = <0 0 0xffa50800 0x800>;
+
+			ams_ps: ams_ps at 0 {
+				compatible = "xlnx,zynqmp-ams-ps";
+				status = "disabled";
+				reg = <0x0 0x400>;
+			};
+
+			ams_pl: ams_pl at 400 {
+				compatible = "xlnx,zynqmp-ams-pl";
+				status = "disabled";
+				reg = <0x400 0x400>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
 		zynqmp_dpdma: dma-controller at fd4c0000 {
 			compatible = "xlnx,zynqmp-dpdma";
 			status = "disabled";
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 19 17:02:46 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Wed, 19 Jan 2022 19:02:46 -0600
Subject: [PATCH 4/4] iio: adc: xilinx-ams: Fix single channel switching
 sequence
In-Reply-To: <20220120010246.3794962-1-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
Message-ID: <20220120010246.3794962-5-robert.hancock@calian.com>

Some of the AMS channels need to be read by switching into single-channel
mode from the normal polling sequence. There was a logic issue in this
switching code that could cause the first read of these channels to read
back as zero.

It appears that the sequencer should be set back to default mode before
changing the channel selection, and the channel should be set before
switching the sequencer back into single-channel mode.

Also, write 1 to the EOC bit in the status register to clear it before
waiting for it to become set, so that we actually wait for a new
conversion to complete, and don't proceed based on a previous conversion
completing.

Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/iio/adc/xilinx-ams.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
index 199027c93cdc..7bf097fa10cb 100644
--- a/drivers/iio/adc/xilinx-ams.c
+++ b/drivers/iio/adc/xilinx-ams.c
@@ -530,14 +530,18 @@ static int ams_enable_single_channel(struct ams *ams, unsigned int offset)
 		return -EINVAL;
 	}
 
-	/* set single channel, sequencer off mode */
+	/* put sysmon in a soft reset to change the sequence */
 	ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK,
-			  AMS_CONF1_SEQ_SINGLE_CHANNEL);
+			  AMS_CONF1_SEQ_DEFAULT);
 
 	/* write the channel number */
 	ams_ps_update_reg(ams, AMS_REG_CONFIG0, AMS_CONF0_CHANNEL_NUM_MASK,
 			  channel_num);
 
+	/* set single channel, sequencer off mode */
+	ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK,
+			  AMS_CONF1_SEQ_SINGLE_CHANNEL);
+
 	return 0;
 }
 
@@ -551,6 +555,8 @@ static int ams_read_vcc_reg(struct ams *ams, unsigned int offset, u32 *data)
 	if (ret)
 		return ret;
 
+	/* clear end-of-conversion flag, wait for next conversion to complete */
+	writel(expect, ams->base + AMS_ISR_1);
 	ret = readl_poll_timeout(ams->base + AMS_ISR_1, reg, (reg & expect),
 				 AMS_INIT_POLL_TIME_US, AMS_INIT_TIMEOUT_US);
 	if (ret)
-- 
2.31.1



From robert.hancock at calian.com  Wed Jan 19 17:09:39 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Thu, 20 Jan 2022 01:09:39 +0000
Subject: [PATCH 2/4] iio: adc: xilinx-ams: Fixed missing PS channels
In-Reply-To: <20220120010246.3794962-3-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-3-robert.hancock@calian.com>
Message-ID: <c615acdc4f0a818e070705e1f3f5d82660fb4c8a.camel@calian.com>

On Wed, 2022-01-19 at 19:02 -0600, Robert Hancock wrote:
> The code forgot to increment num_channels for the PS channel inputs,
> resulting in them not being enabled as they should.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>  drivers/iio/adc/xilinx-ams.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index 8343c5f74121..b93864362dac 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
>  
>  		/* add PS channels to iio device channels */
>  		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
> +		num_channels = ARRAY_SIZE(ams_ps_channels);
>  	} else if (fwnode_property_match_string(fwnode, "compatible",
>  						"xlnx,zynqmp-ams-pl") == 0) {
>  		ams->pl_base = fwnode_iomap(fwnode, 0);

Looks like this is the same change just submitted by Michael Tretter ("iio:
adc: xilinx-ams: Fix num_channels for PS channels").

-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From itaru.kitayama at gmail.com  Wed Jan 19 17:26:50 2022
From: itaru.kitayama at gmail.com (Itaru Kitayama)
Date: Thu, 20 Jan 2022 10:26:50 +0900
Subject: My subscription is often disabled
Message-ID: <CANW9uysYVmMujd8a6X3E23x0rZGWn3smG4AEtzHEK9_bbN5xdA@mail.gmail.com>

I am subscribed to the Linux ARM Kernel mailing list using GMail, but
my subscription often
gets disabled periodically say every three months or less. Is this
what others using GMail experiencing?

Itaru.


From guodong.liu at mediatek.com  Wed Jan 19 17:22:33 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Thu, 20 Jan 2022 09:22:33 +0800
Subject: [SPAM]Re: [PATCH v1 2/2] iio: adc: mt8186: Add compatible node
 for mt8186
In-Reply-To: <20220115150208.15fb6284@jic23-huawei>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
 <20220110084841.575-2-guodong.liu@mediatek.com>
 <292950d7-d057-4e66-5d0d-a5144f50f2ce@collabora.com>
 <20220115150208.15fb6284@jic23-huawei>
Message-ID: <0572e542b1a07db852c4af62d71b89ed19a1eb3b.camel@mediatek.com>

-----Original Message-----
From: Jonathan Cameron <jic23 at jic23.retrosnub.co.uk>
To: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com
>
Cc: Guodong Liu <guodong.liu at mediatek.com>, Lars-Peter Clausen <
lars at metafoo.de>, Rob Herring <robh+dt at kernel.org>, Matthias Brugger <
matthias.bgg at gmail.com>, Zhiyong Tao <zhiyong.tao at mediatek.com>, 
linux-iio at vger.kernel.org, devicetree at vger.kernel.org, 
linux-kernel at vger.kernel.org, linux-arm-kernel at lists.infradead.org, 
linux-mediatek at lists.infradead.org, 
Project_Global_Chrome_Upstream_Group at mediatek.com
Subject: [SPAM]Re: [PATCH v1 2/2] iio: adc: mt8186: Add compatible node
for mt8186
Date: Sat, 15 Jan 2022 15:02:08 +0000

On Mon, 10 Jan 2022 11:01:28 +0100
AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
wrote:

> Il 10/01/22 09:48, Guodong Liu ha scritto:
> > This commit adds mt8186 compatible node.
> > 
> > Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>  
> 
> Acked-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>

Applied with a slight tweak to patch 2 as an earlier tidyup added
a bracket before the } in the table so make this line match as well.

Applied to the togreg branch of iio.git and pushed out as testing for
0-day to poke at it for us.  I'll be rebasing the tree after rc1 is
out.

Thanks,
Jonathan


Hi Jonathan

Thanks for you help.

Thanks,
Guodong

> 
> > ---
> >   drivers/iio/adc/mt6577_auxadc.c | 6 ++++++
> >   1 file changed, 6 insertions(+)
> > 
> > diff --git a/drivers/iio/adc/mt6577_auxadc.c
> > b/drivers/iio/adc/mt6577_auxadc.c
> > index d4fccd52ef08..fb08d761589a 100644
> > --- a/drivers/iio/adc/mt6577_auxadc.c
> > +++ b/drivers/iio/adc/mt6577_auxadc.c
> > @@ -46,6 +46,11 @@ struct mt6577_auxadc_device {
> >   	const struct mtk_auxadc_compatible *dev_comp;
> >   };
> >   
> > +static const struct mtk_auxadc_compatible mt8186_compat = {
> > +	.sample_data_cali = false,
> > +	.check_global_idle = false,
> > +};
> > +
> >   static const struct mtk_auxadc_compatible mt8173_compat = {
> >   	.sample_data_cali = false,
> >   	.check_global_idle = true,
> > @@ -334,6 +339,7 @@ static const struct of_device_id
> > mt6577_auxadc_of_match[] = {
> >   	{ .compatible = "mediatek,mt2712-auxadc", .data =
> > &mt8173_compat},
> >   	{ .compatible = "mediatek,mt7622-auxadc", .data =
> > &mt8173_compat},
> >   	{ .compatible = "mediatek,mt8173-auxadc", .data =
> > &mt8173_compat},
> > +	{ .compatible = "mediatek,mt8186-auxadc", .data =
> > &mt8186_compat},
> >   	{ .compatible = "mediatek,mt6765-auxadc", .data =
> > &mt6765_compat},
> >   	{ }
> >   };
> >   



From guodong.liu at mediatek.com  Wed Jan 19 17:47:00 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Thu, 20 Jan 2022 09:47:00 +0800
Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix
 PIN_CONFIG_BIAS_DISABLE readback
In-Reply-To: <CAGXv+5GHVtCO9tN7B0O2c5V_Bk61-LL79LvbE1CRbyBfnvKSGQ@mail.gmail.com>
References: <20220111112244.1483783-1-wenst@chromium.org>
 <20220111112244.1483783-3-wenst@chromium.org>
 <eca4a0c18fe75536c8276410628b9459c040dce2.camel@mediatek.com>
 <CAGXv+5GHVtCO9tN7B0O2c5V_Bk61-LL79LvbE1CRbyBfnvKSGQ@mail.gmail.com>
Message-ID: <883391d5642d217e79fb09bebd81f9b5027ce20a.camel@mediatek.com>

-----Original Message-----
From: Chen-Yu Tsai <wenst at chromium.org>
To: Guodong Liu <guodong.liu at mediatek.com>
Cc: Sean Wang <sean.wang at kernel.org>, Linus Walleij <
linus.walleij at linaro.org>, Matthias Brugger <matthias.bgg at gmail.com>, 
linux-mediatek at lists.infradead.org, linux-gpio at vger.kernel.org, 
linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
Zhiyong Tao <zhiyong.tao at mediatek.com>, Hui Liu <hui.liu at mediatek.com>,
Light Hsieh <light.hsieh at mediatek.com>
Subject: Re: [PATCH 2/7] pinctrl: mediatek: paris: Fix
PIN_CONFIG_BIAS_DISABLE readback
Date: Wed, 19 Jan 2022 13:57:18 +0800

On Wed, Jan 19, 2022 at 9:42 AM Guodong Liu <guodong.liu at mediatek.com>
wrote:
> 
> -----Original Message-----
> From: Chen-Yu Tsai <wenst at chromium.org>
> To: Sean Wang <sean.wang at kernel.org>, Linus Walleij <
> linus.walleij at linaro.org>, Matthias Brugger <matthias.bgg at gmail.com>
> Cc: Chen-Yu Tsai <wenst at chromium.org>,
> linux-mediatek at lists.infradead.org, linux-gpio at vger.kernel.org,
> linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org,
> Zhiyong Tao <zhiyong.tao at mediatek.com>, Guodong Liu <
> guodong.liu at mediatek.com>
> Subject: [PATCH 2/7] pinctrl: mediatek: paris: Fix
> PIN_CONFIG_BIAS_DISABLE readback
> Date: Tue, 11 Jan 2022 19:22:39 +0800
> 
> When reading back pin bias settings, if the pin is not in a
> bias-disabled state, the function should return -EINVAL.
> 
> Fix this in the mediatek-paris pinctrl library so that the read back
> state is not littered with bogus a "input bias disabled" combined
> with
> "pull up" or "pull down" states.
> 
> Fixes: 805250982bb5 ("pinctrl: mediatek: add pinctrl-paris that
> implements the vendor dt-bindings")
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/pinctrl/mediatek/pinctrl-paris.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pinctrl/mediatek/pinctrl-paris.c
> b/drivers/pinctrl/mediatek/pinctrl-paris.c
> index f9f9110f2107..1ca598ea7ba7 100644
> --- a/drivers/pinctrl/mediatek/pinctrl-paris.c
> +++ b/drivers/pinctrl/mediatek/pinctrl-paris.c
> @@ -97,8 +97,8 @@ static int mtk_pinconf_get(struct pinctrl_dev
> *pctldev,
>                         if (err)
>                                 goto out;
>                         if (param == PIN_CONFIG_BIAS_DISABLE) {
> -                               if (ret == MTK_PUPD_SET_R1R0_00)
> -                                       ret = MTK_DISABLE;
> +                               if (ret != MTK_PUPD_SET_R1R0_00)
> +                                       err = -EINVAL;
> Hi Chen-Yu
> 
> When the API "hw->soc->bias_get_combo(hw, desc, &pullup, &ret)" is
> called,
> The ret vaule of ret may be MTK_DISABLE or MTK_PUPD_SET_R1R0_00
> or  (pullen
> == 0),  All those cases are expected to be as "bias-disable".
> We advices to keep original code,
> +                               if (ret == MTK_PUPD_SET_R1R0_00)
> +                                       ret = MTK_DISABLE;
> +                               if (ret != MTK_DISABLE)
> +                                       err = -EINVAL;

IIUC you are suggesting to assign MTK_DISABLE to ret in the other two
cases,
and then check if ret == MTK_DISABLE.

Thanks for pointing that out.

ChenYu

> Thanks

Hi Chen-Yu

Yes, just for pins with config of MTK_PUPD_SET_R1R0_00 are required to
do additional assignment operations(ret = MTK_DISABLE;), in the other
two cases, the assignment operations of ret as MTK_DISABLE is obtained
by function call "hw->soc->bias_get_combo(hw, desc, &pullup, &ret)".

Thanks

>                         } else if (param == PIN_CONFIG_BIAS_PULL_UP)
> {
>                                 /* When desire to get pull-up value,
> return
>                                  *  error if current setting is pull-
> down
> 

From gustavoars at kernel.org  Wed Jan 19 17:55:46 2022
From: gustavoars at kernel.org (Gustavo A. R. Silva)
Date: Wed, 19 Jan 2022 19:55:46 -0600
Subject: [PATCH][next] usb: xhci-mtk: Use struct_size() helper in
 create_sch_ep()
Message-ID: <20220120015546.GA75917@embeddedor>

Make use of the struct_size() helper instead of an open-coded version,
in order to avoid any potential type mistakes or integer overflows that,
in the worst scenario, could lead to heap overflows.

Also, address the following sparse warnings:
drivers/usb/host/xhci-mtk-sch.c:265:20: warning: using sizeof on a flexible structure

Link: https://github.com/KSPP/linux/issues/160
Link: https://github.com/KSPP/linux/issues/174
Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
---
 drivers/usb/host/xhci-mtk-sch.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c
index edbfa82c6565..f3139ce7b0a9 100644
--- a/drivers/usb/host/xhci-mtk-sch.c
+++ b/drivers/usb/host/xhci-mtk-sch.c
@@ -248,7 +248,6 @@ create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	struct mu3h_sch_bw_info *bw_info;
 	struct mu3h_sch_tt *tt = NULL;
 	u32 len_bw_budget_table;
-	size_t mem_size;
 
 	bw_info = get_bw_info(mtk, udev, ep);
 	if (!bw_info)
@@ -262,9 +261,9 @@ create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev,
 	else
 		len_bw_budget_table = 1;
 
-	mem_size = sizeof(struct mu3h_sch_ep_info) +
-			len_bw_budget_table * sizeof(u32);
-	sch_ep = kzalloc(mem_size, GFP_KERNEL);
+	sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table,
+				     len_bw_budget_table),
+			 GFP_KERNEL);
 	if (!sch_ep)
 		return ERR_PTR(-ENOMEM);
 
-- 
2.27.0



From xueshuai at linux.alibaba.com  Wed Jan 19 18:40:30 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 20 Jan 2022 10:40:30 +0800
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <20220119204259.GA962224@bhelgaas>
References: <20220119204259.GA962224@bhelgaas>
Message-ID: <28d484ac-23e2-698b-762b-cd0c8b220570@linux.alibaba.com>

Hi, Bjorn,

Thank you for your valuable comments.

? 2022/1/20 AM4:42, Bjorn Helgaas ??:
> On Wed, Jan 19, 2022 at 02:40:11PM +0800, Shuai Xue wrote:
>> [+to Rafael, question about HEST/GHES/SDEI init]
>>
>> Hi, Bjorn,
>>
>> Thank you for your comments and quick reply.
>>
>> ? 2022/1/19 AM6:49, Bjorn Helgaas ??:
>>> On Sun, Jan 16, 2022 at 04:43:10PM +0800, Shuai Xue wrote:
>>>> On an ACPI system, ACPI is initialised very early from a
>>>> subsys_initcall(), while SDEI is not ready until a
>>>> subsys_initcall_sync(). This patch is to reduce the time before GHES
>>>> initialization.
>>>>
>>>> The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
>>>> apei_sdei_unregister_ghes()) to register or unregister event callback
>>>> for dispatcher in firmware. When the GHES driver probing, it registers
>>>> the corresponding callback according to the notification type specified
>>>> by GHES. If the GHES notification type is SDEI, the GHES driver will
>>>> call apei_sdei_register_ghes() to register event call.
>>>>
>>>> When the firmware emits an event, it migrates the handling of the event
>>>> into the kernel at the registered entry-point __sdei_asm_handler. And
>>>> finally, the kernel will call the registered event callback and return
>>>> status_code to indicate the status of event handling. SDEI_EV_FAILED
>>>> indicates that the kernel failed to handle the event.
>>>>
>>>> Consequently, when an error occurs during kernel booting, the kernel is
>>>> unable to handle and report errors until the GHES driver is initialized
>>>> by device_initcall(), in which the event callback is registered.  For
>>>> example, when the kernel booting, the console logs many times from
>>>> firmware before GHES drivers init in our platform:
>>>>
>>>> 	Trip in MM PCIe RAS handle(Intr:910)
>>>>   	Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
>>>> 	Find RP(98:1.0)
>>>> 	--Walk dev(98:1.0) CE:0 UCE:4000
>>>> 	...
>>>> 	ERROR:   sdei_dispatch_event(32a) ret:-1
>>>> 	--handler(910) end
>>>
>>> If I understand correctly, the firmware noticed an error, tried to
>>> report it to the kernel, and is complaining because the kernel isn't
>>> ready to handle it yet.  And the reason for this patch is to reduce
>>> these complaints from the firmware.
>>
>> My thoughts exactly :)
>>
>>> That doesn't seem like a very good reason for this patch.  There is
>>> *always* a window before the kernel is ready to handle events from the
>>> firmware.
>>
>> Yes, there is always a window. But if we could do better in kernel that
>> reduces the window by 90% (from 33 seconds to 3 second), why not?
>>
>>> Why is the firmware noticing these errors in the first place?  If
>>> you're seeing these complaints regularly, my guess is that either you
>>> have some terrible hardware or (more likely) the firmware isn't
>>> clearing some expected error condition correctly.  For example, maybe
>>> the Unsupported Request errors that happen while enumerating PCIe
>>> devices are being reported.
>>>
>>> If you register the callback function, the kernel will now start
>>> seeing these error reports.  What happens then?  Does the kernel log
>>> the errors somewhere?  Is that better than the current situation where
>>> the firmware logs them?
>>
>> Yep, it is a hardware issue. The firmware only logs in console
>> (ttyAMA0) and we can not see it in kernel side. After the kernel
>> starts seeing these error reports, we could see EDAC/ghes and
>> efi/cper detailed logs in dmesg. We did not notice the problem until
>> we check the console log, which inspired us to reduce the window
>> when kernel startup, so that we can see the message clearly and
>> properly. I think the intuition is to check the log of dmesg, not
>> the console.
> 
>>> However, I DO think that:
>>>
>>>   - Removing acpi_hest_init() from acpi_pci_root_init(), and
>>>
>>>   - Converting ghes_init() and sdei_init() from initcalls to explicit
>>>     calls
>>>
>>> are very good reasons to do something like this patch because HEST is
>>> not PCI-specific, and IMO, explicit calls are better than initcalls
>>> because initcall ordering is implicit and not well-defined within a
>>> level.
>>
>> Haha, if the above reasons still don't convince you, I would like to
>> accept yours :) Should we do it in one patch or separate it into two
>> patches?
> 
> IMO, this can be done in one patch, but this would probably go via
> Rafael.

Got it, I will send a new patch and cc to Rafael.

>>>> -static int __init ghes_init(void)
>>>> +void __init ghes_init(void)
>>>>  {
>>>>  	int rc;
>>>>  
>>>>  	if (acpi_disabled)
>>>> -		return -ENODEV;
>>>> +		return;
>>>>  
>>>>  	switch (hest_disable) {
>>>>  	case HEST_NOT_FOUND:
>>>> -		return -ENODEV;
>>>> +		pr_info(GHES_PFX "HEST is not found!\n");
>>>
>>> I don't know whether this "HEST is not found" message is
>>> worthwhile or not.  I don't think lack of an HEST is an error, and
>>> users may be alarmed.  But this is an ACPI thing, so up to you and
>>> Rafael.
>>
>> If we explicit call ghes_init(), we can't tell if ghes is
>> initialized successfully based on the return value of initcall. So I
>> add a info message.
> 
> When ghes_init() is an initcall and you return -ENODEV for the
> HEST_NOT_FOUND case, I don't think we log any message about that, do
> we?  do_one_initcall() will capture and return the -ENODEV, but the
> caller (do_initcall_level()) just ignores it.

I see, thank you. I will delete it in next version.

>>>> @@ -1495,8 +1494,7 @@ static int __init ghes_init(void)
>>>>  	else
>>>>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
>>>>  
>>>> -	return 0;
>>>> +	return;
>>>>  err:
>>>> -	return rc;
>>>> +	ghes_disable = 1;
>>>
>>> Why do you set ghes_disable here?  As far as I can tell, we will never
>>> look at it again.  The places we do look at it are:
>>>
>>>   - ghes_init(): earlier in this function, so we've already done that,
>>>
>>>   - acpi_hest_init(): we've already called that, too, and
>>>
>>>   - acpi_bus_osc_negotiate_platform_control(): called from
>>>     acpi_bus_init(), which we've already called.
>>
>> I add it for future potential usage. Thank you for pointing it out.
>> If you think it is not necessary, I will delete it in next version.
> 
> I think it is not necessary to save information that will never be
> used.  If you need it in the future, you can add it and the reason
> will be obvious.
> 
> Bjorn

You are right. I will delete it.

Best Regards,
Shuai




From ilkka at os.amperecomputing.com  Wed Jan 19 18:57:57 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Wed, 19 Jan 2022 18:57:57 -0800
Subject: [PATCH v4 0/2] ACPI: Arm Generic Diagnostic Dump and Reset device
Message-ID: <20220120025759.8630-1-ilkka@os.amperecomputing.com>

Arm Generic Diagnostic Dump and Reset device enables a maintainer to
request OS to perform a diagnostic dump and reset a system via SDEI
event or an interrupt. This patchset adds support for the SDEI path.

I do have a patch to enable the interrupt path as well but I'm holding
it back since AGDI table is missing interrupt configuration fields
(trigger type etc.).

The recently published specification is available at
https://developer.arm.com/documentation/den0093/latest

The patchset was tested on Ampere Altra/Mt. Jade.

The patchset applies on top of
  git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm bleeding-edge (fc720b592cc6)


>From v1:
     * Moved pdata to the stack and dropped unnecessary kzalloc() in agdi_init()
     * Changed the ACPICA patch upstreaming order comment in the paragraph above

>From v2:
     * The first patch was split. The most of it was merged to ACPICA project
       at first and later ported to linux-acpi
       (fd919e37cb15914c6fe13e13d530a4f732407c6d). The rest are in the first
       patch.

>From v3:
     Fixed:
	* Moved header files in alphabetical order and removed unnecessary ones

     Not addressed:
 	* agdi_init() is still called from device_initcall() as it has to be
	  done after sdei_init()
	  (http://lists.infradead.org/pipermail/linux-arm-kernel/2022-January/709969.html)

	  Can be moved to acpi_init(), after Shuai Xue's patch get's approved
	  (http://lists.infradead.org/pipermail/linux-arm-kernel/2022-January/710268.html)


Ilkka Koskinen (2):
  ACPI: tables: Add AGDI to the list of known table signatures
  ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump and Reset
    device

 drivers/acpi/arm64/Kconfig  |   8 +++
 drivers/acpi/arm64/Makefile |   1 +
 drivers/acpi/arm64/agdi.c   | 122 ++++++++++++++++++++++++++++++++++++
 drivers/acpi/tables.c       |   2 +-
 4 files changed, 132 insertions(+), 1 deletion(-)
 create mode 100644 drivers/acpi/arm64/agdi.c

-- 
2.17.1



From ilkka at os.amperecomputing.com  Wed Jan 19 18:57:58 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Wed, 19 Jan 2022 18:57:58 -0800
Subject: [PATCH v4 1/2] ACPI: tables: Add AGDI to the list of known table
 signatures
In-Reply-To: <20220120025759.8630-1-ilkka@os.amperecomputing.com>
References: <20220120025759.8630-1-ilkka@os.amperecomputing.com>
Message-ID: <20220120025759.8630-2-ilkka@os.amperecomputing.com>

Add AGDI to the list of known ACPI table signatures to allow the
kernel to recognize it when upgrading tables via initrd.

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/acpi/tables.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 682a3ea9cb40..973b466fa652 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -500,7 +500,7 @@ static const char table_sigs[][ACPI_NAMESEG_SIZE] __initconst = {
 	ACPI_SIG_WDDT, ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT,
 	ACPI_SIG_PSDT, ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT,
 	ACPI_SIG_IORT, ACPI_SIG_NFIT, ACPI_SIG_HMAT, ACPI_SIG_PPTT,
-	ACPI_SIG_NHLT, ACPI_SIG_AEST };
+	ACPI_SIG_NHLT, ACPI_SIG_AEST, ACPI_SIG_AGDI };
 
 #define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
 
-- 
2.17.1



From ilkka at os.amperecomputing.com  Wed Jan 19 18:57:59 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Wed, 19 Jan 2022 18:57:59 -0800
Subject: [PATCH v4 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump
 and Reset device
In-Reply-To: <20220120025759.8630-1-ilkka@os.amperecomputing.com>
References: <20220120025759.8630-1-ilkka@os.amperecomputing.com>
Message-ID: <20220120025759.8630-3-ilkka@os.amperecomputing.com>

ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
issue diagnostic dump and reset via an SDEI event or an interrupt.
This patch implements SDEI path.

[0] https://developer.arm.com/documentation/den0093/latest/

Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/acpi/arm64/Kconfig  |   8 +++
 drivers/acpi/arm64/Makefile |   1 +
 drivers/acpi/arm64/agdi.c   | 122 ++++++++++++++++++++++++++++++++++++
 3 files changed, 131 insertions(+)
 create mode 100644 drivers/acpi/arm64/agdi.c

diff --git a/drivers/acpi/arm64/Kconfig b/drivers/acpi/arm64/Kconfig
index 6dba187f4f2e..24869ba5b365 100644
--- a/drivers/acpi/arm64/Kconfig
+++ b/drivers/acpi/arm64/Kconfig
@@ -8,3 +8,11 @@ config ACPI_IORT
 
 config ACPI_GTDT
 	bool
+
+config ACPI_AGDI
+	bool "Arm Generic Diagnostic Dump and Reset Device Interface"
+	depends on ARM_SDE_INTERFACE
+	help
+	  Arm Generic Diagnostic Dump and Reset Device Interface (AGDI) is
+	  a standard that enables issuing a non-maskable diagnostic dump and
+	  reset command.
diff --git a/drivers/acpi/arm64/Makefile b/drivers/acpi/arm64/Makefile
index 66acbe77f46e..7b9e4045659d 100644
--- a/drivers/acpi/arm64/Makefile
+++ b/drivers/acpi/arm64/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_ACPI_AGDI) 	+= agdi.o
 obj-$(CONFIG_ACPI_IORT) 	+= iort.o
 obj-$(CONFIG_ACPI_GTDT) 	+= gtdt.o
 obj-y				+= dma.o
diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
new file mode 100644
index 000000000000..28f16b95ba12
--- /dev/null
+++ b/drivers/acpi/arm64/agdi.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file implements handling of
+ * Arm Generic Diagnostic Dump and Reset Interface table (AGDI)
+ *
+ * Copyright (c) 2022, Ampere Computing LLC
+ */
+
+#define pr_fmt(fmt) "ACPI: AGDI: " fmt
+
+#include <linux/acpi.h>
+#include <linux/arm_sdei.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+struct agdi_data {
+	int sdei_event;
+};
+
+static int agdi_sdei_handler(u32 sdei_event, struct pt_regs *regs, void *arg)
+{
+	nmi_panic(regs, "Arm Generic Diagnostic Dump and Reset SDEI event issued");
+	return 0;
+}
+
+static int agdi_sdei_probe(struct platform_device *pdev,
+			   struct agdi_data *adata)
+{
+	int err;
+
+	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
+			adata->sdei_event);
+		return err;
+	}
+
+	err = sdei_event_enable(adata->sdei_event);
+	if (err)  {
+		sdei_event_unregister(adata->sdei_event);
+		dev_err(&pdev->dev, "Failed to enable event %d\n",
+			adata->sdei_event);
+		return err;
+	}
+
+	return 0;
+}
+
+static int agdi_probe(struct platform_device *pdev)
+{
+	struct agdi_data *adata;
+
+	adata = dev_get_platdata(&pdev->dev);
+	if (!adata)
+		return -EINVAL;
+
+	return agdi_sdei_probe(pdev, adata);
+}
+
+static int agdi_remove(struct platform_device *pdev)
+{
+	struct agdi_data *adata = platform_get_drvdata(pdev);
+
+	sdei_event_disable(adata->sdei_event);
+	sdei_event_unregister(adata->sdei_event);
+
+	return 0;
+}
+
+static struct platform_driver agdi_driver = {
+	.driver = {
+		.name = "agdi",
+	},
+	.probe = agdi_probe,
+	.remove = agdi_remove,
+};
+
+static int __init agdi_init(void)
+{
+	int ret;
+	acpi_status status;
+	struct acpi_table_agdi *agdi_table;
+	struct agdi_data pdata;
+	struct platform_device *pdev;
+
+	if (acpi_disabled)
+		return 0;
+
+	status = acpi_get_table(ACPI_SIG_AGDI, 0,
+				(struct acpi_table_header **) &agdi_table);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	if (agdi_table->flags & ACPI_AGDI_SIGNALING_MODE) {
+		pr_warn("Interrupt signaling is not supported");
+		ret = -ENODEV;
+		goto err_put_table;
+	}
+
+	pdata.sdei_event = agdi_table->sdei_event;
+
+	pdev = platform_device_register_data(NULL, "agdi", 0, &pdata, sizeof(pdata));
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		goto err_put_table;
+	}
+
+	ret = platform_driver_register(&agdi_driver);
+	if (ret)
+		goto err_device_unregister;
+
+	acpi_put_table((struct acpi_table_header *)agdi_table);
+	return 0;
+
+err_device_unregister:
+	platform_device_unregister(pdev);
+err_put_table:
+	acpi_put_table((struct acpi_table_header *)agdi_table);
+	return ret;
+}
+device_initcall(agdi_init);
-- 
2.17.1



From victor.liu at nxp.com  Wed Jan 19 19:00:26 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Thu, 20 Jan 2022 11:00:26 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <c371d737fd5e7e19e966d7aec42da0c3edd9a556.camel@nxp.com>

Hi Heiko, Wyon,

On Wed, 2022-01-19 at 10:37 +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.
> 
> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)

[...]

> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);

For the Rockchip part, can you please give a test? Any comments?

We already have T-b tags on i.MX8mq and Meson platforms.

Regards,
Liu Ying

>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  



From sfr at canb.auug.org.au  Wed Jan 19 19:22:20 2022
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Thu, 20 Jan 2022 14:22:20 +1100
Subject: linux-next: build warning after merge of the arm-soc tree
In-Reply-To: <CACPK8XfS+Gy1dhL-_uWKhW1D4++6LdWM-SdXtnsEV15OUhiK1w@mail.gmail.com>
References: <20211026103939.136dc73b@canb.auug.org.au>
 <CACPK8XfS+Gy1dhL-_uWKhW1D4++6LdWM-SdXtnsEV15OUhiK1w@mail.gmail.com>
Message-ID: <20220120142220.1717e755@canb.auug.org.au>

Hi all,

On Tue, 26 Oct 2021 06:15:29 +0000 Joel Stanley <joel at jms.id.au> wrote:
>
> On Mon, 25 Oct 2021 at 23:39, Stephen Rothwell <sfr at canb.auug.org.au> wrote:
> >
> > After merging the arm-soc tree, today's linux-next build (htmldocs)
> > produced this warning:
> >
> > Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing:2: WARNING: Inline emphasis start-string without end-string.
> >
> > Introduced by commit
> >
> >   c6807970c3bc ("soc: aspeed: Add UART routing support")
> >
> > The problem is (probably) the '*'s on the previous line.  
> 
> Chai-Wei, are you able to send a fix for this issue?

I am still getting this warning.

-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220120/4b885a14/attachment.sig>

From lkp at intel.com  Wed Jan 19 19:27:42 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 20 Jan 2022 11:27:42 +0800
Subject: [xilinx-xlnx:master 248/360] ERROR: modpost:
 "dwc3_gadget_exit_hibernation" [drivers/usb/dwc3/dwc3.ko] undefined!
Message-ID: <202201200811.ALRs8uxb-lkp@intel.com>

tree:   https://github.com/Xilinx/linux-xlnx master
head:   dc405906cdb8a89cd81b6ca4f438fe213c187cb2
commit: 9b62852ec04b7d48971ce8016b13c27403929908 [248/360] Merge tag 'v5.15' into master
config: x86_64-randconfig-a006-20220117 (https://download.01.org/0day-ci/archive/20220120/202201200811.ALRs8uxb-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f7b7138a62648f4019c55e4671682af1f851f295)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/9b62852ec04b7d48971ce8016b13c27403929908
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout 9b62852ec04b7d48971ce8016b13c27403929908
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "dwc3_gadget_exit_hibernation" [drivers/usb/dwc3/dwc3.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From anshuman.khandual at arm.com  Wed Jan 19 19:37:11 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 20 Jan 2022 09:07:11 +0530
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <CAAH8bW_=KtrwLpg4tx+1tdMjN2mUiuLOoZH6nvbn8qNjU6aB3A@mail.gmail.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <Yedgj+Lo2eru8197@casper.infradead.org>
 <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>
 <CAAH8bW_=KtrwLpg4tx+1tdMjN2mUiuLOoZH6nvbn8qNjU6aB3A@mail.gmail.com>
Message-ID: <5b62ed03-8da8-a94d-cc48-a8cac1eae1c9@arm.com>



On 1/19/22 10:52 PM, Yury Norov wrote:
>> Why should not this just scan over the entire user provided struct page
>> array and make sure that all pages there in are valid via above method,
>> but in vmap() itself before calling vmap_pages_range(). Because seems
>> like a single invalid page detected in vmap_pages_pte_range() will
>> anyways abort the entire vmap(). This will also enable us to drop the
>> existing NULL check above.
>
> I can do this, but why is it any better than the current approach?

Because it will just return on the first instance where the valid page
check fails, saving us some CPU cycles and an incomplete mapping ?


From guangming.cao at mediatek.com  Wed Jan 19 19:34:50 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 20 Jan 2022 11:34:50 +0800
Subject: [PATCH v4] dma-buf: system_heap: Add a size check for allocation
In-Reply-To: <CALAqxLUtK8V9LgC-DY+tkzFYyWfzF+JhbrLZk6UhEG57HQBDSA@mail.gmail.com>
References: <CALAqxLUtK8V9LgC-DY+tkzFYyWfzF+JhbrLZk6UhEG57HQBDSA@mail.gmail.com>
Message-ID: <20220120033450.90164-1-guangming.cao@mediatek.com>

From: Guangming <Guangming.Cao at mediatek.com>

Add a size check for allocation since the allocation size should be
always less than the total DRAM size on system heap.
And it can prevent consuming too much time for invalid allocations.

Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/system_heap.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..bd6f255620e2 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -347,6 +347,13 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	struct page *page, *tmp_page;
 	int i, ret = -ENOMEM;
 
+	/*
+	 * Size check. The "len" should be less than totalram since system_heap
+	 * memory is comes from system. Adding check here can prevent consuming
+	 * too much time for invalid allocations.
+	 */
+	if (len >> PAGE_SHIFT > totalram_pages())
+		return -EINVAL;
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 	if (!buffer)
 		return ERR_PTR(-ENOMEM);
-- 
2.17.1



From john.stultz at linaro.org  Wed Jan 19 19:48:55 2022
From: john.stultz at linaro.org (John Stultz)
Date: Wed, 19 Jan 2022 19:48:55 -0800
Subject: [PATCH v4] dma-buf: system_heap: Add a size check for allocation
In-Reply-To: <20220120033450.90164-1-guangming.cao@mediatek.com>
References: <CALAqxLUtK8V9LgC-DY+tkzFYyWfzF+JhbrLZk6UhEG57HQBDSA@mail.gmail.com>
 <20220120033450.90164-1-guangming.cao@mediatek.com>
Message-ID: <CALAqxLW5uEZCGHGk3rYoiOGzN5XMKb39JzoPB1iEX9k3UsiT-A@mail.gmail.com>

On Wed, Jan 19, 2022 at 7:34 PM <guangming.cao at mediatek.com> wrote:
>
> From: Guangming <Guangming.Cao at mediatek.com>
>
> Add a size check for allocation since the allocation size should be
> always less than the total DRAM size on system heap.
> And it can prevent consuming too much time for invalid allocations.
>
> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> ---
>  drivers/dma-buf/heaps/system_heap.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index 23a7e74ef966..bd6f255620e2 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -347,6 +347,13 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
>         struct page *page, *tmp_page;
>         int i, ret = -ENOMEM;
>
> +       /*
> +        * Size check. The "len" should be less than totalram since system_heap
> +        * memory is comes from system. Adding check here can prevent consuming
> +        * too much time for invalid allocations.
> +        */
> +       if (len >> PAGE_SHIFT > totalram_pages())
> +               return -EINVAL;

Thanks so much for revising and sending this along! It looks good to me.

Acked-by: John Stultz <john.stultz at linaro.org>

thanks again
-john


From willy at infradead.org  Wed Jan 19 20:27:35 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Thu, 20 Jan 2022 04:27:35 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <5b62ed03-8da8-a94d-cc48-a8cac1eae1c9@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <Yedgj+Lo2eru8197@casper.infradead.org>
 <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>
 <CAAH8bW_=KtrwLpg4tx+1tdMjN2mUiuLOoZH6nvbn8qNjU6aB3A@mail.gmail.com>
 <5b62ed03-8da8-a94d-cc48-a8cac1eae1c9@arm.com>
Message-ID: <Yejkt/dpUKsaAu4t@casper.infradead.org>

On Thu, Jan 20, 2022 at 09:07:11AM +0530, Anshuman Khandual wrote:
> 
> 
> On 1/19/22 10:52 PM, Yury Norov wrote:
> >> Why should not this just scan over the entire user provided struct page
> >> array and make sure that all pages there in are valid via above method,
> >> but in vmap() itself before calling vmap_pages_range(). Because seems
> >> like a single invalid page detected in vmap_pages_pte_range() will
> >> anyways abort the entire vmap(). This will also enable us to drop the
> >> existing NULL check above.
> >
> > I can do this, but why is it any better than the current approach?
> 
> Because it will just return on the first instance where the valid page
> check fails, saving us some CPU cycles and an incomplete mapping ?

The valid page check is never intended to fail!  If you're worried about
the efficiency of doing this, you have seriously confused your priorities.


From xueshuai at linux.alibaba.com  Wed Jan 19 21:05:22 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Thu, 20 Jan 2022 13:05:22 +0800
Subject: [PATCH v6] ACPI: explicit init HEST, SDEI and GHES in apci_init
In-Reply-To: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
References: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
Message-ID: <20220120050522.23689-1-xueshuai@linux.alibaba.com>

>From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
the estatus memory pool. On the other hand, ghes_init() relies on
sdei_init() to detect the SDEI version and (un)register events. The
dependencies are as follows:

    ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
    ghes_init() => sdei_init()

HEST is not PCI-specific and initcall ordering is implicit and not
well-defined within a level.

Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
convert ghes_init() and sdei_init() from initcalls to explicit calls in the
following order:

    acpi_hest_init()
    sdei_init()
    ghes_init()

Suggested-by: Bjorn Helgaas <helgaas at kernel.org>
Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
---
 drivers/acpi/apei/ghes.c    | 17 +++++++----------
 drivers/acpi/bus.c          |  4 ++++
 drivers/acpi/pci_root.c     |  3 ---
 drivers/firmware/arm_sdei.c | 13 ++-----------
 include/acpi/apei.h         |  4 +++-
 include/linux/arm_sdei.h    |  2 ++
 6 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0c5c9acc6254..bed4f10cfcb8 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1457,33 +1457,33 @@ static struct platform_driver ghes_platform_driver = {
 	.remove		= ghes_remove,
 };
 
-static int __init ghes_init(void)
+void __init ghes_init(void)
 {
 	int rc;
 
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 
 	switch (hest_disable) {
 	case HEST_NOT_FOUND:
-		return -ENODEV;
+		return;
 	case HEST_DISABLED:
 		pr_info(GHES_PFX "HEST is not enabled!\n");
-		return -EINVAL;
+		return;
 	default:
 		break;
 	}
 
 	if (ghes_disable) {
 		pr_info(GHES_PFX "GHES is not enabled!\n");
-		return -EINVAL;
+		return;
 	}
 
 	ghes_nmi_init_cxt();
 
 	rc = platform_driver_register(&ghes_platform_driver);
 	if (rc)
-		goto err;
+		return;
 
 	rc = apei_osc_setup();
 	if (rc == 0 && osc_sb_apei_support_acked)
@@ -1495,8 +1495,5 @@ static int __init ghes_init(void)
 	else
 		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
 
-	return 0;
-err:
-	return rc;
+	return;
 }
-device_initcall(ghes_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 07f604832fd6..1dcd71df2cd5 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -30,6 +30,7 @@
 #include <linux/acpi_viot.h>
 #include <linux/pci.h>
 #include <acpi/apei.h>
+#include <linux/arm_sdei.h>
 #include <linux/suspend.h>
 #include <linux/prmt.h>
 
@@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
 
 	pci_mmcfg_late_init();
 	acpi_iort_init();
+	acpi_hest_init();
+	sdei_init();
+	ghes_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b76db99cced3..6f9e75d14808 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -22,8 +22,6 @@
 #include <linux/slab.h>
 #include <linux/dmi.h>
 #include <linux/platform_data/x86/apple.h>
-#include <acpi/apei.h>	/* for acpi_hest_init() */
-
 #include "internal.h"
 
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
@@ -943,7 +941,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 void __init acpi_pci_root_init(void)
 {
-	acpi_hest_init();
 	if (acpi_pci_disabled)
 		return;
 
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
index a7e762c352f9..1e1a51510e83 100644
--- a/drivers/firmware/arm_sdei.c
+++ b/drivers/firmware/arm_sdei.c
@@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
 	return true;
 }
 
-static int __init sdei_init(void)
+void __init sdei_init(void)
 {
 	struct platform_device *pdev;
 	int ret;
 
 	ret = platform_driver_register(&sdei_driver);
 	if (ret || !sdei_present_acpi())
-		return ret;
+		return;
 
 	pdev = platform_device_register_simple(sdei_driver.driver.name,
 					       0, NULL, 0);
@@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
 		pr_info("Failed to register ACPI:SDEI platform device %d\n",
 			ret);
 	}
-
-	return ret;
 }
 
-/*
- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
- * by device_initcall(). We want to be called in the middle.
- */
-subsys_initcall_sync(sdei_init);
-
 int sdei_event_handler(struct pt_regs *regs,
 		       struct sdei_registered_event *arg)
 {
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index ece0a8af2bae..4e60dd73c3bb 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -27,14 +27,16 @@ extern int hest_disable;
 extern int erst_disable;
 #ifdef CONFIG_ACPI_APEI_GHES
 extern bool ghes_disable;
+void __init ghes_init(void);
 #else
 #define ghes_disable 1
+static inline void ghes_init(void) { }
 #endif
 
 #ifdef CONFIG_ACPI_APEI
 void __init acpi_hest_init(void);
 #else
-static inline void acpi_hest_init(void) { return; }
+static inline void acpi_hest_init(void) { }
 #endif
 
 int erst_write(const struct cper_record_header *record);
diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
index 0a241c5c911d..14dc461b0e82 100644
--- a/include/linux/arm_sdei.h
+++ b/include/linux/arm_sdei.h
@@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
 /* For use by arch code when CPU hotplug notifiers are not appropriate. */
 int sdei_mask_local_cpu(void);
 int sdei_unmask_local_cpu(void);
+void __init sdei_init(void);
 #else
 static inline int sdei_mask_local_cpu(void) { return 0; }
 static inline int sdei_unmask_local_cpu(void) { return 0; }
+static inline void sdei_init(void) { }
 #endif /* CONFIG_ARM_SDE_INTERFACE */
 
 
-- 
2.20.1.12.g72788fdb



From axe.yang at mediatek.com  Wed Jan 19 21:34:08 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Thu, 20 Jan 2022 13:34:08 +0800
Subject: [PATCH v4 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <Yehq7L36yfJ8D/j2@smile.fi.intel.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
 <20220119103212.13158-4-axe.yang@mediatek.com>
 <Yehq7L36yfJ8D/j2@smile.fi.intel.com>
Message-ID: <0b6ef0ce05bb92cd458043be2441101e20166242.camel@mediatek.com>

On Wed, 2022-01-19 at 21:47 +0200, Andy Shevchenko wrote:
> On Wed, Jan 19, 2022 at 06:32:12PM +0800, Axe Yang wrote:
> > Add support for eint IRQ when MSDC is used as an SDIO host. This
> > feature requires SDIO device support async IRQ function. With this
> > feature, SDIO host can be awakened by SDIO card in suspend state,
> > without additional pin.
> > 
> > MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> > turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> > resume, switch GPIO function back to DAT1 mode then turn on clock.
> > 
> > Some device tree property should be added or modified in MSDC node
> > to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> > are mandatory. And cap-sdio-async-irq flag is necessary since this
> > feature depends on asynchronous interrupt:
> >         &mmcX {
> >                 ...
> >                 pinctrl-names = "default", "state_uhs",
> > "state_eint",
> >                                 "state_dat1";
> >                 ...
> >                 pinctrl-2 = <&mmc2_pins_eint>;
> >                 pinctrl-3 = <&mmc2_pins_dat1>;
> >                 ...
> >                 cap-sdio-async-irq;
> >                 ...
> >         };
> > 
> > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> 
> The submitters SoB must be last among all SoB tags. Please, read
> Submitting
> Patches document carefully.
> 
> > Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> 
> Who is they, why their SoB appeared here?
> 

Yong Mao is the co-developer of this patch, I will reorder the SoB
chains.

> ...
> 
> >  /*
> > - * Copyright (c) 2014-2015 MediaTek Inc.
> > + * Copyright (c) 2022 MediaTek Inc.
> 
> This doesn't feel right. Why did you remove old years?

I should keep the publish year 2014 of this driver.
But I still think range 2014-2022 is the most appropriate way to change
the copyright time. Over these years, mediatek is keeping maintaining
this driver continuously. What do you think?

> 
> >   * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
> >   */
> 
> ...
> 
> > +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> > +	if (IS_ERR(desc))
> > +		return PTR_ERR(desc);
> > +	ret = gpiod_to_irq(desc);
> > +	if (ret < 0)
> > +		return ret;
> > +
> > +	irq = ret;
> 
> Since both of them are local variables and there is no specific use
> of the
> returned value, I believe it's fine just to
> 
> 	irq = gpiod_to_irq(desc);
> 	...

I agree, will fix in next version.

> Hmm... I was wondering if you can use fwnode_irq_get_byname().
> Ah, it's not (yet) in upstream.
> 
> ...
> 
> >  static int __maybe_unused msdc_runtime_suspend(struct device *dev)
> >  {
> > +	unsigned long flags;
> 
> Can you keep reversed xmas tree order?
> 
> >  	struct mmc_host *mmc = dev_get_drvdata(dev);
> >  	struct msdc_host *host = mmc_priv(mmc);
> 
> (it means to add new variable here)

Will fix it in next version.

> 
> >  	return 0;
> >  }
> 
> ...
> 
> >  static int __maybe_unused msdc_runtime_resume(struct device *dev)
> >  {
> > +	unsigned long flags;
> 
> Ditto.

Will fix it in next version.

> 
> >  	struct mmc_host *mmc = dev_get_drvdata(dev);
> >  	struct msdc_host *host = mmc_priv(mmc);
> >  	int ret;
> >  	return 0;
> >  }
> 

--
Best Regard,
Axe Yang


From masahiroy at kernel.org  Wed Jan 19 21:44:18 2022
From: masahiroy at kernel.org (Masahiro Yamada)
Date: Thu, 20 Jan 2022 14:44:18 +0900
Subject: [PATCH] ARM: vdso: remove -nostdlib compiler flag
Message-ID: <20220120054418.409817-1-masahiroy@kernel.org>

The -nostdlib option requests the compiler to not use the standard
system startup files or libraries when linking. It is effective only
when $(CC) is used as a linker driver.

Since commit fe00e50b2db8 ("ARM: 8858/1: vdso: use $(LD) instead of
$(CC) to link VDSO"), $(LD) is directly used, hence -nostdlib is
unneeded.

Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
---

KernelVersion: 5.16

 arch/arm/vdso/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
index 7c9e395b77f7..ec52b776f926 100644
--- a/arch/arm/vdso/Makefile
+++ b/arch/arm/vdso/Makefile
@@ -18,7 +18,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
 
 ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
 ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
-	    -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
+	    -z max-page-size=4096 -shared $(ldflags-y) \
 	    --hash-style=sysv --build-id=sha1 \
 	    -T
 
-- 
2.32.0



From sboyd at kernel.org  Wed Jan 19 22:01:47 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Wed, 19 Jan 2022 22:01:47 -0800
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20220120000651.in7s6nazif5qjkme@pali>
References: <163425678347.1688384.10695189000353676651@swboyd.mtv.corp.google.com>
 <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali> <20220115130509.4a240730@thinkpad>
 <20220115122618.plhiqnjh2755bv5h@pali>
 <20220119231655.EFFF3C004E1@smtp.kernel.org>
 <20220120000651.in7s6nazif5qjkme@pali>
Message-ID: <20220120060149.0FF24C340E0@smtp.kernel.org>

Quoting Pali Roh?r (2022-01-19 16:06:51)
> On Wednesday 19 January 2022 15:16:54 Stephen Boyd wrote:
> > Quoting Pali Roh?r (2022-01-15 04:26:18)
> > > On Saturday 15 January 2022 13:05:09 Marek Beh?n wrote:
> > > > On Sat, 15 Jan 2022 12:50:18 +0100
> > > > Pali Roh?r <pali at kernel.org> wrote:
> > > > 
> > > > > On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > > > > > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > > > > > 
> > > > > > > If I was designing this driver and DTS bindings I would have choose
> > > > > > > something like this:
> > > > > > > 
> > > > > > > uart at 0x12000 {  
> > > > > > 
> > > > > > Drop the 0x
> > > > > >   
> > > > > > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > > > > > >     clock-controller {
> > > > > > >         ...
> > > > > > >     };  
> > > > > > 
> > > > > > Drop this node and put whatever properties are inside into the parent
> > > > > > node.
> > > > > >   
> > > > > > >     serial1 {
> > > > > > >         ...
> > > > > > >         status = "disabled";
> > > > > > >     };
> > > > > > >     serial2 {
> > > > > > >         ...
> > > > > > >         status = "disabled";
> > > > > > >     };
> > > > > > > };
> > > > > > > 
> > > > > > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > > > > > defined in top level nodes and would be handled by one driver.
> > > > > > > 
> > > > > > > This is really how hardware block looks like. But it is not backward
> > > > > > > compatible...  
> > > > > > 
> > > > > > Sounds good to me. I presume we need the serial child nodes so we can
> > > > > > reference them from the stdout-path?  
> > > > > 
> > > > > Yes, exactly, separate nodes for serial1 and serial2 are still required.
> > > > > 
> > > > > But dropping clock controller is not possible as for higher baudrates we
> > > > > need to use and configure uart clock controller. Without it we just get
> > > > > comparable feature support which is already present in driver.
> > > > 
> > > > What Stephen means is making clock controller out of the uart node
> > > > directly. No need to add separate subnode just for clock controller.
> > > 
> > > This is already implemented in v7 patch series. Clock controller is
> > > already outside of uart nodes.
> > 
> > I mean to combine the uart node and the clock-controller node together
> > 
> >       uart-wrapper {
> >               reg = <0x12000 0x18>, <0x12200 0x30>;
> >               #clock-cells ...
> > 
> >               serial1 {
> >                       ...
> >               };
> > 
> >               serial2 {
> >                       ...
> >               };
> >       };
> 
> Ok, now I see what you mean.
> 
> But problem is that this is not backward compatible change. And would
> not work per existing DT bindings definitions, which defines how
> bootloader should set configured clocks.
> 
> As I wrote in emails 3 months ago, this new "proposed" DTS definition is
> something which I would have chosen if I had designed this driver and
> bindings in past. But that did not happen and different approach is
> already widely in used.
> 
> To support existing DTS definitions and bootloaders, it is really
> required to have current structure backward compatible like it is
> defined in current DT bindings document. And my changes in this patch
> series are backward compatible.

I'm lost. Is the bootloader the one that's expecting some particular
serial node format and updating something? What is the bootloader doing?

> 
> To change DTS structure, it would be needed to provide uart nodes in DTS
> files two times: once in old style (the current one) and second time in
> this new style.

That's not a good idea. Why do we need to support both at the same time?

> 
> But such thing would even more complicate updating driver and it needs
> to be implemented.
> 
> Plus this would open a question how to define default stdout-path if
> there would be 4 serial nodes, where one pair would describe old style
> and second pair new style; meaning that 2 cross nodes would describe
> same define.

Huh? We shouldn't have both bindings present in the DTB.

> 
> For me this looks like a more complications and I do not see any benefit
> from it.
> 
> It is really important to break backward compatibility, just to try
> having new cleaner API at the cost of having more complications and
> requirement for more development and also important maintenance?

It's important to not make DT nodes have reg properties that overlap.
Maybe this is a DT purist viewpoint and I'm totally off base! I think
Rob did ack this binding already so I must be coming from the wrong
angle.

Nothing prevents register overlap from happening in practice, but it's
good to avoid such a situation as it clearly divides the I/O space by
assigning an address range to a particular device. In this case, we see
the two uarts are really one device, but we need two nodes in DT for
stdout-path, so we make some child nodes and have the driver figure out
which serial port to use for the console.

We shouldn't be adding more nodes to DT to get drivers to probe for
device I/O spaces that have already been described in DT. When this
happens, we learn that some I/O range is actually a combination of
functions, like uart and clks, and thus we should be able to add any
required properties to the existing DT node to support that new feature
that wasn't described before in the binding.


From chiawei_wang at aspeedtech.com  Wed Jan 19 22:03:51 2022
From: chiawei_wang at aspeedtech.com (ChiaWei Wang)
Date: Thu, 20 Jan 2022 06:03:51 +0000
Subject: linux-next: build warning after merge of the arm-soc tree
In-Reply-To: <20220120142220.1717e755@canb.auug.org.au>
References: <20211026103939.136dc73b@canb.auug.org.au>
 <CACPK8XfS+Gy1dhL-_uWKhW1D4++6LdWM-SdXtnsEV15OUhiK1w@mail.gmail.com>
 <20220120142220.1717e755@canb.auug.org.au>
Message-ID: <HK0PR06MB37791E63C4F75BF22B6AB715915A9@HK0PR06MB3779.apcprd06.prod.outlook.com>

Hi Stephen & Joel,

I am sorry for missing this email.
Will fix this ASAP and submit a patch for your review.

Thanks,
Chiawei

> -----Original Message-----
> From: Stephen Rothwell <sfr at canb.auug.org.au>
> Sent: Thursday, January 20, 2022 11:22 AM
> 
> Hi all,
> 
> On Tue, 26 Oct 2021 06:15:29 +0000 Joel Stanley <joel at jms.id.au> wrote:
> >
> > On Mon, 25 Oct 2021 at 23:39, Stephen Rothwell <sfr at canb.auug.org.au>
> wrote:
> > >
> > > After merging the arm-soc tree, today's linux-next build (htmldocs)
> > > produced this warning:
> > >
> > > Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing:2: WARNING:
> Inline emphasis start-string without end-string.
> > >
> > > Introduced by commit
> > >
> > >   c6807970c3bc ("soc: aspeed: Add UART routing support")
> > >
> > > The problem is (probably) the '*'s on the previous line.
> >
> > Chai-Wei, are you able to send a fix for this issue?
> 
> I am still getting this warning.
> 
> --
> Cheers,
> Stephen Rothwell

From chunfeng.yun at mediatek.com  Wed Jan 19 22:31:55 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 20 Jan 2022 14:31:55 +0800
Subject: [PATCH][next] usb: xhci-mtk: Use struct_size() helper in
 create_sch_ep()
In-Reply-To: <20220120015546.GA75917@embeddedor>
References: <20220120015546.GA75917@embeddedor>
Message-ID: <b7d0e7572ce7f7958f579ac564d25cbfee497cdc.camel@mediatek.com>

On Wed, 2022-01-19 at 19:55 -0600, Gustavo A. R. Silva wrote:
> Make use of the struct_size() helper instead of an open-coded
> version,
> in order to avoid any potential type mistakes or integer overflows
> that,
> in the worst scenario, could lead to heap overflows.
> 
> Also, address the following sparse warnings:
> drivers/usb/host/xhci-mtk-sch.c:265:20: warning: using sizeof on a
> flexible structure
> 
> Link: https://github.com/KSPP/linux/issues/160
> Link: https://github.com/KSPP/linux/issues/174
> Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> ---
>  drivers/usb/host/xhci-mtk-sch.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-
> mtk-sch.c
> index edbfa82c6565..f3139ce7b0a9 100644
> --- a/drivers/usb/host/xhci-mtk-sch.c
> +++ b/drivers/usb/host/xhci-mtk-sch.c
> @@ -248,7 +248,6 @@ create_sch_ep(struct xhci_hcd_mtk *mtk, struct
> usb_device *udev,
>  	struct mu3h_sch_bw_info *bw_info;
>  	struct mu3h_sch_tt *tt = NULL;
>  	u32 len_bw_budget_table;
> -	size_t mem_size;
>  
>  	bw_info = get_bw_info(mtk, udev, ep);
>  	if (!bw_info)
> @@ -262,9 +261,9 @@ create_sch_ep(struct xhci_hcd_mtk *mtk, struct
> usb_device *udev,
>  	else
>  		len_bw_budget_table = 1;
>  
> -	mem_size = sizeof(struct mu3h_sch_ep_info) +
> -			len_bw_budget_table * sizeof(u32);
> -	sch_ep = kzalloc(mem_size, GFP_KERNEL);
> +	sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table,
> +				     len_bw_budget_table),
> +			 GFP_KERNEL);
>  	if (!sch_ep)
>  		return ERR_PTR(-ENOMEM);
Acked-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Thanks a lot

>  

From joel at jms.id.au  Wed Jan 19 22:33:06 2022
From: joel at jms.id.au (Joel Stanley)
Date: Thu, 20 Jan 2022 17:03:06 +1030
Subject: [PATCH] ARM: dts: aspeed: rainier: Remove SPI NOR controllers
Message-ID: <20220120063307.63898-1-joel@jms.id.au>

Early Rainier builds had SPI NOR as a fallback boot device when eMMC
was not programmed. Most systems don't have the NOR populated, so remove
it from the device tree as it is not used.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts | 24 --------------------
 1 file changed, 24 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
index 652c866c14dc..43bacb16d336 100644
--- a/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
@@ -2360,30 +2360,6 @@ &mac3 {
 	use-ncsi;
 };
 
-&fmc {
-	status = "okay";
-	flash at 0 {
-		status = "okay";
-		m25p,fast-read;
-		label = "bmc";
-		spi-max-frequency = <50000000>;
-#include "openbmc-flash-layout-128.dtsi"
-	};
-};
-
-&spi1 {
-	status = "okay";
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_spi1_default>;
-
-	flash at 0 {
-		status = "okay";
-		m25p,fast-read;
-		label = "pnor";
-		spi-max-frequency = <100000000>;
-	};
-};
-
 &wdt1 {
 	aspeed,reset-type = "none";
 	aspeed,external-signal;
-- 
2.34.1



From chunfeng.yun at mediatek.com  Wed Jan 19 22:50:57 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 20 Jan 2022 14:50:57 +0800
Subject: [PATCH] usb: host: xhci-mtk: Simplify supplies handling with
 regulator_bulk
In-Reply-To: <20220118133348.111860-1-angelogioacchino.delregno@collabora.com>
References: <20220118133348.111860-1-angelogioacchino.delregno@collabora.com>
Message-ID: <91bb8078e2d0824c325eb3819e59cdcb65b68a4e.camel@mediatek.com>

On Tue, 2022-01-18 at 14:33 +0100, AngeloGioacchino Del Regno wrote:
> Remove the custom functions xhci_mtk_ldos_{enable,disable}() by
> switching to using regulator_bulk to perform the very same thing,
> as the regulators are always either both enabled or both disabled.
> 
> Signed-off-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
>  drivers/usb/host/xhci-mtk.c | 56 ++++++++++++-----------------------
> --
>  drivers/usb/host/xhci-mtk.h |  4 +--
>  2 files changed, 20 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-
> mtk.c
> index 62c835d446be..3b81931e5b77 100644
> --- a/drivers/usb/host/xhci-mtk.c
> +++ b/drivers/usb/host/xhci-mtk.c
> @@ -395,31 +395,6 @@ static int xhci_mtk_clks_get(struct xhci_hcd_mtk
> *mtk)
>  	return devm_clk_bulk_get_optional(mtk->dev, BULK_CLKS_NUM,
> clks);
>  }
>  
> -static int xhci_mtk_ldos_enable(struct xhci_hcd_mtk *mtk)
> -{
> -	int ret;
> -
> -	ret = regulator_enable(mtk->vbus);
> -	if (ret) {
> -		dev_err(mtk->dev, "failed to enable vbus\n");
> -		return ret;
> -	}
> -
> -	ret = regulator_enable(mtk->vusb33);
> -	if (ret) {
> -		dev_err(mtk->dev, "failed to enable vusb33\n");
> -		regulator_disable(mtk->vbus);
> -		return ret;
> -	}
> -	return 0;
> -}
> -
> -static void xhci_mtk_ldos_disable(struct xhci_hcd_mtk *mtk)
> -{
> -	regulator_disable(mtk->vbus);
> -	regulator_disable(mtk->vusb33);
> -}
> -
>  static void xhci_mtk_quirks(struct device *dev, struct xhci_hcd
> *xhci)
>  {
>  	struct usb_hcd *hcd = xhci_to_hcd(xhci);
> @@ -475,6 +450,10 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
>  	return ret;
>  }
>  
> +static const char * const xhci_mtk_supply_names[] = {
> +	"vusb33", "vbus",
> +};
> +
>  static const struct xhci_driver_overrides xhci_mtk_overrides
> __initconst = {
>  	.reset = xhci_mtk_setup,
>  	.add_endpoint = xhci_mtk_add_ep,
> @@ -507,17 +486,18 @@ static int xhci_mtk_probe(struct
> platform_device *pdev)
>  		return -ENOMEM;
>  
>  	mtk->dev = dev;
> -	mtk->vbus = devm_regulator_get(dev, "vbus");
> -	if (IS_ERR(mtk->vbus)) {
> -		dev_err(dev, "fail to get vbus\n");
> -		return PTR_ERR(mtk->vbus);
> -	}
> +	mtk->num_supplies = ARRAY_SIZE(xhci_mtk_supply_names);
> +	mtk->supplies = devm_kcalloc(dev, mtk->num_supplies,
> +				     sizeof(*mtk->supplies),
> GFP_KERNEL);
> +	if (!mtk->supplies)
> +		return -ENOMEM;
>  
> -	mtk->vusb33 = devm_regulator_get(dev, "vusb33");
> -	if (IS_ERR(mtk->vusb33)) {
> -		dev_err(dev, "fail to get vusb33\n");
> -		return PTR_ERR(mtk->vusb33);
> -	}
> +	regulator_bulk_set_supply_names(mtk->supplies,
> xhci_mtk_supply_names,
> +					mtk->num_supplies);
> +
> +	ret = devm_regulator_bulk_get(dev, mtk->num_supplies, mtk-
> >supplies);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Failed to get
> regulators\n");
>  
>  	ret = xhci_mtk_clks_get(mtk);
>  	if (ret)
> @@ -558,7 +538,7 @@ static int xhci_mtk_probe(struct platform_device
> *pdev)
>  	pm_runtime_enable(dev);
>  	pm_runtime_get_sync(dev);
>  
> -	ret = xhci_mtk_ldos_enable(mtk);
> +	ret = regulator_bulk_enable(mtk->num_supplies, mtk->supplies);
>  	if (ret)
>  		goto disable_pm;
>  
> @@ -667,7 +647,7 @@ static int xhci_mtk_probe(struct platform_device
> *pdev)
>  	clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks);
>  
>  disable_ldos:
> -	xhci_mtk_ldos_disable(mtk);
> +	regulator_bulk_disable(mtk->num_supplies, mtk->supplies);
>  
>  disable_pm:
>  	pm_runtime_put_noidle(dev);
> @@ -695,7 +675,7 @@ static int xhci_mtk_remove(struct platform_device
> *pdev)
>  	usb_put_hcd(hcd);
>  	xhci_mtk_sch_exit(mtk);
>  	clk_bulk_disable_unprepare(BULK_CLKS_NUM, mtk->clks);
> -	xhci_mtk_ldos_disable(mtk);
> +	regulator_bulk_disable(mtk->num_supplies, mtk->supplies);
>  
>  	pm_runtime_disable(dev);
>  	pm_runtime_put_noidle(dev);
> diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-
> mtk.h
> index 4b1ea89f959a..9b78cd2ba0ac 100644
> --- a/drivers/usb/host/xhci-mtk.h
> +++ b/drivers/usb/host/xhci-mtk.h
> @@ -150,9 +150,9 @@ struct xhci_hcd_mtk {
>  	int num_u3_ports;
>  	int u2p_dis_msk;
>  	int u3p_dis_msk;
> -	struct regulator *vusb33;
> -	struct regulator *vbus;
>  	struct clk_bulk_data clks[BULK_CLKS_NUM];
> +	struct regulator_bulk_data *supplies;
> +	u8 num_supplies;
Could you please help to change it like as clock bulk?

1. #define BULK_REGULATORS_NUM 2; then define @supplies array,

        struct regulator_bulk_data supplies[BULK_REGULATORS_NUM];

2. also add a helper to get regulator bulk; e.g.

static int xhci_mtk_regulators_get(struct xhci_hcd_mtk *mtk)
{
    struct regulator_bulk_data *supplies = mtk->supplies;

    supplies[0].supply = "vusb33";
    supplies[1].supply = "vbus";

    return devm_regulator_bulk_get(mtk->dev, BUL
K_REGULATORS_NUM, supplies);
}

Thanks a lot


>  	unsigned int has_ippc:1;
>  	unsigned int lpm_support:1;
>  	unsigned int u2_lpm_disable:1;

From biao.huang at mediatek.com  Wed Jan 19 23:02:17 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:17 +0800
Subject: [PATCH net-next v1 0/9] add more features support for mtk-star-emac
Message-ID: <20220120070226.1492-1-biao.huang@mediatek.com>

This series add more features support for mtk-star-emac:
1. add reference clock pad selection for RMII;
2. add simple timing adjustment for RMII;
3. add support for MII;
4. add support for new IC MT8365;
5. separate tx/rx interrupt handling.

Biao Huang (8):
  net: ethernet: mtk-star-emac: modify IRQ trigger flags
  net: ethernet: mtk-star-emac: add support for MT8365 SoC
  dt-bindings: net: mtk-star-emac: add support for MT8365
  net: ethernet: mtk-star-emac: add clock pad selection for RMII
  net: ethernet: mtk-star-emac: add timing adjustment support
  dt-bindings: net: mtk-star-emac: add description for new  properties
  net: ethernet: mtk-star-emac: add support for MII interface
  net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs

Fabien Parent (1):
  net: ethernet: mtk-star-emac: store bit_clk_div in compat structure

 .../bindings/net/mediatek,star-emac.yaml      |  17 +
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 473 ++++++++++++------
 2 files changed, 337 insertions(+), 153 deletions(-)

-- 
2.18.0





From biao.huang at mediatek.com  Wed Jan 19 23:02:18 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:18 +0800
Subject: [PATCH net-next v1 1/9] net: ethernet: mtk-star-emac: store
 bit_clk_div in compat structure
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-2-biao.huang@mediatek.com>

From: Fabien Parent <fparent at baylibre.com>

Not all the SoC are using the same clock divider. Move the divider into
a compat structure specific to the SoCs.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Fabien Parent <fparent at baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 23 +++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 1d5dd2015453..26f5020f2e9c 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/platform_device.h>
@@ -232,6 +233,10 @@ struct mtk_star_ring {
 	unsigned int tail;
 };
 
+struct mtk_star_compat {
+	unsigned char bit_clk_div;
+};
+
 struct mtk_star_priv {
 	struct net_device *ndev;
 
@@ -257,6 +262,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 
+	const struct mtk_star_compat *compat_data;
+
 	/* Protects against concurrent descriptor access. */
 	spinlock_t lock;
 
@@ -899,7 +906,7 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
 	regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
 			   MTK_STAR_MSK_MAC_CLK_CONF,
-			   MTK_STAR_BIT_CLK_DIV_10);
+			   priv->compat_data->bit_clk_div);
 }
 
 static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
@@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(ndev);
 	priv->ndev = ndev;
+	priv->compat_data = of_device_get_match_data(&pdev->dev);
 	SET_NETDEV_DEV(ndev, dev);
 	platform_set_drvdata(pdev, ndev);
 
@@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static struct mtk_star_compat mtk_star_mt8516_compat = {
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
-	{ .compatible = "mediatek,mt8516-eth", },
-	{ .compatible = "mediatek,mt8518-eth", },
-	{ .compatible = "mediatek,mt8175-eth", },
+	{ .compatible = "mediatek,mt8516-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8518-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8175-eth",
+	  .data = &mtk_star_mt8516_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:19 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:19 +0800
Subject: [PATCH net-next v1 2/9] net: ethernet: mtk-star-emac: modify IRQ
 trigger flags
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-3-biao.huang@mediatek.com>

If the flags in request_irq() is IRQF_TRIGGER_NONE, the trigger method
is determined by "interrupt" property in dts.
So, modify the flag from IRQF_TRIGGER_FALLING to IRQF_TRIGGER_NONE.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 26f5020f2e9c..7c2af775d601 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -959,7 +959,7 @@ static int mtk_star_enable(struct net_device *ndev)
 
 	/* Request the interrupt */
 	ret = request_irq(ndev->irq, mtk_star_handle_irq,
-			  IRQF_TRIGGER_FALLING, ndev->name, ndev);
+			  IRQF_TRIGGER_NONE, ndev->name, ndev);
 	if (ret)
 		goto err_free_skbs;
 
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:20 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:20 +0800
Subject: [PATCH net-next v1 3/9] net: ethernet: mtk-star-emac: add support for
 MT8365 SoC
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-4-biao.huang@mediatek.com>

Add Ethernet driver support for MT8365 SoC.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
Signed-off-by: Fabien Parent <fparent at baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 75 ++++++++++++++++---
 1 file changed, 64 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 7c2af775d601..403439782db9 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_MAC_CLK_CONF		0x00ac
 #define MTK_STAR_MSK_MAC_CLK_CONF		GENMASK(7, 0)
 #define MTK_STAR_BIT_CLK_DIV_10			0x0a
+#define MTK_STAR_BIT_CLK_DIV_50			0x32
 
 /* Counter registers. */
 #define MTK_STAR_REG_C_RXOKPKT			0x0100
@@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_C_RX_TWIST			0x0218
 
 /* Ethernet CFG Control */
-#define MTK_PERICFG_REG_NIC_CFG_CON		0x03c4
-#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII	GENMASK(3, 0)
-#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	BIT(0)
+#define MTK_PERICFG_REG_NIC_CFG0_CON		0x03c4
+#define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
+#define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
+#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -234,6 +237,7 @@ struct mtk_star_ring {
 };
 
 struct mtk_star_compat {
+	int (*set_interface_mode)(struct net_device *ndev);
 	unsigned char bit_clk_div;
 };
 
@@ -909,13 +913,6 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 			   priv->compat_data->bit_clk_div);
 }
 
-static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
-{
-	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON,
-			   MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
-			   MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
-}
-
 static int mtk_star_enable(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
@@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	mtk_star_set_mode_rmii(priv);
+	if (priv->compat_data->set_interface_mode) {
+		ret = priv->compat_data->set_interface_mode(ndev);
+		if (ret) {
+			dev_err(dev, "Failed to set phy interface, err = %d\n", ret);
+			return -EINVAL;
+		}
+	}
 
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
@@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static int mt8516_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val = 0;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG0_CON,
+			   MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+			   intf_val);
+	return 0;
+}
+
+static int mt8365_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val = 0;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON_V2,
+			   MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+			   intf_val);
+	return 0;
+}
+
 static struct mtk_star_compat mtk_star_mt8516_compat = {
+	.set_interface_mode = mt8516_set_interface_mode,
 	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
 };
 
+static struct mtk_star_compat mtk_star_mt8365_compat = {
+	.set_interface_mode = mt8365_set_interface_mode,
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
 	{ .compatible = "mediatek,mt8516-eth",
 	  .data = &mtk_star_mt8516_compat },
@@ -1575,6 +1626,8 @@ static const struct of_device_id mtk_star_of_match[] = {
 	  .data = &mtk_star_mt8516_compat },
 	{ .compatible = "mediatek,mt8175-eth",
 	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8365-eth",
+	  .data = &mtk_star_mt8365_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:21 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:21 +0800
Subject: [PATCH net-next v1 4/9] dt-bindings: net: mtk-star-emac: add support
 for MT8365
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-5-biao.huang@mediatek.com>

Add binding document for Ethernet on MT8365.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index e6a5ff208253..87a8b25b03a6 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -23,6 +23,7 @@ properties:
       - mediatek,mt8516-eth
       - mediatek,mt8518-eth
       - mediatek,mt8175-eth
+      - mediatek,mt8365-eth
 
   reg:
     maxItems: 1
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:23 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:23 +0800
Subject: [PATCH net-next v1 6/9] net: ethernet: mtk-star-emac: add timing
 adjustment support
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-7-biao.huang@mediatek.com>

Add simple clock inversion for timing adjustment in driver.
Add property "mediatek,txc-inverse" or "mediatek,rxc-inverse" to
device node when necessary.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index ab2fe72fdd6a..e37fa2cb5433 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -131,6 +131,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_INT_MASK			0x0054
 #define MTK_STAR_BIT_INT_MASK_FNRC		BIT(6)
 
+/* Delay-Macro Register */
+#define MTK_STAR_REG_TEST0			0x0058
+#define MTK_STAR_BIT_INV_RX_CLK			BIT(30)
+#define MTK_STAR_BIT_INV_TX_CLK			BIT(31)
+
 /* Misc. Config Register */
 #define MTK_STAR_REG_TEST1			0x005c
 #define MTK_STAR_BIT_TEST1_RST_HASH_MBIST	BIT(31)
@@ -268,6 +273,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 	bool rmii_rxc;
+	bool rx_inv;
+	bool tx_inv;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1450,6 +1457,25 @@ static void mtk_star_clk_disable_unprepare(void *data)
 	clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
 }
 
+static int mtk_star_set_timing(struct mtk_star_priv *priv)
+{
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int delay_val = 0;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_write(priv->regs, MTK_STAR_REG_TEST0, delay_val);
+
+	return 0;
+}
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1532,6 +1558,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	}
 
 	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+	priv->rx_inv = of_property_read_bool(of_node, "mediatek,rxc-inverse");
+	priv->tx_inv = of_property_read_bool(of_node, "mediatek,txc-inverse");
 
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
@@ -1541,6 +1569,12 @@ static int mtk_star_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = mtk_star_set_timing(priv);
+	if (ret) {
+		dev_err(dev, "Failed to set timing, err = %d\n", ret);
+		return -EINVAL;
+	}
+
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(dev, "unsupported DMA mask\n");
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:22 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:22 +0800
Subject: [PATCH net-next v1 5/9] net: ethernet: mtk-star-emac: add clock pad
 selection for RMII
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-6-biao.huang@mediatek.com>

This patch add a new dts property named "mediatek,rmii-rxc" parsing
in driver, which will configure MAC to select which pin the RMII reference
clock is connected to, TXC or RXC.

TXC pad is the default reference clock pin. If user wants to use RXC pad
instead, add "mediatek,rmii-rxc" to corresponding device node.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 403439782db9..ab2fe72fdd6a 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -189,6 +189,8 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -265,6 +267,7 @@ struct mtk_star_priv {
 	int speed;
 	int duplex;
 	int pause;
+	bool rmii_rxc;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1528,6 +1531,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
 		if (ret) {
@@ -1571,17 +1576,21 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 	struct device *dev = mtk_star_get_dev(priv);
-	unsigned int intf_val = 0;
+	unsigned int intf_val = 0, rmii_rxc = 0;
 
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
 		return -EINVAL;
 	}
 
+	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG1_CON,
+			   MTK_PERICFG_BIT_NIC_CFG_CON_CLK,
+			   rmii_rxc);
 	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG0_CON,
 			   MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
 			   intf_val);
@@ -1597,6 +1606,7 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
@@ -1604,7 +1614,8 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	}
 
 	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON_V2,
-			   MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+			   MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF |
+			   MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2,
 			   intf_val);
 	return 0;
 }
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:25 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:25 +0800
Subject: [PATCH net-next v1 8/9] net: ethernet: mtk-star-emac: add support for
 MII interface
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-9-biao.huang@mediatek.com>

Add support for MII interface.
If user wants to use MII, assign "MII" to "phy-mode" property in dts.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index e37fa2cb5433..08a372848651 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -193,6 +193,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_MII		0
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
@@ -1463,6 +1464,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 	unsigned int delay_val = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
 	case PHY_INTERFACE_MODE_RMII:
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
@@ -1545,7 +1547,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ret = of_get_phy_mode(of_node, &priv->phy_intf);
 	if (ret) {
 		return ret;
-	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII) {
+	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII &&
+		   priv->phy_intf != PHY_INTERFACE_MODE_MII) {
 		dev_err(dev, "unsupported phy mode: %s\n",
 			phy_modes(priv->phy_intf));
 		return -EINVAL;
@@ -1613,6 +1616,9 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 	unsigned int intf_val = 0, rmii_rxc = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
@@ -1638,6 +1644,9 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	unsigned int intf_val = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:24 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:24 +0800
Subject: [PATCH net-next v1 7/9] dt-bindings: net: mtk-star-emac: add
 description for new properties
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-8-biao.huang@mediatek.com>

Add description for new properties which will be parsed in driver.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 .../bindings/net/mediatek,star-emac.yaml         | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index 87a8b25b03a6..41b1b1dd562c 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -48,6 +48,22 @@ properties:
       Phandle to the device containing the PERICFG register range. This is used
       to control the MII mode.
 
+  mediatek,rmii-rxc:
+    type: boolean
+    description:
+      If present, indicates that the RMII reference clock, which is from external
+      PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+  mediatek,rxc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on RXC pad will be inversed.
+
+  mediatek,txc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on TXC pad will be inversed.
+
   mdio:
     type: object
     description:
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 19 23:02:26 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 20 Jan 2022 15:02:26 +0800
Subject: [PATCH net-next v1 9/9] net: ethernet: mtk-star-emac: separate tx/rx
 handling with two NAPIs
In-Reply-To: <20220120070226.1492-1-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
Message-ID: <20220120070226.1492-10-biao.huang@mediatek.com>

Current driver may lost tx interrupts under bidirectional test with iperf3,
which leads to some unexpected issues.

This patch let rx/tx interrupt enable/disable separately, and rx/tx are
handled in different NAPIs.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 317 ++++++++++--------
 1 file changed, 181 insertions(+), 136 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 08a372848651..c46e05bfd8a5 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -229,7 +229,7 @@ struct mtk_star_ring_desc_data {
 	struct sk_buff *skb;
 };
 
-#define MTK_STAR_RING_NUM_DESCS			128
+#define MTK_STAR_RING_NUM_DESCS			512
 #define MTK_STAR_NUM_TX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_RX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_DESCS_TOTAL		(MTK_STAR_RING_NUM_DESCS * 2)
@@ -264,7 +264,8 @@ struct mtk_star_priv {
 	struct mtk_star_ring rx_ring;
 
 	struct mii_bus *mii;
-	struct napi_struct napi;
+	struct napi_struct tx_napi;
+	struct napi_struct rx_napi;
 
 	struct device_node *phy_node;
 	phy_interface_t phy_intf;
@@ -380,19 +381,16 @@ mtk_star_ring_push_head_tx(struct mtk_star_ring *ring,
 	mtk_star_ring_push_head(ring, desc_data, flags);
 }
 
-static unsigned int mtk_star_ring_num_used_descs(struct mtk_star_ring *ring)
+static unsigned int mtk_star_tx_ring_avail(struct mtk_star_ring *ring)
 {
-	return abs(ring->head - ring->tail);
-}
+	u32 avail;
 
-static bool mtk_star_ring_full(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) == MTK_STAR_RING_NUM_DESCS;
-}
+	if (ring->tail > ring->head)
+		avail = ring->tail - ring->head - 1;
+	else
+		avail = MTK_STAR_RING_NUM_DESCS - ring->head + ring->tail - 1;
 
-static bool mtk_star_ring_descs_available(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) > 0;
+	return avail;
 }
 
 static dma_addr_t mtk_star_dma_map_rx(struct mtk_star_priv *priv,
@@ -415,7 +413,7 @@ static void mtk_star_dma_unmap_rx(struct mtk_star_priv *priv,
 }
 
 static dma_addr_t mtk_star_dma_map_tx(struct mtk_star_priv *priv,
-				      struct sk_buff *skb)
+					     struct sk_buff *skb)
 {
 	struct device *dev = mtk_star_get_dev(priv);
 
@@ -437,6 +435,36 @@ static void mtk_star_nic_disable_pd(struct mtk_star_priv *priv)
 			  MTK_STAR_BIT_MAC_CFG_NIC_PD);
 }
 
+static void mtk_star_enable_dma_irq(struct mtk_star_priv *priv,
+				    bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value &= ~MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value &= ~MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
+static void mtk_star_disable_dma_irq(struct mtk_star_priv *priv,
+				     bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value |= MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value |= MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
 /* Unmask the three interrupts we care about, mask all others. */
 static void mtk_star_intr_enable(struct mtk_star_priv *priv)
 {
@@ -452,20 +480,11 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0);
 }
 
-static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv)
-{
-	unsigned int val;
-
-	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
-
-	return val;
-}
-
 static unsigned int mtk_star_intr_ack_all(struct mtk_star_priv *priv)
 {
 	unsigned int val;
 
-	val = mtk_star_intr_read(priv);
+	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
 	regmap_write(priv->regs, MTK_STAR_REG_INT_STS, val);
 
 	return val;
@@ -737,25 +756,46 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv)
 	mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx);
 }
 
-/* All processing for TX and RX happens in the napi poll callback.
- *
- * FIXME: The interrupt handling should be more fine-grained with each
- * interrupt enabled/disabled independently when needed. Unfortunatly this
- * turned out to impact the driver's stability and until we have something
- * working properly, we're disabling all interrupts during TX & RX processing
- * or when resetting the counter registers.
+/* mtk_star_handle_irq - Interrupt Handler.
+ * @irq: interrupt number.
+ * @data: pointer to a network interface device structure.
+ * Description : this is the driver interrupt service routine.
+ * it mainly handles:
+ *  1. tx complete interrupt for frame transmission.
+ *  2. rx complete interrupt for frame reception.
+ *  3. MAC Management Counter interrupt to avoid counter overflow.
  */
 static irqreturn_t mtk_star_handle_irq(int irq, void *data)
 {
-	struct mtk_star_priv *priv;
-	struct net_device *ndev;
+	struct net_device *ndev = data;
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	unsigned int intr_status = mtk_star_intr_ack_all(priv);
+	unsigned long flags = 0;
+
+	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
+		if (napi_schedule_prep(&priv->rx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Rx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, true, false);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->rx_napi);
+		}
+	}
 
-	ndev = data;
-	priv = netdev_priv(ndev);
+	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
+		if (napi_schedule_prep(&priv->tx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Tx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, false, true);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->tx_napi);
+		}
+	}
 
-	if (netif_running(ndev)) {
-		mtk_star_intr_disable(priv);
-		napi_schedule(&priv->napi);
+	/* interrupt is triggered once any counters reach 0x8000000 */
+	if (intr_status & MTK_STAR_REG_INT_STS_MIB_CNT_TH) {
+		mtk_star_update_stats(priv);
+		mtk_star_reset_counters(priv);
 	}
 
 	return IRQ_HANDLED;
@@ -971,7 +1011,8 @@ static int mtk_star_enable(struct net_device *ndev)
 	if (ret)
 		goto err_free_skbs;
 
-	napi_enable(&priv->napi);
+	napi_enable(&priv->tx_napi);
+	napi_enable(&priv->rx_napi);
 
 	mtk_star_intr_ack_all(priv);
 	mtk_star_intr_enable(priv);
@@ -1004,7 +1045,8 @@ static void mtk_star_disable(struct net_device *ndev)
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 
 	netif_stop_queue(ndev);
-	napi_disable(&priv->napi);
+	napi_disable(&priv->tx_napi);
+	napi_disable(&priv->rx_napi);
 	mtk_star_intr_disable(priv);
 	mtk_star_dma_disable(priv);
 	mtk_star_intr_ack_all(priv);
@@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 	struct mtk_star_ring *ring = &priv->tx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
 	struct mtk_star_ring_desc_data desc_data;
+	int nfrags = skb_shinfo(skb)->nr_frags;
+
+	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
+		if (!netif_queue_stopped(ndev)) {
+			netif_stop_queue(ndev);
+			/* This is a hard error, log it. */
+			netdev_err(priv->ndev, "%s: Tx Ring full when queue awake\n",
+				   __func__);
+		}
+		return NETDEV_TX_BUSY;
+	}
 
 	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
 	if (dma_mapping_error(dev, desc_data.dma_addr))
@@ -1050,18 +1103,10 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 
 	desc_data.skb = skb;
 	desc_data.len = skb->len;
-
-	spin_lock_bh(&priv->lock);
-
 	mtk_star_ring_push_head_tx(ring, &desc_data);
 
 	netdev_sent_queue(ndev, skb->len);
 
-	if (mtk_star_ring_full(ring))
-		netif_stop_queue(ndev);
-
-	spin_unlock_bh(&priv->lock);
-
 	mtk_star_dma_resume_tx(priv);
 
 	return NETDEV_TX_OK;
@@ -1092,23 +1137,31 @@ static int mtk_star_tx_complete_one(struct mtk_star_priv *priv)
 	return ret;
 }
 
-static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
+static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
 {
-	struct mtk_star_ring *ring = &priv->tx_ring;
-	struct net_device *ndev = priv->ndev;
-	int ret, pkts_compl, bytes_compl;
+	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
+	struct mtk_star_priv *priv;
+	struct mtk_star_ring *ring;
+	struct net_device *ndev;
+	unsigned long flags = 0;
+	unsigned int entry;
 	bool wake = false;
 
-	spin_lock(&priv->lock);
+	priv = container_of(napi, struct mtk_star_priv, tx_napi);
+	ndev = priv->ndev;
 
-	for (pkts_compl = 0, bytes_compl = 0;;
+	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));
+	ring = &priv->tx_ring;
+	entry = ring->tail;
+	for (pkts_compl = 0, bytes_compl = 0;
+	     (entry != ring->head) && (count < budget);
 	     pkts_compl++, bytes_compl += ret, wake = true) {
-		if (!mtk_star_ring_descs_available(ring))
-			break;
 
 		ret = mtk_star_tx_complete_one(priv);
 		if (ret < 0)
 			break;
+		count++;
+		entry = ring->tail;
 	}
 
 	netdev_completed_queue(ndev, pkts_compl, bytes_compl);
@@ -1116,7 +1169,16 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
 	if (wake && netif_queue_stopped(ndev))
 		netif_wake_queue(ndev);
 
-	spin_unlock(&priv->lock);
+	__netif_tx_unlock_bh(netdev_get_tx_queue(priv->ndev, 0));
+
+	count = min(count, budget);
+	if (count < budget && napi_complete_done(napi, count)) {
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, false, true);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	return count;
 }
 
 static void mtk_star_netdev_get_stats64(struct net_device *ndev,
@@ -1196,7 +1258,7 @@ static const struct ethtool_ops mtk_star_ethtool_ops = {
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 };
 
-static int mtk_star_receive_packet(struct mtk_star_priv *priv)
+static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
 {
 	struct mtk_star_ring *ring = &priv->rx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
@@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
 	struct net_device *ndev = priv->ndev;
 	struct sk_buff *curr_skb, *new_skb;
 	dma_addr_t new_dma_addr;
-	int ret;
+	int ret, count = 0;
 
-	spin_lock(&priv->lock);
-	ret = mtk_star_ring_pop_tail(ring, &desc_data);
-	spin_unlock(&priv->lock);
-	if (ret)
-		return -1;
+	while (count < budget) {
+		ret = mtk_star_ring_pop_tail(ring, &desc_data);
+		if (ret)
+			return -1;
 
-	curr_skb = desc_data.skb;
+		curr_skb = desc_data.skb;
 
-	if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
-	    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
-		/* Error packet -> drop and reuse skb. */
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
+		    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
+			/* Error packet -> drop and reuse skb. */
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	/* Prepare new skb before receiving the current one. Reuse the current
-	 * skb if we fail at any point.
-	 */
-	new_skb = mtk_star_alloc_skb(ndev);
-	if (!new_skb) {
-		ndev->stats.rx_dropped++;
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		/* Prepare new skb before receiving the current one.
+		 * Reuse the current skb if we fail at any point.
+		 */
+		new_skb = mtk_star_alloc_skb(ndev);
+		if (!new_skb) {
+			ndev->stats.rx_dropped++;
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
-	if (dma_mapping_error(dev, new_dma_addr)) {
-		ndev->stats.rx_dropped++;
-		dev_kfree_skb(new_skb);
-		new_skb = curr_skb;
-		netdev_err(ndev, "DMA mapping error of RX descriptor\n");
-		goto push_new_skb;
-	}
+		new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
+		if (dma_mapping_error(dev, new_dma_addr)) {
+			ndev->stats.rx_dropped++;
+			dev_kfree_skb(new_skb);
+			new_skb = curr_skb;
+			netdev_err(ndev, "DMA mapping error of RX descriptor\n");
+			goto push_new_skb;
+		}
 
-	/* We can't fail anymore at this point: it's safe to unmap the skb. */
-	mtk_star_dma_unmap_rx(priv, &desc_data);
+		/* We can't fail anymore at this point:
+		 * it's safe to unmap the skb.
+		 */
+		mtk_star_dma_unmap_rx(priv, &desc_data);
 
-	skb_put(desc_data.skb, desc_data.len);
-	desc_data.skb->ip_summed = CHECKSUM_NONE;
-	desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
-	desc_data.skb->dev = ndev;
-	netif_receive_skb(desc_data.skb);
+		skb_put(desc_data.skb, desc_data.len);
+		desc_data.skb->ip_summed = CHECKSUM_NONE;
+		desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
+		desc_data.skb->dev = ndev;
+		netif_receive_skb(desc_data.skb);
 
-	/* update dma_addr for new skb */
-	desc_data.dma_addr = new_dma_addr;
+		/* update dma_addr for new skb */
+		desc_data.dma_addr = new_dma_addr;
 
 push_new_skb:
-	desc_data.len = skb_tailroom(new_skb);
-	desc_data.skb = new_skb;
-
-	spin_lock(&priv->lock);
-	mtk_star_ring_push_head_rx(ring, &desc_data);
-	spin_unlock(&priv->lock);
-
-	return 0;
-}
 
-static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
-{
-	int received, ret;
+		count++;
 
-	for (received = 0, ret = 0; received < budget && ret == 0; received++)
-		ret = mtk_star_receive_packet(priv);
+		desc_data.len = skb_tailroom(new_skb);
+		desc_data.skb = new_skb;
+		mtk_star_ring_push_head_rx(ring, &desc_data);
+	}
 
 	mtk_star_dma_resume_rx(priv);
 
-	return received;
+	return count;
 }
 
-static int mtk_star_poll(struct napi_struct *napi, int budget)
+static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
 {
 	struct mtk_star_priv *priv;
-	unsigned int status;
-	int received = 0;
+	unsigned long flags = 0;
+	int work_done = 0;
 
-	priv = container_of(napi, struct mtk_star_priv, napi);
+	priv = container_of(napi, struct mtk_star_priv, rx_napi);
 
-	status = mtk_star_intr_read(priv);
-	mtk_star_intr_ack_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_TNTC)
-		/* Clean-up all TX descriptors. */
-		mtk_star_tx_complete_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_FNRC)
-		/* Receive up to $budget packets. */
-		received = mtk_star_process_rx(priv, budget);
-
-	if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
-		mtk_star_update_stats(priv);
-		mtk_star_reset_counters(priv);
+	work_done = mtk_star_rx(priv, budget);
+	if (work_done < budget) {
+		napi_complete_done(napi, work_done);
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, true, false);
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
-	if (received < budget)
-		napi_complete_done(napi, received);
-
-	mtk_star_intr_enable(priv);
-
-	return received;
+	return work_done;
 }
 
 static void mtk_star_mdio_rwok_clear(struct mtk_star_priv *priv)
@@ -1478,6 +1519,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 
 	return 0;
 }
+
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1604,7 +1646,10 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ndev->netdev_ops = &mtk_star_netdev_ops;
 	ndev->ethtool_ops = &mtk_star_ethtool_ops;
 
-	netif_napi_add(ndev, &priv->napi, mtk_star_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_napi_add(ndev, &priv->rx_napi,
+		       mtk_star_rx_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_tx_napi_add(ndev, &priv->tx_napi,
+			  mtk_star_tx_poll, MTK_STAR_NAPI_WEIGHT);
 
 	return devm_register_netdev(dev, ndev);
 }
-- 
2.25.1



From p.yadav at ti.com  Wed Jan 19 23:06:20 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Thu, 20 Jan 2022 12:36:20 +0530
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
 <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
Message-ID: <20220120070620.wyeosdstbfcsaplt@ti.com>

On 19/01/22 08:49PM, Krzysztof Kozlowski wrote:
> On 19/01/2022 20:31, Pratyush Yadav wrote:
> > On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
> >> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> >> controller bindings to DT schema format
> >>
> >> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> >> ---
> >>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
> >>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
> >>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
> >>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
> >>  MAINTAINERS                                   |   2 +-
> >>  5 files changed, 224 insertions(+), 123 deletions(-)
> >>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
> >>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> >>
> >> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >> new file mode 100644
> >> index 000000000000..aa5a1f48494b
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >> @@ -0,0 +1,35 @@
> >> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> >> +%YAML 1.2
> >> +---
> >> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> >> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >> +
> >> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> >> +
> >> +maintainers:
> >> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >> +
> >> +description:
> >> +  See spi-peripheral-props.yaml for more info.
> >> +
> >> +properties:
> >> +  controller-data:
> >> +    type: object
> >> +    additionalProperties: false
> >> +
> >> +    properties:
> >> +      samsung,spi-feedback-delay:
> >> +        description: |
> >> +          The sampling phase shift to be applied on the miso line (to account
> >> +          for any lag in the miso line). Valid values:
> >> +           - 0: No phase shift.
> >> +           - 1: 90 degree phase shift sampling.
> >> +           - 2: 180 degree phase shift sampling.
> >> +           - 3: 270 degree phase shift sampling.
> >> +        $ref: /schemas/types.yaml#/definitions/uint32
> >> +        enum: [0, 1, 2, 3]
> >> +
> >> +    required:
> >> +      - samsung,spi-feedback-delay
> > 
> > I am not quite sure if this required would work here. Let's say another 
> > controller also uses a controller-data node, but it contains a different 
> > set of properties. Won't this cause an error to be raised for that 
> > controller since this property is not there?
> 
> The controller-data is Samsung SPI specific (does not exist in any other
> binding), so why would controller-data get added to a different controller?

It does not as of now, but the name is fairly generic and some 
controller in the future might use it. I do not think it is a good idea 
to list required properties in X-peripheral-props.yaml in general since 
all those will be collected by spi-peripheral-props.yaml and so will 
apply to _all_ controllers that reference it.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From guangming.cao at mediatek.com  Wed Jan 19 23:08:50 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 20 Jan 2022 15:08:50 +0800
Subject: [PATCH v5] dma-buf: system_heap: Add a size check for allocation
In-Reply-To: <CALAqxLW5uEZCGHGk3rYoiOGzN5XMKb39JzoPB1iEX9k3UsiT-A@mail.gmail.com>
References: <CALAqxLW5uEZCGHGk3rYoiOGzN5XMKb39JzoPB1iEX9k3UsiT-A@mail.gmail.com>
Message-ID: <20220120070850.95495-1-guangming.cao@mediatek.com>

From: Guangming <Guangming.Cao at mediatek.com>

Add a size check for allocation since the allocation size should be
always less than the total DRAM size on system heap.
Adding this check can prevent comsuming too much time for invalid allocations.

Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/system_heap.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..459dc18bc4a2 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -347,6 +347,14 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	struct page *page, *tmp_page;
 	int i, ret = -ENOMEM;
 
+	/*
+	 * Size check. The "len" should be less than totalram since system_heap
+	 * memory is comes from system. Adding check here can prevent comsuming
+	 * too much time for invalid allocations.
+	 */
+	if (len >> PAGE_SHIFT > totalram_pages())
+		return ERR_PTR(-EINVAL);
+
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 	if (!buffer)
 		return ERR_PTR(-ENOMEM);
-- 
2.17.1



From krzysztof.kozlowski at canonical.com  Wed Jan 19 23:36:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 08:36:03 +0100
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220120070620.wyeosdstbfcsaplt@ti.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
 <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
 <20220120070620.wyeosdstbfcsaplt@ti.com>
Message-ID: <0c0a22ed-2c4b-374c-4f4c-06afd4e8681d@canonical.com>

On 20/01/2022 08:06, Pratyush Yadav wrote:
> On 19/01/22 08:49PM, Krzysztof Kozlowski wrote:
>> On 19/01/2022 20:31, Pratyush Yadav wrote:
>>> On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
>>>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
>>>> controller bindings to DT schema format
>>>>
>>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
>>>> ---
>>>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
>>>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
>>>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
>>>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
>>>>  MAINTAINERS                                   |   2 +-
>>>>  5 files changed, 224 insertions(+), 123 deletions(-)
>>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
>>>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>>>> new file mode 100644
>>>> index 000000000000..aa5a1f48494b
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
>>>> @@ -0,0 +1,35 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
>>>> +
>>>> +maintainers:
>>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>>>> +
>>>> +description:
>>>> +  See spi-peripheral-props.yaml for more info.
>>>> +
>>>> +properties:
>>>> +  controller-data:
>>>> +    type: object
>>>> +    additionalProperties: false
>>>> +
>>>> +    properties:
>>>> +      samsung,spi-feedback-delay:
>>>> +        description: |
>>>> +          The sampling phase shift to be applied on the miso line (to account
>>>> +          for any lag in the miso line). Valid values:
>>>> +           - 0: No phase shift.
>>>> +           - 1: 90 degree phase shift sampling.
>>>> +           - 2: 180 degree phase shift sampling.
>>>> +           - 3: 270 degree phase shift sampling.
>>>> +        $ref: /schemas/types.yaml#/definitions/uint32
>>>> +        enum: [0, 1, 2, 3]
>>>> +
>>>> +    required:
>>>> +      - samsung,spi-feedback-delay
>>>
>>> I am not quite sure if this required would work here. Let's say another 
>>> controller also uses a controller-data node, but it contains a different 
>>> set of properties. Won't this cause an error to be raised for that 
>>> controller since this property is not there?
>>
>> The controller-data is Samsung SPI specific (does not exist in any other
>> binding), so why would controller-data get added to a different controller?
> 
> It does not as of now, but the name is fairly generic and some 
> controller in the future might use it. I do not think it is a good idea 
> to list required properties in X-peripheral-props.yaml in general since 
> all those will be collected by spi-peripheral-props.yaml and so will 
> apply to _all_ controllers that reference it.

Right, but have in mind this is merely a bindings conversion. These were
made like this long time ago.

I think we can drop the "required:" entirely with the commit 3/4 which
makes it optional.



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Wed Jan 19 23:38:56 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 08:38:56 +0100
Subject: [PATCH v4 5/5] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <Yeh6x6U3tA7y5gvF@jack.zhora.eu>
References: <20220119201005.13145-1-krzysztof.kozlowski@canonical.com>
 <20220119201005.13145-6-krzysztof.kozlowski@canonical.com>
 <Yeh6x6U3tA7y5gvF@jack.zhora.eu>
Message-ID: <5d16420a-4852-ab29-59d0-b100feeb2862@canonical.com>

On 19/01/2022 21:55, Andi Shyti wrote:
> Hi Krzysztof,
> 
> On Wed, Jan 19, 2022 at 09:10:05PM +0100, Krzysztof Kozlowski wrote:
>> The Samsung SoC SPI driver requires to provide controller-data node
>> for each of SPI peripheral device nodes.  Make this controller-data node
>> optional, so DTS could be simpler.
>>
>> Suggested-by: Rob Herring <robh at kernel.org>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
>> ---
>>  drivers/spi/spi-s3c64xx.c | 14 ++++++--------
>>  1 file changed, 6 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
>> index 8755cd85e83c..769d958a2f86 100644
>> --- a/drivers/spi/spi-s3c64xx.c
>> +++ b/drivers/spi/spi-s3c64xx.c
>> @@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
>>  		return ERR_PTR(-EINVAL);
>>  	}
>>  
>> -	data_np = of_get_child_by_name(slave_np, "controller-data");
>> -	if (!data_np) {
>> -		dev_err(&spi->dev, "child node 'controller-data' not found\n");
>> -		return ERR_PTR(-EINVAL);
>> -	}
>> -
>>  	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
>> -	if (!cs) {
>> -		of_node_put(data_np);
>> +	if (!cs)
>>  		return ERR_PTR(-ENOMEM);
>> +
>> +	data_np = of_get_child_by_name(slave_np, "controller-data");
>> +	if (!data_np) {
>> +		dev_info(&spi->dev, "child node 'controller-data' not found, using defaults\n");
> 
> "not found" sounds like an error; I would just write something
> like "feedback delay set to '0' dfault", you also tell that the
> default value is '0'.

Sure, I will rewrite the message.


Best regards,
Krzysztof


From guoren at kernel.org  Wed Jan 19 23:38:53 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:53 +0800
Subject: [PATCH V3 00/17] riscv: compat: Add COMPAT mode support for rv64
Message-ID: <20220120073911.99857-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Currently, most 64-bit architectures (x86, parisc, powerpc, arm64,
s390, mips, sparc) have supported COMPAT mode. But they all have
history issues and can't use standard linux unistd.h. RISC-V would
be first standard __SYSCALL_COMPAT user of include/uapi/asm-generic
/unistd.h.

The patchset are based on v5.16-rc6, you can compare rv64-compat32
v.s. rv32-whole in qemu with following step:

 - Prepare rv32 rootfs & fw_jump.bin by buildroot.org
   $ git clone git://git.busybox.net/buildroot
   $ cd buildroot
   $ make qemu_riscv32_virt_defconfig O=qemu_riscv32_virt_defconfig
   $ make -C qemu_riscv32_virt_defconfig
   $ make qemu_riscv64_virt_defconfig O=qemu_riscv64_virt_defconfig
   $ make -C qemu_riscv64_virt_defconfig
   (Got fw_jump.bin & rootfs.ext2 in qemu_riscvXX_virt_defconfig/images)

 - Prepare Linux rv32 & rv64 Image
   $ git clone git at github.com:c-sky/csky-linux.git -b riscv_compat_v3 linux
   $ cd linux
   $ echo "CONFIG_STRICT_KERNEL_RWX=n" >> arch/riscv/configs/defconfig
   $ echo "CONFIG_STRICT_MODULE_RWX=n" >> arch/riscv/configs/defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ rv32_defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ Image
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ Image

 - Prepare Qemu: (made by LIU Zhiwei <zhiwei_liu at c-sky.com>)
   $ git clone https://github.com/romanheros/qemu.git -b riscv-upstream-uxl-v7
   $ cd qemu
   $ ./configure --target-list="riscv64-softmmu riscv32-softmmu"
   $ make

 - Run rv64 with rv32 rootfs in compat mode:
   $ ./build/qemu-system-riscv64 -cpu rv64,x-h=true -M virt -m 64m -nographic -bios qemu_riscv64_virt_defconfig/images/fw_jump.bin -kernel build-rv64/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv64-unknown-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.37) #96 SMP Tue Dec 28 21:01:55 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 17 pages/cpu s30696 r8192 d30744 u69632
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15655
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0xffffffcefee00000 - 0xffffffceff000000   (2048 kB)
[    0.000000]       pci io : 0xffffffceff000000 - 0xffffffcf00000000   (  16 MB)
[    0.000000]      vmemmap : 0xffffffcf00000000 - 0xffffffcfffffffff   (4095 MB)
[    0.000000]      vmalloc : 0xffffffd000000000 - 0xffffffdfffffffff   (65535 MB)
[    0.000000]       lowmem : 0xffffffe000000000 - 0xffffffe003e00000   (  62 MB)
[    0.000000]       kernel : 0xffffffff80000000 - 0xffffffffffffffff   (2047 MB)
[    0.000000] Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 64 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv64imafdcsuh
mmu             : sv48

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
# ca[   78.386630] random: fast init done
# cat /proc/meminfo
MemTotal:          53076 kB
MemFree:           40264 kB
MemAvailable:      40244 kB
Buffers:             236 kB
Cached:             1560 kB
SwapCached:            0 kB
Active:             1700 kB
Inactive:            516 kB
Active(anon):         40 kB
Inactive(anon):      424 kB
Active(file):       1660 kB
Inactive(file):       92 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           444 kB
Mapped:             1188 kB
Shmem:                44 kB
KReclaimable:        952 kB
Slab:               5744 kB
SReclaimable:        952 kB
SUnreclaim:         4792 kB
KernelStack:         624 kB
PageTables:          156 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26536 kB
Committed_AS:       1748 kB
VmallocTotal:   67108863 kB
VmallocUsed:         652 kB
VmallocChunk:          0 kB
Percpu:               80 kB
#

 - Run rv32 with rv32 rootfs:
   $ ./build/qemu-system-riscv32 -cpu rv32,x-h=true -M virt -m 64m -nographic -bios qemu_riscv32_virt_defconfig/images/fw_jump.bin -kernel build-rv32/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11-201-g7600ca7960-dirty) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #7 SMP Tue Dec 28 21:02:21 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80400000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 12 pages/cpu s16600 r8192 d24360 u49152
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15240
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0x9dc00000 - 0x9e000000   (4096 kB)
[    0.000000]       pci io : 0x9e000000 - 0x9f000000   (  16 MB)
[    0.000000]      vmemmap : 0x9f000000 - 0x9fffffff   (  15 MB)
[    0.000000]      vmalloc : 0xa0000000 - 0xbfffffff   ( 511 MB)
[    0.000000]       lowmem : 0xc0000000 - 0xc3c00000   (  60 MB)
[    0.000000] Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss, 9516K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 32 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv32imafdcsuh
mmu             : sv32

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
[   79.320589] random: fast init done
# cat /proc/meminfo
MemTotal:          52176 kB
MemFree:           41012 kB
MemAvailable:      42176 kB
Buffers:             644 kB
Cached:             2724 kB
SwapCached:            0 kB
Active:             3128 kB
Inactive:            752 kB
Active(anon):         40 kB
Inactive(anon):      516 kB
Active(file):       3088 kB
Inactive(file):      236 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 4 kB
Writeback:             0 kB
AnonPages:           556 kB
Mapped:             2172 kB
Shmem:                44 kB
KReclaimable:        656 kB
Slab:               3684 kB
SReclaimable:        656 kB
SUnreclaim:         3028 kB
KernelStack:         312 kB
PageTables:           88 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26088 kB
Committed_AS:       2088 kB
VmallocTotal:     524287 kB
VmallocUsed:          12 kB
VmallocChunk:          0 kB
Percpu:               60 kB
#

 Some conclusions:
 - kernel statics:
   64: Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved)
   32: Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss,  9516K reserved)
   rv32 better than rv64:                  1%               22%           17%          13%        19%         11%
   The code size is very similar, but data size rv32 would be better.

 - rv32 kernel runtime KernelStack, Slab... are smaller,
   rv64: MemTotal: 53076 kB,        MemFree: 40264 kB
   rv32: MemTotal: 52176 + 2048 kB, MemFree: 41012  + 2048 kB
   rv32 better than rv64:       2%                         6%

   (Because opensbi problem, we could add another 2MB for rv32.)
   Overall, rv64-compat is 6% worse than rv32-full at memory footprint.
   If the user space memory usage increases, the gap will be further
   reduced.

 - Qemu, kernel, rv32 = rv64 defconfig, rootfs, opensbi
   are the same in this comparison.

Changes in v3:
 - Rebase on newest master (pre linux-5.17-rc1)
 - Using newest qemu version v7 for test
 - Remove fcntl common modification
 - Fixup SET_PERSONALITY in elf.h by Arnd
 - Fixup KVM Kconfig
 - Update Acked-by & Reviewed-by

Changes in v2:
 - Add __ARCH_WANT_COMPAT_STAT suggested
 - Cleanup fcntl compatduplicate definitions
 - Cleanup compat.h
 - Move rv32_defconfig into Makefile
 - Fixup rv64 rootfs boot failed, remove hw_compat_mode_detect
 - Move SYSVIPC_COMPAT into init/Kconfig
 - Simplify compat_elf_check

Guo Ren (17):
  kconfig: Add SYSVIPC_COMPAT for all architectures
  fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
  asm-generic: compat: Cleanup duplicate definitions
  syscalls: compat: Fix the missing part for __SYSCALL_COMPAT
  riscv: Fixup difference with defconfig
  riscv: compat: Add basic compat date type implementation
  riscv: compat: Re-implement TASK_SIZE for COMPAT_32BIT
  riscv: compat: syscall: Add compat_sys_call_table implementation
  riscv: compat: syscall: Add entry.S implementation
  riscv: compat: Add elf.h implementation
  riscv: compat: vdso: Add rv32 VDSO base code implementation
  riscv: compat: vdso: Add setup additional pages implementation
  riscv: compat: signal: Add rt_frame implementation
  riscv: compat: ptrace: Add compat_arch_ptrace implement
  riscv: compat: Add UXL_32 support in start_thread
  riscv: compat: Add COMPAT Kbuild skeletal support
  KVM: compat: riscv: Prevent KVM_COMPAT from being selected

 arch/arm64/Kconfig                            |   4 -
 arch/arm64/include/asm/compat.h               | 108 +-------
 arch/arm64/include/asm/unistd.h               |   1 +
 arch/mips/Kconfig                             |   5 -
 arch/mips/include/asm/compat.h                |  24 +-
 arch/mips/include/asm/unistd.h                |   2 +
 arch/parisc/Kconfig                           |   4 -
 arch/parisc/include/asm/compat.h              |  47 +---
 arch/parisc/include/asm/unistd.h              |   1 +
 arch/powerpc/Kconfig                          |   5 -
 arch/powerpc/include/asm/compat.h             |  47 +---
 arch/powerpc/include/asm/unistd.h             |   1 +
 arch/riscv/Kconfig                            |  19 ++
 arch/riscv/Makefile                           |   9 +
 arch/riscv/configs/rv32_defconfig             | 135 ----------
 arch/riscv/include/asm/compat.h               | 136 ++++++++++
 arch/riscv/include/asm/csr.h                  |   7 +
 arch/riscv/include/asm/elf.h                  |  56 +++-
 arch/riscv/include/asm/mmu.h                  |   1 +
 arch/riscv/include/asm/pgtable.h              |  11 +-
 arch/riscv/include/asm/processor.h            |   6 +
 arch/riscv/include/asm/syscall.h              |   3 +
 arch/riscv/include/asm/thread_info.h          |   1 +
 arch/riscv/include/asm/vdso.h                 |   9 +
 arch/riscv/include/uapi/asm/unistd.h          |   2 +-
 arch/riscv/kernel/Makefile                    |   3 +
 arch/riscv/kernel/compat_signal.c             | 243 ++++++++++++++++++
 arch/riscv/kernel/compat_syscall_table.c      |  72 ++++++
 arch/riscv/kernel/compat_vdso/.gitignore      |   2 +
 arch/riscv/kernel/compat_vdso/Makefile        |  68 +++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |   8 +
 .../kernel/compat_vdso/compat_vdso.lds.S      |   3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |   3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |   5 +
 arch/riscv/kernel/compat_vdso/getcpu.S        |   3 +
 arch/riscv/kernel/compat_vdso/note.S          |   3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |   3 +
 arch/riscv/kernel/entry.S                     |  18 +-
 arch/riscv/kernel/process.c                   |   5 +
 arch/riscv/kernel/ptrace.c                    |  87 ++++++-
 arch/riscv/kernel/signal.c                    |  13 +-
 arch/riscv/kernel/sys_riscv.c                 |   6 +-
 arch/riscv/kernel/vdso.c                      | 104 +++++---
 arch/riscv/kernel/vdso/vdso.S                 |   6 +-
 arch/s390/Kconfig                             |   3 -
 arch/s390/include/asm/compat.h                | 109 +-------
 arch/s390/include/asm/unistd.h                |   1 +
 arch/sparc/Kconfig                            |   5 -
 arch/sparc/include/asm/compat.h               |  39 ++-
 arch/sparc/include/asm/unistd.h               |   1 +
 arch/x86/Kconfig                              |   4 -
 arch/x86/include/asm/compat.h                 | 114 +-------
 arch/x86/include/asm/unistd.h                 |   1 +
 drivers/firmware/efi/libstub/efi-stub.c       |   2 +-
 fs/stat.c                                     |   2 +-
 include/asm-generic/compat.h                  | 122 +++++++++
 include/uapi/asm-generic/unistd.h             |   4 +-
 init/Kconfig                                  |   4 +
 tools/include/uapi/asm-generic/unistd.h       |   4 +-
 virt/kvm/Kconfig                              |   2 +-
 60 files changed, 1082 insertions(+), 634 deletions(-)
 delete mode 100644 arch/riscv/configs/rv32_defconfig
 create mode 100644 arch/riscv/include/asm/compat.h
 create mode 100644 arch/riscv/kernel/compat_signal.c
 create mode 100644 arch/riscv/kernel/compat_syscall_table.c
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:54 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:54 +0800
Subject: [PATCH V3 01/17] kconfig: Add SYSVIPC_COMPAT for all architectures
Message-ID: <20220120073911.99857-2-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

The existing per-arch definitions are pretty much historic cruft.
Move SYSVIPC_COMPAT into init/Kconfig.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Acked-by: Arnd Bergmann <arnd at arndb.de>
Cc: Christoph Hellwig <hch at infradead.org>
---
 arch/arm64/Kconfig   | 4 ----
 arch/mips/Kconfig    | 5 -----
 arch/parisc/Kconfig  | 4 ----
 arch/powerpc/Kconfig | 5 -----
 arch/s390/Kconfig    | 3 ---
 arch/sparc/Kconfig   | 5 -----
 arch/x86/Kconfig     | 4 ----
 init/Kconfig         | 4 ++++
 8 files changed, 4 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f6e333b59314..f0aec4bed837 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2035,10 +2035,6 @@ config DMI
 
 endmenu
 
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on COMPAT && SYSVIPC
-
 menu "Power management options"
 
 source "kernel/power/Kconfig"
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3dd8c4618293..06b2864cee37 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -3177,16 +3177,12 @@ config MIPS32_COMPAT
 config COMPAT
 	bool
 
-config SYSVIPC_COMPAT
-	bool
-
 config MIPS32_O32
 	bool "Kernel support for o32 binaries"
 	depends on 64BIT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT
 	select MIPS32_COMPAT
-	select SYSVIPC_COMPAT if SYSVIPC
 	help
 	  Select this option if you want to run o32 binaries.  These are pure
 	  32-bit binaries as used by the 32-bit Linux/MIPS port.  Most of
@@ -3200,7 +3196,6 @@ config MIPS32_N32
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select COMPAT
 	select MIPS32_COMPAT
-	select SYSVIPC_COMPAT if SYSVIPC
 	help
 	  Select this option if you want to run n32 binaries.  These are
 	  64-bit binaries using 32-bit quantities for addressing and certain
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 43c1c880def6..bc56759d44a2 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -345,10 +345,6 @@ config COMPAT
 	def_bool y
 	depends on 64BIT
 
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on COMPAT && SYSVIPC
-
 config AUDIT_ARCH
 	def_bool y
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0631c9241af3..d6f7d4ab1396 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -297,11 +297,6 @@ config COMPAT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
 
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
 config SCHED_OMIT_FRAME_POINTER
 	bool
 	default y
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index f6a9475cbc8c..1321545104b6 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -460,9 +460,6 @@ config COMPAT
 	  (and some other stuff like libraries and such) is needed for
 	  executing 31 bit applications.  It is safe to say "Y".
 
-config SYSVIPC_COMPAT
-	def_bool y if COMPAT && SYSVIPC
-
 config SMP
 	def_bool y
 
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 66fc08646be5..45401b99d6cb 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -494,9 +494,4 @@ config COMPAT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
 
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
 source "drivers/sbus/char/Kconfig"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 407533c835fe..199ec9d960d0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2869,10 +2869,6 @@ config COMPAT
 if COMPAT
 config COMPAT_FOR_U64_ALIGNMENT
 	def_bool y
-
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on SYSVIPC
 endif
 
 endmenu
diff --git a/init/Kconfig b/init/Kconfig
index e9119bf54b1f..589ccec56571 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -386,6 +386,10 @@ config SYSVIPC_SYSCTL
 	depends on SYSCTL
 	default y
 
+config SYSVIPC_COMPAT
+	def_bool y
+	depends on COMPAT && SYSVIPC
+
 config POSIX_MQUEUE
 	bool "POSIX Message Queues"
 	depends on NET
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:55 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:55 +0800
Subject: [PATCH V3 02/17] fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
Message-ID: <20220120073911.99857-3-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

RISC-V doesn't neeed compat_stat, so using __ARCH_WANT_COMPAT_STAT
to exclude unnecessary SYSCALL functions.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm64/include/asm/unistd.h   | 1 +
 arch/mips/include/asm/unistd.h    | 2 ++
 arch/parisc/include/asm/unistd.h  | 1 +
 arch/powerpc/include/asm/unistd.h | 1 +
 arch/s390/include/asm/unistd.h    | 1 +
 arch/sparc/include/asm/unistd.h   | 1 +
 arch/x86/include/asm/unistd.h     | 1 +
 fs/stat.c                         | 2 +-
 8 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 4e65da3445c7..037feba03a51 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -3,6 +3,7 @@
  * Copyright (C) 2012 ARM Ltd.
  */
 #ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_STAT
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index c2196b1b6604..25a5253db7f4 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -50,6 +50,8 @@
 # ifdef CONFIG_32BIT
 #  define __ARCH_WANT_STAT64
 #  define __ARCH_WANT_SYS_TIME32
+# else
+#  define __ARCH_WANT_COMPAT_STAT
 # endif
 # ifdef CONFIG_MIPS32_O32
 #  define __ARCH_WANT_SYS_TIME32
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..14e0668184cb 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -168,6 +168,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_CLONE3
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
+#define __ARCH_WANT_COMPAT_STAT
 
 #ifdef CONFIG_64BIT
 #define __ARCH_WANT_SYS_TIME
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 5eb462af6766..b1129b4ef57d 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -44,6 +44,7 @@
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_NEWFSTATAT
+#define __ARCH_WANT_COMPAT_STAT
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
 #define __ARCH_WANT_SYS_FORK
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 9e9f75ef046a..4260bc5ce7f8 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -28,6 +28,7 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 # ifdef CONFIG_COMPAT
+#   define __ARCH_WANT_COMPAT_STAT
 #   define __ARCH_WANT_SYS_TIME32
 #   define __ARCH_WANT_SYS_UTIME32
 # endif
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 1e66278ba4a5..d6bc76706a7a 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -46,6 +46,7 @@
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
+#define __ARCH_WANT_COMPAT_STAT
 #endif
 
 #ifdef __32bit_syscall_numbers__
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 80e9d5206a71..761173ccc33c 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -22,6 +22,7 @@
 #  include <asm/unistd_32_ia32.h>
 #  define __ARCH_WANT_SYS_TIME
 #  define __ARCH_WANT_SYS_UTIME
+#  define __ARCH_WANT_COMPAT_STAT
 #  define __ARCH_WANT_COMPAT_SYS_PREADV64
 #  define __ARCH_WANT_COMPAT_SYS_PWRITEV64
 #  define __ARCH_WANT_COMPAT_SYS_PREADV64V2
diff --git a/fs/stat.c b/fs/stat.c
index 28d2020ba1f4..ffdeb9065d53 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -639,7 +639,7 @@ SYSCALL_DEFINE5(statx,
 	return do_statx(dfd, filename, flags, mask, buffer);
 }
 
-#ifdef CONFIG_COMPAT
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)
 static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
 	struct compat_stat tmp;
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:56 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:56 +0800
Subject: [PATCH V3 03/17] asm-generic: compat: Cleanup duplicate definitions
Message-ID: <20220120073911.99857-4-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

There are 7 64bit architectures that support Linux COMPAT mode to
run 32bit applications. A lot of definitions are duplicate:
 - COMPAT_USER_HZ
 - COMPAT_RLIM_INFINITY
 - COMPAT_OFF_T_MAX
 - __compat_uid_t, __compat_uid_t
 - compat_dev_t
 - compat_ipc_pid_t
 - struct compat_flock
 - struct compat_flock64
 - struct compat_statfs
 - struct compat_ipc64_perm, compat_semid64_ds,
	  compat_msqid64_ds, compat_shmid64_ds

Cleanup duplicate definitions and merge them into asm-generic.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm64/include/asm/compat.h   | 108 +++-----------------------
 arch/mips/include/asm/compat.h    |  24 ++----
 arch/parisc/include/asm/compat.h  |  47 ++----------
 arch/powerpc/include/asm/compat.h |  47 ++----------
 arch/s390/include/asm/compat.h    | 109 +++-----------------------
 arch/sparc/include/asm/compat.h   |  39 ++++------
 arch/x86/include/asm/compat.h     | 114 +++-------------------------
 include/asm-generic/compat.h      | 122 ++++++++++++++++++++++++++++++
 8 files changed, 191 insertions(+), 419 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eaa6ca062d89..f54f295efae3 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -5,9 +5,18 @@
 #ifndef __ASM_COMPAT_H
 #define __ASM_COMPAT_H
 
+#define COMPAT_RLIM_INFINITY		0xffffffff
+
 #define compat_mode_t compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
 #include <asm-generic/compat.h>
 
 #ifdef CONFIG_COMPAT
@@ -19,21 +28,15 @@ typedef u16		compat_mode_t;
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 
-#define COMPAT_USER_HZ		100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE	"armv8b\0\0"
 #else
 #define COMPAT_UTS_MACHINE	"armv8l\0\0"
 #endif
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
 typedef u16		__compat_uid16_t;
 typedef u16		__compat_gid16_t;
-typedef u32		compat_dev_t;
 typedef s32		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
 #ifdef __AARCH64EB__
@@ -65,106 +68,13 @@ struct compat_stat {
 	compat_ulong_t	__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 #define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
 #define COMPAT_MINSIGSTKSZ	2048
 
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	unsigned short mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	compat_ulong_t unused1;
-	compat_ulong_t unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused3;
-	compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
 static inline int is_compat_task(void)
 {
 	return test_thread_flag(TIF_32BIT);
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index bbb3bc5a42fd..cc2d76953792 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -9,12 +9,17 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 
+#define __compat_uid_t	__compat_uid_t
 typedef s32		__compat_uid_t;
 typedef s32		__compat_gid_t;
+
+#define __compat_uid32_t __compat_uid32_t
 typedef __compat_uid_t	__compat_uid32_t;
 typedef __compat_gid_t	__compat_gid32_t;
-#define __compat_uid32_t __compat_uid32_t
-#define __compat_gid32_t __compat_gid32_t
+
+#define compat_flock		compat_flock
+#define compat_statfs		compat_statfs
+#define compat_ipc64_perm	compat_ipc64_perm
 
 #define _COMPAT_NSIG		128		/* Don't ask !$@#% ...	*/
 #define _COMPAT_NSIG_BPW	32
@@ -22,12 +27,9 @@ typedef u32		compat_sigset_word;
 
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"mips\0\0\0"
 
-typedef u32		compat_dev_t;
 typedef u32		compat_nlink_t;
-typedef s32		compat_ipc_pid_t;
 typedef struct {
 	s32	val[2];
 } compat_fsid_t;
@@ -69,14 +71,6 @@ struct compat_flock {
 #define F_SETLK64	34
 #define F_SETLKW64	35
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
@@ -92,10 +86,6 @@ struct compat_statfs {
 	int		f_spare[5];
 };
 
-#define COMPAT_RLIM_INFINITY	0x7fffffffUL
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid32_t uid;
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c04f5a637c39..113476345c76 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -8,19 +8,21 @@
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 
+#define COMPAT_RLIM_INFINITY	0xffffffff
+
 #define compat_mode_t compat_mode_t
 typedef u16	compat_mode_t;
 
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16	compat_ipc_pid_t;
+
+#define compat_ipc64_perm compat_ipc64_perm
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ 		100
 #define COMPAT_UTS_MACHINE	"parisc\0\0"
 
-typedef u32	__compat_uid_t;
-typedef u32	__compat_gid_t;
-typedef u32	compat_dev_t;
 typedef u16	compat_nlink_t;
-typedef u16	compat_ipc_pid_t;
 
 struct compat_stat {
 	compat_dev_t		st_dev;	/* dev_t is 32 bits on parisc */
@@ -53,37 +55,6 @@ struct compat_stat {
 	u32			st_spare4[3];
 };
 
-struct compat_flock {
-	short			l_type;
-	short			l_whence;
-	compat_off_t		l_start;
-	compat_off_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_flock64 {
-	short			l_type;
-	short			l_whence;
-	compat_loff_t		l_start;
-	compat_loff_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_statfs {
-	s32		f_type;
-	s32		f_bsize;
-	s32		f_blocks;
-	s32		f_bfree;
-	s32		f_bavail;
-	s32		f_files;
-	s32		f_ffree;
-	__kernel_fsid_t	f_fsid;
-	s32		f_namelen;
-	s32		f_frsize;
-	s32		f_flags;
-	s32		f_spare[4];
-};
-
 struct compat_sigcontext {
 	compat_int_t sc_flags;
 	compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */
@@ -93,10 +64,6 @@ struct compat_sigcontext {
 	compat_int_t sc_sar; /* cr11 */
 };
 
-#define COMPAT_RLIM_INFINITY 0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid_t uid;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 7afc96fb6524..6369c6debc9c 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -8,20 +8,22 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 
+#define COMPAT_RLIM_INFINITY		0xffffffff
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		compat_ipc_pid_t;
+
+#define compat_ipc64_perm compat_ipc64_perm
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #ifdef __BIG_ENDIAN__
 #define COMPAT_UTS_MACHINE	"ppc\0\0"
 #else
 #define COMPAT_UTS_MACHINE	"ppcle\0\0"
 #endif
 
-typedef u32		__compat_uid_t;
-typedef u32		__compat_gid_t;
-typedef u32		compat_dev_t;
 typedef s16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
@@ -44,45 +46,10 @@ struct compat_stat {
 	u32		__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 /*
  * ipc64_perm is actually 32/64bit clean but since the compat layer refers to
  * it we may as well define it.
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index cdc7ae72529d..442829e03c76 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -9,9 +9,21 @@
 #include <linux/sched/task_stack.h>
 #include <linux/thread_info.h>
 
+#define COMPAT_RLIM_INFINITY	0xffffffff
+
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
 #include <asm-generic/compat.h>
 
 #define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
@@ -53,14 +65,9 @@ typedef u16		compat_mode_t;
 			 PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
 			 PSW32_ASC_PRIMARY)
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"s390\0\0\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef u16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 
 typedef struct {
@@ -102,41 +109,10 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64       12
 #define F_SETLK64       13
 #define F_SETLKW64      14    
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_statfs {
-	u32		f_type;
-	u32		f_bsize;
-	u32		f_blocks;
-	u32		f_bfree;
-	u32		f_bavail;
-	u32		f_files;
-	u32		f_ffree;
-	compat_fsid_t	f_fsid;
-	u32		f_namelen;
-	u32		f_frsize;
-	u32		f_flags;
-	u32		f_spare[4];
-};
-
 struct compat_statfs64 {
 	u32		f_type;
 	u32		f_bsize;
@@ -152,10 +128,6 @@ struct compat_statfs64 {
 	u32		f_spare[4];
 };
 
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 /*
  * A pointer passed in from user mode. This should not
  * be used for syscall parameters, just declare them
@@ -178,61 +150,4 @@ static inline int is_compat_task(void)
 
 #endif
 
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	compat_mode_t mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	unsigned int __unused1;
-	unsigned int __unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
 #endif /* _ASM_S390X_COMPAT_H */
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index bd949fcf9d63..44c7d1db3c80 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -9,16 +9,26 @@
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
+#define compat_flock	compat_flock
+#define compat_flock64	compat_flock64
+
+#define compat_ipc64_perm compat_ipc64_perm
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"sparc\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef s16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
@@ -97,25 +107,6 @@ struct compat_flock64 {
 	short		__unused;
 };
 
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY 0x7fffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid32_t uid;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7516e4199b3c..3512a9fbca2b 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -12,19 +12,26 @@
 #include <asm/user32.h>
 #include <asm/unistd.h>
 
+#define COMPAT_RLIM_INFINITY	0xffffffff
+
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"i686\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef u16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
 typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
@@ -50,107 +57,10 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 
-/*
- * IA32 uses 4 byte alignment for 64 bit quantities,
- * so we need to pack this structure.
- */
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-} __attribute__((packed));
-
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	unsigned short mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	compat_ulong_t unused1;
-	compat_ulong_t unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused3;
-	compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
 #ifdef CONFIG_X86_X32_ABI
 #define COMPAT_USE_64BIT_TIME \
 	(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
diff --git a/include/asm-generic/compat.h b/include/asm-generic/compat.h
index d46c0201cc34..5d4cb53e4dfc 100644
--- a/include/asm-generic/compat.h
+++ b/include/asm-generic/compat.h
@@ -2,6 +2,18 @@
 #ifndef __ASM_GENERIC_COMPAT_H
 #define __ASM_GENERIC_COMPAT_H
 
+#ifndef COMPAT_USER_HZ
+#define COMPAT_USER_HZ		100
+#endif
+
+#ifndef COMPAT_RLIM_INFINITY
+#define COMPAT_RLIM_INFINITY	0x7fffffff
+#endif
+
+#ifndef COMPAT_OFF_T_MAX
+#define COMPAT_OFF_T_MAX	0x7fffffff
+#endif
+
 /* These types are common across all compat ABIs */
 typedef u32 compat_size_t;
 typedef s32 compat_ssize_t;
@@ -24,6 +36,11 @@ typedef u32 compat_caddr_t;
 typedef u32 compat_aio_context_t;
 typedef u32 compat_old_sigset_t;
 
+#ifndef __compat_uid_t
+typedef u32 __compat_uid_t;
+typedef u32 __compat_gid_t;
+#endif
+
 #ifndef __compat_uid32_t
 typedef u32 __compat_uid32_t;
 typedef u32 __compat_gid32_t;
@@ -47,4 +64,109 @@ typedef u32 compat_sigset_word;
 #define _COMPAT_NSIG_BPW 32
 #endif
 
+#ifndef compat_dev_t
+typedef u32 compat_dev_t;
+#endif
+
+#ifndef compat_ipc_pid_t
+typedef s32 compat_ipc_pid_t;
+#endif
+
+#ifndef compat_flock
+struct compat_flock {
+	compat_short_t	l_type;
+	compat_short_t	l_whence;
+	compat_off_t	l_start;
+	compat_off_t	l_len;
+	compat_pid_t	l_pid;
+} __attribute__((packed));
+#endif
+
+#ifndef compat_flock64
+struct compat_flock64 {
+	compat_short_t	l_type;
+	compat_short_t	l_whence;
+	compat_loff_t	l_start;
+	compat_loff_t	l_len;
+	compat_pid_t	l_pid;
+} __attribute__((packed));
+#endif
+
+#ifndef compat_statfs
+struct compat_statfs {
+	compat_uint_t	f_type;
+	compat_uint_t	f_bsize;
+	compat_uint_t	f_blocks;
+	compat_uint_t	f_bfree;
+	compat_uint_t	f_bavail;
+	compat_uint_t	f_files;
+	compat_uint_t	f_ffree;
+	__kernel_fsid_t	f_fsid;
+	compat_uint_t	f_namelen;
+	compat_uint_t	f_frsize;
+	compat_uint_t	f_flags;
+	compat_uint_t	f_spare[4];
+} __attribute__((packed));
+#endif
+
+#ifndef compat_ipc64_perm
+struct compat_ipc64_perm {
+	compat_key_t key;
+	__compat_uid32_t uid;
+	__compat_gid32_t gid;
+	__compat_uid32_t cuid;
+	__compat_gid32_t cgid;
+	compat_mode_t	mode;
+	unsigned char	__pad1[4 - sizeof(compat_mode_t)];
+	compat_ushort_t	seq;
+	compat_ushort_t	__pad2;
+	compat_ulong_t	unused1;
+	compat_ulong_t	unused2;
+} __attribute__((packed));
+
+struct compat_semid64_ds {
+	struct compat_ipc64_perm sem_perm;
+	compat_ulong_t sem_otime;
+	compat_ulong_t sem_otime_high;
+	compat_ulong_t sem_ctime;
+	compat_ulong_t sem_ctime_high;
+	compat_ulong_t sem_nsems;
+	compat_ulong_t __unused3;
+	compat_ulong_t __unused4;
+} __attribute__((packed));
+
+struct compat_msqid64_ds {
+	struct compat_ipc64_perm msg_perm;
+	compat_ulong_t msg_stime;
+	compat_ulong_t msg_stime_high;
+	compat_ulong_t msg_rtime;
+	compat_ulong_t msg_rtime_high;
+	compat_ulong_t msg_ctime;
+	compat_ulong_t msg_ctime_high;
+	compat_ulong_t msg_cbytes;
+	compat_ulong_t msg_qnum;
+	compat_ulong_t msg_qbytes;
+	compat_pid_t   msg_lspid;
+	compat_pid_t   msg_lrpid;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+} __attribute__((packed));
+
+struct compat_shmid64_ds {
+	struct compat_ipc64_perm shm_perm;
+	compat_size_t  shm_segsz;
+	compat_ulong_t shm_atime;
+	compat_ulong_t shm_atime_high;
+	compat_ulong_t shm_dtime;
+	compat_ulong_t shm_dtime_high;
+	compat_ulong_t shm_ctime;
+	compat_ulong_t shm_ctime_high;
+	compat_pid_t   shm_cpid;
+	compat_pid_t   shm_lpid;
+	compat_ulong_t shm_nattch;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+} __attribute__((packed));
+#endif
+
 #endif
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:57 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:57 +0800
Subject: [PATCH V3 04/17] syscalls: compat: Fix the missing part for
 __SYSCALL_COMPAT
Message-ID: <20220120073911.99857-5-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Make "uapi asm unistd.h" could be used for architectures' COMPAT
mode. The __SYSCALL_COMPAT is first used in riscv.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 include/uapi/asm-generic/unistd.h       | 4 ++--
 tools/include/uapi/asm-generic/unistd.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 1c48b0ae3ba3..45fa180cc56a 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
 
 /* kernel/ptrace.c */
 #define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
+__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
 
 /* kernel/sched/core.c */
 #define __NR_sched_setparam 118
@@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
 #define __NR_kexec_file_load 294
 __SYSCALL(__NR_kexec_file_load,     sys_kexec_file_load)
 /* 295 through 402 are unassigned to sync up with generic numbers, don't use */
-#if __BITS_PER_LONG == 32
+#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
 #define __NR_clock_gettime64 403
 __SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
 #define __NR_clock_settime64 404
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index 4557a8b6086f..aafe5cfeb27c 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
 
 /* kernel/ptrace.c */
 #define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
+__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
 
 /* kernel/sched/core.c */
 #define __NR_sched_setparam 118
@@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
 #define __NR_kexec_file_load 294
 __SYSCALL(__NR_kexec_file_load,     sys_kexec_file_load)
 /* 295 through 402 are unassigned to sync up with generic numbers, don't use */
-#if __BITS_PER_LONG == 32
+#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
 #define __NR_clock_gettime64 403
 __SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
 #define __NR_clock_settime64 404
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:58 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:58 +0800
Subject: [PATCH V3 05/17] riscv: Fixup difference with defconfig
Message-ID: <20220120073911.99857-6-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Let's follow the origin patch's spirit:

The only difference between rv32_defconfig and defconfig is that
rv32_defconfig has  CONFIG_ARCH_RV32I=y.

This is helpful to compare rv64-compat-rv32 v.s. rv32-linux.

Fixes: 1b937e8faa87ccfb ("RISC-V: Add separate defconfig for 32bit systems")
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Anup Patel <anup.patel at wdc.com>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/Makefile               |   4 +
 arch/riscv/configs/rv32_defconfig | 135 ------------------------------
 2 files changed, 4 insertions(+), 135 deletions(-)
 delete mode 100644 arch/riscv/configs/rv32_defconfig

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8a107ed18b0d..a02e588c4947 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -148,3 +148,7 @@ PHONY += rv64_randconfig
 rv64_randconfig:
 	$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \
 		-f $(srctree)/Makefile randconfig
+
+PHONY += rv32_defconfig
+rv32_defconfig:
+	$(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig
deleted file mode 100644
index 8b56a7f1eb06..000000000000
--- a/arch/riscv/configs/rv32_defconfig
+++ /dev/null
@@ -1,135 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BPF_SYSCALL=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_CGROUP_BPF=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_SOC_SIFIVE=y
-CONFIG_SOC_VIRT=y
-CONFIG_ARCH_RV32I=y
-CONFIG_SMP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_VIRTUALIZATION=y
-CONFIG_KVM=m
-CONFIG_JUMP_LABEL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NETLINK_DIAG=y
-CONFIG_NET_9P=y
-CONFIG_NET_9P_VIRTIO=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCIE_XILINX=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_SCSI_VIRTIO=y
-CONFIG_ATA=y
-CONFIG_SATA_AHCI=y
-CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_NETDEVICES=y
-CONFIG_VIRTIO_NET=y
-CONFIG_MACB=y
-CONFIG_E1000E=y
-CONFIG_R8169=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_VIRTIO_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_VIRTIO=y
-CONFIG_SPI=y
-CONFIG_SPI_SIFIVE=y
-# CONFIG_PTP_1588_CLOCK is not set
-CONFIG_DRM=y
-CONFIG_DRM_RADEON=y
-CONFIG_DRM_VIRTIO_GPU=y
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_USB=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_UAS=y
-CONFIG_MMC=y
-CONFIG_MMC_SPI=y
-CONFIG_RTC_CLASS=y
-CONFIG_VIRTIO_PCI=y
-CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_INPUT=y
-CONFIG_VIRTIO_MMIO=y
-CONFIG_RPMSG_CHAR=y
-CONFIG_RPMSG_VIRTIO=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_NFS_V4_2=y
-CONFIG_ROOT_NFS=y
-CONFIG_9P_FS=y
-CONFIG_CRYPTO_USER_API_HASH=y
-CONFIG_CRYPTO_DEV_VIRTIO=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_SCHED_STACK_END_CHECK=y
-CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_VM_PGFLAGS=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_PER_CPU_MAPS=y
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_PLIST=y
-CONFIG_DEBUG_SG=y
-# CONFIG_RCU_TRACE is not set
-CONFIG_RCU_EQS_DEBUG=y
-# CONFIG_FTRACE is not set
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_MEMTEST=y
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:38:59 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:38:59 +0800
Subject: [PATCH V3 06/17] riscv: compat: Add basic compat date type
 implementation
Message-ID: <20220120073911.99857-7-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement asm/compat.h for struct compat_xxx, RLIM_INFINITY,
OFF_T_MAX, is_compat_task, compat_user_regset, regset convert.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/compat.h      | 136 +++++++++++++++++++++++++++
 arch/riscv/include/asm/thread_info.h |   1 +
 2 files changed, 137 insertions(+)
 create mode 100644 arch/riscv/include/asm/compat.h

diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
new file mode 100644
index 000000000000..12f6b612c7da
--- /dev/null
+++ b/arch/riscv/include/asm/compat.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_COMPAT_H
+#define __ASM_COMPAT_H
+
+#define compat_mode_t	compat_mode_t
+typedef u16		compat_mode_t;
+
+#define COMPAT_UTS_MACHINE	"riscv\0\0"
+
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/sched/task_stack.h>
+#include <asm-generic/compat.h>
+
+#define F_GETLK64	12
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+static inline int is_compat_task(void)
+{
+	return test_thread_flag(TIF_32BIT);
+}
+
+struct compat_user_regs_struct {
+	compat_ulong_t pc;
+	compat_ulong_t ra;
+	compat_ulong_t sp;
+	compat_ulong_t gp;
+	compat_ulong_t tp;
+	compat_ulong_t t0;
+	compat_ulong_t t1;
+	compat_ulong_t t2;
+	compat_ulong_t s0;
+	compat_ulong_t s1;
+	compat_ulong_t a0;
+	compat_ulong_t a1;
+	compat_ulong_t a2;
+	compat_ulong_t a3;
+	compat_ulong_t a4;
+	compat_ulong_t a5;
+	compat_ulong_t a6;
+	compat_ulong_t a7;
+	compat_ulong_t s2;
+	compat_ulong_t s3;
+	compat_ulong_t s4;
+	compat_ulong_t s5;
+	compat_ulong_t s6;
+	compat_ulong_t s7;
+	compat_ulong_t s8;
+	compat_ulong_t s9;
+	compat_ulong_t s10;
+	compat_ulong_t s11;
+	compat_ulong_t t3;
+	compat_ulong_t t4;
+	compat_ulong_t t5;
+	compat_ulong_t t6;
+};
+
+static inline void regs_to_cregs(struct compat_user_regs_struct *cregs,
+				 struct pt_regs *regs)
+{
+	cregs->pc	= (compat_ulong_t) regs->epc;
+	cregs->ra	= (compat_ulong_t) regs->ra;
+	cregs->sp	= (compat_ulong_t) regs->sp;
+	cregs->gp	= (compat_ulong_t) regs->gp;
+	cregs->tp	= (compat_ulong_t) regs->tp;
+	cregs->t0	= (compat_ulong_t) regs->t0;
+	cregs->t1	= (compat_ulong_t) regs->t1;
+	cregs->t2	= (compat_ulong_t) regs->t2;
+	cregs->s0	= (compat_ulong_t) regs->s0;
+	cregs->s1	= (compat_ulong_t) regs->s1;
+	cregs->a0	= (compat_ulong_t) regs->a0;
+	cregs->a1	= (compat_ulong_t) regs->a1;
+	cregs->a2	= (compat_ulong_t) regs->a2;
+	cregs->a3	= (compat_ulong_t) regs->a3;
+	cregs->a4	= (compat_ulong_t) regs->a4;
+	cregs->a5	= (compat_ulong_t) regs->a5;
+	cregs->a6	= (compat_ulong_t) regs->a6;
+	cregs->a7	= (compat_ulong_t) regs->a7;
+	cregs->s2	= (compat_ulong_t) regs->s2;
+	cregs->s3	= (compat_ulong_t) regs->s3;
+	cregs->s4	= (compat_ulong_t) regs->s4;
+	cregs->s5	= (compat_ulong_t) regs->s5;
+	cregs->s6	= (compat_ulong_t) regs->s6;
+	cregs->s7	= (compat_ulong_t) regs->s7;
+	cregs->s8	= (compat_ulong_t) regs->s8;
+	cregs->s9	= (compat_ulong_t) regs->s9;
+	cregs->s10	= (compat_ulong_t) regs->s10;
+	cregs->s11	= (compat_ulong_t) regs->s11;
+	cregs->t3	= (compat_ulong_t) regs->t3;
+	cregs->t4	= (compat_ulong_t) regs->t4;
+	cregs->t5	= (compat_ulong_t) regs->t5;
+	cregs->t6	= (compat_ulong_t) regs->t6;
+};
+
+static inline void cregs_to_regs(struct compat_user_regs_struct *cregs,
+				 struct pt_regs *regs)
+{
+	regs->epc	= (unsigned long) cregs->pc;
+	regs->ra	= (unsigned long) cregs->ra;
+	regs->sp	= (unsigned long) cregs->sp;
+	regs->gp	= (unsigned long) cregs->gp;
+	regs->tp	= (unsigned long) cregs->tp;
+	regs->t0	= (unsigned long) cregs->t0;
+	regs->t1	= (unsigned long) cregs->t1;
+	regs->t2	= (unsigned long) cregs->t2;
+	regs->s0	= (unsigned long) cregs->s0;
+	regs->s1	= (unsigned long) cregs->s1;
+	regs->a0	= (unsigned long) cregs->a0;
+	regs->a1	= (unsigned long) cregs->a1;
+	regs->a2	= (unsigned long) cregs->a2;
+	regs->a3	= (unsigned long) cregs->a3;
+	regs->a4	= (unsigned long) cregs->a4;
+	regs->a5	= (unsigned long) cregs->a5;
+	regs->a6	= (unsigned long) cregs->a6;
+	regs->a7	= (unsigned long) cregs->a7;
+	regs->s2	= (unsigned long) cregs->s2;
+	regs->s3	= (unsigned long) cregs->s3;
+	regs->s4	= (unsigned long) cregs->s4;
+	regs->s5	= (unsigned long) cregs->s5;
+	regs->s6	= (unsigned long) cregs->s6;
+	regs->s7	= (unsigned long) cregs->s7;
+	regs->s8	= (unsigned long) cregs->s8;
+	regs->s9	= (unsigned long) cregs->s9;
+	regs->s10	= (unsigned long) cregs->s10;
+	regs->s11	= (unsigned long) cregs->s11;
+	regs->t3	= (unsigned long) cregs->t3;
+	regs->t4	= (unsigned long) cregs->t4;
+	regs->t5	= (unsigned long) cregs->t5;
+	regs->t6	= (unsigned long) cregs->t6;
+};
+
+#endif /* __ASM_COMPAT_H */
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 60da0dcacf14..9392e35c689d 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -91,6 +91,7 @@ struct thread_info {
 #define TIF_SECCOMP		8	/* syscall secure computing */
 #define TIF_NOTIFY_SIGNAL	9	/* signal notifications exist */
 #define TIF_UPROBE		10	/* uprobe breakpoint or singlestep */
+#define TIF_32BIT		11	/* 32bit process */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:00 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:00 +0800
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
Message-ID: <20220120073911.99857-8-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Make TASK_SIZE from const to dynamic detect TIF_32BIT flag
function. Refer to arm64 to implement DEFAULT_MAP_WINDOW_64 for
efi-stub.

Limit 32-bit compatible process in 0-2GB virtual address range
(which is enough for real scenarios), because it could avoid
address sign extend problem when 32-bit enter 64-bit and ease
software design.

The standard 32-bit TASK_SIZE is 0x9dc00000:FIXADDR_START, and
compared to a compatible 32-bit, it increases 476MB for the
application's virtual address.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/pgtable.h        | 11 ++++++++++-
 arch/riscv/include/asm/processor.h      |  6 ++++++
 drivers/firmware/efi/libstub/efi-stub.c |  2 +-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 67f687aee673..e0add598e66a 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -669,7 +669,16 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
  * Note that PGDIR_SIZE must evenly divide TASK_SIZE.
  */
 #ifdef CONFIG_64BIT
-#define TASK_SIZE (PGDIR_SIZE * PTRS_PER_PGD / 2)
+#define TASK_SIZE_64	(PGDIR_SIZE * PTRS_PER_PGD / 2)
+
+#ifdef CONFIG_COMPAT
+#define TASK_SIZE_32	(_AC(0x80000000, UL) - PAGE_SIZE)
+#define TASK_SIZE	(test_thread_flag(TIF_32BIT) ? \
+			 TASK_SIZE_32 : TASK_SIZE_64)
+#else
+#define TASK_SIZE	TASK_SIZE_64
+#endif
+
 #else
 #define TASK_SIZE FIXADDR_START
 #endif
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 0749924d9e55..8649436b8fcf 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -61,6 +61,12 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
 extern void start_thread(struct pt_regs *regs,
 			unsigned long pc, unsigned long sp);
 
+#ifdef CONFIG_COMPAT
+#define DEFAULT_MAP_WINDOW_64 TASK_SIZE_64
+#else
+#define DEFAULT_MAP_WINDOW_64 TASK_SIZE
+#endif
+
 /* Free all resources held by a thread. */
 static inline void release_thread(struct task_struct *dead_task)
 {
diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index e87e7f1b1a33..f57f85646a45 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c
@@ -38,7 +38,7 @@
 #define EFI_RT_VIRTUAL_BASE	SZ_512M
 #define EFI_RT_VIRTUAL_SIZE	SZ_512M
 
-#ifdef CONFIG_ARM64
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
 # define EFI_RT_VIRTUAL_LIMIT	DEFAULT_MAP_WINDOW_64
 #else
 # define EFI_RT_VIRTUAL_LIMIT	TASK_SIZE
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:01 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:01 +0800
Subject: [PATCH V3 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
Message-ID: <20220120073911.99857-9-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement compat_syscall_table.c with compat_sys_call_table & fixup
system call such as truncate64,pread64,fallocate which need two
regs to indicate 64bit-arg (copied from arm64).

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/syscall.h         |  3 +
 arch/riscv/include/uapi/asm/unistd.h     |  2 +-
 arch/riscv/kernel/Makefile               |  1 +
 arch/riscv/kernel/compat_syscall_table.c | 72 ++++++++++++++++++++++++
 arch/riscv/kernel/sys_riscv.c            |  6 +-
 5 files changed, 81 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/kernel/compat_syscall_table.c

diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 7ac6a0e275f2..4ff98a22ef24 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -16,6 +16,9 @@
 
 /* The array of function pointers for syscalls. */
 extern void * const sys_call_table[];
+#ifdef CONFIG_COMPAT
+extern void * const compat_sys_call_table[];
+#endif
 
 /*
  * Only the low 32 bits of orig_r0 are meaningful, so we return int.
diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
index 8062996c2dfd..c9e50eed14aa 100644
--- a/arch/riscv/include/uapi/asm/unistd.h
+++ b/arch/riscv/include/uapi/asm/unistd.h
@@ -15,7 +15,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#ifdef __LP64__
+#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
 #define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SET_GET_RLIMIT
 #endif /* __LP64__ */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 3397ddac1a30..1f2111179615 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
+obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
diff --git a/arch/riscv/kernel/compat_syscall_table.c b/arch/riscv/kernel/compat_syscall_table.c
new file mode 100644
index 000000000000..53905947678e
--- /dev/null
+++ b/arch/riscv/kernel/compat_syscall_table.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define __SYSCALL_COMPAT
+
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <asm-generic/mman-common.h>
+#include <asm-generic/syscalls.h>
+#include <asm/syscall.h>
+
+#define arg_u32p(name)  u32, name##_lo, u32, name##_hi
+
+#define arg_u64(name)   (((u64)name##_hi << 32) | \
+			 ((u64)name##_lo & 0xffffffff))
+
+COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
+		       arg_u32p(length))
+{
+	return ksys_truncate(pathname, arg_u64(length));
+}
+
+COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, arg_u32p(length))
+{
+	return ksys_ftruncate(fd, arg_u64(length));
+}
+
+COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
+		       arg_u32p(offset), arg_u32p(len))
+{
+	return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
+}
+
+COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
+		       size_t, count, arg_u32p(pos))
+{
+	return ksys_pread64(fd, buf, count, arg_u64(pos));
+}
+
+COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd,
+		       const char __user *, buf, size_t, count, arg_u32p(pos))
+{
+	return ksys_pwrite64(fd, buf, count, arg_u64(pos));
+}
+
+COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, arg_u32p(offset),
+		       arg_u32p(nbytes), unsigned int, flags)
+{
+	return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes),
+				    flags);
+}
+
+COMPAT_SYSCALL_DEFINE4(readahead, int, fd, arg_u32p(offset),
+		       size_t, count)
+{
+	return ksys_readahead(fd, arg_u64(offset), count);
+}
+
+COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, int, advice, arg_u32p(offset),
+		       arg_u32p(len))
+{
+	return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice);
+}
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call)      [nr] = (call),
+
+asmlinkage long compat_sys_rt_sigreturn(void);
+
+void * const compat_sys_call_table[__NR_syscalls] = {
+	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 12f8a7fce78b..9c0194f176fc 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -33,7 +33,9 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
 {
 	return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0);
 }
-#else
+#endif
+
+#if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags,
 	unsigned long, fd, off_t, offset)
@@ -44,7 +46,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 	 */
 	return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 12);
 }
-#endif /* !CONFIG_64BIT */
+#endif
 
 /*
  * Allows the instruction cache to be flushed from userspace.  Despite RISC-V
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:02 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:02 +0800
Subject: [PATCH V3 09/17] riscv: compat: syscall: Add entry.S implementation
Message-ID: <20220120073911.99857-10-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement the entry of compat_sys_call_table[] in asm. Ref to
riscv-privileged spec 4.1.1 Supervisor Status Register (sstatus):

 BIT[32:33] = UXL[1:0]:
 - 1:32
 - 2:64
 - 3:128

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/csr.h |  7 +++++++
 arch/riscv/kernel/entry.S    | 18 ++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 5046f431645c..7dac12366833 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -36,6 +36,13 @@
 #define SR_SD		_AC(0x8000000000000000, UL) /* FS/XS dirty */
 #endif
 
+#ifdef CONFIG_COMPAT
+#define SR_UXL		_AC(0x300000000, UL) /* XLEN mask for U-mode */
+#define SR_UXL_32	_AC(0x100000000, UL) /* XLEN = 32 for U-mode */
+#define SR_UXL_64	_AC(0x200000000, UL) /* XLEN = 64 for U-mode */
+#define SR_UXL_SHIFT	32
+#endif
+
 /* SATP flags */
 #ifndef CONFIG_64BIT
 #define SATP_PPN	_AC(0x003FFFFF, UL)
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index ed29e9c8f660..1951743f09b3 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -207,13 +207,27 @@ check_syscall_nr:
 	 * Syscall number held in a7.
 	 * If syscall number is above allowed value, redirect to ni_syscall.
 	 */
-	bgeu a7, t0, 1f
+	bgeu a7, t0, 3f
+#ifdef CONFIG_COMPAT
+	REG_L s0, PT_STATUS(sp)
+	srli s0, s0, SR_UXL_SHIFT
+	andi s0, s0, (SR_UXL >> SR_UXL_SHIFT)
+	li t0, (SR_UXL_32 >> SR_UXL_SHIFT)
+	sub t0, s0, t0
+	bnez t0, 1f
+
+	/* Call compat_syscall */
+	la s0, compat_sys_call_table
+	j 2f
+1:
+#endif
 	/* Call syscall */
 	la s0, sys_call_table
+2:
 	slli t0, a7, RISCV_LGPTR
 	add s0, s0, t0
 	REG_L s0, 0(s0)
-1:
+3:
 	jalr s0
 
 ret_from_syscall:
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:03 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:03 +0800
Subject: [PATCH V3 10/17] riscv: compat: Add elf.h implementation
Message-ID: <20220120073911.99857-11-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement necessary type and macro for compat elf. See the code
comment for detail.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/elf.h | 51 +++++++++++++++++++++++++++++++++++-
 1 file changed, 50 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index f53c40026c7a..353b4589c79c 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -8,6 +8,8 @@
 #ifndef _ASM_RISCV_ELF_H
 #define _ASM_RISCV_ELF_H
 
+#include <uapi/linux/elf.h>
+#include <linux/compat.h>
 #include <uapi/asm/elf.h>
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
@@ -18,11 +20,13 @@
  */
 #define ELF_ARCH	EM_RISCV
 
+#ifndef ELF_CLASS
 #ifdef CONFIG_64BIT
 #define ELF_CLASS	ELFCLASS64
 #else
 #define ELF_CLASS	ELFCLASS32
 #endif
+#endif
 
 #define ELF_DATA	ELFDATA2LSB
 
@@ -31,6 +35,15 @@
  */
 #define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
 
+#ifdef CONFIG_COMPAT
+/*
+ * Use the same code with elf_check_arch, because elf32_hdr &
+ * elf64_hdr e_machine's offset are different. The checker is
+ * a little bit simple compare to other architectures.
+ */
+#define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
+#endif
+
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	(PAGE_SIZE)
 
@@ -43,8 +56,14 @@
 #define ELF_ET_DYN_BASE		((TASK_SIZE / 3) * 2)
 
 #ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
+#define STACK_RND_MASK		(test_thread_flag(TIF_32BIT) ? \
+				 0x7ff >> (PAGE_SHIFT - 12) : \
+				 0x3ffff >> (PAGE_SHIFT - 12))
+#else
 #define STACK_RND_MASK		(0x3ffff >> (PAGE_SHIFT - 12))
 #endif
+#endif
 /*
  * This yields a mask that user programs can use to figure out what
  * instruction set this CPU supports.  This could be done in user space,
@@ -60,11 +79,19 @@ extern unsigned long elf_hwcap;
  */
 #define ELF_PLATFORM	(NULL)
 
+#define COMPAT_ELF_PLATFORM	(NULL)
+
 #ifdef CONFIG_MMU
 #define ARCH_DLINFO						\
 do {								\
+	/*							\
+	 * Note that we add ulong after elf_addr_t because	\
+	 * casting current->mm->context.vdso triggers a cast	\
+	 * warning of cast from pointer to integer for		\
+	 * COMPAT ELFCLASS32.					\
+	 */							\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
-		(elf_addr_t)current->mm->context.vdso);		\
+		(elf_addr_t)(ulong)current->mm->context.vdso);	\
 	NEW_AUX_ENT(AT_L1I_CACHESIZE,				\
 		get_cache_size(1, CACHE_TYPE_INST));		\
 	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,			\
@@ -90,4 +117,26 @@ do {							\
 		*(struct user_regs_struct *)regs;	\
 } while (0);
 
+#ifdef CONFIG_COMPAT
+
+/*
+ * FIXME: not sure SET_PERSONALITY for compat process is right!
+ */
+#define SET_PERSONALITY(ex)					\
+do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
+		set_thread_flag(TIF_32BIT);			\
+	else							\
+		clear_thread_flag(TIF_32BIT);			\
+	if (personality(current->personality) != PER_LINUX32)	\
+		set_personality(PER_LINUX |			\
+			(current->personality & (~PER_MASK)));	\
+} while (0)
+
+#define COMPAT_ELF_ET_DYN_BASE		((TASK_SIZE_32 / 3) * 2)
+
+/* rv32 registers */
+typedef compat_ulong_t			compat_elf_greg_t;
+typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
+
+#endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:04 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:04 +0800
Subject: [PATCH V3 11/17] riscv: compat: vdso: Add rv32 VDSO base code
 implementation
Message-ID: <20220120073911.99857-12-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

There is no vgettimeofday supported in rv32 that makes simple to
generate rv32 vdso code which only needs riscv64 compiler. Other
architectures need change compiler or -m (machine parameter) to
support vdso32 compiling. If rv32 support vgettimeofday (which
cause C compile) in future, we would add CROSS_COMPILE to support
that makes more requirement on compiler enviornment.

linux-rv64/arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:
file format elf64-littleriscv

Disassembly of section .text:

0000000000000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

000000000000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

0000000000000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

linux-rv32/arch/riscv/kernel/vdso/vdso.so.dbg:
file format elf32-littleriscv

Disassembly of section .text:

00000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

0000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

00000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

Finally, reuse all *.S from vdso in compat_vdso that makes
implementation clear and readable.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/Makefile                           |  5 ++
 arch/riscv/include/asm/vdso.h                 |  9 +++
 arch/riscv/kernel/Makefile                    |  1 +
 arch/riscv/kernel/compat_vdso/.gitignore      |  2 +
 arch/riscv/kernel/compat_vdso/Makefile        | 68 +++++++++++++++++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |  8 +++
 .../kernel/compat_vdso/compat_vdso.lds.S      |  3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |  3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |  5 ++
 arch/riscv/kernel/compat_vdso/getcpu.S        |  3 +
 arch/riscv/kernel/compat_vdso/note.S          |  3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |  3 +
 arch/riscv/kernel/vdso/vdso.S                 |  6 +-
 13 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index a02e588c4947..f73d50552e09 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -106,12 +106,17 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 PHONY += vdso_install
 vdso_install:
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso $@)
 
 ifeq ($(KBUILD_EXTMOD),)
 ifeq ($(CONFIG_MMU),y)
 prepare: vdso_prepare
 vdso_prepare: prepare0
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
+
 endif
 endif
 
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index bc6f75f3a199..af981426fe0f 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -21,6 +21,15 @@
 
 #define VDSO_SYMBOL(base, name)							\
 	(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
+
+#ifdef CONFIG_COMPAT
+#include <generated/compat_vdso-offsets.h>
+
+#define COMPAT_VDSO_SYMBOL(base, name)						\
+	(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
+
+#endif /* CONFIG_COMPAT */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* CONFIG_MMU */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 1f2111179615..59cf97faddae 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -66,3 +66,4 @@ obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
 obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
+obj-$(CONFIG_COMPAT)		+= compat_vdso/
diff --git a/arch/riscv/kernel/compat_vdso/.gitignore b/arch/riscv/kernel/compat_vdso/.gitignore
new file mode 100644
index 000000000000..19d83d846c1e
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+compat_vdso.lds
diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
new file mode 100644
index 000000000000..7bbbbf94307f
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_RISCV_32|R_RISCV_64|R_RISCV_JUMP_SLOT
+include $(srctree)/lib/vdso/Makefile
+# Symbols present in the compat_vdso
+compat_vdso-syms  = rt_sigreturn
+compat_vdso-syms += getcpu
+compat_vdso-syms += flush_icache
+
+# Files to link into the compat_vdso
+obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
+
+ccflags-y := -fno-stack-protector
+
+# Build rules
+targets := $(obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
+obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))
+
+obj-y += compat_vdso.o
+CPPFLAGS_compat_vdso.lds += -P -C -U$(ARCH)
+
+# Disable profiling and instrumentation for VDSO code
+GCOV_PROFILE := n
+KCOV_INSTRUMENT := n
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
+
+# Force dependency
+$(obj)/compat_vdso.o: $(obj)/compat_vdso.so
+
+# link rule for the .so file, .lds has to be first
+$(obj)/compat_vdso.so.dbg: $(obj)/compat_vdso.lds $(obj-compat_vdso) FORCE
+	$(call if_changed,compat_vdsold)
+LDFLAGS_compat_vdso.so.dbg = -shared -S -soname=linux-compat_vdso.so.1 \
+	--build-id=sha1 --hash-style=both --eh-frame-hdr
+
+# strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+# Generate VDSO offsets using helper script
+gen-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
+quiet_cmd_compat_vdsosym = VDSOSYM $@
+	cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) | LC_ALL=C sort > $@
+
+include/generated/compat_vdso-offsets.h: $(obj)/compat_vdso.so.dbg FORCE
+	$(call if_changed,compat_vdsosym)
+
+# actual build commands
+# The DSO images are built using a special linker script
+# Make sure only to export the intended __compat_vdso_xxx symbol offsets.
+quiet_cmd_compat_vdsold = VDSOLD  $@
+      cmd_compat_vdsold = $(LD) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
+                   $(OBJCOPY) $(patsubst %, -G __compat_vdso_%, $(compat_vdso-syms)) $@.tmp $@ && \
+                   rm $@.tmp
+
+# install commands for the unstripped file
+quiet_cmd_compat_vdso_install = INSTALL $@
+      cmd_compat_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/compat_vdso/$@
+
+compat_vdso.so: $(obj)/compat_vdso.so.dbg
+	@mkdir -p $(MODLIB)/compat_vdso
+	$(call cmd,compat_vdso_install)
+
+compat_vdso_install: compat_vdso.so
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.S b/arch/riscv/kernel/compat_vdso/compat_vdso.S
new file mode 100644
index 000000000000..fea4a8b0c45d
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define	vdso_start	compat_vdso_start
+#define	vdso_end	compat_vdso_end
+
+#define	__VDSO_PATH	"arch/riscv/kernel/compat_vdso/compat_vdso.so"
+
+#include <../vdso/vdso.S>
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
new file mode 100644
index 000000000000..02a9ec5dc7f6
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/vdso.lds.S>
diff --git a/arch/riscv/kernel/compat_vdso/flush_icache.S b/arch/riscv/kernel/compat_vdso/flush_icache.S
new file mode 100644
index 000000000000..88e21a84a974
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/flush_icache.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/flush_icache.S>
diff --git a/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
new file mode 100755
index 000000000000..8ac070c783b3
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+LC_ALL=C
+sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define compat\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/compat_vdso/getcpu.S b/arch/riscv/kernel/compat_vdso/getcpu.S
new file mode 100644
index 000000000000..946449a15a94
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/getcpu.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/getcpu.S>
diff --git a/arch/riscv/kernel/compat_vdso/note.S b/arch/riscv/kernel/compat_vdso/note.S
new file mode 100644
index 000000000000..67c50898b8e5
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/note.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/note.S>
diff --git a/arch/riscv/kernel/compat_vdso/rt_sigreturn.S b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
new file mode 100644
index 000000000000..f4c98f18c053
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/rt_sigreturn.S>
diff --git a/arch/riscv/kernel/vdso/vdso.S b/arch/riscv/kernel/vdso/vdso.S
index df222245be05..83f1c899e8d8 100644
--- a/arch/riscv/kernel/vdso/vdso.S
+++ b/arch/riscv/kernel/vdso/vdso.S
@@ -7,12 +7,16 @@
 #include <linux/linkage.h>
 #include <asm/page.h>
 
+#ifndef __VDSO_PATH
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
+#endif
+
 	__PAGE_ALIGNED_DATA
 
 	.globl vdso_start, vdso_end
 	.balign PAGE_SIZE
 vdso_start:
-	.incbin "arch/riscv/kernel/vdso/vdso.so"
+	.incbin __VDSO_PATH
 	.balign PAGE_SIZE
 vdso_end:
 
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:05 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:05 +0800
Subject: [PATCH V3 12/17] riscv: compat: vdso: Add setup additional pages
 implementation
Message-ID: <20220120073911.99857-13-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Reconstruct __setup_additional_pages() by appending vdso info
pointer argument to meet compat_vdso_info requirement. And change
vm_special_mapping *dm, *cm initialization into static.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/elf.h |   5 ++
 arch/riscv/include/asm/mmu.h |   1 +
 arch/riscv/kernel/vdso.c     | 104 +++++++++++++++++++++++++----------
 3 files changed, 81 insertions(+), 29 deletions(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 353b4589c79c..c2a7e22637eb 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -138,5 +138,10 @@ do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
 typedef compat_ulong_t			compat_elf_greg_t;
 typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
 
+extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+					      int uses_interp);
+#define compat_arch_setup_additional_pages \
+				compat_arch_setup_additional_pages
+
 #endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 0099dc116168..cedcf8ea3c76 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h
@@ -16,6 +16,7 @@ typedef struct {
 	atomic_long_t id;
 #endif
 	void *vdso;
+	void *vdso_info;
 #ifdef CONFIG_SMP
 	/* A local icache flush is needed before user execution can resume. */
 	cpumask_t icache_stale_mask;
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index a9436a65161a..deca69524799 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -23,6 +23,9 @@ struct vdso_data {
 #endif
 
 extern char vdso_start[], vdso_end[];
+#ifdef CONFIG_COMPAT
+extern char compat_vdso_start[], compat_vdso_end[];
+#endif
 
 enum vvar_pages {
 	VVAR_DATA_PAGE_OFFSET,
@@ -30,6 +33,11 @@ enum vvar_pages {
 	VVAR_NR_PAGES,
 };
 
+enum rv_vdso_map {
+	RV_VDSO_MAP_VVAR,
+	RV_VDSO_MAP_VDSO,
+};
+
 #define VVAR_SIZE  (VVAR_NR_PAGES << PAGE_SHIFT)
 
 /*
@@ -52,12 +60,6 @@ struct __vdso_info {
 	struct vm_special_mapping *cm;
 };
 
-static struct __vdso_info vdso_info __ro_after_init = {
-	.name = "vdso",
-	.vdso_code_start = vdso_start,
-	.vdso_code_end = vdso_end,
-};
-
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		       struct vm_area_struct *new_vma)
 {
@@ -66,35 +68,35 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	return 0;
 }
 
-static int __init __vdso_init(void)
+static int __init __vdso_init(struct __vdso_info *vdso_info)
 {
 	unsigned int i;
 	struct page **vdso_pagelist;
 	unsigned long pfn;
 
-	if (memcmp(vdso_info.vdso_code_start, "\177ELF", 4)) {
+	if (memcmp(vdso_info->vdso_code_start, "\177ELF", 4)) {
 		pr_err("vDSO is not a valid ELF object!\n");
 		return -EINVAL;
 	}
 
-	vdso_info.vdso_pages = (
-		vdso_info.vdso_code_end -
-		vdso_info.vdso_code_start) >>
+	vdso_info->vdso_pages = (
+		vdso_info->vdso_code_end -
+		vdso_info->vdso_code_start) >>
 		PAGE_SHIFT;
 
-	vdso_pagelist = kcalloc(vdso_info.vdso_pages,
+	vdso_pagelist = kcalloc(vdso_info->vdso_pages,
 				sizeof(struct page *),
 				GFP_KERNEL);
 	if (vdso_pagelist == NULL)
 		return -ENOMEM;
 
 	/* Grab the vDSO code pages. */
-	pfn = sym_to_pfn(vdso_info.vdso_code_start);
+	pfn = sym_to_pfn(vdso_info->vdso_code_start);
 
-	for (i = 0; i < vdso_info.vdso_pages; i++)
+	for (i = 0; i < vdso_info->vdso_pages; i++)
 		vdso_pagelist[i] = pfn_to_page(pfn + i);
 
-	vdso_info.cm->pages = vdso_pagelist;
+	vdso_info->cm->pages = vdso_pagelist;
 
 	return 0;
 }
@@ -116,13 +118,14 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 {
 	struct mm_struct *mm = task->mm;
 	struct vm_area_struct *vma;
+	struct __vdso_info *vdso_info = mm->context.vdso_info;
 
 	mmap_read_lock(mm);
 
 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
 		unsigned long size = vma->vm_end - vma->vm_start;
 
-		if (vma_is_special_mapping(vma, vdso_info.dm))
+		if (vma_is_special_mapping(vma, vdso_info->dm))
 			zap_page_range(vma, vma->vm_start, size);
 	}
 
@@ -187,11 +190,6 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 	return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
-enum rv_vdso_map {
-	RV_VDSO_MAP_VVAR,
-	RV_VDSO_MAP_VDSO,
-};
-
 static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
 	[RV_VDSO_MAP_VVAR] = {
 		.name   = "[vvar]",
@@ -203,25 +201,53 @@ static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
 	},
 };
 
+static struct __vdso_info vdso_info __ro_after_init = {
+	.name = "vdso",
+	.vdso_code_start = vdso_start,
+	.vdso_code_end = vdso_end,
+	.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+	.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+};
+
+#ifdef CONFIG_COMPAT
+static struct __vdso_info compat_vdso_info __ro_after_init = {
+	.name = "compat_vdso",
+	.vdso_code_start = compat_vdso_start,
+	.vdso_code_end = compat_vdso_end,
+	.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+	.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+};
+#endif
+
 static int __init vdso_init(void)
 {
-	vdso_info.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR];
-	vdso_info.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO];
+	int ret;
+
+	ret = __vdso_init(&vdso_info);
+	if (ret)
+		goto out;
 
-	return __vdso_init();
+#ifdef CONFIG_COMPAT
+	ret = __vdso_init(&compat_vdso_info);
+	if (ret)
+		goto out;
+#endif
+out:
+	return ret;
 }
 arch_initcall(vdso_init);
 
 static int __setup_additional_pages(struct mm_struct *mm,
 				    struct linux_binprm *bprm,
-				    int uses_interp)
+				    int uses_interp,
+				    struct __vdso_info *vdso_info)
 {
 	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	void *ret;
 
 	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
 
-	vdso_text_len = vdso_info.vdso_pages << PAGE_SHIFT;
+	vdso_text_len = vdso_info->vdso_pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
 	vdso_mapping_len = vdso_text_len + VVAR_SIZE;
 
@@ -232,16 +258,18 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	}
 
 	ret = _install_special_mapping(mm, vdso_base, VVAR_SIZE,
-		(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info.dm);
+		(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info->dm);
 	if (IS_ERR(ret))
 		goto up_fail;
 
 	vdso_base += VVAR_SIZE;
 	mm->context.vdso = (void *)vdso_base;
+	mm->context.vdso_info = (void *)vdso_info;
+
 	ret =
 	   _install_special_mapping(mm, vdso_base, vdso_text_len,
 		(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
-		vdso_info.cm);
+		vdso_info->cm);
 
 	if (IS_ERR(ret))
 		goto up_fail;
@@ -253,6 +281,24 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	return PTR_ERR(ret);
 }
 
+#ifdef CONFIG_COMPAT
+int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int uses_interp)
+{
+	struct mm_struct *mm = current->mm;
+	int ret;
+
+	if (mmap_write_lock_killable(mm))
+		return -EINTR;
+
+	ret = __setup_additional_pages(mm, bprm, uses_interp,
+							&compat_vdso_info);
+	mmap_write_unlock(mm);
+
+	return ret;
+}
+#endif
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
@@ -261,7 +307,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (mmap_write_lock_killable(mm))
 		return -EINTR;
 
-	ret = __setup_additional_pages(mm, bprm, uses_interp);
+	ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso_info);
 	mmap_write_unlock(mm);
 
 	return ret;
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:06 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:06 +0800
Subject: [PATCH V3 13/17] riscv: compat: signal: Add rt_frame implementation
Message-ID: <20220120073911.99857-14-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement compat_setup_rt_frame for sigcontext save & restore. The
main process is the same with signal, but the rv32 pt_regs' size
is different from rv64's, so we needs convert them.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/kernel/Makefile        |   1 +
 arch/riscv/kernel/compat_signal.c | 243 ++++++++++++++++++++++++++++++
 arch/riscv/kernel/signal.c        |  13 +-
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/kernel/compat_signal.c

diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 59cf97faddae..ef47f7d5843f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -66,4 +66,5 @@ obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
 obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
+obj-$(CONFIG_COMPAT)		+= compat_signal.o
 obj-$(CONFIG_COMPAT)		+= compat_vdso/
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
new file mode 100644
index 000000000000..7041742ded08
--- /dev/null
+++ b/arch/riscv/kernel/compat_signal.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/compat.h>
+#include <linux/signal.h>
+#include <linux/uaccess.h>
+#include <linux/syscalls.h>
+#include <linux/tracehook.h>
+#include <linux/linkage.h>
+
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#include <asm/switch_to.h>
+#include <asm/csr.h>
+
+#define COMPAT_DEBUG_SIG 0
+
+struct compat_sigcontext {
+	struct compat_user_regs_struct sc_regs;
+	union __riscv_fp_state sc_fpregs;
+};
+
+struct compat_ucontext {
+	compat_ulong_t		uc_flags;
+	struct compat_ucontext	*uc_link;
+	compat_stack_t		uc_stack;
+	sigset_t		uc_sigmask;
+	/* There's some padding here to allow sigset_t to be expanded in the
+	 * future.  Though this is unlikely, other architectures put uc_sigmask
+	 * at the end of this structure and explicitly state it can be
+	 * expanded, so we didn't want to box ourselves in here. */
+	__u8		  __unused[1024 / 8 - sizeof(sigset_t)];
+	/* We can't put uc_sigmask at the end of this structure because we need
+	 * to be able to expand sigcontext in the future.  For example, the
+	 * vector ISA extension will almost certainly add ISA state.  We want
+	 * to ensure all user-visible ISA state can be saved and restored via a
+	 * ucontext, so we're putting this at the end in order to allow for
+	 * infinite extensibility.  Since we know this will be extended and we
+	 * assume sigset_t won't be extended an extreme amount, we're
+	 * prioritizing this. */
+	struct compat_sigcontext uc_mcontext;
+};
+
+struct compat_rt_sigframe {
+	struct compat_siginfo info;
+	struct compat_ucontext uc;
+};
+
+#ifdef CONFIG_FPU
+static long compat_restore_fp_state(struct pt_regs *regs,
+	union __riscv_fp_state __user *sc_fpregs)
+{
+	long err;
+	struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
+	size_t i;
+
+	err = __copy_from_user(&current->thread.fstate, state, sizeof(*state));
+	if (unlikely(err))
+		return err;
+
+	fstate_restore(current, regs);
+
+	/* We support no other extension state at this time. */
+	for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
+		u32 value;
+
+		err = __get_user(value, &sc_fpregs->q.reserved[i]);
+		if (unlikely(err))
+			break;
+		if (value != 0)
+			return -EINVAL;
+	}
+
+	return err;
+}
+
+static long compat_save_fp_state(struct pt_regs *regs,
+			  union __riscv_fp_state __user *sc_fpregs)
+{
+	long err;
+	struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
+	size_t i;
+
+	fstate_save(current, regs);
+	err = __copy_to_user(state, &current->thread.fstate, sizeof(*state));
+	if (unlikely(err))
+		return err;
+
+	/* We support no other extension state at this time. */
+	for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
+		err = __put_user(0, &sc_fpregs->q.reserved[i]);
+		if (unlikely(err))
+			break;
+	}
+
+	return err;
+}
+#else
+#define compat_save_fp_state(task, regs) (0)
+#define compat_restore_fp_state(task, regs) (0)
+#endif
+
+static long compat_restore_sigcontext(struct pt_regs *regs,
+	struct compat_sigcontext __user *sc)
+{
+	long err;
+	struct compat_user_regs_struct cregs;
+
+	/* sc_regs is structured the same as the start of pt_regs */
+	err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));
+
+	cregs_to_regs(&cregs, regs);
+
+	/* Restore the floating-point state. */
+	if (has_fpu())
+		err |= compat_restore_fp_state(regs, &sc->sc_fpregs);
+	return err;
+}
+
+COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
+{
+	struct pt_regs *regs = current_pt_regs();
+	struct compat_rt_sigframe __user *frame;
+	struct task_struct *task;
+	sigset_t set;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current->restart_block.fn = do_no_restart_syscall;
+
+	frame = (struct compat_rt_sigframe __user *)regs->sp;
+
+	if (!access_ok(frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	set_current_blocked(&set);
+
+	if (compat_restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
+	if (compat_restore_altstack(&frame->uc.uc_stack))
+		goto badframe;
+
+	return regs->a0;
+
+badframe:
+	task = current;
+	if (show_unhandled_signals) {
+		pr_info_ratelimited(
+			"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
+			task->comm, task_pid_nr(task), __func__,
+			frame, (void *)regs->epc, (void *)regs->sp);
+	}
+	force_sig(SIGSEGV);
+	return 0;
+}
+
+static long compat_setup_sigcontext(struct compat_rt_sigframe __user *frame,
+	struct pt_regs *regs)
+{
+	struct compat_sigcontext __user *sc = &frame->uc.uc_mcontext;
+	struct compat_user_regs_struct cregs;
+	long err;
+
+	regs_to_cregs(&cregs, regs);
+
+	/* sc_regs is structured the same as the start of pt_regs */
+	err = __copy_to_user(&sc->sc_regs, &cregs, sizeof(sc->sc_regs));
+	/* Save the floating-point state. */
+	if (has_fpu())
+		err |= compat_save_fp_state(regs, &sc->sc_fpregs);
+	return err;
+}
+
+static inline void __user *compat_get_sigframe(struct ksignal *ksig,
+	struct pt_regs *regs, size_t framesize)
+{
+	unsigned long sp;
+	/* Default to using normal stack */
+	sp = regs->sp;
+
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+		return (void __user __force *)(-1UL);
+
+	/* This is the X/Open sanctioned signal stack switching. */
+	sp = sigsp(sp, ksig) - framesize;
+
+	/* Align the stack frame. */
+	sp &= ~0xfUL;
+
+	return (void __user *)sp;
+}
+
+int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+	struct pt_regs *regs)
+{
+	struct compat_rt_sigframe __user *frame;
+	long err = 0;
+
+	frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
+	if (!access_ok(frame, sizeof(*frame)))
+		return -EFAULT;
+
+	err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+
+	/* Create the ucontext. */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(NULL, &frame->uc.uc_link);
+	err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
+	err |= compat_setup_sigcontext(frame, regs);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+	if (err)
+		return -EFAULT;
+
+	regs->ra = (unsigned long)COMPAT_VDSO_SYMBOL(
+			current->mm->context.vdso, rt_sigreturn);
+
+	/*
+	 * Set up registers for signal handler.
+	 * Registers that we don't modify keep the value they had from
+	 * user-space at the time we took the signal.
+	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
+	 * since some things rely on this (e.g. glibc's debug/segfault.c).
+	 */
+	regs->epc = (unsigned long)ksig->ka.sa.sa_handler;
+	regs->sp = (unsigned long)frame;
+	regs->a0 = ksig->sig;                     /* a0: signal number */
+	regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
+	regs->a2 = (unsigned long)(&frame->uc);   /* a2: ucontext pointer */
+
+#if COMPAT_DEBUG_SIG
+	pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
+		current->comm, task_pid_nr(current), ksig->sig,
+		(void *)regs->epc, (void *)regs->ra, frame);
+#endif
+
+	return 0;
+}
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index c2d5ecbe5526..27d8f39228c4 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2012 Regents of the University of California
  */
 
+#include <linux/compat.h>
 #include <linux/signal.h>
 #include <linux/uaccess.h>
 #include <linux/syscalls.h>
@@ -229,6 +230,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+				 struct pt_regs *regs);
+#endif
+
 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
 	sigset_t *oldset = sigmask_to_save();
@@ -258,8 +264,13 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 		}
 	}
 
+#ifdef CONFIG_COMPAT
 	/* Set up the stack frame */
-	ret = setup_rt_frame(ksig, oldset, regs);
+	if (is_compat_task())
+		ret = compat_setup_rt_frame(ksig, oldset, regs);
+	else
+#endif
+		ret = setup_rt_frame(ksig, oldset, regs);
 
 	signal_setup_done(ret, ksig, 0);
 }
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:07 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:07 +0800
Subject: [PATCH V3 14/17] riscv: compat: ptrace: Add compat_arch_ptrace
 implement
Message-ID: <20220120073911.99857-15-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Now, you can use native gdb on riscv64 for rv32 app debugging.

$ uname -a
Linux buildroot 5.16.0-rc4-00036-gbef6b82fdf23-dirty #53 SMP Mon Dec 20 23:06:53 CST 2021 riscv64 GNU/Linux
$ cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv64imafdcsuh
mmu             : sv48

$ file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ file /usr/bin/gdb
/usr/bin/gdb: ELF 32-bit LSB shared object, UCB RISC-V, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ /usr/bin/gdb /bin/busybox
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
Reading symbols from /bin/busybox...
(No debugging symbols found in /bin/busybox)
(gdb) b main
Breakpoint 1 at 0x8ddc
(gdb) r
Starting program: /bin/busybox
Failed to read a valid object file image from memory.

Breakpoint 1, 0x555a8ddc in main ()
(gdb) i r
ra             0x77df0b74       0x77df0b74
sp             0x7fdd3d10       0x7fdd3d10
gp             0x5567e800       0x5567e800 <bb_common_bufsiz1+160>
tp             0x77f64280       0x77f64280
t0             0x0      0
t1             0x555a6fac       1431990188
t2             0x77dd8db4       2011008436
fp             0x7fdd3e34       0x7fdd3e34
s1             0x7fdd3e34       2145205812
a0             0xffffffff       -1
a1             0x2000   8192
a2             0x7fdd3e3c       2145205820
a3             0x0      0
a4             0x7fdd3d30       2145205552
a5             0x555a8dc0       1431997888
a6             0x77f2c170       2012397936
a7             0x6a7c7a2f       1786542639
s2             0x0      0
s3             0x0      0
s4             0x555a8dc0       1431997888
s5             0x77f8a3a8       2012783528
s6             0x7fdd3e3c       2145205820
s7             0x5567cecc       1432866508
--Type <RET> for more, q to quit, c to continue without paging--
s8             0x1      1
s9             0x0      0
s10            0x55634448       1432568904
s11            0x0      0
t3             0x77df0bb8       2011106232
t4             0x42fc   17148
t5             0x0      0
t6             0x40     64
pc             0x555a8ddc       0x555a8ddc <main+28>
(gdb) si
0x555a78f0 in mallopt at plt ()
(gdb) c
Continuing.
BusyBox v1.34.1 (2021-12-19 22:39:48 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
...
[Inferior 1 (process 107) exited normally]
(gdb) q

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/kernel/ptrace.c | 87 +++++++++++++++++++++++++++++++++++---
 1 file changed, 82 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 9c0511119bad..76042ed861a3 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -12,6 +12,7 @@
 #include <asm/thread_info.h>
 #include <asm/switch_to.h>
 #include <linux/audit.h>
+#include <linux/compat.h>
 #include <linux/ptrace.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
@@ -113,11 +114,6 @@ static const struct user_regset_view riscv_user_native_view = {
 	.n = ARRAY_SIZE(riscv_user_regset),
 };
 
-const struct user_regset_view *task_user_regset_view(struct task_struct *task)
-{
-	return &riscv_user_native_view;
-}
-
 struct pt_regs_offset {
 	const char *name;
 	int offset;
@@ -275,3 +271,84 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
 		trace_sys_exit(regs, regs_return_value(regs));
 #endif
 }
+
+#ifdef CONFIG_COMPAT
+static int compat_riscv_gpr_get(struct task_struct *target,
+				const struct user_regset *regset,
+				struct membuf to)
+{
+	struct compat_user_regs_struct cregs;
+
+	regs_to_cregs(&cregs, task_pt_regs(target));
+
+	return membuf_write(&to, &cregs,
+			    sizeof(struct compat_user_regs_struct));
+}
+
+static int compat_riscv_gpr_set(struct task_struct *target,
+				const struct user_regset *regset,
+				unsigned int pos, unsigned int count,
+				const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct compat_user_regs_struct cregs;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
+
+	cregs_to_regs(&cregs, task_pt_regs(target));
+
+	return ret;
+}
+
+static const struct user_regset compat_riscv_user_regset[] = {
+	[REGSET_X] = {
+		.core_note_type = NT_PRSTATUS,
+		.n = ELF_NGREG,
+		.size = sizeof(compat_elf_greg_t),
+		.align = sizeof(compat_elf_greg_t),
+		.regset_get = compat_riscv_gpr_get,
+		.set = compat_riscv_gpr_set,
+	},
+#ifdef CONFIG_FPU
+	[REGSET_F] = {
+		.core_note_type = NT_PRFPREG,
+		.n = ELF_NFPREG,
+		.size = sizeof(elf_fpreg_t),
+		.align = sizeof(elf_fpreg_t),
+		.regset_get = riscv_fpr_get,
+		.set = riscv_fpr_set,
+	},
+#endif
+};
+
+static const struct user_regset_view compat_riscv_user_native_view = {
+	.name = "riscv",
+	.e_machine = EM_RISCV,
+	.regsets = compat_riscv_user_regset,
+	.n = ARRAY_SIZE(compat_riscv_user_regset),
+};
+
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	long ret = -EIO;
+
+	switch (request) {
+	default:
+		ret = compat_ptrace_request(child, request, caddr, cdata);
+		break;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_COMPAT */
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+#ifdef CONFIG_COMPAT
+	if (test_tsk_thread_flag(task, TIF_32BIT))
+		return &compat_riscv_user_native_view;
+	else
+#endif
+		return &riscv_user_native_view;
+}
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:08 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:08 +0800
Subject: [PATCH V3 15/17] riscv: compat: Add UXL_32 support in start_thread
Message-ID: <20220120073911.99857-16-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

If the current task is in COMPAT mode, set SR_UXL_32 in status for
returning userspace.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/kernel/process.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 03ac3aa611f5..1a666ad299b4 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 	}
 	regs->epc = pc;
 	regs->sp = sp;
+
+#ifdef CONFIG_COMPAT
+	if (is_compat_task())
+		regs->status |= SR_UXL_32;
+#endif
 }
 
 void flush_thread(void)
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:09 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:09 +0800
Subject: [PATCH V3 16/17] riscv: compat: Add COMPAT Kbuild skeletal support
Message-ID: <20220120073911.99857-17-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Adds initial skeletal COMPAT Kbuild (Runing 32bit U-mode on 64bit
S-mode) support.
 - Setup kconfig & dummy functions for compiling.
 - Implement compat_start_thread by the way.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/Kconfig | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 4602cfe92a20..d16ab3af3b34 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -73,6 +73,7 @@ config RISCV
 	select HAVE_ARCH_KGDB if !XIP_KERNEL
 	select HAVE_ARCH_KGDB_QXFER_PKT
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
+	select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
@@ -123,12 +124,18 @@ config ARCH_MMAP_RND_BITS_MIN
 	default 18 if 64BIT
 	default 8
 
+config ARCH_MMAP_RND_COMPAT_BITS_MIN
+	default 8
+
 # max bits determined by the following formula:
 #  VA_BITS - PAGE_SHIFT - 3
 config ARCH_MMAP_RND_BITS_MAX
 	default 24 if 64BIT # SV39 based
 	default 17
 
+config ARCH_MMAP_RND_COMPAT_BITS_MAX
+	default 17
+
 # set if we run in machine mode, cleared if we run in supervisor mode
 config RISCV_M_MODE
 	bool
@@ -428,6 +435,18 @@ config CRASH_DUMP
 
 	  For more details see Documentation/admin-guide/kdump/kdump.rst
 
+config COMPAT
+	bool "Kernel support for 32-bit U-mode"
+	default 64BIT
+	depends on 64BIT && MMU
+	help
+	  This option enables support for a 32-bit U-mode running under a 64-bit
+	  kernel at S-mode. riscv32-specific components such as system calls,
+	  the user helper functions (vdso), signal rt_frame functions and the
+	  ptrace interface are handled appropriately by the kernel.
+
+	  If you want to execute 32-bit userspace applications, say Y.
+
 endmenu
 
 menu "Boot options"
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:10 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:10 +0800
Subject: [PATCH V3 17/17] KVM: compat: riscv: Prevent KVM_COMPAT from being
 selected
Message-ID: <20220120073911.99857-18-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Current riscv doesn't support the 32bit KVM/arm API. Let's make it
clear by not selecting KVM_COMPAT.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
---
 virt/kvm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index f4834c20e4a6..a8c5c9f06b3c 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -53,7 +53,7 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
 
 config KVM_COMPAT
        def_bool y
-       depends on KVM && COMPAT && !(S390 || ARM64)
+       depends on KVM && COMPAT && !(S390 || ARM64 || RISCV)
 
 config HAVE_KVM_IRQ_BYPASS
        bool
-- 
2.25.1



From guoren at kernel.org  Wed Jan 19 23:39:11 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Thu, 20 Jan 2022 15:39:11 +0800
Subject: [PATCH V2 00/17] riscv: compat: Add COMPAT mode support for rv64
Message-ID: <20211228143958.3409187-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Currently, most 64-bit architectures (x86, parisc, powerpc, arm64,
s390, mips, sparc) have supported COMPAT mode. But they all have
history issues and can't use standard linux unistd.h. RISC-V would
be first standard __SYSCALL_COMPAT user of include/uapi/asm-generic
/unistd.h.

The patchset are based on v5.16-rc6, you can compare rv64-compat32
v.s. rv32-whole in qemu with following step:

 - Prepare rv32 rootfs & fw_jump.bin by buildroot.org
   $ git clone git://git.busybox.net/buildroot
   $ cd buildroot
   $ make qemu_riscv32_virt_defconfig O=qemu_riscv32_virt_defconfig
   $ make -C qemu_riscv32_virt_defconfig
   $ make qemu_riscv64_virt_defconfig O=qemu_riscv64_virt_defconfig
   $ make -C qemu_riscv64_virt_defconfig
   (Got fw_jump.bin & rootfs.ext2 in qemu_riscvXX_virt_defconfig/images)

 - Prepare Linux rv32 & rv64 Image
   $ git clone git at github.com:c-sky/csky-linux.git -b riscv_compat_v2 linux
   $ cd linux
   $ echo "CONFIG_STRICT_KERNEL_RWX=n" >> arch/riscv/configs/defconfig
   $ echo "CONFIG_STRICT_MODULE_RWX=n" >> arch/riscv/configs/defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ rv32_defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ Image
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ Image

 - Prepare Qemu: (made by LIU Zhiwei <zhiwei_liu at c-sky.com>)
   $ git clone https://github.com/romanheros/qemu.git -b riscv-upstream-uxl-v5
   $ cd qemu
   $ ./configure --target-list="riscv64-softmmu riscv32-softmmu"
   $ make

 - Run rv64 with rv32 rootfs in compat mode:
   $ ./build/qemu-system-riscv64 -cpu rv64,x-h=true -M virt -m 64m -nographic -bios qemu_riscv64_virt_defconfig/images/fw_jump.bin -kernel build-rv64/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv64-unknown-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.37) #96 SMP Tue Dec 28 21:01:55 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 17 pages/cpu s30696 r8192 d30744 u69632
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15655
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0xffffffcefee00000 - 0xffffffceff000000   (2048 kB)
[    0.000000]       pci io : 0xffffffceff000000 - 0xffffffcf00000000   (  16 MB)
[    0.000000]      vmemmap : 0xffffffcf00000000 - 0xffffffcfffffffff   (4095 MB)
[    0.000000]      vmalloc : 0xffffffd000000000 - 0xffffffdfffffffff   (65535 MB)
[    0.000000]       lowmem : 0xffffffe000000000 - 0xffffffe003e00000   (  62 MB)
[    0.000000]       kernel : 0xffffffff80000000 - 0xffffffffffffffff   (2047 MB)
[    0.000000] Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 64 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv64imafdcsuh
mmu             : sv48

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
# ca[   78.386630] random: fast init done
# cat /proc/meminfo
MemTotal:          53076 kB
MemFree:           40264 kB
MemAvailable:      40244 kB
Buffers:             236 kB
Cached:             1560 kB
SwapCached:            0 kB
Active:             1700 kB
Inactive:            516 kB
Active(anon):         40 kB
Inactive(anon):      424 kB
Active(file):       1660 kB
Inactive(file):       92 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           444 kB
Mapped:             1188 kB
Shmem:                44 kB
KReclaimable:        952 kB
Slab:               5744 kB
SReclaimable:        952 kB
SUnreclaim:         4792 kB
KernelStack:         624 kB
PageTables:          156 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26536 kB
Committed_AS:       1748 kB
VmallocTotal:   67108863 kB
VmallocUsed:         652 kB
VmallocChunk:          0 kB
Percpu:               80 kB
#

 - Run rv32 with rv32 rootfs:
   $ ./build/qemu-system-riscv32 -cpu rv32,x-h=true -M virt -m 64m -nographic -bios qemu_riscv32_virt_defconfig/images/fw_jump.bin -kernel build-rv32/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11-201-g7600ca7960-dirty) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #7 SMP Tue Dec 28 21:02:21 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80400000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 12 pages/cpu s16600 r8192 d24360 u49152
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15240
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0x9dc00000 - 0x9e000000   (4096 kB)
[    0.000000]       pci io : 0x9e000000 - 0x9f000000   (  16 MB)
[    0.000000]      vmemmap : 0x9f000000 - 0x9fffffff   (  15 MB)
[    0.000000]      vmalloc : 0xa0000000 - 0xbfffffff   ( 511 MB)
[    0.000000]       lowmem : 0xc0000000 - 0xc3c00000   (  60 MB)
[    0.000000] Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss, 9516K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 32 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv32imafdcsuh
mmu             : sv32

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
[   79.320589] random: fast init done
# cat /proc/meminfo
MemTotal:          52176 kB
MemFree:           41012 kB
MemAvailable:      42176 kB
Buffers:             644 kB
Cached:             2724 kB
SwapCached:            0 kB
Active:             3128 kB
Inactive:            752 kB
Active(anon):         40 kB
Inactive(anon):      516 kB
Active(file):       3088 kB
Inactive(file):      236 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 4 kB
Writeback:             0 kB
AnonPages:           556 kB
Mapped:             2172 kB
Shmem:                44 kB
KReclaimable:        656 kB
Slab:               3684 kB
SReclaimable:        656 kB
SUnreclaim:         3028 kB
KernelStack:         312 kB
PageTables:           88 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26088 kB
Committed_AS:       2088 kB
VmallocTotal:     524287 kB
VmallocUsed:          12 kB
VmallocChunk:          0 kB
Percpu:               60 kB
#

 Some conclusions:
 - kernel statics:
   64: Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved)
   32: Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss,  9516K reserved)
   rv32 better than rv64:                  1%               22%           17%          13%        19%         11%
   The code size is very similar, but data size rv32 would be better.

 - rv32 kernel runtime KernelStack, Slab... are smaller,
   rv64: MemTotal: 53076 kB,        MemFree: 40264 kB
   rv32: MemTotal: 52176 + 2048 kB, MemFree: 41012  + 2048 kB
   rv32 better than rv64:       2%                         6%

   (Because opensbi problem, we could add another 2MB for rv32.)
   Overall, rv64-compat is 6% worse than rv32-full at memory footprint.
   If the user space memory usage increases, the gap will be further
   reduced.

 - Qemu, kernel, rv32 = rv64 defconfig, rootfs, opensbi
   are the same in this comparison.

Changes in v2:
 - Add __ARCH_WANT_COMPAT_STAT suggested
 - Cleanup fcntl compatduplicate definitions
 - Cleanup compat.h
 - Move rv32_defconfig into Makefile
 - Fixup rv64 rootfs boot failed, remove hw_compat_mode_detect
 - Move SYSVIPC_COMPAT into init/Kconfig
 - Simplify compat_elf_check

Guo Ren (17):
  kconfig: Add SYSVIPC_COMPAT for all architectures
  fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
  asm-generic: fcntl: compat: Remove duplicate definitions
  asm-generic: compat: Cleanup duplicate definitions
  syscalls: compat: Fix the missing part for __SYSCALL_COMPAT
  riscv: Fixup difference with defconfig
  riscv: compat: Add basic compat date type implementation
  riscv: compat: Re-implement TASK_SIZE for COMPAT_32BIT
  riscv: compat: syscall: Add compat_sys_call_table implementation
  riscv: compat: syscall: Add entry.S implementation
  riscv: compat: Add elf.h implementation
  riscv: compat: vdso: Add rv32 VDSO base code implementation
  riscv: compat: vdso: Add setup additional pages implementation
  riscv: compat: signal: Add rt_frame implementation
  riscv: compat: ptrace: Add compat_arch_ptrace implement
  riscv: compat: Add UXL_32 support in start_thread
  riscv: compat: Add COMPAT Kbuild skeletal support

 arch/arm64/Kconfig                            |   4 -
 arch/arm64/include/asm/compat.h               | 112 +-------
 arch/arm64/include/asm/unistd.h               |   1 +
 arch/mips/Kconfig                             |   5 -
 arch/mips/include/asm/compat.h                |  24 +-
 arch/mips/include/asm/unistd.h                |   2 +
 arch/parisc/Kconfig                           |   4 -
 arch/parisc/include/asm/compat.h              |  47 +---
 arch/parisc/include/asm/unistd.h              |   1 +
 arch/powerpc/Kconfig                          |   5 -
 arch/powerpc/include/asm/compat.h             |  51 +---
 arch/powerpc/include/asm/unistd.h             |   1 +
 arch/riscv/Kconfig                            |  19 ++
 arch/riscv/Makefile                           |   9 +
 arch/riscv/configs/rv32_defconfig             | 135 ----------
 arch/riscv/include/asm/compat.h               | 132 ++++++++++
 arch/riscv/include/asm/csr.h                  |   7 +
 arch/riscv/include/asm/elf.h                  |  54 +++-
 arch/riscv/include/asm/mmu.h                  |   1 +
 arch/riscv/include/asm/pgtable.h              |  11 +-
 arch/riscv/include/asm/processor.h            |   6 +
 arch/riscv/include/asm/syscall.h              |   3 +
 arch/riscv/include/asm/thread_info.h          |   1 +
 arch/riscv/include/asm/vdso.h                 |   9 +
 arch/riscv/include/uapi/asm/unistd.h          |   2 +-
 arch/riscv/kernel/Makefile                    |   3 +
 arch/riscv/kernel/compat_signal.c             | 243 ++++++++++++++++++
 arch/riscv/kernel/compat_syscall_table.c      |  72 ++++++
 arch/riscv/kernel/compat_vdso/.gitignore      |   2 +
 arch/riscv/kernel/compat_vdso/Makefile        |  68 +++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |   8 +
 .../kernel/compat_vdso/compat_vdso.lds.S      |   3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |   3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |   5 +
 arch/riscv/kernel/compat_vdso/getcpu.S        |   3 +
 arch/riscv/kernel/compat_vdso/note.S          |   3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |   3 +
 arch/riscv/kernel/entry.S                     |  18 +-
 arch/riscv/kernel/process.c                   |   5 +
 arch/riscv/kernel/ptrace.c                    |  87 ++++++-
 arch/riscv/kernel/signal.c                    |  13 +-
 arch/riscv/kernel/sys_riscv.c                 |   6 +-
 arch/riscv/kernel/vdso.c                      | 104 +++++---
 arch/riscv/kernel/vdso/vdso.S                 |   6 +-
 arch/s390/Kconfig                             |   3 -
 arch/s390/include/asm/compat.h                | 113 +-------
 arch/s390/include/asm/unistd.h                |   1 +
 arch/sparc/Kconfig                            |   5 -
 arch/sparc/include/asm/compat.h               |  43 ++--
 arch/sparc/include/asm/unistd.h               |   1 +
 arch/x86/Kconfig                              |   4 -
 arch/x86/include/asm/compat.h                 | 118 +--------
 arch/x86/include/asm/unistd.h                 |   1 +
 drivers/firmware/efi/libstub/efi-stub.c       |   2 +-
 fs/stat.c                                     |   2 +-
 include/asm-generic/compat.h                  | 122 +++++++++
 include/uapi/asm-generic/fcntl.h              |   2 +-
 include/uapi/asm-generic/unistd.h             |   4 +-
 init/Kconfig                                  |   4 +
 tools/include/uapi/asm-generic/unistd.h       |   4 +-
 60 files changed, 1076 insertions(+), 654 deletions(-)
 delete mode 100644 arch/riscv/configs/rv32_defconfig
 create mode 100644 arch/riscv/include/asm/compat.h
 create mode 100644 arch/riscv/kernel/compat_signal.c
 create mode 100644 arch/riscv/kernel/compat_syscall_table.c
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

-- 
2.25.1


_______________________________________________
linux-riscv mailing list
linux-riscv at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv



From yongqiang.niu at mediatek.com  Wed Jan 19 23:43:11 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Thu, 20 Jan 2022 15:43:11 +0800
Subject: [PATCH v1, 1/1] soc: mediatek: cmdq: add cmdq_pkt_poll_addr function
In-Reply-To: <20220120074311.2243-1-yongqiang.niu@mediatek.com>
References: <20220120074311.2243-1-yongqiang.niu@mediatek.com>
Message-ID: <20220120074311.2243-2-yongqiang.niu@mediatek.com>

From: mtk18742 <moudy.ho at mediatek.com>

add cmdq_pkt_poll_addr function in cmdq helper functions

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/soc/mediatek/mtk-cmdq-helper.c   | 39 ++++++++++++++++++++++++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h    |  2 ++
 3 files changed, 42 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 3c8e4212d941..6c5cfb284140 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -344,6 +344,45 @@ int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_set_event);
 
+s32 cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, u32 value, u32 addr, u32 mask, u8 reg_gpr)
+{
+	struct cmdq_instruction inst = { {0} };
+
+	s32 err;
+
+	if (mask != 0xffffffff) {
+		inst.op = CMDQ_CODE_MASK;
+		inst.mask = ~mask;
+		err = cmdq_pkt_append_command(pkt, inst);
+		if (err != 0)
+			return err;
+
+		addr = addr | 0x1;
+	}
+
+	/* Move extra handle APB address to GPR */
+	inst.op = CMDQ_CODE_MOVE;
+	inst.value = addr;
+	inst.sop = reg_gpr;
+	inst.dst_t = 1;
+	err = cmdq_pkt_append_command(pkt, inst);
+	if (err != 0)
+		pr_err("%s fail append command move addr to reg err:%d",
+			__func__, err);
+
+	inst.op = CMDQ_CODE_POLL;
+	inst.value = value;
+	inst.sop = reg_gpr;
+	inst.dst_t = 1;
+	err = cmdq_pkt_append_command(pkt, inst);
+	if (err != 0)
+		pr_err("%s fail append command poll err:%d",
+			__func__, err);
+
+	return err;
+}
+EXPORT_SYMBOL(cmdq_pkt_poll_addr);
+
 int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
 		  u16 offset, u32 value)
 {
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 44365aab043c..a27329fd7c7f 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -54,6 +54,7 @@
  */
 enum cmdq_code {
 	CMDQ_CODE_MASK = 0x02,
+	CMDQ_CODE_MOVE = 0x02,
 	CMDQ_CODE_WRITE = 0x04,
 	CMDQ_CODE_POLL = 0x08,
 	CMDQ_CODE_JUMP = 0x10,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index ac6b5f3cba95..28dc5ce0ff03 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -280,4 +280,6 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
 int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb cb,
 			 void *data);
 
+s32 cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, u32 value, u32 addr, u32 mask, u8 reg_gpr);
+
 #endif	/* __MTK_CMDQ_H__ */
-- 
2.25.1



From yongqiang.niu at mediatek.com  Wed Jan 19 23:43:10 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Thu, 20 Jan 2022 15:43:10 +0800
Subject: [PATCH v1, 0/1] soc: mediatek: cmdq: add cmdq_pkt_poll_addr function
Message-ID: <20220120074311.2243-1-yongqiang.niu@mediatek.com>

add cmdq_pkt_poll_addr function

mtk18742 (1):
  soc: mediatek: cmdq: add cmdq_pkt_poll_addr function

 drivers/soc/mediatek/mtk-cmdq-helper.c   | 39 ++++++++++++++++++++++++
 include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
 include/linux/soc/mediatek/mtk-cmdq.h    |  2 ++
 3 files changed, 42 insertions(+)

-- 
2.25.1



From leoyang.li at nxp.com  Thu Jan 20 00:06:48 2022
From: leoyang.li at nxp.com (Leo Li)
Date: Thu, 20 Jan 2022 08:06:48 +0000
Subject: [PATCH 2/7] arm64: dts: ls1028a: move Mali DP500 node into /soc
In-Reply-To: <20210831134013.1625527-3-michael@walle.cc>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-3-michael@walle.cc>
Message-ID: <AS8PR04MB89460673836CDB9AEFC0C09A8F5A9@AS8PR04MB8946.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Michael Walle <michael at walle.cc>
> Sent: Tuesday, August 31, 2021 9:40 PM
> To: linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Cc: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>; Rob
> Herring <robh+dt at kernel.org>; Vladimir Oltean <vladimir.oltean at nxp.com>;
> Michael Walle <michael at walle.cc>
> Subject: [PATCH 2/7] arm64: dts: ls1028a: move Mali DP500 node into /soc
> 
> Move it inside the /soc subnode because it is part of the CCSR space.

I just noticed that the dp0_out label has been changed to dpi0_out besides the move.  Is this an intentional change or a typo?  If intentional we probably should mention it, otherwise we should change it back as it is breaking build for off-tree patch that uses the label.

> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
>  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 41 ++++++++++---------
>  1 file changed, 21 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> index 9a65a7118faa..92e4f004c1c2 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> @@ -793,6 +793,27 @@ QORIQ_CLK_PLL_DIV(16)>,
>  			clock-names = "wdog_clk", "apb_pclk";
>  		};
> 
> +		malidp0: display at f080000 {
> +			compatible = "arm,mali-dp500";
> +			reg = <0x0 0xf080000 0x0 0x10000>;
> +			interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
> +				     <0 223 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "DE", "SE";
> +			clocks = <&dpclk>,
> +				 <&clockgen QORIQ_CLK_HWACCEL 2>,
> +				 <&clockgen QORIQ_CLK_HWACCEL 2>,
> +				 <&clockgen QORIQ_CLK_HWACCEL 2>;
> +			clock-names = "pxlclk", "mclk", "aclk", "pclk";
> +			arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
> +			arm,malidp-arqos-value = <0xd000d000>;
> +
> +			port {
> +				dpi0_out: endpoint {
> +
> +				};
> +			};
> +		};
> +
>  		sai1: audio-controller at f100000 {
>  			#sound-dai-cells = <0>;
>  			compatible = "fsl,vf610-sai";
> @@ -1139,24 +1160,4 @@ ftm_alarm0: timer at 2800000 {
>  		};
>  	};
> 
> -	malidp0: display at f080000 {
> -		compatible = "arm,mali-dp500";
> -		reg = <0x0 0xf080000 0x0 0x10000>;
> -		interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
> -			     <0 223 IRQ_TYPE_LEVEL_HIGH>;
> -		interrupt-names = "DE", "SE";
> -		clocks = <&dpclk>,
> -			 <&clockgen QORIQ_CLK_HWACCEL 2>,
> -			 <&clockgen QORIQ_CLK_HWACCEL 2>,
> -			 <&clockgen QORIQ_CLK_HWACCEL 2>;
> -		clock-names = "pxlclk", "mclk", "aclk", "pclk";
> -		arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
> -		arm,malidp-arqos-value = <0xd000d000>;
> -
> -		port {
> -			dp0_out: endpoint {
> -
> -			};
> -		};
> -	};
>  };
> --
> 2.30.2



From michael at walle.cc  Thu Jan 20 00:17:37 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 20 Jan 2022 09:17:37 +0100
Subject: [PATCH 2/7] arm64: dts: ls1028a: move Mali DP500 node into /soc
In-Reply-To: <AS8PR04MB89460673836CDB9AEFC0C09A8F5A9@AS8PR04MB8946.eurprd04.prod.outlook.com>
References: <20210831134013.1625527-1-michael@walle.cc>
 <20210831134013.1625527-3-michael@walle.cc>
 <AS8PR04MB89460673836CDB9AEFC0C09A8F5A9@AS8PR04MB8946.eurprd04.prod.outlook.com>
Message-ID: <ad65d1782c051a51534ad0197cc374d8@walle.cc>

Am 2022-01-20 09:06, schrieb Leo Li:
>> -----Original Message-----
>> From: Michael Walle <michael at walle.cc>
>> Sent: Tuesday, August 31, 2021 9:40 PM
>> To: linux-arm-kernel at lists.infradead.org; devicetree at vger.kernel.org; 
>> linux-
>> kernel at vger.kernel.org
>> Cc: Shawn Guo <shawnguo at kernel.org>; Leo Li <leoyang.li at nxp.com>; Rob
>> Herring <robh+dt at kernel.org>; Vladimir Oltean 
>> <vladimir.oltean at nxp.com>;
>> Michael Walle <michael at walle.cc>
>> Subject: [PATCH 2/7] arm64: dts: ls1028a: move Mali DP500 node into 
>> /soc
>> 
>> Move it inside the /soc subnode because it is part of the CCSR space.
> 
> I just noticed that the dp0_out label has been changed to dpi0_out
> besides the move.  Is this an intentional change or a typo?  If
> intentional we probably should mention it, otherwise we should change
> it back as it is breaking build for off-tree patch that uses the
> label.

It's intentional, because dp0_out might sound like displayport. And
from what I've found the output is a display pixel interface, hence dpi.

I agree, that this should have been two patches, must have slipped.
But this series was merged months ago, so we can't change anything
anymore.

Besides, given the fact that there is no support for the DisplayPort
PHY in upstream (yet, I'm working on that), I doubt there are any
out-of-tree device trees, which don't use the proprietary NXP
driver.

Also, if there is an out-of-tree device tree, it should be easy
enough for NXP to change that :)

-michael


From christian.koenig at amd.com  Thu Jan 20 00:27:07 2022
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Thu, 20 Jan 2022 09:27:07 +0100
Subject: [PATCH v5] dma-buf: system_heap: Add a size check for allocation
In-Reply-To: <20220120070850.95495-1-guangming.cao@mediatek.com>
References: <CALAqxLW5uEZCGHGk3rYoiOGzN5XMKb39JzoPB1iEX9k3UsiT-A@mail.gmail.com>
 <20220120070850.95495-1-guangming.cao@mediatek.com>
Message-ID: <4f2631d3-0845-cae6-6fc0-9c00ce6301ce@amd.com>



Am 20.01.22 um 08:08 schrieb guangming.cao at mediatek.com:
> From: Guangming <Guangming.Cao at mediatek.com>
>
> Add a size check for allocation since the allocation size should be
> always less than the total DRAM size on system heap.
> Adding this check can prevent comsuming too much time for invalid allocations.
>
> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> ---
>   drivers/dma-buf/heaps/system_heap.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
>
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index 23a7e74ef966..459dc18bc4a2 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -347,6 +347,14 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
>   	struct page *page, *tmp_page;
>   	int i, ret = -ENOMEM;
>   
> +	/*
> +	 * Size check. The "len" should be less than totalram since system_heap
> +	 * memory is comes from system. Adding check here can prevent comsuming
> +	 * too much time for invalid allocations.
> +	 */
> +	if (len >> PAGE_SHIFT > totalram_pages())

Maybe use PFN_UP() or PFN_DOWN() here instead of open coding this.

Apart from that looks good to me.

Christian.

> +		return ERR_PTR(-EINVAL);
> +
>   	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
>   	if (!buffer)
>   		return ERR_PTR(-ENOMEM);



From narmstrong at baylibre.com  Thu Jan 20 00:33:51 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:51 +0100
Subject: [PATCH v2 0/6] drm/meson: add support for MIPI DSI Display
Message-ID: <20220120083357.1541262-1-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
glue on the same Amlogic SoCs.

This adds support for the glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

The DW-MIPI-DSI transceiver + D-PHY are clocked by the GP0 PLL, and the ENCL encoder + VIU
pixel reader by the VCLK2 clock using the HDMI PLL.

The DW-MIPI-DSI transceiver gets this pixel stream as input clocked with the VCLK2 clock.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

This patchset is based on an earlier attempt at [1] for the AXG SoCs, but:
- the AXG has a single clock source for both transceiver + pixel, which makes it an
  exception instead of a rule, it's simpler to add support for G12A then add AXG on it
- previous glue code was a single monolitic code mixing encoders & bridges, this version
  is aligned on the previous cleanup done on HDMI & CVBS bridges architecture at [2]
- since the only output of AXG is DSI, AXG VPU support is post-poned until we implement
  single-clock DSI support specific case on top of this.

Changes from v1 at [3]:
- fixed DSI host bindings
- add reviewed-by tags for bindings
- moved magic values to defines thanks to Martin's searches
- added proper prefixes to defines
- moved phy_configure to phy_init() dw-mipi-dsi callback
- moved phy_on to a new phy_power_on() dw-mipi-dsi callback
- correctly return phy_init/configure errors to callback returns

[1] https://lore.kernel.org/r/20200907081825.1654-1-narmstrong at baylibre.com
[2] https://lore.kernel.org/r/20211020123947.2585572-1-narmstrong at baylibre.com

Neil Armstrong (6):
  dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
  dt-bindings: display: meson-vpu: add third DPI output port
  drm/meson: venc: add ENCL encoder setup for MIPI-DSI output
  drm/meson: vclk: add DSI clock config
  drm/meson: add DSI encoder
  drm/meson: add support for MIPI-DSI transceiver

 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 116 ++++++
 .../bindings/display/amlogic,meson-vpu.yaml   |   5 +
 drivers/gpu/drm/meson/Kconfig                 |   7 +
 drivers/gpu/drm/meson/Makefile                |   3 +-
 drivers/gpu/drm/meson/meson_drv.c             |   7 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c     | 357 ++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h     | 160 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.c     | 160 ++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h     |  12 +
 drivers/gpu/drm/meson/meson_registers.h       |  15 +
 drivers/gpu/drm/meson/meson_vclk.c            |  47 +++
 drivers/gpu/drm/meson/meson_vclk.h            |   1 +
 drivers/gpu/drm/meson/meson_venc.c            | 211 ++++++++++-
 drivers/gpu/drm/meson/meson_venc.h            |   6 +
 drivers/gpu/drm/meson/meson_vpp.h             |   2 +
 15 files changed, 1106 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:52 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:52 +0100
Subject: [PATCH v2 1/6] dt-bindings: display: add Amlogic MIPI DSI Host
 Controller bindings
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-2-narmstrong@baylibre.com>

The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue
on the same Amlogic SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../display/amlogic,meson-dw-mipi-dsi.yaml    | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
new file mode 100644
index 000000000000..e057659545a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-mipi-dsi.yaml
@@ -0,0 +1,116 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/display/amlogic,meson-dw-mipi-dsi.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller
+
+maintainers:
+  - Neil Armstrong <narmstrong at baylibre.com>
+
+description: |
+  The Amlogic Meson Synopsys Designware Integration is composed of
+  - A Synopsys DesignWare MIPI DSI Host Controller IP
+  - A TOP control block controlling the Clocks & Resets of the IP
+
+allOf:
+  - $ref: dsi-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-g12a-dw-mipi-dsi
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    minItems: 2
+    items:
+      - const: pclk
+      - const: px_clk
+      - const: meas_clk
+
+  resets:
+    minItems: 1
+
+  reset-names:
+    items:
+      - const: top
+
+  phys:
+    minItems: 1
+
+  phy-names:
+    items:
+      - const: dphy
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: Input node to receive pixel data.
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description: DSI output node to panel.
+
+    required:
+      - port at 0
+      - port at 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - phys
+  - phy-names
+  - ports
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    dsi at 7000 {
+          compatible = "amlogic,meson-g12a-dw-mipi-dsi";
+          reg = <0x6000 0x400>;
+          resets = <&reset_top>;
+          reset-names = "top";
+          clocks = <&clk_pclk>, <&clk_px>;
+          clock-names = "pclk", "px_clk";
+          phys = <&mipi_dphy>;
+          phy-names = "dphy";
+
+          ports {
+              #address-cells = <1>;
+              #size-cells = <0>;
+
+              /* VPU VENC Input */
+              mipi_dsi_venc_port: port at 0 {
+                  reg = <0>;
+
+                  mipi_dsi_in: endpoint {
+                       remote-endpoint = <&dpi_out>;
+                  };
+              };
+
+              /* DSI Output */
+              mipi_dsi_panel_port: port at 1 {
+                  reg = <1>;
+
+                  mipi_out_panel: endpoint {
+                      remote-endpoint = <&mipi_in_panel>;
+                  };
+              };
+          };
+    };
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:53 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:53 +0100
Subject: [PATCH v2 2/6] dt-bindings: display: meson-vpu: add third DPI output
 port
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-3-narmstrong@baylibre.com>

Add third port corresponding to the ENCL DPI encoder used to connect
to DSI or LVDS transceivers.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/display/amlogic,meson-vpu.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
index 851cb0781217..525a01a38568 100644
--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
+++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml
@@ -92,6 +92,11 @@ properties:
     description:
       A port node pointing to the HDMI-TX port node.
 
+  port at 2:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node pointing to the DPI port node (e.g. DSI or LVDS transceiver).
+
   "#address-cells":
     const: 1
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:54 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:54 +0100
Subject: [PATCH v2 3/6] drm/meson: venc: add ENCL encoder setup for MIPI-DSI
 output
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-4-narmstrong@baylibre.com>

This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
Amlogic AXG, G12A, G12B & SM1 SoCs.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_registers.h |  15 ++
 drivers/gpu/drm/meson/meson_venc.c      | 211 +++++++++++++++++++++++-
 drivers/gpu/drm/meson/meson_venc.h      |   6 +
 drivers/gpu/drm/meson/meson_vpp.h       |   2 +
 4 files changed, 232 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 0f3cafab8860..a422a8df1641 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -1300,13 +1300,28 @@
 #define RDMA_STATUS2 0x1116
 #define RDMA_STATUS3 0x1117
 #define L_GAMMA_CNTL_PORT 0x1400
+#define		L_GAMMA_CNTL_PORT_VCOM_POL	BIT(7)	/* RW */
+#define		L_GAMMA_CNTL_PORT_RVS_OUT	BIT(6)	/* RW */
+#define		L_GAMMA_CNTL_PORT_ADR_RDY	BIT(5)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_WR_RDY	BIT(4)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_RD_RDY	BIT(3)	/* Read Only */
+#define		L_GAMMA_CNTL_PORT_TR		BIT(2)	/* RW */
+#define		L_GAMMA_CNTL_PORT_SET		BIT(1)	/* RW */
+#define		L_GAMMA_CNTL_PORT_EN		BIT(0)	/* RW */
 #define L_GAMMA_DATA_PORT 0x1401
 #define L_GAMMA_ADDR_PORT 0x1402
+#define		L_GAMMA_ADDR_PORT_RD		BIT(12)
+#define		L_GAMMA_ADDR_PORT_AUTO_INC	BIT(11)
+#define		L_GAMMA_ADDR_PORT_SEL_R		BIT(10)
+#define		L_GAMMA_ADDR_PORT_SEL_G		BIT(9)
+#define		L_GAMMA_ADDR_PORT_SEL_B		BIT(8)
+#define		L_GAMMA_ADDR_PORT_ADDR		GENMASK(7, 0)
 #define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
 #define L_RGB_BASE_ADDR 0x1405
 #define L_RGB_COEFF_ADDR 0x1406
 #define L_POL_CNTL_ADDR 0x1407
 #define L_DITH_CNTL_ADDR 0x1408
+#define		L_DITH_CNTL_DITH10_EN	BIT(10)
 #define L_GAMMA_PROBE_CTRL 0x1409
 #define L_GAMMA_PROBE_COLOR_L 0x140a
 #define L_GAMMA_PROBE_COLOR_H 0x140b
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 3c55ed003359..eb2ac0549d46 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/iopoll.h>
 
 #include <drm/drm_modes.h>
 
@@ -1557,6 +1558,205 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 }
 EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
 
+static unsigned short meson_encl_gamma_table[256] = {
+	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
+	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
+	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
+	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
+	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
+	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
+	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
+	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
+	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
+	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
+	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
+	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
+	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
+	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
+	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
+	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
+};
+
+static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
+				       u32 rgb_mask)
+{
+	int i, ret;
+	u32 reg;
+
+	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+
+	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
+		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+
+	for (i = 0; i < 256; i++) {
+		ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+						 reg, reg & L_GAMMA_CNTL_PORT_WR_RDY,
+						 10, 10000);
+		if (ret)
+			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
+
+		writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT));
+	}
+
+	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
+					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
+	if (ret)
+		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
+
+	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
+		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23),
+		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
+}
+
+void meson_encl_load_gamma(struct meson_drm *priv)
+{
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G);
+	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B);
+
+	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN,
+			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
+}
+
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode)
+{
+	unsigned int max_pxcnt;
+	unsigned int max_lncnt;
+	unsigned int havon_begin;
+	unsigned int havon_end;
+	unsigned int vavon_bline;
+	unsigned int vavon_eline;
+	unsigned int hso_begin;
+	unsigned int hso_end;
+	unsigned int vso_begin;
+	unsigned int vso_end;
+	unsigned int vso_bline;
+	unsigned int vso_eline;
+
+	max_pxcnt = mode->htotal - 1;
+	max_lncnt = mode->vtotal - 1;
+	havon_begin = mode->htotal - mode->hsync_start;
+	havon_end = havon_begin + mode->hdisplay - 1;
+	vavon_bline = mode->vtotal - mode->vsync_start;
+	vavon_eline = vavon_bline + mode->vdisplay - 1;
+	hso_begin = 0;
+	hso_end = mode->hsync_end - mode->hsync_start;
+	vso_begin = 0;
+	vso_end = 0;
+	vso_bline = 0;
+	vso_eline = mode->vsync_end - mode->vsync_start;
+
+	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE));
+	writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN |
+		       ENCL_VIDEO_MODE_ADV_GAIN_HDTV |
+		       ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER,
+		       priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
+	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
+	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
+	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
+
+	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
+	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
+	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
+	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
+	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
+	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
+	writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK,
+		       priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
+
+	/* default black pattern */
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
+	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
+	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0,
+			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
+	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */
+
+	writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
+
+	/* DE signal for TTL */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
+
+	/* Hsync signal for TTL */
+	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
+	} else {
+		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
+		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
+	}
+	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
+
+	/* Vsync signal for TTL */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
+	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	} else {
+		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
+		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
+	}
+
+	/* DE signal */
+	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
+	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
+	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
+	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
+
+	/* Hsync signal */
+	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
+	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
+	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
+	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
+
+	/* Vsync signal */
+	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
+	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
+	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
+	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
+
+	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
+	writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2,
+		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
+
+	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
+}
+EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
+
 void meson_venci_cvbs_mode_set(struct meson_drm *priv,
 			       struct meson_cvbs_enci_mode *mode)
 {
@@ -1747,8 +1947,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
 
 void meson_venc_enable_vsync(struct meson_drm *priv)
 {
-	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
-		       priv->io_base + _REG(VENC_INTCTRL));
+	switch (priv->venc.current_mode) {
+	case MESON_VENC_MODE_MIPI_DSI:
+		writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+		break;
+	default:
+		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
+			       priv->io_base + _REG(VENC_INTCTRL));
+	}
 	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
 }
 
diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
index 9138255ffc9e..0f59adb1c6db 100644
--- a/drivers/gpu/drm/meson/meson_venc.h
+++ b/drivers/gpu/drm/meson/meson_venc.h
@@ -21,6 +21,7 @@ enum {
 	MESON_VENC_MODE_CVBS_PAL,
 	MESON_VENC_MODE_CVBS_NTSC,
 	MESON_VENC_MODE_HDMI,
+	MESON_VENC_MODE_MIPI_DSI,
 };
 
 struct meson_cvbs_enci_mode {
@@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
 	unsigned int analog_sync_adj;
 };
 
+/* LCD Encoder gamma setup */
+void meson_encl_load_gamma(struct meson_drm *priv);
+
 /* HDMI Clock parameters */
 enum drm_mode_status
 meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
@@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
 			      unsigned int ycrcb_map,
 			      bool yuv420_mode,
 			      const struct drm_display_mode *mode);
+void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
+				  const struct drm_display_mode *mode);
 unsigned int meson_venci_get_field(struct meson_drm *priv);
 
 void meson_venc_enable_vsync(struct meson_drm *priv);
diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
index afc9553ed8d3..b790042a1650 100644
--- a/drivers/gpu/drm/meson/meson_vpp.h
+++ b/drivers/gpu/drm/meson/meson_vpp.h
@@ -12,6 +12,8 @@
 struct drm_rect;
 struct meson_drm;
 
+/* Mux VIU/VPP to ENCL */
+#define MESON_VIU_VPP_MUX_ENCL	0x0
 /* Mux VIU/VPP to ENCI */
 #define MESON_VIU_VPP_MUX_ENCI	0x5
 /* Mux VIU/VPP to ENCP */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:55 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:55 +0100
Subject: [PATCH v2 4/6] drm/meson: vclk: add DSI clock config
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-5-narmstrong@baylibre.com>

The DSI path used the ENCL pixel encoder, thus this adds a clock
config using the HDMI PLL in order to feed the ENCL encoder via the
VCLK2 path and the CTS_ENCL clock output.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/meson_vclk.c | 47 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_vclk.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 2a82119eb58e..5e4d982be1c8 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -55,6 +55,8 @@
 #define VCLK2_DIV_MASK		0xff
 #define VCLK2_DIV_EN		BIT(16)
 #define VCLK2_DIV_RESET		BIT(17)
+#define CTS_ENCL_SEL_MASK	(0xf << 12)
+#define CTS_ENCL_SEL_SHIFT	12
 #define CTS_VDAC_SEL_MASK	(0xf << 28)
 #define CTS_VDAC_SEL_SHIFT	28
 #define HHI_VIID_CLK_CNTL	0x12c /* 0x4b offset in data sheet */
@@ -83,6 +85,7 @@
 #define VCLK_DIV12_EN		BIT(4)
 #define HHI_VID_CLK_CNTL2	0x194 /* 0x65 offset in data sheet */
 #define CTS_ENCI_EN		BIT(0)
+#define CTS_ENCL_EN		BIT(3)
 #define CTS_ENCP_EN		BIT(2)
 #define CTS_VDAC_EN		BIT(4)
 #define HDMI_TX_PIXEL_EN	BIT(5)
@@ -1024,6 +1027,47 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq,
 	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL, VCLK_EN, VCLK_EN);
 }
 
+static void meson_dsi_clock_config(struct meson_drm *priv, unsigned int freq)
+{
+	meson_hdmi_pll_generic_set(priv, freq * 10);
+
+	/* Setup vid_pll divider value /5 */
+	meson_vid_pll_set(priv, VID_PLL_DIV_5);
+
+	/* Disable VCLK2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, 0);
+
+	/* Setup the VCLK2 divider value /2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_MASK, 2 - 1);
+
+	/* select vid_pll for vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL,
+			   VCLK2_SEL_MASK, (0 << VCLK2_SEL_SHIFT));
+
+	/* enable vclk2 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_EN, VCLK2_EN);
+
+	/* select vclk2_div1 for encl */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV,
+			   CTS_ENCL_SEL_MASK, (8 << CTS_ENCL_SEL_SHIFT));
+
+	/* release vclk2_div_reset and enable vclk2_div */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_DIV, VCLK2_DIV_EN | VCLK2_DIV_RESET,
+			   VCLK2_DIV_EN);
+
+	/* enable vclk2_div1 gate */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_DIV1_EN, VCLK2_DIV1_EN);
+
+	/* reset vclk2 */
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, VCLK2_SOFT_RESET);
+	regmap_update_bits(priv->hhi, HHI_VIID_CLK_CNTL, VCLK2_SOFT_RESET, 0);
+
+	/* enable encl_clk */
+	regmap_update_bits(priv->hhi, HHI_VID_CLK_CNTL2, CTS_ENCL_EN, CTS_ENCL_EN);
+
+	usleep_range(10000, 11000);
+}
+
 void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		      unsigned int phy_freq, unsigned int vclk_freq,
 		      unsigned int venc_freq, unsigned int dac_freq,
@@ -1050,6 +1094,9 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
 		meson_vclk_set(priv, phy_freq, 0, 0, 0,
 			       VID_PLL_DIV_5, 2, 1, 1, false, false);
 		return;
+	} else if (target == MESON_VCLK_TARGET_DSI) {
+		meson_dsi_clock_config(priv, phy_freq);
+		return;
 	}
 
 	hdmi_tx_div = vclk_freq / dac_freq;
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h
index 60617aaf18dd..1152b3af8d2e 100644
--- a/drivers/gpu/drm/meson/meson_vclk.h
+++ b/drivers/gpu/drm/meson/meson_vclk.h
@@ -17,6 +17,7 @@ enum {
 	MESON_VCLK_TARGET_CVBS = 0,
 	MESON_VCLK_TARGET_HDMI = 1,
 	MESON_VCLK_TARGET_DMT = 2,
+	MESON_VCLK_TARGET_DSI = 3,
 };
 
 /* 27MHz is the CVBS Pixel Clock */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:56 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:56 +0100
Subject: [PATCH v2 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-6-narmstrong@baylibre.com>

This adds an encoder bridge designed to drive a MIPI-DSI display
by using the ENCL encoder through the internal MIPI DSI transceiver
connected to the output of the ENCL pixel encoder.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Makefile            |   2 +-
 drivers/gpu/drm/meson/meson_drv.c         |   7 +
 drivers/gpu/drm/meson/meson_encoder_dsi.c | 160 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
 4 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h

diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 3afa31bdc950..833e18c20603 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -2,7 +2,7 @@
 meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
 meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
 meson-drm-y += meson_rdma.o meson_osd_afbcd.o
-meson-drm-y += meson_encoder_hdmi.o
+meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 26aeaf0ab86e..15344cf9f913 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -33,6 +33,7 @@
 #include "meson_registers.h"
 #include "meson_encoder_cvbs.h"
 #include "meson_encoder_hdmi.h"
+#include "meson_encoder_dsi.h"
 #include "meson_viu.h"
 #include "meson_vpp.h"
 #include "meson_rdma.h"
@@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
 	if (ret)
 		goto exit_afbcd;
 
+	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
+		ret = meson_encoder_dsi_init(priv);
+		if (ret)
+			goto free_drm;
+	}
+
 	ret = meson_plane_create(priv);
 	if (ret)
 		goto exit_afbcd;
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
new file mode 100644
index 000000000000..12a586316183
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+
+#include "meson_drv.h"
+#include "meson_encoder_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+#include "meson_vclk.h"
+
+struct meson_encoder_dsi {
+	struct drm_encoder encoder;
+	struct drm_bridge bridge;
+	struct drm_bridge *next_bridge;
+	struct meson_drm *priv;
+};
+
+#define bridge_to_meson_encoder_dsi(x) \
+	container_of(x, struct meson_encoder_dsi, bridge)
+
+static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
+				    enum drm_bridge_attach_flags flags)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+
+	return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
+				 &encoder_dsi->bridge, flags);
+}
+
+static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
+
+	meson_venc_mipi_dsi_mode_set(priv, mode);
+	meson_encl_load_gamma(priv);
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, ENCL_VIDEO_MODE_ADV_VFIFO_EN,
+			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
+	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
+}
+
+static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
+					    struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = encoder_dsi->priv;
+
+	writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+
+	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
+}
+
+static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
+					     struct drm_bridge_state *bridge_state)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi =
+					bridge_to_meson_encoder_dsi(bridge);
+	struct meson_drm *priv = meson_encoder_dsi->priv;
+
+	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
+
+	writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
+}
+
+static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
+	.attach	= meson_encoder_dsi_attach,
+	/*
+	 * TOFIX: remove when dw-mipi-dsi moves out of mode_set
+	 * We should get rid of mode_set, but until dw-mipi-dsi uses it
+	 * we need to setup the pixel clock before the following
+	 * bridge tries to setup the HW.
+	 */
+	.mode_set = meson_encoder_dsi_mode_set,
+	.atomic_enable = meson_encoder_dsi_atomic_enable,
+	.atomic_disable	= meson_encoder_dsi_atomic_disable,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+};
+
+int meson_encoder_dsi_init(struct meson_drm *priv)
+{
+	struct meson_encoder_dsi *meson_encoder_dsi;
+	struct device_node *remote;
+	int ret;
+
+	meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
+	if (!meson_encoder_dsi)
+		return -ENOMEM;
+
+	/* DSI Transceiver Bridge */
+	remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
+	if (!remote) {
+		dev_err(priv->dev, "DSI transceiver device is disabled");
+		return 0;
+	}
+
+	meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
+	if (!meson_encoder_dsi->next_bridge) {
+		dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
+		return -EPROBE_DEFER;
+	}
+
+	/* DSI Encoder Bridge */
+	meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
+	meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
+	meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
+
+	drm_bridge_add(&meson_encoder_dsi->bridge);
+
+	meson_encoder_dsi->priv = priv;
+
+	/* Encoder */
+	ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
+		return ret;
+	}
+
+	meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
+
+	/* Attach DSI Encoder Bridge to Encoder */
+	ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
+	if (ret) {
+		dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * We should have now in place:
+	 * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
+	 */
+
+	dev_dbg(priv->dev, "DSI encoder initialized\n");
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.h b/drivers/gpu/drm/meson/meson_encoder_dsi.h
new file mode 100644
index 000000000000..0f4b641eb633
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_encoder_dsi.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ */
+
+#ifndef __MESON_ENCODER_DSI_H
+#define __MESON_ENCODER_DSI_H
+
+int meson_encoder_dsi_init(struct meson_drm *priv);
+
+#endif /* __MESON_ENCODER_DSI_H */
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 20 00:33:57 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:33:57 +0100
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-1-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
Message-ID: <20220120083357.1541262-7-narmstrong@baylibre.com>

The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
Glue on other Amlogic SoCs.

This adds support for the Glue managing the transceiver, mimicing the init flow provided
by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
Analog PHY in the proper way.

An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
DW-MIPI-DSI transceiver.

Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
---
 drivers/gpu/drm/meson/Kconfig             |   7 +
 drivers/gpu/drm/meson/Makefile            |   1 +
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
 4 files changed, 525 insertions(+)
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
 create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h

diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
index 6c70fc3214af..71a1364b51e1 100644
--- a/drivers/gpu/drm/meson/Kconfig
+++ b/drivers/gpu/drm/meson/Kconfig
@@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
 	default y if DRM_MESON
 	select DRM_DW_HDMI
 	imply DRM_DW_HDMI_I2S_AUDIO
+
+config DRM_MESON_DW_MIPI_DSI
+	tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
+	depends on DRM_MESON
+	default y if DRM_MESON
+	select DRM_DW_MIPI_DSI
+	select GENERIC_PHY_MIPI_DPHY
diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
index 833e18c20603..43071bdbd4b9 100644
--- a/drivers/gpu/drm/meson/Makefile
+++ b/drivers/gpu/drm/meson/Makefile
@@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
 
 obj-$(CONFIG_DRM_MESON) += meson-drm.o
 obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
+obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
new file mode 100644
index 000000000000..75f373152caf
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/reset.h>
+#include <linux/phy/phy.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/bridge/dw_mipi_dsi.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+
+#include "meson_drv.h"
+#include "meson_dw_mipi_dsi.h"
+#include "meson_registers.h"
+#include "meson_venc.h"
+
+#define DRIVER_NAME "meson-dw-mipi-dsi"
+#define DRIVER_DESC "Amlogic Meson MIPI-DSI DRM driver"
+
+struct meson_dw_mipi_dsi {
+	struct meson_drm *priv;
+	struct device *dev;
+	void __iomem *base;
+	struct phy *phy;
+	union phy_configure_opts phy_opts;
+	struct dw_mipi_dsi *dmd;
+	struct dw_mipi_dsi_plat_data pdata;
+	struct mipi_dsi_device *dsi_device;
+	const struct drm_display_mode *mode;
+	struct clk *px_clk;
+};
+
+#define encoder_to_meson_dw_mipi_dsi(x) \
+	container_of(x, struct meson_dw_mipi_dsi, encoder)
+
+static void meson_dw_mipi_dsi_hw_init(struct meson_dw_mipi_dsi *mipi_dsi)
+{
+	/* Software reset */
+	writel_bits_relaxed(MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+	writel_bits_relaxed(MIPI_DSI_TOP_SW_RESET_DWC | MIPI_DSI_TOP_SW_RESET_INTR |
+			    MIPI_DSI_TOP_SW_RESET_DPI | MIPI_DSI_TOP_SW_RESET_TIMING,
+			    0, mipi_dsi->base + MIPI_DSI_TOP_SW_RESET);
+
+	/* Enable clocks */
+	writel_bits_relaxed(MIPI_DSI_TOP_CLK_SYSCLK_EN | MIPI_DSI_TOP_CLK_PIXCLK_EN,
+			    MIPI_DSI_TOP_CLK_SYSCLK_EN | MIPI_DSI_TOP_CLK_PIXCLK_EN,
+			    mipi_dsi->base + MIPI_DSI_TOP_CLK_CNTL);
+
+	/* Take memory out of power down */
+	writel_relaxed(0, mipi_dsi->base + MIPI_DSI_TOP_MEM_PD);
+}
+
+static int dw_mipi_dsi_phy_init(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	unsigned int dpi_data_format, venc_data_width;
+	int ret;
+
+	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+	if (ret) {
+		pr_err("Failed to set DSI PLL rate %lu\n",
+		       mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate);
+
+		return ret;
+	}
+
+	switch (mipi_dsi->dsi_device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		dpi_data_format = DPI_COLOR_24BIT;
+		venc_data_width = VENC_IN_COLOR_24B;
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		dpi_data_format = DPI_COLOR_18BIT_CFG_2;
+		venc_data_width = VENC_IN_COLOR_18B;
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		return -EINVAL;
+	};
+
+	/* Configure color format for DPI register */
+	writel_relaxed(FIELD_PREP(MIPI_DSI_TOP_DPI_COLOR_MODE, dpi_data_format) |
+		       FIELD_PREP(MIPI_DSI_TOP_IN_COLOR_MODE, venc_data_width) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP2_SEL, 2) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP1_SEL, 1) |
+		       FIELD_PREP(MIPI_DSI_TOP_COMP0_SEL, 0) |
+		       (mipi_dsi->mode->flags & DRM_MODE_FLAG_NHSYNC ?
+				0 : MIPI_DSI_TOP_HSYNC_INVERT) |
+		       (mipi_dsi->mode->flags & DRM_MODE_FLAG_NVSYNC ?
+				0 : MIPI_DSI_TOP_VSYNC_INVERT),
+			mipi_dsi->base + MIPI_DSI_TOP_CNTL);
+
+	return phy_configure(mipi_dsi->phy, &mipi_dsi->phy_opts);
+}
+
+static void dw_mipi_dsi_phy_power_on(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (phy_power_on(mipi_dsi->phy))
+		dev_warn(mipi_dsi->dev, "Failed to power on PHY\n");
+}
+
+static void dw_mipi_dsi_phy_power_off(void *priv_data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (phy_power_off(mipi_dsi->phy))
+		dev_warn(mipi_dsi->dev, "Failed to power off PHY\n");
+}
+
+static int
+dw_mipi_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode,
+			  unsigned long mode_flags, u32 lanes, u32 format,
+			  unsigned int *lane_mbps)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+	int bpp;
+
+	mipi_dsi->mode = mode;
+
+	bpp = mipi_dsi_pixel_format_to_bpp(mipi_dsi->dsi_device->format);
+
+	phy_mipi_dphy_get_default_config(mode->clock * 1000,
+					 bpp, mipi_dsi->dsi_device->lanes,
+					 &mipi_dsi->phy_opts.mipi_dphy);
+
+	*lane_mbps = mipi_dsi->phy_opts.mipi_dphy.hs_clk_rate / 1000000;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps,
+			   struct dw_mipi_dsi_dphy_timing *timing)
+{
+	/* TOFIX handle other cases */
+
+	timing->clk_lp2hs = 37;
+	timing->clk_hs2lp = 135;
+	timing->data_lp2hs = 50;
+	timing->data_hs2lp = 3;
+
+	return 0;
+}
+
+static int
+dw_mipi_dsi_get_esc_clk_rate(void *priv_data, unsigned int *esc_clk_rate)
+{
+	*esc_clk_rate = 4; /* Mhz */
+
+	return 0;
+}
+
+static const struct dw_mipi_dsi_phy_ops meson_dw_mipi_dsi_phy_ops = {
+	.init = dw_mipi_dsi_phy_init,
+	.power_on = dw_mipi_dsi_phy_power_on,
+	.power_off = dw_mipi_dsi_phy_power_off,
+	.get_lane_mbps = dw_mipi_dsi_get_lane_mbps,
+	.get_timing = dw_mipi_dsi_phy_get_timing,
+	.get_esc_clk_rate = dw_mipi_dsi_get_esc_clk_rate,
+};
+
+static int meson_dw_mipi_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(dev);
+	struct drm_device *drm = data;
+	struct meson_drm *priv = drm->dev_private;
+
+	/* Check before if we are supposed to have a sub-device... */
+	if (!mipi_dsi->dsi_device) {
+		dw_mipi_dsi_remove(mipi_dsi->dmd);
+		return -EPROBE_DEFER;
+	}
+
+	mipi_dsi->priv = priv;
+
+	meson_dw_mipi_dsi_hw_init(mipi_dsi);
+
+	return 0;
+}
+
+static const struct component_ops meson_dw_mipi_dsi_ops = {
+	.bind	= meson_dw_mipi_dsi_bind,
+};
+
+static int meson_dw_mipi_dsi_host_attach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	mipi_dsi->dsi_device = device;
+
+	switch (device->format) {
+	case MIPI_DSI_FMT_RGB888:
+		break;
+	case MIPI_DSI_FMT_RGB666:
+		break;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB565:
+		dev_err(mipi_dsi->dev, "invalid pixel format %d\n", device->format);
+		return -EINVAL;
+	};
+
+	return phy_init(mipi_dsi->phy);
+}
+
+static int meson_dw_mipi_dsi_host_detach(void *priv_data,
+					 struct mipi_dsi_device *device)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = priv_data;
+
+	if (device == mipi_dsi->dsi_device)
+		mipi_dsi->dsi_device = NULL;
+	else
+		return -EINVAL;
+
+	return phy_exit(mipi_dsi->phy);
+}
+
+static const struct dw_mipi_dsi_host_ops meson_dw_mipi_dsi_host_ops = {
+	.attach = meson_dw_mipi_dsi_host_attach,
+	.detach = meson_dw_mipi_dsi_host_detach,
+};
+
+static int meson_dw_mipi_dsi_probe(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi;
+	struct reset_control *top_rst;
+	struct resource *res;
+	int ret;
+
+	mipi_dsi = devm_kzalloc(&pdev->dev, sizeof(*mipi_dsi), GFP_KERNEL);
+	if (!mipi_dsi)
+		return -ENOMEM;
+
+	mipi_dsi->dev = &pdev->dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	mipi_dsi->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(mipi_dsi->base))
+		return PTR_ERR(mipi_dsi->base);
+
+	mipi_dsi->phy = devm_phy_get(&pdev->dev, "dphy");
+	if (IS_ERR(mipi_dsi->phy)) {
+		ret = PTR_ERR(mipi_dsi->phy);
+		dev_err(&pdev->dev, "failed to get mipi dphy: %d\n", ret);
+		return ret;
+	}
+
+	mipi_dsi->px_clk = devm_clk_get(&pdev->dev, "px_clk");
+	if (IS_ERR(mipi_dsi->px_clk)) {
+		dev_err(&pdev->dev, "Unable to get PLL clk\n");
+		return PTR_ERR(mipi_dsi->px_clk);
+	}
+
+	/*
+	 * We use a TOP reset signal because the APB reset signal
+	 * is handled by the TOP control registers.
+	 */
+	top_rst = devm_reset_control_get_exclusive(&pdev->dev, "top");
+	if (IS_ERR(top_rst)) {
+		ret = PTR_ERR(top_rst);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev, "Unable to get reset control: %d\n", ret);
+
+		return ret;
+	}
+
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to prepare/enable PX clock\n");
+		return ret;
+	}
+
+	reset_control_assert(top_rst);
+	usleep_range(10, 20);
+	reset_control_deassert(top_rst);
+
+	/* MIPI DSI Controller */
+
+	mipi_dsi->pdata.base = mipi_dsi->base;
+	mipi_dsi->pdata.max_data_lanes = 4;
+	mipi_dsi->pdata.phy_ops = &meson_dw_mipi_dsi_phy_ops;
+	mipi_dsi->pdata.host_ops = &meson_dw_mipi_dsi_host_ops;
+	mipi_dsi->pdata.priv_data = mipi_dsi;
+	platform_set_drvdata(pdev, mipi_dsi);
+
+	mipi_dsi->dmd = dw_mipi_dsi_probe(pdev, &mipi_dsi->pdata);
+	if (IS_ERR(mipi_dsi->dmd)) {
+		ret = PTR_ERR(mipi_dsi->dmd);
+		if (ret != -EPROBE_DEFER)
+			dev_err(&pdev->dev,
+				"Failed to probe dw_mipi_dsi: %d\n", ret);
+		goto err_clkdisable;
+	}
+
+	return component_add(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+err_clkdisable:
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return ret;
+}
+
+static int meson_dw_mipi_dsi_remove(struct platform_device *pdev)
+{
+	struct meson_dw_mipi_dsi *mipi_dsi = dev_get_drvdata(&pdev->dev);
+
+	dw_mipi_dsi_remove(mipi_dsi->dmd);
+
+	component_del(mipi_dsi->dev, &meson_dw_mipi_dsi_ops);
+
+	clk_disable_unprepare(mipi_dsi->px_clk);
+
+	return 0;
+}
+
+static const struct of_device_id meson_dw_mipi_dsi_of_table[] = {
+	{ .compatible = "amlogic,meson-g12a-dw-mipi-dsi", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, meson_dw_mipi_dsi_of_table);
+
+static struct platform_driver meson_dw_mipi_dsi_platform_driver = {
+	.probe		= meson_dw_mipi_dsi_probe,
+	.remove		= meson_dw_mipi_dsi_remove,
+	.driver		= {
+		.name		= DRIVER_NAME,
+		.of_match_table	= meson_dw_mipi_dsi_of_table,
+	},
+};
+module_platform_driver(meson_dw_mipi_dsi_platform_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong at baylibre.com>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
new file mode 100644
index 000000000000..e1bd6b85d6a3
--- /dev/null
+++ b/drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong at baylibre.com>
+ * Copyright (C) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_DW_MIPI_DSI_H
+#define __MESON_DW_MIPI_DSI_H
+
+/* Top-level registers */
+/* [31: 4]    Reserved.     Default 0.
+ *     [3] RW timing_rst_n: Default 1.
+ *		1=Assert SW reset of timing feature.   0=Release reset.
+ *     [2] RW dpi_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_dpi block.   0=Release reset.
+ *     [1] RW intr_rst_n: Default 1.
+ *		1=Assert SW reset on mipi_dsi_host_intr block.  0=Release reset.
+ *     [0] RW dwc_rst_n:  Default 1.
+ *		1=Assert SW reset on IP core.   0=Release reset.
+ */
+#define MIPI_DSI_TOP_SW_RESET                      0x3c0
+
+#define MIPI_DSI_TOP_SW_RESET_DWC	BIT(0)
+#define MIPI_DSI_TOP_SW_RESET_INTR	BIT(1)
+#define MIPI_DSI_TOP_SW_RESET_DPI	BIT(2)
+#define MIPI_DSI_TOP_SW_RESET_TIMING	BIT(3)
+
+/* [31: 5] Reserved.   Default 0.
+ *     [4] RW manual_edpihalt: Default 0.
+ *		1=Manual suspend VencL; 0=do not suspend VencL.
+ *     [3] RW auto_edpihalt_en: Default 0.
+ *		1=Enable IP's edpihalt signal to suspend VencL;
+ *		0=IP's edpihalt signal does not affect VencL.
+ *     [2] RW clock_freerun: Apply to auto-clock gate only. Default 0.
+ *		0=Default, use auto-clock gating to save power;
+ *		1=use free-run clock, disable auto-clock gating, for debug mode.
+ *     [1] RW enable_pixclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable pixclk.      Default 0.
+ *     [0] RW enable_sysclk: A manual clock gate option, due to DWC IP does not
+ *		have auto-clock gating. 1=Enable sysclk.      Default 0.
+ */
+#define MIPI_DSI_TOP_CLK_CNTL                      0x3c4
+
+#define MIPI_DSI_TOP_CLK_SYSCLK_EN	BIT(0)
+#define MIPI_DSI_TOP_CLK_PIXCLK_EN	BIT(1)
+
+/* [31:24]    Reserved. Default 0.
+ * [23:20] RW dpi_color_mode: Define DPI pixel format. Default 0.
+ *		0=16-bit RGB565 config 1;
+ *		1=16-bit RGB565 config 2;
+ *		2=16-bit RGB565 config 3;
+ *		3=18-bit RGB666 config 1;
+ *		4=18-bit RGB666 config 2;
+ *		5=24-bit RGB888;
+ *		6=20-bit YCbCr 4:2:2;
+ *		7=24-bit YCbCr 4:2:2;
+ *		8=16-bit YCbCr 4:2:2;
+ *		9=30-bit RGB;
+ *		10=36-bit RGB;
+ *		11=12-bit YCbCr 4:2:0.
+ *    [19] Reserved. Default 0.
+ * [18:16] RW in_color_mode:  Define VENC data width. Default 0.
+ *		0=30-bit pixel;
+ *		1=24-bit pixel;
+ *		2=18-bit pixel, RGB666;
+ *		3=16-bit pixel, RGB565.
+ * [15:14] RW chroma_subsample: Define method of chroma subsampling. Default 0.
+ *		Applicable to YUV422 or YUV420 only.
+ *		0=Use even pixel's chroma;
+ *		1=Use odd pixel's chroma;
+ *		2=Use averaged value between even and odd pair.
+ * [13:12] RW comp2_sel:  Select which component to be Cr or B: Default 2.
+ *		0=comp0; 1=comp1; 2=comp2.
+ * [11:10] RW comp1_sel:  Select which component to be Cb or G: Default 1.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *  [9: 8] RW comp0_sel:  Select which component to be Y  or R: Default 0.
+ *		0=comp0; 1=comp1; 2=comp2.
+ *     [7]    Reserved. Default 0.
+ *     [6] RW de_pol:  Default 0.
+ *		If DE input is active low, set to 1 to invert to active high.
+ *     [5] RW hsync_pol: Default 0.
+ *		If HS input is active low, set to 1 to invert to active high.
+ *     [4] RW vsync_pol: Default 0.
+ *		If VS input is active low, set to 1 to invert to active high.
+ *     [3] RW dpicolorm: Signal to IP.   Default 0.
+ *     [2] RW dpishutdn: Signal to IP.   Default 0.
+ *     [1]    Reserved.  Default 0.
+ *     [0]    Reserved.  Default 0.
+ */
+#define MIPI_DSI_TOP_CNTL                          0x3c8
+
+/* VENC data width */
+#define VENC_IN_COLOR_30B   0x0
+#define VENC_IN_COLOR_24B   0x1
+#define VENC_IN_COLOR_18B   0x2
+#define VENC_IN_COLOR_16B   0x3
+
+/* DPI pixel format */
+#define DPI_COLOR_16BIT_CFG_1		0
+#define DPI_COLOR_16BIT_CFG_2		1
+#define DPI_COLOR_16BIT_CFG_3		2
+#define DPI_COLOR_18BIT_CFG_1		3
+#define DPI_COLOR_18BIT_CFG_2		4
+#define DPI_COLOR_24BIT			5
+#define DPI_COLOR_20BIT_YCBCR_422	6
+#define DPI_COLOR_24BIT_YCBCR_422	7
+#define DPI_COLOR_16BIT_YCBCR_422	8
+#define DPI_COLOR_30BIT			9
+#define DPI_COLOR_36BIT			10
+#define DPI_COLOR_12BIT_YCBCR_420	11
+
+#define MIPI_DSI_TOP_DPI_COLOR_MODE	GENMASK(23, 20)
+#define MIPI_DSI_TOP_IN_COLOR_MODE	GENMASK(18, 16)
+#define MIPI_DSI_TOP_CHROMA_SUBSAMPLE	GENMASK(15, 14)
+#define MIPI_DSI_TOP_COMP2_SEL		GENMASK(13, 12)
+#define MIPI_DSI_TOP_COMP1_SEL		GENMASK(11, 10)
+#define MIPI_DSI_TOP_COMP0_SEL		GENMASK(9, 8)
+#define MIPI_DSI_TOP_DE_INVERT		BIT(6)
+#define MIPI_DSI_TOP_HSYNC_INVERT	BIT(5)
+#define MIPI_DSI_TOP_VSYNC_INVERT	BIT(4)
+#define MIPI_DSI_TOP_DPICOLORM		BIT(3)
+#define MIPI_DSI_TOP_DPISHUTDN		BIT(2)
+
+#define MIPI_DSI_TOP_SUSPEND_CNTL                  0x3cc
+#define MIPI_DSI_TOP_SUSPEND_LINE                  0x3d0
+#define MIPI_DSI_TOP_SUSPEND_PIX                   0x3d4
+#define MIPI_DSI_TOP_MEAS_CNTL                     0x3d8
+/* [0] R  stat_edpihalt:  edpihalt signal from IP.    Default 0. */
+#define MIPI_DSI_TOP_STAT                          0x3dc
+#define MIPI_DSI_TOP_MEAS_STAT_TE0                 0x3e0
+#define MIPI_DSI_TOP_MEAS_STAT_TE1                 0x3e4
+#define MIPI_DSI_TOP_MEAS_STAT_VS0                 0x3e8
+#define MIPI_DSI_TOP_MEAS_STAT_VS1                 0x3ec
+/* [31:16] RW intr_stat/clr. Default 0.
+ *		For each bit, read as this interrupt level status,
+ *		write 1 to clear.
+ * [31:22] Reserved
+ * [   21] stat/clr of eof interrupt
+ * [   21] vde_fall interrupt
+ * [   19] stat/clr of de_rise interrupt
+ * [   18] stat/clr of vs_fall interrupt
+ * [   17] stat/clr of vs_rise interrupt
+ * [   16] stat/clr of dwc_edpite interrupt
+ * [15: 0] RW intr_enable. Default 0.
+ *		For each bit, 1=enable this interrupt, 0=disable.
+ *	[15: 6] Reserved
+ *	[    5] eof interrupt
+ *	[    4] de_fall interrupt
+ *	[    3] de_rise interrupt
+ *	[    2] vs_fall interrupt
+ *	[    1] vs_rise interrupt
+ *	[    0] dwc_edpite interrupt
+ */
+#define MIPI_DSI_TOP_INTR_CNTL_STAT                0x3f0
+// 31: 2    Reserved.   Default 0.
+//  1: 0 RW mem_pd.     Default 3.
+#define MIPI_DSI_TOP_MEM_PD                        0x3f4
+
+#endif /* __MESON_DW_MIPI_DSI_H */
-- 
2.25.1



From yu.tu at amlogic.com  Thu Jan 20 00:43:05 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Thu, 20 Jan 2022 16:43:05 +0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <7hfspjqrn7.fsf@baylibre.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <7hfspjqrn7.fsf@baylibre.com>
Message-ID: <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>

Hi Kevin,
	Thank you very much for your reply.

On 2022/1/20 6:37, Kevin Hilman wrote:
> [ EXTERNAL EMAIL ]
> 
> Hello,
> 
> Yu Tu <yu.tu at amlogic.com> writes:
> 
>> Using the common Clock code to describe the UART baud rate
>> clock makes it easier for the UART driver to be compatible
>> with the baud rate requirements of the UART IP on different
>> meson chips. Add Meson S4 SoC compatible.
> 
> Could you describe how this was tested and on which SoCs?  There seem to
> be some changes in this series that might affect previous SoCs.
> 
For me, the board starts normally and prints. My intention was to add 
the S4 SOC UART compatible, but for the S4 our baud rate clock is 
calculated at 12MHz by default.So a series of changes were made at your 
suggestion.

Since most SoCs are too old, I was able to find all the platforms myself 
such as Meson6, Meson8, Meson8b, GXL and so on. I only tested it with 
G12A and S4.But when I talked to Martin earlier he tried meson8b's log.
The test patch is in the attachment.

I have found that on some boards with this change, the initcall_debug 
Uart driver takes longer to initialize. Running the stty command to 
change the baud rate at the same time may cause a jam.

I'd love to know what else you suggest.

> Thanks,
> 
> Kevin
> 
> 
-------------- next part --------------
?# cat /sys/kernel/debug/clk//clk_summary | head
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
 xtal                                 6        6        0    24000000          0     0  50000         Y
    ff803000.serial#xtal_div          1        1        0    12000000          0     0  50000         Y
       ff803000.serial#use_xtal       1        1        0    12000000          0     0  50000         Y
          ff803000.serial#baud_div       1        1        0      115385          0     0  50000         Y
    cts_oscin                         0        0        0    24000000          0     0  50000         Y
       g12a_ao_cec_pre                0        0        0    24000000          0     0  50000         N
          g12a_ao_cec_div             0        0        0       32742          0     0  50000         Y
-------------- next part --------------
# cat /sys/kernel/debug/clk/clk_summary 
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
[...]
 xtal                                 6        6        2    24000000          0     0  50000         Y
[...]
    c81004c0.serial#xtal_div3         0        0        0     8000000          0     0  50000         Y
[...]
    fixed_pll_dco                     1        1        0  2550000000          0     0  50000         Y
       fixed_pll                      1        1        0  2550000000          0     0  50000         Y
[...]
          fclk_div3_div               1        1        0   850000000          0     0  50000         Y
             fclk_div3                2        2        0   850000000          0     0  50000         Y
[...]
                mpeg_clk_sel          1        1        0   850000000          0     0  50000         Y
                   mpeg_clk_div       1        1        0   141666667          0     0  50000         Y
                      clk81          17       20        0   141666667          0     0  50000         Y
[...]
                         c81004c0.serial#clk81_div4       1        1        0    35416666          0     0  50000         Y
                            c81004c0.serial#use_xtal       1        1        0    35416666          0     0  50000         Y
                               c81004c0.serial#baud_div       1        1        0      115364          0     0  50000         Y
-------------- next part --------------
?# cat /sys/kernel/debug/clk/clk_summary | head
                                 enable  prepare  protect                                duty  hardware
   clock                          count    count    count        rate   accuracy phase  cycle    enable
-------------------------------------------------------------------------------------------------------
 xtal                                 7        7        0    24000000          0     0  50000         Y
    fe07a000.serial#xtal_div          1        1        0    12000000          0     0  50000         Y
       fe07a000.serial#use_xtal       1        1        0    12000000          0     0  50000         Y
          fe07a000.serial#baud_div       1        1        0      923077          0     0  50000         Y
    hdcp22_skpclk_mux                 0        0        0    24000000          0     0  50000         Y
       hdcp22_skpclk_div              0        0        0    24000000          0     0  50000         Y
          hdcp22_skpclk_gate          0        0        0    24000000          0     0  50000         N

From Eugen.Hristev at microchip.com  Thu Jan 20 00:43:33 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Thu, 20 Jan 2022 08:43:33 +0000
Subject: [PATCH v3 23/23] media: atmel: atmel-isc: change format
 propagation to subdev into only verification
In-Reply-To: <20220112092137.rzgmo436hjl2bdfv@uno.localdomain>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-24-eugen.hristev@microchip.com>
 <20220112092137.rzgmo436hjl2bdfv@uno.localdomain>
Message-ID: <9470258e-544c-ae65-2222-7a28467c7c99@microchip.com>

On 1/12/22 11:21 AM, Jacopo Mondi wrote:
> Hi Eugen


Hi Jacopo,

> 
> On Mon, Dec 13, 2021 at 03:49:40PM +0200, Eugen Hristev wrote:
>> As a top MC video driver, the atmel-isc should not propagate the format to the
>> subdevice.
>> It should rather check at streamon() time if the subdev is properly configured
>> with a compatible format.
>> Removed the whole format finding logic, and reworked the format verification
>> at streamon time, such that the ISC will return an error if the subdevice
>> is not properly configured.
>> With this being done, the module parameter 'sensor_prefered' makes no sense
>> anymore. The ISC should not decide which format the sensor is using. The
>> ISC should only cope with the situation and inform userspace if the streaming
>> is possible in the current configuration.
> 
> Sounds great!
> 
>>
>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>> ---
>> Changes in v3:
>> - clamp to maximum resolution once the frame size from the subdev is found
>>
>>   drivers/media/platform/atmel/atmel-isc-base.c | 271 ++++++++----------
>>   drivers/media/platform/atmel/atmel-isc.h      |   1 +
>>   2 files changed, 126 insertions(+), 146 deletions(-)
>>
>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>> index 31c8e3029eee..00c8c9588a78 100644
>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>> @@ -36,11 +36,6 @@ static unsigned int debug;
>>   module_param(debug, int, 0644);
>>   MODULE_PARM_DESC(debug, "debug level (0-2)");
>>
>> -static unsigned int sensor_preferred = 1;
>> -module_param(sensor_preferred, uint, 0644);
>> -MODULE_PARM_DESC(sensor_preferred,
>> -              "Sensor is preferred to output the specified format (1-on 0-off), default 1");
>> -
>>   #define ISC_IS_FORMAT_RAW(mbus_code) \
>>        (((mbus_code) & 0xf000) == 0x3000)
>>
>> @@ -532,7 +527,7 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
>>         * convert it to any of the formats that we usually can with a
>>         * RAW sensor. Thus, do not advertise them.
>>         */
>> -     if (!isc->config.sd_format ||
>> +     if (isc->config.sd_format &&
> 
> Is this change intentional ?
> 
>>            !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>>                return -EINVAL;
>>
>> @@ -621,20 +616,30 @@ static int isc_try_validate_formats(struct isc_device *isc)
>>                break;
>>        default:
>>        /* any other different formats are not supported */
>> +             v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n");
>>                ret = -EINVAL;
>>        }
>>        v4l2_dbg(1, debug, &isc->v4l2_dev,
>>                 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
>>                 rgb, yuv, grey, bayer);
> 
> Would it make sense to move this before the switch so that the
> error messages, if any, appear later ?

Actually, no, because the variables rgb, yuv, grey, bayer, are set 
according to what happens in the switch
> 
>>
>> -     /* we cannot output RAW if we do not receive RAW */
>> -     if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
>> +     if ((bayer) &&
>> +         !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
>> +             v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n");
>>                return -EINVAL;
>> +     }
>>
>> -     /* we cannot output GREY if we do not receive RAW/GREY */
>>        if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
>> -         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
>> +         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
>> +             v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
>>                return -EINVAL;
>> +     }
>> +
>> +     if ((rgb || bayer || yuv) &&
>> +         ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
>> +             v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n");
>> +             return -EINVAL;
>> +     }
>>
>>        return ret;
>>   }
>> @@ -862,7 +867,7 @@ static void isc_try_fse(struct isc_device *isc,
>>         * If we do not know yet which format the subdev is using, we cannot
>>         * do anything.
>>         */
>> -     if (!isc->try_config.sd_format)
>> +     if (!isc->config.sd_format)
>>                return;
>>
>>        fse.code = isc->try_config.sd_format->mbus_code;
>> @@ -883,180 +888,141 @@ static void isc_try_fse(struct isc_device *isc,
>>        }
>>   }
>>
>> -static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
>> -                     u32 *code)
>> +static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
>>   {
>> -     int i;
>> -     struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
>>        struct v4l2_pix_format *pixfmt = &f->fmt.pix;
>> -     struct v4l2_subdev_pad_config pad_cfg = {};
>> -     struct v4l2_subdev_state pad_state = {
>> -             .pads = &pad_cfg
>> -             };
>> -     struct v4l2_subdev_format format = {
>> -             .which = V4L2_SUBDEV_FORMAT_TRY,
>> -     };
>> -     u32 mbus_code;
>> -     int ret;
>> -     bool rlp_dma_direct_dump = false;
>> +     unsigned int i;
>>
>>        if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>>                return -EINVAL;
>>
>> -     /* Step 1: find a RAW format that is supported */
>> -     for (i = 0; i < isc->num_user_formats; i++) {
>> -             if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
>> -                     sd_fmt = isc->user_formats[i];
>> +     isc->try_config.fourcc = isc->user_formats[0]->fourcc;
>> +
>> +     /* find if the format requested is supported */
>> +     for (i = 0; i < isc->controller_formats_size; i++)
>> +             if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
>> +                     isc->try_config.fourcc = pixfmt->pixelformat;
>>                        break;
>>                }
>> -     }
>> -     /* Step 2: We can continue with this RAW format, or we can look
>> -      * for better: maybe sensor supports directly what we need.
>> -      */
>> -     direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
>> -
>> -     /* Step 3: We have both. We decide given the module parameter which
>> -      * one to use.
>> -      */
>> -     if (direct_fmt && sd_fmt && sensor_preferred)
>> -             sd_fmt = direct_fmt;
>> -
>> -     /* Step 4: we do not have RAW but we have a direct format. Use it. */
>> -     if (direct_fmt && !sd_fmt)
>> -             sd_fmt = direct_fmt;
>> -
>> -     /* Step 5: if we are using a direct format, we need to package
>> -      * everything as 8 bit data and just dump it
>> -      */
>> -     if (sd_fmt == direct_fmt)
>> -             rlp_dma_direct_dump = true;
>> -
>> -     /* Step 6: We have no format. This can happen if the userspace
>> -      * requests some weird/invalid format.
>> -      * In this case, default to whatever we have
>> -      */
>> -     if (!sd_fmt && !direct_fmt) {
>> -             sd_fmt = isc->user_formats[isc->num_user_formats - 1];
>> -             v4l2_dbg(1, debug, &isc->v4l2_dev,
>> -                      "Sensor not supporting %.4s, using %.4s\n",
>> -                      (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
>> -     }
>> -
>> -     if (!sd_fmt) {
>> -             ret = -EINVAL;
>> -             goto isc_try_fmt_err;
>> -     }
>> -
>> -     /* Step 7: Print out what we decided for debugging */
>> -     v4l2_dbg(1, debug, &isc->v4l2_dev,
>> -              "Preferring to have sensor using format %.4s\n",
>> -              (char *)&sd_fmt->fourcc);
>> -
>> -     /* Step 8: at this moment we decided which format the subdev will use */
>> -     isc->try_config.sd_format = sd_fmt;
>> -
>> -     /* Limit to Atmel ISC hardware capabilities */
>> -     if (pixfmt->width > isc->max_width)
>> -             pixfmt->width = isc->max_width;
>> -     if (pixfmt->height > isc->max_height)
>> -             pixfmt->height = isc->max_height;
>> -
>> -     /*
>> -      * The mbus format is the one the subdev outputs.
>> -      * The pixels will be transferred in this format Sensor -> ISC
>> -      */
>> -     mbus_code = sd_fmt->mbus_code;
>> -
>> -     /*
>> -      * Validate formats. If the required format is not OK, default to raw.
>> -      */
>> -
>> -     isc->try_config.fourcc = pixfmt->pixelformat;
>> -
>> -     if (isc_try_validate_formats(isc)) {
>> -             pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
>> -             /* Re-try to validate the new format */
>> -             ret = isc_try_validate_formats(isc);
>> -             if (ret)
>> -                     goto isc_try_fmt_err;
>> -     }
>> -
>> -     ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
>> -     if (ret)
>> -             goto isc_try_fmt_err;
>> -
>> -     ret = isc_try_configure_pipeline(isc);
>> -     if (ret)
>> -             goto isc_try_fmt_err;
>>
>> -     /* Obtain frame sizes if possible to have crop requirements ready */
>> -     isc_try_fse(isc, &pad_state);
>> -
>> -     v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
>> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
>> -                            &pad_state, &format);
>> -     if (ret < 0)
>> -             goto isc_try_fmt_subdev_err;
>> +     /* If we did not find the requested format, we will fallback here */
>> +     pixfmt->pixelformat = isc->try_config.fourcc;
>> +     pixfmt->colorspace = V4L2_COLORSPACE_SRGB;
>> +     pixfmt->field = V4L2_FIELD_NONE;
>>
>> -     v4l2_fill_pix_format(pixfmt, &format.format);
>> +     isc_try_configure_rlp_dma(isc, false);
>>
>>        /* Limit to Atmel ISC hardware capabilities */
>> -     if (pixfmt->width > isc->max_width)
>> -             pixfmt->width = isc->max_width;
>> -     if (pixfmt->height > isc->max_height)
>> -             pixfmt->height = isc->max_height;
>> +     v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
>> +                           &pixfmt->height, 16, isc->max_height, 0, 0);
>>
>>        pixfmt->field = V4L2_FIELD_NONE;
>>        pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
>>        pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
>>                             pixfmt->height;
>>
>> -     if (code)
>> -             *code = mbus_code;
>> +     isc->try_fmt = *f;
>>
>>        return 0;
>> +}
>>
>> -isc_try_fmt_err:
>> -     v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
>> -isc_try_fmt_subdev_err:
>> -     memset(&isc->try_config, 0, sizeof(isc->try_config));
>> +static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>> +{
>> +     isc_try_fmt(isc, f);
>>
>> -     return ret;
>> +     /* make the try configuration active */
>> +     isc->config = isc->try_config;
>> +     isc->fmt = isc->try_fmt;
>> +
>> +     v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n",
>> +              (char *)&f->fmt.pix.pixelformat,
>> +              f->fmt.pix.width, f->fmt.pix.height);
>> +
>> +     return 0;
>>   }
>>
>> -static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>> +static int isc_validate(struct isc_device *isc)
>>   {
>> +     int ret;
>> +     int i;
>> +     struct isc_format *sd_fmt = NULL;
>> +     struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
>>        struct v4l2_subdev_format format = {
>>                .which = V4L2_SUBDEV_FORMAT_ACTIVE,
>> +             .pad = isc->remote_pad,
>> +     };
>> +     struct v4l2_subdev_pad_config pad_cfg = {};
>> +     struct v4l2_subdev_state pad_state = {
>> +             .pads = &pad_cfg,
>>        };
>> -     u32 mbus_code = 0;
>> -     int ret;
>>
>> -     ret = isc_try_fmt(isc, f, &mbus_code);
>> +     /* Get current format from subdev */
>> +     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
>> +                            &format);
> 
> Ah! Haven't you just said we don't care anymore about the subdev
> format ? :)

We don't ! but we can't stream anything if the sensor streams a format 
that we don't understand do we ?

> 
> Kidding, I might got a bit lost in the logic, but if I look at your
> above isc_try_validate_formats() it seems like an ideal candidate for
> .link_validate() media_entity operation.
> 
> Just to make sure we're on the same page, here's how it should ideally
> look like:
> - set format does care about subdev format. It only checks that the
>    format required from the user is one of the ISC supported one. Ie.
>    no v4l2_subdev_call()
> 
> - as s_stream time your top driver calls media_pipeline_start()
> 
> - media_pipeline_start() walks all the entities in the pipeline and
>    validates the format of connected pads. To validate formats the
>    __media_pipeline_start() functions calls link_validate() on each
>    entity. You should in your driver set

Is this done automatically ? if this would be the case, where all links 
are correctly set, then, in theory, it would not be possible that some 
entities have a format set that is not supported by the other side

> 
>          static const struct media_entity_operations your_media_entity_ops = {
>                  .link_validate = v4l2_subdev_link_validate,
>          };
> 
>    if you want to use the default link validation procedure, or set the
>    callback to your custom validation function, which can behave more
>    or less like isc_try_validate_formats()

Does this mean that I can ask the subdev for the format ?
Or how can I obtain the format on the other side of the link ?
link validate can do this for me ?


Thanks for reviewing,
Eugen
> 
> Does it match your understanding too ?
> 
> Thanks
>     j
> 
> 
> 
>>        if (ret)
>>                return ret;
>>
>> -     v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
>> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
>> -                            set_fmt, NULL, &format);
>> -     if (ret < 0)
>> -             return ret;
>> +     /* Identify the subdev's format configuration */
>> +     for (i = 0; i < isc->num_user_formats; i++)
>> +             if (isc->user_formats[i]->mbus_code == format.format.code) {
>> +                     sd_fmt = isc->user_formats[i];
>> +                     break;
>> +             }
>> +
>> +     /* Check if the format is not supported */
>> +     if (!sd_fmt) {
>> +             v4l2_err(&isc->v4l2_dev,
>> +                      "Current subdevice is streaming a media bus code that is not supported 0x%x\n",
>> +                      format.format.code);
>> +             return -EPIPE;
>> +     }
>> +
>> +     /* At this moment we know which format the subdev will use */
>> +     isc->try_config.sd_format = sd_fmt;
>> +
>> +     /* If the sensor is not RAW, we can only do a direct dump */
>> +     if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
>> +             isc_try_configure_rlp_dma(isc, true);
>>
>>        /* Limit to Atmel ISC hardware capabilities */
>> -     if (f->fmt.pix.width > isc->max_width)
>> -             f->fmt.pix.width = isc->max_width;
>> -     if (f->fmt.pix.height > isc->max_height)
>> -             f->fmt.pix.height = isc->max_height;
>> +     v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
>> +                           &format.format.height, 16, isc->max_height, 0, 0);
>>
>> -     isc->fmt = *f;
>> +     /* Check if the frame size is the same. Otherwise we may overflow */
>> +     if (pixfmt->height != format.format.height ||
>> +         pixfmt->width != format.format.width) {
>> +             v4l2_err(&isc->v4l2_dev,
>> +                      "ISC not configured with the proper frame size: %dx%d\n",
>> +                      format.format.width, format.format.height);
>> +             return -EPIPE;
>> +     }
>>
>> +     v4l2_dbg(1, debug, &isc->v4l2_dev,
>> +              "Identified subdev using format %.4s with %dx%d %d bpp\n",
>> +              (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height,
>> +              isc->try_config.bpp);
>> +
>> +     /* Reset and restart AWB if the subdevice changed the format */
>>        if (isc->try_config.sd_format && isc->config.sd_format &&
>>            isc->try_config.sd_format != isc->config.sd_format) {
>>                isc->ctrls.hist_stat = HIST_INIT;
>>                isc_reset_awb_ctrls(isc);
>>                isc_update_v4l2_ctrls(isc);
>>        }
>> -     /* make the try configuration active */
>> +
>> +     /* Validate formats */
>> +     ret = isc_try_validate_formats(isc);
>> +     if (ret)
>> +             return ret;
>> +
>> +     /* Obtain frame sizes if possible to have crop requirements ready */
>> +     isc_try_fse(isc, &pad_state);
>> +
>> +     /* Configure ISC pipeline for the config */
>> +     ret = isc_try_configure_pipeline(isc);
>> +     if (ret)
>> +             return ret;
>> +
>>        isc->config = isc->try_config;
>>
>>        v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
>> @@ -1064,6 +1030,19 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>>        return 0;
>>   }
>>
>> +static int isc_streamon(struct file *file, void *priv, enum v4l2_buf_type bt)
>> +{
>> +     struct isc_device *isc = video_drvdata(file);
>> +     int ret;
>> +
>> +     ret = isc_validate(isc);
>> +
>> +     if (ret)
>> +             return ret;
>> +
>> +     return vb2_ioctl_streamon(file, priv, bt);
>> +}
>> +
>>   static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>>                              struct v4l2_format *f)
>>   {
>> @@ -1080,7 +1059,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
>>   {
>>        struct isc_device *isc = video_drvdata(file);
>>
>> -     return isc_try_fmt(isc, f, NULL);
>> +     return isc_try_fmt(isc, f);
>>   }
>>
>>   static int isc_enum_input(struct file *file, void *priv,
>> @@ -1176,7 +1155,7 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = {
>>        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
>>        .vidioc_create_bufs             = vb2_ioctl_create_bufs,
>>        .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
>> -     .vidioc_streamon                = vb2_ioctl_streamon,
>> +     .vidioc_streamon                = isc_streamon,
>>        .vidioc_streamoff               = vb2_ioctl_streamoff,
>>
>>        .vidioc_g_parm                  = isc_g_parm,
>> @@ -1879,7 +1858,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
>>        };
>>        int ret;
>>
>> -     ret = isc_try_fmt(isc, &f, NULL);
>> +     ret = isc_try_fmt(isc, &f);
>>        if (ret)
>>                return ret;
>>
>> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
>> index c2cb805faff3..7081698adddd 100644
>> --- a/drivers/media/platform/atmel/atmel-isc.h
>> +++ b/drivers/media/platform/atmel/atmel-isc.h
>> @@ -297,6 +297,7 @@ struct isc_device {
>>        struct completion       comp;
>>
>>        struct v4l2_format      fmt;
>> +     struct v4l2_format      try_fmt;
>>        struct isc_format       **user_formats;
>>        unsigned int            num_user_formats;
>>
>> --
>> 2.25.1
>>


From Eugen.Hristev at microchip.com  Thu Jan 20 00:48:19 2022
From: Eugen.Hristev at microchip.com (Eugen.Hristev at microchip.com)
Date: Thu, 20 Jan 2022 08:48:19 +0000
Subject: [PATCH v3 23/23] media: atmel: atmel-isc: change format
 propagation to subdev into only verification
In-Reply-To: <9470258e-544c-ae65-2222-7a28467c7c99@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-24-eugen.hristev@microchip.com>
 <20220112092137.rzgmo436hjl2bdfv@uno.localdomain>
 <9470258e-544c-ae65-2222-7a28467c7c99@microchip.com>
Message-ID: <d99b8670-a778-5618-dcad-1827d5b64d88@microchip.com>

On 1/20/22 10:43 AM, Eugen Hristev - M18282 wrote:
> On 1/12/22 11:21 AM, Jacopo Mondi wrote:
>> Hi Eugen
> 
> 
> Hi Jacopo,
> 
>>
>> On Mon, Dec 13, 2021 at 03:49:40PM +0200, Eugen Hristev wrote:
>>> As a top MC video driver, the atmel-isc should not propagate the format to the
>>> subdevice.
>>> It should rather check at streamon() time if the subdev is properly configured
>>> with a compatible format.
>>> Removed the whole format finding logic, and reworked the format verification
>>> at streamon time, such that the ISC will return an error if the subdevice
>>> is not properly configured.
>>> With this being done, the module parameter 'sensor_prefered' makes no sense
>>> anymore. The ISC should not decide which format the sensor is using. The
>>> ISC should only cope with the situation and inform userspace if the streaming
>>> is possible in the current configuration.
>>
>> Sounds great!
>>
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
>>> ---
>>> Changes in v3:
>>> - clamp to maximum resolution once the frame size from the subdev is found
>>>
>>>    drivers/media/platform/atmel/atmel-isc-base.c | 271 ++++++++----------
>>>    drivers/media/platform/atmel/atmel-isc.h      |   1 +
>>>    2 files changed, 126 insertions(+), 146 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
>>> index 31c8e3029eee..00c8c9588a78 100644
>>> --- a/drivers/media/platform/atmel/atmel-isc-base.c
>>> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
>>> @@ -36,11 +36,6 @@ static unsigned int debug;
>>>    module_param(debug, int, 0644);
>>>    MODULE_PARM_DESC(debug, "debug level (0-2)");
>>>
>>> -static unsigned int sensor_preferred = 1;
>>> -module_param(sensor_preferred, uint, 0644);
>>> -MODULE_PARM_DESC(sensor_preferred,
>>> -              "Sensor is preferred to output the specified format (1-on 0-off), default 1");
>>> -
>>>    #define ISC_IS_FORMAT_RAW(mbus_code) \
>>>         (((mbus_code) & 0xf000) == 0x3000)
>>>
>>> @@ -532,7 +527,7 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
>>>          * convert it to any of the formats that we usually can with a
>>>          * RAW sensor. Thus, do not advertise them.
>>>          */
>>> -     if (!isc->config.sd_format ||
>>> +     if (isc->config.sd_format &&
>>
>> Is this change intentional ?
>>
>>>             !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
>>>                 return -EINVAL;
>>>
>>> @@ -621,20 +616,30 @@ static int isc_try_validate_formats(struct isc_device *isc)
>>>                 break;
>>>         default:
>>>         /* any other different formats are not supported */
>>> +             v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n");
>>>                 ret = -EINVAL;
>>>         }
>>>         v4l2_dbg(1, debug, &isc->v4l2_dev,
>>>                  "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
>>>                  rgb, yuv, grey, bayer);
>>
>> Would it make sense to move this before the switch so that the
>> error messages, if any, appear later ?
> 
> Actually, no, because the variables rgb, yuv, grey, bayer, are set
> according to what happens in the switch
>>
>>>
>>> -     /* we cannot output RAW if we do not receive RAW */
>>> -     if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
>>> +     if ((bayer) &&
>>> +         !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
>>> +             v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n");
>>>                 return -EINVAL;
>>> +     }
>>>
>>> -     /* we cannot output GREY if we do not receive RAW/GREY */
>>>         if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
>>> -         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
>>> +         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
>>> +             v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
>>>                 return -EINVAL;
>>> +     }
>>> +
>>> +     if ((rgb || bayer || yuv) &&
>>> +         ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
>>> +             v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n");
>>> +             return -EINVAL;
>>> +     }
>>>
>>>         return ret;
>>>    }
>>> @@ -862,7 +867,7 @@ static void isc_try_fse(struct isc_device *isc,
>>>          * If we do not know yet which format the subdev is using, we cannot
>>>          * do anything.
>>>          */
>>> -     if (!isc->try_config.sd_format)
>>> +     if (!isc->config.sd_format)
>>>                 return;
>>>
>>>         fse.code = isc->try_config.sd_format->mbus_code;
>>> @@ -883,180 +888,141 @@ static void isc_try_fse(struct isc_device *isc,
>>>         }
>>>    }
>>>
>>> -static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
>>> -                     u32 *code)
>>> +static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
>>>    {
>>> -     int i;
>>> -     struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
>>>         struct v4l2_pix_format *pixfmt = &f->fmt.pix;
>>> -     struct v4l2_subdev_pad_config pad_cfg = {};
>>> -     struct v4l2_subdev_state pad_state = {
>>> -             .pads = &pad_cfg
>>> -             };
>>> -     struct v4l2_subdev_format format = {
>>> -             .which = V4L2_SUBDEV_FORMAT_TRY,
>>> -     };
>>> -     u32 mbus_code;
>>> -     int ret;
>>> -     bool rlp_dma_direct_dump = false;
>>> +     unsigned int i;
>>>
>>>         if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
>>>                 return -EINVAL;
>>>
>>> -     /* Step 1: find a RAW format that is supported */
>>> -     for (i = 0; i < isc->num_user_formats; i++) {
>>> -             if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
>>> -                     sd_fmt = isc->user_formats[i];
>>> +     isc->try_config.fourcc = isc->user_formats[0]->fourcc;
>>> +
>>> +     /* find if the format requested is supported */
>>> +     for (i = 0; i < isc->controller_formats_size; i++)
>>> +             if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
>>> +                     isc->try_config.fourcc = pixfmt->pixelformat;
>>>                         break;
>>>                 }
>>> -     }
>>> -     /* Step 2: We can continue with this RAW format, or we can look
>>> -      * for better: maybe sensor supports directly what we need.
>>> -      */
>>> -     direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
>>> -
>>> -     /* Step 3: We have both. We decide given the module parameter which
>>> -      * one to use.
>>> -      */
>>> -     if (direct_fmt && sd_fmt && sensor_preferred)
>>> -             sd_fmt = direct_fmt;
>>> -
>>> -     /* Step 4: we do not have RAW but we have a direct format. Use it. */
>>> -     if (direct_fmt && !sd_fmt)
>>> -             sd_fmt = direct_fmt;
>>> -
>>> -     /* Step 5: if we are using a direct format, we need to package
>>> -      * everything as 8 bit data and just dump it
>>> -      */
>>> -     if (sd_fmt == direct_fmt)
>>> -             rlp_dma_direct_dump = true;
>>> -
>>> -     /* Step 6: We have no format. This can happen if the userspace
>>> -      * requests some weird/invalid format.
>>> -      * In this case, default to whatever we have
>>> -      */
>>> -     if (!sd_fmt && !direct_fmt) {
>>> -             sd_fmt = isc->user_formats[isc->num_user_formats - 1];
>>> -             v4l2_dbg(1, debug, &isc->v4l2_dev,
>>> -                      "Sensor not supporting %.4s, using %.4s\n",
>>> -                      (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
>>> -     }
>>> -
>>> -     if (!sd_fmt) {
>>> -             ret = -EINVAL;
>>> -             goto isc_try_fmt_err;
>>> -     }
>>> -
>>> -     /* Step 7: Print out what we decided for debugging */
>>> -     v4l2_dbg(1, debug, &isc->v4l2_dev,
>>> -              "Preferring to have sensor using format %.4s\n",
>>> -              (char *)&sd_fmt->fourcc);
>>> -
>>> -     /* Step 8: at this moment we decided which format the subdev will use */
>>> -     isc->try_config.sd_format = sd_fmt;
>>> -
>>> -     /* Limit to Atmel ISC hardware capabilities */
>>> -     if (pixfmt->width > isc->max_width)
>>> -             pixfmt->width = isc->max_width;
>>> -     if (pixfmt->height > isc->max_height)
>>> -             pixfmt->height = isc->max_height;
>>> -
>>> -     /*
>>> -      * The mbus format is the one the subdev outputs.
>>> -      * The pixels will be transferred in this format Sensor -> ISC
>>> -      */
>>> -     mbus_code = sd_fmt->mbus_code;
>>> -
>>> -     /*
>>> -      * Validate formats. If the required format is not OK, default to raw.
>>> -      */
>>> -
>>> -     isc->try_config.fourcc = pixfmt->pixelformat;
>>> -
>>> -     if (isc_try_validate_formats(isc)) {
>>> -             pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
>>> -             /* Re-try to validate the new format */
>>> -             ret = isc_try_validate_formats(isc);
>>> -             if (ret)
>>> -                     goto isc_try_fmt_err;
>>> -     }
>>> -
>>> -     ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
>>> -     if (ret)
>>> -             goto isc_try_fmt_err;
>>> -
>>> -     ret = isc_try_configure_pipeline(isc);
>>> -     if (ret)
>>> -             goto isc_try_fmt_err;
>>>
>>> -     /* Obtain frame sizes if possible to have crop requirements ready */
>>> -     isc_try_fse(isc, &pad_state);
>>> -
>>> -     v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
>>> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
>>> -                            &pad_state, &format);
>>> -     if (ret < 0)
>>> -             goto isc_try_fmt_subdev_err;
>>> +     /* If we did not find the requested format, we will fallback here */
>>> +     pixfmt->pixelformat = isc->try_config.fourcc;
>>> +     pixfmt->colorspace = V4L2_COLORSPACE_SRGB;
>>> +     pixfmt->field = V4L2_FIELD_NONE;
>>>
>>> -     v4l2_fill_pix_format(pixfmt, &format.format);
>>> +     isc_try_configure_rlp_dma(isc, false);
>>>
>>>         /* Limit to Atmel ISC hardware capabilities */
>>> -     if (pixfmt->width > isc->max_width)
>>> -             pixfmt->width = isc->max_width;
>>> -     if (pixfmt->height > isc->max_height)
>>> -             pixfmt->height = isc->max_height;
>>> +     v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
>>> +                           &pixfmt->height, 16, isc->max_height, 0, 0);
>>>
>>>         pixfmt->field = V4L2_FIELD_NONE;
>>>         pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
>>>         pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
>>>                              pixfmt->height;
>>>
>>> -     if (code)
>>> -             *code = mbus_code;
>>> +     isc->try_fmt = *f;
>>>
>>>         return 0;
>>> +}
>>>
>>> -isc_try_fmt_err:
>>> -     v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
>>> -isc_try_fmt_subdev_err:
>>> -     memset(&isc->try_config, 0, sizeof(isc->try_config));
>>> +static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>>> +{
>>> +     isc_try_fmt(isc, f);
>>>
>>> -     return ret;
>>> +     /* make the try configuration active */
>>> +     isc->config = isc->try_config;
>>> +     isc->fmt = isc->try_fmt;
>>> +
>>> +     v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n",
>>> +              (char *)&f->fmt.pix.pixelformat,
>>> +              f->fmt.pix.width, f->fmt.pix.height);
>>> +
>>> +     return 0;
>>>    }
>>>
>>> -static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>>> +static int isc_validate(struct isc_device *isc)
>>>    {
>>> +     int ret;
>>> +     int i;
>>> +     struct isc_format *sd_fmt = NULL;
>>> +     struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
>>>         struct v4l2_subdev_format format = {
>>>                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
>>> +             .pad = isc->remote_pad,
>>> +     };
>>> +     struct v4l2_subdev_pad_config pad_cfg = {};
>>> +     struct v4l2_subdev_state pad_state = {
>>> +             .pads = &pad_cfg,
>>>         };
>>> -     u32 mbus_code = 0;
>>> -     int ret;
>>>
>>> -     ret = isc_try_fmt(isc, f, &mbus_code);
>>> +     /* Get current format from subdev */
>>> +     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
>>> +                            &format);
>>
>> Ah! Haven't you just said we don't care anymore about the subdev
>> format ? :)
> 
> We don't ! but we can't stream anything if the sensor streams a format
> that we don't understand do we ?

Actually, thinking about this, we really need to know what format is at 
the input for the ISC. According to this format, we need to understand 
how to process it, since the ISC could have at input either Raw bayer 
and we need to know the rotation, or directly a non-raw format like yuv422 .

Rather than asking the subdev for the streaming format, we could obtain 
this information from the pad link ?

> 
>>
>> Kidding, I might got a bit lost in the logic, but if I look at your
>> above isc_try_validate_formats() it seems like an ideal candidate for
>> .link_validate() media_entity operation.
>>
>> Just to make sure we're on the same page, here's how it should ideally
>> look like:
>> - set format does care about subdev format. It only checks that the
>>     format required from the user is one of the ISC supported one. Ie.
>>     no v4l2_subdev_call()
>>
>> - as s_stream time your top driver calls media_pipeline_start()
>>
>> - media_pipeline_start() walks all the entities in the pipeline and
>>     validates the format of connected pads. To validate formats the
>>     __media_pipeline_start() functions calls link_validate() on each
>>     entity. You should in your driver set
> 
> Is this done automatically ? if this would be the case, where all links
> are correctly set, then, in theory, it would not be possible that some
> entities have a format set that is not supported by the other side
> 
>>
>>           static const struct media_entity_operations your_media_entity_ops = {
>>                   .link_validate = v4l2_subdev_link_validate,
>>           };
>>
>>     if you want to use the default link validation procedure, or set the
>>     callback to your custom validation function, which can behave more
>>     or less like isc_try_validate_formats()
> 
> Does this mean that I can ask the subdev for the format ?
> Or how can I obtain the format on the other side of the link ?
> link validate can do this for me ?
> 
> 
> Thanks for reviewing,
> Eugen
>>
>> Does it match your understanding too ?
>>
>> Thanks
>>      j
>>
>>
>>
>>>         if (ret)
>>>                 return ret;
>>>
>>> -     v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
>>> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
>>> -                            set_fmt, NULL, &format);
>>> -     if (ret < 0)
>>> -             return ret;
>>> +     /* Identify the subdev's format configuration */
>>> +     for (i = 0; i < isc->num_user_formats; i++)
>>> +             if (isc->user_formats[i]->mbus_code == format.format.code) {
>>> +                     sd_fmt = isc->user_formats[i];
>>> +                     break;
>>> +             }
>>> +
>>> +     /* Check if the format is not supported */
>>> +     if (!sd_fmt) {
>>> +             v4l2_err(&isc->v4l2_dev,
>>> +                      "Current subdevice is streaming a media bus code that is not supported 0x%x\n",
>>> +                      format.format.code);
>>> +             return -EPIPE;
>>> +     }
>>> +
>>> +     /* At this moment we know which format the subdev will use */
>>> +     isc->try_config.sd_format = sd_fmt;
>>> +
>>> +     /* If the sensor is not RAW, we can only do a direct dump */
>>> +     if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
>>> +             isc_try_configure_rlp_dma(isc, true);
>>>
>>>         /* Limit to Atmel ISC hardware capabilities */
>>> -     if (f->fmt.pix.width > isc->max_width)
>>> -             f->fmt.pix.width = isc->max_width;
>>> -     if (f->fmt.pix.height > isc->max_height)
>>> -             f->fmt.pix.height = isc->max_height;
>>> +     v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
>>> +                           &format.format.height, 16, isc->max_height, 0, 0);
>>>
>>> -     isc->fmt = *f;
>>> +     /* Check if the frame size is the same. Otherwise we may overflow */
>>> +     if (pixfmt->height != format.format.height ||
>>> +         pixfmt->width != format.format.width) {
>>> +             v4l2_err(&isc->v4l2_dev,
>>> +                      "ISC not configured with the proper frame size: %dx%d\n",
>>> +                      format.format.width, format.format.height);
>>> +             return -EPIPE;
>>> +     }
>>>
>>> +     v4l2_dbg(1, debug, &isc->v4l2_dev,
>>> +              "Identified subdev using format %.4s with %dx%d %d bpp\n",
>>> +              (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height,
>>> +              isc->try_config.bpp);
>>> +
>>> +     /* Reset and restart AWB if the subdevice changed the format */
>>>         if (isc->try_config.sd_format && isc->config.sd_format &&
>>>             isc->try_config.sd_format != isc->config.sd_format) {
>>>                 isc->ctrls.hist_stat = HIST_INIT;
>>>                 isc_reset_awb_ctrls(isc);
>>>                 isc_update_v4l2_ctrls(isc);
>>>         }
>>> -     /* make the try configuration active */
>>> +
>>> +     /* Validate formats */
>>> +     ret = isc_try_validate_formats(isc);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     /* Obtain frame sizes if possible to have crop requirements ready */
>>> +     isc_try_fse(isc, &pad_state);
>>> +
>>> +     /* Configure ISC pipeline for the config */
>>> +     ret = isc_try_configure_pipeline(isc);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>>         isc->config = isc->try_config;
>>>
>>>         v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
>>> @@ -1064,6 +1030,19 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
>>>         return 0;
>>>    }
>>>
>>> +static int isc_streamon(struct file *file, void *priv, enum v4l2_buf_type bt)
>>> +{
>>> +     struct isc_device *isc = video_drvdata(file);
>>> +     int ret;
>>> +
>>> +     ret = isc_validate(isc);
>>> +
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     return vb2_ioctl_streamon(file, priv, bt);
>>> +}
>>> +
>>>    static int isc_s_fmt_vid_cap(struct file *file, void *priv,
>>>                               struct v4l2_format *f)
>>>    {
>>> @@ -1080,7 +1059,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
>>>    {
>>>         struct isc_device *isc = video_drvdata(file);
>>>
>>> -     return isc_try_fmt(isc, f, NULL);
>>> +     return isc_try_fmt(isc, f);
>>>    }
>>>
>>>    static int isc_enum_input(struct file *file, void *priv,
>>> @@ -1176,7 +1155,7 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = {
>>>         .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
>>>         .vidioc_create_bufs             = vb2_ioctl_create_bufs,
>>>         .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
>>> -     .vidioc_streamon                = vb2_ioctl_streamon,
>>> +     .vidioc_streamon                = isc_streamon,
>>>         .vidioc_streamoff               = vb2_ioctl_streamoff,
>>>
>>>         .vidioc_g_parm                  = isc_g_parm,
>>> @@ -1879,7 +1858,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
>>>         };
>>>         int ret;
>>>
>>> -     ret = isc_try_fmt(isc, &f, NULL);
>>> +     ret = isc_try_fmt(isc, &f);
>>>         if (ret)
>>>                 return ret;
>>>
>>> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
>>> index c2cb805faff3..7081698adddd 100644
>>> --- a/drivers/media/platform/atmel/atmel-isc.h
>>> +++ b/drivers/media/platform/atmel/atmel-isc.h
>>> @@ -297,6 +297,7 @@ struct isc_device {
>>>         struct completion       comp;
>>>
>>>         struct v4l2_format      fmt;
>>> +     struct v4l2_format      try_fmt;
>>>         struct isc_format       **user_formats;
>>>         unsigned int            num_user_formats;
>>>
>>> --
>>> 2.25.1
>>>
> 


From guangming.cao at mediatek.com  Thu Jan 20 00:52:59 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 20 Jan 2022 16:52:59 +0800
Subject: [PATCH v6] dma-buf: system_heap: Add a size check for allocation
In-Reply-To: <4f2631d3-0845-cae6-6fc0-9c00ce6301ce@amd.com>
References: <4f2631d3-0845-cae6-6fc0-9c00ce6301ce@amd.com>
Message-ID: <20220120085259.98147-1-guangming.cao@mediatek.com>

From: Guangming <Guangming.Cao at mediatek.com>

Add a size check for allocation since the allocation size should be
always less than the total DRAM size on system heap.
Adding this check can prevent comsuming too much time for invalid allocations.

Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
---
 drivers/dma-buf/heaps/system_heap.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..b65e597a742f 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -347,6 +347,14 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	struct page *page, *tmp_page;
 	int i, ret = -ENOMEM;
 
+	/*
+	 * Size check. The "len" should be less than totalram since system_heap
+	 * memory is comes from system. Adding check here can prevent comsuming
+	 * too much time for invalid allocations.
+	 */
+	if (PFN_DOWN(len) > totalram_pages())
+		return ERR_PTR(-EINVAL);
+
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 	if (!buffer)
 		return ERR_PTR(-ENOMEM);
-- 
2.17.1



From jacopo at jmondi.org  Thu Jan 20 00:58:46 2022
From: jacopo at jmondi.org (Jacopo Mondi)
Date: Thu, 20 Jan 2022 09:58:46 +0100
Subject: [PATCH v3 23/23] media: atmel: atmel-isc: change format
 propagation to subdev into only verification
In-Reply-To: <9470258e-544c-ae65-2222-7a28467c7c99@microchip.com>
References: <20211213134940.324266-1-eugen.hristev@microchip.com>
 <20211213134940.324266-24-eugen.hristev@microchip.com>
 <20220112092137.rzgmo436hjl2bdfv@uno.localdomain>
 <9470258e-544c-ae65-2222-7a28467c7c99@microchip.com>
Message-ID: <20220120085846.sa4prpvps5xmckil@uno.localdomain>

Hi Eugen

On Thu, Jan 20, 2022 at 08:43:33AM +0000, Eugen.Hristev at microchip.com wrote:
> On 1/12/22 11:21 AM, Jacopo Mondi wrote:
> > Hi Eugen
>
>
> Hi Jacopo,
>
> >
> > On Mon, Dec 13, 2021 at 03:49:40PM +0200, Eugen Hristev wrote:
> >> As a top MC video driver, the atmel-isc should not propagate the format to the
> >> subdevice.
> >> It should rather check at streamon() time if the subdev is properly configured
> >> with a compatible format.
> >> Removed the whole format finding logic, and reworked the format verification
> >> at streamon time, such that the ISC will return an error if the subdevice
> >> is not properly configured.
> >> With this being done, the module parameter 'sensor_prefered' makes no sense
> >> anymore. The ISC should not decide which format the sensor is using. The
> >> ISC should only cope with the situation and inform userspace if the streaming
> >> is possible in the current configuration.
> >
> > Sounds great!
> >
> >>
> >> Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
> >> ---
> >> Changes in v3:
> >> - clamp to maximum resolution once the frame size from the subdev is found
> >>
> >>   drivers/media/platform/atmel/atmel-isc-base.c | 271 ++++++++----------
> >>   drivers/media/platform/atmel/atmel-isc.h      |   1 +
> >>   2 files changed, 126 insertions(+), 146 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
> >> index 31c8e3029eee..00c8c9588a78 100644
> >> --- a/drivers/media/platform/atmel/atmel-isc-base.c
> >> +++ b/drivers/media/platform/atmel/atmel-isc-base.c
> >> @@ -36,11 +36,6 @@ static unsigned int debug;
> >>   module_param(debug, int, 0644);
> >>   MODULE_PARM_DESC(debug, "debug level (0-2)");
> >>
> >> -static unsigned int sensor_preferred = 1;
> >> -module_param(sensor_preferred, uint, 0644);
> >> -MODULE_PARM_DESC(sensor_preferred,
> >> -              "Sensor is preferred to output the specified format (1-on 0-off), default 1");
> >> -
> >>   #define ISC_IS_FORMAT_RAW(mbus_code) \
> >>        (((mbus_code) & 0xf000) == 0x3000)
> >>
> >> @@ -532,7 +527,7 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
> >>         * convert it to any of the formats that we usually can with a
> >>         * RAW sensor. Thus, do not advertise them.
> >>         */
> >> -     if (!isc->config.sd_format ||
> >> +     if (isc->config.sd_format &&
> >
> > Is this change intentional ?
> >
> >>            !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
> >>                return -EINVAL;
> >>
> >> @@ -621,20 +616,30 @@ static int isc_try_validate_formats(struct isc_device *isc)
> >>                break;
> >>        default:
> >>        /* any other different formats are not supported */
> >> +             v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n");
> >>                ret = -EINVAL;
> >>        }
> >>        v4l2_dbg(1, debug, &isc->v4l2_dev,
> >>                 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
> >>                 rgb, yuv, grey, bayer);
> >
> > Would it make sense to move this before the switch so that the
> > error messages, if any, appear later ?
>
> Actually, no, because the variables rgb, yuv, grey, bayer, are set
> according to what happens in the switch
> >
> >>
> >> -     /* we cannot output RAW if we do not receive RAW */
> >> -     if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
> >> +     if ((bayer) &&
> >> +         !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
> >> +             v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n");
> >>                return -EINVAL;
> >> +     }
> >>
> >> -     /* we cannot output GREY if we do not receive RAW/GREY */
> >>        if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
> >> -         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
> >> +         !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
> >> +             v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
> >>                return -EINVAL;
> >> +     }
> >> +
> >> +     if ((rgb || bayer || yuv) &&
> >> +         ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
> >> +             v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n");
> >> +             return -EINVAL;
> >> +     }
> >>
> >>        return ret;
> >>   }
> >> @@ -862,7 +867,7 @@ static void isc_try_fse(struct isc_device *isc,
> >>         * If we do not know yet which format the subdev is using, we cannot
> >>         * do anything.
> >>         */
> >> -     if (!isc->try_config.sd_format)
> >> +     if (!isc->config.sd_format)
> >>                return;
> >>
> >>        fse.code = isc->try_config.sd_format->mbus_code;
> >> @@ -883,180 +888,141 @@ static void isc_try_fse(struct isc_device *isc,
> >>        }
> >>   }
> >>
> >> -static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
> >> -                     u32 *code)
> >> +static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
> >>   {
> >> -     int i;
> >> -     struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
> >>        struct v4l2_pix_format *pixfmt = &f->fmt.pix;
> >> -     struct v4l2_subdev_pad_config pad_cfg = {};
> >> -     struct v4l2_subdev_state pad_state = {
> >> -             .pads = &pad_cfg
> >> -             };
> >> -     struct v4l2_subdev_format format = {
> >> -             .which = V4L2_SUBDEV_FORMAT_TRY,
> >> -     };
> >> -     u32 mbus_code;
> >> -     int ret;
> >> -     bool rlp_dma_direct_dump = false;
> >> +     unsigned int i;
> >>
> >>        if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
> >>                return -EINVAL;
> >>
> >> -     /* Step 1: find a RAW format that is supported */
> >> -     for (i = 0; i < isc->num_user_formats; i++) {
> >> -             if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
> >> -                     sd_fmt = isc->user_formats[i];
> >> +     isc->try_config.fourcc = isc->user_formats[0]->fourcc;
> >> +
> >> +     /* find if the format requested is supported */
> >> +     for (i = 0; i < isc->controller_formats_size; i++)
> >> +             if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
> >> +                     isc->try_config.fourcc = pixfmt->pixelformat;
> >>                        break;
> >>                }
> >> -     }
> >> -     /* Step 2: We can continue with this RAW format, or we can look
> >> -      * for better: maybe sensor supports directly what we need.
> >> -      */
> >> -     direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
> >> -
> >> -     /* Step 3: We have both. We decide given the module parameter which
> >> -      * one to use.
> >> -      */
> >> -     if (direct_fmt && sd_fmt && sensor_preferred)
> >> -             sd_fmt = direct_fmt;
> >> -
> >> -     /* Step 4: we do not have RAW but we have a direct format. Use it. */
> >> -     if (direct_fmt && !sd_fmt)
> >> -             sd_fmt = direct_fmt;
> >> -
> >> -     /* Step 5: if we are using a direct format, we need to package
> >> -      * everything as 8 bit data and just dump it
> >> -      */
> >> -     if (sd_fmt == direct_fmt)
> >> -             rlp_dma_direct_dump = true;
> >> -
> >> -     /* Step 6: We have no format. This can happen if the userspace
> >> -      * requests some weird/invalid format.
> >> -      * In this case, default to whatever we have
> >> -      */
> >> -     if (!sd_fmt && !direct_fmt) {
> >> -             sd_fmt = isc->user_formats[isc->num_user_formats - 1];
> >> -             v4l2_dbg(1, debug, &isc->v4l2_dev,
> >> -                      "Sensor not supporting %.4s, using %.4s\n",
> >> -                      (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
> >> -     }
> >> -
> >> -     if (!sd_fmt) {
> >> -             ret = -EINVAL;
> >> -             goto isc_try_fmt_err;
> >> -     }
> >> -
> >> -     /* Step 7: Print out what we decided for debugging */
> >> -     v4l2_dbg(1, debug, &isc->v4l2_dev,
> >> -              "Preferring to have sensor using format %.4s\n",
> >> -              (char *)&sd_fmt->fourcc);
> >> -
> >> -     /* Step 8: at this moment we decided which format the subdev will use */
> >> -     isc->try_config.sd_format = sd_fmt;
> >> -
> >> -     /* Limit to Atmel ISC hardware capabilities */
> >> -     if (pixfmt->width > isc->max_width)
> >> -             pixfmt->width = isc->max_width;
> >> -     if (pixfmt->height > isc->max_height)
> >> -             pixfmt->height = isc->max_height;
> >> -
> >> -     /*
> >> -      * The mbus format is the one the subdev outputs.
> >> -      * The pixels will be transferred in this format Sensor -> ISC
> >> -      */
> >> -     mbus_code = sd_fmt->mbus_code;
> >> -
> >> -     /*
> >> -      * Validate formats. If the required format is not OK, default to raw.
> >> -      */
> >> -
> >> -     isc->try_config.fourcc = pixfmt->pixelformat;
> >> -
> >> -     if (isc_try_validate_formats(isc)) {
> >> -             pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
> >> -             /* Re-try to validate the new format */
> >> -             ret = isc_try_validate_formats(isc);
> >> -             if (ret)
> >> -                     goto isc_try_fmt_err;
> >> -     }
> >> -
> >> -     ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
> >> -     if (ret)
> >> -             goto isc_try_fmt_err;
> >> -
> >> -     ret = isc_try_configure_pipeline(isc);
> >> -     if (ret)
> >> -             goto isc_try_fmt_err;
> >>
> >> -     /* Obtain frame sizes if possible to have crop requirements ready */
> >> -     isc_try_fse(isc, &pad_state);
> >> -
> >> -     v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
> >> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
> >> -                            &pad_state, &format);
> >> -     if (ret < 0)
> >> -             goto isc_try_fmt_subdev_err;
> >> +     /* If we did not find the requested format, we will fallback here */
> >> +     pixfmt->pixelformat = isc->try_config.fourcc;
> >> +     pixfmt->colorspace = V4L2_COLORSPACE_SRGB;
> >> +     pixfmt->field = V4L2_FIELD_NONE;
> >>
> >> -     v4l2_fill_pix_format(pixfmt, &format.format);
> >> +     isc_try_configure_rlp_dma(isc, false);
> >>
> >>        /* Limit to Atmel ISC hardware capabilities */
> >> -     if (pixfmt->width > isc->max_width)
> >> -             pixfmt->width = isc->max_width;
> >> -     if (pixfmt->height > isc->max_height)
> >> -             pixfmt->height = isc->max_height;
> >> +     v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
> >> +                           &pixfmt->height, 16, isc->max_height, 0, 0);
> >>
> >>        pixfmt->field = V4L2_FIELD_NONE;
> >>        pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
> >>        pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
> >>                             pixfmt->height;
> >>
> >> -     if (code)
> >> -             *code = mbus_code;
> >> +     isc->try_fmt = *f;
> >>
> >>        return 0;
> >> +}
> >>
> >> -isc_try_fmt_err:
> >> -     v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
> >> -isc_try_fmt_subdev_err:
> >> -     memset(&isc->try_config, 0, sizeof(isc->try_config));
> >> +static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
> >> +{
> >> +     isc_try_fmt(isc, f);
> >>
> >> -     return ret;
> >> +     /* make the try configuration active */
> >> +     isc->config = isc->try_config;
> >> +     isc->fmt = isc->try_fmt;
> >> +
> >> +     v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n",
> >> +              (char *)&f->fmt.pix.pixelformat,
> >> +              f->fmt.pix.width, f->fmt.pix.height);
> >> +
> >> +     return 0;
> >>   }
> >>
> >> -static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
> >> +static int isc_validate(struct isc_device *isc)
> >>   {
> >> +     int ret;
> >> +     int i;
> >> +     struct isc_format *sd_fmt = NULL;
> >> +     struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
> >>        struct v4l2_subdev_format format = {
> >>                .which = V4L2_SUBDEV_FORMAT_ACTIVE,
> >> +             .pad = isc->remote_pad,
> >> +     };
> >> +     struct v4l2_subdev_pad_config pad_cfg = {};
> >> +     struct v4l2_subdev_state pad_state = {
> >> +             .pads = &pad_cfg,
> >>        };
> >> -     u32 mbus_code = 0;
> >> -     int ret;
> >>
> >> -     ret = isc_try_fmt(isc, f, &mbus_code);
> >> +     /* Get current format from subdev */
> >> +     ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
> >> +                            &format);
> >
> > Ah! Haven't you just said we don't care anymore about the subdev
> > format ? :)
>
> We don't ! but we can't stream anything if the sensor streams a format
> that we don't understand do we ?
>
> >
> > Kidding, I might got a bit lost in the logic, but if I look at your
> > above isc_try_validate_formats() it seems like an ideal candidate for
> > .link_validate() media_entity operation.
> >
> > Just to make sure we're on the same page, here's how it should ideally
> > look like:
> > - set format does care about subdev format. It only checks that the
> >    format required from the user is one of the ISC supported one. Ie.
> >    no v4l2_subdev_call()
> >
> > - as s_stream time your top driver calls media_pipeline_start()
> >
> > - media_pipeline_start() walks all the entities in the pipeline and
> >    validates the format of connected pads. To validate formats the
> >    __media_pipeline_start() functions calls link_validate() on each
> >    entity. You should in your driver set
>
> Is this done automatically ? if this would be the case, where all links

Have a look at the media_pipeline_start() function in
drivers/media/mc/mc-entity.c

It walks the entities linked in the graph and calls .link_validate()
on each link it finds

> are correctly set, then, in theory, it would not be possible that some
> entities have a format set that is not supported by the other side
>

Not if validation is done correctly ;)

> >
> >          static const struct media_entity_operations your_media_entity_ops = {
> >                  .link_validate = v4l2_subdev_link_validate,
> >          };
> >
> >    if you want to use the default link validation procedure, or set the
> >    callback to your custom validation function, which can behave more
> >    or less like isc_try_validate_formats()
>
> Does this mean that I can ask the subdev for the format ?
> Or how can I obtain the format on the other side of the link ?
> link validate can do this for me ?

If you implement your own validation function then yes.
Have a look at v4l2_subdev_link_validate() in v4l2-subdev.c

It fetches formats from each side of the link and matches them.

As you have some more complex validations, you can define your own
validation function and compare the formats on each side of the link
with the same logic as implemented in isc_try_validate_formats() (if I
remember the function name right)

Thanks
   j

>
>
> Thanks for reviewing,
> Eugen
> >
> > Does it match your understanding too ?
> >
> > Thanks
> >     j
> >
> >
> >
> >>        if (ret)
> >>                return ret;
> >>
> >> -     v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
> >> -     ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
> >> -                            set_fmt, NULL, &format);
> >> -     if (ret < 0)
> >> -             return ret;
> >> +     /* Identify the subdev's format configuration */
> >> +     for (i = 0; i < isc->num_user_formats; i++)
> >> +             if (isc->user_formats[i]->mbus_code == format.format.code) {
> >> +                     sd_fmt = isc->user_formats[i];
> >> +                     break;
> >> +             }
> >> +
> >> +     /* Check if the format is not supported */
> >> +     if (!sd_fmt) {
> >> +             v4l2_err(&isc->v4l2_dev,
> >> +                      "Current subdevice is streaming a media bus code that is not supported 0x%x\n",
> >> +                      format.format.code);
> >> +             return -EPIPE;
> >> +     }
> >> +
> >> +     /* At this moment we know which format the subdev will use */
> >> +     isc->try_config.sd_format = sd_fmt;
> >> +
> >> +     /* If the sensor is not RAW, we can only do a direct dump */
> >> +     if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
> >> +             isc_try_configure_rlp_dma(isc, true);
> >>
> >>        /* Limit to Atmel ISC hardware capabilities */
> >> -     if (f->fmt.pix.width > isc->max_width)
> >> -             f->fmt.pix.width = isc->max_width;
> >> -     if (f->fmt.pix.height > isc->max_height)
> >> -             f->fmt.pix.height = isc->max_height;
> >> +     v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
> >> +                           &format.format.height, 16, isc->max_height, 0, 0);
> >>
> >> -     isc->fmt = *f;
> >> +     /* Check if the frame size is the same. Otherwise we may overflow */
> >> +     if (pixfmt->height != format.format.height ||
> >> +         pixfmt->width != format.format.width) {
> >> +             v4l2_err(&isc->v4l2_dev,
> >> +                      "ISC not configured with the proper frame size: %dx%d\n",
> >> +                      format.format.width, format.format.height);
> >> +             return -EPIPE;
> >> +     }
> >>
> >> +     v4l2_dbg(1, debug, &isc->v4l2_dev,
> >> +              "Identified subdev using format %.4s with %dx%d %d bpp\n",
> >> +              (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height,
> >> +              isc->try_config.bpp);
> >> +
> >> +     /* Reset and restart AWB if the subdevice changed the format */
> >>        if (isc->try_config.sd_format && isc->config.sd_format &&
> >>            isc->try_config.sd_format != isc->config.sd_format) {
> >>                isc->ctrls.hist_stat = HIST_INIT;
> >>                isc_reset_awb_ctrls(isc);
> >>                isc_update_v4l2_ctrls(isc);
> >>        }
> >> -     /* make the try configuration active */
> >> +
> >> +     /* Validate formats */
> >> +     ret = isc_try_validate_formats(isc);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     /* Obtain frame sizes if possible to have crop requirements ready */
> >> +     isc_try_fse(isc, &pad_state);
> >> +
> >> +     /* Configure ISC pipeline for the config */
> >> +     ret = isc_try_configure_pipeline(isc);
> >> +     if (ret)
> >> +             return ret;
> >> +
> >>        isc->config = isc->try_config;
> >>
> >>        v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
> >> @@ -1064,6 +1030,19 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
> >>        return 0;
> >>   }
> >>
> >> +static int isc_streamon(struct file *file, void *priv, enum v4l2_buf_type bt)
> >> +{
> >> +     struct isc_device *isc = video_drvdata(file);
> >> +     int ret;
> >> +
> >> +     ret = isc_validate(isc);
> >> +
> >> +     if (ret)
> >> +             return ret;
> >> +
> >> +     return vb2_ioctl_streamon(file, priv, bt);
> >> +}
> >> +
> >>   static int isc_s_fmt_vid_cap(struct file *file, void *priv,
> >>                              struct v4l2_format *f)
> >>   {
> >> @@ -1080,7 +1059,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
> >>   {
> >>        struct isc_device *isc = video_drvdata(file);
> >>
> >> -     return isc_try_fmt(isc, f, NULL);
> >> +     return isc_try_fmt(isc, f);
> >>   }
> >>
> >>   static int isc_enum_input(struct file *file, void *priv,
> >> @@ -1176,7 +1155,7 @@ static const struct v4l2_ioctl_ops isc_ioctl_ops = {
> >>        .vidioc_dqbuf                   = vb2_ioctl_dqbuf,
> >>        .vidioc_create_bufs             = vb2_ioctl_create_bufs,
> >>        .vidioc_prepare_buf             = vb2_ioctl_prepare_buf,
> >> -     .vidioc_streamon                = vb2_ioctl_streamon,
> >> +     .vidioc_streamon                = isc_streamon,
> >>        .vidioc_streamoff               = vb2_ioctl_streamoff,
> >>
> >>        .vidioc_g_parm                  = isc_g_parm,
> >> @@ -1879,7 +1858,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
> >>        };
> >>        int ret;
> >>
> >> -     ret = isc_try_fmt(isc, &f, NULL);
> >> +     ret = isc_try_fmt(isc, &f);
> >>        if (ret)
> >>                return ret;
> >>
> >> diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
> >> index c2cb805faff3..7081698adddd 100644
> >> --- a/drivers/media/platform/atmel/atmel-isc.h
> >> +++ b/drivers/media/platform/atmel/atmel-isc.h
> >> @@ -297,6 +297,7 @@ struct isc_device {
> >>        struct completion       comp;
> >>
> >>        struct v4l2_format      fmt;
> >> +     struct v4l2_format      try_fmt;
> >>        struct isc_format       **user_formats;
> >>        unsigned int            num_user_formats;
> >>
> >> --
> >> 2.25.1
> >>
>


From narmstrong at baylibre.com  Thu Jan 20 00:59:03 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 09:59:03 +0100
Subject: [PATCH V2 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <2022011810264745683311@amlogic.com>
References: <20211230094434.3053195-1-shunzhou.jiang@amlogic.com>
 <20211230094434.3053195-3-shunzhou.jiang@amlogic.com>
 <CAFBinCALAOJz16=u7r8tLM6ditriq=-NOACS2HRLrWs5B_FkVA@mail.gmail.com>
 <b2a9b8f0-2b12-c49f-9609-21999b1fffc8@baylibre.com>
 <2022011810264745683311@amlogic.com>
Message-ID: <b846de5f-cf30-c000-ea37-61d79bcd4e7e@baylibre.com>

Hi Shunzhou,

On 18/01/2022 03:26, shunzhou.jiang at amlogic.com wrote:
> Dears Neil & Martin:
> Sorry for my late reply
> S4_VPU_HDMI:? for vpu domain,? this domain provide power to many moudles(osd,?vpp,?hdr,?dv,?di), if close, will cause system crash
> S4_USB_COMB?domain: for usb, if not always on,? all usb status will clear to 0, that's not right status for usb
> S4_ETH: for ethernet online wakeup, and if power down, status also not right
>>> +?????? SEC_PD(S4_VPU_HDMI,???? GENPD_FLAG_ALWAYS_ON),
>>> +?????? SEC_PD(S4_USB_COMB,???? GENPD_FLAG_ALWAYS_ON),
>>> +?????? SEC_PD(S4_GE2D,???????? 0),
>>> +?????? SEC_PD(S4_ETH,????????? GENPD_FLAG_ALWAYS_ON),

Thanks for clarifications, can you resend the patchset with those infos in comments like it was done for A1 ?

Thanks,
Neil

> 
>  
> Shunzhou Jiang
> SW Department
> 
>     ?
>     *From:*?Neil Armstrong <mailto:narmstrong at baylibre.com>
>     *Date:*?2022-01-12?16:36
>     *To:*?Martin Blumenstingl <mailto:martin.blumenstingl at googlemail.com>; Shunzhou.Jiang <mailto:shunzhou.jiang at amlogic.com>
>     *CC:*?devicetree <mailto:devicetree at vger.kernel.org>; linux-arm-kernel <mailto:linux-arm-kernel at lists.infradead.org>; linux-amlogic <mailto:linux-amlogic at lists.infradead.org>; linux-kernel <mailto:linux-kernel at vger.kernel.org>; khilman <mailto:khilman at baylibre.com>; jbrunet <mailto:jbrunet at baylibre.com>
>     *Subject:*?Re: [PATCH V2 2/2] soc: s4: Add support for power domains controller
>     [ EXTERNAL EMAIL ]
>     ?
>     Hi Shunzhou,
>     ?
>     On 30/12/2021 23:15, Martin Blumenstingl wrote:
>     > On Thu, Dec 30, 2021 at 10:44 AM Shunzhou.Jiang
>     > <shunzhou.jiang at amlogic.com> wrote:
>     >>
>     >> From: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>     >>
>     >> Add support s4 Power controller. In s4, power control
>     >> registers are in secure domain, and should be accessed by smc.
>     >>
>     >> Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
>     > Also here I don't have any datasheet to compare this with, so this gets my:
>     > Acked-by: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
>     >
>     > [...]
>     >> +?????? SEC_PD(S4_VPU_HDMI,???? GENPD_FLAG_ALWAYS_ON),
>     >> +?????? SEC_PD(S4_USB_COMB,???? GENPD_FLAG_ALWAYS_ON),
>     >> +?????? SEC_PD(S4_GE2D,???????? 0),
>     >> +?????? SEC_PD(S4_ETH,????????? GENPD_FLAG_ALWAYS_ON),
>     > For the A1 SoC's UART entry we have the following comment which
>     > explains why we want to to be "always on":
>     >?? UART should keep working in ATF after suspend and before resume
>     >
>     > If for some reason you need to re-send this series then it would be
>     > great if you could add a comment above each entry with
>     > GENPD_FLAG_ALWAYS_ON.
>     > It will help others (like me) understand these SoCs better.
>     ?
>     Can you resend with those comments added so I can apply the patches ?
>     ?
>     Thanks,
>     Neil
>     ?
>     >
>     >
>     > Best regards,
>     > Martin
>     >
>     ?
> 


From benjamin.gaignard at collabora.com  Thu Jan 20 00:59:09 2022
From: benjamin.gaignard at collabora.com (Benjamin Gaignard)
Date: Thu, 20 Jan 2022 09:59:09 +0100
Subject: [PATCH v2] media: platform: mtk-vcodec: Do not force /dev/videoX node
 number
Message-ID: <20220120085909.103886-1-benjamin.gaignard@collabora.com>

Let's v4l2 framework use a free /dev/videoX node for decode and encoder.
For the decoder call video_register_device() before register the media
controller device so the mapping between ins correctly done.
Since the registering sequence has changed rework exiting errors case too.

Fixes: 590577a4e525 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Decoder Driver")
Fixes: 4e855a6efa54 ("[media] vcodec: mediatek: Add Mediatek V4L2 Video Encoder Driver")

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
version 2:
 - add Fixes and Reviewed-by tags as suggested by Angelo
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  | 27 +++++++++----------
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  2 +-
 2 files changed, 13 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 86b639d82be8..a4a3f9631d04 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -374,7 +374,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (IS_ERR((__force void *)dev->m2m_dev_dec)) {
 		mtk_v4l2_err("Failed to init mem2mem dec device");
 		ret = PTR_ERR((__force void *)dev->m2m_dev_dec);
-		goto err_dec_mem_init;
+		goto err_dec_alloc;
 	}
 
 	dev->decode_workqueue =
@@ -391,10 +391,16 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 					   &pdev->dev);
 		if (ret) {
 			mtk_v4l2_err("Main device of_platform_populate failed.");
-			goto err_event_workq;
+			goto err_reg_cont;
 		}
 	}
 
+	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		mtk_v4l2_err("Failed to register video device");
+		goto err_reg_cont;
+	}
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
@@ -408,7 +414,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 							 MEDIA_ENT_F_PROC_VIDEO_DECODER);
 		if (ret) {
 			mtk_v4l2_err("Failed to register media controller");
-			goto err_reg_cont;
+			goto err_dec_mem_init;
 		}
 
 		ret = media_device_register(&dev->mdev_dec);
@@ -419,30 +425,21 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 
 		mtk_v4l2_debug(0, "media registered as /dev/media%d", vfd_dec->minor);
 	}
-	ret = video_register_device(vfd_dec, VFL_TYPE_VIDEO, 0);
-	if (ret) {
-		mtk_v4l2_err("Failed to register video device");
-		goto err_dec_reg;
-	}
 
 	mtk_v4l2_debug(0, "decoder registered as /dev/video%d", vfd_dec->minor);
 
 	return 0;
 
-err_dec_reg:
-	if (dev->vdec_pdata->uses_stateless_api)
-		media_device_unregister(&dev->mdev_dec);
 err_media_reg:
-	if (dev->vdec_pdata->uses_stateless_api)
-		v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+	v4l2_m2m_unregister_media_controller(dev->m2m_dev_dec);
+err_dec_mem_init:
+	video_unregister_device(vfd_dec);
 err_reg_cont:
 	if (dev->vdec_pdata->uses_stateless_api)
 		media_device_cleanup(&dev->mdev_dec);
 	destroy_workqueue(dev->decode_workqueue);
 err_event_workq:
 	v4l2_m2m_release(dev->m2m_dev_dec);
-err_dec_mem_init:
-	video_unregister_device(vfd_dec);
 err_dec_alloc:
 	v4l2_device_unregister(&dev->v4l2_dev);
 err_core_workq:
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..3975613b75b3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -350,7 +350,7 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 	if (of_get_property(pdev->dev.of_node, "dma-ranges", NULL))
 		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(34));
 
-	ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, 1);
+	ret = video_register_device(vfd_enc, VFL_TYPE_VIDEO, -1);
 	if (ret) {
 		mtk_v4l2_err("Failed to register video device");
 		goto err_enc_reg;
-- 
2.30.2



From p.yadav at ti.com  Thu Jan 20 01:00:02 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Thu, 20 Jan 2022 14:30:02 +0530
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <0c0a22ed-2c4b-374c-4f4c-06afd4e8681d@canonical.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
 <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
 <20220120070620.wyeosdstbfcsaplt@ti.com>
 <0c0a22ed-2c4b-374c-4f4c-06afd4e8681d@canonical.com>
Message-ID: <20220120090002.hg4jmb7q2s25k64y@ti.com>

On 20/01/22 08:36AM, Krzysztof Kozlowski wrote:
> On 20/01/2022 08:06, Pratyush Yadav wrote:
> > On 19/01/22 08:49PM, Krzysztof Kozlowski wrote:
> >> On 19/01/2022 20:31, Pratyush Yadav wrote:
> >>> On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
> >>>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> >>>> controller bindings to DT schema format
> >>>>
> >>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> >>>> ---
> >>>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
> >>>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
> >>>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
> >>>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
> >>>>  MAINTAINERS                                   |   2 +-
> >>>>  5 files changed, 224 insertions(+), 123 deletions(-)
> >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
> >>>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >>>> new file mode 100644
> >>>> index 000000000000..aa5a1f48494b
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> >>>> @@ -0,0 +1,35 @@
> >>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> >>>> +%YAML 1.2
> >>>> +---
> >>>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> >>>> +
> >>>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> >>>> +
> >>>> +maintainers:
> >>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> >>>> +
> >>>> +description:
> >>>> +  See spi-peripheral-props.yaml for more info.
> >>>> +
> >>>> +properties:
> >>>> +  controller-data:
> >>>> +    type: object
> >>>> +    additionalProperties: false
> >>>> +
> >>>> +    properties:
> >>>> +      samsung,spi-feedback-delay:
> >>>> +        description: |
> >>>> +          The sampling phase shift to be applied on the miso line (to account
> >>>> +          for any lag in the miso line). Valid values:
> >>>> +           - 0: No phase shift.
> >>>> +           - 1: 90 degree phase shift sampling.
> >>>> +           - 2: 180 degree phase shift sampling.
> >>>> +           - 3: 270 degree phase shift sampling.
> >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> >>>> +        enum: [0, 1, 2, 3]
> >>>> +
> >>>> +    required:
> >>>> +      - samsung,spi-feedback-delay
> >>>
> >>> I am not quite sure if this required would work here. Let's say another 
> >>> controller also uses a controller-data node, but it contains a different 
> >>> set of properties. Won't this cause an error to be raised for that 
> >>> controller since this property is not there?
> >>
> >> The controller-data is Samsung SPI specific (does not exist in any other
> >> binding), so why would controller-data get added to a different controller?
> > 
> > It does not as of now, but the name is fairly generic and some 
> > controller in the future might use it. I do not think it is a good idea 
> > to list required properties in X-peripheral-props.yaml in general since 
> > all those will be collected by spi-peripheral-props.yaml and so will 
> > apply to _all_ controllers that reference it.
> 
> Right, but have in mind this is merely a bindings conversion. These were
> made like this long time ago.

Yes, but the bindings infrastructure is not capable of handling these 
required properties as of now. So even if your next patch was _not_ 
making it optional, I would still say you should drop the "required:". 
Even though the property is actually a required one, we currently do not 
have the means to express that.

> 
> I think we can drop the "required:" entirely with the commit 3/4 which
> makes it optional.

I would prefer you never add it in the first place.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From pali at kernel.org  Thu Jan 20 01:01:18 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 10:01:18 +0100
Subject: [PATCH v2 00/11] PCI: Small improvements for pci-bridge-emul and
 mvebu
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <20220120090118.3f3ioi7wqvrl5usu@pali>

Hello Lorenzo, could you please review these patches? There are here
without any new comments for month.

On Tuesday 04 January 2022 16:35:18 Pali Roh?r wrote:
> This patch series contains small improvements for pci-bridge-emul and
> mvebu drivers. This patch series is based on top of the patches:
> https://lore.kernel.org/linux-pci/20211125124605.25915-1-pali at kernel.org/
> (which are now in pci/mvebu branch)
> 
> In V2 was added comment into code explaining PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
> and PCI_BRIDGE_EMUL_NO_IO_FORWARD flags.
> 
> Pali Roh?r (11):
>   MAINTAINERS: Add Pali Roh?r as pci-mvebu.c maintainer
>   PCI: pci-bridge-emul: Make struct pci_bridge_emul_ops as const
>   PCI: pci-bridge-emul: Rename PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR to
>     PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
>   PCI: pci-bridge-emul: Add support for new flag
>     PCI_BRIDGE_EMUL_NO_IO_FORWARD
>   PCI: mvebu: Add help string for CONFIG_PCI_MVEBU option
>   PCI: mvebu: Remove duplicate nports assignment
>   PCI: mvebu: Set PCI_BRIDGE_EMUL_NO_IO_FORWARD when IO is unsupported
>   PCI: mvebu: Properly initialize vendor, device and revision of
>     emulated bridge
>   PCI: mvebu: Update comment for PCI_EXP_LNKCAP register on emulated
>     bridge
>   PCI: mvebu: Update comment for PCI_EXP_LNKCTL register on emulated
>     bridge
>   PCI: mvebu: Fix reporting Data Link Layer Link Active on emulated
>     bridge
> 
>  MAINTAINERS                           |  1 +
>  drivers/pci/controller/Kconfig        |  4 ++
>  drivers/pci/controller/pci-aardvark.c |  2 +-
>  drivers/pci/controller/pci-mvebu.c    | 64 ++++++++++++---------------
>  drivers/pci/pci-bridge-emul.c         | 11 ++++-
>  drivers/pci/pci-bridge-emul.h         | 14 +++++-
>  6 files changed, 57 insertions(+), 39 deletions(-)
> 
> -- 
> 2.20.1
> 


From michal.simek at xilinx.com  Thu Jan 20 01:17:59 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Thu, 20 Jan 2022 10:17:59 +0100
Subject: [PATCH v2] clk: zynqmp: replace warn_once with pr_debug for
 failed clock ops
In-Reply-To: <20220119115434.2042017-1-m.tretter@pengutronix.de>
References: <20220119115434.2042017-1-m.tretter@pengutronix.de>
Message-ID: <c496ed85-d64a-4961-3577-a917fecfc51e@xilinx.com>



On 1/19/22 12:54, Michael Tretter wrote:
> The warning that a clock operation failed is only printed once. However,
> the function is called for various different clocks. The limit hides the
> warnings if different clocks are affected by the failures.
> 
> The clock ops might fail if the firmware that handles the clocks is
> misconfigured. Therefore, replace the pr_warn_once with pr_debug to
> allow the user to see all errors if necessary. By default, hide the
> error messages and let drivers handle the errors.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---
> This is v2 of the patch to improve the error messages of the ZynqMP
> clock driver [0].
> 
> [0] https://lore.kernel.org/all/20220112141229.700708-1-m.tretter at pengutronix.de/
> 
> Changelog:
> 
> v2:
> 
> - Update commit message
> - Use pr_debug instead of pr_warn
> ---
>   drivers/clk/zynqmp/clk-gate-zynqmp.c | 12 +++++------
>   drivers/clk/zynqmp/clk-mux-zynqmp.c  |  8 +++----
>   drivers/clk/zynqmp/divider.c         | 12 +++++------
>   drivers/clk/zynqmp/pll.c             | 32 ++++++++++++++--------------
>   4 files changed, 32 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> index 565ed67a0430..b89e55737198 100644
> --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c
> +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c
> @@ -41,8 +41,8 @@ static int zynqmp_clk_gate_enable(struct clk_hw *hw)
>   	ret = zynqmp_pm_clock_enable(clk_id);
>   
>   	if (ret)
> -		pr_warn_once("%s() clock enabled failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock enable failed for %s (id %d), ret = %d\n",
> +			 __func__, clk_name, clk_id, ret);
>   
>   	return ret;
>   }
> @@ -61,8 +61,8 @@ static void zynqmp_clk_gate_disable(struct clk_hw *hw)
>   	ret = zynqmp_pm_clock_disable(clk_id);
>   
>   	if (ret)
> -		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock disable failed for %s (id %d), ret = %d\n",
> +			 __func__, clk_name, clk_id, ret);
>   }
>   
>   /**
> @@ -80,8 +80,8 @@ static int zynqmp_clk_gate_is_enabled(struct clk_hw *hw)
>   
>   	ret = zynqmp_pm_clock_getstate(clk_id, &state);
>   	if (ret) {
> -		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock get state failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   		return -EIO;
>   	}
>   
> diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c
> index 17afce594f28..60359333f26d 100644
> --- a/drivers/clk/zynqmp/clk-mux-zynqmp.c
> +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c
> @@ -51,8 +51,8 @@ static u8 zynqmp_clk_mux_get_parent(struct clk_hw *hw)
>   	ret = zynqmp_pm_clock_getparent(clk_id, &val);
>   
>   	if (ret) {
> -		pr_warn_once("%s() getparent failed for clock: %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() getparent failed for clock: %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   		/*
>   		 * clk_core_get_parent_by_index() takes num_parents as incorrect
>   		 * index which is exactly what I want to return here
> @@ -80,8 +80,8 @@ static int zynqmp_clk_mux_set_parent(struct clk_hw *hw, u8 index)
>   	ret = zynqmp_pm_clock_setparent(clk_id, index);
>   
>   	if (ret)
> -		pr_warn_once("%s() set parent failed for clock: %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() set parent failed for clock: %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   
>   	return ret;
>   }
> diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c
> index cb49281f9cf9..422ea79907dd 100644
> --- a/drivers/clk/zynqmp/divider.c
> +++ b/drivers/clk/zynqmp/divider.c
> @@ -89,8 +89,8 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
>   	ret = zynqmp_pm_clock_getdivider(clk_id, &div);
>   
>   	if (ret)
> -		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() get divider failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   
>   	if (div_type == TYPE_DIV1)
>   		value = div & 0xFFFF;
> @@ -177,8 +177,8 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
>   		ret = zynqmp_pm_clock_getdivider(clk_id, &bestdiv);
>   
>   		if (ret)
> -			pr_warn_once("%s() get divider failed for %s, ret = %d\n",
> -				     __func__, clk_name, ret);
> +			pr_debug("%s() get divider failed for %s, ret = %d\n",
> +				 __func__, clk_name, ret);
>   		if (div_type == TYPE_DIV1)
>   			bestdiv = bestdiv & 0xFFFF;
>   		else
> @@ -244,8 +244,8 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
>   	ret = zynqmp_pm_clock_setdivider(clk_id, div);
>   
>   	if (ret)
> -		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() set divider failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   
>   	return ret;
>   }
> diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c
> index 036e4ff64a2f..91a6b4cc910e 100644
> --- a/drivers/clk/zynqmp/pll.c
> +++ b/drivers/clk/zynqmp/pll.c
> @@ -56,8 +56,8 @@ static inline enum pll_mode zynqmp_pll_get_mode(struct clk_hw *hw)
>   
>   	ret = zynqmp_pm_get_pll_frac_mode(clk_id, ret_payload);
>   	if (ret) {
> -		pr_warn_once("%s() PLL get frac mode failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() PLL get frac mode failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   		return PLL_MODE_ERROR;
>   	}
>   
> @@ -84,8 +84,8 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on)
>   
>   	ret = zynqmp_pm_set_pll_frac_mode(clk_id, mode);
>   	if (ret)
> -		pr_warn_once("%s() PLL set frac mode failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() PLL set frac mode failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   	else
>   		clk->set_pll_mode = true;
>   }
> @@ -145,8 +145,8 @@ static unsigned long zynqmp_pll_recalc_rate(struct clk_hw *hw,
>   
>   	ret = zynqmp_pm_clock_getdivider(clk_id, &fbdiv);
>   	if (ret) {
> -		pr_warn_once("%s() get divider failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() get divider failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   		return 0ul;
>   	}
>   
> @@ -200,8 +200,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
>   			WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
>   			     clk_name);
>   		else if (ret)
> -			pr_warn_once("%s() set divider failed for %s, ret = %d\n",
> -				     __func__, clk_name, ret);
> +			pr_debug("%s() set divider failed for %s, ret = %d\n",
> +				 __func__, clk_name, ret);
>   		zynqmp_pm_set_pll_frac_data(clk_id, f);
>   
>   		return rate + frac;
> @@ -211,8 +211,8 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
>   	fbdiv = clamp_t(u32, fbdiv, PLL_FBDIV_MIN, PLL_FBDIV_MAX);
>   	ret = zynqmp_pm_clock_setdivider(clk_id, fbdiv);
>   	if (ret)
> -		pr_warn_once("%s() set divider failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() set divider failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   
>   	return parent_rate * fbdiv;
>   }
> @@ -233,8 +233,8 @@ static int zynqmp_pll_is_enabled(struct clk_hw *hw)
>   
>   	ret = zynqmp_pm_clock_getstate(clk_id, &state);
>   	if (ret) {
> -		pr_warn_once("%s() clock get state failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock get state failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   		return -EIO;
>   	}
>   
> @@ -265,8 +265,8 @@ static int zynqmp_pll_enable(struct clk_hw *hw)
>   
>   	ret = zynqmp_pm_clock_enable(clk_id);
>   	if (ret)
> -		pr_warn_once("%s() clock enable failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock enable failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   
>   	return ret;
>   }
> @@ -287,8 +287,8 @@ static void zynqmp_pll_disable(struct clk_hw *hw)
>   
>   	ret = zynqmp_pm_clock_disable(clk_id);
>   	if (ret)
> -		pr_warn_once("%s() clock disable failed for %s, ret = %d\n",
> -			     __func__, clk_name, ret);
> +		pr_debug("%s() clock disable failed for %s, ret = %d\n",
> +			 __func__, clk_name, ret);
>   }
>   
>   static const struct clk_ops zynqmp_pll_ops = {


Acked-by: Michal Simek <michal.simek at xilinx.com>

Thanks,
Michal


From krzysztof.kozlowski at canonical.com  Thu Jan 20 01:24:59 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 10:24:59 +0100
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220120090002.hg4jmb7q2s25k64y@ti.com>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
 <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
 <20220120070620.wyeosdstbfcsaplt@ti.com>
 <0c0a22ed-2c4b-374c-4f4c-06afd4e8681d@canonical.com>
 <20220120090002.hg4jmb7q2s25k64y@ti.com>
Message-ID: <20220120092459.gbaoief77p2tynaf@krzk-bin>

On Thu, Jan 20, 2022 at 02:30:02PM +0530, Pratyush Yadav wrote:
> On 20/01/22 08:36AM, Krzysztof Kozlowski wrote:
> > On 20/01/2022 08:06, Pratyush Yadav wrote:
> > > On 19/01/22 08:49PM, Krzysztof Kozlowski wrote:
> > >> On 19/01/2022 20:31, Pratyush Yadav wrote:
> > >>> On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
> > >>>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> > >>>> controller bindings to DT schema format
> > >>>>
> > >>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > >>>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> > >>>> ---
> > >>>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
> > >>>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
> > >>>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
> > >>>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
> > >>>>  MAINTAINERS                                   |   2 +-
> > >>>>  5 files changed, 224 insertions(+), 123 deletions(-)
> > >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
> > >>>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> > >>>>
> > >>>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > >>>> new file mode 100644
> > >>>> index 000000000000..aa5a1f48494b
> > >>>> --- /dev/null
> > >>>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > >>>> @@ -0,0 +1,35 @@
> > >>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > >>>> +%YAML 1.2
> > >>>> +---
> > >>>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> > >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > >>>> +
> > >>>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> > >>>> +
> > >>>> +maintainers:
> > >>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > >>>> +
> > >>>> +description:
> > >>>> +  See spi-peripheral-props.yaml for more info.
> > >>>> +
> > >>>> +properties:
> > >>>> +  controller-data:
> > >>>> +    type: object
> > >>>> +    additionalProperties: false
> > >>>> +
> > >>>> +    properties:
> > >>>> +      samsung,spi-feedback-delay:
> > >>>> +        description: |
> > >>>> +          The sampling phase shift to be applied on the miso line (to account
> > >>>> +          for any lag in the miso line). Valid values:
> > >>>> +           - 0: No phase shift.
> > >>>> +           - 1: 90 degree phase shift sampling.
> > >>>> +           - 2: 180 degree phase shift sampling.
> > >>>> +           - 3: 270 degree phase shift sampling.
> > >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> > >>>> +        enum: [0, 1, 2, 3]
> > >>>> +
> > >>>> +    required:
> > >>>> +      - samsung,spi-feedback-delay
> > >>>
> > >>> I am not quite sure if this required would work here. Let's say another 
> > >>> controller also uses a controller-data node, but it contains a different 
> > >>> set of properties. Won't this cause an error to be raised for that 
> > >>> controller since this property is not there?
> > >>
> > >> The controller-data is Samsung SPI specific (does not exist in any other
> > >> binding), so why would controller-data get added to a different controller?
> > > 
> > > It does not as of now, but the name is fairly generic and some 
> > > controller in the future might use it. I do not think it is a good idea 
> > > to list required properties in X-peripheral-props.yaml in general since 
> > > all those will be collected by spi-peripheral-props.yaml and so will 
> > > apply to _all_ controllers that reference it.
> > 
> > Right, but have in mind this is merely a bindings conversion. These were
> > made like this long time ago.
> 
> Yes, but the bindings infrastructure is not capable of handling these 
> required properties as of now. So even if your next patch was _not_ 
> making it optional, I would still say you should drop the "required:". 
> Even though the property is actually a required one, we currently do not 
> have the means to express that.
> 
> > 
> > I think we can drop the "required:" entirely with the commit 3/4 which
> > makes it optional.
> 
> I would prefer you never add it in the first place.

If I understand correctly, you propose to squash next patch making it
optional to this conversion? I believe there is a value in splitting
conversion of existing bindings from making changes to the bindings, but
I don't mind squashing them if that is desired.

Best regards,
Krzysztof



From arnd at arndb.de  Thu Jan 20 01:26:18 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:26:18 +0100
Subject: [PATCH V3 04/17] syscalls: compat: Fix the missing part for
 __SYSCALL_COMPAT
In-Reply-To: <20220120073911.99857-5-guoren@kernel.org>
References: <20220120073911.99857-5-guoren@kernel.org>
Message-ID: <CAK8P3a3ixShQBKmdXWxf8QdB_aLeWr7TQB+7MqQBSgh0-shSSQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:38 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Make "uapi asm unistd.h" could be used for architectures' COMPAT
> mode. The __SYSCALL_COMPAT is first used in riscv.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From pali at kernel.org  Thu Jan 20 01:26:41 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 10:26:41 +0100
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell,armada-3700-uart-clock
In-Reply-To: <20220120060149.0FF24C340E0@smtp.kernel.org>
References: <20211015093701.pfvkighxsndj4ujg@pali>
 <163433494758.1688384.5994009027317282677@swboyd.mtv.corp.google.com>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali>
 <20220115130509.4a240730@thinkpad>
 <20220115122618.plhiqnjh2755bv5h@pali>
 <20220119231655.EFFF3C004E1@smtp.kernel.org>
 <20220120000651.in7s6nazif5qjkme@pali>
 <20220120060149.0FF24C340E0@smtp.kernel.org>
Message-ID: <20220120092641.o4ffzeyakhuuf3c7@pali>

On Wednesday 19 January 2022 22:01:47 Stephen Boyd wrote:
> Quoting Pali Roh?r (2022-01-19 16:06:51)
> > On Wednesday 19 January 2022 15:16:54 Stephen Boyd wrote:
> > > Quoting Pali Roh?r (2022-01-15 04:26:18)
> > > > On Saturday 15 January 2022 13:05:09 Marek Beh?n wrote:
> > > > > On Sat, 15 Jan 2022 12:50:18 +0100
> > > > > Pali Roh?r <pali at kernel.org> wrote:
> > > > > 
> > > > > > On Saturday 15 January 2022 00:02:11 Stephen Boyd wrote:
> > > > > > > Quoting Pali Roh?r (2021-10-15 23:42:10)  
> > > > > > > > 
> > > > > > > > If I was designing this driver and DTS bindings I would have choose
> > > > > > > > something like this:
> > > > > > > > 
> > > > > > > > uart at 0x12000 {  
> > > > > > > 
> > > > > > > Drop the 0x
> > > > > > >   
> > > > > > > >     reg = <0x12000 0x18>, <0x12200 0x30>;
> > > > > > > >     clock-controller {
> > > > > > > >         ...
> > > > > > > >     };  
> > > > > > > 
> > > > > > > Drop this node and put whatever properties are inside into the parent
> > > > > > > node.
> > > > > > >   
> > > > > > > >     serial1 {
> > > > > > > >         ...
> > > > > > > >         status = "disabled";
> > > > > > > >     };
> > > > > > > >     serial2 {
> > > > > > > >         ...
> > > > > > > >         status = "disabled";
> > > > > > > >     };
> > > > > > > > };
> > > > > > > > 
> > > > > > > > Meaning that 0x12000 node would be 3 subnodes and all registers would be
> > > > > > > > defined in top level nodes and would be handled by one driver.
> > > > > > > > 
> > > > > > > > This is really how hardware block looks like. But it is not backward
> > > > > > > > compatible...  
> > > > > > > 
> > > > > > > Sounds good to me. I presume we need the serial child nodes so we can
> > > > > > > reference them from the stdout-path?  
> > > > > > 
> > > > > > Yes, exactly, separate nodes for serial1 and serial2 are still required.
> > > > > > 
> > > > > > But dropping clock controller is not possible as for higher baudrates we
> > > > > > need to use and configure uart clock controller. Without it we just get
> > > > > > comparable feature support which is already present in driver.
> > > > > 
> > > > > What Stephen means is making clock controller out of the uart node
> > > > > directly. No need to add separate subnode just for clock controller.
> > > > 
> > > > This is already implemented in v7 patch series. Clock controller is
> > > > already outside of uart nodes.
> > > 
> > > I mean to combine the uart node and the clock-controller node together
> > > 
> > >       uart-wrapper {
> > >               reg = <0x12000 0x18>, <0x12200 0x30>;
> > >               #clock-cells ...
> > > 
> > >               serial1 {
> > >                       ...
> > >               };
> > > 
> > >               serial2 {
> > >                       ...
> > >               };
> > >       };
> > 
> > Ok, now I see what you mean.
> > 
> > But problem is that this is not backward compatible change. And would
> > not work per existing DT bindings definitions, which defines how
> > bootloader should set configured clocks.
> > 
> > As I wrote in emails 3 months ago, this new "proposed" DTS definition is
> > something which I would have chosen if I had designed this driver and
> > bindings in past. But that did not happen and different approach is
> > already widely in used.
> > 
> > To support existing DTS definitions and bootloaders, it is really
> > required to have current structure backward compatible like it is
> > defined in current DT bindings document. And my changes in this patch
> > series are backward compatible.
> 
> I'm lost. Is the bootloader the one that's expecting some particular
> serial node format and updating something? What is the bootloader doing?

If bootloader uses or configures UART to different clock it needs to
update "clocks" property in DT. Otherwise UART would be unusable and
there would be no dmesg output.

A3720 heavily depends that bootloader patches at boot time DTB file to
the layout of the current hardware.

> > 
> > To change DTS structure, it would be needed to provide uart nodes in DTS
> > files two times: once in old style (the current one) and second time in
> > this new style.
> 
> That's not a good idea. Why do we need to support both at the same time?

Because old bootloaders do not and will never support this new style. It
is not only linux kernel project who provides DTB files. Also bootloader
itself has own DTB files and use it for booting (e.g kernel). For some
boards is in-kernel-tree DTS file only as a reference. So it is
important that kernel can use and support DTS files from old version and
also from the new patched version. Gregory (A3720 DTS files maintainer)
always ask me what happens if I try to boot new patched kernel drivers
with old unmodified DTS files and wants to know if nothing is broken by
introduced changed.

> > 
> > But such thing would even more complicate updating driver and it needs
> > to be implemented.
> > 
> > Plus this would open a question how to define default stdout-path if
> > there would be 4 serial nodes, where one pair would describe old style
> > and second pair new style; meaning that 2 cross nodes would describe
> > same define.
> 
> Huh? We shouldn't have both bindings present in the DTB.

Ideally yes, I would like to see to prevent it. But for backward
compatibility we really need old bindings still present (as explained
above).

So really I see two options here: Make changes in patches backward
compatible (old nodes stay in DT and also kernel would be able to use
old DT). Or let old bindings untouched in DT and new backward
incompatible definitions would have to be in separate nodes.

> > 
> > For me this looks like a more complications and I do not see any benefit
> > from it.
> > 
> > It is really important to break backward compatibility, just to try
> > having new cleaner API at the cost of having more complications and
> > requirement for more development and also important maintenance?
> 
> It's important to not make DT nodes have reg properties that overlap.
> Maybe this is a DT purist viewpoint and I'm totally off base! I think
> Rob did ack this binding already so I must be coming from the wrong
> angle.

I know this. In case it happens that driver for "one DT node" needs to
access regs of "another DT node" then regmap interface is used and
driver access regs of "another DT node" via regmap. No overlapping is in
DT. But here it is not possible to use regmap as "another DT node" is in
"disabled" state on some boards. And so regmap driver is not bound to
it.

In beginning there was not overlapping in DT because people have not
looked properly that some registers of uart2 are in uart1 space and did
not exported them to driver (bootloader initialized them to some sane
values and nobody noticed that they are required).

This overlapping starting to be required after I properly looked how
driver is working, how it maps to HW and how to implement choosing
clocks and allowing to change baudrate to higher values.

> Nothing prevents register overlap from happening in practice, but it's
> good to avoid such a situation as it clearly divides the I/O space by
> assigning an address range to a particular device. In this case, we see
> the two uarts are really one device, but we need two nodes in DT for
> stdout-path, so we make some child nodes and have the driver figure out
> which serial port to use for the console.
> 
> We shouldn't be adding more nodes to DT to get drivers to probe for
> device I/O spaces that have already been described in DT. When this
> happens, we learn that some I/O range is actually a combination of
> functions, like uart and clks, and thus we should be able to add any
> required properties to the existing DT node to support that new feature
> that wasn't described before in the binding.


From arnd at arndb.de  Thu Jan 20 01:29:33 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:29:33 +0100
Subject: [PATCH V3 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <20220120073911.99857-7-guoren@kernel.org>
References: <20220120073911.99857-7-guoren@kernel.org>
Message-ID: <CAK8P3a00uYPBBphpipBoqCnGFwr_C9vDzS1p1iLN==YTVOARug@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:38 AM <guoren at kernel.org> wrote:

> @@ -0,0 +1,136 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __ASM_COMPAT_H
> +#define __ASM_COMPAT_H
> +
> +#define compat_mode_t  compat_mode_t
> +typedef u16            compat_mode_t;

I think this one is wrong, as rv32 should get the native definition from

include/uapi/asm-generic/posix_types.h:typedef unsigned int     __kernel_mode_t;

I think it works if you just remove those two lines. The rest looks good to me.

       Arnd


From Jason at zx2c4.com  Thu Jan 20 01:44:02 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Thu, 20 Jan 2022 10:44:02 +0100
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <YeiPn8Mo1AM7X9Ud@archlinux-ax161>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com> <YeiPn8Mo1AM7X9Ud@archlinux-ax161>
Message-ID: <CAHmME9rPy=T=0Ddbw+01bFycXNPfuxgMm+U80DzDSLy0Cdh_Gg@mail.gmail.com>

On 1/19/22, Nathan Chancellor <nathan at kernel.org> wrote:
> On Wed, Jan 19, 2022 at 02:54:50PM +0100, Jason A. Donenfeld wrote:
>> blake2s_compress_generic is weakly aliased to blake2s_generic. The
>
> Isn't it the other way around?

Thanks. Changed that 'to' to a 'by'.

Jason


From bhe at redhat.com  Thu Jan 20 01:45:39 2022
From: bhe at redhat.com (Baoquan He)
Date: Thu, 20 Jan 2022 17:45:39 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <Yef5oz/XiZT/Pxfy@xhacker>
References: <20211206160514.2000-1-jszhang@kernel.org>
 <20220116133847.GE2388@MiWiFi-R3L-srv> <YebK70Sx4w8zLfj/@xhacker>
 <20220119080859.GB4977@MiWiFi-R3L-srv>
 <CA+zEjCvqYAWaWW9hVbHqYm_GbV-BaiOM4c77WHnxDNh+SRDUuw@mail.gmail.com>
 <20220119093322.GC4977@MiWiFi-R3L-srv> <Yef5oz/XiZT/Pxfy@xhacker>
Message-ID: <20220120094539.GC18398@MiWiFi-R3L-srv>

On 01/19/22 at 07:44pm, Jisheng Zhang wrote:
> On Wed, Jan 19, 2022 at 05:33:22PM +0800, Baoquan He wrote:
> > On 01/19/22 at 09:52am, Alexandre Ghiti wrote:
> > > Hi Baoquan,
> > > 
> > > On Wed, Jan 19, 2022 at 9:11 AM Baoquan He <bhe at redhat.com> wrote:
> > > >
> > > > On 01/18/22 at 10:13pm, Jisheng Zhang wrote:
> > > > > On Sun, Jan 16, 2022 at 09:38:47PM +0800, Baoquan He wrote:
> > > > > > Hi Jisheng,
> > > > >
> > > > > Hi Baoquan,
> > > > >
> > > > > >
> > > > > > On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> > > > > > > Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> > > > > > > by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> > > > > > > and increase compile coverage.
> > > > > >
> > > > > > I go through this patchset, You mention the benefits it brings are
> > > > > > 1) simplity the code;
> > > > > > 2) increase compile coverage;
> > > > > >
> > > > > > For benefit 1), it mainly removes the dummy function in x86, arm and
> > > > > > arm64, right?
> > > > >
> > > > > Another benefit: remove those #ifdef #else #endif usage. Recently, I
> > > > > fixed a bug due to lots of "#ifdefs":
> > > > > http://lists.infradead.org/pipermail/linux-riscv/2021-December/010607.html
> > > >
> > > > Glad to know the fix. While, sometime the ifdeffery is necessary. I am
> > > > sorry about the one in riscv and you have fixed, it's truly a bug . But,
> > > > the increasing compile coverage at below you tried to make, it may cause
> > > > issue. Please see below my comment.
> > > >
> > > > >
> > > > > >
> > > > > > For benefit 2), increasing compile coverage, could you tell more how it
> > > > > > achieves and why it matters? What if people disables CONFIG_KEXEC_CORE in
> > > > > > purpose? Please forgive my poor compiling knowledge.
> > > > >
> > > > > Just my humble opinion, let's compare the code::
> > > > >
> > > > > #ifdef CONFIG_KEXEC_CORE
> > > > >
> > > > > code block A;
> > > > >
> > > > > #endif
> > > > >
> > > > > If KEXEC_CORE is disabled, code block A won't be compiled at all, the
> > > > > preprocessor will remove code block A;
> > > > >
> > > > > If we convert the code to:
> > > > >
> > > > > if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
> > > > >       code block A;
> > > > > }
> > > > >
> > > > > Even if KEXEC_CORE is disabled, code block A is still compiled.
> > > >
> > > > This is what I am worried about. Before, if CONFIG_KEXEC_CORE is
> > > > unset, those relevant codes are not compiled in. I can't see what
> > > > benefit is brought in if compiled in the unneeded code block. Do I miss
> > > > anything?
> > > >
> > > 
> > > This is explained in Documentation/process/coding-style.rst "21)
> > > Conditional Compilation".
> > 
> > Thanks for the pointer, Alex.
> > 
> > I read that part, while my confusion isn't gone. With the current code,
> > CONFIG_KEXEC_CORE is set,
> >   - reserve_crashkernel_low() and reserve_crashkernel() compiled in.
> 
> Although the code block will be compiled, but the code block will be
> optimized out.
> 
> > CONFIG_KEXEC_CORE is unset,
> >   - reserve_crashkernel_low() and reserve_crashkernel() compiled out. 
> > 
> > After this patch applied, does it have the same effect as the old code?
> 
> I compared the .o, and can confirm they acchieve the same effect.

Checked the .o, it's truly as you said. I didn't know this before,
thank you and Alex, learned this now.

Seems only static function has this effect. I tested your x86 patch,
those two functions are all optimized out. If I remove the static,
the entire reserve_crashkernel_low() exists, while reserve_crashkernel()
will be optimized as a empty function. 



From bhe at redhat.com  Thu Jan 20 01:50:19 2022
From: bhe at redhat.com (Baoquan He)
Date: Thu, 20 Jan 2022 17:50:19 +0800
Subject: [PATCH v2 0/5] kexec: use IS_ENABLED(CONFIG_KEXEC_CORE) instead
 of #ifdef
In-Reply-To: <20211206160514.2000-1-jszhang@kernel.org>
References: <20211206160514.2000-1-jszhang@kernel.org>
Message-ID: <20220120095019.GA4579@MiWiFi-R3L-srv>

On 12/07/21 at 12:05am, Jisheng Zhang wrote:
> Replace the conditional compilation using "#ifdef CONFIG_KEXEC_CORE"
> by a check for "IS_ENABLED(CONFIG_KEXEC_CORE)", to simplify the code
> and increase compile coverage.

Only checked the x86 patch, but the whole patchset looks good to me,
thanks, Jisheng.

Acked-by: Baoquan He <bhe at redhat.com>

Maybe Andrew can help pick this whole series lest each patch need be taken
care of by its own ARCH maintainer.

> 
> I only modify x86, arm, arm64 and riscv, other architectures such as
> sh, powerpc and s390 are better to be kept kexec code as-is so they
> are not touched.
> 
> Since v1:
>  - collect Reviewed-by tag
>  - fix misleading commit msg.
> 
> Jisheng Zhang (5):
>   kexec: make crashk_res, crashk_low_res and crash_notes symbols always
>     visible
>   riscv: mm: init: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
>   x86/setup: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
>   arm64: mm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
>   arm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef
> 
>  arch/arm/kernel/setup.c |  7 +++----
>  arch/arm64/mm/init.c    |  9 +++------
>  arch/riscv/mm/init.c    |  6 ++----
>  arch/x86/kernel/setup.c | 10 +++-------
>  include/linux/kexec.h   | 12 ++++++------
>  5 files changed, 17 insertions(+), 27 deletions(-)
> 
> -- 
> 2.34.1
> 



From p.yadav at ti.com  Thu Jan 20 02:08:09 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Thu, 20 Jan 2022 15:38:09 +0530
Subject: [PATCH v3 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220120092459.gbaoief77p2tynaf@krzk-bin>
References: <20220112100046.68068-1-krzysztof.kozlowski@canonical.com>
 <20220112100046.68068-3-krzysztof.kozlowski@canonical.com>
 <20220119192758.z3lvlkaeyeiqi73a@ti.com>
 <5f912896-0635-fbe7-4fda-f4cb569190d9@canonical.com>
 <20220120070620.wyeosdstbfcsaplt@ti.com>
 <0c0a22ed-2c4b-374c-4f4c-06afd4e8681d@canonical.com>
 <20220120090002.hg4jmb7q2s25k64y@ti.com>
 <20220120092459.gbaoief77p2tynaf@krzk-bin>
Message-ID: <20220120100809.mfe2eqkgpjjfpt3c@ti.com>

On 20/01/22 10:24AM, Krzysztof Kozlowski wrote:
> On Thu, Jan 20, 2022 at 02:30:02PM +0530, Pratyush Yadav wrote:
> > On 20/01/22 08:36AM, Krzysztof Kozlowski wrote:
> > > On 20/01/2022 08:06, Pratyush Yadav wrote:
> > > > On 19/01/22 08:49PM, Krzysztof Kozlowski wrote:
> > > >> On 19/01/2022 20:31, Pratyush Yadav wrote:
> > > >>> On 12/01/22 11:00AM, Krzysztof Kozlowski wrote:
> > > >>>> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> > > >>>> controller bindings to DT schema format
> > > >>>>
> > > >>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > > >>>> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
> > > >>>> ---
> > > >>>>  .../spi/samsung,spi-peripheral-props.yaml     |  35 ++++
> > > >>>>  .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
> > > >>>>  .../bindings/spi/spi-peripheral-props.yaml    |   1 +
> > > >>>>  .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
> > > >>>>  MAINTAINERS                                   |   2 +-
> > > >>>>  5 files changed, 224 insertions(+), 123 deletions(-)
> > > >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > > >>>>  create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
> > > >>>>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt
> > > >>>>
> > > >>>> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > > >>>> new file mode 100644
> > > >>>> index 000000000000..aa5a1f48494b
> > > >>>> --- /dev/null
> > > >>>> +++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
> > > >>>> @@ -0,0 +1,35 @@
> > > >>>> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > > >>>> +%YAML 1.2
> > > >>>> +---
> > > >>>> +$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
> > > >>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > >>>> +
> > > >>>> +title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
> > > >>>> +
> > > >>>> +maintainers:
> > > >>>> +  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > > >>>> +
> > > >>>> +description:
> > > >>>> +  See spi-peripheral-props.yaml for more info.
> > > >>>> +
> > > >>>> +properties:
> > > >>>> +  controller-data:
> > > >>>> +    type: object
> > > >>>> +    additionalProperties: false
> > > >>>> +
> > > >>>> +    properties:
> > > >>>> +      samsung,spi-feedback-delay:
> > > >>>> +        description: |
> > > >>>> +          The sampling phase shift to be applied on the miso line (to account
> > > >>>> +          for any lag in the miso line). Valid values:
> > > >>>> +           - 0: No phase shift.
> > > >>>> +           - 1: 90 degree phase shift sampling.
> > > >>>> +           - 2: 180 degree phase shift sampling.
> > > >>>> +           - 3: 270 degree phase shift sampling.
> > > >>>> +        $ref: /schemas/types.yaml#/definitions/uint32
> > > >>>> +        enum: [0, 1, 2, 3]
> > > >>>> +
> > > >>>> +    required:
> > > >>>> +      - samsung,spi-feedback-delay
> > > >>>
> > > >>> I am not quite sure if this required would work here. Let's say another 
> > > >>> controller also uses a controller-data node, but it contains a different 
> > > >>> set of properties. Won't this cause an error to be raised for that 
> > > >>> controller since this property is not there?
> > > >>
> > > >> The controller-data is Samsung SPI specific (does not exist in any other
> > > >> binding), so why would controller-data get added to a different controller?
> > > > 
> > > > It does not as of now, but the name is fairly generic and some 
> > > > controller in the future might use it. I do not think it is a good idea 
> > > > to list required properties in X-peripheral-props.yaml in general since 
> > > > all those will be collected by spi-peripheral-props.yaml and so will 
> > > > apply to _all_ controllers that reference it.
> > > 
> > > Right, but have in mind this is merely a bindings conversion. These were
> > > made like this long time ago.
> > 
> > Yes, but the bindings infrastructure is not capable of handling these 
> > required properties as of now. So even if your next patch was _not_ 
> > making it optional, I would still say you should drop the "required:". 
> > Even though the property is actually a required one, we currently do not 
> > have the means to express that.
> > 
> > > 
> > > I think we can drop the "required:" entirely with the commit 3/4 which
> > > makes it optional.
> > 
> > I would prefer you never add it in the first place.
> 
> If I understand correctly, you propose to squash next patch making it
> optional to this conversion? I believe there is a value in splitting
> conversion of existing bindings from making changes to the bindings, but
> I don't mind squashing them if that is desired.

No, I don't want you to squash the next patch. I want you to just drop 
the "required:" property and call it a lossy conversion since there is 
no way as of now to express that. In the ideal world you would have kept 
it, and removed it in the next patch.

> 
> Best regards,
> Krzysztof
> 

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From pavel at denx.de  Thu Jan 20 02:08:49 2022
From: pavel at denx.de (Pavel Machek)
Date: Thu, 20 Jan 2022 11:08:49 +0100
Subject: [PATCH AUTOSEL 4.4 06/29] ARM: imx: rename
 DEBUG_IMX21_IMX27_UART to DEBUG_IMX27_UART
In-Reply-To: <20220118030822.1955469-6-sashal@kernel.org>
References: <20220118030822.1955469-1-sashal@kernel.org>
 <20220118030822.1955469-6-sashal@kernel.org>
Message-ID: <20220120100849.GA14998@amd>

Hi!

> From: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> 
> [ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]
> 
> Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
> DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.

This is unsuitable for 4.4 as imx21 is still supported there.

Best regards,
                                                                Pavel
-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220120/f379b0da/attachment.sig>

From guangming.cao at mediatek.com  Thu Jan 20 02:00:36 2022
From: guangming.cao at mediatek.com (guangming.cao at mediatek.com)
Date: Thu, 20 Jan 2022 18:00:36 +0800
Subject: [PATCH v6 RESEND] dma-buf: system_heap: Add a size check for
 allocation
In-Reply-To: <20220120085259.98147-1-guangming.cao@mediatek.com>
References: <20220120085259.98147-1-guangming.cao@mediatek.com>
Message-ID: <20220120100036.99867-1-guangming.cao@mediatek.com>

From: Guangming <Guangming.Cao at mediatek.com>

Add a size check for allocation since the allocation size should be
always less than the total DRAM size on system heap.
Adding this check can prevent comsuming too much time for invalid allocations.

Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
Acked-by: John Stultz <john.stultz at linaro.org>
---
 drivers/dma-buf/heaps/system_heap.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index 23a7e74ef966..b65e597a742f 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -347,6 +347,14 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	struct page *page, *tmp_page;
 	int i, ret = -ENOMEM;
 
+	/*
+	 * Size check. The "len" should be less than totalram since system_heap
+	 * memory is comes from system. Adding check here can prevent comsuming
+	 * too much time for invalid allocations.
+	 */
+	if (PFN_DOWN(len) > totalram_pages())
+		return ERR_PTR(-EINVAL);
+
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 	if (!buffer)
 		return ERR_PTR(-ENOMEM);
-- 
2.17.1



From christian.koenig at amd.com  Thu Jan 20 02:22:10 2022
From: christian.koenig at amd.com (=?UTF-8?Q?Christian_K=c3=b6nig?=)
Date: Thu, 20 Jan 2022 11:22:10 +0100
Subject: [PATCH v6 RESEND] dma-buf: system_heap: Add a size check for
 allocation
In-Reply-To: <20220120100036.99867-1-guangming.cao@mediatek.com>
References: <20220120085259.98147-1-guangming.cao@mediatek.com>
 <20220120100036.99867-1-guangming.cao@mediatek.com>
Message-ID: <90bf495d-dbf6-cb0d-f54f-e0080b810f8d@amd.com>

Am 20.01.22 um 11:00 schrieb guangming.cao at mediatek.com:
> From: Guangming <Guangming.Cao at mediatek.com>
>
> Add a size check for allocation since the allocation size should be
> always less than the total DRAM size on system heap.
> Adding this check can prevent comsuming too much time for invalid allocations.
>
> Signed-off-by: Guangming <Guangming.Cao at mediatek.com>
> Acked-by: John Stultz <john.stultz at linaro.org>

Acked-by: Christian K?nig <christian.koenig at amd.com>

> ---
>   drivers/dma-buf/heaps/system_heap.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
>
> diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
> index 23a7e74ef966..b65e597a742f 100644
> --- a/drivers/dma-buf/heaps/system_heap.c
> +++ b/drivers/dma-buf/heaps/system_heap.c
> @@ -347,6 +347,14 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
>   	struct page *page, *tmp_page;
>   	int i, ret = -ENOMEM;
>   
> +	/*
> +	 * Size check. The "len" should be less than totalram since system_heap
> +	 * memory is comes from system. Adding check here can prevent comsuming
> +	 * too much time for invalid allocations.
> +	 */
> +	if (PFN_DOWN(len) > totalram_pages())
> +		return ERR_PTR(-EINVAL);
> +
>   	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
>   	if (!buffer)
>   		return ERR_PTR(-ENOMEM);



From arnd at arndb.de  Thu Jan 20 01:37:43 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:37:43 +0100
Subject: [PATCH V3 13/17] riscv: compat: signal: Add rt_frame
 implementation
In-Reply-To: <20220120073911.99857-14-guoren@kernel.org>
References: <20220120073911.99857-14-guoren@kernel.org>
Message-ID: <CAK8P3a03-3QTC-vxmnbouK7wBd8iunPGZpX0-Jf6ntS1DY0E=w@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Implement compat_setup_rt_frame for sigcontext save & restore. The
> main process is the same with signal, but the rv32 pt_regs' size
> is different from rv64's, so we needs convert them.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

I hope someone else can properly review this part, it's not my area
but it looks complex enough that it could bring subtle bugs.

       Arnd


From arnd at arndb.de  Thu Jan 20 01:31:09 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:31:09 +0100
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <20220120073911.99857-8-guoren@kernel.org>
References: <20220120073911.99857-8-guoren@kernel.org>
Message-ID: <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Make TASK_SIZE from const to dynamic detect TIF_32BIT flag
> function. Refer to arm64 to implement DEFAULT_MAP_WINDOW_64 for
> efi-stub.
>
> Limit 32-bit compatible process in 0-2GB virtual address range
> (which is enough for real scenarios), because it could avoid
> address sign extend problem when 32-bit enter 64-bit and ease
> software design.
>
> The standard 32-bit TASK_SIZE is 0x9dc00000:FIXADDR_START, and
> compared to a compatible 32-bit, it increases 476MB for the
> application's virtual address.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From baruch at tkos.co.il  Thu Jan 20 02:29:32 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 20 Jan 2022 12:29:32 +0200
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <1965fc315525b8ab26cf9f71f939c24d@codeaurora.org>
References: <20220119002438.106079-1-sean.anderson@seco.com>
 <87ee53fv01.fsf@tarshish>
 <1965fc315525b8ab26cf9f71f939c24d@codeaurora.org>
Message-ID: <871r12g0j2.fsf@tarshish>

Hi Kathiravan,

On Thu, Jan 20 2022, Kathiravan T wrote:
> On 2022-01-19 23:44, Baruch Siach wrote:
>> Hi Sean,
>> On Tue, Jan 18 2022, Sean Anderson wrote:
>>> This is a rework of patches 3-5 of [1]. It attempts to correctly program
>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>>> we no longer need a special property duplicating this configuration,
>>> snps,ref-clock-period-ns is deprecated.
>>> Please test this! Patches 3/4 in this series have the effect of
>>> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>>> the "ref" clock. I have build tested, but not much else.
>> Tested here on IPQ6010 based system. USB still works. But the with 
>> "ref"
>> clock at 24MHz, period is calculated as 0x29. Previous
>> snps,ref-clock-period-ns value used to be 0x32.
>> Is that expected?
>
> Yes, it is 0x29 for IPQ60xx based SoCs. In downstream it was wrongly mentioned
> as 0x32, which was corrected recently.

Thanks for the update. This needs fixing in upstream kernel. I'll send a
patch.

For some reason USB appears to work here with both values. Is it because
I only use USB2 signals? If this is the case them I can not actually
test this series on my system.

Thanks,
baruch

>>> [1] 
>>> https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/
>>> Changes in v2:
>>> - Document clock members
>>> - Also program GFLADJ.240MHZDECR
>>> - Don't program GFLADJ if the version is < 2.50a
>>> - Add snps,ref-clock-frequency-hz property for ACPI
>>> Sean Anderson (7):
>>>   dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>>>   usb: dwc3: Get clocks individually
>>>   usb: dwc3: Calculate REFCLKPER based on reference clock
>>>   usb: dwc3: Program GFLADJ
>>>   usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
>>>   arm64: dts: zynqmp: Move USB clocks to dwc3 node
>>>   arm64: dts: ipq6018: Use reference clock to set dwc3 period
>>>  .../devicetree/bindings/usb/snps,dwc3.yaml    |   7 +-
>>>  arch/arm64/boot/dts/qcom/ipq6018.dtsi         |   3 +-
>>>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |   4 +-
>>>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |   4 +-
>>>  drivers/usb/dwc3/core.c                       | 112 +++++++++++++++---
>>>  drivers/usb/dwc3/core.h                       |  17 ++-
>>>  6 files changed, 120 insertions(+), 27 deletions(-)


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From alexandre.belloni at bootlin.com  Thu Jan 20 02:54:43 2022
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Thu, 20 Jan 2022 11:54:43 +0100
Subject: [PATCH] dt-bindings: rtc: st,stm32-rtc: Make each example a
 separate entry
In-Reply-To: <Yeg4Sba3eye24+LG@robh.at.kernel.org>
References: <20220106182518.1435497-7-robh@kernel.org>
 <Yeg4Sba3eye24+LG@robh.at.kernel.org>
Message-ID: <Yek/c2hPGID0neTc@piout.net>

Hello Rob,

On 19/01/2022 10:11:53-0600, Rob Herring wrote:
> On Thu, 06 Jan 2022 12:25:15 -0600, Rob Herring wrote:
> > Each independent example should be a separate entry. This allows for
> > 'interrupts' to have different cell sizes.
> > 
> > Signed-off-by: Rob Herring <robh at kernel.org>
> > ---
> >  Documentation/devicetree/bindings/rtc/st,stm32-rtc.yaml | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> 
> Applied, thanks!

Just for the record, I didn't reply but I trust you completely on this
one ;) I'm usually letting you apply dt-bindings only patches, let me
know if you prefer they go through my tree.

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From arnd at arndb.de  Thu Jan 20 02:10:53 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 11:10:53 +0100
Subject: [PATCH V3 17/17] KVM: compat: riscv: Prevent KVM_COMPAT from
 being selected
In-Reply-To: <20220120073911.99857-18-guoren@kernel.org>
References: <20220120073911.99857-18-guoren@kernel.org>
Message-ID: <CAK8P3a1_qwRpfHRyF75WEqfxGxgVnfB15vNS-egQctx7R5-DvA@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Current riscv doesn't support the 32bit KVM/arm API. Let's make it
> clear by not selecting KVM_COMPAT.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> ---
>  virt/kvm/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
> index f4834c20e4a6..a8c5c9f06b3c 100644
> --- a/virt/kvm/Kconfig
> +++ b/virt/kvm/Kconfig
> @@ -53,7 +53,7 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
>
>  config KVM_COMPAT
>         def_bool y
> -       depends on KVM && COMPAT && !(S390 || ARM64)
> +       depends on KVM && COMPAT && !(S390 || ARM64 || RISCV)

Maybe this should be flipped around into a positive list now?
The remaining architectures would be mips, powerpc and x86, but it's unclear
if this actually meant to work on all of them, or any potential ones
added in the
future.

       Arnd


From james.clark at arm.com  Thu Jan 20 03:30:46 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 20 Jan 2022 11:30:46 +0000
Subject: [PATCH v2 0/1] coresight: Fix TRCCONFIGR.QE sysfs interface
Message-ID: <20220120113047.2839622-1-james.clark@arm.com>

Changes since v1:
 * Add Mike's reviewed by tag
 * Also make it impossible to write the reserved value of 0b10, regardless
   of what is supplied by the user.

James Clark (1):
  coresight: Fix TRCCONFIGR.QE sysfs interface

 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

-- 
2.28.0



From james.clark at arm.com  Thu Jan 20 03:30:47 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 20 Jan 2022 11:30:47 +0000
Subject: [PATCH v2 1/1] coresight: Fix TRCCONFIGR.QE sysfs interface
In-Reply-To: <20220120113047.2839622-1-james.clark@arm.com>
References: <20220120113047.2839622-1-james.clark@arm.com>
Message-ID: <20220120113047.2839622-2-james.clark@arm.com>

It's impossible to program a valid value for TRCCONFIGR.QE
when TRCIDR0.QSUPP==0b10. In that case the following is true:

  Q element support is implemented, and only supports Q elements without
  instruction counts. TRCCONFIGR.QE can only take the values 0b00 or 0b11.

Currently the low bit of QSUPP is checked to see if the low bit of QE can
be written to, but as you can see when QSUPP==0b10 the low bit is cleared
making it impossible to ever write the only valid value of 0b11 to QE.
0b10 would be written instead, which is a reserved QE value even for all
values of QSUPP.

The fix is to allow writing the low bit of QE for any non zero value of
QSUPP.

This change also ensures that the low bit is always set, even when the
user attempts to only set the high bit.

Signed-off-by: James Clark <james.clark at arm.com>
Reviewed-by: Mike Leach <mike.leach at linaro.org>
---
 drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a0640fa5c55b..57e94424a8d6 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -367,8 +367,12 @@ static ssize_t mode_store(struct device *dev,
 	mode = ETM_MODE_QELEM(config->mode);
 	/* start by clearing QE bits */
 	config->cfg &= ~(BIT(13) | BIT(14));
-	/* if supported, Q elements with instruction counts are enabled */
-	if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
+	/*
+	 * if supported, Q elements with instruction counts are enabled.
+	 * Always set the low bit for any requested mode. Valid combos are
+	 * 0b00, 0b01 and 0b11.
+	 */
+	if (mode && drvdata->q_support)
 		config->cfg |= BIT(13);
 	/*
 	 * if supported, Q elements with and without instruction
-- 
2.28.0



From arnd at arndb.de  Thu Jan 20 01:39:45 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:39:45 +0100
Subject: [PATCH V3 15/17] riscv: compat: Add UXL_32 support in start_thread
In-Reply-To: <20220120073911.99857-16-guoren@kernel.org>
References: <20220120073911.99857-16-guoren@kernel.org>
Message-ID: <CAK8P3a0Mr2m2dVoVss59cN-9X7GVBD29VQLo3m4xswRznk_WUQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> +
> +#ifdef CONFIG_COMPAT
> +       if (is_compat_task())
> +               regs->status |= SR_UXL_32;
> +#endif


You should not need that #ifdef, as the is_compat_task() definition is
meant to drop the code at compile time, unless the SR_UXL_32
definition is not visible here.

         Arnd


From james.clark at arm.com  Thu Jan 20 03:37:29 2022
From: james.clark at arm.com (James Clark)
Date: Thu, 20 Jan 2022 11:37:29 +0000
Subject: [PATCH 1/1] coresight: Fix TRCCONFIGR.QE sysfs interface
In-Reply-To: <CAJ9a7VhedrLMKfXBqzD_9fFxzKTg63-9wUM38Tw6ukhmSR9aoA@mail.gmail.com>
References: <20220114173254.1876151-1-james.clark@arm.com>
 <20220114173254.1876151-2-james.clark@arm.com>
 <CAJ9a7VhedrLMKfXBqzD_9fFxzKTg63-9wUM38Tw6ukhmSR9aoA@mail.gmail.com>
Message-ID: <139e5fb6-b917-163e-751c-1ef745852529@arm.com>



On 19/01/2022 15:22, Mike Leach wrote:
> Hi James
> 
> On Fri, 14 Jan 2022 at 17:33, James Clark <james.clark at arm.com> wrote:
>>
>> It's impossible to program a valid value for TRCCONFIGR.QE
>> when TRCIDR0.QSUPP==0b10. In that case the following is true:
>>
>>   Q element support is implemented, and only supports Q elements without
>>   instruction counts. TRCCONFIGR.QE can only take the values 0b00 or 0b11.
>>
>> Currently the low bit of QSUPP is checked to see if the low bit of QE can
>> be written to, but as you can see when QSUPP==0b10 the low bit is cleared
>> making it impossible to ever write the only valid value of 0b11 to QE.
>> 0b10 would be written instead, which is a reserved QE value even for all
>> values of QSUPP.
>>
>> The fix is to allow writing the low bit of QE for any non zero value of
>> QSUPP.
>>
>> This change doesn't go any further to validate if the user supplied value
>> is valid, because none of the other parts this function do, but it does fix
>> the case where it was impossible to ever set a valid value.
>>
> 
> I concur that the input is not checked as valid, However all the other
> fields are single bit - with no invalid values - other than the cond
> field, which controls tracing of non-branch conditionals -
> architecturally unsupported for A profile in ETMv4/.
> 
> 
>> Signed-off-by: James Clark <james.clark at arm.com>
>> ---
>>  drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
>> index a0640fa5c55b..a99bb537ea23 100644
>> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
>> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
>> @@ -368,7 +368,7 @@ static ssize_t mode_store(struct device *dev,
>>         /* start by clearing QE bits */
>>         config->cfg &= ~(BIT(13) | BIT(14));
>>         /* if supported, Q elements with instruction counts are enabled */
>> -       if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
>> +       if ((mode & BIT(0)) && drvdata->q_support)
>>                 config->cfg |= BIT(13);
> 
> This can be trivially changed to
> 
> if ((mode)  && drvdata->q_support)
>          config->cfg |= BIT(13);
> 
> to ensure that any input mode 2'b01, 2'b10, 2'b11 results in output
> settings of 2'b01, 2'b11, 2'b11 respectively
> 
> With that
> 
> Reviewed-by: Mike Leach <mike.leach at linaro.org>
> 

Thanks for the review. Can I also get your opinion about this one? At the very least
I think the comment is not detailed enough, but I also think that case 0 should set
BIT(0) rather than BIT(1). Or is there some edge case and it's correct?


	/* start by clearing all instruction event enable bits */
	config->eventctrl1 &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3));
	switch (drvdata->nr_event) {
	case 0x0:
		/* generate Event element for event 1 */
		config->eventctrl1 |= val & BIT(1);
		break;
	case 0x1:
		/* generate Event element for event 1 and 2 */
		config->eventctrl1 |= val & (BIT(0) | BIT(1));
		break;
	case 0x2:
		/* generate Event element for event 1, 2 and 3 */
		config->eventctrl1 |= val & (BIT(0) | BIT(1) | BIT(2));
		break;
	case 0x3:
		/* generate Event element for all 4 events */
		config->eventctrl1 |= val & 0xF;
		break;
	default:
		break;
	}


>>         /*
>>          * if supported, Q elements with and without instruction
>> --
>> 2.17.1
>>
> 
> 


From alexandru.elisei at arm.com  Thu Jan 20 03:52:00 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 20 Jan 2022 11:52:00 +0000
Subject: [PATCH v5 17/69] KVM: arm64: nv: Add non-VHE-EL2->EL1
 translation helpers
In-Reply-To: <20211129200150.351436-18-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-18-maz@kernel.org>
Message-ID: <YelM4PNEjbxYkpZ3@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:58PM +0000, Marc Zyngier wrote:
> Some EL2 system registers immediately affect the current execution
> of the system, so we need to use their respective EL1 counterparts.
> For this we need to define a mapping between the two. In general,
> this only affects non-VHE guest hypervisors, as VHE system registers
> are compatible with the EL1 counterparts.
> 
> These helpers will get used in subsequent patches.
> 
> Co-developed-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_nested.h | 50 +++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> index 1028ac65a897..67a2c0d05233 100644
> --- a/arch/arm64/include/asm/kvm_nested.h
> +++ b/arch/arm64/include/asm/kvm_nested.h
> @@ -2,6 +2,7 @@
>  #ifndef __ARM64_KVM_NESTED_H
>  #define __ARM64_KVM_NESTED_H
>  
> +#include <linux/bitfield.h>
>  #include <linux/kvm_host.h>
>  
>  static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
> @@ -11,4 +12,53 @@ static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
>  		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
>  }
>  
> +/* Translation helpers from non-VHE EL2 to EL1 */
> +static inline u64 tcr_el2_ips_to_tcr_el1_ps(u64 tcr_el2)

When E2H = 0, there is no IPS field in TCR_EL2, but there is a PS field.
And for TCR_EL1, there is no PS field, but there is an IPS field. Maybe
tcr_el2_ps_to_tcr_el1_ips() would be more precise, and would also match the
field defines used by the function?

> +{
> +	return (u64)FIELD_GET(TCR_EL2_PS_MASK, tcr_el2) << TCR_IPS_SHIFT;
> +}
> +
> +static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
> +{
> +	return TCR_EPD1_MASK |				/* disable TTBR1_EL1 */
> +	       ((tcr & TCR_EL2_TBI) ? TCR_TBI0 : 0) |
> +	       tcr_el2_ips_to_tcr_el1_ps(tcr) |
> +	       (tcr & TCR_EL2_TG0_MASK) |
> +	       (tcr & TCR_EL2_ORGN0_MASK) |
> +	       (tcr & TCR_EL2_IRGN0_MASK) |
> +	       (tcr & TCR_EL2_T0SZ_MASK);

There are a few fields in TCR_EL2 which have a corresponding field in
TCR_EL1, when E2H = 0: HPD -> HPD0 (hierarchical permissions toggle), HA
and HD (hardware management of dirty bit and access flag), DS (when
FEAT_LPA2), and probably others. Why do we not also translate them? Is it
because we hide the feature they depend on (FEAT_HPDS, FEAT_HAFBDS, etc) in
the guest ID registers? Is it something else?

> +}
> +
> +static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
> +{
> +	u64 cpacr_el1 = 0;
> +
> +	if (!(cptr_el2 & CPTR_EL2_TFP))
> +		cpacr_el1 |= CPACR_EL1_FPEN;
> +	if (cptr_el2 & CPTR_EL2_TTA)
> +		cpacr_el1 |= CPACR_EL1_TTA;
> +	if (!(cptr_el2 & CPTR_EL2_TZ))
> +		cpacr_el1 |= CPACR_EL1_ZEN;
> +
> +	return cpacr_el1;

Nitpick: it would make comparing against the architecture easier if the
fields were checked in the order they were definied in the architecture. So
first check the TTA bit, then TFP and lastly TZ.

I checked the field definitions for CPTR_EL2 and the above looks correct to
me, as TFP, TTA and TZ were the only fields which affect EL2; I also
checked that the values in CPACR_EL1 are set correctly to mirror the
CPTR_EL2 settings.

> +}
> +
> +static inline u64 translate_sctlr_el2_to_sctlr_el1(u64 sctlr)
> +{
> +	/* Bit 20 is RES1 in SCTLR_EL1, but RES0 in SCTLR_EL2 */
> +	return sctlr | BIT(20);

Bits 8 and 7 in SCTLR_EL2 are RES0 when E2H,TGE != {1,1}, but they are RES1
in SCTLR_EL1 if EL0 is not capable of using AArch32. Shouldn't we also set
them?

Bit 5 in SCTLR_EL2 is RES1 when E2H,TGE != {1,1}, but it is RES0 in
SCTLR_EL1 if EL0 is not capable of using AArch32. Shouldn't we clear it?

> +}
> +
> +static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
> +{
> +	/* Force ASID to 0 (ASID 0 or RES0) */

That got me confused at first, until I realized that the first ASID refers
to the ASID field of the register, and the second ASID to the translation
table property. Might be more helpful if the comment was simply "Clear the
ASID field" or something like that.

> +	return ttbr0 & ~GENMASK_ULL(63, 48);
> +}
> +
> +static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
> +{
> +	return ((FIELD_GET(CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN, cnthctl) << 10) |

I don't understand why those two bits are left shifted by 10, the result is
0x3 << 10 and CNTKCTL_EL[16:10] is RES0.

> +		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));

CNTKCTL_EL1.{EVNTI,EVNTDIR,EVNTEN} refer to CNT*V*CT_EL0,
CNTHCTL_EL2.{EVNTI,EVNTDIR,EVNTEN} refer to CNT*P*CT_EL0. I don't
understand why they are treated as equivalent.

I get the feeling I'm misunderstanding something about this function.

Thanks,
Alex

> +}
> +
>  #endif /* __ARM64_KVM_NESTED_H */
> -- 
> 2.30.2
> 


From patchwork-bot+netdevbpf at kernel.org  Thu Jan 20 04:00:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 20 Jan 2022 12:00:10 +0000
Subject: [PATCH v2 0/2] net: stmmac: dwmac-visconti: Fix bit definitions
 and clock configuration for RMII mode
In-Reply-To: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220119044648.18094-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <164268001022.32466.14296016089234300224.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Wed, 19 Jan 2022 13:46:46 +0900 you wrote:
> Hi,
> 
> This series is a fix for RMII/MII operation mode of the dwmac-visconti driver.
> It is composed of two parts:
> 
> * 1/2: fix constant definitions for cleared bits in ETHER_CLK_SEL register
> * 2/2: fix configuration of ETHER_CLK_SEL register for running in RMII operation mode.
> 
> [...]

Here is the summary with links:
  - [v2,1/2] net: stmmac: dwmac-visconti: Fix bit definitions for ETHER_CLK_SEL
    https://git.kernel.org/netdev/net/c/1ba1a4a90fa4
  - [v2,2/2] net: stmmac: dwmac-visconti: Fix clock configuration for RMII mode
    https://git.kernel.org/netdev/net/c/0959bc4bd420

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From jneuhauser at dh-electronics.com  Thu Jan 20 04:07:09 2022
From: jneuhauser at dh-electronics.com (Johann Neuhauser)
Date: Thu, 20 Jan 2022 12:07:09 +0000
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <61a45bcf348144beaa9e6678f1ed0fa1@dh-electronics.com>

> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Tuesday, January 18, 2022 9:30 PM
> 
> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
> in use, ETHCKEN gate can be turned off. Current driver does not permit
> that, fix it.
> 
> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
> ETHPTP_K remain functional as before.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>     Figure 83. Peripheral clock distribution for Ethernet
>     https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/clk/clk-stm32mp1.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
> index 863274aa50e38..23a34ab459a3b 100644
> --- a/drivers/clk/clk-stm32mp1.c
> +++ b/drivers/clk/clk-stm32mp1.c
> @@ -2008,7 +2008,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>         KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
>         KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
>         KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
> -       KCLK(ETHCK_K, "ethck_k", eth_src, 0, G_ETHCK, M_ETHCK),
> 
>         /* Particulary Kernel Clocks (no mux or no gate) */
>         MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
> @@ -2017,11 +2016,16 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>         MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
>         MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
> 
> -       COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE |
> +       COMPOSITE(NO_ID, "ck_ker_eth", eth_src, CLK_OPS_PARENT_ENABLE |
>                   CLK_SET_RATE_NO_REPARENT,
>                   _NO_GATE,
>                   _MMUX(M_ETHCK),
> -                 _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
> +                 _NO_DIV),
> +
> +       MGATE_MP1(ETHCK_K, "ethck_k", "ck_ker_eth", 0, G_ETHCK),
> +
> +       DIV(ETHPTP_K, "ethptp_k", "ck_ker_eth", CLK_OPS_PARENT_ENABLE |
> +           CLK_SET_RATE_NO_REPARENT, RCC_ETHCKSELR, 4, 4, 0),
> 
>         /* RTC clock */
>         COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE,
> --
> 2.34.1
Tested-by: Johann Neuhauser <jneuhauser at dh-electronics.com>

From jneuhauser at dh-electronics.com  Thu Jan 20 04:07:54 2022
From: jneuhauser at dh-electronics.com (Johann Neuhauser)
Date: Thu, 20 Jan 2022 12:07:54 +0000
Subject: [PATCH 4/5] ARM: dts: stm32: Add alternate pinmux for mco2 pins
In-Reply-To: <20220118202958.1840431-4-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-4-marex@denx.de>
Message-ID: <f6be9f579bfb4588847ab1326902eee1@dh-electronics.com>

> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Tuesday, January 18, 2022 9:30 PM
> 
> Add pinmux option for MCO2 pin. This is used on DHCOM when the
> ethernet PHY 50 MHz clock is generated by the MCO2 on PG2 pin.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>  arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> index 2cd2ac9beaf20..6da84e3f05ea3 100644
> --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> @@ -882,6 +882,21 @@ pins {
>                 };
>         };
> 
> +       mco2_pins_a: mco2-0 {
> +               pins {
> +                       pinmux = <STM32_PINMUX('G', 2, AF1)>; /* MCO2 */
> +                       bias-disable;
> +                       drive-push-pull;
> +                       slew-rate = <2>;
> +               };
> +       };
> +
> +       mco2_sleep_pins_a: mco2-sleep-0 {
> +               pins {
> +                       pinmux = <STM32_PINMUX('G', 2, ANALOG)>; /* MCO2 */
> +               };
> +       };
> +
>         m_can1_pins_a: m-can1-0 {
>                 pins1 {
>                         pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
> --
> 2.34.1
Tested-by: Johann Neuhauser <jneuhauser at dh-electronics.com>

From robin.murphy at arm.com  Thu Jan 20 04:22:35 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 20 Jan 2022 12:22:35 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YehilqRvYLhryUk4@shell.armlinux.org.uk>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
Message-ID: <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>

On 2022-01-19 19:12, Russell King (Oracle) wrote:
> On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
>> Indeed, my impression is that the only legitimate way to get hold of a page
>> pointer without assumed provenance is via pfn_to_page(), which is where
>> pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
>> tautology.
> 
> That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
> values of pfn.
> 
> Given how pfn_to_page() is defined in the sparsemem case:
> 
> #define __pfn_to_page(pfn)                              \
> ({	unsigned long __pfn = (pfn);                    \
> 	struct mem_section *__sec = __pfn_to_section(__pfn);    \
> 	__section_mem_map_addr(__sec) + __pfn;          \
> })
> #define page_to_pfn __page_to_pfn
> 
> that isn't the case, especially when looking at page_to_pfn():
> 
> #define __page_to_pfn(pg)                                       \
> ({      const struct page *__pg = (pg);                         \
>          int __sec = page_to_section(__pg);                      \
> 	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
> })
> 
> Where:
> 
> static inline unsigned long page_to_section(const struct page *page)
> {
> 	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> }
> 
> So if page_to_section() returns something that is, e.g. zero for an
> invalid page in a non-zero section, you're not going to end up with
> the right pfn from page_to_pfn().

Right, I emphasised "should" in an attempt to imply "in the absence of 
serious bugs that have further-reaching consequences anyway".

> As I've said now a couple of times, trying to determine of a struct
> page pointer is valid is the wrong question to be asking.

And doing so in one single place, on the justification of avoiding an 
incredibly niche symptom, is even more so. Not to mention that an 
address size fault is one of the best possible outcomes anyway, vs. the 
untold damage that may stem from accesses actually going through to 
random parts of the physical memory map.

Robin.


From jneuhauser at dh-electronics.com  Thu Jan 20 04:07:12 2022
From: jneuhauser at dh-electronics.com (Johann Neuhauser)
Date: Thu, 20 Jan 2022 12:07:12 +0000
Subject: [PATCH 2/5] clk: stm32mp1: Add parent_data to ETHRX clock
In-Reply-To: <20220118202958.1840431-2-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-2-marex@denx.de>
Message-ID: <ddf6afba3fd2402a8b3f60fe30bbdbba@dh-electronics.com>

> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Tuesday, January 18, 2022 9:30 PM
> 
> Pass parent_data to ETHRX clock with new fw_name = "ETH_RX_CLK/ETH_REF_CLK".
> By default, this change has no impact on the operation of the clock driver.
> However, due to the fw_name, it permits DT to override ETHRX clock parent,
> which might be needed in case the ETHRX clock are supplied by external clock
> source.
> 
> Example of MCO2 supplying clock to ETH_RX_CLK via external pad-to-pad wire:
> &rcc {
>          clocks = <&rcc CK_MCO2>;
>          clock-names = "ETH_RX_CLK/ETH_REF_CLK";
> };
> 
> Note that while this patch permits to implement this rare usecase, the issue
> with ethernet RX and TX input clock modeling on MP1 is far more complex and
> requires more core plumbing.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>     Figure 83. Peripheral clock distribution for Ethernet
>     https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-
> stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>  drivers/clk/clk-stm32mp1.c | 36 ++++++++++++++++++++++++++++++++----
>  1 file changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
> index 23a34ab459a3b..7ad2e6203baef 100644
> --- a/drivers/clk/clk-stm32mp1.c
> +++ b/drivers/clk/clk-stm32mp1.c
> @@ -155,6 +155,10 @@ static const char * const eth_src[] = {
>         "pll4_p", "pll3_q"
>  };
> 
> +const struct clk_parent_data ethrx_src[] = {
> +       { .name = "ethck_k", .fw_name = "ETH_RX_CLK/ETH_REF_CLK" },
> +};
> +
>  static const char * const rng_src[] = {
>         "ck_csi", "pll4_r", "ck_lse", "ck_lsi"
>  };
> @@ -317,6 +321,7 @@ struct clock_config {
>         const char *name;
>         const char *parent_name;
>         const char * const *parent_names;
> +       const struct clk_parent_data *parent_data;
>         int num_parents;
>         unsigned long flags;
>         void *cfg;
> @@ -576,6 +581,7 @@ static struct clk_hw *
>  clk_stm32_register_gate_ops(struct device *dev,
>                             const char *name,
>                             const char *parent_name,
> +                           const struct clk_parent_data *parent_data,
>                             unsigned long flags,
>                             void __iomem *base,
>                             const struct stm32_gate_cfg *cfg,
> @@ -586,7 +592,10 @@ clk_stm32_register_gate_ops(struct device *dev,
>         int ret;
> 
>         init.name = name;
> -       init.parent_names = &parent_name;
> +       if (parent_name)
> +               init.parent_names = &parent_name;
> +       if (parent_data)
> +               init.parent_data = parent_data;
>         init.num_parents = 1;
>         init.flags = flags;
> 
> @@ -611,6 +620,7 @@ clk_stm32_register_gate_ops(struct device *dev,
>  static struct clk_hw *
>  clk_stm32_register_composite(struct device *dev,
>                              const char *name, const char * const *parent_names,
> +                            const struct clk_parent_data *parent_data,
>                              int num_parents, void __iomem *base,
>                              const struct stm32_composite_cfg *cfg,
>                              unsigned long flags, spinlock_t *lock)
> @@ -1135,6 +1145,7 @@ _clk_stm32_register_gate(struct device *dev,
>         return clk_stm32_register_gate_ops(dev,
>                                     cfg->name,
>                                     cfg->parent_name,
> +                                   cfg->parent_data,
>                                     cfg->flags,
>                                     base,
>                                     cfg->cfg,
> @@ -1148,8 +1159,8 @@ _clk_stm32_register_composite(struct device *dev,
>                               const struct clock_config *cfg)
>  {
>         return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
> -                                           cfg->num_parents, base, cfg->cfg,
> -                                           cfg->flags, lock);
> +                                           cfg->parent_data, cfg->num_parents,
> +                                           base, cfg->cfg, cfg->flags, lock);
>  }
> 
>  #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
> @@ -1258,6 +1269,16 @@ _clk_stm32_register_composite(struct device *dev,
>         .func           = _clk_stm32_register_gate,\
>  }
> 
> +#define STM32_GATE_PDATA(_id, _name, _parent, _flags, _gate)\
> +{\
> +       .id             = _id,\
> +       .name           = _name,\
> +       .parent_data    = _parent,\
> +       .flags          = _flags,\
> +       .cfg            = (struct stm32_gate_cfg *) {_gate},\
> +       .func           = _clk_stm32_register_gate,\
> +}
> +
>  #define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _mgate, _ops)\
>         (&(struct stm32_gate_cfg) {\
>                 &(struct gate_cfg) {\
> @@ -1291,6 +1312,10 @@ _clk_stm32_register_composite(struct device *dev,
>         STM32_GATE(_id, _name, _parent, _flags,\
>                    _STM32_MGATE(_mgate))
> 
> +#define MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)\
> +       STM32_GATE_PDATA(_id, _name, _parent, _flags,\
> +                  _STM32_MGATE(_mgate))
> +
>  #define _STM32_DIV(_div_offset, _div_shift, _div_width,\
>                    _div_flags, _div_table, _ops)\
>         .div = &(struct stm32_div_cfg) {\
> @@ -1354,6 +1379,9 @@ _clk_stm32_register_composite(struct device *dev,
>  #define PCLK(_id, _name, _parent, _flags, _mgate)\
>         MGATE_MP1(_id, _name, _parent, _flags, _mgate)
> 
> +#define PCLK_PDATA(_id, _name, _parent, _flags, _mgate)\
> +       MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)
> +
>  #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
>              COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
>                        CLK_SET_RATE_NO_REPARENT | _flags,\
> @@ -1951,7 +1979,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>         PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
>         PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
>         PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
> -       PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX),
> +       PCLK_PDATA(ETHRX, "ethrx", ethrx_src, 0, G_ETHRX),
>         PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
>         PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
>         PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
> --
> 2.34.1
Tested-by: Johann Neuhauser <jneuhauser at dh-electronics.com>


From jneuhauser at dh-electronics.com  Thu Jan 20 04:08:13 2022
From: jneuhauser at dh-electronics.com (Johann Neuhauser)
Date: Thu, 20 Jan 2022 12:08:13 +0000
Subject: [PATCH 5/5] ARM: dts: stm32: Switch DWMAC RMII clock to MCO2 on
 DHCOM
In-Reply-To: <20220118202958.1840431-5-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-5-marex@denx.de>
Message-ID: <5dde4cf58557485790bb7c14497e8cd1@dh-electronics.com>

> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Tuesday, January 18, 2022 9:30 PM
> 
> The DHCOM SoM has two options for supplying ETHRX clock to the DWMAC
> block and PHY. Either (1) ETHCK_K generates 50 MHz clock on ETH_CLK
> pad for the PHY and the same 50 MHz clock are fed back to ETHRX via
> internal eth_clk_fb clock connection OR (2) ETH_CLK is not used at
> all, MCO2 generates 50 MHz clock on MCO2 output pad for the PHY and
> the same MCO2 clock are fed back into ETHRX via ETH_RX_CLK input pad
> using external pad-to-pad connection.
> 
> Option (1) has two downsides. ETHCK_K is supplied directly from either
> PLL3_Q or PLL4_P, hence the PLL output is limited to exactly 50 MHz and
> since the same PLL output is also used to supply SDMMC blocks, the
> performance of SD and eMMC access is affected. The second downside is
> that using this option, the EMI of the SoM is higher.
> 
> Option (2) solves both of those problems, so implement it here. In this
> case, the PLL4_P is no longer limited and can be operated faster, at
> 100 MHz, which improves SDMMC performance (read performance is improved
> from ~41 MiB/s to ~57 MiB/s with dd if=/dev/mmcblk1 of=/dev/null bs=64M
> count=1). The EMI interference also decreases.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>  arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 22 ++++++++++++++++----
>  1 file changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
> index 8c41f819f7769..b091d9901e976 100644
> --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
> +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi
> @@ -116,15 +116,29 @@ &dts {
>         status = "okay";
>  };
> 
> +&rcc {
> +       /* Connect MCO2 output to ETH_RX_CLK input via pad-pad connection */
> +       clocks = <&rcc CK_MCO2>;
> +       clock-names = "ETH_RX_CLK/ETH_REF_CLK";
> +
> +       /*
> +        * Set PLL4P output to 100 MHz to supply SDMMC with faster clock,
> +        * set MCO2 output to 50 MHz to supply ETHRX clock with PLL4P/2,
> +        * so that MCO2 behaves as a divider for the ETHRX clock here.
> +        */
> +       assigned-clocks = <&rcc CK_MCO2>, <&rcc PLL4_P>;
> +       assigned-clock-parents = <&rcc PLL4_P>;
> +       assigned-clock-rates = <50000000>, <100000000>;
> +};
> +
>  &ethernet0 {
>         status = "okay";
> -       pinctrl-0 = <&ethernet0_rmii_pins_a>;
> -       pinctrl-1 = <&ethernet0_rmii_sleep_pins_a>;
> +       pinctrl-0 = <&ethernet0_rmii_pins_b &mco2_pins_a>;
> +       pinctrl-1 = <&ethernet0_rmii_sleep_pins_b &mco2_sleep_pins_a>;
>         pinctrl-names = "default", "sleep";
>         phy-mode = "rmii";
>         max-speed = <100>;
>         phy-handle = <&phy0>;
> -       st,eth-ref-clk-sel;
> 
>         mdio0 {
>                 #address-cells = <1>;
> @@ -136,7 +150,7 @@ phy0: ethernet-phy at 1 {
>                         /* LAN8710Ai */
>                         compatible = "ethernet-phy-id0007.c0f0",
>                                      "ethernet-phy-ieee802.3-c22";
> -                       clocks = <&rcc ETHCK_K>;
> +                       clocks = <&rcc CK_MCO2>;
>                         reset-gpios = <&gpioh 3 GPIO_ACTIVE_LOW>;
>                         reset-assert-us = <500>;
>                         reset-deassert-us = <500>;
> --
> 2.34.1
Tested-by: Johann Neuhauser <jneuhauser at dh-electronics.com>

From arnd at arndb.de  Thu Jan 20 01:36:13 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:36:13 +0100
Subject: [PATCH V3 10/17] riscv: compat: Add elf.h implementation
In-Reply-To: <20220120073911.99857-11-guoren@kernel.org>
References: <20220120073911.99857-11-guoren@kernel.org>
Message-ID: <CAK8P3a2HaeFGdOr4Rm_ZcEP0rjh2Mo53=-ZRnEPtFfnmzfeE6g@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Implement necessary type and macro for compat elf. See the code
> comment for detail.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>

> +
> +/*
> + * FIXME: not sure SET_PERSONALITY for compat process is right!
> + */
> +#define SET_PERSONALITY(ex)                                    \
> +do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)              \
> +               set_thread_flag(TIF_32BIT);                     \
> +       else                                                    \
> +               clear_thread_flag(TIF_32BIT);                   \
> +       if (personality(current->personality) != PER_LINUX32)   \
> +               set_personality(PER_LINUX |                     \
> +                       (current->personality & (~PER_MASK)));  \
> +} while (0)
> +

The implementation looks good to me now,  you can remove that comment above it.

        Arnd


From hverkuil at xs4all.nl  Thu Jan 20 04:31:01 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Jan 2022 13:31:01 +0100
Subject: [PATCH v2 3/4] media: aspeed: Correct values for detected timing
In-Reply-To: <20211222082139.26933-4-jammy_huang@aspeedtech.com>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-4-jammy_huang@aspeedtech.com>
Message-ID: <5868782b-3383-5ee6-4111-841707ffee39@xs4all.nl>

Hi Jammy,

I just want to double check this: I assume you have tested this with the
various polarity combinations?

I ask because I've never seen this before in any other hardware. The
sync and porch values reported by hardware are always independent from the
polarity, so that's why I am surprised to see this.

Same for the next patch (4/4).

Regards,

	Hans

On 12/22/21 09:21, Jammy Huang wrote:
> Correct timing's fp/sync/bp value based on the information below.
> It should be noticed that the calculation formula should be changed
> per sync polarity.
> 
> The sequence of signal: sync - backporch - video data - frontporch
> 
> The following registers start counting from sync's rising edge:
> 1. VR090: frame edge's left and right
> 2. VR094: frame edge's top and bottom
> 3. VR09C: counting from sync's rising edge to falling edge
> 
> [Vertical timing]
>             +--+     +-------------------+     +--+
>             |  |     |    v i d e o      |     |  |
>          +--+  +-----+                   +-----+  +---+
> 
>        vsync+--+
>    frame_top+--------+
> frame_bottom+----------------------------+
> 
>                   +-------------------+
>                   |    v i d e o      |
>       +--+  +-----+                   +-----+  +---+
>          |  |                               |  |
>          +--+                               +--+
>        vsync+-------------------------------+
>    frame_top+-----+
> frame_bottom+-------------------------+
> 
> [Horizontal timing]
>             +--+     +-------------------+     +--+
>             |  |     |    v i d e o      |     |  |
>          +--+  +-----+                   +-----+  +---+
> 
>        hsync+--+
>   frame_left+--------+
>  frame_right+----------------------------+
> 
>                   +-------------------+
>                   |    v i d e o      |
>       +--+  +-----+                   +-----+  +---+
>          |  |                               |  |
>          +--+                               +--+
>        hsync+-------------------------------+
>   frame_left+-----+
>  frame_right+-------------------------+
> 
> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
> ---
>  v2:
>   - Code refined per Joel's suggestion
>   - Update commit message to have name matching variable
> ---
>  drivers/media/platform/aspeed-video.c | 30 ++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
> index c241038ee27c..7c50567f5ab0 100644
> --- a/drivers/media/platform/aspeed-video.c
> +++ b/drivers/media/platform/aspeed-video.c
> @@ -936,7 +936,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>  	u32 src_lr_edge;
>  	u32 src_tb_edge;
>  	u32 sync;
> -	u32 htotal;
> +	u32 htotal, vtotal, vsync, hsync;
>  	struct v4l2_bt_timings *det = &video->detected_timings;
>  
>  	det->width = MIN_WIDTH;
> @@ -983,21 +983,35 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>  		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
>  		sync = aspeed_video_read(video, VE_SYNC_STATUS);
>  		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
> +		vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
> +		vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
> +		hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
>  
>  		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>  		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
> -		det->vfrontporch = video->frame_top;
> -		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
> -			video->frame_bottom;
> -		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
> +		if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
> +			det->vbackporch = video->frame_top - vsync;
> +			det->vfrontporch = vtotal - video->frame_bottom;
> +			det->vsync = vsync;
> +		} else {
> +			det->vbackporch = video->frame_top;
> +			det->vfrontporch = vsync - video->frame_bottom;
> +			det->vsync = vtotal - vsync;
> +		}
>  		if (video->frame_top > video->frame_bottom)
>  			continue;
>  
>  		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>  		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
> -		det->hfrontporch = video->frame_left;
> -		det->hbackporch = htotal - video->frame_right;
> -		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
> +		if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
> +			det->hbackporch = video->frame_left - hsync;
> +			det->hfrontporch = htotal - video->frame_right;
> +			det->hsync = hsync;
> +		} else {
> +			det->hbackporch = video->frame_left;
> +			det->hfrontporch = hsync - video->frame_right;
> +			det->hsync = htotal - hsync;
> +		}
>  		if (video->frame_left > video->frame_right)
>  			continue;
>  


From matthias.schiffer at ew.tq-group.com  Thu Jan 20 04:32:33 2022
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Thu, 20 Jan 2022 13:32:33 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am65: disable optional
 peripherals by default
In-Reply-To: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>
References: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>
Message-ID: <2982ff768a71247dfe0acb0e7af97a36041193bd.camel@ew.tq-group.com>

On Tue, 2022-01-11 at 12:25 +0100, Matthias Schiffer wrote:
> All peripharals that require pinmuxing or other configuration to work
> should be disabled by default. Dependent DTS are adjusted
> accordingly.
> 
> The following nodes are now "disabled" according to dtx_diff and were
> not
> overridden to "okay", as they define no pinctrl:
> 
> k3-am654-base-board:
> - mcu_i2c0
> - mcu_spi0..2
> - cal
> - main_i2c3
> - ehrpwm0..5
> - main_uart1..2
> - main_spi1..4
> 
> k3-am65-iot2050*:
> - mci_spi1..2
> - cal
> - ehrpwm0..5
> - main_spi0..4

I noticed that I didn't disable mcu_uart0 in k3-am65-mcu.dtsi, which
would make sense for consistency. It is currently not disabled in
k3-am654-base-board.dts either, but it doesn't have a pinmuxing
defined. Does it work with the default muxing, or should it rather be
disabled for that board?

I can send a v2 if this patch is acceptable at all (which would be
desirable for the addition of our TQMa65xx SoM and MBa65xx carrier
board, as it allows for a similar reduction of DTS lines as the one
seen in the diffstat below for k3-am65-iot2050-common.dtsi and
k3-am654-base-board.dts).

Kind regards,
Matthias


> 
> Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com>
> ---
> 
> These changes were not tested on hardware, and I'm not familiar with
> any of these boards, so it would be great if someone could check
> whether the effective changes listed above are correct, or if some of
> these devices (in particular I2C, UART and PWM) are actually
> connected
> and work with the default pinmuxing.
> 
> There were also a few devices where I was unsure whether they are
> optional
> or not - for example one of the io2050 disables all the txpru nodes,
> so
> maybe it would make sense to disable these in the SoC DTSI as well? I
> left
> these nodes unchanged for now.
> 
>  .../dts/ti/k3-am65-iot2050-common-pg1.dtsi    |   4 -
>  .../dts/ti/k3-am65-iot2050-common-pg2.dtsi    |   7 +
>  .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 132 +++++-----------
> --
>  arch/arm64/boot/dts/ti/k3-am65-main.dtsi      |  52 +++++++
>  arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi       |  10 ++
>  arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi    |   2 +
>  .../ti/k3-am6528-iot2050-basic-common.dtsi    |   6 +-
>  .../arm64/boot/dts/ti/k3-am654-base-board.dts | 129 +++-------------
> -
>  .../ti/k3-am6548-iot2050-advanced-common.dtsi |   5 +-
>  9 files changed, 134 insertions(+), 213 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> index 51f902fa35a7..746f0e89a305 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> @@ -13,10 +13,6 @@ &dss {
>  	assigned-clock-parents = <&k3_clks 67 5>;
>  };
>  
> -&serdes0 {
> -	status = "disabled";
> -};
> -
>  &sdhci1 {
>  	no-1-8-v;
>  };
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> index e73458ca6900..b769fe6fc072 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> @@ -35,6 +35,7 @@ &dss {
>  &serdes0 {
>  	assigned-clocks = <&k3_clks 153 4>, <&serdes0
> AM654_SERDES_CMU_REFCLK>;
>  	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
> +	status = "okay";
>  };
>  
>  &dwc3_0 {
> @@ -42,10 +43,16 @@ &dwc3_0 {
>  				 <&k3_clks 151 8>;  /* set
> PIPE3_TXB_CLK to WIZ8B2M4VSB */
>  	phys = <&serdes0 PHY_TYPE_USB3 0>;
>  	phy-names = "usb3-phy";
> +	status = "okay";
>  };
>  
>  &usb0 {
>  	maximum-speed = "super-speed";
>  	snps,dis-u1-entry-quirk;
>  	snps,dis-u2-entry-quirk;
> +	status = "okay";
> +};
> +
> +&usb0_phy {
> +	status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> index 3079eaee01c0..873c123c611e 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> @@ -362,15 +362,13 @@ &wkup_uart0 {
>  &main_uart1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_uart1_pins_default>;
> -};
> -
> -&main_uart2 {
> -	status = "disabled";
> +	status = "okay";
>  };
>  
>  &mcu_uart0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&arduino_uart_pins_default>;
> +	status = "okay";
>  };
>  
>  &main_gpio0 {
> @@ -416,12 +414,14 @@ &wkup_i2c0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&wkup_i2c0_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  };
>  
>  &mcu_i2c0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_i2c0_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  
>  	psu: regulator at 60 {
>  		compatible = "ti,tps62363";
> @@ -481,6 +481,7 @@ &main_i2c0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c0_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  
>  	rtc: rtc8564 at 51 {
>  		compatible = "nxp,pcf8563";
> @@ -498,12 +499,14 @@ &main_i2c1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c1_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  };
>  
>  &main_i2c2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c2_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  };
>  
>  &main_i2c3 {
> @@ -514,6 +517,8 @@ &main_i2c3 {
>  	#address-cells = <1>;
>  	#size-cells = <0>;
>  
> +	status = "okay";
> +
>  	edp-bridge at f {
>  		compatible = "toshiba,tc358767";
>  		reg = <0x0f>;
> @@ -541,13 +546,10 @@ bridge_in: endpoint {
>  	};
>  };
>  
> -&mcu_cpsw {
> -	status = "disabled";
> -};
> -
>  &ecap0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&ecap0_pins_default>;
> +	status = "okay";
>  };
>  
>  &sdhci1 {
> @@ -555,20 +557,38 @@ &sdhci1 {
>  	pinctrl-0 = <&main_mmc1_pins_default>;
>  	ti,driver-strength-ohm = <50>;
>  	disable-wp;
> +	status = "okay";
> +};
> +
> +&dwc3_0 {
> +	status = "okay";
>  };
>  
> +
>  &usb0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&usb0_pins_default>;
>  	dr_mode = "host";
>  };
>  
> +&usb0_phy {
> +	status = "okay";
> +};
> +
> +&dwc3_1 {
> +	status = "okay";
> +};
> +
>  &usb1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&usb1_pins_default>;
>  	dr_mode = "host";
>  };
>  
> +&usb1_phy {
> +	status = "okay";
> +};
> +
>  &mcu_spi0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_spi0_pins_default>;
> @@ -576,13 +596,12 @@ &mcu_spi0 {
>  	#address-cells = <1>;
>  	#size-cells= <0>;
>  	ti,pindir-d0-out-d1-in;
> -};
> -
> -&tscadc0 {
> -	status = "disabled";
> +	status = "okay";
>  };
>  
>  &tscadc1 {
> +	status = "okay";
> +
>  	adc {
>  		ti,adc-channels = <0 1 2 3 4 5>;
>  	};
> @@ -591,6 +610,7 @@ adc {
>  &ospi0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> +	status = "okay";
>  
>  	flash at 0 {
>  		compatible = "jedec,spi-nor";
> @@ -611,6 +631,7 @@ flash at 0 {
>  &dss {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&dss_vout1_pins_default>;
> +	status = "okay";
>  
>  	assigned-clocks = <&k3_clks 67 2>;
>  	assigned-clock-parents = <&k3_clks 67 5>;
> @@ -628,17 +649,14 @@ dpi_out: endpoint {
>  	};
>  };
>  
> -&pcie0_rc {
> -	status = "disabled";
> -};
> -
> -&pcie0_ep {
> -	status = "disabled";
> +&serdes1 {
> +	status = "okay";
>  };
>  
>  &pcie1_rc {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&minipcie_pins_default>;
> +	status = "okay";
>  
>  	num-lanes = <1>;
>  	phys = <&serdes1 PHY_TYPE_PCIE 0>;
> @@ -646,20 +664,9 @@ &pcie1_rc {
>  	reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>;
>  };
>  
> -&m_can0 {
> -	status = "disabled";
> -};
> -
> -&m_can1 {
> -	status = "disabled";
> -};
> -
> -&pcie1_ep {
> -	status = "disabled";
> -};
> -
>  &mailbox0_cluster0 {
>  	interrupts = <436>;
> +	status = "okay";
>  
>  	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
>  		ti,mbox-tx = <1 0 0>;
> @@ -669,6 +676,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
>  
>  &mailbox0_cluster1 {
>  	interrupts = <432>;
> +	status = "okay";
>  
>  	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
>  		ti,mbox-tx = <1 0 0>;
> @@ -676,46 +684,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
>  	};
>  };
>  
> -&mailbox0_cluster2 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster3 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster4 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster5 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster6 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster7 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster8 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster9 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster10 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster11 {
> -	status = "disabled";
> -};
> -
>  &mcu_r5fss0_core0 {
>  	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
>  			<&mcu_r5fss0_core0_memory_region>;
> @@ -727,27 +695,3 @@ &mcu_r5fss0_core1 {
>  			<&mcu_r5fss0_core1_memory_region>;
>  	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>;
>  };
> -
> -&icssg0_mdio {
> -	status = "disabled";
> -};
> -
> -&icssg1_mdio {
> -	status = "disabled";
> -};
> -
> -&icssg2_mdio {
> -	status = "disabled";
> -};
> -
> -&mcasp0 {
> -	status = "disabled";
> -};
> -
> -&mcasp1 {
> -	status = "disabled";
> -};
> -
> -&mcasp2 {
> -	status = "disabled";
> -};
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> index ce8bb4a61011..5aa425d1ba80 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> @@ -64,6 +64,7 @@ serdes0: serdes at 900000 {
>  		ti,serdes-clk = <&serdes0_clk>;
>  		#clock-cells = <1>;
>  		mux-controls = <&serdes_mux 0>;
> +		status = "disabled";
>  	};
>  
>  	serdes1: serdes at 910000 {
> @@ -79,6 +80,7 @@ serdes1: serdes at 910000 {
>  		ti,serdes-clk = <&serdes1_clk>;
>  		#clock-cells = <1>;
>  		mux-controls = <&serdes_mux 1>;
> +		status = "disabled";
>  	};
>  
>  	main_uart0: serial at 2800000 {
> @@ -88,6 +90,7 @@ main_uart0: serial at 2800000 {
>  		clock-frequency = <48000000>;
>  		current-speed = <115200>;
>  		power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	main_uart1: serial at 2810000 {
> @@ -96,6 +99,7 @@ main_uart1: serial at 2810000 {
>  		interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
>  		clock-frequency = <48000000>;
>  		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	main_uart2: serial at 2820000 {
> @@ -104,6 +108,7 @@ main_uart2: serial at 2820000 {
>  		interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
>  		clock-frequency = <48000000>;
>  		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	crypto: crypto at 4e00000 {
> @@ -152,6 +157,7 @@ main_i2c0: i2c at 2000000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 110 1>;
>  		power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	main_i2c1: i2c at 2010000 {
> @@ -163,6 +169,7 @@ main_i2c1: i2c at 2010000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 111 1>;
>  		power-domains = <&k3_pds 111 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	main_i2c2: i2c at 2020000 {
> @@ -174,6 +181,7 @@ main_i2c2: i2c at 2020000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 112 1>;
>  		power-domains = <&k3_pds 112 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	main_i2c3: i2c at 2030000 {
> @@ -185,6 +193,7 @@ main_i2c3: i2c at 2030000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 113 1>;
>  		power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	ecap0: pwm at 3100000 {
> @@ -194,6 +203,7 @@ ecap0: pwm at 3100000 {
>  		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&k3_clks 39 0>;
>  		clock-names = "fck";
> +		status = "disabled";
>  	};
>  
>  	main_spi0: spi at 2100000 {
> @@ -206,6 +216,7 @@ main_spi0: spi at 2100000 {
>  		#size-cells = <0>;
>  		dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>;
>  		dma-names = "tx0", "rx0";
> +		status = "disabled";
>  	};
>  
>  	main_spi1: spi at 2110000 {
> @@ -218,6 +229,7 @@ main_spi1: spi at 2110000 {
>  		#size-cells = <0>;
>  		assigned-clocks = <&k3_clks 137 1>;
>  		assigned-clock-rates = <48000000>;
> +		status = "disabled";
>  	};
>  
>  	main_spi2: spi at 2120000 {
> @@ -228,6 +240,7 @@ main_spi2: spi at 2120000 {
>  		power-domains = <&k3_pds 139 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	main_spi3: spi at 2130000 {
> @@ -238,6 +251,7 @@ main_spi3: spi at 2130000 {
>  		power-domains = <&k3_pds 140 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	main_spi4: spi at 2140000 {
> @@ -248,6 +262,7 @@ main_spi4: spi at 2140000 {
>  		power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	sdhci0: mmc at 4f80000 {
> @@ -272,6 +287,7 @@ sdhci0: mmc at 4f80000 {
>  		ti,otap-del-sel-hs400 = <0x0>;
>  		ti,trm-icp = <0x8>;
>  		dma-coherent;
> +		status = "disabled";
>  	};
>  
>  	sdhci1: mmc at 4fa0000 {
> @@ -295,6 +311,7 @@ sdhci1: mmc at 4fa0000 {
>  		ti,otap-del-sel = <0x2>;
>  		ti,trm-icp = <0x8>;
>  		dma-coherent;
> +		status = "disabled";
>  	};
>  
>  	scm_conf: scm-conf at 100000 {
> @@ -361,6 +378,7 @@ dwc3_0: dwc3 at 4000000 {
>  		assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
>  		assigned-clock-parents = <&k3_clks 151 4>,	/*
> set REF_CLK to 20MHz i.e. PER0_PLL/48 */
>  					 <&k3_clks 151 9>;	/*
> set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
> +		status = "disabled";
>  
>  		usb0: usb at 10000 {
>  			compatible = "snps,dwc3";
> @@ -386,6 +404,7 @@ usb0_phy: phy at 4100000 {
>  		clocks = <&k3_clks 151 0>, <&k3_clks 151 1>;
>  		clock-names = "wkupclk", "refclk";
>  		#phy-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	dwc3_1: dwc3 at 4020000 {
> @@ -400,6 +419,7 @@ dwc3_1: dwc3 at 4020000 {
>  		clocks = <&k3_clks 152 2>;
>  		assigned-clocks = <&k3_clks 152 2>;
>  		assigned-clock-parents = <&k3_clks 152 4>;	/*
> set REF_CLK to 20MHz i.e. PER0_PLL/48 */
> +		status = "disabled";
>  
>  		usb1: usb at 10000 {
>  			compatible = "snps,dwc3";
> @@ -424,6 +444,7 @@ usb1_phy: phy at 4110000 {
>  		clocks = <&k3_clks 152 0>, <&k3_clks 152 1>;
>  		clock-names = "wkupclk", "refclk";
>  		#phy-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	intr_main_gpio: interrupt-controller at a00000 {
> @@ -497,6 +518,7 @@ mailbox0_cluster0: mailbox at 31f80000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster1: mailbox at 31f81000 {
> @@ -506,6 +528,7 @@ mailbox0_cluster1: mailbox at 31f81000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster2: mailbox at 31f82000 {
> @@ -515,6 +538,7 @@ mailbox0_cluster2: mailbox at 31f82000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster3: mailbox at 31f83000 {
> @@ -524,6 +548,7 @@ mailbox0_cluster3: mailbox at 31f83000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster4: mailbox at 31f84000 {
> @@ -533,6 +558,7 @@ mailbox0_cluster4: mailbox at 31f84000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster5: mailbox at 31f85000 {
> @@ -542,6 +568,7 @@ mailbox0_cluster5: mailbox at 31f85000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster6: mailbox at 31f86000 {
> @@ -551,6 +578,7 @@ mailbox0_cluster6: mailbox at 31f86000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster7: mailbox at 31f87000 {
> @@ -560,6 +588,7 @@ mailbox0_cluster7: mailbox at 31f87000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster8: mailbox at 31f88000 {
> @@ -569,6 +598,7 @@ mailbox0_cluster8: mailbox at 31f88000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster9: mailbox at 31f89000 {
> @@ -578,6 +608,7 @@ mailbox0_cluster9: mailbox at 31f89000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster10: mailbox at 31f8a000 {
> @@ -587,6 +618,7 @@ mailbox0_cluster10: mailbox at 31f8a000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		mailbox0_cluster11: mailbox at 31f8b000 {
> @@ -596,6 +628,7 @@ mailbox0_cluster11: mailbox at 31f8b000 {
>  			ti,mbox-num-users = <4>;
>  			ti,mbox-num-fifos = <16>;
>  			interrupt-parent = <&intr_main_navss>;
> +			status = "disabled";
>  		};
>  
>  		ringacc: ringacc at 3c000000 {
> @@ -703,6 +736,7 @@ pcie0_rc: pcie at 5500000 {
>  		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
>  		msi-map = <0x0 &gic_its 0x0 0x10000>;
>  		device_type = "pci";
> +		status = "disabled";
>  	};
>  
>  	pcie0_ep: pcie-ep at 5500000 {
> @@ -716,6 +750,7 @@ pcie0_ep: pcie-ep at 5500000 {
>  		max-link-speed = <2>;
>  		dma-coherent;
>  		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
> +		status = "disabled";
>  	};
>  
>  	pcie1_rc: pcie at 5600000 {
> @@ -736,6 +771,7 @@ pcie1_rc: pcie at 5600000 {
>  		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
>  		msi-map = <0x0 &gic_its 0x10000 0x10000>;
>  		device_type = "pci";
> +		status = "disabled";
>  	};
>  
>  	pcie1_ep: pcie-ep at 5600000 {
> @@ -749,6 +785,7 @@ pcie1_ep: pcie-ep at 5600000 {
>  		max-link-speed = <2>;
>  		dma-coherent;
>  		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
> +		status = "disabled";
>  	};
>  
>  	mcasp0: mcasp at 2b00000 {
> @@ -766,6 +803,7 @@ mcasp0: mcasp at 2b00000 {
>  		clocks = <&k3_clks 104 0>;
>  		clock-names = "fck";
>  		power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	mcasp1: mcasp at 2b10000 {
> @@ -783,6 +821,7 @@ mcasp1: mcasp at 2b10000 {
>  		clocks = <&k3_clks 105 0>;
>  		clock-names = "fck";
>  		power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	mcasp2: mcasp at 2b20000 {
> @@ -800,6 +839,7 @@ mcasp2: mcasp at 2b20000 {
>  		clocks = <&k3_clks 106 0>;
>  		clock-names = "fck";
>  		power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	cal: cal at 6f03000 {
> @@ -813,6 +853,7 @@ cal: cal at 6f03000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 2 0>;
>  		power-domains = <&k3_pds 2 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  
>  		ports {
>  			#address-cells = <1>;
> @@ -857,6 +898,8 @@ dss: dss at 4a00000 {
>  
>  		dma-coherent;
>  
> +		status = "disabled";
> +
>  		dss_ports: ports {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
> @@ -870,6 +913,7 @@ ehrpwm0: pwm at 3000000 {
>  		power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 0>, <&k3_clks 40 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	ehrpwm1: pwm at 3010000 {
> @@ -879,6 +923,7 @@ ehrpwm1: pwm at 3010000 {
>  		power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 1>, <&k3_clks 41 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	ehrpwm2: pwm at 3020000 {
> @@ -888,6 +933,7 @@ ehrpwm2: pwm at 3020000 {
>  		power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 2>, <&k3_clks 42 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	ehrpwm3: pwm at 3030000 {
> @@ -897,6 +943,7 @@ ehrpwm3: pwm at 3030000 {
>  		power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 3>, <&k3_clks 43 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	ehrpwm4: pwm at 3040000 {
> @@ -906,6 +953,7 @@ ehrpwm4: pwm at 3040000 {
>  		power-domains = <&k3_pds 44 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 4>, <&k3_clks 44 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	ehrpwm5: pwm at 3050000 {
> @@ -915,6 +963,7 @@ ehrpwm5: pwm at 3050000 {
>  		power-domains = <&k3_pds 45 TI_SCI_PD_EXCLUSIVE>;
>  		clocks = <&ehrpwm_tbclk 5>, <&k3_clks 45 0>;
>  		clock-names = "tbclk", "fck";
> +		status = "disabled";
>  	};
>  
>  	icssg0: icssg at b000000 {
> @@ -1055,6 +1104,7 @@ icssg0_mdio: mdio at 32400 {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
>  			bus_freq = <1000000>;
> +			status = "disabled";
>  		};
>  	};
>  
> @@ -1196,6 +1246,7 @@ icssg1_mdio: mdio at 32400 {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
>  			bus_freq = <1000000>;
> +			status = "disabled";
>  		};
>  	};
>  
> @@ -1337,6 +1388,7 @@ icssg2_mdio: mdio at 32400 {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
>  			bus_freq = <1000000>;
> +			status = "disabled";
>  		};
>  	};
>  };
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> index 8d592bf41d6f..50f26e96276f 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> @@ -46,6 +46,7 @@ mcu_i2c0: i2c at 40b00000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 114 1>;
>  		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	mcu_spi0: spi at 40300000 {
> @@ -56,6 +57,7 @@ mcu_spi0: spi at 40300000 {
>  		power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	mcu_spi1: spi at 40310000 {
> @@ -66,6 +68,7 @@ mcu_spi1: spi at 40310000 {
>  		power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	mcu_spi2: spi at 40320000 {
> @@ -76,6 +79,7 @@ mcu_spi2: spi at 40320000 {
>  		power-domains = <&k3_pds 144 TI_SCI_PD_EXCLUSIVE>;
>  		#address-cells = <1>;
>  		#size-cells = <0>;
> +		status = "disabled";
>  	};
>  
>  	tscadc0: tscadc at 40200000 {
> @@ -89,6 +93,7 @@ tscadc0: tscadc at 40200000 {
>  		dmas = <&mcu_udmap 0x7100>,
>  			<&mcu_udmap 0x7101 >;
>  		dma-names = "fifo0", "fifo1";
> +		status = "disabled";
>  
>  		adc {
>  			#io-channel-cells = <1>;
> @@ -107,6 +112,7 @@ tscadc1: tscadc at 40210000 {
>  		dmas = <&mcu_udmap 0x7102>,
>  			<&mcu_udmap 0x7103>;
>  		dma-names = "fifo0", "fifo1";
> +		status = "disabled";
>  
>  		adc {
>  			#io-channel-cells = <1>;
> @@ -172,6 +178,7 @@ m_can0: mcan at 40528000 {
>  			     <GIC_SPI 545 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "int0", "int1";
>  		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
> +		status = "disabled";
>  	};
>  
>  	m_can1: mcan at 40568000 {
> @@ -187,6 +194,7 @@ m_can1: mcan at 40568000 {
>  			     <GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>;
>  		interrupt-names = "int0", "int1";
>  		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
> +		status = "disabled";
>  	};
>  
>  	fss: fss at 47000000 {
> @@ -252,6 +260,8 @@ mcu_cpsw: ethernet at 46000000 {
>  			    "tx4", "tx5", "tx6", "tx7",
>  			    "rx";
>  
> +		status = "disabled";
> +
>  		ethernet-ports {
>  			#address-cells = <1>;
>  			#size-cells = <0>;
> diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> index 9c69d0917f69..8f0c505a16ed 100644
> --- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> @@ -54,6 +54,7 @@ wkup_uart0: serial at 42300000 {
>  		clock-frequency = <48000000>;
>  		current-speed = <115200>;
>  		power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	wkup_i2c0: i2c at 42120000 {
> @@ -65,6 +66,7 @@ wkup_i2c0: i2c at 42120000 {
>  		clock-names = "fck";
>  		clocks = <&k3_clks 115 1>;
>  		power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>;
> +		status = "disabled";
>  	};
>  
>  	intr_wkup_gpio: interrupt-controller at 42200000 {
> diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-
> common.dtsi b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-
> common.dtsi
> index 4a9bf7d7c07d..29f539cc2392 100644
> --- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
> @@ -29,11 +29,6 @@ cpu-map {
>  	/delete-node/ l2-cache1;
>  };
>  
> -/* eMMC */
> -&sdhci0 {
> -	status = "disabled";
> -};
> -
>  &main_pmx0 {
>  	main_uart0_pins_default: main-uart0-pins-default {
>  		pinctrl-single,pins = <
> @@ -52,6 +47,7 @@ AM65X_IOPAD(0x0194, PIN_INPUT,  1)  /* (E24)
> UART0_RIN */
>  &main_uart0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_uart0_pins_default>;
> +	status = "okay";
>  };
>  
>  &mcu_r5fss0 {
> diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> index 9043f91c9bec..821ee7f2eff0 100644
> --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> @@ -275,12 +275,14 @@ &main_uart0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_uart0_pins_default>;
>  	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
> +	status = "okay";
>  };
>  
>  &wkup_i2c0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&wkup_i2c0_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  
>  	pca9554: gpio at 39 {
>  		compatible = "nxp,pca9554";
> @@ -300,6 +302,7 @@ &main_i2c0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c0_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  
>  	pca9555: gpio at 21 {
>  		compatible = "nxp,pca9555";
> @@ -313,17 +316,20 @@ &main_i2c1 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c1_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  };
>  
>  &main_i2c2 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&main_i2c2_pins_default>;
>  	clock-frequency = <400000>;
> +	status = "okay";
>  };
>  
>  &ecap0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&ecap0_pins_default>;
> +	status = "okay";
>  };
>  
>  &main_spi0 {
> @@ -332,6 +338,7 @@ &main_spi0 {
>  	#address-cells = <1>;
>  	#size-cells= <0>;
>  	ti,pindir-d0-out-d1-in;
> +	status = "okay";
>  
>  	flash at 0{
>  		compatible = "jedec,spi-nor";
> @@ -351,6 +358,7 @@ &sdhci0 {
>  	non-removable;
>  	ti,driver-strength-ohm = <50>;
>  	disable-wp;
> +	status = "okay";
>  };
>  
>  /*
> @@ -364,6 +372,11 @@ &sdhci1 {
>  	pinctrl-0 = <&main_mmc1_pins_default>;
>  	ti,driver-strength-ohm = <50>;
>  	disable-wp;
> +	status = "okay";
> +};
> +
> +&dwc3_1 {
> +	status = "okay";
>  };
>  
>  &usb1 {
> @@ -372,60 +385,29 @@ &usb1 {
>  	dr_mode = "otg";
>  };
>  
> -&dwc3_0 {
> -	status = "disabled";
> -};
> -
> -&usb0_phy {
> -	status = "disabled";
> +&usb1_phy {
> +	status = "okay";
>  };
>  
>  &tscadc0 {
> +	status = "okay";
> +
>  	adc {
>  		ti,adc-channels = <0 1 2 3 4 5 6 7>;
>  	};
>  };
>  
>  &tscadc1 {
> +	status = "okay";
> +
>  	adc {
>  		ti,adc-channels = <0 1 2 3 4 5 6 7>;
>  	};
>  };
>  
> -&serdes0 {
> -	status = "disabled";
> -};
> -
> -&serdes1 {
> -	status = "disabled";
> -};
> -
> -&pcie0_rc {
> -	status = "disabled";
> -};
> -
> -&pcie0_ep {
> -	status = "disabled";
> -};
> -
> -&pcie1_rc {
> -	status = "disabled";
> -};
> -
> -&pcie1_ep {
> -	status = "disabled";
> -};
> -
> -&m_can0 {
> -	status = "disabled";
> -};
> -
> -&m_can1 {
> -	status = "disabled";
> -};
> -
>  &mailbox0_cluster0 {
>  	interrupts = <436>;
> +	status = "okay";
>  
>  	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
>  		ti,mbox-tx = <1 0 0>;
> @@ -435,6 +417,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
>  
>  &mailbox0_cluster1 {
>  	interrupts = <432>;
> +	status = "okay";
>  
>  	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
>  		ti,mbox-tx = <1 0 0>;
> @@ -442,46 +425,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
>  	};
>  };
>  
> -&mailbox0_cluster2 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster3 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster4 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster5 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster6 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster7 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster8 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster9 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster10 {
> -	status = "disabled";
> -};
> -
> -&mailbox0_cluster11 {
> -	status = "disabled";
> -};
> -
>  &mcu_r5fss0_core0 {
>  	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
>  			<&mcu_r5fss0_core0_memory_region>;
> @@ -497,6 +440,7 @@ &mcu_r5fss0_core1 {
>  &ospi0 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> +	status = "okay";
>  
>  	flash at 0{
>  		compatible = "jedec,spi-nor";
> @@ -517,6 +461,7 @@ flash at 0{
>  &mcu_cpsw {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
> +	status = "okay";
>  };
>  
>  &davinci_mdio {
> @@ -531,31 +476,3 @@ &cpsw_port1 {
>  	phy-mode = "rgmii-rxid";
>  	phy-handle = <&phy0>;
>  };
> -
> -&mcasp0 {
> -	status = "disabled";
> -};
> -
> -&mcasp1 {
> -	status = "disabled";
> -};
> -
> -&mcasp2 {
> -	status = "disabled";
> -};
> -
> -&dss {
> -	status = "disabled";
> -};
> -
> -&icssg0_mdio {
> -	status = "disabled";
> -};
> -
> -&icssg1_mdio {
> -	status = "disabled";
> -};
> -
> -&icssg2_mdio {
> -	status = "disabled";
> -};
> diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-
> common.dtsi b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-
> common.dtsi
> index d25e8b26187f..731224ec5c36 100644
> --- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
> +++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
> @@ -49,8 +49,5 @@ &sdhci0 {
>  	non-removable;
>  	ti,driver-strength-ohm = <50>;
>  	disable-wp;
> -};
> -
> -&main_uart0 {
> -	status = "disabled";
> +	status = "okay";
>  };



From jneuhauser at dh-electronics.com  Thu Jan 20 04:07:34 2022
From: jneuhauser at dh-electronics.com (Johann Neuhauser)
Date: Thu, 20 Jan 2022 12:07:34 +0000
Subject: [PATCH 3/5] ARM: dts: stm32: Add alternate pinmux for ethernet0
 pins
In-Reply-To: <20220118202958.1840431-3-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-3-marex@denx.de>
Message-ID: <575f3b5e888843728f6f4b09c60cc0c1@dh-electronics.com>

> From: Marek Vasut [mailto:marex at denx.de]
> Sent: Tuesday, January 18, 2022 9:30 PM
> 
> Add another mux option for ethernet0 pins, this is used on DHCOM when
> the ethernet PHY 50 MHz clock is generated by the MCO2 on PG2 pin and
> then fed back via PA1 pin.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>  arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 34 ++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> index 3b65130affec8..2cd2ac9beaf20 100644
> --- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> +++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
> @@ -338,6 +338,40 @@ pins1 {
>                 };
>         };
> 
> +       ethernet0_rmii_pins_b: rmii-1 {
> +               pins1 {
> +                       pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH1_RMII_TXD0 */
> +                                <STM32_PINMUX('G', 14, AF11)>, /* ETH1_RMII_TXD1 */
> +                                <STM32_PINMUX('B', 11, AF11)>, /* ETH1_RMII_TX_EN */
> +                                <STM32_PINMUX('A', 1, AF11)>,  /* ETH1_RMII_REF_CLK */
> +                                <STM32_PINMUX('A', 2, AF11)>,  /* ETH1_MDIO */
> +                                <STM32_PINMUX('C', 1, AF11)>;  /* ETH1_MDC */
> +                       bias-disable;
> +                       drive-push-pull;
> +                       slew-rate = <2>;
> +               };
> +               pins2 {
> +                       pinmux = <STM32_PINMUX('C', 4, AF11)>,  /* ETH1_RMII_RXD0 */
> +                                <STM32_PINMUX('C', 5, AF11)>,  /* ETH1_RMII_RXD1 */
> +                                <STM32_PINMUX('A', 7, AF11)>;  /* ETH1_RMII_CRS_DV */
> +                       bias-disable;
> +               };
> +       };
> +
> +       ethernet0_rmii_sleep_pins_b: rmii-sleep-1 {
> +               pins1 {
> +                       pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* ETH1_RMII_TXD0 */
> +                                <STM32_PINMUX('G', 14, ANALOG)>, /* ETH1_RMII_TXD1 */
> +                                <STM32_PINMUX('B', 11, ANALOG)>, /* ETH1_RMII_TX_EN */
> +                                <STM32_PINMUX('A', 2, ANALOG)>,  /* ETH1_MDIO */
> +                                <STM32_PINMUX('C', 1, ANALOG)>,  /* ETH1_MDC */
> +                                <STM32_PINMUX('C', 4, ANALOG)>,  /* ETH1_RMII_RXD0 */
> +                                <STM32_PINMUX('C', 5, ANALOG)>,  /* ETH1_RMII_RXD1 */
> +                                <STM32_PINMUX('A', 1, ANALOG)>,  /* ETH1_RMII_REF_CLK */
> +                                <STM32_PINMUX('A', 7, ANALOG)>;  /* ETH1_RMII_CRS_DV */
> +               };
> +       };
> +
>         fmc_pins_a: fmc-0 {
>                 pins1 {
>                         pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
> --
> 2.34.1
Tested-by: Johann Neuhauser <jneuhauser at dh-electronics.com>

From matthias.schiffer at ew.tq-group.com  Thu Jan 20 04:41:52 2022
From: matthias.schiffer at ew.tq-group.com (Matthias Schiffer)
Date: Thu, 20 Jan 2022 13:41:52 +0100
Subject: [PATCH 1/2] arm64: dts: ti: k3-am65: disable optional
 peripherals by default
In-Reply-To: <2982ff768a71247dfe0acb0e7af97a36041193bd.camel@ew.tq-group.com>
References: <5beef188724ef42b0c2147ca9bf6e6ca25c75dec.1641900122.git.matthias.schiffer@ew.tq-group.com>
 <2982ff768a71247dfe0acb0e7af97a36041193bd.camel@ew.tq-group.com>
Message-ID: <0a362c8ed3d3552befa9cf57ab778365d8cd0734.camel@ew.tq-group.com>

On Thu, 2022-01-20 at 13:32 +0100, Matthias Schiffer wrote:
> On Tue, 2022-01-11 at 12:25 +0100, Matthias Schiffer wrote:
> > All peripharals that require pinmuxing or other configuration to
> > work
> > should be disabled by default. Dependent DTS are adjusted
> > accordingly.
> > 
> > The following nodes are now "disabled" according to dtx_diff and
> > were
> > not
> > overridden to "okay", as they define no pinctrl:
> > 
> > k3-am654-base-board:
> > - mcu_i2c0
> > - mcu_spi0..2
> > - cal
> > - main_i2c3
> > - ehrpwm0..5
> > - main_uart1..2
> > - main_spi1..4
> > 
> > k3-am65-iot2050*:
> > - mci_spi1..2
> > - cal
> > - ehrpwm0..5
> > - main_spi0..4
> 
> I noticed that I didn't disable mcu_uart0 in k3-am65-mcu.dtsi, which
> would make sense for consistency. It is currently not disabled in
> k3-am654-base-board.dts either, but it doesn't have a pinmuxing
> defined. Does it work with the default muxing, or should it rather be
> disabled for that board?
> 

Ah, I found a mcu_uart0 pinmuxing in ti-u-boot's k3-am654-r5-base-
board.dts. So I assume that the muxing is installed by the bootloader,
and the kernel expects that this muxing is already in place, so that
mcu_uart0 can work? Is there a reason not to make the pinmuxing
explicit by copying it to the kernel's k3-am654-base-board.dts?



> I can send a v2 if this patch is acceptable at all (which would be
> desirable for the addition of our TQMa65xx SoM and MBa65xx carrier
> board, as it allows for a similar reduction of DTS lines as the one
> seen in the diffstat below for k3-am65-iot2050-common.dtsi and
> k3-am654-base-board.dts).




> 
> Kind regards,
> Matthias
> 
> 
> > Signed-off-by: Matthias Schiffer <matthias.schiffer at ew.tq-group.com
> > >
> > ---
> > 
> > These changes were not tested on hardware, and I'm not familiar
> > with
> > any of these boards, so it would be great if someone could check
> > whether the effective changes listed above are correct, or if some
> > of
> > these devices (in particular I2C, UART and PWM) are actually
> > connected
> > and work with the default pinmuxing.
> > 
> > There were also a few devices where I was unsure whether they are
> > optional
> > or not - for example one of the io2050 disables all the txpru
> > nodes,
> > so
> > maybe it would make sense to disable these in the SoC DTSI as well?
> > I
> > left
> > these nodes unchanged for now.
> > 
> >  .../dts/ti/k3-am65-iot2050-common-pg1.dtsi    |   4 -
> >  .../dts/ti/k3-am65-iot2050-common-pg2.dtsi    |   7 +
> >  .../boot/dts/ti/k3-am65-iot2050-common.dtsi   | 132 +++++---------
> > --
> > --
> >  arch/arm64/boot/dts/ti/k3-am65-main.dtsi      |  52 +++++++
> >  arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi       |  10 ++
> >  arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi    |   2 +
> >  .../ti/k3-am6528-iot2050-basic-common.dtsi    |   6 +-
> >  .../arm64/boot/dts/ti/k3-am654-base-board.dts | 129 +++-----------
> > --
> > -
> >  .../ti/k3-am6548-iot2050-advanced-common.dtsi |   5 +-
> >  9 files changed, 134 insertions(+), 213 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> > index 51f902fa35a7..746f0e89a305 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg1.dtsi
> > @@ -13,10 +13,6 @@ &dss {
> >  	assigned-clock-parents = <&k3_clks 67 5>;
> >  };
> >  
> > -&serdes0 {
> > -	status = "disabled";
> > -};
> > -
> >  &sdhci1 {
> >  	no-1-8-v;
> >  };
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> > index e73458ca6900..b769fe6fc072 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common-pg2.dtsi
> > @@ -35,6 +35,7 @@ &dss {
> >  &serdes0 {
> >  	assigned-clocks = <&k3_clks 153 4>, <&serdes0
> > AM654_SERDES_CMU_REFCLK>;
> >  	assigned-clock-parents = <&k3_clks 153 7>, <&k3_clks 153 4>;
> > +	status = "okay";
> >  };
> >  
> >  &dwc3_0 {
> > @@ -42,10 +43,16 @@ &dwc3_0 {
> >  				 <&k3_clks 151 8>;  /* set
> > PIPE3_TXB_CLK to WIZ8B2M4VSB */
> >  	phys = <&serdes0 PHY_TYPE_USB3 0>;
> >  	phy-names = "usb3-phy";
> > +	status = "okay";
> >  };
> >  
> >  &usb0 {
> >  	maximum-speed = "super-speed";
> >  	snps,dis-u1-entry-quirk;
> >  	snps,dis-u2-entry-quirk;
> > +	status = "okay";
> > +};
> > +
> > +&usb0_phy {
> > +	status = "okay";
> >  };
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> > index 3079eaee01c0..873c123c611e 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi
> > @@ -362,15 +362,13 @@ &wkup_uart0 {
> >  &main_uart1 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_uart1_pins_default>;
> > -};
> > -
> > -&main_uart2 {
> > -	status = "disabled";
> > +	status = "okay";
> >  };
> >  
> >  &mcu_uart0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&arduino_uart_pins_default>;
> > +	status = "okay";
> >  };
> >  
> >  &main_gpio0 {
> > @@ -416,12 +414,14 @@ &wkup_i2c0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&wkup_i2c0_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  };
> >  
> >  &mcu_i2c0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&mcu_i2c0_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  
> >  	psu: regulator at 60 {
> >  		compatible = "ti,tps62363";
> > @@ -481,6 +481,7 @@ &main_i2c0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c0_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  
> >  	rtc: rtc8564 at 51 {
> >  		compatible = "nxp,pcf8563";
> > @@ -498,12 +499,14 @@ &main_i2c1 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c1_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  };
> >  
> >  &main_i2c2 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c2_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  };
> >  
> >  &main_i2c3 {
> > @@ -514,6 +517,8 @@ &main_i2c3 {
> >  	#address-cells = <1>;
> >  	#size-cells = <0>;
> >  
> > +	status = "okay";
> > +
> >  	edp-bridge at f {
> >  		compatible = "toshiba,tc358767";
> >  		reg = <0x0f>;
> > @@ -541,13 +546,10 @@ bridge_in: endpoint {
> >  	};
> >  };
> >  
> > -&mcu_cpsw {
> > -	status = "disabled";
> > -};
> > -
> >  &ecap0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&ecap0_pins_default>;
> > +	status = "okay";
> >  };
> >  
> >  &sdhci1 {
> > @@ -555,20 +557,38 @@ &sdhci1 {
> >  	pinctrl-0 = <&main_mmc1_pins_default>;
> >  	ti,driver-strength-ohm = <50>;
> >  	disable-wp;
> > +	status = "okay";
> > +};
> > +
> > +&dwc3_0 {
> > +	status = "okay";
> >  };
> >  
> > +
> >  &usb0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&usb0_pins_default>;
> >  	dr_mode = "host";
> >  };
> >  
> > +&usb0_phy {
> > +	status = "okay";
> > +};
> > +
> > +&dwc3_1 {
> > +	status = "okay";
> > +};
> > +
> >  &usb1 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&usb1_pins_default>;
> >  	dr_mode = "host";
> >  };
> >  
> > +&usb1_phy {
> > +	status = "okay";
> > +};
> > +
> >  &mcu_spi0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&mcu_spi0_pins_default>;
> > @@ -576,13 +596,12 @@ &mcu_spi0 {
> >  	#address-cells = <1>;
> >  	#size-cells= <0>;
> >  	ti,pindir-d0-out-d1-in;
> > -};
> > -
> > -&tscadc0 {
> > -	status = "disabled";
> > +	status = "okay";
> >  };
> >  
> >  &tscadc1 {
> > +	status = "okay";
> > +
> >  	adc {
> >  		ti,adc-channels = <0 1 2 3 4 5>;
> >  	};
> > @@ -591,6 +610,7 @@ adc {
> >  &ospi0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> > +	status = "okay";
> >  
> >  	flash at 0 {
> >  		compatible = "jedec,spi-nor";
> > @@ -611,6 +631,7 @@ flash at 0 {
> >  &dss {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&dss_vout1_pins_default>;
> > +	status = "okay";
> >  
> >  	assigned-clocks = <&k3_clks 67 2>;
> >  	assigned-clock-parents = <&k3_clks 67 5>;
> > @@ -628,17 +649,14 @@ dpi_out: endpoint {
> >  	};
> >  };
> >  
> > -&pcie0_rc {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie0_ep {
> > -	status = "disabled";
> > +&serdes1 {
> > +	status = "okay";
> >  };
> >  
> >  &pcie1_rc {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&minipcie_pins_default>;
> > +	status = "okay";
> >  
> >  	num-lanes = <1>;
> >  	phys = <&serdes1 PHY_TYPE_PCIE 0>;
> > @@ -646,20 +664,9 @@ &pcie1_rc {
> >  	reset-gpios = <&wkup_gpio0 27 GPIO_ACTIVE_HIGH>;
> >  };
> >  
> > -&m_can0 {
> > -	status = "disabled";
> > -};
> > -
> > -&m_can1 {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie1_ep {
> > -	status = "disabled";
> > -};
> > -
> >  &mailbox0_cluster0 {
> >  	interrupts = <436>;
> > +	status = "okay";
> >  
> >  	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
> >  		ti,mbox-tx = <1 0 0>;
> > @@ -669,6 +676,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
> >  
> >  &mailbox0_cluster1 {
> >  	interrupts = <432>;
> > +	status = "okay";
> >  
> >  	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
> >  		ti,mbox-tx = <1 0 0>;
> > @@ -676,46 +684,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
> >  	};
> >  };
> >  
> > -&mailbox0_cluster2 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster3 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster4 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster5 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster6 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster7 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster8 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster9 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster10 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster11 {
> > -	status = "disabled";
> > -};
> > -
> >  &mcu_r5fss0_core0 {
> >  	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
> >  			<&mcu_r5fss0_core0_memory_region>;
> > @@ -727,27 +695,3 @@ &mcu_r5fss0_core1 {
> >  			<&mcu_r5fss0_core1_memory_region>;
> >  	mboxes = <&mailbox0_cluster1 &mbox_mcu_r5fss0_core1>;
> >  };
> > -
> > -&icssg0_mdio {
> > -	status = "disabled";
> > -};
> > -
> > -&icssg1_mdio {
> > -	status = "disabled";
> > -};
> > -
> > -&icssg2_mdio {
> > -	status = "disabled";
> > -};
> > -
> > -&mcasp0 {
> > -	status = "disabled";
> > -};
> > -
> > -&mcasp1 {
> > -	status = "disabled";
> > -};
> > -
> > -&mcasp2 {
> > -	status = "disabled";
> > -};
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> > index ce8bb4a61011..5aa425d1ba80 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
> > @@ -64,6 +64,7 @@ serdes0: serdes at 900000 {
> >  		ti,serdes-clk = <&serdes0_clk>;
> >  		#clock-cells = <1>;
> >  		mux-controls = <&serdes_mux 0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	serdes1: serdes at 910000 {
> > @@ -79,6 +80,7 @@ serdes1: serdes at 910000 {
> >  		ti,serdes-clk = <&serdes1_clk>;
> >  		#clock-cells = <1>;
> >  		mux-controls = <&serdes_mux 1>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_uart0: serial at 2800000 {
> > @@ -88,6 +90,7 @@ main_uart0: serial at 2800000 {
> >  		clock-frequency = <48000000>;
> >  		current-speed = <115200>;
> >  		power-domains = <&k3_pds 146 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_uart1: serial at 2810000 {
> > @@ -96,6 +99,7 @@ main_uart1: serial at 2810000 {
> >  		interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>;
> >  		clock-frequency = <48000000>;
> >  		power-domains = <&k3_pds 147 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_uart2: serial at 2820000 {
> > @@ -104,6 +108,7 @@ main_uart2: serial at 2820000 {
> >  		interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>;
> >  		clock-frequency = <48000000>;
> >  		power-domains = <&k3_pds 148 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	crypto: crypto at 4e00000 {
> > @@ -152,6 +157,7 @@ main_i2c0: i2c at 2000000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 110 1>;
> >  		power-domains = <&k3_pds 110 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_i2c1: i2c at 2010000 {
> > @@ -163,6 +169,7 @@ main_i2c1: i2c at 2010000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 111 1>;
> >  		power-domains = <&k3_pds 111 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_i2c2: i2c at 2020000 {
> > @@ -174,6 +181,7 @@ main_i2c2: i2c at 2020000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 112 1>;
> >  		power-domains = <&k3_pds 112 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_i2c3: i2c at 2030000 {
> > @@ -185,6 +193,7 @@ main_i2c3: i2c at 2030000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 113 1>;
> >  		power-domains = <&k3_pds 113 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	ecap0: pwm at 3100000 {
> > @@ -194,6 +203,7 @@ ecap0: pwm at 3100000 {
> >  		power-domains = <&k3_pds 39 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&k3_clks 39 0>;
> >  		clock-names = "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	main_spi0: spi at 2100000 {
> > @@ -206,6 +216,7 @@ main_spi0: spi at 2100000 {
> >  		#size-cells = <0>;
> >  		dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>;
> >  		dma-names = "tx0", "rx0";
> > +		status = "disabled";
> >  	};
> >  
> >  	main_spi1: spi at 2110000 {
> > @@ -218,6 +229,7 @@ main_spi1: spi at 2110000 {
> >  		#size-cells = <0>;
> >  		assigned-clocks = <&k3_clks 137 1>;
> >  		assigned-clock-rates = <48000000>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_spi2: spi at 2120000 {
> > @@ -228,6 +240,7 @@ main_spi2: spi at 2120000 {
> >  		power-domains = <&k3_pds 139 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_spi3: spi at 2130000 {
> > @@ -238,6 +251,7 @@ main_spi3: spi at 2130000 {
> >  		power-domains = <&k3_pds 140 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	main_spi4: spi at 2140000 {
> > @@ -248,6 +262,7 @@ main_spi4: spi at 2140000 {
> >  		power-domains = <&k3_pds 141 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	sdhci0: mmc at 4f80000 {
> > @@ -272,6 +287,7 @@ sdhci0: mmc at 4f80000 {
> >  		ti,otap-del-sel-hs400 = <0x0>;
> >  		ti,trm-icp = <0x8>;
> >  		dma-coherent;
> > +		status = "disabled";
> >  	};
> >  
> >  	sdhci1: mmc at 4fa0000 {
> > @@ -295,6 +311,7 @@ sdhci1: mmc at 4fa0000 {
> >  		ti,otap-del-sel = <0x2>;
> >  		ti,trm-icp = <0x8>;
> >  		dma-coherent;
> > +		status = "disabled";
> >  	};
> >  
> >  	scm_conf: scm-conf at 100000 {
> > @@ -361,6 +378,7 @@ dwc3_0: dwc3 at 4000000 {
> >  		assigned-clocks = <&k3_clks 151 2>, <&k3_clks 151 7>;
> >  		assigned-clock-parents = <&k3_clks 151 4>,	/*
> > set REF_CLK to 20MHz i.e. PER0_PLL/48 */
> >  					 <&k3_clks 151 9>;	/*
> > set PIPE3_TXB_CLK to CLK_12M_RC/256 (for HS only) */
> > +		status = "disabled";
> >  
> >  		usb0: usb at 10000 {
> >  			compatible = "snps,dwc3";
> > @@ -386,6 +404,7 @@ usb0_phy: phy at 4100000 {
> >  		clocks = <&k3_clks 151 0>, <&k3_clks 151 1>;
> >  		clock-names = "wkupclk", "refclk";
> >  		#phy-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	dwc3_1: dwc3 at 4020000 {
> > @@ -400,6 +419,7 @@ dwc3_1: dwc3 at 4020000 {
> >  		clocks = <&k3_clks 152 2>;
> >  		assigned-clocks = <&k3_clks 152 2>;
> >  		assigned-clock-parents = <&k3_clks 152 4>;	/*
> > set REF_CLK to 20MHz i.e. PER0_PLL/48 */
> > +		status = "disabled";
> >  
> >  		usb1: usb at 10000 {
> >  			compatible = "snps,dwc3";
> > @@ -424,6 +444,7 @@ usb1_phy: phy at 4110000 {
> >  		clocks = <&k3_clks 152 0>, <&k3_clks 152 1>;
> >  		clock-names = "wkupclk", "refclk";
> >  		#phy-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	intr_main_gpio: interrupt-controller at a00000 {
> > @@ -497,6 +518,7 @@ mailbox0_cluster0: mailbox at 31f80000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster1: mailbox at 31f81000 {
> > @@ -506,6 +528,7 @@ mailbox0_cluster1: mailbox at 31f81000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster2: mailbox at 31f82000 {
> > @@ -515,6 +538,7 @@ mailbox0_cluster2: mailbox at 31f82000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster3: mailbox at 31f83000 {
> > @@ -524,6 +548,7 @@ mailbox0_cluster3: mailbox at 31f83000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster4: mailbox at 31f84000 {
> > @@ -533,6 +558,7 @@ mailbox0_cluster4: mailbox at 31f84000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster5: mailbox at 31f85000 {
> > @@ -542,6 +568,7 @@ mailbox0_cluster5: mailbox at 31f85000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster6: mailbox at 31f86000 {
> > @@ -551,6 +578,7 @@ mailbox0_cluster6: mailbox at 31f86000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster7: mailbox at 31f87000 {
> > @@ -560,6 +588,7 @@ mailbox0_cluster7: mailbox at 31f87000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster8: mailbox at 31f88000 {
> > @@ -569,6 +598,7 @@ mailbox0_cluster8: mailbox at 31f88000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster9: mailbox at 31f89000 {
> > @@ -578,6 +608,7 @@ mailbox0_cluster9: mailbox at 31f89000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster10: mailbox at 31f8a000 {
> > @@ -587,6 +618,7 @@ mailbox0_cluster10: mailbox at 31f8a000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		mailbox0_cluster11: mailbox at 31f8b000 {
> > @@ -596,6 +628,7 @@ mailbox0_cluster11: mailbox at 31f8b000 {
> >  			ti,mbox-num-users = <4>;
> >  			ti,mbox-num-fifos = <16>;
> >  			interrupt-parent = <&intr_main_navss>;
> > +			status = "disabled";
> >  		};
> >  
> >  		ringacc: ringacc at 3c000000 {
> > @@ -703,6 +736,7 @@ pcie0_rc: pcie at 5500000 {
> >  		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
> >  		msi-map = <0x0 &gic_its 0x0 0x10000>;
> >  		device_type = "pci";
> > +		status = "disabled";
> >  	};
> >  
> >  	pcie0_ep: pcie-ep at 5500000 {
> > @@ -716,6 +750,7 @@ pcie0_ep: pcie-ep at 5500000 {
> >  		max-link-speed = <2>;
> >  		dma-coherent;
> >  		interrupts = <GIC_SPI 340 IRQ_TYPE_EDGE_RISING>;
> > +		status = "disabled";
> >  	};
> >  
> >  	pcie1_rc: pcie at 5600000 {
> > @@ -736,6 +771,7 @@ pcie1_rc: pcie at 5600000 {
> >  		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
> >  		msi-map = <0x0 &gic_its 0x10000 0x10000>;
> >  		device_type = "pci";
> > +		status = "disabled";
> >  	};
> >  
> >  	pcie1_ep: pcie-ep at 5600000 {
> > @@ -749,6 +785,7 @@ pcie1_ep: pcie-ep at 5600000 {
> >  		max-link-speed = <2>;
> >  		dma-coherent;
> >  		interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcasp0: mcasp at 2b00000 {
> > @@ -766,6 +803,7 @@ mcasp0: mcasp at 2b00000 {
> >  		clocks = <&k3_clks 104 0>;
> >  		clock-names = "fck";
> >  		power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcasp1: mcasp at 2b10000 {
> > @@ -783,6 +821,7 @@ mcasp1: mcasp at 2b10000 {
> >  		clocks = <&k3_clks 105 0>;
> >  		clock-names = "fck";
> >  		power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcasp2: mcasp at 2b20000 {
> > @@ -800,6 +839,7 @@ mcasp2: mcasp at 2b20000 {
> >  		clocks = <&k3_clks 106 0>;
> >  		clock-names = "fck";
> >  		power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	cal: cal at 6f03000 {
> > @@ -813,6 +853,7 @@ cal: cal at 6f03000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 2 0>;
> >  		power-domains = <&k3_pds 2 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  
> >  		ports {
> >  			#address-cells = <1>;
> > @@ -857,6 +898,8 @@ dss: dss at 4a00000 {
> >  
> >  		dma-coherent;
> >  
> > +		status = "disabled";
> > +
> >  		dss_ports: ports {
> >  			#address-cells = <1>;
> >  			#size-cells = <0>;
> > @@ -870,6 +913,7 @@ ehrpwm0: pwm at 3000000 {
> >  		power-domains = <&k3_pds 40 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 0>, <&k3_clks 40 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	ehrpwm1: pwm at 3010000 {
> > @@ -879,6 +923,7 @@ ehrpwm1: pwm at 3010000 {
> >  		power-domains = <&k3_pds 41 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 1>, <&k3_clks 41 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	ehrpwm2: pwm at 3020000 {
> > @@ -888,6 +933,7 @@ ehrpwm2: pwm at 3020000 {
> >  		power-domains = <&k3_pds 42 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 2>, <&k3_clks 42 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	ehrpwm3: pwm at 3030000 {
> > @@ -897,6 +943,7 @@ ehrpwm3: pwm at 3030000 {
> >  		power-domains = <&k3_pds 43 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 3>, <&k3_clks 43 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	ehrpwm4: pwm at 3040000 {
> > @@ -906,6 +953,7 @@ ehrpwm4: pwm at 3040000 {
> >  		power-domains = <&k3_pds 44 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 4>, <&k3_clks 44 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	ehrpwm5: pwm at 3050000 {
> > @@ -915,6 +963,7 @@ ehrpwm5: pwm at 3050000 {
> >  		power-domains = <&k3_pds 45 TI_SCI_PD_EXCLUSIVE>;
> >  		clocks = <&ehrpwm_tbclk 5>, <&k3_clks 45 0>;
> >  		clock-names = "tbclk", "fck";
> > +		status = "disabled";
> >  	};
> >  
> >  	icssg0: icssg at b000000 {
> > @@ -1055,6 +1104,7 @@ icssg0_mdio: mdio at 32400 {
> >  			#address-cells = <1>;
> >  			#size-cells = <0>;
> >  			bus_freq = <1000000>;
> > +			status = "disabled";
> >  		};
> >  	};
> >  
> > @@ -1196,6 +1246,7 @@ icssg1_mdio: mdio at 32400 {
> >  			#address-cells = <1>;
> >  			#size-cells = <0>;
> >  			bus_freq = <1000000>;
> > +			status = "disabled";
> >  		};
> >  	};
> >  
> > @@ -1337,6 +1388,7 @@ icssg2_mdio: mdio at 32400 {
> >  			#address-cells = <1>;
> >  			#size-cells = <0>;
> >  			bus_freq = <1000000>;
> > +			status = "disabled";
> >  		};
> >  	};
> >  };
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> > index 8d592bf41d6f..50f26e96276f 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
> > @@ -46,6 +46,7 @@ mcu_i2c0: i2c at 40b00000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 114 1>;
> >  		power-domains = <&k3_pds 114 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcu_spi0: spi at 40300000 {
> > @@ -56,6 +57,7 @@ mcu_spi0: spi at 40300000 {
> >  		power-domains = <&k3_pds 142 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcu_spi1: spi at 40310000 {
> > @@ -66,6 +68,7 @@ mcu_spi1: spi at 40310000 {
> >  		power-domains = <&k3_pds 143 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	mcu_spi2: spi at 40320000 {
> > @@ -76,6 +79,7 @@ mcu_spi2: spi at 40320000 {
> >  		power-domains = <&k3_pds 144 TI_SCI_PD_EXCLUSIVE>;
> >  		#address-cells = <1>;
> >  		#size-cells = <0>;
> > +		status = "disabled";
> >  	};
> >  
> >  	tscadc0: tscadc at 40200000 {
> > @@ -89,6 +93,7 @@ tscadc0: tscadc at 40200000 {
> >  		dmas = <&mcu_udmap 0x7100>,
> >  			<&mcu_udmap 0x7101 >;
> >  		dma-names = "fifo0", "fifo1";
> > +		status = "disabled";
> >  
> >  		adc {
> >  			#io-channel-cells = <1>;
> > @@ -107,6 +112,7 @@ tscadc1: tscadc at 40210000 {
> >  		dmas = <&mcu_udmap 0x7102>,
> >  			<&mcu_udmap 0x7103>;
> >  		dma-names = "fifo0", "fifo1";
> > +		status = "disabled";
> >  
> >  		adc {
> >  			#io-channel-cells = <1>;
> > @@ -172,6 +178,7 @@ m_can0: mcan at 40528000 {
> >  			     <GIC_SPI 545 IRQ_TYPE_LEVEL_HIGH>;
> >  		interrupt-names = "int0", "int1";
> >  		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
> > +		status = "disabled";
> >  	};
> >  
> >  	m_can1: mcan at 40568000 {
> > @@ -187,6 +194,7 @@ m_can1: mcan at 40568000 {
> >  			     <GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>;
> >  		interrupt-names = "int0", "int1";
> >  		bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>;
> > +		status = "disabled";
> >  	};
> >  
> >  	fss: fss at 47000000 {
> > @@ -252,6 +260,8 @@ mcu_cpsw: ethernet at 46000000 {
> >  			    "tx4", "tx5", "tx6", "tx7",
> >  			    "rx";
> >  
> > +		status = "disabled";
> > +
> >  		ethernet-ports {
> >  			#address-cells = <1>;
> >  			#size-cells = <0>;
> > diff --git a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> > b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> > index 9c69d0917f69..8f0c505a16ed 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi
> > @@ -54,6 +54,7 @@ wkup_uart0: serial at 42300000 {
> >  		clock-frequency = <48000000>;
> >  		current-speed = <115200>;
> >  		power-domains = <&k3_pds 150 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	wkup_i2c0: i2c at 42120000 {
> > @@ -65,6 +66,7 @@ wkup_i2c0: i2c at 42120000 {
> >  		clock-names = "fck";
> >  		clocks = <&k3_clks 115 1>;
> >  		power-domains = <&k3_pds 115 TI_SCI_PD_EXCLUSIVE>;
> > +		status = "disabled";
> >  	};
> >  
> >  	intr_wkup_gpio: interrupt-controller at 42200000 {
> > diff --git a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-
> > common.dtsi b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-
> > common.dtsi
> > index 4a9bf7d7c07d..29f539cc2392 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am6528-iot2050-basic-common.dtsi
> > @@ -29,11 +29,6 @@ cpu-map {
> >  	/delete-node/ l2-cache1;
> >  };
> >  
> > -/* eMMC */
> > -&sdhci0 {
> > -	status = "disabled";
> > -};
> > -
> >  &main_pmx0 {
> >  	main_uart0_pins_default: main-uart0-pins-default {
> >  		pinctrl-single,pins = <
> > @@ -52,6 +47,7 @@ AM65X_IOPAD(0x0194, PIN_INPUT,  1)  /* (E24)
> > UART0_RIN */
> >  &main_uart0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_uart0_pins_default>;
> > +	status = "okay";
> >  };
> >  
> >  &mcu_r5fss0 {
> > diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> > b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> > index 9043f91c9bec..821ee7f2eff0 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> > +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
> > @@ -275,12 +275,14 @@ &main_uart0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_uart0_pins_default>;
> >  	power-domains = <&k3_pds 146 TI_SCI_PD_SHARED>;
> > +	status = "okay";
> >  };
> >  
> >  &wkup_i2c0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&wkup_i2c0_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  
> >  	pca9554: gpio at 39 {
> >  		compatible = "nxp,pca9554";
> > @@ -300,6 +302,7 @@ &main_i2c0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c0_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  
> >  	pca9555: gpio at 21 {
> >  		compatible = "nxp,pca9555";
> > @@ -313,17 +316,20 @@ &main_i2c1 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c1_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  };
> >  
> >  &main_i2c2 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&main_i2c2_pins_default>;
> >  	clock-frequency = <400000>;
> > +	status = "okay";
> >  };
> >  
> >  &ecap0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&ecap0_pins_default>;
> > +	status = "okay";
> >  };
> >  
> >  &main_spi0 {
> > @@ -332,6 +338,7 @@ &main_spi0 {
> >  	#address-cells = <1>;
> >  	#size-cells= <0>;
> >  	ti,pindir-d0-out-d1-in;
> > +	status = "okay";
> >  
> >  	flash at 0{
> >  		compatible = "jedec,spi-nor";
> > @@ -351,6 +358,7 @@ &sdhci0 {
> >  	non-removable;
> >  	ti,driver-strength-ohm = <50>;
> >  	disable-wp;
> > +	status = "okay";
> >  };
> >  
> >  /*
> > @@ -364,6 +372,11 @@ &sdhci1 {
> >  	pinctrl-0 = <&main_mmc1_pins_default>;
> >  	ti,driver-strength-ohm = <50>;
> >  	disable-wp;
> > +	status = "okay";
> > +};
> > +
> > +&dwc3_1 {
> > +	status = "okay";
> >  };
> >  
> >  &usb1 {
> > @@ -372,60 +385,29 @@ &usb1 {
> >  	dr_mode = "otg";
> >  };
> >  
> > -&dwc3_0 {
> > -	status = "disabled";
> > -};
> > -
> > -&usb0_phy {
> > -	status = "disabled";
> > +&usb1_phy {
> > +	status = "okay";
> >  };
> >  
> >  &tscadc0 {
> > +	status = "okay";
> > +
> >  	adc {
> >  		ti,adc-channels = <0 1 2 3 4 5 6 7>;
> >  	};
> >  };
> >  
> >  &tscadc1 {
> > +	status = "okay";
> > +
> >  	adc {
> >  		ti,adc-channels = <0 1 2 3 4 5 6 7>;
> >  	};
> >  };
> >  
> > -&serdes0 {
> > -	status = "disabled";
> > -};
> > -
> > -&serdes1 {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie0_rc {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie0_ep {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie1_rc {
> > -	status = "disabled";
> > -};
> > -
> > -&pcie1_ep {
> > -	status = "disabled";
> > -};
> > -
> > -&m_can0 {
> > -	status = "disabled";
> > -};
> > -
> > -&m_can1 {
> > -	status = "disabled";
> > -};
> > -
> >  &mailbox0_cluster0 {
> >  	interrupts = <436>;
> > +	status = "okay";
> >  
> >  	mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
> >  		ti,mbox-tx = <1 0 0>;
> > @@ -435,6 +417,7 @@ mbox_mcu_r5fss0_core0: mbox-mcu-r5fss0-core0 {
> >  
> >  &mailbox0_cluster1 {
> >  	interrupts = <432>;
> > +	status = "okay";
> >  
> >  	mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
> >  		ti,mbox-tx = <1 0 0>;
> > @@ -442,46 +425,6 @@ mbox_mcu_r5fss0_core1: mbox-mcu-r5fss0-core1 {
> >  	};
> >  };
> >  
> > -&mailbox0_cluster2 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster3 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster4 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster5 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster6 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster7 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster8 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster9 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster10 {
> > -	status = "disabled";
> > -};
> > -
> > -&mailbox0_cluster11 {
> > -	status = "disabled";
> > -};
> > -
> >  &mcu_r5fss0_core0 {
> >  	memory-region = <&mcu_r5fss0_core0_dma_memory_region>,
> >  			<&mcu_r5fss0_core0_memory_region>;
> > @@ -497,6 +440,7 @@ &mcu_r5fss0_core1 {
> >  &ospi0 {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
> > +	status = "okay";
> >  
> >  	flash at 0{
> >  		compatible = "jedec,spi-nor";
> > @@ -517,6 +461,7 @@ flash at 0{
> >  &mcu_cpsw {
> >  	pinctrl-names = "default";
> >  	pinctrl-0 = <&mcu_cpsw_pins_default &mcu_mdio_pins_default>;
> > +	status = "okay";
> >  };
> >  
> >  &davinci_mdio {
> > @@ -531,31 +476,3 @@ &cpsw_port1 {
> >  	phy-mode = "rgmii-rxid";
> >  	phy-handle = <&phy0>;
> >  };
> > -
> > -&mcasp0 {
> > -	status = "disabled";
> > -};
> > -
> > -&mcasp1 {
> > -	status = "disabled";
> > -};
> > -
> > -&mcasp2 {
> > -	status = "disabled";
> > -};
> > -
> > -&dss {
> > -	status = "disabled";
> > -};
> > -
> > -&icssg0_mdio {
> > -	status = "disabled";
> > -};
> > -
> > -&icssg1_mdio {
> > -	status = "disabled";
> > -};
> > -
> > -&icssg2_mdio {
> > -	status = "disabled";
> > -};
> > diff --git a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-
> > common.dtsi b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-
> > common.dtsi
> > index d25e8b26187f..731224ec5c36 100644
> > --- a/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
> > +++ b/arch/arm64/boot/dts/ti/k3-am6548-iot2050-advanced-common.dtsi
> > @@ -49,8 +49,5 @@ &sdhci0 {
> >  	non-removable;
> >  	ti,driver-strength-ohm = <50>;
> >  	disable-wp;
> > -};
> > -
> > -&main_uart0 {
> > -	status = "disabled";
> > +	status = "okay";
> >  };



From quentin.schulz at theobroma-systems.com  Thu Jan 20 04:51:56 2022
From: quentin.schulz at theobroma-systems.com (quentin.schulz at theobroma-systems.com)
Date: Thu, 20 Jan 2022 13:51:56 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma-haikou USB OTG mode
Message-ID: <20220120125156.16217-1-quentin.schulz@theobroma-systems.com>

From: Quentin Schulz <quentin.schulz at theobroma-systems.com>

The micro USB3.0 port available on the Haikou evaluation kit for Puma
RK3399-Q7 SoM supports dual-role model (aka drd or OTG) but its support
was broken until now because of missing logic around the ID pin.

This adds proper support for USB OTG on Puma Haikou by "connecting" the
GPIO used for USB ID to the USB3 controller device.

Cc: Quentin Schulz <foss+kernel at 0leil.net>
Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
---
 .../arm64/boot/dts/rockchip/rk3399-puma-haikou.dts |  1 +
 arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi      | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
index 292bb7e80cf3..2564ef28d256 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma-haikou.dts
@@ -231,6 +231,7 @@ &usbdrd3_0 {
 };
 
 &usbdrd_dwc3_0 {
+	extcon = <&extcon_usb3>;
 	dr_mode = "otg";
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
index fb67db4619ea..c9a563ae3cfd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -32,6 +32,13 @@ clkin_gmac: external-gmac-clock {
 		#clock-cells = <0>;
 	};
 
+	extcon_usb3: extcon-usb3 {
+		compatible = "linux,extcon-usb-gpio";
+		id-gpio = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb3_id>;
+	};
+
 	vcc1v2_phy: vcc1v2-phy {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc1v2_phy";
@@ -422,6 +429,13 @@ vcc5v0_host_en: vcc5v0-host-en {
 			  <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
+
+	usb3 {
+		usb3_id: usb3-id {
+			rockchip,pins =
+			  <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
 };
 
 &sdhci {
-- 
2.34.1



From David.Laight at ACULAB.COM  Thu Jan 20 04:53:11 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Thu, 20 Jan 2022 12:53:11 +0000
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>
References: <20220120073911.99857-8-guoren@kernel.org>
 <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>
Message-ID: <f16cf10425a14c2e8183d5c90667ce72@AcuMS.aculab.com>

> > Limit 32-bit compatible process in 0-2GB virtual address range
> > (which is enough for real scenarios), because it could avoid
> > address sign extend problem when 32-bit enter 64-bit and ease
> > software design.

Eh?
I thought nearly all the other 32bit unix ports (of any flavour)
put the user-kernel boundary at 3GB.
(Apart from some very old sparc ones that use 3.5GB.)

2GB is used by Windows.

I think the x86-64 32bit compat code even puts the boundary at 4GB.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From arnd at arndb.de  Thu Jan 20 03:52:28 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 12:52:28 +0100
Subject: [PATCH V3 03/17] asm-generic: compat: Cleanup duplicate
 definitions
In-Reply-To: <20220120073911.99857-4-guoren@kernel.org>
References: <20220120073911.99857-4-guoren@kernel.org>
Message-ID: <CAK8P3a1UmnjHk8B6hSULiKv3FKoY5BW9=4=ESerQzc+4=LR5Zw@mail.gmail.com>

  On Thu, Jan 20, 2022 at 8:38 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> There are 7 64bit architectures that support Linux COMPAT mode to
> run 32bit applications. A lot of definitions are duplicate:
>  - COMPAT_USER_HZ
>  - COMPAT_RLIM_INFINITY
>  - COMPAT_OFF_T_MAX
>  - __compat_uid_t, __compat_uid_t
>  - compat_dev_t
>  - compat_ipc_pid_t
>  - struct compat_flock
>  - struct compat_flock64
>  - struct compat_statfs
>  - struct compat_ipc64_perm, compat_semid64_ds,
>           compat_msqid64_ds, compat_shmid64_ds
>
> Cleanup duplicate definitions and merge them into asm-generic.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

> ---
>  arch/arm64/include/asm/compat.h   | 108 +++-----------------------
>  arch/mips/include/asm/compat.h    |  24 ++----
>  arch/parisc/include/asm/compat.h  |  47 ++----------
>  arch/powerpc/include/asm/compat.h |  47 ++----------
>  arch/s390/include/asm/compat.h    | 109 +++-----------------------
>  arch/sparc/include/asm/compat.h   |  39 ++++------
>  arch/x86/include/asm/compat.h     | 114 +++-------------------------
>  include/asm-generic/compat.h      | 122 ++++++++++++++++++++++++++++++
>  8 files changed, 191 insertions(+), 419 deletions(-)
>
> diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> index eaa6ca062d89..f54f295efae3 100644
> --- a/arch/arm64/include/asm/compat.h
> +++ b/arch/arm64/include/asm/compat.h
> @@ -5,9 +5,18 @@
>  #ifndef __ASM_COMPAT_H
>  #define __ASM_COMPAT_H
>
> +#define COMPAT_RLIM_INFINITY           0xffffffff
...
> +#ifndef COMPAT_RLIM_INFINITY
> +#define COMPAT_RLIM_INFINITY   0x7fffffff
> +#endif

While this is a correct conversion, I think the default should
be 0xffffffff, to match the asm-generic RLIM_INFINITY
definition, with only mips and sparc getting the exception

> -struct compat_flock {
> -       short           l_type;
> -       short           l_whence;
> -       compat_off_t    l_start;
> -       compat_off_t    l_len;
> -       compat_pid_t    l_pid;
> -};
...
> +#ifndef compat_flock
> +struct compat_flock {
> +       compat_short_t  l_type;
> +       compat_short_t  l_whence;
> +       compat_off_t    l_start;
> +       compat_off_t    l_len;
> +       compat_pid_t    l_pid;
> +} __attribute__((packed));
> +#endif

You are adding __attribute__((packed)) here, which I think has
no effect on the layout on the structure on any of the architectures
but it does change the alignment requirements needlessly.

Better leave it without the attribute.

> -struct compat_flock64 {
> -       short           l_type;
> -       short           l_whence;
> -       compat_loff_t   l_start;
> -       compat_loff_t   l_len;
> -       compat_pid_t    l_pid;
> -};
...
> +#ifndef compat_flock64
> +struct compat_flock64 {
> +       compat_short_t  l_type;
> +       compat_short_t  l_whence;
> +       compat_loff_t   l_start;
> +       compat_loff_t   l_len;
> +       compat_pid_t    l_pid;
> +} __attribute__((packed));
> +#endif

This one is different: on all architectures other than x86,
the added packed attribute changes the size of the
structure by removing the four padding bytes at the
end. x86 originally added the attribute here to work around
the weirdness of the x86-32 ABI that aligns 64-bit values
on a 4-byte boundary.

The easiest workaround would be to have x86 keep its
custom definition. A slightly nicer version would drop the
attribute on x86 as well but instead change the compat_loff_t
definition to use compat_s64 instead of s64, giving it the
correct alignment.

> -struct compat_statfs {
> -       int             f_type;
> -       int             f_bsize;
> -       int             f_blocks;
> -       int             f_bfree;
> -       int             f_bavail;
> -       int             f_files;
> -       int             f_ffree;
> -       compat_fsid_t   f_fsid;
> -       int             f_namelen;      /* SunOS ignores this field. */
> -       int             f_frsize;
> -       int             f_flags;
> -       int             f_spare[4];
> -};
...
> +#ifndef compat_statfs
> +struct compat_statfs {
> +       compat_uint_t   f_type;
> +       compat_uint_t   f_bsize;
> +       compat_uint_t   f_blocks;
> +       compat_uint_t   f_bfree;
> +       compat_uint_t   f_bavail;
> +       compat_uint_t   f_files;
> +       compat_uint_t   f_ffree;
> +       __kernel_fsid_t f_fsid;
> +       compat_uint_t   f_namelen;
> +       compat_uint_t   f_frsize;
> +       compat_uint_t   f_flags;
> +       compat_uint_t   f_spare[4];
> +} __attribute__((packed));
> +#endif

None of the architectures use the packed attribute at the moment,
so please don't add one here.

Changing compat_fsid_t to __kernel_fsid_t is harmless, but seems
unnecessary.

Changing the signed int to an unsigned int (regardless of notation)
may be a change in behavior. s390 is the only architecture
using unsigned members here at the moment, as of b8668fd0a7e1
("s390/uapi: change struct statfs[64] member types to unsigned
values").
The description of that patch sounds like this was changed to fix
a bug, but I don't see what the actual problem would be in the
put_compat_statfs().

For the moment I'd suggest leaving this with the signed version,
with s390 being another exception next to mips. We can follow-up
with merging s390 into the common definition using either the
signed or unsigned types, but I think that needs to be a separate
patch with a detailed explanation.

 +#ifndef compat_ipc64_perm
> +struct compat_ipc64_perm {
> +       compat_key_t key;
> +       __compat_uid32_t uid;
> +       __compat_gid32_t gid;
> +       __compat_uid32_t cuid;
> +       __compat_gid32_t cgid;
> +       compat_mode_t   mode;
> +       unsigned char   __pad1[4 - sizeof(compat_mode_t)];
> +       compat_ushort_t seq;
> +       compat_ushort_t __pad2;
> +       compat_ulong_t  unused1;
> +       compat_ulong_t  unused2;
> +} __attribute__((packed));
> +
> +struct compat_semid64_ds {
> +       struct compat_ipc64_perm sem_perm;
> +       compat_ulong_t sem_otime;
> +       compat_ulong_t sem_otime_high;
> +       compat_ulong_t sem_ctime;
> +       compat_ulong_t sem_ctime_high;
> +       compat_ulong_t sem_nsems;
> +       compat_ulong_t __unused3;
> +       compat_ulong_t __unused4;
> +} __attribute__((packed));
> +
> +struct compat_msqid64_ds {
> +       struct compat_ipc64_perm msg_perm;
> +       compat_ulong_t msg_stime;
> +       compat_ulong_t msg_stime_high;
> +       compat_ulong_t msg_rtime;
> +       compat_ulong_t msg_rtime_high;
> +       compat_ulong_t msg_ctime;
> +       compat_ulong_t msg_ctime_high;
> +       compat_ulong_t msg_cbytes;
> +       compat_ulong_t msg_qnum;
> +       compat_ulong_t msg_qbytes;
> +       compat_pid_t   msg_lspid;
> +       compat_pid_t   msg_lrpid;
> +       compat_ulong_t __unused4;
> +       compat_ulong_t __unused5;
> +} __attribute__((packed));
> +
> +struct compat_shmid64_ds {
> +       struct compat_ipc64_perm shm_perm;
> +       compat_size_t  shm_segsz;
> +       compat_ulong_t shm_atime;
> +       compat_ulong_t shm_atime_high;
> +       compat_ulong_t shm_dtime;
> +       compat_ulong_t shm_dtime_high;
> +       compat_ulong_t shm_ctime;
> +       compat_ulong_t shm_ctime_high;
> +       compat_pid_t   shm_cpid;
> +       compat_pid_t   shm_lpid;
> +       compat_ulong_t shm_nattch;
> +       compat_ulong_t __unused4;
> +       compat_ulong_t __unused5;
> +} __attribute__((packed));
> +#endif

I checked these in detail, looking at the seven architectures, and your
conversion looks exactly right (I had initially missed the part about
compat_mode_t that you got right).

As with compat_flock, the packed attribute has no impact on the layout
here, but please drop it anyway for consistency.

        Arnd


From David.Laight at ACULAB.COM  Thu Jan 20 05:02:27 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Thu, 20 Jan 2022 13:02:27 +0000
Subject: [PATCH V3 03/17] asm-generic: compat: Cleanup duplicate
 definitions
In-Reply-To: <CAK8P3a1UmnjHk8B6hSULiKv3FKoY5BW9=4=ESerQzc+4=LR5Zw@mail.gmail.com>
References: <20220120073911.99857-4-guoren@kernel.org>
 <CAK8P3a1UmnjHk8B6hSULiKv3FKoY5BW9=4=ESerQzc+4=LR5Zw@mail.gmail.com>
Message-ID: <f2c1a3a10bf643d693afed6d23b3baf9@AcuMS.aculab.com>

From: Arnd Bergmann
> Sent: 20 January 2022 11:52
..
> As with compat_flock, the packed attribute has no impact on the layout
> here, but please drop it anyway for consistency.

Never mind the structure layout, because 'packed' allows the
structure to be aligned on any boundary it forces the compiler
to use byte memory accesses and shifts on some architectures.
This is a horrid performance penalty.

'packed' should only be specified for structures that can
occur on any address boundary.
ie basically never.

If you need to remove the implicit pad before a field (eg 64bit
fields on x64-32) then you can mark the field itself as 'packed'.
Although, in that case, putting the attribute on the type (compat_s64)
is generally cleaner.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From linux at armlinux.org.uk  Thu Jan 20 05:03:06 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 20 Jan 2022 13:03:06 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
 <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
Message-ID: <Yeldih0PHotN4/bn@shell.armlinux.org.uk>

On Thu, Jan 20, 2022 at 12:22:35PM +0000, Robin Murphy wrote:
> On 2022-01-19 19:12, Russell King (Oracle) wrote:
> > On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
> > > Indeed, my impression is that the only legitimate way to get hold of a page
> > > pointer without assumed provenance is via pfn_to_page(), which is where
> > > pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
> > > tautology.
> > 
> > That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
> > values of pfn.
> > 
> > Given how pfn_to_page() is defined in the sparsemem case:
> > 
> > #define __pfn_to_page(pfn)                              \
> > ({	unsigned long __pfn = (pfn);                    \
> > 	struct mem_section *__sec = __pfn_to_section(__pfn);    \
> > 	__section_mem_map_addr(__sec) + __pfn;          \
> > })
> > #define page_to_pfn __page_to_pfn
> > 
> > that isn't the case, especially when looking at page_to_pfn():
> > 
> > #define __page_to_pfn(pg)                                       \
> > ({      const struct page *__pg = (pg);                         \
> >          int __sec = page_to_section(__pg);                      \
> > 	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
> > })
> > 
> > Where:
> > 
> > static inline unsigned long page_to_section(const struct page *page)
> > {
> > 	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> > }
> > 
> > So if page_to_section() returns something that is, e.g. zero for an
> > invalid page in a non-zero section, you're not going to end up with
> > the right pfn from page_to_pfn().
> 
> Right, I emphasised "should" in an attempt to imply "in the absence of
> serious bugs that have further-reaching consequences anyway".
> 
> > As I've said now a couple of times, trying to determine of a struct
> > page pointer is valid is the wrong question to be asking.
> 
> And doing so in one single place, on the justification of avoiding an
> incredibly niche symptom, is even more so. Not to mention that an address
> size fault is one of the best possible outcomes anyway, vs. the untold
> damage that may stem from accesses actually going through to random parts of
> the physical memory map.

I don't see it as a "niche" symptom.

If we start off with the struct page being invalid, then the result of
page_to_pfn() can not be relied upon to produce something that is
meaningful - which is exactly why the vmap() issue arises.

With a pfn_valid() check, we at least know that the PFN points at
memory. However, that memory could be _anything_ in the system - it
could be the kernel image, and it could give userspace access to
change kernel code.

So, while it is useful to do a pfn_valid() check in vmap(), as I said
to willy, this must _not_ be the primary check. It should IMHO use
WARN_ON() to make it blatently obvious that it should be something we
expect _not_ to trigger under normal circumstances, but is there to
catch programming errors elsewhere.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From guoren at kernel.org  Thu Jan 20 05:27:08 2022
From: guoren at kernel.org (Guo Ren)
Date: Thu, 20 Jan 2022 21:27:08 +0800
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <f16cf10425a14c2e8183d5c90667ce72@AcuMS.aculab.com>
References: <20220120073911.99857-8-guoren@kernel.org>
 <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>
 <f16cf10425a14c2e8183d5c90667ce72@AcuMS.aculab.com>
Message-ID: <CAJF2gTRwh40xDBkoRJWZEUketKFDAy7_z=-WW7E=T46yH4zPvw@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:53 PM David Laight <David.Laight at aculab.com> wrote:
>
> > > Limit 32-bit compatible process in 0-2GB virtual address range
> > > (which is enough for real scenarios), because it could avoid
> > > address sign extend problem when 32-bit enter 64-bit and ease
> > > software design.
>
> Eh?
> I thought nearly all the other 32bit unix ports (of any flavour)
> put the user-kernel boundary at 3GB.
No, riscv32 is about 2.4G, csky is 2G/2.5G.

> (Apart from some very old sparc ones that use 3.5GB.)
>
> 2GB is used by Windows.
>
> I think the x86-64 32bit compat code even puts the boundary at 4GB.
Yes, we could give rv32 compat for 4GB with some effort. But it's unnecessary.

There are no history issues for rv32, we use compat mode to reduce
memory footprint. eg: only 64MB memory available.

At end compat for 4GB is another topic, let's give the initial compat
for 2GB support to riscv.

>
>         David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From guoren at kernel.org  Thu Jan 20 05:35:56 2022
From: guoren at kernel.org (Guo Ren)
Date: Thu, 20 Jan 2022 21:35:56 +0800
Subject: [PATCH V3 10/17] riscv: compat: Add elf.h implementation
In-Reply-To: <CAK8P3a2HaeFGdOr4Rm_ZcEP0rjh2Mo53=-ZRnEPtFfnmzfeE6g@mail.gmail.com>
References: <20220120073911.99857-11-guoren@kernel.org>
 <CAK8P3a2HaeFGdOr4Rm_ZcEP0rjh2Mo53=-ZRnEPtFfnmzfeE6g@mail.gmail.com>
Message-ID: <CAJF2gTQnrCS1X6KQt0pbNFc01sYgBDgfb9RGT1G=rTEGK1mbRQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 9:33 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > Implement necessary type and macro for compat elf. See the code
> > comment for detail.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
>
> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
>
> > +
> > +/*
> > + * FIXME: not sure SET_PERSONALITY for compat process is right!
> > + */
> > +#define SET_PERSONALITY(ex)                                    \
> > +do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)              \
> > +               set_thread_flag(TIF_32BIT);                     \
> > +       else                                                    \
> > +               clear_thread_flag(TIF_32BIT);                   \
> > +       if (personality(current->personality) != PER_LINUX32)   \
> > +               set_personality(PER_LINUX |                     \
> > +                       (current->personality & (~PER_MASK)));  \
> > +} while (0)
> > +
>
> The implementation looks good to me now,  you can remove that comment above it.
Thx for pointing it out. I forgot.

>
>         Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From arnd at arndb.de  Thu Jan 20 01:41:25 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 10:41:25 +0100
Subject: [PATCH V3 16/17] riscv: compat: Add COMPAT Kbuild skeletal support
In-Reply-To: <20220120073911.99857-17-guoren@kernel.org>
References: <20220120073911.99857-17-guoren@kernel.org>
Message-ID: <CAK8P3a1nUcYjhEE5eyFAE_QqfjhRsZZ81ni8jyR8cPaP5QKJDg@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> Adds initial skeletal COMPAT Kbuild (Runing 32bit U-mode on 64bit
> S-mode) support.
>  - Setup kconfig & dummy functions for compiling.
>  - Implement compat_start_thread by the way.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From alexander.sverdlin at gmail.com  Thu Jan 20 05:37:38 2022
From: alexander.sverdlin at gmail.com (Alexander Sverdlin)
Date: Thu, 20 Jan 2022 14:37:38 +0100
Subject: [PATCH] ep93xx: clock: Fix UAF in ep93xx_clk_register_gate()
Message-ID: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>

arch/arm/mach-ep93xx/clock.c:151:2: note: Taking true branch
if (IS_ERR(clk))
^
arch/arm/mach-ep93xx/clock.c:152:3: note: Memory is released
kfree(psc);
^~~~~~~~~~
arch/arm/mach-ep93xx/clock.c:154:2: note: Use of memory after it is freed
return &psc->hw;
^ ~~~~~~~~

Link: https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org/thread/B5YCO2NJEXINCYE26Y255LCVMO55BGWW/
Reported-by: kernel test robot <lkp at intel.com>
Fixes: 9645ccc7bd7a ("ep93xx: clock: convert in-place to COMMON_CLK")
Cc: stable at vger.kernel.org
Signed-off-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index cc75087134d3..4aee14f18123 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -148,8 +148,10 @@ static struct clk_hw *ep93xx_clk_register_gate(const char *name,
 	psc->lock = &clk_lock;
 
 	clk = clk_register(NULL, &psc->hw);
-	if (IS_ERR(clk))
+	if (IS_ERR(clk)) {
 		kfree(psc);
+		return (void *)clk;
+	}
 
 	return &psc->hw;
 }
-- 
2.34.1



From alexander.sverdlin at gmail.com  Thu Jan 20 05:37:39 2022
From: alexander.sverdlin at gmail.com (Alexander Sverdlin)
Date: Thu, 20 Jan 2022 14:37:39 +0100
Subject: [PATCH] ep93xx: clock: Don't use plain integer as NULL pointer
In-Reply-To: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>
References: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>
Message-ID: <20220120133739.4170298-2-alexander.sverdlin@gmail.com>

Fix sparse warning:
arch/arm/mach-ep93xx/clock.c:210:35: sparse: sparse: Using plain integer as NULL pointer

Reported-by: kernel test robot <lkp at intel.com>
Link: https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org/thread/TLFJ6D7WGMDJSQ6XK7UZE4XR2PLRZJSV/
Signed-off-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 4aee14f18123..71c54da0c1e1 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -209,7 +209,7 @@ static int ep93xx_mux_determine_rate(struct clk_hw *hw,
 				struct clk_rate_request *req)
 {
 	unsigned long rate = req->rate;
-	struct clk *best_parent = 0;
+	struct clk *best_parent = NULL;
 	unsigned long __parent_rate;
 	unsigned long best_rate = 0, actual_rate, mclk_rate;
 	unsigned long best_parent_rate;
-- 
2.34.1



From guoren at kernel.org  Thu Jan 20 05:43:03 2022
From: guoren at kernel.org (Guo Ren)
Date: Thu, 20 Jan 2022 21:43:03 +0800
Subject: [PATCH V3 15/17] riscv: compat: Add UXL_32 support in start_thread
In-Reply-To: <CAK8P3a0Mr2m2dVoVss59cN-9X7GVBD29VQLo3m4xswRznk_WUQ@mail.gmail.com>
References: <20220120073911.99857-16-guoren@kernel.org>
 <CAK8P3a0Mr2m2dVoVss59cN-9X7GVBD29VQLo3m4xswRznk_WUQ@mail.gmail.com>
Message-ID: <CAJF2gTTGD_Ks2pO4jXx+QbiLV4nkjzk6mP-xKJOCvHtGTeFfOQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 9:39 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> > +
> > +#ifdef CONFIG_COMPAT
> > +       if (is_compat_task())
> > +               regs->status |= SR_UXL_32;
> > +#endif
>
>
> You should not need that #ifdef, as the is_compat_task() definition is
> meant to drop the code at compile time, unless the SR_UXL_32
> definition is not visible here.
I almost put CONFIG_COMPAT in every compat related code, because I
hope the next arch that wants to support COMPAT could easily find
where to be modified.

>
>          Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From alim.akhtar at samsung.com  Thu Jan 20 05:53:31 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Thu, 20 Jan 2022 19:23:31 +0530
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220119201509.6220FC004E1@smtp.kernel.org>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
 <20220118144851.69537-5-alim.akhtar@samsung.com>
 <20220119201509.6220FC004E1@smtp.kernel.org>
Message-ID: <016c01d80e05$1ef9eab0$5cedc010$@samsung.com>

Hi Stephen

>-----Original Message-----
>From: Stephen Boyd [mailto:sboyd at kernel.org]
>Sent: Thursday, January 20, 2022 1:45 AM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org;
>krzysztof.kozlowski at canonical.com; s.nawrocki at samsung.com; linux-
>samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com; Alim Akhtar
><alim.akhtar at samsung.com>; linux-fsd at tesla.com; Jayati Sahu
><jayati.sahu at samsung.com>; Ajay Kumar <ajaykumar.rs at samsung.com>
>Subject: Re: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
>
>Quoting Alim Akhtar (2022-01-18 06:48:39)
>> diff --git a/drivers/clk/samsung/clk-fsd.c
>> b/drivers/clk/samsung/clk-fsd.c new file mode 100644 index
>> 000000000000..2669396d81b9
>> --- /dev/null
>> +++ b/drivers/clk/samsung/clk-fsd.c
>> @@ -0,0 +1,308 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
>> + *             https://www.samsung.com
>> + * Copyright (c) 2017-2022 Tesla, Inc.
>> + *             https://www.tesla.com
>> + *
>> + * Common Clock Framework support for FSD SoC.
>> + */
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/of.h>
>
>include init.h for __initconst and kernel.h for ARRAY_SIZE
>
I did not face any compilation error.
Do I need to explicitly add these header files in driver? I see clk.h implicitly includes kernel.h
Same is the case of other driver in this directory.

>> +
>> +#include <dt-bindings/clock/fsd-clk.h>
>> +
>> +#include "clk.h"
>> +



From andriy.shevchenko at linux.intel.com  Thu Jan 20 05:56:30 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 20 Jan 2022 15:56:30 +0200
Subject: [PATCH v4 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <0b6ef0ce05bb92cd458043be2441101e20166242.camel@mediatek.com>
References: <20220119103212.13158-1-axe.yang@mediatek.com>
 <20220119103212.13158-4-axe.yang@mediatek.com>
 <Yehq7L36yfJ8D/j2@smile.fi.intel.com>
 <0b6ef0ce05bb92cd458043be2441101e20166242.camel@mediatek.com>
Message-ID: <YelqDifksEmtMv44@smile.fi.intel.com>

On Thu, Jan 20, 2022 at 01:34:08PM +0800, Axe Yang wrote:
> On Wed, 2022-01-19 at 21:47 +0200, Andy Shevchenko wrote:
> > On Wed, Jan 19, 2022 at 06:32:12PM +0800, Axe Yang wrote:

...

> > > Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> > 
> > The submitters SoB must be last among all SoB tags. Please, read
> > Submitting
> > Patches document carefully.
> > 
> > > Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> > 
> > Who is they, why their SoB appeared here?
> 
> Yong Mao is the co-developer of this patch, I will reorder the SoB
> chains.

And you will need to add a corresponding tag.

...

> > > - * Copyright (c) 2014-2015 MediaTek Inc.
> > > + * Copyright (c) 2022 MediaTek Inc.
> > 
> > This doesn't feel right. Why did you remove old years?
> 
> I should keep the publish year 2014 of this driver.
> But I still think range 2014-2022 is the most appropriate way to change
> the copyright time. Over these years, mediatek is keeping maintaining
> this driver continuously. What do you think?

I guess I already showed my opinion on the topic? The common sense tells
me that it should be as simple as '2014-2015,2022' there.

-- 
With Best Regards,
Andy Shevchenko




From alexandru.elisei at arm.com  Thu Jan 20 05:58:02 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 20 Jan 2022 13:58:02 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <20211129200150.351436-15-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
Message-ID: <YelqampUOCIt3YZE@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> From: Jintack Lim <jintack.lim at linaro.org>
> 
> Support injecting exceptions and performing exception returns to and
> from virtual EL2.  This must be done entirely in software except when
> taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
> == {1,1}  (a VHE guest hypervisor).
> 
> Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> [maz: switch to common exception injection framework]
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>
> [..]
>
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> new file mode 100644
> index 000000000000..339e8272b01e
> --- /dev/null
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -0,0 +1,176 @@
> +/*
> + * Copyright (C) 2016 - Linaro and Columbia University
> + * Author: Jintack Lim <jintack.lim at linaro.org>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/kvm.h>
> +#include <linux/kvm_host.h>
> +
> +#include <asm/kvm_emulate.h>
> +#include <asm/kvm_nested.h>
> +
> +#include "hyp/include/hyp/adjust_pc.h"
> +
> +#include "trace.h"
> +
> +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> +{
> +	u64 spsr, elr, mode;
> +	bool direct_eret;
> +
> +	/*
> +	 * Going through the whole put/load motions is a waste of time
> +	 * if this is a VHE guest hypervisor returning to its own
> +	 * userspace, or the hypervisor performing a local exception
> +	 * return. No need to save/restore registers, no need to
> +	 * switch S2 MMU. Just do the canonical ERET.
> +	 */
> +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> +
> +	direct_eret  = (mode == PSR_MODE_EL0t &&
> +			vcpu_el2_e2h_is_set(vcpu) &&
> +			vcpu_el2_tge_is_set(vcpu));
> +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> +
> +	if (direct_eret) {
> +		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
> +		*vcpu_cpsr(vcpu) = spsr;
> +		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
> +		return;
> +	}
> +
> +	preempt_disable();
> +	kvm_arch_vcpu_put(vcpu);
> +
> +	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
> +
> +	trace_kvm_nested_eret(vcpu, elr, spsr);
> +
> +	/*
> +	 * Note that the current exception level is always the virtual EL2,
> +	 * since we set HCR_EL2.NV bit only when entering the virtual EL2.
> +	 */
> +	*vcpu_pc(vcpu) = elr;
> +	*vcpu_cpsr(vcpu) = spsr;
> +
> +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> +	preempt_enable();

According to ARM DDI 0487G.a, page D13-3289, ERET'ing to EL1 when HCR_EL2.TGE is
set is an illegal exception return. I don't see this case treated here.

Thanks,
Alex


From robin.murphy at arm.com  Thu Jan 20 06:22:10 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 20 Jan 2022 14:22:10 +0000
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <20220119021844.3C225C340E5@smtp.kernel.org>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com> <YeF/AYZ0DuKGwLLk@maud>
 <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>
 <69525223-7d90-5714-bbe9-4d7f0b9a293d@arm.com>
 <20220119021844.3C225C340E5@smtp.kernel.org>
Message-ID: <5d839338-6072-9c52-1893-2f804d937ea1@arm.com>

On 2022-01-19 02:18, Stephen Boyd wrote:
> Quoting Robin Murphy (2022-01-18 07:01:46)
>> On 2022-01-18 07:19, Chen-Yu Tsai wrote:
>>> Hi,
>>>
>>> On Fri, Jan 14, 2022 at 9:47 PM Alyssa Rosenzweig <alyssa at collabora.com> wrote:
>>>>
>>>>>> That links to an internal Google issue tracker which I assume has more
>>>>>> information on the bug. I would appreciate if someone from Google or
>>>>>> MediaTek could explain what this change actually does and why it's
>>>>>> necessary on MT8192.
>>>>>>
>>>>>> At any rate, this register logically belongs to the MT8192 "infra" clock
>>>>>> device, so it makes sense to set it there too. This avoids adding any
>>>>>> platform-specific hacks to the 3D driver, either mainline (Panfrost) or
>>>>>> legacy (kbase).
>>>>>
>>>>> Does this really have anything to do with clocks?
>>>>
>>>> I have no idea. MediaTek, Google, please explain.
>>>>
>>>>> In particular, "ACP" usually refers to the Accelerator Coherency Port
>>>>> of a CPU cluster or DSU, and given the stated symptom of the issue
>>>>> affected by it, my first guess would be that this bit might indeed
>>>>> control routing of GPU traffic either to the ACP or the (presumably
>>>>> non-coherent) main interconnect.
>>>>
>>>> I'd easily believe that.
>>>
>>> As Robin guessed, "ACP" here does refer to the Accelerator Coherency Port.
>>> And the bit in infracfg toggles whether ACP is used or not.
>>>
>>> Explanation from MediaTek in verbatim:
>>>
>>> -------------------------------------------------------------------------
>>> The ACP path on MT8192 is just for experimental only.
>>> We are not intended to enable ACP by design.
>>>
>>> But due to an unexpected operation, it was accidently opened by default.
>>> So we need a patch to disable the ACP for MT8192.
>>> -------------------------------------------------------------------------
>>
>> Aha! That's great, thanks ChenYu!
>>
>> Stephen, my thinking here is that if this feature controls the GPU
>> interconnect, and only matters when the GPU is going to be used (as
>> strongly implied by the downstream implementation), then the GPU driver
>> is the only interested party and may as well take responsibility if
>> there's no better alternative.
>>
>> I'd agree that if there was already a "base" infracfg driver doing
>> general system-wide set-and-forget configuration then it would equally
>> well fit in there, but that doesn't seem to be the case.
> 
> Wouldn't this first set-and-forget configuration fit that bill? We can't
> have a "base" driver because why?

Sure, everything has a starting point somewhere, it just means more work 
for someone to have to do. I'm not that person - I'm just here as a 
curious reviewer asking questions to help refine the abstraction - so I 
chose to lean towards the pragmatic side here given what I know about 
how much Alyssa enjoys kernel development ;)

>> Short of trying
>> to abuse the bp_infracfg data in the mtk-pm-domains driver (which
>> doesn't seem like a particularly pleasant idea), the code to poke a bit
>> into a syscon regmap is going to be pretty much the same wherever we add
>> it. There's already a bit of a pattern for MTK drivers to look up and
>> poke their own infracfg bits directly as needed, so between that and the
>> downstream implementation for this particular bit, leaving it to
>> Panfrost seems like the least surprising option.
>>
> 
> I'd prefer we leave the SoC glue out of device drivers for subsystems
> that really don't want to or need to know about the SoC level details.
> The GPU driver wants to live life drawing triangles! :) It doesn't want
> to know that the ACP path didn't work out on some SoC it got plopped
> down into. And of course GPU is the only interested party, because the
> SoC glue for the GPU is all messed up so GPU can't operate properly
> without this bit toggled. I wonder where the fix would end up if this
> port was shared by more than one driver. Probably back here in the
> closest thing there is to the SoC driver.

As I hoped to imply, I agree that that's a perfectly valid line of 
reasoning too. However it does gloss over certain other considerations 
like managing dependencies between the drivers such that it's not too 
cryptic for a user to configure a kernel that actually works as 
expected, and the GPU driver has a guarantee that the configuration 
really has been done by the point that it wants to start DMA, for instance.

> It's not as simple as poking bits in some SoC glue IO space
> unconditionally either. The GPU driver will need to know which SoC is
> being used and then only poke the bits if the affected SoC is in use. Or
> we'll have some DT binding update to poke the bit if some syscon
> property is present in the DT node. Either way, it's a set-and-forget
> thing, so the GPU driver will now have some set-and-forget logic for one
> SoC out of many that it supports; do it once at boot, grab a regmap,
> parse some more stuff to make sure it's needed, poke the bit, release
> the regmap, finally start drawing.

In this case we do happen to have this handy function called 
panfrost_probe() which already deals with one-off startup stuff :P

We also already have SoC-specific GPU compatibles because even without 
experimental interconnect easter eggs, people integrate these IPs in 
fairly involved ways and there's a fair degree of variety. However 
unless we want to be super-strict it's also not too hard to simply 
assume that if we can find a "mediatek,mt8192-infracfg" syscon then we 
set the MT8192 magic bit within it, and if we can't then we don't.

> Of course, I won't oppose the mess being moved somewhere outside of the
> subsystem I maintain ;-) I was mainly curious to understand why the
> regmap path is proposed.

Well, regmap because it's a syscon, so whoever's accessing it that 
should be via its existing regmap rather than going behind its back. To 
be fair, there is a nascent infracfg "driver" already (even if it's just 
two helper functions), so adding some new infrastructure in there is a 
clear possibility - the functionally-similar Rockchip GRF already has 
something comparable, for example - it's just somewhat more code and 
more work thinking through the additional reasoning, compared to piling 
SoC-specific GPU-related stuff into the place that already knows about 
SoC-specific GPU stuff. As things stand, if someone *is* prepared to 
take that on then it's fine by me!

FWIW, I have no desire to look more closely at the downstream driver, 
but I did notice in the context of the linked patch that there appeared 
to be some power-management-looking stuff as well as this magic bit, so 
if it's possible that that might be something we care about in future 
and mean we end up needing to poke syscons from Panfrost anyway, it 
might want factoring in to the decision.

Cheers,
Robin.


From jagan at amarulasolutions.com  Thu Jan 20 06:22:54 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Thu, 20 Jan 2022 19:52:54 +0530
Subject: [PATCH v2 5/6] drm/meson: add DSI encoder
In-Reply-To: <20220120083357.1541262-6-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-6-narmstrong@baylibre.com>
Message-ID: <CAMty3ZCrcQchnne1KU1RQA6MfwRQS8dObJQcOF_H7fEQ57wa0w@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> This adds an encoder bridge designed to drive a MIPI-DSI display
> by using the ENCL encoder through the internal MIPI DSI transceiver
> connected to the output of the ENCL pixel encoder.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/Makefile            |   2 +-
>  drivers/gpu/drm/meson/meson_drv.c         |   7 +
>  drivers/gpu/drm/meson/meson_encoder_dsi.c | 160 ++++++++++++++++++++++
>  drivers/gpu/drm/meson/meson_encoder_dsi.h |  12 ++
>  4 files changed, 180 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.c
>  create mode 100644 drivers/gpu/drm/meson/meson_encoder_dsi.h
>
> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> index 3afa31bdc950..833e18c20603 100644
> --- a/drivers/gpu/drm/meson/Makefile
> +++ b/drivers/gpu/drm/meson/Makefile
> @@ -2,7 +2,7 @@
>  meson-drm-y := meson_drv.o meson_plane.o meson_crtc.o meson_encoder_cvbs.o
>  meson-drm-y += meson_viu.o meson_vpp.o meson_venc.o meson_vclk.o meson_overlay.o
>  meson-drm-y += meson_rdma.o meson_osd_afbcd.o
> -meson-drm-y += meson_encoder_hdmi.o
> +meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>
>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 26aeaf0ab86e..15344cf9f913 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -33,6 +33,7 @@
>  #include "meson_registers.h"
>  #include "meson_encoder_cvbs.h"
>  #include "meson_encoder_hdmi.h"
> +#include "meson_encoder_dsi.h"
>  #include "meson_viu.h"
>  #include "meson_vpp.h"
>  #include "meson_rdma.h"
> @@ -323,6 +324,12 @@ static int meson_drv_bind_master(struct device *dev, bool has_components)
>         if (ret)
>                 goto exit_afbcd;
>
> +       if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
> +               ret = meson_encoder_dsi_init(priv);
> +               if (ret)
> +                       goto free_drm;
> +       }
> +
>         ret = meson_plane_create(priv);
>         if (ret)
>                 goto exit_afbcd;
> diff --git a/drivers/gpu/drm/meson/meson_encoder_dsi.c b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> new file mode 100644
> index 000000000000..12a586316183
> --- /dev/null
> +++ b/drivers/gpu/drm/meson/meson_encoder_dsi.c
> @@ -0,0 +1,160 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (C) 2016 BayLibre, SAS
> + * Author: Neil Armstrong <narmstrong at baylibre.com>
> + * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_graph.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_simple_kms_helper.h>
> +#include <drm/drm_bridge.h>
> +#include <drm/drm_bridge_connector.h>
> +#include <drm/drm_device.h>
> +#include <drm/drm_probe_helper.h>
> +
> +#include "meson_drv.h"
> +#include "meson_encoder_dsi.h"
> +#include "meson_registers.h"
> +#include "meson_venc.h"
> +#include "meson_vclk.h"
> +
> +struct meson_encoder_dsi {
> +       struct drm_encoder encoder;
> +       struct drm_bridge bridge;
> +       struct drm_bridge *next_bridge;
> +       struct meson_drm *priv;
> +};
> +
> +#define bridge_to_meson_encoder_dsi(x) \
> +       container_of(x, struct meson_encoder_dsi, bridge)
> +
> +static int meson_encoder_dsi_attach(struct drm_bridge *bridge,
> +                                   enum drm_bridge_attach_flags flags)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +
> +       return drm_bridge_attach(bridge->encoder, encoder_dsi->next_bridge,
> +                                &encoder_dsi->bridge, flags);
> +}
> +
> +static void meson_encoder_dsi_mode_set(struct drm_bridge *bridge,
> +                                      const struct drm_display_mode *mode,
> +                                      const struct drm_display_mode *adjusted_mode)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = encoder_dsi->priv;
> +
> +       meson_vclk_setup(priv, MESON_VCLK_TARGET_DSI, mode->clock, 0, 0, 0, false);
> +
> +       meson_venc_mipi_dsi_mode_set(priv, mode);
> +       meson_encl_load_gamma(priv);
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, ENCL_VIDEO_MODE_ADV_VFIFO_EN,
> +                           priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_TST_EN));
> +}
> +
> +static void meson_encoder_dsi_atomic_enable(struct drm_bridge *bridge,
> +                                           struct drm_bridge_state *bridge_state)
> +{
> +       struct meson_encoder_dsi *encoder_dsi = bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = encoder_dsi->priv;
> +
> +       writel_bits_relaxed(BIT(0), 0, priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
> +
> +       writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +}
> +
> +static void meson_encoder_dsi_atomic_disable(struct drm_bridge *bridge,
> +                                            struct drm_bridge_state *bridge_state)
> +{
> +       struct meson_encoder_dsi *meson_encoder_dsi =
> +                                       bridge_to_meson_encoder_dsi(bridge);
> +       struct meson_drm *priv = meson_encoder_dsi->priv;
> +
> +       writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +       writel_bits_relaxed(BIT(0), BIT(0), priv->io_base + _REG(VPP_WRAP_OSD1_MATRIX_EN_CTRL));
> +}
> +
> +static const struct drm_bridge_funcs meson_encoder_dsi_bridge_funcs = {
> +       .attach = meson_encoder_dsi_attach,
> +       /*
> +        * TOFIX: remove when dw-mipi-dsi moves out of mode_set
> +        * We should get rid of mode_set, but until dw-mipi-dsi uses it
> +        * we need to setup the pixel clock before the following
> +        * bridge tries to setup the HW.
> +        */
> +       .mode_set = meson_encoder_dsi_mode_set,
> +       .atomic_enable = meson_encoder_dsi_atomic_enable,
> +       .atomic_disable = meson_encoder_dsi_atomic_disable,
> +       .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
> +       .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
> +       .atomic_reset = drm_atomic_helper_bridge_reset,
> +};
> +
> +int meson_encoder_dsi_init(struct meson_drm *priv)
> +{
> +       struct meson_encoder_dsi *meson_encoder_dsi;
> +       struct device_node *remote;
> +       int ret;
> +
> +       meson_encoder_dsi = devm_kzalloc(priv->dev, sizeof(*meson_encoder_dsi), GFP_KERNEL);
> +       if (!meson_encoder_dsi)
> +               return -ENOMEM;
> +
> +       /* DSI Transceiver Bridge */
> +       remote = of_graph_get_remote_node(priv->dev->of_node, 2, 0);
> +       if (!remote) {
> +               dev_err(priv->dev, "DSI transceiver device is disabled");
> +               return 0;
> +       }
> +
> +       meson_encoder_dsi->next_bridge = of_drm_find_bridge(remote);
> +       if (!meson_encoder_dsi->next_bridge) {
> +               dev_dbg(priv->dev, "Failed to find DSI transceiver bridge: %d\n", ret);
> +               return -EPROBE_DEFER;
> +       }
> +
> +       /* DSI Encoder Bridge */
> +       meson_encoder_dsi->bridge.funcs = &meson_encoder_dsi_bridge_funcs;
> +       meson_encoder_dsi->bridge.of_node = priv->dev->of_node;
> +       meson_encoder_dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
> +
> +       drm_bridge_add(&meson_encoder_dsi->bridge);
> +
> +       meson_encoder_dsi->priv = priv;
> +
> +       /* Encoder */
> +       ret = drm_simple_encoder_init(priv->drm, &meson_encoder_dsi->encoder,
> +                                     DRM_MODE_ENCODER_DSI);
> +       if (ret) {
> +               dev_err(priv->dev, "Failed to init DSI encoder: %d\n", ret);
> +               return ret;
> +       }
> +
> +       meson_encoder_dsi->encoder.possible_crtcs = BIT(0);
> +
> +       /* Attach DSI Encoder Bridge to Encoder */
> +       ret = drm_bridge_attach(&meson_encoder_dsi->encoder, &meson_encoder_dsi->bridge, NULL, 0);
> +       if (ret) {
> +               dev_err(priv->dev, "Failed to attach bridge: %d\n", ret);
> +               return ret;
> +       }
> +
> +       /*
> +        * We should have now in place:
> +        * encoder->[dsi encoder bridge]->[dw-mipi-dsi bridge]->[panel bridge]->[panel]
> +        */

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>


From jagan at amarulasolutions.com  Thu Jan 20 06:24:55 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Thu, 20 Jan 2022 19:54:55 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-7-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
Message-ID: <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> Glue on other Amlogic SoCs.
>
> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> Analog PHY in the proper way.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/Kconfig             |   7 +
>  drivers/gpu/drm/meson/Makefile            |   1 +
>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
>  4 files changed, 525 insertions(+)
>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
>
> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
> index 6c70fc3214af..71a1364b51e1 100644
> --- a/drivers/gpu/drm/meson/Kconfig
> +++ b/drivers/gpu/drm/meson/Kconfig
> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
>         default y if DRM_MESON
>         select DRM_DW_HDMI
>         imply DRM_DW_HDMI_I2S_AUDIO
> +
> +config DRM_MESON_DW_MIPI_DSI
> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
> +       depends on DRM_MESON
> +       default y if DRM_MESON
> +       select DRM_DW_MIPI_DSI
> +       select GENERIC_PHY_MIPI_DPHY
> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> index 833e18c20603..43071bdbd4b9 100644
> --- a/drivers/gpu/drm/meson/Makefile
> +++ b/drivers/gpu/drm/meson/Makefile
> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>
>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o

Can the naming convention prefix with dw-mipi-dsi like other glue
drivers follow?

Jagan.


From alyssa at collabora.com  Thu Jan 20 06:27:03 2022
From: alyssa at collabora.com (Alyssa Rosenzweig)
Date: Thu, 20 Jan 2022 09:27:03 -0500
Subject: [PATCH] clk: mediatek: Disable ACP to fix 3D on MT8192
In-Reply-To: <5d839338-6072-9c52-1893-2f804d937ea1@arm.com>
References: <20220110181330.3224-1-alyssa.rosenzweig@collabora.com>
 <eb6d11af-ff48-a366-d428-77bcaa250a8a@arm.com>
 <YeF/AYZ0DuKGwLLk@maud>
 <CAGXv+5H9BsNUdiY6zMH6THKKMvRdPypNtUEVviMHQEjgNGDk_A@mail.gmail.com>
 <69525223-7d90-5714-bbe9-4d7f0b9a293d@arm.com>
 <20220119021844.3C225C340E5@smtp.kernel.org>
 <5d839338-6072-9c52-1893-2f804d937ea1@arm.com>
Message-ID: <YelxN/zpdkukBBqy@maud>

> We also already have SoC-specific GPU compatibles because even without
> experimental interconnect easter eggs, people integrate these IPs in fairly
> involved ways and there's a fair degree of variety. However unless we want
> to be super-strict it's also not too hard to simply assume that if we can
> find a "mediatek,mt8192-infracfg" syscon then we set the MT8192 magic bit
> within it, and if we can't then we don't.

We need a MT8192-specific compatible for the GPU anyway due to "unique"
power management requirements, this is why the MT8183 before it has a
specific GPU compatible. So I'm not worried about the compatible.


From arnd at arndb.de  Thu Jan 20 06:42:42 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 15:42:42 +0100
Subject: [PATCH V3 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <20220120073911.99857-9-guoren@kernel.org>
References: <20220120073911.99857-9-guoren@kernel.org>
Message-ID: <CAK8P3a0LxB3we9wHOa4OPmNow6wz5NP49zeYhh7QXNv-MiR8UA@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
>  /* The array of function pointers for syscalls. */
>  extern void * const sys_call_table[];
> +#ifdef CONFIG_COMPAT
> +extern void * const compat_sys_call_table[];
> +#endif

No need for the #ifdef, the normal convention is to just define the
extern declaration unconditionally for symbols that may or may not be defined.

> +COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
> +                      arg_u32p(length))
> +{
> +       return ksys_truncate(pathname, arg_u64(length));
> +}

Are you sure these are the right calling conventions? According to [1],
I think the 64-bit argument should be in an aligned pair of registers,
which means you need an extra pad argument as in the arm64 version
of these functions. Same for ftruncate64, pread64, pwrite64, and
readahead.

> +COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, arg_u32p(length))
> +{
> +       return ksys_ftruncate(fd, arg_u64(length));
> +}
> +
> +COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
> +                      arg_u32p(offset), arg_u32p(len))
> +{
> +       return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
> +}
> +
> +COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
> +                      size_t, count, arg_u32p(pos))
> +{
> +       return ksys_pread64(fd, buf, count, arg_u64(pos));
> +}
> +
> +COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd,
> +                      const char __user *, buf, size_t, count, arg_u32p(pos))
> +{
> +       return ksys_pwrite64(fd, buf, count, arg_u64(pos));
> +}
> +
> +COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, arg_u32p(offset),
> +                      arg_u32p(nbytes), unsigned int, flags)
> +{
> +       return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes),
> +                                   flags);
> +}
> +
> +COMPAT_SYSCALL_DEFINE4(readahead, int, fd, arg_u32p(offset),
> +                      size_t, count)
> +{
> +       return ksys_readahead(fd, arg_u64(offset), count);
> +}
> +
> +COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, int, advice, arg_u32p(offset),
> +                      arg_u32p(len))
> +{
> +       return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice);
> +}

I still feel like these should be the common implementations next to the
native handlers inside of an #ifdef CONFIG_COMPAT.

The names clash with the custom versions defined for powerpc and sparc,
but the duplicates look compatible if you can account for the padded
argument and the lo/hi order of the pairs, so could just be removed here
(all other architectures use custom function names instead).

        Arnd

[1] https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf


From hverkuil-cisco at xs4all.nl  Thu Jan 20 06:44:26 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Jan 2022 15:44:26 +0100
Subject: [PATCH v14 00/13] amphion video decoder/encoder driver
In-Reply-To: <cover.1638865027.git.ming.qian@nxp.com>
References: <cover.1638865027.git.ming.qian@nxp.com>
Message-ID: <d0540f65-ccc8-cfc8-d5c6-8dc40603b18d@xs4all.nl>

Hi Ming,

Running 'scripts/checkpatch.pl --strict' over the patches gives me lots
of issues, most of them easily fixed.

As always with checkpatch, use common sense since not everything can be
fixed.

You probably ran checkpatch.pl without the --strict option, but in the media
subsystem we use that option.

Note that sparse and smatch are happy, so it is just the checkpatch issues
that need to be improved.

On 12/7/21 09:24, Ming Qian wrote:
> Hi all,
> 
> This patch series adds support for
> the amphion video encoder and decoder
> via the VPU block present in imx8q platforms.
> Currently, support for IMX8QXP and IMX8QM is included.
> 
> It features decoding for the following formats:
> - H.264
> - HEVC
> - MPEG4
> - MPEG2
> - VC1
> - VP8
> 
> It features encoding for the following formats:
> - H.264
> 
> The driver creates a separate device node for the encoder and decoder.
> 
> This driver is dependent on vpu firmwares.
> The firmwares have been submitted to linux-firmware.
> The firmware patch is since commit
> b563148fd28623f6b6ce68bb06c3dd3bd138b058:
> linux-firmware: Update firmware file for Intel Bluetooth 9462
> (Fri Oct 8 16:30:14 2021 +0530)
> 
> and it's available in the git repository at:
>     https://github.com/mingqian-0/linux-firmware.git
> 
> for you to fetch changes up to bb3eee4f99589d4910dee4c053a3a685546b5dbb:
> amphion: add VPU firmwares for NXP i.MX8Q SoCs
> (Tue Oct 12 15:09:57 2021 +0800)
> 
> encoder is tested with gstreamer
> decoder is tested with gstreamer, but the following patches are required:
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1379
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1381
> 
> 
> Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>

For v15 please add this tag from Nicolas to the patch(es) that it applies to.
Tags in the cover letter are ignored.

Regarding patch 12/13 (firmware patch): who will take that? I think it should
go through Shawn Guo, or if he can Ack it, then I can take it with the rest of
the series as well.

Regards,

	Hans

> 
> 
> Changelog:
> 
> v14
> - fix some errors according to Hans's comments
> 
> v13
> - make a workaround that avoid firmware entering wfi wrongly
> 
> v12
> - support reset decoder when starting a new stream
> - don't append an empty last buffer, set last_buffer_dequeued
> - improve the resolution change flow
> - return all buffers if start_streaming fail
> - fill encoder capture buffer's filed to none
> - fix a bug in calculating bytesperline
> 
> v11
> - fix dt_binding_check error after upgrade dtschema
> - remove "default y"
> - add media device
> 
> v10
> - refine vpu log, remove custom logging infrastructure
> - support non contiguous planes format nv12m instead of nv12
> - rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
> - rename V4L2_PIX_FMT_NV12_10BE_8L128 to V4L2_PIX_FMT_NV12MT_10BE_8L128
> - merge two module into one
> - fix kernel panic in rmmod
> 
> v9
> - drop V4L2_BUF_FLAG_CODECCONFIG
> - drop V4L2_EVENT_CODEC_ERROR
> - drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
> - fix some build warnings with W=1 reported by kernel test robot
> 
> v8
> - move driver from driver/media/platform/imx/vpu-8q to
>   driver/media/platform/amphion
> - rename driver name to amphion
> - remove imx_vpu.h
> - move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
> - move the definition of V4L2_EVENT_SKIP to videodev2.h
> 
> v7
> - fix build warnings with W=1 reported by kernel test robot
> 
> v6:
> - rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
> - rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128
> 
> v5:
> - move some definition from imx_vph.h to videodev2.h
> - remove some unnecessary content
> - add some documentation descriptions
> - pass the lateset v4l2-compliance test
> 
> v4:
> - redefine the memory-region in devicetree bindings documentation
> - use v4l2's mechanism to implement synchronize queuing ioctl
> - remove the unnecessary mutex ioctl_sync
> - don't notify source change event if the parameters are same as previously established
> - add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format
> 
> v3:
> - don't make vpu device node a simple-bus
> - trigger probing vpu core in the driver
> - remove unnecessary vpu core index property
> 
> v2:
> - fix dt bindings build error
> - split driver patch into several parts to avoid exceeding bytes limit
> 
> Compliance
> ==========
> # v4l2-compliance -d /dev/video0
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/video0:
> 
> Driver Info:
> 	Driver name      : amphion-vpu
> 	Card type        : amphion vpu decoder
> 	Bus info         : platform: amphion-vpu
> 	Driver version   : 5.15.0
> 	Capabilities     : 0x84204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 		Device Capabilities
> 	Device Caps      : 0x04204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 	Detected Stateful Decoder
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> Interface Info:
> 	ID               : 0x0300000c
> 	Type             : V4L Video
> Entity Info:
> 	ID               : 0x00000001 (1)
> 	Name             : amphion-vpu-decoder-source
> 	Function         : V4L2 I/O
> 	Pad 0x01000002   : 0: Source
> 	  Link 0x02000008: to remote pad 0x1000004 of entity 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable
> 
> Required ioctls:
> 	test MC information (see 'Media Driver Info' above): OK
> 	test VIDIOC_QUERYCAP: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/video0 open: OK
> 	test VIDIOC_QUERYCAP: OK
> 	test VIDIOC_G/S_PRIORITY: OK
> 	test for unlimited opens: OK
> 
> Debug ioctls:
> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
> 
> Input ioctls:
> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
> 
> Output ioctls:
> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
> 
> Input/Output configuration ioctls:
> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> 	test VIDIOC_G/S_EDID: OK (Not Supported)
> 
> Control ioctls:
> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> 	test VIDIOC_QUERYCTRL: OK
> 	test VIDIOC_G/S_CTRL: OK
> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> 	Standard Controls: 3 Private Controls: 0
> 
> Format ioctls:
> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> 	test VIDIOC_G/S_PARM: OK (Not Supported)
> 	test VIDIOC_G_FBUF: OK (Not Supported)
> 	test VIDIOC_G_FMT: OK
> 	test VIDIOC_TRY_FMT: OK
> 	test VIDIOC_S_FMT: OK
> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> 	test Cropping: OK (Not Supported)
> 	test Composing: OK
> 	test Scaling: OK (Not Supported)
> 
> Codec ioctls:
> 	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> 	test VIDIOC_(TRY_)DECODER_CMD: OK
> 
> Buffer ioctls:
> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> 	test VIDIOC_EXPBUF: OK
> 	test Requests: OK (Not Supported)
> 
> Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0
> 
> # v4l2-compliance -d /dev/video1
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/video1:
> 
> Driver Info:
> 	Driver name      : amphion-vpu
> 	Card type        : amphion vpu encoder
> 	Bus info         : platform: amphion-vpu
> 	Driver version   : 5.15.0
> 	Capabilities     : 0x84204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 		Device Capabilities
> 	Device Caps      : 0x04204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 	Detected Stateful Encoder
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> Interface Info:
> 	ID               : 0x0300001a
> 	Type             : V4L Video
> Entity Info:
> 	ID               : 0x0000000f (15)
> 	Name             : amphion-vpu-encoder-source
> 	Function         : V4L2 I/O
> 	Pad 0x01000010   : 0: Source
> 	  Link 0x02000016: to remote pad 0x1000012 of entity 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable
> 
> Required ioctls:
> 	test MC information (see 'Media Driver Info' above): OK
> 	test VIDIOC_QUERYCAP: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/video1 open: OK
> 	test VIDIOC_QUERYCAP: OK
> 	test VIDIOC_G/S_PRIORITY: OK
> 	test for unlimited opens: OK
> 
> Debug ioctls:
> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
> 
> Input ioctls:
> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
> 
> Output ioctls:
> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
> 
> Input/Output configuration ioctls:
> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> 	test VIDIOC_G/S_EDID: OK (Not Supported)
> 
> Control ioctls:
> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> 	test VIDIOC_QUERYCTRL: OK
> 	test VIDIOC_G/S_CTRL: OK
> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> 	Standard Controls: 20 Private Controls: 0
> 
> Format ioctls:
> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> 	test VIDIOC_G/S_PARM: OK
> 	test VIDIOC_G_FBUF: OK (Not Supported)
> 	test VIDIOC_G_FMT: OK
> 	test VIDIOC_TRY_FMT: OK
> 	test VIDIOC_S_FMT: OK
> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> 	test Cropping: OK
> 	test Composing: OK (Not Supported)
> 	test Scaling: OK (Not Supported)
> 
> Codec ioctls:
> 	test VIDIOC_(TRY_)ENCODER_CMD: OK
> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> 	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
> 
> Buffer ioctls:
> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> 	test VIDIOC_EXPBUF: OK
> 	test Requests: OK (Not Supported)
> 
> Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed: 0, Warnings: 0
> 
> # v4l2-compliance -d /dev/media0
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/media0:
> 
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> 
> Required ioctls:
> 	test MEDIA_IOC_DEVICE_INFO: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/media0 open: OK
> 	test MEDIA_IOC_DEVICE_INFO: OK
> 	test for unlimited opens: OK
> 
> Media Controller ioctls:
> 	test MEDIA_IOC_G_TOPOLOGY: OK
> 	Entities: 6 Interfaces: 2 Pads: 8 Links: 8
> 	test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
> 	test MEDIA_IOC_SETUP_LINK: OK
> 
> Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0
> 
> Ming Qian (13):
>   dt-bindings: media: amphion: add amphion video codec bindings
>   media: add nv12m_8l128 and nv12m_10be_8l128 video format.
>   media: amphion: add amphion vpu device driver
>   media: amphion: add vpu core driver
>   media: amphion: implement vpu core communication based on mailbox
>   media: amphion: add vpu v4l2 m2m support
>   media: amphion: add v4l2 m2m vpu encoder stateful driver
>   media: amphion: add v4l2 m2m vpu decoder stateful driver
>   media: amphion: implement windsor encoder rpc interface
>   media: amphion: implement malone decoder rpc interface
>   ARM64: dts: freescale: imx8q: add imx vpu codec entries
>   firmware: imx: scu-pd: imx8q: add vpu mu resources
>   MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
> 
>  .../bindings/media/amphion,vpu.yaml           |  180 ++
>  .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
>  MAINTAINERS                                   |    9 +
>  .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
>  arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
>  arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
>  arch/arm64/configs/defconfig                  |    1 +
>  drivers/firmware/imx/scu-pd.c                 |    4 +
>  drivers/media/platform/Kconfig                |   19 +
>  drivers/media/platform/Makefile               |    2 +
>  drivers/media/platform/amphion/Makefile       |   20 +
>  drivers/media/platform/amphion/vdec.c         | 1692 +++++++++++++++++
>  drivers/media/platform/amphion/venc.c         | 1354 +++++++++++++
>  drivers/media/platform/amphion/vpu.h          |  356 ++++
>  drivers/media/platform/amphion/vpu_cmds.c     |  437 +++++
>  drivers/media/platform/amphion/vpu_cmds.h     |   25 +
>  drivers/media/platform/amphion/vpu_codec.h    |   67 +
>  drivers/media/platform/amphion/vpu_color.c    |  186 ++
>  drivers/media/platform/amphion/vpu_core.c     |  872 +++++++++
>  drivers/media/platform/amphion/vpu_core.h     |   15 +
>  drivers/media/platform/amphion/vpu_dbg.c      |  497 +++++
>  drivers/media/platform/amphion/vpu_defs.h     |  186 ++
>  drivers/media/platform/amphion/vpu_drv.c      |  260 +++
>  drivers/media/platform/amphion/vpu_helpers.c  |  416 ++++
>  drivers/media/platform/amphion/vpu_helpers.h  |   70 +
>  drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
>  drivers/media/platform/amphion/vpu_imx8q.h    |  116 ++
>  drivers/media/platform/amphion/vpu_malone.c   | 1630 ++++++++++++++++
>  drivers/media/platform/amphion/vpu_malone.h   |   42 +
>  drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
>  drivers/media/platform/amphion/vpu_mbox.h     |   16 +
>  drivers/media/platform/amphion/vpu_msgs.c     |  388 ++++
>  drivers/media/platform/amphion/vpu_msgs.h     |   14 +
>  drivers/media/platform/amphion/vpu_rpc.c      |  265 +++
>  drivers/media/platform/amphion/vpu_rpc.h      |  453 +++++
>  drivers/media/platform/amphion/vpu_v4l2.c     |  733 +++++++
>  drivers/media/platform/amphion/vpu_v4l2.h     |   56 +
>  drivers/media/platform/amphion/vpu_windsor.c  | 1207 ++++++++++++
>  drivers/media/platform/amphion/vpu_windsor.h  |   39 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
>  include/uapi/linux/videodev2.h                |    2 +
>  41 files changed, 12158 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
>  create mode 100644 drivers/media/platform/amphion/Makefile
>  create mode 100644 drivers/media/platform/amphion/vdec.c
>  create mode 100644 drivers/media/platform/amphion/venc.c
>  create mode 100644 drivers/media/platform/amphion/vpu.h
>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
>  create mode 100644 drivers/media/platform/amphion/vpu_codec.h
>  create mode 100644 drivers/media/platform/amphion/vpu_color.c
>  create mode 100644 drivers/media/platform/amphion/vpu_core.c
>  create mode 100644 drivers/media/platform/amphion/vpu_core.h
>  create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
>  create mode 100644 drivers/media/platform/amphion/vpu_defs.h
>  create mode 100644 drivers/media/platform/amphion/vpu_drv.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
>  create mode 100644 drivers/media/platform/amphion/vpu_malone.c
>  create mode 100644 drivers/media/platform/amphion/vpu_malone.h
>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.h
> 
> 
> base-commit: 1f1517fafda598839a02e39968c5063ddcfa51fc


From arnd at arndb.de  Thu Jan 20 06:57:27 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 20 Jan 2022 15:57:27 +0100
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <CAJF2gTRwh40xDBkoRJWZEUketKFDAy7_z=-WW7E=T46yH4zPvw@mail.gmail.com>
References: <20220120073911.99857-8-guoren@kernel.org>
 <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>
 <f16cf10425a14c2e8183d5c90667ce72@AcuMS.aculab.com>
 <CAJF2gTRwh40xDBkoRJWZEUketKFDAy7_z=-WW7E=T46yH4zPvw@mail.gmail.com>
Message-ID: <CAK8P3a3FLnqibdXCGR8c+mm92HSiuvocZDeW8MyoTO_L1sYT=w@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:27 PM Guo Ren <guoren at kernel.org> wrote:
> On Thu, Jan 20, 2022 at 8:53 PM David Laight <David.Laight at aculab.com> wrote:
> > I think the x86-64 32bit compat code even puts the boundary at 4GB.
> Yes, we could give rv32 compat for 4GB with some effort. But it's unnecessary.
>
> There are no history issues for rv32, we use compat mode to reduce
> memory footprint. eg: only 64MB memory available.
>
> At end compat for 4GB is another topic, let's give the initial compat
> for 2GB support to riscv.

I think it's fine either way. Having the entire 4GB space available is nice
when you are trying to build 32-bit software natively rather then using a
cross-compiler, as you can just do it on a larger machine that supports both.

One example of software that runs into virtual memory size limitations is
the gnu linker when building large applications, but it's unlikely that you'll
actually need to run applications that run into this, while also needing to
build them natively.

Using the same limit as on native 32-bit machines can help with compatibility
of certain software, but again this is rarely a problem and I have not seen any
reports of issues with the 4GB TASK_SIZE_32 on arm64. On x86, there
is an option to use the native 3GB TASK_SIZE for compat tasks. This was
introduced to work around buggy applications a long time ago, but is
probably not used any more in practice.

       Arnd


From angelogioacchino.delregno at collabora.com  Thu Jan 20 07:02:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 20 Jan 2022 16:02:44 +0100
Subject: [PATCH v5, 14/15] media: mtk-vcodec: support stateless VP8
 decoding
In-Reply-To: <20220117094001.20049-15-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
 <20220117094001.20049-15-yunfei.dong@mediatek.com>
Message-ID: <ce69e326-04b7-6866-92c3-50745b3a3d01@collabora.com>

Il 17/01/22 10:40, Yunfei Dong ha scritto:
> Add support for VP8 decoding using the stateless API,
> as supported by MT8192.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
>   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
>   .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  24 +-
>   .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
>   .../mtk-vcodec/vdec/vdec_vp8_req_if.c         | 440 ++++++++++++++++++
>   .../media/platform/mtk-vcodec/vdec_drv_if.c   |   4 +
>   .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
>   6 files changed, 469 insertions(+), 2 deletions(-)
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
> 

Hello Yunfei,
I've found some issues in this patch, and there are also some other considerations
to tidy it up.

(....snip....)

> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
> new file mode 100644
> index 000000000000..969568b98251
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
> @@ -0,0 +1,440 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong at mediatek.com>
> + */
> +
> +#include <linux/slab.h>
> +#include <media/v4l2-mem2mem.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <uapi/linux/v4l2-controls.h>
> +
> +#include "../mtk_vcodec_util.h"
> +#include "../mtk_vcodec_dec.h"
> +#include "../mtk_vcodec_intr.h"
> +#include "../vdec_drv_base.h"
> +#include "../vdec_drv_if.h"
> +#include "../vdec_vpu_if.h"
> +
> +/* Decoding picture buffer size (3 reference frames plus current frame) */
> +#define VP8_DPB_SIZE			4
> +
> +/* HW working buffer size (bytes) */
> +#define VP8_SEG_ID_SZ		(256 * 1024)

This is SZ_256K

> +#define VP8_PP_WRAPY_SZ		(64 * 1024)
> +#define VP8_PP_WRAPC_SZ		(64 * 1024)
> +#define VP8_VLD_PRED_SZ		(64 * 1024)

And these are all SZ_64K.

> +
> +/**
> + * struct vdec_vp8_slice_info - decode misc information
> + * @vld_wrapper_dma   : vld wrapper dma address
> + * @seg_id_buf_dma    : seg id dma address
> + * @wrap_y_dma        : wrap y dma address
> + * @wrap_c_dma        : wrap y dma address
> + * @cur_y_fb_dma      : current plane Y frame buffer dma address
> + * @cur_c_fb_dma      : current plane C frame buffer dma address
> + * @bs_dma            : bitstream dma address
> + * @bs_sz             : bitstream size
> + * @resolution_changed: resolution change flag 1 - changed,  0 - not change
> + * @frame_header_type : current frame header type
> + * @wait_key_frame    : wait key frame coming
> + * @crc               : used to check whether hardware's status is right
> + * @timeout           : decode timeout: 1 timeout, 0 no timeount

There's no `timeout` in this structure, did you forget to remove the
documentation for this one?

> + * @reserved:         : reserved, currently unused
> + */
> +struct vdec_vp8_slice_info {
> +	u64 vld_wrapper_dma;
> +	u64 seg_id_buf_dma;
> +	u64 wrap_y_dma;
> +	u64 wrap_c_dma;
> +	u64 cur_y_fb_dma;
> +	u64 cur_c_fb_dma;
> +	u64 bs_dma;
> +	u32 bs_sz;
> +	u32 resolution_changed;
> +	u32 frame_header_type;
> +	u32 crc[8];
> +	u32 reserved;
> +};
> +
> +/**
> + * struct vdec_vp8_slice_dpb_info  - vp8 reference information
> + * @y_dma_addr    : Y bitstream physical address
> + * @c_dma_addr    : CbCr bitstream physical address
> + * @reference_flag: reference picture flag
> + * @reserved      : 64bit align
> + */
> +struct vdec_vp8_slice_dpb_info {
> +	dma_addr_t y_dma_addr;
> +	dma_addr_t c_dma_addr;
> +	int reference_flag;
> +	int reserved;
> +};
> +
> +/**
> + * struct vdec_vp8_slice_vsi - VPU shared information
> + * @dec          : decoding information
> + * @pic          : picture information
> + * @vp8_dpb_info : reference buffer information
> + */
> +struct vdec_vp8_slice_vsi {
> +	struct vdec_vp8_slice_info dec;
> +	struct vdec_pic_info pic;
> +	struct vdec_vp8_slice_dpb_info vp8_dpb_info[3];
> +};
> +
> +/**
> + * struct vdec_vp8_slice_inst - VP8 decoder instance
> + * @seg_id_buf     : seg buffer
> + * @wrap_y_buf     : wrapper y buffer
> + * @wrap_c_buf     : wrapper c buffer
> + * @vld_wrapper_buf: vld wrapper buffer
> + * @ctx            : V4L2 context
> + * @vpu            : VPU instance for decoder
> + * @vsi            : VPU share information
> + */
> +struct vdec_vp8_slice_inst {
> +	struct mtk_vcodec_mem seg_id_buf;
> +	struct mtk_vcodec_mem wrap_y_buf;
> +	struct mtk_vcodec_mem wrap_c_buf;
> +	struct mtk_vcodec_mem vld_wrapper_buf;
> +	struct mtk_vcodec_ctx *ctx;
> +	struct vdec_vpu_inst vpu;
> +	struct vdec_vp8_slice_vsi *vsi;
> +};
> +
> +static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
> +{
> +	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
> +

You should check if ctrl is NULL here, and eventually return a ERR_PTR(-EINVAL)
if that ever occurs... or you may get a NULL pointer kernel panic...

> +	return ctrl->p_cur.p;
> +}
> +

...snip...

> +
> +static void vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst)

static int ..... ?

> +{
> +	const struct v4l2_ctrl_vp8_frame *frame_header =
> +		vdec_vp8_slice_get_ctrl_ptr(inst->ctx, V4L2_CTRL_TYPE_VP8_FRAME);

This is crashing the kernel, because it ends up being NULL...
... the solution to that is to look for V4L2_CID_STATELESS_VP8_FRAME instead of
V4L2_CTRL_TYPE_VP8_FRAME, but you should really do an error check here and
eventually bail out, in case anything goes horribly wrong...

> +	struct mtk_vcodec_ctx *ctx = inst->ctx;
> +	struct vb2_queue *vq;
> +	struct vb2_buffer *vb;
> +	u64 referenct_ts;
> +	int index, vb2_index;
> +

...so you'd be checking for error pointer of frame_header here and returning.

> +	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
> +	for (index = 0; index < 3; index++) {
> +		referenct_ts = vdec_vp8_slice_get_ref_by_ts(frame_header, index);
> +		vb2_index = vb2_find_timestamp(vq, referenct_ts, 0);
> +		if (vb2_index < 0) {
> +			if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header))
> +				mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)",
> +					       index, referenct_ts);
> +			inst->vsi->vp8_dpb_info[index].reference_flag = 0;
> +			continue;
> +		}
> +		inst->vsi->vp8_dpb_info[index].reference_flag = 1;
> +
> +		vb = vq->bufs[vb2_index];
> +		inst->vsi->vp8_dpb_info[index].y_dma_addr =
> +			vb2_dma_contig_plane_dma_addr(vb, 0);
> +		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
> +			inst->vsi->vp8_dpb_info[index].c_dma_addr =
> +				vb2_dma_contig_plane_dma_addr(vb, 1);
> +		else
> +			inst->vsi->vp8_dpb_info[index].c_dma_addr =
> +				inst->vsi->vp8_dpb_info[index].y_dma_addr +
> +				ctx->picinfo.fb_sz[0];
> +	}
> +
> +	inst->vsi->dec.frame_header_type = frame_header->flags >> 1;
> +}
> +
> +static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx)
> +{
> +	struct vdec_vp8_slice_inst *inst;
> +	int err;
> +
> +	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
> +	if (!inst)
> +		return -ENOMEM;
> +
> +	inst->ctx = ctx;
> +
> +	inst->vpu.id = SCP_IPI_VDEC_LAT;
> +	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
> +	inst->vpu.ctx = ctx;
> +	inst->vpu.codec_type = ctx->current_codec;
> +	inst->vpu.capture_type = ctx->capture_fourcc;
> +
> +	err = vpu_dec_init(&inst->vpu);
> +	if (err) {
> +		mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
> +		goto error_free_inst;
> +	}
> +
> +	inst->vsi = inst->vpu.vsi;
> +	err = vdec_vp8_slice_alloc_working_buf(inst);
> +	if (err)
> +		goto error_deinit;
> +
> +	mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n",
> +			 (int)sizeof(struct v4l2_ctrl_vp8_frame),
> +			 (int)sizeof(struct vdec_vp8_slice_vsi));
> +	mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p",
> +			 inst, inst->vpu.codec_type, inst->vpu.vsi);
> +
> +	ctx->drv_handle = inst;
> +	return 0;
> +
> +error_deinit:
> +	vpu_dec_deinit(&inst->vpu);
> +error_free_inst:
> +	kfree(inst);
> +	return err;
> +}
> +
> +static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> +				 struct vdec_fb *fb, bool *res_chg)
> +{
> +	struct vdec_vp8_slice_inst *inst = h_vdec;
> +	struct vdec_vpu_inst *vpu = &inst->vpu;
> +	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
> +	unsigned int data;
> +	u64 y_fb_dma, c_fb_dma;
> +	int err, timeout;
> +
> +	/* Resolution changes are never initiated by us */
> +	*res_chg = false;
> +
> +	/* bs NULL means flush decoder */
> +	if (!bs)
> +		return vpu_dec_reset(vpu);
> +
> +	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
> +
> +	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
> +	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
> +
> +	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
> +	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
> +		c_fb_dma = y_fb_dma +
> +			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
> +	else
> +		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
> +
> +	inst->vsi->dec.bs_dma = (unsigned long)bs->dma_addr;

inst->vsi->dec.bs_dma is u64... so please cast to u64.

> +	inst->vsi->dec.bs_sz = bs->size;
> +	inst->vsi->dec.cur_y_fb_dma = y_fb_dma;
> +	inst->vsi->dec.cur_c_fb_dma = c_fb_dma;
> +
> +	mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%lx) y/c(0x%llx 0x%llx)",
> +			 inst->ctx->decoded_frame_cnt,
> +			 bs->size, (unsigned long)bs->dma_addr,

...and it would be useful if it was u64 here too, obviously.

> +			 y_fb_dma, c_fb_dma);
> +
> +	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
> +				   &dst_buf_info->m2m_buf.vb, true);
> +
> +	vdec_vp8_slice_get_decode_parameters(inst);
> +	err = vpu_dec_start(vpu, &data, 1);
> +	if (err) {
> +		mtk_vcodec_debug(inst, "vp8 dec start err!");
> +		goto error;
> +	}

Regards,
Angelo



From pgwipeout at gmail.com  Thu Jan 20 07:06:43 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 20 Jan 2022 10:06:43 -0500
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
In-Reply-To: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
References: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
Message-ID: <CAMdYzYr+UXU-x=OakdHnOzLe1e4Y0xdGR-rybsmpLCMGbsWwXg@mail.gmail.com>

On Wed, Jan 19, 2022 at 8:52 AM <quentin.schulz at theobroma-systems.com> wrote:
>
> From: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
>
> There are signal integrity issues running the eMMC at 200MHz on Puma
> RK3399-Q7.
>
> Similar to the work-around found for RK3399 Gru boards, lowering the
> frequency to 100MHz made the eMMC much more stable, so let's lower the
> frequency to 100MHz.
>
> It might be possible to run at 150MHz as on RK3399 Gru boards but only
> 100MHz was extensively tested.
>
> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
> ---
>
> Note/RFC: as opposed to gru DTSI, max-frequency is used here instead of
> assigned-clock-rates.
>
> AFAIU, max-frequency applies to the SD bus rate, while
> assigned-clock-rates applies to the clock fed to the SD host controller
> inside the SoC. max-frequency does not interact with the clock subsystem
> AFAICT. assigned-clock-rates sets the clock rate at probe, regardless of
> eMMC tuning.
> Technically, the Arasan SDHC IP supports silicon-hardcoded clock
> multiplier so I think setting assigned-clock-rates as a way of rate
> limiting the eMMC block is incorrect and max-frequency should be used
> instead (as done in this patch). Otherwise the SDHC could still potentially
> derive a 200MHz clock from a lower rate clock thanks to its multiplier.
>
>  arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> index fb67db4619ea..a6108578aae0 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> @@ -425,6 +425,12 @@ vcc5v0_host_en: vcc5v0-host-en {
>  };
>
>  &sdhci {
> +       /*
> +        * Signal integrity isn't great at 200MHz but 100MHz has proven stable
> +        * enough.
> +        */
> +       max-frequency = <100000000>;
> +
>         bus-width = <8>;
>         mmc-hs400-1_8v;
>         mmc-hs400-enhanced-strobe;

I don't have these boards nor the schematics handy for them, but
wouldn't it be better to simply switch to mmc-hs200-1_8v?
Other rk3399 boards don't have issues with hs200 at full 200mhz, and
as I understand it hs400-es exhibits stability issues on most rk3399
boards.

Feel free to disregard my comments if you've already tested this.

> --
> 2.34.1
>
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From hverkuil-cisco at xs4all.nl  Thu Jan 20 07:09:47 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Jan 2022 16:09:47 +0100
Subject: [PATCH v14 06/13] media: amphion: add vpu v4l2 m2m support
In-Reply-To: <7cb9fcb62f0e24c48644ff86d4423564a318a39f.1638865027.git.ming.qian@nxp.com>
References: <cover.1638865027.git.ming.qian@nxp.com>
 <7cb9fcb62f0e24c48644ff86d4423564a318a39f.1638865027.git.ming.qian@nxp.com>
Message-ID: <af54768c-3366-863a-bcbb-baa9321770a5@xs4all.nl>

Hi Ming,

On 12/7/21 09:24, Ming Qian wrote:
> vpu_v4l2.c implements the v4l2 m2m driver methods.
> vpu_helpers.c implements the common helper functions
> vpu_color.c converts the v4l2 colorspace with
> the VUI parameters that specified by ITU-T | ISO/IEC
> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
> Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
> Reported-by: kernel test robot <lkp at intel.com>
> ---
>  drivers/media/platform/amphion/vpu_color.c   | 186 +++++
>  drivers/media/platform/amphion/vpu_helpers.c | 416 +++++++++++
>  drivers/media/platform/amphion/vpu_helpers.h |  70 ++
>  drivers/media/platform/amphion/vpu_v4l2.c    | 733 +++++++++++++++++++
>  drivers/media/platform/amphion/vpu_v4l2.h    |  56 ++
>  5 files changed, 1461 insertions(+)
>  create mode 100644 drivers/media/platform/amphion/vpu_color.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
> 
> diff --git a/drivers/media/platform/amphion/vpu_color.c b/drivers/media/platform/amphion/vpu_color.c
> new file mode 100644
> index 000000000000..1c062dc40306
> --- /dev/null
> +++ b/drivers/media/platform/amphion/vpu_color.c
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/ioctl.h>
> +#include <linux/list.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/types.h>
> +#include <media/v4l2-device.h>
> +#include "vpu.h"
> +#include "vpu_helpers.h"
> +
> +static const u8 colorprimaries[] = {
> +	0,
> +	V4L2_COLORSPACE_REC709,         /*Rec. ITU-R BT.709-6*/
> +	0,
> +	0,
> +	V4L2_COLORSPACE_470_SYSTEM_M,   /*Rec. ITU-R BT.470-6 System M*/
> +	V4L2_COLORSPACE_470_SYSTEM_BG,  /*Rec. ITU-R BT.470-6 System B, G*/
> +	V4L2_COLORSPACE_SMPTE170M,      /*SMPTE170M*/
> +	V4L2_COLORSPACE_SMPTE240M,      /*SMPTE240M*/
> +	0,                              /*Generic film*/
> +	V4L2_COLORSPACE_BT2020,         /*Rec. ITU-R BT.2020-2*/
> +	0,                              /*SMPTE ST 428-1*/
> +};
> +
> +static const u8 colortransfers[] = {
> +	0,
> +	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.709-6*/
> +	0,
> +	0,
> +	0,                              /*Rec. ITU-R BT.470-6 System M*/
> +	0,                              /*Rec. ITU-R BT.470-6 System B, G*/
> +	V4L2_XFER_FUNC_709,             /*SMPTE170M*/
> +	V4L2_XFER_FUNC_SMPTE240M,       /*SMPTE240M*/
> +	V4L2_XFER_FUNC_NONE,            /*Linear transfer characteristics*/
> +	0,
> +	0,
> +	0,                              /*IEC 61966-2-4*/
> +	0,                              /*Rec. ITU-R BT.1361-0 extended colour gamut*/
> +	V4L2_XFER_FUNC_SRGB,            /*IEC 61966-2-1 sRGB or sYCC*/
> +	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (10 bit system)*/
> +	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (12 bit system)*/
> +	V4L2_XFER_FUNC_SMPTE2084,       /*SMPTE ST 2084*/
> +	0,                              /*SMPTE ST 428-1*/
> +	0                               /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
> +};
> +
> +static const u8 colormatrixcoefs[] = {
> +	0,
> +	V4L2_YCBCR_ENC_709,              /*Rec. ITU-R BT.709-6*/
> +	0,
> +	0,
> +	0,                               /*Title 47 Code of Federal Regulations*/
> +	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 625*/
> +	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 525*/
> +	V4L2_YCBCR_ENC_SMPTE240M,        /*SMPTE240M*/
> +	0,
> +	V4L2_YCBCR_ENC_BT2020,           /*Rec. ITU-R BT.2020-2*/
> +	V4L2_YCBCR_ENC_BT2020_CONST_LUM  /*Rec. ITU-R BT.2020-2 constant*/
> +};
> +
> +u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
> +{
> +	return VPU_ARRAY_FIND(colorprimaries, primaries);
> +}
> +
> +u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
> +{
> +	return VPU_ARRAY_AT(colorprimaries, primaries);
> +}
> +
> +u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
> +{
> +	return VPU_ARRAY_FIND(colortransfers, transfers);
> +}
> +
> +u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
> +{
> +	return VPU_ARRAY_AT(colortransfers, transfers);
> +}
> +
> +u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
> +{
> +	return VPU_ARRAY_FIND(colormatrixcoefs, matrix);
> +}
> +
> +u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
> +{
> +	return VPU_ARRAY_AT(colormatrixcoefs, matrix);
> +}
> +
> +u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
> +{
> +	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
> +}
> +
> +u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
> +{
> +	if (full_range)
> +		return V4L2_QUANTIZATION_FULL_RANGE;
> +
> +	return V4L2_QUANTIZATION_LIM_RANGE;
> +}
> +
> +int vpu_color_check_primaries(u32 primaries)
> +{
> +	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
> +}
> +
> +int vpu_color_check_transfers(u32 transfers)
> +{
> +	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
> +}
> +
> +int vpu_color_check_matrix(u32 matrix)
> +{
> +	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
> +}
> +
> +int vpu_color_check_full_range(u32 full_range)
> +{
> +	int ret = -EINVAL;
> +
> +	switch (full_range) {
> +	case V4L2_QUANTIZATION_FULL_RANGE:
> +	case V4L2_QUANTIZATION_LIM_RANGE:
> +		ret = 0;
> +		break;
> +	default:
> +		break;
> +
> +	}
> +
> +	return ret;
> +}
> +
> +int vpu_color_get_default(u32 primaries,
> +		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
> +{
> +	u32 transfers;
> +	u32 matrix;
> +	u32 full_range;
> +
> +	switch (primaries) {
> +	case V4L2_COLORSPACE_REC709:
> +		transfers = V4L2_XFER_FUNC_709;
> +		matrix = V4L2_YCBCR_ENC_709;
> +		break;
> +	case V4L2_COLORSPACE_470_SYSTEM_M:
> +	case V4L2_COLORSPACE_470_SYSTEM_BG:
> +	case V4L2_COLORSPACE_SMPTE170M:
> +		transfers = V4L2_XFER_FUNC_709;
> +		matrix = V4L2_YCBCR_ENC_601;
> +		break;
> +	case V4L2_COLORSPACE_SMPTE240M:
> +		transfers = V4L2_XFER_FUNC_SMPTE240M;
> +		matrix = V4L2_YCBCR_ENC_SMPTE240M;
> +		break;
> +	case V4L2_COLORSPACE_BT2020:
> +		transfers = V4L2_XFER_FUNC_709;
> +		matrix = V4L2_YCBCR_ENC_BT2020;
> +		break;
> +	default:
> +		transfers = V4L2_XFER_FUNC_DEFAULT;
> +		matrix = V4L2_YCBCR_ENC_DEFAULT;
> +		break;
> +	}
> +	full_range = V4L2_QUANTIZATION_LIM_RANGE;
> +
> +	if (ptransfers)
> +		*ptransfers = transfers;
> +	if (pmatrix)
> +		*pmatrix = matrix;
> +	if (pfull_range)
> +		*pfull_range = full_range;
> +
> +
> +	return 0;
> +}
> diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c
> new file mode 100644
> index 000000000000..f41df259eb1e
> --- /dev/null
> +++ b/drivers/media/platform/amphion/vpu_helpers.c
> @@ -0,0 +1,416 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interconnect.h>
> +#include <linux/ioctl.h>
> +#include <linux/list.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/platform_device.h>
> +#include "vpu.h"
> +#include "vpu_core.h"
> +#include "vpu_rpc.h"
> +#include "vpu_helpers.h"
> +
> +int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
> +{
> +	int i;
> +
> +	for (i = 0; i < size; i++) {
> +		if (array[i] == x)
> +			return i;
> +	}
> +
> +	return 0;
> +}
> +
> +bool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
> +{
> +	const struct vpu_format *pfmt;
> +
> +	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
> +		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
> +			continue;
> +		if (pfmt->type == type)
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
> +const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
> +{
> +	const struct vpu_format *pfmt;
> +
> +	if (!inst || !inst->formats)
> +		return NULL;
> +
> +	if (!vpu_iface_check_format(inst, pixelfmt))
> +		return NULL;
> +
> +	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
> +		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
> +			return pfmt;
> +	}
> +
> +	return NULL;
> +}
> +
> +const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
> +{
> +	const struct vpu_format *pfmt;
> +	int i = 0;
> +
> +	if (!inst || !inst->formats)
> +		return NULL;
> +
> +	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
> +		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
> +			continue;
> +
> +		if (pfmt->type == type) {
> +			if (index == i)
> +				return pfmt;
> +			i++;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
> +{
> +	const struct vpu_core_resources *res;
> +
> +	if (!inst)
> +		return width;
> +
> +	res = vpu_get_resource(inst);
> +	if (!res)
> +		return width;
> +	if (res->max_width)
> +		width = clamp(width, res->min_width, res->max_width);
> +	if (res->step_width)
> +		width = ALIGN(width, res->step_width);
> +
> +	return width;
> +}
> +
> +u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
> +{
> +	const struct vpu_core_resources *res;
> +
> +	if (!inst)
> +		return height;
> +
> +	res = vpu_get_resource(inst);
> +	if (!res)
> +		return height;
> +	if (res->max_height)
> +		height = clamp(height, res->min_height, res->max_height);
> +	if (res->step_height)
> +		height = ALIGN(height, res->step_height);
> +
> +	return height;
> +}
> +
> +static u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
> +			u32 stride, u32 interlaced, u32 *pbl)
> +{
> +	u32 bytesperline;
> +	u32 size = 0;
> +
> +	bytesperline = ALIGN(width, stride);
> +	if (pbl)
> +		bytesperline = max(bytesperline, *pbl);
> +	height = ALIGN(height, 2);
> +	if (plane_no == 0)
> +		size = bytesperline * height;
> +	else if (plane_no == 1)
> +		size = bytesperline * height >> 1;
> +	if (pbl)
> +		*pbl = bytesperline;
> +
> +	return size;
> +}
> +
> +static u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
> +			u32 stride, u32 interlaced, u32 *pbl)
> +{
> +	u32 ws = 3;
> +	u32 hs = 7;
> +	u32 bitdepth = 8;
> +	u32 bytesperline;
> +	u32 size = 0;
> +
> +	if (interlaced)
> +		hs++;
> +	if (fmt == V4L2_PIX_FMT_NV12M_10BE_8L128)
> +		bitdepth = 10;
> +	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
> +	bytesperline = ALIGN(bytesperline, 1 << ws);
> +	bytesperline = ALIGN(bytesperline, stride);
> +	if (pbl)
> +		bytesperline = max(bytesperline, *pbl);
> +	height = ALIGN(height, 1 << hs);
> +	if (plane_no == 0)
> +		size = bytesperline * height;
> +	else if (plane_no == 1)
> +		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
> +	if (pbl)
> +		*pbl = bytesperline;
> +
> +	return size;
> +}
> +
> +static u32 get_default_plane_size(u32 width, u32 height, int plane_no,
> +			u32 stride, u32 interlaced, u32 *pbl)
> +{
> +	u32 bytesperline;
> +	u32 size = 0;
> +
> +	bytesperline = ALIGN(width, stride);
> +	if (pbl)
> +		bytesperline = max(bytesperline, *pbl);
> +	if (plane_no == 0)
> +		size = bytesperline * height;
> +	if (pbl)
> +		*pbl = bytesperline;
> +
> +	return size;
> +}
> +
> +u32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
> +		u32 stride, u32 interlaced, u32 *pbl)
> +{
> +	switch (fmt) {
> +	case V4L2_PIX_FMT_NV12M:
> +		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
> +	case V4L2_PIX_FMT_NV12M_8L128:
> +	case V4L2_PIX_FMT_NV12M_10BE_8L128:
> +		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
> +	default:
> +		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
> +	}
> +}
> +
> +u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
> +					u32 *rptr, u32 size, void *dst)
> +{
> +	u32 offset;
> +	u32 start;
> +	u32 end;
> +	void *virt;
> +
> +	if (!stream_buffer || !rptr || !dst)
> +		return -EINVAL;
> +
> +	if (!size)
> +		return 0;
> +
> +	offset = *rptr;
> +	start = stream_buffer->phys;
> +	end = start + stream_buffer->length;
> +	virt = stream_buffer->virt;
> +
> +	if (offset < start || offset > end)
> +		return -EINVAL;
> +
> +	if (offset + size <= end) {
> +		memcpy(dst, virt + (offset - start), size);
> +	} else {
> +		memcpy(dst, virt + (offset - start), end - offset);
> +		memcpy(dst + end - offset, virt, size + offset - end);
> +	}
> +
> +	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
> +	return size;
> +}
> +
> +u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
> +				u32 *wptr, u32 size, void *src)
> +{
> +	u32 offset;
> +	u32 start;
> +	u32 end;
> +	void *virt;
> +
> +	if (!stream_buffer || !wptr || !src)
> +		return -EINVAL;
> +
> +	if (!size)
> +		return 0;
> +
> +	offset = *wptr;
> +	start = stream_buffer->phys;
> +	end = start + stream_buffer->length;
> +	virt = stream_buffer->virt;
> +	if (offset < start || offset > end)
> +		return -EINVAL;
> +
> +	if (offset + size <= end) {
> +		memcpy(virt + (offset - start), src, size);
> +	} else {
> +		memcpy(virt + (offset - start), src, end - offset);
> +		memcpy(virt, src + end - offset, size + offset - end);
> +	}
> +
> +	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
> +
> +	return size;
> +}
> +
> +u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
> +				u32 *wptr, u8 val, u32 size)
> +{
> +	u32 offset;
> +	u32 start;
> +	u32 end;
> +	void *virt;
> +
> +	if (!stream_buffer || !wptr)
> +		return -EINVAL;
> +
> +	if (!size)
> +		return 0;
> +
> +	offset = *wptr;
> +	start = stream_buffer->phys;
> +	end = start + stream_buffer->length;
> +	virt = stream_buffer->virt;
> +	if (offset < start || offset > end)
> +		return -EINVAL;
> +
> +	if (offset + size <= end) {
> +		memset(virt + (offset - start), val, size);
> +	} else {
> +		memset(virt + (offset - start), val, end - offset);
> +		memset(virt, val, size + offset - end);
> +	}
> +
> +	offset += size;
> +	if (offset >= end)
> +		offset -= stream_buffer->length;
> +
> +	*wptr = offset;
> +
> +	return size;
> +}
> +
> +u32 vpu_helper_get_free_space(struct vpu_inst *inst)
> +{
> +	struct vpu_rpc_buffer_desc desc;
> +
> +	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
> +		return 0;
> +
> +	if (desc.rptr > desc.wptr)
> +		return desc.rptr - desc.wptr;
> +	else if (desc.rptr < desc.wptr)
> +		return (desc.end - desc.start + desc.rptr - desc.wptr);
> +	else
> +		return desc.end - desc.start;
> +}
> +
> +u32 vpu_helper_get_used_space(struct vpu_inst *inst)
> +{
> +	struct vpu_rpc_buffer_desc desc;
> +
> +	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
> +		return 0;
> +
> +	if (desc.wptr > desc.rptr)
> +		return desc.wptr - desc.rptr;
> +	else if (desc.wptr < desc.rptr)
> +		return (desc.end - desc.start + desc.wptr - desc.rptr);
> +	else
> +		return 0;
> +}
> +
> +int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct vpu_inst *inst = ctrl_to_inst(ctrl);
> +
> +	switch (ctrl->id) {
> +	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
> +		ctrl->val = inst->min_buffer_cap;
> +		break;
> +	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
> +		ctrl->val = inst->min_buffer_out;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +#define READ_BYTE(buffer, pos)	\
> +	(*(u8 *)((buffer)->virt + ((pos) % buffer->length)))
> +
> +int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
> +			u32 pixelformat, u32 offset, u32 bytesused)
> +{
> +	u32 start_code;
> +	int start_code_size;
> +	u32 val = 0;
> +	int i;
> +	int ret = -EINVAL;
> +
> +	if (!stream_buffer || !stream_buffer->virt)
> +		return -EINVAL;
> +
> +	switch (pixelformat) {
> +	case V4L2_PIX_FMT_H264:
> +		start_code_size = 4;
> +		start_code = 0x00000001;
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	for (i = 0; i < bytesused; i++) {
> +		val = (val << 8) | READ_BYTE(stream_buffer, offset + i);
> +		if (i < start_code_size - 1)
> +			continue;
> +		if (val == start_code) {
> +			ret = i + 1 - start_code_size;
> +			break;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
> +{
> +	u32 i;
> +
> +	if (!pairs || !cnt)
> +		return -EINVAL;
> +
> +	for (i = 0; i < cnt; i++) {
> +		if (pairs[i].src == src)
> +			return pairs[i].dst;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
> +{
> +	u32 i;
> +
> +	if (!pairs || !cnt)
> +		return -EINVAL;
> +
> +	for (i = 0; i < cnt; i++) {
> +		if (pairs[i].dst == dst)
> +			return pairs[i].src;
> +	}
> +
> +	return -EINVAL;
> +}
> diff --git a/drivers/media/platform/amphion/vpu_helpers.h b/drivers/media/platform/amphion/vpu_helpers.h
> new file mode 100644
> index 000000000000..8cb9b8c77745
> --- /dev/null
> +++ b/drivers/media/platform/amphion/vpu_helpers.h
> @@ -0,0 +1,70 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#ifndef _AMPHION_VPU_HELPERS_H
> +#define _AMPHION_VPU_HELPERS_H
> +
> +struct vpu_pair {
> +	u32 src;
> +	u32 dst;
> +};
> +
> +#define MAKE_TIMESTAMP(s, ns)		(((s32)(s) * NSEC_PER_SEC) + (ns))
> +#define VPU_INVALID_TIMESTAMP		MAKE_TIMESTAMP(-1, 0)
> +#define	VPU_ARRAY_AT(array, i)		(((i) < ARRAY_SIZE(array)) ? array[i] : 0)
> +#define VPU_ARRAY_FIND(array, x)	vpu_helper_find_in_array_u8(array, ARRAY_SIZE(array), x)
> +
> +int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x);
> +bool vpu_helper_check_type(struct vpu_inst *inst, u32 type);
> +const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt);
> +const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index);
> +u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width);
> +u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height);
> +u32 vpu_helper_get_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
> +					u32 stride, u32 interlaced, u32 *pbl);
> +u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
> +					u32 *rptr, u32 size, void *dst);
> +u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
> +				u32 *wptr, u32 size, void *src);
> +u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
> +				u32 *wptr, u8 val, u32 size);
> +u32 vpu_helper_get_free_space(struct vpu_inst *inst);
> +u32 vpu_helper_get_used_space(struct vpu_inst *inst);
> +int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
> +void vpu_helper_get_kmp_next(const u8 *pattern, int *next, int size);
> +int vpu_helper_kmp_search(u8 *s, int s_len, const u8 *p, int p_len, int *next);
> +int vpu_helper_kmp_search_in_stream_buffer(struct vpu_buffer *stream_buffer,
> +					u32 offset, int bytesused,
> +					const u8 *p, int p_len, int *next);
> +int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
> +			u32 pixelformat, u32 offset, u32 bytesused);
> +
> +static inline u32 vpu_helper_step_walk(struct vpu_buffer *stream_buffer, u32 pos, u32 step)
> +{
> +	pos += step;
> +	if (pos > stream_buffer->phys + stream_buffer->length)
> +		pos -= stream_buffer->length;
> +
> +	return pos;
> +}
> +
> +int vpu_color_check_primaries(u32 primaries);
> +int vpu_color_check_transfers(u32 transfers);
> +int vpu_color_check_matrix(u32 matrix);
> +int vpu_color_check_full_range(u32 full_range);
> +u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
> +u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
> +u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
> +u32 vpu_color_cvrt_transfers_i2v(u32 transfers);
> +u32 vpu_color_cvrt_matrix_v2i(u32 matrix);
> +u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
> +u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
> +u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
> +int vpu_color_get_default(u32 primaries,
> +		u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
> +
> +int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
> +int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
> +#endif
> diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
> new file mode 100644
> index 000000000000..a91690f691bc
> --- /dev/null
> +++ b/drivers/media/platform/amphion/vpu_v4l2.c
> @@ -0,0 +1,733 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interconnect.h>
> +#include <linux/ioctl.h>
> +#include <linux/list.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/videodev2.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-mem2mem.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-v4l2.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/videobuf2-vmalloc.h>
> +#include "vpu.h"
> +#include "vpu_core.h"
> +#include "vpu_v4l2.h"
> +#include "vpu_msgs.h"
> +#include "vpu_helpers.h"
> +
> +void vpu_inst_lock(struct vpu_inst *inst)
> +{
> +	mutex_lock(&inst->lock);
> +}
> +
> +void vpu_inst_unlock(struct vpu_inst *inst)
> +{
> +	mutex_unlock(&inst->lock);
> +}
> +
> +dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
> +{
> +	if (plane_no >= vb->num_planes)
> +		return 0;
> +	return vb2_dma_contig_plane_dma_addr(vb, plane_no) +
> +			vb->planes[plane_no].data_offset;
> +}
> +
> +unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
> +{
> +	if (plane_no >= vb->num_planes)
> +		return 0;
> +	return vb2_plane_size(vb, plane_no) - vb->planes[plane_no].data_offset;
> +}
> +
> +void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state)
> +{
> +	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
> +
> +	vpu_buf->state = state;
> +}
> +
> +unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
> +{
> +	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
> +
> +	return vpu_buf->state;
> +}
> +
> +void vpu_v4l2_set_error(struct vpu_inst *inst)
> +{
> +	struct vb2_queue *src_q;
> +	struct vb2_queue *dst_q;
> +
> +	if (!inst)
> +		return;
> +
> +	vpu_inst_lock(inst);
> +	dev_err(inst->dev, "some error occurs in codec\n");
> +	if (inst->fh.m2m_ctx) {
> +		src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
> +		dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
> +		if (src_q)
> +			src_q->error = 1;
> +		if (dst_q)
> +			dst_q->error = 1;
> +	}
> +	vpu_inst_unlock(inst);
> +}
> +
> +int vpu_notify_eos(struct vpu_inst *inst)
> +{
> +	static const struct v4l2_event ev = {
> +		.id = 0,
> +		.type = V4L2_EVENT_EOS
> +	};
> +
> +	vpu_trace(inst->dev, "[%d]\n", inst->id);
> +	v4l2_event_queue_fh(&inst->fh, &ev);
> +
> +	return 0;
> +}
> +
> +int vpu_notify_source_change(struct vpu_inst *inst)
> +{
> +	static const struct v4l2_event ev = {
> +		.id = 0,
> +		.type = V4L2_EVENT_SOURCE_CHANGE,
> +		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
> +	};
> +
> +	vpu_trace(inst->dev, "[%d]\n", inst->id);
> +	v4l2_event_queue_fh(&inst->fh, &ev);
> +	return 0;
> +}
> +
> +int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
> +{
> +	struct vb2_queue *q;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
> +	if (!list_empty(&q->done_list))
> +		return -EINVAL;
> +
> +	if (q->last_buffer_dequeued)
> +		return 0;
> +	vpu_trace(inst->dev, "last buffer dequeued\n");
> +	q->last_buffer_dequeued = true;
> +	wake_up(&q->done_wq);
> +	vpu_notify_eos(inst);
> +	return 0;
> +}
> +
> +const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst,
> +		 struct v4l2_format *f)
> +{
> +	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
> +	u32 type = f->type;
> +	u32 stride = 1;
> +	u32 bytesperline;
> +	u32 sizeimage;
> +	const struct vpu_format *fmt;
> +	const struct vpu_core_resources *res;
> +	int i;
> +
> +	fmt = vpu_helper_find_format(inst, type, pixmp->pixelformat);
> +	if (!fmt) {
> +		fmt = vpu_helper_enum_format(inst, type, 0);
> +		if (!fmt)
> +			return NULL;
> +		pixmp->pixelformat = fmt->pixfmt;
> +	}
> +
> +	res = vpu_get_resource(inst);
> +	if (res)
> +		stride = res->stride;
> +	if (pixmp->width)
> +		pixmp->width = vpu_helper_valid_frame_width(inst, pixmp->width);
> +	if (pixmp->height)
> +		pixmp->height = vpu_helper_valid_frame_height(inst, pixmp->height);
> +	pixmp->flags = fmt->flags;
> +	pixmp->num_planes = fmt->num_planes;
> +	if (pixmp->field == V4L2_FIELD_ANY)
> +		pixmp->field = V4L2_FIELD_NONE;
> +	for (i = 0; i < pixmp->num_planes; i++) {
> +		bytesperline = max_t(s32, pixmp->plane_fmt[i].bytesperline, 0);
> +		sizeimage = vpu_helper_get_plane_size(pixmp->pixelformat,
> +				pixmp->width, pixmp->height, i, stride,
> +				pixmp->field > V4L2_FIELD_NONE ? 1 : 0,
> +				&bytesperline);
> +		sizeimage = max_t(s32, pixmp->plane_fmt[i].sizeimage, sizeimage);
> +		pixmp->plane_fmt[i].bytesperline = bytesperline;
> +		pixmp->plane_fmt[i].sizeimage = sizeimage;
> +	}
> +
> +	return fmt;
> +}
> +
> +static bool vpu_check_ready(struct vpu_inst *inst, u32 type)
> +{
> +	if (!inst)
> +		return false;
> +	if (inst->state == VPU_CODEC_STATE_DEINIT || inst->id < 0)
> +		return false;
> +	if (!inst->ops->check_ready)
> +		return true;
> +	return call_vop(inst, check_ready, type);
> +}
> +
> +int vpu_process_output_buffer(struct vpu_inst *inst)
> +{
> +	struct v4l2_m2m_buffer *buf = NULL;
> +	struct vb2_v4l2_buffer *vbuf = NULL;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	if (!vpu_check_ready(inst, inst->out_format.type))
> +		return -EINVAL;
> +
> +	v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
> +		vbuf = &buf->vb;
> +		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
> +			break;
> +		vbuf = NULL;
> +	}
> +
> +	if (!vbuf)
> +		return -EINVAL;
> +
> +	dev_dbg(inst->dev, "[%d]frame id = %d / %d\n",
> +		inst->id, vbuf->sequence, inst->sequence);
> +	return call_vop(inst, process_output, &vbuf->vb2_buf);
> +}
> +
> +int vpu_process_capture_buffer(struct vpu_inst *inst)
> +{
> +	struct v4l2_m2m_buffer *buf = NULL;
> +	struct vb2_v4l2_buffer *vbuf = NULL;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	if (!vpu_check_ready(inst, inst->cap_format.type))
> +		return -EINVAL;
> +
> +	v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
> +		vbuf = &buf->vb;
> +		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
> +			break;
> +		vbuf = NULL;
> +	}
> +	if (!vbuf)
> +		return -EINVAL;
> +
> +	return call_vop(inst, process_capture, &vbuf->vb2_buf);
> +}
> +
> +struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst,
> +						u32 type, u32 sequence)
> +{
> +	struct v4l2_m2m_buffer *buf = NULL;
> +	struct vb2_v4l2_buffer *vbuf = NULL;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return NULL;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type)) {
> +		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
> +			vbuf = &buf->vb;
> +			if (vbuf->sequence == sequence)
> +				break;
> +			vbuf = NULL;
> +		}
> +	} else {
> +		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
> +			vbuf = &buf->vb;
> +			if (vbuf->sequence == sequence)
> +				break;
> +			vbuf = NULL;
> +		}
> +	}
> +
> +	return vbuf;
> +}
> +
> +struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst,
> +						u32 type, u32 idx)
> +{
> +	struct v4l2_m2m_buffer *buf = NULL;
> +	struct vb2_v4l2_buffer *vbuf = NULL;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return NULL;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type)) {
> +		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
> +			vbuf = &buf->vb;
> +			if (vbuf->vb2_buf.index == idx)
> +				break;
> +			vbuf = NULL;
> +		}
> +	} else {
> +		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
> +			vbuf = &buf->vb;
> +			if (vbuf->vb2_buf.index == idx)
> +				break;
> +			vbuf = NULL;
> +		}
> +	}
> +
> +	return vbuf;
> +}
> +
> +int vpu_get_num_buffers(struct vpu_inst *inst, u32 type)
> +{
> +	struct vb2_queue *q;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type))
> +		q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
> +	else
> +		q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
> +
> +	return q->num_buffers;
> +}
> +
> +static void vpu_m2m_device_run(void *priv)
> +{
> +}
> +
> +static void vpu_m2m_job_abort(void *priv)
> +{
> +	struct vpu_inst *inst = priv;
> +	struct v4l2_m2m_ctx *m2m_ctx = inst->fh.m2m_ctx;
> +
> +	v4l2_m2m_job_finish(m2m_ctx->m2m_dev, m2m_ctx);
> +}
> +
> +static const struct v4l2_m2m_ops vpu_m2m_ops = {
> +	.device_run = vpu_m2m_device_run,
> +	.job_abort = vpu_m2m_job_abort
> +};
> +
> +static int vpu_vb2_queue_setup(struct vb2_queue *vq,
> +				unsigned int *buf_count,
> +				unsigned int *plane_count,
> +				unsigned int psize[],
> +				struct device *allocators[])
> +{
> +	struct vpu_inst *inst = vb2_get_drv_priv(vq);
> +	struct vpu_format *cur_fmt;
> +	int i;
> +
> +	cur_fmt = vpu_get_format(inst, vq->type);
> +
> +	if (*plane_count) {
> +		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) {

Huh? This 'if' is really weird. Why do you need this?

> +			for (i = 0; i < *plane_count; i++) {
> +				if (!psize[i])

This should never happen when you use VIDIOC_CREATE_BUFS to add more buffers.

> +					psize[i] = cur_fmt->sizeimage[i];
> +			}
> +			return 0;

At minimum this needs comments, but it all looks very suspicious.

> +		}
> +		if (*plane_count != cur_fmt->num_planes)
> +			return -EINVAL;
> +		for (i = 0; i < cur_fmt->num_planes; i++) {
> +			if (psize[i] < cur_fmt->sizeimage[i])
> +				return -EINVAL;
> +		}
> +		return 0;
> +	}
> +
> +	*plane_count = cur_fmt->num_planes;
> +	for (i = 0; i < cur_fmt->num_planes; i++)
> +		psize[i] = cur_fmt->sizeimage[i];
> +
> +	return 0;
> +}
> +
> +static int vpu_vb2_buf_init(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +
> +	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
> +	return 0;
> +}
> +
> +static int vpu_vb2_buf_out_validate(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +
> +	vbuf->field = V4L2_FIELD_NONE;
> +
> +	return 0;
> +}
> +
> +static int vpu_vb2_buf_prepare(struct vb2_buffer *vb)
> +{
> +	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +	struct vpu_format *cur_fmt;
> +	u32 i;
> +
> +	cur_fmt = vpu_get_format(inst, vb->type);
> +	if (vb->num_planes != cur_fmt->num_planes)
> +		return -EINVAL;

This can't happen, so you can drop this.

> +	for (i = 0; i < cur_fmt->num_planes; i++) {
> +		if (vpu_get_vb_length(vb, i) < cur_fmt->sizeimage[i]) {
> +			dev_dbg(inst->dev, "[%d] %s buf[%d] is invalid\n",
> +					inst->id,
> +					vpu_type_name(vb->type),
> +					vb->index);
> +			vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
> +	struct vb2_queue *q = vb->vb2_queue;
> +
> +	if (vbuf->flags & V4L2_BUF_FLAG_LAST)
> +		vpu_notify_eos(inst);
> +
> +	if (list_empty(&q->done_list))
> +		call_vop(inst, on_queue_empty, q->type);
> +}
> +
> +void vpu_vb2_buffers_return(struct vpu_inst *inst,
> +		unsigned int type, enum vb2_buffer_state state)
> +{
> +	struct vb2_v4l2_buffer *buf;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type)) {
> +		while ((buf = v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx)))
> +			v4l2_m2m_buf_done(buf, state);
> +	} else {
> +		while ((buf = v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
> +			v4l2_m2m_buf_done(buf, state);
> +	}
> +}
> +
> +static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
> +{
> +	struct vpu_inst *inst = vb2_get_drv_priv(q);
> +	struct vpu_format *fmt = vpu_get_format(inst, q->type);
> +	int ret;
> +
> +	vpu_inst_unlock(inst);
> +	ret = vpu_inst_register(inst);
> +	vpu_inst_lock(inst);
> +	if (ret) {
> +		vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
> +		return ret;
> +	}
> +
> +	vpu_trace(inst->dev, "[%d] %s %c%c%c%c %dx%d %u(%u) %u(%u) %u(%u) %d\n",
> +			inst->id, vpu_type_name(q->type),
> +			fmt->pixfmt,
> +			fmt->pixfmt >> 8,
> +			fmt->pixfmt >> 16,
> +			fmt->pixfmt >> 24,
> +			fmt->width, fmt->height,
> +			fmt->sizeimage[0], fmt->bytesperline[0],
> +			fmt->sizeimage[1], fmt->bytesperline[1],
> +			fmt->sizeimage[2], fmt->bytesperline[2],
> +			q->num_buffers);
> +	call_vop(inst, start, q->type);
> +	vb2_clear_last_buffer_dequeued(q);
> +
> +	return 0;
> +}
> +
> +static void vpu_vb2_stop_streaming(struct vb2_queue *q)
> +{
> +	struct vpu_inst *inst = vb2_get_drv_priv(q);
> +
> +	vpu_trace(inst->dev, "[%d] %s\n", inst->id, vpu_type_name(q->type));
> +
> +	call_vop(inst, stop, q->type);
> +	vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_ERROR);
> +	if (V4L2_TYPE_IS_OUTPUT(q->type))
> +		inst->sequence = 0;
> +}
> +
> +static void vpu_vb2_buf_queue(struct vb2_buffer *vb)
> +{
> +	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> +	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return;
> +	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
> +		vbuf->sequence = inst->sequence++;
> +		if ((s64)vb->timestamp < 0)
> +			vb->timestamp = VPU_INVALID_TIMESTAMP;
> +	}
> +
> +	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
> +	vpu_process_output_buffer(inst);
> +	vpu_process_capture_buffer(inst);
> +}
> +
> +static struct vb2_ops vpu_vb2_ops = {
> +	.queue_setup        = vpu_vb2_queue_setup,
> +	.buf_init           = vpu_vb2_buf_init,
> +	.buf_out_validate   = vpu_vb2_buf_out_validate,
> +	.buf_prepare        = vpu_vb2_buf_prepare,
> +	.buf_finish         = vpu_vb2_buf_finish,
> +	.start_streaming    = vpu_vb2_start_streaming,
> +	.stop_streaming     = vpu_vb2_stop_streaming,
> +	.buf_queue          = vpu_vb2_buf_queue,
> +	.wait_prepare       = vb2_ops_wait_prepare,
> +	.wait_finish        = vb2_ops_wait_finish,
> +};
> +
> +static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq,
> +			  struct vb2_queue *dst_vq)
> +{
> +	struct vpu_inst *inst = priv;
> +	int ret;
> +
> +	inst->out_format.type = src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
> +	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> +	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> +	src_vq->ops = &vpu_vb2_ops;
> +	src_vq->mem_ops = &vb2_dma_contig_memops;
> +	if (inst->type == VPU_CORE_TYPE_DEC && inst->use_stream_buffer)
> +		src_vq->mem_ops = &vb2_vmalloc_memops;
> +	src_vq->drv_priv = inst;
> +	src_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
> +	src_vq->min_buffers_needed = 1;
> +	src_vq->dev = inst->vpu->dev;
> +	src_vq->lock = &inst->lock;
> +	ret = vb2_queue_init(src_vq);
> +	if (ret)
> +		return ret;
> +
> +	inst->cap_format.type = dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
> +	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
> +	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> +	dst_vq->ops = &vpu_vb2_ops;
> +	dst_vq->mem_ops = &vb2_dma_contig_memops;
> +	if (inst->type == VPU_CORE_TYPE_ENC && inst->use_stream_buffer)
> +		dst_vq->mem_ops = &vb2_vmalloc_memops;
> +	dst_vq->drv_priv = inst;
> +	dst_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
> +	dst_vq->min_buffers_needed = 1;
> +	dst_vq->dev = inst->vpu->dev;
> +	dst_vq->lock = &inst->lock;
> +	ret = vb2_queue_init(dst_vq);
> +	if (ret) {
> +		vb2_queue_release(src_vq);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int vpu_v4l2_release(struct vpu_inst *inst)
> +{
> +	vpu_trace(inst->vpu->dev, "%p\n", inst);
> +
> +	vpu_release_core(inst->core);
> +	put_device(inst->dev);
> +
> +	if (inst->workqueue) {
> +		cancel_work_sync(&inst->msg_work);
> +		destroy_workqueue(inst->workqueue);
> +		inst->workqueue = NULL;
> +	}
> +
> +	v4l2_ctrl_handler_free(&inst->ctrl_handler);
> +	mutex_destroy(&inst->lock);
> +	v4l2_fh_del(&inst->fh);
> +	v4l2_fh_exit(&inst->fh);
> +
> +	call_vop(inst, cleanup);
> +
> +	return 0;
> +}
> +
> +int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
> +{
> +	struct vpu_dev *vpu = video_drvdata(file);
> +	struct vpu_func *func;
> +	int ret = 0;
> +
> +	if (!file || !inst || !inst->ops)
> +		return -EINVAL;
> +
> +	if (inst->type == VPU_CORE_TYPE_ENC)
> +		func = &vpu->encoder;
> +	else
> +		func = &vpu->decoder;
> +
> +	atomic_set(&inst->ref_count, 0);
> +	vpu_inst_get(inst);
> +	inst->vpu = vpu;
> +	inst->core = vpu_request_core(vpu, inst->type);
> +	if (inst->core)
> +		inst->dev = get_device(inst->core->dev);
> +	mutex_init(&inst->lock);
> +	INIT_LIST_HEAD(&inst->cmd_q);
> +	inst->id = VPU_INST_NULL_ID;
> +	inst->release = vpu_v4l2_release;
> +	inst->pid = current->pid;
> +	inst->tgid = current->tgid;
> +	inst->min_buffer_cap = 2;
> +	inst->min_buffer_out = 2;
> +	v4l2_fh_init(&inst->fh, func->vfd);
> +	v4l2_fh_add(&inst->fh);
> +
> +	ret = call_vop(inst, ctrl_init);
> +	if (ret)
> +		goto error;
> +
> +	inst->fh.m2m_ctx = v4l2_m2m_ctx_init(func->m2m_dev,
> +					inst, vpu_m2m_queue_init);
> +	if (IS_ERR(inst->fh.m2m_ctx)) {
> +		dev_err(vpu->dev, "v4l2_m2m_ctx_init fail\n");
> +		ret = PTR_ERR(func->m2m_dev);
> +		goto error;
> +	}
> +
> +	inst->fh.ctrl_handler = &inst->ctrl_handler;
> +	file->private_data = &inst->fh;
> +	inst->state = VPU_CODEC_STATE_DEINIT;
> +	inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
> +	if (inst->workqueue) {
> +		INIT_WORK(&inst->msg_work, vpu_inst_run_work);
> +		ret = kfifo_init(&inst->msg_fifo,
> +				inst->msg_buffer,
> +				roundup_pow_of_two(sizeof(inst->msg_buffer)));
> +		if (ret) {
> +			destroy_workqueue(inst->workqueue);
> +			inst->workqueue = NULL;
> +		}
> +	}
> +	vpu_trace(vpu->dev, "tgid = %d, pid = %d, type = %s, inst = %p\n",
> +			inst->tgid, inst->pid, vpu_core_type_desc(inst->type), inst);
> +
> +	return 0;
> +error:
> +	vpu_inst_put(inst);
> +	return ret;
> +}
> +
> +int vpu_v4l2_close(struct file *file)
> +{
> +	struct vpu_dev *vpu = video_drvdata(file);
> +	struct vpu_inst *inst = to_inst(file);
> +
> +	vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n",
> +			inst->tgid, inst->pid, inst);
> +
> +	vpu_inst_lock(inst);
> +	if (inst->fh.m2m_ctx) {
> +		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
> +		inst->fh.m2m_ctx = NULL;
> +	}
> +	vpu_inst_unlock(inst);
> +
> +	call_vop(inst, release);
> +	vpu_inst_unregister(inst);
> +	vpu_inst_put(inst);
> +
> +	return 0;
> +}
> +
> +int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
> +{
> +	struct video_device *vfd;
> +	int ret;
> +
> +	if (!vpu || !func)
> +		return -EINVAL;
> +
> +	if (func->vfd)
> +		return 0;
> +
> +	func->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
> +	if (IS_ERR(func->m2m_dev)) {
> +		dev_err(vpu->dev, "v4l2_m2m_init fail\n");
> +		func->vfd = NULL;
> +		return PTR_ERR(func->m2m_dev);
> +	}
> +
> +	vfd = video_device_alloc();
> +	if (!vfd) {
> +		v4l2_m2m_release(func->m2m_dev);
> +		dev_err(vpu->dev, "alloc vpu decoder video device fail\n");
> +		return -ENOMEM;
> +	}
> +	vfd->release = video_device_release;
> +	vfd->vfl_dir = VFL_DIR_M2M;
> +	vfd->v4l2_dev = &vpu->v4l2_dev;
> +	vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
> +	if (func->type == VPU_CORE_TYPE_ENC) {
> +		strscpy(vfd->name, "amphion-vpu-encoder", sizeof(vfd->name));
> +		vfd->fops = venc_get_fops();
> +		vfd->ioctl_ops = venc_get_ioctl_ops();
> +	} else {
> +		strscpy(vfd->name, "amphion-vpu-decoder", sizeof(vfd->name));
> +		vfd->fops = vdec_get_fops();
> +		vfd->ioctl_ops = vdec_get_ioctl_ops();
> +	}
> +
> +	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
> +	if (ret) {
> +		video_device_release(vfd);
> +		v4l2_m2m_release(func->m2m_dev);
> +		return ret;
> +	}
> +	video_set_drvdata(vfd, vpu);
> +	func->vfd = vfd;
> +
> +	ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);
> +	if (ret) {
> +		v4l2_m2m_release(func->m2m_dev);
> +		func->m2m_dev = NULL;
> +		video_unregister_device(func->vfd);
> +		func->vfd = NULL;
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +void vpu_remove_func(struct vpu_func *func)
> +{
> +	if (!func)
> +		return;
> +
> +	if (func->m2m_dev) {
> +		v4l2_m2m_unregister_media_controller(func->m2m_dev);
> +		v4l2_m2m_release(func->m2m_dev);
> +		func->m2m_dev = NULL;
> +	}
> +	if (func->vfd) {
> +		video_unregister_device(func->vfd);
> +		func->vfd = NULL;
> +	}
> +}
> diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h
> new file mode 100644
> index 000000000000..17aa36603f82
> --- /dev/null
> +++ b/drivers/media/platform/amphion/vpu_v4l2.h
> @@ -0,0 +1,56 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#ifndef _AMPHION_VPU_V4L2_H
> +#define _AMPHION_VPU_V4L2_H
> +
> +#include <linux/videodev2.h>
> +
> +void vpu_inst_lock(struct vpu_inst *inst);
> +void vpu_inst_unlock(struct vpu_inst *inst);
> +void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state);
> +unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf);
> +
> +int vpu_v4l2_open(struct file *file, struct vpu_inst *inst);
> +int vpu_v4l2_close(struct file *file);
> +
> +const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
> +int vpu_process_output_buffer(struct vpu_inst *inst);
> +int vpu_process_capture_buffer(struct vpu_inst *inst);
> +struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
> +struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
> +void vpu_v4l2_set_error(struct vpu_inst *inst);
> +int vpu_notify_eos(struct vpu_inst *inst);
> +int vpu_notify_source_change(struct vpu_inst *inst);
> +int vpu_set_last_buffer_dequeued(struct vpu_inst *inst);
> +void vpu_vb2_buffers_return(struct vpu_inst *inst,
> +		unsigned int type, enum vb2_buffer_state state);
> +int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
> +
> +dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
> +unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
> +static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
> +{
> +	if (V4L2_TYPE_IS_OUTPUT(type))
> +		return &inst->out_format;
> +	else
> +		return &inst->cap_format;
> +}
> +
> +static inline char *vpu_type_name(u32 type)
> +{
> +	return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
> +}
> +
> +static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf)
> +{
> +#ifdef V4L2_BUF_FLAG_CODECCONFIG
> +	return (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) ? 1 : 0;
> +#else
> +	return 0;
> +#endif
> +}
> +
> +#endif


From angelogioacchino.delregno at collabora.com  Thu Jan 20 07:10:45 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 20 Jan 2022 16:10:45 +0100
Subject: [PATCH v5, 12/15] media: mtk-vcodec: Extract H264 common code
In-Reply-To: <20220117094001.20049-13-yunfei.dong@mediatek.com>
References: <20220117094001.20049-1-yunfei.dong@mediatek.com>
 <20220117094001.20049-13-yunfei.dong@mediatek.com>
Message-ID: <651387eb-561f-06b4-f269-7b5f7873fc59@collabora.com>

Il 17/01/22 10:39, Yunfei Dong ha scritto:
> Mt8192 can use some of common code with mt8183. Moves them to
> a new file in order to reuse.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
>   drivers/media/platform/mtk-vcodec/Makefile    |   1 +
>   .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 307 ++++++++++++++
>   .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 253 +++++++++++
>   .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 395 +-----------------
>   4 files changed, 579 insertions(+), 377 deletions(-)
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
>   create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
> 
> diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
> index 359619653a0e..3f41d748eee5 100644
> --- a/drivers/media/platform/mtk-vcodec/Makefile
> +++ b/drivers/media/platform/mtk-vcodec/Makefile
> @@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
>   		vdec/vdec_vp8_if.o \
>   		vdec/vdec_vp9_if.o \
>   		vdec/vdec_h264_req_if.o \
> +		vdec/vdec_h264_req_common.o \
>   		mtk_vcodec_dec_drv.o \
>   		vdec_drv_if.o \
>   		vdec_vpu_if.o \
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
> new file mode 100644
> index 000000000000..90e8c4906e2a
> --- /dev/null
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
> @@ -0,0 +1,307 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Author: Yunfei Dong <yunfei.dong at mediatek.com>
> + */
> +
> +#include "vdec_h264_req_common.h"
> +
> +/* get used parameters for sps/pps */
> +#define GET_MTK_VDEC_FLAG(cond, flag) \
> +	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
> +#define GET_MTK_VDEC_PARAM(param) \
> +	{ dst_param->param = src_param->param; }
> +
> +/*
> + * The firmware expects unused reflist entries to have the value 0x20.
> + */
> +void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
> +{
> +	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
> +}
> +
> +void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
> +{
> +	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
> +

Like written in the review for the VP8 driver, please perform a NULL check and
handle the error case properly in the caller...

> +	return ctrl->p_cur.p;
> +}
> +
> +void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
> +				 struct slice_api_h264_decode_param *decode_params,
> +				 mtk_h264_dpb_info *h264_dpb_info)

				struct mtk_h264_dpb_info *h264_dpb_info)
				^^^^^^
Oops! This typo makes this code unable to be compiled.

> +{
> +	struct vb2_queue *vq;
> +	struct vb2_buffer *vb;
> +	struct vb2_v4l2_buffer *vb2_v4l2;
> +	int index;
> +
> +	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
> +
> +	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
> +		const struct slice_h264_dpb_entry *dpb;
> +		int vb2_index;
> +

...snip...

> +void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
> +				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
> +{
> +	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
> +	       sizeof(dst_matrix->scaling_list_4x4));
> +
> +	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
> +	       sizeof(dst_matrix->scaling_list_8x8));
> +}
> +
> +void
> +mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
> +				 const struct v4l2_ctrl_h264_decode_params *src_params,
> +				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);

There's another overlook here:
				const struct v4l2_h264_dpb_entry *dpb)

> +{
> +	int i;

Regards,
Angelo


From alexandru.elisei at arm.com  Thu Jan 20 07:12:54 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 20 Jan 2022 15:12:54 +0000
Subject: [PATCH v5 18/69] KVM: arm64: nv: Handle virtual EL2 registers in
 vcpu_read/write_sys_reg()
In-Reply-To: <20211129200150.351436-19-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-19-maz@kernel.org>
Message-ID: <Yel79mQSV/8iINrS@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:00:59PM +0000, Marc Zyngier wrote:
> KVM internally uses accessor functions when reading or writing the
> guest's system registers. This takes care of accessing either the stored
> copy or using the "live" EL1 system registers when the host uses VHE.
> 
> With the introduction of virtual EL2 we add a bunch of EL2 system
> registers, which now must also be taken care of:
> - If the guest is running in vEL2, and we access an EL1 sysreg, we must
>   revert to the stored version of that, and not use the CPU's copy.
> - If the guest is running in vEL1, and we access an EL2 sysreg, we must
>   also use the stored version, since the CPU carries the EL1 copy.
> - Some EL2 system registers are supposed to affect the current execution
>   of the system, so we need to put them into their respective EL1
>   counterparts. For this we need to define a mapping between the two.
>   This is done using the newly introduced struct el2_sysreg_map.
> - Some EL2 system registers have a different format than their EL1
>   counterpart, so we need to translate them before writing them to the
>   CPU. This is done using an (optional) translate function in the map.
> - There are the three special registers SP_EL2, SPSR_EL2 and ELR_EL2,
>   which need some separate handling (SPSR_EL2 is being handled in a
>   separate patch).
> 
> All of these cases are now wrapped into the existing accessor functions,
> so KVM users wouldn't need to care whether they access EL2 or EL1
> registers and also which state the guest is in.
> 
> This handles what was formerly known as the "shadow state" dynamically,
> without requiring a separate copy for each vCPU EL.
> 
> Co-developed-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/sys_regs.c | 143 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 139 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 730a24468915..61596355e42d 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -24,6 +24,7 @@
>  #include <asm/kvm_emulate.h>
>  #include <asm/kvm_hyp.h>
>  #include <asm/kvm_mmu.h>
> +#include <asm/kvm_nested.h>
>  #include <asm/perf_event.h>
>  #include <asm/sysreg.h>
>  
> @@ -64,23 +65,157 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu,
>  	return false;
>  }
>  
> +#define PURE_EL2_SYSREG(el2)						\
> +	case el2: {							\
> +		*el1r = el2;						\
> +		return true;						\
> +	}
> +
> +#define MAPPED_EL2_SYSREG(el2, el1, fn)					\
> +	case el2: {							\
> +		*xlate = fn;						\
> +		*el1r = el1;						\
> +		return true;						\
> +	}
> +
> +static bool get_el2_mapping(unsigned int reg,
> +			    unsigned int *el1r, u64 (**xlate)(u64))

Nitpick: this could be renamed to get_el2_to_el1_mapping() to remove any
ambiguities regarding what is being mapped to what (and to match the
translate_* functions). With our without this change, the patch looks
correct to me:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,
Alex

> +{
> +	switch (reg) {
> +		PURE_EL2_SYSREG(  VPIDR_EL2	);
> +		PURE_EL2_SYSREG(  VMPIDR_EL2	);
> +		PURE_EL2_SYSREG(  ACTLR_EL2	);
> +		PURE_EL2_SYSREG(  HCR_EL2	);
> +		PURE_EL2_SYSREG(  MDCR_EL2	);
> +		PURE_EL2_SYSREG(  HSTR_EL2	);
> +		PURE_EL2_SYSREG(  HACR_EL2	);
> +		PURE_EL2_SYSREG(  VTTBR_EL2	);
> +		PURE_EL2_SYSREG(  VTCR_EL2	);
> +		PURE_EL2_SYSREG(  RVBAR_EL2	);
> +		PURE_EL2_SYSREG(  TPIDR_EL2	);
> +		PURE_EL2_SYSREG(  HPFAR_EL2	);
> +		PURE_EL2_SYSREG(  ELR_EL2	);
> +		PURE_EL2_SYSREG(  SPSR_EL2	);
> +		MAPPED_EL2_SYSREG(SCTLR_EL2,   SCTLR_EL1,
> +				  translate_sctlr_el2_to_sctlr_el1	     );
> +		MAPPED_EL2_SYSREG(CPTR_EL2,    CPACR_EL1,
> +				  translate_cptr_el2_to_cpacr_el1	     );
> +		MAPPED_EL2_SYSREG(TTBR0_EL2,   TTBR0_EL1,
> +				  translate_ttbr0_el2_to_ttbr0_el1	     );
> +		MAPPED_EL2_SYSREG(TTBR1_EL2,   TTBR1_EL1,   NULL	     );
> +		MAPPED_EL2_SYSREG(TCR_EL2,     TCR_EL1,
> +				  translate_tcr_el2_to_tcr_el1		     );
> +		MAPPED_EL2_SYSREG(VBAR_EL2,    VBAR_EL1,    NULL	     );
> +		MAPPED_EL2_SYSREG(AFSR0_EL2,   AFSR0_EL1,   NULL	     );
> +		MAPPED_EL2_SYSREG(AFSR1_EL2,   AFSR1_EL1,   NULL	     );
> +		MAPPED_EL2_SYSREG(ESR_EL2,     ESR_EL1,     NULL	     );
> +		MAPPED_EL2_SYSREG(FAR_EL2,     FAR_EL1,     NULL	     );
> +		MAPPED_EL2_SYSREG(MAIR_EL2,    MAIR_EL1,    NULL	     );
> +		MAPPED_EL2_SYSREG(AMAIR_EL2,   AMAIR_EL1,   NULL	     );
> +		MAPPED_EL2_SYSREG(CNTHCTL_EL2, CNTKCTL_EL1,
> +				  translate_cnthctl_el2_to_cntkctl_el1	     );
> +	default:
> +		return false;
> +	}
> +}
> +
>  u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
>  {
>  	u64 val = 0x8badf00d8badf00d;
> +	u64 (*xlate)(u64) = NULL;
> +	unsigned int el1r;
> +
> +	if (!vcpu->arch.sysregs_loaded_on_cpu)
> +		goto memory_read;
> +
> +	if (unlikely(get_el2_mapping(reg, &el1r, &xlate))) {
> +		if (!is_hyp_ctxt(vcpu))
> +			goto memory_read;
> +
> +		/*
> +		 * ELR_EL2 is special cased for now.
> +		 */
> +		switch (reg) {
> +		case ELR_EL2:
> +			return read_sysreg_el1(SYS_ELR);
> +		}
> +
> +		/*
> +		 * If this register does not have an EL1 counterpart,
> +		 * then read the stored EL2 version.
> +		 */
> +		if (reg == el1r)
> +			goto memory_read;
> +
> +		/*
> +		 * If we have a non-VHE guest and that the sysreg
> +		 * requires translation to be used at EL1, use the
> +		 * in-memory copy instead.
> +		 */
> +		if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
> +			goto memory_read;
> +
> +		/* Get the current version of the EL1 counterpart. */
> +		WARN_ON(!__vcpu_read_sys_reg_from_cpu(el1r, &val));
> +		return val;
> +	}
> +
> +	/* EL1 register can't be on the CPU if the guest is in vEL2. */
> +	if (unlikely(is_hyp_ctxt(vcpu)))
> +		goto memory_read;
>  
> -	if (vcpu->arch.sysregs_loaded_on_cpu &&
> -	    __vcpu_read_sys_reg_from_cpu(reg, &val))
> +	if (__vcpu_read_sys_reg_from_cpu(reg, &val))
>  		return val;
>  
> +memory_read:
>  	return __vcpu_sys_reg(vcpu, reg);
>  }
>  
>  void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
>  {
> -	if (vcpu->arch.sysregs_loaded_on_cpu &&
> -	    __vcpu_write_sys_reg_to_cpu(val, reg))
> +	u64 (*xlate)(u64) = NULL;
> +	unsigned int el1r;
> +
> +	if (!vcpu->arch.sysregs_loaded_on_cpu)
> +		goto memory_write;
> +
> +	if (unlikely(get_el2_mapping(reg, &el1r, &xlate))) {
> +		if (!is_hyp_ctxt(vcpu))
> +			goto memory_write;
> +
> +		/*
> +		 * Always store a copy of the write to memory to avoid having
> +		 * to reverse-translate virtual EL2 system registers for a
> +		 * non-VHE guest hypervisor.
> +		 */
> +		__vcpu_sys_reg(vcpu, reg) = val;
> +
> +		switch (reg) {
> +		case ELR_EL2:
> +			write_sysreg_el1(val, SYS_ELR);
> +			return;
> +		}
> +
> +		/* No EL1 counterpart? We're done here.? */
> +		if (reg == el1r)
> +			return;
> +
> +		if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
> +			val = xlate(val);
> +
> +		/* Redirect this to the EL1 version of the register. */
> +		WARN_ON(!__vcpu_write_sys_reg_to_cpu(val, el1r));
> +		return;
> +	}
> +
> +	/* EL1 register can't be on the CPU if the guest is in vEL2. */
> +	if (unlikely(is_hyp_ctxt(vcpu)))
> +		goto memory_write;
> +
> +	if (__vcpu_write_sys_reg_to_cpu(val, reg))
>  		return;
>  
> +memory_write:
>  	 __vcpu_sys_reg(vcpu, reg) = val;
>  }
>  
> -- 
> 2.30.2
> 


From hverkuil-cisco at xs4all.nl  Thu Jan 20 07:17:08 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Thu, 20 Jan 2022 16:17:08 +0100
Subject: [PATCH v14 07/13] media: amphion: add v4l2 m2m vpu encoder
 stateful driver
In-Reply-To: <21224efcf6e54e021a3e0f594f2b503247f77f74.1638865027.git.ming.qian@nxp.com>
References: <cover.1638865027.git.ming.qian@nxp.com>
 <21224efcf6e54e021a3e0f594f2b503247f77f74.1638865027.git.ming.qian@nxp.com>
Message-ID: <2115e687-760e-bbcf-244a-ee0ffe8921b8@xs4all.nl>

Hi Ming,

Some comments below:

On 12/7/21 09:24, Ming Qian wrote:
> This consists of video encoder implementation plus encoder controls.
> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
> Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
> ---
>  drivers/media/platform/amphion/venc.c | 1354 +++++++++++++++++++++++++
>  1 file changed, 1354 insertions(+)
>  create mode 100644 drivers/media/platform/amphion/venc.c
> 
> diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
> new file mode 100644
> index 000000000000..ca394504dbd8
> --- /dev/null
> +++ b/drivers/media/platform/amphion/venc.c
> @@ -0,0 +1,1354 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright 2020-2021 NXP
> + */
> +
> +#include <linux/init.h>
> +#include <linux/interconnect.h>
> +#include <linux/ioctl.h>
> +#include <linux/list.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/delay.h>
> +#include <linux/videodev2.h>
> +#include <linux/ktime.h>
> +#include <linux/rational.h>
> +#include <media/v4l2-device.h>
> +#include <media/v4l2-event.h>
> +#include <media/v4l2-mem2mem.h>
> +#include <media/v4l2-ioctl.h>
> +#include <media/videobuf2-v4l2.h>
> +#include <media/videobuf2-dma-contig.h>
> +#include <media/videobuf2-vmalloc.h>
> +#include "vpu.h"
> +#include "vpu_defs.h"
> +#include "vpu_core.h"
> +#include "vpu_helpers.h"
> +#include "vpu_v4l2.h"
> +#include "vpu_cmds.h"
> +#include "vpu_rpc.h"
> +
> +#define VENC_OUTPUT_ENABLE	(1 << 0)
> +#define VENC_CAPTURE_ENABLE	(1 << 1)
> +#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
> +#define VENC_MAX_BUF_CNT	8
> +
> +struct venc_t {
> +	struct vpu_encode_params params;
> +	u32 request_key_frame;
> +	u32 input_ready;
> +	u32 cpb_size;
> +	bool bitrate_change;
> +
> +	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
> +	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
> +	struct vpu_buffer act[VENC_MAX_BUF_CNT];
> +	struct list_head frames;
> +	u32 frame_count;
> +	u32 encode_count;
> +	u32 ready_count;
> +	u32 enable;
> +	u32 stopped;
> +
> +	u32 skipped_count;
> +	u32 skipped_bytes;
> +
> +	wait_queue_head_t wq;
> +};
> +
> +struct venc_frame_t {
> +	struct list_head list;
> +	struct vpu_enc_pic_info info;
> +	u32 bytesused;
> +	s64 timestamp;
> +};
> +
> +static const struct vpu_format venc_formats[] = {
> +	{
> +		.pixfmt = V4L2_PIX_FMT_NV12M,
> +		.num_planes = 2,
> +		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
> +	},
> +	{
> +		.pixfmt = V4L2_PIX_FMT_H264,
> +		.num_planes = 1,
> +		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
> +	},
> +	{0, 0, 0, 0},
> +};
> +
> +static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
> +{
> +	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
> +	strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));
> +	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
> +
> +	return 0;
> +}
> +
> +static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	const struct vpu_format *fmt;
> +
> +	memset(f->reserved, 0, sizeof(f->reserved));
> +	fmt = vpu_helper_enum_format(inst, f->type, f->index);
> +	if (!fmt)
> +		return -EINVAL;
> +
> +	f->pixelformat = fmt->pixfmt;
> +	f->flags = fmt->flags;
> +
> +	return 0;
> +}
> +
> +static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	const struct vpu_core_resources *res;
> +
> +	if (!fsize || fsize->index)
> +		return -EINVAL;
> +
> +	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
> +		return -EINVAL;
> +
> +	res = vpu_get_resource(inst);
> +	if (!res)
> +		return -EINVAL;
> +	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
> +	fsize->stepwise.max_width = res->max_width;
> +	fsize->stepwise.max_height = res->max_height;
> +	fsize->stepwise.min_width = res->min_width;
> +	fsize->stepwise.min_height = res->min_height;
> +	fsize->stepwise.step_width = res->step_width;
> +	fsize->stepwise.step_height = res->step_height;
> +
> +	return 0;
> +}
> +
> +static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	const struct vpu_core_resources *res;
> +
> +	if (!fival || fival->index)
> +		return -EINVAL;
> +
> +	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
> +		return -EINVAL;
> +
> +	if (!fival->width || !fival->height)
> +		return -EINVAL;
> +
> +	res = vpu_get_resource(inst);
> +	if (!res)
> +		return -EINVAL;
> +	if (fival->width < res->min_width ||
> +		fival->width > res->max_width ||
> +		fival->height < res->min_height ||
> +		fival->height > res->max_height)
> +		return -EINVAL;
> +
> +	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
> +	fival->stepwise.min.numerator = 1;
> +	fival->stepwise.min.denominator = USHRT_MAX;
> +	fival->stepwise.max.numerator = USHRT_MAX;
> +	fival->stepwise.max.denominator = 1;
> +	fival->stepwise.step.numerator = 1;
> +	fival->stepwise.step.denominator = 1;
> +
> +	return 0;
> +}
> +
> +static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	struct venc_t *venc = inst->priv;
> +	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
> +	struct vpu_format *cur_fmt;
> +	int i;
> +
> +	cur_fmt = vpu_get_format(inst, f->type);
> +
> +	pixmp->pixelformat = cur_fmt->pixfmt;
> +	pixmp->num_planes = cur_fmt->num_planes;
> +	pixmp->width = cur_fmt->width;
> +	pixmp->height = cur_fmt->height;
> +	pixmp->field = cur_fmt->field;
> +	pixmp->flags = cur_fmt->flags;
> +	for (i = 0; i < pixmp->num_planes; i++) {
> +		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
> +		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
> +	}
> +
> +	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
> +	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
> +	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
> +	f->fmt.pix_mp.quantization = venc->params.color.full_range;
> +
> +	return 0;
> +}
> +
> +static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +
> +	vpu_try_fmt_common(inst, f);
> +
> +	return 0;
> +}
> +
> +static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	const struct vpu_format *fmt;
> +	struct vpu_format *cur_fmt;
> +	struct vb2_queue *q;
> +	struct venc_t *venc = inst->priv;
> +	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
> +	int i;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
> +	if (!q)
> +		return -EINVAL;
> +	if (vb2_is_streaming(q))

That should be vb2_is_busy(): once buffers have been allocated you can no longer
change the format. Same issue is present in the next patch.

Regards,

	Hans

> +		return -EBUSY;
> +
> +	fmt = vpu_try_fmt_common(inst, f);
> +	if (!fmt)
> +		return -EINVAL;
> +
> +	cur_fmt = vpu_get_format(inst, f->type);
> +
> +	cur_fmt->pixfmt = fmt->pixfmt;
> +	cur_fmt->num_planes = fmt->num_planes;
> +	cur_fmt->flags = fmt->flags;
> +	cur_fmt->width = pix_mp->width;
> +	cur_fmt->height = pix_mp->height;
> +	for (i = 0; i < fmt->num_planes; i++) {
> +		cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
> +		cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
> +	}
> +
> +	if (pix_mp->field != V4L2_FIELD_ANY)
> +		cur_fmt->field = pix_mp->field;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
> +		venc->params.input_format = cur_fmt->pixfmt;
> +		venc->params.src_stride = cur_fmt->bytesperline[0];
> +		venc->params.src_width = cur_fmt->width;
> +		venc->params.src_height = cur_fmt->height;
> +		venc->params.crop.left = 0;
> +		venc->params.crop.top = 0;
> +		venc->params.crop.width = cur_fmt->width;
> +		venc->params.crop.height = cur_fmt->height;
> +	} else {
> +		venc->params.codec_format = cur_fmt->pixfmt;
> +		venc->params.out_width = cur_fmt->width;
> +		venc->params.out_height = cur_fmt->height;
> +	}
> +
> +	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
> +		if (!vpu_color_check_primaries(pix_mp->colorspace)) {
> +			venc->params.color.primaries = pix_mp->colorspace;
> +			vpu_color_get_default(venc->params.color.primaries,
> +						&venc->params.color.transfer,
> +						&venc->params.color.matrix,
> +						&venc->params.color.full_range);
> +		}
> +		if (!vpu_color_check_transfers(pix_mp->xfer_func))
> +			venc->params.color.transfer = pix_mp->xfer_func;
> +		if (!vpu_color_check_matrix(pix_mp->ycbcr_enc))
> +			venc->params.color.matrix = pix_mp->ycbcr_enc;
> +		if (!vpu_color_check_full_range(pix_mp->quantization))
> +			venc->params.color.full_range = pix_mp->quantization;
> +	}
> +
> +	pix_mp->colorspace = venc->params.color.primaries;
> +	pix_mp->xfer_func = venc->params.color.transfer;
> +	pix_mp->ycbcr_enc = venc->params.color.matrix;
> +	pix_mp->quantization = venc->params.color.full_range;
> +
> +	return 0;
> +}
> +
> +static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	struct venc_t *venc = inst->priv;
> +	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
> +
> +	if (!parm)
> +		return -EINVAL;
> +
> +	if (!vpu_helper_check_type(inst, parm->type))
> +		return -EINVAL;
> +
> +	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
> +	parm->parm.capture.readbuffers = 0;
> +	timeperframe->numerator = venc->params.frame_rate.numerator;
> +	timeperframe->denominator = venc->params.frame_rate.denominator;
> +
> +	return 0;
> +}
> +
> +static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	struct venc_t *venc = inst->priv;
> +	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
> +	unsigned long n, d;
> +
> +	if (!parm)
> +		return -EINVAL;
> +
> +	if (!vpu_helper_check_type(inst, parm->type))
> +		return -EINVAL;
> +
> +	if (!timeperframe->numerator)
> +		timeperframe->numerator = venc->params.frame_rate.numerator;
> +	if (!timeperframe->denominator)
> +		timeperframe->denominator = venc->params.frame_rate.denominator;
> +
> +	venc->params.frame_rate.numerator = timeperframe->numerator;
> +	venc->params.frame_rate.denominator = timeperframe->denominator;
> +
> +	rational_best_approximation(venc->params.frame_rate.numerator,
> +				    venc->params.frame_rate.denominator,
> +				    venc->params.frame_rate.numerator,
> +				    venc->params.frame_rate.denominator,
> +				    &n, &d);
> +	venc->params.frame_rate.numerator = n;
> +	venc->params.frame_rate.denominator = d;
> +
> +	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
> +	memset(parm->parm.capture.reserved,
> +			0, sizeof(parm->parm.capture.reserved));
> +
> +	return 0;
> +}
> +
> +static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	struct venc_t *venc = inst->priv;
> +
> +	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
> +		return -EINVAL;
> +
> +	switch (s->target) {
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +		s->r.left = 0;
> +		s->r.top = 0;
> +		s->r.width = inst->out_format.width;
> +		s->r.height = inst->out_format.height;
> +		break;
> +	case V4L2_SEL_TGT_CROP:
> +		s->r = venc->params.crop;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)
> +{
> +	struct v4l2_rect *rect = NULL;
> +	u32 min_width;
> +	u32 min_height;
> +	u32 src_width;
> +	u32 src_height;
> +
> +	rect = &venc->params.crop;
> +	min_width = res->min_width;
> +	min_height = res->min_height;
> +	src_width = venc->params.src_width;
> +	src_height = venc->params.src_height;
> +
> +	if (rect->width == 0 || rect->height == 0)
> +		return -EINVAL;
> +	if (rect->left > src_width - min_width ||
> +		rect->top > src_height - min_height)
> +		return -EINVAL;
> +
> +	rect->width = min(rect->width, src_width - rect->left);
> +	rect->width = max_t(u32, rect->width, min_width);
> +
> +	rect->height = min(rect->height, src_height - rect->top);
> +	rect->height = max_t(u32, rect->height, min_height);
> +
> +	return 0;
> +}
> +
> +static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	const struct vpu_core_resources *res;
> +	struct venc_t *venc = inst->priv;
> +
> +	res = vpu_get_resource(inst);
> +	if (!res)
> +		return -EINVAL;
> +
> +	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
> +		return -EINVAL;
> +	if (s->target != V4L2_SEL_TGT_CROP)
> +		return -EINVAL;
> +
> +	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
> +	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
> +	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
> +	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
> +	if (venc_valid_crop(venc, res)) {
> +		venc->params.crop.left = 0;
> +		venc->params.crop.top = 0;
> +		venc->params.crop.width = venc->params.src_width;
> +		venc->params.crop.height = venc->params.src_height;
> +	}
> +
> +	inst->crop = venc->params.crop;
> +
> +	return 0;
> +}
> +
> +static int venc_drain(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc = inst->priv;
> +	int ret;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +	if (inst->state != VPU_CODEC_STATE_DRAIN)
> +		return 0;
> +
> +	if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
> +		return 0;
> +
> +	if (!venc->input_ready)
> +		return 0;
> +
> +	venc->input_ready = false;
> +	vpu_trace(inst->dev, "[%d]\n", inst->id);
> +	ret = vpu_session_stop(inst);
> +	if (ret)
> +		return ret;
> +	inst->state = VPU_CODEC_STATE_STOP;
> +	wake_up_all(&venc->wq);
> +
> +	return 0;
> +}
> +
> +static int venc_request_eos(struct vpu_inst *inst)
> +{
> +	inst->state = VPU_CODEC_STATE_DRAIN;
> +	venc_drain(inst);
> +
> +	return 0;
> +}
> +
> +static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	int ret;
> +
> +	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
> +	if (ret)
> +		return ret;
> +
> +	vpu_inst_lock(inst);
> +	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
> +		if (inst->state == VPU_CODEC_STATE_DEINIT)
> +			vpu_set_last_buffer_dequeued(inst);
> +		else
> +			venc_request_eos(inst);
> +	}
> +	vpu_inst_unlock(inst);
> +
> +	return 0;
> +}
> +
> +static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
> +{
> +	switch (sub->type) {
> +	case V4L2_EVENT_EOS:
> +		return v4l2_event_subscribe(fh, sub, 0, NULL);
> +	case V4L2_EVENT_CTRL:
> +		return v4l2_ctrl_subscribe_event(fh, sub);
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static const struct v4l2_ioctl_ops venc_ioctl_ops = {
> +	.vidioc_querycap               = venc_querycap,
> +	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
> +	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
> +	.vidioc_enum_framesizes        = venc_enum_framesizes,
> +	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
> +	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
> +	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
> +	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
> +	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
> +	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
> +	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
> +	.vidioc_g_parm                 = venc_g_parm,
> +	.vidioc_s_parm                 = venc_s_parm,
> +	.vidioc_g_selection            = venc_g_selection,
> +	.vidioc_s_selection            = venc_s_selection,
> +	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
> +	.vidioc_encoder_cmd            = venc_encoder_cmd,
> +	.vidioc_subscribe_event        = venc_subscribe_event,
> +	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
> +	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
> +	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
> +	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
> +	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
> +	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
> +	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
> +	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
> +	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
> +	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
> +};
> +
> +static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
> +{
> +	struct vpu_inst *inst = ctrl_to_inst(ctrl);
> +	struct venc_t *venc = inst->priv;
> +	int ret = 0;
> +
> +	vpu_inst_lock(inst);
> +	switch (ctrl->id) {
> +	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
> +		venc->params.profile = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
> +		venc->params.level = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
> +		venc->params.rc_mode = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_BITRATE:
> +		if (ctrl->val != venc->params.bitrate)
> +			venc->bitrate_change = true;
> +		venc->params.bitrate = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
> +		venc->params.gop_length = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
> +		venc->params.bframes = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
> +		venc->params.i_frame_qp = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
> +		venc->params.p_frame_qp = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
> +		venc->params.b_frame_qp = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
> +		venc->request_key_frame = 1;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
> +		venc->cpb_size = ctrl->val * 1024;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
> +		venc->params.sar.enable = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
> +		venc->params.sar.idc = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
> +		venc->params.sar.width = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
> +		venc->params.sar.height = ctrl->val;
> +		break;
> +	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
> +		break;
> +	default:
> +		ret = -EINVAL;
> +		break;
> +	}
> +	vpu_inst_unlock(inst);
> +
> +	return ret;
> +}
> +
> +static const struct v4l2_ctrl_ops venc_ctrl_ops = {
> +	.s_ctrl = venc_op_s_ctrl,
> +	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
> +};
> +
> +static int venc_ctrl_init(struct vpu_inst *inst)
> +{
> +	struct v4l2_ctrl *ctrl;
> +	int ret;
> +
> +	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
> +	if (ret)
> +		return ret;
> +
> +	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_PROFILE,
> +			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
> +			~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
> +			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
> +			  (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
> +			V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
> +
> +	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_LEVEL,
> +			V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
> +			0x0,
> +			V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
> +
> +	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
> +			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
> +			0x0,
> +			V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_BITRATE,
> +			BITRATE_MIN,
> +			BITRATE_MAX,
> +			BITRATE_STEP,
> +			BITRATE_DEFAULT);
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
> +	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
> +	if (ctrl)
> +		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
> +	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
> +	if (ctrl)
> +		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
> +
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
> +	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
> +			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
> +			0x0,
> +			V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
> +			0, USHRT_MAX, 1, 1);
> +	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
> +			0, USHRT_MAX, 1, 1);
> +	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
> +			V4L2_CID_MPEG_VIDEO_HEADER_MODE,
> +			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
> +			~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
> +			V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
> +
> +	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
> +	if (ret) {
> +		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
> +		v4l2_ctrl_handler_free(&inst->ctrl_handler);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type)) {
> +		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
> +			return false;
> +		return venc->input_ready;
> +	}
> +
> +	if (list_empty(&venc->frames))
> +		return false;
> +	return true;
> +}
> +
> +static u32 venc_get_enable_mask(u32 type)
> +{
> +	if (V4L2_TYPE_IS_OUTPUT(type))
> +		return VENC_OUTPUT_ENABLE;
> +	else
> +		return VENC_CAPTURE_ENABLE;
> +}
> +
> +static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
> +{
> +	u32 mask = venc_get_enable_mask(type);
> +
> +	if (enable)
> +		venc->enable |= mask;
> +	else
> +		venc->enable &= ~mask;
> +}
> +
> +static u32 venc_get_enable(struct venc_t *venc, u32 type)
> +{
> +	return venc->enable & venc_get_enable_mask(type);
> +}
> +
> +static void venc_input_done(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	vpu_inst_lock(inst);
> +	venc->input_ready = true;
> +	vpu_process_output_buffer(inst);
> +	if (inst->state == VPU_CODEC_STATE_DRAIN)
> +		venc_drain(inst);
> +	vpu_inst_unlock(inst);
> +}
> +
> +/*
> + * It's hardware limitation, that there may be several bytes
> + * redundant data at the beginning of frame.
> + * For android platform, the redundant data may cause cts test fail
> + * So driver will strip them
> + */
> +static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
> +{
> +	struct venc_t *venc;
> +	int skipped;
> +
> +	if (!inst || !frame || !frame->bytesused)
> +		return -EINVAL;
> +
> +	venc = inst->priv;
> +	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
> +				inst->cap_format.pixfmt,
> +				frame->info.wptr - inst->stream_buffer.phys,
> +				frame->bytesused);
> +	if (skipped > 0) {
> +		frame->bytesused -= skipped;
> +		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
> +						frame->info.wptr, skipped);
> +		venc->skipped_bytes += skipped;
> +		venc->skipped_count++;
> +	}
> +
> +	return 0;
> +}
> +
> +static int venc_get_one_encoded_frame(struct vpu_inst *inst,
> +					struct venc_frame_t *frame,
> +					struct vb2_v4l2_buffer *vbuf)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	if (!vbuf)
> +		return -EAGAIN;
> +
> +	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return 0;
> +	}
> +	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
> +		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
> +		return -ENOMEM;
> +	}
> +
> +	venc_precheck_encoded_frame(inst, frame);
> +
> +	if (frame->bytesused) {
> +		u32 rptr = frame->info.wptr;
> +		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
> +
> +		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
> +			&rptr, frame->bytesused, dst);
> +		vpu_iface_update_stream_buffer(inst, rptr, 0);
> +	}
> +	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
> +	vbuf->sequence = frame->info.frame_id;
> +	vbuf->vb2_buf.timestamp = frame->info.timestamp;
> +	vbuf->field = inst->cap_format.field;
> +	vbuf->flags |= frame->info.pic_type;
> +	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
> +	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->info.timestamp);
> +	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
> +	venc->ready_count++;
> +
> +	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
> +		dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);
> +
> +	return 0;
> +}
> +
> +static int venc_get_encoded_frames(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc;
> +	struct venc_frame_t *frame;
> +	struct venc_frame_t *tmp;
> +
> +	if (!inst || !inst->priv || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	venc = inst->priv;
> +	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
> +		if (venc_get_one_encoded_frame(inst, frame,
> +					v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
> +			break;
> +		list_del_init(&frame->list);
> +		vfree(frame);
> +	}
> +
> +	return 0;
> +}
> +
> +static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
> +{
> +	struct vpu_enc_pic_info *info = arg;
> +	struct venc_frame_t *frame;
> +	struct venc_t *venc;
> +	int ret = 0;
> +
> +	if (!inst || !info)
> +		return -EINVAL;
> +	venc = inst->priv;
> +	frame = vzalloc(sizeof(*frame));
> +	if (!frame)
> +		return -ENOMEM;
> +
> +	memcpy(&frame->info, info, sizeof(frame->info));
> +	frame->bytesused = info->frame_size;
> +
> +	vpu_inst_lock(inst);
> +	list_add_tail(&frame->list, &venc->frames);
> +	venc->encode_count++;
> +	venc_get_encoded_frames(inst);
> +	vpu_inst_unlock(inst);
> +
> +	return ret;
> +}
> +
> +static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
> +{
> +	struct vb2_v4l2_buffer *vbuf;
> +
> +	if (!inst || !frame || !inst->fh.m2m_ctx)
> +		return;
> +
> +	vpu_inst_lock(inst);
> +	if (!venc_get_enable(inst->priv, frame->type))
> +		goto exit;
> +	vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
> +	if (!vbuf) {
> +		dev_err(inst->dev, "[%d] can't find buf: type %d, sequence %d\n",
> +				inst->id, frame->type, frame->sequence);
> +		goto exit;
> +	}
> +
> +	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
> +	if (V4L2_TYPE_IS_OUTPUT(frame->type))
> +		v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
> +	else
> +		v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
> +	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
> +exit:
> +	vpu_inst_unlock(inst);
> +}
> +
> +static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	if (venc->stopped && list_empty(&venc->frames))
> +		vpu_set_last_buffer_dequeued(inst);
> +}
> +
> +static void venc_stop_done(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	vpu_inst_lock(inst);
> +	venc->stopped = true;
> +	venc_set_last_buffer_dequeued(inst);
> +	vpu_inst_unlock(inst);
> +
> +	wake_up_all(&venc->wq);
> +}
> +
> +static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
> +{
> +}
> +
> +static void venc_release(struct vpu_inst *inst)
> +{
> +}
> +
> +static void venc_cleanup(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc;
> +
> +	if (!inst)
> +		return;
> +
> +	venc = inst->priv;
> +	if (venc)
> +		vfree(venc);
> +	inst->priv = NULL;
> +	vfree(inst);
> +}
> +
> +static int venc_start_session(struct vpu_inst *inst, u32 type)
> +{
> +	struct venc_t *venc = inst->priv;
> +	int stream_buffer_size;
> +	int ret;
> +
> +	venc_set_enable(venc, type, 1);
> +	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
> +		return 0;
> +
> +	vpu_iface_init_instance(inst);
> +	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
> +	if (stream_buffer_size > 0) {
> +		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
> +		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
> +		if (ret)
> +			goto error;
> +
> +		inst->use_stream_buffer = true;
> +		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
> +	}
> +
> +	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
> +	if (ret)
> +		goto error;
> +	ret = vpu_session_configure_codec(inst);
> +	if (ret)
> +		goto error;
> +
> +	inst->state = VPU_CODEC_STATE_CONFIGURED;
> +	/*vpu_iface_config_memory_resource*/
> +
> +	/*config enc expert mode parameter*/
> +	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
> +	if (ret)
> +		goto error;
> +
> +	ret = vpu_session_start(inst);
> +	if (ret)
> +		goto error;
> +	inst->state = VPU_CODEC_STATE_STARTED;
> +
> +	venc->bitrate_change = false;
> +	venc->input_ready = true;
> +	venc->frame_count = 0;
> +	venc->encode_count = 0;
> +	venc->ready_count = 0;
> +	venc->stopped = false;
> +	vpu_process_output_buffer(inst);
> +	if (venc->frame_count == 0)
> +		dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
> +
> +	return 0;
> +error:
> +	venc_set_enable(venc, type, 0);
> +	inst->state = VPU_CODEC_STATE_DEINIT;
> +
> +	vpu_free_dma(&inst->stream_buffer);
> +	return ret;
> +}
> +
> +static void venc_cleanup_mem_resource(struct vpu_inst *inst)
> +{
> +	struct venc_t *venc;
> +	u32 i;
> +
> +	venc = inst->priv;
> +
> +	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
> +		vpu_free_dma(&venc->enc[i]);
> +	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
> +		vpu_free_dma(&venc->ref[i]);
> +	for (i = 0; i < ARRAY_SIZE(venc->act); i++)
> +		vpu_free_dma(&venc->act[i]);
> +}
> +
> +static void venc_request_mem_resource(struct vpu_inst *inst,
> +				u32 enc_frame_size,
> +				u32 enc_frame_num,
> +				u32 ref_frame_size,
> +				u32 ref_frame_num,
> +				u32 act_frame_size,
> +				u32 act_frame_num)
> +{
> +	struct venc_t *venc;
> +	u32 i;
> +	int ret;
> +
> +	venc = inst->priv;
> +	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
> +		dev_err(inst->dev, "[%d] enc num(%d) is out of range\n",
> +				inst->id, enc_frame_num);
> +		return;
> +	}
> +	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
> +		dev_err(inst->dev, "[%d] ref num(%d) is out of range\n",
> +				inst->id, ref_frame_num);
> +		return;
> +	}
> +	if (act_frame_num > ARRAY_SIZE(venc->act)) {
> +		dev_err(inst->dev, "[%d] act num(%d) is out of range\n",
> +				inst->id, act_frame_num);
> +		return;
> +	}
> +
> +	for (i = 0; i < enc_frame_num; i++) {
> +		venc->enc[i].length = enc_frame_size;
> +		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
> +		if (ret) {
> +			venc_cleanup_mem_resource(inst);
> +			return;
> +		}
> +	}
> +	for (i = 0; i < ref_frame_num; i++) {
> +		venc->ref[i].length = ref_frame_size;
> +		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
> +		if (ret) {
> +			venc_cleanup_mem_resource(inst);
> +			return;
> +		}
> +	}
> +	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
> +		venc_cleanup_mem_resource(inst);
> +		return;
> +	}
> +	venc->act[0].length = act_frame_size;
> +	venc->act[0].phys = inst->act.phys;
> +	venc->act[0].virt = inst->act.virt;
> +
> +	for (i = 0; i < enc_frame_num; i++)
> +		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
> +	for (i = 0; i < ref_frame_num; i++)
> +		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
> +	for (i = 0; i < act_frame_num; i++)
> +		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
> +}
> +
> +static void venc_cleanup_frames(struct venc_t *venc)
> +{
> +	struct venc_frame_t *frame;
> +	struct venc_frame_t *tmp;
> +
> +	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
> +		list_del_init(&frame->list);
> +		vfree(frame);
> +	}
> +}
> +
> +static int venc_stop_session(struct vpu_inst *inst, u32 type)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	venc_set_enable(venc, type, 0);
> +	if (venc->enable & VENC_ENABLE_MASK)
> +		return 0;
> +
> +	if (inst->state == VPU_CODEC_STATE_DEINIT)
> +		return 0;
> +
> +	if (inst->state != VPU_CODEC_STATE_STOP)
> +		venc_request_eos(inst);
> +
> +	call_vop(inst, wait_prepare);
> +	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
> +		set_bit(inst->id, &inst->core->hang_mask);
> +		vpu_session_debug(inst);
> +	}
> +	call_vop(inst, wait_finish);
> +
> +	inst->state = VPU_CODEC_STATE_DEINIT;
> +	venc_cleanup_frames(inst->priv);
> +	vpu_free_dma(&inst->stream_buffer);
> +	venc_cleanup_mem_resource(inst);
> +
> +	return 0;
> +}
> +
> +static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
> +{
> +	struct venc_t *venc = inst->priv;
> +	struct vb2_v4l2_buffer *vbuf;
> +	u32 flags;
> +
> +	if (inst->state == VPU_CODEC_STATE_DEINIT)
> +		return -EINVAL;
> +
> +	vbuf = to_vb2_v4l2_buffer(vb);
> +	if (inst->state == VPU_CODEC_STATE_STARTED)
> +		inst->state = VPU_CODEC_STATE_ACTIVE;
> +
> +	flags = vbuf->flags;
> +	if (venc->request_key_frame) {
> +		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
> +		venc->request_key_frame = 0;
> +	}
> +	if (venc->bitrate_change) {
> +		vpu_session_update_parameters(inst, &venc->params);
> +		venc->bitrate_change = false;
> +	}
> +	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
> +	vpu_iface_input_frame(inst, vb);
> +	vbuf->flags = flags;
> +	venc->input_ready = false;
> +	venc->frame_count++;
> +	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
> +
> +	return 0;
> +}
> +
> +static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
> +{
> +	struct venc_t *venc;
> +	struct venc_frame_t *frame = NULL;
> +	struct vb2_v4l2_buffer *vbuf;
> +	int ret;
> +
> +	if (!inst || !inst->fh.m2m_ctx)
> +		return -EINVAL;
> +
> +	venc = inst->priv;
> +	if (list_empty(&venc->frames))
> +		return -EINVAL;
> +
> +	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
> +	vbuf = to_vb2_v4l2_buffer(vb);
> +	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
> +	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
> +	if (ret)
> +		return ret;
> +
> +	list_del_init(&frame->list);
> +	vfree(frame);
> +	return 0;
> +}
> +
> +static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)
> +{
> +	struct venc_t *venc = inst->priv;
> +
> +	if (V4L2_TYPE_IS_OUTPUT(type))
> +		return;
> +
> +	if (venc->stopped)
> +		venc_set_last_buffer_dequeued(inst);
> +}
> +
> +static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
> +{
> +	struct venc_t *venc = inst->priv;
> +	int num = -1;
> +
> +	switch (i) {
> +	case 0:
> +		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
> +		break;
> +	case 1:
> +		num = scnprintf(str, size, "level = %d\n", venc->params.level);
> +		break;
> +	case 2:
> +		num = scnprintf(str, size, "fps = %d/%d\n",
> +				venc->params.frame_rate.numerator,
> +				venc->params.frame_rate.denominator);
> +		break;
> +	case 3:
> +		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
> +				venc->params.src_width,
> +				venc->params.src_height,
> +				venc->params.out_width,
> +				venc->params.out_height);
> +		break;
> +	case 4:
> +		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
> +				venc->params.crop.left,
> +				venc->params.crop.top,
> +				venc->params.crop.width,
> +				venc->params.crop.height);
> +		break;
> +	case 5:
> +		num = scnprintf(str, size,
> +				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
> +				venc->enable,
> +				venc->frame_count, venc->encode_count,
> +				venc->ready_count,
> +				venc->stopped);
> +		break;
> +	case 6:
> +		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
> +		break;
> +	case 7:
> +		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
> +		break;
> +	case 8:
> +		num = scnprintf(str, size, "rc: mode = %d, bitrate = %d, qp = %d\n",
> +				venc->params.rc_mode,
> +				venc->params.bitrate,
> +				venc->params.i_frame_qp);
> +		break;
> +	case 9:
> +		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
> +				venc->params.sar.enable,
> +				venc->params.sar.idc,
> +				venc->params.sar.width,
> +				venc->params.sar.height);
> +
> +		break;
> +	case 10:
> +		num = scnprintf(str, size,
> +				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
> +				venc->params.color.primaries,
> +				venc->params.color.transfer,
> +				venc->params.color.matrix,
> +				venc->params.color.full_range);
> +		break;
> +	case 11:
> +		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
> +				venc->skipped_count, venc->skipped_bytes);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return num;
> +}
> +
> +static struct vpu_inst_ops venc_inst_ops = {
> +	.ctrl_init = venc_ctrl_init,
> +	.check_ready = venc_check_ready,
> +	.input_done = venc_input_done,
> +	.get_one_frame = venc_frame_encoded,
> +	.buf_done = venc_buf_done,
> +	.stop_done = venc_stop_done,
> +	.event_notify = venc_event_notify,
> +	.release = venc_release,
> +	.cleanup = venc_cleanup,
> +	.start = venc_start_session,
> +	.mem_request = venc_request_mem_resource,
> +	.stop = venc_stop_session,
> +	.process_output = venc_process_output,
> +	.process_capture = venc_process_capture,
> +	.on_queue_empty = venc_on_queue_empty,
> +	.get_debug_info = venc_get_debug_info,
> +	.wait_prepare = vpu_inst_unlock,
> +	.wait_finish = vpu_inst_lock,
> +};
> +
> +static void venc_init(struct file *file)
> +{
> +	struct vpu_inst *inst = to_inst(file);
> +	struct venc_t *venc;
> +	struct v4l2_format f;
> +	struct v4l2_streamparm parm;
> +
> +	venc = inst->priv;
> +	venc->params.qp_min = 1;
> +	venc->params.qp_max = 51;
> +	venc->params.qp_min_i = 1;
> +	venc->params.qp_max_i = 51;
> +	venc->params.bitrate_max = BITRATE_MAX;
> +	venc->params.bitrate_min = BITRATE_MIN;
> +
> +	memset(&f, 0, sizeof(f));
> +	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
> +	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
> +	f.fmt.pix_mp.width = 1280;
> +	f.fmt.pix_mp.height = 720;
> +	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
> +	f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
> +	venc_s_fmt(file, &inst->fh, &f);
> +
> +	memset(&f, 0, sizeof(f));
> +	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
> +	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
> +	f.fmt.pix_mp.width = 1280;
> +	f.fmt.pix_mp.height = 720;
> +	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
> +	venc_s_fmt(file, &inst->fh, &f);
> +
> +	memset(&parm, 0, sizeof(parm));
> +	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
> +	parm.parm.capture.timeperframe.numerator = 1;
> +	parm.parm.capture.timeperframe.denominator = 30;
> +	venc_s_parm(file, &inst->fh, &parm);
> +}
> +
> +static int venc_open(struct file *file)
> +{
> +	struct vpu_inst *inst;
> +	struct venc_t *venc;
> +	int ret;
> +
> +	inst = vzalloc(sizeof(*inst));
> +	if (!inst)
> +		return -ENOMEM;
> +
> +	venc = vzalloc(sizeof(*venc));
> +	if (!venc) {
> +		vfree(inst);
> +		return -ENOMEM;
> +	}
> +
> +	inst->ops = &venc_inst_ops;
> +	inst->formats = venc_formats;
> +	inst->type = VPU_CORE_TYPE_ENC;
> +	inst->priv = venc;
> +	INIT_LIST_HEAD(&venc->frames);
> +	init_waitqueue_head(&venc->wq);
> +
> +	ret = vpu_v4l2_open(file, inst);
> +	if (ret)
> +		return ret;
> +
> +	venc_init(file);
> +
> +	return 0;
> +}
> +
> +static const struct v4l2_file_operations venc_fops = {
> +	.owner = THIS_MODULE,
> +	.open = venc_open,
> +	.release = vpu_v4l2_close,
> +	.unlocked_ioctl = video_ioctl2,
> +	.poll = v4l2_m2m_fop_poll,
> +	.mmap = v4l2_m2m_fop_mmap,
> +};
> +
> +const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
> +{
> +	return &venc_ioctl_ops;
> +}
> +
> +const struct v4l2_file_operations *venc_get_fops(void)
> +{
> +	return &venc_fops;
> +}


From maxime at cerno.tech  Thu Jan 20 07:39:28 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Thu, 20 Jan 2022 16:39:28 +0100
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
Message-ID: <20220120153928.yvkrqduoytddvegs@houat>

Hi Stefan,

On Sun, Jan 16, 2022 at 06:26:58PM +0100, Stefan Wahren wrote:
> recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
> Aarch64 with Arch Linux. I'm able to reproduce this issue on my
> Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
> the connected HDMI monitor off and on again.

By turning the monitor on and off, you mean that you used the power
button on it? Not something like disabling the output in sysfs, right?

> Kernel output is the following:
> 
> [15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
> unhandled: 0
> [15053.295440] ->handle_irq():? 00000000b28cf1d1,
> brcmstb_l2_intc_irq_handle+0x0/0x1e0
> [15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
> [15053.315233] ->action(): 00000000236e815e
> [15053.322022] ->action->handler(): 0000000013023289,
> bad_chained_irq+0x0/0x50
> [15053.331909]????? IRQ_LEVEL set
> [15053.337822]??? IRQ_NOPROBE set
> [15053.343715]? IRQ_NOREQUEST set
> [15053.349585]?? IRQ_NOTHREAD set

IRQ10 is the interrupt that a monitor has been connected on HDMI1, which
makes sense if you were using HDMI1. Usually, when a display is turned
on, it will issue a pulse on the HPD line so we would have a
disconnection interrupt followed by a connection interrupt.

This is weird though, since we have an interrupt handler on that
interrupt (hpd-connected in the DT binding):
https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/vc4/vc4_hdmi.c#L1578

> Content of /proc/interrupts after the issue occured:
> 
> ?????????? CPU0?????? CPU1?????? CPU2?????? CPU3??????
> ? 9:????????? 0????????? 0????????? 0????????? 0???? GICv2? 25 Level????
> vgic
> ?10:????????? 1????????? 0????????? 0????????? 0???? GICv2 128 Level????
> (null)
> ?12:???? 130322????? 26028????? 27670???? 135225???? GICv2? 30 Level????
> arch_timer
> ?13:????????? 0????????? 0????????? 0????????? 0???? GICv2? 27 Level????
> kvm guest vtimer
> ?19:????????? 0????????? 0????????? 0????????? 0???? GICv2 107 Level????
> fe004000.txp
> ?20:?????? 7450????????? 0????????? 0????????? 0???? GICv2? 65 Level????
> fe00b880.mailbox
> ?25:?????? 6525????????? 0????????? 0????????? 0???? GICv2 153 Level????
> uart-pl011
> ?26:????????? 0????????? 0????????? 0????????? 0???? GICv2 149 Level????
> fe205000.i2c, fe804000.i2c
> ?27:????????? 9????????? 0????????? 0????????? 0???? GICv2 125 Level????
> ttyS1
> ?28:????? 36999????????? 0????????? 0????????? 0???? GICv2 158 Level????
> mmc0, mmc1
> ?29:????????? 1????????? 0????????? 0????????? 0???? GICv2 129 Level????
> vc4 hvs
> ?30:????????? 0????????? 0????????? 0????????? 0???? GICv2 105 Level????
> fe980000.usb, fe980000.usb
> ?31:????????? 0????????? 0????????? 0????????? 0???? GICv2 112 Level????
> DMA IRQ
> ?33:????????? 0????????? 0????????? 0????????? 0???? GICv2 114 Level????
> DMA IRQ
> ?40:????????? 0????????? 0????????? 0????????? 0???? GICv2 141 Level????
> vc4 crtc
> ?41:????????? 0????????? 0????????? 0????????? 0???? GICv2 142 Level????
> vc4 crtc, vc4 crtc
> ?42:???????? 10????????? 0????????? 0????????? 0???? GICv2 133 Level????
> vc4 crtc
> ?43:????????? 1????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
> ?44:????????? 0????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
> ?47:????????? 0????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
> ?48:????????? 1????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
> ?49:????????? 0????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
> ?50:????????? 0????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
> ?53:????????? 0????????? 0????????? 0????????? 0?
> interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
> ?54:????????? 0????????? 0????????? 0????????? 0?

And it's there as well.

> interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
> ?55:????????? 7????????? 0????????? 0????????? 0???? GICv2? 66 Level????
> VCHIQ doorbell
> ?56:????????? 0????????? 0????????? 0????????? 0???? GICv2? 48 Level????
> arm-pmu
> ?57:????????? 0????????? 0????????? 0????????? 0???? GICv2? 49 Level????
> arm-pmu
> ?58:????????? 0????????? 0????????? 0????????? 0???? GICv2? 50 Level????
> arm-pmu
> ?59:????????? 0????????? 0????????? 0????????? 0???? GICv2? 51 Level????
> arm-pmu
> ?62:????? 47599????????? 0????????? 0????????? 0???? GICv2 189 Level????
> eth0
> ?63:?????? 4681????????? 0????????? 0????????? 0???? GICv2 190 Level????
> eth0
> ?64:????????? 0????????? 0????????? 0????????? 0???? GICv2 175 Level????
> PCIe PME, aerdrv
> ?65:??????? 326????????? 0????????? 0????????? 0? BRCM STB PCIe MSI
> 524288 Edge????? xhci_hcd
> IPI0:????? 2442?????? 5185?????? 7195????? 18290?????? Rescheduling
> interrupts
> IPI1:?????? 481??????? 383??????? 518??????? 533?????? Function call
> interrupts
> IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop interrupts
> IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for
> crash dump) interrupts
> IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast
> interrupts
> IPI5:???????? 1????????? 0????????? 0????????? 0?????? IRQ work interrupts
> IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up
> interrupts
> Err:????????? 1
> 
> Comparing the vendor & mainline DTS, i noticed differences at hdmi0/1.
> The vendor DTS has an additional register to access the same space as
> aon_intr (interrupt parent), which looks ugly [2].

This is an artifact from the past. We used to use that register directly
in our driver before we went to upstream the CEC support, but we don't
anymore. The DT patch must have been carried around since then, but
nothing should be using it.

> Additionally i noted that bcm2711.dtsi uses the compatible
> "brcm,bcm2711-l2-intc" with a level high interrupt, but according to
> irq-brcmstb-l2.c [3] the compatible is not defined and would fallback to
> "brcm,l2-intc" with brcmstb_l2_edge_intc_of_init. This looks fishy.
> 
> I didn't try to reproduce this with Raspberry Pi OS & mainline kernel,
> but i hope these are enough information so far.

I don't remember anyone reporting this before, and I have tested the
disconnection / connection interrupts myself a number of times without
ever seeing this. The level vs edge stuff might be a good explanation

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220120/5912762f/attachment.sig>

From David.Laight at ACULAB.COM  Thu Jan 20 07:46:18 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Thu, 20 Jan 2022 15:46:18 +0000
Subject: [PATCH V3 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <CAK8P3a3FLnqibdXCGR8c+mm92HSiuvocZDeW8MyoTO_L1sYT=w@mail.gmail.com>
References: <20220120073911.99857-8-guoren@kernel.org>
 <CAK8P3a1UvqsS-D7cVXBkp4KCRWDfquQ6QTkvrQ=FqLxhsAi7Rw@mail.gmail.com>
 <f16cf10425a14c2e8183d5c90667ce72@AcuMS.aculab.com>
 <CAJF2gTRwh40xDBkoRJWZEUketKFDAy7_z=-WW7E=T46yH4zPvw@mail.gmail.com>
 <CAK8P3a3FLnqibdXCGR8c+mm92HSiuvocZDeW8MyoTO_L1sYT=w@mail.gmail.com>
Message-ID: <01a8da9e5a374373a922e569a1e10ee8@AcuMS.aculab.com>

...
> One example of software that runs into virtual memory size limitations is
> the gnu linker when building large applications, but it's unlikely that you'll
> actually need to run applications that run into this, while also needing to
> build them natively.

There are also database programs that want to mmap() large sparse files.
To some extent that is where the pressure for 64bit addresses comes from.

While (I think) most of the current riscv systems are 'toy' ones
there are definitely press reports of some quite high power systems.

I suspect they are less 'toy' than the Altera (Intel) Nios processors
we use on out fpga - you can run linux on the Nios cpu, but you probably
don't really want to do so.
Better to find an fpga with a 'proper' ARM core in the corner.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)

From maxime at cerno.tech  Thu Jan 20 07:54:05 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Thu, 20 Jan 2022 16:54:05 +0100
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <bdda31f0-7ec0-50e8-dfaa-d8536a3219e5@gmail.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <31f2cd8f-32b6-beca-0cae-66c23b73ece0@gmail.com>
 <bdda31f0-7ec0-50e8-dfaa-d8536a3219e5@gmail.com>
Message-ID: <20220120155405.jeg7cx4lafnytun4@houat>

Hi Florian,

On Sun, Jan 16, 2022 at 08:59:15PM -0800, Florian Fainelli wrote:
> > > ??12:???? 130322????? 26028????? 27670???? 135225???? GICv2? 30 Level
> > > arch_timer
> > > ??13:????????? 0????????? 0????????? 0????????? 0???? GICv2? 27 Level
> > > kvm guest vtimer
> > > ??19:????????? 0????????? 0????????? 0????????? 0???? GICv2 107 Level
> > > fe004000.txp
> > > ??20:?????? 7450????????? 0????????? 0????????? 0???? GICv2? 65 Level
> > > fe00b880.mailbox
> > > ??25:?????? 6525????????? 0????????? 0????????? 0???? GICv2 153 Level
> > > uart-pl011
> > > ??26:????????? 0????????? 0????????? 0????????? 0???? GICv2 149 Level
> > > fe205000.i2c, fe804000.i2c
> > > ??27:????????? 9????????? 0????????? 0????????? 0???? GICv2 125 Level
> > > ttyS1
> > > ??28:????? 36999????????? 0????????? 0????????? 0???? GICv2 158 Level
> > > mmc0, mmc1
> > > ??29:????????? 1????????? 0????????? 0????????? 0???? GICv2 129 Level
> > > vc4 hvs
> > > ??30:????????? 0????????? 0????????? 0????????? 0???? GICv2 105 Level
> > > fe980000.usb, fe980000.usb
> > > ??31:????????? 0????????? 0????????? 0????????? 0???? GICv2 112 Level
> > > DMA IRQ
> > > ??33:????????? 0????????? 0????????? 0????????? 0???? GICv2 114 Level
> > > DMA IRQ
> > > ??40:????????? 0????????? 0????????? 0????????? 0???? GICv2 141 Level
> > > vc4 crtc
> > > ??41:????????? 0????????? 0????????? 0????????? 0???? GICv2 142 Level
> > > vc4 crtc, vc4 crtc
> > > ??42:???????? 10????????? 0????????? 0????????? 0???? GICv2 133 Level
> > > vc4 crtc
> > > ??43:????????? 1????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
> > > ??44:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
> > > ??47:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
> > > ??48:????????? 1????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
> > > ??49:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
> > > ??50:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
> > > ??53:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
> > > ??54:????????? 0????????? 0????????? 0????????? 0
> > > interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
> > > ??55:????????? 7????????? 0????????? 0????????? 0???? GICv2? 66 Level
> > > VCHIQ doorbell
> > > ??56:????????? 0????????? 0????????? 0????????? 0???? GICv2? 48 Level
> > > arm-pmu
> > > ??57:????????? 0????????? 0????????? 0????????? 0???? GICv2? 49 Level
> > > arm-pmu
> > > ??58:????????? 0????????? 0????????? 0????????? 0???? GICv2? 50 Level
> > > arm-pmu
> > > ??59:????????? 0????????? 0????????? 0????????? 0???? GICv2? 51 Level
> > > arm-pmu
> > > ??62:????? 47599????????? 0????????? 0????????? 0???? GICv2 189 Level
> > > eth0
> > > ??63:?????? 4681????????? 0????????? 0????????? 0???? GICv2 190 Level
> > > eth0
> > > ??64:????????? 0????????? 0????????? 0????????? 0???? GICv2 175 Level
> > > PCIe PME, aerdrv
> > > ??65:??????? 326????????? 0????????? 0????????? 0? BRCM STB PCIe MSI
> > > 524288 Edge????? xhci_hcd
> > > IPI0:????? 2442?????? 5185?????? 7195????? 18290?????? Rescheduling
> > > interrupts
> > > IPI1:?????? 481??????? 383??????? 518??????? 533?????? Function call
> > > interrupts
> > > IPI2:???????? 0????????? 0????????? 0????????? 0?????? CPU stop
> > > interrupts
> > > IPI3:???????? 0????????? 0????????? 0????????? 0?????? CPU stop (for
> > > crash dump) interrupts
> > > IPI4:???????? 0????????? 0????????? 0????????? 0?????? Timer broadcast
> > > interrupts
> > > IPI5:???????? 1????????? 0????????? 0????????? 0?????? IRQ work
> > > interrupts
> > > IPI6:???????? 0????????? 0????????? 0????????? 0?????? CPU wake-up
> > > interrupts
> > > Err:????????? 1
> > > 
> > > Comparing the vendor & mainline DTS, i noticed differences at hdmi0/1.
> > > The vendor DTS has an additional register to access the same space as
> > > aon_intr (interrupt parent), which looks ugly [2].
> > 
> > OK, so while I do see how we set external_irq_controller to let the
> > interrupt be managed externally from vc4_hdmi.c else do it internally, I
> > don't see the code that tries to map the "intr2" register space, let
> > alone fetch its resource, do you know where that is?
> 
> Downstream appears to be setting the 'aon_intr' Device Tree node with a
> status = disabled property, still leaves me wondering whether the "intr2"
> register space is used.

It's not used, its last (and only) user was reverted in:
https://github.com/raspberrypi/linux/commit/07170fdd6daffb3fb276a9dc814d6d02d82b055f

> I think it would be prudent to change the hpd_con, hpd_rm variables in
> vc4_hdmi.c to be signed integers instead of unsigned integers, if nothing
> else such that -EPROBE_DEFER might be returned.

Yeah, that would make sense.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220120/16ebd7eb/attachment-0001.sig>

From catalin.marinas at arm.com  Thu Jan 20 07:56:21 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Jan 2022 15:56:21 +0000
Subject: [PATCH v2] arm64: atomics: lse: Dereference matching size
In-Reply-To: <20220112202259.3950286-1-keescook@chromium.org>
References: <20220112202259.3950286-1-keescook@chromium.org>
Message-ID: <164269417315.2457156.6204086542906520057.b4-ty@arm.com>

On Wed, 12 Jan 2022 12:22:59 -0800, Kees Cook wrote:
> When building with -Warray-bounds, the following warning is generated:
> 
> In file included from ./arch/arm64/include/asm/lse.h:16,
>                  from ./arch/arm64/include/asm/cmpxchg.h:14,
>                  from ./arch/arm64/include/asm/atomic.h:16,
>                  from ./include/linux/atomic.h:7,
>                  from ./include/asm-generic/bitops/atomic.h:5,
>                  from ./arch/arm64/include/asm/bitops.h:25,
>                  from ./include/linux/bitops.h:33,
>                  from ./include/linux/kernel.h:22,
>                  from kernel/printk/printk.c:22:
> ./arch/arm64/include/asm/atomic_lse.h:247:9: warning: array subscript 'long unsigned int[0]' is partly outside array bounds of 'atomic_t[1]' [-Warray-bounds]
>   247 |         asm volatile(                                                   \
>       |         ^~~
> ./arch/arm64/include/asm/atomic_lse.h:266:1: note: in expansion of macro '__CMPXCHG_CASE'
>   266 | __CMPXCHG_CASE(w,  , acq_, 32,  a, "memory")
>       | ^~~~~~~~~~~~~~
> kernel/printk/printk.c:3606:17: note: while referencing 'printk_cpulock_owner'
>  3606 | static atomic_t printk_cpulock_owner = ATOMIC_INIT(-1);
>       |                 ^~~~~~~~~~~~~~~~~~~~
> 
> [...]

Applied to arm64 (for-next/core), thanks!

[1/1] arm64: atomics: lse: Dereference matching size
      https://git.kernel.org/arm64/c/3364c6ce23c6

-- 
Catalin



From catalin.marinas at arm.com  Thu Jan 20 07:56:36 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 20 Jan 2022 15:56:36 +0000
Subject: (subset) [PATCH 1/2] arm64: mm: apply __ro_after_init to
 memory_limit
In-Reply-To: <20211215064559.2843555-1-peng.fan@oss.nxp.com>
References: <20211215064559.2843555-1-peng.fan@oss.nxp.com>
Message-ID: <164269417315.2457156.15866873741014097353.b4-ty@arm.com>

On Wed, 15 Dec 2021 14:45:58 +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> This variable is only set during initialization, so mark with
> __ro_after_init.
> 
> 

Applied to arm64 (for-next/core), thanks!

[1/2] arm64: mm: apply __ro_after_init to memory_limit
      https://git.kernel.org/arm64/c/bb425a759847

-- 
Catalin



From quentin.schulz at theobroma-systems.com  Thu Jan 20 08:03:44 2022
From: quentin.schulz at theobroma-systems.com (Quentin Schulz)
Date: Thu, 20 Jan 2022 17:03:44 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
In-Reply-To: <CAMdYzYr+UXU-x=OakdHnOzLe1e4Y0xdGR-rybsmpLCMGbsWwXg@mail.gmail.com>
References: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
 <CAMdYzYr+UXU-x=OakdHnOzLe1e4Y0xdGR-rybsmpLCMGbsWwXg@mail.gmail.com>
Message-ID: <3e87ed0a-8b79-006a-dce6-62becc9906ef@theobroma-systems.com>

Hi Peter,

On 1/20/22 16:06, Peter Geis wrote:
> On Wed, Jan 19, 2022 at 8:52 AM <quentin.schulz at theobroma-systems.com> wrote:
>>
>> From: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
>>
>> There are signal integrity issues running the eMMC at 200MHz on Puma
>> RK3399-Q7.
>>
>> Similar to the work-around found for RK3399 Gru boards, lowering the
>> frequency to 100MHz made the eMMC much more stable, so let's lower the
>> frequency to 100MHz.
>>
>> It might be possible to run at 150MHz as on RK3399 Gru boards but only
>> 100MHz was extensively tested.
>>
>> Cc: Quentin Schulz <foss+kernel at 0leil.net>
>> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
>> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
>> ---
>>
>> Note/RFC: as opposed to gru DTSI, max-frequency is used here instead of
>> assigned-clock-rates.
>>
>> AFAIU, max-frequency applies to the SD bus rate, while
>> assigned-clock-rates applies to the clock fed to the SD host controller
>> inside the SoC. max-frequency does not interact with the clock subsystem
>> AFAICT. assigned-clock-rates sets the clock rate at probe, regardless of
>> eMMC tuning.
>> Technically, the Arasan SDHC IP supports silicon-hardcoded clock
>> multiplier so I think setting assigned-clock-rates as a way of rate
>> limiting the eMMC block is incorrect and max-frequency should be used
>> instead (as done in this patch). Otherwise the SDHC could still potentially
>> derive a 200MHz clock from a lower rate clock thanks to its multiplier.
>>
>>   arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>> index fb67db4619ea..a6108578aae0 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>> @@ -425,6 +425,12 @@ vcc5v0_host_en: vcc5v0-host-en {
>>   };
>>
>>   &sdhci {
>> +       /*
>> +        * Signal integrity isn't great at 200MHz but 100MHz has proven stable
>> +        * enough.
>> +        */
>> +       max-frequency = <100000000>;
>> +
>>          bus-width = <8>;
>>          mmc-hs400-1_8v;
>>          mmc-hs400-enhanced-strobe;
> 
> I don't have these boards nor the schematics handy for them, but
> wouldn't it be better to simply switch to mmc-hs200-1_8v?

Thanks for the suggestion, I just tested, by removing mmc-hs400-1_8v; 
and mmc-hs400-enhanced-strobe; but keeping the clock rate at 200MHz and 
adding mmc-hs200-1_8v; failed a basic dd test.

Cheers,
Quentin

> Other rk3399 boards don't have issues with hs200 at full 200mhz, and
> as I understand it hs400-es exhibits stability issues on most rk3399
> boards.
> 
> Feel free to disregard my comments if you've already tested this.
> 
>> --
>> 2.34.1
>>
>>
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip at lists.infradead.org
>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_mailman_listinfo_linux-2Drockchip&d=DwIBaQ&c=_sEr5x9kUWhuk4_nFwjJtA&r=LYjLexDn7rXIzVmkNPvw5ymA1XTSqHGq8yBP6m6qZZ4njZguQhZhkI_-172IIy1t&m=OTusi9XARCbef1Ba5t1gv4_LqRkOaxFY3UtvYky6NVLpeiziqqmdOJ8-R5WXWFNr&s=xBnqhBu20rxvu_V-5EhXyA_yNxcJpa4Dq6HO2Ow3Gk8&e=


From helgaas at kernel.org  Thu Jan 20 08:22:41 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 20 Jan 2022 10:22:41 -0600
Subject: [PATCH v6] ACPI: explicit init HEST, SDEI and GHES in apci_init
In-Reply-To: <20220120050522.23689-1-xueshuai@linux.alibaba.com>
Message-ID: <20220120162241.GA1047212@bhelgaas>

On Thu, Jan 20, 2022 at 01:05:22PM +0800, Shuai Xue wrote:
> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
> the estatus memory pool. On the other hand, ghes_init() relies on
> sdei_init() to detect the SDEI version and (un)register events. The
> dependencies are as follows:
> 
>     ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
>     ghes_init() => sdei_init()
> 
> HEST is not PCI-specific and initcall ordering is implicit and not
> well-defined within a level.
> 
> Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
> convert ghes_init() and sdei_init() from initcalls to explicit calls in the
> following order:
> 
>     acpi_hest_init()
>     sdei_init()
>     ghes_init()
> 
> Suggested-by: Bjorn Helgaas <helgaas at kernel.org>

I didn't suggest the approach; I just reviewed the patch and the
commit log and proposed moving it out of acpi_pci_root_init().  That
doesn't need to be acknowledged.

> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>

Reviewed-by: Bjorn Helgaas <bhelgaas at google.com>

Minor extra "return" below.

> ---
>  drivers/acpi/apei/ghes.c    | 17 +++++++----------
>  drivers/acpi/bus.c          |  4 ++++
>  drivers/acpi/pci_root.c     |  3 ---
>  drivers/firmware/arm_sdei.c | 13 ++-----------
>  include/acpi/apei.h         |  4 +++-
>  include/linux/arm_sdei.h    |  2 ++
>  6 files changed, 18 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 0c5c9acc6254..bed4f10cfcb8 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -1457,33 +1457,33 @@ static struct platform_driver ghes_platform_driver = {
>  	.remove		= ghes_remove,
>  };
>  
> -static int __init ghes_init(void)
> +void __init ghes_init(void)
>  {
>  	int rc;
>  
>  	if (acpi_disabled)
> -		return -ENODEV;
> +		return;
>  
>  	switch (hest_disable) {
>  	case HEST_NOT_FOUND:
> -		return -ENODEV;
> +		return;
>  	case HEST_DISABLED:
>  		pr_info(GHES_PFX "HEST is not enabled!\n");
> -		return -EINVAL;
> +		return;
>  	default:
>  		break;
>  	}
>  
>  	if (ghes_disable) {
>  		pr_info(GHES_PFX "GHES is not enabled!\n");
> -		return -EINVAL;
> +		return;
>  	}
>  
>  	ghes_nmi_init_cxt();
>  
>  	rc = platform_driver_register(&ghes_platform_driver);
>  	if (rc)
> -		goto err;
> +		return;
>  
>  	rc = apei_osc_setup();
>  	if (rc == 0 && osc_sb_apei_support_acked)
> @@ -1495,8 +1495,5 @@ static int __init ghes_init(void)
>  	else
>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
>  
> -	return 0;
> -err:
> -	return rc;
> +	return;

Unnecessary "return".

>  }
> -device_initcall(ghes_init);
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 07f604832fd6..1dcd71df2cd5 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -30,6 +30,7 @@
>  #include <linux/acpi_viot.h>
>  #include <linux/pci.h>
>  #include <acpi/apei.h>
> +#include <linux/arm_sdei.h>

This "arm" looks a little out of place in this supposedly arch-generic
code.  Not really a new thing with this patch, since this #include
already appears in drivers/acpi/apei/ghes.c.  Maybe it's unavoidable.

>  #include <linux/suspend.h>
>  #include <linux/prmt.h>
>  
> @@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
>  
>  	pci_mmcfg_late_init();
>  	acpi_iort_init();
> +	acpi_hest_init();
> +	sdei_init();
> +	ghes_init();
>  	acpi_scan_init();
>  	acpi_ec_init();
>  	acpi_debugfs_init();
> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
> index b76db99cced3..6f9e75d14808 100644
> --- a/drivers/acpi/pci_root.c
> +++ b/drivers/acpi/pci_root.c
> @@ -22,8 +22,6 @@
>  #include <linux/slab.h>
>  #include <linux/dmi.h>
>  #include <linux/platform_data/x86/apple.h>
> -#include <acpi/apei.h>	/* for acpi_hest_init() */
> -
>  #include "internal.h"
>  
>  #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
> @@ -943,7 +941,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>  
>  void __init acpi_pci_root_init(void)
>  {
> -	acpi_hest_init();
>  	if (acpi_pci_disabled)
>  		return;
>  
> diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
> index a7e762c352f9..1e1a51510e83 100644
> --- a/drivers/firmware/arm_sdei.c
> +++ b/drivers/firmware/arm_sdei.c
> @@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
>  	return true;
>  }
>  
> -static int __init sdei_init(void)
> +void __init sdei_init(void)
>  {
>  	struct platform_device *pdev;
>  	int ret;
>  
>  	ret = platform_driver_register(&sdei_driver);
>  	if (ret || !sdei_present_acpi())
> -		return ret;
> +		return;
>  
>  	pdev = platform_device_register_simple(sdei_driver.driver.name,
>  					       0, NULL, 0);
> @@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
>  		pr_info("Failed to register ACPI:SDEI platform device %d\n",
>  			ret);
>  	}
> -
> -	return ret;
>  }
>  
> -/*
> - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
> - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
> - * by device_initcall(). We want to be called in the middle.
> - */
> -subsys_initcall_sync(sdei_init);
> -
>  int sdei_event_handler(struct pt_regs *regs,
>  		       struct sdei_registered_event *arg)
>  {
> diff --git a/include/acpi/apei.h b/include/acpi/apei.h
> index ece0a8af2bae..4e60dd73c3bb 100644
> --- a/include/acpi/apei.h
> +++ b/include/acpi/apei.h
> @@ -27,14 +27,16 @@ extern int hest_disable;
>  extern int erst_disable;
>  #ifdef CONFIG_ACPI_APEI_GHES
>  extern bool ghes_disable;
> +void __init ghes_init(void);
>  #else
>  #define ghes_disable 1
> +static inline void ghes_init(void) { }
>  #endif
>  
>  #ifdef CONFIG_ACPI_APEI
>  void __init acpi_hest_init(void);
>  #else
> -static inline void acpi_hest_init(void) { return; }
> +static inline void acpi_hest_init(void) { }
>  #endif
>  
>  int erst_write(const struct cper_record_header *record);
> diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
> index 0a241c5c911d..14dc461b0e82 100644
> --- a/include/linux/arm_sdei.h
> +++ b/include/linux/arm_sdei.h
> @@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
>  /* For use by arch code when CPU hotplug notifiers are not appropriate. */
>  int sdei_mask_local_cpu(void);
>  int sdei_unmask_local_cpu(void);
> +void __init sdei_init(void);
>  #else
>  static inline int sdei_mask_local_cpu(void) { return 0; }
>  static inline int sdei_unmask_local_cpu(void) { return 0; }
> +static inline void sdei_init(void) { }
>  #endif /* CONFIG_ARM_SDE_INTERFACE */
>  
>  
> -- 
> 2.20.1.12.g72788fdb
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From rafael at kernel.org  Thu Jan 20 08:24:24 2022
From: rafael at kernel.org (Rafael J. Wysocki)
Date: Thu, 20 Jan 2022 17:24:24 +0100
Subject: [PATCH v5] ACPI: Move sdei_init and ghes_init ahead to handle
 platform errors earlier
In-Reply-To: <20220119204259.GA962224@bhelgaas>
References: <e57cc874-dacd-912d-4282-3cb6b1b77323@linux.alibaba.com>
 <20220119204259.GA962224@bhelgaas>
Message-ID: <CAJZ5v0j34en1bCZamSGA9XgC-VZRgLgiA89o060_FAWWf21Byw@mail.gmail.com>

On Wed, Jan 19, 2022 at 9:43 PM Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> On Wed, Jan 19, 2022 at 02:40:11PM +0800, Shuai Xue wrote:
> > [+to Rafael, question about HEST/GHES/SDEI init]
> >
> > Hi, Bjorn,
> >
> > Thank you for your comments and quick reply.
> >
> > ? 2022/1/19 AM6:49, Bjorn Helgaas ??:
> > > On Sun, Jan 16, 2022 at 04:43:10PM +0800, Shuai Xue wrote:
> > >> On an ACPI system, ACPI is initialised very early from a
> > >> subsys_initcall(), while SDEI is not ready until a
> > >> subsys_initcall_sync(). This patch is to reduce the time before GHES
> > >> initialization.
> > >>
> > >> The SDEI driver provides functions (e.g. apei_sdei_register_ghes(),
> > >> apei_sdei_unregister_ghes()) to register or unregister event callback
> > >> for dispatcher in firmware. When the GHES driver probing, it registers
> > >> the corresponding callback according to the notification type specified
> > >> by GHES. If the GHES notification type is SDEI, the GHES driver will
> > >> call apei_sdei_register_ghes() to register event call.
> > >>
> > >> When the firmware emits an event, it migrates the handling of the event
> > >> into the kernel at the registered entry-point __sdei_asm_handler. And
> > >> finally, the kernel will call the registered event callback and return
> > >> status_code to indicate the status of event handling. SDEI_EV_FAILED
> > >> indicates that the kernel failed to handle the event.
> > >>
> > >> Consequently, when an error occurs during kernel booting, the kernel is
> > >> unable to handle and report errors until the GHES driver is initialized
> > >> by device_initcall(), in which the event callback is registered.  For
> > >> example, when the kernel booting, the console logs many times from
> > >> firmware before GHES drivers init in our platform:
> > >>
> > >>    Trip in MM PCIe RAS handle(Intr:910)
> > >>    Clean PE[1.1.1] ERR_STS:0x4000100 -> 0 INT_STS:F0000000
> > >>    Find RP(98:1.0)
> > >>    --Walk dev(98:1.0) CE:0 UCE:4000
> > >>    ...
> > >>    ERROR:   sdei_dispatch_event(32a) ret:-1
> > >>    --handler(910) end
> > >
> > > If I understand correctly, the firmware noticed an error, tried to
> > > report it to the kernel, and is complaining because the kernel isn't
> > > ready to handle it yet.  And the reason for this patch is to reduce
> > > these complaints from the firmware.
> >
> > My thoughts exactly :)
> >
> > > That doesn't seem like a very good reason for this patch.  There is
> > > *always* a window before the kernel is ready to handle events from the
> > > firmware.
> >
> > Yes, there is always a window. But if we could do better in kernel that
> > reduces the window by 90% (from 33 seconds to 3 second), why not?
> >
> > > Why is the firmware noticing these errors in the first place?  If
> > > you're seeing these complaints regularly, my guess is that either you
> > > have some terrible hardware or (more likely) the firmware isn't
> > > clearing some expected error condition correctly.  For example, maybe
> > > the Unsupported Request errors that happen while enumerating PCIe
> > > devices are being reported.
> > >
> > > If you register the callback function, the kernel will now start
> > > seeing these error reports.  What happens then?  Does the kernel log
> > > the errors somewhere?  Is that better than the current situation where
> > > the firmware logs them?
> >
> > Yep, it is a hardware issue. The firmware only logs in console
> > (ttyAMA0) and we can not see it in kernel side. After the kernel
> > starts seeing these error reports, we could see EDAC/ghes and
> > efi/cper detailed logs in dmesg. We did not notice the problem until
> > we check the console log, which inspired us to reduce the window
> > when kernel startup, so that we can see the message clearly and
> > properly. I think the intuition is to check the log of dmesg, not
> > the console.
>
> > > However, I DO think that:
> > >
> > >   - Removing acpi_hest_init() from acpi_pci_root_init(), and
> > >
> > >   - Converting ghes_init() and sdei_init() from initcalls to explicit
> > >     calls
> > >
> > > are very good reasons to do something like this patch because HEST is
> > > not PCI-specific, and IMO, explicit calls are better than initcalls
> > > because initcall ordering is implicit and not well-defined within a
> > > level.
> >
> > Haha, if the above reasons still don't convince you, I would like to
> > accept yours :) Should we do it in one patch or separate it into two
> > patches?
>
> IMO, this can be done in one patch, but this would probably go via
> Rafael.

Yes, that would make sense IMO.


From narmstrong at baylibre.com  Thu Jan 20 08:26:20 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 17:26:20 +0100
Subject: [PATCH v2 3/6] drm/meson: venc: add ENCL encoder setup for
 MIPI-DSI output
In-Reply-To: <20220120083357.1541262-4-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-4-narmstrong@baylibre.com>
Message-ID: <17810339-0e9c-0042-b6f7-927f5fe00421@baylibre.com>

On 20/01/2022 09:33, Neil Armstrong wrote:
> This adds supports for the ENCL encoder connected to a MIPI-DSI transceiver on the
> Amlogic AXG, G12A, G12B & SM1 SoCs.
> 
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---
>  drivers/gpu/drm/meson/meson_registers.h |  15 ++
>  drivers/gpu/drm/meson/meson_venc.c      | 211 +++++++++++++++++++++++-
>  drivers/gpu/drm/meson/meson_venc.h      |   6 +
>  drivers/gpu/drm/meson/meson_vpp.h       |   2 +
>  4 files changed, 232 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
> index 0f3cafab8860..a422a8df1641 100644
> --- a/drivers/gpu/drm/meson/meson_registers.h
> +++ b/drivers/gpu/drm/meson/meson_registers.h
> @@ -1300,13 +1300,28 @@
>  #define RDMA_STATUS2 0x1116
>  #define RDMA_STATUS3 0x1117
>  #define L_GAMMA_CNTL_PORT 0x1400
> +#define		L_GAMMA_CNTL_PORT_VCOM_POL	BIT(7)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_RVS_OUT	BIT(6)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_ADR_RDY	BIT(5)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_WR_RDY	BIT(4)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_RD_RDY	BIT(3)	/* Read Only */
> +#define		L_GAMMA_CNTL_PORT_TR		BIT(2)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_SET		BIT(1)	/* RW */
> +#define		L_GAMMA_CNTL_PORT_EN		BIT(0)	/* RW */
>  #define L_GAMMA_DATA_PORT 0x1401
>  #define L_GAMMA_ADDR_PORT 0x1402
> +#define		L_GAMMA_ADDR_PORT_RD		BIT(12)
> +#define		L_GAMMA_ADDR_PORT_AUTO_INC	BIT(11)
> +#define		L_GAMMA_ADDR_PORT_SEL_R		BIT(10)
> +#define		L_GAMMA_ADDR_PORT_SEL_G		BIT(9)
> +#define		L_GAMMA_ADDR_PORT_SEL_B		BIT(8)
> +#define		L_GAMMA_ADDR_PORT_ADDR		GENMASK(7, 0)
>  #define L_GAMMA_VCOM_HSWITCH_ADDR 0x1403
>  #define L_RGB_BASE_ADDR 0x1405
>  #define L_RGB_COEFF_ADDR 0x1406
>  #define L_POL_CNTL_ADDR 0x1407
>  #define L_DITH_CNTL_ADDR 0x1408
> +#define		L_DITH_CNTL_DITH10_EN	BIT(10)
>  #define L_GAMMA_PROBE_CTRL 0x1409
>  #define L_GAMMA_PROBE_COLOR_L 0x140a
>  #define L_GAMMA_PROBE_COLOR_H 0x140b

OK Somehow the following disappeared from the patchset...

 #define VENC_INTCTRL 0x1b6e
 #define		VENC_INTCTRL_ENCI_LNRST_INT_EN  BIT(1)
-#define		VENC_INTCTRL_ENCP_LNRST_INT_EN  BIT(9)
 #define VENC_INTFLAG 0x1b6f

 #define ENCL_VIDEO_MODE 0x1ca7
-#define		ENCL_PX_LN_CNT_SHADOW_EN	BIT(15)
 #define ENCL_VIDEO_MODE_ADV 0x1ca8
-#define		ENCL_VIDEO_MODE_ADV_VFIFO_EN	BIT(3)
-#define		ENCL_VIDEO_MODE_ADV_GAIN_HDTV	BIT(4)
-#define		ENCL_SEL_GAMMA_RGB_IN		BIT(10)
 #define ENCL_DBG_PX_RST 0x1ca9
 #define ENCL_VIDEO_FILT_CTRL 0x1cc2

-#define		ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER	BIT(12)
 #define ENCL_VIDEO_OFLD_VPEQ_OFST 0x1cc3

 #define ENCL_VIDEO_RGBIN_CTRL 0x1cc7
-#define		ENCL_VIDEO_RGBIN_RGB	BIT(0)
-#define		ENCL_VIDEO_RGBIN_ZBLK	BIT(1)
 #define ENCL_MAX_LINE_SWITCH_POINT 0x1cc8


 #define L_TCON_MISC_SEL_ADDR 0x1441
-#define		L_TCON_MISC_SEL_STV1	BIT(4)
-#define		L_TCON_MISC_SEL_STV2	BIT(5)
 #define L_DUAL_PORT_CNTL_ADDR 0x1442

I'll resend with those

> diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
> index 3c55ed003359..eb2ac0549d46 100644
> --- a/drivers/gpu/drm/meson/meson_venc.c
> +++ b/drivers/gpu/drm/meson/meson_venc.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/export.h>
> +#include <linux/iopoll.h>
>  
>  #include <drm/drm_modes.h>
>  
> @@ -1557,6 +1558,205 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
>  }
>  EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
>  
> +static unsigned short meson_encl_gamma_table[256] = {
> +	0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
> +	64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124,
> +	128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188,
> +	192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252,
> +	256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316,
> +	320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380,
> +	384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444,
> +	448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508,
> +	512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572,
> +	576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636,
> +	640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700,
> +	704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764,
> +	768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828,
> +	832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892,
> +	896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956,
> +	960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020,
> +};
> +
> +static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data,
> +				       u32 rgb_mask)
> +{
> +	int i, ret;
> +	u32 reg;
> +
> +	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0,
> +			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
> +
> +	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
> +	if (ret)
> +		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
> +
> +	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
> +		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0),
> +		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
> +
> +	for (i = 0; i < 256; i++) {
> +		ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +						 reg, reg & L_GAMMA_CNTL_PORT_WR_RDY,
> +						 10, 10000);
> +		if (ret)
> +			pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__);
> +
> +		writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT));
> +	}
> +
> +	ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT),
> +					 reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000);
> +	if (ret)
> +		pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__);
> +
> +	writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask |
> +		       FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23),
> +		       priv->io_base + _REG(L_GAMMA_ADDR_PORT));
> +}
> +
> +void meson_encl_load_gamma(struct meson_drm *priv)
> +{
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R);
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G);
> +	meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B);
> +
> +	writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN,
> +			    priv->io_base + _REG(L_GAMMA_CNTL_PORT));
> +}
> +
> +void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
> +				  const struct drm_display_mode *mode)
> +{
> +	unsigned int max_pxcnt;
> +	unsigned int max_lncnt;
> +	unsigned int havon_begin;
> +	unsigned int havon_end;
> +	unsigned int vavon_bline;
> +	unsigned int vavon_eline;
> +	unsigned int hso_begin;
> +	unsigned int hso_end;
> +	unsigned int vso_begin;
> +	unsigned int vso_end;
> +	unsigned int vso_bline;
> +	unsigned int vso_eline;
> +
> +	max_pxcnt = mode->htotal - 1;
> +	max_lncnt = mode->vtotal - 1;
> +	havon_begin = mode->htotal - mode->hsync_start;
> +	havon_end = havon_begin + mode->hdisplay - 1;
> +	vavon_bline = mode->vtotal - mode->vsync_start;
> +	vavon_eline = vavon_bline + mode->vdisplay - 1;
> +	hso_begin = 0;
> +	hso_end = mode->hsync_end - mode->hsync_start;
> +	vso_begin = 0;
> +	vso_end = 0;
> +	vso_bline = 0;
> +	vso_eline = mode->vsync_end - mode->vsync_start;
> +
> +	meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL);
> +
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +	writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE));
> +	writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN |
> +		       ENCL_VIDEO_MODE_ADV_GAIN_HDTV |
> +		       ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +
> +	writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER,
> +		       priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL));
> +	writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT));
> +	writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN));
> +	writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE));
> +
> +	writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN));
> +	writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END));
> +	writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN));
> +	writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END));
> +	writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE));
> +	writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE));
> +	writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK,
> +		       priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL));
> +
> +	/* default black pattern */
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB));
> +	writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR));
> +	writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN));
> +	writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0,
> +			    priv->io_base + _REG(ENCL_VIDEO_MODE_ADV));
> +
> +	writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN));
> +
> +	writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR));
> +	writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */
> +
> +	writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR));
> +
> +	/* DE signal for TTL */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR));
> +
> +	/* DE signal for TTL */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR));
> +
> +	/* Hsync signal for TTL */
> +	if (mode->flags & DRM_MODE_FLAG_PHSYNC) {
> +		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR));
> +		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR));
> +	} else {
> +		writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR));
> +		writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR));
> +	}
> +	writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR));
> +
> +	/* Vsync signal for TTL */
> +	writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR));
> +	writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR));
> +	if (mode->flags & DRM_MODE_FLAG_PVSYNC) {
> +		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR));
> +		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR));
> +	} else {
> +		writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR));
> +		writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR));
> +	}
> +
> +	/* DE signal */
> +	writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR));
> +	writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR));
> +	writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR));
> +	writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR));
> +
> +	/* Hsync signal */
> +	writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR));
> +	writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR));
> +	writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR));
> +	writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR));
> +
> +	/* Vsync signal */
> +	writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR));
> +	writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR));
> +	writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR));
> +	writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR));
> +
> +	writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR));
> +	writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2,
> +		       priv->io_base + _REG(L_TCON_MISC_SEL_ADDR));
> +
> +	priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI;
> +}
> +EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set);
> +
>  void meson_venci_cvbs_mode_set(struct meson_drm *priv,
>  			       struct meson_cvbs_enci_mode *mode)
>  {
> @@ -1747,8 +1947,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
>  
>  void meson_venc_enable_vsync(struct meson_drm *priv)
>  {
> -	writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
> -		       priv->io_base + _REG(VENC_INTCTRL));
> +	switch (priv->venc.current_mode) {
> +	case MESON_VENC_MODE_MIPI_DSI:
> +		writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN,
> +			       priv->io_base + _REG(VENC_INTCTRL));
> +		break;
> +	default:
> +		writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
> +			       priv->io_base + _REG(VENC_INTCTRL));
> +	}
>  	regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
>  }
>  
> diff --git a/drivers/gpu/drm/meson/meson_venc.h b/drivers/gpu/drm/meson/meson_venc.h
> index 9138255ffc9e..0f59adb1c6db 100644
> --- a/drivers/gpu/drm/meson/meson_venc.h
> +++ b/drivers/gpu/drm/meson/meson_venc.h
> @@ -21,6 +21,7 @@ enum {
>  	MESON_VENC_MODE_CVBS_PAL,
>  	MESON_VENC_MODE_CVBS_NTSC,
>  	MESON_VENC_MODE_HDMI,
> +	MESON_VENC_MODE_MIPI_DSI,
>  };
>  
>  struct meson_cvbs_enci_mode {
> @@ -47,6 +48,9 @@ struct meson_cvbs_enci_mode {
>  	unsigned int analog_sync_adj;
>  };
>  
> +/* LCD Encoder gamma setup */
> +void meson_encl_load_gamma(struct meson_drm *priv);
> +
>  /* HDMI Clock parameters */
>  enum drm_mode_status
>  meson_venc_hdmi_supported_mode(const struct drm_display_mode *mode);
> @@ -63,6 +67,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
>  			      unsigned int ycrcb_map,
>  			      bool yuv420_mode,
>  			      const struct drm_display_mode *mode);
> +void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv,
> +				  const struct drm_display_mode *mode);
>  unsigned int meson_venci_get_field(struct meson_drm *priv);
>  
>  void meson_venc_enable_vsync(struct meson_drm *priv);
> diff --git a/drivers/gpu/drm/meson/meson_vpp.h b/drivers/gpu/drm/meson/meson_vpp.h
> index afc9553ed8d3..b790042a1650 100644
> --- a/drivers/gpu/drm/meson/meson_vpp.h
> +++ b/drivers/gpu/drm/meson/meson_vpp.h
> @@ -12,6 +12,8 @@
>  struct drm_rect;
>  struct meson_drm;
>  
> +/* Mux VIU/VPP to ENCL */
> +#define MESON_VIU_VPP_MUX_ENCL	0x0
>  /* Mux VIU/VPP to ENCI */
>  #define MESON_VIU_VPP_MUX_ENCI	0x5
>  /* Mux VIU/VPP to ENCP */
> 



From alexandru.elisei at arm.com  Thu Jan 20 08:28:47 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 20 Jan 2022 16:28:47 +0000
Subject: [PATCH v5 19/69] KVM: arm64: nv: Handle SPSR_EL2 specially
In-Reply-To: <20211129200150.351436-20-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-20-maz@kernel.org>
Message-ID: <YemNv+Bmr4hXmi3P@monolith.localdoman>

Hi Marc,

On Mon, Nov 29, 2021 at 08:01:00PM +0000, Marc Zyngier wrote:
> SPSR_EL2 needs special attention when running nested on ARMv8.3:
> 
> If taking an exception while running at vEL2 (actually EL1), the
> HW will update the SPSR_EL1 register with the EL1 mode. We need
> to track this in order to make sure that accesses to the virtual
> view of SPSR_EL2 is correct.
> 
> To do so, we place an illegal value in SPSR_EL1.M, and patch it
> accordingly if required when accessing it.

When KVM runs a L1 guest hypervisor with hardware HCR_EL2.NV1 clear (virtual
HCR_EL2.E2H set), when an exception is taken from vEL2 to vEL2, SPSR_EL1.M is
automatically set to CurrentEL_EL2. But this doesn't happen when hardware NV1 is
set (virtual HCR_EL2.E2H unset) and as far as I can tell this patch does the
right thing to emulate it in software:

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>

Thanks,
Alex

> 
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_emulate.h | 37 ++++++++++++++++++++++++++++
>  arch/arm64/kvm/sys_regs.c            | 23 +++++++++++++++--
>  2 files changed, 58 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index 46c849ba281e..2db11ff3fdad 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -241,6 +241,43 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
>  	return __is_hyp_ctxt(&vcpu->arch.ctxt);
>  }
>  
> +static inline u64 __fixup_spsr_el2_write(struct kvm_cpu_context *ctxt, u64 val)
> +{
> +	if (!__vcpu_el2_e2h_is_set(ctxt)) {
> +		/*
> +		 * Clear the .M field when writing SPSR to the CPU, so that we
> +		 * can detect when the CPU clobbered our SPSR copy during a
> +		 * local exception.
> +		 */
> +		val &= ~0xc;
> +	}
> +
> +	return val;
> +}
> +
> +static inline u64 __fixup_spsr_el2_read(const struct kvm_cpu_context *ctxt, u64 val)
> +{
> +	if (__vcpu_el2_e2h_is_set(ctxt))
> +		return val;
> +
> +	/*
> +	 * SPSR.M == 0 means the CPU has not touched the SPSR, so the
> +	 * register has still the value we saved on the last write.
> +	 */
> +	if ((val & 0xc) == 0)
> +		return ctxt_sys_reg(ctxt, SPSR_EL2);
> +
> +	/*
> +	 * Otherwise there was a "local" exception on the CPU,
> +	 * which from the guest's point of view was being taken from
> +	 * EL2 to EL2, although it actually happened to be from
> +	 * EL1 to EL1.
> +	 * So we need to fix the .M field in SPSR, to make it look
> +	 * like EL2, which is what the guest would expect.
> +	 */
> +	return (val & ~0x0c) | CurrentEL_EL2;
> +}
> +
>  /*
>   * The layout of SPSR for an AArch32 state is different when observed from an
>   * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 61596355e42d..875040bcfbe1 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -133,11 +133,14 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
>  			goto memory_read;
>  
>  		/*
> -		 * ELR_EL2 is special cased for now.
> +		 * ELR_EL2 and SPSR_EL2 are special cased for now.
>  		 */
>  		switch (reg) {
>  		case ELR_EL2:
>  			return read_sysreg_el1(SYS_ELR);
> +		case SPSR_EL2:
> +			val = read_sysreg_el1(SYS_SPSR);
> +			return __fixup_spsr_el2_read(&vcpu->arch.ctxt, val);
>  		}
>  
>  		/*
> @@ -194,6 +197,10 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
>  		case ELR_EL2:
>  			write_sysreg_el1(val, SYS_ELR);
>  			return;
> +		case SPSR_EL2:
> +			val = __fixup_spsr_el2_write(&vcpu->arch.ctxt, val);
> +			write_sysreg_el1(val, SYS_SPSR);
> +			return;
>  		}
>  
>  		/* No EL1 counterpart? We're done here.? */
> @@ -1620,6 +1627,18 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu,
>  	return true;
>  }
>  
> +static bool access_spsr_el2(struct kvm_vcpu *vcpu,
> +			    struct sys_reg_params *p,
> +			    const struct sys_reg_desc *r)
> +{
> +	if (p->is_write)
> +		vcpu_write_sys_reg(vcpu, p->regval, SPSR_EL2);
> +	else
> +		p->regval = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> +
> +	return true;
> +}
> +
>  /*
>   * Architected system registers.
>   * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
> @@ -2052,7 +2071,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>  	{ SYS_DESC(SYS_VTCR_EL2), access_rw, reset_val, VTCR_EL2, 0 },
>  
>  	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
> -	{ SYS_DESC(SYS_SPSR_EL2), access_rw, reset_val, SPSR_EL2, 0 },
> +	{ SYS_DESC(SYS_SPSR_EL2), access_spsr_el2, reset_val, SPSR_EL2, 0 },
>  	{ SYS_DESC(SYS_ELR_EL2), access_rw, reset_val, ELR_EL2, 0 },
>  	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
>  
> -- 
> 2.30.2
> 


From narmstrong at baylibre.com  Thu Jan 20 08:30:14 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 20 Jan 2022 17:30:14 +0100
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
 <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
Message-ID: <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>

Hi,

On 20/01/2022 15:24, Jagan Teki wrote:
> On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>>
>> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
>> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
>> Glue on other Amlogic SoCs.
>>
>> This adds support for the Glue managing the transceiver, mimicing the init flow provided
>> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
>> Analog PHY in the proper way.
>>
>> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
>> DW-MIPI-DSI transceiver.
>>
>> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
>> ---
>>  drivers/gpu/drm/meson/Kconfig             |   7 +
>>  drivers/gpu/drm/meson/Makefile            |   1 +
>>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
>>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
>>  4 files changed, 525 insertions(+)
>>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
>>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
>>
>> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
>> index 6c70fc3214af..71a1364b51e1 100644
>> --- a/drivers/gpu/drm/meson/Kconfig
>> +++ b/drivers/gpu/drm/meson/Kconfig
>> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
>>         default y if DRM_MESON
>>         select DRM_DW_HDMI
>>         imply DRM_DW_HDMI_I2S_AUDIO
>> +
>> +config DRM_MESON_DW_MIPI_DSI
>> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
>> +       depends on DRM_MESON
>> +       default y if DRM_MESON
>> +       select DRM_DW_MIPI_DSI
>> +       select GENERIC_PHY_MIPI_DPHY
>> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
>> index 833e18c20603..43071bdbd4b9 100644
>> --- a/drivers/gpu/drm/meson/Makefile
>> +++ b/drivers/gpu/drm/meson/Makefile
>> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
>>
>>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
>>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
>> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
> 
> Can the naming convention prefix with dw-mipi-dsi like other glue
> drivers follow?

Seems only rockchip names their glue like that:

$ find drivers/gpu/drm/ -name "*dw*mipi*dsi*.c"
drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c

If you look at dw-hdmi it's even worse:

$ find drivers/gpu/drm/ -name "*dw*hdmi*.c" | grep -v mod
drivers/gpu/drm/meson/meson_dw_hdmi.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
drivers/gpu/drm/imx/dw_hdmi-imx.c
drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

Neil
> 
> Jagan.
> 


From robh at kernel.org  Thu Jan 20 08:31:52 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 10:31:52 -0600
Subject: [PATCH v2 00/11] PCI: Small improvements for pci-bridge-emul and
 mvebu
In-Reply-To: <20220104153529.31647-1-pali@kernel.org>
References: <20211221141455.30011-1-pali@kernel.org>
 <20220104153529.31647-1-pali@kernel.org>
Message-ID: <YemOeJ2qIJV9dzO6@robh.at.kernel.org>

On Tue, Jan 04, 2022 at 04:35:18PM +0100, Pali Roh?r wrote:
> This patch series contains small improvements for pci-bridge-emul and
> mvebu drivers. This patch series is based on top of the patches:
> https://lore.kernel.org/linux-pci/20211125124605.25915-1-pali at kernel.org/
> (which are now in pci/mvebu branch)
> 
> In V2 was added comment into code explaining PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
> and PCI_BRIDGE_EMUL_NO_IO_FORWARD flags.
> 
> Pali Roh?r (11):
>   MAINTAINERS: Add Pali Roh?r as pci-mvebu.c maintainer
>   PCI: pci-bridge-emul: Make struct pci_bridge_emul_ops as const
>   PCI: pci-bridge-emul: Rename PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR to
>     PCI_BRIDGE_EMUL_NO_PREFMEM_FORWARD
>   PCI: pci-bridge-emul: Add support for new flag
>     PCI_BRIDGE_EMUL_NO_IO_FORWARD
>   PCI: mvebu: Add help string for CONFIG_PCI_MVEBU option
>   PCI: mvebu: Remove duplicate nports assignment
>   PCI: mvebu: Set PCI_BRIDGE_EMUL_NO_IO_FORWARD when IO is unsupported
>   PCI: mvebu: Properly initialize vendor, device and revision of
>     emulated bridge
>   PCI: mvebu: Update comment for PCI_EXP_LNKCAP register on emulated
>     bridge
>   PCI: mvebu: Update comment for PCI_EXP_LNKCTL register on emulated
>     bridge
>   PCI: mvebu: Fix reporting Data Link Layer Link Active on emulated
>     bridge

For the series,

Reviewed-by: Rob Herring <robh at kernel.org>

In the future, please do not thread new versions with the old version 
of the series.

Rob


From robin.murphy at arm.com  Thu Jan 20 08:37:01 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 20 Jan 2022 16:37:01 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <Yeldih0PHotN4/bn@shell.armlinux.org.uk>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
 <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
 <Yeldih0PHotN4/bn@shell.armlinux.org.uk>
Message-ID: <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>

On 2022-01-20 13:03, Russell King (Oracle) wrote:
> On Thu, Jan 20, 2022 at 12:22:35PM +0000, Robin Murphy wrote:
>> On 2022-01-19 19:12, Russell King (Oracle) wrote:
>>> On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
>>>> Indeed, my impression is that the only legitimate way to get hold of a page
>>>> pointer without assumed provenance is via pfn_to_page(), which is where
>>>> pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
>>>> tautology.
>>>
>>> That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
>>> values of pfn.
>>>
>>> Given how pfn_to_page() is defined in the sparsemem case:
>>>
>>> #define __pfn_to_page(pfn)                              \
>>> ({	unsigned long __pfn = (pfn);                    \
>>> 	struct mem_section *__sec = __pfn_to_section(__pfn);    \
>>> 	__section_mem_map_addr(__sec) + __pfn;          \
>>> })
>>> #define page_to_pfn __page_to_pfn
>>>
>>> that isn't the case, especially when looking at page_to_pfn():
>>>
>>> #define __page_to_pfn(pg)                                       \
>>> ({      const struct page *__pg = (pg);                         \
>>>           int __sec = page_to_section(__pg);                      \
>>> 	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
>>> })
>>>
>>> Where:
>>>
>>> static inline unsigned long page_to_section(const struct page *page)
>>> {
>>> 	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
>>> }
>>>
>>> So if page_to_section() returns something that is, e.g. zero for an
>>> invalid page in a non-zero section, you're not going to end up with
>>> the right pfn from page_to_pfn().
>>
>> Right, I emphasised "should" in an attempt to imply "in the absence of
>> serious bugs that have further-reaching consequences anyway".
>>
>>> As I've said now a couple of times, trying to determine of a struct
>>> page pointer is valid is the wrong question to be asking.
>>
>> And doing so in one single place, on the justification of avoiding an
>> incredibly niche symptom, is even more so. Not to mention that an address
>> size fault is one of the best possible outcomes anyway, vs. the untold
>> damage that may stem from accesses actually going through to random parts of
>> the physical memory map.
> 
> I don't see it as a "niche" symptom.

The commit message specifically cites a Data Abort "at address 
translation later". Broadly speaking, a Data Abort due to an address 
size fault only occurs if you've been lucky enough that the bogus PA 
which got mapped is so spectacularly wrong that it's beyond the range 
configured in TCR.IPS. How many other architectures even have a 
mechanism like that?

> If we start off with the struct page being invalid, then the result of
> page_to_pfn() can not be relied upon to produce something that is
> meaningful - which is exactly why the vmap() issue arises.
> 
> With a pfn_valid() check, we at least know that the PFN points at
> memory.

No, we know it points to some PA space which has a struct page to 
represent it. pfn_valid() only says that pfn_to_page() will yield a 
valid result. That also includes things like reserved pages covering 
non-RAM areas, where a kernel VA mapping existing at all could 
potentially be fatal to the system even if it's never explicitly 
accessed - for all we know it might be a carveout belonging to 
overly-aggressive Secure software such that even a speculative prefetch 
might trigger an instant system reset.

> However, that memory could be _anything_ in the system - it
> could be the kernel image, and it could give userspace access to
> change kernel code.
> 
> So, while it is useful to do a pfn_valid() check in vmap(), as I said
> to willy, this must _not_ be the primary check. It should IMHO use
> WARN_ON() to make it blatently obvious that it should be something we
> expect _not_ to trigger under normal circumstances, but is there to
> catch programming errors elsewhere.

Rather, "to partially catch unrelated programming errors elsewhere, 
provided the buggy code happens to call vmap() rather than any of the 
many other functions with a struct page * argument." That's where it 
stretches my definition of "useful" just a bit too far. It's not about 
perfect being the enemy of good, it's about why vmap() should be 
special, and death by a thousand "useful" cuts - if we don't trust the 
pointer, why not check its alignment for basic plausibility first? If it 
seems valid, why not check if the page flags look sensible to make sure? 
How many useful little checks is too many? Every bit of code footprint 
and execution overhead imposed unconditionally on all end users to 
theoretically save developers' debugging time still adds up. Although on 
that note, it looks like arch/arm's pfn_valid() is still a linear scan 
of the memblock array, so the overhead of adding that for every page in 
every vmap() might not even be so small...

Robin.


From lorenzo.pieralisi at arm.com  Thu Jan 20 08:38:19 2022
From: lorenzo.pieralisi at arm.com (Lorenzo Pieralisi)
Date: Thu, 20 Jan 2022 16:38:19 +0000
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <alpine.DEB.2.22.394.2201131801380.3166@ubuntu200401>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <20220105104602.GA4752@lpieralisi>
 <alpine.DEB.2.22.394.2201051530290.2489@ubuntu200401>
 <alpine.DEB.2.22.394.2201131801380.3166@ubuntu200401>
Message-ID: <20220120163819.GA8187@lpieralisi>

On Thu, Jan 13, 2022 at 06:17:13PM -0800, Ilkka Koskinen wrote:
> 
> Hi Lorenzo,
> 
> On Wed, 5 Jan 2022, Ilkka Koskinen wrote:
> > 
> > Hi Lorenzo,
> > 
> > On Wed, 5 Jan 2022, Lorenzo Pieralisi wrote:
> > > [+James, for SDEI bits]
> > > 
> > > On Thu, Dec 30, 2021 at 07:37:25PM -0800, Ilkka Koskinen wrote:
> > > > ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
> > > > Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
> > > > issue diagnostic dump and reset via an SDEI event or an interrupt.
> > > > This patch implements SDEI path.
> > > > 
> > > > [0] https://developer.arm.com/documentation/den0093/latest/
> > > > 
> > > > Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
> > > > ---
> > > >  drivers/acpi/arm64/Kconfig  |   8 +++
> > > >  drivers/acpi/arm64/Makefile |   1 +
> > > >  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
> > > >  3 files changed, 134 insertions(+)
> > > >  create mode 100644 drivers/acpi/arm64/agdi.c
> 
> <snip>
> 
> > > > diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
> > > > new file mode 100644
> > > > index 000000000000..6525ccbae5c1
> > > > --- /dev/null
> > > > +++ b/drivers/acpi/arm64/agdi.c
> 
> <snip>
> 
> > > > 
> > > > +static int __init agdi_init(void)
> > > > +{
> > > > +	int ret;
> > > > +	acpi_status status;
> > > > +	struct acpi_table_agdi *agdi_table;
> > > > +	struct agdi_data pdata;
> > > > +	struct platform_device *pdev;
> > > > +
> > > > +	if (acpi_disabled)
> > > > +		return 0;
> > > 
> > > Why don't we call agdi_init() from acpi_init() as we do for IORT/VIOT ?
> > > 
> > > I don't think it is necessary to add a device_initcall(), with related
> > > ordering dependencies.
> > 
> > That's a good point. I change it.
> 
> Actually, I looked at this more carefully. acpi_init() is called in
> subsys_initcall() while sdei_init() is called in subsys_initcall_sync().
> That is, if I call this function in acpi_init(), SDEI driver won't be ready
> and this driver fails to register the event.

Maybe this will help:

https://lore.kernel.org/linux-arm-kernel/20220120050522.23689-1-xueshuai at linux.alibaba.com/


From robh at kernel.org  Thu Jan 20 08:49:05 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 10:49:05 -0600
Subject: [PATCH v2 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220112151814.24361-9-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-9-pali@kernel.org>
Message-ID: <YemSgTfl7NiTfcKc@robh.at.kernel.org>

On Wed, Jan 12, 2022 at 04:18:11PM +0100, Pali Roh?r wrote:
> Split struct pci_ops between ops and child_ops. Member ops is used for
> accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> accessing real PCIe cards.
> 
> There is no need to mix these two struct pci_ops into one as PCI core code
> already provides separate callbacks via bridge->ops and bridge->child_ops.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
>  1 file changed, 44 insertions(+), 38 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index 9ea2f6a7c2b0..1e90ab888075 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  	mvebu_writel(port, mask, PCIE_MASK_OFF);
>  }
>  
> -static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> -				 struct pci_bus *bus,
> -				 u32 devfn, int where, int size, u32 *val)
> +static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> +						    struct pci_bus *bus,
> +						    int devfn);
> +
> +static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> +				    int size, u32 *val)
>  {
> -	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> +	struct mvebu_pcie *pcie = bus->sysdata;
> +	struct mvebu_pcie_port *port;
> +	void __iomem *conf_data;
> +
> +	port = mvebu_pcie_find_port(pcie, bus, devfn);
> +	if (!port) {
> +		*val = 0xffffffff;
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	}
> +
> +	if (!mvebu_pcie_link_up(port)) {
> +		*val = 0xffffffff;
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +	}
> +
> +	conf_data = port->base + PCIE_CONF_DATA_OFF;
>  
>  	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
>  		     PCIE_CONF_ADDR_OFF);
> @@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
>  	return PCIBIOS_SUCCESSFUL;
>  }
>  
> -static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
> -				 struct pci_bus *bus,
> -				 u32 devfn, int where, int size, u32 val)
> +static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
> +				    int where, int size, u32 val)
>  {
> -	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> +	struct mvebu_pcie *pcie = bus->sysdata;
> +	struct mvebu_pcie_port *port;
> +	void __iomem *conf_data;
> +

> +	port = mvebu_pcie_find_port(pcie, bus, devfn);
> +	if (!port)
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +	if (!mvebu_pcie_link_up(port))
> +		return PCIBIOS_DEVICE_NOT_FOUND;
> +
> +	conf_data = port->base + PCIE_CONF_DATA_OFF;

Again, the same setup code in read and write is a sign to use 
.map_bus(). You can copy it from my version I pointed you to.

Rob


From linux at armlinux.org.uk  Thu Jan 20 08:54:03 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 20 Jan 2022 16:54:03 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
 <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
 <Yeldih0PHotN4/bn@shell.armlinux.org.uk>
 <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>
Message-ID: <YemTq/yGkHQ+grd1@shell.armlinux.org.uk>

On Thu, Jan 20, 2022 at 04:37:01PM +0000, Robin Murphy wrote:
> On 2022-01-20 13:03, Russell King (Oracle) wrote:
> > On Thu, Jan 20, 2022 at 12:22:35PM +0000, Robin Murphy wrote:
> > > On 2022-01-19 19:12, Russell King (Oracle) wrote:
> > > > On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
> > > > > Indeed, my impression is that the only legitimate way to get hold of a page
> > > > > pointer without assumed provenance is via pfn_to_page(), which is where
> > > > > pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
> > > > > tautology.
> > > > 
> > > > That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
> > > > values of pfn.
> > > > 
> > > > Given how pfn_to_page() is defined in the sparsemem case:
> > > > 
> > > > #define __pfn_to_page(pfn)                              \
> > > > ({	unsigned long __pfn = (pfn);                    \
> > > > 	struct mem_section *__sec = __pfn_to_section(__pfn);    \
> > > > 	__section_mem_map_addr(__sec) + __pfn;          \
> > > > })
> > > > #define page_to_pfn __page_to_pfn
> > > > 
> > > > that isn't the case, especially when looking at page_to_pfn():
> > > > 
> > > > #define __page_to_pfn(pg)                                       \
> > > > ({      const struct page *__pg = (pg);                         \
> > > >           int __sec = page_to_section(__pg);                      \
> > > > 	(unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
> > > > })
> > > > 
> > > > Where:
> > > > 
> > > > static inline unsigned long page_to_section(const struct page *page)
> > > > {
> > > > 	return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> > > > }
> > > > 
> > > > So if page_to_section() returns something that is, e.g. zero for an
> > > > invalid page in a non-zero section, you're not going to end up with
> > > > the right pfn from page_to_pfn().
> > > 
> > > Right, I emphasised "should" in an attempt to imply "in the absence of
> > > serious bugs that have further-reaching consequences anyway".
> > > 
> > > > As I've said now a couple of times, trying to determine of a struct
> > > > page pointer is valid is the wrong question to be asking.
> > > 
> > > And doing so in one single place, on the justification of avoiding an
> > > incredibly niche symptom, is even more so. Not to mention that an address
> > > size fault is one of the best possible outcomes anyway, vs. the untold
> > > damage that may stem from accesses actually going through to random parts of
> > > the physical memory map.
> > 
> > I don't see it as a "niche" symptom.
> 
> The commit message specifically cites a Data Abort "at address translation
> later". Broadly speaking, a Data Abort due to an address size fault only
> occurs if you've been lucky enough that the bogus PA which got mapped is so
> spectacularly wrong that it's beyond the range configured in TCR.IPS. How
> many other architectures even have a mechanism like that?

I think we're misinterpreting each other.

> > If we start off with the struct page being invalid, then the result of
> > page_to_pfn() can not be relied upon to produce something that is
> > meaningful - which is exactly why the vmap() issue arises.
> > 
> > With a pfn_valid() check, we at least know that the PFN points at
> > memory.
> 
> No, we know it points to some PA space which has a struct page to represent
> it. pfn_valid() only says that pfn_to_page() will yield a valid result. That
> also includes things like reserved pages covering non-RAM areas, where a
> kernel VA mapping existing at all could potentially be fatal to the system
> even if it's never explicitly accessed - for all we know it might be a
> carveout belonging to overly-aggressive Secure software such that even a
> speculative prefetch might trigger an instant system reset.

So are you saying that the "address size fault" can happen because we've
mapped something for which pfn_valid() returns true?

> > However, that memory could be _anything_ in the system - it
> > could be the kernel image, and it could give userspace access to
> > change kernel code.
> > 
> > So, while it is useful to do a pfn_valid() check in vmap(), as I said
> > to willy, this must _not_ be the primary check. It should IMHO use
> > WARN_ON() to make it blatently obvious that it should be something we
> > expect _not_ to trigger under normal circumstances, but is there to
> > catch programming errors elsewhere.
> 
> Rather, "to partially catch unrelated programming errors elsewhere, provided
> the buggy code happens to call vmap() rather than any of the many other
> functions with a struct page * argument." That's where it stretches my
> definition of "useful" just a bit too far. It's not about perfect being the
> enemy of good, it's about why vmap() should be special, and death by a
> thousand "useful" cuts - if we don't trust the pointer, why not check its
> alignment for basic plausibility first? If it seems valid, why not check if
> the page flags look sensible to make sure? How many useful little checks is
> too many? Every bit of code footprint and execution overhead imposed
> unconditionally on all end users to theoretically save developers' debugging
> time still adds up. Although on that note, it looks like arch/arm's
> pfn_valid() is still a linear scan of the memblock array, so the overhead of
> adding that for every page in every vmap() might not even be so small...

Well, I think I've adequately explained why I believe:

	pfn_is_valid(page_to_pfn(page))

being used as the primary check is substandard, and will likely lead to
a future CVE. When generating an array of struct page's, I believe that
it is the responsibility for the generator to ensure that the array
only contains valid pages.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From pali at kernel.org  Thu Jan 20 08:55:22 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 17:55:22 +0100
Subject: [PATCH v2 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <YemSgTfl7NiTfcKc@robh.at.kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-9-pali@kernel.org>
 <YemSgTfl7NiTfcKc@robh.at.kernel.org>
Message-ID: <20220120165522.v2xitzokcom4phmw@pali>

On Thursday 20 January 2022 10:49:05 Rob Herring wrote:
> On Wed, Jan 12, 2022 at 04:18:11PM +0100, Pali Roh?r wrote:
> > Split struct pci_ops between ops and child_ops. Member ops is used for
> > accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> > accessing real PCIe cards.
> > 
> > There is no need to mix these two struct pci_ops into one as PCI core code
> > already provides separate callbacks via bridge->ops and bridge->child_ops.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
> >  1 file changed, 44 insertions(+), 38 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index 9ea2f6a7c2b0..1e90ab888075 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> >  	mvebu_writel(port, mask, PCIE_MASK_OFF);
> >  }
> >  
> > -static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> > -				 struct pci_bus *bus,
> > -				 u32 devfn, int where, int size, u32 *val)
> > +static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > +						    struct pci_bus *bus,
> > +						    int devfn);
> > +
> > +static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> > +				    int size, u32 *val)
> >  {
> > -	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> > +	struct mvebu_pcie *pcie = bus->sysdata;
> > +	struct mvebu_pcie_port *port;
> > +	void __iomem *conf_data;
> > +
> > +	port = mvebu_pcie_find_port(pcie, bus, devfn);
> > +	if (!port) {
> > +		*val = 0xffffffff;
> > +		return PCIBIOS_DEVICE_NOT_FOUND;
> > +	}
> > +
> > +	if (!mvebu_pcie_link_up(port)) {
> > +		*val = 0xffffffff;
> > +		return PCIBIOS_DEVICE_NOT_FOUND;
> > +	}
> > +
> > +	conf_data = port->base + PCIE_CONF_DATA_OFF;
> >  
> >  	mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
> >  		     PCIE_CONF_ADDR_OFF);
> > @@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> >  	return PCIBIOS_SUCCESSFUL;
> >  }
> >  
> > -static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
> > -				 struct pci_bus *bus,
> > -				 u32 devfn, int where, int size, u32 val)
> > +static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
> > +				    int where, int size, u32 val)
> >  {
> > -	void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> > +	struct mvebu_pcie *pcie = bus->sysdata;
> > +	struct mvebu_pcie_port *port;
> > +	void __iomem *conf_data;
> > +
> 
> > +	port = mvebu_pcie_find_port(pcie, bus, devfn);
> > +	if (!port)
> > +		return PCIBIOS_DEVICE_NOT_FOUND;
> > +
> > +	if (!mvebu_pcie_link_up(port))
> > +		return PCIBIOS_DEVICE_NOT_FOUND;
> > +
> > +	conf_data = port->base + PCIE_CONF_DATA_OFF;
> 
> Again, the same setup code in read and write is a sign to use 
> .map_bus(). You can copy it from my version I pointed you to.
> 
> Rob

I'm planning to do other cleanup in followup patches. But there are too
many mvebu and aardvark patches on the list waiting, and I do not want
to send another batch.


From robert.hancock at calian.com  Thu Jan 20 08:56:25 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Thu, 20 Jan 2022 16:56:25 +0000
Subject: [PATCH v2 6/7] arm64: dts: zynqmp: Move USB clocks to dwc3 node
In-Reply-To: <20220119002438.106079-7-sean.anderson@seco.com>
References: <20220119002438.106079-1-sean.anderson@seco.com>
 <20220119002438.106079-7-sean.anderson@seco.com>
Message-ID: <dd0a14dadc15a242af160a127c1db4241b9526e7.camel@calian.com>

On Tue, 2022-01-18 at 19:24 -0500, Sean Anderson wrote:
> These clocks are not used by the dwc3-xilinx driver except to
> enable/disable them. Move them to the dwc3 node so its driver can use
> them to configure the reference clock period.
> 
> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> ---
> 
> (no changes since v1)
> 
>  arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 4 ++--
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi         | 4 ++--
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> index 1e0b1bca7c94..8493dd7d5f1f 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> @@ -223,11 +223,11 @@ &uart1 {
>  	clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
>  };
>  
> -&usb0 {
> +&dwc3_0 {
>  	clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
>  };
>  
> -&usb1 {
> +&dwc3_1 {
>  	clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
>  };
>  
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 74e66443e4ce..ba68fb8529ee 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -811,7 +811,6 @@ usb0: usb at ff9d0000 {
>  			status = "disabled";
>  			compatible = "xlnx,zynqmp-dwc3";
>  			reg = <0x0 0xff9d0000 0x0 0x100>;
> -			clock-names = "bus_clk", "ref_clk";
>  			power-domains = <&zynqmp_firmware PD_USB_0>;
>  			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
>  				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
> @@ -825,6 +824,7 @@ dwc3_0: usb at fe200000 {
>  				interrupt-parent = <&gic>;
>  				interrupt-names = "dwc_usb3", "otg";
>  				interrupts = <0 65 4>, <0 69 4>;
> +				clock-names = "bus_early", "ref";
>  				#stream-id-cells = <1>;
>  				iommus = <&smmu 0x860>;
>  				snps,quirk-frame-length-adjustment = <0x20>;
> @@ -838,7 +838,6 @@ usb1: usb at ff9e0000 {
>  			status = "disabled";
>  			compatible = "xlnx,zynqmp-dwc3";
>  			reg = <0x0 0xff9e0000 0x0 0x100>;
> -			clock-names = "bus_clk", "ref_clk";
>  			power-domains = <&zynqmp_firmware PD_USB_1>;
>  			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
>  				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
> @@ -852,6 +851,7 @@ dwc3_1: usb at fe300000 {
>  				interrupt-parent = <&gic>;
>  				interrupt-names = "dwc_usb3", "otg";
>  				interrupts = <0 70 4>, <0 74 4>;
> +				clock-names = "bus_early", "ref";
>  				#stream-id-cells = <1>;
>  				iommus = <&smmu 0x861>;
>  				snps,quirk-frame-length-adjustment = <0x20>;

Tested and working on ZynqMP.

Reviewed-by: Robert Hancock <robert.hancock at calian.com>
Tested-by: Robert Hancock <robert.hancock at calian.com>


From robh at kernel.org  Thu Jan 20 09:09:17 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 11:09:17 -0600
Subject: [PATCH v2 05/11] PCI: mvebu: Correctly configure x1/x4 mode
In-Reply-To: <20220112151814.24361-6-pali@kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-6-pali@kernel.org>
Message-ID: <YemXPQx4F1eRtLxO@robh.at.kernel.org>

On Wed, Jan 12, 2022 at 04:18:08PM +0100, Pali Roh?r wrote:
> If x1/x4 mode is not set correctly then link with endpoint card is not
> established.
> 
> Use DTS property 'num-lanes' to deteriminate x1/x4 mode.
> 
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> ---
>  drivers/pci/controller/pci-mvebu.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index a075ba26cff1..0f2ec0a17874 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -93,6 +93,7 @@ struct mvebu_pcie_port {
>  	void __iomem *base;
>  	u32 port;
>  	u32 lane;
> +	bool is_x4;

I would just store the number of lanes.

>  	int devfn;
>  	unsigned int mem_target;
>  	unsigned int mem_attr;
> @@ -233,13 +234,25 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
>  
>  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  {
> -	u32 ctrl, cmd, dev_rev, mask;
> +	u32 ctrl, lnkcap, cmd, dev_rev, mask;
>  
>  	/* Setup PCIe controller to Root Complex mode. */
>  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
>  	ctrl |= PCIE_CTRL_RC_MODE;
>  	mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
>  
> +	/*
> +	 * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
> +	 * Capability register. This register is defined by PCIe specification
> +	 * as read-only but this mvebu controller has it as read-write and must
> +	 * be set to number of SerDes PCIe lanes (1 or 4). If this register is
> +	 * not set correctly then link with endpoint card is not established.
> +	 */
> +	lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
> +	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
> +	lnkcap |= (port->is_x4 ? 4 : 1) << 4;

then this is just: lanes << 4

> +	mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
> +
>  	/* Disable Root Bridge I/O space, memory space and bus mastering. */
>  	cmd = mvebu_readl(port, PCIE_CMD_OFF);
>  	cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
> @@ -986,6 +999,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  	struct device *dev = &pcie->pdev->dev;
>  	enum of_gpio_flags flags;
>  	int reset_gpio, ret;
> +	u32 num_lanes;
>  
>  	port->pcie = pcie;
>  
> @@ -998,6 +1012,9 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  	if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane))
>  		port->lane = 0;
>  
> +	if (!of_property_read_u32(child, "num-lanes", &num_lanes) && num_lanes == 4)
> +		port->is_x4 = true;

And this can be:

num_lanes = 1;
of_property_read_u32(child, "num-lanes", &num_lanes);

If you want to validate the DT is only 1 or 4, make the DT schema do 
that.


> +
>  	port->name = devm_kasprintf(dev, GFP_KERNEL, "pcie%d.%d", port->port,
>  				    port->lane);
>  	if (!port->name) {
> -- 
> 2.20.1
> 
> 


From pgwipeout at gmail.com  Thu Jan 20 09:14:56 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 20 Jan 2022 12:14:56 -0500
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
In-Reply-To: <3e87ed0a-8b79-006a-dce6-62becc9906ef@theobroma-systems.com>
References: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
 <CAMdYzYr+UXU-x=OakdHnOzLe1e4Y0xdGR-rybsmpLCMGbsWwXg@mail.gmail.com>
 <3e87ed0a-8b79-006a-dce6-62becc9906ef@theobroma-systems.com>
Message-ID: <CAMdYzYpT8BUrukUozRSQDHgiQHMPbS5GtV7huL4xFFRsdxw0qQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 11:03 AM Quentin Schulz
<quentin.schulz at theobroma-systems.com> wrote:
>
> Hi Peter,
>
> On 1/20/22 16:06, Peter Geis wrote:
> > On Wed, Jan 19, 2022 at 8:52 AM <quentin.schulz at theobroma-systems.com> wrote:
> >>
> >> From: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
> >>
> >> There are signal integrity issues running the eMMC at 200MHz on Puma
> >> RK3399-Q7.
> >>
> >> Similar to the work-around found for RK3399 Gru boards, lowering the
> >> frequency to 100MHz made the eMMC much more stable, so let's lower the
> >> frequency to 100MHz.
> >>
> >> It might be possible to run at 150MHz as on RK3399 Gru boards but only
> >> 100MHz was extensively tested.
> >>
> >> Cc: Quentin Schulz <foss+kernel at 0leil.net>
> >> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
> >> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
> >> ---
> >>
> >> Note/RFC: as opposed to gru DTSI, max-frequency is used here instead of
> >> assigned-clock-rates.
> >>
> >> AFAIU, max-frequency applies to the SD bus rate, while
> >> assigned-clock-rates applies to the clock fed to the SD host controller
> >> inside the SoC. max-frequency does not interact with the clock subsystem
> >> AFAICT. assigned-clock-rates sets the clock rate at probe, regardless of
> >> eMMC tuning.
> >> Technically, the Arasan SDHC IP supports silicon-hardcoded clock
> >> multiplier so I think setting assigned-clock-rates as a way of rate
> >> limiting the eMMC block is incorrect and max-frequency should be used
> >> instead (as done in this patch). Otherwise the SDHC could still potentially
> >> derive a 200MHz clock from a lower rate clock thanks to its multiplier.
> >>
> >>   arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 ++++++
> >>   1 file changed, 6 insertions(+)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> >> index fb67db4619ea..a6108578aae0 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> >> +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
> >> @@ -425,6 +425,12 @@ vcc5v0_host_en: vcc5v0-host-en {
> >>   };
> >>
> >>   &sdhci {
> >> +       /*
> >> +        * Signal integrity isn't great at 200MHz but 100MHz has proven stable
> >> +        * enough.
> >> +        */
> >> +       max-frequency = <100000000>;
> >> +
> >>          bus-width = <8>;
> >>          mmc-hs400-1_8v;
> >>          mmc-hs400-enhanced-strobe;
> >
> > I don't have these boards nor the schematics handy for them, but
> > wouldn't it be better to simply switch to mmc-hs200-1_8v?
>
> Thanks for the suggestion, I just tested, by removing mmc-hs400-1_8v;
> and mmc-hs400-enhanced-strobe; but keeping the clock rate at 200MHz and
> adding mmc-hs200-1_8v; failed a basic dd test.

Quite understandable.
I more meant it may permit you to reach a higher clock rate than
100mhz and thus possibly a higher data rate, for example perhaps
150mhz would be reachable.
For example I would do a bandwidth test for hs400-es at 100mhz, then
test at hs200 and find the maximum stable clock rate.
If 200mhz is stable enough to probe and /sys/kernel/debug/mmc<x>/ios
shows you are in 8bit hs200, you can adjust the clock rate through
/sys/kernel/debug/mmc<x>/clock without needing to reboot.
It will speed up testing.

If hs200 permits a higher overall data rate than hs400-es, it would be
worth making that switch.

Always,
Peter

>
> Cheers,
> Quentin
>
> > Other rk3399 boards don't have issues with hs200 at full 200mhz, and
> > as I understand it hs400-es exhibits stability issues on most rk3399
> > boards.
> >
> > Feel free to disregard my comments if you've already tested this.
> >
> >> --
> >> 2.34.1
> >>
> >>
> >> _______________________________________________
> >> Linux-rockchip mailing list
> >> Linux-rockchip at lists.infradead.org
> >> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_mailman_listinfo_linux-2Drockchip&d=DwIBaQ&c=_sEr5x9kUWhuk4_nFwjJtA&r=LYjLexDn7rXIzVmkNPvw5ymA1XTSqHGq8yBP6m6qZZ4njZguQhZhkI_-172IIy1t&m=OTusi9XARCbef1Ba5t1gv4_LqRkOaxFY3UtvYky6NVLpeiziqqmdOJ8-R5WXWFNr&s=xBnqhBu20rxvu_V-5EhXyA_yNxcJpa4Dq6HO2Ow3Gk8&e=


From pali at kernel.org  Thu Jan 20 09:19:15 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 18:19:15 +0100
Subject: [PATCH v2 05/11] PCI: mvebu: Correctly configure x1/x4 mode
In-Reply-To: <YemXPQx4F1eRtLxO@robh.at.kernel.org>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-6-pali@kernel.org>
 <YemXPQx4F1eRtLxO@robh.at.kernel.org>
Message-ID: <20220120171915.rynfs3hucnfj4kyb@pali>

On Thursday 20 January 2022 11:09:17 Rob Herring wrote:
> On Wed, Jan 12, 2022 at 04:18:08PM +0100, Pali Roh?r wrote:
> > If x1/x4 mode is not set correctly then link with endpoint card is not
> > established.
> > 
> > Use DTS property 'num-lanes' to deteriminate x1/x4 mode.
> > 
> > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > ---
> >  drivers/pci/controller/pci-mvebu.c | 19 ++++++++++++++++++-
> >  1 file changed, 18 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > index a075ba26cff1..0f2ec0a17874 100644
> > --- a/drivers/pci/controller/pci-mvebu.c
> > +++ b/drivers/pci/controller/pci-mvebu.c
> > @@ -93,6 +93,7 @@ struct mvebu_pcie_port {
> >  	void __iomem *base;
> >  	u32 port;
> >  	u32 lane;
> > +	bool is_x4;
> 
> I would just store the number of lanes.
> 
> >  	int devfn;
> >  	unsigned int mem_target;
> >  	unsigned int mem_attr;
> > @@ -233,13 +234,25 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
> >  
> >  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> >  {
> > -	u32 ctrl, cmd, dev_rev, mask;
> > +	u32 ctrl, lnkcap, cmd, dev_rev, mask;
> >  
> >  	/* Setup PCIe controller to Root Complex mode. */
> >  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> >  	ctrl |= PCIE_CTRL_RC_MODE;
> >  	mvebu_writel(port, ctrl, PCIE_CTRL_OFF);
> >  
> > +	/*
> > +	 * Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
> > +	 * Capability register. This register is defined by PCIe specification
> > +	 * as read-only but this mvebu controller has it as read-write and must
> > +	 * be set to number of SerDes PCIe lanes (1 or 4). If this register is
> > +	 * not set correctly then link with endpoint card is not established.
> > +	 */
> > +	lnkcap = mvebu_readl(port, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
> > +	lnkcap &= ~PCI_EXP_LNKCAP_MLW;
> > +	lnkcap |= (port->is_x4 ? 4 : 1) << 4;
> 
> then this is just: lanes << 4

As only 1 and 4 are valid valid values, I chose this style (is_x4) to
ensure that no other (invalid) value is written into mvebu register.
Setting width to smaller number (if incorrect value is provided) still
allows controller to work and link should be negotiated. So setting 1 is
a sane default when controller does not have configured 4 SerDes lines
to PCIe.

> > +	mvebu_writel(port, lnkcap, PCIE_CAP_PCIEXP + PCI_EXP_LNKCAP);
> > +
> >  	/* Disable Root Bridge I/O space, memory space and bus mastering. */
> >  	cmd = mvebu_readl(port, PCIE_CMD_OFF);
> >  	cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
> > @@ -986,6 +999,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> >  	struct device *dev = &pcie->pdev->dev;
> >  	enum of_gpio_flags flags;
> >  	int reset_gpio, ret;
> > +	u32 num_lanes;
> >  
> >  	port->pcie = pcie;
> >  
> > @@ -998,6 +1012,9 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
> >  	if (of_property_read_u32(child, "marvell,pcie-lane", &port->lane))
> >  		port->lane = 0;
> >  
> > +	if (!of_property_read_u32(child, "num-lanes", &num_lanes) && num_lanes == 4)
> > +		port->is_x4 = true;
> 
> And this can be:
> 
> num_lanes = 1;
> of_property_read_u32(child, "num-lanes", &num_lanes);
> 
> If you want to validate the DT is only 1 or 4, make the DT schema do 
> that.

The problem is that there is no schema for this platform and PCIe yet.
So adding it would mean to first convert everything to schema and then
this constrain can be expressed in schema.

I'm planning to look at possibility to write schema for this platform
but I do not want to do it before open issues with representation of
other pcie properties in dts schema are resolved.

> 
> > +
> >  	port->name = devm_kasprintf(dev, GFP_KERNEL, "pcie%d.%d", port->port,
> >  				    port->lane);
> >  	if (!port->name) {
> > -- 
> > 2.20.1
> > 
> > 


From robh at kernel.org  Thu Jan 20 09:23:32 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 11:23:32 -0600
Subject: [PATCH] dt-bindings: watchdog: fsl-imx7ulp-wdt: Fix
 assigned-clock-parents
Message-ID: <20220120172333.1628990-1-robh@kernel.org>

The schema has a typo with 'assigned-clocks-parents'. As it is not
required to list assigned clocks in bindings, just drop the assigned-clocks
property definitions to fix this.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml     | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
index fb603a20e396..4ca8a31359a5 100644
--- a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
@@ -29,12 +29,6 @@ properties:
   clocks:
     maxItems: 1
 
-  assigned-clocks:
-    maxItems: 1
-
-  assigned-clocks-parents:
-    maxItems: 1
-
   timeout-sec: true
 
 required:
@@ -56,7 +50,7 @@ examples:
         interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
         clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
         assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
-        assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
+        assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
         timeout-sec = <40>;
     };
 
-- 
2.32.0



From mathieu.poirier at linaro.org  Thu Jan 20 09:23:43 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 20 Jan 2022 10:23:43 -0700
Subject: [PATCH 8/9] remoteproc: imx_rproc: support i.MX8QM
In-Reply-To: <20220111033333.403448-11-peng.fan@oss.nxp.com>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-11-peng.fan@oss.nxp.com>
Message-ID: <20220120172343.GA1338735@p14s>

On Tue, Jan 11, 2022 at 11:33:32AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Most logic are same as i.MX8QXP, but i.MX8QM has two general purpose
> M4 cores:
>  Use the lower 16 bits specifying core, higher 16 bits for flags.
>  The 2nd core has different start address from SCFW view

Are the cores running independently or in lockstep?  This is relevant
information that should be in the changelog.  The above is an implementation
detail that should be added as comments in the code. 

> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/remoteproc/imx_rproc.c | 55 +++++++++++++++++++++++++++++++---
>  1 file changed, 51 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
> index 09d2a06e5ed6..7bc274fbce9f 100644
> --- a/drivers/remoteproc/imx_rproc.c
> +++ b/drivers/remoteproc/imx_rproc.c
> @@ -77,8 +77,11 @@ struct imx_rproc_mem {
>  
>  /* att flags */
>  /* M4 own area. Can be mapped at probe */
> -#define ATT_OWN		BIT(1)
> -#define ATT_IOMEM	BIT(2)
> +#define ATT_OWN         BIT(31)
> +#define ATT_IOMEM       BIT(30)

ATT_OWN was defined in 2017 and has had the same value since.  ATT_IOMEM was
introduced by this commit [1] (that you signed off on), which as supposed to be
a fix for another commit.

Now, overnight, both bitfields are changed without any explanation other than a
cryptic comments.  What about all the other platforms that previously used those
bitfields - was this change tested on those as well?

I will stop here with this patchset - it needs to much work for me to continue
reviewing it.

Thanks,
Mathieu

[1]. 91bb26637353 remoteproc: imx_rproc: Fix TCM io memory type


> +/* I = [0:7] */
> +#define ATT_CORE_MASK   0xffff
> +#define ATT_CORE(I)     BIT((I))
>  
>  struct imx_rproc {
>  	struct device			*dev;
> @@ -98,11 +101,25 @@ struct imx_rproc {
>  	struct notifier_block		proc_nb;
>  	u32				rproc_pt;
>  	u32				rsrc;
> +	u32				reg;
>  	int                             num_pd;
>  	struct device                   **pd_dev;
>  	struct device_link              **pd_dev_link;
>  };
>  
> +static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
> +	/* dev addr , sys addr  , size      , flags */
> +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> +	/* TCML */
> +	{ 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_CORE(0)},
> +	{ 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_CORE(1)},
> +	/* TCMU */
> +	{ 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_CORE(0)},
> +	{ 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_CORE(1)},
> +	/* DDR (Data) */
> +	{ 0x80000000, 0x80000000, 0x60000000, 0 },
> +};
> +
>  static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
>  	/* dev addr , sys addr  , size	    , flags */
>  	{ 0x08000000, 0x08000000, 0x10000000, 0},
> @@ -260,6 +277,12 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
>  	.method		= IMX_RPROC_NONE,
>  };
>  
> +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
> +	.att            = imx_rproc_att_imx8qm,
> +	.att_size       = ARRAY_SIZE(imx_rproc_att_imx8qm),
> +	.method         = IMX_RPROC_SCU_API,
> +};
> +
>  static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
>  	.att		= imx_rproc_att_imx8qxp,
>  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> @@ -310,7 +333,10 @@ static int imx_rproc_start(struct rproc *rproc)
>  		ret = res.a0;
>  		break;
>  	case IMX_RPROC_SCU_API:
> -		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);
> +		if (priv->reg)
> +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x38fe0000);
> +		else
> +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true, 0x34fe0000);
>  		break;
>  	default:
>  		return -EOPNOTSUPP;
> @@ -342,7 +368,10 @@ static int imx_rproc_stop(struct rproc *rproc)
>  			dev_info(dev, "Not in wfi, force stopped\n");
>  		break;
>  	case IMX_RPROC_SCU_API:
> -		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
> +		if (priv->reg)
> +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x38fe0000);
> +		else
> +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false, 0x34fe0000);
>  		break;
>  	default:
>  		return -EOPNOTSUPP;
> @@ -364,6 +393,11 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
>  	for (i = 0; i < dcfg->att_size; i++) {
>  		const struct imx_rproc_att *att = &dcfg->att[i];
>  
> +		if (att->flags & ATT_CORE_MASK) {
> +			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
> +				continue;
> +		}
> +
>  		if (da >= att->da && da + len < att->da + att->size) {
>  			unsigned int offset = da - att->da;
>  
> @@ -594,6 +628,11 @@ static int imx_rproc_addr_init(struct imx_rproc *priv,
>  		if (!(att->flags & ATT_OWN))
>  			continue;
>  
> +		if (att->flags & ATT_CORE_MASK) {
> +			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
> +				continue;
> +		}
> +
>  		if (b >= IMX_RPROC_MEM_MAX)
>  			break;
>  
> @@ -809,6 +848,13 @@ static int imx_rproc_detect_mode(struct imx_rproc *priv)
>  			return ret;
>  		}
>  
> +		priv->reg = of_get_cpu_hwid(dev->of_node, 0);
> +		if (priv->reg == ~0U)
> +			priv->reg = 0;
> +
> +		if (priv->reg > 1)
> +			return -EINVAL;
> +
>  		priv->has_clk = false;
>  		/*
>  		 * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
> @@ -1005,6 +1051,7 @@ static const struct of_device_id imx_rproc_of_match[] = {
>  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
>  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
>  	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
> +	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
>  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
>  	{},
>  };
> -- 
> 2.25.1
> 


From robh at kernel.org  Thu Jan 20 09:23:55 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 11:23:55 -0600
Subject: [PATCH] ARM: dts: imx7ulp: Fix 'assigned-clocks-parents' typo
Message-ID: <20220120172355.1629650-1-robh@kernel.org>

The correct property name is 'assigned-clock-parents', not
'assigned-clocks-parents'. Though if the platform works with the typo, one
has to wonder if the property is even needed.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 arch/arm/boot/dts/imx7ulp.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7ulp.dtsi b/arch/arm/boot/dts/imx7ulp.dtsi
index b7ea37ad4e55..bcec98b96411 100644
--- a/arch/arm/boot/dts/imx7ulp.dtsi
+++ b/arch/arm/boot/dts/imx7ulp.dtsi
@@ -259,7 +259,7 @@ wdog1: watchdog at 403d0000 {
 			interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
 			assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
-			assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
+			assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
 			timeout-sec = <40>;
 		};
 
-- 
2.32.0



From robh at kernel.org  Thu Jan 20 09:36:16 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 11:36:16 -0600
Subject: [PATCH] dt-bindings: Drop unnecessary pinctrl properties
In-Reply-To: <20220119015325.2438277-1-robh@kernel.org>
References: <20220119015325.2438277-1-robh@kernel.org>
Message-ID: <YemdkDfmemrwab2Y@robh.at.kernel.org>

On Tue, 18 Jan 2022 19:53:25 -0600, Rob Herring wrote:
> For a single pinctrl mode, it is not necessary to define pinctrl
> properties as the tools always allow pinctrl properties.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../display/rockchip/rockchip,rk3066-hdmi.yaml         |  8 --------
>  Documentation/devicetree/bindings/input/gpio-keys.yaml |  6 ------
>  .../devicetree/bindings/pinctrl/cirrus,lochnagar.yaml  |  9 ---------
>  .../devicetree/bindings/pinctrl/cirrus,madera.yaml     | 10 ----------
>  .../devicetree/bindings/sound/samsung-i2s.yaml         |  6 ------
>  5 files changed, 39 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Thu Jan 20 09:36:38 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 11:36:38 -0600
Subject: [PATCH] dt-bindings: Fix array schemas encoded as matrices
In-Reply-To: <20220119015627.2443334-1-robh@kernel.org>
References: <20220119015627.2443334-1-robh@kernel.org>
Message-ID: <YemdpgQqS8FX9/5g@robh.at.kernel.org>

On Tue, 18 Jan 2022 19:56:26 -0600, Rob Herring wrote:
> The YAML DT encoding has leaked into some array properties. Properties
> which are defined as an array should have a schema that's just an array.
> That means there should only be a single level of 'minItems',
> 'maxItems', and/or 'items'.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../bindings/media/nxp,imx7-mipi-csi2.yaml    | 12 ++--
>  .../bindings/media/nxp,imx8mq-mipi-csi2.yaml  | 12 ++--
>  .../bindings/net/can/bosch,m_can.yaml         | 52 ++++++++--------
>  .../bindings/net/ethernet-controller.yaml     | 59 +++++++++----------
>  4 files changed, 62 insertions(+), 73 deletions(-)
> 

Applied, thanks!


From sboyd at kernel.org  Thu Jan 20 09:46:57 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 20 Jan 2022 09:46:57 -0800
Subject: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <016c01d80e05$1ef9eab0$5cedc010$@samsung.com>
References: <20220118144851.69537-1-alim.akhtar@samsung.com>
 <CGME20220118150028epcas5p282c05b78f28a9b11d46da94e78330f0c@epcas5p2.samsung.com>
 <20220118144851.69537-5-alim.akhtar@samsung.com>
 <20220119201509.6220FC004E1@smtp.kernel.org>
 <016c01d80e05$1ef9eab0$5cedc010$@samsung.com>
Message-ID: <20220120174659.03D39C340E0@smtp.kernel.org>

Quoting Alim Akhtar (2022-01-20 05:53:31)
> Hi Stephen
> 
> >-----Original Message-----
> >From: Stephen Boyd [mailto:sboyd at kernel.org]
> >Sent: Thursday, January 20, 2022 1:45 AM
> >To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
> >kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> >Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
> >olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
> >catalin.marinas at arm.com; robh+dt at kernel.org;
> >krzysztof.kozlowski at canonical.com; s.nawrocki at samsung.com; linux-
> >samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com; Alim Akhtar
> ><alim.akhtar at samsung.com>; linux-fsd at tesla.com; Jayati Sahu
> ><jayati.sahu at samsung.com>; Ajay Kumar <ajaykumar.rs at samsung.com>
> >Subject: Re: [PATCH v2 04/16] clk: samsung: fsd: Add initial clock support
> >
> >Quoting Alim Akhtar (2022-01-18 06:48:39)
> >> diff --git a/drivers/clk/samsung/clk-fsd.c
> >> b/drivers/clk/samsung/clk-fsd.c new file mode 100644 index
> >> 000000000000..2669396d81b9
> >> --- /dev/null
> >> +++ b/drivers/clk/samsung/clk-fsd.c
> >> @@ -0,0 +1,308 @@
> >> +// SPDX-License-Identifier: GPL-2.0-only
> >> +/*
> >> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> >> + *             https://www.samsung.com
> >> + * Copyright (c) 2017-2022 Tesla, Inc.
> >> + *             https://www.tesla.com
> >> + *
> >> + * Common Clock Framework support for FSD SoC.
> >> + */
> >> +
> >> +#include <linux/clk-provider.h>
> >> +#include <linux/of.h>
> >
> >include init.h for __initconst and kernel.h for ARRAY_SIZE
> >
> I did not face any compilation error.
> Do I need to explicitly add these header files in driver? I see clk.h implicitly includes kernel.h
> Same is the case of other driver in this directory.

Yes they should be included. Depending on implicit includes leads to
pain later when that include is moved out of the header and compilation
breaks here. Include what you use, thanks!


From helgaas at kernel.org  Thu Jan 20 09:50:47 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 20 Jan 2022 11:50:47 -0600
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220113103523.5usmja7bp44f7ju7@pali>
Message-ID: <20220120175047.GA1050722@bhelgaas>

On Thu, Jan 13, 2022 at 11:35:23AM +0100, Pali Roh?r wrote:
> On Wednesday 12 January 2022 18:19:21 Bjorn Helgaas wrote:
> > On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Roh?r wrote:
> > > On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> > > > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > > > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > > > > Properly propagate failure from mvebu_pcie_add_windows()
> > > > > > > function back to the caller
> > > > > > > mvebu_pci_bridge_emul_base_conf_write() and correctly
> > > > > > > updates PCI_IO_BASE, PCI_MEM_BASE and
> > > > > > > PCI_IO_BASE_UPPER16 registers on error.  On error set
> > > > > > > base value higher than limit value which indicates that
> > > > > > > address range is disabled. 
> > > > > > 
> > > > > > Does the spec say that if software programs something
> > > > > > invalid, hardware should proactively set the base and
> > > > > > limit registers to disable the window?
> > > > > 
> > > > > No. But this patch address something totally different.
> > > > > Software can do fully valid operation, e.g. try to set
> > > > > forwarding memory window as large as possible. But because
> > > > > this driver "emulates" pci bridge by calling software/kernel
> > > > > function (mvebu_pcie_add_windows), some operations which in
> > > > > real HW cannot happen, are possible in software.
> > > > > 
> > > > > For example there are limitations in sizes of forwarding
> > > > > memory windows, because it is done by mvebu-mbus driver,
> > > > > which is responsible for configuring mapping and forwarding
> > > > > of PCIe I/O and MEM windows. And due to Marvell HW, there
> > > > > are restrictions which are not in PCIe HW.
> > > > > 
> > > > > Currently if such error happens, obviously kernel is not
> > > > > able to set PCIe windows and it just print warnings to
> > > > > dmesg. Trying to access these windows would result in the
> > > > > worst case in crashes.
> > > > > 
> > > > > With this change when mvebu_pcie_add_windows() function
> > > > > fails then into emulated config space is put information
> > > > > that particular forwarding window is disabled. I think that
> > > > > it is better to indicate it in config space what is the
> > > > > current "reality" of hardware configuration. If window is
> > > > > disabled in real-HW (meaning in mvebu-mbus driver) then show
> > > > > it also in emulated config space of pci bridge.
> > > > > 
> > > > > Do you have better idea what should emulated pci bridge do,
> > > > > if software try to set fully valid configuration of
> > > > > forwarding window, but it is not possible to achieve it
> > > > > (even compliant PCI bridge must be able to do it)?
> > > > 
> > > > On an ACPI system, the host bridge window sizes are
> > > > constrained by the host bridge _CRS method.  I assume there's
> > > > a similar constraint in DT.
> > > > 
> > > > Is the fact that mvebu_pcie_add_windows() can fail a symptom
> > > > of a DT that describes more available space than mvebu-bus can
> > > > map?
> > > 
> > > Memory maps for mvebu are more complicated. There is no explicit
> > > size in DT ranges property as it is dynamically allocated by
> > > mvebu-mbus:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47
> > 
> > I wish I knew how to really interpret those "ranges" properties.
> > (Is there a good description in Documentation/ somewhere?  All
> > I've found so far is https://elinux.org/Device_Tree_Usage, which
> > is good, but doesn't match this example completely.)
> > 
> > I see:
> > 
> >   pciec: pcie {
> >     ranges = <...>;
> >     pcie1: pcie at 1,0 {
> >       ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
> > 	        0x81000000 0 0 0x81000000 0x1 0 1 0>;
> >     };
> >     pcie2: pcie at 2,0 {
> >       ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
> > 	        0x81000000 0 0 0x81000000 0x2 0 1 0>;
> >     };
> >     pcie3: pcie at 3,0 {
> >       ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
> > 	        0x81000000 0 0 0x81000000 0x3 0 1 0>;
> >     };
> >     pcie4: pcie at 4,0 {
> >       ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
> > 	        0x81000000 0 0 0x81000000 0x4 0 1 0>;
> >     };
> >   };
> > 
> > What does this look like in dmesg, i.e., what CPU address ranges are
> > mapped to what PCI bus addresses?
> 
> These explicit ranges in DT are probably ignored as they are invalid.
> You can see them (0xffffffffffffffff) in dmesg. 

Are you saying that this DT ranges and the dmesg line are connected?

  ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
            0x81000000 0 0 0x81000000 0x1 0 1 0>;

  mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000

1) It would be nice if there were a hint somewhere in Documentation/
that would allow mere mortals to see the connection there.

2) Why do we have these DT entries if they are invalid and useless?

> MEM and I/O resources are parsed in pci-mvebu.c driver in
> mvebu_pcie_parse_request_resources() function.

So mvebu-mbus.c fills in the static mbus_state from the DT
"pcie-mem-aperture", which seems unconnected to the DT descriptions of
the PCI controllers:

  static struct mvebu_mbus_state mbus_state;

  mvebu_mbus_dt_init
    mvebu_mbus_get_pcie_resources(&mbus_state.pcie_mem_aperture)
      of_property_read_u32_array("pcie-mem-aperture")

  mvebu_pcie_probe
    mvebu_pcie_parse_request_resources
      mvebu_mbus_get_pcie_mem_aperture(&pcie->mem)
	*res = mbus_state.pcie_mem_aperture
      pci_add_resource(&bridge->windows, &pcie->mem)

> Here is relevant dmesg output:
> 
> mvebu-pcie soc:pcie: host bridge /soc/pcie ranges:
> mvebu-pcie soc:pcie:      MEM 0x00f1080000..0x00f1081fff -> 0x0000080000
> mvebu-pcie soc:pcie:      MEM 0x00f1040000..0x00f1041fff -> 0x0000040000
> mvebu-pcie soc:pcie:      MEM 0x00f1044000..0x00f1045fff -> 0x0000044000
> mvebu-pcie soc:pcie:      MEM 0x00f1048000..0x00f1049fff -> 0x0000048000
> mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
> mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
> mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
> mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
> mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
> mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
> mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
> mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
> mvebu-pcie soc:pcie: PCI host bridge to bus 0000:00
> pci_bus 0000:00: root bus resource [bus 00-ff]
> pci_bus 0000:00: root bus resource [mem 0xf1080000-0xf1081fff] (bus address [0x00080000-0x00081fff])
> pci_bus 0000:00: root bus resource [mem 0xf1040000-0xf1041fff] (bus address [0x00040000-0x00041fff])
> pci_bus 0000:00: root bus resource [mem 0xf1044000-0xf1045fff] (bus address [0x00044000-0x00045fff])
> pci_bus 0000:00: root bus resource [mem 0xf1048000-0xf1049fff] (bus address [0x00048000-0x00049fff])
> pci_bus 0000:00: root bus resource [mem 0xe0000000-0xe7ffffff]

I see 0xf1080000-0xf1081fff, 0xf1040000-0xf1041fff, etc mentioned in
the DT info above, but I don't see where [mem 0xe0000000-0xe7ffffff]
came from.

Regardless, this means PCI thinks [mem 0xe0000000-0xe7ffffff] is
available on bus 00 and can be assigned to devices on bus 00 according
to the normal PCI rules (BARs aligned on size, PCI bridge windows
aligned on 1MB and multiple of 1MB in size).  IIUC, mvebu imposes
additional alignment constraints on the bridge windows.

These are the bridge window assignments from your dmesg:

> pci 0000:00:01.0: BAR 8: assigned [mem 0xe0000000-0xe00fffff]
> pci 0000:00:02.0: BAR 8: assigned [mem 0xe0200000-0xe04fffff]
> pci 0000:00:03.0: BAR 8: assigned [mem 0xe0100000-0xe01fffff]

> pci 0000:00:01.0: PCI bridge to [bus 01]
> pci 0000:00:01.0:   bridge window [mem 0xe0000000-0xe00fffff]
> pci 0000:00:02.0: PCI bridge to [bus 02]
> pci 0000:00:02.0:   bridge window [mem 0xe0200000-0xe04fffff]
> pci 0000:00:03.0: PCI bridge to [bus 03]
> pci 0000:00:03.0:   bridge window [mem 0xe0100000-0xe01fffff]

The PCI core knows nothing about the mvebu constraints.  Are we just
lucky here that when PCI assigned these bridge windows, they happen to
be supported on mvebu?  What happens if PCI decides it needs 29MB on
bus 01?

> > Are pcie1, pcie2, etc Root Ports?  Or are they each separate host
> > bridges (they each have "bus-range = <0x00 0xff>")?
> 
> From kernel point of view they are root ports. But in reality every of
> these root port is on separate bus segment, but kernel pci-mvebu.c
> driver merges all these segments/domains into one host bridge and put
> all root ports into bus 0.
> 
> Here is lspci -tvnn output with topology:
> 
> $ lspci -tvnn
> -[0000:00]-+-01.0-[01]----00.0  Device [1e0f:0001]
>            +-02.0-[02]----00.0  Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter [168c:003c]
>            \-03.0-[03]----00.0  Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e]

> Buses 1, 2 and 3 represents mPCIe cards, all of them are in reality
> in separate bus segments and on different HW host bridges. So they
> do *not* share access to config space, do *not* share INTx
> interrupts, etc...
> 
> > Is space from pciec dynamically assigned to pcie1, pcie2, etc?  If
> > so, I assume there are more restrictions on the size and alignment
> > than on PCI bridge windows, which allow size/alignment down to
> > 1MB?
> 
> Yes, exactly. I do not know now all restrictions. At least there are
> fixed number of memory slots and each has to be of size 2^N. They
> are dynamically assigned by kernel mbus driver at time when somebody
> updates BASE/LIMIT registers. And that kernel mbus driver takes care
> to split non-aligned window size to more slots of size 2^N. And
> resources are shared from pool with other HW parts (e.g. DMA), so
> other drivers loaded in kernel can "eat" available slots before
> pci-mvebu and then there does not have to be nothing to allocate for
> PCI.

So IIUC,

  pcie1 == 00:01.0 Root Port
  pcie2 == 00:02.0 Root Port
  pcie3 == 00:03.0 Root Port

>From a software point of view, they're all under a single host bridge,
and Linux assumes everything under a host bridge plays by the PCI
rules.

In this case, the root ports *don't* play by the rules since they have
additional alignment restrictions, so I think these really should be
described as separate host bridges in DT with the address space
carved up statically among them.

It's common on x86 to have multiple host bridges that all appear to
software to be in domain 0000.  The bus number ranges under each are
static, e.g., one bridge has [bus 00-7f] and another has [bus 80-ff].

> But most Armada boards do not have exported all peripherals from SoC,
> unconnected are disabled in DT and therefore exhaustion should not
> happen.
> 
> > I'm trying to see how this could be described in ACPI because that's a
> > fairly general model that accommodates most machines.  Possibly
> > describing mvebu in ACPI would involve losing some flexibility.
> 
> I do not understand APCI model very well and I'm in impression that it
> is impossible to represent mvebu in ACPI.

It could be described as a separate host bridge for every root port.
ACPI uses _CRS (current resource settings) to describe the apertures
to PCI and any address translation.  Currently the _CRS description is
static, but ACPI does allow those resource assignments to be modified
via _PRS (possible resource settings) and _SRS (set resource
settings).

Bjorn


From mathieu.poirier at linaro.org  Thu Jan 20 09:56:42 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 20 Jan 2022 10:56:42 -0700
Subject: [PATCH] coresight: syscfg: Fix memleak on registration failure
 in cscfg_create_device
In-Reply-To: <20220110073100.15497-1-linmq006@gmail.com>
References: <20220110073100.15497-1-linmq006@gmail.com>
Message-ID: <20220120175642.GB1338735@p14s>

Good morning,

On Mon, Jan 10, 2022 at 07:31:00AM +0000, Miaoqian Lin wrote:
> device_register() calls device_initialize(),
> according to doc of device_initialize:
> 
>     Use put_device() to give up your reference instead of freeing
>     * @dev directly once you have called this function.

That is _if_ device_initialize() is called manually.  In this instance
@dev is registered with device_register() and unregistered with
device_unregister().  The latter conforms to the comment you pointed out and
calls put_device() as expected.

Thanks,
Mathieu

> 
> To prevent potential memleak, use put_device() instead call kfree
> directly.
> 
> Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
> ---
>  drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index 43054568430f..007fa1c761a7 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -764,7 +764,7 @@ struct device *cscfg_device(void)
>  /* Must have a release function or the kernel will complain on module unload */
>  static void cscfg_dev_release(struct device *dev)
>  {
> -	kfree(cscfg_mgr);
> +	put_device(dev);
>  	cscfg_mgr = NULL;
>  }
>  
> -- 
> 2.17.1
> 


From krzysztof.kozlowski at canonical.com  Thu Jan 20 09:57:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 18:57:43 +0100
Subject: [PATCH v5 0/4] spi: dt-bindings: samsung: convert to dtschema
Message-ID: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v4
================
1. Do not require samsung,spi-feedback-delay and fold patch 3 into patch 2.
2. Rework message in patch 4.
3. Add tags.

Changes since v3
================
1. Patch 2: correct path in exynos-usi.yaml.
2. Add patch 5.
3. Add tags.

Changes since v2
================
1. Patch 2: drop child device schema, as Rob suggested.

Changes since v1
================
1. Patch 2: describe devices matching compatible, correct issues pointed out by
   Rob, add reviewed-by tag.
2. New patches 3 and 4.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  ARM: dts: exynos: split dmas into array of phandles in Exynos5250
  spi: dt-bindings: samsung: convert to dtschema
  mfd: dt-bindings: google,cros-ec: reference Samsung SPI bindings
  spi: s3c64xx: allow controller-data to be optional

 .../bindings/mfd/google,cros-ec.yaml          |  29 +--
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  33 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 arch/arm/boot/dts/exynos5250.dtsi             |   9 +-
 drivers/spi/spi-s3c64xx.c                     |  14 +-
 9 files changed, 248 insertions(+), 151 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Thu Jan 20 09:57:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 18:57:44 +0100
Subject: [PATCH v5 1/4] ARM: dts: exynos: split dmas into array of phandles in
 Exynos5250
In-Reply-To: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220120175747.43403-2-krzysztof.kozlowski@canonical.com>

"dmas" property should be rather an array of phandles, as dtschema
points.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..102bb57bf704 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -496,8 +496,7 @@ spi_0: spi at 12d20000 {
 			status = "disabled";
 			reg = <0x12d20000 0x100>;
 			interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 5
-				&pdma0 4>;
+			dmas = <&pdma0 5>, <&pdma0 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -512,8 +511,7 @@ spi_1: spi at 12d30000 {
 			status = "disabled";
 			reg = <0x12d30000 0x100>;
 			interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma1 5
-				&pdma1 4>;
+			dmas = <&pdma1 5>, <&pdma1 4>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
@@ -528,8 +526,7 @@ spi_2: spi at 12d40000 {
 			status = "disabled";
 			reg = <0x12d40000 0x100>;
 			interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
-			dmas = <&pdma0 7
-				&pdma0 6>;
+			dmas = <&pdma0 7>, <&pdma0 6>;
 			dma-names = "tx", "rx";
 			#address-cells = <1>;
 			#size-cells = <0>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Thu Jan 20 09:57:46 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 18:57:46 +0100
Subject: [PATCH v5 3/4] mfd: dt-bindings: google,
 cros-ec: reference Samsung SPI bindings
In-Reply-To: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220120175747.43403-4-krzysztof.kozlowski@canonical.com>

The ChromeOS Embedded Controller appears on boards with Samsung Exynos
SoC, where Exynos SPI bindings expect controller-data node.  Reference
newly added dtschema for this property.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/mfd/google,cros-ec.yaml          | 29 ++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index 58a1a9405228..66a995bbbbe9 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -31,7 +31,7 @@ properties:
 
   controller-data:
     description:
-      SPI controller data, see bindings/spi/spi-samsung.txt
+      SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
     type: object
 
   google,cros-ec-spi-pre-delay:
@@ -148,18 +148,21 @@ patternProperties:
 required:
   - compatible
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - google,cros-ec-i2c
-          - google,cros-ec-rpmsg
-then:
-  properties:
-    google,cros-ec-spi-pre-delay: false
-    google,cros-ec-spi-msg-delay: false
-    spi-max-frequency: false
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - google,cros-ec-i2c
+              - google,cros-ec-rpmsg
+    then:
+      properties:
+        google,cros-ec-spi-pre-delay: false
+        google,cros-ec-spi-msg-delay: false
+        spi-max-frequency: false
+
+  - $ref: /schemas/spi/samsung,spi-peripheral-props.yaml
 
 additionalProperties: false
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Thu Jan 20 09:57:47 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 18:57:47 +0100
Subject: [PATCH v5 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220120175747.43403-5-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI driver requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 drivers/spi/spi-s3c64xx.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..386550fca81c 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
 		return ERR_PTR(-EINVAL);
 	}
 
-	data_np = of_get_child_by_name(slave_np, "controller-data");
-	if (!data_np) {
-		dev_err(&spi->dev, "child node 'controller-data' not found\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		of_node_put(data_np);
+	if (!cs)
 		return ERR_PTR(-ENOMEM);
+
+	data_np = of_get_child_by_name(slave_np, "controller-data");
+	if (!data_np) {
+		dev_info(&spi->dev, "feedback delay set to default (0)\n");
+		return cs;
 	}
 
 	of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Thu Jan 20 09:57:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 20 Jan 2022 18:57:45 +0100
Subject: [PATCH v5 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220120175747.43403-3-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format.

The conversion also drops requirement from providing controller-data and
its data for each of SPI peripheral device nodes.  The dtschema cannot
express this and the requirement is being relaxed in the driver now.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  33 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 6 files changed, 223 insertions(+), 124 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
index 273f2d95a043..e72b6a3fae99 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
@@ -22,7 +22,7 @@ description: |
 
   [1] Documentation/devicetree/bindings/serial/samsung_uart.yaml
   [2] Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
-  [3] Documentation/devicetree/bindings/spi/spi-samsung.txt
+  [3] Documentation/devicetree/bindings/spi/samsung,spi.yaml
 
 properties:
   $nodename:
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..f0db3fb3d688
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  See spi-peripheral-props.yaml for more info.
+
+properties:
+  controller-data:
+    type: object
+    additionalProperties: false
+
+    properties:
+      samsung,spi-feedback-delay:
+        description: |
+          The sampling phase shift to be applied on the miso line (to account
+          for any lag in the miso line). Valid values:
+           - 0: No phase shift.
+           - 1: 90 degree phase shift sampling.
+           - 2: 180 degree phase shift sampling.
+           - 3: 270 degree phase shift sampling.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2, 3]
+        default: 0
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..61c77088e8ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi # for S5PV210 and S5PC110
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..df885eeb144f 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -85,5 +85,6 @@ properties:
 # The controller specific properties go here.
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
+  - $ref: samsung,spi-peripheral-props.yaml#
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 5ea5655a29c3..1f951bc877f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17054,7 +17054,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From stefan.wahren at i2se.com  Thu Jan 20 10:10:37 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 20 Jan 2022 19:10:37 +0100
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <20220120153928.yvkrqduoytddvegs@houat>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <20220120153928.yvkrqduoytddvegs@houat>
Message-ID: <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>

Hi Maxime,

Am 20.01.22 um 16:39 schrieb Maxime Ripard:
> Hi Stefan,
>
> On Sun, Jan 16, 2022 at 06:26:58PM +0100, Stefan Wahren wrote:
>> recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
>> Aarch64 with Arch Linux. I'm able to reproduce this issue on my
>> Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
>> the connected HDMI monitor off and on again.
> By turning the monitor on and off, you mean that you used the power
> button on it?
yes, correct
>  Not something like disabling the output in sysfs, right?
>
>> Kernel output is the following:
>>
>> [15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
>> unhandled: 0
>> [15053.295440] ->handle_irq():? 00000000b28cf1d1,
>> brcmstb_l2_intc_irq_handle+0x0/0x1e0
>> [15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
>> [15053.315233] ->action(): 00000000236e815e
>> [15053.322022] ->action->handler(): 0000000013023289,
>> bad_chained_irq+0x0/0x50
>> [15053.331909]????? IRQ_LEVEL set
>> [15053.337822]??? IRQ_NOPROBE set
>> [15053.343715]? IRQ_NOREQUEST set
>> [15053.349585]?? IRQ_NOTHREAD set
> IRQ10 is the interrupt that a monitor has been connected on HDMI1, which
> makes sense if you were using HDMI1.

The irq number in this output is always 10 regardless of the used HDMI
connector (0 or 1). So maybe it's the hardware interrupt? Also in the
interrupts list there is a interrupt with number 10 in the first column,
which has the name (null) and it's count is identical to the occured
warnings.

[??? 0.000000] irq_brcmstb_l2: registered L2 intc
(/soc/interrupt-controller at 7ef00100, parent irq: 10)

>  Usually, when a display is turned
> on, it will issue a pulse on the HPD line so we would have a
> disconnection interrupt followed by a connection interrupt.
>
> This is weird though, since we have an interrupt handler on that
> interrupt (hpd-connected in the DT binding):
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/vc4/vc4_hdmi.c#L1578

I played a little bit with turn on/off and it seems the connect
interrupts get lost sometimes (see below). I mean the warning doesn't
occur always, it happens most of the time.

reduced /proc/interrupts for HDMI 0 case:

?10:????????? 5????????? 0????????? 0????????? 0???? GICv2 128 Level????
(null)
?...

?43:????????? 1????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
?44:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
?47:????????? 4????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
?48:????????? 7????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
?49:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
?50:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
?53:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
?54:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected

...

Err:????????? 5

/proc/interrupts for HDMI 1 case:

?10:????????? 6????????? 0????????? 0????????? 0???? GICv2 128 Level????
(null)
...
?43:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
?44:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
?47:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
?48:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
?49:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
?50:????????? 0????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
?53:????????? 3????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
?54:????????? 7????????? 0????????? 0????????? 0?
interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected

...

Err:????????? 6

I could send a diff of the config against arm64/defconfig? Contrary to
the Raspberry Pi OS, Arch Linux uses U-Boot not sure this is related.

Regards



From p.yadav at ti.com  Thu Jan 20 10:25:24 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Thu, 20 Jan 2022 23:55:24 +0530
Subject: [PATCH v5 2/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220120175747.43403-3-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
 <20220120175747.43403-3-krzysztof.kozlowski@canonical.com>
Message-ID: <20220120182524.d5fe3uigbelhcs7l@ti.com>

On 20/01/22 06:57PM, Krzysztof Kozlowski wrote:
> Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
> controller bindings to DT schema format.
> 
> The conversion also drops requirement from providing controller-data and
> its data for each of SPI peripheral device nodes.  The dtschema cannot
> express this and the requirement is being relaxed in the driver now.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>

Thanks.

Acked-by: Pratyush Yadav <p.yadav at ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From mathieu.poirier at linaro.org  Thu Jan 20 10:28:22 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 20 Jan 2022 11:28:22 -0700
Subject: [PATCH] coresight: syscfg: Fix memleak on registration failure
 in cscfg_create_device
In-Reply-To: <20220120175642.GB1338735@p14s>
References: <20220110073100.15497-1-linmq006@gmail.com>
 <20220120175642.GB1338735@p14s>
Message-ID: <20220120182822.GA1342128@p14s>

On Thu, Jan 20, 2022 at 10:56:42AM -0700, Mathieu Poirier wrote:
> Good morning,
> 
> On Mon, Jan 10, 2022 at 07:31:00AM +0000, Miaoqian Lin wrote:
> > device_register() calls device_initialize(),
> > according to doc of device_initialize:
> > 
> >     Use put_device() to give up your reference instead of freeing
> >     * @dev directly once you have called this function.
> 
> That is _if_ device_initialize() is called manually.  In this instance
> @dev is registered with device_register() and unregistered with
> device_unregister().  The latter conforms to the comment you pointed out and
> calls put_device() as expected.

I originally misunderstood the context - you are referring to the failure path in
cscfg_create_device().  You are correct about needing to call put_device() but
your solution will not work when the module is unloaded properly and
device_unregister() is called by way of cscfg_clear_device().  In that case
device_unregister() is already calling put_device().

Here simply calling put_device() instead of cscfg_dev_release() in the error
path should do just fine.  That will call cscfg_dev_release() and the memory
allocated for cscfg_mgr will be release.

> 
> Thanks,
> Mathieu
> 
> > 
> > To prevent potential memleak, use put_device() instead call kfree
> > directly.
> > 
> > Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
> > ---
> >  drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> > index 43054568430f..007fa1c761a7 100644
> > --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> > +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> > @@ -764,7 +764,7 @@ struct device *cscfg_device(void)
> >  /* Must have a release function or the kernel will complain on module unload */
> >  static void cscfg_dev_release(struct device *dev)
> >  {
> > -	kfree(cscfg_mgr);
> > +	put_device(dev);
> >  	cscfg_mgr = NULL;
> >  }
> >  
> > -- 
> > 2.17.1
> > 


From jagan at amarulasolutions.com  Thu Jan 20 10:32:06 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Fri, 21 Jan 2022 00:02:06 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
 <CAMty3ZBvbPvKgUpNW1LVho5_S9kwzNioE0SxvX_E8bmgw-+fXw@mail.gmail.com>
 <b2086dd4-643f-26b3-3930-4d8beb170b75@baylibre.com>
Message-ID: <CAMty3ZCb=oTw8inrk0MNHtjfJPVMKm2u-L8YSr=e0eQZ9HyQbA@mail.gmail.com>

On Thu, Jan 20, 2022 at 10:00 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> Hi,
>
> On 20/01/2022 15:24, Jagan Teki wrote:
> > On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
> >>
> >> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> >> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> >> Glue on other Amlogic SoCs.
> >>
> >> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> >> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> >> Analog PHY in the proper way.
> >>
> >> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> >> DW-MIPI-DSI transceiver.
> >>
> >> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> >> ---
> >>  drivers/gpu/drm/meson/Kconfig             |   7 +
> >>  drivers/gpu/drm/meson/Makefile            |   1 +
> >>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.c | 357 ++++++++++++++++++++++
> >>  drivers/gpu/drm/meson/meson_dw_mipi_dsi.h | 160 ++++++++++
> >>  4 files changed, 525 insertions(+)
> >>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> >>  create mode 100644 drivers/gpu/drm/meson/meson_dw_mipi_dsi.h
> >>
> >> diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
> >> index 6c70fc3214af..71a1364b51e1 100644
> >> --- a/drivers/gpu/drm/meson/Kconfig
> >> +++ b/drivers/gpu/drm/meson/Kconfig
> >> @@ -17,3 +17,10 @@ config DRM_MESON_DW_HDMI
> >>         default y if DRM_MESON
> >>         select DRM_DW_HDMI
> >>         imply DRM_DW_HDMI_I2S_AUDIO
> >> +
> >> +config DRM_MESON_DW_MIPI_DSI
> >> +       tristate "MIPI DSI Synopsys Controller support for Amlogic Meson Display"
> >> +       depends on DRM_MESON
> >> +       default y if DRM_MESON
> >> +       select DRM_DW_MIPI_DSI
> >> +       select GENERIC_PHY_MIPI_DPHY
> >> diff --git a/drivers/gpu/drm/meson/Makefile b/drivers/gpu/drm/meson/Makefile
> >> index 833e18c20603..43071bdbd4b9 100644
> >> --- a/drivers/gpu/drm/meson/Makefile
> >> +++ b/drivers/gpu/drm/meson/Makefile
> >> @@ -6,3 +6,4 @@ meson-drm-y += meson_encoder_hdmi.o meson_encoder_dsi.o
> >>
> >>  obj-$(CONFIG_DRM_MESON) += meson-drm.o
> >>  obj-$(CONFIG_DRM_MESON_DW_HDMI) += meson_dw_hdmi.o
> >> +obj-$(CONFIG_DRM_MESON_DW_MIPI_DSI) += meson_dw_mipi_dsi.o
> >
> > Can the naming convention prefix with dw-mipi-dsi like other glue
> > drivers follow?
>
> Seems only rockchip names their glue like that:
>
> $ find drivers/gpu/drm/ -name "*dw*mipi*dsi*.c"
> drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
> drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c
> drivers/gpu/drm/stm/dw_mipi_dsi-stm.c
>
> If you look at dw-hdmi it's even worse:
>
> $ find drivers/gpu/drm/ -name "*dw*hdmi*.c" | grep -v mod
> drivers/gpu/drm/meson/meson_dw_hdmi.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-cec.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
> drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
> drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c
> drivers/gpu/drm/imx/dw_hdmi-imx.c
> drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c

Look like there is no standard naming, thanks.

Jagan.


From jagan at amarulasolutions.com  Thu Jan 20 10:33:10 2022
From: jagan at amarulasolutions.com (Jagan Teki)
Date: Fri, 21 Jan 2022 00:03:10 +0530
Subject: [PATCH v2 6/6] drm/meson: add support for MIPI-DSI transceiver
In-Reply-To: <20220120083357.1541262-7-narmstrong@baylibre.com>
References: <20220120083357.1541262-1-narmstrong@baylibre.com>
 <20220120083357.1541262-7-narmstrong@baylibre.com>
Message-ID: <CAMty3ZBdzW++6mCaqCLuL0QWwY7ve1vmLSPhaS8QqYji_jDXSg@mail.gmail.com>

On Thu, Jan 20, 2022 at 2:04 PM Neil Armstrong <narmstrong at baylibre.com> wrote:
>
> The Amlogic G12A/G12B/SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a),
> with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI
> Glue on other Amlogic SoCs.
>
> This adds support for the Glue managing the transceiver, mimicing the init flow provided
> by Amlogic to setup the ENCL encoder, the glue, the transceiver, the digital D-PHY and the
> Analog PHY in the proper way.
>
> An optional "MEAS" clock can be enabled to measure the delay between each vsync feeding the
> DW-MIPI-DSI transceiver.
>
> Signed-off-by: Neil Armstrong <narmstrong at baylibre.com>
> ---

Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>


From robh at kernel.org  Thu Jan 20 10:40:06 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 12:40:06 -0600
Subject: [PATCH v2 08/11] PCI: mvebu: Use child_ops API
In-Reply-To: <20220120165522.v2xitzokcom4phmw@pali>
References: <20220105150239.9628-1-pali@kernel.org>
 <20220112151814.24361-1-pali@kernel.org>
 <20220112151814.24361-9-pali@kernel.org> <YemSgTfl7NiTfcKc@robh.at.kernel.org>
 <20220120165522.v2xitzokcom4phmw@pali>
Message-ID: <CAL_JsqJS=V3qVCzmN0r9yOQNXZcsFgvneySqPy_CXYKsyzUK0g@mail.gmail.com>

On Thu, Jan 20, 2022 at 10:55 AM Pali Roh?r <pali at kernel.org> wrote:
>
> On Thursday 20 January 2022 10:49:05 Rob Herring wrote:
> > On Wed, Jan 12, 2022 at 04:18:11PM +0100, Pali Roh?r wrote:
> > > Split struct pci_ops between ops and child_ops. Member ops is used for
> > > accessing PCIe Root Ports via pci-bridge-emul.c driver and child_ops for
> > > accessing real PCIe cards.
> > >
> > > There is no need to mix these two struct pci_ops into one as PCI core code
> > > already provides separate callbacks via bridge->ops and bridge->child_ops.
> > >
> > > Signed-off-by: Pali Roh?r <pali at kernel.org>
> > > ---
> > >  drivers/pci/controller/pci-mvebu.c | 82 ++++++++++++++++--------------
> > >  1 file changed, 44 insertions(+), 38 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> > > index 9ea2f6a7c2b0..1e90ab888075 100644
> > > --- a/drivers/pci/controller/pci-mvebu.c
> > > +++ b/drivers/pci/controller/pci-mvebu.c
> > > @@ -294,11 +294,29 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
> > >     mvebu_writel(port, mask, PCIE_MASK_OFF);
> > >  }
> > >
> > > -static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> > > -                            struct pci_bus *bus,
> > > -                            u32 devfn, int where, int size, u32 *val)
> > > +static struct mvebu_pcie_port *mvebu_pcie_find_port(struct mvebu_pcie *pcie,
> > > +                                               struct pci_bus *bus,
> > > +                                               int devfn);
> > > +
> > > +static int mvebu_pcie_child_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> > > +                               int size, u32 *val)
> > >  {
> > > -   void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> > > +   struct mvebu_pcie *pcie = bus->sysdata;
> > > +   struct mvebu_pcie_port *port;
> > > +   void __iomem *conf_data;
> > > +
> > > +   port = mvebu_pcie_find_port(pcie, bus, devfn);
> > > +   if (!port) {
> > > +           *val = 0xffffffff;
> > > +           return PCIBIOS_DEVICE_NOT_FOUND;
> > > +   }
> > > +
> > > +   if (!mvebu_pcie_link_up(port)) {
> > > +           *val = 0xffffffff;
> > > +           return PCIBIOS_DEVICE_NOT_FOUND;
> > > +   }
> > > +
> > > +   conf_data = port->base + PCIE_CONF_DATA_OFF;
> > >
> > >     mvebu_writel(port, PCIE_CONF_ADDR(bus->number, devfn, where),
> > >                  PCIE_CONF_ADDR_OFF);
> > > @@ -321,11 +339,21 @@ static int mvebu_pcie_hw_rd_conf(struct mvebu_pcie_port *port,
> > >     return PCIBIOS_SUCCESSFUL;
> > >  }
> > >
> > > -static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
> > > -                            struct pci_bus *bus,
> > > -                            u32 devfn, int where, int size, u32 val)
> > > +static int mvebu_pcie_child_wr_conf(struct pci_bus *bus, u32 devfn,
> > > +                               int where, int size, u32 val)
> > >  {
> > > -   void __iomem *conf_data = port->base + PCIE_CONF_DATA_OFF;
> > > +   struct mvebu_pcie *pcie = bus->sysdata;
> > > +   struct mvebu_pcie_port *port;
> > > +   void __iomem *conf_data;
> > > +
> >
> > > +   port = mvebu_pcie_find_port(pcie, bus, devfn);
> > > +   if (!port)
> > > +           return PCIBIOS_DEVICE_NOT_FOUND;
> > > +
> > > +   if (!mvebu_pcie_link_up(port))
> > > +           return PCIBIOS_DEVICE_NOT_FOUND;
> > > +
> > > +   conf_data = port->base + PCIE_CONF_DATA_OFF;
> >
> > Again, the same setup code in read and write is a sign to use
> > .map_bus(). You can copy it from my version I pointed you to.
> >
> > Rob
>
> I'm planning to do other cleanup in followup patches. But there are too
> many mvebu and aardvark patches on the list waiting, and I do not want
> to send another batch.

It can all be part of this patch.

Rob


From baruch at tkos.co.il  Thu Jan 20 10:43:41 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Thu, 20 Jan 2022 20:43:41 +0200
Subject: [PATCH] arm64: dts: qcom: ipq6018: fix usb reference period
Message-ID: <4f4df55cf44cd0fd7d773aca171d4f48662fb1a5.1642704221.git.baruch@tkos.co.il>

Reference clock period for rate of 24MHz is 41ns (0x29).

Link: https://lore.kernel.org/r/1965fc315525b8ab26cf9f71f939c24d at codeaurora.org
Link: https://lore.kernel.org/r/a1932eba-564c-fe32-f220-53aa75250105 at seco.com
Fixes: 20bb9e3dd2e4 ("arm64: dts: qcom: ipq6018: add usb3 DT description")
Reported-by: Kathiravan T <kathirav at codeaurora.org>
Signed-off-by: Baruch Siach <baruch at tkos.co.il>
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index 665ee301b85d..5eb7dc9cc231 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -762,7 +762,7 @@ dwc_0: usb at 8A00000 {
 				snps,hird-threshold = /bits/ 8 <0x0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_u3_susphy_quirk;
-				snps,ref-clock-period-ns = <0x32>;
+				snps,ref-clock-period-ns = <0x29>;
 				dr_mode = "host";
 			};
 		};
-- 
2.34.1



From arzamas-16 at mail.ee  Thu Jan 20 10:58:52 2022
From: arzamas-16 at mail.ee (Boris Lysov)
Date: Thu, 20 Jan 2022 21:58:52 +0300
Subject: [PATCH 1/2] dt-bindings: i2c: i2c-mt65xx: remove mt6577 support
In-Reply-To: <20220120185853.24266-1-arzamas-16@mail.ee>
References: <20220120185853.24266-1-arzamas-16@mail.ee>
Message-ID: <20220120185853.24266-2-arzamas-16@mail.ee>

Remove mentions of mt6577 from the dt-binding doc because the existing driver
doesn't support this SoC. mt6577 was used in this driver as some sort of a
"generic" configuration and it is now replaced with mt2701.

Update the dt-binding example to replace mt6577 with mt6589, as the example
uses [1] register addresses of the latter SoC.

[1] https://marc.info/?l=devicetree&m=159949247901831&w=2

Signed-off-by: Boris Lysov <arzamas-16 at mail.ee>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216ae7084..d1d0c5d2b9e9 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -4,13 +4,12 @@ The MediaTek's I2C controller is used to interface with I2C devices.
 
 Required properties:
   - compatible: value should be either of the following.
-      "mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for MediaTek MT2701
+      "mediatek,mt2701-i2c": for MediaTek MT2701
       "mediatek,mt2712-i2c": for MediaTek MT2712
-      "mediatek,mt6577-i2c": for MediaTek MT6577
       "mediatek,mt6589-i2c": for MediaTek MT6589
-      "mediatek,mt6797-i2c", "mediatek,mt6577-i2c": for MediaTek MT6797
+      "mediatek,mt6797-i2c", "mediatek,mt2701-i2c": for MediaTek MT6797
       "mediatek,mt7622-i2c": for MediaTek MT7622
-      "mediatek,mt7623-i2c", "mediatek,mt6577-i2c": for MediaTek MT7623
+      "mediatek,mt7623-i2c", "mediatek,mt2701-i2c": for MediaTek MT7623
       "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629
       "mediatek,mt8173-i2c": for MediaTek MT8173
       "mediatek,mt8183-i2c": for MediaTek MT8183
@@ -38,7 +37,7 @@ Optional properties:
 Example:
 
 	i2c0: i2c at 1100d000 {
-			compatible = "mediatek,mt6577-i2c";
+			compatible = "mediatek,mt6589-i2c";
 			reg = <0x1100d000 0x70>,
 			      <0x11000300 0x80>;
 			interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_LOW>;
-- 
2.20.1



From arzamas-16 at mail.ee  Thu Jan 20 10:58:51 2022
From: arzamas-16 at mail.ee (Boris Lysov)
Date: Thu, 20 Jan 2022 21:58:51 +0300
Subject: [PATCH 0/2] i2c: mediatek: remove mt6577 support
Message-ID: <20220120185853.24266-1-arzamas-16@mail.ee>

This small patch series removes mt6577 support from the i2c-mt65xx driver and
devicectree binding documentation.

The existing i2c-mt65xx driver relies on DMA since it was first introduced.
mt6577 does not support DMA [1] for I2C and SoC's Generic DMA engine cannot
be used for this purpose, too, which makes this particular driver incompatible
with mt6577 and other similar SoCs with same I2C IP.

[1] see references in
https://lists.infradead.org/pipermail/linux-mediatek/2021-October/030333.html

Boris Lysov (2):
  dt-bindings: i2c: i2c-mt65xx: remove compatibility with mt6577
  i2c: mediatek: remove compatibility with mt6577

 .../devicetree/bindings/i2c/i2c-mt65xx.txt    |  9 +++---
 drivers/i2c/busses/i2c-mt65xx.c               | 28 +++++++++----------
 2 files changed, 18 insertions(+), 19 deletions(-)

-- 
2.20.1



From arzamas-16 at mail.ee  Thu Jan 20 10:58:53 2022
From: arzamas-16 at mail.ee (Boris Lysov)
Date: Thu, 20 Jan 2022 21:58:53 +0300
Subject: [PATCH 2/2] i2c: mediatek: remove mt6577 support
In-Reply-To: <20220120185853.24266-1-arzamas-16@mail.ee>
References: <20220120185853.24266-1-arzamas-16@mail.ee>
Message-ID: <20220120185853.24266-3-arzamas-16@mail.ee>

The mt6577 compatibility was introduced back in 2014 in commit 8452c80d5b4b
("I2C: mediatek: Add driver for MediaTek I2C controller") by Xudong Chen.

The i2c-mt65xx driver relies on DMA since it was first introduced. mt6577 does
not support DMA [1] for I2C and doesn't have dedicated DMA engines for I2C.
Moreover, the entire mt65xx Cortex-A9 SoC family (mt6515, mt6517, mt6575,
and mt6577) which share the same I2C IP doesn't support I2C DMA at all which
makes this particular driver incompatible with these SoCs.

The existing code used mt6577 as a "generic" configuration to be used with
other SoCs such as mt6589 (for quirks), and mt2701/mt6797/mt7623 (in general).

This patch makes mt2701 (which is *actually* supported by this driver) a new
placeholder for generic Mediatek I2C bus configuration.

[1] see references in
https://lists.infradead.org/pipermail/linux-mediatek/2021-October/030333.html

Signed-off-by: Boris Lysov <arzamas-16 at mail.ee>
---
 drivers/i2c/busses/i2c-mt65xx.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9ea427f53083..24c94e58dc08 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -298,7 +298,7 @@ static const struct i2c_spec_values fast_mode_plus_spec = {
 	.min_su_dat_ns = 50 + I2C_FAST_MODE_PLUS_BUFFER,
 };
 
-static const struct i2c_adapter_quirks mt6577_i2c_quirks = {
+static const struct i2c_adapter_quirks mt2701_i2c_quirks = {
 	.flags = I2C_AQ_COMB_WRITE_THEN_READ,
 	.max_num_msgs = 1,
 	.max_write_len = 255,
@@ -315,35 +315,35 @@ static const struct i2c_adapter_quirks mt8183_i2c_quirks = {
 	.flags = I2C_AQ_NO_ZERO_LEN,
 };
 
-static const struct mtk_i2c_compatible mt2712_compat = {
+static const struct mtk_i2c_compatible mt2701_compat = {
+	.quirks = &mt2701_i2c_quirks,
 	.regs = mt_i2c_regs_v1,
 	.pmic_i2c = 0,
 	.dcm = 1,
-	.auto_restart = 1,
-	.aux_len_reg = 1,
-	.timing_adjust = 1,
+	.auto_restart = 0,
+	.aux_len_reg = 0,
+	.timing_adjust = 0,
 	.dma_sync = 0,
 	.ltiming_adjust = 0,
 	.apdma_sync = 0,
-	.max_dma_support = 33,
+	.max_dma_support = 32,
 };
 
-static const struct mtk_i2c_compatible mt6577_compat = {
-	.quirks = &mt6577_i2c_quirks,
+static const struct mtk_i2c_compatible mt2712_compat = {
 	.regs = mt_i2c_regs_v1,
 	.pmic_i2c = 0,
 	.dcm = 1,
-	.auto_restart = 0,
-	.aux_len_reg = 0,
-	.timing_adjust = 0,
+	.auto_restart = 1,
+	.aux_len_reg = 1,
+	.timing_adjust = 1,
 	.dma_sync = 0,
 	.ltiming_adjust = 0,
 	.apdma_sync = 0,
-	.max_dma_support = 32,
+	.max_dma_support = 33,
 };
 
 static const struct mtk_i2c_compatible mt6589_compat = {
-	.quirks = &mt6577_i2c_quirks,
+	.quirks = &mt2701_i2c_quirks,
 	.regs = mt_i2c_regs_v1,
 	.pmic_i2c = 1,
 	.dcm = 0,
@@ -412,8 +412,8 @@ static const struct mtk_i2c_compatible mt8192_compat = {
 };
 
 static const struct of_device_id mtk_i2c_of_match[] = {
+	{ .compatible = "mediatek,mt2701-i2c", .data = &mt2701_compat },
 	{ .compatible = "mediatek,mt2712-i2c", .data = &mt2712_compat },
-	{ .compatible = "mediatek,mt6577-i2c", .data = &mt6577_compat },
 	{ .compatible = "mediatek,mt6589-i2c", .data = &mt6589_compat },
 	{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
 	{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
-- 
2.20.1



From willy at infradead.org  Thu Jan 20 11:04:26 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Thu, 20 Jan 2022 19:04:26 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <YemTq/yGkHQ+grd1@shell.armlinux.org.uk>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
 <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
 <Yeldih0PHotN4/bn@shell.armlinux.org.uk>
 <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>
 <YemTq/yGkHQ+grd1@shell.armlinux.org.uk>
Message-ID: <YemyOsvx9+dFkICP@casper.infradead.org>

On Thu, Jan 20, 2022 at 04:54:03PM +0000, Russell King (Oracle) wrote:
> Well, I think I've adequately explained why I believe:
> 
> 	pfn_is_valid(page_to_pfn(page))
> 
> being used as the primary check is substandard, and will likely lead to
> a future CVE. When generating an array of struct page's, I believe that
> it is the responsibility for the generator to ensure that the array
> only contains valid pages.

So you're saying that virt_to_page() should be made more expensive?


From pali at kernel.org  Thu Jan 20 11:08:26 2022
From: pali at kernel.org (Pali =?utf-8?B?Um9ow6Fy?=)
Date: Thu, 20 Jan 2022 20:08:26 +0100
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220120175047.GA1050722@bhelgaas>
References: <20220113103523.5usmja7bp44f7ju7@pali>
 <20220120175047.GA1050722@bhelgaas>
Message-ID: <20220120190826.wkhkcx53lmafq2yp@pali>

On Thursday 20 January 2022 11:50:47 Bjorn Helgaas wrote:
> On Thu, Jan 13, 2022 at 11:35:23AM +0100, Pali Roh?r wrote:
> > On Wednesday 12 January 2022 18:19:21 Bjorn Helgaas wrote:
> > > On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Roh?r wrote:
> > > > On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> > > > > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > > > > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > > > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > > > > > Properly propagate failure from mvebu_pcie_add_windows()
> > > > > > > > function back to the caller
> > > > > > > > mvebu_pci_bridge_emul_base_conf_write() and correctly
> > > > > > > > updates PCI_IO_BASE, PCI_MEM_BASE and
> > > > > > > > PCI_IO_BASE_UPPER16 registers on error.  On error set
> > > > > > > > base value higher than limit value which indicates that
> > > > > > > > address range is disabled. 
> > > > > > > 
> > > > > > > Does the spec say that if software programs something
> > > > > > > invalid, hardware should proactively set the base and
> > > > > > > limit registers to disable the window?
> > > > > > 
> > > > > > No. But this patch address something totally different.
> > > > > > Software can do fully valid operation, e.g. try to set
> > > > > > forwarding memory window as large as possible. But because
> > > > > > this driver "emulates" pci bridge by calling software/kernel
> > > > > > function (mvebu_pcie_add_windows), some operations which in
> > > > > > real HW cannot happen, are possible in software.
> > > > > > 
> > > > > > For example there are limitations in sizes of forwarding
> > > > > > memory windows, because it is done by mvebu-mbus driver,
> > > > > > which is responsible for configuring mapping and forwarding
> > > > > > of PCIe I/O and MEM windows. And due to Marvell HW, there
> > > > > > are restrictions which are not in PCIe HW.
> > > > > > 
> > > > > > Currently if such error happens, obviously kernel is not
> > > > > > able to set PCIe windows and it just print warnings to
> > > > > > dmesg. Trying to access these windows would result in the
> > > > > > worst case in crashes.
> > > > > > 
> > > > > > With this change when mvebu_pcie_add_windows() function
> > > > > > fails then into emulated config space is put information
> > > > > > that particular forwarding window is disabled. I think that
> > > > > > it is better to indicate it in config space what is the
> > > > > > current "reality" of hardware configuration. If window is
> > > > > > disabled in real-HW (meaning in mvebu-mbus driver) then show
> > > > > > it also in emulated config space of pci bridge.
> > > > > > 
> > > > > > Do you have better idea what should emulated pci bridge do,
> > > > > > if software try to set fully valid configuration of
> > > > > > forwarding window, but it is not possible to achieve it
> > > > > > (even compliant PCI bridge must be able to do it)?
> > > > > 
> > > > > On an ACPI system, the host bridge window sizes are
> > > > > constrained by the host bridge _CRS method.  I assume there's
> > > > > a similar constraint in DT.
> > > > > 
> > > > > Is the fact that mvebu_pcie_add_windows() can fail a symptom
> > > > > of a DT that describes more available space than mvebu-bus can
> > > > > map?
> > > > 
> > > > Memory maps for mvebu are more complicated. There is no explicit
> > > > size in DT ranges property as it is dynamically allocated by
> > > > mvebu-mbus:
> > > > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-385.dtsi?h=v5.15#n47
> > > 
> > > I wish I knew how to really interpret those "ranges" properties.
> > > (Is there a good description in Documentation/ somewhere?  All
> > > I've found so far is https://elinux.org/Device_Tree_Usage, which
> > > is good, but doesn't match this example completely.)
> > > 
> > > I see:
> > > 
> > >   pciec: pcie {
> > >     ranges = <...>;
> > >     pcie1: pcie at 1,0 {
> > >       ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
> > > 	        0x81000000 0 0 0x81000000 0x1 0 1 0>;
> > >     };
> > >     pcie2: pcie at 2,0 {
> > >       ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
> > > 	        0x81000000 0 0 0x81000000 0x2 0 1 0>;
> > >     };
> > >     pcie3: pcie at 3,0 {
> > >       ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
> > > 	        0x81000000 0 0 0x81000000 0x3 0 1 0>;
> > >     };
> > >     pcie4: pcie at 4,0 {
> > >       ranges = <0x82000000 0 0 0x82000000 0x4 0 1 0
> > > 	        0x81000000 0 0 0x81000000 0x4 0 1 0>;
> > >     };
> > >   };
> > > 
> > > What does this look like in dmesg, i.e., what CPU address ranges are
> > > mapped to what PCI bus addresses?
> > 
> > These explicit ranges in DT are probably ignored as they are invalid.
> > You can see them (0xffffffffffffffff) in dmesg. 
> 
> Are you saying that this DT ranges and the dmesg line are connected?
> 
>   ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
>             0x81000000 0 0 0x81000000 0x1 0 1 0>;
> 
>   mvebu-pcie soc:pcie: MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
> 
> 1) It would be nice if there were a hint somewhere in Documentation/
> that would allow mere mortals to see the connection there.

I agree, that there is missing lot of documentation related to Marvell
PCIe controllers, both pci-mvebu.c and pci-aardvark.c. The main problem
now is that it is hard to find information which explain everything...
like mysterious Memory Controller (which is now explained):
https://lore.kernel.org/linux-pci/20211003120944.3lmwxylnhlp2kfj7 at pali/

> 2) Why do we have these DT entries if they are invalid and useless?

Sorry, I do not know. I was not involved during introducing of DT files
for this platform. I'm just observing how it works...

> > MEM and I/O resources are parsed in pci-mvebu.c driver in
> > mvebu_pcie_parse_request_resources() function.
> 
> So mvebu-mbus.c fills in the static mbus_state from the DT
> "pcie-mem-aperture", which seems unconnected to the DT descriptions of
> the PCI controllers:
> 
>   static struct mvebu_mbus_state mbus_state;
> 
>   mvebu_mbus_dt_init
>     mvebu_mbus_get_pcie_resources(&mbus_state.pcie_mem_aperture)
>       of_property_read_u32_array("pcie-mem-aperture")
> 
>   mvebu_pcie_probe
>     mvebu_pcie_parse_request_resources
>       mvebu_mbus_get_pcie_mem_aperture(&pcie->mem)
> 	*res = mbus_state.pcie_mem_aperture
>       pci_add_resource(&bridge->windows, &pcie->mem)
> 
> > Here is relevant dmesg output:
> > 
> > mvebu-pcie soc:pcie: host bridge /soc/pcie ranges:
> > mvebu-pcie soc:pcie:      MEM 0x00f1080000..0x00f1081fff -> 0x0000080000
> > mvebu-pcie soc:pcie:      MEM 0x00f1040000..0x00f1041fff -> 0x0000040000
> > mvebu-pcie soc:pcie:      MEM 0x00f1044000..0x00f1045fff -> 0x0000044000
> > mvebu-pcie soc:pcie:      MEM 0x00f1048000..0x00f1049fff -> 0x0000048000
> > mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
> > mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0100000000
> > mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
> > mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0200000000
> > mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
> > mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0300000000
> > mvebu-pcie soc:pcie:      MEM 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
> > mvebu-pcie soc:pcie:       IO 0xffffffffffffffff..0x00fffffffe -> 0x0400000000
> > mvebu-pcie soc:pcie: PCI host bridge to bus 0000:00
> > pci_bus 0000:00: root bus resource [bus 00-ff]
> > pci_bus 0000:00: root bus resource [mem 0xf1080000-0xf1081fff] (bus address [0x00080000-0x00081fff])
> > pci_bus 0000:00: root bus resource [mem 0xf1040000-0xf1041fff] (bus address [0x00040000-0x00041fff])
> > pci_bus 0000:00: root bus resource [mem 0xf1044000-0xf1045fff] (bus address [0x00044000-0x00045fff])
> > pci_bus 0000:00: root bus resource [mem 0xf1048000-0xf1049fff] (bus address [0x00048000-0x00049fff])
> > pci_bus 0000:00: root bus resource [mem 0xe0000000-0xe7ffffff]
> 
> I see 0xf1080000-0xf1081fff, 0xf1040000-0xf1041fff, etc mentioned in
> the DT info above, but I don't see where [mem 0xe0000000-0xe7ffffff]
> came from.

0xe0000000 is defined in above mentioned "pcie-mem-aperture" DT property
and it is in armada-38x.dtsi DTS file included from armada-385.dtsi:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/armada-38x.dtsi?h=v5.15#n42

> Regardless, this means PCI thinks [mem 0xe0000000-0xe7ffffff] is
> available on bus 00 and can be assigned to devices on bus 00 according
> to the normal PCI rules (BARs aligned on size, PCI bridge windows
> aligned on 1MB and multiple of 1MB in size).  IIUC, mvebu imposes
> additional alignment constraints on the bridge windows.
> 
> These are the bridge window assignments from your dmesg:
> 
> > pci 0000:00:01.0: BAR 8: assigned [mem 0xe0000000-0xe00fffff]
> > pci 0000:00:02.0: BAR 8: assigned [mem 0xe0200000-0xe04fffff]
> > pci 0000:00:03.0: BAR 8: assigned [mem 0xe0100000-0xe01fffff]
> 
> > pci 0000:00:01.0: PCI bridge to [bus 01]
> > pci 0000:00:01.0:   bridge window [mem 0xe0000000-0xe00fffff]
> > pci 0000:00:02.0: PCI bridge to [bus 02]
> > pci 0000:00:02.0:   bridge window [mem 0xe0200000-0xe04fffff]
> > pci 0000:00:03.0: PCI bridge to [bus 03]
> > pci 0000:00:03.0:   bridge window [mem 0xe0100000-0xe01fffff]
> 
> The PCI core knows nothing about the mvebu constraints.  Are we just
> lucky here that when PCI assigned these bridge windows, they happen to
> be supported on mvebu?  What happens if PCI decides it needs 29MB on
> bus 01?

In this case pci-mvebu.c split 29MB window into continuous ranges of
power of two (16MB + 8MB + 4MB + 1MB) and then register each range to
mbus slot. Code is in function mvebu_pcie_add_windows():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/pci-mvebu.c?h=v5.15#n300

So at the end there is continuous space of 29MB PCIe window, just it
"eats" 4 mbus slots.

This function may fail (if there is not enough free mbus slots) and this
patch is propagating that failure back to the caller.

> > > Are pcie1, pcie2, etc Root Ports?  Or are they each separate host
> > > bridges (they each have "bus-range = <0x00 0xff>")?
> > 
> > From kernel point of view they are root ports. But in reality every of
> > these root port is on separate bus segment, but kernel pci-mvebu.c
> > driver merges all these segments/domains into one host bridge and put
> > all root ports into bus 0.
> > 
> > Here is lspci -tvnn output with topology:
> > 
> > $ lspci -tvnn
> > -[0000:00]-+-01.0-[01]----00.0  Device [1e0f:0001]
> >            +-02.0-[02]----00.0  Qualcomm Atheros QCA986x/988x 802.11ac Wireless Network Adapter [168c:003c]
> >            \-03.0-[03]----00.0  Qualcomm Atheros AR9287 Wireless Network Adapter (PCI-Express) [168c:002e]
> 
> > Buses 1, 2 and 3 represents mPCIe cards, all of them are in reality
> > in separate bus segments and on different HW host bridges. So they
> > do *not* share access to config space, do *not* share INTx
> > interrupts, etc...
> > 
> > > Is space from pciec dynamically assigned to pcie1, pcie2, etc?  If
> > > so, I assume there are more restrictions on the size and alignment
> > > than on PCI bridge windows, which allow size/alignment down to
> > > 1MB?
> > 
> > Yes, exactly. I do not know now all restrictions. At least there are
> > fixed number of memory slots and each has to be of size 2^N. They
> > are dynamically assigned by kernel mbus driver at time when somebody
> > updates BASE/LIMIT registers. And that kernel mbus driver takes care
> > to split non-aligned window size to more slots of size 2^N. And
> > resources are shared from pool with other HW parts (e.g. DMA), so
> > other drivers loaded in kernel can "eat" available slots before
> > pci-mvebu and then there does not have to be nothing to allocate for
> > PCI.
> 
> So IIUC,
> 
>   pcie1 == 00:01.0 Root Port
>   pcie2 == 00:02.0 Root Port
>   pcie3 == 00:03.0 Root Port
> 
> From a software point of view, they're all under a single host bridge,
> and Linux assumes everything under a host bridge plays by the PCI
> rules.

Yes.

> In this case, the root ports *don't* play by the rules since they have
> additional alignment restrictions, so I think these really should be
> described as separate host bridges in DT with the address space
> carved up statically among them.

I fully agree with you.

But pci-mvebu.c driver and also its DT bindings are written differently.
Changing it probably would not be simple due to backward compatibility
and will take development resources...

> It's common on x86 to have multiple host bridges that all appear to
> software to be in domain 0000.  The bus number ranges under each are
> static, e.g., one bridge has [bus 00-7f] and another has [bus 80-ff].

For mvebu they are dynamic and kernel assigns them at boot. As my above
printed lspci topology is simple, first bridge has assigned [bus 01-01],
second bridge [bus 02-02] and third bridge [bus 03-03].

> > But most Armada boards do not have exported all peripherals from SoC,
> > unconnected are disabled in DT and therefore exhaustion should not
> > happen.
> > 
> > > I'm trying to see how this could be described in ACPI because that's a
> > > fairly general model that accommodates most machines.  Possibly
> > > describing mvebu in ACPI would involve losing some flexibility.
> > 
> > I do not understand APCI model very well and I'm in impression that it
> > is impossible to represent mvebu in ACPI.
> 
> It could be described as a separate host bridge for every root port.
> ACPI uses _CRS (current resource settings) to describe the apertures
> to PCI and any address translation.  Currently the _CRS description is
> static, but ACPI does allow those resource assignments to be modified
> via _PRS (possible resource settings) and _SRS (set resource
> settings).
> 
> Bjorn


From peter.hilber at opensynergy.com  Thu Jan 20 11:09:56 2022
From: peter.hilber at opensynergy.com (Peter Hilber)
Date: Thu, 20 Jan 2022 20:09:56 +0100
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20220119122338.GE6113@e120937-lin>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
 <20220119122338.GE6113@e120937-lin>
Message-ID: <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>

On 19.01.22 13:23, Cristian Marussi wrote:
> On Tue, Jan 18, 2022 at 03:21:03PM +0100, Peter Hilber wrote:
>> On 21.12.21 15:00, Cristian Marussi wrote:
>>> Add support for .mark_txdone and .poll_done transport operations to SCMI
>>> VirtIO transport as pre-requisites to enable atomic operations.
>>>
>>> Add a Kernel configuration option to enable SCMI VirtIO transport polling
>>> and atomic mode for selected SCMI transactions while leaving it default
>>> disabled.
>>>
>>
>> Hi Cristian,
>>
>> thanks for the update. I have some more remarks inline below.
>>
> 
> Hi Peter,
> 
> thanks for your review, much appreciated, please see my replies online.
> 
>> My impression is that the virtio core does not expose helper functions suitable
>> to busy-poll for used buffers. But changing this might not be difficult. Maybe
>> more_used() from virtio_ring.c could be exposed via a wrapper?
>>
> 
> While I definitely agree that the virtio core support for polling is far from
> ideal, some support is provided and my point was at first to try implement SCMI
> virtio polling leveraging what we have now in the core and see if it was attainable
> (indeed I tried early in this series to avoid as a whole to have to support polling
> at the SCMI transport layer to attain SCMI cmds atomicity..but that was an ill
> attempt that led nowhere good...)
> 
> Btw, I was planning to post a new series next week (after merge-windows) with some
> fixes I did already, at this point I'll include also some fixes derived
> from some of your remarks.
> 
>> Best regards,
>>
>> Peter
>>
[snip]>>> + *
>>> + * Return: True once polling has successfully completed.
>>> + */
>>> +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
>>> +			     struct scmi_xfer *xfer)
>>> +{
>>> +	bool pending, ret = false;
>>> +	unsigned int length, any_prefetched = 0;
>>> +	unsigned long flags;
>>> +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
>>> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
>>> +
>>> +	if (!msg)
>>> +		return true;
>>> +
>>> +	spin_lock_irqsave(&msg->poll_lock, flags);
>>> +	/* Processed already by other polling loop on another CPU ? */
>>> +	if (msg->poll_idx == VIO_MSG_POLL_DONE) {
>>> +		spin_unlock_irqrestore(&msg->poll_lock, flags);
>>> +		return true;
>>> +	}
>>> +
>>> +	/* Has cmdq index moved at all ? */
>>> +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
>>
>> In my understanding, the polling comparison could still be subject to the ABA
>> problem when exactly 2**16 messages have been marked as used since
>> msg->poll_idx was set (unlikely scenario, granted).
>>
>> I think this would be a lot simpler if the virtio core exported some
>> concurrency-safe helper function for such polling (similar to more_used() from
>> virtio_ring.c), as discussed at the top.
> 
> So this is the main limitation indeed of the current implementation, I
> cannot distinguish if there was an exact full wrap and I'm reading the same
> last_idx as before but a whoppying 2**16 messages have instead gone through...
> 
> The tricky part seems to me here that even introducing dedicated helpers
> for polling in order to account for such wrapping (similar to more_used())
> those would be based by current VirtIO spec on a single bit wrap counter,
> so how do you discern if 2 whole wraps have happened (even more unlikely..) ?
> 
> Maybe I'm missing something though...
> 

In my understanding, there is no need to keep track of the old state. We
actually only want to check whether the device has marked any buffers as `used'
which we did not retrieve yet via virtqueue_get_buf_ctx().

This is what more_used() checks in my understanding. One would just need to
translate the external `struct virtqueue' param to the virtio_ring.c internal
representation `struct vring_virtqueue' and then call `more_used()'.

There would be no need to keep `poll_idx` then.

Best regards,

Peter


> I'll have a though about this, but in my opinion this seems something so
> unlikely that we could live with it, for the moment at least...
> [snip]


From rananta at google.com  Thu Jan 20 11:16:15 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Thu, 20 Jan 2022 11:16:15 -0800
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YeisZCJedWYJPLV5@google.com>
References: <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
 <YedWUJNnQK3HFrWC@google.com>
 <CAAeT=FyJAG1dEFLvrQ4UXrwUqBUhY0AKkjzFpyi74zCJZUEYVg@mail.gmail.com>
 <YeisZCJedWYJPLV5@google.com>
Message-ID: <CAJHc60zhRyOad7AqtEFn-Ptro5BGVkfpB2wXWGw5EZMxOHUc=w@mail.gmail.com>

On Wed, Jan 19, 2022 at 4:27 PM Sean Christopherson <seanjc at google.com> wrote:
>
> On Tue, Jan 18, 2022, Reiji Watanabe wrote:
> > On Tue, Jan 18, 2022 at 4:07 PM Sean Christopherson <seanjc at google.com> wrote:
> > >
> > > On Fri, Jan 14, 2022, Reiji Watanabe wrote:
> > > > The restriction, with which KVM doesn't need to worry about the changes
> > > > in the registers after KVM_RUN, could potentially protect or be useful
> > > > to protect KVM and simplify future changes/maintenance of the KVM codes
> > > > that consumes the values.
> > >
> > > That sort of protection is definitely welcome, the previously mentioned CPUID mess
> > > on x86 would have benefit greatly by KVM being restrictive in the past.  That said,
> > > hooking KVM_RUN is likely the wrong way to go about implementing any restrictions.
> > > Running a vCPU is where much of the vCPU's state is explicitly consumed, but it's
> > > all too easy for KVM to implicity/indirectly consume state via a different ioctl(),
> > > e.g. if there are side effects that are visible in other registers, than an update
> > > can also be visible to userspace via KVM_{G,S}ET_{S,}REGS, at which point disallowing
> > > modifying state after KVM_RUN but not after reading/writing regs is arbitrary and
> > > inconsitent.
> >
> > Thank you for your comments !
> > I think I understand your concern, and that's a great point.
> > That's not the case for those pseudo registers though at least for now :)
> > BTW, is this concern specific to hooking KVM_RUN ? (Wouldn't it be the
> > same for the option with "if kvm->created_vcpus > 0" ?)
>
> Not really?  The goal with created_vcpus is to avoid having inconsistent state in
> "struct kvm_vcpu" with respect to the VM as whole.  "struct kvm" obvioulsy can't
> be inconsistent with itself, e.g. even if userspace consumes some side effect,
> that's simply "the state".  Did that make sense?  Hard to explain in writing :-)
>
> > > If possible, preventing modification if kvm->created_vcpus > 0 is ideal as it's
> > > a relatively common pattern in KVM, and provides a clear boundary to userpace
> > > regarding what is/isn't allowed.
> >
> > Yes, I agree that would be better in general.  For (pseudo) registers,
>
> What exactly are these pseudo registers?  If it's something that's an immutable
> property of the (virtual) system, then it might make sense to use a separate,
> non-vCPU mechanism for setting/getting their values.  Then you can easily restrict
> the <whatever> to pre-created_vcpus, e.g. see x86's KVM_SET_IDENTITY_MAP_ADDR.
>
In general, these pseudo-registers are reserved non-architectural
register spaces, currently being used to represent KVM-as-a-firmware's
versioning across guests' migrations [1]. That is, the user-space
configures these registers for the guests to see same 'firmware'
versions before and after migrations. The model is built over the
existing KVM_GET_REG_LIST and KVM_[SET|GET]_ONE_REG APIs. Since this
series' efforts falls into the same realm, the idea was keep this
consistent with the existing model to which VMMs (such as QEMU) are
already used to.

Granted, even though these registers should technically be immutable,
there was no similar protection employed for the existing
psuedo-registers. I was wondering if that could be of any value if we
start providing one; But I guess not, since it may break the
user-space's expectations of KVM (and probably why we didn't have it
earlier).

Regards,
Raghavendra

[1]: https://github.com/torvalds/linux/blob/master/Documentation/virt/kvm/arm/psci.rst

> > I would think preventing modification if kvm->created_vcpus > 0 might
> > not be a very good option for KVM/ARM though considering usage of
> > KVM_GET_REG_LIST and KVM_{G,S}ET_ONE_REG.


From alim.akhtar at samsung.com  Thu Jan 20 11:24:35 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 00:54:35 +0530
Subject: [PATCH v2 0/3] Add FSD SPI support
References: <CGME20220120193608epcas5p466c73dfdcc7eb5cdcd52516a635fca79@epcas5p4.samsung.com>
Message-ID: <20220120192438.25555-1-alim.akhtar@samsung.com>

Adds support for SPI controller found in Tesla FSD SoC

-Changes since v1
* Splited SPI changes from a larger inital patch set
* Rebased on Krzysztof's latest (v5) SPI schema changes
* Added tag

Note: This series is depended on [1] patches which adds
support of FSD SoC and on Krzysztof's v5 [2] of spi schema changes

[1] https://lkml.org/lkml/2022/1/18/498
[2] https://www.spinics.net/lists/kernel/msg4211991.html

Alim Akhtar (2):
  spi: dt-bindings: samsung: Add fsd spi compatible
  spi: s3c64xx: Add spi port configuration for Tesla FSD SoC

Aswani Reddy (1):
  arm64: dts: fsd: Add SPI device nodes

 .../devicetree/bindings/spi/samsung,spi.yaml  |  1 +
 arch/arm64/boot/dts/tesla/fsd.dtsi            | 57 +++++++++++++++++++
 drivers/spi/spi-s3c64xx.c                     | 13 +++++
 3 files changed, 71 insertions(+)

-- 
2.25.1



From alim.akhtar at samsung.com  Thu Jan 20 11:24:36 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 00:54:36 +0530
Subject: [PATCH v2 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <20220120192438.25555-1-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193613epcas5p238851849d212e01d7d830d78ca7d6379@epcas5p2.samsung.com>
Message-ID: <20220120192438.25555-2-alim.akhtar@samsung.com>

Adds spi controller dt-binding compatible information for
Tesla Full Self-Driving (FSD) SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Adithya K V <adithya.kv at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
index 61c77088e8ee..bf9a76d931d2 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -21,6 +21,7 @@ properties:
           - samsung,s3c6410-spi
           - samsung,s5pv210-spi # for S5PV210 and S5PC110
           - samsung,exynos5433-spi
+          - tesla,fsd-spi
       - const: samsung,exynos7-spi
         deprecated: true
 
-- 
2.25.1



From alim.akhtar at samsung.com  Thu Jan 20 11:24:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 00:54:37 +0530
Subject: [PATCH v2 2/3] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220120192438.25555-1-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193618epcas5p45be1db500363072e647bf179623f8e7a@epcas5p4.samsung.com>
Message-ID: <20220120192438.25555-3-alim.akhtar@samsung.com>

Adds compatible and port configuration for spi controller
for Tesla Full Self-Driving SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/spi/spi-s3c64xx.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 386550fca81c..423518bf0270 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1440,6 +1440,16 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
+static struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.clk_ioclk	= false,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1470,6 +1480,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,exynos5433-spi",
 			.data = (void *)&exynos5433_spi_port_config,
 	},
+	{ .compatible = "tesla,fsd-spi",
+			.data = (void *)&fsd_spi_port_config,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
-- 
2.25.1



From alim.akhtar at samsung.com  Thu Jan 20 11:24:38 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 00:54:38 +0530
Subject: [PATCH v2 3/3] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220120192438.25555-1-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193622epcas5p3a65c8424c6a01aed9a87f5ac2a89eb06@epcas5p3.samsung.com>
Message-ID: <20220120192438.25555-4-alim.akhtar@samsung.com>

From: Aswani Reddy <aswani.reddy at samsung.com>

Adds device tree node for SPI IPs

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 57 ++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index bab63c9f79dc..86cf1446d1fc 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -29,6 +29,9 @@ aliases {
 		pinctrl0 = &pinctrl_fsys0;
 		pinctrl1 = &pinctrl_peric;
 		pinctrl2 = &pinctrl_pmu;
+		spi0 = &spi_0;
+		spi1 = &spi_1;
+		spi2 = &spi_2;
 	};
 
 	cpus {
@@ -667,6 +670,60 @@ pinctrl_fsys0: pinctrl at 15020000 {
 			reg = <0x0 0x15020000 0x0 0x1000>;
 			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		spi_0: spi at 14140000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14140000 0x0 0x100>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 4>, <&pdma1 5>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI0>,
+				<&clock_peric PERIC_SCLK_SPI0>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_1: spi at 14150000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14150000 0x0 0x100>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 6>, <&pdma1 7>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI1>,
+				<&clock_peric PERIC_SCLK_SPI1>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_2: spi at 14160000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14160000 0x0 0x100>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 8>, <&pdma1 9>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI2>,
+				<&clock_peric PERIC_SCLK_SPI2>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi2_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
 	};
 };
 
-- 
2.25.1



From helgaas at kernel.org  Thu Jan 20 11:37:13 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 20 Jan 2022 13:37:13 -0600
Subject: [PATCH 08/15] PCI: mvebu: Propagate errors when updating
 PCI_IO_BASE and PCI_MEM_BASE registers
In-Reply-To: <20220120190826.wkhkcx53lmafq2yp@pali>
Message-ID: <20220120193713.GA1060589@bhelgaas>

On Thu, Jan 20, 2022 at 08:08:26PM +0100, Pali Roh?r wrote:
> On Thursday 20 January 2022 11:50:47 Bjorn Helgaas wrote:
> > On Thu, Jan 13, 2022 at 11:35:23AM +0100, Pali Roh?r wrote:
> > > On Wednesday 12 January 2022 18:19:21 Bjorn Helgaas wrote:
> > > > On Sat, Jan 08, 2022 at 12:46:58AM +0100, Pali Roh?r wrote:
> > > > > On Friday 07 January 2022 17:16:17 Bjorn Helgaas wrote:
> > > > > > On Fri, Jan 07, 2022 at 11:28:26PM +0100, Pali Roh?r wrote:
> > > > > > > On Friday 07 January 2022 15:55:04 Bjorn Helgaas wrote:
> > > > > > > > On Thu, Nov 25, 2021 at 01:45:58PM +0100, Pali Roh?r wrote:
> > > > > > > > > Properly propagate failure from
> > > > > > > > > mvebu_pcie_add_windows() function back to the caller
> > > > > > > > > mvebu_pci_bridge_emul_base_conf_write() and
> > > > > > > > > correctly updates PCI_IO_BASE, PCI_MEM_BASE and
> > > > > > > > > PCI_IO_BASE_UPPER16 registers on error.  On error
> > > > > > > > > set base value higher than limit value which
> > > > > > > > > indicates that address range is disabled. 

> > Regardless, this means PCI thinks [mem 0xe0000000-0xe7ffffff] is
> > available on bus 00 and can be assigned to devices on bus 00
> > according to the normal PCI rules (BARs aligned on size, PCI
> > bridge windows aligned on 1MB and multiple of 1MB in size).  IIUC,
> > mvebu imposes additional alignment constraints on the bridge
> > windows.
> > 
> > These are the bridge window assignments from your dmesg:
> > 
> > > pci 0000:00:01.0: BAR 8: assigned [mem 0xe0000000-0xe00fffff]
> > > pci 0000:00:02.0: BAR 8: assigned [mem 0xe0200000-0xe04fffff]
> > > pci 0000:00:03.0: BAR 8: assigned [mem 0xe0100000-0xe01fffff]
> > 
> > > pci 0000:00:01.0: PCI bridge to [bus 01]
> > > pci 0000:00:01.0:   bridge window [mem 0xe0000000-0xe00fffff]
> > > pci 0000:00:02.0: PCI bridge to [bus 02]
> > > pci 0000:00:02.0:   bridge window [mem 0xe0200000-0xe04fffff]
> > > pci 0000:00:03.0: PCI bridge to [bus 03]
> > > pci 0000:00:03.0:   bridge window [mem 0xe0100000-0xe01fffff]
> > 
> > The PCI core knows nothing about the mvebu constraints.  Are we
> > just lucky here that when PCI assigned these bridge windows, they
> > happen to be supported on mvebu?  What happens if PCI decides it
> > needs 29MB on bus 01?
> 
> In this case pci-mvebu.c split 29MB window into continuous ranges of
> power of two (16MB + 8MB + 4MB + 1MB) and then register each range
> to mbus slot. Code is in function mvebu_pcie_add_windows():
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/controller/pci-mvebu.c?h=v5.15#n300
> 
> So at the end there is continuous space of 29MB PCIe window, just it
> "eats" 4 mbus slots.
> 
> This function may fail (if there is not enough free mbus slots) and
> this patch is propagating that failure back to the caller.

This failure cannot occur in conforming PCI hardware.  I guess if you
want to propagate the error from mvebu_pcie_add_windows() back to
mvebu_pci_bridge_emul_base_conf_write() and do something there, I'm OK
with that.

But change the commit log so it doesn't say "... and correctly update
PCI_IO_BASE, PCI_MEM_BASE and PCI_IO_BASE_UPPER16" because this is
completely device-specific behavior and is not "correct" per any PCI
spec.

Instead, say something about how mvebu doesn't support arbitrary
windows and we're disabling the window completely if we can't provide
what's requested.  

Maybe this error warrants a clue in dmesg?  How would a user figure
out what's going on in this situation?  From the patch, it looks like
we would assign resources to a device, but the device just would not
work because the root port window was silently disabled?

Bjorn


From f.fainelli at gmail.com  Thu Jan 20 11:48:30 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 20 Jan 2022 11:48:30 -0800
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <20220120153928.yvkrqduoytddvegs@houat>
 <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>
Message-ID: <409091e8-abec-ce90-a247-246167223d92@gmail.com>



On 1/20/2022 10:10 AM, Stefan Wahren wrote:
> Hi Maxime,
> 
> Am 20.01.22 um 16:39 schrieb Maxime Ripard:
>> Hi Stefan,
>>
>> On Sun, Jan 16, 2022 at 06:26:58PM +0100, Stefan Wahren wrote:
>>> recently i saw a report [1] about bad chained IRQ with Linux 5.15.13
>>> Aarch64 with Arch Linux. I'm able to reproduce this issue on my
>>> Raspberry Pi 4 B (8 GB RAM, Firmware: 2022-01-06T15:39:30) by turning
>>> the connected HDMI monitor off and on again.
>> By turning the monitor on and off, you mean that you used the power
>> button on it?
> yes, correct
>>   Not something like disabling the output in sysfs, right?
>>
>>> Kernel output is the following:
>>>
>>> [15053.285438] irq 10, desc: 00000000acc41fca, depth: 0, count: 0,
>>> unhandled: 0
>>> [15053.295440] ->handle_irq():? 00000000b28cf1d1,
>>> brcmstb_l2_intc_irq_handle+0x0/0x1e0
>>> [15053.306049] ->irq_data.chip(): 000000005f172760, gic_data+0x0/0x768
>>> [15053.315233] ->action(): 00000000236e815e
>>> [15053.322022] ->action->handler(): 0000000013023289,
>>> bad_chained_irq+0x0/0x50
>>> [15053.331909]????? IRQ_LEVEL set
>>> [15053.337822]??? IRQ_NOPROBE set
>>> [15053.343715]? IRQ_NOREQUEST set
>>> [15053.349585]?? IRQ_NOTHREAD set
>> IRQ10 is the interrupt that a monitor has been connected on HDMI1, which
>> makes sense if you were using HDMI1.
> 
> The irq number in this output is always 10 regardless of the used HDMI
> connector (0 or 1). So maybe it's the hardware interrupt? Also in the
> interrupts list there is a interrupt with number 10 in the first column,
> which has the name (null) and it's count is identical to the occured
> warnings.

10 is the virtual interrupt number of the interrupt descriptor 
allocated, the hardware interrupt is 128 (32 for the SPI offset and 96 
for the actual number within the SPI).

> 
> [??? 0.000000] irq_brcmstb_l2: registered L2 intc
> (/soc/interrupt-controller at 7ef00100, parent irq: 10)
> 
>>   Usually, when a display is turned
>> on, it will issue a pulse on the HPD line so we would have a
>> disconnection interrupt followed by a connection interrupt.
>>
>> This is weird though, since we have an interrupt handler on that
>> interrupt (hpd-connected in the DT binding):
>> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/vc4/vc4_hdmi.c#L1578
> 
> I played a little bit with turn on/off and it seems the connect
> interrupts get lost sometimes (see below). I mean the warning doesn't
> occur always, it happens most of the time.

The fact that you are losing interrupts makes sense because we have a 
level handler registered for HW interrupt 128 which "steals" the 
interrupt events from the L2 interrupt controller handler that would 
process them as edge, if used. The complains from the kernel is because 
on one hand the interrupt descriptor wants a certain set of properties 
(level triggered in particular), but the flow that is installed by 
irq-brcmstb-l2 is of edge type, mayhem ensues.

> 
> reduced /proc/interrupts for HDMI 0 case:
> 
>  ?10:????????? 5????????? 0????????? 0????????? 0???? GICv2 128 Level
> (null)
>  ?...
> 
>  ?43:????????? 1????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
>  ?44:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
>  ?47:????????? 4????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
>  ?48:????????? 7????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
>  ?49:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
>  ?50:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
>  ?53:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
>  ?54:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
> 
> ...
> 
> Err:????????? 5
> 
> /proc/interrupts for HDMI 1 case:
> 
>  ?10:????????? 6????????? 0????????? 0????????? 0???? GICv2 128 Level
> (null)
> ...
>  ?43:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 0 Edge????? vc4 hdmi cec tx
>  ?44:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 1 Edge????? vc4 hdmi cec rx
>  ?47:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 4 Edge????? vc4 hdmi hpd connected
>  ?48:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 5 Edge????? vc4 hdmi hpd disconnected
>  ?49:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 8 Edge????? vc4 hdmi cec tx
>  ?50:????????? 0????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100?? 7 Edge????? vc4 hdmi cec rx
>  ?53:????????? 3????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 10 Edge????? vc4 hdmi hpd connected
>  ?54:????????? 7????????? 0????????? 0????????? 0
> interrupt-controller at 7ef00100? 11 Edge????? vc4 hdmi hpd disconnected
> 
> ...
> 
> Err:????????? 6
> 
> I could send a diff of the config against arm64/defconfig? Contrary to
> the Raspberry Pi OS, Arch Linux uses U-Boot not sure this is related.

Can we get the full dump of the Device Tree that you are running with? 
Something like:

dtc -I fs /proc/device-tree -O dts > live.dts

would be helpful to figure out what is going on here.
-- 
Florian


From linux at roeck-us.net  Thu Jan 20 11:58:46 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Thu, 20 Jan 2022 11:58:46 -0800
Subject: [PATCH] dt-bindings: watchdog: fsl-imx7ulp-wdt: Fix
 assigned-clock-parents
In-Reply-To: <20220120172333.1628990-1-robh@kernel.org>
References: <20220120172333.1628990-1-robh@kernel.org>
Message-ID: <f1df742c-2f97-75d6-9fe2-4cc508dc9937@roeck-us.net>

On 1/20/22 9:23 AM, Rob Herring wrote:
> The schema has a typo with 'assigned-clocks-parents'. As it is not
> required to list assigned clocks in bindings, just drop the assigned-clocks
> property definitions to fix this.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>

Acked-by: Guenter Roeck <linux at roeck-us.net>

> ---
>   .../devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml     | 8 +-------
>   1 file changed, 1 insertion(+), 7 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
> index fb603a20e396..4ca8a31359a5 100644
> --- a/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
> +++ b/Documentation/devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml
> @@ -29,12 +29,6 @@ properties:
>     clocks:
>       maxItems: 1
>   
> -  assigned-clocks:
> -    maxItems: 1
> -
> -  assigned-clocks-parents:
> -    maxItems: 1
> -
>     timeout-sec: true
>   
>   required:
> @@ -56,7 +50,7 @@ examples:
>           interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
>           clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
>           assigned-clocks = <&pcc2 IMX7ULP_CLK_WDG1>;
> -        assigned-clocks-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
> +        assigned-clock-parents = <&scg1 IMX7ULP_CLK_FIRC_BUS_CLK>;
>           timeout-sec = <40>;
>       };
>   
> 



From semen.protsenko at linaro.org  Thu Jan 20 12:19:55 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 20 Jan 2022 22:19:55 +0200
Subject: [RFC 0/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
Message-ID: <20220120201958.2649-1-semen.protsenko@linaro.org>

This is a draft of a new IOMMU driver used in modern Exynos SoCs (like
Exynos850) and Google's GS101 SoC (used in Pixel 6 phone). Most of its
code were taken from GS101 downstream kernel [1], with some extra
patches on top (fixes from Exynos850 downstream kernel and some porting
changes to adapt it to the mainline kernel). All development history can
be found at [2].

Similarities with existing exynos-iommu.c is minimal. I did some
analysis using similarity-tester tool:

8<-------------------------------------------------------------------->8
    $ sim_c -peu -S exynos-iommu.c "|" samsung-*

    exynos-iommu.c consists for 15 % of samsung-iommu.c material
    exynos-iommu.c consists for 1 %  of samsung-iommu-fault.c material
    exynos-iommu.c consists for 3 %  of samsung-iommu.h material
8<-------------------------------------------------------------------->8

So the similarity is very low, most of that code is some boilerplate
that shouldn't be extracted to common code (like allocating the memory
and requesting clocks/interrupts in probe function).

It was tested on v5.4 Android kernel on Exynos850 (E850-96 board) with
DPU use-case (displaying some graphics to the screen). Also it
apparently works fine on v5.10 GS101 kernel (on Pixel 6). On mainline
kernel I managed to build, match and bind the driver. No real world test
was done, but the changes from v5.10 (where it works fine) are minimal
(see [2] for details). So I'm pretty sure the driver is functional.

For this patch series I'd like to receive some high-level review for
driver's design and architecture. Coding style and API issues I can fix
later, when sending real (not RFC) series. Particularly I'd like to hear
some opinions about:
  - namings: Kconfig option, file names, module name, compatible, etc
  - modularity: should this driver be a different platform driver (like
    in this series), or should it be integrated into existing
    exynos-iommu.c driver somehow
  - dt-bindings: does it look ok as it is, or some interface changes are
    needed
  - internal driver architecture: approach seems to be similar to
    exynos-iommu.c, but any comments are welcome
  - ongoing work: please let me know if you're aware of some efforts to
    upstream this driver by some other party (e.g. Google engineers
    might be working on something similar)

Basically, I want to figure out what should be changed/fixed in this
driver (on a high level), so it can be considered "upstreamable".

[1] https://android.googlesource.com/kernel/gs/
[2] https://github.com/joe-skb7/linux/commits/iommu-exynos850-dev

Sam Protsenko (3):
  dt-bindings: iommu: Add bindings for samsung,sysmmu-v8
  iommu/samsung: Introduce Exynos sysmmu-v8 driver
  arm64: defconfig: Enable sysmmu-v8 IOMMU

 .../bindings/iommu/samsung,sysmmu-v8.txt      |   31 +
 arch/arm64/configs/defconfig                  |    2 +
 drivers/iommu/Kconfig                         |   13 +
 drivers/iommu/Makefile                        |    3 +
 drivers/iommu/samsung-iommu-fault.c           |  617 +++++++
 drivers/iommu/samsung-iommu-group.c           |   50 +
 drivers/iommu/samsung-iommu.c                 | 1521 +++++++++++++++++
 drivers/iommu/samsung-iommu.h                 |  216 +++
 include/dt-bindings/soc/samsung,sysmmu-v8.h   |   43 +
 9 files changed, 2496 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
 create mode 100644 drivers/iommu/samsung-iommu-fault.c
 create mode 100644 drivers/iommu/samsung-iommu-group.c
 create mode 100644 drivers/iommu/samsung-iommu.c
 create mode 100644 drivers/iommu/samsung-iommu.h
 create mode 100644 include/dt-bindings/soc/samsung,sysmmu-v8.h

-- 
2.30.2



From semen.protsenko at linaro.org  Thu Jan 20 12:19:56 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 20 Jan 2022 22:19:56 +0200
Subject: [RFC 1/3] dt-bindings: iommu: Add bindings for samsung,sysmmu-v8
In-Reply-To: <20220120201958.2649-1-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
Message-ID: <20220120201958.2649-2-semen.protsenko@linaro.org>

Only example of usage and header for now.

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 .../bindings/iommu/samsung,sysmmu-v8.txt      | 31 +++++++++++++
 include/dt-bindings/soc/samsung,sysmmu-v8.h   | 43 +++++++++++++++++++
 2 files changed, 74 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
 create mode 100644 include/dt-bindings/soc/samsung,sysmmu-v8.h

diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt b/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
new file mode 100644
index 000000000000..d6004ea4a746
--- /dev/null
+++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
@@ -0,0 +1,31 @@
+Example (Exynos850, IOMMU for DPU usage):
+
+	#include <dt-bindings/soc/samsung,sysmmu-v8.h>
+
+	/* IOMMU group info */
+	iommu_group_dpu: iommu_group_dpu {
+		compatible = "samsung,sysmmu-group";
+	};
+
+	sysmmu_dpu: sysmmu at 130c0000 {
+		compatible = "samsung,sysmmu-v8";
+		reg = <0x130c0000 0x9000>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+		qos = <15>;
+
+		clocks = <&cmu_dpu CLK_GOUT_DPU_SMMU_CLK>;
+		clock-names = "gate";
+
+		sysmmu,secure-irq;
+		sysmmu,secure_base = <0x130d0000>;
+		sysmmu,default_tlb = <TLB_CFG(BL1, PREFETCH_PREDICTION)>;
+		sysmmu,tlb_property =
+			<1 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x2, 0xF)>,
+			<2 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x4, 0xF)>,
+			<3 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x6, 0xF)>,
+			<4 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x8, 0xF)>;
+		port-name = "DPU";
+		#iommu-cells = <0>;
+		//power-domains = <&pd_dpu>;
+	};
diff --git a/include/dt-bindings/soc/samsung,sysmmu-v8.h b/include/dt-bindings/soc/samsung,sysmmu-v8.h
new file mode 100644
index 000000000000..2d422e05dae1
--- /dev/null
+++ b/include/dt-bindings/soc/samsung,sysmmu-v8.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Device Tree binding constants for Exynos System MMU.
+ */
+
+#ifndef _DT_BINDINGS_SAMSUNG_SYSMMU_V8_H
+#define _DT_BINDINGS_SAMSUNG_SYSMMU_V8_H
+
+/* define for fetchsize in TLB_CFG */
+#define BL1			(0x0 << 5)
+#define BL2			(0x1 << 5)
+#define BL4			(0x2 << 5)
+#define BL8			(0x3 << 5)
+#define BL16			(0x4 << 5)
+#define BL32			(0x5 << 5)
+#define BL64			(0x6 << 5)
+
+/* define for prefetch in TLB_CFG */
+#define PREFETCH_NONE		(0x0 << 1)
+#define PREFETCH_DESCENDING	(0x1 << 1)
+#define PREFETCH_ASCENDING	(0x3 << 1)
+#define PREFETCH_PREDICTION	(0x5 << 1)
+
+/* combine fetchsize and prefetch */
+#define TLB_CFG(fetchsize, prefetch)	(fetchsize | prefetch)
+#define TLB_CFG_DEFAULT		0x0
+
+/* define for direction in TLB_MATCH_CFG */
+#define DIR_NONE		(0x0 << 8)
+#define DIR_READ		(0x1 << 8)
+#define DIR_WRITE		(0x2 << 8)
+#define DIR_RW			(0x3 << 8)
+
+/* define for TLB_MATCH_SID */
+#define SYSMMU_ID_MASK(id,mask)		((mask) << 16 | (id))
+#define SYSMMU_NOID			0
+
+#endif /* _DT_BINDINGS_SAMSUNG_SYSMMU_V8_H */
-- 
2.30.2



From semen.protsenko at linaro.org  Thu Jan 20 12:19:58 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 20 Jan 2022 22:19:58 +0200
Subject: [RFC 3/3] arm64: defconfig: Enable sysmmu-v8 IOMMU
In-Reply-To: <20220120201958.2649-1-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
Message-ID: <20220120201958.2649-4-semen.protsenko@linaro.org>

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..bb03628b5e25 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1033,6 +1033,8 @@ CONFIG_ARM_SMMU=y
 CONFIG_ARM_SMMU_V3=y
 CONFIG_MTK_IOMMU=y
 CONFIG_QCOM_IOMMU=y
+CONFIG_SAMSUNG_IOMMU=m
+CONFIG_SAMSUNG_IOMMU_GROUP=y
 CONFIG_REMOTEPROC=y
 CONFIG_QCOM_Q6V5_MSS=m
 CONFIG_QCOM_Q6V5_PAS=m
-- 
2.30.2



From semen.protsenko at linaro.org  Thu Jan 20 12:19:57 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 20 Jan 2022 22:19:57 +0200
Subject: [RFC 2/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
In-Reply-To: <20220120201958.2649-1-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
Message-ID: <20220120201958.2649-3-semen.protsenko@linaro.org>

Introduce new driver for modern Exynos ARMv8 SoCs, e.g. Exynos850. Also
it's used for Google's GS101 SoC.

This is squashed commit, contains next patches of different authors. See
`iommu-exynos850-dev' branch for details: [1].

Original authors (Samsung):

 - Cho KyongHo <pullip.cho at samsung.com>
 - Hyesoo Yu <hyesoo.yu at samsung.com>
 - Janghyuck Kim <janghyuck.kim at samsung.com>
 - Jinkyu Yang <jinkyu1.yang at samsung.com>

Some improvements were made by Google engineers:

 - Alex <acnwigwe at google.com>
 - Carlos Llamas <cmllamas at google.com>
 - Daniel Mentz <danielmentz at google.com>
 - Erick Reyes <erickreyes at google.com>
 - J. Avila <elavila at google.com>
 - Jonglin Lee <jonglin at google.com>
 - Mark Salyzyn <salyzyn at google.com>
 - Thierry Strudel <tstrudel at google.com>
 - Will McVicker <willmcvicker at google.com>

[1] https://github.com/joe-skb7/linux/tree/iommu-exynos850-dev

Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
---
 drivers/iommu/Kconfig               |   13 +
 drivers/iommu/Makefile              |    3 +
 drivers/iommu/samsung-iommu-fault.c |  617 +++++++++++
 drivers/iommu/samsung-iommu-group.c |   50 +
 drivers/iommu/samsung-iommu.c       | 1521 +++++++++++++++++++++++++++
 drivers/iommu/samsung-iommu.h       |  216 ++++
 6 files changed, 2420 insertions(+)
 create mode 100644 drivers/iommu/samsung-iommu-fault.c
 create mode 100644 drivers/iommu/samsung-iommu-group.c
 create mode 100644 drivers/iommu/samsung-iommu.c
 create mode 100644 drivers/iommu/samsung-iommu.h

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3eb68fa1b8cc..78e7039f18aa 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -452,6 +452,19 @@ config QCOM_IOMMU
 	help
 	  Support for IOMMU on certain Qualcomm SoCs.
 
+config SAMSUNG_IOMMU
+	tristate "Samsung IOMMU Support"
+	select ARM_DMA_USE_IOMMU
+	select IOMMU_DMA
+	select SAMSUNG_IOMMU_GROUP
+	help
+	  Support for IOMMU on Samsung Exynos SoCs.
+
+config SAMSUNG_IOMMU_GROUP
+	tristate "Samsung IOMMU Group Support"
+	help
+	  Support for IOMMU group on Samsung Exynos SoCs.
+
 config HYPERV_IOMMU
 	bool "Hyper-V x2APIC IRQ Handling"
 	depends on HYPERV && X86
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index bc7f730edbb0..a8bdf449f1d4 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -27,6 +27,9 @@ obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
 obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
+obj-$(CONFIG_SAMSUNG_IOMMU) += samsung_iommu.o
+samsung_iommu-objs += samsung-iommu.o samsung-iommu-fault.o
+obj-$(CONFIG_SAMSUNG_IOMMU_GROUP) += samsung-iommu-group.o
 obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o
 obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
 obj-$(CONFIG_APPLE_DART) += apple-dart.o
diff --git a/drivers/iommu/samsung-iommu-fault.c b/drivers/iommu/samsung-iommu-fault.c
new file mode 100644
index 000000000000..c6b4259976c4
--- /dev/null
+++ b/drivers/iommu/samsung-iommu-fault.c
@@ -0,0 +1,617 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ */
+
+#define pr_fmt(fmt) "sysmmu: " fmt
+
+#include <linux/smc.h>
+#include <linux/arm-smccc.h>
+#include <linux/pm_runtime.h>
+
+#include "samsung-iommu.h"
+
+#define MMU_TLB_INFO(n)			(0x2000 + ((n) * 0x20))
+#define MMU_CAPA1_NUM_TLB_SET(reg)	(((reg) >> 16) & 0xFF)
+#define MMU_CAPA1_NUM_TLB_WAY(reg)	((reg) & 0xFF)
+#define MMU_CAPA1_SET_TLB_READ_ENTRY(tid, set, way, line)		\
+					((set) | ((way) << 8) |		\
+					 ((line) << 16) | ((tid) << 20))
+
+#define MMU_TLB_ENTRY_VALID(reg)	((reg) >> 28)
+#define MMU_SBB_ENTRY_VALID(reg)	((reg) >> 28)
+#define MMU_VADDR_FROM_TLB(reg, idx)	((((reg) & 0xFFFFC) | ((idx) & 0x3)) << 12)
+#define MMU_VID_FROM_TLB(reg)		(((reg) >> 20) & 0x7U)
+#define MMU_PADDR_FROM_TLB(reg)		((phys_addr_t)((reg) & 0xFFFFFF) << 12)
+#define MMU_VADDR_FROM_SBB(reg)		(((reg) & 0xFFFFF) << 12)
+#define MMU_VID_FROM_SBB(reg)		(((reg) >> 20) & 0x7U)
+#define MMU_PADDR_FROM_SBB(reg)		((phys_addr_t)((reg) & 0x3FFFFFF) << 10)
+
+#define REG_MMU_INT_STATUS		0x060
+#define REG_MMU_INT_CLEAR		0x064
+#define REG_MMU_FAULT_RW_MASK		GENMASK(20, 20)
+#define IS_READ_FAULT(x)		(((x) & REG_MMU_FAULT_RW_MASK) == 0)
+
+#define SYSMMU_FAULT_PTW_ACCESS   0
+#define SYSMMU_FAULT_PAGE_FAULT   1
+#define SYSMMU_FAULT_ACCESS       2
+#define SYSMMU_FAULT_RESERVED     3
+#define SYSMMU_FAULT_UNKNOWN      4
+
+#define SYSMMU_SEC_FAULT_MASK		(BIT(SYSMMU_FAULT_PTW_ACCESS) | \
+					 BIT(SYSMMU_FAULT_PAGE_FAULT) | \
+					 BIT(SYSMMU_FAULT_ACCESS))
+
+#define SYSMMU_FAULTS_NUM         (SYSMMU_FAULT_UNKNOWN + 1)
+
+#if IS_ENABLED(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION)
+#define SMC_DRM_SEC_SMMU_INFO		(0x820020D0)
+#define SMC_DRM_SEC_SYSMMU_INT_CLEAR	(0x820020D7)
+
+/* secure SysMMU SFR access */
+enum sec_sysmmu_sfr_access_t {
+	SEC_SMMU_SFR_READ,
+	SEC_SMMU_SFR_WRITE,
+};
+
+#define is_secure_info_fail(x)		((((x) >> 16) & 0xffff) == 0xdead)
+static inline u32 read_sec_info(unsigned int addr)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(SMC_DRM_SEC_SMMU_INFO,
+		      (unsigned long)addr, 0, SEC_SMMU_SFR_READ, 0, 0, 0, 0,
+		      &res);
+	if (is_secure_info_fail(res.a0))
+		pr_err("Invalid value returned, %#lx\n", res.a0);
+
+	return (u32)res.a0;
+}
+
+static inline u32 clear_sec_fault(unsigned int addr, unsigned int val)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(SMC_DRM_SEC_SYSMMU_INT_CLEAR,
+		      (unsigned long)addr, (unsigned long)val, 0, 0, 0, 0, 0,
+		      &res);
+	return (u32)res.a0;
+}
+
+#else
+static inline u32 read_sec_info(unsigned int addr)
+{
+	return 0xdead;
+}
+
+static inline u32 clear_sec_fault(unsigned int addr, unsigned int val)
+{
+	return 0;
+}
+
+#endif
+
+static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
+	"PTW ACCESS FAULT",
+	"PAGE FAULT",
+	"ACCESS FAULT",
+	"RESERVED",
+	"UNKNOWN FAULT"
+};
+
+static unsigned int sysmmu_fault_type[SYSMMU_FAULTS_NUM] = {
+	IOMMU_FAULT_REASON_WALK_EABT,
+	IOMMU_FAULT_REASON_PTE_FETCH,
+	IOMMU_FAULT_REASON_ACCESS,
+	IOMMU_FAULT_REASON_UNKNOWN,
+	IOMMU_FAULT_REASON_UNKNOWN,
+};
+
+struct samsung_sysmmu_fault_info {
+	struct sysmmu_drvdata *drvdata;
+	struct iommu_fault_event event;
+};
+
+static inline u32 __sysmmu_get_intr_status(struct sysmmu_drvdata *data,
+					   bool is_secure)
+{
+	if (is_secure)
+		return read_sec_info(data->secure_base + REG_MMU_INT_STATUS);
+	else
+		return readl_relaxed(data->sfrbase + REG_MMU_INT_STATUS);
+}
+
+static inline sysmmu_iova_t __sysmmu_get_fault_address(struct sysmmu_drvdata *data,
+						       unsigned int vid, bool is_secure)
+{
+	if (is_secure)
+		return read_sec_info(MMU_SEC_VM_REG(data, IDX_FAULT_VA, vid));
+	else
+		return readl_relaxed(MMU_VM_REG(data, IDX_FAULT_VA, vid));
+}
+
+static inline void sysmmu_tlb_compare(phys_addr_t pgtable[MAX_VIDS],
+				      unsigned int idx_sub, u32 vpn, u32 ppn, u32 attr)
+{
+	sysmmu_pte_t *entry;
+	sysmmu_iova_t vaddr = MMU_VADDR_FROM_TLB(vpn, idx_sub);
+	unsigned int vid = MMU_VID_FROM_TLB(attr);
+	phys_addr_t paddr = MMU_PADDR_FROM_TLB(ppn);
+	phys_addr_t phys = 0;
+
+	if (!pgtable[vid])
+		return;
+
+	entry = section_entry(phys_to_virt(pgtable[vid]), vaddr);
+
+	if (lv1ent_section(entry)) {
+		phys = section_phys(entry);
+	} else if (lv1ent_page(entry)) {
+		entry = page_entry(entry, vaddr);
+
+		if (lv2ent_large(entry))
+			phys = lpage_phys(entry);
+		else if (lv2ent_small(entry))
+			phys = spage_phys(entry);
+	} else {
+		pr_crit(">> Invalid address detected! entry: %#lx",
+			(unsigned long)*entry);
+		return;
+	}
+
+	if (paddr != phys) {
+		pr_crit(">> TLB mismatch detected!\n");
+		pr_crit("   TLB: %pa, PT entry: %pa\n", &paddr, &phys);
+	}
+}
+
+static inline void sysmmu_sbb_compare(u32 sbb_vpn, u32 sbb_link, u32 sbbattr,
+				      phys_addr_t pgtable[MAX_VIDS])
+{
+	sysmmu_pte_t *entry;
+	sysmmu_iova_t vaddr = MMU_VADDR_FROM_SBB(sbb_vpn);
+	unsigned int vid = MMU_VID_FROM_SBB(sbbattr);
+	phys_addr_t paddr = MMU_PADDR_FROM_SBB(sbb_link);
+	phys_addr_t phys = 0;
+
+	if (!pgtable[vid])
+		return;
+
+	entry = section_entry(phys_to_virt(pgtable[vid]), vaddr);
+
+	if (lv1ent_page(entry)) {
+		phys = lv2table_base(entry);
+
+		if (paddr != phys) {
+			pr_crit(">> SBB mismatch detected!\n");
+			pr_crit("   entry addr: %pa / SBB addr %pa\n",
+				&paddr, &phys);
+		}
+	} else {
+		pr_crit(">> Invalid address detected! entry: %#lx",
+			(unsigned long)*entry);
+	}
+}
+
+static inline
+unsigned int dump_tlb_entry_port_type(struct sysmmu_drvdata *drvdata, phys_addr_t pgtable[MAX_VIDS],
+				      unsigned int idx_way, unsigned int idx_set,
+				      unsigned int idx_sub)
+{
+	u32 attr = readl_relaxed(MMU_REG(drvdata, IDX_TLB_ATTR));
+
+	if (MMU_TLB_ENTRY_VALID(attr)) {
+		u32 vpn, ppn;
+
+		vpn = readl_relaxed(MMU_REG(drvdata, IDX_TLB_VPN)) + idx_sub;
+		ppn = readl_relaxed(MMU_REG(drvdata, IDX_TLB_PPN));
+
+		pr_crit("[%02u][%02u] VPN: %#010x, PPN: %#010x, ATTR: %#010x\n",
+			idx_way, idx_set, vpn, ppn, attr);
+		sysmmu_tlb_compare(pgtable, idx_sub, vpn, ppn, attr);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+#define MMU_NUM_TLB_SUBLINE		4
+static unsigned int dump_tlb_entry_port(struct sysmmu_drvdata *drvdata,
+					phys_addr_t pgtable[MAX_VIDS],
+					unsigned int tlb, unsigned int way, unsigned int num_set)
+{
+	unsigned int cnt = 0;
+	unsigned int set, line, val;
+
+	for (set = 0; set < num_set; set++) {
+		for (line = 0; line < MMU_NUM_TLB_SUBLINE; line++) {
+			val = MMU_CAPA1_SET_TLB_READ_ENTRY(tlb, set, way, line);
+			writel_relaxed(val, MMU_REG(drvdata, IDX_TLB_READ));
+			cnt += dump_tlb_entry_port_type(drvdata, pgtable,
+							way, set, line);
+		}
+	}
+
+	return cnt;
+}
+
+static inline void dump_sysmmu_tlb_status(struct sysmmu_drvdata *drvdata,
+					  phys_addr_t pgtable[MAX_VIDS])
+{
+	unsigned int t, i;
+	u32 capa0, capa1, info;
+	unsigned int cnt;
+	unsigned int num_tlb, num_port, num_sbb;
+	void __iomem *sfrbase = drvdata->sfrbase;
+
+	capa0 = readl_relaxed(sfrbase + REG_MMU_CAPA0_V7);
+	capa1 = readl_relaxed(sfrbase + REG_MMU_CAPA1_V7);
+
+	num_tlb = MMU_CAPA1_NUM_TLB(capa1);
+	num_port = MMU_CAPA1_NUM_PORT(capa1);
+	num_sbb = 1 << MMU_CAPA_NUM_SBB_ENTRY(capa0);
+
+	pr_crit("SysMMU has %u TLBs, %u ports, %u sbb entries\n",
+		num_tlb, num_port, num_sbb);
+
+	for (t = 0; t < num_tlb; t++) {
+		unsigned int num_set, num_way;
+
+		info = readl_relaxed(sfrbase + MMU_TLB_INFO(t));
+		num_way = MMU_CAPA1_NUM_TLB_WAY(info);
+		num_set = MMU_CAPA1_NUM_TLB_SET(info);
+
+		pr_crit("TLB.%u has %u way, %u set.\n", t, num_way, num_set);
+		pr_crit("------------- TLB[WAY][SET][ENTRY] -------------\n");
+		for (i = 0, cnt = 0; i < num_way; i++)
+			cnt += dump_tlb_entry_port(drvdata, pgtable,
+						   t, i, num_set);
+	}
+	if (!cnt)
+		pr_crit(">> No Valid TLB Entries\n");
+
+	pr_crit("--- SBB(Second-Level Page Table Base Address Buffer) ---\n");
+	for (i = 0, cnt = 0; i < num_sbb; i++) {
+		u32 sbb_vpn, sbblink, sbbattr;
+
+		writel_relaxed(i, MMU_REG(drvdata, IDX_SBB_READ));
+		sbb_vpn = readl_relaxed(MMU_REG(drvdata, IDX_SBB_VPN));
+
+		if (MMU_SBB_ENTRY_VALID(sbb_vpn)) {
+			sbblink = readl_relaxed(MMU_REG(drvdata, IDX_SBB_LINK));
+			sbbattr = readl_relaxed(MMU_REG(drvdata, IDX_SBB_ATTR));
+
+			pr_crit("[%02d] VPN: %#010x, PPN: %#010x, ATTR: %#010x",
+				i, sbb_vpn, sbblink, sbbattr);
+			sysmmu_sbb_compare(sbb_vpn, sbblink, sbbattr, pgtable);
+			cnt++;
+		}
+	}
+	if (!cnt)
+		pr_crit(">> No Valid SBB Entries\n");
+}
+
+static inline void dump_sysmmu_status(struct sysmmu_drvdata *drvdata,
+				      phys_addr_t pgtable[MAX_VIDS], unsigned int vid)
+{
+	int info;
+	void __iomem *sfrbase = drvdata->sfrbase;
+
+	info = MMU_RAW_VER(readl_relaxed(sfrbase + REG_MMU_VERSION));
+
+	pr_crit("ADDR: (VA: %p), MMU_CTRL: %#010x, PT_BASE: %#010x\n",
+		sfrbase,
+		readl_relaxed(sfrbase + REG_MMU_CTRL),
+		readl_relaxed(MMU_VM_REG(drvdata, IDX_FLPT_BASE, vid)));
+	pr_crit("VERSION %d.%d.%d, MMU_CFG: %#010x, MMU_STATUS: %#010x\n",
+		MMU_MAJ_VER(info), MMU_MIN_VER(info), MMU_REV_VER(info),
+		readl_relaxed(sfrbase + REG_MMU_CFG),
+		readl_relaxed(sfrbase + REG_MMU_STATUS));
+
+	if (drvdata->has_vcr)
+		pr_crit("MMU_CTRL_VM: %#010x, MMU_CFG_VM: %#010x\n",
+			readl_relaxed(MMU_VM_REG(drvdata, IDX_CTRL_VM, vid)),
+			readl_relaxed(MMU_VM_REG(drvdata, IDX_CFG_VM, vid)));
+
+	dump_sysmmu_tlb_status(drvdata, pgtable);
+}
+
+static void sysmmu_get_fault_msg(struct sysmmu_drvdata *drvdata, unsigned int intr_type,
+				 unsigned int vid, sysmmu_iova_t fault_addr,
+				 bool is_secure, char *fault_msg, size_t fault_msg_sz)
+{
+	const char *port_name = NULL;
+	unsigned int info;
+
+	of_property_read_string(drvdata->dev->of_node, "port-name", &port_name);
+
+	if (is_secure) {
+		info = read_sec_info(MMU_SEC_REG(drvdata, IDX_FAULT_TRANS_INFO));
+		scnprintf(fault_msg, fault_msg_sz,
+			  "SysMMU %s %s from %s (secure) at %#010x",
+			  IS_READ_FAULT(info) ? "READ" : "WRITE",
+			  sysmmu_fault_name[intr_type],
+			  port_name ? port_name : dev_name(drvdata->dev),
+			  fault_addr);
+	} else {
+		info = readl_relaxed(MMU_VM_REG(drvdata, IDX_FAULT_TRANS_INFO, vid));
+		scnprintf(fault_msg, fault_msg_sz,
+			  "SysMMU %s %s from %s VID %u at %#010x",
+			  IS_READ_FAULT(info) ? "READ" : "WRITE",
+			  sysmmu_fault_name[intr_type],
+			  port_name ? port_name : dev_name(drvdata->dev), vid,
+			  fault_addr);
+	}
+}
+
+static void sysmmu_show_secure_fault_information(struct sysmmu_drvdata *drvdata,
+						 unsigned int intr_type, sysmmu_iova_t fault_addr)
+{
+	unsigned int info;
+	phys_addr_t pgtable;
+	unsigned int sfrbase = drvdata->secure_base;
+	char err_msg[128];
+
+	pgtable = read_sec_info(MMU_SEC_REG(drvdata, IDX_SEC_FLPT_BASE));
+	pgtable <<= PAGE_SHIFT;
+
+	info = read_sec_info(MMU_SEC_REG(drvdata, IDX_FAULT_TRANS_INFO));
+
+	pr_crit("----------------------------------------------------------\n");
+
+	sysmmu_get_fault_msg(drvdata, intr_type, 0, fault_addr,
+			     true, err_msg, sizeof(err_msg));
+
+	pr_crit("%s (pgtable @ %pa)\n", err_msg, &pgtable);
+
+	if (intr_type == SYSMMU_FAULT_UNKNOWN) {
+		pr_crit("The fault is not caused by this System MMU.\n");
+		pr_crit("Please check IRQ and SFR base address.\n");
+		goto finish;
+	}
+
+	pr_crit("AxID: %#x, AxLEN: %#x\n", info & 0xFFFF, (info >> 16) & 0xF);
+
+	if (!pfn_valid(pgtable >> PAGE_SHIFT)) {
+		pr_crit("Page table base is not in a valid memory region\n");
+		pgtable = 0;
+	}
+
+	if (intr_type == SYSMMU_FAULT_PTW_ACCESS) {
+		pr_crit("System MMU has failed to access page table\n");
+		pgtable = 0;
+	}
+
+	info = MMU_RAW_VER(read_sec_info(sfrbase + REG_MMU_VERSION));
+
+	pr_crit("ADDR: %#x, MMU_CTRL: %#010x, PT_BASE: %#010x\n",
+		sfrbase,
+		read_sec_info(sfrbase + REG_MMU_CTRL),
+		read_sec_info(MMU_SEC_REG(drvdata, IDX_SEC_FLPT_BASE)));
+	pr_crit("VERSION %d.%d.%d, MMU_CFG: %#010x, MMU_STATUS: %#010x\n",
+		MMU_MAJ_VER(info), MMU_MIN_VER(info), MMU_REV_VER(info),
+		read_sec_info(sfrbase + REG_MMU_CFG),
+		read_sec_info(sfrbase + REG_MMU_STATUS));
+
+finish:
+	pr_crit("----------------------------------------------------------\n");
+}
+
+static void sysmmu_show_fault_info_simple(struct sysmmu_drvdata *drvdata,
+					  unsigned int intr_type, unsigned int vid,
+					  sysmmu_iova_t fault_addr, phys_addr_t *pt)
+{
+	u32 info;
+	char err_msg[128];
+
+	info = readl_relaxed(MMU_VM_REG(drvdata, IDX_FAULT_TRANS_INFO, vid));
+
+	sysmmu_get_fault_msg(drvdata, intr_type, vid, fault_addr,
+			     false, err_msg, sizeof(err_msg));
+
+	pr_crit("%s (pgtable @ %pa, AxID: %#x)\n", err_msg, pt, info & 0xFFFF);
+}
+
+static void sysmmu_show_fault_information(struct sysmmu_drvdata *drvdata,
+					  unsigned int intr_type, unsigned int vid,
+					  sysmmu_iova_t fault_addr)
+{
+	unsigned int i;
+	phys_addr_t pgtable[MAX_VIDS];
+
+	for (i = 0; i < __max_vids(drvdata); i++) {
+		pgtable[i] = readl_relaxed(MMU_VM_REG(drvdata, IDX_FLPT_BASE, i));
+		pgtable[i] <<= PAGE_SHIFT;
+	}
+
+	pr_crit("----------------------------------------------------------\n");
+	sysmmu_show_fault_info_simple(drvdata, intr_type, vid, fault_addr, &pgtable[vid]);
+
+	if (intr_type == SYSMMU_FAULT_UNKNOWN) {
+		pr_crit("The fault is not caused by this System MMU.\n");
+		pr_crit("Please check IRQ and SFR base address.\n");
+		goto finish;
+	}
+
+	for (i = 0; i < __max_vids(drvdata); i++) {
+		if (pgtable[i] != drvdata->pgtable[i])
+			pr_crit("Page table (VID %u) base of driver: %pa\n", i,
+				&drvdata->pgtable[i]);
+		if (pgtable[i] && !pfn_valid(pgtable[i] >> PAGE_SHIFT)) {
+			pr_crit("Page table (VID %u) base is not in a valid memory region\n", i);
+			pgtable[i] = 0;
+		}
+	}
+
+	if (pgtable[vid]) {
+		sysmmu_pte_t *ent;
+
+		ent = section_entry(phys_to_virt(pgtable[vid]), fault_addr);
+		pr_crit("Lv1 entry: %#010x\n", *ent);
+
+		if (lv1ent_page(ent)) {
+			ent = page_entry(ent, fault_addr);
+			pr_crit("Lv2 entry: %#010x\n", *ent);
+		}
+	}
+
+	if (intr_type == SYSMMU_FAULT_PTW_ACCESS) {
+		pr_crit("System MMU has failed to access page table\n");
+		pgtable[vid] = 0;
+	}
+
+	dump_sysmmu_status(drvdata, pgtable, vid);
+finish:
+	pr_crit("----------------------------------------------------------\n");
+}
+
+static void sysmmu_get_interrupt_info(struct sysmmu_drvdata *data, unsigned int *intr_type,
+				      unsigned int *vid, sysmmu_iova_t *addr, bool is_secure)
+{
+	u32 istatus;
+
+	istatus = (unsigned int)__ffs(__sysmmu_get_intr_status(data, is_secure));
+	*vid = istatus / 4;
+	*intr_type = istatus % 4;
+	*addr = __sysmmu_get_fault_address(data, *vid, is_secure);
+}
+
+static int sysmmu_clear_interrupt(struct sysmmu_drvdata *data, bool is_secure)
+{
+	u32 val = __sysmmu_get_intr_status(data, is_secure);
+
+	if (is_secure) {
+		if (val & ~SYSMMU_SEC_FAULT_MASK) {
+			dev_warn(data->dev, "Unknown secure fault (%x)\n", val);
+			val &= SYSMMU_SEC_FAULT_MASK;
+		}
+		return clear_sec_fault(data->secure_base, val);
+	}
+	writel(val, data->sfrbase + REG_MMU_INT_CLEAR);
+	return 0;
+}
+
+irqreturn_t samsung_sysmmu_irq(int irq, void *dev_id)
+{
+	unsigned int itype;
+	unsigned int vid;
+	sysmmu_iova_t addr;
+	struct sysmmu_drvdata *drvdata = dev_id;
+	bool is_secure = (irq == drvdata->secure_irq);
+
+	if (drvdata->hide_page_fault)
+		return IRQ_WAKE_THREAD;
+
+	dev_info(drvdata->dev, "[%s] interrupt (%d) happened\n",
+		 is_secure ? "Secure" : "Non-secure", irq);
+
+	if (drvdata->async_fault_mode)
+		return IRQ_WAKE_THREAD;
+
+	sysmmu_get_interrupt_info(drvdata, &itype, &vid, &addr, is_secure);
+	if (is_secure)
+		sysmmu_show_secure_fault_information(drvdata, itype, addr);
+	else
+		sysmmu_show_fault_information(drvdata, itype, vid, addr);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static int samsung_sysmmu_fault_notifier(struct device *dev, void *data)
+{
+	struct samsung_sysmmu_fault_info *fi;
+	struct sysmmu_clientdata *client;
+	struct sysmmu_drvdata *drvdata;
+	unsigned int i;
+	int ret, result = 0;
+
+	fi = (struct samsung_sysmmu_fault_info *)data;
+	drvdata = fi->drvdata;
+
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+
+	for (i = 0; i < client->sysmmu_count; i++) {
+		if (drvdata == client->sysmmus[i]) {
+			ret = iommu_report_device_fault(dev, &fi->event);
+			if (ret == -EAGAIN)
+				result = ret;
+			break;
+		}
+	}
+
+	return result;
+}
+
+irqreturn_t samsung_sysmmu_irq_thread(int irq, void *dev_id)
+{
+	unsigned int itype, vid;
+	int ret;
+	sysmmu_iova_t addr;
+	struct sysmmu_drvdata *drvdata = dev_id;
+	bool is_secure = (irq == drvdata->secure_irq);
+	struct iommu_group *group = drvdata->group;
+	enum iommu_fault_reason reason;
+	struct samsung_sysmmu_fault_info fi = {
+		.drvdata = drvdata,
+		.event.fault.type = IOMMU_FAULT_DMA_UNRECOV,
+	};
+	char fault_msg[128] = "Unspecified SysMMU fault";
+
+	/* Prevent power down while handling faults */
+	pm_runtime_get_sync(drvdata->dev);
+
+	sysmmu_get_interrupt_info(drvdata, &itype, &vid, &addr, is_secure);
+	reason = sysmmu_fault_type[itype];
+
+	fi.event.fault.event.addr = addr;
+	fi.event.fault.event.pasid = vid;
+	if (vid)
+		fi.event.fault.event.flags |= IOMMU_FAULT_UNRECOV_PASID_VALID;
+	fi.event.fault.event.reason = reason;
+	if (reason == IOMMU_FAULT_REASON_PTE_FETCH ||
+	    reason == IOMMU_FAULT_REASON_PERMISSION)
+		fi.event.fault.type = IOMMU_FAULT_PAGE_REQ;
+
+	ret = iommu_group_for_each_dev(group, &fi,
+				       samsung_sysmmu_fault_notifier);
+	if (ret == -EAGAIN) {
+		if (is_secure) {
+			if (drvdata->async_fault_mode && !drvdata->hide_page_fault)
+				sysmmu_show_secure_fault_information(drvdata, itype, addr);
+			ret = sysmmu_clear_interrupt(drvdata, true);
+			if (ret) {
+				if (drvdata->hide_page_fault)
+					sysmmu_show_secure_fault_information(drvdata, itype, addr);
+				dev_err(drvdata->dev, "Failed to clear secure fault (%d)\n", ret);
+				goto out;
+			}
+		} else  {
+			phys_addr_t pgtable;
+
+			pgtable = readl_relaxed(MMU_VM_REG(drvdata, IDX_FLPT_BASE, vid));
+			pgtable <<= PAGE_SHIFT;
+			if (!drvdata->hide_page_fault)
+				sysmmu_show_fault_info_simple(drvdata, itype, vid, addr, &pgtable);
+			sysmmu_clear_interrupt(drvdata, false);
+		}
+		pm_runtime_put(drvdata->dev);
+		return IRQ_HANDLED;
+	}
+
+	if (drvdata->async_fault_mode || drvdata->hide_page_fault) {
+		if (is_secure)
+			sysmmu_show_secure_fault_information(drvdata, itype, addr);
+		else
+			sysmmu_show_fault_information(drvdata, itype, vid, addr);
+	}
+
+out:
+	sysmmu_get_fault_msg(drvdata, itype, vid, addr, is_secure, fault_msg, sizeof(fault_msg));
+
+	pm_runtime_put(drvdata->dev);
+
+	panic(fault_msg);
+
+	return IRQ_HANDLED;
+}
diff --git a/drivers/iommu/samsung-iommu-group.c b/drivers/iommu/samsung-iommu-group.c
new file mode 100644
index 000000000000..425a7345363c
--- /dev/null
+++ b/drivers/iommu/samsung-iommu-group.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ */
+
+#include <linux/iommu.h>
+#include <linux/kmemleak.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+static int sysmmu_group_device_probe(struct platform_device *pdev)
+{
+	struct iommu_group *data;
+	struct device *dev = &pdev->dev;
+
+	data = iommu_group_alloc();
+	if (IS_ERR(data)) {
+		dev_err(dev, "Failed to alloc group, ret:%d\n", (int)PTR_ERR(data));
+		return PTR_ERR(data);
+	}
+
+	platform_set_drvdata(pdev, data);
+	iommu_group_set_name(data, dev->of_node->name);
+
+	dev_dbg(dev, "Initialized IOMMU group[%s]\n", dev->of_node->name);
+
+	return 0;
+}
+
+static void sysmmu_group_device_shutdown(struct platform_device *pdev)
+{
+}
+
+static const struct of_device_id sysmmu_group_of_match[] = {
+	{ .compatible = "samsung,sysmmu-group" },
+	{ }
+};
+
+static struct platform_driver sysmmu_group_driver = {
+	.driver	= {
+		.name			= "sysmmu-group",
+		.of_match_table		= of_match_ptr(sysmmu_group_of_match),
+		.suppress_bind_attrs	= true,
+	},
+	.probe = sysmmu_group_device_probe,
+	.shutdown = sysmmu_group_device_shutdown,
+};
+module_platform_driver(sysmmu_group_driver);
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/samsung-iommu.c b/drivers/iommu/samsung-iommu.c
new file mode 100644
index 000000000000..e66da74167b9
--- /dev/null
+++ b/drivers/iommu/samsung-iommu.c
@@ -0,0 +1,1521 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ */
+
+#define pr_fmt(fmt) "sysmmu: " fmt
+
+#include <linux/dma-iommu.h>
+#include <linux/kmemleak.h>
+#include <linux/module.h>
+#include <linux/of_iommu.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "samsung-iommu.h"
+
+#define FLPD_SHAREABLE_FLAG	BIT(6)
+#define SLPD_SHAREABLE_FLAG	BIT(4)
+
+#define MMU_TLB_CFG_MASK(reg)		((reg) & (GENMASK(7, 5) | GENMASK(3, 2) | GENMASK(1, 1)))
+#define MMU_TLB_MATCH_CFG_MASK(reg)	((reg) & (GENMASK(31, 16) | GENMASK(9, 8)))
+
+#define REG_MMU_TLB_CFG(n)		(0x2000 + ((n) * 0x20) + 0x4)
+#define REG_MMU_TLB_MATCH_CFG(n)	(0x2000 + ((n) * 0x20) + 0x8)
+#define REG_MMU_TLB_MATCH_ID(n)		(0x2000 + ((n) * 0x20) + 0x14)
+
+#define DEFAULT_QOS_VALUE	-1
+#define DEFAULT_TLB_NONE	~0U
+#define UNUSED_TLB_INDEX	~0U
+
+#define REG_MMU_S2PF_ENABLE	0x7000
+#define MMU_S2PF_ENABLE		BIT(0)
+
+static const unsigned int sysmmu_reg_set[MAX_SET_IDX][MAX_REG_IDX] = {
+	/* Default without VM */
+	{
+		/*
+		 * SysMMUs without VM support do not have the two registers CTRL_VM and CFG_VM.
+		 * Setting the offsets to 1 will trigger an unaligned access exception.
+		 */
+		0x1,	0x1,
+		/* FLPT base, TLB invalidation, Fault information */
+		0x000C,	0x0010,	0x0014,	0x0018,
+		0x0020,	0x0024,	0x0070,	0x0078,
+		/* TLB information */
+		0x8000,	0x8004,	0x8008,	0x800C,
+		/* SBB information */
+		0x8020,	0x8024,	0x8028,	0x802C,
+		/* secure FLPT base (same as non-secure) */
+		0x000C,
+	},
+	/* VM */
+	{
+		/* CTRL_VM, CFG_VM */
+		0x8000,	0x8004,
+		/* FLPT base, TLB invalidation, Fault information */
+		0x800C,	0x8010,	0x8014,	0x8018,
+		0x8020,	0x8024,	0x1000,	0x1004,
+		/* TLB information */
+		0x3000,	0x3004,	0x3008,	0x300C,
+		/* SBB information */
+		0x3020,	0x3024,	0x3028,	0x302C,
+		/* secure FLPT base */
+		0x000C,
+	},
+};
+
+static struct iommu_ops samsung_sysmmu_ops;
+static struct platform_driver samsung_sysmmu_driver;
+
+struct samsung_sysmmu_domain {
+	struct iommu_domain domain;
+	struct iommu_group *group;
+	struct sysmmu_drvdata *vm_sysmmu; /* valid only if vid != 0 */
+	/* if vid != 0, domain is aux domain attached to only one device and sysmmu */
+	unsigned int vid;
+	sysmmu_pte_t *page_table;
+	atomic_t *lv2entcnt;
+	spinlock_t pgtablelock; /* serialize races to page table updates */
+};
+
+static bool sysmmu_global_init_done;
+static struct device sync_dev;
+static struct kmem_cache *flpt_cache, *slpt_cache;
+
+static inline u32 __sysmmu_get_tlb_num(struct sysmmu_drvdata *data)
+{
+	return MMU_CAPA1_NUM_TLB(readl_relaxed(data->sfrbase +
+					       REG_MMU_CAPA1_V7));
+}
+
+static inline u32 __sysmmu_get_hw_version(struct sysmmu_drvdata *data)
+{
+	return MMU_RAW_VER(readl_relaxed(data->sfrbase + REG_MMU_VERSION));
+}
+
+static inline bool __sysmmu_has_capa1(struct sysmmu_drvdata *data)
+{
+	return MMU_CAPA1_EXIST(readl_relaxed(data->sfrbase + REG_MMU_CAPA0_V7));
+}
+
+static inline u32 __sysmmu_get_capa_type(struct sysmmu_drvdata *data)
+{
+	return MMU_CAPA1_TYPE(readl_relaxed(data->sfrbase + REG_MMU_CAPA1_V7));
+}
+
+static inline bool __sysmmu_get_capa_no_block_mode(struct sysmmu_drvdata *data)
+{
+	return MMU_CAPA1_NO_BLOCK_MODE(readl_relaxed(data->sfrbase +
+						     REG_MMU_CAPA1_V7));
+}
+
+static inline bool __sysmmu_get_capa_vcr_enabled(struct sysmmu_drvdata *data)
+{
+	return MMU_CAPA1_VCR_ENABLED(readl_relaxed(data->sfrbase +
+						   REG_MMU_CAPA1_V7));
+}
+
+static inline void __sysmmu_tlb_invalidate_all(struct sysmmu_drvdata *data, unsigned int vid)
+{
+	writel(0x1, MMU_VM_REG(data, IDX_ALL_INV, vid));
+}
+
+static inline void __sysmmu_tlb_invalidate(struct sysmmu_drvdata *data, unsigned int vid,
+					   dma_addr_t start, dma_addr_t end)
+{
+	writel_relaxed(ALIGN_DOWN(start, SPAGE_SIZE), MMU_VM_REG(data, IDX_RANGE_INV_START, vid));
+	writel_relaxed(ALIGN_DOWN(end, SPAGE_SIZE), MMU_VM_REG(data, IDX_RANGE_INV_END, vid));
+	writel(0x1, MMU_VM_REG(data, IDX_RANGE_INV, vid));
+}
+
+static inline void __sysmmu_disable_vid(struct sysmmu_drvdata *data, unsigned int vid)
+{
+	u32 ctrl_val = readl_relaxed(MMU_VM_REG(data, IDX_CTRL_VM, vid));
+
+	ctrl_val &= ~CTRL_VID_ENABLE;
+	writel(ctrl_val, MMU_VM_REG(data, IDX_CTRL_VM, vid));
+	__sysmmu_tlb_invalidate_all(data, vid);
+	writel_relaxed(0, MMU_VM_REG(data, IDX_FLPT_BASE, vid));
+}
+
+static inline void __sysmmu_disable(struct sysmmu_drvdata *data)
+{
+	if (data->no_block_mode) {
+		__sysmmu_tlb_invalidate_all(data, 0);
+	} else {
+		u32 ctrl_val = readl_relaxed(data->sfrbase + REG_MMU_CTRL);
+
+		ctrl_val &= ~CTRL_MMU_ENABLE;
+		writel(ctrl_val | CTRL_MMU_BLOCK, data->sfrbase + REG_MMU_CTRL);
+	}
+}
+
+static inline void __sysmmu_set_tlb(struct sysmmu_drvdata *data)
+{
+	struct tlb_props *tlb_props = &data->tlb_props;
+	struct tlb_config *cfg = tlb_props->cfg;
+	int id_cnt = tlb_props->id_cnt;
+	int i;
+	unsigned int index;
+
+	if (tlb_props->default_cfg != DEFAULT_TLB_NONE)
+		writel_relaxed(MMU_TLB_CFG_MASK(tlb_props->default_cfg),
+			       data->sfrbase + REG_MMU_TLB_CFG(0));
+
+	for (i = 0; i < id_cnt; i++) {
+		if (cfg[i].index == UNUSED_TLB_INDEX)
+			continue;
+
+		index = cfg[i].index;
+		writel_relaxed(MMU_TLB_CFG_MASK(cfg[i].cfg),
+			       data->sfrbase + REG_MMU_TLB_CFG(index));
+		writel_relaxed(MMU_TLB_MATCH_CFG_MASK(cfg[i].match_cfg),
+			       data->sfrbase + REG_MMU_TLB_MATCH_CFG(index));
+		writel_relaxed(cfg[i].match_id,
+			       data->sfrbase + REG_MMU_TLB_MATCH_ID(index));
+	}
+}
+
+static inline void __sysmmu_init_config(struct sysmmu_drvdata *data)
+{
+	u32 cfg = readl_relaxed(data->sfrbase + REG_MMU_CFG);
+
+	if (data->qos != DEFAULT_QOS_VALUE) {
+		cfg &= ~CFG_QOS(0xF);
+		cfg |= CFG_QOS_OVRRIDE | CFG_QOS((u32)data->qos);
+	}
+
+	if (data->no_s2pf) {
+		u32 val = readl_relaxed(data->sfrbase + REG_MMU_S2PF_ENABLE);
+
+		writel_relaxed(val & ~MMU_S2PF_ENABLE, data->sfrbase + REG_MMU_S2PF_ENABLE);
+	}
+
+	__sysmmu_set_tlb(data);
+
+	writel_relaxed(cfg, data->sfrbase + REG_MMU_CFG);
+}
+
+static inline void __sysmmu_enable_vid(struct sysmmu_drvdata *data, unsigned int vid)
+{
+	u32 ctrl_val;
+
+	writel_relaxed(data->pgtable[vid] / SPAGE_SIZE, MMU_VM_REG(data, IDX_FLPT_BASE, vid));
+
+	__sysmmu_tlb_invalidate_all(data, vid);
+
+	ctrl_val = readl_relaxed(MMU_VM_REG(data, IDX_CTRL_VM, vid));
+	if (!data->async_fault_mode)
+		ctrl_val |= CTRL_FAULT_STALL_MODE;
+	else
+		ctrl_val &= ~CTRL_FAULT_STALL_MODE;
+	writel(ctrl_val | CTRL_VID_ENABLE, MMU_VM_REG(data, IDX_CTRL_VM, vid));
+}
+
+static inline void __sysmmu_enable(struct sysmmu_drvdata *data)
+{
+	unsigned int vid;
+	u32 ctrl_val = readl_relaxed(data->sfrbase + REG_MMU_CTRL);
+
+	if (!data->no_block_mode)
+		writel_relaxed(ctrl_val | CTRL_MMU_BLOCK, data->sfrbase + REG_MMU_CTRL);
+
+	__sysmmu_init_config(data);
+
+	for (vid = 0; vid < __max_vids(data); vid++)
+		if (data->pgtable[vid])
+			__sysmmu_enable_vid(data, vid);
+
+	writel(ctrl_val | CTRL_MMU_ENABLE, data->sfrbase + REG_MMU_CTRL);
+}
+
+static struct samsung_sysmmu_domain *to_sysmmu_domain(struct iommu_domain *dom)
+{
+	return container_of(dom, struct samsung_sysmmu_domain, domain);
+}
+
+static inline void pgtable_flush(void *vastart, void *vaend)
+{
+	dma_sync_single_for_device(&sync_dev, virt_to_phys(vastart),
+				   (size_t)(vaend - vastart), DMA_TO_DEVICE);
+}
+
+static bool samsung_sysmmu_capable(enum iommu_cap cap)
+{
+	return cap == IOMMU_CAP_CACHE_COHERENCY;
+}
+
+static struct iommu_domain *samsung_sysmmu_domain_alloc(unsigned int type)
+{
+	struct samsung_sysmmu_domain *domain;
+
+	if (type != IOMMU_DOMAIN_UNMANAGED &&
+	    type != IOMMU_DOMAIN_DMA &&
+	    type != IOMMU_DOMAIN_IDENTITY) {
+		pr_err("invalid domain type %u\n", type);
+		return NULL;
+	}
+
+	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+	if (!domain)
+		return NULL;
+
+	domain->page_table =
+		(sysmmu_pte_t *)kmem_cache_alloc(flpt_cache,
+						 GFP_KERNEL | __GFP_ZERO);
+	if (!domain->page_table)
+		goto err_pgtable;
+
+	domain->lv2entcnt = kcalloc(NUM_LV1ENTRIES, sizeof(*domain->lv2entcnt),
+				    GFP_KERNEL);
+	if (!domain->lv2entcnt)
+		goto err_counter;
+
+	pgtable_flush(domain->page_table, domain->page_table + NUM_LV1ENTRIES);
+
+	spin_lock_init(&domain->pgtablelock);
+
+	return &domain->domain;
+
+err_counter:
+	kmem_cache_free(flpt_cache, domain->page_table);
+err_pgtable:
+	kfree(domain);
+	return NULL;
+}
+
+static void samsung_sysmmu_domain_free(struct iommu_domain *dom)
+{
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+
+	kmem_cache_free(flpt_cache, domain->page_table);
+	kfree(domain->lv2entcnt);
+	kfree(domain);
+}
+
+static inline void samsung_sysmmu_detach_drvdata(struct sysmmu_drvdata *data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&data->lock, flags);
+	if (--data->attached_count == 0) {
+		if (pm_runtime_active(data->dev))
+			__sysmmu_disable(data);
+
+		list_del(&data->list);
+		data->pgtable[0] = 0;
+		data->group = NULL;
+	}
+	spin_unlock_irqrestore(&data->lock, flags);
+}
+
+/* TODO: Since upstream has removed of_get_dma_window() we'll temporarily
+ * open code relevant portion here, until we can come up with a generic
+ * enough implementation that can be proposed upstream for these drivers.
+ */
+static int samsung_sysmmu_get_dma_window(struct device_node *dn,
+					 dma_addr_t *addr, size_t *size)
+{
+	const __be32 *dma_window, *prop;
+	u32 cells;
+
+	dma_window = of_get_property(dn, "dma-window", NULL);
+	if (!dma_window)
+		return -ENODEV;
+
+	prop = of_get_property(dn, "#dma-address-cells", NULL);
+	cells = prop ? be32_to_cpup(prop) : of_n_addr_cells(dn);
+	if (!cells)
+		return -EINVAL;
+	*addr = of_read_number(dma_window, cells);
+	dma_window += cells;
+
+	prop = of_get_property(dn, "#dma-size-cells", NULL);
+	cells = prop ? be32_to_cpup(prop) : of_n_size_cells(dn);
+	if (!cells)
+		return -EINVAL;
+	*size = of_read_number(dma_window, cells);
+
+	return 0;
+}
+
+static int samsung_sysmmu_set_domain_range(struct iommu_domain *dom,
+					   struct device *dev)
+{
+	struct iommu_domain_geometry *geom = &dom->geometry;
+	dma_addr_t start, end;
+	size_t size;
+
+	if (samsung_sysmmu_get_dma_window(dev->of_node, &start, &size))
+		return 0;
+
+	end = start + size;
+
+	if (end > DMA_BIT_MASK(32))
+		end = DMA_BIT_MASK(32);
+
+	if (geom->force_aperture) {
+		dma_addr_t d_start, d_end;
+
+		d_start = max(start, geom->aperture_start);
+		d_end = min(end, geom->aperture_end);
+
+		if (d_start >= d_end) {
+			dev_err(dev, "current range is [%pad..%pad]\n",
+				&geom->aperture_start, &geom->aperture_end);
+			dev_err(dev, "requested range [%zx @ %pad] is not allowed\n",
+				size, &start);
+			return -ERANGE;
+		}
+
+		geom->aperture_start = d_start;
+		geom->aperture_end = d_end;
+	} else {
+		geom->aperture_start = start;
+		geom->aperture_end = end;
+		/*
+		 * All CPUs should observe the change of force_aperture after
+		 * updating aperture_start and aperture_end because dma-iommu
+		 * restricts dma virtual memory by this aperture when
+		 * force_aperture is set.
+		 * We allow allocating dma virtual memory during changing the
+		 * aperture range because the current allocation is free from
+		 * the new restricted range.
+		 */
+		smp_wmb();
+		geom->force_aperture = true;
+	}
+
+	dev_info(dev, "changed DMA range [%pad..%pad] successfully.\n",
+		 &geom->aperture_start, &geom->aperture_end);
+
+	return 0;
+}
+
+static struct samsung_sysmmu_domain *attach_helper(struct iommu_domain *dom, struct device *dev)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct samsung_sysmmu_domain *domain;
+
+	if (!fwspec || fwspec->ops != &samsung_sysmmu_ops) {
+		dev_err(dev, "failed to attach, IOMMU instance data %s.\n",
+			!fwspec ? "is not initialized" : "has different ops");
+		return ERR_PTR(-ENXIO);
+	}
+
+	if (!dev_iommu_priv_get(dev)) {
+		dev_err(dev, "has no IOMMU\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	domain = to_sysmmu_domain(dom);
+	if (domain->vm_sysmmu) {
+		dev_err(dev, "IOMMU domain is already used as AUX domain\n");
+		return ERR_PTR(-EBUSY);
+	}
+
+	return domain;
+}
+
+static int samsung_sysmmu_attach_dev(struct iommu_domain *dom,
+				     struct device *dev)
+{
+	struct sysmmu_clientdata *client;
+	struct samsung_sysmmu_domain *domain;
+	struct list_head *group_list;
+	struct sysmmu_drvdata *drvdata;
+	struct iommu_group *group = dev->iommu_group;
+	unsigned long flags;
+	phys_addr_t page_table;
+	int i, ret = -EINVAL;
+
+	domain = attach_helper(dom, dev);
+	if (IS_ERR(domain))
+		return (int)PTR_ERR(domain);
+
+	domain->group = group;
+	group_list = iommu_group_get_iommudata(group);
+	page_table = virt_to_phys(domain->page_table);
+
+	client = dev_iommu_priv_get(dev);
+	for (i = 0; i < (int)client->sysmmu_count; i++) {
+		drvdata = client->sysmmus[i];
+
+		spin_lock_irqsave(&drvdata->lock, flags);
+		if (drvdata->attached_count++ == 0) {
+			list_add(&drvdata->list, group_list);
+			drvdata->group = group;
+			drvdata->pgtable[0] = page_table;
+
+			if (pm_runtime_active(drvdata->dev))
+				__sysmmu_enable(drvdata);
+		} else if (drvdata->pgtable[0] != page_table) {
+			dev_err(dev, "%s is already attached to other domain\n",
+				dev_name(drvdata->dev));
+			spin_unlock_irqrestore(&drvdata->lock, flags);
+			goto err_drvdata_add;
+		}
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+	}
+
+	ret = samsung_sysmmu_set_domain_range(dom, dev);
+	if (ret)
+		goto err_drvdata_add;
+
+	dev_info(dev, "attached with pgtable %pa\n", &domain->page_table);
+
+	return 0;
+
+err_drvdata_add:
+	while (i-- > 0) {
+		drvdata = client->sysmmus[i];
+
+		samsung_sysmmu_detach_drvdata(drvdata);
+	}
+
+	return ret;
+}
+
+static void samsung_sysmmu_detach_dev(struct iommu_domain *dom,
+				      struct device *dev)
+{
+	struct sysmmu_clientdata *client;
+	struct samsung_sysmmu_domain *domain;
+	struct list_head *group_list;
+	struct sysmmu_drvdata *drvdata;
+	struct iommu_group *group = dev->iommu_group;
+	unsigned int i;
+
+	domain = to_sysmmu_domain(dom);
+	group_list = iommu_group_get_iommudata(group);
+
+	client = dev_iommu_priv_get(dev);
+	for (i = 0; i < client->sysmmu_count; i++) {
+		drvdata = client->sysmmus[i];
+
+		samsung_sysmmu_detach_drvdata(drvdata);
+	}
+
+	dev_info(dev, "detached from pgtable %pa\n", &domain->page_table);
+}
+
+static inline sysmmu_pte_t make_sysmmu_pte(phys_addr_t paddr,
+					   unsigned int pgsize, unsigned int attr)
+{
+	return ((sysmmu_pte_t)((paddr) >> PG_ENT_SHIFT)) | pgsize | attr;
+}
+
+static sysmmu_pte_t *alloc_lv2entry(struct samsung_sysmmu_domain *domain,
+				    sysmmu_pte_t *sent, sysmmu_iova_t iova,
+				    atomic_t *pgcounter)
+{
+	if (lv1ent_section(sent)) {
+		WARN(1, "trying mapping on %#08x mapped with 1MiB page", iova);
+		return ERR_PTR(-EADDRINUSE);
+	}
+
+	if (lv1ent_unmapped(sent)) {
+		unsigned long flags;
+		sysmmu_pte_t *pent;
+
+		pent = kmem_cache_zalloc(slpt_cache, GFP_KERNEL);
+		if (!pent)
+			return ERR_PTR(-ENOMEM);
+
+		spin_lock_irqsave(&domain->pgtablelock, flags);
+		if (lv1ent_unmapped(sent)) {
+			*sent = make_sysmmu_pte(virt_to_phys(pent),
+						SLPD_FLAG, 0);
+			kmemleak_ignore(pent);
+			atomic_set(pgcounter, 0);
+			pgtable_flush(pent, pent + NUM_LV2ENTRIES);
+			pgtable_flush(sent, sent + 1);
+		} else {
+			/* allocated entry is not used, so free it. */
+			kmem_cache_free(slpt_cache, pent);
+		}
+		spin_unlock_irqrestore(&domain->pgtablelock, flags);
+	}
+
+	return page_entry(sent, iova);
+}
+
+static inline void clear_lv2_page_table(sysmmu_pte_t *ent, unsigned int n)
+{
+	memset(ent, 0, sizeof(*ent) * n);
+}
+
+static int lv1set_section(struct samsung_sysmmu_domain *domain,
+			  sysmmu_pte_t *sent, sysmmu_iova_t iova,
+			  phys_addr_t paddr, int prot, atomic_t *pgcnt)
+{
+	unsigned int attr = !!(prot & IOMMU_CACHE) ? FLPD_SHAREABLE_FLAG : 0;
+	sysmmu_pte_t *pent_to_free = NULL;
+
+	if (lv1ent_section(sent)) {
+		WARN(1, "Trying mapping 1MB@%#08x on valid FLPD", iova);
+		return -EADDRINUSE;
+	}
+
+	if (lv1ent_page(sent)) {
+		if (WARN_ON(atomic_read(pgcnt) != 0)) {
+			WARN(1, "Trying mapping 1MB@%#08x on valid SLPD", iova);
+			return -EADDRINUSE;
+		}
+
+		pent_to_free = page_entry(sent, 0);
+		atomic_set(pgcnt, NUM_LV2ENTRIES);
+	}
+
+	*sent = make_sysmmu_pte(paddr, SECT_FLAG, attr);
+	pgtable_flush(sent, sent + 1);
+
+	if (pent_to_free) {
+		struct iommu_iotlb_gather gather = {
+			.start = iova,
+			.end = iova + SECT_SIZE - 1,
+		};
+
+		iommu_iotlb_sync(&domain->domain, &gather);
+		kmem_cache_free(slpt_cache, pent_to_free);
+	}
+
+	return 0;
+}
+
+static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr,
+		       size_t size, int prot, atomic_t *pgcnt)
+{
+	unsigned int attr = !!(prot & IOMMU_CACHE) ? SLPD_SHAREABLE_FLAG : 0;
+
+	if (size == SPAGE_SIZE) {
+		if (WARN_ON(!lv2ent_unmapped(pent)))
+			return -EADDRINUSE;
+
+		*pent = make_sysmmu_pte(paddr, SPAGE_FLAG, attr);
+		pgtable_flush(pent, pent + 1);
+		atomic_inc(pgcnt);
+	} else {	/* size == LPAGE_SIZE */
+		unsigned int i;
+
+		for (i = 0; i < SPAGES_PER_LPAGE; i++, pent++) {
+			if (WARN_ON(!lv2ent_unmapped(pent))) {
+				clear_lv2_page_table(pent - i, i);
+				return -EADDRINUSE;
+			}
+
+			*pent = make_sysmmu_pte(paddr, LPAGE_FLAG, attr);
+		}
+		pgtable_flush(pent - SPAGES_PER_LPAGE, pent);
+		atomic_add(SPAGES_PER_LPAGE, pgcnt);
+	}
+
+	return 0;
+}
+
+static int samsung_sysmmu_map(struct iommu_domain *dom, unsigned long l_iova,
+			      phys_addr_t paddr, size_t size, int prot,
+			      gfp_t unused)
+{
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
+	atomic_t *lv2entcnt = &domain->lv2entcnt[lv1ent_offset(iova)];
+	sysmmu_pte_t *entry;
+	int ret = -ENOMEM;
+
+	/* Do not use IO coherency if iOMMU_PRIV exists */
+	if (!!(prot & IOMMU_PRIV))
+		prot &= ~IOMMU_CACHE;
+
+	entry = section_entry(domain->page_table, iova);
+
+	if (size == SECT_SIZE) {
+		ret = lv1set_section(domain, entry, iova, paddr, prot,
+				     lv2entcnt);
+	} else {
+		sysmmu_pte_t *pent;
+
+		pent = alloc_lv2entry(domain, entry, iova, lv2entcnt);
+
+		if (IS_ERR(pent))
+			ret = PTR_ERR(pent);
+		else
+			ret = lv2set_page(pent, paddr, size, prot, lv2entcnt);
+	}
+
+	if (ret)
+		pr_err("failed to map %#zx @ %#x, ret:%d\n", size, iova, ret);
+
+	return ret;
+}
+
+static size_t samsung_sysmmu_unmap(struct iommu_domain *dom,
+				   unsigned long l_iova, size_t size,
+				   struct iommu_iotlb_gather *gather)
+{
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+	sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
+	atomic_t *lv2entcnt = &domain->lv2entcnt[lv1ent_offset(iova)];
+	sysmmu_pte_t *sent, *pent;
+	size_t err_pgsize;
+
+	sent = section_entry(domain->page_table, iova);
+
+	if (lv1ent_section(sent)) {
+		if (WARN_ON(size < SECT_SIZE)) {
+			err_pgsize = SECT_SIZE;
+			goto err;
+		}
+
+		*sent = 0;
+		pgtable_flush(sent, sent + 1);
+		size = SECT_SIZE;
+		goto done;
+	}
+
+	if (unlikely(lv1ent_unmapped(sent))) {
+		if (size > SECT_SIZE)
+			size = SECT_SIZE;
+		goto done;
+	}
+
+	/* lv1ent_page(sent) == true here */
+
+	pent = page_entry(sent, iova);
+
+	if (unlikely(lv2ent_unmapped(pent))) {
+		size = SPAGE_SIZE;
+		goto done;
+	}
+
+	if (lv2ent_small(pent)) {
+		*pent = 0;
+		size = SPAGE_SIZE;
+		pgtable_flush(pent, pent + 1);
+		atomic_dec(lv2entcnt);
+		goto done;
+	}
+
+	/* lv1ent_large(pent) == true here */
+	if (WARN_ON(size < LPAGE_SIZE)) {
+		err_pgsize = LPAGE_SIZE;
+		goto err;
+	}
+
+	clear_lv2_page_table(pent, SPAGES_PER_LPAGE);
+	pgtable_flush(pent, pent + SPAGES_PER_LPAGE);
+	size = LPAGE_SIZE;
+	atomic_sub(SPAGES_PER_LPAGE, lv2entcnt);
+
+done:
+	iommu_iotlb_gather_add_page(dom, gather, iova, size);
+
+	return size;
+
+err:
+	pr_err("failed: size(%#zx) @ %#x is smaller than page size %#zx\n",
+	       size, iova, err_pgsize);
+
+	return 0;
+}
+
+static void samsung_sysmmu_flush_iotlb_all(struct iommu_domain *dom)
+{
+	unsigned long flags;
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+	struct sysmmu_drvdata *drvdata;
+
+	if (domain->vm_sysmmu) {
+		/* Domain is used as AUX domain */
+		drvdata = domain->vm_sysmmu;
+		spin_lock_irqsave(&drvdata->lock, flags);
+		if (drvdata->attached_count && drvdata->rpm_resume)
+			__sysmmu_tlb_invalidate_all(drvdata, domain->vid);
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+	} else if (domain->group) {
+		/* Domain is used as regular domain */
+		/*
+		 * domain->group might be NULL if flush_iotlb_all is called
+		 * before attach_dev. Just ignore it.
+		 */
+		struct list_head *sysmmu_list = iommu_group_get_iommudata(domain->group);
+
+		list_for_each_entry(drvdata, sysmmu_list, list) {
+			spin_lock_irqsave(&drvdata->lock, flags);
+			if (drvdata->attached_count && drvdata->rpm_resume)
+				__sysmmu_tlb_invalidate_all(drvdata, 0);
+			spin_unlock_irqrestore(&drvdata->lock, flags);
+		}
+	}
+}
+
+static void samsung_sysmmu_iotlb_sync(struct iommu_domain *dom,
+				      struct iommu_iotlb_gather *gather)
+{
+	unsigned long flags;
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+	struct sysmmu_drvdata *drvdata;
+
+	if (domain->vm_sysmmu) {
+		/* Domain is used as AUX domain */
+		drvdata = domain->vm_sysmmu;
+		spin_lock_irqsave(&drvdata->lock, flags);
+		if (drvdata->attached_count && drvdata->rpm_resume)
+			__sysmmu_tlb_invalidate(drvdata, domain->vid, gather->start, gather->end);
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+	} else if (domain->group) {
+		/* Domain is used as regular domain */
+		/*
+		 * domain->group might be NULL if iotlb_sync is called
+		 * before attach_dev. Just ignore it.
+		 */
+		struct list_head *sysmmu_list = iommu_group_get_iommudata(domain->group);
+
+		list_for_each_entry(drvdata, sysmmu_list, list) {
+			spin_lock_irqsave(&drvdata->lock, flags);
+			if (drvdata->attached_count && drvdata->rpm_resume)
+				__sysmmu_tlb_invalidate(drvdata, 0, gather->start, gather->end);
+			spin_unlock_irqrestore(&drvdata->lock, flags);
+		}
+	}
+}
+
+static phys_addr_t samsung_sysmmu_iova_to_phys(struct iommu_domain *dom,
+					       dma_addr_t d_iova)
+{
+	struct samsung_sysmmu_domain *domain = to_sysmmu_domain(dom);
+	sysmmu_iova_t iova = (sysmmu_iova_t)d_iova;
+	sysmmu_pte_t *entry;
+	phys_addr_t phys = 0;
+
+	entry = section_entry(domain->page_table, iova);
+
+	if (lv1ent_section(entry)) {
+		phys = section_phys(entry) + section_offs(iova);
+	} else if (lv1ent_page(entry)) {
+		entry = page_entry(entry, iova);
+
+		if (lv2ent_large(entry))
+			phys = lpage_phys(entry) + lpage_offs(iova);
+		else if (lv2ent_small(entry))
+			phys = spage_phys(entry) + spage_offs(iova);
+	}
+
+	return phys;
+}
+
+static struct iommu_device *samsung_sysmmu_probe_device(struct device *dev)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct sysmmu_clientdata *client;
+	int i;
+
+	if (!fwspec) {
+		dev_dbg(dev, "IOMMU instance data is not initialized\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (fwspec->ops != &samsung_sysmmu_ops) {
+		dev_err(dev, "has different IOMMU ops\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+	client->dev_link = kcalloc(client->sysmmu_count,
+				   sizeof(*client->dev_link), GFP_KERNEL);
+	if (!client->dev_link)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < (int)client->sysmmu_count; i++) {
+		client->dev_link[i] =
+			device_link_add(dev, client->sysmmus[i]->dev,
+					DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+		if (!client->dev_link[i]) {
+			dev_err(dev, "failed to add device link of %s\n",
+				dev_name(client->sysmmus[i]->dev));
+			while (i-- > 0)
+				device_link_del(client->dev_link[i]);
+			return ERR_PTR(-EINVAL);
+		}
+		dev_dbg(dev, "device link to %s\n",
+			dev_name(client->sysmmus[i]->dev));
+	}
+
+	return &client->sysmmus[0]->iommu;
+}
+
+static void samsung_sysmmu_release_device(struct device *dev)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct sysmmu_clientdata *client;
+	unsigned int i;
+
+	if (!fwspec || fwspec->ops != &samsung_sysmmu_ops)
+		return;
+
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+	for (i = 0; i < client->sysmmu_count; i++)
+		device_link_del(client->dev_link[i]);
+	kfree(client->dev_link);
+
+	iommu_fwspec_free(dev);
+}
+
+static void samsung_sysmmu_group_data_release(void *iommu_data)
+{
+	kfree(iommu_data);
+}
+
+static struct iommu_group *samsung_sysmmu_device_group(struct device *dev)
+{
+	struct iommu_group *group;
+	struct device_node *np;
+	struct platform_device *pdev;
+	struct list_head *list;
+	bool need_unmanaged_domain = false;
+
+	if (device_iommu_mapped(dev))
+		return iommu_group_get(dev);
+
+	np = of_parse_phandle(dev->of_node, "samsung,iommu-group", 0);
+	if (!np) {
+		dev_err(dev, "group is not registered\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev) {
+		dev_err(dev, "no device in device_node[%s]\n", np->name);
+		of_node_put(np);
+		return ERR_PTR(-ENODEV);
+	}
+
+	if (of_property_read_bool(np, "samsung,unmanaged-domain"))
+		need_unmanaged_domain = true;
+
+	of_node_put(np);
+
+	group = platform_get_drvdata(pdev);
+	if (!group) {
+		dev_err(dev, "no group in device_node[%s]\n", np->name);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	if (iommu_group_get_iommudata(group))
+		return group;
+
+	list = kzalloc(sizeof(*list), GFP_KERNEL);
+	if (!list)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(list);
+	iommu_group_set_iommudata(group, list,
+				  samsung_sysmmu_group_data_release);
+
+	if (need_unmanaged_domain) {
+		int ret;
+		struct iommu_domain *domain =
+				iommu_domain_alloc(&platform_bus_type);
+
+		ret = iommu_attach_group(domain, group);
+		if (ret) {
+			dev_err(dev, "failed to attach group, ret:%d\n", ret);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return group;
+}
+
+static void samsung_sysmmu_clientdata_release(struct device *dev, void *res)
+{
+	struct sysmmu_clientdata *client = res;
+
+	kfree(client->sysmmus);
+}
+
+static int samsung_sysmmu_of_xlate(struct device *dev,
+				   struct of_phandle_args *args)
+{
+	struct platform_device *sysmmu = of_find_device_by_node(args->np);
+	struct sysmmu_drvdata *data = platform_get_drvdata(sysmmu);
+	struct sysmmu_drvdata **new_link;
+	struct sysmmu_clientdata *client;
+	struct iommu_fwspec *fwspec;
+	unsigned int fwid = 0;
+	int ret;
+
+	ret = iommu_fwspec_add_ids(dev, &fwid, 1);
+	if (ret) {
+		dev_err(dev, "failed to add fwspec. (err:%d)\n", ret);
+		iommu_device_unlink(&data->iommu, dev);
+		return ret;
+	}
+
+	fwspec = dev_iommu_fwspec_get(dev);
+	if (!dev_iommu_priv_get(dev)) {
+		client = devres_alloc(samsung_sysmmu_clientdata_release,
+				      sizeof(*client), GFP_KERNEL);
+		if (!client)
+			return -ENOMEM;
+		dev_iommu_priv_set(dev, client);
+		devres_add(&sysmmu->dev, client);
+	}
+
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+	new_link = krealloc(client->sysmmus,
+			    sizeof(data) * (client->sysmmu_count + 1),
+			    GFP_KERNEL);
+	if (!new_link)
+		return -ENOMEM;
+
+	client->sysmmus = new_link;
+	client->sysmmus[client->sysmmu_count++] = data;
+
+	dev_info(dev, "has sysmmu %s (total count:%d)\n",
+		 dev_name(data->dev), client->sysmmu_count);
+
+	return ret;
+}
+
+static int samsung_sysmmu_aux_attach_dev(struct iommu_domain *dom, struct device *dev)
+{
+	struct sysmmu_clientdata *client;
+	struct samsung_sysmmu_domain *domain;
+	struct sysmmu_drvdata *drvdata;
+	unsigned long flags;
+	unsigned int vid;
+
+	domain = attach_helper(dom, dev);
+	if (IS_ERR(domain))
+		return (int)PTR_ERR(domain);
+
+	if (domain->group) {
+		dev_err(dev, "IOMMU domain is already in use as vid 0 domain\n");
+		return -EBUSY;
+	}
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+	if (client->sysmmu_count != 1) {
+		dev_err(dev, "IOMMU AUX domains not supported for devices served by more than one IOMMU\n");
+		return -ENXIO;
+	}
+	drvdata = client->sysmmus[0];
+	if (!drvdata->has_vcr) {
+		dev_err(dev, "SysMMU does not support IOMMU AUX domains\n");
+		return -ENXIO;
+	}
+	spin_lock_irqsave(&drvdata->lock, flags);
+	if (!drvdata->attached_count) {
+		dev_err(dev, "IOMMU needs to be enabled to attach AUX domain\n");
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+		return -ENXIO;
+	}
+	for (vid = 1; vid < MAX_VIDS; vid++)
+		if (!drvdata->pgtable[vid])
+			break;
+	if (vid == MAX_VIDS) {
+		dev_err(dev, "Unable to allocate vid for AUX domain\n");
+		spin_unlock_irqrestore(&drvdata->lock, flags);
+		return -EBUSY;
+	}
+	drvdata->pgtable[vid] = virt_to_phys(domain->page_table);
+	if (pm_runtime_active(drvdata->dev))
+		__sysmmu_enable_vid(drvdata, vid);
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+	domain->vm_sysmmu = drvdata;
+	domain->vid = vid;
+	return 0;
+}
+
+static void samsung_sysmmu_aux_detach_dev(struct iommu_domain *dom, struct device *dev)
+{
+	struct samsung_sysmmu_domain *domain;
+	struct sysmmu_drvdata *drvdata;
+	unsigned long flags;
+	unsigned int vid;
+
+	domain = to_sysmmu_domain(dom);
+
+	if (WARN_ON(!domain->vm_sysmmu || !domain->vid))
+		return;
+
+	drvdata = domain->vm_sysmmu;
+	vid = domain->vid;
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+	drvdata->pgtable[vid] = 0;
+	__sysmmu_disable_vid(drvdata, vid);
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	domain->vm_sysmmu = NULL;
+	domain->vid = 0;
+}
+
+static int samsung_sysmmu_aux_get_pasid(struct iommu_domain *dom, struct device *dev)
+{
+	struct samsung_sysmmu_domain *domain;
+
+	domain = to_sysmmu_domain(dom);
+
+	if (!domain->vm_sysmmu)
+		return -EINVAL;
+
+	return (int)domain->vid;
+}
+
+static bool samsung_sysmmu_dev_has_feat(struct device *dev, enum iommu_dev_features f)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct sysmmu_clientdata *client;
+	struct sysmmu_drvdata *drvdata;
+
+	if (f != IOMMU_DEV_FEAT_AUX)
+		return false;
+
+	client = (struct sysmmu_clientdata *) dev_iommu_priv_get(dev);
+	if (!fwspec || !client || fwspec->ops != &samsung_sysmmu_ops)
+		return false;
+
+	if (client->sysmmu_count != 1)
+		return false;
+	drvdata = client->sysmmus[0];
+	return !!drvdata->has_vcr;
+}
+
+static bool samsung_sysmmu_dev_feat_enabled(struct device *dev, enum iommu_dev_features f)
+{
+	return samsung_sysmmu_dev_has_feat(dev, f);
+}
+
+static int samsung_sysmmu_dev_enable_feat(struct device *dev, enum iommu_dev_features f)
+{
+	if (!samsung_sysmmu_dev_has_feat(dev, f))
+		return -EINVAL;
+	return 0;
+}
+
+static int samsung_sysmmu_dev_disable_feat(struct device *dev, enum iommu_dev_features f)
+{
+	return -EINVAL;
+}
+
+static void samsung_sysmmu_get_resv_regions(struct device *dev, struct list_head *head)
+{
+	enum iommu_resv_type resvtype[] = {
+		IOMMU_RESV_DIRECT, IOMMU_RESV_RESERVED
+	};
+	const char *propname[ARRAY_SIZE(resvtype)] = {
+		"samsung,iommu-identity-map",
+		"samsung,iommu-reserved-map"
+	};
+	int n_addr_cells = of_n_addr_cells(dev->of_node);
+	int n_size_cells = of_n_size_cells(dev->of_node);
+	int n_all_cells = n_addr_cells + n_size_cells;
+	unsigned int type;
+
+	for (type = 0; type < ARRAY_SIZE(propname); type++) {
+		const __be32 *prop;
+		u64 base, size;
+		int i, cnt;
+
+		prop = of_get_property(dev->of_node, propname[type], &cnt);
+		if (!prop)
+			continue;
+
+		cnt /=  sizeof(u32);
+		if (cnt % n_all_cells != 0) {
+			dev_err(dev, "Invalid number(%d) of values in %s\n", cnt, propname[type]);
+			break;
+		}
+
+		for (i = 0; i < cnt; i += n_all_cells) {
+			struct iommu_resv_region *region;
+
+			base = of_read_number(prop + i, n_addr_cells);
+			size = of_read_number(prop + i + n_addr_cells, n_size_cells);
+			if (base & ~dma_get_mask(dev) || (base + size) & ~dma_get_mask(dev)) {
+				dev_err(dev, "Unreachable DMA region in %s, [%#lx..%#lx)\n",
+					propname[type], (unsigned long)base,
+					(unsigned long)(base + size));
+				continue;
+			}
+
+			region = iommu_alloc_resv_region(base, size, 0, resvtype[type]);
+			if (!region)
+				continue;
+
+			list_add_tail(&region->list, head);
+			dev_info(dev, "Reserved IOMMU mapping [%#lx..%#lx)\n",
+				 (unsigned long)base,
+				 (unsigned long)(base + size));
+		}
+	}
+}
+
+static struct iommu_ops samsung_sysmmu_ops = {
+	.capable		= samsung_sysmmu_capable,
+	.domain_alloc		= samsung_sysmmu_domain_alloc,
+	.domain_free		= samsung_sysmmu_domain_free,
+	.attach_dev		= samsung_sysmmu_attach_dev,
+	.detach_dev		= samsung_sysmmu_detach_dev,
+	.map			= samsung_sysmmu_map,
+	.unmap			= samsung_sysmmu_unmap,
+	.flush_iotlb_all	= samsung_sysmmu_flush_iotlb_all,
+	.iotlb_sync		= samsung_sysmmu_iotlb_sync,
+	.iova_to_phys		= samsung_sysmmu_iova_to_phys,
+	.probe_device		= samsung_sysmmu_probe_device,
+	.release_device		= samsung_sysmmu_release_device,
+	.device_group		= samsung_sysmmu_device_group,
+	.of_xlate		= samsung_sysmmu_of_xlate,
+	.get_resv_regions	= samsung_sysmmu_get_resv_regions,
+	.put_resv_regions	= generic_iommu_put_resv_regions,
+	.dev_has_feat		= samsung_sysmmu_dev_has_feat,
+	.dev_feat_enabled	= samsung_sysmmu_dev_feat_enabled,
+	.dev_enable_feat	= samsung_sysmmu_dev_enable_feat,
+	.dev_disable_feat	= samsung_sysmmu_dev_disable_feat,
+	.aux_attach_dev		= samsung_sysmmu_aux_attach_dev,
+	.aux_detach_dev		= samsung_sysmmu_aux_detach_dev,
+	.aux_get_pasid		= samsung_sysmmu_aux_get_pasid,
+	.pgsize_bitmap		= SECT_SIZE | LPAGE_SIZE | SPAGE_SIZE,
+	.owner						= THIS_MODULE,
+};
+
+static int sysmmu_get_hw_info(struct sysmmu_drvdata *data)
+{
+	data->version = __sysmmu_get_hw_version(data);
+	data->num_tlb = __sysmmu_get_tlb_num(data);
+
+	/* Default value */
+	data->reg_set = sysmmu_reg_set[REG_IDX_DEFAULT];
+
+	if (__sysmmu_get_capa_vcr_enabled(data)) {
+		data->reg_set = sysmmu_reg_set[REG_IDX_VM];
+		data->has_vcr = true;
+	}
+	if (__sysmmu_get_capa_no_block_mode(data))
+		data->no_block_mode = true;
+
+	return 0;
+}
+
+static int sysmmu_parse_tlb_property(struct device *dev,
+				     struct sysmmu_drvdata *drvdata)
+{
+	const char *default_props_name = "sysmmu,default_tlb";
+	const char *props_name = "sysmmu,tlb_property";
+	struct tlb_props *tlb_props = &drvdata->tlb_props;
+	struct tlb_config *cfg;
+	int i, cnt, ret;
+	size_t readsize;
+
+	if (of_property_read_u32(dev->of_node, default_props_name,
+				 &tlb_props->default_cfg))
+		tlb_props->default_cfg = DEFAULT_TLB_NONE;
+
+	cnt = of_property_count_elems_of_size(dev->of_node, props_name,
+					      sizeof(*cfg));
+	if (cnt <= 0)
+		return 0;
+
+	cfg = devm_kcalloc(dev, (unsigned int)cnt, sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	readsize = (unsigned int)cnt * sizeof(*cfg) / sizeof(u32);
+	ret = of_property_read_variable_u32_array(dev->of_node, props_name,
+						  (u32 *)cfg,
+						  readsize, readsize);
+	if (ret < 0) {
+		dev_err(dev, "failed to get tlb property, return %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < cnt; i++) {
+		if (cfg[i].index >= drvdata->num_tlb) {
+			dev_err(dev, "invalid index %d is ignored. (max:%d)\n",
+				cfg[i].index, drvdata->num_tlb);
+			cfg[i].index = UNUSED_TLB_INDEX;
+		}
+	}
+
+	tlb_props->id_cnt = cnt;
+	tlb_props->cfg = cfg;
+
+	return 0;
+}
+
+static int __sysmmu_secure_irq_init(struct device *sysmmu,
+				    struct sysmmu_drvdata *data)
+{
+	struct platform_device *pdev = to_platform_device(sysmmu);
+	int ret;
+
+	ret = platform_get_irq(pdev, 1);
+	if (ret <= 0) {
+		dev_err(sysmmu, "unable to find secure IRQ resource\n");
+		return -EINVAL;
+	}
+	data->secure_irq = ret;
+
+	ret = devm_request_threaded_irq(sysmmu, (unsigned int)data->secure_irq,
+					samsung_sysmmu_irq,
+					samsung_sysmmu_irq_thread,
+					IRQF_ONESHOT, dev_name(sysmmu), data);
+	if (ret) {
+		dev_err(sysmmu, "failed to set secure irq handler %d, ret:%d\n",
+			data->secure_irq, ret);
+		return ret;
+	}
+
+	ret = of_property_read_u32(sysmmu->of_node, "sysmmu,secure_base",
+				   &data->secure_base);
+	if (ret) {
+		dev_err(sysmmu, "failed to get secure base\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int sysmmu_parse_dt(struct device *sysmmu, struct sysmmu_drvdata *data)
+{
+	int qos = DEFAULT_QOS_VALUE;
+	int ret;
+
+	/* Parsing QoS */
+	ret = of_property_read_u32_index(sysmmu->of_node, "qos", 0, &qos);
+	if (!ret && qos > 15) {
+		dev_err(sysmmu, "Invalid QoS value %d, use default.\n", qos);
+		qos = DEFAULT_QOS_VALUE;
+	}
+
+	data->qos = qos;
+	data->no_s2pf = of_property_read_bool(sysmmu->of_node, "sysmmu,no-s2pf");
+
+	/* Secure IRQ */
+	if (of_find_property(sysmmu->of_node, "sysmmu,secure-irq", NULL)) {
+		ret = __sysmmu_secure_irq_init(sysmmu, data);
+		if (ret) {
+			dev_err(sysmmu, "failed to init secure irq\n");
+			return ret;
+		}
+	}
+
+	data->hide_page_fault = of_property_read_bool(sysmmu->of_node,
+						      "sysmmu,hide-page-fault");
+	/* use async fault mode */
+	data->async_fault_mode = of_property_read_bool(sysmmu->of_node,
+						       "sysmmu,async-fault");
+
+	ret = sysmmu_parse_tlb_property(sysmmu, data);
+	if (ret)
+		dev_err(sysmmu, "Failed to parse TLB property\n");
+
+	return ret;
+}
+
+static int samsung_sysmmu_init_global(void)
+{
+	int ret = 0;
+
+	flpt_cache = kmem_cache_create("samsung-iommu-lv1table",
+				       LV1TABLE_SIZE, LV1TABLE_SIZE,
+				       0, NULL);
+	if (!flpt_cache)
+		return -ENOMEM;
+
+	slpt_cache = kmem_cache_create("samsung-iommu-lv2table",
+				       LV2TABLE_SIZE, LV2TABLE_SIZE,
+				       0, NULL);
+	if (!slpt_cache) {
+		ret = -ENOMEM;
+		goto err_init_slpt_fail;
+	}
+
+	bus_set_iommu(&platform_bus_type, &samsung_sysmmu_ops);
+
+	device_initialize(&sync_dev);
+	sysmmu_global_init_done = true;
+
+	return 0;
+
+err_init_slpt_fail:
+	kmem_cache_destroy(flpt_cache);
+
+	return ret;
+}
+
+static int samsung_sysmmu_device_probe(struct platform_device *pdev)
+{
+	struct sysmmu_drvdata *data;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int irq, ret, err = 0;
+
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "failed to get resource info\n");
+		return -ENOENT;
+	}
+
+	data->sfrbase = devm_ioremap_resource(dev, res);
+	if (IS_ERR(data->sfrbase))
+		return PTR_ERR(data->sfrbase);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, (unsigned int)irq, samsung_sysmmu_irq,
+					samsung_sysmmu_irq_thread,
+					IRQF_ONESHOT, dev_name(dev), data);
+	if (ret) {
+		dev_err(dev, "unabled to register handler of irq %d\n", irq);
+		return ret;
+	}
+
+	data->clk = devm_clk_get(dev, "gate");
+	if (PTR_ERR(data->clk) == -ENOENT) {
+		data->clk = NULL;
+	} else if (IS_ERR(data->clk)) {
+		dev_err(dev, "failed to get clock!\n");
+		return PTR_ERR(data->clk);
+	}
+
+	// XXX: HACK: keep the gate clock enabled to fix registers access freeze
+	// TODO: Implement proper clock handling later
+	clk_prepare_enable(data->clk);
+
+	ret = sysmmu_get_hw_info(data);
+	if (ret) {
+		dev_err(dev, "failed to get h/w info\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&data->list);
+	spin_lock_init(&data->lock);
+	data->dev = dev;
+
+	ret = sysmmu_parse_dt(data->dev, data);
+	if (ret)
+		return ret;
+
+	ret = iommu_device_sysfs_add(&data->iommu, data->dev,
+				     NULL, dev_name(dev));
+	if (ret) {
+		dev_err(dev, "failed to register iommu in sysfs\n");
+		return ret;
+	}
+
+	err = iommu_device_register(&data->iommu, &samsung_sysmmu_ops, dev);
+	if (err) {
+		dev_err(dev, "failed to register iommu\n");
+		goto err_iommu_register;
+	}
+
+	if (!sysmmu_global_init_done) {
+		err = samsung_sysmmu_init_global();
+		if (err) {
+			dev_err(dev, "failed to initialize global data\n");
+			goto err_global_init;
+		}
+	}
+	pm_runtime_enable(dev);
+
+	platform_set_drvdata(pdev, data);
+
+	dev_info(dev, "initialized IOMMU. Ver %d.%d.%d, %sgate clock\n",
+		 MMU_MAJ_VER(data->version),
+		 MMU_MIN_VER(data->version),
+		 MMU_REV_VER(data->version),
+		 data->clk ? "" : "no ");
+	return 0;
+
+err_global_init:
+	iommu_device_unregister(&data->iommu);
+err_iommu_register:
+	iommu_device_sysfs_remove(&data->iommu);
+	return err;
+}
+
+static void samsung_sysmmu_device_shutdown(struct platform_device *pdev)
+{
+}
+
+static int __maybe_unused samsung_sysmmu_runtime_suspend(struct device *sysmmu)
+{
+	unsigned long flags;
+	struct sysmmu_drvdata *drvdata = dev_get_drvdata(sysmmu);
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+	drvdata->rpm_resume = false;
+	if (drvdata->attached_count > 0)
+		__sysmmu_disable(drvdata);
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	return 0;
+}
+
+static int __maybe_unused samsung_sysmmu_runtime_resume(struct device *sysmmu)
+{
+	unsigned long flags;
+	struct sysmmu_drvdata *drvdata = dev_get_drvdata(sysmmu);
+
+	spin_lock_irqsave(&drvdata->lock, flags);
+	drvdata->rpm_resume = true;
+	if (drvdata->attached_count > 0)
+		__sysmmu_enable(drvdata);
+	spin_unlock_irqrestore(&drvdata->lock, flags);
+
+	return 0;
+}
+
+static int __maybe_unused samsung_sysmmu_suspend(struct device *dev)
+{
+	if (pm_runtime_status_suspended(dev))
+		return 0;
+
+	dev->power.must_resume = true;
+	return samsung_sysmmu_runtime_suspend(dev);
+}
+
+static int __maybe_unused samsung_sysmmu_resume(struct device *dev)
+{
+	if (pm_runtime_status_suspended(dev))
+		return 0;
+
+	return samsung_sysmmu_runtime_resume(dev);
+}
+
+static const struct dev_pm_ops samsung_sysmmu_pm_ops = {
+	SET_RUNTIME_PM_OPS(samsung_sysmmu_runtime_suspend,
+			   samsung_sysmmu_runtime_resume, NULL)
+	SET_LATE_SYSTEM_SLEEP_PM_OPS(samsung_sysmmu_suspend,
+				     samsung_sysmmu_resume)
+};
+
+static const struct of_device_id sysmmu_of_match[] = {
+	{ .compatible = "samsung,sysmmu-v8" },
+	{ }
+};
+
+static struct platform_driver samsung_sysmmu_driver = {
+	.driver	= {
+		.name			= "samsung-sysmmu",
+		.of_match_table		= of_match_ptr(sysmmu_of_match),
+		.pm			= &samsung_sysmmu_pm_ops,
+		.suppress_bind_attrs	= true,
+	},
+	.probe	= samsung_sysmmu_device_probe,
+	.shutdown = samsung_sysmmu_device_shutdown,
+};
+module_platform_driver(samsung_sysmmu_driver);
+MODULE_SOFTDEP("pre: samsung-iommu-group");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/iommu/samsung-iommu.h b/drivers/iommu/samsung-iommu.h
new file mode 100644
index 000000000000..c6162740b296
--- /dev/null
+++ b/drivers/iommu/samsung-iommu.h
@@ -0,0 +1,216 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ */
+
+#ifndef __SAMSUNG_IOMMU_H
+#define __SAMSUNG_IOMMU_H
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/iommu.h>
+
+#define MAX_VIDS			8U
+
+struct tlb_config {
+	unsigned int index;
+	u32 cfg;
+	u32 match_cfg;
+	u32 match_id;
+};
+
+struct tlb_props {
+	int id_cnt;
+	u32 default_cfg;
+	struct tlb_config *cfg;
+};
+
+struct sysmmu_drvdata {
+	struct list_head list;
+	struct iommu_device iommu;
+	struct device *dev;
+	struct iommu_group *group;
+	void __iomem *sfrbase;
+	struct clk *clk;
+	phys_addr_t pgtable[MAX_VIDS];
+	spinlock_t lock; /* protect atomic update to H/W status */
+	u32 version;
+	unsigned int num_tlb;
+	int qos;
+	int attached_count;
+	int secure_irq;
+	unsigned int secure_base;
+	const unsigned int *reg_set;
+	struct tlb_props tlb_props;
+	bool no_block_mode;
+	bool has_vcr;
+	bool no_s2pf;		/* Disable stage 2 prefetch */
+	bool rpm_resume;	/* true if .runtime_resume() is called */
+	bool async_fault_mode;
+	bool hide_page_fault;
+};
+
+struct sysmmu_clientdata {
+	struct sysmmu_drvdata **sysmmus;
+	struct device_link **dev_link;
+	unsigned int sysmmu_count;
+};
+
+
+enum {
+	REG_IDX_DEFAULT = 0,
+	REG_IDX_VM,
+
+	MAX_SET_IDX,
+};
+
+enum {
+	IDX_CTRL_VM = 0,
+	IDX_CFG_VM,
+	IDX_FLPT_BASE,
+	IDX_ALL_INV,
+	IDX_VPN_INV,
+	IDX_RANGE_INV,
+	IDX_RANGE_INV_START,
+	IDX_RANGE_INV_END,
+	IDX_FAULT_VA,
+	IDX_FAULT_TRANS_INFO,
+	IDX_TLB_READ,
+	IDX_TLB_VPN,
+	IDX_TLB_PPN,
+	IDX_TLB_ATTR,
+	IDX_SBB_READ,
+	IDX_SBB_VPN,
+	IDX_SBB_LINK,
+	IDX_SBB_ATTR,
+	IDX_SEC_FLPT_BASE,
+
+	MAX_REG_IDX,
+};
+
+#define MMU_VM_REG_MULT(idx)		(((idx) == IDX_FAULT_VA || (idx) == IDX_FAULT_TRANS_INFO) \
+					 ? 0x10 : 0x1000)
+
+#define MMU_REG(data, idx)		((data)->sfrbase + (data)->reg_set[idx])
+#define MMU_VM_REG(data, idx, vmid)	(MMU_REG(data, idx) + (vmid) * MMU_VM_REG_MULT(idx))
+#define MMU_SEC_REG(data, offset_idx)	((data)->secure_base + (data)->reg_set[offset_idx])
+#define MMU_SEC_VM_REG(data, offset_idx, vmid) (MMU_SEC_REG(data, offset_idx) + \
+						(vmid) * MMU_VM_REG_MULT(offset_idx))
+
+static inline unsigned int __max_vids(struct sysmmu_drvdata *data)
+{
+	if (data->has_vcr)
+		return MAX_VIDS;
+	return 1;
+}
+
+typedef u32 sysmmu_iova_t;
+typedef u32 sysmmu_pte_t;
+
+#define SECT_ORDER 20
+#define LPAGE_ORDER 16
+#define SPAGE_ORDER 12
+
+#define SECT_SIZE  (1UL << SECT_ORDER)
+#define LPAGE_SIZE (1UL << LPAGE_ORDER)
+#define SPAGE_SIZE (1UL << SPAGE_ORDER)
+
+#define SECT_MASK (~(SECT_SIZE - 1))
+#define LPAGE_MASK (~(LPAGE_SIZE - 1))
+#define SPAGE_MASK (~(SPAGE_SIZE - 1))
+
+#define SECT_ENT_MASK	~((SECT_SIZE >> PG_ENT_SHIFT) - 1)
+#define LPAGE_ENT_MASK	~((LPAGE_SIZE >> PG_ENT_SHIFT) - 1)
+#define SPAGE_ENT_MASK	~((SPAGE_SIZE >> PG_ENT_SHIFT) - 1)
+
+#define SPAGES_PER_LPAGE	(LPAGE_SIZE / SPAGE_SIZE)
+
+#define NUM_LV1ENTRIES	4096
+#define NUM_LV2ENTRIES (SECT_SIZE / SPAGE_SIZE)
+#define LV1TABLE_SIZE (NUM_LV1ENTRIES * sizeof(sysmmu_pte_t))
+#define LV2TABLE_SIZE (NUM_LV2ENTRIES * sizeof(sysmmu_pte_t))
+
+#define lv1ent_offset(iova) ((iova) >> SECT_ORDER)
+#define lv2ent_offset(iova) (((iova) & ~SECT_MASK) >> SPAGE_ORDER)
+
+#define FLPD_FLAG_MASK	7
+#define SLPD_FLAG_MASK	3
+
+#define SECT_FLAG	2
+#define SLPD_FLAG	1
+
+#define LPAGE_FLAG	1
+#define SPAGE_FLAG	2
+
+#define PG_ENT_SHIFT	4
+#define lv1ent_unmapped(sent)	((*(sent) & 7) == 0)
+#define lv1ent_page(sent)	((*(sent) & 7) == 1)
+
+#define lv1ent_section(sent)	((*(sent) & FLPD_FLAG_MASK) == SECT_FLAG)
+#define lv2table_base(sent)	((phys_addr_t)(*(sent) & ~0x3FU) << PG_ENT_SHIFT)
+#define lv2ent_unmapped(pent)	((*(pent) & SLPD_FLAG_MASK) == 0)
+#define lv2ent_small(pent)	((*(pent) & SLPD_FLAG_MASK) == SPAGE_FLAG)
+#define lv2ent_large(pent)	((*(pent) & SLPD_FLAG_MASK) == LPAGE_FLAG)
+
+#define PGBASE_TO_PHYS(pgent)	((phys_addr_t)(pgent) << PG_ENT_SHIFT)
+#define ENT_TO_PHYS(ent) (phys_addr_t)(*(ent))
+#define section_phys(sent) PGBASE_TO_PHYS(ENT_TO_PHYS(sent) & SECT_ENT_MASK)
+#define section_offs(iova) ((iova) & (SECT_SIZE - 1))
+#define lpage_phys(pent) PGBASE_TO_PHYS(ENT_TO_PHYS(pent) & LPAGE_ENT_MASK)
+#define lpage_offs(iova) ((iova) & (LPAGE_SIZE - 1))
+#define spage_phys(pent) PGBASE_TO_PHYS(ENT_TO_PHYS(pent) & SPAGE_ENT_MASK)
+#define spage_offs(iova) ((iova) & (SPAGE_SIZE - 1))
+
+static inline sysmmu_pte_t *page_entry(sysmmu_pte_t *sent, sysmmu_iova_t iova)
+{
+	return (sysmmu_pte_t *)(phys_to_virt(lv2table_base(sent))) +
+				lv2ent_offset(iova);
+}
+
+static inline sysmmu_pte_t *section_entry(sysmmu_pte_t *pgtable,
+					  sysmmu_iova_t iova)
+{
+	return pgtable + lv1ent_offset(iova);
+}
+
+#define REG_MMU_CTRL			0x000
+#define REG_MMU_CFG			0x004
+#define REG_MMU_STATUS			0x008
+#define REG_MMU_FLPT_BASE		0x00C
+#define REG_MMU_VERSION			0x034
+#define REG_MMU_CAPA0_V7		0x870
+#define REG_MMU_CAPA1_V7		0x874
+
+#define MMU_CAPA_NUM_TLB_WAY(reg)	((reg) & 0xFF)
+#define MMU_CAPA_NUM_SBB_ENTRY(reg)	(((reg) >> 12) & 0xF)
+#define MMU_CAPA1_EXIST(reg)		(((reg) >> 11) & 0x1)
+#define MMU_CAPA1_TYPE(reg)		(((reg) >> 28) & 0xF)
+#define MMU_CAPA1_NO_BLOCK_MODE(reg)	(((reg) >> 15) & 0x1)
+#define MMU_CAPA1_VCR_ENABLED(reg)	(((reg) >> 14) & 0x1)
+#define MMU_CAPA1_NUM_TLB(reg)		(((reg) >> 4) & 0xFF)
+#define MMU_CAPA1_NUM_PORT(reg)		((reg) & 0xF)
+
+#define MMU_MAJ_VER(val)	((val) >> 11)
+#define MMU_MIN_VER(val)	(((val) >> 4) & 0x7F)
+#define MMU_REV_VER(val)	((val) & 0xF)
+#define MMU_RAW_VER(reg)	(((reg) >> 17) & 0x7FFF)
+
+#define CTRL_VID_ENABLE			BIT(0)
+#define CTRL_MMU_ENABLE			BIT(0)
+#define CTRL_MMU_BLOCK			BIT(1)
+#define CTRL_INT_ENABLE			BIT(2)
+#define CTRL_FAULT_STALL_MODE		BIT(3)
+
+#define CFG_MASK_GLOBAL			0x00000F80 /* Bit 11, 10-7 */
+#define CFG_MASK_VM			0xB00F1004 /* Bit 31, 29, 28, 19-16, 12, 2 */
+#define CFG_QOS_OVRRIDE			BIT(11)
+#define CFG_QOS(n)			(((n) & 0xFU) << 7)
+
+irqreturn_t samsung_sysmmu_irq_thread(int irq, void *dev_id);
+irqreturn_t samsung_sysmmu_irq(int irq, void *dev_id);
+
+#endif /* __SAMSUNG_IOMMU_H */
+
-- 
2.30.2



From mst at redhat.com  Thu Jan 20 12:39:12 2022
From: mst at redhat.com (Michael S. Tsirkin)
Date: Thu, 20 Jan 2022 15:39:12 -0500
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
 <20220119122338.GE6113@e120937-lin>
 <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>
Message-ID: <20220120150418-mutt-send-email-mst@kernel.org>

On Thu, Jan 20, 2022 at 08:09:56PM +0100, Peter Hilber wrote:
> On 19.01.22 13:23, Cristian Marussi wrote:
> > On Tue, Jan 18, 2022 at 03:21:03PM +0100, Peter Hilber wrote:
> >> On 21.12.21 15:00, Cristian Marussi wrote:
> >>> Add support for .mark_txdone and .poll_done transport operations to SCMI
> >>> VirtIO transport as pre-requisites to enable atomic operations.
> >>>
> >>> Add a Kernel configuration option to enable SCMI VirtIO transport polling
> >>> and atomic mode for selected SCMI transactions while leaving it default
> >>> disabled.
> >>>
> >>
> >> Hi Cristian,
> >>
> >> thanks for the update. I have some more remarks inline below.
> >>
> > 
> > Hi Peter,
> > 
> > thanks for your review, much appreciated, please see my replies online.
> > 
> >> My impression is that the virtio core does not expose helper functions suitable
> >> to busy-poll for used buffers. But changing this might not be difficult. Maybe
> >> more_used() from virtio_ring.c could be exposed via a wrapper?
> >>
> > 
> > While I definitely agree that the virtio core support for polling is far from
> > ideal, some support is provided and my point was at first to try implement SCMI
> > virtio polling leveraging what we have now in the core and see if it was attainable
> > (indeed I tried early in this series to avoid as a whole to have to support polling
> > at the SCMI transport layer to attain SCMI cmds atomicity..but that was an ill
> > attempt that led nowhere good...)
> > 
> > Btw, I was planning to post a new series next week (after merge-windows) with some
> > fixes I did already, at this point I'll include also some fixes derived
> > from some of your remarks.
> > 
> >> Best regards,
> >>
> >> Peter
> >>
> [snip]>>> + *
> >>> + * Return: True once polling has successfully completed.
> >>> + */
> >>> +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> >>> +			     struct scmi_xfer *xfer)
> >>> +{
> >>> +	bool pending, ret = false;
> >>> +	unsigned int length, any_prefetched = 0;
> >>> +	unsigned long flags;
> >>> +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> >>> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> >>> +
> >>> +	if (!msg)
> >>> +		return true;
> >>> +
> >>> +	spin_lock_irqsave(&msg->poll_lock, flags);
> >>> +	/* Processed already by other polling loop on another CPU ? */
> >>> +	if (msg->poll_idx == VIO_MSG_POLL_DONE) {
> >>> +		spin_unlock_irqrestore(&msg->poll_lock, flags);
> >>> +		return true;
> >>> +	}
> >>> +
> >>> +	/* Has cmdq index moved at all ? */
> >>> +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> >>
> >> In my understanding, the polling comparison could still be subject to the ABA
> >> problem when exactly 2**16 messages have been marked as used since
> >> msg->poll_idx was set (unlikely scenario, granted).
> >>
> >> I think this would be a lot simpler if the virtio core exported some
> >> concurrency-safe helper function for such polling (similar to more_used() from
> >> virtio_ring.c), as discussed at the top.
> > 
> > So this is the main limitation indeed of the current implementation, I
> > cannot distinguish if there was an exact full wrap and I'm reading the same
> > last_idx as before but a whoppying 2**16 messages have instead gone through...
> > 
> > The tricky part seems to me here that even introducing dedicated helpers
> > for polling in order to account for such wrapping (similar to more_used())
> > those would be based by current VirtIO spec on a single bit wrap counter,
> > so how do you discern if 2 whole wraps have happened (even more unlikely..) ?
> > 
> > Maybe I'm missing something though...
> > 
> 
> In my understanding, there is no need to keep track of the old state. We
> actually only want to check whether the device has marked any buffers as `used'
> which we did not retrieve yet via virtqueue_get_buf_ctx().
> 
> This is what more_used() checks in my understanding. One would just need to
> translate the external `struct virtqueue' param to the virtio_ring.c internal
> representation `struct vring_virtqueue' and then call `more_used()'.
> 
> There would be no need to keep `poll_idx` then.
> 
> Best regards,
> 
> Peter

Not really, I don't think so.

There's no magic in more_used. No synchronization happens.
more_used is exactly like virtqueue_poll except
you get to maintain your own index.

As it is, it is quite possible to read the cached index,
then another thread makes 2^16 bufs available, then device
uses them all, and presto you get a false positive.

I guess we can play with memory barriers such that cache
read happens after the index read - but it seems that
will just lead to the same wrap around problem
in reverse. So IIUC it's quite a bit more involved than
just translating structures.

And yes, a more_used like API would remove the need to pass
the index around, but it will also obscure the fact that
there's internal state here and that it's inherently racy
wrt wrap arounds. Whereas I'm happy to see that virtqueue_poll
seems to have made it clear enough that people get it.


It's not hard to handle wrap around in the driver if you like though:
just have a 32 bit atomic counter and increment it each time you are
going to make 2^16 buffers available. That gets you to 2^48 with an
overhead of an atomic read and that should be enough short term. Make
sure the cache line where you put the counter is not needed elsewhere -
checking it in a tight loop with an atomic will force it to the local
CPU. And if you are doing that virtqueue_poll will be enough.



> 
> > I'll have a though about this, but in my opinion this seems something so
> > unlikely that we could live with it, for the moment at least...
> > [snip]



From stefan.wahren at i2se.com  Thu Jan 20 13:23:39 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 20 Jan 2022 22:23:39 +0100
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <409091e8-abec-ce90-a247-246167223d92@gmail.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <20220120153928.yvkrqduoytddvegs@houat>
 <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>
 <409091e8-abec-ce90-a247-246167223d92@gmail.com>
Message-ID: <dc990eae-506c-5f4e-efde-ec483c6f9aa9@i2se.com>

Hi,

Am 20.01.22 um 20:48 schrieb Florian Fainelli:
>
> Can we get the full dump of the Device Tree that you are running with?
> Something like:
>
> dtc -I fs /proc/device-tree -O dts > live.dts
>
> would be helpful to figure out what is going on here.

sorry guys, i assumed that the Arch people know what they do. I figured
out that they mixed the vendor DTB with the mainline kernel.

Thanks a lot




From f.fainelli at gmail.com  Thu Jan 20 13:38:08 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 20 Jan 2022 13:38:08 -0800
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <dc990eae-506c-5f4e-efde-ec483c6f9aa9@i2se.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <20220120153928.yvkrqduoytddvegs@houat>
 <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>
 <409091e8-abec-ce90-a247-246167223d92@gmail.com>
 <dc990eae-506c-5f4e-efde-ec483c6f9aa9@i2se.com>
Message-ID: <8a040749-e4fa-8b9d-e3e9-377a1e6f27a0@gmail.com>



On 1/20/2022 1:23 PM, Stefan Wahren wrote:
> Hi,
> 
> Am 20.01.22 um 20:48 schrieb Florian Fainelli:
>>
>> Can we get the full dump of the Device Tree that you are running with?
>> Something like:
>>
>> dtc -I fs /proc/device-tree -O dts > live.dts
>>
>> would be helpful to figure out what is going on here.
> 
> sorry guys, i assumed that the Arch people know what they do. I figured
> out that they mixed the vendor DTB with the mainline kernel.

No worries, it's always good to be thrown debugging exercises :), glad 
you figured it out.
-- 
Florian


From jbrunet at baylibre.com  Thu Jan 20 13:40:31 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:40:31 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <20220118030911.12815-4-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
Message-ID: <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:

> Using the common Clock code to describe the UART baud rate clock
> makes it easier for the UART driver to be compatible with the
> baud rate requirements of the UART IP on different meson chips.
>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
>  1 file changed, 142 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 7570958d010c..92fa91c825e6 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -6,6 +6,7 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/console.h>
>  #include <linux/delay.h>
>  #include <linux/init.h>
> @@ -65,9 +66,7 @@
>  #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>  
>  /* AML_UART_REG5 bits */
> -#define AML_UART_BAUD_MASK		0x7fffff
>  #define AML_UART_BAUD_USE		BIT(23)
> -#define AML_UART_BAUD_XTAL		BIT(24)
>  
>  #define AML_UART_PORT_NUM		12
>  #define AML_UART_PORT_OFFSET		6
> @@ -76,6 +75,11 @@
>  #define AML_UART_POLL_USEC		5
>  #define AML_UART_TIMEOUT_USEC		10000
>  
> +struct meson_uart_data {
> +	struct clk	*baud_clk;
> +	bool		use_xtal_clk;
> +};
> +
>  static struct uart_driver meson_uart_driver;
>  
>  static struct uart_port *meson_ports[AML_UART_PORT_NUM];
> @@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
>  
>  static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
>  	u32 val;
>  
>  	while (!meson_uart_tx_empty(port))
>  		cpu_relax();
>  
> -	if (port->uartclk == 24000000) {
> -		val = ((port->uartclk / 3) / baud) - 1;
> -		val |= AML_UART_BAUD_XTAL;
> -	} else {
> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
> -	}
> +	val = readl(port->membase + AML_UART_REG5);
>  	val |= AML_UART_BAUD_USE;
>  	writel(val, port->membase + AML_UART_REG5);
> +
> +	clk_set_rate(private_data->baud_clk, baud);
>  }
>  
>  static void meson_uart_set_termios(struct uart_port *port,
> @@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
>  
>  static void meson_uart_release_port(struct uart_port *port)
>  {
> -	/* nothing to do */
> +	struct meson_uart_data *private_data = port->private_data;
> +
> +	clk_disable_unprepare(private_data->baud_clk);
>  }
>  
>  static int meson_uart_request_port(struct uart_port *port)
>  {
> +	struct meson_uart_data *private_data = port->private_data;
> +	int ret;
> +
> +	ret = clk_prepare_enable(private_data->baud_clk);
> +	if (ret)
> +		return ret;
> +
>  	return 0;
>  }
>  
> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>  	.cons		= MESON_SERIAL_CONSOLE,
>  };
>  
> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
> -						 const char *id)
> -{
> -	struct clk *clk = NULL;
> -	int ret;
> -
> -	clk = devm_clk_get(dev, id);
> -	if (IS_ERR(clk))
> -		return clk;
> -
> -	ret = clk_prepare_enable(clk);
> -	if (ret) {
> -		dev_err(dev, "couldn't enable clk\n");
> -		return ERR_PTR(ret);
> -	}
> -
> -	devm_add_action_or_reset(dev,
> -			(void(*)(void *))clk_disable_unprepare,
> -			clk);
> -
> -	return clk;
> -}
> +static struct clk_div_table xtal_div_table[] = {
> +	{0, 3},
> +	{1, 1},
> +	{2, 2},
> +	{3, 2},
> +};
>  
> -static int meson_uart_probe_clocks(struct platform_device *pdev,
> -				   struct uart_port *port)
> +static int meson_uart_probe_clocks(struct uart_port *port)
>  {
> -	struct clk *clk_xtal = NULL;
> -	struct clk *clk_pclk = NULL;
> -	struct clk *clk_baud = NULL;
> +	struct meson_uart_data *private_data = port->private_data;
> +	struct clk *clk_baud, *clk_xtal;
> +	struct clk_hw *hw;
> +	char clk_name[32];
> +	struct clk_parent_data use_xtal_mux_parents[2] = {
> +		{ .index = -1, },
> +		{ .index = -1, },
> +	};

You are using hw pointers later, you don't need to init the index to -1
I think

>  
> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
> -	if (IS_ERR(clk_pclk))
> -		return PTR_ERR(clk_pclk);
> +	clk_baud = devm_clk_get(port->dev, "baud");
> +	if (IS_ERR(clk_baud)) {
> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
> +		return PTR_ERR(clk_baud);
> +	}
>  
> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>  	if (IS_ERR(clk_xtal))
> -		return PTR_ERR(clk_xtal);
> -
> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
> -	if (IS_ERR(clk_baud))
> -		return PTR_ERR(clk_baud);
> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
> +				     "Failed to get the 'xtal' clock\n");
> +
> +	if (private_data->use_xtal_clk) {
> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +			 "xtal_div");
> +		hw = devm_clk_hw_register_divider_table(port->dev,
> +							clk_name,
> +							__clk_get_name(clk_baud),
> +							CLK_SET_RATE_NO_REPARENT,
> +							port->membase + AML_UART_REG5,
> +							26, 2,
> +							CLK_DIVIDER_READ_ONLY,
> +							xtal_div_table, NULL);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[1].hw = hw;
> +	} else {
> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +			 "clk81_div4");
> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
> +						       clk_name,
> +						       __clk_get_name(clk_baud),
> +						       CLK_SET_RATE_NO_REPARENT,
> +						       1, 4);
> +		if (IS_ERR(hw))
> +			return PTR_ERR(hw);
> +
> +		use_xtal_mux_parents[0].hw = hw;
> +	}

The above is still wrong.

use_xtal_mux_parents initialize both parent to nothing
And you init the parent in the conditional above.
It is means only one path is actually set instead of both.

The mux always has 2 sources - Both should be set regardless of the HW version
You just add
* /4 on path 0 on legacy SoC
* the funky divider on path 1 on newer SoC.

>  
> -	port->uartclk = clk_get_rate(clk_baud);
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 "use_xtal");
> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
> +					clk_name,
> +					ARRAY_SIZE(use_xtal_mux_parents),
> +					NULL, NULL,
> +					use_xtal_mux_parents,
> +					CLK_SET_RATE_PARENT,
> +					port->membase + AML_UART_REG5,
> +					24, 0x1,
> +					CLK_MUX_READ_ONLY,
> +					NULL, NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	port->uartclk = clk_hw_get_rate(hw);
> +
> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
> +		 "baud_div");
> +	hw = devm_clk_hw_register_divider(port->dev,
> +					  clk_name,
> +					  clk_hw_get_name(hw),
> +					  CLK_SET_RATE_PARENT,
> +					  port->membase + AML_UART_REG5,
> +					  0, 23,
> +					  CLK_DIVIDER_ROUND_CLOSEST,
> +					  NULL);
> +	if (IS_ERR(hw))
> +		return PTR_ERR(hw);
> +
> +	private_data->baud_clk = hw->clk;
>  
>  	return 0;
>  }
>  
>  static int meson_uart_probe(struct platform_device *pdev)
>  {
> +	struct meson_uart_data *private_data;
>  	struct resource *res_mem;
>  	struct uart_port *port;
> +	struct clk *pclk;
>  	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>  	int ret = 0;
>  	int irq;
> @@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	if (!res_mem)
>  		return -ENODEV;
>  
> +	pclk = devm_clk_get(&pdev->dev, "pclk");
> +	if (IS_ERR(pclk))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
> +				     "Failed to get the 'pclk' clock\n");
> +
> +	ret = clk_prepare_enable(pclk);
> +	if (ret)
> +		return ret;
> +

I think this is unbalanced. 

>  	irq = platform_get_irq(pdev, 0);
>  	if (irq < 0)
>  		return irq;
> @@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	if (IS_ERR(port->membase))
>  		return PTR_ERR(port->membase);
>  
> -	ret = meson_uart_probe_clocks(pdev, port);
> -	if (ret)
> -		return ret;
> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
> +				    GFP_KERNEL);
> +	if (!private_data)
> +		return -ENOMEM;
> +
> +	if (device_get_match_data(&pdev->dev))
> +		private_data->use_xtal_clk = true;
>  
>  	port->iotype = UPIO_MEM;
>  	port->mapbase = res_mem->start;
> @@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>  	port->x_char = 0;
>  	port->ops = &meson_uart_ops;
>  	port->fifosize = fifosize;
> +	port->private_data = private_data;
> +
> +	ret = meson_uart_probe_clocks(port);
> +	if (ret)
> +		return ret;
>  
>  	meson_ports[pdev->id] = port;
>  	platform_set_drvdata(pdev, port);
> @@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
>  }
>  
>  static const struct of_device_id meson_uart_dt_match[] = {
> -	{ .compatible = "amlogic,meson6-uart" },
> -	{ .compatible = "amlogic,meson8-uart" },
> -	{ .compatible = "amlogic,meson8b-uart" },
> -	{ .compatible = "amlogic,meson-gx-uart" },
> +	{
> +		.compatible = "amlogic,meson6-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson8b-uart",
> +		.data = (void *)false,
> +	},
> +	{
> +		.compatible = "amlogic,meson-gx-uart",
> +		.data = (void *)true,
> +	},
>  	{ /* sentinel */ },
>  };
>  MODULE_DEVICE_TABLE(of, meson_uart_dt_match);



From jbrunet at baylibre.com  Thu Jan 20 13:48:05 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:48:05 +0100
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <7a8016ba-730b-f599-2032-31cf03990a55@kernel.org>
Message-ID: <1jbl062i4o.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 10:39, Jiri Slaby <jirislaby at kernel.org> wrote:

> On 18. 01. 22, 4:09, Yu Tu wrote:
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
> ...
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
> ...
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> -{
>> -	struct clk *clk = NULL;
>> -	int ret;
>> -
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> -
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> -
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
>
> This can be const, right?
>
>> +	{0, 3},
>> +	{1, 1},
>> +	{2, 2},
>> +	{3, 2},
>
> Not sure if you didn't remove too much whitespace. I think it should be
> like: "{ 0, 3 },". But I actually don't care, it's a minor thing.

Seconds
It worth fixing in the next version

>
> I cannot comment on the rest (clk and OF part) as my knowledge is pretty
> limited there. Leaving up to others.
>
> thanks,



From jbrunet at baylibre.com  Thu Jan 20 13:49:28 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 20 Jan 2022 22:49:28 +0100
Subject: [PATCH V6 4/5] tty: serial: meson: Make some bit of the REG5
 register writable
In-Reply-To: <20220118030911.12815-5-yu.tu@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-5-yu.tu@amlogic.com>
Message-ID: <1j7dau2hxi.fsf@starbuckisacylon.baylibre.com>


On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:

> The UART_REG5 register defaults to 0. The console port is set in
> ROMCODE. But other UART ports default to 0, so make bit24 and
> bit[26,27] writable so that the UART can choose a more
> appropriate clock.

Suggestion: Instead of talking bits (which is a bit cryptic) tell us
what is actually does

Something like:
 Make the internal clock source mux and divider writeable, allowing the
 uart to deviate from the settings intially applied by the ROMCode and
 using the most appropriate clocks

>
> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
> ---
>  drivers/tty/serial/meson_uart.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
> index 92fa91c825e6..4e7b2b38ab0a 100644
> --- a/drivers/tty/serial/meson_uart.c
> +++ b/drivers/tty/serial/meson_uart.c
> @@ -678,7 +678,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>  							CLK_SET_RATE_NO_REPARENT,
>  							port->membase + AML_UART_REG5,
>  							26, 2,
> -							CLK_DIVIDER_READ_ONLY,
> +							CLK_DIVIDER_ROUND_CLOSEST,
>  							xtal_div_table, NULL);
>  		if (IS_ERR(hw))
>  			return PTR_ERR(hw);
> @@ -708,7 +708,7 @@ static int meson_uart_probe_clocks(struct uart_port *port)
>  					CLK_SET_RATE_PARENT,
>  					port->membase + AML_UART_REG5,
>  					24, 0x1,
> -					CLK_MUX_READ_ONLY,
> +					CLK_MUX_ROUND_CLOSEST,
>  					NULL, NULL);
>  	if (IS_ERR(hw))
>  		return PTR_ERR(hw);



From sboyd at kernel.org  Thu Jan 20 14:03:54 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Thu, 20 Jan 2022 14:03:54 -0800
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220120220356.79C3CC340E0@smtp.kernel.org>

Quoting Marek Vasut (2022-01-18 12:29:54)
> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
> in use, ETHCKEN gate can be turned off. Current driver does not permit
> that, fix it.
> 
> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
> ETHPTP_K remain functional as before.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>     Figure 83. Peripheral clock distribution for Ethernet
>     https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---

Any cover letter? What is the merge strategy of this patch series? Do I
need to ack the patches?


From robh at kernel.org  Thu Jan 20 14:38:15 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 20 Jan 2022 16:38:15 -0600
Subject: [PATCH v5 3/4] mfd: dt-bindings: google,cros-ec: reference
 Samsung SPI bindings
In-Reply-To: <20220120175747.43403-4-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
 <20220120175747.43403-4-krzysztof.kozlowski@canonical.com>
Message-ID: <YenkV2rgEXQJ6Bc5@robh.at.kernel.org>

On Thu, Jan 20, 2022 at 06:57:46PM +0100, Krzysztof Kozlowski wrote:
> The ChromeOS Embedded Controller appears on boards with Samsung Exynos
> SoC, where Exynos SPI bindings expect controller-data node.  Reference
> newly added dtschema for this property.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/mfd/google,cros-ec.yaml          | 29 ++++++++++---------
>  1 file changed, 16 insertions(+), 13 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> index 58a1a9405228..66a995bbbbe9 100644
> --- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> +++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
> @@ -31,7 +31,7 @@ properties:
>  
>    controller-data:
>      description:
> -      SPI controller data, see bindings/spi/spi-samsung.txt
> +      SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
>      type: object

We should be able to drop all of this if unevaluatedProperties is used.

>  
>    google,cros-ec-spi-pre-delay:
> @@ -148,18 +148,21 @@ patternProperties:
>  required:
>    - compatible
>  
> -if:
> -  properties:
> -    compatible:
> -      contains:
> -        enum:
> -          - google,cros-ec-i2c
> -          - google,cros-ec-rpmsg
> -then:
> -  properties:
> -    google,cros-ec-spi-pre-delay: false
> -    google,cros-ec-spi-msg-delay: false
> -    spi-max-frequency: false
> +allOf:
> +  - if:
> +      properties:
> +        compatible:
> +          contains:
> +            enum:
> +              - google,cros-ec-i2c
> +              - google,cros-ec-rpmsg
> +    then:
> +      properties:
> +        google,cros-ec-spi-pre-delay: false
> +        google,cros-ec-spi-msg-delay: false
> +        spi-max-frequency: false
> +
> +  - $ref: /schemas/spi/samsung,spi-peripheral-props.yaml

SPI device schemas should reference spi-peripheral-props.yaml only. 
spi-peripheral-props.yaml in turn should reference all the vendor 
specific peripheral property schemas.

You should be able to do just:

else:
  $ref: /schemas/spi/spi-peripheral-props.yaml

Can you please hold off sending anything referencing 
spi-peripheral-props.yaml until after the merge window. Otherwise, the 
checks fail (though I trust you've run validation).

Rob


From marex at denx.de  Thu Jan 20 14:39:58 2022
From: marex at denx.de (Marek Vasut)
Date: Thu, 20 Jan 2022 23:39:58 +0100
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <20220120220356.79C3CC340E0@smtp.kernel.org>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220120220356.79C3CC340E0@smtp.kernel.org>
Message-ID: <2752700e-83ec-d844-e99e-73be8ff87ee9@denx.de>

On 1/20/22 23:03, Stephen Boyd wrote:
> Quoting Marek Vasut (2022-01-18 12:29:54)
>> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
>> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
>> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
>> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
>> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
>> in use, ETHCKEN gate can be turned off. Current driver does not permit
>> that, fix it.
>>
>> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
>> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
>> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
>> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
>> ETHPTP_K remain functional as before.
>>
>> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>>      Figure 83. Peripheral clock distribution for Ethernet
>>      https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
>>
>> Signed-off-by: Marek Vasut <marex at denx.de>
>> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
>> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
>> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
>> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
>> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
>> Cc: Stephen Boyd <sboyd at kernel.org>
>> Cc: linux-clk at vger.kernel.org
>> Cc: linux-stm32 at st-md-mailman.stormreply.com
>> To: linux-arm-kernel at lists.infradead.org
>> ---
> 
> Any cover letter?

If there is a need for V2, I will send one. Admittedly, I forgot one here.

> What is the merge strategy of this patch series?

Clock bits 1/5 and 2/5 can go through clock tree, DT bits through Alex's 
ST tree.

> Do I need to ack the patches?

I am waiting for AB/RB from ST, then they can be merged.

If you want to review the first two patches, sure, the top half of 2/5 
is probably the most interesting part, based on your suggestion from 
almost a year ago. The rest are clock controller hardware details.


From nfraprado at collabora.com  Thu Jan 20 14:42:04 2022
From: nfraprado at collabora.com (=?UTF-8?q?N=C3=ADcolas=20F=2E=20R=2E=20A=2E=20Prado?=)
Date: Thu, 20 Jan 2022 17:42:04 -0500
Subject: [PATCH] arm64: dts: mt8183: jacuzzi: Fix bus properties in anx's DSI
 endpoint
Message-ID: <20220120224204.773117-1-nfraprado@collabora.com>

mt8183-kukui-jacuzzi has an anx7625 bridge connected to the output of
its DSI host. However, after fd0310b6fe7d ("drm/bridge: anx7625: add
MIPI DPI input feature"), a bus-type property started being required in
the endpoint node by the driver to indicate whether it is DSI or DPI.

Add the missing bus-type property and set it to 5
(V4L2_FWNODE_BUS_TYPE_PARALLEL) so that the driver has its input
configured to DSI and the display pipeline can probe correctly.

While at it, also set the data-lanes property that was also introduced
in that same commit, so that we don't rely on the default value.

Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature")
Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
index 8f7bf33f607d..e8f133dc96b9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
@@ -171,6 +171,8 @@ port at 0 {
 
 			anx7625_in: endpoint {
 				remote-endpoint = <&dsi_out>;
+				bus-type = <5>;
+				data-lanes = <0 1 2 3>;
 			};
 		};
 
-- 
2.34.1



From peng.fan at nxp.com  Thu Jan 20 17:00:04 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Fri, 21 Jan 2022 01:00:04 +0000
Subject: [PATCH 8/9] remoteproc: imx_rproc: support i.MX8QM
In-Reply-To: <20220120172343.GA1338735@p14s>
References: <20220111033333.403448-1-peng.fan@oss.nxp.com>
 <20220111033333.403448-11-peng.fan@oss.nxp.com>
 <20220120172343.GA1338735@p14s>
Message-ID: <DU0PR04MB94171209E7B16B8FF31099DB885B9@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: Re: [PATCH 8/9] remoteproc: imx_rproc: support i.MX8QM
> 
> On Tue, Jan 11, 2022 at 11:33:32AM +0800, Peng Fan (OSS) wrote:
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > Most logic are same as i.MX8QXP, but i.MX8QM has two general purpose
> > M4 cores:
> >  Use the lower 16 bits specifying core, higher 16 bits for flags.
> >  The 2nd core has different start address from SCFW view
> 
> Are the cores running independently or in lockstep? 

Independetly.

 This is relevant
> information that should be in the changelog.  The above is an
> implementation detail that should be added as comments in the code.

Fix in V2.

> 
> >
> > Signed-off-by: Peng Fan <peng.fan at nxp.com>
> > ---
> >  drivers/remoteproc/imx_rproc.c | 55
> > +++++++++++++++++++++++++++++++---
> >  1 file changed, 51 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/remoteproc/imx_rproc.c
> > b/drivers/remoteproc/imx_rproc.c index 09d2a06e5ed6..7bc274fbce9f
> > 100644
> > --- a/drivers/remoteproc/imx_rproc.c
> > +++ b/drivers/remoteproc/imx_rproc.c
> > @@ -77,8 +77,11 @@ struct imx_rproc_mem {
> >
> >  /* att flags */
> >  /* M4 own area. Can be mapped at probe */
> > -#define ATT_OWN		BIT(1)
> > -#define ATT_IOMEM	BIT(2)
> > +#define ATT_OWN         BIT(31)
> > +#define ATT_IOMEM       BIT(30)
> 
> ATT_OWN was defined in 2017 and has had the same value since.
> ATT_IOMEM was introduced by this commit [1] (that you signed off on), which
> as supposed to be a fix for another commit.
> 
> Now, overnight, both bitfields are changed without any explanation other than
> a cryptic comments.  What about all the other platforms that previously used
> those bitfields - was this change tested on those as well?

Yes. Actually in NXP downstream, the new bit definition has been used for
quite some time and tested on many platforms.

The bit change is just to make code easy to get it is remote core0 or remote core1,
no function impact to other platforms.

I'll update in V2.

Thanks,
Peng.

> 
> I will stop here with this patchset - it needs to much work for me to continue
> reviewing it.
> 
> Thanks,
> Mathieu
> 
> [1]. 91bb26637353 remoteproc: imx_rproc: Fix TCM io memory type
> 
> 
> > +/* I = [0:7] */
> > +#define ATT_CORE_MASK   0xffff
> > +#define ATT_CORE(I)     BIT((I))
> >
> >  struct imx_rproc {
> >  	struct device			*dev;
> > @@ -98,11 +101,25 @@ struct imx_rproc {
> >  	struct notifier_block		proc_nb;
> >  	u32				rproc_pt;
> >  	u32				rsrc;
> > +	u32				reg;
> >  	int                             num_pd;
> >  	struct device                   **pd_dev;
> >  	struct device_link              **pd_dev_link;
> >  };
> >
> > +static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
> > +	/* dev addr , sys addr  , size      , flags */
> > +	{ 0x08000000, 0x08000000, 0x10000000, 0},
> > +	/* TCML */
> > +	{ 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_CORE(0)},
> > +	{ 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_CORE(1)},
> > +	/* TCMU */
> > +	{ 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_CORE(0)},
> > +	{ 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_CORE(1)},
> > +	/* DDR (Data) */
> > +	{ 0x80000000, 0x80000000, 0x60000000, 0 }, };
> > +
> >  static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
> >  	/* dev addr , sys addr  , size	    , flags */
> >  	{ 0x08000000, 0x08000000, 0x10000000, 0}, @@ -260,6 +277,12 @@
> > static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
> >  	.method		= IMX_RPROC_NONE,
> >  };
> >
> > +static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
> > +	.att            = imx_rproc_att_imx8qm,
> > +	.att_size       = ARRAY_SIZE(imx_rproc_att_imx8qm),
> > +	.method         = IMX_RPROC_SCU_API,
> > +};
> > +
> >  static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
> >  	.att		= imx_rproc_att_imx8qxp,
> >  	.att_size	= ARRAY_SIZE(imx_rproc_att_imx8qxp),
> > @@ -310,7 +333,10 @@ static int imx_rproc_start(struct rproc *rproc)
> >  		ret = res.a0;
> >  		break;
> >  	case IMX_RPROC_SCU_API:
> > -		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true,
> 0x34fe0000);
> > +		if (priv->reg)
> > +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true,
> 0x38fe0000);
> > +		else
> > +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, true,
> > +0x34fe0000);
> >  		break;
> >  	default:
> >  		return -EOPNOTSUPP;
> > @@ -342,7 +368,10 @@ static int imx_rproc_stop(struct rproc *rproc)
> >  			dev_info(dev, "Not in wfi, force stopped\n");
> >  		break;
> >  	case IMX_RPROC_SCU_API:
> > -		ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false,
> 0x34fe0000);
> > +		if (priv->reg)
> > +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false,
> 0x38fe0000);
> > +		else
> > +			ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc, false,
> > +0x34fe0000);
> >  		break;
> >  	default:
> >  		return -EOPNOTSUPP;
> > @@ -364,6 +393,11 @@ static int imx_rproc_da_to_sys(struct imx_rproc
> *priv, u64 da,
> >  	for (i = 0; i < dcfg->att_size; i++) {
> >  		const struct imx_rproc_att *att = &dcfg->att[i];
> >
> > +		if (att->flags & ATT_CORE_MASK) {
> > +			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
> > +				continue;
> > +		}
> > +
> >  		if (da >= att->da && da + len < att->da + att->size) {
> >  			unsigned int offset = da - att->da;
> >
> > @@ -594,6 +628,11 @@ static int imx_rproc_addr_init(struct imx_rproc
> *priv,
> >  		if (!(att->flags & ATT_OWN))
> >  			continue;
> >
> > +		if (att->flags & ATT_CORE_MASK) {
> > +			if (!((BIT(priv->reg)) & (att->flags & ATT_CORE_MASK)))
> > +				continue;
> > +		}
> > +
> >  		if (b >= IMX_RPROC_MEM_MAX)
> >  			break;
> >
> > @@ -809,6 +848,13 @@ static int imx_rproc_detect_mode(struct
> imx_rproc *priv)
> >  			return ret;
> >  		}
> >
> > +		priv->reg = of_get_cpu_hwid(dev->of_node, 0);
> > +		if (priv->reg == ~0U)
> > +			priv->reg = 0;
> > +
> > +		if (priv->reg > 1)
> > +			return -EINVAL;
> > +
> >  		priv->has_clk = false;
> >  		/*
> >  		 * If Mcore resource is not owned by Acore partition, It is kicked
> > by ROM, @@ -1005,6 +1051,7 @@ static const struct of_device_id
> imx_rproc_of_match[] = {
> >  	{ .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
> >  	{ .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
> >  	{ .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
> > +	{ .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
> >  	{ .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
> >  	{},
> >  };
> > --
> > 2.25.1
> >


From linus.walleij at linaro.org  Thu Jan 20 17:20:14 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 21 Jan 2022 02:20:14 +0100
Subject: [PATCH] spi: pxa2xx_spi: Convert to use GPIO descriptors
Message-ID: <20220121012014.287288-1-linus.walleij@linaro.org>

This converts the PXA2xx SPI driver to use GPIO descriptors
exclusively to retrieve GPIO chip select lines.

The device tree and ACPI paths of the driver already use
descriptors, hence ->use_gpio_descriptors is already set and
this codepath is well tested.

Convert all the PXA boards providing chip select GPIOs as
platform data and drop the old GPIO chipselect handling in
favor of the core managing it exclusively.

Cc: Marek Vasut <marek.vasut at gmail.com>
Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 Documentation/spi/pxa2xx.rst   |  3 --
 arch/arm/mach-pxa/corgi.c      | 26 +++++++---------
 arch/arm/mach-pxa/hx4700.c     | 10 +++++-
 arch/arm/mach-pxa/icontrol.c   | 26 +++++++++++++---
 arch/arm/mach-pxa/littleton.c  | 10 +++++-
 arch/arm/mach-pxa/magician.c   | 12 +++++--
 arch/arm/mach-pxa/poodle.c     | 14 ++++++---
 arch/arm/mach-pxa/spitz.c      | 26 +++++++---------
 arch/arm/mach-pxa/stargate2.c  | 21 +++++++++++--
 arch/arm/mach-pxa/z2.c         | 20 ++++++++++--
 drivers/spi/spi-pxa2xx.c       | 57 ----------------------------------
 include/linux/spi/pxa2xx_spi.h |  1 -
 12 files changed, 117 insertions(+), 109 deletions(-)

diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst
index 6347580826be..716f65d87d04 100644
--- a/Documentation/spi/pxa2xx.rst
+++ b/Documentation/spi/pxa2xx.rst
@@ -101,7 +101,6 @@ device. All fields are optional.
 	u8 rx_threshold;
 	u8 dma_burst_size;
 	u32 timeout;
-	int gpio_cs;
   };
 
 The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
@@ -146,7 +145,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
 	.rx_threshold = 8, /* SSP hardward FIFO threshold */
 	.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
 	.timeout = 235, /* See Intel documentation */
-	.gpio_cs = 2, /* Use external chip select */
   };
 
   static struct pxa2xx_spi_chip cs8405a_chip_info = {
@@ -154,7 +152,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
 	.rx_threshold = 8, /* SSP hardward FIFO threshold */
 	.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
 	.timeout = 235, /* See Intel documentation */
-	.gpio_cs = 3, /* Use external chip select */
   };
 
   static struct spi_board_info streetracer_spi_board_info[] __initdata = {
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 593c7f793da5..44659fbc37ba 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -530,6 +530,16 @@ static struct pxa2xx_spi_controller corgi_spi_info = {
 	.num_chipselect	= 3,
 };
 
+static struct gpiod_lookup_table corgi_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void corgi_wait_for_hsync(void)
 {
 	while (gpio_get_value(CORGI_GPIO_HSYNC))
@@ -548,10 +558,6 @@ static struct ads7846_platform_data corgi_ads7846_info = {
 	.wait_for_sync		= corgi_wait_for_hsync,
 };
 
-static struct pxa2xx_spi_chip corgi_ads7846_chip = {
-	.gpio_cs	= CORGI_GPIO_ADS7846_CS,
-};
-
 static void corgi_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -580,14 +586,6 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
 	.kick_battery		= corgi_bl_kick_battery,
 };
 
-static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
-	.gpio_cs	= CORGI_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip corgi_max1111_chip = {
-	.gpio_cs	= CORGI_GPIO_MAX1111_CS,
-};
-
 static struct spi_board_info corgi_spi_devices[] = {
 	{
 		.modalias	= "ads7846",
@@ -595,7 +593,6 @@ static struct spi_board_info corgi_spi_devices[] = {
 		.bus_num	= 1,
 		.chip_select	= 0,
 		.platform_data	= &corgi_ads7846_info,
-		.controller_data= &corgi_ads7846_chip,
 		.irq		= PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
 	}, {
 		.modalias	= "corgi-lcd",
@@ -603,18 +600,17 @@ static struct spi_board_info corgi_spi_devices[] = {
 		.bus_num	= 1,
 		.chip_select	= 1,
 		.platform_data	= &corgi_lcdcon_info,
-		.controller_data= &corgi_lcdcon_chip,
 	}, {
 		.modalias	= "max1111",
 		.max_speed_hz	= 450000,
 		.bus_num	= 1,
 		.chip_select	= 2,
-		.controller_data= &corgi_max1111_chip,
 	},
 };
 
 static void __init corgi_init_spi(void)
 {
+	gpiod_add_lookup_table(&corgi_spi_gpio_table);
 	pxa2xx_set_spi_info(1, &corgi_spi_info);
 	gpiod_add_lookup_table(&corgi_lcdcon_gpio_table);
 	spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 1d4c5db54be2..e1870fbb19e7 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -616,7 +616,6 @@ static struct pxa2xx_spi_chip tsc2046_chip = {
 	.tx_threshold = 1,
 	.rx_threshold = 2,
 	.timeout      = 64,
-	.gpio_cs      = GPIO88_HX4700_TSC2046_CS,
 };
 
 static struct spi_board_info tsc2046_board_info[] __initdata = {
@@ -635,6 +634,14 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
 	.enable_dma     = 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /*
  * External power
  */
@@ -896,6 +903,7 @@ static void __init hx4700_init(void)
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
 	i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
+	gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
 	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
 	spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
 
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 04a12523cdee..753fe166ab68 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -13,7 +13,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
-#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -42,7 +42,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS1
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
@@ -50,7 +49,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS2
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
@@ -58,7 +56,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS3
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
@@ -66,7 +63,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS4
 };
 
 static const struct property_entry mcp251x_properties[] = {
@@ -143,6 +139,24 @@ struct platform_device pxa_spi_ssp4 = {
 	}
 };
 
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+	.dev_id = "pxa2xx-spi.3",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
+	.dev_id = "pxa2xx-spi.4",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct platform_device *icontrol_spi_devices[] __initdata = {
 	&pxa_spi_ssp3,
 	&pxa_spi_ssp4,
@@ -175,6 +189,8 @@ static mfp_cfg_t mfp_can_cfg[] __initdata = {
 static void __init icontrol_can_init(void)
 {
 	pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+	gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
 	platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
 	spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
 }
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 793f61375ee8..73f5953b3bb6 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -195,7 +195,6 @@ static struct pxa2xx_spi_controller littleton_spi_info = {
 static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
 	.rx_threshold	= 1,
 	.tx_threshold	= 1,
-	.gpio_cs	= LITTLETON_GPIO_LCD_CS,
 };
 
 static struct spi_board_info littleton_spi_devices[] __initdata = {
@@ -208,8 +207,17 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
 	},
 };
 
+static struct gpiod_lookup_table littleton_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init littleton_init_spi(void)
 {
+	gpiod_add_lookup_table(&littleton_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &littleton_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index cd9fa465b9b2..200fd35168e0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -938,8 +938,6 @@ struct pxa2xx_spi_chip tsc2046_chip_info = {
 	.tx_threshold	= 1,
 	.rx_threshold	= 2,
 	.timeout	= 64,
-	/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
-	.gpio_cs	= GPIO14_MAGICIAN_TSC2046_CS,
 };
 
 static struct pxa2xx_spi_controller magician_spi_info = {
@@ -947,6 +945,15 @@ static struct pxa2xx_spi_controller magician_spi_info = {
 	.enable_dma	= 1,
 };
 
+static struct gpiod_lookup_table magician_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct spi_board_info ads7846_spi_board_info[] __initdata = {
 	{
 		.modalias		= "ads7846",
@@ -1031,6 +1038,7 @@ static void __init magician_init(void)
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
 
+	gpiod_add_lookup_table(&magician_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &magician_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 3a4ecc3c8f8b..58cfa434afde 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -197,6 +197,14 @@ static struct pxa2xx_spi_controller poodle_spi_info = {
 	.num_chipselect	= 1,
 };
 
+static struct gpiod_lookup_table poodle_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct ads7846_platform_data poodle_ads7846_info = {
 	.model			= 7846,
 	.vref_delay_usecs	= 100,
@@ -205,23 +213,19 @@ static struct ads7846_platform_data poodle_ads7846_info = {
 	.gpio_pendown		= POODLE_GPIO_TP_INT,
 };
 
-static struct pxa2xx_spi_chip poodle_ads7846_chip = {
-	.gpio_cs		= POODLE_GPIO_TP_CS,
-};
-
 static struct spi_board_info poodle_spi_devices[] = {
 	{
 		.modalias	= "ads7846",
 		.max_speed_hz	= 10000,
 		.bus_num	= 1,
 		.platform_data	= &poodle_ads7846_info,
-		.controller_data= &poodle_ads7846_chip,
 		.irq		= PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
 	},
 };
 
 static void __init poodle_init_spi(void)
 {
+	gpiod_add_lookup_table(&poodle_spi_gpio_table);
 	pxa2xx_set_spi_info(1, &poodle_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 371008e9bb02..a648e7094e84 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -510,10 +510,6 @@ static struct ads7846_platform_data spitz_ads7846_info = {
 	.wait_for_sync		= spitz_ads7846_wait_for_hsync,
 };
 
-static struct pxa2xx_spi_chip spitz_ads7846_chip = {
-	.gpio_cs		= SPITZ_GPIO_ADS7846_CS,
-};
-
 static void spitz_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -555,14 +551,6 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
 	.kick_battery		= spitz_bl_kick_battery,
 };
 
-static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
-	.gpio_cs	= SPITZ_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip spitz_max1111_chip = {
-	.gpio_cs	= SPITZ_GPIO_MAX1111_CS,
-};
-
 static struct spi_board_info spitz_spi_devices[] = {
 	{
 		.modalias		= "ads7846",
@@ -570,7 +558,6 @@ static struct spi_board_info spitz_spi_devices[] = {
 		.bus_num		= 2,
 		.chip_select		= 0,
 		.platform_data		= &spitz_ads7846_info,
-		.controller_data	= &spitz_ads7846_chip,
 		.irq			= PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
 	}, {
 		.modalias		= "corgi-lcd",
@@ -578,13 +565,11 @@ static struct spi_board_info spitz_spi_devices[] = {
 		.bus_num		= 2,
 		.chip_select		= 1,
 		.platform_data		= &spitz_lcdcon_info,
-		.controller_data	= &spitz_lcdcon_chip,
 	}, {
 		.modalias		= "max1111",
 		.max_speed_hz		= 450000,
 		.bus_num		= 2,
 		.chip_select		= 2,
-		.controller_data	= &spitz_max1111_chip,
 	},
 };
 
@@ -592,6 +577,16 @@ static struct pxa2xx_spi_controller spitz_spi_info = {
 	.num_chipselect	= 3,
 };
 
+static struct gpiod_lookup_table spitz_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init spitz_spi_init(void)
 {
 	if (machine_is_akita())
@@ -599,6 +594,7 @@ static void __init spitz_spi_init(void)
 	else
 		gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
 
+	gpiod_add_lookup_table(&spitz_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &spitz_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 8ca02ec1d44c..650043023006 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -346,6 +346,23 @@ static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
 	.num_chipselect = 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", 24, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+	.dev_id = "pxa2xx-spi.3",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", 39, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+
 /* An upcoming kernel change will scrap SFRM usage so these
  * drivers have been moved to use GPIOs */
 static struct pxa2xx_spi_chip staccel_chip_info = {
@@ -353,7 +370,6 @@ static struct pxa2xx_spi_chip staccel_chip_info = {
 	.rx_threshold = 8,
 	.dma_burst_size = 8,
 	.timeout = 235,
-	.gpio_cs = 24,
 };
 
 static struct pxa2xx_spi_chip cc2420_info = {
@@ -361,7 +377,6 @@ static struct pxa2xx_spi_chip cc2420_info = {
 	.rx_threshold = 8,
 	.dma_burst_size = 8,
 	.timeout = 235,
-	.gpio_cs = 39,
 };
 
 static struct spi_board_info spi_board_info[] __initdata = {
@@ -410,6 +425,8 @@ static void __init imote2_stargate2_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
+	gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
 	pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
 	pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
 	pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index 8e74fbb0a96e..7eaeda269927 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -570,7 +570,6 @@ static struct pxa2xx_spi_chip z2_lbs_chip_info = {
 	.rx_threshold	= 8,
 	.tx_threshold	= 8,
 	.timeout	= 1000,
-	.gpio_cs	= GPIO24_ZIPITZ2_WIFI_CS,
 };
 
 static struct libertas_spi_platform_data z2_lbs_pdata = {
@@ -584,7 +583,6 @@ static struct pxa2xx_spi_chip lms283_chip_info = {
 	.rx_threshold	= 1,
 	.tx_threshold	= 1,
 	.timeout	= 64,
-	.gpio_cs	= GPIO88_ZIPITZ2_LCD_CS,
 };
 
 static struct gpiod_lookup_table lms283_gpio_table = {
@@ -624,8 +622,26 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
 	.num_chipselect	= 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init z2_spi_init(void)
 {
+	gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
 	pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
 	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
 	gpiod_add_lookup_table(&lms283_gpio_table);
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index e88f86274eeb..b69c81f49031 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -13,7 +13,6 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -1163,57 +1162,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_controller *controller)
 	return 0;
 }
 
-static void cleanup_cs(struct spi_device *spi)
-{
-	if (!gpio_is_valid(spi->cs_gpio))
-		return;
-
-	gpio_free(spi->cs_gpio);
-	spi->cs_gpio = -ENOENT;
-}
-
-static int setup_cs(struct spi_device *spi, struct chip_data *chip,
-		    struct pxa2xx_spi_chip *chip_info)
-{
-	struct driver_data *drv_data = spi_controller_get_devdata(spi->controller);
-
-	if (chip == NULL)
-		return 0;
-
-	if (chip_info == NULL)
-		return 0;
-
-	if (drv_data->ssp_type == CE4100_SSP)
-		return 0;
-
-	/*
-	 * NOTE: setup() can be called multiple times, possibly with
-	 * different chip_info, release previously requested GPIO.
-	 */
-	cleanup_cs(spi);
-
-	if (gpio_is_valid(chip_info->gpio_cs)) {
-		int gpio = chip_info->gpio_cs;
-		int err;
-
-		err = gpio_request(gpio, "SPI_CS");
-		if (err) {
-			dev_err(&spi->dev, "failed to request chip select GPIO%d\n", gpio);
-			return err;
-		}
-
-		err = gpio_direction_output(gpio, !(spi->mode & SPI_CS_HIGH));
-		if (err) {
-			gpio_free(gpio);
-			return err;
-		}
-
-		spi->cs_gpio = gpio;
-	}
-
-	return 0;
-}
-
 static int setup(struct spi_device *spi)
 {
 	struct pxa2xx_spi_chip *chip_info;
@@ -1368,10 +1316,6 @@ static int setup(struct spi_device *spi)
 	if (drv_data->ssp_type == CE4100_SSP)
 		return 0;
 
-	err = setup_cs(spi, chip, chip_info);
-	if (err)
-		kfree(chip);
-
 	return err;
 }
 
@@ -1379,7 +1323,6 @@ static void cleanup(struct spi_device *spi)
 {
 	struct chip_data *chip = spi_get_ctldata(spi);
 
-	cleanup_cs(spi);
 	kfree(chip);
 }
 
diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h
index ca74dce36706..4658e7801b42 100644
--- a/include/linux/spi/pxa2xx_spi.h
+++ b/include/linux/spi/pxa2xx_spi.h
@@ -42,7 +42,6 @@ struct pxa2xx_spi_chip {
 	u8 rx_threshold;
 	u8 dma_burst_size;
 	u32 timeout;
-	int gpio_cs;
 };
 
 #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
-- 
2.34.1



From ming.qian at nxp.com  Thu Jan 20 17:48:05 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Fri, 21 Jan 2022 01:48:05 +0000
Subject: [EXT] Re: [PATCH v14 00/13] amphion video decoder/encoder driver
In-Reply-To: <d0540f65-ccc8-cfc8-d5c6-8dc40603b18d@xs4all.nl>
References: <cover.1638865027.git.ming.qian@nxp.com>
 <d0540f65-ccc8-cfc8-d5c6-8dc40603b18d@xs4all.nl>
Message-ID: <AM6PR04MB6341CA0D4EF44B279C5FD89EE75B9@AM6PR04MB6341.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Hans Verkuil [mailto:hverkuil-cisco at xs4all.nl]
> Sent: Thursday, January 20, 2022 10:44 PM
> To: Ming Qian <ming.qian at nxp.com>; mchehab at kernel.org;
> shawnguo at kernel.org; robh+dt at kernel.org; s.hauer at pengutronix.de
> Cc: kernel at pengutronix.de; festevam at gmail.com; dl-linux-imx
> <linux-imx at nxp.com>; Aisheng Dong <aisheng.dong at nxp.com>;
> linux-media at vger.kernel.org; linux-kernel at vger.kernel.org;
> devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: [EXT] Re: [PATCH v14 00/13] amphion video decoder/encoder driver
> 
> Caution: EXT Email
> 
> Hi Ming,
> 
> Running 'scripts/checkpatch.pl --strict' over the patches gives me lots of issues,
> most of them easily fixed.
> 
> As always with checkpatch, use common sense since not everything can be
> fixed.
> 
> You probably ran checkpatch.pl without the --strict option, but in the media
> subsystem we use that option.
> 
> Note that sparse and smatch are happy, so it is just the checkpatch issues that
> need to be improved.

Yes, I just run checkpatch.pl without the --strict option,
I'll fix the issues in v15.

> 
> On 12/7/21 09:24, Ming Qian wrote:
> > Hi all,
> >
> > This patch series adds support for
> > the amphion video encoder and decoder
> > via the VPU block present in imx8q platforms.
> > Currently, support for IMX8QXP and IMX8QM is included.
> >
> > It features decoding for the following formats:
> > - H.264
> > - HEVC
> > - MPEG4
> > - MPEG2
> > - VC1
> > - VP8
> >
> > It features encoding for the following formats:
> > - H.264
> >
> > The driver creates a separate device node for the encoder and decoder.
> >
> > This driver is dependent on vpu firmwares.
> > The firmwares have been submitted to linux-firmware.
> > The firmware patch is since commit
> > b563148fd28623f6b6ce68bb06c3dd3bd138b058:
> > linux-firmware: Update firmware file for Intel Bluetooth 9462 (Fri Oct
> > 8 16:30:14 2021 +0530)
> >
> > and it's available in the git repository at:
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> >
> ub.com%2Fmingqian-0%2Flinux-firmware.git&amp;data=04%7C01%7Cming.qi
> an%
> >
> 40nxp.com%7Ce806f02c9c204fab735408d9dc235f55%7C686ea1d3bc2b4c6fa
> 92cd99
> >
> c5c301635%7C0%7C1%7C637782866747675249%7CUnknown%7CTWFpbGZ
> sb3d8eyJWIjo
> >
> iMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C300
> 0&amp
> > ;sdata=tGdn4wXog4281rkjx%2FkS5Yu995uf1dKk%2B%2Fw7g%2B4hiCc%3D
> &amp;rese
> > rved=0
> >
> > for you to fetch changes up to
> bb3eee4f99589d4910dee4c053a3a685546b5dbb:
> > amphion: add VPU firmwares for NXP i.MX8Q SoCs (Tue Oct 12 15:09:57
> > 2021 +0800)
> >
> > encoder is tested with gstreamer
> > decoder is tested with gstreamer, but the following patches are required:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> >
> ab.freedesktop.org%2Fgstreamer%2Fgstreamer%2F-%2Fmerge_requests%2F1
> 379
> >
> &amp;data=04%7C01%7Cming.qian%40nxp.com%7Ce806f02c9c204fab73540
> 8d9dc23
> >
> 5f55%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C1%7C63778286674
> 7675249%7
> >
> CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBT
> iI6Ik1
> >
> haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Z%2B28N2DXrRHm1PFwWrpk
> 0koOSTVdqrm
> > qqY6fKbJuh34%3D&amp;reserved=0
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> >
> ab.freedesktop.org%2Fgstreamer%2Fgstreamer%2F-%2Fmerge_requests%2F1
> 381
> >
> &amp;data=04%7C01%7Cming.qian%40nxp.com%7Ce806f02c9c204fab73540
> 8d9dc23
> >
> 5f55%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C1%7C63778286674
> 7675249%7
> >
> CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBT
> iI6Ik1
> >
> haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=jitq4XO15%2BMux3jyVYGs0fp
> Lwxr7hbv
> > WAZad9TEGyso%3D&amp;reserved=0
> >
> >
> > Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> 
> For v15 please add this tag from Nicolas to the patch(es) that it applies to.
> Tags in the cover letter are ignored.cd 
> 
> Regarding patch 12/13 (firmware patch): who will take that? I think it should
> go through Shawn Guo, or if he can Ack it, then I can take it with the rest of
> the series as well.
> 
> Regards,
> 
>         Hans
> 
> >
> >
> > Changelog:
> >
> > v14
> > - fix some errors according to Hans's comments
> >
> > v13
> > - make a workaround that avoid firmware entering wfi wrongly
> >
> > v12
> > - support reset decoder when starting a new stream
> > - don't append an empty last buffer, set last_buffer_dequeued
> > - improve the resolution change flow
> > - return all buffers if start_streaming fail
> > - fill encoder capture buffer's filed to none
> > - fix a bug in calculating bytesperline
> >
> > v11
> > - fix dt_binding_check error after upgrade dtschema
> > - remove "default y"
> > - add media device
> >
> > v10
> > - refine vpu log, remove custom logging infrastructure
> > - support non contiguous planes format nv12m instead of nv12
> > - rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
> > - rename V4L2_PIX_FMT_NV12_10BE_8L128 to
> > V4L2_PIX_FMT_NV12MT_10BE_8L128
> > - merge two module into one
> > - fix kernel panic in rmmod
> >
> > v9
> > - drop V4L2_BUF_FLAG_CODECCONFIG
> > - drop V4L2_EVENT_CODEC_ERROR
> > - drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
> > - fix some build warnings with W=1 reported by kernel test robot
> >
> > v8
> > - move driver from driver/media/platform/imx/vpu-8q to
> >   driver/media/platform/amphion
> > - rename driver name to amphion
> > - remove imx_vpu.h
> > - move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
> > - move the definition of V4L2_EVENT_SKIP to videodev2.h
> >
> > v7
> > - fix build warnings with W=1 reported by kernel test robot
> >
> > v6:
> > - rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
> > - rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128
> >
> > v5:
> > - move some definition from imx_vph.h to videodev2.h
> > - remove some unnecessary content
> > - add some documentation descriptions
> > - pass the lateset v4l2-compliance test
> >
> > v4:
> > - redefine the memory-region in devicetree bindings documentation
> > - use v4l2's mechanism to implement synchronize queuing ioctl
> > - remove the unnecessary mutex ioctl_sync
> > - don't notify source change event if the parameters are same as
> > previously established
> > - add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format
> >
> > v3:
> > - don't make vpu device node a simple-bus
> > - trigger probing vpu core in the driver
> > - remove unnecessary vpu core index property
> >
> > v2:
> > - fix dt bindings build error
> > - split driver patch into several parts to avoid exceeding bytes limit
> >
> > Compliance
> > ==========
> > # v4l2-compliance -d /dev/video0
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/video0:
> >
> > Driver Info:
> >       Driver name      : amphion-vpu
> >       Card type        : amphion vpu decoder
> >       Bus info         : platform: amphion-vpu
> >       Driver version   : 5.15.0
> >       Capabilities     : 0x84204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >               Device Capabilities
> >       Device Caps      : 0x04204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >       Detected Stateful Decoder
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> > Interface Info:
> >       ID               : 0x0300000c
> >       Type             : V4L Video
> > Entity Info:
> >       ID               : 0x00000001 (1)
> >       Name             : amphion-vpu-decoder-source
> >       Function         : V4L2 I/O
> >       Pad 0x01000002   : 0: Source
> >         Link 0x02000008: to remote pad 0x1000004 of entity
> > 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable
> >
> > Required ioctls:
> >       test MC information (see 'Media Driver Info' above): OK
> >       test VIDIOC_QUERYCAP: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/video0 open: OK
> >       test VIDIOC_QUERYCAP: OK
> >       test VIDIOC_G/S_PRIORITY: OK
> >       test for unlimited opens: OK
> >
> > Debug ioctls:
> >       test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> >       test VIDIOC_LOG_STATUS: OK (Not Supported)
> >
> > Input ioctls:
> >       test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> >       test VIDIOC_ENUMAUDIO: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDIO: OK (Not Supported)
> >       Inputs: 0 Audio Inputs: 0 Tuners: 0
> >
> > Output ioctls:
> >       test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> >       Outputs: 0 Audio Outputs: 0 Modulators: 0
> >
> > Input/Output configuration ioctls:
> >       test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> >       test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> >       test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> >       test VIDIOC_G/S_EDID: OK (Not Supported)
> >
> > Control ioctls:
> >       test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> >       test VIDIOC_QUERYCTRL: OK
> >       test VIDIOC_G/S_CTRL: OK
> >       test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> >       test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> >       test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> >       Standard Controls: 3 Private Controls: 0
> >
> > Format ioctls:
> >       test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> >       test VIDIOC_G/S_PARM: OK (Not Supported)
> >       test VIDIOC_G_FBUF: OK (Not Supported)
> >       test VIDIOC_G_FMT: OK
> >       test VIDIOC_TRY_FMT: OK
> >       test VIDIOC_S_FMT: OK
> >       test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> >       test Cropping: OK (Not Supported)
> >       test Composing: OK
> >       test Scaling: OK (Not Supported)
> >
> > Codec ioctls:
> >       test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> >       test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> >       test VIDIOC_(TRY_)DECODER_CMD: OK
> >
> > Buffer ioctls:
> >       test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> >       test VIDIOC_EXPBUF: OK
> >       test Requests: OK (Not Supported)
> >
> > Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed:
> > 0, Warnings: 0
> >
> > # v4l2-compliance -d /dev/video1
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/video1:
> >
> > Driver Info:
> >       Driver name      : amphion-vpu
> >       Card type        : amphion vpu encoder
> >       Bus info         : platform: amphion-vpu
> >       Driver version   : 5.15.0
> >       Capabilities     : 0x84204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >               Device Capabilities
> >       Device Caps      : 0x04204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >       Detected Stateful Encoder
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> > Interface Info:
> >       ID               : 0x0300001a
> >       Type             : V4L Video
> > Entity Info:
> >       ID               : 0x0000000f (15)
> >       Name             : amphion-vpu-encoder-source
> >       Function         : V4L2 I/O
> >       Pad 0x01000010   : 0: Source
> >         Link 0x02000016: to remote pad 0x1000012 of entity
> > 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable
> >
> > Required ioctls:
> >       test MC information (see 'Media Driver Info' above): OK
> >       test VIDIOC_QUERYCAP: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/video1 open: OK
> >       test VIDIOC_QUERYCAP: OK
> >       test VIDIOC_G/S_PRIORITY: OK
> >       test for unlimited opens: OK
> >
> > Debug ioctls:
> >       test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> >       test VIDIOC_LOG_STATUS: OK (Not Supported)
> >
> > Input ioctls:
> >       test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> >       test VIDIOC_ENUMAUDIO: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDIO: OK (Not Supported)
> >       Inputs: 0 Audio Inputs: 0 Tuners: 0
> >
> > Output ioctls:
> >       test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> >       Outputs: 0 Audio Outputs: 0 Modulators: 0
> >
> > Input/Output configuration ioctls:
> >       test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> >       test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> >       test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> >       test VIDIOC_G/S_EDID: OK (Not Supported)
> >
> > Control ioctls:
> >       test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> >       test VIDIOC_QUERYCTRL: OK
> >       test VIDIOC_G/S_CTRL: OK
> >       test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> >       test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> >       test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> >       Standard Controls: 20 Private Controls: 0
> >
> > Format ioctls:
> >       test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> >       test VIDIOC_G/S_PARM: OK
> >       test VIDIOC_G_FBUF: OK (Not Supported)
> >       test VIDIOC_G_FMT: OK
> >       test VIDIOC_TRY_FMT: OK
> >       test VIDIOC_S_FMT: OK
> >       test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> >       test Cropping: OK
> >       test Composing: OK (Not Supported)
> >       test Scaling: OK (Not Supported)
> >
> > Codec ioctls:
> >       test VIDIOC_(TRY_)ENCODER_CMD: OK
> >       test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> >       test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
> >
> > Buffer ioctls:
> >       test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> >       test VIDIOC_EXPBUF: OK
> >       test Requests: OK (Not Supported)
> >
> > Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed:
> > 0, Warnings: 0
> >
> > # v4l2-compliance -d /dev/media0
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/media0:
> >
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> >
> > Required ioctls:
> >       test MEDIA_IOC_DEVICE_INFO: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/media0 open: OK
> >       test MEDIA_IOC_DEVICE_INFO: OK
> >       test for unlimited opens: OK
> >
> > Media Controller ioctls:
> >       test MEDIA_IOC_G_TOPOLOGY: OK
> >       Entities: 6 Interfaces: 2 Pads: 8 Links: 8
> >       test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
> >       test MEDIA_IOC_SETUP_LINK: OK
> >
> > Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0,
> > Warnings: 0
> >
> > Ming Qian (13):
> >   dt-bindings: media: amphion: add amphion video codec bindings
> >   media: add nv12m_8l128 and nv12m_10be_8l128 video format.
> >   media: amphion: add amphion vpu device driver
> >   media: amphion: add vpu core driver
> >   media: amphion: implement vpu core communication based on mailbox
> >   media: amphion: add vpu v4l2 m2m support
> >   media: amphion: add v4l2 m2m vpu encoder stateful driver
> >   media: amphion: add v4l2 m2m vpu decoder stateful driver
> >   media: amphion: implement windsor encoder rpc interface
> >   media: amphion: implement malone decoder rpc interface
> >   ARM64: dts: freescale: imx8q: add imx vpu codec entries
> >   firmware: imx: scu-pd: imx8q: add vpu mu resources
> >   MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
> >
> >  .../bindings/media/amphion,vpu.yaml           |  180 ++
> >  .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
> >  MAINTAINERS                                   |    9 +
> >  .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
> >  arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
> >  arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
> >  arch/arm64/configs/defconfig                  |    1 +
> >  drivers/firmware/imx/scu-pd.c                 |    4 +
> >  drivers/media/platform/Kconfig                |   19 +
> >  drivers/media/platform/Makefile               |    2 +
> >  drivers/media/platform/amphion/Makefile       |   20 +
> >  drivers/media/platform/amphion/vdec.c         | 1692
> +++++++++++++++++
> >  drivers/media/platform/amphion/venc.c         | 1354 +++++++++++++
> >  drivers/media/platform/amphion/vpu.h          |  356 ++++
> >  drivers/media/platform/amphion/vpu_cmds.c     |  437 +++++
> >  drivers/media/platform/amphion/vpu_cmds.h     |   25 +
> >  drivers/media/platform/amphion/vpu_codec.h    |   67 +
> >  drivers/media/platform/amphion/vpu_color.c    |  186 ++
> >  drivers/media/platform/amphion/vpu_core.c     |  872 +++++++++
> >  drivers/media/platform/amphion/vpu_core.h     |   15 +
> >  drivers/media/platform/amphion/vpu_dbg.c      |  497 +++++
> >  drivers/media/platform/amphion/vpu_defs.h     |  186 ++
> >  drivers/media/platform/amphion/vpu_drv.c      |  260 +++
> >  drivers/media/platform/amphion/vpu_helpers.c  |  416 ++++
> >  drivers/media/platform/amphion/vpu_helpers.h  |   70 +
> >  drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
> >  drivers/media/platform/amphion/vpu_imx8q.h    |  116 ++
> >  drivers/media/platform/amphion/vpu_malone.c   | 1630
> ++++++++++++++++
> >  drivers/media/platform/amphion/vpu_malone.h   |   42 +
> >  drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
> >  drivers/media/platform/amphion/vpu_mbox.h     |   16 +
> >  drivers/media/platform/amphion/vpu_msgs.c     |  388 ++++
> >  drivers/media/platform/amphion/vpu_msgs.h     |   14 +
> >  drivers/media/platform/amphion/vpu_rpc.c      |  265 +++
> >  drivers/media/platform/amphion/vpu_rpc.h      |  453 +++++
> >  drivers/media/platform/amphion/vpu_v4l2.c     |  733 +++++++
> >  drivers/media/platform/amphion/vpu_v4l2.h     |   56 +
> >  drivers/media/platform/amphion/vpu_windsor.c  | 1207 ++++++++++++
> >  drivers/media/platform/amphion/vpu_windsor.h  |   39 +
> >  drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
> >  include/uapi/linux/videodev2.h                |    2 +
> >  41 files changed, 12158 insertions(+), 3 deletions(-)  create mode
> > 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
> >  create mode 100644 drivers/media/platform/amphion/Makefile
> >  create mode 100644 drivers/media/platform/amphion/vdec.c
> >  create mode 100644 drivers/media/platform/amphion/venc.c
> >  create mode 100644 drivers/media/platform/amphion/vpu.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_codec.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_color.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_core.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_core.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_defs.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_drv.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_malone.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_malone.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_windsor.h
> >
> >
> > base-commit: 1f1517fafda598839a02e39968c5063ddcfa51fc


From ck.hu at mediatek.com  Thu Jan 20 18:08:47 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 21 Jan 2022 10:08:47 +0800
Subject: [PATCH v1, 1/1] soc: mediatek: cmdq: add cmdq_pkt_poll_addr
 function
In-Reply-To: <20220120074311.2243-2-yongqiang.niu@mediatek.com>
References: <20220120074311.2243-1-yongqiang.niu@mediatek.com>
 <20220120074311.2243-2-yongqiang.niu@mediatek.com>
Message-ID: <e4328a0fd2c97d073793532d238abd781797fe13.camel@mediatek.com>

Hi, Yongqiang:

On Thu, 2022-01-20 at 15:43 +0800, Yongqiang Niu wrote:
> From: mtk18742 <moudy.ho at mediatek.com>
> 
> add cmdq_pkt_poll_addr function in cmdq helper functions
> 
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-cmdq-helper.c   | 39
> ++++++++++++++++++++++++
>  include/linux/mailbox/mtk-cmdq-mailbox.h |  1 +
>  include/linux/soc/mediatek/mtk-cmdq.h    |  2 ++
>  3 files changed, 42 insertions(+)
> 
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c
> b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 3c8e4212d941..6c5cfb284140 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -344,6 +344,45 @@ int cmdq_pkt_set_event(struct cmdq_pkt *pkt, u16
> event)
>  }
>  EXPORT_SYMBOL(cmdq_pkt_set_event);
>  
> +s32 cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, u32 value, u32 addr,
> u32 mask, u8 reg_gpr)
> +{
> +	struct cmdq_instruction inst = { {0} };
> +
> +	s32 err;
> +
> +	if (mask != 0xffffffff) {
> +		inst.op = CMDQ_CODE_MASK;
> +		inst.mask = ~mask;
> +		err = cmdq_pkt_append_command(pkt, inst);
> +		if (err != 0)
> +			return err;
> +
> +		addr = addr | 0x1;
> +	}
> +
> +	/* Move extra handle APB address to GPR */
> +	inst.op = CMDQ_CODE_MOVE;
> +	inst.value = addr;
> +	inst.sop = reg_gpr;
> +	inst.dst_t = 1;
> +	err = cmdq_pkt_append_command(pkt, inst);
> +	if (err != 0)
> +		pr_err("%s fail append command move addr to reg
> err:%d",
> +			__func__, err);

cmdq_pkt_assign() could assign a value to GPR, so remove this part.

> +
> +	inst.op = CMDQ_CODE_POLL;
> +	inst.value = value;
> +	inst.sop = reg_gpr;
> +	inst.dst_t = 1;
> +	err = cmdq_pkt_append_command(pkt, inst);
> +	if (err != 0)
> +		pr_err("%s fail append command poll err:%d",
> +			__func__, err);
> +
> +	return err;
> +}
> +EXPORT_SYMBOL(cmdq_pkt_poll_addr);
> +
>  int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
>  		  u16 offset, u32 value)
>  {
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h
> b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index 44365aab043c..a27329fd7c7f 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -54,6 +54,7 @@
>   */
>  enum cmdq_code {
>  	CMDQ_CODE_MASK = 0x02,
> +	CMDQ_CODE_MOVE = 0x02,
>  	CMDQ_CODE_WRITE = 0x04,
>  	CMDQ_CODE_POLL = 0x08,
>  	CMDQ_CODE_JUMP = 0x10,
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h
> b/include/linux/soc/mediatek/mtk-cmdq.h
> index ac6b5f3cba95..28dc5ce0ff03 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -280,4 +280,6 @@ int cmdq_pkt_finalize(struct cmdq_pkt *pkt);
>  int cmdq_pkt_flush_async(struct cmdq_pkt *pkt, cmdq_async_flush_cb
> cb,
>  			 void *data);
>  

Add comment for this function, parameters, and return value like other
interface.

Regards,
CK

> +s32 cmdq_pkt_poll_addr(struct cmdq_pkt *pkt, u32 value, u32 addr,
> u32 mask, u8 reg_gpr);
> +
>  #endif	/* __MTK_CMDQ_H__ */



From anshuman.khandual at arm.com  Thu Jan 20 18:28:39 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 21 Jan 2022 07:58:39 +0530
Subject: [PATCH 1/2] arm64: mm: apply __ro_after_init to memory_limit
In-Reply-To: <20211215064559.2843555-1-peng.fan@oss.nxp.com>
References: <20211215064559.2843555-1-peng.fan@oss.nxp.com>
Message-ID: <3204def4-df7b-4a0c-1b8d-045ead96f0b2@arm.com>



On 12/15/21 12:15 PM, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> This variable is only set during initialization, so mark with
> __ro_after_init.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  arch/arm64/mm/init.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index a8834434af99..db63cc885771 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -172,7 +172,7 @@ int pfn_is_map_memory(unsigned long pfn)
>  }
>  EXPORT_SYMBOL(pfn_is_map_memory);
>  
> -static phys_addr_t memory_limit = PHYS_ADDR_MAX;
> +static phys_addr_t memory_limit __ro_after_init = PHYS_ADDR_MAX;
>  
>  /*
>   * Limit the memory size that was specified via FDT.
> 

Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>


From yu.tu at amlogic.com  Thu Jan 20 18:51:56 2022
From: yu.tu at amlogic.com (Yu Tu)
Date: Fri, 21 Jan 2022 10:51:56 +0800
Subject: [PATCH V6 3/5] tty: serial: meson: Describes the calculation of
 the UART baud rate clock using a clock frame
In-Reply-To: <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <20220118030911.12815-4-yu.tu@amlogic.com>
 <1jfspi2i5s.fsf@starbuckisacylon.baylibre.com>
Message-ID: <9d8ff96b-8a1d-6778-cb71-1e5855303f8a@amlogic.com>

Hi Jerome ,
	Thank you very much for your reply.
	At present, it is found that after using CCF to describe baud rate 
clock, when using stty to change baud rate, the situation will be stuck. 
  If initcall_debug is enabled, the initialization of the UART driver 
takes longer . Shall we discuss this first and change it as you suggest? 
I have replied to Kevin about this question yesterday.
Do you need to discuss it? What should I do next?

On 2022/1/21 5:40, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Tue 18 Jan 2022 at 11:09, Yu Tu <yu.tu at amlogic.com> wrote:
> 
>> Using the common Clock code to describe the UART baud rate clock
>> makes it easier for the UART driver to be compatible with the
>> baud rate requirements of the UART IP on different meson chips.
>>
>> Signed-off-by: Yu Tu <yu.tu at amlogic.com>
>> ---
>>   drivers/tty/serial/meson_uart.c | 195 +++++++++++++++++++++++---------
>>   1 file changed, 142 insertions(+), 53 deletions(-)
>>
>> diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c
>> index 7570958d010c..92fa91c825e6 100644
>> --- a/drivers/tty/serial/meson_uart.c
>> +++ b/drivers/tty/serial/meson_uart.c
>> @@ -6,6 +6,7 @@
>>    */
>>   
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/console.h>
>>   #include <linux/delay.h>
>>   #include <linux/init.h>
>> @@ -65,9 +66,7 @@
>>   #define AML_UART_RECV_IRQ(c)		((c) & 0xff)
>>   
>>   /* AML_UART_REG5 bits */
>> -#define AML_UART_BAUD_MASK		0x7fffff
>>   #define AML_UART_BAUD_USE		BIT(23)
>> -#define AML_UART_BAUD_XTAL		BIT(24)
>>   
>>   #define AML_UART_PORT_NUM		12
>>   #define AML_UART_PORT_OFFSET		6
>> @@ -76,6 +75,11 @@
>>   #define AML_UART_POLL_USEC		5
>>   #define AML_UART_TIMEOUT_USEC		10000
>>   
>> +struct meson_uart_data {
>> +	struct clk	*baud_clk;
>> +	bool		use_xtal_clk;
>> +};
>> +
>>   static struct uart_driver meson_uart_driver;
>>   
>>   static struct uart_port *meson_ports[AML_UART_PORT_NUM];
>> @@ -293,19 +297,17 @@ static int meson_uart_startup(struct uart_port *port)
>>   
>>   static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>>   	u32 val;
>>   
>>   	while (!meson_uart_tx_empty(port))
>>   		cpu_relax();
>>   
>> -	if (port->uartclk == 24000000) {
>> -		val = ((port->uartclk / 3) / baud) - 1;
>> -		val |= AML_UART_BAUD_XTAL;
>> -	} else {
>> -		val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
>> -	}
>> +	val = readl(port->membase + AML_UART_REG5);
>>   	val |= AML_UART_BAUD_USE;
>>   	writel(val, port->membase + AML_UART_REG5);
>> +
>> +	clk_set_rate(private_data->baud_clk, baud);
>>   }
>>   
>>   static void meson_uart_set_termios(struct uart_port *port,
>> @@ -395,11 +397,20 @@ static int meson_uart_verify_port(struct uart_port *port,
>>   
>>   static void meson_uart_release_port(struct uart_port *port)
>>   {
>> -	/* nothing to do */
>> +	struct meson_uart_data *private_data = port->private_data;
>> +
>> +	clk_disable_unprepare(private_data->baud_clk);
>>   }
>>   
>>   static int meson_uart_request_port(struct uart_port *port)
>>   {
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	int ret;
>> +
>> +	ret = clk_prepare_enable(private_data->baud_clk);
>> +	if (ret)
>> +		return ret;
>> +
>>   	return 0;
>>   }
>>   
>> @@ -629,57 +640,105 @@ static struct uart_driver meson_uart_driver = {
>>   	.cons		= MESON_SERIAL_CONSOLE,
>>   };
>>   
>> -static inline struct clk *meson_uart_probe_clock(struct device *dev,
>> -						 const char *id)
>> -{
>> -	struct clk *clk = NULL;
>> -	int ret;
>> -
>> -	clk = devm_clk_get(dev, id);
>> -	if (IS_ERR(clk))
>> -		return clk;
>> -
>> -	ret = clk_prepare_enable(clk);
>> -	if (ret) {
>> -		dev_err(dev, "couldn't enable clk\n");
>> -		return ERR_PTR(ret);
>> -	}
>> -
>> -	devm_add_action_or_reset(dev,
>> -			(void(*)(void *))clk_disable_unprepare,
>> -			clk);
>> -
>> -	return clk;
>> -}
>> +static struct clk_div_table xtal_div_table[] = {
>> +	{0, 3},
>> +	{1, 1},
>> +	{2, 2},
>> +	{3, 2},
>> +};
>>   
>> -static int meson_uart_probe_clocks(struct platform_device *pdev,
>> -				   struct uart_port *port)
>> +static int meson_uart_probe_clocks(struct uart_port *port)
>>   {
>> -	struct clk *clk_xtal = NULL;
>> -	struct clk *clk_pclk = NULL;
>> -	struct clk *clk_baud = NULL;
>> +	struct meson_uart_data *private_data = port->private_data;
>> +	struct clk *clk_baud, *clk_xtal;
>> +	struct clk_hw *hw;
>> +	char clk_name[32];
>> +	struct clk_parent_data use_xtal_mux_parents[2] = {
>> +		{ .index = -1, },
>> +		{ .index = -1, },
>> +	};
> 
> You are using hw pointers later, you don't need to init the index to -1
> I think
> 
>>   
>> -	clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
>> -	if (IS_ERR(clk_pclk))
>> -		return PTR_ERR(clk_pclk);
>> +	clk_baud = devm_clk_get(port->dev, "baud");
>> +	if (IS_ERR(clk_baud)) {
>> +		dev_err(port->dev, "Failed to get the 'baud' clock\n");
>> +		return PTR_ERR(clk_baud);
>> +	}
>>   
>> -	clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
>> +	clk_xtal = devm_clk_get(port->dev, "xtal");
>>   	if (IS_ERR(clk_xtal))
>> -		return PTR_ERR(clk_xtal);
>> -
>> -	clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
>> -	if (IS_ERR(clk_baud))
>> -		return PTR_ERR(clk_baud);
>> +		return dev_err_probe(port->dev, PTR_ERR(clk_xtal),
>> +				     "Failed to get the 'xtal' clock\n");
>> +
>> +	if (private_data->use_xtal_clk) {
>> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +			 "xtal_div");
>> +		hw = devm_clk_hw_register_divider_table(port->dev,
>> +							clk_name,
>> +							__clk_get_name(clk_baud),
>> +							CLK_SET_RATE_NO_REPARENT,
>> +							port->membase + AML_UART_REG5,
>> +							26, 2,
>> +							CLK_DIVIDER_READ_ONLY,
>> +							xtal_div_table, NULL);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[1].hw = hw;
>> +	} else {
>> +		snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +			 "clk81_div4");
>> +		hw = devm_clk_hw_register_fixed_factor(port->dev,
>> +						       clk_name,
>> +						       __clk_get_name(clk_baud),
>> +						       CLK_SET_RATE_NO_REPARENT,
>> +						       1, 4);
>> +		if (IS_ERR(hw))
>> +			return PTR_ERR(hw);
>> +
>> +		use_xtal_mux_parents[0].hw = hw;
>> +	}
> 
> The above is still wrong.
> 
> use_xtal_mux_parents initialize both parent to nothing
> And you init the parent in the conditional above.
> It is means only one path is actually set instead of both.
> 
> The mux always has 2 sources - Both should be set regardless of the HW version
> You just add
> * /4 on path 0 on legacy SoC
> * the funky divider on path 1 on newer SoC.
> 
>>   
>> -	port->uartclk = clk_get_rate(clk_baud);
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 "use_xtal");
>> +	hw = __devm_clk_hw_register_mux(port->dev, NULL,
>> +					clk_name,
>> +					ARRAY_SIZE(use_xtal_mux_parents),
>> +					NULL, NULL,
>> +					use_xtal_mux_parents,
>> +					CLK_SET_RATE_PARENT,
>> +					port->membase + AML_UART_REG5,
>> +					24, 0x1,
>> +					CLK_MUX_READ_ONLY,
>> +					NULL, NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	port->uartclk = clk_hw_get_rate(hw);
>> +
>> +	snprintf(clk_name, sizeof(clk_name), "%s#%s", dev_name(port->dev),
>> +		 "baud_div");
>> +	hw = devm_clk_hw_register_divider(port->dev,
>> +					  clk_name,
>> +					  clk_hw_get_name(hw),
>> +					  CLK_SET_RATE_PARENT,
>> +					  port->membase + AML_UART_REG5,
>> +					  0, 23,
>> +					  CLK_DIVIDER_ROUND_CLOSEST,
>> +					  NULL);
>> +	if (IS_ERR(hw))
>> +		return PTR_ERR(hw);
>> +
>> +	private_data->baud_clk = hw->clk;
>>   
>>   	return 0;
>>   }
>>   
>>   static int meson_uart_probe(struct platform_device *pdev)
>>   {
>> +	struct meson_uart_data *private_data;
>>   	struct resource *res_mem;
>>   	struct uart_port *port;
>> +	struct clk *pclk;
>>   	u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */
>>   	int ret = 0;
>>   	int irq;
>> @@ -705,6 +764,15 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	if (!res_mem)
>>   		return -ENODEV;
>>   
>> +	pclk = devm_clk_get(&pdev->dev, "pclk");
>> +	if (IS_ERR(pclk))
>> +		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
>> +				     "Failed to get the 'pclk' clock\n");
>> +
>> +	ret = clk_prepare_enable(pclk);
>> +	if (ret)
>> +		return ret;
>> +
> 
> I think this is unbalanced.
> 
>>   	irq = platform_get_irq(pdev, 0);
>>   	if (irq < 0)
>>   		return irq;
>> @@ -724,9 +792,13 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	if (IS_ERR(port->membase))
>>   		return PTR_ERR(port->membase);
>>   
>> -	ret = meson_uart_probe_clocks(pdev, port);
>> -	if (ret)
>> -		return ret;
>> +	private_data = devm_kzalloc(&pdev->dev, sizeof(*private_data),
>> +				    GFP_KERNEL);
>> +	if (!private_data)
>> +		return -ENOMEM;
>> +
>> +	if (device_get_match_data(&pdev->dev))
>> +		private_data->use_xtal_clk = true;
>>   
>>   	port->iotype = UPIO_MEM;
>>   	port->mapbase = res_mem->start;
>> @@ -740,6 +812,11 @@ static int meson_uart_probe(struct platform_device *pdev)
>>   	port->x_char = 0;
>>   	port->ops = &meson_uart_ops;
>>   	port->fifosize = fifosize;
>> +	port->private_data = private_data;
>> +
>> +	ret = meson_uart_probe_clocks(port);
>> +	if (ret)
>> +		return ret;
>>   
>>   	meson_ports[pdev->id] = port;
>>   	platform_set_drvdata(pdev, port);
>> @@ -766,10 +843,22 @@ static int meson_uart_remove(struct platform_device *pdev)
>>   }
>>   
>>   static const struct of_device_id meson_uart_dt_match[] = {
>> -	{ .compatible = "amlogic,meson6-uart" },
>> -	{ .compatible = "amlogic,meson8-uart" },
>> -	{ .compatible = "amlogic,meson8b-uart" },
>> -	{ .compatible = "amlogic,meson-gx-uart" },
>> +	{
>> +		.compatible = "amlogic,meson6-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8b-uart",
>> +		.data = (void *)false,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gx-uart",
>> +		.data = (void *)true,
>> +	},
>>   	{ /* sentinel */ },
>>   };
>>   MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
> 


From jason-jh.lin at mediatek.com  Thu Jan 20 18:45:25 2022
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Fri, 21 Jan 2022 10:45:25 +0800
Subject: [PATCH v14 08/12] soc: mediatek: add mtk-mmsys support for
 mt8195 vdosys0
In-Reply-To: <20220107101425.6917-9-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-9-jason-jh.lin@mediatek.com>
Message-ID: <91feaca3440e50855d43e6474560c5656c21ffed.camel@mediatek.com>

Hi Matthias,

mtk-mmsys and mtk-mutex needs your review....
Could you please spare a little time to review these patches?

Thank you very much!

Regards,
Jason-JH.Lin

On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> Add mt8195 vdosys0 clock driver name and routing table to
> the driver data of mtk-mmsys.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
> The vdosys1 impelmentation patch [1] will be dependened on this
> patch.
> [1] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
> - 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20211208024426.15595-6-nancy.lin at mediatek.com/
> ---
>  drivers/soc/mediatek/mt8195-mmsys.h    | 220
> +++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       |  11 ++
>  include/linux/soc/mediatek/mtk-mmsys.h |   9 +
>  3 files changed, 240 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> 
> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> b/drivers/soc/mediatek/mt8195-mmsys.h
> new file mode 100644
> index 000000000000..e04cabdfa2dc
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> @@ -0,0 +1,220 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> +
> +#define MT8195_VDO0_OVL_MOUT_EN					
> 0xf14
> +/*
> + * MT8195_VDO0_OVL_MOUT[2:0]: DISP_OVL0
> + *   BIT(0) : DISP_RDMA0
> + *   BIT(1) : DISP_WDMA0
> + *   BIT(2): DISP_OVL1
> + */
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> +/*
> + * MT8195_VDO0_OVL_MOUT[6:4]: DISP_OVL1
> + *   BIT(0) : DISP_RDMA1
> + *   BIT(1) : DISP_WDMA1
> + *   BIT(2): DISP_OVL0
> + */
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
> +
> +#define MT8195_VDO0_SEL_IN					0xf34
> +/*
> + * MT8195_VDO0_SEL_IN[1:0]: VPP_MERGE
> + *   0 : DSC_WRAP0_OUT
> + *   1 : DISP_DITHER1
> + *   2: VDO1_VIRTUAL0
> + */
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		0
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		BIT(0)
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		BIT(1)
> +/*
> + * MT8195_VDO0_SEL_IN[4:4]: DSC_WRAP0_IN
> + *   0: DISP_DITHER0
> + *   1: VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		0
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		BIT(4)
> +/*
> + * MT8195_VDO0_SEL_IN[5:5]: DSC_WRAP1_IN
> + *   0: DISP_DITHER1
> + *   1: VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		0
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		BIT(5)
> +/*
> + * MT8195_VDO0_SEL_IN[8:8]: SINA_VIRTUAL0
> + *   0: VPP_MERGE
> + *   1: DSC_WRAP1_OUT
> + */
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		0
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		
> BIT(8)
> +/*
> + * MT8195_VDO0_SEL_IN[9:9]: SINB_VIRTUAL0
> + *   0: DSC_WRAP0_OUT
> + */
> +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		
> 0
> +/*
> + * MT8195_VDO0_SEL_IN[13:12]: DP_INTF0
> + *   0 : DSC_WRAP1_OUT
> + *   1 : VPP_MERGE
> + *   2: VDO1_VIRTUAL0
> + */
> +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		0
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			
> BIT(12)
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		BIT(13)
> +/*
> + * MT8195_VDO0_SEL_IN[16:16]: DSI0
> + *   0 : DSC_WRAP0_OUT
> + *   1 : DISP_DITHER0
> + */
> +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			
> 0
> +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			BIT(16)
> +/*
> + * MT8195_VDO0_SEL_IN[17:17]: DSI1
> + *   0 : DSC_WRAP1_OUT
> + *   1 : VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			
> 0
> +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			BIT(17)
> +/*
> + * MT8195_VDO0_SEL_IN[20:20]: DISP_WDMA1
> + *   0 : DISP_OVL1
> + *   1 : VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			
> 0
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			
> BIT(20)
> +/*
> + * MT8195_VDO0_SEL_IN[21:21]: DSC_WRAP1_OUT
> + *   0 : DSC_WRAP1_IN
> + *   1 : DITHER1
> + */
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		
> (0)
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		
> BIT(21)
> +/*
> + * MT8195_VDO0_SEL_IN[22:22]: DISP_WDMA0
> + *   0 : DISP_OVL0
> + */
> +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			
> 0
> +
> +#define MT8195_VDO0_SEL_OUT					0xf38
> +/*
> + * MT8195_VDO0_SOUT[0:0]: DISP_DITHER0
> + *   0 : DSC_WRAP0_IN
> + *   1 : DSI0
> + */
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		0
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			BIT(0)
> +/*
> + * MT8195_VDO0_SOUT[1:1]: DISP_DITHER1
> + *   0 : DSC_WRAP1_IN
> + *   1 : VPP_MERGE
> + *   2 : DSC_WRAP1_OUT
> + */
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		0
> +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			
> BIT(1)
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		BIT(2)
> +/*
> + * MT8195_VDO0_SOUT[4:4]: VDO1_VIRTUAL0
> + *   0 : VPP_MERGE
> + *   1 : DP_INTF0
> + */
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			
> 0
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			
> BIT(4)
> +/*
> + * MT8195_VDO0_SOUT[10:8]: VPP_MERGE
> + *   0 : DSI1
> + *   1 : DP_INTF0
> + *   2 : SINA_VIRTUAL0
> + *   3 : DISP_WDMA1
> + *   4 : DSC_WRAP0_IN
> + */
> +#define MT8195_SOUT_VPP_MERGE_TO_DSI1				
> 0
> +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			BIT(8)
> +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			
> BIT(9)
> +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(BIT(9)
> | BIT(8))
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			
> BIT(10)
> +/*
> + * MT8195_VDO0_SOUT[11:11]: VPP_MERGE
> + *  0 : DSC_WRAP1_IN
> + */
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			
> 0
> +/*
> + * MT8195_VDO0_SOUT[13:12]: DSC_WRAP0_OUT
> + *  0 : DSI0
> + *  1 : SINB_VIRTUAL0
> + *  2 : VPP_MERGE
> + */
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			0
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		BIT(12)
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			
> BIT(13)
> +/*
> + * MT8195_VDO0_SOUT[17:16]: DSC_WRAP1_OUT
> + *  0 : DSI1
> + *  1 : DP_INTF0
> + *  2 : SINA_VIRTUAL0
> + *  3 : VPP_MERGE
> + */
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			0
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			
> BIT(16)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		BIT(17)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			
> (BIT(17) | BIT(16))
> +
> +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] =
> {
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
> +		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> +	}, {
> +		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
> +		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
> +		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,
> +		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
> +		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
> +		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
> +		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
> +		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
> +	}
> +};
> +
> +#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> b/drivers/soc/mediatek/mtk-mmsys.c
> index 5f79c7e039ad..5865d268c5b4 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -18,6 +18,7 @@
>  #include "mt8167-mmsys.h"
>  #include "mt8183-mmsys.h"
>  #include "mt8192-mmsys.h"
> +#include "mt8195-mmsys.h"
>  #include "mt8365-mmsys.h"
>  
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data =
> {
> @@ -66,6 +67,12 @@ static const struct mtk_mmsys_driver_data
> mt8192_mmsys_driver_data = {
>  	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
>  };
>  
> +static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data
> = {
> +	.clk_driver = "clk-mt8195-vdo0",
> +	.routes = mmsys_mt8195_routing_table,
> +	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> +};
> +
>  static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data =
> {
>  	.clk_driver = "clk-mt8365-mm",
>  	.routes = mt8365_mmsys_routing_table,
> @@ -391,6 +398,10 @@ static const struct of_device_id
> of_match_mtk_mmsys[] = {
>  		.compatible = "mediatek,mt8192-mmsys",
>  		.data = &mt8192_mmsys_driver_data,
>  	},
> +	{
> +		.compatible = "mediatek,mt8195-vdosys0",
> +		.data = &mt8195_vdosys0_driver_data,
> +	},
>  	{
>  		.compatible = "mediatek,mt8365-mmsys",
>  		.data = &mt8365_mmsys_driver_data,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> b/include/linux/soc/mediatek/mtk-mmsys.h
> index 45e77d1cd6c1..c0ba22ad7229 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -23,13 +23,22 @@ enum mtk_ddp_comp_id {
>  	DDP_COMPONENT_COLOR0,
>  	DDP_COMPONENT_COLOR1,
>  	DDP_COMPONENT_DITHER,
> +	DDP_COMPONENT_DP_INTF0,
>  	DDP_COMPONENT_DPI0,
>  	DDP_COMPONENT_DPI1,
> +	DDP_COMPONENT_DSC0,
> +	DDP_COMPONENT_DSC1,
>  	DDP_COMPONENT_DSI0,
>  	DDP_COMPONENT_DSI1,
>  	DDP_COMPONENT_DSI2,
>  	DDP_COMPONENT_DSI3,
>  	DDP_COMPONENT_GAMMA,
> +	DDP_COMPONENT_MERGE0,
> +	DDP_COMPONENT_MERGE1,
> +	DDP_COMPONENT_MERGE2,
> +	DDP_COMPONENT_MERGE3,
> +	DDP_COMPONENT_MERGE4,
> +	DDP_COMPONENT_MERGE5,
>  	DDP_COMPONENT_OD0,
>  	DDP_COMPONENT_OD1,
>  	DDP_COMPONENT_OVL0,
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>



From yury.norov at gmail.com  Thu Jan 20 18:56:16 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Thu, 20 Jan 2022 18:56:16 -0800
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <5b62ed03-8da8-a94d-cc48-a8cac1eae1c9@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <Yedgj+Lo2eru8197@casper.infradead.org>
 <cfe4c63e-57c0-2a9d-c3e9-959bc77b87c6@arm.com>
 <CAAH8bW_=KtrwLpg4tx+1tdMjN2mUiuLOoZH6nvbn8qNjU6aB3A@mail.gmail.com>
 <5b62ed03-8da8-a94d-cc48-a8cac1eae1c9@arm.com>
Message-ID: <CAAH8bW_wL7=7+Jj6vXmQSe_az0BvS_otxhBe4LOKU5fcJV9aXQ@mail.gmail.com>

On Wed, Jan 19, 2022 at 7:37 PM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
>
>
> On 1/19/22 10:52 PM, Yury Norov wrote:
> >> Why should not this just scan over the entire user provided struct page
> >> array and make sure that all pages there in are valid via above method,
> >> but in vmap() itself before calling vmap_pages_range(). Because seems
> >> like a single invalid page detected in vmap_pages_pte_range() will
> >> anyways abort the entire vmap(). This will also enable us to drop the
> >> existing NULL check above.
> >
> > I can do this, but why is it any better than the current approach?
>
> Because it will just return on the first instance where the valid page
> check fails, saving us some CPU cycles and an incomplete mapping ?

This should normally never happen, that's why warn_on() is there. If it
happens, there is a serious problem, and the code must be fixed. So,
no CPU cycles saving in real life.


From lkp at intel.com  Thu Jan 20 19:31:12 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 21 Jan 2022 11:31:12 +0800
Subject: [xilinx-xlnx:master 129/395]
 drivers/clk/clk-xlnx-clock-wizard-v.c:164:16: error: implicit declaration of
 function 'FIELD_GET'; did you mean 'FOLL_GET'?
Message-ID: <202201211116.bvPrCZMH-lkp@intel.com>

Hi Shubhrajyoti,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6057b70444aa27680466a4b33d68b18f415d495b
commit: c1e2db426dc728a5417024c9bd75c39ec81331d9 [129/395] clocking-wizard: Support higher frequency accuracy
config: powerpc-allmodconfig (https://download.01.org/0day-ci/archive/20220121/202201211116.bvPrCZMH-lkp at intel.com/config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/c1e2db426dc728a5417024c9bd75c39ec81331d9
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout c1e2db426dc728a5417024c9bd75c39ec81331d9
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=powerpc SHELL=/bin/bash drivers/clk/ drivers/media/platform/xilinx/ drivers/phy/xilinx/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_recalc_rate_all':
>> drivers/clk/clk-xlnx-clock-wizard-v.c:164:16: error: implicit declaration of function 'FIELD_GET'; did you mean 'FOLL_GET'? [-Werror=implicit-function-declaration]
     164 |         regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
         |                ^~~~~~~~~
         |                FOLL_GET
   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_get_divisors':
   drivers/clk/clk-xlnx-clock-wizard-v.c:229:25: warning: this decimal constant is unsigned only in ISO C90
     229 |                         if (vco_freq >= WZRD_VCO_MIN && vco_freq <= WZRD_VCO_MAX) {
         |                         ^~
   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_dynamic_all_nolock':
>> drivers/clk/clk-xlnx-clock-wizard-v.c:276:19: error: implicit declaration of function 'FIELD_PREP' [-Werror=implicit-function-declaration]
     276 |         regval1 = FIELD_PREP(WZRD_DIVCLK_EDGE, edged);
         |                   ^~~~~~~~~~
   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_recalc_rate':
   drivers/clk/clk-xlnx-clock-wizard-v.c:342:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     342 |                         (void __iomem *)((u64)divider->base + divider->offset);
         |                                          ^
   drivers/clk/clk-xlnx-clock-wizard-v.c:342:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     342 |                         (void __iomem *)((u64)divider->base + divider->offset);
         |                         ^
   drivers/clk/clk-xlnx-clock-wizard-v.c: In function 'clk_wzrd_dynamic_reconfig':
   drivers/clk/clk-xlnx-clock-wizard-v.c:375:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     375 |                         (void __iomem *)((u64)divider->base + divider->offset);
         |                                          ^
   drivers/clk/clk-xlnx-clock-wizard-v.c:375:25: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
     375 |                         (void __iomem *)((u64)divider->base + divider->offset);
         |                         ^
   cc1: some warnings being treated as errors


vim +164 drivers/clk/clk-xlnx-clock-wizard-v.c

   154	
   155	static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
   156						      unsigned long parent_rate)
   157	{
   158		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   159		u32 edged, div, div2, p5en, edge, prediv2, all, regl, regh, mult, reg;
   160	
   161		edge = !!(readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_1)) & WZRD_CLKFBOUT_EDGE);
   162	
   163		reg = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_2));
 > 164		regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
   165		regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
   166	
   167		mult = regl + regh + edge;
   168		if (!mult)
   169			mult = 1;
   170	
   171		regl = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_4)) &
   172			     WZRD_CLKFBOUT_FRAC_EN;
   173		if (regl) {
   174			regl = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_3)) &
   175				WZRD_CLKFBOUT_FRAC_MASK;
   176			mult = mult * WZRD_FRAC_GRADIENT + regl;
   177			parent_rate = DIV_ROUND_CLOSEST((parent_rate * mult), WZRD_FRAC_GRADIENT);
   178		} else {
   179			parent_rate = parent_rate * mult;
   180		}
   181	
   182		/* O Calculation */
   183		reg = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKOUT0_1));
   184		edged = FIELD_GET(WZRD_CLKFBOUT_EDGE, reg);
   185		p5en = FIELD_GET(WZRD_P5EN, reg);
   186		prediv2 = FIELD_GET(WZRD_CLKOUT0_PREDIV2, reg);
   187	
   188		reg = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKOUT0_2));
   189		/* Low time */
   190		regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
   191		/* High time */
   192		regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
   193		all = regh + regl + edged;
   194		if (!all)
   195			all = 1;
   196	
   197		if (prediv2)
   198			div2 = PREDIV2_MULT * all + p5en;
   199		else
   200			div2 = all;
   201	
   202		/* D calculation */
   203		edged = !!(readl(divider->base + WZRD_CLK_CFG_REG(WZRD_DESKEW_2)) &
   204			     WZRD_DIVCLK_EDGE);
   205		reg = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_DIVCLK));
   206		/* Low time */
   207		regl = FIELD_GET(WZRD_CLKFBOUT_L_MASK, reg);
   208		/* High time */
   209		regh = FIELD_GET(WZRD_CLKFBOUT_H_MASK, reg);
   210		div = regl + regh + edged;
   211		if (!div)
   212			div = 1;
   213	
   214		div = div * div2;
   215		return divider_recalc_rate(hw, parent_rate, div, divider->table,
   216				divider->flags, divider->width);
   217	}
   218	
   219	static int clk_wzrd_get_divisors(struct clk_hw *hw, unsigned long rate,
   220					 unsigned long parent_rate)
   221	{
   222		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   223		u64 vco_freq, freq, diff;
   224		u32 m, d, o;
   225	
   226		for (m = WZRD_M_MIN; m <= WZRD_M_MAX; m++) {
   227			for (d = WZRD_D_MIN; d <= WZRD_D_MAX; d++) {
   228				vco_freq = DIV_ROUND_CLOSEST((parent_rate * m), d);
   229				if (vco_freq >= WZRD_VCO_MIN && vco_freq <= WZRD_VCO_MAX) {
   230					for (o = WZRD_O_MIN; o <= WZRD_O_MAX; o++) {
   231						freq = DIV_ROUND_CLOSEST(vco_freq, o);
   232						diff = abs(freq - rate);
   233	
   234						if (diff < WZRD_MIN_ERR) {
   235							divider->valuem = m;
   236							divider->valued = d;
   237							divider->valueo = o;
   238							return 0;
   239						}
   240					}
   241				}
   242			}
   243		}
   244		return -EBUSY;
   245	}
   246	
   247	static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
   248					       unsigned long parent_rate)
   249	{
   250		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   251		u32 value, regh, edged, p5en, p5fedge, value2, m, regval, regval1;
   252		int err;
   253	
   254		err = clk_wzrd_get_divisors(hw, rate, parent_rate);
   255		if (err)
   256			return err;
   257	
   258		writel(0, divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_4));
   259	
   260		m = divider->valuem;
   261		edged = m % WZRD_DUTY_CYCLE;
   262		regh = m / WZRD_DUTY_CYCLE;
   263		regval1 = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_1));
   264		regval1 |= WZRD_MULT_PREDIV2;
   265		if (edged)
   266			regval1 = regval1 | WZRD_CLKFBOUT_EDGE;
   267		else
   268			regval1 = regval1 & ~WZRD_CLKFBOUT_EDGE;
   269		writel(regval1, divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_1));
   270		regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
   271		writel(regval1, divider->base + WZRD_CLK_CFG_REG(WZRD_CLKFBOUT_2));
   272	
   273		value2 = divider->valued;
   274		edged = value2 % WZRD_DUTY_CYCLE;
   275		regh = (value2 / WZRD_DUTY_CYCLE);
 > 276		regval1 = FIELD_PREP(WZRD_DIVCLK_EDGE, edged);
   277		writel(regval1, divider->base + WZRD_CLK_CFG_REG(WZRD_DESKEW_2));
   278		regval1 = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
   279		writel(regval1, divider->base + WZRD_CLK_CFG_REG(WZRD_DIVCLK));
   280	
   281		value = divider->valueo;
   282		regh = value / WZRD_O_DIV;
   283		regval1 = readl(divider->base + WZRD_CLK_CFG_REG(WZRD_CLKOUT0_1));
   284		regval1 |= WZRD_CLKFBOUT_PREDIV2;
   285		regval1 = regval1 & ~(WZRD_CLKFBOUT_EDGE | WZRD_P5EN | WZRD_P5FEDGE);
   286		if (value % WZRD_O_DIV > 1) {
   287			edged = 1;
   288			regval1 |= edged << WZRD_CLKFBOUT_H_SHIFT;
   289		}
   290		p5fedge = value % WZRD_DUTY_CYCLE;
   291		p5en = value % WZRD_DUTY_CYCLE;
   292	
   293		regval1 = regval1 | FIELD_PREP(WZRD_P5EN, p5en) | FIELD_PREP(WZRD_P5FEDGE, p5fedge);
   294		writel(regval1, divider->base + WZRD_CLK_CFG_REG(WZRD_CLKOUT0_1));
   295		regval = regh | regh << WZRD_CLKFBOUT_H_SHIFT;
   296		writel(regval, divider->base + WZRD_CLK_CFG_REG(WZRD_CLKOUT0_2));
   297	
   298		/* Check status register */
   299		err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
   300					 value, value & WZRD_DR_LOCK_BIT_MASK,
   301					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
   302		if (err)
   303			return err;
   304	
   305		/* Initiate reconfiguration */
   306		writel(WZRD_DR_BEGIN_DYNA_RECONF,
   307		       divider->base + WZRD_DR_INIT_REG_OFFSET);
   308	
   309		/* Check status register */
   310		return  readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET,
   311					 value, value & WZRD_DR_LOCK_BIT_MASK,
   312					 WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
   313	}
   314	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From xueshuai at linux.alibaba.com  Thu Jan 20 19:43:25 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Fri, 21 Jan 2022 11:43:25 +0800
Subject: [PATCH v6] ACPI: explicit init HEST, SDEI and GHES in apci_init
In-Reply-To: <20220120162241.GA1047212@bhelgaas>
References: <20220120162241.GA1047212@bhelgaas>
Message-ID: <4c34906a-244e-3956-0ca7-7131b268cf60@linux.alibaba.com>

Hi, Bjorn,

Thank you for your comments.

? 2022/1/21 AM12:22, Bjorn Helgaas ??:
> On Thu, Jan 20, 2022 at 01:05:22PM +0800, Shuai Xue wrote:
>> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
>> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
>> the estatus memory pool. On the other hand, ghes_init() relies on
>> sdei_init() to detect the SDEI version and (un)register events. The
>> dependencies are as follows:
>>
>>     ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
>>     ghes_init() => sdei_init()
>>
>> HEST is not PCI-specific and initcall ordering is implicit and not
>> well-defined within a level.
>>
>> Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
>> convert ghes_init() and sdei_init() from initcalls to explicit calls in the
>> following order:
>>
>>     acpi_hest_init()
>>     sdei_init()
>>     ghes_init()
>>
>> Suggested-by: Bjorn Helgaas <helgaas at kernel.org>
> 
> I didn't suggest the approach; I just reviewed the patch and the
> commit log and proposed moving it out of acpi_pci_root_init().  That
> doesn't need to be acknowledged.

I will delete it in next version :)

>> Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
> 
> Reviewed-by: Bjorn Helgaas <bhelgaas at google.com>

Will add this in next version.


> Minor extra "return" below. 
>> ---
>>  drivers/acpi/apei/ghes.c    | 17 +++++++----------
>>  drivers/acpi/bus.c          |  4 ++++
>>  drivers/acpi/pci_root.c     |  3 ---
>>  drivers/firmware/arm_sdei.c | 13 ++-----------
>>  include/acpi/apei.h         |  4 +++-
>>  include/linux/arm_sdei.h    |  2 ++
>>  6 files changed, 18 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
>> index 0c5c9acc6254..bed4f10cfcb8 100644
>> --- a/drivers/acpi/apei/ghes.c
>> +++ b/drivers/acpi/apei/ghes.c
>> @@ -1457,33 +1457,33 @@ static struct platform_driver ghes_platform_driver = {
>>  	.remove		= ghes_remove,
>>  };
>>  
>> -static int __init ghes_init(void)
>> +void __init ghes_init(void)
>>  {
>>  	int rc;
>>  
>>  	if (acpi_disabled)
>> -		return -ENODEV;
>> +		return;
>>  
>>  	switch (hest_disable) {
>>  	case HEST_NOT_FOUND:
>> -		return -ENODEV;
>> +		return;
>>  	case HEST_DISABLED:
>>  		pr_info(GHES_PFX "HEST is not enabled!\n");
>> -		return -EINVAL;
>> +		return;
>>  	default:
>>  		break;
>>  	}
>>  
>>  	if (ghes_disable) {
>>  		pr_info(GHES_PFX "GHES is not enabled!\n");
>> -		return -EINVAL;
>> +		return;
>>  	}
>>  
>>  	ghes_nmi_init_cxt();
>>  
>>  	rc = platform_driver_register(&ghes_platform_driver);
>>  	if (rc)
>> -		goto err;
>> +		return;
>>  
>>  	rc = apei_osc_setup();
>>  	if (rc == 0 && osc_sb_apei_support_acked)
>> @@ -1495,8 +1495,5 @@ static int __init ghes_init(void)
>>  	else
>>  		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
>>  
>> -	return 0;
>> -err:
>> -	return rc;
>> +	return;
> 
> Unnecessary "return".

Will fix it in next version.

> 
>>  }
>> -device_initcall(ghes_init);
>> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
>> index 07f604832fd6..1dcd71df2cd5 100644
>> --- a/drivers/acpi/bus.c
>> +++ b/drivers/acpi/bus.c
>> @@ -30,6 +30,7 @@
>>  #include <linux/acpi_viot.h>
>>  #include <linux/pci.h>
>>  #include <acpi/apei.h>
>> +#include <linux/arm_sdei.h>
> 
> This "arm" looks a little out of place in this supposedly arch-generic
> code.  Not really a new thing with this patch, since this #include
> already appears in drivers/acpi/apei/ghes.c.  Maybe it's unavoidable.

Yep, should we move sdei_init() into the beginning of ghes_init()?

> sdei_init() and ghes_init() stick out here because they're the only
> functions without an "acpi_" prefix.  Maybe a separate patch to rename
> them?

Sorry, I forgot to send a patch to rename them. I have a question about this.

> Software Delegated Exception Interface (|SDEI|) is an Arm specification for
> Non-secure world to register handlers with firmware to receive notifications
> about system events.
> LINK: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/sdei.rst

I think SDEI is not a ACPI Specification but Arm specification so we should
not rename sdei_init() with an "acpi_" prefix.  If we move sdei_init() into
ghes_init(), and rename ghes_init() to acpi_ghes_init(), then all looks
fine? What's your opinion, Bjorn?

Best Regards.

Shuai

> 
>>  #include <linux/suspend.h>
>>  #include <linux/prmt.h>
>>  
>> @@ -1331,6 +1332,9 @@ static int __init acpi_init(void)
>>  
>>  	pci_mmcfg_late_init();
>>  	acpi_iort_init();
>> +	acpi_hest_init();
>> +	sdei_init();
>> +	ghes_init();
>>  	acpi_scan_init();
>>  	acpi_ec_init();
>>  	acpi_debugfs_init();
>> diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
>> index b76db99cced3..6f9e75d14808 100644
>> --- a/drivers/acpi/pci_root.c
>> +++ b/drivers/acpi/pci_root.c
>> @@ -22,8 +22,6 @@
>>  #include <linux/slab.h>
>>  #include <linux/dmi.h>
>>  #include <linux/platform_data/x86/apple.h>
>> -#include <acpi/apei.h>	/* for acpi_hest_init() */
>> -
>>  #include "internal.h"
>>  
>>  #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
>> @@ -943,7 +941,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
>>  
>>  void __init acpi_pci_root_init(void)
>>  {
>> -	acpi_hest_init();
>>  	if (acpi_pci_disabled)
>>  		return;
>>  
>> diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
>> index a7e762c352f9..1e1a51510e83 100644
>> --- a/drivers/firmware/arm_sdei.c
>> +++ b/drivers/firmware/arm_sdei.c
>> @@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
>>  	return true;
>>  }
>>  
>> -static int __init sdei_init(void)
>> +void __init sdei_init(void)
>>  {
>>  	struct platform_device *pdev;
>>  	int ret;
>>  
>>  	ret = platform_driver_register(&sdei_driver);
>>  	if (ret || !sdei_present_acpi())
>> -		return ret;
>> +		return;
>>  
>>  	pdev = platform_device_register_simple(sdei_driver.driver.name,
>>  					       0, NULL, 0);
>> @@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
>>  		pr_info("Failed to register ACPI:SDEI platform device %d\n",
>>  			ret);
>>  	}
>> -
>> -	return ret;
>>  }
>>  
>> -/*
>> - * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
>> - * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
>> - * by device_initcall(). We want to be called in the middle.
>> - */
>> -subsys_initcall_sync(sdei_init);
>> -
>>  int sdei_event_handler(struct pt_regs *regs,
>>  		       struct sdei_registered_event *arg)
>>  {
>> diff --git a/include/acpi/apei.h b/include/acpi/apei.h
>> index ece0a8af2bae..4e60dd73c3bb 100644
>> --- a/include/acpi/apei.h
>> +++ b/include/acpi/apei.h
>> @@ -27,14 +27,16 @@ extern int hest_disable;
>>  extern int erst_disable;
>>  #ifdef CONFIG_ACPI_APEI_GHES
>>  extern bool ghes_disable;
>> +void __init ghes_init(void);
>>  #else
>>  #define ghes_disable 1
>> +static inline void ghes_init(void) { }
>>  #endif
>>  
>>  #ifdef CONFIG_ACPI_APEI
>>  void __init acpi_hest_init(void);
>>  #else
>> -static inline void acpi_hest_init(void) { return; }
>> +static inline void acpi_hest_init(void) { }
>>  #endif
>>  
>>  int erst_write(const struct cper_record_header *record);
>> diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
>> index 0a241c5c911d..14dc461b0e82 100644
>> --- a/include/linux/arm_sdei.h
>> +++ b/include/linux/arm_sdei.h
>> @@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
>>  /* For use by arch code when CPU hotplug notifiers are not appropriate. */
>>  int sdei_mask_local_cpu(void);
>>  int sdei_unmask_local_cpu(void);
>> +void __init sdei_init(void);
>>  #else
>>  static inline int sdei_mask_local_cpu(void) { return 0; }
>>  static inline int sdei_unmask_local_cpu(void) { return 0; }
>> +static inline void sdei_init(void) { }
>>  #endif /* CONFIG_ARM_SDE_INTERFACE */
>>  
>>  
>> -- 
>> 2.20.1.12.g72788fdb
>>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From f.fainelli at gmail.com  Thu Jan 20 19:51:52 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 20 Jan 2022 19:51:52 -0800
Subject: [BUG] bcm2711: bad_chained_irq in brcmstb_l2_intc_irq_handle
In-Reply-To: <8a040749-e4fa-8b9d-e3e9-377a1e6f27a0@gmail.com>
References: <330c4d09-3ba7-dfc7-25a7-4840b2ea6784@i2se.com>
 <20220120153928.yvkrqduoytddvegs@houat>
 <84253e32-8dbf-dc2e-f44f-4555b8888f8c@i2se.com>
 <409091e8-abec-ce90-a247-246167223d92@gmail.com>
 <dc990eae-506c-5f4e-efde-ec483c6f9aa9@i2se.com>
 <8a040749-e4fa-8b9d-e3e9-377a1e6f27a0@gmail.com>
Message-ID: <85dc13e0-b309-6cf1-e132-6fe5d9dbe88e@gmail.com>



On 1/20/2022 1:38 PM, Florian Fainelli wrote:
> 
> 
> On 1/20/2022 1:23 PM, Stefan Wahren wrote:
>> Hi,
>>
>> Am 20.01.22 um 20:48 schrieb Florian Fainelli:
>>>
>>> Can we get the full dump of the Device Tree that you are running with?
>>> Something like:
>>>
>>> dtc -I fs /proc/device-tree -O dts > live.dts
>>>
>>> would be helpful to figure out what is going on here.
>>
>> sorry guys, i assumed that the Arch people know what they do. I figured
>> out that they mixed the vendor DTB with the mainline kernel.
> 
> No worries, it's always good to be thrown debugging exercises :), glad 
> you figured it out.

The kernel could have been a bit more verbose about that error case, let 
me try to reproduce this locally with a maliciously crafted DTB and see 
if we can detect an attempt to register a flow handler on an existing 
interrupt descriptor, and vice versa.

Thanks!
-- 
Florian


From yury.norov at gmail.com  Thu Jan 20 21:26:18 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Thu, 20 Jan 2022 21:26:18 -0800
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
 <Yeg79CcofyNuVLid@casper.infradead.org>
 <e9226eb4-4ecf-ac01-e823-ff507a354ac5@arm.com>
 <YehilqRvYLhryUk4@shell.armlinux.org.uk>
 <319b09bc-56a2-207f-6180-3cc7d8cd43d1@arm.com>
 <Yeldih0PHotN4/bn@shell.armlinux.org.uk>
 <e6fde086-16b9-430f-5510-5296ef74a4e7@arm.com>
Message-ID: <CAAH8bW8zPpWxSG6OXoudhBo3oYZJV7dFzO6CQRSixMPxk6VQnw@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:37 AM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2022-01-20 13:03, Russell King (Oracle) wrote:
> > On Thu, Jan 20, 2022 at 12:22:35PM +0000, Robin Murphy wrote:
> >> On 2022-01-19 19:12, Russell King (Oracle) wrote:
> >>> On Wed, Jan 19, 2022 at 06:43:10PM +0000, Robin Murphy wrote:
> >>>> Indeed, my impression is that the only legitimate way to get hold of a page
> >>>> pointer without assumed provenance is via pfn_to_page(), which is where
> >>>> pfn_valid() comes in. Thus pfn_valid(page_to_pfn()) really *should* be a
> >>>> tautology.
> >>>
> >>> That can only be true if pfn == page_to_pfn(pfn_to_page(pfn)) for all
> >>> values of pfn.
> >>>
> >>> Given how pfn_to_page() is defined in the sparsemem case:
> >>>
> >>> #define __pfn_to_page(pfn)                              \
> >>> ({  unsigned long __pfn = (pfn);                    \
> >>>     struct mem_section *__sec = __pfn_to_section(__pfn);    \
> >>>     __section_mem_map_addr(__sec) + __pfn;          \
> >>> })
> >>> #define page_to_pfn __page_to_pfn
> >>>
> >>> that isn't the case, especially when looking at page_to_pfn():
> >>>
> >>> #define __page_to_pfn(pg)                                       \
> >>> ({      const struct page *__pg = (pg);                         \
> >>>           int __sec = page_to_section(__pg);                      \
> >>>     (unsigned long)(__pg - __section_mem_map_addr(__nr_to_section(__sec))); \
> >>> })
> >>>
> >>> Where:
> >>>
> >>> static inline unsigned long page_to_section(const struct page *page)
> >>> {
> >>>     return (page->flags >> SECTIONS_PGSHIFT) & SECTIONS_MASK;
> >>> }
> >>>
> >>> So if page_to_section() returns something that is, e.g. zero for an
> >>> invalid page in a non-zero section, you're not going to end up with
> >>> the right pfn from page_to_pfn().
> >>
> >> Right, I emphasised "should" in an attempt to imply "in the absence of
> >> serious bugs that have further-reaching consequences anyway".
> >>
> >>> As I've said now a couple of times, trying to determine of a struct
> >>> page pointer is valid is the wrong question to be asking.
> >>
> >> And doing so in one single place, on the justification of avoiding an
> >> incredibly niche symptom, is even more so. Not to mention that an address
> >> size fault is one of the best possible outcomes anyway, vs. the untold
> >> damage that may stem from accesses actually going through to random parts of
> >> the physical memory map.

It's not a single place. Many exported functions check arguments this
way or another.
__vunmap() in vfree() path, for example, checks for address alignment, which is
quite similar to me. And later even makes BUG_ON(!page).

> > I don't see it as a "niche" symptom.
>
> The commit message specifically cites a Data Abort "at address
> translation later". Broadly speaking, a Data Abort due to an address
> size fault only occurs if you've been lucky enough that the bogus PA
> which got mapped is so spectacularly wrong that it's beyond the range
> configured in TCR.IPS. How many other architectures even have a
> mechanism like that?
>
> > If we start off with the struct page being invalid, then the result of
> > page_to_pfn() can not be relied upon to produce something that is
> > meaningful - which is exactly why the vmap() issue arises.
> >
> > With a pfn_valid() check, we at least know that the PFN points at
> > memory.
>
> No, we know it points to some PA space which has a struct page to
> represent it. pfn_valid() only says that pfn_to_page() will yield a
> valid result. That also includes things like reserved pages covering
> non-RAM areas, where a kernel VA mapping existing at all could
> potentially be fatal to the system even if it's never explicitly
> accessed - for all we know it might be a carveout belonging to
> overly-aggressive Secure software such that even a speculative prefetch
> might trigger an instant system reset.
>
> > However, that memory could be _anything_ in the system - it
> > could be the kernel image, and it could give userspace access to
> > change kernel code.
> >
> > So, while it is useful to do a pfn_valid() check in vmap(), as I said
> > to willy, this must _not_ be the primary check. It should IMHO use
> > WARN_ON() to make it blatently obvious that it should be something we
> > expect _not_ to trigger under normal circumstances, but is there to
> > catch programming errors elsewhere.

It actually uses WARN_ON().

> Rather, "to partially catch unrelated programming errors elsewhere,
> provided the buggy code happens to call vmap() rather than any of the
> many other functions with a struct page * argument." That's where it
> stretches my definition of "useful" just a bit too far. It's not about
> perfect being the enemy of good, it's about why vmap() should be
> special, and death by a thousand "useful" cuts - if we don't trust the
> pointer, why not check its alignment for basic plausibility first?

Because in that particular case pfn_valid() is enough. If someone else
will have a real case where IS_ALIGNED() would help - I will be all for
adding that check in vmap().

>  If it
> seems valid, why not check if the page flags look sensible to make sure?
> How many useful little checks is too many?

I'd put in 'too many' group those that test for something that never happened
to people.

> Every bit of code footprint
> and execution overhead imposed unconditionally on all end users to
> theoretically save developers' debugging time still adds up.

Not theoretically - practically!

End users will value kernel stability even when buggy drivers are installed.
They will also value developers who fix bugs quickly. It has been noticed that
DEBUG_VIRTUAL could catch this bug. But sometimes stopping the production
hardware, building a custom kernel with many debug options in the hope that
one of them will help, and running a suspicious driver for hours would take
itself for more than a day.

Thanks,
Yury

> Although on
> that note, it looks like arch/arm's pfn_valid() is still a linear scan
> of the memblock array, so the overhead of adding that for every page in
> every vmap() might not even be so small...
>
> Robin.


From o.rempel at pengutronix.de  Thu Jan 20 21:43:14 2022
From: o.rempel at pengutronix.de (Oleksij Rempel)
Date: Fri, 21 Jan 2022 06:43:14 +0100
Subject: [PATCH] dt-bindings: i2c: imx: Make each example a separate entry
In-Reply-To: <20220119015253.2437352-1-robh@kernel.org>
References: <20220119015253.2437352-1-robh@kernel.org>
Message-ID: <20220121054314.GA19904@pengutronix.de>

On Tue, Jan 18, 2022 at 07:52:53PM -0600, Rob Herring wrote:
> Each independent example should be a separate entry. This allows for
> 'interrupts' to have different cell sizes.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>

Reviewed-by: Oleksij Rempel <o.rempel at pengutronix.de>

Thank you!

> ---
>  Documentation/devicetree/bindings/i2c/i2c-imx.yaml | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
> index c167958ae2a9..01720e338b4c 100644
> --- a/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
> +++ b/Documentation/devicetree/bindings/i2c/i2c-imx.yaml
> @@ -88,9 +88,7 @@ unevaluatedProperties: false
>  examples:
>    - |
>      #include <dt-bindings/clock/imx5-clock.h>
> -    #include <dt-bindings/clock/vf610-clock.h>
> -    #include <dt-bindings/gpio/gpio.h>
> -    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
>  
>      i2c at 83fc4000 {
>          compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
> @@ -99,6 +97,9 @@ examples:
>          clocks = <&clks IMX5_CLK_I2C2_GATE>;
>      };
>  
> +  - |
> +    #include <dt-bindings/clock/vf610-clock.h>
> +
>      i2c at 40066000 {
>          compatible = "fsl,vf610-i2c";
>          reg = <0x40066000 0x1000>;
> -- 
> 2.32.0
> 
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From lkp at intel.com  Thu Jan 20 21:45:27 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 21 Jan 2022 13:45:27 +0800
Subject: [xilinx-xlnx:master 173/395]
 drivers/clk/clk-xlnx-clock-wizard.c:324:8: error: implicit declaration of
 function 'FIELD_PREP'
Message-ID: <202201211331.u58BkUAq-lkp@intel.com>

Hi Shubhrajyoti,

FYI, the error/warning still remains.

tree:   https://github.com/Xilinx/linux-xlnx master
head:   6057b70444aa27680466a4b33d68b18f415d495b
commit: bf7387ee9a75c2a390b19f63c47076344e664b86 [173/395] clocking-wizard: Support higher frequency accuracy
config: i386-randconfig-a015-20211031 (https://download.01.org/0day-ci/archive/20220121/202201211331.u58BkUAq-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 82ed106567063ea269c6d5669278b733e173a42f)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/Xilinx/linux-xlnx/commit/bf7387ee9a75c2a390b19f63c47076344e664b86
        git remote add xilinx-xlnx https://github.com/Xilinx/linux-xlnx
        git fetch --no-tags xilinx-xlnx master
        git checkout bf7387ee9a75c2a390b19f63c47076344e664b86
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/clk/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/clk/clk-xlnx-clock-wizard.c:324:8: error: implicit declaration of function 'FIELD_PREP' [-Werror,-Wimplicit-function-declaration]
           reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
                 ^
>> drivers/clk/clk-xlnx-clock-wizard.c:392:6: error: implicit declaration of function 'FIELD_GET' [-Werror,-Wimplicit-function-declaration]
           d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
               ^
   2 errors generated.


vim +/FIELD_PREP +324 drivers/clk/clk-xlnx-clock-wizard.c

   301	
   302	static int clk_wzrd_dynamic_all_nolock(struct clk_hw *hw, unsigned long rate,
   303					       unsigned long parent_rate)
   304	{
   305		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   306		u32 reg, pre;
   307		u16 retries;
   308		int err;
   309		u64 vco_freq, rate_div, f, clockout0_div;
   310	
   311		err = clk_wzrd_get_divisors(hw, rate, parent_rate);
   312		if (err)
   313			pr_err("failed to get divisors\n");
   314	
   315		vco_freq = DIV_ROUND_CLOSEST((parent_rate * divider->valuem), divider->valued);
   316		rate_div = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   317	
   318		clockout0_div = rate_div / WZRD_FRAC_POINTS;
   319	
   320		pre = DIV_ROUND_CLOSEST((vco_freq * WZRD_FRAC_POINTS), rate);
   321		f = (u32)(pre - (clockout0_div * WZRD_FRAC_POINTS));
   322		f = f & WZRD_CLKOUT_FRAC_MASK;
   323	
 > 324		reg = FIELD_PREP(WZRD_CLKOUT_DIVIDE_MASK, clockout0_div) |
   325		      FIELD_PREP(WZRD_CLKOUT0_FRAC_MASK, f);
   326	
   327		writel(reg, divider->base + WZRD_CLK_CFG_REG(2));
   328		/* Set divisor and clear phase offset */
   329		reg = FIELD_PREP(WZRD_CLKFBOUT_MULT_MASK, divider->valuem) |
   330		      FIELD_PREP(WZRD_DIVCLK_DIVIDE_MASK, divider->valued);
   331		writel(reg, divider->base + WZRD_CLK_CFG_REG(0));
   332		writel(divider->valueo, divider->base + WZRD_CLK_CFG_REG(2));
   333		writel(0, divider->base + WZRD_CLK_CFG_REG(3));
   334		/* Check status register */
   335		retries = WZRD_DR_NUM_RETRIES;
   336		while (retries--) {
   337			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   338								WZRD_DR_LOCK_BIT_MASK)
   339				break;
   340		}
   341	
   342		if (!retries)
   343			return -ETIMEDOUT;
   344	
   345		/* Initiate reconfiguration */
   346		writel(WZRD_DR_BEGIN_DYNA_RECONF,
   347		       divider->base + WZRD_DR_INIT_REG_OFFSET);
   348	
   349		/* Check status register */
   350		retries = WZRD_DR_NUM_RETRIES;
   351		while (retries--) {
   352			if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
   353								WZRD_DR_LOCK_BIT_MASK)
   354				break;
   355		}
   356	
   357		if (!retries)
   358			return -ETIMEDOUT;
   359	
   360		return 0;
   361	}
   362	
   363	static int clk_wzrd_dynamic_all(struct clk_hw *hw, unsigned long rate,
   364					unsigned long parent_rate)
   365	{
   366		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   367		unsigned long flags = 0;
   368		int ret;
   369	
   370		if (divider->lock)
   371			spin_lock_irqsave(divider->lock, flags);
   372		else
   373			__acquire(divider->lock);
   374	
   375		ret = clk_wzrd_dynamic_all_nolock(hw, rate, parent_rate);
   376	
   377		if (divider->lock)
   378			spin_unlock_irqrestore(divider->lock, flags);
   379		else
   380			__release(divider->lock);
   381	
   382		return ret;
   383	}
   384	
   385	static unsigned long clk_wzrd_recalc_rate_all(struct clk_hw *hw,
   386						      unsigned long parent_rate)
   387	{
   388		struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
   389		u32 m, d, o, div, reg, f;
   390	
   391		reg = readl(divider->base + WZRD_CLK_CFG_REG(0));
 > 392		d = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   393		m = FIELD_GET(WZRD_CLKFBOUT_MULT_MASK, reg);
   394		reg = readl(divider->base + WZRD_CLK_CFG_REG(2));
   395		o = FIELD_GET(WZRD_DIVCLK_DIVIDE_MASK, reg);
   396		f = FIELD_GET(WZRD_CLKOUT0_FRAC_MASK, reg);
   397	
   398		div = DIV_ROUND_CLOSEST(d * (WZRD_FRAC_POINTS * o + f), WZRD_FRAC_POINTS);
   399		return divider_recalc_rate(hw, parent_rate * m, div, divider->table,
   400				divider->flags, divider->width);
   401	}
   402	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From guodong.liu at mediatek.com  Thu Jan 20 22:01:18 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Fri, 21 Jan 2022 14:01:18 +0800
Subject: [PATCH v2 0/2] pinctrl: mediatek: Support pinctrl driver on mt8186
Message-ID: <20220121060120.10683-1-guodong.liu@mediatek.com>

changes since v1:
- add default pinctrl config to consistent with other MTK pinctrl drivers

Patch 1 add pinctrl file and binding document.

Patch 2 add pinctrl chip driver on mt8186.

Guodong Liu (2):
  dt-bindings: pinctrl: mt8186: add pinctrl file and binding document
  pinctrl: add pinctrl driver on mt8186

 .../bindings/pinctrl/pinctrl-mt8186.yaml      |  303 +++
 drivers/pinctrl/mediatek/Kconfig              |    7 +
 drivers/pinctrl/mediatek/Makefile             |    1 +
 drivers/pinctrl/mediatek/pinctrl-mt8186.c     | 1313 ++++++++++
 drivers/pinctrl/mediatek/pinctrl-mtk-mt8186.h | 2186 +++++++++++++++++
 include/dt-bindings/pinctrl/mt8186-pinfunc.h  | 1174 +++++++++
 6 files changed, 4984 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8186.c
 create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8186.h
 create mode 100644 include/dt-bindings/pinctrl/mt8186-pinfunc.h

-- 
2.25.5



From guodong.liu at mediatek.com  Thu Jan 20 22:01:19 2022
From: guodong.liu at mediatek.com (Guodong Liu)
Date: Fri, 21 Jan 2022 14:01:19 +0800
Subject: [PATCH v2 1/2] dt-bindings: pinctrl: mt8186: add pinctrl file and
 binding document
In-Reply-To: <20220121060120.10683-1-guodong.liu@mediatek.com>
References: <20220121060120.10683-1-guodong.liu@mediatek.com>
Message-ID: <20220121060120.10683-2-guodong.liu@mediatek.com>

1. This patch adds pinctrl file for mt8186.
2. This patch adds mt8186 compatible node in binding document.

Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
---
 .../bindings/pinctrl/pinctrl-mt8186.yaml      |  303 +++++
 include/dt-bindings/pinctrl/mt8186-pinfunc.h  | 1174 +++++++++++++++++
 2 files changed, 1477 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
 create mode 100644 include/dt-bindings/pinctrl/mt8186-pinfunc.h

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
new file mode 100644
index 000000000000..0a1154faca29
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8186.yaml
@@ -0,0 +1,303 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/pinctrl-mt8186.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT8186 Pin Controller
+
+maintainers:
+  - Sean Wang <sean.wang at mediatek.com>
+
+description: |
+  The Mediatek's Pin controller is used to control SoC pins.
+
+properties:
+  compatible:
+    const: mediatek,mt8186-pinctrl
+
+  gpio-controller: true
+
+  '#gpio-cells':
+    description: |
+      Number of cells in GPIO specifier. Since the generic GPIO binding is used,
+      the amount of cells must be specified as 2. See the below
+      mentioned gpio binding representation for description of particular cells.
+    const: 2
+
+  gpio-ranges:
+    description: gpio valid number range.
+    maxItems: 1
+
+  reg:
+    description: |
+      Physical address base for gpio base registers. There are 8 GPIO
+      physical address base in mt8186.
+    maxItems: 8
+
+  reg-names:
+    description: |
+      Gpio base register names.
+    maxItems: 8
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 2
+
+  interrupts:
+    description: The interrupt outputs to sysirq.
+    maxItems: 1
+
+  mediatek,rsel_resistance_in_si_unit:
+    type: boolean
+    description: |
+      Identifying i2c pins pull up/down type which is RSEL. It can support
+      RSEL define or si unit value(ohm) to set different resistance.
+
+# PIN CONFIGURATION NODES
+patternProperties:
+  '-pins$':
+    type: object
+    additionalProperties: false
+    patternProperties:
+      '^pins':
+        type: object
+        additionalProperties: false
+        description: |
+          A pinctrl node should contain at least one subnodes representing the
+          pinctrl groups available on the machine. Each subnode will list the
+          pins it needs, and how they should be configured, with regard to muxer
+          configuration, pullups, drive strength, input enable/disable and
+          input schmitt.
+          An example of using macro:
+          pincontroller {
+            /* GPIO0 set as multifunction GPIO0 */
+            gpio-pins {
+              pins {
+                pinmux = <PINMUX_GPIO0__FUNC_GPIO0>;
+              }
+            };
+            /* GPIO128 set as multifunction SDA0 */
+            i2c0-pins {
+              pins {
+                pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+              }
+            };
+          };
+        $ref: "pinmux-node.yaml"
+
+        properties:
+          pinmux:
+            description: |
+              Integer array, represents gpio pin number and mux setting.
+              Supported pin number and mux varies for different SoCs, and are
+              defined as macros in dt-bindings/pinctrl/<soc>-pinfunc.h
+              directly.
+
+          drive-strength:
+            enum: [2, 4, 6, 8, 10, 12, 14, 16]
+
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+          bias-pull-down:
+            description: |
+              For pull down type is normal, it don't need add RSEL & R1R0 define
+              and resistance value.
+              For pull down type is PUPD/R0/R1 type, it can add R1R0 define to
+              set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+              "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" &
+              "MTK_PUPD_SET_R1R0_11" define in mt8186.
+              For pull down type is RSEL, it can add RSEL define & resistance
+              value(ohm) to set different resistance by identifying property
+              "mediatek,rsel_resistance_in_si_unit".
+              It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
+              & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011"
+              & "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101"
+              & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
+              define in mt8186. It can also support resistance value(ohm)
+              "75000" & "5000" in mt8186.
+              oneOf:
+                - enum: [100, 101, 102, 103]
+                - description: mt8186 pull down PUPD/R0/R1 type define value.
+                - enum: [200, 201, 202, 203, 204, 205, 206, 207]
+                - description: mt8186 pull down RSEL type define value.
+                - enum: [75000, 5000]
+                - description: mt8186 pull down RSEL type si unit value(ohm).
+
+              An example of using RSEL define:
+              pincontroller {
+                i2c0_pin {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-down = <MTK_PULL_SET_RSEL_001>;
+                  }
+                };
+              };
+              An example of using si unit resistance value(ohm):
+              &pio {
+                mediatek,rsel_resistance_in_si_unit;
+              }
+              pincontroller {
+                i2c0_pin {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-down = <75000>;
+                  }
+                };
+              };
+
+          bias-pull-up:
+            description: |
+              For pull up type is normal, it don't need add RSEL & R1R0 define
+              and resistance value.
+              For pull up type is PUPD/R0/R1 type, it can add R1R0 define to
+              set different resistance. It can support "MTK_PUPD_SET_R1R0_00" &
+              "MTK_PUPD_SET_R1R0_01" & "MTK_PUPD_SET_R1R0_10" &
+              "MTK_PUPD_SET_R1R0_11" define in mt8186.
+              For pull up type is RSEL, it can add RSEL define & resistance
+              value(ohm) to set different resistance by identifying property
+              "mediatek,rsel_resistance_in_si_unit".
+              It can support "MTK_PULL_SET_RSEL_000" & "MTK_PULL_SET_RSEL_001"
+              & "MTK_PULL_SET_RSEL_010" & "MTK_PULL_SET_RSEL_011"
+              & "MTK_PULL_SET_RSEL_100" & "MTK_PULL_SET_RSEL_101"
+              & "MTK_PULL_SET_RSEL_110" & "MTK_PULL_SET_RSEL_111"
+              define in mt8186. It can also support resistance value(ohm)
+              "1000" & "1500" & "2000" & "3000" & "4000" & "5000" & "10000" &
+              "75000" in mt8186.
+              oneOf:
+                - enum: [100, 101, 102, 103]
+                - description: mt8186 pull up PUPD/R0/R1 type define value.
+                - enum: [200, 201, 202, 203, 204, 205, 206, 207]
+                - description: mt8186 pull up RSEL type define value.
+                - enum: [1000, 1500, 2000, 3000, 4000, 5000, 10000, 75000]
+                - description: mt8186 pull up RSEL type si unit value(ohm).
+              An example of using RSEL define:
+              pincontroller {
+                i2c0-pins {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-up = <MTK_PULL_SET_RSEL_001>;
+                  }
+                };
+              };
+              An example of using si unit resistance value(ohm):
+              &pio {
+                mediatek,rsel_resistance_in_si_unit;
+              }
+              pincontroller {
+                i2c0-pins {
+                  pins {
+                    pinmux = <PINMUX_GPIO128__FUNC_SDA0>;
+                    bias-pull-up = <1000>;
+                  }
+                };
+              };
+
+          bias-disable: true
+
+          output-high: true
+
+          output-low: true
+
+          input-enable: true
+
+          input-disable: true
+
+          input-schmitt-enable: true
+
+          input-schmitt-disable: true
+
+        required:
+          - pinmux
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - '#interrupt-cells'
+  - gpio-controller
+  - '#gpio-cells'
+  - gpio-ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/pinctrl/mt8186-pinfunc.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    pio: pinctrl at 10005000 {
+      compatible = "mediatek,mt8186-pinctrl";
+      reg = <0x10005000 0x1000>,
+            <0x10002000 0x0200>,
+            <0x10002200 0x0200>,
+            <0x10002400 0x0200>,
+            <0x10002600 0x0200>,
+            <0x10002A00 0x0200>,
+            <0x10002c00 0x0200>,
+            <0x1000b000 0x1000>;
+      reg-names = "iocfg0", "iocfg_bm", "iocfg_bl",
+                  "iocfg_br", "iocfg_lm", "iocfg_rb",
+                  "iocfg_tl", "eint";
+      gpio-controller;
+      #gpio-cells = <2>;
+      gpio-ranges = <&pio 0 0 185>;
+      interrupt-controller;
+      interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH 0>;
+      #interrupt-cells = <2>;
+
+      pio-pins {
+        pins {
+          pinmux = <PINMUX_GPIO0__FUNC_GPIO0>;
+          output-low;
+        };
+      };
+
+      spi0-pins {
+        pins-spi {
+          pinmux = <PINMUX_GPIO0__FUNC_SPI0_CLK_B>,
+                   <PINMUX_GPIO1__FUNC_SPI0_CSB_B>,
+                   <PINMUX_GPIO2__FUNC_SPI0_MO_B>;
+          bias-disable;
+        };
+        pins-spi-mi {
+          pinmux = <PINMUX_GPIO3__FUNC_SPI0_MI_B>;
+          bias-pull-down;
+        };
+      };
+
+      i2c0-pins {
+        pins {
+          pinmux = <PINMUX_GPIO127__FUNC_SCL0>,
+                   <PINMUX_GPIO128__FUNC_SDA0>;
+          bias-disable;
+          mediatek,drive-strength-adv = <7>;
+        };
+      };
+    };
diff --git a/include/dt-bindings/pinctrl/mt8186-pinfunc.h b/include/dt-bindings/pinctrl/mt8186-pinfunc.h
new file mode 100644
index 000000000000..f58983d11bca
--- /dev/null
+++ b/include/dt-bindings/pinctrl/mt8186-pinfunc.h
@@ -0,0 +1,1174 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Guodong Liu <Guodong.Liu at mediatek.com>
+ *
+ */
+
+#ifndef __MT8168_PINFUNC_H
+#define __MT8168_PINFUNC_H
+
+#include "mt65xx.h"
+
+#define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0)
+#define PINMUX_GPIO0__FUNC_I2S0_MCK (MTK_PIN_NO(0) | 1)
+#define PINMUX_GPIO0__FUNC_SPI0_CLK_B (MTK_PIN_NO(0) | 2)
+#define PINMUX_GPIO0__FUNC_I2S2_MCK (MTK_PIN_NO(0) | 3)
+#define PINMUX_GPIO0__FUNC_CMFLASH0 (MTK_PIN_NO(0) | 4)
+#define PINMUX_GPIO0__FUNC_SCP_SPI0_CK (MTK_PIN_NO(0) | 5)
+#define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 6)
+#define PINMUX_GPIO0__FUNC_DBG_MON_A0 (MTK_PIN_NO(0) | 7)
+
+#define PINMUX_GPIO1__FUNC_GPIO1 (MTK_PIN_NO(1) | 0)
+#define PINMUX_GPIO1__FUNC_I2S0_BCK (MTK_PIN_NO(1) | 1)
+#define PINMUX_GPIO1__FUNC_SPI0_CSB_B (MTK_PIN_NO(1) | 2)
+#define PINMUX_GPIO1__FUNC_I2S2_BCK (MTK_PIN_NO(1) | 3)
+#define PINMUX_GPIO1__FUNC_CMFLASH1 (MTK_PIN_NO(1) | 4)
+#define PINMUX_GPIO1__FUNC_SCP_SPI0_CS (MTK_PIN_NO(1) | 5)
+#define PINMUX_GPIO1__FUNC_TP_GPIO1_AO (MTK_PIN_NO(1) | 6)
+
+#define PINMUX_GPIO2__FUNC_GPIO2 (MTK_PIN_NO(2) | 0)
+#define PINMUX_GPIO2__FUNC_I2S0_LRCK (MTK_PIN_NO(2) | 1)
+#define PINMUX_GPIO2__FUNC_SPI0_MO_B (MTK_PIN_NO(2) | 2)
+#define PINMUX_GPIO2__FUNC_I2S2_LRCK (MTK_PIN_NO(2) | 3)
+#define PINMUX_GPIO2__FUNC_CMFLASH2 (MTK_PIN_NO(2) | 4)
+#define PINMUX_GPIO2__FUNC_SCP_SPI0_MO (MTK_PIN_NO(2) | 5)
+#define PINMUX_GPIO2__FUNC_TP_GPIO2_AO (MTK_PIN_NO(2) | 6)
+
+#define PINMUX_GPIO3__FUNC_GPIO3 (MTK_PIN_NO(3) | 0)
+#define PINMUX_GPIO3__FUNC_I2S0_DI (MTK_PIN_NO(3) | 1)
+#define PINMUX_GPIO3__FUNC_SPI0_MI_B (MTK_PIN_NO(3) | 2)
+#define PINMUX_GPIO3__FUNC_I2S2_DI (MTK_PIN_NO(3) | 3)
+#define PINMUX_GPIO3__FUNC_SRCLKENAI1 (MTK_PIN_NO(3) | 4)
+#define PINMUX_GPIO3__FUNC_SCP_SPI0_MI (MTK_PIN_NO(3) | 5)
+#define PINMUX_GPIO3__FUNC_TP_GPIO3_AO (MTK_PIN_NO(3) | 6)
+
+#define PINMUX_GPIO4__FUNC_GPIO4 (MTK_PIN_NO(4) | 0)
+#define PINMUX_GPIO4__FUNC_I2S3_DO (MTK_PIN_NO(4) | 1)
+#define PINMUX_GPIO4__FUNC_I2S1_DO (MTK_PIN_NO(4) | 3)
+#define PINMUX_GPIO4__FUNC_TP_GPIO4_AO (MTK_PIN_NO(4) | 6)
+
+#define PINMUX_GPIO5__FUNC_GPIO5 (MTK_PIN_NO(5) | 0)
+#define PINMUX_GPIO5__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(5) | 1)
+#define PINMUX_GPIO5__FUNC_TP_GPIO5_AO (MTK_PIN_NO(5) | 6)
+
+#define PINMUX_GPIO6__FUNC_GPIO6 (MTK_PIN_NO(6) | 0)
+#define PINMUX_GPIO6__FUNC_I2S3_MCK (MTK_PIN_NO(6) | 1)
+#define PINMUX_GPIO6__FUNC_SPI1_CLK_B (MTK_PIN_NO(6) | 2)
+#define PINMUX_GPIO6__FUNC_I2S1_MCK (MTK_PIN_NO(6) | 3)
+#define PINMUX_GPIO6__FUNC_DPI_DATA22 (MTK_PIN_NO(6) | 4)
+#define PINMUX_GPIO6__FUNC_TP_GPIO6_AO (MTK_PIN_NO(6) | 6)
+
+#define PINMUX_GPIO7__FUNC_GPIO7 (MTK_PIN_NO(7) | 0)
+#define PINMUX_GPIO7__FUNC_I2S3_BCK (MTK_PIN_NO(7) | 1)
+#define PINMUX_GPIO7__FUNC_SPI1_CSB_B (MTK_PIN_NO(7) | 2)
+#define PINMUX_GPIO7__FUNC_I2S1_BCK (MTK_PIN_NO(7) | 3)
+#define PINMUX_GPIO7__FUNC_DPI_DATA23 (MTK_PIN_NO(7) | 4)
+#define PINMUX_GPIO7__FUNC_TP_GPIO7_AO (MTK_PIN_NO(7) | 6)
+
+#define PINMUX_GPIO8__FUNC_GPIO8 (MTK_PIN_NO(8) | 0)
+#define PINMUX_GPIO8__FUNC_I2S3_LRCK (MTK_PIN_NO(8) | 1)
+#define PINMUX_GPIO8__FUNC_SPI1_MO_B (MTK_PIN_NO(8) | 2)
+#define PINMUX_GPIO8__FUNC_I2S1_LRCK (MTK_PIN_NO(8) | 3)
+#define PINMUX_GPIO8__FUNC_CONN_UART0_RXD (MTK_PIN_NO(8) | 4)
+#define PINMUX_GPIO8__FUNC_SSPM_URXD_AO (MTK_PIN_NO(8) | 5)
+#define PINMUX_GPIO8__FUNC_ADSP_UART_RX (MTK_PIN_NO(8) | 6)
+#define PINMUX_GPIO8__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(8) | 7)
+
+#define PINMUX_GPIO9__FUNC_GPIO9 (MTK_PIN_NO(9) | 0)
+#define PINMUX_GPIO9__FUNC_I2S3_DO (MTK_PIN_NO(9) | 1)
+#define PINMUX_GPIO9__FUNC_SPI1_MI_B (MTK_PIN_NO(9) | 2)
+#define PINMUX_GPIO9__FUNC_I2S1_DO (MTK_PIN_NO(9) | 3)
+#define PINMUX_GPIO9__FUNC_CONN_UART0_TXD (MTK_PIN_NO(9) | 4)
+#define PINMUX_GPIO9__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(9) | 5)
+#define PINMUX_GPIO9__FUNC_ADSP_UART_TX (MTK_PIN_NO(9) | 6)
+#define PINMUX_GPIO9__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(9) | 7)
+
+#define PINMUX_GPIO10__FUNC_GPIO10 (MTK_PIN_NO(10) | 0)
+#define PINMUX_GPIO10__FUNC_I2S0_MCK (MTK_PIN_NO(10) | 1)
+#define PINMUX_GPIO10__FUNC_SPI4_CLK_A (MTK_PIN_NO(10) | 2)
+#define PINMUX_GPIO10__FUNC_I2S2_MCK (MTK_PIN_NO(10) | 3)
+#define PINMUX_GPIO10__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(10) | 4)
+#define PINMUX_GPIO10__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(10) | 5)
+#define PINMUX_GPIO10__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(10) | 6)
+#define PINMUX_GPIO10__FUNC_CONN_MCU_TDI (MTK_PIN_NO(10) | 7)
+
+#define PINMUX_GPIO11__FUNC_GPIO11 (MTK_PIN_NO(11) | 0)
+#define PINMUX_GPIO11__FUNC_I2S0_BCK (MTK_PIN_NO(11) | 1)
+#define PINMUX_GPIO11__FUNC_SPI4_CSB_A (MTK_PIN_NO(11) | 2)
+#define PINMUX_GPIO11__FUNC_I2S2_BCK (MTK_PIN_NO(11) | 3)
+#define PINMUX_GPIO11__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(11) | 4)
+#define PINMUX_GPIO11__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(11) | 5)
+#define PINMUX_GPIO11__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(11) | 6)
+#define PINMUX_GPIO11__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(11) | 7)
+
+#define PINMUX_GPIO12__FUNC_GPIO12 (MTK_PIN_NO(12) | 0)
+#define PINMUX_GPIO12__FUNC_I2S0_LRCK (MTK_PIN_NO(12) | 1)
+#define PINMUX_GPIO12__FUNC_SPI4_MO_A (MTK_PIN_NO(12) | 2)
+#define PINMUX_GPIO12__FUNC_I2S2_LRCK (MTK_PIN_NO(12) | 3)
+#define PINMUX_GPIO12__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(12) | 4)
+#define PINMUX_GPIO12__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(12) | 5)
+#define PINMUX_GPIO12__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(12) | 6)
+#define PINMUX_GPIO12__FUNC_CONN_MCU_TCK (MTK_PIN_NO(12) | 7)
+
+#define PINMUX_GPIO13__FUNC_GPIO13 (MTK_PIN_NO(13) | 0)
+#define PINMUX_GPIO13__FUNC_I2S0_DI (MTK_PIN_NO(13) | 1)
+#define PINMUX_GPIO13__FUNC_SPI4_MI_A (MTK_PIN_NO(13) | 2)
+#define PINMUX_GPIO13__FUNC_I2S2_DI (MTK_PIN_NO(13) | 3)
+#define PINMUX_GPIO13__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(13) | 4)
+#define PINMUX_GPIO13__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(13) | 5)
+#define PINMUX_GPIO13__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(13) | 6)
+#define PINMUX_GPIO13__FUNC_CONN_MCU_TDO (MTK_PIN_NO(13) | 7)
+
+#define PINMUX_GPIO14__FUNC_GPIO14 (MTK_PIN_NO(14) | 0)
+#define PINMUX_GPIO14__FUNC_CLKM0 (MTK_PIN_NO(14) | 3)
+#define PINMUX_GPIO14__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(14) | 4)
+#define PINMUX_GPIO14__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(14) | 5)
+#define PINMUX_GPIO14__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(14) | 6)
+#define PINMUX_GPIO14__FUNC_CONN_MCU_TMS (MTK_PIN_NO(14) | 7)
+
+#define PINMUX_GPIO15__FUNC_GPIO15 (MTK_PIN_NO(15) | 0)
+#define PINMUX_GPIO15__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(15) | 1)
+#define PINMUX_GPIO15__FUNC_SRCLKENAI1 (MTK_PIN_NO(15) | 2)
+#define PINMUX_GPIO15__FUNC_CLKM1 (MTK_PIN_NO(15) | 3)
+#define PINMUX_GPIO15__FUNC_PWM0 (MTK_PIN_NO(15) | 4)
+
+#define PINMUX_GPIO16__FUNC_GPIO16 (MTK_PIN_NO(16) | 0)
+#define PINMUX_GPIO16__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(16) | 1)
+#define PINMUX_GPIO16__FUNC_SRCLKENAI0 (MTK_PIN_NO(16) | 2)
+#define PINMUX_GPIO16__FUNC_CLKM2 (MTK_PIN_NO(16) | 3)
+#define PINMUX_GPIO16__FUNC_PWM1 (MTK_PIN_NO(16) | 4)
+
+#define PINMUX_GPIO17__FUNC_GPIO17 (MTK_PIN_NO(17) | 0)
+#define PINMUX_GPIO17__FUNC_CLKM3 (MTK_PIN_NO(17) | 3)
+#define PINMUX_GPIO17__FUNC_PWM2 (MTK_PIN_NO(17) | 4)
+#define PINMUX_GPIO17__FUNC_DBG_MON_A32 (MTK_PIN_NO(17) | 7)
+
+#define PINMUX_GPIO18__FUNC_GPIO18 (MTK_PIN_NO(18) | 0)
+#define PINMUX_GPIO18__FUNC_CMVREF0 (MTK_PIN_NO(18) | 2)
+#define PINMUX_GPIO18__FUNC_SPI2_CLK_B (MTK_PIN_NO(18) | 6)
+#define PINMUX_GPIO18__FUNC_DBG_MON_A26 (MTK_PIN_NO(18) | 7)
+
+#define PINMUX_GPIO19__FUNC_GPIO19 (MTK_PIN_NO(19) | 0)
+#define PINMUX_GPIO19__FUNC_CMVREF1 (MTK_PIN_NO(19) | 2)
+#define PINMUX_GPIO19__FUNC_ANT_SEL3 (MTK_PIN_NO(19) | 5)
+#define PINMUX_GPIO19__FUNC_SPI2_CSB_B (MTK_PIN_NO(19) | 6)
+#define PINMUX_GPIO19__FUNC_DBG_MON_A2 (MTK_PIN_NO(19) | 7)
+
+#define PINMUX_GPIO20__FUNC_GPIO20 (MTK_PIN_NO(20) | 0)
+#define PINMUX_GPIO20__FUNC_CMVREF2 (MTK_PIN_NO(20) | 2)
+#define PINMUX_GPIO20__FUNC_ANT_SEL4 (MTK_PIN_NO(20) | 5)
+#define PINMUX_GPIO20__FUNC_SPI2_MO_B (MTK_PIN_NO(20) | 6)
+#define PINMUX_GPIO20__FUNC_DBG_MON_A3 (MTK_PIN_NO(20) | 7)
+
+#define PINMUX_GPIO21__FUNC_GPIO21 (MTK_PIN_NO(21) | 0)
+#define PINMUX_GPIO21__FUNC_I2S0_MCK (MTK_PIN_NO(21) | 1)
+#define PINMUX_GPIO21__FUNC_I2S1_MCK (MTK_PIN_NO(21) | 2)
+#define PINMUX_GPIO21__FUNC_I2S3_MCK (MTK_PIN_NO(21) | 3)
+#define PINMUX_GPIO21__FUNC_ANT_SEL5 (MTK_PIN_NO(21) | 5)
+#define PINMUX_GPIO21__FUNC_SPI2_MI_B (MTK_PIN_NO(21) | 6)
+#define PINMUX_GPIO21__FUNC_DBG_MON_A4 (MTK_PIN_NO(21) | 7)
+
+#define PINMUX_GPIO22__FUNC_GPIO22 (MTK_PIN_NO(22) | 0)
+#define PINMUX_GPIO22__FUNC_I2S0_BCK (MTK_PIN_NO(22) | 1)
+#define PINMUX_GPIO22__FUNC_I2S1_BCK (MTK_PIN_NO(22) | 2)
+#define PINMUX_GPIO22__FUNC_I2S3_BCK (MTK_PIN_NO(22) | 3)
+#define PINMUX_GPIO22__FUNC_TDM_RX_LRCK (MTK_PIN_NO(22) | 4)
+#define PINMUX_GPIO22__FUNC_ANT_SEL6 (MTK_PIN_NO(22) | 5)
+#define PINMUX_GPIO22__FUNC_DBG_MON_A5 (MTK_PIN_NO(22) | 7)
+
+#define PINMUX_GPIO23__FUNC_GPIO23 (MTK_PIN_NO(23) | 0)
+#define PINMUX_GPIO23__FUNC_I2S0_LRCK (MTK_PIN_NO(23) | 1)
+#define PINMUX_GPIO23__FUNC_I2S1_LRCK (MTK_PIN_NO(23) | 2)
+#define PINMUX_GPIO23__FUNC_I2S3_LRCK (MTK_PIN_NO(23) | 3)
+#define PINMUX_GPIO23__FUNC_TDM_RX_BCK (MTK_PIN_NO(23) | 4)
+#define PINMUX_GPIO23__FUNC_ANT_SEL7 (MTK_PIN_NO(23) | 5)
+#define PINMUX_GPIO23__FUNC_DBG_MON_A6 (MTK_PIN_NO(23) | 7)
+
+#define PINMUX_GPIO24__FUNC_GPIO24 (MTK_PIN_NO(24) | 0)
+#define PINMUX_GPIO24__FUNC_I2S0_DI (MTK_PIN_NO(24) | 1)
+#define PINMUX_GPIO24__FUNC_I2S1_DO (MTK_PIN_NO(24) | 2)
+#define PINMUX_GPIO24__FUNC_I2S3_DO (MTK_PIN_NO(24) | 3)
+#define PINMUX_GPIO24__FUNC_TDM_RX_MCK (MTK_PIN_NO(24) | 4)
+#define PINMUX_GPIO24__FUNC_DBG_MON_A7 (MTK_PIN_NO(24) | 7)
+
+#define PINMUX_GPIO25__FUNC_GPIO25 (MTK_PIN_NO(25) | 0)
+#define PINMUX_GPIO25__FUNC_I2S2_MCK (MTK_PIN_NO(25) | 1)
+#define PINMUX_GPIO25__FUNC_PCM_CLK (MTK_PIN_NO(25) | 2)
+#define PINMUX_GPIO25__FUNC_SPI4_CLK_B (MTK_PIN_NO(25) | 3)
+#define PINMUX_GPIO25__FUNC_TDM_RX_DATA0 (MTK_PIN_NO(25) | 4)
+#define PINMUX_GPIO25__FUNC_DBG_MON_A8 (MTK_PIN_NO(25) | 7)
+
+#define PINMUX_GPIO26__FUNC_GPIO26 (MTK_PIN_NO(26) | 0)
+#define PINMUX_GPIO26__FUNC_I2S2_BCK (MTK_PIN_NO(26) | 1)
+#define PINMUX_GPIO26__FUNC_PCM_SYNC (MTK_PIN_NO(26) | 2)
+#define PINMUX_GPIO26__FUNC_SPI4_CSB_B (MTK_PIN_NO(26) | 3)
+#define PINMUX_GPIO26__FUNC_TDM_RX_DATA1 (MTK_PIN_NO(26) | 4)
+#define PINMUX_GPIO26__FUNC_DBG_MON_A9 (MTK_PIN_NO(26) | 7)
+
+#define PINMUX_GPIO27__FUNC_GPIO27 (MTK_PIN_NO(27) | 0)
+#define PINMUX_GPIO27__FUNC_I2S2_LRCK (MTK_PIN_NO(27) | 1)
+#define PINMUX_GPIO27__FUNC_PCM_DI (MTK_PIN_NO(27) | 2)
+#define PINMUX_GPIO27__FUNC_SPI4_MO_B (MTK_PIN_NO(27) | 3)
+#define PINMUX_GPIO27__FUNC_TDM_RX_DATA2 (MTK_PIN_NO(27) | 4)
+#define PINMUX_GPIO27__FUNC_DBG_MON_A10 (MTK_PIN_NO(27) | 7)
+
+#define PINMUX_GPIO28__FUNC_GPIO28 (MTK_PIN_NO(28) | 0)
+#define PINMUX_GPIO28__FUNC_I2S2_DI (MTK_PIN_NO(28) | 1)
+#define PINMUX_GPIO28__FUNC_PCM_DO (MTK_PIN_NO(28) | 2)
+#define PINMUX_GPIO28__FUNC_SPI4_MI_B (MTK_PIN_NO(28) | 3)
+#define PINMUX_GPIO28__FUNC_TDM_RX_DATA3 (MTK_PIN_NO(28) | 4)
+
+#define PINMUX_GPIO29__FUNC_GPIO29 (MTK_PIN_NO(29) | 0)
+#define PINMUX_GPIO29__FUNC_ANT_SEL0 (MTK_PIN_NO(29) | 1)
+#define PINMUX_GPIO29__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(29) | 2)
+
+#define PINMUX_GPIO30__FUNC_GPIO30 (MTK_PIN_NO(30) | 0)
+#define PINMUX_GPIO30__FUNC_ANT_SEL1 (MTK_PIN_NO(30) | 1)
+
+#define PINMUX_GPIO31__FUNC_GPIO31 (MTK_PIN_NO(31) | 0)
+#define PINMUX_GPIO31__FUNC_ANT_SEL2 (MTK_PIN_NO(31) | 1)
+#define PINMUX_GPIO31__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(31) | 2)
+#define PINMUX_GPIO31__FUNC_SRCLKENAI1 (MTK_PIN_NO(31) | 3)
+
+#define PINMUX_GPIO32__FUNC_GPIO32 (MTK_PIN_NO(32) | 0)
+#define PINMUX_GPIO32__FUNC_URXD0 (MTK_PIN_NO(32) | 1)
+#define PINMUX_GPIO32__FUNC_UTXD0 (MTK_PIN_NO(32) | 2)
+#define PINMUX_GPIO32__FUNC_ADSP_UART_RX (MTK_PIN_NO(32) | 3)
+#define PINMUX_GPIO32__FUNC_TP_URXD1_AO (MTK_PIN_NO(32) | 4)
+
+#define PINMUX_GPIO33__FUNC_GPIO33 (MTK_PIN_NO(33) | 0)
+#define PINMUX_GPIO33__FUNC_UTXD0 (MTK_PIN_NO(33) | 1)
+#define PINMUX_GPIO33__FUNC_URXD0 (MTK_PIN_NO(33) | 2)
+#define PINMUX_GPIO33__FUNC_ADSP_UART_TX (MTK_PIN_NO(33) | 3)
+#define PINMUX_GPIO33__FUNC_TP_UTXD1_AO (MTK_PIN_NO(33) | 4)
+
+#define PINMUX_GPIO34__FUNC_GPIO34 (MTK_PIN_NO(34) | 0)
+#define PINMUX_GPIO34__FUNC_URXD1 (MTK_PIN_NO(34) | 1)
+#define PINMUX_GPIO34__FUNC_TP_URXD2_AO (MTK_PIN_NO(34) | 2)
+#define PINMUX_GPIO34__FUNC_SSPM_URXD_AO (MTK_PIN_NO(34) | 3)
+#define PINMUX_GPIO34__FUNC_ADSP_UART_RX (MTK_PIN_NO(34) | 4)
+#define PINMUX_GPIO34__FUNC_CONN_UART0_RXD (MTK_PIN_NO(34) | 5)
+
+#define PINMUX_GPIO35__FUNC_GPIO35 (MTK_PIN_NO(35) | 0)
+#define PINMUX_GPIO35__FUNC_UTXD1 (MTK_PIN_NO(35) | 1)
+#define PINMUX_GPIO35__FUNC_TP_UTXD2_AO (MTK_PIN_NO(35) | 2)
+#define PINMUX_GPIO35__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(35) | 3)
+#define PINMUX_GPIO35__FUNC_ADSP_UART_TX (MTK_PIN_NO(35) | 4)
+#define PINMUX_GPIO35__FUNC_CONN_UART0_TXD (MTK_PIN_NO(35) | 5)
+#define PINMUX_GPIO35__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(35) | 6)
+
+#define PINMUX_GPIO36__FUNC_GPIO36 (MTK_PIN_NO(36) | 0)
+#define PINMUX_GPIO36__FUNC_SPI0_CLK_A (MTK_PIN_NO(36) | 1)
+#define PINMUX_GPIO36__FUNC_CLKM0 (MTK_PIN_NO(36) | 2)
+#define PINMUX_GPIO36__FUNC_SCP_SPI0_CK (MTK_PIN_NO(36) | 4)
+#define PINMUX_GPIO36__FUNC_SPINOR_CK (MTK_PIN_NO(36) | 5)
+#define PINMUX_GPIO36__FUNC_DBG_MON_A11 (MTK_PIN_NO(36) | 7)
+
+#define PINMUX_GPIO37__FUNC_GPIO37 (MTK_PIN_NO(37) | 0)
+#define PINMUX_GPIO37__FUNC_SPI0_CSB_A (MTK_PIN_NO(37) | 1)
+#define PINMUX_GPIO37__FUNC_CLKM1 (MTK_PIN_NO(37) | 2)
+#define PINMUX_GPIO37__FUNC_PWM0 (MTK_PIN_NO(37) | 3)
+#define PINMUX_GPIO37__FUNC_SCP_SPI0_CS (MTK_PIN_NO(37) | 4)
+#define PINMUX_GPIO37__FUNC_SPINOR_CS (MTK_PIN_NO(37) | 5)
+#define PINMUX_GPIO37__FUNC_DBG_MON_A12 (MTK_PIN_NO(37) | 7)
+
+#define PINMUX_GPIO38__FUNC_GPIO38 (MTK_PIN_NO(38) | 0)
+#define PINMUX_GPIO38__FUNC_SPI0_MO_A (MTK_PIN_NO(38) | 1)
+#define PINMUX_GPIO38__FUNC_CLKM2 (MTK_PIN_NO(38) | 2)
+#define PINMUX_GPIO38__FUNC_PWM1 (MTK_PIN_NO(38) | 3)
+#define PINMUX_GPIO38__FUNC_SCP_SPI0_MO (MTK_PIN_NO(38) | 4)
+#define PINMUX_GPIO38__FUNC_SPINOR_IO0 (MTK_PIN_NO(38) | 5)
+#define PINMUX_GPIO38__FUNC_DBG_MON_A13 (MTK_PIN_NO(38) | 7)
+
+#define PINMUX_GPIO39__FUNC_GPIO39 (MTK_PIN_NO(39) | 0)
+#define PINMUX_GPIO39__FUNC_SPI0_MI_A (MTK_PIN_NO(39) | 1)
+#define PINMUX_GPIO39__FUNC_CLKM3 (MTK_PIN_NO(39) | 2)
+#define PINMUX_GPIO39__FUNC_PWM2 (MTK_PIN_NO(39) | 3)
+#define PINMUX_GPIO39__FUNC_SCP_SPI0_MI (MTK_PIN_NO(39) | 4)
+#define PINMUX_GPIO39__FUNC_SPINOR_IO1 (MTK_PIN_NO(39) | 5)
+#define PINMUX_GPIO39__FUNC_DBG_MON_A14 (MTK_PIN_NO(39) | 7)
+
+#define PINMUX_GPIO40__FUNC_GPIO40 (MTK_PIN_NO(40) | 0)
+#define PINMUX_GPIO40__FUNC_SPI1_CLK_A (MTK_PIN_NO(40) | 1)
+#define PINMUX_GPIO40__FUNC_SCP_SPI1_CK (MTK_PIN_NO(40) | 2)
+#define PINMUX_GPIO40__FUNC_UCTS0 (MTK_PIN_NO(40) | 4)
+#define PINMUX_GPIO40__FUNC_SPINOR_IO2 (MTK_PIN_NO(40) | 5)
+#define PINMUX_GPIO40__FUNC_TP_UCTS1_AO (MTK_PIN_NO(40) | 6)
+#define PINMUX_GPIO40__FUNC_DBG_MON_A15 (MTK_PIN_NO(40) | 7)
+
+#define PINMUX_GPIO41__FUNC_GPIO41 (MTK_PIN_NO(41) | 0)
+#define PINMUX_GPIO41__FUNC_SPI1_CSB_A (MTK_PIN_NO(41) | 1)
+#define PINMUX_GPIO41__FUNC_SCP_SPI1_CS (MTK_PIN_NO(41) | 2)
+#define PINMUX_GPIO41__FUNC_PWM0 (MTK_PIN_NO(41) | 3)
+#define PINMUX_GPIO41__FUNC_URTS0 (MTK_PIN_NO(41) | 4)
+#define PINMUX_GPIO41__FUNC_SPINOR_IO3 (MTK_PIN_NO(41) | 5)
+#define PINMUX_GPIO41__FUNC_TP_URTS1_AO (MTK_PIN_NO(41) | 6)
+#define PINMUX_GPIO41__FUNC_DBG_MON_A16 (MTK_PIN_NO(41) | 7)
+
+#define PINMUX_GPIO42__FUNC_GPIO42 (MTK_PIN_NO(42) | 0)
+#define PINMUX_GPIO42__FUNC_SPI1_MO_A (MTK_PIN_NO(42) | 1)
+#define PINMUX_GPIO42__FUNC_SCP_SPI1_MO (MTK_PIN_NO(42) | 2)
+#define PINMUX_GPIO42__FUNC_PWM1 (MTK_PIN_NO(42) | 3)
+#define PINMUX_GPIO42__FUNC_UCTS1 (MTK_PIN_NO(42) | 4)
+#define PINMUX_GPIO42__FUNC_TP_UCTS2_AO (MTK_PIN_NO(42) | 6)
+#define PINMUX_GPIO42__FUNC_DBG_MON_A17 (MTK_PIN_NO(42) | 7)
+
+#define PINMUX_GPIO43__FUNC_GPIO43 (MTK_PIN_NO(43) | 0)
+#define PINMUX_GPIO43__FUNC_SPI1_MI_A (MTK_PIN_NO(43) | 1)
+#define PINMUX_GPIO43__FUNC_SCP_SPI1_MI (MTK_PIN_NO(43) | 2)
+#define PINMUX_GPIO43__FUNC_PWM2 (MTK_PIN_NO(43) | 3)
+#define PINMUX_GPIO43__FUNC_URTS1 (MTK_PIN_NO(43) | 4)
+#define PINMUX_GPIO43__FUNC_TP_URTS2_AO (MTK_PIN_NO(43) | 6)
+#define PINMUX_GPIO43__FUNC_DBG_MON_A18 (MTK_PIN_NO(43) | 7)
+
+#define PINMUX_GPIO44__FUNC_GPIO44 (MTK_PIN_NO(44) | 0)
+#define PINMUX_GPIO44__FUNC_SPI2_CLK_A (MTK_PIN_NO(44) | 1)
+#define PINMUX_GPIO44__FUNC_SCP_SPI0_CK (MTK_PIN_NO(44) | 2)
+#define PINMUX_GPIO44__FUNC_DBG_MON_A19 (MTK_PIN_NO(44) | 7)
+
+#define PINMUX_GPIO45__FUNC_GPIO45 (MTK_PIN_NO(45) | 0)
+#define PINMUX_GPIO45__FUNC_SPI2_CSB_A (MTK_PIN_NO(45) | 1)
+#define PINMUX_GPIO45__FUNC_SCP_SPI0_CS (MTK_PIN_NO(45) | 2)
+#define PINMUX_GPIO45__FUNC_DBG_MON_A20 (MTK_PIN_NO(45) | 7)
+
+#define PINMUX_GPIO46__FUNC_GPIO46 (MTK_PIN_NO(46) | 0)
+#define PINMUX_GPIO46__FUNC_SPI2_MO_A (MTK_PIN_NO(46) | 1)
+#define PINMUX_GPIO46__FUNC_SCP_SPI0_MO (MTK_PIN_NO(46) | 2)
+#define PINMUX_GPIO46__FUNC_DBG_MON_A21 (MTK_PIN_NO(46) | 7)
+
+#define PINMUX_GPIO47__FUNC_GPIO47 (MTK_PIN_NO(47) | 0)
+#define PINMUX_GPIO47__FUNC_SPI2_MI_A (MTK_PIN_NO(47) | 1)
+#define PINMUX_GPIO47__FUNC_SCP_SPI0_MI (MTK_PIN_NO(47) | 2)
+#define PINMUX_GPIO47__FUNC_DBG_MON_A22 (MTK_PIN_NO(47) | 7)
+
+#define PINMUX_GPIO48__FUNC_GPIO48 (MTK_PIN_NO(48) | 0)
+#define PINMUX_GPIO48__FUNC_SPI3_CLK (MTK_PIN_NO(48) | 1)
+#define PINMUX_GPIO48__FUNC_TP_URXD1_AO (MTK_PIN_NO(48) | 2)
+#define PINMUX_GPIO48__FUNC_TP_URXD2_AO (MTK_PIN_NO(48) | 3)
+#define PINMUX_GPIO48__FUNC_URXD1 (MTK_PIN_NO(48) | 4)
+#define PINMUX_GPIO48__FUNC_I2S2_MCK (MTK_PIN_NO(48) | 5)
+#define PINMUX_GPIO48__FUNC_SCP_SPI0_CK (MTK_PIN_NO(48) | 6)
+
+#define PINMUX_GPIO49__FUNC_GPIO49 (MTK_PIN_NO(49) | 0)
+#define PINMUX_GPIO49__FUNC_SPI3_CSB (MTK_PIN_NO(49) | 1)
+#define PINMUX_GPIO49__FUNC_TP_UTXD1_AO (MTK_PIN_NO(49) | 2)
+#define PINMUX_GPIO49__FUNC_TP_UTXD2_AO (MTK_PIN_NO(49) | 3)
+#define PINMUX_GPIO49__FUNC_UTXD1 (MTK_PIN_NO(49) | 4)
+#define PINMUX_GPIO49__FUNC_I2S2_BCK (MTK_PIN_NO(49) | 5)
+#define PINMUX_GPIO49__FUNC_SCP_SPI0_CS (MTK_PIN_NO(49) | 6)
+
+#define PINMUX_GPIO50__FUNC_GPIO50 (MTK_PIN_NO(50) | 0)
+#define PINMUX_GPIO50__FUNC_SPI3_MO (MTK_PIN_NO(50) | 1)
+#define PINMUX_GPIO50__FUNC_I2S2_LRCK (MTK_PIN_NO(50) | 5)
+#define PINMUX_GPIO50__FUNC_SCP_SPI0_MO (MTK_PIN_NO(50) | 6)
+
+#define PINMUX_GPIO51__FUNC_GPIO51 (MTK_PIN_NO(51) | 0)
+#define PINMUX_GPIO51__FUNC_SPI3_MI (MTK_PIN_NO(51) | 1)
+#define PINMUX_GPIO51__FUNC_I2S2_DI (MTK_PIN_NO(51) | 5)
+#define PINMUX_GPIO51__FUNC_SCP_SPI0_MI (MTK_PIN_NO(51) | 6)
+
+#define PINMUX_GPIO52__FUNC_GPIO52 (MTK_PIN_NO(52) | 0)
+#define PINMUX_GPIO52__FUNC_SPI5_CLK (MTK_PIN_NO(52) | 1)
+#define PINMUX_GPIO52__FUNC_I2S2_MCK (MTK_PIN_NO(52) | 2)
+#define PINMUX_GPIO52__FUNC_I2S1_MCK (MTK_PIN_NO(52) | 3)
+#define PINMUX_GPIO52__FUNC_SCP_SPI1_CK (MTK_PIN_NO(52) | 4)
+#define PINMUX_GPIO52__FUNC_LVTS_26M (MTK_PIN_NO(52) | 5)
+#define PINMUX_GPIO52__FUNC_DFD_TCK_XI (MTK_PIN_NO(52) | 6)
+#define PINMUX_GPIO52__FUNC_DBG_MON_B30 (MTK_PIN_NO(52) | 7)
+
+#define PINMUX_GPIO53__FUNC_GPIO53 (MTK_PIN_NO(53) | 0)
+#define PINMUX_GPIO53__FUNC_SPI5_CSB (MTK_PIN_NO(53) | 1)
+#define PINMUX_GPIO53__FUNC_I2S2_BCK (MTK_PIN_NO(53) | 2)
+#define PINMUX_GPIO53__FUNC_I2S1_BCK (MTK_PIN_NO(53) | 3)
+#define PINMUX_GPIO53__FUNC_SCP_SPI1_CS (MTK_PIN_NO(53) | 4)
+#define PINMUX_GPIO53__FUNC_LVTS_FOUT (MTK_PIN_NO(53) | 5)
+#define PINMUX_GPIO53__FUNC_DFD_TDI (MTK_PIN_NO(53) | 6)
+#define PINMUX_GPIO53__FUNC_DBG_MON_B31 (MTK_PIN_NO(53) | 7)
+
+#define PINMUX_GPIO54__FUNC_GPIO54 (MTK_PIN_NO(54) | 0)
+#define PINMUX_GPIO54__FUNC_SPI5_MO (MTK_PIN_NO(54) | 1)
+#define PINMUX_GPIO54__FUNC_I2S2_LRCK (MTK_PIN_NO(54) | 2)
+#define PINMUX_GPIO54__FUNC_I2S1_LRCK (MTK_PIN_NO(54) | 3)
+#define PINMUX_GPIO54__FUNC_SCP_SPI1_MO (MTK_PIN_NO(54) | 4)
+#define PINMUX_GPIO54__FUNC_LVTS_SCK (MTK_PIN_NO(54) | 5)
+#define PINMUX_GPIO54__FUNC_DFD_TDO (MTK_PIN_NO(54) | 6)
+#define PINMUX_GPIO54__FUNC_DBG_MON_A1 (MTK_PIN_NO(54) | 7)
+
+#define PINMUX_GPIO55__FUNC_GPIO55 (MTK_PIN_NO(55) | 0)
+#define PINMUX_GPIO55__FUNC_SPI5_MI (MTK_PIN_NO(55) | 1)
+#define PINMUX_GPIO55__FUNC_I2S2_DI (MTK_PIN_NO(55) | 2)
+#define PINMUX_GPIO55__FUNC_I2S1_DO (MTK_PIN_NO(55) | 3)
+#define PINMUX_GPIO55__FUNC_SCP_SPI1_MI (MTK_PIN_NO(55) | 4)
+#define PINMUX_GPIO55__FUNC_LVTS_SDO (MTK_PIN_NO(55) | 5)
+#define PINMUX_GPIO55__FUNC_DFD_TMS (MTK_PIN_NO(55) | 6)
+#define PINMUX_GPIO55__FUNC_DBG_MON_B32 (MTK_PIN_NO(55) | 7)
+
+#define PINMUX_GPIO56__FUNC_GPIO56 (MTK_PIN_NO(56) | 0)
+#define PINMUX_GPIO56__FUNC_I2S1_DO (MTK_PIN_NO(56) | 1)
+#define PINMUX_GPIO56__FUNC_I2S3_DO (MTK_PIN_NO(56) | 2)
+#define PINMUX_GPIO56__FUNC_DBG_MON_A23 (MTK_PIN_NO(56) | 7)
+
+#define PINMUX_GPIO57__FUNC_GPIO57 (MTK_PIN_NO(57) | 0)
+#define PINMUX_GPIO57__FUNC_I2S1_BCK (MTK_PIN_NO(57) | 1)
+#define PINMUX_GPIO57__FUNC_I2S3_BCK (MTK_PIN_NO(57) | 2)
+#define PINMUX_GPIO57__FUNC_DBG_MON_A24 (MTK_PIN_NO(57) | 7)
+
+#define PINMUX_GPIO58__FUNC_GPIO58 (MTK_PIN_NO(58) | 0)
+#define PINMUX_GPIO58__FUNC_I2S1_LRCK (MTK_PIN_NO(58) | 1)
+#define PINMUX_GPIO58__FUNC_I2S3_LRCK (MTK_PIN_NO(58) | 2)
+#define PINMUX_GPIO58__FUNC_DBG_MON_A25 (MTK_PIN_NO(58) | 7)
+
+#define PINMUX_GPIO59__FUNC_GPIO59 (MTK_PIN_NO(59) | 0)
+#define PINMUX_GPIO59__FUNC_I2S1_MCK (MTK_PIN_NO(59) | 1)
+#define PINMUX_GPIO59__FUNC_I2S3_MCK (MTK_PIN_NO(59) | 2)
+#define PINMUX_GPIO59__FUNC_DBG_MON_A27 (MTK_PIN_NO(59) | 7)
+
+#define PINMUX_GPIO60__FUNC_GPIO60 (MTK_PIN_NO(60) | 0)
+#define PINMUX_GPIO60__FUNC_TDM_RX_LRCK (MTK_PIN_NO(60) | 1)
+#define PINMUX_GPIO60__FUNC_ANT_SEL3 (MTK_PIN_NO(60) | 2)
+#define PINMUX_GPIO60__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(60) | 5)
+
+#define PINMUX_GPIO61__FUNC_GPIO61 (MTK_PIN_NO(61) | 0)
+#define PINMUX_GPIO61__FUNC_TDM_RX_BCK (MTK_PIN_NO(61) | 1)
+#define PINMUX_GPIO61__FUNC_ANT_SEL4 (MTK_PIN_NO(61) | 2)
+#define PINMUX_GPIO61__FUNC_SPINOR_CK (MTK_PIN_NO(61) | 4)
+#define PINMUX_GPIO61__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(61) | 5)
+
+#define PINMUX_GPIO62__FUNC_GPIO62 (MTK_PIN_NO(62) | 0)
+#define PINMUX_GPIO62__FUNC_TDM_RX_MCK (MTK_PIN_NO(62) | 1)
+#define PINMUX_GPIO62__FUNC_ANT_SEL5 (MTK_PIN_NO(62) | 2)
+#define PINMUX_GPIO62__FUNC_SPINOR_CS (MTK_PIN_NO(62) | 4)
+#define PINMUX_GPIO62__FUNC_CONN_MCU_TDI (MTK_PIN_NO(62) | 5)
+
+#define PINMUX_GPIO63__FUNC_GPIO63 (MTK_PIN_NO(63) | 0)
+#define PINMUX_GPIO63__FUNC_TDM_RX_DATA0 (MTK_PIN_NO(63) | 1)
+#define PINMUX_GPIO63__FUNC_ANT_SEL6 (MTK_PIN_NO(63) | 2)
+#define PINMUX_GPIO63__FUNC_SPINOR_IO0 (MTK_PIN_NO(63) | 4)
+#define PINMUX_GPIO63__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(63) | 5)
+
+#define PINMUX_GPIO64__FUNC_GPIO64 (MTK_PIN_NO(64) | 0)
+#define PINMUX_GPIO64__FUNC_TDM_RX_DATA1 (MTK_PIN_NO(64) | 1)
+#define PINMUX_GPIO64__FUNC_ANT_SEL7 (MTK_PIN_NO(64) | 2)
+#define PINMUX_GPIO64__FUNC_PWM0 (MTK_PIN_NO(64) | 3)
+#define PINMUX_GPIO64__FUNC_SPINOR_IO1 (MTK_PIN_NO(64) | 4)
+#define PINMUX_GPIO64__FUNC_CONN_MCU_TCK (MTK_PIN_NO(64) | 5)
+
+#define PINMUX_GPIO65__FUNC_GPIO65 (MTK_PIN_NO(65) | 0)
+#define PINMUX_GPIO65__FUNC_TDM_RX_DATA2 (MTK_PIN_NO(65) | 1)
+#define PINMUX_GPIO65__FUNC_UCTS0 (MTK_PIN_NO(65) | 2)
+#define PINMUX_GPIO65__FUNC_PWM1 (MTK_PIN_NO(65) | 3)
+#define PINMUX_GPIO65__FUNC_SPINOR_IO2 (MTK_PIN_NO(65) | 4)
+#define PINMUX_GPIO65__FUNC_CONN_MCU_TDO (MTK_PIN_NO(65) | 5)
+#define PINMUX_GPIO65__FUNC_TP_UCTS1_AO (MTK_PIN_NO(65) | 6)
+#define PINMUX_GPIO65__FUNC_TP_UCTS2_AO (MTK_PIN_NO(65) | 7)
+
+#define PINMUX_GPIO66__FUNC_GPIO66 (MTK_PIN_NO(66) | 0)
+#define PINMUX_GPIO66__FUNC_TDM_RX_DATA3 (MTK_PIN_NO(66) | 1)
+#define PINMUX_GPIO66__FUNC_URTS0 (MTK_PIN_NO(66) | 2)
+#define PINMUX_GPIO66__FUNC_PWM2 (MTK_PIN_NO(66) | 3)
+#define PINMUX_GPIO66__FUNC_SPINOR_IO3 (MTK_PIN_NO(66) | 4)
+#define PINMUX_GPIO66__FUNC_CONN_MCU_TMS (MTK_PIN_NO(66) | 5)
+#define PINMUX_GPIO66__FUNC_TP_URTS1_AO (MTK_PIN_NO(66) | 6)
+#define PINMUX_GPIO66__FUNC_TP_URTS2_AO (MTK_PIN_NO(66) | 7)
+
+#define PINMUX_GPIO67__FUNC_GPIO67 (MTK_PIN_NO(67) | 0)
+#define PINMUX_GPIO67__FUNC_MSDC0_DSL (MTK_PIN_NO(67) | 1)
+
+#define PINMUX_GPIO68__FUNC_GPIO68 (MTK_PIN_NO(68) | 0)
+#define PINMUX_GPIO68__FUNC_MSDC0_CLK (MTK_PIN_NO(68) | 1)
+
+#define PINMUX_GPIO69__FUNC_GPIO69 (MTK_PIN_NO(69) | 0)
+#define PINMUX_GPIO69__FUNC_MSDC0_CMD (MTK_PIN_NO(69) | 1)
+
+#define PINMUX_GPIO70__FUNC_GPIO70 (MTK_PIN_NO(70) | 0)
+#define PINMUX_GPIO70__FUNC_MSDC0_RSTB (MTK_PIN_NO(70) | 1)
+
+#define PINMUX_GPIO71__FUNC_GPIO71 (MTK_PIN_NO(71) | 0)
+#define PINMUX_GPIO71__FUNC_MSDC0_DAT0 (MTK_PIN_NO(71) | 1)
+
+#define PINMUX_GPIO72__FUNC_GPIO72 (MTK_PIN_NO(72) | 0)
+#define PINMUX_GPIO72__FUNC_MSDC0_DAT1 (MTK_PIN_NO(72) | 1)
+
+#define PINMUX_GPIO73__FUNC_GPIO73 (MTK_PIN_NO(73) | 0)
+#define PINMUX_GPIO73__FUNC_MSDC0_DAT2 (MTK_PIN_NO(73) | 1)
+
+#define PINMUX_GPIO74__FUNC_GPIO74 (MTK_PIN_NO(74) | 0)
+#define PINMUX_GPIO74__FUNC_MSDC0_DAT3 (MTK_PIN_NO(74) | 1)
+
+#define PINMUX_GPIO75__FUNC_GPIO75 (MTK_PIN_NO(75) | 0)
+#define PINMUX_GPIO75__FUNC_MSDC0_DAT4 (MTK_PIN_NO(75) | 1)
+
+#define PINMUX_GPIO76__FUNC_GPIO76 (MTK_PIN_NO(76) | 0)
+#define PINMUX_GPIO76__FUNC_MSDC0_DAT5 (MTK_PIN_NO(76) | 1)
+
+#define PINMUX_GPIO77__FUNC_GPIO77 (MTK_PIN_NO(77) | 0)
+#define PINMUX_GPIO77__FUNC_MSDC0_DAT6 (MTK_PIN_NO(77) | 1)
+
+#define PINMUX_GPIO78__FUNC_GPIO78 (MTK_PIN_NO(78) | 0)
+#define PINMUX_GPIO78__FUNC_MSDC0_DAT7 (MTK_PIN_NO(78) | 1)
+
+#define PINMUX_GPIO79__FUNC_GPIO79 (MTK_PIN_NO(79) | 0)
+#define PINMUX_GPIO79__FUNC_KPCOL0 (MTK_PIN_NO(79) | 1)
+
+#define PINMUX_GPIO80__FUNC_GPIO80 (MTK_PIN_NO(80) | 0)
+#define PINMUX_GPIO80__FUNC_KPCOL1 (MTK_PIN_NO(80) | 1)
+#define PINMUX_GPIO80__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(80) | 2)
+#define PINMUX_GPIO80__FUNC_PWM0 (MTK_PIN_NO(80) | 3)
+#define PINMUX_GPIO80__FUNC_CLKM0 (MTK_PIN_NO(80) | 4)
+
+#define PINMUX_GPIO81__FUNC_GPIO81 (MTK_PIN_NO(81) | 0)
+#define PINMUX_GPIO81__FUNC_KPROW0 (MTK_PIN_NO(81) | 1)
+#define PINMUX_GPIO81__FUNC_PWM1 (MTK_PIN_NO(81) | 3)
+#define PINMUX_GPIO81__FUNC_CLKM1 (MTK_PIN_NO(81) | 4)
+
+#define PINMUX_GPIO82__FUNC_GPIO82 (MTK_PIN_NO(82) | 0)
+#define PINMUX_GPIO82__FUNC_KPROW1 (MTK_PIN_NO(82) | 1)
+#define PINMUX_GPIO82__FUNC_PWM2 (MTK_PIN_NO(82) | 3)
+#define PINMUX_GPIO82__FUNC_CLKM2 (MTK_PIN_NO(82) | 4)
+
+#define PINMUX_GPIO83__FUNC_GPIO83 (MTK_PIN_NO(83) | 0)
+#define PINMUX_GPIO83__FUNC_AP_GOOD (MTK_PIN_NO(83) | 1)
+#define PINMUX_GPIO83__FUNC_GPS_PPS (MTK_PIN_NO(83) | 2)
+#define PINMUX_GPIO83__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(83) | 4)
+#define PINMUX_GPIO83__FUNC_DBG_MON_A28 (MTK_PIN_NO(83) | 7)
+
+#define PINMUX_GPIO84__FUNC_GPIO84 (MTK_PIN_NO(84) | 0)
+#define PINMUX_GPIO84__FUNC_MSDC1_CLK (MTK_PIN_NO(84) | 1)
+#define PINMUX_GPIO84__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(84) | 2)
+#define PINMUX_GPIO84__FUNC_UDI_TCK (MTK_PIN_NO(84) | 4)
+#define PINMUX_GPIO84__FUNC_CONN_DSP_JCK (MTK_PIN_NO(84) | 5)
+#define PINMUX_GPIO84__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(84) | 6)
+#define PINMUX_GPIO84__FUNC_DFD_TCK_XI (MTK_PIN_NO(84) | 7)
+
+#define PINMUX_GPIO85__FUNC_GPIO85 (MTK_PIN_NO(85) | 0)
+#define PINMUX_GPIO85__FUNC_MSDC1_CMD (MTK_PIN_NO(85) | 1)
+#define PINMUX_GPIO85__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(85) | 2)
+#define PINMUX_GPIO85__FUNC_CONN_MCU_AICE_TMSC (MTK_PIN_NO(85) | 3)
+#define PINMUX_GPIO85__FUNC_UDI_TMS (MTK_PIN_NO(85) | 4)
+#define PINMUX_GPIO85__FUNC_CONN_DSP_JMS (MTK_PIN_NO(85) | 5)
+#define PINMUX_GPIO85__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(85) | 6)
+#define PINMUX_GPIO85__FUNC_DFD_TMS (MTK_PIN_NO(85) | 7)
+
+#define PINMUX_GPIO86__FUNC_GPIO86 (MTK_PIN_NO(86) | 0)
+#define PINMUX_GPIO86__FUNC_MSDC1_DAT0 (MTK_PIN_NO(86) | 1)
+#define PINMUX_GPIO86__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(86) | 2)
+#define PINMUX_GPIO86__FUNC_UDI_TDI (MTK_PIN_NO(86) | 4)
+#define PINMUX_GPIO86__FUNC_CONN_DSP_JDI (MTK_PIN_NO(86) | 5)
+#define PINMUX_GPIO86__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(86) | 6)
+#define PINMUX_GPIO86__FUNC_DFD_TDI (MTK_PIN_NO(86) | 7)
+
+#define PINMUX_GPIO87__FUNC_GPIO87 (MTK_PIN_NO(87) | 0)
+#define PINMUX_GPIO87__FUNC_MSDC1_DAT1 (MTK_PIN_NO(87) | 1)
+#define PINMUX_GPIO87__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(87) | 2)
+#define PINMUX_GPIO87__FUNC_UDI_TDO (MTK_PIN_NO(87) | 4)
+#define PINMUX_GPIO87__FUNC_CONN_DSP_JDO (MTK_PIN_NO(87) | 5)
+#define PINMUX_GPIO87__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(87) | 6)
+#define PINMUX_GPIO87__FUNC_DFD_TDO (MTK_PIN_NO(87) | 7)
+
+#define PINMUX_GPIO88__FUNC_GPIO88 (MTK_PIN_NO(88) | 0)
+#define PINMUX_GPIO88__FUNC_MSDC1_DAT2 (MTK_PIN_NO(88) | 1)
+#define PINMUX_GPIO88__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(88) | 2)
+#define PINMUX_GPIO88__FUNC_CONN_MCU_AICE_TCKC (MTK_PIN_NO(88) | 3)
+#define PINMUX_GPIO88__FUNC_UDI_NTRST (MTK_PIN_NO(88) | 4)
+#define PINMUX_GPIO88__FUNC_CONN_WIFI_TXD (MTK_PIN_NO(88) | 5)
+#define PINMUX_GPIO88__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(88) | 6)
+
+#define PINMUX_GPIO89__FUNC_GPIO89 (MTK_PIN_NO(89) | 0)
+#define PINMUX_GPIO89__FUNC_MSDC1_DAT3 (MTK_PIN_NO(89) | 1)
+#define PINMUX_GPIO89__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(89) | 5)
+
+#define PINMUX_GPIO90__FUNC_GPIO90 (MTK_PIN_NO(90) | 0)
+#define PINMUX_GPIO90__FUNC_IDDIG_P0 (MTK_PIN_NO(90) | 1)
+#define PINMUX_GPIO90__FUNC_PGD_HV_HSC_PWR4 (MTK_PIN_NO(90) | 4)
+#define PINMUX_GPIO90__FUNC_GDU_SUM_TROOP2_2 (MTK_PIN_NO(90) | 5)
+
+#define PINMUX_GPIO91__FUNC_GPIO91 (MTK_PIN_NO(91) | 0)
+#define PINMUX_GPIO91__FUNC_USB_DRVVBUS_P0 (MTK_PIN_NO(91) | 1)
+#define PINMUX_GPIO91__FUNC_PGD_HV_HSC_PWR5 (MTK_PIN_NO(91) | 4)
+#define PINMUX_GPIO91__FUNC_GDU_TROOPS_DET0 (MTK_PIN_NO(91) | 5)
+
+#define PINMUX_GPIO92__FUNC_GPIO92 (MTK_PIN_NO(92) | 0)
+#define PINMUX_GPIO92__FUNC_VBUS_VALID_P0 (MTK_PIN_NO(92) | 1)
+#define PINMUX_GPIO92__FUNC_PGD_DA_EFUSE_RDY (MTK_PIN_NO(92) | 4)
+#define PINMUX_GPIO92__FUNC_GDU_TROOPS_DET1 (MTK_PIN_NO(92) | 5)
+
+#define PINMUX_GPIO93__FUNC_GPIO93 (MTK_PIN_NO(93) | 0)
+#define PINMUX_GPIO93__FUNC_IDDIG_P1 (MTK_PIN_NO(93) | 1)
+#define PINMUX_GPIO93__FUNC_PWM0 (MTK_PIN_NO(93) | 2)
+#define PINMUX_GPIO93__FUNC_CLKM0 (MTK_PIN_NO(93) | 3)
+#define PINMUX_GPIO93__FUNC_PGD_DA_EFUSE_RDY_PRE (MTK_PIN_NO(93) | 4)
+#define PINMUX_GPIO93__FUNC_GDU_TROOPS_DET2 (MTK_PIN_NO(93) | 5)
+
+#define PINMUX_GPIO94__FUNC_GPIO94 (MTK_PIN_NO(94) | 0)
+#define PINMUX_GPIO94__FUNC_USB_DRVVBUS_P1 (MTK_PIN_NO(94) | 1)
+#define PINMUX_GPIO94__FUNC_PWM1 (MTK_PIN_NO(94) | 2)
+#define PINMUX_GPIO94__FUNC_CLKM1 (MTK_PIN_NO(94) | 3)
+#define PINMUX_GPIO94__FUNC_PGD_DA_PWRGD_RESET (MTK_PIN_NO(94) | 4)
+
+#define PINMUX_GPIO95__FUNC_GPIO95 (MTK_PIN_NO(95) | 0)
+#define PINMUX_GPIO95__FUNC_VBUS_VALID_P1 (MTK_PIN_NO(95) | 1)
+#define PINMUX_GPIO95__FUNC_PWM2 (MTK_PIN_NO(95) | 2)
+#define PINMUX_GPIO95__FUNC_CLKM2 (MTK_PIN_NO(95) | 3)
+#define PINMUX_GPIO95__FUNC_PGD_DA_PWRGD_ENB (MTK_PIN_NO(95) | 4)
+
+#define PINMUX_GPIO96__FUNC_GPIO96 (MTK_PIN_NO(96) | 0)
+#define PINMUX_GPIO96__FUNC_DSI_TE (MTK_PIN_NO(96) | 1)
+#define PINMUX_GPIO96__FUNC_DBG_MON_A29 (MTK_PIN_NO(96) | 7)
+
+#define PINMUX_GPIO97__FUNC_GPIO97 (MTK_PIN_NO(97) | 0)
+#define PINMUX_GPIO97__FUNC_DISP_PWM (MTK_PIN_NO(97) | 1)
+#define PINMUX_GPIO97__FUNC_DBG_MON_A30 (MTK_PIN_NO(97) | 7)
+
+#define PINMUX_GPIO98__FUNC_GPIO98 (MTK_PIN_NO(98) | 0)
+#define PINMUX_GPIO98__FUNC_LCM_RST (MTK_PIN_NO(98) | 1)
+
+#define PINMUX_GPIO99__FUNC_GPIO99 (MTK_PIN_NO(99) | 0)
+#define PINMUX_GPIO99__FUNC_DPI_PCLK (MTK_PIN_NO(99) | 1)
+#define PINMUX_GPIO99__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(99) | 2)
+#define PINMUX_GPIO99__FUNC_SSPM_JTAG_TCK (MTK_PIN_NO(99) | 3)
+#define PINMUX_GPIO99__FUNC_ANT_SEL0 (MTK_PIN_NO(99) | 5)
+#define PINMUX_GPIO99__FUNC_TP_GPIO0_AO (MTK_PIN_NO(99) | 6)
+#define PINMUX_GPIO99__FUNC_PGD_LV_LSC_PWR0 (MTK_PIN_NO(99) | 7)
+
+#define PINMUX_GPIO100__FUNC_GPIO100 (MTK_PIN_NO(100) | 0)
+#define PINMUX_GPIO100__FUNC_DPI_VSYNC (MTK_PIN_NO(100) | 1)
+#define PINMUX_GPIO100__FUNC_KPCOL2 (MTK_PIN_NO(100) | 2)
+#define PINMUX_GPIO100__FUNC_SSPM_JTAG_TMS (MTK_PIN_NO(100) | 3)
+#define PINMUX_GPIO100__FUNC_ANT_SEL1 (MTK_PIN_NO(100) | 5)
+#define PINMUX_GPIO100__FUNC_TP_GPIO1_AO (MTK_PIN_NO(100) | 6)
+#define PINMUX_GPIO100__FUNC_PGD_LV_LSC_PWR1 (MTK_PIN_NO(100) | 7)
+
+#define PINMUX_GPIO101__FUNC_GPIO101 (MTK_PIN_NO(101) | 0)
+#define PINMUX_GPIO101__FUNC_DPI_HSYNC (MTK_PIN_NO(101) | 1)
+#define PINMUX_GPIO101__FUNC_KPROW2 (MTK_PIN_NO(101) | 2)
+#define PINMUX_GPIO101__FUNC_SSPM_JTAG_TDI (MTK_PIN_NO(101) | 3)
+#define PINMUX_GPIO101__FUNC_ANT_SEL2 (MTK_PIN_NO(101) | 5)
+#define PINMUX_GPIO101__FUNC_TP_GPIO2_AO (MTK_PIN_NO(101) | 6)
+#define PINMUX_GPIO101__FUNC_PGD_LV_LSC_PWR2 (MTK_PIN_NO(101) | 7)
+
+#define PINMUX_GPIO102__FUNC_GPIO102 (MTK_PIN_NO(102) | 0)
+#define PINMUX_GPIO102__FUNC_DPI_DE (MTK_PIN_NO(102) | 1)
+#define PINMUX_GPIO102__FUNC_SSPM_JTAG_TDO (MTK_PIN_NO(102) | 3)
+#define PINMUX_GPIO102__FUNC_ANT_SEL3 (MTK_PIN_NO(102) | 5)
+#define PINMUX_GPIO102__FUNC_TP_GPIO3_AO (MTK_PIN_NO(102) | 6)
+#define PINMUX_GPIO102__FUNC_PGD_LV_LSC_PWR3 (MTK_PIN_NO(102) | 7)
+
+#define PINMUX_GPIO103__FUNC_GPIO103 (MTK_PIN_NO(103) | 0)
+#define PINMUX_GPIO103__FUNC_DPI_DATA0 (MTK_PIN_NO(103) | 1)
+#define PINMUX_GPIO103__FUNC_SSPM_JTAG_TRSTN (MTK_PIN_NO(103) | 3)
+#define PINMUX_GPIO103__FUNC_CLKM0 (MTK_PIN_NO(103) | 4)
+#define PINMUX_GPIO103__FUNC_ANT_SEL4 (MTK_PIN_NO(103) | 5)
+#define PINMUX_GPIO103__FUNC_TP_GPIO4_AO (MTK_PIN_NO(103) | 6)
+#define PINMUX_GPIO103__FUNC_PGD_LV_LSC_PWR4 (MTK_PIN_NO(103) | 7)
+
+#define PINMUX_GPIO104__FUNC_GPIO104 (MTK_PIN_NO(104) | 0)
+#define PINMUX_GPIO104__FUNC_DPI_DATA1 (MTK_PIN_NO(104) | 1)
+#define PINMUX_GPIO104__FUNC_GPS_PPS (MTK_PIN_NO(104) | 2)
+#define PINMUX_GPIO104__FUNC_UCTS2 (MTK_PIN_NO(104) | 3)
+#define PINMUX_GPIO104__FUNC_CLKM1 (MTK_PIN_NO(104) | 4)
+#define PINMUX_GPIO104__FUNC_ANT_SEL5 (MTK_PIN_NO(104) | 5)
+#define PINMUX_GPIO104__FUNC_TP_GPIO5_AO (MTK_PIN_NO(104) | 6)
+#define PINMUX_GPIO104__FUNC_PGD_LV_LSC_PWR5 (MTK_PIN_NO(104) | 7)
+
+#define PINMUX_GPIO105__FUNC_GPIO105 (MTK_PIN_NO(105) | 0)
+#define PINMUX_GPIO105__FUNC_DPI_DATA2 (MTK_PIN_NO(105) | 1)
+#define PINMUX_GPIO105__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(105) | 2)
+#define PINMUX_GPIO105__FUNC_URTS2 (MTK_PIN_NO(105) | 3)
+#define PINMUX_GPIO105__FUNC_CLKM2 (MTK_PIN_NO(105) | 4)
+#define PINMUX_GPIO105__FUNC_ANT_SEL6 (MTK_PIN_NO(105) | 5)
+#define PINMUX_GPIO105__FUNC_TP_GPIO6_AO (MTK_PIN_NO(105) | 6)
+#define PINMUX_GPIO105__FUNC_PGD_LV_HSC_PWR0 (MTK_PIN_NO(105) | 7)
+
+#define PINMUX_GPIO106__FUNC_GPIO106 (MTK_PIN_NO(106) | 0)
+#define PINMUX_GPIO106__FUNC_DPI_DATA3 (MTK_PIN_NO(106) | 1)
+#define PINMUX_GPIO106__FUNC_TP_UTXD1_AO (MTK_PIN_NO(106) | 2)
+#define PINMUX_GPIO106__FUNC_UTXD2 (MTK_PIN_NO(106) | 3)
+#define PINMUX_GPIO106__FUNC_PWM0 (MTK_PIN_NO(106) | 4)
+#define PINMUX_GPIO106__FUNC_ANT_SEL7 (MTK_PIN_NO(106) | 5)
+#define PINMUX_GPIO106__FUNC_TP_GPIO7_AO (MTK_PIN_NO(106) | 6)
+#define PINMUX_GPIO106__FUNC_PGD_LV_HSC_PWR1 (MTK_PIN_NO(106) | 7)
+
+#define PINMUX_GPIO107__FUNC_GPIO107 (MTK_PIN_NO(107) | 0)
+#define PINMUX_GPIO107__FUNC_DPI_DATA4 (MTK_PIN_NO(107) | 1)
+#define PINMUX_GPIO107__FUNC_TP_URXD1_AO (MTK_PIN_NO(107) | 2)
+#define PINMUX_GPIO107__FUNC_URXD2 (MTK_PIN_NO(107) | 3)
+#define PINMUX_GPIO107__FUNC_PWM1 (MTK_PIN_NO(107) | 4)
+#define PINMUX_GPIO107__FUNC_GDU_SUM_TROOP0_0 (MTK_PIN_NO(107) | 6)
+#define PINMUX_GPIO107__FUNC_PGD_LV_HSC_PWR2 (MTK_PIN_NO(107) | 7)
+
+#define PINMUX_GPIO108__FUNC_GPIO108 (MTK_PIN_NO(108) | 0)
+#define PINMUX_GPIO108__FUNC_DPI_DATA5 (MTK_PIN_NO(108) | 1)
+#define PINMUX_GPIO108__FUNC_TP_UCTS1_AO (MTK_PIN_NO(108) | 2)
+#define PINMUX_GPIO108__FUNC_UCTS0 (MTK_PIN_NO(108) | 3)
+#define PINMUX_GPIO108__FUNC_PWM2 (MTK_PIN_NO(108) | 4)
+#define PINMUX_GPIO108__FUNC_GDU_SUM_TROOP0_1 (MTK_PIN_NO(108) | 6)
+#define PINMUX_GPIO108__FUNC_PGD_LV_HSC_PWR3 (MTK_PIN_NO(108) | 7)
+
+#define PINMUX_GPIO109__FUNC_GPIO109 (MTK_PIN_NO(109) | 0)
+#define PINMUX_GPIO109__FUNC_DPI_DATA6 (MTK_PIN_NO(109) | 1)
+#define PINMUX_GPIO109__FUNC_TP_URTS1_AO (MTK_PIN_NO(109) | 2)
+#define PINMUX_GPIO109__FUNC_URTS0 (MTK_PIN_NO(109) | 3)
+#define PINMUX_GPIO109__FUNC_I2S0_DI (MTK_PIN_NO(109) | 4)
+#define PINMUX_GPIO109__FUNC_I2S2_DI (MTK_PIN_NO(109) | 5)
+#define PINMUX_GPIO109__FUNC_GDU_SUM_TROOP0_2 (MTK_PIN_NO(109) | 6)
+#define PINMUX_GPIO109__FUNC_PGD_LV_HSC_PWR4 (MTK_PIN_NO(109) | 7)
+
+#define PINMUX_GPIO110__FUNC_GPIO110 (MTK_PIN_NO(110) | 0)
+#define PINMUX_GPIO110__FUNC_DPI_DATA7 (MTK_PIN_NO(110) | 1)
+#define PINMUX_GPIO110__FUNC_TP_UCTS2_AO (MTK_PIN_NO(110) | 2)
+#define PINMUX_GPIO110__FUNC_UCTS1 (MTK_PIN_NO(110) | 3)
+#define PINMUX_GPIO110__FUNC_I2S3_BCK (MTK_PIN_NO(110) | 4)
+#define PINMUX_GPIO110__FUNC_I2S1_BCK (MTK_PIN_NO(110) | 5)
+#define PINMUX_GPIO110__FUNC_GDU_SUM_TROOP1_0 (MTK_PIN_NO(110) | 6)
+#define PINMUX_GPIO110__FUNC_PGD_LV_HSC_PWR5 (MTK_PIN_NO(110) | 7)
+
+#define PINMUX_GPIO111__FUNC_GPIO111 (MTK_PIN_NO(111) | 0)
+#define PINMUX_GPIO111__FUNC_DPI_DATA8 (MTK_PIN_NO(111) | 1)
+#define PINMUX_GPIO111__FUNC_TP_URTS2_AO (MTK_PIN_NO(111) | 2)
+#define PINMUX_GPIO111__FUNC_URTS1 (MTK_PIN_NO(111) | 3)
+#define PINMUX_GPIO111__FUNC_I2S3_MCK (MTK_PIN_NO(111) | 4)
+#define PINMUX_GPIO111__FUNC_I2S1_MCK (MTK_PIN_NO(111) | 5)
+#define PINMUX_GPIO111__FUNC_GDU_SUM_TROOP1_1 (MTK_PIN_NO(111) | 6)
+#define PINMUX_GPIO111__FUNC_PGD_HV_HSC_PWR0 (MTK_PIN_NO(111) | 7)
+
+#define PINMUX_GPIO112__FUNC_GPIO112 (MTK_PIN_NO(112) | 0)
+#define PINMUX_GPIO112__FUNC_DPI_DATA9 (MTK_PIN_NO(112) | 1)
+#define PINMUX_GPIO112__FUNC_TP_URXD2_AO (MTK_PIN_NO(112) | 2)
+#define PINMUX_GPIO112__FUNC_URXD1 (MTK_PIN_NO(112) | 3)
+#define PINMUX_GPIO112__FUNC_I2S3_LRCK (MTK_PIN_NO(112) | 4)
+#define PINMUX_GPIO112__FUNC_I2S1_LRCK (MTK_PIN_NO(112) | 5)
+#define PINMUX_GPIO112__FUNC_GDU_SUM_TROOP1_2 (MTK_PIN_NO(112) | 6)
+#define PINMUX_GPIO112__FUNC_PGD_HV_HSC_PWR1 (MTK_PIN_NO(112) | 7)
+
+#define PINMUX_GPIO113__FUNC_GPIO113 (MTK_PIN_NO(113) | 0)
+#define PINMUX_GPIO113__FUNC_DPI_DATA10 (MTK_PIN_NO(113) | 1)
+#define PINMUX_GPIO113__FUNC_TP_UTXD2_AO (MTK_PIN_NO(113) | 2)
+#define PINMUX_GPIO113__FUNC_UTXD1 (MTK_PIN_NO(113) | 3)
+#define PINMUX_GPIO113__FUNC_I2S3_DO (MTK_PIN_NO(113) | 4)
+#define PINMUX_GPIO113__FUNC_I2S1_DO (MTK_PIN_NO(113) | 5)
+#define PINMUX_GPIO113__FUNC_GDU_SUM_TROOP2_0 (MTK_PIN_NO(113) | 6)
+#define PINMUX_GPIO113__FUNC_PGD_HV_HSC_PWR2 (MTK_PIN_NO(113) | 7)
+
+#define PINMUX_GPIO114__FUNC_GPIO114 (MTK_PIN_NO(114) | 0)
+#define PINMUX_GPIO114__FUNC_DPI_DATA11 (MTK_PIN_NO(114) | 1)
+#define PINMUX_GPIO114__FUNC_GDU_SUM_TROOP2_1 (MTK_PIN_NO(114) | 6)
+#define PINMUX_GPIO114__FUNC_PGD_HV_HSC_PWR3 (MTK_PIN_NO(114) | 7)
+
+#define PINMUX_GPIO115__FUNC_GPIO115 (MTK_PIN_NO(115) | 0)
+#define PINMUX_GPIO115__FUNC_PCM_CLK (MTK_PIN_NO(115) | 1)
+#define PINMUX_GPIO115__FUNC_I2S0_BCK (MTK_PIN_NO(115) | 2)
+#define PINMUX_GPIO115__FUNC_I2S2_BCK (MTK_PIN_NO(115) | 3)
+
+#define PINMUX_GPIO116__FUNC_GPIO116 (MTK_PIN_NO(116) | 0)
+#define PINMUX_GPIO116__FUNC_PCM_SYNC (MTK_PIN_NO(116) | 1)
+#define PINMUX_GPIO116__FUNC_I2S0_LRCK (MTK_PIN_NO(116) | 2)
+#define PINMUX_GPIO116__FUNC_I2S2_LRCK (MTK_PIN_NO(116) | 3)
+
+#define PINMUX_GPIO117__FUNC_GPIO117 (MTK_PIN_NO(117) | 0)
+#define PINMUX_GPIO117__FUNC_PCM_DI (MTK_PIN_NO(117) | 1)
+#define PINMUX_GPIO117__FUNC_I2S0_DI (MTK_PIN_NO(117) | 2)
+#define PINMUX_GPIO117__FUNC_I2S2_DI (MTK_PIN_NO(117) | 3)
+
+#define PINMUX_GPIO118__FUNC_GPIO118 (MTK_PIN_NO(118) | 0)
+#define PINMUX_GPIO118__FUNC_PCM_DO (MTK_PIN_NO(118) | 1)
+#define PINMUX_GPIO118__FUNC_I2S0_MCK (MTK_PIN_NO(118) | 2)
+#define PINMUX_GPIO118__FUNC_I2S2_MCK (MTK_PIN_NO(118) | 3)
+#define PINMUX_GPIO118__FUNC_I2S3_DO (MTK_PIN_NO(118) | 4)
+#define PINMUX_GPIO118__FUNC_I2S1_DO (MTK_PIN_NO(118) | 5)
+
+#define PINMUX_GPIO119__FUNC_GPIO119 (MTK_PIN_NO(119) | 0)
+#define PINMUX_GPIO119__FUNC_JTMS_SEL1 (MTK_PIN_NO(119) | 1)
+#define PINMUX_GPIO119__FUNC_UDI_TMS (MTK_PIN_NO(119) | 2)
+#define PINMUX_GPIO119__FUNC_DFD_TMS (MTK_PIN_NO(119) | 3)
+#define PINMUX_GPIO119__FUNC_SPM_JTAG_TMS (MTK_PIN_NO(119) | 4)
+#define PINMUX_GPIO119__FUNC_SCP_JTAG_TMS (MTK_PIN_NO(119) | 5)
+#define PINMUX_GPIO119__FUNC_ADSP_JTAG_TMS (MTK_PIN_NO(119) | 6)
+
+#define PINMUX_GPIO120__FUNC_GPIO120 (MTK_PIN_NO(120) | 0)
+#define PINMUX_GPIO120__FUNC_JTCK_SEL1 (MTK_PIN_NO(120) | 1)
+#define PINMUX_GPIO120__FUNC_UDI_TCK (MTK_PIN_NO(120) | 2)
+#define PINMUX_GPIO120__FUNC_DFD_TCK_XI (MTK_PIN_NO(120) | 3)
+#define PINMUX_GPIO120__FUNC_SPM_JTAG_TCK (MTK_PIN_NO(120) | 4)
+#define PINMUX_GPIO120__FUNC_SCP_JTAG_TCK (MTK_PIN_NO(120) | 5)
+#define PINMUX_GPIO120__FUNC_ADSP_JTAG_TCK (MTK_PIN_NO(120) | 6)
+
+#define PINMUX_GPIO121__FUNC_GPIO121 (MTK_PIN_NO(121) | 0)
+#define PINMUX_GPIO121__FUNC_JTDI_SEL1 (MTK_PIN_NO(121) | 1)
+#define PINMUX_GPIO121__FUNC_UDI_TDI (MTK_PIN_NO(121) | 2)
+#define PINMUX_GPIO121__FUNC_DFD_TDI (MTK_PIN_NO(121) | 3)
+#define PINMUX_GPIO121__FUNC_SPM_JTAG_TDI (MTK_PIN_NO(121) | 4)
+#define PINMUX_GPIO121__FUNC_SCP_JTAG_TDI (MTK_PIN_NO(121) | 5)
+#define PINMUX_GPIO121__FUNC_ADSP_JTAG_TDI (MTK_PIN_NO(121) | 6)
+
+#define PINMUX_GPIO122__FUNC_GPIO122 (MTK_PIN_NO(122) | 0)
+#define PINMUX_GPIO122__FUNC_JTDO_SEL1 (MTK_PIN_NO(122) | 1)
+#define PINMUX_GPIO122__FUNC_UDI_TDO (MTK_PIN_NO(122) | 2)
+#define PINMUX_GPIO122__FUNC_DFD_TDO (MTK_PIN_NO(122) | 3)
+#define PINMUX_GPIO122__FUNC_SPM_JTAG_TDO (MTK_PIN_NO(122) | 4)
+#define PINMUX_GPIO122__FUNC_SCP_JTAG_TDO (MTK_PIN_NO(122) | 5)
+#define PINMUX_GPIO122__FUNC_ADSP_JTAG_TDO (MTK_PIN_NO(122) | 6)
+
+#define PINMUX_GPIO123__FUNC_GPIO123 (MTK_PIN_NO(123) | 0)
+#define PINMUX_GPIO123__FUNC_JTRSTN_SEL1 (MTK_PIN_NO(123) | 1)
+#define PINMUX_GPIO123__FUNC_UDI_NTRST (MTK_PIN_NO(123) | 2)
+#define PINMUX_GPIO123__FUNC_SPM_JTAG_TRSTN (MTK_PIN_NO(123) | 4)
+#define PINMUX_GPIO123__FUNC_SCP_JTAG_TRSTN (MTK_PIN_NO(123) | 5)
+#define PINMUX_GPIO123__FUNC_ADSP_JTAG_TRSTN (MTK_PIN_NO(123) | 6)
+
+#define PINMUX_GPIO124__FUNC_GPIO124 (MTK_PIN_NO(124) | 0)
+#define PINMUX_GPIO124__FUNC_CMMCLK0 (MTK_PIN_NO(124) | 1)
+#define PINMUX_GPIO124__FUNC_CLKM0 (MTK_PIN_NO(124) | 2)
+#define PINMUX_GPIO124__FUNC_PWM0 (MTK_PIN_NO(124) | 3)
+
+#define PINMUX_GPIO125__FUNC_GPIO125 (MTK_PIN_NO(125) | 0)
+#define PINMUX_GPIO125__FUNC_CMMCLK1 (MTK_PIN_NO(125) | 1)
+#define PINMUX_GPIO125__FUNC_CLKM1 (MTK_PIN_NO(125) | 2)
+#define PINMUX_GPIO125__FUNC_PWM1 (MTK_PIN_NO(125) | 3)
+#define PINMUX_GPIO125__FUNC_DBG_MON_B0 (MTK_PIN_NO(125) | 7)
+
+#define PINMUX_GPIO126__FUNC_GPIO126 (MTK_PIN_NO(126) | 0)
+#define PINMUX_GPIO126__FUNC_CMMCLK2 (MTK_PIN_NO(126) | 1)
+#define PINMUX_GPIO126__FUNC_CLKM2 (MTK_PIN_NO(126) | 2)
+#define PINMUX_GPIO126__FUNC_PWM2 (MTK_PIN_NO(126) | 3)
+#define PINMUX_GPIO126__FUNC_DBG_MON_B1 (MTK_PIN_NO(126) | 7)
+
+#define PINMUX_GPIO127__FUNC_GPIO127 (MTK_PIN_NO(127) | 0)
+#define PINMUX_GPIO127__FUNC_SCL0 (MTK_PIN_NO(127) | 1)
+#define PINMUX_GPIO127__FUNC_SCP_SCL0 (MTK_PIN_NO(127) | 4)
+#define PINMUX_GPIO127__FUNC_SCP_SCL1 (MTK_PIN_NO(127) | 5)
+
+#define PINMUX_GPIO128__FUNC_GPIO128 (MTK_PIN_NO(128) | 0)
+#define PINMUX_GPIO128__FUNC_SDA0 (MTK_PIN_NO(128) | 1)
+#define PINMUX_GPIO128__FUNC_SCP_SDA0 (MTK_PIN_NO(128) | 4)
+#define PINMUX_GPIO128__FUNC_SCP_SDA1 (MTK_PIN_NO(128) | 5)
+
+#define PINMUX_GPIO129__FUNC_GPIO129 (MTK_PIN_NO(129) | 0)
+#define PINMUX_GPIO129__FUNC_SCL1 (MTK_PIN_NO(129) | 1)
+#define PINMUX_GPIO129__FUNC_SCP_SCL0 (MTK_PIN_NO(129) | 4)
+#define PINMUX_GPIO129__FUNC_SCP_SCL1 (MTK_PIN_NO(129) | 5)
+#define PINMUX_GPIO129__FUNC_DBG_MON_B4 (MTK_PIN_NO(129) | 7)
+
+#define PINMUX_GPIO130__FUNC_GPIO130 (MTK_PIN_NO(130) | 0)
+#define PINMUX_GPIO130__FUNC_SDA1 (MTK_PIN_NO(130) | 1)
+#define PINMUX_GPIO130__FUNC_SCP_SDA0 (MTK_PIN_NO(130) | 4)
+#define PINMUX_GPIO130__FUNC_SCP_SDA1 (MTK_PIN_NO(130) | 5)
+#define PINMUX_GPIO130__FUNC_DBG_MON_B5 (MTK_PIN_NO(130) | 7)
+
+#define PINMUX_GPIO131__FUNC_GPIO131 (MTK_PIN_NO(131) | 0)
+#define PINMUX_GPIO131__FUNC_SCL2 (MTK_PIN_NO(131) | 1)
+#define PINMUX_GPIO131__FUNC_SSPM_UTXD_AO (MTK_PIN_NO(131) | 2)
+#define PINMUX_GPIO131__FUNC_CONN_UART0_TXD (MTK_PIN_NO(131) | 3)
+#define PINMUX_GPIO131__FUNC_SCP_SCL0 (MTK_PIN_NO(131) | 4)
+#define PINMUX_GPIO131__FUNC_SCP_SCL1 (MTK_PIN_NO(131) | 5)
+#define PINMUX_GPIO131__FUNC_DBG_MON_B6 (MTK_PIN_NO(131) | 7)
+
+#define PINMUX_GPIO132__FUNC_GPIO132 (MTK_PIN_NO(132) | 0)
+#define PINMUX_GPIO132__FUNC_SDA2 (MTK_PIN_NO(132) | 1)
+#define PINMUX_GPIO132__FUNC_SSPM_URXD_AO (MTK_PIN_NO(132) | 2)
+#define PINMUX_GPIO132__FUNC_CONN_UART0_RXD (MTK_PIN_NO(132) | 3)
+#define PINMUX_GPIO132__FUNC_SCP_SDA0 (MTK_PIN_NO(132) | 4)
+#define PINMUX_GPIO132__FUNC_SCP_SDA1 (MTK_PIN_NO(132) | 5)
+#define PINMUX_GPIO132__FUNC_DBG_MON_B7 (MTK_PIN_NO(132) | 7)
+
+#define PINMUX_GPIO133__FUNC_GPIO133 (MTK_PIN_NO(133) | 0)
+#define PINMUX_GPIO133__FUNC_SCL3 (MTK_PIN_NO(133) | 1)
+#define PINMUX_GPIO133__FUNC_SCP_SCL0 (MTK_PIN_NO(133) | 4)
+#define PINMUX_GPIO133__FUNC_SCP_SCL1 (MTK_PIN_NO(133) | 5)
+#define PINMUX_GPIO133__FUNC_DBG_MON_B8 (MTK_PIN_NO(133) | 7)
+
+#define PINMUX_GPIO134__FUNC_GPIO134 (MTK_PIN_NO(134) | 0)
+#define PINMUX_GPIO134__FUNC_SDA3 (MTK_PIN_NO(134) | 1)
+#define PINMUX_GPIO134__FUNC_GPS_PPS (MTK_PIN_NO(134) | 3)
+#define PINMUX_GPIO134__FUNC_SCP_SDA0 (MTK_PIN_NO(134) | 4)
+#define PINMUX_GPIO134__FUNC_SCP_SDA1 (MTK_PIN_NO(134) | 5)
+#define PINMUX_GPIO134__FUNC_DBG_MON_B9 (MTK_PIN_NO(134) | 7)
+
+#define PINMUX_GPIO135__FUNC_GPIO135 (MTK_PIN_NO(135) | 0)
+#define PINMUX_GPIO135__FUNC_SCL4 (MTK_PIN_NO(135) | 1)
+#define PINMUX_GPIO135__FUNC_TP_UTXD1_AO (MTK_PIN_NO(135) | 2)
+#define PINMUX_GPIO135__FUNC_UTXD1 (MTK_PIN_NO(135) | 3)
+#define PINMUX_GPIO135__FUNC_SCP_SCL0 (MTK_PIN_NO(135) | 4)
+#define PINMUX_GPIO135__FUNC_SCP_SCL1 (MTK_PIN_NO(135) | 5)
+#define PINMUX_GPIO135__FUNC_DBG_MON_B10 (MTK_PIN_NO(135) | 7)
+
+#define PINMUX_GPIO136__FUNC_GPIO136 (MTK_PIN_NO(136) | 0)
+#define PINMUX_GPIO136__FUNC_SDA4 (MTK_PIN_NO(136) | 1)
+#define PINMUX_GPIO136__FUNC_TP_URXD1_AO (MTK_PIN_NO(136) | 2)
+#define PINMUX_GPIO136__FUNC_URXD1 (MTK_PIN_NO(136) | 3)
+#define PINMUX_GPIO136__FUNC_SCP_SDA0 (MTK_PIN_NO(136) | 4)
+#define PINMUX_GPIO136__FUNC_SCP_SDA1 (MTK_PIN_NO(136) | 5)
+#define PINMUX_GPIO136__FUNC_DBG_MON_B11 (MTK_PIN_NO(136) | 7)
+
+#define PINMUX_GPIO137__FUNC_GPIO137 (MTK_PIN_NO(137) | 0)
+#define PINMUX_GPIO137__FUNC_SCL5 (MTK_PIN_NO(137) | 1)
+#define PINMUX_GPIO137__FUNC_UTXD2 (MTK_PIN_NO(137) | 2)
+#define PINMUX_GPIO137__FUNC_UCTS1 (MTK_PIN_NO(137) | 3)
+#define PINMUX_GPIO137__FUNC_SCP_SCL0 (MTK_PIN_NO(137) | 4)
+#define PINMUX_GPIO137__FUNC_SCP_SCL1 (MTK_PIN_NO(137) | 5)
+
+#define PINMUX_GPIO138__FUNC_GPIO138 (MTK_PIN_NO(138) | 0)
+#define PINMUX_GPIO138__FUNC_SDA5 (MTK_PIN_NO(138) | 1)
+#define PINMUX_GPIO138__FUNC_URXD2 (MTK_PIN_NO(138) | 2)
+#define PINMUX_GPIO138__FUNC_URTS1 (MTK_PIN_NO(138) | 3)
+#define PINMUX_GPIO138__FUNC_SCP_SDA0 (MTK_PIN_NO(138) | 4)
+#define PINMUX_GPIO138__FUNC_SCP_SDA1 (MTK_PIN_NO(138) | 5)
+
+#define PINMUX_GPIO139__FUNC_GPIO139 (MTK_PIN_NO(139) | 0)
+#define PINMUX_GPIO139__FUNC_SCL6 (MTK_PIN_NO(139) | 1)
+#define PINMUX_GPIO139__FUNC_UTXD1 (MTK_PIN_NO(139) | 2)
+#define PINMUX_GPIO139__FUNC_TP_UTXD1_AO (MTK_PIN_NO(139) | 3)
+#define PINMUX_GPIO139__FUNC_SCP_SCL0 (MTK_PIN_NO(139) | 4)
+#define PINMUX_GPIO139__FUNC_SCP_SCL1 (MTK_PIN_NO(139) | 5)
+#define PINMUX_GPIO139__FUNC_DBG_MON_B12 (MTK_PIN_NO(139) | 7)
+
+#define PINMUX_GPIO140__FUNC_GPIO140 (MTK_PIN_NO(140) | 0)
+#define PINMUX_GPIO140__FUNC_SDA6 (MTK_PIN_NO(140) | 1)
+#define PINMUX_GPIO140__FUNC_URXD1 (MTK_PIN_NO(140) | 2)
+#define PINMUX_GPIO140__FUNC_TP_URXD1_AO (MTK_PIN_NO(140) | 3)
+#define PINMUX_GPIO140__FUNC_SCP_SDA0 (MTK_PIN_NO(140) | 4)
+#define PINMUX_GPIO140__FUNC_SCP_SDA1 (MTK_PIN_NO(140) | 5)
+#define PINMUX_GPIO140__FUNC_DBG_MON_B13 (MTK_PIN_NO(140) | 7)
+
+#define PINMUX_GPIO141__FUNC_GPIO141 (MTK_PIN_NO(141) | 0)
+#define PINMUX_GPIO141__FUNC_SCL7 (MTK_PIN_NO(141) | 1)
+#define PINMUX_GPIO141__FUNC_URTS0 (MTK_PIN_NO(141) | 2)
+#define PINMUX_GPIO141__FUNC_TP_URTS1_AO (MTK_PIN_NO(141) | 3)
+#define PINMUX_GPIO141__FUNC_SCP_SCL0 (MTK_PIN_NO(141) | 4)
+#define PINMUX_GPIO141__FUNC_SCP_SCL1 (MTK_PIN_NO(141) | 5)
+#define PINMUX_GPIO141__FUNC_UDI_TCK (MTK_PIN_NO(141) | 6)
+#define PINMUX_GPIO141__FUNC_DBG_MON_B14 (MTK_PIN_NO(141) | 7)
+
+#define PINMUX_GPIO142__FUNC_GPIO142 (MTK_PIN_NO(142) | 0)
+#define PINMUX_GPIO142__FUNC_SDA7 (MTK_PIN_NO(142) | 1)
+#define PINMUX_GPIO142__FUNC_UCTS0 (MTK_PIN_NO(142) | 2)
+#define PINMUX_GPIO142__FUNC_TP_UCTS1_AO (MTK_PIN_NO(142) | 3)
+#define PINMUX_GPIO142__FUNC_SCP_SDA0 (MTK_PIN_NO(142) | 4)
+#define PINMUX_GPIO142__FUNC_SCP_SDA1 (MTK_PIN_NO(142) | 5)
+
+#define PINMUX_GPIO143__FUNC_GPIO143 (MTK_PIN_NO(143) | 0)
+#define PINMUX_GPIO143__FUNC_SCL8 (MTK_PIN_NO(143) | 1)
+#define PINMUX_GPIO143__FUNC_SCP_SCL0 (MTK_PIN_NO(143) | 4)
+#define PINMUX_GPIO143__FUNC_SCP_SCL1 (MTK_PIN_NO(143) | 5)
+#define PINMUX_GPIO143__FUNC_DBG_MON_B16 (MTK_PIN_NO(143) | 7)
+
+#define PINMUX_GPIO144__FUNC_GPIO144 (MTK_PIN_NO(144) | 0)
+#define PINMUX_GPIO144__FUNC_SDA8 (MTK_PIN_NO(144) | 1)
+#define PINMUX_GPIO144__FUNC_SCP_SDA0 (MTK_PIN_NO(144) | 4)
+#define PINMUX_GPIO144__FUNC_SCP_SDA1 (MTK_PIN_NO(144) | 5)
+#define PINMUX_GPIO144__FUNC_DBG_MON_B17 (MTK_PIN_NO(144) | 7)
+
+#define PINMUX_GPIO145__FUNC_GPIO145 (MTK_PIN_NO(145) | 0)
+#define PINMUX_GPIO145__FUNC_SCL9 (MTK_PIN_NO(145) | 1)
+#define PINMUX_GPIO145__FUNC_CMVREF1 (MTK_PIN_NO(145) | 2)
+#define PINMUX_GPIO145__FUNC_GPS_PPS (MTK_PIN_NO(145) | 3)
+#define PINMUX_GPIO145__FUNC_SCP_SCL0 (MTK_PIN_NO(145) | 4)
+#define PINMUX_GPIO145__FUNC_SCP_SCL1 (MTK_PIN_NO(145) | 5)
+#define PINMUX_GPIO145__FUNC_DBG_MON_B18 (MTK_PIN_NO(145) | 7)
+
+#define PINMUX_GPIO146__FUNC_GPIO146 (MTK_PIN_NO(146) | 0)
+#define PINMUX_GPIO146__FUNC_SDA9 (MTK_PIN_NO(146) | 1)
+#define PINMUX_GPIO146__FUNC_CMVREF0 (MTK_PIN_NO(146) | 2)
+#define PINMUX_GPIO146__FUNC_SCP_SDA0 (MTK_PIN_NO(146) | 4)
+#define PINMUX_GPIO146__FUNC_SCP_SDA1 (MTK_PIN_NO(146) | 5)
+#define PINMUX_GPIO146__FUNC_DBG_MON_B19 (MTK_PIN_NO(146) | 7)
+
+#define PINMUX_GPIO147__FUNC_GPIO147 (MTK_PIN_NO(147) | 0)
+#define PINMUX_GPIO147__FUNC_CMFLASH0 (MTK_PIN_NO(147) | 1)
+#define PINMUX_GPIO147__FUNC_LVTS_SDI (MTK_PIN_NO(147) | 2)
+#define PINMUX_GPIO147__FUNC_DPI_DATA12 (MTK_PIN_NO(147) | 3)
+#define PINMUX_GPIO147__FUNC_TP_GPIO0_AO (MTK_PIN_NO(147) | 4)
+#define PINMUX_GPIO147__FUNC_ANT_SEL3 (MTK_PIN_NO(147) | 5)
+#define PINMUX_GPIO147__FUNC_DFD_TCK_XI (MTK_PIN_NO(147) | 6)
+#define PINMUX_GPIO147__FUNC_DBG_MON_B20 (MTK_PIN_NO(147) | 7)
+
+#define PINMUX_GPIO148__FUNC_GPIO148 (MTK_PIN_NO(148) | 0)
+#define PINMUX_GPIO148__FUNC_CMFLASH1 (MTK_PIN_NO(148) | 1)
+#define PINMUX_GPIO148__FUNC_LVTS_SCF (MTK_PIN_NO(148) | 2)
+#define PINMUX_GPIO148__FUNC_DPI_DATA13 (MTK_PIN_NO(148) | 3)
+#define PINMUX_GPIO148__FUNC_TP_GPIO1_AO (MTK_PIN_NO(148) | 4)
+#define PINMUX_GPIO148__FUNC_ANT_SEL4 (MTK_PIN_NO(148) | 5)
+#define PINMUX_GPIO148__FUNC_DFD_TMS (MTK_PIN_NO(148) | 6)
+#define PINMUX_GPIO148__FUNC_DBG_MON_B21 (MTK_PIN_NO(148) | 7)
+
+#define PINMUX_GPIO149__FUNC_GPIO149 (MTK_PIN_NO(149) | 0)
+#define PINMUX_GPIO149__FUNC_CMFLASH2 (MTK_PIN_NO(149) | 1)
+#define PINMUX_GPIO149__FUNC_CLKM0 (MTK_PIN_NO(149) | 2)
+#define PINMUX_GPIO149__FUNC_DPI_DATA14 (MTK_PIN_NO(149) | 3)
+#define PINMUX_GPIO149__FUNC_TP_GPIO2_AO (MTK_PIN_NO(149) | 4)
+#define PINMUX_GPIO149__FUNC_ANT_SEL5 (MTK_PIN_NO(149) | 5)
+#define PINMUX_GPIO149__FUNC_DFD_TDI (MTK_PIN_NO(149) | 6)
+#define PINMUX_GPIO149__FUNC_DBG_MON_B22 (MTK_PIN_NO(149) | 7)
+
+#define PINMUX_GPIO150__FUNC_GPIO150 (MTK_PIN_NO(150) | 0)
+#define PINMUX_GPIO150__FUNC_CLKM1 (MTK_PIN_NO(150) | 2)
+#define PINMUX_GPIO150__FUNC_DPI_DATA15 (MTK_PIN_NO(150) | 3)
+#define PINMUX_GPIO150__FUNC_TP_GPIO3_AO (MTK_PIN_NO(150) | 4)
+#define PINMUX_GPIO150__FUNC_ANT_SEL6 (MTK_PIN_NO(150) | 5)
+#define PINMUX_GPIO150__FUNC_DFD_TDO (MTK_PIN_NO(150) | 6)
+#define PINMUX_GPIO150__FUNC_DBG_MON_B23 (MTK_PIN_NO(150) | 7)
+
+#define PINMUX_GPIO151__FUNC_GPIO151 (MTK_PIN_NO(151) | 0)
+#define PINMUX_GPIO151__FUNC_GPS_L1_ELNA_EN (MTK_PIN_NO(151) | 1)
+#define PINMUX_GPIO151__FUNC_CLKM2 (MTK_PIN_NO(151) | 2)
+#define PINMUX_GPIO151__FUNC_DPI_DATA16 (MTK_PIN_NO(151) | 3)
+#define PINMUX_GPIO151__FUNC_TP_GPIO4_AO (MTK_PIN_NO(151) | 4)
+#define PINMUX_GPIO151__FUNC_ANT_SEL7 (MTK_PIN_NO(151) | 5)
+#define PINMUX_GPIO151__FUNC_UDI_TMS (MTK_PIN_NO(151) | 6)
+#define PINMUX_GPIO151__FUNC_DBG_MON_B24 (MTK_PIN_NO(151) | 7)
+
+#define PINMUX_GPIO152__FUNC_GPIO152 (MTK_PIN_NO(152) | 0)
+#define PINMUX_GPIO152__FUNC_CLKM3 (MTK_PIN_NO(152) | 2)
+#define PINMUX_GPIO152__FUNC_DPI_DATA17 (MTK_PIN_NO(152) | 3)
+#define PINMUX_GPIO152__FUNC_TP_GPIO5_AO (MTK_PIN_NO(152) | 4)
+
+#define PINMUX_GPIO153__FUNC_GPIO153 (MTK_PIN_NO(153) | 0)
+#define PINMUX_GPIO153__FUNC_CONN_TCXOENA_REQ (MTK_PIN_NO(153) | 1)
+#define PINMUX_GPIO153__FUNC_DPI_DATA18 (MTK_PIN_NO(153) | 3)
+#define PINMUX_GPIO153__FUNC_TP_GPIO6_AO (MTK_PIN_NO(153) | 4)
+#define PINMUX_GPIO153__FUNC_UDI_TDI (MTK_PIN_NO(153) | 6)
+#define PINMUX_GPIO153__FUNC_DBG_MON_B26 (MTK_PIN_NO(153) | 7)
+
+#define PINMUX_GPIO154__FUNC_GPIO154 (MTK_PIN_NO(154) | 0)
+#define PINMUX_GPIO154__FUNC_PWM0 (MTK_PIN_NO(154) | 1)
+#define PINMUX_GPIO154__FUNC_CMVREF2 (MTK_PIN_NO(154) | 2)
+#define PINMUX_GPIO154__FUNC_DPI_DATA19 (MTK_PIN_NO(154) | 3)
+#define PINMUX_GPIO154__FUNC_TP_GPIO7_AO (MTK_PIN_NO(154) | 4)
+#define PINMUX_GPIO154__FUNC_UDI_TDO (MTK_PIN_NO(154) | 6)
+#define PINMUX_GPIO154__FUNC_DBG_MON_B27 (MTK_PIN_NO(154) | 7)
+
+#define PINMUX_GPIO155__FUNC_GPIO155 (MTK_PIN_NO(155) | 0)
+#define PINMUX_GPIO155__FUNC_PWM1 (MTK_PIN_NO(155) | 1)
+#define PINMUX_GPIO155__FUNC_CMVREF1 (MTK_PIN_NO(155) | 2)
+#define PINMUX_GPIO155__FUNC_DPI_DATA20 (MTK_PIN_NO(155) | 3)
+#define PINMUX_GPIO155__FUNC_UDI_NTRST (MTK_PIN_NO(155) | 6)
+#define PINMUX_GPIO155__FUNC_DBG_MON_B28 (MTK_PIN_NO(155) | 7)
+
+#define PINMUX_GPIO156__FUNC_GPIO156 (MTK_PIN_NO(156) | 0)
+#define PINMUX_GPIO156__FUNC_PWM2 (MTK_PIN_NO(156) | 1)
+#define PINMUX_GPIO156__FUNC_CMVREF0 (MTK_PIN_NO(156) | 2)
+#define PINMUX_GPIO156__FUNC_DPI_DATA21 (MTK_PIN_NO(156) | 3)
+
+#define PINMUX_GPIO157__FUNC_GPIO157 (MTK_PIN_NO(157) | 0)
+#define PINMUX_GPIO157__FUNC_PWRAP_SPI0_CSN (MTK_PIN_NO(157) | 1)
+
+#define PINMUX_GPIO158__FUNC_GPIO158 (MTK_PIN_NO(158) | 0)
+#define PINMUX_GPIO158__FUNC_PWRAP_SPI0_CK (MTK_PIN_NO(158) | 1)
+
+#define PINMUX_GPIO159__FUNC_GPIO159 (MTK_PIN_NO(159) | 0)
+#define PINMUX_GPIO159__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(159) | 1)
+#define PINMUX_GPIO159__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(159) | 2)
+
+#define PINMUX_GPIO160__FUNC_GPIO160 (MTK_PIN_NO(160) | 0)
+#define PINMUX_GPIO160__FUNC_PWRAP_SPI0_MI (MTK_PIN_NO(160) | 1)
+#define PINMUX_GPIO160__FUNC_PWRAP_SPI0_MO (MTK_PIN_NO(160) | 2)
+
+#define PINMUX_GPIO161__FUNC_GPIO161 (MTK_PIN_NO(161) | 0)
+#define PINMUX_GPIO161__FUNC_SRCLKENA0 (MTK_PIN_NO(161) | 1)
+
+#define PINMUX_GPIO162__FUNC_GPIO162 (MTK_PIN_NO(162) | 0)
+#define PINMUX_GPIO162__FUNC_SRCLKENA1 (MTK_PIN_NO(162) | 1)
+#define PINMUX_GPIO162__FUNC_DBG_MON_A31 (MTK_PIN_NO(162) | 7)
+
+#define PINMUX_GPIO163__FUNC_GPIO163 (MTK_PIN_NO(163) | 0)
+#define PINMUX_GPIO163__FUNC_SCP_VREQ_VAO (MTK_PIN_NO(163) | 1)
+#define PINMUX_GPIO163__FUNC_DVFSRC_EXT_REQ (MTK_PIN_NO(163) | 2)
+
+#define PINMUX_GPIO164__FUNC_GPIO164 (MTK_PIN_NO(164) | 0)
+#define PINMUX_GPIO164__FUNC_RTC32K_CK (MTK_PIN_NO(164) | 1)
+
+#define PINMUX_GPIO165__FUNC_GPIO165 (MTK_PIN_NO(165) | 0)
+#define PINMUX_GPIO165__FUNC_WATCHDOG (MTK_PIN_NO(165) | 1)
+
+#define PINMUX_GPIO166__FUNC_GPIO166 (MTK_PIN_NO(166) | 0)
+#define PINMUX_GPIO166__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(166) | 1)
+#define PINMUX_GPIO166__FUNC_AUD_CLK_MISO (MTK_PIN_NO(166) | 2)
+#define PINMUX_GPIO166__FUNC_I2S1_MCK (MTK_PIN_NO(166) | 3)
+
+#define PINMUX_GPIO167__FUNC_GPIO167 (MTK_PIN_NO(167) | 0)
+#define PINMUX_GPIO167__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(167) | 1)
+#define PINMUX_GPIO167__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(167) | 2)
+#define PINMUX_GPIO167__FUNC_I2S1_BCK (MTK_PIN_NO(167) | 3)
+
+#define PINMUX_GPIO168__FUNC_GPIO168 (MTK_PIN_NO(168) | 0)
+#define PINMUX_GPIO168__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(168) | 1)
+#define PINMUX_GPIO168__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(168) | 2)
+#define PINMUX_GPIO168__FUNC_I2S1_LRCK (MTK_PIN_NO(168) | 3)
+
+#define PINMUX_GPIO169__FUNC_GPIO169 (MTK_PIN_NO(169) | 0)
+#define PINMUX_GPIO169__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(169) | 1)
+#define PINMUX_GPIO169__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(169) | 2)
+#define PINMUX_GPIO169__FUNC_I2S1_DO (MTK_PIN_NO(169) | 3)
+
+#define PINMUX_GPIO170__FUNC_GPIO170 (MTK_PIN_NO(170) | 0)
+#define PINMUX_GPIO170__FUNC_AUD_CLK_MISO (MTK_PIN_NO(170) | 1)
+#define PINMUX_GPIO170__FUNC_AUD_CLK_MOSI (MTK_PIN_NO(170) | 2)
+#define PINMUX_GPIO170__FUNC_I2S2_MCK (MTK_PIN_NO(170) | 3)
+
+#define PINMUX_GPIO171__FUNC_GPIO171 (MTK_PIN_NO(171) | 0)
+#define PINMUX_GPIO171__FUNC_AUD_SYNC_MISO (MTK_PIN_NO(171) | 1)
+#define PINMUX_GPIO171__FUNC_AUD_SYNC_MOSI (MTK_PIN_NO(171) | 2)
+#define PINMUX_GPIO171__FUNC_I2S2_BCK (MTK_PIN_NO(171) | 3)
+
+#define PINMUX_GPIO172__FUNC_GPIO172 (MTK_PIN_NO(172) | 0)
+#define PINMUX_GPIO172__FUNC_AUD_DAT_MISO0 (MTK_PIN_NO(172) | 1)
+#define PINMUX_GPIO172__FUNC_AUD_DAT_MOSI0 (MTK_PIN_NO(172) | 2)
+#define PINMUX_GPIO172__FUNC_I2S2_LRCK (MTK_PIN_NO(172) | 3)
+#define PINMUX_GPIO172__FUNC_VOW_DAT_MISO (MTK_PIN_NO(172) | 4)
+
+#define PINMUX_GPIO173__FUNC_GPIO173 (MTK_PIN_NO(173) | 0)
+#define PINMUX_GPIO173__FUNC_AUD_DAT_MISO1 (MTK_PIN_NO(173) | 1)
+#define PINMUX_GPIO173__FUNC_AUD_DAT_MOSI1 (MTK_PIN_NO(173) | 2)
+#define PINMUX_GPIO173__FUNC_I2S2_DI (MTK_PIN_NO(173) | 3)
+#define PINMUX_GPIO173__FUNC_VOW_CLK_MISO (MTK_PIN_NO(173) | 4)
+
+#define PINMUX_GPIO174__FUNC_GPIO174 (MTK_PIN_NO(174) | 0)
+#define PINMUX_GPIO174__FUNC_CONN_TOP_CLK (MTK_PIN_NO(174) | 1)
+#define PINMUX_GPIO174__FUNC_AUXIF_CLK (MTK_PIN_NO(174) | 2)
+#define PINMUX_GPIO174__FUNC_DFD_TCK_XI (MTK_PIN_NO(174) | 3)
+#define PINMUX_GPIO174__FUNC_DBG_MON_B3 (MTK_PIN_NO(174) | 7)
+
+#define PINMUX_GPIO175__FUNC_GPIO175 (MTK_PIN_NO(175) | 0)
+#define PINMUX_GPIO175__FUNC_CONN_TOP_DATA (MTK_PIN_NO(175) | 1)
+#define PINMUX_GPIO175__FUNC_AUXIF_ST (MTK_PIN_NO(175) | 2)
+#define PINMUX_GPIO175__FUNC_DFD_TMS (MTK_PIN_NO(175) | 3)
+#define PINMUX_GPIO175__FUNC_DBG_MON_B15 (MTK_PIN_NO(175) | 7)
+
+#define PINMUX_GPIO176__FUNC_GPIO176 (MTK_PIN_NO(176) | 0)
+#define PINMUX_GPIO176__FUNC_CONN_BT_CLK (MTK_PIN_NO(176) | 1)
+#define PINMUX_GPIO176__FUNC_DFD_TDI (MTK_PIN_NO(176) | 3)
+#define PINMUX_GPIO176__FUNC_DBG_MON_B2 (MTK_PIN_NO(176) | 7)
+
+#define PINMUX_GPIO177__FUNC_GPIO177 (MTK_PIN_NO(177) | 0)
+#define PINMUX_GPIO177__FUNC_CONN_BT_DATA (MTK_PIN_NO(177) | 1)
+#define PINMUX_GPIO177__FUNC_DFD_TDO (MTK_PIN_NO(177) | 3)
+
+#define PINMUX_GPIO178__FUNC_GPIO178 (MTK_PIN_NO(178) | 0)
+#define PINMUX_GPIO178__FUNC_CONN_HRST_B (MTK_PIN_NO(178) | 1)
+#define PINMUX_GPIO178__FUNC_UDI_TMS (MTK_PIN_NO(178) | 3)
+#define PINMUX_GPIO178__FUNC_DBG_MON_B25 (MTK_PIN_NO(178) | 7)
+
+#define PINMUX_GPIO179__FUNC_GPIO179 (MTK_PIN_NO(179) | 0)
+#define PINMUX_GPIO179__FUNC_CONN_WB_PTA (MTK_PIN_NO(179) | 1)
+#define PINMUX_GPIO179__FUNC_UDI_TCK (MTK_PIN_NO(179) | 3)
+#define PINMUX_GPIO179__FUNC_DBG_MON_B29 (MTK_PIN_NO(179) | 7)
+
+#define PINMUX_GPIO180__FUNC_GPIO180 (MTK_PIN_NO(180) | 0)
+#define PINMUX_GPIO180__FUNC_CONN_WF_CTRL0 (MTK_PIN_NO(180) | 1)
+#define PINMUX_GPIO180__FUNC_UDI_TDI (MTK_PIN_NO(180) | 3)
+
+#define PINMUX_GPIO181__FUNC_GPIO181 (MTK_PIN_NO(181) | 0)
+#define PINMUX_GPIO181__FUNC_CONN_WF_CTRL1 (MTK_PIN_NO(181) | 1)
+#define PINMUX_GPIO181__FUNC_UDI_TDO (MTK_PIN_NO(181) | 3)
+
+#define PINMUX_GPIO182__FUNC_GPIO182 (MTK_PIN_NO(182) | 0)
+#define PINMUX_GPIO182__FUNC_CONN_WF_CTRL2 (MTK_PIN_NO(182) | 1)
+#define PINMUX_GPIO182__FUNC_UDI_NTRST (MTK_PIN_NO(182) | 3)
+
+#define PINMUX_GPIO183__FUNC_GPIO183 (MTK_PIN_NO(183) | 0)
+#define PINMUX_GPIO183__FUNC_SPMI_SCL (MTK_PIN_NO(183) | 1)
+
+#define PINMUX_GPIO184__FUNC_GPIO184 (MTK_PIN_NO(184) | 0)
+#define PINMUX_GPIO184__FUNC_SPMI_SDA (MTK_PIN_NO(184) | 1)
+
+#endif /* __MT8168-PINFUNC_H */
-- 
2.25.5



From guoren at kernel.org  Thu Jan 20 22:25:29 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 21 Jan 2022 14:25:29 +0800
Subject: [PATCH V3 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAK8P3a0LxB3we9wHOa4OPmNow6wz5NP49zeYhh7QXNv-MiR8UA@mail.gmail.com>
References: <20220120073911.99857-9-guoren@kernel.org>
 <CAK8P3a0LxB3we9wHOa4OPmNow6wz5NP49zeYhh7QXNv-MiR8UA@mail.gmail.com>
Message-ID: <CAJF2gTQVUF4LSO0a6_MV8x-UAiJw32pAFyS1oPNLXhcEaemzqg@mail.gmail.com>

On Thu, Jan 20, 2022 at 10:43 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> >
> >  /* The array of function pointers for syscalls. */
> >  extern void * const sys_call_table[];
> > +#ifdef CONFIG_COMPAT
> > +extern void * const compat_sys_call_table[];
> > +#endif
>
> No need for the #ifdef, the normal convention is to just define the
> extern declaration unconditionally for symbols that may or may not be defined.
Okay

>
> > +COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
> > +                      arg_u32p(length))
> > +{
> > +       return ksys_truncate(pathname, arg_u64(length));
> > +}
>
> Are you sure these are the right calling conventions? According to [1],
> I think the 64-bit argument should be in an aligned pair of registers,
> which means you need an extra pad argument as in the arm64 version
> of these functions. Same for ftruncate64, pread64, pwrite64, and
> readahead.

[1] has abandoned.

See:
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc

Ltp test results:

ftruncate01                                        PASS       0
ftruncate01_64                                     PASS       0
ftruncate03                                        PASS       0
ftruncate03_64                                     PASS       0
ftruncate04                                        CONF       32
ftruncate04_64                                     CONF       32

truncate02                                         PASS       0
truncate02_64                                      PASS       0
truncate03                                         PASS       0
truncate03_64                                      PASS       0

pread01                                            PASS       0
pread01_64                                         PASS       0
pread02                                            PASS       0
pread02_64                                         PASS       0
pread03                                            PASS       0
pread03_64                                         PASS       0

pwrite01_64                                        PASS       0
pwrite02_64                                        PASS       0
pwrite03_64                                        PASS       0
pwrite04_64                                        PASS       0

readahead01                                        PASS       0
readahead02                                        CONF       32


>
> > +COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, arg_u32p(length))
> > +{
> > +       return ksys_ftruncate(fd, arg_u64(length));
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
> > +                      arg_u32p(offset), arg_u32p(len))
> > +{
> > +       return ksys_fallocate(fd, mode, arg_u64(offset), arg_u64(len));
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
> > +                      size_t, count, arg_u32p(pos))
> > +{
> > +       return ksys_pread64(fd, buf, count, arg_u64(pos));
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd,
> > +                      const char __user *, buf, size_t, count, arg_u32p(pos))
> > +{
> > +       return ksys_pwrite64(fd, buf, count, arg_u64(pos));
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, arg_u32p(offset),
> > +                      arg_u32p(nbytes), unsigned int, flags)
> > +{
> > +       return ksys_sync_file_range(fd, arg_u64(offset), arg_u64(nbytes),
> > +                                   flags);
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE4(readahead, int, fd, arg_u32p(offset),
> > +                      size_t, count)
> > +{
> > +       return ksys_readahead(fd, arg_u64(offset), count);
> > +}
> > +
> > +COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, int, advice, arg_u32p(offset),
> > +                      arg_u32p(len))
> > +{
> > +       return ksys_fadvise64_64(fd, arg_u64(offset), arg_u64(len), advice);
> > +}
>
> I still feel like these should be the common implementations next to the
> native handlers inside of an #ifdef CONFIG_COMPAT.
>
> The names clash with the custom versions defined for powerpc and sparc,
> but the duplicates look compatible if you can account for the padded
> argument and the lo/hi order of the pairs, so could just be removed here
> (all other architectures use custom function names instead).
I would try it later.

>
>         Arnd
>
> [1] https://riscv.org/wp-content/uploads/2015/01/riscv-calling.pdf



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From guoren at kernel.org  Thu Jan 20 22:35:52 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 21 Jan 2022 14:35:52 +0800
Subject: [PATCH V3 17/17] KVM: compat: riscv: Prevent KVM_COMPAT from
 being selected
In-Reply-To: <CAK8P3a1_qwRpfHRyF75WEqfxGxgVnfB15vNS-egQctx7R5-DvA@mail.gmail.com>
References: <20220120073911.99857-18-guoren@kernel.org>
 <CAK8P3a1_qwRpfHRyF75WEqfxGxgVnfB15vNS-egQctx7R5-DvA@mail.gmail.com>
Message-ID: <CAJF2gTTCwOiTPJO1B6Asa2NUNR0D624t26nnA8S4vrSSax8R-Q@mail.gmail.com>

On Thu, Jan 20, 2022 at 6:32 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > Current riscv doesn't support the 32bit KVM/arm API. Let's make it
> > clear by not selecting KVM_COMPAT.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > ---
> >  virt/kvm/Kconfig | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
> > index f4834c20e4a6..a8c5c9f06b3c 100644
> > --- a/virt/kvm/Kconfig
> > +++ b/virt/kvm/Kconfig
> > @@ -53,7 +53,7 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
> >
> >  config KVM_COMPAT
> >         def_bool y
> > -       depends on KVM && COMPAT && !(S390 || ARM64)
> > +       depends on KVM && COMPAT && !(S390 || ARM64 || RISCV)
>
> Maybe this should be flipped around into a positive list now?
I think it's another patch to do that. Not in this series.

> The remaining architectures would be mips, powerpc and x86, but it's unclear
> if this actually meant to work on all of them, or any potential ones
> added in the
Yes, it's unclear and arch maintainers need to confirm that.

> future.
>
>        Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From cgel.zte at gmail.com  Thu Jan 20 22:52:16 2022
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Fri, 21 Jan 2022 06:52:16 +0000
Subject: [PATCH linux-next] arm64: kexec: Support the case of VA_BITS=39 in
 trans_pgd_idmap_page()
Message-ID: <20220121065216.1001021-1-si.hao@zte.com.cn>

From: sihao <si.hao at zte.com.cn>

When the values of CONFIG_ARM64_VA_BITS and CONFIG_ARM64_PA_BITS are not
equal, the following panic occurs when kexec is executed.

This happens because trans_pgd_idmap_page() does not support VA_BITS=39.
So the patch supports the case of VA_BITS=39.

->kexec -e
[   36.168728] 000: kexec_core: Starting new kernel
[   36.168735] 000: Disabling non-boot CPUs ...
[   36.168739] 000: Bye!
[   36.189457] 000: Unable to handle kernel paging request at virtual
address 000000000fb3c000
[   36.189460] 000: Mem abort info:
[   36.189462] 000:   ESR = 0x86000006
[   36.189463] 000:   EC = 0x21: IABT (current EL), IL = 32 bits
[   36.189466] 000:   SET = 0, FnV = 0
[   36.189468] 000:   EA = 0, S1PTW = 0
[   36.189470] 000: user pgtable: 4k pages, 39-bit VAs,
pgdp=000000000de68000
[   36.189475] 000: [000000000fb3c000] pgd=000000000fb24003,
pud=000000000fb24003, pmd=0000000000000000
[   36.189482] 000: Internal error: Oops: 86000006 [#1] PREEMPT SMP
[   36.189488] 000: Modules linked in:
[   36.189493] 000: CPU: 0 PID: 825 Comm: kexec Not tainted XXX
[   36.189498] 000: Hardware name: XXX
[   36.189500] 000: pstate: 600003c5 (nZCv DAIF -PAN -UAO)
[   36.189503] 000: pc : 0xfb3c000
[   36.189510] 000: lr : machine_kexec+0x2a4/0x300
[   36.189520] 000: sp : ffffffc0111fbc90
[   36.189523] 000: x29: ffffffc0111fbc90 x28: ffffff800fb66440
[   36.189527] 000: x27: 0000000000000000 x26: 0000000000000000
[   36.189531] 000: x25: 0000000056000000 x24: 0000000000000015
[   36.189534] 000: x23: 000000000de64000 x22: 000000000fb3c000
[   36.189538] 000: x21: ffffffc010699298 x20: ffffffc010752e90
[   36.189542] 000: x19: ffffff800acc0400 x18: 0000000000000001
[   36.189545] 000: x17: 0000000000000000 x16: 0000000000000000
[   36.189549] 000: x15: ffffff800fb66838 x14: ffffffffffffffff
[   36.189552] 000: x13: ffffffc0108f0b48 x12: ffffffc0111fbba0
[   36.189556] 000: x11: ffffffc01088d450 x10: ffffffc01088d468
[   36.189559] 000: x9 : 0000000000000001 x8 : 0000000000024d30
[   36.189563] 000: x7 : ffffffc0108f0738 x6 : ffffffc0108ebe18
[   36.189566] 000: x5 : 0000000000024d30 x4 : 0000000000004920
[   36.189570] 000: x3 : 0000000000000006 x2 : b9bb936edd96cd00
[   36.189573] 000: x1 : 0000000000000000 x0 : ffffff800acc0400
[   36.189576] 000: Call trace:
[   36.189578] 000:  0xfb3c000
[   36.189580] 000:  kernel_kexec+0x98/0xe8
[   36.189586] 000:  __do_sys_reboot+0x1d0/0x208
[   36.189593] 000:  __arm64_sys_reboot+0x2c/0x38
[   36.189597] 000:  el0_svc_common.constprop.0+0x74/0x168
[   36.189603] 000:  el0_svc_handler+0x80/0xa0
[   36.189607] 000:  el0_svc+0x8/0x204
[   36.189616] 000: Code: bad PC value
[   36.189621] 000: ---[ end trace f930c021f9bf10a9 ]---
[   36.189625] 000: Kernel panic - not syncing: Fatal exception

Reported-by: sihao <si.hao at zte.com.cn>
Signed-off-by: sihao <si.hao at zte.com.cn>
---
 arch/arm64/mm/trans_pgd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
index d7da8ca40d2e..3d88185adcf5 100644
--- a/arch/arm64/mm/trans_pgd.c
+++ b/arch/arm64/mm/trans_pgd.c
@@ -232,7 +232,7 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0,
 {
 	phys_addr_t dst_addr = virt_to_phys(page);
 	unsigned long pfn = __phys_to_pfn(dst_addr);
-	int max_msb = (dst_addr & GENMASK(52, 48)) ? 51 : 47;
+	int max_msb = (dst_addr & GENMASK(52, VA_BITS)) ? 51 : (VA_BITS - 1);
 	int bits_mapped = PAGE_SHIFT - 4;
 	unsigned long level_mask, prev_level_entry, *levels[4];
 	int this_level, index, level_lsb, level_msb;
-- 
2.25.1



From guoren at kernel.org  Thu Jan 20 22:59:30 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 21 Jan 2022 14:59:30 +0800
Subject: [PATCH V3 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <CAK8P3a00uYPBBphpipBoqCnGFwr_C9vDzS1p1iLN==YTVOARug@mail.gmail.com>
References: <20220120073911.99857-7-guoren@kernel.org>
 <CAK8P3a00uYPBBphpipBoqCnGFwr_C9vDzS1p1iLN==YTVOARug@mail.gmail.com>
Message-ID: <CAJF2gTQVgDkyVdoezsrA4AN=9C7RMOxZBCyLB2JvQkKYsLud3Q@mail.gmail.com>

On Thu, Jan 20, 2022 at 5:35 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:38 AM <guoren at kernel.org> wrote:
>
> > @@ -0,0 +1,136 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +#ifndef __ASM_COMPAT_H
> > +#define __ASM_COMPAT_H
> > +
> > +#define compat_mode_t  compat_mode_t
> > +typedef u16            compat_mode_t;
>
> I think this one is wrong, as rv32 should get the native definition from
>
> include/uapi/asm-generic/posix_types.h:typedef unsigned int     __kernel_mode_t;
>
> I think it works if you just remove those two lines. The rest looks good to me.
Yes, you are right. compat_mode_t should be unsigned int.

>
>        Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From guoren at kernel.org  Thu Jan 20 23:12:56 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 21 Jan 2022 15:12:56 +0800
Subject: [PATCH V3 13/17] riscv: compat: signal: Add rt_frame
 implementation
In-Reply-To: <CAK8P3a03-3QTC-vxmnbouK7wBd8iunPGZpX0-Jf6ntS1DY0E=w@mail.gmail.com>
References: <20220120073911.99857-14-guoren@kernel.org>
 <CAK8P3a03-3QTC-vxmnbouK7wBd8iunPGZpX0-Jf6ntS1DY0E=w@mail.gmail.com>
Message-ID: <CAJF2gTRMWj0yVLn2=16Gu1O-6tuqLaxcdduw0YnDK6vrizJEsQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 6:31 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > Implement compat_setup_rt_frame for sigcontext save & restore. The
> > main process is the same with signal, but the rv32 pt_regs' size
> > is different from rv64's, so we needs convert them.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Cc: Arnd Bergmann <arnd at arndb.de>
>
> I hope someone else can properly review this part, it's not my area
> but it looks complex enough that it could bring subtle bugs.
Here are ltp signal test results:

sigaction01                                        PASS       0
sigaction02                                        PASS       0
sigaltstack01                                      PASS       0
sigaltstack02                                      PASS       0
sighold02                                          PASS       0
signal01                                           PASS       0
signal02                                           PASS       0
signal03                                           PASS       0
signal04                                           PASS       0
signal05                                           PASS       0
signal06                                           CONF       32
signalfd01                                         PASS       0
signalfd4_01                                       PASS       0
signalfd4_02                                       PASS       0
sigpending02                                       PASS       0
sigprocmask01                                      PASS       0
sigrelse01                                         PASS       0
sigsuspend01                                       PASS       0
sigtimedwait01                                     PASS       0
sigwait01                                          PASS       0
sigwaitinfo01                                      CONF       32


>
>        Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From axe.yang at mediatek.com  Thu Jan 20 23:19:41 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 21 Jan 2022 15:19:41 +0800
Subject: [PATCH v5 2/3] mmc: core: Add support for SDIO async interrupt
In-Reply-To: <20220121071942.11601-1-axe.yang@mediatek.com>
References: <20220121071942.11601-1-axe.yang@mediatek.com>
Message-ID: <20220121071942.11601-3-axe.yang@mediatek.com>

If cap-sdio-async-irq flag is set in host dts node, parse EAI
information from SDIO CCCR interrupt externsion segment. If async
interrupt is supported by SDIO card then send command to card to
enable it and set enable_async_irq flag in sdio_cccr structure to 1.
The parse flow is implemented in sdio_read_cccr().

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/sdio.c  | 17 +++++++++++++++++
 include/linux/mmc/card.h |  3 ++-
 include/linux/mmc/host.h |  1 +
 include/linux/mmc/sdio.h |  5 +++++
 5 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index cf140f4ec864..a972241548b4 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -410,6 +410,8 @@ int mmc_of_parse(struct mmc_host *host)
 	if (device_property_read_bool(dev, "no-mmc-hs400"))
 		host->caps2 &= ~(MMC_CAP2_HS400_1_8V | MMC_CAP2_HS400_1_2V |
 				 MMC_CAP2_HS400_ES);
+	if (device_property_read_bool(dev, "cap-sdio-async-irq"))
+		host->caps2 |= MMC_CAP2_SDIO_ASYNC_IRQ;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 41164748723d..771fb5d18585 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -225,6 +225,23 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
 			if (data & SDIO_DRIVE_SDTD)
 				card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+
+			if (card->host->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ) {
+				ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTERRUPT_EXT, 0,
+						       &data);
+				if (ret)
+					goto out;
+
+				if (data & SDIO_INTERRUPT_EXT_SAI) {
+					data |= SDIO_INTERRUPT_EXT_EAI;
+					ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_INTERRUPT_EXT,
+							       data, NULL);
+					if (ret)
+						goto out;
+
+					card->cccr.enable_async_irq = 1;
+				}
+			}
 		}
 
 		/* if no uhs mode ensure we check for high speed */
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 37f975875102..4df9182bc0e6 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -219,7 +219,8 @@ struct sdio_cccr {
 				wide_bus:1,
 				high_power:1,
 				high_speed:1,
-				disable_cd:1;
+				disable_cd:1,
+				enable_async_irq:1;
 };
 
 struct sdio_cis {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 7afb57cab00b..502a5418264c 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -402,6 +402,7 @@ struct mmc_host {
 #define MMC_CAP2_CRYPTO		0
 #endif
 #define MMC_CAP2_ALT_GPT_TEGRA	(1 << 28)	/* Host with eMMC that has GPT entry at a non-standard location */
+#define MMC_CAP2_SDIO_ASYNC_IRQ	(1 << 29)	/* SDIO host supports asynchronous interrupt */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index 2a05d1ac4f0e..1ef400f28642 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -159,6 +159,11 @@
 #define  SDIO_DTSx_SET_TYPE_A	(1 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_C	(2 << SDIO_DRIVE_DTSx_SHIFT)
 #define  SDIO_DTSx_SET_TYPE_D	(3 << SDIO_DRIVE_DTSx_SHIFT)
+
+#define SDIO_CCCR_INTERRUPT_EXT	0x16
+#define SDIO_INTERRUPT_EXT_SAI	(1 << 0)
+#define SDIO_INTERRUPT_EXT_EAI	(1 << 1)
+
 /*
  * Function Basic Registers (FBR)
  */
-- 
2.25.1



From axe.yang at mediatek.com  Thu Jan 20 23:19:40 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 21 Jan 2022 15:19:40 +0800
Subject: [PATCH v5 1/3] dt-bindings: mmc: add cap-sdio-async-irq flag
In-Reply-To: <20220121071942.11601-1-axe.yang@mediatek.com>
References: <20220121071942.11601-1-axe.yang@mediatek.com>
Message-ID: <20220121071942.11601-2-axe.yang@mediatek.com>

Asynchronous interrupt is a mechanism that allow SDIO devices alarm
interrupt when host stop providing clock to card. Add a DT flag to
enable this feature if it is supported by SDIO card.

Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mmc-controller.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
index 513f3c8758aa..16fb06f88471 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ b/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -165,6 +165,11 @@ properties:
     description:
       eMMC hardware reset is supported
 
+  cap-sdio-async-irq:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      SDIO async interrupt is supported.
+
   cap-sdio-irq:
     $ref: /schemas/types.yaml#/definitions/flag
     description:
-- 
2.25.1



From axe.yang at mediatek.com  Thu Jan 20 23:19:39 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 21 Jan 2022 15:19:39 +0800
Subject: [PATCH v5 0/3] mmc: mediatek: add support for SDIO async IRQ 
Message-ID: <20220121071942.11601-1-axe.yang@mediatek.com>

Change in v5:
- resort variables to reversed xmas tree order
- restore old copyright year range and add current year back

Change in v4:
- add MMC_CAP2_SDIO_ASYNC_IRQ judge before lookup eint pinctrl
- replace spin_lock_irqsave() variant with spin_lock() in eint irq handler

Changes in v3:
- correct abbreviations with capital letters in commit message
- replace copyright year with 2022 in mtk-sd.c
- remove unnessary pointer casting
- adjust variable order to reversed xmas tree
- remove a redundant blank line
- refine if statement, following standard pattern

Change in v2:
- change flag name from 'cap-sdio-async-int' to 'cap-sdio-async-irq'
- change corresponding macro names from xxx_INT to xxx_IRQ
- resort new member in msdc_host structure
- refine function msdc_request_dat1_eint_irq()
- rename msdc_{suspend,resume} function names, add suffix '_noirq'
- add MMC_CAP2_NO_SDIO judgement before parse eint related pin setting

Axe Yang (3):
  dt-bindings: mmc: add cap-sdio-async-irq flag
  mmc: core: Add support for SDIO async interrupt
  mmc: mediatek: add support for SDIO eint IRQ

 .../bindings/mmc/mmc-controller.yaml          |   5 +
 drivers/mmc/core/host.c                       |   2 +
 drivers/mmc/core/sdio.c                       |  17 +++
 drivers/mmc/host/mtk-sd.c                     | 123 ++++++++++++++++--
 include/linux/mmc/card.h                      |   3 +-
 include/linux/mmc/host.h                      |   1 +
 include/linux/mmc/sdio.h                      |   5 +
 7 files changed, 147 insertions(+), 9 deletions(-)

-- 
2.25.1




From hverkuil at xs4all.nl  Thu Jan 20 23:28:41 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 21 Jan 2022 08:28:41 +0100
Subject: [PATCH v2 3/4] media: aspeed: Correct values for detected timing
In-Reply-To: <eda33316-b0dc-3d21-e2e1-ebde776dbd85@aspeedtech.com>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-4-jammy_huang@aspeedtech.com>
 <5868782b-3383-5ee6-4111-841707ffee39@xs4all.nl>
 <eda33316-b0dc-3d21-e2e1-ebde776dbd85@aspeedtech.com>
Message-ID: <53e8cd96-2a07-3391-9a5c-6c4510874a6b@xs4all.nl>

Hi Jammy,

On 1/21/22 07:01, Jammy Huang wrote:
> Hi Hans,
> 
> Yes, this is a weird part of our hardware.
> Because it uses the rising edge of the sync to start counting, an additional calculation
> is needed to get the exact value of the timings.
> 
> This problem was found when I was debugging the timing detection unstable problem.

OK, thank you for the confirmation.

I would like a v3 where basically the explanation you made in the cover letter
is copied to the code, probably as a comment block just before aspeed_video_get_resolution().

This is unusual enough that it should be documented well in the code.

Regards,

	Hans

> 
> Reards,
> 
> Jammy
> 
> On 2022/1/20 ?? 08:31, Hans Verkuil wrote:
>> Hi Jammy,
>>
>> I just want to double check this: I assume you have tested this with the
>> various polarity combinations?
>>
>> I ask because I've never seen this before in any other hardware. The
>> sync and porch values reported by hardware are always independent from the
>> polarity, so that's why I am surprised to see this.
>>
>> Same for the next patch (4/4).
>>
>> Regards,
>>
>> ????Hans
>>
>> On 12/22/21 09:21, Jammy Huang wrote:
>>> Correct timing's fp/sync/bp value based on the information below.
>>> It should be noticed that the calculation formula should be changed
>>> per sync polarity.
>>>
>>> The sequence of signal: sync - backporch - video data - frontporch
>>>
>>> The following registers start counting from sync's rising edge:
>>> 1. VR090: frame edge's left and right
>>> 2. VR094: frame edge's top and bottom
>>> 3. VR09C: counting from sync's rising edge to falling edge
>>>
>>> [Vertical timing]
>>> ???????????? +--+???? +-------------------+???? +--+
>>> ???????????? |? |???? |??? v i d e o????? |???? |? |
>>> ????????? +--+? +-----+?????????????????? +-----+? +---+
>>>
>>> ??????? vsync+--+
>>> ??? frame_top+--------+
>>> frame_bottom+----------------------------+
>>>
>>> ?????????????????? +-------------------+
>>> ?????????????????? |??? v i d e o????? |
>>> ?????? +--+? +-----+?????????????????? +-----+? +---+
>>> ????????? |? |?????????????????????????????? |? |
>>> ????????? +--+?????????????????????????????? +--+
>>> ??????? vsync+-------------------------------+
>>> ??? frame_top+-----+
>>> frame_bottom+-------------------------+
>>>
>>> [Horizontal timing]
>>> ???????????? +--+???? +-------------------+???? +--+
>>> ???????????? |? |???? |??? v i d e o????? |???? |? |
>>> ????????? +--+? +-----+?????????????????? +-----+? +---+
>>>
>>> ??????? hsync+--+
>>> ?? frame_left+--------+
>>> ? frame_right+----------------------------+
>>>
>>> ?????????????????? +-------------------+
>>> ?????????????????? |??? v i d e o????? |
>>> ?????? +--+? +-----+?????????????????? +-----+? +---+
>>> ????????? |? |?????????????????????????????? |? |
>>> ????????? +--+?????????????????????????????? +--+
>>> ??????? hsync+-------------------------------+
>>> ?? frame_left+-----+
>>> ? frame_right+-------------------------+
>>>
>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>> ---
>>> ? v2:
>>> ?? - Code refined per Joel's suggestion
>>> ?? - Update commit message to have name matching variable
>>> ---
>>> ? drivers/media/platform/aspeed-video.c | 30 ++++++++++++++++++++-------
>>> ? 1 file changed, 22 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>>> index c241038ee27c..7c50567f5ab0 100644
>>> --- a/drivers/media/platform/aspeed-video.c
>>> +++ b/drivers/media/platform/aspeed-video.c
>>> @@ -936,7 +936,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>> ????? u32 src_lr_edge;
>>> ????? u32 src_tb_edge;
>>> ????? u32 sync;
>>> -??? u32 htotal;
>>> +??? u32 htotal, vtotal, vsync, hsync;
>>> ????? struct v4l2_bt_timings *det = &video->detected_timings;
>>> ? ????? det->width = MIN_WIDTH;
>>> @@ -983,21 +983,35 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>> ????????? mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
>>> ????????? sync = aspeed_video_read(video, VE_SYNC_STATUS);
>>> ????????? htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
>>> +??????? vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
>>> +??????? vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
>>> +??????? hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
>>> ? ????????? video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>>> ????????? video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
>>> -??????? det->vfrontporch = video->frame_top;
>>> -??????? det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
>>> -??????????? video->frame_bottom;
>>> -??????? det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
>>> +??????? if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>>> +??????????? det->vbackporch = video->frame_top - vsync;
>>> +??????????? det->vfrontporch = vtotal - video->frame_bottom;
>>> +??????????? det->vsync = vsync;
>>> +??????? } else {
>>> +??????????? det->vbackporch = video->frame_top;
>>> +??????????? det->vfrontporch = vsync - video->frame_bottom;
>>> +??????????? det->vsync = vtotal - vsync;
>>> +??????? }
>>> ????????? if (video->frame_top > video->frame_bottom)
>>> ????????????? continue;
>>> ? ????????? video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>>> ????????? video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
>>> -??????? det->hfrontporch = video->frame_left;
>>> -??????? det->hbackporch = htotal - video->frame_right;
>>> -??????? det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
>>> +??????? if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>>> +??????????? det->hbackporch = video->frame_left - hsync;
>>> +??????????? det->hfrontporch = htotal - video->frame_right;
>>> +??????????? det->hsync = hsync;
>>> +??????? } else {
>>> +??????????? det->hbackporch = video->frame_left;
>>> +??????????? det->hfrontporch = hsync - video->frame_right;
>>> +??????????? det->hsync = htotal - hsync;
>>> +??????? }
>>> ????????? if (video->frame_left > video->frame_right)
>>> ????????????? continue;
>>> ? 


From axe.yang at mediatek.com  Thu Jan 20 23:19:42 2022
From: axe.yang at mediatek.com (Axe Yang)
Date: Fri, 21 Jan 2022 15:19:42 +0800
Subject: [PATCH v5 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220121071942.11601-1-axe.yang@mediatek.com>
References: <20220121071942.11601-1-axe.yang@mediatek.com>
Message-ID: <20220121071942.11601-4-axe.yang@mediatek.com>

Add support for eint IRQ when MSDC is used as an SDIO host. This
feature requires SDIO device support async IRQ function. With this
feature, SDIO host can be awakened by SDIO card in suspend state,
without additional pin.

MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
resume, switch GPIO function back to DAT1 mode then turn on clock.

Some device tree property should be added or modified in MSDC node
to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
are mandatory. And cap-sdio-async-irq flag is necessary since this
feature depends on asynchronous interrupt:
        &mmcX {
                ...
                pinctrl-names = "default", "state_uhs", "state_eint",
                                "state_dat1";
                ...
                pinctrl-2 = <&mmc2_pins_eint>;
                pinctrl-3 = <&mmc2_pins_dat1>;
                ...
                cap-sdio-async-irq;
                ...
        };

Co-developed-by: Yong Mao <yong.mao at mediatek.com>
Signed-off-by: Yong Mao <yong.mao at mediatek.com>
Signed-off-by: Axe Yang <axe.yang at mediatek.com>
---
 drivers/mmc/host/mtk-sd.c | 123 +++++++++++++++++++++++++++++++++++---
 1 file changed, 115 insertions(+), 8 deletions(-)

diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 65037e1d7723..f8e38228d810 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014-2015 MediaTek Inc.
+ * Copyright (c) 2014-2015, 2022 MediaTek Inc.
  * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
  */
 
@@ -9,6 +9,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/gpio/consumer.h>
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
@@ -440,8 +441,12 @@ struct msdc_host {
 	struct pinctrl *pinctrl;
 	struct pinctrl_state *pins_default;
 	struct pinctrl_state *pins_uhs;
+	struct pinctrl_state *pins_eint;
+	struct pinctrl_state *pins_dat1;
 	struct delayed_work req_timeout;
 	int irq;		/* host interrupt */
+	int eint_irq;		/* device interrupt */
+	int sdio_irq_cnt;	/* irq enable cnt */
 	struct reset_control *reset;
 
 	struct clk *src_clk;	/* msdc source clock */
@@ -465,6 +470,7 @@ struct msdc_host {
 	bool hs400_tuning;	/* hs400 mode online tuning */
 	bool internal_cd;	/* Use internal card-detect logic */
 	bool cqhci;		/* support eMMC hw cmdq */
+	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
 	struct msdc_save_para save_para; /* used when gate HCLK */
 	struct msdc_tune_para def_tune_para; /* default tune setting */
 	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
@@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
 	__msdc_enable_sdio_irq(host, enb);
 	spin_unlock_irqrestore(&host->lock, flags);
 
-	if (enb)
-		pm_runtime_get_noresume(host->dev);
-	else
-		pm_runtime_put_noidle(host->dev);
+	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
+		if (enb)
+			pm_runtime_get_noresume(host->dev);
+		else
+			pm_runtime_put_noidle(host->dev);
+	}
 }
 
 static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
@@ -2461,6 +2469,48 @@ static const struct mmc_host_ops mt_msdc_ops = {
 	.hw_reset = msdc_hw_reset,
 };
 
+static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
+{
+	struct msdc_host *host = dev_id;
+	struct mmc_host *mmc = mmc_from_priv(host);
+
+	spin_lock(&host->lock);
+	if (likely(host->sdio_irq_cnt > 0)) {
+		disable_irq_nosync(host->eint_irq);
+		disable_irq_wake(host->eint_irq);
+		host->sdio_irq_cnt--;
+	}
+	spin_unlock(&host->lock);
+
+	sdio_signal_irq(mmc);
+
+	return IRQ_HANDLED;
+}
+
+static int msdc_request_dat1_eint_irq(struct msdc_host *host)
+{
+	struct gpio_desc *desc;
+	int irq, ret;
+
+	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
+	if (IS_ERR(desc))
+		return PTR_ERR(desc);
+
+	irq = gpiod_to_irq(desc);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
+					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+					"sdio-eint", host);
+	if (ret)
+		return ret;
+
+	host->eint_irq = irq;
+
+	return 0;
+}
+
 static const struct cqhci_host_ops msdc_cmdq_ops = {
 	.enable         = msdc_cqe_enable,
 	.disable        = msdc_cqe_disable,
@@ -2631,6 +2681,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
 		goto host_free;
 	}
 
+	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ)) {
+		/* Support for SDIO eint irq */
+		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
+		if (IS_ERR(host->pins_eint)) {
+			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
+		} else {
+			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
+			if (IS_ERR(host->pins_dat1)) {
+				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
+						    "Cannot find pinctrl dat1!\n");
+				goto host_free;
+			}
+
+			host->sdio_eint_ready = true;
+		}
+	}
+
 	msdc_of_property_parse(pdev, host);
 
 	host->dev = &pdev->dev;
@@ -2722,6 +2789,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
 	if (ret)
 		goto release;
 
+	if (host->sdio_eint_ready) {
+		ret = msdc_request_dat1_eint_irq(host);
+		if (ret) {
+			dev_err(host->dev, "Failed to register data1 eint irq!\n");
+			goto release;
+		}
+
+		pinctrl_select_state(host->pinctrl, host->pins_dat1);
+	}
+
 	pm_runtime_set_active(host->dev);
 	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(host->dev);
@@ -2843,8 +2920,22 @@ static int __maybe_unused msdc_runtime_suspend(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
+	unsigned long flags;
 
 	msdc_save_reg(host);
+
+	if (host->sdio_eint_ready) {
+		disable_irq(host->irq);
+		pinctrl_select_state(host->pinctrl, host->pins_eint);
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt == 0) {
+			enable_irq(host->eint_irq);
+			enable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt++;
+		}
+		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		spin_unlock_irqrestore(&host->lock, flags);
+	}
 	msdc_gate_clock(host);
 	return 0;
 }
@@ -2853,6 +2944,7 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	struct msdc_host *host = mmc_priv(mmc);
+	unsigned long flags;
 	int ret;
 
 	ret = msdc_ungate_clock(host);
@@ -2860,10 +2952,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
 		return ret;
 
 	msdc_restore_reg(host);
+
+	if (host->sdio_eint_ready) {
+		spin_lock_irqsave(&host->lock, flags);
+		if (host->sdio_irq_cnt > 0) {
+			disable_irq_nosync(host->eint_irq);
+			disable_irq_wake(host->eint_irq);
+			host->sdio_irq_cnt--;
+			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+		} else {
+			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		pinctrl_select_state(host->pinctrl, host->pins_uhs);
+		enable_irq(host->irq);
+	}
 	return 0;
 }
 
-static int __maybe_unused msdc_suspend(struct device *dev)
+static int __maybe_unused msdc_suspend_noirq(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret;
@@ -2877,13 +2984,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
 	return pm_runtime_force_suspend(dev);
 }
 
-static int __maybe_unused msdc_resume(struct device *dev)
+static int __maybe_unused msdc_resume_noirq(struct device *dev)
 {
 	return pm_runtime_force_resume(dev);
 }
 
 static const struct dev_pm_ops msdc_dev_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
 	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
 };
 
-- 
2.25.1



From hverkuil at xs4all.nl  Thu Jan 20 23:30:17 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 21 Jan 2022 08:30:17 +0100
Subject: [PATCH v2 4/4] media: aspeed: Fix timing polarity incorrect
In-Reply-To: <20211222082139.26933-5-jammy_huang@aspeedtech.com>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-5-jammy_huang@aspeedtech.com>
Message-ID: <418fc1b2-ddbe-24e3-82cc-aa8ce74f4507@xs4all.nl>

On 12/22/21 09:21, Jammy Huang wrote:
> This is a workaround for sync polarity unstable.
> Sync value get by VR09C counts from sync's rising edge, which means
> sync's polarity is negative if sync value is bigger than total/2.

Do you have an example of such a format, or is this mostly theoretical?

Either provide the example or make a note that it is theoretical.

Regards,

	Hans

> 
> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
> ---
>  v2:
>   - Use 'total/2' rather than 'total<<1'
>   - Update comment
> ---
>  drivers/media/platform/aspeed-video.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
> index 7c50567f5ab0..c3e3343d91e1 100644
> --- a/drivers/media/platform/aspeed-video.c
> +++ b/drivers/media/platform/aspeed-video.c
> @@ -989,6 +989,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>  
>  		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>  		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
> +
> +		/*
> +		 * This is a workaround for polarity detection when the sync
> +		 * value is larger than half.
> +		 */
> +		if (vsync > (vtotal / 2))
> +			det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
> +		else
> +			det->polarities |= V4L2_DV_VSYNC_POS_POL;
> +
>  		if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>  			det->vbackporch = video->frame_top - vsync;
>  			det->vfrontporch = vtotal - video->frame_bottom;
> @@ -1003,6 +1013,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>  
>  		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>  		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
> +
> +		/*
> +		 * This is a workaround for polarity detection when the sync
> +		 * value is larger than half.
> +		 */
> +		if (hsync > (htotal / 2))
> +			det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
> +		else
> +			det->polarities |= V4L2_DV_HSYNC_POS_POL;
> +
>  		if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>  			det->hbackporch = video->frame_left - hsync;
>  			det->hfrontporch = htotal - video->frame_right;


From reijiw at google.com  Thu Jan 20 23:35:35 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 20 Jan 2022 23:35:35 -0800
Subject: [PATCH v4 1/4] KVM: arm64: Introduce a new VMID allocator for KVM
In-Reply-To: <20211122121844.867-2-shameerali.kolothum.thodi@huawei.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
 <20211122121844.867-2-shameerali.kolothum.thodi@huawei.com>
Message-ID: <CAAeT=FwWNZ7O=oxGB5d0Pp2jVZVs71nCAGJTp9_+6fhuOK+dKw@mail.gmail.com>

On Mon, Nov 22, 2021 at 4:19 AM Shameer Kolothum
<shameerali.kolothum.thodi at huawei.com> wrote:
>
> A new VMID allocator for arm64 KVM use. This is based on
> arm64 ASID allocator algorithm.
>
> One major deviation from the ASID allocator is the way we
> flush the context. Unlike ASID allocator, we expect less
> frequent rollover in the case of VMIDs. Hence, instead of
> marking the CPU as flush_pending and issuing a local context
> invalidation on the next context switch, we  broadcast TLB
> flush + I-cache invalidation over the inner shareable domain
> on rollover.
>
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |   4 +
>  arch/arm64/kvm/vmid.c             | 177 ++++++++++++++++++++++++++++++
>  2 files changed, 181 insertions(+)
>  create mode 100644 arch/arm64/kvm/vmid.c
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2a5f7f38006f..f4a86a79ea4a 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -690,6 +690,10 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu *vcpu,
>  int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
>                             struct kvm_device_attr *attr);
>
> +int kvm_arm_vmid_alloc_init(void);
> +void kvm_arm_vmid_alloc_free(void);
> +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
> +
>  static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
>  {
>         vcpu_arch->steal.base = GPA_INVALID;
> diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> new file mode 100644
> index 000000000000..aa01c97f7df0
> --- /dev/null
> +++ b/arch/arm64/kvm/vmid.c
> @@ -0,0 +1,177 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * VMID allocator.
> + *
> + * Based on Arm64 ASID allocator algorithm.
> + * Please refer arch/arm64/mm/context.c for detailed
> + * comments on algorithm.
> + *
> + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
> + * Copyright (C) 2012 ARM Ltd.
> + */
> +
> +#include <linux/bitfield.h>
> +#include <linux/bitops.h>
> +
> +#include <asm/kvm_asm.h>
> +#include <asm/kvm_mmu.h>
> +
> +static unsigned int kvm_arm_vmid_bits;
> +static DEFINE_RAW_SPINLOCK(cpu_vmid_lock);
> +
> +static atomic64_t vmid_generation;
> +static unsigned long *vmid_map;
> +
> +static DEFINE_PER_CPU(atomic64_t, active_vmids);
> +static DEFINE_PER_CPU(u64, reserved_vmids);
> +
> +#define VMID_MASK              (~GENMASK(kvm_arm_vmid_bits - 1, 0))
> +#define VMID_FIRST_VERSION     (1UL << kvm_arm_vmid_bits)
> +
> +#define NUM_USER_VMIDS         VMID_FIRST_VERSION
> +#define vmid2idx(vmid)         ((vmid) & ~VMID_MASK)
> +#define idx2vmid(idx)          vmid2idx(idx)
> +
> +#define vmid_gen_match(vmid) \
> +       (!(((vmid) ^ atomic64_read(&vmid_generation)) >> kvm_arm_vmid_bits))
> +
> +static void flush_context(void)
> +{
> +       int cpu;
> +       u64 vmid;
> +
> +       bitmap_clear(vmid_map, 0, NUM_USER_VMIDS);
> +
> +       for_each_possible_cpu(cpu) {
> +               vmid = atomic64_xchg_relaxed(&per_cpu(active_vmids, cpu), 0);
> +
> +               /* Preserve reserved VMID */
> +               if (vmid == 0)
> +                       vmid = per_cpu(reserved_vmids, cpu);
> +               __set_bit(vmid2idx(vmid), vmid_map);
> +               per_cpu(reserved_vmids, cpu) = vmid;
> +       }
> +
> +       /*
> +        * Unlike ASID allocator, we expect less frequent rollover in
> +        * case of VMIDs. Hence, instead of marking the CPU as
> +        * flush_pending and issuing a local context invalidation on
> +        * the next context-switch, we broadcast TLB flush + I-cache
> +        * invalidation over the inner shareable domain on rollover.
> +        */
> +        kvm_call_hyp(__kvm_flush_vm_context);
> +}
> +
> +static bool check_update_reserved_vmid(u64 vmid, u64 newvmid)
> +{
> +       int cpu;
> +       bool hit = false;
> +
> +       /*
> +        * Iterate over the set of reserved VMIDs looking for a match
> +        * and update to use newvmid (i.e. the same VMID in the current
> +        * generation).
> +        */
> +       for_each_possible_cpu(cpu) {
> +               if (per_cpu(reserved_vmids, cpu) == vmid) {
> +                       hit = true;
> +                       per_cpu(reserved_vmids, cpu) = newvmid;
> +               }
> +       }

Once updating reserved_vmids gets done for the all CPUs, it appears
that the function doesn't need to iterate over the set of reserved
VMIDs (correct ?). So, I'm wondering if KVM can manage the number of
CPUs for which reserved_vmids need to get updated so that the function
can skip the loop when the number is zero.  I'm not sure how likely
that would help though.
(Since every vmid allocation for non-new guest needs to iterate over
 reserved_vmids holding cpu_vmid_lock, I'm a bit concerned about the
 performance impact on systems with a large number of CPUs.)

Thanks,
Reiji

> +
> +       return hit;
> +}
> +
> +static u64 new_vmid(struct kvm_vmid *kvm_vmid)
> +{
> +       static u32 cur_idx = 1;
> +       u64 vmid = atomic64_read(&kvm_vmid->id);
> +       u64 generation = atomic64_read(&vmid_generation);
> +
> +       if (vmid != 0) {
> +               u64 newvmid = generation | (vmid & ~VMID_MASK);
> +
> +               if (check_update_reserved_vmid(vmid, newvmid)) {
> +                       atomic64_set(&kvm_vmid->id, newvmid);
> +                       return newvmid;
> +               }
> +
> +               if (!__test_and_set_bit(vmid2idx(vmid), vmid_map)) {
> +                       atomic64_set(&kvm_vmid->id, newvmid);
> +                       return newvmid;
> +               }
> +       }
> +
> +       vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS, cur_idx);
> +       if (vmid != NUM_USER_VMIDS)
> +               goto set_vmid;
> +
> +       /* We're out of VMIDs, so increment the global generation count */
> +       generation = atomic64_add_return_relaxed(VMID_FIRST_VERSION,
> +                                                &vmid_generation);
> +       flush_context();
> +
> +       /* We have more VMIDs than CPUs, so this will always succeed */
> +       vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS, 1);
> +
> +set_vmid:
> +       __set_bit(vmid, vmid_map);
> +       cur_idx = vmid;
> +       vmid = idx2vmid(vmid) | generation;
> +       atomic64_set(&kvm_vmid->id, vmid);
> +       return vmid;
> +}
> +
> +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
> +{
> +       unsigned long flags;
> +       u64 vmid, old_active_vmid;
> +
> +       vmid = atomic64_read(&kvm_vmid->id);
> +
> +       /*
> +        * Please refer comments in check_and_switch_context() in
> +        * arch/arm64/mm/context.c.
> +        */
> +       old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
> +       if (old_active_vmid && vmid_gen_match(vmid) &&
> +           atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
> +                                    old_active_vmid, vmid))
> +               return;
> +
> +       raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
> +
> +       /* Check that our VMID belongs to the current generation. */
> +       vmid = atomic64_read(&kvm_vmid->id);
> +       if (!vmid_gen_match(vmid))
> +               vmid = new_vmid(kvm_vmid);
> +
> +       atomic64_set(this_cpu_ptr(&active_vmids), vmid);
> +       raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
> +}
> +
> +/*
> + * Initialize the VMID allocator
> + */
> +int kvm_arm_vmid_alloc_init(void)
> +{
> +       kvm_arm_vmid_bits = kvm_get_vmid_bits();
> +
> +       /*
> +        * Expect allocation after rollover to fail if we don't have
> +        * at least one more VMID than CPUs. VMID #0 is always reserved.
> +        */
> +       WARN_ON(NUM_USER_VMIDS - 1 <= num_possible_cpus());
> +       atomic64_set(&vmid_generation, VMID_FIRST_VERSION);
> +       vmid_map = kcalloc(BITS_TO_LONGS(NUM_USER_VMIDS),
> +                          sizeof(*vmid_map), GFP_KERNEL);
> +       if (!vmid_map)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +void kvm_arm_vmid_alloc_free(void)
> +{
> +       kfree(vmid_map);
> +}
> --
> 2.17.1
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From liang.yang at amlogic.com  Thu Jan 20 23:45:04 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:04 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller support
Message-ID: <20220121074508.42168-1-liang.yang@amlogic.com>

This driver will add a MMC clock controller driver support.
The original idea about adding a clock controller is during the
discussion in the NAND driver mainline effort[1].

This driver is tested in the S400 board (AXG platform) with NAND driver.

Changes since v9 [10]
 - use clk_parent_data instead of parent_names

Changes since v8 [9]
 - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
 - use struct_size to caculate onecell_data
 - add clk-phase-delay.h
 - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG

Changes since v7 [8]
 - move meson_clk_get_phase_delay_data() from header to driver
 - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
 - remove onecell date and ID for internal MUX clk
 - use helper for functions for ONE_BASED in sclk-div
 - add ONE_BASED support for duty cycle

Changes since v6 [7]:
 - add one based support for sclk divier
 - alloc sclk in probe for multiple instance
 - fix coding styles

Changes since v5 [6]:
 - remove divider ops with .init and use sclk_div instead
 - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
 - drop the useless type cast 

Changes since v4 [5]:
 - use struct parm in phase delay driver
 - remove 0 delay releted part in phase delay driver
 - don't rebuild the parent name once again
 - add divider ops with .init

Changes since v3 [4]:
 - separate clk-phase-delay driver
 - replace clk_get_rate() with clk_hw_get_rate()
 - collect Rob's R-Y
 - drop 'meson-' prefix from compatible string

 Changes since v2 [3]:
 - squash dt-binding clock-id patch
 - update license
 - fix alignment
 - construct a clk register helper() function

Changes since v1 [2]:
 - implement phase clock
 - update compatible name
 - adjust file name
 - divider probe() into small functions, and re-use them

[1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
[2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
[3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
[4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
[5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
[6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
[7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
[8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
[9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
[10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
Liang Yang (4):
  clk: meson: add one based divider support for sclk
  clk: meson: add emmc sub clock phase delay driver
  clk: meson: add DT documentation for emmc clock controller
  clk: meson: add sub MMC clock controller driver

 .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
 drivers/clk/meson/Kconfig                     |  18 ++
 drivers/clk/meson/Makefile                    |   2 +
 drivers/clk/meson/clk-phase-delay.c           |  69 ++++
 drivers/clk/meson/clk-phase-delay.h           |  20 ++
 drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
 drivers/clk/meson/sclk-div.c                  |  59 ++--
 drivers/clk/meson/sclk-div.h                  |   3 +
 include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
 9 files changed, 529 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h
 create mode 100644 drivers/clk/meson/mmc-clkc.c
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:05 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:05 +0800
Subject: [PATCH v10 1/4] clk: meson: add one based divider support for sclk
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-2-liang.yang@amlogic.com>

When MESON_SCLK_ONE_BASED flag is set, the sclk divider will be:
one based divider (div = val), and zero value gates the clock

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/sclk-div.c | 59 ++++++++++++++++++++++--------------
 drivers/clk/meson/sclk-div.h |  3 ++
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/clk/meson/sclk-div.c b/drivers/clk/meson/sclk-div.c
index 76d31c0a3342..4ddc1763a12d 100644
--- a/drivers/clk/meson/sclk-div.c
+++ b/drivers/clk/meson/sclk-div.c
@@ -4,16 +4,17 @@
  * Author: Jerome Brunet <jbrunet at baylibre.com>
  *
  * Sample clock generator divider:
- * This HW divider gates with value 0 but is otherwise a zero based divider:
+ * This HW divider gates with value 0:
  *
  * val >= 1
- * divider = val + 1
+ * divider = val + 1 if ONE_BASED is not set, otherwise divider = val.
  *
  * The duty cycle may also be set for the LR clock variant. The duty cycle
  * ratio is:
  *
  * hi = [0 - val]
- * duty_cycle = (1 + hi) / (1 + val)
+ * duty_cycle = (1 + hi) / (1 + val) if ONE_BASED is not set, otherwise:
+ * duty_cycle = hi / (1 + val)
  */
 
 #include <linux/clk-provider.h>
@@ -28,22 +29,37 @@ meson_sclk_div_data(struct clk_regmap *clk)
 	return (struct meson_sclk_div_data *)clk->data;
 }
 
-static int sclk_div_maxval(struct meson_sclk_div_data *sclk)
+static inline int sclk_get_reg(int val, unsigned char flag)
 {
-	return (1 << sclk->div.width) - 1;
+	if ((flag & MESON_SCLK_ONE_BASED) || !val)
+		return val;
+	return val - 1;
+}
+
+static inline int sclk_get_divider(int reg, unsigned char flag)
+{
+	if (flag & MESON_SCLK_ONE_BASED)
+		return reg;
+	return reg + 1;
 }
 
 static int sclk_div_maxdiv(struct meson_sclk_div_data *sclk)
 {
-	return sclk_div_maxval(sclk) + 1;
+	unsigned int reg = (1 << sclk->div.width) - 1;
+
+	return sclk_get_divider(reg, sclk->flags);
 }
 
 static int sclk_div_getdiv(struct clk_hw *hw, unsigned long rate,
-			   unsigned long prate, int maxdiv)
+			   unsigned long prate)
 {
 	int div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
+	int mindiv = sclk_get_divider(1, sclk->flags);
+	int maxdiv = sclk_div_maxdiv(sclk);
 
-	return clamp(div, 2, maxdiv);
+	return clamp(div, mindiv, maxdiv);
 }
 
 static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
@@ -51,25 +67,25 @@ static int sclk_div_bestdiv(struct clk_hw *hw, unsigned long rate,
 			    struct meson_sclk_div_data *sclk)
 {
 	struct clk_hw *parent = clk_hw_get_parent(hw);
-	int bestdiv = 0, i;
+	int bestdiv = 0, i, mindiv;
 	unsigned long maxdiv, now, parent_now;
 	unsigned long best = 0, best_parent = 0;
 
 	if (!rate)
 		rate = 1;
 
-	maxdiv = sclk_div_maxdiv(sclk);
-
 	if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT))
-		return sclk_div_getdiv(hw, rate, *prate, maxdiv);
+		return sclk_div_getdiv(hw, rate, *prate);
 
 	/*
 	 * The maximum divider we can use without overflowing
 	 * unsigned long in rate * i below
 	 */
+	maxdiv = sclk_div_maxdiv(sclk);
 	maxdiv = min(ULONG_MAX / rate, maxdiv);
+	mindiv = sclk_get_divider(1, sclk->flags);
 
-	for (i = 2; i <= maxdiv; i++) {
+	for (i = mindiv; i <= maxdiv; i++) {
 		/*
 		 * It's the most ideal case if the requested rate can be
 		 * divided from parent clock without needing to change
@@ -115,10 +131,7 @@ static void sclk_apply_ratio(struct clk_regmap *clk,
 					    sclk->cached_duty.num,
 					    sclk->cached_duty.den);
 
-	if (hi)
-		hi -= 1;
-
-	meson_parm_write(clk->map, &sclk->hi, hi);
+	meson_parm_write(clk->map, &sclk->hi, sclk_get_reg(hi, sclk->flags));
 }
 
 static int sclk_div_set_duty_cycle(struct clk_hw *hw,
@@ -149,7 +162,7 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 	}
 
 	hi = meson_parm_read(clk->map, &sclk->hi);
-	duty->num = hi + 1;
+	duty->num = sclk_get_divider(hi, sclk->flags);
 	duty->den = sclk->cached_div;
 	return 0;
 }
@@ -157,10 +170,13 @@ static int sclk_div_get_duty_cycle(struct clk_hw *hw,
 static void sclk_apply_divider(struct clk_regmap *clk,
 			       struct meson_sclk_div_data *sclk)
 {
+	unsigned int div;
+
 	if (MESON_PARM_APPLICABLE(&sclk->hi))
 		sclk_apply_ratio(clk, sclk);
 
-	meson_parm_write(clk->map, &sclk->div, sclk->cached_div - 1);
+	div = sclk_get_reg(sclk->cached_div, sclk->flags);
+	meson_parm_write(clk->map, &sclk->div, div);
 }
 
 static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -168,9 +184,8 @@ static int sclk_div_set_rate(struct clk_hw *hw, unsigned long rate,
 {
 	struct clk_regmap *clk = to_clk_regmap(hw);
 	struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
-	unsigned long maxdiv = sclk_div_maxdiv(sclk);
 
-	sclk->cached_div = sclk_div_getdiv(hw, rate, prate, maxdiv);
+	sclk->cached_div = sclk_div_getdiv(hw, rate, prate);
 
 	if (clk_hw_is_enabled(hw))
 		sclk_apply_divider(clk, sclk);
@@ -228,7 +243,7 @@ static int sclk_div_init(struct clk_hw *hw)
 	if (!val)
 		sclk->cached_div = sclk_div_maxdiv(sclk);
 	else
-		sclk->cached_div = val + 1;
+		sclk->cached_div = sclk_get_divider(val, sclk->flags);
 
 	sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
 
diff --git a/drivers/clk/meson/sclk-div.h b/drivers/clk/meson/sclk-div.h
index b64b2a32005f..944dab5ec0cf 100644
--- a/drivers/clk/meson/sclk-div.h
+++ b/drivers/clk/meson/sclk-div.h
@@ -10,11 +10,14 @@
 #include <linux/clk-provider.h>
 #include "parm.h"
 
+#define MESON_SCLK_ONE_BASED	BIT(0)
+
 struct meson_sclk_div_data {
 	struct parm div;
 	struct parm hi;
 	unsigned int cached_div;
 	struct clk_duty cached_duty;
+	u8 flags;
 };
 
 extern const struct clk_ops meson_sclk_div_ops;
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:06 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:06 +0800
Subject: [PATCH v10 2/4] clk: meson: add emmc sub clock phase delay driver
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-3-liang.yang@amlogic.com>

Export the emmc sub clock phase delay ops which will be used
by the emmc sub clock driver itself.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig           |  4 ++
 drivers/clk/meson/Makefile          |  1 +
 drivers/clk/meson/clk-phase-delay.c | 69 +++++++++++++++++++++++++++++
 drivers/clk/meson/clk-phase-delay.h | 20 +++++++++
 4 files changed, 94 insertions(+)
 create mode 100644 drivers/clk/meson/clk-phase-delay.c
 create mode 100644 drivers/clk/meson/clk-phase-delay.h

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 3014e2f1fbb4..bb0f59eea366 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -18,6 +18,10 @@ config COMMON_CLK_MESON_PHASE
 	tristate
 	select COMMON_CLK_MESON_REGMAP
 
+config COMMON_CLK_MESON_PHASE_DELAY
+	tristate
+	select COMMON_CLK_MESON_REGMAP
+
 config COMMON_CLK_MESON_PLL
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index b3ef5f67820f..99fe4eeed000 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
 obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
 obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
 obj-$(CONFIG_COMMON_CLK_MESON_REGMAP) += clk-regmap.o
+obj-$(CONFIG_COMMON_CLK_MESON_PHASE_DELAY) += clk-phase-delay.o
 obj-$(CONFIG_COMMON_CLK_MESON_SCLK_DIV) += sclk-div.o
 obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
diff --git a/drivers/clk/meson/clk-phase-delay.c b/drivers/clk/meson/clk-phase-delay.c
new file mode 100644
index 000000000000..3c1ae0ee2a24
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-phase-delay.h"
+
+static inline struct meson_clk_phase_delay_data *
+meson_clk_get_phase_delay_data(struct clk_regmap *clk)
+{
+	return clk->data;
+}
+
+static int meson_clk_phase_delay_get_phase(struct clk_hw *hw)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, p, d;
+	int degrees;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	p = meson_parm_read(clk->map, &ph->phase);
+	degrees = p * 360 / (1 << (ph->phase.width));
+
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	d = meson_parm_read(clk->map, &ph->delay);
+	degrees += d * ph->delay_step_ps * 360 / period_ps;
+	degrees %= 360;
+
+	return degrees;
+}
+
+static int meson_clk_phase_delay_set_phase(struct clk_hw *hw, int degrees)
+{
+	struct clk_regmap *clk = to_clk_regmap(hw);
+	struct meson_clk_phase_delay_data *ph;
+	unsigned long period_ps, d = 0;
+	unsigned int p;
+
+	ph = meson_clk_get_phase_delay_data(clk);
+	period_ps = DIV_ROUND_UP_ULL(NSEC_PER_SEC * 1000ull,
+				     clk_hw_get_rate(hw));
+
+	/*
+	 * First compute the phase index (p), the remainder (r) is the
+	 * part we'll try to acheive using the delays (d).
+	 */
+	p = 360 / 1 << (ph->phase.width);
+	degrees = degrees / p;
+	d = DIV_ROUND_CLOSEST((degrees % p) * period_ps,
+			      360 * ph->delay_step_ps);
+	d = min(d, PMASK(ph->delay.width));
+
+	meson_parm_write(clk->map, &ph->phase, degrees);
+	meson_parm_write(clk->map, &ph->delay, d);
+	return 0;
+}
+
+const struct clk_ops meson_clk_phase_delay_ops = {
+	.get_phase = meson_clk_phase_delay_get_phase,
+	.set_phase = meson_clk_phase_delay_set_phase,
+};
+EXPORT_SYMBOL_GPL(meson_clk_phase_delay_ops);
diff --git a/drivers/clk/meson/clk-phase-delay.h b/drivers/clk/meson/clk-phase-delay.h
new file mode 100644
index 000000000000..b4f211d02c84
--- /dev/null
+++ b/drivers/clk/meson/clk-phase-delay.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MESON_CLK_PHASE_DELAY_H
+#define __MESON_CLK_PHASE_DELAY_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_phase_delay_data {
+	struct parm     phase;
+	struct parm     delay;
+	unsigned int    delay_step_ps;
+};
+
+extern const struct clk_ops meson_clk_phase_delay_ops;
+
+#endif /* __MESON_CLK_PHASE_DELAY_H */
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:07 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:07 +0800
Subject: [PATCH v10 3/4] clk: meson: add DT documentation for emmc clock
 controller
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-4-liang.yang@amlogic.com>

Document the MMC sub clock controller driver, the potential consumer
of this driver is MMC or NAND. Also add four clock bindings IDs which
provided by this driver.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/clock/amlogic,mmc-clkc.yaml      | 64 +++++++++++++++++++
 include/dt-bindings/clock/amlogic,mmc-clkc.h  | 14 ++++
 2 files changed, 78 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
 create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h

diff --git a/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
new file mode 100644
index 000000000000..0fe2e33c2082
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic MMC Sub Clock Controller Driver Device Tree Bindings
+
+maintainers:
+  - jianxin.pan at amlogic.com
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,axg-mmc-clkc", "syscon"
+      - "amlogic,gx-mmc-clkc", "syscon"
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "clkin0", "clkin1"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    sd_mmc_c_clkc: clock-controller at 7000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x7000 0x0 0x4>;
+	#clock-cells = <1>;
+
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_C_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+     };
+
+  - |
+    sd_emmc_b_clkc: clock-controller at 5000 {
+	compatible = "amlogic,axg-mmc-clkc", "syscon";
+	reg = <0x0 0x5000 0x0 0x4>;
+
+	#clock-cells = <1>;
+	clock-names = "clkin0", "clkin1";
+	clocks = <&clkc CLKID_SD_EMMC_B_CLK0>,
+		 <&clkc CLKID_FCLK_DIV2>;
+    };
+
+...
\ No newline at end of file
diff --git a/include/dt-bindings/clock/amlogic,mmc-clkc.h b/include/dt-bindings/clock/amlogic,mmc-clkc.h
new file mode 100644
index 000000000000..71301517b183
--- /dev/null
+++ b/include/dt-bindings/clock/amlogic,mmc-clkc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __MMC_CLKC_H
+#define __MMC_CLKC_H
+
+#define CLKID_MMC_DIV		0
+#define CLKID_MMC_PHASE_CORE	1
+#define CLKID_MMC_PHASE_TX	2
+#define CLKID_MMC_PHASE_RX	3
+
+#endif
-- 
2.34.1



From liang.yang at amlogic.com  Thu Jan 20 23:45:08 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 21 Jan 2022 15:45:08 +0800
Subject: [PATCH v10 4/4] clk: meson: add sub MMC clock controller driver
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <20220121074508.42168-5-liang.yang@amlogic.com>

The patch will add a MMC clock controller driver which used by MMC or NAND,
It provide a mux and divider clock, and three phase clocks - core, tx, tx.

Two clocks are provided as the parent of MMC clock controller from
upper layer clock controller - eg "amlogic,axg-clkc" in AXG platform.

To specify which clock the MMC or NAND driver may consume,
the preprocessor macros in the dt-bindings/clock/amlogic,mmc-clkc.h header
can be used in the device tree sources.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/clk/meson/Kconfig    |  14 ++
 drivers/clk/meson/Makefile   |   1 +
 drivers/clk/meson/mmc-clkc.c | 302 +++++++++++++++++++++++++++++++++++
 3 files changed, 317 insertions(+)
 create mode 100644 drivers/clk/meson/mmc-clkc.c

diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index bb0f59eea366..5f344a0892cb 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -39,6 +39,20 @@ config COMMON_CLK_MESON_AO_CLKC
 	select COMMON_CLK_MESON_REGMAP
 	select RESET_CONTROLLER
 
+config COMMON_CLK_MMC_MESON
+	tristate "Meson MMC Sub Clock Controller Driver"
+	depends on ARCH_MESON || COMPILE_TEST
+	select MFD_SYSCON
+	select COMMON_CLK_AMLOGIC
+	select COMMON_CLK_MESON_PHASE
+	select COMMON_CLK_MESON_PHASE_DELAY
+	select COMMON_CLK_MESON_SCLK_DIV
+	help
+	  Support for the MMC sub clock controller on
+	  Amlogic Meson Platform, which includes S905 (GXBB, GXL),
+	  A113D/X (AXG) devices. Say Y if you want this
+	  clock enabled.
+
 config COMMON_CLK_MESON_EE_CLKC
 	tristate
 	select COMMON_CLK_MESON_REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index 99fe4eeed000..7a7ffb37a726 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_COMMON_CLK_MESON_VID_PLL_DIV) += vid-pll-div.o
 
 obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
+obj-$(CONFIG_COMMON_CLK_MMC_MESON) += mmc-clkc.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
 obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
diff --git a/drivers/clk/meson/mmc-clkc.c b/drivers/clk/meson/mmc-clkc.c
new file mode 100644
index 000000000000..e42c4015c7a3
--- /dev/null
+++ b/drivers/clk/meson/mmc-clkc.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/mfd/syscon.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/amlogic,mmc-clkc.h>
+
+#include "sclk-div.h"
+#include "clk-phase-delay.h"
+#include "clk-regmap.h"
+#include "clk-phase.h"
+
+/* clock ID used by internal driver */
+
+#define SD_EMMC_CLOCK		0
+#define CLK_DELAY_STEP_PS_GX	200
+#define CLK_DELAY_STEP_PS_AXG	78
+#define MUX_CLK_NUM_PARENTS	2
+#define MMC_MAX_CLKS		4
+
+static struct clk_parent_data mmc_clkc_parent_data[MUX_CLK_NUM_PARENTS];
+
+struct mmc_clkc_data {
+	struct meson_clk_phase_delay_data tx;
+	struct meson_clk_phase_delay_data rx;
+};
+
+static struct clk_regmap_mux_data mmc_clkc_mux_data = {
+	.offset = SD_EMMC_CLOCK,
+	.mask   = 0x3,
+	.shift  = 6,
+};
+
+static const struct meson_sclk_div_data mmc_clkc_div_data = {
+	.div = {
+		.reg_off = SD_EMMC_CLOCK,
+		.width   = 6,
+	},
+	.flags = MESON_SCLK_ONE_BASED,
+};
+
+static struct meson_clk_phase_data mmc_clkc_core_phase = {
+	.ph = {
+		.reg_off = SD_EMMC_CLOCK,
+		.shift   = 8,
+		.width   = 2,
+	}
+};
+
+static const struct mmc_clkc_data mmc_clkc_gx_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 4,
+		},
+		.delay_step_ps = CLK_DELAY_STEP_PS_GX,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 20,
+			.width   = 4,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_GX,
+	},
+};
+
+static const struct mmc_clkc_data mmc_clkc_axg_data = {
+	.tx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 10,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 16,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+	.rx = {
+		.phase = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 12,
+			.width   = 2,
+		},
+		.delay = {
+			.reg_off = SD_EMMC_CLOCK,
+			.shift   = 22,
+			.width   = 6,
+		},
+		.delay_step_ps   = CLK_DELAY_STEP_PS_AXG,
+	},
+};
+
+static const struct of_device_id mmc_clkc_match_table[] = {
+	{
+		.compatible	= "amlogic,gx-mmc-clkc",
+		.data		= &mmc_clkc_gx_data
+	},
+	{
+		.compatible	= "amlogic,axg-mmc-clkc",
+		.data		= &mmc_clkc_axg_data
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mmc_clkc_match_table);
+
+static struct clk_regmap *
+mmc_clkc_register_clk(struct device *dev, struct regmap *map,
+		      struct clk_init_data *init,
+		      const char *suffix, void *data)
+{
+	struct clk_regmap *clk;
+	char *name;
+	int ret;
+
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+	if (!clk)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s#%s", dev_name(dev), suffix);
+	if (!name)
+		return ERR_PTR(-ENOMEM);
+
+	init->name = name;
+	clk->map = map;
+	clk->data = data;
+	clk->hw.init = init;
+	ret = devm_clk_hw_register(dev, &clk->hw);
+	if (ret)
+		clk = ERR_PTR(ret);
+
+	kfree(name);
+	return clk;
+}
+
+static struct clk_regmap *mmc_clkc_register_mux(struct device *dev,
+						struct regmap *map)
+{
+	struct clk_init_data init = {0};
+	struct clk_regmap *mux;
+	struct clk *clk;
+	int i;
+
+	for (i = 0; i < MUX_CLK_NUM_PARENTS; i++) {
+		char name[8];
+
+		snprintf(name, sizeof(name), "clkin%d", i);
+		clk = devm_clk_get(dev, name);
+		if (IS_ERR(clk)) {
+			if (clk != ERR_PTR(-EPROBE_DEFER))
+				dev_err_probe(dev, PTR_ERR(clk),
+					      "Missing clock\n");
+			return ERR_CAST(clk);
+		}
+
+		mmc_clkc_parent_data[i].fw_name = __clk_get_name(clk);
+	}
+
+	init.ops = &clk_regmap_mux_ops;
+	init.flags = CLK_SET_RATE_PARENT;
+	init.parent_data = mmc_clkc_parent_data;
+	init.num_parents = MUX_CLK_NUM_PARENTS;
+
+	mux = mmc_clkc_register_clk(dev, map, &init, "mux", &mmc_clkc_mux_data);
+	if (IS_ERR(mux))
+		dev_err(dev, "Mux clock registration failed\n");
+
+	return mux;
+}
+
+static struct clk_regmap *
+mmc_clkc_register_clk_with_parent(struct device *dev, struct regmap *map,
+				  char *suffix, const struct clk_hw *hw,
+				  unsigned long flags,
+				  const struct clk_ops *ops, void *data)
+{
+	struct clk_init_data init;
+	struct clk_regmap *clk;
+	const char *parent_name = clk_hw_get_name(hw);
+
+	init.ops = ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	clk = mmc_clkc_register_clk(dev, map, &init, suffix, data);
+	if (IS_ERR(clk))
+		dev_err(dev, "%s clock registration failed\n", suffix);
+
+	return clk;
+}
+
+static int mmc_clkc_probe(struct platform_device *pdev)
+{
+	struct clk_hw_onecell_data *onecell_data;
+	struct device *dev = &pdev->dev;
+	const struct mmc_clkc_data *data;
+	struct regmap *map;
+	struct clk_regmap *clk, *core;
+	struct meson_sclk_div_data *div_data, *tx, *rx;
+
+	data = of_device_get_match_data(dev);
+	if (!data)
+		return -ENODEV;
+
+	/* cast to drop the const */
+	tx = (struct meson_sclk_div_data *)&data->tx;
+	rx = (struct meson_sclk_div_data *)&data->rx;
+
+	map = syscon_node_to_regmap(dev->of_node);
+	if (IS_ERR(map)) {
+		dev_err(dev, "could not find mmc clock controller\n");
+		return PTR_ERR(map);
+	}
+
+	onecell_data = devm_kzalloc(dev,
+				    struct_size(onecell_data, hws,
+						MMC_MAX_CLKS),
+				    GFP_KERNEL);
+	if (!onecell_data)
+		return -ENOMEM;
+
+	clk = mmc_clkc_register_mux(dev, map);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	div_data = devm_kzalloc(dev, sizeof(*div_data), GFP_KERNEL);
+	if (!div_data)
+		return -ENOMEM;
+
+	memcpy(div_data, &mmc_clkc_div_data, sizeof(*div_data));
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "div",
+						&clk->hw,
+						CLK_SET_RATE_PARENT,
+						&meson_sclk_div_ops,
+						div_data);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_DIV] = &clk->hw;
+	core = mmc_clkc_register_clk_with_parent(dev, map, "core",
+						 &clk->hw,
+						 CLK_SET_RATE_PARENT,
+						 &meson_clk_phase_ops,
+						 &mmc_clkc_core_phase);
+	if (IS_ERR(core))
+		return PTR_ERR(core);
+	onecell_data->hws[CLKID_MMC_PHASE_CORE] = &core->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "rx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						rx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+	onecell_data->hws[CLKID_MMC_PHASE_RX] = &clk->hw;
+	clk = mmc_clkc_register_clk_with_parent(dev, map, "tx",
+						&core->hw,  0,
+						&meson_clk_phase_delay_ops,
+						tx);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	onecell_data->hws[CLKID_MMC_PHASE_TX] = &clk->hw;
+	onecell_data->num = MMC_MAX_CLKS;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   onecell_data);
+}
+
+static struct platform_driver mmc_clkc_driver = {
+	.probe		= mmc_clkc_probe,
+	.driver		= {
+		.name	= "meson-mmc-clkc",
+		.of_match_table = of_match_ptr(mmc_clkc_match_table),
+	},
+};
+
+module_platform_driver(mmc_clkc_driver);
+
+MODULE_DESCRIPTION("Amlogic AXG MMC clock driver");
+MODULE_AUTHOR("Jianxin Pan <jianxin.pan at amlogic.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.34.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:17 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:17 +0800
Subject: [PATCH v8 09/10] ARM: sunplus: Add initial support for Sunplus SP7021
 SoC
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <109f1c3e6a19e56a3a4dcf1a2b9b060d8c88a3b3.1642751015.git.qinjian@cqplus1.com>

This patch aims to add an initial support for Sunplus SP7021 SoC.

Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 MAINTAINERS                    |  1 +
 arch/arm/Kconfig               |  2 ++
 arch/arm/Makefile              |  1 +
 arch/arm/mach-sunplus/Kconfig  | 26 ++++++++++++++++++++++++++
 arch/arm/mach-sunplus/Makefile |  9 +++++++++
 arch/arm/mach-sunplus/sp7021.c | 16 ++++++++++++++++
 6 files changed, 55 insertions(+)
 create mode 100644 arch/arm/mach-sunplus/Kconfig
 create mode 100644 arch/arm/mach-sunplus/Makefile
 create mode 100644 arch/arm/mach-sunplus/sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index febbd97bf..0ae537a41 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,7 @@ F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F:	arch/arm/mach-sunplus/
 F:	drivers/clk/clk-sp7021.c
 F:	drivers/irqchip/irq-sp7021-intc.c
 F:	drivers/reset/reset-sunplus.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 59baf6c13..8c7883b5a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -689,6 +689,8 @@ source "arch/arm/mach-sti/Kconfig"
 
 source "arch/arm/mach-stm32/Kconfig"
 
+source "arch/arm/mach-sunplus/Kconfig"
+
 source "arch/arm/mach-sunxi/Kconfig"
 
 source "arch/arm/mach-tegra/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 847c31e7c..973ffb830 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -212,6 +212,7 @@ machine-$(CONFIG_ARCH_RENESAS)	 	+= shmobile
 machine-$(CONFIG_ARCH_INTEL_SOCFPGA)	+= socfpga
 machine-$(CONFIG_ARCH_STI)		+= sti
 machine-$(CONFIG_ARCH_STM32)		+= stm32
+machine-$(CONFIG_ARCH_SUNPLUS)		+= sunplus
 machine-$(CONFIG_ARCH_SUNXI)		+= sunxi
 machine-$(CONFIG_ARCH_TEGRA)		+= tegra
 machine-$(CONFIG_ARCH_U8500)		+= ux500
diff --git a/arch/arm/mach-sunplus/Kconfig b/arch/arm/mach-sunplus/Kconfig
new file mode 100644
index 000000000..e720606dd
--- /dev/null
+++ b/arch/arm/mach-sunplus/Kconfig
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+menuconfig ARCH_SUNPLUS
+	bool "Sunplus SoCs"
+	depends on ARCH_MULTI_V7
+	help
+	  Support for Sunplus SoC family: SP7021 and succeeding SoC-based systems,
+	  such as the Banana Pi BPI-F2S development board (and derivatives).
+	  (<http://www.sinovoip.com.cn/ecp_view.asp?id=586>)
+	  (<https://tibbo.com/store/plus1.html>)
+
+config SOC_SP7021
+	bool "Sunplus SP7021 SoC support"
+	depends on ARCH_SUNPLUS
+	default ARCH_SUNPLUS
+	select ARM_GIC
+	select ARM_PSCI
+	select PINCTRL
+	select PINCTRL_SPPCTL
+	select SERIAL_SUNPLUS
+	select SERIAL_SUNPLUS_CONSOLE
+	help
+	  Support for Sunplus SP7021 SoC. It is based on ARM 4-core
+	  Cortex-A7 with various peripherals (ex: I2C, SPI, SDIO,
+	  Ethernet and etc.), FPGA interface,  chip-to-chip bus.
+	  It is designed for industrial control.
diff --git a/arch/arm/mach-sunplus/Makefile b/arch/arm/mach-sunplus/Makefile
new file mode 100644
index 000000000..c902580a7
--- /dev/null
+++ b/arch/arm/mach-sunplus/Makefile
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-$(CONFIG_SOC_SP7021)	+= sp7021.o
+
diff --git a/arch/arm/mach-sunplus/sp7021.c b/arch/arm/mach-sunplus/sp7021.c
new file mode 100644
index 000000000..774d0a5bd
--- /dev/null
+++ b/arch/arm/mach-sunplus/sp7021.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+#include <linux/kernel.h>
+#include <asm/mach/arch.h>
+
+static const char *sp7021_compat[] __initconst = {
+	"sunplus,sp7021",
+	NULL
+};
+
+DT_MACHINE_START(SP7021_DT, "SP7021")
+	.dt_compat	= sp7021_compat,
+MACHINE_END
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:08 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:08 +0800
Subject: [PATCH v8 00/10] Add Sunplus SP7021 SoC Support
Message-ID: <cover.1642751015.git.qinjian@cqplus1.com>

This patch series add Sunplus SP7021 SoC support.

Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates many
peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and etc.) into a
single chip. It is designed for industrial control.

SP7021 consists of two chips (dies) in a package. One is called C-chip
(computing chip). It is a 4-core ARM Cortex A7 CPU. It adopts high-level
process (22 nm) for high performance computing. The other is called P-
chip (peripheral chip). It has many peripherals and an ARM A926 added
especially for real-time control. P-chip is made for customers. It adopts
low-level process (ex: 0.11 um) to reduce cost.

Refer to (for documentations):
https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview

Refer to (applications):
https://tibbo.com/store/plus1.html

Refer to (applications):
http://www.sinovoip.com.cn/ecp_view.asp?id=586

Changes in v8:
- clk-sp7021.c: fix the comments form Stephen Boyd

Changes in v7:
- sunplus,sp7021-clkc.yaml: Add clocks & clock-names
- clk-sp7021.c: fix the comments form Stephen Boyd
- irq-sp7021-intc.c: fix the comments from Marc

Changes in v6:
- reset-sunplus.c: fix the comments from Philipp
- irq-sp7021-intc.c: fix the comments from Marc
- mach-sunplus: fix the comments from Arnd

Changes in v5:
- reset-sunplus.c: fix strict checks
- clk/Kconfig: fix spell
- clk-sp7021.c: using bitfield ops, fix strict checks
- irqchip/Kconfig: fix spell
- irq-sp7021-intc.c: cleanup error path in probe, fix strict checks
- arm/Kconfig: fix spell & typo, remove CONFIG_SERIAL_SUNPLUS
- mach-sunplus/Kconfig: fix typo
- sp7021_defconfig: add CONFIG_SERIAL_SUNPLUS

Changes in v4:
- mach-sunplus: add initial support for SP7021
- sp7021_defconfig: add generic SP7021 defconfig
- reset-sunplus: remove Q645 support
- reset-sunplus.c: refine code based on Philipp's review
- clk-sp7021: clock defines add prefix, more clean up

Changes in v3:
- sp7021-intc: remove primary controller mode due to P-chip running Linux
  not supported any more.
- sp7021-intc.h: removed, not set ext through the DT but sp_intc_set_ext()
- sunplus,sp7021-intc.yaml: update descriptions for above changes
- irq-sp7021-intc.c: more cleanup based on Marc's review
- all driver's Kconfig removed default, it's selected by platform config

Changes in v2:
- sunplus,sp7021-intc.yaml: add descrption for "#interrupt-cells", interrupts
- sunplus,sp7021-intc.yaml: drop "ext0-mask"/"ext1-mask" from DT
- sunplus,sp7021-intc.yaml: fix example.dt too long error
- irq-sp7021-intc.c: major rewrite
- all files with dual license

Qin Jian (10):
  dt-bindings: vendor-prefixes: Add Sunplus
  dt-bindings: arm: sunplus: Add bindings for Sunplus SP7021 SoC boards
  dt-bindings: reset: Add bindings for SP7021 reset driver
  reset: Add Sunplus SP7021 reset driver
  dt-bindings: clock: Add bindings for SP7021 clock driver
  clk: Add Sunplus SP7021 clock driver
  dt-bindings: interrupt-controller: Add bindings for SP7021 interrupt
    controller
  irqchip: Add Sunplus SP7021 interrupt controller driver
  ARM: sunplus: Add initial support for Sunplus SP7021 SoC
  ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig

 .../bindings/arm/sunplus,sp7021.yaml          |  27 +
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  52 ++
 .../sunplus,sp7021-intc.yaml                  |  62 ++
 .../bindings/reset/sunplus,reset.yaml         |  38 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |  17 +
 arch/arm/Kconfig                              |   2 +
 arch/arm/Makefile                             |   1 +
 arch/arm/configs/multi_v7_defconfig           |   1 +
 arch/arm/configs/sp7021_defconfig             |  61 ++
 arch/arm/mach-sunplus/Kconfig                 |  26 +
 arch/arm/mach-sunplus/Makefile                |   9 +
 arch/arm/mach-sunplus/sp7021.c                |  16 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-sp7021.c                      | 753 ++++++++++++++++++
 drivers/irqchip/Kconfig                       |   9 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-sp7021-intc.c             | 288 +++++++
 drivers/reset/Kconfig                         |   9 +
 drivers/reset/Makefile                        |   1 +
 drivers/reset/reset-sunplus.c                 | 130 +++
 include/dt-bindings/clock/sp-sp7021.h         | 112 +++
 include/dt-bindings/reset/sp-sp7021.h         |  97 +++
 24 files changed, 1724 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 create mode 100644 arch/arm/configs/sp7021_defconfig
 create mode 100644 arch/arm/mach-sunplus/Kconfig
 create mode 100644 arch/arm/mach-sunplus/Makefile
 create mode 100644 arch/arm/mach-sunplus/sp7021.c
 create mode 100644 drivers/clk/clk-sp7021.c
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c
 create mode 100644 drivers/reset/reset-sunplus.c
 create mode 100644 include/dt-bindings/clock/sp-sp7021.h
 create mode 100644 include/dt-bindings/reset/sp-sp7021.h

-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:18 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:18 +0800
Subject: [PATCH v8 10/10] ARM: sp7021_defconfig: Add Sunplus SP7021 defconfig
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <5fd536a7ff7a331dffd64ef0780c41ec721a01e8.1642751015.git.qinjian@cqplus1.com>

Add generic Sunplus SP7021 based board defconfig

Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 MAINTAINERS                         |  1 +
 arch/arm/configs/multi_v7_defconfig |  1 +
 arch/arm/configs/sp7021_defconfig   | 61 +++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 arch/arm/configs/sp7021_defconfig

diff --git a/MAINTAINERS b/MAINTAINERS
index 0ae537a41..9340f8760 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2664,6 +2664,7 @@ F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F:	arch/arm/configs/sp7021_*defconfig
 F:	arch/arm/mach-sunplus/
 F:	drivers/clk/clk-sp7021.c
 F:	drivers/irqchip/irq-sp7021-intc.c
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index b4f74454f..585e3b5d3 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -87,6 +87,7 @@ CONFIG_MACH_SPEAR1310=y
 CONFIG_MACH_SPEAR1340=y
 CONFIG_ARCH_STI=y
 CONFIG_ARCH_STM32=y
+CONFIG_ARCH_SUNPLUS=y
 CONFIG_ARCH_SUNXI=y
 CONFIG_ARCH_TEGRA=y
 CONFIG_ARCH_UNIPHIER=y
diff --git a/arch/arm/configs/sp7021_defconfig b/arch/arm/configs/sp7021_defconfig
new file mode 100644
index 000000000..cda16d33a
--- /dev/null
+++ b/arch/arm/configs/sp7021_defconfig
@@ -0,0 +1,61 @@
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PERF_EVENTS=y
+CONFIG_SLAB=y
+CONFIG_ARCH_SUNPLUS=y
+# CONFIG_VDSO is not set
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_ARCH_TIMER=y
+CONFIG_THUMB2_KERNEL=y
+CONFIG_FORCE_MAX_ZONEORDER=12
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_UEVENT_HELPER=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_INPUT_SPARSEKMAP=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_STAGING=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_RESET_CONTROLLER=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FANOTIFY=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_IOCHARSET="utf8"
+CONFIG_EXFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_USER=y
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:12 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:12 +0800
Subject: [PATCH v8 04/10] reset: Add Sunplus SP7021 reset driver
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <d962524ec4379482740caa45fc7605747de3b4b1.1642751015.git.qinjian@cqplus1.com>

Add reset driver for Sunplus SP7021 SoC.

Reviewed-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 MAINTAINERS                   |   1 +
 drivers/reset/Kconfig         |   9 +++
 drivers/reset/Makefile        |   1 +
 drivers/reset/reset-sunplus.c | 130 ++++++++++++++++++++++++++++++++++
 4 files changed, 141 insertions(+)
 create mode 100644 drivers/reset/reset-sunplus.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 652f42cab..6caffd6d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,7 @@ S:	Maintained
 W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F:	drivers/reset/reset-sunplus.c
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index be799a5ab..fb14456a8 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -224,6 +224,15 @@ config RESET_SOCFPGA
 	  This enables the reset driver for the SoCFPGA ARMv7 platforms. This
 	  driver gets initialized early during platform init calls.
 
+config RESET_SUNPLUS
+	bool "Sunplus SoCs Reset Driver" if COMPILE_TEST
+	default ARCH_SUNPLUS
+	help
+	  This enables the reset driver support for Sunplus SoCs.
+	  The reset lines that can be asserted and deasserted by toggling bits
+	  in a contiguous, exclusive register space. The register is HIWORD_MASKED,
+	  which means each register hold 16 reset lines.
+
 config RESET_SUNXI
 	bool "Allwinner SoCs Reset Driver" if COMPILE_TEST && !ARCH_SUNXI
 	default ARCH_SUNXI
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 21d46d886..f03403e97 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
 obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_SUNPLUS) += reset-sunplus.o
 obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o
 obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o
 obj-$(CONFIG_RESET_TI_SYSCON) += reset-ti-syscon.o
diff --git a/drivers/reset/reset-sunplus.c b/drivers/reset/reset-sunplus.c
new file mode 100644
index 000000000..113b36b57
--- /dev/null
+++ b/drivers/reset/reset-sunplus.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * SP7021 reset driver
+ *
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reboot.h>
+
+/* HIWORD_MASK_REG BITS */
+#define BITS_PER_HWM_REG	16
+
+struct sp_reset {
+	struct reset_controller_dev rcdev;
+	struct notifier_block notifier;
+	void __iomem *base;
+};
+
+static inline struct sp_reset *to_sp_reset(struct reset_controller_dev *rcdev)
+{
+	return container_of(rcdev, struct sp_reset, rcdev);
+}
+
+static int sp_reset_update(struct reset_controller_dev *rcdev,
+			   unsigned long id, bool assert)
+{
+	struct sp_reset *reset = to_sp_reset(rcdev);
+	int index = id / BITS_PER_HWM_REG;
+	int shift = id % BITS_PER_HWM_REG;
+	u32 val;
+
+	val = (1 << (16 + shift)) | (assert << shift);
+	writel(val, reset->base + (index * 4));
+
+	return 0;
+}
+
+static int sp_reset_assert(struct reset_controller_dev *rcdev,
+			   unsigned long id)
+{
+	return sp_reset_update(rcdev, id, true);
+}
+
+static int sp_reset_deassert(struct reset_controller_dev *rcdev,
+			     unsigned long id)
+{
+	return sp_reset_update(rcdev, id, false);
+}
+
+static int sp_reset_status(struct reset_controller_dev *rcdev,
+			   unsigned long id)
+{
+	struct sp_reset *reset = to_sp_reset(rcdev);
+	int index = id / BITS_PER_HWM_REG;
+	int shift = id % BITS_PER_HWM_REG;
+	u32 reg;
+
+	reg = readl(reset->base + (index * 4));
+
+	return !!(reg & BIT(shift));
+}
+
+static const struct reset_control_ops sp_reset_ops = {
+	.assert   = sp_reset_assert,
+	.deassert = sp_reset_deassert,
+	.status   = sp_reset_status,
+};
+
+static int sp_restart(struct notifier_block *nb, unsigned long mode,
+		      void *cmd)
+{
+	struct sp_reset *reset = container_of(nb, struct sp_reset, notifier);
+
+	sp_reset_assert(&reset->rcdev, 0);
+	sp_reset_deassert(&reset->rcdev, 0);
+
+	return NOTIFY_DONE;
+}
+
+static int sp_reset_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sp_reset *reset;
+	struct resource *res;
+	int ret;
+
+	reset = devm_kzalloc(dev, sizeof(*reset), GFP_KERNEL);
+	if (!reset)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	reset->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(reset->base))
+		return PTR_ERR(reset->base);
+
+	reset->rcdev.ops = &sp_reset_ops;
+	reset->rcdev.owner = THIS_MODULE;
+	reset->rcdev.of_node = dev->of_node;
+	reset->rcdev.nr_resets = resource_size(res) / 4 * BITS_PER_HWM_REG;
+
+	ret = devm_reset_controller_register(dev, &reset->rcdev);
+	if (ret)
+		return ret;
+
+	reset->notifier.notifier_call = sp_restart;
+	reset->notifier.priority = 192;
+
+	return register_restart_handler(&reset->notifier);
+}
+
+static const struct of_device_id sp_reset_dt_ids[] = {
+	{.compatible = "sunplus,sp7021-reset",},
+	{ /* sentinel */ },
+};
+
+static struct platform_driver sp_reset_driver = {
+	.probe = sp_reset_probe,
+	.driver = {
+		.name			= "sunplus-reset",
+		.of_match_table		= sp_reset_dt_ids,
+		.suppress_bind_attrs	= true,
+	},
+};
+builtin_platform_driver(sp_reset_driver);
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:14 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:14 +0800
Subject: [PATCH v8 06/10] clk: Add Sunplus SP7021 clock driver
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <34eeb839f4657491a704d00b532b2d8858eb35b6.1642751015.git.qinjian@cqplus1.com>

Add clock driver for Sunplus SP7021 SoC.

Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
Fix the comments from Stephen Boyd.
---
 MAINTAINERS              |   1 +
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-sp7021.c | 753 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 764 insertions(+)
 create mode 100644 drivers/clk/clk-sp7021.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 90ebb823f..5069f552f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2663,6 +2663,7 @@ W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F:	drivers/clk/clk-sp7021.c
 F:	drivers/reset/reset-sunplus.c
 F:	include/dt-bindings/clock/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c5b3dc973..91656de22 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -334,6 +334,15 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_SP7021
+	bool "Clock driver for Sunplus SP7021 SoC"
+	default SOC_SP7021
+	help
+	  This driver supports the Sunplus SP7021 SoC clocks.
+	  It implements SP7021 PLLs/gate.
+	  Not all features of the PLL are currently supported
+	  by the driver.
+
 config COMMON_CLK_STM32MP157
 	def_bool COMMON_CLK && MACH_STM32MP157
 	help
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index e42312121..f15bb5070 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_COMMON_CLK_SI5351)		+= clk-si5351.o
 obj-$(CONFIG_COMMON_CLK_SI514)		+= clk-si514.o
 obj-$(CONFIG_COMMON_CLK_SI544)		+= clk-si544.o
 obj-$(CONFIG_COMMON_CLK_SI570)		+= clk-si570.o
+obj-$(CONFIG_COMMON_CLK_SP7021)		+= clk-sp7021.o
 obj-$(CONFIG_COMMON_CLK_STM32F)		+= clk-stm32f4.o
 obj-$(CONFIG_COMMON_CLK_STM32H7)	+= clk-stm32h7.o
 obj-$(CONFIG_COMMON_CLK_STM32MP157)	+= clk-stm32mp1.o
diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
new file mode 100644
index 000000000..8a3e28a2a
--- /dev/null
+++ b/drivers/clk/clk-sp7021.c
@@ -0,0 +1,753 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+//#define DEBUG
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/bitfield.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/sp-sp7021.h>
+
+#define REG(i)		(pll_regs + (i) * 4)
+
+#define PLLA_CTL	REG(7)
+#define PLLE_CTL	REG(12)
+#define PLLF_CTL	REG(13)
+#define PLLTV_CTL	REG(14)
+#define PLLSYS_CTL	REG(26)
+
+/* speical div_width values for PLLTV/PLLA */
+#define DIV_TV		33
+#define DIV_A		34
+
+/* PLLTV parameters */
+enum {
+	SEL_FRA,
+	SDM_MOD,
+	PH_SEL,
+	NFRA,
+	DIVR,
+	DIVN,
+	DIVM,
+	P_MAX
+};
+
+#define MASK_SEL_FRA	GENMASK(1, 1)
+#define MASK_SDM_MOD	GENMASK(2, 2)
+#define MASK_PH_SEL	GENMASK(4, 4)
+#define MASK_NFRA	GENMASK(12, 6)
+#define MASK_DIVR	GENMASK(8, 7)
+#define MASK_DIVN	GENMASK(7, 0)
+#define MASK_DIVM	GENMASK(14, 8)
+
+/* HIWORD_MASK FIELD_PREP */
+#define HWM_FIELD_PREP(mask, value)		\
+({						\
+	u32 m = mask;				\
+	(m << 16) | FIELD_PREP(m, value);	\
+})
+
+struct sp_pll {
+	struct clk_hw hw;
+	void __iomem *reg;
+	spinlock_t *lock;	/* lock for reg */
+	int div_shift;
+	int div_width;
+	int pd_bit;		/* power down bit idx */
+	int bp_bit;		/* bypass bit idx */
+	unsigned long brate;	/* base rate, TODO: replace brate with muldiv */
+	u32 p[P_MAX];		/* for hold PLLTV/PLLA parameters */
+};
+
+#define to_sp_pll(_hw)	container_of(_hw, struct sp_pll, hw)
+
+#define clk_regs	(sp_clk_base + 0x000) /* G0 ~ CLKEN */
+#define pll_regs	(sp_clk_base + 0x200) /* G4 ~ PLL */
+static void __iomem *sp_clk_base;
+static struct clk_hw_onecell_data *sp_clk_data;
+
+#define F_CRITICAL	BIT(31)	/* clock is critical */
+#define F_EXTCLK	BIT(16)	/* parent clock is EXTCLK */
+const struct clk_parent_data parents[] = {
+	{ .name = "pllsys" },
+	{ .name = "extclk" },
+	{ .name = "plle" },
+};
+
+#define PD_PLLSYS	(&parents[0])
+#define PD_EXTCLK	(&parents[1])
+#define PD_PLLE		(&parents[2])
+
+static const u32 gates[] = {
+	CLK_SYSTEM			| F_CRITICAL,
+	CLK_RTC,
+	CLK_IOCTL			| F_CRITICAL,
+	CLK_IOP				| F_CRITICAL,
+	CLK_OTPRX,
+	CLK_NOC,
+	CLK_BR,
+	CLK_RBUS_L00			| F_CRITICAL,
+	CLK_SPIFL,
+	CLK_SDCTRL0			| F_CRITICAL,
+	CLK_PERI0	| F_EXTCLK,
+	CLK_A926			| F_CRITICAL,
+	CLK_UMCTL2			| F_CRITICAL,
+	CLK_PERI1	| F_EXTCLK,
+
+	CLK_DDR_PHY0			| F_CRITICAL,
+	CLK_ACHIP			| F_CRITICAL,
+	CLK_STC0,
+	CLK_STC_AV0,
+	CLK_STC_AV1,
+	CLK_STC_AV2,
+	CLK_UA0		| F_EXTCLK,
+	CLK_UA1		| F_EXTCLK,
+	CLK_UA2		| F_EXTCLK,
+	CLK_UA3		| F_EXTCLK,
+	CLK_UA4		| F_EXTCLK,
+	CLK_HWUA	| F_EXTCLK,
+	CLK_DDC0,
+	CLK_UADMA	| F_EXTCLK,
+
+	CLK_CBDMA0,
+	CLK_CBDMA1,
+	CLK_SPI_COMBO_0,
+	CLK_SPI_COMBO_1,
+	CLK_SPI_COMBO_2,
+	CLK_SPI_COMBO_3,
+	CLK_AUD,
+	CLK_USBC0,
+	CLK_USBC1,
+	CLK_UPHY0,
+	CLK_UPHY1,
+
+	CLK_I2CM0,
+	CLK_I2CM1,
+	CLK_I2CM2,
+	CLK_I2CM3,
+	CLK_PMC,
+	CLK_CARD_CTL0,
+	CLK_CARD_CTL1,
+
+	CLK_CARD_CTL4,
+	CLK_BCH,
+	CLK_DDFCH,
+	CLK_CSIIW0,
+	CLK_CSIIW1,
+	CLK_MIPICSI0,
+	CLK_MIPICSI1,
+
+	CLK_HDMI_TX,
+	CLK_VPOST,
+
+	CLK_TGEN,
+	CLK_DMIX,
+	CLK_TCON,
+	CLK_INTERRUPT			| F_CRITICAL,
+
+	CLK_RGST			| F_CRITICAL,
+	CLK_GPIO,
+	CLK_RBUS_TOP			| F_CRITICAL,
+
+	CLK_MAILBOX,
+	CLK_SPIND,
+	CLK_I2C2CBUS,
+	CLK_SEC,
+	CLK_GPOST0,
+	CLK_DVE,
+
+	CLK_OSD0,
+	CLK_DISP_PWM,
+	CLK_UADBG,
+	CLK_DUMMY_MASTER,
+	CLK_FIO_CTL,
+	CLK_FPGA,
+	CLK_L2SW,
+	CLK_ICM,
+	CLK_AXI_GLOBAL,
+};
+
+static DEFINE_SPINLOCK(plla_lock);
+static DEFINE_SPINLOCK(plle_lock);
+static DEFINE_SPINLOCK(pllf_lock);
+static DEFINE_SPINLOCK(pllsys_lock);
+static DEFINE_SPINLOCK(plltv_lock);
+
+#define _M		1000000UL
+#define F_27M		(27 * _M)
+
+/*********************************** PLL_TV **********************************/
+
+/* TODO: set proper FVCO range */
+#define FVCO_MIN	(100 * _M)
+#define FVCO_MAX	(200 * _M)
+
+#define F_MIN		(FVCO_MIN / 8)
+#define F_MAX		(FVCO_MAX)
+
+static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
+{
+	/* valid m values: 27M must be divisible by m, 0 means end */
+	static const u32 m_table[] = {
+		1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 0
+	};
+	u32 m, n, r;
+	unsigned long fvco, nf;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+
+	/* DIVM */
+	for (m = 0; m_table[m]; m++) {
+		nf = fvco * m_table[m];
+		n = nf / F_27M;
+		if ((n * F_27M) == nf)
+			break;
+	}
+	m = m_table[m];
+
+	if (!m) {
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+		       __func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+	}
+
+	/* save parameters */
+	clk->p[SEL_FRA] = 0;
+	clk->p[DIVR]    = r;
+	clk->p[DIVN]    = n;
+	clk->p[DIVM]    = m;
+
+	return freq;
+}
+
+/* parameters for PLLTV fractional divider */
+static const u32 pt[][5] = {
+	/* conventional fractional */
+	{
+		1,			// factor
+		5,			// 5 * p0 (nint)
+		1,			// 1 * p0
+		F_27M,			// F_27M / p0
+		1,			// p0 / p2
+	},
+	/* phase rotation */
+	{
+		10,			// factor
+		54,			// 5.4 * p0 (nint)
+		2,			// 0.2 * p0
+		F_27M / 10,		// F_27M / p0
+		5,			// p0 / p2
+	},
+};
+
+static const u32 mods[] = { 91, 55 }; /* SDM_MOD mod values */
+
+static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
+{
+	u32 m, r;
+	u32 nint, nfra;
+	u32 df_quotient_min = 210000000;
+	u32 df_remainder_min = 0;
+	unsigned long fvco, nf, f, fout = 0;
+	int sdm, ph;
+
+	/* check freq */
+	if (freq < F_MIN) {
+		pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
+		freq = F_MIN;
+	} else if (freq > F_MAX) {
+		pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
+			__func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
+		freq = F_MAX;
+	}
+
+	/* DIVR 0~3 */
+	for (r = 0; r <= 3; r++) {
+		fvco = freq << r;
+		if (fvco <= FVCO_MAX)
+			break;
+	}
+	f = F_27M >> r;
+
+	/* PH_SEL 1/0 */
+	for (ph = 1; ph >= 0; ph--) {
+		const u32 *pp = pt[ph];
+		u32 ms = 1;
+
+		/* SDM_MOD 0/1 */
+		for (sdm = 0; sdm <= 1; sdm++) {
+			u32 mod = mods[sdm];
+
+			/* DIVM 1~32 */
+			for (m = ms; m <= 32; m++) {
+				u32 df; /* diff freq */
+				u32 df_quotient = 0, df_remainder = 0;
+
+				nf = fvco * m;
+				nint = nf / pp[3];
+
+				if (nint < pp[1])
+					continue;
+				if (nint > pp[1])
+					break;
+
+				nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
+				if (nfra)
+					df = (f * (nint + pp[2]) / pp[0]) -
+					     (f * (mod - nfra) / mod / pp[4]);
+				else
+					df = (f * (nint) / pp[0]);
+
+				df_quotient  = df / m;
+				df_remainder = ((df % m) * 1000) / m;
+
+				if (freq > df_quotient) {
+					df_quotient  = freq - df_quotient - 1;
+					df_remainder = 1000 - df_remainder;
+				} else {
+					df_quotient = df_quotient - freq;
+				}
+
+				if (df_quotient_min > df_quotient ||
+				    (df_quotient_min == df_quotient &&
+				    df_remainder_min > df_remainder)) {
+					/* found a closer freq, save parameters */
+					clk->p[SEL_FRA] = 1;
+					clk->p[SDM_MOD] = sdm;
+					clk->p[PH_SEL]  = ph;
+					clk->p[NFRA]    = nfra;
+					clk->p[DIVR]    = r;
+					clk->p[DIVM]    = m;
+
+					fout = df / m;
+					df_quotient_min = df_quotient;
+					df_remainder_min = df_remainder;
+				}
+			}
+		}
+	}
+
+	if (!fout) {
+		pr_err("%s: %s freq:%lu not found a valid setting\n",
+		       __func__, clk_hw_get_name(&clk->hw), freq);
+		return -EINVAL;
+	}
+
+	return fout;
+}
+
+static long plltv_div(struct sp_pll *clk, unsigned long freq)
+{
+	if (freq % 100)
+		return plltv_fractional_div(clk, freq);
+
+	return plltv_integer_div(clk, freq);
+}
+
+static void plltv_set_rate(struct sp_pll *clk)
+{
+	u32 reg;
+
+	reg  = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
+	reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
+	reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
+	reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
+	writel(reg, clk->reg);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
+	writel(reg, clk->reg + 4);
+
+	reg  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
+	reg |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
+	writel(reg, clk->reg + 8);
+}
+
+/*********************************** PLL_A ***********************************/
+
+/* from Q628_PLLs_REG_setting.xlsx */
+static const struct {
+	u32 rate;
+	u32 regs[5];
+} pa[] = {
+	{
+		.rate = 135475200,
+		.regs = {
+			0x4801,
+			0x02df,
+			0x248f,
+			0x0211,
+			0x33e9
+		}
+	},
+	{
+		.rate = 147456000,
+		.regs = {
+			0x4801,
+			0x1adf,
+			0x2490,
+			0x0349,
+			0x33e9
+		}
+	},
+	{
+		.rate = 196608000,
+		.regs = {
+			0x4801,
+			0x42ef,
+			0x2495,
+			0x01c6,
+			0x33e9
+		}
+	},
+};
+
+static void plla_set_rate(struct sp_pll *clk)
+{
+	const u32 *pp = pa[clk->p[0]].regs;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
+		writel(0xffff0000 | pp[i], clk->reg + (i * 4));
+}
+
+static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
+{
+	int i = ARRAY_SIZE(pa);
+
+	while (--i) {
+		if (rate >= pa[i].rate)
+			break;
+	}
+	clk->p[0] = i;
+
+	return pa[i].rate;
+}
+
+/********************************** SP_PLL ***********************************/
+
+static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
+{
+	u32 fbdiv;
+	u32 max = 1 << clk->div_width;
+
+	fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
+	if (fbdiv > max)
+		fbdiv = max;
+
+	return fbdiv;
+}
+
+static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long *prate)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	long ret;
+
+	if (rate == *prate)
+		ret = *prate; /* bypass */
+	else if (clk->div_width == DIV_A) {
+		ret = plla_round_rate(clk, rate);
+	} else if (clk->div_width == DIV_TV) {
+		ret = plltv_div(clk, rate);
+		if (ret < 0)
+			ret = *prate;
+	} else {
+		ret = sp_pll_calc_div(clk, rate) * clk->brate;
+	}
+
+	return ret;
+}
+
+static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
+					unsigned long prate)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	u32 reg = readl(clk->reg);
+	unsigned long ret;
+
+	if (reg & BIT(clk->bp_bit))
+		ret = prate; /* bypass */
+	else if (clk->div_width == DIV_A)
+		ret = pa[clk->p[0]].rate;
+	else if (clk->div_width == DIV_TV) {
+		u32 m, r, reg2;
+
+		r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
+		reg2 = readl(clk->reg + 8);
+		m = FIELD_GET(MASK_DIVM, reg2) + 1;
+
+		if (reg & BIT(1)) { /* SEL_FRA */
+			/* fractional divider */
+			u32 sdm  = FIELD_GET(MASK_SDM_MOD, reg);
+			u32 ph   = FIELD_GET(MASK_PH_SEL, reg);
+			u32 nfra = FIELD_GET(MASK_NFRA, reg);
+			const u32 *pp = pt[ph];
+
+			ret = prate >> r;
+			ret = (ret * (pp[1] + pp[2]) / pp[0]) -
+				  (ret * (mods[sdm] - nfra) / mods[sdm] / pp[4]);
+			ret /= m;
+		} else {
+			/* integer divider */
+			u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
+
+			ret = (prate / m * n) >> r;
+		}
+	} else {
+		u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
+
+		ret = clk->brate * fbdiv;
+	}
+
+	return ret;
+}
+
+static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			   unsigned long prate)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	unsigned long flags;
+	u32 reg;
+
+	spin_lock_irqsave(clk->lock, flags);
+
+	reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
+
+	if (rate == prate)
+		reg |= BIT(clk->bp_bit); /* bypass */
+	else if (clk->div_width == DIV_A)
+		plla_set_rate(clk);
+	else if (clk->div_width == DIV_TV)
+		plltv_set_rate(clk);
+	else if (clk->div_width) {
+		u32 fbdiv = sp_pll_calc_div(clk, rate);
+		u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
+
+		reg |= (mask << 16) | (((fbdiv - 1) << clk->div_shift) & mask);
+	}
+
+	writel(reg, clk->reg);
+
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return 0;
+}
+
+static int sp_pll_enable(struct clk_hw *hw)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
+	spin_unlock_irqrestore(clk->lock, flags);
+
+	return 0;
+}
+
+static void sp_pll_disable(struct clk_hw *hw)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+	unsigned long flags;
+
+	spin_lock_irqsave(clk->lock, flags);
+	writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
+	spin_unlock_irqrestore(clk->lock, flags);
+}
+
+static int sp_pll_is_enabled(struct clk_hw *hw)
+{
+	struct sp_pll *clk = to_sp_pll(hw);
+
+	return readl(clk->reg) & BIT(clk->pd_bit);
+}
+
+static const struct clk_ops sp_pll_ops = {
+	.enable = sp_pll_enable,
+	.disable = sp_pll_disable,
+	.is_enabled = sp_pll_is_enabled,
+	.round_rate = sp_pll_round_rate,
+	.recalc_rate = sp_pll_recalc_rate,
+	.set_rate = sp_pll_set_rate
+};
+
+static const struct clk_ops sp_pll_sub_ops = {
+	.enable = sp_pll_enable,
+	.disable = sp_pll_disable,
+	.is_enabled = sp_pll_is_enabled,
+	.recalc_rate = sp_pll_recalc_rate,
+};
+
+struct clk_hw *sp_pll_register(struct device *dev, const char *name,
+			       const struct clk_parent_data *parent_data,
+			       void __iomem *reg, int pd_bit, int bp_bit,
+			       unsigned long brate, int shift, int width,
+			       spinlock_t *lock)
+{
+	struct sp_pll *pll;
+	struct clk_hw *hw;
+	struct clk_init_data initd = {
+		.name = name,
+		.parent_data = parent_data,
+		.ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
+		.num_parents = 1,
+		/* system clock, should not be disabled */
+		.flags = (reg == PLLSYS_CTL) ? CLK_IS_CRITICAL : 0,
+	};
+	int ret;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	pll->hw.init = &initd;
+	pll->reg = reg;
+	pll->pd_bit = pd_bit;
+	pll->bp_bit = bp_bit;
+	pll->brate = brate;
+	pll->div_shift = shift;
+	pll->div_width = width;
+	pll->lock = lock;
+
+	hw = &pll->hw;
+	ret = devm_clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(pll);
+		hw = ERR_PTR(ret);
+	} else {
+		pr_debug("%-20s%lu\n", name, clk_hw_get_rate(hw));
+		devm_clk_hw_register_clkdev(dev, hw, NULL, name);
+	}
+
+	return hw;
+}
+
+static int sp7021_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int i, ret;
+	struct clk_hw **hws;
+	struct resource *res;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));
+	if (WARN_ON(!sp_clk_base))
+		return -ENXIO;
+
+	sp_clk_data = devm_kzalloc(dev, struct_size(sp_clk_data, hws, CLK_MAX),
+				   GFP_KERNEL);
+	if (!sp_clk_data)
+		return -ENOMEM;
+
+	hws = sp_clk_data->hws;
+
+	/* PLL_A */
+	hws[PLL_A] = sp_pll_register(dev, "plla", PD_EXTCLK, PLLA_CTL,
+				     11, 12, 27000000, 0, DIV_A, &plla_lock);
+	if (IS_ERR(hws[PLL_A]))
+		return PTR_ERR(hws[PLL_A]);
+
+	/* PLL_E */
+	hws[PLL_E] = sp_pll_register(dev, "plle", PD_EXTCLK, PLLE_CTL,
+				     6, 2, 50000000, 0, 0, &plle_lock);
+	if (IS_ERR(hws[PLL_E]))
+		return PTR_ERR(hws[PLL_E]);
+	hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", PD_PLLE, PLLE_CTL,
+					 13, -1, 2500000, 0, 0, &plle_lock);
+	if (IS_ERR(hws[PLL_E_2P5]))
+		return PTR_ERR(hws[PLL_E_2P5]);
+	hws[PLL_E_25] = sp_pll_register(dev, "plle_25", PD_PLLE, PLLE_CTL,
+					12, -1, 25000000, 0, 0, &plle_lock);
+	if (IS_ERR(hws[PLL_E_25]))
+		return PTR_ERR(hws[PLL_E_25]);
+	hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", PD_PLLE, PLLE_CTL,
+					   11, -1, 112500000, 0, 0, &plle_lock);
+	if (IS_ERR(hws[PLL_E_112P5]))
+		return PTR_ERR(hws[PLL_E_112P5]);
+
+	/* PLL_F */
+	hws[PLL_F] = sp_pll_register(dev, "pllf", PD_EXTCLK, PLLF_CTL,
+				     0, 10, 13500000, 1, 4, &pllf_lock);
+	if (IS_ERR(hws[PLL_F]))
+		return PTR_ERR(hws[PLL_F]);
+
+	/* PLL_TV */
+	hws[PLL_TV] = sp_pll_register(dev, "plltv", PD_EXTCLK, PLLTV_CTL,
+				      0, 15, 27000000, 0, DIV_TV, &plltv_lock);
+	if (IS_ERR(hws[PLL_TV]))
+		return PTR_ERR(hws[PLL_TV]);
+	hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
+						     PLLTV_CTL + 4, 5, 1,
+						     CLK_DIVIDER_POWER_OF_TWO,
+						     &plltv_lock);
+	if (IS_ERR(hws[PLL_TV_A]))
+		return PTR_ERR(hws[PLL_TV_A]);
+	ret = devm_clk_hw_register_clkdev(dev, hws[PLL_TV_A], NULL, "plltv_a");
+	if (ret)
+		return ret;
+
+	/* PLL_SYS */
+	hws[PLL_SYS] = sp_pll_register(dev, "pllsys", PD_EXTCLK, PLLSYS_CTL,
+				       10, 9, 13500000, 0, 4, &pllsys_lock);
+	if (IS_ERR(hws[PLL_SYS]))
+		return PTR_ERR(hws[PLL_SYS]);
+
+	/* gates */
+	for (i = 0; i < ARRAY_SIZE(gates); i++) {
+		u32 f = gates[i];
+		const char *parent_name = parents[!!(f & F_EXTCLK)].name;
+		bool critical = f & F_CRITICAL;
+		int j = f & 0xffff;
+		char s[10];
+
+		sprintf(s, "clken%02x", j);
+		hws[j] = clk_hw_register_gate(dev, s, parent_name,
+					      critical ? CLK_IS_CRITICAL : 0,
+					      clk_regs + (j >> 4) * 4,
+					      j & 0x0f,
+					      CLK_GATE_HIWORD_MASK, NULL);
+		if (IS_ERR(hws[j]))
+			return PTR_ERR(hws[j]);
+	}
+
+	sp_clk_data->num = CLK_MAX;
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
+}
+
+static const struct of_device_id sp7021_clk_dt_ids[] = {
+	{ .compatible = "sunplus,sp7021-clkc", },
+	{ }
+};
+
+static struct platform_driver sp7021_clk_driver = {
+	.probe  = sp7021_clk_probe,
+	.driver = {
+		.name = "sp7021-clk",
+		.of_match_table = sp7021_clk_dt_ids,
+	},
+};
+builtin_platform_driver(sp7021_clk_driver);
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:10 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:10 +0800
Subject: [PATCH v8 02/10] dt-bindings: arm: sunplus: Add bindings for Sunplus
 SP7021 SoC boards
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <87cc20bb3ef747c4da89f9e60c0847532bb0a679.1642751015.git.qinjian@cqplus1.com>

This introduces bindings for boards based Sunplus SP7021 SoC.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 .../bindings/arm/sunplus,sp7021.yaml          | 27 +++++++++++++++++++
 MAINTAINERS                                   |  7 +++++
 2 files changed, 34 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml

diff --git a/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
new file mode 100644
index 000000000..5b9985b73
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/sunplus,sp7021.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 Boards Device Tree Bindings
+
+maintainers:
+  - qinjian <qinjian at cqplus1.com>
+
+description: |
+  ARM platforms using Sunplus SP7021, an ARM Cortex A7 (4-cores) based SoC.
+  Wiki: https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - items:
+          - const: sunplus,sp7021-achip
+
+additionalProperties: true
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index e0bca0de0..6a5422f10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2655,6 +2655,13 @@ F:	drivers/clocksource/armv7m_systick.c
 N:	stm32
 N:	stm
 
+ARM/SUNPLUS SP7021 SOC SUPPORT
+M:	Qin Jian <qinjian at cqplus1.com>
+L:	linux-arm-kernel at lists.infradead.org (moderated for mon-subscribers)
+S:	Maintained
+W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
+F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+
 ARM/Synaptics SoC support
 M:	Jisheng Zhang <Jisheng.Zhang at synaptics.com>
 M:	Sebastian Hesselbarth <sebastian.hesselbarth at gmail.com>
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:13 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:13 +0800
Subject: [PATCH v8 05/10] dt-bindings: clock: Add bindings for SP7021 clock
 driver
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <504303c7cf92af8368dcda0cdde3b9c15a833418.1642751015.git.qinjian@cqplus1.com>

Add documentation to describe Sunplus SP7021 clock driver bindings.

Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
Add clocks & clock-names.
---
 .../bindings/clock/sunplus,sp7021-clkc.yaml   |  52 ++++++++
 MAINTAINERS                                   |   2 +
 include/dt-bindings/clock/sp-sp7021.h         | 112 ++++++++++++++++++
 3 files changed, 166 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 create mode 100644 include/dt-bindings/clock/sp-sp7021.h

diff --git a/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
new file mode 100644
index 000000000..e6d098cf4
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/sunplus,sp7021-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Clock Controller Binding
+
+maintainers:
+  - Qin Jian <qinjian at cqplus1.com>
+
+properties:
+  compatible:
+    const: sunplus,sp7021-clkc
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: External oscillator clock
+      - description: System clock
+
+  clock-names:
+    items:
+      - const: extclk
+      - const: pllsys
+
+required:
+  - compatible
+  - "#clock-cells"
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    clkc: clock-controller at 9c000000 {
+      compatible = "sunplus,sp7021-clkc";
+      #clock-cells = <1>;
+      reg = <0x9c000000 0x280>;
+      clocks = <&extclk>, <&clkc PLL_SYS>;
+      clock-names = "extclk", "pllsys";
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6caffd6d0..90ebb823f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,8 +2661,10 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for mon-subscribers)
 S:	Maintained
 W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 F:	drivers/reset/reset-sunplus.c
+F:	include/dt-bindings/clock/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
diff --git a/include/dt-bindings/clock/sp-sp7021.h b/include/dt-bindings/clock/sp-sp7021.h
new file mode 100644
index 000000000..45dac6de8
--- /dev/null
+++ b/include/dt-bindings/clock/sp-sp7021.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+#ifndef _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_CLOCK_SUNPLUS_SP7021_H
+
+#define XTAL			27000000
+
+/* plls */
+#define PLL_A			0
+#define PLL_E			1
+#define PLL_E_2P5		2
+#define PLL_E_25		3
+#define PLL_E_112P5		4
+#define PLL_F			5
+#define PLL_TV			6
+#define PLL_TV_A		7
+#define PLL_SYS			8
+
+/* gates: mo_clken0 ~ mo_clken9 */
+#define CLK_SYSTEM		0x10
+#define CLK_RTC			0x12
+#define CLK_IOCTL		0x13
+#define CLK_IOP			0x14
+#define CLK_OTPRX		0x15
+#define CLK_NOC			0x16
+#define CLK_BR			0x17
+#define CLK_RBUS_L00	        0x18
+#define CLK_SPIFL		0x19
+#define CLK_SDCTRL0		0x1a
+#define CLK_PERI0		0x1b
+#define CLK_A926		0x1d
+#define CLK_UMCTL2		0x1e
+#define CLK_PERI1		0x1f
+
+#define CLK_DDR_PHY0	        0x20
+#define CLK_ACHIP		0x22
+#define CLK_STC0		0x24
+#define CLK_STC_AV0		0x25
+#define CLK_STC_AV1		0x26
+#define CLK_STC_AV2		0x27
+#define CLK_UA0			0x28
+#define CLK_UA1			0x29
+#define CLK_UA2			0x2a
+#define CLK_UA3			0x2b
+#define CLK_UA4			0x2c
+#define CLK_HWUA		0x2d
+#define CLK_DDC0		0x2e
+#define CLK_UADMA		0x2f
+
+#define CLK_CBDMA0		0x30
+#define CLK_CBDMA1		0x31
+#define CLK_SPI_COMBO_0	        0x32
+#define CLK_SPI_COMBO_1	        0x33
+#define CLK_SPI_COMBO_2	        0x34
+#define CLK_SPI_COMBO_3	        0x35
+#define CLK_AUD			0x36
+#define CLK_USBC0		0x3a
+#define CLK_USBC1		0x3b
+#define CLK_UPHY0		0x3d
+#define CLK_UPHY1		0x3e
+
+#define CLK_I2CM0		0x40
+#define CLK_I2CM1		0x41
+#define CLK_I2CM2		0x42
+#define CLK_I2CM3		0x43
+#define CLK_PMC			0x4d
+#define CLK_CARD_CTL0	        0x4e
+#define CLK_CARD_CTL1	        0x4f
+
+#define CLK_CARD_CTL4	        0x52
+#define CLK_BCH			0x54
+#define CLK_DDFCH		0x5b
+#define CLK_CSIIW0		0x5c
+#define CLK_CSIIW1		0x5d
+#define CLK_MIPICSI0	        0x5e
+#define CLK_MIPICSI1	        0x5f
+
+#define CLK_HDMI_TX		0x60
+#define CLK_VPOST		0x65
+
+#define CLK_TGEN		0x70
+#define CLK_DMIX		0x71
+#define CLK_TCON		0x7a
+#define CLK_INTERRUPT	        0x7f
+
+#define CLK_RGST		0x80
+#define CLK_GPIO		0x83
+#define CLK_RBUS_TOP	        0x84
+
+#define CLK_MAILBOX		0x96
+#define CLK_SPIND		0x9a
+#define CLK_I2C2CBUS	        0x9b
+#define CLK_SEC			0x9d
+#define CLK_DVE			0x9e
+#define CLK_GPOST0		0x9f
+
+#define CLK_OSD0		0xa0
+#define CLK_DISP_PWM	        0xa2
+#define CLK_UADBG		0xa3
+#define CLK_DUMMY_MASTER	0xa4
+#define CLK_FIO_CTL		0xa5
+#define CLK_FPGA		0xa6
+#define CLK_L2SW		0xa7
+#define CLK_ICM			0xa8
+#define CLK_AXI_GLOBAL	        0xa9
+
+#define CLK_MAX			0xb0
+
+#endif
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:09 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:09 +0800
Subject: [PATCH v8 01/10] dt-bindings: vendor-prefixes: Add Sunplus
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <2e74a1339a5ea54d92fdc4d1998a2b169e23b82b.1642751015.git.qinjian@cqplus1.com>

Add vendor prefix for Sunplus Technology Co., Ltd. (http://www.sunplus.com)

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index a867f7102..50d4ee5ac 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1131,6 +1131,8 @@ patternProperties:
     description: Summit microelectronics
   "^sunchip,.*":
     description: Shenzhen Sunchip Technology Co., Ltd
+  "^sunplus,.*":
+    description: Sunplus Technology Co., Ltd.
   "^SUNW,.*":
     description: Sun Microsystems, Inc
   "^supermicro,.*":
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:11 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:11 +0800
Subject: [PATCH v8 03/10] dt-bindings: reset: Add bindings for SP7021 reset
 driver
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <6444261d9d4179839ce8f828a9814a057821082a.1642751015.git.qinjian@cqplus1.com>

Add documentation to describe Sunplus SP7021 reset driver bindings.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 .../bindings/reset/sunplus,reset.yaml         | 38 ++++++++
 MAINTAINERS                                   |  2 +
 include/dt-bindings/reset/sp-sp7021.h         | 97 +++++++++++++++++++
 3 files changed, 137 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 create mode 100644 include/dt-bindings/reset/sp-sp7021.h

diff --git a/Documentation/devicetree/bindings/reset/sunplus,reset.yaml b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
new file mode 100644
index 000000000..c083c821f
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/sunplus,reset.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/reset/sunplus,reset.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Sunplus SoC Reset Controller
+
+maintainers:
+  - Qin Jian <qinjian at cqplus1.com>
+
+properties:
+  compatible:
+    const: sunplus,sp7021-reset
+
+  "#reset-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#reset-cells"
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    rstc: reset at 9c000054 {
+      compatible = "sunplus,sp7021-reset";
+      #reset-cells = <1>;
+      reg = <0x9c000054 0x28>;
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 6a5422f10..652f42cab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2661,6 +2661,8 @@ L:	linux-arm-kernel at lists.infradead.org (moderated for mon-subscribers)
 S:	Maintained
 W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
+F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
+F:	include/dt-bindings/reset/sp-sp7021.h
 
 ARM/Synaptics SoC support
 M:	Jisheng Zhang <Jisheng.Zhang at synaptics.com>
diff --git a/include/dt-bindings/reset/sp-sp7021.h b/include/dt-bindings/reset/sp-sp7021.h
new file mode 100644
index 000000000..fd2a50327
--- /dev/null
+++ b/include/dt-bindings/reset/sp-sp7021.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+#ifndef _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+#define _DT_BINDINGS_RST_SUNPLUS_SP7021_H
+
+/* mo_reset0 ~ mo_reset9 */
+#define RST_SYSTEM		0x00
+#define RST_RTC			0x02
+#define RST_IOCTL		0x03
+#define RST_IOP			0x04
+#define RST_OTPRX		0x05
+#define RST_NOC			0x06
+#define RST_BR			0x07
+#define RST_RBUS_L00	        0x08
+#define RST_SPIFL		0x09
+#define RST_SDCTRL0		0x0a
+#define RST_PERI0		0x0b
+#define RST_A926		0x0d
+#define RST_UMCTL2		0x0e
+#define RST_PERI1		0x0f
+
+#define RST_DDR_PHY0	        0x10
+#define RST_ACHIP		0x12
+#define RST_STC0		0x14
+#define RST_STC_AV0		0x15
+#define RST_STC_AV1		0x16
+#define RST_STC_AV2		0x17
+#define RST_UA0			0x18
+#define RST_UA1			0x19
+#define RST_UA2			0x1a
+#define RST_UA3			0x1b
+#define RST_UA4			0x1c
+#define RST_HWUA		0x1d
+#define RST_DDC0		0x1e
+#define RST_UADMA		0x1f
+
+#define RST_CBDMA0		0x20
+#define RST_CBDMA1		0x21
+#define RST_SPI_COMBO_0	        0x22
+#define RST_SPI_COMBO_1	        0x23
+#define RST_SPI_COMBO_2	        0x24
+#define RST_SPI_COMBO_3	        0x25
+#define RST_AUD			0x26
+#define RST_USBC0		0x2a
+#define RST_USBC1		0x2b
+#define RST_UPHY0		0x2d
+#define RST_UPHY1		0x2e
+
+#define RST_I2CM0		0x30
+#define RST_I2CM1		0x31
+#define RST_I2CM2		0x32
+#define RST_I2CM3		0x33
+#define RST_PMC			0x3d
+#define RST_CARD_CTL0	        0x3e
+#define RST_CARD_CTL1	        0x3f
+
+#define RST_CARD_CTL4	        0x42
+#define RST_BCH			0x44
+#define RST_DDFCH		0x4b
+#define RST_CSIIW0		0x4c
+#define RST_CSIIW1		0x4d
+#define RST_MIPICSI0	        0x4e
+#define RST_MIPICSI1	        0x4f
+
+#define RST_HDMI_TX		0x50
+#define RST_VPOST		0x55
+
+#define RST_TGEN		0x60
+#define RST_DMIX		0x61
+#define RST_TCON		0x6a
+#define RST_INTERRUPT	        0x6f
+
+#define RST_RGST		0x70
+#define RST_GPIO		0x73
+#define RST_RBUS_TOP	        0x74
+
+#define RST_MAILBOX		0x86
+#define RST_SPIND		0x8a
+#define RST_I2C2CBUS	        0x8b
+#define RST_SEC			0x8d
+#define RST_DVE			0x8e
+#define RST_GPOST0		0x8f
+
+#define RST_OSD0		0x90
+#define RST_DISP_PWM	        0x92
+#define RST_UADBG		0x93
+#define RST_DUMMY_MASTER	0x94
+#define RST_FIO_CTL		0x95
+#define RST_FPGA		0x96
+#define RST_L2SW		0x97
+#define RST_ICM			0x98
+#define RST_AXI_GLOBAL	        0x99
+
+#endif
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:15 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:15 +0800
Subject: [PATCH v8 07/10] dt-bindings: interrupt-controller: Add bindings for
 SP7021 interrupt controller
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <5e7f28ecab70fbe39727ace4758a306afe723dd1.1642751015.git.qinjian@cqplus1.com>

Add documentation to describe Sunplus SP7021 interrupt controller bindings.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
 .../sunplus,sp7021-intc.yaml                  | 62 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
new file mode 100644
index 000000000..5daeab63c
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (C) Sunplus Co., Ltd. 2021
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interrupt-controller/sunplus,sp7021-intc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Sunplus SP7021 SoC Interrupt Controller Device Tree Bindings
+
+maintainers:
+  - Qin Jian <qinjian at cqplus1.com>
+
+properties:
+  compatible:
+    items:
+      - const: sunplus,sp7021-intc
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+    description:
+      The first cell is the IRQ number, the second cell is the trigger
+      type as defined in interrupt.txt in this directory.
+
+  reg:
+    maxItems: 2
+    description:
+      Specifies base physical address(s) and size of the controller regs.
+      The 1st region include type/polarity/priority/mask regs.
+      The 2nd region include clear/masked_ext0/masked_ext1/group regs.
+
+  interrupts:
+    maxItems: 2
+    description:
+      EXT_INT0 & EXT_INT1, 2 interrupts references to primary interrupt
+      controller.
+
+required:
+  - compatible
+  - interrupt-controller
+  - "#interrupt-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    intc: interrupt-controller at 9c000780 {
+        compatible = "sunplus,sp7021-intc";
+        interrupt-controller;
+        #interrupt-cells = <2>;
+        reg = <0x9c000780 0x80>, <0x9c000a80 0x80>;
+        interrupt-parent = <&gic>;
+        interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, /* EXT_INT0 */
+                     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; /* EXT_INT1 */
+    };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 5069f552f..6b3bbe021 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2662,6 +2662,7 @@ S:	Maintained
 W:	https://sunplus-tibbo.atlassian.net/wiki/spaces/doc/overview
 F:	Documentation/devicetree/bindings/arm/sunplus,sp7021.yaml
 F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
+F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 F:	drivers/clk/clk-sp7021.c
 F:	drivers/reset/reset-sunplus.c
-- 
2.33.1



From qinjian at cqplus1.com  Thu Jan 20 23:53:16 2022
From: qinjian at cqplus1.com (Qin Jian)
Date: Fri, 21 Jan 2022 15:53:16 +0800
Subject: [PATCH v8 08/10] irqchip: Add Sunplus SP7021 interrupt controller
 driver
In-Reply-To: <cover.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
Message-ID: <fabbeb729dc8cef5e6dd232d84e1c1bbe22115d9.1642751015.git.qinjian@cqplus1.com>

Add interrupt controller driver for Sunplus SP7021 SoC.

This is the interrupt controller in P-chip which collects all interrupt
sources in P-chip and routes them to parent interrupt controller in C-chip.

Signed-off-by: Qin Jian <qinjian at cqplus1.com>
---
Fix the comments from Marc.
---
 MAINTAINERS                       |   1 +
 drivers/irqchip/Kconfig           |   9 +
 drivers/irqchip/Makefile          |   1 +
 drivers/irqchip/irq-sp7021-intc.c | 288 ++++++++++++++++++++++++++++++
 4 files changed, 299 insertions(+)
 create mode 100644 drivers/irqchip/irq-sp7021-intc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 6b3bbe021..febbd97bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2665,6 +2665,7 @@ F:	Documentation/devicetree/bindings/clock/sunplus,sp7021-clkc.yaml
 F:	Documentation/devicetree/bindings/interrupt-controller/sunplus,sp7021-intc.yaml
 F:	Documentation/devicetree/bindings/reset/sunplus,reset.yaml
 F:	drivers/clk/clk-sp7021.c
+F:	drivers/irqchip/irq-sp7021-intc.c
 F:	drivers/reset/reset-sunplus.c
 F:	include/dt-bindings/clock/sp-sp7021.h
 F:	include/dt-bindings/reset/sp-sp7021.h
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index aca7b595c..32d7a8e0c 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -602,4 +602,13 @@ config APPLE_AIC
 	  Support for the Apple Interrupt Controller found on Apple Silicon SoCs,
 	  such as the M1.
 
+config SUNPLUS_SP7021_INTC
+	bool "Sunplus SP7021 interrupt controller" if COMPILE_TEST
+	default SOC_SP7021
+	help
+	  Support for the Sunplus SP7021 Interrupt Controller IP core.
+	  SP7021 SoC has 2 Chips: C-Chip & P-Chip. This is used as a
+	  chained controller, routing all interrupt source in P-Chip to
+	  the primary controller on C-Chip.
+
 endmenu
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index f88cbf36a..75411f654 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -116,3 +116,4 @@ obj-$(CONFIG_MACH_REALTEK_RTL)		+= irq-realtek-rtl.o
 obj-$(CONFIG_WPCM450_AIC)		+= irq-wpcm450-aic.o
 obj-$(CONFIG_IRQ_IDT3243X)		+= irq-idt3243x.o
 obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
+obj-$(CONFIG_SUNPLUS_SP7021_INTC)	+= irq-sp7021-intc.o
diff --git a/drivers/irqchip/irq-sp7021-intc.c b/drivers/irqchip/irq-sp7021-intc.c
new file mode 100644
index 000000000..d1821a955
--- /dev/null
+++ b/drivers/irqchip/irq-sp7021-intc.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Copyright (C) Sunplus Technology Co., Ltd.
+ *       All rights reserved.
+ */
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define SP_INTC_HWIRQ_MIN	0
+#define SP_INTC_HWIRQ_MAX	223
+
+#define SP_INTC_NR_IRQS		(SP_INTC_HWIRQ_MAX - SP_INTC_HWIRQ_MIN + 1)
+#define SP_INTC_NR_GROUPS	DIV_ROUND_UP(SP_INTC_NR_IRQS, 32)
+#define SP_INTC_REG_SIZE	(SP_INTC_NR_GROUPS * 4)
+
+/* REG_GROUP_0 regs */
+#define REG_INTR_TYPE		(sp_intc.g0)
+#define REG_INTR_POLARITY	(REG_INTR_TYPE     + SP_INTC_REG_SIZE)
+#define REG_INTR_PRIORITY	(REG_INTR_POLARITY + SP_INTC_REG_SIZE)
+#define REG_INTR_MASK		(REG_INTR_PRIORITY + SP_INTC_REG_SIZE)
+
+/* REG_GROUP_1 regs */
+#define REG_INTR_CLEAR		(sp_intc.g1)
+#define REG_MASKED_EXT1		(REG_INTR_CLEAR    + SP_INTC_REG_SIZE)
+#define REG_MASKED_EXT0		(REG_MASKED_EXT1   + SP_INTC_REG_SIZE)
+#define REG_INTR_GROUP		(REG_INTR_CLEAR    + 31 * 4)
+
+#define GROUP_MASK		(BIT(SP_INTC_NR_GROUPS) - 1)
+#define GROUP_SHIFT_EXT1	(0)
+#define GROUP_SHIFT_EXT0	(8)
+
+/*
+ * When GPIO_INT0~7 set to edge trigger, doesn't work properly.
+ * WORKAROUND: change it to level trigger, and toggle the polarity
+ * at ACK/Handler to make the HW work.
+ */
+#define GPIO_INT0_HWIRQ		120
+#define GPIO_INT7_HWIRQ		127
+#define IS_GPIO_INT(irq)					\
+({								\
+	u32 i = irq;						\
+	(i >= GPIO_INT0_HWIRQ) && (i <= GPIO_INT7_HWIRQ);	\
+})
+
+/* index of states */
+enum {
+	_IS_EDGE = 0,
+	_IS_LOW,
+	_IS_ACTIVE
+};
+
+#define STATE_BIT(irq, idx)		(((irq) - GPIO_INT0_HWIRQ) * 3 + (idx))
+#define ASSIGN_STATE(irq, idx, v)	assign_bit(STATE_BIT(irq, idx), sp_intc.states, v)
+#define TEST_STATE(irq, idx)		test_bit(STATE_BIT(irq, idx), sp_intc.states)
+
+static struct sp_intctl {
+	/*
+	 * REG_GROUP_0: include type/polarity/priority/mask regs.
+	 * REG_GROUP_1: include clear/masked_ext0/masked_ext1/group regs.
+	 */
+	void __iomem *g0; // REG_GROUP_0 base
+	void __iomem *g1; // REG_GROUP_1 base
+
+	struct irq_domain *domain;
+	raw_spinlock_t lock;
+
+	/*
+	 * store GPIO_INT states
+	 * each interrupt has 3 states: is_edge, is_low, is_active
+	 */
+	DECLARE_BITMAP(states, (GPIO_INT7_HWIRQ - GPIO_INT0_HWIRQ + 1) * 3);
+} sp_intc;
+
+static struct irq_chip sp_intc_chip;
+
+static void sp_intc_assign_bit(u32 hwirq, void __iomem *base, bool value)
+{
+	u32 offset, mask;
+	unsigned long flags;
+	void __iomem *reg;
+
+	offset = (hwirq / 32) * 4;
+	reg = base + offset;
+
+	raw_spin_lock_irqsave(&sp_intc.lock, flags);
+	mask = readl_relaxed(reg);
+	if (value)
+		mask |= BIT(hwirq % 32);
+	else
+		mask &= ~BIT(hwirq % 32);
+	writel_relaxed(mask, reg);
+	raw_spin_unlock_irqrestore(&sp_intc.lock, flags);
+}
+
+static void sp_intc_ack_irq(struct irq_data *d)
+{
+	u32 hwirq = d->hwirq;
+
+	if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_EDGE))) { // WORKAROUND
+		sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, !TEST_STATE(hwirq, _IS_LOW));
+		ASSIGN_STATE(hwirq, _IS_ACTIVE, true);
+	}
+
+	sp_intc_assign_bit(hwirq, REG_INTR_CLEAR, 1);
+}
+
+static void sp_intc_mask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 0);
+}
+
+static void sp_intc_unmask_irq(struct irq_data *d)
+{
+	sp_intc_assign_bit(d->hwirq, REG_INTR_MASK, 1);
+}
+
+static int sp_intc_set_type(struct irq_data *d, unsigned int type)
+{
+	u32 hwirq = d->hwirq;
+	bool is_edge = !(type & IRQ_TYPE_LEVEL_MASK);
+	bool is_low = (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_EDGE_FALLING);
+
+	irq_set_handler_locked(d, is_edge ? handle_edge_irq : handle_level_irq);
+
+	if (unlikely(IS_GPIO_INT(hwirq) && is_edge)) { // WORKAROUND
+		/* store states */
+		ASSIGN_STATE(hwirq, _IS_EDGE, is_edge);
+		ASSIGN_STATE(hwirq, _IS_LOW, is_low);
+		ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+		/* change to level */
+		is_edge = false;
+	}
+
+	sp_intc_assign_bit(hwirq, REG_INTR_TYPE, is_edge);
+	sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, is_low);
+
+	return 0;
+}
+
+static int sp_intc_get_ext_irq(int ext_num)
+{
+	void __iomem *base = ext_num ? REG_MASKED_EXT1 : REG_MASKED_EXT0;
+	u32 shift = ext_num ? GROUP_SHIFT_EXT1 : GROUP_SHIFT_EXT0;
+	u32 groups;
+	u32 pending_group;
+	u32 group;
+	u32 pending_irq;
+
+	groups = readl_relaxed(REG_INTR_GROUP);
+	pending_group = (groups >> shift) & GROUP_MASK;
+	if (!pending_group)
+		return -1;
+
+	group = fls(pending_group) - 1;
+	pending_irq = readl_relaxed(base + group * 4);
+	if (!pending_irq)
+		return -1;
+
+	return (group * 32) + fls(pending_irq) - 1;
+}
+
+static void sp_intc_handle_ext_cascaded(struct irq_desc *desc)
+{
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	int ext_num = (int)irq_desc_get_handler_data(desc);
+	int hwirq;
+
+	chained_irq_enter(chip, desc);
+
+	while ((hwirq = sp_intc_get_ext_irq(ext_num)) >= 0) {
+		if (unlikely(IS_GPIO_INT(hwirq) && TEST_STATE(hwirq, _IS_ACTIVE))) { // WORKAROUND
+			ASSIGN_STATE(hwirq, _IS_ACTIVE, false);
+			sp_intc_assign_bit(hwirq, REG_INTR_POLARITY, TEST_STATE(hwirq, _IS_LOW));
+		} else {
+			generic_handle_domain_irq(sp_intc.domain, hwirq);
+		}
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+#ifdef CONFIG_SMP
+static int sp_intc_set_affinity(struct irq_data *d, const struct cpumask *mask, bool force)
+{
+	return -EINVAL;
+}
+#endif
+
+static struct irq_chip sp_intc_chip = {
+	.name = "sp_intc",
+	.irq_ack = sp_intc_ack_irq,
+	.irq_mask = sp_intc_mask_irq,
+	.irq_unmask = sp_intc_unmask_irq,
+	.irq_set_type = sp_intc_set_type,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = sp_intc_set_affinity,
+#endif
+};
+
+static int sp_intc_irq_domain_map(struct irq_domain *domain,
+				  unsigned int irq, irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &sp_intc_chip, handle_level_irq);
+	irq_set_chip_data(irq, &sp_intc_chip);
+	irq_set_noprobe(irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops sp_intc_dm_ops = {
+	.xlate = irq_domain_xlate_twocell,
+	.map = sp_intc_irq_domain_map,
+};
+
+static int sp_intc_irq_map(struct device_node *node, int i)
+{
+	unsigned int irq;
+
+	irq = irq_of_parse_and_map(node, i);
+	if (!irq)
+		return -ENOENT;
+
+	irq_set_chained_handler_and_data(irq, sp_intc_handle_ext_cascaded, (void *)i);
+
+	return 0;
+}
+
+static int __init sp_intc_init_dt(struct device_node *node, struct device_node *parent)
+{
+	int i, ret;
+
+	sp_intc.g0 = of_iomap(node, 0);
+	if (!sp_intc.g0)
+		return -ENXIO;
+
+	sp_intc.g1 = of_iomap(node, 1);
+	if (!sp_intc.g1) {
+		ret = -ENXIO;
+		goto out_unmap0;
+	}
+
+	ret = sp_intc_irq_map(node, 0); // EXT_INT0
+	if (ret)
+		goto out_unmap1;
+
+	ret = sp_intc_irq_map(node, 1); // EXT_INT1
+	if (ret)
+		goto out_unmap1;
+
+	/* initial regs */
+	for (i = 0; i < SP_INTC_NR_GROUPS; i++) {
+		/* all mask */
+		writel_relaxed(0, REG_INTR_MASK + i * 4);
+		/* all edge */
+		writel_relaxed(~0, REG_INTR_TYPE + i * 4);
+		/* all high-active */
+		writel_relaxed(0, REG_INTR_POLARITY + i * 4);
+		/* all EXT_INT0 */
+		writel_relaxed(~0, REG_INTR_PRIORITY + i * 4);
+		/* all clear */
+		writel_relaxed(~0, REG_INTR_CLEAR + i * 4);
+	}
+
+	sp_intc.domain = irq_domain_add_linear(node, SP_INTC_NR_IRQS,
+					       &sp_intc_dm_ops, &sp_intc);
+	if (!sp_intc.domain) {
+		ret = -ENOMEM;
+		goto out_unmap1;
+	}
+
+	raw_spin_lock_init(&sp_intc.lock);
+
+	return 0;
+
+out_unmap1:
+	iounmap(sp_intc.g1);
+out_unmap0:
+	iounmap(sp_intc.g0);
+
+	return ret;
+}
+
+IRQCHIP_DECLARE(sp_intc, "sunplus,sp7021-intc", sp_intc_init_dt);
-- 
2.33.1



From jammy_huang at aspeedtech.com  Thu Jan 20 22:01:58 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Fri, 21 Jan 2022 14:01:58 +0800
Subject: [PATCH v2 3/4] media: aspeed: Correct values for detected timing
In-Reply-To: <5868782b-3383-5ee6-4111-841707ffee39@xs4all.nl>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-4-jammy_huang@aspeedtech.com>
 <5868782b-3383-5ee6-4111-841707ffee39@xs4all.nl>
Message-ID: <eda33316-b0dc-3d21-e2e1-ebde776dbd85@aspeedtech.com>

Hi Hans,

Yes, this is a weird part of our hardware.
Because it uses the rising edge of the sync to start counting, an 
additional calculation
is needed to get the exact value of the timings.

This problem was found when I was debugging the timing detection 
unstable problem.

Reards,

Jammy

On 2022/1/20 ?? 08:31, Hans Verkuil wrote:
> Hi Jammy,
>
> I just want to double check this: I assume you have tested this with the
> various polarity combinations?
>
> I ask because I've never seen this before in any other hardware. The
> sync and porch values reported by hardware are always independent from the
> polarity, so that's why I am surprised to see this.
>
> Same for the next patch (4/4).
>
> Regards,
>
> 	Hans
>
> On 12/22/21 09:21, Jammy Huang wrote:
>> Correct timing's fp/sync/bp value based on the information below.
>> It should be noticed that the calculation formula should be changed
>> per sync polarity.
>>
>> The sequence of signal: sync - backporch - video data - frontporch
>>
>> The following registers start counting from sync's rising edge:
>> 1. VR090: frame edge's left and right
>> 2. VR094: frame edge's top and bottom
>> 3. VR09C: counting from sync's rising edge to falling edge
>>
>> [Vertical timing]
>>              +--+     +-------------------+     +--+
>>              |  |     |    v i d e o      |     |  |
>>           +--+  +-----+                   +-----+  +---+
>>
>>         vsync+--+
>>     frame_top+--------+
>> frame_bottom+----------------------------+
>>
>>                    +-------------------+
>>                    |    v i d e o      |
>>        +--+  +-----+                   +-----+  +---+
>>           |  |                               |  |
>>           +--+                               +--+
>>         vsync+-------------------------------+
>>     frame_top+-----+
>> frame_bottom+-------------------------+
>>
>> [Horizontal timing]
>>              +--+     +-------------------+     +--+
>>              |  |     |    v i d e o      |     |  |
>>           +--+  +-----+                   +-----+  +---+
>>
>>         hsync+--+
>>    frame_left+--------+
>>   frame_right+----------------------------+
>>
>>                    +-------------------+
>>                    |    v i d e o      |
>>        +--+  +-----+                   +-----+  +---+
>>           |  |                               |  |
>>           +--+                               +--+
>>         hsync+-------------------------------+
>>    frame_left+-----+
>>   frame_right+-------------------------+
>>
>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>> ---
>>   v2:
>>    - Code refined per Joel's suggestion
>>    - Update commit message to have name matching variable
>> ---
>>   drivers/media/platform/aspeed-video.c | 30 ++++++++++++++++++++-------
>>   1 file changed, 22 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>> index c241038ee27c..7c50567f5ab0 100644
>> --- a/drivers/media/platform/aspeed-video.c
>> +++ b/drivers/media/platform/aspeed-video.c
>> @@ -936,7 +936,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>   	u32 src_lr_edge;
>>   	u32 src_tb_edge;
>>   	u32 sync;
>> -	u32 htotal;
>> +	u32 htotal, vtotal, vsync, hsync;
>>   	struct v4l2_bt_timings *det = &video->detected_timings;
>>   
>>   	det->width = MIN_WIDTH;
>> @@ -983,21 +983,35 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>   		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
>>   		sync = aspeed_video_read(video, VE_SYNC_STATUS);
>>   		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
>> +		vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
>> +		vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
>> +		hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
>>   
>>   		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>>   		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
>> -		det->vfrontporch = video->frame_top;
>> -		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
>> -			video->frame_bottom;
>> -		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
>> +		if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>> +			det->vbackporch = video->frame_top - vsync;
>> +			det->vfrontporch = vtotal - video->frame_bottom;
>> +			det->vsync = vsync;
>> +		} else {
>> +			det->vbackporch = video->frame_top;
>> +			det->vfrontporch = vsync - video->frame_bottom;
>> +			det->vsync = vtotal - vsync;
>> +		}
>>   		if (video->frame_top > video->frame_bottom)
>>   			continue;
>>   
>>   		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>>   		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
>> -		det->hfrontporch = video->frame_left;
>> -		det->hbackporch = htotal - video->frame_right;
>> -		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
>> +		if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>> +			det->hbackporch = video->frame_left - hsync;
>> +			det->hfrontporch = htotal - video->frame_right;
>> +			det->hsync = hsync;
>> +		} else {
>> +			det->hbackporch = video->frame_left;
>> +			det->hfrontporch = hsync - video->frame_right;
>> +			det->hsync = htotal - hsync;
>> +		}
>>   		if (video->frame_left > video->frame_right)
>>   			continue;
>>   


From qinjian at cqplus1.com  Fri Jan 21 00:12:16 2022
From: qinjian at cqplus1.com (=?utf-8?B?cWluamlhblvopoPlgaVd?=)
Date: Fri, 21 Jan 2022 08:12:16 +0000
Subject: [PATCH v8 05/10] dt-bindings: clock: Add bindings for SP7021
 clock driver
In-Reply-To: <504303c7cf92af8368dcda0cdde3b9c15a833418.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
 <504303c7cf92af8368dcda0cdde3b9c15a833418.1642751015.git.qinjian@cqplus1.com>
Message-ID: <d9af9a9e14aa4718b38047adaa9bc30b@cqplus1.com>

> Add documentation to describe Sunplus SP7021 clock driver bindings.
> 
> Signed-off-by: Qin Jian <qinjian at cqplus1.com>
> ---
> Add clocks & clock-names.
> ---

Sorry, forgot update the status of this patch

Reviewed-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Rob Herring <robh at kernel.org>


From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:03 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:03 +0100
Subject: [RFC PATCH v2 0/7] Add support for BCM2835 camera interface (unicam)
Message-ID: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>

Hello !

This patch series adds the BCM2835 CCP2/CSI2 camera interface named
unicam. This driver is already used in the out-of-tree linux-rpi
repository [1], and this work aims to support it in mainline.

The series is based on top of:
- Rebased on top of 5.16 Tomi Valkeinen's multiplexed stream work, on
  his multistream/work branch [2] which has been submitted as v10 at the
  time of this writing. The objective is to demonstrate the use of
  multiplexed streams on a real world widely used example as well as
  supporting unicam mainline.
- The "Add 12bit and 14bit luma-only formats" series [3] is partly
  applied (the Y10P format bug) the new formats are now part of this
  series.

The series is made of 7 patches:
- 1/7 and 2/7 introduce the new formats needed for the unicam driver
- 3/7 introduces dt-bindings documentation and MAINTAINERS entry
  I have tentatively assigned maintainership, is this fine ?
- 4/7 adds the driver support in media/platform
- 5/7 introduces the csi nodes in the bcm2711 file, in a disabled state
- 6/7 modifies imx219 driver to make it use the multiplexed streams API
- 7/7 is the imx219 dtsi file tested on my RPi 4b with the mainline dtb
  and not the downstream dtb anymore.

All those patches are in my tree [4].

Patch 4/7 comes from the linux-rpi work [1] with substantial
modifications:
- Removed the non-mc API which is deprecated, and not needed upstream
- Moved from one video node with two source pads (image and embedded) to
  two video nodes
- Added a subdev between the sensor and the video nodes to properly
  route the streams
- Added support for multiplexed streams API

In order to test it, one will need a RPi board and the camv2 (imx219)
sensor.  An updated v4l-utils is also needed [5] to have support for
multiplexed streams.

v4l2-compliance passes on both video devices, without streaming testing
though.

This series in its v2 does integrate the device tree nodes into the
upstream BCM2835 or BCM2711 device tree support.

The media-ctl topology is:
```
pi at raspberrypi:~ $ media-ctl -d0 -p
Media controller API version 5.16.0

Media device information
------------------------
driver          unicam
model           unicam
serial          
bus info        platform:fe801000.csi
hw revision     0x0
driver version  5.16.0

Device topology
- entity 1: unicam-subdev (3 pads, 3 links, 1 route)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
	routes:
		0/0 -> 1/0 [ACTIVE]
	pad0: Sink
		[stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
		<- "imx219 10-0010":0 [ENABLED,IMMUTABLE]
	pad1: Source
		[stream:0 fmt:UYVY8_2X8/640x480 field:none colorspace:srgb xfer:srgb ycbcr:601 quantization:lim-range]
		-> "unicam-image":0 [ENABLED,IMMUTABLE]
	pad2: Source
		-> "unicam-embedded":0 [ENABLED,IMMUTABLE]

- entity 5: imx219 10-0010 (1 pad, 1 link, 2 routes)
            type V4L2 subdev subtype Sensor flags 0
            device node name /dev/v4l-subdev1
	routes:
		0/0 -> 0/0 [ACTIVE, IMMUTABLE, SOURCE]
		0/0 -> 0/1 [ACTIVE, SOURCE]
	pad0: Source
		[stream:0 fmt:SRGGB10_1X10/3280x2464 field:none colorspace:raw
		crop.bounds:(8,8)/3280x2464
		crop:(8,8)/3280x2464]
		[stream:1 fmt:METADATA_8/16384x1 field:none
		crop.bounds:(8,8)/3280x2464
		crop:(8,8)/3280x2464]
		-> "unicam-subdev":0 [ENABLED,IMMUTABLE]

- entity 7: unicam-image (1 pad, 1 link, 0 route)
            type Node subtype V4L flags 1
            device node name /dev/video0
	pad0: Sink
		<- "unicam-subdev":1 [ENABLED,IMMUTABLE]

- entity 13: unicam-embedded (1 pad, 1 link, 0 route)
             type Node subtype V4L flags 0
             device node name /dev/video1
	pad0: Sink
		<- "unicam-subdev":2 [ENABLED,IMMUTABLE]
```

In order to properly configure the media pipeline, it is needed to call
the usual ioctls, and configure routing in order to send the embedded
data from the sensor to the "unicam-embedded" device node :

``` media=0
media-ctl -d${media} -l "'imx219 10-0010':0->'unicam-subdev':0 [1]"
media-ctl -d${media} -l "'unicam-subdev':1->'unicam-image':0 [1]"
media-ctl -d${media} -v -R "'unicam-subdev' [0/0->1/0[1],0/1->2/0[1]]"
media-ctl -d${media} -V "'imx219 10-0010':0/0
[fmt:SRGGB10_1X10/3280x2464 field:none]" v4l2-ctl -d0 --set-fmt-video
width=3280,height=2464,pixelformat='pRAA',field=none media-ctl
-d${media} -v -V "'imx219 10-0010':0/1 [fmt:METADATA_8/16384x1
field:none]" media-ctl -d${media} -p ```

Be sure to configure the routes before setting the format, as s_routing
resets the default format.

Then a frame can be capture with yavta:
`yavta --capture=1 /dev/video0 -F/tmp/test-#.bin`

Side note:
My tree [4] also includes a backport for the unicam-isp drivers, it is
then possible, and it has been successfully tested, to use libcamera and
qcam to display the camera output.

[1]: https://github.com/raspberrypi/linux/tree/rpi-5.15.y
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux.git/log/?h=multistream/work
[3]: https://patchwork.linuxtv.org/project/linux-media/list/?series=7099
[4]: https://github.com/jhautbois/linux/tree/jmh/tomba/multistream/next/work-v10-with-laurent-isp
[5]: https://github.com/tomba/v4l-utils

Jean-Michel Hautbois (7):
  media: v4l: Add V4L2-PIX-FMT-Y12P format
  media: v4l: Add V4L2-PIX-FMT-Y14P format
  media: dt-bindings: media: Add bindings for bcm2835-unicam
  media: bcm2835-unicam: Add support for for CCP2/CSI2 camera interface
  ARM: dts: bcm2711: Add unicam CSI nodes
  media: imx219: Add support for multiplexed streams
  media: bcm283x: Include the imx219 node

 .../bindings/media/brcm,bcm2835-unicam.yaml   |  103 +
 .../media/v4l/pixfmt-yuv-luma.rst             |   44 +
 MAINTAINERS                                   |    7 +
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts         |    1 +
 arch/arm/boot/dts/bcm2711.dtsi                |   31 +
 arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi     |  103 +
 drivers/media/i2c/imx219.c                    |  452 +--
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/bcm2835/Kconfig        |   21 +
 drivers/media/platform/bcm2835/Makefile       |    3 +
 .../media/platform/bcm2835/bcm2835-unicam.c   | 2678 +++++++++++++++++
 .../media/platform/bcm2835/vc4-regs-unicam.h  |  253 ++
 13 files changed, 3488 insertions(+), 211 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
 create mode 100644 drivers/media/platform/bcm2835/Kconfig
 create mode 100644 drivers/media/platform/bcm2835/Makefile
 create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
 create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h

-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:04 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:04 +0100
Subject: [RFC PATCH v2 1/7] media: v4l: Add V4L2-PIX-FMT-Y12P format
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-2-jeanmichel.hautbois@ideasonboard.com>

This is a packed grey-scale image format with a depth of 12 bits per
pixel. Two consecutive pixels are packed into 3 bytes. The first 2 bytes
contain the 8 high order bits of the pixels, and the 3rd byte contains
the 4 least significants bits of each pixel, in the same order.

Add the entry in userspace API, and document it.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 .../userspace-api/media/v4l/pixfmt-yuv-luma.rst       | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
index 8ebd58c3588f..d37ce6027095 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
@@ -92,6 +92,17 @@ are often referred to as greyscale formats.
       - ...
       - ...
 
+    * .. _V4L2-PIX-FMT-Y12P:
+
+      - ``V4L2_PIX_FMT_Y12P``
+      - 'Y12P'
+
+      - Y'\ :sub:`0`\ [11:4]
+      - Y'\ :sub:`1`\ [11:4]
+      - Y'\ :sub:`1`\ [3:0] Y'\ :sub:`0`\ [3:0]
+      - ...
+      - ...
+
     * .. _V4L2-PIX-FMT-Y14:
 
       - ``V4L2_PIX_FMT_Y14``
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:05 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:05 +0100
Subject: [RFC PATCH v2 2/7] media: v4l: Add V4L2-PIX-FMT-Y14P format
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-3-jeanmichel.hautbois@ideasonboard.com>

This is a packed grey-scale image format with a depth of 14 bits per
pixel. Every four consecutive samples are packed into seven bytes. Each
of the first four bytes contain the eight high order bits of the pixels,
and the three following bytes contains the six least significants bits
of each pixel, in the same order.

As the other formats only needed 5 bytes before, append two bytes in the
documentation array.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 .../media/v4l/pixfmt-yuv-luma.rst             | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
index d37ce6027095..c64485b03d27 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-luma.rst
@@ -36,6 +36,8 @@ are often referred to as greyscale formats.
       - Byte 2
       - Byte 3
       - Byte 4
+      - Byte 5
+      - Byte 6
 
     * .. _V4L2-PIX-FMT-GREY:
 
@@ -47,6 +49,8 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y10:
 
@@ -58,6 +62,8 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y10BPACK:
 
@@ -69,6 +75,8 @@ are often referred to as greyscale formats.
       - Y'\ :sub:`1`\ [3:0] Y'\ :sub:`2`\ [9:6]
       - Y'\ :sub:`2`\ [5:0] Y'\ :sub:`3`\ [9:8]
       - Y'\ :sub:`3`\ [7:0]
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y10P:
 
@@ -80,6 +88,8 @@ are often referred to as greyscale formats.
       - Y'\ :sub:`2`\ [9:2]
       - Y'\ :sub:`3`\ [9:2]
       - Y'\ :sub:`3`\ [1:0] Y'\ :sub:`2`\ [1:0] Y'\ :sub:`1`\ [1:0] Y'\ :sub:`0`\ [1:0]
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y12:
 
@@ -91,6 +101,8 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y12P:
 
@@ -102,6 +114,8 @@ are often referred to as greyscale formats.
       - Y'\ :sub:`1`\ [3:0] Y'\ :sub:`0`\ [3:0]
       - ...
       - ...
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y14:
 
@@ -113,6 +127,21 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
+
+    * .. _V4L2-PIX-FMT-Y14P:
+
+      - ``V4L2_PIX_FMT_Y14P``
+      - 'Y14P'
+
+      - Y'\ :sub:`0`\ [13:6]
+      - Y'\ :sub:`1`\ [13:6]
+      - Y'\ :sub:`2`\ [13:6]
+      - Y'\ :sub:`3`\ [13:6]
+      - Y'\ :sub:`1`\ [1:0] Y'\ :sub:`0`\ [5:0]
+      - Y'\ :sub:`2`\ [3:0] Y'\ :sub:`1`\ [5:2]
+      - Y'\ :sub:`3`\ [5:0] Y'\ :sub:`2`\ [5:4]
 
     * .. _V4L2-PIX-FMT-Y16:
 
@@ -124,6 +153,8 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
 
     * .. _V4L2-PIX-FMT-Y16-BE:
 
@@ -135,6 +166,8 @@ are often referred to as greyscale formats.
       - ...
       - ...
       - ...
+      - ...
+      - ...
 
 .. raw:: latex
 
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:06 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:06 +0100
Subject: [RFC PATCH v2 3/7] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-4-jeanmichel.hautbois@ideasonboard.com>

Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera
interface. Also add a MAINTAINERS entry for it.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
Dave: I assumed you were the maintainer for this file, as I based it on the
bcm2835-unicam.txt file. Are  you happy to be added directly as the
maintainer, or should this be specified as "Raspberry Pi Kernel
Maintenance <kernel-list at raspberrypi.com>"
- in v2: multiple corrections to pass the bot checking as Rob kindly
  told me.
---
 .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
 MAINTAINERS                                   |   6 +
 2 files changed, 109 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml

diff --git a/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
new file mode 100644
index 000000000000..1427514142cf
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/brcm,bcm2835-unicam.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM283x Camera Interface (Unicam)
+
+maintainers:
+  - Dave Stevenson <dave.stevenson at raspberrypi.com>
+
+description: |-
+  The Unicam block on BCM283x SoCs is the receiver for either
+  CSI-2 or CCP2 data from image sensors or similar devices.
+
+  The main platform using this SoC is the Raspberry Pi family of boards.
+  On the Pi the VideoCore firmware can also control this hardware block,
+  and driving it from two different processors will cause issues.
+  To avoid this, the firmware checks the device tree configuration
+  during boot. If it finds device tree nodes called csi0 or csi1 then
+  it will stop the firmware accessing the block, and it can then
+  safely be used via the device tree binding.
+
+properties:
+  compatible:
+    const: brcm,bcm2835-unicam
+
+  reg:
+    description:
+      physical base address and length of the register sets for the device.
+    maxItems: 1
+
+  interrupts:
+    description: the IRQ line for this Unicam instance.
+    maxItems: 1
+
+  clocks:
+    description: |-
+      list of clock specifiers, corresponding to entries in clock-names
+      property.
+
+  clock-names:
+    items:
+      - const: lp
+      - const: vpu
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: False
+
+examples:
+  - |
+    csi1: csi1 at 7e801000 {
+        compatible = "brcm,bcm2835-unicam";
+        reg = <0x7e801000 0x800>,
+              <0x7e802004 0x4>;
+        interrupts = <2 7>;
+        clocks = <&clocks BCM2835_CLOCK_CAM1>,
+                 <&firmware_clocks 4>;
+        clock-names = "lp", "vpu";
+        port {
+                csi1_ep: endpoint {
+                        remote-endpoint = <&tc358743_0>;
+                        data-lanes = <1 2>;
+                };
+        };
+    };
+
+    i2c0: i2c at 7e205000 {
+        tc358743: csi-hdmi-bridge at 0f {
+            compatible = "toshiba,tc358743";
+            reg = <0x0f>;
+            clocks = <&tc358743_clk>;
+            clock-names = "refclk";
+
+            tc358743_clk: bridge-clk {
+                    compatible = "fixed-clock";
+                    #clock-cells = <0>;
+                    clock-frequency = <27000000>;
+            };
+
+            port {
+                    tc358743_0: endpoint {
+                            remote-endpoint = <&csi1_ep>;
+                            clock-lanes = <0>;
+                            data-lanes = <1 2>;
+                            clock-noncontinuous;
+                            link-frequencies =
+                                /bits/ 64 <297000000>;
+                    };
+            };
+        };
+    };
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 33f75892f98e..07f238fd5ff9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3679,6 +3679,12 @@ F:	Documentation/media/v4l-drivers/bcm2835-isp.rst
 F:	drivers/staging/vc04_services/bcm2835-isp
 F:	include/uapi/linux/bcm2835-isp.h
 
+BROADCOM BCM2835 CAMERA DRIVER
+M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+
 BROADCOM BCM47XX MIPS ARCHITECTURE
 M:	Hauke Mehrtens <hauke at hauke-m.de>
 M:	Rafa? Mi?ecki <zajec5 at gmail.com>
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:10 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:10 +0100
Subject: [RFC PATCH v2 7/7] media: bcm283x: Include the imx219 node
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-8-jeanmichel.hautbois@ideasonboard.com>

Configure the csi1 endpoint, add the imx219 node and connect it through
the i2c mux.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
 MAINTAINERS                               |   1 +
 arch/arm/boot/dts/bcm2711-rpi-4-b.dts     |   1 +
 arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi | 102 ++++++++++++++++++++++
 3 files changed, 104 insertions(+)
 create mode 100644 arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index b17bb533e007..56544ac98d69 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3684,6 +3684,7 @@ M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+F:	arch/arm/boot/dts/bcm283x*
 F:	drivers/media/platform/bcm2835/
 
 BROADCOM BCM47XX MIPS ARCHITECTURE
diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
index 4432412044de..f7625b70fe57 100644
--- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
+++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
@@ -4,6 +4,7 @@
 #include "bcm2711-rpi.dtsi"
 #include "bcm283x-rpi-usb-peripheral.dtsi"
 #include "bcm283x-rpi-wifi-bt.dtsi"
+#include "bcm283x-rpi-imx219.dtsi"
 
 / {
 	compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
diff --git a/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi b/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
new file mode 100644
index 000000000000..f2c6a85fd731
--- /dev/null
+++ b/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/bcm2835.h>
+
+/ {
+	compatible = "brcm,bcm2835";
+
+	imx219_vdig: fixedregulator at 1 {
+		compatible = "regulator-fixed";
+		regulator-name = "imx219_vdig";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	imx219_vddl: fixedregulator at 2 {
+		compatible = "regulator-fixed";
+		regulator-name = "imx219_vddl";
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+	};
+
+	imx219_clk: imx219_clk {
+		#clock-cells = <0>;
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "24MHz-clock";
+	};
+
+	cam1_reg: cam1_reg {
+		compatible = "regulator-fixed";
+		regulator-name = "imx219_vana";
+		enable-active-high;
+		status = "okay";
+		gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
+	};
+
+	i2c0mux {
+		compatible = "i2c-mux-pinctrl";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		i2c-parent = <&i2c0>;
+
+		pinctrl-names = "i2c0", "i2c_csi_dsi";
+		pinctrl-0 = <&i2c0_gpio0>;
+		pinctrl-1 = <&i2c0_gpio44>;
+
+		i2c at 0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c at 1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			imx219: sensor at 10 {
+				compatible = "sony,imx219";
+				reg = <0x10>;
+				status = "okay";
+
+				clocks = <&imx219_clk>;
+				clock-names = "xclk";
+
+				VANA-supply = <&cam1_reg>;   /* 2.8v */
+				VDIG-supply = <&imx219_vdig>;   /* 1.8v */
+				VDDL-supply = <&imx219_vddl>;   /* 1.2v */
+
+				rotation = <0>;
+				orientation = <0>;
+
+				port {
+					imx219_0: endpoint {
+						remote-endpoint = <&csi1_ep>;
+						clock-lanes = <0>;
+						data-lanes = <1 2>;
+						clock-noncontinuous;
+						link-frequencies = /bits/ 64 <456000000>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&csi1 {
+	status="okay";
+	num-data-lanes = <2>;
+	port {
+		csi1_ep: endpoint {
+			remote-endpoint = <&imx219_0>;
+			data-lanes = <1 2>;
+			clock-lanes = <0>;
+		};
+	};
+};
+
+&i2c0 {
+	/delete-property/ pinctrl-names;
+	/delete-property/ pinctrl-0;
+};
+
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:09 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:09 +0100
Subject: [RFC PATCH v2 6/7] media: imx219: Add support for multiplexed streams
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-7-jeanmichel.hautbois@ideasonboard.com>

As of now, imx219 was not supporting anything more than one stream. Add
support for embedded data, based on linux-rpi kernel, and make it work
with multiplexed streams. We have only one source pad with two streams:
stream 0 is the image, and stream 1 is the embedded data.

Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>

---
in v2: modified the get_format_pad function as it was not correctly
propagating the format in case of sensor flips.
---
 drivers/media/i2c/imx219.c | 452 ++++++++++++++++++++-----------------
 1 file changed, 241 insertions(+), 211 deletions(-)

diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index e10af3f74b38..d73fe6b8b2fb 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -118,6 +118,16 @@
 #define IMX219_PIXEL_ARRAY_WIDTH	3280U
 #define IMX219_PIXEL_ARRAY_HEIGHT	2464U
 
+/* Embedded metadata stream structure */
+#define IMX219_EMBEDDED_LINE_WIDTH 16384
+#define IMX219_NUM_EMBEDDED_LINES 1
+
+enum pad_types {
+	IMAGE_PAD,
+	METADATA_PAD,
+	NUM_PADS
+};
+
 struct imx219_reg {
 	u16 address;
 	u8 val;
@@ -429,7 +439,7 @@ static const char * const imx219_supply_name[] = {
  * - v flip
  * - h&v flips
  */
-static const u32 codes[] = {
+static const u32 imx219_mbus_formats[] = {
 	MEDIA_BUS_FMT_SRGGB10_1X10,
 	MEDIA_BUS_FMT_SGRBG10_1X10,
 	MEDIA_BUS_FMT_SGBRG10_1X10,
@@ -655,62 +665,17 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
 
 	lockdep_assert_held(&imx219->mutex);
 
-	for (i = 0; i < ARRAY_SIZE(codes); i++)
-		if (codes[i] == code)
+	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); i++)
+		if (imx219_mbus_formats[i] == code)
 			break;
 
-	if (i >= ARRAY_SIZE(codes))
+	if (i >= ARRAY_SIZE(imx219_mbus_formats))
 		i = 0;
 
 	i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
 	    (imx219->hflip->val ? 1 : 0);
 
-	return codes[i];
-}
-
-static void imx219_set_default_format(struct imx219 *imx219)
-{
-	struct v4l2_mbus_framefmt *fmt;
-
-	fmt = &imx219->fmt;
-	fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
-	fmt->colorspace = V4L2_COLORSPACE_SRGB;
-	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
-	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-							  fmt->colorspace,
-							  fmt->ycbcr_enc);
-	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
-	fmt->width = supported_modes[0].width;
-	fmt->height = supported_modes[0].height;
-	fmt->field = V4L2_FIELD_NONE;
-}
-
-static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
-{
-	struct imx219 *imx219 = to_imx219(sd);
-	struct v4l2_mbus_framefmt *try_fmt =
-		v4l2_subdev_get_try_format(sd, fh->state, 0);
-	struct v4l2_rect *try_crop;
-
-	mutex_lock(&imx219->mutex);
-
-	/* Initialize try_fmt */
-	try_fmt->width = supported_modes[0].width;
-	try_fmt->height = supported_modes[0].height;
-	try_fmt->code = imx219_get_format_code(imx219,
-					       MEDIA_BUS_FMT_SRGGB10_1X10);
-	try_fmt->field = V4L2_FIELD_NONE;
-
-	/* Initialize try_crop rectangle. */
-	try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
-	try_crop->top = IMX219_PIXEL_ARRAY_TOP;
-	try_crop->left = IMX219_PIXEL_ARRAY_LEFT;
-	try_crop->width = IMX219_PIXEL_ARRAY_WIDTH;
-	try_crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
-
-	mutex_unlock(&imx219->mutex);
-
-	return 0;
+	return imx219_mbus_formats[i];
 }
 
 static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
@@ -802,98 +767,148 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
 	.s_ctrl = imx219_set_ctrl,
 };
 
-static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
-				 struct v4l2_subdev_state *sd_state,
-				 struct v4l2_subdev_mbus_code_enum *code)
+static void imx219_init_formats(struct v4l2_subdev_state *state)
 {
-	struct imx219 *imx219 = to_imx219(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	format = v4l2_state_get_stream_format(state, 0, 0);
+	format->code = imx219_mbus_formats[0];
+	format->width = supported_modes[0].width;
+	format->height = supported_modes[0].height;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_RAW;
+
+	if (state->routing.routes[1].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
+		format = v4l2_state_get_stream_format(state, 0, 1);
+		format->code = MEDIA_BUS_FMT_METADATA_8;
+		format->width = IMX219_EMBEDDED_LINE_WIDTH;
+		format->height = 1;
+		format->field = V4L2_FIELD_NONE;
+		format->colorspace = V4L2_COLORSPACE_DEFAULT;
+	}
+}
 
-	if (code->index >= (ARRAY_SIZE(codes) / 4))
-		return -EINVAL;
+static int _imx219_set_routing(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.source_pad = 0,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_IMMUTABLE |
+				 V4L2_SUBDEV_ROUTE_FL_SOURCE |
+				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+		{
+			.source_pad = 0,
+			.source_stream = 1,
+			.flags = V4L2_SUBDEV_ROUTE_FL_SOURCE |
+				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		}
+	};
 
-	mutex_lock(&imx219->mutex);
-	code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
-	mutex_unlock(&imx219->mutex);
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	int ret;
+
+	ret = v4l2_subdev_set_routing(sd, state, &routing);
+	if (ret)
+		return ret;
+
+	imx219_init_formats(state);
 
 	return 0;
 }
 
-static int imx219_enum_frame_size(struct v4l2_subdev *sd,
-				  struct v4l2_subdev_state *sd_state,
-				  struct v4l2_subdev_frame_size_enum *fse)
+static int imx219_set_routing(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *state,
+			      enum v4l2_subdev_format_whence which,
+			      struct v4l2_subdev_krouting *routing)
 {
-	struct imx219 *imx219 = to_imx219(sd);
-	u32 code;
+	int ret;
 
-	if (fse->index >= ARRAY_SIZE(supported_modes))
+	if (routing->num_routes == 0 || routing->num_routes > 2)
 		return -EINVAL;
 
-	mutex_lock(&imx219->mutex);
-	code = imx219_get_format_code(imx219, fse->code);
-	mutex_unlock(&imx219->mutex);
-	if (fse->code != code)
-		return -EINVAL;
+	v4l2_subdev_lock_state(state);
 
-	fse->min_width = supported_modes[fse->index].width;
-	fse->max_width = fse->min_width;
-	fse->min_height = supported_modes[fse->index].height;
-	fse->max_height = fse->min_height;
+	ret = _imx219_set_routing(sd, state);
 
-	return 0;
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
 }
 
-static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
+static int imx219_init_cfg(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_state *state)
 {
-	fmt->colorspace = V4L2_COLORSPACE_SRGB;
-	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
-	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
-							  fmt->colorspace,
-							  fmt->ycbcr_enc);
-	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
+	int ret;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = _imx219_set_routing(sd, state);
+
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
 }
 
-static void imx219_update_pad_format(struct imx219 *imx219,
-				     const struct imx219_mode *mode,
-				     struct v4l2_subdev_format *fmt)
+static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_state *sd_state,
+				 struct v4l2_subdev_mbus_code_enum *code)
 {
-	fmt->format.width = mode->width;
-	fmt->format.height = mode->height;
-	fmt->format.field = V4L2_FIELD_NONE;
-	imx219_reset_colorspace(&fmt->format);
+	if (code->index >= ARRAY_SIZE(imx219_mbus_formats))
+		return -EINVAL;
+
+	code->code = imx219_mbus_formats[code->index];
+
+	return 0;
 }
 
-static int __imx219_get_pad_format(struct imx219 *imx219,
-				   struct v4l2_subdev_state *sd_state,
-				   struct v4l2_subdev_format *fmt)
+static int imx219_enum_frame_size(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *sd_state,
+				  struct v4l2_subdev_frame_size_enum *fse)
 {
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		struct v4l2_mbus_framefmt *try_fmt =
-			v4l2_subdev_get_try_format(&imx219->sd, sd_state,
-						   fmt->pad);
-		/* update the code which could change due to vflip or hflip: */
-		try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
-		fmt->format = *try_fmt;
+	unsigned int i;
+
+	if (fse->stream == 0) {
+		for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
+			if (imx219_mbus_formats[i] == fse->code)
+				break;
+		}
+
+		if (i == ARRAY_SIZE(imx219_mbus_formats))
+			return -EINVAL;
+
+		if (fse->index >= ARRAY_SIZE(supported_modes))
+			return -EINVAL;
+
+		fse->min_width  = supported_modes[fse->index].width;
+		fse->max_width  = fse->min_width;
+		fse->max_height = supported_modes[fse->index].height;
+		fse->min_height = fse->max_height;
 	} else {
-		imx219_update_pad_format(imx219, imx219->mode, fmt);
-		fmt->format.code = imx219_get_format_code(imx219,
-							  imx219->fmt.code);
+		if (fse->code != MEDIA_BUS_FMT_METADATA_8)
+			return -EINVAL;
+
+		fse->min_width = IMX219_EMBEDDED_LINE_WIDTH;
+		fse->max_width = fse->min_width;
+		fse->min_height = IMX219_NUM_EMBEDDED_LINES;
+		fse->max_height = fse->min_height;
 	}
 
 	return 0;
 }
 
-static int imx219_get_pad_format(struct v4l2_subdev *sd,
-				 struct v4l2_subdev_state *sd_state,
-				 struct v4l2_subdev_format *fmt)
+static void imx219_update_metadata_pad_format(struct v4l2_subdev_format *fmt)
 {
-	struct imx219 *imx219 = to_imx219(sd);
-	int ret;
-
-	mutex_lock(&imx219->mutex);
-	ret = __imx219_get_pad_format(imx219, sd_state, fmt);
-	mutex_unlock(&imx219->mutex);
-
-	return ret;
+	fmt->format.width = IMX219_EMBEDDED_LINE_WIDTH;
+	fmt->format.height = IMX219_NUM_EMBEDDED_LINES;
+	fmt->format.code = MEDIA_BUS_FMT_METADATA_8;
+	fmt->format.field = V4L2_FIELD_NONE;
 }
 
 static int imx219_set_pad_format(struct v4l2_subdev *sd,
@@ -901,82 +916,91 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
 				 struct v4l2_subdev_format *fmt)
 {
 	struct imx219 *imx219 = to_imx219(sd);
+	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
 	const struct imx219_mode *mode;
-	struct v4l2_mbus_framefmt *framefmt;
-	int exposure_max, exposure_def, hblank;
+	struct v4l2_mbus_framefmt *format;
 	unsigned int i;
+	int ret = 0;
+	int exposure_max, exposure_def, hblank;
 
-	mutex_lock(&imx219->mutex);
+	if (fmt->pad != 0) {
+		dev_err(&client->dev, "%s Could not get pad %d\n", __func__,
+			fmt->pad);
+		return -EINVAL;
+	}
 
-	for (i = 0; i < ARRAY_SIZE(codes); i++)
-		if (codes[i] == fmt->format.code)
+	if (fmt->stream == 1) {
+		/* Only one embedded data mode is supported */
+		imx219_update_metadata_pad_format(fmt);
+		return 0;
+	}
+
+	if (fmt->stream != 0)
+		return -EINVAL;
+
+	/*
+	 * Validate the media bus code, defaulting to the first one if the
+	 * requested code isn't supported.
+	 */
+	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
+		if (imx219_mbus_formats[i] == fmt->format.code)
 			break;
-	if (i >= ARRAY_SIZE(codes))
-		i = 0;
+	}
 
-	/* Bayer order varies with flips */
-	fmt->format.code = imx219_get_format_code(imx219, codes[i]);
+	if (i >= ARRAY_SIZE(imx219_mbus_formats))
+		i = 0;
 
 	mode = v4l2_find_nearest_size(supported_modes,
 				      ARRAY_SIZE(supported_modes),
 				      width, height,
-				      fmt->format.width, fmt->format.height);
-	imx219_update_pad_format(imx219, mode, fmt);
-	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
-		*framefmt = fmt->format;
-	} else if (imx219->mode != mode ||
-		   imx219->fmt.code != fmt->format.code) {
-		imx219->fmt = fmt->format;
-		imx219->mode = mode;
-		/* Update limits and set FPS to default */
-		__v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
-					 IMX219_VTS_MAX - mode->height, 1,
-					 mode->vts_def - mode->height);
-		__v4l2_ctrl_s_ctrl(imx219->vblank,
-				   mode->vts_def - mode->height);
-		/* Update max exposure while meeting expected vblanking */
-		exposure_max = mode->vts_def - 4;
-		exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
-			exposure_max : IMX219_EXPOSURE_DEFAULT;
-		__v4l2_ctrl_modify_range(imx219->exposure,
-					 imx219->exposure->minimum,
-					 exposure_max, imx219->exposure->step,
-					 exposure_def);
-		/*
-		 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
-		 * depends on mode->width only, and is not changeble in any
-		 * way other than changing the mode.
-		 */
-		hblank = IMX219_PPL_DEFAULT - mode->width;
-		__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
-					 hblank);
-	}
+				      fmt->format.width,
+				      fmt->format.height);
 
-	mutex_unlock(&imx219->mutex);
+	v4l2_subdev_lock_state(sd_state);
 
-	return 0;
-}
+	/* Update the stored format and return it. */
+	format = v4l2_state_get_stream_format(sd_state, fmt->pad, fmt->stream);
 
-static int imx219_set_framefmt(struct imx219 *imx219)
-{
-	switch (imx219->fmt.code) {
-	case MEDIA_BUS_FMT_SRGGB8_1X8:
-	case MEDIA_BUS_FMT_SGRBG8_1X8:
-	case MEDIA_BUS_FMT_SGBRG8_1X8:
-	case MEDIA_BUS_FMT_SBGGR8_1X8:
-		return imx219_write_regs(imx219, raw8_framefmt_regs,
-					ARRAY_SIZE(raw8_framefmt_regs));
-
-	case MEDIA_BUS_FMT_SRGGB10_1X10:
-	case MEDIA_BUS_FMT_SGRBG10_1X10:
-	case MEDIA_BUS_FMT_SGBRG10_1X10:
-	case MEDIA_BUS_FMT_SBGGR10_1X10:
-		return imx219_write_regs(imx219, raw10_framefmt_regs,
-					ARRAY_SIZE(raw10_framefmt_regs));
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && imx219->streaming) {
+		ret = -EBUSY;
+		goto done;
 	}
 
-	return -EINVAL;
+	/* Bayer order varies with flips */
+	fmt->format.code = imx219_get_format_code(imx219, imx219_mbus_formats[i]);
+	fmt->format = *format;
+
+	/* Update limits and set FPS to default */
+	__v4l2_ctrl_modify_range(imx219->vblank,
+				 IMX219_VBLANK_MIN,
+				 IMX219_VTS_MAX - mode->height,
+				 1,
+				 mode->vts_def - mode->height);
+	__v4l2_ctrl_s_ctrl(imx219->vblank, mode->vts_def - mode->height);
+	/*
+	 * Update max exposure while meeting
+	 * expected vblanking
+	 */
+	exposure_max = mode->vts_def - 4;
+	exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
+			exposure_max : IMX219_EXPOSURE_DEFAULT;
+	__v4l2_ctrl_modify_range(imx219->exposure,
+				 imx219->exposure->minimum,
+				 exposure_max,
+				 imx219->exposure->step,
+				 exposure_def);
+	/*
+	 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so
+	 * hblank depends on mode->width only, and is not
+	 * changeble in any way other than changing the mode.
+	 */
+	hblank = IMX219_PPL_DEFAULT - mode->width;
+	__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, hblank);
+
+done:
+	v4l2_subdev_unlock_state(sd_state);
+
+	return ret;
 }
 
 static const struct v4l2_rect *
@@ -1037,9 +1061,11 @@ static int imx219_start_streaming(struct imx219 *imx219)
 	const struct imx219_reg_list *reg_list;
 	int ret;
 
-	ret = pm_runtime_resume_and_get(&client->dev);
-	if (ret < 0)
+	ret = pm_runtime_get_sync(&client->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&client->dev);
 		return ret;
+	}
 
 	/* Apply default values of current mode */
 	reg_list = &imx219->mode->reg_list;
@@ -1049,13 +1075,6 @@ static int imx219_start_streaming(struct imx219 *imx219)
 		goto err_rpm_put;
 	}
 
-	ret = imx219_set_framefmt(imx219);
-	if (ret) {
-		dev_err(&client->dev, "%s failed to set frame format: %d\n",
-			__func__, ret);
-		goto err_rpm_put;
-	}
-
 	/* Apply customized values from user */
 	ret =  __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
 	if (ret)
@@ -1133,21 +1152,22 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
 /* Power/clock management functions */
 static int imx219_power_on(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 	int ret;
 
 	ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
 				    imx219->supplies);
 	if (ret) {
-		dev_err(dev, "%s: failed to enable regulators\n",
+		dev_err(&client->dev, "%s: failed to enable regulators\n",
 			__func__);
 		return ret;
 	}
 
 	ret = clk_prepare_enable(imx219->xclk);
 	if (ret) {
-		dev_err(dev, "%s: failed to enable clock\n",
+		dev_err(&client->dev, "%s: failed to enable clock\n",
 			__func__);
 		goto reg_off;
 	}
@@ -1166,7 +1186,8 @@ static int imx219_power_on(struct device *dev)
 
 static int imx219_power_off(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 
 	gpiod_set_value_cansleep(imx219->reset_gpio, 0);
@@ -1178,7 +1199,8 @@ static int imx219_power_off(struct device *dev)
 
 static int __maybe_unused imx219_suspend(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 
 	if (imx219->streaming)
@@ -1189,7 +1211,8 @@ static int __maybe_unused imx219_suspend(struct device *dev)
 
 static int __maybe_unused imx219_resume(struct device *dev)
 {
-	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct imx219 *imx219 = to_imx219(sd);
 	int ret;
 
@@ -1255,11 +1278,13 @@ static const struct v4l2_subdev_video_ops imx219_video_ops = {
 };
 
 static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
-	.enum_mbus_code = imx219_enum_mbus_code,
-	.get_fmt = imx219_get_pad_format,
-	.set_fmt = imx219_set_pad_format,
-	.get_selection = imx219_get_selection,
-	.enum_frame_size = imx219_enum_frame_size,
+	.init_cfg		= imx219_init_cfg,
+	.enum_mbus_code		= imx219_enum_mbus_code,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= imx219_set_pad_format,
+	.get_selection		= imx219_get_selection,
+	.set_routing		= imx219_set_routing,
+	.enum_frame_size	= imx219_enum_frame_size,
 };
 
 static const struct v4l2_subdev_ops imx219_subdev_ops = {
@@ -1268,10 +1293,6 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = {
 	.pad = &imx219_pad_ops,
 };
 
-static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
-	.open = imx219_open,
-};
-
 /* Initialize control handlers */
 static int imx219_init_controls(struct imx219 *imx219)
 {
@@ -1446,6 +1467,7 @@ static int imx219_check_hwcfg(struct device *dev)
 static int imx219_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
+	struct v4l2_subdev *sd;
 	struct imx219 *imx219;
 	int ret;
 
@@ -1453,7 +1475,8 @@ static int imx219_probe(struct i2c_client *client)
 	if (!imx219)
 		return -ENOMEM;
 
-	v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
+	sd = &imx219->sd;
+	v4l2_i2c_subdev_init(sd, client, &imx219_subdev_ops);
 
 	/* Check the hardware configuration in device tree */
 	if (imx219_check_hwcfg(dev))
@@ -1520,27 +1543,29 @@ static int imx219_probe(struct i2c_client *client)
 		goto error_power_off;
 
 	/* Initialize subdev */
-	imx219->sd.internal_ops = &imx219_internal_ops;
-	imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
-			    V4L2_SUBDEV_FL_HAS_EVENTS;
-	imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS |
+		     V4L2_SUBDEV_FL_MULTIPLEXED;
 
-	/* Initialize source pad */
+	/* Initialize the media entity. */
 	imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
-
-	/* Initialize default format */
-	imx219_set_default_format(imx219);
-
-	ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
+	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
+	ret = media_entity_pads_init(&sd->entity, 1, &imx219->pad);
 	if (ret) {
 		dev_err(dev, "failed to init entity pads: %d\n", ret);
 		goto error_handler_free;
 	}
 
-	ret = v4l2_async_register_subdev_sensor(&imx219->sd);
+	ret = v4l2_subdev_init_finalize(sd);
+	if (ret) {
+		dev_err(dev, "failed to finalize sensor init: %d\n", ret);
+		goto error_media_entity;
+	}
+
+	ret = v4l2_async_register_subdev_sensor(sd);
 	if (ret < 0) {
 		dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
-		goto error_media_entity;
+		goto error_free_state;
 	}
 
 	/* Enable runtime PM and turn off the device */
@@ -1550,6 +1575,8 @@ static int imx219_probe(struct i2c_client *client)
 
 	return 0;
 
+error_free_state:
+	v4l2_subdev_cleanup(sd);
 error_media_entity:
 	media_entity_cleanup(&imx219->sd.entity);
 
@@ -1568,6 +1595,9 @@ static int imx219_remove(struct i2c_client *client)
 	struct imx219 *imx219 = to_imx219(sd);
 
 	v4l2_async_unregister_subdev(sd);
+
+	v4l2_subdev_cleanup(sd);
+
 	media_entity_cleanup(&sd->entity);
 	imx219_free_controls(imx219);
 
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:08 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:08 +0100
Subject: [RFC PATCH v2 5/7] ARM: dts: bcm2711: Add unicam CSI nodes
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-6-jeanmichel.hautbois@ideasonboard.com>

Add both MIPI CSI-2 nodes in the core bcm2711 tree. Use the 3-cells
interrupt declaration, corresponding clocks and default as disabled.

Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
---
 arch/arm/boot/dts/bcm2711.dtsi | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
index dff18fc9a906..077141df7024 100644
--- a/arch/arm/boot/dts/bcm2711.dtsi
+++ b/arch/arm/boot/dts/bcm2711.dtsi
@@ -3,6 +3,7 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/soc/bcm2835-pm.h>
+#include <dt-bindings/power/raspberrypi-power.h>
 
 / {
 	compatible = "brcm,bcm2711";
@@ -293,6 +294,36 @@ hvs: hvs at 7e400000 {
 			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		csi0: csi1 at 7e800000 {
+			compatible = "brcm,bcm2835-unicam";
+			reg = <0x7e800000 0x800>,
+			      <0x7e802000 0x4>;
+			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clocks BCM2835_CLOCK_CAM0>,
+				 <&firmware_clocks 4>;
+			clock-names = "lp", "vpu";
+			power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#clock-cells = <1>;
+			status="disabled";
+		};
+
+		csi1: csi1 at 7e801000 {
+			compatible = "brcm,bcm2835-unicam";
+			reg = <0x7e801000 0x800>,
+			      <0x7e802004 0x4>;
+			interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clocks BCM2835_CLOCK_CAM1>,
+				 <&firmware_clocks 4>;
+			clock-names = "lp", "vpu";
+			power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			#clock-cells = <1>;
+			status="disabled";
+		};
+
 		pixelvalve3: pixelvalve at 7ec12000 {
 			compatible = "brcm,bcm2711-pixelvalve3";
 			reg = <0x7ec12000 0x100>;
-- 
2.32.0



From jeanmichel.hautbois at ideasonboard.com  Fri Jan 21 00:18:07 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Fri, 21 Jan 2022 09:18:07 +0100
Subject: [RFC PATCH v2 4/7] media: bcm2835-unicam: Add support for for
 CCP2/CSI2 camera interface
In-Reply-To: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <20220121081810.155500-5-jeanmichel.hautbois@ideasonboard.com>

Add driver for the Unicam camera receiver block on BCM283x processors.
It is represented as two video device nodes: unicam-image and
unicam-embedded which are connected to an internal subdev (named
unicam-subdev) in order to manage streams routing.

Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>

---
in v2: Remove the unicam_{info,debug,error} macros and use
dev_dbg/dev_err instead.
---
 MAINTAINERS                                   |    1 +
 drivers/media/platform/Kconfig                |    1 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/bcm2835/Kconfig        |   21 +
 drivers/media/platform/bcm2835/Makefile       |    3 +
 .../media/platform/bcm2835/bcm2835-unicam.c   | 2678 +++++++++++++++++
 .../media/platform/bcm2835/vc4-regs-unicam.h  |  253 ++
 7 files changed, 2959 insertions(+)
 create mode 100644 drivers/media/platform/bcm2835/Kconfig
 create mode 100644 drivers/media/platform/bcm2835/Makefile
 create mode 100644 drivers/media/platform/bcm2835/bcm2835-unicam.c
 create mode 100644 drivers/media/platform/bcm2835/vc4-regs-unicam.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 07f238fd5ff9..b17bb533e007 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3684,6 +3684,7 @@ M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
 L:	linux-media at vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
+F:	drivers/media/platform/bcm2835/
 
 BROADCOM BCM47XX MIPS ARCHITECTURE
 M:	Hauke Mehrtens <hauke at hauke-m.de>
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 9fbdba0fd1e7..033b0358fbb8 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -170,6 +170,7 @@ source "drivers/media/platform/am437x/Kconfig"
 source "drivers/media/platform/xilinx/Kconfig"
 source "drivers/media/platform/rcar-vin/Kconfig"
 source "drivers/media/platform/atmel/Kconfig"
+source "drivers/media/platform/bcm2835/Kconfig"
 source "drivers/media/platform/sunxi/Kconfig"
 
 config VIDEO_TI_CAL
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 19bcbced7382..689e64857db1 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -85,6 +85,8 @@ obj-$(CONFIG_VIDEO_QCOM_CAMSS)		+= qcom/camss/
 
 obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 
+obj-y					+= bcm2835/
+
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
diff --git a/drivers/media/platform/bcm2835/Kconfig b/drivers/media/platform/bcm2835/Kconfig
new file mode 100644
index 000000000000..bd1370199650
--- /dev/null
+++ b/drivers/media/platform/bcm2835/Kconfig
@@ -0,0 +1,21 @@
+# Broadcom VideoCore4 V4L2 camera support
+
+config VIDEO_BCM2835_UNICAM
+	tristate "Broadcom BCM283x/BCM271x Unicam video capture driver"
+	depends on VIDEO_V4L2
+	depends on ARCH_BCM2835 || COMPILE_TEST
+	select VIDEO_V4L2_SUBDEV_API
+	select MEDIA_CONTROLLER
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_FWNODE
+	help
+	  Say Y here to enable support for the BCM283x/BCM271x CSI-2 receiver.
+	  This is a V4L2 driver that controls the CSI-2 receiver directly,
+	  independently from the VC4 firmware.
+	  This driver is mutually exclusive with the use of bcm2835-camera. The
+	  firmware will disable all access to the peripheral from within the
+	  firmware if it finds a DT node using it, and bcm2835-camera will
+	  therefore fail to probe.
+
+	  To compile this driver as a module, choose M here. The module will be
+	  called bcm2835-unicam.
diff --git a/drivers/media/platform/bcm2835/Makefile b/drivers/media/platform/bcm2835/Makefile
new file mode 100644
index 000000000000..a98aba03598a
--- /dev/null
+++ b/drivers/media/platform/bcm2835/Makefile
@@ -0,0 +1,3 @@
+# Makefile for BCM2835 Unicam driver
+
+obj-$(CONFIG_VIDEO_BCM2835_UNICAM) += bcm2835-unicam.o
diff --git a/drivers/media/platform/bcm2835/bcm2835-unicam.c b/drivers/media/platform/bcm2835/bcm2835-unicam.c
new file mode 100644
index 000000000000..7636496be00a
--- /dev/null
+++ b/drivers/media/platform/bcm2835/bcm2835-unicam.c
@@ -0,0 +1,2678 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * BCM283x / BCM271x Unicam Capture Driver
+ *
+ * Copyright (C) 2017-2020 - Raspberry Pi (Trading) Ltd.
+ *
+ * Dave Stevenson <dave.stevenson at raspberrypi.com>
+ *
+ * Based on TI am437x driver by
+ *   Benoit Parrot <bparrot at ti.com>
+ *   Lad, Prabhakar <prabhakar.csengg at gmail.com>
+ *
+ * and TI CAL camera interface driver by
+ *    Benoit Parrot <bparrot at ti.com>
+ *
+ *
+ * There are two camera drivers in the kernel for BCM283x - this one
+ * and bcm2835-camera (currently in staging).
+ *
+ * This driver directly controls the Unicam peripheral - there is no
+ * involvement with the VideoCore firmware. Unicam receives CSI-2 or
+ * CCP2 data and writes it into SDRAM.
+ * The only potential processing options are to repack Bayer data into an
+ * alternate format, and applying windowing.
+ * The repacking does not shift the data, so can repack V4L2_PIX_FMT_Sxxxx10P
+ * to V4L2_PIX_FMT_Sxxxx10, or V4L2_PIX_FMT_Sxxxx12P to V4L2_PIX_FMT_Sxxxx12,
+ * but not generically up to V4L2_PIX_FMT_Sxxxx16. The driver will add both
+ * formats where the relevant formats are defined, and will automatically
+ * configure the repacking as required.
+ * Support for windowing may be added later.
+ *
+ * It should be possible to connect this driver to any sensor with a
+ * suitable output interface and V4L2 subdevice driver.
+ *
+ * bcm2835-camera uses the VideoCore firmware to control the sensor,
+ * Unicam, ISP, and all tuner control loops. Fully processed frames are
+ * delivered to the driver by the firmware. It only has sensor drivers
+ * for Omnivision OV5647, and Sony IMX219 sensors.
+ *
+ * The two drivers are mutually exclusive for the same Unicam instance.
+ * The VideoCore firmware checks the device tree configuration during boot.
+ * If it finds device tree nodes called csi0 or csi1 it will block the
+ * firmware from accessing the peripheral, and bcm2835-camera will
+ * not be able to stream data.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_graph.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-dv-timings.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-fwnode.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include <media/v4l2-async.h>
+#define v4l2_async_nf_add_subdev __v4l2_async_nf_add_subdev
+
+#include "vc4-regs-unicam.h"
+
+#define UNICAM_MODULE_NAME	"unicam"
+#define UNICAM_VERSION		"0.1.0"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-3");
+
+/*
+ * Unicam must request a minimum of 250Mhz from the VPU clock.
+ * Otherwise the input FIFOs overrun and cause image corruption.
+ */
+#define MIN_VPU_CLOCK_RATE (250 * 1000 * 1000)
+/*
+ * To protect against a dodgy sensor driver never returning an error from
+ * enum_mbus_code, set a maximum index value to be used.
+ */
+#define MAX_ENUM_MBUS_CODE	128
+
+/*
+ * Stride is a 16 bit register, but also has to be a multiple of 32.
+ */
+#define BPL_ALIGNMENT		32
+#define MAX_BYTESPERLINE	((1 << 16) - BPL_ALIGNMENT)
+/*
+ * Max width is therefore determined by the max stride divided by
+ * the number of bits per pixel. Take 32bpp as a
+ * worst case.
+ * No imposed limit on the height, so adopt a square image for want
+ * of anything better.
+ */
+#define MAX_WIDTH		(MAX_BYTESPERLINE / 4)
+#define MAX_HEIGHT		MAX_WIDTH
+/* Define a nominal minimum image size */
+#define MIN_WIDTH		16
+#define MIN_HEIGHT		16
+/* Default size of the embedded buffer */
+#define UNICAM_EMBEDDED_SIZE	16384
+
+/*
+ * Size of the dummy buffer. Can be any size really, but the DMA
+ * allocation works in units of page sizes.
+ */
+#define DUMMY_BUF_SIZE		(PAGE_SIZE)
+
+#define UNICAM_SD_PAD_SINK		0
+#define UNICAM_SD_PAD_FIRST_SOURCE	1
+#define UNICAM_SD_NUM_SOURCE_PADS	2
+#define UNICAM_SD_NUM_PADS		(1 + UNICAM_SD_NUM_SOURCE_PADS)
+
+static inline bool unicam_sd_pad_is_sink(u32 pad)
+{
+	/* Camera RX has 1 sink pad, and N source pads */
+	return pad == 0;
+}
+
+static inline bool unicam_sd_pad_is_source(u32 pad)
+{
+	/* Camera RX has 1 sink pad, and N source pads */
+	return pad >= UNICAM_SD_PAD_FIRST_SOURCE &&
+	       pad <= UNICAM_SD_NUM_SOURCE_PADS;
+}
+
+enum node_types {
+	IMAGE_NODE,
+	METADATA_NODE,
+	MAX_NODES
+};
+
+#define MASK_CS_DEFAULT		BIT(V4L2_COLORSPACE_DEFAULT)
+#define MASK_CS_SMPTE170M	BIT(V4L2_COLORSPACE_SMPTE170M)
+#define MASK_CS_SMPTE240M	BIT(V4L2_COLORSPACE_SMPTE240M)
+#define MASK_CS_REC709		BIT(V4L2_COLORSPACE_REC709)
+#define MASK_CS_BT878		BIT(V4L2_COLORSPACE_BT878)
+#define MASK_CS_470_M		BIT(V4L2_COLORSPACE_470_SYSTEM_M)
+#define MASK_CS_470_BG		BIT(V4L2_COLORSPACE_470_SYSTEM_BG)
+#define MASK_CS_JPEG		BIT(V4L2_COLORSPACE_JPEG)
+#define MASK_CS_SRGB		BIT(V4L2_COLORSPACE_SRGB)
+#define MASK_CS_OPRGB		BIT(V4L2_COLORSPACE_OPRGB)
+#define MASK_CS_BT2020		BIT(V4L2_COLORSPACE_BT2020)
+#define MASK_CS_RAW		BIT(V4L2_COLORSPACE_RAW)
+#define MASK_CS_DCI_P3		BIT(V4L2_COLORSPACE_DCI_P3)
+
+#define MAX_COLORSPACE		32
+
+/*
+ * struct unicam_fmt - Unicam media bus format information
+ * @pixelformat: V4L2 pixel format FCC identifier. 0 if n/a.
+ * @repacked_fourcc: V4L2 pixel format FCC identifier if the data is expanded
+ * out to 16bpp. 0 if n/a.
+ * @code: V4L2 media bus format code.
+ * @depth: Bits per pixel as delivered from the source.
+ * @csi_dt: CSI data type.
+ * @valid_colorspaces: Bitmask of valid colorspaces so that the Media Controller
+ *		centric try_fmt can validate the colorspace and pass
+ *		v4l2-compliance.
+ * @check_variants: Flag to denote that there are multiple mediabus formats
+ *		still in the list that could match this V4L2 format.
+ * @mc_skip: Media Controller shouldn't list this format via ENUM_FMT as it is
+ *		a duplicate of an earlier format.
+ * @metadata_fmt: This format only applies to the metadata pad.
+ */
+struct unicam_fmt {
+	u32	fourcc;
+	u32	repacked_fourcc;
+	u32	code;
+	u8	depth;
+	u8	csi_dt;
+	u32	valid_colorspaces;
+	u8	check_variants:1;
+	u8	mc_skip:1;
+	u8	metadata_fmt:1;
+};
+
+static const struct unicam_fmt formats[] = {
+	/* YUV Formats */
+	{
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.code		= MEDIA_BUS_FMT_YUYV8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.code		= MEDIA_BUS_FMT_UYVY8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.code		= MEDIA_BUS_FMT_YVYU8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.code		= MEDIA_BUS_FMT_VYUY8_2X8,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.check_variants = 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YUYV,
+		.code		= MEDIA_BUS_FMT_YUYV8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_UYVY,
+		.code		= MEDIA_BUS_FMT_UYVY8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_YVYU,
+		.code		= MEDIA_BUS_FMT_YVYU8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_VYUY,
+		.code		= MEDIA_BUS_FMT_VYUY8_1X16,
+		.depth		= 16,
+		.csi_dt		= 0x1e,
+		.mc_skip	= 1,
+		.valid_colorspaces = MASK_CS_SMPTE170M | MASK_CS_REC709 |
+				     MASK_CS_JPEG,
+	}, {
+	/* RGB Formats */
+		.fourcc		= V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+		.code		= MEDIA_BUS_FMT_RGB565_2X8_LE,
+		.depth		= 16,
+		.csi_dt		= 0x22,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+		.code		= MEDIA_BUS_FMT_RGB565_2X8_BE,
+		.depth		= 16,
+		.csi_dt		= 0x22,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+		.code		= MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
+		.depth		= 16,
+		.csi_dt		= 0x21,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+		.code		= MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
+		.depth		= 16,
+		.csi_dt		= 0x21,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB24, /* rgb */
+		.code		= MEDIA_BUS_FMT_RGB888_1X24,
+		.depth		= 24,
+		.csi_dt		= 0x24,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_BGR24, /* bgr */
+		.code		= MEDIA_BUS_FMT_BGR888_1X24,
+		.depth		= 24,
+		.csi_dt		= 0x24,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_RGB32, /* argb */
+		.code		= MEDIA_BUS_FMT_ARGB8888_1X32,
+		.depth		= 32,
+		.csi_dt		= 0x0,
+		.valid_colorspaces = MASK_CS_SRGB,
+	}, {
+	/* Bayer Formats */
+		.fourcc		= V4L2_PIX_FMT_SBGGR8,
+		.code		= MEDIA_BUS_FMT_SBGGR8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG8,
+		.code		= MEDIA_BUS_FMT_SGBRG8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG8,
+		.code		= MEDIA_BUS_FMT_SGRBG8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB8,
+		.code		= MEDIA_BUS_FMT_SRGGB8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR10,
+		.code		= MEDIA_BUS_FMT_SBGGR10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG10,
+		.code		= MEDIA_BUS_FMT_SGBRG10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG10,
+		.code		= MEDIA_BUS_FMT_SGRBG10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB10P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB10,
+		.code		= MEDIA_BUS_FMT_SRGGB10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR12,
+		.code		= MEDIA_BUS_FMT_SBGGR12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG12,
+		.code		= MEDIA_BUS_FMT_SGBRG12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG12,
+		.code		= MEDIA_BUS_FMT_SGRBG12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB12P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB12,
+		.code		= MEDIA_BUS_FMT_SRGGB12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SBGGR14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SBGGR14,
+		.code		= MEDIA_BUS_FMT_SBGGR14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGBRG14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGBRG14,
+		.code		= MEDIA_BUS_FMT_SGBRG14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SGRBG14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SGRBG14,
+		.code		= MEDIA_BUS_FMT_SGRBG14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_SRGGB14P,
+		.repacked_fourcc = V4L2_PIX_FMT_SRGGB14,
+		.code		= MEDIA_BUS_FMT_SRGGB14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+	/*
+	 * 16 bit Bayer formats could be supported, but there is no CSI2
+	 * data_type defined for raw 16, and no sensors that produce it at
+	 * present.
+	 */
+
+	/* Greyscale formats */
+		.fourcc		= V4L2_PIX_FMT_GREY,
+		.code		= MEDIA_BUS_FMT_Y8_1X8,
+		.depth		= 8,
+		.csi_dt		= 0x2a,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y10P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y10,
+		.code		= MEDIA_BUS_FMT_Y10_1X10,
+		.depth		= 10,
+		.csi_dt		= 0x2b,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y12P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y12,
+		.code		= MEDIA_BUS_FMT_Y12_1X12,
+		.depth		= 12,
+		.csi_dt		= 0x2c,
+		.valid_colorspaces = MASK_CS_RAW,
+	}, {
+		.fourcc		= V4L2_PIX_FMT_Y14P,
+		.repacked_fourcc = V4L2_PIX_FMT_Y14,
+		.code		= MEDIA_BUS_FMT_Y14_1X14,
+		.depth		= 14,
+		.csi_dt		= 0x2d,
+		.valid_colorspaces = MASK_CS_RAW,
+	},
+	/* Embedded data format */
+	{
+		.fourcc		= V4L2_META_FMT_8,
+		.code		= MEDIA_BUS_FMT_METADATA_8,
+		.depth		= 8,
+		.metadata_fmt	= 1,
+	}
+};
+
+struct unicam_buffer {
+	struct vb2_v4l2_buffer vb;
+	struct list_head list;
+};
+
+static inline struct unicam_buffer *to_unicam_buffer(struct vb2_buffer *vb)
+{
+	return container_of(vb, struct unicam_buffer, vb.vb2_buf);
+}
+
+struct unicam_node {
+	bool registered;
+	int open;
+	bool streaming;
+	unsigned int node_id;
+	/* Source pad id on the sensor for this node */
+	unsigned int src_pad_id;
+	/* Pointer pointing to current v4l2_buffer */
+	struct unicam_buffer *cur_frm;
+	/* Pointer pointing to next v4l2_buffer */
+	struct unicam_buffer *next_frm;
+	/* video capture */
+	const struct unicam_fmt *fmt;
+	/* Used to store current pixel format */
+	struct v4l2_format v_fmt;
+	/* Used to store current mbus frame format */
+	struct v4l2_mbus_framefmt m_fmt;
+	/* Buffer queue used in video-buf */
+	struct vb2_queue buffer_queue;
+	/* Queue of filled frames */
+	struct list_head dma_queue;
+	/* IRQ lock for DMA queue */
+	spinlock_t dma_queue_lock;
+	/* lock used to access this structure */
+	struct mutex lock;
+	/* Identifies video device for this channel */
+	struct video_device video_dev;
+	/* Pointer to the parent handle */
+	struct unicam_device *dev;
+	struct media_pad pad;
+	unsigned int embedded_lines;
+	struct media_pipeline pipe;
+	/*
+	 * Dummy buffer intended to be used by unicam
+	 * if we have no other queued buffers to swap to.
+	 */
+	void *dummy_buf_cpu_addr;
+	dma_addr_t dummy_buf_dma_addr;
+};
+
+struct unicam_device {
+	struct kref kref;
+
+	/* V4l2 specific parameters */
+	struct v4l2_async_subdev asd;
+
+	/* peripheral base address */
+	void __iomem *base;
+	/* clock gating base address */
+	void __iomem *clk_gate_base;
+	/* lp clock handle */
+	struct clk *clock;
+	/* vpu clock handle */
+	struct clk *vpu_clock;
+	/* vpu clock request */
+	struct clk_request *vpu_req;
+	/* clock status for error handling */
+	bool clocks_enabled;
+	/* V4l2 device */
+	struct v4l2_device v4l2_dev;
+	struct media_device mdev;
+
+	/* parent device */
+	struct platform_device *pdev;
+	/* subdevice async Notifier */
+	struct v4l2_async_notifier notifier;
+	unsigned int sequence;
+
+	/* ptr to  sub device */
+	struct v4l2_subdev *sensor;
+	/* Pad config for the sensor */
+	struct v4l2_subdev_state *sensor_state;
+
+	/* Internal subdev */
+	struct v4l2_subdev sd;
+	struct media_pad pads[UNICAM_SD_NUM_PADS];
+
+	bool streaming;
+
+	enum v4l2_mbus_type bus_type;
+	/*
+	 * Stores bus.mipi_csi2.flags for CSI2 sensors, or
+	 * bus.mipi_csi1.strobe for CCP2.
+	 */
+	unsigned int bus_flags;
+	unsigned int max_data_lanes;
+	unsigned int active_data_lanes;
+	bool sensor_embedded_data;
+
+	struct unicam_node node[MAX_NODES];
+	struct v4l2_ctrl_handler ctrl_handler;
+
+	bool mc_api;
+};
+
+static inline struct unicam_device *
+to_unicam_device(struct v4l2_device *v4l2_dev)
+{
+	return container_of(v4l2_dev, struct unicam_device, v4l2_dev);
+}
+
+static inline struct unicam_device *
+sd_to_unicam_device(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct unicam_device, sd);
+}
+
+static inline bool is_metadata_node(struct unicam_node *node)
+{
+	return node->video_dev.device_caps & V4L2_CAP_META_CAPTURE;
+}
+
+static inline bool is_image_node(struct unicam_node *node)
+{
+	return node->video_dev.device_caps & V4L2_CAP_VIDEO_CAPTURE;
+}
+
+/* Hardware access */
+static inline void clk_write(struct unicam_device *dev, u32 val)
+{
+	writel(val | 0x5a000000, dev->clk_gate_base);
+}
+
+static inline u32 reg_read(struct unicam_device *dev, u32 offset)
+{
+	return readl(dev->base + offset);
+}
+
+static inline void reg_write(struct unicam_device *dev, u32 offset, u32 val)
+{
+	writel(val, dev->base + offset);
+}
+
+static inline int get_field(u32 value, u32 mask)
+{
+	return (value & mask) >> __ffs(mask);
+}
+
+static inline void set_field(u32 *valp, u32 field, u32 mask)
+{
+	u32 val = *valp;
+
+	val &= ~mask;
+	val |= (field << __ffs(mask)) & mask;
+	*valp = val;
+}
+
+static inline u32 reg_read_field(struct unicam_device *dev, u32 offset,
+				 u32 mask)
+{
+	return get_field(reg_read(dev, offset), mask);
+}
+
+static inline void reg_write_field(struct unicam_device *dev, u32 offset,
+				   u32 field, u32 mask)
+{
+	u32 val = reg_read(dev, offset);
+
+	set_field(&val, field, mask);
+	reg_write(dev, offset, val);
+}
+
+/* Power management functions */
+static inline int unicam_runtime_get(struct unicam_device *dev)
+{
+	return pm_runtime_get_sync(&dev->pdev->dev);
+}
+
+static inline void unicam_runtime_put(struct unicam_device *dev)
+{
+	pm_runtime_put_sync(&dev->pdev->dev);
+}
+
+/* Format setup functions */
+static const struct unicam_fmt *find_format_by_code(u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		if (formats[i].code == code)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static const struct unicam_fmt *find_format_by_fourcc(u32 fourcc)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
+		if (formats[i].fourcc == fourcc)
+			return &formats[i];
+	}
+
+	return NULL;
+}
+
+static unsigned int bytes_per_line(u32 width, const struct unicam_fmt *fmt,
+				   u32 v4l2_fourcc)
+{
+	if (v4l2_fourcc == fmt->repacked_fourcc)
+		/* Repacking always goes to 16bpp */
+		return ALIGN(width << 1, BPL_ALIGNMENT);
+	else
+		return ALIGN((width * fmt->depth) >> 3, BPL_ALIGNMENT);
+}
+
+static int unicam_calc_format_size_bpl(struct unicam_device *dev,
+				       const struct unicam_fmt *fmt,
+				       struct v4l2_format *f)
+{
+	unsigned int min_bytesperline;
+
+	v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, MAX_WIDTH, 2,
+			      &f->fmt.pix.height, MIN_HEIGHT, MAX_HEIGHT, 0,
+			      0);
+
+	min_bytesperline = bytes_per_line(f->fmt.pix.width, fmt,
+					  f->fmt.pix.pixelformat);
+
+	if (f->fmt.pix.bytesperline > min_bytesperline &&
+	    f->fmt.pix.bytesperline <= MAX_BYTESPERLINE)
+		f->fmt.pix.bytesperline = ALIGN(f->fmt.pix.bytesperline,
+						BPL_ALIGNMENT);
+	else
+		f->fmt.pix.bytesperline = min_bytesperline;
+
+	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
+
+	dev_dbg(dev->v4l2_dev.dev, "%s: fourcc: %08X size: %dx%d bpl:%d img_size:%d\n",
+		__func__,
+		f->fmt.pix.pixelformat,
+		f->fmt.pix.width, f->fmt.pix.height,
+		f->fmt.pix.bytesperline, f->fmt.pix.sizeimage);
+
+	return 0;
+}
+
+static void unicam_wr_dma_addr(struct unicam_device *dev, dma_addr_t dmaaddr,
+			       unsigned int buffer_size, int node_id)
+{
+	dma_addr_t endaddr = dmaaddr + buffer_size;
+
+	if (node_id == IMAGE_NODE) {
+		reg_write(dev, UNICAM_IBSA0, dmaaddr);
+		reg_write(dev, UNICAM_IBEA0, endaddr);
+	} else {
+		reg_write(dev, UNICAM_DBSA0, dmaaddr);
+		reg_write(dev, UNICAM_DBEA0, endaddr);
+	}
+}
+
+static unsigned int unicam_get_lines_done(struct unicam_device *dev)
+{
+	dma_addr_t start_addr, cur_addr;
+	unsigned int stride = dev->node[IMAGE_NODE].v_fmt.fmt.pix.bytesperline;
+	struct unicam_buffer *frm = dev->node[IMAGE_NODE].cur_frm;
+
+	if (!frm)
+		return 0;
+
+	start_addr = vb2_dma_contig_plane_dma_addr(&frm->vb.vb2_buf, 0);
+	cur_addr = reg_read(dev, UNICAM_IBWP);
+	return (unsigned int)(cur_addr - start_addr) / stride;
+}
+
+static void unicam_schedule_next_buffer(struct unicam_node *node)
+{
+	struct unicam_device *dev = node->dev;
+	struct unicam_buffer *buf;
+	unsigned int size;
+	dma_addr_t addr;
+
+	buf = list_first_entry(&node->dma_queue, struct unicam_buffer, list);
+	node->next_frm = buf;
+	list_del(&buf->list);
+
+	addr = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+	if (is_image_node(node)) {
+		size = node->v_fmt.fmt.pix.sizeimage;
+		unicam_wr_dma_addr(dev, addr, size, IMAGE_NODE);
+	} else {
+		size = node->v_fmt.fmt.meta.buffersize;
+		unicam_wr_dma_addr(dev, addr, size, METADATA_NODE);
+	}
+}
+
+static void unicam_schedule_dummy_buffer(struct unicam_node *node)
+{
+	struct unicam_device *dev = node->dev;
+	int node_id = is_image_node(node) ? IMAGE_NODE : METADATA_NODE;
+
+	dev_dbg(dev->v4l2_dev.dev, "Scheduling dummy buffer for node %d\n", node_id);
+
+	unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr, DUMMY_BUF_SIZE,
+			   node_id);
+	node->next_frm = NULL;
+}
+
+static void unicam_process_buffer_complete(struct unicam_node *node,
+					   unsigned int sequence)
+{
+	node->cur_frm->vb.field = node->m_fmt.field;
+	node->cur_frm->vb.sequence = sequence;
+
+	vb2_buffer_done(&node->cur_frm->vb.vb2_buf, VB2_BUF_STATE_DONE);
+}
+
+static void unicam_queue_event_sof(struct unicam_device *unicam)
+{
+	struct v4l2_event event = {
+		.type = V4L2_EVENT_FRAME_SYNC,
+		.u.frame_sync.frame_sequence = unicam->sequence,
+	};
+
+	v4l2_event_queue(&unicam->node[IMAGE_NODE].video_dev, &event);
+}
+
+/*
+ * unicam_isr : ISR handler for unicam capture
+ * @irq: irq number
+ * @dev_id: dev_id ptr
+ *
+ * It changes status of the captured buffer, takes next buffer from the queue
+ * and sets its address in unicam registers
+ */
+static irqreturn_t unicam_isr(int irq, void *dev)
+{
+	struct unicam_device *unicam = dev;
+	unsigned int lines_done = unicam_get_lines_done(dev);
+	unsigned int sequence = unicam->sequence;
+	unsigned int i;
+	u32 ista, sta;
+	bool fe;
+	u64 ts;
+
+	sta = reg_read(unicam, UNICAM_STA);
+	/* Write value back to clear the interrupts */
+	reg_write(unicam, UNICAM_STA, sta);
+
+	ista = reg_read(unicam, UNICAM_ISTA);
+	/* Write value back to clear the interrupts */
+	reg_write(unicam, UNICAM_ISTA, ista);
+
+	dev_dbg(unicam->v4l2_dev.dev, "ISR: ISTA: 0x%X, STA: 0x%X, sequence %d, lines done %d",
+		ista, sta, sequence, lines_done);
+
+	if (!(sta & (UNICAM_IS | UNICAM_PI0)))
+		return IRQ_HANDLED;
+
+	/*
+	 * Look for either the Frame End interrupt or the Packet Capture status
+	 * to signal a frame end.
+	 */
+	fe = (ista & UNICAM_FEI || sta & UNICAM_PI0);
+
+	/*
+	 * We must run the frame end handler first. If we have a valid next_frm
+	 * and we get a simultaneout FE + FS interrupt, running the FS handler
+	 * first would null out the next_frm ptr and we would have lost the
+	 * buffer forever.
+	 */
+	if (fe) {
+		/*
+		 * Ensure we have swapped buffers already as we can't
+		 * stop the peripheral. If no buffer is available, use a
+		 * dummy buffer to dump out frames until we get a new buffer
+		 * to use.
+		 */
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			/*
+			 * If cur_frm == next_frm, it means we have not had
+			 * a chance to swap buffers, likely due to having
+			 * multiple interrupts occurring simultaneously (like FE
+			 * + FS + LS). In this case, we cannot signal the buffer
+			 * as complete, as the HW will reuse that buffer.
+			 */
+			if (unicam->node[i].cur_frm &&
+			    unicam->node[i].cur_frm != unicam->node[i].next_frm)
+				unicam_process_buffer_complete(&unicam->node[i],
+							       sequence);
+			unicam->node[i].cur_frm = unicam->node[i].next_frm;
+		}
+		unicam->sequence++;
+	}
+
+	if (ista & UNICAM_FSI) {
+		/*
+		 * Timestamp is to be when the first data byte was captured,
+		 * aka frame start.
+		 */
+		ts = ktime_get_ns();
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			if (unicam->node[i].cur_frm)
+				unicam->node[i].cur_frm->vb.vb2_buf.timestamp =
+								ts;
+			else
+				dev_dbg(unicam->v4l2_dev.dev, "ISR: [%d] Dropping frame, buffer not available at FS\n",
+					i);
+			/*
+			 * Set the next frame output to go to a dummy frame
+			 * if we have not managed to obtain another frame
+			 * from the queue.
+			 */
+			unicam_schedule_dummy_buffer(&unicam->node[i]);
+		}
+
+		unicam_queue_event_sof(unicam);
+	}
+
+	/*
+	 * Cannot swap buffer at frame end, there may be a race condition
+	 * where the HW does not actually swap it if the new frame has
+	 * already started.
+	 */
+	if (ista & (UNICAM_FSI | UNICAM_LCI) && !fe) {
+		for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+			if (!unicam->node[i].streaming)
+				continue;
+
+			spin_lock(&unicam->node[i].dma_queue_lock);
+			if (!list_empty(&unicam->node[i].dma_queue) &&
+			    !unicam->node[i].next_frm)
+				unicam_schedule_next_buffer(&unicam->node[i]);
+			spin_unlock(&unicam->node[i].dma_queue_lock);
+		}
+	}
+
+	if (reg_read(unicam, UNICAM_ICTL) & UNICAM_FCM) {
+		/* Switch out of trigger mode if selected */
+		reg_write_field(unicam, UNICAM_ICTL, 1, UNICAM_TFC);
+		reg_write_field(unicam, UNICAM_ICTL, 0, UNICAM_FCM);
+	}
+	return IRQ_HANDLED;
+}
+
+/* V4L2 Common IOCTLs */
+static int unicam_querycap(struct file *file, void *priv,
+			   struct v4l2_capability *cap)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+
+	strscpy(cap->driver, UNICAM_MODULE_NAME, sizeof(cap->driver));
+	strscpy(cap->card, UNICAM_MODULE_NAME, sizeof(cap->card));
+
+	snprintf(cap->bus_info, sizeof(cap->bus_info),
+		 "platform:%s", dev_name(&dev->pdev->dev));
+
+	cap->capabilities |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_META_CAPTURE;
+
+	return 0;
+}
+
+static int unicam_log_status(struct file *file, void *fh)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+	u32 reg;
+
+	/* status for sub devices */
+	v4l2_device_call_all(&dev->v4l2_dev, 0, core, log_status);
+
+	dev_info(dev->v4l2_dev.dev, "-----Receiver status-----\n");
+	dev_info(dev->v4l2_dev.dev, "V4L2 width/height:   %ux%u\n",
+		 node->v_fmt.fmt.pix.width, node->v_fmt.fmt.pix.height);
+	dev_info(dev->v4l2_dev.dev, "Mediabus format:     %08x\n", node->fmt->code);
+	dev_info(dev->v4l2_dev.dev, "V4L2 format:         %08x\n",
+		 node->v_fmt.fmt.pix.pixelformat);
+	reg = reg_read(dev, UNICAM_IPIPE);
+	dev_info(dev->v4l2_dev.dev, "Unpacking/packing:   %u / %u\n",
+		 get_field(reg, UNICAM_PUM_MASK),
+		 get_field(reg, UNICAM_PPM_MASK));
+	dev_info(dev->v4l2_dev.dev, "----Live data----\n");
+	dev_info(dev->v4l2_dev.dev, "Programmed stride:   %4u\n",
+		 reg_read(dev, UNICAM_IBLS));
+	dev_info(dev->v4l2_dev.dev, "Detected resolution: %ux%u\n",
+		 reg_read(dev, UNICAM_IHSTA),
+		 reg_read(dev, UNICAM_IVSTA));
+	dev_info(dev->v4l2_dev.dev, "Write pointer:       %08x\n",
+		 reg_read(dev, UNICAM_IBWP));
+
+	return 0;
+}
+
+static int unicam_subscribe_event(struct v4l2_fh *fh,
+				  const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_FRAME_SYNC:
+		return v4l2_event_subscribe(fh, sub, 2, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_event_subscribe(fh, sub, 4, NULL);
+	}
+
+	return v4l2_ctrl_subscribe_event(fh, sub);
+}
+
+static void unicam_notify(struct v4l2_subdev *sd,
+			  unsigned int notification, void *arg)
+{
+	struct unicam_device *dev = to_unicam_device(sd->v4l2_dev);
+
+	switch (notification) {
+	case V4L2_DEVICE_NOTIFY_EVENT:
+		v4l2_event_queue(&dev->node[IMAGE_NODE].video_dev, arg);
+		break;
+	default:
+		break;
+	}
+}
+
+/* V4L2 Media Controller Centric IOCTLs */
+
+static int unicam_mc_enum_fmt_vid_cap(struct file *file, void  *priv,
+				      struct v4l2_fmtdesc *f)
+{
+	int i, j;
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(formats); i++) {
+		if (f->mbus_code && formats[i].code != f->mbus_code)
+			continue;
+		if (formats[i].mc_skip || formats[i].metadata_fmt)
+			continue;
+
+		if (formats[i].fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].fourcc;
+				f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+		if (formats[i].repacked_fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].repacked_fourcc;
+				f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int unicam_mc_g_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_image_node(node))
+		return -EINVAL;
+
+	*f = node->v_fmt;
+
+	return 0;
+}
+
+static void unicam_mc_try_fmt(struct unicam_node *node, struct v4l2_format *f,
+			      const struct unicam_fmt **ret_fmt)
+{
+	struct v4l2_pix_format *v4l2_format = &f->fmt.pix;
+	struct unicam_device *dev = node->dev;
+	const struct unicam_fmt *fmt;
+	int is_rgb;
+
+	/*
+	 * Default to the first format if the requested pixel format code isn't
+	 * supported.
+	 */
+	fmt = find_format_by_fourcc(v4l2_format->pixelformat);
+	if (!fmt) {
+		fmt = &formats[0];
+		v4l2_format->pixelformat = fmt->fourcc;
+	}
+
+	unicam_calc_format_size_bpl(dev, fmt, f);
+
+	if (v4l2_format->field == V4L2_FIELD_ANY)
+		v4l2_format->field = V4L2_FIELD_NONE;
+
+	if (v4l2_format->colorspace >= MAX_COLORSPACE ||
+	    !(fmt->valid_colorspaces & (1 << v4l2_format->colorspace))) {
+		v4l2_format->colorspace = __ffs(fmt->valid_colorspaces);
+
+		v4l2_format->xfer_func =
+			V4L2_MAP_XFER_FUNC_DEFAULT(v4l2_format->colorspace);
+		v4l2_format->ycbcr_enc =
+			V4L2_MAP_YCBCR_ENC_DEFAULT(v4l2_format->colorspace);
+		is_rgb = v4l2_format->colorspace == V4L2_COLORSPACE_SRGB;
+		v4l2_format->quantization =
+			V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb,
+						      v4l2_format->colorspace,
+						      v4l2_format->ycbcr_enc);
+	}
+
+	if (ret_fmt)
+		*ret_fmt = fmt;
+
+	dev_dbg(dev->v4l2_dev.dev, "%s: %08x %ux%u (bytesperline %u sizeimage %u)\n",
+		__func__, v4l2_format->pixelformat,
+		v4l2_format->width, v4l2_format->height,
+		v4l2_format->bytesperline, v4l2_format->sizeimage);
+}
+
+static int unicam_mc_try_fmt_vid_cap(struct file *file, void *priv,
+				     struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	unicam_mc_try_fmt(node, f, NULL);
+	return 0;
+}
+
+static int unicam_mc_s_fmt_vid_cap(struct file *file, void *priv,
+				   struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+	const struct unicam_fmt *fmt;
+
+	if (vb2_is_busy(&node->buffer_queue)) {
+		dev_dbg(dev->v4l2_dev.dev, "%s device busy\n", __func__);
+		return -EBUSY;
+	}
+
+	unicam_mc_try_fmt(node, f, &fmt);
+
+	node->v_fmt = *f;
+	node->fmt = fmt;
+
+	return 0;
+}
+
+static int unicam_mc_enum_framesizes(struct file *file, void *fh,
+				     struct v4l2_frmsizeenum *fsize)
+{
+	struct unicam_node *node = video_drvdata(file);
+	struct unicam_device *dev = node->dev;
+
+	if (fsize->index > 0)
+		return -EINVAL;
+
+	if (!find_format_by_fourcc(fsize->pixel_format)) {
+		dev_dbg(dev->v4l2_dev.dev, "Invalid pixel format 0x%08x\n",
+			fsize->pixel_format);
+		return -EINVAL;
+	}
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = MIN_WIDTH;
+	fsize->stepwise.max_width = MAX_WIDTH;
+	fsize->stepwise.step_width = 1;
+	fsize->stepwise.min_height = MIN_HEIGHT;
+	fsize->stepwise.max_height = MAX_HEIGHT;
+	fsize->stepwise.step_height = 1;
+
+	return 0;
+}
+
+static int unicam_mc_enum_fmt_meta_cap(struct file *file, void  *priv,
+				       struct v4l2_fmtdesc *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+	int i, j;
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	for (i = 0, j = 0; i < ARRAY_SIZE(formats); i++) {
+		if (f->mbus_code && formats[i].code != f->mbus_code)
+			continue;
+		if (!formats[i].metadata_fmt)
+			continue;
+
+		if (formats[i].fourcc) {
+			if (j == f->index) {
+				f->pixelformat = formats[i].fourcc;
+				f->type = V4L2_BUF_TYPE_META_CAPTURE;
+				return 0;
+			}
+			j++;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int unicam_mc_g_fmt_meta_cap(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	*f = node->v_fmt;
+
+	return 0;
+}
+
+static int unicam_mc_try_fmt_meta_cap(struct file *file, void *priv,
+				      struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	f->fmt.meta.dataformat = V4L2_META_FMT_8;
+
+	return 0;
+}
+
+static int unicam_mc_s_fmt_meta_cap(struct file *file, void *priv,
+				    struct v4l2_format *f)
+{
+	struct unicam_node *node = video_drvdata(file);
+
+	if (!is_metadata_node(node))
+		return -EINVAL;
+
+	unicam_mc_try_fmt_meta_cap(file, priv, f);
+
+	node->v_fmt = *f;
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops unicam_mc_ioctl_ops = {
+	.vidioc_querycap      = unicam_querycap,
+	.vidioc_enum_fmt_vid_cap  = unicam_mc_enum_fmt_vid_cap,
+	.vidioc_g_fmt_vid_cap     = unicam_mc_g_fmt_vid_cap,
+	.vidioc_try_fmt_vid_cap   = unicam_mc_try_fmt_vid_cap,
+	.vidioc_s_fmt_vid_cap     = unicam_mc_s_fmt_vid_cap,
+
+	.vidioc_enum_fmt_meta_cap	= unicam_mc_enum_fmt_meta_cap,
+	.vidioc_g_fmt_meta_cap		= unicam_mc_g_fmt_meta_cap,
+	.vidioc_try_fmt_meta_cap	= unicam_mc_try_fmt_meta_cap,
+	.vidioc_s_fmt_meta_cap		= unicam_mc_s_fmt_meta_cap,
+
+	.vidioc_enum_framesizes   = unicam_mc_enum_framesizes,
+	.vidioc_reqbufs       = vb2_ioctl_reqbufs,
+	.vidioc_create_bufs   = vb2_ioctl_create_bufs,
+	.vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+	.vidioc_querybuf      = vb2_ioctl_querybuf,
+	.vidioc_qbuf          = vb2_ioctl_qbuf,
+	.vidioc_dqbuf         = vb2_ioctl_dqbuf,
+	.vidioc_expbuf        = vb2_ioctl_expbuf,
+	.vidioc_streamon      = vb2_ioctl_streamon,
+	.vidioc_streamoff     = vb2_ioctl_streamoff,
+
+	.vidioc_log_status		= unicam_log_status,
+	.vidioc_subscribe_event		= unicam_subscribe_event,
+	.vidioc_unsubscribe_event	= v4l2_event_unsubscribe,
+};
+
+static const struct media_entity_operations unicam_mc_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+	.has_route = v4l2_subdev_has_route,
+};
+
+/* videobuf2 Operations */
+
+static int unicam_queue_setup(struct vb2_queue *vq,
+			      unsigned int *nbuffers,
+			      unsigned int *nplanes,
+			      unsigned int sizes[],
+			      struct device *alloc_devs[])
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+	unsigned int size = is_image_node(node) ?
+				node->v_fmt.fmt.pix.sizeimage :
+				node->v_fmt.fmt.meta.buffersize;
+
+	if (vq->num_buffers + *nbuffers < 3)
+		*nbuffers = 3 - vq->num_buffers;
+
+	if (*nplanes) {
+		if (sizes[0] < size) {
+			dev_err(dev->v4l2_dev.dev, "sizes[0] %i < size %u\n", sizes[0],
+				size);
+			return -EINVAL;
+		}
+		size = sizes[0];
+	}
+
+	*nplanes = 1;
+	sizes[0] = size;
+
+	return 0;
+}
+
+static int unicam_buffer_prepare(struct vb2_buffer *vb)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+	struct unicam_device *dev = node->dev;
+	struct unicam_buffer *buf = to_unicam_buffer(vb);
+	unsigned long size;
+
+	if (WARN_ON(!node->fmt))
+		return -EINVAL;
+
+	size = is_image_node(node) ? node->v_fmt.fmt.pix.sizeimage :
+				     node->v_fmt.fmt.meta.buffersize;
+	if (vb2_plane_size(vb, 0) < size) {
+		dev_err(dev->v4l2_dev.dev, "data will not fit into plane (%lu < %lu)\n",
+			vb2_plane_size(vb, 0), size);
+		return -EINVAL;
+	}
+
+	vb2_set_plane_payload(&buf->vb.vb2_buf, 0, size);
+	return 0;
+}
+
+static void unicam_buffer_queue(struct vb2_buffer *vb)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vb->vb2_queue);
+	struct unicam_buffer *buf = to_unicam_buffer(vb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	list_add_tail(&buf->list, &node->dma_queue);
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+}
+
+static void unicam_set_packing_config(struct unicam_device *dev)
+{
+	u32 pack, unpack;
+	u32 val;
+
+	if (dev->node[IMAGE_NODE].v_fmt.fmt.pix.pixelformat ==
+	    dev->node[IMAGE_NODE].fmt->fourcc) {
+		unpack = UNICAM_PUM_NONE;
+		pack = UNICAM_PPM_NONE;
+	} else {
+		switch (dev->node[IMAGE_NODE].fmt->depth) {
+		case 8:
+			unpack = UNICAM_PUM_UNPACK8;
+			break;
+		case 10:
+			unpack = UNICAM_PUM_UNPACK10;
+			break;
+		case 12:
+			unpack = UNICAM_PUM_UNPACK12;
+			break;
+		case 14:
+			unpack = UNICAM_PUM_UNPACK14;
+			break;
+		case 16:
+			unpack = UNICAM_PUM_UNPACK16;
+			break;
+		default:
+			unpack = UNICAM_PUM_NONE;
+			break;
+		}
+
+		/* Repacking is always to 16bpp */
+		pack = UNICAM_PPM_PACK16;
+	}
+
+	val = 0;
+	set_field(&val, unpack, UNICAM_PUM_MASK);
+	set_field(&val, pack, UNICAM_PPM_MASK);
+	reg_write(dev, UNICAM_IPIPE, val);
+}
+
+static void unicam_cfg_image_id(struct unicam_device *dev)
+{
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 mode, hardcode VC 0 for now. */
+		reg_write(dev, UNICAM_IDI0,
+			  (0 << 6) | dev->node[IMAGE_NODE].fmt->csi_dt);
+	} else {
+		/* CCP2 mode */
+		reg_write(dev, UNICAM_IDI0,
+			  0x80 | dev->node[IMAGE_NODE].fmt->csi_dt);
+	}
+}
+
+static void unicam_enable_ed(struct unicam_device *dev)
+{
+	u32 val = reg_read(dev, UNICAM_DCS);
+
+	set_field(&val, 2, UNICAM_EDL_MASK);
+	/* Do not wrap at the end of the embedded data buffer */
+	set_field(&val, 0, UNICAM_DBOB);
+
+	reg_write(dev, UNICAM_DCS, val);
+}
+
+static void unicam_start_rx(struct unicam_device *dev, dma_addr_t *addr)
+{
+	int line_int_freq = dev->node[IMAGE_NODE].v_fmt.fmt.pix.height >> 2;
+	unsigned int size, i;
+	u32 val;
+
+	if (line_int_freq < 128)
+		line_int_freq = 128;
+
+	/* Enable lane clocks */
+	val = 1;
+	for (i = 0; i < dev->active_data_lanes; i++)
+		val = val << 2 | 1;
+	clk_write(dev, val);
+
+	/* Basic init */
+	reg_write(dev, UNICAM_CTRL, UNICAM_MEM);
+
+	/* Enable analogue control, and leave in reset. */
+	val = UNICAM_AR;
+	set_field(&val, 7, UNICAM_CTATADJ_MASK);
+	set_field(&val, 7, UNICAM_PTATADJ_MASK);
+	reg_write(dev, UNICAM_ANA, val);
+	usleep_range(1000, 2000);
+
+	/* Come out of reset */
+	reg_write_field(dev, UNICAM_ANA, 0, UNICAM_AR);
+
+	/* Peripheral reset */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
+
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
+
+	/* Enable Rx control. */
+	val = reg_read(dev, UNICAM_CTRL);
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		set_field(&val, UNICAM_CPM_CSI2, UNICAM_CPM_MASK);
+		set_field(&val, UNICAM_DCM_STROBE, UNICAM_DCM_MASK);
+	} else {
+		set_field(&val, UNICAM_CPM_CCP2, UNICAM_CPM_MASK);
+		set_field(&val, dev->bus_flags, UNICAM_DCM_MASK);
+	}
+	/* Packet framer timeout */
+	set_field(&val, 0xf, UNICAM_PFT_MASK);
+	set_field(&val, 128, UNICAM_OET_MASK);
+	reg_write(dev, UNICAM_CTRL, val);
+
+	reg_write(dev, UNICAM_IHWIN, 0);
+	reg_write(dev, UNICAM_IVWIN, 0);
+
+	/* AXI bus access QoS setup */
+	val = reg_read(dev, UNICAM_PRI);
+	set_field(&val, 0, UNICAM_BL_MASK);
+	set_field(&val, 0, UNICAM_BS_MASK);
+	set_field(&val, 0xe, UNICAM_PP_MASK);
+	set_field(&val, 8, UNICAM_NP_MASK);
+	set_field(&val, 2, UNICAM_PT_MASK);
+	set_field(&val, 1, UNICAM_PE);
+	reg_write(dev, UNICAM_PRI, val);
+
+	reg_write_field(dev, UNICAM_ANA, 0, UNICAM_DDL);
+
+	/* Always start in trigger frame capture mode (UNICAM_FCM set) */
+	val = UNICAM_FSIE | UNICAM_FEIE | UNICAM_FCM | UNICAM_IBOB;
+	set_field(&val, line_int_freq, UNICAM_LCIE_MASK);
+	reg_write(dev, UNICAM_ICTL, val);
+	reg_write(dev, UNICAM_STA, UNICAM_STA_MASK_ALL);
+	reg_write(dev, UNICAM_ISTA, UNICAM_ISTA_MASK_ALL);
+
+	/* tclk_term_en */
+	reg_write_field(dev, UNICAM_CLT, 2, UNICAM_CLT1_MASK);
+	/* tclk_settle */
+	reg_write_field(dev, UNICAM_CLT, 6, UNICAM_CLT2_MASK);
+	/* td_term_en */
+	reg_write_field(dev, UNICAM_DLT, 2, UNICAM_DLT1_MASK);
+	/* ths_settle */
+	reg_write_field(dev, UNICAM_DLT, 6, UNICAM_DLT2_MASK);
+	/* trx_enable */
+	reg_write_field(dev, UNICAM_DLT, 0, UNICAM_DLT3_MASK);
+
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_SOE);
+
+	/* Packet compare setup - required to avoid missing frame ends */
+	val = 0;
+	set_field(&val, 1, UNICAM_PCE);
+	set_field(&val, 1, UNICAM_GI);
+	set_field(&val, 1, UNICAM_CPH);
+	set_field(&val, 0, UNICAM_PCVC_MASK);
+	set_field(&val, 1, UNICAM_PCDT_MASK);
+	reg_write(dev, UNICAM_CMP0, val);
+
+	/* Enable clock lane and set up terminations */
+	val = 0;
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 */
+		set_field(&val, 1, UNICAM_CLE);
+		set_field(&val, 1, UNICAM_CLLPE);
+		if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+			set_field(&val, 1, UNICAM_CLTRE);
+			set_field(&val, 1, UNICAM_CLHSE);
+		}
+	} else {
+		/* CCP2 */
+		set_field(&val, 1, UNICAM_CLE);
+		set_field(&val, 1, UNICAM_CLHSE);
+		set_field(&val, 1, UNICAM_CLTRE);
+	}
+	reg_write(dev, UNICAM_CLK, val);
+
+	/*
+	 * Enable required data lanes with appropriate terminations.
+	 * The same value needs to be written to UNICAM_DATn registers for
+	 * the active lanes, and 0 for inactive ones.
+	 */
+	val = 0;
+	if (dev->bus_type == V4L2_MBUS_CSI2_DPHY) {
+		/* CSI2 */
+		set_field(&val, 1, UNICAM_DLE);
+		set_field(&val, 1, UNICAM_DLLPE);
+		if (dev->bus_flags & V4L2_MBUS_CSI2_CONTINUOUS_CLOCK) {
+			set_field(&val, 1, UNICAM_DLTRE);
+			set_field(&val, 1, UNICAM_DLHSE);
+		}
+	} else {
+		/* CCP2 */
+		set_field(&val, 1, UNICAM_DLE);
+		set_field(&val, 1, UNICAM_DLHSE);
+		set_field(&val, 1, UNICAM_DLTRE);
+	}
+	reg_write(dev, UNICAM_DAT0, val);
+
+	if (dev->active_data_lanes == 1)
+		val = 0;
+	reg_write(dev, UNICAM_DAT1, val);
+
+	if (dev->max_data_lanes > 2) {
+		/*
+		 * Registers UNICAM_DAT2 and UNICAM_DAT3 only valid if the
+		 * instance supports more than 2 data lanes.
+		 */
+		if (dev->active_data_lanes == 2)
+			val = 0;
+		reg_write(dev, UNICAM_DAT2, val);
+
+		if (dev->active_data_lanes == 3)
+			val = 0;
+		reg_write(dev, UNICAM_DAT3, val);
+	}
+
+	reg_write(dev, UNICAM_IBLS,
+		  dev->node[IMAGE_NODE].v_fmt.fmt.pix.bytesperline);
+	size = dev->node[IMAGE_NODE].v_fmt.fmt.pix.sizeimage;
+	unicam_wr_dma_addr(dev, addr[IMAGE_NODE], size, IMAGE_NODE);
+	unicam_set_packing_config(dev);
+	unicam_cfg_image_id(dev);
+
+	val = reg_read(dev, UNICAM_MISC);
+	set_field(&val, 1, UNICAM_FL0);
+	set_field(&val, 1, UNICAM_FL1);
+	reg_write(dev, UNICAM_MISC, val);
+
+	if (dev->node[METADATA_NODE].streaming && dev->sensor_embedded_data) {
+		dev_dbg(dev->v4l2_dev.dev, "enable metadata dma\n");
+		size = dev->node[METADATA_NODE].v_fmt.fmt.meta.buffersize;
+		unicam_enable_ed(dev);
+		unicam_wr_dma_addr(dev, addr[METADATA_NODE], size, METADATA_NODE);
+	}
+
+	/* Enable peripheral */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPE);
+
+	/* Load image pointers */
+	reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_LIP_MASK);
+
+	/* Load embedded data buffer pointers if needed */
+	if (dev->node[METADATA_NODE].streaming && dev->sensor_embedded_data)
+		reg_write_field(dev, UNICAM_DCS, 1, UNICAM_LDP);
+
+	/*
+	 * Enable trigger only for the first frame to
+	 * sync correctly to the FS from the source.
+	 */
+	reg_write_field(dev, UNICAM_ICTL, 1, UNICAM_TFC);
+}
+
+static void unicam_disable(struct unicam_device *dev)
+{
+	/* Analogue lane control disable */
+	reg_write_field(dev, UNICAM_ANA, 1, UNICAM_DDL);
+
+	/* Stop the output engine */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_SOE);
+
+	/* Disable the data lanes. */
+	reg_write(dev, UNICAM_DAT0, 0);
+	reg_write(dev, UNICAM_DAT1, 0);
+
+	if (dev->max_data_lanes > 2) {
+		reg_write(dev, UNICAM_DAT2, 0);
+		reg_write(dev, UNICAM_DAT3, 0);
+	}
+
+	/* Peripheral reset */
+	reg_write_field(dev, UNICAM_CTRL, 1, UNICAM_CPR);
+	usleep_range(50, 100);
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPR);
+
+	/* Disable peripheral */
+	reg_write_field(dev, UNICAM_CTRL, 0, UNICAM_CPE);
+
+	/* Clear ED setup */
+	reg_write(dev, UNICAM_DCS, 0);
+
+	/* Disable all lane clocks */
+	clk_write(dev, 0);
+}
+
+static void unicam_return_buffers(struct unicam_node *node,
+				  enum vb2_buffer_state state)
+{
+	struct unicam_buffer *buf, *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	list_for_each_entry_safe(buf, tmp, &node->dma_queue, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb.vb2_buf, state);
+	}
+
+	if (node->cur_frm)
+		vb2_buffer_done(&node->cur_frm->vb.vb2_buf,
+				state);
+	if (node->next_frm && node->cur_frm != node->next_frm)
+		vb2_buffer_done(&node->next_frm->vb.vb2_buf,
+				state);
+
+	node->cur_frm = NULL;
+	node->next_frm = NULL;
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+}
+
+static int unicam_video_check_format(struct unicam_node *node)
+{
+	const struct v4l2_mbus_framefmt *format;
+	struct media_pad *remote_pad;
+	struct v4l2_subdev_state *state;
+	int ret = 0;
+
+	remote_pad = media_entity_remote_pad(&node->pad);
+	if (!remote_pad)
+		return -ENODEV;
+
+	state = v4l2_subdev_lock_active_state(node->dev->sensor);
+
+	format = v4l2_state_get_stream_format(state,
+					      remote_pad->index, 0);
+	if (!format) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (node->fmt->code != format->code ||
+	    node->v_fmt.fmt.pix.height != format->height ||
+	    node->v_fmt.fmt.pix.width != format->width ||
+	    node->v_fmt.fmt.pix.field != format->field) {
+		ret = -EPIPE;
+		goto out;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+	dma_addr_t buffer_addr[MAX_NODES] = { 0 };
+	struct unicam_buffer *buf;
+	unsigned long flags;
+	unsigned int i;
+	int ret;
+
+	node->streaming = true;
+
+	dev->sequence = 0;
+	ret = unicam_runtime_get(dev);
+	if (ret < 0) {
+		dev_dbg(dev->v4l2_dev.dev, "unicam_runtime_get failed\n");
+		goto err_streaming;
+	}
+
+	ret = media_pipeline_start(node->video_dev.entity.pads, &node->pipe);
+	if (ret < 0) {
+		dev_err(dev->v4l2_dev.dev, "Failed to start media pipeline: %d\n", ret);
+		goto err_pm_put;
+	}
+
+	dev->active_data_lanes = dev->max_data_lanes;
+
+	unicam_video_check_format(node);
+
+	dev_dbg(dev->v4l2_dev.dev, "Running with %u data lanes\n",
+		dev->active_data_lanes);
+
+	ret = clk_set_min_rate(dev->vpu_clock, MIN_VPU_CLOCK_RATE);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "failed to set up VPU clock\n");
+		goto error_pipeline;
+	}
+
+	ret = clk_prepare_enable(dev->vpu_clock);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "Failed to enable VPU clock: %d\n", ret);
+		goto error_pipeline;
+	}
+
+	ret = clk_set_rate(dev->clock, 100 * 1000 * 1000);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "failed to set up CSI clock\n");
+		goto err_vpu_clock;
+	}
+
+	ret = clk_prepare_enable(dev->clock);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "Failed to enable CSI clock: %d\n", ret);
+		goto err_vpu_clock;
+	}
+
+	dev_dbg(dev->v4l2_dev.dev, "node %s\n", node->video_dev.name);
+
+	spin_lock_irqsave(&node->dma_queue_lock, flags);
+	buf = list_first_entry(&node->dma_queue,
+			       struct unicam_buffer, list);
+	node->cur_frm = buf;
+	node->next_frm = buf;
+	list_del(&buf->list);
+	spin_unlock_irqrestore(&node->dma_queue_lock, flags);
+
+	buffer_addr[i] =
+		vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
+
+	unicam_start_rx(dev, buffer_addr);
+
+	ret = v4l2_subdev_call(&dev->sd, video, s_stream, 1);
+	if (ret < 0) {
+		dev_err(dev->v4l2_dev.dev, "stream on failed in subdev\n");
+		goto err_disable_unicam;
+	}
+
+	dev->clocks_enabled = true;
+	return 0;
+
+err_disable_unicam:
+	unicam_disable(dev);
+	clk_disable_unprepare(dev->clock);
+err_vpu_clock:
+	if (clk_set_min_rate(dev->vpu_clock, 0))
+		dev_err(dev->v4l2_dev.dev, "failed to reset the VPU clock\n");
+	clk_disable_unprepare(dev->vpu_clock);
+error_pipeline:
+	media_pipeline_stop(node->video_dev.entity.pads);
+err_pm_put:
+	unicam_runtime_put(dev);
+err_streaming:
+	unicam_return_buffers(node, VB2_BUF_STATE_QUEUED);
+	node->streaming = false;
+
+	return ret;
+}
+
+static void unicam_stop_streaming(struct vb2_queue *vq)
+{
+	struct unicam_node *node = vb2_get_drv_priv(vq);
+	struct unicam_device *dev = node->dev;
+
+	node->streaming = false;
+	/*
+	 * Stop streaming the sensor and disable the peripheral.
+	 * We cannot continue streaming embedded data with the
+	 * image pad disabled.
+	 */
+	if (v4l2_subdev_call(&dev->sd, video, s_stream, 0) < 0)
+		dev_err(dev->v4l2_dev.dev, "stream off failed in subdev\n");
+
+	unicam_disable(dev);
+
+	media_pipeline_stop(node->video_dev.entity.pads);
+
+	if (dev->clocks_enabled) {
+		if (clk_set_min_rate(dev->vpu_clock, 0))
+			dev_err(dev->v4l2_dev.dev, "failed to reset the VPU clock\n");
+		clk_disable_unprepare(dev->vpu_clock);
+		clk_disable_unprepare(dev->clock);
+		dev->clocks_enabled = false;
+	}
+	unicam_runtime_put(dev);
+
+	if (is_metadata_node(node)) {
+		/*
+		 * Allow the hardware to spin in the dummy buffer.
+		 * This is only really needed if the embedded data pad is
+		 * disabled before the image pad.
+		 */
+		unicam_wr_dma_addr(dev, node->dummy_buf_dma_addr,
+				   DUMMY_BUF_SIZE, METADATA_NODE);
+	}
+
+	/* Clear all queued buffers for the node */
+	unicam_return_buffers(node, VB2_BUF_STATE_ERROR);
+}
+
+static const struct vb2_ops unicam_video_qops = {
+	.wait_prepare		= vb2_ops_wait_prepare,
+	.wait_finish		= vb2_ops_wait_finish,
+	.queue_setup		= unicam_queue_setup,
+	.buf_prepare		= unicam_buffer_prepare,
+	.buf_queue		= unicam_buffer_queue,
+	.start_streaming	= unicam_start_streaming,
+	.stop_streaming		= unicam_stop_streaming,
+};
+
+/* unicam capture driver file operations */
+static const struct v4l2_file_operations unicam_fops = {
+	.owner		= THIS_MODULE,
+	.open           = v4l2_fh_open,
+	.release        = vb2_fop_release,
+	.poll		= vb2_fop_poll,
+	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
+	.mmap           = vb2_fop_mmap,
+};
+
+static int
+unicam_async_bound(struct v4l2_async_notifier *notifier,
+		   struct v4l2_subdev *subdev,
+		   struct v4l2_async_subdev *asd)
+{
+	struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
+
+	if (unicam->sensor) {
+		dev_info(unicam->v4l2_dev.dev, "subdev %s (Already set!!)",
+			 subdev->name);
+		return 0;
+	}
+
+	unicam->sensor = subdev;
+	dev_dbg(unicam->v4l2_dev.dev, "Using sensor %s for capture\n", subdev->name);
+
+	return 0;
+}
+
+static void unicam_release(struct kref *kref)
+{
+	struct unicam_device *unicam =
+		container_of(kref, struct unicam_device, kref);
+
+	v4l2_ctrl_handler_free(&unicam->ctrl_handler);
+	media_device_cleanup(&unicam->mdev);
+
+	if (unicam->sensor_state)
+		__v4l2_subdev_state_free(unicam->sensor_state);
+
+	kfree(unicam);
+}
+
+static void unicam_put(struct unicam_device *unicam)
+{
+	kref_put(&unicam->kref, unicam_release);
+}
+
+static void unicam_get(struct unicam_device *unicam)
+{
+	kref_get(&unicam->kref);
+}
+
+static void unicam_node_release(struct video_device *vdev)
+{
+	struct unicam_node *node = video_get_drvdata(vdev);
+
+	unicam_put(node->dev);
+}
+
+static void unicam_mc_set_default_format(struct unicam_node *node)
+{
+	dev_dbg(node->dev->v4l2_dev.dev, "Set default format for %s node\n",
+		node->node_id == IMAGE_NODE ? "image" : "metadata");
+
+	if (is_image_node(node)) {
+		struct v4l2_pix_format *pix_fmt = &node->v_fmt.fmt.pix;
+
+		pix_fmt->width = 640;
+		pix_fmt->height = 480;
+		pix_fmt->field = V4L2_FIELD_NONE;
+		pix_fmt->colorspace = V4L2_COLORSPACE_SRGB;
+		pix_fmt->ycbcr_enc = V4L2_YCBCR_ENC_601;
+		pix_fmt->quantization = V4L2_QUANTIZATION_LIM_RANGE;
+		pix_fmt->xfer_func = V4L2_XFER_FUNC_SRGB;
+		pix_fmt->pixelformat = formats[0].fourcc;
+		unicam_calc_format_size_bpl(node->dev, &formats[0],
+					    &node->v_fmt);
+		node->v_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+		node->fmt = &formats[0];
+	} else {
+		const struct unicam_fmt *fmt;
+
+		/* Fix this node format as embedded data. */
+		fmt = find_format_by_code(MEDIA_BUS_FMT_METADATA_8);
+		node->v_fmt.fmt.meta.dataformat = fmt->fourcc;
+		node->fmt = fmt;
+		node->v_fmt.fmt.meta.buffersize = UNICAM_EMBEDDED_SIZE;
+		node->embedded_lines = 1;
+		node->v_fmt.type = V4L2_BUF_TYPE_META_CAPTURE;
+	}
+}
+
+static int register_node(struct unicam_device *unicam, struct unicam_node *node,
+			 enum v4l2_buf_type type)
+{
+	struct video_device *vdev;
+	struct vb2_queue *q;
+	int ret;
+
+	node->dev = unicam;
+	node->node_id = type == V4L2_BUF_TYPE_VIDEO_CAPTURE ?
+				IMAGE_NODE :
+				METADATA_NODE;
+
+	spin_lock_init(&node->dma_queue_lock);
+	mutex_init(&node->lock);
+
+	vdev = &node->video_dev;
+	/*
+	 * If the sensor subdevice has any controls, associate the node
+	 *  with the ctrl handler to allow access from userland.
+	 */
+	if (!list_empty(&unicam->ctrl_handler.ctrls))
+		vdev->ctrl_handler = &unicam->ctrl_handler;
+
+	q = &node->buffer_queue;
+	q->type = type;
+	q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
+	q->drv_priv = node;
+	q->ops = &unicam_video_qops;
+	q->mem_ops = &vb2_dma_contig_memops;
+	q->buf_struct_size = sizeof(struct unicam_buffer);
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+	q->lock = &node->lock;
+	q->min_buffers_needed = 1;
+	q->dev = &unicam->pdev->dev;
+
+	ret = vb2_queue_init(q);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "vb2_queue_init() failed\n");
+		return ret;
+	}
+
+	INIT_LIST_HEAD(&node->dma_queue);
+
+	vdev->release = unicam_node_release;
+	vdev->fops = &unicam_fops;
+	vdev->ioctl_ops = &unicam_mc_ioctl_ops;
+	vdev->v4l2_dev = &unicam->v4l2_dev;
+	vdev->vfl_dir = VFL_DIR_RX;
+	vdev->queue = q;
+	vdev->lock = &node->lock;
+	vdev->device_caps = (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
+				V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_META_CAPTURE;
+	vdev->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_IO_MC;
+	vdev->entity.ops = &unicam_mc_entity_ops;
+
+	/* Define the device names */
+	snprintf(vdev->name, sizeof(vdev->name), "%s-%s", UNICAM_MODULE_NAME,
+		 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "image" : "embedded");
+
+	video_set_drvdata(vdev, node);
+	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
+	node->pad.flags = MEDIA_PAD_FL_SINK;
+	media_entity_pads_init(&vdev->entity, 1, &node->pad);
+
+	node->dummy_buf_cpu_addr = dma_alloc_coherent(&unicam->pdev->dev,
+						      DUMMY_BUF_SIZE,
+						      &node->dummy_buf_dma_addr,
+						      GFP_KERNEL);
+	if (!node->dummy_buf_cpu_addr) {
+		dev_err(unicam->v4l2_dev.dev, "Unable to allocate dummy buffer.\n");
+		return -ENOMEM;
+	}
+
+	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Unable to register video device %s\n",
+			vdev->name);
+		return ret;
+	}
+
+	/*
+	 * Acquire a reference to unicam, which will be released when the video
+	 * device will be unregistered and userspace will have closed all open
+	 * file handles.
+	 */
+	unicam_get(unicam);
+	node->registered = true;
+
+	ret = media_create_pad_link(&unicam->sd.entity,
+				    node->src_pad_id,
+				    &node->video_dev.entity,
+				    0,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		dev_err(unicam->v4l2_dev.dev, "Unable to create pad link for %s",
+			unicam->sensor->name);
+
+	unicam_mc_set_default_format(node);
+
+	return ret;
+}
+
+static void unregister_nodes(struct unicam_device *unicam)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(unicam->node); i++) {
+		struct unicam_node *node = &unicam->node[i];
+
+		if (node->dummy_buf_cpu_addr) {
+			dma_free_coherent(&unicam->pdev->dev, DUMMY_BUF_SIZE,
+					  node->dummy_buf_cpu_addr,
+					  node->dummy_buf_dma_addr);
+		}
+
+		if (node->registered) {
+			node->registered = false;
+			video_unregister_device(&node->video_dev);
+		}
+	}
+}
+
+static int unicam_async_complete(struct v4l2_async_notifier *notifier)
+{
+	struct unicam_device *unicam = to_unicam_device(notifier->v4l2_dev);
+	unsigned int i, source_pads = 0;
+	int ret;
+	static struct lock_class_key key;
+
+	unicam->v4l2_dev.notify = unicam_notify;
+
+	unicam->sensor_state = __v4l2_subdev_state_alloc(unicam->sensor,
+							 "unicam:state->lock",
+							 &key);
+	if (!unicam->sensor_state)
+		return -ENOMEM;
+
+	for (i = 0; i < unicam->sd.entity.num_pads; i++) {
+		if (unicam->sd.entity.pads[i].flags & MEDIA_PAD_FL_SOURCE) {
+			if (source_pads < MAX_NODES) {
+				unicam->node[source_pads].src_pad_id = i;
+				dev_dbg(unicam->v4l2_dev.dev, "source pad %u is index %u\n",
+					source_pads, i);
+			}
+			source_pads++;
+		}
+	}
+	if (!source_pads) {
+		dev_err(unicam->v4l2_dev.dev, "No source pads on sensor.\n");
+		goto unregister;
+	}
+
+	ret = register_node(unicam, &unicam->node[IMAGE_NODE],
+			    V4L2_BUF_TYPE_VIDEO_CAPTURE);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Unable to register image video device.\n");
+		goto unregister;
+	}
+
+	/* \todo: check before :-) */
+	unicam->sensor_embedded_data = true;
+
+	ret = register_node(unicam, &unicam->node[METADATA_NODE],
+			    V4L2_BUF_TYPE_META_CAPTURE);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Unable to register metadata video device.\n");
+		goto unregister;
+	}
+
+	ret = media_create_pad_link(&unicam->sensor->entity,
+				    0,
+				    &unicam->sd.entity,
+				    UNICAM_SD_PAD_SINK,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+	if (ret)
+		dev_err(unicam->v4l2_dev.dev, "Unable to create pad link for %s",
+			unicam->sensor->name);
+
+	ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Unable to register subdev nodes.\n");
+		goto unregister;
+	}
+
+	/*
+	 * Release the initial reference, all references are now owned by the
+	 * video devices.
+	 */
+	unicam_put(unicam);
+	return 0;
+
+unregister:
+	unregister_nodes(unicam);
+	unicam_put(unicam);
+
+	return ret;
+}
+
+static const struct v4l2_async_notifier_operations unicam_async_ops = {
+	.bound = unicam_async_bound,
+	.complete = unicam_async_complete,
+};
+
+static int of_unicam_connect_subdevs(struct unicam_device *dev)
+{
+	struct platform_device *pdev = dev->pdev;
+	struct v4l2_fwnode_endpoint ep = { };
+	struct device_node *ep_node;
+	struct device_node *sensor_node;
+	unsigned int lane;
+	int ret = -EINVAL;
+
+	if (of_property_read_u32(pdev->dev.of_node, "num-data-lanes",
+				 &dev->max_data_lanes) < 0) {
+		dev_err(dev->v4l2_dev.dev, "number of data lanes not set\n");
+		return -EINVAL;
+	}
+
+	/* Get the local endpoint and remote device. */
+	ep_node = of_graph_get_next_endpoint(pdev->dev.of_node, NULL);
+	if (!ep_node) {
+		dev_dbg(dev->v4l2_dev.dev, "can't get next endpoint\n");
+		return -EINVAL;
+	}
+
+	dev_dbg(dev->v4l2_dev.dev, "ep_node is %pOF\n", ep_node);
+
+	sensor_node = of_graph_get_remote_port_parent(ep_node);
+	if (!sensor_node) {
+		dev_dbg(dev->v4l2_dev.dev, "can't get remote parent\n");
+		goto cleanup_exit;
+	}
+
+	dev_dbg(dev->v4l2_dev.dev, "found subdevice %pOF\n", sensor_node);
+
+	/* Parse the local endpoint and validate its configuration. */
+	v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep_node), &ep);
+
+	dev_dbg(dev->v4l2_dev.dev, "parsed local endpoint, bus_type %u\n",
+		ep.bus_type);
+
+	dev->bus_type = ep.bus_type;
+
+	switch (ep.bus_type) {
+	case V4L2_MBUS_CSI2_DPHY:
+		switch (ep.bus.mipi_csi2.num_data_lanes) {
+		case 1:
+		case 2:
+		case 4:
+			break;
+
+		default:
+			dev_err(dev->v4l2_dev.dev, "subdevice %pOF: %u data lanes not supported\n",
+				sensor_node,
+				ep.bus.mipi_csi2.num_data_lanes);
+			goto cleanup_exit;
+		}
+
+		for (lane = 0; lane < ep.bus.mipi_csi2.num_data_lanes; lane++) {
+			if (ep.bus.mipi_csi2.data_lanes[lane] != lane + 1) {
+				dev_err(dev->v4l2_dev.dev, "subdevice %pOF: data lanes reordering not supported\n",
+					sensor_node);
+				goto cleanup_exit;
+			}
+		}
+
+		if (ep.bus.mipi_csi2.num_data_lanes > dev->max_data_lanes) {
+			dev_err(dev->v4l2_dev.dev, "subdevice requires %u data lanes when %u are supported\n",
+				ep.bus.mipi_csi2.num_data_lanes,
+				dev->max_data_lanes);
+		}
+
+		dev->max_data_lanes = ep.bus.mipi_csi2.num_data_lanes;
+		dev->bus_flags = ep.bus.mipi_csi2.flags;
+
+		break;
+
+	case V4L2_MBUS_CCP2:
+		if (ep.bus.mipi_csi1.clock_lane != 0 ||
+		    ep.bus.mipi_csi1.data_lane != 1) {
+			dev_err(dev->v4l2_dev.dev, "subdevice %pOF: unsupported lanes configuration\n",
+				sensor_node);
+			goto cleanup_exit;
+		}
+
+		dev->max_data_lanes = 1;
+		dev->bus_flags = ep.bus.mipi_csi1.strobe;
+		break;
+
+	default:
+		/* Unsupported bus type */
+		dev_err(dev->v4l2_dev.dev, "subdevice %pOF: unsupported bus type %u\n",
+			sensor_node, ep.bus_type);
+		goto cleanup_exit;
+	}
+
+	dev_dbg(dev->v4l2_dev.dev, "subdevice %pOF: %s bus, %u data lanes, flags=0x%08x\n",
+		sensor_node,
+		dev->bus_type == V4L2_MBUS_CSI2_DPHY ? "CSI-2" : "CCP2",
+		dev->max_data_lanes, dev->bus_flags);
+
+	/* Initialize and register the async notifier. */
+	v4l2_async_nf_init(&dev->notifier);
+	dev->notifier.ops = &unicam_async_ops;
+
+	dev->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
+	dev->asd.match.fwnode = fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep_node));
+	ret = v4l2_async_nf_add_subdev(&dev->notifier, &dev->asd);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "Error adding subdevice: %d\n", ret);
+		goto cleanup_exit;
+	}
+
+	ret = v4l2_async_nf_register(&dev->v4l2_dev, &dev->notifier);
+	if (ret) {
+		dev_err(dev->v4l2_dev.dev, "Error registering async notifier: %d\n", ret);
+		ret = -EINVAL;
+	}
+
+cleanup_exit:
+	of_node_put(sensor_node);
+	of_node_put(ep_node);
+
+	return ret;
+}
+
+static int bcm2835_media_dev_init(struct unicam_device *unicam,
+				  struct platform_device *pdev)
+{
+	int ret = 0;
+
+	unicam->mdev.dev = &pdev->dev;
+	strscpy(unicam->mdev.model, UNICAM_MODULE_NAME,
+		sizeof(unicam->mdev.model));
+	strscpy(unicam->mdev.serial, "", sizeof(unicam->mdev.serial));
+	snprintf(unicam->mdev.bus_info, sizeof(unicam->mdev.bus_info),
+		 "platform:%s", dev_name(&pdev->dev));
+	unicam->mdev.hw_revision = 0;
+
+	media_device_init(&unicam->mdev);
+
+	unicam->v4l2_dev.mdev = &unicam->mdev;
+
+	ret = v4l2_device_register(&pdev->dev, &unicam->v4l2_dev);
+
+	return ret;
+}
+
+/* Internal subdev */
+
+static int _unicam_subdev_set_routing(struct v4l2_subdev *sd,
+				      struct v4l2_subdev_state *state,
+				      struct v4l2_subdev_krouting *routing)
+{
+	static const struct v4l2_mbus_framefmt format = {
+		.width = 640,
+		.height = 480,
+		.code = MEDIA_BUS_FMT_UYVY8_2X8,
+		.field = V4L2_FIELD_NONE,
+		.colorspace = V4L2_COLORSPACE_SRGB,
+		.ycbcr_enc = V4L2_YCBCR_ENC_601,
+		.quantization = V4L2_QUANTIZATION_LIM_RANGE,
+		.xfer_func = V4L2_XFER_FUNC_SRGB,
+		.flags = 0,
+	};
+	int ret;
+
+	ret = v4l2_subdev_routing_validate_1_to_1(routing);
+	if (ret)
+		return ret;
+
+	v4l2_subdev_lock_state(state);
+
+	ret = v4l2_subdev_set_routing_with_fmt(sd, state, routing, &format);
+
+	v4l2_subdev_unlock_state(state);
+
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int unicam_subdev_set_routing(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *state,
+				     enum v4l2_subdev_format_whence which,
+				     struct v4l2_subdev_krouting *routing)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+
+	if (which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->streaming)
+		return -EBUSY;
+
+	return _unicam_subdev_set_routing(sd, state, routing);
+}
+
+static int unicam_subdev_init_cfg(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_state *state)
+{
+	struct v4l2_subdev_route routes[] = {
+		{
+			.sink_pad = 0,
+			.sink_stream = 0,
+			.source_pad = 1,
+			.source_stream = 0,
+			.flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+		},
+	};
+
+	struct v4l2_subdev_krouting routing = {
+		.num_routes = ARRAY_SIZE(routes),
+		.routes = routes,
+	};
+
+	/* Initialize routing to single route to the fist source pad */
+	return _unicam_subdev_set_routing(sd, state, &routing);
+}
+
+static int unicam_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					struct v4l2_subdev_mbus_code_enum *code)
+{
+	int ret = 0;
+
+	v4l2_subdev_lock_state(state);
+
+	/* No transcoding, source and sink codes must match. */
+	if (unicam_sd_pad_is_source(code->pad)) {
+		struct v4l2_mbus_framefmt *fmt;
+
+		if (code->index > 0) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fmt = v4l2_subdev_state_get_opposite_stream_format(state,
+								   code->pad,
+								   code->stream);
+		if (!fmt) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		code->code = fmt->code;
+	} else {
+		if (code->index >= ARRAY_SIZE(formats)) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		code->code = formats[code->index].code;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_subdev_start_streaming(struct unicam_device *unicam)
+{
+	const struct v4l2_subdev_krouting *routing;
+	struct v4l2_subdev_state *state;
+	int ret = 0;
+
+	state = v4l2_subdev_lock_active_state(&unicam->sd);
+
+	routing = &state->routing;
+
+	v4l2_subdev_unlock_state(state);
+
+	unicam->streaming = true;
+
+	ret = v4l2_subdev_call(unicam->sensor, video, s_stream, 1);
+	if (ret) {
+		v4l2_subdev_call(unicam->sensor, video, s_stream, 0);
+		unicam->streaming = false;
+		return ret;
+	}
+
+	return 0;
+}
+
+static int unicam_subdev_stop_streaming(struct unicam_device *unicam)
+{
+	v4l2_subdev_call(unicam->sensor, video, s_stream, 0);
+
+	unicam->streaming = false;
+
+	return 0;
+}
+
+static int unicam_subdev_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+
+	if (enable)
+		return unicam_subdev_start_streaming(unicam);
+	else
+		return unicam_subdev_stop_streaming(unicam);
+	return 0;
+}
+
+static int unicam_subdev_set_pad_format(struct v4l2_subdev *sd,
+					struct v4l2_subdev_state *state,
+					struct v4l2_subdev_format *format)
+{
+	struct unicam_device *unicam = sd_to_unicam_device(sd);
+	struct v4l2_mbus_framefmt *fmt;
+	int ret = 0;
+
+	if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE && unicam->streaming)
+		return -EBUSY;
+
+	/* No transcoding, source and sink formats must match. */
+	if (unicam_sd_pad_is_source(format->pad))
+		return v4l2_subdev_get_fmt(sd, state, format);
+
+	// TODO: implement fmt validation
+
+	v4l2_subdev_lock_state(state);
+
+	fmt = v4l2_state_get_stream_format(state, format->pad, format->stream);
+	if (!fmt) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*fmt = format->format;
+
+	fmt = v4l2_subdev_state_get_opposite_stream_format(state, format->pad,
+							   format->stream);
+	if (!fmt) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*fmt = format->format;
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static int unicam_subdev_enum_frame_size(struct v4l2_subdev *sd,
+					 struct v4l2_subdev_state *state,
+					 struct v4l2_subdev_frame_size_enum *fse)
+{
+	const struct unicam_fmt *fmtinfo;
+	int ret = 0;
+
+	if (fse->index > 0)
+		return -EINVAL;
+
+	v4l2_subdev_lock_state(state);
+
+	/* No transcoding, source and sink formats must match. */
+	if (unicam_sd_pad_is_source(fse->pad)) {
+		struct v4l2_mbus_framefmt *fmt;
+
+		fmt = v4l2_subdev_state_get_opposite_stream_format(state,
+								   fse->pad,
+								   fse->stream);
+
+		if (!fmt) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (fse->code != fmt->code) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fse->min_width = fmt->width;
+		fse->max_width = fmt->width;
+		fse->min_height = fmt->height;
+		fse->max_height = fmt->height;
+	} else {
+		fmtinfo = find_format_by_code(fse->code);
+		if (!fmtinfo) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		fse->min_width = MIN_WIDTH * 8 / ALIGN(fmtinfo->depth, 8);
+		fse->max_width = MAX_WIDTH * 8 / ALIGN(fmtinfo->depth, 8);
+		fse->min_height = MIN_HEIGHT;
+		fse->max_height = MAX_HEIGHT;
+	}
+
+out:
+	v4l2_subdev_unlock_state(state);
+
+	return ret;
+}
+
+static const struct v4l2_subdev_video_ops unicam_subdev_video_ops = {
+	.s_stream	= unicam_subdev_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops unicam_subdev_pad_ops = {
+	.init_cfg		= unicam_subdev_init_cfg,
+	.enum_mbus_code		= unicam_subdev_enum_mbus_code,
+	.get_fmt		= v4l2_subdev_get_fmt,
+	.set_fmt		= unicam_subdev_set_pad_format,
+	.set_routing		= unicam_subdev_set_routing,
+	.enum_frame_size	= unicam_subdev_enum_frame_size,
+};
+
+static const struct v4l2_subdev_ops unicam_subdev_ops = {
+	.video		= &unicam_subdev_video_ops,
+	.pad		= &unicam_subdev_pad_ops,
+};
+
+static struct media_entity_operations unicam_subdev_media_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+	.has_route = v4l2_subdev_has_route,
+};
+
+static int unicam_probe(struct platform_device *pdev)
+{
+	struct unicam_device *unicam;
+	int ret = 0;
+	int i;
+
+	unicam = kzalloc(sizeof(*unicam), GFP_KERNEL);
+	if (!unicam)
+		return -ENOMEM;
+
+	kref_init(&unicam->kref);
+	unicam->pdev = pdev;
+
+	unicam->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(unicam->base)) {
+		dev_err(unicam->v4l2_dev.dev, "Failed to get main io block\n");
+		ret = PTR_ERR(unicam->base);
+		goto err_unicam_put;
+	}
+
+	unicam->clk_gate_base = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(unicam->clk_gate_base)) {
+		dev_err(unicam->v4l2_dev.dev, "Failed to get 2nd io block\n");
+		ret = PTR_ERR(unicam->clk_gate_base);
+		goto err_unicam_put;
+	}
+
+	unicam->clock = devm_clk_get(&pdev->dev, "lp");
+	if (IS_ERR(unicam->clock)) {
+		dev_err(unicam->v4l2_dev.dev, "Failed to get lp clock\n");
+		ret = PTR_ERR(unicam->clock);
+		goto err_unicam_put;
+	}
+
+	unicam->vpu_clock = devm_clk_get(&pdev->dev, "vpu");
+	if (IS_ERR(unicam->vpu_clock)) {
+		dev_err(unicam->v4l2_dev.dev, "Failed to get vpu clock\n");
+		ret = PTR_ERR(unicam->vpu_clock);
+		goto err_unicam_put;
+	}
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret <= 0) {
+		dev_err(&pdev->dev, "No IRQ resource\n");
+		ret = -EINVAL;
+		goto err_unicam_put;
+	}
+
+	ret = devm_request_irq(&pdev->dev, ret, unicam_isr, 0,
+			       "unicam_capture0", unicam);
+	if (ret) {
+		dev_err(&pdev->dev, "Unable to request interrupt\n");
+		ret = -EINVAL;
+		goto err_unicam_put;
+	}
+
+	ret = bcm2835_media_dev_init(unicam, pdev);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev,
+			"Unable to register v4l2 device.\n");
+		goto err_unicam_put;
+	}
+
+	ret = media_device_register(&unicam->mdev);
+	if (ret < 0) {
+		dev_err(unicam->v4l2_dev.dev,
+			"Unable to register media-controller device.\n");
+		goto err_v4l2_unregister;
+	}
+
+	/* Reserve space for the controls */
+	ret = v4l2_ctrl_handler_init(&unicam->ctrl_handler, 16);
+	if (ret < 0)
+		goto err_media_unregister;
+
+	/* set the driver data in platform device */
+	platform_set_drvdata(pdev, unicam);
+
+	dev_dbg(unicam->v4l2_dev.dev, "Initialize internal subdev");
+	v4l2_subdev_init(&unicam->sd, &unicam_subdev_ops);
+	v4l2_set_subdevdata(&unicam->sd, unicam);
+	unicam->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	unicam->sd.dev = &pdev->dev;
+	unicam->sd.owner = THIS_MODULE;
+	unicam->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_MULTIPLEXED;
+	snprintf(unicam->sd.name, sizeof(unicam->sd.name), "unicam-subdev");
+
+	unicam->pads[UNICAM_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+
+	for (i = UNICAM_SD_PAD_FIRST_SOURCE; i < UNICAM_SD_NUM_PADS; ++i)
+		unicam->pads[i].flags = MEDIA_PAD_FL_SOURCE;
+	unicam->sd.entity.ops = &unicam_subdev_media_ops;
+	ret = media_entity_pads_init(&unicam->sd.entity,
+				     ARRAY_SIZE(unicam->pads), unicam->pads);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Could not init media controller for subdev");
+		goto err_subdev_unregister;
+	}
+
+	ret = v4l2_subdev_init_finalize(&unicam->sd);
+	if (ret) {
+		dev_err(unicam->v4l2_dev.dev, "Could not finalize init for subdev");
+		goto err_entity_cleanup;
+	}
+
+	ret = v4l2_device_register_subdev(&unicam->v4l2_dev, &unicam->sd);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register internal subdev\n");
+		goto err_subdev_unregister;
+	}
+
+	ret = of_unicam_connect_subdevs(unicam);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to connect subdevs\n");
+		goto err_subdev_unregister;
+	}
+
+	/* Enable the block power domain */
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+err_subdev_unregister:
+	v4l2_subdev_cleanup(&unicam->sd);
+err_entity_cleanup:
+	media_entity_cleanup(&unicam->sd.entity);
+err_media_unregister:
+	media_device_unregister(&unicam->mdev);
+err_v4l2_unregister:
+	v4l2_device_unregister(&unicam->v4l2_dev);
+err_unicam_put:
+	unicam_put(unicam);
+
+	return ret;
+}
+
+static int unicam_remove(struct platform_device *pdev)
+{
+	struct unicam_device *unicam = platform_get_drvdata(pdev);
+
+	v4l2_async_nf_unregister(&unicam->notifier);
+	v4l2_device_unregister(&unicam->v4l2_dev);
+	media_device_unregister(&unicam->mdev);
+	unregister_nodes(unicam);
+
+	pm_runtime_disable(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id unicam_of_match[] = {
+	{ .compatible = "brcm,bcm2835-unicam", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, unicam_of_match);
+
+static struct platform_driver unicam_driver = {
+	.probe		= unicam_probe,
+	.remove		= unicam_remove,
+	.driver = {
+		.name	= UNICAM_MODULE_NAME,
+		.of_match_table = of_match_ptr(unicam_of_match),
+	},
+};
+
+module_platform_driver(unicam_driver);
+
+MODULE_AUTHOR("Dave Stevenson <dave.stevenson at raspberrypi.com>");
+MODULE_DESCRIPTION("BCM2835 Unicam driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(UNICAM_VERSION);
diff --git a/drivers/media/platform/bcm2835/vc4-regs-unicam.h b/drivers/media/platform/bcm2835/vc4-regs-unicam.h
new file mode 100644
index 000000000000..ae059a171d0f
--- /dev/null
+++ b/drivers/media/platform/bcm2835/vc4-regs-unicam.h
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Copyright (C) 2017-2020 Raspberry Pi Trading.
+ * Dave Stevenson <dave.stevenson at raspberrypi.com>
+ */
+
+#ifndef VC4_REGS_UNICAM_H
+#define VC4_REGS_UNICAM_H
+
+/*
+ * The following values are taken from files found within the code drop
+ * made by Broadcom for the BCM21553 Graphics Driver, predominantly in
+ * brcm_usrlib/dag/vmcsx/vcinclude/hardware_vc4.h.
+ * They have been modified to be only the register offset.
+ */
+#define UNICAM_CTRL	0x000
+#define UNICAM_STA	0x004
+#define UNICAM_ANA	0x008
+#define UNICAM_PRI	0x00c
+#define UNICAM_CLK	0x010
+#define UNICAM_CLT	0x014
+#define UNICAM_DAT0	0x018
+#define UNICAM_DAT1	0x01c
+#define UNICAM_DAT2	0x020
+#define UNICAM_DAT3	0x024
+#define UNICAM_DLT	0x028
+#define UNICAM_CMP0	0x02c
+#define UNICAM_CMP1	0x030
+#define UNICAM_CAP0	0x034
+#define UNICAM_CAP1	0x038
+#define UNICAM_ICTL	0x100
+#define UNICAM_ISTA	0x104
+#define UNICAM_IDI0	0x108
+#define UNICAM_IPIPE	0x10c
+#define UNICAM_IBSA0	0x110
+#define UNICAM_IBEA0	0x114
+#define UNICAM_IBLS	0x118
+#define UNICAM_IBWP	0x11c
+#define UNICAM_IHWIN	0x120
+#define UNICAM_IHSTA	0x124
+#define UNICAM_IVWIN	0x128
+#define UNICAM_IVSTA	0x12c
+#define UNICAM_ICC	0x130
+#define UNICAM_ICS	0x134
+#define UNICAM_IDC	0x138
+#define UNICAM_IDPO	0x13c
+#define UNICAM_IDCA	0x140
+#define UNICAM_IDCD	0x144
+#define UNICAM_IDS	0x148
+#define UNICAM_DCS	0x200
+#define UNICAM_DBSA0	0x204
+#define UNICAM_DBEA0	0x208
+#define UNICAM_DBWP	0x20c
+#define UNICAM_DBCTL	0x300
+#define UNICAM_IBSA1	0x304
+#define UNICAM_IBEA1	0x308
+#define UNICAM_IDI1	0x30c
+#define UNICAM_DBSA1	0x310
+#define UNICAM_DBEA1	0x314
+#define UNICAM_MISC	0x400
+
+/*
+ * The following bitmasks are from the kernel released by Broadcom
+ * for Android - https://android.googlesource.com/kernel/bcm/
+ * The Rhea, Hawaii, and Java chips all contain the same VideoCore4
+ * Unicam block as BCM2835, as defined in eg
+ * arch/arm/mach-rhea/include/mach/rdb_A0/brcm_rdb_cam.h and similar.
+ * Values reworked to use the kernel BIT and GENMASK macros.
+ *
+ * Some of the bit mnenomics have been amended to match the datasheet.
+ */
+/* UNICAM_CTRL Register */
+#define UNICAM_CPE		BIT(0)
+#define UNICAM_MEM		BIT(1)
+#define UNICAM_CPR		BIT(2)
+#define UNICAM_CPM_MASK		GENMASK(3, 3)
+#define UNICAM_CPM_CSI2		0
+#define UNICAM_CPM_CCP2		1
+#define UNICAM_SOE		BIT(4)
+#define UNICAM_DCM_MASK		GENMASK(5, 5)
+#define UNICAM_DCM_STROBE	0
+#define UNICAM_DCM_DATA		1
+#define UNICAM_SLS		BIT(6)
+#define UNICAM_PFT_MASK		GENMASK(11, 8)
+#define UNICAM_OET_MASK		GENMASK(20, 12)
+
+/* UNICAM_STA Register */
+#define UNICAM_SYN		BIT(0)
+#define UNICAM_CS		BIT(1)
+#define UNICAM_SBE		BIT(2)
+#define UNICAM_PBE		BIT(3)
+#define UNICAM_HOE		BIT(4)
+#define UNICAM_PLE		BIT(5)
+#define UNICAM_SSC		BIT(6)
+#define UNICAM_CRCE		BIT(7)
+#define UNICAM_OES		BIT(8)
+#define UNICAM_IFO		BIT(9)
+#define UNICAM_OFO		BIT(10)
+#define UNICAM_BFO		BIT(11)
+#define UNICAM_DL		BIT(12)
+#define UNICAM_PS		BIT(13)
+#define UNICAM_IS		BIT(14)
+#define UNICAM_PI0		BIT(15)
+#define UNICAM_PI1		BIT(16)
+#define UNICAM_FSI_S		BIT(17)
+#define UNICAM_FEI_S		BIT(18)
+#define UNICAM_LCI_S		BIT(19)
+#define UNICAM_BUF0_RDY		BIT(20)
+#define UNICAM_BUF0_NO		BIT(21)
+#define UNICAM_BUF1_RDY		BIT(22)
+#define UNICAM_BUF1_NO		BIT(23)
+#define UNICAM_DI		BIT(24)
+
+#define UNICAM_STA_MASK_ALL \
+		(UNICAM_DL + \
+		UNICAM_SBE + \
+		UNICAM_PBE + \
+		UNICAM_HOE + \
+		UNICAM_PLE + \
+		UNICAM_SSC + \
+		UNICAM_CRCE + \
+		UNICAM_IFO + \
+		UNICAM_OFO + \
+		UNICAM_PS + \
+		UNICAM_PI0 + \
+		UNICAM_PI1)
+
+/* UNICAM_ANA Register */
+#define UNICAM_APD		BIT(0)
+#define UNICAM_BPD		BIT(1)
+#define UNICAM_AR		BIT(2)
+#define UNICAM_DDL		BIT(3)
+#define UNICAM_CTATADJ_MASK	GENMASK(7, 4)
+#define UNICAM_PTATADJ_MASK	GENMASK(11, 8)
+
+/* UNICAM_PRI Register */
+#define UNICAM_PE		BIT(0)
+#define UNICAM_PT_MASK		GENMASK(2, 1)
+#define UNICAM_NP_MASK		GENMASK(7, 4)
+#define UNICAM_PP_MASK		GENMASK(11, 8)
+#define UNICAM_BS_MASK		GENMASK(15, 12)
+#define UNICAM_BL_MASK		GENMASK(17, 16)
+
+/* UNICAM_CLK Register */
+#define UNICAM_CLE		BIT(0)
+#define UNICAM_CLPD		BIT(1)
+#define UNICAM_CLLPE		BIT(2)
+#define UNICAM_CLHSE		BIT(3)
+#define UNICAM_CLTRE		BIT(4)
+#define UNICAM_CLAC_MASK	GENMASK(8, 5)
+#define UNICAM_CLSTE		BIT(29)
+
+/* UNICAM_CLT Register */
+#define UNICAM_CLT1_MASK	GENMASK(7, 0)
+#define UNICAM_CLT2_MASK	GENMASK(15, 8)
+
+/* UNICAM_DATn Registers */
+#define UNICAM_DLE		BIT(0)
+#define UNICAM_DLPD		BIT(1)
+#define UNICAM_DLLPE		BIT(2)
+#define UNICAM_DLHSE		BIT(3)
+#define UNICAM_DLTRE		BIT(4)
+#define UNICAM_DLSM		BIT(5)
+#define UNICAM_DLFO		BIT(28)
+#define UNICAM_DLSTE		BIT(29)
+
+#define UNICAM_DAT_MASK_ALL (UNICAM_DLSTE + UNICAM_DLFO)
+
+/* UNICAM_DLT Register */
+#define UNICAM_DLT1_MASK	GENMASK(7, 0)
+#define UNICAM_DLT2_MASK	GENMASK(15, 8)
+#define UNICAM_DLT3_MASK	GENMASK(23, 16)
+
+/* UNICAM_ICTL Register */
+#define UNICAM_FSIE		BIT(0)
+#define UNICAM_FEIE		BIT(1)
+#define UNICAM_IBOB		BIT(2)
+#define UNICAM_FCM		BIT(3)
+#define UNICAM_TFC		BIT(4)
+#define UNICAM_LIP_MASK		GENMASK(6, 5)
+#define UNICAM_LCIE_MASK	GENMASK(28, 16)
+
+/* UNICAM_IDI0/1 Register */
+#define UNICAM_ID0_MASK		GENMASK(7, 0)
+#define UNICAM_ID1_MASK		GENMASK(15, 8)
+#define UNICAM_ID2_MASK		GENMASK(23, 16)
+#define UNICAM_ID3_MASK		GENMASK(31, 24)
+
+/* UNICAM_ISTA Register */
+#define UNICAM_FSI		BIT(0)
+#define UNICAM_FEI		BIT(1)
+#define UNICAM_LCI		BIT(2)
+
+#define UNICAM_ISTA_MASK_ALL (UNICAM_FSI + UNICAM_FEI + UNICAM_LCI)
+
+/* UNICAM_IPIPE Register */
+#define UNICAM_PUM_MASK		GENMASK(2, 0)
+		/* Unpacking modes */
+		#define UNICAM_PUM_NONE		0
+		#define UNICAM_PUM_UNPACK6	1
+		#define UNICAM_PUM_UNPACK7	2
+		#define UNICAM_PUM_UNPACK8	3
+		#define UNICAM_PUM_UNPACK10	4
+		#define UNICAM_PUM_UNPACK12	5
+		#define UNICAM_PUM_UNPACK14	6
+		#define UNICAM_PUM_UNPACK16	7
+#define UNICAM_DDM_MASK		GENMASK(6, 3)
+#define UNICAM_PPM_MASK		GENMASK(9, 7)
+		/* Packing modes */
+		#define UNICAM_PPM_NONE		0
+		#define UNICAM_PPM_PACK8	1
+		#define UNICAM_PPM_PACK10	2
+		#define UNICAM_PPM_PACK12	3
+		#define UNICAM_PPM_PACK14	4
+		#define UNICAM_PPM_PACK16	5
+#define UNICAM_DEM_MASK		GENMASK(11, 10)
+#define UNICAM_DEBL_MASK	GENMASK(14, 12)
+#define UNICAM_ICM_MASK		GENMASK(16, 15)
+#define UNICAM_IDM_MASK		GENMASK(17, 17)
+
+/* UNICAM_ICC Register */
+#define UNICAM_ICFL_MASK	GENMASK(4, 0)
+#define UNICAM_ICFH_MASK	GENMASK(9, 5)
+#define UNICAM_ICST_MASK	GENMASK(12, 10)
+#define UNICAM_ICLT_MASK	GENMASK(15, 13)
+#define UNICAM_ICLL_MASK	GENMASK(31, 16)
+
+/* UNICAM_DCS Register */
+#define UNICAM_DIE		BIT(0)
+#define UNICAM_DIM		BIT(1)
+#define UNICAM_DBOB		BIT(3)
+#define UNICAM_FDE		BIT(4)
+#define UNICAM_LDP		BIT(5)
+#define UNICAM_EDL_MASK		GENMASK(15, 8)
+
+/* UNICAM_DBCTL Register */
+#define UNICAM_DBEN		BIT(0)
+#define UNICAM_BUF0_IE		BIT(1)
+#define UNICAM_BUF1_IE		BIT(2)
+
+/* UNICAM_CMP[0,1] register */
+#define UNICAM_PCE		BIT(31)
+#define UNICAM_GI		BIT(9)
+#define UNICAM_CPH		BIT(8)
+#define UNICAM_PCVC_MASK	GENMASK(7, 6)
+#define UNICAM_PCDT_MASK	GENMASK(5, 0)
+
+/* UNICAM_MISC register */
+#define UNICAM_FL0		BIT(6)
+#define UNICAM_FL1		BIT(9)
+
+#endif
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Fri Jan 21 00:26:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 09:26:01 +0100
Subject: [RFC 1/3] dt-bindings: iommu: Add bindings for samsung,sysmmu-v8
In-Reply-To: <20220120201958.2649-2-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
 <20220120201958.2649-2-semen.protsenko@linaro.org>
Message-ID: <9a006308-cabb-7ee2-0556-860d425b251f@canonical.com>

On 20/01/2022 21:19, Sam Protsenko wrote:
> Only example of usage and header for now.
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  .../bindings/iommu/samsung,sysmmu-v8.txt      | 31 +++++++++++++

Please, don't copy paste bindings or entire drviers from vendor kernel.
It looks very bad. Instead, submit them in dtschema.

NAK.

>  include/dt-bindings/soc/samsung,sysmmu-v8.h   | 43 +++++++++++++++++++
>  2 files changed, 74 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
>  create mode 100644 include/dt-bindings/soc/samsung,sysmmu-v8.h
> 
> diff --git a/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt b/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
> new file mode 100644
> index 000000000000..d6004ea4a746
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iommu/samsung,sysmmu-v8.txt
> @@ -0,0 +1,31 @@
> +Example (Exynos850, IOMMU for DPU usage):
> +
> +	#include <dt-bindings/soc/samsung,sysmmu-v8.h>
> +
> +	/* IOMMU group info */
> +	iommu_group_dpu: iommu_group_dpu {
> +		compatible = "samsung,sysmmu-group";
> +	};
> +
> +	sysmmu_dpu: sysmmu at 130c0000 {
> +		compatible = "samsung,sysmmu-v8";
> +		reg = <0x130c0000 0x9000>;
> +		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
> +		qos = <15>;
> +
> +		clocks = <&cmu_dpu CLK_GOUT_DPU_SMMU_CLK>;
> +		clock-names = "gate";
> +
> +		sysmmu,secure-irq;
> +		sysmmu,secure_base = <0x130d0000>;
> +		sysmmu,default_tlb = <TLB_CFG(BL1, PREFETCH_PREDICTION)>;
> +		sysmmu,tlb_property =
> +			<1 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x2, 0xF)>,
> +			<2 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x4, 0xF)>,
> +			<3 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x6, 0xF)>,
> +			<4 TLB_CFG(BL1, PREFETCH_PREDICTION) (DIR_READ | (1 << 16)) SYSMMU_ID_MASK(0x8, 0xF)>;
> +		port-name = "DPU";
> +		#iommu-cells = <0>;
> +		//power-domains = <&pd_dpu>;

We try not to store dead code in kernel.



Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Fri Jan 21 00:35:11 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 09:35:11 +0100
Subject: [RFC 0/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
In-Reply-To: <20220120201958.2649-1-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
Message-ID: <32a92895-d724-c1bf-4eab-15c971625cf0@canonical.com>

On 20/01/2022 21:19, Sam Protsenko wrote:
> This is a draft of a new IOMMU driver used in modern Exynos SoCs (like
> Exynos850) and Google's GS101 SoC (used in Pixel 6 phone). Most of its
> code were taken from GS101 downstream kernel [1], with some extra
> patches on top (fixes from Exynos850 downstream kernel and some porting
> changes to adapt it to the mainline kernel). All development history can
> be found at [2].
> 
> Similarities with existing exynos-iommu.c is minimal. I did some
> analysis using similarity-tester tool:
> 
> 8<-------------------------------------------------------------------->8
>     $ sim_c -peu -S exynos-iommu.c "|" samsung-*
> 
>     exynos-iommu.c consists for 15 % of samsung-iommu.c material
>     exynos-iommu.c consists for 1 %  of samsung-iommu-fault.c material
>     exynos-iommu.c consists for 3 %  of samsung-iommu.h material
> 8<-------------------------------------------------------------------->8
> 
> So the similarity is very low, most of that code is some boilerplate
> that shouldn't be extracted to common code (like allocating the memory
> and requesting clocks/interrupts in probe function).

This is not a prove of lack of similarities. The vendor drivers have
proven track of poor quality and a lot of code not compatible with Linux
kernel style.

Therefore comparing mainline driver, reviewed and well tested, with a
vendor out-of-tree driver is wrong. You will almost always have 0% of
similarities, because vendor kernel drivers are mostly developed from
scratch instead of re-using existing drivers.

Recently Samsung admitted it - if I extend existing driver, I will have
to test old and new platform, so it is easier for me to write a new driver.

No, this is not that approach we use it in mainline.

Linaro should know it much better.

> 
> It was tested on v5.4 Android kernel on Exynos850 (E850-96 board) with
> DPU use-case (displaying some graphics to the screen). Also it
> apparently works fine on v5.10 GS101 kernel (on Pixel 6). On mainline
> kernel I managed to build, match and bind the driver. No real world test
> was done, but the changes from v5.10 (where it works fine) are minimal
> (see [2] for details). So I'm pretty sure the driver is functional.

No, we do not take untested code or code for different out-of-tree
kernels, not for mainline.

I am pretty sure drivers is poor or not working.

> 
> For this patch series I'd like to receive some high-level review for
> driver's design and architecture. Coding style and API issues I can fix
> later, when sending real (not RFC) series. Particularly I'd like to hear
> some opinions about:
>   - namings: Kconfig option, file names, module name, compatible, etc
>   - modularity: should this driver be a different platform driver (like
>     in this series), or should it be integrated into existing
>     exynos-iommu.c driver somehow
>   - dt-bindings: does it look ok as it is, or some interface changes are
>     needed

You sent bindings in TXT with dead code inside, and you ask if it is ok.
I consider this approach that you sent whatever junk to us hoping that
we will point all the issues instead of finding them by yourself.

I am pretty sure you have several folks in Linaro who can perform first
review and bring the code closer to mainline style.


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Fri Jan 21 00:40:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 09:40:21 +0100
Subject: [RFC 2/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
In-Reply-To: <20220120201958.2649-3-semen.protsenko@linaro.org>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
 <20220120201958.2649-3-semen.protsenko@linaro.org>
Message-ID: <a111932a-6685-2a9d-abce-87af26b121a4@canonical.com>

On 20/01/2022 21:19, Sam Protsenko wrote:
> Introduce new driver for modern Exynos ARMv8 SoCs, e.g. Exynos850. Also
> it's used for Google's GS101 SoC.
> 
> This is squashed commit, contains next patches of different authors. See
> `iommu-exynos850-dev' branch for details: [1].
> 
> Original authors (Samsung):
> 
>  - Cho KyongHo <pullip.cho at samsung.com>
>  - Hyesoo Yu <hyesoo.yu at samsung.com>
>  - Janghyuck Kim <janghyuck.kim at samsung.com>
>  - Jinkyu Yang <jinkyu1.yang at samsung.com>
> 
> Some improvements were made by Google engineers:
> 
>  - Alex <acnwigwe at google.com>
>  - Carlos Llamas <cmllamas at google.com>
>  - Daniel Mentz <danielmentz at google.com>
>  - Erick Reyes <erickreyes at google.com>
>  - J. Avila <elavila at google.com>
>  - Jonglin Lee <jonglin at google.com>
>  - Mark Salyzyn <salyzyn at google.com>
>  - Thierry Strudel <tstrudel at google.com>
>  - Will McVicker <willmcvicker at google.com>
> 
> [1] https://github.com/joe-skb7/linux/tree/iommu-exynos850-dev
> 
> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> ---
>  drivers/iommu/Kconfig               |   13 +
>  drivers/iommu/Makefile              |    3 +
>  drivers/iommu/samsung-iommu-fault.c |  617 +++++++++++
>  drivers/iommu/samsung-iommu-group.c |   50 +
>  drivers/iommu/samsung-iommu.c       | 1521 +++++++++++++++++++++++++++
>  drivers/iommu/samsung-iommu.h       |  216 ++++
>  6 files changed, 2420 insertions(+)
>  create mode 100644 drivers/iommu/samsung-iommu-fault.c
>  create mode 100644 drivers/iommu/samsung-iommu-group.c
>  create mode 100644 drivers/iommu/samsung-iommu.c
>  create mode 100644 drivers/iommu/samsung-iommu.h
> 

Existing driver supports several different Exynos SysMMU IP block
versions. Several. Please explain why it cannot support one more version?

Similarity of vendor driver with mainline is not an argument.


> diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> index 3eb68fa1b8cc..78e7039f18aa 100644
> --- a/drivers/iommu/Kconfig
> +++ b/drivers/iommu/Kconfig
> @@ -452,6 +452,19 @@ config QCOM_IOMMU
>  	help
>  	  Support for IOMMU on certain Qualcomm SoCs.
>  
> +config SAMSUNG_IOMMU
> +	tristate "Samsung IOMMU Support"
> +	select ARM_DMA_USE_IOMMU
> +	select IOMMU_DMA
> +	select SAMSUNG_IOMMU_GROUP
> +	help
> +	  Support for IOMMU on Samsung Exynos SoCs.
> +
> +config SAMSUNG_IOMMU_GROUP
> +	tristate "Samsung IOMMU Group Support"
> +	help
> +	  Support for IOMMU group on Samsung Exynos SoCs.
> +
>  config HYPERV_IOMMU
>  	bool "Hyper-V x2APIC IRQ Handling"
>  	depends on HYPERV && X86
> diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> index bc7f730edbb0..a8bdf449f1d4 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -27,6 +27,9 @@ obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
>  obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
>  obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
>  obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
> +obj-$(CONFIG_SAMSUNG_IOMMU) += samsung_iommu.o
> +samsung_iommu-objs += samsung-iommu.o samsung-iommu-fault.o
> +obj-$(CONFIG_SAMSUNG_IOMMU_GROUP) += samsung-iommu-group.o
>  obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o
>  obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
>  obj-$(CONFIG_APPLE_DART) += apple-dart.o
> diff --git a/drivers/iommu/samsung-iommu-fault.c b/drivers/iommu/samsung-iommu-fault.c
> new file mode 100644
> index 000000000000..c6b4259976c4
> --- /dev/null
> +++ b/drivers/iommu/samsung-iommu-fault.c
> @@ -0,0 +1,617 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> + */
> +
> +#define pr_fmt(fmt) "sysmmu: " fmt
> +
> +#include <linux/smc.h>
> +#include <linux/arm-smccc.h>
> +#include <linux/pm_runtime.h>
> +
> +#include "samsung-iommu.h"
> +
> +#define MMU_TLB_INFO(n)			(0x2000 + ((n) * 0x20))
> +#define MMU_CAPA1_NUM_TLB_SET(reg)	(((reg) >> 16) & 0xFF)
> +#define MMU_CAPA1_NUM_TLB_WAY(reg)	((reg) & 0xFF)
> +#define MMU_CAPA1_SET_TLB_READ_ENTRY(tid, set, way, line)		\
> +					((set) | ((way) << 8) |		\
> +					 ((line) << 16) | ((tid) << 20))
> +
> +#define MMU_TLB_ENTRY_VALID(reg)	((reg) >> 28)
> +#define MMU_SBB_ENTRY_VALID(reg)	((reg) >> 28)
> +#define MMU_VADDR_FROM_TLB(reg, idx)	((((reg) & 0xFFFFC) | ((idx) & 0x3)) << 12)
> +#define MMU_VID_FROM_TLB(reg)		(((reg) >> 20) & 0x7U)
> +#define MMU_PADDR_FROM_TLB(reg)		((phys_addr_t)((reg) & 0xFFFFFF) << 12)
> +#define MMU_VADDR_FROM_SBB(reg)		(((reg) & 0xFFFFF) << 12)
> +#define MMU_VID_FROM_SBB(reg)		(((reg) >> 20) & 0x7U)
> +#define MMU_PADDR_FROM_SBB(reg)		((phys_addr_t)((reg) & 0x3FFFFFF) << 10)
> +
> +#define REG_MMU_INT_STATUS		0x060
> +#define REG_MMU_INT_CLEAR		0x064
> +#define REG_MMU_FAULT_RW_MASK		GENMASK(20, 20)
> +#define IS_READ_FAULT(x)		(((x) & REG_MMU_FAULT_RW_MASK) == 0)
> +
> +#define SYSMMU_FAULT_PTW_ACCESS   0
> +#define SYSMMU_FAULT_PAGE_FAULT   1
> +#define SYSMMU_FAULT_ACCESS       2
> +#define SYSMMU_FAULT_RESERVED     3
> +#define SYSMMU_FAULT_UNKNOWN      4
> +
> +#define SYSMMU_SEC_FAULT_MASK		(BIT(SYSMMU_FAULT_PTW_ACCESS) | \
> +					 BIT(SYSMMU_FAULT_PAGE_FAULT) | \
> +					 BIT(SYSMMU_FAULT_ACCESS))
> +
> +#define SYSMMU_FAULTS_NUM         (SYSMMU_FAULT_UNKNOWN + 1)
> +
> +#if IS_ENABLED(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION)

You just copy-pasted vendor stuff, without actually going through it.

It is very disappointing because instead of putting your own effort, you
expect community to do your job.

What the hell is CONFIG_EXYNOS_CONTENT_PATH_PROTECTION?

I'll stop reviewing. Please work on extending existing driver. If you
submitted something nice and clean, ready for upstream, instead of
vendor junk, you could get away with separate driver. But you did not.
It looks really bad.

Best regards,
Krzysztof


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:03 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:03 +0000
Subject: [PATCH v7 00/14] Convert powerpc to default topdown mmap layout
Message-ID: <cover.1642752946.git.christophe.leroy@csgroup.eu>

Rebased on top of powerpc/next branch

This series converts powerpc to default topdown mmap layout.

powerpc requires its own arch_get_unmapped_area() only when
slices are needed, which is only for book3s/64. First part of
the series moves slices into book3s/64 specific directories
and cleans up other subarchitectures.

Last part converts to default topdown mmap layout.

A small modification is done to core mm to allow
powerpc to still provide its own arch_randomize_brk()

Another modification is done to core mm to allow powerpc
to use generic versions of get_unmapped_area functions for Radix
while still providing its own implementation for Hash, the
selection between Radix and Hash being doing at runtime.

Last modification to core mm is to give len and flags to
arch_get_mmap_end().

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>

Changes in v7:
- Taken into account comments from Catalin (patches 3 and 4)

Changes in v6:
- New patch (patch 4) to take arch_get_mmap_base() and arch_get_mmap_end() into account in generic hugetlb_get_unmapped_area()
- Get back arch_randomize_brk() simplification as it relies on default topdown mmap layout.
- Fixed precedence between || and && in powerpc's arch_get_mmap_end() (patch 9)

Changes in v5:
- Added patch 3
- Added arch_get_mmap_base() and arch_get_mmap_end() to patch 7 to better match original powerpc behaviour
- Switched patched 10 and 11 and performed full randomisation in patch 10 just before switching to default implementation, as suggested by Nic.

Changes in v4:
- Move arch_randomize_brk() simplification out of this series
- Add a change to core mm to enable using generic implementation
while providing arch specific one at the same time.
- Reworked radix get_unmapped_area to use generic implementation
- Rebase on top of Nic's series v6

Changes in v3:
- Fixed missing <linux/elf-randomize.h> in last patch
- Added a patch to move SZ_1T out of drivers/pci/controller/pci-xgene.c

Changes in v2:
- Moved patch 4 before patch 2
- Make generic arch_randomize_brk() __weak
- Added patch 9

Christophe Leroy (14):
  mm: Allow arch specific arch_randomize_brk() with
    CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
  mm, hugetlbfs: Allow an arch to always use generic versions of
    get_unmapped_area functions
  mm: Add len and flags parameters to arch_get_mmap_end()
  mm, hugetlbfs: Allow for "high" userspace addresses
  sizes.h: Add SZ_1T macro
  powerpc/mm: Move vma_mmu_pagesize()
  powerpc/mm: Make slice specific to book3s/64
  powerpc/mm: Remove CONFIG_PPC_MM_SLICES
  powerpc/mm: Use generic_get_unmapped_area() and call it from
    arch_get_unmapped_area()
  powerpc/mm: Use generic_hugetlb_get_unmapped_area()
  powerpc/mm: Move get_unmapped_area functions to slice.c
  powerpc/mm: Enable full randomisation of memory mappings
  powerpc/mm: Convert to default topdown mmap layout
  powerpc: Simplify and move arch_randomize_brk()

 arch/arm64/include/asm/processor.h            |   4 +-
 arch/powerpc/Kconfig                          |   2 +-
 arch/powerpc/include/asm/book3s/64/hugetlb.h  |   4 -
 arch/powerpc/include/asm/book3s/64/mmu-hash.h |   1 +
 arch/powerpc/include/asm/book3s/64/mmu.h      |   6 -
 arch/powerpc/include/asm/book3s/64/slice.h    |  24 ++
 arch/powerpc/include/asm/hugetlb.h            |   2 +-
 arch/powerpc/include/asm/paca.h               |   7 -
 arch/powerpc/include/asm/page.h               |   1 -
 arch/powerpc/include/asm/processor.h          |   2 -
 arch/powerpc/include/asm/slice.h              |  46 ----
 arch/powerpc/include/asm/task_size_64.h       |   8 +
 arch/powerpc/kernel/paca.c                    |   5 -
 arch/powerpc/kernel/process.c                 |  41 ---
 arch/powerpc/mm/Makefile                      |   3 +-
 arch/powerpc/mm/book3s64/Makefile             |   2 +-
 arch/powerpc/mm/book3s64/hash_utils.c         |  33 ++-
 arch/powerpc/mm/book3s64/radix_hugetlbpage.c  |  55 ----
 arch/powerpc/mm/{ => book3s64}/slice.c        |  71 ++++-
 arch/powerpc/mm/hugetlbpage.c                 |  34 ---
 arch/powerpc/mm/mmap.c                        | 256 ------------------
 arch/powerpc/mm/nohash/mmu_context.c          |   9 -
 arch/powerpc/mm/nohash/tlb.c                  |   4 -
 arch/powerpc/platforms/Kconfig.cputype        |   4 -
 drivers/pci/controller/pci-xgene.c            |   1 -
 fs/hugetlbfs/inode.c                          |  26 +-
 include/linux/hugetlb.h                       |   5 +
 include/linux/sched/mm.h                      |  17 ++
 include/linux/sizes.h                         |   2 +
 mm/mmap.c                                     |  43 +--
 mm/util.c                                     |   2 +-
 31 files changed, 185 insertions(+), 535 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/slice.h
 rename arch/powerpc/mm/{ => book3s64}/slice.c (91%)
 delete mode 100644 arch/powerpc/mm/mmap.c

-- 
2.33.1

From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:08 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:08 +0000
Subject: [PATCH v7 01/14] mm: Allow arch specific arch_randomize_brk() with
 CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <da994d318af0602fe8facf770556e5fcb32a61ba.1642752946.git.christophe.leroy@csgroup.eu>

Commit e7142bf5d231 ("arm64, mm: make randomization selected by
generic topdown mmap layout") introduced a default version of
arch_randomize_brk() provided when
CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT is selected.

powerpc could select CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
but needs to provide its own arch_randomize_brk().

In order to allow that, define generic version of arch_randomize_brk()
as a __weak symbol.

Cc: Alexandre Ghiti <alex at ghiti.fr>
Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 mm/util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/util.c b/mm/util.c
index 741ba32a43ac..46d1a2dd7a32 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -344,7 +344,7 @@ unsigned long randomize_stack_top(unsigned long stack_top)
 }
 
 #ifdef CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
-unsigned long arch_randomize_brk(struct mm_struct *mm)
+unsigned long __weak arch_randomize_brk(struct mm_struct *mm)
 {
 	/* Is the current task 32bit ? */
 	if (!IS_ENABLED(CONFIG_64BIT) || is_compat_task())
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:12 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:12 +0000
Subject: [PATCH v7 02/14] mm, hugetlbfs: Allow an arch to always use generic
 versions of get_unmapped_area functions
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <a2da430c521ff6a6254f17623f2610ff4f1866e4.1642752946.git.christophe.leroy@csgroup.eu>

Unlike most architectures, powerpc can only define at runtime
if it is going to use the generic arch_get_unmapped_area() or not.

Today, powerpc has a copy of the generic arch_get_unmapped_area()
because when selection HAVE_ARCH_UNMAPPED_AREA the generic
arch_get_unmapped_area() is not available.

Rename it generic_get_unmapped_area() and make it independent of
HAVE_ARCH_UNMAPPED_AREA.

Do the same for arch_get_unmapped_area_topdown() versus
HAVE_ARCH_UNMAPPED_AREA_TOPDOWN.

Do the same for hugetlb_get_unmapped_area() versus
HAVE_ARCH_HUGETLB_UNMAPPED_AREA.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
---
 fs/hugetlbfs/inode.c     | 17 +++++++++++++----
 include/linux/hugetlb.h  |  5 +++++
 include/linux/sched/mm.h |  9 +++++++++
 mm/mmap.c                | 31 ++++++++++++++++++++++++-------
 4 files changed, 51 insertions(+), 11 deletions(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 49d2e686be74..c7cde4e5924d 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -195,7 +195,6 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
  * Called under mmap_write_lock(mm).
  */
 
-#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 static unsigned long
 hugetlb_get_unmapped_area_bottomup(struct file *file, unsigned long addr,
 		unsigned long len, unsigned long pgoff, unsigned long flags)
@@ -244,9 +243,10 @@ hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr,
 	return addr;
 }
 
-static unsigned long
-hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-		unsigned long len, unsigned long pgoff, unsigned long flags)
+unsigned long
+generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
@@ -282,6 +282,15 @@ hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 	return hugetlb_get_unmapped_area_bottomup(file, addr, len,
 			pgoff, flags);
 }
+
+#ifndef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+static unsigned long
+hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+			  unsigned long len, unsigned long pgoff,
+			  unsigned long flags)
+{
+	return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
+}
 #endif
 
 static size_t
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 00351ccb49a3..df899d1937ff 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -513,6 +513,11 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 					unsigned long flags);
 #endif /* HAVE_ARCH_HUGETLB_UNMAPPED_AREA */
 
+unsigned long
+generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags);
+
 /*
  * huegtlb page specific state flags.  These flags are located in page.private
  * of the hugetlb head page.  Functions created via the below macros should be
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index aca874d33fe6..2584f7c13f69 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -144,6 +144,15 @@ extern unsigned long
 arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 			  unsigned long len, unsigned long pgoff,
 			  unsigned long flags);
+
+unsigned long
+generic_get_unmapped_area(struct file *filp, unsigned long addr,
+			  unsigned long len, unsigned long pgoff,
+			  unsigned long flags);
+unsigned long
+generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags);
 #else
 static inline void arch_pick_mmap_layout(struct mm_struct *mm,
 					 struct rlimit *rlim_stack) {}
diff --git a/mm/mmap.c b/mm/mmap.c
index bfb0ea164a90..7ac6a07ff382 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2131,10 +2131,10 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
  *
  * This function "knows" that -ENOMEM has the bits set.
  */
-#ifndef HAVE_ARCH_UNMAPPED_AREA
 unsigned long
-arch_get_unmapped_area(struct file *filp, unsigned long addr,
-		unsigned long len, unsigned long pgoff, unsigned long flags)
+generic_get_unmapped_area(struct file *filp, unsigned long addr,
+			  unsigned long len, unsigned long pgoff,
+			  unsigned long flags)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma, *prev;
@@ -2164,17 +2164,25 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
 }
+
+#ifndef HAVE_ARCH_UNMAPPED_AREA
+unsigned long
+arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		       unsigned long len, unsigned long pgoff,
+		       unsigned long flags)
+{
+	return generic_get_unmapped_area(filp, addr, len, pgoff, flags);
+}
 #endif
 
 /*
  * This mmap-allocator allocates new areas top-down from below the
  * stack's low limit (the base):
  */
-#ifndef HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
 unsigned long
-arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
-			  unsigned long len, unsigned long pgoff,
-			  unsigned long flags)
+generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
+				  unsigned long len, unsigned long pgoff,
+				  unsigned long flags)
 {
 	struct vm_area_struct *vma, *prev;
 	struct mm_struct *mm = current->mm;
@@ -2222,6 +2230,15 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 
 	return addr;
 }
+
+#ifndef HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+unsigned long
+arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
+			       unsigned long len, unsigned long pgoff,
+			       unsigned long flags)
+{
+	return generic_get_unmapped_area_topdown(filp, addr, len, pgoff, flags);
+}
 #endif
 
 unsigned long
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:18 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:18 +0000
Subject: [PATCH v7 04/14] mm, hugetlbfs: Allow for "high" userspace addresses
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <6c95091eab9f58cee58da3762a4dc4c56ab700e7.1642752946.git.christophe.leroy@csgroup.eu>

This is a complement of f6795053dac8 ("mm: mmap: Allow for "high"
userspace addresses") for hugetlb.

This patch adds support for "high" userspace addresses that are
optionally supported on the system and have to be requested via a hint
mechanism ("high" addr parameter to mmap).

Architectures such as powerpc and x86 achieve this by making changes to
their architectural versions of hugetlb_get_unmapped_area() function.
However, arm64 uses the generic version of that function.

So take into account arch_get_mmap_base() and arch_get_mmap_end() in
hugetlb_get_unmapped_area(). To allow that, move those two macros
out of mm/mmap.c into include/linux/sched/mm.h

If these macros are not defined in architectural code then they default
to (TASK_SIZE) and (base) so should not introduce any behavioural
changes to architectures that do not define them.

For the time being, only ARM64 is affected by this change.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Cc: Steve Capper <steve.capper at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Fixes: f6795053dac8 ("mm: mmap: Allow for "high" userspace addresses")
Cc: <stable at vger.kernel.org> # 5.0.x
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
---
 fs/hugetlbfs/inode.c     | 9 +++++----
 include/linux/sched/mm.h | 8 ++++++++
 mm/mmap.c                | 8 --------
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index c7cde4e5924d..a8d3b0899b60 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -205,7 +205,7 @@ hugetlb_get_unmapped_area_bottomup(struct file *file, unsigned long addr,
 	info.flags = 0;
 	info.length = len;
 	info.low_limit = current->mm->mmap_base;
-	info.high_limit = TASK_SIZE;
+	info.high_limit = arch_get_mmap_end(addr, len, flags);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	return vm_unmapped_area(&info);
@@ -221,7 +221,7 @@ hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr,
 	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
 	info.length = len;
 	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
-	info.high_limit = current->mm->mmap_base;
+	info.high_limit = arch_get_mmap_base(addr, current->mm->mmap_base);
 	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
 	info.align_offset = 0;
 	addr = vm_unmapped_area(&info);
@@ -236,7 +236,7 @@ hugetlb_get_unmapped_area_topdown(struct file *file, unsigned long addr,
 		VM_BUG_ON(addr != -ENOMEM);
 		info.flags = 0;
 		info.low_limit = current->mm->mmap_base;
-		info.high_limit = TASK_SIZE;
+		info.high_limit = arch_get_mmap_end(addr, len, flags);
 		addr = vm_unmapped_area(&info);
 	}
 
@@ -251,6 +251,7 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	struct hstate *h = hstate_file(file);
+	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
 	if (len & ~huge_page_mask(h))
 		return -EINVAL;
@@ -266,7 +267,7 @@ generic_hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 	if (addr) {
 		addr = ALIGN(addr, huge_page_size(h));
 		vma = find_vma(mm, addr);
-		if (TASK_SIZE - len >= addr &&
+		if (mmap_end - len >= addr &&
 		    (!vma || addr + len <= vm_start_gap(vma)))
 			return addr;
 	}
diff --git a/include/linux/sched/mm.h b/include/linux/sched/mm.h
index 2584f7c13f69..cc9d80bd36d5 100644
--- a/include/linux/sched/mm.h
+++ b/include/linux/sched/mm.h
@@ -135,6 +135,14 @@ static inline void mm_update_next_owner(struct mm_struct *mm)
 #endif /* CONFIG_MEMCG */
 
 #ifdef CONFIG_MMU
+#ifndef arch_get_mmap_end
+#define arch_get_mmap_end(addr, len, flags)	(TASK_SIZE)
+#endif
+
+#ifndef arch_get_mmap_base
+#define arch_get_mmap_base(addr, base) (base)
+#endif
+
 extern void arch_pick_mmap_layout(struct mm_struct *mm,
 				  struct rlimit *rlim_stack);
 extern unsigned long
diff --git a/mm/mmap.c b/mm/mmap.c
index ad48f7af7511..c773b5ad9a11 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2112,14 +2112,6 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
 	return addr;
 }
 
-#ifndef arch_get_mmap_end
-#define arch_get_mmap_end(addr, len, flags)	(TASK_SIZE)
-#endif
-
-#ifndef arch_get_mmap_base
-#define arch_get_mmap_base(addr, base) (base)
-#endif
-
 /* Get an address range which is currently unmapped.
  * For shmat() with addr=0.
  *
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:15 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:15 +0000
Subject: [PATCH v7 03/14] mm: Add len and flags parameters to
 arch_get_mmap_end()
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <0c8611ef3bcd758c4ff281b92015f447ab7f9b19.1642752946.git.christophe.leroy@csgroup.eu>

Powerpc needs flags and len to make decision on arch_get_mmap_end().

So add them as parameters to arch_get_mmap_end().

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Cc: Steve Capper <steve.capper at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/include/asm/processor.h | 4 ++--
 mm/mmap.c                          | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..9ceec2bf4b93 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -91,8 +91,8 @@
 #endif /* CONFIG_COMPAT */
 
 #ifndef CONFIG_ARM64_FORCE_52BIT
-#define arch_get_mmap_end(addr) ((addr > DEFAULT_MAP_WINDOW) ? TASK_SIZE :\
-				DEFAULT_MAP_WINDOW)
+#define arch_get_mmap_end(addr, len, flags) \
+		(((addr) > DEFAULT_MAP_WINDOW) ? TASK_SIZE : DEFAULT_MAP_WINDOW)
 
 #define arch_get_mmap_base(addr, base) ((addr > DEFAULT_MAP_WINDOW) ? \
 					base + TASK_SIZE - DEFAULT_MAP_WINDOW :\
diff --git a/mm/mmap.c b/mm/mmap.c
index 7ac6a07ff382..ad48f7af7511 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -2113,7 +2113,7 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info)
 }
 
 #ifndef arch_get_mmap_end
-#define arch_get_mmap_end(addr)	(TASK_SIZE)
+#define arch_get_mmap_end(addr, len, flags)	(TASK_SIZE)
 #endif
 
 #ifndef arch_get_mmap_base
@@ -2139,7 +2139,7 @@ generic_get_unmapped_area(struct file *filp, unsigned long addr,
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma, *prev;
 	struct vm_unmapped_area_info info;
-	const unsigned long mmap_end = arch_get_mmap_end(addr);
+	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
 	if (len > mmap_end - mmap_min_addr)
 		return -ENOMEM;
@@ -2187,7 +2187,7 @@ generic_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
 	struct vm_area_struct *vma, *prev;
 	struct mm_struct *mm = current->mm;
 	struct vm_unmapped_area_info info;
-	const unsigned long mmap_end = arch_get_mmap_end(addr);
+	const unsigned long mmap_end = arch_get_mmap_end(addr, len, flags);
 
 	/* requested length too big for entire address space */
 	if (len > mmap_end - mmap_min_addr)
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:21 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:21 +0000
Subject: [PATCH v7 05/14] sizes.h: Add SZ_1T macro
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <575cb7164cf124c75df7cb9242ea7374733942bf.1642752946.git.christophe.leroy@csgroup.eu>

Today drivers/pci/controller/pci-xgene.c defines SZ_1T

Move it into linux/sizes.h so that it can be re-used elsewhere.

Cc: Toan Le <toan at os.amperecomputing.com>
Cc: linux-pci at vger.kernel.org
Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: Krzysztof Wilczy?ski <kw at linux.com>
Acked-by: Bjorn Helgaas <bhelgaas at google.com>
---
 drivers/pci/controller/pci-xgene.c | 1 -
 include/linux/sizes.h              | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/pci-xgene.c b/drivers/pci/controller/pci-xgene.c
index 56d0d50338c8..716dcab5ca47 100644
--- a/drivers/pci/controller/pci-xgene.c
+++ b/drivers/pci/controller/pci-xgene.c
@@ -49,7 +49,6 @@
 #define EN_REG				0x00000001
 #define OB_LO_IO			0x00000002
 #define XGENE_PCIE_DEVICEID		0xE004
-#define SZ_1T				(SZ_1G*1024ULL)
 #define PIPE_PHY_RATE_RD(src)		((0xc000 & (u32)(src)) >> 0xe)
 
 #define XGENE_V1_PCI_EXP_CAP		0x40
diff --git a/include/linux/sizes.h b/include/linux/sizes.h
index 1ac79bcee2bb..84aa448d8bb3 100644
--- a/include/linux/sizes.h
+++ b/include/linux/sizes.h
@@ -47,6 +47,8 @@
 #define SZ_8G				_AC(0x200000000, ULL)
 #define SZ_16G				_AC(0x400000000, ULL)
 #define SZ_32G				_AC(0x800000000, ULL)
+
+#define SZ_1T				_AC(0x10000000000, ULL)
 #define SZ_64T				_AC(0x400000000000, ULL)
 
 #endif /* __LINUX_SIZES_H__ */
-- 
2.33.1

From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:24 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:24 +0000
Subject: [PATCH v7 06/14] powerpc/mm: Move vma_mmu_pagesize()
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <44aac3ced0ce952719fa0b7bb924a3be7752c25f.1642752946.git.christophe.leroy@csgroup.eu>

vma_mmu_pagesize() is only required for slices,
otherwise there is a generic weak version doing the
exact same thing.

Move it to slice.c

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
---
 arch/powerpc/mm/hugetlbpage.c | 11 -----------
 arch/powerpc/mm/slice.c       |  9 +++++++++
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index ddead41e2194..0eec3b61bd13 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -565,17 +565,6 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 }
 #endif
 
-unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
-{
-	/* With radix we don't use slice, so derive it from vma*/
-	if (IS_ENABLED(CONFIG_PPC_MM_SLICES) && !radix_enabled()) {
-		unsigned int psize = get_slice_psize(vma->vm_mm, vma->vm_start);
-
-		return 1UL << mmu_psize_to_shift(psize);
-	}
-	return vma_kernel_pagesize(vma);
-}
-
 bool __init arch_hugetlb_valid_size(unsigned long size)
 {
 	int shift = __ffs(size);
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index f42711f865f3..8a3ac062b71e 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -759,4 +759,13 @@ int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
 
 	return !slice_check_range_fits(mm, maskp, addr, len);
 }
+
+unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
+{
+	/* With radix we don't use slice, so derive it from vma*/
+	if (radix_enabled())
+		return vma_kernel_pagesize(vma);
+
+	return 1UL << mmu_psize_to_shift(get_slice_psize(vma->vm_mm, vma->vm_start));
+}
 #endif
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:27 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:27 +0000
Subject: [PATCH v7 07/14] powerpc/mm: Make slice specific to book3s/64
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <0291cfad5e241a98aff2241fdb6bc30368e66d8a.1642752946.git.christophe.leroy@csgroup.eu>

Since commit 555904d07eef ("powerpc/8xx: MM_SLICE is not needed
anymore") only book3s/64 selects CONFIG_PPC_MM_SLICES.

Move slice.c into mm/book3s64/

Move necessary stuff in asm/book3s/64/slice.h and
remove asm/slice.h

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
---
 arch/powerpc/include/asm/book3s/64/mmu-hash.h |  1 +
 arch/powerpc/include/asm/book3s/64/slice.h    | 18 ++++++++
 arch/powerpc/include/asm/page.h               |  1 -
 arch/powerpc/include/asm/slice.h              | 46 -------------------
 arch/powerpc/mm/Makefile                      |  1 -
 arch/powerpc/mm/book3s64/Makefile             |  1 +
 arch/powerpc/mm/{ => book3s64}/slice.c        |  2 -
 arch/powerpc/mm/nohash/mmu_context.c          |  9 ----
 arch/powerpc/mm/nohash/tlb.c                  |  4 --
 9 files changed, 20 insertions(+), 63 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/slice.h
 rename arch/powerpc/mm/{ => book3s64}/slice.c (99%)

diff --git a/arch/powerpc/include/asm/book3s/64/mmu-hash.h b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
index 21f780942911..1c4eebbc69c9 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu-hash.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu-hash.h
@@ -18,6 +18,7 @@
  * complete pgtable.h but only a portion of it.
  */
 #include <asm/book3s/64/pgtable.h>
+#include <asm/book3s/64/slice.h>
 #include <asm/task_size_64.h>
 #include <asm/cpu_has_feature.h>
 
diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index f0d3194ba41b..5b0f7105bc8b 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_POWERPC_BOOK3S_64_SLICE_H
 #define _ASM_POWERPC_BOOK3S_64_SLICE_H
 
+#ifndef __ASSEMBLY__
+
 #define SLICE_LOW_SHIFT		28
 #define SLICE_LOW_TOP		(0x100000000ul)
 #define SLICE_NUM_LOW		(SLICE_LOW_TOP >> SLICE_LOW_SHIFT)
@@ -13,4 +15,20 @@
 
 #define SLB_ADDR_LIMIT_DEFAULT	DEFAULT_MAP_WINDOW_USER64
 
+struct mm_struct;
+
+unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
+				      unsigned long flags, unsigned int psize,
+				      int topdown);
+
+unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr);
+
+void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
+			   unsigned long len, unsigned int psize);
+
+void slice_init_new_context_exec(struct mm_struct *mm);
+void slice_setup_new_exec(void);
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* _ASM_POWERPC_BOOK3S_64_SLICE_H */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 254687258f42..62e0c6f12869 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -329,6 +329,5 @@ static inline unsigned long kaslr_offset(void)
 
 #include <asm-generic/memory_model.h>
 #endif /* __ASSEMBLY__ */
-#include <asm/slice.h>
 
 #endif /* _ASM_POWERPC_PAGE_H */
diff --git a/arch/powerpc/include/asm/slice.h b/arch/powerpc/include/asm/slice.h
deleted file mode 100644
index 0bdd9c62eca0..000000000000
--- a/arch/powerpc/include/asm/slice.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_POWERPC_SLICE_H
-#define _ASM_POWERPC_SLICE_H
-
-#ifdef CONFIG_PPC_BOOK3S_64
-#include <asm/book3s/64/slice.h>
-#endif
-
-#ifndef __ASSEMBLY__
-
-struct mm_struct;
-
-#ifdef CONFIG_PPC_MM_SLICES
-
-#ifdef CONFIG_HUGETLB_PAGE
-#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-#endif
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
-unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
-				      unsigned long flags, unsigned int psize,
-				      int topdown);
-
-unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr);
-
-void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
-			   unsigned long len, unsigned int psize);
-
-void slice_init_new_context_exec(struct mm_struct *mm);
-void slice_setup_new_exec(void);
-
-#else /* CONFIG_PPC_MM_SLICES */
-
-static inline void slice_init_new_context_exec(struct mm_struct *mm) {}
-
-static inline unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr)
-{
-	return 0;
-}
-
-#endif /* CONFIG_PPC_MM_SLICES */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_POWERPC_SLICE_H */
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index df8172da2301..d4c20484dad9 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_PPC_MMU_NOHASH)	+= nohash/
 obj-$(CONFIG_PPC_BOOK3S_32)	+= book3s32/
 obj-$(CONFIG_PPC_BOOK3S_64)	+= book3s64/
 obj-$(CONFIG_NUMA) += numa.o
-obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o
 obj-$(CONFIG_PPC_COPRO_BASE)	+= copro_fault.o
diff --git a/arch/powerpc/mm/book3s64/Makefile b/arch/powerpc/mm/book3s64/Makefile
index 2d50cac499c5..af2f3e75d458 100644
--- a/arch/powerpc/mm/book3s64/Makefile
+++ b/arch/powerpc/mm/book3s64/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_hugetlbpage.o
 endif
 obj-$(CONFIG_SPAPR_TCE_IOMMU)	+= iommu_api.o
 obj-$(CONFIG_PPC_PKEY)	+= pkeys.o
+obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 
 # Instrumenting the SLB fault path can lead to duplicate SLB entries
 KCOV_INSTRUMENT_slb.o := n
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/book3s64/slice.c
similarity index 99%
rename from arch/powerpc/mm/slice.c
rename to arch/powerpc/mm/book3s64/slice.c
index 8a3ac062b71e..e4382713746d 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -692,7 +692,6 @@ void slice_init_new_context_exec(struct mm_struct *mm)
 		bitmap_fill(mask->high_slices, SLICE_NUM_HIGH);
 }
 
-#ifdef CONFIG_PPC_BOOK3S_64
 void slice_setup_new_exec(void)
 {
 	struct mm_struct *mm = current->mm;
@@ -704,7 +703,6 @@ void slice_setup_new_exec(void)
 
 	mm_ctx_set_slb_addr_limit(&mm->context, DEFAULT_MAP_WINDOW);
 }
-#endif
 
 void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
 			   unsigned long len, unsigned int psize)
diff --git a/arch/powerpc/mm/nohash/mmu_context.c b/arch/powerpc/mm/nohash/mmu_context.c
index 85b048f04c56..ccd5819b1bd9 100644
--- a/arch/powerpc/mm/nohash/mmu_context.c
+++ b/arch/powerpc/mm/nohash/mmu_context.c
@@ -317,15 +317,6 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next,
  */
 int init_new_context(struct task_struct *t, struct mm_struct *mm)
 {
-	/*
-	 * We have MMU_NO_CONTEXT set to be ~0. Hence check
-	 * explicitly against context.id == 0. This ensures that we properly
-	 * initialize context slice details for newly allocated mm's (which will
-	 * have id == 0) and don't alter context slice inherited via fork (which
-	 * will have id != 0).
-	 */
-	if (mm->context.id == 0)
-		slice_init_new_context_exec(mm);
 	mm->context.id = MMU_NO_CONTEXT;
 	mm->context.active = 0;
 	pte_frag_set(&mm->context, NULL);
diff --git a/arch/powerpc/mm/nohash/tlb.c b/arch/powerpc/mm/nohash/tlb.c
index fd2c77af5c55..7e1e7c3dc66a 100644
--- a/arch/powerpc/mm/nohash/tlb.c
+++ b/arch/powerpc/mm/nohash/tlb.c
@@ -773,9 +773,5 @@ void __init early_init_mmu(void)
 #ifdef CONFIG_PPC_47x
 	early_init_mmu_47x();
 #endif
-
-#ifdef CONFIG_PPC_MM_SLICES
-	mm_ctx_set_slb_addr_limit(&init_mm.context, SLB_ADDR_LIMIT_DEFAULT);
-#endif
 }
 #endif /* CONFIG_PPC64 */
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:30 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:30 +0000
Subject: [PATCH v7 08/14] powerpc/mm: Remove CONFIG_PPC_MM_SLICES
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <3e4c787053bfe6f9d566711a8fc486d7235334c5.1642752946.git.christophe.leroy@csgroup.eu>

CONFIG_PPC_MM_SLICES is always selected by hash book3s/64.
CONFIG_PPC_MM_SLICES is never selected by other platforms.

Remove it.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
Reviewed-by: Nicholas Piggin <npiggin at gmail.com>
---
 arch/powerpc/include/asm/hugetlb.h     |  2 +-
 arch/powerpc/include/asm/paca.h        |  7 -------
 arch/powerpc/kernel/paca.c             |  5 -----
 arch/powerpc/mm/book3s64/Makefile      |  3 +--
 arch/powerpc/mm/book3s64/hash_utils.c  | 14 --------------
 arch/powerpc/mm/hugetlbpage.c          |  2 +-
 arch/powerpc/mm/mmap.c                 |  4 ++--
 arch/powerpc/platforms/Kconfig.cputype |  4 ----
 8 files changed, 5 insertions(+), 36 deletions(-)

diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h
index 962708fa1017..46e0b9dc77bf 100644
--- a/arch/powerpc/include/asm/hugetlb.h
+++ b/arch/powerpc/include/asm/hugetlb.h
@@ -24,7 +24,7 @@ static inline int is_hugepage_only_range(struct mm_struct *mm,
 					 unsigned long addr,
 					 unsigned long len)
 {
-	if (IS_ENABLED(CONFIG_PPC_MM_SLICES) && !radix_enabled())
+	if (IS_ENABLED(CONFIG_PPC_64S_HASH_MMU) && !radix_enabled())
 		return slice_is_hugepage_only_range(mm, addr, len);
 	return 0;
 }
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 295573a82c66..bd4dd02e61c8 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -152,16 +152,9 @@ struct paca_struct {
 	struct tlb_core_data tcd;
 #endif /* CONFIG_PPC_BOOK3E */
 
-#ifdef CONFIG_PPC_BOOK3S
 #ifdef CONFIG_PPC_64S_HASH_MMU
-#ifdef CONFIG_PPC_MM_SLICES
 	unsigned char mm_ctx_low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
 	unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
-#else
-	u16 mm_ctx_user_psize;
-	u16 mm_ctx_sllp;
-#endif
-#endif
 #endif
 
 	/*
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 39da688a9455..ba593fd60124 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -344,15 +344,10 @@ void copy_mm_to_paca(struct mm_struct *mm)
 {
 	mm_context_t *context = &mm->context;
 
-#ifdef CONFIG_PPC_MM_SLICES
 	VM_BUG_ON(!mm_ctx_slb_addr_limit(context));
 	memcpy(&get_paca()->mm_ctx_low_slices_psize, mm_ctx_low_slices(context),
 	       LOW_SLICE_ARRAY_SZ);
 	memcpy(&get_paca()->mm_ctx_high_slices_psize, mm_ctx_high_slices(context),
 	       TASK_SLICE_ARRAY_SZ(context));
-#else /* CONFIG_PPC_MM_SLICES */
-	get_paca()->mm_ctx_user_psize = context->user_psize;
-	get_paca()->mm_ctx_sllp = context->sllp;
-#endif
 }
 #endif /* CONFIG_PPC_64S_HASH_MMU */
diff --git a/arch/powerpc/mm/book3s64/Makefile b/arch/powerpc/mm/book3s64/Makefile
index af2f3e75d458..d527dc8e30a8 100644
--- a/arch/powerpc/mm/book3s64/Makefile
+++ b/arch/powerpc/mm/book3s64/Makefile
@@ -5,7 +5,7 @@ ccflags-y	:= $(NO_MINIMAL_TOC)
 obj-y				+= mmu_context.o pgtable.o trace.o
 ifdef CONFIG_PPC_64S_HASH_MMU
 CFLAGS_REMOVE_slb.o = $(CC_FLAGS_FTRACE)
-obj-y				+= hash_pgtable.o hash_utils.o hash_tlb.o slb.o
+obj-y				+= hash_pgtable.o hash_utils.o hash_tlb.o slb.o slice.o
 obj-$(CONFIG_PPC_HASH_MMU_NATIVE)	+= hash_native.o
 obj-$(CONFIG_PPC_4K_PAGES)	+= hash_4k.o
 obj-$(CONFIG_PPC_64K_PAGES)	+= hash_64k.o
@@ -21,7 +21,6 @@ obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_hugetlbpage.o
 endif
 obj-$(CONFIG_SPAPR_TCE_IOMMU)	+= iommu_api.o
 obj-$(CONFIG_PPC_PKEY)	+= pkeys.o
-obj-$(CONFIG_PPC_MM_SLICES)	+= slice.o
 
 # Instrumenting the SLB fault path can lead to duplicate SLB entries
 KCOV_INSTRUMENT_slb.o := n
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 7abf82a698d3..154a5a860959 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1264,7 +1264,6 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
 	return pp;
 }
 
-#ifdef CONFIG_PPC_MM_SLICES
 static unsigned int get_paca_psize(unsigned long addr)
 {
 	unsigned char *psizes;
@@ -1281,12 +1280,6 @@ static unsigned int get_paca_psize(unsigned long addr)
 	return (psizes[index >> 1] >> (mask_index * 4)) & 0xF;
 }
 
-#else
-unsigned int get_paca_psize(unsigned long addr)
-{
-	return get_paca()->mm_ctx_user_psize;
-}
-#endif
 
 /*
  * Demote a segment to using 4k pages.
@@ -1710,7 +1703,6 @@ DEFINE_INTERRUPT_HANDLER_RAW(do_hash_fault)
 	return 0;
 }
 
-#ifdef CONFIG_PPC_MM_SLICES
 static bool should_hash_preload(struct mm_struct *mm, unsigned long ea)
 {
 	int psize = get_slice_psize(mm, ea);
@@ -1727,12 +1719,6 @@ static bool should_hash_preload(struct mm_struct *mm, unsigned long ea)
 
 	return true;
 }
-#else
-static bool should_hash_preload(struct mm_struct *mm, unsigned long ea)
-{
-	return true;
-}
-#endif
 
 static void hash_preload(struct mm_struct *mm, pte_t *ptep, unsigned long ea,
 			 bool is_exec, unsigned long trap)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 0eec3b61bd13..f18b3a1d18f0 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -558,7 +558,7 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 		return radix__hugetlb_get_unmapped_area(file, addr, len,
 						       pgoff, flags);
 #endif
-#ifdef CONFIG_PPC_MM_SLICES
+#ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr, len, flags, file_to_psize(file), 1);
 #endif
 	BUG();
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index c475cf810aa8..9b0d6e395bc0 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -190,7 +190,7 @@ unsigned long arch_get_unmapped_area(struct file *filp,
 				     unsigned long pgoff,
 				     unsigned long flags)
 {
-#ifdef CONFIG_PPC_MM_SLICES
+#ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr, len, flags,
 				       mm_ctx_user_psize(&current->mm->context), 0);
 #else
@@ -204,7 +204,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 					     const unsigned long pgoff,
 					     const unsigned long flags)
 {
-#ifdef CONFIG_PPC_MM_SLICES
+#ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr0, len, flags,
 				       mm_ctx_user_psize(&current->mm->context), 1);
 #else
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 87bc1929ee5a..c775b566e7b4 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -376,7 +376,6 @@ config SPE
 config PPC_64S_HASH_MMU
 	bool "Hash MMU Support"
 	depends on PPC_BOOK3S_64
-	select PPC_MM_SLICES
 	default y
 	help
 	  Enable support for the Power ISA Hash style MMU. This is implemented
@@ -450,9 +449,6 @@ config PPC_BOOK3E_MMU
 	def_bool y
 	depends on FSL_BOOKE || PPC_BOOK3E
 
-config PPC_MM_SLICES
-	bool
-
 config PPC_HAVE_PMU_SUPPORT
 	bool
 
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:33 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:33 +0000
Subject: [PATCH v7 09/14] powerpc/mm: Use generic_get_unmapped_area() and call
 it from arch_get_unmapped_area()
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <d31a52e296a4cead876165158bce415aac3631bb.1642752946.git.christophe.leroy@csgroup.eu>

Use the generic version of arch_get_unmapped_area() which
is now available at all time instead of its copy
radix__arch_get_unmapped_area()

To allow that for PPC64, add arch_get_mmap_base() and
arch_get_mmap_end() macros.

Instead of setting mm->get_unmapped_area() to either
arch_get_unmapped_area() or generic_get_unmapped_area(),
always set it to arch_get_unmapped_area() and call
generic_get_unmapped_area() from there when radix is enabled.

Do the same with radix__arch_get_unmapped_area_topdown()

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/include/asm/task_size_64.h |   8 ++
 arch/powerpc/mm/mmap.c                  | 127 ++----------------------
 2 files changed, 14 insertions(+), 121 deletions(-)

diff --git a/arch/powerpc/include/asm/task_size_64.h b/arch/powerpc/include/asm/task_size_64.h
index 38fdf8041d12..5a709951c901 100644
--- a/arch/powerpc/include/asm/task_size_64.h
+++ b/arch/powerpc/include/asm/task_size_64.h
@@ -72,4 +72,12 @@
 #define STACK_TOP_MAX TASK_SIZE_USER64
 #define STACK_TOP (is_32bit_task() ? STACK_TOP_USER32 : STACK_TOP_USER64)
 
+#define arch_get_mmap_base(addr, base) \
+	(((addr) > DEFAULT_MAP_WINDOW) ? (base) + TASK_SIZE - DEFAULT_MAP_WINDOW : (base))
+
+#define arch_get_mmap_end(addr, len, flags) \
+	(((addr) > DEFAULT_MAP_WINDOW) || \
+	 (((flags) & MAP_FIXED) && ((addr) + (len) > DEFAULT_MAP_WINDOW)) ? TASK_SIZE : \
+									    DEFAULT_MAP_WINDOW)
+
 #endif /* _ASM_POWERPC_TASK_SIZE_64_H */
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index 9b0d6e395bc0..46781d0103d1 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -81,115 +81,15 @@ static inline unsigned long mmap_base(unsigned long rnd,
 }
 
 #ifdef HAVE_ARCH_UNMAPPED_AREA
-#ifdef CONFIG_PPC_RADIX_MMU
-/*
- * Same function as generic code used only for radix, because we don't need to overload
- * the generic one. But we will have to duplicate, because hash select
- * HAVE_ARCH_UNMAPPED_AREA
- */
-static unsigned long
-radix__arch_get_unmapped_area(struct file *filp, unsigned long addr,
-			     unsigned long len, unsigned long pgoff,
-			     unsigned long flags)
-{
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	int fixed = (flags & MAP_FIXED);
-	unsigned long high_limit;
-	struct vm_unmapped_area_info info;
-
-	high_limit = DEFAULT_MAP_WINDOW;
-	if (addr >= high_limit || (fixed && (addr + len > high_limit)))
-		high_limit = TASK_SIZE;
-
-	if (len > high_limit)
-		return -ENOMEM;
-
-	if (fixed) {
-		if (addr > high_limit - len)
-			return -ENOMEM;
-		return addr;
-	}
-
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (high_limit - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-
-	info.flags = 0;
-	info.length = len;
-	info.low_limit = mm->mmap_base;
-	info.high_limit = high_limit;
-	info.align_mask = 0;
-
-	return vm_unmapped_area(&info);
-}
-
-static unsigned long
-radix__arch_get_unmapped_area_topdown(struct file *filp,
-				     const unsigned long addr0,
-				     const unsigned long len,
-				     const unsigned long pgoff,
-				     const unsigned long flags)
-{
-	struct vm_area_struct *vma;
-	struct mm_struct *mm = current->mm;
-	unsigned long addr = addr0;
-	int fixed = (flags & MAP_FIXED);
-	unsigned long high_limit;
-	struct vm_unmapped_area_info info;
-
-	high_limit = DEFAULT_MAP_WINDOW;
-	if (addr >= high_limit || (fixed && (addr + len > high_limit)))
-		high_limit = TASK_SIZE;
-
-	if (len > high_limit)
-		return -ENOMEM;
-
-	if (fixed) {
-		if (addr > high_limit - len)
-			return -ENOMEM;
-		return addr;
-	}
-
-	if (addr) {
-		addr = PAGE_ALIGN(addr);
-		vma = find_vma(mm, addr);
-		if (high_limit - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-
-	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
-	info.length = len;
-	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
-	info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
-	info.align_mask = 0;
-
-	addr = vm_unmapped_area(&info);
-	if (!(addr & ~PAGE_MASK))
-		return addr;
-	VM_BUG_ON(addr != -ENOMEM);
-
-	/*
-	 * A failed mmap() very likely causes application failure,
-	 * so fall back to the bottom-up function here. This scenario
-	 * can happen with large stack limits and large mmap()
-	 * allocations.
-	 */
-	return radix__arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
-}
-#endif
-
 unsigned long arch_get_unmapped_area(struct file *filp,
 				     unsigned long addr,
 				     unsigned long len,
 				     unsigned long pgoff,
 				     unsigned long flags)
 {
+	if (radix_enabled())
+		return generic_get_unmapped_area(filp, addr, len, pgoff, flags);
+
 #ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr, len, flags,
 				       mm_ctx_user_psize(&current->mm->context), 0);
@@ -204,6 +104,9 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 					     const unsigned long pgoff,
 					     const unsigned long flags)
 {
+	if (radix_enabled())
+		return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags);
+
 #ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr0, len, flags,
 				       mm_ctx_user_psize(&current->mm->context), 1);
@@ -213,21 +116,6 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 }
 #endif /* HAVE_ARCH_UNMAPPED_AREA */
 
-static void radix__arch_pick_mmap_layout(struct mm_struct *mm,
-					unsigned long random_factor,
-					struct rlimit *rlim_stack)
-{
-#ifdef CONFIG_PPC_RADIX_MMU
-	if (mmap_is_legacy(rlim_stack)) {
-		mm->mmap_base = TASK_UNMAPPED_BASE;
-		mm->get_unmapped_area = radix__arch_get_unmapped_area;
-	} else {
-		mm->mmap_base = mmap_base(random_factor, rlim_stack);
-		mm->get_unmapped_area = radix__arch_get_unmapped_area_topdown;
-	}
-#endif
-}
-
 /*
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
@@ -239,9 +127,6 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 	if (current->flags & PF_RANDOMIZE)
 		random_factor = arch_mmap_rnd();
 
-	if (radix_enabled())
-		return radix__arch_pick_mmap_layout(mm, random_factor,
-						    rlim_stack);
 	/*
 	 * Fall back to the standard layout if the personality
 	 * bit is set, or if the expected stack growth is unlimited:
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:36 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:36 +0000
Subject: [PATCH v7 10/14] powerpc/mm: Use generic_hugetlb_get_unmapped_area()
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <976bb751596336cce4f86563b45e0d41ff208235.1642752946.git.christophe.leroy@csgroup.eu>

Use the generic version of arch_hugetlb_get_unmapped_area()
which is now available at all time.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/include/asm/book3s/64/hugetlb.h |  4 --
 arch/powerpc/mm/book3s64/radix_hugetlbpage.c | 55 --------------------
 arch/powerpc/mm/hugetlbpage.c                |  4 +-
 3 files changed, 1 insertion(+), 62 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h
index 12e150e615b7..b37a28f62cf6 100644
--- a/arch/powerpc/include/asm/book3s/64/hugetlb.h
+++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h
@@ -8,10 +8,6 @@
  */
 void radix__flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
 void radix__local_flush_hugetlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
-extern unsigned long
-radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-				unsigned long len, unsigned long pgoff,
-				unsigned long flags);
 
 extern void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 						unsigned long addr, pte_t *ptep,
diff --git a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
index 23d3e08911d3..d2fb776febb4 100644
--- a/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
+++ b/arch/powerpc/mm/book3s64/radix_hugetlbpage.c
@@ -41,61 +41,6 @@ void radix__flush_hugetlb_tlb_range(struct vm_area_struct *vma, unsigned long st
 		radix__flush_tlb_range_psize(vma->vm_mm, start, end, psize);
 }
 
-/*
- * A vairant of hugetlb_get_unmapped_area doing topdown search
- * FIXME!! should we do as x86 does or non hugetlb area does ?
- * ie, use topdown or not based on mmap_is_legacy check ?
- */
-unsigned long
-radix__hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-				unsigned long len, unsigned long pgoff,
-				unsigned long flags)
-{
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma;
-	struct hstate *h = hstate_file(file);
-	int fixed = (flags & MAP_FIXED);
-	unsigned long high_limit;
-	struct vm_unmapped_area_info info;
-
-	high_limit = DEFAULT_MAP_WINDOW;
-	if (addr >= high_limit || (fixed && (addr + len > high_limit)))
-		high_limit = TASK_SIZE;
-
-	if (len & ~huge_page_mask(h))
-		return -EINVAL;
-	if (len > high_limit)
-		return -ENOMEM;
-
-	if (fixed) {
-		if (addr > high_limit - len)
-			return -ENOMEM;
-		if (prepare_hugepage_range(file, addr, len))
-			return -EINVAL;
-		return addr;
-	}
-
-	if (addr) {
-		addr = ALIGN(addr, huge_page_size(h));
-		vma = find_vma(mm, addr);
-		if (high_limit - len >= addr && addr >= mmap_min_addr &&
-		    (!vma || addr + len <= vm_start_gap(vma)))
-			return addr;
-	}
-	/*
-	 * We are always doing an topdown search here. Slice code
-	 * does that too.
-	 */
-	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
-	info.length = len;
-	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
-	info.high_limit = mm->mmap_base + (high_limit - DEFAULT_MAP_WINDOW);
-	info.align_mask = PAGE_MASK & ~huge_page_mask(h);
-	info.align_offset = 0;
-
-	return vm_unmapped_area(&info);
-}
-
 void radix__huge_ptep_modify_prot_commit(struct vm_area_struct *vma,
 					 unsigned long addr, pte_t *ptep,
 					 pte_t old_pte, pte_t pte)
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index f18b3a1d18f0..bfd7f4af1e58 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -553,11 +553,9 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
 					unsigned long len, unsigned long pgoff,
 					unsigned long flags)
 {
-#ifdef CONFIG_PPC_RADIX_MMU
 	if (radix_enabled())
-		return radix__hugetlb_get_unmapped_area(file, addr, len,
+		return generic_hugetlb_get_unmapped_area(file, addr, len,
 						       pgoff, flags);
-#endif
 #ifdef CONFIG_PPC_64S_HASH_MMU
 	return slice_get_unmapped_area(addr, len, flags, file_to_psize(file), 1);
 #endif
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:40 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:40 +0000
Subject: [PATCH v7 11/14] powerpc/mm: Move get_unmapped_area functions to
 slice.c
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <1c083902be8813752bff297f2fb760bdc089339a.1642752946.git.christophe.leroy@csgroup.eu>

hugetlb_get_unmapped_area() is now identical to the
generic version if only RADIX is enabled, so move it
to slice.c and let it fallback on the generic one
when HASH MMU is not compiled in.

Do the same with arch_get_unmapped_area() and
arch_get_unmapped_area_topdown().

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/include/asm/book3s/64/mmu.h   |  6 ----
 arch/powerpc/include/asm/book3s/64/slice.h |  6 ++++
 arch/powerpc/mm/book3s64/slice.c           | 42 ++++++++++++++++++++++
 arch/powerpc/mm/hugetlbpage.c              | 21 -----------
 arch/powerpc/mm/mmap.c                     | 36 -------------------
 5 files changed, 48 insertions(+), 63 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h
index ba5b1becf518..db47524fa8ea 100644
--- a/arch/powerpc/include/asm/book3s/64/mmu.h
+++ b/arch/powerpc/include/asm/book3s/64/mmu.h
@@ -4,12 +4,6 @@
 
 #include <asm/page.h>
 
-#ifdef CONFIG_HUGETLB_PAGE
-#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-#endif
-#define HAVE_ARCH_UNMAPPED_AREA
-#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-
 #ifndef __ASSEMBLY__
 /*
  * Page size definition
diff --git a/arch/powerpc/include/asm/book3s/64/slice.h b/arch/powerpc/include/asm/book3s/64/slice.h
index 5b0f7105bc8b..b8eb4ad271b9 100644
--- a/arch/powerpc/include/asm/book3s/64/slice.h
+++ b/arch/powerpc/include/asm/book3s/64/slice.h
@@ -4,6 +4,12 @@
 
 #ifndef __ASSEMBLY__
 
+#ifdef CONFIG_HUGETLB_PAGE
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+#endif
+#define HAVE_ARCH_UNMAPPED_AREA
+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
+
 #define SLICE_LOW_SHIFT		28
 #define SLICE_LOW_TOP		(0x100000000ul)
 #define SLICE_NUM_LOW		(SLICE_LOW_TOP >> SLICE_LOW_SHIFT)
diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index e4382713746d..03681042b807 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -639,6 +639,32 @@ unsigned long slice_get_unmapped_area(unsigned long addr, unsigned long len,
 }
 EXPORT_SYMBOL_GPL(slice_get_unmapped_area);
 
+unsigned long arch_get_unmapped_area(struct file *filp,
+				     unsigned long addr,
+				     unsigned long len,
+				     unsigned long pgoff,
+				     unsigned long flags)
+{
+	if (radix_enabled())
+		return generic_get_unmapped_area(filp, addr, len, pgoff, flags);
+
+	return slice_get_unmapped_area(addr, len, flags,
+				       mm_ctx_user_psize(&current->mm->context), 0);
+}
+
+unsigned long arch_get_unmapped_area_topdown(struct file *filp,
+					     const unsigned long addr0,
+					     const unsigned long len,
+					     const unsigned long pgoff,
+					     const unsigned long flags)
+{
+	if (radix_enabled())
+		return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags);
+
+	return slice_get_unmapped_area(addr0, len, flags,
+				       mm_ctx_user_psize(&current->mm->context), 1);
+}
+
 unsigned int notrace get_slice_psize(struct mm_struct *mm, unsigned long addr)
 {
 	unsigned char *psizes;
@@ -766,4 +792,20 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct *vma)
 
 	return 1UL << mmu_psize_to_shift(get_slice_psize(vma->vm_mm, vma->vm_start));
 }
+
+static int file_to_psize(struct file *file)
+{
+	struct hstate *hstate = hstate_file(file);
+	return shift_to_mmu_psize(huge_page_shift(hstate));
+}
+
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+					unsigned long len, unsigned long pgoff,
+					unsigned long flags)
+{
+	if (radix_enabled())
+		return generic_hugetlb_get_unmapped_area(file, addr, len, pgoff, flags);
+
+	return slice_get_unmapped_area(addr, len, flags, file_to_psize(file), 1);
+}
 #endif
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index bfd7f4af1e58..eb9de09e49a3 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -542,27 +542,6 @@ struct page *follow_huge_pd(struct vm_area_struct *vma,
 	return page;
 }
 
-#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-static inline int file_to_psize(struct file *file)
-{
-	struct hstate *hstate = hstate_file(file);
-	return shift_to_mmu_psize(huge_page_shift(hstate));
-}
-
-unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-					unsigned long len, unsigned long pgoff,
-					unsigned long flags)
-{
-	if (radix_enabled())
-		return generic_hugetlb_get_unmapped_area(file, addr, len,
-						       pgoff, flags);
-#ifdef CONFIG_PPC_64S_HASH_MMU
-	return slice_get_unmapped_area(addr, len, flags, file_to_psize(file), 1);
-#endif
-	BUG();
-}
-#endif
-
 bool __init arch_hugetlb_valid_size(unsigned long size)
 {
 	int shift = __ffs(size);
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index 46781d0103d1..5972d619d274 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -80,42 +80,6 @@ static inline unsigned long mmap_base(unsigned long rnd,
 	return PAGE_ALIGN(DEFAULT_MAP_WINDOW - gap - rnd);
 }
 
-#ifdef HAVE_ARCH_UNMAPPED_AREA
-unsigned long arch_get_unmapped_area(struct file *filp,
-				     unsigned long addr,
-				     unsigned long len,
-				     unsigned long pgoff,
-				     unsigned long flags)
-{
-	if (radix_enabled())
-		return generic_get_unmapped_area(filp, addr, len, pgoff, flags);
-
-#ifdef CONFIG_PPC_64S_HASH_MMU
-	return slice_get_unmapped_area(addr, len, flags,
-				       mm_ctx_user_psize(&current->mm->context), 0);
-#else
-	BUG();
-#endif
-}
-
-unsigned long arch_get_unmapped_area_topdown(struct file *filp,
-					     const unsigned long addr0,
-					     const unsigned long len,
-					     const unsigned long pgoff,
-					     const unsigned long flags)
-{
-	if (radix_enabled())
-		return generic_get_unmapped_area_topdown(filp, addr0, len, pgoff, flags);
-
-#ifdef CONFIG_PPC_64S_HASH_MMU
-	return slice_get_unmapped_area(addr0, len, flags,
-				       mm_ctx_user_psize(&current->mm->context), 1);
-#else
-	BUG();
-#endif
-}
-#endif /* HAVE_ARCH_UNMAPPED_AREA */
-
 /*
  * This function, called very early during the creation of a new
  * process VM image, sets up which VM layout function to use:
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:42 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:42 +0000
Subject: [PATCH v7 12/14] powerpc/mm: Enable full randomisation of memory
 mappings
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <675b7946a15dd18d5517bf10a8b49b09142b6c58.1642752946.git.christophe.leroy@csgroup.eu>

Do like most other architectures and provide randomisation also to
"legacy" memory mappings, by adding the random factor to
mm->mmap_base in arch_pick_mmap_layout().

See commit 8b8addf891de ("x86/mm/32: Enable full randomization on
i386 and X86_32") for all explanations and benefits of that mmap
randomisation.

At the moment, slice_find_area_bottomup() doesn't use mm->mmap_base
but uses the fixed TASK_UNMAPPED_BASE instead.
slice_find_area_bottomup() being used as a fallback to
slice_find_area_topdown(), it can't use mm->mmap_base
directly.

Instead of always using TASK_UNMAPPED_BASE as base address, leave
it to the caller. When called from slice_find_area_topdown()
TASK_UNMAPPED_BASE is used. Otherwise mm->mmap_base is used.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/mm/book3s64/slice.c | 18 +++++++-----------
 arch/powerpc/mm/mmap.c           |  2 +-
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/mm/book3s64/slice.c b/arch/powerpc/mm/book3s64/slice.c
index 03681042b807..c0b58afb9a47 100644
--- a/arch/powerpc/mm/book3s64/slice.c
+++ b/arch/powerpc/mm/book3s64/slice.c
@@ -276,20 +276,18 @@ static bool slice_scan_available(unsigned long addr,
 }
 
 static unsigned long slice_find_area_bottomup(struct mm_struct *mm,
-					      unsigned long len,
+					      unsigned long addr, unsigned long len,
 					      const struct slice_mask *available,
 					      int psize, unsigned long high_limit)
 {
 	int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
-	unsigned long addr, found, next_end;
+	unsigned long found, next_end;
 	struct vm_unmapped_area_info info;
 
 	info.flags = 0;
 	info.length = len;
 	info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
 	info.align_offset = 0;
-
-	addr = TASK_UNMAPPED_BASE;
 	/*
 	 * Check till the allow max value for this mmap request
 	 */
@@ -322,12 +320,12 @@ static unsigned long slice_find_area_bottomup(struct mm_struct *mm,
 }
 
 static unsigned long slice_find_area_topdown(struct mm_struct *mm,
-					     unsigned long len,
+					     unsigned long addr, unsigned long len,
 					     const struct slice_mask *available,
 					     int psize, unsigned long high_limit)
 {
 	int pshift = max_t(int, mmu_psize_defs[psize].shift, PAGE_SHIFT);
-	unsigned long addr, found, prev;
+	unsigned long found, prev;
 	struct vm_unmapped_area_info info;
 	unsigned long min_addr = max(PAGE_SIZE, mmap_min_addr);
 
@@ -335,8 +333,6 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
 	info.length = len;
 	info.align_mask = PAGE_MASK & ((1ul << pshift) - 1);
 	info.align_offset = 0;
-
-	addr = mm->mmap_base;
 	/*
 	 * If we are trying to allocate above DEFAULT_MAP_WINDOW
 	 * Add the different to the mmap_base.
@@ -377,7 +373,7 @@ static unsigned long slice_find_area_topdown(struct mm_struct *mm,
 	 * can happen with large stack limits and large mmap()
 	 * allocations.
 	 */
-	return slice_find_area_bottomup(mm, len, available, psize, high_limit);
+	return slice_find_area_bottomup(mm, TASK_UNMAPPED_BASE, len, available, psize, high_limit);
 }
 
 
@@ -386,9 +382,9 @@ static unsigned long slice_find_area(struct mm_struct *mm, unsigned long len,
 				     int topdown, unsigned long high_limit)
 {
 	if (topdown)
-		return slice_find_area_topdown(mm, len, mask, psize, high_limit);
+		return slice_find_area_topdown(mm, mm->mmap_base, len, mask, psize, high_limit);
 	else
-		return slice_find_area_bottomup(mm, len, mask, psize, high_limit);
+		return slice_find_area_bottomup(mm, mm->mmap_base, len, mask, psize, high_limit);
 }
 
 static inline void slice_copy_mask(struct slice_mask *dst,
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
index 5972d619d274..d9eae456558a 100644
--- a/arch/powerpc/mm/mmap.c
+++ b/arch/powerpc/mm/mmap.c
@@ -96,7 +96,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
 	 * bit is set, or if the expected stack growth is unlimited:
 	 */
 	if (mmap_is_legacy(rlim_stack)) {
-		mm->mmap_base = TASK_UNMAPPED_BASE;
+		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
 		mm->get_unmapped_area = arch_get_unmapped_area;
 	} else {
 		mm->mmap_base = mmap_base(random_factor, rlim_stack);
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:45 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:45 +0000
Subject: [PATCH v7 13/14] powerpc/mm: Convert to default topdown mmap layout
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <f8159eb83a8015801df01357ca42026df0703f2b.1642752946.git.christophe.leroy@csgroup.eu>

Select CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT and
remove arch/powerpc/mm/mmap.c

This change reuses the generic framework added by
commit 67f3977f805b ("arm64, mm: move generic mmap layout
functions to mm") without any functional change.

Comparison between powerpc implementation and the generic one:
- mmap_is_legacy() is identical.
- arch_mmap_rnd() does exactly the same allthough it's written
slightly differently.
- MIN_GAP and MAX_GAP are identical.
- mmap_base() does the same but uses STACK_RND_MASK which provides
the same values as stack_maxrandom_size().
- arch_pick_mmap_layout() is identical.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/Kconfig                 |   2 +-
 arch/powerpc/include/asm/processor.h |   2 -
 arch/powerpc/mm/Makefile             |   2 +-
 arch/powerpc/mm/mmap.c               | 105 ---------------------------
 4 files changed, 2 insertions(+), 109 deletions(-)
 delete mode 100644 arch/powerpc/mm/mmap.c

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0631c9241af3..b4ae3d8bde46 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -122,7 +122,6 @@ config PPC
 	select ARCH_HAS_DEBUG_WX		if STRICT_KERNEL_RWX
 	select ARCH_HAS_DEVMEM_IS_ALLOWED
 	select ARCH_HAS_DMA_MAP_DIRECT 		if PPC_PSERIES
-	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_HUGEPD			if HUGETLB_PAGE
@@ -158,6 +157,7 @@ config PPC
 	select ARCH_USE_MEMTEST
 	select ARCH_USE_QUEUED_RWLOCKS		if PPC_QUEUED_SPINLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS	if PPC_QUEUED_SPINLOCKS
+	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_WANT_IRQS_OFF_ACTIVATE_MM
 	select ARCH_WANT_LD_ORPHAN_WARN
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 2c8686d9e964..873adaab20c8 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -392,8 +392,6 @@ static inline void prefetchw(const void *x)
 
 #define spin_lock_prefetch(x)	prefetchw(x)
 
-#define HAVE_ARCH_PICK_MMAP_LAYOUT
-
 /* asm stubs */
 extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val);
 extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val);
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index d4c20484dad9..503a6e249940 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -5,7 +5,7 @@
 
 ccflags-$(CONFIG_PPC64)	:= $(NO_MINIMAL_TOC)
 
-obj-y				:= fault.o mem.o pgtable.o mmap.o maccess.o pageattr.o \
+obj-y				:= fault.o mem.o pgtable.o maccess.o pageattr.o \
 				   init_$(BITS).o pgtable_$(BITS).o \
 				   pgtable-frag.o ioremap.o ioremap_$(BITS).o \
 				   init-common.o mmu_context.o drmem.o \
diff --git a/arch/powerpc/mm/mmap.c b/arch/powerpc/mm/mmap.c
deleted file mode 100644
index d9eae456558a..000000000000
--- a/arch/powerpc/mm/mmap.c
+++ /dev/null
@@ -1,105 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *  flexible mmap layout support
- *
- * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
- * All Rights Reserved.
- *
- * Started by Ingo Molnar <mingo at elte.hu>
- */
-
-#include <linux/personality.h>
-#include <linux/mm.h>
-#include <linux/random.h>
-#include <linux/sched/signal.h>
-#include <linux/sched/mm.h>
-#include <linux/elf-randomize.h>
-#include <linux/security.h>
-#include <linux/mman.h>
-
-/*
- * Top of mmap area (just below the process stack).
- *
- * Leave at least a ~128 MB hole.
- */
-#define MIN_GAP (128*1024*1024)
-#define MAX_GAP (TASK_SIZE/6*5)
-
-static inline int mmap_is_legacy(struct rlimit *rlim_stack)
-{
-	if (current->personality & ADDR_COMPAT_LAYOUT)
-		return 1;
-
-	if (rlim_stack->rlim_cur == RLIM_INFINITY)
-		return 1;
-
-	return sysctl_legacy_va_layout;
-}
-
-unsigned long arch_mmap_rnd(void)
-{
-	unsigned long shift, rnd;
-
-	shift = mmap_rnd_bits;
-#ifdef CONFIG_COMPAT
-	if (is_32bit_task())
-		shift = mmap_rnd_compat_bits;
-#endif
-	rnd = get_random_long() % (1ul << shift);
-
-	return rnd << PAGE_SHIFT;
-}
-
-static inline unsigned long stack_maxrandom_size(void)
-{
-	if (!(current->flags & PF_RANDOMIZE))
-		return 0;
-
-	/* 8MB for 32bit, 1GB for 64bit */
-	if (is_32bit_task())
-		return (1<<23);
-	else
-		return (1<<30);
-}
-
-static inline unsigned long mmap_base(unsigned long rnd,
-				      struct rlimit *rlim_stack)
-{
-	unsigned long gap = rlim_stack->rlim_cur;
-	unsigned long pad = stack_maxrandom_size() + stack_guard_gap;
-
-	/* Values close to RLIM_INFINITY can overflow. */
-	if (gap + pad > gap)
-		gap += pad;
-
-	if (gap < MIN_GAP)
-		gap = MIN_GAP;
-	else if (gap > MAX_GAP)
-		gap = MAX_GAP;
-
-	return PAGE_ALIGN(DEFAULT_MAP_WINDOW - gap - rnd);
-}
-
-/*
- * This function, called very early during the creation of a new
- * process VM image, sets up which VM layout function to use:
- */
-void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack)
-{
-	unsigned long random_factor = 0UL;
-
-	if (current->flags & PF_RANDOMIZE)
-		random_factor = arch_mmap_rnd();
-
-	/*
-	 * Fall back to the standard layout if the personality
-	 * bit is set, or if the expected stack growth is unlimited:
-	 */
-	if (mmap_is_legacy(rlim_stack)) {
-		mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
-		mm->get_unmapped_area = arch_get_unmapped_area;
-	} else {
-		mm->mmap_base = mmap_base(random_factor, rlim_stack);
-		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
-	}
-}
-- 
2.33.1


From christophe.leroy at csgroup.eu  Fri Jan 21 00:42:48 2022
From: christophe.leroy at csgroup.eu (Christophe Leroy)
Date: Fri, 21 Jan 2022 08:42:48 +0000
Subject: [PATCH v7 14/14] powerpc: Simplify and move arch_randomize_brk()
In-Reply-To: <cover.1642752946.git.christophe.leroy@csgroup.eu>
References: <cover.1642752946.git.christophe.leroy@csgroup.eu>
Message-ID: <49dc4982c458867c66f022d11f16ad34e656cd85.1642752946.git.christophe.leroy@csgroup.eu>

arch_randomize_brk() is only needed for hash on book3s/64, for other
platforms the one provided by the default mmap layout is good enough.

Move it to hash_utils.c and use randomize_page() like the generic one.

And properly opt out the radix case instead of making an assumption
on mmu_highuser_ssize.

Also change to a 32M range like most other architectures instead of 8M.

Signed-off-by: Christophe Leroy <christophe.leroy at csgroup.eu>
---
 arch/powerpc/kernel/process.c         | 41 ---------------------------
 arch/powerpc/mm/book3s64/hash_utils.c | 19 +++++++++++++
 2 files changed, 19 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 984813a4d5dc..e7f809bdd433 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -34,10 +34,8 @@
 #include <linux/ftrace.h>
 #include <linux/kernel_stat.h>
 #include <linux/personality.h>
-#include <linux/random.h>
 #include <linux/hw_breakpoint.h>
 #include <linux/uaccess.h>
-#include <linux/elf-randomize.h>
 #include <linux/pkeys.h>
 #include <linux/seq_buf.h>
 
@@ -2313,42 +2311,3 @@ unsigned long arch_align_stack(unsigned long sp)
 		sp -= get_random_int() & ~PAGE_MASK;
 	return sp & ~0xf;
 }
-
-static inline unsigned long brk_rnd(void)
-{
-        unsigned long rnd = 0;
-
-	/* 8MB for 32bit, 1GB for 64bit */
-	if (is_32bit_task())
-		rnd = (get_random_long() % (1UL<<(23-PAGE_SHIFT)));
-	else
-		rnd = (get_random_long() % (1UL<<(30-PAGE_SHIFT)));
-
-	return rnd << PAGE_SHIFT;
-}
-
-unsigned long arch_randomize_brk(struct mm_struct *mm)
-{
-	unsigned long base = mm->brk;
-	unsigned long ret;
-
-#ifdef CONFIG_PPC_BOOK3S_64
-	/*
-	 * If we are using 1TB segments and we are allowed to randomise
-	 * the heap, we can put it above 1TB so it is backed by a 1TB
-	 * segment. Otherwise the heap will be in the bottom 1TB
-	 * which always uses 256MB segments and this may result in a
-	 * performance penalty.
-	 */
-	if (!radix_enabled() && !is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
-		base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
-#endif
-
-	ret = PAGE_ALIGN(base + brk_rnd());
-
-	if (ret < mm->brk)
-		return mm->brk;
-
-	return ret;
-}
-
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 154a5a860959..d28003132a51 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -37,6 +37,8 @@
 #include <linux/cpu.h>
 #include <linux/pgtable.h>
 #include <linux/debugfs.h>
+#include <linux/random.h>
+#include <linux/elf-randomize.h>
 
 #include <asm/interrupt.h>
 #include <asm/processor.h>
@@ -2171,3 +2173,20 @@ void __init print_system_hash_info(void)
 	if (htab_hash_mask)
 		pr_info("htab_hash_mask    = 0x%lx\n", htab_hash_mask);
 }
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	/*
+	 * If we are using 1TB segments and we are allowed to randomise
+	 * the heap, we can put it above 1TB so it is backed by a 1TB
+	 * segment. Otherwise the heap will be in the bottom 1TB
+	 * which always uses 256MB segments and this may result in a
+	 * performance penalty.
+	 */
+	if (is_32bit_task())
+		return randomize_page(mm->brk, SZ_32M);
+	else if (!radix_enabled() && mmu_highuser_ssize == MMU_SEGSIZE_1T)
+		return randomize_page(max_t(unsigned long, mm->brk, SZ_1T), SZ_1G);
+	else
+		return randomize_page(mm->brk, SZ_1G);
+}
-- 
2.33.1


From shameerali.kolothum.thodi at huawei.com  Fri Jan 21 00:44:35 2022
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Fri, 21 Jan 2022 08:44:35 +0000
Subject: [PATCH v4 1/4] KVM: arm64: Introduce a new VMID allocator for KVM
In-Reply-To: <CAAeT=FwWNZ7O=oxGB5d0Pp2jVZVs71nCAGJTp9_+6fhuOK+dKw@mail.gmail.com>
References: <20211122121844.867-1-shameerali.kolothum.thodi@huawei.com>
 <20211122121844.867-2-shameerali.kolothum.thodi@huawei.com>
 <CAAeT=FwWNZ7O=oxGB5d0Pp2jVZVs71nCAGJTp9_+6fhuOK+dKw@mail.gmail.com>
Message-ID: <1bca6f5f13424601b431f72a1b1f2319@huawei.com>



> -----Original Message-----
> From: Reiji Watanabe [mailto:reijiw at google.com]
> Sent: 21 January 2022 07:36
> To: Shameerali Kolothum Thodi <shameerali.kolothum.thodi at huawei.com>
> Cc: Linux ARM <linux-arm-kernel at lists.infradead.org>;
> kvmarm at lists.cs.columbia.edu; linux-kernel at vger.kernel.org;
> jean-philippe at linaro.org; Marc Zyngier <maz at kernel.org>; Linuxarm
> <linuxarm at huawei.com>; Jonathan Cameron
> <jonathan.cameron at huawei.com>; Catalin Marinas
> <catalin.marinas at arm.com>; Will Deacon <will at kernel.org>
> Subject: Re: [PATCH v4 1/4] KVM: arm64: Introduce a new VMID allocator for
> KVM
> 
> On Mon, Nov 22, 2021 at 4:19 AM Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com> wrote:
> >
> > A new VMID allocator for arm64 KVM use. This is based on
> > arm64 ASID allocator algorithm.
> >
> > One major deviation from the ASID allocator is the way we
> > flush the context. Unlike ASID allocator, we expect less
> > frequent rollover in the case of VMIDs. Hence, instead of
> > marking the CPU as flush_pending and issuing a local context
> > invalidation on the next context switch, we  broadcast TLB
> > flush + I-cache invalidation over the inner shareable domain
> > on rollover.
> >
> > Signed-off-by: Shameer Kolothum
> <shameerali.kolothum.thodi at huawei.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h |   4 +
> >  arch/arm64/kvm/vmid.c             | 177
> ++++++++++++++++++++++++++++++
> >  2 files changed, 181 insertions(+)
> >  create mode 100644 arch/arm64/kvm/vmid.c
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h
> b/arch/arm64/include/asm/kvm_host.h
> > index 2a5f7f38006f..f4a86a79ea4a 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -690,6 +690,10 @@ int kvm_arm_pvtime_get_attr(struct kvm_vcpu
> *vcpu,
> >  int kvm_arm_pvtime_has_attr(struct kvm_vcpu *vcpu,
> >                             struct kvm_device_attr *attr);
> >
> > +int kvm_arm_vmid_alloc_init(void);
> > +void kvm_arm_vmid_alloc_free(void);
> > +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
> > +
> >  static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch
> *vcpu_arch)
> >  {
> >         vcpu_arch->steal.base = GPA_INVALID;
> > diff --git a/arch/arm64/kvm/vmid.c b/arch/arm64/kvm/vmid.c
> > new file mode 100644
> > index 000000000000..aa01c97f7df0
> > --- /dev/null
> > +++ b/arch/arm64/kvm/vmid.c
> > @@ -0,0 +1,177 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * VMID allocator.
> > + *
> > + * Based on Arm64 ASID allocator algorithm.
> > + * Please refer arch/arm64/mm/context.c for detailed
> > + * comments on algorithm.
> > + *
> > + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved.
> > + * Copyright (C) 2012 ARM Ltd.
> > + */
> > +
> > +#include <linux/bitfield.h>
> > +#include <linux/bitops.h>
> > +
> > +#include <asm/kvm_asm.h>
> > +#include <asm/kvm_mmu.h>
> > +
> > +static unsigned int kvm_arm_vmid_bits;
> > +static DEFINE_RAW_SPINLOCK(cpu_vmid_lock);
> > +
> > +static atomic64_t vmid_generation;
> > +static unsigned long *vmid_map;
> > +
> > +static DEFINE_PER_CPU(atomic64_t, active_vmids);
> > +static DEFINE_PER_CPU(u64, reserved_vmids);
> > +
> > +#define VMID_MASK              (~GENMASK(kvm_arm_vmid_bits - 1,
> 0))
> > +#define VMID_FIRST_VERSION     (1UL << kvm_arm_vmid_bits)
> > +
> > +#define NUM_USER_VMIDS         VMID_FIRST_VERSION
> > +#define vmid2idx(vmid)         ((vmid) & ~VMID_MASK)
> > +#define idx2vmid(idx)          vmid2idx(idx)
> > +
> > +#define vmid_gen_match(vmid) \
> > +       (!(((vmid) ^ atomic64_read(&vmid_generation)) >>
> kvm_arm_vmid_bits))
> > +
> > +static void flush_context(void)
> > +{
> > +       int cpu;
> > +       u64 vmid;
> > +
> > +       bitmap_clear(vmid_map, 0, NUM_USER_VMIDS);
> > +
> > +       for_each_possible_cpu(cpu) {
> > +               vmid = atomic64_xchg_relaxed(&per_cpu(active_vmids,
> cpu), 0);
> > +
> > +               /* Preserve reserved VMID */
> > +               if (vmid == 0)
> > +                       vmid = per_cpu(reserved_vmids, cpu);
> > +               __set_bit(vmid2idx(vmid), vmid_map);
> > +               per_cpu(reserved_vmids, cpu) = vmid;
> > +       }
> > +
> > +       /*
> > +        * Unlike ASID allocator, we expect less frequent rollover in
> > +        * case of VMIDs. Hence, instead of marking the CPU as
> > +        * flush_pending and issuing a local context invalidation on
> > +        * the next context-switch, we broadcast TLB flush + I-cache
> > +        * invalidation over the inner shareable domain on rollover.
> > +        */
> > +        kvm_call_hyp(__kvm_flush_vm_context);
> > +}
> > +
> > +static bool check_update_reserved_vmid(u64 vmid, u64 newvmid)
> > +{
> > +       int cpu;
> > +       bool hit = false;
> > +
> > +       /*
> > +        * Iterate over the set of reserved VMIDs looking for a match
> > +        * and update to use newvmid (i.e. the same VMID in the current
> > +        * generation).
> > +        */
> > +       for_each_possible_cpu(cpu) {
> > +               if (per_cpu(reserved_vmids, cpu) == vmid) {
> > +                       hit = true;
> > +                       per_cpu(reserved_vmids, cpu) = newvmid;
> > +               }
> > +       }
> 
> Once updating reserved_vmids gets done for the all CPUs, it appears
> that the function doesn't need to iterate over the set of reserved
> VMIDs (correct ?). So, I'm wondering if KVM can manage the number of
> CPUs for which reserved_vmids need to get updated so that the function
> can skip the loop when the number is zero.  I'm not sure how likely
> that would help though.

Ok. I think that is possible to do. In the flush_context() we can update the
number of CPUs with valid reserved_vmid and add a check here. Not sure on
the probability of that being zero though.

> (Since every vmid allocation for non-new guest needs to iterate over
>  reserved_vmids holding cpu_vmid_lock, I'm a bit concerned about the
>  performance impact on systems with a large number of CPUs.)

But the non-new guest VMID allocation will normally go through the fast path
unless there is a rollover. And for 16bit VMID space, the frequency of rollover
is very rare I guess.

Thanks,
Shameer

> 
> Thanks,
> Reiji
> 
> > +
> > +       return hit;
> > +}
> > +
> > +static u64 new_vmid(struct kvm_vmid *kvm_vmid)
> > +{
> > +       static u32 cur_idx = 1;
> > +       u64 vmid = atomic64_read(&kvm_vmid->id);
> > +       u64 generation = atomic64_read(&vmid_generation);
> > +
> > +       if (vmid != 0) {
> > +               u64 newvmid = generation | (vmid & ~VMID_MASK);
> > +
> > +               if (check_update_reserved_vmid(vmid, newvmid)) {
> > +                       atomic64_set(&kvm_vmid->id, newvmid);
> > +                       return newvmid;
> > +               }
> > +
> > +               if (!__test_and_set_bit(vmid2idx(vmid), vmid_map)) {
> > +                       atomic64_set(&kvm_vmid->id, newvmid);
> > +                       return newvmid;
> > +               }
> > +       }
> > +
> > +       vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS,
> cur_idx);
> > +       if (vmid != NUM_USER_VMIDS)
> > +               goto set_vmid;
> > +
> > +       /* We're out of VMIDs, so increment the global generation count */
> > +       generation = atomic64_add_return_relaxed(VMID_FIRST_VERSION,
> > +
> &vmid_generation);
> > +       flush_context();
> > +
> > +       /* We have more VMIDs than CPUs, so this will always succeed */
> > +       vmid = find_next_zero_bit(vmid_map, NUM_USER_VMIDS, 1);
> > +
> > +set_vmid:
> > +       __set_bit(vmid, vmid_map);
> > +       cur_idx = vmid;
> > +       vmid = idx2vmid(vmid) | generation;
> > +       atomic64_set(&kvm_vmid->id, vmid);
> > +       return vmid;
> > +}
> > +
> > +void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
> > +{
> > +       unsigned long flags;
> > +       u64 vmid, old_active_vmid;
> > +
> > +       vmid = atomic64_read(&kvm_vmid->id);
> > +
> > +       /*
> > +        * Please refer comments in check_and_switch_context() in
> > +        * arch/arm64/mm/context.c.
> > +        */
> > +       old_active_vmid = atomic64_read(this_cpu_ptr(&active_vmids));
> > +       if (old_active_vmid && vmid_gen_match(vmid) &&
> > +           atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
> > +                                    old_active_vmid, vmid))
> > +               return;
> > +
> > +       raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
> > +
> > +       /* Check that our VMID belongs to the current generation. */
> > +       vmid = atomic64_read(&kvm_vmid->id);
> > +       if (!vmid_gen_match(vmid))
> > +               vmid = new_vmid(kvm_vmid);
> > +
> > +       atomic64_set(this_cpu_ptr(&active_vmids), vmid);
> > +       raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
> > +}
> > +
> > +/*
> > + * Initialize the VMID allocator
> > + */
> > +int kvm_arm_vmid_alloc_init(void)
> > +{
> > +       kvm_arm_vmid_bits = kvm_get_vmid_bits();
> > +
> > +       /*
> > +        * Expect allocation after rollover to fail if we don't have
> > +        * at least one more VMID than CPUs. VMID #0 is always reserved.
> > +        */
> > +       WARN_ON(NUM_USER_VMIDS - 1 <= num_possible_cpus());
> > +       atomic64_set(&vmid_generation, VMID_FIRST_VERSION);
> > +       vmid_map = kcalloc(BITS_TO_LONGS(NUM_USER_VMIDS),
> > +                          sizeof(*vmid_map), GFP_KERNEL);
> > +       if (!vmid_map)
> > +               return -ENOMEM;
> > +
> > +       return 0;
> > +}
> > +
> > +void kvm_arm_vmid_alloc_free(void)
> > +{
> > +       kfree(vmid_map);
> > +}
> > --
> > 2.17.1
> >
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm at lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

From arnd at arndb.de  Fri Jan 21 00:56:43 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Fri, 21 Jan 2022 09:56:43 +0100
Subject: [PATCH V3 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAJF2gTQVUF4LSO0a6_MV8x-UAiJw32pAFyS1oPNLXhcEaemzqg@mail.gmail.com>
References: <20220120073911.99857-9-guoren@kernel.org>
 <CAK8P3a0LxB3we9wHOa4OPmNow6wz5NP49zeYhh7QXNv-MiR8UA@mail.gmail.com>
 <CAJF2gTQVUF4LSO0a6_MV8x-UAiJw32pAFyS1oPNLXhcEaemzqg@mail.gmail.com>
Message-ID: <CAK8P3a1sOejkdOyoRUfw4ESS7ewX_8Wj9tQNrZ40OiuDqJnrmw@mail.gmail.com>

On Fri, Jan 21, 2022 at 7:25 AM Guo Ren <guoren at kernel.org> wrote:
> On Thu, Jan 20, 2022 at 10:43 PM Arnd Bergmann <arnd at arndb.de> wrote:
> > On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:

> > Are you sure these are the right calling conventions? According to [1],
> > I think the 64-bit argument should be in an aligned pair of registers,
> > which means you need an extra pad argument as in the arm64 version
> > of these functions. Same for ftruncate64, pread64, pwrite64, and
> > readahead.
>
> [1] has abandoned.
>
> See:
> https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc

Ok, thanks for the reference, I picked the first one that came up in
a google search and didn't expect this to ever have changed.

> > I still feel like these should be the common implementations next to the
> > native handlers inside of an #ifdef CONFIG_COMPAT.
> >
> > The names clash with the custom versions defined for powerpc and sparc,
> > but the duplicates look compatible if you can account for the padded
> > argument and the lo/hi order of the pairs, so could just be removed here
> > (all other architectures use custom function names instead).
> I would try it later.

This becomes easier then, as powerpc and sparc already have the non-padded
calling conventions, so you could just generalize those without looking at
the other architectures or adding the padding. The powerpc version already
has the dual-endian version, so using that will work on big-endian sparc and
on little-endian riscv as well, though we may need to come up with a better name
for the arg_u32/arg_u64/merge_64 macros in order to put that into a global
header without namespace collisions.

         Arnd


From gregory.clement at bootlin.com  Fri Jan 21 01:02:33 2022
From: gregory.clement at bootlin.com (Gregory CLEMENT)
Date: Fri, 21 Jan 2022 10:02:33 +0100
Subject: [PATCH] arm64: dts: marvell: armada-37xx: Increase PCIe IO size
 from 64 KiB to 1 MiB
In-Reply-To: <20220113170755.11856-1-pali@kernel.org>
References: <20220113170755.11856-1-pali@kernel.org>
Message-ID: <878rv95umu.fsf@BL-laptop>

Pali Roh?r <pali at kernel.org> writes:

> Commit 514ef1e62d65 ("arm64: dts: marvell: armada-37xx: Extend PCIe MEM
> space") increased size of PCIe MEM to 127 MiB, which is the maximal
> possible size for allocated 128 MiB PCIe window. PCIe IO size in that
> commit was unchanged.
>
> Armada 3720 PCIe controller supports 32-bit IO space mapping so it is
> possible to assign more than 64 KiB if address space for IO.
>
> Currently controller has assigned 127 MiB + 64 KiB memory and therefore
> there is 960 KiB of unused memory. So assign it to IO space by increasing
> IO window from 64 KiB to 1 MiB.
>
> DTS file armada-3720-turris-mox.dts already uses whole 128 MiB space, so
> only update comment about 32-bit IO space mapping.
>
> Signed-off-by: Pali Roh?r <pali at kernel.org>
> Fixes: 514ef1e62d65 ("arm64: dts: marvell: armada-37xx: Extend PCIe
> MEM space")

Applied on mvebu/fixes

Thanks,

Gregory

> ---
>  arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 2 +-
>  arch/arm64/boot/dts/marvell/armada-37xx.dtsi           | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> index dd01409d4bb7..23e1b07c060a 100644
> --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> @@ -153,7 +153,7 @@
>  	 * 2 size cells and also expects that the second range starts at 16 MB offset. If these
>  	 * conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
>  	 * space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
> -	 * for IO and the rest 112 MB (64+32+16) for MEM, despite that maximal IO size is just 64 kB.
> +	 * for IO and the rest 112 MB (64+32+16) for MEM. Controller supports 32-bit IO mapping.
>  	 * This bug is not present in U-Boot ports for other Armada 3700 devices and is fixed in
>  	 * U-Boot version 2021.07. See relevant U-Boot commits (the last one contains fix):
>  	 * https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
> diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> index 1c74f02535c6..8d59eabadce6 100644
> --- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> +++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
> @@ -508,12 +508,12 @@
>  			/*
>  			 * The 128 MiB address range [0xe8000000-0xf0000000] is
>  			 * dedicated for PCIe and can be assigned to 8 windows
> -			 * with size a power of two. Use one 64 KiB window for
> +			 * with size a power of two. Use one 1 MiB window for
>  			 * IO at the end and the remaining seven windows
>  			 * (totaling 127 MiB) for MEM.
>  			 */
>  			ranges = <0x82000000 0 0xe8000000   0 0xe8000000   0 0x07f00000   /* Port 0 MEM */
> -				  0x81000000 0 0xefff0000   0 0xefff0000   0 0x00010000>; /* Port 0 IO */
> +				  0x81000000 0 0xeff00000   0 0xeff00000   0 0x00100000>; /* Port 0 IO*/
>  			interrupt-map-mask = <0 0 0 7>;
>  			interrupt-map = <0 0 0 1 &pcie_intc 0>,
>  					<0 0 0 2 &pcie_intc 1>,
> -- 
> 2.20.1
>

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com


From gregory.clement at bootlin.com  Fri Jan 21 01:03:56 2022
From: gregory.clement at bootlin.com (Gregory CLEMENT)
Date: Fri, 21 Jan 2022 10:03:56 +0100
Subject: [PATCH] arm64: dts: armada-3720-turris-mox: Add missing
 ethernet0 alias
In-Reply-To: <20220117182006.31412-1-pali@kernel.org>
References: <20220117182006.31412-1-pali@kernel.org>
Message-ID: <875yqd5ukj.fsf@BL-laptop>

Pali Roh?r <pali at kernel.org> writes:

> U-Boot uses ethernet* aliases for setting MAC addresses. Therefore define
> also alias for ethernet0.
>
> Fixes: 7109d817db2e ("arm64: dts: marvell: add DTS for Turris Mox")
> Signed-off-by: Pali Roh?r <pali at kernel.org>

Applied on mvebu/fixes

Thanks,

Gregory


> ---
>  arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> index 23e1b07c060a..6581092c2c90 100644
> --- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> +++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts
> @@ -18,6 +18,7 @@
>  
>  	aliases {
>  		spi0 = &spi0;
> +		ethernet0 = &eth0;
>  		ethernet1 = &eth1;
>  		mmc0 = &sdhci0;
>  		mmc1 = &sdhci1;
> -- 
> 2.20.1
>

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com


From gabriel.fernandez at foss.st.com  Fri Jan 21 01:03:34 2022
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Fri, 21 Jan 2022 10:03:34 +0100
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <2502d220-e918-c6fc-6c66-16a3c7a48d5b@foss.st.com>

Hi Marek,

The split between ETHCK_K gate, ETHPTPDIV and ck_ker_eth is fine for me.
It's reflected much better the clock ethernet distribution.
However the initial code should have let the ethck gate disable if ethck 
is not used.

You can add
Acked-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>

On 1/18/22 9:29 PM, Marek Vasut wrote:
> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
> in use, ETHCKEN gate can be turned off. Current driver does not permit
> that, fix it.
> 
> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
> ETHPTP_K remain functional as before.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>      Figure 83. Peripheral clock distribution for Ethernet
>      https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/clk/clk-stm32mp1.c | 10 +++++++---
>   1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
> index 863274aa50e38..23a34ab459a3b 100644
> --- a/drivers/clk/clk-stm32mp1.c
> +++ b/drivers/clk/clk-stm32mp1.c
> @@ -2008,7 +2008,6 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>   	KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
>   	KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
>   	KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
> -	KCLK(ETHCK_K, "ethck_k", eth_src, 0, G_ETHCK, M_ETHCK),
>   
>   	/* Particulary Kernel Clocks (no mux or no gate) */
>   	MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
> @@ -2017,11 +2016,16 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>   	MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
>   	MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
>   
> -	COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE |
> +	COMPOSITE(NO_ID, "ck_ker_eth", eth_src, CLK_OPS_PARENT_ENABLE |
>   		  CLK_SET_RATE_NO_REPARENT,
>   		  _NO_GATE,
>   		  _MMUX(M_ETHCK),
> -		  _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
> +		  _NO_DIV),
> +
> +	MGATE_MP1(ETHCK_K, "ethck_k", "ck_ker_eth", 0, G_ETHCK),
> +
> +	DIV(ETHPTP_K, "ethptp_k", "ck_ker_eth", CLK_OPS_PARENT_ENABLE |
> +	    CLK_SET_RATE_NO_REPARENT, RCC_ETHCKSELR, 4, 4, 0),
>   
>   	/* RTC clock */
>   	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE,
> 


From abel.vesa at nxp.com  Fri Jan 21 01:04:16 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 21 Jan 2022 11:04:16 +0200
Subject: [PATCH 6/9] soc: imx: add i.MX8MP HSIO blk-ctrl
In-Reply-To: <20220119134027.2931945-7-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-7-l.stach@pengutronix.de>
Message-ID: <Yep3EF6VPc5LhMAE@abelvesa>

On 22-01-19 14:40:24, Lucas Stach wrote:
> The i.MX8MP added some blk-ctrl peripherals that don't follow the regular
> structure of the blk-ctrls in the previous SoCs. Add a new file for those
> with currently only the HSIO blk-ctrl being supported. Others will be added
> later on.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  drivers/soc/imx/Makefile          |   1 +
>  drivers/soc/imx/imx8mp-blk-ctrl.c | 444 ++++++++++++++++++++++++++++++
>  2 files changed, 445 insertions(+)
>  create mode 100644 drivers/soc/imx/imx8mp-blk-ctrl.c
> 
> diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
> index 8a707077914c..63cd29f6d4d2 100644
> --- a/drivers/soc/imx/Makefile
> +++ b/drivers/soc/imx/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
>  obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
>  obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
>  obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
> +obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o
> diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c

So far the imx8m-blk-ctrl is used only by i.MX8MM, while this new one is
used by i.MX8MP. Do you think we can have the generic stuff we should
probably put the generic stuff in something new called imx-blk-ctrl
(which could be used for future non-i.MX8) ? Then maybe we can have one
file per SoC that only adds the SoC specific stuff. For example, you
define those structs that look quite the same in each file. Same goes
for the probe function.

I can prepare a patch and send it, if you want.

> new file mode 100644
> index 000000000000..7f4e1a151d2b
> --- /dev/null
> +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
> @@ -0,0 +1,444 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/*
> + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_domain.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> +#include <linux/clk.h>
> +
> +#include <dt-bindings/power/imx8mp-power.h>
> +
> +#define GPR_REG0		0x0
> +#define  PCIE_CLOCK_MODULE_EN	BIT(0)
> +#define  USB_CLOCK_MODULE_EN	BIT(1)
> +
> +struct imx8mp_hsio_blk_ctrl_domain;
> +
> +struct imx8mp_hsio_blk_ctrl {
> +	struct device *dev;
> +	struct notifier_block power_nb;
> +	struct device *bus_power_dev;
> +	struct regmap *regmap;
> +	struct imx8mp_hsio_blk_ctrl_domain *domains;
> +	struct genpd_onecell_data onecell_data;
> +};
> +
> +struct imx8mp_hsio_blk_ctrl_domain_data {
> +	const char *name;
> +	const char *clk_name;
> +	const char *gpc_name;
> +};
> +
> +struct imx8mp_hsio_blk_ctrl_domain {
> +	struct generic_pm_domain genpd;
> +	struct clk *clk;
> +	struct device *power_dev;
> +	struct imx8mp_hsio_blk_ctrl *bc;
> +	int id;
> +};
> +
> +static inline struct imx8mp_hsio_blk_ctrl_domain *
> +to_imx8mp_hsio_blk_ctrl_domain(struct generic_pm_domain *genpd)
> +{
> +	return container_of(genpd, struct imx8mp_hsio_blk_ctrl_domain, genpd);
> +}
> +
> +static int imx8mp_hsio_blk_ctrl_power_on(struct generic_pm_domain *genpd)
> +{
> +	struct imx8mp_hsio_blk_ctrl_domain *domain =
> +			to_imx8mp_hsio_blk_ctrl_domain(genpd);
> +	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
> +	int ret;
> +
> +	/* make sure bus domain is awake */
> +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(bc->bus_power_dev);
> +		dev_err(bc->dev, "failed to power up bus domain\n");
> +		return ret;
> +	}
> +
> +	/* enable upstream and blk-ctrl clocks */
> +	ret = clk_prepare_enable(domain->clk);
> +	if (ret) {
> +		dev_err(bc->dev, "failed to enable clocks\n");
> +		goto bus_put;
> +	}
> +
> +	switch (domain->id) {
> +	case IMX8MP_HSIOBLK_PD_USB:
> +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> +		break;
> +	case IMX8MP_HSIOBLK_PD_PCIE:
> +		regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	/* power up upstream GPC domain */
> +	ret = pm_runtime_get_sync(domain->power_dev);
> +	if (ret < 0) {
> +		dev_err(bc->dev, "failed to power up peripheral domain\n");
> +		goto clk_disable;
> +	}
> +
> +	return 0;
> +
> +clk_disable:
> +	clk_disable_unprepare(domain->clk);
> +bus_put:
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return ret;
> +}
> +
> +static int imx8mp_hsio_blk_ctrl_power_off(struct generic_pm_domain *genpd)
> +{
> +	struct imx8mp_hsio_blk_ctrl_domain *domain =
> +			to_imx8mp_hsio_blk_ctrl_domain(genpd);
> +	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
> +
> +	/* disable clocks */
> +	switch (domain->id) {
> +	case IMX8MP_HSIOBLK_PD_USB:
> +		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> +		break;
> +	case IMX8MP_HSIOBLK_PD_PCIE:
> +		regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	clk_disable_unprepare(domain->clk);
> +
> +	/* power down upstream GPC domain */
> +	pm_runtime_put(domain->power_dev);
> +
> +	/* allow bus domain to suspend */
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return 0;
> +}
> +
> +static struct generic_pm_domain *
> +imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
> +{
> +	struct genpd_onecell_data *onecell_data = data;
> +	unsigned int index = args->args[0];
> +
> +	if (args->args_count != 1 ||
> +	    index >= onecell_data->num_domains)
> +		return ERR_PTR(-EINVAL);
> +
> +	return onecell_data->domains[index];
> +}
> +
> +static struct lock_class_key blk_ctrl_genpd_lock_class;
> +
> +static const struct imx8mp_hsio_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
> +	[IMX8MP_HSIOBLK_PD_USB] = {
> +		.name = "hsioblk-usb",
> +		.clk_name = "usb",
> +		.gpc_name = "usb",
> +	},
> +	[IMX8MP_HSIOBLK_PD_USB_PHY1] = {
> +		.name = "hsioblk-ubs-phy1",
> +		.gpc_name = "usb-phy1",
> +	},
> +	[IMX8MP_HSIOBLK_PD_USB_PHY2] = {
> +		.name = "hsioblk-ubs-phy2",
> +		.gpc_name = "usb-phy2",
> +	},
> +	[IMX8MP_HSIOBLK_PD_PCIE] = {
> +		.name = "hsioblk-pcie",
> +		.clk_name = "pcie",
> +		.gpc_name = "pcie",
> +	},
> +	[IMX8MP_HSIOBLK_PD_PCIE_PHY] = {
> +		.name = "hsioblk-pcie-phy",
> +		.gpc_name = "pcie-phy",
> +	},
> +};
> +
> +static int imx8mp_hsio_power_notifier(struct notifier_block *nb,
> +				      unsigned long action, void *data)
> +{
> +	struct imx8mp_hsio_blk_ctrl *bc = container_of(nb, struct imx8mp_hsio_blk_ctrl,
> +						 power_nb);
> +	struct clk *usb_clk = bc->domains[IMX8MP_HSIOBLK_PD_USB].clk;
> +	int ret;
> +
> +	switch (action) {
> +	case GENPD_NOTIFY_ON:
> +		/*
> +		 * enable USB clock for a moment for the power-on ADB handshake
> +		 * to proceed
> +		 */
> +		ret = clk_prepare_enable(usb_clk);
> +		if (ret)
> +			return NOTIFY_BAD;
> +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> +
> +		udelay(5);
> +
> +		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> +		clk_disable_unprepare(usb_clk);
> +		break;
> +	case GENPD_NOTIFY_PRE_OFF:
> +		/* enable USB clock for the power-down ADB handshake to work */
> +		ret = clk_prepare_enable(usb_clk);
> +		if (ret)
> +			return NOTIFY_BAD;
> +
> +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> +		break;
> +	case GENPD_NOTIFY_OFF:
> +		clk_disable_unprepare(usb_clk);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return NOTIFY_OK;
> +}
> +
> +static int imx8mp_hsio_blk_ctrl_probe(struct platform_device *pdev)
> +{
> +	int num_domains = ARRAY_SIZE(imx8mp_hsio_domain_data);
> +	struct device *dev = &pdev->dev;
> +	struct imx8mp_hsio_blk_ctrl *bc;
> +	void __iomem *base;
> +	int i, ret;
> +
> +	struct regmap_config regmap_config = {
> +		.reg_bits	= 32,
> +		.val_bits	= 32,
> +		.reg_stride	= 4,
> +		.max_register	= 0x24,
> +	};
> +
> +	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
> +	if (!bc)
> +		return -ENOMEM;
> +
> +	bc->dev = dev;
> +
> +	base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(base))
> +		return PTR_ERR(base);
> +
> +	bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
> +	if (IS_ERR(bc->regmap))
> +		return dev_err_probe(dev, PTR_ERR(bc->regmap),
> +				     "failed to init regmap\n");
> +
> +	bc->domains = devm_kcalloc(dev, num_domains,
> +				   sizeof(struct imx8mp_hsio_blk_ctrl_domain),
> +				   GFP_KERNEL);
> +	if (!bc->domains)
> +		return -ENOMEM;
> +
> +	bc->onecell_data.num_domains = num_domains;
> +	bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
> +	bc->onecell_data.domains =
> +		devm_kcalloc(dev, num_domains,
> +			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
> +	if (!bc->onecell_data.domains)
> +		return -ENOMEM;
> +
> +	bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus");
> +	if (IS_ERR(bc->bus_power_dev))
> +		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
> +				     "failed to attach power domain\n");
> +
> +	for (i = 0; i < num_domains; i++) {
> +		const struct imx8mp_hsio_blk_ctrl_domain_data *data =
> +				&imx8mp_hsio_domain_data[i];
> +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> +
> +		if (data->clk_name) {
> +			domain->clk = devm_clk_get(dev, data->clk_name);
> +			if (IS_ERR(domain->clk)) {
> +				ret = PTR_ERR(domain->clk);
> +				dev_err_probe(dev, ret, "failed to get clock\n");
> +				goto cleanup_pds;
> +			}
> +		}
> +
> +		domain->power_dev =
> +			dev_pm_domain_attach_by_name(dev, data->gpc_name);
> +		if (IS_ERR(domain->power_dev)) {
> +			dev_err_probe(dev, PTR_ERR(domain->power_dev),
> +				      "failed to attach power domain\n");
> +			ret = PTR_ERR(domain->power_dev);
> +			goto cleanup_pds;
> +		}
> +
> +		domain->genpd.name = data->name;
> +		domain->genpd.power_on = imx8mp_hsio_blk_ctrl_power_on;
> +		domain->genpd.power_off = imx8mp_hsio_blk_ctrl_power_off;
> +		domain->bc = bc;
> +		domain->id = i;
> +
> +		ret = pm_genpd_init(&domain->genpd, NULL, true);
> +		if (ret) {
> +			dev_err_probe(dev, ret, "failed to init power domain\n");
> +			dev_pm_domain_detach(domain->power_dev, true);
> +			goto cleanup_pds;
> +		}
> +
> +		/*
> +		 * We use runtime PM to trigger power on/off of the upstream GPC
> +		 * domain, as a strict hierarchical parent/child power domain
> +		 * setup doesn't allow us to meet the sequencing requirements.
> +		 * This means we have nested locking of genpd locks, without the
> +		 * nesting being visible at the genpd level, so we need a
> +		 * separate lock class to make lockdep aware of the fact that
> +		 * this are separate domain locks that can be nested without a
> +		 * self-deadlock.
> +		 */
> +		lockdep_set_class(&domain->genpd.mlock,
> +				  &blk_ctrl_genpd_lock_class);
> +
> +		bc->onecell_data.domains[i] = &domain->genpd;
> +	}
> +
> +	ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to add power domain provider\n");
> +		goto cleanup_pds;
> +	}
> +
> +	bc->power_nb.notifier_call = imx8mp_hsio_power_notifier;
> +	ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to add power notifier\n");
> +		goto cleanup_provider;
> +	}
> +
> +	dev_set_drvdata(dev, bc);
> +
> +	return 0;
> +
> +cleanup_provider:
> +	of_genpd_del_provider(dev->of_node);
> +cleanup_pds:
> +	for (i--; i >= 0; i--) {
> +		pm_genpd_remove(&bc->domains[i].genpd);
> +		dev_pm_domain_detach(bc->domains[i].power_dev, true);
> +	}
> +
> +	dev_pm_domain_detach(bc->bus_power_dev, true);
> +
> +	return ret;
> +}
> +
> +static int imx8mp_hsio_blk_ctrl_remove(struct platform_device *pdev)
> +{
> +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
> +	int i;
> +
> +	of_genpd_del_provider(pdev->dev.of_node);
> +
> +	for (i = 0; bc->onecell_data.num_domains; i++) {
> +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> +
> +		pm_genpd_remove(&domain->genpd);
> +		dev_pm_domain_detach(domain->power_dev, true);
> +	}
> +
> +	dev_pm_genpd_remove_notifier(bc->bus_power_dev);
> +
> +	dev_pm_domain_detach(bc->bus_power_dev, true);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int imx8mp_hsio_blk_ctrl_suspend(struct device *dev)
> +{
> +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
> +	int ret, i;
> +
> +	/*
> +	 * This may look strange, but is done so the generic PM_SLEEP code
> +	 * can power down our domains and more importantly power them up again
> +	 * after resume, without tripping over our usage of runtime PM to
> +	 * control the upstream GPC domains. Things happen in the right order
> +	 * in the system suspend/resume paths due to the device parent/child
> +	 * hierarchy.
> +	 */
> +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(bc->bus_power_dev);
> +		return ret;
> +	}
> +
> +	for (i = 0; i < bc->onecell_data.num_domains; i++) {
> +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> +
> +		ret = pm_runtime_get_sync(domain->power_dev);
> +		if (ret < 0) {
> +			pm_runtime_put_noidle(domain->power_dev);
> +			goto out_fail;
> +		}
> +	}
> +
> +	return 0;
> +
> +out_fail:
> +	for (i--; i >= 0; i--)
> +		pm_runtime_put(bc->domains[i].power_dev);
> +
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return ret;
> +}
> +
> +static int imx8mp_hsio_blk_ctrl_resume(struct device *dev)
> +{
> +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
> +	int i;
> +
> +	for (i = 0; i < bc->onecell_data.num_domains; i++)
> +		pm_runtime_put(bc->domains[i].power_dev);
> +
> +	pm_runtime_put(bc->bus_power_dev);
> +
> +	return 0;
> +}
> +#endif
> +
> +static const struct dev_pm_ops imx8mp_hsio_blk_ctrl_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(imx8mp_hsio_blk_ctrl_suspend,
> +				imx8mp_hsio_blk_ctrl_resume)
> +};
> +
> +static const struct of_device_id imx8mp_hsio_blk_ctrl_of_match[] = {
> +	{
> +		.compatible = "fsl,imx8mp-hsio-blk-ctrl",
> +	}, {
> +		/* Sentinel */
> +	}
> +};
> +MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
> +
> +static struct platform_driver imx8mp_hsio_blk_ctrl_driver = {
> +	.probe = imx8mp_hsio_blk_ctrl_probe,
> +	.remove = imx8mp_hsio_blk_ctrl_remove,
> +	.driver = {
> +		.name = "imx8mp-hsio-blk-ctrl",
> +		.pm = &imx8mp_hsio_blk_ctrl_pm_ops,
> +		.of_match_table = imx8mp_hsio_blk_ctrl_of_match,
> +	},
> +};
> +module_platform_driver(imx8mp_hsio_blk_ctrl_driver);
> -- 
> 2.30.2
>


From gabriel.fernandez at foss.st.com  Fri Jan 21 01:05:04 2022
From: gabriel.fernandez at foss.st.com (gabriel.fernandez at foss.st.com)
Date: Fri, 21 Jan 2022 10:05:04 +0100
Subject: [PATCH 2/5] clk: stm32mp1: Add parent_data to ETHRX clock
In-Reply-To: <20220118202958.1840431-2-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-2-marex@denx.de>
Message-ID: <9c62790d-b6ee-1462-0a9f-9c5b0bd71a23@foss.st.com>

Hi Marek,

Thanks for the patchet.

You can add

Acked-by: Gabriel Fernandez <gabriel.fernandez at foss.st.com>




On 1/18/22 9:29 PM, Marek Vasut wrote:
> Pass parent_data to ETHRX clock with new fw_name = "ETH_RX_CLK/ETH_REF_CLK".
> By default, this change has no impact on the operation of the clock driver.
> However, due to the fw_name, it permits DT to override ETHRX clock parent,
> which might be needed in case the ETHRX clock are supplied by external clock
> source.
> 
> Example of MCO2 supplying clock to ETH_RX_CLK via external pad-to-pad wire:
> &rcc {
>           clocks = <&rcc CK_MCO2>;
>           clock-names = "ETH_RX_CLK/ETH_REF_CLK";
> };
> 
> Note that while this patch permits to implement this rare usecase, the issue
> with ethernet RX and TX input clock modeling on MP1 is far more complex and
> requires more core plumbing.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>      Figure 83. Peripheral clock distribution for Ethernet
>      https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---
>   drivers/clk/clk-stm32mp1.c | 36 ++++++++++++++++++++++++++++++++----
>   1 file changed, 32 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
> index 23a34ab459a3b..7ad2e6203baef 100644
> --- a/drivers/clk/clk-stm32mp1.c
> +++ b/drivers/clk/clk-stm32mp1.c
> @@ -155,6 +155,10 @@ static const char * const eth_src[] = {
>   	"pll4_p", "pll3_q"
>   };
>   
> +const struct clk_parent_data ethrx_src[] = {
> +	{ .name = "ethck_k", .fw_name = "ETH_RX_CLK/ETH_REF_CLK" },
> +};
> +
>   static const char * const rng_src[] = {
>   	"ck_csi", "pll4_r", "ck_lse", "ck_lsi"
>   };
> @@ -317,6 +321,7 @@ struct clock_config {
>   	const char *name;
>   	const char *parent_name;
>   	const char * const *parent_names;
> +	const struct clk_parent_data *parent_data;
>   	int num_parents;
>   	unsigned long flags;
>   	void *cfg;
> @@ -576,6 +581,7 @@ static struct clk_hw *
>   clk_stm32_register_gate_ops(struct device *dev,
>   			    const char *name,
>   			    const char *parent_name,
> +			    const struct clk_parent_data *parent_data,
>   			    unsigned long flags,
>   			    void __iomem *base,
>   			    const struct stm32_gate_cfg *cfg,
> @@ -586,7 +592,10 @@ clk_stm32_register_gate_ops(struct device *dev,
>   	int ret;
>   
>   	init.name = name;
> -	init.parent_names = &parent_name;
> +	if (parent_name)
> +		init.parent_names = &parent_name;
> +	if (parent_data)
> +		init.parent_data = parent_data;
>   	init.num_parents = 1;
>   	init.flags = flags;
>   
> @@ -611,6 +620,7 @@ clk_stm32_register_gate_ops(struct device *dev,
>   static struct clk_hw *
>   clk_stm32_register_composite(struct device *dev,
>   			     const char *name, const char * const *parent_names,
> +			     const struct clk_parent_data *parent_data,
>   			     int num_parents, void __iomem *base,
>   			     const struct stm32_composite_cfg *cfg,
>   			     unsigned long flags, spinlock_t *lock)
> @@ -1135,6 +1145,7 @@ _clk_stm32_register_gate(struct device *dev,
>   	return clk_stm32_register_gate_ops(dev,
>   				    cfg->name,
>   				    cfg->parent_name,
> +				    cfg->parent_data,
>   				    cfg->flags,
>   				    base,
>   				    cfg->cfg,
> @@ -1148,8 +1159,8 @@ _clk_stm32_register_composite(struct device *dev,
>   			      const struct clock_config *cfg)
>   {
>   	return clk_stm32_register_composite(dev, cfg->name, cfg->parent_names,
> -					    cfg->num_parents, base, cfg->cfg,
> -					    cfg->flags, lock);
> +					    cfg->parent_data, cfg->num_parents,
> +					    base, cfg->cfg, cfg->flags, lock);
>   }
>   
>   #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
> @@ -1258,6 +1269,16 @@ _clk_stm32_register_composite(struct device *dev,
>   	.func		= _clk_stm32_register_gate,\
>   }
>   
> +#define STM32_GATE_PDATA(_id, _name, _parent, _flags, _gate)\
> +{\
> +	.id		= _id,\
> +	.name		= _name,\
> +	.parent_data	= _parent,\
> +	.flags		= _flags,\
> +	.cfg		= (struct stm32_gate_cfg *) {_gate},\
> +	.func		= _clk_stm32_register_gate,\
> +}
> +
>   #define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _mgate, _ops)\
>   	(&(struct stm32_gate_cfg) {\
>   		&(struct gate_cfg) {\
> @@ -1291,6 +1312,10 @@ _clk_stm32_register_composite(struct device *dev,
>   	STM32_GATE(_id, _name, _parent, _flags,\
>   		   _STM32_MGATE(_mgate))
>   
> +#define MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)\
> +	STM32_GATE_PDATA(_id, _name, _parent, _flags,\
> +		   _STM32_MGATE(_mgate))
> +
>   #define _STM32_DIV(_div_offset, _div_shift, _div_width,\
>   		   _div_flags, _div_table, _ops)\
>   	.div = &(struct stm32_div_cfg) {\
> @@ -1354,6 +1379,9 @@ _clk_stm32_register_composite(struct device *dev,
>   #define PCLK(_id, _name, _parent, _flags, _mgate)\
>   	MGATE_MP1(_id, _name, _parent, _flags, _mgate)
>   
> +#define PCLK_PDATA(_id, _name, _parent, _flags, _mgate)\
> +	MGATE_MP1_PDATA(_id, _name, _parent, _flags, _mgate)
> +
>   #define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
>   	     COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE |\
>   		       CLK_SET_RATE_NO_REPARENT | _flags,\
> @@ -1951,7 +1979,7 @@ static const struct clock_config stm32mp1_clock_cfg[] = {
>   	PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
>   	PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
>   	PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
> -	PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX),
> +	PCLK_PDATA(ETHRX, "ethrx", ethrx_src, 0, G_ETHRX),
>   	PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
>   	PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
>   	PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
> 


From gregory.clement at bootlin.com  Fri Jan 21 01:17:49 2022
From: gregory.clement at bootlin.com (Gregory CLEMENT)
Date: Fri, 21 Jan 2022 10:17:49 +0100
Subject: [PATCH v2 1/1] ARM: orion/gpio: Get rid of unused first
 parameter in orion_gpio_init()
In-Reply-To: <20211214140656.53694-1-andriy.shevchenko@linux.intel.com>
References: <20211214140656.53694-1-andriy.shevchenko@linux.intel.com>
Message-ID: <8735lh5txe.fsf@BL-laptop>

Andy Shevchenko <andriy.shevchenko at linux.intel.com> writes:

> The OF node pointer is always NULL, get rid of unused parameter in
> orion_gpio_init(). As a side effect it will allow to switch GPIO
> library to the fwnode API, as well as in case of resurrecting it here
> it should be fwnode_handle anyways.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>


Applied on mvebu/arm

Thanks,

Gregory

> ---
> v2: wrapped to 80 limit (Russell)
>  arch/arm/mach-dove/irq.c                      | 6 +++---
>  arch/arm/mach-mv78xx0/irq.c                   | 3 +--
>  arch/arm/mach-orion5x/irq.c                   | 2 +-
>  arch/arm/plat-orion/gpio.c                    | 8 ++------
>  arch/arm/plat-orion/include/plat/orion-gpio.h | 3 +--
>  5 files changed, 8 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
> index 31ccbcee2627..d36f6b8269c2 100644
> --- a/arch/arm/mach-dove/irq.c
> +++ b/arch/arm/mach-dove/irq.c
> @@ -73,12 +73,12 @@ void __init dove_init_irq(void)
>  	/*
>  	 * Initialize gpiolib for GPIOs 0-71.
>  	 */
> -	orion_gpio_init(NULL, 0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
> +	orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
>  			IRQ_DOVE_GPIO_START, gpio0_irqs);
>  
> -	orion_gpio_init(NULL, 32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
> +	orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
>  			IRQ_DOVE_GPIO_START + 32, gpio1_irqs);
>  
> -	orion_gpio_init(NULL, 64, 8, DOVE_GPIO2_VIRT_BASE, 0,
> +	orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
>  			IRQ_DOVE_GPIO_START + 64, gpio2_irqs);
>  }
> diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
> index 788569e960e1..0b5f055ca1c3 100644
> --- a/arch/arm/mach-mv78xx0/irq.c
> +++ b/arch/arm/mach-mv78xx0/irq.c
> @@ -67,7 +67,6 @@ void __init mv78xx0_init_irq(void)
>  	 * registers for core #1 are at an offset of 0x18 from those of
>  	 * core #0.)
>  	 */
> -	orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE,
> -			mv78xx0_core_index() ? 0x18 : 0,
> +	orion_gpio_init(0, 32, GPIO_VIRT_BASE, mv78xx0_core_index() ? 0x18 : 0,
>  			IRQ_MV78XX0_GPIO_START, gpio0_irqs);
>  }
> diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
> index ac4af2283bef..1ae775d02d90 100644
> --- a/arch/arm/mach-orion5x/irq.c
> +++ b/arch/arm/mach-orion5x/irq.c
> @@ -49,6 +49,6 @@ void __init orion5x_init_irq(void)
>  	/*
>  	 * Initialize gpiolib for GPIOs 0-31.
>  	 */
> -	orion_gpio_init(NULL, 0, 32, GPIO_VIRT_BASE, 0,
> +	orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0,
>  			IRQ_ORION5X_GPIO_START, gpio0_irqs);
>  }
> diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
> index 734f0be4f14a..3ef9ecdd6343 100644
> --- a/arch/arm/plat-orion/gpio.c
> +++ b/arch/arm/plat-orion/gpio.c
> @@ -516,8 +516,7 @@ static void orion_gpio_mask_irq(struct irq_data *d)
>  	irq_gc_unlock(gc);
>  }
>  
> -void __init orion_gpio_init(struct device_node *np,
> -			    int gpio_base, int ngpio,
> +void __init orion_gpio_init(int gpio_base, int ngpio,
>  			    void __iomem *base, int mask_offset,
>  			    int secondary_irq_base,
>  			    int irqs[4])
> @@ -545,9 +544,6 @@ void __init orion_gpio_init(struct device_node *np,
>  	ochip->chip.base = gpio_base;
>  	ochip->chip.ngpio = ngpio;
>  	ochip->chip.can_sleep = 0;
> -#ifdef CONFIG_OF
> -	ochip->chip.of_node = np;
> -#endif
>  	ochip->chip.dbg_show = orion_gpio_dbg_show;
>  
>  	spin_lock_init(&ochip->lock);
> @@ -605,7 +601,7 @@ void __init orion_gpio_init(struct device_node *np,
>  			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
>  
>  	/* Setup irq domain on top of the generic chip. */
> -	ochip->domain = irq_domain_add_legacy(np,
> +	ochip->domain = irq_domain_add_legacy(NULL,
>  					      ochip->chip.ngpio,
>  					      ochip->secondary_irq_base,
>  					      ochip->secondary_irq_base,
> diff --git a/arch/arm/plat-orion/include/plat/orion-gpio.h b/arch/arm/plat-orion/include/plat/orion-gpio.h
> index e856b073a9c8..25a2963e0e0f 100644
> --- a/arch/arm/plat-orion/include/plat/orion-gpio.h
> +++ b/arch/arm/plat-orion/include/plat/orion-gpio.h
> @@ -30,8 +30,7 @@ int orion_gpio_led_blink_set(struct gpio_desc *desc, int state,
>  void orion_gpio_set_valid(unsigned pin, int mode);
>  
>  /* Initialize gpiolib. */
> -void __init orion_gpio_init(struct device_node *np,
> -			    int gpio_base, int ngpio,
> +void __init orion_gpio_init(int gpio_base, int ngpio,
>  			    void __iomem *base, int mask_offset,
>  			    int secondary_irq_base,
>  			    int irq[4]);
> -- 
> 2.33.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Gregory Clement, Bootlin
Embedded Linux and Kernel engineering
http://bootlin.com


From l.stach at pengutronix.de  Fri Jan 21 01:19:32 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 21 Jan 2022 10:19:32 +0100
Subject: [PATCH 6/9] soc: imx: add i.MX8MP HSIO blk-ctrl
In-Reply-To: <Yep3EF6VPc5LhMAE@abelvesa>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-7-l.stach@pengutronix.de>
 <Yep3EF6VPc5LhMAE@abelvesa>
Message-ID: <fb539bab6302c870f4d78b1039400a1b1835300a.camel@pengutronix.de>

Hi Abel,

Am Freitag, dem 21.01.2022 um 11:04 +0200 schrieb Abel Vesa:
> On 22-01-19 14:40:24, Lucas Stach wrote:
> > The i.MX8MP added some blk-ctrl peripherals that don't follow the regular
> > structure of the blk-ctrls in the previous SoCs. Add a new file for those
> > with currently only the HSIO blk-ctrl being supported. Others will be added
> > later on.
> > 
> > Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> > ---
> >  drivers/soc/imx/Makefile          |   1 +
> >  drivers/soc/imx/imx8mp-blk-ctrl.c | 444 ++++++++++++++++++++++++++++++
> >  2 files changed, 445 insertions(+)
> >  create mode 100644 drivers/soc/imx/imx8mp-blk-ctrl.c
> > 
> > diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
> > index 8a707077914c..63cd29f6d4d2 100644
> > --- a/drivers/soc/imx/Makefile
> > +++ b/drivers/soc/imx/Makefile
> > @@ -6,3 +6,4 @@ obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
> >  obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
> >  obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
> >  obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
> > +obj-$(CONFIG_SOC_IMX8M) += imx8mp-blk-ctrl.o
> > diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c
> 
> So far the imx8m-blk-ctrl is used only by i.MX8MM, while this new one is
> used by i.MX8MP. Do you think we can have the generic stuff we should
> probably put the generic stuff in something new called imx-blk-ctrl
> (which could be used for future non-i.MX8) ? Then maybe we can have one
> file per SoC that only adds the SoC specific stuff. For example, you
> define those structs that look quite the same in each file. Same goes
> for the probe function.
> 
The i.MX8MP VPU and MEDIA blk-ctrls also match the structure laid out
in imx8m-blk-ctrl and should use this driver. HSIO, AUDIO and HDMI
however don't have that regular clk/reset register structure and need
special handling, that's why I added the new file for those.
 
> I can prepare a patch and send it, if you want.

For now I didn't consider the overlap big enough to warrant that. While
many things look similar they are different in little details, so I
didn't want to start with adding abstractions there. Usually it's
easier to first (mostly) duplicate some code and then refactor to
abstract some things and move them into common code when you have the
full picture where the real overlap is. Trying to move too much stuff
into common code before having the full picture is usually a recipe for
unreadable code.

However, I won't stop you from giving it a shot. I just think it would
be better to first get all the blk-ctrls on the 8MP working, even with
some duplication, and then clean things up when we have a more complete
picture.

Regards,
Lucas

> 
> > new file mode 100644
> > index 000000000000..7f4e1a151d2b
> > --- /dev/null
> > +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c
> > @@ -0,0 +1,444 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +/*
> > + * Copyright 2022 Pengutronix, Lucas Stach <kernel at pengutronix.de>
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/pm_domain.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/regmap.h>
> > +#include <linux/clk.h>
> > +
> > +#include <dt-bindings/power/imx8mp-power.h>
> > +
> > +#define GPR_REG0		0x0
> > +#define  PCIE_CLOCK_MODULE_EN	BIT(0)
> > +#define  USB_CLOCK_MODULE_EN	BIT(1)
> > +
> > +struct imx8mp_hsio_blk_ctrl_domain;
> > +
> > +struct imx8mp_hsio_blk_ctrl {
> > +	struct device *dev;
> > +	struct notifier_block power_nb;
> > +	struct device *bus_power_dev;
> > +	struct regmap *regmap;
> > +	struct imx8mp_hsio_blk_ctrl_domain *domains;
> > +	struct genpd_onecell_data onecell_data;
> > +};
> > +
> > +struct imx8mp_hsio_blk_ctrl_domain_data {
> > +	const char *name;
> > +	const char *clk_name;
> > +	const char *gpc_name;
> > +};
> > +
> > +struct imx8mp_hsio_blk_ctrl_domain {
> > +	struct generic_pm_domain genpd;
> > +	struct clk *clk;
> > +	struct device *power_dev;
> > +	struct imx8mp_hsio_blk_ctrl *bc;
> > +	int id;
> > +};
> > +
> > +static inline struct imx8mp_hsio_blk_ctrl_domain *
> > +to_imx8mp_hsio_blk_ctrl_domain(struct generic_pm_domain *genpd)
> > +{
> > +	return container_of(genpd, struct imx8mp_hsio_blk_ctrl_domain, genpd);
> > +}
> > +
> > +static int imx8mp_hsio_blk_ctrl_power_on(struct generic_pm_domain *genpd)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl_domain *domain =
> > +			to_imx8mp_hsio_blk_ctrl_domain(genpd);
> > +	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
> > +	int ret;
> > +
> > +	/* make sure bus domain is awake */
> > +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> > +	if (ret < 0) {
> > +		pm_runtime_put_noidle(bc->bus_power_dev);
> > +		dev_err(bc->dev, "failed to power up bus domain\n");
> > +		return ret;
> > +	}
> > +
> > +	/* enable upstream and blk-ctrl clocks */
> > +	ret = clk_prepare_enable(domain->clk);
> > +	if (ret) {
> > +		dev_err(bc->dev, "failed to enable clocks\n");
> > +		goto bus_put;
> > +	}
> > +
> > +	switch (domain->id) {
> > +	case IMX8MP_HSIOBLK_PD_USB:
> > +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> > +		break;
> > +	case IMX8MP_HSIOBLK_PD_PCIE:
> > +		regmap_set_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	/* power up upstream GPC domain */
> > +	ret = pm_runtime_get_sync(domain->power_dev);
> > +	if (ret < 0) {
> > +		dev_err(bc->dev, "failed to power up peripheral domain\n");
> > +		goto clk_disable;
> > +	}
> > +
> > +	return 0;
> > +
> > +clk_disable:
> > +	clk_disable_unprepare(domain->clk);
> > +bus_put:
> > +	pm_runtime_put(bc->bus_power_dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static int imx8mp_hsio_blk_ctrl_power_off(struct generic_pm_domain *genpd)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl_domain *domain =
> > +			to_imx8mp_hsio_blk_ctrl_domain(genpd);
> > +	struct imx8mp_hsio_blk_ctrl *bc = domain->bc;
> > +
> > +	/* disable clocks */
> > +	switch (domain->id) {
> > +	case IMX8MP_HSIOBLK_PD_USB:
> > +		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> > +		break;
> > +	case IMX8MP_HSIOBLK_PD_PCIE:
> > +		regmap_clear_bits(bc->regmap, GPR_REG0, PCIE_CLOCK_MODULE_EN);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	clk_disable_unprepare(domain->clk);
> > +
> > +	/* power down upstream GPC domain */
> > +	pm_runtime_put(domain->power_dev);
> > +
> > +	/* allow bus domain to suspend */
> > +	pm_runtime_put(bc->bus_power_dev);
> > +
> > +	return 0;
> > +}
> > +
> > +static struct generic_pm_domain *
> > +imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
> > +{
> > +	struct genpd_onecell_data *onecell_data = data;
> > +	unsigned int index = args->args[0];
> > +
> > +	if (args->args_count != 1 ||
> > +	    index >= onecell_data->num_domains)
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	return onecell_data->domains[index];
> > +}
> > +
> > +static struct lock_class_key blk_ctrl_genpd_lock_class;
> > +
> > +static const struct imx8mp_hsio_blk_ctrl_domain_data imx8mp_hsio_domain_data[] = {
> > +	[IMX8MP_HSIOBLK_PD_USB] = {
> > +		.name = "hsioblk-usb",
> > +		.clk_name = "usb",
> > +		.gpc_name = "usb",
> > +	},
> > +	[IMX8MP_HSIOBLK_PD_USB_PHY1] = {
> > +		.name = "hsioblk-ubs-phy1",
> > +		.gpc_name = "usb-phy1",
> > +	},
> > +	[IMX8MP_HSIOBLK_PD_USB_PHY2] = {
> > +		.name = "hsioblk-ubs-phy2",
> > +		.gpc_name = "usb-phy2",
> > +	},
> > +	[IMX8MP_HSIOBLK_PD_PCIE] = {
> > +		.name = "hsioblk-pcie",
> > +		.clk_name = "pcie",
> > +		.gpc_name = "pcie",
> > +	},
> > +	[IMX8MP_HSIOBLK_PD_PCIE_PHY] = {
> > +		.name = "hsioblk-pcie-phy",
> > +		.gpc_name = "pcie-phy",
> > +	},
> > +};
> > +
> > +static int imx8mp_hsio_power_notifier(struct notifier_block *nb,
> > +				      unsigned long action, void *data)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl *bc = container_of(nb, struct imx8mp_hsio_blk_ctrl,
> > +						 power_nb);
> > +	struct clk *usb_clk = bc->domains[IMX8MP_HSIOBLK_PD_USB].clk;
> > +	int ret;
> > +
> > +	switch (action) {
> > +	case GENPD_NOTIFY_ON:
> > +		/*
> > +		 * enable USB clock for a moment for the power-on ADB handshake
> > +		 * to proceed
> > +		 */
> > +		ret = clk_prepare_enable(usb_clk);
> > +		if (ret)
> > +			return NOTIFY_BAD;
> > +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> > +
> > +		udelay(5);
> > +
> > +		regmap_clear_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> > +		clk_disable_unprepare(usb_clk);
> > +		break;
> > +	case GENPD_NOTIFY_PRE_OFF:
> > +		/* enable USB clock for the power-down ADB handshake to work */
> > +		ret = clk_prepare_enable(usb_clk);
> > +		if (ret)
> > +			return NOTIFY_BAD;
> > +
> > +		regmap_set_bits(bc->regmap, GPR_REG0, USB_CLOCK_MODULE_EN);
> > +		break;
> > +	case GENPD_NOTIFY_OFF:
> > +		clk_disable_unprepare(usb_clk);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return NOTIFY_OK;
> > +}
> > +
> > +static int imx8mp_hsio_blk_ctrl_probe(struct platform_device *pdev)
> > +{
> > +	int num_domains = ARRAY_SIZE(imx8mp_hsio_domain_data);
> > +	struct device *dev = &pdev->dev;
> > +	struct imx8mp_hsio_blk_ctrl *bc;
> > +	void __iomem *base;
> > +	int i, ret;
> > +
> > +	struct regmap_config regmap_config = {
> > +		.reg_bits	= 32,
> > +		.val_bits	= 32,
> > +		.reg_stride	= 4,
> > +		.max_register	= 0x24,
> > +	};
> > +
> > +	bc = devm_kzalloc(dev, sizeof(*bc), GFP_KERNEL);
> > +	if (!bc)
> > +		return -ENOMEM;
> > +
> > +	bc->dev = dev;
> > +
> > +	base = devm_platform_ioremap_resource(pdev, 0);
> > +	if (IS_ERR(base))
> > +		return PTR_ERR(base);
> > +
> > +	bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
> > +	if (IS_ERR(bc->regmap))
> > +		return dev_err_probe(dev, PTR_ERR(bc->regmap),
> > +				     "failed to init regmap\n");
> > +
> > +	bc->domains = devm_kcalloc(dev, num_domains,
> > +				   sizeof(struct imx8mp_hsio_blk_ctrl_domain),
> > +				   GFP_KERNEL);
> > +	if (!bc->domains)
> > +		return -ENOMEM;
> > +
> > +	bc->onecell_data.num_domains = num_domains;
> > +	bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
> > +	bc->onecell_data.domains =
> > +		devm_kcalloc(dev, num_domains,
> > +			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
> > +	if (!bc->onecell_data.domains)
> > +		return -ENOMEM;
> > +
> > +	bc->bus_power_dev = genpd_dev_pm_attach_by_name(dev, "bus");
> > +	if (IS_ERR(bc->bus_power_dev))
> > +		return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev),
> > +				     "failed to attach power domain\n");
> > +
> > +	for (i = 0; i < num_domains; i++) {
> > +		const struct imx8mp_hsio_blk_ctrl_domain_data *data =
> > +				&imx8mp_hsio_domain_data[i];
> > +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> > +
> > +		if (data->clk_name) {
> > +			domain->clk = devm_clk_get(dev, data->clk_name);
> > +			if (IS_ERR(domain->clk)) {
> > +				ret = PTR_ERR(domain->clk);
> > +				dev_err_probe(dev, ret, "failed to get clock\n");
> > +				goto cleanup_pds;
> > +			}
> > +		}
> > +
> > +		domain->power_dev =
> > +			dev_pm_domain_attach_by_name(dev, data->gpc_name);
> > +		if (IS_ERR(domain->power_dev)) {
> > +			dev_err_probe(dev, PTR_ERR(domain->power_dev),
> > +				      "failed to attach power domain\n");
> > +			ret = PTR_ERR(domain->power_dev);
> > +			goto cleanup_pds;
> > +		}
> > +
> > +		domain->genpd.name = data->name;
> > +		domain->genpd.power_on = imx8mp_hsio_blk_ctrl_power_on;
> > +		domain->genpd.power_off = imx8mp_hsio_blk_ctrl_power_off;
> > +		domain->bc = bc;
> > +		domain->id = i;
> > +
> > +		ret = pm_genpd_init(&domain->genpd, NULL, true);
> > +		if (ret) {
> > +			dev_err_probe(dev, ret, "failed to init power domain\n");
> > +			dev_pm_domain_detach(domain->power_dev, true);
> > +			goto cleanup_pds;
> > +		}
> > +
> > +		/*
> > +		 * We use runtime PM to trigger power on/off of the upstream GPC
> > +		 * domain, as a strict hierarchical parent/child power domain
> > +		 * setup doesn't allow us to meet the sequencing requirements.
> > +		 * This means we have nested locking of genpd locks, without the
> > +		 * nesting being visible at the genpd level, so we need a
> > +		 * separate lock class to make lockdep aware of the fact that
> > +		 * this are separate domain locks that can be nested without a
> > +		 * self-deadlock.
> > +		 */
> > +		lockdep_set_class(&domain->genpd.mlock,
> > +				  &blk_ctrl_genpd_lock_class);
> > +
> > +		bc->onecell_data.domains[i] = &domain->genpd;
> > +	}
> > +
> > +	ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data);
> > +	if (ret) {
> > +		dev_err_probe(dev, ret, "failed to add power domain provider\n");
> > +		goto cleanup_pds;
> > +	}
> > +
> > +	bc->power_nb.notifier_call = imx8mp_hsio_power_notifier;
> > +	ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb);
> > +	if (ret) {
> > +		dev_err_probe(dev, ret, "failed to add power notifier\n");
> > +		goto cleanup_provider;
> > +	}
> > +
> > +	dev_set_drvdata(dev, bc);
> > +
> > +	return 0;
> > +
> > +cleanup_provider:
> > +	of_genpd_del_provider(dev->of_node);
> > +cleanup_pds:
> > +	for (i--; i >= 0; i--) {
> > +		pm_genpd_remove(&bc->domains[i].genpd);
> > +		dev_pm_domain_detach(bc->domains[i].power_dev, true);
> > +	}
> > +
> > +	dev_pm_domain_detach(bc->bus_power_dev, true);
> > +
> > +	return ret;
> > +}
> > +
> > +static int imx8mp_hsio_blk_ctrl_remove(struct platform_device *pdev)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
> > +	int i;
> > +
> > +	of_genpd_del_provider(pdev->dev.of_node);
> > +
> > +	for (i = 0; bc->onecell_data.num_domains; i++) {
> > +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> > +
> > +		pm_genpd_remove(&domain->genpd);
> > +		dev_pm_domain_detach(domain->power_dev, true);
> > +	}
> > +
> > +	dev_pm_genpd_remove_notifier(bc->bus_power_dev);
> > +
> > +	dev_pm_domain_detach(bc->bus_power_dev, true);
> > +
> > +	return 0;
> > +}
> > +
> > +#ifdef CONFIG_PM_SLEEP
> > +static int imx8mp_hsio_blk_ctrl_suspend(struct device *dev)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
> > +	int ret, i;
> > +
> > +	/*
> > +	 * This may look strange, but is done so the generic PM_SLEEP code
> > +	 * can power down our domains and more importantly power them up again
> > +	 * after resume, without tripping over our usage of runtime PM to
> > +	 * control the upstream GPC domains. Things happen in the right order
> > +	 * in the system suspend/resume paths due to the device parent/child
> > +	 * hierarchy.
> > +	 */
> > +	ret = pm_runtime_get_sync(bc->bus_power_dev);
> > +	if (ret < 0) {
> > +		pm_runtime_put_noidle(bc->bus_power_dev);
> > +		return ret;
> > +	}
> > +
> > +	for (i = 0; i < bc->onecell_data.num_domains; i++) {
> > +		struct imx8mp_hsio_blk_ctrl_domain *domain = &bc->domains[i];
> > +
> > +		ret = pm_runtime_get_sync(domain->power_dev);
> > +		if (ret < 0) {
> > +			pm_runtime_put_noidle(domain->power_dev);
> > +			goto out_fail;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +
> > +out_fail:
> > +	for (i--; i >= 0; i--)
> > +		pm_runtime_put(bc->domains[i].power_dev);
> > +
> > +	pm_runtime_put(bc->bus_power_dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static int imx8mp_hsio_blk_ctrl_resume(struct device *dev)
> > +{
> > +	struct imx8mp_hsio_blk_ctrl *bc = dev_get_drvdata(dev);
> > +	int i;
> > +
> > +	for (i = 0; i < bc->onecell_data.num_domains; i++)
> > +		pm_runtime_put(bc->domains[i].power_dev);
> > +
> > +	pm_runtime_put(bc->bus_power_dev);
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> > +static const struct dev_pm_ops imx8mp_hsio_blk_ctrl_pm_ops = {
> > +	SET_SYSTEM_SLEEP_PM_OPS(imx8mp_hsio_blk_ctrl_suspend,
> > +				imx8mp_hsio_blk_ctrl_resume)
> > +};
> > +
> > +static const struct of_device_id imx8mp_hsio_blk_ctrl_of_match[] = {
> > +	{
> > +		.compatible = "fsl,imx8mp-hsio-blk-ctrl",
> > +	}, {
> > +		/* Sentinel */
> > +	}
> > +};
> > +MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
> > +
> > +static struct platform_driver imx8mp_hsio_blk_ctrl_driver = {
> > +	.probe = imx8mp_hsio_blk_ctrl_probe,
> > +	.remove = imx8mp_hsio_blk_ctrl_remove,
> > +	.driver = {
> > +		.name = "imx8mp-hsio-blk-ctrl",
> > +		.pm = &imx8mp_hsio_blk_ctrl_pm_ops,
> > +		.of_match_table = imx8mp_hsio_blk_ctrl_of_match,
> > +	},
> > +};
> > +module_platform_driver(imx8mp_hsio_blk_ctrl_driver);
> > -- 
> > 2.30.2
> > 




From guoren at kernel.org  Fri Jan 21 01:22:22 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 21 Jan 2022 17:22:22 +0800
Subject: [PATCH V3 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAK8P3a1sOejkdOyoRUfw4ESS7ewX_8Wj9tQNrZ40OiuDqJnrmw@mail.gmail.com>
References: <20220120073911.99857-9-guoren@kernel.org>
 <CAK8P3a0LxB3we9wHOa4OPmNow6wz5NP49zeYhh7QXNv-MiR8UA@mail.gmail.com>
 <CAJF2gTQVUF4LSO0a6_MV8x-UAiJw32pAFyS1oPNLXhcEaemzqg@mail.gmail.com>
 <CAK8P3a1sOejkdOyoRUfw4ESS7ewX_8Wj9tQNrZ40OiuDqJnrmw@mail.gmail.com>
Message-ID: <CAJF2gTSzMym_PS36JgpWLQUdAO3nq+z7mdDWRT=EzQq+waPSpA@mail.gmail.com>

On Fri, Jan 21, 2022 at 4:57 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Fri, Jan 21, 2022 at 7:25 AM Guo Ren <guoren at kernel.org> wrote:
> > On Thu, Jan 20, 2022 at 10:43 PM Arnd Bergmann <arnd at arndb.de> wrote:
> > > On Thu, Jan 20, 2022 at 8:39 AM <guoren at kernel.org> wrote:
>
> > > Are you sure these are the right calling conventions? According to [1],
> > > I think the 64-bit argument should be in an aligned pair of registers,
> > > which means you need an extra pad argument as in the arm64 version
> > > of these functions. Same for ftruncate64, pread64, pwrite64, and
> > > readahead.
> >
> > [1] has abandoned.
> >
> > See:
> > https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc
>
> Ok, thanks for the reference, I picked the first one that came up in
> a google search and didn't expect this to ever have changed.
>
> > > I still feel like these should be the common implementations next to the
> > > native handlers inside of an #ifdef CONFIG_COMPAT.
> > >
> > > The names clash with the custom versions defined for powerpc and sparc,
> > > but the duplicates look compatible if you can account for the padded
> > > argument and the lo/hi order of the pairs, so could just be removed here
> > > (all other architectures use custom function names instead).
> > I would try it later.
>
> This becomes easier then, as powerpc and sparc already have the non-padded
> calling conventions, so you could just generalize those without looking at
> the other architectures or adding the padding. The powerpc version already
> has the dual-endian version, so using that will work on big-endian sparc and
> on little-endian riscv as well, though we may need to come up with a better name
> for the arg_u32/arg_u64/merge_64 macros in order to put that into a global
> header without namespace collisions.
Sounds good, thanks!

>
>          Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From martin.kepplinger at puri.sm  Fri Jan 21 01:33:25 2022
From: martin.kepplinger at puri.sm (Martin Kepplinger)
Date: Fri, 21 Jan 2022 10:33:25 +0100
Subject: [PATCH v1 1/2] arm64: dts: imx8mq: fix mipi_csi bidirectional port
 numbers
In-Reply-To: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
References: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
Message-ID: <20220121093326.2388251-2-martin.kepplinger@puri.sm>

The port numbers for the imx8mq mipi csi controller are wrong and
the mipi driver can't find any media devices as port at 1 is connected
to the CSI bridge, not port at 0. And port at 0 is connected to the
source - the sensor. Fix this.

Fixes: bcadd5f66c2a ("arm64: dts: imx8mq: add mipi csi phy and csi bridge descriptions")
Signed-off-by: Martin Kepplinger <martin.kepplinger at puri.sm>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 2df2510d0118..bb68c94c2fc9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1151,8 +1151,8 @@ ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
 
-					port at 0 {
-						reg = <0>;
+					port at 1 {
+						reg = <1>;
 
 						csi1_mipi_ep: endpoint {
 							remote-endpoint = <&csi1_ep>;
@@ -1203,8 +1203,8 @@ ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
 
-					port at 0 {
-						reg = <0>;
+					port at 1 {
+						reg = <1>;
 
 						csi2_mipi_ep: endpoint {
 							remote-endpoint = <&csi2_ep>;
-- 
2.30.2



From martin.kepplinger at puri.sm  Fri Jan 21 01:33:24 2022
From: martin.kepplinger at puri.sm (Martin Kepplinger)
Date: Fri, 21 Jan 2022 10:33:24 +0100
Subject: [PATCH v1 0/2] arm64: dts: imx8mq: fix mipi_csi port numbering
Message-ID: <20220121093326.2388251-1-martin.kepplinger@puri.sm>

hi Shawn and all interested,

This is a fix for an embarrassing bug that slipped into commit
bcadd5f66c2a ("arm64: dts: imx8mq: add mipi csi phy and csi bridge descriptions")
and commit fed7603597fa ("arm64: dts: imx8mq-librem5: describe the selfie cam").

When preparing the imx8mq.dtsi description I only tested with port at 1
being connected to the csi bridge, but what I sent said port at 0.

I have this on my list for a while and want to sort this out now. I'm
sorry for the inconvenience. Until now imx8mq-librem5 is the only user
(maybe because of this :).

thank you,

                              martin


Martin Kepplinger (2):
  arm64: dts: imx8mq: fix mipi_csi bidirectional port numbers
  arm64: dts: imx8mq-librem5: fix mipi_csi1 port number to sensor

 arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 4 ++--
 arch/arm64/boot/dts/freescale/imx8mq.dtsi         | 8 ++++----
 2 files changed, 6 insertions(+), 6 deletions(-)

-- 
2.30.2



From martin.kepplinger at puri.sm  Fri Jan 21 01:33:26 2022
From: martin.kepplinger at puri.sm (Martin Kepplinger)
Date: Fri, 21 Jan 2022 10:33:26 +0100
Subject: [PATCH v1 2/2] arm64: dts: imx8mq-librem5: fix mipi_csi1 port number
 to sensor
In-Reply-To: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
References: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
Message-ID: <20220121093326.2388251-3-martin.kepplinger@puri.sm>

Since the previous commit fixed a hardware description bug for imx8mq,
we need to fix up all DT users like this. The mipi_csi port at 0
is connected to the sensor, not port at 1.

Fixes: fed7603597fa ("arm64: dts: imx8mq-librem5: describe the selfie cam")
Signed-off-by: Martin Kepplinger <martin.kepplinger at puri.sm>
---
 arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
index f3e3418f7edc..2d4a472af6a9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -1115,8 +1115,8 @@ &mipi_csi1 {
 	status = "okay";
 
 	ports {
-		port at 1 {
-			reg = <1>;
+		port at 0 {
+			reg = <0>;
 
 			mipi1_sensor_ep: endpoint {
 				remote-endpoint = <&camera1_ep>;
-- 
2.30.2



From Jonathan.Cameron at Huawei.com  Fri Jan 21 01:42:43 2022
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Fri, 21 Jan 2022 09:42:43 +0000
Subject: [PATCH] spi: pxa2xx_spi: Convert to use GPIO descriptors
In-Reply-To: <20220121012014.287288-1-linus.walleij@linaro.org>
References: <20220121012014.287288-1-linus.walleij@linaro.org>
Message-ID: <20220121094243.0000651f@Huawei.com>

On Fri, 21 Jan 2022 02:20:14 +0100
Linus Walleij <linus.walleij at linaro.org> wrote:

> This converts the PXA2xx SPI driver to use GPIO descriptors
> exclusively to retrieve GPIO chip select lines.
> 
> The device tree and ACPI paths of the driver already use
> descriptors, hence ->use_gpio_descriptors is already set and
> this codepath is well tested.
> 
> Convert all the PXA boards providing chip select GPIOs as
> platform data and drop the old GPIO chipselect handling in
> favor of the core managing it exclusively.
> 
> Cc: Marek Vasut <marek.vasut at gmail.com>
> Cc: Daniel Mack <daniel at zonque.org>
> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
> Cc: Robert Jarzmik <robert.jarzmik at free.fr>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
>  Documentation/spi/pxa2xx.rst   |  3 --
>  arch/arm/mach-pxa/corgi.c      | 26 +++++++---------
>  arch/arm/mach-pxa/hx4700.c     | 10 +++++-
>  arch/arm/mach-pxa/icontrol.c   | 26 +++++++++++++---
>  arch/arm/mach-pxa/littleton.c  | 10 +++++-
>  arch/arm/mach-pxa/magician.c   | 12 +++++--
>  arch/arm/mach-pxa/poodle.c     | 14 ++++++---
>  arch/arm/mach-pxa/spitz.c      | 26 +++++++---------
>  arch/arm/mach-pxa/stargate2.c  | 21 +++++++++++--
>  arch/arm/mach-pxa/z2.c         | 20 ++++++++++--
>  drivers/spi/spi-pxa2xx.c       | 57 ----------------------------------
>  include/linux/spi/pxa2xx_spi.h |  1 -
>  12 files changed, 117 insertions(+), 109 deletions(-)
> 

...

> diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
> index 8ca02ec1d44c..650043023006 100644
> --- a/arch/arm/mach-pxa/stargate2.c
> +++ b/arch/arm/mach-pxa/stargate2.c
> @@ -346,6 +346,23 @@ static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
>  	.num_chipselect = 1,
>  };
>  
> +static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
> +	.dev_id = "pxa2xx-spi.1",
> +	.table = {
> +		GPIO_LOOKUP_IDX("gpio-pxa", 24, "cs", 0, GPIO_ACTIVE_LOW),
> +		{ },
> +	},
> +};
> +
> +static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
> +	.dev_id = "pxa2xx-spi.3",
> +	.table = {
> +		GPIO_LOOKUP_IDX("gpio-pxa", 39, "cs", 0, GPIO_ACTIVE_LOW),
> +		{ },
> +	},
> +};
> +

Nitpick, one line will do.

As a side note I have a patch outstanding (from May 2021) to drop
stargate2/imote2 on basis that I strongly suspect I'm the only person
who still has access to hardware and I've not booted one for a few years.

https://lore.kernel.org/all/20210523163606.1966355-1-jic23 at kernel.org/
Patch still applies cleanly.

In meantime for stargate2/imote2 (same file)  Should both patches go in
the merge conflict will be very obvious ;)

Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>

> +
>  /* An upcoming kernel change will scrap SFRM usage so these
>   * drivers have been moved to use GPIOs */
>  static struct pxa2xx_spi_chip staccel_chip_info = {
> @@ -353,7 +370,6 @@ static struct pxa2xx_spi_chip staccel_chip_info = {
>  	.rx_threshold = 8,
>  	.dma_burst_size = 8,
>  	.timeout = 235,
> -	.gpio_cs = 24,
>  };
>  
>  static struct pxa2xx_spi_chip cc2420_info = {
> @@ -361,7 +377,6 @@ static struct pxa2xx_spi_chip cc2420_info = {
>  	.rx_threshold = 8,
>  	.dma_burst_size = 8,
>  	.timeout = 235,
> -	.gpio_cs = 39,
>  };
>  
>  static struct spi_board_info spi_board_info[] __initdata = {
> @@ -410,6 +425,8 @@ static void __init imote2_stargate2_init(void)
>  	pxa_set_btuart_info(NULL);
>  	pxa_set_stuart_info(NULL);
>  
> +	gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
> +	gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
>  	pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
>  	pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
>  	pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);


From alexander.stein at ew.tq-group.com  Fri Jan 21 01:56:44 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 21 Jan 2022 10:56:44 +0100
Subject: [PATCH 1/1] drm: mxsfb: Use dev_err_probe() helper
Message-ID: <20220121095644.329256-1-alexander.stein@ew.tq-group.com>

Use the dev_err_probe() helper, instead of open-coding the same
operation. This also adds a nice hint in
/sys/kernel/debug/devices_deferred.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
Based on next-20220120

 drivers/gpu/drm/mxsfb/mxsfb_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
index 86d78634a979..bc0d766d217b 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
@@ -258,8 +258,7 @@ static int mxsfb_load(struct drm_device *drm,
 
 	ret = mxsfb_attach_bridge(mxsfb);
 	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			dev_err(drm->dev, "Cannot connect bridge: %d\n", ret);
+		dev_err_probe(drm->dev, ret, "Cannot connect bridge\n");
 		goto err_vblank;
 	}
 
-- 
2.25.1



From harinik at xilinx.com  Fri Jan 21 02:16:23 2022
From: harinik at xilinx.com (Harini Katakam)
Date: Fri, 21 Jan 2022 15:46:23 +0530
Subject: [PATCH 0/3] dt-bindings: dmaengine: zynqmp_dma: Convert binding
 to YAML
In-Reply-To: <20220112151541.1328732-1-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
Message-ID: <CAFcVECKJMAH3==zoYihtJg_6SJprd7ELC8uL7SO1yGCZzZxemA@mail.gmail.com>

Hi Michael,

On Thu, Jan 13, 2022 at 4:52 AM Michael Tretter
<m.tretter at pengutronix.de> wrote:
>
> Hi,
>
> This series converts the ZynqMP dma engine dt bindings to yaml and fixes the
> ZynqMP device tree following the stricter yaml bindings.
>
> The series is based on https://github.com/Xilinx/linux-xlnx/tree/zynqmp/dt to
> avoid conflicts when applying the patches to the zynqmp/dt tree.
>
> Patch 1 converts the binding to yaml, Patches 2 and 3 cleanup the dma engine
> nodes in the zynqmp.dtsi that is included by actual board device trees.

Thanks for the series Michael.
Reviewed-by: Harini Katakam <harini.katakam at xilinx.com>

Regards,
Harini


From s.hauer at pengutronix.de  Fri Jan 21 02:32:45 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Fri, 21 Jan 2022 11:32:45 +0100
Subject: [PATCH v3 00/22] drm/rockchip: RK356x VOP2 support
In-Reply-To: <AA3A26CB-6282-4A6B-99DC-8042DC8926BB@gmail.com>
References: <20211220110630.3521121-1-s.hauer@pengutronix.de>
 <AA3A26CB-6282-4A6B-99DC-8042DC8926BB@gmail.com>
Message-ID: <20220121103245.GT23490@pengutronix.de>

Hi Piotr,

On Wed, Jan 19, 2022 at 12:29:49PM +0100, Piotr Oniszczuk wrote:
> 
> 
> > Wiadomo?? napisana przez Sascha Hauer <s.hauer at pengutronix.de> w dniu 20.12.2021, o godz. 12:06:
> > 
> > 
> > Third round of patches and last one for this year. I hopefully integrated
> > all review feedback. Additionally the driver is now fully converted to
> > regmap, so no struct vop_reg necessary anymore.
> > 
> > Sascha
> > 
> > Changes since v2:
> > - Add pin names to HDMI supply pin description
> > - Add hclk support to HDMI driver
> > - Dual license rockchip-vop2 binding, update binding
> > - Add HDMI connector to board dts files
> > - drop unnecessary gamma_lut registers from vop2
> > - Update dclk_vop[012] clock handling, no longer hacks needed
> > - Complete regmap conversion
> > 
> 
> Sascha
> 
> I'm using you VOP2 code on rk3566 tvbox (x96-x6) with very good results.
> 
> I have just few questions:
> 
> 1. how support for CEC looks/prospects (plans for future, not in this code, expecting others should implement, etc)?

I had to google what CEC actually is. We don't have plans supporting it.
It looks like this is a matter of the HDMI driver supporting this and
not bound to the rockchip driver.

> 
> 2. VOP2 code works nice for me for x11/glamour and for EGLFS with EGL DMAbuf rendering by Mesa EGL_LINUX_DMA_BUF_EXT.
> I have issue however with app. rendering to DRM planes (GUI is DRM plane1, video is DRM pane2). 
> My ppp starts/works without any errors in log - but screen stays with kernel messages content.
> (it looks to me like i.e. app renders to DRM plane but DRM display driver not pass it to CRTC. just wild guess here...).

You enabled the panfrost driver with other patches, right?

> 
> 3. in kernel dmesg I have many:
> 
> "rockchip-drm display-subsystem: [drm] *ERROR* Unsupported format modifier 0x810000000000001".

This message is correct. This corresponds to
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED and the VOP2 driver doesn't
support this. I have a similar problem here with
weston-simple-dmabuf-egl.  By default this uses DRM_FORMAT_XRGB8888
which ends up being PIPE_FORMAT_B8G8R8_UNORM in MESA. In
panfrost_afbc_format() we have:

        /* Don't allow swizzled formats on v7 */
        switch (format) {
        case PIPE_FORMAT_B8G8R8A8_UNORM:
        case PIPE_FORMAT_B8G8R8X8_UNORM:
        case PIPE_FORMAT_A8R8G8B8_UNORM:
        case PIPE_FORMAT_X8R8G8B8_UNORM:
        case PIPE_FORMAT_X8B8G8R8_UNORM:
        case PIPE_FORMAT_A8B8G8R8_UNORM:
        case PIPE_FORMAT_B8G8R8_UNORM:
        case PIPE_FORMAT_B5G6R5_UNORM:
                if (dev->arch >= 7)
                        return PIPE_FORMAT_NONE;

                break;
        default:
                break;
        }

This means the driver won't do AFBC with that format and picks
DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED instead. Now weston is
clever enough to not pass that into the VOP2 driver, apparently your
application is not and as a result you see that message.

In weston-simple-dmabuf-egl I can pass a suitable format on the command
line, in my case I use DRM_FORMAT_ABGR8888 (which becomes
PIPE_FORMAT_R8G8B8A8_UNORM). With this the panfrost driver does AFBC
which then can be rendered in the VOP2 cluster window overlay.

> 
> It comes from MESA i think - but i suspect because VOP2 provides
> unknown/wrong DRM modifier to mesa?

Nope, the modifiers the VOP2 driver propagates are correct. It doesn't
claim to support DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From semen.protsenko at linaro.org  Fri Jan 21 03:08:55 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Fri, 21 Jan 2022 13:08:55 +0200
Subject: [RFC 2/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
In-Reply-To: <a111932a-6685-2a9d-abce-87af26b121a4@canonical.com>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
 <20220120201958.2649-3-semen.protsenko@linaro.org>
 <a111932a-6685-2a9d-abce-87af26b121a4@canonical.com>
Message-ID: <CAPLW+4kKR+7hM-eZc8-v6Dzeaj+TPBRmCLDSVNEnfx2WmN2TJA@mail.gmail.com>

On Fri, 21 Jan 2022 at 10:40, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 20/01/2022 21:19, Sam Protsenko wrote:
> > Introduce new driver for modern Exynos ARMv8 SoCs, e.g. Exynos850. Also
> > it's used for Google's GS101 SoC.
> >
> > This is squashed commit, contains next patches of different authors. See
> > `iommu-exynos850-dev' branch for details: [1].
> >
> > Original authors (Samsung):
> >
> >  - Cho KyongHo <pullip.cho at samsung.com>
> >  - Hyesoo Yu <hyesoo.yu at samsung.com>
> >  - Janghyuck Kim <janghyuck.kim at samsung.com>
> >  - Jinkyu Yang <jinkyu1.yang at samsung.com>
> >
> > Some improvements were made by Google engineers:
> >
> >  - Alex <acnwigwe at google.com>
> >  - Carlos Llamas <cmllamas at google.com>
> >  - Daniel Mentz <danielmentz at google.com>
> >  - Erick Reyes <erickreyes at google.com>
> >  - J. Avila <elavila at google.com>
> >  - Jonglin Lee <jonglin at google.com>
> >  - Mark Salyzyn <salyzyn at google.com>
> >  - Thierry Strudel <tstrudel at google.com>
> >  - Will McVicker <willmcvicker at google.com>
> >
> > [1] https://github.com/joe-skb7/linux/tree/iommu-exynos850-dev
> >
> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
> > ---
> >  drivers/iommu/Kconfig               |   13 +
> >  drivers/iommu/Makefile              |    3 +
> >  drivers/iommu/samsung-iommu-fault.c |  617 +++++++++++
> >  drivers/iommu/samsung-iommu-group.c |   50 +
> >  drivers/iommu/samsung-iommu.c       | 1521 +++++++++++++++++++++++++++
> >  drivers/iommu/samsung-iommu.h       |  216 ++++
> >  6 files changed, 2420 insertions(+)
> >  create mode 100644 drivers/iommu/samsung-iommu-fault.c
> >  create mode 100644 drivers/iommu/samsung-iommu-group.c
> >  create mode 100644 drivers/iommu/samsung-iommu.c
> >  create mode 100644 drivers/iommu/samsung-iommu.h
> >
>
> Existing driver supports several different Exynos SysMMU IP block
> versions. Several. Please explain why it cannot support one more version?
>
> Similarity of vendor driver with mainline is not an argument.
>
>
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index 3eb68fa1b8cc..78e7039f18aa 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -452,6 +452,19 @@ config QCOM_IOMMU
> >       help
> >         Support for IOMMU on certain Qualcomm SoCs.
> >
> > +config SAMSUNG_IOMMU
> > +     tristate "Samsung IOMMU Support"
> > +     select ARM_DMA_USE_IOMMU
> > +     select IOMMU_DMA
> > +     select SAMSUNG_IOMMU_GROUP
> > +     help
> > +       Support for IOMMU on Samsung Exynos SoCs.
> > +
> > +config SAMSUNG_IOMMU_GROUP
> > +     tristate "Samsung IOMMU Group Support"
> > +     help
> > +       Support for IOMMU group on Samsung Exynos SoCs.
> > +
> >  config HYPERV_IOMMU
> >       bool "Hyper-V x2APIC IRQ Handling"
> >       depends on HYPERV && X86
> > diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> > index bc7f730edbb0..a8bdf449f1d4 100644
> > --- a/drivers/iommu/Makefile
> > +++ b/drivers/iommu/Makefile
> > @@ -27,6 +27,9 @@ obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
> >  obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
> >  obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
> >  obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
> > +obj-$(CONFIG_SAMSUNG_IOMMU) += samsung_iommu.o
> > +samsung_iommu-objs += samsung-iommu.o samsung-iommu-fault.o
> > +obj-$(CONFIG_SAMSUNG_IOMMU_GROUP) += samsung-iommu-group.o
> >  obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o io-pgfault.o
> >  obj-$(CONFIG_SPRD_IOMMU) += sprd-iommu.o
> >  obj-$(CONFIG_APPLE_DART) += apple-dart.o
> > diff --git a/drivers/iommu/samsung-iommu-fault.c b/drivers/iommu/samsung-iommu-fault.c
> > new file mode 100644
> > index 000000000000..c6b4259976c4
> > --- /dev/null
> > +++ b/drivers/iommu/samsung-iommu-fault.c
> > @@ -0,0 +1,617 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +/*
> > + * Copyright (c) 2020 Samsung Electronics Co., Ltd.
> > + */
> > +
> > +#define pr_fmt(fmt) "sysmmu: " fmt
> > +
> > +#include <linux/smc.h>
> > +#include <linux/arm-smccc.h>
> > +#include <linux/pm_runtime.h>
> > +
> > +#include "samsung-iommu.h"
> > +
> > +#define MMU_TLB_INFO(n)                      (0x2000 + ((n) * 0x20))
> > +#define MMU_CAPA1_NUM_TLB_SET(reg)   (((reg) >> 16) & 0xFF)
> > +#define MMU_CAPA1_NUM_TLB_WAY(reg)   ((reg) & 0xFF)
> > +#define MMU_CAPA1_SET_TLB_READ_ENTRY(tid, set, way, line)            \
> > +                                     ((set) | ((way) << 8) |         \
> > +                                      ((line) << 16) | ((tid) << 20))
> > +
> > +#define MMU_TLB_ENTRY_VALID(reg)     ((reg) >> 28)
> > +#define MMU_SBB_ENTRY_VALID(reg)     ((reg) >> 28)
> > +#define MMU_VADDR_FROM_TLB(reg, idx) ((((reg) & 0xFFFFC) | ((idx) & 0x3)) << 12)
> > +#define MMU_VID_FROM_TLB(reg)                (((reg) >> 20) & 0x7U)
> > +#define MMU_PADDR_FROM_TLB(reg)              ((phys_addr_t)((reg) & 0xFFFFFF) << 12)
> > +#define MMU_VADDR_FROM_SBB(reg)              (((reg) & 0xFFFFF) << 12)
> > +#define MMU_VID_FROM_SBB(reg)                (((reg) >> 20) & 0x7U)
> > +#define MMU_PADDR_FROM_SBB(reg)              ((phys_addr_t)((reg) & 0x3FFFFFF) << 10)
> > +
> > +#define REG_MMU_INT_STATUS           0x060
> > +#define REG_MMU_INT_CLEAR            0x064
> > +#define REG_MMU_FAULT_RW_MASK                GENMASK(20, 20)
> > +#define IS_READ_FAULT(x)             (((x) & REG_MMU_FAULT_RW_MASK) == 0)
> > +
> > +#define SYSMMU_FAULT_PTW_ACCESS   0
> > +#define SYSMMU_FAULT_PAGE_FAULT   1
> > +#define SYSMMU_FAULT_ACCESS       2
> > +#define SYSMMU_FAULT_RESERVED     3
> > +#define SYSMMU_FAULT_UNKNOWN      4
> > +
> > +#define SYSMMU_SEC_FAULT_MASK                (BIT(SYSMMU_FAULT_PTW_ACCESS) | \
> > +                                      BIT(SYSMMU_FAULT_PAGE_FAULT) | \
> > +                                      BIT(SYSMMU_FAULT_ACCESS))
> > +
> > +#define SYSMMU_FAULTS_NUM         (SYSMMU_FAULT_UNKNOWN + 1)
> > +
> > +#if IS_ENABLED(CONFIG_EXYNOS_CONTENT_PATH_PROTECTION)
>
> You just copy-pasted vendor stuff, without actually going through it.
>
> It is very disappointing because instead of putting your own effort, you
> expect community to do your job.
>
> What the hell is CONFIG_EXYNOS_CONTENT_PATH_PROTECTION?
>
> I'll stop reviewing. Please work on extending existing driver. If you
> submitted something nice and clean, ready for upstream, instead of
> vendor junk, you could get away with separate driver. But you did not.
> It looks really bad.
>

Krzysztof, that's not what I asked in my patch 0/3. I probably wasn't
really clear, sorry. Let me please try and describe that better, and
maybe provide some context.

I'm just starting to work on that driver, it's basically downstream
version of it. Of course I'm going to rework it before sending the
actual patch series (that's why this series has RFC tag). I'd never
asked community to do my job for me and really review the downstream
driver! I just want to know from the starters some *very* basic and
high-level info, which could help me to rework the driver in correct
way. Like naming of files, compatible strings, should it be part of
existing driver or it's ok to have it as another platform_driver. In
other words, that kind of "review" shouldn't take more than 2 minutes
of your time. And it could spare us all unneeded extra review rounds
in future. Right now I don't need the code review per se (and I'm
really sorry you had to spend your time on that, knowing how busy
maintainers can be during the MW). I thought about omitting the code
at all, only asking the questions, but then I figured it's a good idea
to attach some code for the reference. Maybe it wasn't a good idea
after all.

For the record, I'm well aware that we don't send downstream code
without making it upstreamable first, and I know it must be tested
well, etc. For example, you already saw me sending clk-exynos850
driver, which I re-implemented from scratch, and it has ~0.0% of
downstream code. So why would I change my policy about that all of the
sudden... Anyway, hope you understand now that there weren't any ill
intentions on my side, w.r.t. this RFC.

> Best regards,
> Krzysztof


From abel.vesa at nxp.com  Fri Jan 21 03:22:35 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 21 Jan 2022 13:22:35 +0200
Subject: [RFC 0/3] soc: imx: Refactor BLK CTRL driver
Message-ID: <20220121112238.47281-1-abel.vesa@nxp.com>

This splits the SoC specific parts into separate drivers for i.MX8MM and
i.MX8MN. Should be more readable and easier to maintain.

As for the i.MX8MP BLK CTRL driver (sent by Lucas here:
https://lore.kernel.org/linux-arm-kernel/20220119134027.2931945-7-l.stach at pengutronix.de/raw)
It can remain as a separate driver until we figure out what is the
overlap and how can we make it use the generic part.

This patchset doesn't rely on the above-mentioned patch and does not
impact it in any way.

Abel Vesa (3):
  soc: imx: make i.MX8MM BLK CTRL a separate driver
  soc: imx: make i.MX8MN BLK CTRL a separate driver
  soc: imx: Rename generic BLK CTRL driver to suggest future usability

 drivers/soc/imx/Kconfig           |  14 +
 drivers/soc/imx/Makefile          |   4 +-
 drivers/soc/imx/imx-blk-ctrl.c    | 322 ++++++++++++++++
 drivers/soc/imx/imx-blk-ctrl.h    |  72 ++++
 drivers/soc/imx/imx8m-blk-ctrl.c  | 617 ------------------------------
 drivers/soc/imx/imx8mm-blk-ctrl.c | 173 +++++++++
 drivers/soc/imx/imx8mn-blk-ctrl.c | 101 +++++
 7 files changed, 685 insertions(+), 618 deletions(-)
 create mode 100644 drivers/soc/imx/imx-blk-ctrl.c
 create mode 100644 drivers/soc/imx/imx-blk-ctrl.h
 delete mode 100644 drivers/soc/imx/imx8m-blk-ctrl.c
 create mode 100644 drivers/soc/imx/imx8mm-blk-ctrl.c
 create mode 100644 drivers/soc/imx/imx8mn-blk-ctrl.c

-- 
2.31.1



From abel.vesa at nxp.com  Fri Jan 21 03:22:36 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 21 Jan 2022 13:22:36 +0200
Subject: [RFC 1/3] soc: imx: make i.MX8MM BLK CTRL a separate driver
In-Reply-To: <20220121112238.47281-1-abel.vesa@nxp.com>
References: <20220121112238.47281-1-abel.vesa@nxp.com>
Message-ID: <20220121112238.47281-2-abel.vesa@nxp.com>

The imx8m-blk-ctrl driver was increasing in size with every new BLK CTRL
addition for every SoC. Lets split the SoC specific parts into separate
drivers. Do that for i.MX8MM now.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/soc/imx/Kconfig           |   7 +
 drivers/soc/imx/Makefile          |   1 +
 drivers/soc/imx/imx8m-blk-ctrl.c  | 210 +-----------------------------
 drivers/soc/imx/imx8m-blk-ctrl.h  |  72 ++++++++++
 drivers/soc/imx/imx8mm-blk-ctrl.c | 173 ++++++++++++++++++++++++
 5 files changed, 257 insertions(+), 206 deletions(-)
 create mode 100644 drivers/soc/imx/imx8m-blk-ctrl.h
 create mode 100644 drivers/soc/imx/imx8mm-blk-ctrl.c

diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig
index a840494e849a..b0cc53f3fc2c 100644
--- a/drivers/soc/imx/Kconfig
+++ b/drivers/soc/imx/Kconfig
@@ -20,4 +20,11 @@ config SOC_IMX8M
 	  support, it will provide the SoC info like SoC family,
 	  ID and revision etc.
 
+config SOC_IMX8MM_BLK_CTRL
+	bool "i.MX8MM SoC BLK CTRL support"
+	depends on SOC_IMX8M
+	help
+	  If you say yes here you get support for the NXP i.MX8MM BLK CTRL
+	  support.
+
 endmenu
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 8a707077914c..06c2970e6308 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
 obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
 obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
+obj-$(CONFIG_SOC_IMX8MM_BLK_CTRL) += imx8mm-blk-ctrl.o
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 511e74f0db8a..599b2a9a38bb 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -4,67 +4,11 @@
  * Copyright 2021 Pengutronix, Lucas Stach <kernel at pengutronix.de>
  */
 
-#include <linux/device.h>
-#include <linux/module.h>
 #include <linux/of_device.h>
-#include <linux/platform_device.h>
-#include <linux/pm_domain.h>
-#include <linux/pm_runtime.h>
-#include <linux/regmap.h>
-#include <linux/clk.h>
 
-#include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
 
-#define BLK_SFT_RSTN	0x0
-#define BLK_CLK_EN	0x4
-#define BLK_MIPI_RESET_DIV	0x8 /* Mini/Nano DISPLAY_BLK_CTRL only */
-
-struct imx8m_blk_ctrl_domain;
-
-struct imx8m_blk_ctrl {
-	struct device *dev;
-	struct notifier_block power_nb;
-	struct device *bus_power_dev;
-	struct regmap *regmap;
-	struct imx8m_blk_ctrl_domain *domains;
-	struct genpd_onecell_data onecell_data;
-};
-
-struct imx8m_blk_ctrl_domain_data {
-	const char *name;
-	const char * const *clk_names;
-	int num_clks;
-	const char *gpc_name;
-	u32 rst_mask;
-	u32 clk_mask;
-
-	/*
-	 * i.MX8M Mini and Nano have a third DISPLAY_BLK_CTRL register
-	 * which is used to control the reset for the MIPI Phy.
-	 * Since it's only present in certain circumstances,
-	 * an if-statement should be used before setting and clearing this
-	 * register.
-	 */
-	u32 mipi_phy_rst_mask;
-};
-
-#define DOMAIN_MAX_CLKS 3
-
-struct imx8m_blk_ctrl_domain {
-	struct generic_pm_domain genpd;
-	const struct imx8m_blk_ctrl_domain_data *data;
-	struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
-	struct device *power_dev;
-	struct imx8m_blk_ctrl *bc;
-};
-
-struct imx8m_blk_ctrl_data {
-	int max_reg;
-	notifier_fn_t power_notifier_fn;
-	const struct imx8m_blk_ctrl_domain_data *domains;
-	int num_domains;
-};
+#include "imx8m-blk-ctrl.h"
 
 static inline struct imx8m_blk_ctrl_domain *
 to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd)
@@ -165,7 +109,7 @@ imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
 
 static struct lock_class_key blk_ctrl_genpd_lock_class;
 
-static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
+int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 {
 	const struct imx8m_blk_ctrl_data *bc_data;
 	struct device *dev = &pdev->dev;
@@ -299,7 +243,7 @@ static int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int imx8m_blk_ctrl_remove(struct platform_device *pdev)
+int imx8m_blk_ctrl_remove(struct platform_device *pdev)
 {
 	struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
 	int i;
@@ -375,150 +319,10 @@ static int imx8m_blk_ctrl_resume(struct device *dev)
 }
 #endif
 
-static const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = {
+const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend, imx8m_blk_ctrl_resume)
 };
 
-static int imx8mm_vpu_power_notifier(struct notifier_block *nb,
-				     unsigned long action, void *data)
-{
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
-						 power_nb);
-
-	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
-		return NOTIFY_OK;
-
-	/*
-	 * The ADB in the VPUMIX domain has no separate reset and clock
-	 * enable bits, but is ungated together with the VPU clocks. To
-	 * allow the handshake with the GPC to progress we put the VPUs
-	 * in reset and ungate the clocks.
-	 */
-	regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1) | BIT(2));
-	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1) | BIT(2));
-
-	if (action == GENPD_NOTIFY_ON) {
-		/*
-		 * On power up we have no software backchannel to the GPC to
-		 * wait for the ADB handshake to happen, so we just delay for a
-		 * bit. On power down the GPC driver waits for the handshake.
-		 */
-		udelay(5);
-
-		/* set "fuse" bits to enable the VPUs */
-		regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
-		regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
-		regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
-		regmap_set_bits(bc->regmap, 0x14, 0xffffffff);
-	}
-
-	return NOTIFY_OK;
-}
-
-static const struct imx8m_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[] = {
-	[IMX8MM_VPUBLK_PD_G1] = {
-		.name = "vpublk-g1",
-		.clk_names = (const char *[]){ "g1", },
-		.num_clks = 1,
-		.gpc_name = "g1",
-		.rst_mask = BIT(1),
-		.clk_mask = BIT(1),
-	},
-	[IMX8MM_VPUBLK_PD_G2] = {
-		.name = "vpublk-g2",
-		.clk_names = (const char *[]){ "g2", },
-		.num_clks = 1,
-		.gpc_name = "g2",
-		.rst_mask = BIT(0),
-		.clk_mask = BIT(0),
-	},
-	[IMX8MM_VPUBLK_PD_H1] = {
-		.name = "vpublk-h1",
-		.clk_names = (const char *[]){ "h1", },
-		.num_clks = 1,
-		.gpc_name = "h1",
-		.rst_mask = BIT(2),
-		.clk_mask = BIT(2),
-	},
-};
-
-static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
-	.max_reg = 0x18,
-	.power_notifier_fn = imx8mm_vpu_power_notifier,
-	.domains = imx8mm_vpu_blk_ctl_domain_data,
-	.num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data),
-};
-
-static int imx8mm_disp_power_notifier(struct notifier_block *nb,
-				      unsigned long action, void *data)
-{
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
-						 power_nb);
-
-	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
-		return NOTIFY_OK;
-
-	/* Enable bus clock and deassert bus reset */
-	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(12));
-	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(6));
-
-	/*
-	 * On power up we have no software backchannel to the GPC to
-	 * wait for the ADB handshake to happen, so we just delay for a
-	 * bit. On power down the GPC driver waits for the handshake.
-	 */
-	if (action == GENPD_NOTIFY_ON)
-		udelay(5);
-
-
-	return NOTIFY_OK;
-}
-
-static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[] = {
-	[IMX8MM_DISPBLK_PD_CSI_BRIDGE] = {
-		.name = "dispblk-csi-bridge",
-		.clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb",
-					       "csi-bridge-core", },
-		.num_clks = 3,
-		.gpc_name = "csi-bridge",
-		.rst_mask = BIT(0) | BIT(1) | BIT(2),
-		.clk_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5),
-	},
-	[IMX8MM_DISPBLK_PD_LCDIF] = {
-		.name = "dispblk-lcdif",
-		.clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
-		.num_clks = 3,
-		.gpc_name = "lcdif",
-		.clk_mask = BIT(6) | BIT(7),
-	},
-	[IMX8MM_DISPBLK_PD_MIPI_DSI] = {
-		.name = "dispblk-mipi-dsi",
-		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
-		.num_clks = 2,
-		.gpc_name = "mipi-dsi",
-		.rst_mask = BIT(5),
-		.clk_mask = BIT(8) | BIT(9),
-		.mipi_phy_rst_mask = BIT(17),
-	},
-	[IMX8MM_DISPBLK_PD_MIPI_CSI] = {
-		.name = "dispblk-mipi-csi",
-		.clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
-		.num_clks = 2,
-		.gpc_name = "mipi-csi",
-		.rst_mask = BIT(3) | BIT(4),
-		.clk_mask = BIT(10) | BIT(11),
-		.mipi_phy_rst_mask = BIT(16),
-	},
-};
-
-static const struct imx8m_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = {
-	.max_reg = 0x2c,
-	.power_notifier_fn = imx8mm_disp_power_notifier,
-	.domains = imx8mm_disp_blk_ctl_domain_data,
-	.num_domains = ARRAY_SIZE(imx8mm_disp_blk_ctl_domain_data),
-};
-
-
 static int imx8mn_disp_power_notifier(struct notifier_block *nb,
 				      unsigned long action, void *data)
 {
@@ -591,12 +395,6 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
 
 static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
 	{
-		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
-		.data = &imx8mm_vpu_blk_ctl_dev_data
-	}, {
-		.compatible = "fsl,imx8mm-disp-blk-ctrl",
-		.data = &imx8mm_disp_blk_ctl_dev_data
-	}, {
 		.compatible = "fsl,imx8mn-disp-blk-ctrl",
 		.data = &imx8mn_disp_blk_ctl_dev_data
 	}, {
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.h b/drivers/soc/imx/imx8m-blk-ctrl.h
new file mode 100644
index 000000000000..618b3429bb69
--- /dev/null
+++ b/drivers/soc/imx/imx8m-blk-ctrl.h
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2021 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ * Copyright 2022 NXP, Abel Vesa <abel.vesa at nxp.com>
+ */
+
+#ifndef __IMX_BLK_CTRL_H
+#define __IMX_BLK_CTRL_H
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#define BLK_SFT_RSTN	0x0
+#define BLK_CLK_EN	0x4
+#define BLK_MIPI_RESET_DIV	0x8 /* Mini/Nano DISPLAY_BLK_CTRL only */
+
+struct imx8m_blk_ctrl_domain;
+
+struct imx8m_blk_ctrl {
+	struct device *dev;
+	struct notifier_block power_nb;
+	struct device *bus_power_dev;
+	struct regmap *regmap;
+	struct imx8m_blk_ctrl_domain *domains;
+	struct genpd_onecell_data onecell_data;
+};
+
+struct imx8m_blk_ctrl_domain_data {
+	const char *name;
+	const char * const *clk_names;
+	int num_clks;
+	const char *gpc_name;
+	u32 rst_mask;
+	u32 clk_mask;
+
+	/*
+	 * i.MX8M Mini and Nano have a third DISPLAY_BLK_CTRL register
+	 * which is used to control the reset for the MIPI Phy.
+	 * Since it's only present in certain circumstances,
+	 * an if-statement should be used before setting and clearing this
+	 * register.
+	 */
+	u32 mipi_phy_rst_mask;
+};
+
+#define DOMAIN_MAX_CLKS 3
+
+struct imx8m_blk_ctrl_domain {
+	struct generic_pm_domain genpd;
+	const struct imx8m_blk_ctrl_domain_data *data;
+	struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
+	struct device *power_dev;
+	struct imx8m_blk_ctrl *bc;
+};
+
+struct imx8m_blk_ctrl_data {
+	int max_reg;
+	notifier_fn_t power_notifier_fn;
+	const struct imx8m_blk_ctrl_domain_data *domains;
+	int num_domains;
+};
+
+extern const struct dev_pm_ops imx8m_blk_ctrl_pm_ops;
+
+int imx8m_blk_ctrl_remove(struct platform_device *pdev);
+int imx8m_blk_ctrl_probe(struct platform_device *pdev);
+
+#endif
diff --git a/drivers/soc/imx/imx8mm-blk-ctrl.c b/drivers/soc/imx/imx8mm-blk-ctrl.c
new file mode 100644
index 000000000000..eb63d28b0157
--- /dev/null
+++ b/drivers/soc/imx/imx8mm-blk-ctrl.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2021 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ * Copyright 2022 NXP, Abel Vesa <abel.vesa at nxp.com>
+ */
+
+#include <dt-bindings/power/imx8mm-power.h>
+
+#include "imx8m-blk-ctrl.h"
+
+static int imx8mm_vpu_power_notifier(struct notifier_block *nb,
+				     unsigned long action, void *data)
+{
+	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+						 power_nb);
+
+	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
+		return NOTIFY_OK;
+
+	/*
+	 * The ADB in the VPUMIX domain has no separate reset and clock
+	 * enable bits, but is ungated together with the VPU clocks. To
+	 * allow the handshake with the GPC to progress we put the VPUs
+	 * in reset and ungate the clocks.
+	 */
+	regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1) | BIT(2));
+	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1) | BIT(2));
+
+	if (action == GENPD_NOTIFY_ON) {
+		/*
+		 * On power up we have no software backchannel to the GPC to
+		 * wait for the ADB handshake to happen, so we just delay for a
+		 * bit. On power down the GPC driver waits for the handshake.
+		 */
+		udelay(5);
+
+		/* set "fuse" bits to enable the VPUs */
+		regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0x14, 0xffffffff);
+	}
+
+	return NOTIFY_OK;
+}
+
+static const struct imx8m_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[] = {
+	[IMX8MM_VPUBLK_PD_G1] = {
+		.name = "vpublk-g1",
+		.clk_names = (const char *[]){ "g1", },
+		.num_clks = 1,
+		.gpc_name = "g1",
+		.rst_mask = BIT(1),
+		.clk_mask = BIT(1),
+	},
+	[IMX8MM_VPUBLK_PD_G2] = {
+		.name = "vpublk-g2",
+		.clk_names = (const char *[]){ "g2", },
+		.num_clks = 1,
+		.gpc_name = "g2",
+		.rst_mask = BIT(0),
+		.clk_mask = BIT(0),
+	},
+	[IMX8MM_VPUBLK_PD_H1] = {
+		.name = "vpublk-h1",
+		.clk_names = (const char *[]){ "h1", },
+		.num_clks = 1,
+		.gpc_name = "h1",
+		.rst_mask = BIT(2),
+		.clk_mask = BIT(2),
+	},
+};
+
+static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
+	.max_reg = 0x18,
+	.power_notifier_fn = imx8mm_vpu_power_notifier,
+	.domains = imx8mm_vpu_blk_ctl_domain_data,
+	.num_domains = ARRAY_SIZE(imx8mm_vpu_blk_ctl_domain_data),
+};
+
+static int imx8mm_disp_power_notifier(struct notifier_block *nb,
+				      unsigned long action, void *data)
+{
+	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+						 power_nb);
+
+	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
+		return NOTIFY_OK;
+
+	/* Enable bus clock and deassert bus reset */
+	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(12));
+	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(6));
+
+	/*
+	 * On power up we have no software backchannel to the GPC to
+	 * wait for the ADB handshake to happen, so we just delay for a
+	 * bit. On power down the GPC driver waits for the handshake.
+	 */
+	if (action == GENPD_NOTIFY_ON)
+		udelay(5);
+
+
+	return NOTIFY_OK;
+}
+
+static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[] = {
+	[IMX8MM_DISPBLK_PD_CSI_BRIDGE] = {
+		.name = "dispblk-csi-bridge",
+		.clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb",
+					       "csi-bridge-core", },
+		.num_clks = 3,
+		.gpc_name = "csi-bridge",
+		.rst_mask = BIT(0) | BIT(1) | BIT(2),
+		.clk_mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5),
+	},
+	[IMX8MM_DISPBLK_PD_LCDIF] = {
+		.name = "dispblk-lcdif",
+		.clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
+		.num_clks = 3,
+		.gpc_name = "lcdif",
+		.clk_mask = BIT(6) | BIT(7),
+	},
+	[IMX8MM_DISPBLK_PD_MIPI_DSI] = {
+		.name = "dispblk-mipi-dsi",
+		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
+		.num_clks = 2,
+		.gpc_name = "mipi-dsi",
+		.rst_mask = BIT(5),
+		.clk_mask = BIT(8) | BIT(9),
+		.mipi_phy_rst_mask = BIT(17),
+	},
+	[IMX8MM_DISPBLK_PD_MIPI_CSI] = {
+		.name = "dispblk-mipi-csi",
+		.clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
+		.num_clks = 2,
+		.gpc_name = "mipi-csi",
+		.rst_mask = BIT(3) | BIT(4),
+		.clk_mask = BIT(10) | BIT(11),
+		.mipi_phy_rst_mask = BIT(16),
+	},
+};
+
+static const struct imx8m_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = {
+	.max_reg = 0x2c,
+	.power_notifier_fn = imx8mm_disp_power_notifier,
+	.domains = imx8mm_disp_blk_ctl_domain_data,
+	.num_domains = ARRAY_SIZE(imx8mm_disp_blk_ctl_domain_data),
+};
+
+static const struct of_device_id imx8mm_blk_ctrl_of_match[] = {
+	{
+		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
+		.data = &imx8mm_vpu_blk_ctl_dev_data
+	}, {
+		.compatible = "fsl,imx8mm-disp-blk-ctrl",
+		.data = &imx8mm_disp_blk_ctl_dev_data
+	}, {
+		/* Sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx8mm_blk_ctrl_of_match);
+
+static struct platform_driver imx8mm_blk_ctrl_driver = {
+	.probe = imx8m_blk_ctrl_probe,
+	.remove = imx8m_blk_ctrl_remove,
+	.driver = {
+		.name = "imx8mm-blk-ctrl",
+		.pm = &imx8m_blk_ctrl_pm_ops,
+		.of_match_table = imx8mm_blk_ctrl_of_match,
+	},
+};
+module_platform_driver(imx8mm_blk_ctrl_driver);
-- 
2.31.1



From abel.vesa at nxp.com  Fri Jan 21 03:22:37 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 21 Jan 2022 13:22:37 +0200
Subject: [RFC 2/3] soc: imx: make i.MX8MN BLK CTRL a separate driver
In-Reply-To: <20220121112238.47281-1-abel.vesa@nxp.com>
References: <20220121112238.47281-1-abel.vesa@nxp.com>
Message-ID: <20220121112238.47281-3-abel.vesa@nxp.com>

The imx8m-blk-ctrl driver was increasing in size with every new BLK CTRL
addition for every SoC. Lets split the SoC specific parts into separate
drivers. Do that for i.MX8MN now.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/soc/imx/Kconfig           |   7 +++
 drivers/soc/imx/Makefile          |   1 +
 drivers/soc/imx/imx8m-blk-ctrl.c  |  93 ---------------------------
 drivers/soc/imx/imx8mn-blk-ctrl.c | 101 ++++++++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 93 deletions(-)
 create mode 100644 drivers/soc/imx/imx8mn-blk-ctrl.c

diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig
index b0cc53f3fc2c..8a3e0920b022 100644
--- a/drivers/soc/imx/Kconfig
+++ b/drivers/soc/imx/Kconfig
@@ -27,4 +27,11 @@ config SOC_IMX8MM_BLK_CTRL
 	  If you say yes here you get support for the NXP i.MX8MM BLK CTRL
 	  support.
 
+config SOC_IMX8MN_BLK_CTRL
+	bool "i.MX8MN SoC BLK CTRL support"
+	depends on SOC_IMX8M
+	help
+	  If you say yes here you get support for the NXP i.MX8MN BLK CTRL
+	  support.
+
 endmenu
diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index 06c2970e6308..f5243bc5f08f 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
 obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
 obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
 obj-$(CONFIG_SOC_IMX8MM_BLK_CTRL) += imx8mm-blk-ctrl.o
+obj-$(CONFIG_SOC_IMX8MN_BLK_CTRL) += imx8mn-blk-ctrl.o
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 599b2a9a38bb..ebdb044c6afa 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -6,8 +6,6 @@
 
 #include <linux/of_device.h>
 
-#include <dt-bindings/power/imx8mn-power.h>
-
 #include "imx8m-blk-ctrl.h"
 
 static inline struct imx8m_blk_ctrl_domain *
@@ -322,94 +320,3 @@ static int imx8m_blk_ctrl_resume(struct device *dev)
 const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend, imx8m_blk_ctrl_resume)
 };
-
-static int imx8mn_disp_power_notifier(struct notifier_block *nb,
-				      unsigned long action, void *data)
-{
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
-						 power_nb);
-
-	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
-		return NOTIFY_OK;
-
-	/* Enable bus clock and deassert bus reset */
-	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8));
-	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8));
-
-	/*
-	 * On power up we have no software backchannel to the GPC to
-	 * wait for the ADB handshake to happen, so we just delay for a
-	 * bit. On power down the GPC driver waits for the handshake.
-	 */
-	if (action == GENPD_NOTIFY_ON)
-		udelay(5);
-
-
-	return NOTIFY_OK;
-}
-
-static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = {
-	[IMX8MN_DISPBLK_PD_MIPI_DSI] = {
-		.name = "dispblk-mipi-dsi",
-		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
-		.num_clks = 2,
-		.gpc_name = "mipi-dsi",
-		.rst_mask = BIT(0) | BIT(1),
-		.clk_mask = BIT(0) | BIT(1),
-		.mipi_phy_rst_mask = BIT(17),
-	},
-	[IMX8MN_DISPBLK_PD_MIPI_CSI] = {
-		.name = "dispblk-mipi-csi",
-		.clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
-		.num_clks = 2,
-		.gpc_name = "mipi-csi",
-		.rst_mask = BIT(2) | BIT(3),
-		.clk_mask = BIT(2) | BIT(3),
-		.mipi_phy_rst_mask = BIT(16),
-	},
-	[IMX8MN_DISPBLK_PD_LCDIF] = {
-		.name = "dispblk-lcdif",
-		.clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
-		.num_clks = 3,
-		.gpc_name = "lcdif",
-		.rst_mask = BIT(4) | BIT(5),
-		.clk_mask = BIT(4) | BIT(5),
-	},
-	[IMX8MN_DISPBLK_PD_ISI] = {
-		.name = "dispblk-isi",
-		.clk_names = (const char *[]){ "disp_axi", "disp_apb", "disp_axi_root",
-						"disp_apb_root"},
-		.num_clks = 4,
-		.gpc_name = "isi",
-		.rst_mask = BIT(6) | BIT(7),
-		.clk_mask = BIT(6) | BIT(7),
-	},
-};
-
-static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
-	.max_reg = 0x84,
-	.power_notifier_fn = imx8mn_disp_power_notifier,
-	.domains = imx8mn_disp_blk_ctl_domain_data,
-	.num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
-};
-
-static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
-	{
-		.compatible = "fsl,imx8mn-disp-blk-ctrl",
-		.data = &imx8mn_disp_blk_ctl_dev_data
-	}, {
-		/* Sentinel */
-	}
-};
-MODULE_DEVICE_TABLE(of, imx8m_blk_ctrl_of_match);
-
-static struct platform_driver imx8m_blk_ctrl_driver = {
-	.probe = imx8m_blk_ctrl_probe,
-	.remove = imx8m_blk_ctrl_remove,
-	.driver = {
-		.name = "imx8m-blk-ctrl",
-		.pm = &imx8m_blk_ctrl_pm_ops,
-		.of_match_table = imx8m_blk_ctrl_of_match,
-	},
-};
-module_platform_driver(imx8m_blk_ctrl_driver);
diff --git a/drivers/soc/imx/imx8mn-blk-ctrl.c b/drivers/soc/imx/imx8mn-blk-ctrl.c
new file mode 100644
index 000000000000..20f53cd4e387
--- /dev/null
+++ b/drivers/soc/imx/imx8mn-blk-ctrl.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * Copyright 2021 Pengutronix, Lucas Stach <kernel at pengutronix.de>
+ * Copyright 2022 NXP, Abel Vesa <abel.vesa at nxp.com>
+ */
+
+#include <dt-bindings/power/imx8mn-power.h>
+
+#include "imx8m-blk-ctrl.h"
+
+static int imx8mn_disp_power_notifier(struct notifier_block *nb,
+				      unsigned long action, void *data)
+{
+	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+						 power_nb);
+
+	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
+		return NOTIFY_OK;
+
+	/* Enable bus clock and deassert bus reset */
+	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8));
+	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8));
+
+	/*
+	 * On power up we have no software backchannel to the GPC to
+	 * wait for the ADB handshake to happen, so we just delay for a
+	 * bit. On power down the GPC driver waits for the handshake.
+	 */
+	if (action == GENPD_NOTIFY_ON)
+		udelay(5);
+
+
+	return NOTIFY_OK;
+}
+
+static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = {
+	[IMX8MN_DISPBLK_PD_MIPI_DSI] = {
+		.name = "dispblk-mipi-dsi",
+		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
+		.num_clks = 2,
+		.gpc_name = "mipi-dsi",
+		.rst_mask = BIT(0) | BIT(1),
+		.clk_mask = BIT(0) | BIT(1),
+		.mipi_phy_rst_mask = BIT(17),
+	},
+	[IMX8MN_DISPBLK_PD_MIPI_CSI] = {
+		.name = "dispblk-mipi-csi",
+		.clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
+		.num_clks = 2,
+		.gpc_name = "mipi-csi",
+		.rst_mask = BIT(2) | BIT(3),
+		.clk_mask = BIT(2) | BIT(3),
+		.mipi_phy_rst_mask = BIT(16),
+	},
+	[IMX8MN_DISPBLK_PD_LCDIF] = {
+		.name = "dispblk-lcdif",
+		.clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
+		.num_clks = 3,
+		.gpc_name = "lcdif",
+		.rst_mask = BIT(4) | BIT(5),
+		.clk_mask = BIT(4) | BIT(5),
+	},
+	[IMX8MN_DISPBLK_PD_ISI] = {
+		.name = "dispblk-isi",
+		.clk_names = (const char *[]){ "disp_axi", "disp_apb", "disp_axi_root",
+						"disp_apb_root"},
+		.num_clks = 4,
+		.gpc_name = "isi",
+		.rst_mask = BIT(6) | BIT(7),
+		.clk_mask = BIT(6) | BIT(7),
+	},
+};
+
+static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
+	.max_reg = 0x84,
+	.power_notifier_fn = imx8mn_disp_power_notifier,
+	.domains = imx8mn_disp_blk_ctl_domain_data,
+	.num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
+};
+
+static const struct of_device_id imx8mn_blk_ctrl_of_match[] = {
+	{
+		.compatible = "fsl,imx8mn-disp-blk-ctrl",
+		.data = &imx8mn_disp_blk_ctl_dev_data
+	}, {
+		/* Sentinel */
+	}
+};
+MODULE_DEVICE_TABLE(of, imx8mn_blk_ctrl_of_match);
+
+static struct platform_driver imx8mn_blk_ctrl_driver = {
+	.probe = imx8m_blk_ctrl_probe,
+	.remove = imx8m_blk_ctrl_remove,
+	.driver = {
+		.name = "imx8mn-blk-ctrl",
+		.pm = &imx8m_blk_ctrl_pm_ops,
+		.of_match_table = imx8mn_blk_ctrl_of_match,
+	},
+};
+module_platform_driver(imx8mn_blk_ctrl_driver);
-- 
2.31.1



From abel.vesa at nxp.com  Fri Jan 21 03:22:38 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 21 Jan 2022 13:22:38 +0200
Subject: [RFC 3/3] soc: imx: Rename generic BLK CTRL driver to suggest future
 usability
In-Reply-To: <20220121112238.47281-1-abel.vesa@nxp.com>
References: <20220121112238.47281-1-abel.vesa@nxp.com>
Message-ID: <20220121112238.47281-4-abel.vesa@nxp.com>

By changing the prefix for every single generic API from "imx8m_" to
"imx_" we suggest that it can be used by future i.MX SoC families.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/soc/imx/Makefile                      |  2 +-
 .../imx/{imx8m-blk-ctrl.c => imx-blk-ctrl.c}  | 64 +++++++++----------
 .../imx/{imx8m-blk-ctrl.h => imx-blk-ctrl.h}  | 24 +++----
 drivers/soc/imx/imx8mm-blk-ctrl.c             | 20 +++---
 drivers/soc/imx/imx8mn-blk-ctrl.c             | 14 ++--
 5 files changed, 62 insertions(+), 62 deletions(-)
 rename drivers/soc/imx/{imx8m-blk-ctrl.c => imx-blk-ctrl.c} (79%)
 rename drivers/soc/imx/{imx8m-blk-ctrl.h => imx-blk-ctrl.h} (72%)

diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile
index f5243bc5f08f..5cbcb14ab631 100644
--- a/drivers/soc/imx/Makefile
+++ b/drivers/soc/imx/Makefile
@@ -5,6 +5,6 @@ endif
 obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o
 obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o
 obj-$(CONFIG_SOC_IMX8M) += soc-imx8m.o
-obj-$(CONFIG_SOC_IMX8M) += imx8m-blk-ctrl.o
+obj-$(CONFIG_SOC_IMX8M) += imx-blk-ctrl.o
 obj-$(CONFIG_SOC_IMX8MM_BLK_CTRL) += imx8mm-blk-ctrl.o
 obj-$(CONFIG_SOC_IMX8MN_BLK_CTRL) += imx8mn-blk-ctrl.o
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx-blk-ctrl.c
similarity index 79%
rename from drivers/soc/imx/imx8m-blk-ctrl.c
rename to drivers/soc/imx/imx-blk-ctrl.c
index ebdb044c6afa..58452a936085 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx-blk-ctrl.c
@@ -6,19 +6,19 @@
 
 #include <linux/of_device.h>
 
-#include "imx8m-blk-ctrl.h"
+#include "imx-blk-ctrl.h"
 
-static inline struct imx8m_blk_ctrl_domain *
-to_imx8m_blk_ctrl_domain(struct generic_pm_domain *genpd)
+static inline struct imx_blk_ctrl_domain *
+to_imx_blk_ctrl_domain(struct generic_pm_domain *genpd)
 {
-	return container_of(genpd, struct imx8m_blk_ctrl_domain, genpd);
+	return container_of(genpd, struct imx_blk_ctrl_domain, genpd);
 }
 
-static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
+static int imx_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 {
-	struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd);
-	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
-	struct imx8m_blk_ctrl *bc = domain->bc;
+	struct imx_blk_ctrl_domain *domain = to_imx_blk_ctrl_domain(genpd);
+	const struct imx_blk_ctrl_domain_data *data = domain->data;
+	struct imx_blk_ctrl *bc = domain->bc;
 	int ret;
 
 	/* make sure bus domain is awake */
@@ -70,11 +70,11 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd)
 	return ret;
 }
 
-static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
+static int imx_blk_ctrl_power_off(struct generic_pm_domain *genpd)
 {
-	struct imx8m_blk_ctrl_domain *domain = to_imx8m_blk_ctrl_domain(genpd);
-	const struct imx8m_blk_ctrl_domain_data *data = domain->data;
-	struct imx8m_blk_ctrl *bc = domain->bc;
+	struct imx_blk_ctrl_domain *domain = to_imx_blk_ctrl_domain(genpd);
+	const struct imx_blk_ctrl_domain_data *data = domain->data;
+	struct imx_blk_ctrl *bc = domain->bc;
 
 	/* put devices into reset and disable clocks */
 	if (data->mipi_phy_rst_mask)
@@ -93,7 +93,7 @@ static int imx8m_blk_ctrl_power_off(struct generic_pm_domain *genpd)
 }
 
 static struct generic_pm_domain *
-imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
+imx_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
 {
 	struct genpd_onecell_data *onecell_data = data;
 	unsigned int index = args->args[0];
@@ -107,11 +107,11 @@ imx8m_blk_ctrl_xlate(struct of_phandle_args *args, void *data)
 
 static struct lock_class_key blk_ctrl_genpd_lock_class;
 
-int imx8m_blk_ctrl_probe(struct platform_device *pdev)
+int imx_blk_ctrl_probe(struct platform_device *pdev)
 {
-	const struct imx8m_blk_ctrl_data *bc_data;
+	const struct imx_blk_ctrl_data *bc_data;
 	struct device *dev = &pdev->dev;
-	struct imx8m_blk_ctrl *bc;
+	struct imx_blk_ctrl *bc;
 	void __iomem *base;
 	int i, ret;
 
@@ -140,13 +140,13 @@ int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 				     "failed to init regmap\n");
 
 	bc->domains = devm_kcalloc(dev, bc_data->num_domains,
-				   sizeof(struct imx8m_blk_ctrl_domain),
+				   sizeof(struct imx_blk_ctrl_domain),
 				   GFP_KERNEL);
 	if (!bc->domains)
 		return -ENOMEM;
 
 	bc->onecell_data.num_domains = bc_data->num_domains;
-	bc->onecell_data.xlate = imx8m_blk_ctrl_xlate;
+	bc->onecell_data.xlate = imx_blk_ctrl_xlate;
 	bc->onecell_data.domains =
 		devm_kcalloc(dev, bc_data->num_domains,
 			     sizeof(struct generic_pm_domain *), GFP_KERNEL);
@@ -159,8 +159,8 @@ int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 				     "failed to attach power domain\n");
 
 	for (i = 0; i < bc_data->num_domains; i++) {
-		const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i];
-		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
+		const struct imx_blk_ctrl_domain_data *data = &bc_data->domains[i];
+		struct imx_blk_ctrl_domain *domain = &bc->domains[i];
 		int j;
 
 		domain->data = data;
@@ -184,8 +184,8 @@ int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 		}
 
 		domain->genpd.name = data->name;
-		domain->genpd.power_on = imx8m_blk_ctrl_power_on;
-		domain->genpd.power_off = imx8m_blk_ctrl_power_off;
+		domain->genpd.power_on = imx_blk_ctrl_power_on;
+		domain->genpd.power_off = imx_blk_ctrl_power_off;
 		domain->bc = bc;
 
 		ret = pm_genpd_init(&domain->genpd, NULL, true);
@@ -241,15 +241,15 @@ int imx8m_blk_ctrl_probe(struct platform_device *pdev)
 	return ret;
 }
 
-int imx8m_blk_ctrl_remove(struct platform_device *pdev)
+int imx_blk_ctrl_remove(struct platform_device *pdev)
 {
-	struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
+	struct imx_blk_ctrl *bc = dev_get_drvdata(&pdev->dev);
 	int i;
 
 	of_genpd_del_provider(pdev->dev.of_node);
 
 	for (i = 0; bc->onecell_data.num_domains; i++) {
-		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
+		struct imx_blk_ctrl_domain *domain = &bc->domains[i];
 
 		pm_genpd_remove(&domain->genpd);
 		dev_pm_domain_detach(domain->power_dev, true);
@@ -263,9 +263,9 @@ int imx8m_blk_ctrl_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
-static int imx8m_blk_ctrl_suspend(struct device *dev)
+static int imx_blk_ctrl_suspend(struct device *dev)
 {
-	struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev);
+	struct imx_blk_ctrl *bc = dev_get_drvdata(dev);
 	int ret, i;
 
 	/*
@@ -283,7 +283,7 @@ static int imx8m_blk_ctrl_suspend(struct device *dev)
 	}
 
 	for (i = 0; i < bc->onecell_data.num_domains; i++) {
-		struct imx8m_blk_ctrl_domain *domain = &bc->domains[i];
+		struct imx_blk_ctrl_domain *domain = &bc->domains[i];
 
 		ret = pm_runtime_get_sync(domain->power_dev);
 		if (ret < 0) {
@@ -303,9 +303,9 @@ static int imx8m_blk_ctrl_suspend(struct device *dev)
 	return ret;
 }
 
-static int imx8m_blk_ctrl_resume(struct device *dev)
+static int imx_blk_ctrl_resume(struct device *dev)
 {
-	struct imx8m_blk_ctrl *bc = dev_get_drvdata(dev);
+	struct imx_blk_ctrl *bc = dev_get_drvdata(dev);
 	int i;
 
 	for (i = 0; i < bc->onecell_data.num_domains; i++)
@@ -317,6 +317,6 @@ static int imx8m_blk_ctrl_resume(struct device *dev)
 }
 #endif
 
-const struct dev_pm_ops imx8m_blk_ctrl_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(imx8m_blk_ctrl_suspend, imx8m_blk_ctrl_resume)
+const struct dev_pm_ops imx_blk_ctrl_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(imx_blk_ctrl_suspend, imx_blk_ctrl_resume)
 };
diff --git a/drivers/soc/imx/imx8m-blk-ctrl.h b/drivers/soc/imx/imx-blk-ctrl.h
similarity index 72%
rename from drivers/soc/imx/imx8m-blk-ctrl.h
rename to drivers/soc/imx/imx-blk-ctrl.h
index 618b3429bb69..8b70e072db1c 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.h
+++ b/drivers/soc/imx/imx-blk-ctrl.h
@@ -18,18 +18,18 @@
 #define BLK_CLK_EN	0x4
 #define BLK_MIPI_RESET_DIV	0x8 /* Mini/Nano DISPLAY_BLK_CTRL only */
 
-struct imx8m_blk_ctrl_domain;
+struct imx_blk_ctrl_domain;
 
-struct imx8m_blk_ctrl {
+struct imx_blk_ctrl {
 	struct device *dev;
 	struct notifier_block power_nb;
 	struct device *bus_power_dev;
 	struct regmap *regmap;
-	struct imx8m_blk_ctrl_domain *domains;
+	struct imx_blk_ctrl_domain *domains;
 	struct genpd_onecell_data onecell_data;
 };
 
-struct imx8m_blk_ctrl_domain_data {
+struct imx_blk_ctrl_domain_data {
 	const char *name;
 	const char * const *clk_names;
 	int num_clks;
@@ -49,24 +49,24 @@ struct imx8m_blk_ctrl_domain_data {
 
 #define DOMAIN_MAX_CLKS 3
 
-struct imx8m_blk_ctrl_domain {
+struct imx_blk_ctrl_domain {
 	struct generic_pm_domain genpd;
-	const struct imx8m_blk_ctrl_domain_data *data;
+	const struct imx_blk_ctrl_domain_data *data;
 	struct clk_bulk_data clks[DOMAIN_MAX_CLKS];
 	struct device *power_dev;
-	struct imx8m_blk_ctrl *bc;
+	struct imx_blk_ctrl *bc;
 };
 
-struct imx8m_blk_ctrl_data {
+struct imx_blk_ctrl_data {
 	int max_reg;
 	notifier_fn_t power_notifier_fn;
-	const struct imx8m_blk_ctrl_domain_data *domains;
+	const struct imx_blk_ctrl_domain_data *domains;
 	int num_domains;
 };
 
-extern const struct dev_pm_ops imx8m_blk_ctrl_pm_ops;
+extern const struct dev_pm_ops imx_blk_ctrl_pm_ops;
 
-int imx8m_blk_ctrl_remove(struct platform_device *pdev);
-int imx8m_blk_ctrl_probe(struct platform_device *pdev);
+int imx_blk_ctrl_remove(struct platform_device *pdev);
+int imx_blk_ctrl_probe(struct platform_device *pdev);
 
 #endif
diff --git a/drivers/soc/imx/imx8mm-blk-ctrl.c b/drivers/soc/imx/imx8mm-blk-ctrl.c
index eb63d28b0157..15f1e431c1f3 100644
--- a/drivers/soc/imx/imx8mm-blk-ctrl.c
+++ b/drivers/soc/imx/imx8mm-blk-ctrl.c
@@ -7,12 +7,12 @@
 
 #include <dt-bindings/power/imx8mm-power.h>
 
-#include "imx8m-blk-ctrl.h"
+#include "imx-blk-ctrl.h"
 
 static int imx8mm_vpu_power_notifier(struct notifier_block *nb,
 				     unsigned long action, void *data)
 {
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+	struct imx_blk_ctrl *bc = container_of(nb, struct imx_blk_ctrl,
 						 power_nb);
 
 	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
@@ -45,7 +45,7 @@ static int imx8mm_vpu_power_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
-static const struct imx8m_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[] = {
+static const struct imx_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[] = {
 	[IMX8MM_VPUBLK_PD_G1] = {
 		.name = "vpublk-g1",
 		.clk_names = (const char *[]){ "g1", },
@@ -72,7 +72,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mm_vpu_blk_ctl_domain_data[]
 	},
 };
 
-static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
+static const struct imx_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
 	.max_reg = 0x18,
 	.power_notifier_fn = imx8mm_vpu_power_notifier,
 	.domains = imx8mm_vpu_blk_ctl_domain_data,
@@ -82,7 +82,7 @@ static const struct imx8m_blk_ctrl_data imx8mm_vpu_blk_ctl_dev_data = {
 static int imx8mm_disp_power_notifier(struct notifier_block *nb,
 				      unsigned long action, void *data)
 {
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+	struct imx_blk_ctrl *bc = container_of(nb, struct imx_blk_ctrl,
 						 power_nb);
 
 	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
@@ -104,7 +104,7 @@ static int imx8mm_disp_power_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
-static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[] = {
+static const struct imx_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[] = {
 	[IMX8MM_DISPBLK_PD_CSI_BRIDGE] = {
 		.name = "dispblk-csi-bridge",
 		.clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb",
@@ -141,7 +141,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mm_disp_blk_ctl_domain_data[]
 	},
 };
 
-static const struct imx8m_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = {
+static const struct imx_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = {
 	.max_reg = 0x2c,
 	.power_notifier_fn = imx8mm_disp_power_notifier,
 	.domains = imx8mm_disp_blk_ctl_domain_data,
@@ -162,11 +162,11 @@ static const struct of_device_id imx8mm_blk_ctrl_of_match[] = {
 MODULE_DEVICE_TABLE(of, imx8mm_blk_ctrl_of_match);
 
 static struct platform_driver imx8mm_blk_ctrl_driver = {
-	.probe = imx8m_blk_ctrl_probe,
-	.remove = imx8m_blk_ctrl_remove,
+	.probe = imx_blk_ctrl_probe,
+	.remove = imx_blk_ctrl_remove,
 	.driver = {
 		.name = "imx8mm-blk-ctrl",
-		.pm = &imx8m_blk_ctrl_pm_ops,
+		.pm = &imx_blk_ctrl_pm_ops,
 		.of_match_table = imx8mm_blk_ctrl_of_match,
 	},
 };
diff --git a/drivers/soc/imx/imx8mn-blk-ctrl.c b/drivers/soc/imx/imx8mn-blk-ctrl.c
index 20f53cd4e387..932b81515792 100644
--- a/drivers/soc/imx/imx8mn-blk-ctrl.c
+++ b/drivers/soc/imx/imx8mn-blk-ctrl.c
@@ -7,12 +7,12 @@
 
 #include <dt-bindings/power/imx8mn-power.h>
 
-#include "imx8m-blk-ctrl.h"
+#include "imx-blk-ctrl.h"
 
 static int imx8mn_disp_power_notifier(struct notifier_block *nb,
 				      unsigned long action, void *data)
 {
-	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+	struct imx_blk_ctrl *bc = container_of(nb, struct imx_blk_ctrl,
 						 power_nb);
 
 	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
@@ -34,7 +34,7 @@ static int imx8mn_disp_power_notifier(struct notifier_block *nb,
 	return NOTIFY_OK;
 }
 
-static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = {
+static const struct imx_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = {
 	[IMX8MN_DISPBLK_PD_MIPI_DSI] = {
 		.name = "dispblk-mipi-dsi",
 		.clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
@@ -72,7 +72,7 @@ static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[]
 	},
 };
 
-static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
+static const struct imx_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
 	.max_reg = 0x84,
 	.power_notifier_fn = imx8mn_disp_power_notifier,
 	.domains = imx8mn_disp_blk_ctl_domain_data,
@@ -90,11 +90,11 @@ static const struct of_device_id imx8mn_blk_ctrl_of_match[] = {
 MODULE_DEVICE_TABLE(of, imx8mn_blk_ctrl_of_match);
 
 static struct platform_driver imx8mn_blk_ctrl_driver = {
-	.probe = imx8m_blk_ctrl_probe,
-	.remove = imx8m_blk_ctrl_remove,
+	.probe = imx_blk_ctrl_probe,
+	.remove = imx_blk_ctrl_remove,
 	.driver = {
 		.name = "imx8mn-blk-ctrl",
-		.pm = &imx8m_blk_ctrl_pm_ops,
+		.pm = &imx_blk_ctrl_pm_ops,
 		.of_match_table = imx8mn_blk_ctrl_of_match,
 	},
 };
-- 
2.31.1



From gankulkarni at os.amperecomputing.com  Fri Jan 21 03:33:30 2022
From: gankulkarni at os.amperecomputing.com (Ganapatrao Kulkarni)
Date: Fri, 21 Jan 2022 17:03:30 +0530
Subject: [PATCH v5 36/69] KVM: arm64: nv: Filter out unsupported features
 from ID regs
In-Reply-To: <87zgouuxvy.wl-maz@kernel.org>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-37-maz@kernel.org>
 <e850857c-9cab-8e16-0568-acb513514ae8@os.amperecomputing.com>
 <87h7b3wqe9.wl-maz@kernel.org>
 <ef667048-7fbe-55dc-9856-546fd9d3c690@os.amperecomputing.com>
 <87zgouuxvy.wl-maz@kernel.org>
Message-ID: <300f7a61-acd1-21bd-d36d-1532d2cecf44@os.amperecomputing.com>

Hi Marc,

On 21-12-2021 02:40 pm, Marc Zyngier wrote:
> On Tue, 21 Dec 2021 06:03:49 +0000,
> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>
>>
>>
>> On 20-12-2021 03:26 pm, Marc Zyngier wrote:
>>> On Mon, 20 Dec 2021 07:26:50 +0000,
>>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
>>>>
>>>>
>>>> Hi Marc,
>>>>
>>>> On 30-11-2021 01:31 am, Marc Zyngier wrote:
>>>>> As there is a number of features that we either can't support,
>>>>> or don't want to support right away with NV, let's add some
>>>>> basic filtering so that we don't advertize silly things to the
>>>>> EL2 guest.
>>>>>
>>>>> Whilst we are at it, avertize ARMv8.4-TTL as well as ARMv8.5-GTG.
>>>>>
>>>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
>>>>> ---
>>>>>     arch/arm64/include/asm/kvm_nested.h |   6 ++
>>>>>     arch/arm64/kvm/nested.c             | 152 ++++++++++++++++++++++++++++
>>>>>     arch/arm64/kvm/sys_regs.c           |   4 +-
>>>>>     arch/arm64/kvm/sys_regs.h           |   2 +
>>>>>     4 files changed, 163 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
>>>>> index 07c15f51cf86..026ddaad972c 100644
>>>>> --- a/arch/arm64/include/asm/kvm_nested.h
>>>>> +++ b/arch/arm64/include/asm/kvm_nested.h
>>>>> @@ -67,4 +67,10 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
>>>>>     extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
>>>>>     extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
>>>>>     +struct sys_reg_params;
>>>>> +struct sys_reg_desc;
>>>>> +
>>>>> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
>>>>> +			  const struct sys_reg_desc *r);
>>>>> +
>>>>>     #endif /* __ARM64_KVM_NESTED_H */
>>>>> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
>>>>> index 42a96c8d2adc..19b674983e13 100644
>>>>> --- a/arch/arm64/kvm/nested.c
>>>>> +++ b/arch/arm64/kvm/nested.c
>>>>> @@ -20,6 +20,10 @@
>>>>>     #include <linux/kvm_host.h>
>>>>>       #include <asm/kvm_emulate.h>
>>>>> +#include <asm/kvm_nested.h>
>>>>> +#include <asm/sysreg.h>
>>>>> +
>>>>> +#include "sys_regs.h"
>>>>>       /*
>>>>>      * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
>>>>> @@ -38,3 +42,151 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
>>>>>       	return -EINVAL;
>>>>>     }
>>>>> +
>>>>> +/*
>>>>> + * Our emulated CPU doesn't support all the possible features. For the
>>>>> + * sake of simplicity (and probably mental sanity), wipe out a number
>>>>> + * of feature bits we don't intend to support for the time being.
>>>>> + * This list should get updated as new features get added to the NV
>>>>> + * support, and new extension to the architecture.
>>>>> + */
>>>>> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
>>>>> +			  const struct sys_reg_desc *r)
>>>>> +{
>>>>> +	u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
>>>>> +			 (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
>>>>> +	u64 val, tmp;
>>>>> +
>>>>> +	if (!nested_virt_in_use(v))
>>>>> +		return;
>>>>> +
>>>>> +	val = p->regval;
>>>>> +
>>>>> +	switch (id) {
>>>>> +	case SYS_ID_AA64ISAR0_EL1:
>>>>> +		/* Support everything but O.S. and Range TLBIs */
>>>>> +		val &= ~(FEATURE(ID_AA64ISAR0_TLB)	|
>>>>> +			 GENMASK_ULL(27, 24)		|
>>>>> +			 GENMASK_ULL(3, 0));
>>>>> +		break;
>>>>> +
>>>>> +	case SYS_ID_AA64ISAR1_EL1:
>>>>> +		/* Support everything but PtrAuth and Spec Invalidation */
>>>>> +		val &= ~(GENMASK_ULL(63, 56)		|
>>>>> +			 FEATURE(ID_AA64ISAR1_SPECRES)	|
>>>>> +			 FEATURE(ID_AA64ISAR1_GPI)	|
>>>>> +			 FEATURE(ID_AA64ISAR1_GPA)	|
>>>>> +			 FEATURE(ID_AA64ISAR1_API)	|
>>>>> +			 FEATURE(ID_AA64ISAR1_APA));
>>>>> +		break;
>>>>> +
>>>>> +	case SYS_ID_AA64PFR0_EL1:
>>>>> +		/* No AMU, MPAM, S-EL2, RAS or SVE */
>>>>> +		val &= ~(GENMASK_ULL(55, 52)		|
>>>>> +			 FEATURE(ID_AA64PFR0_AMU)	|
>>>>> +			 FEATURE(ID_AA64PFR0_MPAM)	|
>>>>> +			 FEATURE(ID_AA64PFR0_SEL2)	|
>>>>> +			 FEATURE(ID_AA64PFR0_RAS)	|
>>>>> +			 FEATURE(ID_AA64PFR0_SVE)	|
>>>>> +			 FEATURE(ID_AA64PFR0_EL3)	|
>>>>> +			 FEATURE(ID_AA64PFR0_EL2));
>>>>> +		/* 64bit EL2/EL3 only */
>>>>> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), 0b0001);
>>>>> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), 0b0001);
>>>>> +		break;
>>>>> +
>>>>> +	case SYS_ID_AA64PFR1_EL1:
>>>>> +		/* Only support SSBS */
>>>>> +		val &= FEATURE(ID_AA64PFR1_SSBS);
>>>>> +		break;
>>>>> +
>>>>> +	case SYS_ID_AA64MMFR0_EL1:
>>>>> +		/* Hide ECV, FGT, ExS, Secure Memory */
>>>>> +		val &= ~(GENMASK_ULL(63, 43)			|
>>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN4_2)		|
>>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN16_2)	|
>>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN64_2)	|
>>>>> +			 FEATURE(ID_AA64MMFR0_SNSMEM));
>>>>> +
>>>>> +		/* Disallow unsupported S2 page sizes */
>>>>> +		switch (PAGE_SIZE) {
>>>>> +		case SZ_64K:
>>>>> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0001);
>>>>> +			fallthrough;
>>>>> +		case SZ_16K:
>>>>> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0001);
>>>>> +			fallthrough;
>>>>> +		case SZ_4K:
>>>>> +			/* Support everything */
>>>>> +			break;
>>>>> +		}
>>>>
>>>> It seems to me that Host hypervisor(L0) has to boot with 4KB page size
>>>> to support all (4, 16 and 64KB) page sizes at L1, any specific reason
>>>> for this restriction?
>>>
>>> Well, yes.
>>>
>>> If you have a L0 that has booted with (let's say) 64kB page size, how
>>> do you provide S2 mappings with 4kB granularity so that you can
>>> implement the permissions that a L1 guest hypervisor can impose on its
>>> own guest, given that KVM currently mandates S1 and S2 to use the same
>>> page sizes?
>>>
>>> You can't. That's why we tell the guest hypervisor how much we
>>> support, and the guest hypervisor can decide to go ahead or not
>>> depending on what it does.
>>>
>>> If one day we can support S2 mappings that are smaller than the host
>>> page sizes, then we'll be able to allow to advertise all page sizes.
>>> But I wouldn't hold my breath for this to happen.
>>
>> Thanks for the detailed explanation!.
>> Can we put one line comment that explains why this manipulation?
>> It would be helpful to see a comment like S2 PAGE_SIZE should be
>> at-least the size of Host PAGE_SIZE?
> 
> Can do, but we need to get the terminology straight, because this is
> very quickly becoming confusing. Something like:
> 
> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> index 7c9dd1edf011..d35a947f5679 100644
> --- a/arch/arm64/kvm/nested.c
> +++ b/arch/arm64/kvm/nested.c
> @@ -850,7 +850,12 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
>   			/* Support everything */
>   			break;
>   		}
> -		/* Advertize supported S2 page sizes */
> +		/*
> +		 * Since we can't support a guest S2 page size smaller than
> +		 * the host's own page size (due to KVM only populating its
> +		 * own S2 using the kernel's page size), advertise the
> +		 * limitation using FEAT_GTG.
> +		 */

I have tried booting L0 with 4K page-size and L1 with 64K and with this 
config the L2/NestedVM boot hangs. I have tried L2 with page-sizes 4K 
and 64K(though S1 page size of L2 should not matter?).


>   		switch (PAGE_SIZE) {
>   		case SZ_4K:
>   			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0010);
> 
> So not quite a one line comment! ;-)
> 
> Ultimately, all there is to know is in the description of FEAT_GTG in
> the ARMv8 ARM.
> 
> Thanks,
> 
> 	M.
> 

Thanks,
Ganapat


From angelogioacchino.delregno at collabora.com  Fri Jan 21 03:46:17 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 21 Jan 2022 12:46:17 +0100
Subject: [PATCH] arm64: dts: mt8183: jacuzzi: Fix bus properties in anx's
 DSI endpoint
In-Reply-To: <20220120224204.773117-1-nfraprado@collabora.com>
References: <20220120224204.773117-1-nfraprado@collabora.com>
Message-ID: <29069a98-a839-4fb6-5b83-7877402aaf30@collabora.com>

Il 20/01/22 23:42, N?colas F. R. A. Prado ha scritto:
> mt8183-kukui-jacuzzi has an anx7625 bridge connected to the output of
> its DSI host. However, after fd0310b6fe7d ("drm/bridge: anx7625: add
> MIPI DPI input feature"), a bus-type property started being required in
> the endpoint node by the driver to indicate whether it is DSI or DPI.
> 
> Add the missing bus-type property and set it to 5
> (V4L2_FWNODE_BUS_TYPE_PARALLEL) so that the driver has its input
> configured to DSI and the display pipeline can probe correctly.
> 
> While at it, also set the data-lanes property that was also introduced
> in that same commit, so that we don't rely on the default value.
> 
> Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature")
> Signed-off-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> ---
>   arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> index 8f7bf33f607d..e8f133dc96b9 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
> @@ -171,6 +171,8 @@ port at 0 {
>   
>   			anx7625_in: endpoint {
>   				remote-endpoint = <&dsi_out>;
> +				bus-type = <5>;
> +				data-lanes = <0 1 2 3>;
>   			};
>   		};
>   
> 


From hverkuil at xs4all.nl  Fri Jan 21 03:56:05 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 21 Jan 2022 12:56:05 +0100
Subject: [PATCH v9 12/15] media: mtk-vcodec: enc: Remove
 mtk_vcodec_release_enc_pm
In-Reply-To: <e940d705-2057-4d5e-0a21-8464ca04caaf@gmail.com>
References: <20211112105509.12010-1-yong.wu@mediatek.com>
 <20211112105509.12010-13-yong.wu@mediatek.com>
 <68c3a573-8453-38e9-93b2-2067bedcd06f@collabora.com>
 <4bd9e849-96dd-6f1c-2841-979459366ee5@collabora.com>
 <fa9b2b73-c6bb-5737-93ac-ba2ab6b3b771@xs4all.nl>
 <e940d705-2057-4d5e-0a21-8464ca04caaf@gmail.com>
Message-ID: <8ae4a49a-4abf-be55-f6c8-9fc4ffd02fc8@xs4all.nl>

Hi Matthias,

On 1/13/22 17:10, Matthias Brugger wrote:
> Hi Hans,
> 
> On 13/01/2022 11:15, Hans Verkuil wrote:
>> On 13/01/2022 11:11, AngeloGioacchino Del Regno wrote:
>>> Il 11/01/22 11:57, AngeloGioacchino Del Regno ha scritto:
>>>> Il 12/11/21 11:55, Yong Wu ha scritto:
>>>>> After this patchset, mtk_vcodec_release_enc_pm has only one line.
>>>>> then remove that function, use pm_runtime_disable instead.
>>>>>
>>>>> meanwhile, mtk_vcodec_init_enc_pm only operate for the clocks,
>>>>> rename it from the _pm to _clk.
>>>>>
>>>>> No functional change.
>>>>>
>>>>> CC: Tiffany Lin <tiffany.lin at mediatek.com>
>>>>> CC: Irui Wang <irui.wang at mediatek.com>
>>>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>>>
>>>> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>>>
>>>
>>> Hello Yong,
>>> the mtk-vcodec patches were merged in Yunfei's vcodec patch series and Hans has
>>> scheduled that for v5.18.
>>>
>>> Can you please send a v10 and drop patches 10/15, 11/15, 12/15 (all of the
>>> media: mtk-vcodec: *) from this series?
>>>
>>> For the records, I think that after sending v10 this series is ready to be merged,
>>> as it was well reviewed and also tested on many MTK platforms.
>>
>> Good to know. When I have the v10 I'll try to prioritize reviewing it and running
>> my usual tests.
>>
>> Yong, please make sure you run 'checkpatch.pl --strict' over the v10 patches and fix
>> any issues (using common sense).
>>
> 
> Can you please take me in the look when you take the patches. I'll take the DTS related as soon as you queue up the others.

This just got merged into our tree.

Regards,

	Hans


From angelogioacchino.delregno at collabora.com  Fri Jan 21 03:58:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 21 Jan 2022 12:58:21 +0100
Subject: [PATCH v11 2/3] dts: arm64: mt8183: add Mediatek MDP3 nodes
In-Reply-To: <20220105093758.6850-3-moudy.ho@mediatek.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-3-moudy.ho@mediatek.com>
Message-ID: <d61ec481-8059-a897-504a-0125f88fad61@collabora.com>

Il 05/01/22 10:37, Moudy Ho ha scritto:
> Add device nodes for Media Data Path 3 (MDP3) modules.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
>   arch/arm64/boot/dts/mediatek/mt8183.dtsi | 108 ++++++++++++++++++++++-
>   1 file changed, 107 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> index ba4584faca5a..b872ef1ff6b3 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> @@ -1325,6 +1325,79 @@
>   			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
>   		};
>   
> +		mdp3_rdma0: mdp3_rdma0 at 14001000 {
> +			compatible = "mediatek,mt8183-mdp3",
> +				     "mediatek,mt8183-mdp3-rdma0";
> +			mediatek,scp = <&scp>;
> +			mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
> +					      "mediatek,mt8183-mdp3-dl2",
> +					      "mediatek,mt8183-mdp3-path1",
> +					      "mediatek,mt8183-mdp3-path2",
> +					      "mediatek,mt8183-mdp3-imgi",
> +					      "mediatek,mt8183-mdp3-exto";
> +			reg = <0 0x14001000 0 0x1000>,
> +			      <0 0x14000000 0 0x1000>,
> +			      <0 0x14005000 0 0x1000>,
> +			      <0 0x14006000 0 0x1000>,
> +			      <0 0x15020000 0 0x1000>;
> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
> +						  <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
> +						  <&gce SUBSYS_1502XXXX 0 0x1000>;
> +			power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> +				 <&mmsys CLK_MM_MDP_RSZ1>,
> +				 <&mmsys CLK_MM_MDP_DL_TXCK>,
> +				 <&mmsys CLK_MM_MDP_DL_RX>,
> +				 <&mmsys CLK_MM_IPU_DL_TXCK>,
> +				 <&mmsys CLK_MM_IPU_DL_RX>;
> +			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
> +			mediatek,mmsys = <&mmsys>;
> +			mediatek,mm-mutex = <&mutex>;
> +			mediatek,mailbox-gce = <&gce>;
> +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> +				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
> +				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
> +				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;

Hello Moudy,
the mboxes for gce 21, 22, 23 are missing the third cell. Please fix.

Regards,
Angelo

> +			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> +				     <&gce 0x14010000 SUBSYS_1401XXXX>,
> +				     <&gce 0x14020000 SUBSYS_1402XXXX>,
> +				     <&gce 0x15020000 SUBSYS_1502XXXX>;
> +		};
> +



From michal.simek at xilinx.com  Fri Jan 21 03:58:56 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Fri, 21 Jan 2022 12:58:56 +0100
Subject: [PATCH 0/3] dt-bindings: dmaengine: zynqmp_dma: Convert binding
 to YAML
In-Reply-To: <20220112151541.1328732-1-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
Message-ID: <b3754a86-9c1f-f2ce-cc75-d8638010aa94@xilinx.com>



On 1/12/22 16:15, Michael Tretter wrote:
> Hi,
> 
> This series converts the ZynqMP dma engine dt bindings to yaml and fixes the
> ZynqMP device tree following the stricter yaml bindings.
> 
> The series is based on https://github.com/Xilinx/linux-xlnx/tree/zynqmp/dt to
> avoid conflicts when applying the patches to the zynqmp/dt tree.
> 
> Patch 1 converts the binding to yaml, Patches 2 and 3 cleanup the dma engine
> nodes in the zynqmp.dtsi that is included by actual board device trees.
> 
> Michael
> 
> Michael Tretter (3):
>    dt-bindings: dmaengine: zynqmp_dma: convert to yaml
>    arm64: zynqmp: Add missing #dma-cells property
>    arm64: zynqmp: Rename dma to dma-controller
> 
>   .../dma/xilinx/xlnx,zynqmp-dma-1.0.yaml       | 85 +++++++++++++++++++
>   .../bindings/dma/xilinx/zynqmp_dma.txt        | 26 ------
>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 48 +++++++----
>   3 files changed, 117 insertions(+), 42 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
>   delete mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> 

Rob/Vinod:
Not sure how you want to split it but feel free to take 2/3 and 3/3 via your 
tree with my ack.

Acked-by: Michal Simek <michal.simek at xilinx.com>

If you want to take just 1/3 I will take the rest via my soc tree.

Thanks,
Michal



From vincenzo.frascino at arm.com  Fri Jan 21 04:12:26 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 21 Jan 2022 12:12:26 +0000
Subject: [PATCH] arm64: vdso: fix "no previous prototype" warning
In-Reply-To: <20220109113504.1921017-1-mkl@pengutronix.de>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
Message-ID: <0030cecf-e79b-f666-8516-d0589bc49b81@arm.com>

Hi Marc,

On 1/9/22 11:35 AM, Marc Kleine-Budde wrote:
> If compiling the arm64 kernel with W=1 the following warning is produced:
> 
> | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
> |     9 | int __kernel_clock_gettime(clockid_t clock,
> |       |     ^~~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
> |    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
> |    21 | int __kernel_clock_getres(clockid_t clock_id,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> 
> This patch adds the missing prototype to fix the warning and make
> compilation with "CONFIG_WERROR=y" possible.
> 

Instead of adding the prototypes, how about we silence the warning for the
specific file? Since adding them does not seem to add any value in this context.

If you agree, could please test the patch I sent in reply to this one and let me
know if it works for your usecase? Thanks.

> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Vincenzo Frascino <vincenzo.frascino at arm.com>
> Signed-off-by: Marc Kleine-Budde <mkl at pengutronix.de>
> ---
>  arch/arm64/kernel/vdso/vgettimeofday.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
> index 4236cf34d7d9..cc37674b9d35 100644
> --- a/arch/arm64/kernel/vdso/vgettimeofday.c
> +++ b/arch/arm64/kernel/vdso/vgettimeofday.c
> @@ -6,18 +6,27 @@
>   *
>   */
>  
> +int __kernel_clock_gettime(clockid_t clock,
> +			   struct __kernel_timespec *ts);
> +
>  int __kernel_clock_gettime(clockid_t clock,
>  			   struct __kernel_timespec *ts)
>  {
>  	return __cvdso_clock_gettime(clock, ts);
>  }
>  
> +int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> +			  struct timezone *tz);
> +
>  int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
>  			  struct timezone *tz)
>  {
>  	return __cvdso_gettimeofday(tv, tz);
>  }
>  
> +int __kernel_clock_getres(clockid_t clock_id,
> +			  struct __kernel_timespec *res);
> +
>  int __kernel_clock_getres(clockid_t clock_id,
>  			  struct __kernel_timespec *res)
>  {
> 

-- 
Regards,
Vincenzo


From vincenzo.frascino at arm.com  Fri Jan 21 04:12:34 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 21 Jan 2022 12:12:34 +0000
Subject: [PATCH] arm64: vdso: Fix "no previous prototype" warning
In-Reply-To: <20220109113504.1921017-1-mkl@pengutronix.de>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
Message-ID: <20220121121234.47273-1-vincenzo.frascino@arm.com>

If compiling the arm64 kernel with W=1 the following warning is produced:

| arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
|     9 | int __kernel_clock_gettime(clockid_t clock,
|       |     ^~~~~~~~~~~~~~~~~~~~~~
| arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
|    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
|       |     ^~~~~~~~~~~~~~~~~~~~~
| arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
|    21 | int __kernel_clock_getres(clockid_t clock_id,
|       |     ^~~~~~~~~~~~~~~~~~~~~

This patch removes "-Wmissing-prototypes" and "-Wmissing-declarations" compilers
flags from the compilation of vgettimeofday.c to make possible to build the
kernel with CONFIG_WERROR enabled.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Suggested-by: Marc Kleine-Budde <mkl at pengutronix.de>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino at arm.com>
---
 arch/arm64/kernel/vdso/Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makefile
index 60813497a381..172452f79e46 100644
--- a/arch/arm64/kernel/vdso/Makefile
+++ b/arch/arm64/kernel/vdso/Makefile
@@ -29,8 +29,11 @@ ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv	\
 ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18
 ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
 
+# -Wmissing-prototypes and -Wmissing-declarations are removed from
+# the CFLAGS of vgettimeofday.c to make possible to build the
+# kernel with CONFIG_WERROR enabled.
 CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \
-				$(CC_FLAGS_LTO)
+				$(CC_FLAGS_LTO) -Wmissing-prototypes -Wmissing-declarations
 KASAN_SANITIZE			:= n
 KCSAN_SANITIZE			:= n
 UBSAN_SANITIZE			:= n
-- 
2.34.1



From m.szyprowski at samsung.com  Fri Jan 21 04:31:17 2022
From: m.szyprowski at samsung.com (Marek Szyprowski)
Date: Fri, 21 Jan 2022 13:31:17 +0100
Subject: [RFC 2/3] iommu/samsung: Introduce Exynos sysmmu-v8 driver
In-Reply-To: <CAPLW+4kKR+7hM-eZc8-v6Dzeaj+TPBRmCLDSVNEnfx2WmN2TJA@mail.gmail.com>
References: <20220120201958.2649-1-semen.protsenko@linaro.org>
 <20220120201958.2649-3-semen.protsenko@linaro.org>
 <a111932a-6685-2a9d-abce-87af26b121a4@canonical.com>
 <CGME20220121110911eucas1p28d11e1b04773e8174b9d65f011dc1977@eucas1p2.samsung.com>
 <CAPLW+4kKR+7hM-eZc8-v6Dzeaj+TPBRmCLDSVNEnfx2WmN2TJA@mail.gmail.com>
Message-ID: <54b76143-dff3-8a19-7ab9-57fb80d59743@samsung.com>

Hi Sam,

On 21.01.2022 12:08, Sam Protsenko wrote:
> On Fri, 21 Jan 2022 at 10:40, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>> On 20/01/2022 21:19, Sam Protsenko wrote:
>>> Introduce new driver for modern Exynos ARMv8 SoCs, e.g. Exynos850. Also
>>> it's used for Google's GS101 SoC.
>>>
>>> This is squashed commit, contains next patches of different authors. See
>>> `iommu-exynos850-dev' branch for details: [1].
>>>
>>> Original authors (Samsung):
>>>
>>>   - Cho KyongHo <pullip.cho at samsung.com>
>>>   - Hyesoo Yu <hyesoo.yu at samsung.com>
>>>   - Janghyuck Kim <janghyuck.kim at samsung.com>
>>>   - Jinkyu Yang <jinkyu1.yang at samsung.com>
>>>
>>> Some improvements were made by Google engineers:
>>>
>>>   - Alex <acnwigwe at google.com>
>>>   - Carlos Llamas <cmllamas at google.com>
>>>   - Daniel Mentz <danielmentz at google.com>
>>>   - Erick Reyes <erickreyes at google.com>
>>>   - J. Avila <elavila at google.com>
>>>   - Jonglin Lee <jonglin at google.com>
>>>   - Mark Salyzyn <salyzyn at google.com>
>>>   - Thierry Strudel <tstrudel at google.com>
>>>   - Will McVicker <willmcvicker at google.com>
>>>
>>> [1] https://protect2.fireeye.com/v1/url?k=19bd3571-46260c3c-19bcbe3e-0cc47aa8f5ba-8a160a7fd38bb35a&q=1&e=eb3f71b3-8df2-46c6-b6d8-0a931ef99024&u=https%3A%2F%2Fgithub.com%2Fjoe-skb7%2Flinux%2Ftree%2Fiommu-exynos850-dev
>>>
>>> Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>>> ---
>>>   drivers/iommu/Kconfig               |   13 +
>>>   drivers/iommu/Makefile              |    3 +
>>>   drivers/iommu/samsung-iommu-fault.c |  617 +++++++++++
>>>   drivers/iommu/samsung-iommu-group.c |   50 +
>>>   drivers/iommu/samsung-iommu.c       | 1521 +++++++++++++++++++++++++++
>>>   drivers/iommu/samsung-iommu.h       |  216 ++++
>>>   6 files changed, 2420 insertions(+)
>>>   create mode 100644 drivers/iommu/samsung-iommu-fault.c
>>>   create mode 100644 drivers/iommu/samsung-iommu-group.c
>>>   create mode 100644 drivers/iommu/samsung-iommu.c
>>>   create mode 100644 drivers/iommu/samsung-iommu.h
>>>
>> Existing driver supports several different Exynos SysMMU IP block
>> versions. Several. Please explain why it cannot support one more version?
>>
>> Similarity of vendor driver with mainline is not an argument.
>>
>>> ...
>> You just copy-pasted vendor stuff, without actually going through it.
>>
>> It is very disappointing because instead of putting your own effort, you
>> expect community to do your job.
>>
>> What the hell is CONFIG_EXYNOS_CONTENT_PATH_PROTECTION?
>>
>> I'll stop reviewing. Please work on extending existing driver. If you
>> submitted something nice and clean, ready for upstream, instead of
>> vendor junk, you could get away with separate driver. But you did not.
>> It looks really bad.
>>
> Krzysztof, that's not what I asked in my patch 0/3. I probably wasn't
> really clear, sorry. Let me please try and describe that better, and
> maybe provide some context.
>
> I'm just starting to work on that driver, it's basically downstream
> version of it. Of course I'm going to rework it before sending the
> actual patch series (that's why this series has RFC tag). I'd never
> asked community to do my job for me and really review the downstream
> driver! I just want to know from the starters some *very* basic and
> high-level info, which could help me to rework the driver in correct
> way. Like naming of files, compatible strings, should it be part of
> existing driver or it's ok to have it as another platform_driver. In
> other words, that kind of "review" shouldn't take more than 2 minutes
> of your time. And it could spare us all unneeded extra review rounds
> in future. Right now I don't need the code review per se (and I'm
> really sorry you had to spend your time on that, knowing how busy
> maintainers can be during the MW). I thought about omitting the code
> at all, only asking the questions, but then I figured it's a good idea
> to attach some code for the reference. Maybe it wasn't a good idea
> after all.
>
> For the record, I'm well aware that we don't send downstream code
> without making it upstreamable first, and I know it must be tested
> well, etc. For example, you already saw me sending clk-exynos850
> driver, which I re-implemented from scratch, and it has ~0.0% of
> downstream code. So why would I change my policy about that all of the
> sudden... Anyway, hope you understand now that there weren't any ill
> intentions on my side, w.r.t. this RFC.


Well, for starting point the existing exynos-iommu driver is really 
enough. I've played a bit with newer Exyos SoCs some time ago. If I 
remember right, if you limit the iommu functionality to the essential 
things like mapping pages to IO-virtual space, the hardware differences 
between SYSMMU v5 (already supported by the exynos-iommu driver) and v7 
are just a matter of changing a one register during the initialization 
and different bits the page fault reason decoding. You must of course 
rely on the DMA-mapping framework and its implementation based on 
mainline DMA-IOMMU helpers. All the code for custom iommu group(s) 
handling or extended fault management are not needed for the initial 
version.

The IOMMU driver on its own doesn't really make much sense, so you need 
the other driver/device pair which will make use of it. You have 
mentioned DPU, so you are trying to bring the display stack. Please 
check the existing Exynos DRM driver(s). They nicely use DMA-mapping 
framework and are really modular, so adding hw-specific sub-drivers for 
Exynos850 shouldn't be that hard. Don't expect that the vendor's drivers 
based on custom frameworks will work there though.

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland



From mike.leach at linaro.org  Fri Jan 21 04:40:56 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:40:56 +0000
Subject: [PATCH 1/1] coresight: Fix TRCCONFIGR.QE sysfs interface
In-Reply-To: <139e5fb6-b917-163e-751c-1ef745852529@arm.com>
References: <20220114173254.1876151-1-james.clark@arm.com>
 <20220114173254.1876151-2-james.clark@arm.com>
 <CAJ9a7VhedrLMKfXBqzD_9fFxzKTg63-9wUM38Tw6ukhmSR9aoA@mail.gmail.com>
 <139e5fb6-b917-163e-751c-1ef745852529@arm.com>
Message-ID: <CAJ9a7VhA0YLaamjddvsmiiY-6fdzjobobtxj++Bphi1wt6EPsg@mail.gmail.com>

Hi James,

On Thu, 20 Jan 2022 at 11:37, James Clark <james.clark at arm.com> wrote:
>
>
>
> On 19/01/2022 15:22, Mike Leach wrote:
> > Hi James
> >
> > On Fri, 14 Jan 2022 at 17:33, James Clark <james.clark at arm.com> wrote:
> >>
> >> It's impossible to program a valid value for TRCCONFIGR.QE
> >> when TRCIDR0.QSUPP==0b10. In that case the following is true:
> >>
> >>   Q element support is implemented, and only supports Q elements without
> >>   instruction counts. TRCCONFIGR.QE can only take the values 0b00 or 0b11.
> >>
> >> Currently the low bit of QSUPP is checked to see if the low bit of QE can
> >> be written to, but as you can see when QSUPP==0b10 the low bit is cleared
> >> making it impossible to ever write the only valid value of 0b11 to QE.
> >> 0b10 would be written instead, which is a reserved QE value even for all
> >> values of QSUPP.
> >>
> >> The fix is to allow writing the low bit of QE for any non zero value of
> >> QSUPP.
> >>
> >> This change doesn't go any further to validate if the user supplied value
> >> is valid, because none of the other parts this function do, but it does fix
> >> the case where it was impossible to ever set a valid value.
> >>
> >
> > I concur that the input is not checked as valid, However all the other
> > fields are single bit - with no invalid values - other than the cond
> > field, which controls tracing of non-branch conditionals -
> > architecturally unsupported for A profile in ETMv4/.
> >
> >
> >> Signed-off-by: James Clark <james.clark at arm.com>
> >> ---
> >>  drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> >> index a0640fa5c55b..a99bb537ea23 100644
> >> --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> >> +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> >> @@ -368,7 +368,7 @@ static ssize_t mode_store(struct device *dev,
> >>         /* start by clearing QE bits */
> >>         config->cfg &= ~(BIT(13) | BIT(14));
> >>         /* if supported, Q elements with instruction counts are enabled */
> >> -       if ((mode & BIT(0)) && (drvdata->q_support & BIT(0)))
> >> +       if ((mode & BIT(0)) && drvdata->q_support)
> >>                 config->cfg |= BIT(13);
> >
> > This can be trivially changed to
> >
> > if ((mode)  && drvdata->q_support)
> >          config->cfg |= BIT(13);
> >
> > to ensure that any input mode 2'b01, 2'b10, 2'b11 results in output
> > settings of 2'b01, 2'b11, 2'b11 respectively
> >
> > With that
> >
> > Reviewed-by: Mike Leach <mike.leach at linaro.org>
> >
>
> Thanks for the review. Can I also get your opinion about this one? At the very least
> I think the comment is not detailed enough, but I also think that case 0 should set
> BIT(0) rather than BIT(1). Or is there some edge case and it's correct?
>

Agreed - case 0 should be BIT(0)

However, now you mention it there is a corner case too...
On an ETM4.3 or later, if TRCIDR4.NUMRSPAIR == 0, then
drvdata->nr_event == 0 means zero events, otherwise drvdata->nr_event
== 0 means 1 event as implemented in the code below.

So a check on drvdata->nr_resource (which is the processed NUMRSPAIR
value wrt etm arch ) to skip setting eventctrl1 if this is 0 could be
added.

Regards

Mike

Mike
>
>         /* start by clearing all instruction event enable bits */
>         config->eventctrl1 &= ~(BIT(0) | BIT(1) | BIT(2) | BIT(3));
>         switch (drvdata->nr_event) {
>         case 0x0:
>                 /* generate Event element for event 1 */
>                 config->eventctrl1 |= val & BIT(1);
>                 break;
>         case 0x1:
>                 /* generate Event element for event 1 and 2 */
>                 config->eventctrl1 |= val & (BIT(0) | BIT(1));
>                 break;
>         case 0x2:
>                 /* generate Event element for event 1, 2 and 3 */
>                 config->eventctrl1 |= val & (BIT(0) | BIT(1) | BIT(2));
>                 break;
>         case 0x3:
>                 /* generate Event element for all 4 events */
>                 config->eventctrl1 |= val & 0xF;
>                 break;
>         default:
>                 break;
>         }
>
>
> >>         /*
> >>          * if supported, Q elements with and without instruction
> >> --
> >> 2.17.1
> >>
> >
> >



-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:42:34 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:42:34 +0000
Subject: [PATCH v2 2/6] coresight: Fail to open with return stacks if they
 are unavailable
In-Reply-To: <20220113091056.1297982-3-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-3-james.clark@arm.com>
Message-ID: <CAJ9a7ViuON11QZRhejcmCM3KOkWx-i0NZw_Kh-2m1Ps0bop2xw@mail.gmail.com>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> Maintain consistency with the other options by failing to open when they
> aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
> added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
> requested but not supported by hardware.
>
> The consequence of not doing this is that the user may not be
> aware that they are not enabling the feature as it is silently disabled.
>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 04669ecc0efa..a93c1a5fe045 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>         }
>
>         /* return stack - enable if selected and supported */
> -       if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
> -               /* bit[12], Return stack enable bit */
> -               config->cfg |= BIT(12);
> -
> +       if (attr->config & BIT(ETM_OPT_RETSTK)) {
> +               if (!drvdata->retstack) {
> +                       ret = -EINVAL;
> +                       goto out;
> +               } else {
> +                       /* bit[12], Return stack enable bit */
> +                       config->cfg |= BIT(12);
> +               }
> +       }
>         /*
>          * Set any selected configuration and preset.
>          *
> --
> 2.28.0
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:43:27 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:43:27 +0000
Subject: [PATCH v2 1/6] coresight: Add config flag to enable branch
 broadcast
In-Reply-To: <20220113091056.1297982-2-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-2-james.clark@arm.com>
Message-ID: <CAJ9a7VhYEzXFbSDvvUsH-D9T_1bTVUJW6P_TJj_W8_C1T-2vVw@mail.gmail.com>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> When enabled, all taken branch addresses are output, even if the branch
> was because of a direct branch instruction. This enables reconstruction
> of the program flow without having access to the memory image of the
> code being executed.
>
> Use bit 8 for the config option which would be the correct bit for
> programming ETMv3. Although branch broadcast can't be enabled on ETMv3
> because it's not in the define ETM3X_SUPPORTED_OPTIONS, using the
> correct bit might help prevent future collisions or allow it to be
> enabled if needed.
>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm-perf.c   |  2 ++
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 ++++++++++
>  include/linux/coresight-pmu.h                      |  2 ++
>  3 files changed, 14 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index c039b6ae206f..43bbd5dc3d3b 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -52,6 +52,7 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
>   * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config';
>   * now take them as general formats and apply on all ETMs.
>   */
> +PMU_FORMAT_ATTR(branch_broadcast, "config:"__stringify(ETM_OPT_BRANCH_BROADCAST));
>  PMU_FORMAT_ATTR(cycacc,                "config:" __stringify(ETM_OPT_CYCACC));
>  /* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
>  PMU_FORMAT_ATTR(contextid1,    "config:" __stringify(ETM_OPT_CTXTID));
> @@ -97,6 +98,7 @@ static struct attribute *etm_config_formats_attr[] = {
>         &format_attr_sinkid.attr,
>         &format_attr_preset.attr,
>         &format_attr_configid.attr,
> +       &format_attr_branch_broadcast.attr,
>         NULL,
>  };
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index bf18128cf5de..04669ecc0efa 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -692,6 +692,16 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>                 ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
>         }
>
> +       /* branch broadcast - enable if selected and supported */
> +       if (attr->config & BIT(ETM_OPT_BRANCH_BROADCAST)) {
> +               if (!drvdata->trcbb) {
> +                       ret = -EINVAL;
> +                       goto out;
> +               } else {
> +                       config->cfg |= BIT(ETM4_CFG_BIT_BB);
> +               }
> +       }
> +
>  out:
>         return ret;
>  }
> diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h
> index 4ac5c081af93..6c2fd6cc5a98 100644
> --- a/include/linux/coresight-pmu.h
> +++ b/include/linux/coresight-pmu.h
> @@ -18,6 +18,7 @@
>   * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
>   * directly use below macros as config bits.
>   */
> +#define ETM_OPT_BRANCH_BROADCAST 8
>  #define ETM_OPT_CYCACC         12
>  #define ETM_OPT_CTXTID         14
>  #define ETM_OPT_CTXTID2                15
> @@ -25,6 +26,7 @@
>  #define ETM_OPT_RETSTK         29
>
>  /* ETMv4 CONFIGR programming bits for the ETM OPTs */
> +#define ETM4_CFG_BIT_BB         3
>  #define ETM4_CFG_BIT_CYCACC    4
>  #define ETM4_CFG_BIT_CTXTID    6
>  #define ETM4_CFG_BIT_VMID      7
> --
> 2.28.0
>
Reviewed-by: Mike Leach <mike.leach at linaro.org>

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:44:37 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:44:37 +0000
Subject: [PATCH v2 3/6] perf cs-etm: Update deduction of TRCCONFIGR
 register for branch broadcast
In-Reply-To: <20220113091056.1297982-4-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-4-james.clark@arm.com>
Message-ID: <CAJ9a7ViKA_vHd8WOfoxnHrjS4Cx7R9-G28VHMK7e03c+8vZ8Yw@mail.gmail.com>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> Now that a config flag for branch broadcast has been added, take it into
> account when trying to deduce what the driver would have programmed the
> TRCCONFIGR register to.
>
> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  tools/include/linux/coresight-pmu.h | 2 ++
>  tools/perf/arch/arm/util/cs-etm.c   | 3 +++
>  2 files changed, 5 insertions(+)
>
> diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h
> index 4ac5c081af93..6c2fd6cc5a98 100644
> --- a/tools/include/linux/coresight-pmu.h
> +++ b/tools/include/linux/coresight-pmu.h
> @@ -18,6 +18,7 @@
>   * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
>   * directly use below macros as config bits.
>   */
> +#define ETM_OPT_BRANCH_BROADCAST 8
>  #define ETM_OPT_CYCACC         12
>  #define ETM_OPT_CTXTID         14
>  #define ETM_OPT_CTXTID2                15
> @@ -25,6 +26,7 @@
>  #define ETM_OPT_RETSTK         29
>
>  /* ETMv4 CONFIGR programming bits for the ETM OPTs */
> +#define ETM4_CFG_BIT_BB         3
>  #define ETM4_CFG_BIT_CYCACC    4
>  #define ETM4_CFG_BIT_CTXTID    6
>  #define ETM4_CFG_BIT_VMID      7
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 293a23bf8be3..c7ef4e9b4a3a 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -527,6 +527,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
>         if (config_opts & BIT(ETM_OPT_CTXTID2))
>                 config |= BIT(ETM4_CFG_BIT_VMID) |
>                           BIT(ETM4_CFG_BIT_VMID_OPT);
> +       if (config_opts & BIT(ETM_OPT_BRANCH_BROADCAST))
> +               config |= BIT(ETM4_CFG_BIT_BB);
> +
>         return config;
>  }
>
> --
> 2.28.0
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>
-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:47:05 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:47:05 +0000
Subject: [PATCH v2 4/6] Documentation: coresight: Turn numbered
 subsections into real subsections
In-Reply-To: <20220113091056.1297982-5-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-5-james.clark@arm.com>
Message-ID: <CAJ9a7Vj7=WPTZD_oWtXaZBUWbHpKbPti7CXMviUdd+ueKbpAMw@mail.gmail.com>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> This is to allow them to be referenced in a later commit. There was
> also a mistake where sysFS was introduced as section 2, but numbered
> as section 1. And vice versa for 'Using perf framework'. This can't
> happen with unnumbered sections.
>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  Documentation/trace/coresight/coresight.rst | 17 ++++++++++++-----
>  1 file changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
> index a15571d96cc8..db66ff45ff4c 100644
> --- a/Documentation/trace/coresight/coresight.rst
> +++ b/Documentation/trace/coresight/coresight.rst
> @@ -339,7 +339,8 @@ Preference is given to the former as using the sysFS interface
>  requires a deep understanding of the Coresight HW.  The following sections
>  provide details on using both methods.
>
> -1) Using the sysFS interface:
> +Using the sysFS interface
> +~~~~~~~~~~~~~~~~~~~~~~~~~
>
>  Before trace collection can start, a coresight sink needs to be identified.
>  There is no limit on the amount of sinks (nor sources) that can be enabled at
> @@ -446,7 +447,8 @@ wealth of possibilities that coresight provides.
>      Instruction     0       0x8026B588      E8BD8000        true    LDM      sp!,{pc}
>      Timestamp                                       Timestamp: 17107041535
>
> -2) Using perf framework:
> +Using perf framework
> +~~~~~~~~~~~~~~~~~~~~
>
>  Coresight tracers are represented using the Perf framework's Performance
>  Monitoring Unit (PMU) abstraction.  As such the perf framework takes charge of
> @@ -495,7 +497,11 @@ More information on the above and other example on how to use Coresight with
>  the perf tools can be found in the "HOWTO.md" file of the openCSD gitHub
>  repository [#third]_.
>
> -2.1) AutoFDO analysis using the perf tools:
> +Advanced perf framework usage
> +-----------------------------
> +
> +AutoFDO analysis using the perf tools
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>  perf can be used to record and analyze trace of programs.
>
> @@ -513,7 +519,8 @@ The --itrace option controls the type and frequency of synthesized events
>  Note that only 64-bit programs are currently supported - further work is
>  required to support instruction decode of 32-bit Arm programs.
>
> -2.2) Tracing PID
> +Tracing PID
> +~~~~~~~~~~~
>
>  The kernel can be built to write the PID value into the PE ContextID registers.
>  For a kernel running at EL1, the PID is stored in CONTEXTIDR_EL1.  A PE may
> @@ -547,7 +554,7 @@ wants to trace PIDs for both host and guest, the two configs "contextid1" and
>
>
>  Generating coverage files for Feedback Directed Optimization: AutoFDO
> ----------------------------------------------------------------------
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
>  'perf inject' accepts the --itrace option in which case tracing data is
>  removed and replaced with the synthesized events. e.g.
> --
> 2.28.0
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:49:50 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:49:50 +0000
Subject: [PATCH v2 5/6] Documentation: coresight: Link config options to
 existing documentation
In-Reply-To: <20220113091056.1297982-6-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-6-james.clark@arm.com>
Message-ID: <CAJ9a7VgyG-pomy0F35pXhy=vNUcUFgxnpMNPZ0pKxbnHdyemhA@mail.gmail.com>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> In order to document the newly added branch_broadcast option, create a
> table that links all of the config option formats to any existing docs.
> That way when the branch broadcast docs are expanded they are accessible
> from both places.
>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  .../coresight/coresight-etm4x-reference.rst   |  4 ++
>  Documentation/trace/coresight/coresight.rst   | 39 +++++++++++++++++++
>  2 files changed, 43 insertions(+)
>
> diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.rst b/Documentation/trace/coresight/coresight-etm4x-reference.rst
> index d25dfe86af9b..0439b4006227 100644
> --- a/Documentation/trace/coresight/coresight-etm4x-reference.rst
> +++ b/Documentation/trace/coresight/coresight-etm4x-reference.rst
> @@ -650,6 +650,7 @@ Bit assignments shown below:-
>      parameter is set this value is applied to the currently indexed
>      address range.
>
> +.. _coresight-branch-broadcast:
>
>  **bit (4):**
>      ETM_MODE_BB
> @@ -657,6 +658,7 @@ Bit assignments shown below:-
>  **description:**
>      Set to enable branch broadcast if supported in hardware [IDR0].
>
> +.. _coresight-cycle-accurate:
>
>  **bit (5):**
>      ETMv4_MODE_CYCACC
> @@ -678,6 +680,7 @@ Bit assignments shown below:-
>  **description:**
>      Set to enable virtual machine ID tracing if supported [IDR2].
>
> +.. _coresight-timestamp:
>
>  **bit (11):**
>      ETMv4_MODE_TIMESTAMP
> @@ -685,6 +688,7 @@ Bit assignments shown below:-
>  **description:**
>      Set to enable timestamp generation if supported [IDR0].
>
> +.. _coresight-return-stack:
>
>  **bit (12):**
>      ETM_MODE_RETURNSTACK
> diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst
> index db66ff45ff4c..803a224dbb0e 100644
> --- a/Documentation/trace/coresight/coresight.rst
> +++ b/Documentation/trace/coresight/coresight.rst
> @@ -585,6 +585,45 @@ sort example is from the AutoFDO tutorial (https://gcc.gnu.org/wiki/AutoFDO/Tuto
>         Bubble sorting array of 30000 elements
>         5806 ms
>
> +Config option formats
> +~~~~~~~~~~~~~~~~~~~~~
> +
> +The following strings can be provided between // on the perf command line to enable various options.
> +They are also listed in the folder /sys/bus/event_source/devices/cs_etm/format/
> +
> +.. list-table::
> +   :header-rows: 1
> +
> +   * - Option
> +     - Description
> +   * - branch_broadcast
> +     - Session local version of the system wide setting:
> +       :ref:`ETM_MODE_BB <coresight-branch-broadcast>`
> +   * - contextid
> +     - See `Tracing PID`_
> +   * - contextid1
> +     - See `Tracing PID`_
> +   * - contextid2
> +     - See `Tracing PID`_
> +   * - configid
> +     - Selection for a custom configuration. This is an implementation detail and not used directly,
> +       see :ref:`trace/coresight/coresight-config:Using Configurations in perf`
> +   * - preset
> +     - Override for parameters in a custom configuration, see
> +       :ref:`trace/coresight/coresight-config:Using Configurations in perf`
> +   * - sinkid
> +     - Hashed version of the string to select a sink, automatically set when using the @ notation.
> +       This is an internal implementation detail and is not used directly, see `Using perf
> +       framework`_.
> +   * - cycacc
> +     - Session local version of the system wide setting: :ref:`ETMv4_MODE_CYCACC
> +       <coresight-cycle-accurate>`
> +   * - retstack
> +     - Session local version of the system wide setting: :ref:`ETM_MODE_RETURNSTACK
> +       <coresight-return-stack>`
> +   * - timestamp
> +     - Session local version of the system wide setting: :ref:`ETMv4_MODE_TIMESTAMP
> +       <coresight-timestamp>`
>
>  How to use the STM module
>  -------------------------
> --
> 2.28.0
>


-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From mike.leach at linaro.org  Fri Jan 21 04:50:34 2022
From: mike.leach at linaro.org (Mike Leach)
Date: Fri, 21 Jan 2022 12:50:34 +0000
Subject: [PATCH v2 6/6] Documentation: coresight: Expand branch broadcast
 documentation
In-Reply-To: <20220113091056.1297982-7-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-7-james.clark@arm.com>
Message-ID: <CAJ9a7VihnvK6uwYri0kh_pwQu893+FrdcUNg0Y5iW7Euh3YwuA@mail.gmail.com>

On Thu, 13 Jan 2022 at 09:11, James Clark <james.clark at arm.com> wrote:
>
> Now that there is a way of enabling branch broadcast via perf, mention
> the possible use cases and known limitations.
>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>  .../trace/coresight/coresight-etm4x-reference.rst      | 10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/trace/coresight/coresight-etm4x-reference.rst b/Documentation/trace/coresight/coresight-etm4x-reference.rst
> index 0439b4006227..ec336575919c 100644
> --- a/Documentation/trace/coresight/coresight-etm4x-reference.rst
> +++ b/Documentation/trace/coresight/coresight-etm4x-reference.rst
> @@ -656,7 +656,15 @@ Bit assignments shown below:-
>      ETM_MODE_BB
>
>  **description:**
> -    Set to enable branch broadcast if supported in hardware [IDR0].
> +    Set to enable branch broadcast if supported in hardware [IDR0]. The primary use for this feature
> +    is when code is patched dynamically at run time and the full program flow may not be able to be
> +    reconstructed using only conditional branches.
> +
> +    Choosing this option will result in a significant increase in the amount of trace generated -
> +    possible danger of overflows, or fewer instructions covered. Note, that this option also
> +    overrides any setting of :ref:`ETM_MODE_RETURNSTACK <coresight-return-stack>`, so where a branch
> +    broadcast range overlaps a return stack range, return stacks will not be available for that
> +    range.
>
>  .. _coresight-cycle-accurate:
>
> --
> 2.28.0
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>
-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK


From marex at denx.de  Fri Jan 21 05:08:09 2022
From: marex at denx.de (Marek Vasut)
Date: Fri, 21 Jan 2022 14:08:09 +0100
Subject: [PATCH 1/1] drm: mxsfb: Use dev_err_probe() helper
In-Reply-To: <20220121095644.329256-1-alexander.stein@ew.tq-group.com>
References: <20220121095644.329256-1-alexander.stein@ew.tq-group.com>
Message-ID: <29ee478e-b754-dfbc-f2c6-f522ed597fd5@denx.de>

On 1/21/22 10:56, Alexander Stein wrote:
> Use the dev_err_probe() helper, instead of open-coding the same
> operation. This also adds a nice hint in
> /sys/kernel/debug/devices_deferred.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Reviewed-by: Marek Vasut <marex at denx.de>

Thanks


From alexander.stein at ew.tq-group.com  Fri Jan 21 05:12:38 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 21 Jan 2022 14:12:38 +0100
Subject: [PATCH 1/1] drm: mxsfb: Fix NULL pointer dereference
Message-ID: <20220121131238.507567-1-alexander.stein@ew.tq-group.com>

Do not deference the NULL pointer if the bridge does not return a
bridge state. Assume a fixed format instead.

Fixes: commit b776b0f00f24 ("drm: mxsfb: Use bus_format from the nearest bridge if present")
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
This can happen if a "ti,sn75lvds83", "lvds-encoder" bridge is attached
to it. atomic_get_input_bus_fmts is only implemented for the
lvds-decoder case.

 drivers/gpu/drm/mxsfb/mxsfb_kms.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
index 0655582ae8ed..4cfb6c001679 100644
--- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
+++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
@@ -361,7 +361,11 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc,
 		bridge_state =
 			drm_atomic_get_new_bridge_state(state,
 							mxsfb->bridge);
-		bus_format = bridge_state->input_bus_cfg.format;
+		if (!bridge_state)
+			bus_format = MEDIA_BUS_FMT_FIXED;
+		else
+			bus_format = bridge_state->input_bus_cfg.format;
+
 		if (bus_format == MEDIA_BUS_FMT_FIXED) {
 			dev_warn_once(drm->dev,
 				      "Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"
-- 
2.25.1



From marex at denx.de  Fri Jan 21 05:12:51 2022
From: marex at denx.de (Marek Vasut)
Date: Fri, 21 Jan 2022 14:12:51 +0100
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <2752700e-83ec-d844-e99e-73be8ff87ee9@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220120220356.79C3CC340E0@smtp.kernel.org>
 <2752700e-83ec-d844-e99e-73be8ff87ee9@denx.de>
Message-ID: <6bf770a8-9a87-9806-d1a1-9564e018817c@denx.de>

On 1/20/22 23:39, Marek Vasut wrote:
> On 1/20/22 23:03, Stephen Boyd wrote:
>> Quoting Marek Vasut (2022-01-18 12:29:54)
>>> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
>>> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
>>> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
>>> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
>>> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
>>> in use, ETHCKEN gate can be turned off. Current driver does not permit
>>> that, fix it.
>>>
>>> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
>>> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
>>> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
>>> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
>>> ETHPTP_K remain functional as before.
>>>
>>> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>>> ???? Figure 83. Peripheral clock distribution for Ethernet
>>>      
>>> https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf 
>>>
>>>
>>> Signed-off-by: Marek Vasut <marex at denx.de>
>>> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
>>> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
>>> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
>>> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
>>> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
>>> Cc: Stephen Boyd <sboyd at kernel.org>
>>> Cc: linux-clk at vger.kernel.org
>>> Cc: linux-stm32 at st-md-mailman.stormreply.com
>>> To: linux-arm-kernel at lists.infradead.org
>>> ---
>>
>> Any cover letter?
> 
> If there is a need for V2, I will send one. Admittedly, I forgot one here.
> 
>> What is the merge strategy of this patch series?
> 
> Clock bits 1/5 and 2/5 can go through clock tree, DT bits through Alex's 
> ST tree.
> 
>> Do I need to ack the patches?
> 
> I am waiting for AB/RB from ST, then they can be merged.
> 
> If you want to review the first two patches, sure, the top half of 2/5 
> is probably the most interesting part, based on your suggestion from 
> almost a year ago. The rest are clock controller hardware details.

So if you want to pick 1/5 and 2/5 via clock tree with A-B from Gabriel, 
please do.


From marex at denx.de  Fri Jan 21 05:14:01 2022
From: marex at denx.de (Marek Vasut)
Date: Fri, 21 Jan 2022 14:14:01 +0100
Subject: [PATCH 1/1] drm: mxsfb: Fix NULL pointer dereference
In-Reply-To: <20220121131238.507567-1-alexander.stein@ew.tq-group.com>
References: <20220121131238.507567-1-alexander.stein@ew.tq-group.com>
Message-ID: <4d3654b5-9a87-1c02-f2d9-d0974e628c20@denx.de>

On 1/21/22 14:12, Alexander Stein wrote:
> Do not deference the NULL pointer if the bridge does not return a
> bridge state. Assume a fixed format instead.
> 
> Fixes: commit b776b0f00f24 ("drm: mxsfb: Use bus_format from the nearest bridge if present")
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
> This can happen if a "ti,sn75lvds83", "lvds-encoder" bridge is attached
> to it. atomic_get_input_bus_fmts is only implemented for the
> lvds-decoder case.
> 
>   drivers/gpu/drm/mxsfb/mxsfb_kms.c | 6 +++++-
>   1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> index 0655582ae8ed..4cfb6c001679 100644
> --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> @@ -361,7 +361,11 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc,
>   		bridge_state =
>   			drm_atomic_get_new_bridge_state(state,
>   							mxsfb->bridge);
> -		bus_format = bridge_state->input_bus_cfg.format;
> +		if (!bridge_state)
> +			bus_format = MEDIA_BUS_FMT_FIXED;
> +		else
> +			bus_format = bridge_state->input_bus_cfg.format;
> +
>   		if (bus_format == MEDIA_BUS_FMT_FIXED) {
>   			dev_warn_once(drm->dev,
>   				      "Bridge does not provide bus format, assuming MEDIA_BUS_FMT_RGB888_1X24.\n"


Shouldn't this be fixed on the bridge driver side instead ?

Which bridge driver do you use ?


From eugen.hristev at microchip.com  Fri Jan 21 05:14:05 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:05 +0200
Subject: [PATCH v4 00/11] media: atmel: atmel-isc: implement media controller
Message-ID: <20220121131416.603972-1-eugen.hristev@microchip.com>


This series is the v4 series that attempts to support media controller in the
atmel ISC and XISC drivers.
The CSI2DC driver was accepted thus removed from the patch series, together with
other patches.

Important note: this series applies on top of current media_staging tree, as it
relies on previous patches in the series which were accepted.

Changes in v4:
-> as reviewed by Hans, added new patch to remove the 'stop' variable and reworked
one patch that was using it
-> as reviewed by Jacopo, reworked some parts of the media controller implementation

Thanks to everyone who reviewed my work !

Eugen


Previous cover letter from v3:

This series is the v3 of the series that attempts to support media controller
in the atmel ISC and XISC drivers.
This series also includes the csi2dc driver which was previously sent in a
separate series:
https://www.spinics.net/lists/linux-media/msg181042.html
https://www.spinics.net/lists/linux-media/msg181044.html
The driver now addresses comments received in latest v5 series from last year.

The series includes some minor changes and fixes that improve the isc common
code base, like removing the enum frameintervals VIDIOC, fixing bytesperline
for planar formats, etc.

Many thanks to folks from libcamera who helped a lot with understanding
how a media controller driver should behave.

Feedback is welcome !

Changes in v3:
- change in bindings, small fixes in csi2dc driver and conversion to mc
for the isc-base.
- removed some MAINTAINERS patches and used patterns in MAINTAINERS

Changes in v2:
- integrated many changes suggested by Jacopo in the review of the v1 series.
- add a few new patches


Eugen Hristev (11):
  media: atmel: atmel-isc: replace 'stop' variable with vb2 calls
  media: atmel: atmel-isc-base: use streaming status when queueing
    buffers
  media: atmel: atmel-isc: implement media controller
  media: atmel: atmel-sama5d2-isc: fix wrong mask in YUYV format check
  media: atmel: atmel-isc-base: use mutex to lock awb workqueue from
    streaming
  media: atmel: atmel-isc: compact the controller formats list
  media: atmel: atmel-isc: change format propagation to subdev into only
    verification
  dt-bindings: media: microchip,xisc: add bus-width of 14
  ARM: dts: at91: sama7g5: add nodes for video capture
  ARM: configs: at91: sama7: add xisc and csi2dc
  ARM: multi_v7_defconfig: add atmel video pipeline modules

 .../bindings/media/microchip,xisc.yaml        |   2 +-
 arch/arm/boot/dts/sama7g5.dtsi                |  49 ++
 arch/arm/configs/multi_v7_defconfig           |   3 +
 arch/arm/configs/sama7_defconfig              |   2 +
 drivers/media/platform/atmel/Makefile         |   2 +-
 drivers/media/platform/atmel/atmel-isc-base.c | 455 +++++++++++-------
 .../media/platform/atmel/atmel-isc-scaler.c   | 250 ++++++++++
 drivers/media/platform/atmel/atmel-isc.h      |  43 +-
 .../media/platform/atmel/atmel-sama5d2-isc.c  |  67 ++-
 .../media/platform/atmel/atmel-sama7g5-isc.c  |  72 ++-
 10 files changed, 694 insertions(+), 251 deletions(-)
 create mode 100644 drivers/media/platform/atmel/atmel-isc-scaler.c

-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:06 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:06 +0200
Subject: [PATCH v4 01/11] media: atmel: atmel-isc: replace 'stop' variable
 with vb2 calls
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-2-eugen.hristev@microchip.com>

The stop variable is redundant as the state of the streaming can be obtained
by calling vb2_start_streaming_called(&isc->vb2_vidq) or by calling
vb2_is_busy(&isc->vb2_vidq).
Thus, remove the stop variable completely.

Suggested-by: Hans Verkuil <hverkuil at xs4all.nl>
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
Changes in v4:
- new patch

 drivers/media/platform/atmel/atmel-isc-base.c | 12 +++++-------
 drivers/media/platform/atmel/atmel-isc.h      |  2 --
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
index db15770d5b88..9c62d0ae7887 100644
--- a/drivers/media/platform/atmel/atmel-isc-base.c
+++ b/drivers/media/platform/atmel/atmel-isc-base.c
@@ -362,7 +362,6 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
 	spin_lock_irqsave(&isc->dma_queue_lock, flags);
 
 	isc->sequence = 0;
-	isc->stop = false;
 	reinit_completion(&isc->comp);
 
 	isc->cur_frm = list_first_entry(&isc->dma_queue,
@@ -403,8 +402,6 @@ static void isc_stop_streaming(struct vb2_queue *vq)
 
 	v4l2_ctrl_activate(isc->do_wb_ctrl, false);
 
-	isc->stop = true;
-
 	/* Wait until the end of the current frame */
 	if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ))
 		v4l2_err(&isc->v4l2_dev,
@@ -1029,7 +1026,7 @@ static int isc_s_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct isc_device *isc = video_drvdata(file);
 
-	if (vb2_is_streaming(&isc->vb2_vidq))
+	if (vb2_is_busy(&isc->vb2_vidq))
 		return -EBUSY;
 
 	return isc_set_fmt(isc, f);
@@ -1236,7 +1233,8 @@ irqreturn_t isc_interrupt(int irq, void *dev_id)
 			isc->cur_frm = NULL;
 		}
 
-		if (!list_empty(&isc->dma_queue) && !isc->stop) {
+		if (!list_empty(&isc->dma_queue) &&
+		    vb2_start_streaming_called(&isc->vb2_vidq)) {
 			isc->cur_frm = list_first_entry(&isc->dma_queue,
 						     struct isc_buffer, list);
 			list_del(&isc->cur_frm->list);
@@ -1244,7 +1242,7 @@ irqreturn_t isc_interrupt(int irq, void *dev_id)
 			isc_start_dma(isc);
 		}
 
-		if (isc->stop)
+		if (!vb2_start_streaming_called(&isc->vb2_vidq))
 			complete(&isc->comp);
 
 		ret = IRQ_HANDLED;
@@ -1398,7 +1396,7 @@ static void isc_awb_work(struct work_struct *w)
 	int ret;
 
 	/* streaming is not active anymore */
-	if (isc->stop)
+	if (!vb2_start_streaming_called(&isc->vb2_vidq))
 		return;
 
 	if (ctrls->hist_stat != HIST_ENABLED)
diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
index 07fa6dbf8460..5fbf52a9080b 100644
--- a/drivers/media/platform/atmel/atmel-isc.h
+++ b/drivers/media/platform/atmel/atmel-isc.h
@@ -201,7 +201,6 @@ struct isc_reg_offsets {
  * @dma_queue:		the queue for dma buffers
  * @cur_frm:		current isc frame/buffer
  * @sequence:		current frame number
- * @stop:		true if isc is not streaming, false if streaming
  * @comp:		completion reference that signals frame completion
  *
  * @fmt:		current v42l format
@@ -276,7 +275,6 @@ struct isc_device {
 	struct list_head	dma_queue;
 	struct isc_buffer	*cur_frm;
 	unsigned int		sequence;
-	bool			stop;
 	struct completion	comp;
 
 	struct v4l2_format	fmt;
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:07 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:07 +0200
Subject: [PATCH v4 02/11] media: atmel: atmel-isc-base: use streaming status
 when queueing buffers
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-3-eugen.hristev@microchip.com>

During experiments with libcamera, it looks like vb2_is_streaming returns
true before our start streaming is called.
Order of operations is streamon -> queue -> start_streaming
ISC would have started the DMA immediately when a buffer is being added
to the vbqueue if the queue is streaming.
It is more safe to start the DMA after the start streaming of the driver is
called.
Thus, even if vb2queue is streaming, add the buffer to the dma queue of the
driver instead of actually starting the DMA process, if the start streaming
has not been called yet.
Tho achieve this, we have to use vb2_start_streaming_called instead of
vb2_is_streaming.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
Changes in v4:
- changed to using vb2_start_streaming_called instead of stop variable

 drivers/media/platform/atmel/atmel-isc-base.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
index 9c62d0ae7887..6b0005987a17 100644
--- a/drivers/media/platform/atmel/atmel-isc-base.c
+++ b/drivers/media/platform/atmel/atmel-isc-base.c
@@ -439,7 +439,7 @@ static void isc_buffer_queue(struct vb2_buffer *vb)
 
 	spin_lock_irqsave(&isc->dma_queue_lock, flags);
 	if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
-		vb2_is_streaming(vb->vb2_queue)) {
+		vb2_start_streaming_called(vb->vb2_queue)) {
 		isc->cur_frm = buf;
 		isc_start_dma(isc);
 	} else
@@ -1532,7 +1532,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
 
 		isc_update_awb_ctrls(isc);
 
-		if (vb2_is_streaming(&isc->vb2_vidq)) {
+		if (vb2_start_streaming_called(&isc->vb2_vidq)) {
 			/*
 			 * If we are streaming, we can update profile to
 			 * have the new settings in place.
@@ -1549,7 +1549,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
 
 		/* if we have autowhitebalance on, start histogram procedure */
 		if (ctrls->awb == ISC_WB_AUTO &&
-		    vb2_is_streaming(&isc->vb2_vidq) &&
+		    vb2_start_streaming_called(&isc->vb2_vidq) &&
 		    ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
 			isc_set_histogram(isc, true);
 
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:08 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:08 +0200
Subject: [PATCH v4 03/11] media: atmel: atmel-isc: implement media controller
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-4-eugen.hristev@microchip.com>

Implement the support for media-controller.
This means that the capabilities of the driver have changed and now
it also advertises the IO_MC .
The driver will register it's media device, and add the video entity to this
media device. The subdevices are registered to the same media device.
The ISC will have a base entity which is auto-detected as atmel_isc_base.
It will also register a subdevice that allows cropping of the incoming frame
to the maximum frame size supported by the ISC.
The ISC will create a link between the subdevice that is asynchronously
registered and the atmel_isc_scaler entity.
Then, the atmel_isc_scaler and atmel_isc_base are connected through another
link.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
Changes in v4:
As suggested by Jacopo:
- renamed atmel_isc_mc to atmel_isc_scaler.c
- moved init_mc/clean_mc to isc_base file

Changes in v2:
- implement try formats

 drivers/media/platform/atmel/Makefile         |   2 +-
 drivers/media/platform/atmel/atmel-isc-base.c |  73 +++++-
 .../media/platform/atmel/atmel-isc-scaler.c   | 245 ++++++++++++++++++
 drivers/media/platform/atmel/atmel-isc.h      |  37 +++
 .../media/platform/atmel/atmel-sama5d2-isc.c  |  14 +-
 .../media/platform/atmel/atmel-sama7g5-isc.c  |  12 +-
 6 files changed, 375 insertions(+), 8 deletions(-)
 create mode 100644 drivers/media/platform/atmel/atmel-isc-scaler.c

diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile
index 794e8f739287..f02d03df89d6 100644
--- a/drivers/media/platform/atmel/Makefile
+++ b/drivers/media/platform/atmel/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 atmel-isc-objs = atmel-sama5d2-isc.o
 atmel-xisc-objs = atmel-sama7g5-isc.o
-atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o
+atmel-isc-common-objs = atmel-isc-base.o atmel-isc-clk.o atmel-isc-scaler.o
 
 obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o
 obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-common.o
diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
index 6b0005987a17..6b482270eb93 100644
--- a/drivers/media/platform/atmel/atmel-isc-base.c
+++ b/drivers/media/platform/atmel/atmel-isc-base.c
@@ -1710,6 +1710,7 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
 					      struct isc_device, v4l2_dev);
 	struct isc_subdev_entity *subdev_entity =
 		container_of(notifier, struct isc_subdev_entity, notifier);
+	int pad;
 
 	if (video_is_registered(&isc->video_dev)) {
 		v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n");
@@ -1718,6 +1719,16 @@ static int isc_async_bound(struct v4l2_async_notifier *notifier,
 
 	subdev_entity->sd = subdev;
 
+	pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
+					  MEDIA_PAD_FL_SOURCE);
+	if (pad < 0) {
+		v4l2_err(&isc->v4l2_dev, "failed to find pad for %s\n",
+			 subdev->name);
+		return pad;
+	}
+
+	isc->remote_pad = pad;
+
 	return 0;
 }
 
@@ -1732,8 +1743,8 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
 	v4l2_ctrl_handler_free(&isc->ctrls.handler);
 }
 
-static struct isc_format *find_format_by_code(struct isc_device *isc,
-					      unsigned int code, int *index)
+struct isc_format *isc_find_format_by_code(struct isc_device *isc,
+					   unsigned int code, int *index)
 {
 	struct isc_format *fmt = &isc->formats_list[0];
 	unsigned int i;
@@ -1749,6 +1760,7 @@ static struct isc_format *find_format_by_code(struct isc_device *isc,
 
 	return NULL;
 }
+EXPORT_SYMBOL_GPL(isc_find_format_by_code);
 
 static int isc_formats_init(struct isc_device *isc)
 {
@@ -1765,7 +1777,7 @@ static int isc_formats_init(struct isc_device *isc)
 	       NULL, &mbus_code)) {
 		mbus_code.index++;
 
-		fmt = find_format_by_code(isc, mbus_code.code, &i);
+		fmt = isc_find_format_by_code(isc, mbus_code.code, &i);
 		if (!fmt) {
 			v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n",
 				  mbus_code.code);
@@ -1891,7 +1903,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
 	vdev->queue		= q;
 	vdev->lock		= &isc->lock;
 	vdev->ctrl_handler	= &isc->ctrls.handler;
-	vdev->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE;
+	vdev->device_caps	= V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
+				  V4L2_CAP_IO_MC;
 	video_set_drvdata(vdev, isc);
 
 	ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
@@ -1901,8 +1914,18 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
 		goto isc_async_complete_err;
 	}
 
+	ret = isc_scaler_link(isc);
+	if (ret < 0)
+		goto isc_async_complete_unregister_device;
+
+	ret = media_device_register(&isc->mdev);
+	if (ret < 0)
+		goto isc_async_complete_unregister_device;
 	return 0;
 
+isc_async_complete_unregister_device:
+	video_unregister_device(vdev);
+
 isc_async_complete_err:
 	mutex_destroy(&isc->lock);
 	return ret;
@@ -1969,6 +1992,48 @@ int isc_pipeline_init(struct isc_device *isc)
 }
 EXPORT_SYMBOL_GPL(isc_pipeline_init);
 
+int isc_mc_init(struct isc_device *isc, u32 ver)
+{
+	const struct of_device_id *match;
+	int ret;
+
+	isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
+	isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
+	isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+
+	ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
+				     isc->pads);
+	if (ret < 0) {
+		dev_err(isc->dev, "media entity init failed\n");
+		return ret;
+	}
+
+	isc->mdev.dev = isc->dev;
+
+	match = of_match_node(isc->dev->driver->of_match_table,
+			      isc->dev->of_node);
+
+	strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
+		sizeof(isc->mdev.driver_name));
+	strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
+	snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
+		 isc->v4l2_dev.name);
+	isc->mdev.hw_revision = ver;
+
+	media_device_init(&isc->mdev);
+
+	isc->v4l2_dev.mdev = &isc->mdev;
+
+	return isc_scaler_init(isc);
+}
+EXPORT_SYMBOL_GPL(isc_mc_init);
+
+void isc_mc_cleanup(struct isc_device *isc)
+{
+	media_entity_cleanup(&isc->video_dev.entity);
+}
+EXPORT_SYMBOL_GPL(isc_mc_cleanup);
+
 /* regmap configuration */
 #define ATMEL_ISC_REG_MAX    0xd5c
 const struct regmap_config isc_regmap_config = {
diff --git a/drivers/media/platform/atmel/atmel-isc-scaler.c b/drivers/media/platform/atmel/atmel-isc-scaler.c
new file mode 100644
index 000000000000..ec95c9665883
--- /dev/null
+++ b/drivers/media/platform/atmel/atmel-isc-scaler.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Microchip Image Sensor Controller (ISC) Scaler entity support
+ *
+ * Copyright (C) 2021 Microchip Technology, Inc.
+ *
+ * Author: Eugen Hristev <eugen.hristev at microchip.com>
+ *
+ */
+
+#include <media/media-device.h>
+#include <media/media-entity.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "atmel-isc-regs.h"
+#include "atmel-isc.h"
+
+static int isc_scaler_get_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *sd_state,
+			      struct v4l2_subdev_format *format)
+{
+	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
+	struct v4l2_mbus_framefmt *v4l2_try_fmt;
+
+	if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
+		v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+							  format->pad);
+		format->format = *v4l2_try_fmt;
+
+		return 0;
+	}
+
+	format->format = isc->scaler_format;
+
+	return 0;
+}
+
+static int isc_scaler_set_fmt(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *sd_state,
+			      struct v4l2_subdev_format *req_fmt)
+{
+	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
+	struct v4l2_mbus_framefmt *v4l2_try_fmt;
+	struct isc_format *fmt;
+	unsigned int i;
+
+	if (req_fmt->pad == ISC_SCALER_PAD_SOURCE)
+		v4l_bound_align_image
+			(&req_fmt->format.width, 16, isc->max_width, 0,
+			 &req_fmt->format.height, 16, isc->max_height, 0, 0);
+	else
+		v4l_bound_align_image
+			(&req_fmt->format.width, 16, 10000, 0,
+			 &req_fmt->format.height, 16, 10000, 0, 0);
+
+	req_fmt->format.colorspace = V4L2_COLORSPACE_SRGB;
+	req_fmt->format.field = V4L2_FIELD_NONE;
+	req_fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	req_fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT;
+	req_fmt->format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
+	fmt = isc_find_format_by_code(isc, req_fmt->format.code, &i);
+
+	if (!fmt)
+		fmt = &isc->formats_list[0];
+
+	req_fmt->format.code = fmt->mbus_code;
+
+	if (req_fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		v4l2_try_fmt = v4l2_subdev_get_try_format(sd, sd_state,
+							  req_fmt->pad);
+		*v4l2_try_fmt = req_fmt->format;
+		/* Trying on the pad sink makes the source sink change too */
+		if (req_fmt->pad == ISC_SCALER_PAD_SINK) {
+			v4l2_try_fmt =
+				v4l2_subdev_get_try_format(sd, sd_state,
+							   ISC_SCALER_PAD_SOURCE);
+			*v4l2_try_fmt = req_fmt->format;
+
+			v4l_bound_align_image(&v4l2_try_fmt->width,
+					      16, isc->max_width, 0,
+					      &v4l2_try_fmt->height,
+					      16, isc->max_height, 0, 0);
+		}
+		/* if we are just trying, we are done */
+		return 0;
+	}
+
+	isc->scaler_format = req_fmt->format;
+
+	return 0;
+}
+
+static int isc_scaler_enum_mbus_code(struct v4l2_subdev *sd,
+				     struct v4l2_subdev_state *sd_state,
+				     struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
+	int supported_index = 0;
+	int i;
+
+	for (i = 0; i < isc->formats_list_size; i++) {
+		if (!isc->formats_list[i].sd_support)
+			continue;
+		if (supported_index == code->index) {
+			code->code = isc->formats_list[i].mbus_code;
+			return 0;
+		}
+		supported_index++;
+	}
+
+	return -EINVAL;
+}
+
+static int isc_scaler_g_sel(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_state *sd_state,
+			    struct v4l2_subdev_selection *sel)
+{
+	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
+
+	if (sel->pad == ISC_SCALER_PAD_SOURCE)
+		return -EINVAL;
+
+	if (sel->target != V4L2_SEL_TGT_CROP_BOUNDS &&
+	    sel->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	sel->r.height = isc->max_height;
+	sel->r.width = isc->max_width;
+
+	sel->r.left = 0;
+	sel->r.top = 0;
+
+	return 0;
+}
+
+static int isc_scaler_init_cfg(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *sd_state)
+{
+	struct v4l2_mbus_framefmt *v4l2_try_fmt =
+		v4l2_subdev_get_try_format(sd, sd_state, 0);
+	struct isc_device *isc = container_of(sd, struct isc_device, scaler_sd);
+
+	*v4l2_try_fmt = isc->scaler_format;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
+	.enum_mbus_code = isc_scaler_enum_mbus_code,
+	.set_fmt = isc_scaler_set_fmt,
+	.get_fmt = isc_scaler_get_fmt,
+	.get_selection = isc_scaler_g_sel,
+	.init_cfg = isc_scaler_init_cfg,
+};
+
+static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
+	.pad = &isc_scaler_pad_ops,
+};
+
+int isc_scaler_init(struct isc_device *isc)
+{
+	int ret;
+
+	v4l2_subdev_init(&isc->scaler_sd, &xisc_scaler_subdev_ops);
+
+	isc->scaler_sd.owner = THIS_MODULE;
+	isc->scaler_sd.dev = isc->dev;
+	snprintf(isc->scaler_sd.name, sizeof(isc->scaler_sd.name),
+		 "atmel_isc_scaler");
+
+	isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+	isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+	isc->scaler_format.height = isc->max_height;
+	isc->scaler_format.width = isc->max_width;
+	isc->scaler_format.code = isc->formats_list[0].mbus_code;
+	isc->scaler_format.colorspace = V4L2_COLORSPACE_SRGB;
+	isc->scaler_format.field = V4L2_FIELD_NONE;
+	isc->scaler_format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	isc->scaler_format.quantization = V4L2_QUANTIZATION_DEFAULT;
+	isc->scaler_format.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+
+	ret = media_entity_pads_init(&isc->scaler_sd.entity,
+				     ISC_SCALER_PADS_NUM,
+				     isc->scaler_pads);
+	if (ret < 0) {
+		dev_err(isc->dev, "scaler sd media entity init failed\n");
+		return ret;
+	}
+	ret = v4l2_device_register_subdev(&isc->v4l2_dev, &isc->scaler_sd);
+	if (ret < 0) {
+		dev_err(isc->dev, "scaler sd failed to register subdev\n");
+		return ret;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(isc_scaler_init);
+
+int isc_scaler_link(struct isc_device *isc)
+{
+	int ret;
+
+	ret = media_create_pad_link(&isc->current_subdev->sd->entity,
+				    isc->remote_pad, &isc->scaler_sd.entity,
+				    ISC_SCALER_PAD_SINK,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+
+	if (ret < 0) {
+		v4l2_err(&isc->v4l2_dev,
+			 "Failed to create pad link: %s to %s\n",
+			 isc->current_subdev->sd->entity.name,
+			 isc->scaler_sd.entity.name);
+		return ret;
+	}
+
+	dev_dbg(isc->dev, "link with %s pad: %d\n",
+		isc->current_subdev->sd->name, isc->remote_pad);
+
+	ret = media_create_pad_link(&isc->scaler_sd.entity,
+				    ISC_SCALER_PAD_SOURCE,
+				    &isc->video_dev.entity, ISC_PAD_SINK,
+				    MEDIA_LNK_FL_ENABLED |
+				    MEDIA_LNK_FL_IMMUTABLE);
+
+	if (ret < 0) {
+		v4l2_err(&isc->v4l2_dev,
+			 "Failed to create pad link: %s to %s\n",
+			 isc->scaler_sd.entity.name,
+			 isc->video_dev.entity.name);
+		return ret;
+	}
+
+	dev_dbg(isc->dev, "link with %s pad: %d\n", isc->scaler_sd.name,
+		ISC_SCALER_PAD_SOURCE);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(isc_scaler_link);
+
diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
index 5fbf52a9080b..c9234c90ae58 100644
--- a/drivers/media/platform/atmel/atmel-isc.h
+++ b/drivers/media/platform/atmel/atmel-isc.h
@@ -183,6 +183,17 @@ struct isc_reg_offsets {
 	u32 his_entry;
 };
 
+enum isc_mc_pads {
+	ISC_PAD_SINK	= 0,
+	ISC_PADS_NUM	= 1,
+};
+
+enum isc_scaler_pads {
+	ISC_SCALER_PAD_SINK	= 0,
+	ISC_SCALER_PAD_SOURCE	= 1,
+	ISC_SCALER_PADS_NUM	= 2,
+};
+
 /*
  * struct isc_device - ISC device driver data/config struct
  * @regmap:		Register map
@@ -257,6 +268,12 @@ struct isc_reg_offsets {
  *			be used as an input to the controller
  * @controller_formats_size:	size of controller_formats array
  * @formats_list_size:	size of formats_list array
+ * @pads:		media controller pads for isc video entity
+ * @mdev:		media device that is registered by the isc
+ * @remote_pad:		remote pad on the connected subdevice
+ * @scaler_sd:		subdevice for the scaler that isc registers
+ * @scaler_pads:	media controller pads for the scaler subdevice
+ * @scaler_format:	current format for the scaler subdevice
  */
 struct isc_device {
 	struct regmap		*regmap;
@@ -344,6 +361,19 @@ struct isc_device {
 	struct isc_format		*formats_list;
 	u32				controller_formats_size;
 	u32				formats_list_size;
+
+	struct {
+		struct media_pad		pads[ISC_PADS_NUM];
+		struct media_device		mdev;
+
+		u32				remote_pad;
+	};
+
+	struct {
+		struct v4l2_subdev		scaler_sd;
+		struct media_pad		scaler_pads[ISC_SCALER_PADS_NUM];
+		struct v4l2_mbus_framefmt	scaler_format;
+	};
 };
 
 extern const struct regmap_config isc_regmap_config;
@@ -355,4 +385,11 @@ int isc_clk_init(struct isc_device *isc);
 void isc_subdev_cleanup(struct isc_device *isc);
 void isc_clk_cleanup(struct isc_device *isc);
 
+int isc_scaler_link(struct isc_device *isc);
+int isc_scaler_init(struct isc_device *isc);
+int isc_mc_init(struct isc_device *isc, u32 ver);
+void isc_mc_cleanup(struct isc_device *isc);
+
+struct isc_format *isc_find_format_by_code(struct isc_device *isc,
+					   unsigned int code, int *index);
 #endif
diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index c5b9563e36cb..c244682ea22f 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -553,6 +553,12 @@ static int atmel_isc_probe(struct platform_device *pdev)
 			break;
 	}
 
+	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
+
+	ret = isc_mc_init(isc, ver);
+	if (ret < 0)
+		goto isc_probe_mc_init_err;
+
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	pm_request_idle(dev);
@@ -562,7 +568,7 @@ static int atmel_isc_probe(struct platform_device *pdev)
 	ret = clk_prepare_enable(isc->ispck);
 	if (ret) {
 		dev_err(dev, "failed to enable ispck: %d\n", ret);
-		goto cleanup_subdev;
+		goto isc_probe_mc_init_err;
 	}
 
 	/* ispck should be greater or equal to hclock */
@@ -572,7 +578,6 @@ static int atmel_isc_probe(struct platform_device *pdev)
 		goto unprepare_clk;
 	}
 
-	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
 	dev_info(dev, "Microchip ISC version %x\n", ver);
 
 	return 0;
@@ -580,6 +585,9 @@ static int atmel_isc_probe(struct platform_device *pdev)
 unprepare_clk:
 	clk_disable_unprepare(isc->ispck);
 
+isc_probe_mc_init_err:
+	isc_mc_cleanup(isc);
+
 cleanup_subdev:
 	isc_subdev_cleanup(isc);
 
@@ -600,6 +608,8 @@ static int atmel_isc_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
+	isc_mc_cleanup(isc);
+
 	isc_subdev_cleanup(isc);
 
 	v4l2_device_unregister(&isc->v4l2_dev);
diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
index 07a80b08bc54..9dc75eed0098 100644
--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
@@ -547,15 +547,23 @@ static int microchip_xisc_probe(struct platform_device *pdev)
 			break;
 	}
 
+	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
+
+	ret = isc_mc_init(isc, ver);
+	if (ret < 0)
+		goto isc_probe_mc_init_err;
+
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	pm_request_idle(dev);
 
-	regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver);
 	dev_info(dev, "Microchip XISC version %x\n", ver);
 
 	return 0;
 
+isc_probe_mc_init_err:
+	isc_mc_cleanup(isc);
+
 cleanup_subdev:
 	isc_subdev_cleanup(isc);
 
@@ -576,6 +584,8 @@ static int microchip_xisc_remove(struct platform_device *pdev)
 
 	pm_runtime_disable(&pdev->dev);
 
+	isc_mc_cleanup(isc);
+
 	isc_subdev_cleanup(isc);
 
 	v4l2_device_unregister(&isc->v4l2_dev);
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:09 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:09 +0200
Subject: [PATCH v4 04/11] media: atmel: atmel-sama5d2-isc: fix wrong mask in
 YUYV format check
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-5-eugen.hristev@microchip.com>

While this does not happen in production, this check should be done
versus the mask, as checking with the YCYC value may not include
some bits that may be set.
Is it correct and safe to check the whole mask.

Fixes: 123aaf816b95 ("media: atmel: atmel-sama5d2-isc: fix YUYV format")
Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/media/platform/atmel/atmel-sama5d2-isc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index c244682ea22f..025c3e8a7e95 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -291,7 +291,7 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc)
 	 * Thus, if the YCYC mode is selected, replace it with the
 	 * sama5d2-compliant mode which is YYCC .
 	 */
-	if ((rlp_mode & ISC_RLP_CFG_MODE_YCYC) == ISC_RLP_CFG_MODE_YCYC) {
+	if ((rlp_mode & ISC_RLP_CFG_MODE_MASK) == ISC_RLP_CFG_MODE_YCYC) {
 		rlp_mode &= ~ISC_RLP_CFG_MODE_MASK;
 		rlp_mode |= ISC_RLP_CFG_MODE_YYCC;
 	}
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:10 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:10 +0200
Subject: [PATCH v4 05/11] media: atmel: atmel-isc-base: use mutex to lock awb
 workqueue from streaming
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-6-eugen.hristev@microchip.com>

The AWB workqueue runs in a kernel thread and needs to be synchronized
w.r.t. the streaming status.
It is possible that streaming is stopped while the AWB workq is running.
In this case it is likely that the check for vb2_start_streaming_called is done
at one point in time, but the AWB computations are done later, including a call
to isc_update_profile, which requires streaming to be started.
Thus , isc_update_profile will fail if during this operation sequence the
streaming was stopped.
To solve this issue, a mutex is added, that will serialize the awb work and
streaming stopping, with the mention that either streaming is stopped
completely including termination of the last frame is done, and after that
the AWB work can check stream status and stop; either first AWB work is
completed and after that the streaming can stop correctly.
The awb spin lock cannot be used since this spinlock is taken in the same
context and using it in the stop streaming will result in a recursion BUG.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 drivers/media/platform/atmel/atmel-isc-base.c | 31 ++++++++++++++++---
 drivers/media/platform/atmel/atmel-isc.h      |  1 +
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
index 6b482270eb93..f7a88399bd54 100644
--- a/drivers/media/platform/atmel/atmel-isc-base.c
+++ b/drivers/media/platform/atmel/atmel-isc-base.c
@@ -400,6 +400,7 @@ static void isc_stop_streaming(struct vb2_queue *vq)
 	struct isc_buffer *buf;
 	int ret;
 
+	mutex_lock(&isc->awb_mutex);
 	v4l2_ctrl_activate(isc->do_wb_ctrl, false);
 
 	/* Wait until the end of the current frame */
@@ -407,6 +408,8 @@ static void isc_stop_streaming(struct vb2_queue *vq)
 		v4l2_err(&isc->v4l2_dev,
 			 "Timeout waiting for end of the capture\n");
 
+	mutex_unlock(&isc->awb_mutex);
+
 	/* Disable DMA interrupt */
 	regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
 
@@ -1395,10 +1398,6 @@ static void isc_awb_work(struct work_struct *w)
 	u32 min, max;
 	int ret;
 
-	/* streaming is not active anymore */
-	if (!vb2_start_streaming_called(&isc->vb2_vidq))
-		return;
-
 	if (ctrls->hist_stat != HIST_ENABLED)
 		return;
 
@@ -1453,7 +1452,24 @@ static void isc_awb_work(struct work_struct *w)
 	}
 	regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
 		     hist_id | baysel | ISC_HIS_CFG_RAR);
+
+	/*
+	 * We have to make sure the streaming has not stopped meanwhile.
+	 * ISC requires a frame to clock the internal profile update.
+	 * To avoid issues, lock the sequence with a mutex
+	 */
+	mutex_lock(&isc->awb_mutex);
+
+	/* streaming is not active anymore */
+	if (!vb2_start_streaming_called(&isc->vb2_vidq)) {
+		mutex_unlock(&isc->awb_mutex);
+		return;
+	};
+
 	isc_update_profile(isc);
+
+	mutex_unlock(&isc->awb_mutex);
+
 	/* if awb has been disabled, we don't need to start another histogram */
 	if (ctrls->awb)
 		regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_HISREQ);
@@ -1532,6 +1548,8 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
 
 		isc_update_awb_ctrls(isc);
 
+		mutex_lock(&isc->awb_mutex);
+
 		if (vb2_start_streaming_called(&isc->vb2_vidq)) {
 			/*
 			 * If we are streaming, we can update profile to
@@ -1546,6 +1564,7 @@ static int isc_s_awb_ctrl(struct v4l2_ctrl *ctrl)
 			 */
 			v4l2_ctrl_activate(isc->do_wb_ctrl, false);
 		}
+		mutex_unlock(&isc->awb_mutex);
 
 		/* if we have autowhitebalance on, start histogram procedure */
 		if (ctrls->awb == ISC_WB_AUTO &&
@@ -1738,6 +1757,7 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier,
 {
 	struct isc_device *isc = container_of(notifier->v4l2_dev,
 					      struct isc_device, v4l2_dev);
+	mutex_destroy(&isc->awb_mutex);
 	cancel_work_sync(&isc->awb_work);
 	video_unregister_device(&isc->video_dev);
 	v4l2_ctrl_handler_free(&isc->ctrls.handler);
@@ -1848,6 +1868,8 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
 	isc->current_subdev = container_of(notifier,
 					   struct isc_subdev_entity, notifier);
 	mutex_init(&isc->lock);
+	mutex_init(&isc->awb_mutex);
+
 	init_completion(&isc->comp);
 
 	/* Initialize videobuf2 queue */
@@ -1927,6 +1949,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier)
 	video_unregister_device(vdev);
 
 isc_async_complete_err:
+	mutex_destroy(&isc->awb_mutex);
 	mutex_destroy(&isc->lock);
 	return ret;
 }
diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
index c9234c90ae58..04ea5e340808 100644
--- a/drivers/media/platform/atmel/atmel-isc.h
+++ b/drivers/media/platform/atmel/atmel-isc.h
@@ -305,6 +305,7 @@ struct isc_device {
 	struct work_struct	awb_work;
 
 	struct mutex		lock; /* serialize access to file operations */
+	struct mutex		awb_mutex; /* serialize access to streaming status from awb work queue */
 	spinlock_t		awb_lock; /* serialize access to DMA buffers from awb work queue */
 
 	struct regmap_field	*pipeline[ISC_PIPE_LINE_NODE_NUM];
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:11 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:11 +0200
Subject: [PATCH v4 06/11] media: atmel: atmel-isc: compact the controller
 formats list
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-7-eugen.hristev@microchip.com>

Compact the list array to be more readable.
No other changes, only cosmetic.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
Reviewed-by: Jacopo Mondi <jacopo+renesas at jmondi.org>
---
 .../media/platform/atmel/atmel-sama5d2-isc.c  | 51 ++++++----------
 .../media/platform/atmel/atmel-sama7g5-isc.c  | 60 +++++++------------
 2 files changed, 37 insertions(+), 74 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
index 025c3e8a7e95..d96ee3373889 100644
--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c
@@ -60,56 +60,39 @@
 static const struct isc_format sama5d2_controller_formats[] = {
 	{
 		.fourcc		= V4L2_PIX_FMT_ARGB444,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_ARGB555,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_RGB565,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_ABGR32,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_XBGR32,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUV420,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUYV,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUV422P,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_GREY,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_Y10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SBGGR10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGBRG10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SRGGB10,
 	},
 };
diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
index 9dc75eed0098..e07ae188c15f 100644
--- a/drivers/media/platform/atmel/atmel-sama7g5-isc.c
+++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c
@@ -63,65 +63,45 @@
 static const struct isc_format sama7g5_controller_formats[] = {
 	{
 		.fourcc		= V4L2_PIX_FMT_ARGB444,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_ARGB555,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_RGB565,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_ABGR32,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_XBGR32,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUV420,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_UYVY,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_VYUY,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUYV,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_YUV422P,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_GREY,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_Y10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_Y16,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SBGGR8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGBRG8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGRBG8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SRGGB8,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SBGGR10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGBRG10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SGRBG10,
-	},
-	{
+	}, {
 		.fourcc		= V4L2_PIX_FMT_SRGGB10,
 	},
 };
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:12 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:12 +0200
Subject: [PATCH v4 07/11] media: atmel: atmel-isc: change format propagation
 to subdev into only verification
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-8-eugen.hristev@microchip.com>

As a top MC video driver, the atmel-isc should not propagate the format to the
subdevice.
It should rather check at start_streaming() time if the subdev is properly
configured with a compatible format.
Removed the whole format finding logic, and reworked the format verification
at start_streaming time, such that the ISC will return an error if the subdevice
is not properly configured. To achieve this, media_pipeline_start
is called and a link_validate callback is created to check the formats.
With this being done, the module parameter 'sensor_preferred' makes no sense
anymore. The ISC should not decide which format the sensor is using. The
ISC should only cope with the situation and inform userspace if the streaming
is possible in the current configuration.
The redesign of the format propagation has also risen the question of the
enumfmt callback. If enumfmt is called with an mbus_code, the enumfmt handler
should only return the formats that are supported for this mbus_code.
To make it more easy to understand the formats, changed the report order
to report first the native formats, and after that the formats that the ISC
can convert to.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
Changes in v4:
- moved validation code into link_validate and used media_pipeline_start
- merged this patch with the enum_fmt patch which was previously in v3 of
the series

Changes in v3:
- clamp to maximum resolution once the frame size from the subdev is found

 drivers/media/platform/atmel/atmel-isc-base.c | 335 ++++++++++--------
 .../media/platform/atmel/atmel-isc-scaler.c   |   5 +
 drivers/media/platform/atmel/atmel-isc.h      |   3 +
 3 files changed, 191 insertions(+), 152 deletions(-)

diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c
index f7a88399bd54..31c79313aadc 100644
--- a/drivers/media/platform/atmel/atmel-isc-base.c
+++ b/drivers/media/platform/atmel/atmel-isc-base.c
@@ -36,11 +36,6 @@ static unsigned int debug;
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "debug level (0-2)");
 
-static unsigned int sensor_preferred = 1;
-module_param(sensor_preferred, uint, 0644);
-MODULE_PARM_DESC(sensor_preferred,
-		 "Sensor is preferred to output the specified format (1-on 0-off), default 1");
-
 #define ISC_IS_FORMAT_RAW(mbus_code) \
 	(((mbus_code) & 0xf000) == 0x3000)
 
@@ -337,6 +332,10 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
 	unsigned long flags;
 	int ret;
 
+	ret = media_pipeline_start(&isc->video_dev.entity, &isc->mpipe);
+	if (ret)
+		goto err_pipeline_start;
+
 	/* Enable stream on the sub device */
 	ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1);
 	if (ret && ret != -ENOIOCTLCMD) {
@@ -384,6 +383,9 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count)
 	v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
 
 err_start_stream:
+	media_pipeline_stop(&isc->video_dev.entity);
+
+err_pipeline_start:
 	spin_lock_irqsave(&isc->dma_queue_lock, flags);
 	list_for_each_entry(buf, &isc->dma_queue, list)
 		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED);
@@ -420,6 +422,9 @@ static void isc_stop_streaming(struct vb2_queue *vq)
 	if (ret && ret != -ENOIOCTLCMD)
 		v4l2_err(&isc->v4l2_dev, "stream off failed in subdev\n");
 
+	/* Stop media pipeline */
+	media_pipeline_stop(&isc->video_dev.entity);
+
 	/* Release all active buffers */
 	spin_lock_irqsave(&isc->dma_queue_lock, flags);
 	if (unlikely(isc->cur_frm)) {
@@ -496,21 +501,56 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv,
 	u32 index = f->index;
 	u32 i, supported_index;
 
-	if (index < isc->controller_formats_size) {
-		f->pixelformat = isc->controller_formats[index].fourcc;
-		return 0;
+	supported_index = 0;
+
+	for (i = 0; i < isc->formats_list_size; i++) {
+		if (!isc->formats_list[i].sd_support)
+			continue;
+		/*
+		 * If specific mbus_code is requested, provide only
+		 * supported formats with this mbus code
+		 */
+		if (f->mbus_code && f->mbus_code !=
+		    isc->formats_list[i].mbus_code)
+			continue;
+		if (supported_index == index) {
+			f->pixelformat = isc->formats_list[i].fourcc;
+			return 0;
+		}
+		supported_index++;
 	}
 
-	index -= isc->controller_formats_size;
+	/*
+	 * If the sensor does not support this mbus_code whatsoever,
+	 * there is no reason to advertise any of our output formats
+	 */
+	if (supported_index == 0)
+		return -EINVAL;
 
+	/*
+	 * If the sensor uses a format that is not raw, then we cannot
+	 * convert it to any of the formats that we usually can with a
+	 * RAW sensor. Thus, do not advertise them.
+	 */
+	if (isc->config.sd_format &&
+	    !ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
+		return -EINVAL;
+
+	/*
+	 * Iterate again through the formats that we can convert to.
+	 * However, to avoid duplicates, skip the formats that
+	 * the sensor already supports directly
+	 */
+	index -= supported_index;
 	supported_index = 0;
 
-	for (i = 0; i < isc->formats_list_size; i++) {
-		if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) ||
-		    !isc->formats_list[i].sd_support)
+	for (i = 0; i < isc->controller_formats_size; i++) {
+		/* if this format is already supported by sensor, skip it */
+		if (find_format_by_fourcc(isc, isc->controller_formats[i].fourcc))
 			continue;
 		if (supported_index == index) {
-			f->pixelformat = isc->formats_list[i].fourcc;
+			f->pixelformat =
+				isc->controller_formats[i].fourcc;
 			return 0;
 		}
 		supported_index++;
@@ -581,20 +621,30 @@ static int isc_try_validate_formats(struct isc_device *isc)
 		break;
 	default:
 	/* any other different formats are not supported */
+		v4l2_err(&isc->v4l2_dev, "Requested unsupported format.\n");
 		ret = -EINVAL;
 	}
 	v4l2_dbg(1, debug, &isc->v4l2_dev,
 		 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n",
 		 rgb, yuv, grey, bayer);
 
-	/* we cannot output RAW if we do not receive RAW */
-	if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
+	if ((bayer) &&
+	    !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
+		v4l2_err(&isc->v4l2_dev, "Cannot output RAW if we do not receive RAW.\n");
 		return -EINVAL;
+	}
 
-	/* we cannot output GREY if we do not receive RAW/GREY */
 	if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
-	    !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code))
+	    !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
+		v4l2_err(&isc->v4l2_dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
+		return -EINVAL;
+	}
+
+	if ((rgb || bayer || yuv) &&
+	    ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
+		v4l2_err(&isc->v4l2_dev, "Cannot convert GREY to another format.\n");
 		return -EINVAL;
+	}
 
 	return ret;
 }
@@ -822,7 +872,7 @@ static void isc_try_fse(struct isc_device *isc,
 	 * If we do not know yet which format the subdev is using, we cannot
 	 * do anything.
 	 */
-	if (!isc->try_config.sd_format)
+	if (!isc->config.sd_format)
 		return;
 
 	fse.code = isc->try_config.sd_format->mbus_code;
@@ -843,180 +893,141 @@ static void isc_try_fse(struct isc_device *isc,
 	}
 }
 
-static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f,
-			u32 *code)
+static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
 {
-	int i;
-	struct isc_format *sd_fmt = NULL, *direct_fmt = NULL;
 	struct v4l2_pix_format *pixfmt = &f->fmt.pix;
-	struct v4l2_subdev_pad_config pad_cfg = {};
-	struct v4l2_subdev_state pad_state = {
-		.pads = &pad_cfg
-		};
-	struct v4l2_subdev_format format = {
-		.which = V4L2_SUBDEV_FORMAT_TRY,
-	};
-	u32 mbus_code;
-	int ret;
-	bool rlp_dma_direct_dump = false;
+	unsigned int i;
 
 	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 
-	/* Step 1: find a RAW format that is supported */
-	for (i = 0; i < isc->num_user_formats; i++) {
-		if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) {
-			sd_fmt = isc->user_formats[i];
+	isc->try_config.fourcc = isc->user_formats[0]->fourcc;
+
+	/* find if the format requested is supported */
+	for (i = 0; i < isc->controller_formats_size; i++)
+		if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
+			isc->try_config.fourcc = pixfmt->pixelformat;
 			break;
 		}
-	}
-	/* Step 2: We can continue with this RAW format, or we can look
-	 * for better: maybe sensor supports directly what we need.
-	 */
-	direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat);
-
-	/* Step 3: We have both. We decide given the module parameter which
-	 * one to use.
-	 */
-	if (direct_fmt && sd_fmt && sensor_preferred)
-		sd_fmt = direct_fmt;
-
-	/* Step 4: we do not have RAW but we have a direct format. Use it. */
-	if (direct_fmt && !sd_fmt)
-		sd_fmt = direct_fmt;
-
-	/* Step 5: if we are using a direct format, we need to package
-	 * everything as 8 bit data and just dump it
-	 */
-	if (sd_fmt == direct_fmt)
-		rlp_dma_direct_dump = true;
-
-	/* Step 6: We have no format. This can happen if the userspace
-	 * requests some weird/invalid format.
-	 * In this case, default to whatever we have
-	 */
-	if (!sd_fmt && !direct_fmt) {
-		sd_fmt = isc->user_formats[isc->num_user_formats - 1];
-		v4l2_dbg(1, debug, &isc->v4l2_dev,
-			 "Sensor not supporting %.4s, using %.4s\n",
-			 (char *)&pixfmt->pixelformat, (char *)&sd_fmt->fourcc);
-	}
-
-	if (!sd_fmt) {
-		ret = -EINVAL;
-		goto isc_try_fmt_err;
-	}
-
-	/* Step 7: Print out what we decided for debugging */
-	v4l2_dbg(1, debug, &isc->v4l2_dev,
-		 "Preferring to have sensor using format %.4s\n",
-		 (char *)&sd_fmt->fourcc);
-
-	/* Step 8: at this moment we decided which format the subdev will use */
-	isc->try_config.sd_format = sd_fmt;
-
-	/* Limit to Atmel ISC hardware capabilities */
-	if (pixfmt->width > isc->max_width)
-		pixfmt->width = isc->max_width;
-	if (pixfmt->height > isc->max_height)
-		pixfmt->height = isc->max_height;
-
-	/*
-	 * The mbus format is the one the subdev outputs.
-	 * The pixels will be transferred in this format Sensor -> ISC
-	 */
-	mbus_code = sd_fmt->mbus_code;
-
-	/*
-	 * Validate formats. If the required format is not OK, default to raw.
-	 */
-
-	isc->try_config.fourcc = pixfmt->pixelformat;
-
-	if (isc_try_validate_formats(isc)) {
-		pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc;
-		/* Re-try to validate the new format */
-		ret = isc_try_validate_formats(isc);
-		if (ret)
-			goto isc_try_fmt_err;
-	}
-
-	ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump);
-	if (ret)
-		goto isc_try_fmt_err;
-
-	ret = isc_try_configure_pipeline(isc);
-	if (ret)
-		goto isc_try_fmt_err;
 
-	/* Obtain frame sizes if possible to have crop requirements ready */
-	isc_try_fse(isc, &pad_state);
-
-	v4l2_fill_mbus_format(&format.format, pixfmt, mbus_code);
-	ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt,
-			       &pad_state, &format);
-	if (ret < 0)
-		goto isc_try_fmt_subdev_err;
+	/* If we did not find the requested format, we will fallback here */
+	pixfmt->pixelformat = isc->try_config.fourcc;
+	pixfmt->colorspace = V4L2_COLORSPACE_SRGB;
+	pixfmt->field = V4L2_FIELD_NONE;
 
-	v4l2_fill_pix_format(pixfmt, &format.format);
+	isc_try_configure_rlp_dma(isc, false);
 
 	/* Limit to Atmel ISC hardware capabilities */
-	if (pixfmt->width > isc->max_width)
-		pixfmt->width = isc->max_width;
-	if (pixfmt->height > isc->max_height)
-		pixfmt->height = isc->max_height;
+	v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
+			      &pixfmt->height, 16, isc->max_height, 0, 0);
 
 	pixfmt->field = V4L2_FIELD_NONE;
 	pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
 	pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
 			     pixfmt->height;
 
-	if (code)
-		*code = mbus_code;
+	isc->try_fmt = *f;
 
 	return 0;
+}
 
-isc_try_fmt_err:
-	v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n");
-isc_try_fmt_subdev_err:
-	memset(&isc->try_config, 0, sizeof(isc->try_config));
+static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
+{
+	isc_try_fmt(isc, f);
 
-	return ret;
+	/* make the try configuration active */
+	isc->config = isc->try_config;
+	isc->fmt = isc->try_fmt;
+
+	v4l2_dbg(1, debug, &isc->v4l2_dev, "ISC set_fmt to %.4s @%dx%d\n",
+		 (char *)&f->fmt.pix.pixelformat,
+		 f->fmt.pix.width, f->fmt.pix.height);
+
+	return 0;
 }
 
-static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
+static int isc_validate(struct isc_device *isc)
 {
+	int ret;
+	int i;
+	struct isc_format *sd_fmt = NULL;
+	struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
 	struct v4l2_subdev_format format = {
 		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = isc->remote_pad,
+	};
+	struct v4l2_subdev_pad_config pad_cfg = {};
+	struct v4l2_subdev_state pad_state = {
+		.pads = &pad_cfg,
 	};
-	u32 mbus_code = 0;
-	int ret;
 
-	ret = isc_try_fmt(isc, f, &mbus_code);
+	/* Get current format from subdev */
+	ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
+			       &format);
 	if (ret)
 		return ret;
 
-	v4l2_fill_mbus_format(&format.format, &f->fmt.pix, mbus_code);
-	ret = v4l2_subdev_call(isc->current_subdev->sd, pad,
-			       set_fmt, NULL, &format);
-	if (ret < 0)
-		return ret;
+	/* Identify the subdev's format configuration */
+	for (i = 0; i < isc->num_user_formats; i++)
+		if (isc->user_formats[i]->mbus_code == format.format.code) {
+			sd_fmt = isc->user_formats[i];
+			break;
+		}
+
+	/* Check if the format is not supported */
+	if (!sd_fmt) {
+		v4l2_err(&isc->v4l2_dev,
+			 "Current subdevice is streaming a media bus code that is not supported 0x%x\n",
+			 format.format.code);
+		return -EPIPE;
+	}
+
+	/* At this moment we know which format the subdev will use */
+	isc->try_config.sd_format = sd_fmt;
+
+	/* If the sensor is not RAW, we can only do a direct dump */
+	if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
+		isc_try_configure_rlp_dma(isc, true);
 
 	/* Limit to Atmel ISC hardware capabilities */
-	if (f->fmt.pix.width > isc->max_width)
-		f->fmt.pix.width = isc->max_width;
-	if (f->fmt.pix.height > isc->max_height)
-		f->fmt.pix.height = isc->max_height;
+	v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
+			      &format.format.height, 16, isc->max_height, 0, 0);
+
+	/* Check if the frame size is the same. Otherwise we may overflow */
+	if (pixfmt->height != format.format.height ||
+	    pixfmt->width != format.format.width) {
+		v4l2_err(&isc->v4l2_dev,
+			 "ISC not configured with the proper frame size: %dx%d\n",
+			 format.format.width, format.format.height);
+		return -EPIPE;
+	}
 
-	isc->fmt = *f;
+	v4l2_dbg(1, debug, &isc->v4l2_dev,
+		 "Identified subdev using format %.4s with %dx%d %d bpp\n",
+		 (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height,
+		 isc->try_config.bpp);
 
+	/* Reset and restart AWB if the subdevice changed the format */
 	if (isc->try_config.sd_format && isc->config.sd_format &&
 	    isc->try_config.sd_format != isc->config.sd_format) {
 		isc->ctrls.hist_stat = HIST_INIT;
 		isc_reset_awb_ctrls(isc);
 		isc_update_v4l2_ctrls(isc);
 	}
-	/* make the try configuration active */
+
+	/* Validate formats */
+	ret = isc_try_validate_formats(isc);
+	if (ret)
+		return ret;
+
+	/* Obtain frame sizes if possible to have crop requirements ready */
+	isc_try_fse(isc, &pad_state);
+
+	/* Configure ISC pipeline for the config */
+	ret = isc_try_configure_pipeline(isc);
+	if (ret)
+		return ret;
+
 	isc->config = isc->try_config;
 
 	v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n");
@@ -1040,7 +1051,7 @@ static int isc_try_fmt_vid_cap(struct file *file, void *priv,
 {
 	struct isc_device *isc = video_drvdata(file);
 
-	return isc_try_fmt(isc, f, NULL);
+	return isc_try_fmt(isc, f);
 }
 
 static int isc_enum_input(struct file *file, void *priv,
@@ -1841,7 +1852,7 @@ static int isc_set_default_fmt(struct isc_device *isc)
 	};
 	int ret;
 
-	ret = isc_try_fmt(isc, &f, NULL);
+	ret = isc_try_fmt(isc, &f);
 	if (ret)
 		return ret;
 
@@ -2015,6 +2026,24 @@ int isc_pipeline_init(struct isc_device *isc)
 }
 EXPORT_SYMBOL_GPL(isc_pipeline_init);
 
+int isc_link_validate(struct media_link *link)
+{
+	struct video_device *vdev =
+		media_entity_to_video_device(link->sink->entity);
+	struct isc_device *isc = video_get_drvdata(vdev);
+	int ret;
+
+	ret = v4l2_subdev_link_validate(link);
+	if (ret)
+		return ret;
+
+	return isc_validate(isc);
+}
+
+static const struct media_entity_operations isc_entity_operations = {
+	.link_validate = isc_link_validate,
+};
+
 int isc_mc_init(struct isc_device *isc, u32 ver)
 {
 	const struct of_device_id *match;
@@ -2022,6 +2051,8 @@ int isc_mc_init(struct isc_device *isc, u32 ver)
 
 	isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
 	isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
+	isc->video_dev.entity.ops = &isc_entity_operations;
+
 	isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 
 	ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
diff --git a/drivers/media/platform/atmel/atmel-isc-scaler.c b/drivers/media/platform/atmel/atmel-isc-scaler.c
index ec95c9665883..93375a61aea6 100644
--- a/drivers/media/platform/atmel/atmel-isc-scaler.c
+++ b/drivers/media/platform/atmel/atmel-isc-scaler.c
@@ -155,6 +155,10 @@ static const struct v4l2_subdev_pad_ops isc_scaler_pad_ops = {
 	.init_cfg = isc_scaler_init_cfg,
 };
 
+static const struct media_entity_operations isc_scaler_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
 static const struct v4l2_subdev_ops xisc_scaler_subdev_ops = {
 	.pad = &isc_scaler_pad_ops,
 };
@@ -172,6 +176,7 @@ int isc_scaler_init(struct isc_device *isc)
 
 	isc->scaler_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 	isc->scaler_sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_SCALER;
+	isc->scaler_sd.entity.ops = &isc_scaler_entity_ops;
 	isc->scaler_pads[ISC_SCALER_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 	isc->scaler_pads[ISC_SCALER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 
diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h
index 04ea5e340808..e36cf9d3942a 100644
--- a/drivers/media/platform/atmel/atmel-isc.h
+++ b/drivers/media/platform/atmel/atmel-isc.h
@@ -270,6 +270,7 @@ enum isc_scaler_pads {
  * @formats_list_size:	size of formats_list array
  * @pads:		media controller pads for isc video entity
  * @mdev:		media device that is registered by the isc
+ * @mpipe:		media device pipeline used by the isc
  * @remote_pad:		remote pad on the connected subdevice
  * @scaler_sd:		subdevice for the scaler that isc registers
  * @scaler_pads:	media controller pads for the scaler subdevice
@@ -295,6 +296,7 @@ struct isc_device {
 	struct completion	comp;
 
 	struct v4l2_format	fmt;
+	struct v4l2_format	try_fmt;
 	struct isc_format	**user_formats;
 	unsigned int		num_user_formats;
 
@@ -366,6 +368,7 @@ struct isc_device {
 	struct {
 		struct media_pad		pads[ISC_PADS_NUM];
 		struct media_device		mdev;
+		struct media_pipeline		mpipe;
 
 		u32				remote_pad;
 	};
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:13 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:13 +0200
Subject: [PATCH v4 08/11] dt-bindings: media: microchip,
 xisc: add bus-width of 14
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-9-eugen.hristev@microchip.com>

The Microchip XISC supports a bus width of 14 bits.
Add it to the supported bus widths.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 Documentation/devicetree/bindings/media/microchip,xisc.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/microchip,xisc.yaml b/Documentation/devicetree/bindings/media/microchip,xisc.yaml
index 086e1430af4f..3be8f64c3e21 100644
--- a/Documentation/devicetree/bindings/media/microchip,xisc.yaml
+++ b/Documentation/devicetree/bindings/media/microchip,xisc.yaml
@@ -67,7 +67,7 @@ properties:
           remote-endpoint: true
 
           bus-width:
-            enum: [8, 9, 10, 11, 12]
+            enum: [8, 9, 10, 11, 12, 14]
             default: 12
 
           hsync-active:
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:14 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:14 +0200
Subject: [PATCH v4 09/11] ARM: dts: at91: sama7g5: add nodes for video capture
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-10-eugen.hristev@microchip.com>

Add node for the XISC (eXtended Image Sensor Controller) and CSI2DC
(csi2 demux controller).
These nodes represent the top level of the video capture hardware pipeline
and are directly connected in hardware.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
Changes in v4:
- add mandatory property bus type

Changes in v3:
- change bus width for endpoints to the default 14

 arch/arm/boot/dts/sama7g5.dtsi | 49 ++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi
index 7039311bf678..d47d62f01895 100644
--- a/arch/arm/boot/dts/sama7g5.dtsi
+++ b/arch/arm/boot/dts/sama7g5.dtsi
@@ -236,6 +236,55 @@ sdmmc2: mmc at e120c000 {
 			status = "disabled";
 		};
 
+		csi2dc: csi2dc at e1404000 {
+			compatible = "microchip,sama7g5-csi2dc";
+			reg = <0xe1404000 0x500>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 34>, <&xisc>;
+			clock-names = "pclk", "scck";
+			assigned-clocks = <&xisc>;
+			assigned-clock-rates = <266000000>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port at 0 {
+					reg = <0>;
+					csi2dc_in: endpoint {
+					};
+				};
+
+				port at 1 {
+					reg = <1>;
+					csi2dc_out: endpoint {
+						bus-width = <14>;
+						hsync-active = <1>;
+						vsync-active = <1>;
+						remote-endpoint = <&xisc_in>;
+					};
+				};
+			};
+		};
+
+		xisc: xisc at e1408000 {
+			compatible = "microchip,sama7g5-isc";
+			reg = <0xe1408000 0x2000>;
+			interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&pmc PMC_TYPE_PERIPHERAL 56>;
+			clock-names = "hclock";
+			#clock-cells = <0>;
+			clock-output-names = "isc-mck";
+
+			port {
+				xisc_in: endpoint {
+					bus-type = <5>; /* Parallel */
+					bus-width = <14>;
+					hsync-active = <1>;
+					vsync-active = <1>;
+					remote-endpoint = <&csi2dc_out>;
+				};
+			};
+		};
+
 		pwm: pwm at e1604000 {
 			compatible = "microchip,sama7g5-pwm", "atmel,sama5d2-pwm";
 			reg = <0xe1604000 0x4000>;
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:15 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:15 +0200
Subject: [PATCH v4 10/11] ARM: configs: at91: sama7: add xisc and csi2dc
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-11-eugen.hristev@microchip.com>

Enable XISC and CSI2DC drivers.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 arch/arm/configs/sama7_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig
index 938aae4bd80b..15978f2ab4ea 100644
--- a/arch/arm/configs/sama7_defconfig
+++ b/arch/arm/configs/sama7_defconfig
@@ -126,6 +126,8 @@ CONFIG_MEDIA_SUPPORT_FILTER=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_PLATFORM_SUPPORT=y
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_ATMEL_XISC=y
+CONFIG_VIDEO_MICROCHIP_CSI2DC=y
 CONFIG_VIDEO_IMX219=m
 CONFIG_VIDEO_IMX274=m
 CONFIG_VIDEO_OV5647=m
-- 
2.25.1



From eugen.hristev at microchip.com  Fri Jan 21 05:14:16 2022
From: eugen.hristev at microchip.com (Eugen Hristev)
Date: Fri, 21 Jan 2022 15:14:16 +0200
Subject: [PATCH v4 11/11] ARM: multi_v7_defconfig: add atmel video pipeline
 modules
In-Reply-To: <20220121131416.603972-1-eugen.hristev@microchip.com>
References: <20220121131416.603972-1-eugen.hristev@microchip.com>
Message-ID: <20220121131416.603972-12-eugen.hristev@microchip.com>

Add drivers for the atmel video capture pipeline: atmel isc, xisc and
microchip csi2dc.

Signed-off-by: Eugen Hristev <eugen.hristev at microchip.com>
---
 arch/arm/configs/multi_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index c951aeed2138..92b7749a6df8 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -638,7 +638,10 @@ CONFIG_VIDEO_S5P_MIPI_CSIS=m
 CONFIG_VIDEO_EXYNOS_FIMC_LITE=m
 CONFIG_VIDEO_EXYNOS4_FIMC_IS=m
 CONFIG_VIDEO_RCAR_VIN=m
+CONFIG_VIDEO_ATMEL_ISC=m
+CONFIG_VIDEO_ATMEL_XISC=m
 CONFIG_VIDEO_ATMEL_ISI=m
+CONFIG_VIDEO_MICROCHIP_CSI2DC=m
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
 CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Fri Jan 21 05:24:57 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 21 Jan 2022 14:24:57 +0100
Subject: (EXT) Re: [PATCH 1/1] drm: mxsfb: Fix NULL pointer dereference
In-Reply-To: <4d3654b5-9a87-1c02-f2d9-d0974e628c20@denx.de>
References: <20220121131238.507567-1-alexander.stein@ew.tq-group.com>
 <4d3654b5-9a87-1c02-f2d9-d0974e628c20@denx.de>
Message-ID: <2361278.ElGaqSPkdT@steina-w>

Am Freitag, 21. Januar 2022, 14:14:01 CET schrieb Marek Vasut:
> On 1/21/22 14:12, Alexander Stein wrote:
> > Do not deference the NULL pointer if the bridge does not return a
> > bridge state. Assume a fixed format instead.
> > 
> > Fixes: commit b776b0f00f24 ("drm: mxsfb: Use bus_format from the nearest
> > bridge if present") Signed-off-by: Alexander Stein
> > <alexander.stein at ew.tq-group.com>
> > ---
> > This can happen if a "ti,sn75lvds83", "lvds-encoder" bridge is attached
> > to it. atomic_get_input_bus_fmts is only implemented for the
> > lvds-decoder case.
> > 
> >   drivers/gpu/drm/mxsfb/mxsfb_kms.c | 6 +++++-
> >   1 file changed, 5 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> > b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 0655582ae8ed..4cfb6c001679
> > 100644
> > --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> > +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
> > @@ -361,7 +361,11 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc
> > *crtc,> 
> >   		bridge_state =
> >   		
> >   			drm_atomic_get_new_bridge_state(state,
> >   			
> >   							
mxsfb->bridge);
> > 
> > -		bus_format = bridge_state->input_bus_cfg.format;
> > +		if (!bridge_state)
> > +			bus_format = MEDIA_BUS_FMT_FIXED;
> > +		else
> > +			bus_format = bridge_state-
>input_bus_cfg.format;
> > +
> > 
> >   		if (bus_format == MEDIA_BUS_FMT_FIXED) {
> >   		
> >   			dev_warn_once(drm->dev,
> >   			
> >   				      "Bridge does not provide bus 
format, assuming
> >   				      MEDIA_BUS_FMT_RGB888_1X24.
\n"
> 
> Shouldn't this be fixed on the bridge driver side instead ?
> 
> Which bridge driver do you use ?

It's drivers/gpu/drm/bridge/lvds-codec.c. I thought naming the compatibles 
would suffice. I consider a patch for the bridge driver as a separate issue, 
hence the warning from mxsfb. Although I'm unsure how/what to implement. 
Similar to the encode case where the bus format is specified in DT? 

Anyway, mxsfb should not never dereference the NULL pointer which 
drm_atomic_get_new_bridge_state is allowed to return.

Best regards,
Alexander






From marex at denx.de  Fri Jan 21 05:28:44 2022
From: marex at denx.de (Marek Vasut)
Date: Fri, 21 Jan 2022 14:28:44 +0100
Subject: (EXT) Re: [PATCH 1/1] drm: mxsfb: Fix NULL pointer dereference
In-Reply-To: <2361278.ElGaqSPkdT@steina-w>
References: <20220121131238.507567-1-alexander.stein@ew.tq-group.com>
 <4d3654b5-9a87-1c02-f2d9-d0974e628c20@denx.de> <2361278.ElGaqSPkdT@steina-w>
Message-ID: <9b71782f-a54f-9323-ffd8-141dfe5e875e@denx.de>

On 1/21/22 14:24, Alexander Stein wrote:
> Am Freitag, 21. Januar 2022, 14:14:01 CET schrieb Marek Vasut:
>> On 1/21/22 14:12, Alexander Stein wrote:
>>> Do not deference the NULL pointer if the bridge does not return a
>>> bridge state. Assume a fixed format instead.
>>>
>>> Fixes: commit b776b0f00f24 ("drm: mxsfb: Use bus_format from the nearest
>>> bridge if present") Signed-off-by: Alexander Stein
>>> <alexander.stein at ew.tq-group.com>
>>> ---
>>> This can happen if a "ti,sn75lvds83", "lvds-encoder" bridge is attached
>>> to it. atomic_get_input_bus_fmts is only implemented for the
>>> lvds-decoder case.
>>>
>>>    drivers/gpu/drm/mxsfb/mxsfb_kms.c | 6 +++++-
>>>    1 file changed, 5 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
>>> b/drivers/gpu/drm/mxsfb/mxsfb_kms.c index 0655582ae8ed..4cfb6c001679
>>> 100644
>>> --- a/drivers/gpu/drm/mxsfb/mxsfb_kms.c
>>> +++ b/drivers/gpu/drm/mxsfb/mxsfb_kms.c
>>> @@ -361,7 +361,11 @@ static void mxsfb_crtc_atomic_enable(struct drm_crtc
>>> *crtc,>
>>>    		bridge_state =
>>>    		
>>>    			drm_atomic_get_new_bridge_state(state,
>>>    			
>>>    							
> mxsfb->bridge);
>>>
>>> -		bus_format = bridge_state->input_bus_cfg.format;
>>> +		if (!bridge_state)
>>> +			bus_format = MEDIA_BUS_FMT_FIXED;
>>> +		else
>>> +			bus_format = bridge_state-
>> input_bus_cfg.format;
>>> +
>>>
>>>    		if (bus_format == MEDIA_BUS_FMT_FIXED) {
>>>    		
>>>    			dev_warn_once(drm->dev,
>>>    			
>>>    				      "Bridge does not provide bus
> format, assuming
>>>    				      MEDIA_BUS_FMT_RGB888_1X24.
> \n"
>>
>> Shouldn't this be fixed on the bridge driver side instead ?
>>
>> Which bridge driver do you use ?
> 
> It's drivers/gpu/drm/bridge/lvds-codec.c. I thought naming the compatibles
> would suffice. I consider a patch for the bridge driver as a separate issue,
> hence the warning from mxsfb. Although I'm unsure how/what to implement.
> Similar to the encode case where the bus format is specified in DT?

I'm sorry, I missed the lvds-codec part. Laurent is already on CC.

> Anyway, mxsfb should not never dereference the NULL pointer which
> drm_atomic_get_new_bridge_state is allowed to return.

That line ^ should be in the commit message.


From houtao1 at huawei.com  Fri Jan 21 05:56:30 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Fri, 21 Jan 2022 21:56:30 +0800
Subject: [PATCH bpf-next 0/2] arm64, bpf: support more atomic ops
Message-ID: <20220121135632.136976-1-houtao1@huawei.com>

Hi,

Atomics support in bpf has already been done by "Atomics for eBPF"
patch series [1], but it only adds support for x86, and this patchset
adds support for arm64.

Patch #1 changes the type of test program from fentry/ to raw_tp/ for
atomics test, because bpf trampoline is not available for arm64 now.
After the change, atomics test will be available for arm64 and other
arches.

Patch #2 implements atomic[64]_fetch_add, atomic[64]_[fetch_]{and,or,xor}
and atomic[64]_{xchg|cmpxchg} for arm64. For no-LSE-ATOMICS case and
cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case, both ./test_verifier and
"./test_progs -t atomic" are exercised and passed correspondingly.

Comments are always welcome.

Regards,
Tao

Hou Tao (2):
  selftests/bpf: use raw_tp program for atomic test
  arm64, bpf: support more atomic operations

 arch/arm64/include/asm/insn.h                 |  45 +++-
 arch/arm64/lib/insn.c                         | 155 +++++++++++--
 arch/arm64/net/bpf_jit.h                      |  43 +++-
 arch/arm64/net/bpf_jit_comp.c                 | 216 ++++++++++++++----
 .../selftests/bpf/prog_tests/atomics.c        | 114 +++------
 tools/testing/selftests/bpf/progs/atomics.c   |  29 +--
 6 files changed, 438 insertions(+), 164 deletions(-)

-- 
2.27.0



From houtao1 at huawei.com  Fri Jan 21 05:56:31 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Fri, 21 Jan 2022 21:56:31 +0800
Subject: [PATCH bpf-next 1/2] selftests/bpf: use raw_tp program for atomic test
In-Reply-To: <20220121135632.136976-1-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
Message-ID: <20220121135632.136976-2-houtao1@huawei.com>

Now atomic tests will attach fentry program and run it through
bpf_prog_test_run(), but attaching fentry program depends on bpf
trampoline which is only available under x86-64. Considering many
archs have atomic support, using raw_tp program instead.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 .../selftests/bpf/prog_tests/atomics.c        | 114 +++++-------------
 tools/testing/selftests/bpf/progs/atomics.c   |  29 ++---
 2 files changed, 44 insertions(+), 99 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/atomics.c b/tools/testing/selftests/bpf/prog_tests/atomics.c
index 86b7d5d84eec..0de292c1ec02 100644
--- a/tools/testing/selftests/bpf/prog_tests/atomics.c
+++ b/tools/testing/selftests/bpf/prog_tests/atomics.c
@@ -8,18 +8,13 @@ static void test_add(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__add__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(add)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.add.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run add",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run add"))
+		return;
 
 	ASSERT_EQ(skel->data->add64_value, 3, "add64_value");
 	ASSERT_EQ(skel->bss->add64_result, 1, "add64_result");
@@ -31,28 +26,19 @@ static void test_add(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->add_stack_result, 1, "add_stack_result");
 
 	ASSERT_EQ(skel->data->add_noreturn_value, 3, "add_noreturn_value");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_sub(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__sub__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(sub)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.sub.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run sub",
-		  "err %d errno %d retval %d duration %d\n",
-		  err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run sub"))
+		return;
 
 	ASSERT_EQ(skel->data->sub64_value, -1, "sub64_value");
 	ASSERT_EQ(skel->bss->sub64_result, 1, "sub64_result");
@@ -64,27 +50,19 @@ static void test_sub(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->sub_stack_result, 1, "sub_stack_result");
 
 	ASSERT_EQ(skel->data->sub_noreturn_value, -1, "sub_noreturn_value");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_and(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__and__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(and)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.and.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run and",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run and"))
+		return;
 
 	ASSERT_EQ(skel->data->and64_value, 0x010ull << 32, "and64_value");
 	ASSERT_EQ(skel->bss->and64_result, 0x110ull << 32, "and64_result");
@@ -93,27 +71,19 @@ static void test_and(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->and32_result, 0x110, "and32_result");
 
 	ASSERT_EQ(skel->data->and_noreturn_value, 0x010ull << 32, "and_noreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_or(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__or__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(or)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.or.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run or",
-		  "err %d errno %d retval %d duration %d\n",
-		  err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run or"))
+		return;
 
 	ASSERT_EQ(skel->data->or64_value, 0x111ull << 32, "or64_value");
 	ASSERT_EQ(skel->bss->or64_result, 0x110ull << 32, "or64_result");
@@ -122,26 +92,19 @@ static void test_or(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->or32_result, 0x110, "or32_result");
 
 	ASSERT_EQ(skel->data->or_noreturn_value, 0x111ull << 32, "or_noreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_xor(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__xor__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(xor)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.xor.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run xor",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run xor"))
+		return;
 
 	ASSERT_EQ(skel->data->xor64_value, 0x101ull << 32, "xor64_value");
 	ASSERT_EQ(skel->bss->xor64_result, 0x110ull << 32, "xor64_result");
@@ -150,26 +113,19 @@ static void test_xor(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->xor32_result, 0x110, "xor32_result");
 
 	ASSERT_EQ(skel->data->xor_noreturn_value, 0x101ull << 32, "xor_nxoreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_cmpxchg(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__cmpxchg__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(cmpxchg)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.cmpxchg.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run cmpxchg",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run cmpxchg"))
+		return;
 
 	ASSERT_EQ(skel->data->cmpxchg64_value, 2, "cmpxchg64_value");
 	ASSERT_EQ(skel->bss->cmpxchg64_result_fail, 1, "cmpxchg_result_fail");
@@ -178,45 +134,33 @@ static void test_cmpxchg(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->data->cmpxchg32_value, 2, "lcmpxchg32_value");
 	ASSERT_EQ(skel->bss->cmpxchg32_result_fail, 1, "cmpxchg_result_fail");
 	ASSERT_EQ(skel->bss->cmpxchg32_result_succeed, 1, "cmpxchg_result_succeed");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_xchg(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__xchg__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(xchg)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.xchg.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run xchg",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_TRUE(!err && !retval, "test_run xchg"))
+		return;
 
 	ASSERT_EQ(skel->data->xchg64_value, 2, "xchg64_value");
 	ASSERT_EQ(skel->bss->xchg64_result, 1, "xchg64_result");
 
 	ASSERT_EQ(skel->data->xchg32_value, 2, "xchg32_value");
 	ASSERT_EQ(skel->bss->xchg32_result, 1, "xchg32_result");
-
-cleanup:
-	close(link_fd);
 }
 
 void test_atomics(void)
 {
 	struct atomics_lskel *skel;
-	__u32 duration = 0;
 
 	skel = atomics_lskel__open_and_load();
-	if (CHECK(!skel, "skel_load", "atomics skeleton failed\n"))
+	if (!ASSERT_OK_PTR(skel, "atomics skeleton load"))
 		return;
 
 	if (skel->data->skip_tests) {
diff --git a/tools/testing/selftests/bpf/progs/atomics.c b/tools/testing/selftests/bpf/progs/atomics.c
index 16e57313204a..45772d225fa4 100644
--- a/tools/testing/selftests/bpf/progs/atomics.c
+++ b/tools/testing/selftests/bpf/progs/atomics.c
@@ -20,11 +20,12 @@ __u64 add_stack_value_copy = 0;
 __u64 add_stack_result = 0;
 __u64 add_noreturn_value = 1;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(add, int a)
+SEC("raw_tp/sys_enter")
+int add(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
+
 #ifdef ENABLE_ATOMICS_TESTS
 	__u64 add_stack_value = 1;
 
@@ -46,8 +47,8 @@ __s64 sub_stack_value_copy = 0;
 __s64 sub_stack_result = 0;
 __s64 sub_noreturn_value = 1;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(sub, int a)
+SEC("raw_tp/sys_enter")
+int sub(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -70,8 +71,8 @@ __u32 and32_value = 0x110;
 __u32 and32_result = 0;
 __u64 and_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(and, int a)
+SEC("raw_tp/sys_enter")
+int and(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -91,8 +92,8 @@ __u32 or32_value = 0x110;
 __u32 or32_result = 0;
 __u64 or_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(or, int a)
+SEC("raw_tp/sys_enter")
+int or(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -111,8 +112,8 @@ __u32 xor32_value = 0x110;
 __u32 xor32_result = 0;
 __u64 xor_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(xor, int a)
+SEC("raw_tp/sys_enter")
+int xor(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -132,8 +133,8 @@ __u32 cmpxchg32_value = 1;
 __u32 cmpxchg32_result_fail = 0;
 __u32 cmpxchg32_result_succeed = 0;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(cmpxchg, int a)
+SEC("raw_tp/sys_enter")
+int cmpxchg(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -153,8 +154,8 @@ __u64 xchg64_result = 0;
 __u32 xchg32_value = 1;
 __u32 xchg32_result = 0;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(xchg, int a)
+SEC("raw_tp/sys_enter")
+int xchg(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
-- 
2.27.0



From houtao1 at huawei.com  Fri Jan 21 05:56:32 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Fri, 21 Jan 2022 21:56:32 +0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <20220121135632.136976-1-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
Message-ID: <20220121135632.136976-3-houtao1@huawei.com>

Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
it only add support for x86-64, so support these atomic operations
for arm64 as well.

Basically the implementation procedure is almost mechanical translation
of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
under arch/arm64/include/asm. An extra temporary register is needed
for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
adding TMP_REG_4 just use BPF_REG_AX instead.

For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
both ./test_verifier and "./test_progs -t atomic" are exercised and
passed correspondingly.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/include/asm/insn.h |  45 +++++--
 arch/arm64/lib/insn.c         | 155 +++++++++++++++++++++---
 arch/arm64/net/bpf_jit.h      |  43 ++++++-
 arch/arm64/net/bpf_jit_comp.c | 216 +++++++++++++++++++++++++++-------
 4 files changed, 394 insertions(+), 65 deletions(-)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 6b776c8667b2..1416d636f1af 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -280,6 +280,23 @@ enum aarch64_insn_adr_type {
 	AARCH64_INSN_ADR_TYPE_ADR,
 };
 
+enum aarch64_insn_mem_atomic_op {
+	AARCH64_INSN_MEM_ATOMIC_ADD,
+	AARCH64_INSN_MEM_ATOMIC_BIC,
+	AARCH64_INSN_MEM_ATOMIC_EOR,
+	AARCH64_INSN_MEM_ATOMIC_ORR,
+	AARCH64_INSN_MEM_ATOMIC_SWP,
+};
+
+enum aarch64_insn_mem_order_type {
+	AARCH64_INSN_MEM_ORDER_NONE,
+	AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL,
+};
+
+enum aarch64_insn_mb_type {
+	AARCH64_INSN_MB_ISH,
+};
+
 #define	__AARCH64_INSN_FUNCS(abbr, mask, val)				\
 static __always_inline bool aarch64_insn_is_##abbr(u32 code)		\
 {									\
@@ -303,6 +320,11 @@ __AARCH64_INSN_FUNCS(store_post,	0x3FE00C00, 0x38000400)
 __AARCH64_INSN_FUNCS(load_post,	0x3FE00C00, 0x38400400)
 __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
 __AARCH64_INSN_FUNCS(ldadd,	0x3F20FC00, 0x38200000)
+__AARCH64_INSN_FUNCS(ldclr,	0x3F20FC00, 0x38201000)
+__AARCH64_INSN_FUNCS(ldeor,	0x3F20FC00, 0x38202000)
+__AARCH64_INSN_FUNCS(ldset,	0x3F20FC00, 0x38203000)
+__AARCH64_INSN_FUNCS(swp,	0x3F20FC00, 0x38208000)
+__AARCH64_INSN_FUNCS(cas,	0x3FA07C00, 0x08A07C00)
 __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
 __AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
 __AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
@@ -474,13 +496,21 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 				   enum aarch64_insn_register state,
 				   enum aarch64_insn_size_type size,
 				   enum aarch64_insn_ldst_type type);
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-			   enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size);
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size);
+u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
+				      enum aarch64_insn_register base,
+				      enum aarch64_insn_register state,
+				      enum aarch64_insn_size_type size);
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+				  enum aarch64_insn_register address,
+				  enum aarch64_insn_register value,
+				  enum aarch64_insn_size_type size,
+				  enum aarch64_insn_mem_atomic_op op,
+				  enum aarch64_insn_mem_order_type order);
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+			 enum aarch64_insn_register address,
+			 enum aarch64_insn_register value,
+			 enum aarch64_insn_size_type size,
+			 enum aarch64_insn_mem_order_type order);
 u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
 				 enum aarch64_insn_register src,
 				 int imm, enum aarch64_insn_variant variant,
@@ -541,6 +571,7 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
 			      enum aarch64_insn_prfm_type type,
 			      enum aarch64_insn_prfm_target target,
 			      enum aarch64_insn_prfm_policy policy);
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
 s32 aarch64_get_branch_offset(u32 insn);
 u32 aarch64_set_branch_offset(u32 insn, s32 offset);
 
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index fccfe363e567..2a7dde58c44b 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -328,6 +328,29 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
 	return insn;
 }
 
+static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
+					  u32 insn)
+{
+	u32 order;
+
+	switch (type) {
+	case AARCH64_INSN_MEM_ORDER_NONE:
+		order = 0;
+		break;
+	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
+		order = 3;
+		break;
+	default:
+		pr_err("%s: unknown mem order %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn &= ~GENMASK(23, 22);
+	insn |= order << 22;
+
+	return insn;
+}
+
 static inline long branch_imm_common(unsigned long pc, unsigned long addr,
 				     long range)
 {
@@ -603,12 +626,49 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 					    state);
 }
 
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-			   enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size)
+u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
+				      enum aarch64_insn_register base,
+				      enum aarch64_insn_register state,
+				      enum aarch64_insn_size_type size)
+{
+	u32 insn = aarch64_insn_gen_load_store_ex(reg, base, state, size,
+						  AARCH64_INSN_LDST_STORE_EX);
+
+	if (insn == AARCH64_BREAK_FAULT)
+		return insn;
+
+	return insn | BIT(15);
+}
+
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+				  enum aarch64_insn_register address,
+				  enum aarch64_insn_register value,
+				  enum aarch64_insn_size_type size,
+				  enum aarch64_insn_mem_atomic_op op,
+				  enum aarch64_insn_mem_order_type order)
 {
-	u32 insn = aarch64_insn_get_ldadd_value();
+	u32 insn;
+
+	switch (op) {
+	case AARCH64_INSN_MEM_ATOMIC_ADD:
+		insn = aarch64_insn_get_ldadd_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_BIC:
+		insn = aarch64_insn_get_ldclr_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_EOR:
+		insn = aarch64_insn_get_ldeor_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_ORR:
+		insn = aarch64_insn_get_ldset_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_SWP:
+		insn = aarch64_insn_get_swp_value();
+		break;
+	default:
+		pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
+		return AARCH64_BREAK_FAULT;
+	}
 
 	switch (size) {
 	case AARCH64_INSN_SIZE_32:
@@ -621,6 +681,8 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
 
 	insn = aarch64_insn_encode_ldst_size(size, insn);
 
+	insn = aarch64_insn_encode_ldst_order(order, insn);
+
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
 					    result);
 
@@ -631,16 +693,60 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
 					    value);
 }
 
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size)
+static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
+					 u32 insn)
 {
-	/*
-	 * STADD is simply encoded as an alias for LDADD with XZR as
-	 * the destination register.
-	 */
-	return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address,
-				      value, size);
+	u32 order;
+
+	switch (type) {
+	case AARCH64_INSN_MEM_ORDER_NONE:
+		order = 0;
+		break;
+	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
+		order = BIT(15) | BIT(22);
+		break;
+	default:
+		pr_err("%s: unknown mem order %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn &= ~(BIT(15) | BIT(22));
+	insn |= order;
+
+	return insn;
+}
+
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+			 enum aarch64_insn_register address,
+			 enum aarch64_insn_register value,
+			 enum aarch64_insn_size_type size,
+			 enum aarch64_insn_mem_order_type order)
+{
+	u32 insn;
+
+	switch (size) {
+	case AARCH64_INSN_SIZE_32:
+	case AARCH64_INSN_SIZE_64:
+		break;
+	default:
+		pr_err("%s: unimplemented size encoding %d\n", __func__, size);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn = aarch64_insn_get_cas_value();
+
+	insn = aarch64_insn_encode_ldst_size(size, insn);
+
+	insn = aarch64_insn_encode_cas_order(order, insn);
+
+	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
+					    result);
+
+	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
+					    address);
+
+	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
+					    value);
 }
 
 static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
@@ -1456,3 +1562,24 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
 	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
 }
+
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
+{
+	u32 opt;
+	u32 insn;
+
+	switch (type) {
+	case AARCH64_INSN_MB_ISH:
+		opt = 0xb;
+		break;
+	default:
+		pr_err("%s: unknown dmb type %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn = aarch64_insn_get_dmb_value();
+	insn &= ~GENMASK(11, 8);
+	insn |= (opt << 8);
+
+	return insn;
+}
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index cc0cf0f5c7c3..308f96587861 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -88,10 +88,41 @@
 /* [Rn] = Rt; (atomic) Rs = [state] */
 #define A64_STXR(sf, Rt, Rn, Rs) \
 	A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
+/* smp_mb(); [Rn] = Rt; (atomic) Rs = [state] */
+#define A64_STLXR(sf, Rt, Rn, Rs) \
+	aarch64_insn_gen_store_release_ex(Rt, Rn, Rs, A64_SIZE(sf))
 
-/* LSE atomics */
-#define A64_STADD(sf, Rn, Rs) \
-	aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf))
+/*
+ * LSE atomics
+ *
+ * ST{ADD,CLR,SET,EOR} is simply encoded as an alias for
+ * LDD{ADD,CLR,SET,EOR} with XZR as the destination register.
+ */
+#define A64_ST_OP(sf, Rn, Rs, op) \
+	aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
+		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+		AARCH64_INSN_MEM_ORDER_NONE)
+/* [Rn] <op>= Rs */
+#define A64_STADD(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ADD)
+#define A64_STCLR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, BIC)
+#define A64_STEOR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, EOR)
+#define A64_STSET(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ORR)
+
+#define A64_LD_OP_AL(sf, Rt, Rn, Rs, op) \
+	aarch64_insn_gen_atomic_ld_op(Rt, Rn, Rs, \
+		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
+/* Rt = [Rn]; [Rn] <op>= Rs */
+#define A64_LDADDAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ADD)
+#define A64_LDCLRAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, BIC)
+#define A64_LDEORAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, EOR)
+#define A64_LDSETAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ORR)
+/* Rt = [Rn]; [Rn] = Rs */
+#define A64_SWPAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SWP)
+/* Rs = CAS(Rn, Rs, Rt) */
+#define A64_CASAL(sf, Rt, Rn, Rs) \
+	aarch64_insn_gen_cas(Rt, Rn, Rs, A64_SIZE(sf), \
+		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
 
 /* Add/subtract (immediate) */
 #define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
@@ -196,6 +227,9 @@
 #define A64_ANDS(sf, Rd, Rn, Rm) A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND_SETFLAGS)
 /* Rn & Rm; set condition flags */
 #define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm)
+/* Rd = ~Rm (alias of ORN with A64_ZR as Rn) */
+#define A64_MVN(sf, Rd, Rm)  \
+	A64_LOGIC_SREG(sf, Rd, A64_ZR, Rm, ORN)
 
 /* Logical (immediate) */
 #define A64_LOGIC_IMM(sf, Rd, Rn, imm, type) ({ \
@@ -219,4 +253,7 @@
 #define A64_BTI_J  A64_HINT(AARCH64_INSN_HINT_BTIJ)
 #define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC)
 
+/* DMB */
+#define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
+
 #endif /* _BPF_JIT_H */
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 74f9a9b6a053..79e2c2c4c733 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -27,6 +27,17 @@
 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
 #define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
 
+#define check_imm(bits, imm) do {				\
+	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
+	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
+		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
+			i, imm, imm);				\
+		return -EINVAL;					\
+	}							\
+} while (0)
+#define check_imm19(imm) check_imm(19, imm)
+#define check_imm26(imm) check_imm(26, imm)
+
 /* Map BPF registers to A64 registers */
 static const int bpf2a64[] = {
 	/* return value from in-kernel function, and exit value from eBPF */
@@ -329,6 +340,163 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
 #undef jmp_offset
 }
 
+static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const u8 code = insn->code;
+	const u8 dst = bpf2a64[insn->dst_reg];
+	const u8 src = bpf2a64[insn->src_reg];
+	const u8 tmp = bpf2a64[TMP_REG_1];
+	const u8 tmp2 = bpf2a64[TMP_REG_2];
+	const bool isdw = BPF_SIZE(code) == BPF_DW;
+	const s16 off = insn->off;
+	u8 reg;
+
+	if (!off) {
+		reg = dst;
+	} else {
+		emit_a64_mov_i(1, tmp, off, ctx);
+		emit(A64_ADD(1, tmp, tmp, dst), ctx);
+		reg = tmp;
+	}
+
+	switch (insn->imm) {
+	/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+	case BPF_ADD:
+		emit(A64_STADD(isdw, reg, src), ctx);
+		break;
+	case BPF_AND:
+		emit(A64_MVN(isdw, tmp2, src), ctx);
+		emit(A64_STCLR(isdw, reg, tmp2), ctx);
+		break;
+	case BPF_OR:
+		emit(A64_STSET(isdw, reg, src), ctx);
+		break;
+	case BPF_XOR:
+		emit(A64_STEOR(isdw, reg, src), ctx);
+		break;
+	/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
+	case BPF_ADD | BPF_FETCH:
+		emit(A64_LDADDAL(isdw, src, reg, src), ctx);
+		break;
+	case BPF_AND | BPF_FETCH:
+		emit(A64_MVN(isdw, tmp2, src), ctx);
+		emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
+		break;
+	case BPF_OR | BPF_FETCH:
+		emit(A64_LDSETAL(isdw, src, reg, src), ctx);
+		break;
+	case BPF_XOR | BPF_FETCH:
+		emit(A64_LDEORAL(isdw, src, reg, src), ctx);
+		break;
+	/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+	case BPF_XCHG:
+		emit(A64_SWPAL(isdw, src, reg, src), ctx);
+		break;
+	/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+	case BPF_CMPXCHG:
+		emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
+		break;
+	default:
+		pr_err_once("unknown atomic op code %02x\n", insn->imm);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int emit_ll_sc_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const u8 code = insn->code;
+	const u8 dst = bpf2a64[insn->dst_reg];
+	const u8 src = bpf2a64[insn->src_reg];
+	const u8 tmp = bpf2a64[TMP_REG_1];
+	const u8 tmp2 = bpf2a64[TMP_REG_2];
+	const u8 tmp3 = bpf2a64[TMP_REG_3];
+	const int i = insn - ctx->prog->insnsi;
+	const s32 imm = insn->imm;
+	const s16 off = insn->off;
+	const bool isdw = BPF_SIZE(code) == BPF_DW;
+	u8 reg;
+	s32 jmp_offset;
+
+	if (!off) {
+		reg = dst;
+	} else {
+		emit_a64_mov_i(1, tmp, off, ctx);
+		emit(A64_ADD(1, tmp, tmp, dst), ctx);
+		reg = tmp;
+	}
+
+	if (imm == BPF_ADD || imm == BPF_AND ||
+	    imm == BPF_OR || imm == BPF_XOR) {
+		/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+		emit(A64_LDXR(isdw, tmp2, reg), ctx);
+		if (imm == BPF_ADD)
+			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
+		else if (imm == BPF_AND)
+			emit(A64_AND(isdw, tmp2, tmp2, src), ctx);
+		else if (imm == BPF_OR)
+			emit(A64_ORR(isdw, tmp2, tmp2, src), ctx);
+		else
+			emit(A64_EOR(isdw, tmp2, tmp2, src), ctx);
+		emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -3;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+	} else if (imm == (BPF_ADD | BPF_FETCH) ||
+		   imm == (BPF_AND | BPF_FETCH) ||
+		   imm == (BPF_OR | BPF_FETCH) ||
+		   imm == (BPF_XOR | BPF_FETCH)) {
+		/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
+		const u8 ax = bpf2a64[BPF_REG_AX];
+
+		emit(A64_MOV(isdw, ax, src), ctx);
+		emit(A64_LDXR(isdw, src, reg), ctx);
+		if (imm == (BPF_ADD | BPF_FETCH))
+			emit(A64_ADD(isdw, tmp2, src, ax), ctx);
+		else if (imm == (BPF_AND | BPF_FETCH))
+			emit(A64_AND(isdw, tmp2, src, ax), ctx);
+		else if (imm == (BPF_OR | BPF_FETCH))
+			emit(A64_ORR(isdw, tmp2, src, ax), ctx);
+		else
+			emit(A64_EOR(isdw, tmp2, src, ax), ctx);
+		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -3;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else if (imm == BPF_XCHG) {
+		/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+		emit(A64_MOV(isdw, tmp2, src), ctx);
+		emit(A64_LDXR(isdw, src, reg), ctx);
+		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -2;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else if (imm == BPF_CMPXCHG) {
+		/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+		const u8 r0 = bpf2a64[BPF_REG_0];
+
+		emit(A64_MOV(isdw, tmp2, r0), ctx);
+		emit(A64_LDXR(isdw, r0, reg), ctx);
+		emit(A64_EOR(isdw, tmp3, r0, tmp2), ctx);
+		jmp_offset = 4;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(isdw, tmp3, jmp_offset), ctx);
+		emit(A64_STLXR(isdw, src, reg, tmp3), ctx);
+		jmp_offset = -4;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else {
+		pr_err_once("unknown atomic op code %02x\n", imm);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static void build_epilogue(struct jit_ctx *ctx)
 {
 	const u8 r0 = bpf2a64[BPF_REG_0];
@@ -434,29 +602,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
 	const u8 src = bpf2a64[insn->src_reg];
 	const u8 tmp = bpf2a64[TMP_REG_1];
 	const u8 tmp2 = bpf2a64[TMP_REG_2];
-	const u8 tmp3 = bpf2a64[TMP_REG_3];
 	const s16 off = insn->off;
 	const s32 imm = insn->imm;
 	const int i = insn - ctx->prog->insnsi;
 	const bool is64 = BPF_CLASS(code) == BPF_ALU64 ||
 			  BPF_CLASS(code) == BPF_JMP;
-	const bool isdw = BPF_SIZE(code) == BPF_DW;
-	u8 jmp_cond, reg;
+	u8 jmp_cond;
 	s32 jmp_offset;
 	u32 a64_insn;
 	int ret;
 
-#define check_imm(bits, imm) do {				\
-	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
-	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
-		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
-			i, imm, imm);				\
-		return -EINVAL;					\
-	}							\
-} while (0)
-#define check_imm19(imm) check_imm(19, imm)
-#define check_imm26(imm) check_imm(26, imm)
-
 	switch (code) {
 	/* dst = src */
 	case BPF_ALU | BPF_MOV | BPF_X:
@@ -891,33 +1046,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
 
 	case BPF_STX | BPF_ATOMIC | BPF_W:
 	case BPF_STX | BPF_ATOMIC | BPF_DW:
-		if (insn->imm != BPF_ADD) {
-			pr_err_once("unknown atomic op code %02x\n", insn->imm);
-			return -EINVAL;
-		}
-
-		/* STX XADD: lock *(u32 *)(dst + off) += src
-		 * and
-		 * STX XADD: lock *(u64 *)(dst + off) += src
-		 */
-
-		if (!off) {
-			reg = dst;
-		} else {
-			emit_a64_mov_i(1, tmp, off, ctx);
-			emit(A64_ADD(1, tmp, tmp, dst), ctx);
-			reg = tmp;
-		}
-		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) {
-			emit(A64_STADD(isdw, reg, src), ctx);
-		} else {
-			emit(A64_LDXR(isdw, tmp2, reg), ctx);
-			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
-			emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
-			jmp_offset = -3;
-			check_imm19(jmp_offset);
-			emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
-		}
+		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
+			ret = emit_lse_atomic(insn, ctx);
+		else
+			ret = emit_ll_sc_atomic(insn, ctx);
+		if (ret)
+			return ret;
 		break;
 
 	default:
-- 
2.27.0



From quic_jinlmao at quicinc.com  Fri Jan 21 06:01:47 2022
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Fri, 21 Jan 2022 22:01:47 +0800
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <20211216190223.GA78825@p14s>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
Message-ID: <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>

Hi Mathieu,

Good Day.

On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> [...]
>
>>>>> +
>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>> +{
>>>>> +    static int traceid = TPDM_TRACE_ID_START;
>>>>> +
>>>>> +    drvdata->traceid = traceid++;
>>>>> +}
>>>> I have been specific on how to properly do this in the last revision.  Given the
>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>
>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>> process it before the holidays.
>>>>
>>>> Thanks,
>>>> Mathieu
>>> Hi Mathieu,
>>>
>>> Sorry, not addressed your previous comments here.
>>>
>>> For the trace id, each coresight component has 7 bits to store the trace
>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>> Architecture specification v3.0
>>
> Correct
>
>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>> our internal device. About 80 ids are already used.
>>>
>>> Some components have fixed trace id in HW. If we use functions below to
>>> count the trace id, there will be conflict to other components.
>>>
>>> Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
>>> components ? And handle trace ids in its' own driver ?
>>>
>> This will limit systems to 15 cores - some have more!
>>
> Correct
>
>>> static inline int coresight_get_system_trace_id(int id)
>>> {
>>>           /* Start system IDs above the highest per CPU trace ID. */
>>>           return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>> }
> Looking at my own suggestion again this won't work since it returns the same traceID
> when called multiple times.
>
> For this patchset and _without_ taking into account internal devices that have
> their traceID set in HW:
>
> 1. Define a bitmask that is 7 bit wide.
Should it be a 128 bit wide bitmask? (0--127)?
> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> first available bit after cpumask_last(cpu_possible_mask) + 1.

Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
Return the first zero bit position as the trace id and set the bit.

> 4. Define a new function called coresight_put_system_trace_id(int id) that
> clears the bit in the mask corresponding to @id.
>
> For now that should work.
>
>>> static inline int coresight_get_trace_id(int cpu)
>>> {
>>>       /*
>>>        * A trace ID of value 0 is invalid, so let's start at some
>>>        * random value that fits in 7 bits and go from there.  Since
>>>        * the common convention is to have data trace IDs be I(N) + 1,
>>>        * set instruction trace IDs as a function of the CPU number.
>>>        */
>>>       return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>> }
>>>
>> This fixed relationship between cpu and trace ID is used in the perf
>> tooling to populate the elements in the perf.data file to correctly
>> allow association between CPU and trace data, and thus allow correct
>> trace decode.
> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> perf header - theoretically we should be able to change the allocation scheme
> without impacting the decoding process.
>
>> It should be possible to create another more dynamic mapping scheme -
>> but this must include a way to support the perf requirements too.
>>
> TraceIDs have been a lurking problem for as long as the subsystem has existed.
> For now what I have suggested above should be sufficient to provide an
> in-between solution that doesn't hold back this patchset.
>
> That being said, we need to start thinking about the best way to do this.  I
> will put a patchset together in the new year that aims in that direction.
>
>> Regards
>>
>> Mike
>>
>>> Thanks
>>>
>>> Jinlong Mao
>>>
>>>>> +
>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>> +{
>>>>> +    struct device *dev = &adev->dev;
>>>>> +    struct coresight_platform_data *pdata;
>>>>> +    struct tpdm_drvdata *drvdata;
>>>>> +    struct coresight_desc desc = { 0 };
>>>>> +
>>>>> +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>> +    if (!desc.name)
>>>>> +            return -ENOMEM;
>>>>> +    pdata = coresight_get_platform_data(dev);
>>>>> +    if (IS_ERR(pdata))
>>>>> +            return PTR_ERR(pdata);
>>>>> +    adev->dev.platform_data = pdata;
>>>>> +
>>>>> +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>> +    if (!drvdata)
>>>>> +            return -ENOMEM;
>>>>> +    drvdata->dev = &adev->dev;
>>>>> +    dev_set_drvdata(dev, drvdata);
>>>>> +
>>>>> +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>> +    if (!drvdata->base)
>>>>> +            return -ENOMEM;
>>>>> +
>>>>> +    mutex_init(&drvdata->lock);
>>>>> +
>>>>> +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>> +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>> +    desc.ops = &tpdm_cs_ops;
>>>>> +    desc.pdata = adev->dev.platform_data;
>>>>> +    desc.dev = &adev->dev;
>>>>> +    drvdata->csdev = coresight_register(&desc);
>>>>> +    if (IS_ERR(drvdata->csdev))
>>>>> +            return PTR_ERR(drvdata->csdev);
>>>>> +
>>>>> +    tpdm_init_default_data(drvdata);
>>>>> +    pm_runtime_put(&adev->dev);
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>> +{
>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>> +
>>>>> +    coresight_unregister(drvdata->csdev);
>>>>> +}
>>>>> +
>>>>> +static struct amba_id tpdm_ids[] = {
>>>>> +    {
>>>>> +            .id = 0x000f0e00,
>>>>> +            .mask = 0x000fff00,
>>>>> +    },
>>>>> +    { 0, 0},
>>>>> +};
>>>>> +
>>>>> +static struct amba_driver tpdm_driver = {
>>>>> +    .drv = {
>>>>> +            .name   = "coresight-tpdm",
>>>>> +            .owner  = THIS_MODULE,
>>>>> +            .suppress_bind_attrs = true,
>>>>> +    },
>>>>> +    .probe          = tpdm_probe,
>>>>> +    .id_table       = tpdm_ids,
>>>>> +};
>>>>> +
>>>>> +module_amba_driver(tpdm_driver);
>>>>> +
>>>>> +MODULE_LICENSE("GPL v2");
>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> new file mode 100644
>>>>> index 000000000000..980ae90ff1c8
>>>>> --- /dev/null
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> @@ -0,0 +1,31 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>> +/*
>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>> + */
>>>>> +
>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>> +
>>>>> +/* Default value of the traceid */
>>>>> +#define TPDM_TRACE_ID_START 128
>>>>> +
>>>>> +/**
>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>> + * @base:       memory mapped base address for this component.
>>>>> + * @dev:        The device entity associated to this component.
>>>>> + * @csdev:      component vitals needed by the framework.
>>>>> + * @lock:       lock for the enable value.
>>>>> + * @enable:     enable status of the component.
>>>>> + * @traceid:    value of the current ID for this component.
>>>>> + */
>>>>> +
>>>>> +struct tpdm_drvdata {
>>>>> +    void __iomem            *base;
>>>>> +    struct device           *dev;
>>>>> +    struct coresight_device *csdev;
>>>>> +    struct mutex            lock;
>>>>> +    bool                    enable;
>>>>> +    int                     traceid;
>>>>> +};
>>>>> +
>>>>> +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>> --- a/include/linux/coresight.h
>>>>> +++ b/include/linux/coresight.h
>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>>       CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>>       CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>>       CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>> +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>>    };
>>>>>
>>>>>    enum coresight_dev_subtype_helper {
>>>>> --
>>>>> 2.17.1
>>>>>
>>
>>
>> -- 
>> Mike Leach
>> Principal Engineer, ARM Ltd.
>> Manchester Design Centre. UK


From mkorpershoek at baylibre.com  Fri Jan 21 06:03:19 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 21 Jan 2022 15:03:19 +0100
Subject: [PATCH v4 0/4] input: MT6358 PMIC button support
Message-ID: <20220121140323.4080640-1-mkorpershoek@baylibre.com>

The MediaTek MT6358 PMIC has support for two buttons: PWR and HOME.

The interrupt logic is a little different than other PMICs from the
same family:
for MT6323 and MT6397, we have one interrupt source per button
* for MT6358, we have two interrupts lines per button: the press and
* release interrupts are distinct sources.

Changes since v3 [1]:
* checkpatch.pl --strict fixes

Changes since v2 [2]:
* added 4th patch with device tree enable
* cover letter title prefixed with 'input'

This has been tested with evtest on mt8183-pumpkin on input/next

[1] https://lore.kernel.org/r/20210702134310.3451560-1-mkorpershoek at baylibre.com
[2] https://lore.kernel.org/r/id:20210512152648.39961-1-mkorpershoek at baylibre.com

Mattijs Korpershoek (4):
  Input: mtk-pmic-keys - use get_irq_byname() instead of index
  dt-bindings: input: mtk-pmic-keys: add MT6358 binding definition
  Input: mtk-pmic-keys - add support for MT6358
  arm64: dts: mt6358: add mt6358-keys node

 .../bindings/input/mtk-pmic-keys.txt          |  5 +-
 arch/arm64/boot/dts/mediatek/mt6358.dtsi      | 12 ++++
 drivers/input/keyboard/mtk-pmic-keys.c        | 55 +++++++++++++++++--
 3 files changed, 67 insertions(+), 5 deletions(-)


base-commit: 87a0b2fafc09766d8c55461a18345a1cfb10a7fe
-- 
2.32.0



From mkorpershoek at baylibre.com  Fri Jan 21 06:03:20 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 21 Jan 2022 15:03:20 +0100
Subject: [PATCH v4 1/4] Input: mtk-pmic-keys - use get_irq_byname() instead of
 index
In-Reply-To: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
References: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
Message-ID: <20220121140323.4080640-2-mkorpershoek@baylibre.com>

Some pmics of the mt6397 family (such as MT6358), have two IRQs per
physical key: one for press event, another for release event.

The mtk-pmic-keys driver assumes that each key only has one
IRQ. The key index and the RES_IRQ resource index have a 1/1 mapping.

This won't work for MT6358, as we have multiple resources (2) for one key.

To prepare mtk-pmic-keys to support MT6358, retrieve IRQs by name
instead of by index.

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/mtk-pmic-keys.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index 62391d6c7da6..d1abf95d5701 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -241,6 +241,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	unsigned int keycount;
 	struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
 	struct device_node *node = pdev->dev.of_node, *child;
+	static const char *const irqnames[] = { "powerkey", "homekey" };
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_regs *mtk_pmic_regs;
 	struct input_dev *input_dev;
@@ -268,7 +269,8 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	input_dev->id.version = 0x0001;
 
 	keycount = of_get_available_child_count(node);
-	if (keycount > MTK_PMIC_MAX_KEY_COUNT) {
+	if (keycount > MTK_PMIC_MAX_KEY_COUNT ||
+	    keycount > ARRAY_SIZE(irqnames)) {
 		dev_err(keys->dev, "too many keys defined (%d)\n", keycount);
 		return -EINVAL;
 	}
@@ -276,7 +278,8 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	for_each_child_of_node(node, child) {
 		keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index];
 
-		keys->keys[index].irq = platform_get_irq(pdev, index);
+		keys->keys[index].irq =
+			platform_get_irq_byname(pdev, irqnames[index]);
 		if (keys->keys[index].irq < 0) {
 			of_node_put(child);
 			return keys->keys[index].irq;
-- 
2.32.0



From mkorpershoek at baylibre.com  Fri Jan 21 06:03:21 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 21 Jan 2022 15:03:21 +0100
Subject: [PATCH v4 2/4] dt-bindings: input: mtk-pmic-keys: add MT6358 binding
 definition
In-Reply-To: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
References: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
Message-ID: <20220121140323.4080640-3-mkorpershoek@baylibre.com>

Add the binding documentation of the mtk-pmic-keys for the MT6358 PMICs.

MT6358 is a little different since it used separate IRQs for the
release key (_r) event

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
index 535d92885372..9d00f2a8e13a 100644
--- a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
+++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
@@ -9,7 +9,10 @@ For MT6397/MT6323 MFD bindings see:
 Documentation/devicetree/bindings/mfd/mt6397.txt
 
 Required properties:
-- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
+- compatible: Should be one of:
+	- "mediatek,mt6397-keys"
+	- "mediatek,mt6323-keys"
+	- "mediatek,mt6358-keys"
 - linux,keycodes: See Documentation/devicetree/bindings/input/input.yaml
 
 Optional Properties:
-- 
2.32.0



From mkorpershoek at baylibre.com  Fri Jan 21 06:03:23 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 21 Jan 2022 15:03:23 +0100
Subject: [PATCH v4 4/4] arm64: dts: mt6358: add mt6358-keys node
In-Reply-To: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
References: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
Message-ID: <20220121140323.4080640-5-mkorpershoek@baylibre.com>

This enables the power,home keys on MediaTek boards with a mt6358 pmic.

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 arch/arm64/boot/dts/mediatek/mt6358.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt6358.dtsi b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
index 95145076b7e6..98f3b0e0c9f6 100644
--- a/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2020 MediaTek Inc.
  */
+#include <dt-bindings/input/input.h>
 
 &pwrap {
 	pmic: mt6358 {
@@ -357,5 +358,16 @@ mt6358_vsim2_reg: ldo_vsim2 {
 		mt6358rtc: mt6358rtc {
 			compatible = "mediatek,mt6358-rtc";
 		};
+
+		mt6358keys: mt6358keys {
+			compatible = "mediatek,mt6358-keys";
+			power {
+				linux,keycodes = <KEY_POWER>;
+				wakeup-source;
+			};
+			home {
+				linux,keycodes = <KEY_HOME>;
+			};
+		};
 	};
 };
-- 
2.32.0



From mkorpershoek at baylibre.com  Fri Jan 21 06:03:22 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 21 Jan 2022 15:03:22 +0100
Subject: [PATCH v4 3/4] Input: mtk-pmic-keys - add support for MT6358
In-Reply-To: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
References: <20220121140323.4080640-1-mkorpershoek@baylibre.com>
Message-ID: <20220121140323.4080640-4-mkorpershoek@baylibre.com>

MT6358 pmic keys behave differently than mt6397 and mt6323: there are
two interrupts per key: one for press, the other one for release (_r)

Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/mtk-pmic-keys.c | 48 ++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c
index d1abf95d5701..c31ab4368388 100644
--- a/drivers/input/keyboard/mtk-pmic-keys.c
+++ b/drivers/input/keyboard/mtk-pmic-keys.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mfd/mt6323/registers.h>
+#include <linux/mfd/mt6358/registers.h>
 #include <linux/mfd/mt6397/core.h>
 #include <linux/mfd/mt6397/registers.h>
 #include <linux/module.h>
@@ -74,11 +75,22 @@ static const struct mtk_pmic_regs mt6323_regs = {
 	.pmic_rst_reg = MT6323_TOP_RST_MISC,
 };
 
+static const struct mtk_pmic_regs mt6358_regs = {
+	.keys_regs[MTK_PMIC_PWRKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
+				   0x2, MT6358_PSC_TOP_INT_CON0, 0x5),
+	.keys_regs[MTK_PMIC_HOMEKEY_INDEX] =
+		MTK_PMIC_KEYS_REGS(MT6358_TOPSTATUS,
+				   0x8, MT6358_PSC_TOP_INT_CON0, 0xa),
+	.pmic_rst_reg = MT6358_TOP_RST_MISC,
+};
+
 struct mtk_pmic_keys_info {
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_keys_regs *regs;
 	unsigned int keycode;
 	int irq;
+	int irq_r; /* optional: release irq if different */
 	bool wakeup:1;
 };
 
@@ -188,6 +200,18 @@ static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys,
 		return ret;
 	}
 
+	if (info->irq_r > 0) {
+		ret = devm_request_threaded_irq(keys->dev, info->irq_r, NULL,
+						mtk_pmic_keys_irq_handler_thread,
+						IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+						"mtk-pmic-keys", info);
+		if (ret) {
+			dev_err(keys->dev, "Failed to request IRQ_r: %d: %d\n",
+				info->irq, ret);
+			return ret;
+		}
+	}
+
 	input_set_capability(keys->input_dev, EV_KEY, info->keycode);
 
 	return 0;
@@ -199,8 +223,11 @@ static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev)
 	int index;
 
 	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
-		if (keys->keys[index].wakeup)
+		if (keys->keys[index].wakeup) {
 			enable_irq_wake(keys->keys[index].irq);
+			if (keys->keys[index].irq_r > 0)
+				enable_irq_wake(keys->keys[index].irq_r);
+		}
 	}
 
 	return 0;
@@ -212,8 +239,11 @@ static int __maybe_unused mtk_pmic_keys_resume(struct device *dev)
 	int index;
 
 	for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) {
-		if (keys->keys[index].wakeup)
+		if (keys->keys[index].wakeup) {
 			disable_irq_wake(keys->keys[index].irq);
+			if (keys->keys[index].irq_r > 0)
+				disable_irq_wake(keys->keys[index].irq_r);
+		}
 	}
 
 	return 0;
@@ -229,6 +259,9 @@ static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = {
 	}, {
 		.compatible = "mediatek,mt6323-keys",
 		.data = &mt6323_regs,
+	}, {
+		.compatible = "mediatek,mt6358-keys",
+		.data = &mt6358_regs,
 	}, {
 		/* sentinel */
 	}
@@ -242,6 +275,7 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 	struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent);
 	struct device_node *node = pdev->dev.of_node, *child;
 	static const char *const irqnames[] = { "powerkey", "homekey" };
+	static const char *const irqnames_r[] = { "powerkey_r", "homekey_r" };
 	struct mtk_pmic_keys *keys;
 	const struct mtk_pmic_regs *mtk_pmic_regs;
 	struct input_dev *input_dev;
@@ -285,6 +319,16 @@ static int mtk_pmic_keys_probe(struct platform_device *pdev)
 			return keys->keys[index].irq;
 		}
 
+		if (of_device_is_compatible(node, "mediatek,mt6358-keys")) {
+			keys->keys[index].irq_r = platform_get_irq_byname(pdev,
+									  irqnames_r[index]);
+
+			if (keys->keys[index].irq_r < 0) {
+				of_node_put(child);
+				return keys->keys[index].irq_r;
+			}
+		}
+
 		error = of_property_read_u32(child,
 			"linux,keycodes", &keys->keys[index].keycode);
 		if (error) {
-- 
2.32.0



From frederic at kernel.org  Fri Jan 21 06:47:32 2022
From: frederic at kernel.org (Frederic Weisbecker)
Date: Fri, 21 Jan 2022 15:47:32 +0100
Subject: [PATCH v4 1/2] Documentation: Fill the gaps about entry/noinstr
 constraints
In-Reply-To: <20220110105044.94423-1-nsaenzju@redhat.com>
References: <20220110105044.94423-1-nsaenzju@redhat.com>
Message-ID: <20220121144732.GA233613@lothringen>

On Mon, Jan 10, 2022 at 11:50:43AM +0100, Nicolas Saenz Julienne wrote:
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> The entry/exit handling for exceptions, interrupts, syscalls and KVM is
> not really documented except for some comments.
> 
> Fill the gaps.
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de
> Co-developed-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> Reviewed-by: Mark Rutland <mark.rutland at arm.com>
> Reviewed-by: Paul E. McKenney <paulmck at kernel.org>

Nice!

Reviewed-by: Frederic Weisbecker <frederic at kernel.org>


From frederic at kernel.org  Fri Jan 21 06:55:23 2022
From: frederic at kernel.org (Frederic Weisbecker)
Date: Fri, 21 Jan 2022 15:55:23 +0100
Subject: [PATCH v4 2/2] Documentation: core-api: entry: Add comments
 about nesting
In-Reply-To: <20220110105044.94423-2-nsaenzju@redhat.com>
References: <20220110105044.94423-1-nsaenzju@redhat.com>
 <20220110105044.94423-2-nsaenzju@redhat.com>
Message-ID: <20220121145523.GB233613@lothringen>

On Mon, Jan 10, 2022 at 11:50:44AM +0100, Nicolas Saenz Julienne wrote:
> The topic of nesting and reentrancy in the context of early entry code
> hasn't been addressed so far. So do it.
> 
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>

Reviewed-by: Frederic Weisbecker <frederic at kernel.org>


From piotr.oniszczuk at gmail.com  Fri Jan 21 07:43:41 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Fri, 21 Jan 2022 16:43:41 +0100
Subject: [PATCH v3 00/22] drm/rockchip: RK356x VOP2 support
In-Reply-To: <20220121103245.GT23490@pengutronix.de>
References: <20211220110630.3521121-1-s.hauer@pengutronix.de>
 <AA3A26CB-6282-4A6B-99DC-8042DC8926BB@gmail.com>
 <20220121103245.GT23490@pengutronix.de>
Message-ID: <44C87C12-A194-4AC8-922B-C4C215474AC9@gmail.com>



> Wiadomo?? napisana przez Sascha Hauer <s.hauer at pengutronix.de> w dniu 21.01.2022, o godz. 11:32:
> 
>> 
>> 1. how support for CEC looks/prospects (plans for future, not in this code, expecting others should implement, etc)?
> 
> I had to google what CEC actually is. We don't have plans supporting it.
> It looks like this is a matter of the HDMI driver supporting this and
> not bound to the rockchip driver.

Ah ok. sure. got it!
(I asked as Rockchip hdmi driver already well supports CEC - so i was thinking on rk3566 this is more of enabling than writing support code).

> You enabled the panfrost driver with other patches, right?

Oh - i wasn't aware any patches are needed for Mesa for rk3566....
If so - may you pls point me for latest/correct patches for rk3566? 

> 
>> 
>> 3. in kernel dmesg I have many:
>> 
>> "rockchip-drm display-subsystem: [drm] *ERROR* Unsupported format modifier 0x810000000000001".
> 
> This message is correct. This corresponds to
> DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED and the VOP2 driver doesn't
> support this. I have a similar problem here with
> weston-simple-dmabuf-egl.  By default this uses DRM_FORMAT_XRGB8888
> which ends up being PIPE_FORMAT_B8G8R8_UNORM in MESA.

Ah ok. Clear now.

Thx!

btw: i added support for argb8888 in my app and now all is ok. 
no anymore errors in dmesg :-)

so summarising:
your vop2 code works for me in all supported video pipeline variants:

-x11/Glamour
-Wayland-EGL
-EGLFS/EGL-dmabuf
-EGLFS/DRM Planes 

Your vop2 work is impressive!

btw:
you mention:

> In weston-simple-dmabuf-egl I can pass a suitable format on the command
> line, in my case I use DRM_FORMAT_ABGR8888 (which becomes
> PIPE_FORMAT_R8G8B8A8_UNORM). With this the panfrost driver does AFBC
> which then can be rendered in the VOP2 cluster window overlay.

is this mean that: when my app is using ARGB8888 format - then I have AFBC on rk3566?




From andriy.shevchenko at linux.intel.com  Fri Jan 21 08:25:57 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 21 Jan 2022 18:25:57 +0200
Subject: [PATCH v5 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220121071942.11601-4-axe.yang@mediatek.com>
References: <20220121071942.11601-1-axe.yang@mediatek.com>
 <20220121071942.11601-4-axe.yang@mediatek.com>
Message-ID: <YerelftLTFS3HRWx@smile.fi.intel.com>

On Fri, Jan 21, 2022 at 03:19:42PM +0800, Axe Yang wrote:
> Add support for eint IRQ when MSDC is used as an SDIO host. This
> feature requires SDIO device support async IRQ function. With this
> feature, SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in MSDC node
> to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>         &mmcX {
>                 ...
>                 pinctrl-names = "default", "state_uhs", "state_eint",
>                                 "state_dat1";
>                 ...
>                 pinctrl-2 = <&mmc2_pins_eint>;
>                 pinctrl-3 = <&mmc2_pins_dat1>;
>                 ...
>                 cap-sdio-async-irq;
>                 ...
>         };

LGTM, so FWIW,
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>


> Co-developed-by: Yong Mao <yong.mao at mediatek.com>
> Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 123 +++++++++++++++++++++++++++++++++++---
>  1 file changed, 115 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 65037e1d7723..f8e38228d810 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2014-2015, 2022 MediaTek Inc.
>   * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
>   */
>  
> @@ -9,6 +9,7 @@
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/iopoll.h>
>  #include <linux/ioport.h>
>  #include <linux/irq.h>
> @@ -440,8 +441,12 @@ struct msdc_host {
>  	struct pinctrl *pinctrl;
>  	struct pinctrl_state *pins_default;
>  	struct pinctrl_state *pins_uhs;
> +	struct pinctrl_state *pins_eint;
> +	struct pinctrl_state *pins_dat1;
>  	struct delayed_work req_timeout;
>  	int irq;		/* host interrupt */
> +	int eint_irq;		/* device interrupt */
> +	int sdio_irq_cnt;	/* irq enable cnt */
>  	struct reset_control *reset;
>  
>  	struct clk *src_clk;	/* msdc source clock */
> @@ -465,6 +470,7 @@ struct msdc_host {
>  	bool hs400_tuning;	/* hs400 mode online tuning */
>  	bool internal_cd;	/* Use internal card-detect logic */
>  	bool cqhci;		/* support eMMC hw cmdq */
> +	bool sdio_eint_ready;	/* Ready to support SDIO eint interrupt */
>  	struct msdc_save_para save_para; /* used when gate HCLK */
>  	struct msdc_tune_para def_tune_para; /* default tune setting */
>  	struct msdc_tune_para saved_tune_para; /* tune result of CMD21/CMD19 */
> @@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enb)
>  	__msdc_enable_sdio_irq(host, enb);
>  	spin_unlock_irqrestore(&host->lock, flags);
>  
> -	if (enb)
> -		pm_runtime_get_noresume(host->dev);
> -	else
> -		pm_runtime_put_noidle(host->dev);
> +	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
> +		if (enb)
> +			pm_runtime_get_noresume(host->dev);
> +		else
> +			pm_runtime_put_noidle(host->dev);
> +	}
>  }
>  
>  static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
> @@ -2461,6 +2469,48 @@ static const struct mmc_host_ops mt_msdc_ops = {
>  	.hw_reset = msdc_hw_reset,
>  };
>  
> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +	struct msdc_host *host = dev_id;
> +	struct mmc_host *mmc = mmc_from_priv(host);
> +
> +	spin_lock(&host->lock);
> +	if (likely(host->sdio_irq_cnt > 0)) {
> +		disable_irq_nosync(host->eint_irq);
> +		disable_irq_wake(host->eint_irq);
> +		host->sdio_irq_cnt--;
> +	}
> +	spin_unlock(&host->lock);
> +
> +	sdio_signal_irq(mmc);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> +{
> +	struct gpio_desc *desc;
> +	int irq, ret;
> +
> +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
> +
> +	irq = gpiod_to_irq(desc);
> +	if (irq < 0)
> +		return irq;
> +
> +	ret = devm_request_threaded_irq(host->dev, irq, NULL, msdc_sdio_eint_irq,
> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_NO_AUTOEN,
> +					"sdio-eint", host);
> +	if (ret)
> +		return ret;
> +
> +	host->eint_irq = irq;
> +
> +	return 0;
> +}
> +
>  static const struct cqhci_host_ops msdc_cmdq_ops = {
>  	.enable         = msdc_cqe_enable,
>  	.disable        = msdc_cqe_disable,
> @@ -2631,6 +2681,23 @@ static int msdc_drv_probe(struct platform_device *pdev)
>  		goto host_free;
>  	}
>  
> +	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 & MMC_CAP2_SDIO_ASYNC_IRQ)) {
> +		/* Support for SDIO eint irq */
> +		host->pins_eint = pinctrl_lookup_state(host->pinctrl, "state_eint");
> +		if (IS_ERR(host->pins_eint)) {
> +			dev_dbg(&pdev->dev, "Cannot find pinctrl eint!\n");
> +		} else {
> +			host->pins_dat1 = pinctrl_lookup_state(host->pinctrl, "state_dat1");
> +			if (IS_ERR(host->pins_dat1)) {
> +				ret = dev_err_probe(&pdev->dev, PTR_ERR(host->pins_dat1),
> +						    "Cannot find pinctrl dat1!\n");
> +				goto host_free;
> +			}
> +
> +			host->sdio_eint_ready = true;
> +		}
> +	}
> +
>  	msdc_of_property_parse(pdev, host);
>  
>  	host->dev = &pdev->dev;
> @@ -2722,6 +2789,16 @@ static int msdc_drv_probe(struct platform_device *pdev)
>  	if (ret)
>  		goto release;
>  
> +	if (host->sdio_eint_ready) {
> +		ret = msdc_request_dat1_eint_irq(host);
> +		if (ret) {
> +			dev_err(host->dev, "Failed to register data1 eint irq!\n");
> +			goto release;
> +		}
> +
> +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> +	}
> +
>  	pm_runtime_set_active(host->dev);
>  	pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
>  	pm_runtime_use_autosuspend(host->dev);
> @@ -2843,8 +2920,22 @@ static int __maybe_unused msdc_runtime_suspend(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);
> +	unsigned long flags;
>  
>  	msdc_save_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		disable_irq(host->irq);
> +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt == 0) {
> +			enable_irq(host->eint_irq);
> +			enable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt++;
> +		}
> +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
>  	msdc_gate_clock(host);
>  	return 0;
>  }
> @@ -2853,6 +2944,7 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);
> +	unsigned long flags;
>  	int ret;
>  
>  	ret = msdc_ungate_clock(host);
> @@ -2860,10 +2952,25 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev)
>  		return ret;
>  
>  	msdc_restore_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt > 0) {
> +			disable_irq_nosync(host->eint_irq);
> +			disable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt--;
> +			sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		} else {
> +			sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
> +		}
> +		spin_unlock_irqrestore(&host->lock, flags);
> +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> +		enable_irq(host->irq);
> +	}
>  	return 0;
>  }
>  
> -static int __maybe_unused msdc_suspend(struct device *dev)
> +static int __maybe_unused msdc_suspend_noirq(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	int ret;
> @@ -2877,13 +2984,13 @@ static int __maybe_unused msdc_suspend(struct device *dev)
>  	return pm_runtime_force_suspend(dev);
>  }
>  
> -static int __maybe_unused msdc_resume(struct device *dev)
> +static int __maybe_unused msdc_resume_noirq(struct device *dev)
>  {
>  	return pm_runtime_force_resume(dev);
>  }
>  
>  static const struct dev_pm_ops msdc_dev_pm_ops = {
> -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq, msdc_resume_noirq)
>  	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL)
>  };
>  
> -- 
> 2.25.1
> 

-- 
With Best Regards,
Andy Shevchenko




From sampaio.ime at gmail.com  Fri Jan 21 08:54:12 2022
From: sampaio.ime at gmail.com (Luiz Sampaio)
Date: Fri, 21 Jan 2022 13:54:12 -0300
Subject: [PATCH 07/31] input: touchscreen: changing LED_* from enum
 led_brightness to actual value
In-Reply-To: <20220121165436.30956-1-sampaio.ime@gmail.com>
References: <20220121165436.30956-1-sampaio.ime@gmail.com>
Message-ID: <20220121165436.30956-8-sampaio.ime@gmail.com>

The enum led_brightness, which contains the declaration of LED_OFF,
LED_ON, LED_HALF and LED_FULL is obsolete, as the led class now supports
max_brightness.
---
 drivers/input/touchscreen/stmfts.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index bc11203c9cf7..7e7cb5f4d6d3 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -608,8 +608,8 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
 		return PTR_ERR(sdata->ledvdd);
 
 	sdata->led_cdev.name = STMFTS_DEV_NAME;
-	sdata->led_cdev.max_brightness = LED_ON;
-	sdata->led_cdev.brightness = LED_OFF;
+	sdata->led_cdev.max_brightness = 1;
+	sdata->led_cdev.brightness = 0;
 	sdata->led_cdev.brightness_set_blocking = stmfts_brightness_set;
 	sdata->led_cdev.brightness_get = stmfts_brightness_get;
 
-- 
2.34.1



From sampaio.ime at gmail.com  Fri Jan 21 08:54:13 2022
From: sampaio.ime at gmail.com (Luiz Sampaio)
Date: Fri, 21 Jan 2022 13:54:13 -0300
Subject: [PATCH 08/31] leds: changing LED_* from enum led_brightness to actual
 value
In-Reply-To: <20220121165436.30956-1-sampaio.ime@gmail.com>
References: <20220121165436.30956-1-sampaio.ime@gmail.com>
Message-ID: <20220121165436.30956-9-sampaio.ime@gmail.com>

The enum led_brightness, which contains the declaration of LED_OFF,
LED_ON, LED_HALF and LED_FULL is obsolete, as the led class now supports
max_brightness.
---
 drivers/leds/blink/leds-lgm-sso.c        |  8 +++----
 drivers/leds/flash/leds-ktd2692.c        |  4 ++--
 drivers/leds/flash/leds-lm3601x.c        | 10 ++++----
 drivers/leds/flash/leds-mt6360.c         | 10 ++++----
 drivers/leds/flash/leds-rt4505.c         |  8 +++----
 drivers/leds/flash/leds-rt8515.c         |  4 ++--
 drivers/leds/flash/leds-sgm3140.c        |  4 ++--
 drivers/leds/led-class.c                 |  6 ++---
 drivers/leds/led-core.c                  |  8 +++----
 drivers/leds/led-triggers.c              |  4 ++--
 drivers/leds/leds-adp5520.c              |  2 +-
 drivers/leds/leds-an30259a.c             |  8 +++----
 drivers/leds/leds-apu.c                  |  6 ++---
 drivers/leds/leds-ariel.c                |  8 +++----
 drivers/leds/leds-asic3.c                |  2 +-
 drivers/leds/leds-aw2013.c               |  6 ++---
 drivers/leds/leds-bcm6328.c              | 14 +++++------
 drivers/leds/leds-bcm6358.c              | 14 +++++------
 drivers/leds/leds-bd2802.c               | 14 +++++------
 drivers/leds/leds-clevo-mail.c           |  6 ++---
 drivers/leds/leds-cobalt-qube.c          |  2 +-
 drivers/leds/leds-cpcap.c                | 10 ++++----
 drivers/leds/leds-da903x.c               |  4 ++--
 drivers/leds/leds-da9052.c               |  4 ++--
 drivers/leds/leds-dac124s085.c           |  2 +-
 drivers/leds/leds-el15203000.c           |  4 ++--
 drivers/leds/leds-gpio.c                 |  4 ++--
 drivers/leds/leds-is31fl319x.c           |  2 +-
 drivers/leds/leds-lm3530.c               |  4 ++--
 drivers/leds/leds-lm3532.c               |  8 +++----
 drivers/leds/leds-lm3533.c               |  4 ++--
 drivers/leds/leds-lm3692x.c              |  2 +-
 drivers/leds/leds-lm3697.c               |  6 ++---
 drivers/leds/leds-lp3952.c               |  4 ++--
 drivers/leds/leds-lt3593.c               |  2 +-
 drivers/leds/leds-max77650.c             |  4 ++--
 drivers/leds/leds-menf21bmc.c            |  2 +-
 drivers/leds/leds-mlxcpld.c              | 22 ++++++++---------
 drivers/leds/leds-mlxreg.c               | 10 ++++----
 drivers/leds/leds-mt6323.c               |  2 +-
 drivers/leds/leds-netxbig.c              |  4 ++--
 drivers/leds/leds-nic78bx.c              |  2 +-
 drivers/leds/leds-ns2.c                  |  4 ++--
 drivers/leds/leds-ot200.c                |  2 +-
 drivers/leds/leds-pca9532.c              |  6 ++---
 drivers/leds/leds-pca955x.c              | 30 ++++++++++++------------
 drivers/leds/leds-pca963x.c              |  4 ++--
 drivers/leds/leds-pm8058.c               |  8 +++----
 drivers/leds/leds-powernv.c              | 12 +++++-----
 drivers/leds/leds-pwm.c                  |  2 +-
 drivers/leds/leds-rb532.c                |  2 +-
 drivers/leds/leds-regulator.c            |  2 +-
 drivers/leds/leds-sc27xx-bltc.c          |  6 ++---
 drivers/leds/leds-spi-byte.c             |  2 +-
 drivers/leds/leds-ss4200.c               | 12 +++++-----
 drivers/leds/leds-sunfire.c              |  2 +-
 drivers/leds/leds-syscon.c               |  2 +-
 drivers/leds/leds-tca6507.c              |  8 +++----
 drivers/leds/leds-wm831x-status.c        |  8 +++----
 drivers/leds/leds-wm8350.c               |  8 +++----
 drivers/leds/simple/simatic-ipc-leds.c   | 10 ++++----
 drivers/leds/trigger/ledtrig-activity.c  |  2 +-
 drivers/leds/trigger/ledtrig-backlight.c |  4 ++--
 drivers/leds/trigger/ledtrig-camera.c    |  4 ++--
 drivers/leds/trigger/ledtrig-cpu.c       |  4 ++--
 drivers/leds/trigger/ledtrig-gpio.c      |  4 ++--
 drivers/leds/trigger/ledtrig-heartbeat.c |  4 ++--
 drivers/leds/trigger/ledtrig-netdev.c    |  6 ++---
 drivers/leds/trigger/ledtrig-oneshot.c   |  6 ++---
 drivers/leds/trigger/ledtrig-panic.c     |  2 +-
 drivers/leds/trigger/ledtrig-pattern.c   |  2 +-
 drivers/leds/trigger/ledtrig-timer.c     |  2 +-
 drivers/leds/trigger/ledtrig-transient.c |  6 ++---
 drivers/leds/trigger/ledtrig-tty.c       |  4 ++--
 74 files changed, 217 insertions(+), 217 deletions(-)

diff --git a/drivers/leds/blink/leds-lgm-sso.c b/drivers/leds/blink/leds-lgm-sso.c
index 6f270c0272fb..26c17c64bd4f 100644
--- a/drivers/leds/blink/leds-lgm-sso.c
+++ b/drivers/leds/blink/leds-lgm-sso.c
@@ -51,7 +51,7 @@
 #define SSO_LED_MAX_NUM			SZ_32
 #define MAX_FREQ_RANK			10
 #define DEF_GPTC_CLK_RATE		200000000
-#define SSO_DEF_BRIGHTNESS		LED_HALF
+#define SSO_DEF_BRIGHTNESS		127
 #define DATA_CLK_EDGE			0 /* 0-rising, 1-falling */
 
 static const u32 freq_div_tbl[] = {4000, 2000, 1000, 800};
@@ -244,7 +244,7 @@ static void sso_led_brightness_set(struct led_classdev *led_cdev,
 	desc->brightness = brightness;
 	regmap_write(priv->mmap, DUTY_CYCLE(desc->pin), brightness);
 
-	if (brightness == LED_OFF)
+	if (brightness == 0)
 		val = 0;
 	else
 		val = 1;
@@ -360,7 +360,7 @@ static int sso_create_led(struct sso_led_priv *priv, struct sso_led *led,
 	led->cdev.brightness_set = sso_led_brightness_set;
 	led->cdev.brightness_get = sso_led_brightness_get;
 	led->cdev.brightness = desc->brightness;
-	led->cdev.max_brightness = LED_FULL;
+	led->cdev.max_brightness = 255;
 
 	if (desc->retain_state_shutdown)
 		led->cdev.flags |= LED_RETAIN_AT_SHUTDOWN;
@@ -696,7 +696,7 @@ __sso_led_dt_parse(struct sso_led_priv *priv, struct fwnode_handle *fw_ssoled)
 
 		if (!fwnode_property_read_string(fwnode_child, "default-state", &tmp)) {
 			if (!strcmp(tmp, "on"))
-				desc->brightness = LED_FULL;
+				desc->brightness = 255;
 		}
 
 		ret = sso_create_led(priv, led, fwnode_child);
diff --git a/drivers/leds/flash/leds-ktd2692.c b/drivers/leds/flash/leds-ktd2692.c
index ed1f20a58bf6..30937156d156 100644
--- a/drivers/leds/flash/leds-ktd2692.c
+++ b/drivers/leds/flash/leds-ktd2692.c
@@ -161,7 +161,7 @@ static int ktd2692_led_brightness_set(struct led_classdev *led_cdev,
 
 	mutex_lock(&led->lock);
 
-	if (brightness == LED_OFF) {
+	if (brightness == 0) {
 		led->mode = KTD2692_MODE_DISABLE;
 		gpiod_direction_output(led->aux_gpio, KTD2692_LOW);
 	} else {
@@ -199,7 +199,7 @@ static int ktd2692_led_flash_strobe_set(struct led_classdev_flash *fled_cdev,
 
 	ktd2692_expresswire_write(led, led->mode | KTD2692_REG_MODE_BASE);
 
-	fled_cdev->led_cdev.brightness = LED_OFF;
+	fled_cdev->led_cdev.brightness = 0;
 	led->mode = KTD2692_MODE_DISABLE;
 
 	mutex_unlock(&led->lock);
diff --git a/drivers/leds/flash/leds-lm3601x.c b/drivers/leds/flash/leds-lm3601x.c
index d0e1d4814042..0edcb56a8e8d 100644
--- a/drivers/leds/flash/leds-lm3601x.c
+++ b/drivers/leds/flash/leds-lm3601x.c
@@ -185,9 +185,9 @@ static int lm3601x_brightness_set(struct led_classdev *cdev,
 	else
 		led_mode_val = LM3601X_MODE_IR_DRV;
 
-	if (brightness == LED_OFF) {
+	if (brightness == 0) {
 		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
-					led_mode_val, LED_OFF);
+					led_mode_val, 0);
 		goto out;
 	}
 
@@ -232,7 +232,7 @@ static int lm3601x_strobe_set(struct led_classdev_flash *fled_cdev,
 					LM3601X_MODE_STROBE);
 	else
 		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
-					LM3601X_MODE_STROBE, LED_OFF);
+					LM3601X_MODE_STROBE, 0);
 
 	ret = lm3601x_read_faults(led);
 out:
@@ -252,9 +252,9 @@ static int lm3601x_flash_brightness_set(struct led_classdev_flash *fled_cdev,
 	if (ret < 0)
 		goto out;
 
-	if (brightness == LED_OFF) {
+	if (brightness == 0) {
 		ret = regmap_update_bits(led->regmap, LM3601X_ENABLE_REG,
-					LM3601X_MODE_STROBE, LED_OFF);
+					LM3601X_MODE_STROBE, 0);
 		goto out;
 	}
 
diff --git a/drivers/leds/flash/leds-mt6360.c b/drivers/leds/flash/leds-mt6360.c
index e1066a52d2d2..69145a154b53 100644
--- a/drivers/leds/flash/leds-mt6360.c
+++ b/drivers/leds/flash/leds-mt6360.c
@@ -402,7 +402,7 @@ static int mt6360_isnk_init_default_state(struct mt6360_led *led)
 		return ret;
 
 	if (!(regval & MT6360_ISNK_ENMASK(led->led_no)))
-		level = LED_OFF;
+		level = 0;
 
 	switch (led->default_state) {
 	case STATE_ON:
@@ -412,7 +412,7 @@ static int mt6360_isnk_init_default_state(struct mt6360_led *led)
 		led->isnk.brightness = min(level, led->isnk.max_brightness);
 		break;
 	default:
-		led->isnk.brightness = LED_OFF;
+		led->isnk.brightness = 0;
 	}
 
 	return mt6360_isnk_brightness_set(&led->isnk, led->isnk.brightness);
@@ -440,7 +440,7 @@ static int mt6360_flash_init_default_state(struct mt6360_led *led)
 	if ((regval & enable_mask) == enable_mask)
 		level += 1;
 	else
-		level = LED_OFF;
+		level = 0;
 
 	switch (led->default_state) {
 	case STATE_ON:
@@ -451,7 +451,7 @@ static int mt6360_flash_init_default_state(struct mt6360_led *led)
 			min(level, flash->led_cdev.max_brightness);
 		break;
 	default:
-		flash->led_cdev.brightness = LED_OFF;
+		flash->led_cdev.brightness = 0;
 	}
 
 	return mt6360_torch_brightness_set(&flash->led_cdev,
@@ -542,7 +542,7 @@ static int mt6360_led_register(struct device *parent, struct mt6360_led *led,
 
 	switch (led->led_no) {
 	case MT6360_VIRTUAL_MULTICOLOR:
-		ret = mt6360_mc_brightness_set(&led->mc.led_cdev, LED_OFF);
+		ret = mt6360_mc_brightness_set(&led->mc.led_cdev, 0);
 		if (ret) {
 			dev_err(parent,
 				"Failed to init multicolor brightness\n");
diff --git a/drivers/leds/flash/leds-rt4505.c b/drivers/leds/flash/leds-rt4505.c
index ee129ab7255d..d92899347928 100644
--- a/drivers/leds/flash/leds-rt4505.c
+++ b/drivers/leds/flash/leds-rt4505.c
@@ -59,7 +59,7 @@ static int rt4505_torch_brightness_set(struct led_classdev *lcdev,
 
 	mutex_lock(&priv->lock);
 
-	if (level != LED_OFF) {
+	if (level != 0) {
 		ret = regmap_update_bits(priv->regmap,
 					 RT4505_REG_ILED, RT4505_ITORCH_MASK,
 					 (level - 1) << RT4505_ITORCH_SHIFT);
@@ -90,19 +90,19 @@ static enum led_brightness rt4505_torch_brightness_get(
 	ret = regmap_read(priv->regmap, RT4505_REG_ENABLE, &val);
 	if (ret) {
 		dev_err(lcdev->dev, "Failed to get LED enable\n");
-		ret = LED_OFF;
+		ret = 0;
 		goto unlock;
 	}
 
 	if ((val & RT4505_ENABLE_MASK) != RT4505_TORCH_SET) {
-		ret = LED_OFF;
+		ret = 0;
 		goto unlock;
 	}
 
 	ret = regmap_read(priv->regmap, RT4505_REG_ILED, &val);
 	if (ret) {
 		dev_err(lcdev->dev, "Failed to get LED brightness\n");
-		ret = LED_OFF;
+		ret = 0;
 		goto unlock;
 	}
 
diff --git a/drivers/leds/flash/leds-rt8515.c b/drivers/leds/flash/leds-rt8515.c
index 44904fdee3cc..e9eb5f57fe50 100644
--- a/drivers/leds/flash/leds-rt8515.c
+++ b/drivers/leds/flash/leds-rt8515.c
@@ -95,7 +95,7 @@ static int rt8515_led_brightness_set(struct led_classdev *led,
 
 	mutex_lock(&rt->lock);
 
-	if (brightness == LED_OFF) {
+	if (brightness == 0) {
 		/* Off */
 		rt8515_gpio_led_off(rt);
 	} else if (brightness < RT8515_TORCH_MAX) {
@@ -132,7 +132,7 @@ static int rt8515_led_flash_strobe_set(struct led_classdev_flash *fled,
 		rt8515_gpio_led_off(rt);
 	}
 
-	fled->led_cdev.brightness = LED_OFF;
+	fled->led_cdev.brightness = 0;
 	/* After this the torch LED will be disabled */
 
 	mutex_unlock(&rt->lock);
diff --git a/drivers/leds/flash/leds-sgm3140.c b/drivers/leds/flash/leds-sgm3140.c
index f4f831570f11..4c36488a33bb 100644
--- a/drivers/leds/flash/leds-sgm3140.c
+++ b/drivers/leds/flash/leds-sgm3140.c
@@ -101,7 +101,7 @@ static int sgm3140_brightness_set(struct led_classdev *led_cdev,
 {
 	struct led_classdev_flash *fled_cdev = lcdev_to_flcdev(led_cdev);
 	struct sgm3140 *priv = flcdev_to_sgm3140(fled_cdev);
-	bool enable = brightness == LED_ON;
+	bool enable = brightness == 1;
 	int ret;
 
 	if (priv->enabled == enable)
@@ -241,7 +241,7 @@ static int sgm3140_probe(struct platform_device *pdev)
 	fled_cdev->ops = &sgm3140_flash_ops;
 
 	led_cdev->brightness_set_blocking = sgm3140_brightness_set;
-	led_cdev->max_brightness = LED_ON;
+	led_cdev->max_brightness = 1;
 	led_cdev->flags |= LED_DEV_CAP_FLASH;
 
 	sgm3140_init_flash_timeout(priv);
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 6a8ea94834fa..786132946a10 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -53,7 +53,7 @@ static ssize_t brightness_store(struct device *dev,
 	if (ret)
 		goto unlock;
 
-	if (state == LED_OFF)
+	if (state == 0)
 		led_trigger_remove(led_cdev);
 	led_set_brightness(led_cdev, state);
 	flush_work(&led_cdev->set_brightness_work);
@@ -405,7 +405,7 @@ int led_classdev_register_ext(struct device *parent,
 	up_write(&leds_list_lock);
 
 	if (!led_cdev->max_brightness)
-		led_cdev->max_brightness = LED_FULL;
+		led_cdev->max_brightness = 255;
 
 	led_update_brightness(led_cdev);
 
@@ -448,7 +448,7 @@ void led_classdev_unregister(struct led_classdev *led_cdev)
 	led_stop_software_blink(led_cdev);
 
 	if (!(led_cdev->flags & LED_RETAIN_AT_SHUTDOWN))
-		led_set_brightness(led_cdev, LED_OFF);
+		led_set_brightness(led_cdev, 0);
 
 	flush_work(&led_cdev->set_brightness_work);
 
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 4a97cb745788..eb51f9f7d81c 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -64,7 +64,7 @@ static void led_timer_function(struct timer_list *t)
 	unsigned long delay;
 
 	if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) {
-		led_set_brightness_nosleep(led_cdev, LED_OFF);
+		led_set_brightness_nosleep(led_cdev, 0);
 		clear_bit(LED_BLINK_SW, &led_cdev->work_flags);
 		return;
 	}
@@ -89,7 +89,7 @@ static void led_timer_function(struct timer_list *t)
 		 * to restore it when the delay_off period is over.
 		 */
 		led_cdev->blink_brightness = brightness;
-		brightness = LED_OFF;
+		brightness = 0;
 		delay = led_cdev->blink_delay_off;
 	}
 
@@ -121,7 +121,7 @@ static void set_brightness_delayed(struct work_struct *ws)
 	int ret = 0;
 
 	if (test_and_clear_bit(LED_BLINK_DISABLE, &led_cdev->work_flags)) {
-		led_cdev->delayed_set_value = LED_OFF;
+		led_cdev->delayed_set_value = 0;
 		led_stop_software_blink(led_cdev);
 	}
 
@@ -154,7 +154,7 @@ static void led_set_software_blink(struct led_classdev *led_cdev,
 
 	/* never on - just set to off */
 	if (!delay_on) {
-		led_set_brightness_nosleep(led_cdev, LED_OFF);
+		led_set_brightness_nosleep(led_cdev, 0);
 		return;
 	}
 
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 072491d3e17b..17fba1ad0d3d 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -185,7 +185,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
 		led_cdev->trigger = NULL;
 		led_cdev->trigger_data = NULL;
 		led_cdev->activated = false;
-		led_set_brightness(led_cdev, LED_OFF);
+		led_set_brightness(led_cdev, 0);
 	}
 	if (trig) {
 		spin_lock(&trig->leddev_list_lock);
@@ -231,7 +231,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
 	synchronize_rcu();
 	led_cdev->trigger = NULL;
 	led_cdev->trigger_data = NULL;
-	led_set_brightness(led_cdev, LED_OFF);
+	led_set_brightness(led_cdev, 0);
 	kfree(event);
 
 	return ret;
diff --git a/drivers/leds/leds-adp5520.c b/drivers/leds/leds-adp5520.c
index 5a0cc7af2df8..0cc92acffbed 100644
--- a/drivers/leds/leds-adp5520.c
+++ b/drivers/leds/leds-adp5520.c
@@ -125,7 +125,7 @@ static int adp5520_led_probe(struct platform_device *pdev)
 		led_dat->cdev.name = cur_led->name;
 		led_dat->cdev.default_trigger = cur_led->default_trigger;
 		led_dat->cdev.brightness_set_blocking = adp5520_led_set;
-		led_dat->cdev.brightness = LED_OFF;
+		led_dat->cdev.brightness = 0;
 
 		if (cur_led->flags & ADP5520_FLAG_LED_MASK)
 			led_dat->flags = cur_led->flags;
diff --git a/drivers/leds/leds-an30259a.c b/drivers/leds/leds-an30259a.c
index a0df1fb28774..8df45d78418b 100644
--- a/drivers/leds/leds-an30259a.c
+++ b/drivers/leds/leds-an30259a.c
@@ -93,7 +93,7 @@ static int an30259a_brightness_set(struct led_classdev *cdev,
 		goto error;
 
 	switch (brightness) {
-	case LED_OFF:
+	case 0:
 		led_on &= ~AN30259A_LED_EN(led->num);
 		led_on &= ~AN30259A_LED_SLOPE(led->num);
 		led->sloping = false;
@@ -262,7 +262,7 @@ static void an30259a_init_default_state(struct an30259a_led *led)
 
 	switch (led->default_state) {
 	case STATE_ON:
-		led->cdev.brightness = LED_FULL;
+		led->cdev.brightness = 255;
 		break;
 	case STATE_KEEP:
 		err = regmap_read(chip->regmap, AN30259A_REG_LED_ON, &led_on);
@@ -270,14 +270,14 @@ static void an30259a_init_default_state(struct an30259a_led *led)
 			break;
 
 		if (!(led_on & AN30259A_LED_EN(led->num))) {
-			led->cdev.brightness = LED_OFF;
+			led->cdev.brightness = 0;
 			break;
 		}
 		regmap_read(chip->regmap, AN30259A_REG_LEDCC(led->num),
 			    &led->cdev.brightness);
 		break;
 	default:
-		led->cdev.brightness = LED_OFF;
+		led->cdev.brightness = 0;
 	}
 
 	an30259a_brightness_set(&led->cdev, led->cdev.brightness);
diff --git a/drivers/leds/leds-apu.c b/drivers/leds/leds-apu.c
index c409b80c236d..172f86daab3b 100644
--- a/drivers/leds/leds-apu.c
+++ b/drivers/leds/leds-apu.c
@@ -77,9 +77,9 @@ struct apu_led_pdata {
 static struct apu_led_pdata *apu_led;
 
 static const struct apu_led_profile apu1_led_profile[] = {
-	{ "apu:green:1", LED_ON,  APU1_FCH_GPIO_BASE + 0 * APU1_IOSIZE },
-	{ "apu:green:2", LED_OFF, APU1_FCH_GPIO_BASE + 1 * APU1_IOSIZE },
-	{ "apu:green:3", LED_OFF, APU1_FCH_GPIO_BASE + 2 * APU1_IOSIZE },
+	{ "apu:green:1", 1,  APU1_FCH_GPIO_BASE + 0 * APU1_IOSIZE },
+	{ "apu:green:2", 0, APU1_FCH_GPIO_BASE + 1 * APU1_IOSIZE },
+	{ "apu:green:3", 0, APU1_FCH_GPIO_BASE + 2 * APU1_IOSIZE },
 };
 
 static const struct dmi_system_id apu_led_dmi_table[] __initconst = {
diff --git a/drivers/leds/leds-ariel.c b/drivers/leds/leds-ariel.c
index 49e1bddaa15e..6a6cfdf7c7df 100644
--- a/drivers/leds/leds-ariel.c
+++ b/drivers/leds/leds-ariel.c
@@ -37,12 +37,12 @@ static enum led_brightness ariel_led_get(struct led_classdev *led_cdev)
 	unsigned int led_status = 0;
 
 	if (regmap_read(led->ec_ram, led->ec_index, &led_status))
-		return LED_OFF;
+		return 0;
 
 	if (led_status == EC_LED_STILL)
-		return LED_FULL;
+		return 255;
 	else
-		return LED_OFF;
+		return 0;
 }
 
 static void ariel_led_set(struct led_classdev *led_cdev,
@@ -50,7 +50,7 @@ static void ariel_led_set(struct led_classdev *led_cdev,
 {
 	struct ariel_led *led = led_cdev_to_ariel_led(led_cdev);
 
-	if (brightness == LED_OFF)
+	if (brightness == 0)
 		regmap_write(led->ec_ram, led->ec_index, EC_LED_OFF);
 	else
 		regmap_write(led->ec_ram, led->ec_index, EC_LED_STILL);
diff --git a/drivers/leds/leds-asic3.c b/drivers/leds/leds-asic3.c
index 8cbc1b8bafa5..53b7b8551808 100644
--- a/drivers/leds/leds-asic3.c
+++ b/drivers/leds/leds-asic3.c
@@ -42,7 +42,7 @@ static void brightness_set(struct led_classdev *cdev,
 	u32 timebase;
 	unsigned int base;
 
-	timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4);
+	timebase = (value == 0) ? 0 : (LED_EN|0x4);
 
 	base = led_n_base[cell->id];
 	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32);
diff --git a/drivers/leds/leds-aw2013.c b/drivers/leds/leds-aw2013.c
index 80d937454aee..4b3043ed1d69 100644
--- a/drivers/leds/leds-aw2013.c
+++ b/drivers/leds/leds-aw2013.c
@@ -206,7 +206,7 @@ static int aw2013_blink_set(struct led_classdev *cdev,
 	}
 
 	if (!led->cdev.brightness) {
-		led->cdev.brightness = LED_FULL;
+		led->cdev.brightness = 255;
 		ret = aw2013_brightness_set(&led->cdev, led->cdev.brightness);
 		if (ret)
 			return ret;
@@ -214,8 +214,8 @@ static int aw2013_blink_set(struct led_classdev *cdev,
 
 	/* Never on - just set to off */
 	if (!*delay_on) {
-		led->cdev.brightness = LED_OFF;
-		return aw2013_brightness_set(&led->cdev, LED_OFF);
+		led->cdev.brightness = 0;
+		return aw2013_brightness_set(&led->cdev, 0);
 	}
 
 	mutex_lock(&led->chip->mutex);
diff --git a/drivers/leds/leds-bcm6328.c b/drivers/leds/leds-bcm6328.c
index 2d4d87957a30..7a2d26429653 100644
--- a/drivers/leds/leds-bcm6328.c
+++ b/drivers/leds/leds-bcm6328.c
@@ -138,8 +138,8 @@ static void bcm6328_led_set(struct led_classdev *led_cdev,
 	led->blink_leds[1] &= ~BIT(led->pin);
 
 	/* Set LED on/off */
-	if ((led->active_low && value == LED_OFF) ||
-	    (!led->active_low && value != LED_OFF))
+	if ((led->active_low && value == 0) ||
+	    (!led->active_low && value != 0))
 		bcm6328_led_mode(led, BCM6328_LED_MODE_ON);
 	else
 		bcm6328_led_mode(led, BCM6328_LED_MODE_OFF);
@@ -348,7 +348,7 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
 
 	if (!of_property_read_string(nc, "default-state", &state)) {
 		if (!strcmp(state, "on")) {
-			led->cdev.brightness = LED_FULL;
+			led->cdev.brightness = 255;
 		} else if (!strcmp(state, "keep")) {
 			void __iomem *mode;
 			unsigned long val, shift;
@@ -364,14 +364,14 @@ static int bcm6328_led(struct device *dev, struct device_node *nc, u32 reg,
 			val &= BCM6328_LED_MODE_MASK;
 			if ((led->active_low && val == BCM6328_LED_MODE_OFF) ||
 			    (!led->active_low && val == BCM6328_LED_MODE_ON))
-				led->cdev.brightness = LED_FULL;
+				led->cdev.brightness = 255;
 			else
-				led->cdev.brightness = LED_OFF;
+				led->cdev.brightness = 0;
 		} else {
-			led->cdev.brightness = LED_OFF;
+			led->cdev.brightness = 0;
 		}
 	} else {
-		led->cdev.brightness = LED_OFF;
+		led->cdev.brightness = 0;
 	}
 
 	bcm6328_led_set(&led->cdev, led->cdev.brightness);
diff --git a/drivers/leds/leds-bcm6358.c b/drivers/leds/leds-bcm6358.c
index 9d2e487fa08a..955fdd4e0967 100644
--- a/drivers/leds/leds-bcm6358.c
+++ b/drivers/leds/leds-bcm6358.c
@@ -82,8 +82,8 @@ static void bcm6358_led_set(struct led_classdev *led_cdev,
 	spin_lock_irqsave(led->lock, flags);
 	bcm6358_led_busy(led->mem);
 	val = bcm6358_led_read(led->mem + BCM6358_REG_MODE);
-	if ((led->active_low && value == LED_OFF) ||
-	    (!led->active_low && value != LED_OFF))
+	if ((led->active_low && value == 0) ||
+	    (!led->active_low && value != 0))
 		val |= BIT(led->pin);
 	else
 		val &= ~(BIT(led->pin));
@@ -112,21 +112,21 @@ static int bcm6358_led(struct device *dev, struct device_node *nc, u32 reg,
 
 	if (!of_property_read_string(nc, "default-state", &state)) {
 		if (!strcmp(state, "on")) {
-			led->cdev.brightness = LED_FULL;
+			led->cdev.brightness = 255;
 		} else if (!strcmp(state, "keep")) {
 			unsigned long val;
 			val = bcm6358_led_read(led->mem + BCM6358_REG_MODE);
 			val &= BIT(led->pin);
 			if ((led->active_low && !val) ||
 			    (!led->active_low && val))
-				led->cdev.brightness = LED_FULL;
+				led->cdev.brightness = 255;
 			else
-				led->cdev.brightness = LED_OFF;
+				led->cdev.brightness = 0;
 		} else {
-			led->cdev.brightness = LED_OFF;
+			led->cdev.brightness = 0;
 		}
 	} else {
-		led->cdev.brightness = LED_OFF;
+		led->cdev.brightness = 0;
 	}
 
 	bcm6358_led_set(&led->cdev, led->cdev.brightness);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
index 8bbaef5a2986..096b8c86c0ea 100644
--- a/drivers/leds/leds-bd2802.c
+++ b/drivers/leds/leds-bd2802.c
@@ -522,7 +522,7 @@ static int bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
 		container_of(led_cdev, struct bd2802_led, cdev_##name);	\
 	led->led_id = id;						\
 	led->color = clr;						\
-	if (value == LED_OFF) {						\
+	if (value == 0) {						\
 		led->state = BD2802_OFF;				\
 		bd2802_turn_off(led, led->led_id, led->color);		\
 	} else {							\
@@ -557,7 +557,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	int ret;
 
 	led->cdev_led1r.name = "led1_R";
-	led->cdev_led1r.brightness = LED_OFF;
+	led->cdev_led1r.brightness = 0;
 	led->cdev_led1r.brightness_set_blocking = bd2802_set_led1r_brightness;
 	led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
 
@@ -569,7 +569,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	}
 
 	led->cdev_led1g.name = "led1_G";
-	led->cdev_led1g.brightness = LED_OFF;
+	led->cdev_led1g.brightness = 0;
 	led->cdev_led1g.brightness_set_blocking = bd2802_set_led1g_brightness;
 	led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
 
@@ -581,7 +581,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	}
 
 	led->cdev_led1b.name = "led1_B";
-	led->cdev_led1b.brightness = LED_OFF;
+	led->cdev_led1b.brightness = 0;
 	led->cdev_led1b.brightness_set_blocking = bd2802_set_led1b_brightness;
 	led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
 
@@ -593,7 +593,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	}
 
 	led->cdev_led2r.name = "led2_R";
-	led->cdev_led2r.brightness = LED_OFF;
+	led->cdev_led2r.brightness = 0;
 	led->cdev_led2r.brightness_set_blocking = bd2802_set_led2r_brightness;
 	led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
 
@@ -605,7 +605,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	}
 
 	led->cdev_led2g.name = "led2_G";
-	led->cdev_led2g.brightness = LED_OFF;
+	led->cdev_led2g.brightness = 0;
 	led->cdev_led2g.brightness_set_blocking = bd2802_set_led2g_brightness;
 	led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
 
@@ -617,7 +617,7 @@ static int bd2802_register_led_classdev(struct bd2802_led *led)
 	}
 
 	led->cdev_led2b.name = "led2_B";
-	led->cdev_led2b.brightness = LED_OFF;
+	led->cdev_led2b.brightness = 0;
 	led->cdev_led2b.brightness_set_blocking = bd2802_set_led2b_brightness;
 	led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
 	led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index f512e99b976b..24e985539b18 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -97,9 +97,9 @@ static void clevo_mail_led_set(struct led_classdev *led_cdev,
 {
 	i8042_lock_chip();
 
-	if (value == LED_OFF)
+	if (value == 0)
 		i8042_command(NULL, CLEVO_MAIL_LED_OFF);
-	else if (value <= LED_HALF)
+	else if (value <= 127)
 		i8042_command(NULL, CLEVO_MAIL_LED_BLINK_0_5HZ);
 	else
 		i8042_command(NULL, CLEVO_MAIL_LED_BLINK_1HZ);
@@ -210,7 +210,7 @@ static void __exit clevo_mail_led_exit(void)
 	platform_device_unregister(pdev);
 	platform_driver_unregister(&clevo_mail_led_driver);
 
-	clevo_mail_led_set(NULL, LED_OFF);
+	clevo_mail_led_set(NULL, 0);
 }
 
 module_init(clevo_mail_led_init);
diff --git a/drivers/leds/leds-cobalt-qube.c b/drivers/leds/leds-cobalt-qube.c
index ef22e1e94048..4af123a10342 100644
--- a/drivers/leds/leds-cobalt-qube.c
+++ b/drivers/leds/leds-cobalt-qube.c
@@ -29,7 +29,7 @@ static void qube_front_led_set(struct led_classdev *led_cdev,
 
 static struct led_classdev qube_front_led = {
 	.name			= "qube::front",
-	.brightness		= LED_FULL,
+	.brightness		= 255,
 	.brightness_set		= qube_front_led_set,
 	.default_trigger	= "default-on",
 };
diff --git a/drivers/leds/leds-cpcap.c b/drivers/leds/leds-cpcap.c
index 7d41ce8c9bb1..8f7eba98a636 100644
--- a/drivers/leds/leds-cpcap.c
+++ b/drivers/leds/leds-cpcap.c
@@ -108,13 +108,13 @@ static int cpcap_led_set(struct led_classdev *ledc, enum led_brightness value)
 
 	mutex_lock(&led->update_lock);
 
-	if (value > LED_OFF) {
+	if (value > 0) {
 		err = cpcap_led_set_power(led, true);
 		if (err)
 			goto exit;
 	}
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		/* Avoid HW issue by turning off current before duty cycle */
 		err = regmap_update_bits(led->regmap,
 			led->info->reg, led->info->mask, CPCAP_LED_NO_CURRENT);
@@ -123,9 +123,9 @@ static int cpcap_led_set(struct led_classdev *ledc, enum led_brightness value)
 			goto exit;
 		}
 
-		brightness = cpcap_led_val(value, LED_OFF);
+		brightness = cpcap_led_val(value, 0);
 	} else {
-		brightness = cpcap_led_val(value, LED_ON);
+		brightness = cpcap_led_val(value, 1);
 	}
 
 	err = regmap_update_bits(led->regmap, led->info->reg, led->info->mask,
@@ -135,7 +135,7 @@ static int cpcap_led_set(struct led_classdev *ledc, enum led_brightness value)
 		goto exit;
 	}
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		err = cpcap_led_set_power(led, false);
 		if (err)
 			goto exit;
diff --git a/drivers/leds/leds-da903x.c b/drivers/leds/leds-da903x.c
index 2b5fb00438a2..a09446591add 100644
--- a/drivers/leds/leds-da903x.c
+++ b/drivers/leds/leds-da903x.c
@@ -66,7 +66,7 @@ static int da903x_led_set(struct led_classdev *led_cdev,
 	case DA9034_ID_LED_1:
 	case DA9034_ID_LED_2:
 		offset = DA9034_LED_OFFSET(led->id);
-		val = (value * 0x5f / LED_FULL) & 0x7f;
+		val = (value * 0x5f / 255) & 0x7f;
 		val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
 		ret = da903x_write(led->master, DA9034_LED1_CONTROL + offset,
 				   val);
@@ -104,7 +104,7 @@ static int da903x_led_probe(struct platform_device *pdev)
 	led->cdev.name = pdata->name;
 	led->cdev.default_trigger = pdata->default_trigger;
 	led->cdev.brightness_set_blocking = da903x_led_set;
-	led->cdev.brightness = LED_OFF;
+	led->cdev.brightness = 0;
 
 	led->id = id;
 	led->flags = pdata->flags;
diff --git a/drivers/leds/leds-da9052.c b/drivers/leds/leds-da9052.c
index 04060c862bf9..69b72892b540 100644
--- a/drivers/leds/leds-da9052.c
+++ b/drivers/leds/leds-da9052.c
@@ -119,7 +119,7 @@ static int da9052_led_probe(struct platform_device *pdev)
 	for (i = 0; i < pled->num_leds; i++) {
 		led[i].cdev.name = pled->leds[i].name;
 		led[i].cdev.brightness_set_blocking = da9052_led_set;
-		led[i].cdev.brightness = LED_OFF;
+		led[i].cdev.brightness = 0;
 		led[i].cdev.max_brightness = DA9052_MAX_BRIGHTNESS;
 		led[i].led_index = pled->leds[i].flags;
 		led[i].da9052 = dev_get_drvdata(pdev->dev.parent);
@@ -169,7 +169,7 @@ static int da9052_led_remove(struct platform_device *pdev)
 	pled = pdata->pled;
 
 	for (i = 0; i < pled->num_leds; i++) {
-		da9052_set_led_brightness(&led[i], LED_OFF);
+		da9052_set_led_brightness(&led[i], 0);
 		led_classdev_unregister(&led[i].cdev);
 	}
 
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
index 20dc9b9d7dea..582d9a070115 100644
--- a/drivers/leds/leds-dac124s085.c
+++ b/drivers/leds/leds-dac124s085.c
@@ -66,7 +66,7 @@ static int dac124s085_probe(struct spi_device *spi)
 		snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
 		mutex_init(&led->mutex);
 		led->ldev.name = led->name;
-		led->ldev.brightness = LED_OFF;
+		led->ldev.brightness = 0;
 		led->ldev.max_brightness = 0xfff;
 		led->ldev.brightness_set_blocking = dac124s085_set_brightness;
 		ret = led_classdev_register(&spi->dev, &led->ldev);
diff --git a/drivers/leds/leds-el15203000.c b/drivers/leds/leds-el15203000.c
index f9eb59a25570..b1a7ceaca434 100644
--- a/drivers/leds/leds-el15203000.c
+++ b/drivers/leds/leds-el15203000.c
@@ -133,7 +133,7 @@ static int el15203000_set_blocking(struct led_classdev *ldev,
 {
 	struct el15203000_led *led = to_el15203000_led(ldev);
 
-	return el15203000_cmd(led, brightness == LED_OFF ? EL_OFF : EL_ON);
+	return el15203000_cmd(led, brightness == 0 ? EL_OFF : EL_ON);
 }
 
 static int el15203000_pattern_set_S(struct led_classdev *ldev,
@@ -256,7 +256,7 @@ static int el15203000_probe_dt(struct el15203000 *priv)
 		}
 
 		led->priv			  = priv;
-		led->ldev.max_brightness	  = LED_ON;
+		led->ldev.max_brightness	  = 1;
 		led->ldev.brightness_set_blocking = el15203000_set_blocking;
 
 		if (led->reg == 'S') {
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 092eb59a7d32..ac363efc37bc 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -38,7 +38,7 @@ static void gpio_led_set(struct led_classdev *led_cdev,
 	struct gpio_led_data *led_dat = cdev_to_gpio_led_data(led_cdev);
 	int level;
 
-	if (value == LED_OFF)
+	if (value == 0)
 		level = 0;
 	else
 		level = 1;
@@ -292,7 +292,7 @@ static void gpio_led_shutdown(struct platform_device *pdev)
 		struct gpio_led_data *led = &priv->leds[i];
 
 		if (!(led->cdev.flags & LED_RETAIN_AT_SHUTDOWN))
-			gpio_led_set(&led->cdev, LED_OFF);
+			gpio_led_set(&led->cdev, 0);
 	}
 }
 
diff --git a/drivers/leds/leds-is31fl319x.c b/drivers/leds/leds-is31fl319x.c
index 4161b9dd7e48..2a9c8dcc9a2c 100644
--- a/drivers/leds/leds-is31fl319x.c
+++ b/drivers/leds/leds-is31fl319x.c
@@ -140,7 +140,7 @@ static int is31fl319x_brightness_set(struct led_classdev *cdev,
 		ret = regmap_read(is31->regmap, IS31FL319X_PWM(i), &pwm_value);
 		dev_dbg(&is31->client->dev, "%s read %d: ret=%d: %d\n",
 			__func__, i, ret, pwm_value);
-		on = ret >= 0 && pwm_value > LED_OFF;
+		on = ret >= 0 && pwm_value > 0;
 
 		if (i < 3)
 			ctrl1 |= on << i;       /* 0..2 => bit 0..2 */
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c
index e72393534b72..a5358cac5d4d 100644
--- a/drivers/leds/leds-lm3530.c
+++ b/drivers/leds/leds-lm3530.c
@@ -174,7 +174,7 @@ static void lm3530_als_configure(struct lm3530_platform_data *pdata,
 
 	for (i = 0; i < LM3530_ALS_ZB_MAX; i++)
 		als->zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) +
-			als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
+			als_vstep + (i * als_vstep)) * 255) / 1000;
 
 	als->config =
 		(pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
@@ -436,7 +436,7 @@ static int lm3530_probe(struct i2c_client *client,
 	drvdata->mode = pdata->mode;
 	drvdata->client = client;
 	drvdata->pdata = pdata;
-	drvdata->brightness = LED_OFF;
+	drvdata->brightness = 0;
 	drvdata->enable = false;
 	drvdata->led_dev.name = LM3530_LED_DEV;
 	drvdata->led_dev.brightness_set = lm3530_brightness_set;
diff --git a/drivers/leds/leds-lm3532.c b/drivers/leds/leds-lm3532.c
index beb53040e09e..b0671fe4957b 100644
--- a/drivers/leds/leds-lm3532.c
+++ b/drivers/leds/leds-lm3532.c
@@ -354,7 +354,7 @@ static int lm3532_brightness_set(struct led_classdev *led_cdev,
 	mutex_lock(&led->priv->lock);
 
 	if (led->mode == LM3532_ALS_CTRL) {
-		if (brt_val > LED_OFF)
+		if (brt_val > 0)
 			ret = lm3532_led_enable(led);
 		else
 			ret = lm3532_led_disable(led);
@@ -362,7 +362,7 @@ static int lm3532_brightness_set(struct led_classdev *led_cdev,
 		goto unlock;
 	}
 
-	if (brt_val == LED_OFF) {
+	if (brt_val == 0) {
 		ret = lm3532_led_disable(led);
 		goto unlock;
 	}
@@ -459,9 +459,9 @@ static int lm3532_als_configure(struct lm3532_data *priv,
 
 	for (i = 0; i < LM3532_ALS_ZB_MAX; i++) {
 		als->zones_lo[i] = ((als_vmin + als_vstep + (i * als_vstep)) *
-				LED_FULL) / 1000;
+				255) / 1000;
 		als->zones_hi[i] = ((als_vmin + LM3532_ALS_OFFSET_mV +
-				als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
+				als_vstep + (i * als_vstep)) * 255) / 1000;
 
 		zone_reg = LM3532_REG_ZN_0_HI + i * 2;
 		ret = regmap_write(priv->regmap, zone_reg, als->zones_lo[i]);
diff --git a/drivers/leds/leds-lm3533.c b/drivers/leds/leds-lm3533.c
index 43d5970d96aa..7411c528a0d4 100644
--- a/drivers/leds/leds-lm3533.c
+++ b/drivers/leds/leds-lm3533.c
@@ -678,7 +678,7 @@ static int lm3533_led_probe(struct platform_device *pdev)
 	led->cdev.brightness_set_blocking = lm3533_led_set;
 	led->cdev.brightness_get = lm3533_led_get;
 	led->cdev.blink_set = lm3533_led_blink_set;
-	led->cdev.brightness = LED_OFF;
+	led->cdev.brightness = 0;
 	led->cdev.groups = lm3533_led_attribute_groups;
 	led->id = pdev->id;
 
@@ -738,7 +738,7 @@ static void lm3533_led_shutdown(struct platform_device *pdev)
 	dev_dbg(&pdev->dev, "%s\n", __func__);
 
 	lm3533_ctrlbank_disable(&led->cb);
-	lm3533_led_set(&led->cdev, LED_OFF);		/* disable blink */
+	lm3533_led_set(&led->cdev, 0);		/* disable blink */
 }
 
 static struct platform_driver lm3533_led_driver = {
diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c
index afe6fb297855..be5fbed7f428 100644
--- a/drivers/leds/leds-lm3692x.c
+++ b/drivers/leds/leds-lm3692x.c
@@ -440,7 +440,7 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
 	}
 
 	ret = fwnode_property_read_u32(child, "led-max-microamp", &max_cur);
-	led->led_dev.max_brightness = ret ? LED_FULL :
+	led->led_dev.max_brightness = ret ? 255 :
 		lm3692x_max_brightness(led, max_cur);
 
 	init_data.fwnode = child;
diff --git a/drivers/leds/leds-lm3697.c b/drivers/leds/leds-lm3697.c
index a8c9322558cc..9366e0b7fb4d 100644
--- a/drivers/leds/leds-lm3697.c
+++ b/drivers/leds/leds-lm3697.c
@@ -52,7 +52,7 @@
  * @lmu_data: Register and setting values for common code
  * @control_bank: Control bank the LED is associated to. 0 is control bank A
  *		   1 is control bank B
- * @enabled: LED brightness level (or LED_OFF)
+ * @enabled: LED brightness level (or 0)
  * @num_leds: Number of LEDs available
  */
 struct lm3697_led {
@@ -130,7 +130,7 @@ static int lm3697_brightness_set(struct led_classdev *led_cdev,
 
 	mutex_lock(&led->priv->lock);
 
-	if (brt_val == LED_OFF) {
+	if (brt_val == 0) {
 		ret = regmap_update_bits(led->priv->regmap, LM3697_CTRL_ENABLE,
 					 ctrl_en_val, ~ctrl_en_val);
 		if (ret) {
@@ -138,7 +138,7 @@ static int lm3697_brightness_set(struct led_classdev *led_cdev,
 			goto brightness_out;
 		}
 
-		led->enabled = LED_OFF;
+		led->enabled = 0;
 	} else {
 		ret = ti_lmu_common_set_brightness(&led->lmu_data, brt_val);
 		if (ret) {
diff --git a/drivers/leds/leds-lp3952.c b/drivers/leds/leds-lp3952.c
index 6ee9131fbf25..3b65b0206312 100644
--- a/drivers/leds/leds-lp3952.c
+++ b/drivers/leds/leds-lp3952.c
@@ -67,7 +67,7 @@ static int lp3952_set_brightness(struct led_classdev *cdev,
 	dev_dbg(cdev->dev, "Brightness request: %d on %d\n", value,
 		led->channel);
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		lp3952_on_off(priv, led->channel, false);
 		return 0;
 	}
@@ -124,7 +124,7 @@ static int lp3952_register_led_classdev(struct lp3952_led_array *priv)
 			continue;
 
 		priv->leds[i].cdev.name = priv->leds[i].name;
-		priv->leds[i].cdev.brightness = LED_OFF;
+		priv->leds[i].cdev.brightness = 0;
 		priv->leds[i].cdev.max_brightness = LP3952_BRIGHT_MAX;
 		priv->leds[i].cdev.brightness_set_blocking =
 				lp3952_set_brightness;
diff --git a/drivers/leds/leds-lt3593.c b/drivers/leds/leds-lt3593.c
index d0160fde0f94..dd69c190ce10 100644
--- a/drivers/leds/leds-lt3593.c
+++ b/drivers/leds/leds-lt3593.c
@@ -90,7 +90,7 @@ static int lt3593_led_probe(struct platform_device *pdev)
 	}
 
 	led_data->cdev.brightness_set_blocking = lt3593_led_set;
-	led_data->cdev.brightness = state ? LED_FULL : LED_OFF;
+	led_data->cdev.brightness = state ? 255 : 0;
 
 	init_data.fwnode = child;
 	init_data.devicename = LED_LT3593_NAME;
diff --git a/drivers/leds/leds-max77650.c b/drivers/leds/leds-max77650.c
index 1eeac56b0014..5ea67e3c319c 100644
--- a/drivers/leds/leds-max77650.c
+++ b/drivers/leds/leds-max77650.c
@@ -45,14 +45,14 @@ static struct max77650_led *max77650_to_led(struct led_classdev *cdev)
 }
 
 static int max77650_led_brightness_set(struct led_classdev *cdev,
-				       enum led_brightness brightness)
+				       unsigned int brightness)
 {
 	struct max77650_led *led = max77650_to_led(cdev);
 	int val, mask;
 
 	mask = MAX77650_LED_BR_MASK | MAX77650_LED_EN_MASK;
 
-	if (brightness == LED_OFF)
+	if (brightness == 0)
 		val = MAX77650_LED_DISABLE;
 	else
 		val = MAX77650_LED_ENABLE | brightness;
diff --git a/drivers/leds/leds-menf21bmc.c b/drivers/leds/leds-menf21bmc.c
index 6b1b47160602..0203db50cda2 100644
--- a/drivers/leds/leds-menf21bmc.c
+++ b/drivers/leds/leds-menf21bmc.c
@@ -62,7 +62,7 @@ menf21bmc_led_set(struct led_classdev *led_cdev, enum led_brightness value)
 	if (led_val < 0)
 		goto err_out;
 
-	if (value == LED_OFF)
+	if (value == 0)
 		led_val &= ~led->led_bit;
 	else
 		led_val |= led->led_bit;
diff --git a/drivers/leds/leds-mlxcpld.c b/drivers/leds/leds-mlxcpld.c
index 1355c84a2919..93526857e766 100644
--- a/drivers/leds/leds-mlxcpld.c
+++ b/drivers/leds/leds-mlxcpld.c
@@ -131,7 +131,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:fan1:green",
 	},
 	{
-		0x21, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x21, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:fan1:red",
 	},
 	{
@@ -139,7 +139,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:fan2:green",
 	},
 	{
-		0x21, 0x0f, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x21, 0x0f, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:fan2:red",
 	},
 	{
@@ -147,7 +147,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:fan3:green",
 	},
 	{
-		0x22, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x22, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:fan3:red",
 	},
 	{
@@ -155,7 +155,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:fan4:green",
 	},
 	{
-		0x22, 0x0f, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x22, 0x0f, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:fan4:red",
 	},
 	{
@@ -163,7 +163,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:psu:green",
 	},
 	{
-		0x20, 0x0f, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x20, 0x0f, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:psu:red",
 	},
 	{
@@ -171,7 +171,7 @@ static struct mlxcpld_led_profile mlxcpld_led_default_profile[] = {
 		"mlxcpld:status:green",
 	},
 	{
-		0x20, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x20, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:status:red",
 	},
 };
@@ -183,7 +183,7 @@ static struct mlxcpld_led_profile mlxcpld_led_msn2100_profile[] = {
 		"mlxcpld:fan:green",
 	},
 	{
-		0x21, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x21, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:fan:red",
 	},
 	{
@@ -191,7 +191,7 @@ static struct mlxcpld_led_profile mlxcpld_led_msn2100_profile[] = {
 		"mlxcpld:psu1:green",
 	},
 	{
-		0x23, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x23, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:psu1:red",
 	},
 	{
@@ -199,7 +199,7 @@ static struct mlxcpld_led_profile mlxcpld_led_msn2100_profile[] = {
 		"mlxcpld:psu2:green",
 	},
 	{
-		0x23, 0x0f, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x23, 0x0f, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:psu2:red",
 	},
 	{
@@ -207,11 +207,11 @@ static struct mlxcpld_led_profile mlxcpld_led_msn2100_profile[] = {
 		"mlxcpld:status:green",
 	},
 	{
-		0x20, 0xf0, MLXCPLD_LED_RED_STATIC_ON, LED_OFF,
+		0x20, 0xf0, MLXCPLD_LED_RED_STATIC_ON, 0,
 		"mlxcpld:status:red",
 	},
 	{
-		0x24, 0xf0, MLXCPLD_LED_GREEN_STATIC_ON, LED_OFF,
+		0x24, 0xf0, MLXCPLD_LED_GREEN_STATIC_ON, 0,
 		"mlxcpld:uid:blue",
 	},
 };
diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c
index b7855c93bd72..2340a205ce44 100644
--- a/drivers/leds/leds-mlxreg.c
+++ b/drivers/leds/leds-mlxreg.c
@@ -119,7 +119,7 @@ mlxreg_led_get_hw(struct mlxreg_led_data *led_data)
 		dev_warn(led_data->led_cdev.dev, "Failed to get current brightness, error: %d\n",
 			 err);
 		/* Assume the LED is OFF */
-		return LED_OFF;
+		return 0;
 	}
 
 	regval = regval & ~data->mask;
@@ -220,20 +220,20 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv)
 		led_data->data_parent = priv;
 		if (strstr(data->label, "red") ||
 		    strstr(data->label, "orange")) {
-			brightness = LED_OFF;
+			brightness = 0;
 			led_data->base_color = MLXREG_LED_RED_SOLID;
 		} else if (strstr(data->label, "amber")) {
-			brightness = LED_OFF;
+			brightness = 0;
 			led_data->base_color = MLXREG_LED_AMBER_SOLID;
 		} else {
-			brightness = LED_OFF;
+			brightness = 0;
 			led_data->base_color = MLXREG_LED_GREEN_SOLID;
 		}
 		snprintf(led_data->led_cdev_name, sizeof(led_data->led_cdev_name),
 			 "mlxreg:%s", data->label);
 		led_cdev->name = led_data->led_cdev_name;
 		led_cdev->brightness = brightness;
-		led_cdev->max_brightness = LED_ON;
+		led_cdev->max_brightness = 1;
 		led_cdev->brightness_set_blocking =
 						mlxreg_led_brightness_set;
 		led_cdev->brightness_get = mlxreg_led_brightness_get;
diff --git a/drivers/leds/leds-mt6323.c b/drivers/leds/leds-mt6323.c
index f59e0e8bda8b..cbefd78f2d49 100644
--- a/drivers/leds/leds-mt6323.c
+++ b/drivers/leds/leds-mt6323.c
@@ -354,7 +354,7 @@ static int mt6323_led_set_dt_default(struct led_classdev *cdev,
 			ret =
 			mt6323_led_set_brightness(cdev, cdev->max_brightness);
 		} else  {
-			ret = mt6323_led_set_brightness(cdev, LED_OFF);
+			ret = mt6323_led_set_brightness(cdev, 0);
 		}
 	}
 
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c
index 77213b79f84d..8ffbe5e19952 100644
--- a/drivers/leds/leds-netxbig.c
+++ b/drivers/leds/leds-netxbig.c
@@ -177,7 +177,7 @@ static void netxbig_led_set(struct led_classdev *led_cdev,
 
 	spin_lock_irqsave(&led_dat->lock, flags);
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		mode = NETXBIG_LED_OFF;
 		set_brightness = 0;
 	} else {
@@ -295,7 +295,7 @@ static int create_netxbig_led(struct platform_device *pdev,
 	 * the whole boot process (bootloader+linux).
 	 */
 	led_dat->sata = 0;
-	led_dat->cdev.brightness = LED_OFF;
+	led_dat->cdev.brightness = 0;
 	led_dat->cdev.max_brightness = template->bright_max;
 	led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
 	led_dat->mode_addr = template->mode_addr;
diff --git a/drivers/leds/leds-nic78bx.c b/drivers/leds/leds-nic78bx.c
index f196f52eec1e..25639c40975c 100644
--- a/drivers/leds/leds-nic78bx.c
+++ b/drivers/leds/leds-nic78bx.c
@@ -72,7 +72,7 @@ static enum led_brightness nic78bx_brightness_get(struct led_classdev *cdev)
 	value = inb(nled->data->io_base);
 	spin_unlock_irqrestore(&nled->data->lock, flags);
 
-	return (value & nled->bit) ? 1 : LED_OFF;
+	return (value & nled->bit) ? 1 : 0;
 }
 
 static struct nic78bx_led nic78bx_leds[] = {
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c
index 1677d66d8b0e..34e899adfc0d 100644
--- a/drivers/leds/leds-ns2.c
+++ b/drivers/leds/leds-ns2.c
@@ -106,7 +106,7 @@ static void ns2_led_set(struct led_classdev *led_cdev,
 	struct ns2_led *led = container_of(led_cdev, struct ns2_led, cdev);
 	enum ns2_led_modes mode;
 
-	if (value == LED_OFF)
+	if (value == 0)
 		mode = NS_V2_LED_OFF;
 	else if (led->sata)
 		mode = NS_V2_LED_SATA;
@@ -224,7 +224,7 @@ static int ns2_led_register(struct device *dev, struct fwnode_handle *node,
 
 	/* Set LED initial state. */
 	led->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
-	led->cdev.brightness = (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
+	led->cdev.brightness = (mode == NS_V2_LED_OFF) ? 0 : 255;
 
 	init_data.fwnode = node;
 
diff --git a/drivers/leds/leds-ot200.c b/drivers/leds/leds-ot200.c
index 12af1127d9b7..693fbfeced6c 100644
--- a/drivers/leds/leds-ot200.c
+++ b/drivers/leds/leds-ot200.c
@@ -105,7 +105,7 @@ static void ot200_led_brightness_set(struct led_classdev *led_cdev,
 	else
 		BUG();
 
-	if (value == LED_OFF)
+	if (value == 0)
 		*val &= ~led->mask;
 	else
 		*val |= led->mask;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 017794bb87ae..3e14a61e9807 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -177,9 +177,9 @@ static int pca9532_set_brightness(struct led_classdev *led_cdev,
 	int err = 0;
 	struct pca9532_led *led = ldev_to_led(led_cdev);
 
-	if (value == LED_OFF)
+	if (value == 0)
 		led->state = PCA9532_OFF;
-	else if (value == LED_FULL)
+	else if (value == 255)
 		led->state = PCA9532_ON;
 	else {
 		led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */
@@ -386,7 +386,7 @@ static int pca9532_configure(struct i2c_client *client,
 			led->name = pled->name;
 			led->ldev.name = led->name;
 			led->ldev.default_trigger = pled->default_trigger;
-			led->ldev.brightness = LED_OFF;
+			led->ldev.brightness = 0;
 			led->ldev.brightness_set_blocking =
 						pca9532_set_brightness;
 			led->ldev.blink_set = pca9532_set_blink;
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
index a6b5699aeae4..2230d3f0e846 100644
--- a/drivers/leds/leds-pca955x.c
+++ b/drivers/leds/leds-pca955x.c
@@ -57,9 +57,9 @@
 #define PCA955X_LS_BLINK0	0x2	/* Blink at PWM0 rate */
 #define PCA955X_LS_BLINK1	0x3	/* Blink at PWM1 rate */
 
-#define PCA955X_GPIO_INPUT	LED_OFF
-#define PCA955X_GPIO_HIGH	LED_OFF
-#define PCA955X_GPIO_LOW	LED_FULL
+#define PCA955X_GPIO_INPUT	0
+#define PCA955X_GPIO_HIGH	0
+#define PCA955X_GPIO_LOW	255
 
 enum pca955x_type {
 	pca9550,
@@ -265,13 +265,13 @@ static enum led_brightness pca955x_led_get(struct led_classdev *led_cdev)
 	ls = (ls >> ((pca955x_led->led_num % 4) << 1)) & 0x3;
 	switch (ls) {
 	case PCA955X_LS_LED_ON:
-		ret = LED_FULL;
+		ret = 255;
 		break;
 	case PCA955X_LS_LED_OFF:
-		ret = LED_OFF;
+		ret = 0;
 		break;
 	case PCA955X_LS_BLINK0:
-		ret = LED_HALF;
+		ret = 127;
 		break;
 	case PCA955X_LS_BLINK1:
 		ret = pca955x_read_pwm(pca955x->client, 1, &pwm);
@@ -307,13 +307,13 @@ static int pca955x_led_set(struct led_classdev *led_cdev,
 		goto out;
 
 	switch (value) {
-	case LED_FULL:
+	case 255:
 		ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON);
 		break;
-	case LED_OFF:
+	case 0:
 		ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_OFF);
 		break;
-	case LED_HALF:
+	case 127:
 		ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK0);
 		break;
 	default:
@@ -578,12 +578,12 @@ static int pca955x_probe(struct i2c_client *client)
 
 			if (pdata->leds[i].default_state ==
 			    LEDS_GPIO_DEFSTATE_OFF) {
-				err = pca955x_led_set(led, LED_OFF);
+				err = pca955x_led_set(led, 0);
 				if (err)
 					return err;
 			} else if (pdata->leds[i].default_state ==
 				   LEDS_GPIO_DEFSTATE_ON) {
-				err = pca955x_led_set(led, LED_FULL);
+				err = pca955x_led_set(led, 255);
 				if (err)
 					return err;
 			}
@@ -621,16 +621,16 @@ static int pca955x_probe(struct i2c_client *client)
 			 */
 			if (pdata->leds[i].default_state ==
 			    LEDS_GPIO_DEFSTATE_KEEP) {
-				if (led->brightness != LED_FULL &&
-				    led->brightness != LED_OFF &&
-				    led->brightness != LED_HALF)
+				if (led->brightness != 255 &&
+				    led->brightness != 0 &&
+				    led->brightness != 127)
 					keep_pwm = true;
 			}
 		}
 	}
 
 	/* PWM0 is used for half brightness or 50% duty cycle */
-	err = pca955x_write_pwm(client, 0, 255 - LED_HALF);
+	err = pca955x_write_pwm(client, 0, 255 - 127);
 	if (err)
 		return err;
 
diff --git a/drivers/leds/leds-pca963x.c b/drivers/leds/leds-pca963x.c
index 00aecd67e348..17612f5021b9 100644
--- a/drivers/leds/leds-pca963x.c
+++ b/drivers/leds/leds-pca963x.c
@@ -128,11 +128,11 @@ static int pca963x_brightness(struct pca963x_led *led,
 	ledout = i2c_smbus_read_byte_data(client, ledout_addr);
 
 	switch (brightness) {
-	case LED_FULL:
+	case 255:
 		val = (ledout & ~mask) | (PCA963X_LED_ON << shift);
 		ret = i2c_smbus_write_byte_data(client, ledout_addr, val);
 		break;
-	case LED_OFF:
+	case 0:
 		val = ledout & ~mask;
 		ret = i2c_smbus_write_byte_data(client, ledout_addr, val);
 		break;
diff --git a/drivers/leds/leds-pm8058.c b/drivers/leds/leds-pm8058.c
index fb2ab72c0c40..535b471a634a 100644
--- a/drivers/leds/leds-pm8058.c
+++ b/drivers/leds/leds-pm8058.c
@@ -64,7 +64,7 @@ static enum led_brightness pm8058_led_get(struct led_classdev *cled)
 	ret = regmap_read(led->map, led->reg, &val);
 	if (ret) {
 		pr_err("Failed to get LED brightness\n");
-		return LED_OFF;
+		return 0;
 	}
 
 	switch (led->ledtype) {
@@ -78,7 +78,7 @@ static enum led_brightness pm8058_led_get(struct led_classdev *cled)
 		val >>= PM8058_LED_TYPE_KEYPAD_SHIFT;
 		break;
 	default:
-		val = LED_OFF;
+		val = 0;
 		break;
 	}
 
@@ -133,8 +133,8 @@ static int pm8058_led_probe(struct platform_device *pdev)
 			led->cdev.brightness = maxbright;
 			pm8058_led_set(&led->cdev, maxbright);
 		} else {
-			led->cdev.brightness = LED_OFF;
-			pm8058_led_set(&led->cdev, LED_OFF);
+			led->cdev.brightness = 0;
+			pm8058_led_set(&led->cdev, 0);
 		}
 	}
 
diff --git a/drivers/leds/leds-powernv.c b/drivers/leds/leds-powernv.c
index 743e2cdd0891..9ee3ad46a82c 100644
--- a/drivers/leds/leds-powernv.c
+++ b/drivers/leds/leds-powernv.c
@@ -146,7 +146,7 @@ static enum led_brightness powernv_led_get(struct powernv_led_data *powernv_led)
 	if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
 		dev_err(dev, "%s: OPAL get led call failed [rc=%d]\n",
 			__func__, rc);
-		return LED_OFF;
+		return 0;
 	}
 
 	led_mask = be64_to_cpu(mask);
@@ -156,14 +156,14 @@ static enum led_brightness powernv_led_get(struct powernv_led_data *powernv_led)
 	if (!((led_mask >> powernv_led->led_type) & OPAL_SLOT_LED_STATE_ON)) {
 		dev_err(dev, "%s: LED status not available for %s\n",
 			__func__, powernv_led->cdev.name);
-		return LED_OFF;
+		return 0;
 	}
 
 	/* LED status value */
 	if ((led_value >> powernv_led->led_type) & OPAL_SLOT_LED_STATE_ON)
-		return LED_FULL;
+		return 255;
 
-	return LED_OFF;
+	return 0;
 }
 
 /*
@@ -225,8 +225,8 @@ static int powernv_led_create(struct device *dev,
 
 	powernv_led->cdev.brightness_set_blocking = powernv_brightness_set;
 	powernv_led->cdev.brightness_get = powernv_brightness_get;
-	powernv_led->cdev.brightness = LED_OFF;
-	powernv_led->cdev.max_brightness = LED_FULL;
+	powernv_led->cdev.brightness = 0;
+	powernv_led->cdev.max_brightness = 255;
 
 	/* Register the classdev */
 	rc = devm_led_classdev_register(dev, &powernv_led->cdev);
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
index 6832180c1c54..50e97e70051a 100644
--- a/drivers/leds/leds-pwm.c
+++ b/drivers/leds/leds-pwm.c
@@ -67,7 +67,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
 
 	led_data->active_low = led->active_low;
 	led_data->cdev.name = led->name;
-	led_data->cdev.brightness = LED_OFF;
+	led_data->cdev.brightness = 0;
 	led_data->cdev.max_brightness = led->max_brightness;
 	led_data->cdev.flags = LED_CORE_SUSPENDRESUME;
 
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
index b6447c1721b4..350418795353 100644
--- a/drivers/leds/leds-rb532.c
+++ b/drivers/leds/leds-rb532.c
@@ -27,7 +27,7 @@ static void rb532_led_set(struct led_classdev *cdev,
 
 static enum led_brightness rb532_led_get(struct led_classdev *cdev)
 {
-	return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+	return (get_latch_u5() & LO_ULED) ? 255 : 0;
 }
 
 static struct led_classdev rb532_uled = {
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c
index 208c98918433..c99460ac1d3c 100644
--- a/drivers/leds/leds-regulator.c
+++ b/drivers/leds/leds-regulator.c
@@ -96,7 +96,7 @@ static int regulator_led_brightness_set(struct led_classdev *led_cdev,
 
 	mutex_lock(&led->mutex);
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		regulator_led_disable(led);
 		goto out;
 	}
diff --git a/drivers/leds/leds-sc27xx-bltc.c b/drivers/leds/leds-sc27xx-bltc.c
index e199ea15e406..e7c105e45a81 100644
--- a/drivers/leds/leds-sc27xx-bltc.c
+++ b/drivers/leds/leds-sc27xx-bltc.c
@@ -114,14 +114,14 @@ static int sc27xx_led_disable(struct sc27xx_led *leds)
 			(SC27XX_LED_RUN | SC27XX_LED_TYPE) << ctrl_shift, 0);
 }
 
-static int sc27xx_led_set(struct led_classdev *ldev, enum led_brightness value)
+static int sc27xx_led_set(struct led_classdev *ldev, unsigned int value)
 {
 	struct sc27xx_led *leds = to_sc27xx_led(ldev);
 	int err;
 
 	mutex_lock(&leds->priv->lock);
 
-	if (value == LED_OFF)
+	if (value == 0)
 		err = sc27xx_led_disable(leds);
 	else
 		err = sc27xx_led_enable(leds, value);
@@ -161,7 +161,7 @@ static int sc27xx_led_pattern_clear(struct led_classdev *ldev)
 	err = regmap_update_bits(regmap, ctrl_base,
 			(SC27XX_LED_RUN | SC27XX_LED_TYPE) << ctrl_shift, 0);
 
-	ldev->brightness = LED_OFF;
+	ldev->brightness = 0;
 
 	mutex_unlock(&leds->priv->lock);
 
diff --git a/drivers/leds/leds-spi-byte.c b/drivers/leds/leds-spi-byte.c
index f1964c96fb15..e96fc874c0f4 100644
--- a/drivers/leds/leds-spi-byte.c
+++ b/drivers/leds/leds-spi-byte.c
@@ -103,7 +103,7 @@ static int spi_byte_probe(struct spi_device *spi)
 	mutex_init(&led->mutex);
 	led->cdef = device_get_match_data(dev);
 	led->ldev.name = led->name;
-	led->ldev.brightness = LED_OFF;
+	led->ldev.brightness = 0;
 	led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value;
 	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
 
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index fcaa34706b6c..08cbe2ba5417 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -220,7 +220,7 @@ static void nasgpio_led_set_brightness(struct led_classdev *led_cdev,
 				       enum led_brightness brightness)
 {
 	u32 setting = 0;
-	if (brightness >= LED_HALF)
+	if (brightness >= 127)
 		setting = 1;
 	/*
 	 * Hold the lock across both operations.  This ensures
@@ -433,12 +433,12 @@ static void set_power_light_amber_noblink(void)
 	if (!amber || !blue)
 		return;
 	/*
-	 * LED_OFF implies disabling future blinking
+	 * 0 implies disabling future blinking
 	 */
 	pr_debug("setting blue off and amber on\n");
 
-	nasgpio_led_set_brightness(&blue->led_cdev, LED_OFF);
-	nasgpio_led_set_brightness(&amber->led_cdev, LED_FULL);
+	nasgpio_led_set_brightness(&blue->led_cdev, 0);
+	nasgpio_led_set_brightness(&amber->led_cdev, 255);
 }
 
 static ssize_t blink_show(struct device *dev,
@@ -482,9 +482,9 @@ static int register_nasgpio_led(int led_nr)
 	struct led_classdev *led = get_classdev_for_led_nr(led_nr);
 
 	led->name = nas_led->name;
-	led->brightness = LED_OFF;
+	led->brightness = 0;
 	if (nasgpio_led_get_attr(led, GP_LVL))
-		led->brightness = LED_FULL;
+		led->brightness = 255;
 	led->brightness_set = nasgpio_led_set_brightness;
 	led->blink_set = nasgpio_led_set_blink;
 	led->groups = nasgpio_led_groups;
diff --git a/drivers/leds/leds-sunfire.c b/drivers/leds/leds-sunfire.c
index eba7313719bf..f9e42661d02a 100644
--- a/drivers/leds/leds-sunfire.c
+++ b/drivers/leds/leds-sunfire.c
@@ -144,7 +144,7 @@ static int sunfire_led_generic_probe(struct platform_device *pdev,
 
 		p->leds[i].reg = (void __iomem *) pdev->resource[0].start;
 		lp->name = types[i].name;
-		lp->brightness = LED_FULL;
+		lp->brightness = 255;
 		lp->brightness_set = types[i].handler;
 		lp->default_trigger = types[i].default_trigger;
 
diff --git a/drivers/leds/leds-syscon.c b/drivers/leds/leds-syscon.c
index 7eddb8ecb44e..1533b39e22ec 100644
--- a/drivers/leds/leds-syscon.c
+++ b/drivers/leds/leds-syscon.c
@@ -40,7 +40,7 @@ static void syscon_led_set(struct led_classdev *led_cdev,
 	u32 val;
 	int ret;
 
-	if (value == LED_OFF) {
+	if (value == 0) {
 		val = 0;
 		sled->state = false;
 	} else {
diff --git a/drivers/leds/leds-tca6507.c b/drivers/leds/leds-tca6507.c
index 1473ced8664c..e40d659b6119 100644
--- a/drivers/leds/leds-tca6507.c
+++ b/drivers/leds/leds-tca6507.c
@@ -423,7 +423,7 @@ static int led_prepare(struct tca6507_led *led)
 		if (best == -1) {
 			/* Best brightness is full-on */
 			set_select(tca, led->num, TCA6507_LS_LED_ON);
-			led->led_cdev.brightness = LED_FULL;
+			led->led_cdev.brightness = 255;
 			return 0;
 		}
 
@@ -577,12 +577,12 @@ static int tca6507_blink_set(struct led_classdev *led_cdev,
 	if (led->offtime == 0)
 		led->offtime = 512;
 
-	if (led->led_cdev.brightness == LED_OFF)
-		led->led_cdev.brightness = LED_FULL;
+	if (led->led_cdev.brightness == 0)
+		led->led_cdev.brightness = 255;
 	if (led_assign(led) < 0) {
 		led->ontime = 0;
 		led->offtime = 0;
-		led->led_cdev.brightness = LED_OFF;
+		led->led_cdev.brightness = 0;
 		return -EINVAL;
 	}
 	*delay_on = led->ontime;
diff --git a/drivers/leds/leds-wm831x-status.c b/drivers/leds/leds-wm831x-status.c
index c48b80574f02..37328c0c00b1 100644
--- a/drivers/leds/leds-wm831x-status.c
+++ b/drivers/leds/leds-wm831x-status.c
@@ -52,7 +52,7 @@ static void wm831x_status_set(struct wm831x_status *led)
 		led->reg_val |= led->blink_time << WM831X_LED_DUR_SHIFT;
 		led->reg_val |= led->blink_cyc;
 	} else {
-		if (led->brightness != LED_OFF)
+		if (led->brightness != 0)
 			led->reg_val |= 1 << WM831X_LED_MODE_SHIFT;
 	}
 
@@ -71,7 +71,7 @@ static int wm831x_status_brightness_set(struct led_classdev *led_cdev,
 
 	spin_lock_irqsave(&led->value_lock, flags);
 	led->brightness = value;
-	if (value == LED_OFF)
+	if (value == 0)
 		led->blink = 0;
 	spin_unlock_irqrestore(&led->value_lock, flags);
 	wm831x_status_set(led);
@@ -248,9 +248,9 @@ static int wm831x_status_probe(struct platform_device *pdev)
 	drvdata->reg_val = wm831x_reg_read(wm831x, drvdata->reg);
 
 	if (drvdata->reg_val & WM831X_LED_MODE_MASK)
-		drvdata->brightness = LED_FULL;
+		drvdata->brightness = 255;
 	else
-		drvdata->brightness = LED_OFF;
+		drvdata->brightness = 0;
 
 	/* Set a default source if configured, otherwise leave the
 	 * current hardware setting.
diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c
index 8f243c413723..512bbc266258 100644
--- a/drivers/leds/leds-wm8350.c
+++ b/drivers/leds/leds-wm8350.c
@@ -150,7 +150,7 @@ static int wm8350_led_set(struct led_classdev *led_cdev,
 
 	spin_lock_irqsave(&led->value_lock, flags);
 
-	if (led->value == LED_OFF) {
+	if (led->value == 0) {
 		spin_unlock_irqrestore(&led->value_lock, flags);
 		return wm8350_led_disable(led);
 	}
@@ -160,7 +160,7 @@ static int wm8350_led_set(struct led_classdev *led_cdev,
 	 * brightness due to the non-linear current settings provided
 	 * by the hardware.
 	 */
-	uA = (led->max_uA_index * led->value) / LED_FULL;
+	uA = (led->max_uA_index * led->value) / 255;
 	spin_unlock_irqrestore(&led->value_lock, flags);
 	BUG_ON(uA >= ARRAY_SIZE(isink_cur));
 
@@ -179,7 +179,7 @@ static void wm8350_led_shutdown(struct platform_device *pdev)
 {
 	struct wm8350_led *led = platform_get_drvdata(pdev);
 
-	led->value = LED_OFF;
+	led->value = 0;
 	wm8350_led_disable(led);
 }
 
@@ -236,7 +236,7 @@ static int wm8350_led_probe(struct platform_device *pdev)
 			 pdata->max_uA);
 
 	spin_lock_init(&led->value_lock);
-	led->value = LED_OFF;
+	led->value = 0;
 	platform_set_drvdata(pdev, led);
 
 	return led_classdev_register(&pdev->dev, &led->cdev);
diff --git a/drivers/leds/simple/simatic-ipc-leds.c b/drivers/leds/simple/simatic-ipc-leds.c
index ff2c96e73241..be5d7e1e4145 100644
--- a/drivers/leds/simple/simatic-ipc-leds.c
+++ b/drivers/leds/simple/simatic-ipc-leds.c
@@ -73,7 +73,7 @@ static void simatic_ipc_led_set_io(struct led_classdev *led_cd,
 	spin_lock_irqsave(&reg_lock, flags);
 
 	val = inw(SIMATIC_IPC_LED_PORT_BASE);
-	if (brightness == LED_OFF)
+	if (brightness == 0)
 		outw(val | led->value, SIMATIC_IPC_LED_PORT_BASE);
 	else
 		outw(val & ~led->value, SIMATIC_IPC_LED_PORT_BASE);
@@ -85,7 +85,7 @@ static enum led_brightness simatic_ipc_led_get_io(struct led_classdev *led_cd)
 {
 	struct simatic_ipc_led *led = cdev_to_led(led_cd);
 
-	return inw(SIMATIC_IPC_LED_PORT_BASE) & led->value ? LED_OFF : led_cd->max_brightness;
+	return inw(SIMATIC_IPC_LED_PORT_BASE) & led->value ? 0 : led_cd->max_brightness;
 }
 
 static void simatic_ipc_led_set_mem(struct led_classdev *led_cd,
@@ -96,7 +96,7 @@ static void simatic_ipc_led_set_mem(struct led_classdev *led_cd,
 	u32 *p;
 
 	p = simatic_ipc_led_memory + led->value;
-	*p = (*p & ~1) | (brightness == LED_OFF);
+	*p = (*p & ~1) | (brightness == 0);
 }
 
 static enum led_brightness simatic_ipc_led_get_mem(struct led_classdev *led_cd)
@@ -106,7 +106,7 @@ static enum led_brightness simatic_ipc_led_get_mem(struct led_classdev *led_cd)
 	u32 *p;
 
 	p = simatic_ipc_led_memory + led->value;
-	return (*p & 1) ? LED_OFF : led_cd->max_brightness;
+	return (*p & 1) ? 0 : led_cd->max_brightness;
 }
 
 static int simatic_ipc_leds_probe(struct platform_device *pdev)
@@ -176,7 +176,7 @@ static int simatic_ipc_leds_probe(struct platform_device *pdev)
 			cdev->brightness_set = simatic_ipc_led_set_io;
 			cdev->brightness_get = simatic_ipc_led_get_io;
 		}
-		cdev->max_brightness = LED_ON;
+		cdev->max_brightness = 1;
 		cdev->name = ipcled->name;
 
 		err = devm_led_classdev_register(dev, cdev);
diff --git a/drivers/leds/trigger/ledtrig-activity.c b/drivers/leds/trigger/ledtrig-activity.c
index 30bc9df03636..d0d8cc8db8c6 100644
--- a/drivers/leds/trigger/ledtrig-activity.c
+++ b/drivers/leds/trigger/ledtrig-activity.c
@@ -129,7 +129,7 @@ static void led_activity_function(struct timer_list *t)
 		activity_data->state = !activity_data->state;
 		led_set_brightness_nosleep(led_cdev,
 			(activity_data->state ^ activity_data->invert) ?
-			led_cdev->blink_brightness : LED_OFF);
+			led_cdev->blink_brightness : 0);
 	}
 
 	target = (cpus > 1) ? (100 / cpus) : 50;
diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c
index 487577d22cfc..ec965e192365 100644
--- a/drivers/leds/trigger/ledtrig-backlight.c
+++ b/drivers/leds/trigger/ledtrig-backlight.c
@@ -47,7 +47,7 @@ static int fb_notifier_callback(struct notifier_block *p,
 
 	if ((n->old_status == UNBLANK) ^ n->invert) {
 		n->brightness = led->brightness;
-		led_set_brightness_nosleep(led, LED_OFF);
+		led_set_brightness_nosleep(led, 0);
 	} else {
 		led_set_brightness_nosleep(led, n->brightness);
 	}
@@ -84,7 +84,7 @@ static ssize_t bl_trig_invert_store(struct device *dev,
 
 	/* After inverting, we need to update the LED. */
 	if ((n->old_status == BLANK) ^ n->invert)
-		led_set_brightness_nosleep(led, LED_OFF);
+		led_set_brightness_nosleep(led, 0);
 	else
 		led_set_brightness_nosleep(led, n->brightness);
 
diff --git a/drivers/leds/trigger/ledtrig-camera.c b/drivers/leds/trigger/ledtrig-camera.c
index ab1c410872ff..1c9707c60a19 100644
--- a/drivers/leds/trigger/ledtrig-camera.c
+++ b/drivers/leds/trigger/ledtrig-camera.c
@@ -19,7 +19,7 @@ DEFINE_LED_TRIGGER(ledtrig_torch);
 
 void ledtrig_flash_ctrl(bool on)
 {
-	enum led_brightness brt = on ? LED_FULL : LED_OFF;
+	unsigned int brt = on ? 255 : 0;
 
 	led_trigger_event(ledtrig_flash, brt);
 }
@@ -27,7 +27,7 @@ EXPORT_SYMBOL_GPL(ledtrig_flash_ctrl);
 
 void ledtrig_torch_ctrl(bool on)
 {
-	enum led_brightness brt = on ? LED_FULL : LED_OFF;
+	unsigned int brt = on ? 255 : 0;
 
 	led_trigger_event(ledtrig_torch, brt);
 }
diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c
index 8af4f9bb9cde..a7d358412f8a 100644
--- a/drivers/leds/trigger/ledtrig-cpu.c
+++ b/drivers/leds/trigger/ledtrig-cpu.c
@@ -84,11 +84,11 @@ void ledtrig_cpu(enum cpu_led_event ledevt)
 		total_cpus = num_present_cpus();
 
 		led_trigger_event(trig->_trig,
-			is_active ? LED_FULL : LED_OFF);
+			is_active ? 255 : 0);
 
 
 		led_trigger_event(trig_cpu_all,
-			DIV_ROUND_UP(LED_FULL * active_cpus, total_cpus));
+			DIV_ROUND_UP(255 * active_cpus, total_cpus));
 
 	}
 }
diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c
index 0120faa3dafa..d794e44f2eff 100644
--- a/drivers/leds/trigger/ledtrig-gpio.c
+++ b/drivers/leds/trigger/ledtrig-gpio.c
@@ -37,9 +37,9 @@ static irqreturn_t gpio_trig_irq(int irq, void *_led)
 			led_set_brightness_nosleep(gpio_data->led,
 					   gpio_data->desired_brightness);
 		else
-			led_set_brightness_nosleep(gpio_data->led, LED_FULL);
+			led_set_brightness_nosleep(gpio_data->led, 255);
 	} else {
-		led_set_brightness_nosleep(gpio_data->led, LED_OFF);
+		led_set_brightness_nosleep(gpio_data->led, 0);
 	}
 
 	return IRQ_HANDLED;
diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c
index 7fe0a05574d2..0b5ec7dc14fa 100644
--- a/drivers/leds/trigger/ledtrig-heartbeat.c
+++ b/drivers/leds/trigger/ledtrig-heartbeat.c
@@ -35,13 +35,13 @@ static void led_heartbeat_function(struct timer_list *t)
 	struct heartbeat_trig_data *heartbeat_data =
 		from_timer(heartbeat_data, t, timer);
 	struct led_classdev *led_cdev;
-	unsigned long brightness = LED_OFF;
+	unsigned long brightness = 0;
 	unsigned long delay = 0;
 
 	led_cdev = heartbeat_data->led_cdev;
 
 	if (unlikely(panic_heartbeats)) {
-		led_set_brightness_nosleep(led_cdev, LED_OFF);
+		led_set_brightness_nosleep(led_cdev, 0);
 		return;
 	}
 
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index d5e774d83021..e3174d09111c 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c
@@ -74,13 +74,13 @@ static void set_baseline_state(struct led_netdev_data *trigger_data)
 		led_cdev->blink_brightness = led_cdev->max_brightness;
 
 	if (!test_bit(NETDEV_LED_MODE_LINKUP, &trigger_data->mode))
-		led_set_brightness(led_cdev, LED_OFF);
+		led_set_brightness(led_cdev, 0);
 	else {
 		if (test_bit(NETDEV_LED_LINK, &trigger_data->mode))
 			led_set_brightness(led_cdev,
 					   led_cdev->blink_brightness);
 		else
-			led_set_brightness(led_cdev, LED_OFF);
+			led_set_brightness(led_cdev, 0);
 
 		/* If we are looking for RX/TX start periodically
 		 * checking stats
@@ -355,7 +355,7 @@ static void netdev_trig_work(struct work_struct *work)
 
 	/* If we dont have a device, insure we are off */
 	if (!trigger_data->net_dev) {
-		led_set_brightness(trigger_data->led_cdev, LED_OFF);
+		led_set_brightness(trigger_data->led_cdev, 0);
 		return;
 	}
 
diff --git a/drivers/leds/trigger/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c
index bee3bd452abf..bc5ff2d2fd6c 100644
--- a/drivers/leds/trigger/ledtrig-oneshot.c
+++ b/drivers/leds/trigger/ledtrig-oneshot.c
@@ -58,9 +58,9 @@ static ssize_t led_invert_store(struct device *dev,
 	oneshot_data->invert = !!state;
 
 	if (oneshot_data->invert)
-		led_set_brightness_nosleep(led_cdev, LED_FULL);
+		led_set_brightness_nosleep(led_cdev, 255);
 	else
-		led_set_brightness_nosleep(led_cdev, LED_OFF);
+		led_set_brightness_nosleep(led_cdev, 0);
 
 	return size;
 }
@@ -184,7 +184,7 @@ static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
 	kfree(oneshot_data);
 
 	/* Stop blinking */
-	led_set_brightness(led_cdev, LED_OFF);
+	led_set_brightness(led_cdev, 0);
 }
 
 static struct led_trigger oneshot_led_trigger = {
diff --git a/drivers/leds/trigger/ledtrig-panic.c b/drivers/leds/trigger/ledtrig-panic.c
index 64abf2e91608..2576632d2264 100644
--- a/drivers/leds/trigger/ledtrig-panic.c
+++ b/drivers/leds/trigger/ledtrig-panic.c
@@ -58,7 +58,7 @@ static struct notifier_block led_trigger_panic_nb = {
 
 static long led_panic_blink(int state)
 {
-	led_trigger_event(trigger, state ? LED_FULL : LED_OFF);
+	led_trigger_event(trigger, state ? 255 : 0);
 	return 0;
 }
 
diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c
index 43a265dc4696..d49e45395aca 100644
--- a/drivers/leds/trigger/ledtrig-pattern.c
+++ b/drivers/leds/trigger/ledtrig-pattern.c
@@ -432,7 +432,7 @@ static void pattern_trig_deactivate(struct led_classdev *led_cdev)
 
 	del_timer_sync(&data->timer);
 
-	led_set_brightness(led_cdev, LED_OFF);
+	led_set_brightness(led_cdev, 0);
 	kfree(data);
 	led_cdev->activated = false;
 }
diff --git a/drivers/leds/trigger/ledtrig-timer.c b/drivers/leds/trigger/ledtrig-timer.c
index b4688d1d9d2b..cb2b4dcd4a2c 100644
--- a/drivers/leds/trigger/ledtrig-timer.c
+++ b/drivers/leds/trigger/ledtrig-timer.c
@@ -124,7 +124,7 @@ static int timer_trig_activate(struct led_classdev *led_cdev)
 static void timer_trig_deactivate(struct led_classdev *led_cdev)
 {
 	/* Stop blinking */
-	led_set_brightness(led_cdev, LED_OFF);
+	led_set_brightness(led_cdev, 0);
 }
 
 static struct led_trigger timer_led_trigger = {
diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c
index 80635183fac8..b35ba2527346 100644
--- a/drivers/leds/trigger/ledtrig-transient.c
+++ b/drivers/leds/trigger/ledtrig-transient.c
@@ -79,7 +79,7 @@ static ssize_t transient_activate_store(struct device *dev,
 		transient_data->activate = state;
 		led_set_brightness_nosleep(led_cdev, transient_data->state);
 		transient_data->restore_state =
-		    (transient_data->state == LED_FULL) ? LED_OFF : LED_FULL;
+		    (transient_data->state == 255) ? 0 : 255;
 		mod_timer(&transient_data->timer,
 			  jiffies + msecs_to_jiffies(transient_data->duration));
 	}
@@ -123,7 +123,7 @@ static ssize_t transient_state_show(struct device *dev,
 		led_trigger_get_drvdata(dev);
 	int state;
 
-	state = (transient_data->state == LED_FULL) ? 1 : 0;
+	state = (transient_data->state == 255) ? 1 : 0;
 	return sprintf(buf, "%d\n", state);
 }
 
@@ -142,7 +142,7 @@ static ssize_t transient_state_store(struct device *dev,
 	if (state != 1 && state != 0)
 		return -EINVAL;
 
-	transient_data->state = (state == 1) ? LED_FULL : LED_OFF;
+	transient_data->state = (state == 1) ? 255 : 0;
 	return size;
 }
 
diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c
index f62db7e520b5..378ccb7b12df 100644
--- a/drivers/leds/trigger/ledtrig-tty.c
+++ b/drivers/leds/trigger/ledtrig-tty.c
@@ -122,12 +122,12 @@ static void ledtrig_tty_work(struct work_struct *work)
 
 	if (icount.rx != trigger_data->rx ||
 	    icount.tx != trigger_data->tx) {
-		led_set_brightness_sync(trigger_data->led_cdev, LED_ON);
+		led_set_brightness_sync(trigger_data->led_cdev, 1);
 
 		trigger_data->rx = icount.rx;
 		trigger_data->tx = icount.tx;
 	} else {
-		led_set_brightness_sync(trigger_data->led_cdev, LED_OFF);
+		led_set_brightness_sync(trigger_data->led_cdev, 0);
 	}
 
 out:
-- 
2.34.1



From catalin.marinas at arm.com  Fri Jan 21 08:59:49 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 21 Jan 2022 16:59:49 +0000
Subject: [GIT PULL] arm64 fixes for 5.17-rc1
Message-ID: <YermhR/kQO+dg7P/@arm.com>

Hi Linus,

Please pull the arm64 updates below, some fixes that turned up during
the merging window. Thanks.

The following changes since commit 945409a6ef442cfe5f2f14e5626d4306d53100f0:

  Merge branches 'for-next/misc', 'for-next/cache-ops-dzp', 'for-next/stacktrace', 'for-next/xor-neon', 'for-next/kasan', 'for-next/armv8_7-fp', 'for-next/atomics', 'for-next/bti', 'for-next/sve', 'for-next/kselftest' and 'for-next/kcsan', remote-tracking branch 'arm64/for-next/perf' into for-next/core (2022-01-05 18:14:32 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to bb425a7598479fa0f171ec806033c440f218b0ce:

  arm64: mm: apply __ro_after_init to memory_limit (2022-01-20 09:15:16 +0000)

----------------------------------------------------------------
arm64 fixes/cleanups:

- Add brackets to the io_stop_wc macro.

- Avoid -Warray-bounds warning with the LSE atomics inline asm.

- Apply __ro_after_init to memory_limit.

----------------------------------------------------------------
Kees Cook (1):
      arm64: atomics: lse: Dereference matching size

Peng Fan (1):
      arm64: mm: apply __ro_after_init to memory_limit

Xiongfeng Wang (1):
      asm-generic: Add missing brackets for io_stop_wc macro

 arch/arm64/include/asm/atomic_lse.h | 2 +-
 arch/arm64/include/asm/cmpxchg.h    | 2 +-
 arch/arm64/mm/init.c                | 2 +-
 include/asm-generic/barrier.h       | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

-- 
Catalin


From catalin.marinas at arm.com  Fri Jan 21 09:07:35 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 21 Jan 2022 17:07:35 +0000
Subject: [PATCH linux-next] arm64: kexec: Support the case of VA_BITS=39
 in trans_pgd_idmap_page()
In-Reply-To: <20220121065216.1001021-1-si.hao@zte.com.cn>
References: <20220121065216.1001021-1-si.hao@zte.com.cn>
Message-ID: <YeroVxXEcUz8RTgv@arm.com>

On Fri, Jan 21, 2022 at 06:52:16AM +0000, cgel.zte at gmail.com wrote:
> From: sihao <si.hao at zte.com.cn>
> 
> When the values of CONFIG_ARM64_VA_BITS and CONFIG_ARM64_PA_BITS are not
> equal, the following panic occurs when kexec is executed.
> 
> This happens because trans_pgd_idmap_page() does not support VA_BITS=39.
> So the patch supports the case of VA_BITS=39.
[...]
> diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c
> index d7da8ca40d2e..3d88185adcf5 100644
> --- a/arch/arm64/mm/trans_pgd.c
> +++ b/arch/arm64/mm/trans_pgd.c
> @@ -232,7 +232,7 @@ int trans_pgd_idmap_page(struct trans_pgd_info *info, phys_addr_t *trans_ttbr0,
>  {
>  	phys_addr_t dst_addr = virt_to_phys(page);
>  	unsigned long pfn = __phys_to_pfn(dst_addr);
> -	int max_msb = (dst_addr & GENMASK(52, 48)) ? 51 : 47;

This should have been GENMASK(51, 48), though it doesn't make any
difference and may work better with the change below:

> +	int max_msb = (dst_addr & GENMASK(52, VA_BITS)) ? 51 : (VA_BITS - 1);

So when VA_BITS == 52, the mask is 0 and we set max_msb to 51.

I wonder, could we use fls64() instead here?

-- 
Catalin


From mathieu.poirier at linaro.org  Fri Jan 21 09:15:52 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 21 Jan 2022 10:15:52 -0700
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
 <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
Message-ID: <20220121171552.GA1811357@p14s>

Hey Jinlong,

On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
> 
> Good Day.
> 
> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > [...]
> > 
> > > > > > +
> > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > +{
> > > > > > +    static int traceid = TPDM_TRACE_ID_START;
> > > > > > +
> > > > > > +    drvdata->traceid = traceid++;
> > > > > > +}
> > > > > I have been specific on how to properly do this in the last revision.  Given the
> > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > > 
> > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > process it before the holidays.
> > > > > 
> > > > > Thanks,
> > > > > Mathieu
> > > > Hi Mathieu,
> > > > 
> > > > Sorry, not addressed your previous comments here.
> > > > 
> > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > Architecture specification v3.0
> > > 
> > Correct
> > 
> > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > our internal device. About 80 ids are already used.
> > > > 
> > > > Some components have fixed trace id in HW. If we use functions below to
> > > > count the trace id, there will be conflict to other components.
> > > > 
> > > > Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
> > > > components ? And handle trace ids in its' own driver ?
> > > > 
> > > This will limit systems to 15 cores - some have more!
> > > 
> > Correct
> > 
> > > > static inline int coresight_get_system_trace_id(int id)
> > > > {
> > > >           /* Start system IDs above the highest per CPU trace ID. */
> > > >           return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > }
> > Looking at my own suggestion again this won't work since it returns the same traceID
> > when called multiple times.
> > 
> > For this patchset and _without_ taking into account internal devices that have
> > their traceID set in HW:
> > 
> > 1. Define a bitmask that is 7 bit wide.
> Should it be a 128 bit wide bitmask? (0--127)?

Yes, you are correct.

> > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > first available bit after cpumask_last(cpu_possible_mask) + 1.
> 
> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> Return the first zero bit position as the trace id and set the bit.

I need to clarify something with Mike on this - I will get back to you on
Monday.

> 
> > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > clears the bit in the mask corresponding to @id.
> > 
> > For now that should work.
> > 
> > > > static inline int coresight_get_trace_id(int cpu)
> > > > {
> > > >       /*
> > > >        * A trace ID of value 0 is invalid, so let's start at some
> > > >        * random value that fits in 7 bits and go from there.  Since
> > > >        * the common convention is to have data trace IDs be I(N) + 1,
> > > >        * set instruction trace IDs as a function of the CPU number.
> > > >        */
> > > >       return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > }
> > > > 
> > > This fixed relationship between cpu and trace ID is used in the perf
> > > tooling to populate the elements in the perf.data file to correctly
> > > allow association between CPU and trace data, and thus allow correct
> > > trace decode.
> > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > perf header - theoretically we should be able to change the allocation scheme
> > without impacting the decoding process.
> > 
> > > It should be possible to create another more dynamic mapping scheme -
> > > but this must include a way to support the perf requirements too.
> > > 
> > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > For now what I have suggested above should be sufficient to provide an
> > in-between solution that doesn't hold back this patchset.
> > 
> > That being said, we need to start thinking about the best way to do this.  I
> > will put a patchset together in the new year that aims in that direction.
> > 
> > > Regards
> > > 
> > > Mike
> > > 
> > > > Thanks
> > > > 
> > > > Jinlong Mao
> > > > 
> > > > > > +
> > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > +{
> > > > > > +    struct device *dev = &adev->dev;
> > > > > > +    struct coresight_platform_data *pdata;
> > > > > > +    struct tpdm_drvdata *drvdata;
> > > > > > +    struct coresight_desc desc = { 0 };
> > > > > > +
> > > > > > +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > +    if (!desc.name)
> > > > > > +            return -ENOMEM;
> > > > > > +    pdata = coresight_get_platform_data(dev);
> > > > > > +    if (IS_ERR(pdata))
> > > > > > +            return PTR_ERR(pdata);
> > > > > > +    adev->dev.platform_data = pdata;
> > > > > > +
> > > > > > +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > +    if (!drvdata)
> > > > > > +            return -ENOMEM;
> > > > > > +    drvdata->dev = &adev->dev;
> > > > > > +    dev_set_drvdata(dev, drvdata);
> > > > > > +
> > > > > > +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > +    if (!drvdata->base)
> > > > > > +            return -ENOMEM;
> > > > > > +
> > > > > > +    mutex_init(&drvdata->lock);
> > > > > > +
> > > > > > +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > +    desc.ops = &tpdm_cs_ops;
> > > > > > +    desc.pdata = adev->dev.platform_data;
> > > > > > +    desc.dev = &adev->dev;
> > > > > > +    drvdata->csdev = coresight_register(&desc);
> > > > > > +    if (IS_ERR(drvdata->csdev))
> > > > > > +            return PTR_ERR(drvdata->csdev);
> > > > > > +
> > > > > > +    tpdm_init_default_data(drvdata);
> > > > > > +    pm_runtime_put(&adev->dev);
> > > > > > +
> > > > > > +    return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > +{
> > > > > > +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > +
> > > > > > +    coresight_unregister(drvdata->csdev);
> > > > > > +}
> > > > > > +
> > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > +    {
> > > > > > +            .id = 0x000f0e00,
> > > > > > +            .mask = 0x000fff00,
> > > > > > +    },
> > > > > > +    { 0, 0},
> > > > > > +};
> > > > > > +
> > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > +    .drv = {
> > > > > > +            .name   = "coresight-tpdm",
> > > > > > +            .owner  = THIS_MODULE,
> > > > > > +            .suppress_bind_attrs = true,
> > > > > > +    },
> > > > > > +    .probe          = tpdm_probe,
> > > > > > +    .id_table       = tpdm_ids,
> > > > > > +};
> > > > > > +
> > > > > > +module_amba_driver(tpdm_driver);
> > > > > > +
> > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > new file mode 100644
> > > > > > index 000000000000..980ae90ff1c8
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > @@ -0,0 +1,31 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > +/*
> > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > + */
> > > > > > +
> > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +
> > > > > > +/* Default value of the traceid */
> > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > +
> > > > > > +/**
> > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > + * @base:       memory mapped base address for this component.
> > > > > > + * @dev:        The device entity associated to this component.
> > > > > > + * @csdev:      component vitals needed by the framework.
> > > > > > + * @lock:       lock for the enable value.
> > > > > > + * @enable:     enable status of the component.
> > > > > > + * @traceid:    value of the current ID for this component.
> > > > > > + */
> > > > > > +
> > > > > > +struct tpdm_drvdata {
> > > > > > +    void __iomem            *base;
> > > > > > +    struct device           *dev;
> > > > > > +    struct coresight_device *csdev;
> > > > > > +    struct mutex            lock;
> > > > > > +    bool                    enable;
> > > > > > +    int                     traceid;
> > > > > > +};
> > > > > > +
> > > > > > +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > --- a/include/linux/coresight.h
> > > > > > +++ b/include/linux/coresight.h
> > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > >    };
> > > > > > 
> > > > > >    enum coresight_dev_subtype_helper {
> > > > > > --
> > > > > > 2.17.1
> > > > > > 
> > > 
> > > 
> > > -- 
> > > Mike Leach
> > > Principal Engineer, ARM Ltd.
> > > Manchester Design Centre. UK


From alim.akhtar at samsung.com  Fri Jan 21 09:28:24 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:24 +0530
Subject: [PATCH v3 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
References: <CGME20220121174016epcas5p347510c17404c703f6b857bc43413ed2a@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-1-alim.akhtar@samsung.com>

Adds basic support for the Tesla Full Self-Driving (FSD)
SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
as well as several IPs.

Patches 1 to 9 provide support for the clock controller
(which is designed similarly to Exynos SoCs).

The remaining changes provide pinmux support, initial device tree support.

- Changes since v2
* Addressed Krzysztof's and Stephen's review comments
* Added Reviewed-by and Acked-by tags
* Rebased on next-20220120

- Changes since v1
* fixed make dt_binding_check error as pointed by Rob
* Addressed Krzysztof's and Rob's review comments
* Added Reviewed-by and Acked-by tags
* Dropped SPI, MCT and ADC from this series (to be posted in small sets)

NOTE: These patches are based on next-20220120

Alim Akhtar (16):
  dt-bindings: add vendor prefix for Tesla
  dt-bindings: clock: Add bindings definitions for FSD CMU blocks
  dt-bindings: clock: Document FSD CMU bindings
  clk: samsung: fsd: Add initial clock support
  clk: samsung: fsd: Add cmu_peric block clock information
  clk: samsung: fsd: Add cmu_fsys0 clock information
  clk: samsung: fsd: Add cmu_fsys1 clock information
  clk: samsung: fsd: Add cmu_imem block clock information
  clk: samsung: fsd: Add cmu_mfc block clock information
  clk: samsung: fsd: Add cam_csi block clock information
  dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
  pinctrl: samsung: add FSD SoC specific data
  dt-bindings: arm: add Tesla FSD ARM SoC
  arm64: dts: fsd: Add initial device tree support
  arm64: dts: fsd: Add initial pinctrl support
  arm64: defconfig: Enable Tesla FSD SoC

 .../devicetree/bindings/arm/tesla.yaml        |   27 +
 .../bindings/clock/tesla,fsd-clock.yaml       |  198 ++
 .../bindings/pinctrl/samsung-pinctrl.txt      |    1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    8 +
 arch/arm64/Kconfig.platforms                  |    6 +
 arch/arm64/boot/dts/Makefile                  |    1 +
 arch/arm64/boot/dts/tesla/Makefile            |    3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts         |   39 +
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  335 +++
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  673 ++++++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/clk/samsung/Kconfig                   |    8 +
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-fsd.c                 | 1803 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |    1 +
 drivers/clk/samsung/clk-pll.h                 |    1 +
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    |   71 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |    1 +
 include/dt-bindings/clock/fsd-clk.h           |  150 ++
 21 files changed, 3332 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
 create mode 100644 drivers/clk/samsung/clk-fsd.c
 create mode 100644 include/dt-bindings/clock/fsd-clk.h


base-commit: 7fc5253f5a13271e9df35d6b936ff97b74540a59
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:25 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:25 +0530
Subject: [PATCH v3 01/16] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174021epcas5p2bd857858aa9070f4b91ed937bf81e307@epcas5p2.samsung.com>
Message-ID: <20220121172840.12121-2-alim.akhtar@samsung.com>

Add vendor prefix for the Tesla (https://www.tesla.com)

Cc: linux-fsd at tesla.com
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 64c604752052..09fbef521394 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1209,6 +1209,8 @@ patternProperties:
     description: Shenzhen Techstar Electronics Co., Ltd.
   "^terasic,.*":
     description: Terasic Inc.
+  "^tesla,.*":
+    description: Tesla, Inc.
   "^tfc,.*":
     description: Three Five Corp
   "^thead,.*":
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:26 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:26 +0530
Subject: [PATCH v3 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174028epcas5p2797a0f7024ccd3e96be91c82cea66490@epcas5p2.samsung.com>
Message-ID: <20220121172840.12121-3-alim.akhtar@samsung.com>

Clock controller driver of FSD platform is designed to have separate
instances for each particular CMU. So clock IDs in this bindings header
also start from 1 for each CMU block.

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
[robot: reported missing #endif]
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 include/dt-bindings/clock/fsd-clk.h | 150 ++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 include/dt-bindings/clock/fsd-clk.h

diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
new file mode 100644
index 000000000000..c8a2af1dd1ad
--- /dev/null
+++ b/include/dt-bindings/clock/fsd-clk.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * The constants defined in this header are being used in dts
+ * and fsd platform driver.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_FSD_H
+#define _DT_BINDINGS_CLOCK_FSD_H
+
+/* CMU */
+#define DOUT_CMU_PLL_SHARED0_DIV4		1
+#define DOUT_CMU_PERIC_SHARED1DIV36		2
+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
+#define DOUT_CMU_PERIC_SHARED0DIV20		4
+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
+#define DOUT_CMU_PLL_SHARED0_DIV6		6
+#define DOUT_CMU_FSYS0_SHARED1DIV4		7
+#define DOUT_CMU_FSYS0_SHARED0DIV4		8
+#define DOUT_CMU_FSYS1_SHARED0DIV8		9
+#define DOUT_CMU_FSYS1_SHARED0DIV4		10
+#define CMU_CPUCL_SWITCH_GATE			11
+#define DOUT_CMU_IMEM_TCUCLK			12
+#define DOUT_CMU_IMEM_ACLK			13
+#define DOUT_CMU_IMEM_DMACLK			14
+#define GAT_CMU_FSYS0_SHARED0DIV4		15
+#define CMU_NR_CLK				16
+
+/* PERIC */
+#define PERIC_SCLK_UART0			1
+#define PERIC_PCLK_UART0			2
+#define PERIC_SCLK_UART1			3
+#define PERIC_PCLK_UART1			4
+#define PERIC_DMA0_IPCLKPORT_ACLK		5
+#define PERIC_DMA1_IPCLKPORT_ACLK		6
+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
+#define PERIC_PCLK_SPI0                         9
+#define PERIC_SCLK_SPI0                         10
+#define PERIC_PCLK_SPI1                         11
+#define PERIC_SCLK_SPI1                         12
+#define PERIC_PCLK_SPI2                         13
+#define PERIC_SCLK_SPI2                         14
+#define PERIC_PCLK_TDM0                         15
+#define PERIC_PCLK_HSI2C0			16
+#define PERIC_PCLK_HSI2C1			17
+#define PERIC_PCLK_HSI2C2			18
+#define PERIC_PCLK_HSI2C3			19
+#define PERIC_PCLK_HSI2C4			20
+#define PERIC_PCLK_HSI2C5			21
+#define PERIC_PCLK_HSI2C6			22
+#define PERIC_PCLK_HSI2C7			23
+#define PERIC_MCAN0_IPCLKPORT_CCLK		24
+#define PERIC_MCAN0_IPCLKPORT_PCLK		25
+#define PERIC_MCAN1_IPCLKPORT_CCLK		26
+#define PERIC_MCAN1_IPCLKPORT_PCLK		27
+#define PERIC_MCAN2_IPCLKPORT_CCLK		28
+#define PERIC_MCAN2_IPCLKPORT_PCLK		29
+#define PERIC_MCAN3_IPCLKPORT_CCLK		30
+#define PERIC_MCAN3_IPCLKPORT_PCLK		31
+#define PERIC_PCLK_ADCIF			32
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
+#define PERIC_HCLK_TDM0				40
+#define PERIC_PCLK_TDM1				41
+#define PERIC_HCLK_TDM1				42
+#define PERIC_EQOS_PHYRXCLK_MUX			43
+#define PERIC_EQOS_PHYRXCLK			44
+#define PERIC_DOUT_RGMII_CLK			45
+#define PERIC_NR_CLK				46
+
+/* FSYS0 */
+#define UFS0_MPHY_REFCLK_IXTAL24		1
+#define UFS0_MPHY_REFCLK_IXTAL26		2
+#define UFS1_MPHY_REFCLK_IXTAL24		3
+#define UFS1_MPHY_REFCLK_IXTAL26		4
+#define UFS0_TOP0_HCLK_BUS			5
+#define UFS0_TOP0_ACLK				6
+#define UFS0_TOP0_CLK_UNIPRO			7
+#define UFS0_TOP0_FMP_CLK			8
+#define UFS1_TOP1_HCLK_BUS			9
+#define UFS1_TOP1_ACLK				10
+#define UFS1_TOP1_CLK_UNIPRO			11
+#define UFS1_TOP1_FMP_CLK			12
+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
+#define FSYS0_NR_CLK				23
+
+/* FSYS1 */
+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
+#define FSYS1_NR_CLK				9
+
+/* IMEM */
+#define IMEM_DMA0_IPCLKPORT_ACLK		1
+#define IMEM_DMA1_IPCLKPORT_ACLK		2
+#define IMEM_WDT0_IPCLKPORT_PCLK		3
+#define IMEM_WDT1_IPCLKPORT_PCLK		4
+#define IMEM_WDT2_IPCLKPORT_PCLK		5
+#define IMEM_MCT_PCLK				6
+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
+#define IMEM_NR_CLK				12
+
+/* MFC */
+#define MFC_MFC_IPCLKPORT_ACLK			1
+#define MFC_NR_CLK				2
+
+/* CAM_CSI */
+#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
+#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
+#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
+#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
+#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
+#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
+#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
+#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
+#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
+#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
+#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
+#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
+#define CAM_CSI_NR_CLK				13
+
+#endif /*_DT_BINDINGS_CLOCK_FSD_H */
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:27 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:27 +0530
Subject: [PATCH v3 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174033epcas5p1d7b305397c87497e101ebd4d1eb5ae0d@epcas5p1.samsung.com>
Message-ID: <20220121172840.12121-4-alim.akhtar@samsung.com>

Add dt-schema documentation for Tesla FSD SoC clock controller.

Cc: linux-fsd at tesla.com
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../bindings/clock/tesla,fsd-clock.yaml       | 198 ++++++++++++++++++
 1 file changed, 198 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..dc808e2f8327
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+description: |
+  FSD clock controller consist of several clock management unit
+  (CMU), which generates clocks for various inteernal SoC blocks.
+  The root clock comes from external OSC clock (24 MHz).
+
+  All available clocks are defined as preprocessor macros in
+  'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+  compatible:
+    enum:
+      - tesla,fsd-clock-cmu
+      - tesla,fsd-clock-imem
+      - tesla,fsd-clock-peric
+      - tesla,fsd-clock-fsys0
+      - tesla,fsd-clock-fsys1
+      - tesla,fsd-clock-mfc
+      - tesla,fsd-clock-cam_csi
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  clock-names:
+    minItems: 1
+    maxItems: 6
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cmu
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-imem
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: IMEM TCU clock (from CMU_CMU)
+            - description: IMEM bus clock (from CMU_CMU)
+            - description: IMEM DMA clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_imem_tcuclk
+            - const: dout_cmu_imem_aclk
+            - const: dout_cmu_imem_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-peric
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div4 clock (from CMU_CMU)
+            - description: PERIC shared1 div36 clock (from CMU_CMU)
+            - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+            - description: PERIC shared0 div20 clock (from CMU_CMU)
+            - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div4
+            - const: dout_cmu_peric_shared1div36
+            - const: dout_cmu_peric_shared0div3_tbuclk
+            - const: dout_cmu_peric_shared0div20
+            - const: dout_cmu_peric_shared1div4_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys0
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div6 clock (from CMU_CMU)
+            - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+            - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div6
+            - const: dout_cmu_fsys0_shared1div4
+            - const: dout_cmu_fsys0_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys1
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+            - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_fsys1_shared0div8
+            - const: dout_cmu_fsys1_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-mfc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cam_csi
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_FSYS1
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+
+    clock_fsys1: clock-controller at 16810000 {
+          compatible = "tesla,fsd-clock-fsys1";
+          reg = <0x16810000 0x3000>;
+          #clock-cells = <1>;
+
+          clocks = <&fin_pll>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+          clock-names = "fin_pll",
+                        "dout_cmu_fsys1_shared0div8",
+                        "dout_cmu_fsys1_shared0div4";
+    };
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:28 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:28 +0530
Subject: [PATCH v3 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174037epcas5p125c19dec012f7363570019db98f587b9@epcas5p1.samsung.com>
Message-ID: <20220121172840.12121-5-alim.akhtar@samsung.com>

Add initial clock support for FSD (Full Self-Driving) SoC
which is required to bring-up platforms based on this SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/Kconfig   |   8 +
 drivers/clk/samsung/Makefile  |   1 +
 drivers/clk/samsung/clk-fsd.c | 310 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c |   1 +
 drivers/clk/samsung/clk-pll.h |   1 +
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-fsd.c

diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 0e18d6ff2916..5f64c58f120f 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG
 	select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
 	select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
 	select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
+	select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
 
 config S3C64XX_COMMON_CLK
 	bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,10 @@ config S3C2443_COMMON_CLK
 	help
 	  Support for the clock controller present on the Samsung
 	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+
+config TESLA_FSD_COMMON_CLK
+	bool "Tesla FSD clock controller support" if COMPILE_TEST
+	depends on COMMON_CLK_SAMSUNG
+	help
+	  Support for the clock controller present on the Tesla FSD SoC.
+	  Choose Y here only if you build for this SoC.
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 0df74916a895..17e5d1cb9da2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_S3C64XX_COMMON_CLK)	+= clk-s3c64xx.o
 obj-$(CONFIG_S5PV210_COMMON_CLK)	+= clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_TESLA_FSD_COMMON_CLK)	+= clk-fsd.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..1caa31d08fc0
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * Common Clock Framework support for FSD SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/fsd-clk.h>
+
+#include "clk.h"
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0			0x0
+#define PLL_LOCKTIME_PLL_SHARED1			0x4
+#define PLL_LOCKTIME_PLL_SHARED2			0x8
+#define PLL_LOCKTIME_PLL_SHARED3			0xc
+#define PLL_CON0_PLL_SHARED0				0x100
+#define PLL_CON0_PLL_SHARED1				0x120
+#define PLL_CON0_PLL_SHARED2				0x140
+#define PLL_CON0_PLL_SHARED3				0x160
+#define MUX_CMU_CIS0_CLKMUX				0x1000
+#define MUX_CMU_CIS1_CLKMUX				0x1004
+#define MUX_CMU_CIS2_CLKMUX				0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX				0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX				0x1014
+#define MUX_PLL_SHARED0_MUX				0x1020
+#define MUX_PLL_SHARED1_MUX				0x1024
+#define DIV_CMU_CIS0_CLK				0x1800
+#define DIV_CMU_CIS1_CLK				0x1804
+#define DIV_CMU_CIS2_CLK				0x1808
+#define DIV_CMU_CMU_ACLK				0x180c
+#define DIV_CMU_CPUCL_SWITCH				0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4			0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3			0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4			0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4			0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8			0x182c
+#define DIV_CMU_IMEM_ACLK				0x1834
+#define DIV_CMU_IMEM_DMACLK				0x1838
+#define DIV_CMU_IMEM_TCUCLK				0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20			0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK		0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36			0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK		0x1850
+#define DIV_PLL_SHARED0_DIV2				0x1858
+#define DIV_PLL_SHARED0_DIV3				0x185c
+#define DIV_PLL_SHARED0_DIV4				0x1860
+#define DIV_PLL_SHARED0_DIV6				0x1864
+#define DIV_PLL_SHARED1_DIV3				0x1868
+#define DIV_PLL_SHARED1_DIV36				0x186c
+#define DIV_PLL_SHARED1_DIV4				0x1870
+#define DIV_PLL_SHARED1_DIV9				0x1874
+#define GAT_CMU_CIS0_CLKGATE				0x2000
+#define GAT_CMU_CIS1_CLKGATE				0x2004
+#define GAT_CMU_CIS2_CLKGATE				0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE			0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE			0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK			0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE			0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE			0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE			0x2028
+#define GAT_CMU_IMEM_ACLK_GATE				0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE			0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE			0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE		0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE			0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE		0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE			0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK			0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK		0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU	0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK		0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_CON0_PLL_SHARED0,
+	PLL_CON0_PLL_SHARED1,
+	PLL_CON0_PLL_SHARED2,
+	PLL_CON0_PLL_SHARED3,
+	MUX_CMU_CIS0_CLKMUX,
+	MUX_CMU_CIS1_CLKMUX,
+	MUX_CMU_CIS2_CLKMUX,
+	MUX_CMU_CPUCL_SWITCHMUX,
+	MUX_CMU_FSYS1_ACLK_MUX,
+	MUX_PLL_SHARED0_MUX,
+	MUX_PLL_SHARED1_MUX,
+	DIV_CMU_CIS0_CLK,
+	DIV_CMU_CIS1_CLK,
+	DIV_CMU_CIS2_CLK,
+	DIV_CMU_CMU_ACLK,
+	DIV_CMU_CPUCL_SWITCH,
+	DIV_CMU_FSYS0_SHARED0DIV4,
+	DIV_CMU_FSYS0_SHARED1DIV3,
+	DIV_CMU_FSYS0_SHARED1DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV8,
+	DIV_CMU_IMEM_ACLK,
+	DIV_CMU_IMEM_DMACLK,
+	DIV_CMU_IMEM_TCUCLK,
+	DIV_CMU_PERIC_SHARED0DIV20,
+	DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+	DIV_CMU_PERIC_SHARED1DIV36,
+	DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+	DIV_PLL_SHARED0_DIV2,
+	DIV_PLL_SHARED0_DIV3,
+	DIV_PLL_SHARED0_DIV4,
+	DIV_PLL_SHARED0_DIV6,
+	DIV_PLL_SHARED1_DIV3,
+	DIV_PLL_SHARED1_DIV36,
+	DIV_PLL_SHARED1_DIV4,
+	DIV_PLL_SHARED1_DIV9,
+	GAT_CMU_CIS0_CLKGATE,
+	GAT_CMU_CIS1_CLKGATE,
+	GAT_CMU_CIS2_CLKGATE,
+	GAT_CMU_CPUCL_SWITCH_GATE,
+	GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+	GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+	GAT_CMU_IMEM_ACLK_GATE,
+	GAT_CMU_IMEM_DMACLK_GATE,
+	GAT_CMU_IMEM_TCUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+	GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+	GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+	GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+	GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+	GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+	GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2000000000, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1800000000, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+	    PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+	    PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+	    PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+	    PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+	MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+	MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+	MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+	    MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+	MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+	DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+	DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+	DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+	    DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+	DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+	    DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+	    DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+	DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+	    DIV_CMU_IMEM_ACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+	    DIV_CMU_IMEM_DMACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+	    DIV_CMU_IMEM_TCUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+	    "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+	    "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+	    "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+	    "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV2, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV3, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+	    DIV_PLL_SHARED0_DIV4, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+	    DIV_PLL_SHARED0_DIV6, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV3, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+	    DIV_PLL_SHARED1_DIV36, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV4, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+	    DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+	GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+	     GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+	     GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+	     GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+	     GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+	     GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+	     GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+	     GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+	.pll_clks		= cmu_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cmu_pll_clks),
+	.mux_clks		= cmu_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cmu_mux_clks),
+	.div_clks		= cmu_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cmu_div_clks),
+	.gate_clks		= cmu_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cmu_gate_clks),
+	.nr_clk_ids		= CMU_NR_CLK,
+	.clk_regs		= cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 70cdc87f714e..fe383471c5f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_1450x:
 	case pll_1451x:
 	case pll_1452x:
+	case pll_142xx:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c83a20195f6d..a9892c2d1f57 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -39,6 +39,7 @@ enum samsung_pll_type {
 	pll_1460x,
 	pll_0822x,
 	pll_0831x,
+	pll_142xx,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:29 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:29 +0530
Subject: [PATCH v3 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174042epcas5p2374041f784eed694fc2421353e40bdfa@epcas5p2.samsung.com>
Message-ID: <20220121172840.12121-6-alim.akhtar@samsung.com>

Add CMU_PERIC block clock information needed for various IPs
functions found in this block.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 405 ++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 1caa31d08fc0..d190ceb7c1ab 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -8,14 +8,19 @@
  * Common Clock Framework support for FSD SoC.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/clock/fsd-clk.h>
 
 #include "clk.h"
+#include "clk-exynos-arm64.h"
 
 /* Register Offset definitions for CMU_CMU (0x11c10000) */
 #define PLL_LOCKTIME_PLL_SHARED0			0x0
@@ -308,3 +313,403 @@ static void __init fsd_clk_cmu_init(struct device_node *np)
 }
 
 CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX		0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX		0x120
+#define PLL_CON0_PERIC_PCLK_MUX			0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX		0x160
+#define PLL_CON0_SPI_CLK			0x180
+#define PLL_CON0_SPI_PCLK			0x1a0
+#define PLL_CON0_UART_CLK			0x1c0
+#define PLL_CON0_UART_PCLK			0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK			0x1000
+#define DIV_EQOS_BUSCLK				0x1800
+#define DIV_PERIC_MCAN_CLK			0x1804
+#define DIV_RGMII_CLK				0x1808
+#define DIV_RII_CLK				0x180c
+#define DIV_RMII_CLK				0x1810
+#define DIV_SPI_CLK				0x1814
+#define DIV_UART_CLK				0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I	0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK		0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK	0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK	0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK	0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK	0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM	0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS	0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM	0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS	0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK	0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK	0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK	0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK	0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK	0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK	0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK	0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK	0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK	0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I		0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I		0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I		0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I	0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I	0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK		0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D	0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P	0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0	0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK		0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK		0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK		0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK		0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK		0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK		0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK		0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK		0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK		0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK		0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK		0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK		0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK		0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK		0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK		0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK		0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK		0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK		0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0	0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0	0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK		0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK	0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK		0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI	0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK		0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI	0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK		0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI	0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M		0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK		0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M		0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK		0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART	0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK		0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART	0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK		0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK		0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+	PLL_CON0_PERIC_DMACLK_MUX,
+	PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+	PLL_CON0_PERIC_PCLK_MUX,
+	PLL_CON0_PERIC_TBUCLK_MUX,
+	PLL_CON0_SPI_CLK,
+	PLL_CON0_SPI_PCLK,
+	PLL_CON0_UART_CLK,
+	PLL_CON0_UART_PCLK,
+	MUX_PERIC_EQOS_PHYRXCLK,
+	DIV_EQOS_BUSCLK,
+	DIV_PERIC_MCAN_CLK,
+	DIV_RGMII_CLK,
+	DIV_RII_CLK,
+	DIV_RMII_CLK,
+	DIV_SPI_CLK,
+	DIV_UART_CLK,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+	GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+	GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+	GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+	GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+	GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+	GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+	GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+	GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+	GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+	GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+	GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART0_IPCLKPORT_PCLK,
+	GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART1_IPCLKPORT_PCLK,
+	GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+	FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+	MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+	MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+	    PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+	MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+	MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+	MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+	MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+		MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+	DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+	DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+	DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+		DIV_RGMII_CLK, 0, 4),
+	DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+	DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+	DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+	DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+	     GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+	     "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+	     "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+	.mux_clks		= peric_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric_mux_clks),
+	.div_clks		= peric_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric_div_clks),
+	.gate_clks		= peric_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric_gate_clks),
+	.fixed_clks		= peric_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(peric_fixed_clks),
+	.nr_clk_ids		= PERIC_NR_CLK,
+	.clk_regs		= peric_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric_clk_regs),
+	.clk_name		= "dout_cmu_pll_shared0_div4",
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+	{
+		.compatible = "tesla,fsd-clock-peric",
+		.data = &peric_cmu_info,
+	}, {
+	},
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+	.driver	= {
+		.name = "fsd-cmu",
+		.of_match_table = fsd_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+	return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:30 +0530
Subject: [PATCH v3 06/16] clk: samsung: fsd: Add cmu_fsys0 clock information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174046epcas5p4b32e4448d9d1cf589a19b878b6d174db@epcas5p4.samsung.com>
Message-ID: <20220121172840.12121-7-alim.akhtar@samsung.com>

CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
the related clock information for the same.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index d190ceb7c1ab..8062afab75e3 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -673,6 +673,305 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_pll_shared0_div4",
 };
 
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO		0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK		0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1		0x160
+#define DIV_CLK_UNIPRO				0x1800
+#define DIV_EQS_RGMII_CLK_125			0x1804
+#define DIV_PERIBUS_GRP				0x1808
+#define DIV_EQOS_RII_CLK2O5			0x180c
+#define DIV_EQOS_RMIICLK_25			0x1810
+#define DIV_PCIE_PHY_OSCCLK			0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I	0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK	0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK	0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO	0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK	0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC	0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK	0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK	0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK	0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK	0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK	0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK		0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I	0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I	0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK	0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D	0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1	0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P	0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S	0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK	0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL	0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0	0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC	0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK	0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC	0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC	0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK	0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK	0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK	0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS	0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK	0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO	0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK	0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS	0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK	0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO	0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK	0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE			0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+	PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+	PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+	PLL_CON0_EQOS_RGMII_125_MUX1,
+	DIV_CLK_UNIPRO,
+	DIV_EQS_RGMII_CLK_125,
+	DIV_PERIBUS_GRP,
+	DIV_EQOS_RII_CLK2O5,
+	DIV_EQOS_RMIICLK_25,
+	DIV_PCIE_PHY_OSCCLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+	GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+	GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+	GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+	GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+	FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+	FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+	FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+	    PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+	MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+	    PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+	MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+	    PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+	DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+	DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQS_RGMII_CLK_125, 0, 4),
+	DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+	    "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQOS_RMIICLK_25, 0, 5),
+	DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+	     "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+	     "xtal_clk_pcie_phy",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+	      "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+	      CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+	     "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+	     "dout_fsys0_pcie_phy_oscclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+	.mux_clks		= fsys0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys0_mux_clks),
+	.div_clks		= fsys0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys0_div_clks),
+	.gate_clks		= fsys0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys0_gate_clks),
+	.fixed_clks		= fsys0_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys0_fixed_clks),
+	.nr_clk_ids		= FSYS0_NR_CLK,
+	.clk_regs		= fsys0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys0_clk_regs),
+	.clk_name		= "dout_cmu_fsys0_shared1div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -695,6 +994,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	{
 		.compatible = "tesla,fsd-clock-peric",
 		.data = &peric_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys0",
+		.data = &fsys0_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:31 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:31 +0530
Subject: [PATCH v3 07/16] clk: samsung: fsd: Add cmu_fsys1 clock information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174050epcas5p31341f66152e9f69200905a2936cc14ea@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-8-alim.akhtar@samsung.com>

Adds cmu_fsys1 block clock information which are needed
for PCIe IPs in block FSYS1.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 8062afab75e3..95367d151ab6 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -972,6 +972,178 @@ static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys0_shared1div4",
 };
 
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX			0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX			0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK			0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK			0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK	0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK		0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK	0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK		0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL	0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK				0x2034
+#define GAT_FSYS1_PHY1_OSCCLK				0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK		0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK	0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK	0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK		0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0	0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0	0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK		0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK	0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK	0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK	0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK		0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK		0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK	0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK	0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK		0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK		0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL	0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK		0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK		0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+	PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+	PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+	DIV_CLK_FSYS1_PHY0_OSCCLK,
+	DIV_CLK_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+	GAT_FSYS1_PHY0_OSCCLLK,
+	GAT_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+	GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+	FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+	FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+	    PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+	MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+	    PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+	DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+	    DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+	DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+	    DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+	GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+	.mux_clks		= fsys1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys1_mux_clks),
+	.div_clks		= fsys1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys1_div_clks),
+	.gate_clks		= fsys1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys1_gate_clks),
+	.fixed_clks		= fsys1_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys1_fixed_clks),
+	.nr_clk_ids		= FSYS1_NR_CLK,
+	.clk_regs		= fsys1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys1_clk_regs),
+	.clk_name		= "dout_cmu_fsys1_shared0div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -997,6 +1169,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys0",
 		.data = &fsys0_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys1",
+		.data = &fsys1_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:32 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:32 +0530
Subject: [PATCH v3 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174054epcas5p313db9c80af71592554a9c4a7b8d105ec@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-9-alim.akhtar@samsung.com>

Adds cmu_imem clock related code, imem block contains IPs
like WDT, DMA, TMU etc, these clocks are required for such
IP function.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 95367d151ab6..d39ec207213e 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1144,6 +1144,289 @@ static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys1_shared0div4",
 };
 
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK				0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK			0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK			0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK			0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK		0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO		0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK		0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK		0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS		0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK		0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS		0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK		0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK			0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK		0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK			0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK			0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK			0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM	0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM	0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM	0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS	0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS	0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS	0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM		0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS		0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM		0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS		0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK		0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK		0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK		0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK		0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK		0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK		0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK			0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK			0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK	0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK			0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK			0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK	0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK	0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK			0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D	0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU	0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P	0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK		0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK		0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK	0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK		0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK		0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK		0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK		0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK		0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK			0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK			0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK			0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK			0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+	PLL_CON0_CLK_IMEM_ACLK,
+	PLL_CON0_CLK_IMEM_INTMEMCLK,
+	PLL_CON0_CLK_IMEM_TCUCLK,
+	DIV_OSCCLK_IMEM_TMUTSCLK,
+	GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_WDT0_IPCLKPORT_CLK,
+	GAT_IMEM_WDT1_IPCLKPORT_CLK,
+	GAT_IMEM_WDT2_IPCLKPORT_CLK,
+	GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+	GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+	GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+	GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+	GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+	GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+	GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+	GAT_IMEM_GIC_IPCLKPORT_CLK,
+	GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_PCLK,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+	GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+	GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_TCU_IPCLKPORT_ACLK,
+	GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+	MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+	    PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+	    PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+	DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+	GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+	     GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+	.mux_clks		= imem_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(imem_mux_clks),
+	.div_clks		= imem_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(imem_div_clks),
+	.gate_clks		= imem_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(imem_gate_clks),
+	.nr_clk_ids		= IMEM_NR_CLK,
+	.clk_regs		= imem_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:33 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:33 +0530
Subject: [PATCH v3 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174058epcas5p13276d857b7a9d3d24c84d5b46e0556fd@epcas5p1.samsung.com>
Message-ID: <20220121172840.12121-10-alim.akhtar@samsung.com>

Adds cmu_mfc clock related code, these clocks are
required for MFC IP.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index d39ec207213e..a9c4424b29ff 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1427,6 +1427,124 @@ static void __init fsd_clk_imem_init(struct device_node *np)
 
 CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
 
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC					0x0
+#define PLL_CON0_PLL_MFC					0x100
+#define MUX_MFC_BUSD						0x1000
+#define MUX_MFC_BUSP						0x1008
+#define DIV_MFC_BUSD_DIV4					0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK				0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM			0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS			0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK			0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK				0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D	0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P	0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK			0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK			0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK			0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK			0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK			0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK				0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK				0x2040
+#define GAT_MFC_BUSD_DIV4_GATE					0x2044
+#define GAT_MFC_BUSD_GATE					0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_MFC,
+	PLL_CON0_PLL_MFC,
+	MUX_MFC_BUSD,
+	MUX_MFC_BUSP,
+	DIV_MFC_BUSD_DIV4,
+	GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+	GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+	GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+	GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+	GAT_MFC_BUSD_DIV4_GATE,
+	GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 666000000, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+	    PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+	MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+	MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+	MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+	DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+	GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+	     GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+	     GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+	.pll_clks		= mfc_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(mfc_pll_clks),
+	.mux_clks		= mfc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mfc_mux_clks),
+	.div_clks		= mfc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mfc_div_clks),
+	.gate_clks		= mfc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mfc_gate_clks),
+	.nr_clk_ids		= MFC_NR_CLK,
+	.clk_regs		= mfc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1455,6 +1573,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys1",
 		.data = &fsys1_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-mfc",
+		.data = &mfc_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:34 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:34 +0530
Subject: [PATCH v3 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174102epcas5p32991b37e5be465e189ec5aeed32907bd@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-11-alim.akhtar@samsung.com>

Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sathyakam M <sathya at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index a9c4424b29ff..4f88d71cb52e 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1545,6 +1545,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
 	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
 };
 
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI		0x0
+#define PLL_CON0_PLL_CAM_CSI			0x100
+#define DIV_CAM_CSI0_ACLK			0x1800
+#define DIV_CAM_CSI1_ACLK			0x1804
+#define DIV_CAM_CSI2_ACLK			0x1808
+#define DIV_CAM_CSI_BUSD			0x180c
+#define DIV_CAM_CSI_BUSP			0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK	0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK	0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0	0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1	0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2	0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC	0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC		0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK		0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK		0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK		0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK		0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK		0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK		0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK		0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK		0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK		0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK		0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK		0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK		0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK		0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK		0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK		0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK		0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK		0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK		0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK		0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK		0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK		0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK		0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK		0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK		0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D	0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P	0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK	0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK	0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CAM_CSI,
+	PLL_CON0_PLL_CAM_CSI,
+	DIV_CAM_CSI0_ACLK,
+	DIV_CAM_CSI1_ACLK,
+	DIV_CAM_CSI2_ACLK,
+	DIV_CAM_CSI_BUSD,
+	DIV_CAM_CSI_BUSP,
+	GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+	GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1066000000, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+	    PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+	MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+	DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+	DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+	GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+	     GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+	     "dout_cam_csi_busd",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+	     "dout_cam_csi_busp",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+	     GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+	.pll_clks		= cam_csi_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cam_csi_pll_clks),
+	.mux_clks		= cam_csi_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cam_csi_mux_clks),
+	.div_clks		= cam_csi_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cam_csi_div_clks),
+	.gate_clks		= cam_csi_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cam_csi_gate_clks),
+	.nr_clk_ids		= CAM_CSI_NR_CLK,
+	.clk_regs		= cam_csi_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cam_csi_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1576,6 +1780,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-mfc",
 		.data = &mfc_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-cam_csi",
+		.data = &cam_csi_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:35 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:35 +0530
Subject: [PATCH v3 11/16] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174105epcas5p4c2719b5f14d43cfa4f3b6dd160a74972@epcas5p4.samsung.com>
Message-ID: <20220121172840.12121-12-alim.akhtar@samsung.com>

Add compatible for Tesla Full Self-Driving SoC. The
pinctrl hardware IP is similar to what found on most of the
Exynos series of SoC, so this new compatible is added in
Samsung pinctrl binding.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
index 9e70edceb21b..81747b88b718 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt
@@ -25,6 +25,7 @@ Required Properties:
   - "samsung,exynos7885-pinctrl": for Exynos7885 compatible pin-controller.
   - "samsung,exynos850-pinctrl": for Exynos850 compatible pin-controller.
   - "samsung,exynosautov9-pinctrl": for ExynosAutov9 compatible pin-controller.
+  - "tesla,fsd-pinctrl": for Tesla FSD SoC compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:36 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:36 +0530
Subject: [PATCH v3 12/16] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174109epcas5p374e8960a466f7de537277f4583305857@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-13-alim.akhtar@samsung.com>

Adds Tesla FSD SoC specific data to enable pinctrl.
FSD SoC has similar pinctrl controller as found in the most
Samsung/Exynos SoCs.

Cc: linux-fsd at tesla.com
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
 3 files changed, 74 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 2e490e7696f4..6fd06a6ee131 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -727,3 +727,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
 	.ctrl		= exynosautov9_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
 };
+
+/*
+ * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
+ * gpio/pin-mux/pinconfig controllers.
+ */
+
+/* pin banks of FSD pin-controller 0 (FSYS) */
+static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
+};
+
+/* pin banks of FSD pin-controller 1 (PERIC) */
+static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
+};
+
+/* pin banks of FSD pin-controller 2 (PMU) */
+static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
+};
+
+const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 FSYS0 data */
+		.pin_banks	= fsd_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 1 PERIC data */
+		.pin_banks	= fsd_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 2 PMU data */
+		.pin_banks	= fsd_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks2),
+	},
+};
+
+const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
+	.ctrl		= fsd_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 0f6e9305fec5..c542c8ed8fe7 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1271,6 +1271,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos850_of_data },
 	{ .compatible = "samsung,exynosautov9-pinctrl",
 		.data = &exynosautov9_of_data },
+	{ .compatible = "tesla,fsd-pinctrl",
+		.data = &fsd_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 1f8d30ba05af..5b32d3f30fcd 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -342,6 +342,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
+extern const struct samsung_pinctrl_of_match_data fsd_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:37 +0530
Subject: [PATCH v3 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174113epcas5p1e0ef0c9244eb08628b73d1477444be69@epcas5p1.samsung.com>
Message-ID: <20220121172840.12121-14-alim.akhtar@samsung.com>

Add device tree bindings for the Tesla FSD ARM SoC.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml

diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..09856da657dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: FSD SoC board
+        items:
+          - enum:
+              - tesla,fsd-evb   # Tesla FSD Evaluation
+          - const: tesla,fsd
+
+additionalProperties: true
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:38 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:38 +0530
Subject: [PATCH v3 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174117epcas5p4c1a7afa8b63ce4c55f05b6411d12fc09@epcas5p4.samsung.com>
Message-ID: <20220121172840.12121-15-alim.akhtar@samsung.com>

Add initial device tree support for "Full Self-Driving" (FSD) SoC
This SoC contain three clusters of four cortex-a72 CPUs and various
peripheral IPs.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 MAINTAINERS                           |   8 +
 arch/arm64/Kconfig.platforms          |   6 +
 arch/arm64/boot/dts/Makefile          |   1 +
 arch/arm64/boot/dts/tesla/Makefile    |   3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi    | 651 ++++++++++++++++++++++++++
 6 files changed, 708 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 27730a5a6345..ed1c10c26e5b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2754,6 +2754,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/tegra-cec.txt
 F:	drivers/media/cec/platform/tegra/
 
+ARM/TESLA FSD SoC SUPPORT
+M:	Alim Akhtar <alim.akhtar at samsung.com>
+M:	linux-fsd at tesla.com
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	arch/arm64/boot/dts/tesla*
+
 ARM/TETON BGA MACHINE SUPPORT
 M:	"Mark F. Brown" <mark.brown314 at gmail.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..739254493d6a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -268,6 +268,12 @@ config ARCH_TEGRA
 	help
 	  This enables support for the NVIDIA Tegra SoC family.
 
+config ARCH_TESLA_FSD
+	bool "ARMv8 based Tesla platform"
+	depends on ARCH_EXYNOS
+	help
+	  Support for ARMv8 based Tesla platforms.
+
 config ARCH_SPRD
 	bool "Spreadtrum SoC platform"
 	help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += tesla
 subdir-y += ti
 subdir-y += toshiba
 subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a1ee50e2fd06
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+	fsd-evb.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
new file mode 100644
index 000000000000..5af560c1b5e6
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+	model = "Tesla Full Self-Driving (FSD) Evaluation board";
+	compatible = "tesla,fsd-evb", "tesla,fsd";
+
+	aliases {
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
+
+&serial_0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..9a2b88f58c13
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "tesla,fsd";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &hsi2c_0;
+		i2c1 = &hsi2c_1;
+		i2c2 = &hsi2c_2;
+		i2c3 = &hsi2c_3;
+		i2c4 = &hsi2c_4;
+		i2c5 = &hsi2c_5;
+		i2c6 = &hsi2c_6;
+		i2c7 = &hsi2c_7;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpucl0_0>;
+				};
+				core1 {
+					cpu = <&cpucl0_1>;
+				};
+				core2 {
+					cpu = <&cpucl0_2>;
+				};
+				core3 {
+					cpu = <&cpucl0_3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpucl1_0>;
+				};
+				core1 {
+					cpu = <&cpucl1_1>;
+				};
+				core2 {
+					cpu = <&cpucl1_2>;
+				};
+				core3 {
+					cpu = <&cpucl1_3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpucl2_0>;
+				};
+				core1 {
+					cpu = <&cpucl2_1>;
+				};
+				core2 {
+					cpu = <&cpucl2_2>;
+				};
+				core3 {
+					cpu = <&cpucl2_3>;
+				};
+			};
+		};
+
+		/* Cluster 0 */
+		cpucl0_0: cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x000>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_1: cpu at 1 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x001>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_2: cpu at 2 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x002>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_3: cpu at 3 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x003>;
+				enable-method = "psci";
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 1 */
+		cpucl1_0: cpu at 100 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x100>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_1: cpu at 101 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x101>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_2: cpu at 102 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x102>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_3: cpu at 103 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x103>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 2 */
+		cpucl2_0: cpu at 200 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x200>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_1: cpu at 201 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x201>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_2: cpu at 202 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x202>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_3: cpu at 203 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x203>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP: cpu-sleep {
+				idle-state-name = "c2";
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <30>;
+				exit-latency-us = <75>;
+				min-residency-us = <300>;
+			};
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	fin_pll: clock {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		#clock-cells = <0>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+		gic: interrupt-controller at 10400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
+				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+		};
+
+		smmu_imem: iommu at 10200000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x10200000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <7>;
+			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
+				     /* Per context non-secure context interrupts, 0-3 interrupts */
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+		};
+
+		smmu_isp: iommu at 12100000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x12100000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <11>;
+			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+				     /* Per context non-secure context interrupts, 0-7 interrupts */
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+		};
+
+		smmu_peric: iommu at 14900000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x14900000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		smmu_fsys0: iommu at 15450000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x15450000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		clock_imem: clock-controller at 10010000 {
+			compatible = "tesla,fsd-clock-imem";
+			reg = <0x0 0x10010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
+				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_imem_tcuclk",
+				"dout_cmu_imem_aclk",
+				"dout_cmu_imem_dmaclk";
+		};
+
+		clock_cmu: clock-controller at 11c10000 {
+			compatible = "tesla,fsd-clock-cmu";
+			reg = <0x0 0x11c10000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_csi: clock-controller at 12610000 {
+			compatible = "tesla,fsd-clock-cam_csi";
+			reg = <0x0 0x12610000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_mfc: clock-controller at 12810000 {
+			compatible = "tesla,fsd-clock-mfc";
+			reg = <0x0 0x12810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_peric: clock-controller at 14010000 {
+			compatible = "tesla,fsd-clock-peric";
+			reg = <0x0 0x14010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div4",
+				"dout_cmu_peric_shared1div36",
+				"dout_cmu_peric_shared0div3_tbuclk",
+				"dout_cmu_peric_shared0div20",
+				"dout_cmu_peric_shared1div4_dmaclk";
+		};
+
+		clock_fsys0: clock-controller at 15010000 {
+			compatible = "tesla,fsd-clock-fsys0";
+			reg = <0x0 0x15010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div6",
+				"dout_cmu_fsys0_shared1div4",
+				"dout_cmu_fsys0_shared0div4";
+		};
+
+		clock_fsys1: clock-controller at 16810000 {
+			compatible = "tesla,fsd-clock-fsys1";
+			reg = <0x0 0x16810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_fsys1_shared0div8",
+				"dout_cmu_fsys1_shared0div4";
+		};
+
+		mdma0: mdma at 10100000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10100000 0x0 0x1000>;
+			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x800 0x0>;
+		};
+
+		mdma1: mdma at 10110000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10110000 0x0 0x1000>;
+			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x801 0x0>;
+		};
+
+		pdma0: pdma at 14280000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x2 0x0>;
+		};
+
+		pdma1: pdma at 14290000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x1 0x0>;
+		};
+
+		serial_0: serial at 14180000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14180000 0x0 0x100>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 0>, <&pdma1 1>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART0>,
+				 <&clock_peric PERIC_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		serial_1: serial at 14190000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14190000 0x0 0x100>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 2>, <&pdma1 3>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART1>,
+				 <&clock_peric PERIC_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller at 11400000 {
+			compatible = "samsung,exynos7-pmu", "syscon";
+			reg = <0x0 0x11400000 0x0 0x5000>;
+		};
+
+		watchdog_0: watchdog at 100a0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100a0000 0x0 0x100>;
+			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_1: watchdog at 100b0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100b0000 0x0 0x100>;
+			interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_2: watchdog at 100c0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100c0000 0x0 0x100>;
+			interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		pwm_0: pwm at 14100000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14100000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		pwm_1: pwm at 14110000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14110000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		hsi2c_0: hsi2c at 14200000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14200000 0x0 0x1000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: hsi2c at 14210000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14210000 0x0 0x1000>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: hsi2c at 14220000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14220000 0x0 0x1000>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: hsi2c at 14230000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14230000 0x0 0x1000>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: hsi2c at 14240000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14240000 0x0 0x1000>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: hsi2c at 14250000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14250000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: hsi2c at 14260000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: hsi2c at 14270000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+	};
+};
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:39 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:39 +0530
Subject: [PATCH v3 15/16] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174121epcas5p3f03348e9bd2d159dd00ce126506cf8ce@epcas5p3.samsung.com>
Message-ID: <20220121172840.12121-16-alim.akhtar@samsung.com>

Add initial pin configuration nodes for FSD SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 335 +++++++++++++++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
 2 files changed, 357 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi

diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..8f2c61eacf61
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+	gpf0: gpf0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf6: gpf6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric {
+	gpc8: gpc8 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb4: gpb4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb5: gpb5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb6: gpb6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb7: gpb7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd3: gpd3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg4: gpg4 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg5: gpg5 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg6: gpg6 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg7: gpg7 {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	pwm0_out: pwm0-out-pins {
+		samsung,pins = "gpb6-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	pwm1_out: pwm1-out-pins {
+		samsung,pins = "gpb6-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	hs_i2c0_bus: hs-i2c0-bus-pins {
+		samsung,pins = "gpb0-0", "gpb0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus-pins {
+		samsung,pins = "gpb0-2", "gpb0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus-pins {
+		samsung,pins = "gpb0-4", "gpb0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus-pins {
+		samsung,pins = "gpb0-6", "gpb0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus-pins {
+		samsung,pins = "gpb1-0", "gpb1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus-pins {
+		samsung,pins = "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus-pins {
+		samsung,pins = "gpb1-4", "gpb1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus-pins {
+		samsung,pins = "gpb1-6", "gpb1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_data: uart0-data-pins {
+		samsung,pins = "gpb7-0", "gpb7-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data-pins {
+		samsung,pins = "gpb7-4", "gpb7-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus-pins {
+		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus-pins {
+		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus-pins {
+		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_pmu {
+	gpq0: gpq0 {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 9a2b88f58c13..bab63c9f79dc 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -26,6 +26,9 @@ aliases {
 		i2c5 = &hsi2c_5;
 		i2c6 = &hsi2c_6;
 		i2c7 = &hsi2c_7;
+		pinctrl0 = &pinctrl_fsys0;
+		pinctrl1 = &pinctrl_peric;
+		pinctrl2 = &pinctrl_pmu;
 	};
 
 	cpus {
@@ -647,5 +650,24 @@ hsi2c_7: hsi2c at 14270000 {
 			clock-names = "hsi2c";
 			status = "disabled";
 		};
+
+		pinctrl_pmu: pinctrl at 114f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x114f0000 0x0 0x1000>;
+		};
+
+		pinctrl_peric: pinctrl at 141f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x141f0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys0: pinctrl at 15020000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x15020000 0x0 0x1000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
+
+#include "fsd-pinctrl.dtsi"
-- 
2.25.1



From alim.akhtar at samsung.com  Fri Jan 21 09:28:40 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Fri, 21 Jan 2022 22:58:40 +0530
Subject: [PATCH v3 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220121172840.12121-1-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174126epcas5p281335ae041b65918d0e6675f5c6d44ba@epcas5p2.samsung.com>
Message-ID: <20220121172840.12121-17-alim.akhtar@samsung.com>

This patch enables the Tesla FSD SoC in arm64 defconfig.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index ee4bd7710a0d..7dd0693a233e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -54,6 +54,7 @@ CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_INTEL_SOCFPGA=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
-- 
2.25.1



From andrii.nakryiko at gmail.com  Fri Jan 21 09:43:48 2022
From: andrii.nakryiko at gmail.com (Andrii Nakryiko)
Date: Fri, 21 Jan 2022 09:43:48 -0800
Subject: [PATCH bpf-next 1/2] selftests/bpf: use raw_tp program for atomic
 test
In-Reply-To: <20220121135632.136976-2-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-2-houtao1@huawei.com>
Message-ID: <CAEf4BzYUWzf6gL0xeixucFskV+6dcd+R0WkAeV76=nr1bDLyzQ@mail.gmail.com>

On Fri, Jan 21, 2022 at 5:57 AM Hou Tao <houtao1 at huawei.com> wrote:
>
> Now atomic tests will attach fentry program and run it through
> bpf_prog_test_run(), but attaching fentry program depends on bpf
> trampoline which is only available under x86-64. Considering many
> archs have atomic support, using raw_tp program instead.
>
> Signed-off-by: Hou Tao <houtao1 at huawei.com>
> ---

Nits about using generic ASSERT_TRUE instead of dedicated ASSERT_OK
checks, but otherwise LGTM

Acked-by: Andrii Nakryiko <andrii at kernel.org>


>  .../selftests/bpf/prog_tests/atomics.c        | 114 +++++-------------
>  tools/testing/selftests/bpf/progs/atomics.c   |  29 ++---
>  2 files changed, 44 insertions(+), 99 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/atomics.c b/tools/testing/selftests/bpf/prog_tests/atomics.c
> index 86b7d5d84eec..0de292c1ec02 100644
> --- a/tools/testing/selftests/bpf/prog_tests/atomics.c
> +++ b/tools/testing/selftests/bpf/prog_tests/atomics.c
> @@ -8,18 +8,13 @@ static void test_add(struct atomics_lskel *skel)
>  {
>         int err, prog_fd;
>         __u32 duration = 0, retval;
> -       int link_fd;
> -
> -       link_fd = atomics_lskel__add__attach(skel);
> -       if (!ASSERT_GT(link_fd, 0, "attach(add)"))
> -               return;
>
> +       /* No need to attach it, just run it directly */
>         prog_fd = skel->progs.add.prog_fd;
> -       err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
> +       err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
>                                 NULL, NULL, &retval, &duration);
> -       if (CHECK(err || retval, "test_run add",
> -                 "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
> -               goto cleanup;
> +       if (!ASSERT_TRUE(!err && !retval, "test_run add"))

please do this as two separate asserts: ASSERT_OK(err) and ASSERT_OK(retval)

> +               return;
>
>         ASSERT_EQ(skel->data->add64_value, 3, "add64_value");
>         ASSERT_EQ(skel->bss->add64_result, 1, "add64_result");
> @@ -31,28 +26,19 @@ static void test_add(struct atomics_lskel *skel)
>         ASSERT_EQ(skel->bss->add_stack_result, 1, "add_stack_result");
>
>         ASSERT_EQ(skel->data->add_noreturn_value, 3, "add_noreturn_value");
> -
> -cleanup:
> -       close(link_fd);
>  }
>
>  static void test_sub(struct atomics_lskel *skel)
>  {
>         int err, prog_fd;
>         __u32 duration = 0, retval;
> -       int link_fd;
> -
> -       link_fd = atomics_lskel__sub__attach(skel);
> -       if (!ASSERT_GT(link_fd, 0, "attach(sub)"))
> -               return;
>
> +       /* No need to attach it, just run it directly */
>         prog_fd = skel->progs.sub.prog_fd;
> -       err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
> +       err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
>                                 NULL, NULL, &retval, &duration);
> -       if (CHECK(err || retval, "test_run sub",
> -                 "err %d errno %d retval %d duration %d\n",
> -                 err, errno, retval, duration))
> -               goto cleanup;
> +       if (!ASSERT_TRUE(!err && !retval, "test_run sub"))

same as above, same below for all the CHECKs replaced with ASSERT_TRUE

> +               return;
>
>         ASSERT_EQ(skel->data->sub64_value, -1, "sub64_value");
>         ASSERT_EQ(skel->bss->sub64_result, 1, "sub64_result");
> @@ -64,27 +50,19 @@ static void test_sub(struct atomics_lskel *skel)
>         ASSERT_EQ(skel->bss->sub_stack_result, 1, "sub_stack_result");
>
>         ASSERT_EQ(skel->data->sub_noreturn_value, -1, "sub_noreturn_value");
> -
> -cleanup:
> -       close(link_fd);
>  }
>

[...]


From tharvey at gateworks.com  Fri Jan 21 10:17:05 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 21 Jan 2022 10:17:05 -0800
Subject: [PATCH v2] arm64: dts: imx8mm-venice-gw73xx-0x: add dt overlays for
 serial modes
Message-ID: <20220121181705.13363-1-tharvey@gateworks.com>

The imx8mm-venice-gw73xx-0x som+baseboard combination has a multi-protocol
RS-232/RS-485/RS-422 transceiver to an off-board connector which
can be configured in a number of ways via UART and GPIO configuration.

The default configuration per the imx8mm-venice-gw73xx-0x dts is for
UART2 TX/RX and UART4 TX/RX to be available as RS-232:
 J15.1 UART2 TX out
 J15.2 UART2 RX in
 J15.3 UART4 TX out
 J15.4 UART4 RX in
 J15.5 GND

Add dt overlays to allow additional the modes of operation:

rs232-rts (UART2 RS-232 with RTS/CTS hardware flow control)
 J15.1 TX out
 J15.2 RX in
 J15.3 RTS out
 J15.4 CTS in
 J15.5 GND

rs485 (UART2 RS-485 half duplex)
 J15.1 TXRX-
 J15.2 N/C
 J15.3 TXRX+
 J15.4 N/C
 J15.5 GND

rs422 (UART2 RS-422 full duplex)
 J15.1 TX-
 J15.2 RX+
 J15.3 TX+
 J15.4 RX-
 J15.5 GND

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
v2: fixed typo: s/uast/uart/
---
 arch/arm64/boot/dts/freescale/Makefile        |  3 +
 .../imx8mm-venice-gw73xx-0x-rs232-rts.dts     | 53 ++++++++++++++++
 .../imx8mm-venice-gw73xx-0x-rs422.dts         | 61 +++++++++++++++++++
 .../imx8mm-venice-gw73xx-0x-rs485.dts         | 61 +++++++++++++++++++
 4 files changed, 178 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index a14a6173b765..5ec8d59347b6 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
new file mode 100644
index 000000000000..2fa635e1c1a8
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW73xx RS232 with RTS/CTS hardware flow control:
+ *  - GPIO4_0 rs485_en needs to be driven low (in-active)
+ *  - UART4_TX becomes RTS
+ *  - UART4_RX becomes CTS
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "rs485_en";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+	cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+			MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28	0x140
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
new file mode 100644
index 000000000000..3e6404340d52
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Gateworks Corporation
+ *
+ * GW73xx RS422 (RS485 full duplex):
+ *  - GPIO1_0 rs485_term selects on-chip termination
+ *  - GPIO4_0 rs485_en needs to be driven high (active)
+ *  - GPIO4_2 rs485_hd needs to be driven low (in-active)
+ *  - UART4_TX is DE for RS485 transmitter
+ *  - RS485_EN needs to be pulled high
+ *  - RS485_HALF needs to be low
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_en";
+	};
+
+	rs485_hd {
+		gpio-hog;
+		gpios = <2 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "rs485_hd";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
new file mode 100644
index 000000000000..2c71ab9854cb
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2021 Gateworks Corporation
+ *
+ * GW73xx RS485 HD:
+ *  - GPIO1_0 rs485_term selects on-chip termination
+ *  - GPIO4_0 rs485_en needs to be driven high (active)
+ *  - GPIO4_2 rs485_hd needs to be driven high (active)
+ *  - UART4_TX is DE for RS485 transmitter
+ *  - RS485_EN needs to be pulled high
+ *  - RS485_HALF needs to be pulled high
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw73xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_en";
+	};
+
+	rs485_hd {
+		gpio-hog;
+		gpios = <2 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_hd";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+		>;
+	};
+};
-- 
2.17.1



From tharvey at gateworks.com  Fri Jan 21 10:17:47 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 21 Jan 2022 10:17:47 -0800
Subject: [PATCH] arm64: dts: imx8mm-venice-gw72xx-0x: add dt overlays for
 serial modes
Message-ID: <20220121181747.13521-1-tharvey@gateworks.com>

The imx8mm-venice-gw72xx-0x som+baseboard combination has a multi-protocol
RS-232/RS-485/RS-422 transceiver to an off-board connector which
can be configured in a number of ways via UART and GPIO configuration.

The default configuration per the imx8mm-venice-gw72xx-0x dts is for
UART2 TX/RX and UART4 TX/RX to be available as RS-232:
 J15.1 UART2 TX out
 J15.2 UART2 RX in
 J15.3 UART4 TX out
 J15.4 UART4 RX in
 J15.5 GND

Add dt overlays to allow additional the modes of operation:

rs232-rts (UART2 RS-232 with RTS/CTS hardware flow control)
 J15.1 TX out
 J15.2 RX in
 J15.3 RTS out
 J15.4 CTS in
 J15.5 GND

rs485 (UART2 RS-485 half duplex)
 J15.1 TXRX-
 J15.2 N/C
 J15.3 TXRX+
 J15.4 N/C
 J15.5 GND

rs422 (UART2 RS-422 full duplex)
 J15.1 TX-
 J15.2 RX+
 J15.3 TX+
 J15.4 RX-
 J15.5 GND

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  3 +
 .../imx8mm-venice-gw72xx-0x-rs232-rts.dts     | 53 ++++++++++++++++
 .../imx8mm-venice-gw72xx-0x-rs422.dts         | 61 +++++++++++++++++++
 .../imx8mm-venice-gw72xx-0x-rs485.dts         | 61 +++++++++++++++++++
 4 files changed, 178 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 5ec8d59347b6..2d3489eb073d 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -43,6 +43,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs232-rts.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs422.dtbo
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs485.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts
new file mode 100644
index 000000000000..3ea73a6886ff
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs232-rts.dts
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS232 with RTS/CTS hardware flow control:
+ *  - GPIO4_0 rs485_en needs to be driven low (in-active)
+ *  - UART4_TX becomes RTS
+ *  - UART4_RX becomes CTS
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "rs485_en";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_LOW>;
+	cts-gpios = <&gpio5 28 GPIO_ACTIVE_LOW>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+			MX8MM_IOMUXC_UART4_RXD_GPIO5_IO28	0x140
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts
new file mode 100644
index 000000000000..c3cd9f2b0db3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs422.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS422 (RS485 full duplex):
+ *  - GPIO1_0 rs485_term selects on-chip termination
+ *  - GPIO4_0 rs485_en needs to be driven high (active)
+ *  - GPIO4_2 rs485_hd needs to be driven low (in-active)
+ *  - UART4_TX is DE for RS485 transmitter
+ *  - RS485_EN needs to be pulled high
+ *  - RS485_HALF needs to be low
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_en";
+	};
+
+	rs485_hd {
+		gpio-hog;
+		gpios = <2 GPIO_ACTIVE_HIGH>;
+		output-low;
+		line-name = "rs485_hd";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+		>;
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts
new file mode 100644
index 000000000000..cc0a287226ab
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-rs485.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ *
+ * GW72xx RS485 HD:
+ *  - GPIO1_0 rs485_term selects on-chip termination
+ *  - GPIO4_0 rs485_en needs to be driven high (active)
+ *  - GPIO4_2 rs485_hd needs to be driven high (active)
+ *  - UART4_TX is DE for RS485 transmitter
+ *  - RS485_EN needs to be pulled high
+ *  - RS485_HALF needs to be pulled high
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw72xx-0x";
+};
+
+&gpio4 {
+	rs485_en {
+		gpio-hog;
+		gpios = <0 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_en";
+	};
+
+	rs485_hd {
+		gpio-hog;
+		gpios = <2 GPIO_ACTIVE_HIGH>;
+		output-high;
+		line-name = "rs485_hd";
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	rts-gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+&uart4 {
+	status = "disabled";
+};
+
+&iomuxc {
+	pinctrl_uart2: uart2grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+			MX8MM_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+			MX8MM_IOMUXC_UART4_TXD_GPIO5_IO29	0x140
+		>;
+	};
+};
-- 
2.17.1



From tharvey at gateworks.com  Fri Jan 21 10:18:41 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 21 Jan 2022 10:18:41 -0800
Subject: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x: add dt overlay for
 imx219 rpi v2 camera
Message-ID: <20220121181841.13650-1-tharvey@gateworks.com>

Add support for the RaspberryPi Camera v2 which is an IMX219 8MP module:
 - https://datasheets.raspberrypi.com/camera/camera-v2-schematics.pdf
 - has its own on-board 24MHz osc so no clock required from baseboard
 - pin 11 enables 1.8V and 2.8V LDO which is connected to
   GW73xx MIPI_GPIO4 (IMX8MM GPIO1_IO1) so we use this as a gpio
   controlled regulator enable.

Support is added via a device-tree overlay.

The IMX219 supports RAW8/RAW10 image formats.

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../imx8mm-venice-gw73xx-0x-imx219.dts        | 84 +++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 2d3489eb073d..324c1b01989a 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -47,6 +47,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs232-rts.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs422.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs485.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-imx219.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts
new file mode 100644
index 000000000000..33aa9eb477a5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-imx219.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw73xx-0x", "fsl,imx8mm";
+
+	reg_cam: regulator-cam {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_cam>;
+		compatible = "regulator-fixed";
+		regulator-name = "reg_cam";
+		gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	cam24m: cam24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "cam24m";
+	};
+};
+
+&csi {
+	status = "okay";
+};
+
+&i2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	imx219: sensor at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+		clocks = <&cam24m>;
+		VDIG-supply = <&reg_cam>;
+
+		port {
+			/* MIPI CSI-2 bus endpoint */
+			imx219_to_mipi_csi2: endpoint {
+				remote-endpoint = <&imx8mm_mipi_csi_in>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+				link-frequencies = /bits/ 64 <456000000>;
+			};
+		};
+	};
+};
+
+&mipi_csi {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			imx8mm_mipi_csi_in: endpoint {
+				remote-endpoint = <&imx219_to_mipi_csi2>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_reg_cam: regcamgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1	0x41
+		>;
+	};
+};
-- 
2.17.1



From tharvey at gateworks.com  Fri Jan 21 10:19:09 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Fri, 21 Jan 2022 10:19:09 -0800
Subject: [PATCH] arm64: dts: imx8mm-venice-gw72xx-0x: add dt overlay for
 imx219 rpi v2 camera
Message-ID: <20220121181909.13727-1-tharvey@gateworks.com>

Add support for the RaspberryPi Camera v2 which is an IMX219 8MP module:
 - https://datasheets.raspberrypi.com/camera/camera-v2-schematics.pdf
 - has its own on-board 24MHz osc so no clock required from baseboard
 - pin 11 enables 1.8V and 2.8V LDO which is connected to
   GW73xx MIPI_GPIO4 (IMX8MM GPIO1_IO1) so we use this as a gpio

Support is added via a device-tree overlay.

The IMX219 supports RAW8/RAW10 image formats.

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 arch/arm64/boot/dts/freescale/Makefile        |  1 +
 .../imx8mm-venice-gw72xx-0x-imx219.dts        | 84 +++++++++++++++++++
 2 files changed, 85 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 324c1b01989a..08d1f28a5165 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -43,6 +43,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-imx219.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs232-rts.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs422.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x-rs485.dtbo
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts
new file mode 100644
index 000000000000..6fbae90735d4
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx-0x-imx219.dts
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "imx8mm-pinfunc.h"
+
+/dts-v1/;
+/plugin/;
+
+&{/} {
+	compatible = "gw,imx8mm-gw72xx-0x", "fsl,imx8mm";
+
+	reg_cam: regulator-cam {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_cam>;
+		compatible = "regulator-fixed";
+		regulator-name = "reg_cam";
+		gpio = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+	};
+
+	cam24m: cam24m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <24000000>;
+		clock-output-names = "cam24m";
+	};
+};
+
+&csi {
+	status = "okay";
+};
+
+&i2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	imx219: sensor at 10 {
+		compatible = "sony,imx219";
+		reg = <0x10>;
+		clocks = <&cam24m>;
+		VDIG-supply = <&reg_cam>;
+
+		port {
+			/* MIPI CSI-2 bus endpoint */
+			imx219_to_mipi_csi2: endpoint {
+				remote-endpoint = <&imx8mm_mipi_csi_in>;
+				clock-lanes = <0>;
+				data-lanes = <1 2>;
+				link-frequencies = /bits/ 64 <456000000>;
+			};
+		};
+	};
+};
+
+&mipi_csi {
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port at 0 {
+			reg = <0>;
+			imx8mm_mipi_csi_in: endpoint {
+				remote-endpoint = <&imx219_to_mipi_csi2>;
+				data-lanes = <1 2>;
+			};
+		};
+	};
+};
+
+&iomuxc {
+	pinctrl_reg_cam: regcamgrp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1	0x41
+		>;
+	};
+};
-- 
2.17.1



From alisaidi at amazon.com  Fri Jan 21 10:24:49 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Fri, 21 Jan 2022 18:24:49 +0000
Subject: [PATCH] perf arm-spe: Use SPE data source for neoverse cores
Message-ID: <20220121182456.13538-1-alisaidi@amazon.com>

When synthesizing data from SPE, augment the type with source information
for Arm Neoverse cores. The field is IMPLDEF but the Neoverse cores all use
the same encoding. I can't find encoding information for any other SPE
implementations to unify their choices with Arm's thus that is left for future
work.

This changes enables the expected behavior of perf c2c on a system with SPE where
lines that are shared among multiple cores show up in perf c2c output. 

Signed-off-by: Ali Saidi <alisaidi at amazon.com> 
---
 .../util/arm-spe-decoder/arm-spe-decoder.c    |  1 +
 .../util/arm-spe-decoder/arm-spe-decoder.h    | 12 +++++
 tools/perf/util/arm-spe.c                     | 48 ++++++++++++++-----
 3 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
index 5e390a1a79ab..091987dd3966 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
@@ -220,6 +220,7 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
 
 			break;
 		case ARM_SPE_DATA_SOURCE:
+			decoder->record.source = payload;
 			break;
 		case ARM_SPE_BAD:
 			break;
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
index 69b31084d6be..1ecf4ee99415 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
@@ -29,10 +29,22 @@ enum arm_spe_op_type {
 	ARM_SPE_ST		= 1 << 1,
 };
 
+enum arm_spe_neoverse_data_source {
+	ARM_SPE_NV_L1D        = 0x0,
+	ARM_SPE_NV_L2         = 0x8,
+	ARM_SPE_NV_PEER_CORE  = 0x9,
+	ARM_SPE_NV_LCL_CLSTR  = 0xa,
+	ARM_SPE_NV_SYS_CACHE  = 0xb,
+	ARM_SPE_NV_PEER_CLSTR = 0xc,
+	ARM_SPE_NV_REMOTE     = 0xd,
+	ARM_SPE_NV_DRAM       = 0xe,
+};
+
 struct arm_spe_record {
 	enum arm_spe_sample_type type;
 	int err;
 	u32 op;
+	u16 source;
 	u32 latency;
 	u64 from_ip;
 	u64 to_ip;
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index d2b64e3f588b..d025af13f5e4 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -34,6 +34,7 @@
 #include "arm-spe-decoder/arm-spe-decoder.h"
 #include "arm-spe-decoder/arm-spe-pkt-decoder.h"
 
+#include <../../../arch/arm64/include/asm/cputype.h>
 #define MAX_TIMESTAMP (~0ULL)
 
 struct arm_spe {
@@ -45,6 +46,7 @@ struct arm_spe {
 	struct perf_session		*session;
 	struct machine			*machine;
 	u32				pmu_type;
+	u64				midr;
 
 	struct perf_tsc_conversion	tc;
 
@@ -399,9 +401,16 @@ static bool arm_spe__is_memory_event(enum arm_spe_sample_type type)
 	return false;
 }
 
-static u64 arm_spe__synth_data_source(const struct arm_spe_record *record)
+static const struct midr_range neoverse_spe[] = {
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	{},
+};
+
+static u64 arm_spe__synth_data_source(const struct arm_spe_record *record, u64 midr)
 {
 	union perf_mem_data_src	data_src = { 0 };
+	bool is_neoverse = is_midr_in_range(midr, neoverse_spe);
 
 	if (record->op == ARM_SPE_LD)
 		data_src.mem_op = PERF_MEM_OP_LOAD;
@@ -409,19 +418,30 @@ static u64 arm_spe__synth_data_source(const struct arm_spe_record *record)
 		data_src.mem_op = PERF_MEM_OP_STORE;
 
 	if (record->type & (ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS)) {
-		data_src.mem_lvl = PERF_MEM_LVL_L3;
+		if (is_neoverse && record->source == ARM_SPE_NV_DRAM) {
+			data_src.mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT;
+		} else if (is_neoverse && record->source == ARM_SPE_NV_PEER_CLSTR) {
+			data_src.mem_snoop = PERF_MEM_SNOOP_HITM;
+			data_src.mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
+		} else {
+			data_src.mem_lvl = PERF_MEM_LVL_L3;
 
-		if (record->type & ARM_SPE_LLC_MISS)
-			data_src.mem_lvl |= PERF_MEM_LVL_MISS;
-		else
-			data_src.mem_lvl |= PERF_MEM_LVL_HIT;
+			if (record->type & ARM_SPE_LLC_MISS)
+				data_src.mem_lvl |= PERF_MEM_LVL_MISS;
+			else
+				data_src.mem_lvl |= PERF_MEM_LVL_HIT;
+		}
 	} else if (record->type & (ARM_SPE_L1D_ACCESS | ARM_SPE_L1D_MISS)) {
-		data_src.mem_lvl = PERF_MEM_LVL_L1;
+		if (is_neoverse && record->source == ARM_SPE_NV_L2) {
+			data_src.mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
+		} else {
+			data_src.mem_lvl = PERF_MEM_LVL_L1;
 
-		if (record->type & ARM_SPE_L1D_MISS)
-			data_src.mem_lvl |= PERF_MEM_LVL_MISS;
-		else
-			data_src.mem_lvl |= PERF_MEM_LVL_HIT;
+			if (record->type & ARM_SPE_L1D_MISS)
+				data_src.mem_lvl |= PERF_MEM_LVL_MISS;
+			else
+				data_src.mem_lvl |= PERF_MEM_LVL_HIT;
+		}
 	}
 
 	if (record->type & ARM_SPE_REMOTE_ACCESS)
@@ -446,7 +466,7 @@ static int arm_spe_sample(struct arm_spe_queue *speq)
 	u64 data_src;
 	int err;
 
-	data_src = arm_spe__synth_data_source(record);
+	data_src = arm_spe__synth_data_source(record, spe->midr);
 
 	if (spe->sample_flc) {
 		if (record->type & ARM_SPE_L1D_MISS) {
@@ -796,6 +816,10 @@ static int arm_spe_process_event(struct perf_session *session,
 	u64 timestamp;
 	struct arm_spe *spe = container_of(session->auxtrace,
 			struct arm_spe, auxtrace);
+	const char *cpuid = perf_env__cpuid(session->evlist->env);
+	u64 midr = strtol(cpuid, NULL, 16);
+
+	spe->midr = midr;
 
 	if (dump_trace)
 		return 0;
-- 
2.33.1



From krzysztof.kozlowski at canonical.com  Fri Jan 21 10:33:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 19:33:15 +0100
Subject: [PATCH v2 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <20220120192438.25555-2-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193613epcas5p238851849d212e01d7d830d78ca7d6379@epcas5p2.samsung.com>
 <20220120192438.25555-2-alim.akhtar@samsung.com>
Message-ID: <aa172f14-2328-fc7c-0063-5c0033970d1d@canonical.com>

On 20/01/2022 20:24, Alim Akhtar wrote:
> Adds spi controller dt-binding compatible information for
> Tesla Full Self-Driving (FSD) SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
>  1 file changed, 1 insertion(+)

I think you forgot to mention - in cover letter - that this depends on
my Samsung SPI bindings conversion to dtschema.

I'll be sending v6 of it after merge window, with minor changes.

> 
> diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> index 61c77088e8ee..bf9a76d931d2 100644
> --- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> +++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
> @@ -21,6 +21,7 @@ properties:
>            - samsung,s3c6410-spi
>            - samsung,s5pv210-spi # for S5PV210 and S5PC110
>            - samsung,exynos5433-spi
> +          - tesla,fsd-spi
>        - const: samsung,exynos7-spi
>          deprecated: true
>  
> 


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Fri Jan 21 10:33:48 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 19:33:48 +0100
Subject: [PATCH v2 2/3] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220120192438.25555-3-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193618epcas5p45be1db500363072e647bf179623f8e7a@epcas5p4.samsung.com>
 <20220120192438.25555-3-alim.akhtar@samsung.com>
Message-ID: <b11b8507-339b-2125-30e6-a927539d7825@canonical.com>

On 20/01/2022 20:24, Alim Akhtar wrote:
> Adds compatible and port configuration for spi controller
> for Tesla Full Self-Driving SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  drivers/spi/spi-s3c64xx.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From krzysztof.kozlowski at canonical.com  Fri Jan 21 10:34:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 21 Jan 2022 19:34:03 +0100
Subject: [PATCH v2 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <20220120192438.25555-2-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193613epcas5p238851849d212e01d7d830d78ca7d6379@epcas5p2.samsung.com>
 <20220120192438.25555-2-alim.akhtar@samsung.com>
Message-ID: <5b90220f-c31d-cc8d-3e86-75ad8e56ab5e@canonical.com>

On 20/01/2022 20:24, Alim Akhtar wrote:
> Adds spi controller dt-binding compatible information for
> Tesla Full Self-Driving (FSD) SoC.
> 
> Cc: linux-fsd at tesla.com
> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From maz at kernel.org  Fri Jan 21 10:42:07 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 21 Jan 2022 18:42:07 +0000
Subject: [PATCH] KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions on
 !VHE
Message-ID: <20220121184207.423426-1-maz@kernel.org>

Injecting an exception into a guest with non-VHE is risky business.
Instead of writing in the shadow register for the switch code to
restore it, we override the CPU register instead. Which gets
overriden a few instructions later by said restore code.

The result is that although the guest correctly gets the exception,
it will return to the original context in some random state,
depending on what was there the first place... Boo.

Fix the issue by writing to the shadow register. The original code
is absolutely fine on VHE, as the state is already loaded, and writing
to the shadow register in that case would actually be a bug.

Fixes: bb666c472ca2 ("KVM: arm64: Inject AArch64 exceptions from HYP")
Cc: stable at vger.kernel.org
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/exception.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
index 0418399e0a20..c5d009715402 100644
--- a/arch/arm64/kvm/hyp/exception.c
+++ b/arch/arm64/kvm/hyp/exception.c
@@ -38,7 +38,10 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 
 static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
 {
-	write_sysreg_el1(val, SYS_SPSR);
+	if (has_vhe())
+		write_sysreg_el1(val, SYS_SPSR);
+	else
+		__vcpu_sys_reg(vcpu, SPSR_EL1) = val;
 }
 
 static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:35 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:35 +0100
Subject: [PATCH v3 0/9] ARM: mstar: cpupll
Message-ID: <20220121193544.23231-1-romain.perier@gmail.com>

This series adds a basic driver for the PLL that generates
the cpu clock on MStar/SigmaStar ARMv7 SoCs.

Unfortunately there isn't much documentation for this thing
so there are few magic values and guesses.

This needs to come after the MPLL DT changes.

Changes since v2:
- Re-ordered Kconfig by name
- Re-ordered includes alphabetically and removed useless ones
- Used timeout for cpu_relax
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_frequencyforreg()
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_regforfrequecy()
- Reduced the number of lines for msc313_cpupll_of_match
- Removed CLK_IS_CRITICAL

Changes since v1:
- Re-worked the series and ensure that 'make dt_binding_check' passes.
  The required commit is merged now, so it is okay.
- Fixed coding style issues in the driver and makes check_patch.pl happy
- Added one more commit for extending the opp_table for infinity2m.

Daniel Palmer (8):
  dt-bindings: clk: mstar msc313 cpupll binding description
  clk: mstar: msc313 cpupll clk driver
  ARM: mstar: Add cpupll to base dtsi
  ARM: mstar: Link cpupll to cpu
  ARM: mstar: Link cpupll to second core
  ARM: mstar: Add OPP table for infinity
  ARM: mstar: Add OPP table for infinity3
  ARM: mstar: Add OPP table for mercury5

Romain Perier (1):
  ARM: mstar: Extend opp_table for infinity2m

 .../bindings/clock/mstar,msc313-cpupll.yaml   |  45 ++++
 arch/arm/boot/dts/mstar-infinity.dtsi         |  34 +++
 arch/arm/boot/dts/mstar-infinity2m.dtsi       |  17 ++
 arch/arm/boot/dts/mstar-infinity3.dtsi        |  58 +++++
 arch/arm/boot/dts/mstar-mercury5.dtsi         |  36 +++
 arch/arm/boot/dts/mstar-v7.dtsi               |   9 +
 drivers/clk/mstar/Kconfig                     |   8 +
 drivers/clk/mstar/Makefile                    |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c         | 221 ++++++++++++++++++
 9 files changed, 429 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:36 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:36 +0100
Subject: [PATCH v3 1/9] dt-bindings: clk: mstar msc313 cpupll binding
 description
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-2-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a binding description for the MStar/SigmaStar CPU PLL block.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/clock/mstar,msc313-cpupll.yaml   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml

diff --git a/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
new file mode 100644
index 000000000000..a9ad7ab5230c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mstar,msc313-cpupll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MStar/Sigmastar MSC313 CPU PLL
+
+maintainers:
+  - Daniel Palmer <daniel at thingy.jp>
+
+description: |
+  The MStar/SigmaStar MSC313 and later ARMv7 chips have a scalable
+  PLL that can be used as the clock source for the CPU(s).
+
+properties:
+  compatible:
+    const: mstar,msc313-cpupll
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mstar-msc313-mpll.h>
+    cpupll: cpupll at 206400 {
+        compatible = "mstar,msc313-cpupll";
+        reg = <0x206400 0x200>;
+        #clock-cells = <1>;
+        clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+    };
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:38 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:38 +0100
Subject: [PATCH v3 3/9] ARM: mstar: Add cpupll to base dtsi
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-4-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

All MStar/SigmaStar ARMv7 SoCs have the CPU PLL at the same
place so add it to the base dtsi.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 89ebfe4f29da..2249faaa3aa7 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -155,6 +155,13 @@ mpll: mpll at 206000 {
 				clocks = <&xtal>;
 			};
 
+			cpupll: cpupll at 206400 {
+				compatible = "mstar,msc313-cpupll";
+				reg = <0x206400 0x200>;
+				#clock-cells = <0>;
+				clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+			};
+
 			gpio: gpio at 207800 {
 				#gpio-cells = <2>;
 				reg = <0x207800 0x200>;
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:39 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:39 +0100
Subject: [PATCH v3 4/9] ARM: mstar: Link cpupll to cpu
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-5-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The CPU clock is sourced from the CPU PLL.
Link cpupll to the cpu so that frequency scaling can happen.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 2249faaa3aa7..c26ba9b7b6dd 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -21,6 +21,8 @@ cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clocks = <&cpupll>;
+			clock-names = "cpuclk";
 		};
 	};
 
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:40 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:40 +0100
Subject: [PATCH v3 5/9] ARM: mstar: Link cpupll to second core
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-6-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The second core also sources it's clock from the CPU PLL.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index 6d4d1d224e96..dc339cd29778 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -11,6 +11,8 @@ cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
 		reg = <0x1>;
+		clocks = <&cpupll>;
+		clock-names = "cpuclk";
 	};
 };
 
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:37 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:37 +0100
Subject: [PATCH v3 2/9] clk: mstar: msc313 cpupll clk driver
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a driver for the CPU pll/ARM pll/MIPS pll that is present
in MStar SoCs.

Currently there is no documentation for this block so it's possible
this driver isn't entirely correct.

Only tested on the version of this IP in the MStar/SigmaStar
ARMv7 SoCs.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 drivers/clk/mstar/Kconfig             |   8 +
 drivers/clk/mstar/Makefile            |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c | 221 ++++++++++++++++++++++++++
 3 files changed, 230 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

diff --git a/drivers/clk/mstar/Kconfig b/drivers/clk/mstar/Kconfig
index de37e1bce2d2..146eeb637318 100644
--- a/drivers/clk/mstar/Kconfig
+++ b/drivers/clk/mstar/Kconfig
@@ -1,4 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config MSTAR_MSC313_CPUPLL
+	bool "MStar CPUPLL driver"
+	depends on ARCH_MSTARV7 || COMPILE_TEST
+	default ARCH_MSTARV7
+	help
+	  Support for the CPU PLL present on MStar/Sigmastar SoCs.
+
 config MSTAR_MSC313_MPLL
 	bool "MStar MPLL driver"
 	depends on ARCH_MSTARV7 || COMPILE_TEST
@@ -7,3 +14,4 @@ config MSTAR_MSC313_MPLL
 	help
 	  Support for the MPLL PLL and dividers block present on
 	  MStar/Sigmastar SoCs.
+
diff --git a/drivers/clk/mstar/Makefile b/drivers/clk/mstar/Makefile
index f8dcd25ede1d..21296a04e65a 100644
--- a/drivers/clk/mstar/Makefile
+++ b/drivers/clk/mstar/Makefile
@@ -2,5 +2,5 @@
 #
 # Makefile for mstar specific clk
 #
-
+obj-$(CONFIG_MSTAR_MSC313_CPUPLL) += clk-msc313-cpupll.o
 obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c
new file mode 100644
index 000000000000..c57b509e8c20
--- /dev/null
+++ b/drivers/clk/mstar/clk-msc313-cpupll.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Daniel Palmer <daniel at thingy.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+/*
+ * This IP is not documented outside of the messy vendor driver.
+ * Below is what we think the registers look like based on looking at
+ * the vendor code and poking at the hardware:
+ *
+ * 0x140 -- LPF low. Seems to store one half of the clock transition
+ * 0x144 /
+ * 0x148 -- LPF high. Seems to store one half of the clock transition
+ * 0x14c /
+ * 0x150 -- vendor code says "toggle lpf enable"
+ * 0x154 -- mu?
+ * 0x15c -- lpf_update_count?
+ * 0x160 -- vendor code says "switch to LPF". Clock source config? Register bank?
+ * 0x164 -- vendor code says "from low to high" which seems to mean transition from LPF low to
+ * LPF high.
+ * 0x174 -- Seems to be the PLL lock status bit
+ * 0x180 -- Seems to be the current frequency, this might need to be populated by software?
+ * 0x184 /  The vendor driver uses these to set the initial value of LPF low
+ *
+ * Frequency seems to be calculated like this:
+ * (parent clock (432mhz) / register_magic_value) * 16 * 524288
+ * Only the lower 24 bits of the resulting value will be used. In addition, the
+ * PLL doesn't seem to be able to lock on frequencies lower than 220 MHz, as
+ * divisor 0xfb586f (220 MHz) works but 0xfb7fff locks up.
+ *
+ * Vendor values:
+ * frequency - register value
+ *
+ * 400000000  - 0x0067AE14
+ * 600000000  - 0x00451EB8,
+ * 800000000  - 0x0033D70A,
+ * 1000000000 - 0x002978d4,
+ */
+
+#define REG_LPF_LOW_L		0x140
+#define REG_LPF_LOW_H		0x144
+#define REG_LPF_HIGH_BOTTOM	0x148
+#define REG_LPF_HIGH_TOP	0x14c
+#define REG_LPF_TOGGLE		0x150
+#define REG_LPF_MYSTERYTWO	0x154
+#define REG_LPF_UPDATE_COUNT	0x15c
+#define REG_LPF_MYSTERYONE	0x160
+#define REG_LPF_TRANSITIONCTRL	0x164
+#define REG_LPF_LOCK		0x174
+#define REG_CURRENT		0x180
+
+#define LPF_LOCK_TIMEOUT	100000000
+
+#define MULTIPLIER_1		16
+#define MULTIPLIER_2		524288
+#define MULTIPLIER		(MULTIPLIER_1 * MULTIPLIER_2)
+
+struct msc313_cpupll {
+	void __iomem *base;
+	struct clk_hw clk_hw;
+};
+
+#define to_cpupll(_hw) container_of(_hw, struct msc313_cpupll, clk_hw)
+
+static u32 msc313_cpupll_reg_read32(struct msc313_cpupll *cpupll, unsigned int reg)
+{
+	u32 value;
+
+	value = ioread16(cpupll->base + reg + 4) << 16;
+	value |= ioread16(cpupll->base + reg);
+
+	return value;
+}
+
+static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
+{
+	u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
+
+	iowrite16(l, cpupll->base + reg);
+	iowrite16(h, cpupll->base + reg + 4);
+}
+
+static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
+{
+	ktime_t timeout;
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
+
+	iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
+	iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
+	iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
+	iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+	iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
+
+	timeout = ktime_add_ns(ktime_get(), LPF_LOCK_TIMEOUT);
+	while (!(ioread16(cpupll->base + REG_LPF_LOCK))) {
+		if (ktime_after(ktime_get(), timeout)) {
+			pr_err("timeout waiting for LPF_LOCK\n");
+			return;
+		}
+		cpu_relax();
+	}
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L, regvalue);
+}
+
+static unsigned long msc313_cpupll_frequencyforreg(u32 reg, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || reg == 0)
+		return 0;
+	return DIV_ROUND_DOWN_ULL(prescaled, reg);
+}
+
+static u32 msc313_cpupll_regforfrequecy(unsigned long rate, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || rate == 0)
+		return 0;
+	return DIV_ROUND_UP_ULL(prescaled, rate);
+}
+
+static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+
+	return msc313_cpupll_frequencyforreg(msc313_cpupll_reg_read32(cpupll, REG_LPF_LOW_L),
+					     parent_rate);
+}
+
+static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
+	long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	/*
+	 * This is my poor attempt at making sure the resulting
+	 * rate doesn't overshoot the requested rate.
+	 */
+	for (; rounded >= rate && reg > 0; reg--)
+		rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	return rounded;
+}
+
+static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+	u32 reg = msc313_cpupll_regforfrequecy(rate, parent_rate);
+
+	msc313_cpupll_setfreq(cpupll, reg);
+
+	return 0;
+}
+
+static const struct clk_ops msc313_cpupll_ops = {
+	.recalc_rate	= msc313_cpupll_recalc_rate,
+	.round_rate	= msc313_cpupll_round_rate,
+	.set_rate	= msc313_cpupll_set_rate,
+};
+
+static const struct of_device_id msc313_cpupll_of_match[] = {
+	{ .compatible = "mstar,msc313-cpupll" },
+	{}
+};
+
+static const struct clk_parent_data cpupll_parent = {
+	.index	= 0,
+};
+
+static int msc313_cpupll_probe(struct platform_device *pdev)
+{
+	struct clk_init_data clk_init = {};
+	struct device *dev = &pdev->dev;
+	struct msc313_cpupll *cpupll;
+	int ret;
+
+	cpupll = devm_kzalloc(&pdev->dev, sizeof(*cpupll), GFP_KERNEL);
+	if (!cpupll)
+		return -ENOMEM;
+
+	cpupll->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(cpupll->base))
+		return PTR_ERR(cpupll->base);
+
+	/* LPF might not contain the current frequency so fix that up */
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L,
+				  msc313_cpupll_reg_read32(cpupll, REG_CURRENT));
+
+	clk_init.name = dev_name(dev);
+	clk_init.ops = &msc313_cpupll_ops;
+	clk_init.parent_data = &cpupll_parent;
+	clk_init.num_parents = 1;
+	cpupll->clk_hw.init = &clk_init;
+
+	ret = devm_clk_hw_register(dev, &cpupll->clk_hw);
+	if (ret)
+		return ret;
+
+	return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, &cpupll->clk_hw);
+}
+
+static struct platform_driver msc313_cpupll_driver = {
+	.driver = {
+		.name = "mstar-msc313-cpupll",
+		.of_match_table = msc313_cpupll_of_match,
+	},
+	.probe = msc313_cpupll_probe,
+};
+builtin_platform_driver(msc313_cpupll_driver);
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:41 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:41 +0100
Subject: [PATCH v3 6/9] ARM: mstar: Add OPP table for infinity
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-7-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add an OPP table for the inifinity chips so
that cpu frequency scaling can happen.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity.dtsi | 34 +++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi
index 0bee517797f4..441a917b88ba 100644
--- a/arch/arm/boot/dts/mstar-infinity.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity.dtsi
@@ -8,6 +8,40 @@
 
 #include <dt-bindings/gpio/msc313-gpio.h>
 
+/ {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-240000000 {
+			opp-hz = /bits/ 64 <240000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+};
+
+&cpu0 {
+	operating-points-v2 = <&cpu0_opp_table>;
+};
+
 &imi {
 	reg = <0xa0000000 0x16000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:42 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:42 +0100
Subject: [PATCH v3 7/9] ARM: mstar: Add OPP table for infinity3
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-8-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The infinity3 has a slightly higher max frequency
compared to the infinity so extend the OPP table.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-infinity3.dtsi | 58 ++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity3.dtsi b/arch/arm/boot/dts/mstar-infinity3.dtsi
index 9857e2a9934d..a56cf29e5d82 100644
--- a/arch/arm/boot/dts/mstar-infinity3.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity3.dtsi
@@ -6,6 +6,64 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+	opp-1008000000 {
+		opp-hz = /bits/ 64 <1008000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+	};
+
+	// overclock frequencies below, shown to work fine up to 1.3 GHz
+	opp-108000000 {
+		opp-hz = /bits/ 64 <1080000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1188000000 {
+		opp-hz = /bits/ 64 <1188000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1296000000 {
+		opp-hz = /bits/ 64 <1296000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1350000000 {
+		opp-hz = /bits/ 64 <1350000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1404000000 {
+		opp-hz = /bits/ 64 <1404000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1458000000 {
+		opp-hz = /bits/ 64 <1458000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1512000000 {
+		opp-hz = /bits/ 64 <1512000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+};
+
 &imi {
 	reg = <0xa0000000 0x20000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:43 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:43 +0100
Subject: [PATCH v3 8/9] ARM: mstar: Add OPP table for mercury5
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-9-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add an OPP table for mercury5 so that cpu frequency scaling can
happen.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 arch/arm/boot/dts/mstar-mercury5.dtsi | 36 +++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-mercury5.dtsi b/arch/arm/boot/dts/mstar-mercury5.dtsi
index a7d0dd9d6132..80a19bd23c9c 100644
--- a/arch/arm/boot/dts/mstar-mercury5.dtsi
+++ b/arch/arm/boot/dts/mstar-mercury5.dtsi
@@ -6,6 +6,42 @@
 
 #include "mstar-v7.dtsi"
 
+/ {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-microvolt = <800000 800000 850000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-200000000 {
+			opp-hz = /bits/ 64 <200000000>;
+			opp-microvolt = <850000 850000 880000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <880000 880000 890000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <900000 900000 1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <900000 900000 1000000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+};
+
 &imi {
 	reg = <0xa0000000 0x20000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Fri Jan 21 11:35:44 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Fri, 21 Jan 2022 20:35:44 +0100
Subject: [PATCH v3 9/9] ARM: mstar: Extend opp_table for infinity2m
In-Reply-To: <20220121193544.23231-1-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
Message-ID: <20220121193544.23231-10-romain.perier@gmail.com>

infinity2m are running up to 1.2Ghz, this extends opp_table with the
corresponding frequencies and enable operating-points table for cpu1

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index dc339cd29778..1b485efd7156 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -6,10 +6,25 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+};
+
 &cpus {
 	cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
+		operating-points-v2 = <&cpu0_opp_table>;
 		reg = <0x1>;
 		clocks = <&cpupll>;
 		clock-names = "cpuclk";
-- 
2.34.1



From helgaas at kernel.org  Fri Jan 21 11:46:07 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 21 Jan 2022 13:46:07 -0600
Subject: [PATCH v6] ACPI: explicit init HEST, SDEI and GHES in apci_init
In-Reply-To: <4c34906a-244e-3956-0ca7-7131b268cf60@linux.alibaba.com>
Message-ID: <20220121194607.GA1146355@bhelgaas>

On Fri, Jan 21, 2022 at 11:43:25AM +0800, Shuai Xue wrote:
> ? 2022/1/21 AM12:22, Bjorn Helgaas ??:
> > On Thu, Jan 20, 2022 at 01:05:22PM +0800, Shuai Xue wrote:
> >> From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
> >> memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
> >> the estatus memory pool. On the other hand, ghes_init() relies on
> >> sdei_init() to detect the SDEI version and (un)register events. The
> >> dependencies are as follows:
> >>
> >>     ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
> >>     ghes_init() => sdei_init()
> >>
> >> HEST is not PCI-specific and initcall ordering is implicit and not
> >> well-defined within a level.
> >>
> >> Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
> >> convert ghes_init() and sdei_init() from initcalls to explicit calls in the
> >> following order:
> >>
> >>     acpi_hest_init()
> >>     sdei_init()
> >>     ghes_init()

> >> --- a/drivers/acpi/bus.c
> >> +++ b/drivers/acpi/bus.c
> >> @@ -30,6 +30,7 @@
> >>  #include <linux/acpi_viot.h>
> >>  #include <linux/pci.h>
> >>  #include <acpi/apei.h>
> >> +#include <linux/arm_sdei.h>
> > 
> > This "arm" looks a little out of place in this supposedly arch-generic
> > code.  Not really a new thing with this patch, since this #include
> > already appears in drivers/acpi/apei/ghes.c.  Maybe it's unavoidable.
> 
> Yep, should we move sdei_init() into the beginning of ghes_init()?
> ...

> > Software Delegated Exception Interface (|SDEI|) is an Arm specification for
> > Non-secure world to register handlers with firmware to receive notifications
> > about system events.
> > LINK: https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/components/sdei.rst
> 
> I think SDEI is not a ACPI Specification but Arm specification so we should
> not rename sdei_init() with an "acpi_" prefix.  If we move sdei_init() into
> ghes_init(), and rename ghes_init() to acpi_ghes_init(), then all looks
> fine? What's your opinion, Bjorn?

Makes sense to me, especially since drivers/acpi/apei/ghes.c already
includes linux/arm_sdei.h.  This is Rafael's area.

Bjorn


From ebiggers at kernel.org  Fri Jan 21 11:54:34 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Fri, 21 Jan 2022 11:54:34 -0800
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <20220119135450.564115-1-Jason@zx2c4.com>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com>
Message-ID: <YesPesOhftSzp2ft@sol.localdomain>

On Wed, Jan 19, 2022 at 02:54:50PM +0100, Jason A. Donenfeld wrote:
> blake2s_compress_generic is weakly aliased to blake2s_generic. The
> current harness for function selection uses a function pointer, which is
> ordinarily inlined and resolved at compile time. But when Clang's CFI is
> enabled, CFI still triggers when making an indirect call via a weak
> symbol. This seems like a bug in Clang's CFI, as though it's bucketing
> weak symbols and strong symbols differently. It also only seems to
> trigger when "full LTO" mode is used, rather than "thin LTO".
> 
> [    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
> [    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
> [    0.000000][    T0] Hardware name: MT6873 (DT)
> [    0.000000][    T0] Call trace:
> [    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
> [    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
> [    0.000000][    T0]  panic+0x194/0x464
> [    0.000000][    T0]  __cfi_check_fail+0x54/0x58
> [    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
> [    0.000000][    T0]  blake2s_update+0x14c/0x178
> [    0.000000][    T0]  _extract_entropy+0xf4/0x29c
> [    0.000000][    T0]  crng_initialize_primary+0x24/0x94
> [    0.000000][    T0]  rand_initialize+0x2c/0x6c
> [    0.000000][    T0]  start_kernel+0x2f8/0x65c
> [    0.000000][    T0]  __primary_switched+0xc4/0x7be4
> [    0.000000][    T0] Rebooting in 5 seconds..
> 
> Nonetheless, the function pointer method isn't so terrific anyway, so
> this patch replaces it with a simple boolean, which also gets inlined
> away. This successfully works around the Clang bug.
> 
> In general, I'm not too keen on all of the indirection involved here; it
> clearly does more harm than good. Hopefully the whole thing can get
> cleaned up down the road when lib/crypto is overhauled more
> comprehensively. But for now, we go with a simple bandaid.
> 
> Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
> Reported-by: Miles Chen <miles.chen at mediatek.com>
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Cc: Sami Tolvanen <samitolvanen at google.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
> ---
>  arch/arm/crypto/blake2s-shash.c   |  4 ++--
>  arch/x86/crypto/blake2s-shash.c   |  4 ++--
>  crypto/blake2s_generic.c          |  4 ++--
>  include/crypto/internal/blake2s.h | 36 ++++++++++++++++++-------------
>  lib/crypto/blake2s.c              |  4 ++--
>  5 files changed, 29 insertions(+), 23 deletions(-)

There are some lines over 80 columns in this patch.

Otherwise this looks fine.  It would be really nice to fix this in clang,
though.

- Eric


From Jason at zx2c4.com  Fri Jan 21 12:22:59 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Fri, 21 Jan 2022 21:22:59 +0100
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <YesPesOhftSzp2ft@sol.localdomain>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com> <YesPesOhftSzp2ft@sol.localdomain>
Message-ID: <CAHmME9ow7TxCaYYayRn9rdJJSdQ48tWQgdrW00g7mHaWvVJ+Zw@mail.gmail.com>

On Fri, Jan 21, 2022 at 8:54 PM Eric Biggers <ebiggers at kernel.org> wrote:
> There are some lines over 80 columns in this patch.

I'll fix that up.

> Otherwise this looks fine.  It would be really nice to fix this in clang,
> though.

I agree. I'm wondering whether it makes sense to roll with this patch,
or to just not change anything and lean on Clang upstream to fix their
bug. Full LTO is marked as "experimental" still. On the other hand,
Android ships with it turned on, so how "experimental" can it really
be? I don't have a strong read on the Clang ecosystem to know what
makes most sense, to apply this or not. Do you have an opinion?

Jason


From samitolvanen at google.com  Fri Jan 21 12:51:40 2022
From: samitolvanen at google.com (Sami Tolvanen)
Date: Fri, 21 Jan 2022 12:51:40 -0800
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <CAHmME9ow7TxCaYYayRn9rdJJSdQ48tWQgdrW00g7mHaWvVJ+Zw@mail.gmail.com>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com> <YesPesOhftSzp2ft@sol.localdomain>
 <CAHmME9ow7TxCaYYayRn9rdJJSdQ48tWQgdrW00g7mHaWvVJ+Zw@mail.gmail.com>
Message-ID: <CABCJKuf=eHuFfNjD-7FBTeft3XNTkEc4G9cDvYpMJgH_se12eg@mail.gmail.com>

Hi Jason,

On Fri, Jan 21, 2022 at 12:23 PM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> On Fri, Jan 21, 2022 at 8:54 PM Eric Biggers <ebiggers at kernel.org> wrote:
> > There are some lines over 80 columns in this patch.
>
> I'll fix that up.
>
> > Otherwise this looks fine.  It would be really nice to fix this in clang,
> > though.
>
> I agree. I'm wondering whether it makes sense to roll with this patch,
> or to just not change anything and lean on Clang upstream to fix their
> bug. Full LTO is marked as "experimental" still. On the other hand,
> Android ships with it turned on, so how "experimental" can it really
> be? I don't have a strong read on the Clang ecosystem to know what
> makes most sense, to apply this or not. Do you have an opinion?

We'll work on fixing the compiler, but please note that it's most
likely going to take a while, so I would prefer to work around the
issue in the kernel for now.

Sami


From robh+dt at kernel.org  Fri Jan 21 13:06:57 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 15:06:57 -0600
Subject: [PATCH v1 14/14] dt-bindings: media: mediatek: mdp3: add yaml for
 new modules added in mt8195
In-Reply-To: <20220117055254.9777-15-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
 <20220117055254.9777-15-roy-cw.yeh@mediatek.com>
Message-ID: <CAL_JsqLcT4_h+5_ci5423rKzd8E8uJZyt7nus-zs+X=ZozPM6A@mail.gmail.com>

On Sun, Jan 16, 2022 at 11:53 PM roy-cw.yeh <roy-cw.yeh at mediatek.com> wrote:
>
> From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>
>
> Add yaml for new modules added in mt8195
>
> Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>
> ---
> This patch is base on [1]
> [1] dt-bindings: arm: mediatek: move out common module from display folder
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20220107101425.6917-8-jason-jh.lin at mediatek.com/

Looks to me like this is based on:

https://lore.kernel.org/r/20220105093758.6850-1-moudy.ho at mediatek.com

Can we have some coordination between all the MDP3 series. I have no
idea how all these sub-blocks fit together to provide any meaningful
review.

> ---
>  .../bindings/arm/mediatek/mediatek,mmsys.yaml |  2 +
>  .../bindings/media/mediatek,mdp3-aal.yaml     | 56 +++++++++++++++++
>  .../bindings/media/mediatek,mdp3-color.yaml   | 56 +++++++++++++++++
>  .../bindings/media/mediatek,mdp3-fg.yaml      | 55 +++++++++++++++++
>  .../bindings/media/mediatek,mdp3-hdr.yaml     | 55 +++++++++++++++++
>  .../bindings/media/mediatek,mdp3-merge.yaml   | 54 ++++++++++++++++
>  .../bindings/media/mediatek,mdp3-ovl.yaml     | 53 ++++++++++++++++
>  .../bindings/media/mediatek,mdp3-pad.yaml     | 56 +++++++++++++++++
>  .../bindings/media/mediatek,mdp3-rdma.yaml    | 28 +++++++++
>  .../bindings/media/mediatek,mdp3-rsz.yaml     |  2 +
>  .../bindings/media/mediatek,mdp3-split.yaml   | 58 ++++++++++++++++++
>  .../bindings/media/mediatek,mdp3-stitch.yaml  | 53 ++++++++++++++++
>  .../bindings/media/mediatek,mdp3-tcc.yaml     | 54 ++++++++++++++++
>  .../bindings/media/mediatek,mdp3-tdshp.yaml   | 61 +++++++++++++++++++
>  .../bindings/media/mediatek,mdp3-wrot.yaml    |  3 +
>  .../bindings/soc/mediatek/mediatek,mutex.yaml |  6 ++
>  16 files changed, 652 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-aal.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-color.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-fg.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-hdr.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-merge.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-ovl.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-pad.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-split.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-stitch.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tcc.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-tdshp.yaml
>
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> index 763c62323a74..9e59c8b738bb 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> @@ -31,6 +31,8 @@ properties:
>                - mediatek,mt8183-mmsys
>                - mediatek,mt8192-mmsys
>                - mediatek,mt8365-mmsys
> +              - mediatek,mt8195-vppsys0
> +              - mediatek,mt8195-vppsys1

What's the difference between 0 and 1? Defining instance indices is
not how things are described in DT. If this is just the same block
with different connections, then you should be describing the
connections (with the graph binding). If there's some other
difference, then maybe those should be properties. I'm pretty sure
I've said this before.

The same question applies to the rest of the schemas with numbering.

Rob


From lkp at intel.com  Fri Jan 21 13:13:03 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 22 Jan 2022 05:13:03 +0800
Subject: [PATCH v3 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220121172840.12121-5-alim.akhtar@samsung.com>
References: <20220121172840.12121-5-alim.akhtar@samsung.com>
Message-ID: <202201220550.FSQ6N02X-lkp@intel.com>

Hi Alim,

I love your patch! Perhaps something to improve:

[auto build test WARNING on next-20220121]
[also build test WARNING on v5.16]
[cannot apply to clk/clk-next robh/for-next pinctrl-samsung/for-next v5.16 v5.16-rc8 v5.16-rc7]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Alim-Akhtar/dt-bindings-add-vendor-prefix-for-Tesla/20220122-022924
base:    c94951012a748a0f8ed77cd8fc25640c6fe198f9
config: mips-allmodconfig (https://download.01.org/0day-ci/archive/20220122/202201220550.FSQ6N02X-lkp at intel.com/config)
compiler: mips-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/69b6b21ebabb149c1c07d83376e9c08a582c6423
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Alim-Akhtar/dt-bindings-add-vendor-prefix-for-Tesla/20220122-022924
        git checkout 69b6b21ebabb149c1c07d83376e9c08a582c6423
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=mips SHELL=/bin/bash drivers/clk/samsung/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/clk/samsung/clk-fsd.c:150:9: warning: this decimal constant is unsigned only in ISO C90
     150 |         PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
         |         ^~~~~~~~~~~~~
   In file included from include/linux/bits.h:22,
                    from include/linux/bitops.h:6,
                    from include/linux/of.h:15,
                    from include/linux/clk-provider.h:9,
                    from drivers/clk/samsung/clk-fsd.c:11:
>> include/linux/build_bug.h:16:51: warning: this decimal constant is unsigned only in ISO C90
      16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
         |                                                   ^
   drivers/clk/samsung/clk-pll.h:48:9: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
      48 |         BUILD_BUG_ON_ZERO(PLL_RATE(_fin, _m, _p, _s, _k, _ks) != (_fout)))
         |         ^~~~~~~~~~~~~~~~~
   drivers/clk/samsung/clk-pll.h:52:33: note: in expansion of macro 'PLL_VALID_RATE'
      52 |                 .rate   =       PLL_VALID_RATE(_fin, _rate,     \
         |                                 ^~~~~~~~~~~~~~
   drivers/clk/samsung/clk-fsd.c:150:9: note: in expansion of macro 'PLL_35XX_RATE'
     150 |         PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
         |         ^~~~~~~~~~~~~
   drivers/clk/samsung/clk-fsd.c:154:9: warning: this decimal constant is unsigned only in ISO C90
     154 |         PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
         |         ^~~~~~~~~~~~~
   In file included from include/linux/bits.h:22,
                    from include/linux/bitops.h:6,
                    from include/linux/of.h:15,
                    from include/linux/clk-provider.h:9,
                    from drivers/clk/samsung/clk-fsd.c:11:
>> include/linux/build_bug.h:16:51: warning: this decimal constant is unsigned only in ISO C90
      16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
         |                                                   ^
   drivers/clk/samsung/clk-pll.h:48:9: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
      48 |         BUILD_BUG_ON_ZERO(PLL_RATE(_fin, _m, _p, _s, _k, _ks) != (_fout)))
         |         ^~~~~~~~~~~~~~~~~
   drivers/clk/samsung/clk-pll.h:52:33: note: in expansion of macro 'PLL_VALID_RATE'
      52 |                 .rate   =       PLL_VALID_RATE(_fin, _rate,     \
         |                                 ^~~~~~~~~~~~~~
   drivers/clk/samsung/clk-fsd.c:154:9: note: in expansion of macro 'PLL_35XX_RATE'
     154 |         PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
         |         ^~~~~~~~~~~~~


vim +150 drivers/clk/samsung/clk-fsd.c

   148	
   149	static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
 > 150		PLL_35XX_RATE(24 * MHZ, 2400000000, 200, 2, 0),
   151	};
   152	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From robh at kernel.org  Fri Jan 21 13:16:49 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 15:16:49 -0600
Subject: [PATCH v11 1/3] dt-binding: mt8183: add Mediatek MDP3 dt-bindings
In-Reply-To: <20220105093758.6850-2-moudy.ho@mediatek.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-2-moudy.ho@mediatek.com>
Message-ID: <YesiwTSxa9HJ1lxG@robh.at.kernel.org>

On Wed, Jan 05, 2022 at 05:37:56PM +0800, Moudy Ho wrote:
> This patch adds DT binding document for Media Data Path 3 (MDP3)
> a unit in multimedia system used for scaling and color format convert.
> 
> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> ---
>  .../bindings/media/mediatek,mdp3-rdma.yaml    | 193 ++++++++++++++++++
>  .../bindings/media/mediatek,mdp3-rsz.yaml     |  55 +++++
>  .../bindings/media/mediatek,mdp3-wrot.yaml    |  57 ++++++
>  .../bindings/soc/mediatek/mediatek,ccorr.yaml |  47 +++++
>  .../bindings/soc/mediatek/mediatek,wdma.yaml  |  58 ++++++
>  5 files changed, 410 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>  create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
>  create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
>  create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> new file mode 100644
> index 000000000000..002503383934
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> @@ -0,0 +1,193 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Read Direct Memory Access
> +
> +maintainers:
> +  - Matthias Brugger <matthias.bgg at gmail.com>
> +
> +description: |
> +  Mediatek Read Direct Memory Access(RDMA) component used to do read DMA.
> +  It contains one line buffer to store the sufficient pixel data, and
> +  must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +  The 1st RDMA is also used to be a controller node in Media Data Path 3(MDP3)
> +  that containing MMSYS, MUTEX, GCE and SCP settings.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          # MDP3 controller node
> +          - const: mediatek,mt8183-mdp3

How is this more specific than this:

> +          - const: mediatek,mt8183-mdp3-rdma0

> +      - items:
> +          # normal RDMA conponent
> +          - const: mediatek,mt8183-mdp3-rdma0
> +
> +  mediatek,scp:
> +    description: The node of system control processor (SCP), using
> +      the remoteproc & rpmsg framework.
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +
> +  mediatek,mdp3-comps:
> +    description: MTK sub-system of direct-link or DIP

This needs a better description. What is DIP? What is direct-link?

> +    $ref: /schemas/types.yaml#/definitions/string-array
> +    items:
> +      - enum:
> +          # MDP direct-link input path selection, create a
> +          # component for path connectedness of HW pipe control
> +          - mediatek,mt8183-mdp3-dl1
> +      - enum:
> +          - mediatek,mt8183-mdp3-dl2
> +      - enum:
> +          # MDP direct-link output path selection, create a
> +          # component for path connectedness of HW pipe control
> +          - mediatek,mt8183-mdp3-path1
> +      - enum:
> +          - mediatek,mt8183-mdp3-path2
> +      - enum:
> +          # Input DMA of ISP PASS2 (DIP) module for raw image input
> +          - mediatek,mt8183-mdp3-imgi
> +      - enum:
> +          # Output DMA of ISP PASS2 (DIP) module for YUV image output
> +          - mediatek,mt8183-mdp3-exto

There's only 1 possible value for mediatek,mdp3-comps, so why does it 
need to be in DT? 

> +
> +  reg:
> +    items:
> +      - description: basic RDMA HW address
> +      - description: MDP direct-link 1st and 2nd input
> +      - description: MDP direct-link 1st output
> +      - description: MDP direct-link 2nd output
> +      - description: ISP input and output
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    items:
> +      - description: GCE client for RDMA
> +      - description: GCR client for MDP direct-link 1st and 2nd input
> +      - description: GCR client for MDP direct-link 1st output
> +      - description: GCR client for MDP direct-link 2nd output
> +      - description: GCR client for ISP input and output
> +
> +  power-domains:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: RDMA clock
> +      - description: RSZ clock
> +      - description: direck-link TX clock in MDP side
> +      - description: direck-link RX clock in MDP side
> +      - description: direck-link TX clock in ISP side
> +      - description: direck-link RX clock in ISP side
> +
> +  iommus:
> +    maxItems: 1
> +
> +  mediatek,mmsys:
> +    description: The node of mux(multiplexer) controller for HW connections.
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +
> +  mediatek,mm-mutex:

Is this some sort of h/w lock? We have a standard binding for that.

> +    description: The node of sof(start of frame) signal controller.
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    maxItems: 1
> +
> +  mediatek,mailbox-gce:
> +    description: The node of global command engine (GCE), used to read/write
> +      registers with critical time limitation.
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +
> +  mboxes:
> +    items:
> +      - description: used for 1st data pipe from RDMA
> +      - description: used for 2nd data pipe from RDMA
> +      - description: used for 3rd data pipe from Direct-Link
> +      - description: used for 4th data pipe from Direct-Link
> +
> +  gce-subsys:
> +    description: sub-system id corresponding to the global command engine (GCE)
> +      register address.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +if:
> +  properties:
> +    compatible:
> +      contains:
> +        const: mediatek,mt8183-mdp3
> +
> +then:
> +  required:
> +    - mediatek,scp
> +    - mediatek,mmsys
> +    - mediatek,mm-mutex
> +    - mediatek,mailbox-gce
> +    - mboxes
> +    - gce-subsys
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - mediatek,gce-client-reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8183-clk.h>
> +    #include <dt-bindings/gce/mt8183-gce.h>
> +    #include <dt-bindings/power/mt8183-power.h>
> +    #include <dt-bindings/memory/mt8183-larb-port.h>
> +
> +    mdp3_rdma0: mdp3_rdma0 at 14001000 {
> +      compatible = "mediatek,mt8183-mdp3",
> +                   "mediatek,mt8183-mdp3-rdma0";
> +      mediatek,scp = <&scp>;
> +      mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
> +                            "mediatek,mt8183-mdp3-dl2",
> +                            "mediatek,mt8183-mdp3-path1",
> +                            "mediatek,mt8183-mdp3-path2",
> +                            "mediatek,mt8183-mdp3-imgi",
> +                            "mediatek,mt8183-mdp3-exto";
> +      reg = <0x14001000 0x1000>,
> +            <0x14000000 0x1000>,
> +            <0x14005000 0x1000>,
> +            <0x14006000 0x1000>,
> +            <0x15020000 0x1000>;
> +      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
> +                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
> +                                <&gce SUBSYS_1502XXXX 0 0x1000>;
> +      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> +               <&mmsys CLK_MM_MDP_RSZ1>,
> +               <&mmsys CLK_MM_MDP_DL_TXCK>,
> +               <&mmsys CLK_MM_MDP_DL_RX>,
> +               <&mmsys CLK_MM_IPU_DL_TXCK>,
> +               <&mmsys CLK_MM_IPU_DL_RX>;
> +      iommus = <&iommu>;
> +      mediatek,mmsys = <&mmsys>;
> +      mediatek,mm-mutex = <&mutex>;
> +      mediatek,mailbox-gce = <&gce>;
> +      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
> +               <&gce 21 CMDQ_THR_PRIO_LOWEST>,
> +               <&gce 22 CMDQ_THR_PRIO_LOWEST>,
> +               <&gce 23 CMDQ_THR_PRIO_LOWEST>;
> +      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> +                   <&gce 0x14010000 SUBSYS_1401XXXX>,
> +                   <&gce 0x14020000 SUBSYS_1402XXXX>,
> +                   <&gce 0x15020000 SUBSYS_1502XXXX>;
> +    };
> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> new file mode 100644
> index 000000000000..cd4cf1531535
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> @@ -0,0 +1,55 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Resizer
> +
> +maintainers:
> +  - Matthias Brugger <matthias.bgg at gmail.com>
> +
> +description: |
> +  One of Media Data Path 3 (MDP3) components used to do frame resizing.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8183-mdp3-rsz0
> +          - mediatek,mt8183-mdp3-rsz1

Again, what's the difference between 0 and 1?

I've probably asked that before, but without a sufficient reasoning 
here in the schema I'm just going to keep asking the same question.

Rob


From robh at kernel.org  Fri Jan 21 13:27:08 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 15:27:08 -0600
Subject: [PATCH v4 1/3] dt-bindings: interconnect: imx8m-noc: Add
 fsl,icc-id property
In-Reply-To: <20220106164150.3474048-1-abel.vesa@nxp.com>
References: <20220106164150.3474048-1-abel.vesa@nxp.com>
Message-ID: <YeslLJqwhX668+oa@robh.at.kernel.org>

On Thu, Jan 06, 2022 at 06:41:48PM +0200, Abel Vesa wrote:
> Add documentation for fsl,icc-id property.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
> 
> Changes since v3:
>  * fixed typo in property description
> 
>  .../devicetree/bindings/interconnect/fsl,imx8m-noc.yaml      | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> index b8204ed22dd5..dc7f6b6f508a 100644
> --- a/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> +++ b/Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
> @@ -47,6 +47,11 @@ properties:
>    operating-points-v2: true
>    opp-table: true
>  
> +  fsl,icc-id:
> +    $ref: "/schemas/types.yaml#/definitions/uint32"
> +    description:
> +      unique ID used for linking i.MX bus or ddrc node to interconnect

Where does this unique ID come from and how is it used? Why aren't cells 
in 'interconnects' sufficient for this?

> +
>    fsl,ddrc:
>      $ref: "/schemas/types.yaml#/definitions/phandle"
>      description:
> -- 
> 2.31.1
> 
> 


From sean.anderson at seco.com  Fri Jan 21 13:34:45 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Fri, 21 Jan 2022 16:34:45 -0500
Subject: [PATCH v12 2/2] pwm: Add support for Xilinx AXI Timer
In-Reply-To: <20211217233015.67664-2-sean.anderson@seco.com>
References: <20211217233015.67664-1-sean.anderson@seco.com>
 <20211217233015.67664-2-sean.anderson@seco.com>
Message-ID: <f9adf970-aea8-1fed-d02d-c7d47491e993@seco.com>



On 12/17/21 6:30 PM, Sean Anderson wrote:
> This adds PWM support for Xilinx LogiCORE IP AXI soft timers commonly
> found on Xilinx FPGAs. At the moment clock control is very basic: we
> just enable the clock during probe and pin the frequency. In the future,
> someone could add support for disabling the clock when not in use.
> 
> Some common code has been specially demarcated. While currently only
> used by the PWM driver, it is anticipated that it may be split off in
> the future to be used by the timer driver as well.
> 
> This driver was written with reference to Xilinx DS764 for v1.03.a [1].
> 
> [1] https://www.xilinx.com/support/documentation/ip_documentation/axi_timer/v1_03_a/axi_timer_ds764.pdf
> 
> Signed-off-by: Sean Anderson <sean.anderson at seco.com>
> Acked-by: Michal Simek <michal.simek at xilinx.com>
> ---
> 
> Changes in v12:
> - Add a comment to the timer driver about #pwm-cells
> - Combine/expand comments on rounding in xilinx_pwm_apply
> 
> Changes in v11:
> - Add comment about why we test for #pwm-cells
> - Clarify comment on generate out signal
> - Rename pwm variables to xilinx_pwm
> - Round like Uwe wants...
> - s/xilinx_timer/xilinx_pwm/ for non-common functions
> 
> Changes in v10:
> - Fix compilation error in timer driver
> 
> Changes in v9:
> - Refactor "if { return } else if { }" to "if { return } if { }"
> - Remove drivers/clocksource/timer-xilinx-common.c from MAINTAINERS
> - Remove xilinx_timer_common_init and integrate it into xilinx_timer_probe
> 
> Changes in v8:
> - Drop new timer driver; it has been deferred for future series
> 
> Changes in v7:
> - Add dependency on OF_ADDRESS
> - Fix period_cycles calculation
> - Fix typo in limitations
> 
> Changes in v6:
> - Capitalize error messages
> - Don't disable regmap locking to allow inspection of registers via
>    debugfs
> - Prevent overflow when calculating period_cycles
> - Remove enabled variable from xilinx_pwm_apply
> - Swap order of period_cycle range comparisons
> 
> Changes in v5:
> - Allow non-zero #pwm-cells
> - Correctly set duty_cycle in get_state when TLR0=TLR1
> - Elaborate on limitation section
> - Perform some additional checks/rounding in apply_state
> - Remove xlnx,axi-timer-2.0 compatible string
> - Rework duty-cycle and period calculations with feedback from Uwe
> - Switch to regmap to abstract endianness issues
> - Use more verbose error messages
> 
> Changes in v4:
> - Don't use volatile in read/write replacements. Some arches have it and
>    some don't.
> - Put common timer properties into their own struct to better reuse
>    code.
> - Remove references to properties which are not good enough for Linux.
> 
> Changes in v3:
> - Add clockevent and clocksource support
> - Remove old microblaze driver
> - Rewrite probe to only use a device_node, since timers may need to be
>    initialized before we have proper devices. This does bloat the code a bit
>    since we can no longer rely on helpers such as dev_err_probe. We also
>    cannot rely on device resources being free'd on failure, so we must free
>    them manually.
> - We now access registers through xilinx_timer_(read|write). This allows us
>    to deal with endianness issues, as originally seen in the microblaze
>    driver. CAVEAT EMPTOR: I have not tested this on big-endian!
> 
> Changes in v2:
> - Add comment describing device
> - Add comment explaining why we depend on !MICROBLAZE
> - Add dependencies on COMMON_CLK and HAS_IOMEM
> - Cast dividends to u64 to avoid overflow
> - Check for over- and underflow when calculating TLR
> - Check range of xlnx,count-width
> - Don't compile this module by default for arm64
> - Don't set pwmchip.base to -1
> - Ensure the clock is always running when the pwm is registered
> - Remove debugfs file :l
> - Rename TCSR_(SET|CLEAR) to TCSR_RUN_(SET|CLEAR)
> - Report errors with dev_error_probe
> - Set xilinx_pwm_ops.owner
> - Use NSEC_TO_SEC instead of defining our own
> - Use TCSR_RUN_MASK to check if the PWM is enabled, as suggested by Uwe
> 
>   MAINTAINERS                        |   6 +
>   arch/microblaze/kernel/timer.c     |   4 +
>   drivers/pwm/Kconfig                |  14 ++
>   drivers/pwm/Makefile               |   1 +
>   drivers/pwm/pwm-xilinx.c           | 319 +++++++++++++++++++++++++++++
>   include/clocksource/timer-xilinx.h |  91 ++++++++
>   6 files changed, 435 insertions(+)
>   create mode 100644 drivers/pwm/pwm-xilinx.c
>   create mode 100644 include/clocksource/timer-xilinx.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 13f9a84a617e..373757fcc8c6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -20925,6 +20925,12 @@ F:	drivers/misc/Makefile
>   F:	drivers/misc/xilinx_sdfec.c
>   F:	include/uapi/misc/xilinx_sdfec.h
>   
> +XILINX PWM DRIVER
> +M:	Sean Anderson <sean.anderson at seco.com>
> +S:	Maintained
> +F:	drivers/pwm/pwm-xilinx.c
> +F:	include/clocksource/timer-xilinx.h
> +
>   XILINX UARTLITE SERIAL DRIVER
>   M:	Peter Korsgaard <jacmet at sunsite.dk>
>   L:	linux-serial at vger.kernel.org
> diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
> index f8832cf49384..26c385582c3b 100644
> --- a/arch/microblaze/kernel/timer.c
> +++ b/arch/microblaze/kernel/timer.c
> @@ -251,6 +251,10 @@ static int __init xilinx_timer_init(struct device_node *timer)
>   	u32 timer_num = 1;
>   	int ret;
>   
> +	/* If this property is present, the device is a PWM and not a timer */
> +	if (of_property_read_bool(timer, "#pwm-cells"))
> +		return 0;
> +
>   	if (initialized)
>   		return -EINVAL;
>   
> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> index 21e3b05a5153..cefbf00b4c7e 100644
> --- a/drivers/pwm/Kconfig
> +++ b/drivers/pwm/Kconfig
> @@ -640,4 +640,18 @@ config PWM_VT8500
>   	  To compile this driver as a module, choose M here: the module
>   	  will be called pwm-vt8500.
>   
> +config PWM_XILINX
> +	tristate "Xilinx AXI Timer PWM support"
> +	depends on OF_ADDRESS
> +	depends on COMMON_CLK
> +	select REGMAP_MMIO
> +	help
> +	  PWM driver for Xilinx LogiCORE IP AXI timers. This timer is
> +	  typically a soft core which may be present in Xilinx FPGAs.
> +	  This device may also be present in Microblaze soft processors.
> +	  If you don't have this IP in your design, choose N.
> +
> +	  To compile this driver as a module, choose M here: the module
> +	  will be called pwm-xilinx.
> +
>   endif
> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> index 708840b7fba8..ea785480359b 100644
> --- a/drivers/pwm/Makefile
> +++ b/drivers/pwm/Makefile
> @@ -60,3 +60,4 @@ obj-$(CONFIG_PWM_TWL)		+= pwm-twl.o
>   obj-$(CONFIG_PWM_TWL_LED)	+= pwm-twl-led.o
>   obj-$(CONFIG_PWM_VISCONTI)	+= pwm-visconti.o
>   obj-$(CONFIG_PWM_VT8500)	+= pwm-vt8500.o
> +obj-$(CONFIG_PWM_XILINX)	+= pwm-xilinx.o
> diff --git a/drivers/pwm/pwm-xilinx.c b/drivers/pwm/pwm-xilinx.c
> new file mode 100644
> index 000000000000..b4d93e8812c6
> --- /dev/null
> +++ b/drivers/pwm/pwm-xilinx.c
> @@ -0,0 +1,319 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
> + *
> + * Limitations:
> + * - When changing both duty cycle and period, we may end up with one cycle
> + *   with the old duty cycle and the new period. This is because the counters
> + *   may only be reloaded by first stopping them, or by letting them be
> + *   automatically reloaded at the end of a cycle. If this automatic reload
> + *   happens after we set TLR0 but before we set TLR1 then we will have a
> + *   bad cycle. This could probably be fixed by reading TCR0 just before
> + *   reprogramming, but I think it would add complexity for little gain.
> + * - Cannot produce 100% duty cycle by configuring the TLRs. This might be
> + *   possible by stopping the counters at an appropriate point in the cycle,
> + *   but this is not (yet) implemented.
> + * - Only produces "normal" output.
> + * - Always produces low output if disabled.
> + */
> +
> +#include <clocksource/timer-xilinx.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +#include <linux/pwm.h>
> +#include <linux/regmap.h>
> +
> +/*
> + * The following functions are "common" to drivers for this device, and may be
> + * exported at a future date.
> + */
> +u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr,
> +			    u64 cycles)
> +{
> +	WARN_ON(cycles < 2 || cycles - 2 > priv->max);
> +
> +	if (tcsr & TCSR_UDT)
> +		return cycles - 2;
> +	return priv->max - cycles + 2;
> +}
> +
> +unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
> +				     u32 tlr, u32 tcsr)
> +{
> +	u64 cycles;
> +
> +	if (tcsr & TCSR_UDT)
> +		cycles = tlr + 2;
> +	else
> +		cycles = (u64)priv->max - tlr + 2;
> +
> +	/* cycles has a max of 2^32 + 2 */
> +	return DIV64_U64_ROUND_UP(cycles * NSEC_PER_SEC,
> +				  clk_get_rate(priv->clk));
> +}
> +
> +/*
> + * The idea here is to capture whether the PWM is actually running (e.g.
> + * because we or the bootloader set it up) and we need to be careful to ensure
> + * we don't cause a glitch. According to the data sheet, to enable the PWM we
> + * need to
> + *
> + * - Set both timers to generate mode (MDT=1)
> + * - Set both timers to PWM mode (PWMA=1)
> + * - Enable the generate out signals (GENT=1)
> + *
> + * In addition,
> + *
> + * - The timer must be running (ENT=1)
> + * - The timer must auto-reload TLR into TCR (ARHT=1)
> + * - We must not be in the process of loading TLR into TCR (LOAD=0)
> + * - Cascade mode must be disabled (CASC=0)
> + *
> + * If any of these differ from usual, then the PWM is either disabled, or is
> + * running in a mode that this driver does not support.
> + */
> +#define TCSR_PWM_SET (TCSR_GENT | TCSR_ARHT | TCSR_ENT | TCSR_PWMA)
> +#define TCSR_PWM_CLEAR (TCSR_MDT | TCSR_LOAD)
> +#define TCSR_PWM_MASK (TCSR_PWM_SET | TCSR_PWM_CLEAR)
> +
> +struct xilinx_pwm_device {
> +	struct pwm_chip chip;
> +	struct xilinx_timer_priv priv;
> +};
> +
> +static inline struct xilinx_timer_priv
> +*xilinx_pwm_chip_to_priv(struct pwm_chip *chip)
> +{
> +	return &container_of(chip, struct xilinx_pwm_device, chip)->priv;
> +}
> +
> +static bool xilinx_timer_pwm_enabled(u32 tcsr0, u32 tcsr1)
> +{
> +	return ((TCSR_PWM_MASK | TCSR_CASC) & tcsr0) == TCSR_PWM_SET &&
> +		(TCSR_PWM_MASK & tcsr1) == TCSR_PWM_SET;
> +}
> +
> +static int xilinx_pwm_apply(struct pwm_chip *chip, struct pwm_device *unused,
> +			    const struct pwm_state *state)
> +{
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +	u64 period_cycles, duty_cycles;
> +	unsigned long rate;
> +
> +	if (state->polarity != PWM_POLARITY_NORMAL)
> +		return -EINVAL;
> +
> +	/*
> +	 * To be representable by TLR, cycles must be between 2 and
> +	 * priv->max + 2. To enforce this we can reduce the cycles, but we may
> +	 * not increase them. Caveat emptor: while this does result in more
> +	 * predictable rounding, it may also result in a completely different
> +	 * duty cycle (% high time) than what was requested.
> +	 */
> +	rate = clk_get_rate(priv->clk);
> +	/* Avoid overflow */
> +	period_cycles = min_t(u64, state->period, ULONG_MAX * NSEC_PER_SEC);
> +	period_cycles = mul_u64_u32_div(period_cycles, rate, NSEC_PER_SEC);
> +	period_cycles = min_t(u64, period_cycles, priv->max + 2);
> +	if (period_cycles < 2)
> +		return -ERANGE;
> +
> +	/* Same thing for duty cycles */
> +	duty_cycles = min_t(u64, state->duty_cycle, ULONG_MAX * NSEC_PER_SEC);
> +	duty_cycles = mul_u64_u32_div(duty_cycles, rate, NSEC_PER_SEC);
> +	duty_cycles = min_t(u64, duty_cycles, priv->max + 2);
> +
> +	/*
> +	 * If we specify 100% duty cycle, we will get 0% instead, so decrease
> +	 * the duty cycle count by one.
> +	 */
> +	if (duty_cycles >= period_cycles)
> +		duty_cycles = period_cycles - 1;
> +
> +	/* Round down to 0% duty cycle for unrepresentable duty cycles */
> +	if (duty_cycles < 2)
> +		duty_cycles = period_cycles;
> +
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	tlr0 = xilinx_timer_tlr_cycles(priv, tcsr0, period_cycles);
> +	tlr1 = xilinx_timer_tlr_cycles(priv, tcsr1, duty_cycles);
> +	regmap_write(priv->map, TLR0, tlr0);
> +	regmap_write(priv->map, TLR1, tlr1);
> +
> +	if (state->enabled) {
> +		/*
> +		 * If the PWM is already running, then the counters will be
> +		 * reloaded at the end of the current cycle.
> +		 */
> +		if (!xilinx_timer_pwm_enabled(tcsr0, tcsr1)) {
> +			/* Load TLR into TCR */
> +			regmap_write(priv->map, TCSR0, tcsr0 | TCSR_LOAD);
> +			regmap_write(priv->map, TCSR1, tcsr1 | TCSR_LOAD);
> +			/* Enable timers all at once with ENALL */
> +			tcsr0 = (TCSR_PWM_SET & ~TCSR_ENT) | (tcsr0 & TCSR_UDT);
> +			tcsr1 = TCSR_PWM_SET | TCSR_ENALL | (tcsr1 & TCSR_UDT);
> +			regmap_write(priv->map, TCSR0, tcsr0);
> +			regmap_write(priv->map, TCSR1, tcsr1);
> +		}
> +	} else {
> +		regmap_write(priv->map, TCSR0, 0);
> +		regmap_write(priv->map, TCSR1, 0);
> +	}
> +
> +	return 0;
> +}
> +
> +static void xilinx_pwm_get_state(struct pwm_chip *chip,
> +				 struct pwm_device *unused,
> +				 struct pwm_state *state)
> +{
> +	struct xilinx_timer_priv *priv = xilinx_pwm_chip_to_priv(chip);
> +	u32 tlr0, tlr1, tcsr0, tcsr1;
> +
> +	regmap_read(priv->map, TLR0, &tlr0);
> +	regmap_read(priv->map, TLR1, &tlr1);
> +	regmap_read(priv->map, TCSR0, &tcsr0);
> +	regmap_read(priv->map, TCSR1, &tcsr1);
> +	state->period = xilinx_timer_get_period(priv, tlr0, tcsr0);
> +	state->duty_cycle = xilinx_timer_get_period(priv, tlr1, tcsr1);
> +	state->enabled = xilinx_timer_pwm_enabled(tcsr0, tcsr1);
> +	state->polarity = PWM_POLARITY_NORMAL;
> +
> +	/* 100% duty cycle results in constant low output */
> +	if (state->period == state->duty_cycle)
> +		state->duty_cycle = 0;
> +}
> +
> +static const struct pwm_ops xilinx_pwm_ops = {
> +	.apply = xilinx_pwm_apply,
> +	.get_state = xilinx_pwm_get_state,
> +	.owner = THIS_MODULE,
> +};
> +
> +static const struct regmap_config xilinx_pwm_regmap_config = {
> +	.reg_bits = 32,
> +	.reg_stride = 4,
> +	.val_bits = 32,
> +	.val_format_endian = REGMAP_ENDIAN_LITTLE,
> +	.max_register = TCR1,
> +};
> +
> +static int xilinx_pwm_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
> +	struct xilinx_timer_priv *priv;
> +	struct xilinx_pwm_device *xilinx_pwm;
> +	u32 pwm_cells, one_timer, width;
> +	void __iomem *regs;
> +
> +	/* If there are no PWM cells, this binding is for a timer */
> +	ret = of_property_read_u32(np, "#pwm-cells", &pwm_cells);
> +	if (ret == -EINVAL)
> +		return -ENODEV;
> +	if (ret)
> +		return dev_err_probe(dev, ret, "could not read #pwm-cells\n");
> +
> +	xilinx_pwm = devm_kzalloc(dev, sizeof(*xilinx_pwm), GFP_KERNEL);
> +	if (!xilinx_pwm)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, xilinx_pwm);
> +	priv = &xilinx_pwm->priv;
> +
> +	regs = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(regs))
> +		return PTR_ERR(regs);
> +
> +	priv->map = devm_regmap_init_mmio(dev, regs,
> +					  &xilinx_pwm_regmap_config);
> +	if (IS_ERR(priv->map))
> +		return dev_err_probe(dev, PTR_ERR(priv->map),
> +				     "Could not create regmap\n");
> +
> +	ret = of_property_read_u32(np, "xlnx,one-timer-only", &one_timer);
> +	if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "Could not read xlnx,one-timer-only\n");
> +
> +	if (one_timer)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "Two timers required for PWM mode\n");
> +
> +
> +	ret = of_property_read_u32(np, "xlnx,count-width", &width);
> +	if (ret == -EINVAL)
> +		width = 32;
> +	else if (ret)
> +		return dev_err_probe(dev, ret,
> +				     "Could not read xlnx,count-width\n");
> +
> +	if (width != 8 && width != 16 && width != 32)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "Invalid counter width %d\n", width);
> +	priv->max = BIT_ULL(width) - 1;
> +
> +	/*
> +	 * The polarity of the Generate Out signals must be active high for PWM
> +	 * mode to work. We could determine this from the device tree, but
> +	 * alas, such properties are not allowed to be used.
> +	 */
> +
> +	priv->clk = devm_clk_get(dev, "s_axi_aclk");
> +	if (IS_ERR(priv->clk))
> +		return dev_err_probe(dev, PTR_ERR(priv->clk),
> +				     "Could not get clock\n");
> +
> +	ret = clk_prepare_enable(priv->clk);
> +	if (ret)
> +		return dev_err_probe(dev, ret, "Clock enable failed\n");
> +	clk_rate_exclusive_get(priv->clk);
> +
> +	xilinx_pwm->chip.dev = dev;
> +	xilinx_pwm->chip.ops = &xilinx_pwm_ops;
> +	xilinx_pwm->chip.npwm = 1;
> +	ret = pwmchip_add(&xilinx_pwm->chip);
> +	if (ret) {
> +		clk_rate_exclusive_put(priv->clk);
> +		clk_disable_unprepare(priv->clk);
> +		return dev_err_probe(dev, ret, "Could not register PWM chip\n");
> +	}
> +
> +	return 0;
> +}
> +
> +static int xilinx_pwm_remove(struct platform_device *pdev)
> +{
> +	struct xilinx_pwm_device *xilinx_pwm = platform_get_drvdata(pdev);
> +
> +	pwmchip_remove(&xilinx_pwm->chip);
> +	clk_rate_exclusive_put(xilinx_pwm->priv.clk);
> +	clk_disable_unprepare(xilinx_pwm->priv.clk);
> +	return 0;
> +}
> +
> +static const struct of_device_id xilinx_pwm_of_match[] = {
> +	{ .compatible = "xlnx,xps-timer-1.00.a", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, xilinx_pwm_of_match);
> +
> +static struct platform_driver xilinx_pwm_driver = {
> +	.probe = xilinx_pwm_probe,
> +	.remove = xilinx_pwm_remove,
> +	.driver = {
> +		.name = "xilinx-pwm",
> +		.of_match_table = of_match_ptr(xilinx_pwm_of_match),
> +	},
> +};
> +module_platform_driver(xilinx_pwm_driver);
> +
> +MODULE_ALIAS("platform:xilinx-pwm");
> +MODULE_DESCRIPTION("PWM driver for Xilinx LogiCORE IP AXI Timer");
> +MODULE_LICENSE("GPL v2");
> diff --git a/include/clocksource/timer-xilinx.h b/include/clocksource/timer-xilinx.h
> new file mode 100644
> index 000000000000..1f7757b84a5e
> --- /dev/null
> +++ b/include/clocksource/timer-xilinx.h
> @@ -0,0 +1,91 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2021 Sean Anderson <sean.anderson at seco.com>
> + */
> +
> +#ifndef XILINX_TIMER_H
> +#define XILINX_TIMER_H
> +
> +#include <linux/compiler.h>
> +
> +#define TCSR0	0x00
> +#define TLR0	0x04
> +#define TCR0	0x08
> +#define TCSR1	0x10
> +#define TLR1	0x14
> +#define TCR1	0x18
> +
> +#define TCSR_MDT	BIT(0)
> +#define TCSR_UDT	BIT(1)
> +#define TCSR_GENT	BIT(2)
> +#define TCSR_CAPT	BIT(3)
> +#define TCSR_ARHT	BIT(4)
> +#define TCSR_LOAD	BIT(5)
> +#define TCSR_ENIT	BIT(6)
> +#define TCSR_ENT	BIT(7)
> +#define TCSR_TINT	BIT(8)
> +#define TCSR_PWMA	BIT(9)
> +#define TCSR_ENALL	BIT(10)
> +#define TCSR_CASC	BIT(11)
> +
> +struct clk;
> +struct device_node;
> +struct regmap;
> +
> +/**
> + * struct xilinx_timer_priv - Private data for Xilinx AXI timer drivers
> + * @map: Regmap of the device, possibly with an offset
> + * @clk: Parent clock
> + * @max: Maximum value of the counters
> + */
> +struct xilinx_timer_priv {
> +	struct regmap *map;
> +	struct clk *clk;
> +	u32 max;
> +};
> +
> +/**
> + * xilinx_timer_tlr_cycles() - Calculate the TLR for a period specified
> + *                             in clock cycles
> + * @priv: The timer's private data
> + * @tcsr: The value of the TCSR register for this counter
> + * @cycles: The number of cycles in this period
> + *
> + * Callers of this function MUST ensure that @cycles is representable as
> + * a TLR.
> + *
> + * Return: The calculated value for TLR
> + */
> +u32 xilinx_timer_tlr_cycles(struct xilinx_timer_priv *priv, u32 tcsr,
> +			    u64 cycles);
> +
> +/**
> + * xilinx_timer_get_period() - Get the current period of a counter
> + * @priv: The timer's private data
> + * @tlr: The value of TLR for this counter
> + * @tcsr: The value of TCSR for this counter
> + *
> + * Return: The period, in ns
> + */
> +unsigned int xilinx_timer_get_period(struct xilinx_timer_priv *priv,
> +				     u32 tlr, u32 tcsr);
> +
> +/**
> + * xilinx_timer_common_init() - Perform common initialization for Xilinx
> + *                              AXI timer drivers.
> + * @priv: The timer's private data
> + * @np: The devicetree node for the timer
> + * @one_timer: Set to %1 if there is only one timer
> + *
> + * This performs common initialization, such as detecting endianness,
> + * and parsing devicetree properties. @priv->regs must be initialized
> + * before calling this function. This function initializes @priv->read,
> + * @priv->write, and @priv->width.
> + *
> + * Return: 0, or negative errno
> + */
> +int xilinx_timer_common_init(struct device_node *np,
> +			     struct xilinx_timer_priv *priv,
> +			     u32 *one_timer);
> +
> +#endif /* XILINX_TIMER_H */
> 

ping?

Uwe/Thierry, can you have a look at this?

--Sean


From robh at kernel.org  Fri Jan 21 14:08:54 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 16:08:54 -0600
Subject: [PATCH v5 2/4] dt-bindings: input: Add Cypress TT2100
 touchscreen controller
In-Reply-To: <20220109115331.388633-3-alistair@alistair23.me>
References: <20220109115331.388633-1-alistair@alistair23.me>
 <20220109115331.388633-3-alistair@alistair23.me>
Message-ID: <Yesu9riVhZb1b8Jj@robh.at.kernel.org>

On Sun, Jan 09, 2022 at 09:53:29PM +1000, Alistair Francis wrote:
> From: Myl?ne Josserand <mylene.josserand at free-electrons.com>
> 
> Add the Cypress TrueTouch Generation 5 touchscreen device tree bindings
> documentation. It can use I2C or SPI bus.
> This touchscreen can handle some defined zone that are designed and
> sent as button. To be able to customize the keycode sent, the
> "linux,code" property in a "button" sub-node can be used.
> 
> Signed-off-by: Myl?ne Josserand <mylene.josserand at free-electrons.com>
> Signed-off-by: Alistair Francis <alistair at alistair23.me>
> ---
>  .../input/touchscreen/cypress,tt21000.yaml    | 92 +++++++++++++++++++
>  1 file changed, 92 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> 
> diff --git a/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> new file mode 100644
> index 000000000000..acd2d9389f8c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/touchscreen/cypress,tt21000.yaml
> @@ -0,0 +1,92 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/touchscreen/cypress,tt21000.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Cypress TT2100 touchscreen controller
> +
> +description: The Cypress TT2100 series (also known as "CYTTSP5" after
> +  the marketing name Cypress TrueTouch Standard Product series 5).
> +
> +maintainers:
> +  - Alistair Francis <alistair at alistair23.me>
> +
> +allOf:
> +  - $ref: touchscreen.yaml#
> +
> +properties:
> +  compatible:
> +    const: cypress,tt21000
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  vdd-supply:
> +    description: Regulator for voltage.
> +
> +  reset-gpios:
> +    maxItems: 1
> +
> +  linux,code:
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    description: EV_ABS specific event code generated by the axis.
> +
> +patternProperties:
> +  "^button-[0-9]+$":

Where does the numbering come from? I assume it correlates to something 
in the h/w. If so, I think you should use 'reg' and a unit-address here. 
Generally, we don't want the node names to be important (i.e. used by 
the OS).

> +    type: object
> +    properties:
> +      linux,code:
> +        $ref: /schemas/types.yaml#/definitions/uint32
> +        description: Keycode to emit
> +
> +    required:
> +      - linux,code
> +
> +    additionalProperties: false
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - vdd-supply
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/input/linux-event-codes.h>
> +
> +    i2c {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        touchscreen at 24 {
> +            compatible = "cypress,tt21000";
> +            reg = <0x24>;
> +            pinctrl-names = "default";
> +            pinctrl-0 = <&tp_reset_ds203>;
> +            interrupt-parent = <&pio>;
> +            interrupts = <1 5 IRQ_TYPE_LEVEL_LOW>;
> +            reset-gpios = <&pio 7 1 GPIO_ACTIVE_LOW>;
> +            vdd-supply = <&reg_touch>;
> +
> +            button-0 {
> +                linux,code = <KEY_HOMEPAGE>;
> +            };
> +
> +            button-1 {
> +                linux,code = <KEY_MENU>;
> +            };
> +
> +            button-2 {
> +                linux,code = <KEY_BACK>;
> +            };
> +        };
> +    };
> +...
> -- 
> 2.31.1
> 
> 


From nathan at kernel.org  Fri Jan 21 14:17:43 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Fri, 21 Jan 2022 15:17:43 -0700
Subject: [PATCH 13/14] ARM: use .arch directives instead of assembler
 command line flags
In-Reply-To: <20210928154143.2106903-14-arnd@kernel.org>
References: <20210928154143.2106903-1-arnd@kernel.org>
 <20210928154143.2106903-14-arnd@kernel.org>
Message-ID: <YesxB6W3XsTWjVFY@archlinux-ax161>

Hi Arnd,

On Tue, Sep 28, 2021 at 05:41:42PM +0200, Arnd Bergmann wrote:
> From: Nick Desaulniers <ndesaulniers at google.com>
> 
> Similar to commit a6c30873ee4a ("ARM: 8989/1: use .fpu assembler
> directives instead of assembler arguments").
> 
> GCC and GNU binutils support setting the "sub arch" via -march=,
> -Wa,-march, target function attribute, and .arch assembler directive.
> 
> Clang's integrated assembler does not support -Wa,-march (and the logic
> to overrule one when multiple of the above are used), and this can
> cause annoying warnings such as:
> 
> clang: warning: argument unused during compilation: '-march=armv6k' [-Wunused-command-line-argument]
> clang: warning: argument unused during compilation: '-march=armv6k' [-Wunused-command-line-argument]
> clang: warning: argument unused during compilation: '-march=armv6k' [-Wunused-command-line-argument]
> 
> Since most assembler is non-conditionally assembled with one sub arch
> (modulo arch/arm/delay-loop.S which conditionally is assembled as armv4
> based on CONFIG_ARCH_RPC, and arch/arm/mach-at91/pm-suspend.S which is
> conditionally assembled as armv7-a based on CONFIG_CPU_V7), prefer the
> .arch assembler directive.
> 
> Link: https://bugs.llvm.org/show_bug.cgi?id=48894
> Link: https://github.com/ClangBuiltLinux/linux/issues/1195
> Suggested-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Nick Desaulniers <ndesaulniers at google.com>
> [arnd] add a few more instances found in compile testing
> Signed-off-by: Arnd Bergmann <arnd at arndb.de>

Did anything ever come of this patch (or series)? I would like to add
-Werror=unused-command-line-argument to CLANG_FLAGS so that invalid
flags will not cause cascading cc-option failures but we cannot not do
that until this is resolved.

Cheers,
Nathan


From nicolas at ndufresne.ca  Fri Jan 21 14:25:26 2022
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Fri, 21 Jan 2022 17:25:26 -0500
Subject: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
 skip
In-Reply-To: <AM6PR04MB63417E126287421BCA133514E7539@AM6PR04MB6341.eurprd04.prod.outlook.com>
References: <cover.1631002447.git.ming.qian@nxp.com>
 <647f84c1e7c2a48d6492d38fa4f06586235500b8.1631002447.git.ming.qian@nxp.com>
 <fffd24d3374ecb2fbfafa9b85fa0ef8012fc7efa.camel@ndufresne.ca>
 <AM6PR04MB634124118288EC775F05AFC3E7D59@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <8984f8a3c0dfd3a5f83fb5cc7b0357dca4787274.camel@ndufresne.ca>
 <AM6PR04MB63417E126287421BCA133514E7539@AM6PR04MB6341.eurprd04.prod.outlook.com>
Message-ID: <a90c49239b86d8212045b1f2ef591c4bbf3cb8fd.camel@ndufresne.ca>

Le jeudi 13 janvier 2022 ? 07:18 +0000, Ming Qian a ?crit?:
> Hi Nicolas,
> 
>    I have question about skip event or similar concepts.
> If the client control the input frame count, and it won't queue any more frames unless some frame is decoded.
> But after seek, There is no requirement to begin queuing coded data starting exactly from a resume point (e.g. SPS or a keyframe). Any queued OUTPUT buffers will be processed and returned to the client until a suitable resume point is found. While looking for a resume point, the decoder should not produce any decoded frames into CAPTURE buffers.
> 
> So client may have queued some frames but without any resume point, in this case the decoder won't produce any decoded frames into CAPTURE buffers, and the client won't queue frames into output buffers. This creates some kind of deadlock.
> 
> In our previous solution, we send skip event to client to tell it that some frame is skipped instead of decoded, then the client can continue to queue frames.
> But the skip event is flawed, so we need some solution to resolve it.
> 1. decoder can produce an empty buffer with V4L2_BUF_FLAG_SKIPPED (or V4L2_BUF_FLAG_ERROR) as you advised, but this seems to conflict with the above description in specification.
> 2. Define a notification mechanism to notify the client
> 
> Can you give some advice?  This constraint of frame depth is common on android

Without going against the spec, you can as of today pop a capture buffer and
mark it done with error. As it has nothing valid in it, I would also set the
payload size to 0.

So I'd say, for every unique input timestamp, that didn't yield a frame
(skipped), pop a capture buffer, copy the timestamp, set the payload size to 0
and set it as done with error.

I'm not sure though if we that we can specify this, as I'm not sure this is
possible with all the existing HW. I must admit, I don't myself had to deal with
that issue as I'm not using a dummy framework. In GStreamer, we take care of
locating the next sync point. So unless there was an error in the framework,
this case does not exist for us.

> 
> Ming
> 
> > > > > +    * - ``V4L2_EVENT_SKIP``
> > > > > +      - 8
> > > > > +      - This event is triggered when one frame is decoded, but it
> > > > > + won't
> > > > > be
> > > > outputed
> > > > > +     to the display. So the application can't get this frame, and
> > > > > + the
> > > > > input
> > > > frame count
> > > > > +     is dismatch with the output frame count. And this evevt is
> > > > > + telling
> > > > > the
> > > > client to
> > > > > +     handle this case.
> > > > 
> > > > Similar to my previous comment, this event is flawed, since
> > > > userspace cannot know were the skip is located in the queued
> > > > buffers. Currently, all decoders are mandated to support
> > > > V4L2_BUF_FLAG_TIMESTAMP_COPY. The timestamp must NOT be
> > interpreted
> > > > by the driver and must be reproduce as-is in the associated CAPTURE
> > > > buffer. It is possible to "garbage" collect skipped frames with this
> > > > method, though tedious.
> > > > 
> > > > An alternative, and I think it would be much nicer then this, would
> > > > be to use the v4l2_buffer.sequence counter, and just make it skip 1
> > > > on skips. Though, the down side is that userspace must also know how
> > > > to reorder frames (a driver job for stateless codecs) in order to
> > > > identify which frame was skipped. So this is perhaps not that
> > > > useful, other then knowing something was skipped in the past.
> > > > 
> > > > A third option would be to introduce V4L2_BUF_FLAG_SKIPPED. This way
> > > > the driver could return an empty payload (bytesused = 0) buffer with
> > > > this flag set, and the proper timestamp properly copied. This would
> > > > let the driver communicate skipped frames in real-time. Note that
> > > > this could break with existing userspace, so it would need to be
> > > > opted-in somehow (a control or some flags).
> > > 
> > > Hi Nicolas,
> > >    The problem we meet is that userspace doesn't care which frame is
> > > skipped, it just need to know that there are a frame is skipped, the
> > > driver should promise the input frame count is equals to the output frame
> > count.
> > >     Your first method is possible in theory, but we find the timestamp
> > > may be unreliable, we meet many timestamp issues that userspace may
> > > enqueue invalid timestamp or repeated timestamp and so on, so we can't
> > accept this solution.
> > 
> > The driver should not interpret the provided timestamp, so it should not be
> > able to say if the timestamp is valid or not, this is not the driver's task.
> > 
> > The driver task is to match the timestamp to the CAPTURE buffer (if that buffer
> > was produced), and reproduce it exactly.
> > 
> > >     I think your second option is better. And there are only 1
> > > question, we find some application prefer to use the V4L2_EVENT_EOS to
> > > check the eos, not checking the empty buffer, if we use this method to
> > > check skipped frame, the
> > 
> > Checking the empty buffer is a legacy method, only available in Samsung MFC
> > driver. The spec says that the last buffer should be flagged with _LAST, and any
> > further attempt to poll should unblock and DQBUF return EPIPE.
> > 
> > > application should check empty buffer instead of V4L2_EVENT_EOS,
> > > otherwise if the last frame is skipped, the application will miss it.
> > > Of course this is not a problem, it just increases the complexity of
> > > the userspace implementation
> > 
> > The EPIPE mechanism covers this issue, which we initially had with the LAST
> > flag.
> > 
> > >     I don't think your third method is feasible, the reasons are as below
> > >               1. usually the empty payload means eos, and as you say,
> > > it may introduce confusion.
> > >       2. The driver may not have the opportunity to return an empty
> > > payload during decoding, in our driver, driver will pass the capture
> > > buffer to firmware, and when some frame is skipped, the firmware won't
> > > return the buffer, driver may not find an available capture buffer to
> > > return to userspace.
> > > 
> > >    The requirement is that userspace need to match the input frame
> > > count and output frame count. It doesn't care which frame is skipped,
> > > so the V4L2_EVENT_SKIP is the easiest way for driver and userspace.
> > >    If you think this event is really inappropriate, I prefer to adopt
> > > your second option
> > 
> > Please, drop SKIP from you driver and this patchset and fix your draining
> > process handling to follow the spec. The Samsung OMX component is
> > irrelevant to mainline submission, the OMX code should be updated to follow
> > the spec.
> > 
> > > 



From robh at kernel.org  Fri Jan 21 14:43:06 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 16:43:06 -0600
Subject: [PATCH v5 1/4] Input: Add driver for Cypress Generation 5
 touchscreen
In-Reply-To: <20220119012637.1713748-1-pgwipeout@gmail.com>
References: <20220109115331.388633-2-alistair@alistair23.me>
 <20220119012637.1713748-1-pgwipeout@gmail.com>
Message-ID: <Yes2+ps8qTT52g3Z@robh.at.kernel.org>

On Tue, Jan 18, 2022 at 08:26:37PM -0500, Peter Geis wrote:
> Good Evening,
> 
> I tried using this with a cypress tma448 and thought there was an issue
> with the driver.
> Further investigation found the tma448 in question had no configuration
> burned into it, thus max size and pressure are zero.
> 
> I've added the patch below to extend the driver with device tree
> overrides.
> Unfortunately device_property_read_u16 is broken on arm64 currently, as
> it returns zero.

FYI, I replied to your bug report:

https://lore.kernel.org/all/CAMdYzYquceSBrOsvO8rW9wmJA_RO=HSwv_waVoS=0hsP414T-A at mail.gmail.com/

Rob


From laurent.pinchart at ideasonboard.com  Fri Jan 21 14:45:07 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 22 Jan 2022 00:45:07 +0200
Subject: [RFC PATCH v2 5/7] ARM: dts: bcm2711: Add unicam CSI nodes
In-Reply-To: <20220121081810.155500-6-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-6-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <Yes3c1v+V1hMlWfW@pendragon.ideasonboard.com>

Hi Jean-Michel,

Thank you for the patch.

On Fri, Jan 21, 2022 at 09:18:08AM +0100, Jean-Michel Hautbois wrote:
> Add both MIPI CSI-2 nodes in the core bcm2711 tree. Use the 3-cells
> interrupt declaration, corresponding clocks and default as disabled.
> 
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
>  arch/arm/boot/dts/bcm2711.dtsi | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> index dff18fc9a906..077141df7024 100644
> --- a/arch/arm/boot/dts/bcm2711.dtsi
> +++ b/arch/arm/boot/dts/bcm2711.dtsi
> @@ -3,6 +3,7 @@
>  
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
>  #include <dt-bindings/soc/bcm2835-pm.h>
> +#include <dt-bindings/power/raspberrypi-power.h>
>  
>  / {
>  	compatible = "brcm,bcm2711";
> @@ -293,6 +294,36 @@ hvs: hvs at 7e400000 {
>  			interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
>  		};
>  
> +		csi0: csi1 at 7e800000 {

The node name should be csi at 7e800000, not csi1 at 7e800000. Now, this will
probably cause issues with the firmware that looks for csi1 (and csi0 ?)
to hand over control of the Unicam CSI-2 receiver to the kernel. I
wonder if this is something that could be handled by a firmware update,
to also recognize nodes named "csi" ?

> +			compatible = "brcm,bcm2835-unicam";
> +			reg = <0x7e800000 0x800>,
> +			      <0x7e802000 0x4>;
> +			interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clocks BCM2835_CLOCK_CAM0>,
> +				 <&firmware_clocks 4>;
> +			clock-names = "lp", "vpu";
> +			power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			#clock-cells = <1>;

Why do you need #address-cells, #size-cells and #clock-cells ? They're
not mentioned in the binding.

> +			status="disabled";

Missing spaces around the =.

Same comment for the next node.

> +		};
> +
> +		csi1: csi1 at 7e801000 {
> +			compatible = "brcm,bcm2835-unicam";
> +			reg = <0x7e801000 0x800>,
> +			      <0x7e802004 0x4>;
> +			interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clocks BCM2835_CLOCK_CAM1>,
> +				 <&firmware_clocks 4>;
> +			clock-names = "lp", "vpu";
> +			power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			#clock-cells = <1>;
> +			status="disabled";
> +		};
> +
>  		pixelvalve3: pixelvalve at 7ec12000 {
>  			compatible = "brcm,bcm2711-pixelvalve3";
>  			reg = <0x7ec12000 0x100>;

-- 
Regards,

Laurent Pinchart


From robh at kernel.org  Fri Jan 21 14:59:22 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 16:59:22 -0600
Subject: [PATCH v2] dt-bindings: serial: Convert rda,8810pl-uart to YAML
In-Reply-To: <20220109170321.GA12989@standask-GA-A55M-S2HP>
References: <20220109170321.GA12989@standask-GA-A55M-S2HP>
Message-ID: <Yes6ytLCkhqGjre8@robh.at.kernel.org>

On Sun, 09 Jan 2022 18:03:21 +0100, Stanislav Jakubek wrote:
> Convert RDA Micro UART bindings to DT schema format.
> 
> Signed-off-by: Stanislav Jakubek <stano.jakubek at gmail.com>
> ---
> Changes in v2:
>   - Fix indentation in example
> 
>  .../bindings/serial/rda,8810pl-uart.txt       | 17 -------
>  .../bindings/serial/rda,8810pl-uart.yaml      | 46 +++++++++++++++++++
>  MAINTAINERS                                   |  2 +-
>  3 files changed, 47 insertions(+), 18 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.txt
>  create mode 100644 Documentation/devicetree/bindings/serial/rda,8810pl-uart.yaml
> 

Applied, thanks!


From willmcvicker at google.com  Fri Jan 21 15:16:44 2022
From: willmcvicker at google.com (Will McVicker)
Date: Fri, 21 Jan 2022 23:16:44 +0000
Subject: [PATCH v1 1/1] ASoC: dpcm: prevent snd_soc_dpcm use after free
Message-ID: <20220121231644.1732744-1-willmcvicker@google.com>

From: KaiChieh Chuang <kaichieh.chuang at mediatek.com>

[ Upstream commit a9764869779081e8bf24da07ac040e8f3efcf13a ]

The dpcm get from fe_clients/be_clients
may be free before use

Add a spin lock at snd_soc_card level,
to protect the dpcm instance.
The lock may be used in atomic context, so use spin lock.

Use irq spin lock version,
since the lock may be used in interrupts.

possible race condition between
void dpcm_be_disconnect(
	...
	list_del(&dpcm->list_be);
	list_del(&dpcm->list_fe);
	kfree(dpcm);
	...

and
	for_each_dpcm_fe()
	for_each_dpcm_be*()

race condition example
Thread 1:
    snd_soc_dapm_mixer_update_power()
        -> soc_dpcm_runtime_update()
            -> dpcm_be_disconnect()
                -> kfree(dpcm);
Thread 2:
    dpcm_fe_dai_trigger()
        -> dpcm_be_dai_trigger()
            -> snd_soc_dpcm_can_be_free_stop()
                -> if (dpcm->fe == fe)

Excpetion Scenario:
	two FE link to same BE
	FE1 -> BE
	FE2 ->

	Thread 1: switch of mixer between FE2 -> BE
	Thread 2: pcm_stop FE1

Exception:

Unable to handle kernel paging request at virtual address dead0000000000e0

pc=<> [<ffffff8960e2cd10>] dpcm_be_dai_trigger+0x29c/0x47c
	sound/soc/soc-pcm.c:3226
		if (dpcm->fe == fe)
lr=<> [<ffffff8960e2f694>] dpcm_fe_dai_do_trigger+0x94/0x26c

Backtrace:
[<ffffff89602dba80>] notify_die+0x68/0xb8
[<ffffff896028c7dc>] die+0x118/0x2a8
[<ffffff89602a2f84>] __do_kernel_fault+0x13c/0x14c
[<ffffff89602a27f4>] do_translation_fault+0x64/0xa0
[<ffffff8960280cf8>] do_mem_abort+0x4c/0xd0
[<ffffff8960282ad0>] el1_da+0x24/0x40
[<ffffff8960e2cd10>] dpcm_be_dai_trigger+0x29c/0x47c
[<ffffff8960e2f694>] dpcm_fe_dai_do_trigger+0x94/0x26c
[<ffffff8960e2edec>] dpcm_fe_dai_trigger+0x3c/0x44
[<ffffff8960de5588>] snd_pcm_do_stop+0x50/0x5c
[<ffffff8960dded24>] snd_pcm_action+0xb4/0x13c
[<ffffff8960ddfdb4>] snd_pcm_drop+0xa0/0x128
[<ffffff8960de69bc>] snd_pcm_common_ioctl+0x9d8/0x30f0
[<ffffff8960de1cac>] snd_pcm_ioctl_compat+0x29c/0x2f14
[<ffffff89604c9d60>] compat_SyS_ioctl+0x128/0x244
[<ffffff8960283740>] el0_svc_naked+0x34/0x38
[<ffffffffffffffff>] 0xffffffffffffffff

Signed-off-by: KaiChieh Chuang <kaichieh.chuang at mediatek.com>
Signed-off-by: Mark Brown <broonie at kernel.org>
[willmcvicker: move spinlock to bottom of struct snd_soc_card]
Signed-off-by: Will McVicker <willmcvicker at google.com>
Cc: stable at vger.kernel.org # 4.19+
---
 include/sound/soc.h  |  2 ++
 sound/soc/soc-core.c |  1 +
 sound/soc/soc-pcm.c  | 40 +++++++++++++++++++++++++++++++++-------
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 88aa48e5485f..7abd8d4746ef 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1113,6 +1113,8 @@ struct snd_soc_card {
 	u32 pop_time;
 
 	void *drvdata;
+
+	spinlock_t dpcm_lock;
 };
 
 /* SoC machine DAI configuration, glues a codec and cpu DAI together */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8531b490f6f6..273898b358c4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2752,6 +2752,7 @@ int snd_soc_register_card(struct snd_soc_card *card)
 	card->instantiated = 0;
 	mutex_init(&card->mutex);
 	mutex_init(&card->dapm_mutex);
+	spin_lock_init(&card->dpcm_lock);
 
 	ret = snd_soc_instantiate_card(card);
 	if (ret != 0)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index af14304645ce..c03b653bf6ff 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1221,6 +1221,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
 		struct snd_soc_pcm_runtime *be, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
+	unsigned long flags;
 
 	/* only add new dpcms */
 	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
@@ -1236,8 +1237,10 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe,
 	dpcm->fe = fe;
 	be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
 	dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_add(&dpcm->list_be, &fe->dpcm[stream].be_clients);
 	list_add(&dpcm->list_fe, &be->dpcm[stream].fe_clients);
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
 	dev_dbg(fe->dev, "connected new DPCM %s path %s %s %s\n",
 			stream ? "capture" : "playback",  fe->dai_link->name,
@@ -1283,6 +1286,7 @@ static void dpcm_be_reparent(struct snd_soc_pcm_runtime *fe,
 void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm, *d;
+	unsigned long flags;
 
 	list_for_each_entry_safe(dpcm, d, &fe->dpcm[stream].be_clients, list_be) {
 		dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
@@ -1302,8 +1306,10 @@ void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
 #ifdef CONFIG_DEBUG_FS
 		debugfs_remove(dpcm->debugfs_state);
 #endif
+		spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 		list_del(&dpcm->list_be);
 		list_del(&dpcm->list_fe);
+		spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 		kfree(dpcm);
 	}
 }
@@ -1557,10 +1563,13 @@ int dpcm_process_paths(struct snd_soc_pcm_runtime *fe,
 void dpcm_clear_pending_state(struct snd_soc_pcm_runtime *fe, int stream)
 {
 	struct snd_soc_dpcm *dpcm;
+	unsigned long flags;
 
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be)
 		dpcm->be->dpcm[stream].runtime_update =
 						SND_SOC_DPCM_UPDATE_NO;
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 }
 
 static void dpcm_be_dai_startup_unwind(struct snd_soc_pcm_runtime *fe,
@@ -2626,6 +2635,7 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
 	struct snd_soc_dpcm *dpcm;
 	enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
 	int ret;
+	unsigned long flags;
 
 	dev_dbg(fe->dev, "ASoC: runtime %s open on FE %s\n",
 			stream ? "capture" : "playback", fe->dai_link->name);
@@ -2695,11 +2705,13 @@ static int dpcm_run_update_startup(struct snd_soc_pcm_runtime *fe, int stream)
 	dpcm_be_dai_shutdown(fe, stream);
 disconnect:
 	/* disconnect any non started BEs */
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
 		struct snd_soc_pcm_runtime *be = dpcm->be;
 		if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
 				dpcm->state = SND_SOC_DPCM_LINK_STATE_FREE;
 	}
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
 	return ret;
 }
@@ -3278,7 +3290,10 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
 {
 	struct snd_soc_dpcm *dpcm;
 	int state;
+	int ret = 1;
+	unsigned long flags;
 
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
 
 		if (dpcm->fe == fe)
@@ -3287,12 +3302,15 @@ int snd_soc_dpcm_can_be_free_stop(struct snd_soc_pcm_runtime *fe,
 		state = dpcm->fe->dpcm[stream].state;
 		if (state == SND_SOC_DPCM_STATE_START ||
 			state == SND_SOC_DPCM_STATE_PAUSED ||
-			state == SND_SOC_DPCM_STATE_SUSPEND)
-			return 0;
+			state == SND_SOC_DPCM_STATE_SUSPEND) {
+			ret = 0;
+			break;
+		}
 	}
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
 	/* it's safe to free/stop this BE DAI */
-	return 1;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_free_stop);
 
@@ -3305,7 +3323,10 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
 {
 	struct snd_soc_dpcm *dpcm;
 	int state;
+	int ret = 1;
+	unsigned long flags;
 
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_for_each_entry(dpcm, &be->dpcm[stream].fe_clients, list_fe) {
 
 		if (dpcm->fe == fe)
@@ -3315,12 +3336,15 @@ int snd_soc_dpcm_can_be_params(struct snd_soc_pcm_runtime *fe,
 		if (state == SND_SOC_DPCM_STATE_START ||
 			state == SND_SOC_DPCM_STATE_PAUSED ||
 			state == SND_SOC_DPCM_STATE_SUSPEND ||
-			state == SND_SOC_DPCM_STATE_PREPARE)
-			return 0;
+			state == SND_SOC_DPCM_STATE_PREPARE) {
+			ret = 0;
+			break;
+		}
 	}
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 
 	/* it's safe to change hw_params */
-	return 1;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dpcm_can_be_params);
 
@@ -3359,6 +3383,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
 	struct snd_pcm_hw_params *params = &fe->dpcm[stream].hw_params;
 	struct snd_soc_dpcm *dpcm;
 	ssize_t offset = 0;
+	unsigned long flags;
 
 	/* FE state */
 	offset += scnprintf(buf + offset, size - offset,
@@ -3386,6 +3411,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
 		goto out;
 	}
 
+	spin_lock_irqsave(&fe->card->dpcm_lock, flags);
 	list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) {
 		struct snd_soc_pcm_runtime *be = dpcm->be;
 		params = &dpcm->hw_params;
@@ -3406,7 +3432,7 @@ static ssize_t dpcm_show_state(struct snd_soc_pcm_runtime *fe,
 				params_channels(params),
 				params_rate(params));
 	}
-
+	spin_unlock_irqrestore(&fe->card->dpcm_lock, flags);
 out:
 	return offset;
 }
-- 
2.35.0.rc0.227.g00780c9af4-goog



From laurent.pinchart at ideasonboard.com  Fri Jan 21 15:27:49 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 22 Jan 2022 01:27:49 +0200
Subject: [RFC PATCH v2 3/7] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <20220121081810.155500-4-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-4-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <YetBdVY57T3QrUNa@pendragon.ideasonboard.com>

Hi Jean-Michel,

Thank you for the patch.

On Fri, Jan 21, 2022 at 09:18:06AM +0100, Jean-Michel Hautbois wrote:
> Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera

s/bindinds/bindings/

I'd mention "Unicam" somewhere here.

> interface. Also add a MAINTAINERS entry for it.
> 
> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
> Dave: I assumed you were the maintainer for this file, as I based it on the
> bcm2835-unicam.txt file. Are  you happy to be added directly as the
> maintainer, or should this be specified as "Raspberry Pi Kernel
> Maintenance <kernel-list at raspberrypi.com>"
> - in v2: multiple corrections to pass the bot checking as Rob kindly
>   told me.
> ---
>  .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
>  MAINTAINERS                                   |   6 +
>  2 files changed, 109 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> 
> diff --git a/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> new file mode 100644
> index 000000000000..1427514142cf
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> @@ -0,0 +1,103 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/media/brcm,bcm2835-unicam.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Broadcom BCM283x Camera Interface (Unicam)
> +
> +maintainers:
> +  - Dave Stevenson <dave.stevenson at raspberrypi.com>
> +
> +description: |-
> +  The Unicam block on BCM283x SoCs is the receiver for either
> +  CSI-2 or CCP2 data from image sensors or similar devices.
> +
> +  The main platform using this SoC is the Raspberry Pi family of boards.
> +  On the Pi the VideoCore firmware can also control this hardware block,
> +  and driving it from two different processors will cause issues.
> +  To avoid this, the firmware checks the device tree configuration
> +  during boot. If it finds device tree nodes called csi0 or csi1 then
> +  it will stop the firmware accessing the block, and it can then
> +  safely be used via the device tree binding.

As mentioned in the review of the DT integration, the nodes should
ideally be called just "csi", not "csi0" and "csi1" (maybe Rob could
confirm this ?). Dave, is there a way the firmware could be updated to
also hand over control of the Unicam instances to Linux when a "csi"
node is found, not just "csi0" or "csi1" ?

Given that the node names are significant, they should be enforced in
the YAML schema.

> +
> +properties:
> +  compatible:
> +    const: brcm,bcm2835-unicam
> +
> +  reg:
> +    description:
> +      physical base address and length of the register sets for the device.

This can be dropped.

> +    maxItems: 1

There are two items in the example below. How does this validate ?

> +
> +  interrupts:
> +    description: the IRQ line for this Unicam instance.

This can be dropped.

> +    maxItems: 1
> +
> +  clocks:
> +    description: |-
> +      list of clock specifiers, corresponding to entries in clock-names
> +      property.

  clocks:
    items:
      - description: The clock for ...
      - description: The clock for ...

(with the two descriptions matching the LP and VPU clocks, I don't know
what they are).

> +
> +  clock-names:
> +    items:
> +      - const: lp
> +      - const: vpu
> +
> +  port:
> +    $ref: /schemas/graph.yaml#/properties/port
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - port
> +
> +additionalProperties: False
> +
> +examples:
> +  - |
> +    csi1: csi1 at 7e801000 {
> +        compatible = "brcm,bcm2835-unicam";
> +        reg = <0x7e801000 0x800>,
> +              <0x7e802004 0x4>;
> +        interrupts = <2 7>;

Let's use the Pi 4 device tree as an example, as that's what we're
upstreaming first.

> +        clocks = <&clocks BCM2835_CLOCK_CAM1>,

This will fail to compile without a proper #include, did you get this to
pass validation ?

> +                 <&firmware_clocks 4>;
> +        clock-names = "lp", "vpu";
> +        port {
> +                csi1_ep: endpoint {
> +                        remote-endpoint = <&tc358743_0>;
> +                        data-lanes = <1 2>;
> +                };
> +        };
> +    };
> +
> +    i2c0: i2c at 7e205000 {
> +        tc358743: csi-hdmi-bridge at 0f {
> +            compatible = "toshiba,tc358743";
> +            reg = <0x0f>;
> +            clocks = <&tc358743_clk>;
> +            clock-names = "refclk";
> +
> +            tc358743_clk: bridge-clk {
> +                    compatible = "fixed-clock";
> +                    #clock-cells = <0>;
> +                    clock-frequency = <27000000>;
> +            };
> +
> +            port {
> +                    tc358743_0: endpoint {
> +                            remote-endpoint = <&csi1_ep>;
> +                            clock-lanes = <0>;
> +                            data-lanes = <1 2>;
> +                            clock-noncontinuous;
> +                            link-frequencies =
> +                                /bits/ 64 <297000000>;
> +                    };
> +            };
> +        };
> +    };

I'd drop this node completely.

> +...
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 33f75892f98e..07f238fd5ff9 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3679,6 +3679,12 @@ F:	Documentation/media/v4l-drivers/bcm2835-isp.rst
>  F:	drivers/staging/vc04_services/bcm2835-isp
>  F:	include/uapi/linux/bcm2835-isp.h
>  
> +BROADCOM BCM2835 CAMERA DRIVER
> +M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
> +L:	linux-media at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> +
>  BROADCOM BCM47XX MIPS ARCHITECTURE
>  M:	Hauke Mehrtens <hauke at hauke-m.de>
>  M:	Rafa? Mi?ecki <zajec5 at gmail.com>

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Jan 21 15:30:17 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 22 Jan 2022 01:30:17 +0200
Subject: [RFC PATCH v2 7/7] media: bcm283x: Include the imx219 node
In-Reply-To: <20220121081810.155500-8-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-8-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <YetCCUFd1F0yTJgU@pendragon.ideasonboard.com>

Hi Jean-Michel,

Thank you for the patch.

On Fri, Jan 21, 2022 at 09:18:10AM +0100, Jean-Michel Hautbois wrote:
> Configure the csi1 endpoint, add the imx219 node and connect it through
> the i2c mux.

This is not meant to be upstreamed, is it ? Please say so very loudly in
the commit message.

> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> ---
>  MAINTAINERS                               |   1 +
>  arch/arm/boot/dts/bcm2711-rpi-4-b.dts     |   1 +
>  arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi | 102 ++++++++++++++++++++++
>  3 files changed, 104 insertions(+)
>  create mode 100644 arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index b17bb533e007..56544ac98d69 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3684,6 +3684,7 @@ M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
>  L:	linux-media at vger.kernel.org
>  S:	Maintained
>  F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
> +F:	arch/arm/boot/dts/bcm283x*
>  F:	drivers/media/platform/bcm2835/
>  
>  BROADCOM BCM47XX MIPS ARCHITECTURE
> diff --git a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> index 4432412044de..f7625b70fe57 100644
> --- a/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> +++ b/arch/arm/boot/dts/bcm2711-rpi-4-b.dts
> @@ -4,6 +4,7 @@
>  #include "bcm2711-rpi.dtsi"
>  #include "bcm283x-rpi-usb-peripheral.dtsi"
>  #include "bcm283x-rpi-wifi-bt.dtsi"
> +#include "bcm283x-rpi-imx219.dtsi"

Let's use an overlay instead.

>  
>  / {
>  	compatible = "raspberrypi,4-model-b", "brcm,bcm2711";
> diff --git a/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi b/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
> new file mode 100644
> index 000000000000..f2c6a85fd731
> --- /dev/null
> +++ b/arch/arm/boot/dts/bcm283x-rpi-imx219.dtsi
> @@ -0,0 +1,102 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <dt-bindings/clock/bcm2835.h>
> +
> +/ {
> +	compatible = "brcm,bcm2835";
> +
> +	imx219_vdig: fixedregulator at 1 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "imx219_vdig";
> +		regulator-min-microvolt = <1800000>;
> +		regulator-max-microvolt = <1800000>;
> +	};
> +
> +	imx219_vddl: fixedregulator at 2 {
> +		compatible = "regulator-fixed";
> +		regulator-name = "imx219_vddl";
> +		regulator-min-microvolt = <1200000>;
> +		regulator-max-microvolt = <1200000>;
> +	};
> +
> +	imx219_clk: imx219_clk {
> +		#clock-cells = <0>;
> +		compatible = "fixed-clock";
> +		clock-frequency = <24000000>;
> +		clock-output-names = "24MHz-clock";
> +	};
> +
> +	cam1_reg: cam1_reg {
> +		compatible = "regulator-fixed";
> +		regulator-name = "imx219_vana";
> +		enable-active-high;
> +		status = "okay";
> +		gpio = <&expgpio 5 GPIO_ACTIVE_HIGH>;
> +	};

This regulator belongs to the board dtsi. Same for the I2C mux below
(but not the imx219 of course).

> +
> +	i2c0mux {
> +		compatible = "i2c-mux-pinctrl";
> +		#address-cells = <1>;
> +		#size-cells = <0>;
> +
> +		i2c-parent = <&i2c0>;
> +
> +		pinctrl-names = "i2c0", "i2c_csi_dsi";
> +		pinctrl-0 = <&i2c0_gpio0>;
> +		pinctrl-1 = <&i2c0_gpio44>;
> +
> +		i2c at 0 {
> +			reg = <0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c at 1 {
> +			reg = <1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			imx219: sensor at 10 {
> +				compatible = "sony,imx219";
> +				reg = <0x10>;
> +				status = "okay";
> +
> +				clocks = <&imx219_clk>;
> +				clock-names = "xclk";
> +
> +				VANA-supply = <&cam1_reg>;   /* 2.8v */
> +				VDIG-supply = <&imx219_vdig>;   /* 1.8v */
> +				VDDL-supply = <&imx219_vddl>;   /* 1.2v */
> +
> +				rotation = <0>;
> +				orientation = <0>;
> +
> +				port {
> +					imx219_0: endpoint {
> +						remote-endpoint = <&csi1_ep>;
> +						clock-lanes = <0>;
> +						data-lanes = <1 2>;
> +						clock-noncontinuous;
> +						link-frequencies = /bits/ 64 <456000000>;
> +					};
> +				};
> +			};
> +		};
> +	};
> +};
> +
> +&csi1 {
> +	status="okay";
> +	num-data-lanes = <2>;
> +	port {
> +		csi1_ep: endpoint {
> +			remote-endpoint = <&imx219_0>;
> +			data-lanes = <1 2>;
> +			clock-lanes = <0>;
> +		};
> +	};
> +};
> +
> +&i2c0 {
> +	/delete-property/ pinctrl-names;
> +	/delete-property/ pinctrl-0;
> +};
> +

-- 
Regards,

Laurent Pinchart


From laurent.pinchart at ideasonboard.com  Fri Jan 21 15:34:30 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Sat, 22 Jan 2022 01:34:30 +0200
Subject: [RFC PATCH v2 6/7] media: imx219: Add support for multiplexed
 streams
In-Reply-To: <20220121081810.155500-7-jeanmichel.hautbois@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-7-jeanmichel.hautbois@ideasonboard.com>
Message-ID: <YetDBvxA0iqSQK/0@pendragon.ideasonboard.com>

Hi Jean-Michel,

Thank you for the patch.

On Fri, Jan 21, 2022 at 09:18:09AM +0100, Jean-Michel Hautbois wrote:
> As of now, imx219 was not supporting anything more than one stream. Add
> support for embedded data, based on linux-rpi kernel, and make it work
> with multiplexed streams. We have only one source pad with two streams:
> stream 0 is the image, and stream 1 is the embedded data.
> 
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> 
> ---
> in v2: modified the get_format_pad function as it was not correctly
> propagating the format in case of sensor flips.
> ---
>  drivers/media/i2c/imx219.c | 452 ++++++++++++++++++++-----------------

This is too big, it bundles multiple changes together. It should be
split in multiple patches.

>  1 file changed, 241 insertions(+), 211 deletions(-)
> 
> diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
> index e10af3f74b38..d73fe6b8b2fb 100644
> --- a/drivers/media/i2c/imx219.c
> +++ b/drivers/media/i2c/imx219.c
> @@ -118,6 +118,16 @@
>  #define IMX219_PIXEL_ARRAY_WIDTH	3280U
>  #define IMX219_PIXEL_ARRAY_HEIGHT	2464U
>  
> +/* Embedded metadata stream structure */
> +#define IMX219_EMBEDDED_LINE_WIDTH 16384
> +#define IMX219_NUM_EMBEDDED_LINES 1
> +
> +enum pad_types {
> +	IMAGE_PAD,
> +	METADATA_PAD,
> +	NUM_PADS
> +};

No used.

> +
>  struct imx219_reg {
>  	u16 address;
>  	u8 val;
> @@ -429,7 +439,7 @@ static const char * const imx219_supply_name[] = {
>   * - v flip
>   * - h&v flips
>   */
> -static const u32 codes[] = {
> +static const u32 imx219_mbus_formats[] = {

For instance renaming this array should go in a patch of its own.

>  	MEDIA_BUS_FMT_SRGGB10_1X10,
>  	MEDIA_BUS_FMT_SGRBG10_1X10,
>  	MEDIA_BUS_FMT_SGBRG10_1X10,
> @@ -655,62 +665,17 @@ static u32 imx219_get_format_code(struct imx219 *imx219, u32 code)
>  
>  	lockdep_assert_held(&imx219->mutex);
>  
> -	for (i = 0; i < ARRAY_SIZE(codes); i++)
> -		if (codes[i] == code)
> +	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); i++)
> +		if (imx219_mbus_formats[i] == code)
>  			break;
>  
> -	if (i >= ARRAY_SIZE(codes))
> +	if (i >= ARRAY_SIZE(imx219_mbus_formats))
>  		i = 0;
>  
>  	i = (i & ~3) | (imx219->vflip->val ? 2 : 0) |
>  	    (imx219->hflip->val ? 1 : 0);
>  
> -	return codes[i];
> -}
> -
> -static void imx219_set_default_format(struct imx219 *imx219)
> -{
> -	struct v4l2_mbus_framefmt *fmt;
> -
> -	fmt = &imx219->fmt;
> -	fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
> -	fmt->colorspace = V4L2_COLORSPACE_SRGB;
> -	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
> -	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
> -							  fmt->colorspace,
> -							  fmt->ycbcr_enc);
> -	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
> -	fmt->width = supported_modes[0].width;
> -	fmt->height = supported_modes[0].height;
> -	fmt->field = V4L2_FIELD_NONE;
> -}
> -
> -static int imx219_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)

So should switching from open to init_cfg. Same thing for adding support
for the V4L2 subdev active state (v4l2_subdev_init_finalize() and the
corresponding changes in the get/set format handlers). This is mainline,
not a BSP, patches must be reviewable.

> -{
> -	struct imx219 *imx219 = to_imx219(sd);
> -	struct v4l2_mbus_framefmt *try_fmt =
> -		v4l2_subdev_get_try_format(sd, fh->state, 0);
> -	struct v4l2_rect *try_crop;
> -
> -	mutex_lock(&imx219->mutex);
> -
> -	/* Initialize try_fmt */
> -	try_fmt->width = supported_modes[0].width;
> -	try_fmt->height = supported_modes[0].height;
> -	try_fmt->code = imx219_get_format_code(imx219,
> -					       MEDIA_BUS_FMT_SRGGB10_1X10);
> -	try_fmt->field = V4L2_FIELD_NONE;
> -
> -	/* Initialize try_crop rectangle. */
> -	try_crop = v4l2_subdev_get_try_crop(sd, fh->state, 0);
> -	try_crop->top = IMX219_PIXEL_ARRAY_TOP;
> -	try_crop->left = IMX219_PIXEL_ARRAY_LEFT;
> -	try_crop->width = IMX219_PIXEL_ARRAY_WIDTH;
> -	try_crop->height = IMX219_PIXEL_ARRAY_HEIGHT;
> -
> -	mutex_unlock(&imx219->mutex);
> -
> -	return 0;
> +	return imx219_mbus_formats[i];
>  }
>  
>  static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
> @@ -802,98 +767,148 @@ static const struct v4l2_ctrl_ops imx219_ctrl_ops = {
>  	.s_ctrl = imx219_set_ctrl,
>  };
>  
> -static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
> -				 struct v4l2_subdev_state *sd_state,
> -				 struct v4l2_subdev_mbus_code_enum *code)
> +static void imx219_init_formats(struct v4l2_subdev_state *state)
>  {
> -	struct imx219 *imx219 = to_imx219(sd);
> +	struct v4l2_mbus_framefmt *format;
> +
> +	format = v4l2_state_get_stream_format(state, 0, 0);
> +	format->code = imx219_mbus_formats[0];
> +	format->width = supported_modes[0].width;
> +	format->height = supported_modes[0].height;
> +	format->field = V4L2_FIELD_NONE;
> +	format->colorspace = V4L2_COLORSPACE_RAW;
> +
> +	if (state->routing.routes[1].flags & V4L2_SUBDEV_ROUTE_FL_ACTIVE) {
> +		format = v4l2_state_get_stream_format(state, 0, 1);
> +		format->code = MEDIA_BUS_FMT_METADATA_8;
> +		format->width = IMX219_EMBEDDED_LINE_WIDTH;
> +		format->height = 1;
> +		format->field = V4L2_FIELD_NONE;
> +		format->colorspace = V4L2_COLORSPACE_DEFAULT;
> +	}
> +}
>  
> -	if (code->index >= (ARRAY_SIZE(codes) / 4))
> -		return -EINVAL;
> +static int _imx219_set_routing(struct v4l2_subdev *sd,
> +			       struct v4l2_subdev_state *state)
> +{
> +	struct v4l2_subdev_route routes[] = {
> +		{
> +			.source_pad = 0,
> +			.source_stream = 0,
> +			.flags = V4L2_SUBDEV_ROUTE_FL_IMMUTABLE |
> +				 V4L2_SUBDEV_ROUTE_FL_SOURCE |
> +				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
> +		},
> +		{
> +			.source_pad = 0,
> +			.source_stream = 1,
> +			.flags = V4L2_SUBDEV_ROUTE_FL_SOURCE |
> +				 V4L2_SUBDEV_ROUTE_FL_ACTIVE,
> +		}
> +	};
>  
> -	mutex_lock(&imx219->mutex);
> -	code->code = imx219_get_format_code(imx219, codes[code->index * 4]);
> -	mutex_unlock(&imx219->mutex);
> +	struct v4l2_subdev_krouting routing = {
> +		.num_routes = ARRAY_SIZE(routes),
> +		.routes = routes,
> +	};
> +
> +	int ret;
> +
> +	ret = v4l2_subdev_set_routing(sd, state, &routing);
> +	if (ret)
> +		return ret;
> +
> +	imx219_init_formats(state);
>  
>  	return 0;
>  }
>  
> -static int imx219_enum_frame_size(struct v4l2_subdev *sd,
> -				  struct v4l2_subdev_state *sd_state,
> -				  struct v4l2_subdev_frame_size_enum *fse)
> +static int imx219_set_routing(struct v4l2_subdev *sd,
> +			      struct v4l2_subdev_state *state,
> +			      enum v4l2_subdev_format_whence which,
> +			      struct v4l2_subdev_krouting *routing)
>  {
> -	struct imx219 *imx219 = to_imx219(sd);
> -	u32 code;
> +	int ret;
>  
> -	if (fse->index >= ARRAY_SIZE(supported_modes))
> +	if (routing->num_routes == 0 || routing->num_routes > 2)
>  		return -EINVAL;
>  
> -	mutex_lock(&imx219->mutex);
> -	code = imx219_get_format_code(imx219, fse->code);
> -	mutex_unlock(&imx219->mutex);
> -	if (fse->code != code)
> -		return -EINVAL;
> +	v4l2_subdev_lock_state(state);
>  
> -	fse->min_width = supported_modes[fse->index].width;
> -	fse->max_width = fse->min_width;
> -	fse->min_height = supported_modes[fse->index].height;
> -	fse->max_height = fse->min_height;
> +	ret = _imx219_set_routing(sd, state);
>  
> -	return 0;
> +	v4l2_subdev_unlock_state(state);
> +
> +	return ret;
>  }
>  
> -static void imx219_reset_colorspace(struct v4l2_mbus_framefmt *fmt)
> +static int imx219_init_cfg(struct v4l2_subdev *sd,
> +			   struct v4l2_subdev_state *state)
>  {
> -	fmt->colorspace = V4L2_COLORSPACE_SRGB;
> -	fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
> -	fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
> -							  fmt->colorspace,
> -							  fmt->ycbcr_enc);
> -	fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
> +	int ret;
> +
> +	v4l2_subdev_lock_state(state);
> +
> +	ret = _imx219_set_routing(sd, state);
> +
> +	v4l2_subdev_unlock_state(state);
> +
> +	return ret;
>  }
>  
> -static void imx219_update_pad_format(struct imx219 *imx219,
> -				     const struct imx219_mode *mode,
> -				     struct v4l2_subdev_format *fmt)
> +static int imx219_enum_mbus_code(struct v4l2_subdev *sd,
> +				 struct v4l2_subdev_state *sd_state,
> +				 struct v4l2_subdev_mbus_code_enum *code)
>  {
> -	fmt->format.width = mode->width;
> -	fmt->format.height = mode->height;
> -	fmt->format.field = V4L2_FIELD_NONE;
> -	imx219_reset_colorspace(&fmt->format);
> +	if (code->index >= ARRAY_SIZE(imx219_mbus_formats))
> +		return -EINVAL;
> +
> +	code->code = imx219_mbus_formats[code->index];
> +
> +	return 0;
>  }
>  
> -static int __imx219_get_pad_format(struct imx219 *imx219,
> -				   struct v4l2_subdev_state *sd_state,
> -				   struct v4l2_subdev_format *fmt)
> +static int imx219_enum_frame_size(struct v4l2_subdev *sd,
> +				  struct v4l2_subdev_state *sd_state,
> +				  struct v4l2_subdev_frame_size_enum *fse)
>  {
> -	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> -		struct v4l2_mbus_framefmt *try_fmt =
> -			v4l2_subdev_get_try_format(&imx219->sd, sd_state,
> -						   fmt->pad);
> -		/* update the code which could change due to vflip or hflip: */
> -		try_fmt->code = imx219_get_format_code(imx219, try_fmt->code);
> -		fmt->format = *try_fmt;
> +	unsigned int i;
> +
> +	if (fse->stream == 0) {
> +		for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
> +			if (imx219_mbus_formats[i] == fse->code)
> +				break;
> +		}
> +
> +		if (i == ARRAY_SIZE(imx219_mbus_formats))
> +			return -EINVAL;
> +
> +		if (fse->index >= ARRAY_SIZE(supported_modes))
> +			return -EINVAL;
> +
> +		fse->min_width  = supported_modes[fse->index].width;
> +		fse->max_width  = fse->min_width;
> +		fse->max_height = supported_modes[fse->index].height;
> +		fse->min_height = fse->max_height;
>  	} else {
> -		imx219_update_pad_format(imx219, imx219->mode, fmt);
> -		fmt->format.code = imx219_get_format_code(imx219,
> -							  imx219->fmt.code);
> +		if (fse->code != MEDIA_BUS_FMT_METADATA_8)
> +			return -EINVAL;
> +
> +		fse->min_width = IMX219_EMBEDDED_LINE_WIDTH;
> +		fse->max_width = fse->min_width;
> +		fse->min_height = IMX219_NUM_EMBEDDED_LINES;
> +		fse->max_height = fse->min_height;
>  	}
>  
>  	return 0;
>  }
>  
> -static int imx219_get_pad_format(struct v4l2_subdev *sd,
> -				 struct v4l2_subdev_state *sd_state,
> -				 struct v4l2_subdev_format *fmt)
> +static void imx219_update_metadata_pad_format(struct v4l2_subdev_format *fmt)
>  {
> -	struct imx219 *imx219 = to_imx219(sd);
> -	int ret;
> -
> -	mutex_lock(&imx219->mutex);
> -	ret = __imx219_get_pad_format(imx219, sd_state, fmt);
> -	mutex_unlock(&imx219->mutex);
> -
> -	return ret;
> +	fmt->format.width = IMX219_EMBEDDED_LINE_WIDTH;
> +	fmt->format.height = IMX219_NUM_EMBEDDED_LINES;
> +	fmt->format.code = MEDIA_BUS_FMT_METADATA_8;
> +	fmt->format.field = V4L2_FIELD_NONE;
>  }
>  
>  static int imx219_set_pad_format(struct v4l2_subdev *sd,
> @@ -901,82 +916,91 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
>  				 struct v4l2_subdev_format *fmt)
>  {
>  	struct imx219 *imx219 = to_imx219(sd);
> +	struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd);
>  	const struct imx219_mode *mode;
> -	struct v4l2_mbus_framefmt *framefmt;
> -	int exposure_max, exposure_def, hblank;
> +	struct v4l2_mbus_framefmt *format;
>  	unsigned int i;
> +	int ret = 0;
> +	int exposure_max, exposure_def, hblank;
>  
> -	mutex_lock(&imx219->mutex);
> +	if (fmt->pad != 0) {
> +		dev_err(&client->dev, "%s Could not get pad %d\n", __func__,
> +			fmt->pad);
> +		return -EINVAL;
> +	}
>  
> -	for (i = 0; i < ARRAY_SIZE(codes); i++)
> -		if (codes[i] == fmt->format.code)
> +	if (fmt->stream == 1) {
> +		/* Only one embedded data mode is supported */
> +		imx219_update_metadata_pad_format(fmt);
> +		return 0;
> +	}
> +
> +	if (fmt->stream != 0)
> +		return -EINVAL;
> +
> +	/*
> +	 * Validate the media bus code, defaulting to the first one if the
> +	 * requested code isn't supported.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(imx219_mbus_formats); ++i) {
> +		if (imx219_mbus_formats[i] == fmt->format.code)
>  			break;
> -	if (i >= ARRAY_SIZE(codes))
> -		i = 0;
> +	}
>  
> -	/* Bayer order varies with flips */
> -	fmt->format.code = imx219_get_format_code(imx219, codes[i]);
> +	if (i >= ARRAY_SIZE(imx219_mbus_formats))
> +		i = 0;
>  
>  	mode = v4l2_find_nearest_size(supported_modes,
>  				      ARRAY_SIZE(supported_modes),
>  				      width, height,
> -				      fmt->format.width, fmt->format.height);
> -	imx219_update_pad_format(imx219, mode, fmt);
> -	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> -		framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> -		*framefmt = fmt->format;
> -	} else if (imx219->mode != mode ||
> -		   imx219->fmt.code != fmt->format.code) {
> -		imx219->fmt = fmt->format;
> -		imx219->mode = mode;
> -		/* Update limits and set FPS to default */
> -		__v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
> -					 IMX219_VTS_MAX - mode->height, 1,
> -					 mode->vts_def - mode->height);
> -		__v4l2_ctrl_s_ctrl(imx219->vblank,
> -				   mode->vts_def - mode->height);
> -		/* Update max exposure while meeting expected vblanking */
> -		exposure_max = mode->vts_def - 4;
> -		exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
> -			exposure_max : IMX219_EXPOSURE_DEFAULT;
> -		__v4l2_ctrl_modify_range(imx219->exposure,
> -					 imx219->exposure->minimum,
> -					 exposure_max, imx219->exposure->step,
> -					 exposure_def);
> -		/*
> -		 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so hblank
> -		 * depends on mode->width only, and is not changeble in any
> -		 * way other than changing the mode.
> -		 */
> -		hblank = IMX219_PPL_DEFAULT - mode->width;
> -		__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1,
> -					 hblank);
> -	}
> +				      fmt->format.width,
> +				      fmt->format.height);
>  
> -	mutex_unlock(&imx219->mutex);
> +	v4l2_subdev_lock_state(sd_state);
>  
> -	return 0;
> -}
> +	/* Update the stored format and return it. */
> +	format = v4l2_state_get_stream_format(sd_state, fmt->pad, fmt->stream);
>  
> -static int imx219_set_framefmt(struct imx219 *imx219)
> -{
> -	switch (imx219->fmt.code) {
> -	case MEDIA_BUS_FMT_SRGGB8_1X8:
> -	case MEDIA_BUS_FMT_SGRBG8_1X8:
> -	case MEDIA_BUS_FMT_SGBRG8_1X8:
> -	case MEDIA_BUS_FMT_SBGGR8_1X8:
> -		return imx219_write_regs(imx219, raw8_framefmt_regs,
> -					ARRAY_SIZE(raw8_framefmt_regs));
> -
> -	case MEDIA_BUS_FMT_SRGGB10_1X10:
> -	case MEDIA_BUS_FMT_SGRBG10_1X10:
> -	case MEDIA_BUS_FMT_SGBRG10_1X10:
> -	case MEDIA_BUS_FMT_SBGGR10_1X10:
> -		return imx219_write_regs(imx219, raw10_framefmt_regs,
> -					ARRAY_SIZE(raw10_framefmt_regs));
> +	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE && imx219->streaming) {
> +		ret = -EBUSY;
> +		goto done;
>  	}
>  
> -	return -EINVAL;
> +	/* Bayer order varies with flips */
> +	fmt->format.code = imx219_get_format_code(imx219, imx219_mbus_formats[i]);
> +	fmt->format = *format;
> +
> +	/* Update limits and set FPS to default */
> +	__v4l2_ctrl_modify_range(imx219->vblank,
> +				 IMX219_VBLANK_MIN,
> +				 IMX219_VTS_MAX - mode->height,
> +				 1,
> +				 mode->vts_def - mode->height);
> +	__v4l2_ctrl_s_ctrl(imx219->vblank, mode->vts_def - mode->height);
> +	/*
> +	 * Update max exposure while meeting
> +	 * expected vblanking
> +	 */
> +	exposure_max = mode->vts_def - 4;
> +	exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
> +			exposure_max : IMX219_EXPOSURE_DEFAULT;
> +	__v4l2_ctrl_modify_range(imx219->exposure,
> +				 imx219->exposure->minimum,
> +				 exposure_max,
> +				 imx219->exposure->step,
> +				 exposure_def);
> +	/*
> +	 * Currently PPL is fixed to IMX219_PPL_DEFAULT, so
> +	 * hblank depends on mode->width only, and is not
> +	 * changeble in any way other than changing the mode.
> +	 */
> +	hblank = IMX219_PPL_DEFAULT - mode->width;
> +	__v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, hblank);
> +
> +done:
> +	v4l2_subdev_unlock_state(sd_state);
> +
> +	return ret;
>  }
>  
>  static const struct v4l2_rect *
> @@ -1037,9 +1061,11 @@ static int imx219_start_streaming(struct imx219 *imx219)
>  	const struct imx219_reg_list *reg_list;
>  	int ret;
>  
> -	ret = pm_runtime_resume_and_get(&client->dev);
> -	if (ret < 0)
> +	ret = pm_runtime_get_sync(&client->dev);
> +	if (ret < 0) {
> +		pm_runtime_put_noidle(&client->dev);
>  		return ret;
> +	}
>  
>  	/* Apply default values of current mode */
>  	reg_list = &imx219->mode->reg_list;
> @@ -1049,13 +1075,6 @@ static int imx219_start_streaming(struct imx219 *imx219)
>  		goto err_rpm_put;
>  	}
>  
> -	ret = imx219_set_framefmt(imx219);
> -	if (ret) {
> -		dev_err(&client->dev, "%s failed to set frame format: %d\n",
> -			__func__, ret);
> -		goto err_rpm_put;
> -	}
> -
>  	/* Apply customized values from user */
>  	ret =  __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler);
>  	if (ret)
> @@ -1133,21 +1152,22 @@ static int imx219_set_stream(struct v4l2_subdev *sd, int enable)
>  /* Power/clock management functions */
>  static int imx219_power_on(struct device *dev)
>  {
> -	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>  	struct imx219 *imx219 = to_imx219(sd);
>  	int ret;
>  
>  	ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
>  				    imx219->supplies);
>  	if (ret) {
> -		dev_err(dev, "%s: failed to enable regulators\n",
> +		dev_err(&client->dev, "%s: failed to enable regulators\n",
>  			__func__);
>  		return ret;
>  	}
>  
>  	ret = clk_prepare_enable(imx219->xclk);
>  	if (ret) {
> -		dev_err(dev, "%s: failed to enable clock\n",
> +		dev_err(&client->dev, "%s: failed to enable clock\n",
>  			__func__);
>  		goto reg_off;
>  	}
> @@ -1166,7 +1186,8 @@ static int imx219_power_on(struct device *dev)
>  
>  static int imx219_power_off(struct device *dev)
>  {
> -	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>  	struct imx219 *imx219 = to_imx219(sd);
>  
>  	gpiod_set_value_cansleep(imx219->reset_gpio, 0);
> @@ -1178,7 +1199,8 @@ static int imx219_power_off(struct device *dev)
>  
>  static int __maybe_unused imx219_suspend(struct device *dev)
>  {
> -	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>  	struct imx219 *imx219 = to_imx219(sd);
>  
>  	if (imx219->streaming)
> @@ -1189,7 +1211,8 @@ static int __maybe_unused imx219_suspend(struct device *dev)
>  
>  static int __maybe_unused imx219_resume(struct device *dev)
>  {
> -	struct v4l2_subdev *sd = dev_get_drvdata(dev);
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
>  	struct imx219 *imx219 = to_imx219(sd);
>  	int ret;
>  
> @@ -1255,11 +1278,13 @@ static const struct v4l2_subdev_video_ops imx219_video_ops = {
>  };
>  
>  static const struct v4l2_subdev_pad_ops imx219_pad_ops = {
> -	.enum_mbus_code = imx219_enum_mbus_code,
> -	.get_fmt = imx219_get_pad_format,
> -	.set_fmt = imx219_set_pad_format,
> -	.get_selection = imx219_get_selection,
> -	.enum_frame_size = imx219_enum_frame_size,
> +	.init_cfg		= imx219_init_cfg,
> +	.enum_mbus_code		= imx219_enum_mbus_code,
> +	.get_fmt		= v4l2_subdev_get_fmt,
> +	.set_fmt		= imx219_set_pad_format,
> +	.get_selection		= imx219_get_selection,
> +	.set_routing		= imx219_set_routing,
> +	.enum_frame_size	= imx219_enum_frame_size,
>  };
>  
>  static const struct v4l2_subdev_ops imx219_subdev_ops = {
> @@ -1268,10 +1293,6 @@ static const struct v4l2_subdev_ops imx219_subdev_ops = {
>  	.pad = &imx219_pad_ops,
>  };
>  
> -static const struct v4l2_subdev_internal_ops imx219_internal_ops = {
> -	.open = imx219_open,
> -};
> -
>  /* Initialize control handlers */
>  static int imx219_init_controls(struct imx219 *imx219)
>  {
> @@ -1446,6 +1467,7 @@ static int imx219_check_hwcfg(struct device *dev)
>  static int imx219_probe(struct i2c_client *client)
>  {
>  	struct device *dev = &client->dev;
> +	struct v4l2_subdev *sd;
>  	struct imx219 *imx219;
>  	int ret;
>  
> @@ -1453,7 +1475,8 @@ static int imx219_probe(struct i2c_client *client)
>  	if (!imx219)
>  		return -ENOMEM;
>  
> -	v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
> +	sd = &imx219->sd;
> +	v4l2_i2c_subdev_init(sd, client, &imx219_subdev_ops);
>  
>  	/* Check the hardware configuration in device tree */
>  	if (imx219_check_hwcfg(dev))
> @@ -1520,27 +1543,29 @@ static int imx219_probe(struct i2c_client *client)
>  		goto error_power_off;
>  
>  	/* Initialize subdev */
> -	imx219->sd.internal_ops = &imx219_internal_ops;
> -	imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> -			    V4L2_SUBDEV_FL_HAS_EVENTS;
> -	imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> +		     V4L2_SUBDEV_FL_HAS_EVENTS |
> +		     V4L2_SUBDEV_FL_MULTIPLEXED;
>  
> -	/* Initialize source pad */
> +	/* Initialize the media entity. */
>  	imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
> -
> -	/* Initialize default format */
> -	imx219_set_default_format(imx219);
> -
> -	ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
> +	sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +	ret = media_entity_pads_init(&sd->entity, 1, &imx219->pad);
>  	if (ret) {
>  		dev_err(dev, "failed to init entity pads: %d\n", ret);
>  		goto error_handler_free;
>  	}
>  
> -	ret = v4l2_async_register_subdev_sensor(&imx219->sd);
> +	ret = v4l2_subdev_init_finalize(sd);
> +	if (ret) {
> +		dev_err(dev, "failed to finalize sensor init: %d\n", ret);
> +		goto error_media_entity;
> +	}
> +
> +	ret = v4l2_async_register_subdev_sensor(sd);
>  	if (ret < 0) {
>  		dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
> -		goto error_media_entity;
> +		goto error_free_state;
>  	}
>  
>  	/* Enable runtime PM and turn off the device */
> @@ -1550,6 +1575,8 @@ static int imx219_probe(struct i2c_client *client)
>  
>  	return 0;
>  
> +error_free_state:
> +	v4l2_subdev_cleanup(sd);
>  error_media_entity:
>  	media_entity_cleanup(&imx219->sd.entity);
>  
> @@ -1568,6 +1595,9 @@ static int imx219_remove(struct i2c_client *client)
>  	struct imx219 *imx219 = to_imx219(sd);
>  
>  	v4l2_async_unregister_subdev(sd);
> +
> +	v4l2_subdev_cleanup(sd);
> +
>  	media_entity_cleanup(&sd->entity);
>  	imx219_free_controls(imx219);
>  

-- 
Regards,

Laurent Pinchart


From robh at kernel.org  Fri Jan 21 15:35:16 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 17:35:16 -0600
Subject: [v2 2/3] dt-bindings: ARM: Mediatek: Remove vppsys in MT8195
 clock document
In-Reply-To: <20220110005902.27148-3-chun-jie.chen@mediatek.com>
References: <20220110005902.27148-1-chun-jie.chen@mediatek.com>
 <20220110005902.27148-3-chun-jie.chen@mediatek.com>
Message-ID: <YetDNPs8Xo/Alndj@robh.at.kernel.org>

On Mon, Jan 10, 2022 at 08:59:01AM +0800, Chun-Jie Chen wrote:
> vppsys0 and vppsys1 sub-system are both integrated with mmsys driver,
> should be describe in mediatek,mmsys.yaml

Driver partitioning is not a reason to change the DT. This needs a 
better description answering why you are doing this and what are the 
implications (is this breaking the ABI?).

> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  .../arm/mediatek/mediatek,mt8195-clock.yaml      | 16 ----------------
>  1 file changed, 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> index 17fcbb45d121..d62d60181147 100644
> --- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8195-clock.yaml
> @@ -28,11 +28,9 @@ properties:
>            - mediatek,mt8195-imp_iic_wrap_s
>            - mediatek,mt8195-imp_iic_wrap_w
>            - mediatek,mt8195-mfgcfg
> -          - mediatek,mt8195-vppsys0
>            - mediatek,mt8195-wpesys
>            - mediatek,mt8195-wpesys_vpp0
>            - mediatek,mt8195-wpesys_vpp1
> -          - mediatek,mt8195-vppsys1
>            - mediatek,mt8195-imgsys
>            - mediatek,mt8195-imgsys1_dip_top
>            - mediatek,mt8195-imgsys1_dip_nr
> @@ -92,13 +90,6 @@ examples:
>          #clock-cells = <1>;
>      };
>  
> -  - |
> -    vppsys0: clock-controller at 14000000 {
> -        compatible = "mediatek,mt8195-vppsys0";
> -        reg = <0x14000000 0x1000>;
> -        #clock-cells = <1>;
> -    };
> -
>    - |
>      wpesys: clock-controller at 14e00000 {
>          compatible = "mediatek,mt8195-wpesys";
> @@ -120,13 +111,6 @@ examples:
>          #clock-cells = <1>;
>      };
>  
> -  - |
> -    vppsys1: clock-controller at 14f00000 {
> -        compatible = "mediatek,mt8195-vppsys1";
> -        reg = <0x14f00000 0x1000>;
> -        #clock-cells = <1>;
> -    };
> -
>    - |
>      imgsys: clock-controller at 15000000 {
>          compatible = "mediatek,mt8195-imgsys";
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Fri Jan 21 15:38:09 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 17:38:09 -0600
Subject: [PATCH v1 1/2] dt-bindings: iio: adc: Add compatible for
 Mediatek MT8186
In-Reply-To: <20220110084841.575-1-guodong.liu@mediatek.com>
References: <20220110084841.575-1-guodong.liu@mediatek.com>
Message-ID: <YetD4SehEDxLkrzH@robh.at.kernel.org>

On Mon, 10 Jan 2022 16:48:40 +0800, Guodong Liu wrote:
> This commit adds dt-binding documentation of auxadc for Mediatek MT8186 SoC
> Platform.
> 
> Signed-off-by: Guodong Liu <guodong.liu at mediatek.com>
> ---
>  .../devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml      | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Fri Jan 21 16:25:46 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:25:46 -0600
Subject: [v1 01/16] dt-bindings: ARM: Mediatek: Add new document bindings
 of MT8186 clock
In-Reply-To: <20220110134416.5191-2-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-2-chun-jie.chen@mediatek.com>
Message-ID: <YetPCgSSRiWpDtcc@robh.at.kernel.org>

On Mon, Jan 10, 2022 at 09:44:01PM +0800, Chun-Jie Chen wrote:
> This patch adds the new binding documentation for system clock
> and functional clock on Mediatek MT8186.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  .../arm/mediatek/mediatek,mt8186-clock.yaml   | 133 ++++++++++++++++++
>  .../mediatek/mediatek,mt8186-sys-clock.yaml   |  74 ++++++++++
>  2 files changed, 207 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
>  create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
> 
> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
> new file mode 100644
> index 000000000000..fc39101bc9b0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-clock.yaml
> @@ -0,0 +1,133 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-clock.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Mediatek Functional Clock Controller for MT8186
> +
> +maintainers:
> +  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +description:
> +  The clock architecture in Mediatek like below
> +  PLLs -->
> +          dividers -->
> +                      muxes
> +                           -->
> +                              clock gate
> +
> +  The devices provide clock gate control in different IP blocks.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8186-imp_iic_wrap
> +          - mediatek,mt8186-mfgsys
> +          - mediatek,mt8186-wpesys
> +          - mediatek,mt8186-imgsys1
> +          - mediatek,mt8186-imgsys2
> +          - mediatek,mt8186-vdecsys
> +          - mediatek,mt8186-vencsys
> +          - mediatek,mt8186-camsys
> +          - mediatek,mt8186-camsys_rawa
> +          - mediatek,mt8186-camsys_rawb
> +          - mediatek,mt8186-mdpsys
> +          - mediatek,mt8186-ipesys
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    imp_iic_wrap: clock-controller at 11017000 {
> +        compatible = "mediatek,mt8186-imp_iic_wrap";
> +        reg = <0x11017000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    mfgsys: clock-controller at 13000000 {
> +        compatible = "mediatek,mt8186-mfgsys";
> +        reg = <0x13000000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    wpesys: clock-controller at 14020000 {
> +        compatible = "mediatek,mt8186-wpesys";
> +        reg = <0x14020000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    imgsys1: clock-controller at 15020000 {
> +        compatible = "mediatek,mt8186-imgsys1";
> +        reg = <0x15020000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    imgsys2: clock-controller at 15820000 {
> +        compatible = "mediatek,mt8186-imgsys2";
> +        reg = <0x15820000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    vdecsys: clock-controller at 1602f000 {
> +        compatible = "mediatek,mt8186-vdecsys";
> +        reg = <0x1602f000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    vencsys: clock-controller at 17000000 {
> +        compatible = "mediatek,mt8186-vencsys";
> +        reg = <0x17000000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    camsys: clock-controller at 1a000000 {
> +        compatible = "mediatek,mt8186-camsys";
> +        reg = <0x1a000000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    camsys_rawa: clock-controller at 1a04f000 {
> +        compatible = "mediatek,mt8186-camsys_rawa";
> +        reg = <0x1a04f000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    camsys_rawb: clock-controller at 1a06f000 {
> +        compatible = "mediatek,mt8186-camsys_rawb";
> +        reg = <0x1a06f000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    mdpsys: clock-controller at 1b000000 {
> +        compatible = "mediatek,mt8186-mdpsys";
> +        reg = <0x1b000000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    ipesys: clock-controller at 1c000000 {
> +        compatible = "mediatek,mt8186-ipesys";
> +        reg = <0x1c000000 0x1000>;
> +        #clock-cells = <1>;
> +    };

There's little point in enumerating every possible compatible. 1 example 
is more than enough.


> diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
> new file mode 100644
> index 000000000000..11473971a165
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mt8186-sys-clock.yaml
> @@ -0,0 +1,74 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-sys-clock.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Mediatek System Clock Controller for MT8186
> +
> +maintainers:
> +  - Chun-Jie Chen <chun-jie.chen at mediatek.com>
> +
> +description:
> +  The clock architecture in Mediatek like below
> +  PLLs -->
> +          dividers -->
> +                      muxes
> +                           -->
> +                              clock gate
> +
> +  The apmixedsys provides most of PLLs which generated from SoC 26m.
> +  The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
> +  The infracfg_ao provides clock gate in peripheral and infrastructure IP blocks.
> +  The mcusys provides mux control to select the clock source in AP MCU.
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - mediatek,mt8186-mcusys
> +          - mediatek,mt8186-topckgen
> +          - mediatek,mt8186-infracfg_ao
> +          - mediatek,mt8186-apmixedsys
> +      - const: syscon
> +
> +  reg:
> +    maxItems: 1
> +
> +  '#clock-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    mcusys: syscon at c53a000 {

clock-controller at ...

Drop unused labels.

> +        compatible = "mediatek,mt8186-mcusys", "syscon";
> +        reg = <0xc53a000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    topckgen: syscon at 10000000 {
> +        compatible = "mediatek,mt8186-topckgen", "syscon";
> +        reg = <0x10000000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    infracfg_ao: syscon at 10001000 {
> +        compatible = "mediatek,mt8186-infracfg_ao", "syscon";
> +        reg = <0x10001000 0x1000>;
> +        #clock-cells = <1>;
> +    };
> +
> +  - |
> +    apmixedsys: syscon at 1000c000 {
> +        compatible = "mediatek,mt8186-apmixedsys", "syscon";
> +        reg = <0x1000c000 0x1000>;
> +        #clock-cells = <1>;
> +    };

Again, 1 example is enough.


From robh at kernel.org  Fri Jan 21 16:27:25 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:27:25 -0600
Subject: [v1 02/16] clk: mediatek: Add dt-bindings of MT8186 clocks
In-Reply-To: <20220110134416.5191-3-chun-jie.chen@mediatek.com>
References: <20220110134416.5191-1-chun-jie.chen@mediatek.com>
 <20220110134416.5191-3-chun-jie.chen@mediatek.com>
Message-ID: <YetPbU52JT6A8CKW@robh.at.kernel.org>

On Mon, Jan 10, 2022 at 09:44:02PM +0800, Chun-Jie Chen wrote:
> Add MT8186 clock dt-bindings, includes topckgen, apmixedsys,
> infracfg_ao, mcusys and subsystem clocks.
> 
> Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> ---
>  include/dt-bindings/clock/mt8186-clk.h | 445 +++++++++++++++++++++++++
>  1 file changed, 445 insertions(+)
>  create mode 100644 include/dt-bindings/clock/mt8186-clk.h

As mentioned, squash with patch 1.

> 
> diff --git a/include/dt-bindings/clock/mt8186-clk.h b/include/dt-bindings/clock/mt8186-clk.h
> new file mode 100644
> index 000000000000..6a291750cea4
> --- /dev/null
> +++ b/include/dt-bindings/clock/mt8186-clk.h
> @@ -0,0 +1,445 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */

Dual license please.

> +/*
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
> + */
> +
> +#ifndef _DT_BINDINGS_CLK_MT8186_H
> +#define _DT_BINDINGS_CLK_MT8186_H
> +
> +/* MCUSYS */
> +
> +#define CLK_MCU_ARMPLL_LL_SEL		0
> +#define CLK_MCU_ARMPLL_BL_SEL		1
> +#define CLK_MCU_ARMPLL_BUS_SEL		2
> +#define CLK_MCU_NR_CLK			3
> +
> +/* TOPCKGEN */
> +
> +#define CLK_TOP_AXI			0
> +#define CLK_TOP_SCP			1
> +#define CLK_TOP_MFG			2
> +#define CLK_TOP_CAMTG			3
> +#define CLK_TOP_CAMTG1			4
> +#define CLK_TOP_CAMTG2			5
> +#define CLK_TOP_CAMTG3			6
> +#define CLK_TOP_CAMTG4			7
> +#define CLK_TOP_CAMTG5			8
> +#define CLK_TOP_CAMTG6			9
> +#define CLK_TOP_UART			10
> +#define CLK_TOP_SPI			11
> +#define CLK_TOP_MSDC50_0_HCLK		12
> +#define CLK_TOP_MSDC50_0		13
> +#define CLK_TOP_MSDC30_1		14
> +#define CLK_TOP_AUDIO			15
> +#define CLK_TOP_AUD_INTBUS		16
> +#define CLK_TOP_AUD_1			17
> +#define CLK_TOP_AUD_2			18
> +#define CLK_TOP_AUD_ENGEN1		19
> +#define CLK_TOP_AUD_ENGEN2		20
> +#define CLK_TOP_DISP_PWM		21
> +#define CLK_TOP_SSPM			22
> +#define CLK_TOP_DXCC			23
> +#define CLK_TOP_USB_TOP			24
> +#define CLK_TOP_SRCK			25
> +#define CLK_TOP_SPM			26
> +#define CLK_TOP_I2C			27
> +#define CLK_TOP_PWM			28
> +#define CLK_TOP_SENINF			29
> +#define CLK_TOP_SENINF1			30
> +#define CLK_TOP_SENINF2			31
> +#define CLK_TOP_SENINF3			32
> +#define CLK_TOP_AES_MSDCFDE		33
> +#define CLK_TOP_PWRAP_ULPOSC		34
> +#define CLK_TOP_CAMTM			35
> +#define CLK_TOP_VENC			36
> +#define CLK_TOP_CAM			37
> +#define CLK_TOP_IMG1			38
> +#define CLK_TOP_IPE			39
> +#define CLK_TOP_DPMAIF			40
> +#define CLK_TOP_VDEC			41
> +#define CLK_TOP_DISP			42
> +#define CLK_TOP_MDP			43
> +#define CLK_TOP_AUDIO_H			44
> +#define CLK_TOP_UFS			45
> +#define CLK_TOP_AES_FDE			46
> +#define CLK_TOP_AUDIODSP		47
> +#define CLK_TOP_DVFSRC			48
> +#define CLK_TOP_DSI_OCC			49
> +#define CLK_TOP_SPMI_MST		50
> +#define CLK_TOP_SPINOR			51
> +#define CLK_TOP_NNA			52
> +#define CLK_TOP_NNA1			53
> +#define CLK_TOP_NNA2			54
> +#define CLK_TOP_SSUSB_XHCI		55
> +#define CLK_TOP_SSUSB_TOP_1P		56
> +#define CLK_TOP_SSUSB_XHCI_1P		57
> +#define CLK_TOP_WPE			58
> +#define CLK_TOP_DPI			59
> +#define CLK_TOP_U3_OCC_250M		60
> +#define CLK_TOP_U3_OCC_500M		61
> +#define CLK_TOP_ADSP_BUS		62
> +#define CLK_TOP_APLL_I2S0_MCK_SEL	63
> +#define CLK_TOP_APLL_I2S1_MCK_SEL	64
> +#define CLK_TOP_APLL_I2S2_MCK_SEL	65
> +#define CLK_TOP_APLL_I2S4_MCK_SEL	66
> +#define CLK_TOP_APLL_TDMOUT_MCK_SEL	67
> +#define CLK_TOP_MAINPLL_D2		68
> +#define CLK_TOP_MAINPLL_D2_D2		69
> +#define CLK_TOP_MAINPLL_D2_D4		70
> +#define CLK_TOP_MAINPLL_D2_D16		71
> +#define CLK_TOP_MAINPLL_D3		72
> +#define CLK_TOP_MAINPLL_D3_D2		73
> +#define CLK_TOP_MAINPLL_D3_D4		74
> +#define CLK_TOP_MAINPLL_D5		75
> +#define CLK_TOP_MAINPLL_D5_D2		76
> +#define CLK_TOP_MAINPLL_D5_D4		77
> +#define CLK_TOP_MAINPLL_D7		78
> +#define CLK_TOP_MAINPLL_D7_D2		79
> +#define CLK_TOP_MAINPLL_D7_D4		80
> +#define CLK_TOP_UNIVPLL			81
> +#define CLK_TOP_UNIVPLL_D2		82
> +#define CLK_TOP_UNIVPLL_D2_D2		83
> +#define CLK_TOP_UNIVPLL_D2_D4		84
> +#define CLK_TOP_UNIVPLL_D3		85
> +#define CLK_TOP_UNIVPLL_D3_D2		86
> +#define CLK_TOP_UNIVPLL_D3_D4		87
> +#define CLK_TOP_UNIVPLL_D3_D8		88
> +#define CLK_TOP_UNIVPLL_D3_D32		89
> +#define CLK_TOP_UNIVPLL_D5		90
> +#define CLK_TOP_UNIVPLL_D5_D2		91
> +#define CLK_TOP_UNIVPLL_D5_D4		92
> +#define CLK_TOP_UNIVPLL_D7		93
> +#define CLK_TOP_UNIVPLL_192M		94
> +#define CLK_TOP_UNIVPLL_192M_D4		95
> +#define CLK_TOP_UNIVPLL_192M_D8		96
> +#define CLK_TOP_UNIVPLL_192M_D16	97
> +#define CLK_TOP_UNIVPLL_192M_D32	98
> +#define CLK_TOP_APLL1_D2		99
> +#define CLK_TOP_APLL1_D4		100
> +#define CLK_TOP_APLL1_D8		101
> +#define CLK_TOP_APLL2_D2		102
> +#define CLK_TOP_APLL2_D4		103
> +#define CLK_TOP_APLL2_D8		104
> +#define CLK_TOP_MMPLL_D2		105
> +#define CLK_TOP_TVDPLL_D2		106
> +#define CLK_TOP_TVDPLL_D4		107
> +#define CLK_TOP_TVDPLL_D8		108
> +#define CLK_TOP_TVDPLL_D16		109
> +#define CLK_TOP_TVDPLL_D32		110
> +#define CLK_TOP_MSDCPLL_D2		111
> +#define CLK_TOP_ULPOSC1			112
> +#define CLK_TOP_ULPOSC1_D2		113
> +#define CLK_TOP_ULPOSC1_D4		114
> +#define CLK_TOP_ULPOSC1_D8		115
> +#define CLK_TOP_ULPOSC1_D10		116
> +#define CLK_TOP_ULPOSC1_D16		117
> +#define CLK_TOP_ULPOSC1_D32		118
> +#define CLK_TOP_ADSPPLL_D2		119
> +#define CLK_TOP_ADSPPLL_D4		120
> +#define CLK_TOP_ADSPPLL_D8		121
> +#define CLK_TOP_NNAPLL_D2		122
> +#define CLK_TOP_NNAPLL_D4		123
> +#define CLK_TOP_NNAPLL_D8		124
> +#define CLK_TOP_NNA2PLL_D2		125
> +#define CLK_TOP_NNA2PLL_D4		126
> +#define CLK_TOP_NNA2PLL_D8		127
> +#define CLK_TOP_F_BIST2FPC		128
> +#define CLK_TOP_466M_FMEM		129
> +#define CLK_TOP_MPLL			130
> +#define CLK_TOP_APLL12_CK_DIV0		131
> +#define CLK_TOP_APLL12_CK_DIV1		132
> +#define CLK_TOP_APLL12_CK_DIV2		133
> +#define CLK_TOP_APLL12_CK_DIV4		134
> +#define CLK_TOP_APLL12_CK_DIV_TDMOUT_M	135
> +#define CLK_TOP_NR_CLK			136
> +
> +/* INFRACFG_AO */
> +
> +#define CLK_INFRA_AO_PMIC_TMR		0
> +#define CLK_INFRA_AO_PMIC_AP		1
> +#define CLK_INFRA_AO_PMIC_MD		2
> +#define CLK_INFRA_AO_PMIC_CONN		3
> +#define CLK_INFRA_AO_SCP_CORE		4
> +#define CLK_INFRA_AO_SEJ		5
> +#define CLK_INFRA_AO_APXGPT		6
> +#define CLK_INFRA_AO_ICUSB		7
> +#define CLK_INFRA_AO_GCE		8
> +#define CLK_INFRA_AO_THERM		9
> +#define CLK_INFRA_AO_I2C_AP		10
> +#define CLK_INFRA_AO_I2C_CCU		11
> +#define CLK_INFRA_AO_I2C_SSPM		12
> +#define CLK_INFRA_AO_I2C_RSV		13
> +#define CLK_INFRA_AO_PWM_HCLK		14
> +#define CLK_INFRA_AO_PWM1		15
> +#define CLK_INFRA_AO_PWM2		16
> +#define CLK_INFRA_AO_PWM3		17
> +#define CLK_INFRA_AO_PWM4		18
> +#define CLK_INFRA_AO_PWM5		19
> +#define CLK_INFRA_AO_PWM		20
> +#define CLK_INFRA_AO_UART0		21
> +#define CLK_INFRA_AO_UART1		22
> +#define CLK_INFRA_AO_UART2		23
> +#define CLK_INFRA_AO_GCE_26M		24
> +#define CLK_INFRA_AO_CQ_DMA_FPC		25
> +#define CLK_INFRA_AO_BTIF		26
> +#define CLK_INFRA_AO_SPI0		27
> +#define CLK_INFRA_AO_MSDC0		28
> +#define CLK_INFRA_AO_MSDCFDE		29
> +#define CLK_INFRA_AO_MSDC1		30
> +#define CLK_INFRA_AO_DVFSRC		31
> +#define CLK_INFRA_AO_GCPU		32
> +#define CLK_INFRA_AO_TRNG		33
> +#define CLK_INFRA_AO_AUXADC		34
> +#define CLK_INFRA_AO_CPUM		35
> +#define CLK_INFRA_AO_CCIF1_AP		36
> +#define CLK_INFRA_AO_CCIF1_MD		37
> +#define CLK_INFRA_AO_AUXADC_MD		38
> +#define CLK_INFRA_AO_AP_DMA		39
> +#define CLK_INFRA_AO_XIU		40
> +#define CLK_INFRA_AO_DEVICE_APC		41
> +#define CLK_INFRA_AO_CCIF_AP		42
> +#define CLK_INFRA_AO_DEBUGTOP		43
> +#define CLK_INFRA_AO_AUDIO		44
> +#define CLK_INFRA_AO_CCIF_MD		45
> +#define CLK_INFRA_AO_DXCC_SEC_CORE	46
> +#define CLK_INFRA_AO_DXCC_AO		47
> +#define CLK_INFRA_AO_IMP_IIC		48
> +#define CLK_INFRA_AO_DRAMC_F26M		49
> +#define CLK_INFRA_AO_RG_PWM_FBCLK6	50
> +#define CLK_INFRA_AO_SSUSB_TOP_HCLK	51
> +#define CLK_INFRA_AO_DISP_PWM		52
> +#define CLK_INFRA_AO_CLDMA_BCLK		53
> +#define CLK_INFRA_AO_AUDIO_26M_BCLK	54
> +#define CLK_INFRA_AO_SSUSB_TOP_P1_HCLK	55
> +#define CLK_INFRA_AO_SPI1		56
> +#define CLK_INFRA_AO_I2C4		57
> +#define CLK_INFRA_AO_MODEM_TEMP_SHARE	58
> +#define CLK_INFRA_AO_SPI2		59
> +#define CLK_INFRA_AO_SPI3		60
> +#define CLK_INFRA_AO_SSUSB_TOP_REF	61
> +#define CLK_INFRA_AO_SSUSB_TOP_XHCI	62
> +#define CLK_INFRA_AO_SSUSB_TOP_P1_REF	63
> +#define CLK_INFRA_AO_SSUSB_TOP_P1_XHCI	64
> +#define CLK_INFRA_AO_SSPM		65
> +#define CLK_INFRA_AO_SSUSB_TOP_P1_SYS	66
> +#define CLK_INFRA_AO_I2C5		67
> +#define CLK_INFRA_AO_I2C5_ARBITER	68
> +#define CLK_INFRA_AO_I2C5_IMM		69
> +#define CLK_INFRA_AO_I2C1_ARBITER	70
> +#define CLK_INFRA_AO_I2C1_IMM		71
> +#define CLK_INFRA_AO_I2C2_ARBITER	72
> +#define CLK_INFRA_AO_I2C2_IMM		73
> +#define CLK_INFRA_AO_SPI4		74
> +#define CLK_INFRA_AO_SPI5		75
> +#define CLK_INFRA_AO_CQ_DMA		76
> +#define CLK_INFRA_AO_BIST2FPC		77
> +#define CLK_INFRA_AO_MSDC0_SELF		78
> +#define CLK_INFRA_AO_SPINOR		79
> +#define CLK_INFRA_AO_SSPM_26M_SELF	80
> +#define CLK_INFRA_AO_SSPM_32K_SELF	81
> +#define CLK_INFRA_AO_I2C6		82
> +#define CLK_INFRA_AO_AP_MSDC0		83
> +#define CLK_INFRA_AO_MD_MSDC0		84
> +#define CLK_INFRA_AO_MSDC0_SRC		85
> +#define CLK_INFRA_AO_MSDC1_SRC		86
> +#define CLK_INFRA_AO_SEJ_F13M		87
> +#define CLK_INFRA_AO_AES_TOP0_BCLK	88
> +#define CLK_INFRA_AO_MCU_PM_BCLK	89
> +#define CLK_INFRA_AO_CCIF2_AP		90
> +#define CLK_INFRA_AO_CCIF2_MD		91
> +#define CLK_INFRA_AO_CCIF3_AP		92
> +#define CLK_INFRA_AO_CCIF3_MD		93
> +#define CLK_INFRA_AO_FADSP_26M		94
> +#define CLK_INFRA_AO_FADSP_32K		95
> +#define CLK_INFRA_AO_CCIF4_AP		96
> +#define CLK_INFRA_AO_CCIF4_MD		97
> +#define CLK_INFRA_AO_FADSP		98
> +#define CLK_INFRA_AO_FLASHIF_133M	99
> +#define CLK_INFRA_AO_FLASHIF_66M	100
> +#define CLK_INFRA_AO_NR_CLK		101
> +
> +/* APMIXEDSYS */
> +
> +#define CLK_APMIXED_ARMPLL_LL		0
> +#define CLK_APMIXED_ARMPLL_BL		1
> +#define CLK_APMIXED_CCIPLL		2
> +#define CLK_APMIXED_MAINPLL		3
> +#define CLK_APMIXED_UNIV2PLL		4
> +#define CLK_APMIXED_MSDCPLL		5
> +#define CLK_APMIXED_MMPLL		6
> +#define CLK_APMIXED_NNAPLL		7
> +#define CLK_APMIXED_NNA2PLL		8
> +#define CLK_APMIXED_ADSPPLL		9
> +#define CLK_APMIXED_MFGPLL		10
> +#define CLK_APMIXED_TVDPLL		11
> +#define CLK_APMIXED_APLL1		12
> +#define CLK_APMIXED_APLL2		13
> +#define CLK_APMIXED_NR_CLK		14
> +
> +/* IMP_IIC_WRAP */
> +
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C0	0
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C1	1
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C2	2
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C3	3
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C4	4
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C5	5
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C6	6
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C7	7
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C8	8
> +#define CLK_IMP_IIC_WRAP_AP_CLOCK_I2C9	9
> +#define CLK_IMP_IIC_WRAP_NR_CLK		10
> +
> +/* MFGCFG */
> +
> +#define CLK_MFG_BG3D			0
> +#define CLK_MFG_NR_CLK			1
> +
> +/* MMSYS */
> +
> +#define CLK_MM_DISP_MUTEX0		0
> +#define CLK_MM_APB_MM_BUS		1
> +#define CLK_MM_DISP_OVL0		2
> +#define CLK_MM_DISP_RDMA0		3
> +#define CLK_MM_DISP_OVL0_2L		4
> +#define CLK_MM_DISP_WDMA0		5
> +#define CLK_MM_DISP_RSZ0		6
> +#define CLK_MM_DISP_AAL0		7
> +#define CLK_MM_DISP_CCORR0		8
> +#define CLK_MM_DISP_COLOR0		9
> +#define CLK_MM_SMI_INFRA		10
> +#define CLK_MM_DISP_DSC_WRAP0		11
> +#define CLK_MM_DISP_GAMMA0		12
> +#define CLK_MM_DISP_POSTMASK0		13
> +#define CLK_MM_DISP_DITHER0		14
> +#define CLK_MM_SMI_COMMON		15
> +#define CLK_MM_DSI0			16
> +#define CLK_MM_DISP_FAKE_ENG0		17
> +#define CLK_MM_DISP_FAKE_ENG1		18
> +#define CLK_MM_SMI_GALS			19
> +#define CLK_MM_SMI_IOMMU		20
> +#define CLK_MM_DISP_RDMA1		21
> +#define CLK_MM_DISP_DPI			22
> +#define CLK_MM_DSI0_DSI_CK_DOMAIN	23
> +#define CLK_MM_DISP_26M			24
> +#define CLK_MM_NR_CLK			25
> +
> +/* WPESYS */
> +
> +#define CLK_WPE_CK_EN			0
> +#define CLK_WPE_SMI_LARB8_CK_EN		1
> +#define CLK_WPE_SYS_EVENT_TX_CK_EN	2
> +#define CLK_WPE_SMI_LARB8_PCLK_EN	3
> +#define CLK_WPE_NR_CLK			4
> +
> +/* IMGSYS1 */
> +
> +#define CLK_IMG1_LARB9_IMG1		0
> +#define CLK_IMG1_LARB10_IMG1		1
> +#define CLK_IMG1_DIP			2
> +#define CLK_IMG1_GALS_IMG1		3
> +#define CLK_IMG1_NR_CLK			4
> +
> +/* IMGSYS2 */
> +
> +#define CLK_IMG2_LARB9_IMG2		0
> +#define CLK_IMG2_LARB10_IMG2		1
> +#define CLK_IMG2_MFB			2
> +#define CLK_IMG2_WPE			3
> +#define CLK_IMG2_MSS			4
> +#define CLK_IMG2_GALS_IMG2		5
> +#define CLK_IMG2_NR_CLK			6
> +
> +/* VDECSYS */
> +
> +#define CLK_VDEC_LARB1_CKEN		0
> +#define CLK_VDEC_LAT_CKEN		1
> +#define CLK_VDEC_LAT_ACTIVE		2
> +#define CLK_VDEC_LAT_CKEN_ENG		3
> +#define CLK_VDEC_MINI_MDP_CKEN_CFG_RG	4
> +#define CLK_VDEC_CKEN			5
> +#define CLK_VDEC_ACTIVE			6
> +#define CLK_VDEC_CKEN_ENG		7
> +#define CLK_VDEC_NR_CLK			8
> +
> +/* VENCSYS */
> +
> +#define CLK_VENC_CKE0_LARB		0
> +#define CLK_VENC_CKE1_VENC		1
> +#define CLK_VENC_CKE2_JPGENC		2
> +#define CLK_VENC_CKE5_GALS		3
> +#define CLK_VENC_NR_CLK			4
> +
> +/* CAMSYS */
> +
> +#define CLK_CAM_LARB13			0
> +#define CLK_CAM_DFP_VAD			1
> +#define CLK_CAM_LARB14			2
> +#define CLK_CAM				3
> +#define CLK_CAMTG			4
> +#define CLK_CAM_SENINF			5
> +#define CLK_CAMSV1			6
> +#define CLK_CAMSV2			7
> +#define CLK_CAMSV3			8
> +#define CLK_CAM_CCU0			9
> +#define CLK_CAM_CCU1			10
> +#define CLK_CAM_MRAW0			11
> +#define CLK_CAM_FAKE_ENG		12
> +#define CLK_CAM_CCU_GALS		13
> +#define CLK_CAM2MM_GALS			14
> +#define CLK_CAM_NR_CLK			15
> +
> +/* CAMSYS_RAWA */
> +
> +#define CLK_CAM_RAWA_LARBX_RAWA		0
> +#define CLK_CAM_RAWA			1
> +#define CLK_CAM_RAWA_CAMTG_RAWA		2
> +#define CLK_CAM_RAWA_NR_CLK		3
> +
> +/* CAMSYS_RAWB */
> +
> +#define CLK_CAM_RAWB_LARBX_RAWB		0
> +#define CLK_CAM_RAWB			1
> +#define CLK_CAM_RAWB_CAMTG_RAWB		2
> +#define CLK_CAM_RAWB_NR_CLK		3
> +
> +/* MDPSYS */
> +
> +#define CLK_MDP_RDMA0			0
> +#define CLK_MDP_TDSHP0			1
> +#define CLK_MDP_IMG_DL_ASYNC0		2
> +#define CLK_MDP_IMG_DL_ASYNC1		3
> +#define CLK_MDP_DISP_RDMA		4
> +#define CLK_MDP_HMS			5
> +#define CLK_MDP_SMI0			6
> +#define CLK_MDP_APB_BUS			7
> +#define CLK_MDP_WROT0			8
> +#define CLK_MDP_RSZ0			9
> +#define CLK_MDP_HDR0			10
> +#define CLK_MDP_MUTEX0			11
> +#define CLK_MDP_WROT1			12
> +#define CLK_MDP_RSZ1			13
> +#define CLK_MDP_FAKE_ENG0		14
> +#define CLK_MDP_AAL0			15
> +#define CLK_MDP_DISP_WDMA		16
> +#define CLK_MDP_COLOR			17
> +#define CLK_MDP_IMG_DL_ASYNC2		18
> +#define CLK_MDP_IMG_DL_RELAY0_ASYNC0	19
> +#define CLK_MDP_IMG_DL_RELAY1_ASYNC1	20
> +#define CLK_MDP_IMG_DL_RELAY2_ASYNC2	21
> +#define CLK_MDP_NR_CLK			22
> +
> +/* IPESYS */
> +
> +#define CLK_IPE_LARB19			0
> +#define CLK_IPE_LARB20			1
> +#define CLK_IPE_SMI_SUBCOM		2
> +#define CLK_IPE_FD			3
> +#define CLK_IPE_FE			4
> +#define CLK_IPE_RSC			5
> +#define CLK_IPE_DPE			6
> +#define CLK_IPE_GALS_IPE		7
> +#define CLK_IPE_NR_CLK			8
> +
> +#endif /* _DT_BINDINGS_CLK_MT8186_H */
> -- 
> 2.18.0
> 
> 


From robh at kernel.org  Fri Jan 21 16:53:11 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:53:11 -0600
Subject: [PATCH V2 1/3] dt-bindings: spi: Convert spi-slave-mt27xx to
 json-schema
In-Reply-To: <20220112103609.17421-2-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
 <20220112103609.17421-2-leilk.liu@mediatek.com>
Message-ID: <YetVd7IR7FDt+nz3@robh.at.kernel.org>

On Wed, Jan 12, 2022 at 06:36:07PM +0800, Leilk Liu wrote:
> Convert Mediatek ARM SOC's SPI Slave controller binding
> to json-schema format.
> 
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
>  .../spi/mediatek,spi-slave-mt27xx.yaml        | 73 +++++++++++++++++++
>  .../bindings/spi/spi-slave-mt27xx.txt         | 33 ---------
>  2 files changed, 73 insertions(+), 33 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
> new file mode 100644
> index 000000000000..3364fff08cca
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
> @@ -0,0 +1,73 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SPI Slave controller for MediaTek ARM SoCs
> +
> +maintainers:
> +  - Leilk Liu <leilk.liu at mediatek.com>
> +
> +allOf:
> +  - $ref: /spi/spi-controller.yaml#
> +
> +properties:
> +  compatible:

> +    oneOf:
> +      - items:
> +          - enum:
> +              - mediatek,mt2712-spi-slave
> +      - items:
> +          - enum:
> +              - mediatek,mt8195-spi-slave

Just:

       enum:
         - mediatek,mt2712-spi-slave
         - mediatek,mt8195-spi-slave

> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: clock used for the clock gate

Just 'maxItems: 1'

> +
> +  clock-names:
> +    items:
> +      - const: spi
> +
> +  assigned-clocks:
> +    maxItems: 1
> +    description: |
> +      The mux clock for the given platform.
> +
> +  assigned-clock-parents:
> +    maxItems: 1
> +    description: |
> +      The parent of mux clock for the given platform.

You can drop assigned-clocks. They are always allowed on nodes with 
'clocks'.

> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt2712-clk.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    spi at 10013000 {
> +      compatible = "mediatek,mt2712-spi-slave";
> +      reg = <0x10013000 0x100>;
> +      interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
> +      clocks = <&infracfg CLK_INFRA_AO_SPI1>;
> +      clock-names = "spi";
> +      assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
> +      assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
> +    };


From robh at kernel.org  Fri Jan 21 16:57:01 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:57:01 -0600
Subject: [PATCH V2 2/3] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <20220112103609.17421-3-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
 <20220112103609.17421-3-leilk.liu@mediatek.com>
Message-ID: <YetWXSzugRwKb+xA@robh.at.kernel.org>

On Wed, Jan 12, 2022 at 06:36:08PM +0800, Leilk Liu wrote:
> Convert Mediatek ARM SOC's SPI Master controller binding
> to json-schema format.
> 
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
>  .../bindings/spi/mediatek,spi-mt65xx.yaml     | 99 +++++++++++++++++++
>  .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
>  2 files changed, 99 insertions(+), 68 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
>  delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
> 
> diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
> new file mode 100644
> index 000000000000..71f0cf6e5d70
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
> @@ -0,0 +1,99 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: SPI Bus controller for MediaTek ARM SoCs
> +
> +maintainers:
> +  - Leilk Liu <leilk.liu at mediatek.com>
> +
> +allOf:
> +  - $ref: /spi/spi-controller.yaml#

/schemas/spi/spi-controller.yaml#

> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - enum:
> +              - mediatek,mt7629-spi
> +          - const: mediatek,mt7622-spi
> +      - items:
> +          - enum:
> +              - mediatek,mt8516-spi
> +          - const: mediatek,mt2712-spi
> +      - items:
> +          - enum:
> +              - mediatek,mt6779-spi
> +              - mediatek,mt8192-spi
> +              - mediatek,mt8195-spi
> +          - const: mediatek,mt6765-spi

> +      - const: mediatek,mt2701-spi
> +      - const: mediatek,mt2712-spi
> +      - const: mediatek,mt6589-spi
> +      - const: mediatek,mt6765-spi
> +      - const: mediatek,mt6893-spi
> +      - const: mediatek,mt7622-spi
> +      - const: mediatek,mt8135-spi
> +      - const: mediatek,mt8173-spi
> +      - const: mediatek,mt8183-spi

All these can be 1 enum.

> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: clock used for the parent clock
> +      - description: clock used for the muxes clock
> +      - description: clock used for the clock gate
> +
> +  clock-names:
> +    items:
> +      - const: parent-clk
> +      - const: sel-clk
> +      - const: spi-clk
> +
> +  mediatek,pad-select:
> +    $ref: /schemas/types.yaml#/definitions/uint32-array
> +    maxItems: 4
> +    items:
> +      enum: [0, 1, 2, 3]
> +    description:
> +      specify which pins group(ck/mi/mo/cs) spi controller used.
> +      This is an array.
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - '#address-cells'
> +  - '#size-cells'
> +
> +unevaluatedProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mt8173-clk.h>
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    spi at 1100a000 {
> +      compatible = "mediatek,mt8173-spi";
> +      #address-cells = <1>;
> +      #size-cells = <0>;
> +      reg = <0x1100a000 0x1000>;
> +      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
> +      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
> +               <&topckgen CLK_TOP_SPI_SEL>,
> +               <&pericfg CLK_PERI_SPI0>;
> +      clock-names = "parent-clk", "sel-clk", "spi-clk";
> +      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
> +      mediatek,pad-select = <1>, <0>;
> +    };


From robh at kernel.org  Fri Jan 21 16:57:25 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:57:25 -0600
Subject: [PATCH V2 3/3] dt-bindings: spi: Add compatible for Mediatek
 MT8186
In-Reply-To: <20220112103609.17421-4-leilk.liu@mediatek.com>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
 <20220112103609.17421-4-leilk.liu@mediatek.com>
Message-ID: <YetWdZnqEODQtBMU@robh.at.kernel.org>

On Wed, 12 Jan 2022 18:36:09 +0800, Leilk Liu wrote:
> This commit adds dt-binding documentation of spi bus for Mediatek MT8186 SoC
> Platform.
> 
> Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> ---
>  Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 

Acked-by: Rob Herring <robh at kernel.org>


From robh at kernel.org  Fri Jan 21 16:59:23 2022
From: robh at kernel.org (Rob Herring)
Date: Fri, 21 Jan 2022 18:59:23 -0600
Subject: [PATCH 1/3] dt-bindings: dmaengine: zynqmp_dma: convert to yaml
In-Reply-To: <20220112151541.1328732-2-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
 <20220112151541.1328732-2-m.tretter@pengutronix.de>
Message-ID: <YetW6/YIR7SGAfHm@robh.at.kernel.org>

On Wed, 12 Jan 2022 16:15:39 +0100, Michael Tretter wrote:
> Convert the Xilinx ZynqMP DMA engine bindings to Yaml.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---
>  .../dma/xilinx/xlnx,zynqmp-dma-1.0.yaml       | 85 +++++++++++++++++++
>  .../bindings/dma/xilinx/zynqmp_dma.txt        | 26 ------
>  2 files changed, 85 insertions(+), 26 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
>  delete mode 100644 Documentation/devicetree/bindings/dma/xilinx/zynqmp_dma.txt
> 

Applied, thanks!


From pcc at google.com  Fri Jan 21 17:02:50 2022
From: pcc at google.com (Peter Collingbourne)
Date: Fri, 21 Jan 2022 17:02:50 -0800
Subject: [PATCH v3] arm64: mte: avoid clearing PSTATE.TCO on entry unless
 necessary
Message-ID: <20220122010250.251885-1-pcc@google.com>

On some microarchitectures, clearing PSTATE.TCO is expensive. Clearing
TCO is only necessary if in-kernel MTE is enabled, or if MTE is
enabled in the userspace process in synchronous (or, soon, asymmetric)
mode, because we do not report uaccess faults to userspace in none
or asynchronous modes. Therefore, adjust the kernel entry code to
clear TCO only if necessary.

Because it is now possible to switch to a task in which TCO needs to
be clear from a task in which TCO is set, we also need to do the same
thing on task switch.

Signed-off-by: Peter Collingbourne <pcc at google.com>
Link: https://linux-review.googlesource.com/id/I52d82a580bd0500d420be501af2c35fa8c90729e
---
v3:
- switch to a C implementation

v2:
- do the same thing in cpu_switch_to()

 arch/arm64/include/asm/mte.h     | 19 +++++++++++++++++++
 arch/arm64/kernel/entry-common.c |  3 +++
 arch/arm64/kernel/entry.S        |  7 -------
 arch/arm64/kernel/mte.c          |  1 +
 4 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 075539f5f1c8..5352db4c0f45 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -11,7 +11,9 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/bitfield.h>
+#include <linux/kasan.h>
 #include <linux/page-flags.h>
+#include <linux/sched.h>
 #include <linux/types.h>
 
 #include <asm/pgtable-types.h>
@@ -86,6 +88,23 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
 
 #endif /* CONFIG_ARM64_MTE */
 
+static inline void mte_disable_tco_entry(struct task_struct *task)
+{
+	/*
+	 * Re-enable tag checking (TCO set on exception entry). This is only
+	 * necessary if MTE is enabled in either the kernel or the userspace
+	 * task in synchronous mode. With MTE disabled in the kernel and
+	 * disabled or asynchronous in userspace, tag check faults (including in
+	 * uaccesses) are not reported, therefore there is no need to re-enable
+	 * checking. This is beneficial on microarchitectures where re-enabling
+	 * TCO is expensive.
+	 */
+	if (kasan_hw_tags_enabled() ||
+	    (system_supports_mte() &&
+	     (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT))))
+		asm volatile(SET_PSTATE_TCO(0));
+}
+
 #ifdef CONFIG_KASAN_HW_TAGS
 /* Whether the MTE asynchronous mode is enabled. */
 DECLARE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..7093b578e325 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/context_tracking.h>
+#include <linux/kasan.h>
 #include <linux/linkage.h>
 #include <linux/lockdep.h>
 #include <linux/ptrace.h>
@@ -56,6 +57,7 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
 {
 	__enter_from_kernel_mode(regs);
 	mte_check_tfsr_entry();
+	mte_disable_tco_entry(current);
 }
 
 /*
@@ -103,6 +105,7 @@ static __always_inline void __enter_from_user_mode(void)
 	CT_WARN_ON(ct_state() != CONTEXT_USER);
 	user_exit_irqoff();
 	trace_hardirqs_off_finish();
+	mte_disable_tco_entry(current);
 }
 
 static __always_inline void enter_from_user_mode(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 772ec2ecf488..e1013a83d4f0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -308,13 +308,6 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	msr_s	SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
 
-	/* Re-enable tag checking (TCO set on exception entry) */
-#ifdef CONFIG_ARM64_MTE
-alternative_if ARM64_MTE
-	SET_PSTATE_TCO(0)
-alternative_else_nop_endif
-#endif
-
 	/*
 	 * Registers that may be useful after this macro is invoked:
 	 *
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index f418ebc65f95..5345587f3384 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -252,6 +252,7 @@ void mte_thread_switch(struct task_struct *next)
 
 	mte_update_sctlr_user(next);
 	mte_update_gcr_excl(next);
+	mte_disable_tco_entry(next);
 
 	/*
 	 * Check if an async tag exception occurred at EL1.
-- 
2.35.0.rc0.227.g00780c9af4-goog



From pcc at google.com  Fri Jan 21 17:03:04 2022
From: pcc at google.com (Peter Collingbourne)
Date: Fri, 21 Jan 2022 17:03:04 -0800
Subject: [PATCH v2] arm64: mte: avoid clearing PSTATE.TCO on entry unless
 necessary
In-Reply-To: <YbzUGJ0tYQEY8c2g@arm.com>
References: <20211110220735.3937127-1-pcc@google.com>
 <YbNCsgH0ekceOkmi@arm.com>
 <CAMn1gO5-B0+wifqaDO63_wYr76Jttd7cx0ynb7UCfy5TNCxhLA@mail.gmail.com>
 <YbzUGJ0tYQEY8c2g@arm.com>
Message-ID: <CAMn1gO7DOtPUOs_V6sd_cLhVJ+W9cJhNc2T2ZVqNOv21uZrVXw@mail.gmail.com>

On Fri, Dec 17, 2021 at 10:17 AM Catalin Marinas
<catalin.marinas at arm.com> wrote:
>
> On Wed, Dec 15, 2021 at 06:44:03PM -0800, Peter Collingbourne wrote:
> > On Fri, Dec 10, 2021 at 4:06 AM Catalin Marinas <catalin.marinas at arm.com> wrote:
> > > On Wed, Nov 10, 2021 at 02:07:35PM -0800, Peter Collingbourne wrote:
> > > > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > > > index 2f69ae43941d..a78ec15f5bbc 100644
> > > > --- a/arch/arm64/kernel/entry.S
> > > > +++ b/arch/arm64/kernel/entry.S
> > > > @@ -189,6 +189,27 @@ alternative_cb_end
> > > >  #endif
> > > >       .endm
> > > >
> > > > +     .macro mte_clear_tco, sctlr
> > > > +     /*
> > > > +      * Re-enable tag checking (TCO set on exception entry). This is only
> > > > +      * necessary if MTE is enabled in either the kernel or the userspace
> > > > +      * task in synchronous mode. With MTE disabled in the kernel and
> > > > +      * disabled or asynchronous in userspace, tag check faults (including in
> > > > +      * uaccesses) are not reported, therefore there is no need to re-enable
> > > > +      * checking. This is beneficial on microarchitectures where re-enabling
> > > > +      * TCO is expensive.
> > > > +      */
> > > > +#ifdef CONFIG_ARM64_MTE
> > > > +alternative_cb       kasan_hw_tags_enable
> > > > +     tbz     \sctlr, #SCTLR_EL1_TCF0_SHIFT, 1f
> > > > +alternative_cb_end
> > > > +alternative_if ARM64_MTE
> > > > +     SET_PSTATE_TCO(0)
> > > > +alternative_else_nop_endif
> > > > +1:
> > > > +#endif
> > > > +     .endm
> > >
> > > The patch looks fine to me but I recall in a private conversation with
> > > Mark he proposed the idea of moving this to entry-common.c (unless it
> > > was about something completely different). The downside is that we run
> > > with the TCO set for slightly longer. There shouldn't be a major
> > > drawback currently as we don't have stack tagging anyway.
> >
> > Yes, Mark made that suggestion on the list. I tried it and found that
> > it led to a performance regression relative to baseline [1].
> [...]
> > [1] https://lore.kernel.org/all/CAMn1gO51k1Dqts=THYq28nVMSvO6ZQB5sEG1wuzEVpAXBTfFjg at mail.gmail.com/
>
> That's weird since there should be the same number of instructions
> executed on entry with your diff above. Could it be that
> mte_disable_tco_entry() is not inlined?

Looks like it was something like that. In the kernel without the patch
enter_from_user_mode() was empty which allowed the compiler to remove
the call from its callers (el0_svc etc). In the kernel with the patch
it contained one instruction (the MSR) and it wasn't inlined,
apparently because of the noinstr annotation (which includes noinline;
I guess removing a call to an empty function doesn't count as
inlining). This was with a kernel version based on 5.10 (don't
currently have a way to run a newer kernel version on this hardware
unfortunately); looks like some refactoring patches have landed since
then that allow enter_from_user_mode to be inlined.

With a similar refactoring patch applied to the 5.10 kernel, things
look fairly reasonable with the patch that I'm sending as v3. Looking
at all combinations of {kasan off, kasan on} x {none, async, sync} x
{big, medium, little} there are some small regressions but they are
mostly on the little cores.

I also tested the patch on non-MTE hardware (DragonBoard 845c) running
the mainline kernel. This revealed that the added call to
system_supports_mte() was necessary to avoid regressing things by too
much on non-MTE hardware (avoids the load from current). With the v3
patch the syscall latency goes from 245.1ns to 247.4ns on the little
cores and 151.4ns to 145.2ns on the big cores.

Peter


From stefan.wahren at i2se.com  Fri Jan 21 17:36:06 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat, 22 Jan 2022 02:36:06 +0100
Subject: [PATCH v3 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220121172840.12121-15-alim.akhtar@samsung.com>
References: <20220121172840.12121-1-alim.akhtar@samsung.com>
 <CGME20220121174117epcas5p4c1a7afa8b63ce4c55f05b6411d12fc09@epcas5p4.samsung.com>
 <20220121172840.12121-15-alim.akhtar@samsung.com>
Message-ID: <df109290-ceaa-97dd-3992-7dd60e515fe2@i2se.com>

Hi Alim,

Am 21.01.22 um 18:28 schrieb Alim Akhtar:
> Add initial device tree support for "Full Self-Driving" (FSD) SoC
> This SoC contain three clusters of four cortex-a72 CPUs and various
> peripheral IPs.
>
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> ---
>  MAINTAINERS                           |   8 +
>  arch/arm64/Kconfig.platforms          |   6 +
>  arch/arm64/boot/dts/Makefile          |   1 +
>  arch/arm64/boot/dts/tesla/Makefile    |   3 +
>  arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
>  arch/arm64/boot/dts/tesla/fsd.dtsi    | 651 ++++++++++++++++++++++++++
>  6 files changed, 708 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/tesla/Makefile
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
>  create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 27730a5a6345..ed1c10c26e5b 100644

> diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
> new file mode 100644
> index 000000000000..9a2b88f58c13
> --- /dev/null
> +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
> @@ -0,0 +1,651 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Tesla Full Self-Driving SoC device tree source
> + *
> + * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
> + *		https://www.samsung.com
> + * Copyright (c) 2017-2022 Tesla, Inc.
> + *		https://www.tesla.com
> + */
> +
> +#include <dt-bindings/clock/fsd-clk.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +/ {
...
> +		pwm_1: pwm at 14110000 {
> +			compatible = "samsung,exynos4210-pwm";
> +			reg = <0x0 0x14110000 0x0 0x100>;
> +			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
> +			#pwm-cells = <3>;
> +			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
> +			clock-names = "timers";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_0: hsi2c at 14200000 {

since this is a i2c interface the node name should be changed to i2c:

hi2c_0: i2c at ...

and the following ones.

> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14200000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c0_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_1: hsi2c at 14210000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14210000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c1_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_2: hsi2c at 14220000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14220000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c2_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_3: hsi2c at 14230000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14230000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c3_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_4: hsi2c at 14240000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14240000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c4_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_5: hsi2c at 14250000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14250000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c5_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_6: hsi2c at 14260000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14260000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c6_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +
> +		hsi2c_7: hsi2c at 14270000 {
> +			compatible = "samsung,exynos7-hsi2c";
> +			reg = <0x0 0x14270000 0x0 0x1000>;
> +			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&hs_i2c7_bus>;
> +			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
> +			clock-names = "hsi2c";
> +			status = "disabled";
> +		};
> +	};
> +};


From eugenis at google.com  Fri Jan 21 18:34:47 2022
From: eugenis at google.com (Evgenii Stepanov)
Date: Fri, 21 Jan 2022 18:34:47 -0800
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
Message-ID: <20220122023447.1480995-1-eugenis@google.com>

ex_handler_load_unaligned_zeropad extracts the source and data register
numbers from the wrong field of the exception table.

Fixes: 753b3236
Signed-off-by: Evgenii Stepanov <eugenis at google.com>
---
 arch/arm64/mm/extable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index c0181e60cc98..489455309695 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -40,8 +40,8 @@ static bool
 ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex,
 				  struct pt_regs *regs)
 {
-	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->type);
-	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->type);
+	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data);
+	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data);
 	unsigned long data, addr, offset;
 
 	addr = pt_regs_read_reg(regs, reg_addr);
-- 
2.35.0.rc0.227.g00780c9af4-goog



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:01 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:01 +0800
Subject: [PATCH v6, 00/15] media: mtk-vcodec: support for MT8192 decoder
Message-ID: <20220122035316.18179-1-yunfei.dong@mediatek.com>

This series adds support for mt8192 h264/vp8/vp9 decoder drivers. Firstly, refactor
power/clock/interrupt interfaces for mt8192 is lat and core architecture.

Secondly, add new functions to get frame buffer size and resolution according
to decoder capability from scp side. Then add callback function to get/put
capture buffer in order to enable lat and core decoder in parallel. 

Then add to support MT21C compressed mode and fix v4l2-compliance fail.

Next, extract H264 request api driver to let mt8183 and mt8192 use the same
code, and adds mt8192 frame based h264 driver for stateless decoder.

Lastly, add vp8 and vp9 stateless decoder drivers.

Patches 1 refactor power/clock/interrupt interface.
Patches 2~4 get frame buffer size and resolution according to decoder capability.
Patches 5~6 enable lat and core decode in parallel.
Patch 7~10 add to support MT21C compressed mode and fix v4l2-compliance fail.
patch 11 record capture queue format type.
Patch 12~13 extract h264 driver and add mt8192 frame based driver for h264 decoder.
Patch 14~15 add vp8 and vp9 stateless decoder drivers.
---
changes compared with v5:
- fix vp9 comments for patch 15
- fix vp8 comments for patch 14.
- fix comments for patch 12.
- fix build errors.
changes compared with v4:
- fix checkpatch.pl fail.
- fix kernel-doc fail.
- rebase to the latest media codec driver.
changes compared with v3:
- remove enum mtk_chip for patch 2.
- add vp8 stateless decoder drivers for patch 14.
- add vp9 stateless decoder drivers for patch 15.
changes compared with v2:
- add new patch 11 to record capture queue format type.
- separate patch 4 according to tzung-bi's suggestion.
- re-write commit message for patch 5 according to tzung-bi's suggestion.
changes compared with v1:
- rewrite commit message for patch 12.
- rewrite cover-letter message.
---
Yunfei Dong (15):
  media: mtk-vcodec: Add vdec enable/disable hardware helpers
  media: mtk-vcodec: Using firmware type to separate different firmware
    architecture
  media: mtk-vcodec: get capture queue buffer size from scp
  media: mtk-vcodec: Read max resolution from dec_capability
  media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set capture buffer
    buffered
  media: mtk-vcodec: Refactor get and put capture buffer flow
  media: mtk-vcodec: Refactor supported vdec formats and framesizes
  media: mtk-vcodec: Add format to support MT21C
  media: mtk-vcodec: disable vp8 4K capability
  media: mtk-vcodec: Fix v4l2-compliance fail
  media: mtk-vcodec: record capture queue format type
  media: mtk-vcodec: Extract H264 common code
  media: mtk-vcodec: support stateless H.264 decoding for mt8192
  media: mtk-vcodec: support stateless VP8 decoding
  media: mtk-vcodec: support stateless VP9 decoding

 drivers/media/platform/mtk-vcodec/Makefile    |    4 +
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   47 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |    5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   |  168 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |    6 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |   14 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  282 ++-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   40 +-
 .../platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |    5 -
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.c |    6 +
 .../media/platform/mtk-vcodec/mtk_vcodec_fw.h |    1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    |  310 +++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    |  253 +++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  440 +---
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  |  614 +++++
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         |  445 ++++
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 1971 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   36 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    3 +
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  |   36 +
 .../platform/mtk-vcodec/vdec_msg_queue.c      |    2 +
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |   53 +-
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   |   15 +
 .../media/platform/mtk-vcodec/venc_vpu_if.c   |    2 +-
 include/linux/remoteproc/mtk_scp.h            |    2 +
 25 files changed, 4174 insertions(+), 586 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:03 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:03 +0800
Subject: [PATCH v6,
 02/15] media: mtk-vcodec: Using firmware type to separate different
 firmware architecture
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-3-yunfei.dong@mediatek.com>

MT8173 platform use vpu firmware, mt8183/mt8192 will use scp
firmware instead, using chip name is not reasonable to separate
different firmware architecture. Using firmware type is much better.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateful.c   |  1 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_stateless.c  |  2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h  | 13 -------------
 .../media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c  |  5 -----
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c   |  6 ++++++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h   |  1 +
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c     |  4 ++--
 drivers/media/platform/mtk-vcodec/venc_vpu_if.c     |  2 +-
 8 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 04ca43c77e5f..7966c132be8f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -613,7 +613,6 @@ static struct vb2_ops mtk_vdec_frame_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
-	.chip = MTK_MT8173,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23d997ac114d..5aebf88f997b 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -343,7 +343,6 @@ static struct vb2_ops mtk_vdec_request_vb2_ops = {
 };
 
 const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
-	.chip = MTK_MT8183,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
@@ -362,7 +361,6 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 
 /* This platform data is used for one lat and one core architecture. */
 const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
-	.chip = MTK_MT8192,
 	.init_vdec_params = mtk_init_vdec_params,
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 94b47b7c912b..5056abe3d2be 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -335,13 +335,6 @@ struct mtk_vcodec_ctx {
 	struct vdec_msg_queue msg_queue;
 };
 
-enum mtk_chip {
-	MTK_MT8173,
-	MTK_MT8183,
-	MTK_MT8192,
-	MTK_MT8195,
-};
-
 /*
  * enum mtk_vdec_hw_arch - Used to separate different hardware architecture
  */
@@ -367,7 +360,6 @@ enum mtk_vdec_hw_arch {
  * @vdec_framesizes: supported video decoder frame sizes
  * @num_framesizes: count of video decoder frame sizes
  *
- * @chip: chip this decoder is compatible with
  * @hw_arch: hardware arch is used to separate pure_sin_core and lat_sin_core
  *
  * @is_subdev_supported: whether support parent-node architecture(subdev)
@@ -390,7 +382,6 @@ struct mtk_vcodec_dec_pdata {
 	const struct mtk_codec_framesizes *vdec_framesizes;
 	const int num_framesizes;
 
-	enum mtk_chip chip;
 	enum mtk_vdec_hw_arch hw_arch;
 
 	bool is_subdev_supported;
@@ -400,8 +391,6 @@ struct mtk_vcodec_dec_pdata {
 /**
  * struct mtk_vcodec_enc_pdata - compatible data for each IC
  *
- * @chip: chip this encoder is compatible with
- *
  * @uses_ext: whether the encoder uses the extended firmware messaging format
  * @min_bitrate: minimum supported encoding bitrate
  * @max_bitrate: maximum supported encoding bitrate
@@ -412,8 +401,6 @@ struct mtk_vcodec_dec_pdata {
  * @core_id: stand for h264 or vp8 encode index
  */
 struct mtk_vcodec_enc_pdata {
-	enum mtk_chip chip;
-
 	bool uses_ext;
 	unsigned long min_bitrate;
 	unsigned long max_bitrate;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..3ac6969c54c0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -378,7 +378,6 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 }
 
 static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
 	.output_formats = mtk_video_formats_output,
@@ -389,7 +388,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_avc_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
-	.chip = MTK_MT8173,
 	.capture_formats = mtk_video_formats_capture_vp8,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_vp8),
 	.output_formats = mtk_video_formats_output,
@@ -400,7 +398,6 @@ static const struct mtk_vcodec_enc_pdata mt8173_vp8_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
-	.chip = MTK_MT8183,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -412,7 +409,6 @@ static const struct mtk_vcodec_enc_pdata mt8183_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
-	.chip = MTK_MT8192,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
@@ -424,7 +420,6 @@ static const struct mtk_vcodec_enc_pdata mt8192_pdata = {
 };
 
 static const struct mtk_vcodec_enc_pdata mt8195_pdata = {
-	.chip = MTK_MT8195,
 	.uses_ext = true,
 	.capture_formats = mtk_video_formats_capture_h264,
 	.num_capture_formats = ARRAY_SIZE(mtk_video_formats_capture_h264),
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
index 94b39ae5c2e1..556e54aadac9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.c
@@ -65,3 +65,9 @@ int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
 	return fw->ops->ipi_send(fw, id, buf, len, wait);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_fw_ipi_send);
+
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw)
+{
+	return fw->type;
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_fw_get_type);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
index 539bb626772c..acd355961e3a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw.h
@@ -39,5 +39,6 @@ int mtk_vcodec_fw_ipi_register(struct mtk_vcodec_fw *fw, int id,
 			       const char *name, void *priv);
 int mtk_vcodec_fw_ipi_send(struct mtk_vcodec_fw *fw, int id,
 			   void *buf, unsigned int len, unsigned int wait);
+int mtk_vcodec_fw_get_type(struct mtk_vcodec_fw *fw);
 
 #endif /* _MTK_VCODEC_FW_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index dd35d2c5f920..7210061c772f 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -33,8 +33,8 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	 */
 	vpu->inst_id = 0xdeadbeef;
 
-	/* Firmware version field does not exist on MT8173. */
-	if (vpu->ctx->dev->vdec_pdata->chip == MTK_MT8173)
+	/* VPU firmware does not contain a version field. */
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
diff --git a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
index e7899d8a3e4e..d3570c4c177d 100644
--- a/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/venc_vpu_if.c
@@ -18,7 +18,7 @@ static void handle_enc_init_msg(struct venc_vpu_inst *vpu, const void *data)
 					     msg->vpu_inst_addr);
 
 	/* Firmware version field value is unspecified on MT8173. */
-	if (vpu->ctx->dev->venc_pdata->chip == MTK_MT8173)
+	if (mtk_vcodec_fw_get_type(vpu->ctx->dev->fw_handler) == VPU)
 		return;
 
 	/* Check firmware version. */
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:08 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:08 +0800
Subject: [PATCH v6,
 07/15] media: mtk-vcodec: Refactor supported vdec formats and
 framesizes
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-8-yunfei.dong@mediatek.com>

Supported output and capture format types for mt8192 are different
with mt8183. Needs to get format types according to decoder capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      |   8 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateful.c      |  13 +-
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 117 +++++++++++++-----
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  13 +-
 4 files changed, 107 insertions(+), 44 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 304f5afbd419..bae43938ee37 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -26,7 +26,7 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	const struct mtk_video_fmt *fmt;
 	unsigned int k;
 
-	for (k = 0; k < dec_pdata->num_formats; k++) {
+	for (k = 0; k < *dec_pdata->num_formats; k++) {
 		fmt = &dec_pdata->vdec_formats[k];
 		if (fmt->fourcc == f->fmt.pix_mp.pixelformat)
 			return fmt;
@@ -525,7 +525,7 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 	if (fsize->index != 0)
 		return -EINVAL;
 
-	for (i = 0; i < dec_pdata->num_framesizes; ++i) {
+	for (i = 0; i < *dec_pdata->num_framesizes; ++i) {
 		if (fsize->pixel_format != dec_pdata->vdec_framesizes[i].fourcc)
 			continue;
 
@@ -564,7 +564,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 	const struct mtk_video_fmt *fmt;
 	int i, j = 0;
 
-	for (i = 0; i < dec_pdata->num_formats; i++) {
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
 		if (output_queue &&
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_DEC)
 			continue;
@@ -577,7 +577,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		++j;
 	}
 
-	if (i == dec_pdata->num_formats)
+	if (i == *dec_pdata->num_formats)
 		return -EINVAL;
 
 	fmt = &dec_pdata->vdec_formats[i];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
index 7966c132be8f..3f33beb9c551 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateful.c
@@ -37,7 +37,9 @@ static const struct mtk_video_fmt mtk_video_formats[] = {
 	},
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
+static const unsigned int num_supported_formats =
+	ARRAY_SIZE(mtk_video_formats);
+
 #define DEFAULT_OUT_FMT_IDX 0
 #define DEFAULT_CAP_FMT_IDX 3
 
@@ -59,7 +61,8 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 	},
 };
 
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
+static const unsigned int num_supported_framesize =
+	ARRAY_SIZE(mtk_vdec_framesizes);
 
 /*
  * This function tries to clean all display buffers, the buffers will return
@@ -235,7 +238,7 @@ static void mtk_vdec_update_fmt(struct mtk_vcodec_ctx *ctx,
 	unsigned int k;
 
 	dst_q_data = &ctx->q_data[MTK_Q_DATA_DST];
-	for (k = 0; k < NUM_FORMATS; k++) {
+	for (k = 0; k < num_supported_formats; k++) {
 		fmt = &mtk_video_formats[k];
 		if (fmt->fourcc == pixelformat) {
 			mtk_v4l2_debug(1, "Update cap fourcc(%d -> %d)",
@@ -617,11 +620,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_frame_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
+	.num_formats = &num_supported_formats,
 	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
 	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_supported_framesize,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
 	.is_subdev_supported = false,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 6d481410bf89..e51d935bd21d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,33 +81,23 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static const struct mtk_video_fmt mtk_video_formats[] = {
-	{
-		.fourcc = V4L2_PIX_FMT_H264_SLICE,
-		.type = MTK_FMT_DEC,
-		.num_planes = 1,
-	},
-	{
-		.fourcc = V4L2_PIX_FMT_MM21,
-		.type = MTK_FMT_FRAME,
-		.num_planes = 2,
-	},
+static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+
+static struct mtk_video_fmt default_out_format;
+static struct mtk_video_fmt default_cap_format;
+static unsigned int num_formats;
+static unsigned int num_framesizes;
+
+static struct v4l2_frmsize_stepwise stepwise_fhd = {
+	.min_width = MTK_VDEC_MIN_W,
+	.max_width = MTK_VDEC_MAX_W,
+	.step_width = 16,
+	.min_height = MTK_VDEC_MIN_H,
+	.max_height = MTK_VDEC_MAX_H,
+	.step_height = 16
 };
 
-#define NUM_FORMATS ARRAY_SIZE(mtk_video_formats)
-#define DEFAULT_OUT_FMT_IDX    0
-#define DEFAULT_CAP_FMT_IDX    1
-
-static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
-	{
-		.fourcc	= V4L2_PIX_FMT_H264_SLICE,
-		.stepwise = {  MTK_VDEC_MIN_W, MTK_VDEC_MAX_W, 16,
-				MTK_VDEC_MIN_H, MTK_VDEC_MAX_H, 16 },
-	},
-};
-
-#define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
-
 static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
 					   struct mtk_vcodec_mem *bs, int error)
 {
@@ -350,6 +340,62 @@ const struct media_device_ops mtk_vcodec_media_ops = {
 	.req_queue	= v4l2_m2m_request_queue,
 };
 
+static void mtk_vcodec_add_formats(unsigned int fourcc,
+				   struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_vcodec_dev *dev = ctx->dev;
+	const struct mtk_vcodec_dec_pdata *pdata = dev->vdec_pdata;
+	int count_formats = *pdata->num_formats;
+	int count_framesizes = *pdata->num_framesizes;
+
+	switch (fourcc) {
+	case V4L2_PIX_FMT_H264_SLICE:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
+		mtk_video_formats[count_formats].num_planes = 1;
+
+		mtk_vdec_framesizes[count_framesizes].fourcc = fourcc;
+		mtk_vdec_framesizes[count_framesizes].stepwise = stepwise_fhd;
+		num_framesizes++;
+		break;
+	case V4L2_PIX_FMT_MM21:
+		mtk_video_formats[count_formats].fourcc = fourcc;
+		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
+		mtk_video_formats[count_formats].num_planes = 2;
+		break;
+	default:
+		mtk_v4l2_err("Can not add unsupported format type");
+		return;
+	}
+
+	num_formats++;
+	mtk_v4l2_debug(3, "num_formats: %d num_frames:%d dec_capability: 0x%x",
+		       count_formats, count_framesizes, ctx->dev->dec_capability);
+}
+
+static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
+{
+	int cap_format_count = 0, out_format_count = 0;
+
+	if (num_formats && num_framesizes)
+		return;
+
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MM21) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
+		cap_format_count++;
+	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
+		out_format_count++;
+	}
+
+	if (cap_format_count)
+		default_cap_format = mtk_video_formats[cap_format_count - 1];
+	if (out_format_count)
+		default_out_format =
+			mtk_video_formats[cap_format_count + out_format_count - 1];
+}
+
 static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 {
 	struct vb2_queue *src_vq;
@@ -360,6 +406,11 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
 		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
 
+	if (!ctx->dev->vdec_pdata->is_subdev_supported)
+		ctx->dev->dec_capability |=
+			MTK_VDEC_FORMAT_H264_SLICE | MTK_VDEC_FORMAT_MM21;
+	mtk_vcodec_get_supported_formats(ctx);
+
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
 	src_vq->requires_requests = true;
@@ -393,11 +444,11 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
@@ -413,11 +464,11 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
 	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
 	.vdec_formats = mtk_video_formats,
-	.num_formats = NUM_FORMATS,
-	.default_out_fmt = &mtk_video_formats[DEFAULT_OUT_FMT_IDX],
-	.default_cap_fmt = &mtk_video_formats[DEFAULT_CAP_FMT_IDX],
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
 	.vdec_framesizes = mtk_vdec_framesizes,
-	.num_framesizes = NUM_SUPPORTED_FRAMESIZE,
+	.num_framesizes = &num_framesizes,
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e0b7d2fda632..13c12de85edf 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -347,6 +347,15 @@ enum mtk_vdec_hw_arch {
 	MTK_VDEC_LAT_SINGLE_CORE,
 };
 
+/*
+ * struct mtk_vdec_format_types - Structure used to get supported
+ *		  format types according to decoder capability
+ */
+enum mtk_vdec_format_types {
+	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+};
+
 /**
  * struct mtk_vcodec_dec_pdata - compatible data for each IC
  * @init_vdec_params: init vdec params
@@ -382,12 +391,12 @@ struct mtk_vcodec_dec_pdata {
 	struct vb2_ops *vdec_vb2_ops;
 
 	const struct mtk_video_fmt *vdec_formats;
-	const int num_formats;
+	const int *num_formats;
 	const struct mtk_video_fmt *default_out_fmt;
 	const struct mtk_video_fmt *default_cap_fmt;
 
 	const struct mtk_codec_framesizes *vdec_framesizes;
-	const int num_framesizes;
+	const int *num_framesizes;
 
 	enum mtk_vdec_hw_arch hw_arch;
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:04 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:04 +0800
Subject: [PATCH v6,
 03/15] media: mtk-vcodec: get capture queue buffer size from scp
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-4-yunfei.dong@mediatek.com>

Different capture buffer format has different buffer size, need to get
real buffer size according to buffer type from scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/vdec_ipi_msg.h  | 36 ++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   | 49 +++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_vpu_if.h   | 15 ++++++
 3 files changed, 100 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
index bf54d6d9a857..47070be2a991 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_ipi_msg.h
@@ -20,6 +20,7 @@ enum vdec_ipi_msgid {
 	AP_IPIMSG_DEC_RESET = 0xA004,
 	AP_IPIMSG_DEC_CORE = 0xA005,
 	AP_IPIMSG_DEC_CORE_END = 0xA006,
+	AP_IPIMSG_DEC_GET_PARAM = 0xA007,
 
 	VPU_IPIMSG_DEC_INIT_ACK = 0xB000,
 	VPU_IPIMSG_DEC_START_ACK = 0xB001,
@@ -28,6 +29,7 @@ enum vdec_ipi_msgid {
 	VPU_IPIMSG_DEC_RESET_ACK = 0xB004,
 	VPU_IPIMSG_DEC_CORE_ACK = 0xB005,
 	VPU_IPIMSG_DEC_CORE_END_ACK = 0xB006,
+	VPU_IPIMSG_DEC_GET_PARAM_ACK = 0xB007,
 };
 
 /**
@@ -114,4 +116,38 @@ struct vdec_vpu_ipi_init_ack {
 	uint32_t inst_id;
 };
 
+/**
+ * struct vdec_ap_ipi_get_param - for AP_IPIMSG_DEC_GET_PARAM
+ * @msg_id	: AP_IPIMSG_DEC_GET_PARAM
+ * @inst_id     : instance ID. Used if the ABI version >= 2.
+ * @data	: picture information
+ * @param_type	: get param type
+ * @codec_type	: Codec fourcc
+ */
+struct vdec_ap_ipi_get_param {
+	u32 msg_id;
+	u32 inst_id;
+	u32 data[4];
+	u32 param_type;
+	u32 codec_type;
+};
+
+/**
+ * struct vdec_vpu_ipi_get_param_ack - for VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @msg_id	: VPU_IPIMSG_DEC_GET_PARAM_ACK
+ * @status	: VPU execution result
+ * @ap_inst_addr	: AP vcodec_vpu_inst instance address
+ * @data     : picture information from SCP.
+ * @param_type	: get param type
+ * @reserved : reserved param
+ */
+struct vdec_vpu_ipi_get_param_ack {
+	u32 msg_id;
+	s32 status;
+	u64 ap_inst_addr;
+	u32 data[4];
+	u32 param_type;
+	u32 reserved;
+};
+
 #endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 7210061c772f..35f4d5583084 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -6,6 +6,7 @@
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_util.h"
+#include "vdec_drv_if.h"
 #include "vdec_ipi_msg.h"
 #include "vdec_vpu_if.h"
 #include "mtk_vcodec_fw.h"
@@ -54,6 +55,26 @@ static void handle_init_ack_msg(const struct vdec_vpu_ipi_init_ack *msg)
 	}
 }
 
+static void handle_get_param_msg_ack(const struct vdec_vpu_ipi_get_param_ack *msg)
+{
+	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
+					(unsigned long)msg->ap_inst_addr;
+
+	mtk_vcodec_debug(vpu, "+ ap_inst_addr = 0x%llx", msg->ap_inst_addr);
+
+	/* param_type is enum vdec_get_param_type */
+	switch (msg->param_type) {
+	case GET_PARAM_PIC_INFO:
+		vpu->fb_sz[0] = msg->data[0];
+		vpu->fb_sz[1] = msg->data[1];
+		break;
+	default:
+		mtk_vcodec_err(vpu, "invalid get param type=%d", msg->param_type);
+		vpu->failure = 1;
+		break;
+	}
+}
+
 /*
  * vpu_dec_ipi_handler - Handler for VPU ipi message.
  *
@@ -89,6 +110,9 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 		case VPU_IPIMSG_DEC_CORE_END_ACK:
 			break;
 
+		case VPU_IPIMSG_DEC_GET_PARAM_ACK:
+			handle_get_param_msg_ack(data);
+			break;
 		default:
 			mtk_vcodec_err(vpu, "invalid msg=%X", msg->msg_id);
 			break;
@@ -217,6 +241,31 @@ int vpu_dec_start(struct vdec_vpu_inst *vpu, uint32_t *data, unsigned int len)
 	return err;
 }
 
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+		      unsigned int len, unsigned int param_type)
+{
+	struct vdec_ap_ipi_get_param msg;
+	int err;
+
+	mtk_vcodec_debug_enter(vpu);
+
+	if (len > ARRAY_SIZE(msg.data)) {
+		mtk_vcodec_err(vpu, "invalid len = %d\n", len);
+		return -EINVAL;
+	}
+
+	memset(&msg, 0, sizeof(msg));
+	msg.msg_id = AP_IPIMSG_DEC_GET_PARAM;
+	msg.inst_id = vpu->inst_id;
+	memcpy(msg.data, data, sizeof(unsigned int) * len);
+	msg.param_type = param_type;
+	msg.codec_type = vpu->codec_type;
+
+	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
+	mtk_vcodec_debug(vpu, "- ret=%d", err);
+	return err;
+}
+
 int vpu_dec_core(struct vdec_vpu_inst *vpu)
 {
 	return vcodec_send_ap_ipi(vpu, AP_IPIMSG_DEC_CORE);
diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
index 4cb3c7f5a3ad..d1feba41dd39 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.h
@@ -28,6 +28,8 @@ struct mtk_vcodec_ctx;
  * @wq          : wait queue to wait VPU message ack
  * @handler     : ipi handler for each decoder
  * @codec_type     : use codec type to separate different codecs
+ * @capture_type    : used capture type to separate different capture format
+ * @fb_sz  : frame buffer size of each plane
  */
 struct vdec_vpu_inst {
 	int id;
@@ -42,6 +44,8 @@ struct vdec_vpu_inst {
 	wait_queue_head_t wq;
 	mtk_vcodec_ipi_handler handler;
 	unsigned int codec_type;
+	unsigned int capture_type;
+	unsigned int fb_sz[2];
 };
 
 /**
@@ -104,4 +108,15 @@ int vpu_dec_core(struct vdec_vpu_inst *vpu);
  */
 int vpu_dec_core_end(struct vdec_vpu_inst *vpu);
 
+/**
+ * vpu_dec_get_param - get param from scp
+ *
+ * @vpu : instance for vdec_vpu_inst
+ * @data: meta data to pass bitstream info to VPU decoder
+ * @len : meta data length
+ * @param_type : get param type
+ */
+int vpu_dec_get_param(struct vdec_vpu_inst *vpu, uint32_t *data,
+		      unsigned int len, unsigned int param_type);
+
 #endif
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:07 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:07 +0800
Subject: [PATCH v6,
 06/15] media: mtk-vcodec: Refactor get and put capture buffer flow
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-7-yunfei.dong@mediatek.com>

For lat and core decode in parallel, need to get capture buffer
when core start to decode and put capture buffer to display
list when core decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 121 ++++++++++++------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +-
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  16 ++-
 3 files changed, 102 insertions(+), 40 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 23a154c4e321..6d481410bf89 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -108,37 +108,87 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
 
 #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
 
-static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
-					       struct vdec_fb *fb)
+static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
+					   struct mtk_vcodec_mem *bs, int error)
 {
-	struct mtk_video_dec_buf *vdec_frame_buf =
-		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
-	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
-	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	struct mtk_video_dec_buf *out_buf;
+	struct vb2_v4l2_buffer *vb;
 
-	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
-	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		unsigned int cap_c_size =
-			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+	if (!bs) {
+		mtk_v4l2_err("Free bitstream buffer fail.");
+		return;
+	}
+	out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	vb = &out_buf->m2m_buf.vb;
 
-		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+	mtk_v4l2_debug(2, "Free bitsteam buffer id = %d to done_list",
+		       vb->vb2_buf.index);
+
+	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
+	if (error) {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+		if (error == -EIO)
+			out_buf->error = true;
+	} else {
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
 	}
 }
 
-static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
-					   struct vb2_v4l2_buffer *vb2_v4l2)
+static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx,
+					   struct vdec_fb *fb, int error)
 {
-	struct mtk_video_dec_buf *framebuf =
-		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
-	struct vdec_fb *pfb = &framebuf->frame_buffer;
-	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
+	struct mtk_video_dec_buf *vdec_frame_buf;
+	struct vb2_v4l2_buffer *vb;
+	unsigned int cap_y_size, cap_c_size;
+
+	if (!fb) {
+		mtk_v4l2_err("Free frame buffer fail.");
+		return;
+	}
+	vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf,
+				      frame_buffer);
+	vb = &vdec_frame_buf->m2m_buf.vb;
+
+	cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
+	cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
+
+	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
 
-	pfb->base_y.va = NULL;
+	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
+
+	mtk_v4l2_debug(2, "Free frame buffer id = %d to done_list",
+		       vb->vb2_buf.index);
+	if (error)
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
+	else
+		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
+}
+
+static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
+{
+	struct mtk_video_dec_buf *framebuf;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vb2_buffer *dst_buf;
+	struct vdec_fb *pfb;
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	if (!vb2_v4l2) {
+		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
+		return NULL;
+	}
+
+	dst_buf = &vb2_v4l2->vb2_buf;
+	framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
+
+	pfb = &framebuf->frame_buffer;
+	pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
 	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
 	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
 
 	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-		pfb->base_c.va = NULL;
+		pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
 		pfb->base_c.dma_addr =
 			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
 		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
@@ -162,12 +212,11 @@ static void mtk_vdec_worker(struct work_struct *work)
 	struct mtk_vcodec_ctx *ctx =
 		container_of(work, struct mtk_vcodec_ctx, decode_work);
 	struct mtk_vcodec_dev *dev = ctx->dev;
-	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
+	struct vb2_v4l2_buffer *vb2_v4l2_src;
 	struct vb2_buffer *vb2_src;
 	struct mtk_vcodec_mem *bs_src;
 	struct mtk_video_dec_buf *dec_buf_src;
 	struct media_request *src_buf_req;
-	struct vdec_fb *dst_buf;
 	bool res_chg = false;
 	int ret;
 
@@ -178,13 +227,6 @@ static void mtk_vdec_worker(struct work_struct *work)
 		return;
 	}
 
-	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	if (!vb2_v4l2_dst) {
-		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
-		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
-		return;
-	}
-
 	vb2_src = &vb2_v4l2_src->vb2_buf;
 	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
 				   m2m_buf.vb);
@@ -193,9 +235,15 @@ static void mtk_vdec_worker(struct work_struct *work)
 	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
 		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
 
-	bs_src->va = NULL;
+	bs_src->va = vb2_plane_vaddr(vb2_src, 0);
 	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
 	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
+	if (!bs_src->va) {
+		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
+		mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id,
+			     vb2_src->index);
+		return;
+	}
 
 	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
 		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
@@ -206,9 +254,7 @@ static void mtk_vdec_worker(struct work_struct *work)
 	else
 		mtk_v4l2_err("vb2 buffer media request is NULL");
 
-	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
-	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);
-	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
+	ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
 	if (ret) {
 		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
 			     ctx->id, vb2_src->index, bs_src->size,
@@ -220,12 +266,9 @@ static void mtk_vdec_worker(struct work_struct *work)
 		}
 	}
 
-	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
-
-	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
-					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
-
+	mtk_vdec_stateless_out_to_done(ctx, bs_src, ret);
 	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
+	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
 }
 
 static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
@@ -358,6 +401,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = false,
 	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
 };
@@ -376,6 +421,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.uses_stateless_api = true,
 	.worker = mtk_vdec_worker,
 	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
 	.is_subdev_supported = true,
 	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 2d1d878692ca..e0b7d2fda632 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,7 +353,8 @@ enum mtk_vdec_hw_arch {
  * @ctrls_setup: init vcodec dec ctrls
  * @worker: worker to start a decode job
  * @flush_decoder: function that flushes the decoder
- *
+ * @get_cap_buffer: get capture buffer from capture queue
+ * @cap_to_disp: put capture buffer to disp list
  * @vdec_vb2_ops: struct vb2_ops
  *
  * @vdec_formats: supported video decoder formats
@@ -375,6 +376,8 @@ struct mtk_vcodec_dec_pdata {
 	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
 	void (*worker)(struct work_struct *work);
 	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
+	struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
+	void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, struct vdec_fb *fb, int error);
 
 	struct vb2_ops *vdec_vb2_ops;
 
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 43542de11e9c..36f3dc1fbe3b 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -670,32 +670,42 @@ static void vdec_h264_slice_deinit(void *h_vdec)
 }
 
 static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
-				  struct vdec_fb *fb, bool *res_chg)
+				  struct vdec_fb *unused, bool *res_chg)
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
 		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	struct mtk_video_dec_buf *dst_buf_info;
+	struct vdec_fb *fb;
 	u32 data[2];
 	u64 y_fb_dma;
 	u64 c_fb_dma;
 	int err;
 
+	inst->num_nalu++;
 	/* bs NULL means flush decoder */
 	if (!bs)
 		return vpu_dec_reset(vpu);
 
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
 	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
 	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
 
 	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
-			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
+			 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
 
 	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
 	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
 	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
 	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
 
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &dst_buf_info->m2m_buf.vb, true);
 	get_vdec_decode_parameters(inst);
 	data[0] = bs->size;
 	/*
@@ -734,6 +744,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
 	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
+
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, 0);
 	return 0;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:10 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:10 +0800
Subject: [PATCH v6, 09/15] media: mtk-vcodec: disable vp8 4K capability
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-10-yunfei.dong@mediatek.com>

For vp8 not support 4K, need to disable it.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index bae43938ee37..ba188d16f0fb 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -532,7 +532,8 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 		fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
 		fsize->stepwise = dec_pdata->vdec_framesizes[i].stepwise;
 		if (!(ctx->dev->dec_capability &
-				VCODEC_CAPABILITY_4K_DISABLED)) {
+				VCODEC_CAPABILITY_4K_DISABLED) &&
+				fsize->pixel_format != V4L2_PIX_FMT_VP8_FRAME) {
 			mtk_v4l2_debug(3, "4K is enabled");
 			fsize->stepwise.max_width =
 					VCODEC_DEC_4K_CODED_WIDTH;
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:05 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:05 +0800
Subject: [PATCH v6,
 04/15] media: mtk-vcodec: Read max resolution from dec_capability
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-5-yunfei.dong@mediatek.com>

Supported max resolution for different platforms are not the same: 2K
or 4K, getting it according to dec_capability.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 29 +++++++++++--------
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |  4 +++
 2 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 130ecef2e766..304f5afbd419 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -152,13 +152,15 @@ void mtk_vcodec_dec_set_default_params(struct mtk_vcodec_ctx *ctx)
 	q_data->coded_height = DFT_CFG_HEIGHT;
 	q_data->fmt = ctx->dev->vdec_pdata->default_cap_fmt;
 	q_data->field = V4L2_FIELD_NONE;
+	ctx->max_width = MTK_VDEC_MAX_W;
+	ctx->max_height = MTK_VDEC_MAX_H;
 
 	v4l_bound_align_image(&q_data->coded_width,
 				MTK_VDEC_MIN_W,
-				MTK_VDEC_MAX_W, 4,
+				ctx->max_width, 4,
 				&q_data->coded_height,
 				MTK_VDEC_MIN_H,
-				MTK_VDEC_MAX_H, 5, 6);
+				ctx->max_height, 5, 6);
 
 	q_data->sizeimage[0] = q_data->coded_width * q_data->coded_height;
 	q_data->bytesperline[0] = q_data->coded_width;
@@ -217,7 +219,7 @@ static int vidioc_vdec_subscribe_evt(struct v4l2_fh *fh,
 	}
 }
 
-static int vidioc_try_fmt(struct v4l2_format *f,
+static int vidioc_try_fmt(struct mtk_vcodec_ctx *ctx, struct v4l2_format *f,
 			  const struct mtk_video_fmt *fmt)
 {
 	struct v4l2_pix_format_mplane *pix_fmt_mp = &f->fmt.pix_mp;
@@ -225,9 +227,9 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 	pix_fmt_mp->field = V4L2_FIELD_NONE;
 
 	pix_fmt_mp->width =
-		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, MTK_VDEC_MAX_W);
+		clamp(pix_fmt_mp->width, MTK_VDEC_MIN_W, ctx->max_width);
 	pix_fmt_mp->height =
-		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, MTK_VDEC_MAX_H);
+		clamp(pix_fmt_mp->height, MTK_VDEC_MIN_H, ctx->max_height);
 
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		pix_fmt_mp->num_planes = 1;
@@ -245,16 +247,16 @@ static int vidioc_try_fmt(struct v4l2_format *f,
 		tmp_h = pix_fmt_mp->height;
 		v4l_bound_align_image(&pix_fmt_mp->width,
 					MTK_VDEC_MIN_W,
-					MTK_VDEC_MAX_W, 6,
+					ctx->max_width, 6,
 					&pix_fmt_mp->height,
 					MTK_VDEC_MIN_H,
-					MTK_VDEC_MAX_H, 6, 9);
+					ctx->max_height, 6, 9);
 
 		if (pix_fmt_mp->width < tmp_w &&
-			(pix_fmt_mp->width + 64) <= MTK_VDEC_MAX_W)
+			(pix_fmt_mp->width + 64) <= ctx->max_width)
 			pix_fmt_mp->width += 64;
 		if (pix_fmt_mp->height < tmp_h &&
-			(pix_fmt_mp->height + 64) <= MTK_VDEC_MAX_H)
+			(pix_fmt_mp->height + 64) <= ctx->max_height)
 			pix_fmt_mp->height += 64;
 
 		mtk_v4l2_debug(0,
@@ -294,7 +296,7 @@ static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
 		fmt = mtk_vdec_find_format(f, dec_pdata);
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
@@ -317,7 +319,7 @@ static int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv,
 		return -EINVAL;
 	}
 
-	return vidioc_try_fmt(f, fmt);
+	return vidioc_try_fmt(ctx, f, fmt);
 }
 
 static int vidioc_vdec_g_selection(struct file *file, void *priv,
@@ -445,7 +447,7 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		return -EINVAL;
 
 	q_data->fmt = fmt;
-	vidioc_try_fmt(f, q_data->fmt);
+	vidioc_try_fmt(ctx, f, q_data->fmt);
 	if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
 		q_data->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage;
 		q_data->coded_width = pix_mp->width;
@@ -545,6 +547,9 @@ static int vidioc_enum_framesizes(struct file *file, void *priv,
 				fsize->stepwise.min_height,
 				fsize->stepwise.max_height,
 				fsize->stepwise.step_height);
+
+		ctx->max_width = fsize->stepwise.max_width;
+		ctx->max_height = fsize->stepwise.max_height;
 		return 0;
 	}
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 5056abe3d2be..2d1d878692ca 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -287,6 +287,8 @@ struct vdec_pic_info {
  *	  mtk_video_dec_buf.
  * @hw_id: hardware index used to identify different hardware.
  *
+ * @max_width: hardware supported max width
+ * @max_height: hardware supported max height
  * @msg_queue: msg queue used to store lat buffer information.
  */
 struct mtk_vcodec_ctx {
@@ -332,6 +334,8 @@ struct mtk_vcodec_ctx {
 	struct mutex lock;
 	int hw_id;
 
+	unsigned int max_width;
+	unsigned int max_height;
 	struct vdec_msg_queue msg_queue;
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:02 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:02 +0800
Subject: [PATCH v6,
 01/15] media: mtk-vcodec: Add vdec enable/disable hardware helpers
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-2-yunfei.dong@mediatek.com>

Lock, power and clock are highly coupled operations. Adds vdec
enable/disable hardware helpers and uses them.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Tzung-Bi Shih<tzungbi at google.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   5 -
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 168 +++++++++++-------
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.h   |   6 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |  20 +--
 .../platform/mtk-vcodec/vdec_msg_queue.c      |   2 +
 5 files changed, 117 insertions(+), 84 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 86b639d82be8..6b52eaeedafa 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -195,9 +195,6 @@ static int fops_vcodec_open(struct file *file)
 	mtk_vcodec_dec_set_default_params(ctx);
 
 	if (v4l2_fh_is_singular(&ctx->fh)) {
-		ret = mtk_vcodec_dec_pw_on(dev, MTK_VDEC_LAT0);
-		if (ret < 0)
-			goto err_load_fw;
 		/*
 		 * Does nothing if firmware was already loaded.
 		 */
@@ -254,8 +251,6 @@ static int fops_vcodec_release(struct file *file)
 	v4l2_m2m_ctx_release(ctx->m2m_ctx);
 	mtk_vcodec_dec_release(ctx);
 
-	if (v4l2_fh_is_singular(&ctx->fh))
-		mtk_vcodec_dec_pw_off(dev, MTK_VDEC_LAT0);
 	v4l2_fh_del(&ctx->fh);
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 44035a50e335..1581a1277473 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -79,74 +79,31 @@ int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_init_dec_clk);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static int mtk_vcodec_dec_pw_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return -EINVAL;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_resume_and_get fail %d", ret);
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_on);
 
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_pw_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	int ret;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-	} else {
-		pm = &vdec_dev->pm;
-	}
-
 	ret = pm_runtime_put_sync(pm->dev);
 	if (ret)
 		mtk_v4l2_err("pm_runtime_put_sync fail %d", ret);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_pw_off);
 
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_on(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int ret, i;
 
-	if (vdec_dev->vdec_pdata->is_subdev_supported) {
-		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
-			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		enable_irq(subdev_dev->dec_irq);
-	} else {
-		pm = &vdec_dev->pm;
-		enable_irq(vdec_dev->dec_irq);
-	}
-
 	dec_clk = &pm->vdec_clk;
 	for (i = 0; i < dec_clk->clk_num; i++) {
 		ret = clk_prepare_enable(dec_clk->clk_info[i].vcodec_clk);
@@ -168,31 +125,120 @@ void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
 	for (i -= 1; i >= 0; i--)
 		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_on);
 
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+static void mtk_vcodec_dec_clock_off(struct mtk_vcodec_pm *pm)
 {
-	struct mtk_vdec_hw_dev *subdev_dev;
-	struct mtk_vcodec_pm *pm;
 	struct mtk_vcodec_clk *dec_clk;
 	int i;
 
+	dec_clk = &pm->vdec_clk;
+	mtk_smi_larb_put(pm->larbvdec);
+	for (i = dec_clk->clk_num - 1; i >= 0; i--)
+		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+}
+
+static void mtk_vcodec_dec_enable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
 	if (vdec_dev->vdec_pdata->is_subdev_supported) {
 		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
-		if (!subdev_dev) {
+		if (subdev_dev)
+			enable_irq(subdev_dev->dec_irq);
+		else
+			mtk_v4l2_err("Failed to get hw dev\n");
+	} else {
+		enable_irq(vdec_dev->dec_irq);
+	}
+}
+
+static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			disable_irq(subdev_dev->dec_irq);
+		else
 			mtk_v4l2_err("Failed to get hw dev\n");
-			return;
-		}
-		pm = &subdev_dev->pm;
-		disable_irq(subdev_dev->dec_irq);
 	} else {
-		pm = &vdec_dev->pm;
 		disable_irq(vdec_dev->dec_irq);
 	}
+}
 
-	dec_clk = &pm->vdec_clk;
-	mtk_smi_larb_put(pm->larbvdec);
-	for (i = dec_clk->clk_num - 1; i >= 0; i--)
-		clk_disable_unprepare(dec_clk->clk_info[i].vcodec_clk);
+static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
+						   int hw_idx)
+{
+	struct mtk_vdec_hw_dev *subdev_dev;
+
+	if (!test_bit(hw_idx, vdec_dev->subdev_bitmap))
+		return NULL;
+
+	if (vdec_dev->vdec_pdata->is_subdev_supported) {
+		subdev_dev = mtk_vcodec_get_hw_dev(vdec_dev, hw_idx);
+		if (subdev_dev)
+			return &subdev_dev->pm;
+
+		mtk_v4l2_err("Failed to get hw dev\n");
+		return NULL;
+	}
+
+	return &vdec_dev->pm;
+}
+
+static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
+					int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_pw_on(pm);
+		mtk_vcodec_dec_clock_on(pm);
+	}
+}
+
+static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
+					 int hw_idx)
+{
+	struct mtk_vcodec_pm *pm;
+
+	pm = mtk_vcodec_dec_get_pm(vdec_dev, hw_idx);
+	if (pm) {
+		mtk_vcodec_dec_clock_off(pm);
+		mtk_vcodec_dec_pw_off(pm);
+	}
+}
+
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mutex_lock(&ctx->dev->dec_mutex[hw_idx]);
+
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+	    hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_on(ctx->dev, MTK_VDEC_LAT0);
+	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+}
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
+
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
+{
+	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
+
+	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
+	if (IS_VDEC_LAT_ARCH(ctx->dev->vdec_pdata->hw_arch) &&
+	    hw_idx == MTK_VDEC_CORE)
+		mtk_vcodec_dec_child_dev_off(ctx->dev, MTK_VDEC_LAT0);
+
+	mutex_unlock(&ctx->dev->dec_mutex[hw_idx]);
 }
-EXPORT_SYMBOL_GPL(mtk_vcodec_dec_clock_off);
+EXPORT_SYMBOL_GPL(mtk_vcodec_dec_disable_hardware);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
index 3cc721bbfaf6..dbcf3cabe6f3 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.h
@@ -11,9 +11,7 @@
 
 int mtk_vcodec_init_dec_clk(struct platform_device *pdev, struct mtk_vcodec_pm *pm);
 
-int mtk_vcodec_dec_pw_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_pw_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_on(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
-void mtk_vcodec_dec_clock_off(struct mtk_vcodec_dev *vdec_dev, int hw_idx);
+void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
+void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx);
 
 #endif /* _MTK_VCODEC_DEC_PM_H_ */
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 05a5b240e906..c93dd0ea3537 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -38,11 +38,9 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		return -EINVAL;
 	}
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ret = ctx->dec_if->init(ctx);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -70,15 +68,11 @@ int vdec_if_decode(struct mtk_vcodec_ctx *ctx, struct mtk_vcodec_mem *bs,
 	if (!ctx->drv_handle)
 		return -EIO;
 
-	mtk_vdec_lock(ctx);
-
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, ctx, ctx->hw_id);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
 	ret = ctx->dec_if->decode(ctx->drv_handle, bs, fb, res_chg);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
 	mtk_vcodec_set_curr_ctx(ctx->dev, NULL, ctx->hw_id);
-
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	return ret;
 }
@@ -103,11 +97,9 @@ void vdec_if_deinit(struct mtk_vcodec_ctx *ctx)
 	if (!ctx->drv_handle)
 		return;
 
-	mtk_vdec_lock(ctx);
-	mtk_vcodec_dec_clock_on(ctx->dev, ctx->hw_id);
+	mtk_vcodec_dec_enable_hardware(ctx, ctx->hw_id);
 	ctx->dec_if->deinit(ctx->drv_handle);
-	mtk_vcodec_dec_clock_off(ctx->dev, ctx->hw_id);
-	mtk_vdec_unlock(ctx);
+	mtk_vcodec_dec_disable_hardware(ctx, ctx->hw_id);
 
 	ctx->drv_handle = NULL;
 }
diff --git a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
index 4b062a8128b4..ae500980ad45 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_msg_queue.c
@@ -212,11 +212,13 @@ static void vdec_msg_queue_core_work(struct work_struct *work)
 		return;
 
 	ctx = lat_buf->ctx;
+	mtk_vcodec_dec_enable_hardware(ctx, MTK_VDEC_CORE);
 	mtk_vcodec_set_curr_ctx(dev, ctx, MTK_VDEC_CORE);
 
 	lat_buf->core_decode(lat_buf);
 
 	mtk_vcodec_set_curr_ctx(dev, NULL, MTK_VDEC_CORE);
+	mtk_vcodec_dec_disable_hardware(ctx, MTK_VDEC_CORE);
 	vdec_msg_queue_qbuf(&ctx->msg_queue.lat_ctx, lat_buf);
 
 	if (!list_empty(&ctx->msg_queue.lat_ctx.ready_queue)) {
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:11 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:11 +0800
Subject: [PATCH v6, 10/15] media: mtk-vcodec: Fix v4l2-compliance fail
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-11-yunfei.dong@mediatek.com>

Need to use default pic info when get pic info fail.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index ba188d16f0fb..5a429ed83ed4 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -478,11 +478,14 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 		ctx->picinfo.pic_w = pix_mp->width;
 		ctx->picinfo.pic_h = pix_mp->height;
 
+		/*
+		 * If get pic info fail, need to use the default pic info params, or
+		 * v4l2-compliance will fail
+		 */
 		ret = vdec_if_get_param(ctx, GET_PARAM_PIC_INFO, &ctx->picinfo);
 		if (ret) {
 			mtk_v4l2_err("[%d]Error!! Get GET_PARAM_PICTURE_INFO Fail",
 				     ctx->id);
-			return -EINVAL;
 		}
 
 		ctx->last_decoded_picinfo = ctx->picinfo;
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:12 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:12 +0800
Subject: [PATCH v6, 11/15] media: mtk-vcodec: record capture queue format type
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-12-yunfei.dong@mediatek.com>

Capture queue format type is difference for different platform,
need to calculate capture buffer size according to capture queue
format type in scp.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c | 2 ++
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 5a429ed83ed4..6ad17e69e32d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -468,6 +468,8 @@ static int vidioc_vdec_s_fmt(struct file *file, void *priv,
 			}
 			ctx->state = MTK_STATE_INIT;
 		}
+	} else {
+		ctx->capture_fourcc = fmt->fourcc;
 	}
 
 	/*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index aa608ab0a247..fde79684106d 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -277,6 +277,7 @@ struct vdec_pic_info {
  *		     to be used with encoder and stateful decoder.
  * @is_flushing: set to true if flushing is in progress.
  * @current_codec: current set input codec, in V4L2 pixel format
+ * @capture_fourcc: capture queue type in V4L2 pixel format
  *
  * @colorspace: enum v4l2_colorspace; supplemental to pixelformat
  * @ycbcr_enc: enum v4l2_ycbcr_encoding, Y'CbCr encoding
@@ -324,6 +325,7 @@ struct mtk_vcodec_ctx {
 	bool is_flushing;
 
 	u32 current_codec;
+	u32 capture_fourcc;
 
 	enum v4l2_colorspace colorspace;
 	enum v4l2_ycbcr_encoding ycbcr_enc;
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:09 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:09 +0800
Subject: [PATCH v6, 08/15] media: mtk-vcodec: Add format to support MT21C
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-9-yunfei.dong@mediatek.com>

Needs to use mediatek compressed mode for mt8192 decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c   | 7 ++++++-
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h         | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index e51d935bd21d..9333e3418b98 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -81,7 +81,7 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[2];
+static struct mtk_video_fmt mtk_video_formats[3];
 static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
 
 static struct mtk_video_fmt default_out_format;
@@ -359,6 +359,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 		num_framesizes++;
 		break;
 	case V4L2_PIX_FMT_MM21:
+	case V4L2_PIX_FMT_MT21C:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_FRAME;
 		mtk_video_formats[count_formats].num_planes = 2;
@@ -384,6 +385,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_MM21, ctx);
 		cap_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_MT21C) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_MT21C, ctx);
+		cap_format_count++;
+	}
 	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_H264_SLICE) {
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 13c12de85edf..aa608ab0a247 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -353,6 +353,7 @@ enum mtk_vdec_hw_arch {
  */
 enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
+	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:06 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:06 +0800
Subject: [PATCH v6,
 05/15] media: mtk-vcodec: Call v4l2_m2m_set_dst_buffered() set
 capture buffer buffered
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-6-yunfei.dong@mediatek.com>

lat thread: output queue      \
                               -> lat hardware -> lat trans buffer
            lat trans buffer  /

core thread: capture queue     \
                                ->core hardware -> capture queue
             lat trans buffer  /

Lat and core work in different thread, setting capture buffer buffered.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 5aebf88f997b..23a154c4e321 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -314,6 +314,9 @@ static void mtk_init_vdec_params(struct mtk_vcodec_ctx *ctx)
 	src_vq = v4l2_m2m_get_vq(ctx->m2m_ctx,
 				 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
 
+	if (ctx->dev->vdec_pdata->hw_arch != MTK_VDEC_PURE_SINGLE_CORE)
+		v4l2_m2m_set_dst_buffered(ctx->m2m_ctx, 1);
+
 	/* Support request api for output plane */
 	src_vq->supports_requests = true;
 	src_vq->requires_requests = true;
-- 
2.25.1



From f.fainelli at gmail.com  Fri Jan 21 19:54:17 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Jan 2022 19:54:17 -0800
Subject: [PATCH 0/4] Broadcom STB PM PSCI extensions
Message-ID: <20220122035421.4086618-1-f.fainelli@gmail.com>

Hi all,

This patch series contains the Broadcom STB PSCI extensions which adds
some additional functions on top of the existing standard PSCI interface
which is the reason for having the driver implement a custom
suspend_ops.

These platforms have traditionally supported a mode that is akin to
ACPI's S2 with the CPU in WFI and all of the chip being clock gated
which is entered with "echo standby > /sys/power/state". Additional a
true suspend to DRAM as defined in ACPI by S3 is implemented with "echo
mem > /sys/power/state".

These platforms also may have an external Broadcom PMIC chip which can
cause the SoC to be powercycled assuming that we communicate that intent
via a vendor specific PSCI SYSTEM_RESET2.

Since it is desirable to get any new functionality added to the kernel
to be loadable as a module as part of shipping said products in a Google
Kernel Image (GKI) environment, we need to export a couple of symbols from
drivers/firmware/psci/psci.c.

Thanks for your feedback.

Florian Fainelli (4):
  firmware: psci: Export a couple of suspend symbols
  soc: bcm: brcmstb: Make legacy PM code depend on !ARM_PSCI_FW
  soc: bcm: brcmstb: Added support for PSCI system suspend operations
  Documentation: ABI: Document Broadcom STB PSCI firmware files

 .../ABI/testing/sysfs-firmware-brcmstb        |  16 +
 drivers/firmware/psci/psci.c                  |   9 +-
 drivers/soc/bcm/brcmstb/Kconfig               |   4 +-
 drivers/soc/bcm/brcmstb/pm/Makefile           |   3 +
 drivers/soc/bcm/brcmstb/pm/pm-psci.c          | 315 ++++++++++++++++++
 include/linux/psci.h                          |   2 +
 include/linux/soc/brcmstb/brcmstb-smccc.h     |  84 +++++
 7 files changed, 430 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-brcmstb
 create mode 100644 drivers/soc/bcm/brcmstb/pm/pm-psci.c
 create mode 100644 include/linux/soc/brcmstb/brcmstb-smccc.h

-- 
2.25.1



From f.fainelli at gmail.com  Fri Jan 21 19:54:18 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Jan 2022 19:54:18 -0800
Subject: [PATCH 1/4] firmware: psci: Export a couple of suspend symbols
In-Reply-To: <20220122035421.4086618-1-f.fainelli@gmail.com>
References: <20220122035421.4086618-1-f.fainelli@gmail.com>
Message-ID: <20220122035421.4086618-2-f.fainelli@gmail.com>

Export psci_system_suspend_enter() and psci_cpu_suspend_enter() for
the Broadcom STB PSCI extension to be usable and built as a loadable
module.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/firmware/psci/psci.c | 9 ++++++++-
 include/linux/psci.h         | 2 ++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c
index cfb448eabdaa..9a60e340c248 100644
--- a/drivers/firmware/psci/psci.c
+++ b/drivers/firmware/psci/psci.c
@@ -355,7 +355,13 @@ int psci_cpu_suspend_enter(u32 state)
 
 	return ret;
 }
+#else
+int psci_cpu_suspend_enter(u32 state)
+{
+	return -EOPNOTSUPP;
+}
 #endif
+EXPORT_SYMBOL_GPL(psci_cpu_suspend_enter);
 
 static int psci_system_suspend(unsigned long unused)
 {
@@ -365,10 +371,11 @@ static int psci_system_suspend(unsigned long unused)
 			      pa_cpu_resume, 0, 0);
 }
 
-static int psci_system_suspend_enter(suspend_state_t state)
+int psci_system_suspend_enter(suspend_state_t state)
 {
 	return cpu_suspend(0, psci_system_suspend);
 }
+EXPORT_SYMBOL_GPL(psci_system_suspend_enter);
 
 static const struct platform_suspend_ops psci_suspend_ops = {
 	.valid          = suspend_valid_only_mem,
diff --git a/include/linux/psci.h b/include/linux/psci.h
index 4ca0060a3fc4..ffeba6b08e10 100644
--- a/include/linux/psci.h
+++ b/include/linux/psci.h
@@ -9,6 +9,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/init.h>
+#include <linux/suspend.h>
 #include <linux/types.h>
 
 #define PSCI_POWER_STATE_TYPE_STANDBY		0
@@ -17,6 +18,7 @@
 bool psci_tos_resident_on(int cpu);
 
 int psci_cpu_suspend_enter(u32 state);
+int psci_system_suspend_enter(suspend_state_t state);
 bool psci_power_state_is_valid(u32 state);
 int psci_set_osi_mode(bool enable);
 bool psci_has_osi_support(void);
-- 
2.25.1



From f.fainelli at gmail.com  Fri Jan 21 19:54:19 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Jan 2022 19:54:19 -0800
Subject: [PATCH 2/4] soc: bcm: brcmstb: Make legacy PM code depend on
 !ARM_PSCI_FW
In-Reply-To: <20220122035421.4086618-1-f.fainelli@gmail.com>
References: <20220122035421.4086618-1-f.fainelli@gmail.com>
Message-ID: <20220122035421.4086618-3-f.fainelli@gmail.com>

On ARM 32-bit the legacy PM code would conflict with a PSCI based
implementation that we are going to introduce in subsequent commits.
Make PM_BRCMSTB depend on !ARM_PSCI_FW to exclude the two
implementations from each other.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/soc/bcm/brcmstb/pm/Makefile | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/bcm/brcmstb/pm/Makefile b/drivers/soc/bcm/brcmstb/pm/Makefile
index 8e10abb14f8b..86004458260c 100644
--- a/drivers/soc/bcm/brcmstb/pm/Makefile
+++ b/drivers/soc/bcm/brcmstb/pm/Makefile
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
+ifndef CONFIG_ARM_PSCI_FW
 obj-$(CONFIG_ARM)		+= s2-arm.o pm-arm.o
 AFLAGS_s2-arm.o			:= -march=armv7-a
+endif
 obj-$(CONFIG_BMIPS_GENERIC)	+= s2-mips.o s3-mips.o pm-mips.o
-- 
2.25.1



From f.fainelli at gmail.com  Fri Jan 21 19:54:20 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Jan 2022 19:54:20 -0800
Subject: [PATCH 3/4] soc: bcm: brcmstb: Added support for PSCI system suspend
 operations
In-Reply-To: <20220122035421.4086618-1-f.fainelli@gmail.com>
References: <20220122035421.4086618-1-f.fainelli@gmail.com>
Message-ID: <20220122035421.4086618-4-f.fainelli@gmail.com>

Add support for the Broadcom STB system suspend operations which
leverage the standard PSCI functions and uses the
psci_cpu_suspend_enter() operation to power off the system with or
without retention ("echo standby > /sys/power/state").

The system reset path also supports a special "powercycle" mode which
signals to the ARM Trusted Firmware that an external PMIC chip must
force the SoC into a power cycle.

As much as possible extensions were built using the SIP namespace rather
than the standard PSCI namespace, however compatibility with the
standard PSCI implementation is retained when CONFIG_BRCMSTB_PM is not
selected.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/soc/bcm/brcmstb/Kconfig           |   4 +-
 drivers/soc/bcm/brcmstb/pm/Makefile       |   1 +
 drivers/soc/bcm/brcmstb/pm/pm-psci.c      | 315 ++++++++++++++++++++++
 include/linux/soc/brcmstb/brcmstb-smccc.h |  84 ++++++
 4 files changed, 402 insertions(+), 2 deletions(-)
 create mode 100644 drivers/soc/bcm/brcmstb/pm/pm-psci.c
 create mode 100644 include/linux/soc/brcmstb/brcmstb-smccc.h

diff --git a/drivers/soc/bcm/brcmstb/Kconfig b/drivers/soc/bcm/brcmstb/Kconfig
index 38e476905d96..a2b31717096e 100644
--- a/drivers/soc/bcm/brcmstb/Kconfig
+++ b/drivers/soc/bcm/brcmstb/Kconfig
@@ -2,8 +2,8 @@
 if SOC_BRCMSTB
 
 config BRCMSTB_PM
-	bool "Support suspend/resume for STB platforms"
-	default y
+	tristate "Support suspend/resume for STB platforms"
+	default ARCH_BRCMSTB || BMIPS_GENERIC
 	depends on PM
 	depends on ARCH_BRCMSTB || BMIPS_GENERIC
 	select ARM_CPU_SUSPEND if ARM
diff --git a/drivers/soc/bcm/brcmstb/pm/Makefile b/drivers/soc/bcm/brcmstb/pm/Makefile
index 86004458260c..4ece53db8937 100644
--- a/drivers/soc/bcm/brcmstb/pm/Makefile
+++ b/drivers/soc/bcm/brcmstb/pm/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
+obj-$(CONFIG_BRCMSTB_PM)	+= pm-psci.o
 ifndef CONFIG_ARM_PSCI_FW
 obj-$(CONFIG_ARM)		+= s2-arm.o pm-arm.o
 AFLAGS_s2-arm.o			:= -march=armv7-a
diff --git a/drivers/soc/bcm/brcmstb/pm/pm-psci.c b/drivers/soc/bcm/brcmstb/pm/pm-psci.c
new file mode 100644
index 000000000000..7ba34d01c2fc
--- /dev/null
+++ b/drivers/soc/bcm/brcmstb/pm/pm-psci.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Broadcom STB PSCI based system wide PM support
+ *
+ * Copyright ? 2018-2022 Broadcom
+ */
+
+#define pr_fmt(fmt) "brcmstb-pm-psci: " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/arm-smccc.h>
+#include <linux/panic_notifier.h>
+#include <linux/psci.h>
+#include <linux/suspend.h>
+#include <linux/soc/brcmstb/brcmstb.h>
+#include <linux/soc/brcmstb/brcmstb-smccc.h>
+#include <linux/reboot.h>
+#include <linux/kobject.h>
+
+#include <uapi/linux/psci.h>
+
+#include <asm/suspend.h>
+#include <asm/system_misc.h>
+
+#include "aon_defs.h"
+
+static psci_fn *invoke_psci_fn;
+static bool brcmstb_psci_system_reset2_supported;
+static bool brcmstb_psci_system_suspend_supported;
+static bool brcmstb_psci_cpu_retention = true;
+
+static int brcmstb_psci_integ_region(unsigned long function_id,
+				     unsigned long base,
+				     unsigned long size)
+{
+	unsigned long end;
+
+	if (!size)
+		return -EINVAL;
+
+	end = DIV_ROUND_UP(base + size, SIP_MIN_REGION_SIZE);
+	base /= SIP_MIN_REGION_SIZE;
+	size = end - base;
+
+	return invoke_psci_fn(function_id, base, size, 0);
+}
+
+static int __maybe_unused brcmstb_psci_integ_region_set(unsigned long base,
+							unsigned long size)
+{
+	return brcmstb_psci_integ_region(SIP_FUNC_INTEG_REGION_SET, base, size);
+}
+
+static int __maybe_unused brcmstb_psci_integ_region_del(unsigned long base,
+							unsigned long size)
+{
+	return brcmstb_psci_integ_region(SIP_FUNC_INTEG_REGION_DEL, base, size);
+}
+
+static int brcmstb_psci_integ_region_reset_all(void)
+{
+	return invoke_psci_fn(SIP_FUNC_INTEG_REGION_RESET_ALL, 0, 0, 0);
+}
+
+static int brcmstb_psci_sys_reset(struct notifier_block *nb,
+				  unsigned long action, void *data)
+{
+	const char *cmd = data;
+	/*
+	 * reset_type[31] = 0 (architectural)
+	 * reset_type[30:0] = 0 (SYSTEM_WARM_RESET)
+	 * cookie = 0 (ignored by the implementation)
+	 */
+	uint32_t reboot_type = 0;
+
+	if ((action == REBOOT_COLD || action == REBOOT_WARM ||
+	    action == REBOOT_SOFT) &&
+	    brcmstb_psci_system_reset2_supported) {
+		if (cmd && !strcmp(cmd, "powercycle"))
+			reboot_type = BIT(31) | 1;
+		invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), reboot_type, 0, 0);
+	} else {
+		invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block brcmstb_psci_sys_reset_nb = {
+	.notifier_call	= brcmstb_psci_sys_reset,
+	.priority	= 128,
+};
+
+void brcmstb_psci_sys_poweroff(void)
+{
+	invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
+}
+
+static int psci_features(u32 psci_func_id)
+{
+	u32 features_func_id;
+
+	switch (ARM_SMCCC_OWNER_NUM(psci_func_id)) {
+	case ARM_SMCCC_OWNER_SIP:
+		features_func_id = SIP_FUNC_PSCI_FEATURES;
+		break;
+	case ARM_SMCCC_OWNER_STANDARD:
+		features_func_id = PSCI_1_0_FN_PSCI_FEATURES;
+		break;
+	default:
+		return PSCI_RET_NOT_SUPPORTED;
+	}
+
+	return invoke_psci_fn(features_func_id, psci_func_id, 0, 0);
+}
+
+static int brcmstb_psci_enter(suspend_state_t state)
+{
+	/* Request a SYSTEM level power state with retention */
+	u32 pstate = 2 << PSCI_0_2_POWER_STATE_AFFL_SHIFT |
+		     !brcmstb_psci_cpu_retention << PSCI_0_2_POWER_STATE_TYPE_SHIFT;
+	int ret = -EINVAL;
+
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		ret = psci_cpu_suspend_enter(pstate);
+		break;
+	case PM_SUSPEND_MEM:
+		ret = brcmstb_psci_system_suspend_supported ?
+			 psci_system_suspend_enter(state) : -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int brcmstb_psci_valid(suspend_state_t state)
+{
+	switch (state) {
+	case PM_SUSPEND_STANDBY:
+		return true;
+	case PM_SUSPEND_MEM:
+		return brcmstb_psci_system_suspend_supported;
+	default:
+		return false;
+	}
+}
+
+static const struct platform_suspend_ops brcmstb_psci_ops = {
+	.enter	= brcmstb_psci_enter,
+	.valid	= brcmstb_psci_valid,
+};
+
+static int brcmstb_psci_panic_notify(struct notifier_block *nb,
+				     unsigned long action, void *data)
+{
+	int ret;
+
+	ret = invoke_psci_fn(SIP_FUNC_PANIC_NOTIFY, BRCMSTB_PANIC_MAGIC, 0, 0);
+	if (ret != PSCI_RET_SUCCESS)
+		return NOTIFY_BAD;
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block brcmstb_psci_nb = {
+	.notifier_call = brcmstb_psci_panic_notify,
+};
+
+static ssize_t brcmstb_psci_version_show(struct kobject *kobj,
+					 struct kobj_attribute *attr,
+					 char *buf)
+{
+	struct arm_smccc_res res = { };
+	u32 version;
+
+	if (invoke_psci_fn == __invoke_psci_fn_hvc)
+		arm_smccc_hvc(SIP_FUNC_PSCI_BRCMSTB_VERSION,
+			      0, 0, 0, 0, 0, 0, 0, &res);
+	else
+		arm_smccc_smc(SIP_FUNC_PSCI_BRCMSTB_VERSION,
+			      0, 0, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != PSCI_RET_SUCCESS)
+		return -EOPNOTSUPP;
+
+	version = res.a1;
+
+	return sprintf(buf, "%d.%d.%d.%d\n",
+		       (version >> 24) & 0xff, (version >> 16) & 0xff,
+		       (version >> 8) & 0xff, version & 0xff);
+}
+
+static struct kobj_attribute brcmstb_psci_version_attr =
+	__ATTR(mon_version, 0400, brcmstb_psci_version_show, NULL);
+
+static ssize_t brcmstb_psci_cpu_retention_show(struct kobject *kobj,
+					       struct kobj_attribute *attr,
+					       char *buf)
+{
+	return sprintf(buf, "%d\n", brcmstb_psci_cpu_retention);
+}
+
+static ssize_t brcmstb_psci_cpu_retention_store(struct kobject *kobj,
+						struct kobj_attribute *attr,
+						const char *buf, size_t count)
+{
+	int ret, val;
+
+	ret = kstrtoint(buf, 10, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	brcmstb_psci_cpu_retention = !!val;
+
+	return count;
+}
+
+static struct kobj_attribute brcmstb_psci_cpu_retention_attr =
+	__ATTR(cpu_retention, 0644, brcmstb_psci_cpu_retention_show,
+	       brcmstb_psci_cpu_retention_store);
+
+static const struct attribute *brcmstb_psci_attributes[] = {
+	&brcmstb_psci_version_attr.attr,
+	&brcmstb_psci_cpu_retention_attr.attr,
+	NULL,
+};
+
+static int brcmstb_pm_psci_init(void)
+{
+	unsigned long funcs_id[] = {
+		PSCI_0_2_FN_SYSTEM_OFF,
+		SIP_FUNC_INTEG_REGION_SET,
+		SIP_FUNC_INTEG_REGION_DEL,
+		SIP_FUNC_INTEG_REGION_RESET_ALL,
+	};
+	struct arm_smccc_res res = { };
+	struct kobject *brcmstb_kobj;
+	unsigned int i;
+	int ret;
+
+	switch (arm_smccc_1_1_get_conduit()) {
+	case SMCCC_CONDUIT_HVC:
+		invoke_psci_fn = __invoke_psci_fn_hvc;
+		break;
+	case SMCCC_CONDUIT_SMC:
+		invoke_psci_fn = __invoke_psci_fn_smc;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* Check the revision of monitor */
+	if (invoke_psci_fn == __invoke_psci_fn_hvc)
+		arm_smccc_hvc(SIP_SVC_REVISION,
+			      0, 0, 0, 0, 0, 0, 0, &res);
+	else
+		arm_smccc_smc(SIP_SVC_REVISION,
+			      0, 0, 0, 0, 0, 0, 0, &res);
+
+	/* Test for our supported features */
+	for (i = 0; i < ARRAY_SIZE(funcs_id); i++) {
+		ret = psci_features(funcs_id[i]);
+		if (ret == PSCI_RET_NOT_SUPPORTED) {
+			pr_err("Firmware does not support function 0x%lx\n",
+			       funcs_id[i]);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	ret = psci_features(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2));
+	if (ret != PSCI_RET_NOT_SUPPORTED)
+		brcmstb_psci_system_reset2_supported = true;
+
+	ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
+	if (ret != PSCI_RET_NOT_SUPPORTED)
+		brcmstb_psci_system_suspend_supported = true;
+
+	ret = brcmstb_psci_integ_region_reset_all();
+	if (ret != PSCI_RET_SUCCESS) {
+		pr_err("Error resetting all integrity checking regions\n");
+		return -EIO;
+	}
+
+	if (res.a0 == SIP_REVISION_MAJOR && res.a1 < SIP_REVISION_MINOR) {
+		pr_info("Firmware is too old! Please update\n");
+		return -EOPNOTSUPP;
+	}
+
+	brcmstb_kobj = kobject_create_and_add("brcmstb", firmware_kobj);
+	if (brcmstb_kobj) {
+		ret = sysfs_create_files(brcmstb_kobj, brcmstb_psci_attributes);
+		if (ret)
+			return ret;
+	}
+
+	pm_power_off = brcmstb_psci_sys_poweroff;
+	register_restart_handler(&brcmstb_psci_sys_reset_nb);
+	suspend_set_ops(&brcmstb_psci_ops);
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &brcmstb_psci_nb);
+
+	pr_info("Using PSCI based system PM (full featured)\n");
+
+	return 0;
+}
+module_init(brcmstb_pm_psci_init);
+
+MODULE_AUTHOR("Broadcom");
+MODULE_DESCRIPTION("Broadcom STB PM PSCI operations");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/soc/brcmstb/brcmstb-smccc.h b/include/linux/soc/brcmstb/brcmstb-smccc.h
new file mode 100644
index 000000000000..2863e894e1c7
--- /dev/null
+++ b/include/linux/soc/brcmstb/brcmstb-smccc.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __BRCMSTB_SMCCC_H
+#define __BRCMSTB_SMCCC_H
+
+#include <linux/arm-smccc.h>
+#include <uapi/linux/psci.h>
+
+#ifdef CONFIG_64BIT
+#define PSCI_FN_NATIVE(version, name)   PSCI_##version##_FN64_##name
+#else
+#define PSCI_FN_NATIVE(version, name)   PSCI_##version##_FN_##name
+#endif
+
+/* Broadcom STB custom SIP function calls */
+#define SIP_FUNC_INTEG_REGION_SET	\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   0)
+#define SIP_FUNC_INTEG_REGION_DEL	\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   1)
+#define SIP_FUNC_INTEG_REGION_RESET_ALL	\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   2)
+#define SIP_FUNC_PANIC_NOTIFY		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   3)
+#define SIP_FUNC_PSCI_FEATURES		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   4)
+#define SIP_FUNC_PSCI_BRCMSTB_VERSION		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   5)
+
+#define SIP_SVC_REVISION		\
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
+			   IS_ENABLED(CONFIG_64BIT), \
+			   ARM_SMCCC_OWNER_SIP, \
+			   0xFF02)
+
+#define SIP_MIN_REGION_SIZE	4096
+#define SIP_REVISION_MAJOR	0
+#define SIP_REVISION_MINOR	2
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+				unsigned long, unsigned long);
+
+static inline unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
+						 unsigned long arg0,
+						 unsigned long arg1,
+						 unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+static inline unsigned long __invoke_psci_fn_smc(unsigned long function_id,
+						 unsigned long arg0,
+						 unsigned long arg1,
+						 unsigned long arg2)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+
+	return res.a0;
+}
+
+
+#endif /* __BRCMSTB_SMCCC_H */
-- 
2.25.1



From f.fainelli at gmail.com  Fri Jan 21 19:54:21 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 21 Jan 2022 19:54:21 -0800
Subject: [PATCH 4/4] Documentation: ABI: Document Broadcom STB PSCI firmware
 files
In-Reply-To: <20220122035421.4086618-1-f.fainelli@gmail.com>
References: <20220122035421.4086618-1-f.fainelli@gmail.com>
Message-ID: <20220122035421.4086618-5-f.fainelli@gmail.com>

Document the attributes created by the Broadcom STB PSCI firmware code
to allow retrieving the firmware version and the control of the CPU
retention upon system suspend entry.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 Documentation/ABI/testing/sysfs-firmware-brcmstb | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-brcmstb

diff --git a/Documentation/ABI/testing/sysfs-firmware-brcmstb b/Documentation/ABI/testing/sysfs-firmware-brcmstb
new file mode 100644
index 000000000000..5ebd8d0a34be
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-brcmstb
@@ -0,0 +1,16 @@
+What:		/sys/firmware/brcmstb/mon_version
+Date:		Jan 2022
+Contact:	Florian Fainelli <f.fainelli at gmail.com>
+Description:
+		Reports the ARM trusted firmware (monitor) version running on
+		the Broadcom STB platforms under the format:
+		A.B.C.D
+
+What:		/sys/firmware/brcmstb/cpu_retention
+Date:		Jan 2022
+Contact:	Florian Fainelli <f.fainelli at gmail.com>
+Description:
+		Allows the toggling of whether S2 standby should be entered
+		with (default) or without CPU retention.
+
+		Accepted values are 0 or 1.
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:14 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:14 +0800
Subject: [PATCH  v6,
 13/15] media: mtk-vcodec: support stateless H.264 decoding for mt8192
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-14-yunfei.dong@mediatek.com>

Adds h264 lat and core architecture driver for mt8192,
and the decode mode is frame based for stateless decoder.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 614 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   8 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 include/linux/remoteproc/mtk_scp.h            |   2 +
 5 files changed, 625 insertions(+), 1 deletion(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 3f41d748eee5..22edb1c86598 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -10,6 +10,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
+		vdec/vdec_h264_req_multi_if.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
new file mode 100644
index 000000000000..1567dbc63e95
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -0,0 +1,614 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+#include "vdec_h264_req_common.h"
+
+/**
+ * enum vdec_h264_core_dec_err_type  - core decode error type
+ * @TRANS_BUFFER_FULL : trans buffer is full
+ * @SLICE_HEADER_FULL : slice header buffer is full
+ */
+enum vdec_h264_core_dec_err_type {
+	TRANS_BUFFER_FULL = 1,
+	SLICE_HEADER_FULL,
+};
+
+/**
+ * struct vdec_h264_slice_lat_dec_param  - parameters for decode current frame
+ * @sps : h264 sps syntax parameters
+ * @pps : h264 pps syntax parameters
+ * @slice_header: h264 slice header syntax parameters
+ * @scaling_matrix : h264 scaling list parameters
+ * @decode_params : decoder parameters of each frame used for hardware decode
+ * @h264_dpb_info : dpb reference list
+ */
+struct vdec_h264_slice_lat_dec_param {
+	struct mtk_h264_sps_param sps;
+	struct mtk_h264_pps_param pps;
+	struct mtk_h264_slice_hd_param slice_header;
+	struct slice_api_h264_scaling_matrix scaling_matrix;
+	struct slice_api_h264_decode_param decode_params;
+	struct mtk_h264_dpb_info h264_dpb_info[V4L2_H264_NUM_DPB_ENTRIES];
+};
+
+/**
+ * struct vdec_h264_slice_info - decode information
+ * @nal_info    : nal info of current picture
+ * @timeout     : Decode timeout: 1 timeout, 0 no timeount
+ * @bs_buf_size : bitstream size
+ * @bs_buf_addr : bitstream buffer dma address
+ * @y_fb_dma    : Y frame buffer dma address
+ * @c_fb_dma    : C frame buffer dma address
+ * @vdec_fb_va  : VDEC frame buffer struct virtual address
+ * @crc         : Used to check whether hardware's status is right
+ */
+struct vdec_h264_slice_info {
+	u16 nal_info;
+	u16 timeout;
+	u32 bs_buf_size;
+	u64 bs_buf_addr;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	u64 vdec_fb_va;
+	u32 crc[8];
+};
+
+/**
+ * struct vdec_h264_slice_vsi - shared memory for decode information exchange
+ *        between VPU and Host. The memory is allocated by VPU then mapping to
+ *        Host in vdec_h264_slice_init() and freed in vdec_h264_slice_deinit()
+ *        by VPU. AP-W/R : AP is writer/reader on this item. VPU-W/R: VPU is
+ *        write/reader on this item.
+ * @wdma_err_addr       : wdma error dma address
+ * @wdma_start_addr     : wdma start dma address
+ * @wdma_end_addr       : wdma end dma address
+ * @slice_bc_start_addr : slice bc start dma address
+ * @slice_bc_end_addr   : slice bc end dma address
+ * @row_info_start_addr : row info start dma address
+ * @row_info_end_addr   : row info end dma address
+ * @trans_start         : trans start dma address
+ * @trans_end           : trans end dma address
+ * @wdma_end_addr_offset: wdma end address offset
+ *
+ * @mv_buf_dma          : HW working motion vector buffer
+ *                        dma address (AP-W, VPU-R)
+ * @dec                 : decode information (AP-R, VPU-W)
+ * @h264_slice_params   : decode parameters for hw used
+ */
+struct vdec_h264_slice_vsi {
+	/* LAT dec addr */
+	u64 wdma_err_addr;
+	u64 wdma_start_addr;
+	u64 wdma_end_addr;
+	u64 slice_bc_start_addr;
+	u64 slice_bc_end_addr;
+	u64 row_info_start_addr;
+	u64 row_info_end_addr;
+	u64 trans_start;
+	u64 trans_end;
+	u64 wdma_end_addr_offset;
+
+	u64 mv_buf_dma[H264_MAX_MV_NUM];
+	struct vdec_h264_slice_info dec;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+};
+
+/**
+ * struct vdec_h264_slice_share_info - shared information used to exchange
+ *                                     message between lat and core
+ * @sps	              : sequence header information from user space
+ * @dec_params        : decoder params from user space
+ * @h264_slice_params : decoder params used for hardware
+ * @trans_start       : trans start dma address
+ * @trans_end         : trans end dma address
+ * @nal_info          : nal info of current picture
+ */
+struct vdec_h264_slice_share_info {
+	struct v4l2_ctrl_h264_sps sps;
+	struct v4l2_ctrl_h264_decode_params dec_params;
+	struct vdec_h264_slice_lat_dec_param h264_slice_params;
+	u64 trans_start;
+	u64 trans_end;
+	u16 nal_info;
+};
+
+/**
+ * struct vdec_h264_slice_inst - h264 decoder instance
+ * @slice_dec_num        : how many picture be decoded
+ * @ctx                 : point to mtk_vcodec_ctx
+ * @pred_buf            : HW working predication buffer
+ * @mv_buf              : HW working motion vector buffer
+ * @vpu                 : VPU instance
+ * @vsi                 : vsi used for lat
+ * @vsi_core            : vsi used for core
+ *
+ * @resolution_changed  : resolution changed
+ * @realloc_mv_buf      : reallocate mv buffer
+ * @cap_num_planes      : number of capture queue plane
+ *
+ * @dpb : decoded picture buffer used to store reference buffer information
+ */
+struct vdec_h264_slice_inst {
+	unsigned int slice_dec_num;
+	struct mtk_vcodec_ctx *ctx;
+	struct mtk_vcodec_mem pred_buf;
+	struct mtk_vcodec_mem mv_buf[H264_MAX_MV_NUM];
+	struct vdec_vpu_inst vpu;
+	struct vdec_h264_slice_vsi *vsi;
+	struct vdec_h264_slice_vsi *vsi_core;
+
+	unsigned int resolution_changed;
+	unsigned int realloc_mv_buf;
+	unsigned int cap_num_planes;
+
+	struct v4l2_h264_dpb_entry dpb[16];
+};
+
+static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *inst,
+						  struct vdec_h264_slice_share_info *share_info)
+{
+	struct vdec_h264_slice_lat_dec_param *slice_param = &inst->vsi->h264_slice_params;
+	const struct v4l2_ctrl_h264_decode_params *dec_params;
+	const struct v4l2_ctrl_h264_scaling_matrix *src_matrix;
+	const struct v4l2_ctrl_h264_sps *sps;
+	const struct v4l2_ctrl_h264_pps *pps;
+
+	dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	if (IS_ERR(dec_params))
+		return PTR_ERR(dec_params);
+
+	src_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	if (IS_ERR(src_matrix))
+		return PTR_ERR(src_matrix);
+
+	sps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+	if (IS_ERR(sps))
+		return PTR_ERR(sps);
+
+	pps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+	if (IS_ERR(pps))
+		return PTR_ERR(pps);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, src_matrix);
+
+	memcpy(&share_info->sps, sps, sizeof(*sps));
+	memcpy(&share_info->dec_params, dec_params, sizeof(*dec_params));
+
+	return 0;
+}
+
+static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *inst,
+						struct vdec_h264_slice_lat_dec_param *slice_param,
+						struct vdec_h264_slice_share_info *share_info)
+{
+	struct v4l2_ctrl_h264_decode_params *dec_params = &share_info->dec_params;
+	struct v4l2_ctrl_h264_sps *sps = &share_info->sps;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params,
+					 inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+				    slice_param->h264_dpb_info);
+
+	mtk_v4l2_debug(3, "cur poc = %d\n", dec_params->bottom_field_order_cnt);
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
+				       inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+
+	/* Adapt the built lists to the firmware's expectations */
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+}
+
+static int vdec_h264_slice_alloc_mv_buf(struct vdec_h264_slice_inst *inst,
+					struct vdec_pic_info *pic)
+{
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
+	struct mtk_vcodec_mem *mem;
+	int i, err;
+
+	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+		mem->size = buf_sz;
+		err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+		if (err) {
+			mtk_vcodec_err(inst, "failed to allocate mv buf");
+			return err;
+		}
+	}
+
+	return 0;
+}
+
+static void vdec_h264_slice_free_mv_buf(struct vdec_h264_slice_inst *inst)
+{
+	int i;
+	struct mtk_vcodec_mem *mem;
+
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		if (mem->va)
+			mtk_vcodec_mem_free(inst->ctx, mem);
+	}
+}
+
+static void vdec_h264_slice_get_pic_info(struct vdec_h264_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+	inst->cap_num_planes =
+		ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "Y/C(%d, %d)", ctx->picinfo.fb_sz[0],
+			 ctx->picinfo.fb_sz[1]);
+
+	if (ctx->last_decoded_picinfo.pic_w != ctx->picinfo.pic_w ||
+	    ctx->last_decoded_picinfo.pic_h != ctx->picinfo.pic_h) {
+		inst->resolution_changed = true;
+		if (ctx->last_decoded_picinfo.buf_w != ctx->picinfo.buf_w ||
+		    ctx->last_decoded_picinfo.buf_h != ctx->picinfo.buf_h)
+			inst->realloc_mv_buf = true;
+
+		mtk_v4l2_debug(1, "resChg: (%d %d) : old(%d, %d) -> new(%d, %d)",
+			       inst->resolution_changed,
+			       inst->realloc_mv_buf,
+			       ctx->last_decoded_picinfo.pic_w,
+			       ctx->last_decoded_picinfo.pic_h,
+			       ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+	}
+}
+
+static void vdec_h264_slice_get_crop_info(struct vdec_h264_slice_inst *inst,
+					  struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->ctx->picinfo.pic_w;
+	cr->height = inst->ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(inst, "l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_h264_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_h264_slice_inst *inst;
+	int err, vsi_size;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_h264 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	vsi_size = round_up(sizeof(struct vdec_h264_slice_vsi), 64);
+	inst->vsi = inst->vpu.vsi;
+	inst->vsi_core =
+		(struct vdec_h264_slice_vsi *)(((char *)inst->vpu.vsi) + vsi_size);
+	inst->resolution_changed = true;
+	inst->realloc_mv_buf = true;
+
+	mtk_vcodec_debug(inst, "lat struct size = %d,%d,%d,%d vsi: %d\n",
+			 (int)sizeof(struct mtk_h264_sps_param),
+			 (int)sizeof(struct mtk_h264_pps_param),
+			 (int)sizeof(struct vdec_h264_slice_lat_dec_param),
+			 (int)sizeof(struct mtk_h264_dpb_info),
+			 vsi_size);
+	mtk_vcodec_debug(inst, "lat H264 instance >> %p, codec_type = 0x%x",
+			 inst, inst->vpu.codec_type);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static void vdec_h264_slice_deinit(void *h_vdec)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_h264_slice_free_mv_buf(inst);
+	vdec_msg_queue_deinit(&inst->ctx->msg_queue, inst->ctx);
+
+	kfree(inst);
+}
+
+static int vdec_h264_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_fb *fb;
+	u64 vdec_fb_va;
+	u64 y_fb_dma, c_fb_dma;
+	int err, timeout, i;
+	struct mtk_vcodec_ctx *ctx = lat_buf->ctx;
+	struct vdec_h264_slice_inst *inst = ctx->drv_handle;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	struct vdec_h264_slice_share_info *share_info = lat_buf->private_data;
+	struct mtk_vcodec_mem *mem;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+
+	mtk_vcodec_debug(inst, "[h264-core] vdec_h264 core decode");
+	memcpy(&inst->vsi_core->h264_slice_params, &share_info->h264_slice_params,
+	       sizeof(share_info->h264_slice_params));
+
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	vdec_fb_va = (unsigned long)fb;
+
+	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma =
+			y_fb_dma + inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	mtk_vcodec_debug(inst, "[h264-core] y/c addr = 0x%llx 0x%llx", y_fb_dma,
+			 c_fb_dma);
+
+	inst->vsi_core->dec.y_fb_dma = y_fb_dma;
+	inst->vsi_core->dec.c_fb_dma = c_fb_dma;
+	inst->vsi_core->dec.vdec_fb_va = vdec_fb_va;
+	inst->vsi_core->dec.nal_info = share_info->nal_info;
+	inst->vsi_core->wdma_start_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi_core->wdma_end_addr =
+		lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi_core->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi_core->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi_core->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+	inst->vsi_core->trans_start = share_info->trans_start;
+	inst->vsi_core->trans_end = share_info->trans_end;
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi_core->mv_buf_dma[i] = mem->dma_addr;
+	}
+
+	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	vb2_v4l2->vb2_buf.timestamp = lat_buf->ts_info.vb2_buf.timestamp;
+	vb2_v4l2->timecode = lat_buf->ts_info.timecode;
+	vb2_v4l2->field = lat_buf->ts_info.field;
+	vb2_v4l2->flags = lat_buf->ts_info.flags;
+	vb2_v4l2->vb2_buf.copied_timestamp =
+		lat_buf->ts_info.vb2_buf.copied_timestamp;
+
+	vdec_h264_slice_fill_decode_reflist(inst, &inst->vsi_core->h264_slice_params,
+					    share_info);
+
+	err = vpu_dec_core(vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "core decode err=%d", err);
+		goto vdec_dec_end;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+	if (timeout)
+		mtk_vcodec_err(inst, "core decode timeout: pic_%d",
+			       ctx->decoded_frame_cnt);
+	inst->vsi_core->dec.timeout = !!timeout;
+
+	vpu_dec_core_end(vpu);
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+			 ctx->decoded_frame_cnt,
+			 inst->vsi_core->dec.crc[0], inst->vsi_core->dec.crc[1],
+			 inst->vsi_core->dec.crc[2], inst->vsi_core->dec.crc[3],
+			 inst->vsi_core->dec.crc[4], inst->vsi_core->dec.crc[5],
+			 inst->vsi_core->dec.crc[6], inst->vsi_core->dec.crc[7]);
+
+vdec_dec_end:
+	vdec_msg_queue_update_ube_rptr(&lat_buf->ctx->msg_queue,
+				       share_info->trans_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, !!err);
+	mtk_vcodec_debug(inst, "core decode done err=%d", err);
+	ctx->decoded_frame_cnt++;
+	return 0;
+}
+
+static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				  struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info;
+	int nal_start_idx, err, timeout = 0, i;
+	unsigned int data[2];
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_h264_slice_share_info *share_info;
+	unsigned char *buf;
+	struct mtk_vcodec_mem *mem;
+
+	if (vdec_msg_queue_init(&inst->ctx->msg_queue, inst->ctx,
+				vdec_h264_slice_core_decode,
+				sizeof(*share_info)))
+		return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs) {
+		vdec_msg_queue_wait_lat_buf_full(&inst->ctx->msg_queue);
+		return vpu_dec_reset(vpu);
+	}
+
+	lat_buf = vdec_msg_queue_dqbuf(&inst->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(inst, "failed to get lat buffer");
+		return -EINVAL;
+	}
+	share_info = lat_buf->private_data;
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	buf = (unsigned char *)bs->va;
+	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
+	if (nal_start_idx < 0) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	inst->vsi->dec.nal_info = buf[nal_start_idx];
+	inst->vsi->dec.bs_buf_addr = (u64)bs->dma_addr;
+	inst->vsi->dec.bs_buf_size = bs->size;
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &lat_buf->ts_info, true);
+
+	err = vdec_h264_slice_fill_decode_parameters(inst, share_info);
+	if (err)
+		goto err_free_fb_out;
+
+	*res_chg = inst->resolution_changed;
+	if (inst->resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->realloc_mv_buf) {
+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		inst->resolution_changed = false;
+	}
+	for (i = 0; i < H264_MAX_MV_NUM; i++) {
+		mem = &inst->mv_buf[i];
+		inst->vsi->mv_buf_dma[i] = mem->dma_addr;
+	}
+	inst->vsi->wdma_start_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	inst->vsi->wdma_end_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr +
+		lat_buf->ctx->msg_queue.wdma_addr.size;
+	inst->vsi->wdma_err_addr = lat_buf->wdma_err_addr.dma_addr;
+	inst->vsi->slice_bc_start_addr = lat_buf->slice_bc_addr.dma_addr;
+	inst->vsi->slice_bc_end_addr = lat_buf->slice_bc_addr.dma_addr +
+		lat_buf->slice_bc_addr.size;
+
+	inst->vsi->trans_end = inst->ctx->msg_queue.wdma_rptr_addr;
+	inst->vsi->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	mtk_vcodec_debug(inst, "lat:trans(0x%llx 0x%llx)err:0x%llx",
+			 inst->vsi->wdma_start_addr,
+			 inst->vsi->wdma_end_addr,
+			 inst->vsi->wdma_err_addr);
+
+	mtk_vcodec_debug(inst, "slice(0x%llx 0x%llx) rprt((0x%llx 0x%llx))",
+			 inst->vsi->slice_bc_start_addr,
+			 inst->vsi->slice_bc_end_addr,
+			 inst->vsi->trans_start,
+			 inst->vsi->trans_end);
+	err = vpu_dec_start(vpu, data, 2);
+	if (err) {
+		mtk_vcodec_debug(inst, "lat decode err: %d", err);
+		goto err_free_fb_out;
+	}
+
+	/* wait decoder done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+	inst->vsi->dec.timeout = !!timeout;
+
+	err = vpu_dec_end(vpu);
+	if (err == SLICE_HEADER_FULL || timeout || err == TRANS_BUFFER_FULL) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
+				       share_info->trans_end);
+
+	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+	       sizeof(share_info->h264_slice_params));
+	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	inst->slice_dec_num++;
+
+err_free_fb_out:
+	mtk_vcodec_err(inst, "slice dec number: %d err: %d", inst->slice_dec_num, err);
+	return err;
+}
+
+static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type,
+				     void *out)
+{
+	struct vdec_h264_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_h264_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*(unsigned int *)out = 6;
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_h264_slice_get_crop_info(inst, out);
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+const struct vdec_common_if vdec_h264_slice_lat_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c93dd0ea3537..c17a7815e1bb 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -20,7 +20,13 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
-		ctx->dec_if = &vdec_h264_slice_if;
+		if (ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) {
+			ctx->dec_if = &vdec_h264_slice_if;
+			ctx->hw_id = MTK_VDEC_CORE;
+		} else {
+			ctx->dec_if = &vdec_h264_slice_lat_if;
+			ctx->hw_id = MTK_VDEC_LAT0;
+		}
 		break;
 	case V4L2_PIX_FMT_H264:
 		ctx->dec_if = &vdec_h264_if;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index d467e8af4a84..6ce848e74167 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -56,6 +56,7 @@ struct vdec_fb_node {
 
 extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
+extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
diff --git a/include/linux/remoteproc/mtk_scp.h b/include/linux/remoteproc/mtk_scp.h
index b47416f7aeb8..7c2b7cc9fe6c 100644
--- a/include/linux/remoteproc/mtk_scp.h
+++ b/include/linux/remoteproc/mtk_scp.h
@@ -41,6 +41,8 @@ enum scp_ipi_id {
 	SCP_IPI_ISP_FRAME,
 	SCP_IPI_FD_CMD,
 	SCP_IPI_CROS_HOST_CMD,
+	SCP_IPI_VDEC_LAT,
+	SCP_IPI_VDEC_CORE,
 	SCP_IPI_NS_SERVICE = 0xFF,
 	SCP_IPI_MAX = 0x100,
 };
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:13 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:13 +0800
Subject: [PATCH v6, 12/15] media: mtk-vcodec: Extract H264 common code
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-13-yunfei.dong@mediatek.com>

Mt8192 can use some of common code with mt8183. Moves them to
a new file in order to reuse.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/vdec/vdec_h264_req_common.c    | 310 +++++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_common.h    | 253 +++++++++++
 .../mtk-vcodec/vdec/vdec_h264_req_if.c        | 424 ++----------------
 4 files changed, 606 insertions(+), 382 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 359619653a0e..3f41d748eee5 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
+		vdec/vdec_h264_req_common.o \
 		mtk_vcodec_dec_drv.o \
 		vdec_drv_if.o \
 		vdec_vpu_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
new file mode 100644
index 000000000000..bf596755e91c
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include "vdec_h264_req_common.h"
+
+/* get used parameters for sps/pps */
+#define GET_MTK_VDEC_FLAG(cond, flag) \
+	{ dst_param->cond = ((src_param->flags & flag) ? (1) : (0)); }
+#define GET_MTK_VDEC_PARAM(param) \
+	{ dst_param->param = src_param->param; }
+
+/*
+ * The firmware expects unused reflist entries to have the value 0x20.
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid)
+{
+	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
+}
+
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	if (!ctrl)
+		return ERR_PTR(-EINVAL);
+
+	return ctrl->p_cur.p;
+}
+
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+				 struct slice_api_h264_decode_param *decode_params,
+				 struct mtk_h264_dpb_info *h264_dpb_info)
+{
+	const struct slice_h264_dpb_entry *dpb;
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	struct vb2_v4l2_buffer *vb2_v4l2;
+	int index, vb2_index;
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+
+	for (index = 0; index < V4L2_H264_NUM_DPB_ENTRIES; index++) {
+		dpb = &decode_params->dpb[index];
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
+			h264_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+
+		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
+		if (vb2_index < 0) {
+			dev_err(&ctx->dev->plat_dev->dev,
+				"Reference invalid: dpb_index(%d) reference_ts(%lld)",
+				index, dpb->reference_ts);
+			continue;
+		}
+
+		/* 1 for short term reference, 2 for long term reference */
+		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
+			h264_dpb_info[index].reference_flag = 1;
+		else
+			h264_dpb_info[index].reference_flag = 2;
+
+		vb = vq->bufs[vb2_index];
+		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
+		h264_dpb_info[index].field = vb2_v4l2->field;
+
+		h264_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			h264_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			h264_dpb_info[index].c_dma_addr =
+				h264_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+}
+
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+				   const struct v4l2_ctrl_h264_sps *src_param)
+{
+	GET_MTK_VDEC_PARAM(chroma_format_idc);
+	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
+	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
+	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
+	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
+	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
+	GET_MTK_VDEC_PARAM(max_num_ref_frames);
+	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
+	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
+
+	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
+			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
+	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
+			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
+	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
+			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
+	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
+			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
+	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
+			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
+	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
+			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+}
+
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+				   const struct v4l2_ctrl_h264_pps *src_param)
+{
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
+	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
+	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
+	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
+	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
+
+	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
+			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
+	GET_MTK_VDEC_FLAG(pic_order_present_flag,
+			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
+	GET_MTK_VDEC_FLAG(weighted_pred_flag,
+			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
+	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
+			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
+	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
+			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
+	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
+			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
+	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
+			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
+	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
+			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
+}
+
+void mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param *dst_param,
+					const struct v4l2_ctrl_h264_slice_params *src_param,
+					const struct v4l2_ctrl_h264_decode_params *dec_param)
+{
+	int temp;
+
+	GET_MTK_VDEC_PARAM(first_mb_in_slice);
+	GET_MTK_VDEC_PARAM(slice_type);
+	GET_MTK_VDEC_PARAM(cabac_init_idc);
+	GET_MTK_VDEC_PARAM(slice_qp_delta);
+	GET_MTK_VDEC_PARAM(disable_deblocking_filter_idc);
+	GET_MTK_VDEC_PARAM(slice_alpha_c0_offset_div2);
+	GET_MTK_VDEC_PARAM(slice_beta_offset_div2);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l0_active_minus1);
+	GET_MTK_VDEC_PARAM(num_ref_idx_l1_active_minus1);
+
+	dst_param->frame_num = dec_param->frame_num;
+	dst_param->pic_order_cnt_lsb = dec_param->pic_order_cnt_lsb;
+
+	dst_param->delta_pic_order_cnt_bottom =
+		dec_param->delta_pic_order_cnt_bottom;
+	dst_param->delta_pic_order_cnt0 =
+		dec_param->delta_pic_order_cnt0;
+	dst_param->delta_pic_order_cnt1 =
+		dec_param->delta_pic_order_cnt1;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC;
+	dst_param->field_pic_flag = temp ? 1 : 0;
+
+	temp = dec_param->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD;
+	dst_param->bottom_field_flag = temp ? 1 : 0;
+
+	GET_MTK_VDEC_FLAG(direct_spatial_mv_pred_flag,
+			  V4L2_H264_SLICE_FLAG_DIRECT_SPATIAL_MV_PRED);
+}
+
+void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
+				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
+{
+	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
+	       sizeof(dst_matrix->scaling_list_4x4));
+
+	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
+	       sizeof(dst_matrix->scaling_list_8x8));
+}
+
+void
+mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
+				 const struct v4l2_ctrl_h264_decode_params *src_params,
+				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
+{
+	struct slice_h264_dpb_entry *dst_entry;
+	const struct v4l2_h264_dpb_entry *src_entry;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
+		dst_entry = &dst_params->dpb[i];
+		src_entry = &dpb[i];
+
+		dst_entry->reference_ts = src_entry->reference_ts;
+		dst_entry->frame_num = src_entry->frame_num;
+		dst_entry->pic_num = src_entry->pic_num;
+		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
+		dst_entry->bottom_field_order_cnt =
+			src_entry->bottom_field_order_cnt;
+		dst_entry->flags = src_entry->flags;
+	}
+
+	/* num_slices is a leftover from the old H.264 support and is ignored
+	 * by the firmware.
+	 */
+	dst_params->num_slices = 0;
+	dst_params->nal_ref_idc = src_params->nal_ref_idc;
+	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
+	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
+	dst_params->flags = src_params->flags;
+}
+
+static bool mtk_vdec_h264_dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
+					  const struct v4l2_h264_dpb_entry *b)
+{
+	return a->top_field_order_cnt == b->top_field_order_cnt &&
+	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
+}
+
+/*
+ * Move DPB entries of dec_param that refer to a frame already existing in dpb
+ * into the already existing slot in dpb, and move other entries into new slots.
+ *
+ * This function is an adaptation of the similarly-named function in
+ * hantro_h264.c.
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+			      struct v4l2_h264_dpb_entry *dpb)
+{
+	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
+	unsigned int i, j;
+
+	/* Disable all entries by default, and mark the ones in use. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
+			set_bit(i, in_use);
+		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
+	}
+
+	/* Try to match new DPB entries with existing ones by their POCs. */
+	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+
+		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
+			continue;
+
+		/*
+		 * To cut off some comparisons, iterate only on target DPB
+		 * entries were already used.
+		 */
+		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
+			struct v4l2_h264_dpb_entry *cdpb;
+
+			cdpb = &dpb[j];
+			if (!mtk_vdec_h264_dpb_entry_match(cdpb, ndpb))
+				continue;
+
+			*cdpb = *ndpb;
+			set_bit(j, used);
+			/* Don't reiterate on this one. */
+			clear_bit(j, in_use);
+			break;
+		}
+
+		if (j == ARRAY_SIZE(dec_param->dpb))
+			set_bit(i, new);
+	}
+
+	/* For entries that could not be matched, use remaining free slots. */
+	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
+		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
+		struct v4l2_h264_dpb_entry *cdpb;
+
+		/*
+		 * Both arrays are of the same sizes, so there is no way
+		 * we can end up with no space in target array, unless
+		 * something is buggy.
+		 */
+		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
+		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
+			return;
+
+		cdpb = &dpb[j];
+		*cdpb = *ndpb;
+		set_bit(j, used);
+	}
+}
+
+unsigned int mtk_vdec_h264_get_mv_buf_size(unsigned int width, unsigned int height)
+{
+	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
+
+	return HW_MB_STORE_SZ * unit_size;
+}
+
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz)
+{
+	if (data_sz > 3 && data[0] == 0 && data[1] == 0 && data[2] == 1)
+		return 3;
+
+	if (data_sz > 4 && data[0] == 0 && data[1] == 0 && data[2] == 0 &&
+	    data[3] == 1)
+		return 4;
+
+	return -1;
+}
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
new file mode 100644
index 000000000000..2d731bc777ca
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_common.h
@@ -0,0 +1,253 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#ifndef _VDEC_H264_REQ_COMMON_H_
+#define _VDEC_H264_REQ_COMMON_H_
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/v4l2-h264.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_drv.h"
+
+#define NAL_NON_IDR_SLICE			0x01
+#define NAL_IDR_SLICE				0x05
+#define NAL_TYPE(value)				((value) & 0x1F)
+
+#define BUF_PREDICTION_SZ			(64 * 4096)
+#define MB_UNIT_LEN				16
+
+/* motion vector size (bytes) for every macro block */
+#define HW_MB_STORE_SZ				64
+
+#define H264_MAX_MV_NUM				32
+
+/**
+ * struct mtk_h264_dpb_info  - h264 dpb information
+ * @y_dma_addr: Y bitstream physical address
+ * @c_dma_addr: CbCr bitstream physical address
+ * @reference_flag: reference picture flag (short/long term reference picture)
+ * @field: field picture flag
+ */
+struct mtk_h264_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int field;
+};
+
+/**
+ * struct mtk_h264_sps_param  - parameters for sps
+ */
+struct mtk_h264_sps_param {
+	unsigned char chroma_format_idc;
+	unsigned char bit_depth_luma_minus8;
+	unsigned char bit_depth_chroma_minus8;
+	unsigned char log2_max_frame_num_minus4;
+	unsigned char pic_order_cnt_type;
+	unsigned char log2_max_pic_order_cnt_lsb_minus4;
+	unsigned char max_num_ref_frames;
+	unsigned char separate_colour_plane_flag;
+	unsigned short pic_width_in_mbs_minus1;
+	unsigned short pic_height_in_map_units_minus1;
+	unsigned int max_frame_nums;
+	unsigned char qpprime_y_zero_transform_bypass_flag;
+	unsigned char delta_pic_order_always_zero_flag;
+	unsigned char frame_mbs_only_flag;
+	unsigned char mb_adaptive_frame_field_flag;
+	unsigned char direct_8x8_inference_flag;
+	unsigned char reserved[3];
+};
+
+/**
+ * struct mtk_h264_pps_param  - parameters for pps
+ */
+struct mtk_h264_pps_param {
+	unsigned char num_ref_idx_l0_default_active_minus1;
+	unsigned char num_ref_idx_l1_default_active_minus1;
+	unsigned char weighted_bipred_idc;
+	char pic_init_qp_minus26;
+	char chroma_qp_index_offset;
+	char second_chroma_qp_index_offset;
+	unsigned char entropy_coding_mode_flag;
+	unsigned char pic_order_present_flag;
+	unsigned char deblocking_filter_control_present_flag;
+	unsigned char constrained_intra_pred_flag;
+	unsigned char weighted_pred_flag;
+	unsigned char redundant_pic_cnt_present_flag;
+	unsigned char transform_8x8_mode_flag;
+	unsigned char scaling_matrix_present_flag;
+	unsigned char reserved[2];
+};
+
+/**
+ * struct mtk_h264_slice_hd_param  - parameters for slice header
+ */
+struct mtk_h264_slice_hd_param {
+	unsigned int first_mb_in_slice;
+	unsigned int field_pic_flag;
+	unsigned int slice_type;
+	unsigned int frame_num;
+	int pic_order_cnt_lsb;
+	int delta_pic_order_cnt_bottom;
+	unsigned int bottom_field_flag;
+	unsigned int direct_spatial_mv_pred_flag;
+	int delta_pic_order_cnt0;
+	int delta_pic_order_cnt1;
+	unsigned int cabac_init_idc;
+	int slice_qp_delta;
+	unsigned int disable_deblocking_filter_idc;
+	int slice_alpha_c0_offset_div2;
+	int slice_beta_offset_div2;
+	unsigned int num_ref_idx_l0_active_minus1;
+	unsigned int num_ref_idx_l1_active_minus1;
+	unsigned int reserved;
+};
+
+struct slice_api_h264_scaling_matrix {
+	unsigned char scaling_list_4x4[6][16];
+	unsigned char scaling_list_8x8[6][64];
+};
+
+struct slice_h264_dpb_entry {
+	unsigned long long reference_ts;
+	unsigned short frame_num;
+	unsigned short pic_num;
+	/* Note that field is indicated by v4l2_buffer.field */
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
+};
+
+/**
+ * struct slice_api_h264_decode_param - parameters for decode.
+ */
+struct slice_api_h264_decode_param {
+	struct slice_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES];
+	unsigned short num_slices;
+	unsigned short nal_ref_idc;
+	unsigned char ref_pic_list_p0[32];
+	unsigned char ref_pic_list_b0[32];
+	unsigned char ref_pic_list_b1[32];
+	int top_field_order_cnt;
+	int bottom_field_order_cnt;
+	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
+};
+
+/**
+ * struct h264_fb - h264 decode frame buffer information
+ * @vdec_fb_va  : virtual address of struct vdec_fb
+ * @y_fb_dma    : dma address of Y frame buffer (luma)
+ * @c_fb_dma    : dma address of C frame buffer (chroma)
+ * @poc         : picture order count of frame buffer
+ * @reserved    : for 8 bytes alignment
+ */
+struct h264_fb {
+	u64 vdec_fb_va;
+	u64 y_fb_dma;
+	u64 c_fb_dma;
+	s32 poc;
+	u32 reserved;
+};
+
+/**
+ * mtk_vdec_h264_fixup_ref_list - fixup unused reference to 0x20.
+ * @ref_list: reference picture list
+ * @num_valid: used reference number
+ */
+void mtk_vdec_h264_fixup_ref_list(u8 *ref_list, size_t num_valid);
+
+/**
+ * mtk_vdec_h264_get_ctrl_ptr - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @id: CID control ID
+ */
+void *mtk_vdec_h264_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id);
+
+/**
+ * mtk_vdec_h264_fill_dpb_info - get each CID contrl address.
+ * @ctx: v4l2 ctx
+ * @decode_params: slice decode params
+ * @h264_dpb_info: dpb buffer information
+ */
+void mtk_vdec_h264_fill_dpb_info(struct mtk_vcodec_ctx *ctx,
+				 struct slice_api_h264_decode_param *decode_params,
+				 struct mtk_h264_dpb_info *h264_dpb_info);
+
+/**
+ * mtk_vdec_h264_copy_sps_params - get sps params.
+ * @dst_params: sps params for hw decoder
+ * @src_params: sps params from user driver
+ */
+void mtk_vdec_h264_copy_sps_params(struct mtk_h264_sps_param *dst_param,
+				   const struct v4l2_ctrl_h264_sps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_pps_params - get pps params.
+ * @dst_params: pps params for hw decoder
+ * @src_params: pps params from user driver
+ */
+void mtk_vdec_h264_copy_pps_params(struct mtk_h264_pps_param *dst_param,
+				   const struct v4l2_ctrl_h264_pps *src_param);
+
+/**
+ * mtk_vdec_h264_copy_slice_hd_params - get slice header params.
+ * @dst_params: slice params for hw decoder
+ * @src_params: slice params from user driver
+ * @dec_param: decode params from user driver
+ */
+void mtk_vdec_h264_copy_slice_hd_params(struct mtk_h264_slice_hd_param *dst_param,
+					const struct v4l2_ctrl_h264_slice_params *src_param,
+					const struct v4l2_ctrl_h264_decode_params *dec_param);
+
+/**
+ * mtk_vdec_h264_copy_scaling_matrix - get each CID contrl address.
+ * @dst_matrix: scaling list params for hw decoder
+ * @src_matrix: scaling list params from user driver
+ */
+void mtk_vdec_h264_copy_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
+				       const struct v4l2_ctrl_h264_scaling_matrix *src_matrix);
+
+/**
+ * mtk_vdec_h264_copy_decode_params - get decode params.
+ * @dst_params: dst params for hw decoder
+ * @src_params: decode params from user driver
+ * @dpb: dpb information
+ */
+void
+mtk_vdec_h264_copy_decode_params(struct slice_api_h264_decode_param *dst_params,
+				 const struct v4l2_ctrl_h264_decode_params *src_params,
+				 const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES]);
+
+/**
+ * mtk_vdec_h264_update_dpb - updata dpb list.
+ * @dec_param: v4l2 control decode params
+ * @dpb: dpb entry informaton
+ */
+void mtk_vdec_h264_update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
+			      struct v4l2_h264_dpb_entry *dpb);
+
+/**
+ * mtk_vdec_h264_find_start_code - find h264 start code using sofeware.
+ * @data: input buffer address
+ * @data_sz: input buffer size
+ *
+ * Return: returns start code position.
+ */
+int mtk_vdec_h264_find_start_code(unsigned char *data, unsigned int data_sz);
+
+/**
+ * mtk_vdec_h264_get_mv_buf_size - get mv buffer size.
+ * @width: picture width
+ * @height: picture height
+ *
+ * Return: returns mv buffer size.
+ */
+unsigned int mtk_vdec_h264_get_mv_buf_size(unsigned int width, unsigned int height);
+
+#endif
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
index 36f3dc1fbe3b..87e0b2f95572 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
@@ -12,109 +12,7 @@
 #include "../vdec_drv_base.h"
 #include "../vdec_drv_if.h"
 #include "../vdec_vpu_if.h"
-
-#define BUF_PREDICTION_SZ			(64 * 4096)
-#define MB_UNIT_LEN				16
-
-/* get used parameters for sps/pps */
-#define GET_MTK_VDEC_FLAG(cond, flag) \
-	{ dst_param->cond = ((src_param->flags & (flag)) ? (1) : (0)); }
-#define GET_MTK_VDEC_PARAM(param) \
-	{ dst_param->param = src_param->param; }
-/* motion vector size (bytes) for every macro block */
-#define HW_MB_STORE_SZ				64
-
-#define H264_MAX_FB_NUM				17
-#define H264_MAX_MV_NUM				32
-#define HDR_PARSING_BUF_SZ			1024
-
-/**
- * struct mtk_h264_dpb_info  - h264 dpb information
- * @y_dma_addr: Y bitstream physical address
- * @c_dma_addr: CbCr bitstream physical address
- * @reference_flag: reference picture flag (short/long term reference picture)
- * @field: field picture flag
- */
-struct mtk_h264_dpb_info {
-	dma_addr_t y_dma_addr;
-	dma_addr_t c_dma_addr;
-	int reference_flag;
-	int field;
-};
-
-/*
- * struct mtk_h264_sps_param  - parameters for sps
- */
-struct mtk_h264_sps_param {
-	unsigned char chroma_format_idc;
-	unsigned char bit_depth_luma_minus8;
-	unsigned char bit_depth_chroma_minus8;
-	unsigned char log2_max_frame_num_minus4;
-	unsigned char pic_order_cnt_type;
-	unsigned char log2_max_pic_order_cnt_lsb_minus4;
-	unsigned char max_num_ref_frames;
-	unsigned char separate_colour_plane_flag;
-	unsigned short pic_width_in_mbs_minus1;
-	unsigned short pic_height_in_map_units_minus1;
-	unsigned int max_frame_nums;
-	unsigned char qpprime_y_zero_transform_bypass_flag;
-	unsigned char delta_pic_order_always_zero_flag;
-	unsigned char frame_mbs_only_flag;
-	unsigned char mb_adaptive_frame_field_flag;
-	unsigned char direct_8x8_inference_flag;
-	unsigned char reserved[3];
-};
-
-/*
- * struct mtk_h264_pps_param  - parameters for pps
- */
-struct mtk_h264_pps_param {
-	unsigned char num_ref_idx_l0_default_active_minus1;
-	unsigned char num_ref_idx_l1_default_active_minus1;
-	unsigned char weighted_bipred_idc;
-	char pic_init_qp_minus26;
-	char chroma_qp_index_offset;
-	char second_chroma_qp_index_offset;
-	unsigned char entropy_coding_mode_flag;
-	unsigned char pic_order_present_flag;
-	unsigned char deblocking_filter_control_present_flag;
-	unsigned char constrained_intra_pred_flag;
-	unsigned char weighted_pred_flag;
-	unsigned char redundant_pic_cnt_present_flag;
-	unsigned char transform_8x8_mode_flag;
-	unsigned char scaling_matrix_present_flag;
-	unsigned char reserved[2];
-};
-
-struct slice_api_h264_scaling_matrix {
-	unsigned char scaling_list_4x4[6][16];
-	unsigned char scaling_list_8x8[6][64];
-};
-
-struct slice_h264_dpb_entry {
-	unsigned long long reference_ts;
-	unsigned short frame_num;
-	unsigned short pic_num;
-	/* Note that field is indicated by v4l2_buffer.field */
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DPB_ENTRY_FLAG_* */
-};
-
-/*
- * struct slice_api_h264_decode_param - parameters for decode.
- */
-struct slice_api_h264_decode_param {
-	struct slice_h264_dpb_entry dpb[16];
-	unsigned short num_slices;
-	unsigned short nal_ref_idc;
-	unsigned char ref_pic_list_p0[32];
-	unsigned char ref_pic_list_b0[32];
-	unsigned char ref_pic_list_b1[32];
-	int top_field_order_cnt;
-	int bottom_field_order_cnt;
-	unsigned int flags; /* V4L2_H264_DECODE_PARAM_FLAG_* */
-};
+#include "vdec_h264_req_common.h"
 
 /*
  * struct mtk_h264_dec_slice_param  - parameters for decode current frame
@@ -127,22 +25,6 @@ struct mtk_h264_dec_slice_param {
 	struct mtk_h264_dpb_info h264_dpb_info[16];
 };
 
-/**
- * struct h264_fb - h264 decode frame buffer information
- * @vdec_fb_va  : virtual address of struct vdec_fb
- * @y_fb_dma    : dma address of Y frame buffer (luma)
- * @c_fb_dma    : dma address of C frame buffer (chroma)
- * @poc         : picture order count of frame buffer
- * @reserved    : for 8 bytes alignment
- */
-struct h264_fb {
-	u64 vdec_fb_va;
-	u64 y_fb_dma;
-	u64 c_fb_dma;
-	s32 poc;
-	u32 reserved;
-};
-
 /**
  * struct vdec_h264_dec_info - decode information
  * @dpb_sz		: decoding picture buffer size
@@ -212,265 +94,45 @@ struct vdec_h264_slice_inst {
 	struct v4l2_h264_dpb_entry dpb[16];
 };
 
-static void *get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
-{
-	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
-
-	return ctrl->p_cur.p;
-}
-
-static void get_h264_dpb_list(struct vdec_h264_slice_inst *inst,
-			      struct mtk_h264_dec_slice_param *slice_param)
-{
-	struct vb2_queue *vq;
-	struct vb2_buffer *vb;
-	struct vb2_v4l2_buffer *vb2_v4l2;
-	u64 index;
-
-	vq = v4l2_m2m_get_vq(inst->ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
-
-	for (index = 0; index < ARRAY_SIZE(slice_param->decode_params.dpb); index++) {
-		const struct slice_h264_dpb_entry *dpb;
-		int vb2_index;
-
-		dpb = &slice_param->decode_params.dpb[index];
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) {
-			slice_param->h264_dpb_info[index].reference_flag = 0;
-			continue;
-		}
-
-		vb2_index = vb2_find_timestamp(vq, dpb->reference_ts, 0);
-		if (vb2_index < 0) {
-			mtk_vcodec_err(inst, "Reference invalid: dpb_index(%lld) reference_ts(%lld)",
-				       index, dpb->reference_ts);
-			continue;
-		}
-		/* 1 for short term reference, 2 for long term reference */
-		if (!(dpb->flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM))
-			slice_param->h264_dpb_info[index].reference_flag = 1;
-		else
-			slice_param->h264_dpb_info[index].reference_flag = 2;
-
-		vb = vq->bufs[vb2_index];
-		vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
-		slice_param->h264_dpb_info[index].field = vb2_v4l2->field;
-
-		slice_param->h264_dpb_info[index].y_dma_addr =
-			vb2_dma_contig_plane_dma_addr(vb, 0);
-		if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
-			slice_param->h264_dpb_info[index].c_dma_addr =
-				vb2_dma_contig_plane_dma_addr(vb, 1);
-		}
-	}
-}
-
-static void get_h264_sps_parameters(struct mtk_h264_sps_param *dst_param,
-				    const struct v4l2_ctrl_h264_sps *src_param)
-{
-	GET_MTK_VDEC_PARAM(chroma_format_idc);
-	GET_MTK_VDEC_PARAM(bit_depth_luma_minus8);
-	GET_MTK_VDEC_PARAM(bit_depth_chroma_minus8);
-	GET_MTK_VDEC_PARAM(log2_max_frame_num_minus4);
-	GET_MTK_VDEC_PARAM(pic_order_cnt_type);
-	GET_MTK_VDEC_PARAM(log2_max_pic_order_cnt_lsb_minus4);
-	GET_MTK_VDEC_PARAM(max_num_ref_frames);
-	GET_MTK_VDEC_PARAM(pic_width_in_mbs_minus1);
-	GET_MTK_VDEC_PARAM(pic_height_in_map_units_minus1);
-
-	GET_MTK_VDEC_FLAG(separate_colour_plane_flag,
-			  V4L2_H264_SPS_FLAG_SEPARATE_COLOUR_PLANE);
-	GET_MTK_VDEC_FLAG(qpprime_y_zero_transform_bypass_flag,
-			  V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
-	GET_MTK_VDEC_FLAG(delta_pic_order_always_zero_flag,
-			  V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
-	GET_MTK_VDEC_FLAG(frame_mbs_only_flag,
-			  V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
-	GET_MTK_VDEC_FLAG(mb_adaptive_frame_field_flag,
-			  V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
-	GET_MTK_VDEC_FLAG(direct_8x8_inference_flag,
-			  V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
-}
-
-static void get_h264_pps_parameters(struct mtk_h264_pps_param *dst_param,
-				    const struct v4l2_ctrl_h264_pps *src_param)
+static int get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 {
-	GET_MTK_VDEC_PARAM(num_ref_idx_l0_default_active_minus1);
-	GET_MTK_VDEC_PARAM(num_ref_idx_l1_default_active_minus1);
-	GET_MTK_VDEC_PARAM(weighted_bipred_idc);
-	GET_MTK_VDEC_PARAM(pic_init_qp_minus26);
-	GET_MTK_VDEC_PARAM(chroma_qp_index_offset);
-	GET_MTK_VDEC_PARAM(second_chroma_qp_index_offset);
-
-	GET_MTK_VDEC_FLAG(entropy_coding_mode_flag,
-			  V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
-	GET_MTK_VDEC_FLAG(pic_order_present_flag,
-			  V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
-	GET_MTK_VDEC_FLAG(weighted_pred_flag,
-			  V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
-	GET_MTK_VDEC_FLAG(deblocking_filter_control_present_flag,
-			  V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
-	GET_MTK_VDEC_FLAG(constrained_intra_pred_flag,
-			  V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
-	GET_MTK_VDEC_FLAG(redundant_pic_cnt_present_flag,
-			  V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
-	GET_MTK_VDEC_FLAG(transform_8x8_mode_flag,
-			  V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
-	GET_MTK_VDEC_FLAG(scaling_matrix_present_flag,
-			  V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-}
-
-static void
-get_h264_scaling_matrix(struct slice_api_h264_scaling_matrix *dst_matrix,
-			const struct v4l2_ctrl_h264_scaling_matrix *src_matrix)
-{
-	memcpy(dst_matrix->scaling_list_4x4, src_matrix->scaling_list_4x4,
-	       sizeof(dst_matrix->scaling_list_4x4));
-
-	memcpy(dst_matrix->scaling_list_8x8, src_matrix->scaling_list_8x8,
-	       sizeof(dst_matrix->scaling_list_8x8));
-}
-
-static void
-get_h264_decode_parameters(struct slice_api_h264_decode_param *dst_params,
-			   const struct v4l2_ctrl_h264_decode_params *src_params,
-			   const struct v4l2_h264_dpb_entry dpb[V4L2_H264_NUM_DPB_ENTRIES])
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dst_params->dpb); i++) {
-		struct slice_h264_dpb_entry *dst_entry = &dst_params->dpb[i];
-		const struct v4l2_h264_dpb_entry *src_entry = &dpb[i];
-
-		dst_entry->reference_ts = src_entry->reference_ts;
-		dst_entry->frame_num = src_entry->frame_num;
-		dst_entry->pic_num = src_entry->pic_num;
-		dst_entry->top_field_order_cnt = src_entry->top_field_order_cnt;
-		dst_entry->bottom_field_order_cnt =
-			src_entry->bottom_field_order_cnt;
-		dst_entry->flags = src_entry->flags;
-	}
-
-	/*
-	 * num_slices is a leftover from the old H.264 support and is ignored
-	 * by the firmware.
-	 */
-	dst_params->num_slices = 0;
-	dst_params->nal_ref_idc = src_params->nal_ref_idc;
-	dst_params->top_field_order_cnt = src_params->top_field_order_cnt;
-	dst_params->bottom_field_order_cnt = src_params->bottom_field_order_cnt;
-	dst_params->flags = src_params->flags;
-}
-
-static bool dpb_entry_match(const struct v4l2_h264_dpb_entry *a,
-			    const struct v4l2_h264_dpb_entry *b)
-{
-	return a->top_field_order_cnt == b->top_field_order_cnt &&
-	       a->bottom_field_order_cnt == b->bottom_field_order_cnt;
-}
-
-/*
- * Move DPB entries of dec_param that refer to a frame already existing in dpb
- * into the already existing slot in dpb, and move other entries into new slots.
- *
- * This function is an adaptation of the similarly-named function in
- * hantro_h264.c.
- */
-static void update_dpb(const struct v4l2_ctrl_h264_decode_params *dec_param,
-		       struct v4l2_h264_dpb_entry *dpb)
-{
-	DECLARE_BITMAP(new, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(in_use, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	DECLARE_BITMAP(used, ARRAY_SIZE(dec_param->dpb)) = { 0, };
-	unsigned int i, j;
-
-	/* Disable all entries by default, and mark the ones in use. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)
-			set_bit(i, in_use);
-		dpb[i].flags &= ~V4L2_H264_DPB_ENTRY_FLAG_ACTIVE;
-	}
-
-	/* Try to match new DPB entries with existing ones by their POCs. */
-	for (i = 0; i < ARRAY_SIZE(dec_param->dpb); i++) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-
-		if (!(ndpb->flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
-			continue;
-
-		/*
-		 * To cut off some comparisons, iterate only on target DPB
-		 * entries were already used.
-		 */
-		for_each_set_bit(j, in_use, ARRAY_SIZE(dec_param->dpb)) {
-			struct v4l2_h264_dpb_entry *cdpb;
-
-			cdpb = &dpb[j];
-			if (!dpb_entry_match(cdpb, ndpb))
-				continue;
-
-			*cdpb = *ndpb;
-			set_bit(j, used);
-			/* Don't reiterate on this one. */
-			clear_bit(j, in_use);
-			break;
-		}
-
-		if (j == ARRAY_SIZE(dec_param->dpb))
-			set_bit(i, new);
-	}
-
-	/* For entries that could not be matched, use remaining free slots. */
-	for_each_set_bit(i, new, ARRAY_SIZE(dec_param->dpb)) {
-		const struct v4l2_h264_dpb_entry *ndpb = &dec_param->dpb[i];
-		struct v4l2_h264_dpb_entry *cdpb;
-
-		/*
-		 * Both arrays are of the same sizes, so there is no way
-		 * we can end up with no space in target array, unless
-		 * something is buggy.
-		 */
-		j = find_first_zero_bit(used, ARRAY_SIZE(dec_param->dpb));
-		if (WARN_ON(j >= ARRAY_SIZE(dec_param->dpb)))
-			return;
-
-		cdpb = &dpb[j];
-		*cdpb = *ndpb;
-		set_bit(j, used);
-	}
-}
-
-/*
- * The firmware expects unused reflist entries to have the value 0x20.
- */
-static void fixup_ref_list(u8 *ref_list, size_t num_valid)
-{
-	memset(&ref_list[num_valid], 0x20, 32 - num_valid);
-}
-
-static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
-{
-	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
-	const struct v4l2_ctrl_h264_sps *sps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
-	const struct v4l2_ctrl_h264_pps *pps =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
-	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	const struct v4l2_ctrl_h264_decode_params *dec_params;
+	const struct v4l2_ctrl_h264_sps *sps;
+	const struct v4l2_ctrl_h264_pps *pps;
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
 	struct mtk_h264_dec_slice_param *slice_param = &inst->h264_slice_param;
 	struct v4l2_h264_reflist_builder reflist_builder;
 	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
 	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
 	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
 
-	update_dpb(dec_params, inst->dpb);
+	dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	if (IS_ERR(dec_params))
+		return PTR_ERR(dec_params);
+
+	sps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+	if (IS_ERR(sps))
+		return PTR_ERR(sps);
+
+	pps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+	if (IS_ERR(pps))
+		return PTR_ERR(pps);
 
-	get_h264_sps_parameters(&slice_param->sps, sps);
-	get_h264_pps_parameters(&slice_param->pps, pps);
-	get_h264_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
-	get_h264_decode_parameters(&slice_param->decode_params, dec_params,
-				   inst->dpb);
-	get_h264_dpb_list(inst, slice_param);
+	scaling_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	if (IS_ERR(scaling_matrix))
+		return PTR_ERR(scaling_matrix);
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params,
+					 dec_params, inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+				    slice_param->h264_dpb_info);
 
 	/* Build the reference lists */
 	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps,
@@ -478,19 +140,14 @@ static void get_vdec_decode_parameters(struct vdec_h264_slice_inst *inst)
 	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
 	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
 	/* Adapt the built lists to the firmware's expectations */
-	fixup_ref_list(p0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b0_reflist, reflist_builder.num_valid);
-	fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
 
 	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
 	       sizeof(inst->vsi_ctx.h264_slice_params));
-}
 
-static unsigned int get_mv_buf_size(unsigned int width, unsigned int height)
-{
-	int unit_size = (width / MB_UNIT_LEN) * (height / MB_UNIT_LEN) + 8;
-
-	return HW_MB_STORE_SZ * unit_size;
+	return 0;
 }
 
 static int allocate_predication_buf(struct vdec_h264_slice_inst *inst)
@@ -525,7 +182,7 @@ static int alloc_mv_buf(struct vdec_h264_slice_inst *inst,
 	int i;
 	int err;
 	struct mtk_vcodec_mem *mem = NULL;
-	unsigned int buf_sz = get_mv_buf_size(pic->buf_w, pic->buf_h);
+	unsigned int buf_sz = mtk_vdec_h264_get_mv_buf_size(pic->buf_w, pic->buf_h);
 
 	mtk_v4l2_debug(3, "size = 0x%x", buf_sz);
 	for (i = 0; i < H264_MAX_MV_NUM; i++) {
@@ -674,7 +331,7 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 {
 	struct vdec_h264_slice_inst *inst = h_vdec;
 	const struct v4l2_ctrl_h264_decode_params *dec_params =
-		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
 	struct vdec_vpu_inst *vpu = &inst->vpu;
 	struct mtk_video_dec_buf *src_buf_info;
 	struct mtk_video_dec_buf *dst_buf_info;
@@ -706,7 +363,10 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
 				   &dst_buf_info->m2m_buf.vb, true);
-	get_vdec_decode_parameters(inst);
+	err = get_vdec_decode_parameters(inst);
+	if (err)
+		goto err_free_fb_out;
+
 	data[0] = bs->size;
 	/*
 	 * Reconstruct the first byte of the NAL unit, as the firmware requests
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:16 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:16 +0800
Subject: [PATCH v6, 15/15] media: mtk-vcodec: support stateless VP9 decoding
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-16-yunfei.dong@mediatek.com>

Add support for VP9 decoding using the stateless API,
as supported by MT8192. And the drivers is lat and core architecture.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Signed-off-by: George Sun <george.sun at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |    1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |   26 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |    1 +
 .../mtk-vcodec/vdec/vdec_vp9_req_lat_if.c     | 1971 +++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |    4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |    1 +
 6 files changed, 2001 insertions(+), 3 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index b457daf2d196..93e7a343b5b0 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -9,6 +9,7 @@ mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
 		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
+		vdec/vdec_vp9_req_lat_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
 		vdec/vdec_h264_req_multi_if.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 2a0164ddc708..3770e8117488 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -91,13 +91,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
 		},
 		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
-	}
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP9_FRAME,
+		},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP9_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP9_FRAME,
+	},
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[4];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
+static struct mtk_video_fmt mtk_video_formats[5];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[3];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -366,6 +381,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
 	case V4L2_PIX_FMT_VP8_FRAME:
+	case V4L2_PIX_FMT_VP9_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -413,6 +429,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP9_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP9_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index e16733fbf0c7..cd2939b47790 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -358,6 +358,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
+	MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
new file mode 100644
index 000000000000..d9a2a4b02b00
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp9_req_lat_if.c
@@ -0,0 +1,1971 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: George Sun <george.sun at mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* reset_frame_context defined in VP9 spec */
+#define VP9_RESET_FRAME_CONTEXT_NONE0 0
+#define VP9_RESET_FRAME_CONTEXT_NONE1 1
+#define VP9_RESET_FRAME_CONTEXT_SPEC 2
+#define VP9_RESET_FRAME_CONTEXT_ALL 3
+
+#define VP9_TILE_BUF_SIZE 4096
+#define VP9_PROB_BUF_SIZE 2560
+#define VP9_COUNTS_BUF_SIZE 16384
+
+#define HDR_FLAG(x) (!!((hdr)->flags & V4L2_VP9_FRAME_FLAG_##x))
+#define LF_FLAG(x) (!!((lf)->flags & V4L2_VP9_LOOP_FILTER_FLAG_##x))
+#define SEG_FLAG(x) (!!((seg)->flags & V4L2_VP9_SEGMENTATION_FLAG_##x))
+
+/*
+ * struct vdec_vp9_slice_frame_ctx - vp9 prob tables footprint
+ */
+struct vdec_vp9_slice_frame_ctx {
+	struct {
+		u8 probs[6][3];
+		u8 padding[2];
+	} coef_probs[4][2][2][6];
+
+	u8 y_mode_prob[4][16];
+	u8 switch_interp_prob[4][16];
+	u8 seg[32];  /* ignore */
+	u8 comp_inter_prob[16];
+	u8 comp_ref_prob[16];
+	u8 single_ref_prob[5][2];
+	u8 single_ref_prob_padding[6];
+
+	u8 joint[3];
+	u8 joint_padding[13];
+	struct {
+		u8 sign;
+		u8 classes[10];
+		u8 padding[5];
+	} sign_classes[2];
+	struct {
+		u8 class0[1];
+		u8 bits[10];
+		u8 padding[5];
+	} class0_bits[2];
+	struct {
+		u8 class0_fp[2][3];
+		u8 fp[3];
+		u8 class0_hp;
+		u8 hp;
+		u8 padding[5];
+	} class0_fp_hp[2];
+
+	u8 uv_mode_prob[10][16];
+	u8 uv_mode_prob_padding[2][16];
+
+	u8 partition_prob[16][4];
+
+	u8 inter_mode_probs[7][4];
+	u8 skip_probs[4];
+
+	u8 tx_p8x8[2][4];
+	u8 tx_p16x16[2][4];
+	u8 tx_p32x32[2][4];
+	u8 intra_inter_prob[8];
+};
+
+/*
+ * struct vdec_vp9_slice_frame_counts - vp9 counts tables footprint
+ */
+struct vdec_vp9_slice_frame_counts {
+	union {
+		struct {
+			u32 band_0[3];
+			u32 padding0[1];
+			u32 band_1_5[5][6];
+			u32 padding1[2];
+		} eob_branch[4][2][2];
+		u32 eob_branch_space[256 * 4];
+	};
+
+	struct {
+		u32 band_0[3][4];
+		u32 band_1_5[5][6][4];
+	} coef_probs[4][2][2];
+
+	u32 intra_inter[4][2];
+	u32 comp_inter[5][2];
+	u32 comp_inter_padding[2];
+	u32 comp_ref[5][2];
+	u32 comp_ref_padding[2];
+	u32 single_ref[5][2][2];
+	u32 inter_mode[7][4];
+	u32 y_mode[4][12];
+	u32 uv_mode[10][10];
+	u32 partition[16][4];
+	u32 switchable_interp[4][4];
+
+	u32 tx_p8x8[2][2];
+	u32 tx_p16x16[2][4];
+	u32 tx_p32x32[2][4];
+
+	u32 skip[3][4];
+
+	u32 joint[4];
+
+	struct {
+		u32 sign[2];
+		u32 class0[2];
+		u32 classes[12];
+		u32 bits[10][2];
+		u32 padding[4];
+		u32 class0_fp[2][4];
+		u32 fp[4];
+		u32 class0_hp[2];
+		u32 hp[2];
+	} mvcomp[2];
+
+	u32 reserved[126][4];
+};
+
+/*
+ * struct vdec_vp9_slice_uncompressed_header - vp9 uncompressed header syntax
+ *                                             used for decoding
+ */
+struct vdec_vp9_slice_uncompressed_header {
+	u8 profile;
+	u8 last_frame_type;
+	u8 frame_type;
+
+	u8 last_show_frame;
+	u8 show_frame;
+	u8 error_resilient_mode;
+
+	u8 bit_depth;
+	u8 padding0[1];
+	u16 last_frame_width;
+	u16 last_frame_height;
+	u16 frame_width;
+	u16 frame_height;
+
+	u8 intra_only;
+	u8 reset_frame_context;
+	u8 ref_frame_sign_bias[4];
+	u8 allow_high_precision_mv;
+	u8 interpolation_filter;
+
+	u8 refresh_frame_context;
+	u8 frame_parallel_decoding_mode;
+	u8 frame_context_idx;
+
+	/* loop_filter_params */
+	u8 loop_filter_level;
+	u8 loop_filter_sharpness;
+	u8 loop_filter_delta_enabled;
+	s8 loop_filter_ref_deltas[4];
+	s8 loop_filter_mode_deltas[2];
+
+	/* quantization_params */
+	u8 base_q_idx;
+	s8 delta_q_y_dc;
+	s8 delta_q_uv_dc;
+	s8 delta_q_uv_ac;
+
+	/* segmentation_params */
+	u8 segmentation_enabled;
+	u8 segmentation_update_map;
+	u8 segmentation_tree_probs[7];
+	u8 padding1[1];
+	u8 segmentation_temporal_udpate;
+	u8 segmentation_pred_prob[3];
+	u8 segmentation_update_data;
+	u8 segmentation_abs_or_delta_update;
+	u8 feature_enabled[8];
+	s16 feature_value[8][4];
+
+	/* tile_info */
+	u8 tile_cols_log2;
+	u8 tile_rows_log2;
+	u8 padding2[2];
+
+	u16 uncompressed_header_size;
+	u16 header_size_in_bytes;
+
+	/* LAT OUT, CORE IN */
+	u32 dequant[8][4];
+};
+
+/*
+ * struct vdec_vp9_slice_compressed_header - vp9 compressed header syntax
+ *                                           used for decoding.
+ */
+struct vdec_vp9_slice_compressed_header {
+	u8 tx_mode;
+	u8 ref_mode;
+	u8 comp_fixed_ref;
+	u8 comp_var_ref[2];
+	u8 padding[3];
+};
+
+/*
+ * struct vdec_vp9_slice_tiles - vp9 tile syntax
+ */
+struct vdec_vp9_slice_tiles {
+	u32 size[4][64];
+	u32 mi_rows[4];
+	u32 mi_cols[64];
+	u8 actual_rows;
+	u8 padding[7];
+};
+
+/*
+ * struct vdec_vp9_slice_reference - vp9 reference frame information
+ */
+struct vdec_vp9_slice_reference {
+	u16 frame_width;
+	u16 frame_height;
+	u8 bit_depth;
+	u8 subsampling_x;
+	u8 subsampling_y;
+	u8 padding;
+};
+
+/*
+ * struct vdec_vp9_slice_frame - vp9 syntax used for decoding
+ */
+struct vdec_vp9_slice_frame {
+	struct vdec_vp9_slice_uncompressed_header uh;
+	struct vdec_vp9_slice_compressed_header ch;
+	struct vdec_vp9_slice_tiles tiles;
+	struct vdec_vp9_slice_reference ref[3];
+};
+
+/*
+ * struct vdec_vp9_slice_init_vsi - VSI used to initialize instance
+ */
+struct vdec_vp9_slice_init_vsi {
+	unsigned int architecture;
+	unsigned int reserved;
+	u64 core_vsi;
+	/* default frame context's position in MicroP */
+	u64 default_frame_ctx;
+};
+
+/**
+ * struct vdec_vp9_slice_mem - memory address and size
+ */
+struct vdec_vp9_slice_mem {
+	union {
+		u64 buf;
+		dma_addr_t dma_addr;
+	};
+	union {
+		size_t size;
+		dma_addr_t dma_addr_end;
+		u64 padding;
+	};
+};
+
+/**
+ * struct vdec_vp9_slice_bs - input buffer for decoding
+ */
+struct vdec_vp9_slice_bs {
+	struct vdec_vp9_slice_mem buf;
+	struct vdec_vp9_slice_mem frame;
+};
+
+/**
+ * struct vdec_vp9_slice_fb - frame buffer for decoding
+ */
+struct vdec_vp9_slice_fb {
+	struct vdec_vp9_slice_mem y;
+	struct vdec_vp9_slice_mem c;
+};
+
+/**
+ * struct vdec_vp9_slice_state - decoding state
+ */
+struct vdec_vp9_slice_state {
+	int err;
+	unsigned int full;
+	unsigned int timeout;
+	unsigned int perf;
+
+	unsigned int crc[12];
+};
+
+/*
+ * struct vdec_vp9_slice_vsi - exchange decoding information
+ *                             between Main CPU and MicroP
+ * @bs          : input buffer
+ * @fb          : output buffer
+ * @ref         : 3 reference buffers
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @ube         : general buffer
+ * @trans       : trans buffer position in general buffer
+ * @err_map     : error buffer
+ * @row_info    : row info buffer
+ * @frame       : decoding syntax
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_vsi {
+	/* used in LAT stage */
+	struct vdec_vp9_slice_bs bs;
+	/* used in Core stage */
+	struct vdec_vp9_slice_fb fb;
+	struct vdec_vp9_slice_fb ref[3];
+
+	struct vdec_vp9_slice_mem mv[2];
+	struct vdec_vp9_slice_mem seg[2];
+	struct vdec_vp9_slice_mem tile;
+	struct vdec_vp9_slice_mem prob;
+	struct vdec_vp9_slice_mem counts;
+
+	/* LAT stage's output, Core stage's input */
+	struct vdec_vp9_slice_mem ube;
+	struct vdec_vp9_slice_mem trans;
+	struct vdec_vp9_slice_mem err_map;
+	struct vdec_vp9_slice_mem row_info;
+
+	/* decoding parameters */
+	struct vdec_vp9_slice_frame frame;
+
+	struct vdec_vp9_slice_state state;
+};
+
+/**
+ * struct vdec_vp9_slice_pfc - per-frame context that contains a local vsi.
+ *                             pass it from lat to core
+ * @vsi         : local vsi. copy to/from remote vsi before/after decoding
+ * @ref_idx     : reference buffer index
+ * @seq         : picture sequence
+ * @state       : decoding state
+ */
+struct vdec_vp9_slice_pfc {
+	struct vdec_vp9_slice_vsi vsi;
+
+	u64 ref_idx[3];
+
+	int seq;
+
+	/* LAT/Core CRC */
+	struct vdec_vp9_slice_state state[2];
+};
+
+/*
+ * enum vdec_vp9_slice_resolution_level
+ */
+enum vdec_vp9_slice_resolution_level {
+	VP9_RES_NONE,
+	VP9_RES_FHD,
+	VP9_RES_4K,
+	VP9_RES_8K,
+};
+
+/*
+ * struct vdec_vp9_slice_ref - picture's width & height should kept
+ *                             for later decoding as reference picture
+ */
+struct vdec_vp9_slice_ref {
+	unsigned int width;
+	unsigned int height;
+};
+
+/**
+ * struct vdec_vp9_slice_instance - represent one vp9 instance
+ * @ctx         : pointer to codec's context
+ * @vpu         : VPU instance
+ * @seq         : global picture sequence
+ * @level       : level of current resolution
+ * @width       : width of last picture
+ * @height      : height of last picture
+ * @frame_type  : frame_type of last picture
+ * @irq         : irq to Main CPU or MicroP
+ * @show_frame  : show_frame of last picture
+ * @dpb         : picture information (width/height) for reference
+ * @mv          : mv working buffer
+ * @seg         : segmentation working buffer
+ * @tile        : tile buffer
+ * @prob        : prob table buffer, used to set/update prob table
+ * @counts      : counts table buffer, used to update prob table
+ * @frame_ctx   : 4 frame context according to VP9 Spec
+ * @dirty       : state of each frame context
+ * @init_vsi    : vsi used for initialized VP9 instance
+ * @vsi         : vsi used for decoding/flush ...
+ * @core_vsi    : vsi used for Core stage
+ */
+struct vdec_vp9_slice_instance {
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+
+	int seq;
+
+	enum vdec_vp9_slice_resolution_level level;
+
+	/* for resolution change and get_pic_info */
+	unsigned int width;
+	unsigned int height;
+
+	/* for last_frame_type */
+	unsigned int frame_type;
+	unsigned int irq;
+
+	unsigned int show_frame;
+
+	/* maintain vp9 reference frame state */
+	struct vdec_vp9_slice_ref dpb[VB2_MAX_FRAME];
+
+	/*
+	 * normal working buffers
+	 * mv[0]/seg[0]/tile/prob/counts is used for LAT
+	 * mv[1]/seg[1] is used for CORE
+	 */
+	struct mtk_vcodec_mem mv[2];
+	struct mtk_vcodec_mem seg[2];
+	struct mtk_vcodec_mem tile;
+	struct mtk_vcodec_mem prob;
+	struct mtk_vcodec_mem counts;
+
+	/* 4 prob tables */
+	struct vdec_vp9_slice_frame_ctx frame_ctx[4];
+	unsigned char dirty[4];
+
+	/* MicroP vsi */
+	union {
+		struct vdec_vp9_slice_init_vsi *init_vsi;
+		struct vdec_vp9_slice_vsi *vsi;
+	};
+	struct vdec_vp9_slice_vsi *core_vsi;
+};
+
+/*
+ * (2, (0, (1, 3)))
+ * max level = 2
+ */
+static const signed char vdec_vp9_slice_inter_mode_tree[6] = {
+	-2, 2, 0, 4, -1, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_intra_mode_tree[18] = {
+	0, 2, -9, 4, -1, 6, 8, 12, -2, 10, -4, -5, -3, 14, -8, 16, -6, -7
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_partition_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 1 */
+static const signed char vdec_vp9_slice_switchable_interp_tree[4] = {
+	0, 2, -1, -2
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_joint_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/* max level = 6 */
+static const signed char vdec_vp9_slice_mv_class_tree[20] = {
+	0, 2, -1, 4, 6, 8, -2, -3, 10, 12,
+	-4, -5, -6, 14, 16, 18, -7, -8, -9, -10
+};
+
+/* max level = 0 */
+static const signed char vdec_vp9_slice_mv_class0_tree[2] = {
+	0, -1
+};
+
+/* max level = 2 */
+static const signed char vdec_vp9_slice_mv_fp_tree[6] = {
+	0, 2, -1, 4, -2, -3
+};
+
+/*
+ * all VP9 instances could share this default frame context.
+ */
+static struct vdec_vp9_slice_frame_ctx *vdec_vp9_slice_default_frame_ctx;
+static DEFINE_MUTEX(vdec_vp9_slice_frame_ctx_lock);
+
+static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf);
+
+static int vdec_vp9_slice_init_default_frame_ctx(struct vdec_vp9_slice_instance *instance)
+{
+	struct vdec_vp9_slice_frame_ctx *remote_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret = 0;
+
+	ctx = instance->ctx;
+	vsi = instance->vpu.vsi;
+	if (!ctx || !vsi)
+		return -EINVAL;
+
+	remote_frame_ctx = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+						     (u32)vsi->default_frame_ctx);
+	if (!remote_frame_ctx) {
+		mtk_vcodec_err(instance, "failed to map default frame ctx\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&vdec_vp9_slice_frame_ctx_lock);
+	if (vdec_vp9_slice_default_frame_ctx)
+		goto out;
+
+	frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_KERNEL);
+	if (!frame_ctx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	memcpy_fromio(frame_ctx, remote_frame_ctx, sizeof(*frame_ctx));
+	vdec_vp9_slice_default_frame_ctx = frame_ctx;
+
+out:
+	mutex_unlock(&vdec_vp9_slice_frame_ctx_lock);
+
+	return ret;
+}
+
+static int vdec_vp9_slice_alloc_working_buffer(struct vdec_vp9_slice_instance *instance,
+					       struct vdec_vp9_slice_vsi *vsi)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	enum vdec_vp9_slice_resolution_level level;
+	/* super blocks */
+	unsigned int max_sb_w;
+	unsigned int max_sb_h;
+	unsigned int max_w;
+	unsigned int max_h;
+	unsigned int w;
+	unsigned int h;
+	size_t size;
+	int ret;
+	int i;
+
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+
+	if (w > VCODEC_DEC_4K_CODED_WIDTH ||
+	    h > VCODEC_DEC_4K_CODED_HEIGHT) {
+		/* 8K? */
+		return -EINVAL;
+	} else if (w > MTK_VDEC_MAX_W || h > MTK_VDEC_MAX_H) {
+		/* 4K */
+		level = VP9_RES_4K;
+		max_w = VCODEC_DEC_4K_CODED_WIDTH;
+		max_h = VCODEC_DEC_4K_CODED_HEIGHT;
+	} else {
+		/* FHD */
+		level = VP9_RES_FHD;
+		max_w = MTK_VDEC_MAX_W;
+		max_h = MTK_VDEC_MAX_H;
+	}
+
+	if (level == instance->level)
+		return 0;
+
+	mtk_vcodec_debug(instance, "resolution level changed, from %u to %u, %ux%u",
+			 instance->level, level, w, h);
+
+	max_sb_w = DIV_ROUND_UP(max_w, 64);
+	max_sb_h = DIV_ROUND_UP(max_h, 64);
+	ret = -ENOMEM;
+
+	/*
+	 * Lat-flush must wait core idle, otherwise core will
+	 * use released buffers
+	 */
+
+	size = (max_sb_w * max_sb_h + 2) * 576;
+	for (i = 0; i < 2; i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+		instance->mv[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->mv[i]))
+			goto err;
+	}
+
+	size = (max_sb_w * max_sb_h * 32) + 256;
+	for (i = 0; i < 2; i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+		instance->seg[i].size = size;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->seg[i]))
+			goto err;
+	}
+
+	if (!instance->tile.va) {
+		instance->tile.size = VP9_TILE_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->tile))
+			goto err;
+	}
+
+	if (!instance->prob.va) {
+		instance->prob.size = VP9_PROB_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->prob))
+			goto err;
+	}
+
+	if (!instance->counts.va) {
+		instance->counts.size = VP9_COUNTS_BUF_SIZE;
+		if (mtk_vcodec_mem_alloc(ctx, &instance->counts))
+			goto err;
+	}
+
+	instance->level = level;
+	return 0;
+
+err:
+	instance->level = VP9_RES_NONE;
+	return ret;
+}
+
+static void vdec_vp9_slice_free_working_buffer(struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(instance->mv); i++) {
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+	}
+	for (i = 0; i < ARRAY_SIZE(instance->seg); i++) {
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+	}
+	if (instance->tile.va)
+		mtk_vcodec_mem_free(ctx, &instance->tile);
+	if (instance->prob.va)
+		mtk_vcodec_mem_free(ctx, &instance->prob);
+	if (instance->counts.va)
+		mtk_vcodec_mem_free(ctx, &instance->counts);
+
+	instance->level = VP9_RES_NONE;
+}
+
+static void vdec_vp9_slice_vsi_from_remote(struct vdec_vp9_slice_vsi *vsi,
+					   struct vdec_vp9_slice_vsi *remote_vsi,
+					   int skip)
+{
+	struct vdec_vp9_slice_frame *rf;
+	struct vdec_vp9_slice_frame *f;
+
+	/*
+	 * compressed header
+	 * dequant
+	 * buffer position
+	 * decode state
+	 */
+	if (!skip) {
+		rf = &remote_vsi->frame;
+		f = &vsi->frame;
+		memcpy_fromio(&f->ch, &rf->ch, sizeof(f->ch));
+		memcpy_fromio(&f->uh.dequant, &rf->uh.dequant, sizeof(f->uh.dequant));
+		memcpy_fromio(&vsi->trans, &remote_vsi->trans, sizeof(vsi->trans));
+	}
+
+	memcpy_fromio(&vsi->state, &remote_vsi->state, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_vsi_to_remote(struct vdec_vp9_slice_vsi *vsi,
+					 struct vdec_vp9_slice_vsi *remote_vsi)
+{
+	memcpy_toio(remote_vsi, vsi, sizeof(*vsi));
+}
+
+static int vdec_vp9_slice_tile_offset(int idx, int mi_num, int tile_log2)
+{
+	int sbs = (mi_num + 7) >> 3;
+	int offset = ((idx * sbs) >> tile_log2) << 3;
+
+	return offset < mi_num ? offset : mi_num;
+}
+
+static int vdec_vp9_slice_setup_lat_from_src_buf(struct vdec_vp9_slice_instance *instance,
+						 struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	src = v4l2_m2m_next_src_buf(instance->ctx->m2m_ctx);
+	if (!src)
+		return -EINVAL;
+
+	dst = &lat_buf->ts_info;
+	v4l2_m2m_buf_copy_metadata(src, dst, true);
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_hdr(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_vp9_slice_uncompressed_header *uh,
+				     struct v4l2_ctrl_vp9_frame *hdr)
+{
+	int i;
+
+	uh->profile = hdr->profile;
+	uh->last_frame_type = instance->frame_type;
+	uh->frame_type = !HDR_FLAG(KEY_FRAME);
+	uh->last_show_frame = instance->show_frame;
+	uh->show_frame = HDR_FLAG(SHOW_FRAME);
+	uh->error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	uh->bit_depth = hdr->bit_depth;
+	uh->last_frame_width = instance->width;
+	uh->last_frame_height = instance->height;
+	uh->frame_width = hdr->frame_width_minus_1 + 1;
+	uh->frame_height = hdr->frame_height_minus_1 + 1;
+	uh->intra_only = HDR_FLAG(INTRA_ONLY);
+	/* map v4l2 enum to values defined in VP9 spec for firmware */
+	switch (hdr->reset_frame_context) {
+	case V4L2_VP9_RESET_FRAME_CTX_NONE:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_SPEC:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_SPEC;
+		break;
+	case V4L2_VP9_RESET_FRAME_CTX_ALL:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_ALL;
+		break;
+	default:
+		uh->reset_frame_context = VP9_RESET_FRAME_CONTEXT_NONE0;
+		break;
+	}
+	/*
+	 * ref_frame_sign_bias specifies the intended direction
+	 * of the motion vector in time for each reference frame.
+	 * - INTRA_FRAME = 0,
+	 * - LAST_FRAME = 1,
+	 * - GOLDEN_FRAME = 2,
+	 * - ALTREF_FRAME = 3,
+	 * ref_frame_sign_bias[INTRA_FRAME] is always 0
+	 * and VDA only passes another 3 directions
+	 */
+	uh->ref_frame_sign_bias[0] = 0;
+	for (i = 0; i < 3; i++)
+		uh->ref_frame_sign_bias[i + 1] =
+			!!(hdr->ref_frame_sign_bias & (1 << i));
+	uh->allow_high_precision_mv = HDR_FLAG(ALLOW_HIGH_PREC_MV);
+	uh->interpolation_filter = hdr->interpolation_filter;
+	uh->refresh_frame_context = HDR_FLAG(REFRESH_FRAME_CTX);
+	uh->frame_parallel_decoding_mode = HDR_FLAG(PARALLEL_DEC_MODE);
+	uh->frame_context_idx = hdr->frame_context_idx;
+
+	/* tile info */
+	uh->tile_cols_log2 = hdr->tile_cols_log2;
+	uh->tile_rows_log2 = hdr->tile_rows_log2;
+
+	uh->uncompressed_header_size = hdr->uncompressed_header_size;
+	uh->header_size_in_bytes = hdr->compressed_header_size;
+}
+
+static void vdec_vp9_slice_setup_frame_ctx(struct vdec_vp9_slice_instance *instance,
+					   struct vdec_vp9_slice_uncompressed_header *uh,
+					   struct v4l2_ctrl_vp9_frame *hdr)
+{
+	int error_resilient_mode;
+	int reset_frame_context;
+	int key_frame;
+	int intra_only;
+	int i;
+
+	key_frame = HDR_FLAG(KEY_FRAME);
+	intra_only = HDR_FLAG(INTRA_ONLY);
+	error_resilient_mode = HDR_FLAG(ERROR_RESILIENT);
+	reset_frame_context = uh->reset_frame_context;
+
+	/*
+	 * according to "6.2 Uncompressed header syntax" in
+	 * "VP9 Bitstream & Decoding Process Specification",
+	 * reset @frame_context_idx when (FrameIsIntra || error_resilient_mode)
+	 */
+	if (key_frame || intra_only || error_resilient_mode) {
+		/*
+		 * @reset_frame_context specifies
+		 * whether the frame context should be
+		 * reset to default values:
+		 * 0 or 1 means do not reset any frame context
+		 * 2 resets just the context specified in the frame header
+		 * 3 resets all contexts
+		 */
+		if (key_frame || error_resilient_mode ||
+		    reset_frame_context == 3) {
+			/* use default table */
+			for (i = 0; i < 4; i++)
+				instance->dirty[i] = 0;
+		} else if (reset_frame_context == 2) {
+			instance->dirty[uh->frame_context_idx] = 0;
+		}
+		uh->frame_context_idx = 0;
+	}
+}
+
+static void vdec_vp9_slice_setup_loop_filter(struct vdec_vp9_slice_uncompressed_header *uh,
+					     struct v4l2_vp9_loop_filter *lf)
+{
+	int i;
+
+	uh->loop_filter_level = lf->level;
+	uh->loop_filter_sharpness = lf->sharpness;
+	uh->loop_filter_delta_enabled = LF_FLAG(DELTA_ENABLED);
+	for (i = 0; i < 4; i++)
+		uh->loop_filter_ref_deltas[i] = lf->ref_deltas[i];
+	for (i = 0; i < 2; i++)
+		uh->loop_filter_mode_deltas[i] = lf->mode_deltas[i];
+}
+
+static void vdec_vp9_slice_setup_quantization(struct vdec_vp9_slice_uncompressed_header *uh,
+					      struct v4l2_vp9_quantization *quant)
+{
+	uh->base_q_idx = quant->base_q_idx;
+	uh->delta_q_y_dc = quant->delta_q_y_dc;
+	uh->delta_q_uv_dc = quant->delta_q_uv_dc;
+	uh->delta_q_uv_ac = quant->delta_q_uv_ac;
+}
+
+static void vdec_vp9_slice_setup_segmentation(struct vdec_vp9_slice_uncompressed_header *uh,
+					      struct v4l2_vp9_segmentation *seg)
+{
+	int i;
+	int j;
+
+	uh->segmentation_enabled = SEG_FLAG(ENABLED);
+	uh->segmentation_update_map = SEG_FLAG(UPDATE_MAP);
+	for (i = 0; i < 7; i++)
+		uh->segmentation_tree_probs[i] = seg->tree_probs[i];
+	uh->segmentation_temporal_udpate = SEG_FLAG(TEMPORAL_UPDATE);
+	for (i = 0; i < 3; i++)
+		uh->segmentation_pred_prob[i] = seg->pred_probs[i];
+	uh->segmentation_update_data = SEG_FLAG(UPDATE_DATA);
+	uh->segmentation_abs_or_delta_update = SEG_FLAG(ABS_OR_DELTA_UPDATE);
+	for (i = 0; i < 8; i++) {
+		uh->feature_enabled[i] = seg->feature_enabled[i];
+		for (j = 0; j < 4; j++)
+			uh->feature_value[i][j] = seg->feature_data[i][j];
+	}
+}
+
+static int vdec_vp9_slice_setup_tile(struct vdec_vp9_slice_vsi *vsi,
+				     struct v4l2_ctrl_vp9_frame *hdr)
+{
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_rows;
+	unsigned int mi_cols;
+	struct vdec_vp9_slice_tiles *tiles;
+	int offset;
+	int start;
+	int end;
+	int i;
+
+	rows_log2 = hdr->tile_rows_log2;
+	cols_log2 = hdr->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+	tiles = &vsi->frame.tiles;
+	tiles->actual_rows = 0;
+
+	if (rows > 4 || cols > 64)
+		return -EINVAL;
+
+	/* setup mi rows/cols information */
+	mi_rows = (hdr->frame_height_minus_1 + 1 + 7) >> 3;
+	mi_cols = (hdr->frame_width_minus_1 + 1 + 7) >> 3;
+
+	for (i = 0; i < rows; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_rows, rows_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_rows, rows_log2);
+		offset = end - start;
+		tiles->mi_rows[i] = (offset + 7) >> 3;
+		if (tiles->mi_rows[i])
+			tiles->actual_rows++;
+	}
+
+	for (i = 0; i < cols; i++) {
+		start = vdec_vp9_slice_tile_offset(i, mi_cols, cols_log2);
+		end = vdec_vp9_slice_tile_offset(i + 1, mi_cols, cols_log2);
+		offset = end - start;
+		tiles->mi_cols[i] = (offset + 7) >> 3;
+	}
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_state(struct vdec_vp9_slice_vsi *vsi)
+{
+	memset(&vsi->state, 0, sizeof(vsi->state));
+}
+
+static void vdec_vp9_slice_setup_ref_idx(struct vdec_vp9_slice_pfc *pfc,
+					 struct v4l2_ctrl_vp9_frame *hdr)
+{
+	pfc->ref_idx[0] = hdr->last_frame_ts;
+	pfc->ref_idx[1] = hdr->golden_frame_ts;
+	pfc->ref_idx[2] = hdr->alt_frame_ts;
+}
+
+static int vdec_vp9_slice_setup_pfc(struct vdec_vp9_slice_instance *instance,
+				    struct vdec_vp9_slice_pfc *pfc)
+{
+	struct v4l2_ctrl_vp9_frame *hdr;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	struct v4l2_ctrl *hdr_ctrl;
+	struct vdec_vp9_slice_vsi *vsi;
+	int ret;
+
+	/* frame header */
+	hdr_ctrl = v4l2_ctrl_find(&instance->ctx->ctrl_hdl, V4L2_CID_STATELESS_VP9_FRAME);
+	if (!hdr_ctrl || !hdr_ctrl->p_cur.p)
+		return -EINVAL;
+
+	hdr = hdr_ctrl->p_cur.p;
+	vsi = &pfc->vsi;
+	uh = &vsi->frame.uh;
+
+	/* setup vsi information */
+	vdec_vp9_slice_setup_hdr(instance, uh, hdr);
+	vdec_vp9_slice_setup_frame_ctx(instance, uh, hdr);
+	vdec_vp9_slice_setup_loop_filter(uh, &hdr->lf);
+	vdec_vp9_slice_setup_quantization(uh, &hdr->quant);
+	vdec_vp9_slice_setup_segmentation(uh, &hdr->seg);
+	ret = vdec_vp9_slice_setup_tile(vsi, hdr);
+	if (ret)
+		return ret;
+	vdec_vp9_slice_setup_state(vsi);
+
+	/* core stage needs buffer index to get ref y/c ... */
+	vdec_vp9_slice_setup_ref_idx(pfc, hdr);
+
+	pfc->seq = instance->seq;
+	instance->seq++;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat_buffer(struct vdec_vp9_slice_instance *instance,
+					   struct vdec_vp9_slice_vsi *vsi,
+					   struct mtk_vcodec_mem *bs,
+					   struct vdec_lat_buf *lat_buf)
+{
+	int i;
+
+	vsi->bs.buf.dma_addr = bs->dma_addr;
+	vsi->bs.buf.size = bs->size;
+	vsi->bs.frame.dma_addr = bs->dma_addr;
+	vsi->bs.frame.size = bs->size;
+
+	for (i = 0; i < 2; i++) {
+		vsi->mv[i].dma_addr = instance->mv[i].dma_addr;
+		vsi->mv[i].size = instance->mv[i].size;
+	}
+	for (i = 0; i < 2; i++) {
+		vsi->seg[i].dma_addr = instance->seg[i].dma_addr;
+		vsi->seg[i].size = instance->seg[i].size;
+	}
+	vsi->tile.dma_addr = instance->tile.dma_addr;
+	vsi->tile.size = instance->tile.size;
+	vsi->prob.dma_addr = instance->prob.dma_addr;
+	vsi->prob.size = instance->prob.size;
+	vsi->counts.dma_addr = instance->counts.dma_addr;
+	vsi->counts.size = instance->counts.size;
+
+	vsi->ube.dma_addr = lat_buf->ctx->msg_queue.wdma_addr.dma_addr;
+	vsi->ube.size = lat_buf->ctx->msg_queue.wdma_addr.size;
+	vsi->trans.dma_addr = lat_buf->ctx->msg_queue.wdma_wptr_addr;
+	/* used to store trans end */
+	vsi->trans.dma_addr_end = lat_buf->ctx->msg_queue.wdma_rptr_addr;
+	vsi->err_map.dma_addr = lat_buf->wdma_err_addr.dma_addr;
+	vsi->err_map.size = lat_buf->wdma_err_addr.size;
+
+	vsi->row_info.buf = 0;
+	vsi->row_info.size = 0;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_prob_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+
+	mtk_vcodec_debug(instance, "ctx dirty %u idx %d\n",
+			 instance->dirty[uh->frame_context_idx],
+			 uh->frame_context_idx);
+
+	if (instance->dirty[uh->frame_context_idx])
+		frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	else
+		frame_ctx = vdec_vp9_slice_default_frame_ctx;
+	memcpy(instance->prob.va, frame_ctx, sizeof(*frame_ctx));
+
+	return 0;
+}
+
+static void vdec_vp9_slice_setup_seg_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct mtk_vcodec_mem *buf)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	/* reset segment buffer */
+	uh = &vsi->frame.uh;
+	if (uh->frame_type == 0 ||
+	    uh->intra_only ||
+	    uh->error_resilient_mode ||
+	    uh->frame_width != instance->width ||
+	    uh->frame_height != instance->height) {
+		mtk_vcodec_debug(instance, "reset seg\n");
+		memset(buf->va, 0, buf->size);
+	}
+}
+
+/*
+ * parse tiles according to `6.4 Decode tiles syntax`
+ * in "vp9-bitstream-specification"
+ *
+ * frame contains uncompress header, compressed header and several tiles.
+ * this function parses tiles' position and size, stores them to tile buffer
+ * for decoding.
+ */
+static int vdec_vp9_slice_setup_tile_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct mtk_vcodec_mem *bs)
+{
+	struct vdec_vp9_slice_uncompressed_header *uh;
+	unsigned int rows_log2;
+	unsigned int cols_log2;
+	unsigned int rows;
+	unsigned int cols;
+	unsigned int mi_row;
+	unsigned int mi_col;
+	unsigned int offset;
+	unsigned int pa;
+	unsigned int size;
+	struct vdec_vp9_slice_tiles *tiles;
+	unsigned char *pos;
+	unsigned char *end;
+	unsigned char *va;
+	unsigned int *tb;
+	int i;
+	int j;
+
+	uh = &vsi->frame.uh;
+	rows_log2 = uh->tile_rows_log2;
+	cols_log2 = uh->tile_cols_log2;
+	rows = 1 << rows_log2;
+	cols = 1 << cols_log2;
+
+	if (rows > 4 || cols > 64) {
+		mtk_vcodec_err(instance, "tile_rows %u tile_cols %u\n",
+			       rows, cols);
+		return -EINVAL;
+	}
+
+	offset = uh->uncompressed_header_size +
+		uh->header_size_in_bytes;
+	if (bs->size <= offset) {
+		mtk_vcodec_err(instance, "bs size %zu tile offset %u\n",
+			       bs->size, offset);
+		return -EINVAL;
+	}
+
+	tiles = &vsi->frame.tiles;
+	/* setup tile buffer */
+
+	va = (unsigned char *)bs->va;
+	pos = va + offset;
+	end = va + bs->size;
+	/* truncated */
+	pa = (unsigned int)bs->dma_addr + offset;
+	tb = instance->tile.va;
+	for (i = 0; i < rows; i++) {
+		for (j = 0; j < cols; j++) {
+			if (i == rows - 1 &&
+			    j == cols - 1) {
+				size = (unsigned int)(end - pos);
+			} else {
+				if (end - pos < 4)
+					return -EINVAL;
+
+				size = (pos[0] << 24) | (pos[1] << 16) |
+					(pos[2] << 8) | pos[3];
+				pos += 4;
+				pa += 4;
+				offset += 4;
+				if (end - pos < size)
+					return -EINVAL;
+			}
+			tiles->size[i][j] = size;
+			if (tiles->mi_rows[i]) {
+				*tb++ = (size << 3) + ((offset << 3) & 0x7f);
+				*tb++ = pa & ~0xf;
+				*tb++ = (pa << 3) & 0x7f;
+				mi_row = (tiles->mi_rows[i] - 1) & 0x1ff;
+				mi_col = (tiles->mi_cols[j] - 1) & 0x3f;
+				*tb++ = (mi_row << 6) + mi_col;
+			}
+			pos += size;
+			pa += size;
+			offset += size;
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_lat(struct vdec_vp9_slice_instance *instance,
+				    struct mtk_vcodec_mem *bs,
+				    struct vdec_lat_buf *lat_buf,
+				    struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	ret = vdec_vp9_slice_setup_lat_from_src_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_pfc(instance, pfc);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_alloc_working_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_lat_buffer(instance, vsi, bs, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[0]);
+
+	/* setup prob/tile buffers for LAT */
+
+	ret = vdec_vp9_slice_setup_prob_buffer(instance, vsi);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_tile_buffer(instance, vsi, bs);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	return ret;
+}
+
+/* implement merge prob process defined in 8.4.1 */
+static unsigned char vdec_vp9_slice_merge_prob(unsigned char pre, unsigned int ct0,
+					       unsigned int ct1, unsigned int cs,
+					       unsigned int uf)
+{
+	unsigned int den;
+	unsigned int prob;
+	unsigned int count;
+	unsigned int factor;
+
+	/*
+	 * The variable den representing the total times
+	 * this boolean has been decoded is set equal to ct0 + ct1.
+	 */
+	den = ct0 + ct1;
+	if (!den)
+		return pre;  /* => count = 0 => factor = 0 */
+	/*
+	 * The variable prob estimating the probability that
+	 * the boolean is decoded as a 0 is set equal to
+	 * (den == 0) ? 128 : Clip3(1, 255, (ct0 * 256 + (den >> 1)) / den).
+	 */
+	prob = ((ct0 << 8) + (den >> 1)) / den;
+	prob = prob < 1 ? 1 : (prob > 255 ? 255 : prob);
+	/* The variable count is set equal to Min(ct0 + ct1, countSat) */
+	count = den < cs ? den : cs;
+	/*
+	 * The variable factor is set equal to
+	 * maxUpdateFactor * count / countSat.
+	 */
+	factor = uf * count / cs;
+	/*
+	 * The return variable outProb is set equal to
+	 * Round2(preProb * (256 - factor) + prob * factor, 8).
+	 */
+	return pre + (((prob - pre) * factor + 128) >> 8);
+}
+
+static inline unsigned char vdec_vp9_slice_adapt_prob(unsigned char pre, unsigned int ct0,
+						      unsigned int ct1)
+{
+	return vdec_vp9_slice_merge_prob(pre, ct0, ct1, 20, 128);
+}
+
+/* implement merge probs process defined in 8.4.2 */
+static unsigned int vdec_vp9_slice_merge_probs(const signed char *tree, int location,
+					       unsigned char *pre_probs, unsigned int *counts,
+					       unsigned char *probs, unsigned int cs,
+					       unsigned int uf)
+{
+	int left = tree[location];
+	int right = tree[location + 1];
+	unsigned int left_count;
+	unsigned int right_count;
+
+	if (left <= 0)
+		left_count = counts[-left];
+	else
+		left_count = vdec_vp9_slice_merge_probs(tree, left, pre_probs, counts,
+							probs, cs, uf);
+
+	if (right <= 0)
+		right_count = counts[-right];
+	else
+		right_count = vdec_vp9_slice_merge_probs(tree, right, pre_probs, counts,
+							 probs, cs, uf);
+
+	/* merge left and right */
+	probs[location >> 1] =
+		vdec_vp9_slice_merge_prob(pre_probs[location >> 1],
+					  left_count, right_count, cs, uf);
+	return left_count + right_count;
+}
+
+static inline void vdec_vp9_slice_adapt_probs(const signed char *tree,
+					      unsigned char *pre_probs,
+					      unsigned int *counts,
+					      unsigned char *probs)
+{
+	vdec_vp9_slice_merge_probs(tree, 0, pre_probs, counts, probs, 20, 128);
+}
+
+/* 8.4 Probability adaptation process */
+static void vdec_vp9_slice_adapt_table(struct vdec_vp9_slice_vsi *vsi,
+				       struct vdec_vp9_slice_frame_ctx *ctx,
+				       struct vdec_vp9_slice_frame_ctx *pre_ctx,
+				       struct vdec_vp9_slice_frame_counts *counts)
+{
+	unsigned char *pp;
+	unsigned char *p;
+	unsigned int *c;
+	unsigned int *e;
+	unsigned int uf;
+	int t, i, j, k, l;
+
+	uf = 128;
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only ||
+	    vsi->frame.uh.last_frame_type)
+		uf = 112;
+
+	p = (unsigned char *)&ctx->coef_probs;
+	pp = (unsigned char *)&pre_ctx->coef_probs;
+	c = (unsigned int *)&counts->coef_probs;
+	e = (unsigned int *)&counts->eob_branch;
+
+	/* 8.4.3 Coefficient probability adaption process */
+	for (t = 0; t < 16; t++) {
+		for (((k) = 0); ((k) < 6); ((k)++)) {
+			for (l = 0; l < (k == 0 ? 3 : 6); l++) {
+				p[0] = vdec_vp9_slice_merge_prob(pp[0], c[3], e[0]
+								 - c[3], 24, uf);
+				p[1] = vdec_vp9_slice_merge_prob(pp[1],	c[0], c[1]
+								 + c[2], 24, uf);
+				p[2] = vdec_vp9_slice_merge_prob(pp[2], c[1],
+								 c[2], 24, uf);
+				p += 3;
+				pp += 3;
+				c += 4;
+				e++;
+			}
+			if (k == 0) {
+				/* 3 * 3 unused values and 2 bytes padding */
+				p += 11;
+				pp += 11;
+				e++;
+			} else {
+				/* extra 2 bytes could make 4 bytes align (3 * 6 + 2) */
+				p += 2;
+				pp += 2;
+				/* 5 * 6=30, extra 2 int */
+				if (k == 5)
+					e += 2;
+			}
+		}
+	}
+
+	if (!vsi->frame.uh.frame_type || vsi->frame.uh.intra_only)
+		return;
+
+	/* 8.4.4 Non coefficient probability adaption process */
+
+	for (i = 0; i < 4; i++) {
+		ctx->intra_inter_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->intra_inter_prob[i],
+						  counts->intra_inter[i][0],
+						  counts->intra_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_inter_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->comp_inter_prob[i],
+						  counts->comp_inter[i][0],
+						  counts->comp_inter[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		ctx->comp_ref_prob[i] =
+			vdec_vp9_slice_adapt_prob(pre_ctx->comp_ref_prob[i],
+						  counts->comp_ref[i][0],
+						  counts->comp_ref[i][1]);
+	}
+
+	for (i = 0; i < 5; i++) {
+		for (j = 0; j < 2; j++) {
+			ctx->single_ref_prob[i][j] =
+				vdec_vp9_slice_adapt_prob(pre_ctx->single_ref_prob[i][j],
+							  counts->single_ref[i][j][0],
+							  counts->single_ref[i][j][1]);
+		}
+	}
+
+	for (i = 0; i < 7; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_inter_mode_tree,
+					   &pre_ctx->inter_mode_probs[i][0],
+					   &counts->inter_mode[i][0],
+					   &ctx->inter_mode_probs[i][0]);
+	}
+
+	for (i = 0; i < 4; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+					   &pre_ctx->y_mode_prob[i][0],
+					   &counts->y_mode[i][0],
+					   &ctx->y_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 10; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_intra_mode_tree,
+					   &pre_ctx->uv_mode_prob[i][0],
+					   &counts->uv_mode[i][0],
+					   &ctx->uv_mode_prob[i][0]);
+	}
+
+	for (i = 0; i < 16; i++) {
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_partition_tree,
+					   &pre_ctx->partition_prob[i][0],
+					   &counts->partition[i][0],
+					   &ctx->partition_prob[i][0]);
+	}
+
+	if (vsi->frame.uh.interpolation_filter == 4) {
+		for (i = 0; i < 4; i++) {
+			vdec_vp9_slice_adapt_probs(vdec_vp9_slice_switchable_interp_tree,
+						   &pre_ctx->switch_interp_prob[i][0],
+						   &counts->switchable_interp[i][0],
+						   &ctx->switch_interp_prob[i][0]);
+		}
+	}
+
+	if (vsi->frame.ch.tx_mode == 4) {
+		for (i = 0; i < 2; i++) {
+			ctx->tx_p8x8[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p8x8[i][0],
+								       counts->tx_p8x8[i][0],
+								       counts->tx_p8x8[i][1]);
+			ctx->tx_p16x16[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p16x16[i][0],
+									 counts->tx_p16x16[i][0],
+									 counts->tx_p16x16[i][1] +
+									 counts->tx_p16x16[i][2]);
+			ctx->tx_p16x16[i][1] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p16x16[i][1],
+									 counts->tx_p16x16[i][1],
+									 counts->tx_p16x16[i][2]);
+			ctx->tx_p32x32[i][0] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][0],
+									 counts->tx_p32x32[i][0],
+									 counts->tx_p32x32[i][1] +
+									 counts->tx_p32x32[i][2] +
+									 counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][1] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][1],
+									 counts->tx_p32x32[i][1],
+									 counts->tx_p32x32[i][2] +
+									 counts->tx_p32x32[i][3]);
+			ctx->tx_p32x32[i][2] = vdec_vp9_slice_adapt_prob(pre_ctx->tx_p32x32[i][2],
+									 counts->tx_p32x32[i][2],
+									 counts->tx_p32x32[i][3]);
+		}
+	}
+
+	for (i = 0; i < 3; i++) {
+		ctx->skip_probs[i] = vdec_vp9_slice_adapt_prob(pre_ctx->skip_probs[i],
+							       counts->skip[i][0],
+							       counts->skip[i][1]);
+	}
+
+	vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_joint_tree,
+				   &pre_ctx->joint[0],
+				   &counts->joint[0],
+				   &ctx->joint[0]);
+
+	for (i = 0; i < 2; i++) {
+		ctx->sign_classes[i].sign = vdec_vp9_slice_adapt_prob(pre_ctx->sign_classes[i].sign,
+								      counts->mvcomp[i].sign[0],
+								      counts->mvcomp[i].sign[1]);
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class_tree,
+					   &pre_ctx->sign_classes[i].classes[0],
+					   &counts->mvcomp[i].classes[0],
+					   &ctx->sign_classes[i].classes[0]);
+
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_class0_tree,
+					   pre_ctx->class0_bits[i].class0,
+					   counts->mvcomp[i].class0,
+					   ctx->class0_bits[i].class0);
+		for (j = 0; j < 10; j++) {
+			ctx->class0_bits[i].bits[j] =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_bits[i].bits[j],
+							  counts->mvcomp[i].bits[j][0],
+							  counts->mvcomp[i].bits[j][1]);
+		}
+
+		for (j = 0; j < 2; ++j) {
+			vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+						   pre_ctx->class0_fp_hp[i].class0_fp[j],
+						   counts->mvcomp[i].class0_fp[j],
+						   ctx->class0_fp_hp[i].class0_fp[j]);
+		}
+		vdec_vp9_slice_adapt_probs(vdec_vp9_slice_mv_fp_tree,
+					   pre_ctx->class0_fp_hp[i].fp,
+					   counts->mvcomp[i].fp,
+					   ctx->class0_fp_hp[i].fp);
+		if (vsi->frame.uh.allow_high_precision_mv) {
+			ctx->class0_fp_hp[i].class0_hp =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_fp_hp[i].class0_hp,
+							  counts->mvcomp[i].class0_hp[0],
+							  counts->mvcomp[i].class0_hp[1]);
+			ctx->class0_fp_hp[i].hp =
+				vdec_vp9_slice_adapt_prob(pre_ctx->class0_fp_hp[i].hp,
+							  counts->mvcomp[i].hp[0],
+							  counts->mvcomp[i].hp[1]);
+		}
+	}
+}
+
+static int vdec_vp9_slice_update_prob(struct vdec_vp9_slice_instance *instance,
+				      struct vdec_vp9_slice_vsi *vsi)
+{
+	struct vdec_vp9_slice_frame_ctx *pre_frame_ctx;
+	struct vdec_vp9_slice_frame_ctx *frame_ctx;
+	struct vdec_vp9_slice_frame_counts *counts;
+	struct vdec_vp9_slice_uncompressed_header *uh;
+
+	uh = &vsi->frame.uh;
+	pre_frame_ctx = &instance->frame_ctx[uh->frame_context_idx];
+	frame_ctx = (struct vdec_vp9_slice_frame_ctx *)instance->prob.va;
+	counts = (struct vdec_vp9_slice_frame_counts *)instance->counts.va;
+
+	if (!uh->refresh_frame_context)
+		return 0;
+
+	if (!uh->frame_parallel_decoding_mode) {
+		/* uh->error_resilient_mode must be 0 */
+		vdec_vp9_slice_adapt_table(vsi,	frame_ctx,
+					   /* use default frame ctx? */
+					   instance->dirty[uh->frame_context_idx] ?
+					   pre_frame_ctx :
+					   vdec_vp9_slice_default_frame_ctx,
+					   counts);
+	}
+
+	memcpy(pre_frame_ctx, frame_ctx, sizeof(*frame_ctx));
+	instance->dirty[uh->frame_context_idx] = 1;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_update_lat(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_lat_buf *lat_buf,
+				     struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[0], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance, "Frame %u LAT CRC 0x%08x\n",
+			 pfc->seq, vsi->state.crc[0]);
+
+	/* buffer full, need to re-decode */
+	if (vsi->state.full) {
+		/* buffer not enough */
+		if (vsi->trans.dma_addr_end - vsi->trans.dma_addr ==
+			vsi->ube.size)
+			return -ENOMEM;
+		return -EAGAIN;
+	}
+
+	vdec_vp9_slice_update_prob(instance, vsi);
+
+	instance->width = vsi->frame.uh.frame_width;
+	instance->height = vsi->frame.uh.frame_height;
+	instance->frame_type = vsi->frame.uh.frame_type;
+	instance->show_frame = vsi->frame.uh.show_frame;
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_to_dst_buf(struct vdec_vp9_slice_instance *instance,
+						struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_v4l2_buffer *src;
+	struct vb2_v4l2_buffer *dst;
+
+	dst = v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx);
+	if (!dst)
+		return -EINVAL;
+
+	src = &lat_buf->ts_info;
+	dst->vb2_buf.timestamp = src->vb2_buf.timestamp;
+	dst->timecode = src->timecode;
+	dst->field = src->field;
+	dst->flags = src->flags;
+	dst->vb2_buf.copied_timestamp = src->vb2_buf.copied_timestamp;
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core_buffer(struct vdec_vp9_slice_instance *instance,
+					    struct vdec_vp9_slice_pfc *pfc,
+					    struct vdec_vp9_slice_vsi *vsi,
+					    struct vdec_fb *fb,
+					    struct vdec_lat_buf *lat_buf)
+{
+	struct vb2_buffer *vb;
+	struct vb2_queue *vq;
+	struct vdec_vp9_slice_reference *ref;
+	int plane;
+	int size;
+	int idx;
+	int w;
+	int h;
+	int i;
+
+	plane = instance->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes;
+	w = vsi->frame.uh.frame_width;
+	h = vsi->frame.uh.frame_height;
+	size = ALIGN(w, 64) * ALIGN(h, 64);
+
+	/* frame buffer */
+	vsi->fb.y.dma_addr = fb->base_y.dma_addr;
+	if (plane == 1)
+		vsi->fb.c.dma_addr = fb->base_y.dma_addr + size;
+	else
+		vsi->fb.c.dma_addr = fb->base_c.dma_addr;
+
+	/* reference buffers */
+	vq = v4l2_m2m_get_vq(instance->ctx->m2m_ctx,
+			     V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	if (!vq)
+		return -EINVAL;
+
+	/* get current output buffer */
+	vb = &v4l2_m2m_next_dst_buf(instance->ctx->m2m_ctx)->vb2_buf;
+	if (!vb)
+		return -EINVAL;
+
+	/* update internal buffer's width/height */
+	for (i = 0; i < vq->num_buffers; i++) {
+		if (vb == vq->bufs[i]) {
+			instance->dpb[i].width = w;
+			instance->dpb[i].height = h;
+			break;
+		}
+	}
+
+	/*
+	 * get buffer's width/height from instance
+	 * get buffer address from vb2buf
+	 */
+	for (i = 0; i < 3; i++) {
+		ref = &vsi->frame.ref[i];
+		idx = vb2_find_timestamp(vq, pfc->ref_idx[i], 0);
+		if (idx < 0) {
+			ref->frame_width = w;
+			ref->frame_height = h;
+			memset(&vsi->ref[i], 0, sizeof(vsi->ref[i]));
+		} else {
+			ref->frame_width = instance->dpb[idx].width;
+			ref->frame_height = instance->dpb[idx].height;
+			vb = vq->bufs[idx];
+			vsi->ref[i].y.dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 0);
+			if (plane == 1)
+				vsi->ref[i].c.dma_addr =
+					vsi->ref[i].y.dma_addr + size;
+			else
+				vsi->ref[i].c.dma_addr =
+					vb2_dma_contig_plane_dma_addr(vb, 1);
+		}
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_setup_core(struct vdec_vp9_slice_instance *instance,
+				     struct vdec_fb *fb,
+				     struct vdec_lat_buf *lat_buf,
+				     struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi = &pfc->vsi;
+	int ret;
+
+	vdec_vp9_slice_setup_state(vsi);
+
+	ret = vdec_vp9_slice_setup_core_to_dst_buf(instance, lat_buf);
+	if (ret)
+		goto err;
+
+	ret = vdec_vp9_slice_setup_core_buffer(instance, pfc, vsi, fb, lat_buf);
+	if (ret)
+		goto err;
+
+	vdec_vp9_slice_setup_seg_buffer(instance, vsi, &instance->seg[1]);
+
+	return 0;
+
+err:
+	return ret;
+}
+
+static int vdec_vp9_slice_update_core(struct vdec_vp9_slice_instance *instance,
+				      struct vdec_lat_buf *lat_buf,
+				      struct vdec_vp9_slice_pfc *pfc)
+{
+	struct vdec_vp9_slice_vsi *vsi;
+
+	vsi = &pfc->vsi;
+	memcpy(&pfc->state[1], &vsi->state, sizeof(vsi->state));
+
+	mtk_vcodec_debug(instance, "Frame %u Y_CRC %08x %08x %08x %08x\n",
+			 pfc->seq,
+			 vsi->state.crc[0], vsi->state.crc[1],
+			 vsi->state.crc[2], vsi->state.crc[3]);
+	mtk_vcodec_debug(instance, "Frame %u C_CRC %08x %08x %08x %08x\n",
+			 pfc->seq,
+			 vsi->state.crc[4], vsi->state.crc[5],
+			 vsi->state.crc[6], vsi->state.crc[7]);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_init_vsi *vsi;
+	int ret;
+
+	instance = kzalloc(sizeof(*instance), GFP_KERNEL);
+	if (!instance)
+		return -ENOMEM;
+
+	instance->ctx = ctx;
+	instance->vpu.id = SCP_IPI_VDEC_LAT;
+	instance->vpu.core_id = SCP_IPI_VDEC_CORE;
+	instance->vpu.ctx = ctx;
+	instance->vpu.codec_type = ctx->current_codec;
+
+	ret = vpu_dec_init(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "failed to init vpu dec, ret %d\n", ret);
+		goto error_vpu_init;
+	}
+
+	/* init vsi and global flags */
+
+	vsi = instance->vpu.vsi;
+	if (!vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+	instance->init_vsi = vsi;
+	instance->core_vsi = mtk_vcodec_fw_map_dm_addr(ctx->dev->fw_handler,
+						       (u32)vsi->core_vsi);
+	if (!instance->core_vsi) {
+		mtk_vcodec_err(instance, "failed to get VP9 core vsi\n");
+		ret = -EINVAL;
+		goto error_vsi;
+	}
+
+	instance->irq = 1;
+
+	ret = vdec_vp9_slice_init_default_frame_ctx(instance);
+	if (ret)
+		goto error_default_frame_ctx;
+
+	ctx->drv_handle = instance;
+
+	return 0;
+
+error_default_frame_ctx:
+error_vsi:
+	vpu_dec_deinit(&instance->vpu);
+error_vpu_init:
+	kfree(instance);
+	return ret;
+}
+
+static void vdec_vp9_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	if (!instance)
+		return;
+
+	vpu_dec_deinit(&instance->vpu);
+	vdec_vp9_slice_free_working_buffer(instance);
+	vdec_msg_queue_deinit(&instance->ctx->msg_queue, instance->ctx);
+	kfree(instance);
+}
+
+static int vdec_vp9_slice_flush(void *h_vdec, struct mtk_vcodec_mem *bs,
+				struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	mtk_vcodec_debug(instance, "flush ...\n");
+
+	vdec_msg_queue_wait_lat_buf_full(&instance->ctx->msg_queue);
+	return vpu_dec_reset(&instance->vpu);
+}
+
+static void vdec_vp9_slice_get_pic_info(struct vdec_vp9_slice_instance *instance)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+	unsigned int data[3];
+
+	mtk_vcodec_debug(instance, "w %u h %u\n",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h);
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&instance->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = instance->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = instance->vpu.fb_sz[1];
+}
+
+static void vdec_vp9_slice_get_dpb_size(struct vdec_vp9_slice_instance *instance,
+					unsigned int *dpb_sz)
+{
+	/* refer VP9 specification */
+	*dpb_sz = 9;
+}
+
+static void vdec_vp9_slice_get_crop_info(struct vdec_vp9_slice_instance *instance,
+					 struct v4l2_rect *cr)
+{
+	struct mtk_vcodec_ctx *ctx = instance->ctx;
+
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = ctx->picinfo.pic_w;
+	cr->height = ctx->picinfo.pic_h;
+
+	mtk_vcodec_debug(instance, "l=%d, t=%d, w=%d, h=%d\n",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static int vdec_vp9_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp9_slice_get_pic_info(instance);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		vdec_vp9_slice_get_dpb_size(instance, out);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp9_slice_get_crop_info(instance, out);
+		break;
+	default:
+		mtk_vcodec_err(instance, "invalid get parameter type=%d\n",
+			       type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_vp9_slice_lat_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				     struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp9_slice_instance *instance = h_vdec;
+	struct vdec_lat_buf *lat_buf;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct vdec_vp9_slice_vsi *vsi;
+	struct mtk_vcodec_ctx *ctx;
+	int ret;
+
+	if (!instance || !instance->ctx)
+		return -EINVAL;
+	ctx = instance->ctx;
+
+	/* init msgQ for the first time */
+	if (vdec_msg_queue_init(&ctx->msg_queue, ctx,
+				vdec_vp9_slice_core_decode,
+				sizeof(*pfc)))
+		return -ENOMEM;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vdec_vp9_slice_flush(h_vdec, bs, fb, res_chg);
+
+	lat_buf = vdec_msg_queue_dqbuf(&instance->ctx->msg_queue.lat_ctx);
+	if (!lat_buf) {
+		mtk_vcodec_err(instance, "Failed to get VP9 lat buf\n");
+		return -EBUSY;
+	}
+	pfc = (struct vdec_vp9_slice_pfc *)lat_buf->private_data;
+	if (!pfc)
+		return -EINVAL;
+	vsi = &pfc->vsi;
+
+	ret = vdec_vp9_slice_setup_lat(instance, bs, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "Failed to setup VP9 lat ret %d\n", ret);
+		return ret;
+	}
+	vdec_vp9_slice_vsi_to_remote(vsi, instance->vsi);
+
+	ret = vpu_dec_start(&instance->vpu, 0, 0);
+	if (ret) {
+		mtk_vcodec_err(instance, "Failed to dec VP9 ret %d\n", ret);
+		return ret;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx,	MTK_INST_IRQ_RECEIVED,
+						   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance, "VP9 decode timeout %d\n", ret);
+			writel(1, &instance->vsi->state.timeout);
+		}
+		vpu_dec_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(vsi, instance->vsi, 0);
+	ret = vdec_vp9_slice_update_lat(instance, lat_buf, pfc);
+
+	/* LAT trans full, no more UBE or decode timeout */
+	if (ret) {
+		mtk_vcodec_err(instance, "VP9 decode error: %d\n", ret);
+		return ret;
+	}
+
+	mtk_vcodec_debug(instance, "lat dma 1 0x%llx 0x%llx\n",
+			 pfc->vsi.trans.dma_addr, pfc->vsi.trans.dma_addr_end);
+
+	vdec_msg_queue_update_ube_wptr(&ctx->msg_queue,
+				       vsi->trans.dma_addr_end +
+				       ctx->msg_queue.wdma_addr.dma_addr);
+	vdec_msg_queue_qbuf(&ctx->dev->msg_queue_core_ctx, lat_buf);
+
+	return 0;
+}
+
+static int vdec_vp9_slice_core_decode(struct vdec_lat_buf *lat_buf)
+{
+	struct vdec_vp9_slice_instance *instance;
+	struct vdec_vp9_slice_pfc *pfc;
+	struct mtk_vcodec_ctx *ctx = NULL;
+	struct vdec_fb *fb = NULL;
+	int ret = -EINVAL;
+
+	if (!lat_buf)
+		goto err;
+
+	pfc = lat_buf->private_data;
+	ctx = lat_buf->ctx;
+	if (!pfc || !ctx)
+		goto err;
+
+	instance = ctx->drv_handle;
+	if (!instance)
+		goto err;
+
+	fb = ctx->dev->vdec_pdata->get_cap_buffer(ctx);
+	if (!fb) {
+		ret = -EBUSY;
+		goto err;
+	}
+
+	ret = vdec_vp9_slice_setup_core(instance, fb, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_setup_core\n");
+		goto err;
+	}
+	vdec_vp9_slice_vsi_to_remote(&pfc->vsi, instance->core_vsi);
+
+	ret = vpu_dec_core(&instance->vpu);
+	if (ret) {
+		mtk_vcodec_err(instance, "vpu_dec_core\n");
+		goto err;
+	}
+
+	if (instance->irq) {
+		ret = mtk_vcodec_wait_for_done_ctx(ctx, MTK_INST_IRQ_RECEIVED,
+						   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+		/* update remote vsi if decode timeout */
+		if (ret) {
+			mtk_vcodec_err(instance, "VP9 core timeout\n");
+			writel(1, &instance->core_vsi->state.timeout);
+		}
+		vpu_dec_core_end(&instance->vpu);
+	}
+
+	vdec_vp9_slice_vsi_from_remote(&pfc->vsi, instance->core_vsi, 1);
+	ret = vdec_vp9_slice_update_core(instance, lat_buf, pfc);
+	if (ret) {
+		mtk_vcodec_err(instance, "vdec_vp9_slice_update_core\n");
+		goto err;
+	}
+
+	pfc->vsi.trans.dma_addr_end += ctx->msg_queue.wdma_addr.dma_addr;
+	mtk_vcodec_debug(instance, "core dma_addr_end 0x%llx\n", pfc->vsi.trans.dma_addr_end);
+	vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, pfc->vsi.trans.dma_addr_end);
+	ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 0);
+
+	return 0;
+
+err:
+	if (ctx) {
+		/* always update read pointer */
+		vdec_msg_queue_update_ube_rptr(&ctx->msg_queue, pfc->vsi.trans.dma_addr_end);
+
+		if (fb)
+			ctx->dev->vdec_pdata->cap_to_disp(ctx, fb, 1);
+	}
+	return ret;
+}
+
+const struct vdec_common_if vdec_vp9_slice_lat_if = {
+	.init		= vdec_vp9_slice_init,
+	.decode		= vdec_vp9_slice_lat_decode,
+	.get_param	= vdec_vp9_slice_get_param,
+	.deinit		= vdec_vp9_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 9db9a57da2c1..2d3a45781359 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -44,6 +44,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_vp9_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP9_FRAME:
+		ctx->dec_if = &vdec_vp9_slice_lat_if;
+		ctx->hw_id = MTK_VDEC_LAT0;
+		break;
 	default:
 		return -EINVAL;
 	}
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index e3adf8f36342..e383a04db7b8 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -60,6 +60,7 @@ extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
+extern const struct vdec_common_if vdec_vp9_slice_lat_if;
 
 /**
  * vdec_if_init() - initialize decode driver
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 19:53:15 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 11:53:15 +0800
Subject: [PATCH  v6, 14/15] media: mtk-vcodec: support stateless VP8 decoding
In-Reply-To: <20220122035316.18179-1-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
Message-ID: <20220122035316.18179-15-yunfei.dong@mediatek.com>

Add support for VP8 decoding using the stateless API,
as supported by MT8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/Makefile    |   1 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  24 +-
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   1 +
 .../mtk-vcodec/vdec/vdec_vp8_req_if.c         | 445 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   4 +
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 6 files changed, 474 insertions(+), 2 deletions(-)
 create mode 100644 drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c

diff --git a/drivers/media/platform/mtk-vcodec/Makefile b/drivers/media/platform/mtk-vcodec/Makefile
index 22edb1c86598..b457daf2d196 100644
--- a/drivers/media/platform/mtk-vcodec/Makefile
+++ b/drivers/media/platform/mtk-vcodec/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_VIDEO_MEDIATEK_VCODEC) += mtk-vcodec-dec.o \
 
 mtk-vcodec-dec-y := vdec/vdec_h264_if.o \
 		vdec/vdec_vp8_if.o \
+		vdec/vdec_vp8_req_if.o \
 		vdec/vdec_vp9_if.o \
 		vdec/vdec_h264_req_if.o \
 		vdec/vdec_h264_req_common.o \
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 9333e3418b98..2a0164ddc708 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -76,13 +76,28 @@ static const struct mtk_stateless_control mtk_stateless_controls[] = {
 			.max = V4L2_STATELESS_H264_START_CODE_ANNEX_B,
 		},
 		.codec_type = V4L2_PIX_FMT_H264_SLICE,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_STATELESS_VP8_FRAME,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
+	},
+	{
+		.cfg = {
+			.id = V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
+			.min = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.def = V4L2_MPEG_VIDEO_VP8_PROFILE_0,
+			.max = V4L2_MPEG_VIDEO_VP8_PROFILE_3,
+		},
+		.codec_type = V4L2_PIX_FMT_VP8_FRAME,
 	}
 };
 
 #define NUM_CTRLS ARRAY_SIZE(mtk_stateless_controls)
 
-static struct mtk_video_fmt mtk_video_formats[3];
-static struct mtk_codec_framesizes mtk_vdec_framesizes[1];
+static struct mtk_video_fmt mtk_video_formats[4];
+static struct mtk_codec_framesizes mtk_vdec_framesizes[2];
 
 static struct mtk_video_fmt default_out_format;
 static struct mtk_video_fmt default_cap_format;
@@ -350,6 +365,7 @@ static void mtk_vcodec_add_formats(unsigned int fourcc,
 
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
+	case V4L2_PIX_FMT_VP8_FRAME:
 		mtk_video_formats[count_formats].fourcc = fourcc;
 		mtk_video_formats[count_formats].type = MTK_FMT_DEC;
 		mtk_video_formats[count_formats].num_planes = 1;
@@ -393,6 +409,10 @@ static void mtk_vcodec_get_supported_formats(struct mtk_vcodec_ctx *ctx)
 		mtk_vcodec_add_formats(V4L2_PIX_FMT_H264_SLICE, ctx);
 		out_format_count++;
 	}
+	if (ctx->dev->dec_capability & MTK_VDEC_FORMAT_VP8_FRAME) {
+		mtk_vcodec_add_formats(V4L2_PIX_FMT_VP8_FRAME, ctx);
+		out_format_count++;
+	}
 
 	if (cap_format_count)
 		default_cap_format = mtk_video_formats[cap_format_count - 1];
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index fde79684106d..e16733fbf0c7 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -357,6 +357,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_MM21 = 0x20,
 	MTK_VDEC_FORMAT_MT21C = 0x40,
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
+	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
 };
 
 /**
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
new file mode 100644
index 000000000000..6bd4f2365826
--- /dev/null
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_vp8_req_if.c
@@ -0,0 +1,445 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Yunfei Dong <yunfei.dong at mediatek.com>
+ */
+
+#include <linux/slab.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/videobuf2-dma-contig.h>
+#include <uapi/linux/v4l2-controls.h>
+
+#include "../mtk_vcodec_util.h"
+#include "../mtk_vcodec_dec.h"
+#include "../mtk_vcodec_intr.h"
+#include "../vdec_drv_base.h"
+#include "../vdec_drv_if.h"
+#include "../vdec_vpu_if.h"
+
+/* Decoding picture buffer size (3 reference frames plus current frame) */
+#define VP8_DPB_SIZE 4
+
+/* HW working buffer size (bytes) */
+#define VP8_SEG_ID_SZ   SZ_256K
+#define VP8_PP_WRAPY_SZ SZ_64K
+#define VP8_PP_WRAPC_SZ SZ_64K
+#define VP8_VLD_PRED_SZ SZ_64K
+
+/**
+ * struct vdec_vp8_slice_info - decode misc information
+ * @vld_wrapper_dma   : vld wrapper dma address
+ * @seg_id_buf_dma    : seg id dma address
+ * @wrap_y_dma        : wrap y dma address
+ * @wrap_c_dma        : wrap y dma address
+ * @cur_y_fb_dma      : current plane Y frame buffer dma address
+ * @cur_c_fb_dma      : current plane C frame buffer dma address
+ * @bs_dma            : bitstream dma address
+ * @bs_sz             : bitstream size
+ * @resolution_changed: resolution change flag 1 - changed,  0 - not change
+ * @frame_header_type : current frame header type
+ * @wait_key_frame    : wait key frame coming
+ * @crc               : used to check whether hardware's status is right
+ * @reserved:         : reserved, currently unused
+ */
+struct vdec_vp8_slice_info {
+	u64 vld_wrapper_dma;
+	u64 seg_id_buf_dma;
+	u64 wrap_y_dma;
+	u64 wrap_c_dma;
+	u64 cur_y_fb_dma;
+	u64 cur_c_fb_dma;
+	u64 bs_dma;
+	u32 bs_sz;
+	u32 resolution_changed;
+	u32 frame_header_type;
+	u32 crc[8];
+	u32 reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_dpb_info  - vp8 reference information
+ * @y_dma_addr    : Y bitstream physical address
+ * @c_dma_addr    : CbCr bitstream physical address
+ * @reference_flag: reference picture flag
+ * @reserved      : 64bit align
+ */
+struct vdec_vp8_slice_dpb_info {
+	dma_addr_t y_dma_addr;
+	dma_addr_t c_dma_addr;
+	int reference_flag;
+	int reserved;
+};
+
+/**
+ * struct vdec_vp8_slice_vsi - VPU shared information
+ * @dec          : decoding information
+ * @pic          : picture information
+ * @vp8_dpb_info : reference buffer information
+ */
+struct vdec_vp8_slice_vsi {
+	struct vdec_vp8_slice_info dec;
+	struct vdec_pic_info pic;
+	struct vdec_vp8_slice_dpb_info vp8_dpb_info[3];
+};
+
+/**
+ * struct vdec_vp8_slice_inst - VP8 decoder instance
+ * @seg_id_buf     : seg buffer
+ * @wrap_y_buf     : wrapper y buffer
+ * @wrap_c_buf     : wrapper c buffer
+ * @vld_wrapper_buf: vld wrapper buffer
+ * @ctx            : V4L2 context
+ * @vpu            : VPU instance for decoder
+ * @vsi            : VPU share information
+ */
+struct vdec_vp8_slice_inst {
+	struct mtk_vcodec_mem seg_id_buf;
+	struct mtk_vcodec_mem wrap_y_buf;
+	struct mtk_vcodec_mem wrap_c_buf;
+	struct mtk_vcodec_mem vld_wrapper_buf;
+	struct mtk_vcodec_ctx *ctx;
+	struct vdec_vpu_inst vpu;
+	struct vdec_vp8_slice_vsi *vsi;
+};
+
+static void *vdec_vp8_slice_get_ctrl_ptr(struct mtk_vcodec_ctx *ctx, int id)
+{
+	struct v4l2_ctrl *ctrl = v4l2_ctrl_find(&ctx->ctrl_hdl, id);
+
+	if (!ctrl)
+		return ERR_PTR(-EINVAL);
+
+	return ctrl->p_cur.p;
+}
+
+static void vdec_vp8_slice_get_crop_info(struct vdec_vp8_slice_inst *inst,
+					 struct v4l2_rect *cr)
+{
+	cr->left = 0;
+	cr->top = 0;
+	cr->width = inst->vsi->pic.pic_w;
+	cr->height = inst->vsi->pic.pic_h;
+	mtk_vcodec_debug(inst, "get crop info l=%d, t=%d, w=%d, h=%d",
+			 cr->left, cr->top, cr->width, cr->height);
+}
+
+static void vdec_vp8_slice_get_pic_info(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	unsigned int data[3];
+
+	data[0] = ctx->picinfo.pic_w;
+	data[1] = ctx->picinfo.pic_h;
+	data[2] = ctx->capture_fourcc;
+	vpu_dec_get_param(&inst->vpu, data, 3, GET_PARAM_PIC_INFO);
+
+	ctx->picinfo.buf_w = ALIGN(ctx->picinfo.pic_w, 64);
+	ctx->picinfo.buf_h = ALIGN(ctx->picinfo.pic_h, 64);
+	ctx->picinfo.fb_sz[0] = inst->vpu.fb_sz[0];
+	ctx->picinfo.fb_sz[1] = inst->vpu.fb_sz[1];
+
+	inst->vsi->pic.pic_w = ctx->picinfo.pic_w;
+	inst->vsi->pic.pic_h = ctx->picinfo.pic_h;
+	inst->vsi->pic.buf_w = ctx->picinfo.buf_w;
+	inst->vsi->pic.buf_h = ctx->picinfo.buf_h;
+	inst->vsi->pic.fb_sz[0] = ctx->picinfo.fb_sz[0];
+	inst->vsi->pic.fb_sz[1] = ctx->picinfo.fb_sz[1];
+	mtk_vcodec_debug(inst, "pic(%d, %d), buf(%d, %d)",
+			 ctx->picinfo.pic_w, ctx->picinfo.pic_h,
+			 ctx->picinfo.buf_w, ctx->picinfo.buf_h);
+	mtk_vcodec_debug(inst, "fb size: Y(%d), C(%d)",
+			 ctx->picinfo.fb_sz[0], ctx->picinfo.fb_sz[1]);
+}
+
+static int vdec_vp8_slice_alloc_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	int err;
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	mem->size = VP8_SEG_ID_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "Cannot allocate working buffer");
+		return err;
+	}
+	inst->vsi->dec.seg_id_buf_dma = (u64)mem->dma_addr;
+
+	mem = &inst->wrap_y_buf;
+	mem->size = VP8_PP_WRAPY_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP Y buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_y_dma = (u64)mem->dma_addr;
+
+	mem = &inst->wrap_c_buf;
+	mem->size = VP8_PP_WRAPC_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate WRAP C buffer");
+		return err;
+	}
+	inst->vsi->dec.wrap_c_dma = (u64)mem->dma_addr;
+
+	mem = &inst->vld_wrapper_buf;
+	mem->size = VP8_VLD_PRED_SZ;
+	err = mtk_vcodec_mem_alloc(inst->ctx, mem);
+	if (err) {
+		mtk_vcodec_err(inst, "cannot allocate vld wrapper buffer");
+		return err;
+	}
+	inst->vsi->dec.vld_wrapper_dma = (u64)mem->dma_addr;
+
+	return 0;
+}
+
+static void vdec_vp8_slice_free_working_buf(struct vdec_vp8_slice_inst *inst)
+{
+	struct mtk_vcodec_mem *mem;
+
+	mem = &inst->seg_id_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.seg_id_buf_dma = 0;
+
+	mem = &inst->wrap_y_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_y_dma = 0;
+
+	mem = &inst->wrap_c_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.wrap_c_dma = 0;
+
+	mem = &inst->vld_wrapper_buf;
+	if (mem->va)
+		mtk_vcodec_mem_free(inst->ctx, mem);
+	inst->vsi->dec.vld_wrapper_dma = 0;
+}
+
+static u64 vdec_vp8_slice_get_ref_by_ts(const struct v4l2_ctrl_vp8_frame *frame_header,
+					int index)
+{
+	switch (index) {
+	case 0:
+		return frame_header->last_frame_ts;
+	case 1:
+		return frame_header->golden_frame_ts;
+	case 2:
+		return frame_header->alt_frame_ts;
+	default:
+		break;
+	}
+
+	return -1;
+}
+
+static int vdec_vp8_slice_get_decode_parameters(struct vdec_vp8_slice_inst *inst)
+{
+	const struct v4l2_ctrl_vp8_frame *frame_header;
+	struct mtk_vcodec_ctx *ctx = inst->ctx;
+	struct vb2_queue *vq;
+	struct vb2_buffer *vb;
+	u64 referenct_ts;
+	int index, vb2_index;
+
+	frame_header = vdec_vp8_slice_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_VP8_FRAME);
+	if (IS_ERR(frame_header))
+		return PTR_ERR(frame_header);
+
+	vq = v4l2_m2m_get_vq(ctx->m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
+	for (index = 0; index < 3; index++) {
+		referenct_ts = vdec_vp8_slice_get_ref_by_ts(frame_header, index);
+		vb2_index = vb2_find_timestamp(vq, referenct_ts, 0);
+		if (vb2_index < 0) {
+			if (!V4L2_VP8_FRAME_IS_KEY_FRAME(frame_header))
+				mtk_vcodec_err(inst, "reference invalid: index(%d) ts(%lld)",
+					       index, referenct_ts);
+			inst->vsi->vp8_dpb_info[index].reference_flag = 0;
+			continue;
+		}
+		inst->vsi->vp8_dpb_info[index].reference_flag = 1;
+
+		vb = vq->bufs[vb2_index];
+		inst->vsi->vp8_dpb_info[index].y_dma_addr =
+			vb2_dma_contig_plane_dma_addr(vb, 0);
+		if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				vb2_dma_contig_plane_dma_addr(vb, 1);
+		else
+			inst->vsi->vp8_dpb_info[index].c_dma_addr =
+				inst->vsi->vp8_dpb_info[index].y_dma_addr +
+				ctx->picinfo.fb_sz[0];
+	}
+
+	inst->vsi->dec.frame_header_type = frame_header->flags >> 1;
+
+	return 0;
+}
+
+static int vdec_vp8_slice_init(struct mtk_vcodec_ctx *ctx)
+{
+	struct vdec_vp8_slice_inst *inst;
+	int err;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+
+	inst->ctx = ctx;
+
+	inst->vpu.id = SCP_IPI_VDEC_LAT;
+	inst->vpu.core_id = SCP_IPI_VDEC_CORE;
+	inst->vpu.ctx = ctx;
+	inst->vpu.codec_type = ctx->current_codec;
+	inst->vpu.capture_type = ctx->capture_fourcc;
+
+	err = vpu_dec_init(&inst->vpu);
+	if (err) {
+		mtk_vcodec_err(inst, "vdec_vp8 init err=%d", err);
+		goto error_free_inst;
+	}
+
+	inst->vsi = inst->vpu.vsi;
+	err = vdec_vp8_slice_alloc_working_buf(inst);
+	if (err)
+		goto error_deinit;
+
+	mtk_vcodec_debug(inst, "vp8 struct size = %d vsi: %d\n",
+			 (int)sizeof(struct v4l2_ctrl_vp8_frame),
+			 (int)sizeof(struct vdec_vp8_slice_vsi));
+	mtk_vcodec_debug(inst, "vp8:%p, codec_type = 0x%x vsi: 0x%p",
+			 inst, inst->vpu.codec_type, inst->vpu.vsi);
+
+	ctx->drv_handle = inst;
+	return 0;
+
+error_deinit:
+	vpu_dec_deinit(&inst->vpu);
+error_free_inst:
+	kfree(inst);
+	return err;
+}
+
+static int vdec_vp8_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+				 struct vdec_fb *fb, bool *res_chg)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
+	unsigned int data;
+	u64 y_fb_dma, c_fb_dma;
+	int err, timeout;
+
+	/* Resolution changes are never initiated by us */
+	*res_chg = false;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vpu_dec_reset(vpu);
+
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
+		c_fb_dma = y_fb_dma +
+			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
+	else
+		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+
+	inst->vsi->dec.bs_dma = (u64)bs->dma_addr;
+	inst->vsi->dec.bs_sz = bs->size;
+	inst->vsi->dec.cur_y_fb_dma = y_fb_dma;
+	inst->vsi->dec.cur_c_fb_dma = c_fb_dma;
+
+	mtk_vcodec_debug(inst, "frame[%d] bs(%zu 0x%llx) y/c(0x%llx 0x%llx)",
+			 inst->ctx->decoded_frame_cnt,
+			 bs->size, (u64)bs->dma_addr,
+			 y_fb_dma, c_fb_dma);
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &dst_buf_info->m2m_buf.vb, true);
+
+	err = vdec_vp8_slice_get_decode_parameters(inst);
+	if (err)
+		goto error;
+
+	err = vpu_dec_start(vpu, &data, 1);
+	if (err) {
+		mtk_vcodec_debug(inst, "vp8 dec start err!");
+		goto error;
+	}
+
+	if (inst->vsi->dec.resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution_changed -");
+		*res_chg = true;
+		return 0;
+	}
+
+	/* wait decode done interrupt */
+	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					       50, MTK_VDEC_CORE);
+
+	err = vpu_dec_end(vpu);
+	if (err || timeout)
+		mtk_vcodec_debug(inst, "vp8 dec error timeout:%d err: %d pic_%d",
+				 timeout, err, inst->ctx->decoded_frame_cnt);
+
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+			 inst->ctx->decoded_frame_cnt,
+			 inst->vsi->dec.crc[0], inst->vsi->dec.crc[1],
+			 inst->vsi->dec.crc[2], inst->vsi->dec.crc[3],
+			 inst->vsi->dec.crc[4], inst->vsi->dec.crc[5],
+			 inst->vsi->dec.crc[6], inst->vsi->dec.crc[7]);
+
+	inst->ctx->decoded_frame_cnt++;
+error:
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, !!err);
+	return err;
+}
+
+static int vdec_vp8_slice_get_param(void *h_vdec, enum vdec_get_param_type type, void *out)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	switch (type) {
+	case GET_PARAM_PIC_INFO:
+		vdec_vp8_slice_get_pic_info(inst);
+		break;
+	case GET_PARAM_CROP_INFO:
+		vdec_vp8_slice_get_crop_info(inst, out);
+		break;
+	case GET_PARAM_DPB_SIZE:
+		*((unsigned int *)out) = VP8_DPB_SIZE;
+		break;
+	default:
+		mtk_vcodec_err(inst, "invalid get parameter type=%d", type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void vdec_vp8_slice_deinit(void *h_vdec)
+{
+	struct vdec_vp8_slice_inst *inst = h_vdec;
+
+	mtk_vcodec_debug_enter(inst);
+
+	vpu_dec_deinit(&inst->vpu);
+	vdec_vp8_slice_free_working_buf(inst);
+	kfree(inst);
+}
+
+const struct vdec_common_if vdec_vp8_slice_if = {
+	.init		= vdec_vp8_slice_init,
+	.decode		= vdec_vp8_slice_decode,
+	.get_param	= vdec_vp8_slice_get_param,
+	.deinit		= vdec_vp8_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index c17a7815e1bb..9db9a57da2c1 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -32,6 +32,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 		ctx->dec_if = &vdec_h264_if;
 		ctx->hw_id = MTK_VDEC_CORE;
 		break;
+	case V4L2_PIX_FMT_VP8_FRAME:
+		ctx->dec_if = &vdec_vp8_slice_if;
+		ctx->hw_id = MTK_VDEC_CORE;
+		break;
 	case V4L2_PIX_FMT_VP8:
 		ctx->dec_if = &vdec_vp8_if;
 		ctx->hw_id = MTK_VDEC_CORE;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index 6ce848e74167..e3adf8f36342 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -58,6 +58,7 @@ extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
 extern const struct vdec_common_if vdec_h264_slice_lat_if;
 extern const struct vdec_common_if vdec_vp8_if;
+extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
 
 /**
-- 
2.25.1



From xueshuai at linux.alibaba.com  Fri Jan 21 21:26:17 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Sat, 22 Jan 2022 13:26:17 +0800
Subject: [PATCH v7 1/2] ACPI: APEI: explicit init HEST and GHES in apci_init
In-Reply-To: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
References: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
Message-ID: <20220122052618.1074-1-xueshuai@linux.alibaba.com>

>From commit e147133a42cb ("ACPI / APEI: Make hest.c manage the estatus
memory pool") was merged, ghes_init() relies on acpi_hest_init() to manage
the estatus memory pool. On the other hand, ghes_init() relies on
sdei_init() to detect the SDEI version and (un)register events. The
dependencies are as follows:

    ghes_init() => acpi_hest_init() => acpi_bus_init() => acpi_init()
    ghes_init() => sdei_init()

HEST is not PCI-specific and initcall ordering is implicit and not
well-defined within a level.

Based on above, remove acpi_hest_init() from acpi_pci_root_init() and
convert ghes_init() and sdei_init() from initcalls to explicit calls in the
following order:

    acpi_hest_init()
    ghes_init()
        sdei_init()

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
---
 drivers/acpi/apei/ghes.c    | 19 ++++++++-----------
 drivers/acpi/bus.c          |  2 ++
 drivers/acpi/pci_root.c     |  3 ---
 drivers/firmware/Kconfig    |  1 +
 drivers/firmware/arm_sdei.c | 13 ++-----------
 include/acpi/apei.h         |  4 +++-
 include/linux/arm_sdei.h    |  2 ++
 7 files changed, 18 insertions(+), 26 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 0c5c9acc6254..aadc0a972f18 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1457,33 +1457,35 @@ static struct platform_driver ghes_platform_driver = {
 	.remove		= ghes_remove,
 };
 
-static int __init ghes_init(void)
+void __init ghes_init(void)
 {
 	int rc;
 
+	sdei_init();
+
 	if (acpi_disabled)
-		return -ENODEV;
+		return;
 
 	switch (hest_disable) {
 	case HEST_NOT_FOUND:
-		return -ENODEV;
+		return;
 	case HEST_DISABLED:
 		pr_info(GHES_PFX "HEST is not enabled!\n");
-		return -EINVAL;
+		return;
 	default:
 		break;
 	}
 
 	if (ghes_disable) {
 		pr_info(GHES_PFX "GHES is not enabled!\n");
-		return -EINVAL;
+		return;
 	}
 
 	ghes_nmi_init_cxt();
 
 	rc = platform_driver_register(&ghes_platform_driver);
 	if (rc)
-		goto err;
+		return;
 
 	rc = apei_osc_setup();
 	if (rc == 0 && osc_sb_apei_support_acked)
@@ -1494,9 +1496,4 @@ static int __init ghes_init(void)
 		pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n");
 	else
 		pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n");
-
-	return 0;
-err:
-	return rc;
 }
-device_initcall(ghes_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 07f604832fd6..3f403db20f69 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1331,6 +1331,8 @@ static int __init acpi_init(void)
 
 	pci_mmcfg_late_init();
 	acpi_iort_init();
+	acpi_hest_init();
+	ghes_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index b76db99cced3..6f9e75d14808 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -22,8 +22,6 @@
 #include <linux/slab.h>
 #include <linux/dmi.h>
 #include <linux/platform_data/x86/apple.h>
-#include <acpi/apei.h>	/* for acpi_hest_init() */
-
 #include "internal.h"
 
 #define ACPI_PCI_ROOT_CLASS		"pci_bridge"
@@ -943,7 +941,6 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
 
 void __init acpi_pci_root_init(void)
 {
-	acpi_hest_init();
 	if (acpi_pci_disabled)
 		return;
 
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..ad114d9cdf8e 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -40,6 +40,7 @@ config ARM_SCPI_POWER_DOMAIN
 config ARM_SDE_INTERFACE
 	bool "ARM Software Delegated Exception Interface (SDEI)"
 	depends on ARM64
+	select ACPI_APEI_GHES
 	help
 	  The Software Delegated Exception Interface (SDEI) is an ARM
 	  standard for registering callbacks from the platform firmware
diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c
index a7e762c352f9..1e1a51510e83 100644
--- a/drivers/firmware/arm_sdei.c
+++ b/drivers/firmware/arm_sdei.c
@@ -1059,14 +1059,14 @@ static bool __init sdei_present_acpi(void)
 	return true;
 }
 
-static int __init sdei_init(void)
+void __init sdei_init(void)
 {
 	struct platform_device *pdev;
 	int ret;
 
 	ret = platform_driver_register(&sdei_driver);
 	if (ret || !sdei_present_acpi())
-		return ret;
+		return;
 
 	pdev = platform_device_register_simple(sdei_driver.driver.name,
 					       0, NULL, 0);
@@ -1076,17 +1076,8 @@ static int __init sdei_init(void)
 		pr_info("Failed to register ACPI:SDEI platform device %d\n",
 			ret);
 	}
-
-	return ret;
 }
 
-/*
- * On an ACPI system SDEI needs to be ready before HEST:GHES tries to register
- * its events. ACPI is initialised from a subsys_initcall(), GHES is initialised
- * by device_initcall(). We want to be called in the middle.
- */
-subsys_initcall_sync(sdei_init);
-
 int sdei_event_handler(struct pt_regs *regs,
 		       struct sdei_registered_event *arg)
 {
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index ece0a8af2bae..4e60dd73c3bb 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -27,14 +27,16 @@ extern int hest_disable;
 extern int erst_disable;
 #ifdef CONFIG_ACPI_APEI_GHES
 extern bool ghes_disable;
+void __init ghes_init(void);
 #else
 #define ghes_disable 1
+static inline void ghes_init(void) { }
 #endif
 
 #ifdef CONFIG_ACPI_APEI
 void __init acpi_hest_init(void);
 #else
-static inline void acpi_hest_init(void) { return; }
+static inline void acpi_hest_init(void) { }
 #endif
 
 int erst_write(const struct cper_record_header *record);
diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h
index 0a241c5c911d..14dc461b0e82 100644
--- a/include/linux/arm_sdei.h
+++ b/include/linux/arm_sdei.h
@@ -46,9 +46,11 @@ int sdei_unregister_ghes(struct ghes *ghes);
 /* For use by arch code when CPU hotplug notifiers are not appropriate. */
 int sdei_mask_local_cpu(void);
 int sdei_unmask_local_cpu(void);
+void __init sdei_init(void);
 #else
 static inline int sdei_mask_local_cpu(void) { return 0; }
 static inline int sdei_unmask_local_cpu(void) { return 0; }
+static inline void sdei_init(void) { }
 #endif /* CONFIG_ARM_SDE_INTERFACE */
 
 
-- 
2.20.1.12.g72788fdb



From xueshuai at linux.alibaba.com  Fri Jan 21 21:26:18 2022
From: xueshuai at linux.alibaba.com (Shuai Xue)
Date: Sat, 22 Jan 2022 13:26:18 +0800
Subject: [PATCH v7 2/2] ACPI: APEI: rename ghes_init with an "acpi_" prefix
In-Reply-To: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
References: <20211126070422.73234-1-xueshuai@linux.alibaba.com>
Message-ID: <20220122052618.1074-2-xueshuai@linux.alibaba.com>

Signed-off-by: Shuai Xue <xueshuai at linux.alibaba.com>
---
 drivers/acpi/apei/ghes.c | 2 +-
 drivers/acpi/bus.c       | 2 +-
 include/acpi/apei.h      | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index aadc0a972f18..d91ad378c00d 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -1457,7 +1457,7 @@ static struct platform_driver ghes_platform_driver = {
 	.remove		= ghes_remove,
 };
 
-void __init ghes_init(void)
+void __init acpi_ghes_init(void)
 {
 	int rc;
 
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 3f403db20f69..cd374210fb9f 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -1332,7 +1332,7 @@ static int __init acpi_init(void)
 	pci_mmcfg_late_init();
 	acpi_iort_init();
 	acpi_hest_init();
-	ghes_init();
+	acpi_ghes_init();
 	acpi_scan_init();
 	acpi_ec_init();
 	acpi_debugfs_init();
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index 4e60dd73c3bb..afaca3a075e8 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -27,10 +27,10 @@ extern int hest_disable;
 extern int erst_disable;
 #ifdef CONFIG_ACPI_APEI_GHES
 extern bool ghes_disable;
-void __init ghes_init(void);
+void __init acpi_ghes_init(void);
 #else
 #define ghes_disable 1
-static inline void ghes_init(void) { }
+static inline void acpi_ghes_init(void) { }
 #endif
 
 #ifdef CONFIG_ACPI_APEI
-- 
2.20.1.12.g72788fdb



From lkp at intel.com  Fri Jan 21 22:09:01 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 22 Jan 2022 14:09:01 +0800
Subject: [PATCH 3/4] soc: bcm: brcmstb: Added support for PSCI system
 suspend operations
In-Reply-To: <20220122035421.4086618-4-f.fainelli@gmail.com>
References: <20220122035421.4086618-4-f.fainelli@gmail.com>
Message-ID: <202201221442.7bCTuqul-lkp@intel.com>

Hi Florian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm/for-next]
[also build test WARNING on soc/for-next arm64/for-next/core clk/clk-next linus/master v5.16 next-20220121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
base:   git://git.armlinux.org.uk/~rmk/linux-arm.git for-next
config: arm64-randconfig-r011-20220120 (https://download.01.org/0day-ci/archive/20220122/202201221442.7bCTuqul-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 7b3d30728816403d1fd73cc5082e9fb761262bce)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/30bf64821ad5d3cbbc91770b3927905d10d3bdf3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
        git checkout 30bf64821ad5d3cbbc91770b3927905d10d3bdf3
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/soc/bcm/brcmstb/pm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/soc/bcm/brcmstb/pm/pm-psci.c:95:6: warning: no previous prototype for function 'brcmstb_psci_sys_poweroff' [-Wmissing-prototypes]
   void brcmstb_psci_sys_poweroff(void)
        ^
   drivers/soc/bcm/brcmstb/pm/pm-psci.c:95:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void brcmstb_psci_sys_poweroff(void)
   ^
   static 
   1 warning generated.


vim +/brcmstb_psci_sys_poweroff +95 drivers/soc/bcm/brcmstb/pm/pm-psci.c

    94	
  > 95	void brcmstb_psci_sys_poweroff(void)
    96	{
    97		invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
    98	}
    99	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Fri Jan 21 23:10:11 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 22 Jan 2022 15:10:11 +0800
Subject: [PATCH 3/4] soc: bcm: brcmstb: Added support for PSCI system
 suspend operations
In-Reply-To: <20220122035421.4086618-4-f.fainelli@gmail.com>
References: <20220122035421.4086618-4-f.fainelli@gmail.com>
Message-ID: <202201221439.RaZlgS8d-lkp@intel.com>

Hi Florian,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm/for-next]
[also build test WARNING on soc/for-next arm64/for-next/core clk/clk-next linus/master v5.16 next-20220121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
base:   git://git.armlinux.org.uk/~rmk/linux-arm.git for-next
config: arm-multi_v7_defconfig (https://download.01.org/0day-ci/archive/20220122/202201221439.RaZlgS8d-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/30bf64821ad5d3cbbc91770b3927905d10d3bdf3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
        git checkout 30bf64821ad5d3cbbc91770b3927905d10d3bdf3
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/soc/bcm/brcmstb/pm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/soc/bcm/brcmstb/pm/pm-psci.c:95:6: warning: no previous prototype for 'brcmstb_psci_sys_poweroff' [-Wmissing-prototypes]
      95 | void brcmstb_psci_sys_poweroff(void)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~


vim +/brcmstb_psci_sys_poweroff +95 drivers/soc/bcm/brcmstb/pm/pm-psci.c

    94	
  > 95	void brcmstb_psci_sys_poweroff(void)
    96	{
    97		invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
    98	}
    99	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From christianshewitt at gmail.com  Fri Jan 21 23:32:18 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:18 +0000
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to Beelink
 g12b devices
Message-ID: <20220122073221.2398-1-christianshewitt@gmail.com>

This resolves a long-running issue where Beelink GT-King/Pro and
GS-King-X wedge on boot or shortly after when booting from vendor
u-boot. In some distros the issue is often reported as triggered
by large file transfers to/from USB or SD cards. Reserving the
BL32 memory region prevents the issue.

Christian Hewitt (3):
  arm64: dts: meson: add BL32 reserved-memory region to GT-King
  arm64: dts: meson: add BL32 reserved-memory region to GT-King Pro
  arm64: dts: meson: add BL32 reserved-memory region to GS-King-X

 arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts   | 8 ++++++++
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts | 8 ++++++++
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts     | 8 ++++++++
 3 files changed, 24 insertions(+)

-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:19 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:19 +0000
Subject: [PATCH 1/3] arm64: dts: meson: add BL32 reserved-memory region to
 GT-King
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-2-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit c5522ff9c729 ("arm64: dts: meson-g12b-gtking: add initial device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
index 5d96c1449050..58a300d6b545 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking.dts
@@ -19,6 +19,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	spdif_dit: audio-codec-1 {
 		#sound-dai-cells = <0>;
 		compatible = "linux,spdif-dit";
-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:20 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:20 +0000
Subject: [PATCH 2/3] arm64: dts: meson: add BL32 reserved-memory region to
 GT-King Pro
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-3-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit 0b928e4e412b ("arm64: dts: meson-g12b-gtking-pro: add initial device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
index 707daf92787b..7782fc9fc12b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gtking-pro.dts
@@ -19,6 +19,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	gpio-keys-polled {
 		compatible = "gpio-keys-polled";
 		#address-cells = <1>;
-- 
2.17.1



From christianshewitt at gmail.com  Fri Jan 21 23:32:21 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Sat, 22 Jan 2022 07:32:21 +0000
Subject: [PATCH 3/3] arm64: dts: meson: add BL32 reserved-memory region to
 GS-King-X
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <20220122073221.2398-4-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
shipping in Beelink g12b devices. This fixes a long running issue with
boxes booting from Vendor u-boot where the board wedges during boot or
soon after due to the (un)reserved region being overwritten.

Fixes commit 93db2ce05204 ("arm64: dts: meson: add initial Beelink GS-King-X device-tree")
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
Tested-by: Furkan Kardame <furkan at fkardame.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
index 6c7bfacbad78..c6178cbe3a9b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-gsking-x.dts
@@ -20,6 +20,14 @@
 		rtc1 = &vrtc;
 	};
 
+	reserved-memory {
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+	};
+
 	gpio-keys-polled {
 		compatible = "gpio-keys-polled";
 		#address-cells = <1>;
-- 
2.17.1



From yunfei.dong at mediatek.com  Fri Jan 21 23:56:04 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 15:56:04 +0800
Subject: [PATCH v1, 1/3] mtk-vcodec: Support MT8186
In-Reply-To: <20220122075606.19373-1-yunfei.dong@mediatek.com>
References: <20220122075606.19373-1-yunfei.dong@mediatek.com>
Message-ID: <20220122075606.19373-2-yunfei.dong@mediatek.com>

Adds MT8186's compatible "mediatek,mt8186-vcodec-dec".
Adds MT8186's device private data mtk_vdec_single_core_pdata.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |  1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  4 ++++
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 19 +++++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
index 66cd6d2242c3..4572f92826f2 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.h
@@ -69,6 +69,7 @@ extern const struct media_device_ops mtk_vcodec_media_ops;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8173_pdata;
 extern const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata;
 extern const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata;
+extern const struct mtk_vcodec_dec_pdata mtk_vdec_single_core_pdata;
 
 
 /*
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 6b52eaeedafa..2d21d0010c9c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -464,6 +464,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
 		.compatible = "mediatek,mt8192-vcodec-dec",
 		.data = &mtk_lat_sig_core_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8186-vcodec-dec",
+		.data = &mtk_vdec_single_core_pdata,
+	},
 	{},
 };
 
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
index 3770e8117488..4b83f00a8857 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
@@ -522,3 +522,22 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
 	.is_subdev_supported = true,
 	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
 };
+
+const struct mtk_vcodec_dec_pdata mtk_vdec_single_core_pdata = {
+	.init_vdec_params = mtk_init_vdec_params,
+	.ctrls_setup = mtk_vcodec_dec_ctrls_setup,
+	.vdec_vb2_ops = &mtk_vdec_request_vb2_ops,
+	.vdec_formats = mtk_video_formats,
+	.num_formats = &num_formats,
+	.default_out_fmt = &default_out_format,
+	.default_cap_fmt = &default_cap_format,
+	.vdec_framesizes = mtk_vdec_framesizes,
+	.num_framesizes = &num_framesizes,
+	.uses_stateless_api = true,
+	.worker = mtk_vdec_worker,
+	.flush_decoder = mtk_vdec_flush_decoder,
+	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
+	.get_cap_buffer = vdec_get_cap_buffer,
+	.is_subdev_supported = true,
+	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
+};
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 23:56:06 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 15:56:06 +0800
Subject: [PATCH v1, 3/3] mtk-vcodec: add h264 decoder driver for mt8186
In-Reply-To: <20220122075606.19373-1-yunfei.dong@mediatek.com>
References: <20220122075606.19373-1-yunfei.dong@mediatek.com>
Message-ID: <20220122075606.19373-4-yunfei.dong@mediatek.com>

Add h264 decode driver to support mt8186. For the architecture
is single core, need to add new interface to decode.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 164 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   5 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 3 files changed, 169 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
index 1567dbc63e95..5541edbafed2 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -137,6 +137,9 @@ struct vdec_h264_slice_share_info {
  * @vsi                 : vsi used for lat
  * @vsi_core            : vsi used for core
  *
+ * @vsi_ctx  : Local VSI data for this decoding context
+ * @h264_slice_param : the parameters that hardware use to decode
+ *
  * @resolution_changed  : resolution changed
  * @realloc_mv_buf      : reallocate mv buffer
  * @cap_num_planes      : number of capture queue plane
@@ -152,6 +155,9 @@ struct vdec_h264_slice_inst {
 	struct vdec_h264_slice_vsi *vsi;
 	struct vdec_h264_slice_vsi *vsi_core;
 
+	struct vdec_h264_slice_vsi vsi_ctx;
+	struct vdec_h264_slice_lat_dec_param h264_slice_param;
+
 	unsigned int resolution_changed;
 	unsigned int realloc_mv_buf;
 	unsigned int cap_num_planes;
@@ -196,6 +202,61 @@ static int vdec_h264_slice_fill_decode_parameters(struct vdec_h264_slice_inst *i
 	return 0;
 }
 
+static int get_vdec_sig_decode_parameters(struct vdec_h264_slice_inst *inst)
+{
+	const struct v4l2_ctrl_h264_decode_params *dec_params;
+	const struct v4l2_ctrl_h264_sps *sps;
+	const struct v4l2_ctrl_h264_pps *pps;
+	const struct v4l2_ctrl_h264_scaling_matrix *scaling_matrix;
+	struct vdec_h264_slice_lat_dec_param *slice_param = &inst->h264_slice_param;
+	struct v4l2_h264_reflist_builder reflist_builder;
+	u8 *p0_reflist = slice_param->decode_params.ref_pic_list_p0;
+	u8 *b0_reflist = slice_param->decode_params.ref_pic_list_b0;
+	u8 *b1_reflist = slice_param->decode_params.ref_pic_list_b1;
+
+	dec_params =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
+	if (IS_ERR(dec_params))
+		return PTR_ERR(dec_params);
+
+	sps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SPS);
+	if (IS_ERR(sps))
+		return PTR_ERR(sps);
+
+	pps = mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_PPS);
+	if (IS_ERR(pps))
+		return PTR_ERR(pps);
+
+	scaling_matrix =
+		mtk_vdec_h264_get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_SCALING_MATRIX);
+	if (IS_ERR(scaling_matrix))
+		return PTR_ERR(scaling_matrix);
+
+	mtk_vdec_h264_update_dpb(dec_params, inst->dpb);
+
+	mtk_vdec_h264_copy_sps_params(&slice_param->sps, sps);
+	mtk_vdec_h264_copy_pps_params(&slice_param->pps, pps);
+	mtk_vdec_h264_copy_scaling_matrix(&slice_param->scaling_matrix, scaling_matrix);
+
+	mtk_vdec_h264_copy_decode_params(&slice_param->decode_params, dec_params, inst->dpb);
+	mtk_vdec_h264_fill_dpb_info(inst->ctx, &slice_param->decode_params,
+				    slice_param->h264_dpb_info);
+
+	/* Build the reference lists */
+	v4l2_h264_init_reflist_builder(&reflist_builder, dec_params, sps, inst->dpb);
+	v4l2_h264_build_p_ref_list(&reflist_builder, p0_reflist);
+
+	v4l2_h264_build_b_ref_lists(&reflist_builder, b0_reflist, b1_reflist);
+	/* Adapt the built lists to the firmware's expectations */
+	mtk_vdec_h264_fixup_ref_list(p0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b0_reflist, reflist_builder.num_valid);
+	mtk_vdec_h264_fixup_ref_list(b1_reflist, reflist_builder.num_valid);
+	memcpy(&inst->vsi_ctx.h264_slice_params, slice_param,
+	       sizeof(inst->vsi_ctx.h264_slice_params));
+
+	return 0;
+}
+
 static void vdec_h264_slice_fill_decode_reflist(struct vdec_h264_slice_inst *inst,
 						struct vdec_h264_slice_lat_dec_param *slice_param,
 						struct vdec_h264_slice_share_info *share_info)
@@ -584,6 +645,102 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 	return err;
 }
 
+static int vdec_h264_slice_single_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
+					 struct vdec_fb *unused, bool *res_chg)
+{
+	struct vdec_h264_slice_inst *inst = (struct vdec_h264_slice_inst *)h_vdec;
+	struct vdec_vpu_inst *vpu = &inst->vpu;
+	struct mtk_video_dec_buf *src_buf_info, *dst_buf_info;
+	struct vdec_fb *fb;
+	unsigned char *buf;
+	unsigned int nal_start_idx, data[2], i;
+	u64 y_fb_dma, c_fb_dma;
+	struct mtk_vcodec_mem *mem;
+	int err;
+
+	/* bs NULL means flush decoder */
+	if (!bs)
+		return vpu_dec_reset(vpu);
+
+	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+
+	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=0x%llx",
+			 inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma, (u64)fb);
+
+	inst->vsi_ctx.dec.bs_buf_addr = (u64)bs->dma_addr;
+	inst->vsi_ctx.dec.bs_buf_size = bs->size;
+	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
+	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
+	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
+
+	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
+				   &dst_buf_info->m2m_buf.vb, true);
+	err = get_vdec_sig_decode_parameters(inst);
+	if (err)
+		goto err_free_fb_out;
+
+	buf = (unsigned char *)bs->va;
+	nal_start_idx = mtk_vdec_h264_find_start_code(buf, bs->size);
+	if (nal_start_idx < 0) {
+		err = -EINVAL;
+		goto err_free_fb_out;
+	}
+	inst->vsi_ctx.dec.nal_info = buf[nal_start_idx];
+
+	*res_chg = inst->resolution_changed;
+	if (inst->resolution_changed) {
+		mtk_vcodec_debug(inst, "- resolution changed -");
+		if (inst->realloc_mv_buf) {
+			err = vdec_h264_slice_alloc_mv_buf(inst, &inst->ctx->picinfo);
+			inst->realloc_mv_buf = false;
+			if (err)
+				goto err_free_fb_out;
+		}
+		inst->resolution_changed = false;
+
+		for (i = 0; i < H264_MAX_MV_NUM; i++) {
+			mem = &inst->mv_buf[i];
+			inst->vsi_ctx.mv_buf_dma[i] = mem->dma_addr;
+		}
+	}
+
+	memcpy(inst->vpu.vsi, &inst->vsi_ctx, sizeof(inst->vsi_ctx));
+	err = vpu_dec_start(vpu, data, 2);
+	if (err)
+		goto err_free_fb_out;
+
+	/* wait decoder done interrupt */
+	err = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
+					   WAIT_INTR_TIMEOUT_MS, MTK_VDEC_CORE);
+	if (err)
+		mtk_vcodec_err(inst, "core decode timeout: pic_%d",
+			       inst->ctx->decoded_frame_cnt);
+
+	inst->vsi->dec.timeout = !!err;
+	err = vpu_dec_end(vpu);
+	if (err)
+		goto err_free_fb_out;
+
+	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
+	mtk_vcodec_debug(inst, "pic[%d] crc: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
+			 inst->ctx->decoded_frame_cnt,
+			 inst->vsi_ctx.dec.crc[0], inst->vsi_ctx.dec.crc[1],
+			 inst->vsi_ctx.dec.crc[2], inst->vsi_ctx.dec.crc[3],
+			 inst->vsi_ctx.dec.crc[4], inst->vsi_ctx.dec.crc[5],
+			 inst->vsi_ctx.dec.crc[6], inst->vsi_ctx.dec.crc[7]);
+err_free_fb_out:
+	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, err);
+	mtk_vcodec_debug(inst, "dec frame number: %d err: %d",
+			 inst->ctx->decoded_frame_cnt, err);
+	inst->ctx->decoded_frame_cnt++;
+
+	return err;
+}
+
 static int vdec_h264_slice_get_param(void *h_vdec, enum vdec_get_param_type type,
 				     void *out)
 {
@@ -612,3 +769,10 @@ const struct vdec_common_if vdec_h264_slice_lat_if = {
 	.get_param	= vdec_h264_slice_get_param,
 	.deinit		= vdec_h264_slice_deinit,
 };
+
+const struct vdec_common_if vdec_h264_slice_single_if = {
+	.init		= vdec_h264_slice_init,
+	.decode		= vdec_h264_slice_single_decode,
+	.get_param	= vdec_h264_slice_get_param,
+	.deinit		= vdec_h264_slice_deinit,
+};
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
index 2d3a45781359..e22b577d692a 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.c
@@ -21,7 +21,10 @@ int vdec_if_init(struct mtk_vcodec_ctx *ctx, unsigned int fourcc)
 	switch (fourcc) {
 	case V4L2_PIX_FMT_H264_SLICE:
 		if (ctx->dev->vdec_pdata->hw_arch == MTK_VDEC_PURE_SINGLE_CORE) {
-			ctx->dec_if = &vdec_h264_slice_if;
+			if (ctx->dev->vdec_pdata->is_subdev_supported)
+				ctx->dec_if = &vdec_h264_slice_single_if;
+			else
+				ctx->dec_if = &vdec_h264_slice_if;
 			ctx->hw_id = MTK_VDEC_CORE;
 		} else {
 			ctx->dec_if = &vdec_h264_slice_lat_if;
diff --git a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
index e383a04db7b8..991c04e65c79 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
+++ b/drivers/media/platform/mtk-vcodec/vdec_drv_if.h
@@ -57,6 +57,7 @@ struct vdec_fb_node {
 extern const struct vdec_common_if vdec_h264_if;
 extern const struct vdec_common_if vdec_h264_slice_if;
 extern const struct vdec_common_if vdec_h264_slice_lat_if;
+extern const struct vdec_common_if vdec_h264_slice_single_if;
 extern const struct vdec_common_if vdec_vp8_if;
 extern const struct vdec_common_if vdec_vp8_slice_if;
 extern const struct vdec_common_if vdec_vp9_if;
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 23:56:05 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 15:56:05 +0800
Subject: [PATCH v1,
 2/3] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8186
In-Reply-To: <20220122075606.19373-1-yunfei.dong@mediatek.com>
References: <20220122075606.19373-1-yunfei.dong@mediatek.com>
Message-ID: <20220122075606.19373-3-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8186.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../bindings/media/mediatek,vcodec-subdev-decoder.yaml        | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index d587fc3e39fb..6415c9f29130 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -47,7 +47,9 @@ description: |
 
 properties:
   compatible:
-    const: mediatek,mt8192-vcodec-dec
+    enum:
+      - mediatek,mt8192-vcodec-dec
+      - mediatek,mt8186-vcodec-dec
 
   reg:
     maxItems: 1
-- 
2.25.1



From yunfei.dong at mediatek.com  Fri Jan 21 23:56:03 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Sat, 22 Jan 2022 15:56:03 +0800
Subject: [PATCH v1, 0/3] support mt8186 decoder
Message-ID: <20220122075606.19373-1-yunfei.dong@mediatek.com>

Firstly, add mt8186 compatible and private data, then add document for
compatible "mediatek,mt8186-vcodec-dec". For mt8186 is single core
architecture, need to add new interface for h264 hardware decoder.

Patche 1 add mt8186 compatible and private data.
Patche 2 add mt8186 compatible document.
Patche 3 add h264 single core driver.
---
This patch depends on "support for MT8192 decoder"[1]

[1]  https://patchwork.kernel.org/project/linux-mediatek/patch/20220122035316.18179-1-yunfei.dong at mediatek.com/
---
Yunfei Dong (3):
  mtk-vcodec: Support MT8186
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8186
  mtk-vcodec: add h264 decoder driver for mt8186

 .../media/mediatek,vcodec-subdev-decoder.yaml |   4 +-
 .../platform/mtk-vcodec/mtk_vcodec_dec.h      |   1 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |   4 +
 .../mtk-vcodec/mtk_vcodec_dec_stateless.c     |  19 ++
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 164 ++++++++++++++++++
 .../media/platform/mtk-vcodec/vdec_drv_if.c   |   5 +-
 .../media/platform/mtk-vcodec/vdec_drv_if.h   |   1 +
 7 files changed, 196 insertions(+), 2 deletions(-)

-- 
2.25.1



From pr-tracker-bot at kernel.org  Sat Jan 22 00:06:38 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sat, 22 Jan 2022 08:06:38 +0000
Subject: [GIT PULL] arm64 fixes for 5.17-rc1
In-Reply-To: <YermhR/kQO+dg7P/@arm.com>
References: <YermhR/kQO+dg7P/@arm.com>
Message-ID: <164283879871.17909.4707779936735793442.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 21 Jan 2022 16:59:49 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/b21bae9af1da9b319b5f52ca8fcda76a26cd175a

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From jeanmichel.hautbois at ideasonboard.com  Sat Jan 22 00:38:59 2022
From: jeanmichel.hautbois at ideasonboard.com (Jean-Michel Hautbois)
Date: Sat, 22 Jan 2022 09:38:59 +0100
Subject: [RFC PATCH v2 3/7] media: dt-bindings: media: Add bindings for
 bcm2835-unicam
In-Reply-To: <YetBdVY57T3QrUNa@pendragon.ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-4-jeanmichel.hautbois@ideasonboard.com>
 <YetBdVY57T3QrUNa@pendragon.ideasonboard.com>
Message-ID: <63dcc000-1d7f-d504-4a1a-e8559a596c9e@ideasonboard.com>

Hi Laurent,

On 22/01/2022 00:27, Laurent Pinchart wrote:
> Hi Jean-Michel,
> 
> Thank you for the patch.
> 
> On Fri, Jan 21, 2022 at 09:18:06AM +0100, Jean-Michel Hautbois wrote:
>> Introduce the dt-bindinds documentation for bcm2835 CCP2/CSI2 camera
> 
> s/bindinds/bindings/
> 
> I'd mention "Unicam" somewhere here.
> 
>> interface. Also add a MAINTAINERS entry for it.

Oh my, I tis not the right dts bindings patch, I mixed up my trees... :-/

Sorry for this I will send a v2.1 soon...

>>
>> Signed-off-by: Dave Stevenson <dave.stevenson at raspberrypi.com>
>> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
>> Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
>> ---
>> Dave: I assumed you were the maintainer for this file, as I based it on the
>> bcm2835-unicam.txt file. Are  you happy to be added directly as the
>> maintainer, or should this be specified as "Raspberry Pi Kernel
>> Maintenance <kernel-list at raspberrypi.com>"
>> - in v2: multiple corrections to pass the bot checking as Rob kindly
>>    told me.
>> ---
>>   .../bindings/media/brcm,bcm2835-unicam.yaml   | 103 ++++++++++++++++++
>>   MAINTAINERS                                   |   6 +
>>   2 files changed, 109 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
>> new file mode 100644
>> index 000000000000..1427514142cf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
>> @@ -0,0 +1,103 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/media/brcm,bcm2835-unicam.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Broadcom BCM283x Camera Interface (Unicam)
>> +
>> +maintainers:
>> +  - Dave Stevenson <dave.stevenson at raspberrypi.com>
>> +
>> +description: |-
>> +  The Unicam block on BCM283x SoCs is the receiver for either
>> +  CSI-2 or CCP2 data from image sensors or similar devices.
>> +
>> +  The main platform using this SoC is the Raspberry Pi family of boards.
>> +  On the Pi the VideoCore firmware can also control this hardware block,
>> +  and driving it from two different processors will cause issues.
>> +  To avoid this, the firmware checks the device tree configuration
>> +  during boot. If it finds device tree nodes called csi0 or csi1 then
>> +  it will stop the firmware accessing the block, and it can then
>> +  safely be used via the device tree binding.
> 
> As mentioned in the review of the DT integration, the nodes should
> ideally be called just "csi", not "csi0" and "csi1" (maybe Rob could
> confirm this ?). Dave, is there a way the firmware could be updated to
> also hand over control of the Unicam instances to Linux when a "csi"
> node is found, not just "csi0" or "csi1" ?
> 
> Given that the node names are significant, they should be enforced in
> the YAML schema.
> 
>> +
>> +properties:
>> +  compatible:
>> +    const: brcm,bcm2835-unicam
>> +
>> +  reg:
>> +    description:
>> +      physical base address and length of the register sets for the device.
> 
> This can be dropped.
> 
>> +    maxItems: 1
> 
> There are two items in the example below. How does this validate ?
> 
>> +
>> +  interrupts:
>> +    description: the IRQ line for this Unicam instance.
> 
> This can be dropped.
> 
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    description: |-
>> +      list of clock specifiers, corresponding to entries in clock-names
>> +      property.
> 
>    clocks:
>      items:
>        - description: The clock for ...
>        - description: The clock for ...
> 
> (with the two descriptions matching the LP and VPU clocks, I don't know
> what they are).
> 
>> +
>> +  clock-names:
>> +    items:
>> +      - const: lp
>> +      - const: vpu
>> +
>> +  port:
>> +    $ref: /schemas/graph.yaml#/properties/port
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - interrupts
>> +  - clocks
>> +  - clock-names
>> +  - port
>> +
>> +additionalProperties: False
>> +
>> +examples:
>> +  - |
>> +    csi1: csi1 at 7e801000 {
>> +        compatible = "brcm,bcm2835-unicam";
>> +        reg = <0x7e801000 0x800>,
>> +              <0x7e802004 0x4>;
>> +        interrupts = <2 7>;
> 
> Let's use the Pi 4 device tree as an example, as that's what we're
> upstreaming first.
> 
>> +        clocks = <&clocks BCM2835_CLOCK_CAM1>,
> 
> This will fail to compile without a proper #include, did you get this to
> pass validation ?
> 
>> +                 <&firmware_clocks 4>;
>> +        clock-names = "lp", "vpu";
>> +        port {
>> +                csi1_ep: endpoint {
>> +                        remote-endpoint = <&tc358743_0>;
>> +                        data-lanes = <1 2>;
>> +                };
>> +        };
>> +    };
>> +
>> +    i2c0: i2c at 7e205000 {
>> +        tc358743: csi-hdmi-bridge at 0f {
>> +            compatible = "toshiba,tc358743";
>> +            reg = <0x0f>;
>> +            clocks = <&tc358743_clk>;
>> +            clock-names = "refclk";
>> +
>> +            tc358743_clk: bridge-clk {
>> +                    compatible = "fixed-clock";
>> +                    #clock-cells = <0>;
>> +                    clock-frequency = <27000000>;
>> +            };
>> +
>> +            port {
>> +                    tc358743_0: endpoint {
>> +                            remote-endpoint = <&csi1_ep>;
>> +                            clock-lanes = <0>;
>> +                            data-lanes = <1 2>;
>> +                            clock-noncontinuous;
>> +                            link-frequencies =
>> +                                /bits/ 64 <297000000>;
>> +                    };
>> +            };
>> +        };
>> +    };
> 
> I'd drop this node completely.
> 
>> +...
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 33f75892f98e..07f238fd5ff9 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -3679,6 +3679,12 @@ F:	Documentation/media/v4l-drivers/bcm2835-isp.rst
>>   F:	drivers/staging/vc04_services/bcm2835-isp
>>   F:	include/uapi/linux/bcm2835-isp.h
>>   
>> +BROADCOM BCM2835 CAMERA DRIVER
>> +M:	Raspberry Pi Kernel Maintenance <kernel-list at raspberrypi.com>
>> +L:	linux-media at vger.kernel.org
>> +S:	Maintained
>> +F:	Documentation/devicetree/bindings/media/brcm,bcm2835-unicam.yaml
>> +
>>   BROADCOM BCM47XX MIPS ARCHITECTURE
>>   M:	Hauke Mehrtens <hauke at hauke-m.de>
>>   M:	Rafa? Mi?ecki <zajec5 at gmail.com>
> 


From hverkuil at xs4all.nl  Sat Jan 22 00:40:44 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Sat, 22 Jan 2022 09:40:44 +0100
Subject: [GIT PULL FOR v5.18] Clean up "mediatek,larb"
Message-ID: <7af52d61-47c7-581d-62ed-76a7f8315b16@xs4all.nl>

Hi Mauro,

This is the PR of v10 of this series, minus patches 12 and 13 (Matthias will take those
once this is merged for 5.18):

https://patchwork.linuxtv.org/project/linux-media/cover/20220117070510.17642-1-yong.wu at mediatek.com/

The first two patches are from:

https://patchwork.linuxtv.org/project/linux-media/patch/20211206130425.184420-1-hsinyi at chromium.org/
https://patchwork.linuxtv.org/project/linux-media/patch/20211206130425.184420-2-hsinyi at chromium.org/

since the v10 series depends on that yaml conversion.

This series touches on several subsystems. I believe I have all the relevant Acks etc.
It made the most sense to merge this through the media subsystem since that's the main
target for these changes.

Regards,

	Hans


The following changes since commit 216a6d4965287400d40227601abb6cedcd2addd3:

  media: mtk-vcodec: Remove mtk_vcodec_release_enc_pm (2022-01-21 12:23:48 +0100)

are available in the Git repository at:

  git://linuxtv.org/hverkuil/media_tree.git tags/br-v5.18g

for you to fetch changes up to ae04f1335521a2d8b917c0e4708280e9819ed0e9:

  memory: mtk-smi: Get rid of mtk_smi_larb_get/put (2022-01-22 09:20:30 +0100)

----------------------------------------------------------------
Tag branch

----------------------------------------------------------------
Hsin-Yi Wang (2):
      dt-bindings: mediatek: convert mtk jpeg decoder/encoder to yaml
      dt-bindings: mediatek: Add mediatek, mt8183-jpgenc compatible

Yong Wu (10):
      dt-binding: mediatek: Get rid of mediatek,larb for multimedia HW
      iommu/mediatek-v1: Free the existed fwspec if the master dev already has
      iommu/mediatek: Return ENODEV if the device is NULL
      iommu/mediatek: Add probe_defer for smi-larb
      iommu/mediatek: Add device_link between the consumer and the larb devices
      media: mtk-jpeg: Get rid of mtk_smi_larb_get/put
      media: mtk-mdp: Get rid of mtk_smi_larb_get/put
      drm/mediatek: Get rid of mtk_smi_larb_get/put
      media: mtk-vcodec: Get rid of mtk_smi_larb_get/put
      memory: mtk-smi: Get rid of mtk_smi_larb_get/put

Yongqiang Niu (1):
      drm/mediatek: Add pm runtime support for ovl and rdma

 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt |  9 ------
 Documentation/devicetree/bindings/media/mediatek,vcodec-decoder.yaml |  7 -----
 Documentation/devicetree/bindings/media/mediatek,vcodec-encoder.yaml |  8 ------
 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt    | 38 ------------------------
 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml   | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++
 Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt    | 35 ----------------------
 Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml   | 72 ++++++++++++++++++++++++++++++++++++++++++++++
 Documentation/devicetree/bindings/media/mediatek-mdp.txt             |  8 ------
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c                              |  8 +++++-
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c                             |  9 +++++-
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c                              | 15 +++++-----
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c                          | 36 ++---------------------
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h                          |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c                               |  5 +---
 drivers/iommu/mtk_iommu.c                                            | 34 ++++++++++++++++++++++
 drivers/iommu/mtk_iommu_v1.c                                         | 42 ++++++++++++++++++++++++++-
 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c                      | 45 ++---------------------------
 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h                      |  2 --
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.c                        | 40 --------------------------
 drivers/media/platform/mtk-mdp/mtk_mdp_comp.h                        |  2 --
 drivers/media/platform/mtk-mdp/mtk_mdp_core.c                        |  1 -
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c               |  2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c                |  1 -
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c                | 41 ++++----------------------
 drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h                   |  3 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc.c                   |  1 -
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c               |  2 --
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_pm.c                | 45 ++++-------------------------
 drivers/memory/mtk-smi.c                                             | 14 ---------
 include/soc/mediatek/smi.h                                           | 20 -------------
 30 files changed, 267 insertions(+), 359 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.txt
 create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-decoder.yaml
 delete mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.txt
 create mode 100644 Documentation/devicetree/bindings/media/mediatek-jpeg-encoder.yaml


From wenst at chromium.org  Sat Jan 22 01:17:00 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:00 +0800
Subject: [PATCH 00/31] clk: mediatek: Cleanups and Improvements - Part 1
Message-ID: <20220122091731.283592-1-wenst@chromium.org>

Hi everyone,

This is part 1 of planned work to cleanup, improve, and modernize the
MediaTek clk drivers. The full proposal for the work is included below.

Part 1 involves cleaning up various parts of the MediaTek common clk
driver library:

- Code style cleanups in places touched by other changes
- Code for a given clk type that happened to be split between different
  files is consolidated
- Parts of the implementation, such as the internal data structures and
  registration/unregistration of a single clk, are internalized and no
  longer exported to other parts of the library
- Unregister APIs for all clk types in the library are added
- Remove function added for the simple driver case
- Error handling is added for all clk types
- MT8195 clk drivers cleaned up with error handling and removal support
  added

Adding error handling to the clk driver library results is a change in
its behavior, and might cause some breakage where the affected system
was originally somewhat working, but not completely. The failure would
result from a duplicated clk, either in name or ID. Old behavior was to
skip over these and ignore the error, whereas the new behavior is to
restore changes and error out.

To detect duplicate IDs, an additional warning will now be printed when
such occurrences happen. In a correct driver such things should not
happen though, so maybe we could consider wrapping that in some debug
Kconfig option. That's why I put it as the last patch in this series.

This series was tested on MT8195 with the series applied on the downstream
ChromeOS v5.10 kernel. Some other patches were applied to make this
series apply cleanly, but nothing The cpumux clk type changes were
not tested due to lack of related hardware. However the changes are
very similar to the other types, and I am confident there are no issues.


Full proposal follows:

MediaTek Kernel Clk Driver Improvement

Objective

Modernize the MediaTek clk drivers to support "struct clk_hw" based
registration and local parenting. Also address any deficiencies, such
as lack of proper cleanup and removal of clocks.

Requirements

- Clks should be registered with clk_hw_* APIs
- Clk parents within the same IP block / driver should be described with
  clk_hw pointers, not global clock names
- All clk registration APIs should have corresponding unregister APIs
  for proper cleanup
- All clk drivers should have proper error path cleanup
- Essential clk drivers should not be allowed to be unbound
- Non-essential modular clk drivers should have removal paths

Background

The clk API in the Linux kernel is split into per-user "struct clk"
consumer and per-provider "struct clk_hw" provider APIs. Upstream has
deprecated the use of clk_register() and co APIs that return "struct clk",
and encourages everyone to migrate to the provider APIs.

The MediaTek clk driver is still using the deprecated clk_register() API
to register clocks. As the driver family is based on a common library
shared by all MediaTek platforms, this presents a huge obstacle in the
deprecation and removal of the old API. This also precludes the MediaTek
driver from fully utilizing new features and improvements in the Common
Clock Framework.

One such feature is the ability to reference clock parents directly with
pointers to their respective "struct clk_hw", instead of looking up clock
names in the global clock table. Newer platforms have hundreds of
individual clocks, split amongst a handful of IP blocks. Most of them are
internal nodes of each IP block's clock tree. Reducing the amount of time
spent on global clock name lookups would make clk drivers probe faster
and boost overall boot time.

Indeed, there has already been an attempt by MediaTek to improve this by
hashing the clock names [1] to get around the slow string comparison.
However this doesn't address the primary deficiency of the current driver
implementation.

Design ideas

As the requirements section lists, many improvements can be made to the
driver library and platform drivers. Given the amount of existing
platforms supported by the driver library, and lack of hardware within
ChromeOS for some of them, the most likely approach is to target one
specific platform to do the improvements, and let MediaTek & the broader
kernel community handle the rest.

1. Add proper cleanup code
   - Add "unregister" APIs to each type of clock supported by the driver
     library
   - Add calls to these new APIs to the error paths of existing drivers
   - Add driver removal code for non-essential modular drivers
2. clk_hw_register() support
   - Add matching clk_hw_register_* API variants
     - This should be made as generic as possible (like the clk_hw_register()
       API) to make step 3 easier to implement.
   - Migrate existing platform driver to new APIs
3. Pointer based local parenting
   - Add macros to handle "struct clk_hw" and "struct clk_parent_data"
     ways of describing clock parents
   - Add clock parent descriptions based on "struct clk_hw" to existing
     platform drivers
     - For clocks on the input-side hardware boundary,
       "struct clk_parent_data" should be used to leave room for device
       tree based clock lookups

4. At this point, we should require MediaTek and other parties to use the
   new APIs to implement drivers for new platforms

5. Once all platform drivers have been converted, the old clk_register()
   based APIs can be removed

Alternatives considered

Hashing the clock names and comparing the hash first [1] has been proposed
by MediaTek. However while this does improve performance, the hashing
itself still incurs a cost that could be avoided entirely for most
instances. The only instances where local clock parenting is unusable
and global clock name matching is needed is for clock parents between
different clock provider IP blocks. The number of clocks wired between
blocks is quite large, and MediaTek has avoided describing them in the
device tree.

[1] https://lore.kernel.org/linux-mediatek/20211005065948.10092-1-mark-pk.tsai at mediatek.com/


Chen-Yu Tsai (31):
  clk: mediatek: Use %pe to print errors
  clk: mediatek: gate: Consolidate gate type clk related code
  clk: mediatek: gate: Internalize clk implementation
  clk: mediatek: gate: Implement unregister API
  clk: mediatek: gate: Clean up included headers
  clk: mediatek: cpumux: Implement unregister API
  clk: mediatek: cpumux: Internalize struct mtk_clk_cpumux
  clk: mediatek: cpumux: Clean up included headers
  clk: mediatek: mux: Implement unregister API
  clk: mediatek: mux: Internalize struct mtk_clk_mux
  clk: mediatek: mux: Clean up included headers
  clk: mediatek: pll: Split definitions into separate header file
  clk: mediatek: pll: Implement unregister API
  clk: mediatek: pll: Clean up included headers
  clk: mediatek: Implement mtk_clk_unregister_fixed_clks() API
  clk: mediatek: Implement mtk_clk_unregister_factors() API
  clk: mediatek: Implement mtk_clk_unregister_divider_clks() API
  clk: mediatek: Implement mtk_clk_unregister_composites() API
  clk: mediatek: Add mtk_clk_simple_remove()
  clk: mediatek: mtk: Clean up included headers
  clk: mediatek: cpumux: Implement error handling in register API
  clk: mediatek: gate: Implement error handling in register API
  clk: mediatek: mux: Reverse check for existing clk to reduce nesting
    level
  clk: mediatek: mux: Implement error handling in register API
  clk: mediatek: pll: Implement error handling in register API
  clk: mediatek: mtk: Implement error handling in register APIs
  clk: mediatek: Unregister clks in mtk_clk_simple_probe() error path
  clk: mediatek: mt8195: Hook up mtk_clk_simple_remove()
  clk: mediatek: mt8195: Implement error handling in probe functions
  clk: mediatek: mt8195: Implement remove functions
  clk: mediatek: Warn if clk IDs are duplicated

 drivers/clk/mediatek/clk-apmixed.c            |   2 +-
 drivers/clk/mediatek/clk-cpumux.c             |  69 +++-
 drivers/clk/mediatek/clk-cpumux.h             |  13 +-
 drivers/clk/mediatek/clk-gate.c               | 148 +++++++--
 drivers/clk/mediatek/clk-gate.h               |  59 ++--
 drivers/clk/mediatek/clk-mt2701.c             |   5 +-
 drivers/clk/mediatek/clk-mt2712.c             |   3 +-
 drivers/clk/mediatek/clk-mt6765.c             |   3 +-
 drivers/clk/mediatek/clk-mt6779.c             |   3 +-
 drivers/clk/mediatek/clk-mt6797.c             |   3 +-
 drivers/clk/mediatek/clk-mt7622.c             |   5 +-
 drivers/clk/mediatek/clk-mt7629.c             |   5 +-
 drivers/clk/mediatek/clk-mt7986-apmixed.c     |   4 +-
 drivers/clk/mediatek/clk-mt8135.c             |   3 +-
 drivers/clk/mediatek/clk-mt8167.c             |   3 +-
 drivers/clk/mediatek/clk-mt8173.c             |   5 +-
 drivers/clk/mediatek/clk-mt8183.c             |   3 +-
 drivers/clk/mediatek/clk-mt8192.c             |   3 +-
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c  |  30 +-
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c  |  25 +-
 drivers/clk/mediatek/clk-mt8195-cam.c         |   1 +
 drivers/clk/mediatek/clk-mt8195-ccu.c         |   1 +
 drivers/clk/mediatek/clk-mt8195-img.c         |   1 +
 .../clk/mediatek/clk-mt8195-imp_iic_wrap.c    |   1 +
 drivers/clk/mediatek/clk-mt8195-infra_ao.c    |   1 +
 drivers/clk/mediatek/clk-mt8195-ipe.c         |   1 +
 drivers/clk/mediatek/clk-mt8195-mfg.c         |   1 +
 drivers/clk/mediatek/clk-mt8195-peri_ao.c     |   1 +
 drivers/clk/mediatek/clk-mt8195-scp_adsp.c    |   1 +
 drivers/clk/mediatek/clk-mt8195-topckgen.c    |  69 +++-
 drivers/clk/mediatek/clk-mt8195-vdec.c        |   1 +
 drivers/clk/mediatek/clk-mt8195-vdo0.c        |  20 +-
 drivers/clk/mediatek/clk-mt8195-vdo1.c        |  20 +-
 drivers/clk/mediatek/clk-mt8195-venc.c        |   1 +
 drivers/clk/mediatek/clk-mt8195-vpp0.c        |   1 +
 drivers/clk/mediatek/clk-mt8195-vpp1.c        |   1 +
 drivers/clk/mediatek/clk-mt8195-wpe.c         |   1 +
 drivers/clk/mediatek/clk-mt8516.c             |   3 +-
 drivers/clk/mediatek/clk-mtk.c                | 299 +++++++++++++-----
 drivers/clk/mediatek/clk-mtk.h                | 105 ++----
 drivers/clk/mediatek/clk-mux.c                |  89 +++++-
 drivers/clk/mediatek/clk-mux.h                |  17 +-
 drivers/clk/mediatek/clk-pll.c                |  94 +++++-
 drivers/clk/mediatek/clk-pll.h                |  57 ++++
 drivers/clk/mediatek/reset.c                  |   3 +-
 45 files changed, 891 insertions(+), 293 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-pll.h

-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:01 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:01 +0800
Subject: [PATCH 01/31] clk: mediatek: Use %pe to print errors
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-2-wenst@chromium.org>

If %pe is used to print errors, a string representation of the error
would be printed instead of a number as with %ld. Also, all the sites
printing errors are deriving the error code from a pointer. Using %pe
is more straightforward.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-apmixed.c |  2 +-
 drivers/clk/mediatek/clk-cpumux.c  |  6 ++----
 drivers/clk/mediatek/clk-mtk.c     | 18 ++++++------------
 drivers/clk/mediatek/clk-mux.c     |  6 ++----
 drivers/clk/mediatek/clk-pll.c     |  3 +--
 drivers/clk/mediatek/reset.c       |  3 +--
 6 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c
index caa9119413f1..a29339cc26c4 100644
--- a/drivers/clk/mediatek/clk-apmixed.c
+++ b/drivers/clk/mediatek/clk-apmixed.c
@@ -92,7 +92,7 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
 	clk = clk_register(NULL, &tx->hw);
 
 	if (IS_ERR(clk)) {
-		pr_err("Failed to register clk %s: %ld\n", name, PTR_ERR(clk));
+		pr_err("Failed to register clk %s: %pe\n", name, clk);
 		kfree(tx);
 	}
 
diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index e188018bc906..cab5095416b6 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -87,8 +87,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 
 	regmap = device_node_to_regmap(node);
 	if (IS_ERR(regmap)) {
-		pr_err("Cannot find regmap for %pOF: %ld\n", node,
-		       PTR_ERR(regmap));
+		pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
 		return PTR_ERR(regmap);
 	}
 
@@ -97,8 +96,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 
 		clk = mtk_clk_register_cpumux(mux, regmap);
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-			       mux->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
 			continue;
 		}
 
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 8d5791b3f460..519a461cbb6f 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -70,8 +70,7 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 					      rc->rate);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-					rc->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", rc->name, clk);
 			continue;
 		}
 
@@ -97,8 +96,7 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 				CLK_SET_RATE_PARENT, ff->mult, ff->div);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-					ff->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", ff->name, clk);
 			continue;
 		}
 
@@ -122,8 +120,7 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
 
 	regmap = device_node_to_regmap(node);
 	if (IS_ERR(regmap)) {
-		pr_err("Cannot find regmap for %pOF: %ld\n", node,
-				PTR_ERR(regmap));
+		pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
 		return PTR_ERR(regmap);
 	}
 
@@ -141,8 +138,7 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
 				gate->shift, gate->ops, gate->flags, dev);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-					gate->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
 			continue;
 		}
 
@@ -264,8 +260,7 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 		clk = mtk_clk_register_composite(mc, base, lock);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-					mc->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", mc->name, clk);
 			continue;
 		}
 
@@ -293,8 +288,7 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			mcd->div_width, mcd->clk_divider_flags, lock);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-				mcd->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", mcd->name, clk);
 			continue;
 		}
 
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 6d3a50eb7d6f..89f23e111d91 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -175,8 +175,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 
 	regmap = device_node_to_regmap(node);
 	if (IS_ERR(regmap)) {
-		pr_err("Cannot find regmap for %pOF: %ld\n", node,
-		       PTR_ERR(regmap));
+		pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
 		return PTR_ERR(regmap);
 	}
 
@@ -187,8 +186,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 			clk = mtk_clk_register_mux(mux, regmap, lock);
 
 			if (IS_ERR(clk)) {
-				pr_err("Failed to register clk %s: %ld\n",
-				       mux->name, PTR_ERR(clk));
+				pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
 				continue;
 			}
 
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 60d7ffa0b924..f04f724e12e5 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -378,8 +378,7 @@ void mtk_clk_register_plls(struct device_node *node,
 		clk = mtk_clk_register_pll(pll, base);
 
 		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %ld\n",
-					pll->name, PTR_ERR(clk));
+			pr_err("Failed to register clk %s: %pe\n", pll->name, clk);
 			continue;
 		}
 
diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c
index ffe464ce7ff8..bcec4b89f449 100644
--- a/drivers/clk/mediatek/reset.c
+++ b/drivers/clk/mediatek/reset.c
@@ -100,8 +100,7 @@ static void mtk_register_reset_controller_common(struct device_node *np,
 
 	regmap = device_node_to_regmap(np);
 	if (IS_ERR(regmap)) {
-		pr_err("Cannot find regmap for %pOF: %ld\n", np,
-				PTR_ERR(regmap));
+		pr_err("Cannot find regmap for %pOF: %pe\n", np, regmap);
 		return;
 	}
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:02 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:02 +0800
Subject: [PATCH 02/31] clk: mediatek: gate: Consolidate gate type clk related
 code
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-3-wenst@chromium.org>

Right now some bits of the gate type clk code are in clk-gate.[ch], but
other bits are in clk-mtk.[ch]. This is different from the cpumux and
mux type clks, for which all of the code are found in the same files.

Move the functions that register multiple clks from a given list,
mtk_clk_register_gates_with_dev() and mtk_clk_register_gates(), to
clk-gate.[ch] to consolidate all the code for the gate type clks.

This commit only moves code with minor whitespace fixups to correct
the code style. Further improvements, such as internalizing various
functions and structures will be done in later commits.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-gate.c | 53 ++++++++++++++++++++++++++++++++-
 drivers/clk/mediatek/clk-gate.h | 25 ++++++++++++++++
 drivers/clk/mediatek/clk-mtk.c  | 51 -------------------------------
 drivers/clk/mediatek/clk-mtk.h  | 25 ----------------
 4 files changed, 77 insertions(+), 77 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 5d88b428565b..54921768bfba 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -11,9 +11,9 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
 
 static u32 mtk_get_clockgating(struct clk_hw *hw)
@@ -182,4 +182,55 @@ struct clk *mtk_clk_register_gate(
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_gate);
 
+int mtk_clk_register_gates_with_dev(struct device_node *node,
+				    const struct mtk_gate *clks, int num,
+				    struct clk_onecell_data *clk_data,
+				    struct device *dev)
+{
+	int i;
+	struct clk *clk;
+	struct regmap *regmap;
+
+	if (!clk_data)
+		return -ENOMEM;
+
+	regmap = device_node_to_regmap(node);
+	if (IS_ERR(regmap)) {
+		pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
+		return PTR_ERR(regmap);
+	}
+
+	for (i = 0; i < num; i++) {
+		const struct mtk_gate *gate = &clks[i];
+
+		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
+			continue;
+
+		clk = mtk_clk_register_gate(gate->name, gate->parent_name,
+					    regmap,
+					    gate->regs->set_ofs,
+					    gate->regs->clr_ofs,
+					    gate->regs->sta_ofs,
+					    gate->shift, gate->ops,
+					    gate->flags, dev);
+
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
+			continue;
+		}
+
+		clk_data->clks[gate->id] = clk;
+	}
+
+	return 0;
+}
+
+int mtk_clk_register_gates(struct device_node *node,
+			   const struct mtk_gate *clks, int num,
+			   struct clk_onecell_data *clk_data)
+{
+	return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
+}
+EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 3c3329ec54b7..432b571d23b3 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -43,6 +43,22 @@ struct clk *mtk_clk_register_gate(
 		unsigned long flags,
 		struct device *dev);
 
+struct mtk_gate_regs {
+	u32 sta_ofs;
+	u32 clr_ofs;
+	u32 set_ofs;
+};
+
+struct mtk_gate {
+	int id;
+	const char *name;
+	const char *parent_name;
+	const struct mtk_gate_regs *regs;
+	int shift;
+	const struct clk_ops *ops;
+	unsigned long flags;
+};
+
 #define GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift,	\
 			_ops, _flags) {				\
 		.id = _id,					\
@@ -57,4 +73,13 @@ struct clk *mtk_clk_register_gate(
 #define GATE_MTK(_id, _name, _parent, _regs, _shift, _ops)		\
 	GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, _ops, 0)
 
+int mtk_clk_register_gates(struct device_node *node,
+			   const struct mtk_gate *clks, int num,
+			   struct clk_onecell_data *clk_data);
+
+int mtk_clk_register_gates_with_dev(struct device_node *node,
+				    const struct mtk_gate *clks, int num,
+				    struct clk_onecell_data *clk_data,
+				    struct device *dev);
+
 #endif /* __DRV_CLK_GATE_H */
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 519a461cbb6f..0c5db3c71fdd 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -106,57 +106,6 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
-int mtk_clk_register_gates_with_dev(struct device_node *node,
-		const struct mtk_gate *clks,
-		int num, struct clk_onecell_data *clk_data,
-		struct device *dev)
-{
-	int i;
-	struct clk *clk;
-	struct regmap *regmap;
-
-	if (!clk_data)
-		return -ENOMEM;
-
-	regmap = device_node_to_regmap(node);
-	if (IS_ERR(regmap)) {
-		pr_err("Cannot find regmap for %pOF: %pe\n", node, regmap);
-		return PTR_ERR(regmap);
-	}
-
-	for (i = 0; i < num; i++) {
-		const struct mtk_gate *gate = &clks[i];
-
-		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
-			continue;
-
-		clk = mtk_clk_register_gate(gate->name, gate->parent_name,
-				regmap,
-				gate->regs->set_ofs,
-				gate->regs->clr_ofs,
-				gate->regs->sta_ofs,
-				gate->shift, gate->ops, gate->flags, dev);
-
-		if (IS_ERR(clk)) {
-			pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
-			continue;
-		}
-
-		clk_data->clks[gate->id] = clk;
-	}
-
-	return 0;
-}
-
-int mtk_clk_register_gates(struct device_node *node,
-		const struct mtk_gate *clks,
-		int num, struct clk_onecell_data *clk_data)
-{
-	return mtk_clk_register_gates_with_dev(node,
-		clks, num, clk_data, NULL);
-}
-EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
-
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 0ff289d93452..bdec7dc5e07a 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -150,31 +150,6 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 		int num, void __iomem *base, spinlock_t *lock,
 		struct clk_onecell_data *clk_data);
 
-struct mtk_gate_regs {
-	u32 sta_ofs;
-	u32 clr_ofs;
-	u32 set_ofs;
-};
-
-struct mtk_gate {
-	int id;
-	const char *name;
-	const char *parent_name;
-	const struct mtk_gate_regs *regs;
-	int shift;
-	const struct clk_ops *ops;
-	unsigned long flags;
-};
-
-int mtk_clk_register_gates(struct device_node *node,
-			const struct mtk_gate *clks, int num,
-			struct clk_onecell_data *clk_data);
-
-int mtk_clk_register_gates_with_dev(struct device_node *node,
-		const struct mtk_gate *clks,
-		int num, struct clk_onecell_data *clk_data,
-		struct device *dev);
-
 struct mtk_clk_divider {
 	int id;
 	const char *name;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:03 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:03 +0800
Subject: [PATCH 03/31] clk: mediatek: gate: Internalize clk implementation
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-4-wenst@chromium.org>

struct mtk_clk_gate and mtk_clk_register_gate() are not used outside of
the gate clk library. Only the API that handles a list of clks is used
by the individual platform clk drivers.

Internalize the parts that aren't used outside of the implementation.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-gate.c | 35 ++++++++++++++++++++++-----------
 drivers/clk/mediatek/clk-gate.h | 31 ++---------------------------
 2 files changed, 25 insertions(+), 41 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 54921768bfba..e51cfd8c653c 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -11,11 +11,28 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/container_of.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
 
 #include "clk-gate.h"
 
+struct mtk_clk_gate {
+	struct clk_hw	hw;
+	struct regmap	*regmap;
+	int		set_ofs;
+	int		clr_ofs;
+	int		sta_ofs;
+	u8		bit;
+};
+
+static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw)
+{
+	return container_of(hw, struct mtk_clk_gate, hw);
+}
+
 static u32 mtk_get_clockgating(struct clk_hw *hw)
 {
 	struct mtk_clk_gate *cg = to_mtk_clk_gate(hw);
@@ -140,17 +157,12 @@ const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
 };
 EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
 
-struct clk *mtk_clk_register_gate(
-		const char *name,
-		const char *parent_name,
-		struct regmap *regmap,
-		int set_ofs,
-		int clr_ofs,
-		int sta_ofs,
-		u8 bit,
-		const struct clk_ops *ops,
-		unsigned long flags,
-		struct device *dev)
+static struct clk *mtk_clk_register_gate(const char *name,
+					 const char *parent_name,
+					 struct regmap *regmap, int set_ofs,
+					 int clr_ofs, int sta_ofs, u8 bit,
+					 const struct clk_ops *ops,
+					 unsigned long flags, struct device *dev)
 {
 	struct mtk_clk_gate *cg;
 	struct clk *clk;
@@ -180,7 +192,6 @@ struct clk *mtk_clk_register_gate(
 
 	return clk;
 }
-EXPORT_SYMBOL_GPL(mtk_clk_register_gate);
 
 int mtk_clk_register_gates_with_dev(struct device_node *node,
 				    const struct mtk_gate *clks, int num,
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 432b571d23b3..3d75521ba20c 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -7,42 +7,15 @@
 #ifndef __DRV_CLK_GATE_H
 #define __DRV_CLK_GATE_H
 
-#include <linux/regmap.h>
 #include <linux/clk-provider.h>
-
-struct clk;
-
-struct mtk_clk_gate {
-	struct clk_hw	hw;
-	struct regmap	*regmap;
-	int		set_ofs;
-	int		clr_ofs;
-	int		sta_ofs;
-	u8		bit;
-};
-
-static inline struct mtk_clk_gate *to_mtk_clk_gate(struct clk_hw *hw)
-{
-	return container_of(hw, struct mtk_clk_gate, hw);
-}
+#include <linux/device.h>
+#include <linux/of.h>
 
 extern const struct clk_ops mtk_clk_gate_ops_setclr;
 extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
 extern const struct clk_ops mtk_clk_gate_ops_no_setclr;
 extern const struct clk_ops mtk_clk_gate_ops_no_setclr_inv;
 
-struct clk *mtk_clk_register_gate(
-		const char *name,
-		const char *parent_name,
-		struct regmap *regmap,
-		int set_ofs,
-		int clr_ofs,
-		int sta_ofs,
-		u8 bit,
-		const struct clk_ops *ops,
-		unsigned long flags,
-		struct device *dev);
-
 struct mtk_gate_regs {
 	u32 sta_ofs;
 	u32 clr_ofs;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:04 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:04 +0800
Subject: [PATCH 04/31] clk: mediatek: gate: Implement unregister API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-5-wenst@chromium.org>

The gate clk type within the MediaTek clk driver library only has a
register function, and no corresponding unregister function. This
means there is no way for its users to properly implement cleanup
and removal.

Add a matching unregister function for the gate type clk.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-gate.c | 35 +++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-gate.h |  3 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index e51cfd8c653c..ed1ad5535d41 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -193,6 +193,21 @@ static struct clk *mtk_clk_register_gate(const char *name,
 	return clk;
 }
 
+static void mtk_clk_unregister_gate(struct clk *clk)
+{
+	struct mtk_clk_gate *cg;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	cg = to_mtk_clk_gate(hw);
+
+	clk_unregister(clk);
+	kfree(cg);
+}
+
 int mtk_clk_register_gates_with_dev(struct device_node *node,
 				    const struct mtk_gate *clks, int num,
 				    struct clk_onecell_data *clk_data,
@@ -244,4 +259,24 @@ int mtk_clk_register_gates(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
 
+void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
+			      struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_gate *gate = &clks[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[gate->id]))
+			continue;
+
+		mtk_clk_unregister_gate(clk_data->clks[gate->id]);
+		clk_data->clks[gate->id] = ERR_PTR(-ENOENT);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_gates);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 3d75521ba20c..344adffb6578 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -55,4 +55,7 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
 				    struct clk_onecell_data *clk_data,
 				    struct device *dev);
 
+void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
+			      struct clk_onecell_data *clk_data);
+
 #endif /* __DRV_CLK_GATE_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:05 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:05 +0800
Subject: [PATCH 05/31] clk: mediatek: gate: Clean up included headers
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-6-wenst@chromium.org>

Some included headers aren't actually used anywhere, while other headers
with the declaration of functions and structures aren't directly
included.

Get rid of the unused ones, and add the ones that should be included
directly.

On the header side, replace headers that are included purely for data
structure definitions with forward declarations. This decreases the
amount of preprocessing and compilation effort required for each
inclusion.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-gate.c | 11 +++--------
 drivers/clk/mediatek/clk-gate.h | 10 +++++++---
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index ed1ad5535d41..e8881ae1489a 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -4,18 +4,13 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
-#include <linux/of.h>
-#include <linux/of_address.h>
-
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/clkdev.h>
 #include <linux/clk-provider.h>
-#include <linux/container_of.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/printk.h>
 #include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/types.h>
 
 #include "clk-gate.h"
 
diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h
index 344adffb6578..6b5738826a22 100644
--- a/drivers/clk/mediatek/clk-gate.h
+++ b/drivers/clk/mediatek/clk-gate.h
@@ -7,9 +7,13 @@
 #ifndef __DRV_CLK_GATE_H
 #define __DRV_CLK_GATE_H
 
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/of.h>
+#include <linux/types.h>
+
+struct clk;
+struct clk_onecell_data;
+struct clk_ops;
+struct device;
+struct device_node;
 
 extern const struct clk_ops mtk_clk_gate_ops_setclr;
 extern const struct clk_ops mtk_clk_gate_ops_setclr_inv;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:07 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:07 +0800
Subject: [PATCH 07/31] clk: mediatek: cpumux: Internalize struct mtk_clk_cpumux
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-8-wenst@chromium.org>

struct mtk_clk_cpumux is an implementation detail of the cpumux clk
type, and is not used outside of the implementation.

Internalize the definition to minimize leakage of details and shrink
the header file.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-cpumux.c | 8 ++++++++
 drivers/clk/mediatek/clk-cpumux.h | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 99a819e3673f..344c6399b22f 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -12,6 +12,14 @@
 #include "clk-mtk.h"
 #include "clk-cpumux.h"
 
+struct mtk_clk_cpumux {
+	struct clk_hw	hw;
+	struct regmap	*regmap;
+	u32		reg;
+	u32		mask;
+	u8		shift;
+};
+
 static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw)
 {
 	return container_of(_hw, struct mtk_clk_cpumux, hw);
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
index fda7770fd803..a538f2bbef0d 100644
--- a/drivers/clk/mediatek/clk-cpumux.h
+++ b/drivers/clk/mediatek/clk-cpumux.h
@@ -7,14 +7,6 @@
 #ifndef __DRV_CLK_CPUMUX_H
 #define __DRV_CLK_CPUMUX_H
 
-struct mtk_clk_cpumux {
-	struct clk_hw	hw;
-	struct regmap	*regmap;
-	u32		reg;
-	u32		mask;
-	u8		shift;
-};
-
 int mtk_clk_register_cpumuxes(struct device_node *node,
 			      const struct mtk_composite *clks, int num,
 			      struct clk_onecell_data *clk_data);
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:08 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:08 +0800
Subject: [PATCH 08/31] clk: mediatek: cpumux: Clean up included headers
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-9-wenst@chromium.org>

Some headers with the declaration of functions and structures aren't
directly included. Explicitly include them so that future changes to
other headers would not result in an unexpected build break.

On the header side, add forward declarations for any data structures
whose pointers are used in function signatures. No headers are
required.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-cpumux.c | 3 +++
 drivers/clk/mediatek/clk-cpumux.h | 4 ++++
 2 files changed, 7 insertions(+)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 344c6399b22f..658aee789f44 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -5,8 +5,11 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/container_of.h>
+#include <linux/err.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
 #include "clk-mtk.h"
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
index a538f2bbef0d..b07e89f7c283 100644
--- a/drivers/clk/mediatek/clk-cpumux.h
+++ b/drivers/clk/mediatek/clk-cpumux.h
@@ -7,6 +7,10 @@
 #ifndef __DRV_CLK_CPUMUX_H
 #define __DRV_CLK_CPUMUX_H
 
+struct clk_onecell_data;
+struct device_node;
+struct mtk_composite;
+
 int mtk_clk_register_cpumuxes(struct device_node *node,
 			      const struct mtk_composite *clks, int num,
 			      struct clk_onecell_data *clk_data);
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:09 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:09 +0800
Subject: [PATCH 09/31] clk: mediatek: mux: Implement unregister API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-10-wenst@chromium.org>

The mux clk type within the MediaTek clk driver library only has a
register function, and no corresponding unregister function. This
means there is no way for its users to properly implement cleanup
and removal.

Add a matching unregister function for the mux type clk.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mux.c | 35 ++++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mux.h |  3 +++
 2 files changed, 38 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 89f23e111d91..6f0c22a699c3 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -164,6 +164,21 @@ static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
 	return clk;
 }
 
+static void mtk_clk_unregister_mux(struct clk *clk)
+{
+	struct mtk_clk_mux *mux;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	mux = to_mtk_clk_mux(hw);
+
+	clk_unregister(clk);
+	kfree(mux);
+}
+
 int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 			   int num, struct device_node *node,
 			   spinlock_t *lock,
@@ -198,4 +213,24 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
 
+void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
+			      struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_mux *mux = &muxes[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
+
+		mtk_clk_unregister_mux(clk_data->clks[mux->id]);
+		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_muxes);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
index 27841d649118..cb2ac4f04c58 100644
--- a/drivers/clk/mediatek/clk-mux.h
+++ b/drivers/clk/mediatek/clk-mux.h
@@ -88,4 +88,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 			   spinlock_t *lock,
 			   struct clk_onecell_data *clk_data);
 
+void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
+			      struct clk_onecell_data *clk_data);
+
 #endif /* __DRV_CLK_MTK_MUX_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:10 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:10 +0800
Subject: [PATCH 10/31] clk: mediatek: mux: Internalize struct mtk_clk_mux
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-11-wenst@chromium.org>

struct mtk_clk_mux is an implementation detail of the mux clk type,
and is not used outside of the implementation.

Internalize the definition to minimize leakage of details and shrink
the header file.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mux.c | 8 ++++++++
 drivers/clk/mediatek/clk-mux.h | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 6f0c22a699c3..2d4d8dc0120a 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -13,6 +13,14 @@
 #include "clk-mtk.h"
 #include "clk-mux.h"
 
+struct mtk_clk_mux {
+	struct clk_hw hw;
+	struct regmap *regmap;
+	const struct mtk_mux *data;
+	spinlock_t *lock;
+	bool reparent;
+};
+
 static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
 {
 	return container_of(hw, struct mtk_clk_mux, hw);
diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
index cb2ac4f04c58..38a2b6014b08 100644
--- a/drivers/clk/mediatek/clk-mux.h
+++ b/drivers/clk/mediatek/clk-mux.h
@@ -9,14 +9,6 @@
 
 #include <linux/clk-provider.h>
 
-struct mtk_clk_mux {
-	struct clk_hw hw;
-	struct regmap *regmap;
-	const struct mtk_mux *data;
-	spinlock_t *lock;
-	bool reparent;
-};
-
 struct mtk_mux {
 	int id;
 	const char *name;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:06 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:06 +0800
Subject: [PATCH 06/31] clk: mediatek: cpumux: Implement unregister API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-7-wenst@chromium.org>

The cpumux clk type within the MediaTek clk driver library only has
a register function, and no corresponding unregister function. This
means there is no way for its users to properly implement cleanup
and removal.

Add a matching unregister function for the cpumux type clk.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-cpumux.c | 31 +++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-cpumux.h |  3 +++
 2 files changed, 34 insertions(+)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index cab5095416b6..99a819e3673f 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -77,6 +77,21 @@ mtk_clk_register_cpumux(const struct mtk_composite *mux,
 	return clk;
 }
 
+static void mtk_clk_unregister_cpumux(struct clk *clk)
+{
+	struct mtk_clk_cpumux *cpumux;
+	struct clk_hw *hw;
+
+	hw = __clk_get_hw(clk);
+	if (!hw)
+		return;
+
+	cpumux = to_mtk_clk_cpumux(hw);
+
+	clk_unregister(clk);
+	kfree(cpumux);
+}
+
 int mtk_clk_register_cpumuxes(struct device_node *node,
 			      const struct mtk_composite *clks, int num,
 			      struct clk_onecell_data *clk_data)
@@ -106,4 +121,20 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 	return 0;
 }
 
+void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
+				 struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_composite *mux = &clks[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
+
+		mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
+		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
+	}
+}
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
index 2aaf1afd4e5f..fda7770fd803 100644
--- a/drivers/clk/mediatek/clk-cpumux.h
+++ b/drivers/clk/mediatek/clk-cpumux.h
@@ -19,4 +19,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 			      const struct mtk_composite *clks, int num,
 			      struct clk_onecell_data *clk_data);
 
+void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
+				 struct clk_onecell_data *clk_data);
+
 #endif /* __DRV_CLK_CPUMUX_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:11 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:11 +0800
Subject: [PATCH 11/31] clk: mediatek: mux: Clean up included headers
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-12-wenst@chromium.org>

Some included headers aren't actually used anywhere, while other headers
with the declaration of functions and structures aren't directly
included.

Get rid of the unused ones, and add the ones that should be included
directly.

On the header side, replace headers that are included purely for data
structure definitions with forward declarations. This decreases the
amount of preprocessing and compilation effort required for each
inclusion.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mux.c | 11 +++++++----
 drivers/clk/mediatek/clk-mux.h |  8 +++++++-
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 2d4d8dc0120a..01af6a52711a 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -4,13 +4,16 @@
  * Author: Owen Chen <owen.chen at mediatek.com>
  */
 
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/compiler_types.h>
+#include <linux/container_of.h>
+#include <linux/err.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
 
-#include "clk-mtk.h"
 #include "clk-mux.h"
 
 struct mtk_clk_mux {
diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
index 38a2b6014b08..903a3c937959 100644
--- a/drivers/clk/mediatek/clk-mux.h
+++ b/drivers/clk/mediatek/clk-mux.h
@@ -7,7 +7,13 @@
 #ifndef __DRV_CLK_MTK_MUX_H
 #define __DRV_CLK_MTK_MUX_H
 
-#include <linux/clk-provider.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct clk;
+struct clk_onecell_data;
+struct clk_ops;
+struct device_node;
 
 struct mtk_mux {
 	int id;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:12 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:12 +0800
Subject: [PATCH 12/31] clk: mediatek: pll: Split definitions into separate
 header file
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-13-wenst@chromium.org>

When the PLL type clk was implemented in the MediaTek clk driver
library, the data structure definitions and function declaration
were put in the common header file.

Since it is its own type of clk, and not all platform clk drivers
utilize it, having the definitions in the common header results
in wasted cycles during compilation.

Split out the related definitions and declarations into its own
header file, and include that only in the platform clk drivers that
need it.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mt2701.c            |  5 +-
 drivers/clk/mediatek/clk-mt2712.c            |  3 +-
 drivers/clk/mediatek/clk-mt6765.c            |  3 +-
 drivers/clk/mediatek/clk-mt6779.c            |  3 +-
 drivers/clk/mediatek/clk-mt6797.c            |  3 +-
 drivers/clk/mediatek/clk-mt7622.c            |  5 +-
 drivers/clk/mediatek/clk-mt7629.c            |  5 +-
 drivers/clk/mediatek/clk-mt7986-apmixed.c    |  4 +-
 drivers/clk/mediatek/clk-mt8135.c            |  3 +-
 drivers/clk/mediatek/clk-mt8167.c            |  3 +-
 drivers/clk/mediatek/clk-mt8173.c            |  5 +-
 drivers/clk/mediatek/clk-mt8183.c            |  3 +-
 drivers/clk/mediatek/clk-mt8192.c            |  3 +-
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c |  1 +
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c |  1 +
 drivers/clk/mediatek/clk-mt8516.c            |  3 +-
 drivers/clk/mediatek/clk-mtk.h               | 39 --------------
 drivers/clk/mediatek/clk-pll.c               |  1 +
 drivers/clk/mediatek/clk-pll.h               | 55 ++++++++++++++++++++
 19 files changed, 91 insertions(+), 57 deletions(-)
 create mode 100644 drivers/clk/mediatek/clk-pll.h

diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
index 695be0f77427..1eb3e4563c3f 100644
--- a/drivers/clk/mediatek/clk-mt2701.c
+++ b/drivers/clk/mediatek/clk-mt2701.c
@@ -10,9 +10,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-mtk.h"
-#include "clk-gate.h"
 #include "clk-cpumux.h"
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt2701-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
index a3bd9a107209..ff72b9ab945b 100644
--- a/drivers/clk/mediatek/clk-mt2712.c
+++ b/drivers/clk/mediatek/clk-mt2712.c
@@ -13,8 +13,9 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-pll.h"
+#include "clk-mtk.h"
 
 #include <dt-bindings/clock/mt2712-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
index d77ea5aff292..24829ca3bd1f 100644
--- a/drivers/clk/mediatek/clk-mt6765.c
+++ b/drivers/clk/mediatek/clk-mt6765.c
@@ -12,9 +12,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-mtk.h"
 #include "clk-mux.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt6765-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
index 9825385c9f94..7b61664da18f 100644
--- a/drivers/clk/mediatek/clk-mt6779.c
+++ b/drivers/clk/mediatek/clk-mt6779.c
@@ -10,9 +10,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
+#include "clk-gate.h"
 #include "clk-mtk.h"
 #include "clk-mux.h"
-#include "clk-gate.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt6779-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
index 428eb24ffec5..02259e81625a 100644
--- a/drivers/clk/mediatek/clk-mt6797.c
+++ b/drivers/clk/mediatek/clk-mt6797.c
@@ -9,8 +9,9 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt6797-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
index ef5947e15c75..0e1fb30a1e98 100644
--- a/drivers/clk/mediatek/clk-mt7622.c
+++ b/drivers/clk/mediatek/clk-mt7622.c
@@ -11,9 +11,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-mtk.h"
-#include "clk-gate.h"
 #include "clk-cpumux.h"
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt7622-clk.h>
 #include <linux/clk.h> /* for consumer */
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
index a0ee079670c7..c0e023bf31eb 100644
--- a/drivers/clk/mediatek/clk-mt7629.c
+++ b/drivers/clk/mediatek/clk-mt7629.c
@@ -12,9 +12,10 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-mtk.h"
-#include "clk-gate.h"
 #include "clk-cpumux.h"
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt7629-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
index 98ec3887585f..21d4c82e782a 100644
--- a/drivers/clk/mediatek/clk-mt7986-apmixed.c
+++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
@@ -10,9 +10,11 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
-#include "clk-mtk.h"
+
 #include "clk-gate.h"
+#include "clk-mtk.h"
 #include "clk-mux.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt7986-clk.h>
 #include <linux/clk.h>
diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
index 9b4b645aea99..09ad272d51f1 100644
--- a/drivers/clk/mediatek/clk-mt8135.c
+++ b/drivers/clk/mediatek/clk-mt8135.c
@@ -11,8 +11,9 @@
 #include <linux/mfd/syscon.h>
 #include <dt-bindings/clock/mt8135-clk.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 static DEFINE_SPINLOCK(mt8135_clk_lock);
 
diff --git a/drivers/clk/mediatek/clk-mt8167.c b/drivers/clk/mediatek/clk-mt8167.c
index e5ea10e31799..812b33a57530 100644
--- a/drivers/clk/mediatek/clk-mt8167.c
+++ b/drivers/clk/mediatek/clk-mt8167.c
@@ -12,8 +12,9 @@
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8167-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
index 8f898ac476c0..46b7655feeaa 100644
--- a/drivers/clk/mediatek/clk-mt8173.c
+++ b/drivers/clk/mediatek/clk-mt8173.c
@@ -8,9 +8,10 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 
-#include "clk-mtk.h"
-#include "clk-gate.h"
 #include "clk-cpumux.h"
+#include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8173-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
index 5046852eb0fd..68496554dd3d 100644
--- a/drivers/clk/mediatek/clk-mt8183.c
+++ b/drivers/clk/mediatek/clk-mt8183.c
@@ -11,9 +11,10 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include "clk-gate.h"
 #include "clk-mtk.h"
 #include "clk-mux.h"
-#include "clk-gate.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8183-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
index cbc7c6dbe0f4..5f998aab3bfd 100644
--- a/drivers/clk/mediatek/clk-mt8192.c
+++ b/drivers/clk/mediatek/clk-mt8192.c
@@ -12,9 +12,10 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include "clk-gate.h"
 #include "clk-mtk.h"
 #include "clk-mux.h"
-#include "clk-gate.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8192-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
index 6156ceeed71e..5b1b7dc447eb 100644
--- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
+++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
@@ -5,6 +5,7 @@
 
 #include "clk-gate.h"
 #include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8195-clk.h>
 #include <linux/of_device.h>
diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
index f1c84186346e..db449ff877d7 100644
--- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
+++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
@@ -4,6 +4,7 @@
 // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
 
 #include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8195-clk.h>
 #include <linux/clk-provider.h>
diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c
index 9d4261ecc760..a37143f920ce 100644
--- a/drivers/clk/mediatek/clk-mt8516.c
+++ b/drivers/clk/mediatek/clk-mt8516.c
@@ -11,8 +11,9 @@
 #include <linux/slab.h>
 #include <linux/mfd/syscon.h>
 
-#include "clk-mtk.h"
 #include "clk-gate.h"
+#include "clk-mtk.h"
+#include "clk-pll.h"
 
 #include <dt-bindings/clock/mt8516-clk.h>
 
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index bdec7dc5e07a..168220f85489 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -179,45 +179,6 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
 void mtk_free_clk_data(struct clk_onecell_data *clk_data);
 
-#define HAVE_RST_BAR	BIT(0)
-#define PLL_AO		BIT(1)
-
-struct mtk_pll_div_table {
-	u32 div;
-	unsigned long freq;
-};
-
-struct mtk_pll_data {
-	int id;
-	const char *name;
-	u32 reg;
-	u32 pwr_reg;
-	u32 en_mask;
-	u32 pd_reg;
-	u32 tuner_reg;
-	u32 tuner_en_reg;
-	u8 tuner_en_bit;
-	int pd_shift;
-	unsigned int flags;
-	const struct clk_ops *ops;
-	u32 rst_bar_mask;
-	unsigned long fmin;
-	unsigned long fmax;
-	int pcwbits;
-	int pcwibits;
-	u32 pcw_reg;
-	int pcw_shift;
-	u32 pcw_chg_reg;
-	const struct mtk_pll_div_table *div_table;
-	const char *parent_name;
-	u32 en_reg;
-	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
-};
-
-void mtk_clk_register_plls(struct device_node *node,
-		const struct mtk_pll_data *plls, int num_plls,
-		struct clk_onecell_data *clk_data);
-
 struct clk *mtk_clk_register_ref2usb_tx(const char *name,
 			const char *parent_name, void __iomem *reg);
 
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index f04f724e12e5..64f59554bc9b 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -13,6 +13,7 @@
 #include <linux/delay.h>
 
 #include "clk-mtk.h"
+#include "clk-pll.h"
 
 #define REG_CON0		0
 #define REG_CON1		4
diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
new file mode 100644
index 000000000000..d01b0c38311d
--- /dev/null
+++ b/drivers/clk/mediatek/clk-pll.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2014 MediaTek Inc.
+ * Author: James Liao <jamesjj.liao at mediatek.com>
+ */
+
+#ifndef __DRV_CLK_MTK_PLL_H
+#define __DRV_CLK_MTK_PLL_H
+
+#include <linux/types.h>
+
+struct clk_ops;
+struct clk_onecell_data;
+struct device_node;
+
+struct mtk_pll_div_table {
+	u32 div;
+	unsigned long freq;
+};
+
+#define HAVE_RST_BAR	BIT(0)
+#define PLL_AO		BIT(1)
+
+struct mtk_pll_data {
+	int id;
+	const char *name;
+	u32 reg;
+	u32 pwr_reg;
+	u32 en_mask;
+	u32 pd_reg;
+	u32 tuner_reg;
+	u32 tuner_en_reg;
+	u8 tuner_en_bit;
+	int pd_shift;
+	unsigned int flags;
+	const struct clk_ops *ops;
+	u32 rst_bar_mask;
+	unsigned long fmin;
+	unsigned long fmax;
+	int pcwbits;
+	int pcwibits;
+	u32 pcw_reg;
+	int pcw_shift;
+	u32 pcw_chg_reg;
+	const struct mtk_pll_div_table *div_table;
+	const char *parent_name;
+	u32 en_reg;
+	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
+};
+
+void mtk_clk_register_plls(struct device_node *node,
+			   const struct mtk_pll_data *plls, int num_plls,
+			   struct clk_onecell_data *clk_data);
+
+#endif /* __DRV_CLK_MTK_PLL_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:14 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:14 +0800
Subject: [PATCH 14/31] clk: mediatek: pll: Clean up included headers
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-15-wenst@chromium.org>

Some included headers aren't actually used anywhere, while other headers
with the declaration of functions and structures aren't directly
included.

Get rid of the unused ones, and add the ones that should be included
directly.

Also, expand the MHZ macro with spelled-out "1000 * 1000" to be able
to not include clk-mtk.h. The existing ternary operator is rewritten
in a shortened form to accommodate the expanded macro.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-pll.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 081e0df8203e..9698d1c97cd6 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -4,15 +4,15 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
-#include <linux/of.h>
-#include <linux/of_address.h>
+#include <linux/clk-provider.h>
+#include <linux/container_of.h>
+#include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
 #include <linux/slab.h>
-#include <linux/clkdev.h>
-#include <linux/delay.h>
 
-#include "clk-mtk.h"
 #include "clk-pll.h"
 
 #define REG_CON0		0
@@ -162,7 +162,7 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
 static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
 		u32 freq, u32 fin)
 {
-	unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
+	unsigned long fmin = pll->data->fmin ?: (1000 * 1000 * 1000);
 	const struct mtk_pll_div_table *div_table = pll->data->div_table;
 	u64 _pcw;
 	int ibits;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:15 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:15 +0800
Subject: [PATCH 15/31] clk: mediatek: Implement
 mtk_clk_unregister_fixed_clks() API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-16-wenst@chromium.org>

mtk_clk_register_fixed_clks(), as the name suggests, is used to register
a given list of fixed rate clks. However it is lacking a counterpart
unregister API.

Implement said unregister API so that the various clock platform drivers
can utilize it to do proper unregistration, cleanup and removal.

In the header file, the register function's declaration is also
reformatted to fit code style guidelines.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 20 ++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  6 ++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 0c5db3c71fdd..7c0d5706eed7 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -80,6 +80,26 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
 
+void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+				   struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_fixed_clk *rc = &clks[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[rc->id]))
+			continue;
+
+		clk_unregister_fixed_rate(clk_data->clks[rc->id]);
+		clk_data->clks[rc->id] = ERR_PTR(-ENOENT);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_fixed_clks);
+
 void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 		int num, struct clk_onecell_data *clk_data)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 168220f85489..cc7f920eabb4 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -34,8 +34,10 @@ struct mtk_fixed_clk {
 		.rate = _rate,				\
 	}
 
-void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
-		int num, struct clk_onecell_data *clk_data);
+void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+				 struct clk_onecell_data *clk_data);
+void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+				   struct clk_onecell_data *clk_data);
 
 struct mtk_fixed_factor {
 	int id;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:16 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:16 +0800
Subject: [PATCH 16/31] clk: mediatek: Implement mtk_clk_unregister_factors()
 API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-17-wenst@chromium.org>

mtk_clk_register_factors(), as the name suggests, is used to register
a given list of fixed factor clks. However it is lacking a counterpart
unregister API.

Implement said unregister API so that the various clock platform drivers
can utilize it to do proper unregistration, cleanup and removal.

In the header file, the register function's declaration is also
reformatted to fit code style guidelines.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 20 ++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  6 ++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 7c0d5706eed7..b267b2f04b84 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -126,6 +126,26 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
+void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
+				struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_fixed_factor *ff = &clks[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[ff->id]))
+			continue;
+
+		clk_unregister_fixed_factor(clk_data->clks[ff->id]);
+		clk_data->clks[ff->id] = ERR_PTR(-ENOENT);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_factors);
+
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock)
 {
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index cc7f920eabb4..4db1a97c1250 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -55,8 +55,10 @@ struct mtk_fixed_factor {
 		.div = _div,				\
 	}
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
-		int num, struct clk_onecell_data *clk_data);
+void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
+			      struct clk_onecell_data *clk_data);
+void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
+				struct clk_onecell_data *clk_data);
 
 struct mtk_composite {
 	int id;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:13 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:13 +0800
Subject: [PATCH 13/31] clk: mediatek: pll: Implement unregister API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-14-wenst@chromium.org>

The PLL clk type within the MediaTek clk driver library only has a
register function, and no corresponding unregister function. This
means there is no way for its users to properly implement cleanup
and removal.

Add a matching unregister function for the PLL type clk.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-pll.c | 49 ++++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-pll.h |  2 ++
 2 files changed, 51 insertions(+)

diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 64f59554bc9b..081e0df8203e 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -360,6 +360,15 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
 	return clk;
 }
 
+static void mtk_clk_unregister_pll(struct clk *clk)
+{
+	struct clk_hw *hw = __clk_get_hw(clk);
+	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+	clk_unregister(clk);
+	kfree(pll);
+}
+
 void mtk_clk_register_plls(struct device_node *node,
 		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
 {
@@ -388,4 +397,44 @@ void mtk_clk_register_plls(struct device_node *node,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
 
+static __iomem void *mtk_clk_pll_get_base(struct clk *clk,
+					  const struct mtk_pll_data *data)
+{
+	struct clk_hw *hw = __clk_get_hw(clk);
+	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
+
+	return pll->base_addr - data->reg;
+}
+
+void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
+			     struct clk_onecell_data *clk_data)
+{
+	__iomem void *base = NULL;
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num_plls; i > 0; i--) {
+		const struct mtk_pll_data *pll = &plls[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[pll->id]))
+			continue;
+
+		/*
+		 * This is quite ugly but unfortunately the clks don't have
+		 * any device tied to them, so there's no place to store the
+		 * pointer to the I/O region base address. We have to fetch
+		 * it from one of the registered clks.
+		 */
+		base = mtk_clk_pll_get_base(clk_data->clks[pll->id], pll);
+
+		mtk_clk_unregister_pll(clk_data->clks[pll->id]);
+		clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
+	}
+
+	iounmap(base);
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_plls);
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
index d01b0c38311d..a889b1e472e7 100644
--- a/drivers/clk/mediatek/clk-pll.h
+++ b/drivers/clk/mediatek/clk-pll.h
@@ -51,5 +51,7 @@ struct mtk_pll_data {
 void mtk_clk_register_plls(struct device_node *node,
 			   const struct mtk_pll_data *plls, int num_plls,
 			   struct clk_onecell_data *clk_data);
+void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
+			     struct clk_onecell_data *clk_data);
 
 #endif /* __DRV_CLK_MTK_PLL_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:17 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:17 +0800
Subject: [PATCH 17/31] clk: mediatek: Implement
 mtk_clk_unregister_divider_clks() API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-18-wenst@chromium.org>

mtk_clk_register_divider_clks(), as the name suggests, is used to register
a given list of divider clks. However it is lacking a counterpart
unregister API.

Implement said unregister API so that the various clock platform drivers
can utilize it to do proper unregistration, cleanup and removal.

In the header file, the register function's declaration is also
reformatted to fit code style guidelines.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 19 +++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  8 +++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index b267b2f04b84..3a6dfe445e63 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -286,6 +286,25 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 	}
 }
 
+void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
+				 struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_clk_divider *mcd = &mcds[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
+			continue;
+
+		clk_unregister_divider(clk_data->clks[mcd->id]);
+		clk_data->clks[mcd->id] = ERR_PTR(-ENOENT);
+	}
+}
+
 int mtk_clk_simple_probe(struct platform_device *pdev)
 {
 	const struct mtk_clk_desc *mcd;
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 4db1a97c1250..e3ae22fb0334 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -176,9 +176,11 @@ struct mtk_clk_divider {
 		.div_width = _width,				\
 }
 
-void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
-			int num, void __iomem *base, spinlock_t *lock,
-				struct clk_onecell_data *clk_data);
+void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
+			       void __iomem *base, spinlock_t *lock,
+			       struct clk_onecell_data *clk_data);
+void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
+				 struct clk_onecell_data *clk_data);
 
 struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
 void mtk_free_clk_data(struct clk_onecell_data *clk_data);
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:18 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:18 +0800
Subject: [PATCH 18/31] clk: mediatek: Implement
 mtk_clk_unregister_composites() API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-19-wenst@chromium.org>

mtk_clk_register_composites(), as the name suggests, is used to register
a given list of composite clks. However it is lacking a counterpart
unregister API.

Implement said unregister API so that the various clock platform drivers
can utilize it to do proper unregistration, cleanup and removal.

In the header file, the register function's declaration is also
reformatted to fit code style guidelines.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 41 ++++++++++++++++++++++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 3a6dfe445e63..2150ed8678e0 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -233,6 +233,27 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 	return ERR_PTR(ret);
 }
 
+static void mtk_clk_unregister_composite(struct clk *clk)
+{
+	struct clk_hw *hw = __clk_get_hw(clk);
+	struct clk_composite *composite = to_clk_composite(hw);
+	struct clk_mux *mux = NULL;
+	struct clk_gate *gate = NULL;
+	struct clk_divider *div = NULL;
+
+	if (composite->mux_hw)
+		mux = to_clk_mux(composite->mux_hw);
+	if (composite->gate_hw)
+		gate = to_clk_gate(composite->gate_hw);
+	if (composite->rate_hw)
+		div = to_clk_divider(composite->rate_hw);
+
+	clk_unregister_composite(clk);
+	kfree(div);
+	kfree(gate);
+	kfree(mux);
+}
+
 void mtk_clk_register_composites(const struct mtk_composite *mcs,
 		int num, void __iomem *base, spinlock_t *lock,
 		struct clk_onecell_data *clk_data)
@@ -259,6 +280,26 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
 
+void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
+				   struct clk_onecell_data *clk_data)
+{
+	int i;
+
+	if (!clk_data)
+		return;
+
+	for (i = num; i > 0; i--) {
+		const struct mtk_composite *mc = &mcs[i - 1];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mc->id]))
+			continue;
+
+		mtk_clk_unregister_composite(clk_data->clks[mc->id]);
+		clk_data->clks[mc->id] = ERR_PTR(-ENOENT);
+	}
+}
+EXPORT_SYMBOL_GPL(mtk_clk_unregister_composites);
+
 void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 			int num, void __iomem *base, spinlock_t *lock,
 				struct clk_onecell_data *clk_data)
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index e3ae22fb0334..3c3a934f53cd 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -153,6 +153,8 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 void mtk_clk_register_composites(const struct mtk_composite *mcs,
 		int num, void __iomem *base, spinlock_t *lock,
 		struct clk_onecell_data *clk_data);
+void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
+				   struct clk_onecell_data *clk_data);
 
 struct mtk_clk_divider {
 	int id;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:19 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:19 +0800
Subject: [PATCH 19/31] clk: mediatek: Add mtk_clk_simple_remove()
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-20-wenst@chromium.org>

In commit c58cd0e40ffa ("clk: mediatek: Add mtk_clk_simple_probe() to
simplify clock providers"), a generic probe function was added to
simplify clk drivers that only needed to support clk gates. However due
to the lack of unregister APIs, a corresponding remove function was not
added.

Now that the unregister APIs have been implemented, add aforementioned
remove function to make it complete.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 15 +++++++++++++++
 drivers/clk/mediatek/clk-mtk.h |  1 +
 2 files changed, 16 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 2150ed8678e0..cd76e1d80242 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -369,6 +369,8 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 	if (r)
 		goto free_data;
 
+	platform_set_drvdata(pdev, clk_data);
+
 	return r;
 
 free_data:
@@ -376,4 +378,17 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 	return r;
 }
 
+int mtk_clk_simple_remove(struct platform_device *pdev)
+{
+	const struct mtk_clk_desc *mcd = of_device_get_match_data(&pdev->dev);
+	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
+	mtk_free_clk_data(clk_data);
+
+	return 0;
+}
+
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 3c3a934f53cd..4fa658f5d934 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -202,5 +202,6 @@ struct mtk_clk_desc {
 };
 
 int mtk_clk_simple_probe(struct platform_device *pdev);
+int mtk_clk_simple_remove(struct platform_device *pdev);
 
 #endif /* __DRV_CLK_MTK_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:20 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:20 +0800
Subject: [PATCH 20/31] clk: mediatek: mtk: Clean up included headers
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-21-wenst@chromium.org>

Some included headers aren't actually used anywhere, while other headers
with the declaration of functions and structures aren't directly
included.

Get rid of the unused ones, and add the ones that should be included
directly.

On the header side, replace headers that are included purely for data
structure definitions with forward declarations. This decreases the
amount of preprocessing and compilation effort required for each
inclusion.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 13 ++++++-------
 drivers/clk/mediatek/clk-mtk.h | 12 ++++++------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index cd76e1d80242..d2c50186cceb 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -4,17 +4,16 @@
  * Author: James Liao <jamesjj.liao at mediatek.com>
  */
 
-#include <linux/of.h>
-#include <linux/of_address.h>
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
 #include <linux/err.h>
 #include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/clkdev.h>
-#include <linux/module.h>
 #include <linux/mfd/syscon.h>
-#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "clk-mtk.h"
 #include "clk-gate.h"
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 4fa658f5d934..7f902581a115 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -7,19 +7,19 @@
 #ifndef __DRV_CLK_MTK_H
 #define __DRV_CLK_MTK_H
 
-#include <linux/regmap.h>
-#include <linux/bitops.h>
 #include <linux/clk-provider.h>
-#include <linux/platform_device.h>
-
-struct clk;
-struct clk_onecell_data;
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
 
 #define MAX_MUX_GATE_BIT	31
 #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
 
 #define MHZ (1000 * 1000)
 
+struct platform_device;
+
 struct mtk_fixed_clk {
 	int id;
 	const char *name;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:21 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:21 +0800
Subject: [PATCH 21/31] clk: mediatek: cpumux: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-22-wenst@chromium.org>

The cpumux clk type registration function does not stop or return errors
if any clk failed to be registered, nor does it implement an error
handling path. This may result in a partially working device if any
step failed.

Make the register function return proper error codes, and bail out if
errors occur. Proper cleanup, i.e. unregister any clks that were
successfully registered, is done in the new error path.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-cpumux.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 658aee789f44..499c60432280 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -123,13 +123,26 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 		clk = mtk_clk_register_cpumux(mux, regmap);
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
-			continue;
+			goto err;
 		}
 
 		clk_data->clks[mux->id] = clk;
 	}
 
 	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_composite *mux = &clks[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
+
+		mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
+		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
+	}
+
+	return PTR_ERR(clk);
 }
 
 void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:22 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:22 +0800
Subject: [PATCH 22/31] clk: mediatek: gate: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-23-wenst@chromium.org>

The gate clk type registration function does not stop or return errors
if any clk failed to be registered, nor does it implement an error
handling path. This may result in a partially working device if any
step failed.

Make the register function return proper error codes, and bail out if
errors occur. Proper cleanup, i.e. unregister any clks that were
successfully registered, is done in the new error path.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-gate.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index e8881ae1489a..631ff170b7b9 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -237,13 +237,26 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
-			continue;
+			goto err;
 		}
 
 		clk_data->clks[gate->id] = clk;
 	}
 
 	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_gate *gate = &clks[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[gate->id]))
+			continue;
+
+		mtk_clk_unregister_gate(clk_data->clks[gate->id]);
+		clk_data->clks[gate->id] = ERR_PTR(-ENOENT);
+	}
+
+	return PTR_ERR(clk);
 }
 
 int mtk_clk_register_gates(struct device_node *node,
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:25 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:25 +0800
Subject: [PATCH 25/31] clk: mediatek: pll: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-26-wenst@chromium.org>

The pll clk type registration function does not stop or return errors
if any clk failed to be registered, nor does it implement an error
handling path. This may result in a partially working device if any
step failed.

Make the register function return proper error codes, and bail out if
errors occur. Proper cleanup, i.e. unregister any clks that were
successfully registered, and unmap the I/O space, is done in the new
error path.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-pll.c | 23 +++++++++++++++++++----
 drivers/clk/mediatek/clk-pll.h |  6 +++---
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 9698d1c97cd6..1dd15f560659 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -369,8 +369,9 @@ static void mtk_clk_unregister_pll(struct clk *clk)
 	kfree(pll);
 }
 
-void mtk_clk_register_plls(struct device_node *node,
-		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
+int mtk_clk_register_plls(struct device_node *node,
+			  const struct mtk_pll_data *plls, int num_plls,
+			  struct clk_onecell_data *clk_data)
 {
 	void __iomem *base;
 	int i;
@@ -379,7 +380,7 @@ void mtk_clk_register_plls(struct device_node *node,
 	base = of_iomap(node, 0);
 	if (!base) {
 		pr_err("%s(): ioremap failed\n", __func__);
-		return;
+		return -EINVAL;
 	}
 
 	for (i = 0; i < num_plls; i++) {
@@ -389,11 +390,25 @@ void mtk_clk_register_plls(struct device_node *node,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", pll->name, clk);
-			continue;
+			goto err;
 		}
 
 		clk_data->clks[pll->id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_pll_data *pll = &plls[i];
+
+		mtk_clk_unregister_pll(clk_data->clks[pll->id]);
+		clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
+	};
+
+	iounmap(base);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
 
diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
index a889b1e472e7..bf06e44caef9 100644
--- a/drivers/clk/mediatek/clk-pll.h
+++ b/drivers/clk/mediatek/clk-pll.h
@@ -48,9 +48,9 @@ struct mtk_pll_data {
 	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
 };
 
-void mtk_clk_register_plls(struct device_node *node,
-			   const struct mtk_pll_data *plls, int num_plls,
-			   struct clk_onecell_data *clk_data);
+int mtk_clk_register_plls(struct device_node *node,
+			  const struct mtk_pll_data *plls, int num_plls,
+			  struct clk_onecell_data *clk_data);
 void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
 			     struct clk_onecell_data *clk_data);
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:24 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:24 +0800
Subject: [PATCH 24/31] clk: mediatek: mux: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-25-wenst@chromium.org>

The mux clk type registration function does not stop or return errors
if any clk failed to be registered, nor does it implement an error
handling path. This may result in a partially working device if any
step failed.

Make the register function return proper error codes, and bail out if
errors occur. Proper cleanup, i.e. unregister any clks that were
successfully registered, is done in the new error path.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mux.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 70aa42144632..f51e67650f03 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -215,13 +215,26 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
-			continue;
+			goto err;
 		}
 
 		clk_data->clks[mux->id] = clk;
 	}
 
 	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_mux *mux = &muxes[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
+
+		mtk_clk_unregister_mux(clk_data->clks[mux->id]);
+		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
+	}
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:23 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:23 +0800
Subject: [PATCH 23/31] clk: mediatek: mux: Reverse check for existing clk to
 reduce nesting level
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-24-wenst@chromium.org>

The clk registration code here currently does:

    if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
            ... do clk registration ...
    }

This extra level of nesting wastes screen real estate.

Reduce the nesting level by reversing the conditional shown above.
Other than that, functionality is not changed.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mux.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index 01af6a52711a..70aa42144632 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -208,16 +208,17 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 	for (i = 0; i < num; i++) {
 		const struct mtk_mux *mux = &muxes[i];
 
-		if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
-			clk = mtk_clk_register_mux(mux, regmap, lock);
+		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+			continue;
 
-			if (IS_ERR(clk)) {
-				pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
-				continue;
-			}
+		clk = mtk_clk_register_mux(mux, regmap, lock);
 
-			clk_data->clks[mux->id] = clk;
+		if (IS_ERR(clk)) {
+			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
+			continue;
 		}
+
+		clk_data->clks[mux->id] = clk;
 	}
 
 	return 0;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:26 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:26 +0800
Subject: [PATCH 26/31] clk: mediatek: mtk: Implement error handling in
 register APIs
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-27-wenst@chromium.org>

The remaining clk registration functions do not stop or return errors
if any clk failed to be registered, nor do they implement error
handling paths. This may result in a partially working device if any
step fails.

Make the register functions return proper error codes, and bail out if
errors occur. Proper cleanup, i.e. unregister any clks that were
successfully registered, is done in the new error path.

This also makes the |struct clk_data *| argument mandatory, as it is
used to track the list of clks registered.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 118 ++++++++++++++++++++++++++-------
 drivers/clk/mediatek/clk-mtk.h |  20 +++---
 2 files changed, 103 insertions(+), 35 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index d2c50186cceb..e1977c8e130a 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -53,16 +53,19 @@ void mtk_free_clk_data(struct clk_onecell_data *clk_data)
 	kfree(clk_data);
 }
 
-void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
-		int num, struct clk_onecell_data *clk_data)
+int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+				struct clk_onecell_data *clk_data)
 {
 	int i;
 	struct clk *clk;
 
+	if (!clk_data)
+		return -ENOMEM;
+
 	for (i = 0; i < num; i++) {
 		const struct mtk_fixed_clk *rc = &clks[i];
 
-		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id]))
 			continue;
 
 		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
@@ -70,12 +73,26 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", rc->name, clk);
-			continue;
+			goto err;
 		}
 
-		if (clk_data)
-			clk_data->clks[rc->id] = clk;
+		clk_data->clks[rc->id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_fixed_clk *rc = &clks[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[rc->id]))
+			continue;
+
+		clk_unregister_fixed_rate(clk_data->clks[rc->id]);
+		clk_data->clks[rc->id] = ERR_PTR(-ENOENT);
+	}
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
 
@@ -99,16 +116,19 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_unregister_fixed_clks);
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
-		int num, struct clk_onecell_data *clk_data)
+int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
+			     struct clk_onecell_data *clk_data)
 {
 	int i;
 	struct clk *clk;
 
+	if (!clk_data)
+		return -ENOMEM;
+
 	for (i = 0; i < num; i++) {
 		const struct mtk_fixed_factor *ff = &clks[i];
 
-		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id]))
 			continue;
 
 		clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
@@ -116,12 +136,26 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", ff->name, clk);
-			continue;
+			goto err;
 		}
 
-		if (clk_data)
-			clk_data->clks[ff->id] = clk;
+		clk_data->clks[ff->id] = clk;
+	}
+
+	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_fixed_factor *ff = &clks[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[ff->id]))
+			continue;
+
+		clk_unregister_fixed_factor(clk_data->clks[ff->id]);
+		clk_data->clks[ff->id] = ERR_PTR(-ENOENT);
 	}
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
 
@@ -253,13 +287,16 @@ static void mtk_clk_unregister_composite(struct clk *clk)
 	kfree(mux);
 }
 
-void mtk_clk_register_composites(const struct mtk_composite *mcs,
-		int num, void __iomem *base, spinlock_t *lock,
-		struct clk_onecell_data *clk_data)
+int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
+				void __iomem *base, spinlock_t *lock,
+				struct clk_onecell_data *clk_data)
 {
 	struct clk *clk;
 	int i;
 
+	if (!clk_data)
+		return -ENOMEM;
+
 	for (i = 0; i < num; i++) {
 		const struct mtk_composite *mc = &mcs[i];
 
@@ -270,12 +307,26 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", mc->name, clk);
-			continue;
+			goto err;
 		}
 
-		if (clk_data)
-			clk_data->clks[mc->id] = clk;
+		clk_data->clks[mc->id] = clk;
+	}
+
+	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_composite *mc = &mcs[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mcs->id]))
+			continue;
+
+		mtk_clk_unregister_composite(clk_data->clks[mc->id]);
+		clk_data->clks[mc->id] = ERR_PTR(-ENOENT);
 	}
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
 
@@ -299,17 +350,20 @@ void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
 }
 EXPORT_SYMBOL_GPL(mtk_clk_unregister_composites);
 
-void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
-			int num, void __iomem *base, spinlock_t *lock,
-				struct clk_onecell_data *clk_data)
+int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
+			      void __iomem *base, spinlock_t *lock,
+			      struct clk_onecell_data *clk_data)
 {
 	struct clk *clk;
 	int i;
 
+	if (!clk_data)
+		return -ENOMEM;
+
 	for (i = 0; i <  num; i++) {
 		const struct mtk_clk_divider *mcd = &mcds[i];
 
-		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
 			continue;
 
 		clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
@@ -318,12 +372,26 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
 
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", mcd->name, clk);
-			continue;
+			goto err;
 		}
 
-		if (clk_data)
-			clk_data->clks[mcd->id] = clk;
+		clk_data->clks[mcd->id] = clk;
+	}
+
+	return 0;
+
+err:
+	while (--i >= 0) {
+		const struct mtk_clk_divider *mcd = &mcds[i];
+
+		if (IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
+			continue;
+
+		mtk_clk_unregister_composite(clk_data->clks[mcd->id]);
+		clk_data->clks[mcd->id] = ERR_PTR(-ENOENT);
 	}
+
+	return PTR_ERR(clk);
 }
 
 void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 7f902581a115..bf6565aa7319 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -34,8 +34,8 @@ struct mtk_fixed_clk {
 		.rate = _rate,				\
 	}
 
-void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
-				 struct clk_onecell_data *clk_data);
+int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
+				struct clk_onecell_data *clk_data);
 void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
 				   struct clk_onecell_data *clk_data);
 
@@ -55,8 +55,8 @@ struct mtk_fixed_factor {
 		.div = _div,				\
 	}
 
-void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
-			      struct clk_onecell_data *clk_data);
+int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
+			     struct clk_onecell_data *clk_data);
 void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
 				struct clk_onecell_data *clk_data);
 
@@ -150,9 +150,9 @@ struct mtk_composite {
 struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
 		void __iomem *base, spinlock_t *lock);
 
-void mtk_clk_register_composites(const struct mtk_composite *mcs,
-		int num, void __iomem *base, spinlock_t *lock,
-		struct clk_onecell_data *clk_data);
+int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
+				void __iomem *base, spinlock_t *lock,
+				struct clk_onecell_data *clk_data);
 void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
 				   struct clk_onecell_data *clk_data);
 
@@ -178,9 +178,9 @@ struct mtk_clk_divider {
 		.div_width = _width,				\
 }
 
-void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
-			       void __iomem *base, spinlock_t *lock,
-			       struct clk_onecell_data *clk_data);
+int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
+			      void __iomem *base, spinlock_t *lock,
+			      struct clk_onecell_data *clk_data);
 void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
 				 struct clk_onecell_data *clk_data);
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:28 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:28 +0800
Subject: [PATCH 28/31] clk: mediatek: mt8195: Hook up mtk_clk_simple_remove()
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-29-wenst@chromium.org>

Various small clock controllers only have clock gates, and utilize
mtk_clk_simple_probe() as their driver probe function.

Now that we have a matching remove function, hook it up for the relevant
drivers. This was done with the following command:

sed -i -e '/mtk_clk_simple_probe/a \
        .remove = mtk_clk_simple_remove,' drivers/clk/mediatek/clk-mt8195-*.c

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mt8195-cam.c          | 1 +
 drivers/clk/mediatek/clk-mt8195-ccu.c          | 1 +
 drivers/clk/mediatek/clk-mt8195-img.c          | 1 +
 drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c | 1 +
 drivers/clk/mediatek/clk-mt8195-infra_ao.c     | 1 +
 drivers/clk/mediatek/clk-mt8195-ipe.c          | 1 +
 drivers/clk/mediatek/clk-mt8195-mfg.c          | 1 +
 drivers/clk/mediatek/clk-mt8195-peri_ao.c      | 1 +
 drivers/clk/mediatek/clk-mt8195-scp_adsp.c     | 1 +
 drivers/clk/mediatek/clk-mt8195-vdec.c         | 1 +
 drivers/clk/mediatek/clk-mt8195-venc.c         | 1 +
 drivers/clk/mediatek/clk-mt8195-vpp0.c         | 1 +
 drivers/clk/mediatek/clk-mt8195-vpp1.c         | 1 +
 drivers/clk/mediatek/clk-mt8195-wpe.c          | 1 +
 14 files changed, 14 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt8195-cam.c b/drivers/clk/mediatek/clk-mt8195-cam.c
index 3d261fc3848e..e4d00fe6e757 100644
--- a/drivers/clk/mediatek/clk-mt8195-cam.c
+++ b/drivers/clk/mediatek/clk-mt8195-cam.c
@@ -134,6 +134,7 @@ static const struct of_device_id of_match_clk_mt8195_cam[] = {
 
 static struct platform_driver clk_mt8195_cam_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-cam",
 		.of_match_table = of_match_clk_mt8195_cam,
diff --git a/drivers/clk/mediatek/clk-mt8195-ccu.c b/drivers/clk/mediatek/clk-mt8195-ccu.c
index f846f1d73605..4e326b6301ba 100644
--- a/drivers/clk/mediatek/clk-mt8195-ccu.c
+++ b/drivers/clk/mediatek/clk-mt8195-ccu.c
@@ -42,6 +42,7 @@ static const struct of_device_id of_match_clk_mt8195_ccu[] = {
 
 static struct platform_driver clk_mt8195_ccu_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-ccu",
 		.of_match_table = of_match_clk_mt8195_ccu,
diff --git a/drivers/clk/mediatek/clk-mt8195-img.c b/drivers/clk/mediatek/clk-mt8195-img.c
index 22b52a8f15fe..12f5c436d075 100644
--- a/drivers/clk/mediatek/clk-mt8195-img.c
+++ b/drivers/clk/mediatek/clk-mt8195-img.c
@@ -88,6 +88,7 @@ static const struct of_device_id of_match_clk_mt8195_img[] = {
 
 static struct platform_driver clk_mt8195_img_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-img",
 		.of_match_table = of_match_clk_mt8195_img,
diff --git a/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
index 4ab312eb26a5..fbc809d05072 100644
--- a/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
+++ b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
@@ -58,6 +58,7 @@ static const struct of_device_id of_match_clk_mt8195_imp_iic_wrap[] = {
 
 static struct platform_driver clk_mt8195_imp_iic_wrap_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-imp_iic_wrap",
 		.of_match_table = of_match_clk_mt8195_imp_iic_wrap,
diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
index 5f9b69967459..8ebe3b9415c4 100644
--- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c
+++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
@@ -198,6 +198,7 @@ static const struct of_device_id of_match_clk_mt8195_infra_ao[] = {
 
 static struct platform_driver clk_mt8195_infra_ao_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-infra_ao",
 		.of_match_table = of_match_clk_mt8195_infra_ao,
diff --git a/drivers/clk/mediatek/clk-mt8195-ipe.c b/drivers/clk/mediatek/clk-mt8195-ipe.c
index fc1d42b6ac84..b0d745cf7752 100644
--- a/drivers/clk/mediatek/clk-mt8195-ipe.c
+++ b/drivers/clk/mediatek/clk-mt8195-ipe.c
@@ -43,6 +43,7 @@ static const struct of_device_id of_match_clk_mt8195_ipe[] = {
 
 static struct platform_driver clk_mt8195_ipe_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-ipe",
 		.of_match_table = of_match_clk_mt8195_ipe,
diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
index aca6d9c0837c..9411c556a5a9 100644
--- a/drivers/clk/mediatek/clk-mt8195-mfg.c
+++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
@@ -39,6 +39,7 @@ static const struct of_device_id of_match_clk_mt8195_mfg[] = {
 
 static struct platform_driver clk_mt8195_mfg_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-mfg",
 		.of_match_table = of_match_clk_mt8195_mfg,
diff --git a/drivers/clk/mediatek/clk-mt8195-peri_ao.c b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
index 907a92b22de8..2f6b3bb657db 100644
--- a/drivers/clk/mediatek/clk-mt8195-peri_ao.c
+++ b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
@@ -54,6 +54,7 @@ static const struct of_device_id of_match_clk_mt8195_peri_ao[] = {
 
 static struct platform_driver clk_mt8195_peri_ao_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-peri_ao",
 		.of_match_table = of_match_clk_mt8195_peri_ao,
diff --git a/drivers/clk/mediatek/clk-mt8195-scp_adsp.c b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
index 26b4846c5894..e16c383f631b 100644
--- a/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
+++ b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
@@ -39,6 +39,7 @@ static const struct of_device_id of_match_clk_mt8195_scp_adsp[] = {
 
 static struct platform_driver clk_mt8195_scp_adsp_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-scp_adsp",
 		.of_match_table = of_match_clk_mt8195_scp_adsp,
diff --git a/drivers/clk/mediatek/clk-mt8195-vdec.c b/drivers/clk/mediatek/clk-mt8195-vdec.c
index a1df04f42a90..a1446b666385 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdec.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdec.c
@@ -96,6 +96,7 @@ static const struct of_device_id of_match_clk_mt8195_vdec[] = {
 
 static struct platform_driver clk_mt8195_vdec_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-vdec",
 		.of_match_table = of_match_clk_mt8195_vdec,
diff --git a/drivers/clk/mediatek/clk-mt8195-venc.c b/drivers/clk/mediatek/clk-mt8195-venc.c
index 7339851a0856..622f57804f96 100644
--- a/drivers/clk/mediatek/clk-mt8195-venc.c
+++ b/drivers/clk/mediatek/clk-mt8195-venc.c
@@ -61,6 +61,7 @@ static const struct of_device_id of_match_clk_mt8195_venc[] = {
 
 static struct platform_driver clk_mt8195_venc_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-venc",
 		.of_match_table = of_match_clk_mt8195_venc,
diff --git a/drivers/clk/mediatek/clk-mt8195-vpp0.c b/drivers/clk/mediatek/clk-mt8195-vpp0.c
index c3241466a8d0..bf2939c3a023 100644
--- a/drivers/clk/mediatek/clk-mt8195-vpp0.c
+++ b/drivers/clk/mediatek/clk-mt8195-vpp0.c
@@ -102,6 +102,7 @@ static const struct of_device_id of_match_clk_mt8195_vpp0[] = {
 
 static struct platform_driver clk_mt8195_vpp0_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-vpp0",
 		.of_match_table = of_match_clk_mt8195_vpp0,
diff --git a/drivers/clk/mediatek/clk-mt8195-vpp1.c b/drivers/clk/mediatek/clk-mt8195-vpp1.c
index ce0b9a40a179..ffd52c762890 100644
--- a/drivers/clk/mediatek/clk-mt8195-vpp1.c
+++ b/drivers/clk/mediatek/clk-mt8195-vpp1.c
@@ -100,6 +100,7 @@ static const struct of_device_id of_match_clk_mt8195_vpp1[] = {
 
 static struct platform_driver clk_mt8195_vpp1_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-vpp1",
 		.of_match_table = of_match_clk_mt8195_vpp1,
diff --git a/drivers/clk/mediatek/clk-mt8195-wpe.c b/drivers/clk/mediatek/clk-mt8195-wpe.c
index 274d60838d8e..b483fab10e18 100644
--- a/drivers/clk/mediatek/clk-mt8195-wpe.c
+++ b/drivers/clk/mediatek/clk-mt8195-wpe.c
@@ -135,6 +135,7 @@ static const struct of_device_id of_match_clk_mt8195_wpe[] = {
 
 static struct platform_driver clk_mt8195_wpe_drv = {
 	.probe = mtk_clk_simple_probe,
+	.remove = mtk_clk_simple_remove,
 	.driver = {
 		.name = "clk-mt8195-wpe",
 		.of_match_table = of_match_clk_mt8195_wpe,
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:27 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:27 +0800
Subject: [PATCH 27/31] clk: mediatek: Unregister clks in
 mtk_clk_simple_probe() error path
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-28-wenst@chromium.org>

Until now the mediatek clk driver library did not have any way to
unregister clks, and so all drivers did not do proper cleanup in
their error paths.

Now that the library does have APIs to unregister clks, use them
in the error path of mtk_clk_simple_probe() to do proper cleanup.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mtk.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index e1977c8e130a..6d0b8842971b 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -434,12 +434,14 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_data;
+		goto unregister_clks;
 
 	platform_set_drvdata(pdev, clk_data);
 
 	return r;
 
+unregister_clks:
+	mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
 free_data:
 	mtk_free_clk_data(clk_data);
 	return r;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:29 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:29 +0800
Subject: [PATCH 29/31] clk: mediatek: mt8195: Implement error handling in
 probe functions
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-30-wenst@chromium.org>

Until now the mediatek clk driver library did not have any way to
unregister clks, and so all drivers did not do proper cleanup in
their error paths.

Now that the library does have APIs to unregister clks, use them
in the error path of the probe functions for the mt8195 clk drivers
to do proper cleanup.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 13 ++++--
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 11 ++++-
 drivers/clk/mediatek/clk-mt8195-topckgen.c   | 49 +++++++++++++++-----
 drivers/clk/mediatek/clk-mt8195-vdo0.c       |  4 +-
 drivers/clk/mediatek/clk-mt8195-vdo1.c       |  4 +-
 5 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
index 5b1b7dc447eb..af8d80f25f30 100644
--- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
+++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
@@ -120,17 +120,24 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
 	if (!clk_data)
 		return -ENOMEM;
 
-	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
-	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+	r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 	if (r)
 		goto free_apmixed_data;
 
+	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+	if (r)
+		goto unregister_plls;
+
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_apmixed_data;
+		goto unregister_gates;
 
 	return r;
 
+unregister_gates:
+	mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+unregister_plls:
+	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 free_apmixed_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
index db449ff877d7..1fff6f3d2dc7 100644
--- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
+++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
@@ -66,13 +66,20 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
 	if (!clk_data)
 		return -ENOMEM;
 
-	mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
-	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
 	if (r)
 		goto free_apusys_pll_data;
 
+	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
+	if (r)
+		goto unregister_plls;
+
+	platform_set_drvdata(pdev, clk_data);
+
 	return r;
 
+unregister_plls:
+	mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
 free_apusys_pll_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
index 3e2aba9c40bb..3631f49a5e5a 100644
--- a/drivers/clk/mediatek/clk-mt8195-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
@@ -1239,25 +1239,52 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
 		goto free_top_data;
 	}
 
-	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
-				    top_clk_data);
-	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
-	mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
-			       &mt8195_clk_lock, top_clk_data);
-	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
-				    &mt8195_clk_lock, top_clk_data);
-	mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
-				    &mt8195_clk_lock, top_clk_data);
-	r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+	r = mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
+					top_clk_data);
 	if (r)
 		goto free_top_data;
 
+	r = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+	if (r)
+		goto unregister_fixed_clks;
+
+	r = mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
+				   &mt8195_clk_lock, top_clk_data);
+	if (r)
+		goto unregister_factors;
+
+	r = mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
+					&mt8195_clk_lock, top_clk_data);
+	if (r)
+		goto unregister_muxes;
+
+	r = mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
+					&mt8195_clk_lock, top_clk_data);
+	if (r)
+		goto unregister_composite_muxes;
+
+	r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+	if (r)
+		goto unregister_composite_divs;
+
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
 	if (r)
-		goto free_top_data;
+		goto unregister_gates;
 
 	return r;
 
+unregister_gates:
+	mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+unregister_composite_divs:
+	mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
+unregister_composite_muxes:
+	mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
+unregister_muxes:
+	mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
+unregister_factors:
+	mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+unregister_fixed_clks:
+	mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
 free_top_data:
 	mtk_free_clk_data(top_clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
index f7ff7618c714..af34eb564b1d 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
@@ -105,10 +105,12 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_vdo0_data;
+		goto unregister_gates;
 
 	return r;
 
+unregister_gates:
+	mtk_clk_unregister_gates(vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
 free_vdo0_data:
 	mtk_free_clk_data(clk_data);
 	return r;
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
index 03df8eae8838..6b502bbc730c 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
@@ -122,10 +122,12 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
 
 	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
 	if (r)
-		goto free_vdo1_data;
+		goto unregister_gates;
 
 	return r;
 
+unregister_gates:
+	mtk_clk_unregister_gates(vdo1_clks, ARRAY_SIZE(vdo1_clks), clk_data);
 free_vdo1_data:
 	mtk_free_clk_data(clk_data);
 	return r;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:30 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:30 +0800
Subject: [PATCH 30/31] clk: mediatek: mt8195: Implement remove functions
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-31-wenst@chromium.org>

Until now the mediatek clk driver library did not have any way to
unregister clks, and so none of the drivers implemented remove
functions.

Now that the library does have APIs to unregister clks, use them
to implement remove functions for the mt8195 clk drivers.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 16 ++++++++++++++++
 drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 13 +++++++++++++
 drivers/clk/mediatek/clk-mt8195-topckgen.c   | 20 ++++++++++++++++++++
 drivers/clk/mediatek/clk-mt8195-vdo0.c       | 16 ++++++++++++++++
 drivers/clk/mediatek/clk-mt8195-vdo1.c       | 16 ++++++++++++++++
 5 files changed, 81 insertions(+)

diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
index af8d80f25f30..29cac3cf5f53 100644
--- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
+++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
@@ -132,6 +132,8 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
 	if (r)
 		goto unregister_gates;
 
+	platform_set_drvdata(pdev, clk_data);
+
 	return r;
 
 unregister_gates:
@@ -143,8 +145,22 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
 	return r;
 }
 
+static int clk_mt8195_apmixed_remove(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_gates(apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
+	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+	mtk_free_clk_data(clk_data);
+
+	return 0;
+}
+
 static struct platform_driver clk_mt8195_apmixed_drv = {
 	.probe = clk_mt8195_apmixed_probe,
+	.remove = clk_mt8195_apmixed_remove,
 	.driver = {
 		.name = "clk-mt8195-apmixed",
 		.of_match_table = of_match_clk_mt8195_apmixed,
diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
index 1fff6f3d2dc7..8cd88dfc3283 100644
--- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
+++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
@@ -85,6 +85,18 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
 	return r;
 }
 
+static int clk_mt8195_apusys_pll_remove(struct platform_device *pdev)
+{
+	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
+	mtk_free_clk_data(clk_data);
+
+	return 0;
+}
+
 static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
 	{ .compatible = "mediatek,mt8195-apusys_pll", },
 	{}
@@ -92,6 +104,7 @@ static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
 
 static struct platform_driver clk_mt8195_apusys_pll_drv = {
 	.probe = clk_mt8195_apusys_pll_probe,
+	.remove = clk_mt8195_apusys_pll_remove,
 	.driver = {
 		.name = "clk-mt8195-apusys_pll",
 		.of_match_table = of_match_clk_mt8195_apusys_pll,
diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
index 3631f49a5e5a..b602fcd7f1d1 100644
--- a/drivers/clk/mediatek/clk-mt8195-topckgen.c
+++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
@@ -1271,6 +1271,8 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
 	if (r)
 		goto unregister_gates;
 
+	platform_set_drvdata(pdev, top_clk_data);
+
 	return r;
 
 unregister_gates:
@@ -1290,8 +1292,26 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
 	return r;
 }
 
+static int clk_mt8195_topck_remove(struct platform_device *pdev)
+{
+	struct clk_onecell_data *top_clk_data = platform_get_drvdata(pdev);
+	struct device_node *node = pdev->dev.of_node;
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
+	mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
+	mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
+	mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
+	mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
+	mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
+	mtk_free_clk_data(top_clk_data);
+
+	return 0;
+}
+
 static struct platform_driver clk_mt8195_topck_drv = {
 	.probe = clk_mt8195_topck_probe,
+	.remove = clk_mt8195_topck_remove,
 	.driver = {
 		.name = "clk-mt8195-topck",
 		.of_match_table = of_match_clk_mt8195_topck,
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
index af34eb564b1d..3bc7ed19d550 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
@@ -107,6 +107,8 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
 	if (r)
 		goto unregister_gates;
 
+	platform_set_drvdata(pdev, clk_data);
+
 	return r;
 
 unregister_gates:
@@ -116,8 +118,22 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
 	return r;
 }
 
+static int clk_mt8195_vdo0_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_gates(vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
+	mtk_free_clk_data(clk_data);
+
+	return 0;
+}
+
 static struct platform_driver clk_mt8195_vdo0_drv = {
 	.probe = clk_mt8195_vdo0_probe,
+	.remove = clk_mt8195_vdo0_remove,
 	.driver = {
 		.name = "clk-mt8195-vdo0",
 	},
diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
index 6b502bbc730c..90c738a85ff1 100644
--- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
+++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
@@ -124,6 +124,8 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
 	if (r)
 		goto unregister_gates;
 
+	platform_set_drvdata(pdev, clk_data);
+
 	return r;
 
 unregister_gates:
@@ -133,8 +135,22 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
 	return r;
 }
 
+static int clk_mt8195_vdo1_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->parent->of_node;
+	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
+
+	of_clk_del_provider(node);
+	mtk_clk_unregister_gates(vdo1_clks, ARRAY_SIZE(vdo1_clks), clk_data);
+	mtk_free_clk_data(clk_data);
+
+	return 0;
+}
+
 static struct platform_driver clk_mt8195_vdo1_drv = {
 	.probe = clk_mt8195_vdo1_probe,
+	.remove = clk_mt8195_vdo1_remove,
 	.driver = {
 		.name = "clk-mt8195-vdo1",
 	},
-- 
2.35.0.rc0.227.g00780c9af4-goog



From wenst at chromium.org  Sat Jan 22 01:17:31 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Sat, 22 Jan 2022 17:17:31 +0800
Subject: [PATCH 31/31] clk: mediatek: Warn if clk IDs are duplicated
In-Reply-To: <20220122091731.283592-1-wenst@chromium.org>
References: <20220122091731.283592-1-wenst@chromium.org>
Message-ID: <20220122091731.283592-32-wenst@chromium.org>

The Mediatek clk driver library handles duplicate clock IDs in two
different ways: either ignoring the duplicate entry, or overwriting
the old clk. Either way may cause unexpected behavior, and the latter
also causes an orphan clk that cannot be cleaned up.

Align the behavior so that later duplicate entries are ignored, and
a warning printed. The warning will also aid in making the issue
noticeable.

Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
---
 drivers/clk/mediatek/clk-cpumux.c |  6 ++++++
 drivers/clk/mediatek/clk-gate.c   |  5 ++++-
 drivers/clk/mediatek/clk-mtk.c    | 18 ++++++++++++++----
 drivers/clk/mediatek/clk-mux.c    |  5 ++++-
 drivers/clk/mediatek/clk-pll.c    |  6 ++++++
 5 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
index 499c60432280..c11b3fae622e 100644
--- a/drivers/clk/mediatek/clk-cpumux.c
+++ b/drivers/clk/mediatek/clk-cpumux.c
@@ -120,6 +120,12 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
 	for (i = 0; i < num; i++) {
 		const struct mtk_composite *mux = &clks[i];
 
+		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
+				node, mux->id);
+			continue;
+		}
+
 		clk = mtk_clk_register_cpumux(mux, regmap);
 		if (IS_ERR(clk)) {
 			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
index 631ff170b7b9..da52023f8455 100644
--- a/drivers/clk/mediatek/clk-gate.c
+++ b/drivers/clk/mediatek/clk-gate.c
@@ -224,8 +224,11 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
 	for (i = 0; i < num; i++) {
 		const struct mtk_gate *gate = &clks[i];
 
-		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id])) {
+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
+				node, gate->id);
 			continue;
+		}
 
 		clk = mtk_clk_register_gate(gate->name, gate->parent_name,
 					    regmap,
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
index 6d0b8842971b..b2a3568922b2 100644
--- a/drivers/clk/mediatek/clk-mtk.c
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -65,8 +65,10 @@ int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
 	for (i = 0; i < num; i++) {
 		const struct mtk_fixed_clk *rc = &clks[i];
 
-		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id])) {
+			pr_warn("Trying to register duplicate clock ID: %d\n", rc->id);
 			continue;
+		}
 
 		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
 					      rc->rate);
@@ -128,8 +130,10 @@ int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
 	for (i = 0; i < num; i++) {
 		const struct mtk_fixed_factor *ff = &clks[i];
 
-		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id])) {
+			pr_warn("Trying to register duplicate clock ID: %d\n", ff->id);
 			continue;
+		}
 
 		clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
 				CLK_SET_RATE_PARENT, ff->mult, ff->div);
@@ -300,8 +304,11 @@ int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
 	for (i = 0; i < num; i++) {
 		const struct mtk_composite *mc = &mcs[i];
 
-		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[mc->id])) {
+			pr_warn("Trying to register duplicate clock ID: %d\n",
+				mc->id);
 			continue;
+		}
 
 		clk = mtk_clk_register_composite(mc, base, lock);
 
@@ -363,8 +370,11 @@ int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
 	for (i = 0; i <  num; i++) {
 		const struct mtk_clk_divider *mcd = &mcds[i];
 
-		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id])) {
+			pr_warn("Trying to register duplicate clock ID: %d\n",
+				mcd->id);
 			continue;
+		}
 
 		clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
 			mcd->flags, base +  mcd->div_reg, mcd->div_shift,
diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
index f51e67650f03..21ad5a4afd65 100644
--- a/drivers/clk/mediatek/clk-mux.c
+++ b/drivers/clk/mediatek/clk-mux.c
@@ -208,8 +208,11 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
 	for (i = 0; i < num; i++) {
 		const struct mtk_mux *mux = &muxes[i];
 
-		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id]))
+		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
+				node, mux->id);
 			continue;
+		}
 
 		clk = mtk_clk_register_mux(mux, regmap, lock);
 
diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
index 1dd15f560659..e5e9c188be99 100644
--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -386,6 +386,12 @@ int mtk_clk_register_plls(struct device_node *node,
 	for (i = 0; i < num_plls; i++) {
 		const struct mtk_pll_data *pll = &plls[i];
 
+		if (!IS_ERR_OR_NULL(clk_data->clks[pll->id])) {
+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
+				node, pll->id);
+			continue;
+		}
+
 		clk = mtk_clk_register_pll(pll, base);
 
 		if (IS_ERR(clk)) {
-- 
2.35.0.rc0.227.g00780c9af4-goog



From andi at etezian.org  Sat Jan 22 02:28:10 2022
From: andi at etezian.org (Andi Shyti)
Date: Sat, 22 Jan 2022 12:28:10 +0200
Subject: [PATCH v2 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <aa172f14-2328-fc7c-0063-5c0033970d1d@canonical.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193613epcas5p238851849d212e01d7d830d78ca7d6379@epcas5p2.samsung.com>
 <20220120192438.25555-2-alim.akhtar@samsung.com>
 <aa172f14-2328-fc7c-0063-5c0033970d1d@canonical.com>
Message-ID: <YevcOlARxNcBeDJE@jack.zhora.eu>

Hi Krzysztof and Alim,

On Fri, Jan 21, 2022 at 07:33:15PM +0100, Krzysztof Kozlowski wrote:
> On 20/01/2022 20:24, Alim Akhtar wrote:
> > Adds spi controller dt-binding compatible information for
> > Tesla Full Self-Driving (FSD) SoC.
> > 
> > Cc: linux-fsd at tesla.com
> > Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> > ---
> >  Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
> >  1 file changed, 1 insertion(+)
> 
> I think you forgot to mention - in cover letter - that this depends on
> my Samsung SPI bindings conversion to dtschema.

It's written in the cover letter:

"Note: This series is depended on [1] patches which adds
support of FSD SoC and on Krzysztof's v5 [2] of spi schema
changes"

Alim, you can also add:

Reviewed-by: Andi Shyti <andi at etezian.org>

Thank you,
Andi


From andi at etezian.org  Sat Jan 22 02:32:30 2022
From: andi at etezian.org (Andi Shyti)
Date: Sat, 22 Jan 2022 12:32:30 +0200
Subject: [PATCH v2 2/3] spi: s3c64xx: Add spi port configuration for
 Tesla FSD SoC
In-Reply-To: <20220120192438.25555-3-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193618epcas5p45be1db500363072e647bf179623f8e7a@epcas5p4.samsung.com>
 <20220120192438.25555-3-alim.akhtar@samsung.com>
Message-ID: <YevdPslZ//gylbGX@jack.zhora.eu>

Hi Alim,

> Adds compatible and port configuration for spi controller
> for Tesla Full Self-Driving SoC.

please next time be a bit clearer in the cover letter. I think
you want to say:

  "This patch adds the compatible..."

But it's anyway recommended to use the imperative form:

  "Add the compatible blah blah blah...."

> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Other than that, looks good to me:

Reviewed-by: Andi Shyti <andi at etezian.org>

Thanks,
Andi


From krzysztof.kozlowski at canonical.com  Sat Jan 22 02:33:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 22 Jan 2022 11:33:01 +0100
Subject: [PATCH v2 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <YevcOlARxNcBeDJE@jack.zhora.eu>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193613epcas5p238851849d212e01d7d830d78ca7d6379@epcas5p2.samsung.com>
 <20220120192438.25555-2-alim.akhtar@samsung.com>
 <aa172f14-2328-fc7c-0063-5c0033970d1d@canonical.com>
 <YevcOlARxNcBeDJE@jack.zhora.eu>
Message-ID: <CA+Eumj7ab9E_4sbVPSQjOc-ZwM9LVdrgE=rj3duYKBYHjtDhyA@mail.gmail.com>

On Sat, 22 Jan 2022 at 11:28, Andi Shyti <andi at etezian.org> wrote:
>
> Hi Krzysztof and Alim,
>
> On Fri, Jan 21, 2022 at 07:33:15PM +0100, Krzysztof Kozlowski wrote:
> > On 20/01/2022 20:24, Alim Akhtar wrote:
> > > Adds spi controller dt-binding compatible information for
> > > Tesla Full Self-Driving (FSD) SoC.
> > >
> > > Cc: linux-fsd at tesla.com
> > > Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> > > Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> > > ---
> > >  Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
> > >  1 file changed, 1 insertion(+)
> >
> > I think you forgot to mention - in cover letter - that this depends on
> > my Samsung SPI bindings conversion to dtschema.
>
> It's written in the cover letter:
>
> "Note: This series is depended on [1] patches which adds
> support of FSD SoC and on Krzysztof's v5 [2] of spi schema
> changes"

Indeed, it is. I simply could not find the cover letter so I assumed
none was sent, but it just got hidden.


From maz at kernel.org  Sat Jan 22 02:39:12 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 22 Jan 2022 10:39:12 +0000
Subject: [PATCH] KVM: arm64: vgic-v3: Restrict SEIS workaround to known broken
 systems
Message-ID: <20220122103912.795026-1-maz@kernel.org>

Contrary to what df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3
locally generated SErrors") was asserting, there is at least one other
system out there (Cavium ThunderX2) implementing SEIS, and not in
an obviously broken way.

So instead of imposing the M1 workaround on an innocent bystander,
let's limit it to the two known broken Apple implementations.

Fixes: df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3 locally generated SErrors")
Reported-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vgic-v3-sr.c |  3 +++
 arch/arm64/kvm/vgic/vgic-v3.c   | 17 +++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 20db2f281cf2..4fb419f7b8b6 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
 	val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
 	/* IDbits */
 	val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
+	/* SEIS */
+	if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
+		val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
 	/* A3V */
 	val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
 	/* EOImode */
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 78cf674c1230..d34a795f730c 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf)
 }
 early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable);
 
+static struct midr_range broken_seis[] = {
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
+	MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
+	{},
+};
+
+static bool vgic_v3_broken_seis(void)
+{
+	return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
+		is_midr_in_range_list(read_cpuid_id(), broken_seis));
+}
+
 /**
  * vgic_v3_probe - probe for a VGICv3 compatible interrupt controller
  * @info:	pointer to the GIC description
@@ -676,9 +688,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
 		group1_trap = true;
 	}
 
-	if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) {
-		kvm_info("GICv3 with locally generated SEI\n");
+	if (vgic_v3_broken_seis()) {
+		kvm_info("GICv3 with broken locally generated SEI\n");
 
+		kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK;
 		group0_trap = true;
 		group1_trap = true;
 		if (ich_vtr_el2 & ICH_VTR_TDS_MASK)
-- 
2.34.1



From andi at etezian.org  Sat Jan 22 02:42:33 2022
From: andi at etezian.org (Andi Shyti)
Date: Sat, 22 Jan 2022 12:42:33 +0200
Subject: [PATCH v2 3/3] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220120192438.25555-4-alim.akhtar@samsung.com>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193622epcas5p3a65c8424c6a01aed9a87f5ac2a89eb06@epcas5p3.samsung.com>
 <20220120192438.25555-4-alim.akhtar@samsung.com>
Message-ID: <YevfmeGwmwLml+6b@jack.zhora.eu>

Hi Alim and Aswani,

On Fri, Jan 21, 2022 at 12:54:38AM +0530, Alim Akhtar wrote:
> From: Aswani Reddy <aswani.reddy at samsung.com>
> 
> Adds device tree node for SPI IPs
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Reviewed-by: Andi Shyti <andi at etezian.org>

Please, also allow me another nit-commnent for the next patches:
the tag section is in chronological order. I suppose that first
Aswani wrote the patch, then you sent it to the mailing list and
at the end Krzysztof has reviewed it, this means that the right
order is:

  Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
  Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
  Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

Thank you,
Andi


From ardb at kernel.org  Sat Jan 22 03:14:08 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 22 Jan 2022 12:14:08 +0100
Subject: [PATCH] KVM: arm64: vgic-v3: Restrict SEIS workaround to known
 broken systems
In-Reply-To: <20220122103912.795026-1-maz@kernel.org>
References: <20220122103912.795026-1-maz@kernel.org>
Message-ID: <CAMj1kXEmNpTGtZU=ZkOTpYpG7bdaubUx3-Zzpf-D1unjk43AYQ@mail.gmail.com>

On Sat, 22 Jan 2022 at 11:39, Marc Zyngier <maz at kernel.org> wrote:
>
> Contrary to what df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3
> locally generated SErrors") was asserting, there is at least one other
> system out there (Cavium ThunderX2) implementing SEIS, and not in
> an obviously broken way.
>
> So instead of imposing the M1 workaround on an innocent bystander,
> let's limit it to the two known broken Apple implementations.
>
> Fixes: df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3 locally generated SErrors")
> Reported-by: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Marc Zyngier <maz at kernel.org>

Thanks for the fix.

Tested-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Ard Biesheuvel <ardb at kernel.org>

One nit below.

> ---
>  arch/arm64/kvm/hyp/vgic-v3-sr.c |  3 +++
>  arch/arm64/kvm/vgic/vgic-v3.c   | 17 +++++++++++++++--
>  2 files changed, 18 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> index 20db2f281cf2..4fb419f7b8b6 100644
> --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
> @@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
>         val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
>         /* IDbits */
>         val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
> +       /* SEIS */
> +       if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
> +               val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
>         /* A3V */
>         val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
>         /* EOImode */
> diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
> index 78cf674c1230..d34a795f730c 100644
> --- a/arch/arm64/kvm/vgic/vgic-v3.c
> +++ b/arch/arm64/kvm/vgic/vgic-v3.c
> @@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf)
>  }
>  early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable);
>
> +static struct midr_range broken_seis[] = {

Can this be const?

> +       MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
> +       MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
> +       {},
> +};
> +
> +static bool vgic_v3_broken_seis(void)
> +{
> +       return ((kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) &&
> +               is_midr_in_range_list(read_cpuid_id(), broken_seis));
> +}
> +
>  /**
>   * vgic_v3_probe - probe for a VGICv3 compatible interrupt controller
>   * @info:      pointer to the GIC description
> @@ -676,9 +688,10 @@ int vgic_v3_probe(const struct gic_kvm_info *info)
>                 group1_trap = true;
>         }
>
> -       if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK) {
> -               kvm_info("GICv3 with locally generated SEI\n");
> +       if (vgic_v3_broken_seis()) {
> +               kvm_info("GICv3 with broken locally generated SEI\n");
>
> +               kvm_vgic_global_state.ich_vtr_el2 &= ~ICH_VTR_SEIS_MASK;
>                 group0_trap = true;
>                 group1_trap = true;
>                 if (ich_vtr_el2 & ICH_VTR_TDS_MASK)
> --
> 2.34.1
>


From maz at kernel.org  Sat Jan 22 03:32:45 2022
From: maz at kernel.org (Marc Zyngier)
Date: Sat, 22 Jan 2022 11:32:45 +0000
Subject: [PATCH] KVM: arm64: vgic-v3: Restrict SEIS workaround to known
 broken systems
In-Reply-To: <CAMj1kXEmNpTGtZU=ZkOTpYpG7bdaubUx3-Zzpf-D1unjk43AYQ@mail.gmail.com>
References: <20220122103912.795026-1-maz@kernel.org>
 <CAMj1kXEmNpTGtZU=ZkOTpYpG7bdaubUx3-Zzpf-D1unjk43AYQ@mail.gmail.com>
Message-ID: <8d8b93e7251b0373d897a2f9222b0520@kernel.org>

On 2022-01-22 11:14, Ard Biesheuvel wrote:
> On Sat, 22 Jan 2022 at 11:39, Marc Zyngier <maz at kernel.org> wrote:
>> 
>> Contrary to what df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3
>> locally generated SErrors") was asserting, there is at least one other
>> system out there (Cavium ThunderX2) implementing SEIS, and not in
>> an obviously broken way.
>> 
>> So instead of imposing the M1 workaround on an innocent bystander,
>> let's limit it to the two known broken Apple implementations.
>> 
>> Fixes: df652bcf1136 ("KVM: arm64: vgic-v3: Work around GICv3 locally 
>> generated SErrors")
>> Reported-by: Ard Biesheuvel <ardb at kernel.org>
>> Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> Thanks for the fix.
> 
> Tested-by: Ard Biesheuvel <ardb at kernel.org>
> Acked-by: Ard Biesheuvel <ardb at kernel.org>

Thanks for that.

> 
> One nit below.
> 
>> ---
>>  arch/arm64/kvm/hyp/vgic-v3-sr.c |  3 +++
>>  arch/arm64/kvm/vgic/vgic-v3.c   | 17 +++++++++++++++--
>>  2 files changed, 18 insertions(+), 2 deletions(-)
>> 
>> diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c 
>> b/arch/arm64/kvm/hyp/vgic-v3-sr.c
>> index 20db2f281cf2..4fb419f7b8b6 100644
>> --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
>> +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
>> @@ -983,6 +983,9 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu 
>> *vcpu, u32 vmcr, int rt)
>>         val = ((vtr >> 29) & 7) << ICC_CTLR_EL1_PRI_BITS_SHIFT;
>>         /* IDbits */
>>         val |= ((vtr >> 23) & 7) << ICC_CTLR_EL1_ID_BITS_SHIFT;
>> +       /* SEIS */
>> +       if (kvm_vgic_global_state.ich_vtr_el2 & ICH_VTR_SEIS_MASK)
>> +               val |= BIT(ICC_CTLR_EL1_SEIS_SHIFT);
>>         /* A3V */
>>         val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
>>         /* EOImode */
>> diff --git a/arch/arm64/kvm/vgic/vgic-v3.c 
>> b/arch/arm64/kvm/vgic/vgic-v3.c
>> index 78cf674c1230..d34a795f730c 100644
>> --- a/arch/arm64/kvm/vgic/vgic-v3.c
>> +++ b/arch/arm64/kvm/vgic/vgic-v3.c
>> @@ -609,6 +609,18 @@ static int __init early_gicv4_enable(char *buf)
>>  }
>>  early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable);
>> 
>> +static struct midr_range broken_seis[] = {
> 
> Can this be const?

Absolutely. I'll fold that in.

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...


From mkl at pengutronix.de  Sat Jan 22 04:05:58 2022
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sat, 22 Jan 2022 13:05:58 +0100
Subject: [PATCH] arm64: vdso: fix "no previous prototype" warning
In-Reply-To: <0030cecf-e79b-f666-8516-d0589bc49b81@arm.com>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
 <0030cecf-e79b-f666-8516-d0589bc49b81@arm.com>
Message-ID: <20220122120558.7eoiytboe7b43b5q@pengutronix.de>

On 21.01.2022 12:12:26, Vincenzo Frascino wrote:
> Hi Marc,
> 
> On 1/9/22 11:35 AM, Marc Kleine-Budde wrote:
> > If compiling the arm64 kernel with W=1 the following warning is produced:
> > 
> > | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
> > |     9 | int __kernel_clock_gettime(clockid_t clock,
> > |       |     ^~~~~~~~~~~~~~~~~~~~~~
> > | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
> > |    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> > |       |     ^~~~~~~~~~~~~~~~~~~~~
> > | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
> > |    21 | int __kernel_clock_getres(clockid_t clock_id,
> > |       |     ^~~~~~~~~~~~~~~~~~~~~
> > 
> > This patch adds the missing prototype to fix the warning and make
> > compilation with "CONFIG_WERROR=y" possible.
> > 
> 
> Instead of adding the prototypes, how about we silence the warning for the
> specific file? Since adding them does not seem to add any value in this context.
> 
> If you agree, could please test the patch I sent in reply to this one and let me
> know if it works for your usecase? Thanks.

The patch silences the W=1 warning, sparse (C=1) however still
complains:

| arch/arm64/kernel/vdso/vgettimeofday.c:9:5: warning: symbol '__kernel_clock_gettime' was not declared. Should it be static?
| arch/arm64/kernel/vdso/vgettimeofday.c:15:5: warning: symbol '__kernel_gettimeofday' was not declared. Should it be static?
| arch/arm64/kernel/vdso/vgettimeofday.c:21:5: warning: symbol '__kernel_clock_getres' was not declared. Should it be static?

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220122/6ef9cf64/attachment-0001.sig>

From mkl at pengutronix.de  Sat Jan 22 04:06:41 2022
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Sat, 22 Jan 2022 13:06:41 +0100
Subject: [PATCH] arm64: vdso: Fix "no previous prototype" warning
In-Reply-To: <20220121121234.47273-1-vincenzo.frascino@arm.com>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
 <20220121121234.47273-1-vincenzo.frascino@arm.com>
Message-ID: <20220122120641.h7p4xujjolkxe52o@pengutronix.de>

On 21.01.2022 12:12:34, Vincenzo Frascino wrote:
> If compiling the arm64 kernel with W=1 the following warning is produced:
> 
> | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
> |     9 | int __kernel_clock_gettime(clockid_t clock,
> |       |     ^~~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
> |    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
> |    21 | int __kernel_clock_getres(clockid_t clock_id,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> 
> This patch removes "-Wmissing-prototypes" and "-Wmissing-declarations" compilers
> flags from the compilation of vgettimeofday.c to make possible to build the
> kernel with CONFIG_WERROR enabled.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Suggested-by: Marc Kleine-Budde <mkl at pengutronix.de>
> Signed-off-by: Vincenzo Frascino <vincenzo.frascino at arm.com>

Tested-by: Marc Kleine-Budde <mkl at pengutronix.de>

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220122/638b928b/attachment.sig>

From irui.wang at mediatek.com  Sat Jan 22 04:13:06 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Sat, 22 Jan 2022 20:13:06 +0800
Subject: pull request: linux-firmware: mediatek: Update MT8173 VPU firmware to
 v1.17 
Message-ID: <20220122121307.20770-1-irui.wang@mediatek.com>

Hi linux-firmware maintainers,

The following changes since commit 0c6a7b3bf728b95c8b7b95328f94335e2bb2c967:

  linux-firmware: Update firmware file for Intel Bluetooth 9260 (2022-01-19 11:16:28 -0500)

are available in the Git repository at:

  https://github.com/irui-wang/linux_fw_vpu_v1.1.7.git v1.1.7

for you to fetch changes up to 80d16ecb66f28c82987bab2a361df4dfe2c8b25f:

  linux-firmware: mediatek: Update MT8173 VPU firmware to v1.17 (2022-01-22 19:48:53 +0800)

----------------------------------------------------------------
Irui Wang (1):
      linux-firmware: mediatek: Update MT8173 VPU firmware to v1.17

 mediatek/mt8173/vpu_d.bin | Bin 2977184 -> 2977184 bytes
 mediatek/mt8173/vpu_p.bin | Bin 131180 -> 131180 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)





From irui.wang at mediatek.com  Sat Jan 22 04:13:07 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Sat, 22 Jan 2022 20:13:07 +0800
Subject: [PATCH] linux-firmware: mediatek: Update MT8173 VPU firmware to v1.17
In-Reply-To: <20220122121307.20770-1-irui.wang@mediatek.com>
References: <20220122121307.20770-1-irui.wang@mediatek.com>
Message-ID: <20220122121307.20770-2-irui.wang@mediatek.com>

[encoder vp8]
set buffer pitch info by input format

Release Version: 1.1.7

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 mediatek/mt8173/vpu_d.bin | Bin 2977184 -> 2977184 bytes
 mediatek/mt8173/vpu_p.bin | Bin 131180 -> 131180 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/mediatek/mt8173/vpu_d.bin b/mediatek/mt8173/vpu_d.bin
index 45e214dd4aac4c54b8dc2778c7de3de69c6f41a6..e966b49bee57e8cfaa3536174830916cf35b184f 100644
GIT binary patch
delta 370
zcmXZWy-LGS7>DtHVv|OjRIOEO{j9C^tB44qlVB)LA}%^Ob#`)a$nM~3^aeWQ0s_Gb
zMG)*22yP+>-arON2cLikemv)Whr{W9JQ`iZj%B5>^!(si_3CjbRgj$v&ij?A^1bvG
zCZX52lbn0HYwRUwhcD(<{3<mDQVToSN1xpR_5bfj^aSUF#BcX%e&<uNc>9jpbo*P%
z(++jAJuT4oo8;1K>Sc2(6|*_zAD5+ at D7cLR115%$g9RITI2gtV3UJ|}h*6AT93 at Pk
pj7dyk8Wqf-idoEI9t&8+5^7jR9Sy9YiB+s&9UItuih|bf&mT1*fl&Ye

delta 370
zcmXZWJ4?e*7>DtHVow at vQnlV{jh9;QiksqU at dI=b#8I4_9J4z(r!I~i@&O7#1s9>S
zgF**U1W|DiQ3r7n at d^0CkLSE+IGo1aiPb>UHRiY}?H>82QmRE#fONK*_P(uRU3!j^
z$Uk?Ij8|K+R+G*33wwF1C0(M8TRdO~FL?bwzteC0wvy_`X}Rj&ONO`Cs6%far7U%y
zklxcAeY=u88eB_$x_?OdbpPZZdxe8IJd8sNHad`jfrBhubfOD6c<_-&H+s;E0{YO8
o0SsaYMGT{a5d;{;7{)PyGA2>M6s9qQS<GP`3s^jh!=<0EKXfvMYybcN

diff --git a/mediatek/mt8173/vpu_p.bin b/mediatek/mt8173/vpu_p.bin
index 96f1c632972cb068d0c1aacbc78b5cc0da07bf4a..55a49ec244539011213928bb66909a3564af703e 100644
GIT binary patch
delta 5437
zcmZWN4OmoV*7ppT%T>8M-UbHIVP;4O|Am!G%XAP-)KRc>bCZ;DTtdUAAxWqxE<eJk
zBtNe?Xl#t;G^3J{cVwvi5Rz8DmK2gU>%$VAh)v>WAu|`_J9lQZ_SuJL?mh2$&;L2^
zIq#)UVEY8NE+>-xg#*gO at N0<>ITvn`y2yv2LF|om1;Z?2eY6Ijx`hws<qE+8f*{X2
zdV~vMx3d1VM84&{RQ=Q4m7ISyC4c50QCzpPNDoCT<=bM9=qC&L99$TX|LFQyA69XS
zlT-h6ZgX}IFxfZc$GPoJO1`<R+vVq;SK7m^kh`6molHTRP{8%cue-i;vVS-4cXE_6
z&6)1}l#=x26;#Dlb;oYe8~rFoA)}bI95v0G)HKBy%*7Q(Xup3#0)5b6?sgr~UyE(l
z8yTeYM>?c2nDZ-)NZI33nvJ_ at Mo~@Q<EOp+W|~o&4Q9ogy-ve>#@CUi^gn3wBqe)&
zM0=3QNi)WBHLWPiuShdVLQwQRx3kA(+>gxUKbR%nN*`~9kGBeWEowR~$6)47#skuB
zafRXyX&22ngzI#qI7l<yE(02u_noBBil~}<OmF#^{_15izKx2HpyIn8AErGX)66xA
z*N(jJ+~c+Rc#rycPayB{|1$cRM1|%!Xoc6~chSaLR&Ovbwi;?h^CE=|Zi&^pWip_N
zd&yqNAg1`~kVOu~Pla027=H=zl?fJvXDkhePEo&fF~AnF^zrxnvB(zc%K)lL+p4+H
zKt at -E!9+57bs4D0 at zs%7iS4U{A)558UIr|glhh3DWH4zqI7M~xJQ`Za6KhxD(~8d=
z(!bUS$>J01rUM9K?w{;__=<R%2N)y|ZP*G{V%;zk9Hec-6u3-!H_Q#w37SPFN)FTu
zSp9;A#}WqW6)!wOVpAexs&;dN=E>S51}Jc-(<3GdVL(xGe)M$@l?PUp{sz0ro|L(;
zpM01S#&t^4ynFl^;!b%963E79Li6rPqvV-qeES&^?LMz&tpt1J^F@;86RbKFb>_a#
zF;xDEv=nuE9>bu$9_ at i%N_Bb?Bgyme#Y!?Vz48Vn85E_?0S7aV?;$szc at e5e#>VYy
zs$b(C8cD`oL8Hz{Vq)4>OO$fn{F;YTotnf1<sN4>AyW_RI<%p~vtBE$&*A#Xj at 4O7
zj3&fr*>z}Dhlj6~%-A#=)4zVxqv-4YO$#t*7dAyrZ_4Eq5waB?Jt&hus$&_{lQxpe
z`8nug_k6ib)Twi09JyZYIcSkd=e0<c=fQcjG`z+wLT at E$o^>pFEj9Ehw}jC#>KsZQ
zljWu6sk=BG6PJZ}lh-f4MT$-dN>o(w33shh1nO9iyku#|Cp&@kr$&Xf?EMW>RKhLF
z{hjtY@<+q2`05FIKy5>ZlNj~dq7xfYo8O67JzU-#N_fBH629oT&k9zO;&)uV)}wWh
z+%|+^rB2!$o$O28XyJ08H0roTlziizyEp|ZQdY$*(kOpA3?%7}hgtOkmg&^0JQRqE
zOhTAc)<)%B9#XY=CM1e2n=9yXrQ10UV}C^;8=swmr|IQqOTbBF=~wWST}@vKP2_>C
z7oeZ~w6!vi9kxH<5HvmZy=X{r1EA3ODxc66$zwz9&ynBSzPDwjhHDpV2UeojmC{-I
z*3L%{+w+k^(D)tXiz#`x-FL>KDNmGxVLQ?d+xSvJ<F-lpFnOaT2&n5D%eOX)BFu9g
z*g7shHx+AY^tma)85$*4wY_N!=_ at mkK0JX>B(pLeM(4KR8ZyKew*L&=T7(m>28}~M
z530z{=Q|*oB$}R?&c49iw0F1yJXRS#@PsbfYu8O18{gsdJLtuc3#Lo)xFcu^tA=bq
z6$THL4B55)p51CM$AC>(zS!Dtk!+DLW9YNwFC`BlK3`eUomm6WDi-Ysqd_Ge$zJD&
zVZQZp2^u84vK71453d{>AL`*7DmiS^_7?_I^22s17WFp%7O5?s0?}e?@i+((_Hn0e
zyI0-~m((nFuSEBIOY%V=+sxq at gi`ZY{&1C~?RyxXZ|(at^buWID0aU4%4S1^4}Q8V
z4Cedb%Ceb|P8!P=gjfqOTc59NwrkX%M- at 86F^{h_`9t{>jQ))Bd^EYXe3dM#oO~NG
zi6|;kI8VE*!KQ>qIg#X6e8f4VL^`~fB9c(K!^1R{{9ok^oCgfqoA+|_l=whFm5`Gk
zwAeaSQ|Qz&`ErU?(Gd<INV&y83McPM%n!~tsOU+E&))+zyir9<bny-y(;S+(n=P3b
zKGDA^l+RMr_rI#9>np;|IfY7dVXcm#Sc93VDUcWMeqfIl;ST4{X@$tAz`dd3Tg7?i
zEh?JFUw(HWtz*{Iw<-!RGlV<O$<09zR4J?I=gWfC^iYkCF`#H;tHGR>XYA53X*<<O
zuQcQQbmOpoac8uamH1I~duf=lO-0XVbyV7BgBhrtL}@RxzBEYD-g9t1tEQF2pEa1Y
ztTNBfkIK{+JK5;`qk{}pOPyBq>X>kL=!1}hJDVz^DQsb1I)5(S;mAfK8!9L&6AjJj
z4W#)oKehya+1t<o{Hf_ob0*#zG|DygKsJualJ*8^)I&7|Ve7{<%855vvSVydTR|`$
z8KR<%V+FzaTZU at x)9qJaC{^@Ou|_F{`>8Q9?Tx+ANt&!dr1gy-;S8xikPQ*y9Lqcz
z4&luQPlrYbnt=Ma1_pak2chKG at 4UgW)OfvFMWPR_!Llki6pxgDJM=xy_LFbE4p1&G
z{OcMS6p?*3AvoIKsfj|d7iu0v3~ikbS~ABv1>qIe#n|xnSRcgM-DIuG6GAUtrPOba
z6T-AI?|T$<%u#-*Sm6%EaOfBd!FaoYe*3a8W%3V{I(gjqlIxI+#Zd90n*ItiHf}I6
zA;j#eIQ$ni{Wj)}Vl&MFHSfypyT8PO$TS=3qo(b+rDNX4um^m~(V$h*f-3GzXjS-Z
z=F*6cnV^5Hv2c0znF;!*&jgT|GjR<{Jx69#vDEI03QR8lFr^I`OivJd59|HbCyx_U
z+Fvzl^{*PGju}rVR^guE2$8>p=EhGDf;DOj5yI$SRrJzOiscPZ6C&3rGxw<I+jj(2
zh*6_nF;1f#xuc^0b?4QvkS!WD*H2MBcSwTm803ikwjDBAj)RodgpijVG0;kC9Wyan
zmmT4<mUqZp>ttznr8S()KNcpdwvoNo>7sCK4an9GkxR!@AeBU)Sc!L at +!G6A(Idol
zVi9a1H%}~KN3eb1jVGGuYO@!VpR)z^NL|r$=1n)bbGA<GdcJk?F!sT7whp^AUz at R4
z$F#M0xgFwQ?PGY^B6Ch|WdDW7{#i$wmh3;d7%q#QCj$VlSzYga_lLT7J>;G~p+8A3
z)_ujEM$CYnSCP8+AH$K;|Nabi82QiI({x08YBsDVt51dF#m;m}gU|9)Ml6((Q{kb5
zXSp%<rcKZo+ois&=o|CS>^3q-tU#?z;&MQD$Df`Gxn$1iWiq;%WS`E#9yfS86z`Yg
z>!T3<WBns+Gg@%T#?vIL-lX{$7w2p|PGUi$y;>O5ZF}}D9w(K@<iNiXKiA_i?alYX
z(rK%(bz?w0+v`8!_-Gx2gYK9{$xvU~-uJdn9IdVrbVSy$jcxL}i^>}2;puQR6atKr
zSsy-%xlI4?mAulM=!_@$8UMp6qfI!+ at fucy@O&R!eTGw>@xfJyZ}Pzjh;Q-1vk-3e
z!KDbd`CtL*+kJ3sBd6^2!9_ at OS%R0KG8PwIzKtyiU-iKm2)li7Dhlc~G5wYSoX(4_
z(&Rgjp5f$c7mt3FEYnJ>vvz*gPj;~m2bH}5XE`PBi24BWIP1GeP-6ru5n<`!7iD7z
zbdmLqk+KMp<TYw>&R82mWr>aCqsHm1uf_sNU*lY?0oB>inW|4btiM{ueEMaTjflZQ
zY7sQUc4_!XYt+<7QqLxPa(p|9r^SY|Hz2ZFQhU=@uzZ5P!*)Eea~j at 6rj1YFwb;@k
zrE)-{bfmRegDtDK`7znrQzYu+ZMdlXcs4$pK7JBLNYJ?y{8kR2SV#6kl5;K`QHRc{
zJ)h4P?R*4jI`<}`Qd;8XE&PR}SfN(XC;}-tLrEXl80Lk4;rvk1Jlz0h+<SeHRZ4s4
zL?CHziAPOApNLQ`wtlh|7Dsn*?aoWicKoB{?auR at Kh^GB*GZ$O1YHM*v2}KEGU^NG
z{j*ranPVkfC*lIA&z)$Y>Adt+Wj(KfI?{BW1e*lSQQL<rB~yALhf(d54m<+sts0~<
zw?2wZxurE+7CkI}-?{>%^YYmvB;!*#;&VS;Aftzg>(f*`ujLn~iMqf4ua{yO?mqF^
zpTSLPKbwTd7^q4+#=Pyba{x_Z`Nih}j#hTeg`*_8BMR at D>pOl%_mV$f=?5vK`il*?
zxb;OhegleMfB7U0c$B;1FbbxwAWs6X+b}DoT~iR{=$ehE_a9x62#<DY&=A#?x%kvy
ziCX1!+lR43VTL0E at g{?z&i#f<>!Vn=?R~65>0UNu>%zED^6cs>+<1H+54_BI?ugVE
z7*|TZ&f0~sG%@#AiA`5#N(S|PBS#;|=(oG at S#b3tqMqnRR5jUrZ5}=kTwBe$y@|y-
zy*BN)h3fk67W(Tumj2GZaIbwi?*Fpy8V**>V*6FEorB+a?W?+m_L-P<)gtXS09eJe
z at 8Tr$96g)- at WuXML?p?$5s7oW^2W3HynUmL>%GN2gp<zGq&md|eJ{z-;)w%6>btcr
zoz4k*?4yqBkwFu^_j10PEE$+BUF~k#B)UI2F#5RzNf`IGfq9t7K~EwFJ&7FDEg3=@
zH)cqRu(!YmIHlItFXkgW%Lf;I$0=id at cMuL){q?J>%m9ZvnXa*IzOtRRL^3>hKr)1
zbs_1}7G{qf!pWm3@~-%Fad7A<DG!OmI`#vc9C$-xN%?U2l#~y-m>kJ#L8D_j5974T
z5j_(4{iJQUo&5<HQ{(wS@#x4x8T+$$l`Qt&Y at t~NenJRAsMz^$t!HsSvZCwXvt^Sw
zal+`R4C+L7tbt~KMK<(0*3#++%Vo)&ML|P-FksOIQ5>s}w#V7m*g;x1S-zoRm at k)e
zmuznDOqI~(mTUenRpJa_VAo`d3&7xI2W8upS}<J=O17u@*j?{1u$+b_%iws}4o$9&
z6JRy4p^~8*p0YRtA^P6R)fWg|GF&ncVozJ>YL`Q%ADZrpSHLxyOgGsQrGyn=b-kd3
zXRu-{?IBRaa$Z at JTq%<PkLp!RTPQ4rI at f)Z;YWb1dKElMLzZQs7BV5la#9OnFyd;{
z0+v&{>+z}J4_qlFH`o_pOxD=>BG>u|Sirz77vA~b at JE_y(I6xp5a0%C>=PgkRm{nU
z5H!rPEFVrmk>z$iJch6N1 at I*lxh59E5Fnpy7pwxPvm_ToX2>Ko6H_|IR!C)#HRf6I
zR?FpLcn)b2N+1U1?ks_2Jd&oZmHuzwt4OQmLJ4S4d4CDoFlzbQ48NfG&fU<AQ`mK2
tFRYRw+Wk6Q#Fuj)G<ouyHOR-ha?9XHKa{_XcqHs0ut^H&4FdTY{|~~;15^M2

delta 5601
zcmZ`d4Ompwwr358!%;bRIB#G;8)gOt!PLa0!ZICXO3YF8g+*lvVu*&_A$>wGlHo at f
ze-dz)gT at swjx#D2IU_^FRZP5c%?gyR)WZTr<E2+YdB(dR#asK#Xnya$_xZVJt+m(x
zT6^t%xMAUMSor#!2!2=q#>|N$#1b(Bs!4ss6VUAJk8lS;G^u{73RlCN$MQB?f)o~u
zQsme26KnSizI8;Yn6b+Aa_=s|w~|pV|68O`<SH@=MT?YUWA>ZAx8w`L*SC~go;Yc`
zRDM)YGFx3^T~}{$+1Hha1i{59GtO;s`}ED)aZPwmS>)nfeg&H>1%ls~H<T`+&|Tol
ze&5f<xxQo=^;+JyAup~Xm|txws9?C>7=}yp(XuLqmQBw|wTk96V7PI{;__5$`^5bw
zcF##uubbg6Q$7y)eDllG%?y`nRa?_omb>O=xwNfFue>jBWjVFAxLoxi%cXvjider3
zdEP^w9bTS1bJ}(<(>7#srCQU<SWZ>Sa_MF*n`+H3PuodVt5LX*3cruS<i3GjUfFW5
zYz4~NP&P-)iYSj%G at rJca-~{TA5boo--~z#;(M;T at _OBA)hJZ;PeS{=LVuz{X!s)(
z+)pE>N-^S^%dTtgG&{;3_$OJ(D_iT8J&dx4?mK;u?qXIPxEo9(K7vZ>sM_Lk-jv$F
zF!QRNMRQdOsCHHu7ASxxJ at dDNnPkRKfgG|seiGD^ruYj;-)XcVJo%Y0=yE1JGY=rc
zX?^w+Uu?8kQz>BAwJn|j&186SC<GGql2Xu<14|-;NBjsduzE}o)QTptWeo4fFv{#0
za(T%D at Fx!^o`g<vBXK%3Iwvfh#X=idlC&7tN?dcv&q-;J<Xp0R3P6!F=LNeD{^(y8
z0fxw<udIbyQu)f%(7Hqpm_$ySoXEw69Okttj8f$)#uH)DiQS~{l^LN%i*Bx&Q3CUp
zhgwbHcRcVgiCz&gvvR9o(LFC~0*5vuJirnP=%>i+l(}SBzvFkfpA at f{F|}fc at Mdxz
zTDRz^bxUaeVMZAq at SaC=7q#M%5nD*linsF;JeW2Ec{Si*lwtRH>uC(sGNa6D_R7c}
zd+dwhRF_w;mGXMx6m#DbI41vadWtq9kK at n}*;B7pYKQ9c%EkIqC0QQlhDhJ5g-}T{
zUR%Gcdb9BO&{9trnTg!Yb4w7$;CF16d9^8tTwv}YUKc!R_m;gcb;x)U#ZMu=tYgW>
zL{1l+X4|rNQHLydj!a%T9eXHg<x`MA%2v+CLZ4k3Ii)pMP=za=lhcJd#aaW;p`G;M
zT*1e|9=z{<H<^$!Bd;#kV?75wG8;S|>GNcoY^8a#Fc$-)+GIR74@;=3pcDhA&0&-?
z%^v^7{s(9qJsL#z9?ihTZG3>YjpnEXtxQx^hza*xRrwou*+>%I@)}GaKc_^7wr&5N
zVl5Ho=04z(i#(FLCA4~+iT3AU4fbeK(c#z7oX_ERWhv20+Eat4`%@X8L)s+S#?X9u
z?@jC|^*|oV&?*)l@=(Pg61XZ_<85T7a3L@{ZQNW&`P#4dXe4D-kWT*=W at AzXZB8_6
zwuI6Hkfy%R^Zu%-U~;ysDrd)(trr9=!=)nf@|uV6G;Uf`0*&OiHJ2cUbZ0yRtz_cb
zui*w6T)QjO|BijK!=k%p-;Rch8v&KZS9n{hja0AGp-juV;IJ4*&Q}nu$5`%2VwpwP
zC(+cJJ#iP2;dTFkL#6YLNi)qA(m|;~IwM(hTcj6iXbw8;Z+Q63IyJVey=4?-cV!|i
z%qW^jROS=td<x=VcD}j(7Z8#WHueOLLD at Ze^41?aAc+{wuTJrQOSo(AaQk7+eD<V%
zCg(TClZ3kxAK&5f+2f&+v*ruv`@XE;snwqSTasnryy}}aYMD|-?P3hAJ);aJ-Zc6<
zd$Otk&N(d`LRru|_hm2lK_x@~UV`Rx-&u>Z>)Ja9$0Dh$I5>2qQ#y??UXkE)V0xPe
zF&{N{s;RI-jB&OWkAdK#ox(9`>!N$fqKAL$A`G~%Bp- at Mx-|^LwpzdQg+8)s=M%W@
z-T4v>kU6E}aTflebUH*)SXWCkWzn6q7nsgRo?kSM>8`<9!^GpPsIjNd@$&C1oeG(x
zsdRR5Z2 at -Z`9&w~I_>$$LWgry&IwP(mOX^Wcyd`jhT|w(tjH-NKZb`8W%&xBnijJP
z72^3#B01%s3w4y@@KB}^!>$do&?Itk*TZ;|D9H9a%gKl0{Vf{f=KR2U)q_<kmw}6N
z<ix92YgiwhB``lIl^8hR#Tr)SV0bYVszQ_+Hh-Ie6VnV_p(|l)ydxm&<oK5He2JC~
z at Wp#~W0-Z~yJ~Agxq-_mOtlu)6(|{g@;0st at 3*a+qV&9h>p&}oj^SceU7m&=EY`5r
z)&8uwdRaq$Z()~#6V9}$tbrU+R|v||pve`3RqXoIceQL<n}JKu)3OG<DiP~eThlkG
z`p}hs)3SO#)w--<Q?#nxz@?otaIyT3(DYRr76%VQ_p%yt66hY%1J&f(o>Y7usC|6%
z_$-s2=c9d?0j}7^9LujYa7^9cXR7{9Enz&v1n;@%Dv#daFmM|7mtuy=Mn at aV{n at Nu
zA3mqwhZjdRYzh9)UYBJR*U>k}vW6_{tD`#g_CO$mRf at zHM|IkO>jj}3kX8`H6Ch*1
zQlY+7#KqMUG^}A~L6CtPtQss<xoFy#;|9Z|5~BHFJM=gm9{}LpduVqyL^&tgW+||r
zUf6SNe3V7!*AUmp;i%~#jPlB_9|$}%)?|$$;d_ at M&!)ZcxHj$m33crM at I8P^XY`+z
zDaM!W6Fzc?b~@MxrJ43Z$9%ioSq`$dDiRHSQS}&<k>RQ-q0=e_r<YT#h-=c at eQNGX
zVIJ->GPimjjF8RMkKvobRb7#1;5Kw+ZB_MIRKH+Bqx~6e_G&1(3ejxK`0=mf1E|Nq
zg<=u2uvqT$4(mtVm}x%P3ROpxbBrC^YPR|f==t&1F%4l+WZ1xc)NkO%oE7j0t67UC
zt~t0OjJq&o;QUQbA1_+?cC)|f<>oPDW^-Jl+9Z&N#R{G&DUUT`EPB6z4y!oZIb37%
z35ez`8trd7t>!nHRUo8NI*3!@*#jFC<ModJI~6W+-Z2x0E_-k)1{ZxWEHv}L|DOsy
zdGp{rFgiaz_zoyW2FTRID{zQf4=;kHr1S7>Mb{motecD1?UK6r{2h4+h+U+jE?Xaa
zN(#J2$Dmw*kh{VusZ+Xtl?~q}GmeD7QfI=ErvXb@{PAo2ARgs4j`TKi<KuZ?aZdZh
z55PiV>aYGG`G~ApKKnyQNaUyA at h+s?vWu;RKl(IekY|rR%-=@&6ZZ6el5=!AFyz3|
zFq}4RM|HUNA5DV_VseJz`ld4&Hj-jzIob$uEd-2Y)v-wsPKu8$P}H at MZ;s_W6kyRk
zzA>v2m;loiX<6Mh>AM;W-aq(6Ng=BmA|ZfmYj~1xK_4ziVjVfxVAh>P<dh_i&=B=K
zg at L`&ntft4<9TqnPLo&M&(6#_c|QxCQn}PCbzrOFJY!A^Vzhz7E90O}%`q3HPdx)M
zhn#npU??v)uH#R50!Cwvvmo~9XN7<hxTxtVEMiO3J9#m8F}bpbfqxd%(Pq4c(c5VV
z$9iF7v!HJF!Um+bc;OqL3+h%c+=+0T7mh*xb6z+K`P;p4H^QA>cpCC_QFuNYt4HB(
z?}k5a^mySwg!{ZOkHY<C?xyXQM85>+Rd)sh!>caGIr8~Zh5j#yov at 3Y|7Ca9<E>;b
zkkj4~`5DsjS}!7*$HQeNd~0`Z!%aTES2}HP#k;N7exIrSc!c8IQF8IPUK1E^p_#p7
zAH)P1I28#Zak+AG2L4P`C#LYHP%|oX5#xy&n#}th8ekOemT(TPp}0xrZfzx{Cql$b
zs)}Ab$2|_cPa01wl{?`diDI2IpyfJ%k&K+w$TZa3PxN2tkYxDcX~oE=B=3uLi2VG;
zbX-GDJ&zCK%u_4ybJ~yL9oc=P{Zv?FCH=Uz=sF_CnYf0Zq!;V%O8JMrk>=@tTEr;X
zU3B*wyLgU-w0?-<uGY9&eZvC7Tk7yNiZ5=Cp&VF`zSjjG)HBO)3nTYDEEKXdo*Ng5
zIvtNLWS(~7>DK>cEzIj`7usDHT<!ReQMS9z2)<0aYk4k<s*L^Z0=|)4?Sg{&)-|yc
z?+&H4o6<Uw=Et0Oq3dmDW<UxVKBI$V64FM3LM*yksc8{)<yypTbm at 5q9+j3h9dh-w
zJq6Q<=C5IjuG`Lee|-*+w(aafq;;O1t*E<AlwYRc=brh?LC?;Ur1C2PcMpB_QrM2w
z<bd?LKYj1v+lb#UF?@uEQBDk at Hg?&u2;pC!!jDB_{xZrL(7ph`M3OsZ;A-uNgcYQ|
z;};Csaek2xuw>}lR}fkHw_dE8^U<#7SvnfJ<7VTiMdi$(ba<g}0Lw!ZqYRWQdPNfZ
z>E57Ju<#022;IQXsz9C|f2_7~*QMz=9Ui$95oV+l;|JT1a-#!*U8}<_L5y<Le#ujw
z46^ak40N;hQlx4{pZyNrJr>>F2!DJTVe!Jr50}P=8M}qCh#hiW6y%qt<6Eo>{^2B{
z8!KVvCK{X}KTM^r8-G;Nkdu10;QD>fH%L0vizFjyx;zWlo0pgHS3GvH(XT}Pj%<7o
zslBq{nFo9c^Z26g6Vh)me4q3wMnvDEgVJTZkFf`Gda(NVbzSj;$3Mem^v}#KH#%4J
zr2-^4k6(>LCyxHK(g!_C`8f?~r1g3P{nEa^2G at VRQ7V)T3y<TSC{My%=gk{$D`v^*
z|6eH%q~n$zC^{0xneaF}u0#X|c;5Y at k?g%ST`)4ryAtJl!GQ;_^Hw6(B79&L?SKKf
z0|w*{7%<EqK&C!#Ej_2 at rl8h)r&JHZ)4cGstAaYl3p4-u`xsnG9vys=m!|+dj2j12
zWMoJ}q<e6AZ~z_Hv_a{!TUF%2!~kc)?H6fTs_z*1M!c}_(N|CU?}R<XHVHFxXcjCw
z1J{Yq=b1T9Pr!3X_)t4Pgvg|L(d8T&nxo+Fdaz-q;g?pH{}=o&u>_)F{}H{6?51AC
zj7(Rw_&d`^Mih|jOc`xt`Cm~CqwcopSy-qT_P4#kLPHQ%P;4F*cvG}J&c4hJfOv-O
zabLJ2#wvviQlIDErsP=LlN?N<k}EmbGGUaKpUG~{wyX7E?g?CKPxp$uf8$^w3mLYA
zaj+gT+zsPk3GgA*QJv_p`3n$zA9EW8=vE-gL9ji&&m9#2Sw85x`$H96Rw(+%+w#=#
z93;5Us^L}aAX`)j6!EBn>S}SjLg0 at 8R$KT4cm|T)>n6b80W|Jp4Lrqy#`eA*vUKbu
zIhQr|-X?92lIxXfn(!0X5$(}Y=?)Krw-u1--Zu$+K`3LCsrI=jvCJ-7-Sy!xn}cfi
z&kw@~zQ|*V21{ajb at FZtTt{baSRf9qKavl@=(BA>J{*N<wtwWq)A$ox02g7JJD?D7
zk_EUGTVOFjvTbQGWCgci1X%4+zMOW*#!(p)6Kq|@@CNc2OJFAI-Bbb#L}X1*qJNUO
z_m=?M*Cn7s<2Osthg#eBR`_pJ-?<e|;<LcLdpj&vAi3{7_y&JmJE27`{l)>Y+nrkq
WfA>NC>xisj8-bNH*VhT;XZ{cKCJoB~

-- 
2.25.1



From neel.gandhi at xilinx.com  Sat Jan 22 04:14:07 2022
From: neel.gandhi at xilinx.com (Neel Gandhi)
Date: Sat, 22 Jan 2022 17:44:07 +0530
Subject: [PATCH] dmaengine: xilinx: dpdma: Fix race condition in vsync IRQ
Message-ID: <20220122121407.11467-1-neel.gandhi@xilinx.com>

Protected race condition of virtual DMA channel from channel queue transfer
via vchan spin lock from the caller of xilinx_dpdma_chan_queue_transfer

Signed-off-by: Neel Gandhi <neel.gandhi at xilinx.com>
---
 drivers/dma/xilinx/xilinx_dpdma.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c
index b0f4948b00a5..7d77a8948e38 100644
--- a/drivers/dma/xilinx/xilinx_dpdma.c
+++ b/drivers/dma/xilinx/xilinx_dpdma.c
@@ -1102,7 +1102,9 @@ static void xilinx_dpdma_chan_vsync_irq(struct  xilinx_dpdma_chan *chan)
        chan->desc.active = pending;
        chan->desc.pending = NULL;

+       spin_lock(&chan->vchan.lock);
        xilinx_dpdma_chan_queue_transfer(chan);
+       spin_unlock(&chan->vchan.lock);

 out:
        spin_unlock_irqrestore(&chan->lock, flags);
@@ -1495,7 +1497,9 @@ static void xilinx_dpdma_chan_err_task(struct tasklet_struct *t)
                    XILINX_DPDMA_EINTR_CHAN_ERR_MASK << chan->id);

        spin_lock_irqsave(&chan->lock, flags);
+       spin_lock(&chan->vchan.lock);
        xilinx_dpdma_chan_queue_transfer(chan);
+       spin_unlock(&chan->vchan.lock);
        spin_unlock_irqrestore(&chan->lock, flags);
 }

--
2.17.1

This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.


From lkp at intel.com  Sat Jan 22 04:22:09 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 22 Jan 2022 20:22:09 +0800
Subject: [PATCH 1/4] firmware: psci: Export a couple of suspend symbols
In-Reply-To: <20220122035421.4086618-2-f.fainelli@gmail.com>
References: <20220122035421.4086618-2-f.fainelli@gmail.com>
Message-ID: <202201221911.EEIlXDWO-lkp@intel.com>

Hi Florian,

I love your patch! Yet something to improve:

[auto build test ERROR on arm/for-next]
[also build test ERROR on soc/for-next arm64/for-next/core clk/clk-next linus/master v5.16 next-20220121]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
base:   git://git.armlinux.org.uk/~rmk/linux-arm.git for-next
config: arm64-randconfig-r011-20220120 (https://download.01.org/0day-ci/archive/20220122/202201221911.EEIlXDWO-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 7b3d30728816403d1fd73cc5082e9fb761262bce)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/488fbdb7de4d39409045b679db3e370600a774d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Florian-Fainelli/Broadcom-STB-PM-PSCI-extensions/20220122-115551
        git checkout 488fbdb7de4d39409045b679db3e370600a774d4
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> ld.lld: error: undefined symbol: cpu_suspend
   >>> referenced by psci.c
   >>> firmware/psci/psci.o:(psci_system_suspend_enter) in archive drivers/built-in.a
--
>> ld.lld: error: undefined symbol: cpu_resume
   >>> referenced by psci.c
   >>> firmware/psci/psci.o:(psci_system_suspend) in archive drivers/built-in.a
   >>> referenced by psci.c
   >>> firmware/psci/psci.o:(psci_system_suspend) in archive drivers/built-in.a

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From stefan.wahren at i2se.com  Sat Jan 22 04:35:47 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sat, 22 Jan 2022 13:35:47 +0100
Subject: [PATCH RFC 1/4] brcmfmac: use separate firmware for 43430
 revision 4
In-Reply-To: <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
 <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>
Message-ID: <8ed4450d-85d9-c69b-761a-7695b3f1bbb3@i2se.com>

Am 01.01.22 um 21:26 schrieb Stefan Wahren:
> A separate firmware is needed, for Broadcom 43430 revision 4. This
> chip can be found on e.g. certain revisions of Raspberry Pi Zero 2 W.
> Original firmware file from IC vendor is named 'brcmfmac43436-sdio.bin',
> but brcmfmac and also btbcm drivers report chip id 43430, so requested
> firmware file name is 'brcmfmac43430c0-sdio.bin' in line with other
> 43430 revisions.
>
> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
> ---
>
> Hi,
> i'm not sure about all these mappings. All i can say is that the wifi
> interface of the RPi Zero 2 cames up with this patch.
gentle ping (yes, i'm aware of the merge window)
>
>  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> index 8effeb7..c79bd47 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
> @@ -618,6 +618,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
>  /* Note the names are not postfixed with a1 for backward compatibility */
>  BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
>  BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
> +BRCMF_FW_CLM_DEF(43430C0, "brcmfmac43430c0-sdio");
>  BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
>  BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
>  BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
> @@ -649,7 +650,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
>  	BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
>  	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
>  	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
> -	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
> +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43430C0),
> +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFF8, 43430B0),
>  	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
>  	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
>  	BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),


From semen.protsenko at linaro.org  Sat Jan 22 04:38:08 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Sat, 22 Jan 2022 14:38:08 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
Message-ID: <CAPLW+4k8=ymx56R7bKOt8kMVG_uUgrTsCkVd5wiY_rkYq8dYbQ@mail.gmail.com>

On Wed, 19 Jan 2022 at 18:53, Olof Johansson <olof at lixom.net> wrote:
>
> On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
> >
> > On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
> > <semen.protsenko at linaro.org> wrote:
> > > On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> > >
> > > Hi Olof, Arnd,
> > >
> > > Just want to check if it's possible for those patches to be applied in
> > > v5.17? Sorry for the noise, but that's important to me.
> >
> > I can see that Olof merged merged this into the "arm/late" branch in
> > the soc tree,
> > so I assume he still plans to send it in the next few days.
>
> Yep, will be sent up today most likely.
>

Thanks for detailed answer! Glad to hear it's still a possibility.
Please let me know if you need any actions on my side (like rebasing,
etc).

> > With the timing over Christmas, I sent out the large bulk of the
> > contents (anything
> > I merged before Dec 23) last year, and Linus already merged it, the rest ended
> > up in the "late" branch.
> >
> > As usual, there is no guarantee that late changes make it in, but I have seen
> > no indication of any problems so far.
>
> Correct. Been sitting on it for a while in case there were fixes
> coming in for the first pieces that got merged, but in traditional
> fashion I'm guessing those will start to show up a few days after the
> late branch gets merged. :)
>
>
> -Olof


From irui.wang at mediatek.com  Sat Jan 22 04:50:28 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Sat, 22 Jan 2022 20:50:28 +0800
Subject: pull request: linux-firmware: mediatek: Update MT8173 VPU
Message-ID: <20220122125029.22195-1-irui.wang@mediatek.com>

Hi linux-firmware maintainers,

The following changes since commit 0c6a7b3bf728b95c8b7b95328f94335e2bb2c967:

  linux-firmware: Update firmware file for Intel Bluetooth 9260 (2022-01-19 11:16:28 -0500)

are available in the Git repository at:

  https://github.com/irui-wang/linux_fw_vpu_v1.1.7.git v1.1.7

for you to fetch changes up to 70390331db03113fd7fe1dff195b135a7f2ad840:

  linux-firmware: mediatek: Update MT8173 VPU firmware to v1.1.7 (2022-01-22 20:30:38 +0800)

----------------------------------------------------------------
Irui Wang (1):
      linux-firmware: mediatek: Update MT8173 VPU firmware to v1.1.7

 mediatek/mt8173/vpu_d.bin | Bin 2977184 -> 2977184 bytes
 mediatek/mt8173/vpu_p.bin | Bin 131180 -> 131180 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)




From irui.wang at mediatek.com  Sat Jan 22 04:50:29 2022
From: irui.wang at mediatek.com (Irui Wang)
Date: Sat, 22 Jan 2022 20:50:29 +0800
Subject: [PATCH] linux-firmware: mediatek: Update MT8173 VPU firmware to v1.1.7
In-Reply-To: <20220122125029.22195-1-irui.wang@mediatek.com>
References: <20220122125029.22195-1-irui.wang@mediatek.com>
Message-ID: <20220122125029.22195-2-irui.wang@mediatek.com>

[encoder vp8]
set buffer pitch info by input format

Release Version: 1.1.7

Signed-off-by: Irui Wang <irui.wang at mediatek.com>
---
 mediatek/mt8173/vpu_d.bin | Bin 2977184 -> 2977184 bytes
 mediatek/mt8173/vpu_p.bin | Bin 131180 -> 131180 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/mediatek/mt8173/vpu_d.bin b/mediatek/mt8173/vpu_d.bin
index 45e214dd4aac4c54b8dc2778c7de3de69c6f41a6..e966b49bee57e8cfaa3536174830916cf35b184f 100644
GIT binary patch
delta 370
zcmXZWy-LGS7>DtHVv|OjRIOEO{j9C^tB44qlVB)LA}%^Ob#`)a$nM~3^aeWQ0s_Gb
zMG)*22yP+>-arON2cLikemv)Whr{W9JQ`iZj%B5>^!(si_3CjbRgj$v&ij?A^1bvG
zCZX52lbn0HYwRUwhcD(<{3<mDQVToSN1xpR_5bfj^aSUF#BcX%e&<uNc>9jpbo*P%
z(++jAJuT4oo8;1K>Sc2(6|*_zAD5+ at D7cLR115%$g9RITI2gtV3UJ|}h*6AT93 at Pk
pj7dyk8Wqf-idoEI9t&8+5^7jR9Sy9YiB+s&9UItuih|bf&mT1*fl&Ye

delta 370
zcmXZWJ4?e*7>DtHVow at vQnlV{jh9;QiksqU at dI=b#8I4_9J4z(r!I~i@&O7#1s9>S
zgF**U1W|DiQ3r7n at d^0CkLSE+IGo1aiPb>UHRiY}?H>82QmRE#fONK*_P(uRU3!j^
z$Uk?Ij8|K+R+G*33wwF1C0(M8TRdO~FL?bwzteC0wvy_`X}Rj&ONO`Cs6%far7U%y
zklxcAeY=u88eB_$x_?OdbpPZZdxe8IJd8sNHad`jfrBhubfOD6c<_-&H+s;E0{YO8
o0SsaYMGT{a5d;{;7{)PyGA2>M6s9qQS<GP`3s^jh!=<0EKXfvMYybcN

diff --git a/mediatek/mt8173/vpu_p.bin b/mediatek/mt8173/vpu_p.bin
index 96f1c632972cb068d0c1aacbc78b5cc0da07bf4a..55a49ec244539011213928bb66909a3564af703e 100644
GIT binary patch
delta 5437
zcmZWN4OmoV*7ppT%T>8M-UbHIVP;4O|Am!G%XAP-)KRc>bCZ;DTtdUAAxWqxE<eJk
zBtNe?Xl#t;G^3J{cVwvi5Rz8DmK2gU>%$VAh)v>WAu|`_J9lQZ_SuJL?mh2$&;L2^
zIq#)UVEY8NE+>-xg#*gO at N0<>ITvn`y2yv2LF|om1;Z?2eY6Ijx`hws<qE+8f*{X2
zdV~vMx3d1VM84&{RQ=Q4m7ISyC4c50QCzpPNDoCT<=bM9=qC&L99$TX|LFQyA69XS
zlT-h6ZgX}IFxfZc$GPoJO1`<R+vVq;SK7m^kh`6molHTRP{8%cue-i;vVS-4cXE_6
z&6)1}l#=x26;#Dlb;oYe8~rFoA)}bI95v0G)HKBy%*7Q(Xup3#0)5b6?sgr~UyE(l
z8yTeYM>?c2nDZ-)NZI33nvJ_ at Mo~@Q<EOp+W|~o&4Q9ogy-ve>#@CUi^gn3wBqe)&
zM0=3QNi)WBHLWPiuShdVLQwQRx3kA(+>gxUKbR%nN*`~9kGBeWEowR~$6)47#skuB
zafRXyX&22ngzI#qI7l<yE(02u_noBBil~}<OmF#^{_15izKx2HpyIn8AErGX)66xA
z*N(jJ+~c+Rc#rycPayB{|1$cRM1|%!Xoc6~chSaLR&Ovbwi;?h^CE=|Zi&^pWip_N
zd&yqNAg1`~kVOu~Pla027=H=zl?fJvXDkhePEo&fF~AnF^zrxnvB(zc%K)lL+p4+H
zKt at -E!9+57bs4D0 at zs%7iS4U{A)558UIr|glhh3DWH4zqI7M~xJQ`Za6KhxD(~8d=
z(!bUS$>J01rUM9K?w{;__=<R%2N)y|ZP*G{V%;zk9Hec-6u3-!H_Q#w37SPFN)FTu
zSp9;A#}WqW6)!wOVpAexs&;dN=E>S51}Jc-(<3GdVL(xGe)M$@l?PUp{sz0ro|L(;
zpM01S#&t^4ynFl^;!b%963E79Li6rPqvV-qeES&^?LMz&tpt1J^F@;86RbKFb>_a#
zF;xDEv=nuE9>bu$9_ at i%N_Bb?Bgyme#Y!?Vz48Vn85E_?0S7aV?;$szc at e5e#>VYy
zs$b(C8cD`oL8Hz{Vq)4>OO$fn{F;YTotnf1<sN4>AyW_RI<%p~vtBE$&*A#Xj at 4O7
zj3&fr*>z}Dhlj6~%-A#=)4zVxqv-4YO$#t*7dAyrZ_4Eq5waB?Jt&hus$&_{lQxpe
z`8nug_k6ib)Twi09JyZYIcSkd=e0<c=fQcjG`z+wLT at E$o^>pFEj9Ehw}jC#>KsZQ
zljWu6sk=BG6PJZ}lh-f4MT$-dN>o(w33shh1nO9iyku#|Cp&@kr$&Xf?EMW>RKhLF
z{hjtY@<+q2`05FIKy5>ZlNj~dq7xfYo8O67JzU-#N_fBH629oT&k9zO;&)uV)}wWh
z+%|+^rB2!$o$O28XyJ08H0roTlziizyEp|ZQdY$*(kOpA3?%7}hgtOkmg&^0JQRqE
zOhTAc)<)%B9#XY=CM1e2n=9yXrQ10UV}C^;8=swmr|IQqOTbBF=~wWST}@vKP2_>C
z7oeZ~w6!vi9kxH<5HvmZy=X{r1EA3ODxc66$zwz9&ynBSzPDwjhHDpV2UeojmC{-I
z*3L%{+w+k^(D)tXiz#`x-FL>KDNmGxVLQ?d+xSvJ<F-lpFnOaT2&n5D%eOX)BFu9g
z*g7shHx+AY^tma)85$*4wY_N!=_ at mkK0JX>B(pLeM(4KR8ZyKew*L&=T7(m>28}~M
z530z{=Q|*oB$}R?&c49iw0F1yJXRS#@PsbfYu8O18{gsdJLtuc3#Lo)xFcu^tA=bq
z6$THL4B55)p51CM$AC>(zS!Dtk!+DLW9YNwFC`BlK3`eUomm6WDi-Ysqd_Ge$zJD&
zVZQZp2^u84vK71453d{>AL`*7DmiS^_7?_I^22s17WFp%7O5?s0?}e?@i+((_Hn0e
zyI0-~m((nFuSEBIOY%V=+sxq at gi`ZY{&1C~?RyxXZ|(at^buWID0aU4%4S1^4}Q8V
z4Cedb%Ceb|P8!P=gjfqOTc59NwrkX%M- at 86F^{h_`9t{>jQ))Bd^EYXe3dM#oO~NG
zi6|;kI8VE*!KQ>qIg#X6e8f4VL^`~fB9c(K!^1R{{9ok^oCgfqoA+|_l=whFm5`Gk
zwAeaSQ|Qz&`ErU?(Gd<INV&y83McPM%n!~tsOU+E&))+zyir9<bny-y(;S+(n=P3b
zKGDA^l+RMr_rI#9>np;|IfY7dVXcm#Sc93VDUcWMeqfIl;ST4{X@$tAz`dd3Tg7?i
zEh?JFUw(HWtz*{Iw<-!RGlV<O$<09zR4J?I=gWfC^iYkCF`#H;tHGR>XYA53X*<<O
zuQcQQbmOpoac8uamH1I~duf=lO-0XVbyV7BgBhrtL}@RxzBEYD-g9t1tEQF2pEa1Y
ztTNBfkIK{+JK5;`qk{}pOPyBq>X>kL=!1}hJDVz^DQsb1I)5(S;mAfK8!9L&6AjJj
z4W#)oKehya+1t<o{Hf_ob0*#zG|DygKsJualJ*8^)I&7|Ve7{<%855vvSVydTR|`$
z8KR<%V+FzaTZU at x)9qJaC{^@Ou|_F{`>8Q9?Tx+ANt&!dr1gy-;S8xikPQ*y9Lqcz
z4&luQPlrYbnt=Ma1_pak2chKG at 4UgW)OfvFMWPR_!Llki6pxgDJM=xy_LFbE4p1&G
z{OcMS6p?*3AvoIKsfj|d7iu0v3~ikbS~ABv1>qIe#n|xnSRcgM-DIuG6GAUtrPOba
z6T-AI?|T$<%u#-*Sm6%EaOfBd!FaoYe*3a8W%3V{I(gjqlIxI+#Zd90n*ItiHf}I6
zA;j#eIQ$ni{Wj)}Vl&MFHSfypyT8PO$TS=3qo(b+rDNX4um^m~(V$h*f-3GzXjS-Z
z=F*6cnV^5Hv2c0znF;!*&jgT|GjR<{Jx69#vDEI03QR8lFr^I`OivJd59|HbCyx_U
z+Fvzl^{*PGju}rVR^guE2$8>p=EhGDf;DOj5yI$SRrJzOiscPZ6C&3rGxw<I+jj(2
zh*6_nF;1f#xuc^0b?4QvkS!WD*H2MBcSwTm803ikwjDBAj)RodgpijVG0;kC9Wyan
zmmT4<mUqZp>ttznr8S()KNcpdwvoNo>7sCK4an9GkxR!@AeBU)Sc!L at +!G6A(Idol
zVi9a1H%}~KN3eb1jVGGuYO@!VpR)z^NL|r$=1n)bbGA<GdcJk?F!sT7whp^AUz at R4
z$F#M0xgFwQ?PGY^B6Ch|WdDW7{#i$wmh3;d7%q#QCj$VlSzYga_lLT7J>;G~p+8A3
z)_ujEM$CYnSCP8+AH$K;|Nabi82QiI({x08YBsDVt51dF#m;m}gU|9)Ml6((Q{kb5
zXSp%<rcKZo+ois&=o|CS>^3q-tU#?z;&MQD$Df`Gxn$1iWiq;%WS`E#9yfS86z`Yg
z>!T3<WBns+Gg@%T#?vIL-lX{$7w2p|PGUi$y;>O5ZF}}D9w(K@<iNiXKiA_i?alYX
z(rK%(bz?w0+v`8!_-Gx2gYK9{$xvU~-uJdn9IdVrbVSy$jcxL}i^>}2;puQR6atKr
zSsy-%xlI4?mAulM=!_@$8UMp6qfI!+ at fucy@O&R!eTGw>@xfJyZ}Pzjh;Q-1vk-3e
z!KDbd`CtL*+kJ3sBd6^2!9_ at OS%R0KG8PwIzKtyiU-iKm2)li7Dhlc~G5wYSoX(4_
z(&Rgjp5f$c7mt3FEYnJ>vvz*gPj;~m2bH}5XE`PBi24BWIP1GeP-6ru5n<`!7iD7z
zbdmLqk+KMp<TYw>&R82mWr>aCqsHm1uf_sNU*lY?0oB>inW|4btiM{ueEMaTjflZQ
zY7sQUc4_!XYt+<7QqLxPa(p|9r^SY|Hz2ZFQhU=@uzZ5P!*)Eea~j at 6rj1YFwb;@k
zrE)-{bfmRegDtDK`7znrQzYu+ZMdlXcs4$pK7JBLNYJ?y{8kR2SV#6kl5;K`QHRc{
zJ)h4P?R*4jI`<}`Qd;8XE&PR}SfN(XC;}-tLrEXl80Lk4;rvk1Jlz0h+<SeHRZ4s4
zL?CHziAPOApNLQ`wtlh|7Dsn*?aoWicKoB{?auR at Kh^GB*GZ$O1YHM*v2}KEGU^NG
z{j*ranPVkfC*lIA&z)$Y>Adt+Wj(KfI?{BW1e*lSQQL<rB~yALhf(d54m<+sts0~<
zw?2wZxurE+7CkI}-?{>%^YYmvB;!*#;&VS;Aftzg>(f*`ujLn~iMqf4ua{yO?mqF^
zpTSLPKbwTd7^q4+#=Pyba{x_Z`Nih}j#hTeg`*_8BMR at D>pOl%_mV$f=?5vK`il*?
zxb;OhegleMfB7U0c$B;1FbbxwAWs6X+b}DoT~iR{=$ehE_a9x62#<DY&=A#?x%kvy
ziCX1!+lR43VTL0E at g{?z&i#f<>!Vn=?R~65>0UNu>%zED^6cs>+<1H+54_BI?ugVE
z7*|TZ&f0~sG%@#AiA`5#N(S|PBS#;|=(oG at S#b3tqMqnRR5jUrZ5}=kTwBe$y@|y-
zy*BN)h3fk67W(Tumj2GZaIbwi?*Fpy8V**>V*6FEorB+a?W?+m_L-P<)gtXS09eJe
z at 8Tr$96g)- at WuXML?p?$5s7oW^2W3HynUmL>%GN2gp<zGq&md|eJ{z-;)w%6>btcr
zoz4k*?4yqBkwFu^_j10PEE$+BUF~k#B)UI2F#5RzNf`IGfq9t7K~EwFJ&7FDEg3=@
zH)cqRu(!YmIHlItFXkgW%Lf;I$0=id at cMuL){q?J>%m9ZvnXa*IzOtRRL^3>hKr)1
zbs_1}7G{qf!pWm3@~-%Fad7A<DG!OmI`#vc9C$-xN%?U2l#~y-m>kJ#L8D_j5974T
z5j_(4{iJQUo&5<HQ{(wS@#x4x8T+$$l`Qt&Y at t~NenJRAsMz^$t!HsSvZCwXvt^Sw
zal+`R4C+L7tbt~KMK<(0*3#++%Vo)&ML|P-FksOIQ5>s}w#V7m*g;x1S-zoRm at k)e
zmuznDOqI~(mTUenRpJa_VAo`d3&7xI2W8upS}<J=O17u@*j?{1u$+b_%iws}4o$9&
z6JRy4p^~8*p0YRtA^P6R)fWg|GF&ncVozJ>YL`Q%ADZrpSHLxyOgGsQrGyn=b-kd3
zXRu-{?IBRaa$Z at JTq%<PkLp!RTPQ4rI at f)Z;YWb1dKElMLzZQs7BV5la#9OnFyd;{
z0+v&{>+z}J4_qlFH`o_pOxD=>BG>u|Sirz77vA~b at JE_y(I6xp5a0%C>=PgkRm{nU
z5H!rPEFVrmk>z$iJch6N1 at I*lxh59E5Fnpy7pwxPvm_ToX2>Ko6H_|IR!C)#HRf6I
zR?FpLcn)b2N+1U1?ks_2Jd&oZmHuzwt4OQmLJ4S4d4CDoFlzbQ48NfG&fU<AQ`mK2
tFRYRw+Wk6Q#Fuj)G<ouyHOR-ha?9XHKa{_XcqHs0ut^H&4FdTY{|~~;15^M2

delta 5601
zcmZ`d4Ompwwr358!%;bRIB#G;8)gOt!PLa0!ZICXO3YF8g+*lvVu*&_A$>wGlHo at f
ze-dz)gT at swjx#D2IU_^FRZP5c%?gyR)WZTr<E2+YdB(dR#asK#Xnya$_xZVJt+m(x
zT6^t%xMAUMSor#!2!2=q#>|N$#1b(Bs!4ss6VUAJk8lS;G^u{73RlCN$MQB?f)o~u
zQsme26KnSizI8;Yn6b+Aa_=s|w~|pV|68O`<SH@=MT?YUWA>ZAx8w`L*SC~go;Yc`
zRDM)YGFx3^T~}{$+1Hha1i{59GtO;s`}ED)aZPwmS>)nfeg&H>1%ls~H<T`+&|Tol
ze&5f<xxQo=^;+JyAup~Xm|txws9?C>7=}yp(XuLqmQBw|wTk96V7PI{;__5$`^5bw
zcF##uubbg6Q$7y)eDllG%?y`nRa?_omb>O=xwNfFue>jBWjVFAxLoxi%cXvjider3
zdEP^w9bTS1bJ}(<(>7#srCQU<SWZ>Sa_MF*n`+H3PuodVt5LX*3cruS<i3GjUfFW5
zYz4~NP&P-)iYSj%G at rJca-~{TA5boo--~z#;(M;T at _OBA)hJZ;PeS{=LVuz{X!s)(
z+)pE>N-^S^%dTtgG&{;3_$OJ(D_iT8J&dx4?mK;u?qXIPxEo9(K7vZ>sM_Lk-jv$F
zF!QRNMRQdOsCHHu7ASxxJ at dDNnPkRKfgG|seiGD^ruYj;-)XcVJo%Y0=yE1JGY=rc
zX?^w+Uu?8kQz>BAwJn|j&186SC<GGql2Xu<14|-;NBjsduzE}o)QTptWeo4fFv{#0
za(T%D at Fx!^o`g<vBXK%3Iwvfh#X=idlC&7tN?dcv&q-;J<Xp0R3P6!F=LNeD{^(y8
z0fxw<udIbyQu)f%(7Hqpm_$ySoXEw69Okttj8f$)#uH)DiQS~{l^LN%i*Bx&Q3CUp
zhgwbHcRcVgiCz&gvvR9o(LFC~0*5vuJirnP=%>i+l(}SBzvFkfpA at f{F|}fc at Mdxz
zTDRz^bxUaeVMZAq at SaC=7q#M%5nD*linsF;JeW2Ec{Si*lwtRH>uC(sGNa6D_R7c}
zd+dwhRF_w;mGXMx6m#DbI41vadWtq9kK at n}*;B7pYKQ9c%EkIqC0QQlhDhJ5g-}T{
zUR%Gcdb9BO&{9trnTg!Yb4w7$;CF16d9^8tTwv}YUKc!R_m;gcb;x)U#ZMu=tYgW>
zL{1l+X4|rNQHLydj!a%T9eXHg<x`MA%2v+CLZ4k3Ii)pMP=za=lhcJd#aaW;p`G;M
zT*1e|9=z{<H<^$!Bd;#kV?75wG8;S|>GNcoY^8a#Fc$-)+GIR74@;=3pcDhA&0&-?
z%^v^7{s(9qJsL#z9?ihTZG3>YjpnEXtxQx^hza*xRrwou*+>%I@)}GaKc_^7wr&5N
zVl5Ho=04z(i#(FLCA4~+iT3AU4fbeK(c#z7oX_ERWhv20+Eat4`%@X8L)s+S#?X9u
z?@jC|^*|oV&?*)l@=(Pg61XZ_<85T7a3L@{ZQNW&`P#4dXe4D-kWT*=W at AzXZB8_6
zwuI6Hkfy%R^Zu%-U~;ysDrd)(trr9=!=)nf@|uV6G;Uf`0*&OiHJ2cUbZ0yRtz_cb
zui*w6T)QjO|BijK!=k%p-;Rch8v&KZS9n{hja0AGp-juV;IJ4*&Q}nu$5`%2VwpwP
zC(+cJJ#iP2;dTFkL#6YLNi)qA(m|;~IwM(hTcj6iXbw8;Z+Q63IyJVey=4?-cV!|i
z%qW^jROS=td<x=VcD}j(7Z8#WHueOLLD at Ze^41?aAc+{wuTJrQOSo(AaQk7+eD<V%
zCg(TClZ3kxAK&5f+2f&+v*ruv`@XE;snwqSTasnryy}}aYMD|-?P3hAJ);aJ-Zc6<
zd$Otk&N(d`LRru|_hm2lK_x@~UV`Rx-&u>Z>)Ja9$0Dh$I5>2qQ#y??UXkE)V0xPe
zF&{N{s;RI-jB&OWkAdK#ox(9`>!N$fqKAL$A`G~%Bp- at Mx-|^LwpzdQg+8)s=M%W@
z-T4v>kU6E}aTflebUH*)SXWCkWzn6q7nsgRo?kSM>8`<9!^GpPsIjNd@$&C1oeG(x
zsdRR5Z2 at -Z`9&w~I_>$$LWgry&IwP(mOX^Wcyd`jhT|w(tjH-NKZb`8W%&xBnijJP
z72^3#B01%s3w4y@@KB}^!>$do&?Itk*TZ;|D9H9a%gKl0{Vf{f=KR2U)q_<kmw}6N
z<ix92YgiwhB``lIl^8hR#Tr)SV0bYVszQ_+Hh-Ie6VnV_p(|l)ydxm&<oK5He2JC~
z at Wp#~W0-Z~yJ~Agxq-_mOtlu)6(|{g@;0st at 3*a+qV&9h>p&}oj^SceU7m&=EY`5r
z)&8uwdRaq$Z()~#6V9}$tbrU+R|v||pve`3RqXoIceQL<n}JKu)3OG<DiP~eThlkG
z`p}hs)3SO#)w--<Q?#nxz@?otaIyT3(DYRr76%VQ_p%yt66hY%1J&f(o>Y7usC|6%
z_$-s2=c9d?0j}7^9LujYa7^9cXR7{9Enz&v1n;@%Dv#daFmM|7mtuy=Mn at aV{n at Nu
zA3mqwhZjdRYzh9)UYBJR*U>k}vW6_{tD`#g_CO$mRf at zHM|IkO>jj}3kX8`H6Ch*1
zQlY+7#KqMUG^}A~L6CtPtQss<xoFy#;|9Z|5~BHFJM=gm9{}LpduVqyL^&tgW+||r
zUf6SNe3V7!*AUmp;i%~#jPlB_9|$}%)?|$$;d_ at M&!)ZcxHj$m33crM at I8P^XY`+z
zDaM!W6Fzc?b~@MxrJ43Z$9%ioSq`$dDiRHSQS}&<k>RQ-q0=e_r<YT#h-=c at eQNGX
zVIJ->GPimjjF8RMkKvobRb7#1;5Kw+ZB_MIRKH+Bqx~6e_G&1(3ejxK`0=mf1E|Nq
zg<=u2uvqT$4(mtVm}x%P3ROpxbBrC^YPR|f==t&1F%4l+WZ1xc)NkO%oE7j0t67UC
zt~t0OjJq&o;QUQbA1_+?cC)|f<>oPDW^-Jl+9Z&N#R{G&DUUT`EPB6z4y!oZIb37%
z35ez`8trd7t>!nHRUo8NI*3!@*#jFC<ModJI~6W+-Z2x0E_-k)1{ZxWEHv}L|DOsy
zdGp{rFgiaz_zoyW2FTRID{zQf4=;kHr1S7>Mb{motecD1?UK6r{2h4+h+U+jE?Xaa
zN(#J2$Dmw*kh{VusZ+Xtl?~q}GmeD7QfI=ErvXb@{PAo2ARgs4j`TKi<KuZ?aZdZh
z55PiV>aYGG`G~ApKKnyQNaUyA at h+s?vWu;RKl(IekY|rR%-=@&6ZZ6el5=!AFyz3|
zFq}4RM|HUNA5DV_VseJz`ld4&Hj-jzIob$uEd-2Y)v-wsPKu8$P}H at MZ;s_W6kyRk
zzA>v2m;loiX<6Mh>AM;W-aq(6Ng=BmA|ZfmYj~1xK_4ziVjVfxVAh>P<dh_i&=B=K
zg at L`&ntft4<9TqnPLo&M&(6#_c|QxCQn}PCbzrOFJY!A^Vzhz7E90O}%`q3HPdx)M
zhn#npU??v)uH#R50!Cwvvmo~9XN7<hxTxtVEMiO3J9#m8F}bpbfqxd%(Pq4c(c5VV
z$9iF7v!HJF!Um+bc;OqL3+h%c+=+0T7mh*xb6z+K`P;p4H^QA>cpCC_QFuNYt4HB(
z?}k5a^mySwg!{ZOkHY<C?xyXQM85>+Rd)sh!>caGIr8~Zh5j#yov at 3Y|7Ca9<E>;b
zkkj4~`5DsjS}!7*$HQeNd~0`Z!%aTES2}HP#k;N7exIrSc!c8IQF8IPUK1E^p_#p7
zAH)P1I28#Zak+AG2L4P`C#LYHP%|oX5#xy&n#}th8ekOemT(TPp}0xrZfzx{Cql$b
zs)}Ab$2|_cPa01wl{?`diDI2IpyfJ%k&K+w$TZa3PxN2tkYxDcX~oE=B=3uLi2VG;
zbX-GDJ&zCK%u_4ybJ~yL9oc=P{Zv?FCH=Uz=sF_CnYf0Zq!;V%O8JMrk>=@tTEr;X
zU3B*wyLgU-w0?-<uGY9&eZvC7Tk7yNiZ5=Cp&VF`zSjjG)HBO)3nTYDEEKXdo*Ng5
zIvtNLWS(~7>DK>cEzIj`7usDHT<!ReQMS9z2)<0aYk4k<s*L^Z0=|)4?Sg{&)-|yc
z?+&H4o6<Uw=Et0Oq3dmDW<UxVKBI$V64FM3LM*yksc8{)<yypTbm at 5q9+j3h9dh-w
zJq6Q<=C5IjuG`Lee|-*+w(aafq;;O1t*E<AlwYRc=brh?LC?;Ur1C2PcMpB_QrM2w
z<bd?LKYj1v+lb#UF?@uEQBDk at Hg?&u2;pC!!jDB_{xZrL(7ph`M3OsZ;A-uNgcYQ|
z;};Csaek2xuw>}lR}fkHw_dE8^U<#7SvnfJ<7VTiMdi$(ba<g}0Lw!ZqYRWQdPNfZ
z>E57Ju<#022;IQXsz9C|f2_7~*QMz=9Ui$95oV+l;|JT1a-#!*U8}<_L5y<Le#ujw
z46^ak40N;hQlx4{pZyNrJr>>F2!DJTVe!Jr50}P=8M}qCh#hiW6y%qt<6Eo>{^2B{
z8!KVvCK{X}KTM^r8-G;Nkdu10;QD>fH%L0vizFjyx;zWlo0pgHS3GvH(XT}Pj%<7o
zslBq{nFo9c^Z26g6Vh)me4q3wMnvDEgVJTZkFf`Gda(NVbzSj;$3Mem^v}#KH#%4J
zr2-^4k6(>LCyxHK(g!_C`8f?~r1g3P{nEa^2G at VRQ7V)T3y<TSC{My%=gk{$D`v^*
z|6eH%q~n$zC^{0xneaF}u0#X|c;5Y at k?g%ST`)4ryAtJl!GQ;_^Hw6(B79&L?SKKf
z0|w*{7%<EqK&C!#Ej_2 at rl8h)r&JHZ)4cGstAaYl3p4-u`xsnG9vys=m!|+dj2j12
zWMoJ}q<e6AZ~z_Hv_a{!TUF%2!~kc)?H6fTs_z*1M!c}_(N|CU?}R<XHVHFxXcjCw
z1J{Yq=b1T9Pr!3X_)t4Pgvg|L(d8T&nxo+Fdaz-q;g?pH{}=o&u>_)F{}H{6?51AC
zj7(Rw_&d`^Mih|jOc`xt`Cm~CqwcopSy-qT_P4#kLPHQ%P;4F*cvG}J&c4hJfOv-O
zabLJ2#wvviQlIDErsP=LlN?N<k}EmbGGUaKpUG~{wyX7E?g?CKPxp$uf8$^w3mLYA
zaj+gT+zsPk3GgA*QJv_p`3n$zA9EW8=vE-gL9ji&&m9#2Sw85x`$H96Rw(+%+w#=#
z93;5Us^L}aAX`)j6!EBn>S}SjLg0 at 8R$KT4cm|T)>n6b80W|Jp4Lrqy#`eA*vUKbu
zIhQr|-X?92lIxXfn(!0X5$(}Y=?)Krw-u1--Zu$+K`3LCsrI=jvCJ-7-Sy!xn}cfi
z&kw@~zQ|*V21{ajb at FZtTt{baSRf9qKavl@=(BA>J{*N<wtwWq)A$ox02g7JJD?D7
zk_EUGTVOFjvTbQGWCgci1X%4+zMOW*#!(p)6Kq|@@CNc2OJFAI-Bbb#L}X1*qJNUO
z_m=?M*Cn7s<2Osthg#eBR`_pJ-?<e|;<LcLdpj&vAi3{7_y&JmJE27`{l)>Y+nrkq
WfA>NC>xisj8-bNH*VhT;XZ{cKCJoB~

-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Sat Jan 22 05:14:57 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 22 Jan 2022 14:14:57 +0100
Subject: [PATCH] ARM: dts: exynos: use define for TMU clock on Exynos4412
Message-ID: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>

Replace clock hard-coded number with a define from bindings.  No
functional change.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos4412.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
index d3802046c8b8..aa0b61b59970 100644
--- a/arch/arm/boot/dts/exynos4412.dtsi
+++ b/arch/arm/boot/dts/exynos4412.dtsi
@@ -813,7 +813,7 @@ &tmu {
 	interrupt-parent = <&combiner>;
 	interrupts = <2 4>;
 	reg = <0x100C0000 0x100>;
-	clocks = <&clock 383>;
+	clocks = <&clock CLK_TMU_APBIF>;
 	clock-names = "tmu_apbif";
 	status = "disabled";
 };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 22 05:25:52 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 22 Jan 2022 14:25:52 +0100
Subject: [PATCH 1/3] ARM: dts: exynos: drop old thermal properties from
 Exynos4210
Message-ID: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>

The samsung,tmu_gain and samsung,tmu_reference_voltage properties of
Exynos Thermal Management Unit driver are not used since April 2018.
They were removed with commit fccfe0993b5d ("thermal: exynos: remove
parsing of samsung,tmu_gain property") and commit 61020d189dbc
("thermal: exynos: remove parsing of samsung, tmu_reference_voltage
property"), so drop them also from Exynos4210 DTS.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

I'll take this patch via Samsung SoC. Adding here for reference, so
Rob's robot will not spot DTS issues when checking against dtschema.
---
 arch/arm/boot/dts/exynos4210.dtsi | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 7e7d65ce6585..2c25cc37934e 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -527,8 +527,6 @@ &tmu {
 	compatible = "samsung,exynos4210-tmu";
 	clocks = <&clock CLK_TMU_APBIF>;
 	clock-names = "tmu_apbif";
-	samsung,tmu_gain = <15>;
-	samsung,tmu_reference_voltage = <7>;
 };
 
 #include "exynos4210-pinctrl.dtsi"
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 22 05:25:53 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 22 Jan 2022 14:25:53 +0100
Subject: [PATCH 2/3] dt-bindings: thermal: samsung: convert to dtschema
In-Reply-To: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220122132554.65192-2-krzysztof.kozlowski@canonical.com>

Convert the Samsung Exynos SoC Thermal Management Unit bindings to DT
schema format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/thermal/exynos-thermal.txt       | 106 ----------
 .../thermal/samsung,exynos-thermal.yaml       | 184 ++++++++++++++++++
 2 files changed, 184 insertions(+), 106 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/thermal/exynos-thermal.txt
 create mode 100644 Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml

diff --git a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt b/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
deleted file mode 100644
index 33004ce7e5df..000000000000
--- a/Documentation/devicetree/bindings/thermal/exynos-thermal.txt
+++ /dev/null
@@ -1,106 +0,0 @@
-* Exynos Thermal Management Unit (TMU)
-
-** Required properties:
-
-- compatible : One of the following:
-	       "samsung,exynos3250-tmu"
-	       "samsung,exynos4412-tmu"
-	       "samsung,exynos4210-tmu"
-	       "samsung,exynos5250-tmu"
-	       "samsung,exynos5260-tmu"
-	       "samsung,exynos5420-tmu" for TMU channel 0, 1 on Exynos5420
-	       "samsung,exynos5420-tmu-ext-triminfo" for TMU channels 2, 3 and 4
-			Exynos5420 (Must pass triminfo base and triminfo clock)
-               "samsung,exynos5433-tmu"
-	       "samsung,exynos7-tmu"
-- reg : Address range of the thermal registers. For soc's which has multiple
-	instances of TMU and some registers are shared across all TMU's like
-	interrupt related then 2 set of register has to supplied. First set
-	belongs	to register set of TMU instance and second set belongs to
-	registers shared with the TMU instance.
-
-  NOTE: On Exynos5420, the TRIMINFO register is misplaced for TMU
-	channels 2, 3 and 4
-	Use "samsung,exynos5420-tmu-ext-triminfo" in cases, there is a misplaced
-	register, also provide clock to access that base.
-
-	TRIMINFO at 0x1006c000 contains data for TMU channel 3
-	TRIMINFO at 0x100a0000 contains data for TMU channel 4
-	TRIMINFO at 0x10068000 contains data for TMU channel 2
-
-- interrupts : Should contain interrupt for thermal system
-- clocks : The main clocks for TMU device
-	-- 1. operational clock for TMU channel
-	-- 2. optional clock to access the shared registers of TMU channel
-	-- 3. optional special clock for functional operation
-- clock-names : Thermal system clock name
-	-- "tmu_apbif" operational clock for current TMU channel
-	-- "tmu_triminfo_apbif" clock to access the shared triminfo register
-		for current TMU channel
-	-- "tmu_sclk" clock for functional operation of the current TMU
-		channel
-
-The Exynos TMU supports generating interrupts when reaching given
-temperature thresholds. Number of supported thermal trip points depends
-on the SoC (only first trip points defined in DT will be configured):
- - most of SoC: 4
- - samsung,exynos5433-tmu: 8
- - samsung,exynos7-tmu: 8
-
-** Optional properties:
-
-- vtmu-supply: This entry is optional and provides the regulator node supplying
-		voltage to TMU. If needed this entry can be placed inside
-		board/platform specific dts file.
-
-Example 1):
-
-	tmu at 100c0000 {
-		compatible = "samsung,exynos4412-tmu";
-		interrupt-parent = <&combiner>;
-		reg = <0x100C0000 0x100>;
-		interrupts = <2 4>;
-		clocks = <&clock 383>;
-		clock-names = "tmu_apbif";
-		vtmu-supply = <&tmu_regulator_node>;
-		#thermal-sensor-cells = <0>;
-	};
-
-Example 2): (In case of Exynos5420 "with misplaced TRIMINFO register")
-	tmu_cpu2: tmu at 10068000 {
-		compatible = "samsung,exynos5420-tmu-ext-triminfo";
-		reg = <0x10068000 0x100>, <0x1006c000 0x4>;
-		interrupts = <0 184 0>;
-		clocks = <&clock 318>, <&clock 318>;
-		clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-		#thermal-sensor-cells = <0>;
-	};
-
-	tmu_cpu3: tmu at 1006c000 {
-		compatible = "samsung,exynos5420-tmu-ext-triminfo";
-		reg = <0x1006c000 0x100>, <0x100a0000 0x4>;
-		interrupts = <0 185 0>;
-		clocks = <&clock 318>, <&clock 319>;
-		clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-		#thermal-sensor-cells = <0>;
-	};
-
-	tmu_gpu: tmu at 100a0000 {
-		compatible = "samsung,exynos5420-tmu-ext-triminfo";
-		reg = <0x100a0000 0x100>, <0x10068000 0x4>;
-		interrupts = <0 215 0>;
-		clocks = <&clock 319>, <&clock 318>;
-		clock-names = "tmu_apbif", "tmu_triminfo_apbif";
-		#thermal-sensor-cells = <0>;
-	};
-
-Note: For multi-instance tmu each instance should have an alias correctly
-numbered in "aliases" node.
-
-Example:
-
-aliases {
-	tmuctrl0 = &tmuctrl_0;
-	tmuctrl1 = &tmuctrl_1;
-	tmuctrl2 = &tmuctrl_2;
-};
diff --git a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
new file mode 100644
index 000000000000..17129f75d962
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/samsung,exynos-thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Thermal Management Unit (TMU)
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description: |
+  For multi-instance tmu each instance should have an alias correctly numbered
+  in "aliases" node.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos3250-tmu
+      - samsung,exynos4412-tmu
+      - samsung,exynos4210-tmu
+      - samsung,exynos5250-tmu
+      - samsung,exynos5260-tmu
+        # For TMU channel 0, 1 on Exynos5420:
+      - samsung,exynos5420-tmu
+        # For TMU channels 2, 3 and 4 of Exynos5420:
+      - samsung,exynos5420-tmu-ext-triminfo
+      - samsung,exynos5433-tmu
+      - samsung,exynos7-tmu
+
+  clocks:
+    minItems: 1
+    maxItems: 3
+
+  clock-names:
+    minItems: 1
+    maxItems: 3
+
+  interrupts:
+    description: |
+      The Exynos TMU supports generating interrupts when reaching given
+      temperature thresholds. Number of supported thermal trip points depends
+      on the SoC (only first trip points defined in DT will be configured)::
+       - most of SoC: 4
+       - samsung,exynos5433-tmu: 8
+       - samsung,exynos7-tmu: 8
+    maxItems: 1
+
+  reg:
+    items:
+      - description: TMU instance registers.
+      - description: |
+          Shared TMU registers.
+
+          Note:: On Exynos5420, the TRIMINFO register is misplaced for TMU
+          channels 2, 3 and 4 Use "samsung,exynos5420-tmu-ext-triminfo" in
+          cases, there is a misplaced register, also provide clock to access
+          that base.
+          TRIMINFO at 0x1006c000 contains data for TMU channel 3
+          TRIMINFO at 0x100a0000 contains data for TMU channel 4
+          TRIMINFO at 0x10068000 contains data for TMU channel 2
+    minItems: 1
+
+  '#thermal-sensor-cells': true
+
+  vtmu-supply:
+    description: The regulator node supplying voltage to TMU.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: /schemas/thermal/thermal-sensor.yaml
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5420-tmu-ext-triminfo
+    then:
+      properties:
+        clocks:
+          items:
+            - description:
+                Operational clock for TMU channel.
+            - description:
+                Optional clock to access the shared registers (e.g. TRIMINFO) of TMU
+                channel.
+        clock-names:
+          items:
+            - const: tmu_apbif
+            - const: tmu_triminfo_apbif
+        reg:
+          minItems: 2
+          maxItems: 2
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5433-tmu
+              - samsung,exynos7-tmu
+    then:
+      properties:
+        clocks:
+          items:
+            - description:
+                Operational clock for TMU channel.
+            - description:
+                Optional special clock for functional operation of TMU channel.
+        clock-names:
+          items:
+            - const: tmu_apbif
+            - const: tmu_sclk
+        reg:
+          minItems: 1
+          maxItems: 1
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos3250-tmu
+              - samsung,exynos4412-tmu
+              - samsung,exynos4210-tmu
+              - samsung,exynos5250-tmu
+              - samsung,exynos5260-tmu
+              - samsung,exynos5420-tmu
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        reg:
+          minItems: 1
+          maxItems: 1
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos4.h>
+
+    tmu at 100c0000 {
+        compatible = "samsung,exynos4412-tmu";
+        reg = <0x100C0000 0x100>;
+        interrupt-parent = <&combiner>;
+        interrupts = <2 4>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clock CLK_TMU_APBIF>;
+        clock-names = "tmu_apbif";
+        vtmu-supply = <&ldo10_reg>;
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tmu at 10068000 {
+        compatible = "samsung,exynos5420-tmu-ext-triminfo";
+        reg = <0x10068000 0x100>, <0x1006c000 0x4>;
+        interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&clock 318>, <&clock 318>; /* CLK_TMU */
+        clock-names = "tmu_apbif", "tmu_triminfo_apbif";
+        vtmu-supply = <&ldo7_reg>;
+    };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tmu at 10060000 {
+        compatible = "samsung,exynos5433-tmu";
+        reg = <0x10060000 0x200>;
+        interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+        #thermal-sensor-cells = <0>;
+        clocks = <&cmu_peris 3>, /* CLK_PCLK_TMU0_APBIF */
+                 <&cmu_peris 35>; /* CLK_SCLK_TMU0 */
+        clock-names = "tmu_apbif", "tmu_sclk";
+        vtmu-supply = <&ldo3_reg>;
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 22 05:25:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 22 Jan 2022 14:25:54 +0100
Subject: [PATCH 3/3] MAINTAINERS: thermal: samsung: drop obsolete properties
In-Reply-To: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220122132554.65192-3-krzysztof.kozlowski@canonical.com>

Update the Samsung Exynos SoC thermal driver entry to match reality and
add Krzysztof Kozlowski as co-maintainer (as he maintains entire Samsung
SoC).  The rationale:
1. Bartlomiej's Samsung email bounces, since he is not working in
   Samsung for some time.
2. The mentioned Lukasz Majewski's Git tree was not updated
   since 2015.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 MAINTAINERS | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 27730a5a6345..928fb4cebe09 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17118,11 +17118,12 @@ S:	Supported
 F:	drivers/net/ethernet/samsung/sxgbe/
 
 SAMSUNG THERMAL DRIVER
-M:	Bartlomiej Zolnierkiewicz <b.zolnierkie at samsung.com>
+M:	Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
+M:	Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
 L:	linux-pm at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
-S:	Supported
-T:	git https://github.com/lmajewski/linux-samsung-thermal.git
+S:	Maintained
+F:	Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
 F:	drivers/thermal/samsung/
 
 SAMSUNG USB2 PHY DRIVER
-- 
2.32.0



From frank-w at public-files.de  Sat Jan 22 06:50:25 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Sat, 22 Jan 2022 15:50:25 +0100
Subject: Aw: Re: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <236548630.RelmrRfzIS@diego>
References: <20220116124911.65203-1-linux@fw-web.de>
 <trinity-5a2f356e-2777-4624-b921-f8f56ce282c7-1642420742957@3c-app-gmx-bap64>
 <CAMdYzYrNQCcOiLf=jUGtCTM44SU8bUpBBOac6_SGJtqX+hvUuA@mail.gmail.com>
 <236548630.RelmrRfzIS@diego>
Message-ID: <trinity-d0efbf68-ed45-47d4-97b3-d3788c5a9de6-1642863025116@3c-app-gmx-bap44>

Hi,

i plan to send a v2 of the series after 5.17-rc1 is out, because i have now verified
the functions from gpio header and found some pinctrl-changes. V1 had only prepared
the nodes to know which devices are present on this header.

should i include this patch again or do you pull it from v1 (maybe as fix)?

regards Frank


> Gesendet: Montag, 17. Januar 2022 um 22:05 Uhr
> Von: "Heiko St?bner" <heiko at sntech.de>

> From looking at the documentation I got the impression that the
> pclk_xpcs is related to the separate qsgmii_pcs in the memory map.
> 
> So yes, I fully agree to dropping this clock from here and then adding
> them to whatever ip block really needs it.


From jic23 at kernel.org  Sat Jan 22 09:04:47 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sat, 22 Jan 2022 17:04:47 +0000
Subject: [PATCH 2/2] iio: at91-sama5d2: Limit requested watermark value
 to hwfifo size
In-Reply-To: <20220117102512.31725-2-paul@crapouillou.net>
References: <20220117102512.31725-1-paul@crapouillou.net>
 <20220117102512.31725-2-paul@crapouillou.net>
Message-ID: <20220122170447.68f35cfa@jic23-huawei>

On Mon, 17 Jan 2022 10:25:12 +0000
Paul Cercueil <paul at crapouillou.net> wrote:

> Instead of returning an error if the watermark value is too high, which
> the core will silently ignore anyway, limit the value to the hardware
> FIFO size; a lower-than-requested value is still better than using the
> default, which is usually 1.

There is another potential error condition in this function which will
also be ignored by the core.

As such whilst I agree this is a sensible thing to do in this
particular case I think we should also be handling the error in the core.

I think it would be better to clean that up at the same time
as these improvements - particularly as I'd guess you have a convenient
test setup to check the error unwind is correct?

Thanks,

Jonathan

> 
> Cc: Eugen Hristev <eugen.hristev at microchip.com>
> Cc: Nicolas Ferre <nicolas.ferre at microchip.com>
> Cc: Alexandre Belloni <alexandre.belloni at bootlin.com>
> Cc: Ludovic Desroches <ludovic.desroches at microchip.com>
> Signed-off-by: Paul Cercueil <paul at crapouillou.net>
> ---
>  drivers/iio/adc/at91-sama5d2_adc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/adc/at91-sama5d2_adc.c b/drivers/iio/adc/at91-sama5d2_adc.c
> index 854b1f81d807..5cc84f4a17bb 100644
> --- a/drivers/iio/adc/at91-sama5d2_adc.c
> +++ b/drivers/iio/adc/at91-sama5d2_adc.c
> @@ -1752,7 +1752,7 @@ static int at91_adc_set_watermark(struct iio_dev *indio_dev, unsigned int val)
>  	int ret;
>  
>  	if (val > AT91_HWFIFO_MAX_SIZE)
> -		return -EINVAL;
> +		val = AT91_HWFIFO_MAX_SIZE;
>  
>  	if (!st->selected_trig->hw_trig) {
>  		dev_dbg(&indio_dev->dev, "we need hw trigger for DMA\n");



From okaya at kernel.org  Sat Jan 22 10:05:30 2022
From: okaya at kernel.org (Sinan Kaya)
Date: Sat, 22 Jan 2022 13:05:30 -0500
Subject: [PATCH v2] dmaengine: qcom_hidma: Remove useless DMA-32 fallback
 configuration
In-Reply-To: <4deb32b0c7838da66608022c584326eb01d0da03.1642232106.git.christophe.jaillet@wanadoo.fr>
References: <4deb32b0c7838da66608022c584326eb01d0da03.1642232106.git.christophe.jaillet@wanadoo.fr>
Message-ID: <ee43d68f-000c-6513-38f2-877b9018ab22@kernel.org>

On 1/15/2022 2:35 AM, Christophe JAILLET wrote:
> As stated in [1], dma_set_mask() with a 64-bit mask never fails if
> dev->dma_mask is non-NULL.
> So, if it fails, the 32 bits case will also fail for the same reason.
> 
> Simplify code and remove some dead code accordingly.
> 
> [1]: https://lore.kernel.org/linux-kernel/YL3vSPK5DXTNvgdx at infradead.org/#t
> 

Can we please document this?

Usual practice was to try allocating 64 bit DMA if possible and fallback
to 32 bits.

> Signed-off-by: Christophe JAILLET <christophe.jaillet at wanadoo.fr>
> ---
> v2: have the subject and updated driver match
> ---
>   drivers/dma/qcom/hidma.c | 4 +---
>   1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c
> index 65d054bb11aa..51587cf8196b 100644
> --- a/drivers/dma/qcom/hidma.c
> +++ b/drivers/dma/qcom/hidma.c
> @@ -838,9 +838,7 @@ static int hidma_probe(struct platform_device *pdev)
>   	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
>   	if (rc) {
>   		dev_warn(&pdev->dev, "unable to set coherent mask to 64");
> -		rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
> -		if (rc)
> -			goto dmafree;
> +		goto dmafree;
>   	}
>   
>   	dmadev->lldev = hidma_ll_init(dmadev->ddev.dev,



From sashal at kernel.org  Sat Jan 22 10:39:30 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 13:39:30 -0500
Subject: [PATCH AUTOSEL 5.16 02/52] clk: samsung: exynos850: Register
 clocks early
In-Reply-To: <CAPLW+4mPnktJTBeokhbmSGTZTqOa3-rkpThYHZ-Y0=_40bbLtA@mail.gmail.com>
References: <20220117165853.1470420-1-sashal@kernel.org>
 <20220117165853.1470420-2-sashal@kernel.org>
 <b75a0bc9-0423-83cc-11e1-d5e08952cc93@canonical.com>
 <CAPLW+4mPnktJTBeokhbmSGTZTqOa3-rkpThYHZ-Y0=_40bbLtA@mail.gmail.com>
Message-ID: <YexPYoPd5CTfNuId@sashalap>

On Mon, Jan 17, 2022 at 09:18:43PM +0200, Sam Protsenko wrote:
>On Mon, 17 Jan 2022 at 19:11, Krzysztof Kozlowski
><krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 17/01/2022 17:58, Sasha Levin wrote:
>> > From: Sam Protsenko <semen.protsenko at linaro.org>
>> >
>> > [ Upstream commit bcda841f9bf2cddcf2f000cba96f2e27f6f2bdbf ]
>> >
>> > Some clocks must be registered before init calls. For example MCT clock
>> > (from CMU_PERI) is needed for MCT timer driver, which is registered
>> > with TIMER_OF_DECLARE(). By the time we get to core_initcall() used for
>> > clk-exynos850 platform driver init, it's already too late. Inability to
>> > get "mct" clock in MCT driver leads to kernel panic, as functions
>> > registered with *_OF_DECLARE() can't do deferred calls. MCT timer driver
>> > can't be fixed either, as it's acting as a clock source and it's
>> > essential to register it in start_kernel() -> time_init().
>> >
>> > Let's register CMU_PERI clocks early, using CLK_OF_DECLARE(). CMU_TOP
>> > generates clocks needed for CMU_PERI, but it's already registered early.
>> >
>> > While at it, let's cleanup the code a bit, by extracting everything
>> > related to CMU initialization and registration to the separate function.
>> >
>> > Similar issue was discussed at [1] and addressed in commit 1f7db7bbf031
>> > ("clk: renesas: cpg-mssr: Add early clock support"), as well as in
>> > drivers/clk/mediatek/clk-mt2712.c.
>> >
>> > [1] https://patchwork.kernel.org/project/linux-renesas-soc/patch/20180829132954.64862-2-chris.brandt at renesas.com/
>> >
>> > Signed-off-by: Sam Protsenko <semen.protsenko at linaro.org>
>> > Signed-off-by: Sylwester Nawrocki <s.nawrocki at samsung.com>
>> > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> > Link: https://lore.kernel.org/r/20211122144206.23134-1-semen.protsenko at linaro.org
>> > Signed-off-by: Sasha Levin <sashal at kernel.org>
>> > ---
>> >  drivers/clk/samsung/clk-exynos850.c | 70 ++++++++++++++++++++---------
>> >  1 file changed, 49 insertions(+), 21 deletions(-)
>> >
>>
>> I propose to skip this one.
>>
>> Backporting it to v5.16 does not hurt but also does not bring any
>> benefits for the upstream kernel users. There is no support for
>> mentioned Exynos850 in v5.16.
>>
>> It could have only meaning for some downstream, out-of-tree kernels
>> which apply Exynos850 support on top of v5.16, but then they can just
>> take this patch as well.
>>
>
>Agreed. DTS patches will be merged only in v5.17, hopefully. Till that
>time the whole clock driver is floating with no users. That's
>historical thing -- I didn't have "Ack" to submit board dts at the
>time, and SoC dts couldn't be applied without users (board dts). So I
>focused on driver work, isolated. Not much sense to backport something
>without having real users.

Dropped, thanks!

-- 
Thanks,
Sasha


From sashal at kernel.org  Sat Jan 22 11:27:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 14:27:01 -0500
Subject: [PATCH AUTOSEL 4.4 06/29] ARM: imx: rename
 DEBUG_IMX21_IMX27_UART to DEBUG_IMX27_UART
In-Reply-To: <20220120100849.GA14998@amd>
References: <20220118030822.1955469-1-sashal@kernel.org>
 <20220118030822.1955469-6-sashal@kernel.org>
 <20220120100849.GA14998@amd>
Message-ID: <YexahcZZO1z/pM94@sashalap>

On Thu, Jan 20, 2022 at 11:08:49AM +0100, Pavel Machek wrote:
>Hi!
>
>> From: Lukas Bulwahn <lukas.bulwahn at gmail.com>
>>
>> [ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]
>>
>> Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
>> DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.
>
>This is unsuitable for 4.4 as imx21 is still supported there.

I'll drop it, thanks!

-- 
Thanks,
Sasha


From pavel at denx.de  Sat Jan 22 12:45:37 2022
From: pavel at denx.de (Pavel Machek)
Date: Sat, 22 Jan 2022 21:45:37 +0100
Subject: [PATCH AUTOSEL 4.4 06/29] ARM: imx: rename
 DEBUG_IMX21_IMX27_UART to DEBUG_IMX27_UART
In-Reply-To: <YexahcZZO1z/pM94@sashalap>
References: <20220118030822.1955469-1-sashal@kernel.org>
 <20220118030822.1955469-6-sashal@kernel.org>
 <20220120100849.GA14998@amd> <YexahcZZO1z/pM94@sashalap>
Message-ID: <20220122204537.GA31487@duo.ucw.cz>

Hi!

> > > From: Lukas Bulwahn <lukas.bulwahn at gmail.com>
> > > 
> > > [ Upstream commit b0100bce4ff82ec1ccd3c1f3d339fd2df6a81784 ]
> > > 
> > > Since commit 4b563a066611 ("ARM: imx: Remove imx21 support"), the config
> > > DEBUG_IMX21_IMX27_UART is really only debug support for IMX27.
> > 
> > This is unsuitable for 4.4 as imx21 is still supported there.
> 
> I'll drop it, thanks!

Thank you.

I have not checked which is the newest kernel that supports imx21,
other kernels may have same issue, too.

Best regards,
								Pavel

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220122/23ccd1c9/attachment.sig>

From sashal at kernel.org  Sat Jan 22 16:10:55 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 19:10:55 -0500
Subject: [PATCH AUTOSEL 5.16 02/19] hwspinlock: stm32: enable clock at probe
In-Reply-To: <20220123001113.2460140-1-sashal@kernel.org>
References: <20220123001113.2460140-1-sashal@kernel.org>
Message-ID: <20220123001113.2460140-2-sashal@kernel.org>

From: Fabien Dessenne <fabien.dessenne at foss.st.com>

[ Upstream commit 60630924bb5af8751adcecc896e7763c3783ca89 ]

Set the clock during probe and keep its control during suspend / resume
operations.
This fixes an issue when CONFIG_PM is not set and where the clock is
never enabled.

Make use of devm_ functions to simplify the code.

Signed-off-by: Fabien Dessenne <fabien.dessenne at foss.st.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Link: https://lore.kernel.org/r/20211011135836.1045437-1-fabien.dessenne at foss.st.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++++++++++----------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 3ad0ce0da4d98..5bd11a7fab65d 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
 	.relax		= stm32_hwspinlock_relax,
 };
 
+static void stm32_hwspinlock_disable_clk(void *data)
+{
+	struct platform_device *pdev = data;
+	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_put_noidle(dev);
+
+	clk_disable_unprepare(hw->clk);
+}
+
 static int stm32_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct stm32_hwspinlock *hw;
 	void __iomem *io_base;
 	size_t array_size;
@@ -66,41 +81,43 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 		return PTR_ERR(io_base);
 
 	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-	hw = devm_kzalloc(&pdev->dev, sizeof(*hw) + array_size, GFP_KERNEL);
+	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
-	hw->clk = devm_clk_get(&pdev->dev, "hsem");
+	hw->clk = devm_clk_get(dev, "hsem");
 	if (IS_ERR(hw->clk))
 		return PTR_ERR(hw->clk);
 
-	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
-		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
+	ret = clk_prepare_enable(hw->clk);
+	if (ret) {
+		dev_err(dev, "Failed to prepare_enable clock\n");
+		return ret;
+	}
 
 	platform_set_drvdata(pdev, hw);
-	pm_runtime_enable(&pdev->dev);
 
-	ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
-				   0, STM32_MUTEX_NUM_LOCKS);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_put(dev);
 
-	if (ret)
-		pm_runtime_disable(&pdev->dev);
+	ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
+	if (ret) {
+		dev_err(dev, "Failed to register action\n");
+		return ret;
+	}
 
-	return ret;
-}
+	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
+		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
 
-static int stm32_hwspinlock_remove(struct platform_device *pdev)
-{
-	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
-	int ret;
+	ret = devm_hwspin_lock_register(dev, &hw->bank, &stm32_hwspinlock_ops,
+					0, STM32_MUTEX_NUM_LOCKS);
 
-	ret = hwspin_lock_unregister(&hw->bank);
 	if (ret)
-		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-
-	pm_runtime_disable(&pdev->dev);
+		dev_err(dev, "Failed to register hwspinlock\n");
 
-	return 0;
+	return ret;
 }
 
 static int __maybe_unused stm32_hwspinlock_runtime_suspend(struct device *dev)
@@ -135,7 +152,6 @@ MODULE_DEVICE_TABLE(of, stm32_hwpinlock_ids);
 
 static struct platform_driver stm32_hwspinlock_driver = {
 	.probe		= stm32_hwspinlock_probe,
-	.remove		= stm32_hwspinlock_remove,
 	.driver		= {
 		.name	= "stm32_hwspinlock",
 		.of_match_table = stm32_hwpinlock_ids,
-- 
2.34.1



From sashal at kernel.org  Sat Jan 22 16:12:01 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 19:12:01 -0500
Subject: [PATCH AUTOSEL 5.15 02/16] hwspinlock: stm32: enable clock at probe
In-Reply-To: <20220123001216.2460383-1-sashal@kernel.org>
References: <20220123001216.2460383-1-sashal@kernel.org>
Message-ID: <20220123001216.2460383-2-sashal@kernel.org>

From: Fabien Dessenne <fabien.dessenne at foss.st.com>

[ Upstream commit 60630924bb5af8751adcecc896e7763c3783ca89 ]

Set the clock during probe and keep its control during suspend / resume
operations.
This fixes an issue when CONFIG_PM is not set and where the clock is
never enabled.

Make use of devm_ functions to simplify the code.

Signed-off-by: Fabien Dessenne <fabien.dessenne at foss.st.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Link: https://lore.kernel.org/r/20211011135836.1045437-1-fabien.dessenne at foss.st.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++++++++++----------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 3ad0ce0da4d98..5bd11a7fab65d 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
 	.relax		= stm32_hwspinlock_relax,
 };
 
+static void stm32_hwspinlock_disable_clk(void *data)
+{
+	struct platform_device *pdev = data;
+	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_put_noidle(dev);
+
+	clk_disable_unprepare(hw->clk);
+}
+
 static int stm32_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct stm32_hwspinlock *hw;
 	void __iomem *io_base;
 	size_t array_size;
@@ -66,41 +81,43 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 		return PTR_ERR(io_base);
 
 	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-	hw = devm_kzalloc(&pdev->dev, sizeof(*hw) + array_size, GFP_KERNEL);
+	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
-	hw->clk = devm_clk_get(&pdev->dev, "hsem");
+	hw->clk = devm_clk_get(dev, "hsem");
 	if (IS_ERR(hw->clk))
 		return PTR_ERR(hw->clk);
 
-	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
-		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
+	ret = clk_prepare_enable(hw->clk);
+	if (ret) {
+		dev_err(dev, "Failed to prepare_enable clock\n");
+		return ret;
+	}
 
 	platform_set_drvdata(pdev, hw);
-	pm_runtime_enable(&pdev->dev);
 
-	ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
-				   0, STM32_MUTEX_NUM_LOCKS);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_put(dev);
 
-	if (ret)
-		pm_runtime_disable(&pdev->dev);
+	ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
+	if (ret) {
+		dev_err(dev, "Failed to register action\n");
+		return ret;
+	}
 
-	return ret;
-}
+	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
+		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
 
-static int stm32_hwspinlock_remove(struct platform_device *pdev)
-{
-	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
-	int ret;
+	ret = devm_hwspin_lock_register(dev, &hw->bank, &stm32_hwspinlock_ops,
+					0, STM32_MUTEX_NUM_LOCKS);
 
-	ret = hwspin_lock_unregister(&hw->bank);
 	if (ret)
-		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-
-	pm_runtime_disable(&pdev->dev);
+		dev_err(dev, "Failed to register hwspinlock\n");
 
-	return 0;
+	return ret;
 }
 
 static int __maybe_unused stm32_hwspinlock_runtime_suspend(struct device *dev)
@@ -135,7 +152,6 @@ MODULE_DEVICE_TABLE(of, stm32_hwpinlock_ids);
 
 static struct platform_driver stm32_hwspinlock_driver = {
 	.probe		= stm32_hwspinlock_probe,
-	.remove		= stm32_hwspinlock_remove,
 	.driver		= {
 		.name	= "stm32_hwspinlock",
 		.of_match_table = stm32_hwpinlock_ids,
-- 
2.34.1



From sashal at kernel.org  Sat Jan 22 16:12:50 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 19:12:50 -0500
Subject: [PATCH AUTOSEL 5.10 1/9] hwspinlock: stm32: enable clock at probe
Message-ID: <20220123001258.2460594-1-sashal@kernel.org>

From: Fabien Dessenne <fabien.dessenne at foss.st.com>

[ Upstream commit 60630924bb5af8751adcecc896e7763c3783ca89 ]

Set the clock during probe and keep its control during suspend / resume
operations.
This fixes an issue when CONFIG_PM is not set and where the clock is
never enabled.

Make use of devm_ functions to simplify the code.

Signed-off-by: Fabien Dessenne <fabien.dessenne at foss.st.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Link: https://lore.kernel.org/r/20211011135836.1045437-1-fabien.dessenne at foss.st.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++++++++++----------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 3ad0ce0da4d98..5bd11a7fab65d 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
 	.relax		= stm32_hwspinlock_relax,
 };
 
+static void stm32_hwspinlock_disable_clk(void *data)
+{
+	struct platform_device *pdev = data;
+	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_put_noidle(dev);
+
+	clk_disable_unprepare(hw->clk);
+}
+
 static int stm32_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct stm32_hwspinlock *hw;
 	void __iomem *io_base;
 	size_t array_size;
@@ -66,41 +81,43 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 		return PTR_ERR(io_base);
 
 	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-	hw = devm_kzalloc(&pdev->dev, sizeof(*hw) + array_size, GFP_KERNEL);
+	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
-	hw->clk = devm_clk_get(&pdev->dev, "hsem");
+	hw->clk = devm_clk_get(dev, "hsem");
 	if (IS_ERR(hw->clk))
 		return PTR_ERR(hw->clk);
 
-	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
-		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
+	ret = clk_prepare_enable(hw->clk);
+	if (ret) {
+		dev_err(dev, "Failed to prepare_enable clock\n");
+		return ret;
+	}
 
 	platform_set_drvdata(pdev, hw);
-	pm_runtime_enable(&pdev->dev);
 
-	ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
-				   0, STM32_MUTEX_NUM_LOCKS);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_put(dev);
 
-	if (ret)
-		pm_runtime_disable(&pdev->dev);
+	ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
+	if (ret) {
+		dev_err(dev, "Failed to register action\n");
+		return ret;
+	}
 
-	return ret;
-}
+	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
+		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
 
-static int stm32_hwspinlock_remove(struct platform_device *pdev)
-{
-	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
-	int ret;
+	ret = devm_hwspin_lock_register(dev, &hw->bank, &stm32_hwspinlock_ops,
+					0, STM32_MUTEX_NUM_LOCKS);
 
-	ret = hwspin_lock_unregister(&hw->bank);
 	if (ret)
-		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-
-	pm_runtime_disable(&pdev->dev);
+		dev_err(dev, "Failed to register hwspinlock\n");
 
-	return 0;
+	return ret;
 }
 
 static int __maybe_unused stm32_hwspinlock_runtime_suspend(struct device *dev)
@@ -135,7 +152,6 @@ MODULE_DEVICE_TABLE(of, stm32_hwpinlock_ids);
 
 static struct platform_driver stm32_hwspinlock_driver = {
 	.probe		= stm32_hwspinlock_probe,
-	.remove		= stm32_hwspinlock_remove,
 	.driver		= {
 		.name	= "stm32_hwspinlock",
 		.of_match_table = stm32_hwpinlock_ids,
-- 
2.34.1



From sashal at kernel.org  Sat Jan 22 16:13:16 2022
From: sashal at kernel.org (Sasha Levin)
Date: Sat, 22 Jan 2022 19:13:16 -0500
Subject: [PATCH AUTOSEL 5.4 1/8] hwspinlock: stm32: enable clock at probe
Message-ID: <20220123001323.2460719-1-sashal@kernel.org>

From: Fabien Dessenne <fabien.dessenne at foss.st.com>

[ Upstream commit 60630924bb5af8751adcecc896e7763c3783ca89 ]

Set the clock during probe and keep its control during suspend / resume
operations.
This fixes an issue when CONFIG_PM is not set and where the clock is
never enabled.

Make use of devm_ functions to simplify the code.

Signed-off-by: Fabien Dessenne <fabien.dessenne at foss.st.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson at linaro.org>
Link: https://lore.kernel.org/r/20211011135836.1045437-1-fabien.dessenne at foss.st.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/hwspinlock/stm32_hwspinlock.c | 58 +++++++++++++++++----------
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index c8eacf4f9692b..f1ca4717230ac 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -54,8 +54,23 @@ static const struct hwspinlock_ops stm32_hwspinlock_ops = {
 	.relax		= stm32_hwspinlock_relax,
 };
 
+static void stm32_hwspinlock_disable_clk(void *data)
+{
+	struct platform_device *pdev = data;
+	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
+	pm_runtime_put_noidle(dev);
+
+	clk_disable_unprepare(hw->clk);
+}
+
 static int stm32_hwspinlock_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct stm32_hwspinlock *hw;
 	void __iomem *io_base;
 	struct resource *res;
@@ -68,41 +83,43 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 		return PTR_ERR(io_base);
 
 	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-	hw = devm_kzalloc(&pdev->dev, sizeof(*hw) + array_size, GFP_KERNEL);
+	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
-	hw->clk = devm_clk_get(&pdev->dev, "hsem");
+	hw->clk = devm_clk_get(dev, "hsem");
 	if (IS_ERR(hw->clk))
 		return PTR_ERR(hw->clk);
 
-	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
-		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
+	ret = clk_prepare_enable(hw->clk);
+	if (ret) {
+		dev_err(dev, "Failed to prepare_enable clock\n");
+		return ret;
+	}
 
 	platform_set_drvdata(pdev, hw);
-	pm_runtime_enable(&pdev->dev);
 
-	ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
-				   0, STM32_MUTEX_NUM_LOCKS);
+	pm_runtime_get_noresume(dev);
+	pm_runtime_set_active(dev);
+	pm_runtime_enable(dev);
+	pm_runtime_put(dev);
 
-	if (ret)
-		pm_runtime_disable(&pdev->dev);
+	ret = devm_add_action_or_reset(dev, stm32_hwspinlock_disable_clk, pdev);
+	if (ret) {
+		dev_err(dev, "Failed to register action\n");
+		return ret;
+	}
 
-	return ret;
-}
+	for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
+		hw->bank.lock[i].priv = io_base + i * sizeof(u32);
 
-static int stm32_hwspinlock_remove(struct platform_device *pdev)
-{
-	struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
-	int ret;
+	ret = devm_hwspin_lock_register(dev, &hw->bank, &stm32_hwspinlock_ops,
+					0, STM32_MUTEX_NUM_LOCKS);
 
-	ret = hwspin_lock_unregister(&hw->bank);
 	if (ret)
-		dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-
-	pm_runtime_disable(&pdev->dev);
+		dev_err(dev, "Failed to register hwspinlock\n");
 
-	return 0;
+	return ret;
 }
 
 static int __maybe_unused stm32_hwspinlock_runtime_suspend(struct device *dev)
@@ -137,7 +154,6 @@ MODULE_DEVICE_TABLE(of, stm32_hwpinlock_ids);
 
 static struct platform_driver stm32_hwspinlock_driver = {
 	.probe		= stm32_hwspinlock_probe,
-	.remove		= stm32_hwspinlock_remove,
 	.driver		= {
 		.name	= "stm32_hwspinlock",
 		.of_match_table = stm32_hwpinlock_ids,
-- 
2.34.1



From qizhong.cheng at mediatek.com  Sat Jan 22 19:33:06 2022
From: qizhong.cheng at mediatek.com (qizhong cheng)
Date: Sun, 23 Jan 2022 11:33:06 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
Message-ID: <20220123033306.29799-1-qizhong.cheng@mediatek.com>

As an edge-triggered interrupts, its interrupt status should be cleared
before dispatch to the handler of device.

Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
---
 drivers/pci/controller/pcie-mediatek.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 2f3f974977a3..705ea33758b1 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
 		if (status & MSI_STATUS){
 			unsigned long imsi_status;
 
+			/* Clear MSI interrupt status */
+			writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
 			while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
 				for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM)
 					generic_handle_domain_irq(port->inner_domain, bit);
 			}
-			/* Clear MSI interrupt status */
-			writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
 		}
 	}
 
-- 
2.25.1



From daniel at 0x0f.com  Sat Jan 22 21:10:12 2022
From: daniel at 0x0f.com (Daniel Palmer)
Date: Sun, 23 Jan 2022 14:10:12 +0900
Subject: [PATCH v3 3/9] ARM: mstar: Add cpupll to base dtsi
In-Reply-To: <20220121193544.23231-4-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
 <20220121193544.23231-4-romain.perier@gmail.com>
Message-ID: <CAFr9PXkWpQqgnNV4+6s-ENwRepHxxm6R0htHkoVYEgjZN5nGkQ@mail.gmail.com>

Hi Romain,

On Sat, 22 Jan 2022 at 04:35, Romain Perier <romain.perier at gmail.com> wrote:
>
> From: Daniel Palmer <daniel at 0x0f.com>
>
> All MStar/SigmaStar ARMv7 SoCs have the CPU PLL at the same
> place so add it to the base dtsi.
>
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> ---
>  arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
> index 89ebfe4f29da..2249faaa3aa7 100644
> --- a/arch/arm/boot/dts/mstar-v7.dtsi
> +++ b/arch/arm/boot/dts/mstar-v7.dtsi
> @@ -155,6 +155,13 @@ mpll: mpll at 206000 {
>                                 clocks = <&xtal>;
>                         };
>
> +                       cpupll: cpupll at 206400 {
> +                               compatible = "mstar,msc313-cpupll";
> +                               reg = <0x206400 0x200>;
> +                               #clock-cells = <0>;
> +                               clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
> +                       };
> +
>                         gpio: gpio at 207800 {
>                                 #gpio-cells = <2>;
>                                 reg = <0x207800 0x200>;
> --
> 2.34.1
>

I guess I can't add a reviewed by for my own commit but this looks good to me.
The same CPUPLL is present on all of the chips seen so far so this is
the right place for this.

Cheers,

Daniel


From daniel at 0x0f.com  Sat Jan 22 21:12:07 2022
From: daniel at 0x0f.com (Daniel Palmer)
Date: Sun, 23 Jan 2022 14:12:07 +0900
Subject: [PATCH v3 8/9] ARM: mstar: Add OPP table for mercury5
In-Reply-To: <20220121193544.23231-9-romain.perier@gmail.com>
References: <20220121193544.23231-1-romain.perier@gmail.com>
 <20220121193544.23231-9-romain.perier@gmail.com>
Message-ID: <CAFr9PXki+_qsPiX90ZaLcJeQhdo-rfUDMTL2D5Zv8Pk=G0Lo+w@mail.gmail.com>

Hi Romain,

On Sat, 22 Jan 2022 at 04:35, Romain Perier <romain.perier at gmail.com> wrote:
>
> From: Daniel Palmer <daniel at 0x0f.com>
>
> Add an OPP table for mercury5 so that cpu frequency scaling can
> happen.
>
> Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
> ---
>  arch/arm/boot/dts/mstar-mercury5.dtsi | 36 +++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/arch/arm/boot/dts/mstar-mercury5.dtsi b/arch/arm/boot/dts/mstar-mercury5.dtsi
> index a7d0dd9d6132..80a19bd23c9c 100644
> --- a/arch/arm/boot/dts/mstar-mercury5.dtsi
> +++ b/arch/arm/boot/dts/mstar-mercury5.dtsi
> @@ -6,6 +6,42 @@
>
>  #include "mstar-v7.dtsi"
>
> +/ {
> +       cpu0_opp_table: opp_table0 {
> +               compatible = "operating-points-v2";
> +               opp-shared;
> +
> +               opp-100000000 {
> +                       opp-hz = /bits/ 64 <100000000>;
> +                       opp-microvolt = <800000 800000 850000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +
> +               opp-200000000 {
> +                       opp-hz = /bits/ 64 <200000000>;
> +                       opp-microvolt = <850000 850000 880000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +
> +               opp-400000000 {
> +                       opp-hz = /bits/ 64 <400000000>;
> +                       opp-microvolt = <880000 880000 890000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +               opp-600000000 {
> +                       opp-hz = /bits/ 64 <600000000>;
> +                       opp-microvolt = <900000 900000 1000000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +
> +               opp-800000000 {
> +                       opp-hz = /bits/ 64 <800000000>;
> +                       opp-microvolt = <900000 900000 1000000>;
> +                       clock-latency-ns = <300000>;
> +               };
> +       };
> +};
> +
>  &imi {
>         reg = <0xa0000000 0x20000>;
>  };
> --
> 2.34.1
>

I think we should drop this one when applying as the frequencies need
to be checked on the hardware again.
I think they should probably match the msc313e settings that Willy verified.

Cheers,

Daniel


From 21cnbao at gmail.com  Sat Jan 22 21:43:06 2022
From: 21cnbao at gmail.com (Barry Song)
Date: Sun, 23 Jan 2022 18:43:06 +1300
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <20220104202227.2903605-1-yuzhao@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
Message-ID: <CAGsJ_4zULJ5vPwn73Z5Bap3eRkAX+Yv24c-n41+zC7fN8xG60g@mail.gmail.com>

On Wed, Jan 5, 2022 at 7:17 PM Yu Zhao <yuzhao at google.com> wrote:
>
> TLDR
> ====
> The current page reclaim is too expensive in terms of CPU usage and it
> often makes poor choices about what to evict. This patchset offers an
> alternative solution that is performant, versatile and
> straightforward.
>
> Design objectives
> =================
> The design objectives are:
> 1. Better representation of access recency
> 2. Try to profit from spatial locality
> 3. Clear fast path making obvious choices
> 4. Simple self-correcting heuristics
>
> The representation of access recency is at the core of all LRU
> approximations. The multigenerational LRU (MGLRU) divides pages into
> multiple lists (generations), each having bounded access recency (a
> time interval). Generations establish a common frame of reference and
> help make better choices, e.g., between different memcgs on a computer
> or different computers in a data center (for cluster job scheduling).
>
> Exploiting spatial locality improves the efficiency when gathering the
> accessed bit. A rmap walk targets a single page and doesn't try to
> profit from discovering an accessed PTE. A page table walk can sweep
> all hotspots in an address space, but its search space can be too
> large to make a profit. The key is to optimize both methods and use
> them in combination. (PMU is another option for further exploration.)
>
> Fast path reduces code complexity and runtime overhead. Unmapped pages
> don't require TLB flushes; clean pages don't require writeback. These
> facts are only helpful when other conditions, e.g., access recency,
> are similar. With generations as a common frame of reference,
> additional factors stand out. But obvious choices might not be good
> choices; thus self-correction is required (the next objective).
>
> The benefits of simple self-correcting heuristics are self-evident.
> Again with generations as a common frame of reference, this becomes
> attainable. Specifically, pages in the same generation are categorized
> based on additional factors, and a closed-loop control statistically
> compares the refault percentages across all categories and throttles
> the eviction of those that have higher percentages.
>
> Patchset overview
> =================
> 1. mm: x86, arm64: add arch_has_hw_pte_young()
> 2. mm: x86: add CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG
> Materializing hardware optimizations when trying to clear the accessed
> bit in many PTEs. If hardware automatically sets the accessed bit in
> PTEs, there is no need to worry about bursty page faults (emulating
> the accessed bit). If it also sets the accessed bit in non-leaf PMD
> entries, there is no need to search the PTE table pointed to by a PMD
> entry that doesn't have the accessed bit set.
>
> 3. mm/vmscan.c: refactor shrink_node()
> A minor refactor.
>
> 4. mm: multigenerational lru: groundwork
> Adding the basic data structure and the functions to initialize it and
> insert/remove pages.
>
> 5. mm: multigenerational lru: mm_struct list
> An infra keeps track of mm_struct's for page table walkers and
> provides them with optimizations, i.e., switch_mm() tracking and Bloom
> filters.
>
> 6. mm: multigenerational lru: aging
> 7. mm: multigenerational lru: eviction
> "The page reclaim" is a producer/consumer model. "The aging" produces
> cold pages, whereas "the eviction " consumes them. Cold pages flow
> through generations. The aging uses the mm_struct list infra to sweep
> dense hotspots in page tables. During a page table walk, the aging
> clears the accessed bit and tags accessed pages with the youngest
> generation number. The eviction sorts those pages when it encounters
> them. For pages in the oldest generation, eviction walks the rmap to
> check the accessed bit one more time before evicting them. During an
> rmap walk, the eviction feeds dense hotspots back to the aging. Dense
> hotspots flow through the Bloom filters. For pages not mapped in page
> tables, the eviction uses the PID controller to statistically
> determine whether they have higher refaults. If so, the eviction
> throttles their eviction by moving them to the next generation (the
> second oldest).
>
> 8. mm: multigenerational lru: user interface
> The knobs to turn on/off MGLRU and provide the userspace with
> thrashing prevention, working set estimation (the aging) and proactive
> reclaim (the eviction).
>
> 9. mm: multigenerational lru: Kconfig
> The Kconfig options.
>
> Benchmark results
> =================
> Independent lab results
> -----------------------
> Based on the popularity of searches [01] and the memory usage in
> Google's public cloud, the most popular open-source memory-hungry
> applications, in alphabetical order, are:
>       Apache Cassandra      Memcached
>       Apache Hadoop         MongoDB
>       Apache Spark          PostgreSQL
>       MariaDB (MySQL)       Redis
>
> An independent lab evaluated MGLRU with the most widely used benchmark
> suites for the above applications. They posted 960 data points along
> with kernel metrics and perf profiles collected over more than 500
> hours of total benchmark time. Their final reports show that, with 95%
> confidence intervals (CIs), the above applications all performed
> significantly better for at least part of their benchmark matrices.
>
> On 5.14:
> 1. Apache Spark [02] took 95% CIs [9.28, 11.19]% and [12.20, 14.93]%
>    less wall time to sort three billion random integers, respectively,
>    under the medium- and the high-concurrency conditions, when
>    overcommitting memory. There were no statistically significant
>    changes in wall time for the rest of the benchmark matrix.
> 2. MariaDB [03] achieved 95% CIs [5.24, 10.71]% and [20.22, 25.97]%
>    more transactions per minute (TPM), respectively, under the medium-
>    and the high-concurrency conditions, when overcommitting memory.
>    There were no statistically significant changes in TPM for the rest
>    of the benchmark matrix.
> 3. Memcached [04] achieved 95% CIs [23.54, 32.25]%, [20.76, 41.61]%
>    and [21.59, 30.02]% more operations per second (OPS), respectively,
>    for sequential access, random access and Gaussian (distribution)
>    access, when THP=always; 95% CIs [13.85, 15.97]% and
>    [23.94, 29.92]% more OPS, respectively, for random access and
>    Gaussian access, when THP=never. There were no statistically
>    significant changes in OPS for the rest of the benchmark matrix.
> 4. MongoDB [05] achieved 95% CIs [2.23, 3.44]%, [6.97, 9.73]% and
>    [2.16, 3.55]% more operations per second (OPS), respectively, for
>    exponential (distribution) access, random access and Zipfian
>    (distribution) access, when underutilizing memory; 95% CIs
>    [8.83, 10.03]%, [21.12, 23.14]% and [5.53, 6.46]% more OPS,
>    respectively, for exponential access, random access and Zipfian
>    access, when overcommitting memory.
>
> On 5.15:
> 5. Apache Cassandra [06] achieved 95% CIs [1.06, 4.10]%, [1.94, 5.43]%
>    and [4.11, 7.50]% more operations per second (OPS), respectively,
>    for exponential (distribution) access, random access and Zipfian
>    (distribution) access, when swap was off; 95% CIs [0.50, 2.60]%,
>    [6.51, 8.77]% and [3.29, 6.75]% more OPS, respectively, for
>    exponential access, random access and Zipfian access, when swap was
>    on.
> 6. Apache Hadoop [07] took 95% CIs [5.31, 9.69]% and [2.02, 7.86]%
>    less average wall time to finish twelve parallel TeraSort jobs,
>    respectively, under the medium- and the high-concurrency
>    conditions, when swap was on. There were no statistically
>    significant changes in average wall time for the rest of the
>    benchmark matrix.
> 7. PostgreSQL [08] achieved 95% CI [1.75, 6.42]% more transactions per
>    minute (TPM) under the high-concurrency condition, when swap was
>    off; 95% CIs [12.82, 18.69]% and [22.70, 46.86]% more TPM,
>    respectively, under the medium- and the high-concurrency
>    conditions, when swap was on. There were no statistically
>    significant changes in TPM for the rest of the benchmark matrix.
> 8. Redis [09] achieved 95% CIs [0.58, 5.94]%, [6.55, 14.58]% and
>    [11.47, 19.36]% more total operations per second (OPS),
>    respectively, for sequential access, random access and Gaussian
>    (distribution) access, when THP=always; 95% CIs [1.27, 3.54]%,
>    [10.11, 14.81]% and [8.75, 13.64]% more total OPS, respectively,
>    for sequential access, random access and Gaussian access, when
>    THP=never.
>
> Our lab results
> ---------------
> To supplement the above results, we ran the following benchmark suites
> on 5.16-rc7 and found no regressions [10]. (These synthetic benchmarks
> are popular among MM developers, but we prefer large-scale A/B
> experiments to validate improvements.)
>       fs_fio_bench_hdd_mq      pft
>       fs_lmbench               pgsql-hammerdb
>       fs_parallelio            redis
>       fs_postmark              stream
>       hackbench                sysbenchthread
>       kernbench                tpcc_spark
>       memcached                unixbench
>       multichase               vm-scalability
>       mutilate                 will-it-scale
>       nginx
>
> [01] https://trends.google.com
> [02] https://lore.kernel.org/linux-mm/20211102002002.92051-1-bot at edi.works/
> [03] https://lore.kernel.org/linux-mm/20211009054315.47073-1-bot at edi.works/
> [04] https://lore.kernel.org/linux-mm/20211021194103.65648-1-bot at edi.works/
> [05] https://lore.kernel.org/linux-mm/20211109021346.50266-1-bot at edi.works/
> [06] https://lore.kernel.org/linux-mm/20211202062806.80365-1-bot at edi.works/
> [07] https://lore.kernel.org/linux-mm/20211209072416.33606-1-bot at edi.works/
> [08] https://lore.kernel.org/linux-mm/20211218071041.24077-1-bot at edi.works/
> [09] https://lore.kernel.org/linux-mm/20211122053248.57311-1-bot at edi.works/
> [10] https://lore.kernel.org/linux-mm/20220104202247.2903702-1-yuzhao at google.com/
>
> Read-world applications
> =======================
> Third-party testimonials
> ------------------------
> Konstantin wrote [11]:
>    I have Archlinux with 8G RAM + zswap + swap. While developing, I
>    have lots of apps opened such as multiple LSP-servers for different
>    langs, chats, two browsers, etc... Usually, my system gets quickly
>    to a point of SWAP-storms, where I have to kill LSP-servers,
>    restart browsers to free memory, etc, otherwise the system lags
>    heavily and is barely usable.
>
>    1.5 day ago I migrated from 5.11.15 kernel to 5.12 + the LRU
>    patchset, and I started up by opening lots of apps to create memory
>    pressure, and worked for a day like this. Till now I had *not a
>    single SWAP-storm*, and mind you I got 3.4G in SWAP. I was never
>    getting to the point of 3G in SWAP before without a single
>    SWAP-storm.
>
> The Arch Linux Zen kernel [12] has been using MGLRU since 5.12. Many
> of its users reported their positive experiences to me, e.g., Shivodit
> wrote:
>    I've tried the latest Zen kernel (5.14.13-zen1-1-zen in the
>    archlinux testing repos), everything's been smooth so far. I also
>    decided to copy a large volume of files to check performance under
>    I/O load, and everything went smoothly - no stuttering was present,
>    everything was responsive.
>
> Large-scale deployments
> -----------------------
> We've rolled out MGLRU to tens of millions of Chrome OS users and
> about a million Android users. Google's fleetwide profiling [13] shows
> an overall 40% decrease in kswapd CPU usage, in addition to

Hi Yu,

Was the overall 40% decrease of kswap CPU usgae seen on x86 or arm64?
And I am curious how much we are taking advantage of NONLEAF_PMD_YOUNG.
Does it help a lot in decreasing the cpu usage? If so, this might be
a good proof that arm64 also needs this hardware feature?
In short, I am curious how much the improvement in this patchset depends
on the hardware ability of NONLEAF_PMD_YOUNG.

> improvements in other UX metrics, e.g., an 85% decrease in the number
> of low-memory kills at the 75th percentile and an 18% decrease in
> rendering latency at the 50th percentile.
>
> [11] https://lore.kernel.org/linux-mm/140226722f2032c86301fbd326d91baefe3d7d23.camel at yandex.ru/
> [12] https://github.com/zen-kernel/zen-kernel/
> [13] https://research.google/pubs/pub44271/
>

Thanks
Barry


From harsha.harsha at xilinx.com  Sun Jan 23 01:47:03 2022
From: harsha.harsha at xilinx.com (Harsha)
Date: Sun, 23 Jan 2022 15:17:03 +0530
Subject: [PATCH 0/4] crypto: Add Xilinx ZynqMP SHA3 driver support
Message-ID: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>

This patch set does the following:
  - Updates the Makefile for xilinx subdirectory
  - Adds communication layer support for sha_hash in zynqmp.c
  - Adds Xilinx ZynqMP driver for SHA3 Algorithm
  - Updates the list of MAINTAINERS

Harsha (4):
  drivers: crypto: Updated Makefile for xilinx subdirectory
  firmware: xilinx: Add ZynqMP SHA API for SHA3 functionality
  crypto: xilinx: Add Xilinx SHA3 driver
  MAINTAINERS: Add maintainer for Xilinx ZynqMP SHA3 driver

 MAINTAINERS                          |   5 +
 drivers/crypto/Kconfig               |  10 ++
 drivers/crypto/Makefile              |   2 +-
 drivers/crypto/xilinx/Makefile       |   1 +
 drivers/crypto/xilinx/zynqmp-sha.c   | 285 +++++++++++++++++++++++++++++++++++
 drivers/firmware/xilinx/zynqmp.c     |  26 ++++
 include/linux/firmware/xlnx-zynqmp.h |   8 +
 7 files changed, 336 insertions(+), 1 deletion(-)
 create mode 100644 drivers/crypto/xilinx/zynqmp-sha.c

-- 
1.8.2.1



From harsha.harsha at xilinx.com  Sun Jan 23 01:47:04 2022
From: harsha.harsha at xilinx.com (Harsha)
Date: Sun, 23 Jan 2022 15:17:04 +0530
Subject: [PATCH 1/4] drivers: crypto: Updated Makefile for xilinx subdirectory
In-Reply-To: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
References: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
Message-ID: <1642931227-20706-2-git-send-email-harsha.harsha@xilinx.com>

This patch updates the Makefile for xilinx subdirectory.
CONFIG_CRYPTO_DEV_ZYNQMP_AES protects zynqmp-aes-gcm.o and it is used
twice (in drivers/crypto/Makefile and drivers/crypto/xilinx/Makefile)
and it is enough to use it once.

Signed-off-by: Harsha <harsha.harsha at xilinx.com>
Reviewed-by: Michal Simek <michal.simek at xilinx.com>
---
 drivers/crypto/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 1fe5120..0a4fff2 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -47,7 +47,7 @@ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/
 obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
 obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
 obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
-obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += xilinx/
+obj-y += xilinx/
 obj-y += hisilicon/
 obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
 obj-y += keembay/
-- 
1.8.2.1



From harsha.harsha at xilinx.com  Sun Jan 23 01:47:05 2022
From: harsha.harsha at xilinx.com (Harsha)
Date: Sun, 23 Jan 2022 15:17:05 +0530
Subject: [PATCH 2/4] firmware: xilinx: Add ZynqMP SHA API for SHA3
 functionality
In-Reply-To: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
References: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
Message-ID: <1642931227-20706-3-git-send-email-harsha.harsha@xilinx.com>

This patch adds zynqmp_pm_sha_hash API in the ZynqMP firmware to compute
SHA3 hash of given data.

Signed-off-by: Harsha <harsha.harsha at xilinx.com>
---
 drivers/firmware/xilinx/zynqmp.c     | 26 ++++++++++++++++++++++++++
 include/linux/firmware/xlnx-zynqmp.h |  8 ++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c
index 3dd45a7..a84c5ea 100644
--- a/drivers/firmware/xilinx/zynqmp.c
+++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1117,6 +1117,32 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)
 EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);
 
 /**
+ * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash
+ * @address:	Address of the data/ Address of output buffer where
+ *		hash should be stored.
+ * @size:	Size of the data.
+ * @flags:
+ *	BIT(0) - for initializing csudma driver and SHA3(Here address
+ *		 and size inputs can be NULL).
+ *	BIT(1) - to call Sha3_Update API which can be called multiple
+ *		 times when data is not contiguous.
+ *	BIT(2) - to get final hash of the whole updated data.
+ *		 Hash will be overwritten at provided address with
+ *		 48 bytes.
+ *
+ * Return:	Returns status, either success or error code.
+ */
+int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags)
+{
+	u32 lower_addr = lower_32_bits(address);
+	u32 upper_addr = upper_32_bits(address);
+
+	return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_addr, lower_addr,
+				   size, flags, NULL);
+}
+EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash);
+
+/**
  * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart
  * @type:	Shutdown or restart? 0 for shutdown, 1 for restart
  * @subtype:	Specifies which system should be restarted or shut down
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h
index 47fd4e5..38ef708 100644
--- a/include/linux/firmware/xlnx-zynqmp.h
+++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -78,6 +78,7 @@ enum pm_api_id {
 	PM_FPGA_LOAD = 22,
 	PM_FPGA_GET_STATUS = 23,
 	PM_GET_CHIPID = 24,
+	PM_SECURE_SHA = 26,
 	PM_PINCTRL_REQUEST = 28,
 	PM_PINCTRL_RELEASE = 29,
 	PM_PINCTRL_GET_FUNCTION = 30,
@@ -410,6 +411,7 @@ int zynqmp_pm_set_requirement(const u32 node, const u32 capabilities,
 			      const u32 qos,
 			      const enum zynqmp_pm_request_ack ack);
 int zynqmp_pm_aes_engine(const u64 address, u32 *out);
+int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags);
 int zynqmp_pm_fpga_load(const u64 address, const u32 size, const u32 flags);
 int zynqmp_pm_fpga_get_status(u32 *value);
 int zynqmp_pm_write_ggs(u32 index, u32 value);
@@ -581,6 +583,12 @@ static inline int zynqmp_pm_aes_engine(const u64 address, u32 *out)
 	return -ENODEV;
 }
 
+static inline int zynqmp_pm_sha_hash(const u64 address, const u32 size,
+				     const u32 flags)
+{
+	return -ENODEV;
+}
+
 static inline int zynqmp_pm_fpga_load(const u64 address, const u32 size,
 				      const u32 flags)
 {
-- 
1.8.2.1



From harsha.harsha at xilinx.com  Sun Jan 23 01:47:06 2022
From: harsha.harsha at xilinx.com (Harsha)
Date: Sun, 23 Jan 2022 15:17:06 +0530
Subject: [PATCH 3/4] crypto: xilinx: Add Xilinx SHA3 driver
In-Reply-To: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
References: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
Message-ID: <1642931227-20706-4-git-send-email-harsha.harsha@xilinx.com>

This patch adds SHA3 driver support for the Xilinx ZynqMP SoC.
Xilinx ZynqMP SoC has SHA3 engine used for secure hash calculation.
The flow is
SHA3 request from Userspace -> SHA3 driver-> ZynqMp driver-> Firmware ->
SHA3 HW Engine

SHA3 HW engine in Xilinx ZynqMP SoC, does not support parallel processing
of 2 hash requests.
Therefore, software fallback is being used for init, update, final,
export and import in the ZynqMP SHA driver
For digest, the calculation of SHA3 hash is done by the hardened
SHA3 accelerator in Xilinx ZynqMP SoC.

Signed-off-by: Harsha <harsha.harsha at xilinx.com>
---
 drivers/crypto/Kconfig             |  10 ++
 drivers/crypto/xilinx/Makefile     |   1 +
 drivers/crypto/xilinx/zynqmp-sha.c | 285 +++++++++++++++++++++++++++++++++++++
 3 files changed, 296 insertions(+)
 create mode 100644 drivers/crypto/xilinx/zynqmp-sha.c

diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 51690e7..2e43f11 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -796,6 +796,16 @@ config CRYPTO_DEV_ZYNQMP_AES
 	  accelerator. Select this if you want to use the ZynqMP module
 	  for AES algorithms.
 
+config CRYPTO_DEV_ZYNQMP_SHA3
+	bool "Support for Xilinx ZynqMP SHA3 hardware accelerator"
+	depends on ARCH_ZYNQMP || COMPILE_TEST
+	select CRYPTO_SHA3
+	help
+	  Xilinx ZynqMP has SHA3 engine used for secure hash calculation.
+	  This driver interfaces with SHA3 hardware engine.
+	  Select this if you want to use the ZynqMP module
+	  for SHA3 hash computation.
+
 source "drivers/crypto/chelsio/Kconfig"
 
 source "drivers/crypto/virtio/Kconfig"
diff --git a/drivers/crypto/xilinx/Makefile b/drivers/crypto/xilinx/Makefile
index 534e32d..730feff 100644
--- a/drivers/crypto/xilinx/Makefile
+++ b/drivers/crypto/xilinx/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_AES) += zynqmp-aes-gcm.o
+obj-$(CONFIG_CRYPTO_DEV_ZYNQMP_SHA3) += zynqmp-sha.o
diff --git a/drivers/crypto/xilinx/zynqmp-sha.c b/drivers/crypto/xilinx/zynqmp-sha.c
new file mode 100644
index 0000000..11f103c
--- /dev/null
+++ b/drivers/crypto/xilinx/zynqmp-sha.c
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx ZynqMP SHA Driver.
+ * Copyright (c) 2022 Xilinx Inc.
+ */
+#include <asm/cacheflush.h>
+#include <crypto/hash.h>
+#include <crypto/internal/hash.h>
+#include <crypto/sha3.h>
+#include <linux/crypto.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#define ZYNQMP_DMA_BIT_MASK		32U
+#define ZYNQMP_DMA_ALLOC_FIXED_SIZE	0x1000U
+
+enum zynqmp_sha_op {
+	ZYNQMP_SHA3_INIT = 1,
+	ZYNQMP_SHA3_UPDATE = 2,
+	ZYNQMP_SHA3_FINAL = 4,
+};
+
+struct zynqmp_sha_drv_ctx {
+	struct shash_alg sha3_384;
+	struct device *dev;
+};
+
+struct zynqmp_sha_tfm_ctx {
+	struct device *dev;
+	struct crypto_shash *fbk_tfm;
+};
+
+struct zynqmp_sha_desc_ctx {
+	struct shash_desc fbk_req;
+};
+
+static dma_addr_t update_dma_addr, final_dma_addr;
+static char *ubuf, *fbuf;
+
+static int zynqmp_sha_init_tfm(struct crypto_shash *hash)
+{
+	const char *fallback_driver_name = crypto_shash_alg_name(hash);
+	struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);
+	struct shash_alg *alg = crypto_shash_alg(hash);
+	struct crypto_shash *fallback_tfm;
+	struct zynqmp_sha_drv_ctx *drv_ctx;
+
+	drv_ctx = container_of(alg, struct zynqmp_sha_drv_ctx, sha3_384);
+	tfm_ctx->dev = drv_ctx->dev;
+
+	/* Allocate a fallback and abort if it failed. */
+	fallback_tfm = crypto_alloc_shash(fallback_driver_name, 0,
+					  CRYPTO_ALG_NEED_FALLBACK);
+	if (IS_ERR(fallback_tfm))
+		return PTR_ERR(fallback_tfm);
+
+	tfm_ctx->fbk_tfm = fallback_tfm;
+	hash->descsize += crypto_shash_descsize(tfm_ctx->fbk_tfm);
+
+	return 0;
+}
+
+static void zynqmp_sha_exit_tfm(struct crypto_shash *hash)
+{
+	struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);
+
+	if (tfm_ctx->fbk_tfm) {
+		crypto_free_shash(tfm_ctx->fbk_tfm);
+		tfm_ctx->fbk_tfm = NULL;
+	}
+
+	memzero_explicit(tfm_ctx, sizeof(struct zynqmp_sha_tfm_ctx));
+}
+
+static int zynqmp_sha_init(struct shash_desc *desc)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+
+	dctx->fbk_req.tfm = tctx->fbk_tfm;
+	return crypto_shash_init(&dctx->fbk_req);
+}
+
+static int zynqmp_sha_update(struct shash_desc *desc, const u8 *data, unsigned int length)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	return crypto_shash_update(&dctx->fbk_req, data, length);
+}
+
+static int zynqmp_sha_final(struct shash_desc *desc, u8 *out)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	return crypto_shash_final(&dctx->fbk_req, out);
+}
+
+static int zynqmp_sha_finup(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	return crypto_shash_finup(&dctx->fbk_req, data, length, out);
+}
+
+static int zynqmp_sha_import(struct shash_desc *desc, const void *in)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+
+	dctx->fbk_req.tfm = tctx->fbk_tfm;
+	return crypto_shash_import(&dctx->fbk_req, in);
+}
+
+static int zynqmp_sha_export(struct shash_desc *desc, void *out)
+{
+	struct zynqmp_sha_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	return crypto_shash_export(&dctx->fbk_req, out);
+}
+
+static int zynqmp_sha_digest(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out)
+{
+	unsigned int remaining_len = len;
+	int update_size;
+	int ret;
+
+	ret = zynqmp_pm_sha_hash(0, 0, ZYNQMP_SHA3_INIT);
+	if (ret)
+		return ret;
+
+	while (remaining_len != 0) {
+		memset(ubuf, 0, ZYNQMP_DMA_ALLOC_FIXED_SIZE);
+		if (remaining_len >= ZYNQMP_DMA_ALLOC_FIXED_SIZE) {
+			update_size = ZYNQMP_DMA_ALLOC_FIXED_SIZE;
+			remaining_len -= ZYNQMP_DMA_ALLOC_FIXED_SIZE;
+		} else {
+			update_size = remaining_len;
+			remaining_len = 0;
+		}
+		memcpy(ubuf, data, update_size);
+		flush_icache_range((unsigned long)ubuf, (unsigned long)ubuf + update_size);
+		ret = zynqmp_pm_sha_hash(update_dma_addr, update_size, ZYNQMP_SHA3_UPDATE);
+		if (ret)
+			return ret;
+
+		data += update_size;
+	}
+
+	ret = zynqmp_pm_sha_hash(final_dma_addr, SHA3_384_DIGEST_SIZE, ZYNQMP_SHA3_FINAL);
+	memcpy(out, fbuf, SHA3_384_DIGEST_SIZE);
+	memset(fbuf, 0, SHA3_384_DIGEST_SIZE);
+
+	return ret;
+}
+
+static struct zynqmp_sha_drv_ctx sha3_drv_ctx = {
+	.sha3_384 = {
+		.init = zynqmp_sha_init,
+		.update = zynqmp_sha_update,
+		.final = zynqmp_sha_final,
+		.finup = zynqmp_sha_finup,
+		.digest = zynqmp_sha_digest,
+		.export = zynqmp_sha_export,
+		.import = zynqmp_sha_import,
+		.init_tfm = zynqmp_sha_init_tfm,
+		.exit_tfm = zynqmp_sha_exit_tfm,
+		.descsize = sizeof(struct zynqmp_sha_desc_ctx),
+		.statesize = sizeof(struct sha3_state),
+		.digestsize = SHA3_384_DIGEST_SIZE,
+		.base = {
+			.cra_name = "sha3-384",
+			.cra_driver_name = "zynqmp-sha3-384",
+			.cra_priority = 300,
+			.cra_flags = CRYPTO_ALG_KERN_DRIVER_ONLY |
+				     CRYPTO_ALG_ALLOCATES_MEMORY |
+				     CRYPTO_ALG_NEED_FALLBACK,
+			.cra_blocksize = SHA3_384_BLOCK_SIZE,
+			.cra_ctxsize = sizeof(struct zynqmp_sha_tfm_ctx),
+			.cra_alignmask = 3,
+			.cra_module = THIS_MODULE,
+		}
+	}
+};
+
+static int zynqmp_sha_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	int err;
+
+	err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(ZYNQMP_DMA_BIT_MASK));
+	if (err < 0) {
+		dev_err(dev, "No usable DMA configuration\n");
+		return err;
+	}
+
+	err = crypto_register_shash(&sha3_drv_ctx.sha3_384);
+	if (err < 0) {
+		dev_err(dev, "Failed to register shash alg.\n");
+		return err;
+	}
+
+	sha3_drv_ctx.dev = dev;
+	platform_set_drvdata(pdev, &sha3_drv_ctx);
+
+	ubuf = dma_alloc_coherent(dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, &update_dma_addr, GFP_KERNEL);
+	if (!ubuf) {
+		err = -ENOMEM;
+		goto err_shash;
+	}
+
+	fbuf = dma_alloc_coherent(dev, SHA3_384_DIGEST_SIZE, &final_dma_addr, GFP_KERNEL);
+	if (!fbuf) {
+		err = -ENOMEM;
+		goto err_mem;
+	}
+
+	return 0;
+
+err_mem:
+	dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr);
+
+err_shash:
+	crypto_unregister_shash(&sha3_drv_ctx.sha3_384);
+
+	return err;
+}
+
+static int zynqmp_sha_remove(struct platform_device *pdev)
+{
+	sha3_drv_ctx.dev = platform_get_drvdata(pdev);
+
+	dma_free_coherent(sha3_drv_ctx.dev, ZYNQMP_DMA_ALLOC_FIXED_SIZE, ubuf, update_dma_addr);
+	dma_free_coherent(sha3_drv_ctx.dev, SHA3_384_DIGEST_SIZE, fbuf, final_dma_addr);
+	crypto_unregister_shash(&sha3_drv_ctx.sha3_384);
+
+	return 0;
+}
+
+static struct platform_driver zynqmp_sha_driver = {
+	.probe = zynqmp_sha_probe,
+	.remove = zynqmp_sha_remove,
+	.driver = {
+		.name = "zynqmp-sha3-384",
+	},
+};
+
+static int __init sha_driver_init(void)
+{
+	struct platform_device *pdev;
+	int ret;
+
+	ret = platform_driver_register(&zynqmp_sha_driver);
+	if (ret)
+		return ret;
+
+	pdev = platform_device_register_simple(zynqmp_sha_driver.driver.name,
+					       0, NULL, 0);
+	if (IS_ERR(pdev)) {
+		ret = PTR_ERR(pdev);
+		platform_driver_unregister(&zynqmp_sha_driver);
+		pr_info("Failed to register ZynqMP SHA3 dvixe %d\n", ret);
+	}
+
+	return ret;
+}
+
+device_initcall(sha_driver_init);
+
+static void __exit sha_driver_exit(void)
+{
+	platform_driver_unregister(&zynqmp_sha_driver);
+}
+
+module_platform_driver(zynqmp_sha_driver);
+
+MODULE_DESCRIPTION("ZynqMP SHA3 hardware acceleration support.");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Harsha <harsha.harsha at xilinx.com>");
-- 
1.8.2.1



From harsha.harsha at xilinx.com  Sun Jan 23 01:47:07 2022
From: harsha.harsha at xilinx.com (Harsha)
Date: Sun, 23 Jan 2022 15:17:07 +0530
Subject: [PATCH 4/4] MAINTAINERS: Add maintainer for Xilinx ZynqMP SHA3 driver
In-Reply-To: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
References: <1642931227-20706-1-git-send-email-harsha.harsha@xilinx.com>
Message-ID: <1642931227-20706-5-git-send-email-harsha.harsha@xilinx.com>

This patch adds an entry for ZynqMP SHA3 driver in the list of
Maintainers.

Signed-off-by: Harsha <harsha.harsha at xilinx.com>
---
 MAINTAINERS | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 4fb3a88..cf2da60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20931,6 +20931,11 @@ T:	git https://github.com/Xilinx/linux-xlnx.git
 F:	Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
 F:	drivers/phy/xilinx/phy-zynqmp.c
 
+XILINX ZYNQMP SHA3 DRIVER
+M:	Harsha <harsha.harsha at xilinx.com>
+S:	Maintained
+F:	drivers/crypto/xilinx/zynqmp-sha.c
+
 XILLYBUS DRIVER
 M:	Eli Billauer <eli.billauer at gmail.com>
 L:	linux-kernel at vger.kernel.org
-- 
1.8.2.1



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:36 +0100
Subject: [PATCH 04/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook
 Snow
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-5-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5250
Chromebook Snow board.  Due to lack of board schematics, use same
regulators as on Arndale board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250-snow-common.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250-snow-common.dtsi b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
index 2335c4687349..ccb32d53d598 100644
--- a/arch/arm/boot/dts/exynos5250-snow-common.dtsi
+++ b/arch/arm/boot/dts/exynos5250-snow-common.dtsi
@@ -698,6 +698,11 @@ &spi_1 {
 	cs-gpios = <&gpa2 5 GPIO_ACTIVE_HIGH>;
 };
 
+&usbdrd {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
 &usbdrd_dwc3 {
 	dr_mode = "host";
 };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:34 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:34 +0100
Subject: [PATCH 02/12] ARM: dts: exynos: add USB DWC3 supplies to Arndale
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-3-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5250 Arndale
board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250-arndale.dts | 5 +++++
 arch/arm/boot/dts/exynos5250.dtsi        | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
index 3583095fbb2a..e639cf6d9b64 100644
--- a/arch/arm/boot/dts/exynos5250-arndale.dts
+++ b/arch/arm/boot/dts/exynos5250-arndale.dts
@@ -632,3 +632,8 @@ i2c_ddc: i2c-10 {
 		#size-cells = <0>;
 	};
 };
+
+&usbdrd {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 139778928b93..a6f48f31f618 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -637,7 +637,7 @@ i2s2: i2s at 12d70000 {
 			#sound-dai-cells = <1>;
 		};
 
-		usb_dwc3 {
+		usbdrd: usb3 {
 			compatible = "samsung,exynos5250-dwusb3";
 			clocks = <&clock CLK_USB3>;
 			clock-names = "usbdrd30";
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:37 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:37 +0100
Subject: [PATCH 05/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook
 Spring
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-6-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5250
Chromebook Spring board.  Due to lack of board schematics, use same
regulators as on Arndale board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250-spring.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250-spring.dts b/arch/arm/boot/dts/exynos5250-spring.dts
index e0feedcf54bb..138f51f974c7 100644
--- a/arch/arm/boot/dts/exynos5250-spring.dts
+++ b/arch/arm/boot/dts/exynos5250-spring.dts
@@ -553,4 +553,9 @@ &spi_1 {
 	num-cs = <1>;
 };
 
+&usbdrd {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
 #include "cros-ec-keyboard.dtsi"
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:32 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:32 +0100
Subject: [PATCH 00/12] usb: dt-bindings: samsung: convert to dtschema
Message-ID: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>

Hi,

Dependencies
============
None.

The DTS patches are independent and I will take them via Samsung SoC tree.
I am including them here just so automatic robot checks won't complain about
DTS differences against newly dtschema.

Best regards,
Krzysztof

Krzysztof Kozlowski (12):
  arm64: dts: exynos: add USB DWC3 supplies to Espresso board
  ARM: dts: exynos: add USB DWC3 supplies to Arndale
  ARM: dts: exynos: add USB DWC3 supplies to SMDK5250
  ARM: dts: exynos: add USB DWC3 supplies to Chromebook Snow
  ARM: dts: exynos: add USB DWC3 supplies to Chromebook Spring
  ARM: dts: exynos: add USB DWC3 supplies to ArndaleOcta
  ARM: dts: exynos: add USB DWC3 supplies to Chromebook Peach Pit
  ARM: dts: exynos: add USB DWC3 supplies to Chromebook Peach Pi
  ARM: dts: exynos: add USB DWC3 supplies to SMDK5420
  ARM: dts: exynos: add fake USB DWC3 supplies to SMDK5410
  dt-bindings: usb: samsung,exynos-dwc3: convert to dtschema
  dt-bindings: usb: samsung,exynos-usb2: convert to dtschema

 .../devicetree/bindings/usb/exynos-usb.txt    | 115 ----------------
 .../bindings/usb/samsung,exynos-dwc3.yaml     | 129 ++++++++++++++++++
 .../bindings/usb/samsung,exynos-usb2.yaml     | 117 ++++++++++++++++
 arch/arm/boot/dts/exynos5250-arndale.dts      |   5 +
 arch/arm/boot/dts/exynos5250-smdk5250.dts     |   5 +
 arch/arm/boot/dts/exynos5250-snow-common.dtsi |   5 +
 arch/arm/boot/dts/exynos5250-spring.dts       |   5 +
 arch/arm/boot/dts/exynos5250.dtsi             |   2 +-
 arch/arm/boot/dts/exynos5410-smdk5410.dts     |  23 ++++
 arch/arm/boot/dts/exynos5420-arndale-octa.dts |  10 ++
 arch/arm/boot/dts/exynos5420-peach-pit.dts    |  10 ++
 arch/arm/boot/dts/exynos5420-smdk5420.dts     |  10 ++
 arch/arm/boot/dts/exynos5800-peach-pi.dts     |  10 ++
 .../boot/dts/exynos/exynos7-espresso.dts      |   5 +
 arch/arm64/boot/dts/exynos/exynos7.dtsi       |   2 +-
 15 files changed, 336 insertions(+), 117 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/usb/exynos-usb.txt
 create mode 100644 Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml
 create mode 100644 Documentation/devicetree/bindings/usb/samsung,exynos-usb2.yaml

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:33 +0100
Subject: [PATCH 01/12] arm64: dts: exynos: add USB DWC3 supplies to Espresso
 board
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-2-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos7 Espresso
board.  Due to lack of schematics of Espresso board, the choice of
regulators is approximate.  What bindings call VDD10, for Exynos7 should
be actually called VDD09 (0.9 V).  Use regulators with a matching
voltage range based on vendor sources for Meizu Pro 5 M576 handset (also
with Exynos7420).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos7-espresso.dts | 5 +++++
 arch/arm64/boot/dts/exynos/exynos7.dtsi         | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
index 125c03f351d9..4c45e689d34a 100644
--- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
+++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
@@ -412,6 +412,11 @@ &ufs {
 	status = "okay";
 };
 
+&usbdrd {
+	vdd10-supply = <&ldo4_reg>;
+	vdd33-supply = <&ldo6_reg>;
+};
+
 &usbdrd_phy {
 	vbus-supply = <&usb30_vbus_reg>;
 	vbus-boost-supply = <&usb3drd_boost_5v>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index c3efbc8add38..01b4210d8b62 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -672,7 +672,7 @@ usbdrd_phy: phy at 15500000 {
 			#phy-cells = <1>;
 		};
 
-		usbdrd3 {
+		usbdrd: usb {
 			compatible = "samsung,exynos7-dwusb3";
 			clocks = <&clock_fsys0 ACLK_USBDRD300>,
 			       <&clock_fsys0 SCLK_USBDRD300_SUSPENDCLK>,
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:35 +0100
Subject: [PATCH 03/12] ARM: dts: exynos: add USB DWC3 supplies to SMDK5250
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-4-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5250
SMDK5250 board.  Due to lack of board schematics, use same regulators as
on Arndale board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5250-smdk5250.dts | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts
index 39bbe18145cf..53670383d607 100644
--- a/arch/arm/boot/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts
@@ -417,3 +417,8 @@ max77686_irq: max77686-irq {
 		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
 	};
 };
+
+&usbdrd {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:38 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:38 +0100
Subject: [PATCH 06/12] ARM: dts: exynos: add USB DWC3 supplies to ArndaleOcta
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-7-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5420
ArndaleOcta board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5420-arndale-octa.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index dfc7f14f5772..ffdf0e247c15 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -825,3 +825,13 @@ &rtc {
 &usbdrd_dwc3_1 {
 	dr_mode = "host";
 };
+
+&usbdrd3_0 {
+	vdd10-supply = <&ldo11_reg>;
+	vdd33-supply = <&ldo9_reg>;
+};
+
+&usbdrd3_1 {
+	vdd10-supply = <&ldo11_reg>;
+	vdd33-supply = <&ldo9_reg>;
+};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:39 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:39 +0100
Subject: [PATCH 07/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook
 Peach Pit
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-8-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5420
Chromebook Peach Pit board.  Due to lack of board schematics, use same
regulators as on Odroid XU board (using same MAX77802 PMIC).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5420-peach-pit.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index e76fb104db19..6252089e4350 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -1090,6 +1090,16 @@ &tmu_gpu {
 	vtmu-supply = <&ldo10_reg>;
 };
 
+&usbdrd3_0 {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
+&usbdrd3_1 {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
 &usbdrd_dwc3_0 {
 	dr_mode = "host";
 };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:40 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:40 +0100
Subject: [PATCH 08/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook
 Peach Pi
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-9-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5800
Chromebook Peach Pi board.  Due to lack of board schematics, use same
regulators as on Odroid XU board (using same MAX77802 PMIC).

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5800-peach-pi.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index 77013ee586f8..fd6f80a9c64e 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -1072,6 +1072,16 @@ &tmu_gpu {
 	vtmu-supply = <&ldo10_reg>;
 };
 
+&usbdrd3_0 {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
+&usbdrd3_1 {
+	vdd10-supply = <&ldo15_reg>;
+	vdd33-supply = <&ldo12_reg>;
+};
+
 &usbdrd_dwc3_0 {
 	dr_mode = "host";
 };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:41 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:41 +0100
Subject: [PATCH 09/12] ARM: dts: exynos: add USB DWC3 supplies to SMDK5420
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-10-krzysztof.kozlowski@canonical.com>

Add required voltage regulators for USB DWC3 block on Exynos5420
SMDK5420 board.  Due to lack of board schematics, use same
regulators as on ArndaleOcta board.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5420-smdk5420.dts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts
index a4f0e3ffedbd..69ce3e430863 100644
--- a/arch/arm/boot/dts/exynos5420-smdk5420.dts
+++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts
@@ -407,6 +407,16 @@ &rtc {
 	clock-names = "rtc", "rtc_src";
 };
 
+&usbdrd3_0 {
+	vdd10-supply = <&ldo11_reg>;
+	vdd33-supply = <&ldo9_reg>;
+};
+
+&usbdrd3_1 {
+	vdd10-supply = <&ldo11_reg>;
+	vdd33-supply = <&ldo9_reg>;
+};
+
 &usbdrd_phy0 {
 	vbus-supply = <&usb300_vbus_reg>;
 };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:42 +0100
Subject: [PATCH 10/12] ARM: dts: exynos: add fake USB DWC3 supplies to SMDK5410
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-11-krzysztof.kozlowski@canonical.com>

Add dummy/fake voltage regulators for USB DWC3 block on Exynos5410
SMDK5410 board.  These regulators are required by dtschema, however the
SMDK5410 board does not define the PMIC providing regulators.  Use dummy
fixed-regulators just to satisfy the dtschema checks.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm/boot/dts/exynos5410-smdk5410.dts | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts
index 2a3ade77a2de..eae69e857247 100644
--- a/arch/arm/boot/dts/exynos5410-smdk5410.dts
+++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts
@@ -41,6 +41,19 @@ firmware at 2037000 {
 		reg = <0x02037000 0x1000>;
 	};
 
+	vdd10_usb3: voltage-regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD10_USB3";
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+	};
+
+	vdd33_usb3: voltage-regulator-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "VDD33_USB3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
 };
 
 &mmc_0 {
@@ -121,3 +134,13 @@ &serial_1 {
 &serial_2 {
 	status = "okay";
 };
+
+&usbdrd3_0 {
+	vdd10-supply = <&vdd10_usb3>;
+	vdd33-supply = <&vdd33_usb3>;
+};
+
+&usbdrd3_1 {
+	vdd10-supply = <&vdd10_usb3>;
+	vdd33-supply = <&vdd33_usb3>;
+};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:44 +0100
Subject: [PATCH 12/12] dt-bindings: usb: samsung,
 exynos-usb2: convert to dtschema
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-13-krzysztof.kozlowski@canonical.com>

Convert the Samsung Exynos SoC USB 2.0 EHCI and OHCI Controller bindings
to DT schema format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/usb/exynos-usb.txt    |  66 ----------
 .../bindings/usb/samsung,exynos-usb2.yaml     | 117 ++++++++++++++++++
 2 files changed, 117 insertions(+), 66 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/usb/exynos-usb.txt
 create mode 100644 Documentation/devicetree/bindings/usb/samsung,exynos-usb2.yaml

diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
deleted file mode 100644
index 61c03c0ef19f..000000000000
--- a/Documentation/devicetree/bindings/usb/exynos-usb.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-Samsung Exynos SoC USB controller
-
-The USB devices interface with USB controllers on Exynos SOCs.
-The device node has following properties.
-
-EHCI
-Required properties:
- - compatible: should be "samsung,exynos4210-ehci" for USB 2.0
-   EHCI controller in host mode.
- - reg: physical base address of the controller and length of memory mapped
-   region.
- - interrupts: interrupt number to the cpu.
- - clocks: from common clock binding: handle to usb clock.
- - clock-names: from common clock binding: Shall be "usbhost".
- - phys: from the *Generic PHY* bindings; array specifying phy(s) used
-   by the root port.
- - phy-names: from the *Generic PHY* bindings; array of the names for
-   each phy for the root ports, must be a subset of the following:
-   "host", "hsic0", "hsic1".
-
-Optional properties:
- - samsung,vbus-gpio:  if present, specifies the GPIO that
-   needs to be pulled up for the bus to be powered.
-
-Example:
-
-	usb at 12110000 {
-		compatible = "samsung,exynos4210-ehci";
-		reg = <0x12110000 0x100>;
-		interrupts = <0 71 0>;
-		samsung,vbus-gpio = <&gpx2 6 1 3 3>;
-
-		clocks = <&clock 285>;
-		clock-names = "usbhost";
-
-		phys = <&usb2phy 1>;
-		phy-names = "host";
-	};
-
-OHCI
-Required properties:
- - compatible: should be "samsung,exynos4210-ohci" for USB 2.0
-   OHCI companion controller in host mode.
- - reg: physical base address of the controller and length of memory mapped
-   region.
- - interrupts: interrupt number to the cpu.
- - clocks: from common clock binding: handle to usb clock.
- - clock-names: from common clock binding: Shall be "usbhost".
- - phys: from the *Generic PHY* bindings; array specifying phy(s) used
-   by the root port.
- - phy-names: from the *Generic PHY* bindings; array of the names for
-   each phy for the root ports, must be a subset of the following:
-   "host", "hsic0", "hsic1".
-
-Example:
-	usb at 12120000 {
-		compatible = "samsung,exynos4210-ohci";
-		reg = <0x12120000 0x100>;
-		interrupts = <0 71 0>;
-
-		clocks = <&clock 285>;
-		clock-names = "usbhost";
-
-		phys = <&usb2phy 1>;
-		phy-names = "host";
-	};
diff --git a/Documentation/devicetree/bindings/usb/samsung,exynos-usb2.yaml b/Documentation/devicetree/bindings/usb/samsung,exynos-usb2.yaml
new file mode 100644
index 000000000000..fbf07d6e707a
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung,exynos-usb2.yaml
@@ -0,0 +1,117 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/samsung,exynos-usb2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC USB 2.0 EHCI/OHCI Controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos4210-ehci
+      - samsung,exynos4210-ohci
+
+  '#address-cells':
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: usbhost
+
+  interrupts:
+    maxItems: 1
+
+  phys:
+    minItems: 1
+    maxItems: 3
+
+  phy-names:
+    items:
+      enum: [host, hsic0, hsic1]
+    minItems: 1
+    maxItems: 3
+
+  reg:
+    maxItems: 1
+
+  samsung,vbus-gpio:
+    description:
+      Only for controller in EHCI mode, if present, specifies the GPIO that
+      needs to be pulled up for the bus to be powered.
+
+  '#size-cells':
+    const: 0
+
+patternProperties:
+  "^.*@[0-9a-f]{1,2}$":
+    description: The hard wired USB devices
+    type: object
+    $ref: /usb/usb-device.yaml
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - interrupts
+  - phys
+  - phy-names
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos4210-ohci
+    then:
+      properties:
+        samsung,vbus-gpio: false
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    usb at 12110000 {
+        compatible = "samsung,exynos4210-ehci";
+        reg = <0x12110000 0x100>;
+        interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clock CLK_USBH20>;
+        clock-names = "usbhost";
+        phys = <&usb2_phy 0>;
+        phy-names = "host";
+
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        hub at 1 {
+            compatible = "usb0424,9514";
+            reg = <1>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            usbether at 1 {
+                compatible = "usb0424,ec00";
+                reg = <1>;
+                local-mac-address = [00 00 00 00 00 00];
+            };
+        };
+    };
+
+    usb at 12120000 {
+        compatible = "samsung,exynos4210-ohci";
+        reg = <0x12120000 0x100>;
+        interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+        clocks = <&clock CLK_USBH20>;
+        clock-names = "usbhost";
+        phys = <&usb2_phy 0>;
+        phy-names = "host";
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:16:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:16:43 +0100
Subject: [PATCH 11/12] dt-bindings: usb: samsung,
 exynos-dwc3: convert to dtschema
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220123111644.25540-12-krzysztof.kozlowski@canonical.com>

Convert the Samsung Exynos SoC USB 3.0 DWC3 Controller bindings to DT
schema format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/usb/exynos-usb.txt    |  49 -------
 .../bindings/usb/samsung,exynos-dwc3.yaml     | 129 ++++++++++++++++++
 2 files changed, 129 insertions(+), 49 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml

diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
index f7ae79825d7d..61c03c0ef19f 100644
--- a/Documentation/devicetree/bindings/usb/exynos-usb.txt
+++ b/Documentation/devicetree/bindings/usb/exynos-usb.txt
@@ -64,52 +64,3 @@ Example:
 		phys = <&usb2phy 1>;
 		phy-names = "host";
 	};
-
-DWC3
-Required properties:
- - compatible: should be one of the following -
-	       "samsung,exynos5250-dwusb3": for USB 3.0 DWC3 controller on
-					    Exynos5250/5420.
-	       "samsung,exynos5433-dwusb3": for USB 3.0 DWC3 controller on
-					    Exynos5433.
-	       "samsung,exynos7-dwusb3": for USB 3.0 DWC3 controller on Exynos7.
- - #address-cells, #size-cells : should be '1' if the device has sub-nodes
-				 with 'reg' property.
- - ranges: allows valid 1:1 translation between child's address space and
-	   parent's address space
- - clocks: Clock IDs array as required by the controller.
- - clock-names: Names of clocks corresponding to IDs in the clock property.
-                Following clock names shall be provided for different
-                compatibles:
-                 - samsung,exynos5250-dwusb3: "usbdrd30",
-                 - samsung,exynos5433-dwusb3: "aclk", "susp_clk", "pipe_pclk",
-                                              "phyclk",
-                 - samsung,exynos7-dwusb3: "usbdrd30", "usbdrd30_susp_clk",
-                                           "usbdrd30_axius_clk"
- - vdd10-supply: 1.0V powr supply
- - vdd33-supply: 3.0V/3.3V power supply
-
-Sub-nodes:
-The dwc3 core should be added as subnode to Exynos dwc3 glue.
-- dwc3 :
-   The binding details of dwc3 can be found in:
-   Documentation/devicetree/bindings/usb/snps,dwc3.yaml
-
-Example:
-	usb at 12000000 {
-		compatible = "samsung,exynos5250-dwusb3";
-		clocks = <&clock 286>;
-		clock-names = "usbdrd30";
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-		vdd10-supply = <&ldo11_reg>;
-		vdd33-supply = <&ldo9_reg>;
-
-		dwc3 {
-			compatible = "synopsys,dwc3";
-			reg = <0x12000000 0x10000>;
-			interrupts = <0 72 0>;
-			usb-phy = <&usb2_phy &usb3_phy>;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml b/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml
new file mode 100644
index 000000000000..22b91a27d776
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/samsung,exynos-dwc3.yaml
@@ -0,0 +1,129 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/samsung,exynos-dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC USB 3.0 DWC3 Controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5250-dwusb3
+      - samsung,exynos5433-dwusb3
+      - samsung,exynos7-dwusb3
+
+  '#address-cells':
+    const: 1
+
+  clocks:
+    minItems: 1
+    maxItems: 4
+
+  clock-names:
+    minItems: 1
+    maxItems: 4
+
+  ranges: true
+
+  '#size-cells':
+    const: 1
+
+  vdd10-supply:
+    description: 1.0V power supply
+
+  vdd33-supply:
+    description: 3.0V/3.3V power supply
+
+patternProperties:
+  "^usb@[0-9a-f]+$":
+    $ref: snps,dwc3.yaml#
+    description: Required child node
+
+required:
+  - compatible
+  - '#address-cells'
+  - clocks
+  - clock-names
+  - ranges
+  - '#size-cells'
+  - vdd10-supply
+  - vdd33-supply
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5250-dwusb3
+    then:
+      properties:
+        clocks:
+          minItems: 1
+          maxItems: 1
+        clock-names:
+          items:
+            - const: usbdrd30
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos54333-dwusb3
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: aclk
+            - const: susp_clk
+            - const: pipe_pclk
+            - const: phyclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos7-dwusb3
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: usbdrd30
+            - const: usbdrd30_susp_clk
+            - const: usbdrd30_axius_clk
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    usb {
+        compatible = "samsung,exynos5250-dwusb3";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+        clocks = <&clock CLK_USBD300>;
+        clock-names = "usbdrd30";
+        vdd33-supply = <&ldo9_reg>;
+        vdd10-supply = <&ldo11_reg>;
+
+        usb at 12000000 {
+            compatible = "snps,dwc3";
+            reg = <0x12000000 0x10000>;
+            interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+            phys = <&usbdrd_phy0 0>, <&usbdrd_phy0 1>;
+            phy-names = "usb2-phy", "usb3-phy";
+            snps,dis_u3_susphy_quirk;
+        };
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:46:50 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:46:50 +0100
Subject: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to
 dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164293835975.31601.16562955007803362485.b4-ty@canonical.com>

On Tue, 11 Jan 2022 21:13:58 +0100, Krzysztof Kozlowski wrote:
> Changes since v1
> ================
> 1. Patch #1: add missing pin assignment (Alim).
> 2. Patch #2: correct double sizeof() (Alim).
> 3. Patch #7, #8: put label-override in proper patch (Alim).
> 4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
> 5. New patches: #25 - #28.
>    Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
>    handling, so they need their own compatibles.
>    Please kindly review and provide feedback on these as I do not have
>    details.
> 6. Add review tags.
> 
> [...]

Applied, thanks!

To Samsung pinctrl tree:

[01/28] pinctrl: samsung: drop pin banks references on error paths
        commit: 50ebd19e3585b9792e994cfa8cbee8947fe06371
[02/28] pinctrl: samsung: accept GPIO bank nodes with a suffix
        commit: a29681b0cc3778c9ff6abdbcad579cba776dbb81
[24/28] dt-bindings: pinctrl: samsung: convert to dtschema
        commit: af030d83da1dc0d750d7bcc88d57dd1cae5f6b61
[25/28] dt-bindings: pinctrl: samsung: describe Exynos850 and ExynosAutov9 wake-ups
        commit: 1755e227c21636ade047dc9b920f647c1d53b4e9
[26/28] pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups
        commit: 832ae134ccc1c78a2f5ec81b7010dd24c3c49535

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 03:46:51 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 12:46:51 +0100
Subject: [PATCH] pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE
 and CMGP gpios
In-Reply-To: <20220114203757.4860-1-semen.protsenko@linaro.org>
References: <20220114203757.4860-1-semen.protsenko@linaro.org>
Message-ID: <164293835975.31601.16620899683024964008.b4-ty@canonical.com>

On Fri, 14 Jan 2022 22:37:57 +0200, Sam Protsenko wrote:
> GPIO_ALIVE and GPIO_CMGP blocks in Exynos850 SoC don't have EINT
> capabilities (like EINT_SVC register), and there are no corresponding
> interrupts wired to GIC. Instead those blocks have wake-up interrupts
> for each pin. The ".eint_gpio_init" callbacks were specified by mistake
> for these blocks, when porting pinctrl code from downstream kernel. That
> leads to error messages like this:
> 
> [...]

Applied, thanks!

[1/1] pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and CMGP gpios
      commit: 96f79935015cf3d7ca6fabf63cd13b8af45a7713

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From jszhang at kernel.org  Sun Jan 23 04:27:58 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 23 Jan 2022 20:27:58 +0800
Subject: [PATCH] net: stmmac: remove unused members in struct stmmac_priv
Message-ID: <20220123122758.2876-1-jszhang@kernel.org>

The tx_coalesce and mii_irq are not used at all now, so remove them.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 40b5ed94cb54..5b195d5051d6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -194,7 +194,6 @@ struct stmmac_priv {
 	u32 tx_coal_timer[MTL_MAX_TX_QUEUES];
 	u32 rx_coal_frames[MTL_MAX_TX_QUEUES];
 
-	int tx_coalesce;
 	int hwts_tx_en;
 	bool tx_path_in_lpi_mode;
 	bool tso;
@@ -229,7 +228,6 @@ struct stmmac_priv {
 	unsigned int flow_ctrl;
 	unsigned int pause;
 	struct mii_bus *mii;
-	int mii_irq[PHY_MAX_ADDR];
 
 	struct phylink_config phylink_config;
 	struct phylink *phylink;
-- 
2.34.1



From linux at fw-web.de  Sun Jan 23 05:35:10 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 23 Jan 2022 14:35:10 +0100
Subject: [PATCH v2] arm64: dts: rk3568: drop pclk_xpcs from gmac0
Message-ID: <20220123133510.135651-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

pclk_xpcs is not supported by mainline driver and breaks dtbs_check

following warnings occour, and many more

rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
    [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
    [15, 389], [15, 185], [15, 172]] is too long
	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
    ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
    'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml

after removing it, the clock and other warnings are gone.

pclk_xpcs on gmac is used to support QSGMII, but this requires a driver
supporting it.
Once xpcs support is introduced, the clock can be added to the
documentation and both controllers.

Fixes: b8d41e5053cd ("arm64: dts: rockchip: add gmac0 node to rk3568")
Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
Acked-by: Michael Riesch <michael.riesch at wolfvision.net>
---
changes in v2:
  - rebase on 5.17-rc1
  - separate from bpi-r2pro series
  - changed commit-message

---
 arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8..d91df1cde736 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -32,13 +32,11 @@ gmac0: ethernet at fe2a0000 {
 		clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
 			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
 			 <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
-			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
-			 <&cru PCLK_XPCS>;
+			 <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
 		clock-names = "stmmaceth", "mac_clk_rx",
 			      "mac_clk_tx", "clk_mac_refout",
 			      "aclk_mac", "pclk_mac",
-			      "clk_mac_speed", "ptp_ref",
-			      "pclk_xpcs";
+			      "clk_mac_speed", "ptp_ref";
 		resets = <&cru SRST_A_GMAC0>;
 		reset-names = "stmmaceth";
 		rockchip,grf = <&grf>;
-- 
2.25.1



From jszhang at kernel.org  Sun Jan 23 05:28:05 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 23 Jan 2022 21:28:05 +0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and unprepare
 "stmmaceth" clk
Message-ID: <20220123132805.758-1-jszhang@kernel.org>

Fix warnings on Allwinner D1 platform:

[    1.604695] ------------[ cut here ]------------
[    1.609328] bus-emac already disabled
[    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
[    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
[    1.627653] Hardware name: Allwinner D1 NeZha (DT)
[    1.632443] Workqueue: events_unbound deferred_probe_work_func
[    1.638286] epc : clk_core_disable+0xcc/0xec
[    1.642561]  ra : clk_core_disable+0xcc/0xec
[    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
[    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
[    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
[    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
[    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
[    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
[    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
[    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
[    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
[    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
[    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
[    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
[    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
[    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
[    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
[    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
[    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
[    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
[    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
[    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
[    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
[    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
[    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
[    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
[    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
[    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
[    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
[    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
[    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
[    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
[    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
[    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
[    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
[    1.873675] ------------[ cut here ]------------
[    1.878366] bus-emac already unprepared
[    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
[    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
[    1.898674] Hardware name: Allwinner D1 NeZha (DT)
[    1.903464] Workqueue: events_unbound deferred_probe_work_func
[    1.909305] epc : clk_core_unprepare+0xe4/0x168
[    1.913840]  ra : clk_core_unprepare+0xe4/0x168
[    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
[    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
[    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
[    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
[    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
[    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
[    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
[    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
[    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
[    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
[    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
[    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
[    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
[    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
[    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
[    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
[    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
[    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
[    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
[    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
[    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
[    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
[    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
[    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
[    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
[    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
[    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
[    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
[    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
[    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
[    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
[    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
[    2.135455] ---[ end trace 8d5c6046255f84a1 ]---

the dwmmac-sun8i driver will get the "stmmaceth" clk as tx_clk during
driver initialization. If stmmac_dvr_probe() fails due to various
reasons, sun8i_dwmac_exit() will disable and unprepare the "stmmaceth"
clk, then stmmac_remove_config_dt() will disable and unprepare the
clk again.

Currently, there's no other usage of tx_clk except preparing and
enabling, we can fix the above warnings by simply removing the tx_clk
and all its usage, we rely on the common stmmac_probe_config_dt()
routine to prepare and enable the stmmaceth clk.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 20 +------------------
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 617d0e4c6495..d97469825e53 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -57,7 +57,6 @@ struct emac_variant {
 };
 
 /* struct sunxi_priv_data - hold all sunxi private data
- * @tx_clk:	reference to MAC TX clock
  * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
  * @regulator:	reference to the optional regulator
  * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
@@ -68,7 +67,6 @@ struct emac_variant {
  * @mux_handle:	Internal pointer used by mdio-mux lib
  */
 struct sunxi_priv_data {
-	struct clk *tx_clk;
 	struct clk *ephy_clk;
 	struct regulator *regulator;
 	struct reset_control *rst_ephy;
@@ -579,22 +577,14 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
 		}
 	}
 
-	ret = clk_prepare_enable(gmac->tx_clk);
-	if (ret) {
-		dev_err(&pdev->dev, "Could not enable AHB clock\n");
-		goto err_disable_regulator;
-	}
-
 	if (gmac->use_internal_phy) {
 		ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
 		if (ret)
-			goto err_disable_clk;
+			goto err_disable_regulator;
 	}
 
 	return 0;
 
-err_disable_clk:
-	clk_disable_unprepare(gmac->tx_clk);
 err_disable_regulator:
 	if (gmac->regulator)
 		regulator_disable(gmac->regulator);
@@ -1043,8 +1033,6 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
 	if (gmac->variant->soc_has_internal_phy)
 		sun8i_dwmac_unpower_internal_phy(gmac);
 
-	clk_disable_unprepare(gmac->tx_clk);
-
 	if (gmac->regulator)
 		regulator_disable(gmac->regulator);
 }
@@ -1167,12 +1155,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	gmac->tx_clk = devm_clk_get(dev, "stmmaceth");
-	if (IS_ERR(gmac->tx_clk)) {
-		dev_err(dev, "Could not get TX clock\n");
-		return PTR_ERR(gmac->tx_clk);
-	}
-
 	/* Optional regulator for PHY */
 	gmac->regulator = devm_regulator_get_optional(dev, "phy");
 	if (IS_ERR(gmac->regulator)) {
-- 
2.34.1



From linux at fw-web.de  Sun Jan 23 05:36:15 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 23 Jan 2022 14:36:15 +0100
Subject: [PATCH v1] arm64: dts: rk356x: fix dma-controller warning
Message-ID: <20220123133615.135789-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

DMA-Cotrollers defined in rk356x.dtsi do not match the pattern in bindings.

arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dt.yaml:
  dmac at fe530000: $nodename:0: 'dmac at fe530000' does not match '^dma-controller(@.*)?$'
	From schema: Documentation/devicetree/bindings/dma/arm,pl330.yaml
arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dt.yaml:
  dmac at fe550000: $nodename:0: 'dmac at fe550000' does not match '^dma-controller(@.*)?$'
	From schema: Documentation/devicetree/bindings/dma/arm,pl330.yaml

This Patch fixes it.

Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a23975..8ccce54ee8e7 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -651,7 +651,7 @@ &i2s1m0_sdo0   &i2s1m0_sdo1
 		status = "disabled";
 	};
 
-	dmac0: dmac at fe530000 {
+	dmac0: dma-controller at fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
 		interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
@@ -662,7 +662,7 @@ dmac0: dmac at fe530000 {
 		#dma-cells = <1>;
 	};
 
-	dmac1: dmac at fe550000 {
+	dmac1: dma-controller at fe550000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe550000 0x0 0x4000>;
 		interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.25.1



From heiko at sntech.de  Sun Jan 23 05:38:09 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 14:38:09 +0100
Subject: Aw: Re: [PATCH v1 1/3] dts64: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <trinity-d0efbf68-ed45-47d4-97b3-d3788c5a9de6-1642863025116@3c-app-gmx-bap44>
References: <20220116124911.65203-1-linux@fw-web.de>
 <236548630.RelmrRfzIS@diego>
 <trinity-d0efbf68-ed45-47d4-97b3-d3788c5a9de6-1642863025116@3c-app-gmx-bap44>
Message-ID: <8763546.c4FMd9deqZ@phil>

Hi Frank,

Am Samstag, 22. Januar 2022, 15:50:25 CET schrieb Frank Wunderlich:
> i plan to send a v2 of the series after 5.17-rc1 is out, because i have now verified
> the functions from gpio header and found some pinctrl-changes. V1 had only prepared
> the nodes to know which devices are present on this header.
> 
> should i include this patch again or do you pull it from v1 (maybe as fix)?

I do plan to include this as fix after -rc1, but I just saw that you already sent
a separate patch of it, so I'll take that one instead :-)

Heiko

> 
> regards Frank
> 
> 
> > Gesendet: Montag, 17. Januar 2022 um 22:05 Uhr
> > Von: "Heiko St?bner" <heiko at sntech.de>
> 
> > From looking at the documentation I got the impression that the
> > pclk_xpcs is related to the separate qsgmii_pcs in the memory map.
> > 
> > So yes, I fully agree to dropping this clock from here and then adding
> > them to whatever ip block really needs it.
> 






From linux at fw-web.de  Sun Jan 23 05:51:14 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 23 Jan 2022 14:51:14 +0100
Subject: [PATCH v2 0/2] Add BananaPi R2 Pro board
Message-ID: <20220123135116.136846-1-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This Series adds RK3568 based Bananapi R2 Board.

changes in v2:
- rebase on 5.17-rc1
- dropped patch for fixing dtbs_check (sent separately)
- verified pins on gpio-header (con2) and changed pinctrl where needed
- changed led part

Frank Wunderlich (2):
  dt-bindings: rockchip: Add BananaPi R2 Pro Board
  arm64: dts: rockchip: Add Bananapi R2 Pro

 .../devicetree/bindings/arm/rockchip.yaml     |   5 +
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-bpi-r2-pro.dts   | 461 ++++++++++++++++++
 3 files changed, 467 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts

-- 
2.25.1



From linux at fw-web.de  Sun Jan 23 05:51:16 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 23 Jan 2022 14:51:16 +0100
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
In-Reply-To: <20220123135116.136846-1-linux@fw-web.de>
References: <20220123135116.136846-1-linux@fw-web.de>
Message-ID: <20220123135116.136846-3-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

This patch adds Devicetree for Bananapi R2 Pro based on RK3568.
Add uart/sd/emmc/i2c/rk809/tsadc nodes for basic function.
Gmac0 is directly connected to wan-port so usable without additional
driver.
On gmac1 there is a switch (rtl8367rb) connected which have not yet a
driver in mainline.

Patch also prepares nodes for GPIO header.

Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
changes in v2:
- drop alias for gmac1 - currently unused due to missing switch driver
- verified / changed pinctrl of pwm/spi/uart/i2c
- add sharing information for con2 functions
- always power on vccio1 iodomain (used for rtc)
- drop V00 from model
- change leds (change names, drop label, add pinctrl, use color+function)
- add fan
---
 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3568-bpi-r2-pro.dts   | 461 ++++++++++++++++++
 2 files changed, 462 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3ad7b..70007b370d87 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -58,3 +58,4 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-bpi-r2-pro.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
new file mode 100644
index 000000000000..738b62adbef8
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Author: Frank Wunderlich <frank-w at public-files.de>
+ *
+ */
+
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include "rk3568.dtsi"
+
+/ {
+	model = "Bananapi-R2 Pro (RK3568) DDR4 Board";
+	compatible = "rockchip,rk3568-bpi-r2pro", "rockchip,rk3568";
+
+	aliases {
+		ethernet0 = &gmac0;
+		mmc0 = &sdmmc0;
+		mmc1 = &sdhci;
+	};
+
+	chosen: chosen {
+		stdout-path = "serial2:1500000n8";
+		bootargs = "earlycon=uart8250,mmio32,0xfe660000";
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&blue_led_pin &green_led_pin>;
+
+		blue_led: led-0 {
+			color = <LED_COLOR_ID_BLUE>;
+			default-state = "off";
+			function = LED_FUNCTION_STATUS;
+			gpios = <&gpio0 RK_PD6 GPIO_ACTIVE_HIGH>;
+		};
+
+		green_led: led-1 {
+			color = <LED_COLOR_ID_GREEN>;
+			default-state = "on";
+			function = LED_FUNCTION_POWER;
+			gpios = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	dc_12v: dc-12v {
+		compatible = "regulator-fixed";
+		regulator-name = "dc_12v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <12000000>;
+		regulator-max-microvolt = <12000000>;
+	};
+
+	vcc3v3_sys: vcc3v3-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc3v3_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_sys: vcc5v0-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_sys";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+};
+
+&gmac0 {
+	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
+	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
+	clock_in_out = "input";
+	phy-handle = <&rgmii_phy0>;
+	phy-mode = "rgmii";
+	pinctrl-names = "default";
+	pinctrl-0 = <&gmac0_miim
+		     &gmac0_tx_bus2
+		     &gmac0_rx_bus2
+		     &gmac0_rgmii_clk
+		     &gmac0_rgmii_bus>;
+
+	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+	snps,reset-active-low;
+	/* Reset time is 20ms, 100ms for rtl8211f */
+	snps,reset-delays-us = <0 20000 100000>;
+
+	tx_delay = <0x3c>;
+	rx_delay = <0x2f>;
+
+	status = "okay";
+};
+
+&i2c0 {
+	status = "okay";
+
+	rk809: pmic at 20 {
+		compatible = "rockchip,rk809";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pmic_int>;
+		rockchip,system-power-controller;
+		vcc1-supply = <&vcc3v3_sys>;
+		vcc2-supply = <&vcc3v3_sys>;
+		vcc3-supply = <&vcc3v3_sys>;
+		vcc4-supply = <&vcc3v3_sys>;
+		vcc5-supply = <&vcc3v3_sys>;
+		vcc6-supply = <&vcc3v3_sys>;
+		vcc7-supply = <&vcc3v3_sys>;
+		vcc8-supply = <&vcc3v3_sys>;
+		vcc9-supply = <&vcc3v3_sys>;
+		wakeup-source;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdd_gpu: DCDC_REG2 {
+				regulator-name = "vdd_gpu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vdd_npu: DCDC_REG4 {
+				regulator-name = "vdd_npu";
+				regulator-init-microvolt = <900000>;
+				regulator-initial-mode = <0x2>;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-ramp-delay = <6001>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_1v8: DCDC_REG5 {
+				regulator-name = "vcc_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_image: LDO_REG1 {
+				regulator-name = "vdda0v9_image";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9: LDO_REG2 {
+				regulator-name = "vdda_0v9";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda0v9_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc3v3_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcca_1v8: LDO_REG7 {
+				regulator-name = "vcca_1v8";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca1v8_pmu: LDO_REG8 {
+				regulator-name = "vcca1v8_pmu";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcca1v8_image: LDO_REG9 {
+				regulator-name = "vcca1v8_image";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3: SWITCH_REG1 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc3v3_sd: SWITCH_REG2 {
+				regulator-name = "vcc3v3_sd";
+				regulator-always-on;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&i2c5 {
+	/* pin 3 (SDA) + 4 (SCL) of header con2 */
+	status = "disabled";
+};
+
+&mdio0 {
+	rgmii_phy0: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0x0>;
+	};
+};
+
+&pinctrl {
+	leds {
+		blue_led_pin: blue-led-pin {
+			rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+		green_led_pin: green-led-pin {
+			rockchip,pins = <0 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int: pmic_int {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_3v3>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&pwm8 {
+	/* fan 5v - gnd - pwm */
+	status = "okay";
+};
+
+&pwm10 {
+	/* pin 7 of header con2 */
+	status = "disabled";
+};
+
+&pwm11 {
+	/* pin 15 of header con2 */
+	status = "disabled";
+};
+
+&pwm12 {
+	/* pin 21 of header con2 */
+	/* shared with uart9 + spi3 */
+	pinctrl-0 = <&pwm12m1_pins>;
+	status = "disabled";
+};
+
+&pwm13 {
+	/* pin 24 of header con2 */
+	/* shared with uart9 */
+	pinctrl-0 = <&pwm13m1_pins>;
+	status = "disabled";
+};
+
+&pwm14 {
+	/* pin 23 of header con2 */
+	/* shared with spi3 */
+	pinctrl-0 = <&pwm14m1_pins>;
+	status = "disabled";
+};
+
+&pwm15 {
+	/* pin 19 of header con2 */
+	/* shared with spi3 */
+	pinctrl-0 = <&pwm15m1_pins>;
+	status = "disabled";
+};
+
+&saradc {
+	vref-supply = <&vcca_1v8>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	max-frequency = <200000000>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd &emmc_datastrobe>;
+	status = "okay";
+};
+
+&sdmmc0 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc0_bus4 &sdmmc0_clk &sdmmc0_cmd &sdmmc0_det>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc3v3_sd>;
+	vqmmc-supply = <&vccio_sd>;
+	status = "okay";
+};
+
+&spi3 {
+	/* pin 19 (MO) + 21 (MI) + 23 (CK) of header con2 */
+	/* shared with pwm12/14/15 and uart9 */
+	pinctrl-0 = <&spi3m1_pins>;
+	status = "disabled";
+};
+
+&tsadc {
+	status = "okay";
+};
+
+&uart0 {
+	/* pin 8 (TX) + 10 (RX) (RTS:16, CTS:18) of header con2 */
+	status = "disabled";
+};
+
+&uart2 {
+	/* debug-uart */
+	status = "okay";
+};
+
+&uart7 {
+	/* pin 11 (TX) + 13 (RX) of header con2 */
+	pinctrl-0 = <&uart7m1_xfer>;
+	status = "disabled";
+};
+
+&uart9 {
+	/* pin 21 (TX) + 24 (RX) of header con2 */
+	/* shared with pwm13 and pwm12/spi3 */
+	pinctrl-0 = <&uart9m1_xfer>;
+	status = "disabled";
+};
-- 
2.25.1



From linux at fw-web.de  Sun Jan 23 05:51:15 2022
From: linux at fw-web.de (Frank Wunderlich)
Date: Sun, 23 Jan 2022 14:51:15 +0100
Subject: [PATCH v2 1/2] dt-bindings: rockchip: Add BananaPi R2 Pro Board
In-Reply-To: <20220123135116.136846-1-linux@fw-web.de>
References: <20220123135116.136846-1-linux@fw-web.de>
Message-ID: <20220123135116.136846-2-linux@fw-web.de>

From: Frank Wunderlich <frank-w at public-files.de>

Add Devicetree Binding for Bananapi R2 Pro Board based on rk3568 SoC

Co-developed-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Peter Geis <pgwipeout at gmail.com>
Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
---
 Documentation/devicetree/bindings/arm/rockchip.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 4aed16176434..33d6423fe6c3 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -651,6 +651,11 @@ properties:
           - const: rockchip,rk3568-evb1-v10
           - const: rockchip,rk3568
 
+      - description: Rockchip RK3568 Banana Pi R2 Pro
+        items:
+          - const: rockchip,rk3568-bpi-r2pro
+          - const: rockchip,rk3568
+
 additionalProperties: true
 
 ...
-- 
2.25.1



From stefan.wahren at i2se.com  Sun Jan 23 06:08:01 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun, 23 Jan 2022 15:08:01 +0100
Subject: [PATCH RFC 00/11] dmaengine: bcm2835: add BCM2711 40-bit DMA
 support
In-Reply-To: <1640606743-10993-1-git-send-email-stefan.wahren@i2se.com>
References: <1640606743-10993-1-git-send-email-stefan.wahren@i2se.com>
Message-ID: <d4242317-711d-23ce-c63e-7d355c8c0e41@i2se.com>

Hi,

Am 27.12.21 um 13:05 schrieb Stefan Wahren:
> The BCM2711 has 4 DMA channels with a 40-bit address range, allowing them
> to access the full 4GB of memory on a Pi 4. This patch series serves as a
> basis for a discussion (just compile tested, so don't expect anything working)
> which include the following points:
>
> * correct DT binding and representation for BCM2711
>
> According to the vendor DTS [1] the 4 DMA channels are connected to SCB.
> I'm not sure how this is properly adapted to the mainline DT.
>
> * general implementation approach
>
> The vendor approach mapped all the BCM2835 control block bits to the BCM2711
> layout and the rest of the differences are handled by a lot of is_40bit_channel
> conditions. An advantage of this is the small amount of changes to the driver.
> But on the down side the code is now much harder to understand and maintain.
>
> This series tries to implement this feature in a more cleaner way
> while keeping it in the bcm2835-dma driver. Before this series the driver
> has ~ 1000 lines and after that ~ 1500 lines.
>
> So the question is this approach acceptable?
>
> Patches 1 - 3 are just clean-ups.
>
> Disclaimer: my knowledge about the DMA controller is very limited
>
> More information:
>
> https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf
>
> [1] - https://github.com/raspberrypi/linux/blob/561deffcf471ba0f7bd48541d06a79d5aa38d297/arch/arm/boot/dts/bcm2711-rpi-ds.dtsi#L47
> [2] - https://github.com/raspberrypi/linux/commit/44364bd140b0bc9187c881fbdc4ee358961059d5
would be nice to get some input aka gentle ping.


From jszhang at kernel.org  Sun Jan 23 06:12:45 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 23 Jan 2022 22:12:45 +0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
Message-ID: <20220123141245.1060-1-jszhang@kernel.org>

I met can't receive rx pkt issue with below steps:
0.plug in ethernet cable then boot normal and get ip from dhcp server
1.quickly hotplug out then hotplug in the ethernet cable
2.trigger the dhcp client to renew lease

tcpdump shows that the request tx pkt is sent out successfully,
but the mac can't receive the rx pkt.

The issue can easily be reproduced on platforms with PHY_POLL external
phy. If we don't allow the phy to stop the RXC during LPI, the issue
is gone. I think it's unsafe to stop the RXC during LPI because the mac
needs RXC clock to support RX logic.

And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
false instead of 0.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..92a9b0b226b1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 	stmmac_mac_set(priv, priv->ioaddr, true);
 	if (phy && priv->dma_cap.eee) {
-		priv->eee_active = phy_init_eee(phy, 1) >= 0;
+		priv->eee_active = phy_init_eee(phy, false) >= 0;
 		priv->eee_enabled = stmmac_eee_init(priv);
 		priv->tx_lpi_enabled = priv->eee_enabled;
 		stmmac_set_eee_pls(priv, priv->hw, true);
-- 
2.34.1



From robh at kernel.org  Sun Jan 23 07:28:31 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 23 Jan 2022 09:28:31 -0600
Subject: [PATCH] dt-bindings: i2c: imx: Make each example a separate entry
In-Reply-To: <20220119015253.2437352-1-robh@kernel.org>
References: <20220119015253.2437352-1-robh@kernel.org>
Message-ID: <Ye10H8MmF4dobZ0d@robh.at.kernel.org>

On Tue, 18 Jan 2022 19:52:53 -0600, Rob Herring wrote:
> Each independent example should be a separate entry. This allows for
> 'interrupts' to have different cell sizes.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  Documentation/devicetree/bindings/i2c/i2c-imx.yaml | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Sun Jan 23 07:29:03 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 23 Jan 2022 09:29:03 -0600
Subject: [PATCH] dt-bindings: i2c: stm32-i2c: Move st,syscfg-fmp
 definition to top level
In-Reply-To: <20220119174407.3810088-1-robh@kernel.org>
References: <20220119174407.3810088-1-robh@kernel.org>
Message-ID: <Ye10P+FlVPzsB7jR@robh.at.kernel.org>

On Wed, 19 Jan 2022 11:44:07 -0600, Rob Herring wrote:
> It is preferred to define all properties in the main schema and leave
> if/then/else schemas to just be further constraints on properties.
> 
> Rework the schema to use be more specific for each cell. Previously,
> multiple entries of 3 cells each was allowed.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/i2c/st,stm32-i2c.yaml | 24 ++++++++++---------
>  1 file changed, 13 insertions(+), 11 deletions(-)
> 

Applied, thanks!


From robh at kernel.org  Sun Jan 23 07:29:19 2022
From: robh at kernel.org (Rob Herring)
Date: Sun, 23 Jan 2022 09:29:19 -0600
Subject: [PATCH] dt-bindings: watchdog: fsl-imx7ulp-wdt: Fix
 assigned-clock-parents
In-Reply-To: <20220120172333.1628990-1-robh@kernel.org>
References: <20220120172333.1628990-1-robh@kernel.org>
Message-ID: <Ye10TywgYxByt4rE@robh.at.kernel.org>

On Thu, 20 Jan 2022 11:23:32 -0600, Rob Herring wrote:
> The schema has a typo with 'assigned-clocks-parents'. As it is not
> required to list assigned clocks in bindings, just drop the assigned-clocks
> property definitions to fix this.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  .../devicetree/bindings/watchdog/fsl-imx7ulp-wdt.yaml     | 8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)
> 

Applied, thanks!


From jszhang at kernel.org  Sun Jan 23 07:22:41 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 23 Jan 2022 23:22:41 +0800
Subject: [PATCH] net: dsa|ethernet: use bool values to pass bool param of
 phy_init_eee
Message-ID: <20220123152241.1480-1-jszhang@kernel.org>

The 2nd param of phy_init_eee(): clk_stop_enable is a bool param, use
true or false instead of 1/0.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/dsa/b53/b53_common.c                 | 2 +-
 drivers/net/dsa/mt7530.c                         | 2 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.c   | 2 +-
 drivers/net/ethernet/freescale/fec_main.c        | 2 +-
 drivers/net/ethernet/marvell/mvneta.c            | 2 +-
 drivers/net/ethernet/microchip/lan743x_ethtool.c | 2 +-
 drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c  | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 3867f3d4545f..a3b98992f180 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -2186,7 +2186,7 @@ int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy)
 {
 	int ret;
 
-	ret = phy_init_eee(phy, 0);
+	ret = phy_init_eee(phy, false);
 	if (ret)
 		return 0;
 
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index b82512e5b33b..bc77a26c825a 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2846,7 +2846,7 @@ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
 			mcr |= PMCR_RX_FC_EN;
 	}
 
-	if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, 0) >= 0) {
+	if (mode == MLO_AN_PHY && phydev && phy_init_eee(phydev, false) >= 0) {
 		switch (speed) {
 		case SPEED_1000:
 			mcr |= PMCR_FORCE_EEE1G;
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 87f1056e29ff..cfe09117fe6c 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1368,7 +1368,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_eee *e)
 	if (!p->eee_enabled) {
 		bcmgenet_eee_enable_set(dev, false);
 	} else {
-		ret = phy_init_eee(dev->phydev, 0);
+		ret = phy_init_eee(dev->phydev, false);
 		if (ret) {
 			netif_err(priv, hw, dev, "EEE initialization failed\n");
 			return ret;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 796133de527e..11227f51404c 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2797,7 +2797,7 @@ static int fec_enet_eee_mode_set(struct net_device *ndev, bool enable)
 	int ret = 0;
 
 	if (enable) {
-		ret = phy_init_eee(ndev->phydev, 0);
+		ret = phy_init_eee(ndev->phydev, false);
 		if (ret)
 			return ret;
 
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index 83c8908f0cc7..7f44b73024a0 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4169,7 +4169,7 @@ static void mvneta_mac_link_up(struct phylink_config *config,
 	mvneta_port_up(pp);
 
 	if (phy && pp->eee_enabled) {
-		pp->eee_active = phy_init_eee(phy, 0) >= 0;
+		pp->eee_active = phy_init_eee(phy, false) >= 0;
 		mvneta_set_eee(pp, pp->eee_active && pp->tx_lpi_enabled);
 	}
 }
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index 91a755efe2e6..5f1e7b8bad4f 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -750,7 +750,7 @@ static int lan743x_ethtool_set_eee(struct net_device *netdev,
 	}
 
 	if (eee->eee_enabled) {
-		ret = phy_init_eee(phydev, 0);
+		ret = phy_init_eee(phydev, false);
 		if (ret) {
 			netif_err(adapter, drv, adapter->netdev,
 				  "EEE initialization failed\n");
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 32161a56726c..77a0d9d7e65a 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -127,7 +127,7 @@ bool sxgbe_eee_init(struct sxgbe_priv_data * const priv)
 	/* MAC core supports the EEE feature. */
 	if (priv->hw_cap.eee) {
 		/* Check if the PHY supports EEE */
-		if (phy_init_eee(ndev->phydev, 1))
+		if (phy_init_eee(ndev->phydev, true))
 			return false;
 
 		priv->eee_active = 1;
-- 
2.34.1



From heiko at sntech.de  Sun Jan 23 07:30:29 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 16:30:29 +0100
Subject: [PATCH 4/4] arm64: dts: rockchip: enable the pine64 touch screen
 on rockpro64
In-Reply-To: <20220107051335.3812535-5-pgwipeout@gmail.com>
References: <20220107051335.3812535-1-pgwipeout@gmail.com>
 <20220107051335.3812535-5-pgwipeout@gmail.com>
Message-ID: <5747938.922zgog0jt@phil>

Hi Peter,

Am Freitag, 7. Januar 2022, 06:13:35 CET schrieb Peter Geis:
> Enable the touch screen, backlight, and dsi nodes for the Pine64 touch panel
> attached to the rockpro64.

can you please also include me in the other patches of the series?
I.e. they introduce a new property for the display, so it's nice to know
when they get applied.

While I do agree with patch 3/4, I'm hesistant about this one.
The display/touchscreen will probably not be connected on every rockpro64
so what happens if it doesn't?

I.e are there alternative uses for the affected pins, that may get fried
when this is always enabled?

So part of me would think that an dt-overlay enabling this might be the
nicer way to go?


Heiko


> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> index 158befb9a48c..f6c36fcd6db3 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> @@ -26,7 +26,7 @@ backlight: backlight {
>  		pwms = <&pwm0 0 1000000 0>;
>  		brightness-levels = <0 4 8 16 32 64 128 255>;
>  		default-brightness-level = <5>;
> -		status = "disabled";
> +		status = "okay";
>  	};
>  
>  	clkin_gmac: external-gmac-clock {
> @@ -594,7 +594,7 @@ touch: touchscreen at 5d {
>  		interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
>  		irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
>  		reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
> -		status = "disabled";
> +		status = "okay";
>  	};
>  };
>  
> @@ -633,7 +633,7 @@ &io_domains {
>  
>  /* enable for pine64 panel display support */
>  &mipi_dsi {
> -	status = "disabled";
> +	status = "okay";
>  	clock-master;
>  
>  	ports {
> 






From miquel.raynal at bootlin.com  Sun Jan 23 07:39:24 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Sun, 23 Jan 2022 16:39:24 +0100
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <20211229143334.297305-1-patrick@stwcx.xyz>
Message-ID: <20220123153924.673172-1-miquel.raynal@bootlin.com>

On Wed, 2021-12-29 at 14:33:33 UTC, Patrick Williams wrote:
> The aspeed-smc can have multiple SPI devices attached to it in the
> device tree.  If one of the devices is missing or failing the entire
> probe will fail and all MTD devices under the controller will be
> removed.  On OpenBMC this results in a kernel panic due to missing
> rootfs:
> 
> [    0.538774] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency
> [    0.540471] aspeed-smc 1e620000.spi: w25q01jv-iq (131072 Kbytes)
> [    0.540750] aspeed-smc 1e620000.spi: CE0 window [ 0x20000000 - 0x28000000 ] 128MB
> [    0.540943] aspeed-smc 1e620000.spi: CE1 window [ 0x28000000 - 0x2c000000 ] 64MB
> [    0.541143] aspeed-smc 1e620000.spi: read control register: 203b0041
> [    0.581442] 5 fixed-partitions partitions found on MTD device bmc
> [    0.581625] Creating 5 MTD partitions on "bmc":
> [    0.581854] 0x000000000000-0x0000000e0000 : "u-boot"
> [    0.584472] 0x0000000e0000-0x000000100000 : "u-boot-env"
> [    0.586468] 0x000000100000-0x000000a00000 : "kernel"
> [    0.588465] 0x000000a00000-0x000006000000 : "rofs"
> [    0.590552] 0x000006000000-0x000008000000 : "rwfs"
> [    0.592605] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency
> [    0.592801] aspeed-smc 1e620000.spi: unrecognized JEDEC id bytes: 00 00 00 00 00 00
> [    0.593039] Deleting MTD partitions on "bmc":
> [    0.593175] Deleting u-boot MTD partition
> [    0.637929] Deleting u-boot-env MTD partition
> [    0.829527] Deleting kernel MTD partition
> [    0.856902] Freeing initrd memory: 1032K
> [    0.866428] Deleting rofs MTD partition
> [    0.906264] Deleting rwfs MTD partition
> [    0.986628] aspeed-smc 1e620000.spi: Aspeed SMC probe failed -2
> [    0.986929] aspeed-smc: probe of 1e620000.spi failed with error -2
> ...
> [    2.936719] /dev/mtdblock: Can't open blockdev
> mount: mounting /dev/mtdblock on run/initramfs/ro failed: No such file or directory
> [    2.963030] MTD: Couldn't look up '/dev/mtdblock': -2
> mount: mounting /dev/mtdblock on run/initramfs/rw failed: No such file or directory
> 
> Mounting read-write /dev/mtdblock filesystem failed.  Please fix and run
> 	mount /dev/mtdblock run/initramfs/rw -t jffs2 -o rw
> or perform a factory reset with the clean-rwfs-filesystem option.
> Fatal error, triggering kernel panic!
> [    3.013047] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
> 
> Many BMC designs have two flash chips so that they can handle a hardware
> failure of one of them.  If one chip failed, it doesn't do any good to
> have redundancy if they all get removed anyhow.
> 
> Improve the resilience of the probe function to handle one of the
> children being missing or failed.  Only in the case where all children
> fail to probe should the controller be failed out.
> 
> Signed-off-by: Patrick Williams <patrick at stwcx.xyz>

Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next, thanks.

Miquel


From heiko at sntech.de  Sun Jan 23 07:40:46 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 16:40:46 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma-haikou USB OTG mode
In-Reply-To: <20220120125156.16217-1-quentin.schulz@theobroma-systems.com>
References: <20220120125156.16217-1-quentin.schulz@theobroma-systems.com>
Message-ID: <164295214821.418606.138757821449348671.b4-ty@sntech.de>

On Thu, 20 Jan 2022 13:51:56 +0100, quentin.schulz at theobroma-systems.com wrote:
> The micro USB3.0 port available on the Haikou evaluation kit for Puma
> RK3399-Q7 SoM supports dual-role model (aka drd or OTG) but its support
> was broken until now because of missing logic around the ID pin.
> 
> This adds proper support for USB OTG on Puma Haikou by "connecting" the
> GPIO used for USB ID to the USB3 controller device.

Applied as fix for 5.17, thanks!

[1/1] arm64: dts: rockchip: fix rk3399-puma-haikou USB OTG mode
      commit: ed2c66a95c0c5669880aa93d0d34c6e9694b4cbd

I've done a bit of reordereing:
- extcon comes alphabetically after dr_mode
- extcon-usb3 before external-gmac...


Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Jan 23 07:40:44 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 16:40:44 +0100
Subject: [PATCH v1] arm64: dts: rk356x: fix dma-controller warning
In-Reply-To: <20220123133615.135789-1-linux@fw-web.de>
References: <20220123133615.135789-1-linux@fw-web.de>
Message-ID: <164295214820.418606.10641294516834022045.b4-ty@sntech.de>

On Sun, 23 Jan 2022 14:36:15 +0100, Frank Wunderlich wrote:
> DMA-Cotrollers defined in rk356x.dtsi do not match the pattern in bindings.
> 
> arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dt.yaml:
>   dmac at fe530000: $nodename:0: 'dmac at fe530000' does not match '^dma-controller(@.*)?$'
> 	From schema: Documentation/devicetree/bindings/dma/arm,pl330.yaml
> arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dt.yaml:
>   dmac at fe550000: $nodename:0: 'dmac at fe550000' does not match '^dma-controller(@.*)?$'
> 	From schema: Documentation/devicetree/bindings/dma/arm,pl330.yaml
> 
> [...]

Applied as fix for 5.17, thanks!

[1/1] arm64: dts: rk356x: fix dma-controller warning
      commit: 2ddd96aadbd0412040ef49eda94549c32de6c92c

I've adapted the subject to
    arm64: dts: rockchip: fix dma-controller node names on rk356x
though. Please use prefixes matching the subsystem
(i.e. arm64: dts: rockchip: ... in this case)

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Jan 23 07:40:45 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 16:40:45 +0100
Subject: [PATCH v2] arm64: dts: rk3568: drop pclk_xpcs from gmac0
In-Reply-To: <20220123133510.135651-1-linux@fw-web.de>
References: <20220123133510.135651-1-linux@fw-web.de>
Message-ID: <164295214820.418606.1356481887548959776.b4-ty@sntech.de>

On Sun, 23 Jan 2022 14:35:10 +0100, Frank Wunderlich wrote:
> pclk_xpcs is not supported by mainline driver and breaks dtbs_check
> 
> following warnings occour, and many more
> 
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clocks:
>     [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
>     [15, 389], [15, 185], [15, 172]] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> rk3568-evb1-v10.dt.yaml: ethernet at fe2a0000: clock-names:
>     ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
>     'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
> 	From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
> 
> [...]

Applied as fix for 5.17, thanks!

[1/1] arm64: dts: rk3568: drop pclk_xpcs from gmac0
      commit: 85a8bccfa945680dc561f06b65ea01341d2033fc

I've adapted the subject to
    arm64: dts: rockchip: drop pclk_xpcs from gmac0 on rk3568
though. Please use prefixes matching the subsystem
(i.e. arm64: dts: rockchip: ... in this case)


Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sun Jan 23 07:40:43 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sun, 23 Jan 2022 16:40:43 +0100
Subject: (subset) [PATCH v2 0/3] (Re)enable DP/HDMI audio for RK3399 Gru
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>
References: <20220114230209.4091727-1-briannorris@chromium.org>
Message-ID: <164295214821.418606.10125525976562860474.b4-ty@sntech.de>

On Fri, 14 Jan 2022 15:02:06 -0800, Brian Norris wrote:
> This series fixes DP/HDMI audio for RK3399 Gru systems.
> 
> First, there was a regression with the switch to SPDIF. Patch 1 can be
> taken separately as a regression fix if desired. But it's not quite so
> useful (at least on Chrome OS systems) without the second part.
> 
> Second, jack detection was never upstreamed, because the hdmi-codec
> dependencies were still being worked out when this platform was first
> supported.
> 
> [...]

Applied as fix for 5.17, thanks!

[1/3] arm64: dts: rockchip: Switch RK3399-Gru DP to SPDIF output
      commit: b5fbaf7d779f5f02b7f75b080e7707222573be2a

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From andrew at lunn.ch  Sun Jan 23 07:52:29 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 23 Jan 2022 16:52:29 +0100
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <20220123141245.1060-1-jszhang@kernel.org>
References: <20220123141245.1060-1-jszhang@kernel.org>
Message-ID: <Ye15va7tFWMgKPEE@lunn.ch>

On Sun, Jan 23, 2022 at 10:12:45PM +0800, Jisheng Zhang wrote:
> I met can't receive rx pkt issue with below steps:
> 0.plug in ethernet cable then boot normal and get ip from dhcp server
> 1.quickly hotplug out then hotplug in the ethernet cable
> 2.trigger the dhcp client to renew lease
> 
> tcpdump shows that the request tx pkt is sent out successfully,
> but the mac can't receive the rx pkt.
> 
> The issue can easily be reproduced on platforms with PHY_POLL external
> phy. If we don't allow the phy to stop the RXC during LPI, the issue
> is gone. I think it's unsafe to stop the RXC during LPI because the mac
> needs RXC clock to support RX logic.
> 
> And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
> false instead of 0.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6708ca2aa4f7..92a9b0b226b1 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
>  
>  	stmmac_mac_set(priv, priv->ioaddr, true);
>  	if (phy && priv->dma_cap.eee) {
> -		priv->eee_active = phy_init_eee(phy, 1) >= 0;
> +		priv->eee_active = phy_init_eee(phy, false) >= 0;

This has not caused issues in the past. So i'm wondering if this is
somehow specific to your system? Does everybody else use a PHY which
does not implement this bit? Does your synthesis of the stmmac have a
different clock tree?

By changing this value for every instance of the stmmac, you are
potentially causing a power regression for stmmac implementations
which don't need the clock. So we need a clear understanding, stopping
the clock is wrong in general and so the change is correct in
general. Or this is specific to your system, and you probably need to
add priv->dma_cap.keep_rx_clock_ticking, which you set in your glue
driver,and use here to decide what to pass to phy_init_eee().

	   Andrew


From andrew at lunn.ch  Sun Jan 23 07:54:24 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 23 Jan 2022 16:54:24 +0100
Subject: [PATCH] net: dsa|ethernet: use bool values to pass bool param of
 phy_init_eee
In-Reply-To: <20220123152241.1480-1-jszhang@kernel.org>
References: <20220123152241.1480-1-jszhang@kernel.org>
Message-ID: <Ye16MDZ/Bp2KZcJq@lunn.ch>

On Sun, Jan 23, 2022 at 11:22:41PM +0800, Jisheng Zhang wrote:
> The 2nd param of phy_init_eee(): clk_stop_enable is a bool param, use
> true or false instead of 1/0.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From jszhang at kernel.org  Sun Jan 23 07:54:58 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Sun, 23 Jan 2022 23:54:58 +0800
Subject: [PATCH] net: stmmac: reduce unnecessary wakeups from eee sw timer
Message-ID: <20220123155458.2288-1-jszhang@kernel.org>

Currently, on EEE capable platforms, if EEE SW timer is used, the SW
timer cause 1 wakeup/s even if the TX has successfully entered EEE.
Remove this unnecessary wakeup by only calling mod_timer() if we
haven't successfully entered EEE.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 92a9b0b226b1..f1246df143da 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -402,7 +402,7 @@ static void stmmac_lpi_entry_timer_config(struct stmmac_priv *priv, bool en)
  * Description: this function is to verify and enter in LPI mode in case of
  * EEE.
  */
-static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
+static int stmmac_enable_eee_mode(struct stmmac_priv *priv)
 {
 	u32 tx_cnt = priv->plat->tx_queues_to_use;
 	u32 queue;
@@ -412,13 +412,14 @@ static void stmmac_enable_eee_mode(struct stmmac_priv *priv)
 		struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
 
 		if (tx_q->dirty_tx != tx_q->cur_tx)
-			return; /* still unfinished work */
+			return -EBUSY; /* still unfinished work */
 	}
 
 	/* Check and enter in LPI mode */
 	if (!priv->tx_path_in_lpi_mode)
 		stmmac_set_eee_mode(priv, priv->hw,
 				priv->plat->en_tx_lpi_clockgating);
+	return 0;
 }
 
 /**
@@ -450,8 +451,8 @@ static void stmmac_eee_ctrl_timer(struct timer_list *t)
 {
 	struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer);
 
-	stmmac_enable_eee_mode(priv);
-	mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
+	if (stmmac_enable_eee_mode(priv))
+		mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
 }
 
 /**
@@ -2647,8 +2648,8 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
 
 	if (priv->eee_enabled && !priv->tx_path_in_lpi_mode &&
 	    priv->eee_sw_timer_en) {
-		stmmac_enable_eee_mode(priv);
-		mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
+		if (stmmac_enable_eee_mode(priv))
+			mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(priv->tx_lpi_timer));
 	}
 
 	/* We still have pending packets, let's call for a new scheduling */
-- 
2.34.1



From gregkh at linuxfoundation.org  Sun Jan 23 08:14:17 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 23 Jan 2022 17:14:17 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 5.16-stable tree
Message-ID: <164295445788113@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 5.16-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-5.16 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-5.16/soc-imx-gpcv2-synchronously-suspend-mix-domains.patch
queue-5.16/crypto-stm32-cryp-fix-double-pm-exit.patch
queue-5.16/crypto-stm32-cryp-fix-bugs-and-crash-in-tests.patch
queue-5.16/drm-bridge-sn65dsi83-fix-bridge-removal.patch
queue-5.16/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From gregkh at linuxfoundation.org  Sun Jan 23 08:14:43 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 23 Jan 2022 17:14:43 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 5.15-stable tree
Message-ID: <164295448335135@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-5.15/soc-imx-gpcv2-synchronously-suspend-mix-domains.patch
queue-5.15/crypto-stm32-cryp-fix-double-pm-exit.patch
queue-5.15/crypto-stm32-cryp-fix-bugs-and-crash-in-tests.patch
queue-5.15/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From jszhang at kernel.org  Sun Jan 23 08:08:12 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Mon, 24 Jan 2022 00:08:12 +0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye15va7tFWMgKPEE@lunn.ch>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch>
Message-ID: <Ye19bHxcQ5Plx0v9@xhacker>

On Sun, Jan 23, 2022 at 04:52:29PM +0100, Andrew Lunn wrote:
> On Sun, Jan 23, 2022 at 10:12:45PM +0800, Jisheng Zhang wrote:
> > I met can't receive rx pkt issue with below steps:
> > 0.plug in ethernet cable then boot normal and get ip from dhcp server
> > 1.quickly hotplug out then hotplug in the ethernet cable
> > 2.trigger the dhcp client to renew lease
> > 
> > tcpdump shows that the request tx pkt is sent out successfully,
> > but the mac can't receive the rx pkt.
> > 
> > The issue can easily be reproduced on platforms with PHY_POLL external
> > phy. If we don't allow the phy to stop the RXC during LPI, the issue
> > is gone. I think it's unsafe to stop the RXC during LPI because the mac
> > needs RXC clock to support RX logic.
> > 
> > And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
> > false instead of 0.
> > 
> > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > ---
> >  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index 6708ca2aa4f7..92a9b0b226b1 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
> >  
> >  	stmmac_mac_set(priv, priv->ioaddr, true);
> >  	if (phy && priv->dma_cap.eee) {
> > -		priv->eee_active = phy_init_eee(phy, 1) >= 0;
> > +		priv->eee_active = phy_init_eee(phy, false) >= 0;
> 
> This has not caused issues in the past. So i'm wondering if this is
> somehow specific to your system? Does everybody else use a PHY which
> does not implement this bit? Does your synthesis of the stmmac have a
> different clock tree?
> 
> By changing this value for every instance of the stmmac, you are
> potentially causing a power regression for stmmac implementations
> which don't need the clock. So we need a clear understanding, stopping
> the clock is wrong in general and so the change is correct in

I think this is a common issue because the MAC needs phy's RXC for RX
logic. But it's better to let other stmmac users verify. The issue
can easily be reproduced on platforms with PHY_POLL external phy.
Or other platforms use a dedicated clock rather than clock from phy
for MAC's RX logic?

If the issue turns out specific to my system, then I will send out
a new patch to adopt your suggestion.

Hi Joakim, IIRC, you have stmmac + external RTL8211F phy platform, but
I'm not sure whether your platform have an irq for the phy. could you
help me to check whether you can reproduce the issue on your platform?

> general. Or this is specific to your system, and you probably need to
> add priv->dma_cap.keep_rx_clock_ticking, which you set in your glue
> driver,and use here to decide what to pass to phy_init_eee().

Thanks a lot for the suggestion.


From alim.akhtar at gmail.com  Sun Jan 23 08:16:28 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Sun, 23 Jan 2022 21:46:28 +0530
Subject: [PATCH] ARM: dts: exynos: use define for TMU clock on Exynos4412
In-Reply-To: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>
References: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ53gMpmxtxjk5K0PsZYUxTC9W9Y1vNOU1aY9WgdG1-c0Hw@mail.gmail.com>

Hi Krzysztof

On Sun, Jan 23, 2022 at 8:42 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Replace clock hard-coded number with a define from bindings.  No
> functional change.
>
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>


>  arch/arm/boot/dts/exynos4412.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/exynos4412.dtsi b/arch/arm/boot/dts/exynos4412.dtsi
> index d3802046c8b8..aa0b61b59970 100644
> --- a/arch/arm/boot/dts/exynos4412.dtsi
> +++ b/arch/arm/boot/dts/exynos4412.dtsi
> @@ -813,7 +813,7 @@ &tmu {
>         interrupt-parent = <&combiner>;
>         interrupts = <2 4>;
>         reg = <0x100C0000 0x100>;
> -       clocks = <&clock 383>;
> +       clocks = <&clock CLK_TMU_APBIF>;
>         clock-names = "tmu_apbif";
>         status = "disabled";
>  };
> --
> 2.32.0
>


-- 
Regards,
Alim


From jszhang at kernel.org  Sun Jan 23 08:09:34 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Mon, 24 Jan 2022 00:09:34 +0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye19bHxcQ5Plx0v9@xhacker>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
Message-ID: <Ye19vpFWXR8wJQVH@xhacker>

On Mon, Jan 24, 2022 at 12:08:22AM +0800, Jisheng Zhang wrote:
> On Sun, Jan 23, 2022 at 04:52:29PM +0100, Andrew Lunn wrote:
> > On Sun, Jan 23, 2022 at 10:12:45PM +0800, Jisheng Zhang wrote:
> > > I met can't receive rx pkt issue with below steps:
> > > 0.plug in ethernet cable then boot normal and get ip from dhcp server
> > > 1.quickly hotplug out then hotplug in the ethernet cable
> > > 2.trigger the dhcp client to renew lease
> > > 
> > > tcpdump shows that the request tx pkt is sent out successfully,
> > > but the mac can't receive the rx pkt.
> > > 
> > > The issue can easily be reproduced on platforms with PHY_POLL external
> > > phy. If we don't allow the phy to stop the RXC during LPI, the issue
> > > is gone. I think it's unsafe to stop the RXC during LPI because the mac
> > > needs RXC clock to support RX logic.
> > > 
> > > And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
> > > false instead of 0.
> > > 
> > > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > > ---
> > >  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > index 6708ca2aa4f7..92a9b0b226b1 100644
> > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > @@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
> > >  
> > >  	stmmac_mac_set(priv, priv->ioaddr, true);
> > >  	if (phy && priv->dma_cap.eee) {
> > > -		priv->eee_active = phy_init_eee(phy, 1) >= 0;
> > > +		priv->eee_active = phy_init_eee(phy, false) >= 0;
> > 
> > This has not caused issues in the past. So i'm wondering if this is
> > somehow specific to your system? Does everybody else use a PHY which
> > does not implement this bit? Does your synthesis of the stmmac have a
> > different clock tree?
> > 
> > By changing this value for every instance of the stmmac, you are
> > potentially causing a power regression for stmmac implementations
> > which don't need the clock. So we need a clear understanding, stopping
> > the clock is wrong in general and so the change is correct in
> 
> I think this is a common issue because the MAC needs phy's RXC for RX
> logic. But it's better to let other stmmac users verify. The issue
> can easily be reproduced on platforms with PHY_POLL external phy.
> Or other platforms use a dedicated clock rather than clock from phy
> for MAC's RX logic?
> 
> If the issue turns out specific to my system, then I will send out
> a new patch to adopt your suggestion.
>

+ Joakim

> Hi Joakim, IIRC, you have stmmac + external RTL8211F phy platform, but
> I'm not sure whether your platform have an irq for the phy. could you
> help me to check whether you can reproduce the issue on your platform?
> 
> > general. Or this is specific to your system, and you probably need to
> > add priv->dma_cap.keep_rx_clock_ticking, which you set in your glue
> > driver,and use here to decide what to pass to phy_init_eee().
> 
> Thanks a lot for the suggestion.


From gregkh at linuxfoundation.org  Sun Jan 23 08:17:06 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 23 Jan 2022 17:17:06 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 5.4-stable tree
Message-ID: <1642954626244228@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -230,7 +230,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -252,7 +252,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-5.4/crypto-stm32-cryp-fix-double-pm-exit.patch
queue-5.4/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From gregkh at linuxfoundation.org  Sun Jan 23 08:17:22 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Sun, 23 Jan 2022 17:17:22 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 5.10-stable tree
Message-ID: <1642954642151148@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-5.10/crypto-stm32-cryp-fix-double-pm-exit.patch
queue-5.10/crypto-stm32-cryp-fix-bugs-and-crash-in-tests.patch
queue-5.10/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From marex at denx.de  Sun Jan 23 08:22:40 2022
From: marex at denx.de (Marek Vasut)
Date: Sun, 23 Jan 2022 17:22:40 +0100
Subject: [PATCH] crypto: stm32/crc32 - Fix kernel BUG triggered in probe()
In-Reply-To: <16429542415161@kroah.com>
References: <16429542415161@kroah.com>
Message-ID: <20220123162240.5532-1-marex@denx.de>

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
---
Backport on 4.19.225, likely works on 4.14 too.
The patch likely failed to apply because the hit 5.3:
fdbd643a74efb ("crypto: stm32/crc32 - rename driver file")
and renamed drivers/crypto/stm32/stm32{-,_}crc32.c
---
 drivers/crypto/stm32/stm32_crc32.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/stm32/stm32_crc32.c b/drivers/crypto/stm32/stm32_crc32.c
index 47d31335c2d42..6848f34a9e66a 100644
--- a/drivers/crypto/stm32/stm32_crc32.c
+++ b/drivers/crypto/stm32/stm32_crc32.c
@@ -230,7 +230,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -252,7 +252,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
-- 
2.34.1



From julian at pidancet.net  Sun Jan 23 08:19:19 2022
From: julian at pidancet.net (Julian Pidancet)
Date: Sun, 23 Jan 2022 17:19:19 +0100
Subject: [PATCH v2] rockchip: rk3328: add support for FriendlyARM NanoPi NEO3
Message-ID: <20220123161919.1024653-1-julian@pidancet.net>

This patch adds support for FriendlyARM NanoPi NEO3

Soc:      RockChip RK3328
RAM:      1GB/2GB DDR4
LAN:      10/100/1000M Ethernet with unique MAC
USB Host: 1x USB3.0 Type A and 2x USB2.0 on 2.54mm pin header
MicroSD:  x 1 for system boot and storage
LED:      Power LED x 1, System LED x 1
Key:      User Button x 1
Fan:      2 Pin JST ZH 1.5mm Connector for 5V Fan
GPIO:     26 pin-header, include I2C, UART, SPI, I2S, GPIO
Power:    5V/1A, via Type-C or GPIO

Signed-off-by: Julian Pidancet <julian at pidancet.net>
---

This is another shot at previous work submitted by Marty Jones
<mj8263788 at gmail.com> (https://lore.kernel.org/linux-arm-kernel/20201228152836.02795e09.mj8263788 at gmail.com/),
which is now a year old.

v2: Following up on Robin Murphy's comments, the NEO3 DTS is now
standalone and no longer includes the nanopi R2S one. The lan_led and
wan_len nodes have been removed, and the sys_led node has been renamed
to stat_led in accordance with the board schematics.

 arch/arm64/boot/dts/rockchip/Makefile         |   1 +
 .../boot/dts/rockchip/rk3328-nanopi-neo3.dts  | 396 ++++++++++++++++++
 2 files changed, 397 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3a..5f6ffb496 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-odroid-go2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-a1.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-evb.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-neo3.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock-pi-e.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-roc-cc.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts
new file mode 100644
index 000000000..1eb7fd5f7
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3328-nanopi-neo3.dts
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2020 David Bauer <mail at david-bauer.net>
+ * Copyright (c) 2022 Julian Pidancet <julian at pidancet.net>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "rk3328.dtsi"
+
+/ {
+	model = "FriendlyElec NanoPi NEO3";
+	compatible = "friendlyarm,nanopi-neo3", "rockchip,rk3328";
+
+	aliases {
+		led-boot = &stat_led;
+		led-failsafe = &stat_led;
+		led-running = &stat_led;
+		led-upgrade = &stat_led;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	gmac_clk: gmac-clock {
+		compatible = "fixed-clock";
+		clock-frequency = <125000000>;
+		clock-output-names = "gmac_clkin";
+		#clock-cells = <0>;
+	};
+
+	keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&reset_button_pin>;
+		pinctrl-names = "default";
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_RESTART>;
+			debounce-interval = <50>;
+		};
+	};
+
+	vcc_rtl8153: vcc-rtl8153-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio2 RK_PC6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&rtl8153_en_drv>;
+		regulator-always-on;
+		regulator-name = "vcc_rtl8153";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&stat_led_pin>;
+		pinctrl-names = "default";
+
+		stat_led: led-0 {
+			gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+			label = "nanopi-neo3:green:stat";
+		};
+	};
+
+	vcc_io_sdio: sdmmcio-regulator {
+		compatible = "regulator-gpio";
+		enable-active-high;
+		gpios = <&gpio1 RK_PD4 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&sdio_vcc_pin>;
+		pinctrl-names = "default";
+		regulator-name = "vcc_io_sdio";
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <3300000>;
+		regulator-settling-time-us = <5000>;
+		regulator-type = "voltage";
+		startup-delay-us = <2000>;
+		states = <1800000 0x1>,
+			 <3300000 0x0>;
+		vin-supply = <&vcc_io_33>;
+	};
+
+	vcc_sd: sdmmc-regulator {
+		compatible = "regulator-fixed";
+		gpio = <&gpio0 RK_PD6 GPIO_ACTIVE_LOW>;
+		pinctrl-0 = <&sdmmc0m1_pin>;
+		pinctrl-names = "default";
+		regulator-name = "vcc_sd";
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_io_33>;
+	};
+
+	vdd_5v: vdd-5v {
+		compatible = "regulator-fixed";
+		regulator-name = "vdd_5v";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_arm>;
+};
+
+&display_subsystem {
+	status = "disabled";
+};
+
+&gmac2io {
+	assigned-clocks = <&cru SCLK_MAC2IO>, <&cru SCLK_MAC2IO_EXT>;
+	assigned-clock-parents = <&gmac_clk>, <&gmac_clk>;
+	clock_in_out = "input";
+	phy-handle = <&rtl8211e>;
+	phy-mode = "rgmii";
+	phy-supply = <&vcc_io_33>;
+	pinctrl-0 = <&rgmiim1_pins>;
+	pinctrl-names = "default";
+	rx_delay = <0x18>;
+	snps,aal;
+	tx_delay = <0x24>;
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rtl8211e: ethernet-phy at 1 {
+			reg = <1>;
+			pinctrl-0 = <&eth_phy_reset_pin>;
+			pinctrl-names = "default";
+			reset-assert-us = <10000>;
+			reset-deassert-us = <50000>;
+			reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>;
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	rk805: pmic at 18 {
+		compatible = "rockchip,rk805";
+		reg = <0x18>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+		#clock-cells = <1>;
+		clock-output-names = "xin32k", "rk805-clkout2";
+		gpio-controller;
+		#gpio-cells = <2>;
+		pinctrl-0 = <&pmic_int_l>;
+		pinctrl-names = "default";
+		rockchip,system-power-controller;
+		wakeup-source;
+
+		vcc1-supply = <&vdd_5v>;
+		vcc2-supply = <&vdd_5v>;
+		vcc3-supply = <&vdd_5v>;
+		vcc4-supply = <&vdd_5v>;
+		vcc5-supply = <&vcc_io_33>;
+		vcc6-supply = <&vdd_5v>;
+
+		regulators {
+			vdd_log: DCDC_REG1 {
+				regulator-name = "vdd_log";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <712500>;
+				regulator-max-microvolt = <1450000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+
+			vdd_arm: DCDC_REG2 {
+				regulator-name = "vdd_arm";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <712500>;
+				regulator-max-microvolt = <1450000>;
+				regulator-ramp-delay = <12500>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <950000>;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-boot-on;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_io_33: DCDC_REG4 {
+				regulator-name = "vcc_io_33";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <3300000>;
+				};
+			};
+
+			vcc_18: LDO_REG1 {
+				regulator-name = "vcc_18";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vcc18_emmc: LDO_REG2 {
+				regulator-name = "vcc18_emmc";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1800000>;
+				};
+			};
+
+			vdd_10: LDO_REG3 {
+				regulator-name = "vdd_10";
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1000000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+					regulator-suspend-microvolt = <1000000>;
+				};
+			};
+		};
+	};
+
+	usb {
+		rtl8153_en_drv: rtl8153-en-drv {
+			rockchip,pins = <2 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+};
+
+&io_domains {
+	pmuio-supply = <&vcc_io_33>;
+	vccio1-supply = <&vcc_io_33>;
+	vccio2-supply = <&vcc18_emmc>;
+	vccio3-supply = <&vcc_io_sdio>;
+	vccio4-supply = <&vcc_18>;
+	vccio5-supply = <&vcc_io_33>;
+	vccio6-supply = <&vcc_io_33>;
+	status = "okay";
+};
+
+&pinctrl {
+	button {
+		reset_button_pin: reset-button-pin {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	ethernet-phy {
+		eth_phy_reset_pin: eth-phy-reset-pin {
+			rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+	};
+
+	leds {
+		stat_led_pin: stat-led-pin {
+			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
+	sd {
+		sdio_vcc_pin: sdio-vcc-pin {
+			rockchip,pins = <1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pwm2 {
+	status = "okay";
+};
+
+&sdmmc {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	disable-wp;
+	pinctrl-0 = <&sdmmc0_clk>, <&sdmmc0_cmd>, <&sdmmc0_dectn>, <&sdmmc0_bus4>;
+	pinctrl-names = "default";
+	sd-uhs-sdr12;
+	sd-uhs-sdr25;
+	sd-uhs-sdr50;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_sd>;
+	vqmmc-supply = <&vcc_io_sdio>;
+	status = "okay";
+};
+
+&tsadc {
+	rockchip,hw-tshut-mode = <0>;
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
+
+&u2phy {
+	status = "okay";
+};
+
+&u2phy_host {
+	status = "okay";
+};
+
+&u2phy_otg {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&usb20_otg {
+	status = "okay";
+	dr_mode = "host";
+};
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usbdrd3 {
+	status = "okay";
+};
+
+&usbdrd_dwc3 {
+	dr_mode = "host";
+	status = "okay";
+
+	usb-eth at 2 {
+		compatible = "realtek,rtl8153";
+		reg = <2>;
+
+		realtek,led-data = <0x87>;
+	};
+};
-- 
2.34.1



From pgwipeout at gmail.com  Sun Jan 23 08:50:39 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Sun, 23 Jan 2022 11:50:39 -0500
Subject: [PATCH 4/4] arm64: dts: rockchip: enable the pine64 touch screen
 on rockpro64
In-Reply-To: <5747938.922zgog0jt@phil>
References: <20220107051335.3812535-1-pgwipeout@gmail.com>
 <20220107051335.3812535-5-pgwipeout@gmail.com>
 <5747938.922zgog0jt@phil>
Message-ID: <CAMdYzYrByfe6s3oKvJDN3skGXh7x=YSxQ4BKwySKhPzyEUEGQA@mail.gmail.com>

On Sun, Jan 23, 2022 at 10:30 AM Heiko Stuebner <heiko at sntech.de> wrote:
>
> Hi Peter,
>
> Am Freitag, 7. Januar 2022, 06:13:35 CET schrieb Peter Geis:
> > Enable the touch screen, backlight, and dsi nodes for the Pine64 touch panel
> > attached to the rockpro64.
>
> can you please also include me in the other patches of the series?
> I.e. they introduce a new property for the display, so it's nice to know
> when they get applied.

Apologies, I use get-maintainers.pl automatically and it seems to need
some help with tagging you in some Rockchip elements.
I'll be sure to always manually include you and the rockchip mailing
list on all patches in future series of this sort.

>
> While I do agree with patch 3/4, I'm hesistant about this one.
> The display/touchscreen will probably not be connected on every rockpro64
> so what happens if it doesn't?

This was supposed to be tagged as Do-Not-Merge, but it seems I failed
to do so on the actual patch.
It's here for purely completeness and testing purposes.

>
> I.e are there alternative uses for the affected pins, that may get fried
> when this is always enabled?
>
> So part of me would think that an dt-overlay enabling this might be the
> nicer way to go?

Absolutely.

>
>
> Heiko

Thanks,
Peter

>
>
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > index 158befb9a48c..f6c36fcd6db3 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
> > @@ -26,7 +26,7 @@ backlight: backlight {
> >               pwms = <&pwm0 0 1000000 0>;
> >               brightness-levels = <0 4 8 16 32 64 128 255>;
> >               default-brightness-level = <5>;
> > -             status = "disabled";
> > +             status = "okay";
> >       };
> >
> >       clkin_gmac: external-gmac-clock {
> > @@ -594,7 +594,7 @@ touch: touchscreen at 5d {
> >               interrupts = <RK_PD5 IRQ_TYPE_EDGE_FALLING>;
> >               irq-gpios = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
> >               reset-gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
> > -             status = "disabled";
> > +             status = "okay";
> >       };
> >  };
> >
> > @@ -633,7 +633,7 @@ &io_domains {
> >
> >  /* enable for pine64 panel display support */
> >  &mipi_dsi {
> > -     status = "disabled";
> > +     status = "okay";
> >       clock-master;
> >
> >       ports {
> >
>
>
>
>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:09:24 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:09:24 +0100
Subject: [PATCH v2 00/28] pinctrl: dt-bindings: samsung: convert to
 dtschema
In-Reply-To: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
References: <20220111201426.326777-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164293835975.31601.16562955007803362485.b4-ty@canonical.com>

On Tue, 11 Jan 2022 21:13:58 +0100, Krzysztof Kozlowski wrote:
> Changes since v1
> ================
> 1. Patch #1: add missing pin assignment (Alim).
> 2. Patch #2: correct double sizeof() (Alim).
> 3. Patch #7, #8: put label-override in proper patch (Alim).
> 4. Patch #24: Extend doc, change the 'if' clause for wake-up interrupts.
> 5. New patches: #25 - #28.
>    Exynos850 and ExynosAutov9 seems to be different in pin ctrl interrupt
>    handling, so they need their own compatibles.
>    Please kindly review and provide feedback on these as I do not have
>    details.
> 6. Add review tags.
> 
> [...]

Applied, thanks!

To Samsung SoC tree (Exynos850 is skipped because it was not merged into
v5.17-rc1):

[03/28] ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
        (no commit info)
[04/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
        (no commit info)
[05/28] ARM: dts: exynos: override pins by label in Peach Pit
        (no commit info)
[06/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
        (no commit info)
[07/28] ARM: dts: exynos: override pins by label in Peach Pi
        (no commit info)
[08/28] ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
        (no commit info)
[09/28] ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
        (no commit info)
[10/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
        (no commit info)
[11/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
        (no commit info)
[12/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
        (no commit info)
[13/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
        (no commit info)
[14/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
        (no commit info)
[15/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
        (no commit info)
[16/28] ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
        (no commit info)
[17/28] arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
        (no commit info)
[18/28] arm64: dts: exynos: align pinctrl with dtschema in Exynos7
        (no commit info)
[20/28] arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
        (no commit info)
[21/28] ARM: dts: s3c24xx: align pinctrl with dtschema
        (no commit info)
[22/28] ARM: dts: s3c64xx: align pinctrl with dtschema
        (no commit info)
[23/28] ARM: dts: s5pv210: align pinctrl with dtschema
        (no commit info)
[28/28] arm64: dts: exynos: use dedicated wake-up pinctrl compatible in ExynosAutov9
        (no commit info)

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:09:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:09:30 +0100
Subject: (subset) [PATCH 1/3] ARM: dts: exynos: drop unsupported MAX77802
 regulators on Odroid XU
In-Reply-To: <20211228164305.35877-2-krzysztof.kozlowski@canonical.com>
References: <20211228164305.35877-1-krzysztof.kozlowski@canonical.com>
 <20211228164305.35877-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777264.25838.6589941658920976244.b4-ty@canonical.com>

On Tue, 28 Dec 2021 17:43:03 +0100, Krzysztof Kozlowski wrote:
> The numbering of regulators is not continuous and the MAX77802 does not
> support regulators LDO16, LDO22 and LDO31.
> 
> 

Applied, thanks!

[1/3] ARM: dts: exynos: drop unsupported MAX77802 regulators on Odroid XU
      commit: 0d42eb5ac66d816c95573135951142483640181c

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:09:31 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:09:31 +0100
Subject: (subset) [PATCH 1/8] arm64: dts: exynos: add necessary clock
 inputs in Exynos7
In-Reply-To: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777264.25838.3443202173947810601.b4-ty@canonical.com>

On Sun, 2 Jan 2022 12:53:49 +0100, Krzysztof Kozlowski wrote:
> Exynos7 devicetree bindings require more input clocks for TOP0 and
> PERIC1 clock controllers, than already provided.  Existing DTS was not
> matching the bindings, so let's update the DTS, even though the error
> could be in the bindings.
> 
> 

Applied, thanks!

[1/8] arm64: dts: exynos: add necessary clock inputs in Exynos7
      commit: 372d171cd9b472cff7852211195f211150bc27d2

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:35 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:35 +0100
Subject: (subset) [PATCH 2/8] ARM: dts: exynos: add necessary clock
 controller inputs in Exynos5260
In-Reply-To: <20220102115356.75796-2-krzysztof.kozlowski@canonical.com>
References: <20220102115356.75796-1-krzysztof.kozlowski@canonical.com>
 <20220102115356.75796-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777264.25838.15093344260237063219.b4-ty@canonical.com>

On Sun, 2 Jan 2022 12:53:50 +0100, Krzysztof Kozlowski wrote:
> Exynos5260 bindings require to feed clock controllers with certain clock
> inputs.  The IO clocks are expected to be provided by the board.  The
> PHY clocks are usually followed by mux which can choose between the PHY
> clock and main 24 MHz oscillator, so skip defining them and just use the
> latter one.
> 
> 
> [...]

Applied, thanks!

[2/8] ARM: dts: exynos: add necessary clock controller inputs in Exynos5260
      commit: 9eb8090f95e2ef8d19ebce6a77e87b26b56fc831

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:36 +0100
Subject: (subset) [PATCH v2 1/4] ARM: dts: exynos: Align MAX77836 nodes
 with dtschema on Monk and Rinato
In-Reply-To: <20220111174337.223320-2-krzysztof.kozlowski@canonical.com>
References: <20220111174337.223320-1-krzysztof.kozlowski@canonical.com>
 <20220111174337.223320-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777264.25838.2090071538223607341.b4-ty@canonical.com>

On Tue, 11 Jan 2022 18:43:34 +0100, Krzysztof Kozlowski wrote:
> The newly introduced dtschema for MAX77836 MUIC requires proper naming
> of extcon child node.
> 
> This should not have actual impact on MFD children driver binding,
> because the max77836 MFD driver uses compatibles.
> 
> 
> [...]

Applied, thanks!

[1/4] ARM: dts: exynos: Align MAX77836 nodes with dtschema on Monk and Rinato
      commit: 8d6f5af71e2ada6214df028441d479e1925e105b

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:37 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:37 +0100
Subject: (subset) [PATCH v2 1/5] arm64: dts: exynos: Align MAX77843 nodes
 with dtschema on TM2
In-Reply-To: <20220111174805.223732-2-krzysztof.kozlowski@canonical.com>
References: <20220111174805.223732-1-krzysztof.kozlowski@canonical.com>
 <20220111174805.223732-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777264.25838.6451252879069426520.b4-ty@canonical.com>

On Tue, 11 Jan 2022 18:48:01 +0100, Krzysztof Kozlowski wrote:
> The newly introduced dtschema for MAX77843 MUIC require the children to
> have proper naming and a port at 0 property.
> 
> This should not have actual impact on MFD children driver binding,
> because the max77843 MFD driver uses compatibles.  The port at 0 is
> disabled to avoid any impact.
> 
> [...]

Applied, thanks!

[1/5] arm64: dts: exynos: Align MAX77843 nodes with dtschema on TM2
      commit: 7638d3c945beb6c781acf5dd0a78e04c76f1c32f

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:38 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:38 +0100
Subject: (subset) [PATCH v5 1/4] ARM: dts: exynos: split dmas into array
 of phandles in Exynos5250
In-Reply-To: <20220120175747.43403-2-krzysztof.kozlowski@canonical.com>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
 <20220120175747.43403-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777263.25838.3565314490773058737.b4-ty@canonical.com>

On Thu, 20 Jan 2022 18:57:44 +0100, Krzysztof Kozlowski wrote:
> "dmas" property should be rather an array of phandles, as dtschema
> points.
> 
> 

Applied, thanks!

[1/4] ARM: dts: exynos: split dmas into array of phandles in Exynos5250
      commit: 88829baee3db050a06fd5ce8a2be0c39992f90da

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:39 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:39 +0100
Subject: (subset) [RFT][PATCH 1/3] ARM: dts: exynos: fix UART3 pins
 configuration in Exynos5250
In-Reply-To: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
References: <20211230195325.328220-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164295777263.25838.13469745668860262642.b4-ty@canonical.com>

On Thu, 30 Dec 2021 20:53:23 +0100, Krzysztof Kozlowski wrote:
> The gpa1-4 pin was put twice in UART3 pin configuration of Exynos5250,
> instead of proper pin gpa1-5.
> 
> 

Applied, thanks!

[1/3] ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
      commit: 372d7027fed43c8570018e124cf78b89523a1f8e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sun Jan 23 09:10:40 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 18:10:40 +0100
Subject: [PATCH v2] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
In-Reply-To: <20220114144606.24358-1-semen.protsenko@linaro.org>
References: <20220114144606.24358-1-semen.protsenko@linaro.org>
Message-ID: <164295777264.25838.905366806236166301.b4-ty@canonical.com>

On Fri, 14 Jan 2022 16:46:06 +0200, Sam Protsenko wrote:
> The proper name is Exynos Auto V9, not V0. It was the typo slipped in
> unnoticed, fix it.
> 
> 

Applied, thanks!

[1/1] soc: samsung: Fix typo in CONFIG_EXYNOS_USI description
      commit: 442b0c08db7e35980bed6af091877f4dda72ffca

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From stefan.wahren at i2se.com  Sun Jan 23 09:32:15 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun, 23 Jan 2022 18:32:15 +0100
Subject: [PATCH v3] staging: vc04_services: Fix RCU dereference check
In-Reply-To: <20211231195406.5479-1-treasure4paddy@gmail.com>
References: <20211231185611.GA4463@pswork>
 <20211231195406.5479-1-treasure4paddy@gmail.com>
Message-ID: <7b0ce9d5-a278-3892-8d4a-905ca15e1edf@i2se.com>

Am 31.12.21 um 20:54 schrieb Padmanabha Srinivasaiah:
> In service_callback path RCU dereferenced pointer struct vchiq_service
> need to be accessed inside rcu read-critical section.
>
> Also userdata/user_service part of vchiq_service is accessed around
> different synchronization mechanism, getting an extra reference to a
> pointer keeps sematics simpler and avoids prolonged graceperiod.
>
> Accessing vchiq_service with rcu_read_[lock/unlock] fixes below issue.
>
> [   32.201659] =============================
> [   32.201664] WARNING: suspicious RCU usage
> [   32.201670] 5.15.11-rt24-v8+ #3 Not tainted
> [   32.201680] -----------------------------
> [   32.201685] drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h:529 suspicious rcu_dereference_check() usage!
> [   32.201695]
> [   32.201695] other info that might help us debug this:
> [   32.201695]
> [   32.201700]
> [   32.201700] rcu_scheduler_active = 2, debug_locks = 1
> [   32.201708] no locks held by vchiq-slot/0/98.
> [   32.201715]
> [   32.201715] stack backtrace:
> [   32.201723] CPU: 1 PID: 98 Comm: vchiq-slot/0 Not tainted 5.15.11-rt24-v8+ #3
> [   32.201733] Hardware name: Raspberry Pi 4 Model B Rev 1.4 (DT)
> [   32.201739] Call trace:
> [   32.201742]  dump_backtrace+0x0/0x1b8
> [   32.201772]  show_stack+0x20/0x30
> [   32.201784]  dump_stack_lvl+0x8c/0xb8
> [   32.201799]  dump_stack+0x18/0x34
> [   32.201808]  lockdep_rcu_suspicious+0xe4/0xf8
> [   32.201817]  service_callback+0x124/0x400
> [   32.201830]  slot_handler_func+0xf60/0x1e20
> [   32.201839]  kthread+0x19c/0x1a8
> [   32.201849]  ret_from_fork+0x10/0x20
>
> Signed-off-by: Padmanabha Srinivasaiah <treasure4paddy at gmail.com>

Tested-by: Stefan Wahren <stefan.wahren at i2se.com>

Thanks



From andrew at lunn.ch  Sun Jan 23 09:39:26 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Sun, 23 Jan 2022 18:39:26 +0100
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye19bHxcQ5Plx0v9@xhacker>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
Message-ID: <Ye2SznI2rNKAUDIq@lunn.ch>

> I think this is a common issue because the MAC needs phy's RXC for RX
> logic. But it's better to let other stmmac users verify. The issue
> can easily be reproduced on platforms with PHY_POLL external phy.

What is the relevance of PHY polling here? Are you saying if the PHY
is using interrupts you do not see this issue?

     Andrew


From f.fainelli at gmail.com  Sun Jan 23 10:29:49 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Sun, 23 Jan 2022 10:29:49 -0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye19vpFWXR8wJQVH@xhacker>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
 <Ye19vpFWXR8wJQVH@xhacker>
Message-ID: <22aac4ec-2a22-42ee-20ee-9e9d6097b9d9@gmail.com>



On 1/23/2022 8:09 AM, Jisheng Zhang wrote:
> On Mon, Jan 24, 2022 at 12:08:22AM +0800, Jisheng Zhang wrote:
>> On Sun, Jan 23, 2022 at 04:52:29PM +0100, Andrew Lunn wrote:
>>> On Sun, Jan 23, 2022 at 10:12:45PM +0800, Jisheng Zhang wrote:
>>>> I met can't receive rx pkt issue with below steps:
>>>> 0.plug in ethernet cable then boot normal and get ip from dhcp server
>>>> 1.quickly hotplug out then hotplug in the ethernet cable
>>>> 2.trigger the dhcp client to renew lease
>>>>
>>>> tcpdump shows that the request tx pkt is sent out successfully,
>>>> but the mac can't receive the rx pkt.
>>>>
>>>> The issue can easily be reproduced on platforms with PHY_POLL external
>>>> phy. If we don't allow the phy to stop the RXC during LPI, the issue
>>>> is gone. I think it's unsafe to stop the RXC during LPI because the mac
>>>> needs RXC clock to support RX logic.
>>>>
>>>> And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
>>>> false instead of 0.
>>>>
>>>> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
>>>> ---
>>>>   drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
>>>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> index 6708ca2aa4f7..92a9b0b226b1 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> @@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
>>>>   
>>>>   	stmmac_mac_set(priv, priv->ioaddr, true);
>>>>   	if (phy && priv->dma_cap.eee) {
>>>> -		priv->eee_active = phy_init_eee(phy, 1) >= 0;
>>>> +		priv->eee_active = phy_init_eee(phy, false) >= 0;
>>>
>>> This has not caused issues in the past. So i'm wondering if this is
>>> somehow specific to your system? Does everybody else use a PHY which
>>> does not implement this bit? Does your synthesis of the stmmac have a
>>> different clock tree?
>>>
>>> By changing this value for every instance of the stmmac, you are
>>> potentially causing a power regression for stmmac implementations
>>> which don't need the clock. So we need a clear understanding, stopping
>>> the clock is wrong in general and so the change is correct in
>>
>> I think this is a common issue because the MAC needs phy's RXC for RX
>> logic. But it's better to let other stmmac users verify. The issue
>> can easily be reproduced on platforms with PHY_POLL external phy.
>> Or other platforms use a dedicated clock rather than clock from phy
>> for MAC's RX logic?
>>
>> If the issue turns out specific to my system, then I will send out
>> a new patch to adopt your suggestion.
>>
> 
> + Joakim
> 
>> Hi Joakim, IIRC, you have stmmac + external RTL8211F phy platform, but
>> I'm not sure whether your platform have an irq for the phy. could you
>> help me to check whether you can reproduce the issue on your platform?
>>
>>> general. Or this is specific to your system, and you probably need to
>>> add priv->dma_cap.keep_rx_clock_ticking, which you set in your glue
>>> driver,and use here to decide what to pass to phy_init_eee().

I suspect the problem is only or largely relevant in a RGMII 
configuration whereby the TXC of the MAC is an input to the PHY which 
then re-generates the RXC and feeds it back to the MAC as RXC (with the 
configured delay). If the PHY stops its clock, then MAC no longer gets a 
RXC and all sorts of problems would arise if the MAC logic on the RX 
side is dependent upon getting the PHY's RXC to be re-sampled internally 
within the MAC.

Now, this would be symptomatic of a fairly naive design on the MAC side 
to support EEE, also usually to really save power while in LPI you would 
want to switch your MAC from its main or fast clock (which is presumably 
at least 250MHz to support Gigabit rates and generate a 125MHz TXC) to a 
slow clock (say 25 or 27MHz) in order to actually save power on the MAC 
side (even if the bulk of the power is on the PHY's analog logic). When 
the PHY signals that we are out of LPI the MAC switches back to its main 
clock. This may occur with the help of the MAC driver, or this can be 
done autonomously sometimes.

So with all that theory and how should things be designed and so on, I 
think you need to investigate this problem a bit more thoroughly.

FWIW phy_init_eee()'s second argument is improperly designed. Before 
deciding to stop the PHY's RX clock, you should first know whether the 
PHY supports it to begin with, otherwise you are requesting something 
the is not able to do, and there is no feedback mechanism. A while back 
I had started this patch series which may still be relevant:

https://github.com/ffainelli/linux/commits/phy-eee-tx-clk
-- 
Florian


From yury.norov at gmail.com  Sun Jan 23 10:38:42 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Sun, 23 Jan 2022 10:38:42 -0800
Subject: [PATCH 11/54] perf: replace bitmap_weight with bitmap_empty where
 appropriate
In-Reply-To: <20220123183925.1052919-1-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
Message-ID: <20220123183925.1052919-12-yury.norov@gmail.com>

In some places, drivers/perf code calls bitmap_weight() to check if any
bit of a given bitmap is set. It's better to use bitmap_empty() in that
case because bitmap_empty() stops traversing the bitmap as soon as it
finds first set bit, while bitmap_weight() counts all bits unconditionally.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 drivers/perf/arm-cci.c                   | 2 +-
 drivers/perf/arm_pmu.c                   | 4 ++--
 drivers/perf/hisilicon/hisi_uncore_pmu.c | 2 +-
 drivers/perf/xgene_pmu.c                 | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
index 54aca3a62814..96e09fa40909 100644
--- a/drivers/perf/arm-cci.c
+++ b/drivers/perf/arm-cci.c
@@ -1096,7 +1096,7 @@ static void cci_pmu_enable(struct pmu *pmu)
 {
 	struct cci_pmu *cci_pmu = to_cci_pmu(pmu);
 	struct cci_pmu_hw_events *hw_events = &cci_pmu->hw_events;
-	int enabled = bitmap_weight(hw_events->used_mask, cci_pmu->num_cntrs);
+	bool enabled = !bitmap_empty(hw_events->used_mask, cci_pmu->num_cntrs);
 	unsigned long flags;
 
 	if (!enabled)
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 295cc7952d0e..a31b302b0ade 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -524,7 +524,7 @@ static void armpmu_enable(struct pmu *pmu)
 {
 	struct arm_pmu *armpmu = to_arm_pmu(pmu);
 	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
-	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+	bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events);
 
 	/* For task-bound events we may be called on other CPUs */
 	if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
@@ -785,7 +785,7 @@ static int cpu_pm_pmu_notify(struct notifier_block *b, unsigned long cmd,
 {
 	struct arm_pmu *armpmu = container_of(b, struct arm_pmu, cpu_pm_nb);
 	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
-	int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+	bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events);
 
 	if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus))
 		return NOTIFY_DONE;
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
index a738aeab5c04..358e4e284a62 100644
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
@@ -393,7 +393,7 @@ EXPORT_SYMBOL_GPL(hisi_uncore_pmu_read);
 void hisi_uncore_pmu_enable(struct pmu *pmu)
 {
 	struct hisi_pmu *hisi_pmu = to_hisi_pmu(pmu);
-	int enabled = bitmap_weight(hisi_pmu->pmu_events.used_mask,
+	bool enabled = !bitmap_empty(hisi_pmu->pmu_events.used_mask,
 				    hisi_pmu->num_counters);
 
 	if (!enabled)
diff --git a/drivers/perf/xgene_pmu.c b/drivers/perf/xgene_pmu.c
index 2b6d476bd213..88bd100a9633 100644
--- a/drivers/perf/xgene_pmu.c
+++ b/drivers/perf/xgene_pmu.c
@@ -867,7 +867,7 @@ static void xgene_perf_pmu_enable(struct pmu *pmu)
 {
 	struct xgene_pmu_dev *pmu_dev = to_pmu_dev(pmu);
 	struct xgene_pmu *xgene_pmu = pmu_dev->parent;
-	int enabled = bitmap_weight(pmu_dev->cntr_assign_mask,
+	bool enabled = !bitmap_empty(pmu_dev->cntr_assign_mask,
 			pmu_dev->max_counters);
 
 	if (!enabled)
-- 
2.30.2



From yury.norov at gmail.com  Sun Jan 23 10:38:47 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Sun, 23 Jan 2022 10:38:47 -0800
Subject: [PATCH 16/54] cpufreq: replace cpumask_weight with cpumask_empty
 where appropriate
In-Reply-To: <20220123183925.1052919-1-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
Message-ID: <20220123183925.1052919-17-yury.norov@gmail.com>

drivers/cpufreq calls cpumask_weight() to check if any bit of a given
cpumask is set. We can do it more efficiently with cpumask_empty() because
cpumask_empty() stops traversing the cpumask as soon as it finds first set
bit, while cpumask_weight() counts all bits unconditionally.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 drivers/cpufreq/qcom-cpufreq-hw.c | 2 +-
 drivers/cpufreq/scmi-cpufreq.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c
index 05f3d7876e44..95a0c57ab5bb 100644
--- a/drivers/cpufreq/qcom-cpufreq-hw.c
+++ b/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -482,7 +482,7 @@ static int qcom_cpufreq_hw_cpu_init(struct cpufreq_policy *policy)
 	}
 
 	qcom_get_related_cpus(index, policy->cpus);
-	if (!cpumask_weight(policy->cpus)) {
+	if (cpumask_empty(policy->cpus)) {
 		dev_err(dev, "Domain-%d failed to get related CPUs\n", index);
 		ret = -ENOENT;
 		goto error;
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c
index 1e0cd4d165f0..919fa6e3f462 100644
--- a/drivers/cpufreq/scmi-cpufreq.c
+++ b/drivers/cpufreq/scmi-cpufreq.c
@@ -154,7 +154,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy)
 	 * table and opp-shared.
 	 */
 	ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, priv->opp_shared_cpus);
-	if (ret || !cpumask_weight(priv->opp_shared_cpus)) {
+	if (ret || cpumask_empty(priv->opp_shared_cpus)) {
 		/*
 		 * Either opp-table is not set or no opp-shared was found.
 		 * Use the CPU mask from SCMI to designate CPUs sharing an OPP
-- 
2.30.2



From yury.norov at gmail.com  Sun Jan 23 10:39:05 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Sun, 23 Jan 2022 10:39:05 -0800
Subject: [PATCH 34/54] perf: replace bitmap_weight with bitmap_weight_eq for
 ThunderX2
In-Reply-To: <20220123183925.1052919-1-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
Message-ID: <20220123183925.1052919-35-yury.norov@gmail.com>

tx2_uncore_event_start() calls bitmap_weight() to compare the weight
of bitmap with a given number. We can do it more efficiently with
bitmap_weight_eq because conditional bitmap_weight may stop traversing
the bitmap earlier, as soon as condition is met.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 drivers/perf/thunderx2_pmu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index 05378c0fd8f3..ebfa66b212c7 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -623,8 +623,8 @@ static void tx2_uncore_event_start(struct perf_event *event, int flags)
 		return;
 
 	/* Start timer for first event */
-	if (bitmap_weight(tx2_pmu->active_counters,
-				tx2_pmu->max_counters) == 1) {
+	if (bitmap_weight_eq(tx2_pmu->active_counters,
+				tx2_pmu->max_counters, 1)) {
 		hrtimer_start(&tx2_pmu->hrtimer,
 			ns_to_ktime(tx2_pmu->hrtimer_interval),
 			HRTIMER_MODE_REL_PINNED);
-- 
2.30.2



From yury.norov at gmail.com  Sun Jan 23 10:39:13 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Sun, 23 Jan 2022 10:39:13 -0800
Subject: [PATCH 42/54] firmware: pcsi: replace cpumask_weight with
 cpumask_weight_eq
In-Reply-To: <20220123183925.1052919-1-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
Message-ID: <20220123183925.1052919-43-yury.norov@gmail.com>

down_and_up_cpus() calls cpumask_weight() to compare the weight of
cpumask with a given number. We can do it more efficiently with
cpumask_weight_{eq, ...} because conditional cpumask_weight may stop
traversing the cpumask earlier, as soon as condition is met.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 drivers/firmware/psci/psci_checker.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c
index 116eb465cdb4..90c9473832a9 100644
--- a/drivers/firmware/psci/psci_checker.c
+++ b/drivers/firmware/psci/psci_checker.c
@@ -90,7 +90,7 @@ static unsigned int down_and_up_cpus(const struct cpumask *cpus,
 		 * cpu_down() checks the number of online CPUs before the TOS
 		 * resident CPU.
 		 */
-		if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
+		if (cpumask_weight_eq(offlined_cpus, nb_available_cpus - 1)) {
 			if (ret != -EBUSY) {
 				pr_err("Unexpected return code %d while trying "
 				       "to power down last online CPU %d\n",
-- 
2.30.2



From yury.norov at gmail.com  Sun Jan 23 10:39:17 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Sun, 23 Jan 2022 10:39:17 -0800
Subject: [PATCH 46/54] soc: replace cpumask_weight with cpumask_weight_lt
In-Reply-To: <20220123183925.1052919-1-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
Message-ID: <20220123183925.1052919-47-yury.norov@gmail.com>

qman_test_stash() calls cpumask_weight() to compare the weight of
cpumask with a given number. We can do it more efficiently with
cpumask_weight_lt because conditional cpumask_weight may stop
traversing the cpumask earlier, as soon as condition is met.

Signed-off-by: Yury Norov <yury.norov at gmail.com>
---
 drivers/soc/fsl/qbman/qman_test_stash.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/qbman/qman_test_stash.c b/drivers/soc/fsl/qbman/qman_test_stash.c
index b7e8e5ec884c..28b08568a349 100644
--- a/drivers/soc/fsl/qbman/qman_test_stash.c
+++ b/drivers/soc/fsl/qbman/qman_test_stash.c
@@ -561,7 +561,7 @@ int qman_test_stash(void)
 {
 	int err;
 
-	if (cpumask_weight(cpu_online_mask) < 2) {
+	if (cpumask_weight_lt(cpu_online_mask, 2)) {
 		pr_info("%s(): skip - only 1 CPU\n", __func__);
 		return 0;
 	}
-- 
2.30.2



From krzysztof.kozlowski at canonical.com  Sun Jan 23 11:15:16 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 20:15:16 +0100
Subject: [PATCH v3 0/3] Add initial support for exynos5420-chagall-wifi
In-Reply-To: <20220118185746.299832-1-henrik@grimler.se>
References: <20220118185746.299832-1-henrik@grimler.se>
Message-ID: <164296530944.41526.610812018359584856.b4-ty@canonical.com>

On Tue, 18 Jan 2022 19:57:43 +0100, Henrik Grimler wrote:
> Samsung's tablet Galaxy Tab S 10.5" (wifi) has codename Chagall WiFi
> and is one of several tablets released in 2014 based on Exynos 5420.
> This initial devicetree adds support for accessing device over USB or
> UART, and allows using a rootfs in either the internal eMMC or an
> external sdcard.  4 out of 8 CPUs are brought up when device boots,
> which is the same as on the somewhat similar board
> exynos5420-arndale-octa.
> 
> [...]

Applied, thanks!

[1/3] dt-bindings: arm: samsung: document Chagall WiFi board binding
      commit: 9998104515d4197d774e5384df750c6384915707
[2/3] ARM: exynos: only do SMC_CMD_CPU1BOOT call on Exynos4
      commit: 534aaa1802eae339d0439feafe3c1217f5643b20
[3/3] ARM: dts: Add support for Samsung Chagall WiFi
      commit: 535f7fffed880312830c72d9c593b59ec741dd8e

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From alim.akhtar at samsung.com  Sun Jan 23 11:07:13 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:13 +0530
Subject: [PATCH v4 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
References: <CGME20220123191930epcas5p2572d936fab64a86238cab945171037d7@epcas5p2.samsung.com>
Message-ID: <20220123190729.1852-1-alim.akhtar@samsung.com>

Adds basic support for the Tesla Full Self-Driving (FSD)
SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
as well as several IPs.

Patches 1 to 9 provide support for the clock controller
(which is designed similarly to Exynos SoCs).

The remaining changes provide pinmux support, initial device tree support.

- Changes since v3
* Addressed Stefen's review comments on patch 14/16
* Fixed kernel test robot warning on patch 04/16
* rebsaed this series on Krzysztof's pinmux new binding schema work [1]

- Changes since v2
* Addressed Krzysztof's and Stephen's review comments
* Added Reviewed-by and Acked-by tags
* Rebased on next-20220120

- Changes since v1
* fixed make dt_binding_check error as pointed by Rob
* Addressed Krzysztof's and Rob's review comments
* Added Reviewed-by and Acked-by tags
* Dropped SPI, MCT and ADC from this series (to be posted in small sets)

NOTE: These patches are based on Krzysztof's pinmux for-next branch
      commit = 832ae134ccc1 
[1] https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/log/?h=for-next

Alim Akhtar (16):
  dt-bindings: add vendor prefix for Tesla
  dt-bindings: clock: Add bindings definitions for FSD CMU blocks
  dt-bindings: clock: Document FSD CMU bindings
  clk: samsung: fsd: Add initial clock support
  clk: samsung: fsd: Add cmu_peric block clock information
  clk: samsung: fsd: Add cmu_fsys0 clock information
  clk: samsung: fsd: Add cmu_fsys1 clock information
  clk: samsung: fsd: Add cmu_imem block clock information
  clk: samsung: fsd: Add cmu_mfc block clock information
  clk: samsung: fsd: Add cam_csi block clock information
  dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
  pinctrl: samsung: add FSD SoC specific data
  dt-bindings: arm: add Tesla FSD ARM SoC
  arm64: dts: fsd: Add initial device tree support
  arm64: dts: fsd: Add initial pinctrl support
  arm64: defconfig: Enable Tesla FSD SoC

 .../devicetree/bindings/arm/tesla.yaml        |   27 +
 .../bindings/clock/tesla,fsd-clock.yaml       |  198 ++
 .../bindings/pinctrl/samsung,pinctrl.yaml     |    1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    8 +
 arch/arm64/Kconfig.platforms                  |    6 +
 arch/arm64/boot/dts/Makefile                  |    1 +
 arch/arm64/boot/dts/tesla/Makefile            |    3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts         |   39 +
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  335 +++
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  673 ++++++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/clk/samsung/Kconfig                   |    8 +
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-fsd.c                 | 1803 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |    1 +
 drivers/clk/samsung/clk-pll.h                 |    1 +
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    |   71 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |    1 +
 include/dt-bindings/clock/fsd-clk.h           |  150 ++
 21 files changed, 3332 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
 create mode 100644 drivers/clk/samsung/clk-fsd.c
 create mode 100644 include/dt-bindings/clock/fsd-clk.h


base-commit: 832ae134ccc1c78a2f5ec81b7010dd24c3c49535
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:14 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:14 +0530
Subject: [PATCH v4 01/16] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191937epcas5p166cfe0edea93cfd2941002c8ceadea0f@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-2-alim.akhtar@samsung.com>

Add vendor prefix for the Tesla (https://www.tesla.com)

Cc: linux-fsd at tesla.com
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 294093d45a23..e7a362c17df7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1205,6 +1205,8 @@ patternProperties:
     description: Shenzhen Techstar Electronics Co., Ltd.
   "^terasic,.*":
     description: Terasic Inc.
+  "^tesla,.*":
+    description: Tesla, Inc.
   "^tfc,.*":
     description: Three Five Corp
   "^thead,.*":
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:15 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:15 +0530
Subject: [PATCH v4 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191941epcas5p11eb602b49b63fc16551939a3278e9271@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-3-alim.akhtar@samsung.com>

Clock controller driver of FSD platform is designed to have separate
instances for each particular CMU. So clock IDs in this bindings header
also start from 1 for each CMU block.

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
[robot: reported missing #endif]
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 include/dt-bindings/clock/fsd-clk.h | 150 ++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 include/dt-bindings/clock/fsd-clk.h

diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
new file mode 100644
index 000000000000..c8a2af1dd1ad
--- /dev/null
+++ b/include/dt-bindings/clock/fsd-clk.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * The constants defined in this header are being used in dts
+ * and fsd platform driver.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_FSD_H
+#define _DT_BINDINGS_CLOCK_FSD_H
+
+/* CMU */
+#define DOUT_CMU_PLL_SHARED0_DIV4		1
+#define DOUT_CMU_PERIC_SHARED1DIV36		2
+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
+#define DOUT_CMU_PERIC_SHARED0DIV20		4
+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
+#define DOUT_CMU_PLL_SHARED0_DIV6		6
+#define DOUT_CMU_FSYS0_SHARED1DIV4		7
+#define DOUT_CMU_FSYS0_SHARED0DIV4		8
+#define DOUT_CMU_FSYS1_SHARED0DIV8		9
+#define DOUT_CMU_FSYS1_SHARED0DIV4		10
+#define CMU_CPUCL_SWITCH_GATE			11
+#define DOUT_CMU_IMEM_TCUCLK			12
+#define DOUT_CMU_IMEM_ACLK			13
+#define DOUT_CMU_IMEM_DMACLK			14
+#define GAT_CMU_FSYS0_SHARED0DIV4		15
+#define CMU_NR_CLK				16
+
+/* PERIC */
+#define PERIC_SCLK_UART0			1
+#define PERIC_PCLK_UART0			2
+#define PERIC_SCLK_UART1			3
+#define PERIC_PCLK_UART1			4
+#define PERIC_DMA0_IPCLKPORT_ACLK		5
+#define PERIC_DMA1_IPCLKPORT_ACLK		6
+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
+#define PERIC_PCLK_SPI0                         9
+#define PERIC_SCLK_SPI0                         10
+#define PERIC_PCLK_SPI1                         11
+#define PERIC_SCLK_SPI1                         12
+#define PERIC_PCLK_SPI2                         13
+#define PERIC_SCLK_SPI2                         14
+#define PERIC_PCLK_TDM0                         15
+#define PERIC_PCLK_HSI2C0			16
+#define PERIC_PCLK_HSI2C1			17
+#define PERIC_PCLK_HSI2C2			18
+#define PERIC_PCLK_HSI2C3			19
+#define PERIC_PCLK_HSI2C4			20
+#define PERIC_PCLK_HSI2C5			21
+#define PERIC_PCLK_HSI2C6			22
+#define PERIC_PCLK_HSI2C7			23
+#define PERIC_MCAN0_IPCLKPORT_CCLK		24
+#define PERIC_MCAN0_IPCLKPORT_PCLK		25
+#define PERIC_MCAN1_IPCLKPORT_CCLK		26
+#define PERIC_MCAN1_IPCLKPORT_PCLK		27
+#define PERIC_MCAN2_IPCLKPORT_CCLK		28
+#define PERIC_MCAN2_IPCLKPORT_PCLK		29
+#define PERIC_MCAN3_IPCLKPORT_CCLK		30
+#define PERIC_MCAN3_IPCLKPORT_PCLK		31
+#define PERIC_PCLK_ADCIF			32
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
+#define PERIC_HCLK_TDM0				40
+#define PERIC_PCLK_TDM1				41
+#define PERIC_HCLK_TDM1				42
+#define PERIC_EQOS_PHYRXCLK_MUX			43
+#define PERIC_EQOS_PHYRXCLK			44
+#define PERIC_DOUT_RGMII_CLK			45
+#define PERIC_NR_CLK				46
+
+/* FSYS0 */
+#define UFS0_MPHY_REFCLK_IXTAL24		1
+#define UFS0_MPHY_REFCLK_IXTAL26		2
+#define UFS1_MPHY_REFCLK_IXTAL24		3
+#define UFS1_MPHY_REFCLK_IXTAL26		4
+#define UFS0_TOP0_HCLK_BUS			5
+#define UFS0_TOP0_ACLK				6
+#define UFS0_TOP0_CLK_UNIPRO			7
+#define UFS0_TOP0_FMP_CLK			8
+#define UFS1_TOP1_HCLK_BUS			9
+#define UFS1_TOP1_ACLK				10
+#define UFS1_TOP1_CLK_UNIPRO			11
+#define UFS1_TOP1_FMP_CLK			12
+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
+#define FSYS0_NR_CLK				23
+
+/* FSYS1 */
+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
+#define FSYS1_NR_CLK				9
+
+/* IMEM */
+#define IMEM_DMA0_IPCLKPORT_ACLK		1
+#define IMEM_DMA1_IPCLKPORT_ACLK		2
+#define IMEM_WDT0_IPCLKPORT_PCLK		3
+#define IMEM_WDT1_IPCLKPORT_PCLK		4
+#define IMEM_WDT2_IPCLKPORT_PCLK		5
+#define IMEM_MCT_PCLK				6
+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
+#define IMEM_NR_CLK				12
+
+/* MFC */
+#define MFC_MFC_IPCLKPORT_ACLK			1
+#define MFC_NR_CLK				2
+
+/* CAM_CSI */
+#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
+#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
+#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
+#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
+#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
+#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
+#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
+#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
+#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
+#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
+#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
+#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
+#define CAM_CSI_NR_CLK				13
+
+#endif /*_DT_BINDINGS_CLOCK_FSD_H */
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:16 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:16 +0530
Subject: [PATCH v4 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191945epcas5p48832df007e438be14b390a0a8dd97cde@epcas5p4.samsung.com>
Message-ID: <20220123190729.1852-4-alim.akhtar@samsung.com>

Add dt-schema documentation for Tesla FSD SoC clock controller.

Cc: linux-fsd at tesla.com
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../bindings/clock/tesla,fsd-clock.yaml       | 198 ++++++++++++++++++
 1 file changed, 198 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..dc808e2f8327
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+description: |
+  FSD clock controller consist of several clock management unit
+  (CMU), which generates clocks for various inteernal SoC blocks.
+  The root clock comes from external OSC clock (24 MHz).
+
+  All available clocks are defined as preprocessor macros in
+  'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+  compatible:
+    enum:
+      - tesla,fsd-clock-cmu
+      - tesla,fsd-clock-imem
+      - tesla,fsd-clock-peric
+      - tesla,fsd-clock-fsys0
+      - tesla,fsd-clock-fsys1
+      - tesla,fsd-clock-mfc
+      - tesla,fsd-clock-cam_csi
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  clock-names:
+    minItems: 1
+    maxItems: 6
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cmu
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-imem
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: IMEM TCU clock (from CMU_CMU)
+            - description: IMEM bus clock (from CMU_CMU)
+            - description: IMEM DMA clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_imem_tcuclk
+            - const: dout_cmu_imem_aclk
+            - const: dout_cmu_imem_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-peric
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div4 clock (from CMU_CMU)
+            - description: PERIC shared1 div36 clock (from CMU_CMU)
+            - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+            - description: PERIC shared0 div20 clock (from CMU_CMU)
+            - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div4
+            - const: dout_cmu_peric_shared1div36
+            - const: dout_cmu_peric_shared0div3_tbuclk
+            - const: dout_cmu_peric_shared0div20
+            - const: dout_cmu_peric_shared1div4_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys0
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div6 clock (from CMU_CMU)
+            - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+            - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div6
+            - const: dout_cmu_fsys0_shared1div4
+            - const: dout_cmu_fsys0_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys1
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+            - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_fsys1_shared0div8
+            - const: dout_cmu_fsys1_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-mfc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cam_csi
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_FSYS1
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+
+    clock_fsys1: clock-controller at 16810000 {
+          compatible = "tesla,fsd-clock-fsys1";
+          reg = <0x16810000 0x3000>;
+          #clock-cells = <1>;
+
+          clocks = <&fin_pll>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+          clock-names = "fin_pll",
+                        "dout_cmu_fsys1_shared0div8",
+                        "dout_cmu_fsys1_shared0div4";
+    };
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:17 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:17 +0530
Subject: [PATCH v4 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191949epcas5p1bf06904feb8fce6abc1dcbcef2d34b1a@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-5-alim.akhtar@samsung.com>

Add initial clock support for FSD (Full Self-Driving) SoC
which is required to bring-up platforms based on this SoC.

Also, fix the build error reported by the kernel test robot [1].

[1] https://lkml.org/lkml/2022/1/21/836

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/Kconfig   |   8 +
 drivers/clk/samsung/Makefile  |   1 +
 drivers/clk/samsung/clk-fsd.c | 310 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c |   1 +
 drivers/clk/samsung/clk-pll.h |   1 +
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-fsd.c

diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 0e18d6ff2916..5f64c58f120f 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG
 	select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
 	select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
 	select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
+	select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
 
 config S3C64XX_COMMON_CLK
 	bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,10 @@ config S3C2443_COMMON_CLK
 	help
 	  Support for the clock controller present on the Samsung
 	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+
+config TESLA_FSD_COMMON_CLK
+	bool "Tesla FSD clock controller support" if COMPILE_TEST
+	depends on COMMON_CLK_SAMSUNG
+	help
+	  Support for the clock controller present on the Tesla FSD SoC.
+	  Choose Y here only if you build for this SoC.
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 0df74916a895..17e5d1cb9da2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_S3C64XX_COMMON_CLK)	+= clk-s3c64xx.o
 obj-$(CONFIG_S5PV210_COMMON_CLK)	+= clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_TESLA_FSD_COMMON_CLK)	+= clk-fsd.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..ae35c4303b55
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * Common Clock Framework support for FSD SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/fsd-clk.h>
+
+#include "clk.h"
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0			0x0
+#define PLL_LOCKTIME_PLL_SHARED1			0x4
+#define PLL_LOCKTIME_PLL_SHARED2			0x8
+#define PLL_LOCKTIME_PLL_SHARED3			0xc
+#define PLL_CON0_PLL_SHARED0				0x100
+#define PLL_CON0_PLL_SHARED1				0x120
+#define PLL_CON0_PLL_SHARED2				0x140
+#define PLL_CON0_PLL_SHARED3				0x160
+#define MUX_CMU_CIS0_CLKMUX				0x1000
+#define MUX_CMU_CIS1_CLKMUX				0x1004
+#define MUX_CMU_CIS2_CLKMUX				0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX				0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX				0x1014
+#define MUX_PLL_SHARED0_MUX				0x1020
+#define MUX_PLL_SHARED1_MUX				0x1024
+#define DIV_CMU_CIS0_CLK				0x1800
+#define DIV_CMU_CIS1_CLK				0x1804
+#define DIV_CMU_CIS2_CLK				0x1808
+#define DIV_CMU_CMU_ACLK				0x180c
+#define DIV_CMU_CPUCL_SWITCH				0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4			0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3			0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4			0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4			0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8			0x182c
+#define DIV_CMU_IMEM_ACLK				0x1834
+#define DIV_CMU_IMEM_DMACLK				0x1838
+#define DIV_CMU_IMEM_TCUCLK				0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20			0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK		0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36			0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK		0x1850
+#define DIV_PLL_SHARED0_DIV2				0x1858
+#define DIV_PLL_SHARED0_DIV3				0x185c
+#define DIV_PLL_SHARED0_DIV4				0x1860
+#define DIV_PLL_SHARED0_DIV6				0x1864
+#define DIV_PLL_SHARED1_DIV3				0x1868
+#define DIV_PLL_SHARED1_DIV36				0x186c
+#define DIV_PLL_SHARED1_DIV4				0x1870
+#define DIV_PLL_SHARED1_DIV9				0x1874
+#define GAT_CMU_CIS0_CLKGATE				0x2000
+#define GAT_CMU_CIS1_CLKGATE				0x2004
+#define GAT_CMU_CIS2_CLKGATE				0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE			0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE			0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK			0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE			0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE			0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE			0x2028
+#define GAT_CMU_IMEM_ACLK_GATE				0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE			0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE			0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE		0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE			0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE		0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE			0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK			0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK		0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU	0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK		0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_CON0_PLL_SHARED0,
+	PLL_CON0_PLL_SHARED1,
+	PLL_CON0_PLL_SHARED2,
+	PLL_CON0_PLL_SHARED3,
+	MUX_CMU_CIS0_CLKMUX,
+	MUX_CMU_CIS1_CLKMUX,
+	MUX_CMU_CIS2_CLKMUX,
+	MUX_CMU_CPUCL_SWITCHMUX,
+	MUX_CMU_FSYS1_ACLK_MUX,
+	MUX_PLL_SHARED0_MUX,
+	MUX_PLL_SHARED1_MUX,
+	DIV_CMU_CIS0_CLK,
+	DIV_CMU_CIS1_CLK,
+	DIV_CMU_CIS2_CLK,
+	DIV_CMU_CMU_ACLK,
+	DIV_CMU_CPUCL_SWITCH,
+	DIV_CMU_FSYS0_SHARED0DIV4,
+	DIV_CMU_FSYS0_SHARED1DIV3,
+	DIV_CMU_FSYS0_SHARED1DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV8,
+	DIV_CMU_IMEM_ACLK,
+	DIV_CMU_IMEM_DMACLK,
+	DIV_CMU_IMEM_TCUCLK,
+	DIV_CMU_PERIC_SHARED0DIV20,
+	DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+	DIV_CMU_PERIC_SHARED1DIV36,
+	DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+	DIV_PLL_SHARED0_DIV2,
+	DIV_PLL_SHARED0_DIV3,
+	DIV_PLL_SHARED0_DIV4,
+	DIV_PLL_SHARED0_DIV6,
+	DIV_PLL_SHARED1_DIV3,
+	DIV_PLL_SHARED1_DIV36,
+	DIV_PLL_SHARED1_DIV4,
+	DIV_PLL_SHARED1_DIV9,
+	GAT_CMU_CIS0_CLKGATE,
+	GAT_CMU_CIS1_CLKGATE,
+	GAT_CMU_CIS2_CLKGATE,
+	GAT_CMU_CPUCL_SWITCH_GATE,
+	GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+	GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+	GAT_CMU_IMEM_ACLK_GATE,
+	GAT_CMU_IMEM_DMACLK_GATE,
+	GAT_CMU_IMEM_TCUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+	GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+	GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+	GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+	GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+	GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+	GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+	    PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+	    PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+	    PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+	    PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+	MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+	MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+	MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+	    MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+	MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+	DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+	DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+	DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+	    DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+	DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+	    DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+	    DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+	DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+	    DIV_CMU_IMEM_ACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+	    DIV_CMU_IMEM_DMACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+	    DIV_CMU_IMEM_TCUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+	    "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+	    "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+	    "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+	    "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV2, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV3, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+	    DIV_PLL_SHARED0_DIV4, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+	    DIV_PLL_SHARED0_DIV6, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV3, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+	    DIV_PLL_SHARED1_DIV36, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV4, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+	    DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+	GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+	     GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+	     GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+	     GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+	     GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+	     GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+	     GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+	     GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+	.pll_clks		= cmu_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cmu_pll_clks),
+	.mux_clks		= cmu_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cmu_mux_clks),
+	.div_clks		= cmu_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cmu_div_clks),
+	.gate_clks		= cmu_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cmu_gate_clks),
+	.nr_clk_ids		= CMU_NR_CLK,
+	.clk_regs		= cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 70cdc87f714e..fe383471c5f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_1450x:
 	case pll_1451x:
 	case pll_1452x:
+	case pll_142xx:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c83a20195f6d..a9892c2d1f57 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -39,6 +39,7 @@ enum samsung_pll_type {
 	pll_1460x,
 	pll_0822x,
 	pll_0831x,
+	pll_142xx,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:18 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:18 +0530
Subject: [PATCH v4 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191953epcas5p2d015b75800b2e431689457fc7b7505c1@epcas5p2.samsung.com>
Message-ID: <20220123190729.1852-6-alim.akhtar@samsung.com>

Add CMU_PERIC block clock information needed for various IPs
functions found in this block.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 405 ++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index ae35c4303b55..a3d328318814 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -8,14 +8,19 @@
  * Common Clock Framework support for FSD SoC.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/clock/fsd-clk.h>
 
 #include "clk.h"
+#include "clk-exynos-arm64.h"
 
 /* Register Offset definitions for CMU_CMU (0x11c10000) */
 #define PLL_LOCKTIME_PLL_SHARED0			0x0
@@ -308,3 +313,403 @@ static void __init fsd_clk_cmu_init(struct device_node *np)
 }
 
 CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX		0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX		0x120
+#define PLL_CON0_PERIC_PCLK_MUX			0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX		0x160
+#define PLL_CON0_SPI_CLK			0x180
+#define PLL_CON0_SPI_PCLK			0x1a0
+#define PLL_CON0_UART_CLK			0x1c0
+#define PLL_CON0_UART_PCLK			0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK			0x1000
+#define DIV_EQOS_BUSCLK				0x1800
+#define DIV_PERIC_MCAN_CLK			0x1804
+#define DIV_RGMII_CLK				0x1808
+#define DIV_RII_CLK				0x180c
+#define DIV_RMII_CLK				0x1810
+#define DIV_SPI_CLK				0x1814
+#define DIV_UART_CLK				0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I	0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK		0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK	0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK	0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK	0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK	0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM	0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS	0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM	0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS	0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK	0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK	0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK	0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK	0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK	0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK	0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK	0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK	0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK	0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I		0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I		0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I		0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I	0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I	0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK		0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D	0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P	0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0	0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK		0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK		0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK		0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK		0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK		0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK		0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK		0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK		0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK		0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK		0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK		0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK		0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK		0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK		0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK		0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK		0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK		0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK		0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0	0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0	0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK		0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK	0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK		0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI	0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK		0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI	0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK		0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI	0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M		0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK		0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M		0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK		0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART	0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK		0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART	0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK		0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK		0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+	PLL_CON0_PERIC_DMACLK_MUX,
+	PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+	PLL_CON0_PERIC_PCLK_MUX,
+	PLL_CON0_PERIC_TBUCLK_MUX,
+	PLL_CON0_SPI_CLK,
+	PLL_CON0_SPI_PCLK,
+	PLL_CON0_UART_CLK,
+	PLL_CON0_UART_PCLK,
+	MUX_PERIC_EQOS_PHYRXCLK,
+	DIV_EQOS_BUSCLK,
+	DIV_PERIC_MCAN_CLK,
+	DIV_RGMII_CLK,
+	DIV_RII_CLK,
+	DIV_RMII_CLK,
+	DIV_SPI_CLK,
+	DIV_UART_CLK,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+	GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+	GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+	GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+	GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+	GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+	GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+	GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+	GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+	GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+	GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+	GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART0_IPCLKPORT_PCLK,
+	GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART1_IPCLKPORT_PCLK,
+	GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+	FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+	MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+	MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+	    PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+	MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+	MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+	MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+	MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+		MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+	DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+	DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+	DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+		DIV_RGMII_CLK, 0, 4),
+	DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+	DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+	DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+	DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+	     GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+	     "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+	     "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+	.mux_clks		= peric_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric_mux_clks),
+	.div_clks		= peric_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric_div_clks),
+	.gate_clks		= peric_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric_gate_clks),
+	.fixed_clks		= peric_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(peric_fixed_clks),
+	.nr_clk_ids		= PERIC_NR_CLK,
+	.clk_regs		= peric_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric_clk_regs),
+	.clk_name		= "dout_cmu_pll_shared0_div4",
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+	{
+		.compatible = "tesla,fsd-clock-peric",
+		.data = &peric_cmu_info,
+	}, {
+	},
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+	.driver	= {
+		.name = "fsd-cmu",
+		.of_match_table = fsd_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+	return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:19 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:19 +0530
Subject: [PATCH v4 06/16] clk: samsung: fsd: Add cmu_fsys0 clock information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123191957epcas5p48578770a81acfbccd8550faed665ffa1@epcas5p4.samsung.com>
Message-ID: <20220123190729.1852-7-alim.akhtar@samsung.com>

CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
the related clock information for the same.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index a3d328318814..785c493be2b6 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -673,6 +673,305 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_pll_shared0_div4",
 };
 
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO		0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK		0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1		0x160
+#define DIV_CLK_UNIPRO				0x1800
+#define DIV_EQS_RGMII_CLK_125			0x1804
+#define DIV_PERIBUS_GRP				0x1808
+#define DIV_EQOS_RII_CLK2O5			0x180c
+#define DIV_EQOS_RMIICLK_25			0x1810
+#define DIV_PCIE_PHY_OSCCLK			0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I	0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK	0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK	0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO	0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK	0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC	0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK	0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK	0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK	0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK	0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK	0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK		0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I	0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I	0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK	0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D	0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1	0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P	0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S	0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK	0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL	0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0	0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC	0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK	0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC	0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC	0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK	0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK	0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK	0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS	0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK	0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO	0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK	0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS	0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK	0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO	0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK	0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE			0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+	PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+	PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+	PLL_CON0_EQOS_RGMII_125_MUX1,
+	DIV_CLK_UNIPRO,
+	DIV_EQS_RGMII_CLK_125,
+	DIV_PERIBUS_GRP,
+	DIV_EQOS_RII_CLK2O5,
+	DIV_EQOS_RMIICLK_25,
+	DIV_PCIE_PHY_OSCCLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+	GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+	GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+	GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+	GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+	FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+	FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+	FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+	    PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+	MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+	    PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+	MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+	    PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+	DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+	DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQS_RGMII_CLK_125, 0, 4),
+	DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+	    "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQOS_RMIICLK_25, 0, 5),
+	DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+	     "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+	     "xtal_clk_pcie_phy",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+	      "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+	      CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+	     "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+	     "dout_fsys0_pcie_phy_oscclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+	.mux_clks		= fsys0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys0_mux_clks),
+	.div_clks		= fsys0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys0_div_clks),
+	.gate_clks		= fsys0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys0_gate_clks),
+	.fixed_clks		= fsys0_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys0_fixed_clks),
+	.nr_clk_ids		= FSYS0_NR_CLK,
+	.clk_regs		= fsys0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys0_clk_regs),
+	.clk_name		= "dout_cmu_fsys0_shared1div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -695,6 +994,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	{
 		.compatible = "tesla,fsd-clock-peric",
 		.data = &peric_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys0",
+		.data = &fsys0_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:20 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:20 +0530
Subject: [PATCH v4 07/16] clk: samsung: fsd: Add cmu_fsys1 clock information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192001epcas5p1e5c0fcf841684b5996c5da8cab805899@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-8-alim.akhtar@samsung.com>

Adds cmu_fsys1 block clock information which are needed
for PCIe IPs in block FSYS1.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 785c493be2b6..19c3ea35a6ea 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -972,6 +972,178 @@ static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys0_shared1div4",
 };
 
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX			0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX			0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK			0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK			0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK	0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK		0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK	0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK		0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL	0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK				0x2034
+#define GAT_FSYS1_PHY1_OSCCLK				0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK		0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK	0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK	0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK		0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0	0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0	0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK		0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK	0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK	0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK	0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK		0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK		0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK	0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK	0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK		0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK		0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL	0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK		0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK		0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+	PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+	PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+	DIV_CLK_FSYS1_PHY0_OSCCLK,
+	DIV_CLK_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+	GAT_FSYS1_PHY0_OSCCLLK,
+	GAT_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+	GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+	FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+	FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+	    PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+	MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+	    PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+	DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+	    DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+	DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+	    DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+	GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+	.mux_clks		= fsys1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys1_mux_clks),
+	.div_clks		= fsys1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys1_div_clks),
+	.gate_clks		= fsys1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys1_gate_clks),
+	.fixed_clks		= fsys1_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys1_fixed_clks),
+	.nr_clk_ids		= FSYS1_NR_CLK,
+	.clk_regs		= fsys1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys1_clk_regs),
+	.clk_name		= "dout_cmu_fsys1_shared0div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -997,6 +1169,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys0",
 		.data = &fsys0_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys1",
+		.data = &fsys1_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:21 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:21 +0530
Subject: [PATCH v4 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192007epcas5p328e069a2d129705d3c9bf6afa965f0fb@epcas5p3.samsung.com>
Message-ID: <20220123190729.1852-9-alim.akhtar@samsung.com>

Adds cmu_imem clock related code, imem block contains IPs
like WDT, DMA, TMU etc, these clocks are required for such
IP function.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 19c3ea35a6ea..f15b5b6b8eca 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1144,6 +1144,289 @@ static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys1_shared0div4",
 };
 
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK				0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK			0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK			0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK			0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK		0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO		0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK		0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK		0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS		0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK		0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS		0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK		0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK			0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK		0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK			0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK			0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK			0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM	0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM	0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM	0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS	0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS	0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS	0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM		0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS		0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM		0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS		0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK		0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK		0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK		0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK		0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK		0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK		0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK			0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK			0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK	0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK			0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK			0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK	0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK	0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK			0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D	0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU	0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P	0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK		0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK		0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK	0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK		0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK		0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK		0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK		0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK		0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK			0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK			0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK			0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK			0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+	PLL_CON0_CLK_IMEM_ACLK,
+	PLL_CON0_CLK_IMEM_INTMEMCLK,
+	PLL_CON0_CLK_IMEM_TCUCLK,
+	DIV_OSCCLK_IMEM_TMUTSCLK,
+	GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_WDT0_IPCLKPORT_CLK,
+	GAT_IMEM_WDT1_IPCLKPORT_CLK,
+	GAT_IMEM_WDT2_IPCLKPORT_CLK,
+	GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+	GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+	GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+	GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+	GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+	GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+	GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+	GAT_IMEM_GIC_IPCLKPORT_CLK,
+	GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_PCLK,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+	GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+	GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_TCU_IPCLKPORT_ACLK,
+	GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+	MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+	    PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+	    PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+	DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+	GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+	     GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+	.mux_clks		= imem_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(imem_mux_clks),
+	.div_clks		= imem_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(imem_div_clks),
+	.gate_clks		= imem_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(imem_gate_clks),
+	.nr_clk_ids		= IMEM_NR_CLK,
+	.clk_regs		= imem_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:22 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:22 +0530
Subject: [PATCH v4 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192011epcas5p480912c2a3195d4caa34ed140cda09ac0@epcas5p4.samsung.com>
Message-ID: <20220123190729.1852-10-alim.akhtar@samsung.com>

Adds cmu_mfc clock related code, these clocks are
required for MFC IP.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index f15b5b6b8eca..f9c4b4c5e0cb 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1427,6 +1427,124 @@ static void __init fsd_clk_imem_init(struct device_node *np)
 
 CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
 
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC					0x0
+#define PLL_CON0_PLL_MFC					0x100
+#define MUX_MFC_BUSD						0x1000
+#define MUX_MFC_BUSP						0x1008
+#define DIV_MFC_BUSD_DIV4					0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK				0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM			0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS			0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK			0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK				0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D	0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P	0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK			0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK			0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK			0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK			0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK			0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK				0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK				0x2040
+#define GAT_MFC_BUSD_DIV4_GATE					0x2044
+#define GAT_MFC_BUSD_GATE					0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_MFC,
+	PLL_CON0_PLL_MFC,
+	MUX_MFC_BUSD,
+	MUX_MFC_BUSP,
+	DIV_MFC_BUSD_DIV4,
+	GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+	GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+	GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+	GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+	GAT_MFC_BUSD_DIV4_GATE,
+	GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+	    PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+	MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+	MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+	MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+	DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+	GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+	     GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+	     GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+	.pll_clks		= mfc_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(mfc_pll_clks),
+	.mux_clks		= mfc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mfc_mux_clks),
+	.div_clks		= mfc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mfc_div_clks),
+	.gate_clks		= mfc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mfc_gate_clks),
+	.nr_clk_ids		= MFC_NR_CLK,
+	.clk_regs		= mfc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1455,6 +1573,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys1",
 		.data = &fsys1_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-mfc",
+		.data = &mfc_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:23 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:23 +0530
Subject: [PATCH v4 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192015epcas5p18f837be62b7d2b129e3a2d61e2e9f4c0@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-11-alim.akhtar@samsung.com>

Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sathyakam M <sathya at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index f9c4b4c5e0cb..5d009c70e97d 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1545,6 +1545,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
 	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
 };
 
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI		0x0
+#define PLL_CON0_PLL_CAM_CSI			0x100
+#define DIV_CAM_CSI0_ACLK			0x1800
+#define DIV_CAM_CSI1_ACLK			0x1804
+#define DIV_CAM_CSI2_ACLK			0x1808
+#define DIV_CAM_CSI_BUSD			0x180c
+#define DIV_CAM_CSI_BUSP			0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK	0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK	0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0	0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1	0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2	0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC	0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC		0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK		0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK		0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK		0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK		0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK		0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK		0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK		0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK		0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK		0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK		0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK		0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK		0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK		0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK		0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK		0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK		0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK		0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK		0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK		0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK		0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK		0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK		0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK		0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK		0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D	0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P	0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK	0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK	0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CAM_CSI,
+	PLL_CON0_PLL_CAM_CSI,
+	DIV_CAM_CSI0_ACLK,
+	DIV_CAM_CSI1_ACLK,
+	DIV_CAM_CSI2_ACLK,
+	DIV_CAM_CSI_BUSD,
+	DIV_CAM_CSI_BUSP,
+	GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+	GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+	    PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+	MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+	DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+	DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+	GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+	     GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+	     "dout_cam_csi_busd",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+	     "dout_cam_csi_busp",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+	     GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+	.pll_clks		= cam_csi_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cam_csi_pll_clks),
+	.mux_clks		= cam_csi_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cam_csi_mux_clks),
+	.div_clks		= cam_csi_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cam_csi_div_clks),
+	.gate_clks		= cam_csi_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cam_csi_gate_clks),
+	.nr_clk_ids		= CAM_CSI_NR_CLK,
+	.clk_regs		= cam_csi_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cam_csi_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1576,6 +1780,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-mfc",
 		.data = &mfc_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-cam_csi",
+		.data = &cam_csi_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:24 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:24 +0530
Subject: [PATCH v4 11/16] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192019epcas5p3c2af6ef38e644adaf9ecd7efbb6ba840@epcas5p3.samsung.com>
Message-ID: <20220123190729.1852-12-alim.akhtar@samsung.com>

Add compatible for Tesla Full Self-Driving SoC. The
pinctrl hardware IP is similar to what found on most of the
Exynos series of SoC, so this new compatible is added in
Samsung pinctrl binding.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
index 28f0851d07bb..989e48c051cf 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
@@ -56,6 +56,7 @@ properties:
       - samsung,exynos7885-pinctrl
       - samsung,exynos850-pinctrl
       - samsung,exynosautov9-pinctrl
+      - tesla,fsd-pinctrl
 
   interrupts:
     description:
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:25 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:25 +0530
Subject: [PATCH v4 12/16] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192023epcas5p2daf1cc38e042a6dce8b0271026065715@epcas5p2.samsung.com>
Message-ID: <20220123190729.1852-13-alim.akhtar@samsung.com>

Adds Tesla FSD SoC specific data to enable pinctrl.
FSD SoC has similar pinctrl controller as found in the most
Samsung/Exynos SoCs.

Cc: linux-fsd at tesla.com
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
 3 files changed, 74 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 4102ce955bd7..d291819c2f77 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -725,3 +725,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
 	.ctrl		= exynosautov9_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
 };
+
+/*
+ * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
+ * gpio/pin-mux/pinconfig controllers.
+ */
+
+/* pin banks of FSD pin-controller 0 (FSYS) */
+static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
+};
+
+/* pin banks of FSD pin-controller 1 (PERIC) */
+static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
+};
+
+/* pin banks of FSD pin-controller 2 (PMU) */
+static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
+};
+
+const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 FSYS0 data */
+		.pin_banks	= fsd_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 1 PERIC data */
+		.pin_banks	= fsd_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 2 PMU data */
+		.pin_banks	= fsd_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks2),
+	},
+};
+
+const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
+	.ctrl		= fsd_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 568b6e65dfed..f610beab23a0 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1320,6 +1320,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos850_of_data },
 	{ .compatible = "samsung,exynosautov9-pinctrl",
 		.data = &exynosautov9_of_data },
+	{ .compatible = "tesla,fsd-pinctrl",
+		.data = &fsd_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 1f8d30ba05af..5b32d3f30fcd 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -342,6 +342,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
+extern const struct samsung_pinctrl_of_match_data fsd_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:26 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:26 +0530
Subject: [PATCH v4 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192027epcas5p155d6d7c5146a090962bc655bf3557629@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-14-alim.akhtar@samsung.com>

Add device tree bindings for the Tesla FSD ARM SoC.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml

diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..09856da657dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: FSD SoC board
+        items:
+          - enum:
+              - tesla,fsd-evb   # Tesla FSD Evaluation
+          - const: tesla,fsd
+
+additionalProperties: true
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:27 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:27 +0530
Subject: [PATCH v4 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192032epcas5p3a732ede117d862503dcf07ee22108cd7@epcas5p3.samsung.com>
Message-ID: <20220123190729.1852-15-alim.akhtar@samsung.com>

Add initial device tree support for "Full Self-Driving" (FSD) SoC
This SoC contain three clusters of four cortex-a72 CPUs and various
peripheral IPs.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 MAINTAINERS                           |   8 +
 arch/arm64/Kconfig.platforms          |   6 +
 arch/arm64/boot/dts/Makefile          |   1 +
 arch/arm64/boot/dts/tesla/Makefile    |   3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi    | 651 ++++++++++++++++++++++++++
 6 files changed, 708 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 89f23af16451..d97d3a5d7f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2753,6 +2753,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/tegra-cec.txt
 F:	drivers/media/cec/platform/tegra/
 
+ARM/TESLA FSD SoC SUPPORT
+M:	Alim Akhtar <alim.akhtar at samsung.com>
+M:	linux-fsd at tesla.com
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	arch/arm64/boot/dts/tesla*
+
 ARM/TETON BGA MACHINE SUPPORT
 M:	"Mark F. Brown" <mark.brown314 at gmail.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..739254493d6a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -268,6 +268,12 @@ config ARCH_TEGRA
 	help
 	  This enables support for the NVIDIA Tegra SoC family.
 
+config ARCH_TESLA_FSD
+	bool "ARMv8 based Tesla platform"
+	depends on ARCH_EXYNOS
+	help
+	  Support for ARMv8 based Tesla platforms.
+
 config ARCH_SPRD
 	bool "Spreadtrum SoC platform"
 	help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += tesla
 subdir-y += ti
 subdir-y += toshiba
 subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a1ee50e2fd06
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+	fsd-evb.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
new file mode 100644
index 000000000000..5af560c1b5e6
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+	model = "Tesla Full Self-Driving (FSD) Evaluation board";
+	compatible = "tesla,fsd-evb", "tesla,fsd";
+
+	aliases {
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
+
+&serial_0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..815bd27efbe2
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,651 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "tesla,fsd";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &hsi2c_0;
+		i2c1 = &hsi2c_1;
+		i2c2 = &hsi2c_2;
+		i2c3 = &hsi2c_3;
+		i2c4 = &hsi2c_4;
+		i2c5 = &hsi2c_5;
+		i2c6 = &hsi2c_6;
+		i2c7 = &hsi2c_7;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpucl0_0>;
+				};
+				core1 {
+					cpu = <&cpucl0_1>;
+				};
+				core2 {
+					cpu = <&cpucl0_2>;
+				};
+				core3 {
+					cpu = <&cpucl0_3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpucl1_0>;
+				};
+				core1 {
+					cpu = <&cpucl1_1>;
+				};
+				core2 {
+					cpu = <&cpucl1_2>;
+				};
+				core3 {
+					cpu = <&cpucl1_3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpucl2_0>;
+				};
+				core1 {
+					cpu = <&cpucl2_1>;
+				};
+				core2 {
+					cpu = <&cpucl2_2>;
+				};
+				core3 {
+					cpu = <&cpucl2_3>;
+				};
+			};
+		};
+
+		/* Cluster 0 */
+		cpucl0_0: cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x000>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_1: cpu at 1 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x001>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_2: cpu at 2 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x002>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_3: cpu at 3 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x003>;
+				enable-method = "psci";
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 1 */
+		cpucl1_0: cpu at 100 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x100>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_1: cpu at 101 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x101>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_2: cpu at 102 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x102>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_3: cpu at 103 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x103>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 2 */
+		cpucl2_0: cpu at 200 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x200>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_1: cpu at 201 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x201>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_2: cpu at 202 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x202>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_3: cpu at 203 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x203>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		idle-states {
+			entry-method = "arm,psci";
+
+			CPU_SLEEP: cpu-sleep {
+				idle-state-name = "c2";
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <30>;
+				exit-latency-us = <75>;
+				min-residency-us = <300>;
+			};
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	fin_pll: clock {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		#clock-cells = <0>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+		gic: interrupt-controller at 10400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
+				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+		};
+
+		smmu_imem: iommu at 10200000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x10200000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <7>;
+			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
+				     /* Per context non-secure context interrupts, 0-3 interrupts */
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+		};
+
+		smmu_isp: iommu at 12100000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x12100000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <11>;
+			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+				     /* Per context non-secure context interrupts, 0-7 interrupts */
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+		};
+
+		smmu_peric: iommu at 14900000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x14900000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		smmu_fsys0: iommu at 15450000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x15450000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		clock_imem: clock-controller at 10010000 {
+			compatible = "tesla,fsd-clock-imem";
+			reg = <0x0 0x10010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
+				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_imem_tcuclk",
+				"dout_cmu_imem_aclk",
+				"dout_cmu_imem_dmaclk";
+		};
+
+		clock_cmu: clock-controller at 11c10000 {
+			compatible = "tesla,fsd-clock-cmu";
+			reg = <0x0 0x11c10000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_csi: clock-controller at 12610000 {
+			compatible = "tesla,fsd-clock-cam_csi";
+			reg = <0x0 0x12610000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_mfc: clock-controller at 12810000 {
+			compatible = "tesla,fsd-clock-mfc";
+			reg = <0x0 0x12810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_peric: clock-controller at 14010000 {
+			compatible = "tesla,fsd-clock-peric";
+			reg = <0x0 0x14010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div4",
+				"dout_cmu_peric_shared1div36",
+				"dout_cmu_peric_shared0div3_tbuclk",
+				"dout_cmu_peric_shared0div20",
+				"dout_cmu_peric_shared1div4_dmaclk";
+		};
+
+		clock_fsys0: clock-controller at 15010000 {
+			compatible = "tesla,fsd-clock-fsys0";
+			reg = <0x0 0x15010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div6",
+				"dout_cmu_fsys0_shared1div4",
+				"dout_cmu_fsys0_shared0div4";
+		};
+
+		clock_fsys1: clock-controller at 16810000 {
+			compatible = "tesla,fsd-clock-fsys1";
+			reg = <0x0 0x16810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_fsys1_shared0div8",
+				"dout_cmu_fsys1_shared0div4";
+		};
+
+		mdma0: mdma at 10100000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10100000 0x0 0x1000>;
+			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x800 0x0>;
+		};
+
+		mdma1: mdma at 10110000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10110000 0x0 0x1000>;
+			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x801 0x0>;
+		};
+
+		pdma0: pdma at 14280000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x2 0x0>;
+		};
+
+		pdma1: pdma at 14290000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x1 0x0>;
+		};
+
+		serial_0: serial at 14180000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14180000 0x0 0x100>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 0>, <&pdma1 1>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART0>,
+				 <&clock_peric PERIC_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		serial_1: serial at 14190000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14190000 0x0 0x100>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 2>, <&pdma1 3>;
+			dma-names = "tx", "rx";
+			clocks = <&clock_peric PERIC_PCLK_UART1>,
+				 <&clock_peric PERIC_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller at 11400000 {
+			compatible = "samsung,exynos7-pmu", "syscon";
+			reg = <0x0 0x11400000 0x0 0x5000>;
+		};
+
+		watchdog_0: watchdog at 100a0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100a0000 0x0 0x100>;
+			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_1: watchdog at 100b0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100b0000 0x0 0x100>;
+			interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_2: watchdog at 100c0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100c0000 0x0 0x100>;
+			interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		pwm_0: pwm at 14100000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14100000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		pwm_1: pwm at 14110000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14110000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		hsi2c_0: i2c at 14200000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14200000 0x0 0x1000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: i2c at 14210000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14210000 0x0 0x1000>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: i2c at 14220000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14220000 0x0 0x1000>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: i2c at 14230000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14230000 0x0 0x1000>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: i2c at 14240000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14240000 0x0 0x1000>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: i2c at 14250000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14250000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: i2c at 14260000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: i2c at 14270000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+	};
+};
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:28 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:28 +0530
Subject: [PATCH v4 15/16] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192036epcas5p118f022cd52b7514bd1c27081bb18226a@epcas5p1.samsung.com>
Message-ID: <20220123190729.1852-16-alim.akhtar@samsung.com>

Add initial pin configuration nodes for FSD SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 335 +++++++++++++++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
 2 files changed, 357 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi

diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..d4d0cb005712
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+	gpf0: gpf0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf6: gpf6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric {
+	gpc8: gpc8-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb4: gpb4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb5: gpb5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb6: gpb6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb7: gpb7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd3: gpd3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg4: gpg4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg5: gpg5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg6: gpg6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg7: gpg7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	pwm0_out: pwm0-out-pins {
+		samsung,pins = "gpb6-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	pwm1_out: pwm1-out-pins {
+		samsung,pins = "gpb6-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	hs_i2c0_bus: hs-i2c0-bus-pins {
+		samsung,pins = "gpb0-0", "gpb0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus-pins {
+		samsung,pins = "gpb0-2", "gpb0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus-pins {
+		samsung,pins = "gpb0-4", "gpb0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus-pins {
+		samsung,pins = "gpb0-6", "gpb0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus-pins {
+		samsung,pins = "gpb1-0", "gpb1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus-pins {
+		samsung,pins = "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus-pins {
+		samsung,pins = "gpb1-4", "gpb1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus-pins {
+		samsung,pins = "gpb1-6", "gpb1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_data: uart0-data-pins {
+		samsung,pins = "gpb7-0", "gpb7-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data-pins {
+		samsung,pins = "gpb7-4", "gpb7-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus-pins {
+		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus-pins {
+		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus-pins {
+		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_pmu {
+	gpq0: gpq0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 815bd27efbe2..1210fe64d7c7 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -26,6 +26,9 @@ aliases {
 		i2c5 = &hsi2c_5;
 		i2c6 = &hsi2c_6;
 		i2c7 = &hsi2c_7;
+		pinctrl0 = &pinctrl_fsys0;
+		pinctrl1 = &pinctrl_peric;
+		pinctrl2 = &pinctrl_pmu;
 	};
 
 	cpus {
@@ -647,5 +650,24 @@ hsi2c_7: i2c at 14270000 {
 			clock-names = "hsi2c";
 			status = "disabled";
 		};
+
+		pinctrl_pmu: pinctrl at 114f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x114f0000 0x0 0x1000>;
+		};
+
+		pinctrl_peric: pinctrl at 141f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x141f0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys0: pinctrl at 15020000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x15020000 0x0 0x1000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
+
+#include "fsd-pinctrl.dtsi"
-- 
2.25.1



From alim.akhtar at samsung.com  Sun Jan 23 11:07:29 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 00:37:29 +0530
Subject: [PATCH v4 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220123190729.1852-1-alim.akhtar@samsung.com>
References: <20220123190729.1852-1-alim.akhtar@samsung.com>
 <CGME20220123192039epcas5p3fc21ed81a383a05f1ea1704481641c69@epcas5p3.samsung.com>
Message-ID: <20220123190729.1852-17-alim.akhtar@samsung.com>

This patch enables the Tesla FSD SoC in arm64 defconfig.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..415fb3aca4b3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -54,6 +54,7 @@ CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_INTEL_SOCFPGA=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Sun Jan 23 11:27:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sun, 23 Jan 2022 20:27:44 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAPLW+4k8=ymx56R7bKOt8kMVG_uUgrTsCkVd5wiY_rkYq8dYbQ@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
 <CAPLW+4k8=ymx56R7bKOt8kMVG_uUgrTsCkVd5wiY_rkYq8dYbQ@mail.gmail.com>
Message-ID: <72a50afd-df9f-ceb3-898e-070d70dc0221@canonical.com>

On 22/01/2022 13:38, Sam Protsenko wrote:
> On Wed, 19 Jan 2022 at 18:53, Olof Johansson <olof at lixom.net> wrote:
>>
>> On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
>>>
>>> On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
>>> <semen.protsenko at linaro.org> wrote:
>>>> On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
>>>>
>>>> Hi Olof, Arnd,
>>>>
>>>> Just want to check if it's possible for those patches to be applied in
>>>> v5.17? Sorry for the noise, but that's important to me.
>>>
>>> I can see that Olof merged merged this into the "arm/late" branch in
>>> the soc tree,
>>> so I assume he still plans to send it in the next few days.
>>
>> Yep, will be sent up today most likely.
>>
> 
> Thanks for detailed answer! Glad to hear it's still a possibility.
> Please let me know if you need any actions on my side (like rebasing,
> etc).
> 
>>> With the timing over Christmas, I sent out the large bulk of the
>>> contents (anything
>>> I merged before Dec 23) last year, and Linus already merged it, the rest ended
>>> up in the "late" branch.
>>>
>>> As usual, there is no guarantee that late changes make it in, but I have seen
>>> no indication of any problems so far.
>>
>> Correct. Been sitting on it for a while in case there were fixes
>> coming in for the first pieces that got merged, but in traditional
>> fashion I'm guessing those will start to show up a few days after the
>> late branch gets merged. :)

Olof,
v5.17-rc1 came earlier, so I see this part did not make into it. Is
there a chance for a past-rc1 pull to Linus with it?

Sam,
Anyway the patches wont' get lost (you mentioned such worry in previous
email to me). They might just need to wait. Unfortunately if patch,
especially with new feature, is coming in the end of cycle, there is a
risk it won't make it. The patches have to wait a few days in my trees
before I send them to Arnd/Olof, so if the patch is coming after rc6, I
can push it to Arnd/Olof around rc7, you see there is very little time.

Best regards,
Krzysztof


From samuel at sholland.org  Sun Jan 23 11:43:37 2022
From: samuel at sholland.org (Samuel Holland)
Date: Sun, 23 Jan 2022 13:43:37 -0600
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and
 unprepare "stmmaceth" clk
In-Reply-To: <20220123132805.758-1-jszhang@kernel.org>
References: <20220123132805.758-1-jszhang@kernel.org>
Message-ID: <38c41c04-abde-4d55-ed7c-515b6bba9c54@sholland.org>

On 1/23/22 7:28 AM, Jisheng Zhang wrote:
> Fix warnings on Allwinner D1 platform:
> 
> [    1.604695] ------------[ cut here ]------------
> [    1.609328] bus-emac already disabled
> [    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
> [    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
> [    1.627653] Hardware name: Allwinner D1 NeZha (DT)
> [    1.632443] Workqueue: events_unbound deferred_probe_work_func
> [    1.638286] epc : clk_core_disable+0xcc/0xec
> [    1.642561]  ra : clk_core_disable+0xcc/0xec
> [    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
> [    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
> [    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
> [    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
> [    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
> [    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
> [    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
> [    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> [    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> [    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
> [    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
> [    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
> [    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
> [    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
> [    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> [    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
> [    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> [    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> [    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> [    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> [    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> [    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> [    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> [    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> [    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> [    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> [    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> [    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> [    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> [    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> [    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> [    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> [    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> [    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
> [    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> [    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> [    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
> [    1.873675] ------------[ cut here ]------------
> [    1.878366] bus-emac already unprepared
> [    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
> [    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
> [    1.898674] Hardware name: Allwinner D1 NeZha (DT)
> [    1.903464] Workqueue: events_unbound deferred_probe_work_func
> [    1.909305] epc : clk_core_unprepare+0xe4/0x168
> [    1.913840]  ra : clk_core_unprepare+0xe4/0x168
> [    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
> [    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
> [    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
> [    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
> [    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
> [    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
> [    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
> [    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> [    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> [    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
> [    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
> [    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
> [    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
> [    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
> [    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
> [    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> [    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> [    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> [    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> [    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> [    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> [    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> [    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> [    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> [    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> [    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> [    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> [    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> [    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> [    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> [    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> [    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> [    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
> [    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> [    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> [    2.135455] ---[ end trace 8d5c6046255f84a1 ]---
> 
> the dwmmac-sun8i driver will get the "stmmaceth" clk as tx_clk during
> driver initialization. If stmmac_dvr_probe() fails due to various
> reasons, sun8i_dwmac_exit() will disable and unprepare the "stmmaceth"
> clk, then stmmac_remove_config_dt() will disable and unprepare the
> clk again.

This should still be balanced, because both stmmac_probe_config_dt and
sun8i_dwmac_init prepare/enable the clock, so the dwmac-sun8i glue layer calls
stmmac_dvr_probe with the clock having an enable count of 2. It looks like the
underlying issue is that commit 5ec55823438e ("net: stmmac: add clocks
management for gmac driver") introduces unbalanced runtime PM.
 - stmmac_dvr_probe calls pm_runtime_get_noresume and pm_runtime_set_active,
since it assumes the clocks are already enabled. This is fine.
 - If stmmac_dvr_probe fails, it calls stmmac_bus_clks_config(priv, false),
which drops the enable count down to 1. This is a bug, not just in this case,
but also because it will unbalance the clocks if runtime PM is disabled.
 - If stmmac_dvr_probe fails, it never calls pm_runtime_disable if the failure
occurs after the call to pm_runtime_enable. This is also a bug.

It looks like at some point stmmac_dvr_remove was expected to leave all of the
clocks disabled, but it must leave them enabled as of commit 8f269102baf7 ("net:
stmmac: disable clocks in stmmac_remove_config_dt()"), since
stmmac_remove_config_dt is called after stmmac_dvr_remove in stmmac_pltfr_remove.
 - If stmmac_dvr_probe succeeds, it calls pm_runtime_put. This allows runtime PM
to suspend the device, dropping the clock enable count to 1. This is fine.
 - But then stmmac_dvr_remove calls pm_runtime_put as well. It needs to do the
opposite. It must ensure the device is runtime resumed, so the clock enable
count matches what it was before stmmac_dvr_probe was called (in this case: 2).

> Currently, there's no other usage of tx_clk except preparing and
> enabling, we can fix the above warnings by simply removing the tx_clk
> and all its usage, we rely on the common stmmac_probe_config_dt()
> routine to prepare and enable the stmmaceth clk.

This is a good change to make, as indeed this code is now unnecessary, and
removing it will allow runtime PM to actually disable the clock. But I am not
sure how this resolves the warnings you are seeing, as the sun8i_dwmac_init/exit
calls should have been balanced already.

Can you check if the PHY regulator is also getting unbalanced? Unbalanced calls
to sun8i_dwmac_exit would also underflow the regulator use count, which should
trigger its own warning.

Regards,
Samuel

> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> ---
>  .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 20 +------------------
>  1 file changed, 1 insertion(+), 19 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> index 617d0e4c6495..d97469825e53 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> @@ -57,7 +57,6 @@ struct emac_variant {
>  };
>  
>  /* struct sunxi_priv_data - hold all sunxi private data
> - * @tx_clk:	reference to MAC TX clock
>   * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
>   * @regulator:	reference to the optional regulator
>   * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
> @@ -68,7 +67,6 @@ struct emac_variant {
>   * @mux_handle:	Internal pointer used by mdio-mux lib
>   */
>  struct sunxi_priv_data {
> -	struct clk *tx_clk;
>  	struct clk *ephy_clk;
>  	struct regulator *regulator;
>  	struct reset_control *rst_ephy;
> @@ -579,22 +577,14 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
>  		}
>  	}
>  
> -	ret = clk_prepare_enable(gmac->tx_clk);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Could not enable AHB clock\n");
> -		goto err_disable_regulator;
> -	}
> -
>  	if (gmac->use_internal_phy) {
>  		ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
>  		if (ret)
> -			goto err_disable_clk;
> +			goto err_disable_regulator;
>  	}
>  
>  	return 0;
>  
> -err_disable_clk:
> -	clk_disable_unprepare(gmac->tx_clk);
>  err_disable_regulator:
>  	if (gmac->regulator)
>  		regulator_disable(gmac->regulator);
> @@ -1043,8 +1033,6 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
>  	if (gmac->variant->soc_has_internal_phy)
>  		sun8i_dwmac_unpower_internal_phy(gmac);
>  
> -	clk_disable_unprepare(gmac->tx_clk);
> -
>  	if (gmac->regulator)
>  		regulator_disable(gmac->regulator);
>  }
> @@ -1167,12 +1155,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
>  		return -EINVAL;
>  	}
>  
> -	gmac->tx_clk = devm_clk_get(dev, "stmmaceth");
> -	if (IS_ERR(gmac->tx_clk)) {
> -		dev_err(dev, "Could not get TX clock\n");
> -		return PTR_ERR(gmac->tx_clk);
> -	}
> -
>  	/* Optional regulator for PHY */
>  	gmac->regulator = devm_regulator_get_optional(dev, "phy");
>  	if (IS_ERR(gmac->regulator)) {
> 



From cristian.marussi at arm.com  Sun Jan 23 12:02:54 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Sun, 23 Jan 2022 20:02:54 +0000
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20220120150418-mutt-send-email-mst@kernel.org>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
 <20220119122338.GE6113@e120937-lin>
 <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>
 <20220120150418-mutt-send-email-mst@kernel.org>
Message-ID: <20220123200254.GF6113@e120937-lin>

On Thu, Jan 20, 2022 at 03:39:12PM -0500, Michael S. Tsirkin wrote:
> On Thu, Jan 20, 2022 at 08:09:56PM +0100, Peter Hilber wrote:
> > On 19.01.22 13:23, Cristian Marussi wrote:
> > > On Tue, Jan 18, 2022 at 03:21:03PM +0100, Peter Hilber wrote:
> > >> On 21.12.21 15:00, Cristian Marussi wrote:
> > >>> Add support for .mark_txdone and .poll_done transport operations to SCMI
> > >>> VirtIO transport as pre-requisites to enable atomic operations.
> > >>>
> > >>> Add a Kernel configuration option to enable SCMI VirtIO transport polling
> > >>> and atomic mode for selected SCMI transactions while leaving it default
> > >>> disabled.
> > >>>
> > >>
> > >> Hi Cristian,
> > >>
> > >> thanks for the update. I have some more remarks inline below.
> > >>
> > > 
> > > Hi Peter,
> > > 
> > > thanks for your review, much appreciated, please see my replies online.
> > > 
> > >> My impression is that the virtio core does not expose helper functions suitable
> > >> to busy-poll for used buffers. But changing this might not be difficult. Maybe
> > >> more_used() from virtio_ring.c could be exposed via a wrapper?
> > >>
> > > 
> > > While I definitely agree that the virtio core support for polling is far from
> > > ideal, some support is provided and my point was at first to try implement SCMI
> > > virtio polling leveraging what we have now in the core and see if it was attainable
> > > (indeed I tried early in this series to avoid as a whole to have to support polling
> > > at the SCMI transport layer to attain SCMI cmds atomicity..but that was an ill
> > > attempt that led nowhere good...)
> > > 
> > > Btw, I was planning to post a new series next week (after merge-windows) with some
> > > fixes I did already, at this point I'll include also some fixes derived
> > > from some of your remarks.
> > > 
> > >> Best regards,
> > >>
> > >> Peter
> > >>
> > [snip]>>> + *

Hi Michael, Peter

I'm gonna post another iteration of this (and some other dependent
patches) with a few fixes as pointed out by Peter but still without addressing
the ABA style race/issue we are talkig about.

A few comments iand a proposal on this ABA race below, though.

> > >>> + * Return: True once polling has successfully completed.
> > >>> + */
> > >>> +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> > >>> +			     struct scmi_xfer *xfer)
> > >>> +{
> > >>> +	bool pending, ret = false;
> > >>> +	unsigned int length, any_prefetched = 0;
> > >>> +	unsigned long flags;
> > >>> +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> > >>> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> > >>> +
> > >>> +	if (!msg)
> > >>> +		return true;
> > >>> +
> > >>> +	spin_lock_irqsave(&msg->poll_lock, flags);
> > >>> +	/* Processed already by other polling loop on another CPU ? */
> > >>> +	if (msg->poll_idx == VIO_MSG_POLL_DONE) {
> > >>> +		spin_unlock_irqrestore(&msg->poll_lock, flags);
> > >>> +		return true;
> > >>> +	}
> > >>> +
> > >>> +	/* Has cmdq index moved at all ? */
> > >>> +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> > >>
> > >> In my understanding, the polling comparison could still be subject to the ABA
> > >> problem when exactly 2**16 messages have been marked as used since
> > >> msg->poll_idx was set (unlikely scenario, granted).
> > >>
> > >> I think this would be a lot simpler if the virtio core exported some
> > >> concurrency-safe helper function for such polling (similar to more_used() from
> > >> virtio_ring.c), as discussed at the top.
> > > 
> > > So this is the main limitation indeed of the current implementation, I
> > > cannot distinguish if there was an exact full wrap and I'm reading the same
> > > last_idx as before but a whoppying 2**16 messages have instead gone through...
> > > 
> > > The tricky part seems to me here that even introducing dedicated helpers
> > > for polling in order to account for such wrapping (similar to more_used())
> > > those would be based by current VirtIO spec on a single bit wrap counter,
> > > so how do you discern if 2 whole wraps have happened (even more unlikely..) ?
> > > 
> > > Maybe I'm missing something though...
> > > 
> > 
> > In my understanding, there is no need to keep track of the old state. We
> > actually only want to check whether the device has marked any buffers as `used'
> > which we did not retrieve yet via virtqueue_get_buf_ctx().
> > 
> > This is what more_used() checks in my understanding. One would just need to
> > translate the external `struct virtqueue' param to the virtio_ring.c internal
> > representation `struct vring_virtqueue' and then call `more_used()'.
> > 
> > There would be no need to keep `poll_idx` then.
> > 
> > Best regards,
> > 
> > Peter
> 
> Not really, I don't think so.
> 
> There's no magic in more_used. No synchronization happens.
> more_used is exactly like virtqueue_poll except
> you get to maintain your own index.
> 
> As it is, it is quite possible to read the cached index,
> then another thread makes 2^16 bufs available, then device
> uses them all, and presto you get a false positive.
> 
> I guess we can play with memory barriers such that cache
> read happens after the index read - but it seems that
> will just lead to the same wrap around problem
> in reverse. So IIUC it's quite a bit more involved than
> just translating structures.
> 
> And yes, a more_used like API would remove the need to pass
> the index around, but it will also obscure the fact that
> there's internal state here and that it's inherently racy
> wrt wrap arounds. Whereas I'm happy to see that virtqueue_poll
> seems to have made it clear enough that people get it.
> 
> 
> It's not hard to handle wrap around in the driver if you like though:
> just have a 32 bit atomic counter and increment it each time you are
> going to make 2^16 buffers available. That gets you to 2^48 with an
> overhead of an atomic read and that should be enough short term. Make
> sure the cache line where you put the counter is not needed elsewhere -
> checking it in a tight loop with an atomic will force it to the local
> CPU. And if you are doing that virtqueue_poll will be enough.
> 
>

I was thinking...keeping the current virtqueue_poll interface, since our
possible issue arises from the used_index wrapping around exactly on top
of the same polled index and given that currently the API returns an
unsigned "opaque" value really carrying just the 16-bit index (and possibly
the wrap bit as bit15 for packed vq) that is supposed to be fed back as
it is to the virtqueue_poll() function....

...why don't we just keep an internal full fledged per-virtqueue wrap-counter
and return that as the MSB 16-bit of the opaque value returned by
virtqueue_prepare_enable_cb and then check it back in virtqueue_poll when the
opaque is fed back ? (filtering it out from the internal helpers machinery)

As in the example below the scissors.

I mean if the internal wrap count is at that point different from the
one provided to virtqueue_poll() via the opaque poll_idx value previously
provided, certainly there is something new to fetch without even looking
at the indexes: at the same time, exposing an opaque index built as
(wraps << 16 | idx) implicitly 'binds' each index to a specific
wrap-iteration, so they can be distiguished (..ok until the wrap-count
upper 16bit wraps too....but...)

I am not really extremely familiar with the internals of virtio so I
could be missing something obvious...feel free to insult me :P

(..and I have not made any perf measurements or consideration at this
point....nor considered the redundancy of the existent packed
used_wrap_counter bit...)

Thanks,
Cristian

----

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 00f64f2f8b72..bda6af121cd7 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -117,6 +117,8 @@ struct vring_virtqueue {
        /* Last used index we've seen. */
        u16 last_used_idx;
 
+       u16 wraps;
+
        /* Hint for event idx: already triggered no need to disable. */
        bool event_triggered;
 
@@ -806,6 +808,8 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue *_vq,
        ret = vq->split.desc_state[i].data;
        detach_buf_split(vq, i, ctx);
        vq->last_used_idx++;
+       if (unlikely(!vq->last_used_idx))
+               vq->wraps++;
        /* If we expect an interrupt for the next entry, tell host
         * by writing event index and flush out the write before
         * the read in the next get_buf call. */
@@ -1508,6 +1512,7 @@ static void *virtqueue_get_buf_ctx_packed(struct virtqueue *_vq,
        if (unlikely(vq->last_used_idx >= vq->packed.vring.num)) {
                vq->last_used_idx -= vq->packed.vring.num;
                vq->packed.used_wrap_counter ^= 1;
+               vq->wraps++;
        }
 
        /*
@@ -1744,6 +1749,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
        vq->weak_barriers = weak_barriers;
        vq->broken = false;
        vq->last_used_idx = 0;
+       vq->wraps = 0;
        vq->event_triggered = false;
        vq->num_added = 0;
        vq->packed_ring = true;
@@ -2092,13 +2098,17 @@ EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
  */
 unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
 {
+       unsigned last_used_idx;
        struct vring_virtqueue *vq = to_vvq(_vq);
 
        if (vq->event_triggered)
                vq->event_triggered = false;
 
-       return vq->packed_ring ? virtqueue_enable_cb_prepare_packed(_vq) :
-                                virtqueue_enable_cb_prepare_split(_vq);
+       last_used_idx = vq->packed_ring ?
+                       virtqueue_enable_cb_prepare_packed(_vq) :
+                       virtqueue_enable_cb_prepare_split(_vq);
+
+       return VRING_BUILD_OPAQUE(last_used_idx, vq->wraps);
 }
 EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare);
 
@@ -2118,9 +2128,13 @@ bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx)
        if (unlikely(vq->broken))
                return false;
 
+       if (unlikely(vq->wraps != VRING_GET_WRAPS(last_used_idx)))
+               return true;
+
        virtio_mb(vq->weak_barriers);
-       return vq->packed_ring ? virtqueue_poll_packed(_vq, last_used_idx) :
-                                virtqueue_poll_split(_vq, last_used_idx);
+       return vq->packed_ring ?
+               virtqueue_poll_packed(_vq, VRING_GET_IDX(last_used_idx)) :
+                       virtqueue_poll_split(_vq, VRING_GET_IDX(last_used_idx));
 }
 EXPORT_SYMBOL_GPL(virtqueue_poll);
 
@@ -2245,6 +2259,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
        vq->weak_barriers = weak_barriers;
        vq->broken = false;
        vq->last_used_idx = 0;
+       vq->wraps = 0;
        vq->event_triggered = false;
        vq->num_added = 0;
        vq->use_dma_api = vring_use_dma_api(vdev);
diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
index 476d3e5c0fe7..e6b03017ebd7 100644
--- a/include/uapi/linux/virtio_ring.h
+++ b/include/uapi/linux/virtio_ring.h
@@ -77,6 +77,17 @@
  */
 #define VRING_PACKED_EVENT_F_WRAP_CTR  15
 
+#define VRING_IDX_MASK                                 GENMASK(15, 0)
+#define VRING_GET_IDX(opaque)                          \
+       ((u16)FIELD_GET(VRING_IDX_MASK, (opaque)))
+
+#define VRING_WRAPS_MASK                               GENMASK(31, 16)
+#define VRING_GET_WRAPS(opaque)                                \
+       ((u16)FIELD_GET(VRING_WRAPS_MASK, (opaque)))
+
+#define VRING_BUILD_OPAQUE(idx, wraps)                 \
+       (FIELD_PREP(VRING_WRAPS_MASK, (wraps)) | ((idx) & VRING_IDX_MASK))
+
 /* We support indirect buffer descriptors */
 #define VIRTIO_RING_F_INDIRECT_DESC    28



From sfr at canb.auug.org.au  Sun Jan 23 12:45:31 2022
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Mon, 24 Jan 2022 07:45:31 +1100
Subject: linux-next: error fetching the arm-soc-fixes tree
In-Reply-To: <20220112074147.7d38bc43@canb.auug.org.au>
References: <20220112074147.7d38bc43@canb.auug.org.au>
Message-ID: <20220124074531.39c35687@canb.auug.org.au>

Hi all,

On Wed, 12 Jan 2022 07:41:47 +1100 Stephen Rothwell <sfr at canb.auug.org.au> wrote:
>
> Hi all,
> 
> Fetching the arm-soc-fixes tree
> (git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git#arm/fixes)
> produces this error:
> 
> fatal: couldn't find remote ref refs/heads/arm/fixes

ping?
-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/dc094488/attachment.sig>

From yuzhao at google.com  Sun Jan 23 13:28:30 2022
From: yuzhao at google.com (Yu Zhao)
Date: Sun, 23 Jan 2022 14:28:30 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YefdFwcoX4+ZcDSY@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz> <Ydu6fXg2FmrseQOn@google.com>
 <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz> <Yee36hPfWSs+jR0m@google.com>
 <YefdFwcoX4+ZcDSY@dhcp22.suse.cz>
Message-ID: <Ye3IfmZGwNYSCgV6@google.com>

On Wed, Jan 19, 2022 at 10:42:47AM +0100, Michal Hocko wrote:
> On Wed 19-01-22 00:04:10, Yu Zhao wrote:
> > On Mon, Jan 10, 2022 at 11:54:42AM +0100, Michal Hocko wrote:
> > > On Sun 09-01-22 21:47:57, Yu Zhao wrote:
> > > > On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> > > > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > > [...]
> > > > > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > > > > +{
> > > > > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > > > > +		.test_walk = should_skip_vma,
> > > > > > +		.p4d_entry = walk_pud_range,
> > > > > > +	};
> > > > > > +
> > > > > > +	int err;
> > > > > > +#ifdef CONFIG_MEMCG
> > > > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > > > +#endif
> > > > > > +
> > > > > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > > > > +
> > > > > > +	do {
> > > > > > +		unsigned long start = walk->next_addr;
> > > > > > +		unsigned long end = mm->highest_vm_end;
> > > > > > +
> > > > > > +		err = -EBUSY;
> > > > > > +
> > > > > > +		rcu_read_lock();
> > > > > > +#ifdef CONFIG_MEMCG
> > > > > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > > > > +			goto contended;
> > > > > > +#endif
> > > > > > +		if (!mmap_read_trylock(mm))
> > > > > > +			goto contended;
> > > > > 
> > > > > Have you evaluated the behavior under mmap_sem contention? I mean what
> > > > > would be an effect of some mms being excluded from the walk? This path
> > > > > is called from direct reclaim and we do allocate with exclusive mmap_sem
> > > > > IIRC and the trylock can fail in a presence of pending writer if I am
> > > > > not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> > > > > can bypass the walk.
> > > > 
> > > > You are right. Here it must be a trylock; otherwise it can deadlock.
> > > 
> > > Yeah, this is clear.
> > > 
> > > > I think there might be a misunderstanding: the aging doesn't
> > > > exclusively rely on page table walks to gather the accessed bit. It
> > > > prefers page table walks but it can also fallback to the rmap-based
> > > > function, i.e., lru_gen_look_around(), which only gathers the accessed
> > > > bit from at most 64 PTEs and therefore is less efficient. But it still
> > > > retains about 80% of the performance gains.
> > > 
> > > I have to say that I really have hard time to understand the runtime
> > > behavior depending on that interaction. How does the reclaim behave when
> > > the virtual scan is enabled, partially enabled and almost completely
> > > disabled due to different constrains? I do not see any such an
> > > evaluation described in changelogs and I consider this to be a rather
> > > important information to judge the overall behavior.
> > 
> > It doesn't have (partially) enabled/disabled states nor does its
> > behavior change with different reclaim constraints. Having either
> > would make its design too complex to implement or benchmark.
> 
> Let me clarify. By "partially enabled" I really meant behavior depedning
> on runtime conditions. Say mmap_sem cannot be locked for half of scanned
> tasks and/or allocation for the mm walker fails due to lack of memory.
> How does this going to affect reclaim efficiency.

Understood. This is not only possible -- it's the default for our ARM
hardware that doesn't support the accessed bit, i.e., CPUs that don't
automatically set the accessed bit.

In try_to_inc_max_seq(), we have:
    /*
     * If the hardware doesn't automatically set the accessed bit, fallback
     * to lru_gen_look_around(), which only clears the accessed bit in a
     * handful of PTEs. Spreading the work out over a period of time usually
     * is less efficient, but it avoids bursty page faults.
     */
    if the accessed bit is not supported
        return

    if alloc_mm_walk() fails
        return

    walk_mm()
        if mmap_sem contented
            return

        scan page tables

We have a microbenchmark that specifically measures this worst case
scenario by entirely disabling page table scanning. Its results showed
that this still retains more than 90% of the optimal performance. I'll
share this microbenchmark in another email when answering Barry's
questions regarding the accessed bit.

Our profiling infra also indirectly confirms this: it collects data
from real users running on hardware with and without the accessed
bit. Users running on hardware without the accessed bit indeed suffer
a small performance degradation, compared with users running on
hardware with it. But they still benefit almost as much, compared with
users running on the same hardware but without MGLRU.

> How does a user/admin
> know that the memory reclaim is in a "degraded" mode because of the
> contention?

As we previously discussed here:
https://lore.kernel.org/linux-mm/Ydu6fXg2FmrseQOn at google.com/
there used to be a counter measuring the contention, and it was deemed
unnecessary and removed in v4. But I don't have a problem if we want
to revive it.


From yuzhao at google.com  Sun Jan 23 13:40:36 2022
From: yuzhao at google.com (Yu Zhao)
Date: Sun, 23 Jan 2022 14:40:36 -0700
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <YeATr//U6XD87fWF@dhcp22.suse.cz>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <Ydxlg5rI4ZvODQvF@dhcp22.suse.cz> <Yd4oaUwHkpadAKwe@google.com>
 <Yd6q0QdLVTS53vu4@dhcp22.suse.cz> <Yd9nk0qlK3jK9baN@google.com>
 <YeATr//U6XD87fWF@dhcp22.suse.cz>
Message-ID: <Ye3LVBuWBcPGd1Es@google.com>

On Thu, Jan 13, 2022 at 12:57:35PM +0100, Michal Hocko wrote:
> On Wed 12-01-22 16:43:15, Yu Zhao wrote:
> > On Wed, Jan 12, 2022 at 11:17:53AM +0100, Michal Hocko wrote:
> [...]
> > > Is there any reason you are not using folio_memcg_lock in the
> > > pte walk instead?
> > 
> > We have a particular lruvec (the first arg), hence a particular memcg
> > to lock. But we don't have a particular page to lock.
> 
> That is certainly true at this layer but the locking should be needed
> only for specific pages, no?

Yes.

> So you can move the lock down to the
> callback which examines respective pages. Or is there anything
> preventing that?

No.

> To be honest, and that is the reason I am asking, I really do not like
> to open code the migration synchronization outside of the memcg proper.

Agreed.

> Code paths which need a stable memcg are supposed to be using
> folio_memcg_lock for the specific examination time.

No argument here, just a clarification: when possible I prefer to
lock a batch of pages rather than individual ones.

> If you prefer a
> trylock approach for this usecase then we can add one.

Done. Thanks.


From laurent.pinchart at ideasonboard.com  Sun Jan 23 14:15:08 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Mon, 24 Jan 2022 00:15:08 +0200
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <20220119023714.1498508-1-victor.liu@nxp.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
Message-ID: <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>

Hi Liu,

Thank you for the patch.

On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> mentions that it should be in UI.  However, the dphy core driver wrongly
> sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> is '8 UI', instead of 8.

I'm not sure I'd change the kernel doc. Other fields that are documented
as "Time, in picoseconds" have min/max values expressed in ps, so
clk_pre, documented as "Time, in UI" doesn't appear wrong if the minimum
value is "8 UI".

Otherwise, this patch looks fine to me. With or without dropping that
documentation change,

Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

> So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
> member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
> value according to the D-PHY specification.
> 
> I'm assuming that all impacted custom drivers shall program values in
> TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
> specification mentions that the frequency of TxByteClkHS is exactly 1/8
> the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
> custom driver code is changed to program those values as
> DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.
> 
> Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
> Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
> as I don't have the hardwares.
> 
> Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
> Cc: Andrzej Hajda <andrzej.hajda at intel.com>
> Cc: Neil Armstrong <narmstrong at baylibre.com>
> Cc: Robert Foss <robert.foss at linaro.org>
> Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
> Cc: Jonas Karlman <jonas at kwiboo.se>
> Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
> Cc: David Airlie <airlied at linux.ie>
> Cc: Daniel Vetter <daniel at ffwll.ch>
> Cc: Kishon Vijay Abraham I <kishon at ti.com>
> Cc: Vinod Koul <vkoul at kernel.org>
> Cc: Kevin Hilman <khilman at baylibre.com>
> Cc: Jerome Brunet <jbrunet at baylibre.com>
> Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
> Cc: Heiko Stuebner <heiko at sntech.de>
> Cc: Maxime Ripard <mripard at kernel.org>
> Cc: Guido G?nther <agx at sigxcpu.org>
> Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
> Signed-off-by: Liu Ying <victor.liu at nxp.com>
> ---
> v1->v2:
> * Use BITS_PER_BYTE macro. (Andrzej)
> * Drop dsi argument from ui2bc() in nwl-dsi.c.
> 
>  drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
>  drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
>  drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
>  drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
>  include/linux/phy/phy-mipi-dphy.h                |  2 +-
>  5 files changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
> index a7389a0facfb..af07eeb47ca0 100644
> --- a/drivers/gpu/drm/bridge/nwl-dsi.c
> +++ b/drivers/gpu/drm/bridge/nwl-dsi.c
> @@ -7,6 +7,7 @@
>   */
>  
>  #include <linux/bitfield.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/irq.h>
>  #include <linux/math64.h>
> @@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
>  /*
>   * ui2bc - UI time periods to byte clock cycles
>   */
> -static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
> +static u32 ui2bc(unsigned int ui)
>  {
> -	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
> -
> -	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
> -				  dsi->mode.clock * 1000 * bpp);
> +	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
>  }
>  
>  /*
> @@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
>  	}
>  
>  	/* values in byte clock cycles */
> -	cycles = ui2bc(dsi, cfg->clk_pre);
> +	cycles = ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
>  	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
> -	cycles += ui2bc(dsi, cfg->clk_pre);
> +	cycles += ui2bc(cfg->clk_pre);
>  	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
>  	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
>  	cycles = ps2bc(dsi, cfg->hs_exit);
> diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> index cd2332bf0e31..fdbd64c03e12 100644
> --- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> +++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
> @@ -9,6 +9,7 @@
>  
>  #include <linux/bitfield.h>
>  #include <linux/bitops.h>
> +#include <linux/bits.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/io.h>
> @@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
>  		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
>  		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
>  	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
> -		     DIV_ROUND_UP(priv->config.clk_pre, temp));
> +		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
>  
>  	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
>  		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
> diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
> index 288c9c67aa74..ccb4045685cd 100644
> --- a/drivers/phy/phy-core-mipi-dphy.c
> +++ b/drivers/phy/phy-core-mipi-dphy.c
> @@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
>  
>  	cfg->clk_miss = 0;
>  	cfg->clk_post = 60000 + 52 * ui;
> -	cfg->clk_pre = 8000;
> +	cfg->clk_pre = 8;
>  	cfg->clk_prepare = 38000;
>  	cfg->clk_settle = 95000;
>  	cfg->clk_term_en = 0;
> @@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
>  	if (cfg->clk_post < (60000 + 52 * ui))
>  		return -EINVAL;
>  
> -	if (cfg->clk_pre < 8000)
> +	if (cfg->clk_pre < 8)
>  		return -EINVAL;
>  
>  	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
> diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> index 347dc79a18c1..630e01b5c19b 100644
> --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
> @@ -5,6 +5,7 @@
>   * Author: Wyon Bi <bivvy.bi at rock-chips.com>
>   */
>  
> +#include <linux/bits.h>
>  #include <linux/kernel.h>
>  #include <linux/clk.h>
>  #include <linux/iopoll.h>
> @@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
>  	 * The value of counter for HS Tclk-pre
>  	 * Tclk-pre = Tpin_txbyteclkhs * value
>  	 */
> -	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
> +	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
>  
>  	/*
>  	 * The value of counter for HS Tlpx Time
> diff --git a/include/linux/phy/phy-mipi-dphy.h b/include/linux/phy/phy-mipi-dphy.h
> index a877ffee845d..59a5e77ab409 100644
> --- a/include/linux/phy/phy-mipi-dphy.h
> +++ b/include/linux/phy/phy-mipi-dphy.h
> @@ -42,7 +42,7 @@ struct phy_configure_opts_mipi_dphy {
>  	 * the transmitter prior to any associated Data Lane beginning
>  	 * the transition from LP to HS mode.
>  	 *
> -	 * Minimum value: 8 UI
> +	 * Minimum value: 8
>  	 */
>  	unsigned int		clk_pre;
>  

-- 
Regards,

Laurent Pinchart


From mst at redhat.com  Sun Jan 23 14:40:08 2022
From: mst at redhat.com (Michael S. Tsirkin)
Date: Sun, 23 Jan 2022 17:40:08 -0500
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20220123200254.GF6113@e120937-lin>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
 <20220119122338.GE6113@e120937-lin>
 <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>
 <20220120150418-mutt-send-email-mst@kernel.org>
 <20220123200254.GF6113@e120937-lin>
Message-ID: <20220123172950-mutt-send-email-mst@kernel.org>

On Sun, Jan 23, 2022 at 08:02:54PM +0000, Cristian Marussi wrote:
> I was thinking...keeping the current virtqueue_poll interface, since our
> possible issue arises from the used_index wrapping around exactly on top
> of the same polled index and given that currently the API returns an
> unsigned "opaque" value really carrying just the 16-bit index (and possibly
> the wrap bit as bit15 for packed vq) that is supposed to be fed back as
> it is to the virtqueue_poll() function....
> 
> ...why don't we just keep an internal full fledged per-virtqueue wrap-counter
> and return that as the MSB 16-bit of the opaque value returned by
> virtqueue_prepare_enable_cb and then check it back in virtqueue_poll when the
> opaque is fed back ? (filtering it out from the internal helpers machinery)
> 
> As in the example below the scissors.
> 
> I mean if the internal wrap count is at that point different from the
> one provided to virtqueue_poll() via the opaque poll_idx value previously
> provided, certainly there is something new to fetch without even looking
> at the indexes: at the same time, exposing an opaque index built as
> (wraps << 16 | idx) implicitly 'binds' each index to a specific
> wrap-iteration, so they can be distiguished (..ok until the wrap-count
> upper 16bit wraps too....but...)
> 
> I am not really extremely familiar with the internals of virtio so I
> could be missing something obvious...feel free to insult me :P
> 
> (..and I have not made any perf measurements or consideration at this
> point....nor considered the redundancy of the existent packed
> used_wrap_counter bit...)
> 
> Thanks,
> Cristian
> 
> ----
> 
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index 00f64f2f8b72..bda6af121cd7 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -117,6 +117,8 @@ struct vring_virtqueue {
>         /* Last used index we've seen. */
>         u16 last_used_idx;
>  
> +       u16 wraps;
> +
>         /* Hint for event idx: already triggered no need to disable. */
>         bool event_triggered;
>  
> @@ -806,6 +808,8 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue *_vq,
>         ret = vq->split.desc_state[i].data;
>         detach_buf_split(vq, i, ctx);
>         vq->last_used_idx++;
> +       if (unlikely(!vq->last_used_idx))
> +               vq->wraps++;

I wonder whether
               vq->wraps += !vq->last_used_idx;
is faster or slower. No branch but OTOH a dependency.


>         /* If we expect an interrupt for the next entry, tell host
>          * by writing event index and flush out the write before
>          * the read in the next get_buf call. */
> @@ -1508,6 +1512,7 @@ static void *virtqueue_get_buf_ctx_packed(struct virtqueue *_vq,
>         if (unlikely(vq->last_used_idx >= vq->packed.vring.num)) {
>                 vq->last_used_idx -= vq->packed.vring.num;
>                 vq->packed.used_wrap_counter ^= 1;
> +               vq->wraps++;
>         }
>  
>         /*
> @@ -1744,6 +1749,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
>         vq->weak_barriers = weak_barriers;
>         vq->broken = false;
>         vq->last_used_idx = 0;
> +       vq->wraps = 0;
>         vq->event_triggered = false;
>         vq->num_added = 0;
>         vq->packed_ring = true;
> @@ -2092,13 +2098,17 @@ EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
>   */
>  unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
>  {
> +       unsigned last_used_idx;
>         struct vring_virtqueue *vq = to_vvq(_vq);
>  
>         if (vq->event_triggered)
>                 vq->event_triggered = false;
>  
> -       return vq->packed_ring ? virtqueue_enable_cb_prepare_packed(_vq) :
> -                                virtqueue_enable_cb_prepare_split(_vq);
> +       last_used_idx = vq->packed_ring ?
> +                       virtqueue_enable_cb_prepare_packed(_vq) :
> +                       virtqueue_enable_cb_prepare_split(_vq);
> +
> +       return VRING_BUILD_OPAQUE(last_used_idx, vq->wraps);
>  }
>  EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare);
>  
> @@ -2118,9 +2128,13 @@ bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx)
>         if (unlikely(vq->broken))
>                 return false;
>  
> +       if (unlikely(vq->wraps != VRING_GET_WRAPS(last_used_idx)))
> +               return true;
> +
>         virtio_mb(vq->weak_barriers);
> -       return vq->packed_ring ? virtqueue_poll_packed(_vq, last_used_idx) :
> -                                virtqueue_poll_split(_vq, last_used_idx);
> +       return vq->packed_ring ?
> +               virtqueue_poll_packed(_vq, VRING_GET_IDX(last_used_idx)) :
> +                       virtqueue_poll_split(_vq, VRING_GET_IDX(last_used_idx));
>  }
>  EXPORT_SYMBOL_GPL(virtqueue_poll);
>  
> @@ -2245,6 +2259,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
>         vq->weak_barriers = weak_barriers;
>         vq->broken = false;
>         vq->last_used_idx = 0;
> +       vq->wraps = 0;
>         vq->event_triggered = false;
>         vq->num_added = 0;
>         vq->use_dma_api = vring_use_dma_api(vdev);
> diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
> index 476d3e5c0fe7..e6b03017ebd7 100644
> --- a/include/uapi/linux/virtio_ring.h
> +++ b/include/uapi/linux/virtio_ring.h
> @@ -77,6 +77,17 @@
>   */
>  #define VRING_PACKED_EVENT_F_WRAP_CTR  15
>  
> +#define VRING_IDX_MASK                                 GENMASK(15, 0)
> +#define VRING_GET_IDX(opaque)                          \
> +       ((u16)FIELD_GET(VRING_IDX_MASK, (opaque)))
> +
> +#define VRING_WRAPS_MASK                               GENMASK(31, 16)
> +#define VRING_GET_WRAPS(opaque)                                \
> +       ((u16)FIELD_GET(VRING_WRAPS_MASK, (opaque)))
> +
> +#define VRING_BUILD_OPAQUE(idx, wraps)                 \
> +       (FIELD_PREP(VRING_WRAPS_MASK, (wraps)) | ((idx) & VRING_IDX_MASK))
> +
>  /* We support indirect buffer descriptors */
>  #define VIRTIO_RING_F_INDIRECT_DESC    28

Yea I think this patch increases the time it takes to wrap around from
2^16 to 2^32 which seems good enough.
Need some comments to explain the logic.
Would be interesting to see perf data.

-- 
MST



From clg at kaod.org  Sun Jan 23 14:44:05 2022
From: clg at kaod.org (=?UTF-8?Q?C=c3=a9dric_Le_Goater?=)
Date: Sun, 23 Jan 2022 23:44:05 +0100
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <20220105063244.lno3xur64uepa7i5@ti.com>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com> <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com> <20220103171721.46c8e697@xps13>
 <YdSP6tKyQ2ZRUC+2@heinlein> <20220105063244.lno3xur64uepa7i5@ti.com>
Message-ID: <d4ba6413-57ce-14c1-ed48-d00db2f74bd3@kaod.org>

>> I had an offline discussion with someone who knew more history on this driver.
>> My understanding is that the linux-aspeed team is aware of this being deprecated
>> but that there was some missing support for interface training that nobody has
>> gotten around to write?  If that is the case this really isn't even a "simple"
>> port to a new API at this point.
> 
> Unless the controller needs some unique feature (I don't think it does
> on a quick glance), the conversion should not be too difficult. For any
> experienced developer, even if they are unfamiliar with the SPI MEM API,
> I don't think it should take more than 2-3 days to do the conversion.
> The code to program the registers would stay the same, all that needs to
> change is the API through which it is accessed.

Writing a spimem driver is not a problem, I think people have done
that in house. Aspeed has one for AST2600. We have one for u-boot
I wrote sometime ago. I even have one for Linux but training comes
with ugly hacks to fit in the current stack.

All Aspeed SoCs need training and that has been the problem for the
last 4 years or so because we can not do training without knowing
a minimum about the flash being trained :/ The previous framework
offered a way to do a first scan and tune the delay settings
afterwards. It worked pretty well on AST2400, AST2500 and AST2600
even if more complex.

One alternative was to include the setting in the DT but the flash
modules are not always soldered on the boards, at least on OpenPOWER
systems which have sockets for them. The board are large, the wires
long, the need is real, some chips freak out if not tuned correctly.

spimem needs an extension I think. Sorry I have not been able to
push that forward. Lack of time and other tasks to address on the
host side of the machine. This is really a software problem, we
have the HW procedures ready. If a spimem expert could get involved
to make a few proposals, I would be happy to help and do some testing.
QEMU models are good enough for the software part. We can do the
training validation on real HW when ready.

Thanks,

C.


From cristian.marussi at arm.com  Sun Jan 23 14:45:54 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Sun, 23 Jan 2022 22:45:54 +0000
Subject: [PATCH v9 09/11] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <20220123172950-mutt-send-email-mst@kernel.org>
References: <20211220195646.44498-10-cristian.marussi@arm.com>
 <20211221140027.41524-1-cristian.marussi@arm.com>
 <f231094a-6f34-3dc1-237d-97218e8fde91@opensynergy.com>
 <20220119122338.GE6113@e120937-lin>
 <2f1ea794-a0b9-2099-edc0-b2aeb3ca6b92@opensynergy.com>
 <20220120150418-mutt-send-email-mst@kernel.org>
 <20220123200254.GF6113@e120937-lin>
 <20220123172950-mutt-send-email-mst@kernel.org>
Message-ID: <20220123224554.GG6113@e120937-lin>

On Sun, Jan 23, 2022 at 05:40:08PM -0500, Michael S. Tsirkin wrote:
> On Sun, Jan 23, 2022 at 08:02:54PM +0000, Cristian Marussi wrote:
> > I was thinking...keeping the current virtqueue_poll interface, since our
> > possible issue arises from the used_index wrapping around exactly on top
> > of the same polled index and given that currently the API returns an
> > unsigned "opaque" value really carrying just the 16-bit index (and possibly
> > the wrap bit as bit15 for packed vq) that is supposed to be fed back as
> > it is to the virtqueue_poll() function....
> > 
> > ...why don't we just keep an internal full fledged per-virtqueue wrap-counter
> > and return that as the MSB 16-bit of the opaque value returned by
> > virtqueue_prepare_enable_cb and then check it back in virtqueue_poll when the
> > opaque is fed back ? (filtering it out from the internal helpers machinery)
> > 
> > As in the example below the scissors.
> > 
> > I mean if the internal wrap count is at that point different from the
> > one provided to virtqueue_poll() via the opaque poll_idx value previously
> > provided, certainly there is something new to fetch without even looking
> > at the indexes: at the same time, exposing an opaque index built as
> > (wraps << 16 | idx) implicitly 'binds' each index to a specific
> > wrap-iteration, so they can be distiguished (..ok until the wrap-count
> > upper 16bit wraps too....but...)
> > 
> > I am not really extremely familiar with the internals of virtio so I
> > could be missing something obvious...feel free to insult me :P
> > 
> > (..and I have not made any perf measurements or consideration at this
> > point....nor considered the redundancy of the existent packed
> > used_wrap_counter bit...)
> > 
> > Thanks,
> > Cristian
> > 
> > ----
> > 
> > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > index 00f64f2f8b72..bda6af121cd7 100644
> > --- a/drivers/virtio/virtio_ring.c
> > +++ b/drivers/virtio/virtio_ring.c
> > @@ -117,6 +117,8 @@ struct vring_virtqueue {
> >         /* Last used index we've seen. */
> >         u16 last_used_idx;
> >  
> > +       u16 wraps;
> > +
> >         /* Hint for event idx: already triggered no need to disable. */
> >         bool event_triggered;
> >  
> > @@ -806,6 +808,8 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue *_vq,
> >         ret = vq->split.desc_state[i].data;
> >         detach_buf_split(vq, i, ctx);
> >         vq->last_used_idx++;
> > +       if (unlikely(!vq->last_used_idx))
> > +               vq->wraps++;
> 
> I wonder whether
>                vq->wraps += !vq->last_used_idx;
> is faster or slower. No branch but OTOH a dependency.
> 
> 
> >         /* If we expect an interrupt for the next entry, tell host
> >          * by writing event index and flush out the write before
> >          * the read in the next get_buf call. */
> > @@ -1508,6 +1512,7 @@ static void *virtqueue_get_buf_ctx_packed(struct virtqueue *_vq,
> >         if (unlikely(vq->last_used_idx >= vq->packed.vring.num)) {
> >                 vq->last_used_idx -= vq->packed.vring.num;
> >                 vq->packed.used_wrap_counter ^= 1;
> > +               vq->wraps++;
> >         }
> >  
> >         /*
> > @@ -1744,6 +1749,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
> >         vq->weak_barriers = weak_barriers;
> >         vq->broken = false;
> >         vq->last_used_idx = 0;
> > +       vq->wraps = 0;
> >         vq->event_triggered = false;
> >         vq->num_added = 0;
> >         vq->packed_ring = true;
> > @@ -2092,13 +2098,17 @@ EXPORT_SYMBOL_GPL(virtqueue_disable_cb);
> >   */
> >  unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
> >  {
> > +       unsigned last_used_idx;
> >         struct vring_virtqueue *vq = to_vvq(_vq);
> >  
> >         if (vq->event_triggered)
> >                 vq->event_triggered = false;
> >  
> > -       return vq->packed_ring ? virtqueue_enable_cb_prepare_packed(_vq) :
> > -                                virtqueue_enable_cb_prepare_split(_vq);
> > +       last_used_idx = vq->packed_ring ?
> > +                       virtqueue_enable_cb_prepare_packed(_vq) :
> > +                       virtqueue_enable_cb_prepare_split(_vq);
> > +
> > +       return VRING_BUILD_OPAQUE(last_used_idx, vq->wraps);
> >  }
> >  EXPORT_SYMBOL_GPL(virtqueue_enable_cb_prepare);
> >  
> > @@ -2118,9 +2128,13 @@ bool virtqueue_poll(struct virtqueue *_vq, unsigned last_used_idx)
> >         if (unlikely(vq->broken))
> >                 return false;
> >  
> > +       if (unlikely(vq->wraps != VRING_GET_WRAPS(last_used_idx)))
> > +               return true;
> > +
> >         virtio_mb(vq->weak_barriers);
> > -       return vq->packed_ring ? virtqueue_poll_packed(_vq, last_used_idx) :
> > -                                virtqueue_poll_split(_vq, last_used_idx);
> > +       return vq->packed_ring ?
> > +               virtqueue_poll_packed(_vq, VRING_GET_IDX(last_used_idx)) :
> > +                       virtqueue_poll_split(_vq, VRING_GET_IDX(last_used_idx));
> >  }
> >  EXPORT_SYMBOL_GPL(virtqueue_poll);
> >  
> > @@ -2245,6 +2259,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
> >         vq->weak_barriers = weak_barriers;
> >         vq->broken = false;
> >         vq->last_used_idx = 0;
> > +       vq->wraps = 0;
> >         vq->event_triggered = false;
> >         vq->num_added = 0;
> >         vq->use_dma_api = vring_use_dma_api(vdev);
> > diff --git a/include/uapi/linux/virtio_ring.h b/include/uapi/linux/virtio_ring.h
> > index 476d3e5c0fe7..e6b03017ebd7 100644
> > --- a/include/uapi/linux/virtio_ring.h
> > +++ b/include/uapi/linux/virtio_ring.h
> > @@ -77,6 +77,17 @@
> >   */
> >  #define VRING_PACKED_EVENT_F_WRAP_CTR  15
> >  
> > +#define VRING_IDX_MASK                                 GENMASK(15, 0)
> > +#define VRING_GET_IDX(opaque)                          \
> > +       ((u16)FIELD_GET(VRING_IDX_MASK, (opaque)))
> > +
> > +#define VRING_WRAPS_MASK                               GENMASK(31, 16)
> > +#define VRING_GET_WRAPS(opaque)                                \
> > +       ((u16)FIELD_GET(VRING_WRAPS_MASK, (opaque)))
> > +
> > +#define VRING_BUILD_OPAQUE(idx, wraps)                 \
> > +       (FIELD_PREP(VRING_WRAPS_MASK, (wraps)) | ((idx) & VRING_IDX_MASK))
> > +
> >  /* We support indirect buffer descriptors */
> >  #define VIRTIO_RING_F_INDIRECT_DESC    28
> 
> Yea I think this patch increases the time it takes to wrap around from
> 2^16 to 2^32 which seems good enough.
> Need some comments to explain the logic.
> Would be interesting to see perf data.
> 

Thanks for your feedback !

I'll try to gather some perf data around it next days.
(and eventually cleanup and adding comments if it is god enough...)

Thanks,
Cristian



From kernelfans at gmail.com  Sun Jan 23 17:02:29 2022
From: kernelfans at gmail.com (Pingfan Liu)
Date: Mon, 24 Jan 2022 09:02:29 +0800
Subject: [PATCHv3 0/4] watchdog_hld cleanup and async model for arm64
In-Reply-To: <20220117101910.14999-1-lecopzer.chen@mediatek.com>
References: <20211014024155.15253-1-kernelfans@gmail.com>
 <20220117101910.14999-1-lecopzer.chen@mediatek.com>
Message-ID: <CAFgQCTtBXWd_+13-AR8LWjLbWq9rX6kAjFmMCC=WpkzmtD-3Og@mail.gmail.com>

On Mon, Jan 17, 2022 at 6:19 PM Lecopzer Chen
<lecopzer.chen at mediatek.com> wrote:
>
> Hi Pingfan,
>
> Is this thread sill in progress?

No, I am working on other topic at present, and this is not in my
queue in near future.
> We are looking for the upstream solution for ARM64 Hardlockup detector.
>
> I'd appreciate it if someone keep working on it,
> if not, I can take over it.
>
Be my guest, and hope you have great work. We badly wants hardlock up
detector on arm64

Best Regards,

Pingfan


From chiawei_wang at aspeedtech.com  Sun Jan 23 17:43:51 2022
From: chiawei_wang at aspeedtech.com (Chia-Wei Wang)
Date: Mon, 24 Jan 2022 09:43:51 +0800
Subject: [PATCH next] docs/ABI: testing: aspeed-uart-routing: Escape asterisk
Message-ID: <20220124014351.9121-1-chiawei_wang@aspeedtech.com>

Escape asterisk symbols to fix the following warning:

"WARNING: Inline emphasis start-string without end-string"

Fixes: c6807970c3bc ("soc: aspeed: Add UART routing support")
Signed-off-by: Chia-Wei Wang <chiawei_wang at aspeedtech.com>
---
 Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing b/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
index b363827da437..910df0e5815a 100644
--- a/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
+++ b/Documentation/ABI/testing/sysfs-driver-aspeed-uart-routing
@@ -1,4 +1,4 @@
-What:		/sys/bus/platform/drivers/aspeed-uart-routing/*/uart*
+What:		/sys/bus/platform/drivers/aspeed-uart-routing/\*/uart\*
 Date:		September 2021
 Contact:	Oskar Senft <osk at google.com>
 		Chia-Wei Wang <chiawei_wang at aspeedtech.com>
@@ -9,7 +9,7 @@ Description:	Selects the RX source of the UARTx device.
 		depends on the selected file.
 
 		e.g.
-		cat /sys/bus/platform/drivers/aspeed-uart-routing/*.uart_routing/uart1
+		cat /sys/bus/platform/drivers/aspeed-uart-routing/\*.uart_routing/uart1
 		[io1] io2 io3 io4 uart2 uart3 uart4 io6
 
 		In this case, UART1 gets its input from IO1 (physical serial port 1).
@@ -17,7 +17,7 @@ Description:	Selects the RX source of the UARTx device.
 Users:		OpenBMC.  Proposed changes should be mailed to
 		openbmc at lists.ozlabs.org
 
-What:		/sys/bus/platform/drivers/aspeed-uart-routing/*/io*
+What:		/sys/bus/platform/drivers/aspeed-uart-routing/\*/io\*
 Date:		September 2021
 Contact:	Oskar Senft <osk at google.com>
 		Chia-Wei Wang <chiawei_wang at aspeedtech.com>
-- 
2.25.1



From aford173 at gmail.com  Sun Jan 23 18:31:14 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:14 -0600
Subject: [PATCH V3 00/10] media: hantro: imx8mq/imx8mm: Let VPU decoders get
 controlled by vpu-blk-ctrl
Message-ID: <20220124023125.414794-1-aford173@gmail.com>

Both the i.MX8MQ and i.MX8MM have G1 and G2 decoders.
The two decoders are similar, but the imx8mm lacks the
post-processor, so they will have distinct compatible flags.

>From what I can tell, the G2 decoder wasn't working, so splitting
the i.MX8MQ VPU into G1 and G2 makes it easier to control them
independently since the TRM of both the i.MX8MQ and
i.MX8MM list them as distinct IP blocks. This also allowed G2 to
become available.

With them being split, the power-domain can shift to the
vpu-blk-ctrl which is available on both i.MX8MQ and i.MX8MM,
but some of bits are different, so they'll have separate bindings.

Lastly, with the G1 and G2 operational, enable the i.MX8MM.
On the i.MX8MM, the clock speed of 600MHz was chosen to match
the default of the kernel repo from NXP and can be overwritten
by board files for anyone who under/over volts the power rail.

There seems to be some disagreement between the TRM and the Datasheet
for the imx8mq as to whether the speed should be 300MHz (TRM) or
600MHz (datasheet), so feedback from NXP would be very much
appreciated.

The repo used as the starting point was:
5.17-rc1

Fluster was run on both i.MX8MM and i.MX8MQ

At 600 MHz, the i.MX8MM had the following:

./fluster.py run -d GStreamer-VP8-V4L2SL-Gst1.0
Ran 55/61 tests successfully               in 8.299 secs

./fluster.py run -dGStreamer-H.264-V4L2SL-Gst1.0
Ran 90/135 tests successfully               in 71.200 secs

./fluster.py run -d GStreamer-VP9-V4L2SL-Gst1.0
Ran 139/303 tests successfully               in 218.079 secs

The i.MX8MQ had the following:

./fluster.py run -d GStreamer-VP8-V4L2SL-Gst1.0
Ran 55/61 tests successfully               in 7.732 secs

./fluster.py run -dGStreamer-H.264-V4L2SL-Gst1.0
Ran 90/135 tests successfully               in 58.558 secs

./fluster.py run -d GStreamer-VP9-V4L2SL-Gst1.0
Ran 144/303 tests successfully               in 271.373 secs

V3:  Rebase on 5.17-RC1.
     Remove imx8mm-vpu-g2 since it's identical to imx8mq-vpu-g2
     Remove unnecessary examples in YAML files.
     Remove some unused variables.

V2:  Remove references to legacy dt-binding from YAML, but keep
     it in the driver so older device trees can still be used.
     Fix typos in YAML
     Remove reg-names, interrupt-names, and clock-names from YAML,
     since each node will only have one of each, they're not necessary
     Add Fluster scores to cover letter for i.MX8MQ


Adam Ford (7):
  dt-bindings: media: nxp, imx8mq-vpu: Split G1 and G2 nodes
  media: hantro: Allow i.MX8MQ G1 and G2 to run independently
  arm64: dts: imx8mq: Enable both G1 and G2 VPU's with vpu-blk-ctrl
  arm64: dts: imx8mm: Fix VPU Hanging
  dt-bindings: media: nxp, imx8mq-vpu: Add support for G1 on imx8mm
  media: hantro: Add support for i.MX8MM Hantro-G1
  arm64: dts: imx8mm: Enable Hantro G1 and G2 video decoders

Lucas Stach (3):
  dt-bindings: power: imx8mq: add defines for VPU blk-ctrl domains
  dt-bindings: soc: add binding for i.MX8MQ VPU blk-ctrl
  soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl

 .../bindings/media/nxp,imx8mq-vpu.yaml        | 68 ++++++++----------
 .../soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml      | 71 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     | 23 +++++-
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     | 63 +++++++++-------
 drivers/soc/imx/imx8m-blk-ctrl.c              | 66 +++++++++++++++++
 drivers/staging/media/hantro/hantro_drv.c     |  2 +
 drivers/staging/media/hantro/hantro_hw.h      |  2 +
 drivers/staging/media/hantro/imx8m_vpu_hw.c   | 62 ++++++++++++----
 include/dt-bindings/power/imx8mq-power.h      |  3 +
 9 files changed, 283 insertions(+), 77 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:15 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:15 -0600
Subject: [PATCH V3 01/10] dt-bindings: power: imx8mq: add defines for VPU
 blk-ctrl domains
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-2-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the defines for the power domains provided by the VPU
blk-ctrl on the i.MX8MQ.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Acked-by: Rob Herring <robh at kernel.org>

diff --git a/include/dt-bindings/power/imx8mq-power.h b/include/dt-bindings/power/imx8mq-power.h
index 8a513bd9166e..9f7d0f1e7c32 100644
--- a/include/dt-bindings/power/imx8mq-power.h
+++ b/include/dt-bindings/power/imx8mq-power.h
@@ -18,4 +18,7 @@
 #define IMX8M_POWER_DOMAIN_MIPI_CSI2	9
 #define IMX8M_POWER_DOMAIN_PCIE2	10
 
+#define IMX8MQ_VPUBLK_PD_G1		0
+#define IMX8MQ_VPUBLK_PD_G2		1
+
 #endif
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:16 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:16 -0600
Subject: [PATCH V3 02/10] dt-bindings: soc: add binding for i.MX8MQ VPU
 blk-ctrl
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-3-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the DT binding for the i.MX8MQ VPU blk-ctrl.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Rob Herring <robh at kernel.org>

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
new file mode 100644
index 000000000000..7263ebedf09f
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MQ VPU blk-ctrl
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+description:
+  The i.MX8MQ VPU blk-ctrl is a top-level peripheral providing access to
+  the NoC and ensuring proper power sequencing of the VPU peripherals
+  located in the VPU domain of the SoC.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx8mq-vpu-blk-ctrl
+
+  reg:
+    maxItems: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  power-domains:
+    minItems: 3
+    maxItems: 3
+
+  power-domain-names:
+    items:
+      - const: bus
+      - const: g1
+      - const: g2
+
+  clocks:
+    minItems: 2
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: g1
+      - const: g2
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - power-domain-names
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+
+    vpu_blk_ctrl: blk-ctrl at 38320000 {
+      compatible = "fsl,imx8mq-vpu-blk-ctrl";
+      reg = <0x38320000 0x100>;
+      power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+      power-domain-names = "bus", "g1", "g2";
+      clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+               <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+      clock-names = "g1", "g2";
+      #power-domain-cells = <1>;
+    };
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:17 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:17 -0600
Subject: [PATCH V3 03/10] soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-4-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the necessary bits to drive the VPU blk-ctrl on the i.MX8MQ, to
avoid putting more of this functionality into the decoder driver.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 511e74f0db8a..122f9c884b38 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -15,6 +15,7 @@
 
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
+#include <dt-bindings/power/imx8mq-power.h>
 
 #define BLK_SFT_RSTN	0x0
 #define BLK_CLK_EN	0x4
@@ -589,6 +590,68 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
 	.num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
 };
 
+static int imx8mq_vpu_power_notifier(struct notifier_block *nb,
+				     unsigned long action, void *data)
+{
+	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+						 power_nb);
+
+	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
+		return NOTIFY_OK;
+
+	/*
+	 * The ADB in the VPUMIX domain has no separate reset and clock
+	 * enable bits, but is ungated and reset together with the VPUs. The
+	 * reset and clock enable inputs to the ADB is a logical OR of the
+	 * VPU bits. In order to set the G2 fuse bits, the G2 clock must
+	 * also be enabled.
+	 */
+	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1));
+	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1));
+
+	if (action == GENPD_NOTIFY_ON) {
+		/*
+		 * On power up we have no software backchannel to the GPC to
+		 * wait for the ADB handshake to happen, so we just delay for a
+		 * bit. On power down the GPC driver waits for the handshake.
+		 */
+		udelay(5);
+
+		/* set "fuse" bits to enable the VPUs */
+		regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
+	}
+
+	return NOTIFY_OK;
+}
+
+static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = {
+	[IMX8MQ_VPUBLK_PD_G1] = {
+		.name = "vpublk-g1",
+		.clk_names = (const char *[]){ "g1", },
+		.num_clks = 1,
+		.gpc_name = "g1",
+		.rst_mask = BIT(1),
+		.clk_mask = BIT(1),
+	},
+	[IMX8MQ_VPUBLK_PD_G2] = {
+		.name = "vpublk-g2",
+		.clk_names = (const char *[]){ "g2", },
+		.num_clks = 1,
+		.gpc_name = "g2",
+		.rst_mask = BIT(0),
+		.clk_mask = BIT(0),
+	},
+};
+
+static const struct imx8m_blk_ctrl_data imx8mq_vpu_blk_ctl_dev_data = {
+	.max_reg = 0x14,
+	.power_notifier_fn = imx8mq_vpu_power_notifier,
+	.domains = imx8mq_vpu_blk_ctl_domain_data,
+	.num_domains = ARRAY_SIZE(imx8mq_vpu_blk_ctl_domain_data),
+};
+
 static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
 	{
 		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
@@ -599,6 +662,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
 	}, {
 		.compatible = "fsl,imx8mn-disp-blk-ctrl",
 		.data = &imx8mn_disp_blk_ctl_dev_data
+	}, {
+		.compatible = "fsl,imx8mq-vpu-blk-ctrl",
+		.data = &imx8mq_vpu_blk_ctl_dev_data
 	}, {
 		/* Sentinel */
 	}
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:18 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:18 -0600
Subject: [PATCH V3 04/10] dt-bindings: media: nxp,
 imx8mq-vpu: Split G1 and G2 nodes
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-5-aford173@gmail.com>

The G1 and G2 are independent and separate decoder blocks
that are enabled by the vpu-blk-ctrl power-domain controller,
which now has a proper driver.

Because these blocks only share the power-domain, and can be
independently fused out, update the bindings to support separate
nodes for the G1 and G2 decoders with vpu-blk-ctrl power-domain
support.

The new DT + old kernel isn't a supported configuration.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Rob Herring <robh at kernel.org>

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 762be3f96ce9..9c28d562112b 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -15,33 +15,20 @@ description:
 
 properties:
   compatible:
-    const: nxp,imx8mq-vpu
+    oneOf:
+      - const: nxp,imx8mq-vpu
+        deprecated: true
+      - const: nxp,imx8mq-vpu-g1
+      - const: nxp,imx8mq-vpu-g2
 
   reg:
-    maxItems: 3
-
-  reg-names:
-    items:
-      - const: g1
-      - const: g2
-      - const: ctrl
+    maxItems: 1
 
   interrupts:
-    maxItems: 2
-
-  interrupt-names:
-    items:
-      - const: g1
-      - const: g2
+    maxItems: 1
 
   clocks:
-    maxItems: 3
-
-  clock-names:
-    items:
-      - const: g1
-      - const: g2
-      - const: bus
+    maxItems: 1
 
   power-domains:
     maxItems: 1
@@ -49,31 +36,33 @@ properties:
 required:
   - compatible
   - reg
-  - reg-names
   - interrupts
-  - interrupt-names
   - clocks
-  - clock-names
 
 additionalProperties: false
 
 examples:
   - |
         #include <dt-bindings/clock/imx8mq-clock.h>
+        #include <dt-bindings/power/imx8mq-power.h>
+        #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+        vpu_g1: video-codec at 38300000 {
+                compatible = "nxp,imx8mq-vpu-g1";
+                reg = <0x38300000 0x10000>;
+                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+        };
+  - |
+        #include <dt-bindings/clock/imx8mq-clock.h>
+        #include <dt-bindings/power/imx8mq-power.h>
         #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu";
-                reg = <0x38300000 0x10000>,
-                      <0x38310000 0x10000>,
-                      <0x38320000 0x10000>;
-                reg-names = "g1", "g2", "ctrl";
-                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-                interrupt-names = "g1", "g2";
-                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
-                         <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
-                         <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
-                clock-names = "g1", "g2", "bus";
-                power-domains = <&pgc_vpu>;
+        vpu_g2: video-codec at 38300000 {
+                compatible = "nxp,imx8mq-vpu-g2";
+                reg = <0x38310000 0x10000>;
+                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
         };
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:19 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:19 -0600
Subject: [PATCH V3 05/10] media: hantro: Allow i.MX8MQ G1 and G2 to run
 independently
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-6-aford173@gmail.com>

The VPU in the i.MX8MQ is really the combination of Hantro G1 and
Hantro G2. With the updated vpu-blk-ctrl, the power domains system
can enable and disable them separately as well as pull them out of
reset. This simplifies the code and lets them run independently
while still retaining backwards compatibility with older device
trees for those using G1.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 6a51f39dde56..a670ddd29c4c 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -616,6 +616,7 @@ static const struct of_device_id of_hantro_match[] = {
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_IMX8M
 	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
+	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
 	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 4a19ae8940b9..f0bd2ffe290b 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -299,6 +299,7 @@ enum hantro_enc_fmt {
 	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
 };
 
+extern const struct hantro_variant imx8mq_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g2_variant;
 extern const struct hantro_variant imx8mq_vpu_variant;
 extern const struct hantro_variant px30_vpu_variant;
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index f5991b8e553a..849ea7122d47 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -205,13 +205,6 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
 	imx8m_soft_reset(vpu, RESET_G1);
 }
 
-static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-
-	imx8m_soft_reset(vpu, RESET_G2);
-}
-
 /*
  * Supported codec ops.
  */
@@ -237,17 +230,33 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
 	},
 };
 
+static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = {
+	[HANTRO_MODE_MPEG2_DEC] = {
+		.run = hantro_g1_mpeg2_dec_run,
+		.init = hantro_mpeg2_dec_init,
+		.exit = hantro_mpeg2_dec_exit,
+	},
+	[HANTRO_MODE_VP8_DEC] = {
+		.run = hantro_g1_vp8_dec_run,
+		.init = hantro_vp8_dec_init,
+		.exit = hantro_vp8_dec_exit,
+	},
+	[HANTRO_MODE_H264_DEC] = {
+		.run = hantro_g1_h264_dec_run,
+		.init = hantro_h264_dec_init,
+		.exit = hantro_h264_dec_exit,
+	},
+};
+
 static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
 	[HANTRO_MODE_HEVC_DEC] = {
 		.run = hantro_g2_hevc_dec_run,
-		.reset = imx8m_vpu_g2_reset,
 		.init = hantro_hevc_dec_init,
 		.exit = hantro_hevc_dec_exit,
 	},
 	[HANTRO_MODE_VP9_DEC] = {
 		.run = hantro_g2_vp9_dec_run,
 		.done = hantro_g2_vp9_dec_done,
-		.reset = imx8m_vpu_g2_reset,
 		.init = hantro_vp9_dec_init,
 		.exit = hantro_vp9_dec_exit,
 	},
@@ -267,6 +276,8 @@ static const struct hantro_irq imx8mq_g2_irqs[] = {
 
 static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
 static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };
+static const char * const imx8mq_g1_clk_names[] = { "g1" };
+static const char * const imx8mq_g2_clk_names[] = { "g2" };
 
 const struct hantro_variant imx8mq_vpu_variant = {
 	.dec_fmts = imx8m_vpu_dec_fmts,
@@ -287,6 +298,21 @@ const struct hantro_variant imx8mq_vpu_variant = {
 	.num_regs = ARRAY_SIZE(imx8mq_reg_names)
 };
 
+const struct hantro_variant imx8mq_vpu_g1_variant = {
+	.dec_fmts = imx8m_vpu_dec_fmts,
+	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
+	.postproc_fmts = imx8m_vpu_postproc_fmts,
+	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
+	.postproc_ops = &hantro_g1_postproc_ops,
+	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
+		 HANTRO_H264_DECODER,
+	.codec_ops = imx8mq_vpu_g1_codec_ops,
+	.irqs = imx8mq_irqs,
+	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
+	.clk_names = imx8mq_g1_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
+};
+
 const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.dec_offset = 0x0,
 	.dec_fmts = imx8m_vpu_g2_dec_fmts,
@@ -296,10 +322,8 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.postproc_ops = &hantro_g2_postproc_ops,
 	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
 	.codec_ops = imx8mq_vpu_g2_codec_ops,
-	.init = imx8mq_vpu_hw_init,
-	.runtime_resume = imx8mq_runtime_resume,
 	.irqs = imx8mq_g2_irqs,
 	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),
-	.clk_names = imx8mq_clk_names,
-	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),
+	.clk_names = imx8mq_g2_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
 };
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:20 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:20 -0600
Subject: [PATCH V3 06/10] arm64: dts: imx8mq: Enable both G1 and G2 VPU's with
 vpu-blk-ctrl
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-7-aford173@gmail.com>

With the Hantro G1 and G2 now setup to run independently, update
the device tree to allow both to operate.  This requires the
vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
certain clock enabled to handle the gating of the G1 and G2
fuses, the clock-parents and clock-rates for the various VPU's
to be moved into the pgc_vpu because they cannot get re-parented
once enabled, and the pgc_vpu is the highest in the chain.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 2df2510d0118..549b2440f55d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
 					pgc_vpu: power-domain at 6 {
 						#power-domain-cells = <0>;
 						reg = <IMX8M_POWER_DOMAIN_VPU>;
-						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
+							 <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+							 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+						assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
+								  <&clk IMX8MQ_CLK_VPU_G2>,
+								  <&clk IMX8MQ_CLK_VPU_BUS>,
+								  <&clk IMX8MQ_VPU_PLL_BYPASS>;
+						assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
+									 <&clk IMX8MQ_VPU_PLL_OUT>,
+									 <&clk IMX8MQ_SYS1_PLL_800M>,
+									 <&clk IMX8MQ_VPU_PLL>;
+						assigned-clock-rates = <600000000>,
+								       <600000000>,
+								       <800000000>,
+								       <0>;
 					};
 
 					pgc_disp: power-domain at 7 {
@@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
 			status = "disabled";
 		};
 
-		vpu: video-codec at 38300000 {
-			compatible = "nxp,imx8mq-vpu";
-			reg = <0x38300000 0x10000>,
-			      <0x38310000 0x10000>,
-			      <0x38320000 0x10000>;
-			reg-names = "g1", "g2", "ctrl";
-			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "g1", "g2";
+		vpu_g1: video-codec at 38300000 {
+			compatible = "nxp,imx8mq-vpu-g1";
+			reg = <0x38300000 0x10000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+		};
+
+		vpu_g2: video-codec at 38310000 {
+			compatible = "nxp,imx8mq-vpu-g2";
+			reg = <0x38310000 0x10000>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
+		};
+
+		vpu_blk_ctrl: blk-ctrl at 38320000 {
+			compatible = "fsl,imx8mq-vpu-blk-ctrl";
+			reg = <0x38320000 0x100>;
+			power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+			power-domain-names = "bus", "g1", "g2";
 			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
-				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
-				 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
-			clock-names = "g1", "g2", "bus";
-			assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
-					  <&clk IMX8MQ_CLK_VPU_G2>,
-					  <&clk IMX8MQ_CLK_VPU_BUS>,
-					  <&clk IMX8MQ_VPU_PLL_BYPASS>;
-			assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
-						 <&clk IMX8MQ_VPU_PLL_OUT>,
-						 <&clk IMX8MQ_SYS1_PLL_800M>,
-						 <&clk IMX8MQ_VPU_PLL>;
-			assigned-clock-rates = <600000000>, <600000000>,
-					       <800000000>, <0>;
-			power-domains = <&pgc_vpu>;
+				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+			clock-names = "g1", "g2";
+			#power-domain-cells = <1>;
 		};
 
 		pcie0: pcie at 33800000 {
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:21 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:21 -0600
Subject: [PATCH V3 07/10] arm64: dts: imx8mm: Fix VPU Hanging
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-8-aford173@gmail.com>

The vpumix power domain has a reset assigned to it, however
when used, it causes a system hang.  Testing has shown that
it does not appear to be needed anywhere.

Fixes: d39d4bb15310 ("arm64: dts: imx8mm: add GPC node")
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index f77f90ed416f..0c7a72c51a31 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -707,7 +707,6 @@ pgc_vpumix: power-domain at 6 {
 						clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
 						assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
 						assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
-						resets = <&src IMX8MQ_RESET_VPU_RESET>;
 					};
 
 					pgc_vpu_g1: power-domain at 7 {
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:22 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:22 -0600
Subject: [PATCH V3 08/10] dt-bindings: media: nxp,
 imx8mq-vpu: Add support for G1 on imx8mm
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-9-aford173@gmail.com>

The i.MX8M mini appears to have a similar G1 decoder but the
post-processing isn't present, so different compatible flag is required.
Since all the other parameters are the same with imx8mq, just add
the new compatible flag to nxp,imx8mq-vpu.yaml.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 9c28d562112b..7dc13a4b1805 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -5,7 +5,7 @@
 $id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
-title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
+title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
 
 maintainers:
   - Philipp Zabel <p.zabel at pengutronix.de>
@@ -20,6 +20,7 @@ properties:
         deprecated: true
       - const: nxp,imx8mq-vpu-g1
       - const: nxp,imx8mq-vpu-g2
+      - const: nxp,imx8mm-vpu-g1
 
   reg:
     maxItems: 1
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:23 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:23 -0600
Subject: [PATCH V3 09/10] media: hantro: Add support for i.MX8MM Hantro-G1
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-10-aford173@gmail.com>

The i.MX8MM has a Hantro G1 video decoder similar to the
imx8mq but lacks the post-processor present in the imx8mq.
Add support in the driver for it with the post-processing
removed.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index a670ddd29c4c..b281ac4fb79c 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -615,6 +615,7 @@ static const struct of_device_id of_hantro_match[] = {
 	{ .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_IMX8M
+	{ .compatible = "nxp,imx8mm-vpu-g1", .data = &imx8mm_vpu_g1_variant, },
 	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
 	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
 	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index f0bd2ffe290b..c00b46e06055 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -299,6 +299,7 @@ enum hantro_enc_fmt {
 	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
 };
 
+extern const struct hantro_variant imx8mm_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g2_variant;
 extern const struct hantro_variant imx8mq_vpu_variant;
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index 849ea7122d47..9802508bade2 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -327,3 +327,15 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.clk_names = imx8mq_g2_clk_names,
 	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
 };
+
+const struct hantro_variant imx8mm_vpu_g1_variant = {
+	.dec_fmts = imx8m_vpu_dec_fmts,
+	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
+	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
+		 HANTRO_H264_DECODER,
+	.codec_ops = imx8mq_vpu_g1_codec_ops,
+	.irqs = imx8mq_irqs,
+	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
+	.clk_names = imx8mq_g1_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
+};
-- 
2.32.0



From aford173 at gmail.com  Sun Jan 23 18:31:24 2022
From: aford173 at gmail.com (Adam Ford)
Date: Sun, 23 Jan 2022 20:31:24 -0600
Subject: [PATCH V3 10/10] arm64: dts: imx8mm: Enable Hantro G1 and G2 video
 decoders
In-Reply-To: <20220124023125.414794-1-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
Message-ID: <20220124023125.414794-11-aford173@gmail.com>

There are two decoders on the i.MX8M Mini controlled by the
vpu-blk-ctrl.  The G1 supports H264 and VP8 while the
G2 support HEVC and VP9.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 0c7a72c51a31..98aec4421713 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1272,6 +1272,22 @@ gpu_2d: gpu at 38008000 {
 			power-domains = <&pgc_gpu>;
 		};
 
+		vpu_g1: video-codec at 38300000 {
+			compatible = "nxp,imx8mm-vpu-g1";
+			reg = <0x38300000 0x10000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G1>;
+		};
+
+		vpu_g2: video-codec at 38310000 {
+			compatible = "nxp,imx8mq-vpu-g2";
+			reg = <0x38310000 0x10000>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G2>;
+		};
+
 		vpu_blk_ctrl: blk-ctrl at 38330000 {
 			compatible = "fsl,imx8mm-vpu-blk-ctrl", "syscon";
 			reg = <0x38330000 0x100>;
@@ -1282,6 +1298,12 @@ vpu_blk_ctrl: blk-ctrl at 38330000 {
 				 <&clk IMX8MM_CLK_VPU_G2_ROOT>,
 				 <&clk IMX8MM_CLK_VPU_H1_ROOT>;
 			clock-names = "g1", "g2", "h1";
+			assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>,
+					  <&clk IMX8MM_CLK_VPU_G2>;
+			assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>,
+						 <&clk IMX8MM_VPU_PLL_OUT>;
+			assigned-clock-rates = <600000000>,
+					       <600000000>;
 			#power-domain-cells = <1>;
 		};
 
-- 
2.32.0



From victor.liu at nxp.com  Sun Jan 23 18:31:48 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:31:48 +0800
Subject: [PATCH v2] phy: dphy: Correct clk_pre parameter
In-Reply-To: <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>
References: <20220119023714.1498508-1-victor.liu@nxp.com>
 <Ye3TbIj5LMvGVRIg@pendragon.ideasonboard.com>
Message-ID: <bd5a0d5ac47c4b139ef5eaaaa9dd8a4e5429516f.camel@nxp.com>

Hi Laurent,

On Mon, 2022-01-24 at 00:15 +0200, Laurent Pinchart wrote:
> Hi Liu,
> 
> Thank you for the patch.

Thank you for your review.

> 
> On Wed, Jan 19, 2022 at 10:37:14AM +0800, Liu Ying wrote:
> > The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
> > parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
> > kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
> > mentions that it should be in UI.  However, the dphy core driver wrongly
> > sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
> > And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
> > is '8 UI', instead of 8.
> 
> I'm not sure I'd change the kernel doc. Other fields that are documented
> as "Time, in picoseconds" have min/max values expressed in ps, so
> clk_pre, documented as "Time, in UI" doesn't appear wrong if the minimum
> value is "8 UI".
> 
> Otherwise, this patch looks fine to me. With or without dropping that
> documentation change,

I'll drop the documentation change in v3.

Regards,
Liu Ying

> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 



From victor.liu at nxp.com  Sun Jan 23 18:32:53 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:32:53 +0800
Subject: [PATCH v3] phy: dphy: Correct clk_pre parameter
Message-ID: <20220124023253.1457834-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.
And, the kernel doc of the 'clk_pre' member wrongly says the minimum value
is '8 UI', instead of 8.

So, let's fix both the dphy core driver and the kernel doc of the 'clk_pre'
member to correctly reflect the T-CLK-PRE parameter's unit and the minimum
value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Cc: Wyon Bi <bivvy.bi at rock-chips.com>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Guido G?nther <agx at sigxcpu.org> # Librem 5 (imx8mq) with it's rather picky panel
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v2->v3:
* Drop D-PHY documentation change. (Laurent)
* Collect R-b tags and T-b tags.
* Cc Wyon.

v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
-- 
2.25.1



From victor.liu at nxp.com  Sun Jan 23 18:40:07 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Mon, 24 Jan 2022 10:40:07 +0800
Subject: [PATCH v4] phy: dphy: Correct clk_pre parameter
Message-ID: <20220124024007.1465018-1-victor.liu@nxp.com>

The D-PHY specification (v1.2) explicitly mentions that the T-CLK-PRE
parameter's unit is Unit Interval(UI) and the minimum value is 8.  Also,
kernel doc of the 'clk_pre' member of struct phy_configure_opts_mipi_dphy
mentions that it should be in UI.  However, the dphy core driver wrongly
sets 'clk_pre' to 8000, which seems to hint that it's in picoseconds.

So, let's fix the dphy core driver to correctly reflect the T-CLK-PRE
parameter's minimum value according to the D-PHY specification.

I'm assuming that all impacted custom drivers shall program values in
TxByteClkHS cycles into hardware for the T-CLK-PRE parameter.  The D-PHY
specification mentions that the frequency of TxByteClkHS is exactly 1/8
the High-Speed(HS) bit rate(each HS bit consumes one UI).  So, relevant
custom driver code is changed to program those values as
DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE), then.

Note that I've only tested the patch with RM67191 DSI panel on i.MX8mq EVK.
Help is needed to test with other i.MX8mq, Meson and Rockchip platforms,
as I don't have the hardwares.

Fixes: 2ed869990e14 ("phy: Add MIPI D-PHY configuration options")
Cc: Andrzej Hajda <andrzej.hajda at intel.com>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Cc: Robert Foss <robert.foss at linaro.org>
Cc: Laurent Pinchart <Laurent.pinchart at ideasonboard.com>
Cc: Jonas Karlman <jonas at kwiboo.se>
Cc: Jernej Skrabec <jernej.skrabec at gmail.com>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Kishon Vijay Abraham I <kishon at ti.com>
Cc: Vinod Koul <vkoul at kernel.org>
Cc: Kevin Hilman <khilman at baylibre.com>
Cc: Jerome Brunet <jbrunet at baylibre.com>
Cc: Martin Blumenstingl <martin.blumenstingl at googlemail.com>
Cc: Heiko Stuebner <heiko at sntech.de>
Cc: Maxime Ripard <mripard at kernel.org>
Cc: Guido G?nther <agx at sigxcpu.org>
Cc: Wyon Bi <bivvy.bi at rock-chips.com>
Tested-by: Liu Ying <victor.liu at nxp.com> # RM67191 DSI panel on i.MX8mq EVK
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Neil Armstrong <narmstrong at baylibre.com> # for phy-meson-axg-mipi-dphy.c
Tested-by: Guido G?nther <agx at sigxcpu.org> # Librem 5 (imx8mq) with it's rather picky panel
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
v3->v4:
* Fix commit message as the patch doesn't fix D-PHY documentation.

v2->v3:
* Drop D-PHY documentation change. (Laurent)
* Collect R-b tags and T-b tags.
* Cc Wyon.

v1->v2:
* Use BITS_PER_BYTE macro. (Andrzej)
* Drop dsi argument from ui2bc() in nwl-dsi.c.

 drivers/gpu/drm/bridge/nwl-dsi.c                 | 12 +++++-------
 drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c    |  3 ++-
 drivers/phy/phy-core-mipi-dphy.c                 |  4 ++--
 drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c |  3 ++-
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index a7389a0facfb..af07eeb47ca0 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/irq.h>
 #include <linux/math64.h>
@@ -196,12 +197,9 @@ static u32 ps2bc(struct nwl_dsi *dsi, unsigned long long ps)
 /*
  * ui2bc - UI time periods to byte clock cycles
  */
-static u32 ui2bc(struct nwl_dsi *dsi, unsigned long long ui)
+static u32 ui2bc(unsigned int ui)
 {
-	u32 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
-
-	return DIV64_U64_ROUND_UP(ui * dsi->lanes,
-				  dsi->mode.clock * 1000 * bpp);
+	return DIV_ROUND_UP(ui, BITS_PER_BYTE);
 }
 
 /*
@@ -232,12 +230,12 @@ static int nwl_dsi_config_host(struct nwl_dsi *dsi)
 	}
 
 	/* values in byte clock cycles */
-	cycles = ui2bc(dsi, cfg->clk_pre);
+	cycles = ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_pre: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_PRE, cycles);
 	cycles = ps2bc(dsi, cfg->lpx + cfg->clk_prepare + cfg->clk_zero);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_tx_gap (pre): 0x%x\n", cycles);
-	cycles += ui2bc(dsi, cfg->clk_pre);
+	cycles += ui2bc(cfg->clk_pre);
 	DRM_DEV_DEBUG_DRIVER(dsi->dev, "cfg_t_post: 0x%x\n", cycles);
 	nwl_dsi_write(dsi, NWL_DSI_CFG_T_POST, cycles);
 	cycles = ps2bc(dsi, cfg->hs_exit);
diff --git a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
index cd2332bf0e31..fdbd64c03e12 100644
--- a/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
+++ b/drivers/phy/amlogic/phy-meson-axg-mipi-dphy.c
@@ -9,6 +9,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
+#include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -250,7 +251,7 @@ static int phy_meson_axg_mipi_dphy_power_on(struct phy *phy)
 		     (DIV_ROUND_UP(priv->config.clk_zero, temp) << 16) |
 		     (DIV_ROUND_UP(priv->config.clk_prepare, temp) << 24));
 	regmap_write(priv->regmap, MIPI_DSI_CLK_TIM1,
-		     DIV_ROUND_UP(priv->config.clk_pre, temp));
+		     DIV_ROUND_UP(priv->config.clk_pre, BITS_PER_BYTE));
 
 	regmap_write(priv->regmap, MIPI_DSI_HS_TIM,
 		     DIV_ROUND_UP(priv->config.hs_exit, temp) |
diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c
index 288c9c67aa74..ccb4045685cd 100644
--- a/drivers/phy/phy-core-mipi-dphy.c
+++ b/drivers/phy/phy-core-mipi-dphy.c
@@ -36,7 +36,7 @@ int phy_mipi_dphy_get_default_config(unsigned long pixel_clock,
 
 	cfg->clk_miss = 0;
 	cfg->clk_post = 60000 + 52 * ui;
-	cfg->clk_pre = 8000;
+	cfg->clk_pre = 8;
 	cfg->clk_prepare = 38000;
 	cfg->clk_settle = 95000;
 	cfg->clk_term_en = 0;
@@ -97,7 +97,7 @@ int phy_mipi_dphy_config_validate(struct phy_configure_opts_mipi_dphy *cfg)
 	if (cfg->clk_post < (60000 + 52 * ui))
 		return -EINVAL;
 
-	if (cfg->clk_pre < 8000)
+	if (cfg->clk_pre < 8)
 		return -EINVAL;
 
 	if (cfg->clk_prepare < 38000 || cfg->clk_prepare > 95000)
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
index 347dc79a18c1..630e01b5c19b 100644
--- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
+++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c
@@ -5,6 +5,7 @@
  * Author: Wyon Bi <bivvy.bi at rock-chips.com>
  */
 
+#include <linux/bits.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/iopoll.h>
@@ -364,7 +365,7 @@ static void inno_dsidphy_mipi_mode_enable(struct inno_dsidphy *inno)
 	 * The value of counter for HS Tclk-pre
 	 * Tclk-pre = Tpin_txbyteclkhs * value
 	 */
-	clk_pre = DIV_ROUND_UP(cfg->clk_pre, t_txbyteclkhs);
+	clk_pre = DIV_ROUND_UP(cfg->clk_pre, BITS_PER_BYTE);
 
 	/*
 	 * The value of counter for HS Tlpx Time
-- 
2.25.1



From jammy_huang at aspeedtech.com  Sun Jan 23 18:29:46 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 10:29:46 +0800
Subject: [PATCH v2 4/4] media: aspeed: Fix timing polarity incorrect
In-Reply-To: <418fc1b2-ddbe-24e3-82cc-aa8ce74f4507@xs4all.nl>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-5-jammy_huang@aspeedtech.com>
 <418fc1b2-ddbe-24e3-82cc-aa8ce74f4507@xs4all.nl>
Message-ID: <b8707885-c10c-ca19-3f2c-f19f567e1f92@aspeedtech.com>


On 2022/1/21 ?? 03:30, Hans Verkuil wrote:
> On 12/22/21 09:21, Jammy Huang wrote:
>> This is a workaround for sync polarity unstable.
>> Sync value get by VR09C counts from sync's rising edge, which means
>> sync's polarity is negative if sync value is bigger than total/2.
> Do you have an example of such a format, or is this mostly theoretical?
>
> Either provide the example or make a note that it is theoretical.

OK, I will update an example in next patch. Let me explain first.

This is a must-be result. Please refer to the graph below as I sent in 
3/4 of this
series. For negative sync, sync width equals to back porch + data enable 
+ front porch.
Thus, sync would be bigger than 90% of total in most cases.

                   +-------------------+
                   |    v i d e o      |
       +--+  +-----+                   +-----+  +---+
          |  |                               |  |
          +--+                               +--+
        vsync+-------------------------------+
    frame_top+-----+
frame_bottom+-------------------------+


Following registers are what I got for 1920x1200 at 60.

1e700090: 07ee206f 04c9001a c4d3efff 04cc001f

1e7000a0: 0000081f 00000000 00000000 00000000

vertical total = 0x4D3 (VR098[27:16]) = 1235
vertical sync = 0x4CC (VR09C[27:16]) = 1228

>
> Regards,
>
> 	Hans
>
>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>> ---
>>   v2:
>>    - Use 'total/2' rather than 'total<<1'
>>    - Update comment
>> ---
>>   drivers/media/platform/aspeed-video.c | 20 ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>
>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>> index 7c50567f5ab0..c3e3343d91e1 100644
>> --- a/drivers/media/platform/aspeed-video.c
>> +++ b/drivers/media/platform/aspeed-video.c
>> @@ -989,6 +989,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>   
>>   		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>>   		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
>> +
>> +		/*
>> +		 * This is a workaround for polarity detection when the sync
>> +		 * value is larger than half.
>> +		 */
>> +		if (vsync > (vtotal / 2))
>> +			det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
>> +		else
>> +			det->polarities |= V4L2_DV_VSYNC_POS_POL;
>> +
>>   		if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>>   			det->vbackporch = video->frame_top - vsync;
>>   			det->vfrontporch = vtotal - video->frame_bottom;
>> @@ -1003,6 +1013,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>   
>>   		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>>   		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
>> +
>> +		/*
>> +		 * This is a workaround for polarity detection when the sync
>> +		 * value is larger than half.
>> +		 */
>> +		if (hsync > (htotal / 2))
>> +			det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
>> +		else
>> +			det->polarities |= V4L2_DV_HSYNC_POS_POL;
>> +
>>   		if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>>   			det->hbackporch = video->frame_left - hsync;
>>   			det->hfrontporch = htotal - video->frame_right;

-- 
Best Regards
Jammy



From wenst at chromium.org  Sun Jan 23 19:12:49 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 24 Jan 2022 11:12:49 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
References: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
Message-ID: <CAGXv+5EcAXFTnjkbeU4f3J2s4Ue5zxrN4QgS=t54BnLX8Gkw2w@mail.gmail.com>

Hi,

On Sun, Jan 23, 2022 at 11:34 AM qizhong cheng
<qizhong.cheng at mediatek.com> wrote:
>
> As an edge-triggered interrupts, its interrupt status should be cleared
> before dispatch to the handler of device.

I'm curious, is this just a code correction or are there real world
cases where something fails?

Also, please add a Fixes tag and maybe Cc stable so this gets backported
automatically.

ChenYu

> Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 2f3f974977a3..705ea33758b1 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
>                 if (status & MSI_STATUS){
>                         unsigned long imsi_status;
>
> +                       /* Clear MSI interrupt status */
> +                       writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
>                         while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
>                                 for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM)
>                                         generic_handle_domain_irq(port->inner_domain, bit);
>                         }
> -                       /* Clear MSI interrupt status */
> -                       writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
>                 }
>         }
>
> --
> 2.25.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From anshuman.khandual at arm.com  Sun Jan 23 19:15:36 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 08:45:36 +0530
Subject: [PATCH V2 0/2] coresight: trbe: Update existing errata for Cortex-X2
Message-ID: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>

Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
well. This series updates the errata definition and detection as required.
This series applies on v5.17-rc1.

Relevant identification document can be found here.

https://developer.arm.com/documentation/101803/0200/AArch64-system-registers/
AArch64-identification-register-summary/MIDR-EL1--Main-ID-Register

Relevant errata document can be found here.

https://developer.arm.com/documentation/SDEN1775100

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Changes in V2:

- Updated Documentation/arm64/silicon-errata.rst

Changes in V1:

https://lore.kernel.org/all/1641980099-20315-1-git-send-email-anshuman.khandual at arm.com/

Anshuman Khandual (2):
  arm64: Add Cortex-X2 CPU part definition
  arm64: errata: Update ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges

 Documentation/arm64/silicon-errata.rst |  4 ++++
 arch/arm64/Kconfig                     | 12 ++++++------
 arch/arm64/include/asm/cputype.h       |  2 ++
 arch/arm64/kernel/cpu_errata.c         |  2 ++
 4 files changed, 14 insertions(+), 6 deletions(-)

-- 
2.20.1



From anshuman.khandual at arm.com  Sun Jan 23 19:15:37 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 08:45:37 +0530
Subject: [PATCH V2 1/2] arm64: Add Cortex-X2 CPU part definition
In-Reply-To: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
References: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642994138-25887-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..657eeb06c784 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -74,6 +74,7 @@
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
 #define ARM_CPU_PART_CORTEX_A710	0xD47
+#define ARM_CPU_PART_CORTEX_X2		0xD48
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
 #define APM_CPU_PART_POTENZA		0x000
@@ -116,6 +117,7 @@
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
+#define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
-- 
2.20.1



From anshuman.khandual at arm.com  Sun Jan 23 19:15:38 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 08:45:38 +0530
Subject: [PATCH V2 2/2] arm64: errata: Update ARM64_ERRATUM_[2119858|2224489]
 with Cortex-X2 ranges
In-Reply-To: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
References: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642994138-25887-3-git-send-email-anshuman.khandual@arm.com>

Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
well. Lets update these errata definition and detection to accommodate all
new Cortex-X2 based cpu MIDR ranges.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  4 ++++
 arch/arm64/Kconfig                     | 12 ++++++------
 arch/arm64/kernel/cpu_errata.c         |  2 ++
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..8789c79310bb 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -98,6 +98,10 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2224489        | ARM64_ERRATUM_2224489       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X2       | #2119858        | ARM64_ERRATUM_2119858       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X2       | #2224489        | ARM64_ERRATUM_2224489       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1349291        | N/A                         |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..77b8f653f4bc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -671,14 +671,14 @@ config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	bool
 
 config ARM64_ERRATUM_2119858
-	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
+	bool "Cortex-A710/X2: 2119858: workaround TRBE overwriting trace data in FILL mode"
 	default y
 	depends on CORESIGHT_TRBE
 	select ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	help
-	  This option adds the workaround for ARM Cortex-A710 erratum 2119858.
+	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2119858.
 
-	  Affected Cortex-A710 cores could overwrite up to 3 cache lines of trace
+	  Affected Cortex-A710/X2 cores could overwrite up to 3 cache lines of trace
 	  data at the base of the buffer (pointed to by TRBASER_EL1) in FILL mode in
 	  the event of a WRAP event.
 
@@ -761,14 +761,14 @@ config ARM64_ERRATUM_2253138
 	  If unsure, say Y.
 
 config ARM64_ERRATUM_2224489
-	bool "Cortex-A710: 2224489: workaround TRBE writing to address out-of-range"
+	bool "Cortex-A710/X2: 2224489: workaround TRBE writing to address out-of-range"
 	depends on CORESIGHT_TRBE
 	default y
 	select ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
 	help
-	  This option adds the workaround for ARM Cortex-A710 erratum 2224489.
+	  This option adds the workaround for ARM Cortex-A710/X2 erratum 2224489.
 
-	  Affected Cortex-A710 cores might write to an out-of-range address, not reserved
+	  Affected Cortex-A710/X2 cores might write to an out-of-range address, not reserved
 	  for TRBE. Under some conditions, the TRBE might generate a write to the next
 	  virtually addressed page following the last page of the TRBE address space
 	  (i.e., the TRBLIMITR_EL1.LIMIT), instead of wrapping around to the base.
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..29cc062a4153 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -347,6 +347,7 @@ static const struct midr_range trbe_overwrite_fill_mode_cpus[] = {
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2119858
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
 #endif
 	{},
 };
@@ -371,6 +372,7 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
 #endif
 #ifdef CONFIG_ARM64_ERRATUM_2224489
 	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+	MIDR_RANGE(MIDR_CORTEX_X2, 0, 0, 2, 0),
 #endif
 	{},
 };
-- 
2.20.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:42 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:42 +0530
Subject: [RFC V1 00/11] arm64/perf: Enable branch stack sampling
Message-ID: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>

This series enables perf branch stack sampling support on arm64 platform
via a new arch feature called Branch Record Buffer Extension (BRBE). All
relevant register definitions could be accessed here.

https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers

The last two patches extend the perf ABI to accommodate additional branch
information that can be captured in BRBE. This series applies on v5.17-rc1.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (11):
  perf: Consolidate branch sample filter helpers
  arm64/perf: Add register definitions for BRBE
  arm64/perf: Update struct arm_pmu for BRBE
  arm64/perf: Update struct pmu_hw_events for BRBE
  arm64/perf: Detect support for BRBE
  arm64/perf: Drive BRBE from perf event states
  arm64/perf: Add BRBE driver
  arm64/perf: Enable branch stack sampling
  perf: Add more generic branch types
  perf: Expand perf_branch_entry.type
  perf: Capture branch privilege information

 arch/arm64/include/asm/sysreg.h          | 216 ++++++++++++
 arch/arm64/kernel/perf_event.c           |  48 +++
 arch/x86/events/intel/lbr.c              |   4 +-
 drivers/perf/Kconfig                     |  11 +
 drivers/perf/Makefile                    |   1 +
 drivers/perf/arm_pmu.c                   |  65 +++-
 drivers/perf/arm_pmu_brbe.c              | 432 +++++++++++++++++++++++
 drivers/perf/arm_pmu_brbe.h              | 259 ++++++++++++++
 drivers/perf/arm_pmu_platform.c          |  34 ++
 include/linux/perf/arm_pmu.h             |  49 +++
 include/linux/perf_event.h               |  24 ++
 include/uapi/linux/perf_event.h          |  26 +-
 kernel/events/core.c                     |   9 +-
 tools/include/uapi/linux/perf_event.h    |  26 +-
 tools/perf/Documentation/perf-record.txt |   1 +
 tools/perf/util/branch.c                 |  13 +-
 tools/perf/util/parse-branch-options.c   |   1 +
 17 files changed, 1202 insertions(+), 17 deletions(-)
 create mode 100644 drivers/perf/arm_pmu_brbe.c
 create mode 100644 drivers/perf/arm_pmu_brbe.h

-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:43 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:43 +0530
Subject: [RFC V1 01/11] perf: Consolidate branch sample filter helpers
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-2-git-send-email-anshuman.khandual@arm.com>

Besides the branch type filtering requests, 'event.attr.branch_sample_type'
also contains various flags indicating which additional information should
be captured, along with the base branch record. These flags help configure
the underlying hardware, and capture the branch records appropriately when
required e.g after PMU interrupt. But first, this moves an existing helper
perf_sample_save_hw_index() into the header before adding some more helpers
for other branch sample filter flags.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 include/linux/perf_event.h | 19 +++++++++++++++++++
 kernel/events/core.c       |  9 ++-------
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 117f230bcdfd..916ce5102b33 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1669,4 +1669,23 @@ typedef int (perf_snapshot_branch_stack_t)(struct perf_branch_entry *entries,
 					   unsigned int cnt);
 DECLARE_STATIC_CALL(perf_snapshot_branch_stack, perf_snapshot_branch_stack_t);
 
+static inline bool branch_sample_no_flags(const struct perf_event *event)
+{
+	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_FLAGS;
+}
+
+static inline bool branch_sample_no_cycles(const struct perf_event *event)
+{
+	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_CYCLES;
+}
+
+static inline bool branch_sample_type(const struct perf_event *event)
+{
+	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_TYPE_SAVE;
+}
+
+static inline bool branch_sample_hw_index(const struct perf_event *event)
+{
+	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
+}
 #endif /* _LINUX_PERF_EVENT_H */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index fc18664f49b0..740d0d829b24 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6984,11 +6984,6 @@ static void perf_output_read(struct perf_output_handle *handle,
 		perf_output_read_one(handle, event, enabled, running);
 }
 
-static inline bool perf_sample_save_hw_index(struct perf_event *event)
-{
-	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
-}
-
 void perf_output_sample(struct perf_output_handle *handle,
 			struct perf_event_header *header,
 			struct perf_sample_data *data,
@@ -7077,7 +7072,7 @@ void perf_output_sample(struct perf_output_handle *handle,
 			     * sizeof(struct perf_branch_entry);
 
 			perf_output_put(handle, data->br_stack->nr);
-			if (perf_sample_save_hw_index(event))
+			if (branch_sample_hw_index(event))
 				perf_output_put(handle, data->br_stack->hw_idx);
 			perf_output_copy(handle, data->br_stack->entries, size);
 		} else {
@@ -7371,7 +7366,7 @@ void perf_prepare_sample(struct perf_event_header *header,
 	if (sample_type & PERF_SAMPLE_BRANCH_STACK) {
 		int size = sizeof(u64); /* nr */
 		if (data->br_stack) {
-			if (perf_sample_save_hw_index(event))
+			if (branch_sample_hw_index(event))
 				size += sizeof(u64);
 
 			size += data->br_stack->nr
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:44 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:44 +0530
Subject: [RFC V1 02/11] arm64/perf: Add register definitions for BRBE
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-3-git-send-email-anshuman.khandual@arm.com>

This adds BRBE related register definitions and various other related field
macros there in. These will be used subsequently in a BRBE driver which is
being added later on.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/sysreg.h | 216 ++++++++++++++++++++++++++++++++
 1 file changed, 216 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..d8fd7e806a47 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -141,6 +141,218 @@
 #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
 #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
 
+/*
+ * BRBINF<N>_EL1 Encoding: [2, 1, 8, CRm, op2]
+ *
+ * derived as <CRm> = c{N<3:0>} <op2> = (N<4>x4 + 0)
+ */
+#define SYS_BRBINF0_EL1			sys_reg(2, 1, 8, 0, 0)
+#define SYS_BRBINF1_EL1			sys_reg(2, 1, 8, 1, 0)
+#define SYS_BRBINF2_EL1			sys_reg(2, 1, 8, 2, 0)
+#define SYS_BRBINF3_EL1			sys_reg(2, 1, 8, 3, 0)
+#define SYS_BRBINF4_EL1			sys_reg(2, 1, 8, 4, 0)
+#define SYS_BRBINF5_EL1			sys_reg(2, 1, 8, 5, 0)
+#define SYS_BRBINF6_EL1			sys_reg(2, 1, 8, 6, 0)
+#define SYS_BRBINF7_EL1			sys_reg(2, 1, 8, 7, 0)
+#define SYS_BRBINF8_EL1			sys_reg(2, 1, 8, 8, 0)
+#define SYS_BRBINF9_EL1			sys_reg(2, 1, 8, 9, 0)
+#define SYS_BRBINF10_EL1		sys_reg(2, 1, 8, 10, 0)
+#define SYS_BRBINF11_EL1		sys_reg(2, 1, 8, 11, 0)
+#define SYS_BRBINF12_EL1		sys_reg(2, 1, 8, 12, 0)
+#define SYS_BRBINF13_EL1		sys_reg(2, 1, 8, 13, 0)
+#define SYS_BRBINF14_EL1		sys_reg(2, 1, 8, 14, 0)
+#define SYS_BRBINF15_EL1		sys_reg(2, 1, 8, 15, 0)
+#define SYS_BRBINF16_EL1		sys_reg(2, 1, 8, 0, 4)
+#define SYS_BRBINF17_EL1		sys_reg(2, 1, 8, 1, 4)
+#define SYS_BRBINF18_EL1		sys_reg(2, 1, 8, 2, 4)
+#define SYS_BRBINF19_EL1		sys_reg(2, 1, 8, 3, 4)
+#define SYS_BRBINF20_EL1		sys_reg(2, 1, 8, 4, 4)
+#define SYS_BRBINF21_EL1		sys_reg(2, 1, 8, 5, 4)
+#define SYS_BRBINF22_EL1		sys_reg(2, 1, 8, 6, 4)
+#define SYS_BRBINF23_EL1		sys_reg(2, 1, 8, 7, 4)
+#define SYS_BRBINF24_EL1		sys_reg(2, 1, 8, 8, 4)
+#define SYS_BRBINF25_EL1		sys_reg(2, 1, 8, 9, 4)
+#define SYS_BRBINF26_EL1		sys_reg(2, 1, 8, 10, 4)
+#define SYS_BRBINF27_EL1		sys_reg(2, 1, 8, 11, 4)
+#define SYS_BRBINF28_EL1		sys_reg(2, 1, 8, 12, 4)
+#define SYS_BRBINF29_EL1		sys_reg(2, 1, 8, 13, 4)
+#define SYS_BRBINF30_EL1		sys_reg(2, 1, 8, 14, 4)
+#define SYS_BRBINF31_EL1		sys_reg(2, 1, 8, 15, 4)
+
+/*
+ * BRBSRC<N>_EL1 Encoding: [2, 1, 8, CRm, op2]
+ *
+ * derived as <CRm> = c{N<3:0>} <op2> = (N<4>x4 + 1)
+ */
+#define SYS_BRBSRC0_EL1			sys_reg(2, 1, 8, 0, 1)
+#define SYS_BRBSRC1_EL1			sys_reg(2, 1, 8, 1, 1)
+#define SYS_BRBSRC2_EL1			sys_reg(2, 1, 8, 2, 1)
+#define SYS_BRBSRC3_EL1			sys_reg(2, 1, 8, 3, 1)
+#define SYS_BRBSRC4_EL1			sys_reg(2, 1, 8, 4, 1)
+#define SYS_BRBSRC5_EL1			sys_reg(2, 1, 8, 5, 1)
+#define SYS_BRBSRC6_EL1			sys_reg(2, 1, 8, 6, 1)
+#define SYS_BRBSRC7_EL1			sys_reg(2, 1, 8, 7, 1)
+#define SYS_BRBSRC8_EL1			sys_reg(2, 1, 8, 8, 1)
+#define SYS_BRBSRC9_EL1			sys_reg(2, 1, 8, 9, 1)
+#define SYS_BRBSRC10_EL1		sys_reg(2, 1, 8, 10, 1)
+#define SYS_BRBSRC11_EL1		sys_reg(2, 1, 8, 11, 1)
+#define SYS_BRBSRC12_EL1		sys_reg(2, 1, 8, 12, 1)
+#define SYS_BRBSRC13_EL1		sys_reg(2, 1, 8, 13, 1)
+#define SYS_BRBSRC14_EL1		sys_reg(2, 1, 8, 14, 1)
+#define SYS_BRBSRC15_EL1		sys_reg(2, 1, 8, 15, 1)
+#define SYS_BRBSRC16_EL1		sys_reg(2, 1, 8, 0, 5)
+#define SYS_BRBSRC17_EL1		sys_reg(2, 1, 8, 1, 5)
+#define SYS_BRBSRC18_EL1		sys_reg(2, 1, 8, 2, 5)
+#define SYS_BRBSRC19_EL1		sys_reg(2, 1, 8, 3, 5)
+#define SYS_BRBSRC20_EL1		sys_reg(2, 1, 8, 4, 5)
+#define SYS_BRBSRC21_EL1		sys_reg(2, 1, 8, 5, 5)
+#define SYS_BRBSRC22_EL1		sys_reg(2, 1, 8, 6, 5)
+#define SYS_BRBSRC23_EL1		sys_reg(2, 1, 8, 7, 5)
+#define SYS_BRBSRC24_EL1		sys_reg(2, 1, 8, 8, 5)
+#define SYS_BRBSRC25_EL1		sys_reg(2, 1, 8, 9, 5)
+#define SYS_BRBSRC26_EL1		sys_reg(2, 1, 8, 10, 5)
+#define SYS_BRBSRC27_EL1		sys_reg(2, 1, 8, 11, 5)
+#define SYS_BRBSRC28_EL1		sys_reg(2, 1, 8, 12, 5)
+#define SYS_BRBSRC29_EL1		sys_reg(2, 1, 8, 13, 5)
+#define SYS_BRBSRC30_EL1		sys_reg(2, 1, 8, 14, 5)
+#define SYS_BRBSRC31_EL1		sys_reg(2, 1, 8, 15, 5)
+
+/*
+ * BRBTGT<N>_EL1 Encoding: [2, 1, 8, CRm, op2]
+ *
+ * derived as <CRm> = c{N<3:0>} <op2> = (N<4>x4 + 2)
+ */
+#define SYS_BRBTGT0_EL1			sys_reg(2, 1, 8, 0, 2)
+#define SYS_BRBTGT1_EL1			sys_reg(2, 1, 8, 1, 2)
+#define SYS_BRBTGT2_EL1			sys_reg(2, 1, 8, 2, 2)
+#define SYS_BRBTGT3_EL1			sys_reg(2, 1, 8, 3, 2)
+#define SYS_BRBTGT4_EL1			sys_reg(2, 1, 8, 4, 2)
+#define SYS_BRBTGT5_EL1			sys_reg(2, 1, 8, 5, 2)
+#define SYS_BRBTGT6_EL1			sys_reg(2, 1, 8, 6, 2)
+#define SYS_BRBTGT7_EL1			sys_reg(2, 1, 8, 7, 2)
+#define SYS_BRBTGT8_EL1			sys_reg(2, 1, 8, 8, 2)
+#define SYS_BRBTGT9_EL1			sys_reg(2, 1, 8, 9, 2)
+#define SYS_BRBTGT10_EL1		sys_reg(2, 1, 8, 10, 2)
+#define SYS_BRBTGT11_EL1		sys_reg(2, 1, 8, 11, 2)
+#define SYS_BRBTGT12_EL1		sys_reg(2, 1, 8, 12, 2)
+#define SYS_BRBTGT13_EL1		sys_reg(2, 1, 8, 13, 2)
+#define SYS_BRBTGT14_EL1		sys_reg(2, 1, 8, 14, 2)
+#define SYS_BRBTGT15_EL1		sys_reg(2, 1, 8, 15, 2)
+#define SYS_BRBTGT16_EL1		sys_reg(2, 1, 8, 0, 6)
+#define SYS_BRBTGT17_EL1		sys_reg(2, 1, 8, 1, 6)
+#define SYS_BRBTGT18_EL1		sys_reg(2, 1, 8, 2, 6)
+#define SYS_BRBTGT19_EL1		sys_reg(2, 1, 8, 3, 6)
+#define SYS_BRBTGT20_EL1		sys_reg(2, 1, 8, 4, 6)
+#define SYS_BRBTGT21_EL1		sys_reg(2, 1, 8, 5, 6)
+#define SYS_BRBTGT22_EL1		sys_reg(2, 1, 8, 6, 6)
+#define SYS_BRBTGT23_EL1		sys_reg(2, 1, 8, 7, 6)
+#define SYS_BRBTGT24_EL1		sys_reg(2, 1, 8, 8, 6)
+#define SYS_BRBTGT25_EL1		sys_reg(2, 1, 8, 9, 6)
+#define SYS_BRBTGT26_EL1		sys_reg(2, 1, 8, 10, 6)
+#define SYS_BRBTGT27_EL1		sys_reg(2, 1, 8, 11, 6)
+#define SYS_BRBTGT28_EL1		sys_reg(2, 1, 8, 12, 6)
+#define SYS_BRBTGT29_EL1		sys_reg(2, 1, 8, 13, 6)
+#define SYS_BRBTGT30_EL1		sys_reg(2, 1, 8, 14, 6)
+#define SYS_BRBTGT31_EL1		sys_reg(2, 1, 8, 15, 6)
+
+#define SYS_BRBIDR0_EL1			sys_reg(2, 1, 9, 2, 0)
+#define SYS_BRBCR_EL1			sys_reg(2, 1, 9, 0, 0)
+#define SYS_BRBFCR_EL1			sys_reg(2, 1, 9, 0, 1)
+#define SYS_BRBTS_EL1			sys_reg(2, 1, 9, 0, 2)
+#define SYS_BRBINFINJ_EL1		sys_reg(2, 1, 9, 1, 0)
+#define SYS_BRBSRCINJ_EL1		sys_reg(2, 1, 9, 1, 1)
+#define SYS_BRBTGTINJ_EL1		sys_reg(2, 1, 9, 1, 2)
+
+#define BRBIDR0_CC_SHIFT	12
+#define BRBIDR0_CC_MASK		GENMASK(3, 0)
+#define BRBIDR0_FORMAT_SHIFT	8
+#define BRBIDR0_FORMAT_MASK	GENMASK(3, 0)
+#define BRBIDR0_NUMREC_SHIFT	0
+#define BRBIDR0_NUMREC_MASK	GENMASK(7, 0)
+
+#define BRBIDR0_CC_20_BIT	0x5
+#define BRBIDR0_FORMAT_0	0x0
+
+#define BRBIDR0_NUMREC_8	0x08
+#define BRBIDR0_NUMREC_16	0x10
+#define BRBIDR0_NUMREC_32	0x20
+#define BRBIDR0_NUMREC_64	0x40
+
+#define BRBINF_VALID_SHIFT	0
+#define BRBINF_VALID_MASK	GENMASK(1, 0)
+#define BRBINF_MPRED		(1UL << 5)
+#define BRBINF_EL_SHIFT		6
+#define BRBINF_EL_MASK		GENMASK(1, 0)
+#define BRBINF_TYPE_SHIFT	8
+#define BRBINF_TYPE_MASK	GENMASK(5, 0)
+#define BRBINF_TX		(1UL << 16)
+#define BRBINF_LASTFAILED	(1UL << 17)
+#define BRBINF_CC_SHIFT		32
+#define BRBINF_CC_MASK		GENMASK(13, 0)
+#define BRBINF_CCU		(1UL << 46)
+
+#define BRBINF_EL_EL0		0x0
+#define BRBINF_EL_EL1		0x1
+#define BRBINF_EL_EL2		0x2
+
+#define BRBINF_VALID_INVALID	0x0
+#define BRBINF_VALID_TARGET	0x1
+#define BRBINF_VALID_SOURCE	0x2
+#define BRBINF_VALID_ALL	0x3
+
+#define BRBINF_TYPE_UNCOND_DIR	0x0
+#define BRBINF_TYPE_INDIR	0x1
+#define BRBINF_TYPE_DIR_LINK	0x2
+#define BRBINF_TYPE_INDIR_LINK	0x3
+#define BRBINF_TYPE_RET_SUB	0x5
+#define BRBINF_TYPE_RET_EXCPT	0x7
+#define BRBINF_TYPE_COND_DIR	0x8
+#define BRBINF_TYPE_DEBUG_HALT	0x21
+#define BRBINF_TYPE_CALL	0x22
+#define BRBINF_TYPE_TRAP	0x23
+#define BRBINF_TYPE_SERROR	0x24
+#define BRBINF_TYPE_INST_DEBUG	0x26
+#define BRBINF_TYPE_DATA_DEBUG	0x27
+#define BRBINF_TYPE_ALGN_FAULT	0x2A
+#define BRBINF_TYPE_INST_FAULT	0x2B
+#define BRBINF_TYPE_DATA_FAULT	0x2C
+#define BRBINF_TYPE_IRQ		0x2E
+#define BRBINF_TYPE_FIQ		0x2F
+#define BRBINF_TYPE_DEBUG_EXIT	0x39
+
+#define BRBCR_E0BRE		(1UL << 0)
+#define BRBCR_E1BRE		(1UL << 1)
+#define BRBCR_CC		(1UL << 3)
+#define BRBCR_MPRED		(1UL << 4)
+#define BRBCR_FZP		(1UL << 8)
+#define BRBCR_ERTN		(1UL <<	22)
+#define BRBCR_EXCEPTION		(1UL << 23)
+#define BRBCR_TS_MASK		GENMASK(1, 0)
+#define BRBCR_TS_SHIFT		5
+
+#define BRBCR_TS_VIRTUAL	0x1
+#define BRBCR_TS_GST_PHYSICAL	0x2
+#define BRBCR_TS_PHYSICAL	0x3
+
+#define BRBFCR_LASTFAILED	(1UL << 6)
+#define BRBFCR_PAUSED		(1UL << 7)
+#define BRBFCR_ENL		(1UL << 16)
+#define BRBFCR_DIRECT		(1UL << 17)
+#define BRBFCR_INDIRECT		(1UL << 18)
+#define BRBFCR_RTN		(1UL << 19)
+#define BRBFCR_INDCALL		(1UL << 20)
+#define BRBFCR_DIRCALL		(1UL << 21)
+#define BRBFCR_CONDDIR		(1UL << 22)
+#define BRBFCR_BANK_MASK	GENMASK(1, 0)
+#define BRBFCR_BANK_SHIFT	28
+
+#define BRBFCR_BANK_FIRST	0x0
+#define BRBFCR_BANK_SECOND	0x1
+
+#define BRBFCR_BRANCH_ALL	(BRBFCR_DIRECT | BRBFCR_INDIRECT | \
+				 BRBFCR_RTN | BRBFCR_INDCALL | \
+				 BRBFCR_DIRCALL | BRBFCR_CONDDIR)
+
 #define SYS_MIDR_EL1			sys_reg(3, 0, 0, 0, 0)
 #define SYS_MPIDR_EL1			sys_reg(3, 0, 0, 0, 5)
 #define SYS_REVIDR_EL1			sys_reg(3, 0, 0, 0, 6)
@@ -937,6 +1149,7 @@
 #define ID_AA64MMFR2_CNP_SHIFT		0
 
 /* id_aa64dfr0 */
+#define ID_AA64DFR0_BRBE_SHIFT		52
 #define ID_AA64DFR0_MTPMU_SHIFT		48
 #define ID_AA64DFR0_TRBE_SHIFT		44
 #define ID_AA64DFR0_TRACE_FILT_SHIFT	40
@@ -959,6 +1172,9 @@
 #define ID_AA64DFR0_PMSVER_8_2		0x1
 #define ID_AA64DFR0_PMSVER_8_3		0x2
 
+#define ID_AA64DFR0_BRBE		0x1
+#define ID_AA64DFR0_BRBE_V1P1		0x2
+
 #define ID_DFR0_PERFMON_SHIFT		24
 
 #define ID_DFR0_PERFMON_8_0		0x3
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:45 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:45 +0530
Subject: [RFC V1 03/11] arm64/perf: Update struct arm_pmu for BRBE
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-4-git-send-email-anshuman.khandual@arm.com>

This updates struct arm_pmu to include all required helpers that will drive
BRBE functionality for a given PMU implementation. These are the following.

- brbe_filter	: Convert perf event filters into BRBE HW filters
- brbe_probe	: Probe BRBE HW and capture its attributes
- brbe_enable	: Enable BRBE HW with a given config
- brbe_disable	: Disable BRBE HW
- brbe_read	: Read BRBE buffer for captured branch records
- brbe_reset	: Reset BRBE buffer
- brbe_supported: Whether BRBE is supported or not

A BRBE driver implementation needs to provide these functionalities.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kernel/perf_event.c | 36 ++++++++++++++++++++++++++++++++++
 include/linux/perf/arm_pmu.h   |  7 +++++++
 2 files changed, 43 insertions(+)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index cab678ed6618..f6a47036b0b4 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1015,6 +1015,35 @@ static int armv8pmu_filter_match(struct perf_event *event)
 	return evtype != ARMV8_PMUV3_PERFCTR_CHAIN;
 }
 
+static void armv8pmu_brbe_filter(struct pmu_hw_events *hw_event, struct perf_event *event)
+{
+}
+
+static void armv8pmu_brbe_enable(struct pmu_hw_events *hw_event)
+{
+}
+
+static void armv8pmu_brbe_disable(struct pmu_hw_events *hw_event)
+{
+}
+
+static void armv8pmu_brbe_read(struct pmu_hw_events *hw_event, struct perf_event *event)
+{
+}
+
+static void armv8pmu_brbe_probe(struct pmu_hw_events *hw_event)
+{
+}
+
+static void armv8pmu_brbe_reset(struct pmu_hw_events *hw_event)
+{
+}
+
+static bool armv8pmu_brbe_supported(struct perf_event *event)
+{
+	return false;
+}
+
 static void armv8pmu_reset(void *info)
 {
 	struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
@@ -1247,6 +1276,13 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
 
 	cpu_pmu->pmu.event_idx		= armv8pmu_user_event_idx;
 
+	cpu_pmu->brbe_filter		= armv8pmu_brbe_filter;
+	cpu_pmu->brbe_enable		= armv8pmu_brbe_enable;
+	cpu_pmu->brbe_disable		= armv8pmu_brbe_disable;
+	cpu_pmu->brbe_read		= armv8pmu_brbe_read;
+	cpu_pmu->brbe_probe		= armv8pmu_brbe_probe;
+	cpu_pmu->brbe_reset		= armv8pmu_brbe_reset;
+	cpu_pmu->brbe_supported		= armv8pmu_brbe_supported;
 	cpu_pmu->name			= name;
 	cpu_pmu->map_event		= map_event;
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 2512e2f9cd4e..c0dd0d6c5883 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -98,6 +98,13 @@ struct arm_pmu {
 	void		(*reset)(void *);
 	int		(*map_event)(struct perf_event *event);
 	int		(*filter_match)(struct perf_event *event);
+	void		(*brbe_filter)(struct pmu_hw_events *hw_events, struct perf_event *event);
+	void		(*brbe_probe)(struct pmu_hw_events *hw_events);
+	void		(*brbe_enable)(struct pmu_hw_events *hw_events);
+	void		(*brbe_disable)(struct pmu_hw_events *hw_events);
+	void		(*brbe_read)(struct pmu_hw_events *hw_events, struct perf_event *event);
+	void		(*brbe_reset)(struct pmu_hw_events *hw_events);
+	bool		(*brbe_supported)(struct perf_event *event);
 	int		num_events;
 	bool		secure_access; /* 32-bit ARM only */
 #define ARMV8_PMUV3_MAX_COMMON_EVENTS		0x40
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:46 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:46 +0530
Subject: [RFC V1 04/11] arm64/perf: Update struct pmu_hw_events for BRBE
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-5-git-send-email-anshuman.khandual@arm.com>

A single perf event instance BRBE related contexts and data will be tracked
in struct pmu_hw_events. Hence update the structure to accommodate required
details related to BRBE.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 include/linux/perf/arm_pmu.h | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index c0dd0d6c5883..c4a705d3d054 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -41,6 +41,11 @@
 	},								\
 }
 
+/*
+ * Maximum branch records in BRBE
+ */
+#define BRBE_MAX_ENTRIES 64
+
 /* The events for a given PMU register set. */
 struct pmu_hw_events {
 	/*
@@ -67,6 +72,23 @@ struct pmu_hw_events {
 	struct arm_pmu		*percpu_pmu;
 
 	int irq;
+
+	/* Detected BRBE attributes */
+	bool				v1p1;
+	int				brbe_cc;
+	int				brbe_nr;
+
+	/* Evaluated BRBE configuration */
+	u64				brbfcr;
+	u64				brbcr;
+
+	/* Tracked BRBE context */
+	unsigned int			brbe_users;
+	void				*brbe_context;
+
+	/* Captured BRBE buffer - copied as is into perf_sample_data */
+	struct perf_branch_stack	brbe_stack;
+	struct perf_branch_entry	brbe_entries[BRBE_MAX_ENTRIES];
 };
 
 enum armpmu_attr_groups {
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:47 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:47 +0530
Subject: [RFC V1 05/11] arm64/perf: Detect support for BRBE
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-6-git-send-email-anshuman.khandual@arm.com>

CPU specific BRBE entries, cycle count, format support gets detected during
PMU init. This information gets saved in per-cpu struct pmu_hw_events which
later helps in operating BRBE during a perf event context.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 drivers/perf/arm_pmu_platform.c | 34 +++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
index 513de1f54e2d..800e4a6e8bc3 100644
--- a/drivers/perf/arm_pmu_platform.c
+++ b/drivers/perf/arm_pmu_platform.c
@@ -172,6 +172,36 @@ static int armpmu_request_irqs(struct arm_pmu *armpmu)
 	return err;
 }
 
+static void arm_brbe_probe_cpu(void *info)
+{
+	struct pmu_hw_events *hw_events;
+	struct arm_pmu *armpmu = info;
+
+	/*
+	 * Return from here, if BRBE driver has not been
+	 * implemented for this PMU. This helps prevent
+	 * kernel crash later when brbe_probe() will be
+	 * called on the PMU.
+	 */
+	if (!armpmu->brbe_probe)
+		return;
+
+	hw_events = per_cpu_ptr(armpmu->hw_events, smp_processor_id());
+	armpmu->brbe_probe(hw_events);
+}
+
+static int armpmu_request_brbe(struct arm_pmu *armpmu)
+{
+	int cpu, err = 0;
+
+	for_each_cpu(cpu, &armpmu->supported_cpus) {
+		err = smp_call_function_single(cpu, arm_brbe_probe_cpu, armpmu, 1);
+		if (err)
+			return err;
+	}
+	return err;
+}
+
 static void armpmu_free_irqs(struct arm_pmu *armpmu)
 {
 	int cpu;
@@ -229,6 +259,10 @@ int arm_pmu_device_probe(struct platform_device *pdev,
 	if (ret)
 		goto out_free_irqs;
 
+	ret = armpmu_request_brbe(pmu);
+	if (ret)
+		goto out_free_irqs;
+
 	ret = armpmu_register(pmu);
 	if (ret) {
 		dev_err(dev, "failed to register PMU devices!\n");
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:48 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:48 +0530
Subject: [RFC V1 06/11] arm64/perf: Drive BRBE from perf event states
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-7-git-send-email-anshuman.khandual@arm.com>

Branch stack sampling rides along the normal perf event and all the branch
records get captured during the PMU interrupt. This just changes perf event
handling on the arm64 platform to accommodate required BRBE operations that
will enable branch stack sampling support.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kernel/perf_event.c |  6 +++++
 drivers/perf/arm_pmu.c         | 40 ++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index f6a47036b0b4..11c82c8f2eec 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -864,6 +864,12 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
 		if (!armpmu_event_set_period(event))
 			continue;
 
+		if (has_branch_stack(event)) {
+			cpu_pmu->brbe_read(cpuc, event);
+			data.br_stack = &cpuc->brbe_stack;
+			cpu_pmu->brbe_reset(cpuc);
+		}
+
 		/*
 		 * Perf event overflow will queue the processing of the event as
 		 * an irq_work which will be taken care of in the handling of
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 295cc7952d0e..0800c8858ed8 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -269,12 +269,22 @@ armpmu_stop(struct perf_event *event, int flags)
 {
 	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
+	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
 
 	/*
 	 * ARM pmu always has to update the counter, so ignore
 	 * PERF_EF_UPDATE, see comments in armpmu_start().
 	 */
 	if (!(hwc->state & PERF_HES_STOPPED)) {
+		if (has_branch_stack(event)) {
+			WARN_ON_ONCE(!hw_events->brbe_users);
+			hw_events->brbe_users--;
+			if (!hw_events->brbe_users) {
+				hw_events->brbe_context = NULL;
+				armpmu->brbe_disable(hw_events);
+			}
+		}
+
 		armpmu->disable(event);
 		armpmu_event_update(event);
 		hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
@@ -285,6 +295,7 @@ static void armpmu_start(struct perf_event *event, int flags)
 {
 	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
+	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
 
 	/*
 	 * ARM pmu always has to reprogram the period, so ignore
@@ -302,6 +313,14 @@ static void armpmu_start(struct perf_event *event, int flags)
 	 * happened since disabling.
 	 */
 	armpmu_event_set_period(event);
+	if (has_branch_stack(event)) {
+		if (event->ctx->task && hw_events->brbe_context != event->ctx) {
+			armpmu->brbe_reset(hw_events);
+			hw_events->brbe_context = event->ctx;
+		}
+		armpmu->brbe_enable(hw_events);
+		hw_events->brbe_users++;
+	}
 	armpmu->enable(event);
 }
 
@@ -347,6 +366,10 @@ armpmu_add(struct perf_event *event, int flags)
 	hw_events->events[idx] = event;
 
 	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	if (has_branch_stack(event))
+		armpmu->brbe_filter(hw_events, event);
+
 	if (flags & PERF_EF_START)
 		armpmu_start(event, PERF_EF_RELOAD);
 
@@ -438,6 +461,7 @@ __hw_perf_event_init(struct perf_event *event)
 {
 	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
 	struct hw_perf_event *hwc = &event->hw;
+	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
 	int mapping;
 
 	hwc->flags = 0;
@@ -492,6 +516,9 @@ __hw_perf_event_init(struct perf_event *event)
 			return -EINVAL;
 	}
 
+	if (has_branch_stack(event))
+		armpmu->brbe_filter(hw_events, event);
+
 	return 0;
 }
 
@@ -520,6 +547,18 @@ static int armpmu_event_init(struct perf_event *event)
 	return __hw_perf_event_init(event);
 }
 
+static void armpmu_sched_task(struct perf_event_context *ctx, bool sched_in)
+{
+	struct arm_pmu *armpmu = to_arm_pmu(ctx->pmu);
+	struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events);
+
+	if (!hw_events->brbe_users)
+		return;
+
+	if (sched_in)
+		armpmu->brbe_reset(hw_events);
+}
+
 static void armpmu_enable(struct pmu *pmu)
 {
 	struct arm_pmu *armpmu = to_arm_pmu(pmu);
@@ -877,6 +916,7 @@ static struct arm_pmu *__armpmu_alloc(gfp_t flags)
 	}
 
 	pmu->pmu = (struct pmu) {
+		.sched_task	= armpmu_sched_task,
 		.pmu_enable	= armpmu_enable,
 		.pmu_disable	= armpmu_disable,
 		.event_init	= armpmu_event_init,
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:49 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:49 +0530
Subject: [RFC V1 07/11] arm64/perf: Add BRBE driver
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-8-git-send-email-anshuman.khandual@arm.com>

This adds a BRBE driver which implements all the required helper functions
for struct arm_pmu. Following functions are defined by this driver which
will configure, enable, capture, reset and disable BRBE buffer HW as and
when requested via perf branch stack sampling framework.

- arm64_pmu_brbe_filter()
- arm64_pmu_brbe_enable()
- arm64_pmu_brbe_disable()
- arm64_pmu_brbe_read()
- arm64_pmu_brbe_probe()
- arm64_pmu_brbe_reset()
- arm64_pmu_brbe_supported()

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/kernel/perf_event.c |   8 +-
 drivers/perf/Kconfig           |  11 +
 drivers/perf/Makefile          |   1 +
 drivers/perf/arm_pmu_brbe.c    | 396 +++++++++++++++++++++++++++++++++
 drivers/perf/arm_pmu_brbe.h    | 259 +++++++++++++++++++++
 include/linux/perf/arm_pmu.h   |  20 ++
 6 files changed, 694 insertions(+), 1 deletion(-)
 create mode 100644 drivers/perf/arm_pmu_brbe.c
 create mode 100644 drivers/perf/arm_pmu_brbe.h

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index 11c82c8f2eec..4c805b3f01fc 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -1023,31 +1023,37 @@ static int armv8pmu_filter_match(struct perf_event *event)
 
 static void armv8pmu_brbe_filter(struct pmu_hw_events *hw_event, struct perf_event *event)
 {
+	arm64_pmu_brbe_filter(hw_event, event);
 }
 
 static void armv8pmu_brbe_enable(struct pmu_hw_events *hw_event)
 {
+	arm64_pmu_brbe_enable(hw_event);
 }
 
 static void armv8pmu_brbe_disable(struct pmu_hw_events *hw_event)
 {
+	arm64_pmu_brbe_disable(hw_event);
 }
 
 static void armv8pmu_brbe_read(struct pmu_hw_events *hw_event, struct perf_event *event)
 {
+	arm64_pmu_brbe_read(hw_event, event);
 }
 
 static void armv8pmu_brbe_probe(struct pmu_hw_events *hw_event)
 {
+	arm64_pmu_brbe_probe(hw_event);
 }
 
 static void armv8pmu_brbe_reset(struct pmu_hw_events *hw_event)
 {
+	arm64_pmu_brbe_reset(hw_event);
 }
 
 static bool armv8pmu_brbe_supported(struct perf_event *event)
 {
-	return false;
+	return arm64_pmu_brbe_supported(event);
 }
 
 static void armv8pmu_reset(void *info)
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index e1a0c44bc686..284fba623c54 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -146,6 +146,17 @@ config MARVELL_CN10K_TAD_PMU
 	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
 	  performance monitors on CN10K family silicons.
 
+config ARM_BRBE_PMU
+	tristate "Enable support for Branch Record Buffer Extension (BRBE)"
+	depends on ARM64 && ARM_PMU
+	default y
+	help
+	  Enable perf support for Branch Record Buffer Extension (BRBE) which
+	  records all branches taken in an execution path. This supports some
+	  branch types and privilege based filtering. It captured additional
+	  relevant information such as cycle count, misprediction and branch
+	  type, branch privilege level etc.
+
 source "drivers/perf/hisilicon/Kconfig"
 
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 2db5418d5b0a..fd985570a63b 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
 obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
+obj-$(CONFIG_ARM_BRBE_PMU) += arm_pmu_brbe.o
diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
new file mode 100644
index 000000000000..8144514b9997
--- /dev/null
+++ b/drivers/perf/arm_pmu_brbe.c
@@ -0,0 +1,396 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Branch Record Buffer Extension Driver.
+ *
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Author: Anshuman Khandual <anshuman.khandual at arm.com>
+ */
+#include "arm_pmu_brbe.h"
+
+#define BRBE_FCR_MASK (BRBFCR_BRANCH_ALL)
+#define BRBE_CR_MASK  (BRBCR_EXCEPTION | BRBCR_ERTN | BRBCR_CC | \
+		       BRBCR_MPRED | BRBCR_E1BRE | BRBCR_E0BRE)
+
+static void set_brbe_disabled(struct pmu_hw_events *cpuc)
+{
+	cpuc->brbe_nr = 0;
+}
+
+static bool brbe_disabled(struct pmu_hw_events *cpuc)
+{
+	return !cpuc->brbe_nr;
+}
+
+bool arm64_pmu_brbe_supported(struct perf_event *event)
+{
+	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
+	struct pmu_hw_events *hw_events = per_cpu_ptr(armpmu->hw_events, event->cpu);
+
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_KERNEL) {
+		if (!perfmon_capable()) {
+			pr_warn_once("does not have permission for kernel branch filter\n");
+			return false;
+		}
+	}
+
+	/*
+	 * If the event does not have at least one of the privilege
+	 * branch filters as in PERF_SAMPLE_BRANCH_PLM_ALL, the core
+	 * perf will adjust its value based on perf event's existing
+	 * privilege level via attr.exclude_[user|kernel|hv].
+	 *
+	 * As event->attr.branch_sample_type might have been changed
+	 * when the event reaches here, it is not possible to figure
+	 * out whether the event originally had HV privilege request
+	 * or got added via the core perf. Just report this situation
+	 * once and continue ignoring if there are other instances.
+	 */
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HV)
+		pr_warn_once("does not support hypervisor privilege branch filter\n");
+
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_ABORT_TX) {
+		pr_warn_once("does not support aborted transaction branch filter\n");
+		return false;
+	}
+
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_NO_TX) {
+		pr_warn_once("does not support non transaction branch filter\n");
+		return false;
+	}
+
+	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_IN_TX) {
+		pr_warn_once("does not support in transaction branch filter\n");
+		return false;
+	}
+	return !brbe_disabled(hw_events);
+}
+
+void arm64_pmu_brbe_probe(struct pmu_hw_events *cpuc)
+{
+	u64 aa64dfr0, brbidr;
+	unsigned int brbe, format, cpu = smp_processor_id();
+
+	aa64dfr0 = read_sysreg_s(SYS_ID_AA64DFR0_EL1);
+	brbe = cpuid_feature_extract_unsigned_field(aa64dfr0, ID_AA64DFR0_BRBE_SHIFT);
+	if (!brbe) {
+		pr_info("no implementation found on cpu %d\n", cpu);
+		set_brbe_disabled(cpuc);
+		return;
+	} else if (brbe == ID_AA64DFR0_BRBE) {
+		pr_info("implementation found on cpu %d\n", cpu);
+		cpuc->v1p1 = false;
+	} else if (brbe == ID_AA64DFR0_BRBE_V1P1) {
+		pr_info("implementation (v1p1) found on cpu %d\n", cpu);
+		cpuc->v1p1 = true;
+	}
+
+	brbidr = read_sysreg_s(SYS_BRBIDR0_EL1);
+	format = brbe_fetch_format(brbidr);
+	if (format != BRBIDR0_FORMAT_0) {
+		pr_warn("format 0 not implemented\n");
+		set_brbe_disabled(cpuc);
+		return;
+	}
+
+	cpuc->brbe_cc = brbe_fetch_cc_bits(brbidr);
+	if (cpuc->brbe_cc != BRBIDR0_CC_20_BIT) {
+		pr_warn("20-bit counter not implemented\n");
+		set_brbe_disabled(cpuc);
+		return;
+	}
+
+	cpuc->brbe_nr = brbe_fetch_numrec(brbidr);
+	if (!valid_brbe_nr(cpuc->brbe_nr)) {
+		pr_warn("invalid number of records\n");
+		set_brbe_disabled(cpuc);
+		return;
+	}
+}
+
+void arm64_pmu_brbe_enable(struct pmu_hw_events *cpuc)
+{
+	u64 brbfcr, brbcr;
+
+	if (brbe_disabled(cpuc))
+		return;
+
+	brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
+	brbfcr &= ~(BRBFCR_BANK_MASK << BRBFCR_BANK_SHIFT);
+	brbfcr &= ~(BRBFCR_ENL | BRBFCR_PAUSED | BRBE_FCR_MASK);
+	brbfcr |= (cpuc->brbfcr & BRBE_FCR_MASK);
+	write_sysreg_s(brbfcr, SYS_BRBFCR_EL1);
+	isb();
+
+	brbcr = read_sysreg_s(SYS_BRBCR_EL1);
+	brbcr &= ~BRBE_CR_MASK;
+	brbcr |= BRBCR_FZP;
+	brbcr |= (BRBCR_TS_PHYSICAL << BRBCR_TS_SHIFT);
+	brbcr |= (cpuc->brbcr & BRBE_CR_MASK);
+	write_sysreg_s(brbcr, SYS_BRBCR_EL1);
+	isb();
+}
+
+void arm64_pmu_brbe_disable(struct pmu_hw_events *cpuc)
+{
+	u64 brbcr;
+
+	if (brbe_disabled(cpuc))
+		return;
+
+	brbcr = read_sysreg_s(SYS_BRBCR_EL1);
+	brbcr &= ~(BRBCR_E0BRE | BRBCR_E1BRE);
+	write_sysreg_s(brbcr, SYS_BRBCR_EL1);
+	isb();
+}
+
+static void perf_branch_to_brbfcr(struct pmu_hw_events *cpuc, int branch_type)
+{
+	cpuc->brbfcr = 0;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY) {
+		cpuc->brbfcr |= BRBFCR_BRANCH_ALL;
+		return;
+	}
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY_CALL)
+		cpuc->brbfcr |= (BRBFCR_INDCALL | BRBFCR_DIRCALL);
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+		cpuc->brbfcr |= BRBFCR_RTN;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_IND_CALL)
+		cpuc->brbfcr |= BRBFCR_INDCALL;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_COND)
+		cpuc->brbfcr |= BRBFCR_CONDDIR;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_IND_JUMP)
+		cpuc->brbfcr |= BRBFCR_INDIRECT;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_CALL)
+		cpuc->brbfcr |= BRBFCR_DIRCALL;
+}
+
+static void perf_branch_to_brbcr(struct pmu_hw_events *cpuc, int branch_type)
+{
+	cpuc->brbcr = (BRBCR_CC | BRBCR_MPRED);
+
+	if (branch_type & PERF_SAMPLE_BRANCH_USER)
+		cpuc->brbcr |= BRBCR_E0BRE;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_KERNEL) {
+		/*
+		 * This should have been verified earlier.
+		 */
+		WARN_ON(!perfmon_capable());
+		cpuc->brbcr |= BRBCR_E1BRE;
+	}
+
+	if (branch_type & PERF_SAMPLE_BRANCH_NO_CYCLES)
+		cpuc->brbcr &= ~BRBCR_CC;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_NO_FLAGS)
+		cpuc->brbcr &= ~BRBCR_MPRED;
+
+	if (!perfmon_capable())
+		return;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY) {
+		cpuc->brbcr |= BRBCR_EXCEPTION;
+		cpuc->brbcr |= BRBCR_ERTN;
+		return;
+	}
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY_CALL)
+		cpuc->brbcr |= BRBCR_EXCEPTION;
+
+	if (branch_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
+		cpuc->brbcr |= BRBCR_ERTN;
+}
+
+
+void arm64_pmu_brbe_filter(struct pmu_hw_events *cpuc, struct perf_event *event)
+{
+	u64 branch_type = event->attr.branch_sample_type;
+
+	if (brbe_disabled(cpuc))
+		return;
+
+	perf_branch_to_brbfcr(cpuc, branch_type);
+	perf_branch_to_brbcr(cpuc, branch_type);
+}
+
+static int brbe_fetch_perf_type(u64 brbinf)
+{
+	int brbe_type = brbe_fetch_type(brbinf);
+
+	switch (brbe_type) {
+	case BRBINF_TYPE_UNCOND_DIR:
+		return PERF_BR_UNCOND;
+	case BRBINF_TYPE_INDIR:
+		return PERF_BR_IND;
+	case BRBINF_TYPE_DIR_LINK:
+		return PERF_BR_CALL;
+	case BRBINF_TYPE_INDIR_LINK:
+		return PERF_BR_IND_CALL;
+	case BRBINF_TYPE_RET_SUB:
+		return PERF_BR_RET;
+	case BRBINF_TYPE_COND_DIR:
+		return PERF_BR_COND;
+	case BRBINF_TYPE_CALL:
+		return PERF_BR_CALL;
+	case BRBINF_TYPE_TRAP:
+		return PERF_BR_SYSCALL;
+	case BRBINF_TYPE_RET_EXCPT:
+		return PERF_BR_UNKNOWN;
+	case BRBINF_TYPE_IRQ:
+		return PERF_BR_UNKNOWN;
+	case BRBINF_TYPE_DEBUG_HALT:
+	case BRBINF_TYPE_SERROR:
+	case BRBINF_TYPE_INST_DEBUG:
+	case BRBINF_TYPE_DATA_DEBUG:
+	case BRBINF_TYPE_ALGN_FAULT:
+	case BRBINF_TYPE_INST_FAULT:
+	case BRBINF_TYPE_DATA_FAULT:
+	case BRBINF_TYPE_FIQ:
+	case BRBINF_TYPE_DEBUG_EXIT:
+		return PERF_BR_UNKNOWN;
+	default:
+		pr_warn("unknown branch type captured\n");
+		return PERF_BR_UNKNOWN;
+	}
+}
+
+static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *event,
+			       u64 brbinf, int idx)
+{
+	int type = brbe_record_valid(brbinf);
+
+	if (!branch_sample_no_cycles(event))
+		cpuc->brbe_entries[idx].cycles = brbe_fetch_cycles(brbinf);
+
+	if (branch_sample_type(event))
+		cpuc->brbe_entries[idx].type = brbe_fetch_perf_type(brbinf);
+
+	if (!branch_sample_no_flags(event)) {
+		/*
+		 * BRBINF_LASTFAILED does not indicate that the last transaction
+		 * got failed or aborted during the current branch record itself.
+		 * Rather, this indicates that all the branch records which were
+		 * in transaction until the curret branch record have failed. So
+		 * the entire BRBE buffer needs to be processed later on to find
+		 * all branch records which might have failed.
+		 */
+		cpuc->brbe_entries[idx].abort = brbinf & BRBINF_LASTFAILED;
+
+		/*
+		 * All these information (i.e transaction state and mispredicts)
+		 * are not available for target only branch records.
+		 */
+		if (type != BRBINF_VALID_TARGET) {
+			cpuc->brbe_entries[idx].mispred = brbinf & BRBINF_MPRED;
+			cpuc->brbe_entries[idx].predicted = !(brbinf & BRBINF_MPRED);
+			cpuc->brbe_entries[idx].in_tx = brbinf & BRBINF_TX;
+		}
+	}
+}
+
+/*
+ * A branch record with BRBINF_EL1.LASTFAILED set, implies that all
+ * preceding consecutive branch records, that were in a transaction
+ * (i.e their BRBINF_EL1.TX set) have been aborted.
+ *
+ * Similarly BRBFCR_EL1.LASTFAILED set, indicate that all preceding
+ * consecutive branch records upto the last record, which were in a
+ * transaction (i.e their BRBINF_EL1.TX set) have been aborted.
+ *
+ * --------------------------------- -------------------
+ * | 00 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX success]
+ * --------------------------------- -------------------
+ * | 01 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX success]
+ * --------------------------------- -------------------
+ * | 02 | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 0 |
+ * --------------------------------- -------------------
+ * | 03 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
+ * --------------------------------- -------------------
+ * | 04 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
+ * --------------------------------- -------------------
+ * | 05 | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 1 |
+ * --------------------------------- -------------------
+ * | .. | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 0 |
+ * --------------------------------- -------------------
+ * | 61 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
+ * --------------------------------- -------------------
+ * | 62 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
+ * --------------------------------- -------------------
+ * | 63 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
+ * --------------------------------- -------------------
+ *
+ * BRBFCR_EL1.LASTFAILED == 1
+ *
+ * Here BRBFCR_EL1.LASTFAILED failes all those consecutive and also
+ * in transaction branches near the end of the BRBE buffer.
+ */
+static void process_branch_aborts(struct pmu_hw_events *cpuc)
+{
+	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
+	bool lastfailed = !!(brbfcr & BRBFCR_LASTFAILED);
+	int idx = cpuc->brbe_nr - 1;
+
+	do {
+		if (cpuc->brbe_entries[idx].in_tx) {
+			cpuc->brbe_entries[idx].abort = lastfailed;
+		} else {
+			lastfailed = cpuc->brbe_entries[idx].abort;
+			cpuc->brbe_entries[idx].abort = false;
+		}
+	} while (idx--, idx >= 0);
+}
+
+void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event)
+{
+	u64 brbinf;
+	int idx;
+
+	if (brbe_disabled(cpuc))
+		return;
+
+	set_brbe_paused();
+	for (idx = 0; idx < cpuc->brbe_nr; idx++) {
+		select_brbe_bank_index(idx);
+		brbinf = get_brbinf_reg(idx);
+		/*
+		 * There are no valid entries anymore on the buffer.
+		 * Abort the branch record processing to save some
+		 * cycles and also reduce the capture/process load
+		 * for the user space as well.
+		 */
+		if (brbe_invalid(brbinf))
+			break;
+
+		if (brbe_valid(brbinf)) {
+			cpuc->brbe_entries[idx].from =  get_brbsrc_reg(idx);
+			cpuc->brbe_entries[idx].to =  get_brbtgt_reg(idx);
+		} else if (brbe_source(brbinf)) {
+			cpuc->brbe_entries[idx].from =  get_brbsrc_reg(idx);
+			cpuc->brbe_entries[idx].to = 0;
+		} else if (brbe_target(brbinf)) {
+			cpuc->brbe_entries[idx].from = 0;
+			cpuc->brbe_entries[idx].to =  get_brbtgt_reg(idx);
+		}
+		capture_brbe_flags(cpuc, event, brbinf, idx);
+	}
+	cpuc->brbe_stack.nr = idx;
+	cpuc->brbe_stack.hw_idx = -1ULL;
+	process_branch_aborts(cpuc);
+}
+
+void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc)
+{
+	if (brbe_disabled(cpuc))
+		return;
+
+	asm volatile(BRB_IALL);
+	isb();
+}
diff --git a/drivers/perf/arm_pmu_brbe.h b/drivers/perf/arm_pmu_brbe.h
new file mode 100644
index 000000000000..f04975cdc242
--- /dev/null
+++ b/drivers/perf/arm_pmu_brbe.h
@@ -0,0 +1,259 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Branch Record Buffer Extension Helpers.
+ *
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Author: Anshuman Khandual <anshuman.khandual at arm.com>
+ */
+#define pr_fmt(fmt) "brbe: " fmt
+
+#include <linux/perf/arm_pmu.h>
+
+/*
+ * BRBE Instructions
+ *
+ * BRB_IALL : Invalidate the entire buffer
+ * BRB_INJ  : Inject latest branch record derived from [BRBSRCINJ, BRBTGTINJ, BRBINFINJ]
+ */
+#define BRB_IALL __emit_inst(0xD5000000 | sys_insn(1, 1, 7, 2, 4) | (0x1f))
+#define BRB_INJ  __emit_inst(0xD5000000 | sys_insn(1, 1, 7, 2, 5) | (0x1f))
+
+/*
+ * BRBE Buffer Organization
+ *
+ * BRBE buffer is arranged as multiple banks of 32 branch record
+ * entries each. An indivdial branch record in a given bank could
+ * be accessedi, after selecting the bank in BRBFCR_EL1.BANK and
+ * accessing the registers i.e [BRBSRC, BRBTGT, BRBINF] set with
+ * indices [0..31].
+ *
+ * Bank 0
+ *
+ *	---------------------------------	------
+ *	| 00 | BRBSRC | BRBTGT | BRBINF |	| 00 |
+ *	---------------------------------	------
+ *	| 01 | BRBSRC | BRBTGT | BRBINF |	| 01 |
+ *	---------------------------------	------
+ *	| .. | BRBSRC | BRBTGT | BRBINF |	| .. |
+ *	---------------------------------	------
+ *	| 31 | BRBSRC | BRBTGT | BRBINF |	| 31 |
+ *	---------------------------------	------
+ *
+ * Bank 1
+ *
+ *	---------------------------------	------
+ *	| 32 | BRBSRC | BRBTGT | BRBINF |	| 00 |
+ *	---------------------------------	------
+ *	| 33 | BRBSRC | BRBTGT | BRBINF |	| 01 |
+ *	---------------------------------	------
+ *	| .. | BRBSRC | BRBTGT | BRBINF |	| .. |
+ *	---------------------------------	------
+ *	| 63 | BRBSRC | BRBTGT | BRBINF |	| 31 |
+ *	---------------------------------	------
+ */
+#define BRBE_BANK0_IDX_MIN 0
+#define BRBE_BANK0_IDX_MAX 31
+#define BRBE_BANK1_IDX_MIN 32
+#define BRBE_BANK1_IDX_MAX 63
+
+#define RETURN_READ_BRBSRCN(n) \
+	read_sysreg_s(SYS_BRBSRC##n##_EL1)
+
+#define RETURN_READ_BRBTGTN(n) \
+	read_sysreg_s(SYS_BRBTGT##n##_EL1)
+
+#define RETURN_READ_BRBINFN(n) \
+	read_sysreg_s(SYS_BRBINF##n##_EL1)
+
+#define BRBE_REGN_CASE(n, case_macro) \
+	case n: return case_macro(n); break
+
+#define BRBE_REGN_SWITCH(x, case_macro)				\
+	do {							\
+		switch (x) {					\
+		BRBE_REGN_CASE(0, case_macro);			\
+		BRBE_REGN_CASE(1, case_macro);			\
+		BRBE_REGN_CASE(2, case_macro);			\
+		BRBE_REGN_CASE(3, case_macro);			\
+		BRBE_REGN_CASE(4, case_macro);			\
+		BRBE_REGN_CASE(5, case_macro);			\
+		BRBE_REGN_CASE(6, case_macro);			\
+		BRBE_REGN_CASE(7, case_macro);			\
+		BRBE_REGN_CASE(8, case_macro);			\
+		BRBE_REGN_CASE(9, case_macro);			\
+		BRBE_REGN_CASE(10, case_macro);			\
+		BRBE_REGN_CASE(11, case_macro);			\
+		BRBE_REGN_CASE(12, case_macro);			\
+		BRBE_REGN_CASE(13, case_macro);			\
+		BRBE_REGN_CASE(14, case_macro);			\
+		BRBE_REGN_CASE(15, case_macro);			\
+		BRBE_REGN_CASE(16, case_macro);			\
+		BRBE_REGN_CASE(17, case_macro);			\
+		BRBE_REGN_CASE(18, case_macro);			\
+		BRBE_REGN_CASE(19, case_macro);			\
+		BRBE_REGN_CASE(20, case_macro);			\
+		BRBE_REGN_CASE(21, case_macro);			\
+		BRBE_REGN_CASE(22, case_macro);			\
+		BRBE_REGN_CASE(23, case_macro);			\
+		BRBE_REGN_CASE(24, case_macro);			\
+		BRBE_REGN_CASE(25, case_macro);			\
+		BRBE_REGN_CASE(26, case_macro);			\
+		BRBE_REGN_CASE(27, case_macro);			\
+		BRBE_REGN_CASE(28, case_macro);			\
+		BRBE_REGN_CASE(29, case_macro);			\
+		BRBE_REGN_CASE(30, case_macro);			\
+		BRBE_REGN_CASE(31, case_macro);			\
+		default:					\
+			pr_warn("unknown register index\n");	\
+			return -1;				\
+		}						\
+	} while (0)
+
+static inline int buffer_to_brbe_idx(int buffer_idx)
+{
+	return buffer_idx % 32;
+}
+
+static inline u64 get_brbsrc_reg(int buffer_idx)
+{
+	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
+
+	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBSRCN);
+}
+
+static inline u64 get_brbtgt_reg(int buffer_idx)
+{
+	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
+
+	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBTGTN);
+}
+
+static inline u64 get_brbinf_reg(int buffer_idx)
+{
+	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
+
+	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBINFN);
+}
+
+static inline u64 brbe_record_valid(u64 brbinf)
+{
+	return brbinf & (BRBINF_VALID_MASK << BRBINF_VALID_SHIFT);
+}
+
+static inline bool brbe_invalid(u64 brbinf)
+{
+	return brbe_record_valid(brbinf) == BRBINF_VALID_INVALID;
+}
+
+static inline bool brbe_valid(u64 brbinf)
+{
+	return brbe_record_valid(brbinf) == BRBINF_VALID_ALL;
+}
+
+static inline bool brbe_source(u64 brbinf)
+{
+	return brbe_record_valid(brbinf) == BRBINF_VALID_SOURCE;
+}
+
+static inline bool brbe_target(u64 brbinf)
+{
+	return brbe_record_valid(brbinf) == BRBINF_VALID_TARGET;
+}
+
+static inline int brbe_fetch_cycles(u64 brbinf)
+{
+	/*
+	 * Captured cycle count is unknown and hence
+	 * should not be passed on the user space.
+	 */
+	if (brbinf & BRBINF_CCU)
+		return 0;
+
+	return (brbinf >> BRBINF_CC_SHIFT) & BRBINF_CC_MASK;
+}
+
+static inline int brbe_fetch_type(u64 brbinf)
+{
+	return (brbinf >> BRBINF_TYPE_SHIFT) & BRBINF_TYPE_MASK;
+}
+
+static inline int brbe_fetch_el(u64 brbinf)
+{
+	return (brbinf >> BRBINF_EL_SHIFT) & BRBINF_EL_MASK;
+}
+
+static inline int brbe_fetch_numrec(u64 brbidr)
+{
+	return (brbidr >> BRBIDR0_NUMREC_SHIFT) & BRBIDR0_NUMREC_MASK;
+}
+
+static inline int brbe_fetch_format(u64 brbidr)
+{
+	return (brbidr >> BRBIDR0_FORMAT_SHIFT) & BRBIDR0_FORMAT_MASK;
+}
+
+static inline int brbe_fetch_cc_bits(u64 brbidr)
+{
+	return (brbidr >> BRBIDR0_CC_SHIFT) & BRBIDR0_CC_MASK;
+}
+
+static inline void select_brbe_bank(int bank)
+{
+	static int brbe_current_bank = -1;
+	u64 brbfcr;
+
+	if (brbe_current_bank == bank)
+		return;
+
+	WARN_ON(bank > 1);
+	brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
+	brbfcr &= ~(BRBFCR_BANK_MASK << BRBFCR_BANK_SHIFT);
+	brbfcr |= ((bank & BRBFCR_BANK_MASK) << BRBFCR_BANK_SHIFT);
+	write_sysreg_s(brbfcr, SYS_BRBFCR_EL1);
+	isb();
+	brbe_current_bank = bank;
+}
+
+static inline void select_brbe_bank_index(int buffer_idx)
+{
+	switch (buffer_idx) {
+	case BRBE_BANK0_IDX_MIN ... BRBE_BANK0_IDX_MAX:
+		select_brbe_bank(0);
+		break;
+	case BRBE_BANK1_IDX_MIN ... BRBE_BANK1_IDX_MAX:
+		select_brbe_bank(1);
+		break;
+	default:
+		pr_warn("unsupported BRBE index\n");
+	}
+}
+
+static inline bool valid_brbe_nr(int brbe_nr)
+{
+	switch (brbe_nr) {
+	case BRBIDR0_NUMREC_8:
+	case BRBIDR0_NUMREC_16:
+	case BRBIDR0_NUMREC_32:
+	case BRBIDR0_NUMREC_64:
+		return true;
+	default:
+		pr_warn("unsupported BRBE entries\n");
+		return false;
+	}
+}
+
+static inline bool brbe_paused(void)
+{
+	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
+
+	return brbfcr & BRBFCR_PAUSED;
+}
+
+static inline void set_brbe_paused(void)
+{
+	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
+
+	write_sysreg_s(brbfcr | BRBFCR_PAUSED, SYS_BRBFCR_EL1);
+	isb();
+}
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index c4a705d3d054..d401771e7767 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -146,6 +146,26 @@ struct arm_pmu {
 	unsigned long acpi_cpuid;
 };
 
+#ifdef CONFIG_ARM_BRBE_PMU
+void arm64_pmu_brbe_filter(struct pmu_hw_events *hw_events, struct perf_event *event);
+void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event);
+void arm64_pmu_brbe_disable(struct pmu_hw_events *cpuc);
+void arm64_pmu_brbe_enable(struct pmu_hw_events *cpuc);
+void arm64_pmu_brbe_probe(struct pmu_hw_events *cpuc);
+void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc);
+bool arm64_pmu_brbe_supported(struct perf_event *event);
+#else
+static inline void arm64_pmu_brbe_filter(struct pmu_hw_events *hw_events, struct perf_event *event)
+{
+}
+static inline void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event) { }
+static inline void arm64_pmu_brbe_disable(struct pmu_hw_events *cpuc) { }
+static inline void arm64_pmu_brbe_enable(struct pmu_hw_events *cpuc) { }
+static inline void arm64_pmu_brbe_probe(struct pmu_hw_events *cpuc) { }
+static inline void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc) { }
+static inline bool arm64_pmu_brbe_supported(struct perf_event *event) {return false; }
+#endif
+
 #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
 
 u64 armpmu_event_update(struct perf_event *event);
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:50 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:50 +0530
Subject: [RFC V1 08/11] arm64/perf: Enable branch stack sampling
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-9-git-send-email-anshuman.khandual@arm.com>

Now that all the required pieces are already in place, just enable the perf
branch stack sampling support on arm64 platform, by removing the gate which
blocks it in armpmu_event_init().

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 drivers/perf/arm_pmu.c | 25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 0800c8858ed8..2117bf5d3232 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -537,9 +537,28 @@ static int armpmu_event_init(struct perf_event *event)
 		!cpumask_test_cpu(event->cpu, &armpmu->supported_cpus))
 		return -ENOENT;
 
-	/* does not support taken branch sampling */
-	if (has_branch_stack(event))
-		return -EOPNOTSUPP;
+	if (has_branch_stack(event)) {
+		/*
+		 * BRBE support is absent. Select CONFIG_ARM_BRBE_PMU
+		 * in the config, before branch stack sampling events
+		 * can be requested.
+		 */
+		if (!IS_ENABLED(CONFIG_ARM_BRBE_PMU)) {
+			pr_warn_once("BRBE is disabled, select CONFIG_ARM_BRBE_PMU\n");
+			return -EOPNOTSUPP;
+		}
+
+		/*
+		 * Branch stack sampling event can not be supported in
+		 * case either the required driver itself is absent or
+		 * BRBE buffer, is not supported. Besides checking for
+		 * the callback prevents a crash in case it's absent.
+		 */
+		if (!armpmu->brbe_supported || !armpmu->brbe_supported(event)) {
+			pr_warn_once("BRBE is not supported\n");
+			return -EOPNOTSUPP;
+		}
+	}
 
 	if (armpmu->map_event(event) == -ENOENT)
 		return -ENOENT;
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:51 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:51 +0530
Subject: [RFC V1 09/11] perf: Add more generic branch types
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-10-git-send-email-anshuman.khandual@arm.com>

This expands generic branch type classification by adding some more entries
, that can still be represented with the existing 4 bit 'type' field. While
here this also updates the x86 implementation with these new branch types.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/x86/events/intel/lbr.c           |  4 ++--
 drivers/perf/arm_pmu_brbe.c           | 11 +++++++----
 include/uapi/linux/perf_event.h       |  5 +++++
 tools/include/uapi/linux/perf_event.h |  5 +++++
 tools/perf/util/branch.c              |  7 ++++++-
 5 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 8043213b75a5..9f86fac8c6a5 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1336,10 +1336,10 @@ static int branch_map[X86_BR_TYPE_MAP_MAX] = {
 	PERF_BR_SYSCALL,	/* X86_BR_SYSCALL */
 	PERF_BR_SYSRET,		/* X86_BR_SYSRET */
 	PERF_BR_UNKNOWN,	/* X86_BR_INT */
-	PERF_BR_UNKNOWN,	/* X86_BR_IRET */
+	PERF_BR_EXPT_RET,	/* X86_BR_IRET */
 	PERF_BR_COND,		/* X86_BR_JCC */
 	PERF_BR_UNCOND,		/* X86_BR_JMP */
-	PERF_BR_UNKNOWN,	/* X86_BR_IRQ */
+	PERF_BR_IRQ,		/* X86_BR_IRQ */
 	PERF_BR_IND_CALL,	/* X86_BR_IND_CALL */
 	PERF_BR_UNKNOWN,	/* X86_BR_ABORT */
 	PERF_BR_UNKNOWN,	/* X86_BR_IN_TX */
diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
index 8144514b9997..8d27ad868359 100644
--- a/drivers/perf/arm_pmu_brbe.c
+++ b/drivers/perf/arm_pmu_brbe.c
@@ -243,18 +243,21 @@ static int brbe_fetch_perf_type(u64 brbinf)
 	case BRBINF_TYPE_TRAP:
 		return PERF_BR_SYSCALL;
 	case BRBINF_TYPE_RET_EXCPT:
-		return PERF_BR_UNKNOWN;
+		return PERF_BR_EXPT_RET;
 	case BRBINF_TYPE_IRQ:
-		return PERF_BR_UNKNOWN;
+		return PERF_BR_IRQ;
+	case BRBINF_TYPE_FIQ:
+		return PERF_BR_FIQ;
 	case BRBINF_TYPE_DEBUG_HALT:
+		return PERF_BR_DEBUG_HALT;
+	case BRBINF_TYPE_DEBUG_EXIT:
+		return PERF_BR_DEBUG_EXIT;
 	case BRBINF_TYPE_SERROR:
 	case BRBINF_TYPE_INST_DEBUG:
 	case BRBINF_TYPE_DATA_DEBUG:
 	case BRBINF_TYPE_ALGN_FAULT:
 	case BRBINF_TYPE_INST_FAULT:
 	case BRBINF_TYPE_DATA_FAULT:
-	case BRBINF_TYPE_FIQ:
-	case BRBINF_TYPE_DEBUG_EXIT:
 		return PERF_BR_UNKNOWN;
 	default:
 		pr_warn("unknown branch type captured\n");
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042ab1db..b91d0f575d0c 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -251,6 +251,11 @@ enum {
 	PERF_BR_SYSRET		= 8,	/* syscall return */
 	PERF_BR_COND_CALL	= 9,	/* conditional function call */
 	PERF_BR_COND_RET	= 10,	/* conditional function return */
+	PERF_BR_EXPT_RET	= 11,	/* exception return */
+	PERF_BR_IRQ		= 12,	/* irq */
+	PERF_BR_FIQ		= 13,	/* fiq */
+	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
+	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
 	PERF_BR_MAX,
 };
 
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 4cd39aaccbe7..1882054e8684 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -251,6 +251,11 @@ enum {
 	PERF_BR_SYSRET		= 8,	/* syscall return */
 	PERF_BR_COND_CALL	= 9,	/* conditional function call */
 	PERF_BR_COND_RET	= 10,	/* conditional function return */
+	PERF_BR_EXPT_RET	= 11,	/* exception return */
+	PERF_BR_IRQ		= 12,	/* irq */
+	PERF_BR_FIQ		= 13,	/* fiq */
+	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
+	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
 	PERF_BR_MAX,
 };
 
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index 2285b1eb3128..74e5e67b1779 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -49,7 +49,12 @@ const char *branch_type_name(int type)
 		"SYSCALL",
 		"SYSRET",
 		"COND_CALL",
-		"COND_RET"
+		"COND_RET",
+		"EXPT_RET",
+		"IRQ",
+		"FIQ",
+		"DEBUG_HALT",
+		"DEBUG_EXIT"
 	};
 
 	if (type >= 0 && type < PERF_BR_MAX)
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:52 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:52 +0530
Subject: [RFC V1 10/11] perf: Expand perf_branch_entry.type
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>

Current perf_branch_entry.type is a 4 bits field just enough to accommodate
16 generic branch types. This is insufficient to accommodate platforms like
arm64 which has much more branch types. Lets just expands this field into a
6 bits one, which can now hold 64 generic branch types. This also adds more
generic branch types and updates the BRBE driver as required.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 drivers/perf/arm_pmu_brbe.c           |  7 ++++++-
 include/uapi/linux/perf_event.h       | 10 ++++++++--
 tools/include/uapi/linux/perf_event.h | 10 ++++++++--
 tools/perf/util/branch.c              |  8 +++++++-
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
index 8d27ad868359..7cd1208c6c58 100644
--- a/drivers/perf/arm_pmu_brbe.c
+++ b/drivers/perf/arm_pmu_brbe.c
@@ -253,12 +253,17 @@ static int brbe_fetch_perf_type(u64 brbinf)
 	case BRBINF_TYPE_DEBUG_EXIT:
 		return PERF_BR_DEBUG_EXIT;
 	case BRBINF_TYPE_SERROR:
+		return PERF_BR_SERROR;
 	case BRBINF_TYPE_INST_DEBUG:
+		return PERF_BR_DEBUG_INST;
 	case BRBINF_TYPE_DATA_DEBUG:
+		return PERF_BR_DEBUG_DATA;
 	case BRBINF_TYPE_ALGN_FAULT:
+		return PERF_BR_FAULT_ALGN;
 	case BRBINF_TYPE_INST_FAULT:
+		return PERF_BR_FAULT_INST;
 	case BRBINF_TYPE_DATA_FAULT:
-		return PERF_BR_UNKNOWN;
+		return PERF_BR_FAULT_DATA;
 	default:
 		pr_warn("unknown branch type captured\n");
 		return PERF_BR_UNKNOWN;
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index b91d0f575d0c..361fdc6b87a0 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -256,6 +256,12 @@ enum {
 	PERF_BR_FIQ		= 13,	/* fiq */
 	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
 	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
+	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
+	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
+	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
+	PERF_BR_FAULT_DATA	= 19,	/* data fault */
+	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
+	PERF_BR_SERROR		= 21,	/* system error */
 	PERF_BR_MAX,
 };
 
@@ -1370,8 +1376,8 @@ struct perf_branch_entry {
 		in_tx:1,    /* in transaction */
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
-		type:4,     /* branch type */
-		reserved:40;
+		type:6,     /* branch type */
+		reserved:38;
 };
 
 union perf_sample_weight {
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 1882054e8684..9a82b8aaed93 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -256,6 +256,12 @@ enum {
 	PERF_BR_FIQ		= 13,	/* fiq */
 	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
 	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
+	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
+	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
+	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
+	PERF_BR_FAULT_DATA	= 19,	/* data fault */
+	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
+	PERF_BR_SERROR		= 21,	/* system error */
 	PERF_BR_MAX,
 };
 
@@ -1370,8 +1376,8 @@ struct perf_branch_entry {
 		in_tx:1,    /* in transaction */
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
-		type:4,     /* branch type */
-		reserved:40;
+		type:6,     /* branch type */
+		reserved:38;
 };
 
 union perf_sample_weight {
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index 74e5e67b1779..1e216ea2e2a8 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -54,7 +54,13 @@ const char *branch_type_name(int type)
 		"IRQ",
 		"FIQ",
 		"DEBUG_HALT",
-		"DEBUG_EXIT"
+		"DEBUG_EXIT",
+		"DEBUG_INST",
+		"DEBUG_DATA",
+		"FAULT_ALGN",
+		"FAULT_DATA",
+		"FAULT_INST",
+		"SERROR"
 	};
 
 	if (type >= 0 && type < PERF_BR_MAX)
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 20:30:53 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 10:00:53 +0530
Subject: [RFC V1 11/11] perf: Capture branch privilege information
In-Reply-To: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>

Platforms like arm64 could capture privilege level information for all the
branch records. Hence this adds a new element in the struct branch_entry to
record the privilege level information, which could be requested through a
new event.attr.branch_sample_type flag PERF_SAMPLE_BRANCH_PRIV_SAVE. While
here, update the BRBE driver as required.

Cc: Will Deacon <will at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 drivers/perf/arm_pmu_brbe.c              | 28 ++++++++++++++++++++++++
 include/linux/perf_event.h               |  5 +++++
 include/uapi/linux/perf_event.h          | 13 ++++++++++-
 tools/include/uapi/linux/perf_event.h    | 13 ++++++++++-
 tools/perf/Documentation/perf-record.txt |  1 +
 tools/perf/util/parse-branch-options.c   |  1 +
 6 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
index 7cd1208c6c58..d4cbea74c148 100644
--- a/drivers/perf/arm_pmu_brbe.c
+++ b/drivers/perf/arm_pmu_brbe.c
@@ -270,6 +270,25 @@ static int brbe_fetch_perf_type(u64 brbinf)
 	}
 }
 
+static int brbe_fetch_perf_priv(u64 brbinf)
+{
+	int brbe_el = brbe_fetch_el(brbinf);
+
+	switch (brbe_el) {
+	case BRBINF_EL_EL0:
+		return PERF_BR_USER;
+	case BRBINF_EL_EL1:
+		return PERF_BR_KERNEL;
+	case BRBINF_EL_EL2:
+		if (is_kernel_in_hyp_mode())
+			return PERF_BR_KERNEL;
+		return PERF_BR_HV;
+	default:
+		pr_warn("unknown branch privilege captured\n");
+		return -1;
+	}
+}
+
 static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *event,
 			       u64 brbinf, int idx)
 {
@@ -302,6 +321,15 @@ static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *ev
 			cpuc->brbe_entries[idx].in_tx = brbinf & BRBINF_TX;
 		}
 	}
+
+	if (branch_sample_priv(event)) {
+		/*
+		 * All these information (i.e branch privilege level) are not
+		 * available for source only branch records.
+		 */
+		if (type != BRBINF_VALID_SOURCE)
+			cpuc->brbe_entries[idx].priv = brbe_fetch_perf_priv(brbinf);
+	}
 }
 
 /*
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 916ce5102b33..8021b6a30d86 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1688,4 +1688,9 @@ static inline bool branch_sample_hw_index(const struct perf_event *event)
 {
 	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
 }
+
+static inline bool branch_sample_priv(const struct perf_event *event)
+{
+	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_PRIV_SAVE;
+}
 #endif /* _LINUX_PERF_EVENT_H */
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 361fdc6b87a0..4d77710f7a4e 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
 
 	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
 
+	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
+
 	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
 };
 
@@ -233,6 +235,8 @@ enum perf_branch_sample_type {
 
 	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
 
+	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
+
 	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
 
@@ -265,6 +269,12 @@ enum {
 	PERF_BR_MAX,
 };
 
+enum {
+	PERF_BR_USER	= 0,
+	PERF_BR_KERNEL	= 1,
+	PERF_BR_HV	= 2,
+};
+
 #define PERF_SAMPLE_BRANCH_PLM_ALL \
 	(PERF_SAMPLE_BRANCH_USER|\
 	 PERF_SAMPLE_BRANCH_KERNEL|\
@@ -1377,7 +1387,8 @@ struct perf_branch_entry {
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
 		type:6,     /* branch type */
-		reserved:38;
+		priv:2,     /* privilege level */
+		reserved:36;
 };
 
 union perf_sample_weight {
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 9a82b8aaed93..a2208400b0b9 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
 
 	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
 
+	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
+
 	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
 };
 
@@ -233,6 +235,8 @@ enum perf_branch_sample_type {
 
 	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
 
+	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
+
 	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
 };
 
@@ -265,6 +269,12 @@ enum {
 	PERF_BR_MAX,
 };
 
+enum {
+	PERF_BR_USER    = 0,
+	PERF_BR_KERNEL  = 1,
+	PERF_BR_HV      = 2,
+};
+
 #define PERF_SAMPLE_BRANCH_PLM_ALL \
 	(PERF_SAMPLE_BRANCH_USER|\
 	 PERF_SAMPLE_BRANCH_KERNEL|\
@@ -1377,7 +1387,8 @@ struct perf_branch_entry {
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
 		type:6,     /* branch type */
-		reserved:38;
+		priv:2,     /* privilege level */
+		reserved:36;
 };
 
 union perf_sample_weight {
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index 9ccc75935bc5..3e33686977a1 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -387,6 +387,7 @@ following filters are defined:
 	- abort_tx: only when the target is a hardware transaction abort
 	- cond: conditional branches
 	- save_type: save branch type during sampling in case binary is not available later
+	- priv: save privilege state during sampling in case binary is not available later
 
 +
 The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
index bb4aa88c50a8..00588b9db474 100644
--- a/tools/perf/util/parse-branch-options.c
+++ b/tools/perf/util/parse-branch-options.c
@@ -32,6 +32,7 @@ static const struct branch_mode branch_modes[] = {
 	BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
 	BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE),
 	BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK),
+	BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE),
 	BRANCH_END
 };
 
-- 
2.25.1



From miles.chen at mediatek.com  Sun Jan 23 21:20:38 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Mon, 24 Jan 2022 13:20:38 +0800
Subject: [PATCH] clk: mediatek: add unregister logic to
 mtk_clk_simple_probe error path
In-Reply-To: <20220117090030.13064-1-miles.chen@mediatek.com>
References: <20220117090030.13064-1-miles.chen@mediatek.com>
Message-ID: <20220124052038.6242-1-miles.chen@mediatek.com>

Hi Stephen,

> Stephen pointed out that there is no unregister logic in
> mtk_clk_simple_probe() error path [1].
> Fix it by adding unregister logic to mtk_clk_simple_probe().

Chen-Yu's work [1] already addresses this problem. So please ignore
this patch.

[1] https://lore.kernel.org/lkml/20220122091731.283592-1-wenst at chromium.org/



From tfiga at chromium.org  Sun Jan 23 21:37:19 2022
From: tfiga at chromium.org (Tomasz Figa)
Date: Mon, 24 Jan 2022 14:37:19 +0900
Subject: [PATCH] CHROMIUM: iommu: rockchip: Make sure that page table
 state is coherent
In-Reply-To: <21bb5af8-1d59-9369-6008-2fd7e88007eb@collabora.com>
References: <1423480761-33453-1-git-send-email-tfiga@chromium.org>
 <20150303133659.GD10502@8bytes.org>
 <CAAFQd5Abk6X7AVTFaNuUSiShn31pzwwTE3VjfLnE4kyziAjy2A@mail.gmail.com>
 <21bb5af8-1d59-9369-6008-2fd7e88007eb@collabora.com>
Message-ID: <CAAFQd5CnhE6KBEeG=LKKqb2Ry324Wye=CQCuLjD_2Fd5JzpgcQ@mail.gmail.com>

Hi Dafna,

On Fri, Dec 10, 2021 at 12:18 AM Dafna Hirschfeld
<dafna.hirschfeld at collabora.com> wrote:
>
>
>
> On 23.03.15 10:38, Tomasz Figa wrote:
> > Sorry, I had to dig my way out through my backlog.
> >
> > On Tue, Mar 3, 2015 at 10:36 PM, Joerg Roedel <joro at 8bytes.org> wrote:
> >> On Mon, Feb 09, 2015 at 08:19:21PM +0900, Tomasz Figa wrote:
> >>> Even though the code uses the dt_lock spin lock to serialize mapping
> >>> operation from different threads, it does not protect from IOMMU
> >>> accesses that might be already taking place and thus altering state
> >>> of the IOTLB. This means that current mapping code which first zaps
> >>> the page table and only then updates it with new mapping which is
> >>> prone to mentioned race.
> >>
> >> Could you elabortate a bit on the race and why it is sufficient to zap
> >> only the first and the last iova? From the description and the comments
> >> in the patch this is not clear to me.
> >
> > Let's start with why it's sufficient to zap only first and last iova.
> >
> > While unmapping, the driver zaps all iovas belonging to the mapping,
> > so the page tables not used by any mapping won't be cached. Now when
> > the driver creates a mapping it might end up occupying several page
> > tables. However, since the mapping area is virtually contiguous, only
> > the first and last page table can be shared with different mappings.
> > This means that only first and last iovas can be already cached. In
> > fact, we could detect if first and last page tables are shared and do
> > not zap at all, but this wouldn't really optimize too much. Why
> > invalidating one iova is enough to invalidate the whole page table is
> > unclear to me as well, but it seems to be the correct way on this
> > hardware.
>
> Hi,
> It seems to me that actually each mapping needs exactly one page.
> Since (as the inline doc in rk_iommu_map states) the pgsize_bitmap
> makes sure that iova mappings fits exactly into one page table
> since the mapping size is maximum 4M.
>
> This actually means that if rk_dte_get_page_table does not allocate a
> new page table but returns one that is already partially used from previous
> mappings then two page tables might be required, but I think the iova
> allocation somehow make sure that this will not be the case.

Yes, it was exactly for the case. Note that the zap operation is
per-IO-page and not per IOPT and there is some prefetching going on in
the TLB of this IOMMU. So neighboring mappings can interfere with each
other.

>
> If it was the case then the code would be buggy because it means
> that the loop in rk_iommu_map_iova will write behind the page table
> given in rk_dte_get_page_table (which we didn't allocate)

Sorry, I don't see how it could write behind the page table. Could you
give me an example?

>
> So I it seems to me that calling 'rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);'
> as done before this patch should be used, but be moved from
> rk_dte_get_page_table to where rk_iommu_zap_iova_first_last is now
>
> Thanks,
> Dafna
>
> >
> > As for the race, it's also kind of explained by the above. The already
> > running hardware can trigger page table look-ups in the IOMMU and so
> > caching of the page table between our zapping and updating its
> > contents. With this patch zapping is performed after updating the page
> > table so the race is gone.
> >
> > Best regards,
> > Tomasz
> >
> >  From mboxrd at z Thu Jan  1 00:00:00 1970
> > Return-Path: <linux-kernel-owner at vger.kernel.org>
> > Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
> >       id S1753210AbbCWM3R (ORCPT <rfc822;w at 1wt.eu>);
> >       Mon, 23 Mar 2015 08:29:17 -0400
> > Received: from 8bytes.org ([81.169.241.247]:33957 "EHLO theia.8bytes.org"
> >       rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
> >       id S1752552AbbCWM3M (ORCPT <rfc822;linux-kernel at vger.kernel.org>);
> >       Mon, 23 Mar 2015 08:29:12 -0400
> > Date: Mon, 23 Mar 2015 13:29:10 +0100
> > From: Joerg Roedel <joro at 8bytes.org>
> > To: Tomasz Figa <tfiga at chromium.org>
> > Cc: iommu at lists.linux-foundation.org,
> >          "linux-arm-kernel at lists.infradead.org"
> >       <linux-arm-kernel at lists.infradead.org>,
> >          "linux-kernel at vger.kernel.org" <linux-kernel at vger.kernel.org>,
> >          "open list:ARM/Rockchip SoC..." <linux-rockchip at lists.infradead.org>,
> >          Heiko Stuebner <heiko at sntech.de>, Daniel Kurtz <djkurtz at chromium.org>
> > Subject: Re: [PATCH] CHROMIUM: iommu: rockchip: Make sure that page table
> >   state is coherent
> > Message-ID: <20150323122910.GO4441 at 8bytes.org>
> > References: <1423480761-33453-1-git-send-email-tfiga at chromium.org>
> >   <20150303133659.GD10502 at 8bytes.org>
> >   <CAAFQd5Abk6X7AVTFaNuUSiShn31pzwwTE3VjfLnE4kyziAjy2A at mail.gmail.com>
> > MIME-Version: 1.0
> > Content-Type: text/plain; charset=us-ascii
> > Content-Disposition: inline
> > In-Reply-To: <CAAFQd5Abk6X7AVTFaNuUSiShn31pzwwTE3VjfLnE4kyziAjy2A at mail.gmail.com>
> > User-Agent: Mutt/1.5.21 (2010-09-15)
> > Sender: linux-kernel-owner at vger.kernel.org
> > List-ID: <linux-kernel.vger.kernel.org>
> > X-Mailing-List: linux-kernel at vger.kernel.org
> >
> > Hi Tomasz,
> >
> > On Mon, Mar 23, 2015 at 05:38:45PM +0900, Tomasz Figa wrote:
> >> While unmapping, the driver zaps all iovas belonging to the mapping,
> >> so the page tables not used by any mapping won't be cached. Now when
> >> the driver creates a mapping it might end up occupying several page
> >> tables. However, since the mapping area is virtually contiguous, only
> >> the first and last page table can be shared with different mappings.
> >> This means that only first and last iovas can be already cached. In
> >> fact, we could detect if first and last page tables are shared and do
> >> not zap at all, but this wouldn't really optimize too much. Why
> >> invalidating one iova is enough to invalidate the whole page table is
> >> unclear to me as well, but it seems to be the correct way on this
> >> hardware.
> >>
> >> As for the race, it's also kind of explained by the above. The already
> >> running hardware can trigger page table look-ups in the IOMMU and so
> >> caching of the page table between our zapping and updating its
> >> contents. With this patch zapping is performed after updating the page
> >> table so the race is gone.
> >
> > Okay, this makes sense. Can you add this information to the patch
> > changelog and resend please?
> >
> > Thanks,
> >
> >       Joerg
> >
> >
> >  From mboxrd at z Thu Jan  1 00:00:00 1970
> > From: Tomasz Figa <tfiga-F7+t8E8rja9g9hUCZPvPmw at public.gmane.org>
> > Subject: [PATCH] CHROMIUM: iommu: rockchip: Make sure that page table state is
> >       coherent
> > Date: Mon,  9 Feb 2015 20:19:21 +0900
> > Message-ID: <1423480761-33453-1-git-send-email-tfiga at chromium.org>
> > Mime-Version: 1.0
> > Content-Type: text/plain; charset="us-ascii"
> > Content-Transfer-Encoding: 7bit
> > Return-path: <iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org>
> > List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/iommu>,
> >       <mailto:iommu-request-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org?subject=unsubscribe>
> > List-Archive: <http://lists.linuxfoundation.org/pipermail/iommu/>
> > List-Post: <mailto:iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org>
> > List-Help: <mailto:iommu-request-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org?subject=help>
> > List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/iommu>,
> >       <mailto:iommu-request-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org?subject=subscribe>
> > Sender: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org
> > Errors-To: iommu-bounces-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org
> > To: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA at public.gmane.org
> > Cc: Heiko Stuebner <heiko-4mtYJXux2i+zQB+pC5nmwQ at public.gmane.org>, linux-kernel-u79uwXL29TY76Z2rM5mHXA at public.gmane.org, Daniel Kurtz <djkurtz-F7+t8E8rja9g9hUCZPvPmw at public.gmane.org>, Tomasz Figa <tfiga-F7+t8E8rja9g9hUCZPvPmw at public.gmane.org>, linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r at public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r at public.gmane.org
> > List-Id: iommu at lists.linux-foundation.org
> >
> > Even though the code uses the dt_lock spin lock to serialize mapping
> > operation from different threads, it does not protect from IOMMU
> > accesses that might be already taking place and thus altering state
> > of the IOTLB. This means that current mapping code which first zaps
> > the page table and only then updates it with new mapping which is
> > prone to mentioned race.
> >
> > In addition, current code assumes that mappings are always > 4 MiB
> > (which translates to 1024 PTEs) and so they would always occupy
> > entire page tables. This is not true for mappings created by V4L2
> > Videobuf2 DMA contig allocator.
> >
> > This patch changes the mapping code to always zap the page table
> > after it is updated, which avoids the aforementioned race and also
> > zap the last page of the mapping to make sure that stale data is
> > not cached from an already existing mapping.
> >
> > Signed-off-by: Tomasz Figa <tfiga-F7+t8E8rja9g9hUCZPvPmw at public.gmane.org>
> > Reviewed-by: Daniel Kurtz <djkurtz-F7+t8E8rja9g9hUCZPvPmw at public.gmane.org>
> > ---
> >   drivers/iommu/rockchip-iommu.c | 23 +++++++++++++++++------
> >   1 file changed, 17 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
> > index 6a8b1ec..b06fe76 100644
> > --- a/drivers/iommu/rockchip-iommu.c
> > +++ b/drivers/iommu/rockchip-iommu.c
> > @@ -544,6 +544,15 @@ static void rk_iommu_zap_iova(struct rk_iommu_domain *rk_domain,
> >       spin_unlock_irqrestore(&rk_domain->iommus_lock, flags);
> >   }
> >
> > +static void rk_iommu_zap_iova_first_last(struct rk_iommu_domain *rk_domain,
> > +                                      dma_addr_t iova, size_t size)
> > +{
> > +     rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
> > +     if (size > SPAGE_SIZE)
> > +             rk_iommu_zap_iova(rk_domain, iova + size - SPAGE_SIZE,
> > +                                     SPAGE_SIZE);
> > +}
> > +
> >   static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
> >                                 dma_addr_t iova)
> >   {
> > @@ -568,12 +577,6 @@ static u32 *rk_dte_get_page_table(struct rk_iommu_domain *rk_domain,
> >       rk_table_flush(page_table, NUM_PT_ENTRIES);
> >       rk_table_flush(dte_addr, 1);
> >
> > -     /*
> > -      * Zap the first iova of newly allocated page table so iommu evicts
> > -      * old cached value of new dte from the iotlb.
> > -      */
> > -     rk_iommu_zap_iova(rk_domain, iova, SPAGE_SIZE);
> > -
> >   done:
> >       pt_phys = rk_dte_pt_address(dte);
> >       return (u32 *)phys_to_virt(pt_phys);
> > @@ -623,6 +626,14 @@ static int rk_iommu_map_iova(struct rk_iommu_domain *rk_domain, u32 *pte_addr,
> >
> >       rk_table_flush(pte_addr, pte_count);
> >
> > +     /*
> > +      * Zap the first and last iova to evict from iotlb any previously
> > +      * mapped cachelines holding stale values for its dte and pte.
> > +      * We only zap the first and last iova, since only they could have
> > +      * dte or pte shared with an existing mapping.
> > +      */
> > +     rk_iommu_zap_iova_first_last(rk_domain, iova, size);
> > +
> >       return 0;
> >   unwind:
> >       /* Unmap the range of iovas that we just mapped */
> >


From leilk.liu at mediatek.com  Sun Jan 23 21:54:00 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Jan 2022 13:54:00 +0800
Subject: [PATCH V2 1/3] dt-bindings: spi: Convert spi-slave-mt27xx to
 json-schema
In-Reply-To: <YetVd7IR7FDt+nz3@robh.at.kernel.org>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
 <20220112103609.17421-2-leilk.liu@mediatek.com>
 <YetVd7IR7FDt+nz3@robh.at.kernel.org>
Message-ID: <284792c07f1adcd2ceeab287c6f38c35ee689c0a.camel@mediatek.com>

On Fri, 2022-01-21 at 18:53 -0600, Rob Herring wrote:
> On Wed, Jan 12, 2022 at 06:36:07PM +0800, Leilk Liu wrote:
> > Convert Mediatek ARM SOC's SPI Slave controller binding
> > to json-schema format.
> > 
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> > ---
> >  .../spi/mediatek,spi-slave-mt27xx.yaml        | 73
> > +++++++++++++++++++
> >  .../bindings/spi/spi-slave-mt27xx.txt         | 33 ---------
> >  2 files changed, 73 insertions(+), 33 deletions(-)
> >  create mode 100644
> > Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> > mt27xx.yaml
> >  delete mode 100644 Documentation/devicetree/bindings/spi/spi-
> > slave-mt27xx.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-
> > slave-mt27xx.yaml
> > b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> > mt27xx.yaml
> > new file mode 100644
> > index 000000000000..3364fff08cca
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-
> > mt27xx.yaml
> > @@ -0,0 +1,73 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: 
> > http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SPI Slave controller for MediaTek ARM SoCs
> > +
> > +maintainers:
> > +  - Leilk Liu <leilk.liu at mediatek.com>
> > +
> > +allOf:
> > +  - $ref: /spi/spi-controller.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - items:
> > +          - enum:
> > +              - mediatek,mt2712-spi-slave
> > +      - items:
> > +          - enum:
> > +              - mediatek,mt8195-spi-slave
> 
> Just:
> 
>        enum:
>          - mediatek,mt2712-spi-slave
>          - mediatek,mt8195-spi-slave
> 
OK, I'll fix it.

> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: clock used for the clock gate
> 
> Just 'maxItems: 1'
> 
OK, I'll fix it.

> > +
> > +  clock-names:
> > +    items:
> > +      - const: spi
> > +
> > +  assigned-clocks:
> > +    maxItems: 1
> > +    description: |
> > +      The mux clock for the given platform.
> > +
> > +  assigned-clock-parents:
> > +    maxItems: 1
> > +    description: |
> > +      The parent of mux clock for the given platform.
> 
> You can drop assigned-clocks. They are always allowed on nodes with 
> 'clocks'.
> 
OK, I'll fix it.

> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/mt2712-clk.h>
> > +    #include <dt-bindings/gpio/gpio.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +    spi at 10013000 {
> > +      compatible = "mediatek,mt2712-spi-slave";
> > +      reg = <0x10013000 0x100>;
> > +      interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
> > +      clocks = <&infracfg CLK_INFRA_AO_SPI1>;
> > +      clock-names = "spi";
> > +      assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
> > +      assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
> > +    };

From leilk.liu at mediatek.com  Sun Jan 23 21:54:49 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Jan 2022 13:54:49 +0800
Subject: [PATCH V2 2/3] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <YetWXSzugRwKb+xA@robh.at.kernel.org>
References: <20220112103609.17421-1-leilk.liu@mediatek.com>
 <20220112103609.17421-3-leilk.liu@mediatek.com>
 <YetWXSzugRwKb+xA@robh.at.kernel.org>
Message-ID: <5b8f822da1dbb7e0d204d6eeccd9cd80b3ef004c.camel@mediatek.com>

On Fri, 2022-01-21 at 18:57 -0600, Rob Herring wrote:
> On Wed, Jan 12, 2022 at 06:36:08PM +0800, Leilk Liu wrote:
> > Convert Mediatek ARM SOC's SPI Master controller binding
> > to json-schema format.
> > 
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> > ---
> >  .../bindings/spi/mediatek,spi-mt65xx.yaml     | 99
> > +++++++++++++++++++
> >  .../devicetree/bindings/spi/spi-mt65xx.txt    | 68 -------------
> >  2 files changed, 99 insertions(+), 68 deletions(-)
> >  create mode 100644
> > Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
> >  delete mode 100644 Documentation/devicetree/bindings/spi/spi-
> > mt65xx.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-
> > mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-
> > mt65xx.yaml
> > new file mode 100644
> > index 000000000000..71f0cf6e5d70
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/spi/mediatek,spi-
> > mt65xx.yaml
> > @@ -0,0 +1,99 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: SPI Bus controller for MediaTek ARM SoCs
> > +
> > +maintainers:
> > +  - Leilk Liu <leilk.liu at mediatek.com>
> > +
> > +allOf:
> > +  - $ref: /spi/spi-controller.yaml#
> 
> /schemas/spi/spi-controller.yaml#
> 
OK, I'll fix it.

> > +
> > +properties:
> > +  compatible:
> > +    oneOf:
> > +      - items:
> > +          - enum:
> > +              - mediatek,mt7629-spi
> > +          - const: mediatek,mt7622-spi
> > +      - items:
> > +          - enum:
> > +              - mediatek,mt8516-spi
> > +          - const: mediatek,mt2712-spi
> > +      - items:
> > +          - enum:
> > +              - mediatek,mt6779-spi
> > +              - mediatek,mt8192-spi
> > +              - mediatek,mt8195-spi
> > +          - const: mediatek,mt6765-spi
> > +      - const: mediatek,mt2701-spi
> > +      - const: mediatek,mt2712-spi
> > +      - const: mediatek,mt6589-spi
> > +      - const: mediatek,mt6765-spi
> > +      - const: mediatek,mt6893-spi
> > +      - const: mediatek,mt7622-spi
> > +      - const: mediatek,mt8135-spi
> > +      - const: mediatek,mt8173-spi
> > +      - const: mediatek,mt8183-spi
> 
> All these can be 1 enum.
> 
OK, I'll fix it.

> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  interrupts:
> > +    maxItems: 1
> > +
> > +  clocks:
> > +    items:
> > +      - description: clock used for the parent clock
> > +      - description: clock used for the muxes clock
> > +      - description: clock used for the clock gate
> > +
> > +  clock-names:
> > +    items:
> > +      - const: parent-clk
> > +      - const: sel-clk
> > +      - const: spi-clk
> > +
> > +  mediatek,pad-select:
> > +    $ref: /schemas/types.yaml#/definitions/uint32-array
> > +    maxItems: 4
> > +    items:
> > +      enum: [0, 1, 2, 3]
> > +    description:
> > +      specify which pins group(ck/mi/mo/cs) spi controller used.
> > +      This is an array.
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - '#address-cells'
> > +  - '#size-cells'
> > +
> > +unevaluatedProperties: false
> > +
> > +examples:
> > +  - |
> > +    #include <dt-bindings/clock/mt8173-clk.h>
> > +    #include <dt-bindings/gpio/gpio.h>
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +
> > +    spi at 1100a000 {
> > +      compatible = "mediatek,mt8173-spi";
> > +      #address-cells = <1>;
> > +      #size-cells = <0>;
> > +      reg = <0x1100a000 0x1000>;
> > +      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
> > +      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
> > +               <&topckgen CLK_TOP_SPI_SEL>,
> > +               <&pericfg CLK_PERI_SPI0>;
> > +      clock-names = "parent-clk", "sel-clk", "spi-clk";
> > +      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72
> > GPIO_ACTIVE_LOW>;
> > +      mediatek,pad-select = <1>, <0>;
> > +    };

From leilk.liu at mediatek.com  Sun Jan 23 22:12:38 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Jan 2022 14:12:38 +0800
Subject: [PATCH V3 2/2] dt-bindings: spi: Add compatible for Mediatek MT8186
In-Reply-To: <20220124061238.7854-1-leilk.liu@mediatek.com>
References: <20220124061238.7854-1-leilk.liu@mediatek.com>
Message-ID: <20220124061238.7854-3-leilk.liu@mediatek.com>

This commit adds dt-binding documentation of spi bus for Mediatek MT8186 SoC
Platform.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
index ea977fba49a7..bfa44acb1bdd 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -26,6 +26,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt6779-spi
+              - mediatek,mt8186-spi
               - mediatek,mt8192-spi
               - mediatek,mt8195-spi
           - const: mediatek,mt6765-spi
-- 
2.25.1



From leilk.liu at mediatek.com  Sun Jan 23 22:12:36 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Jan 2022 14:12:36 +0800
Subject: [PATCH V3 0/3] Add compatible for Mediatek MT8186 
Message-ID: <20220124061238.7854-1-leilk.liu@mediatek.com>

Subject: [PATCH V3 0/3] Add compatible for Mediatek MT8186

v3:
1. Fix Rob review comment in v2.

v2:
1. Fix Rob review comment.
2. split spi-mt65xx & spi-slave-mt27xx to 2 patches.

Leilk Liu (3):
  dt-bindings: spi: Convert spi-slave-mt27xx to json-schema
  dt-bindings: spi: Convert spi-mt65xx to json-schema
  dt-bindings: spi: Add compatible for Mediatek MT8186

 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 102 ++++++++++++++++++
 .../spi/mediatek,spi-slave-mt27xx.yaml        |  58 ++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    |  68 ------------
 .../bindings/spi/spi-slave-mt27xx.txt         |  33 ------
 4 files changed, 160 insertions(+), 101 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

--
2.18.0




From leilk.liu at mediatek.com  Sun Jan 23 22:12:37 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Mon, 24 Jan 2022 14:12:37 +0800
Subject: [PATCH V3 1/2] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <20220124061238.7854-1-leilk.liu@mediatek.com>
References: <20220124061238.7854-1-leilk.liu@mediatek.com>
Message-ID: <20220124061238.7854-2-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Master controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 101 ++++++++++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    |  68 ------------
 2 files changed, 101 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
new file mode 100644
index 000000000000..ea977fba49a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Bus controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: "/schemas/spi/spi-controller.yaml#"
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt7629-spi
+          - const: mediatek,mt7622-spi
+      - items:
+          - enum:
+              - mediatek,mt8516-spi
+          - const: mediatek,mt2712-spi
+      - items:
+          - enum:
+              - mediatek,mt6779-spi
+              - mediatek,mt8192-spi
+              - mediatek,mt8195-spi
+          - const: mediatek,mt6765-spi
+      - items:
+          - enum:
+              - mediatek,mt2701-spi
+              - mediatek,mt2712-spi
+              - mediatek,mt6589-spi
+              - mediatek,mt6765-spi
+              - mediatek,mt6893-spi
+              - mediatek,mt7622-spi
+              - mediatek,mt8135-spi
+              - mediatek,mt8173-spi
+              - mediatek,mt8183-spi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the parent clock
+      - description: clock used for the muxes clock
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: parent-clk
+      - const: sel-clk
+      - const: spi-clk
+
+  mediatek,pad-select:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    maxItems: 4
+    items:
+      enum: [0, 1, 2, 3]
+    description:
+      specify which pins group(ck/mi/mo/cs) spi controller used.
+      This is an array.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 1100a000 {
+      compatible = "mediatek,mt8173-spi";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      reg = <0x1100a000 0x1000>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+               <&topckgen CLK_TOP_SPI_SEL>,
+               <&pericfg CLK_PERI_SPI0>;
+      clock-names = "parent-clk", "sel-clk", "spi-clk";
+      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
+      mediatek,pad-select = <1>, <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
deleted file mode 100644
index 2a24969159cc..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Binding for MTK SPI controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2701-spi: for mt2701 platforms
-    - mediatek,mt2712-spi: for mt2712 platforms
-    - mediatek,mt6589-spi: for mt6589 platforms
-    - mediatek,mt6765-spi: for mt6765 platforms
-    - mediatek,mt7622-spi: for mt7622 platforms
-    - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
-    - mediatek,mt8135-spi: for mt8135 platforms
-    - mediatek,mt8173-spi: for mt8173 platforms
-    - mediatek,mt8183-spi: for mt8183 platforms
-    - mediatek,mt6893-spi: for mt6893 platforms
-    - "mediatek,mt8192-spi", "mediatek,mt6765-spi": for mt8192 platforms
-    - "mediatek,mt8195-spi", "mediatek,mt6765-spi": for mt8195 platforms
-    - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
-    - "mediatek,mt6779-spi", "mediatek,mt6765-spi": for mt6779 platforms
-
-- #address-cells: should be 1.
-
-- #size-cells: should be 0.
-
-- reg: Address and length of the register set for the device
-
-- interrupts: Should contain spi interrupt
-
-- clocks: phandles to input clocks.
-  The first should be one of the following. It's PLL.
-   -  <&clk26m>: specify parent clock 26MHZ.
-   -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
-				      It's the default one.
-   -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
-  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
-
-- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
-  muxes clock, and "spi-clk" for the clock gate.
-
-Optional properties:
--cs-gpios: see spi-bus.txt.
-
-- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
-  controller used. This is an array, the element value should be 0~3,
-  only required for MT8173.
-    0: specify GPIO69,70,71,72 for spi pins.
-    1: specify GPIO102,103,104,105 for spi pins.
-    2: specify GPIO128,129,130,131 for spi pins.
-    3: specify GPIO5,6,7,8 for spi pins.
-
-Example:
-
-- SoC Specific Portion:
-spi: spi at 1100a000 {
-	compatible = "mediatek,mt8173-spi";
-	#address-cells = <1>;
-	#size-cells = <0>;
-	reg = <0 0x1100a000 0 0x1000>;
-	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
-		 <&topckgen CLK_TOP_SPI_SEL>,
-		 <&pericfg CLK_PERI_SPI0>;
-	clock-names = "parent-clk", "sel-clk", "spi-clk";
-	cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
-	mediatek,pad-select = <1>, <0>;
-};
-- 
2.25.1



From anshuman.khandual at arm.com  Sun Jan 23 22:13:43 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 11:43:43 +0530
Subject: [PATCH] mm: Generalize ARCH_HAS_FILTER_PGPROT
Message-ID: <1643004823-16441-1-git-send-email-anshuman.khandual@arm.com>

ARCH_HAS_FILTER_PGPROT config has duplicate definitions on platforms that
subscribe it. Instead make it a generic config option which can be selected
on applicable platforms when required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: "H. Peter Anvin" <hpa at zytor.com>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: x86 at kernel.org
Cc: linux-mm at kvack.org
Cc: linux-kernel at vger.kernel.org
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.17-rc1

 arch/arm64/Kconfig | 4 +---
 arch/x86/Kconfig   | 3 ---
 mm/Kconfig         | 3 +++
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..cad609528e58 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -23,6 +23,7 @@ config ARM64
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
 	select ARCH_HAS_FAST_MULTIPLIER
+	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_GIGANTIC_PAGE
@@ -1166,9 +1167,6 @@ config HW_PERF_EVENTS
 	def_bool y
 	depends on ARM_PMU
 
-config ARCH_HAS_FILTER_PGPROT
-	def_bool y
-
 # Supported by clang >= 7.0
 config CC_HAVE_SHADOW_CALL_STACK
 	def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ebe8fc76949a..5f33a10d3dcc 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -332,9 +332,6 @@ config GENERIC_CALIBRATE_DELAY
 config ARCH_HAS_CPU_RELAX
 	def_bool y
 
-config ARCH_HAS_FILTER_PGPROT
-	def_bool y
-
 config ARCH_HIBERNATION_POSSIBLE
 	def_bool y
 
diff --git a/mm/Kconfig b/mm/Kconfig
index 3326ee3903f3..257ed9c86de3 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -744,6 +744,9 @@ config IDLE_PAGE_TRACKING
 config ARCH_HAS_CACHE_LINE_SIZE
 	bool
 
+config ARCH_HAS_FILTER_PGPROT
+	bool
+
 config ARCH_HAS_PTE_DEVMAP
 	bool
 
-- 
2.25.1



From qiangqing.zhang at nxp.com  Sun Jan 23 22:25:58 2022
From: qiangqing.zhang at nxp.com (Joakim Zhang)
Date: Mon, 24 Jan 2022 06:25:58 +0000
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye19vpFWXR8wJQVH@xhacker>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
 <Ye19vpFWXR8wJQVH@xhacker>
Message-ID: <DB8PR04MB6795A6611E578530ACC337E9E65E9@DB8PR04MB6795.eurprd04.prod.outlook.com>


Hi Jisheng,

> -----Original Message-----
> From: Jisheng Zhang <jszhang at kernel.org>
> Sent: 2022?1?24? 0:10
> To: Andrew Lunn <andrew at lunn.ch>; Joakim Zhang
> <qiangqing.zhang at nxp.com>
> Cc: Giuseppe Cavallaro <peppe.cavallaro at st.com>; Alexandre Torgue
> <alexandre.torgue at foss.st.com>; Jose Abreu <joabreu at synopsys.com>;
> David S . Miller <davem at davemloft.net>; Jakub Kicinski <kuba at kernel.org>;
> Maxime Coquelin <mcoquelin.stm32 at gmail.com>; netdev at vger.kernel.org;
> linux-stm32 at st-md-mailman.stormreply.com;
> linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org
> Subject: Re: [PATCH] net: stmmac: don't stop RXC during LPI
> 
> On Mon, Jan 24, 2022 at 12:08:22AM +0800, Jisheng Zhang wrote:
> > On Sun, Jan 23, 2022 at 04:52:29PM +0100, Andrew Lunn wrote:
> > > On Sun, Jan 23, 2022 at 10:12:45PM +0800, Jisheng Zhang wrote:
> > > > I met can't receive rx pkt issue with below steps:
> > > > 0.plug in ethernet cable then boot normal and get ip from dhcp
> > > > server 1.quickly hotplug out then hotplug in the ethernet cable
> > > > 2.trigger the dhcp client to renew lease
> > > >
> > > > tcpdump shows that the request tx pkt is sent out successfully,
> > > > but the mac can't receive the rx pkt.
> > > >
> > > > The issue can easily be reproduced on platforms with PHY_POLL
> > > > external phy. If we don't allow the phy to stop the RXC during
> > > > LPI, the issue is gone. I think it's unsafe to stop the RXC during
> > > > LPI because the mac needs RXC clock to support RX logic.
> > > >
> > > > And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so
> > > > use false instead of 0.
> > > >
> > > > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > > > ---
> > > >  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > > b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > > index 6708ca2aa4f7..92a9b0b226b1 100644
> > > > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > > @@ -1162,7 +1162,7 @@ static void stmmac_mac_link_up(struct
> > > > phylink_config *config,
> > > >
> > > >  	stmmac_mac_set(priv, priv->ioaddr, true);
> > > >  	if (phy && priv->dma_cap.eee) {
> > > > -		priv->eee_active = phy_init_eee(phy, 1) >= 0;
> > > > +		priv->eee_active = phy_init_eee(phy, false) >= 0;
> > >
> > > This has not caused issues in the past. So i'm wondering if this is
> > > somehow specific to your system? Does everybody else use a PHY which
> > > does not implement this bit? Does your synthesis of the stmmac have
> > > a different clock tree?
> > >
> > > By changing this value for every instance of the stmmac, you are
> > > potentially causing a power regression for stmmac implementations
> > > which don't need the clock. So we need a clear understanding,
> > > stopping the clock is wrong in general and so the change is correct
> > > in
> >
> > I think this is a common issue because the MAC needs phy's RXC for RX
> > logic. But it's better to let other stmmac users verify. The issue can
> > easily be reproduced on platforms with PHY_POLL external phy.
> > Or other platforms use a dedicated clock rather than clock from phy
> > for MAC's RX logic?
> >
> > If the issue turns out specific to my system, then I will send out a
> > new patch to adopt your suggestion.
> >
> 
> + Joakim
> 
> > Hi Joakim, IIRC, you have stmmac + external RTL8211F phy platform, but
> > I'm not sure whether your platform have an irq for the phy. could you
> > help me to check whether you can reproduce the issue on your platform?

Yes, i.MX8MP uses the stmmac + external RTL8211F which works on PHY_POLL mode.
I tried the reproduce steps you provided, but the Ethernet can work properly. I don't know what abnormal behavior should appear obviously?

Regarding to your reported issue, I guess this is a real general issue for SNPS stmmac working on RGMII mode, not sure if other mii modes also suffer similar issue.
Actually we have a same patch for it at local since 5.10 to fix a suspend/resume issue.
https://source.codeaurora.org/external/imx/linux-imx/commit/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c?h=lf-5.10.y&id=a7864e9fbc8f8f99e785ce7419a682651c89b8f7

The root cause is that stmmac needs RXC clock generating from PHY for some receive logic, if RXC clock is not feeding in time, stmmac would be broken. And the feedback from SNPS guys, they confirm that stmmac needs this RXC clock and there is no other clocks can be routed if RXC is not present.
 
Best Regards,
Joakim Zhang

From quic_saipraka at quicinc.com  Sun Jan 23 22:33:29 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:29 +0530
Subject: [PATCHv9 0/5] lib/rwmmio/arm64: Add support to trace register
 reads/writes
Message-ID: <cover.1642482334.git.quic_saipraka@quicinc.com>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

This series is a follow-up for the series [1] and a recent series [2] making use
of both.

[1] https://lore.kernel.org/lkml/cover.1536430404.git.saiprakash.ranjan at codeaurora.org/
[2] https://lore.kernel.org/lkml/1604631386-178312-1-git-send-email-psodagud at codeaurora.org/

Note in previous v4 version, Arnd suggested to benchmark and compare size with callback
based implementation, please see [3] for more details on that with brief comparison below.


**Inline version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
   text           data             bss     dec             hex         filename
 23884219        14284468         532568 38701255        24e88c7        vmlinux

**Callback version with CONFIG_FTRACE=y and CONFIG_TRACE_MMIO_ACCESS=y**
$ size vmlinux
    text          data             bss     dec             hex        filename
 24108179        14279596         532568 38920343        251e097       vmlinux

$ ./scripts/bloat-o-meter inline-vmlinux callback-vmlinux
add/remove: 8/3 grow/shrink: 4889/89 up/down: 242244/-11564 (230680)
Total: Before=25812612, After=26043292, chg +0.89%

[3] https://lore.kernel.org/lkml/466449a1-36da-aaa9-7e4f-477f36b52c9e at quicinc.com/

Changes in v9:
 * Use TRACE_EVENT_CLASS for rwmmio_write and post_write (Steven Rostedt)

Changes in v8:
 * Fix build error reported by kernel test robot.

Changes in v7:
 * Use lib/ instead of kernel/trace/ based on review comment by Steven Rostedt.

Changes in v6:
 * Implemented suggestions by Arnd Bergmann:
   - Use arch independent IO barriers in arm64/asm
   - Add ARCH_HAVE_TRACE_MMIO_ACCESS
   - Add post read and post write logging support
   - Remove tracepoint_active check
 * Fix build error reported by kernel test robot.

Changes in v5:
 * Move arm64 to use asm-generic provided high level MMIO accessors (Arnd).
 * Add inline logging for MMIO relaxed and non-relaxed accessors.
 * Move nVHE KVM comment to makefile (Marc).
 * Fix overflow warning due to switch to inline accessors instead of macro.
 * Modify trace event field to include caller and parent details for more detailed logs.

Changes in v4:
 * Drop dynamic debug based filter support since that will be developed later with
   the help from Steven (Ftrace maintainer).
 * Drop value passed to writel as it is causing hangs when tracing is enabled.
 * Code cleanup for trace event as suggested by Steven for earlier version.
 * Fixed some build errors reported by 0-day bot.

Changes in v3:
 * Create a generic mmio header for instrumented version (Earlier suggested in [1]
   by Will Deacon and recently [2] by Greg to have a generic version first).
 * Add dynamic debug support to filter out traces which can be very useful for targeted
   debugging specific to subsystems or drivers.
 * Few modifications to the rwmmio trace event fields to include the mmio width and print
   addresses in hex.
 * Rewrote commit msg to explain some more about usecases.

Prasad Sodagudi (1):
  lib: Add register read/write tracing support

Sai Prakash Ranjan (4):
  arm64: io: Use asm-generic high level MMIO accessors
  irqchip/tegra: Fix overflow implicit truncation warnings
  drm/meson: Fix overflow implicit truncation warnings
  asm-generic/io: Add logging support for MMIO accessors

 arch/Kconfig                      |  3 +
 arch/arm64/Kconfig                |  1 +
 arch/arm64/include/asm/io.h       | 41 +++----------
 arch/arm64/kvm/hyp/nvhe/Makefile  |  7 ++-
 drivers/gpu/drm/meson/meson_viu.c | 22 +++----
 drivers/irqchip/irq-tegra.c       | 10 ++--
 include/asm-generic/io.h          | 82 ++++++++++++++++++++++++--
 include/trace/events/rwmmio.h     | 97 +++++++++++++++++++++++++++++++
 lib/Kconfig                       |  7 +++
 lib/Makefile                      |  2 +
 lib/trace_readwrite.c             | 47 +++++++++++++++
 11 files changed, 265 insertions(+), 54 deletions(-)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c


base-commit: bd8d9cef2a7932e688ca267ea1adf5ea6557c777
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 23 22:33:30 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:30 +0530
Subject: [PATCHv9 1/5] arm64: io: Use asm-generic high level MMIO accessors
In-Reply-To: <cover.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <87926437f2f9e72dd94f0b30c8784c2da5508644.1642482334.git.quic_saipraka@quicinc.com>

Remove custom arm64 MMIO accessors read{b,w,l,q} and their relaxed
versions in support to use asm-generic defined accessors. Also define
one set of IO barriers (ar/bw version) used by asm-generic code to
override the arm64 specific variants.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/include/asm/io.h | 41 ++++++++-----------------------------
 1 file changed, 8 insertions(+), 33 deletions(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7fd836bea7eb..1b436810d779 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -91,7 +91,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 }
 
 /* IO barriers */
-#define __iormb(v)							\
+#define __io_ar(v)							\
 ({									\
 	unsigned long tmp;						\
 									\
@@ -108,39 +108,14 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 		     : "memory");					\
 })
 
-#define __io_par(v)		__iormb(v)
-#define __iowmb()		dma_wmb()
-#define __iomb()		dma_mb()
-
-/*
- * Relaxed I/O memory access primitives. These follow the Device memory
- * ordering rules but do not guarantee any ordering relative to Normal memory
- * accesses.
- */
-#define readb_relaxed(c)	({ u8  __r = __raw_readb(c); __r; })
-#define readw_relaxed(c)	({ u16 __r = le16_to_cpu((__force __le16)__raw_readw(c)); __r; })
-#define readl_relaxed(c)	({ u32 __r = le32_to_cpu((__force __le32)__raw_readl(c)); __r; })
-#define readq_relaxed(c)	({ u64 __r = le64_to_cpu((__force __le64)__raw_readq(c)); __r; })
+#define __io_bw()		dma_wmb()
+#define __io_br(v)
+#define __io_aw(v)
 
-#define writeb_relaxed(v,c)	((void)__raw_writeb((v),(c)))
-#define writew_relaxed(v,c)	((void)__raw_writew((__force u16)cpu_to_le16(v),(c)))
-#define writel_relaxed(v,c)	((void)__raw_writel((__force u32)cpu_to_le32(v),(c)))
-#define writeq_relaxed(v,c)	((void)__raw_writeq((__force u64)cpu_to_le64(v),(c)))
-
-/*
- * I/O memory access primitives. Reads are ordered relative to any
- * following Normal memory access. Writes are ordered relative to any prior
- * Normal memory access.
- */
-#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(__v); __v; })
-#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(__v); __v; })
-#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(__v); __v; })
-#define readq(c)		({ u64 __v = readq_relaxed(c); __iormb(__v); __v; })
-
-#define writeb(v,c)		({ __iowmb(); writeb_relaxed((v),(c)); })
-#define writew(v,c)		({ __iowmb(); writew_relaxed((v),(c)); })
-#define writel(v,c)		({ __iowmb(); writel_relaxed((v),(c)); })
-#define writeq(v,c)		({ __iowmb(); writeq_relaxed((v),(c)); })
+/* arm64-specific, don't use in portable drivers */
+#define __iormb(v)		__io_ar(v)
+#define __iowmb()		__io_bw()
+#define __iomb()		dma_mb()
 
 /*
  *  I/O port access primitives.
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 23 22:33:31 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:31 +0530
Subject: [PATCHv9 2/5] irqchip/tegra: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <2cd67f7eee96e062ea479b7406799f7a2daa5b1b.1642482334.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for tegra irqchip driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/irqchip/irq-tegra.c: In function ?tegra_ictlr_suspend?:
drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
   writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
                  ^

Cc: Marc Zyngier <maz at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/irqchip/irq-tegra.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
index e1f771c72fc4..9e4e5b39c701 100644
--- a/drivers/irqchip/irq-tegra.c
+++ b/drivers/irqchip/irq-tegra.c
@@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void)
 		lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
 
 		/* Disable COP interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 
 		/* Disable CPU interrupts */
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 
 		/* Enable the wakeup sources of ictlr */
 		writel_relaxed(lic->ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
@@ -172,12 +172,12 @@ static void tegra_ictlr_resume(void)
 
 		writel_relaxed(lic->cpu_iep[i],
 			       ictlr + ICTLR_CPU_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_CPU_IER_CLR);
 		writel_relaxed(lic->cpu_ier[i],
 			       ictlr + ICTLR_CPU_IER_SET);
 		writel_relaxed(lic->cop_iep[i],
 			       ictlr + ICTLR_COP_IEP_CLASS);
-		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
 		writel_relaxed(lic->cop_ier[i],
 			       ictlr + ICTLR_COP_IER_SET);
 	}
@@ -312,7 +312,7 @@ static int __init tegra_ictlr_init(struct device_node *node,
 		lic->base[i] = base;
 
 		/* Disable all interrupts */
-		writel_relaxed(~0UL, base + ICTLR_CPU_IER_CLR);
+		writel_relaxed(~0U, base + ICTLR_CPU_IER_CLR);
 		/* All interrupts target IRQ */
 		writel_relaxed(0, base + ICTLR_CPU_IEP_CLASS);
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 23 22:33:32 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:32 +0530
Subject: [PATCHv9 3/5] drm/meson: Fix overflow implicit truncation warnings
In-Reply-To: <cover.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <b5e5b45bcb7b022147dc0036daf35d72d102e946.1642482334.git.quic_saipraka@quicinc.com>

Fix -Woverflow warnings for drm/meson driver which is a result
of moving arm64 custom MMIO accessor macros to asm-generic function
implementations giving a bonus type-checking now and uncovering these
overflow warnings.

drivers/gpu/drm/meson/meson_viu.c: In function ?meson_viu_init?:
drivers/gpu/drm/meson/meson_registers.h:1826:48: error: large integer implicitly truncated to unsigned type [-Werror=overflow]
 #define  VIU_OSD_BLEND_REORDER(dest, src)      ((src) << (dest * 4))
                                                ^
drivers/gpu/drm/meson/meson_viu.c:472:18: note: in expansion of macro ?VIU_OSD_BLEND_REORDER?
   writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
                  ^~~~~~~~~~~~~~~~~~~~~

Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Neil Armstrong <narmstrong at baylibre.com>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/gpu/drm/meson/meson_viu.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 259f3e6bec90..bb7e109534de 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -469,17 +469,17 @@ void meson_viu_init(struct meson_drm *priv)
 			priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
 
 	if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) {
-		writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
-			       VIU_OSD_BLEND_REORDER(1, 0) |
-			       VIU_OSD_BLEND_REORDER(2, 0) |
-			       VIU_OSD_BLEND_REORDER(3, 0) |
-			       VIU_OSD_BLEND_DIN_EN(1) |
-			       VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
-			       VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
-			       VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
-			       VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
-			       VIU_OSD_BLEND_HOLD_LINES(4),
-			       priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
+		u32 val = (u32)VIU_OSD_BLEND_REORDER(0, 1) |
+			  (u32)VIU_OSD_BLEND_REORDER(1, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(2, 0) |
+			  (u32)VIU_OSD_BLEND_REORDER(3, 0) |
+			  (u32)VIU_OSD_BLEND_DIN_EN(1) |
+			  (u32)VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
+			  (u32)VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
+			  (u32)VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
+			  (u32)VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
+			  (u32)VIU_OSD_BLEND_HOLD_LINES(4);
+		writel_relaxed(val, priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
 
 		writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
 			       priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 23 22:33:33 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:33 +0530
Subject: [PATCHv9 4/5] lib: Add register read/write tracing support
In-Reply-To: <cover.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <ed2994d6adb306b540ed0ece19ecaf2c2817fd42.1642482334.git.quic_saipraka@quicinc.com>

From: Prasad Sodagudi <psodagud at codeaurora.org>

Generic MMIO read/write i.e., __raw_{read,write}{b,l,w,q} accessors
are typically used to read/write from/to memory mapped registers
and can cause hangs or some undefined behaviour in following few
cases,

* If the access to the register space is unclocked, for example: if
  there is an access to multimedia(MM) block registers without MM
  clocks.

* If the register space is protected and not set to be accessible from
  non-secure world, for example: only EL3 (EL: Exception level) access
  is allowed and any EL2/EL1 access is forbidden.

* If xPU(memory/register protection units) is controlling access to
  certain memory/register space for specific clients.

and more...

Such cases usually results in instant reboot/SErrors/NOC or interconnect
hangs and tracing these register accesses can be very helpful to debug
such issues during initial development stages and also in later stages.

So use ftrace trace events to log such MMIO register accesses which
provides rich feature set such as early enablement of trace events,
filtering capability, dumping ftrace logs on console and many more.

Sample output:

rwmmio_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_post_write: __qcom_geni_serial_console_write+0x160/0x1e0 width=32 val=0xa0d5d addr=0xfffffbfffdbff700
rwmmio_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 addr=0xfffffbfffdbff610
rwmmio_post_read: qcom_geni_serial_poll_bit+0x94/0x138 width=32 val=0x0 addr=0xfffffbfffdbff610

Signed-off-by: Prasad Sodagudi <psodagud at codeaurora.org>
Co-developed-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/Kconfig                  |  3 ++
 arch/arm64/Kconfig            |  1 +
 include/trace/events/rwmmio.h | 97 +++++++++++++++++++++++++++++++++++
 lib/Kconfig                   |  7 +++
 lib/Makefile                  |  2 +
 lib/trace_readwrite.c         | 47 +++++++++++++++++
 6 files changed, 157 insertions(+)
 create mode 100644 include/trace/events/rwmmio.h
 create mode 100644 lib/trace_readwrite.c

diff --git a/arch/Kconfig b/arch/Kconfig
index fdba59052abc..54dd42db882d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1322,6 +1322,9 @@ config ARCH_HAS_ELFCORE_COMPAT
 config ARCH_HAS_PARANOID_L1D_FLUSH
 	bool
 
+config ARCH_HAVE_TRACE_MMIO_ACCESS
+	bool
+
 config DYNAMIC_SIGFRAME
 	bool
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3bb0b67292b5..eaa48df2c3bd 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -46,6 +46,7 @@ config ARM64
 	select ARCH_HAS_ZONE_DMA_SET if EXPERT
 	select ARCH_HAVE_ELF_PROT
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+	select ARCH_HAVE_TRACE_MMIO_ACCESS
 	select ARCH_INLINE_READ_LOCK if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_BH if !PREEMPTION
 	select ARCH_INLINE_READ_LOCK_IRQ if !PREEMPTION
diff --git a/include/trace/events/rwmmio.h b/include/trace/events/rwmmio.h
new file mode 100644
index 000000000000..3c3fefbef87d
--- /dev/null
+++ b/include/trace/events/rwmmio.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM rwmmio
+
+#if !defined(_TRACE_RWMMIO_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RWMMIO_H
+
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(rwmmio_rw_template,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		(void *)(unsigned long)__entry->caller, __entry->width,
+		__entry->val, __entry->addr)
+);
+
+DEFINE_EVENT(rwmmio_rw_template, rwmmio_write,
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+	TP_ARGS(caller, val, width, addr)
+);
+
+DEFINE_EVENT(rwmmio_rw_template, rwmmio_post_write,
+	TP_PROTO(unsigned long caller, u64 val, u8 width, volatile void __iomem *addr),
+	TP_ARGS(caller, val, width, addr)
+);
+
+TRACE_EVENT(rwmmio_read,
+
+	TP_PROTO(unsigned long caller, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width, __entry->addr)
+);
+
+TRACE_EVENT(rwmmio_post_read,
+
+	TP_PROTO(unsigned long caller, u64 val, u8 width, const volatile void __iomem *addr),
+
+	TP_ARGS(caller, val, width, addr),
+
+	TP_STRUCT__entry(
+		__field(u64, caller)
+		__field(u64, val)
+		__field(u64, addr)
+		__field(u8, width)
+	),
+
+	TP_fast_assign(
+		__entry->caller = caller;
+		__entry->val = val;
+		__entry->addr = (unsigned long)(void *)addr;
+		__entry->width = width;
+	),
+
+	TP_printk("%pS width=%d val=%#llx addr=%#llx",
+		 (void *)(unsigned long)__entry->caller, __entry->width,
+		 __entry->val, __entry->addr)
+);
+
+#endif /* _TRACE_RWMMIO_H */
+
+#include <trace/define_trace.h>
diff --git a/lib/Kconfig b/lib/Kconfig
index c80fde816a7e..ea520c315c0f 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -119,6 +119,13 @@ config INDIRECT_IOMEM_FALLBACK
 	  mmio accesses when the IO memory address is not a registered
 	  emulated region.
 
+config TRACE_MMIO_ACCESS
+	bool "Register read/write tracing"
+	depends on TRACING && ARCH_HAVE_TRACE_MMIO_ACCESS
+	help
+	  Create tracepoints for MMIO read/write operations. These trace events
+	  can be used for logging all MMIO read/write operations.
+
 source "lib/crypto/Kconfig"
 
 config CRC_CCITT
diff --git a/lib/Makefile b/lib/Makefile
index 300f569c626b..43813b0061cd 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -152,6 +152,8 @@ lib-y += logic_pio.o
 
 lib-$(CONFIG_INDIRECT_IOMEM) += logic_iomem.o
 
+obj-$(CONFIG_TRACE_MMIO_ACCESS) += trace_readwrite.o
+
 obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o
 
 obj-$(CONFIG_BTREE) += btree.o
diff --git a/lib/trace_readwrite.c b/lib/trace_readwrite.c
new file mode 100644
index 000000000000..88637038b30c
--- /dev/null
+++ b/lib/trace_readwrite.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Register read and write tracepoints
+ *
+ * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <asm-generic/io.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/rwmmio.h>
+
+#ifdef CONFIG_TRACE_MMIO_ACCESS
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr)
+{
+	trace_rwmmio_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_write);
+
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr)
+{
+	trace_rwmmio_post_write(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_write_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_write);
+
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr)
+{
+	trace_rwmmio_read(caller_addr, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_read);
+
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr)
+{
+	trace_rwmmio_post_read(caller_addr, val, width, addr);
+}
+EXPORT_SYMBOL_GPL(log_post_read_mmio);
+EXPORT_TRACEPOINT_SYMBOL_GPL(rwmmio_post_read);
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
-- 
2.33.1



From quic_saipraka at quicinc.com  Sun Jan 23 22:33:34 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Mon, 24 Jan 2022 12:03:34 +0530
Subject: [PATCHv9 5/5] asm-generic/io: Add logging support for MMIO accessors
In-Reply-To: <cover.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <9d7bf0462a140c1425e304c1e709f82e9132253d.1642482334.git.quic_saipraka@quicinc.com>

Add logging support for MMIO high level accessors such as read{b,w,l,q}
and their relaxed versions to aid in debugging unexpected crashes/hangs
caused by the corresponding MMIO operation. Also add a generic flag
(__DISABLE_TRACE_MMIO__) which is used to disable MMIO tracing in nVHE KVM
and if required can be used to disable MMIO tracing for specific drivers.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/kvm/hyp/nvhe/Makefile |  7 ++-
 include/asm-generic/io.h         | 82 ++++++++++++++++++++++++++++++--
 2 files changed, 84 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile
index 24b2c2425b38..228d1f8921c3 100644
--- a/arch/arm64/kvm/hyp/nvhe/Makefile
+++ b/arch/arm64/kvm/hyp/nvhe/Makefile
@@ -4,7 +4,12 @@
 #
 
 asflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
-ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS
+
+# Tracepoint and MMIO logging symbols should not be visible at nVHE KVM as
+# there is no way to execute them and any such MMIO access from nVHE KVM
+# will explode instantly (Words of Marc Zyngier). So introduce a generic flag
+# __DISABLE_TRACE_MMIO__ to disable MMIO tracing for nVHE KVM.
+ccflags-y := -D__KVM_NVHE_HYPERVISOR__ -D__DISABLE_EXPORTS -D__DISABLE_TRACE_MMIO__
 
 hostprogs := gen-hyprel
 HOST_EXTRACFLAGS += -I$(objtree)/include
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 7ce93aaf69f8..c9b428657760 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -10,6 +10,7 @@
 #include <asm/page.h> /* I/O is all done through memory accesses */
 #include <linux/string.h> /* for memset() and memcpy() */
 #include <linux/types.h>
+#include <linux/instruction_pointer.h>
 
 #ifdef CONFIG_GENERIC_IOMAP
 #include <asm-generic/iomap.h>
@@ -61,6 +62,35 @@
 #define __io_par(v)     __io_ar(v)
 #endif
 
+#if IS_ENABLED(CONFIG_TRACE_MMIO_ACCESS) && !(defined(__DISABLE_TRACE_MMIO__))
+#include <linux/tracepoint-defs.h>
+
+DECLARE_TRACEPOINT(rwmmio_write);
+DECLARE_TRACEPOINT(rwmmio_post_write);
+DECLARE_TRACEPOINT(rwmmio_read);
+DECLARE_TRACEPOINT(rwmmio_post_read);
+
+void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+		    unsigned long caller_addr);
+void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+			 unsigned long caller_addr);
+void log_read_mmio(u8 width, const volatile void __iomem *addr,
+		   unsigned long caller_addr);
+void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+			unsigned long caller_addr);
+
+#else
+
+static inline void log_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				  unsigned long caller_addr) {}
+static inline void log_post_write_mmio(u64 val, u8 width, volatile void __iomem *addr,
+				       unsigned long caller_addr) {}
+static inline void log_read_mmio(u8 width, const volatile void __iomem *addr,
+				 unsigned long caller_addr) {}
+static inline void log_post_read_mmio(u64 val, u8 width, const volatile void __iomem *addr,
+				      unsigned long caller_addr) {}
+
+#endif /* CONFIG_TRACE_MMIO_ACCESS */
 
 /*
  * __raw_{read,write}{b,w,l,q}() access memory in native endianness.
@@ -149,9 +179,11 @@ static inline u8 readb(const volatile void __iomem *addr)
 {
 	u8 val;
 
+	log_read_mmio(8, addr, _THIS_IP_);
 	__io_br();
 	val = __raw_readb(addr);
 	__io_ar(val);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -162,9 +194,11 @@ static inline u16 readw(const volatile void __iomem *addr)
 {
 	u16 val;
 
+	log_read_mmio(16, addr, _THIS_IP_);
 	__io_br();
 	val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -175,9 +209,11 @@ static inline u32 readl(const volatile void __iomem *addr)
 {
 	u32 val;
 
+	log_read_mmio(32, addr, _THIS_IP_);
 	__io_br();
 	val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -189,9 +225,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 {
 	u64 val;
 
+	log_read_mmio(64, addr, _THIS_IP_);
 	__io_br();
 	val = __le64_to_cpu(__raw_readq(addr));
 	__io_ar(val);
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
 	return val;
 }
 #endif
@@ -201,9 +239,11 @@ static inline u64 readq(const volatile void __iomem *addr)
 #define writeb writeb
 static inline void writeb(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeb(value, addr);
 	__io_aw();
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -211,9 +251,11 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
 #define writew writew
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writew((u16 __force)cpu_to_le16(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -221,9 +263,11 @@ static inline void writew(u16 value, volatile void __iomem *addr)
 #define writel writel
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writel((u32 __force)__cpu_to_le32(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -232,9 +276,11 @@ static inline void writel(u32 value, volatile void __iomem *addr)
 #define writeq writeq
 static inline void writeq(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__io_bw();
 	__raw_writeq(__cpu_to_le64(value), addr);
 	__io_aw();
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 #endif /* CONFIG_64BIT */
@@ -248,7 +294,12 @@ static inline void writeq(u64 value, volatile void __iomem *addr)
 #define readb_relaxed readb_relaxed
 static inline u8 readb_relaxed(const volatile void __iomem *addr)
 {
-	return __raw_readb(addr);
+	u8 val;
+
+	log_read_mmio(8, addr, _THIS_IP_);
+	val = __raw_readb(addr);
+	log_post_read_mmio(val, 8, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -256,7 +307,12 @@ static inline u8 readb_relaxed(const volatile void __iomem *addr)
 #define readw_relaxed readw_relaxed
 static inline u16 readw_relaxed(const volatile void __iomem *addr)
 {
-	return __le16_to_cpu(__raw_readw(addr));
+	u16 val;
+
+	log_read_mmio(16, addr, _THIS_IP_);
+	val = __le16_to_cpu(__raw_readw(addr));
+	log_post_read_mmio(val, 16, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -264,7 +320,12 @@ static inline u16 readw_relaxed(const volatile void __iomem *addr)
 #define readl_relaxed readl_relaxed
 static inline u32 readl_relaxed(const volatile void __iomem *addr)
 {
-	return __le32_to_cpu(__raw_readl(addr));
+	u32 val;
+
+	log_read_mmio(32, addr, _THIS_IP_);
+	val = __le32_to_cpu(__raw_readl(addr));
+	log_post_read_mmio(val, 32, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -272,7 +333,12 @@ static inline u32 readl_relaxed(const volatile void __iomem *addr)
 #define readq_relaxed readq_relaxed
 static inline u64 readq_relaxed(const volatile void __iomem *addr)
 {
-	return __le64_to_cpu(__raw_readq(addr));
+	u64 val;
+
+	log_read_mmio(64, addr, _THIS_IP_);
+	val =__le64_to_cpu(__raw_readq(addr));
+	log_post_read_mmio(val, 64, addr, _THIS_IP_);
+	return val;
 }
 #endif
 
@@ -280,7 +346,9 @@ static inline u64 readq_relaxed(const volatile void __iomem *addr)
 #define writeb_relaxed writeb_relaxed
 static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 8, addr, _THIS_IP_);
 	__raw_writeb(value, addr);
+	log_post_write_mmio(value, 8, addr, _THIS_IP_);
 }
 #endif
 
@@ -288,7 +356,9 @@ static inline void writeb_relaxed(u8 value, volatile void __iomem *addr)
 #define writew_relaxed writew_relaxed
 static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 16, addr, _THIS_IP_);
 	__raw_writew(cpu_to_le16(value), addr);
+	log_post_write_mmio(value, 16, addr, _THIS_IP_);
 }
 #endif
 
@@ -296,7 +366,9 @@ static inline void writew_relaxed(u16 value, volatile void __iomem *addr)
 #define writel_relaxed writel_relaxed
 static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 32, addr, _THIS_IP_);
 	__raw_writel(__cpu_to_le32(value), addr);
+	log_post_write_mmio(value, 32, addr, _THIS_IP_);
 }
 #endif
 
@@ -304,7 +376,9 @@ static inline void writel_relaxed(u32 value, volatile void __iomem *addr)
 #define writeq_relaxed writeq_relaxed
 static inline void writeq_relaxed(u64 value, volatile void __iomem *addr)
 {
+	log_write_mmio(value, 64, addr, _THIS_IP_);
 	__raw_writeq(__cpu_to_le64(value), addr);
+	log_post_write_mmio(value, 64, addr, _THIS_IP_);
 }
 #endif
 
-- 
2.33.1



From qizhong.cheng at mediatek.com  Sun Jan 23 22:27:13 2022
From: qizhong.cheng at mediatek.com (qizhong.cheng)
Date: Mon, 24 Jan 2022 14:27:13 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <CAGXv+5EcAXFTnjkbeU4f3J2s4Ue5zxrN4QgS=t54BnLX8Gkw2w@mail.gmail.com>
References: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
 <CAGXv+5EcAXFTnjkbeU4f3J2s4Ue5zxrN4QgS=t54BnLX8Gkw2w@mail.gmail.com>
Message-ID: <bddf917f241a6628d43ddd95b577024c9ddf9931.camel@mediatek.com>

Hi chenYu,

On Mon, 2022-01-24 at 11:12 +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Sun, Jan 23, 2022 at 11:34 AM qizhong cheng
> <qizhong.cheng at mediatek.com> wrote:
> > 
> > As an edge-triggered interrupts, its interrupt status should be
> > cleared
> > before dispatch to the handler of device.
> 
> I'm curious, is this just a code correction or are there real world
> cases where something fails?

Yes, we found a failure when used iperf tool for wifi and network cards
performance testing. The function of "while" has just been executed,
and the EP sent an MSI before executing "Clear MSI interrupt status".
After executing "Clear MSI interrupt status", this edge-triggered
interrupt status is cleared, but EP is still waiting for interrupt
handler.

> 
> Also, please add a Fixes tag and maybe Cc stable so this gets
> backported
> automatically.

Thanks for your review, I will fix it in the next version.

> 
> ChenYu
> 
> > Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
> > ---
> >  drivers/pci/controller/pcie-mediatek.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/pcie-mediatek.c
> > b/drivers/pci/controller/pcie-mediatek.c
> > index 2f3f974977a3..705ea33758b1 100644
> > --- a/drivers/pci/controller/pcie-mediatek.c
> > +++ b/drivers/pci/controller/pcie-mediatek.c
> > @@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct
> > irq_desc *desc)
> >                 if (status & MSI_STATUS){
> >                         unsigned long imsi_status;
> > 
> > +                       /* Clear MSI interrupt status */
> > +                       writel(MSI_STATUS, port->base +
> > PCIE_INT_STATUS);
> >                         while ((imsi_status = readl(port->base +
> > PCIE_IMSI_STATUS))) {
> >                                 for_each_set_bit(bit, &imsi_status,
> > MTK_MSI_IRQS_NUM)
> >                                         generic_handle_domain_irq(p
> > ort->inner_domain, bit);
> >                         }
> > -                       /* Clear MSI interrupt status */
> > -                       writel(MSI_STATUS, port->base +
> > PCIE_INT_STATUS);
> >                 }
> >         }
> > 
> > --
> > 2.25.1
> > 
> > 
> > _______________________________________________
> > Linux-mediatek mailing list
> > Linux-mediatek at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-mediatek

From roger.lu at mediatek.com  Sun Jan 23 22:39:34 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 24 Jan 2022 14:39:34 +0800
Subject: [PATCH v21 3/8] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <63d8884d-d02d-53f9-8524-4a074ca5bfea@collabora.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-4-roger.lu@mediatek.com>
 <63d8884d-d02d-53f9-8524-4a074ca5bfea@collabora.com>
Message-ID: <dc84332f190a8be7d5b004fc4d2a2c1341f9a357.camel@mediatek.com>

Hi AngeloGioacchino,

Sorry for the late reply and thanks for the advice.

On Fri, 2022-01-07 at 15:33 +0100, AngeloGioacchino Del Regno wrote:
> Il 07/01/22 10:51, Roger Lu ha scritto:
> > The Smart Voltage Scaling(SVS) engine is a piece of hardware
> > which calculates suitable SVS bank voltages to OPP voltage table.
> > Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
> > when receiving OPP_EVENT_ADJUST_VOLTAGE.
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > ---
> >   drivers/soc/mediatek/Kconfig   |   10 +
> >   drivers/soc/mediatek/Makefile  |    1 +
> >   drivers/soc/mediatek/mtk-svs.c | 1446 ++++++++++++++++++++++++++++++++
> >   3 files changed, 1457 insertions(+)
> >   create mode 100644 drivers/soc/mediatek/mtk-svs.c

[snip]

> > +
> > +struct svs_platform_data {
> > +	char *name;
> > +	struct svs_bank *banks;
> > +	bool (*efuse_parsing)(struct svs_platform *svsp);
> > +	unsigned long irqflags;
> > +	const u32 *regs;
> > +	u32 bank_max;
> > +	int (*probe)(struct svs_platform *svsp);
> > +};
> > +
> 
> Please move the definition of struct svs_platform_data at the beginning of
> the file for increased readability.

Okay. I'll move them at the beginning of the file in the next patch.

> 
> With that done,
> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>



From wenst at chromium.org  Sun Jan 23 22:55:58 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Mon, 24 Jan 2022 14:55:58 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <bddf917f241a6628d43ddd95b577024c9ddf9931.camel@mediatek.com>
References: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
 <CAGXv+5EcAXFTnjkbeU4f3J2s4Ue5zxrN4QgS=t54BnLX8Gkw2w@mail.gmail.com>
 <bddf917f241a6628d43ddd95b577024c9ddf9931.camel@mediatek.com>
Message-ID: <CAGXv+5GUW6qcxwnfj3dsn7Lb1yY5bNv+v+PQ2VN1NX9yPmGd2A@mail.gmail.com>

On Mon, Jan 24, 2022 at 2:27 PM qizhong.cheng
<qizhong.cheng at mediatek.com> wrote:
>
> Hi chenYu,
>
> On Mon, 2022-01-24 at 11:12 +0800, Chen-Yu Tsai wrote:
> > Hi,
> >
> > On Sun, Jan 23, 2022 at 11:34 AM qizhong cheng
> > <qizhong.cheng at mediatek.com> wrote:
> > >
> > > As an edge-triggered interrupts, its interrupt status should be
> > > cleared
> > > before dispatch to the handler of device.
> >
> > I'm curious, is this just a code correction or are there real world
> > cases where something fails?
>
> Yes, we found a failure when used iperf tool for wifi and network cards
> performance testing. The function of "while" has just been executed,
> and the EP sent an MSI before executing "Clear MSI interrupt status".
> After executing "Clear MSI interrupt status", this edge-triggered
> interrupt status is cleared, but EP is still waiting for interrupt
> handler.

Can you also include this in the commit log?  It would be nice to record
the exact scenario that this fix targets.

ChenYu

> >
> > Also, please add a Fixes tag and maybe Cc stable so this gets
> > backported
> > automatically.
>
> Thanks for your review, I will fix it in the next version.
>
> >
> > ChenYu
> >
> > > Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
> > > ---
> > >  drivers/pci/controller/pcie-mediatek.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mediatek.c
> > > b/drivers/pci/controller/pcie-mediatek.c
> > > index 2f3f974977a3..705ea33758b1 100644
> > > --- a/drivers/pci/controller/pcie-mediatek.c
> > > +++ b/drivers/pci/controller/pcie-mediatek.c
> > > @@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct
> > > irq_desc *desc)
> > >                 if (status & MSI_STATUS){
> > >                         unsigned long imsi_status;
> > >
> > > +                       /* Clear MSI interrupt status */
> > > +                       writel(MSI_STATUS, port->base +
> > > PCIE_INT_STATUS);
> > >                         while ((imsi_status = readl(port->base +
> > > PCIE_IMSI_STATUS))) {
> > >                                 for_each_set_bit(bit, &imsi_status,
> > > MTK_MSI_IRQS_NUM)
> > >                                         generic_handle_domain_irq(p
> > > ort->inner_domain, bit);
> > >                         }
> > > -                       /* Clear MSI interrupt status */
> > > -                       writel(MSI_STATUS, port->base +
> > > PCIE_INT_STATUS);
> > >                 }
> > >         }
> > >
> > > --
> > > 2.25.1
> > >
> > >
> > > _______________________________________________
> > > Linux-mediatek mailing list
> > > Linux-mediatek at lists.infradead.org
> > > http://lists.infradead.org/mailman/listinfo/linux-mediatek
>


From ck.hu at mediatek.com  Sun Jan 23 23:18:20 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 24 Jan 2022 15:18:20 +0800
Subject: [PATCH v11 21/22] drm/mediatek: add mediatek-drm of vdosys1
 support for MT8195
In-Reply-To: <20220110084645.31191-22-nancy.lin@mediatek.com>
References: <20220110084645.31191-1-nancy.lin@mediatek.com>
 <20220110084645.31191-22-nancy.lin@mediatek.com>
Message-ID: <94cf3379aa648d7366143e2f84bf4e21ad3576c1.camel@mediatek.com>

Hi, Nancy:

On Mon, 2022-01-10 at 16:46 +0800, Nancy.Lin wrote:
> Add driver data of mt8195 vdosys1 to mediatek-drm.
> 
> Signed-off-by: Nancy.Lin <nancy.lin at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 36430f956b4f..e851c56f00b1 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -190,6 +190,14 @@ static const enum mtk_ddp_comp_id
> mt8195_mtk_ddp_main[] = {
>  	DDP_COMPONENT_DP_INTF0,
>  };
>  
> +static const enum mtk_ddp_comp_id mt8195_mtk_ddp_ext[] = {
> +	DDP_COMPONENT_OVL_ADAPTOR,
> +	DDP_COMPONENT_MERGE5,
> +	DDP_COMPONENT_DP_INTF1,
> +};
> +
> +static const int mt8195_vdosys1_mtk_cmdq_mbox[] = {-1, 0, -1};

What does this array mean? These number looks so magic.

Regards,
CK

> +
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data =
> {
>  	.main_path = mt2701_mtk_ddp_main,
>  	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
> @@ -254,6 +262,14 @@ static const struct mtk_mmsys_driver_data
> mt8195_vdosys0_driver_data = {
>  	.mmsys_dev_num = 2,
>  };
>  
> +static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data
> = {
> +	.ext_path = mt8195_mtk_ddp_ext,
> +	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
> +	.mmsys_id = 1,
> +	.mmsys_dev_num = 2,
> +	.mbox_index = mt8195_vdosys1_mtk_cmdq_mbox,
> +};
> +
>  static const struct of_device_id mtk_drm_of_ids[] = {
>  	{ .compatible = "mediatek,mt2701-mmsys",
>  	  .data = &mt2701_mmsys_driver_data},
> @@ -271,6 +287,8 @@ static const struct of_device_id mtk_drm_of_ids[]
> = {
>  	  .data = &mt8192_mmsys_driver_data},
>  	{ .compatible = "mediatek,mt8195-vdosys0",
>  	  .data = &mt8195_vdosys0_driver_data},
> +	{ .compatible = "mediatek,mt8195-vdosys1",
> +	  .data = &mt8195_vdosys1_driver_data},
>  	{ }
>  };
>  MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);



From roger.lu at mediatek.com  Sun Jan 23 23:28:27 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 24 Jan 2022 15:28:27 +0800
Subject: [PATCH v21 4/8] soc: mediatek: SVS: add monitor mode
In-Reply-To: <e118df40-da6b-88f6-fbff-15befb3405d5@collabora.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-5-roger.lu@mediatek.com>
 <e118df40-da6b-88f6-fbff-15befb3405d5@collabora.com>
Message-ID: <f4fbfc91d2f0abf041f058f191e2b239ac173a1e.camel@mediatek.com>

Hi AngeloGioacchino,

Sorry for the late reply and thanks for the advice.

On Fri, 2022-01-07 at 15:34 +0100, AngeloGioacchino Del Regno wrote:
> Il 07/01/22 10:51, Roger Lu ha scritto:
> > SVS monitor mode is based on different thermal temperature
> > to provide suitable SVS bank voltages.
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > ---
> >   drivers/soc/mediatek/mtk-svs.c | 253 ++++++++++++++++++++++++++++++++-
> >   1 file changed, 247 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> > index fc7e2ee44a92..042c6e8e9069 100644
> > --- a/drivers/soc/mediatek/mtk-svs.c
> > +++ b/drivers/soc/mediatek/mtk-svs.c
> > @@ -25,6 +25,7 @@
> >   #include <linux/regulator/consumer.h>
> >   #include <linux/slab.h>
> >   #include <linux/spinlock.h>
> > +#include <linux/thermal.h>
> >   
> >   /* svs bank 1-line sw id */
> >   #define SVSB_CPU_LITTLE			BIT(0)
> > @@ -36,6 +37,7 @@
> >   #define SVSB_MODE_ALL_DISABLE		0
> >   #define SVSB_MODE_INIT01		BIT(1)
> >   #define SVSB_MODE_INIT02		BIT(2)
> > +#define SVSB_MODE_MON			BIT(3)

[snip]

> >   /**
> > @@ -241,6 +254,7 @@ struct svs_platform {
> >    * @get_volts: function pointer to get bank voltages
> >    * @name: bank name
> >    * @buck_name: regulator name
> > + * @tzone_name: thermal zone name
> >    * @suspended: suspend flag of this bank
> >    * @phase: bank current phase
> >    * @volt_od: bank voltage overdrive
> > @@ -270,6 +284,13 @@ struct svs_platform {
> >    * @sw_id: bank software identification
> >    * @cpu_id: cpu core id for SVS CPU bank use only
> >    * @ctl0: TS-x selection
> > + * @temp: bank temperature
> > + * @tzone_htemp: thermal zone high temperature threshold
> > + * @tzone_htemp_voffset: thermal zone high temperature voltage offset
> > + * @tzone_ltemp: thermal zone low temperature threshold
> > + * @tzone_ltemp_voffset: thermal zone low temperature voltage offset
> > + * @bts: svs efuse data
> > + * @mts: svs efuse data
> >    * @bdes: svs efuse data
> >    * @mdes: svs efuse data
> >    * @mtdes: svs efuse data
> > @@ -292,6 +313,7 @@ struct svs_bank {
> >   	void (*get_volts)(struct svs_platform *svsp);
> >   	char *name;
> >   	char *buck_name;
> > +	char *tzone_name;
> >   	bool suspended;
> >   	enum svsb_phase phase;
> >   	s32 volt_od;
> > @@ -321,6 +343,13 @@ struct svs_bank {
> >   	u32 sw_id;
> >   	u32 cpu_id;
> >   	u32 ctl0;
> > +	u32 temp;
> > +	u32 tzone_htemp;
> > +	u32 tzone_htemp_voffset;
> > +	u32 tzone_ltemp;
> > +	u32 tzone_ltemp_voffset;
> > +	u32 bts;
> > +	u32 mts;
> >   	u32 bdes;
> >   	u32 mdes;
> >   	u32 mtdes;
> > @@ -361,10 +390,21 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt,
> > u32 svsb_volt_step,
> >   	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
> >   }
> >   
> 
> I'm sorry for the double review, but this went unnoticed in the previous one.
> 
> > +static int svs_get_zone_temperature(const char *tzone_name, int
> > *tzone_temp)
> > +{
> > +	struct thermal_zone_device *tzd;
> > +
> > +	tzd = thermal_zone_get_zone_by_name(tzone_name);
> 
> This call is expensive, as it's iterating through the (possibly) entire
> thermal_tz_list (drivers/thermal/thermal_core.c) so, for performance purposes,
> noting that you're using this in svs_adjust_pm_opp_volts(), it's not a good
> idea
> to call it at every ISR.
> 
> I would instead propose to get a pointer to the thermal_zone at driver probe
> time and cache that in struct svs_bank: this function would also be removed
> as the only thing that you'd need to do then would be just one call...
> 
> [read forward...]

No problem. I'll cache thermal_zone at driver probe time and remove this API in
the next patch. Thanks.

> 
> > +	if (IS_ERR(tzd))
> > +		return PTR_ERR(tzd);
> > +
> > +	return thermal_zone_get_temp(tzd, tzone_temp);
> > +}
> > +
> >   static int svs_adjust_pm_opp_volts(struct svs_bank *svsb, bool
> > force_update)
> >   {
> > -	int ret = -EPERM;
> > -	u32 i, svsb_volt, opp_volt;
> > +	int ret = -EPERM, tzone_temp = 0;
> > +	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
> >   
> >   	mutex_lock(&svsb->lock);
> >   
> > @@ -378,6 +418,22 @@ static int svs_adjust_pm_opp_volts(struct svs_bank
> > *svsb, bool force_update)
> >   		goto unlock_mutex;
> >   	}
> >   
> > +	/* Get thermal effect */
> > +	if (svsb->phase == SVSB_PHASE_MON) {
> > +		ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
> 
> ... so you can simply call ...
> 
> 
> 	ret = thermal_zone_get_temp(svsb->tzd, tzone_temp);
> 
> 
> ...without any need for any helper.

Sure, I'll call thermal_zone_get_temp() directly after applying this recommended
change in the next patch. Thanks.

> 
> > +		if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
> > +			    svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
> > +			dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n",
> > +				svsb->tzone_name, ret, svsb->temp);
> > +			svsb->phase = SVSB_PHASE_ERROR;
> > +		}
> > +
> > +		if (tzone_temp >= svsb->tzone_htemp)
> > +			temp_voffset += svsb->tzone_htemp_voffset;
> > +		else if (tzone_temp <= svsb->tzone_ltemp)
> > +			temp_voffset += svsb->tzone_ltemp_voffset;
> > +	}
> > +
> >   	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
> >   	for (i = 0; i < svsb->opp_count; i++) {
> >   		switch (svsb->phase) {
> 
> Apart from that, the commit looks good. Looking forward to review the new
> version!
> 
> Regards,
> - Angelo



From krzysztof.kozlowski at canonical.com  Sun Jan 23 23:49:53 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 08:49:53 +0100
Subject: [PATCH v5 3/4] mfd: dt-bindings: google,cros-ec: reference
 Samsung SPI bindings
In-Reply-To: <YenkV2rgEXQJ6Bc5@robh.at.kernel.org>
References: <20220120175747.43403-1-krzysztof.kozlowski@canonical.com>
 <20220120175747.43403-4-krzysztof.kozlowski@canonical.com>
 <YenkV2rgEXQJ6Bc5@robh.at.kernel.org>
Message-ID: <f04f128f-af7b-93df-0452-4c0e915f2eb7@canonical.com>

On 20/01/2022 23:38, Rob Herring wrote:
> On Thu, Jan 20, 2022 at 06:57:46PM +0100, Krzysztof Kozlowski wrote:
>> The ChromeOS Embedded Controller appears on boards with Samsung Exynos
>> SoC, where Exynos SPI bindings expect controller-data node.  Reference
>> newly added dtschema for this property.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/mfd/google,cros-ec.yaml          | 29 ++++++++++---------
>>  1 file changed, 16 insertions(+), 13 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
>> index 58a1a9405228..66a995bbbbe9 100644
>> --- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
>> +++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
>> @@ -31,7 +31,7 @@ properties:
>>  
>>    controller-data:
>>      description:
>> -      SPI controller data, see bindings/spi/spi-samsung.txt
>> +      SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
>>      type: object
> 
> We should be able to drop all of this if unevaluatedProperties is used.
> 
>>  
>>    google,cros-ec-spi-pre-delay:
>> @@ -148,18 +148,21 @@ patternProperties:
>>  required:
>>    - compatible
>>  
>> -if:
>> -  properties:
>> -    compatible:
>> -      contains:
>> -        enum:
>> -          - google,cros-ec-i2c
>> -          - google,cros-ec-rpmsg
>> -then:
>> -  properties:
>> -    google,cros-ec-spi-pre-delay: false
>> -    google,cros-ec-spi-msg-delay: false
>> -    spi-max-frequency: false
>> +allOf:
>> +  - if:
>> +      properties:
>> +        compatible:
>> +          contains:
>> +            enum:
>> +              - google,cros-ec-i2c
>> +              - google,cros-ec-rpmsg
>> +    then:
>> +      properties:
>> +        google,cros-ec-spi-pre-delay: false
>> +        google,cros-ec-spi-msg-delay: false
>> +        spi-max-frequency: false
>> +
>> +  - $ref: /schemas/spi/samsung,spi-peripheral-props.yaml
> 
> SPI device schemas should reference spi-peripheral-props.yaml only. 
> spi-peripheral-props.yaml in turn should reference all the vendor 
> specific peripheral property schemas.
> 
> You should be able to do just:
> 
> else:
>   $ref: /schemas/spi/spi-peripheral-props.yaml

I tried now with your changes (no controller-data and else-ref), but
dt_binding_check complains:

linux/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml:
'additionalProperties' is a required property

	hint: A schema without a "$ref" to another schema must define all
properties and use "additionalProperties"

	from schema $id: http://devicetree.org/meta-schemas/base.yaml#


Which makes sense because only one part - SPI devices - get the ref to
spi-perpheral-props.

Best regards,
Krzysztof


From Bob_King at wistron.com  Mon Jan 24 00:07:11 2022
From: Bob_King at wistron.com (Bob King)
Date: Mon, 24 Jan 2022 16:07:11 +0800
Subject: [PATCH] ARM: dts: aspeed: Adding Wistron Lannister BMC
Message-ID: <20220124080711.22797-1-Bob_King@wistron.com>

Initial introduction of Wistron Lannister equipped with
Aspeed 2600 BMC SoC.

Signed-off-by: Bob King <Bob_King at wistron.com>
---
 arch/arm/boot/dts/Makefile                         |    3 +-
 arch/arm/boot/dts/aspeed-bmc-wistron-lannister.dts | 1007 ++++++++++++++++++++
 2 files changed, 1009 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/aspeed-bmc-wistron-lannister.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 235ad55..7d37aab 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -1548,4 +1548,5 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
 	aspeed-bmc-tyan-s8036.dtb \
 	aspeed-bmc-vegman-n110.dtb \
 	aspeed-bmc-vegman-rx20.dtb \
-	aspeed-bmc-vegman-sx20.dtb
+	aspeed-bmc-vegman-sx20.dtb \
+	aspeed-bmc-wistron-lannister.dtb
diff --git a/arch/arm/boot/dts/aspeed-bmc-wistron-lannister.dts b/arch/arm/boot/dts/aspeed-bmc-wistron-lannister.dts
new file mode 100644
index 0000000..e8e4f9d
--- /dev/null
+++ b/arch/arm/boot/dts/aspeed-bmc-wistron-lannister.dts
@@ -0,0 +1,1007 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+
+#include "aspeed-g6.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/i2c/i2c.h>
+
+/ {
+	model = "Lannister BMC";
+	compatible = "aspeed,ast2600";
+
+	chosen {
+		stdout-path = &uart5;
+		bootargs = "console=ttyS4,115200n8 root=/dev/ram rw init=/linuxrc";
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x40000000>;
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gfx_memory: framebuffer {
+			size = <0x01000000>;
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+
+		video_engine_memory: jpegbuffer {
+			size = <0x02000000>;	/* 32M */
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			reusable;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		video_memory: video {
+			size = <0x04000000>;
+			alignment = <0x01000000>;
+			compatible = "shared-dma-pool";
+			no-map;
+		};
+	};
+
+	leds {
+		compatible = "gpio-leds";
+
+		identify {
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(B, 7) GPIO_ACTIVE_LOW>;
+		};
+
+		status_amber {
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(G, 3) GPIO_ACTIVE_LOW>;
+		};
+
+		status_green {
+			default-state = "keep";
+			gpios = <&gpio0 ASPEED_GPIO(G, 2) GPIO_ACTIVE_LOW>;
+		};
+
+		bmc-heart-beat {
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(P, 7) GPIO_ACTIVE_LOW>;
+		};
+
+		power-ok {
+			default-state = "keep";
+			gpios = <&gpio0 ASPEED_GPIO(R, 6) GPIO_ACTIVE_LOW>;
+		};
+
+		global-error {
+			default-state = "off";
+			gpios = <&gpio0 ASPEED_GPIO(R, 7) GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err1 {
+			default-state = "off";
+			gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err2 {
+			default-state = "off";
+			gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err3 {
+			default-state = "off";
+			gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err4 {
+			default-state = "off";
+			gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err5 {
+			default-state = "off";
+			gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err6 {
+			default-state = "off";
+			gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err7 {
+			default-state = "off";
+			gpios = <&gpio2 6 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err8 {
+			default-state = "off";
+			gpios = <&gpio2 7 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err9 {
+			default-state = "off";
+			gpios = <&gpio2 8 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err10 {
+			default-state = "off";
+			gpios = <&gpio2 9 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err11 {
+			default-state = "off";
+			gpios = <&gpio2 10 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err12 {
+			default-state = "off";
+			gpios = <&gpio2 11 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err13 {
+			default-state = "off";
+			gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err14 {
+			default-state = "off";
+			gpios = <&gpio2 13 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err15 {
+			default-state = "off";
+			gpios = <&gpio2 14 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err16 {
+			default-state = "off";
+			gpios = <&gpio2 15 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err17 {
+			default-state = "off";
+			gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err18 {
+			default-state = "off";
+			gpios = <&gpio3 1 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err19 {
+			default-state = "off";
+			gpios = <&gpio3 2 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err20 {
+			default-state = "off";
+			gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err21 {
+			default-state = "off";
+			gpios = <&gpio3 4 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err22 {
+			default-state = "off";
+			gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err23 {
+			default-state = "off";
+			gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err24 {
+			default-state = "off";
+			gpios = <&gpio3 7 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err25 {
+			default-state = "off";
+			gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err26 {
+			default-state = "off";
+			gpios = <&gpio3 9 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err27 {
+			default-state = "off";
+			gpios = <&gpio3 10 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err28 {
+			default-state = "off";
+			gpios = <&gpio3 11 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err29 {
+			default-state = "off";
+			gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err30 {
+			default-state = "off";
+			gpios = <&gpio3 13 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err31 {
+			default-state = "off";
+			gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
+		};
+
+		dimm-err32 {
+			default-state = "off";
+			gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
+		};
+
+		fan1-fault {
+			default-state = "off";
+			gpios = <&gpio4 1 GPIO_ACTIVE_LOW>;
+		};
+
+		fan2-fault {
+			default-state = "off";
+			gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
+		};
+
+		fan3-fault {
+			default-state = "off";
+			gpios = <&gpio4 3 GPIO_ACTIVE_LOW>;
+		};
+
+		fan4-fault {
+			default-state = "off";
+			gpios = <&gpio4 4 GPIO_ACTIVE_LOW>;
+		};
+
+		fan5-fault {
+			default-state = "off";
+			gpios = <&gpio4 5 GPIO_ACTIVE_LOW>;
+		};
+
+		fan6-fault {
+			default-state = "off";
+			gpios = <&gpio4 6 GPIO_ACTIVE_LOW>;
+		};
+
+		cpu1 {
+			default-state = "off";
+			gpios = <&gpio4 8 GPIO_ACTIVE_LOW>;
+		};
+
+		cpu2 {
+			default-state = "off";
+			gpios = <&gpio4 9 GPIO_ACTIVE_LOW>;
+		};
+
+		riser1-s1 {
+			default-state = "off";
+			gpios = <&gpio5 0 GPIO_ACTIVE_LOW>;
+		};
+
+		riser1-s2 {
+			default-state = "off";
+			gpios = <&gpio5 1 GPIO_ACTIVE_LOW>;
+		};
+
+		riser1-s3 {
+			default-state = "off";
+			gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+		};
+
+		riser2-s1 {
+			default-state = "off";
+			gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+		};
+
+		riser2-s2 {
+			default-state = "off";
+			gpios = <&gpio5 4 GPIO_ACTIVE_LOW>;
+		};
+
+		riser2-s3 {
+			default-state = "off";
+			gpios = <&gpio5 5 GPIO_ACTIVE_LOW>;
+		};
+
+		riser3-s1 {
+			default-state = "off";
+			gpios = <&gpio5 6 GPIO_ACTIVE_LOW>;
+		};
+
+		riser3-s2 {
+			default-state = "off";
+			gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
+		};
+
+		m2-1 {
+			default-state = "off";
+			gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
+		};
+
+		m2-2 {
+			default-state = "off";
+			gpios = <&gpio5 9 GPIO_ACTIVE_LOW>;
+		};
+
+		bat {
+			default-state = "off";
+			gpios = <&gpio5 15 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	gpio-keys-polled {
+		compatible = "gpio-keys-polled";
+		poll-interval = <1000>;
+
+		fan0-presence {
+			/* GPIO18C2 */
+			label = "fan0-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 2) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 2)>;
+		};
+
+		fan1-presence {
+			/* GPIO18C3 */
+			label = "fan1-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 3) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 3)>;
+		};
+
+		fan2-presence {
+			/* GPIO18C7 */
+			label = "fan2-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 7)>;
+		};
+
+		fan3-presence {
+			/* GPIO18C6 */
+			label = "fan3-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 6) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 6)>;
+		};
+
+		fan4-presence {
+			/* GPIO18C5 */
+			label = "fan4-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 5) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 5)>;
+		};
+
+		fan5-presence {
+			/* GPIO18C4 */
+			label = "fan5-presence";
+			gpios = <&gpio1 ASPEED_GPIO(C, 4) GPIO_ACTIVE_LOW>;
+			linux,code = <ASPEED_GPIO(C, 4)>;
+		};
+	};
+};
+
+&fmc {
+	status = "okay";
+	flash at 0 {
+		status = "okay";
+		spi-max-frequency = <50000000>;
+		spi-tx-bus-width = <4>;
+		m25p,fast-read;
+#include "openbmc-flash-layout-64.dtsi"
+	};
+};
+&syscon {
+	uart-clock-high-speed;
+	status = "okay";
+
+	misc_control {
+		compatible = "aspeed,bmc-misc";
+		chip_id {
+			offset = <0x5b0>;
+			bit-mask = <0xffffffff 0xffffffff>;
+			bit-shift = <0>;
+			read-only;
+			reg-width = <64>;
+			hash-data = "d44f9b804976fa23c2e25d62f16154d26520a7e24c5555095fd1b55c027804f1570dcd16189739c640cd7d9a6ce14944a2c4eaf1dc429eed6940e8a83498a474";
+		};
+	};
+};
+
+#if 0
+ GPIO Alias: (runtime alias -> schematic name)
+	ID_BUTTON -> FP_ID_BTN_N
+	CPU_CATERR -> FM_PLT_BMC_THERMTRIP_N
+	PCH_BMC_THERMTRIP -> FM_PLT_BMC_THERMTRIP_N
+	RESET_BUTTON -> FP_BMC_RST_BTN_N
+	RESET_OUT -> RST_BMC_RSTBTN_OUT_R_N
+	POWER_BUTTON -> FP_BMC_PWR_BTN_R_N
+	POWER_OUT -> FM_BMC_PWR_BTN_N
+	PREQ_N -> DBP_ASD_BMC_PREQ_R_N
+	POST_COMPLETE -> FM_BIOS_POST_CMPLT_BMC_N
+	CPU_ERR0 -> FM_CPU_ERR0_LVT3_N
+	CPU_ERR1 -> FM_CPU_ERR1_LVT3_N
+	CPU_ERR2 -> FM_CPU_ERR2_LVT3_N
+	DEBUG_EN_N -> FM_JTAG_TCK_MUX_SEL_R
+	NMI_OUT -> IRQ_BMC_CPU_NMI_R
+	PLTRST_N -> RST_PLTRST_BMC_N
+	PRDY_N -> DBP_ASD_BMC_PRDY_R_N
+	PWR_DEBUG_N ->
+	XDP_PRST_N ->
+	SYSPWROK ->
+	RSMRST_N ->
+	SIO_S3 -> FM_SLPS3_R_N
+	SIO_S5 -> FM_SLPS4_R_N
+	SIO_ONCONTROL -> FM_BMC_ONCTL_R_N
+	SIO_POWER_GOOD -> PWRGD_CPU0_LVC3_R
+	PS_PWROK -> PWRGD_BMC_PS_PWROK_R
+	P3VBAT_BRIDGE_EN ->
+	TCK_MUX_SEL ->
+	SMI -> IRQ_SMI_ACTIVE_BMC_N
+	NMI_BUTTON -> FP_NMI_BTN_N
+#endif
+
+&gpio0 {
+	status = "okay";
+	/* pinctrl-names = "pass-through";
+	pinctrl-0 = <&pinctrl_thru0_default
+			&pinctrl_thru1_default>; */
+	gpio-line-names =
+	/*A0-A7*/	"SMB_BMC0_MUX01_CLK_H","SMB_BMC0_MUX01_DAT_H","RST_BTN_IRMC_N","BTN_PWR_BMC_N","SMB_CPU_PIROM_SCL","SMB_CPU_PIROM_SDA","I2C_BMC_SCL14","I2C_BMC_SDA14",
+	/*B0-B7*/	"FM_SEL_BMC_USB_HOST_N","NMI_OUT","IRQ_SMB3_M2_ALERT_N","SMB_BMC_2_PMBUS_ALERT_N","RST_BMC_PCIE_MUX_N","FM_BMC_EUP_LOT6_N","FM_BMC_BMCINIT_R","FP_ID_LED_N",
+	/*C0-C7*/	"FM_FORCE_BMC_UPDATE_N","RST_RGMII_PHYRST_N","FM_TPM_EN_PULSE","FM_BMC_CRASHLOG_TRIG_N","IRQ_BMC_PCH_NMI_R","FM_CPU1_DISABLE_COD_N","SMB_BMCLC1_CLK_R_H","SMB_BMCLC1_DAT_R_H",
+	/*D0-D7*/	"CPU_ERR0","CPU_ERR1","CPU_ERR2","PRDY_N","FM_SPD_SWITCH_CTRL_N","FM_RISER3_BMC_ID_0","FAN_PRSNT_LC2","FAN_PRSNT_LC1",
+	/*E0-E7*/	"FM_RISER2_RBP_ID_R_0","LED_CSS_R_N","CLK_50M_CKMNG_BMCB","FM_BMC_BOARD_REV_ID2_N","FM_RISER2_ID_0","FM_RISER2_ID_1","SMB_BMCLC2_DAT_R_H","SMB_BMCLC2_CLK_R_H",
+	/*F0-F7*/	"FM_BMC_BOARD_SKU_ID0_N","FM_BMC_BOARD_SKU_ID1_N","FM_BMC_BOARD_SKU_ID2_N","FM_BMC_BOARD_SKU_ID3_N","FM_BMC_BOARD_SKU_ID4_N ","FM_BMC_BOARD_SKU_ID5_N","PRSNT_MONITOR_FP_L","PS_PWROK",
+	/*G0-G7*/	"FM_SMB_BMC_NVME_LVC3_ALERT_N","RST_BMC_I2C_M2_R_N","FP_LED_STATUS_GREEN_N","FP_LED_STATUS_AMBER_N","FM_BMC_BOARD_REV_ID0_N","FM_BMC_BOARD_REV_ID1_N","FM_BMC_CPU_FBRK_OUT_R_N","DBP_PRESENT_IN_R2_N",
+	/*H0-H7*/	"SGPIO_BMC_CLK_R","SGPIO_BMC_LD_R_N","SGPIO_BMC_DOUT_R","SGPIO_BMC_DIN","PLTRST_N","CPU_CATERR","SMB_TEMPSENSOR_STBY_LVC3_R_SCL","SMB_TEMPSENSOR_STBY_LVC3_R_SDA",
+	/*I0-I7*/	"JTAG_ASD_NTRST_R_N","JTAG_ASD_TDI_R","JTAG_ASD_TCK_R","JTAG_ASD_TMS_R","JTAG_ASD_TDO","FM_BMC_PWRBTN_OUT_R_N","","TP_FM_BMC_PCH_SCI_LPC_R_N",
+	/*J0-J7*/	"I2C_BMC_RISER1_SCL1","I2C_BMC_RISER1_SDA1","I2C_BMC_PSU_SCL2","I2C_BMC_PSU_SDA2","I2C_BMC_PWR_SCL3","I2C_BMC_PWR_SDA3","I2C_BMC_SCL4","I2C_BMC_SDA4",
+	/*K0-K7*/	"SMB_HSBP_STBY_LVC3_R_SCL","SMB_HSBP_STBY_LVC3_R_SDA","SMB_SMLINK0_STBY_LVC3_R2_SCL","SMB_SMLINK0_STBY_LVC3_R2_SDA","I2C_BMC_RISER2_SCL7","I2C_BMC_RISER2_SDA7","SMB_PMBUS_SML1_STBY_LVC3_R_SCL","SMB_PMBUS_SML1_STBY_LVC3_R_SDA",
+	/*L0-L7*/	"SMB_PCIE_STBY_LVC3_R_SCL","SMB_PCIE_STBY_LVC3_R_SDA","SMB_HOST_STBY_BMC_LVC3_R_SCL","SMB_HOST_STBY_BMC_LVC3_R_SDA","PREQ_N","TCK_MUX_SEL","V_BMC_GFX_HSYNC_R","V_BMC_GFX_VSYNC_R",
+	/*M0-M7*/	"SPA_CTS_N ","SPA_DCD_N","SPA_DSR_N","PU_SPA_RI_N","SPA_DTR_N","SPA_RTS_N","SPA_SOUT","SPA_SIN",
+	/*N0-N7*/	"SPB_CTS_N","SPB_DCD_N","SPB_DSR_N","PU_SPB_RI_N","SPB_DTR_N","SPB_RTS_N","SPB_SOUT","SPB_SIN",
+	/*O0-O7*/	"FAN_PWM_BMC_1_H","FAN_PWM_BMC_2_H","FAN_PWM_BMC_3_H","FAN_PWM_BMC_4_H","FAN_PWM_BMC_5_H","FAN_PWM_BMC_6_H","NMI_BUTTON","FM_RECOVER_BIOS_R_N",
+	/*P0-P7*/	"RESET_BUTTON","RESET_OUT","POWER_BUTTON","POWER_OUT","FM_RISER3_BMC_ID_1","FM_RISER2_BMC_ID_2","RST_BMC_I2C_R_8","LED_BMC_HEARTBEAT_R_N",
+	/*Q0-Q7*/	"FAN_TACH_BMC_0_N_BUF","FAN_TACH_BMC_1_N_BUF","FAN_TACH_BMC_2_N_BUF","FAN_TACH_BMC_3_N_BUF","FAN_TACH_BMC_4_N_BUF","FAN_TACH_BMC_5_N_BUF","FAN_TACH_BMC_6_N_BUF","FAN_TACH_BMC_7_N_BUF",
+	/*R0-R7*/	"FAN_TACH_BMC_8_N_BUF","FAN_TACH_BMC_9_N_BUF","FAN_TACH_BMC_10_N_BUF","FAN_TACH_BMC_11_N_BUF","FAN_TACH_BMC_LC1_N_BUF","FAN_TACH_BMC_LC2_N_BUF","LED_PWROK_BMC_N","LED_GERR_IRMC_N",
+	/*S0-S7*/	"RGMII_BMC_RMM4_LVC3_R_MDC","RGMII_BMC_RMM4_LVC3_R_MDIO","ID_BUTTON","PCH_BMC_THERMTRIP","TP_LED_BMC_HEARTBEAT_N","A_P3V_BAT_SCALED_EN","FM_ASD_EN_DET_R","FM_PCHHOT_N",
+	/*T0-T7*/	"","","","","","","","",
+	/*U0-U7*/	"","","","","","","","",
+	/*V0-V7*/	"SIO_S3","SIO_S5","TP_BMC_SIO_PWREQ_N","SIO_ONCONTROL","SIO_POWER_GOOD","LED_BMC_HB_LED_N","FM_BMC_SUSACK_N","TP_IRQ_BMC_PCH_SMI_LPC_N_R",
+	/*W0-W7*/	"LPC_LAD0_ESPI_R_IO0","LPC_LAD1_ESPI_R_IO1","LPC_LAD2_ESPI_R_IO2","LPC_LAD3_ESPI_R_IO3","CLK_24M_66M_LPC0_ESPI_BMC","LFRAME_N_ESPI_CS0_BMC_N","IRQ_LPC_SERIRQ_ESPI_ALERT_N","RST_LPC_LRST_ESPI_RST_BMC_R_N",
+	/*X0-X7*/	"ERR_FAT_VRM_N","SMI","POST_COMPLETE","FM_CLR_LDL_H","PU_SPB_FORCEOFF_N","PU_SPA_FORCEOFF_N","FM_RISER1_RBP_ID_0","FM_OCP1_PRSNTB3_N",
+	/*Y0-Y7*/	"FM_M2_PRSTN_BMC_N","IRQ_SML0_ALERT_BMC_R2_N","I2C_BUS8_INT_N","IRQ_SML1_PMBUS_BMC_ALERT_N","SPI_BMC_BOOT_R_IO2","SPI_BMC_BOOT_R_IO3","PU_SPI_BMC_BOOT_ABR","PU_SPI_BMC_BOOT_WP_N",
+	/*Z0-Z7*/	"PWRGD_P3V3_RISER1","PWRGD_P3V3_RISER2","PRSNT_USB3_FP_X_L","PU_GPIOZ3","PU_GPIOZ4","PU_GPIOZ5","PU_GPIOZ6","PU_GPIOZ7";
+};
+
+&gpio1 {
+	status = "disabled";
+	gpio-line-names = /* GPIO18 A-E */
+	/*A0-A7*/	"RGMII_BMC_RMM4_TX_R_CLK","RGMII_BMC_RMM4_TX_R_CTRL","RGMII_BMC_RMM4_R_TXD0","RGMII_BMC_RMM4_R_TXD1","RGMII_BMC_RMM4_R_TXD2","RGMII_BMC_RMM4_R_TXD3","RGMII_BMC_RMM4_RX_CLK","RGMII_BMC_RMM4_RX_CTRL",
+	/*B0-B7*/	"RGMII_BMC_RMM4_RXD0","RGMII_BMC_RMM4_RXD1","RGMII_BMC_RMM4_RXD2","RGMII_BMC_RMM4_RXD3","FAN_PWM_BMC_LC2_H","FAN_PWM_BMC_LC1_H ","RST_EMMC_BMC_R_N","FM_RISER1_BMC_ID_2",
+	/*C0-C7*/	"FM_RISER1_BMC_ID_1","FM_RISER1_BMC_ID_0","FAN_PRSNT1_N","FAN_PRSNT2_N","FAN_PRSNT6_N","FAN_PRSNT5_N","FAN_PRSNT4_N","FAN_PRSNT3_N",
+	/*D0-D7*/	"EMMC_BMC_R_CLK","EMMC_BMC_R_CMD","EMMC_BMC_R_DATA0","EMMC_BMC_R_DATA1","EMMC_BMC_R_DATA2","EMMC_BMC_R_DATA3","EMMC_BMC_CD_N","EMMC_BMC_WP_N",
+	/*E0-E3*/	"EMMC_BMC_R_DATA4","EMMC_BMC_R_DATA5","EMMC_BMC_R_DATA6","EMMC_BMC_R_DATA7";
+};
+
+&sgpiom0 {
+	status = "okay";
+};
+
+&kcs3 {
+	kcs_addr = <0xCA2>;
+	status = "okay";
+};
+
+&kcs4 {
+	kcs_addr = <0xCA4>;
+	status = "okay";
+};
+
+&lpc_snoop {
+	snoop-ports = <0x80>;
+	status = "okay";
+};
+
+&mdio0 {
+	status = "okay";
+
+	ethphy1: ethernet-phy at 0 {
+		compatible = "ethernet-phy-ieee802.3-c22";
+		reg = <0>;
+	};
+};
+
+&mac0 {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_rgmii1_default>;
+	clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
+		 <&syscon ASPEED_CLK_MAC1RCLK>;
+	clock-names = "MACCLK", "RCLK";
+	phy-mode = "rgmii";
+	phy-handle = <&ethphy1>;
+};
+
+&adc0 {
+	status = "okay";
+};
+
+&adc1 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+	pinctrl-0 = <&pinctrl_txd1_default
+			 &pinctrl_rxd1_default
+			 &pinctrl_nrts1_default
+			 &pinctrl_ndtr1_default
+			 &pinctrl_ndsr1_default
+			 &pinctrl_ncts1_default
+			 &pinctrl_ndcd1_default
+			 &pinctrl_nri1_default>;
+};
+
+&uart2 {
+	status = "okay";
+	pinctrl-0 = <&pinctrl_txd2_default
+			 &pinctrl_rxd2_default
+			 &pinctrl_nrts2_default
+			 &pinctrl_ndtr2_default
+			 &pinctrl_ndsr2_default
+			 &pinctrl_ncts2_default
+			 &pinctrl_ndcd2_default
+			 &pinctrl_nri2_default>;
+};
+
+&uart3 {
+	status = "okay";
+	pinctrl-0 = <>;
+};
+
+&uart4 {
+	status = "okay";
+	pinctrl-0 = <>;
+};
+
+&uart5 {
+	status = "okay";
+};
+
+&uart_routing {
+	status = "okay";
+};
+
+&i2c0 {
+	/* I2C_BMC_RISER1 */
+	multi-master;
+	status = "okay";
+
+	pca9545 at 70 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};
+};
+
+&i2c1 {
+	/* I2C_BMC_PSU */
+	multi-master;
+	status = "okay";
+
+	psu1-eeprom at 50 {
+		compatible = "atmel,24c02";
+		reg = <0x50>;
+	};
+
+	psu2-eeprom at 51 {
+		compatible = "atmel,24c02";
+		reg = <0x51>;
+	};
+
+	pmbus at 58 {
+		compatible = "pmbus,sgd009";
+		reg = <0x58>;
+	};
+
+	pmbus at 59 {
+		compatible = "pmbus,sgd009";
+		reg = <0x59>;
+	};
+};
+
+&i2c2 {
+	/* I2C_BMC_PWR */
+	multi-master;
+	status = "okay";
+};
+
+&i2c3 {
+	multi-master;
+	status = "okay";
+
+	gpio2: pca9539 at 74{
+		compatible = "nxp,pca9539";
+		reg = <0x74>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio at 0 {
+			reg = <0>;
+		};
+
+		gpio at 1 {
+			reg = <1>;
+		};
+
+		gpio at 2 {
+			reg = <2>;
+		};
+
+		gpio at 3 {
+			reg = <3>;
+		};
+
+		gpio at 4 {
+			reg = <4>;
+		};
+
+		gpio at 5 {
+			reg = <5>;
+		};
+
+		gpio at 6 {
+			reg = <6>;
+		};
+
+		gpio at 7 {
+			reg = <7>;
+		};
+
+		gpio at 8 {
+			reg = <8>;
+		};
+
+		gpio at 9 {
+			reg = <9>;
+		};
+
+		gpio at 10 {
+			reg = <10>;
+		};
+
+		gpio at 11 {
+			reg = <11>;
+		};
+
+		gpio at 12 {
+			reg = <12>;
+		};
+
+		gpio at 13 {
+			reg = <13>;
+		};
+
+		gpio at 14 {
+			reg = <14>;
+		};
+
+		gpio at 15 {
+			reg = <15>;
+		};
+	};
+
+	gpio3: pca9539 at 75{
+		compatible = "nxp,pca9539";
+		reg = <0x75>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio at 0 {
+			reg = <0>;
+		};
+
+		gpio at 1 {
+			reg = <1>;
+		};
+
+		gpio at 2 {
+			reg = <2>;
+		};
+
+		gpio at 3 {
+			reg = <3>;
+		};
+
+		gpio at 4 {
+			reg = <4>;
+		};
+
+		gpio at 5 {
+			reg = <5>;
+		};
+
+		gpio at 6 {
+			reg = <6>;
+		};
+
+		gpio at 7 {
+			reg = <7>;
+		};
+
+		gpio at 8 {
+			reg = <8>;
+		};
+
+		gpio at 9 {
+			reg = <9>;
+		};
+
+		gpio at 10 {
+			reg = <10>;
+		};
+
+		gpio at 11 {
+			reg = <11>;
+		};
+
+		gpio at 12 {
+			reg = <12>;
+		};
+
+		gpio at 13 {
+			reg = <13>;
+		};
+
+		gpio at 14 {
+			reg = <14>;
+		};
+
+		gpio at 15 {
+			reg = <15>;
+		};
+	};
+
+	gpio4: pca9539 at 76{
+		compatible = "nxp,pca9539";
+		reg = <0x76>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio at 0 {
+			reg = <0>;
+		};
+
+		gpio at 1 {
+			reg = <1>;
+		};
+
+		gpio at 2 {
+			reg = <2>;
+		};
+
+		gpio at 3 {
+			reg = <3>;
+		};
+
+		gpio at 4 {
+			reg = <4>;
+		};
+
+		gpio at 5 {
+			reg = <5>;
+		};
+
+		gpio at 6 {
+			reg = <6>;
+		};
+
+		gpio at 7 {
+			reg = <7>;
+		};
+
+		gpio at 8 {
+			reg = <8>;
+		};
+
+		gpio at 9 {
+			reg = <9>;
+		};
+
+		gpio at 10 {
+			reg = <10>;
+		};
+
+		gpio at 11 {
+			reg = <11>;
+		};
+
+		gpio at 12 {
+			reg = <12>;
+		};
+
+		gpio at 13 {
+			reg = <13>;
+		};
+
+		gpio at 14 {
+			reg = <14>;
+		};
+
+		gpio at 15 {
+			reg = <15>;
+		};
+	};
+
+	gpio5: pca9539 at 77{
+		compatible = "nxp,pca9539";
+		reg = <0x77>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		gpio at 0 {
+			reg = <0>;
+		};
+
+		gpio at 1 {
+			reg = <1>;
+		};
+
+		gpio at 2 {
+			reg = <2>;
+		};
+
+		gpio at 3 {
+			reg = <3>;
+		};
+
+		gpio at 4 {
+			reg = <4>;
+		};
+
+		gpio at 5 {
+			reg = <5>;
+		};
+
+		gpio at 6 {
+			reg = <6>;
+		};
+
+		gpio at 7 {
+			reg = <7>;
+		};
+
+		gpio at 8 {
+			reg = <8>;
+		};
+
+		gpio at 9 {
+			reg = <9>;
+		};
+
+		gpio at 10 {
+			reg = <10>;
+		};
+
+		gpio at 11 {
+			reg = <11>;
+		};
+
+		gpio at 12 {
+			reg = <12>;
+		};
+
+		gpio at 13 {
+			reg = <13>;
+		};
+
+		gpio at 14 {
+			reg = <14>;
+		};
+
+		gpio at 15 {
+			reg = <15>;
+		};
+	};
+};
+
+&i2c4 {
+	/* SMB_HSBP_STBY_LVC3_R */
+	multi-master;
+	status = "okay";
+};
+
+&i2c5 {
+	/* SMB_SMLINK0_STBY_LVC3_R2 */
+	bus-frequency = <1000000>;
+	multi-master;
+	status = "okay";
+};
+
+&i2c6 {
+	/* I2C_BMC_RISER2 */
+	multi-master;
+	status = "okay";
+
+	pca9543 at 70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x70>;
+	};
+
+	pca9545 at 72 {
+		compatible = "nxp,pca9545";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x72>;
+	};
+};
+
+&i2c7 {
+	/* SMB_PMBUS_SML1_STBY_LVC3_R */
+	multi-master;
+	status = "okay";
+};
+
+&i2c8 {
+	/* SMB_PCIE_STBY_LVC3_R */
+	multi-master;
+	status = "okay";
+};
+
+&i2c9 {
+	/* SMB_HOST_STBY_BMC_LVC3_R */
+	multi-master;
+	status = "okay";
+};
+
+&i2c10 {
+	/* SMB_BMC0_MUX01 */
+	multi-master;
+	status = "okay";
+};
+
+&i2c12 {
+	/* SMB_CPU_PIROM */
+	multi-master;
+	status = "okay";
+};
+
+&i2c13 {
+	multi-master;
+	status = "okay";
+};
+
+&i2c15 {
+	/* SMB_TEMPSENSOR_STBY_LVC3_R */
+	multi-master;
+	status = "okay";
+
+	tmp75 at 48 {
+		compatible = "ti,tmp75";
+		reg = <0x48>;
+	};
+};
+
+&vhub {
+	status = "okay";
+};
-- 
2.7.4


---------------------------------------------------------------------------------------------------------------------------------------------------------------
This email contains confidential or legally privileged information and is for the sole use of its intended recipient. 
Any unauthorized review, use, copying or distribution of this email or the content of this email is strictly prohibited.
If you are not the intended recipient, you may reply to the sender and should delete this e-mail immediately.
---------------------------------------------------------------------------------------------------------------------------------------------------------------



From ck.hu at mediatek.com  Mon Jan 24 00:16:08 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 24 Jan 2022 16:16:08 +0800
Subject: [PATCH v14 08/12] soc: mediatek: add mtk-mmsys support for
 mt8195 vdosys0
In-Reply-To: <20220107101425.6917-9-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-9-jason-jh.lin@mediatek.com>
Message-ID: <38d41c11d27658a874b0c0c8dbc103482b1b9037.camel@mediatek.com>

Hi, Jason:

On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> Add mt8195 vdosys0 clock driver name and routing table to
> the driver data of mtk-mmsys.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
> The vdosys1 impelmentation patch [1] will be dependened on this
> patch.
> [1] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
> - 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20211208024426.15595-6-nancy.lin at mediatek.com/
> ---
>  drivers/soc/mediatek/mt8195-mmsys.h    | 220
> +++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       |  11 ++
>  include/linux/soc/mediatek/mtk-mmsys.h |   9 +
>  3 files changed, 240 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> 
> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> b/drivers/soc/mediatek/mt8195-mmsys.h
> new file mode 100644
> index 000000000000..e04cabdfa2dc
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> @@ -0,0 +1,220 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> +
> +#define MT8195_VDO0_OVL_MOUT_EN					
> 0xf14
> +/*
> + * MT8195_VDO0_OVL_MOUT[2:0]: DISP_OVL0
> + *   BIT(0) : DISP_RDMA0
> + *   BIT(1) : DISP_WDMA0
> + *   BIT(2): DISP_OVL1
> + */
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> +/*
> + * MT8195_VDO0_OVL_MOUT[6:4]: DISP_OVL1
> + *   BIT(0) : DISP_RDMA1
> + *   BIT(1) : DISP_WDMA1
> + *   BIT(2): DISP_OVL0
> + */
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
> +#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
> +
> +#define MT8195_VDO0_SEL_IN					0xf34
> +/*
> + * MT8195_VDO0_SEL_IN[1:0]: VPP_MERGE
> + *   0 : DSC_WRAP0_OUT
> + *   1 : DISP_DITHER1
> + *   2: VDO1_VIRTUAL0
> + */
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		0
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		BIT(0)
> +#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		BIT(1)
> +/*
> + * MT8195_VDO0_SEL_IN[4:4]: DSC_WRAP0_IN
> + *   0: DISP_DITHER0
> + *   1: VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		0
> +#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		BIT(4)
> +/*
> + * MT8195_VDO0_SEL_IN[5:5]: DSC_WRAP1_IN
> + *   0: DISP_DITHER1
> + *   1: VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		0
> +#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		BIT(5)
> +/*
> + * MT8195_VDO0_SEL_IN[8:8]: SINA_VIRTUAL0
> + *   0: VPP_MERGE
> + *   1: DSC_WRAP1_OUT
> + */
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		0
> +#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		
> BIT(8)
> +/*
> + * MT8195_VDO0_SEL_IN[9:9]: SINB_VIRTUAL0
> + *   0: DSC_WRAP0_OUT
> + */
> +#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		
> 0
> +/*
> + * MT8195_VDO0_SEL_IN[13:12]: DP_INTF0
> + *   0 : DSC_WRAP1_OUT
> + *   1 : VPP_MERGE
> + *   2: VDO1_VIRTUAL0
> + */
> +#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		0
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			
> BIT(12)
> +#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		BIT(13)
> +/*
> + * MT8195_VDO0_SEL_IN[16:16]: DSI0
> + *   0 : DSC_WRAP0_OUT
> + *   1 : DISP_DITHER0
> + */
> +#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			
> 0
> +#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			BIT(16)
> +/*
> + * MT8195_VDO0_SEL_IN[17:17]: DSI1
> + *   0 : DSC_WRAP1_OUT
> + *   1 : VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			
> 0
> +#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			BIT(17)
> +/*
> + * MT8195_VDO0_SEL_IN[20:20]: DISP_WDMA1
> + *   0 : DISP_OVL1
> + *   1 : VPP_MERGE
> + */
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			
> 0
> +#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			
> BIT(20)
> +/*
> + * MT8195_VDO0_SEL_IN[21:21]: DSC_WRAP1_OUT
> + *   0 : DSC_WRAP1_IN
> + *   1 : DITHER1
> + */
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		
> (0)
> +#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		
> BIT(21)
> +/*
> + * MT8195_VDO0_SEL_IN[22:22]: DISP_WDMA0
> + *   0 : DISP_OVL0
> + */
> +#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			
> 0
> +
> +#define MT8195_VDO0_SEL_OUT					0xf38
> +/*
> + * MT8195_VDO0_SOUT[0:0]: DISP_DITHER0
> + *   0 : DSC_WRAP0_IN
> + *   1 : DSI0
> + */
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		0
> +#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			BIT(0)
> +/*
> + * MT8195_VDO0_SOUT[1:1]: DISP_DITHER1
> + *   0 : DSC_WRAP1_IN
> + *   1 : VPP_MERGE
> + *   2 : DSC_WRAP1_OUT
> + */
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		0
> +#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			
> BIT(1)
> +#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		BIT(2)
> +/*
> + * MT8195_VDO0_SOUT[4:4]: VDO1_VIRTUAL0
> + *   0 : VPP_MERGE
> + *   1 : DP_INTF0
> + */
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			
> 0
> +#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			
> BIT(4)
> +/*
> + * MT8195_VDO0_SOUT[10:8]: VPP_MERGE
> + *   0 : DSI1
> + *   1 : DP_INTF0
> + *   2 : SINA_VIRTUAL0
> + *   3 : DISP_WDMA1
> + *   4 : DSC_WRAP0_IN
> + */
> +#define MT8195_SOUT_VPP_MERGE_TO_DSI1				
> 0
> +#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			BIT(8)
> +#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			
> BIT(9)
> +#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(BIT(9)
> | BIT(8))
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			
> BIT(10)
> +/*
> + * MT8195_VDO0_SOUT[11:11]: VPP_MERGE
> + *  0 : DSC_WRAP1_IN
> + */
> +#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			
> 0
> +/*
> + * MT8195_VDO0_SOUT[13:12]: DSC_WRAP0_OUT
> + *  0 : DSI0
> + *  1 : SINB_VIRTUAL0
> + *  2 : VPP_MERGE
> + */
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			0
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		BIT(12)
> +#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			
> BIT(13)
> +/*
> + * MT8195_VDO0_SOUT[17:16]: DSC_WRAP1_OUT
> + *  0 : DSI1
> + *  1 : DP_INTF0
> + *  2 : SINA_VIRTUAL0
> + *  3 : VPP_MERGE
> + */
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			0
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			
> BIT(16)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		BIT(17)
> +#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			
> (BIT(17) | BIT(16))
> +
> +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] =
> {
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
> +		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> +	}, {
> +		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
> +		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,

Why this mask MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT is 0?

> +		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,

Why this mask MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE is 0?

> +		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,

Why this mask MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0 is 0?

Regards,
CK

> +		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
> +		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
> +		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
> +		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
> +	}
> +};
> +
> +#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c
> b/drivers/soc/mediatek/mtk-mmsys.c
> index 5f79c7e039ad..5865d268c5b4 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -18,6 +18,7 @@
>  #include "mt8167-mmsys.h"
>  #include "mt8183-mmsys.h"
>  #include "mt8192-mmsys.h"
> +#include "mt8195-mmsys.h"
>  #include "mt8365-mmsys.h"
>  
>  static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data =
> {
> @@ -66,6 +67,12 @@ static const struct mtk_mmsys_driver_data
> mt8192_mmsys_driver_data = {
>  	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
>  };
>  
> +static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data
> = {
> +	.clk_driver = "clk-mt8195-vdo0",
> +	.routes = mmsys_mt8195_routing_table,
> +	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
> +};
> +
>  static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data =
> {
>  	.clk_driver = "clk-mt8365-mm",
>  	.routes = mt8365_mmsys_routing_table,
> @@ -391,6 +398,10 @@ static const struct of_device_id
> of_match_mtk_mmsys[] = {
>  		.compatible = "mediatek,mt8192-mmsys",
>  		.data = &mt8192_mmsys_driver_data,
>  	},
> +	{
> +		.compatible = "mediatek,mt8195-vdosys0",
> +		.data = &mt8195_vdosys0_driver_data,
> +	},
>  	{
>  		.compatible = "mediatek,mt8365-mmsys",
>  		.data = &mt8365_mmsys_driver_data,
> diff --git a/include/linux/soc/mediatek/mtk-mmsys.h
> b/include/linux/soc/mediatek/mtk-mmsys.h
> index 45e77d1cd6c1..c0ba22ad7229 100644
> --- a/include/linux/soc/mediatek/mtk-mmsys.h
> +++ b/include/linux/soc/mediatek/mtk-mmsys.h
> @@ -23,13 +23,22 @@ enum mtk_ddp_comp_id {
>  	DDP_COMPONENT_COLOR0,
>  	DDP_COMPONENT_COLOR1,
>  	DDP_COMPONENT_DITHER,
> +	DDP_COMPONENT_DP_INTF0,
>  	DDP_COMPONENT_DPI0,
>  	DDP_COMPONENT_DPI1,
> +	DDP_COMPONENT_DSC0,
> +	DDP_COMPONENT_DSC1,
>  	DDP_COMPONENT_DSI0,
>  	DDP_COMPONENT_DSI1,
>  	DDP_COMPONENT_DSI2,
>  	DDP_COMPONENT_DSI3,
>  	DDP_COMPONENT_GAMMA,
> +	DDP_COMPONENT_MERGE0,
> +	DDP_COMPONENT_MERGE1,
> +	DDP_COMPONENT_MERGE2,
> +	DDP_COMPONENT_MERGE3,
> +	DDP_COMPONENT_MERGE4,
> +	DDP_COMPONENT_MERGE5,
>  	DDP_COMPONENT_OD0,
>  	DDP_COMPONENT_OD1,
>  	DDP_COMPONENT_OVL0,



From mhiramat at kernel.org  Mon Jan 24 00:17:54 2022
From: mhiramat at kernel.org (Masami Hiramatsu)
Date: Mon, 24 Jan 2022 17:17:54 +0900
Subject: [PATCH] arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
Message-ID: <164301227374.1433152.12808232644267107415.stgit@devnote2>

Mark the start_backtrace() as notrace and NOKPROBE_SYMBOL
because this function is called from ftrace and lockdep to
get the caller address via return_address(). The lockdep
is used in kprobes, it should also be NOKPROBE_SYMBOL.

Fixes: b07f3499661c ("arm64: stacktrace: Move start_backtrace() out of the header")
Cc: stable at vger.kernel.org
Signed-off-by: Masami Hiramatsu <mhiramat at kernel.org>
---
 arch/arm64/kernel/stacktrace.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index 94f83cd44e50..b0f21677764d 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -33,7 +33,7 @@
  */
 
 
-void start_backtrace(struct stackframe *frame, unsigned long fp,
+void notrace start_backtrace(struct stackframe *frame, unsigned long fp,
 		     unsigned long pc)
 {
 	frame->fp = fp;
@@ -55,6 +55,7 @@ void start_backtrace(struct stackframe *frame, unsigned long fp,
 	frame->prev_fp = 0;
 	frame->prev_type = STACK_TYPE_UNKNOWN;
 }
+NOKPROBE_SYMBOL(start_backtrace);
 
 /*
  * Unwind from one frame record (A) to the next frame record (B).



From krzysztof.kozlowski at canonical.com  Mon Jan 24 00:23:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 09:23:43 +0100
Subject: [PATCH v6 0/4] spi: dt-bindings: samsung: convert to dtschema
Message-ID: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>

Hi,

Changes since v5
================
1. Add new patch 3 (fix indentation in example).
2. Patch 2: reference spi-peripheral-props in else.
3. Add tags.

Changes since v4
================
1. Do not require samsung,spi-feedback-delay and fold patch 3 into patch 2.
2. Rework message in patch 4.
3. Add tags.

Changes since v3
================
1. Patch 2: correct path in exynos-usi.yaml.
2. Add patch 5.
3. Add tags.

Changes since v2
================
1. Patch 2: drop child device schema, as Rob suggested.

Changes since v1
================
1. Patch 2: describe devices matching compatible, correct issues pointed out by
   Rob, add reviewed-by tag.
2. New patches 3 and 4.

Best regards,
Krzysztof

Krzysztof Kozlowski (4):
  spi: dt-bindings: samsung: convert to dtschema
  mfd: dt-bindings: google,cros-ec: reference Samsung SPI bindings
  mfd: dt-bindings: google,cros-ec: fix indentation in example
  spi: s3c64xx: allow controller-data to be optional

 .../bindings/mfd/google,cros-ec.yaml          |  31 +--
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  33 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 drivers/spi/spi-s3c64xx.c                     |  14 +-
 8 files changed, 246 insertions(+), 146 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Mon Jan 24 00:23:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 09:23:45 +0100
Subject: [PATCH v6 2/4] mfd: dt-bindings: google,
 cros-ec: reference Samsung SPI bindings
In-Reply-To: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
References: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220124082347.32747-3-krzysztof.kozlowski@canonical.com>

The ChromeOS Embedded Controller appears on boards with Samsung Exynos
SoC, where Exynos SPI bindings expect controller-data node.  Reference
SPI peripheral bindings which include now Samsung SPI peripheral parts.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/mfd/google,cros-ec.yaml          | 29 ++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index d1f53bd449f7..525ab18005b3 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -31,7 +31,7 @@ properties:
 
   controller-data:
     description:
-      SPI controller data, see bindings/spi/spi-samsung.txt
+      SPI controller data, see bindings/spi/samsung,spi-peripheral-props.yaml
     type: object
 
   google,cros-ec-spi-pre-delay:
@@ -148,18 +148,21 @@ patternProperties:
 required:
   - compatible
 
-if:
-  properties:
-    compatible:
-      contains:
-        enum:
-          - google,cros-ec-i2c
-          - google,cros-ec-rpmsg
-then:
-  properties:
-    google,cros-ec-spi-pre-delay: false
-    google,cros-ec-spi-msg-delay: false
-    spi-max-frequency: false
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - google,cros-ec-i2c
+              - google,cros-ec-rpmsg
+    then:
+      properties:
+        google,cros-ec-spi-pre-delay: false
+        google,cros-ec-spi-msg-delay: false
+        spi-max-frequency: false
+    else:
+      $ref: /schemas/spi/spi-peripheral-props.yaml
 
 additionalProperties: false
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Mon Jan 24 00:23:46 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 09:23:46 +0100
Subject: [PATCH v6 3/4] mfd: dt-bindings: google,
 cros-ec: fix indentation in example
In-Reply-To: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
References: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220124082347.32747-4-krzysztof.kozlowski@canonical.com>

Correct level of indentation in the example.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 Documentation/devicetree/bindings/mfd/google,cros-ec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
index 525ab18005b3..4caadf73fc4a 100644
--- a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
+++ b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
@@ -203,7 +203,7 @@ examples:
             spi-max-frequency = <5000000>;
 
             proximity {
-                    compatible = "google,cros-ec-mkbp-proximity";
+                compatible = "google,cros-ec-mkbp-proximity";
             };
 
             cbas {
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Mon Jan 24 00:23:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 09:23:44 +0100
Subject: [PATCH v6 1/4] spi: dt-bindings: samsung: convert to dtschema
In-Reply-To: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
References: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220124082347.32747-2-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC (S3C24xx, S3C64xx, S5Pv210, Exynos) SPI
controller bindings to DT schema format.

The conversion also drops requirement from providing controller-data and
its data for each of SPI peripheral device nodes.  The dtschema cannot
express this and the requirement is being relaxed in the driver now.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Acked-by: Pratyush Yadav <p.yadav at ti.com>
---
 .../bindings/soc/samsung/exynos-usi.yaml      |   2 +-
 .../spi/samsung,spi-peripheral-props.yaml     |  33 ++++
 .../devicetree/bindings/spi/samsung,spi.yaml  | 187 ++++++++++++++++++
 .../bindings/spi/spi-peripheral-props.yaml    |   1 +
 .../devicetree/bindings/spi/spi-samsung.txt   | 122 ------------
 MAINTAINERS                                   |   2 +-
 6 files changed, 223 insertions(+), 124 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/samsung,spi.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-samsung.txt

diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
index 58f2e9d8bb0e..d10ec742a6a5 100644
--- a/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
+++ b/Documentation/devicetree/bindings/soc/samsung/exynos-usi.yaml
@@ -22,7 +22,7 @@ description: |
 
   [1] Documentation/devicetree/bindings/serial/samsung_uart.yaml
   [2] Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
-  [3] Documentation/devicetree/bindings/spi/spi-samsung.txt
+  [3] Documentation/devicetree/bindings/spi/samsung,spi.yaml
 
 properties:
   $nodename:
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
new file mode 100644
index 000000000000..f0db3fb3d688
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi-peripheral-props.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi-peripheral-props.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Peripheral-specific properties for Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  See spi-peripheral-props.yaml for more info.
+
+properties:
+  controller-data:
+    type: object
+    additionalProperties: false
+
+    properties:
+      samsung,spi-feedback-delay:
+        description: |
+          The sampling phase shift to be applied on the miso line (to account
+          for any lag in the miso line). Valid values:
+           - 0: No phase shift.
+           - 1: 90 degree phase shift sampling.
+           - 2: 180 degree phase shift sampling.
+           - 3: 270 degree phase shift sampling.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 1, 2, 3]
+        default: 0
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
new file mode 100644
index 000000000000..61c77088e8ee
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -0,0 +1,187 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/samsung,spi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S3C/S5P/Exynos SoC SPI controller
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+
+description:
+  All the SPI controller nodes should be represented in the aliases node using
+  the following format 'spi{n}' where n is a unique number for the alias.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
+          - samsung,s3c6410-spi
+          - samsung,s5pv210-spi # for S5PV210 and S5PC110
+          - samsung,exynos5433-spi
+      - const: samsung,exynos7-spi
+        deprecated: true
+
+  clocks:
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    minItems: 2
+    maxItems: 3
+
+  cs-gpios: true
+
+  dmas:
+    minItems: 2
+    maxItems: 2
+
+  dma-names:
+    items:
+      - const: tx
+      - const: rx
+
+  interrupts:
+    maxItems: 1
+
+  no-cs-readback:
+    description:
+      The CS line is disconnected, therefore the device should not operate
+      based on CS signalling.
+    type: boolean
+
+  num-cs:
+    minimum: 1
+    maximum: 4
+    default: 1
+
+  samsung,spi-src-clk:
+    description:
+      If the spi controller includes a internal clock mux to select the clock
+      source for the spi bus clock, this property can be used to indicate the
+      clock to be used for driving the spi bus clock. If not specified, the
+      clock number 0 is used as default.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - interrupts
+  - reg
+
+allOf:
+  - $ref: spi-controller.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynos5433-spi
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+            - const: spi_ioclk
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: spi
+            - enum:
+                - spi_busclk0
+                - spi_busclk1
+                - spi_busclk2
+                - spi_busclk3
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/clock/samsung,s2mps11.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi at 14d30000 {
+        compatible = "samsung,exynos5433-spi";
+        reg = <0x14d30000 0x100>;
+        interrupts = <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
+        dmas = <&pdma0 11>, <&pdma0 10>;
+        dma-names = "tx", "rx";
+        #address-cells = <1>;
+        #size-cells = <0>;
+        clocks = <&cmu_peric CLK_PCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_SPI1>,
+                 <&cmu_peric CLK_SCLK_IOCLK_SPI1>;
+        clock-names = "spi",
+                      "spi_busclk0",
+                      "spi_ioclk";
+        samsung,spi-src-clk = <0>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&spi1_bus>;
+        num-cs = <1>;
+
+        cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+
+        audio-codec at 0 {
+            compatible = "wlf,wm5110";
+            reg = <0x0>;
+            spi-max-frequency = <20000000>;
+            interrupt-parent = <&gpa0>;
+            interrupts = <4 IRQ_TYPE_NONE>;
+            clocks = <&pmu_system_controller 0>,
+                     <&s2mps13_osc S2MPS11_CLK_BT>;
+            clock-names = "mclk1", "mclk2";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            wlf,micd-detect-debounce = <300>;
+            wlf,micd-bias-start-time = <0x1>;
+            wlf,micd-rate = <0x7>;
+            wlf,micd-dbtime = <0x2>;
+            wlf,micd-force-micbias;
+            wlf,micd-configs = <0x0 1 0>;
+            wlf,hpdet-channel = <1>;
+            wlf,gpsw = <0x1>;
+            wlf,inmode = <2 0 2 0>;
+
+            wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+            wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+            /* core supplies */
+            AVDD-supply = <&ldo18_reg>;
+            DBVDD1-supply = <&ldo18_reg>;
+            CPVDD-supply = <&ldo18_reg>;
+            DBVDD2-supply = <&ldo18_reg>;
+            DBVDD3-supply = <&ldo18_reg>;
+            SPKVDDL-supply = <&ldo18_reg>;
+            SPKVDDR-supply = <&ldo18_reg>;
+
+            controller-data {
+                samsung,spi-feedback-delay = <0>;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
index 5dd209206e88..df885eeb144f 100644
--- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
+++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -85,5 +85,6 @@ properties:
 # The controller specific properties go here.
 allOf:
   - $ref: cdns,qspi-nor-peripheral-props.yaml#
+  - $ref: samsung,spi-peripheral-props.yaml#
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/spi-samsung.txt b/Documentation/devicetree/bindings/spi/spi-samsung.txt
deleted file mode 100644
index 49028a4f5df1..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-samsung.txt
+++ /dev/null
@@ -1,122 +0,0 @@
-* Samsung SPI Controller
-
-The Samsung SPI controller is used to interface with various devices such as flash
-and display controllers using the SPI communication interface.
-
-Required SoC Specific Properties:
-
-- compatible: should be one of the following.
-    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
-    - samsung,s3c6410-spi: for s3c6410 platforms
-    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
-    - samsung,exynos5433-spi: for exynos5433 compatible controllers
-    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>
-
-- reg: physical base address of the controller and length of memory mapped
-  region.
-
-- interrupts: The interrupt number to the cpu. The interrupt specifier format
-  depends on the interrupt controller.
-
-- dmas : Two or more DMA channel specifiers following the convention outlined
-  in bindings/dma/dma.txt
-
-- dma-names: Names for the dma channels. There must be at least one channel
-  named "tx" for transmit and named "rx" for receive.
-
-- clocks: specifies the clock IDs provided to the SPI controller; they are
-  required for interacting with the controller itself, for synchronizing the bus
-  and as I/O clock (the latter is required by exynos5433 and exynos7).
-
-- clock-names: string names of the clocks in the 'clocks' property; for all the
-  the devices the names must be "spi", "spi_busclkN" (where N is determined by
-  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
-  "spi_ioclk" for the I/O clock.
-
-Required Board Specific Properties:
-
-- #address-cells: should be 1.
-- #size-cells: should be 0.
-
-Optional Board Specific Properties:
-
-- samsung,spi-src-clk: If the spi controller includes a internal clock mux to
-  select the clock source for the spi bus clock, this property can be used to
-  indicate the clock to be used for driving the spi bus clock. If not specified,
-  the clock number 0 is used as default.
-
-- num-cs: Specifies the number of chip select lines supported. If
-  not specified, the default number of chip select lines is set to 1.
-
-- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)
-
-- no-cs-readback: the CS line is disconnected, therefore the device should not
-  operate based on CS signalling.
-
-SPI Controller specific data in SPI slave nodes:
-
-- The spi slave nodes should provide the following information which is required
-  by the spi controller.
-
-  - samsung,spi-feedback-delay: The sampling phase shift to be applied on the
-    miso line (to account for any lag in the miso line). The following are the
-    valid values.
-
-      - 0: No phase shift.
-      - 1: 90 degree phase shift sampling.
-      - 2: 180 degree phase shift sampling.
-      - 3: 270 degree phase shift sampling.
-
-Aliases:
-
-- All the SPI controller nodes should be represented in the aliases node using
-  the following format 'spi{n}' where n is a unique number for the alias.
-
-
-Example:
-
-- SoC Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		compatible = "samsung,exynos4210-spi";
-		reg = <0x12d20000 0x100>;
-		interrupts = <0 66 0>;
-		dmas = <&pdma0 5
-			&pdma0 4>;
-		dma-names = "tx", "rx";
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
-
-- Board Specific Portion:
-
-	spi_0: spi at 12d20000 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&spi0_bus>;
-		cs-gpios = <&gpa2 5 0>;
-
-		w25q80bw at 0 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "w25x80";
-			reg = <0>;
-			spi-max-frequency = <10000>;
-
-			controller-data {
-				samsung,spi-feedback-delay = <0>;
-			};
-
-			partition at 0 {
-				label = "U-Boot";
-				reg = <0x0 0x40000>;
-				read-only;
-			};
-
-			partition at 40000 {
-				label = "Kernel";
-				reg = <0x40000 0xc0000>;
-			};
-		};
-	};
diff --git a/MAINTAINERS b/MAINTAINERS
index 77c01b55099c..f0b083b279de 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17114,7 +17114,7 @@ M:	Andi Shyti <andi at etezian.org>
 L:	linux-spi at vger.kernel.org
 L:	linux-samsung-soc at vger.kernel.org
 S:	Maintained
-F:	Documentation/devicetree/bindings/spi/spi-samsung.txt
+F:	Documentation/devicetree/bindings/spi/samsung,spi*.yaml
 F:	drivers/spi/spi-s3c*
 F:	include/linux/platform_data/spi-s3c64xx.h
 F:	include/linux/spi/s3c24xx-fiq.h
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Mon Jan 24 00:23:47 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 24 Jan 2022 09:23:47 +0100
Subject: [PATCH v6 4/4] spi: s3c64xx: allow controller-data to be optional
In-Reply-To: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
References: <20220124082347.32747-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220124082347.32747-5-krzysztof.kozlowski@canonical.com>

The Samsung SoC SPI driver requires to provide controller-data node
for each of SPI peripheral device nodes.  Make this controller-data node
optional, so DTS could be simpler.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Sam Protsenko <semen.protsenko at linaro.org>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 drivers/spi/spi-s3c64xx.c | 14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 8755cd85e83c..386550fca81c 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -796,16 +796,14 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata(
 		return ERR_PTR(-EINVAL);
 	}
 
-	data_np = of_get_child_by_name(slave_np, "controller-data");
-	if (!data_np) {
-		dev_err(&spi->dev, "child node 'controller-data' not found\n");
-		return ERR_PTR(-EINVAL);
-	}
-
 	cs = kzalloc(sizeof(*cs), GFP_KERNEL);
-	if (!cs) {
-		of_node_put(data_np);
+	if (!cs)
 		return ERR_PTR(-ENOMEM);
+
+	data_np = of_get_child_by_name(slave_np, "controller-data");
+	if (!data_np) {
+		dev_info(&spi->dev, "feedback delay set to default (0)\n");
+		return cs;
 	}
 
 	of_property_read_u32(data_np, "samsung,spi-feedback-delay", &fb_delay);
-- 
2.32.0



From francesco.dolcini at toradex.com  Mon Jan 24 00:28:01 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Mon, 24 Jan 2022 09:28:01 +0100
Subject: [PATCH v2 0/2] Enable i.MX7 SOLO temperature sensor
Message-ID: <20220124082803.94286-1-francesco.dolcini@toradex.com>

To be able to read the T junction on i.MX CPU the imx-cpufreq-dt needs to be
loaded, however this is currently not the case for i.MX7S given that it does
have only one operating frequency.

Add "fsl,imx7s" to cpufreq-dt-platdev blocklist and a single frequency
operating point to the CPU.

With that it is now possible to correctly read the CPU T junction.

Tested on Toradex Colibri iMX7S

[    6.232577] imx-cpufreq-dt imx-cpufreq-dt: cpu speed grade 0 mkt segment 1 supported-hw 0x1 0x2
...
[    6.880624] imx_thermal 30360000.anatop:tempmon: Extended Commercial CPU temperature grade - max:105C critical:100C passive:95C

root at colibri-imx7-02983025:~# cat /sys/class/thermal/thermal_zone0/temp 
38000

v2:
 - removed empty new line
 - rebased and tested on v5.17-rc1


Denys Drozdov (1):
  ARM: dts: imx7s: Define operating points table for cpufreq

Stefan Agner (1):
  cpufreq: Add i.MX7S to cpufreq-dt-platdev blocklist

 arch/arm/boot/dts/imx7s.dtsi         | 16 ++++++++++++++++
 drivers/cpufreq/cpufreq-dt-platdev.c |  1 +
 2 files changed, 17 insertions(+)

-- 
2.25.1



From francesco.dolcini at toradex.com  Mon Jan 24 00:28:03 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Mon, 24 Jan 2022 09:28:03 +0100
Subject: [PATCH v2 2/2] cpufreq: Add i.MX7S to cpufreq-dt-platdev blocklist
In-Reply-To: <20220124082803.94286-1-francesco.dolcini@toradex.com>
References: <20220124082803.94286-1-francesco.dolcini@toradex.com>
Message-ID: <20220124082803.94286-3-francesco.dolcini@toradex.com>

From: Stefan Agner <stefan.agner at toradex.com>

The i.MX 7Solo currently does not have multiple operating points,
however, in order for the i.MX Thermal driver to successfully probe
a cpufreq device is required. Add it to the cpufreq-dt-platdev
driver's blocklist to allow using imx-cpufreq-dt.

Signed-off-by: Stefan Agner <stefan.agner at toradex.com>
Cc: Stefan Agner <stefan at agner.ch>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
v2: removed empty line
---
 drivers/cpufreq/cpufreq-dt-platdev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
index ca1d103ec449..6b808f805eab 100644
--- a/drivers/cpufreq/cpufreq-dt-platdev.c
+++ b/drivers/cpufreq/cpufreq-dt-platdev.c
@@ -110,6 +110,7 @@ static const struct of_device_id blocklist[] __initconst = {
 
 	{ .compatible = "fsl,imx7ulp", },
 	{ .compatible = "fsl,imx7d", },
+	{ .compatible = "fsl,imx7s", },
 	{ .compatible = "fsl,imx8mq", },
 	{ .compatible = "fsl,imx8mm", },
 	{ .compatible = "fsl,imx8mn", },
-- 
2.25.1



From francesco.dolcini at toradex.com  Mon Jan 24 00:28:02 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Mon, 24 Jan 2022 09:28:02 +0100
Subject: [PATCH v2 1/2] ARM: dts: imx7s: Define operating points table for
 cpufreq
In-Reply-To: <20220124082803.94286-1-francesco.dolcini@toradex.com>
References: <20220124082803.94286-1-francesco.dolcini@toradex.com>
Message-ID: <20220124082803.94286-2-francesco.dolcini@toradex.com>

From: Denys Drozdov <denys.drozdov at toradex.com>

Processor operating points for imx7s.dtsi should be properly defined to
perform correct imx-cpufreq-dt probe and registration and provide an
access to the temperature sensors using the i.MX thermal driver.

Signed-off-by: Denys Drozdov <denys.drozdov at toradex.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---

v2: no changes

---
 arch/arm/boot/dts/imx7s.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 52a9aeecdbb2..5af6d58666f4 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -76,6 +76,22 @@ cpu0: cpu at 0 {
 			clock-latency = <61036>; /* two CLK32 periods */
 			clocks = <&clks IMX7D_CLK_ARM>;
 			cpu-idle-states = <&cpu_sleep_wait>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			#cooling-cells = <2>;
+			nvmem-cells = <&fuse_grade>;
+			nvmem-cell-names = "speed_grade";
+		};
+	};
+
+	cpu0_opp_table: opp-table {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-792000000 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <150000>;
+			opp-supported-hw = <0xf>, <0xf>;
 		};
 	};
 
-- 
2.25.1



From sha at pengutronix.de  Mon Jan 24 00:31:02 2022
From: sha at pengutronix.de (Sascha Hauer)
Date: Mon, 24 Jan 2022 09:31:02 +0100
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
In-Reply-To: <20220123135116.136846-3-linux@fw-web.de>
References: <20220123135116.136846-1-linux@fw-web.de>
 <20220123135116.136846-3-linux@fw-web.de>
Message-ID: <20220124083102.GW23490@pengutronix.de>

On Sun, Jan 23, 2022 at 02:51:16PM +0100, Frank Wunderlich wrote:
> From: Frank Wunderlich <frank-w at public-files.de>
> 
> This patch adds Devicetree for Bananapi R2 Pro based on RK3568.
> Add uart/sd/emmc/i2c/rk809/tsadc nodes for basic function.
> Gmac0 is directly connected to wan-port so usable without additional
> driver.
> On gmac1 there is a switch (rtl8367rb) connected which have not yet a
> driver in mainline.
> 
> Patch also prepares nodes for GPIO header.
> 
> Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> ---
> +&gmac0 {
> +	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
> +	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
> +	clock_in_out = "input";
> +	phy-handle = <&rgmii_phy0>;
> +	phy-mode = "rgmii";
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&gmac0_miim
> +		     &gmac0_tx_bus2
> +		     &gmac0_rx_bus2
> +		     &gmac0_rgmii_clk
> +		     &gmac0_rgmii_bus>;
> +
> +	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> +	snps,reset-active-low;
> +	/* Reset time is 20ms, 100ms for rtl8211f */

Is this really a rtl8211f? I don't know and it could indeed be a
rtl8211f, I'm just asking because the comment is copy pasted from
the Quartz64 board.

> +	snps,reset-delays-us = <0 20000 100000>;
> +
> +&mdio0 {
> +	rgmii_phy0: ethernet-phy at 0 {
> +		compatible = "ethernet-phy-ieee802.3-c22";
> +		reg = <0x0>;
> +	};

0 is the broadcast address. I'm not sure if it's a good idea to use it.
There should be another address the phy listens on.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From qizhong.cheng at mediatek.com  Mon Jan 24 00:34:43 2022
From: qizhong.cheng at mediatek.com (qizhong.cheng)
Date: Mon, 24 Jan 2022 16:34:43 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <CAGXv+5GUW6qcxwnfj3dsn7Lb1yY5bNv+v+PQ2VN1NX9yPmGd2A@mail.gmail.com>
References: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
 <CAGXv+5EcAXFTnjkbeU4f3J2s4Ue5zxrN4QgS=t54BnLX8Gkw2w@mail.gmail.com>
 <bddf917f241a6628d43ddd95b577024c9ddf9931.camel@mediatek.com>
 <CAGXv+5GUW6qcxwnfj3dsn7Lb1yY5bNv+v+PQ2VN1NX9yPmGd2A@mail.gmail.com>
Message-ID: <a43c470c41d083ad632b276ebf17795f35c98a3a.camel@mediatek.com>

On Mon, 2022-01-24 at 14:55 +0800, Chen-Yu Tsai wrote:
> On Mon, Jan 24, 2022 at 2:27 PM qizhong.cheng
> <qizhong.cheng at mediatek.com> wrote:
> > 
> > Hi chenYu,
> > 
> > On Mon, 2022-01-24 at 11:12 +0800, Chen-Yu Tsai wrote:
> > > Hi,
> > > 
> > > On Sun, Jan 23, 2022 at 11:34 AM qizhong cheng
> > > <qizhong.cheng at mediatek.com> wrote:
> > > > 
> > > > As an edge-triggered interrupts, its interrupt status should be
> > > > cleared
> > > > before dispatch to the handler of device.
> > > 
> > > I'm curious, is this just a code correction or are there real
> > > world
> > > cases where something fails?
> > 
> > Yes, we found a failure when used iperf tool for wifi and network
> > cards
> > performance testing. The function of "while" has just been
> > executed,
> > and the EP sent an MSI before executing "Clear MSI interrupt
> > status".
> > After executing "Clear MSI interrupt status", this edge-triggered
> > interrupt status is cleared, but EP is still waiting for interrupt
> > handler.
> 
> Can you also include this in the commit log?  It would be nice to
> record
> the exact scenario that this fix targets.

Thanks for your suggestion. I will add commit log in the next version
for others review.

> 
> ChenYu
> 
> > > 
> > > Also, please add a Fixes tag and maybe Cc stable so this gets
> > > backported
> > > automatically.
> > 
> > Thanks for your review, I will fix it in the next version.
> > 
> > > 
> > > ChenYu
> > > 
> > > > Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
> > > > ---
> > > >  drivers/pci/controller/pcie-mediatek.c | 4 ++--
> > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/pci/controller/pcie-mediatek.c
> > > > b/drivers/pci/controller/pcie-mediatek.c
> > > > index 2f3f974977a3..705ea33758b1 100644
> > > > --- a/drivers/pci/controller/pcie-mediatek.c
> > > > +++ b/drivers/pci/controller/pcie-mediatek.c
> > > > @@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct
> > > > irq_desc *desc)
> > > >                 if (status & MSI_STATUS){
> > > >                         unsigned long imsi_status;
> > > > 
> > > > +                       /* Clear MSI interrupt status */
> > > > +                       writel(MSI_STATUS, port->base +
> > > > PCIE_INT_STATUS);
> > > >                         while ((imsi_status = readl(port->base
> > > > +
> > > > PCIE_IMSI_STATUS))) {
> > > >                                 for_each_set_bit(bit,
> > > > &imsi_status,
> > > > MTK_MSI_IRQS_NUM)
> > > >                                         generic_handle_domain_i
> > > > rq(p
> > > > ort->inner_domain, bit);
> > > >                         }
> > > > -                       /* Clear MSI interrupt status */
> > > > -                       writel(MSI_STATUS, port->base +
> > > > PCIE_INT_STATUS);
> > > >                 }
> > > >         }
> > > > 
> > > > --
> > > > 2.25.1
> > > > 
> > > > 
> > > > _______________________________________________
> > > > Linux-mediatek mailing list
> > > > Linux-mediatek at lists.infradead.org
> > > > http://lists.infradead.org/mailman/listinfo/linux-mediatek

From thunder.leizhen at huawei.com  Mon Jan 24 00:47:04 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:04 +0800
Subject: [PATCH v20 1/5] arm64: Use insert_resource() to simplify code
In-Reply-To: <20220124084708.683-1-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
Message-ID: <20220124084708.683-2-thunder.leizhen@huawei.com>

insert_resource() traverses the subtree layer by layer from the root node
until a proper location is found. Compared with request_resource(), the
parent node does not need to be determined in advance.

In addition, move the insertion of node 'crashk_res' into function
reserve_crashkernel() to make the associated code close together.

Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 arch/arm64/kernel/setup.c | 17 +++--------------
 arch/arm64/mm/init.c      |  1 +
 2 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f70573928f1bff0..a81efcc359e4e78 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -225,6 +225,8 @@ static void __init request_standard_resources(void)
 	kernel_code.end     = __pa_symbol(__init_begin - 1);
 	kernel_data.start   = __pa_symbol(_sdata);
 	kernel_data.end     = __pa_symbol(_end - 1);
+	insert_resource(&iomem_resource, &kernel_code);
+	insert_resource(&iomem_resource, &kernel_data);
 
 	num_standard_resources = memblock.memory.cnt;
 	res_size = num_standard_resources * sizeof(*standard_resources);
@@ -246,20 +248,7 @@ static void __init request_standard_resources(void)
 			res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
 		}
 
-		request_resource(&iomem_resource, res);
-
-		if (kernel_code.start >= res->start &&
-		    kernel_code.end <= res->end)
-			request_resource(res, &kernel_code);
-		if (kernel_data.start >= res->start &&
-		    kernel_data.end <= res->end)
-			request_resource(res, &kernel_data);
-#ifdef CONFIG_KEXEC_CORE
-		/* Userspace will find "Crash kernel" region in /proc/iomem. */
-		if (crashk_res.end && crashk_res.start >= res->start &&
-		    crashk_res.end <= res->end)
-			request_resource(res, &crashk_res);
-#endif
+		insert_resource(&iomem_resource, res);
 	}
 }
 
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index db63cc885771a52..90f276d46b93bc6 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -109,6 +109,7 @@ static void __init reserve_crashkernel(void)
 	kmemleak_ignore_phys(crash_base);
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
+	insert_resource(&iomem_resource, &crashk_res);
 }
 #else
 static void __init reserve_crashkernel(void)
-- 
2.25.1



From thunder.leizhen at huawei.com  Mon Jan 24 00:47:06 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:06 +0800
Subject: [PATCH v20 3/5] arm64: kdump: reimplement crashkernel=X
In-Reply-To: <20220124084708.683-1-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
Message-ID: <20220124084708.683-4-thunder.leizhen@huawei.com>

From: Chen Zhou <chenzhou10 at huawei.com>

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.

To solve these issues, change the behavior of crashkernel=X and
introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
in DMA zone, and fall back to high allocation if it fails.
We can also use "crashkernel=X,high" to select a region above DMA zone,
which also tries to allocate at least 256M in DMA zone automatically.
"crashkernel=Y,low" can be used to allocate specified size low memory.

Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 arch/arm64/kernel/machine_kexec.c      |  9 +++-
 arch/arm64/kernel/machine_kexec_file.c | 12 ++++-
 arch/arm64/mm/init.c                   | 68 ++++++++++++++++++++++++--
 3 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index e16b248699d5c3c..19c2d487cb08feb 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -329,8 +329,13 @@ bool crash_is_nosave(unsigned long pfn)
 
 	/* in reserved memory? */
 	addr = __pfn_to_phys(pfn);
-	if ((addr < crashk_res.start) || (crashk_res.end < addr))
-		return false;
+	if ((addr < crashk_res.start) || (crashk_res.end < addr)) {
+		if (!crashk_low_res.end)
+			return false;
+
+		if ((addr < crashk_low_res.start) || (crashk_low_res.end < addr))
+			return false;
+	}
 
 	if (!kexec_crash_image)
 		return true;
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 59c648d51848886..889951291cc0f9c 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -65,10 +65,18 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
 
 	/* Exclude crashkernel region */
 	ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
+	if (ret)
+		goto out;
+
+	if (crashk_low_res.end) {
+		ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
+		if (ret)
+			goto out;
+	}
 
-	if (!ret)
-		ret =  crash_prepare_elf64_headers(cmem, true, addr, sz);
+	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
 
+out:
 	kfree(cmem);
 	return ret;
 }
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 6c653a2c7cff052..a5d43feac0d7d96 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -71,6 +71,30 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 #define CRASH_ADDR_LOW_MAX	arm64_dma_phys_limit
 #define CRASH_ADDR_HIGH_MAX	MEMBLOCK_ALLOC_ACCESSIBLE
 
+static int __init reserve_crashkernel_low(unsigned long long low_size)
+{
+	unsigned long long low_base;
+
+	/* passed with crashkernel=0,low ? */
+	if (!low_size)
+		return 0;
+
+	low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
+	if (!low_base) {
+		pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size);
+		return -ENOMEM;
+	}
+
+	pr_info("crashkernel low memory reserved: 0x%llx - 0x%llx (%lld MB)\n",
+		low_base, low_base + low_size, low_size >> 20);
+
+	crashk_low_res.start = low_base;
+	crashk_low_res.end   = low_base + low_size - 1;
+	insert_resource(&iomem_resource, &crashk_low_res);
+
+	return 0;
+}
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -81,29 +105,62 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
+	unsigned long long crash_low_size = SZ_256M;
 	unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
 	int ret;
+	bool fixed_base;
+	char *cmdline = boot_command_line;
 
-	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
+	/* crashkernel=X[@offset] */
+	ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
 				&crash_size, &crash_base);
-	/* no crashkernel= or invalid value specified */
-	if (ret || !crash_size)
-		return;
+	if (ret || !crash_size) {
+		unsigned long long low_size;
 
+		/* crashkernel=X,high */
+		ret = parse_crashkernel_high(cmdline, 0, &crash_size, &crash_base);
+		if (ret || !crash_size)
+			return;
+
+		/* crashkernel=X,low */
+		ret = parse_crashkernel_low(cmdline, 0, &low_size, &crash_base);
+		if (!ret)
+			crash_low_size = low_size;
+
+		crash_max = CRASH_ADDR_HIGH_MAX;
+	}
+
+	fixed_base = !!crash_base;
 	crash_size = PAGE_ALIGN(crash_size);
 
 	/* User specifies base address explicitly. */
 	if (crash_base)
 		crash_max = crash_base + crash_size;
 
+retry:
 	crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
 					       crash_base, crash_max);
 	if (!crash_base) {
+		/*
+		 * Attempt to fully allocate low memory failed, fall back
+		 * to high memory, the minimum required low memory will be
+		 * reserved later.
+		 */
+		if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) {
+			crash_max = CRASH_ADDR_HIGH_MAX;
+			goto retry;
+		}
+
 		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
 			crash_size);
 		return;
 	}
 
+	if (crash_base >= SZ_4G && reserve_crashkernel_low(crash_low_size)) {
+		memblock_phys_free(crash_base, crash_size);
+		return;
+	}
+
 	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
 		crash_base, crash_base + crash_size, crash_size >> 20);
 
@@ -112,6 +169,9 @@ static void __init reserve_crashkernel(void)
 	 * map. Inform kmemleak so that it won't try to access it.
 	 */
 	kmemleak_ignore_phys(crash_base);
+	if (crashk_low_res.end)
+		kmemleak_ignore_phys(crashk_low_res.start);
+
 	crashk_res.start = crash_base;
 	crashk_res.end = crash_base + crash_size - 1;
 	insert_resource(&iomem_resource, &crashk_res);
-- 
2.25.1



From thunder.leizhen at huawei.com  Mon Jan 24 00:47:03 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:03 +0800
Subject: [PATCH v20 0/5] support reserving crashkernel above 4G on arm64 kdump
Message-ID: <20220124084708.683-1-thunder.leizhen@huawei.com>

There are following issues in arm64 kdump:
1. We use crashkernel=X to reserve crashkernel below 4G, which
will fail when there is no enough low memory.
2. If reserving crashkernel above 4G, in this case, crash dump
kernel will boot failure because there is no low memory available
for allocation.

To solve these issues, change the behavior of crashkernel=X.
crashkernel=X tries low allocation in DMA zone and fall back to high
allocation if it fails.

We can also use "crashkernel=X,high" to select a high region above
DMA zone, which also tries to allocate at least 256M low memory in
DMA zone automatically and "crashkernel=Y,low" can be used to allocate
specified size low memory.

When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices. So there may be two regions reserved for
crash dump kernel.
In order to distinct from the high region and make no effect to the use
of existing kexec-tools, rename the low region as "Crash kernel (low)",
and pass the low region by reusing DT property
"linux,usable-memory-range". We made the low memory region as the last
range of "linux,usable-memory-range" to keep compatibility with existing
user-space and older kdump kernels.

Besides, we need to modify kexec-tools:
arm64: support more than one crash kernel regions(see [1])

Another update is document about DT property 'linux,usable-memory-range':
schemas: update 'linux,usable-memory-range' node schema(see [2])


Changes since [v19]:
1. Temporarily stop making reserve_crashkernel[_low]() generic. There are a
   lot of details need to be considered, which can take a long time. Because
   "make generic" does not add new functions and does not improve performance,
   maybe I should say it's just a cleanup. So by stripping it out and leaving
   it for other patches later, we can aggregate the changes to the main functions.
2. Use insert_resource() to replace request_resource(), this not only simplifies
   the code, but also reduces the differences between arm64 and x86 implementations.
3. As commit 157752d84f5d ("kexec: use Crash kernel for Crash kernel low") do for
   x86, we can also extend kexec-tools for arm64, and it's currently applied. See:
   https://www.spinics.net/lists/kexec/msg28284.html

Thank you very much, Borislav Petkov, for so many valuable comments.



Changes since [v17]: v17 --> v19
1. Patch 0001-0004
   Introduce generic parse_crashkernel_high_low() to bring the parsing of
   "crashkernel=X,high" and the parsing of "crashkernel=X,low" together,
   then use it instead of the call to parse_crashkernel_{high|low}(). Two
   confusing parameters of parse_crashkernel_{high|low}() are deleted.

   I previously sent these four patches separately:
   [1] https://lkml.org/lkml/2021/12/25/40
2. Patch 0005-0009
   Introduce generic reserve_crashkernel_mem[_low](), the implementation of
   these two functions is based on function reserve_crashkernel[_low]() in
   arch/x86/kernel/setup.c. There is no functional change for x86.
   1) The check position of xen_pv_domain() does not change.
   2) Still 1M alignment for crash kernel fixed region, when 'base' is specified.

   To avoid compilation problems on other architectures: patch 0004 moves
   the definition of global variable crashk[_low]_res from kexec_core.c to
   crash_core.c, and provide default definitions for all macros involved, a
   particular platform can redefine these macros to override the default
   values.
3. 0010, only one line of comment was changed.
4. 0011
   1) crashk_low_res may also a valid reserved memory, should be checked
      in crash_is_nosave(), see arch/arm64/kernel/machine_kexec.
   2) Drop memblock_mark_nomap() for crashk_low_res, because of:
      2687275a5843 arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required
   3) Also call kmemleak_ignore_phys() for crashk_low_res, because of:
      85f58eb18898 arm64: kdump: Skip kmemleak scan reserved memory for kdump
5. 0012, slightly rebased, because the following patch is applied in advance. 
   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git/commit/?h=dt/linus&id=8347b41748c3019157312fbe7f8a6792ae396eb7
6. 0013, no change.

Others:
1. Discard add ARCH_WANT_RESERVE_CRASH_KERNEL
2. When allocating crash low memory, the start address still starts from 0.
   low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
3. Discard change (1ULL << 32) to CRASH_ADDR_LOW_MAX.
4. Ensure the check position of xen_pv_domain() have no change.
5. Except patch 0010 and 0012, all "Tested-by", "Reviewed-by", "Acked-by" are removed.
6. Update description.



Changes since [v16]
- Because no functional changes in this version, so add
  "Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>" for patch 1-9
- Add "Reviewed-by: Rob Herring <robh at kernel.org>" for patch 8
- Update patch 9 based on the review comments of Rob Herring
- As Catalin Marinas's suggestion, merge the implementation of
  ARCH_WANT_RESERVE_CRASH_KERNEL into patch 5. Ensure that the
  contents of X86 and ARM64 do not overlap, and reduce unnecessary
  temporary differences.

Changes since [v15]
-  Aggregate the processing of "linux,usable-memory-range" into one function.
   Only patch 9-10 have been updated.

Changes since [v14]
- Recovering the requirement that the CrashKernel memory regions on X86
  only requires 1 MiB alignment.
- Combine patches 5 and 6 in v14 into one. The compilation warning fixed
  by patch 6 was introduced by patch 5 in v14.
- As with crashk_res, crashk_low_res is also processed by
  crash_exclude_mem_range() in patch 7.
- Due to commit b261dba2fdb2 ("arm64: kdump: Remove custom linux,usable-memory-range handling")
  has removed the architecture-specific code, extend the property "linux,usable-memory-range"
  in the platform-agnostic FDT core code. See patch 9.
- Discard the x86 description update in the document, because the description
  has been updated by commit b1f4c363666c ("Documentation: kdump: update kdump guide").
- Change "arm64" to "ARM64" in Doc.


Changes since [v13]
- Rebased on top of 5.11-rc5.
- Introduce config CONFIG_ARCH_WANT_RESERVE_CRASH_KERNEL.
Since reserve_crashkernel[_low]() implementations are quite similar on
other architectures, so have CONFIG_ARCH_WANT_RESERVE_CRASH_KERNEL in
arch/Kconfig and select this by X86 and ARM64.
- Some minor cleanup.

Changes since [v12]
- Rebased on top of 5.10-rc1.
- Keep CRASH_ALIGN as 16M suggested by Dave.
- Drop patch "kdump: add threshold for the required memory".
- Add Tested-by from John.

Changes since [v11]
- Rebased on top of 5.9-rc4.
- Make the function reserve_crashkernel() of x86 generic.
Suggested by Catalin, make the function reserve_crashkernel() of x86 generic
and arm64 use the generic version to reimplement crashkernel=X.

Changes since [v10]
- Reimplement crashkernel=X suggested by Catalin, Many thanks to Catalin.

Changes since [v9]
- Patch 1 add Acked-by from Dave.
- Update patch 5 according to Dave's comments.
- Update chosen schema.

Changes since [v8]
- Reuse DT property "linux,usable-memory-range".
Suggested by Rob, reuse DT property "linux,usable-memory-range" to pass the low
memory region.
- Fix kdump broken with ZONE_DMA reintroduced.
- Update chosen schema.

Changes since [v7]
- Move x86 CRASH_ALIGN to 2M
Suggested by Dave and do some test, move x86 CRASH_ALIGN to 2M.
- Update Documentation/devicetree/bindings/chosen.txt.
Add corresponding documentation to Documentation/devicetree/bindings/chosen.txt
suggested by Arnd.
- Add Tested-by from Jhon and pk.

Changes since [v6]
- Fix build errors reported by kbuild test robot.

Changes since [v5]
- Move reserve_crashkernel_low() into kernel/crash_core.c.
- Delete crashkernel=X,high.
- Modify crashkernel=X,low.
If crashkernel=X,low is specified simultaneously, reserve spcified size low
memory for crash kdump kernel devices firstly and then reserve memory above 4G.
In addition, rename crashk_low_res as "Crash kernel (low)" for arm64, and then
pass to crash dump kernel by DT property "linux,low-memory-range".
- Update Documentation/admin-guide/kdump/kdump.rst.

Changes since [v4]
- Reimplement memblock_cap_memory_ranges for multiple ranges by Mike.

Changes since [v3]
- Add memblock_cap_memory_ranges back for multiple ranges.
- Fix some compiling warnings.

Changes since [v2]
- Split patch "arm64: kdump: support reserving crashkernel above 4G" as
two. Put "move reserve_crashkernel_low() into kexec_core.c" in a separate
patch.

Changes since [v1]:
- Move common reserve_crashkernel_low() code into kernel/kexec_core.c.
- Remove memblock_cap_memory_ranges() i added in v1 and implement that
in fdt_enforce_memory_region().
There are at most two crash kernel regions, for two crash kernel regions
case, we cap the memory range [min(regs[*].start), max(regs[*].end)]
and then remove the memory range in the middle.

[1]: https://www.spinics.net/lists/kexec/msg28226.html
[2]: https://github.com/robherring/dt-schema/pull/19 
[v1]: https://lkml.org/lkml/2019/4/2/1174
[v2]: https://lkml.org/lkml/2019/4/9/86
[v3]: https://lkml.org/lkml/2019/4/9/306
[v4]: https://lkml.org/lkml/2019/4/15/273
[v5]: https://lkml.org/lkml/2019/5/6/1360
[v6]: https://lkml.org/lkml/2019/8/30/142
[v7]: https://lkml.org/lkml/2019/12/23/411
[v8]: https://lkml.org/lkml/2020/5/21/213
[v9]: https://lkml.org/lkml/2020/6/28/73
[v10]: https://lkml.org/lkml/2020/7/2/1443
[v11]: https://lkml.org/lkml/2020/8/1/150
[v12]: https://lkml.org/lkml/2020/9/7/1037
[v13]: https://lkml.org/lkml/2020/10/31/34
[v14]: https://lkml.org/lkml/2021/1/30/53
[v15]: https://lkml.org/lkml/2021/10/19/1405
[v16]: https://lkml.org/lkml/2021/11/23/435
[v17]: https://lkml.org/lkml/2021/12/10/38
[v18]: https://lkml.org/lkml/2021/12/22/424
[v19]: https://lkml.org/lkml/2021/12/28/203


Chen Zhou (4):
  arm64: kdump: introduce some macros for crash kernel reservation
  arm64: kdump: reimplement crashkernel=X
  of: fdt: Add memory for devices by DT property
    "linux,usable-memory-range"
  kdump: update Documentation about crashkernel

Zhen Lei (1):
  arm64: Use insert_resource() to simplify code

 Documentation/admin-guide/kdump/kdump.rst     | 11 ++-
 .../admin-guide/kernel-parameters.txt         | 11 ++-
 arch/arm64/kernel/machine_kexec.c             |  9 ++-
 arch/arm64/kernel/machine_kexec_file.c        | 12 ++-
 arch/arm64/kernel/setup.c                     | 17 +---
 arch/arm64/mm/init.c                          | 80 +++++++++++++++++--
 drivers/of/fdt.c                              | 33 +++++---
 7 files changed, 134 insertions(+), 39 deletions(-)

-- 
2.25.1



From thunder.leizhen at huawei.com  Mon Jan 24 00:47:05 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:05 +0800
Subject: [PATCH v20 2/5] arm64: kdump: introduce some macros for crash kernel
 reservation
In-Reply-To: <20220124084708.683-1-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
Message-ID: <20220124084708.683-3-thunder.leizhen@huawei.com>

From: Chen Zhou <chenzhou10 at huawei.com>

Introduce macro CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX
for upper bound of low crash memory, macro CRASH_ADDR_HIGH_MAX for
upper bound of high crash memory, use macros instead.

Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
Tested-by: John Donnelly <John.p.donnelly at oracle.com>
Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>
---
 arch/arm64/mm/init.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 90f276d46b93bc6..6c653a2c7cff052 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -65,6 +65,12 @@ EXPORT_SYMBOL(memstart_addr);
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
+/* Current arm64 boot protocol requires 2MB alignment */
+#define CRASH_ALIGN		SZ_2M
+
+#define CRASH_ADDR_LOW_MAX	arm64_dma_phys_limit
+#define CRASH_ADDR_HIGH_MAX	MEMBLOCK_ALLOC_ACCESSIBLE
+
 /*
  * reserve_crashkernel() - reserves memory for crash kernel
  *
@@ -75,7 +81,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
 static void __init reserve_crashkernel(void)
 {
 	unsigned long long crash_base, crash_size;
-	unsigned long long crash_max = arm64_dma_phys_limit;
+	unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
 	int ret;
 
 	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
@@ -90,8 +96,7 @@ static void __init reserve_crashkernel(void)
 	if (crash_base)
 		crash_max = crash_base + crash_size;
 
-	/* Current arm64 boot protocol requires 2MB alignment */
-	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
+	crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
 					       crash_base, crash_max);
 	if (!crash_base) {
 		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
-- 
2.25.1



From thunder.leizhen at huawei.com  Mon Jan 24 00:47:07 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:07 +0800
Subject: [PATCH v20 4/5] of: fdt: Add memory for devices by DT property "linux,
 usable-memory-range"
In-Reply-To: <20220124084708.683-1-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
Message-ID: <20220124084708.683-5-thunder.leizhen@huawei.com>

From: Chen Zhou <chenzhou10 at huawei.com>

When reserving crashkernel in high memory, some low memory is reserved
for crash dump kernel devices and never mapped by the first kernel.
This memory range is advertised to crash dump kernel via DT property
under /chosen,
        linux,usable-memory-range = <BASE1 SIZE1 [BASE2 SIZE2]>

We reused the DT property linux,usable-memory-range and made the low
memory region as the second range "BASE2 SIZE2", which keeps compatibility
with existing user-space and older kdump kernels.

Crash dump kernel reads this property at boot time and call memblock_add()
to add the low memory region after memblock_cap_memory_range() has been
called.

Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>
---
 drivers/of/fdt.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index ad85ff6474ff139..df4b9d2418a13d4 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -973,16 +973,24 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
 
 static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
 
+/*
+ * The main usage of linux,usable-memory-range is for crash dump kernel.
+ * Originally, the number of usable-memory regions is one. Now there may
+ * be two regions, low region and high region.
+ * To make compatibility with existing user-space and older kdump, the low
+ * region is always the last range of linux,usable-memory-range if exist.
+ */
+#define MAX_USABLE_RANGES		2
+
 /**
  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
  * location from flat tree
  */
 void __init early_init_dt_check_for_usable_mem_range(void)
 {
-	const __be32 *prop;
-	int len;
-	phys_addr_t cap_mem_addr;
-	phys_addr_t cap_mem_size;
+	struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
+	const __be32 *prop, *endp;
+	int len, i;
 	unsigned long node = chosen_node_offset;
 
 	if ((long)node < 0)
@@ -991,16 +999,21 @@ void __init early_init_dt_check_for_usable_mem_range(void)
 	pr_debug("Looking for usable-memory-range property... ");
 
 	prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
-	if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
+	if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells)))
 		return;
 
-	cap_mem_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
-	cap_mem_size = dt_mem_next_cell(dt_root_size_cells, &prop);
+	endp = prop + (len / sizeof(__be32));
+	for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) {
+		rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop);
+		rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop);
 
-	pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
-		 &cap_mem_size);
+		pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
+			 i, &rgn[i].base, &rgn[i].size);
+	}
 
-	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
+	memblock_cap_memory_range(rgn[0].base, rgn[0].size);
+	for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
+		memblock_add(rgn[i].base, rgn[i].size);
 }
 
 #ifdef CONFIG_SERIAL_EARLYCON
-- 
2.25.1



From thunder.leizhen at huawei.com  Mon Jan 24 00:47:08 2022
From: thunder.leizhen at huawei.com (Zhen Lei)
Date: Mon, 24 Jan 2022 16:47:08 +0800
Subject: [PATCH v20 5/5] kdump: update Documentation about crashkernel
In-Reply-To: <20220124084708.683-1-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
Message-ID: <20220124084708.683-6-thunder.leizhen@huawei.com>

From: Chen Zhou <chenzhou10 at huawei.com>

For arm64, the behavior of crashkernel=X has been changed, which
tries low allocation in DMA zone and fall back to high allocation
if it fails.

We can also use "crashkernel=X,high" to select a high region above
DMA zone, which also tries to allocate at least 256M low memory in
DMA zone automatically and "crashkernel=Y,low" can be used to allocate
specified size low memory.

So update the Documentation.

Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
---
 Documentation/admin-guide/kdump/kdump.rst       | 11 +++++++++--
 Documentation/admin-guide/kernel-parameters.txt | 11 +++++++++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index cb30ca3df27c9b2..d4c287044be0c70 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -361,8 +361,15 @@ Boot into System Kernel
    kernel will automatically locate the crash kernel image within the
    first 512MB of RAM if X is not given.
 
-   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
-   the kernel, X if explicitly specified, must be aligned to 2MiB (0x200000).
+   On arm64, use "crashkernel=X" to try low allocation in DMA zone and
+   fall back to high allocation if it fails.
+   We can also use "crashkernel=X,high" to select a high region above
+   DMA zone, which also tries to allocate at least 256M low memory in
+   DMA zone automatically.
+   "crashkernel=Y,low" can be used to allocate specified size low memory.
+   Use "crashkernel=Y at X" if you really have to reserve memory from
+   specified start address X. Note that the start address of the kernel,
+   X if explicitly specified, must be aligned to 2MiB (0x200000).
 
 Load the Dump-capture Kernel
 ============================
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f5a27f067db9ed9..65780c2ca830be0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -792,6 +792,9 @@
 			[KNL, X86-64] Select a region under 4G first, and
 			fall back to reserve region above 4G when '@offset'
 			hasn't been specified.
+			[KNL, ARM64] Try low allocation in DMA zone and fall back
+			to high allocation if it fails when '@offset' hasn't been
+			specified.
 			See Documentation/admin-guide/kdump/kdump.rst for further details.
 
 	crashkernel=range1:size1[,range2:size2,...][@offset]
@@ -808,6 +811,8 @@
 			Otherwise memory region will be allocated below 4G, if
 			available.
 			It will be ignored if crashkernel=X is specified.
+			[KNL, ARM64] range in high memory.
+			Allow kernel to allocate physical memory region from top.
 	crashkernel=size[KMG],low
 			[KNL, X86-64] range under 4G. When crashkernel=X,high
 			is passed, kernel could allocate physical memory region
@@ -816,13 +821,15 @@
 			requires at least 64M+32K low memory, also enough extra
 			low memory is needed to make sure DMA buffers for 32-bit
 			devices won't run out. Kernel would try to allocate at
-			at least 256M below 4G automatically.
+			least 256M below 4G automatically.
 			This one let user to specify own low range under 4G
 			for second kernel instead.
 			0: to disable low allocation.
 			It will be ignored when crashkernel=X,high is not used
 			or memory reserved is below 4G.
-
+			[KNL, ARM64] range in low memory.
+			This one let user to specify a low range in DMA zone for
+			crash dump kernel.
 	cryptomgr.notests
 			[KNL] Disable crypto self-tests
 
-- 
2.25.1



From alain.volmat at foss.st.com  Mon Jan 24 00:49:33 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Mon, 24 Jan 2022 09:49:33 +0100
Subject: [PATCH] media: stm32: dcmi: create a dma scatterlist based on
 DMA max_sg_burst value
In-Reply-To: <20220110103739.118426-1-alain.volmat@foss.st.com>
References: <20220110103739.118426-1-alain.volmat@foss.st.com>
Message-ID: <20220124084933.GA722253@gnbcxd0016.gnb.st.com>

Hi,

could you put this on hold for the moment, I've noticed that a
sg_free_table is actually missing in this patch, leading to a memory
leak.  I'll thus post a v2 of the patch shortly.

Cheers,
Alain

On Mon, Jan 10, 2022 at 11:37:39AM +0100, Alain Volmat wrote:
> Prior to submitting a transfer to the DMA, the client should first check
> the capabilities of the DMA channel in term of maximum of each segment.
> This is given by the max_sg_burst value reported by dma_get_slave_caps API.
> Based on that, if the transfer is larger than what can be handled by the
> DMA channel, we split the transfer into several scatterlist elements.
> 
> Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
> ---
>  drivers/media/platform/stm32/stm32-dcmi.c | 47 ++++++++++++++++++-----
>  1 file changed, 37 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
> index e1b17c05229c..ee170e999a88 100644
> --- a/drivers/media/platform/stm32/stm32-dcmi.c
> +++ b/drivers/media/platform/stm32/stm32-dcmi.c
> @@ -113,7 +113,7 @@ struct dcmi_framesize {
>  struct dcmi_buf {
>  	struct vb2_v4l2_buffer	vb;
>  	bool			prepared;
> -	dma_addr_t		paddr;
> +	struct sg_table		sgt;
>  	size_t			size;
>  	struct list_head	list;
>  };
> @@ -157,6 +157,7 @@ struct stm32_dcmi {
>  	enum state			state;
>  	struct dma_chan			*dma_chan;
>  	dma_cookie_t			dma_cookie;
> +	u32				dma_max_burst;
>  	u32				misr;
>  	int				errors_count;
>  	int				overrun_count;
> @@ -326,13 +327,11 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi,
>  	mutex_lock(&dcmi->dma_lock);
>  
>  	/* Prepare a DMA transaction */
> -	desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr,
> -					   buf->size,
> +	desc = dmaengine_prep_slave_sg(dcmi->dma_chan, buf->sgt.sgl, buf->sgt.nents,
>  					   DMA_DEV_TO_MEM,
>  					   DMA_PREP_INTERRUPT);
>  	if (!desc) {
> -		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n",
> -			__func__, &buf->paddr, buf->size);
> +		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_sg failed\n", __func__);
>  		mutex_unlock(&dcmi->dma_lock);
>  		return -EINVAL;
>  	}
> @@ -524,6 +523,10 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
>  	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
>  	struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb);
>  	unsigned long size;
> +	unsigned int num_sgs = 1;
> +	dma_addr_t dma_buf;
> +	struct scatterlist *sg;
> +	int i, ret;
>  
>  	size = dcmi->fmt.fmt.pix.sizeimage;
>  
> @@ -537,15 +540,33 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
>  
>  	if (!buf->prepared) {
>  		/* Get memory addresses */
> -		buf->paddr =
> -			vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
>  		buf->size = vb2_plane_size(&buf->vb.vb2_buf, 0);
> -		buf->prepared = true;
> +		if (buf->size > dcmi->dma_max_burst)
> +			num_sgs = DIV_ROUND_UP(buf->size, dcmi->dma_max_burst);
>  
> -		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
> +		ret = sg_alloc_table(&buf->sgt, num_sgs, GFP_ATOMIC);
> +		if (ret) {
> +			dev_err(dcmi->dev, "sg table alloc failed\n");
> +			return ret;
> +		}
> +
> +		dma_buf = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
>  
>  		dev_dbg(dcmi->dev, "buffer[%d] phy=%pad size=%zu\n",
> -			vb->index, &buf->paddr, buf->size);
> +			vb->index, &dma_buf, buf->size);
> +
> +		for_each_sg(buf->sgt.sgl, sg, num_sgs, i) {
> +			size_t bytes = min_t(size_t, size, dcmi->dma_max_burst);
> +
> +			sg_dma_address(sg) = dma_buf;
> +			sg_dma_len(sg) = bytes;
> +			dma_buf += bytes;
> +			size -= bytes;
> +		}
> +
> +		buf->prepared = true;
> +
> +		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
>  	}
>  
>  	return 0;
> @@ -1866,6 +1887,7 @@ static int dcmi_probe(struct platform_device *pdev)
>  	struct stm32_dcmi *dcmi;
>  	struct vb2_queue *q;
>  	struct dma_chan *chan;
> +	struct dma_slave_caps caps;
>  	struct clk *mclk;
>  	int irq;
>  	int ret = 0;
> @@ -1953,6 +1975,11 @@ static int dcmi_probe(struct platform_device *pdev)
>  		return ret;
>  	}
>  
> +	dcmi->dma_max_burst = UINT_MAX;
> +	ret = dma_get_slave_caps(chan, &caps);
> +	if (!ret && caps.max_sg_burst)
> +		dcmi->dma_max_burst = caps.max_sg_burst	* DMA_SLAVE_BUSWIDTH_4_BYTES;
> +
>  	spin_lock_init(&dcmi->irqlock);
>  	mutex_init(&dcmi->lock);
>  	mutex_init(&dcmi->dma_lock);
> -- 
> 2.25.1
> 


From frank-w at public-files.de  Mon Jan 24 00:55:05 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 24 Jan 2022 09:55:05 +0100
Subject: Aw: Re: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
In-Reply-To: <20220124083102.GW23490@pengutronix.de>
References: <20220123135116.136846-1-linux@fw-web.de>
 <20220123135116.136846-3-linux@fw-web.de>
 <20220124083102.GW23490@pengutronix.de>
Message-ID: <trinity-2e9cf5db-4c9b-4ad7-b684-74541e639edf-1643014505272@3c-app-gmx-bs10>

Hi

> Gesendet: Montag, 24. Januar 2022 um 09:31 Uhr
> Von: "Sascha Hauer" <sha at pengutronix.de>
> An: "Frank Wunderlich" <linux at fw-web.de>
> Cc: linux-rockchip at lists.infradead.org, "Frank Wunderlich" <frank-w at public-files.de>, "Rob Herring" <robh+dt at kernel.org>, "Heiko Stuebner" <heiko at sntech.de>, "Peter Geis" <pgwipeout at gmail.com>, "Johan Jonker" <jbx6244 at gmail.com>, devicetree at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> Betreff: Re: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
>
> On Sun, Jan 23, 2022 at 02:51:16PM +0100, Frank Wunderlich wrote:
> > From: Frank Wunderlich <frank-w at public-files.de>
> >
> > This patch adds Devicetree for Bananapi R2 Pro based on RK3568.
> > Add uart/sd/emmc/i2c/rk809/tsadc nodes for basic function.
> > Gmac0 is directly connected to wan-port so usable without additional
> > driver.
> > On gmac1 there is a switch (rtl8367rb) connected which have not yet a
> > driver in mainline.
> >
> > Patch also prepares nodes for GPIO header.
> >
> > Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> > ---
> > +&gmac0 {
> > +	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
> > +	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
> > +	clock_in_out = "input";
> > +	phy-handle = <&rgmii_phy0>;
> > +	phy-mode = "rgmii";
> > +	pinctrl-names = "default";
> > +	pinctrl-0 = <&gmac0_miim
> > +		     &gmac0_tx_bus2
> > +		     &gmac0_rx_bus2
> > +		     &gmac0_rgmii_clk
> > +		     &gmac0_rgmii_bus>;
> > +
> > +	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> > +	snps,reset-active-low;
> > +	/* Reset time is 20ms, 100ms for rtl8211f */
>
> Is this really a rtl8211f? I don't know and it could indeed be a
> rtl8211f, I'm just asking because the comment is copy pasted from
> the Quartz64 board.

i know thats a RTL8211 phy, but i see no additional letter on the chip, based on shematics it's a RTL8211F-CG

> > +	snps,reset-delays-us = <0 20000 100000>;
> > +
> > +&mdio0 {
> > +	rgmii_phy0: ethernet-phy at 0 {
> > +		compatible = "ethernet-phy-ieee802.3-c22";
> > +		reg = <0x0>;
> > +	};
>
> 0 is the broadcast address. I'm not sure if it's a good idea to use it.
> There should be another address the phy listens on.

took this from the 3568-EVB (like the most parts, as the board is mostly the same), and in linux it's the same and working. The switch have also phy-id 0 on mdio bus #1, are you sure this is invalid?

regards Frank


From tabba at google.com  Mon Jan 24 00:56:43 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 08:56:43 +0000
Subject: [PATCH] KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions
 on !VHE
In-Reply-To: <20220121184207.423426-1-maz@kernel.org>
References: <20220121184207.423426-1-maz@kernel.org>
Message-ID: <CA+EHjTzks6CpViFPc=xCq4SGpdiEPy_88L3MTjikmNA-9bC0Tg@mail.gmail.com>

Hi Marc,

On Fri, Jan 21, 2022 at 6:42 PM Marc Zyngier <maz at kernel.org> wrote:
>
> Injecting an exception into a guest with non-VHE is risky business.
> Instead of writing in the shadow register for the switch code to
> restore it, we override the CPU register instead. Which gets
> overriden a few instructions later by said restore code.

I see that in __sysreg_restore_el1_state(), which as you said is
called after __vcpu_write_spsr().

> The result is that although the guest correctly gets the exception,
> it will return to the original context in some random state,
> depending on what was there the first place... Boo.
>
> Fix the issue by writing to the shadow register. The original code
> is absolutely fine on VHE, as the state is already loaded, and writing
> to the shadow register in that case would actually be a bug.

Which happens via kvm_vcpu_load_sysregs_vhe() calling
__sysreg_restore_el1_state() before __vcpu_write_spsr() in this case.

Reviewed-by: Fuad Tabba <tabba at google.com>

Cheers,
/fuad


> Fixes: bb666c472ca2 ("KVM: arm64: Inject AArch64 exceptions from HYP")
> Cc: stable at vger.kernel.org
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
>  arch/arm64/kvm/hyp/exception.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> index 0418399e0a20..c5d009715402 100644
> --- a/arch/arm64/kvm/hyp/exception.c
> +++ b/arch/arm64/kvm/hyp/exception.c
> @@ -38,7 +38,10 @@ static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
>
>  static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
>  {
> -       write_sysreg_el1(val, SYS_SPSR);
> +       if (has_vhe())
> +               write_sysreg_el1(val, SYS_SPSR);
> +       else
> +               __vcpu_sys_reg(vcpu, SPSR_EL1) = val;
>  }
>
>  static void __vcpu_write_spsr_abt(struct kvm_vcpu *vcpu, u64 val)
> --
> 2.34.1
>


From pawel.jasinski at portyid.pl  Mon Jan 24 01:01:16 2022
From: pawel.jasinski at portyid.pl (=?UTF-8?Q? Pawe=C5=82_Jasi=C5=84ski ?=)
Date: Mon, 24 Jan 2022 09:01:16 GMT
Subject: Fotowoltaika - nowe warunki
Message-ID: <20220124084500-0.1.1b.5en9.0.coihf7841m@portyid.pl>

Dzie? dobry,

jeszcze w pierwszej po?owie 2022 roku wzrosn? ceny za wykup energii dla posiadaczy fotowoltaiki. 

Aby unikn?? umowy na nowych zasadach trzeba zdecydowa? si? na instalacj? paneli PV do ko?ca marca. 

Jako firma specjalizuj?ca si? w monta?u i serwisie fotowoltaiki ch?tnie podejmiemy si? realizacji ca?ego projektu. S? Pa?stwo zainteresowani?


Pozdrawiam
Pawe? Jasi?ski


From john.garry at huawei.com  Mon Jan 24 01:19:00 2022
From: john.garry at huawei.com (John Garry)
Date: Mon, 24 Jan 2022 09:19:00 +0000
Subject: Test 73 Sig_trap fails on arm64 (was Re: [PATCH] perf test: Test 73
 Sig_trap fails on s390)
In-Reply-To: <20220118124343.GC98966@leoy-ThinkPad-X240s>
References: <20211216151454.752066-1-tmricht@linux.ibm.com>
 <CANpmjNNMWtjcKa961SjEvRbbPXyw5M5SkrXbb3tnyL3_XyniCw@mail.gmail.com>
 <90efb5a9-612a-919e-cf2f-c528692d61e2@huawei.com>
 <20220118091827.GA98966@leoy-ThinkPad-X240s>
 <CANpmjNMPoU+1b1fKFuYDYwisW2YfjQHxGt5hgLp1tioG7C2jmg@mail.gmail.com>
 <20220118124343.GC98966@leoy-ThinkPad-X240s>
Message-ID: <bfa0af18-04ac-857d-d3d8-ad9290f912c8@huawei.com>

On 18/01/2022 12:43, Leo Yan wrote:

Hi Will,

Can you kindly check below the question from Leo on this issue?

You were cc'ed earlier in this thread so should be able to find more 
context, if needed.

Cheers,
John

> On Tue, Jan 18, 2022 at 12:40:04PM +0100, Marco Elver wrote:
> 
> [...]
> 
>>> Both Arm and Arm64 platforms cannot support signal handler with
>>> breakpoint, please see the details in [1].  So I think we need
>>> something like below:
>>>
>>> static int test__sigtrap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
>>> {
>>>          ...
>>>
>>>          if (!BP_SIGNAL_IS_SUPPORTED) {
>>>                  pr_debug("Test not supported on this architecture");
>>>                  return TEST_SKIP;
>>>          }
>>>
>>>          ...
>>> }
>>>
>>> Since we have defined BP_SIGNAL_IS_SUPPORTED, I think we can reuse it at
>>> here.
>>>
>>> [1]https://lore.kernel.org/lkml/157169993406.29376.12473771029179755767.tip-bot2 at tip-bot2/
>> Does this limitation also exist for address watchpoints? The sigtrap
>> test does not make use of instruction breakpoints, but instead just
>> sets up a watchpoint on access to a data address.
> Yes, after reading the code, the flow for either instrution breakpoint
> or watchpoint both use the single step [1], thus the signal handler will
> take the single step execution and lead to the infinite loop.
> 
> I am not the best person to answer this question; @Will, could you
> confirm for this?  Thanks!
> 
> Leo
> 
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/kernel/hw_breakpoint.c



From ck.hu at mediatek.com  Mon Jan 24 01:13:26 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Mon, 24 Jan 2022 17:13:26 +0800
Subject: [PATCH v14 09/12] soc: mediatek: add mtk-mutex support for
 mt8195 vdosys0
In-Reply-To: <20220107101425.6917-10-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-10-jason-jh.lin@mediatek.com>
Message-ID: <6e23ceaac55d64b7c74c5ce6d7114936354c2011.camel@mediatek.com>

Hi, Jason:

On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> Add mtk-mutex support for mt8195 vdosys0.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
> This patch is base on [1]
> [1] Add mmsys and mutex support for MDP
> - 
> https://patchwork.kernel.org/project/linux-mediatek/cover/20220104091712.25670-1-moudy.ho at mediatek.com/
> ---
>  drivers/soc/mediatek/mtk-mutex.c | 95
> +++++++++++++++++++++++++++++++-
>  1 file changed, 92 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/soc/mediatek/mtk-mutex.c
> b/drivers/soc/mediatek/mtk-mutex.c
> index 615c42260a50..89daab7e6863 100644
> --- a/drivers/soc/mediatek/mtk-mutex.c
> +++ b/drivers/soc/mediatek/mtk-mutex.c
> @@ -21,6 +21,9 @@
>  #define MT8183_MUTEX0_MOD0			0x30
>  #define MT8183_MUTEX0_SOF0			0x2c
>  
> +#define MT8195_DISP_MUTEX0_MOD0			0x30
> +#define MT8195_DISP_MUTEX0_SOF			0x2c
> +
>  #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
>  #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
>  #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 *
> (n))
> @@ -83,6 +86,36 @@
>  #define MT8173_MUTEX_MOD_DISP_PWM1		24
>  #define MT8173_MUTEX_MOD_DISP_OD		25
>  
> +#define MT8195_MUTEX_MOD_DISP_OVL0		0
> +#define MT8195_MUTEX_MOD_DISP_WDMA0		1
> +#define MT8195_MUTEX_MOD_DISP_RDMA0		2
> +#define MT8195_MUTEX_MOD_DISP_COLOR0		3
> +#define MT8195_MUTEX_MOD_DISP_CCORR0		4
> +#define MT8195_MUTEX_MOD_DISP_AAL0		5
> +#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
> +#define MT8195_MUTEX_MOD_DISP_DITHER0		7
> +#define MT8195_MUTEX_MOD_DISP_DSI0		8
> +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
> +#define MT8195_MUTEX_MOD_DISP_OVL1		10
> +#define MT8195_MUTEX_MOD_DISP_WDMA1		11
> +#define MT8195_MUTEX_MOD_DISP_RDMA1		12
> +#define MT8195_MUTEX_MOD_DISP_COLOR1		13
> +#define MT8195_MUTEX_MOD_DISP_CCORR1		14
> +#define MT8195_MUTEX_MOD_DISP_AAL1		15
> +#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
> +#define MT8195_MUTEX_MOD_DISP_DITHER1		17
> +#define MT8195_MUTEX_MOD_DISP_DSI1		18
> +#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
> +#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
> +#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
> +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
> +#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
> +#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
> +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
> +#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
> +#define MT8195_MUTEX_MOD_DISP_PWM0		27
> +#define MT8195_MUTEX_MOD_DISP_PWM1		28
> +
>  #define MT2712_MUTEX_MOD_DISP_PWM2		10
>  #define MT2712_MUTEX_MOD_DISP_OVL0		11
>  #define MT2712_MUTEX_MOD_DISP_OVL1		12
> @@ -119,9 +152,21 @@
>  #define MT8167_MUTEX_SOF_DPI1			3
>  #define MT8183_MUTEX_SOF_DSI0			1
>  #define MT8183_MUTEX_SOF_DPI0			2
> +#define MT8195_MUTEX_SOF_DSI0			1
> +#define MT8195_MUTEX_SOF_DSI1			2
> +#define MT8195_MUTEX_SOF_DP_INTF0		3
> +#define MT8195_MUTEX_SOF_DP_INTF1		4
> +#define MT8195_MUTEX_SOF_DPI0			6 /* for
> HDMI_TX */
> +#define MT8195_MUTEX_SOF_DPI1			5 /* for
> digital video out */
>  
>  #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_S
> OF_DSI0 << 6)
>  #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_S
> OF_DPI0 << 6)
> +#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_S
> OF_DSI0 << 7)
> +#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_S
> OF_DSI1 << 7)
> +#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_IN
> TF0 << 7)
> +#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_IN
> TF1 << 7)
> +#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_S
> OF_DPI0 << 7)
> +#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_S
> OF_DPI1 << 7)
>  
>  #define MT8183_MUTEX_MDP_START			5
>  #define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
> @@ -148,6 +193,9 @@ enum mtk_mutex_sof_id {
>  	MUTEX_SOF_DPI1,
>  	MUTEX_SOF_DSI2,
>  	MUTEX_SOF_DSI3,
> +	MUTEX_SOF_DP_INTF0,
> +	MUTEX_SOF_DP_INTF1,
> +	DDP_MUTEX_SOF_MAX,
>  };
>  
>  struct mtk_mutex_data {
> @@ -274,7 +322,23 @@ static const unsigned int
> mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>  	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
>  };
>  
> -static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> +	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
> +	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
> +	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
> +	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
> +	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
> +	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
> +	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
> +	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
> +	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
> +	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
> +	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
> +	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
> +	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
> +};
> +
> +static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>  	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>  	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
>  	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
> @@ -284,7 +348,7 @@ static const unsigned int
> mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
>  	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
>  };
>  
> -static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>  	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>  	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
>  	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
> @@ -292,7 +356,7 @@ static const unsigned int
> mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
>  };
>  
>  /* Add EOF setting so overlay hardware can receive frame done irq */
> -static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
>  	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
>  	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
>  	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 |
> MT8183_MUTEX_EOF_DPI0,
> @@ -306,6 +370,18 @@ static const unsigned int
> mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
>  	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
>  };
>  
> +static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> +	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> +	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 |
> MT8195_MUTEX_EOF_DSI0,
> +	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 |
> MT8195_MUTEX_EOF_DSI1,
> +	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 |
> MT8195_MUTEX_EOF_DPI0,
> +	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 |
> MT8195_MUTEX_EOF_DPI1,
> +	[MUTEX_SOF_DP_INTF0] =
> +		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,

Why add EOF? Add comment for this.

Regards,
CK

> +	[MUTEX_SOF_DP_INTF1] =
> +		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
> +};
> +
>  static const struct mtk_mutex_data mt2701_mutex_driver_data = {
>  	.mutex_mod = mt2701_mutex_mod,
>  	.mutex_sof = mt2712_mutex_sof,
> @@ -355,6 +431,13 @@ static const struct mtk_mutex_data
> mt8192_mutex_driver_data = {
>  	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
>  };
>  
> +static const struct mtk_mutex_data mt8195_mutex_driver_data = {
> +	.mutex_mod = mt8195_mutex_mod,
> +	.mutex_sof = mt8195_mutex_sof,
> +	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
> +	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
> +};
> +
>  struct mtk_mutex *mtk_mutex_get(struct device *dev)
>  {
>  	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
> @@ -442,6 +525,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
>  	case DDP_COMPONENT_DPI1:
>  		sof_id = MUTEX_SOF_DPI1;
>  		break;
> +	case DDP_COMPONENT_DP_INTF0:
> +		sof_id = MUTEX_SOF_DP_INTF0;
> +		break;
>  	default:
>  		if (mtx->data->mutex_mod[id] < 32) {
>  			offset = DISP_REG_MUTEX_MOD(mtx->data-
> >mutex_mod_reg,
> @@ -481,6 +567,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex
> *mutex,
>  	case DDP_COMPONENT_DSI3:
>  	case DDP_COMPONENT_DPI0:
>  	case DDP_COMPONENT_DPI1:
> +	case DDP_COMPONENT_DP_INTF0:
>  		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
>  			       mtx->regs +
>  			       DISP_REG_MUTEX_SOF(mtx->data-
> >mutex_sof_reg,
> @@ -678,6 +765,8 @@ static const struct of_device_id
> mutex_driver_dt_match[] = {
>  	  .data = &mt8183_mutex_driver_data},
>  	{ .compatible = "mediatek,mt8192-disp-mutex",
>  	  .data = &mt8192_mutex_driver_data},
> +	{ .compatible = "mediatek,mt8195-disp-mutex",
> +	  .data = &mt8195_mutex_driver_data},
>  	{},
>  };
>  MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);



From angelogioacchino.delregno at collabora.com  Mon Jan 24 01:26:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 10:26:18 +0100
Subject: [PATCH][next] usb: xhci-mtk: Use struct_size() helper in
 create_sch_ep()
In-Reply-To: <20220120015546.GA75917@embeddedor>
References: <20220120015546.GA75917@embeddedor>
Message-ID: <1e41c2fe-38b2-e7db-ec71-cab1abb708f3@collabora.com>

Il 20/01/22 02:55, Gustavo A. R. Silva ha scritto:
> Make use of the struct_size() helper instead of an open-coded version,
> in order to avoid any potential type mistakes or integer overflows that,
> in the worst scenario, could lead to heap overflows.
> 
> Also, address the following sparse warnings:
> drivers/usb/host/xhci-mtk-sch.c:265:20: warning: using sizeof on a flexible structure
> 
> Link: https://github.com/KSPP/linux/issues/160
> Link: https://github.com/KSPP/linux/issues/174
> Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> Acked-by: Chunfeng Yun <chunfeng.yun at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From leo.yan at linaro.org  Mon Jan 24 01:29:28 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Mon, 24 Jan 2022 17:29:28 +0800
Subject: [PATCH v2 0/7] pid: Introduce helper task_is_in_root_ns()
In-Reply-To: <20220112064046.GA3316542@leoy-ThinkPad-X240s>
References: <20211208083320.472503-1-leo.yan@linaro.org>
 <20220112064046.GA3316542@leoy-ThinkPad-X240s>
Message-ID: <20220124092928.GA1167041@leoy-ThinkPad-X240s>

On Wed, Jan 12, 2022 at 02:40:47PM +0800, Leo Yan wrote:
> Hi David,
> 
> On Wed, Dec 08, 2021 at 04:33:13PM +0800, Leo Yan wrote:
> > The kernel uses open code to check if a process is in root PID namespace
> > or not in several places.
> > 
> > Suggested by Suzuki, this patch set is to create a helper function
> > task_is_in_init_pid_ns() to replace open code.
> > 
> > This patch set has been applied on the mainline kernel and built for
> > Arm64 kernel with enabling all relevant modules.
> 
> I'd like sync for how to merging this patch set.  Except patch 05/07,
> all of other patches in this patch set have been received the reviewed
> or acked tags.  So could you pick up this patch set?
> 
> Furthermore, we have another patch set "coresight: etm: Correct PID
> tracing for non-root namespace" [1], which is dependent on the current
> patch set and it has been Acked by Suzuki.
> 
> I'd like to get opinions from David and CoreSight maintainers Mathieu
> and Suzuki, should we merge the patch set [1] via David's tree as well
> to avoid dependency issue, or prefer to merge it via CoreSight tree?
> If David prefers the prior option, I can resend the patch set [1] with
> looping David.

Gentle ping, Dave.

I verified the current patch set and CoreSight patch set, both can apply
clearly on the latest mainline kernel (with last commit
dd81e1c7d5fb "Merge tag 'powerpc-5.17-2' of
git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux").

Thanks,
Leo

> [1] https://lore.kernel.org/lkml/20211213121323.1887180-1-leo.yan at linaro.org/


From jammy_huang at aspeedtech.com  Mon Jan 24 01:33:43 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 17:33:43 +0800
Subject: [PATCH v3 2/4] media: aspeed: Use FIELD_GET to improve readability
In-Reply-To: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
References: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
Message-ID: <20220124093345.3935-3-jammy_huang@aspeedtech.com>

Use the bitfield macro FIELD_GET, and GENMASK to do the shift and mask in
one go for reg values.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 v3:
  - no update
 v2:
  - Put some codes on one line
---
 drivers/media/platform/aspeed-video.c | 31 +++++++++++----------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index d5f77b205175..c241038ee27c 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -156,26 +156,22 @@
 #define  VE_SRC_LR_EDGE_DET_NO_H	BIT(13)
 #define  VE_SRC_LR_EDGE_DET_NO_DISP	BIT(14)
 #define  VE_SRC_LR_EDGE_DET_NO_CLK	BIT(15)
-#define  VE_SRC_LR_EDGE_DET_RT_SHF	16
-#define  VE_SRC_LR_EDGE_DET_RT		GENMASK(27, VE_SRC_LR_EDGE_DET_RT_SHF)
+#define  VE_SRC_LR_EDGE_DET_RT		GENMASK(27, 16)
 #define  VE_SRC_LR_EDGE_DET_INTERLACE	BIT(31)
 
 #define VE_SRC_TB_EDGE_DET		0x094
 #define  VE_SRC_TB_EDGE_DET_TOP		GENMASK(12, 0)
-#define  VE_SRC_TB_EDGE_DET_BOT_SHF	16
-#define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
+#define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, 16)
 
 #define VE_MODE_DETECT_STATUS		0x098
 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
-#define  VE_MODE_DETECT_V_LINES_SHF	16
-#define  VE_MODE_DETECT_V_LINES		GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
+#define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
 
 #define VE_SYNC_STATUS			0x09c
 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
-#define  VE_SYNC_STATUS_VSYNC_SHF	16
-#define  VE_SYNC_STATUS_VSYNC		GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
+#define  VE_SYNC_STATUS_VSYNC		GENMASK(27, 16)
 
 #define VE_H_TOTAL_PIXELS		0x0A0
 
@@ -988,23 +984,20 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 		sync = aspeed_video_read(video, VE_SYNC_STATUS);
 		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
-		video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
-			VE_SRC_TB_EDGE_DET_BOT_SHF;
-		video->frame_top = src_tb_edge & VE_SRC_TB_EDGE_DET_TOP;
+		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
+		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
 		det->vfrontporch = video->frame_top;
-		det->vbackporch = ((mds & VE_MODE_DETECT_V_LINES) >>
-			VE_MODE_DETECT_V_LINES_SHF) - video->frame_bottom;
-		det->vsync = (sync & VE_SYNC_STATUS_VSYNC) >>
-			VE_SYNC_STATUS_VSYNC_SHF;
+		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
+			video->frame_bottom;
+		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
 		if (video->frame_top > video->frame_bottom)
 			continue;
 
-		video->frame_right = (src_lr_edge & VE_SRC_LR_EDGE_DET_RT) >>
-			VE_SRC_LR_EDGE_DET_RT_SHF;
-		video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
+		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
+		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
 		det->hfrontporch = video->frame_left;
 		det->hbackporch = htotal - video->frame_right;
-		det->hsync = sync & VE_SYNC_STATUS_HSYNC;
+		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
 		if (video->frame_left > video->frame_right)
 			continue;
 
-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 01:33:44 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 17:33:44 +0800
Subject: [PATCH v3 3/4] media: aspeed: Correct values for detected timing
In-Reply-To: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
References: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
Message-ID: <20220124093345.3935-4-jammy_huang@aspeedtech.com>

Correct timing's fp/sync/bp value based on the information below.
It should be noticed that the calculation formula should be changed
per sync polarity.

The sequence of signal: sync - backporch - video data - frontporch

The following registers start counting from sync's rising edge:
1. VR090: frame edge's left and right
2. VR094: frame edge's top and bottom
3. VR09C: counting from sync's rising edge to falling edge

[Vertical timing]
            +--+     +-------------------+     +--+
            |  |     |     v i d e o     |     |  |
         +--+  +-----+                   +-----+  +---+
       vsync+--+
   frame_top+--------+
frame_bottom+----------------------------+

                  +-------------------+
                  |     v i d e o     |
      +--+  +-----+                   +-----+  +---+
         |  |                               |  |
         +--+                               +--+
       vsync+-------------------------------+
   frame_top+-----+
frame_bottom+-------------------------+

[Horizontal timing]
            +--+     +-------------------+     +--+
            |  |     |     v i d e o     |     |  |
         +--+  +-----+                   +-----+  +---+
       hsync+--+
  frame_left+--------+
 frame_right+----------------------------+

                  +-------------------+
                  |     v i d e o     |
      +--+  +-----+                   +-----+  +---+
         |  |                               |  |
         +--+                               +--+
       hsync+-------------------------------+
  frame_left+-----+
 frame_right+-------------------------+

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 v3:
  - Add API, aspeed_video_get_timings(), to handle the calculation of timings.
 v2:
  - Code refined per Joel's suggestion
  - Update commit message to have name matching variable
---
 drivers/media/platform/aspeed-video.c | 30 ++++++++++++++++++++-------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index c241038ee27c..7e988cd05161 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -925,6 +925,87 @@ static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
 		 video->max_compressed_size);
 }
 
+/*
+ * Update v4l2_bt_timings per current status.
+ * frame_top/frame_bottom/frame_left/frame_right need to be ready.
+ *
+ * The following registers start counting from sync's rising edge:
+ * 1. VR090: frame edge's left and right
+ * 2. VR094: frame edge's top and bottom
+ * 3. VR09C: counting from sync's rising edge to falling edge
+ *
+ * [Vertical timing]
+ *             +--+     +-------------------+     +--+
+ *             |  |     |     v i d e o     |     |  |
+ *          +--+  +-----+                   +-----+  +---+
+ *        vsync+--+
+ *    frame_top+--------+
+ * frame_bottom+----------------------------+
+ *
+ *                   +-------------------+
+ *                   |     v i d e o     |
+ *       +--+  +-----+                   +-----+  +---+
+ *          |  |                               |  |
+ *          +--+                               +--+
+ *        vsync+-------------------------------+
+ *    frame_top+-----+
+ * frame_bottom+-------------------------+
+ *
+ * [Horizontal timing]
+ *             +--+     +-------------------+     +--+
+ *             |  |     |     v i d e o     |     |  |
+ *          +--+  +-----+                   +-----+  +---+
+ *        hsync+--+
+ *   frame_left+--------+
+ *  frame_right+----------------------------+
+ *
+ *                   +-------------------+
+ *                   |     v i d e o     |
+ *       +--+  +-----+                   +-----+  +---+
+ *          |  |                               |  |
+ *          +--+                               +--+
+ *        hsync+-------------------------------+
+ *   frame_left+-----+
+ *  frame_right+-------------------------+
+ *
+ * @v: the struct of aspeed_video
+ * @det: v4l2_bt_timings to be updated.
+ */
+static void aspeed_video_get_timings(struct aspeed_video *v,
+				     struct v4l2_bt_timings *det)
+{
+	u32 mds, sync, htotal, vtotal, vsync, hsync;
+
+	mds = aspeed_video_read(v, VE_MODE_DETECT_STATUS);
+	sync = aspeed_video_read(v, VE_SYNC_STATUS);
+	htotal = aspeed_video_read(v, VE_H_TOTAL_PIXELS);
+	vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
+	vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
+	hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
+
+	if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
+		det->vbackporch = v->frame_top - vsync;
+		det->vfrontporch = vtotal - v->frame_bottom;
+		det->vsync = vsync;
+	} else {
+		det->vbackporch = v->frame_top;
+		det->vfrontporch = vsync - v->frame_bottom;
+		det->vsync = vtotal - vsync;
+	}
+
+	if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
+		det->hbackporch = v->frame_left - hsync;
+		det->hfrontporch = htotal - v->frame_right;
+		det->hsync = hsync;
+	} else {
+		det->hbackporch = v->frame_left;
+		det->hfrontporch = hsync - v->frame_right;
+		det->hsync = htotal - hsync;
+	}
+}
+
 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
 
 static void aspeed_video_get_resolution(struct aspeed_video *video)
@@ -935,8 +1016,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	u32 mds;
 	u32 src_lr_edge;
 	u32 src_tb_edge;
-	u32 sync;
-	u32 htotal;
 	struct v4l2_bt_timings *det = &video->detected_timings;
 
 	det->width = MIN_WIDTH;
@@ -980,24 +1059,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 
 		src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
 		src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
-		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
-		sync = aspeed_video_read(video, VE_SYNC_STATUS);
-		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
 		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
 		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
-		det->vfrontporch = video->frame_top;
-		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
-			video->frame_bottom;
-		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
+
 		if (video->frame_top > video->frame_bottom)
 			continue;
 
 		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
 		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
-		det->hfrontporch = video->frame_left;
-		det->hbackporch = htotal - video->frame_right;
-		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
+
 		if (video->frame_left > video->frame_right)
 			continue;
 
@@ -1013,6 +1084,8 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	det->width = (video->frame_right - video->frame_left) + 1;
 	video->v4l2_input_status = 0;
 
+	aspeed_video_get_timings(video, det);
+
 	/*
 	 * Enable mode-detect watchdog, resolution-change watchdog and
 	 * automatic compression after frame capture.
-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 01:33:41 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 17:33:41 +0800
Subject: [PATCH v3 0/4] Correct timing report
Message-ID: <20220124093345.3935-1-jammy_huang@aspeedtech.com>

This series will correct the value of timing detected.

Changes in v3:
 - Add API, aspeed_video_get_timings(), for the calculation of timings
 - Use active rather than 'total/2' as critera for sync polarity workaround
Changes in v2:
 - code refined to improve readability

Jammy Huang (4):
  media: aspeed: Correct value for h-total-pixels
  media: aspeed: Use FIELD_GET to improve readability
  media: aspeed: Correct values for detected timing
  media: aspeed: Fix timing polarity incorrect

 drivers/media/platform/aspeed-video.c | 139 ++++++++++++++++++++------
 1 file changed, 111 insertions(+), 28 deletions(-)

-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 01:33:45 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 17:33:45 +0800
Subject: [PATCH v3 4/4] media: aspeed: Fix timing polarity incorrect
In-Reply-To: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
References: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
Message-ID: <20220124093345.3935-5-jammy_huang@aspeedtech.com>

This is a workaround for polarity detection unstable.
Because h/v sync polarity got from VR098 could be wrong, we try to use
ast SoC's characteristic to confirm sync polarity.

In ast SoC's design, sync value got by VR09C counts from sync's rising
edge, which means sync value = bp + active + fp if negative polarity.
Thus, sync value would be larger than de if negative.

Ex. 1920x1200 at 60
  VR098: c4d3efff, VR09C: 04cc001f
  v-total = 0x4D3 (VR098[27:16]) = 1235
  v-sync  = 0x4CC (VR09C[27:16]) = 1228

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 v3:
  - Use active rather than 'total/2' as critera for workaround
 v2:
  - Use 'total/2' rather than 'total<<1'
  - Update comment
---
 drivers/media/platform/aspeed-video.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 7e988cd05161..a135a31b4234 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -985,6 +985,20 @@ static void aspeed_video_get_timings(struct aspeed_video *v,
 	vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
 	hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
 
+	/*
+	 * This is a workaround for polarity detection.
+	 * Because ast-soc counts sync from sync's rising edge, the reg value
+	 * of sync would be larger than video's active area if negative.
+	 */
+	if (vsync > det->height)
+		det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
+	else
+		det->polarities |= V4L2_DV_VSYNC_POS_POL;
+	if (hsync > det->width)
+		det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
+	else
+		det->polarities |= V4L2_DV_HSYNC_POS_POL;
+
 	if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
 		det->vbackporch = v->frame_top - vsync;
 		det->vfrontporch = vtotal - v->frame_bottom;
-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 01:33:42 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Mon, 24 Jan 2022 17:33:42 +0800
Subject: [PATCH v3 1/4] media: aspeed: Correct value for h-total-pixels
In-Reply-To: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
References: <20220124093345.3935-1-jammy_huang@aspeedtech.com>
Message-ID: <20220124093345.3935-2-jammy_huang@aspeedtech.com>

Previous reg-field, 0x98[11:0], stands for the period of the detected
hsync signal.
Use the correct reg, 0xa0, to get h-total in pixels.

Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver")
Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
v3:
 - no update
v2:
 - no update
---
 drivers/media/platform/aspeed-video.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index b388bc56ce81..d5f77b205175 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -166,7 +166,7 @@
 #define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
 
 #define VE_MODE_DETECT_STATUS		0x098
-#define  VE_MODE_DETECT_H_PIXELS	GENMASK(11, 0)
+#define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
 #define  VE_MODE_DETECT_V_LINES_SHF	16
 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
@@ -177,6 +177,8 @@
 #define  VE_SYNC_STATUS_VSYNC_SHF	16
 #define  VE_SYNC_STATUS_VSYNC		GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
 
+#define VE_H_TOTAL_PIXELS		0x0A0
+
 #define VE_INTERRUPT_CTRL		0x304
 #define VE_INTERRUPT_STATUS		0x308
 #define  VE_INTERRUPT_MODE_DETECT_WD	BIT(0)
@@ -938,6 +940,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	u32 src_lr_edge;
 	u32 src_tb_edge;
 	u32 sync;
+	u32 htotal;
 	struct v4l2_bt_timings *det = &video->detected_timings;
 
 	det->width = MIN_WIDTH;
@@ -983,6 +986,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 		src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
 		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
 		sync = aspeed_video_read(video, VE_SYNC_STATUS);
+		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
 		video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
 			VE_SRC_TB_EDGE_DET_BOT_SHF;
@@ -999,8 +1003,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 			VE_SRC_LR_EDGE_DET_RT_SHF;
 		video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
 		det->hfrontporch = video->frame_left;
-		det->hbackporch = (mds & VE_MODE_DETECT_H_PIXELS) -
-			video->frame_right;
+		det->hbackporch = htotal - video->frame_right;
 		det->hsync = sync & VE_SYNC_STATUS_HSYNC;
 		if (video->frame_left > video->frame_right)
 			continue;
-- 
2.25.1



From greg at kroah.com  Mon Jan 24 01:41:42 2022
From: greg at kroah.com (Greg KH)
Date: Mon, 24 Jan 2022 10:41:42 +0100
Subject: [PATCH] crypto: stm32/crc32 - Fix kernel BUG triggered in probe()
In-Reply-To: <20220123162240.5532-1-marex@denx.de>
References: <16429542415161@kroah.com>
 <20220123162240.5532-1-marex@denx.de>
Message-ID: <Ye50VjsyOdhxN/9W@kroah.com>

On Sun, Jan 23, 2022 at 05:22:40PM +0100, Marek Vasut wrote:
> The include/linux/crypto.h struct crypto_alg field cra_driver_name description
> states "Unique name of the transformation provider. " ... " this contains the
> name of the chip or provider and the name of the transformation algorithm."
> 
> In case of the stm32-crc driver, field cra_driver_name is identical for all
> registered transformation providers and set to the name of the driver itself,
> which is incorrect. This patch fixes it by assigning a unique cra_driver_name
> to each registered transformation provider.
> 
> The kernel crash is triggered when the driver calls crypto_register_shashes()
> which calls crypto_register_shash(), which calls crypto_register_alg(), which
> calls __crypto_register_alg(), which returns -EEXIST, which is propagated
> back through this call chain. Upon -EEXIST from crypto_register_shash(), the
> crypto_register_shashes() starts unregistering the providers back, and calls
> crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
> where the BUG() triggers due to incorrect cra_refcnt.
> 
> Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: <stable at vger.kernel.org> # 4.12+
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Fabien Dessenne <fabien.dessenne at st.com>
> Cc: Herbert Xu <herbert at gondor.apana.org.au>
> Cc: Lionel Debieve <lionel.debieve at st.com>
> Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-crypto at vger.kernel.org
> Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
> Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
> ---
> Backport on 4.19.225, likely works on 4.14 too.
> The patch likely failed to apply because the hit 5.3:
> fdbd643a74efb ("crypto: stm32/crc32 - rename driver file")
> and renamed drivers/crypto/stm32/stm32{-,_}crc32.c
> ---
>  drivers/crypto/stm32/stm32_crc32.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Now queued up, thanks.

greg k-h


From greg at kroah.com  Mon Jan 24 01:42:45 2022
From: greg at kroah.com (Greg KH)
Date: Mon, 24 Jan 2022 10:42:45 +0100
Subject: [PATCH v1 1/1] ASoC: dpcm: prevent snd_soc_dpcm use after free
In-Reply-To: <20220121231644.1732744-1-willmcvicker@google.com>
References: <20220121231644.1732744-1-willmcvicker@google.com>
Message-ID: <Ye50ldr/4/TW7S/3@kroah.com>

On Fri, Jan 21, 2022 at 11:16:44PM +0000, Will McVicker wrote:
> From: KaiChieh Chuang <kaichieh.chuang at mediatek.com>
> 
> [ Upstream commit a9764869779081e8bf24da07ac040e8f3efcf13a ]
> 
> The dpcm get from fe_clients/be_clients
> may be free before use
> 
> Add a spin lock at snd_soc_card level,
> to protect the dpcm instance.
> The lock may be used in atomic context, so use spin lock.
> 
> Use irq spin lock version,
> since the lock may be used in interrupts.
> 
> possible race condition between
> void dpcm_be_disconnect(
> 	...
> 	list_del(&dpcm->list_be);
> 	list_del(&dpcm->list_fe);
> 	kfree(dpcm);
> 	...
> 
> and
> 	for_each_dpcm_fe()
> 	for_each_dpcm_be*()
> 
> race condition example
> Thread 1:
>     snd_soc_dapm_mixer_update_power()
>         -> soc_dpcm_runtime_update()
>             -> dpcm_be_disconnect()
>                 -> kfree(dpcm);
> Thread 2:
>     dpcm_fe_dai_trigger()
>         -> dpcm_be_dai_trigger()
>             -> snd_soc_dpcm_can_be_free_stop()
>                 -> if (dpcm->fe == fe)
> 
> Excpetion Scenario:
> 	two FE link to same BE
> 	FE1 -> BE
> 	FE2 ->
> 
> 	Thread 1: switch of mixer between FE2 -> BE
> 	Thread 2: pcm_stop FE1
> 
> Exception:
> 
> Unable to handle kernel paging request at virtual address dead0000000000e0
> 
> pc=<> [<ffffff8960e2cd10>] dpcm_be_dai_trigger+0x29c/0x47c
> 	sound/soc/soc-pcm.c:3226
> 		if (dpcm->fe == fe)
> lr=<> [<ffffff8960e2f694>] dpcm_fe_dai_do_trigger+0x94/0x26c
> 
> Backtrace:
> [<ffffff89602dba80>] notify_die+0x68/0xb8
> [<ffffff896028c7dc>] die+0x118/0x2a8
> [<ffffff89602a2f84>] __do_kernel_fault+0x13c/0x14c
> [<ffffff89602a27f4>] do_translation_fault+0x64/0xa0
> [<ffffff8960280cf8>] do_mem_abort+0x4c/0xd0
> [<ffffff8960282ad0>] el1_da+0x24/0x40
> [<ffffff8960e2cd10>] dpcm_be_dai_trigger+0x29c/0x47c
> [<ffffff8960e2f694>] dpcm_fe_dai_do_trigger+0x94/0x26c
> [<ffffff8960e2edec>] dpcm_fe_dai_trigger+0x3c/0x44
> [<ffffff8960de5588>] snd_pcm_do_stop+0x50/0x5c
> [<ffffff8960dded24>] snd_pcm_action+0xb4/0x13c
> [<ffffff8960ddfdb4>] snd_pcm_drop+0xa0/0x128
> [<ffffff8960de69bc>] snd_pcm_common_ioctl+0x9d8/0x30f0
> [<ffffff8960de1cac>] snd_pcm_ioctl_compat+0x29c/0x2f14
> [<ffffff89604c9d60>] compat_SyS_ioctl+0x128/0x244
> [<ffffff8960283740>] el0_svc_naked+0x34/0x38
> [<ffffffffffffffff>] 0xffffffffffffffff
> 
> Signed-off-by: KaiChieh Chuang <kaichieh.chuang at mediatek.com>
> Signed-off-by: Mark Brown <broonie at kernel.org>
> [willmcvicker: move spinlock to bottom of struct snd_soc_card]
> Signed-off-by: Will McVicker <willmcvicker at google.com>
> Cc: stable at vger.kernel.org # 4.19+
> ---
>  include/sound/soc.h  |  2 ++
>  sound/soc/soc-core.c |  1 +
>  sound/soc/soc-pcm.c  | 40 +++++++++++++++++++++++++++++++++-------
>  3 files changed, 36 insertions(+), 7 deletions(-)

Now queued up, thanks.

greg k-h


From arend.vanspriel at broadcom.com  Mon Jan 24 01:43:24 2022
From: arend.vanspriel at broadcom.com (Arend van Spriel)
Date: Mon, 24 Jan 2022 10:43:24 +0100
Subject: [PATCH RFC 1/4] brcmfmac: use separate firmware for 43430
 revision 4
In-Reply-To: <8ed4450d-85d9-c69b-761a-7695b3f1bbb3@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
 <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>
 <8ed4450d-85d9-c69b-761a-7695b3f1bbb3@i2se.com>
Message-ID: <dff5f86f-d6a5-f197-3c90-3b77d06991ce@broadcom.com>

On 1/22/2022 1:35 PM, Stefan Wahren wrote:
> Am 01.01.22 um 21:26 schrieb Stefan Wahren:
>> A separate firmware is needed, for Broadcom 43430 revision 4. This
>> chip can be found on e.g. certain revisions of Raspberry Pi Zero 2 W.
>> Original firmware file from IC vendor is named 'brcmfmac43436-sdio.bin',
>> but brcmfmac and also btbcm drivers report chip id 43430, so requested
>> firmware file name is 'brcmfmac43430c0-sdio.bin' in line with other
>> 43430 revisions.
>>
>> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
>> ---
>>
>> Hi,
>> i'm not sure about all these mappings. All i can say is that the wifi
>> interface of the RPi Zero 2 cames up with this patch.
> gentle ping (yes, i'm aware of the merge window)

Sorry, Stefan

Should have seen this earlier, but here it is....

>>
>>   drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
>>   1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>> index 8effeb7..c79bd47 100644
>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>> @@ -618,6 +618,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
>>   /* Note the names are not postfixed with a1 for backward compatibility */
>>   BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
>>   BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
>> +BRCMF_FW_CLM_DEF(43430C0, "brcmfmac43430c0-sdio");
>>   BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
>>   BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
>>   BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
>> @@ -649,7 +650,8 @@ static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
>>   	BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
>>   	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
>>   	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
>> -	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
>> +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43430C0),

According to the revision mask your firmware seems to be for numerical 
revision 2 of this chip...

>> +	BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFF8, 43430B0),

and for the b0 the chip revision is 3 (or higher). So the alphanumeric 
revision of your chip would be 'a2' instead of 'c0'.

>>   	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456),
>>   	BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455),
>>   	BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4219 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/9402a409/attachment-0001.p7s>

From alain.volmat at foss.st.com  Mon Jan 24 01:44:14 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Mon, 24 Jan 2022 10:44:14 +0100
Subject: [PATCH v2] media: stm32: dcmi: create a dma scatterlist based on DMA
 max_sg_burst value
Message-ID: <20220124094414.875302-1-alain.volmat@foss.st.com>

Prior to submitting a transfer to the DMA, the client should first check
the capabilities of the DMA channel in term of maximum of each segment.
This is given by the max_sg_burst value reported by dma_get_slave_caps API.
Based on that, if the transfer is larger than what can be handled by the
DMA channel, we split the transfer into several scatterlist elements.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
v2: add sg_free_table as part of buf_cleanup
    fix checkpatch alignment warning

 drivers/media/platform/stm32/stm32-dcmi.c | 60 ++++++++++++++++++-----
 1 file changed, 48 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index e1b17c05229c..5bc099c3dbca 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -113,7 +113,7 @@ struct dcmi_framesize {
 struct dcmi_buf {
 	struct vb2_v4l2_buffer	vb;
 	bool			prepared;
-	dma_addr_t		paddr;
+	struct sg_table		sgt;
 	size_t			size;
 	struct list_head	list;
 };
@@ -157,6 +157,7 @@ struct stm32_dcmi {
 	enum state			state;
 	struct dma_chan			*dma_chan;
 	dma_cookie_t			dma_cookie;
+	u32				dma_max_burst;
 	u32				misr;
 	int				errors_count;
 	int				overrun_count;
@@ -326,13 +327,10 @@ static int dcmi_start_dma(struct stm32_dcmi *dcmi,
 	mutex_lock(&dcmi->dma_lock);
 
 	/* Prepare a DMA transaction */
-	desc = dmaengine_prep_slave_single(dcmi->dma_chan, buf->paddr,
-					   buf->size,
-					   DMA_DEV_TO_MEM,
-					   DMA_PREP_INTERRUPT);
+	desc = dmaengine_prep_slave_sg(dcmi->dma_chan, buf->sgt.sgl, buf->sgt.nents,
+				       DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);
 	if (!desc) {
-		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_single failed for buffer phy=%pad size=%zu\n",
-			__func__, &buf->paddr, buf->size);
+		dev_err(dcmi->dev, "%s: DMA dmaengine_prep_slave_sg failed\n", __func__);
 		mutex_unlock(&dcmi->dma_lock);
 		return -EINVAL;
 	}
@@ -524,6 +522,10 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb);
 	unsigned long size;
+	unsigned int num_sgs = 1;
+	dma_addr_t dma_buf;
+	struct scatterlist *sg;
+	int i, ret;
 
 	size = dcmi->fmt.fmt.pix.sizeimage;
 
@@ -537,15 +539,33 @@ static int dcmi_buf_prepare(struct vb2_buffer *vb)
 
 	if (!buf->prepared) {
 		/* Get memory addresses */
-		buf->paddr =
-			vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
 		buf->size = vb2_plane_size(&buf->vb.vb2_buf, 0);
-		buf->prepared = true;
+		if (buf->size > dcmi->dma_max_burst)
+			num_sgs = DIV_ROUND_UP(buf->size, dcmi->dma_max_burst);
 
-		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
+		ret = sg_alloc_table(&buf->sgt, num_sgs, GFP_ATOMIC);
+		if (ret) {
+			dev_err(dcmi->dev, "sg table alloc failed\n");
+			return ret;
+		}
+
+		dma_buf = vb2_dma_contig_plane_dma_addr(&buf->vb.vb2_buf, 0);
 
 		dev_dbg(dcmi->dev, "buffer[%d] phy=%pad size=%zu\n",
-			vb->index, &buf->paddr, buf->size);
+			vb->index, &dma_buf, buf->size);
+
+		for_each_sg(buf->sgt.sgl, sg, num_sgs, i) {
+			size_t bytes = min_t(size_t, size, dcmi->dma_max_burst);
+
+			sg_dma_address(sg) = dma_buf;
+			sg_dma_len(sg) = bytes;
+			dma_buf += bytes;
+			size -= bytes;
+		}
+
+		buf->prepared = true;
+
+		vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
 	}
 
 	return 0;
@@ -579,6 +599,15 @@ static void dcmi_buf_queue(struct vb2_buffer *vb)
 	spin_unlock_irq(&dcmi->irqlock);
 }
 
+static void dcmi_buf_cleanup(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct dcmi_buf *buf = container_of(vbuf, struct dcmi_buf, vb);
+
+	if (buf->prepared)
+		sg_free_table(&buf->sgt);
+}
+
 static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi)
 {
 	struct media_entity *entity = &dcmi->vdev->entity;
@@ -914,6 +943,7 @@ static const struct vb2_ops dcmi_video_qops = {
 	.buf_init		= dcmi_buf_init,
 	.buf_prepare		= dcmi_buf_prepare,
 	.buf_queue		= dcmi_buf_queue,
+	.buf_cleanup		= dcmi_buf_cleanup,
 	.start_streaming	= dcmi_start_streaming,
 	.stop_streaming		= dcmi_stop_streaming,
 	.wait_prepare		= vb2_ops_wait_prepare,
@@ -1866,6 +1896,7 @@ static int dcmi_probe(struct platform_device *pdev)
 	struct stm32_dcmi *dcmi;
 	struct vb2_queue *q;
 	struct dma_chan *chan;
+	struct dma_slave_caps caps;
 	struct clk *mclk;
 	int irq;
 	int ret = 0;
@@ -1953,6 +1984,11 @@ static int dcmi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	dcmi->dma_max_burst = UINT_MAX;
+	ret = dma_get_slave_caps(chan, &caps);
+	if (!ret && caps.max_sg_burst)
+		dcmi->dma_max_burst = caps.max_sg_burst	* DMA_SLAVE_BUSWIDTH_4_BYTES;
+
 	spin_lock_init(&dcmi->irqlock);
 	mutex_init(&dcmi->lock);
 	mutex_init(&dcmi->dma_lock);
-- 
2.25.1



From gregkh at linuxfoundation.org  Mon Jan 24 01:48:20 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 24 Jan 2022 10:48:20 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 4.14-stable tree
Message-ID: <1643017700222194@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32_crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32_crc32.c
+++ b/drivers/crypto/stm32/stm32_crc32.c
@@ -206,7 +206,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -228,7 +228,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-4.14/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From gregkh at linuxfoundation.org  Mon Jan 24 01:48:40 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Mon, 24 Jan 2022 10:48:40 +0100
Subject: Patch "crypto: stm32/crc32 - Fix kernel BUG triggered in probe()" has
 been added to the 4.19-stable tree
Message-ID: <164301772032238@kroah.com>


This is a note to let you know that I've just added the patch titled

    crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

to the 4.19-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch
and it can be found in the queue-4.19 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From 29009604ad4e3ef784fd9b9fef6f23610ddf633d Mon Sep 17 00:00:00 2001
From: Marek Vasut <marex at denx.de>
Date: Mon, 20 Dec 2021 20:50:22 +0100
Subject: crypto: stm32/crc32 - Fix kernel BUG triggered in probe()

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32_crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32_crc32.c
+++ b/drivers/crypto/stm32/stm32_crc32.c
@@ -230,7 +230,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -252,7 +252,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,


Patches currently in stable-queue which might be from marex at denx.de are

queue-4.19/crypto-stm32-cryp-fix-double-pm-exit.patch
queue-4.19/crypto-stm32-crc32-fix-kernel-bug-triggered-in-probe.patch


From catalin.marinas at arm.com  Mon Jan 24 01:56:05 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 24 Jan 2022 09:56:05 +0000
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
In-Reply-To: <20220122023447.1480995-1-eugenis@google.com>
References: <20220122023447.1480995-1-eugenis@google.com>
Message-ID: <Ye53tbiEt9Z1Jf9/@arm.com>

On Fri, Jan 21, 2022 at 06:34:47PM -0800, Evgenii Stepanov wrote:
> ex_handler_load_unaligned_zeropad extracts the source and data register
> numbers from the wrong field of the exception table.

Could you please also include the stack dump if you get one from the
null pointer dereference?

> Fixes: 753b3236

This should be expanded:

Fixes: 753b32368705 ("arm64: extable: add load_unaligned_zeropad() handler")
Cc: <stable at vger.kernel.org> # 5.16.x

Thanks.

-- 
Catalin


From mohammad.athari.ismail at intel.com  Mon Jan 24 01:59:49 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Mon, 24 Jan 2022 17:59:49 +0800
Subject: [PATCH net 0/2] Fix PTP issue in stmmac
Message-ID: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>

This patch series to fix PTP issue in stmmac related to:
1/ PTP clock source configuration during initialization.
2/ PTP initialization during resume from suspend.

Mohammad Athari Bin Ismail (2):
  net: stmmac: configure PTP clock source prior to PTP initialization
  net: stmmac: skip only stmmac_ptp_register when resume from suspend

 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++++---------
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  |  3 ---
 2 files changed, 12 insertions(+), 13 deletions(-)

-- 
2.17.1



From mohammad.athari.ismail at intel.com  Mon Jan 24 01:59:50 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Mon, 24 Jan 2022 17:59:50 +0800
Subject: [PATCH net 1/2] net: stmmac: configure PTP clock source prior to PTP
 initialization
In-Reply-To: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
References: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220124095951.23845-2-mohammad.athari.ismail@intel.com>

For Intel platform, it is required to configure PTP clock source prior PTP
initialization in MAC. So, need to move ptp_clk_freq_config execution from
stmmac_ptp_register() to stmmac_init_ptp().

Fixes: 76da35dc99af ("stmmac: intel: Add PSE and PCH PTP clock source selection")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..d7e261768f73 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -889,6 +889,9 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	int ret;
 
+	if (priv->plat->ptp_clk_freq_config)
+		priv->plat->ptp_clk_freq_config(priv);
+
 	ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE);
 	if (ret)
 		return ret;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0d24ebd37873..1c9f02f9c317 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -297,9 +297,6 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
 {
 	int i;
 
-	if (priv->plat->ptp_clk_freq_config)
-		priv->plat->ptp_clk_freq_config(priv);
-
 	for (i = 0; i < priv->dma_cap.pps_out_num; i++) {
 		if (i >= STMMAC_PPS_MAX)
 			break;
-- 
2.17.1



From mohammad.athari.ismail at intel.com  Mon Jan 24 01:59:51 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Mon, 24 Jan 2022 17:59:51 +0800
Subject: [PATCH net 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
References: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220124095951.23845-3-mohammad.athari.ismail@intel.com>

When resume from suspend, besides skipping PTP registration, it also
skipping PTP HW initialization. This could cause PTP clock not able to
operate properly when resume from suspend.

To fix this, only stmmac_ptp_register() is skipped when resume from
suspend.

Fixes: fe1319291150 ("stmmac: Don't init ptp again when resume from suspend/hibernation")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d7e261768f73..cfea38a50a73 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -884,7 +884,7 @@ EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter);
  * This is done by looking at the HW cap. register.
  * This function also registers the ptp driver.
  */
-static int stmmac_init_ptp(struct stmmac_priv *priv)
+static int stmmac_init_ptp(struct stmmac_priv *priv, bool ptp_register)
 {
 	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	int ret;
@@ -914,7 +914,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	priv->hwts_tx_en = 0;
 	priv->hwts_rx_en = 0;
 
-	stmmac_ptp_register(priv);
+	if (ptp_register)
+		stmmac_ptp_register(priv);
 
 	return 0;
 }
@@ -3251,7 +3252,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
  *  0 on success and an appropriate (-)ve integer as defined in errno.h
  *  file on failure.
  */
-static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	u32 rx_cnt = priv->plat->rx_queues_to_use;
@@ -3308,13 +3309,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 
 	stmmac_mmc_setup(priv);
 
-	if (init_ptp) {
-		ret = stmmac_init_ptp(priv);
-		if (ret == -EOPNOTSUPP)
-			netdev_warn(priv->dev, "PTP not supported by HW\n");
-		else if (ret)
-			netdev_warn(priv->dev, "PTP init failed\n");
-	}
+	ret = stmmac_init_ptp(priv, ptp_register);
+	if (ret == -EOPNOTSUPP)
+		netdev_warn(priv->dev, "PTP not supported by HW\n");
+	else if (ret)
+		netdev_warn(priv->dev, "PTP init failed\n");
 
 	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
 
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:35 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:35 +0000
Subject: [PATCH 0/6] Add SCMI Virtio & Clock atomic support
Message-ID: <20220124100341.41191-1-cristian.marussi@arm.com>

Hi,

This small series is the tail-subset of the previous V8 series about atomic
support in SCMI [1], whose 8-patches head-subset has now been queued on
[2]; as such, it is based on [2] on top of tag scmi-updates-5.17:

commit 94d0cd1da14a ("firmware: arm_scmi: Add new parameter to
		     mark_txdone")

Patch 1/5 adds polling mode to SCMI VirtIO transport in order to support
atomic operations on such transport and it could have been an independent
patch indeed, it is provided here only for ease of testing.

Patch 2,3 introduce a new optional SCMI binding, atomic_threshold, to
configure a platform specific time threshold used in the following patches
to select with a finer grain which SCMI resources should be eligible for
atomic operations when requested.

Patch 4 exposes new SCMI Clock protocol operations to allow an SCMI user
to request atomic mode on clock enable commands.

Patch 5 adds support to SCMI Clock protocol for a new clock attributes
field which advertises typical enable latency for a specific resource.
It is marked as RFC since the SCMI spec including such addition is still
to be finalized.

Finally patch 6 add support for atomic operations to the SCMI clock driver;
the underlying logic here is that we register with the Clock framework
atomic-capable clock resources if and only if the backing SCMI transport is
capable of atomic operations AND the specific clock resource has been
advertised by the SCMI platform as having:

	clock_enable_latency <= atomic_threshold

The idea is to avoid costly atomic busy-waiting for resources that have
been advertised as 'slow' to operate upon. (i.e. a PLL vs a gating clock)
This last patch is marked as RFC too since it is dependent on the previous
one (that is RFC-tagged too)

To ease testing the whole series can be find at [3].

Any feedback/testing welcome as usual.

Thanks,
Cristian

[1]: https://lore.kernel.org/linux-arm-kernel/20211220195646.44498-1-cristian.marussi at arm.com/
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/tag/?h=scmi-updates-5.17
[3]: https://gitlab.arm.com/linux-arm/linux-cm/-/commits/scmi_atomic_clk_virtio_V1/

Cristian Marussi (6):
  firmware: arm_scmi: Add atomic mode support to virtio transport
  dt-bindings: firmware: arm,scmi: Add atomic_threshold optional
    property
  firmware: arm_scmi: Support optional system wide atomic_threshold
  firmware: arm_scmi: Add atomic support to clock protocol
  [RFC] firmware: arm_scmi: Add support for clock_enable_latency
  [RFC] clk: scmi: Support atomic clock enable/disable API

 .../bindings/firmware/arm,scmi.yaml           |  10 +
 drivers/clk/clk-scmi.c                        |  71 +++-
 drivers/firmware/arm_scmi/Kconfig             |  15 +
 drivers/firmware/arm_scmi/clock.c             |  34 +-
 drivers/firmware/arm_scmi/driver.c            |  36 +-
 drivers/firmware/arm_scmi/virtio.c            | 315 ++++++++++++++++--
 include/linux/scmi_protocol.h                 |   9 +-
 7 files changed, 440 insertions(+), 50 deletions(-)

-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:36 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:36 +0000
Subject: [PATCH 1/6] firmware: arm_scmi: Add atomic mode support to virtio
 transport
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-2-cristian.marussi@arm.com>

Add support for .mark_txdone and .poll_done transport operations to SCMI
VirtIO transport as pre-requisites to enable atomic operations.

Add a Kernel configuration option to enable SCMI VirtIO transport polling
and atomic mode for selected SCMI transactions while leaving it default
disabled.

Cc: "Michael S. Tsirkin" <mst at redhat.com>
Cc: Igor Skalkin <igor.skalkin at opensynergy.com>
Cc: Peter Hilber <peter.hilber at opensynergy.com>
Cc: virtualization at lists.linux-foundation.org
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
- check for deferred_wq existence before queueing work to avoid
  race at driver removal time
- changed mark_txdone decision-logic about message release
- fixed race while checking for msg polled from another thread
- using dedicated poll_status instead of poll_idx upper bits
- pick initial poll_idx earlier insde send_message to avoid missing
  early replies
- removed F_NOTIFY mention in comment
- clearing xfer->priv on the IRQ tx path once message has been fetched
- added some store barriers
- updated some comments
---
 drivers/firmware/arm_scmi/Kconfig  |  15 ++
 drivers/firmware/arm_scmi/driver.c |   9 +-
 drivers/firmware/arm_scmi/virtio.c | 315 ++++++++++++++++++++++++++---
 3 files changed, 310 insertions(+), 29 deletions(-)

diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
index d429326433d1..7794bd41eaa0 100644
--- a/drivers/firmware/arm_scmi/Kconfig
+++ b/drivers/firmware/arm_scmi/Kconfig
@@ -118,6 +118,21 @@ config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
 	  the ones implemented by kvmtool) and let the core Kernel VirtIO layer
 	  take care of the needed conversions, say N.
 
+config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
+	bool "Enable atomic mode for SCMI VirtIO transport"
+	depends on ARM_SCMI_TRANSPORT_VIRTIO
+	help
+	  Enable support of atomic operation for SCMI VirtIO based transport.
+
+	  If you want the SCMI VirtIO based transport to operate in atomic
+	  mode, avoiding any kind of sleeping behaviour for selected
+	  transactions on the TX path, answer Y.
+
+	  Enabling atomic mode operations allows any SCMI driver using this
+	  transport to optionally ask for atomic SCMI transactions and operate
+	  in atomic context too, at the price of using a number of busy-waiting
+	  primitives all over instead. If unsure say N.
+
 endif #ARM_SCMI_PROTOCOL
 
 config ARM_SCMI_POWER_DOMAIN
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index c2e7897ff56e..dc972a54e93e 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -648,7 +648,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
 
 	unpack_scmi_header(msg_hdr, &xfer->hdr);
 	if (priv)
-		xfer->priv = priv;
+		/* Ensure order between xfer->priv store and following ops */
+		smp_store_mb(xfer->priv, priv);
 	info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
 					    xfer);
 	scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
@@ -680,8 +681,12 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
 		xfer->rx.len = info->desc->max_msg_size;
 
 	if (priv)
-		xfer->priv = priv;
+		/* Ensure order between xfer->priv store and following ops */
+		smp_store_mb(xfer->priv, priv);
 	info->desc->ops->fetch_response(cinfo, xfer);
+	if (priv)
+		/* Ensure order between xfer->priv clear and later accesses */
+		smp_store_mb(xfer->priv, NULL);
 
 	trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
 			   xfer->hdr.protocol_id, xfer->hdr.seq,
diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
index fd0f6f91fc0b..39c293f0ffd3 100644
--- a/drivers/firmware/arm_scmi/virtio.c
+++ b/drivers/firmware/arm_scmi/virtio.c
@@ -3,8 +3,8 @@
  * Virtio Transport driver for Arm System Control and Management Interface
  * (SCMI).
  *
- * Copyright (C) 2020-2021 OpenSynergy.
- * Copyright (C) 2021 ARM Ltd.
+ * Copyright (C) 2020-2022 OpenSynergy.
+ * Copyright (C) 2021-2022 ARM Ltd.
  */
 
 /**
@@ -38,6 +38,9 @@
  * @vqueue: Associated virtqueue
  * @cinfo: SCMI Tx or Rx channel
  * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
+ * @deferred_tx_work: Worker for TX deferred replies processing
+ * @deferred_tx_wq: Workqueue for TX deferred replies
+ * @pending_cmds_list: List of pre-fetched commands queueud for later processing
  * @is_rx: Whether channel is an Rx channel
  * @ready: Whether transport user is ready to hear about channel
  * @max_msg: Maximum number of pending messages for this channel.
@@ -49,6 +52,9 @@ struct scmi_vio_channel {
 	struct virtqueue *vqueue;
 	struct scmi_chan_info *cinfo;
 	struct list_head free_list;
+	struct list_head pending_cmds_list;
+	struct work_struct deferred_tx_work;
+	struct workqueue_struct *deferred_tx_wq;
 	bool is_rx;
 	bool ready;
 	unsigned int max_msg;
@@ -58,6 +64,12 @@ struct scmi_vio_channel {
 	spinlock_t ready_lock;
 };
 
+enum poll_states {
+	VIO_MSG_NOT_POLLED,
+	VIO_MSG_POLLING,
+	VIO_MSG_POLL_DONE,
+};
+
 /**
  * struct scmi_vio_msg - Transport PDU information
  *
@@ -65,12 +77,22 @@ struct scmi_vio_channel {
  * @input: SDU used for (delayed) responses and notifications
  * @list: List which scmi_vio_msg may be part of
  * @rx_len: Input SDU size in bytes, once input has been received
+ * @poll_idx: Last used index registered for polling purposes if this message
+ *	      transaction reply was configured for polling.
+ *	      Note that since virtqueue used index is an unsigned 16-bit we can
+ *	      use some out-of-scale values to signify particular conditions.
+ * @poll_status: Polling state for this message.
+ * @poll_lock: Protect access to @poll_idx and @poll_status.
  */
 struct scmi_vio_msg {
 	struct scmi_msg_payld *request;
 	struct scmi_msg_payld *input;
 	struct list_head list;
 	unsigned int rx_len;
+	unsigned int poll_idx;
+	enum poll_states poll_status;
+	/* lock to protect access to poll_idx. */
+	spinlock_t poll_lock;
 };
 
 /* Only one SCMI VirtIO device can possibly exist */
@@ -81,40 +103,43 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
 	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
 }
 
+/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
 static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
 			       struct scmi_vio_msg *msg,
 			       struct device *dev)
 {
 	struct scatterlist sg_in;
 	int rc;
-	unsigned long flags;
 
 	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
 
-	spin_lock_irqsave(&vioch->lock, flags);
-
 	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
 	if (rc)
 		dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
 	else
 		virtqueue_kick(vioch->vqueue);
 
-	spin_unlock_irqrestore(&vioch->lock, flags);
-
 	return rc;
 }
 
+/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
+static inline void scmi_vio_feed_vq_tx(struct scmi_vio_channel *vioch,
+				       struct scmi_vio_msg *msg)
+{
+	spin_lock(&msg->poll_lock);
+	msg->poll_status = VIO_MSG_NOT_POLLED;
+	spin_unlock(&msg->poll_lock);
+
+	list_add(&msg->list, &vioch->free_list);
+}
+
 static void scmi_finalize_message(struct scmi_vio_channel *vioch,
 				  struct scmi_vio_msg *msg)
 {
-	if (vioch->is_rx) {
+	if (vioch->is_rx)
 		scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
-	} else {
-		/* Here IRQs are assumed to be already disabled by the caller */
-		spin_lock(&vioch->lock);
-		list_add(&msg->list, &vioch->free_list);
-		spin_unlock(&vioch->lock);
-	}
+	else
+		scmi_vio_feed_vq_tx(vioch, msg);
 }
 
 static void scmi_vio_complete_cb(struct virtqueue *vqueue)
@@ -144,6 +169,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
 			virtqueue_disable_cb(vqueue);
 			cb_enabled = false;
 		}
+
 		msg = virtqueue_get_buf(vqueue, &length);
 		if (!msg) {
 			if (virtqueue_enable_cb(vqueue))
@@ -157,7 +183,9 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
 			scmi_rx_callback(vioch->cinfo,
 					 msg_read_header(msg->input), msg);
 
+			spin_lock(&vioch->lock);
 			scmi_finalize_message(vioch, msg);
+			spin_unlock(&vioch->lock);
 		}
 
 		/*
@@ -176,6 +204,34 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
 	spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
 }
 
+static void scmi_vio_deferred_tx_worker(struct work_struct *work)
+{
+	unsigned long flags;
+	struct scmi_vio_channel *vioch;
+	struct scmi_vio_msg *msg, *tmp;
+
+	vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
+
+	/* Process pre-fetched messages */
+	spin_lock_irqsave(&vioch->lock, flags);
+
+	/* Scan the list of possibly pre-fetched messages during polling. */
+	list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
+		list_del(&msg->list);
+
+		scmi_rx_callback(vioch->cinfo,
+				 msg_read_header(msg->input), msg);
+
+		/* Free the processed message once done */
+		scmi_vio_feed_vq_tx(vioch, msg);
+	}
+
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	/* Process possibly still pending messages */
+	scmi_vio_complete_cb(vioch->vqueue);
+}
+
 static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
 
 static vq_callback_t *scmi_vio_complete_callbacks[] = {
@@ -244,6 +300,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 
 	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
 
+	/* Setup a deferred worker for polling. */
+	if (tx && !vioch->deferred_tx_wq) {
+		vioch->deferred_tx_wq =
+			alloc_workqueue(dev_name(&scmi_vdev->dev),
+					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
+					0);
+		if (!vioch->deferred_tx_wq)
+			return -ENOMEM;
+
+		INIT_WORK(&vioch->deferred_tx_work,
+			  scmi_vio_deferred_tx_worker);
+	}
+
 	for (i = 0; i < vioch->max_msg; i++) {
 		struct scmi_vio_msg *msg;
 
@@ -257,6 +326,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 						    GFP_KERNEL);
 			if (!msg->request)
 				return -ENOMEM;
+			spin_lock_init(&msg->poll_lock);
 		}
 
 		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
@@ -264,13 +334,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
 		if (!msg->input)
 			return -ENOMEM;
 
-		if (tx) {
-			spin_lock_irqsave(&vioch->lock, flags);
-			list_add_tail(&msg->list, &vioch->free_list);
-			spin_unlock_irqrestore(&vioch->lock, flags);
-		} else {
+		spin_lock_irqsave(&vioch->lock, flags);
+		if (tx)
+			scmi_vio_feed_vq_tx(vioch, msg);
+		else
 			scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
-		}
+		spin_unlock_irqrestore(&vioch->lock, flags);
 	}
 
 	spin_lock_irqsave(&vioch->lock, flags);
@@ -291,11 +360,22 @@ static int virtio_chan_free(int id, void *p, void *data)
 	unsigned long flags;
 	struct scmi_chan_info *cinfo = p;
 	struct scmi_vio_channel *vioch = cinfo->transport_info;
+	void *deferred_wq = NULL;
 
 	spin_lock_irqsave(&vioch->ready_lock, flags);
 	vioch->ready = false;
 	spin_unlock_irqrestore(&vioch->ready_lock, flags);
 
+	spin_lock_irqsave(&vioch->lock, flags);
+	if (!vioch->is_rx && vioch->deferred_tx_wq) {
+		deferred_wq = vioch->deferred_tx_wq;
+		vioch->deferred_tx_wq = NULL;
+	}
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	if (deferred_wq)
+		destroy_workqueue(deferred_wq);
+
 	scmi_free_channel(cinfo, data, id);
 
 	spin_lock_irqsave(&vioch->lock, flags);
@@ -324,16 +404,33 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
 	}
 
 	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
-	list_del(&msg->list);
+	/* Re-init element so we can discern anytime if it is still in-flight */
+	list_del_init(&msg->list);
 
 	msg_tx_prepare(msg->request, xfer);
 
 	sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
 	sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
 
+	/*
+	 * If polling was requested for this transaction:
+	 *  - retrieve last used index (will be used as polling reference)
+	 *  - bind the polled message to the xfer via .priv
+	 */
+	if (xfer->hdr.poll_completion) {
+		spin_lock(&msg->poll_lock);
+		msg->poll_status = VIO_MSG_POLLING;
+		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
+		spin_unlock(&msg->poll_lock);
+		/* Ensure initialized msg is visibly bound to xfer */
+		smp_store_mb(xfer->priv, msg);
+	}
+
 	rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
 	if (rc) {
-		list_add(&msg->list, &vioch->free_list);
+		/* Ensure order between xfer->priv clear and vq feeding */
+		smp_store_mb(xfer->priv, NULL);
+		scmi_vio_feed_vq_tx(vioch, msg);
 		dev_err(vioch->cinfo->dev,
 			"failed to add to TX virtqueue (%d)\n", rc);
 	} else {
@@ -350,10 +447,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo,
 {
 	struct scmi_vio_msg *msg = xfer->priv;
 
-	if (msg) {
+	if (msg)
 		msg_fetch_response(msg->input, msg->rx_len, xfer);
-		xfer->priv = NULL;
-	}
 }
 
 static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
@@ -361,12 +456,174 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
 {
 	struct scmi_vio_msg *msg = xfer->priv;
 
-	if (msg) {
+	if (msg)
 		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
-		xfer->priv = NULL;
+}
+
+/**
+ * virtio_mark_txdone  - Mark transmission done
+ *
+ * Free only completed polling transfer messages.
+ *
+ * Note that in the SCMI VirtIO transport we never explicitly release timed-out
+ * messages by forcibly re-adding them to the free-list inside the TX code path;
+ * we instead let IRQ/RX callbacks eventually clean up such messages once,
+ * finally, a late reply is received and discarded (if ever).
+ *
+ * This approach was deemed preferable since those pending timed-out buffers are
+ * still effectively owned by the SCMI platform VirtIO device even after timeout
+ * expiration: forcibly freeing and reusing them before they had been returned
+ * explicitly by the SCMI platform could lead to subtle bugs due to message
+ * corruption.
+ * An SCMI platform VirtIO device which never returns message buffers is
+ * anyway broken and it will quickly lead to exhaustion of available messages.
+ *
+ * For this same reason, here, we take care to free only the polled messages
+ * that had been somehow replied, since they won't be freed elsewhere;
+ * late replies to timed-out polled messages would be anyway freed by RX
+ * callbacks instead.
+ *
+ * @cinfo: SCMI channel info
+ * @ret: Transmission return code
+ * @xfer: Transfer descriptor
+ */
+static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
+			       struct scmi_xfer *xfer)
+{
+	unsigned long flags;
+	struct scmi_vio_channel *vioch = cinfo->transport_info;
+	struct scmi_vio_msg *msg = xfer->priv;
+
+	/* Must be a polled xfer and not already freed on the IRQ path */
+	if (!xfer->hdr.poll_completion || !msg)
+		return;
+
+	/* Ensure msg is unbound from xfer anyway at this point */
+	smp_store_mb(xfer->priv, NULL);
+
+	/* Do not free timedout polled messages */
+	if (ret != -ETIMEDOUT) {
+		spin_lock_irqsave(&vioch->lock, flags);
+		scmi_vio_feed_vq_tx(vioch, msg);
+		spin_unlock_irqrestore(&vioch->lock, flags);
 	}
 }
 
+/**
+ * virtio_poll_done  - Provide polling support for VirtIO transport
+ *
+ * @cinfo: SCMI channel info
+ * @xfer: Reference to the transfer being poll for.
+ *
+ * VirtIO core provides a polling mechanism based only on last used indexes:
+ * this means that it is possible to poll the virtqueues waiting for something
+ * new to arrive from the host side but the only way to check if the freshly
+ * arrived buffer was what we were waiting for is to compare the newly arrived
+ * message descriptors with the one we are polling on.
+ *
+ * As a consequence it can happen to dequeue something different from the buffer
+ * we were poll-waiting for: if that is the case such early fetched buffers are
+ * then added to a the @pending_cmds_list list for later processing by a
+ * dedicated deferred worker.
+ *
+ * So, basically, once something new is spotted we proceed to de-queue all the
+ * freshly received used buffers until we found the one we were polling on, or,
+ * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
+ * in the vqueue at the end of the polling loop (possible due to inherent races
+ * in virtqueues handling mechanisms), we similarly kick the deferred worker
+ * and let it process those, to avoid indefinitely looping in the .poll_done
+ * helper.
+ *
+ * Note that, since we do NOT have per-message suppress notification mechanism,
+ * the message we are polling for could be delivered via usual IRQs callbacks
+ * on another core which happened to have IRQs enabled: in such case it will be
+ * handled as such by scmi_rx_callback() and the polling loop in the
+ * SCMI Core TX path will be transparently terminated anyway.
+ *
+ * Return: True once polling has successfully completed.
+ */
+static bool virtio_poll_done(struct scmi_chan_info *cinfo,
+			     struct scmi_xfer *xfer)
+{
+	bool pending, ret = false;
+	unsigned int length, any_prefetched = 0;
+	unsigned long flags;
+	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
+	struct scmi_vio_channel *vioch = cinfo->transport_info;
+
+	if (!msg)
+		return true;
+
+	spin_lock_irqsave(&vioch->lock, flags);
+	spin_lock(&msg->poll_lock);
+	/* Processed already by other polling loop on another CPU ? */
+	if (msg->poll_status == VIO_MSG_POLL_DONE) {
+		spin_unlock(&msg->poll_lock);
+		spin_unlock_irqrestore(&vioch->lock, flags);
+		return true;
+	}
+
+	/* Has cmdq index moved at all ? */
+	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
+	spin_unlock(&msg->poll_lock);
+	if (!pending) {
+		spin_unlock_irqrestore(&vioch->lock, flags);
+		return false;
+	}
+
+	virtqueue_disable_cb(vioch->vqueue);
+
+	/*
+	 * If something arrived we cannot be sure, without dequeueing, if it
+	 * was the reply to the xfer we are polling for, or, to other, even
+	 * possibly non-polling, pending xfers: process all new messages
+	 * till the polled-for message is found OR the vqueue is empty.
+	 */
+	while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
+		next_msg->rx_len = length;
+		/* Is the message we were polling for ? */
+		if (next_msg == msg) {
+			ret = true;
+			break;
+		}
+
+		spin_lock(&next_msg->poll_lock);
+		if (next_msg->poll_status == VIO_MSG_NOT_POLLED) {
+			any_prefetched++;
+			list_add_tail(&next_msg->list,
+				      &vioch->pending_cmds_list);
+		} else {
+			/* We picked another currently polled msg */
+			next_msg->poll_status = VIO_MSG_POLL_DONE;
+		}
+		spin_unlock(&next_msg->poll_lock);
+	}
+
+	/*
+	 * When the polling loop has successfully terminated if something
+	 * else was queued in the meantime, it will be served by a deferred
+	 * worker OR by the normal IRQ/callback OR by other poll loops.
+	 *
+	 * If we are still looking for the polled reply, the polling index has
+	 * to be updated to the current vqueue last used index.
+	 */
+	if (ret) {
+		pending = !virtqueue_enable_cb(vioch->vqueue);
+	} else {
+		spin_lock(&msg->poll_lock);
+		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
+		pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
+		spin_unlock(&msg->poll_lock);
+	}
+
+	if (vioch->deferred_tx_wq && (any_prefetched || pending))
+		queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);
+
+	spin_unlock_irqrestore(&vioch->lock, flags);
+
+	return ret;
+}
+
 static const struct scmi_transport_ops scmi_virtio_ops = {
 	.link_supplier = virtio_link_supplier,
 	.chan_available = virtio_chan_available,
@@ -376,6 +633,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = {
 	.send_message = virtio_send_message,
 	.fetch_response = virtio_fetch_response,
 	.fetch_notification = virtio_fetch_notification,
+	.mark_txdone = virtio_mark_txdone,
+	.poll_done = virtio_poll_done,
 };
 
 static int scmi_vio_probe(struct virtio_device *vdev)
@@ -418,6 +677,7 @@ static int scmi_vio_probe(struct virtio_device *vdev)
 		spin_lock_init(&channels[i].lock);
 		spin_lock_init(&channels[i].ready_lock);
 		INIT_LIST_HEAD(&channels[i].free_list);
+		INIT_LIST_HEAD(&channels[i].pending_cmds_list);
 		channels[i].vqueue = vqs[i];
 
 		sz = virtqueue_get_vring_size(channels[i].vqueue);
@@ -506,4 +766,5 @@ const struct scmi_desc scmi_virtio_desc = {
 	.max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
 	.max_msg = 0, /* overridden by virtio_get_max_msg() */
 	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
+	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
 };
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:37 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:37 +0000
Subject: [PATCH 2/6] dt-bindings: firmware: arm,
 scmi: Add atomic_threshold optional property
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-3-cristian.marussi@arm.com>

SCMI protocols in the platform can optionally signal to the OSPM agent
the expected execution latency for a specific resource/operation pair.

Introduce an SCMI system wide optional property to describe a global time
threshold which can be configured on a per-platform base to determine the
opportunity, or not, for an SCMI command advertised to have a higher
latency than the threshold, to be considered for atomic operations:
high-latency SCMI synchronous commands should be preferably issued in the
usual non-atomic mode.

Cc: Rob Herring <robh+dt at kernel.org>
Cc: devicetree at vger.kernel.org
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 .../devicetree/bindings/firmware/arm,scmi.yaml         | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index eae15df36eef..8edda54dff5b 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -81,6 +81,14 @@ properties:
   '#size-cells':
     const: 0
 
+  atomic_threshold:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      An optional time value, expressed in microseconds, representing the
+      threshold above which, on this platform, any SCMI command advertised to
+      have a higher execution latency, should not be used in atomic mode, even
+      if requested. If left unconfigured defaults to zero.
+
   arm,smc-id:
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
@@ -264,6 +272,8 @@ examples:
             #address-cells = <1>;
             #size-cells = <0>;
 
+            atomic_threshold = <10000>;
+
             scmi_devpd: protocol at 11 {
                 reg = <0x11>;
                 #power-domain-cells = <1>;
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:38 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:38 +0000
Subject: [PATCH 3/6] firmware: arm_scmi: Support optional system wide
 atomic_threshold
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-4-cristian.marussi@arm.com>

An SCMI agent can be configured system-wide with a well-defined atomic
threshold: only SCMI synchronous command whose latency has been advertised
by the SCMI platform to be lower or equal to this configured threshold will
be considered for atomic operations, when requested and supported by the
underlying transport at all.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/driver.c | 27 ++++++++++++++++++++++++---
 include/linux/scmi_protocol.h      |  5 ++++-
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index dc972a54e93e..d2ac6291b84b 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -131,6 +131,12 @@ struct scmi_protocol_instance {
  *	MAX_PROTOCOLS_IMP elements allocated by the base protocol
  * @active_protocols: IDR storing device_nodes for protocols actually defined
  *		      in the DT and confirmed as implemented by fw.
+ * @atomic_threshold: Optional system wide DT-configured threshold, expressed
+ *		      in microseconds, for atomic operations.
+ *		      Only SCMI synchronous commands reported by the platform
+ *		      to have an execution latency lesser-equal to the threshold
+ *		      should be considered for atomic mode operation: such
+ *		      decision is finally left up to the SCMI drivers.
  * @notify_priv: Pointer to private data structure specific to notifications.
  * @node: List head
  * @users: Number of users of this instance
@@ -149,6 +155,7 @@ struct scmi_info {
 	struct mutex protocols_mtx;
 	u8 *protocols_imp;
 	struct idr active_protocols;
+	unsigned int atomic_threshold;
 	void *notify_priv;
 	struct list_head node;
 	int users;
@@ -1409,15 +1416,22 @@ static void scmi_devm_protocol_put(struct scmi_device *sdev, u8 protocol_id)
  * SCMI instance is configured as atomic.
  *
  * @handle: A reference to the SCMI platform instance.
+ * @atomic_threshold: An optional return value for the system wide currently
+ *		      configured threshold for atomic operations.
  *
  * Return: True if transport is configured as atomic
  */
-static bool scmi_is_transport_atomic(const struct scmi_handle *handle)
+static bool scmi_is_transport_atomic(const struct scmi_handle *handle,
+				     unsigned int *atomic_threshold)
 {
+	bool ret;
 	struct scmi_info *info = handle_to_scmi_info(handle);
 
-	return info->desc->atomic_enabled &&
-		is_transport_polling_capable(info);
+	ret = info->desc->atomic_enabled && is_transport_polling_capable(info);
+	if (ret && atomic_threshold)
+		*atomic_threshold = info->atomic_threshold;
+
+	return ret;
 }
 
 static inline
@@ -1957,6 +1971,13 @@ static int scmi_probe(struct platform_device *pdev)
 	handle->version = &info->version;
 	handle->devm_protocol_get = scmi_devm_protocol_get;
 	handle->devm_protocol_put = scmi_devm_protocol_put;
+
+	/* System wide atomic threshold for atomic ops .. if any */
+	if (!of_property_read_u32(np, "atomic_threshold",
+				  &info->atomic_threshold))
+		dev_info(dev,
+			 "SCMI System wide atomic threshold set to %d us\n",
+			 info->atomic_threshold);
 	handle->is_transport_atomic = scmi_is_transport_atomic;
 
 	if (desc->ops->link_supplier) {
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index 9f895cb81818..fdf6bd83cc59 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -619,6 +619,8 @@ struct scmi_notify_ops {
  *			 be interested to know if they can assume SCMI
  *			 command transactions associated to this handle will
  *			 never sleep and act accordingly.
+ *			 An optional atomic threshold value could be returned
+ *			 where configured.
  * @notify_ops: pointer to set of notifications related operations
  */
 struct scmi_handle {
@@ -629,7 +631,8 @@ struct scmi_handle {
 		(*devm_protocol_get)(struct scmi_device *sdev, u8 proto,
 				     struct scmi_protocol_handle **ph);
 	void (*devm_protocol_put)(struct scmi_device *sdev, u8 proto);
-	bool (*is_transport_atomic)(const struct scmi_handle *handle);
+	bool (*is_transport_atomic)(const struct scmi_handle *handle,
+				    unsigned int *atomic_threshold);
 
 	const struct scmi_notify_ops *notify_ops;
 };
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:39 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:39 +0000
Subject: [PATCH 4/6] firmware: arm_scmi: Add atomic support to clock protocol
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-5-cristian.marussi@arm.com>

Introduce new _atomic variant for SCMI clock protocol operations related
to enable disable operations: when an atomic operation is required the xfer
poll_completion flag is set for that transaction.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
 drivers/firmware/arm_scmi/clock.c | 22 +++++++++++++++++++---
 include/linux/scmi_protocol.h     |  4 ++++
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 35b56c8ba0c0..72f930c0e3e2 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -273,7 +273,7 @@ static int scmi_clock_rate_set(const struct scmi_protocol_handle *ph,
 
 static int
 scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
-		      u32 config)
+		      u32 config, bool atomic)
 {
 	int ret;
 	struct scmi_xfer *t;
@@ -284,6 +284,8 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
 	if (ret)
 		return ret;
 
+	t->hdr.poll_completion = atomic;
+
 	cfg = t->tx.buf;
 	cfg->id = cpu_to_le32(clk_id);
 	cfg->attributes = cpu_to_le32(config);
@@ -296,12 +298,24 @@ scmi_clock_config_set(const struct scmi_protocol_handle *ph, u32 clk_id,
 
 static int scmi_clock_enable(const struct scmi_protocol_handle *ph, u32 clk_id)
 {
-	return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE);
+	return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, false);
 }
 
 static int scmi_clock_disable(const struct scmi_protocol_handle *ph, u32 clk_id)
 {
-	return scmi_clock_config_set(ph, clk_id, 0);
+	return scmi_clock_config_set(ph, clk_id, 0, false);
+}
+
+static int scmi_clock_enable_atomic(const struct scmi_protocol_handle *ph,
+				    u32 clk_id)
+{
+	return scmi_clock_config_set(ph, clk_id, CLOCK_ENABLE, true);
+}
+
+static int scmi_clock_disable_atomic(const struct scmi_protocol_handle *ph,
+				     u32 clk_id)
+{
+	return scmi_clock_config_set(ph, clk_id, 0, true);
 }
 
 static int scmi_clock_count_get(const struct scmi_protocol_handle *ph)
@@ -330,6 +344,8 @@ static const struct scmi_clk_proto_ops clk_proto_ops = {
 	.rate_set = scmi_clock_rate_set,
 	.enable = scmi_clock_enable,
 	.disable = scmi_clock_disable,
+	.enable_atomic = scmi_clock_enable_atomic,
+	.disable_atomic = scmi_clock_disable_atomic,
 };
 
 static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph)
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h
index fdf6bd83cc59..b87551f41f9f 100644
--- a/include/linux/scmi_protocol.h
+++ b/include/linux/scmi_protocol.h
@@ -42,6 +42,7 @@ struct scmi_revision_info {
 
 struct scmi_clock_info {
 	char name[SCMI_MAX_STR_SIZE];
+	unsigned int enable_latency;
 	bool rate_discrete;
 	union {
 		struct {
@@ -82,6 +83,9 @@ struct scmi_clk_proto_ops {
 			u64 rate);
 	int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id);
 	int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id);
+	int (*enable_atomic)(const struct scmi_protocol_handle *ph, u32 clk_id);
+	int (*disable_atomic)(const struct scmi_protocol_handle *ph,
+			      u32 clk_id);
 };
 
 /**
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:40 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:40 +0000
Subject: [PATCH 5/6] [RFC] firmware: arm_scmi: Add support for
 clock_enable_latency
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-6-cristian.marussi@arm.com>

An SCMI platform can optionally advertise an enable latency typically
associated with a specific clock resource: add support for parsing such
optional message field and export sich information in the usual publicly
accessible clock descriptor.

Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
RFC tag is due to the fact that this SCMI spec Clock protocol field
addition is still to be published.
---
 drivers/firmware/arm_scmi/clock.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c
index 72f930c0e3e2..552610bfb91e 100644
--- a/drivers/firmware/arm_scmi/clock.c
+++ b/drivers/firmware/arm_scmi/clock.c
@@ -27,7 +27,8 @@ struct scmi_msg_resp_clock_protocol_attributes {
 struct scmi_msg_resp_clock_attributes {
 	__le32 attributes;
 #define	CLOCK_ENABLE	BIT(0)
-	    u8 name[SCMI_MAX_STR_SIZE];
+	u8 name[SCMI_MAX_STR_SIZE];
+	__le32 clock_enable_latency;
 };
 
 struct scmi_clock_set_config {
@@ -116,10 +117,15 @@ static int scmi_clock_attributes_get(const struct scmi_protocol_handle *ph,
 	attr = t->rx.buf;
 
 	ret = ph->xops->do_xfer(ph, t);
-	if (!ret)
+	if (!ret) {
 		strlcpy(clk->name, attr->name, SCMI_MAX_STR_SIZE);
-	else
+		/* TODO Use CLOCK Proto Versioning once SCMI spec is updated */
+		if (t->rx.len > sizeof(attr->attributes) + SCMI_MAX_STR_SIZE)
+			clk->enable_latency =
+				le32_to_cpu(attr->clock_enable_latency);
+	} else {
 		clk->name[0] = '\0';
+	}
 
 	ph->xops->xfer_put(ph, t);
 	return ret;
-- 
2.17.1



From cristian.marussi at arm.com  Mon Jan 24 02:03:41 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Mon, 24 Jan 2022 10:03:41 +0000
Subject: [PATCH 6/6] [RFC] clk: scmi: Support atomic clock enable/disable API
In-Reply-To: <20220124100341.41191-1-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
Message-ID: <20220124100341.41191-7-cristian.marussi@arm.com>

Support also atomic enable/disable clk_ops beside the bare non-atomic one
(prepare/unprepare) when the underlying SCMI transport is configured to
support atomic transactions for synchronous commands.

Compare the SCMI system-wide configured atomic threshold latency time and
the per-clock advertised enable latency (if any) to choose whether to
provide sleeping prepare/unprepare vs atomic enable/disable.

Cc: Michael Turquette <mturquette at baylibre.com>
Cc: Stephen Boyd <sboyd at kernel.org>
Cc: linux-clk at vger.kernel.org
Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
---
Tagged as RFC since dependent on a previous RFC patch
---
 drivers/clk/clk-scmi.c | 71 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 60 insertions(+), 11 deletions(-)

diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c
index 1e357d364ca2..2c7a830ce308 100644
--- a/drivers/clk/clk-scmi.c
+++ b/drivers/clk/clk-scmi.c
@@ -2,7 +2,7 @@
 /*
  * System Control and Power Interface (SCMI) Protocol based clock driver
  *
- * Copyright (C) 2018-2021 ARM Ltd.
+ * Copyright (C) 2018-2022 ARM Ltd.
  */
 
 #include <linux/clk-provider.h>
@@ -88,21 +88,51 @@ static void scmi_clk_disable(struct clk_hw *hw)
 	scmi_proto_clk_ops->disable(clk->ph, clk->id);
 }
 
+static int scmi_clk_atomic_enable(struct clk_hw *hw)
+{
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	return scmi_proto_clk_ops->enable_atomic(clk->ph, clk->id);
+}
+
+static void scmi_clk_atomic_disable(struct clk_hw *hw)
+{
+	struct scmi_clk *clk = to_scmi_clk(hw);
+
+	scmi_proto_clk_ops->disable_atomic(clk->ph, clk->id);
+}
+
+/*
+ * We can provide enable/disable atomic callbacks only if the underlying SCMI
+ * transport for an SCMI instance is configured to handle SCMI commands in an
+ * atomic manner.
+ *
+ * When no SCMI atomic transport support is available we instead provide only
+ * the prepare/unprepare API, as allowed by the clock framework when atomic
+ * calls are not available.
+ *
+ * Two distinct sets of clk_ops are provided since we could have multiple SCMI
+ * instances with different underlying transport quality, so they cannot be
+ * shared.
+ */
 static const struct clk_ops scmi_clk_ops = {
 	.recalc_rate = scmi_clk_recalc_rate,
 	.round_rate = scmi_clk_round_rate,
 	.set_rate = scmi_clk_set_rate,
-	/*
-	 * We can't provide enable/disable callback as we can't perform the same
-	 * in atomic context. Since the clock framework provides standard API
-	 * clk_prepare_enable that helps cases using clk_enable in non-atomic
-	 * context, it should be fine providing prepare/unprepare.
-	 */
 	.prepare = scmi_clk_enable,
 	.unprepare = scmi_clk_disable,
 };
 
-static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
+static const struct clk_ops scmi_atomic_clk_ops = {
+	.recalc_rate = scmi_clk_recalc_rate,
+	.round_rate = scmi_clk_round_rate,
+	.set_rate = scmi_clk_set_rate,
+	.enable = scmi_clk_atomic_enable,
+	.disable = scmi_clk_atomic_disable,
+};
+
+static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk,
+			     const struct clk_ops *scmi_ops)
 {
 	int ret;
 	unsigned long min_rate, max_rate;
@@ -110,7 +140,7 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
 	struct clk_init_data init = {
 		.flags = CLK_GET_RATE_NOCACHE,
 		.num_parents = 0,
-		.ops = &scmi_clk_ops,
+		.ops = scmi_ops,
 		.name = sclk->info->name,
 	};
 
@@ -139,6 +169,8 @@ static int scmi_clk_ops_init(struct device *dev, struct scmi_clk *sclk)
 static int scmi_clocks_probe(struct scmi_device *sdev)
 {
 	int idx, count, err;
+	unsigned int atomic_threshold;
+	bool is_atomic;
 	struct clk_hw **hws;
 	struct clk_hw_onecell_data *clk_data;
 	struct device *dev = &sdev->dev;
@@ -168,8 +200,11 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 	clk_data->num = count;
 	hws = clk_data->hws;
 
+	is_atomic = handle->is_transport_atomic(handle, &atomic_threshold);
+
 	for (idx = 0; idx < count; idx++) {
 		struct scmi_clk *sclk;
+		const struct clk_ops *scmi_ops;
 
 		sclk = devm_kzalloc(dev, sizeof(*sclk), GFP_KERNEL);
 		if (!sclk)
@@ -184,13 +219,27 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 		sclk->id = idx;
 		sclk->ph = ph;
 
-		err = scmi_clk_ops_init(dev, sclk);
+		/*
+		 * Note that when transport is atomic but SCMI protocol did not
+		 * specify (or support) an enable_latency associated with a
+		 * clock, we default to use atomic operations mode.
+		 */
+		if (is_atomic &&
+		    sclk->info->enable_latency <= atomic_threshold)
+			scmi_ops = &scmi_atomic_clk_ops;
+		else
+			scmi_ops = &scmi_clk_ops;
+
+		err = scmi_clk_ops_init(dev, sclk, scmi_ops);
 		if (err) {
 			dev_err(dev, "failed to register clock %d\n", idx);
 			devm_kfree(dev, sclk);
 			hws[idx] = NULL;
 		} else {
-			dev_dbg(dev, "Registered clock:%s\n", sclk->info->name);
+			dev_dbg(dev, "Registered clock:%s%s\n",
+				sclk->info->name,
+				scmi_ops == &scmi_atomic_clk_ops ?
+				" (atomic ops)" : "");
 			hws[idx] = &sclk->hw;
 		}
 	}
-- 
2.17.1



From hverkuil at xs4all.nl  Mon Jan 24 02:22:46 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Mon, 24 Jan 2022 11:22:46 +0100
Subject: [PATCH v2 4/4] media: aspeed: Fix timing polarity incorrect
In-Reply-To: <b8707885-c10c-ca19-3f2c-f19f567e1f92@aspeedtech.com>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-5-jammy_huang@aspeedtech.com>
 <418fc1b2-ddbe-24e3-82cc-aa8ce74f4507@xs4all.nl>
 <b8707885-c10c-ca19-3f2c-f19f567e1f92@aspeedtech.com>
Message-ID: <2ddda01a-3f1f-eff6-6ce1-a5b9354f2993@xs4all.nl>

On 24/01/2022 03:29, Jammy Huang wrote:
> 
> On 2022/1/21 ?? 03:30, Hans Verkuil wrote:
>> On 12/22/21 09:21, Jammy Huang wrote:
>>> This is a workaround for sync polarity unstable.
>>> Sync value get by VR09C counts from sync's rising edge, which means
>>> sync's polarity is negative if sync value is bigger than total/2.
>> Do you have an example of such a format, or is this mostly theoretical?
>>
>> Either provide the example or make a note that it is theoretical.
> 
> OK, I will update an example in next patch. Let me explain first.
> 
> This is a must-be result. Please refer to the graph below as I sent in 3/4 of this
> series. For negative sync, sync width equals to back porch + data enable + front porch.
> Thus, sync would be bigger than 90% of total in most cases.

Right, I suspected that might be the case.

I think it would be better to combine patches 3 and 4 into a single
patch, since they are closely related and it is actually easier to
understand if it's just a single patch.

Regards,

	Hans

> 
> ????????????????? +-------------------+
> ????????????????? |??? v i d e o????? |
> ????? +--+? +-----+?????????????????? +-----+? +---+
> ???????? |? |?????????????????????????????? |? |
> ???????? +--+?????????????????????????????? +--+
> ?????? vsync+-------------------------------+
> ?? frame_top+-----+
> frame_bottom+-------------------------+
> 
> 
> Following registers are what I got for 1920x1200 at 60.
> 
> 1e700090: 07ee206f 04c9001a c4d3efff 04cc001f
> 
> 1e7000a0: 0000081f 00000000 00000000 00000000
> 
> vertical total = 0x4D3 (VR098[27:16]) = 1235
> vertical sync = 0x4CC (VR09C[27:16]) = 1228
> 
>>
>> Regards,
>>
>> ????Hans
>>
>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>> ---
>>> ? v2:
>>> ?? - Use 'total/2' rather than 'total<<1'
>>> ?? - Update comment
>>> ---
>>> ? drivers/media/platform/aspeed-video.c | 20 ++++++++++++++++++++
>>> ? 1 file changed, 20 insertions(+)
>>>
>>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>>> index 7c50567f5ab0..c3e3343d91e1 100644
>>> --- a/drivers/media/platform/aspeed-video.c
>>> +++ b/drivers/media/platform/aspeed-video.c
>>> @@ -989,6 +989,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>> ? ????????? video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>>> ????????? video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
>>> +
>>> +??????? /*
>>> +???????? * This is a workaround for polarity detection when the sync
>>> +???????? * value is larger than half.
>>> +???????? */
>>> +??????? if (vsync > (vtotal / 2))
>>> +??????????? det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
>>> +??????? else
>>> +??????????? det->polarities |= V4L2_DV_VSYNC_POS_POL;
>>> +
>>> ????????? if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>>> ????????????? det->vbackporch = video->frame_top - vsync;
>>> ????????????? det->vfrontporch = vtotal - video->frame_bottom;
>>> @@ -1003,6 +1013,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>> ? ????????? video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>>> ????????? video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
>>> +
>>> +??????? /*
>>> +???????? * This is a workaround for polarity detection when the sync
>>> +???????? * value is larger than half.
>>> +???????? */
>>> +??????? if (hsync > (htotal / 2))
>>> +??????????? det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
>>> +??????? else
>>> +??????????? det->polarities |= V4L2_DV_HSYNC_POS_POL;
>>> +
>>> ????????? if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>>> ????????????? det->hbackporch = video->frame_left - hsync;
>>> ????????????? det->hfrontporch = htotal - video->frame_right;
> 



From arnaud.pouliquen at foss.st.com  Mon Jan 24 02:25:17 2022
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Mon, 24 Jan 2022 11:25:17 +0100
Subject: [PATCH v9 04/11] arm: configs: Configs that had RPMSG_CHAR now get
 RPMSG_CTRL
In-Reply-To: <20220124102524.295783-1-arnaud.pouliquen@foss.st.com>
References: <20220124102524.295783-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20220124102524.295783-5-arnaud.pouliquen@foss.st.com>

In the patch "rpmsg: Move the rpmsg control device from rpmsg_char
to rpmsg_ctrl", we split the rpmsg_char driver in two.
By default give everyone who had the old driver enabled the rpmsg_ctrl
driver too.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm/configs/qcom_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig
index 9981566f2096..2e7e9a4f31f6 100644
--- a/arch/arm/configs/qcom_defconfig
+++ b/arch/arm/configs/qcom_defconfig
@@ -241,6 +241,7 @@ CONFIG_QCOM_Q6V5_PAS=y
 CONFIG_QCOM_Q6V5_PIL=y
 CONFIG_QCOM_WCNSS_PIL=y
 CONFIG_RPMSG_CHAR=y
+CONFIG_RPMSG_CTRL=y
 CONFIG_RPMSG_QCOM_GLINK_SMEM=y
 CONFIG_RPMSG_QCOM_SMD=y
 CONFIG_QCOM_COMMAND_DB=y
-- 
2.25.1



From arnaud.pouliquen at foss.st.com  Mon Jan 24 02:25:19 2022
From: arnaud.pouliquen at foss.st.com (Arnaud Pouliquen)
Date: Mon, 24 Jan 2022 11:25:19 +0100
Subject: [PATCH v9 06/11] arm64: defconfig: Config that had RPMSG_CHAR now
 gets RPMSG_CTRL
In-Reply-To: <20220124102524.295783-1-arnaud.pouliquen@foss.st.com>
References: <20220124102524.295783-1-arnaud.pouliquen@foss.st.com>
Message-ID: <20220124102524.295783-7-arnaud.pouliquen@foss.st.com>

In the patch "rpmsg: Move the rpmsg control device from rpmsg_char
to rpmsg_ctrl", we split the rpmsg_char driver in two.
By default give everyone who had the old driver enabled the rpmsg_ctrl
driver too.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen at foss.st.com>
cc: linux-arm-kernel at lists.infradead.org
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..485c55f19d68 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1039,6 +1039,7 @@ CONFIG_QCOM_Q6V5_PAS=m
 CONFIG_QCOM_SYSMON=m
 CONFIG_QCOM_WCNSS_PIL=m
 CONFIG_RPMSG_CHAR=m
+CONFIG_RPMSG_CTRL=m
 CONFIG_RPMSG_QCOM_GLINK_RPM=y
 CONFIG_RPMSG_QCOM_GLINK_SMEM=m
 CONFIG_RPMSG_QCOM_SMD=y
-- 
2.25.1



From suzuki.poulose at arm.com  Mon Jan 24 02:37:33 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Mon, 24 Jan 2022 10:37:33 +0000
Subject: [PATCH V2 0/2] coresight: trbe: Update existing errata for
 Cortex-X2
In-Reply-To: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
References: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <ecfce441-d79d-4a6b-b8b1-c45619eff78f@arm.com>

On 24/01/2022 03:15, Anshuman Khandual wrote:
> Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
> well. This series updates the errata definition and detection as required.
> This series applies on v5.17-rc1.
> 
> Relevant identification document can be found here.
> 
> https://developer.arm.com/documentation/101803/0200/AArch64-system-registers/
> AArch64-identification-register-summary/MIDR-EL1--Main-ID-Register
> 
> Relevant errata document can be found here.
> 
> https://developer.arm.com/documentation/SDEN1775100
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> 

For the series:

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>


From roger.lu at mediatek.com  Mon Jan 24 02:40:15 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 24 Jan 2022 18:40:15 +0800
Subject: [PATCH v21 5/8] soc: mediatek: SVS: add debug commands
In-Reply-To: <47bcbffc-42f6-335e-dfab-990e0ab5f103@collabora.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-6-roger.lu@mediatek.com>
 <47bcbffc-42f6-335e-dfab-990e0ab5f103@collabora.com>
Message-ID: <2404cea17479df35b5a5d55a923a96b10ebae909.camel@mediatek.com>

Hi AngeloGioacchino,

Sorry for the late reply and thanks for the advice.

On Fri, 2022-01-07 at 15:34 +0100, AngeloGioacchino Del Regno wrote:
> Il 07/01/22 10:51, Roger Lu ha scritto:
> > The purpose of SVS is to help find the suitable voltages
> > for DVFS. Therefore, if SVS bank voltages are concerned
> > to be wrong, we can adjust SVS bank voltages by this patch.
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > ---
> >   drivers/soc/mediatek/mtk-svs.c | 321 ++++++++++++++++++++++++++++++++-
> >   1 file changed, 318 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> > index 042c6e8e9069..93cdaecadd6d 100644
> > --- a/drivers/soc/mediatek/mtk-svs.c
> > +++ b/drivers/soc/mediatek/mtk-svs.c
> 
> ..snip..
> 
> > @@ -605,6 +896,16 @@ static void svs_set_bank_phase(struct svs_platform
> > *svsp,
> >   	}
> >   }
> >   
> > +static inline void svs_save_bank_register_data(struct svs_platform *svsp,
> > +					       enum svsb_phase phase)
> > +{
> > +	struct svs_bank *svsb = svsp->pbank;
> > +	enum svs_reg_index rg_i;
> > +
> 
> I think that it'd be a good idea to add an `enable` parameter, so that we
> don't always do a register dump; after all, this is a debugging feature and
> it's going to be completely irrelevant to the user, so keeping this disabled
> by default would ensure to get no performance degradation (even if small)
> unless really wanted.
> 
> So, in this case, here we'd have
> 
> 	if (!svsp->debug_enabled)
> 		return;

Thanks for pointing out the concern. Excuse us, we really need this to be
enabled by default. If we add a enable flag here, we'll face below problems and
make debug more difficult.

1. If we enable it afterward by cmd, init0[1~2] registers' data cannot be
recorded expectedly because the init flow has been finished already and won't be
run anymore. So, it doesn't work by using cmd to enable the flag.
2. If we add a enable flag here, it means we have to re-build the kernel load in
order to enable this flag. However, we cannot re-build the kernel load and needs
to debug directly sometimes. It's a sad situation... :(

> 
> > +	for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++)
> > +		svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i);
> > +}
> > +
> 
> Of course, this implies adding a new debugfs entry to enable/disable the
> debugging.
> Everything else looks good :)

Oh, excuse us, we have to keep the old design for better instant support and
thanks for the understanding.

> >   static inline void svs_error_isr_handler(struct svs_platform *svsp)
> >   {
> >   	struct svs_bank *svsb = svsp->pbank;
> > @@ -619,6 +920,8 @@ static inline void svs_error_isr_handler(struct
> > svs_platform *svsp)
> >   		svs_readl_relaxed(svsp, SMSTATE1));
> >   	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
> >   
> > +	svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR);
> > +
> >   	svsb->mode_support = SVSB_MODE_ALL_DISABLE;
> >   	svsb->phase = SVSB_PHASE_ERROR;

[snip]




From sudeep.holla at arm.com  Mon Jan 24 02:41:13 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Mon, 24 Jan 2022 10:41:13 +0000
Subject: [PATCH 16/54] cpufreq: replace cpumask_weight with cpumask_empty
 where appropriate
In-Reply-To: <20220123183925.1052919-17-yury.norov@gmail.com>
References: <20220123183925.1052919-1-yury.norov@gmail.com>
 <20220123183925.1052919-17-yury.norov@gmail.com>
Message-ID: <20220124104113.ccbcyipd5gtweulz@bogus>

On Sun, Jan 23, 2022 at 10:38:47AM -0800, Yury Norov wrote:
> drivers/cpufreq calls cpumask_weight() to check if any bit of a given
> cpumask is set. We can do it more efficiently with cpumask_empty() because
> cpumask_empty() stops traversing the cpumask as soon as it finds first set
> bit, while cpumask_weight() counts all bits unconditionally.
>

Reviewed-by: Sudeep Holla <sudeep.holla at arm.com> (for SCMI cpufreq driver)

-- 
Regards,
Sudeep


From roger.lu at mediatek.com  Mon Jan 24 02:48:08 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Mon, 24 Jan 2022 18:48:08 +0800
Subject: [PATCH v21 7/8] arm64: dts: mt8192: add svs device information
In-Reply-To: <010f9b6a-d6bf-b27a-cb2d-c5fd181c3ac7@collabora.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-8-roger.lu@mediatek.com>
 <010f9b6a-d6bf-b27a-cb2d-c5fd181c3ac7@collabora.com>
Message-ID: <3d3518ff5c332129af5d10766477b9776bbbf55e.camel@mediatek.com>

Hi AngeloGioacchino,

On Fri, 2022-01-07 at 15:33 +0100, AngeloGioacchino Del Regno wrote:
> Il 07/01/22 10:51, Roger Lu ha scritto:
> > Add compitable/reg/irq/clock/efuse/reset setting in svs node.
> 
> Typo: compitable => compatible
> .. also, you're not only adding the svs node, but also efuse: please add that
> information in the commit description.
> 
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> 
> This patch seems to not apply on top of the current linux-next, can you please
> rebase it? That would resolve issues with this series and would be picked
> sooner.
> 
> Apart from that...

Sorry to make you confuse. After having discussion internally, we'll submit
another complete mt8192.dtsi patch including this svs node. Therefore, I'll drop
this path from svs patchset in order not to make the reviewer confuse. Thanks
for the comments a lot.

> 
> Reviewed-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> 
> > ---
> >   arch/arm64/boot/dts/mediatek/mt8192.dtsi | 39 ++++++++++++++++++++++++
> >   1 file changed, 39 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > index c7c7d4e017ae..c111e26489dd 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8192.dtsi
> > @@ -9,6 +9,8 @@
> >   #include <dt-bindings/interrupt-controller/arm-gic.h>
> >   #include <dt-bindings/interrupt-controller/irq.h>
> >   #include <dt-bindings/pinctrl/mt8192-pinfunc.h>
> > +#include <dt-bindings/reset/ti-syscon.h>
> > +
> >   
> >   / {
> >   	compatible = "mediatek,mt8192";
> > @@ -268,6 +270,14 @@
> >   			compatible = "mediatek,mt8192-infracfg", "syscon";
> >   			reg = <0 0x10001000 0 0x1000>;
> >   			#clock-cells = <1>;
> > +
> > +			infracfg_rst: reset-controller {
> > +				compatible = "mediatek,infra-reset", "ti,syscon-
> > reset";
> > +				#reset-cells = <1>;
> > +				ti,reset-bits = <
> > +					0x150 5 0x154 5 0 0     (ASSERT_SET |
> > DEASSERT_SET | STATUS_NONE) /* 0: svs */
> > +				>;
> > +			};
> >   		};
> >   
> >   		pericfg: syscon at 10003000 {
> > @@ -362,6 +372,20 @@
> >   			status = "disabled";
> >   		};
> >   
> > +		svs: svs at 1100b000 {
> > +			compatible = "mediatek,mt8192-svs";
> > +			reg = <0 0x1100b000 0 0x1000>;
> > +			interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>;
> > +			clocks = <&infracfg CLK_INFRA_THERM>;
> > +			clock-names = "main";
> > +			nvmem-cells = <&svs_calibration>,
> > +				      <&lvts_e_data1>;
> > +			nvmem-cell-names = "svs-calibration-data",
> > +					   "t-calibration-data";
> > +			resets = <&infracfg_rst 0>;
> > +			reset-names = "svs_rst";
> > +		};
> > +
> >   		spi1: spi at 11010000 {
> >   			compatible = "mediatek,mt8192-spi",
> >   				     "mediatek,mt6765-spi";
> > @@ -479,6 +503,21 @@
> >   			#clock-cells = <1>;
> >   		};
> >   
> > +		efuse: efuse at 11c10000 {
> > +			compatible = "mediatek,efuse";
> > +			reg = <0 0x11c10000 0 0x1000>;
> > +			#address-cells = <1>;
> > +			#size-cells = <1>;
> > +
> > +			lvts_e_data1: data1 at 1c0 {
> > +				reg = <0x1c0 0x58>;
> > +			};
> > +
> > +			svs_calibration: calib at 580 {
> > +				reg = <0x580 0x68>;
> > +			};
> > +		};
> > +
> >   		i2c3: i2c3 at 11cb0000 {
> >   			compatible = "mediatek,mt8192-i2c";
> >   			reg = <0 0x11cb0000 0 0x1000>,
> > 
> 
> 



From jkchen at linux.alibaba.com  Mon Jan 24 03:00:18 2022
From: jkchen at linux.alibaba.com (Jay Chen)
Date: Mon, 24 Jan 2022 19:00:18 +0800
Subject: [PATCH] coresight: tmc: change device registration from misc to cdev
Message-ID: <20220124110018.68485-1-jkchen@linux.alibaba.com>

Currently, there are 130 etr and etf on our machine,
but the current coresight tmc driver uses misc_register
to register the device, which leads to the error that
the device number is not enough.

coresight-tmc: probe of xxxxx failed with error -16

This patch changes the device registration method
to cdev's dynamic registration method to solve the
problem of insufficient device numbers.

Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
 2 files changed, 91 insertions(+), 23 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index d0276af82494..0977f1ce6338 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -12,7 +12,6 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
@@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+static DEFINE_IDA(tmc_ida);
+static dev_t tmc_major;
+static struct class *tmc_class;
+
+#define TMC_DEV_MAX	(MINORMASK + 1)
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
 static int tmc_open(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_prepare(drvdata);
 	if (ret)
@@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 {
 	char *bufp;
 	ssize_t actual;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
 	if (actual <= 0)
 		return 0;
@@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 static int tmc_release(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_unprepare(drvdata);
 	if (ret)
@@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	u32 devid;
+	dev_t devt;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		goto out;
 	}
 
-	drvdata->miscdev.name = desc.name;
-	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
-	drvdata->miscdev.fops = &tmc_fops;
-	ret = misc_register(&drvdata->miscdev);
+	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err_coresight_unregister;
+
+	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
+	drvdata->cdev.cdev.owner = THIS_MODULE;
+	devt = MKDEV(MAJOR(tmc_major), ret);
+	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
 	if (ret)
-		coresight_unregister(drvdata->csdev);
-	else
+		goto err_free_tmc_ida;
+
+	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
+	if (IS_ERR(drvdata->cdev.dev)) {
+		ret = PTR_ERR(drvdata->cdev.dev);
+		goto err_delete_cdev;
+	} else
 		pm_runtime_put(&adev->dev);
+
+	return 0;
+
+err_delete_cdev:
+	cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
+	ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
+	coresight_unregister(drvdata->csdev);
 out:
 	return ret;
 }
@@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
 static void tmc_remove(struct amba_device *adev)
 {
 	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct device *dev = drvdata->cdev.dev;
 
-	/*
-	 * Since misc_open() holds a refcount on the f_ops, which is
-	 * etb fops in this case, device is there until last file
-	 * handler to this device is closed.
-	 */
-	misc_deregister(&drvdata->miscdev);
+	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
+	device_destroy(tmc_class, dev->devt);
+	cdev_del(&drvdata->cdev.cdev);
 	coresight_unregister(drvdata->csdev);
 }
 
@@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int __init tmc_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
+	if (ret < 0) {
+		pr_err("tmc: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	tmc_class = class_create(THIS_MODULE, "tmc");
+	if (IS_ERR(tmc_class)) {
+		pr_err("tmc: failed to create class\n");
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+		return PTR_ERR(tmc_class);
+	}
+
+	ret = amba_driver_register(&tmc_driver);
+	if (ret) {
+		pr_err("tmc: error registering amba driver\n");
+		class_destroy(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+	}
+
+	return ret;
+}
+
+static void __exit tmc_exit(void)
+{
+	amba_driver_unregister(&tmc_driver);
+	class_destroy(tmc_class);
+	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+
+module_init(tmc_init);
+module_exit(tmc_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6bec20a392b3..11441c6b9c26 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -7,9 +7,9 @@
 #ifndef _CORESIGHT_TMC_H
 #define _CORESIGHT_TMC_H
 
+#include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 
@@ -163,11 +163,16 @@ struct etr_buf {
 	void				*private;
 };
 
+struct tmc_cdev {
+	struct cdev cdev;
+	struct device *dev;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
- * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process being monitored by the session
  *		that is using this component.
@@ -191,7 +196,7 @@ struct etr_buf {
 struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
-	struct miscdevice	miscdev;
+	struct tmc_cdev		cdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
-- 
2.27.0



From sha at pengutronix.de  Mon Jan 24 03:03:31 2022
From: sha at pengutronix.de (Sascha Hauer)
Date: Mon, 24 Jan 2022 12:03:31 +0100
Subject: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
In-Reply-To: <trinity-2e9cf5db-4c9b-4ad7-b684-74541e639edf-1643014505272@3c-app-gmx-bs10>
References: <20220123135116.136846-1-linux@fw-web.de>
 <20220123135116.136846-3-linux@fw-web.de>
 <20220124083102.GW23490@pengutronix.de>
 <trinity-2e9cf5db-4c9b-4ad7-b684-74541e639edf-1643014505272@3c-app-gmx-bs10>
Message-ID: <20220124110331.GZ23490@pengutronix.de>

On Mon, Jan 24, 2022 at 09:55:05AM +0100, Frank Wunderlich wrote:
> Hi
> 
> > Gesendet: Montag, 24. Januar 2022 um 09:31 Uhr
> > Von: "Sascha Hauer" <sha at pengutronix.de>
> > An: "Frank Wunderlich" <linux at fw-web.de>
> > Cc: linux-rockchip at lists.infradead.org, "Frank Wunderlich" <frank-w at public-files.de>, "Rob Herring" <robh+dt at kernel.org>, "Heiko Stuebner" <heiko at sntech.de>, "Peter Geis" <pgwipeout at gmail.com>, "Johan Jonker" <jbx6244 at gmail.com>, devicetree at vger.kernel.org, linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
> > Betreff: Re: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
> >
> > On Sun, Jan 23, 2022 at 02:51:16PM +0100, Frank Wunderlich wrote:
> > > From: Frank Wunderlich <frank-w at public-files.de>
> > >
> > > This patch adds Devicetree for Bananapi R2 Pro based on RK3568.
> > > Add uart/sd/emmc/i2c/rk809/tsadc nodes for basic function.
> > > Gmac0 is directly connected to wan-port so usable without additional
> > > driver.
> > > On gmac1 there is a switch (rtl8367rb) connected which have not yet a
> > > driver in mainline.
> > >
> > > Patch also prepares nodes for GPIO header.
> > >
> > > Co-developed-by: Peter Geis <pgwipeout at gmail.com>
> > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > > Signed-off-by: Frank Wunderlich <frank-w at public-files.de>
> > > ---
> > > +&gmac0 {
> > > +	assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>;
> > > +	assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>;
> > > +	clock_in_out = "input";
> > > +	phy-handle = <&rgmii_phy0>;
> > > +	phy-mode = "rgmii";
> > > +	pinctrl-names = "default";
> > > +	pinctrl-0 = <&gmac0_miim
> > > +		     &gmac0_tx_bus2
> > > +		     &gmac0_rx_bus2
> > > +		     &gmac0_rgmii_clk
> > > +		     &gmac0_rgmii_bus>;
> > > +
> > > +	snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
> > > +	snps,reset-active-low;
> > > +	/* Reset time is 20ms, 100ms for rtl8211f */
> >
> > Is this really a rtl8211f? I don't know and it could indeed be a
> > rtl8211f, I'm just asking because the comment is copy pasted from
> > the Quartz64 board.
> 
> i know thats a RTL8211 phy, but i see no additional letter on the
> chip, based on shematics it's a RTL8211F-CG

Ok. I just wanted to make sure you checked that.

> 
> > > +	snps,reset-delays-us = <0 20000 100000>;
> > > +
> > > +&mdio0 {
> > > +	rgmii_phy0: ethernet-phy at 0 {
> > > +		compatible = "ethernet-phy-ieee802.3-c22";
> > > +		reg = <0x0>;
> > > +	};
> >
> > 0 is the broadcast address. I'm not sure if it's a good idea to use it.
> > There should be another address the phy listens on.
> 
> took this from the 3568-EVB (like the most parts, as the board is
> mostly the same), and in linux it's the same and working. The switch
> have also phy-id 0 on mdio bus #1, are you sure this is invalid?

It's not invalid, it's just the broadcast address to which other phys
might answer as well. Anyway, as long as there's only a single phy on
the bus it's probably okay.

Sascha


-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From quentin.schulz at theobroma-systems.com  Mon Jan 24 03:17:00 2022
From: quentin.schulz at theobroma-systems.com (Quentin Schulz)
Date: Mon, 24 Jan 2022 12:17:00 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
In-Reply-To: <CAMdYzYpT8BUrukUozRSQDHgiQHMPbS5GtV7huL4xFFRsdxw0qQ@mail.gmail.com>
References: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
 <CAMdYzYr+UXU-x=OakdHnOzLe1e4Y0xdGR-rybsmpLCMGbsWwXg@mail.gmail.com>
 <3e87ed0a-8b79-006a-dce6-62becc9906ef@theobroma-systems.com>
 <CAMdYzYpT8BUrukUozRSQDHgiQHMPbS5GtV7huL4xFFRsdxw0qQ@mail.gmail.com>
Message-ID: <fea9a91c-ccaa-15be-229e-60f78209cdce@theobroma-systems.com>

Hi Peter,

On 1/20/22 18:14, Peter Geis wrote:
> On Thu, Jan 20, 2022 at 11:03 AM Quentin Schulz
> <quentin.schulz at theobroma-systems.com> wrote:
>>
>> Hi Peter,
>>
>> On 1/20/22 16:06, Peter Geis wrote:
>>> On Wed, Jan 19, 2022 at 8:52 AM <quentin.schulz at theobroma-systems.com> wrote:
>>>>
>>>> From: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
>>>>
>>>> There are signal integrity issues running the eMMC at 200MHz on Puma
>>>> RK3399-Q7.
>>>>
>>>> Similar to the work-around found for RK3399 Gru boards, lowering the
>>>> frequency to 100MHz made the eMMC much more stable, so let's lower the
>>>> frequency to 100MHz.
>>>>
>>>> It might be possible to run at 150MHz as on RK3399 Gru boards but only
>>>> 100MHz was extensively tested.
>>>>
>>>> Cc: Quentin Schulz <foss+kernel at 0leil.net>
>>>> Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher at theobroma-systems.com>
>>>> Signed-off-by: Quentin Schulz <quentin.schulz at theobroma-systems.com>
>>>> ---
>>>>
>>>> Note/RFC: as opposed to gru DTSI, max-frequency is used here instead of
>>>> assigned-clock-rates.
>>>>
>>>> AFAIU, max-frequency applies to the SD bus rate, while
>>>> assigned-clock-rates applies to the clock fed to the SD host controller
>>>> inside the SoC. max-frequency does not interact with the clock subsystem
>>>> AFAICT. assigned-clock-rates sets the clock rate at probe, regardless of
>>>> eMMC tuning.
>>>> Technically, the Arasan SDHC IP supports silicon-hardcoded clock
>>>> multiplier so I think setting assigned-clock-rates as a way of rate
>>>> limiting the eMMC block is incorrect and max-frequency should be used
>>>> instead (as done in this patch). Otherwise the SDHC could still potentially
>>>> derive a 200MHz clock from a lower rate clock thanks to its multiplier.
>>>>
>>>>    arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi | 6 ++++++
>>>>    1 file changed, 6 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>>>> index fb67db4619ea..a6108578aae0 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
>>>> @@ -425,6 +425,12 @@ vcc5v0_host_en: vcc5v0-host-en {
>>>>    };
>>>>
>>>>    &sdhci {
>>>> +       /*
>>>> +        * Signal integrity isn't great at 200MHz but 100MHz has proven stable
>>>> +        * enough.
>>>> +        */
>>>> +       max-frequency = <100000000>;
>>>> +
>>>>           bus-width = <8>;
>>>>           mmc-hs400-1_8v;
>>>>           mmc-hs400-enhanced-strobe;
>>>
>>> I don't have these boards nor the schematics handy for them, but
>>> wouldn't it be better to simply switch to mmc-hs200-1_8v?
>>
>> Thanks for the suggestion, I just tested, by removing mmc-hs400-1_8v;
>> and mmc-hs400-enhanced-strobe; but keeping the clock rate at 200MHz and
>> adding mmc-hs200-1_8v; failed a basic dd test.
> 
> Quite understandable.
> I more meant it may permit you to reach a higher clock rate than
> 100mhz and thus possibly a higher data rate, for example perhaps
> 150mhz would be reachable.
> For example I would do a bandwidth test for hs400-es at 100mhz, then
> test at hs200 and find the maximum stable clock rate.
> If 200mhz is stable enough to probe and /sys/kernel/debug/mmc<x>/ios
> shows you are in 8bit hs200, you can adjust the clock rate through
> /sys/kernel/debug/mmc<x>/clock without needing to reboot.
> It will speed up testing.
> 
> If hs200 permits a higher overall data rate than hs400-es, it would be
> worth making that switch.
> 

Got the HW dept to look into this and they said that since the main 
difference between HS200 and HS400-ES is that for the same clock rate, 
twice the data rate is possible and that the signal integrity issue we 
have is on the clock line, anything that impacts HS400-ES wrt clock rate 
will impact HS200 too. Therefore HS200 should practically be half data 
rate on our board and no improvement should be observed.

Lemme know if there's something we misunderstood or check more thoroughly.

Thanks!
Quentin

> Always,
> Peter
> 
>>
>> Cheers,
>> Quentin
>>
>>> Other rk3399 boards don't have issues with hs200 at full 200mhz, and
>>> as I understand it hs400-es exhibits stability issues on most rk3399
>>> boards.
>>>
>>> Feel free to disregard my comments if you've already tested this.
>>>
>>>> --
>>>> 2.34.1
>>>>
>>>>
>>>> _______________________________________________
>>>> Linux-rockchip mailing list
>>>> Linux-rockchip at lists.infradead.org
>>>> https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_mailman_listinfo_linux-2Drockchip&d=DwIBaQ&c=_sEr5x9kUWhuk4_nFwjJtA&r=LYjLexDn7rXIzVmkNPvw5ymA1XTSqHGq8yBP6m6qZZ4njZguQhZhkI_-172IIy1t&m=OTusi9XARCbef1Ba5t1gv4_LqRkOaxFY3UtvYky6NVLpeiziqqmdOJ8-R5WXWFNr&s=xBnqhBu20rxvu_V-5EhXyA_yNxcJpa4Dq6HO2Ow3Gk8&e=


From angelogioacchino.delregno at collabora.com  Mon Jan 24 03:40:48 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 12:40:48 +0100
Subject: [PATCH v11 1/3] dt-binding: mt8183: add Mediatek MDP3 dt-bindings
In-Reply-To: <YesiwTSxa9HJ1lxG@robh.at.kernel.org>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-2-moudy.ho@mediatek.com>
 <YesiwTSxa9HJ1lxG@robh.at.kernel.org>
Message-ID: <815a363d-749e-d7a5-3786-c11dfd4d22d4@collabora.com>

Il 21/01/22 22:16, Rob Herring ha scritto:
> On Wed, Jan 05, 2022 at 05:37:56PM +0800, Moudy Ho wrote:

Hello Rob,

since I'm not the best at reviewing dt-bindings, I always try to leave that to

other reviewers; in which case, thank you for your awesome review activity on

all of these (and helping me a lot on some of my attempts to write yaml..!!)


In this case, though, since I do have knowledge about the platform, it's probably
worth for me to try to address some of your questions, on at least this one.


>> This patch adds DT binding document for Media Data Path 3 (MDP3)
>> a unit in multimedia system used for scaling and color format convert.
>>
>> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
>> ---
>>   .../bindings/media/mediatek,mdp3-rdma.yaml    | 193 ++++++++++++++++++
>>   .../bindings/media/mediatek,mdp3-rsz.yaml     |  55 +++++
>>   .../bindings/media/mediatek,mdp3-wrot.yaml    |  57 ++++++
>>   .../bindings/soc/mediatek/mediatek,ccorr.yaml |  47 +++++
>>   .../bindings/soc/mediatek/mediatek,wdma.yaml  |  58 ++++++
>>   5 files changed, 410 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>>   create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>>   create mode 100644 Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
>>   create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
>>   create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>> new file mode 100644
>> index 000000000000..002503383934
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
>> @@ -0,0 +1,193 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Mediatek Read Direct Memory Access
>> +
>> +maintainers:
>> +  - Matthias Brugger <matthias.bgg at gmail.com>
>> +
>> +description: |
>> +  Mediatek Read Direct Memory Access(RDMA) component used to do read DMA.
>> +  It contains one line buffer to store the sufficient pixel data, and
>> +  must be siblings to the central MMSYS_CONFIG node.
>> +  For a description of the MMSYS_CONFIG binding, see
>> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
>> +  for details.
>> +  The 1st RDMA is also used to be a controller node in Media Data Path 3(MDP3)
>> +  that containing MMSYS, MUTEX, GCE and SCP settings.
>> +
>> +properties:
>> +  compatible:
>> +    oneOf:
>> +      - items:
>> +          # MDP3 controller node
>> +          - const: mediatek,mt8183-mdp3
> 
> How is this more specific than this:
> 
>> +          - const: mediatek,mt8183-mdp3-rdma0
> 

Probably, oneOf is not the right choice here... "mediatek,mt8183-mdp3" is needed
to probe the "main" mdp3 core pdev, while RDMA0 is a necessary component (as in
this driver uses the component framework, and rdma0 is required for functionality,
as far as I understand).

This shouldn't be a choice, meaning that defining mdp3-rdma0 without mdp3 is
completely useless, as there wouldn't be anything else initializing that component,
nor sub-components of that.

>> +      - items:
>> +          # normal RDMA conponent
>> +          - const: mediatek,mt8183-mdp3-rdma0
>> +
>> +  mediatek,scp:
>> +    description: The node of system control processor (SCP), using
>> +      the remoteproc & rpmsg framework.
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    maxItems: 1
>> +
>> +  mediatek,mdp3-comps:
>> +    description: MTK sub-system of direct-link or DIP
> 
> This needs a better description. What is DIP? What is direct-link?

I agree, this needs a better description.

> 
>> +    $ref: /schemas/types.yaml#/definitions/string-array
>> +    items:
>> +      - enum:
>> +          # MDP direct-link input path selection, create a
>> +          # component for path connectedness of HW pipe control
>> +          - mediatek,mt8183-mdp3-dl1
>> +      - enum:
>> +          - mediatek,mt8183-mdp3-dl2
>> +      - enum:
>> +          # MDP direct-link output path selection, create a
>> +          # component for path connectedness of HW pipe control
>> +          - mediatek,mt8183-mdp3-path1
>> +      - enum:
>> +          - mediatek,mt8183-mdp3-path2
>> +      - enum:
>> +          # Input DMA of ISP PASS2 (DIP) module for raw image input
>> +          - mediatek,mt8183-mdp3-imgi
>> +      - enum:
>> +          # Output DMA of ISP PASS2 (DIP) module for YUV image output
>> +          - mediatek,mt8183-mdp3-exto
> 
> There's only 1 possible value for mediatek,mdp3-comps, so why does it
> need to be in DT?
> 

The wanted logic here (I believe) is that, depending on firmware capabilities
and/or platform/board capabilities, you may miss some subcomponents like IMGI
and/or EXTO.
As for DL1/2 and PATH1/2... DL1+PATH1 is surely critically necessary for the
functionality of the MDP3 RDMA... I don't know whether it's possible that we
get any fw/platform/device that's not using DL2/PATH2 at all.

Moudy, can you please explain?

>> +
>> +  reg:
>> +    items:
>> +      - description: basic RDMA HW address
>> +      - description: MDP direct-link 1st and 2nd input
>> +      - description: MDP direct-link 1st output
>> +      - description: MDP direct-link 2nd output
>> +      - description: ISP input and output
>> +
>> +  mediatek,gce-client-reg:
>> +    description: The register of client driver can be configured by gce with
>> +      4 arguments defined in this property, such as phandle of gce, subsys id,
>> +      register offset and size. Each GCE subsys id is mapping to a client
>> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +    items:
>> +      - description: GCE client for RDMA
>> +      - description: GCR client for MDP direct-link 1st and 2nd input
>> +      - description: GCR client for MDP direct-link 1st output
>> +      - description: GCR client for MDP direct-link 2nd output
>> +      - description: GCR client for ISP input and output
>> +
>> +  power-domains:
>> +    maxItems: 1
>> +
>> +  clocks:
>> +    items:
>> +      - description: RDMA clock
>> +      - description: RSZ clock
>> +      - description: direck-link TX clock in MDP side
>> +      - description: direck-link RX clock in MDP side
>> +      - description: direck-link TX clock in ISP side
>> +      - description: direck-link RX clock in ISP side
>> +
>> +  iommus:
>> +    maxItems: 1
>> +
>> +  mediatek,mmsys:
>> +    description: The node of mux(multiplexer) controller for HW connections.
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> +  mediatek,mm-mutex:
> 
> Is this some sort of h/w lock? We have a standard binding for that.
> 

There's a story behind that one: this was part of mtk (display) DRM drivers, then
it was moved to soc/mediatek/mtk-mutex.c as it started being shared.

I wonder if the mm-mutex can be rewritten and moved to hwspinlock... this driver
is growing and now, with the introduction of MDP3, we're seeing some more.

Though, it's definitely worth mentioning that the usage of MediaTek's mm-mutex is
varying a bit between the drm case and the mdp3 case as, here, we have a "command
queue" mechanism that is used for commands ordering in HW.
This is a very complex architecture that has very specific requirements.
For how I see it, migrating that to hwspinlock would require an almost complete
reimplementation of soc/mediatek/*, which would take a considerable amount of
time and efforts.
I'm mostly sure that I can help with that, but for how things are looking right

now, between refactoring, getting code solid, going through sane reviews and a
final merge, I'd say that this will take 8-12 months from now.

For this reason, I would propose to perform a slow and steady migration of the
MediaTek mmsys, scpsys, mutex over time, but only after getting in the support
for the new SoCs and functionality for the older ones, provided in this series
and some others that were already sent by MTK, half (or more) of which have
already been merged.

>> +    description: The node of sof(start of frame) signal controller.
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +    maxItems: 1
>> +
>> +  mediatek,mailbox-gce:
>> +    description: The node of global command engine (GCE), used to read/write
>> +      registers with critical time limitation.
>> +    $ref: /schemas/types.yaml#/definitions/phandle
>> +
>> +  mboxes:
>> +    items:
>> +      - description: used for 1st data pipe from RDMA
>> +      - description: used for 2nd data pipe from RDMA
>> +      - description: used for 3rd data pipe from Direct-Link
>> +      - description: used for 4th data pipe from Direct-Link
>> +
>> +  gce-subsys:
>> +    description: sub-system id corresponding to the global command engine (GCE)
>> +      register address.
>> +    $ref: /schemas/types.yaml#/definitions/phandle-array
>> +
>> +if:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        const: mediatek,mt8183-mdp3
>> +
>> +then:
>> +  required:
>> +    - mediatek,scp
>> +    - mediatek,mmsys
>> +    - mediatek,mm-mutex
>> +    - mediatek,mailbox-gce
>> +    - mboxes
>> +    - gce-subsys
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - clocks
>> +  - mediatek,gce-client-reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    #include <dt-bindings/clock/mt8183-clk.h>
>> +    #include <dt-bindings/gce/mt8183-gce.h>
>> +    #include <dt-bindings/power/mt8183-power.h>
>> +    #include <dt-bindings/memory/mt8183-larb-port.h>
>> +
>> +    mdp3_rdma0: mdp3_rdma0 at 14001000 {
>> +      compatible = "mediatek,mt8183-mdp3",
>> +                   "mediatek,mt8183-mdp3-rdma0";
>> +      mediatek,scp = <&scp>;
>> +      mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
>> +                            "mediatek,mt8183-mdp3-dl2",
>> +                            "mediatek,mt8183-mdp3-path1",
>> +                            "mediatek,mt8183-mdp3-path2",
>> +                            "mediatek,mt8183-mdp3-imgi",
>> +                            "mediatek,mt8183-mdp3-exto";
>> +      reg = <0x14001000 0x1000>,
>> +            <0x14000000 0x1000>,
>> +            <0x14005000 0x1000>,
>> +            <0x14006000 0x1000>,
>> +            <0x15020000 0x1000>;
>> +      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>,
>> +                                <&gce SUBSYS_1400XXXX 0 0x1000>,
>> +                                <&gce SUBSYS_1400XXXX 0x5000 0x1000>,
>> +                                <&gce SUBSYS_1400XXXX 0x6000 0x1000>,
>> +                                <&gce SUBSYS_1502XXXX 0 0x1000>;
>> +      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
>> +      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
>> +               <&mmsys CLK_MM_MDP_RSZ1>,
>> +               <&mmsys CLK_MM_MDP_DL_TXCK>,
>> +               <&mmsys CLK_MM_MDP_DL_RX>,
>> +               <&mmsys CLK_MM_IPU_DL_TXCK>,
>> +               <&mmsys CLK_MM_IPU_DL_RX>;
>> +      iommus = <&iommu>;
>> +      mediatek,mmsys = <&mmsys>;
>> +      mediatek,mm-mutex = <&mutex>;
>> +      mediatek,mailbox-gce = <&gce>;
>> +      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
>> +               <&gce 21 CMDQ_THR_PRIO_LOWEST>,
>> +               <&gce 22 CMDQ_THR_PRIO_LOWEST>,
>> +               <&gce 23 CMDQ_THR_PRIO_LOWEST>;
>> +      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
>> +                   <&gce 0x14010000 SUBSYS_1401XXXX>,
>> +                   <&gce 0x14020000 SUBSYS_1402XXXX>,
>> +                   <&gce 0x15020000 SUBSYS_1502XXXX>;
>> +    };
>> diff --git a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>> new file mode 100644
>> index 000000000000..cd4cf1531535
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
>> @@ -0,0 +1,55 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Mediatek Resizer
>> +
>> +maintainers:
>> +  - Matthias Brugger <matthias.bgg at gmail.com>
>> +
>> +description: |
>> +  One of Media Data Path 3 (MDP3) components used to do frame resizing.
>> +
>> +properties:
>> +  compatible:
>> +    items:
>> +      - enum:
>> +          - mediatek,mt8183-mdp3-rsz0
>> +          - mediatek,mt8183-mdp3-rsz1
> 
> Again, what's the difference between 0 and 1?
> 
> I've probably asked that before, but without a sufficient reasoning
> here in the schema I'm just going to keep asking the same question.

This can probably be, instead, something like

compatible = "mediatek,mt8183-mdp3-rsz";
reg = < .... >;
mediatek,instance-id = <0>;
gce reg, clocks, blah...

or

compatible = "mediatek,mt8183-mdp3-rsz";
reg = < ...rsz0... >, < ...rsz1... >;
reg-names = "rsz0", "rsz1";
gce reg, clocks, blah...


...In any case, if MediaTek chose to separate these like that, I guess that
there will be differences in newer SoCs that would make that kind of binding
much necessary.

Please Moudy, can you explain why you didn't write that like the examples
that I provided there?

> 
> Rob
> 




From catalin.marinas at arm.com  Mon Jan 24 03:45:14 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 24 Jan 2022 11:45:14 +0000
Subject: [PATCH v3] arm64: mte: avoid clearing PSTATE.TCO on entry unless
 necessary
In-Reply-To: <20220122010250.251885-1-pcc@google.com>
References: <20220122010250.251885-1-pcc@google.com>
Message-ID: <Ye6RSlb0LkegxSKa@arm.com>

On Fri, Jan 21, 2022 at 05:02:50PM -0800, Peter Collingbourne wrote:
> diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
> index 075539f5f1c8..5352db4c0f45 100644
> --- a/arch/arm64/include/asm/mte.h
> +++ b/arch/arm64/include/asm/mte.h
> @@ -11,7 +11,9 @@
>  #ifndef __ASSEMBLY__
>  
>  #include <linux/bitfield.h>
> +#include <linux/kasan.h>
>  #include <linux/page-flags.h>
> +#include <linux/sched.h>
>  #include <linux/types.h>
>  
>  #include <asm/pgtable-types.h>
> @@ -86,6 +88,23 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
>  
>  #endif /* CONFIG_ARM64_MTE */
>  
> +static inline void mte_disable_tco_entry(struct task_struct *task)
> +{
> +	/*
> +	 * Re-enable tag checking (TCO set on exception entry). This is only
> +	 * necessary if MTE is enabled in either the kernel or the userspace
> +	 * task in synchronous mode. With MTE disabled in the kernel and
> +	 * disabled or asynchronous in userspace, tag check faults (including in
> +	 * uaccesses) are not reported, therefore there is no need to re-enable
> +	 * checking. This is beneficial on microarchitectures where re-enabling
> +	 * TCO is expensive.
> +	 */

I'd add a note here that the 1ULL << SCTLR_EL1_TCF0_SHIFT is meant to
check for both synchronous and asymmetric modes even if we don't have
the latter supporting the user yet. We do have the definitions already.

> +	if (kasan_hw_tags_enabled() ||
> +	    (system_supports_mte() &&
> +	     (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT))))
> +		asm volatile(SET_PSTATE_TCO(0));
> +}

Does it make a difference in code generation if you place a:

	if (!system_supports_mte())
		return;

at the beginning of the function (and remove the subsequent check)? It's
probably also easier to read, though the code generation depends on the
likely/unlikely choices for the static branches involved.

> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index f418ebc65f95..5345587f3384 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -252,6 +252,7 @@ void mte_thread_switch(struct task_struct *next)
>  
>  	mte_update_sctlr_user(next);
>  	mte_update_gcr_excl(next);
> +	mte_disable_tco_entry(next);

Maybe a one-line comment here that TCO may not have been disabled on
exception entry for the current task.

Otherwise it looks good to me:

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From angelogioacchino.delregno at collabora.com  Mon Jan 24 03:49:39 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 12:49:39 +0100
Subject: [PATCH v21 7/8] arm64: dts: mt8192: add svs device information
In-Reply-To: <3d3518ff5c332129af5d10766477b9776bbbf55e.camel@mediatek.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-8-roger.lu@mediatek.com>
 <010f9b6a-d6bf-b27a-cb2d-c5fd181c3ac7@collabora.com>
 <3d3518ff5c332129af5d10766477b9776bbbf55e.camel@mediatek.com>
Message-ID: <ffafbbf6-3049-ec14-da24-18b6f1b4d147@collabora.com>

Il 24/01/22 11:48, Roger Lu ha scritto:
> Hi AngeloGioacchino,
> 
> On Fri, 2022-01-07 at 15:33 +0100, AngeloGioacchino Del Regno wrote:
>> Il 07/01/22 10:51, Roger Lu ha scritto:
>>> Add compitable/reg/irq/clock/efuse/reset setting in svs node.
>>
>> Typo: compitable => compatible
>> .. also, you're not only adding the svs node, but also efuse: please add that
>> information in the commit description.
>>
>>>
>>> Signed-off-by: Roger Lu <roger.lu at mediatek.com>
>>
>> This patch seems to not apply on top of the current linux-next, can you please
>> rebase it? That would resolve issues with this series and would be picked
>> sooner.
>>
>> Apart from that...
> 
> Sorry to make you confuse. After having discussion internally, we'll submit
> another complete mt8192.dtsi patch including this svs node. Therefore, I'll drop
> this path from svs patchset in order not to make the reviewer confuse. Thanks
> for the comments a lot.
> 

Yes that decision looks good to me, as this allows different maintainers
to apply patches on a per-subsystem basis.
Thanks!

Regards,
Angelo


From frank-w at public-files.de  Mon Jan 24 03:49:43 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Mon, 24 Jan 2022 12:49:43 +0100
Subject: Aw: Re: Re: [PATCH v2 2/2] arm64: dts: rockchip: Add Bananapi R2 Pro
In-Reply-To: <20220124110331.GZ23490@pengutronix.de>
References: <20220123135116.136846-1-linux@fw-web.de>
 <20220123135116.136846-3-linux@fw-web.de>
 <20220124083102.GW23490@pengutronix.de>
 <trinity-2e9cf5db-4c9b-4ad7-b684-74541e639edf-1643014505272@3c-app-gmx-bs10>
 <20220124110331.GZ23490@pengutronix.de>
Message-ID: <trinity-263c703e-80d0-4663-9a42-21b9b7cb57e5-1643024983188@3c-app-gmx-bs10>

> Gesendet: Montag, 24. Januar 2022 um 12:03 Uhr
> Von: "Sascha Hauer" <sha at pengutronix.de>

> On Mon, Jan 24, 2022 at 09:55:05AM +0100, Frank Wunderlich wrote:

> > took this from the 3568-EVB (like the most parts, as the board is
> > mostly the same), and in linux it's the same and working. The switch
> > have also phy-id 0 on mdio bus #1, are you sure this is invalid?

just to clarify: in linux dts only the basics were taken from evb and changed if
needed (like iodomain, regulators).
mixed this with the barebox submsission where i mainly used the evb dts.

should i add a note in head that some parts are taken from EVB and vendors dts?
As this is my first new DTS, i want to be sure the legal notice is correct.

> It's not invalid, it's just the broadcast address to which other phys
> might answer as well. Anyway, as long as there's only a single phy on
> the bus it's probably okay.

ok, on mdio0 there is the rtl8211 phy and on mdio1 there is the rtl8367rb switch,
so only 1 device per bus. I was not aware that 0 is broadcast.

regards Frank


From jwboyer at kernel.org  Mon Jan 24 03:50:40 2022
From: jwboyer at kernel.org (Josh Boyer)
Date: Mon, 24 Jan 2022 06:50:40 -0500
Subject: pull request: linux-firmware: mediatek: Update MT8173 VPU
In-Reply-To: <20220122125029.22195-1-irui.wang@mediatek.com>
References: <20220122125029.22195-1-irui.wang@mediatek.com>
Message-ID: <CA+5PVA5Vg9h2kK6_xO2Nz2nw=u29i0=C1WOkbQjXDA0-DZhjOw@mail.gmail.com>

On Sat, Jan 22, 2022 at 7:50 AM Irui Wang <irui.wang at mediatek.com> wrote:
>
> Hi linux-firmware maintainers,
>
> The following changes since commit 0c6a7b3bf728b95c8b7b95328f94335e2bb2c967:
>
>   linux-firmware: Update firmware file for Intel Bluetooth 9260 (2022-01-19 11:16:28 -0500)
>
> are available in the Git repository at:
>
>   https://github.com/irui-wang/linux_fw_vpu_v1.1.7.git v1.1.7
>
> for you to fetch changes up to 70390331db03113fd7fe1dff195b135a7f2ad840:
>
>   linux-firmware: mediatek: Update MT8173 VPU firmware to v1.1.7 (2022-01-22 20:30:38 +0800)
>
> ----------------------------------------------------------------
> Irui Wang (1):
>       linux-firmware: mediatek: Update MT8173 VPU firmware to v1.1.7
>
>  mediatek/mt8173/vpu_d.bin | Bin 2977184 -> 2977184 bytes
>  mediatek/mt8173/vpu_p.bin | Bin 131180 -> 131180 bytes
>  2 files changed, 0 insertions(+), 0 deletions(-)

Pulled and pushed out.

josh


From alexandru.elisei at arm.com  Mon Jan 24 03:51:48 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 24 Jan 2022 11:51:48 +0000
Subject: [BUG] rockpro64-v2: NULL pointer dereference when booting
Message-ID: <Ye6S1PBAHtWj1lRp@monolith.localdoman>

Hi,

When booting a rockpro64-v2 with a kernel built from commit dd81e1c7d5fb
("Merge tag 'powerpc-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux"),
which was the latest commit when ran the tests, I encounter a NULL pointer
dereference:

[..]
[    0.000000] Kernel command line: root=PARTUUID=7f4aab92-69d8-47f3-be10-624da40a71f9 rw earlycon rootwait
[..]
[    3.396944] hub 7-0:1.0: USB hub found
[    3.397575] hub 7-0:1.0: 1 port detected
[    3.406086] ohci-platform fe3e0000.usb: Generic Platform OHCI controller
[    3.406932] ohci-platform fe3e0000.usb: new USB bus registered, assigned bus number 8
[    3.408530] ohci-platform fe3e0000.usb: irq 38, io mem 0xfe3e0000
[    3.476869] hub 8-0:1.0: USB hub found
[    3.477501] hub 8-0:1.0: 1 port detected
[    3.483278] rk808 0-001b: chip id: 0x0
[    3.498495] random: fast init done
[    3.509322] rk808-regulator rk808-regulator: there is no dvs0 gpio
[    3.510143] rk808-regulator rk808-regulator: there is no dvs1 gpio
[    3.569278] OF: graph: no port node found in /i2c at ff3d0000/typec-portc at 22
[    3.573471] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[    3.574466] Mem abort info:
[    3.574800]   ESR = 0x96000004
[    3.575163]   EC = 0x25: DABT (current EL), IL = 32 bits
[    3.575770]   SET = 0, FnV = 0
[    3.576204]   EA = 0, S1PTW = 0
[    3.576580]   FSC = 0x04: level 0 translation fault
[    3.577140] Data abort info:
[    3.577482]   ISV = 0, ISS = 0x00000004
[    3.577927]   CM = 0, WnR = 0
[    3.578279] [0000000000000000] user address but active_mm is swapper
[    3.579065] Internal error: Oops: 96000004 [#1] PREEMPT SMP
[    3.579586] Modules linked in:
[    3.579880] CPU: 5 PID: 7 Comm: kworker/u12:0 Not tainted 5.16.0-rc6-00081-g730b49aac426 #244
[    3.580667] Hardware name: Pine64 RockPro64 v2.0 (DT)
[    3.581135] Workqueue: events_unbound deferred_probe_work_func
[    3.581689] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[    3.582335] pc : component_master_add_with_match+0x20/0xfc
[    3.582850] lr : typec_link_ports+0x58/0x8c
[    3.583244] sp : ffff800013093980
[    3.583553] x29: ffff800013093980 x28: ffff80001212b000 x27: ffff00000041d00d
[    3.584223] x26: ffff0000063e85e0 x25: ffff800012fcb290 x24: ffff000001386820
[    3.584891] x23: ffff000006c2e808 x22: ffff800011416670 x21: ffff000006c2e808
[    3.585558] x20: 0000000000000000 x19: ffff000006c2e800 x18: ffffffffffffffff
[    3.586224] x17: 000000040044ffff x16: 00400034b5503510 x15: 0000000000005ff9
[    3.586890] x14: 0000000000000000 x13: 0000000000000003 x12: ffff0000063e8080
[    3.587557] x11: 0000000000000005 x10: ffff800012c13a60 x9 : 0000000000000000
[    3.588224] x8 : 0000200000000000 x7 : 0000000000000038 x6 : 000000000000004b
[    3.588892] x5 : 0000000000000000 x4 : ffff000000711800 x3 : ffff800010cd6390
[    3.589558] x2 : 0000000000000000 x1 : ffff800011416670 x0 : ffff000006c2e808
[    3.590224] Call trace:
[    3.590457]  component_master_add_with_match+0x20/0xfc
[    3.590938]  typec_link_ports+0x58/0x8c
[    3.591299]  typec_register_port+0x1ac/0x300
[    3.591705]  tcpm_register_port+0x62c/0x90c
[    3.592099]  fusb302_probe+0x260/0x430
[    3.592453]  i2c_device_probe+0x338/0x370
[    3.592835]  really_probe.part.0+0x9c/0x30c
[    3.593229]  __driver_probe_device+0x98/0x144
[    3.593639]  driver_probe_device+0xc8/0x160
[    3.594033]  __device_attach_driver+0xb8/0x120
[    3.594450]  bus_for_each_drv+0x78/0xd0
[    3.594810]  __device_attach+0xd8/0x180
[    3.595171]  device_initial_probe+0x14/0x20
[    3.595565]  bus_probe_device+0x9c/0xa4
[    3.595926]  deferred_probe_work_func+0x88/0xc4
[    3.596351]  process_one_work+0x288/0x6e0
[    3.596729]  worker_thread+0x220/0x464
[    3.597081]  kthread+0x17c/0x190
[    3.597392]  ret_from_fork+0x10/0x20
[    3.597737] Code: aa0203f4 a9025bf5 aa0003f5 aa0103f6 (a9400440) 
[    3.598301] ---[ end trace 823a8d1795013b55 ]---

The full log can be found at [1]; config file can be found at [2]. All
pastebins expire after 6 months.

I tried bisecting the bug and the first bad commit is 730b49aac426 ("usb:
typec: port-mapper: Convert to the component framework"). I tried to double
check that the patch is indeed responsible by reverting it from master, but
I got this build error:

drivers/usb/typec/port-mapper.c: In function 'typec_link_ports':
drivers/usb/typec/port-mapper.c:256:15: error: implicit declaration of function 'usb_for_each_port'; did you mean 'usb_for_each_dev'? [-Werror=implicit-function-declaration]
  256 |         ret = usb_for_each_port(&con->dev, each_port);
      |               ^~~~~~~~~~~~~~~~~
      |               usb_for_each_dev

I tried building and booting from the bad commit, and I got the same NULL
pointer dereference error. When building from the last good commit
(8c67d06f3fd9 ("usb: Link the ports to the connectors they are attached
to")), the board boots just fine. The log when booting from the good commit
can be found at [3].

I can help with debugging and testing, but I'm not familiar enough with the
USB subsystem to fix it myself.

[1] https://pastebin.com/w4tMNhve
[2] https://pastebin.com/SiUuLeMs
[3] https://pastebin.com/Pcm9xmL7

Thanks,
Alex


From alistair at alistair23.me  Mon Jan 24 04:00:27 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:00:27 +1000
Subject: [PATCH v2] watchdog: imx2_wdg: Alow ping on suspend
Message-ID: <20220124120027.106754-1-alistair@alistair23.me>

The i.MX watchdog cannot be disabled by softwrae once it has been
enabled. This means that it can't be stopped before suspend.

For systems that enter low power mode this is fine, as the watchdog will
be automatically stopped by hardwrae in low power mode. Not all i.MX
platforms support low power mode in the mainline kernel. For example the
i.MX7D does not enter low power mode and so will be rebooted 2 minutes
after entering freeze or mem sleep states.

This patch introduces a device tree property "fsl,ping-during-suspend"
that can be used to enable ping on suspend support for these systems.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 51bfb796898b..d0c5d47ddede 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -66,6 +66,7 @@ struct imx2_wdt_device {
 	struct watchdog_device wdog;
 	bool ext_reset;
 	bool clk_is_on;
+	bool no_ping;
 };
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
 
 	wdev->ext_reset = of_property_read_bool(dev->of_node,
 						"fsl,ext-reset-output");
+	/*
+	 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
+	 * during suspend.
+	 */
+	wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
 	platform_set_drvdata(pdev, wdog);
 	watchdog_set_drvdata(wdog, wdev);
 	watchdog_set_nowayout(wdog, nowayout);
 	watchdog_set_restart_priority(wdog, 128);
 	watchdog_init_timeout(wdog, timeout, dev);
-	watchdog_stop_ping_on_suspend(wdog);
+	if (wdev->no_ping)
+		watchdog_stop_ping_on_suspend(wdog);
 
 	if (imx2_wdt_is_running(wdev)) {
 		imx2_wdt_set_timeout(wdog, wdog->timeout);
@@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
 		imx2_wdt_ping(wdog);
 	}
 
-	clk_disable_unprepare(wdev->clk);
+	if (wdev->no_ping) {
+		clk_disable_unprepare(wdev->clk);
 
-	wdev->clk_is_on = false;
+		wdev->clk_is_on = false;
+	}
 
 	return 0;
 }
@@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
 	int ret;
 
-	ret = clk_prepare_enable(wdev->clk);
-	if (ret)
-		return ret;
+	if (wdev->no_ping) {
+		ret = clk_prepare_enable(wdev->clk);
 
-	wdev->clk_is_on = true;
+		if (ret)
+			return ret;
+
+		wdev->clk_is_on = true;
+	}
 
 	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
 		/*
@@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
 
 static const struct of_device_id imx2_wdt_dt_ids[] = {
 	{ .compatible = "fsl,imx21-wdt", },
+	{ .compatible = "fsl,imx7d-wdt", },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
-- 
2.31.1



From lkp at intel.com  Mon Jan 24 04:05:44 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 24 Jan 2022 20:05:44 +0800
Subject: [PATCH] clk: mediatek: pll: fix semicolon.cocci warnings
In-Reply-To: <20220122091731.283592-26-wenst@chromium.org>
References: <20220122091731.283592-26-wenst@chromium.org>
Message-ID: <20220124120543.GA22562@efa69eafe693>

From: kernel test robot <lkp at intel.com>

drivers/clk/mediatek/clk-pll.c:407:2-3: Unneeded semicolon


 Remove unneeded semicolon.

Generated by: scripts/coccinelle/misc/semicolon.cocci

CC: Chen-Yu Tsai <wenst at chromium.org>
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: kernel test robot <lkp at intel.com>
---

url:    https://github.com/0day-ci/linux/commits/Chen-Yu-Tsai/clk-mediatek-Cleanups-and-Improvements-Part-1/20220122-172158
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
:::::: branch date: 2 days ago
:::::: commit date: 2 days ago

 clk-pll.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/clk/mediatek/clk-pll.c
+++ b/drivers/clk/mediatek/clk-pll.c
@@ -404,7 +404,7 @@ err:
 
 		mtk_clk_unregister_pll(clk_data->clks[pll->id]);
 		clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
-	};
+	}
 
 	iounmap(base);
 


From angelogioacchino.delregno at collabora.com  Mon Jan 24 04:09:13 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 13:09:13 +0100
Subject: [PATCH 1/3] remoteproc: mtk_scp: Use devm variant of rproc_alloc()
Message-ID: <20220124120915.41292-1-angelogioacchino.delregno@collabora.com>

To simplify the probe function, switch from using rproc_alloc() to
devm_rproc_alloc(); while at it, also put everything on a single line,
as it acceptably fits in 82 columns.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/remoteproc/mtk_scp.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 36e48cf58ed6..95a40e3f11e3 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -756,11 +756,7 @@ static int scp_probe(struct platform_device *pdev)
 	char *fw_name = "scp.img";
 	int ret, i;
 
-	rproc = rproc_alloc(dev,
-			    np->name,
-			    &scp_ops,
-			    fw_name,
-			    sizeof(*scp));
+	rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp));
 	if (!rproc) {
 		dev_err(dev, "unable to allocate remoteproc\n");
 		return -ENOMEM;
@@ -776,8 +772,7 @@ static int scp_probe(struct platform_device *pdev)
 	scp->sram_base = devm_ioremap_resource(dev, res);
 	if (IS_ERR((__force void *)scp->sram_base)) {
 		dev_err(dev, "Failed to parse and map sram memory\n");
-		ret = PTR_ERR((__force void *)scp->sram_base);
-		goto free_rproc;
+		return PTR_ERR((__force void *)scp->sram_base);
 	}
 	scp->sram_size = resource_size(res);
 	scp->sram_phys = res->start;
@@ -789,7 +784,7 @@ static int scp_probe(struct platform_device *pdev)
 		ret = PTR_ERR((__force void *)scp->l1tcm_base);
 		if (ret != -EINVAL) {
 			dev_err(dev, "Failed to map l1tcm memory\n");
-			goto free_rproc;
+			return ret;
 		}
 	} else {
 		scp->l1tcm_size = resource_size(res);
@@ -851,8 +846,6 @@ static int scp_probe(struct platform_device *pdev)
 	for (i = 0; i < SCP_IPI_MAX; i++)
 		mutex_destroy(&scp->ipi_desc[i].lock);
 	mutex_destroy(&scp->send_lock);
-free_rproc:
-	rproc_free(rproc);
 
 	return ret;
 }
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan 24 04:09:14 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 13:09:14 +0100
Subject: [PATCH 2/3] remoteproc: mtk_scp: Reorder scp_probe() sequence
In-Reply-To: <20220124120915.41292-1-angelogioacchino.delregno@collabora.com>
References: <20220124120915.41292-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220124120915.41292-2-angelogioacchino.delregno@collabora.com>

Cleanup the scp_probe() function by reordering some calls in this
function, useful to reduce the usage of goto(s), and preparing
for one more usage of dev_err_probe().

In particular, we can get the clocks before mapping the memory region,
and move the mutexes initialization right before registering the ipi
handler (which is the first mutex user in this driver).

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/remoteproc/mtk_scp.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index 95a40e3f11e3..e40706b0e015 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -791,24 +791,23 @@ static int scp_probe(struct platform_device *pdev)
 		scp->l1tcm_phys = res->start;
 	}
 
-	mutex_init(&scp->send_lock);
-	for (i = 0; i < SCP_IPI_MAX; i++)
-		mutex_init(&scp->ipi_desc[i].lock);
-
 	scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
 	if (IS_ERR((__force void *)scp->reg_base)) {
 		dev_err(dev, "Failed to parse and map cfg memory\n");
-		ret = PTR_ERR((__force void *)scp->reg_base);
-		goto destroy_mutex;
+		return PTR_ERR((__force void *)scp->reg_base);
 	}
 
-	ret = scp_map_memory_region(scp);
+	ret = scp->data->scp_clk_get(scp);
 	if (ret)
-		goto destroy_mutex;
+		return ret;
 
-	ret = scp->data->scp_clk_get(scp);
+	ret = scp_map_memory_region(scp);
 	if (ret)
-		goto release_dev_mem;
+		return ret;
+
+	mutex_init(&scp->send_lock);
+	for (i = 0; i < SCP_IPI_MAX; i++)
+		mutex_init(&scp->ipi_desc[i].lock);
 
 	/* register SCP initialization IPI */
 	ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
@@ -842,7 +841,6 @@ static int scp_probe(struct platform_device *pdev)
 	scp_ipi_unregister(scp, SCP_IPI_INIT);
 release_dev_mem:
 	scp_unmap_memory_region(scp);
-destroy_mutex:
 	for (i = 0; i < SCP_IPI_MAX; i++)
 		mutex_destroy(&scp->ipi_desc[i].lock);
 	mutex_destroy(&scp->send_lock);
-- 
2.33.1



From angelogioacchino.delregno at collabora.com  Mon Jan 24 04:09:15 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 24 Jan 2022 13:09:15 +0100
Subject: [PATCH 3/3] remoteproc: mtk_scp: Use dev_err_probe() where possible
In-Reply-To: <20220124120915.41292-1-angelogioacchino.delregno@collabora.com>
References: <20220124120915.41292-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220124120915.41292-3-angelogioacchino.delregno@collabora.com>

Simplify the probe function, where possible, by using dev_err_probe().
While at it, as to increase human readability, also remove some
unnecessary forced void pointer casts that were previously used in
error checking.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/remoteproc/mtk_scp.c | 28 ++++++++++++----------------
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
index e40706b0e015..dcddb33e9997 100644
--- a/drivers/remoteproc/mtk_scp.c
+++ b/drivers/remoteproc/mtk_scp.c
@@ -757,10 +757,8 @@ static int scp_probe(struct platform_device *pdev)
 	int ret, i;
 
 	rproc = devm_rproc_alloc(dev, np->name, &scp_ops, fw_name, sizeof(*scp));
-	if (!rproc) {
-		dev_err(dev, "unable to allocate remoteproc\n");
-		return -ENOMEM;
-	}
+	if (!rproc)
+		return dev_err_probe(dev, -ENOMEM, "unable to allocate remoteproc\n");
 
 	scp = (struct mtk_scp *)rproc->priv;
 	scp->rproc = rproc;
@@ -770,21 +768,20 @@ static int scp_probe(struct platform_device *pdev)
 
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
 	scp->sram_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR((__force void *)scp->sram_base)) {
-		dev_err(dev, "Failed to parse and map sram memory\n");
-		return PTR_ERR((__force void *)scp->sram_base);
-	}
+	if (IS_ERR(scp->sram_base))
+		return dev_err_probe(dev, PTR_ERR(scp->sram_base),
+				     "Failed to parse and map sram memory\n");
+
 	scp->sram_size = resource_size(res);
 	scp->sram_phys = res->start;
 
 	/* l1tcm is an optional memory region */
 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "l1tcm");
 	scp->l1tcm_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR((__force void *)scp->l1tcm_base)) {
-		ret = PTR_ERR((__force void *)scp->l1tcm_base);
+	if (IS_ERR(scp->l1tcm_base)) {
+		ret = PTR_ERR(scp->l1tcm_base);
 		if (ret != -EINVAL) {
-			dev_err(dev, "Failed to map l1tcm memory\n");
-			return ret;
+			return dev_err_probe(dev, ret, "Failed to map l1tcm memory\n");
 		}
 	} else {
 		scp->l1tcm_size = resource_size(res);
@@ -792,10 +789,9 @@ static int scp_probe(struct platform_device *pdev)
 	}
 
 	scp->reg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
-	if (IS_ERR((__force void *)scp->reg_base)) {
-		dev_err(dev, "Failed to parse and map cfg memory\n");
-		return PTR_ERR((__force void *)scp->reg_base);
-	}
+	if (IS_ERR(scp->reg_base))
+		return dev_err_probe(dev, PTR_ERR(scp->reg_base),
+				     "Failed to parse and map cfg memory\n");
 
 	ret = scp->data->scp_clk_get(scp);
 	if (ret)
-- 
2.33.1



From vincenzo.frascino at arm.com  Mon Jan 24 04:10:02 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Mon, 24 Jan 2022 12:10:02 +0000
Subject: [PATCH] arm64: vdso: fix "no previous prototype" warning
In-Reply-To: <20220122120558.7eoiytboe7b43b5q@pengutronix.de>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
 <0030cecf-e79b-f666-8516-d0589bc49b81@arm.com>
 <20220122120558.7eoiytboe7b43b5q@pengutronix.de>
Message-ID: <ae7224ad-1b2c-d8ce-fc18-d60d879db836@arm.com>

Hi Marc,

On 1/22/22 12:05 PM, Marc Kleine-Budde wrote:
> On 21.01.2022 12:12:26, Vincenzo Frascino wrote:
>> Hi Marc,
>>
>> On 1/9/22 11:35 AM, Marc Kleine-Budde wrote:
>>> If compiling the arm64 kernel with W=1 the following warning is produced:
>>>
>>> | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
>>> |     9 | int __kernel_clock_gettime(clockid_t clock,
>>> |       |     ^~~~~~~~~~~~~~~~~~~~~~
>>> | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
>>> |    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
>>> |       |     ^~~~~~~~~~~~~~~~~~~~~
>>> | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
>>> |    21 | int __kernel_clock_getres(clockid_t clock_id,
>>> |       |     ^~~~~~~~~~~~~~~~~~~~~
>>>
>>> This patch adds the missing prototype to fix the warning and make
>>> compilation with "CONFIG_WERROR=y" possible.
>>>
>>
>> Instead of adding the prototypes, how about we silence the warning for the
>> specific file? Since adding them does not seem to add any value in this context.
>>
>> If you agree, could please test the patch I sent in reply to this one and let me
>> know if it works for your usecase? Thanks.
> 
> The patch silences the W=1 warning, sparse (C=1) however still
> complains:
> 
> | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: warning: symbol '__kernel_clock_gettime' was not declared. Should it be static?
> | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: warning: symbol '__kernel_gettimeofday' was not declared. Should it be static?
> | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: warning: symbol '__kernel_clock_getres' was not declared. Should it be static?
> 

I had a look this morning but it seems but it seems that CHECKFLAGS does not
allow to ignore warnings. I need to investigate it further, but in the meantime
I propose to go ahead with the other patch since it addresses a compilation issue.


> regards,
> Marc
> 

-- 
Regards,
Vincenzo


From alistair at alistair23.me  Mon Jan 24 04:10:01 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:01 +1000
Subject: [PATCH v18 0/8] Add support for the silergy,sy7636a
Message-ID: <20220124121009.108649-1-alistair@alistair23.me>

v18:
 - Rebase
v17:
 - Rebase and fix build issues
v16:
 - Improve vdd regulator comments
v15:
 - Address comments on the patches
v14:
 - Merge the thermal driver and hwmon
v13:
 - Address comments on thermal driver
 - Rebase on master (without other patches)
v12:
 - Rebase
v11:
 - Address comments on hwmon
 - Improve "mfd: simple-mfd-i2c: Add a Kconfig name" commit message
v10:
 - Use dev_get_regmap() instead of dev_get_drvdata()
v9:
 - Convert to use the simple-mfd-i2c instead

Alistair Francis (8):
  dt-bindings: mfd: Initial commit of silergy,sy7636a.yaml
  mfd: simple-mfd-i2c: Add a Kconfig name
  mfd: simple-mfd-i2c: Enable support for the silergy,sy7636a
  regulator: sy7636a: Remove requirement on sy7636a mfd
  hwmon: sy7636a: Add temperature driver for sy7636a
  ARM: imx_v6_v7_defconfig: Enable silergy,sy7636a
  ARM: dts: imx7d-remarkable2: Enable silergy,sy7636a
  ARM: dts: imx7d-remarkable2: Enable lcdif

 .../bindings/mfd/silergy,sy7636a.yaml         |  82 +++++++++++
 Documentation/hwmon/index.rst                 |   1 +
 Documentation/hwmon/sy7636a-hwmon.rst         |  26 ++++
 arch/arm/boot/dts/imx7d-remarkable2.dts       | 136 ++++++++++++++++++
 arch/arm/configs/imx_v6_v7_defconfig          |   3 +
 drivers/hwmon/Kconfig                         |   9 ++
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/sy7636a-hwmon.c                 | 106 ++++++++++++++
 drivers/mfd/Kconfig                           |   2 +-
 drivers/mfd/simple-mfd-i2c.c                  |  11 ++
 drivers/regulator/Kconfig                     |   1 -
 drivers/regulator/sy7636a-regulator.c         |   7 +-
 include/linux/mfd/sy7636a.h                   |  34 +++++
 13 files changed, 415 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
 create mode 100644 Documentation/hwmon/sy7636a-hwmon.rst
 create mode 100644 drivers/hwmon/sy7636a-hwmon.c
 create mode 100644 include/linux/mfd/sy7636a.h

-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:02 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:02 +1000
Subject: [PATCH v18 1/8] dt-bindings: mfd: Initial commit of silergy,
 sy7636a.yaml
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-2-alistair@alistair23.me>

Initial support for the Silergy SY7636A Power Management chip
and regulator.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
Reviewed-by: Rob Herring <robh at kernel.org>
Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>
---
 .../bindings/mfd/silergy,sy7636a.yaml         | 82 +++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml

diff --git a/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
new file mode 100644
index 000000000000..6de74c701635
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/silergy,sy7636a.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/silergy,sy7636a.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: silergy sy7636a PMIC
+
+maintainers:
+  - Alistair Francis <alistair at alistair23.me>
+
+properties:
+  compatible:
+    const: silergy,sy7636a
+
+  reg:
+    description:
+      I2C device address.
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  '#thermal-sensor-cells':
+    const: 0
+
+  epd-pwr-good-gpios:
+    description:
+      Specifying the power good GPIOs.
+    maxItems: 1
+
+  regulators:
+    type: object
+
+    properties:
+      compatible:
+        const: silergy,sy7636a-regulator
+
+      vcom:
+        type: object
+        $ref: /schemas/regulator/regulator.yaml#
+        description:
+          The regulator for the compenstation voltage. Enabling/disabling this
+          enables/disables the entire device.
+        properties:
+          regulator-name:
+            const: vcom
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - '#thermal-sensor-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      pmic at 62 {
+        compatible = "silergy,sy7636a";
+        reg = <0x62>;
+        pinctrl-names = "default";
+        pinctrl-0 = <&pinctrl_epdpmic>;
+        #thermal-sensor-cells = <0>;
+
+        regulators {
+          reg_epdpmic: vcom {
+            regulator-name = "vcom";
+            regulator-boot-on;
+          };
+        };
+      };
+    };
+...
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:03 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:03 +1000
Subject: [PATCH v18 2/8] mfd: simple-mfd-i2c: Add a Kconfig name
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-3-alistair@alistair23.me>

Add a Kconfig name to the "Simple Multi-Functional Device support (I2C)"
device so that it can be enabled via menuconfig.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/mfd/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ba0b3eb131f1..e0d2fcb10a0c 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1188,7 +1188,7 @@ config MFD_SI476X_CORE
 	  module will be called si476x-core.
 
 config MFD_SIMPLE_MFD_I2C
-	tristate
+	tristate "Simple Multi-Functional Device support (I2C)"
 	depends on I2C
 	select MFD_CORE
 	select REGMAP_I2C
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:04 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:04 +1000
Subject: [PATCH v18 3/8] mfd: simple-mfd-i2c: Enable support for the silergy,
 sy7636a
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-4-alistair@alistair23.me>

Signed-off-by: Alistair Francis <alistair at alistair23.me>
Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>
---
 drivers/mfd/simple-mfd-i2c.c | 11 +++++++++++
 include/linux/mfd/sy7636a.h  | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 include/linux/mfd/sy7636a.h

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 51536691ad9d..f4c8fc3ee463 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -62,8 +62,19 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 	return ret;
 }
 
+static const struct mfd_cell sy7636a_cells[] = {
+	{ .name = "sy7636a-regulator", },
+	{ .name = "sy7636a-temperature", },
+};
+
+static const struct simple_mfd_data silergy_sy7636a = {
+	.mfd_cell = sy7636a_cells,
+	.mfd_cell_size = ARRAY_SIZE(sy7636a_cells),
+};
+
 static const struct of_device_id simple_mfd_i2c_of_match[] = {
 	{ .compatible = "kontron,sl28cpld" },
+	{ .compatible = "silergy,sy7636a", .data = &silergy_sy7636a},
 	{}
 };
 MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match);
diff --git a/include/linux/mfd/sy7636a.h b/include/linux/mfd/sy7636a.h
new file mode 100644
index 000000000000..22f03b2f851e
--- /dev/null
+++ b/include/linux/mfd/sy7636a.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Functions to access SY3686A power management chip.
+ *
+ * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
+ */
+
+#ifndef __MFD_SY7636A_H
+#define __MFD_SY7636A_H
+
+#define SY7636A_REG_OPERATION_MODE_CRL		0x00
+/* It is set if a gpio is used to control the regulator */
+#define SY7636A_OPERATION_MODE_CRL_VCOMCTL	BIT(6)
+#define SY7636A_OPERATION_MODE_CRL_ONOFF	BIT(7)
+#define SY7636A_REG_VCOM_ADJUST_CTRL_L		0x01
+#define SY7636A_REG_VCOM_ADJUST_CTRL_H		0x02
+#define SY7636A_REG_VCOM_ADJUST_CTRL_MASK	0x01ff
+#define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL	0x03
+#define SY7636A_REG_POWER_ON_DELAY_TIME		0x06
+#define SY7636A_REG_FAULT_FLAG			0x07
+#define SY7636A_FAULT_FLAG_PG			BIT(0)
+#define SY7636A_REG_TERMISTOR_READOUT		0x08
+
+#define SY7636A_REG_MAX				0x08
+
+#define VCOM_ADJUST_CTRL_MASK	0x1ff
+// Used to shift the high byte
+#define VCOM_ADJUST_CTRL_SHIFT	8
+// Used to scale from VCOM_ADJUST_CTRL to mv
+#define VCOM_ADJUST_CTRL_SCAL	10000
+
+#define FAULT_FLAG_SHIFT	1
+
+#endif /* __LINUX_MFD_SY7636A_H */
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:05 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:05 +1000
Subject: [PATCH v18 4/8] regulator: sy7636a: Remove requirement on sy7636a mfd
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-5-alistair@alistair23.me>

Signed-off-by: Alistair Francis <alistair at alistair23.me>
Acked-by: Mark Brown <broonie at kernel.org>
---
 drivers/regulator/Kconfig             | 1 -
 drivers/regulator/sy7636a-regulator.c | 7 +++++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 1c35fed20d34..25ae5f087ff9 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -1208,7 +1208,6 @@ config REGULATOR_STW481X_VMMC
 
 config REGULATOR_SY7636A
 	tristate "Silergy SY7636A voltage regulator"
-	depends on MFD_SY7636A
 	help
 	  This driver supports Silergy SY3686A voltage regulator.
 
diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c
index 22fddf868e4c..29fc27c2cda0 100644
--- a/drivers/regulator/sy7636a-regulator.c
+++ b/drivers/regulator/sy7636a-regulator.c
@@ -7,11 +7,14 @@
 // Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig at remarkable.com>
 //          Alistair Francis <alistair at alistair23.me>
 
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/mfd/sy7636a.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
 #include <linux/regmap.h>
-#include <linux/gpio/consumer.h>
-#include <linux/mfd/sy7636a.h>
 
 struct sy7636a_data {
 	struct regmap *regmap;
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:06 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:06 +1000
Subject: [PATCH v18 5/8] hwmon: sy7636a: Add temperature driver for sy7636a
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-6-alistair@alistair23.me>

This is a multi-function device to interface with the sy7636a
EPD PMIC chip from Silergy.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 Documentation/hwmon/index.rst         |   1 +
 Documentation/hwmon/sy7636a-hwmon.rst |  26 +++++++
 drivers/hwmon/Kconfig                 |   9 +++
 drivers/hwmon/Makefile                |   1 +
 drivers/hwmon/sy7636a-hwmon.c         | 106 ++++++++++++++++++++++++++
 5 files changed, 143 insertions(+)
 create mode 100644 Documentation/hwmon/sy7636a-hwmon.rst
 create mode 100644 drivers/hwmon/sy7636a-hwmon.c

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index df20022c741f..6e0906ef5d25 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -185,6 +185,7 @@ Hardware Monitoring Kernel Drivers
    smsc47m1
    sparx5-temp
    stpddc60
+   sy7636a-hwmon
    tc654
    tc74
    thmc50
diff --git a/Documentation/hwmon/sy7636a-hwmon.rst b/Documentation/hwmon/sy7636a-hwmon.rst
new file mode 100644
index 000000000000..5612079397d5
--- /dev/null
+++ b/Documentation/hwmon/sy7636a-hwmon.rst
@@ -0,0 +1,26 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Kernel driver sy7636a-hwmon
+=========================
+
+Supported chips:
+
+ * Silergy SY7636A PMIC
+
+
+Description
+-----------
+
+This driver adds hardware temperature reading support for
+the Silergy SY7636A PMIC.
+
+The following sensors are supported
+
+  * Temperature
+      - SoC on-die temperature in milli-degree C
+
+sysfs-Interface
+---------------
+
+temp0_input
+	- SoC on-die temperature (milli-degree C)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 8df25f1079ba..aa5785e657a4 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1672,6 +1672,15 @@ config SENSORS_SIS5595
 	  This driver can also be built as a module. If so, the module
 	  will be called sis5595.
 
+config SENSORS_SY7636A
+	tristate "Silergy SY7636A"
+	help
+	  If you say yes here you get support for the thermistor readout of
+	  the Silergy SY7636A PMIC.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called sy7636a-hwmon.
+
 config SENSORS_DME1737
 	tristate "SMSC DME1737, SCH311x and compatibles"
 	depends on I2C && !PPC
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 185f946d698b..fe54a3dfdb03 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -186,6 +186,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1)	+= smsc47m1.o
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_SPARX5)	+= sparx5-temp.o
 obj-$(CONFIG_SENSORS_STTS751)	+= stts751.o
+obj-$(CONFIG_SENSORS_SY7636A)	+= sy7636a-hwmon.o
 obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
 obj-$(CONFIG_SENSORS_TC74)	+= tc74.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c
new file mode 100644
index 000000000000..6dd9c2a0f0e0
--- /dev/null
+++ b/drivers/hwmon/sy7636a-hwmon.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Functions to access SY3686A power management chip temperature
+ *
+ * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/
+ *
+ * Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig at remarkable.com>
+ *          Alistair Francis <alistair at alistair23.me>
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/machine.h>
+
+#include <linux/mfd/sy7636a.h>
+
+static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type,
+			u32 attr, int channel, long *temp)
+{
+	struct regmap *regmap = dev_get_drvdata(dev);
+	int ret, reg_val;
+
+	ret = regmap_read(regmap,
+			  SY7636A_REG_TERMISTOR_READOUT, &reg_val);
+	if (ret)
+		return ret;
+
+	*temp = reg_val * 1000;
+
+	return 0;
+}
+
+static umode_t sy7636a_is_visible(const void *data,
+				  enum hwmon_sensor_types type,
+				  u32 attr, int channel)
+{
+	if (type != hwmon_temp)
+		return 0;
+
+	if (attr != hwmon_temp_input)
+		return 0;
+
+	return 0444;
+}
+
+static const struct hwmon_ops sy7636a_hwmon_ops = {
+	.is_visible = sy7636a_is_visible,
+	.read = sy7636a_read,
+};
+
+static const struct hwmon_channel_info *sy7636a_info[] = {
+	HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ),
+	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT),
+	NULL
+};
+
+static const struct hwmon_chip_info sy7636a_chip_info = {
+	.ops = &sy7636a_hwmon_ops,
+	.info = sy7636a_info,
+};
+
+static int sy7636a_sensor_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	struct regulator *regulator;
+	struct device *hwmon_dev;
+	int err;
+
+	if (!regmap)
+		return -EPROBE_DEFER;
+
+	regulator = devm_regulator_get(&pdev->dev, "vcom");
+	if (IS_ERR(regulator))
+		return PTR_ERR(regulator);
+
+	err = regulator_enable(regulator);
+	if (err)
+		return err;
+
+	hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+							 "sy7636a_temperature", regmap,
+							 &sy7636a_chip_info, NULL);
+
+	if (IS_ERR(hwmon_dev)) {
+		err = PTR_ERR(hwmon_dev);
+		dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static struct platform_driver sy7636a_sensor_driver = {
+	.probe = sy7636a_sensor_probe,
+	.driver = {
+		.name = "sy7636a-temperature",
+	},
+};
+module_platform_driver(sy7636a_sensor_driver);
+
+MODULE_DESCRIPTION("SY7636A sensor driver");
+MODULE_LICENSE("GPL");
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:07 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:07 +1000
Subject: [PATCH v18 6/8] ARM: imx_v6_v7_defconfig: Enable silergy,sy7636a
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-7-alistair@alistair23.me>

Enable the silergy,sy7636a and silergy,sy7636a-regulator for the
reMarkable2.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/configs/imx_v6_v7_defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index f7498df08dfe..37ec95fce3be 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -223,6 +223,7 @@ CONFIG_RN5T618_POWER=m
 CONFIG_SENSORS_MC13783_ADC=y
 CONFIG_SENSORS_GPIO_FAN=y
 CONFIG_SENSORS_IIO_HWMON=y
+CONFIG_SENSORS_SY7636A=y
 CONFIG_THERMAL_STATISTICS=y
 CONFIG_THERMAL_WRITABLE_TRIPS=y
 CONFIG_CPU_THERMAL=y
@@ -239,6 +240,7 @@ CONFIG_MFD_DA9063=y
 CONFIG_MFD_MC13XXX_SPI=y
 CONFIG_MFD_MC13XXX_I2C=y
 CONFIG_MFD_RN5T618=y
+CONFIG_MFD_SIMPLE_MFD_I2C=y
 CONFIG_MFD_STMPE=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ANATOP=y
@@ -251,6 +253,7 @@ CONFIG_REGULATOR_MC13783=y
 CONFIG_REGULATOR_MC13892=y
 CONFIG_REGULATOR_PFUZE100=y
 CONFIG_REGULATOR_RN5T618=y
+CONFIG_REGULATOR_SY7636A=y
 CONFIG_RC_CORE=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_GPIO_CIR=y
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:08 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:08 +1000
Subject: [PATCH v18 7/8] ARM: dts: imx7d-remarkable2: Enable silergy,sy7636a
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-8-alistair@alistair23.me>

Enable the silergy,sy7636a and silergy,sy7636a-regulator on the
reMarkable2.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/boot/dts/imx7d-remarkable2.dts | 62 +++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-remarkable2.dts b/arch/arm/boot/dts/imx7d-remarkable2.dts
index a2a91bfdd98e..99ac0d242936 100644
--- a/arch/arm/boot/dts/imx7d-remarkable2.dts
+++ b/arch/arm/boot/dts/imx7d-remarkable2.dts
@@ -22,6 +22,27 @@ memory at 80000000 {
 		reg = <0x80000000 0x40000000>;
 	};
 
+	thermal-zones {
+		epd-thermal {
+			thermal-sensors = <&epd_pmic>;
+			polling-delay-passive = <30000>;
+			polling-delay = <30000>;
+			trips {
+				trip0 {
+					temperature = <49000>;
+					hysteresis = <2000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <50000>;
+					hysteresis = <2000>;
+					type = "critical";
+				};
+			};
+		};
+	};
+
 	reg_brcm: regulator-brcm {
 		compatible = "regulator-fixed";
 		regulator-name = "brcm_reg";
@@ -84,6 +105,33 @@ wacom_digitizer: digitizer at 9 {
 	};
 };
 
+&i2c4 {
+	clock-frequency = <100000>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	pinctrl-1 = <&pinctrl_i2c4>;
+	status = "okay";
+
+	epd_pmic: sy7636a at 62 {
+		compatible = "silergy,sy7636a";
+		reg = <0x62>;
+		status = "okay";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_epdpmic>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		#thermal-sensor-cells = <0>;
+
+		epd-pwr-good-gpios = <&gpio6 21 GPIO_ACTIVE_HIGH>;
+		regulators {
+			reg_epdpmic: vcom {
+				regulator-name = "vcom";
+				regulator-boot-on;
+			};
+		};
+	};
+};
+
 &snvs_pwrkey {
 	status = "okay";
 };
@@ -177,6 +225,13 @@ MX7D_PAD_SAI1_TX_BCLK__GPIO6_IO13	0x14
 		>;
 	};
 
+	pinctrl_epdpmic: epdpmicgrp {
+		fsl,pins = <
+			MX7D_PAD_SAI2_RX_DATA__GPIO6_IO21 0x00000074
+			MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x00000014
+		>;
+	};
+
 	pinctrl_i2c1: i2c1grp {
 		fsl,pins = <
 			MX7D_PAD_I2C1_SDA__I2C1_SDA		0x4000007f
@@ -184,6 +239,13 @@ MX7D_PAD_I2C1_SCL__I2C1_SCL		0x4000007f
 		>;
 	};
 
+	pinctrl_i2c4: i2c4grp {
+		fsl,pins = <
+			MX7D_PAD_I2C4_SDA__I2C4_SDA		0x4000007f
+			MX7D_PAD_I2C4_SCL__I2C4_SCL		0x4000007f
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-- 
2.31.1



From alistair at alistair23.me  Mon Jan 24 04:10:09 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Mon, 24 Jan 2022 22:10:09 +1000
Subject: [PATCH v18 8/8] ARM: dts: imx7d-remarkable2: Enable lcdif
In-Reply-To: <20220124121009.108649-1-alistair@alistair23.me>
References: <20220124121009.108649-1-alistair@alistair23.me>
Message-ID: <20220124121009.108649-9-alistair@alistair23.me>

Connect the dispaly on the reMarkable2.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
 arch/arm/boot/dts/imx7d-remarkable2.dts | 74 +++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/arch/arm/boot/dts/imx7d-remarkable2.dts b/arch/arm/boot/dts/imx7d-remarkable2.dts
index 99ac0d242936..03a4029e1e57 100644
--- a/arch/arm/boot/dts/imx7d-remarkable2.dts
+++ b/arch/arm/boot/dts/imx7d-remarkable2.dts
@@ -68,6 +68,16 @@ reg_digitizer: regulator-digitizer {
 		startup-delay-us = <100000>; /* 100 ms */
 	};
 
+	reg_sdoe: regulator-sdoe {
+		compatible = "regulator-fixed";
+		regulator-name = "SDOE";
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&pinctrl_sdoe_reg>;
+		pinctrl-1 = <&pinctrl_sdoe_reg>;
+		gpio = <&gpio3 27 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
 	wifi_pwrseq: wifi_pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		pinctrl-names = "default";
@@ -76,6 +86,16 @@ wifi_pwrseq: wifi_pwrseq {
 		clocks = <&clks IMX7D_CLKO2_ROOT_DIV>;
 		clock-names = "ext_clock";
 	};
+
+	panel {
+		compatible = "eink,vb3300-kca";
+
+		port {
+			panel_in: endpoint {
+				remote-endpoint = <&display_out>;
+			};
+		};
+	};
 };
 
 &clks {
@@ -132,6 +152,20 @@ reg_epdpmic: vcom {
 	};
 };
 
+&lcdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_lcdif>;
+	lcd-supply = <&reg_epdpmic>;
+	lcd2-supply = <&reg_sdoe>;
+	status = "okay";
+
+	port {
+		display_out: endpoint {
+			remote-endpoint = <&panel_in>;
+		};
+	};
+};
+
 &snvs_pwrkey {
 	status = "okay";
 };
@@ -246,6 +280,46 @@ MX7D_PAD_I2C4_SCL__I2C4_SCL		0x4000007f
 		>;
 	};
 
+	pinctrl_lcdif: lcdifgrp {
+		fsl,pins = <
+			MX7D_PAD_LCD_DATA00__LCD_DATA0		0x79
+			MX7D_PAD_LCD_DATA01__LCD_DATA1		0x79
+			MX7D_PAD_LCD_DATA02__LCD_DATA2		0x79
+			MX7D_PAD_LCD_DATA03__LCD_DATA3		0x79
+			MX7D_PAD_LCD_DATA04__LCD_DATA4		0x79
+			MX7D_PAD_LCD_DATA05__LCD_DATA5		0x79
+			MX7D_PAD_LCD_DATA06__LCD_DATA6		0x79
+			MX7D_PAD_LCD_DATA07__LCD_DATA7		0x79
+			MX7D_PAD_LCD_DATA08__LCD_DATA8		0x79
+			MX7D_PAD_LCD_DATA09__LCD_DATA9		0x79
+			MX7D_PAD_LCD_DATA10__LCD_DATA10		0x79
+			MX7D_PAD_LCD_DATA11__LCD_DATA11		0x79
+			MX7D_PAD_LCD_DATA12__LCD_DATA12		0x79
+			MX7D_PAD_LCD_DATA13__LCD_DATA13		0x79
+			MX7D_PAD_LCD_DATA14__LCD_DATA14		0x79
+			MX7D_PAD_LCD_DATA15__LCD_DATA15		0x79
+
+			MX7D_PAD_LCD_DATA17__LCD_DATA17		0x79
+			MX7D_PAD_LCD_DATA18__LCD_DATA18		0x79
+			MX7D_PAD_LCD_DATA19__LCD_DATA19		0x79
+			MX7D_PAD_LCD_DATA20__LCD_DATA20		0x79
+			MX7D_PAD_LCD_DATA21__LCD_DATA21		0x79
+
+			MX7D_PAD_LCD_DATA23__LCD_DATA23		0x79
+			MX7D_PAD_LCD_CLK__LCD_CLK		0x79
+			MX7D_PAD_LCD_ENABLE__LCD_ENABLE		0x79
+			MX7D_PAD_LCD_VSYNC__LCD_VSYNC		0x79
+			MX7D_PAD_LCD_HSYNC__LCD_HSYNC		0x79
+			MX7D_PAD_LCD_RESET__LCD_RESET		0x79
+		>;
+	};
+
+	pinctrl_sdoe_reg: sdoereggrp {
+		fsl,pins = <
+			MX7D_PAD_LCD_DATA22__GPIO3_IO27		0x74
+		>;
+	};
+
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
 			MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX	0x79
-- 
2.31.1



From mkl at pengutronix.de  Mon Jan 24 04:13:00 2022
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Mon, 24 Jan 2022 13:13:00 +0100
Subject: [PATCH] arm64: vdso: fix "no previous prototype" warning
In-Reply-To: <ae7224ad-1b2c-d8ce-fc18-d60d879db836@arm.com>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
 <0030cecf-e79b-f666-8516-d0589bc49b81@arm.com>
 <20220122120558.7eoiytboe7b43b5q@pengutronix.de>
 <ae7224ad-1b2c-d8ce-fc18-d60d879db836@arm.com>
Message-ID: <20220124121300.sj6pmei6iarj36nv@pengutronix.de>

On 24.01.2022 12:10:02, Vincenzo Frascino wrote:
> > The patch silences the W=1 warning, sparse (C=1) however still
> > complains:
> > 
> > | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: warning: symbol '__kernel_clock_gettime' was not declared. Should it be static?
> > | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: warning: symbol '__kernel_gettimeofday' was not declared. Should it be static?
> > | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: warning: symbol '__kernel_clock_getres' was not declared. Should it be static?
> > 
> 
> I had a look this morning but it seems but it seems that CHECKFLAGS does not
> allow to ignore warnings. I need to investigate it further, but in the meantime
> I propose to go ahead with the other patch since it addresses a compilation issue.

Sounds reasonable.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/e1c4a818/attachment-0001.sig>

From heikki.krogerus at linux.intel.com  Mon Jan 24 04:13:06 2022
From: heikki.krogerus at linux.intel.com (Heikki Krogerus)
Date: Mon, 24 Jan 2022 14:13:06 +0200
Subject: [BUG] rockpro64-v2: NULL pointer dereference when booting
In-Reply-To: <Ye6S1PBAHtWj1lRp@monolith.localdoman>
References: <Ye6S1PBAHtWj1lRp@monolith.localdoman>
Message-ID: <Ye6X0lgBBsk4Sd1X@kuha.fi.intel.com>

On Mon, Jan 24, 2022 at 11:51:48AM +0000, Alexandru Elisei wrote:
> Hi,
> 
> When booting a rockpro64-v2 with a kernel built from commit dd81e1c7d5fb
> ("Merge tag 'powerpc-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux"),
> which was the latest commit when ran the tests, I encounter a NULL pointer
> dereference:
> 
> [..]
> [    0.000000] Kernel command line: root=PARTUUID=7f4aab92-69d8-47f3-be10-624da40a71f9 rw earlycon rootwait
> [..]
> [    3.396944] hub 7-0:1.0: USB hub found
> [    3.397575] hub 7-0:1.0: 1 port detected
> [    3.406086] ohci-platform fe3e0000.usb: Generic Platform OHCI controller
> [    3.406932] ohci-platform fe3e0000.usb: new USB bus registered, assigned bus number 8
> [    3.408530] ohci-platform fe3e0000.usb: irq 38, io mem 0xfe3e0000
> [    3.476869] hub 8-0:1.0: USB hub found
> [    3.477501] hub 8-0:1.0: 1 port detected
> [    3.483278] rk808 0-001b: chip id: 0x0
> [    3.498495] random: fast init done
> [    3.509322] rk808-regulator rk808-regulator: there is no dvs0 gpio
> [    3.510143] rk808-regulator rk808-regulator: there is no dvs1 gpio
> [    3.569278] OF: graph: no port node found in /i2c at ff3d0000/typec-portc at 22
> [    3.573471] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> [    3.574466] Mem abort info:
> [    3.574800]   ESR = 0x96000004
> [    3.575163]   EC = 0x25: DABT (current EL), IL = 32 bits
> [    3.575770]   SET = 0, FnV = 0
> [    3.576204]   EA = 0, S1PTW = 0
> [    3.576580]   FSC = 0x04: level 0 translation fault
> [    3.577140] Data abort info:
> [    3.577482]   ISV = 0, ISS = 0x00000004
> [    3.577927]   CM = 0, WnR = 0
> [    3.578279] [0000000000000000] user address but active_mm is swapper
> [    3.579065] Internal error: Oops: 96000004 [#1] PREEMPT SMP
> [    3.579586] Modules linked in:
> [    3.579880] CPU: 5 PID: 7 Comm: kworker/u12:0 Not tainted 5.16.0-rc6-00081-g730b49aac426 #244
> [    3.580667] Hardware name: Pine64 RockPro64 v2.0 (DT)
> [    3.581135] Workqueue: events_unbound deferred_probe_work_func
> [    3.581689] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    3.582335] pc : component_master_add_with_match+0x20/0xfc
> [    3.582850] lr : typec_link_ports+0x58/0x8c
> [    3.583244] sp : ffff800013093980
> [    3.583553] x29: ffff800013093980 x28: ffff80001212b000 x27: ffff00000041d00d
> [    3.584223] x26: ffff0000063e85e0 x25: ffff800012fcb290 x24: ffff000001386820
> [    3.584891] x23: ffff000006c2e808 x22: ffff800011416670 x21: ffff000006c2e808
> [    3.585558] x20: 0000000000000000 x19: ffff000006c2e800 x18: ffffffffffffffff
> [    3.586224] x17: 000000040044ffff x16: 00400034b5503510 x15: 0000000000005ff9
> [    3.586890] x14: 0000000000000000 x13: 0000000000000003 x12: ffff0000063e8080
> [    3.587557] x11: 0000000000000005 x10: ffff800012c13a60 x9 : 0000000000000000
> [    3.588224] x8 : 0000200000000000 x7 : 0000000000000038 x6 : 000000000000004b
> [    3.588892] x5 : 0000000000000000 x4 : ffff000000711800 x3 : ffff800010cd6390
> [    3.589558] x2 : 0000000000000000 x1 : ffff800011416670 x0 : ffff000006c2e808
> [    3.590224] Call trace:
> [    3.590457]  component_master_add_with_match+0x20/0xfc
> [    3.590938]  typec_link_ports+0x58/0x8c
> [    3.591299]  typec_register_port+0x1ac/0x300
> [    3.591705]  tcpm_register_port+0x62c/0x90c
> [    3.592099]  fusb302_probe+0x260/0x430
> [    3.592453]  i2c_device_probe+0x338/0x370
> [    3.592835]  really_probe.part.0+0x9c/0x30c
> [    3.593229]  __driver_probe_device+0x98/0x144
> [    3.593639]  driver_probe_device+0xc8/0x160
> [    3.594033]  __device_attach_driver+0xb8/0x120
> [    3.594450]  bus_for_each_drv+0x78/0xd0
> [    3.594810]  __device_attach+0xd8/0x180
> [    3.595171]  device_initial_probe+0x14/0x20
> [    3.595565]  bus_probe_device+0x9c/0xa4
> [    3.595926]  deferred_probe_work_func+0x88/0xc4
> [    3.596351]  process_one_work+0x288/0x6e0
> [    3.596729]  worker_thread+0x220/0x464
> [    3.597081]  kthread+0x17c/0x190
> [    3.597392]  ret_from_fork+0x10/0x20
> [    3.597737] Code: aa0203f4 a9025bf5 aa0003f5 aa0103f6 (a9400440) 
> [    3.598301] ---[ end trace 823a8d1795013b55 ]---
> 
> The full log can be found at [1]; config file can be found at [2]. All
> pastebins expire after 6 months.
> 
> I tried bisecting the bug and the first bad commit is 730b49aac426 ("usb:
> typec: port-mapper: Convert to the component framework"). I tried to double
> check that the patch is indeed responsible by reverting it from master, but
> I got this build error:
> 
> drivers/usb/typec/port-mapper.c: In function 'typec_link_ports':
> drivers/usb/typec/port-mapper.c:256:15: error: implicit declaration of function 'usb_for_each_port'; did you mean 'usb_for_each_dev'? [-Werror=implicit-function-declaration]
>   256 |         ret = usb_for_each_port(&con->dev, each_port);
>       |               ^~~~~~~~~~~~~~~~~
>       |               usb_for_each_dev
> 
> I tried building and booting from the bad commit, and I got the same NULL
> pointer dereference error. When building from the last good commit
> (8c67d06f3fd9 ("usb: Link the ports to the connectors they are attached
> to")), the board boots just fine. The log when booting from the good commit
> can be found at [3].
> 
> I can help with debugging and testing, but I'm not familiar enough with the
> USB subsystem to fix it myself.
> 
> [1] https://pastebin.com/w4tMNhve
> [2] https://pastebin.com/SiUuLeMs
> [3] https://pastebin.com/Pcm9xmL7

There is already a fix pending:
https://lore.kernel.org/linux-usb/20220124090228.41396-3-heikki.krogerus at linux.intel.com/

thanks,

-- 
heikki


From lkp at intel.com  Mon Jan 24 04:14:16 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 24 Jan 2022 20:14:16 +0800
Subject: [PATCH 25/31] clk: mediatek: pll: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-26-wenst@chromium.org>
References: <20220122091731.283592-26-wenst@chromium.org>
Message-ID: <202201242043.D1yrOE9S-lkp@intel.com>

Hi Chen-Yu,

I love your patch! Perhaps something to improve:

[auto build test WARNING on clk/clk-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Chen-Yu-Tsai/clk-mediatek-Cleanups-and-Improvements-Part-1/20220122-172158
base:   https://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git clk-next
config: h8300-randconfig-c003-20220124 (https://download.01.org/0day-ci/archive/20220124/202201242043.D1yrOE9S-lkp at intel.com/config)
compiler: h8300-linux-gcc (GCC) 11.2.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>


cocci warnings: (new ones prefixed by >>)
>> drivers/clk/mediatek/clk-pll.c:407:2-3: Unneeded semicolon

Please review and possibly fold the followup patch.

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From michal.simek at xilinx.com  Mon Jan 24 04:18:06 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 24 Jan 2022 13:18:06 +0100
Subject: [PATCH 2/3] arm64: zynqmp: Add missing #dma-cells property
In-Reply-To: <20220112151541.1328732-3-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
 <20220112151541.1328732-3-m.tretter@pengutronix.de>
Message-ID: <31b2312c-ce95-a1c3-6d52-710a28af2741@xilinx.com>



On 1/12/22 16:15, Michael Tretter wrote:
> Requesting the dma controllers fails if #dma-cells is not defined. Add
> the missing property.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---
>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 16 ++++++++++++++++
>   1 file changed, 16 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 493719f71fb5..6d96b6b99f84 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -261,6 +261,7 @@ fpd_dma_chan1: dma at fd500000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 124 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14e8>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -273,6 +274,7 @@ fpd_dma_chan2: dma at fd510000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 125 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14e9>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -285,6 +287,7 @@ fpd_dma_chan3: dma at fd520000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 126 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14ea>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -297,6 +300,7 @@ fpd_dma_chan4: dma at fd530000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 127 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14eb>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -309,6 +313,7 @@ fpd_dma_chan5: dma at fd540000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 128 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14ec>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -321,6 +326,7 @@ fpd_dma_chan6: dma at fd550000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 129 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14ed>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -333,6 +339,7 @@ fpd_dma_chan7: dma at fd560000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 130 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14ee>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -345,6 +352,7 @@ fpd_dma_chan8: dma at fd570000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 131 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <128>;
>   			iommus = <&smmu 0x14ef>;
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
> @@ -374,6 +382,7 @@ lpd_dma_chan1: dma at ffa80000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 77 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x868>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -386,6 +395,7 @@ lpd_dma_chan2: dma at ffa90000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 78 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x869>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -398,6 +408,7 @@ lpd_dma_chan3: dma at ffaa0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 79 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86a>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -410,6 +421,7 @@ lpd_dma_chan4: dma at ffab0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 80 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86b>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -422,6 +434,7 @@ lpd_dma_chan5: dma at ffac0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 81 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86c>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -434,6 +447,7 @@ lpd_dma_chan6: dma at ffad0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 82 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86d>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -446,6 +460,7 @@ lpd_dma_chan7: dma at ffae0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 83 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86e>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
> @@ -458,6 +473,7 @@ lpd_dma_chan8: dma at ffaf0000 {
>   			interrupt-parent = <&gic>;
>   			interrupts = <0 84 4>;
>   			clock-names = "clk_main", "clk_apb";
> +			#dma-cells = <1>;
>   			xlnx,bus-width = <64>;
>   			iommus = <&smmu 0x86f>;
>   			power-domains = <&zynqmp_firmware PD_ADMA>;

Applied.
M


From michal.simek at xilinx.com  Mon Jan 24 04:18:16 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Mon, 24 Jan 2022 13:18:16 +0100
Subject: [PATCH 3/3] arm64: zynqmp: Rename dma to dma-controller
In-Reply-To: <20220112151541.1328732-4-m.tretter@pengutronix.de>
References: <20220112151541.1328732-1-m.tretter@pengutronix.de>
 <20220112151541.1328732-4-m.tretter@pengutronix.de>
Message-ID: <1ec5717e-114e-8694-4ba9-43f0407a7288@xilinx.com>



On 1/12/22 16:15, Michael Tretter wrote:
> The ZynqMP dma engines are actually dma-controllers as specified by the
> device tree binding. Rename the device tree nodes accordingly.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---
>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi | 32 +++++++++++++-------------
>   1 file changed, 16 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 6d96b6b99f84..3e15391e5b37 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -254,7 +254,7 @@ pmu at 9000 {
>   		};
>   
>   		/* GDMA */
> -		fpd_dma_chan1: dma at fd500000 {
> +		fpd_dma_chan1: dma-controller at fd500000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd500000 0x0 0x1000>;
> @@ -267,7 +267,7 @@ fpd_dma_chan1: dma at fd500000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan2: dma at fd510000 {
> +		fpd_dma_chan2: dma-controller at fd510000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd510000 0x0 0x1000>;
> @@ -280,7 +280,7 @@ fpd_dma_chan2: dma at fd510000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan3: dma at fd520000 {
> +		fpd_dma_chan3: dma-controller at fd520000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd520000 0x0 0x1000>;
> @@ -293,7 +293,7 @@ fpd_dma_chan3: dma at fd520000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan4: dma at fd530000 {
> +		fpd_dma_chan4: dma-controller at fd530000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd530000 0x0 0x1000>;
> @@ -306,7 +306,7 @@ fpd_dma_chan4: dma at fd530000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan5: dma at fd540000 {
> +		fpd_dma_chan5: dma-controller at fd540000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd540000 0x0 0x1000>;
> @@ -319,7 +319,7 @@ fpd_dma_chan5: dma at fd540000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan6: dma at fd550000 {
> +		fpd_dma_chan6: dma-controller at fd550000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd550000 0x0 0x1000>;
> @@ -332,7 +332,7 @@ fpd_dma_chan6: dma at fd550000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan7: dma at fd560000 {
> +		fpd_dma_chan7: dma-controller at fd560000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd560000 0x0 0x1000>;
> @@ -345,7 +345,7 @@ fpd_dma_chan7: dma at fd560000 {
>   			power-domains = <&zynqmp_firmware PD_GDMA>;
>   		};
>   
> -		fpd_dma_chan8: dma at fd570000 {
> +		fpd_dma_chan8: dma-controller at fd570000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xfd570000 0x0 0x1000>;
> @@ -375,7 +375,7 @@ gic: interrupt-controller at f9010000 {
>   		 * These dma channels, Users should ensure that these dma
>   		 * Channels are allowed for non secure access.
>   		 */
> -		lpd_dma_chan1: dma at ffa80000 {
> +		lpd_dma_chan1: dma-controller at ffa80000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffa80000 0x0 0x1000>;
> @@ -388,7 +388,7 @@ lpd_dma_chan1: dma at ffa80000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan2: dma at ffa90000 {
> +		lpd_dma_chan2: dma-controller at ffa90000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffa90000 0x0 0x1000>;
> @@ -401,7 +401,7 @@ lpd_dma_chan2: dma at ffa90000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan3: dma at ffaa0000 {
> +		lpd_dma_chan3: dma-controller at ffaa0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffaa0000 0x0 0x1000>;
> @@ -414,7 +414,7 @@ lpd_dma_chan3: dma at ffaa0000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan4: dma at ffab0000 {
> +		lpd_dma_chan4: dma-controller at ffab0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffab0000 0x0 0x1000>;
> @@ -427,7 +427,7 @@ lpd_dma_chan4: dma at ffab0000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan5: dma at ffac0000 {
> +		lpd_dma_chan5: dma-controller at ffac0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffac0000 0x0 0x1000>;
> @@ -440,7 +440,7 @@ lpd_dma_chan5: dma at ffac0000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan6: dma at ffad0000 {
> +		lpd_dma_chan6: dma-controller at ffad0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffad0000 0x0 0x1000>;
> @@ -453,7 +453,7 @@ lpd_dma_chan6: dma at ffad0000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan7: dma at ffae0000 {
> +		lpd_dma_chan7: dma-controller at ffae0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffae0000 0x0 0x1000>;
> @@ -466,7 +466,7 @@ lpd_dma_chan7: dma at ffae0000 {
>   			power-domains = <&zynqmp_firmware PD_ADMA>;
>   		};
>   
> -		lpd_dma_chan8: dma at ffaf0000 {
> +		lpd_dma_chan8: dma-controller at ffaf0000 {
>   			status = "disabled";
>   			compatible = "xlnx,zynqmp-dma-1.0";
>   			reg = <0x0 0xffaf0000 0x0 0x1000>;

Applied.
M


From christian.gmeiner at gmail.com  Mon Jan 24 04:21:22 2022
From: christian.gmeiner at gmail.com (Christian Gmeiner)
Date: Mon, 24 Jan 2022 13:21:22 +0100
Subject: [PATCH] Revert "PCI: j721e: Drop redundant struct device *"
Message-ID: <20220124122132.435743-1-christian.gmeiner@gmail.com>

This reverts commit 19e863828acf6d8ac8475ba1fd93c0fe17fdc4ef.

Fixes the following oops:
 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
 Internal error: Oops: 96000004 [#1] PREEMPT SMP
 Modules linked in:
 CPU: 1 PID: 7 Comm: kworker/u4:0 Not tainted 5.17.0-rc1-00086-ge38b27816fea-dirty #71
 Hardware name: CPE0108 (DT)
 Workqueue: events_unbound deferred_probe_work_func
 pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
 pc : j721e_pcie_probe+0x184/0x600
 lr : j721e_pcie_probe+0x170/0x600
 sp : ffff80000957bae0
 x29: ffff80000957bae0 x28: ffff800009357000 x27: ffff00000000c078
 x26: ffff00003fe047a8 x25: 0000000000000000 x24: ffff0000000f5280
 x23: ffff800008c98f78 x22: ffff800008f90ff0 x21: ffff000000231410
 x20: ffff000002ef2780 x19: 0000000000000021 x18: 0000000000000001
 x17: 0000000000000000 x16: 0000000000058c00 x15: ffffffffffffffff
 x14: ffffffffffffffff x13: 0000000000000010 x12: 0101010101010101
 x11: 0000000000000040 x10: ffff8000093e06c8 x9 : ffff8000093e06c0
 x8 : ffff000000400270 x7 : 0000000000000000 x6 : ffff000000231590
 x5 : ffff80000957b9e0 x4 : 0000000000000000 x3 : ffff0000002314f4
 x2 : 0000000000000000 x1 : ffff0000000f5280 x0 : 0000000000000000
 Call trace:
  j721e_pcie_probe+0x184/0x600
  platform_probe+0x68/0xe0
  really_probe+0x144/0x320
  __driver_probe_device+0xc4/0xe0
  driver_probe_device+0x7c/0x110
  __device_attach_driver+0x90/0xe0
  bus_for_each_drv+0x78/0xd0
  __device_attach+0xf0/0x150
  device_initial_probe+0x14/0x20
  bus_probe_device+0x9c/0xb0
  deferred_probe_work_func+0x88/0xc0
  process_one_work+0x1bc/0x340
  worker_thread+0x1f8/0x420
  kthread+0x110/0x120
  ret_from_fork+0x10/0x20
 Code: f9400280 a90573fb d0005396 913fc2d6 (f9400800)

Fixes: 19e863828acf ("PCI: j721e: Drop redundant struct device *")
Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
---
 drivers/pci/controller/cadence/pci-j721e.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 489586a4cdc7..cd43d1898482 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -51,10 +51,11 @@ enum link_status {
 #define MAX_LANES			2
 
 struct j721e_pcie {
-	struct cdns_pcie	*cdns_pcie;
+	struct device		*dev;
 	struct clk		*refclk;
 	u32			mode;
 	u32			num_lanes;
+	struct cdns_pcie	*cdns_pcie;
 	void __iomem		*user_cfg_base;
 	void __iomem		*intd_cfg_base;
 	u32			linkdown_irq_regfield;
@@ -98,7 +99,7 @@ static inline void j721e_pcie_intd_writel(struct j721e_pcie *pcie, u32 offset,
 static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
 {
 	struct j721e_pcie *pcie = priv;
-	struct device *dev = pcie->cdns_pcie->dev;
+	struct device *dev = pcie->dev;
 	u32 reg;
 
 	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
@@ -164,7 +165,7 @@ static const struct cdns_pcie_ops j721e_pcie_ops = {
 static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
 			       unsigned int offset)
 {
-	struct device *dev = pcie->cdns_pcie->dev;
+	struct device *dev = pcie->dev;
 	u32 mask = J721E_MODE_RC;
 	u32 mode = pcie->mode;
 	u32 val = 0;
@@ -183,7 +184,7 @@ static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
 static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
 				     struct regmap *syscon, unsigned int offset)
 {
-	struct device *dev = pcie->cdns_pcie->dev;
+	struct device *dev = pcie->dev;
 	struct device_node *np = dev->of_node;
 	int link_speed;
 	u32 val = 0;
@@ -204,7 +205,7 @@ static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
 static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
 				     struct regmap *syscon, unsigned int offset)
 {
-	struct device *dev = pcie->cdns_pcie->dev;
+	struct device *dev = pcie->dev;
 	u32 lanes = pcie->num_lanes;
 	u32 val = 0;
 	int ret;
@@ -219,7 +220,7 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
 
 static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
 {
-	struct device *dev = pcie->cdns_pcie->dev;
+	struct device *dev = pcie->dev;
 	struct device_node *node = dev->of_node;
 	struct of_phandle_args args;
 	unsigned int offset = 0;
@@ -376,6 +377,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 	if (!pcie)
 		return -ENOMEM;
 
+	pcie->dev = dev;
 	pcie->mode = mode;
 	pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
 
-- 
2.34.1



From dave.stevenson at raspberrypi.com  Mon Jan 24 04:31:34 2022
From: dave.stevenson at raspberrypi.com (Dave Stevenson)
Date: Mon, 24 Jan 2022 12:31:34 +0000
Subject: [RFC PATCH v2 5/7] ARM: dts: bcm2711: Add unicam CSI nodes
In-Reply-To: <Yes3c1v+V1hMlWfW@pendragon.ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-6-jeanmichel.hautbois@ideasonboard.com>
 <Yes3c1v+V1hMlWfW@pendragon.ideasonboard.com>
Message-ID: <CAPY8ntDR5AsxGE5fh_KHMonoZait9evxQkpidu10F7EY9CPxZA@mail.gmail.com>

Hi Laurent and Jean-Michel

On Fri, 21 Jan 2022 at 22:45, Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> Hi Jean-Michel,
>
> Thank you for the patch.
>
> On Fri, Jan 21, 2022 at 09:18:08AM +0100, Jean-Michel Hautbois wrote:
> > Add both MIPI CSI-2 nodes in the core bcm2711 tree. Use the 3-cells
> > interrupt declaration, corresponding clocks and default as disabled.
> >
> > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> > ---
> >  arch/arm/boot/dts/bcm2711.dtsi | 31 +++++++++++++++++++++++++++++++
> >  1 file changed, 31 insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> > index dff18fc9a906..077141df7024 100644
> > --- a/arch/arm/boot/dts/bcm2711.dtsi
> > +++ b/arch/arm/boot/dts/bcm2711.dtsi
> > @@ -3,6 +3,7 @@
> >
> >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> >  #include <dt-bindings/soc/bcm2835-pm.h>
> > +#include <dt-bindings/power/raspberrypi-power.h>
> >
> >  / {
> >       compatible = "brcm,bcm2711";
> > @@ -293,6 +294,36 @@ hvs: hvs at 7e400000 {
> >                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
> >               };
> >
> > +             csi0: csi1 at 7e800000 {
>
> The node name should be csi at 7e800000, not csi1 at 7e800000. Now, this will
> probably cause issues with the firmware that looks for csi1 (and csi0 ?)
> to hand over control of the Unicam CSI-2 receiver to the kernel. I
> wonder if this is something that could be handled by a firmware update,
> to also recognize nodes named "csi" ?

It already looks for any node starting "csi". If you check the
downstream DT [1], then the nodes are "csi0: csi at 7e800000" and "csi1:
csi at 7e801000".

There is no actual action required to hand the peripheral over to the
kernel, it just prevents the firmware from using it and causing
problems (it masks out the interrupt, and that's checked as part of
the firmware initialising the peripheral).

If using imx219 or one of the other sensors supported by the firmware,
"vcgencmd get_camera" should report that the sensor isn't detected,
and "sudo vcdbg log msg" should have a line similar to
"020174.613: camsubs: Ignoring camera 0 as unicam device not available"

  Dave

[1] https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm270x.dtsi#L88

> > +                     compatible = "brcm,bcm2835-unicam";
> > +                     reg = <0x7e800000 0x800>,
> > +                           <0x7e802000 0x4>;
> > +                     interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&clocks BCM2835_CLOCK_CAM0>,
> > +                              <&firmware_clocks 4>;
> > +                     clock-names = "lp", "vpu";
> > +                     power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     #clock-cells = <1>;
>
> Why do you need #address-cells, #size-cells and #clock-cells ? They're
> not mentioned in the binding.
>
> > +                     status="disabled";
>
> Missing spaces around the =.
>
> Same comment for the next node.
>
> > +             };
> > +
> > +             csi1: csi1 at 7e801000 {
> > +                     compatible = "brcm,bcm2835-unicam";
> > +                     reg = <0x7e801000 0x800>,
> > +                           <0x7e802004 0x4>;
> > +                     interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&clocks BCM2835_CLOCK_CAM1>,
> > +                              <&firmware_clocks 4>;
> > +                     clock-names = "lp", "vpu";
> > +                     power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
> > +                     #address-cells = <1>;
> > +                     #size-cells = <0>;
> > +                     #clock-cells = <1>;
> > +                     status="disabled";
> > +             };
> > +
> >               pixelvalve3: pixelvalve at 7ec12000 {
> >                       compatible = "brcm,bcm2711-pixelvalve3";
> >                       reg = <0x7ec12000 0x100>;
>
> --
> Regards,
>
> Laurent Pinchart


From linmq006 at gmail.com  Mon Jan 24 04:41:21 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Mon, 24 Jan 2022 12:41:21 +0000
Subject: [PATCH v2] coresight: syscfg: Fix memleak on registration failure in
 cscfg_create_device
In-Reply-To: <20220120182822.GA1342128@p14s>
References: <20220120182822.GA1342128@p14s>
Message-ID: <20220124124121.8888-1-linmq006@gmail.com>

device_register() calls device_initialize(),
according to doc of device_initialize:

    Use put_device() to give up your reference instead of freeing
    * @dev directly once you have called this function.

To prevent potential memleak, use put_device() for error handling.

Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
Changes in v2:
- simply call put_device() instead of cscfg_dev_release() in the error
path of cscfg_create_device.
---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
index 43054568430f..c30989e0675f 100644
--- a/drivers/hwtracing/coresight/coresight-syscfg.c
+++ b/drivers/hwtracing/coresight/coresight-syscfg.c
@@ -791,7 +791,7 @@ static int cscfg_create_device(void)
 
 	err = device_register(dev);
 	if (err)
-		cscfg_dev_release(dev);
+		put_device(dev);
 
 create_dev_exit_unlock:
 	mutex_unlock(&cscfg_mutex);
-- 
2.17.1



From patrice.chotard at foss.st.com  Mon Jan 24 04:45:56 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 24 Jan 2022 13:45:56 +0100
Subject: [PATCH RESEND v2 2/5] pci: dwc: pcie-st: Add PCIe driver for STi
 platforms
In-Reply-To: <20220103074731.3651-3-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
 <20220103074731.3651-3-avolmat@me.com>
Message-ID: <02f6d254-be3a-0ffc-6859-83f4909c77f1@foss.st.com>

Hi Alain

Some minor remarks below

You can add my reviewed-by

Thanks
Patrice

On 1/3/22 08:47, Alain Volmat wrote:
> Addition of the PCIe driver (supporting RC) for controllers
> found on some STi platforms such as STiH407, STiH410 or
> STiH418.
> The controller is based on the designware PCIe controller.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
> v2: update of the pcie-st driver to add possibility to build as module
>     and remove the __init of the probe
> 
>  drivers/pci/controller/dwc/Kconfig    |  11 +
>  drivers/pci/controller/dwc/Makefile   |   1 +
>  drivers/pci/controller/dwc/pcie-sti.c | 386 ++++++++++++++++++++++++++
>  3 files changed, 398 insertions(+)
>  create mode 100644 drivers/pci/controller/dwc/pcie-sti.c
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 62ce3abf0f19..232b8ffd54af 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -384,4 +384,15 @@ config PCIE_FU740
>  	  Say Y here if you want PCIe controller support for the SiFive
>  	  FU740.
>  
> +config PCIE_STI
> +	tristate "STMicroelectronics PCIe Controller for STi SoCs"
> +	depends on ARCH_STI || COMPILE_TEST
> +	depends on OF && PCI_MSI_IRQ_DOMAIN
> +	select PCIE_DW_HOST
> +	help
> +	  Enable PCIe controller support on STMicroelectronics STi SoCs.
> +	  This controller is based on Designware hardware and therefore
> +	  the driver re-uses the Designware core functions to implement
> +	  the driver.
> +
>  endmenu
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index 8ba7b67f5e50..c98fa18714ce 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -21,6 +21,7 @@ obj-$(CONFIG_PCIE_KEEMBAY) += pcie-keembay.o
>  obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
>  obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
>  obj-$(CONFIG_PCI_MESON) += pci-meson.o
> +obj-$(CONFIG_PCIE_STI) += pcie-sti.o
>  obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
>  obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
>  obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
> diff --git a/drivers/pci/controller/dwc/pcie-sti.c b/drivers/pci/controller/dwc/pcie-sti.c
> new file mode 100644
> index 000000000000..61da00a079ac
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-sti.c
> @@ -0,0 +1,386 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 STMicroelectronics

2022

> + *
> + * STMicroelectronics PCI express Driver for STi SoCs.
> + * ST PCIe IPs are built around a Synopsys IP Core.
> + *
> + * Authors: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> + *          Alain Volmat <avolmat at me.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include "pcie-designware.h"
> +
> +/* RC_ADDRESS_TRANSLATION Registers */
> +#define TRANSLATION_CONTROL		0x900
> +/* Controls if area is inclusive or exclusive */
> +#define RC_PASS_ADDR_RANGE		BIT(1)
> +
> +/* Base of area reserved for config accesses. Fixed size of 64K. */
> +#define CFG_BASE_ADDRESS		0x92c
> +#define CFG_REGION_SIZE			65536

s/65536/SZ_64K

> +#define CFG_SPACE1_OFFSET		0x1000
> +
> +/* First 4K of config space has this BDF (bus,device,function) */
> +#define FUNC0_BDF_NUM			0x930
> +
> +/* Mem regions */
> +#define IN0_MEM_ADDR_START		0x964
> +#define IN0_MEM_ADDR_LIMIT		0x968
> +#define IN1_MEM_ADDR_START		0x974
> +#define IN1_MEM_ADDR_LIMIT		0x978
> +
> +/* syscfg1 bits */
> +#define PCIE_APP_LTSSM_ENABLE		BIT(2)
> +/* syscfg0 bits */
> +#define PCIE_TYPE_ROOT_COMPLEX		BIT(0)
> +
> +/* st,syscfg offsets */
> +#define SYSCFG0_REG	1
> +#define SYSCFG1_REG	2
> +
> +#define to_st_pcie(x)	dev_get_drvdata((x)->dev)
> +
> +/**
> + * struct st_pcie - private data of the controller
> + * @dw: designware pcie
> + * @syscfg0: PCIe conf register setting root complex, regmap offset
> + * @syscfg1: PCIe conf register for PCIE_APP_LTSSM_ENABLE, regmap offset
> + * @phy: associated pcie phy
> + * @lmi: memory made available to the controller
> + * @regmap: Syscfg registers bank in which PCIe port is configured
> + * @pwr: power control
> + * @rst: reset control
> + * @reset_gpio: optional reset gpio
> + * @config_window_start: start address of 64K config space area
> + */
> +struct st_pcie {
> +	struct dw_pcie *dw;
> +	int syscfg0;
> +	int syscfg1;
> +	struct phy *phy;
> +	struct resource	*lmi;
> +	struct regmap *regmap;
> +	struct reset_control *pwr;
> +	struct reset_control *rst;
> +	struct gpio_desc *reset_gpio;
> +	phys_addr_t config_window_start;
> +};
> +
> +/*
> + * The PCI express core IP expects the following arrangement on it's address
> + * bus (slv_haddr) when driving config cycles.
> + * bus_number		[31:24]
> + * dev_number		[23:19]
> + * func_number		[18:16]
> + * unused		[15:12]
> + * ext_reg_number	[11:8]
> + * reg_number		[7:2]
> + *
> + * Bits [15:12] are unused.
> + *
> + * In the glue logic there is a 64K region of address space that can be
> + * written/read to generate config cycles. The base address of this is
> + * controlled by CFG_BASE_ADDRESS. There are 8 16 bit registers called
> + * FUNC0_BDF_NUM to FUNC8_BDF_NUM. These split the bottom half of the 64K
> + * window into 8 regions at 4K boundaries. These control the bus, device and
> + * function number you are trying to talk to.
> + *
> + * The decision on whether to generate a type 0 or type 1 access is controlled
> + * by bits 15:12 of the address you write to.  If they are zero, then a type 0
> + * is generated, if anything else it will be a type 1. Thus the bottom 4K
> + * region controlled by FUNC0_BDF_NUM can only generate type 0, all the others
> + * can only generate type 1.
> + *
> + * We only use FUNC0_BDF_NUM and FUNC1_BDF_NUM. Which one you use is selected
> + * by bit 12 of the address you write to. The selected register is then used
> + * for the top 16 bits of the slv_haddr to form the bus/dev/func, bit 15:12 are
> + * wired to zero, and bits 11:2 form the address of the register you want to
> + * read in config space.
> + *
> + * We always write FUNC0_BDF_NUM as a 32 bit write. So if we want type 1
> + * accesses we have to shift by 16 so in effect we are writing to FUNC1_BDF_NUM
> + */
> +static inline u32 bdf_num(int bus, int devfn, int is_root_bus)
> +{
> +	return ((bus << 8) | devfn) << (is_root_bus ? 0 : 16);
> +}
> +
> +static void __iomem *st_pcie_other_map_bus(struct pci_bus *bus, unsigned int devfn, int where)
> +{
> +	struct pcie_port *pp = bus->sysdata;
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	u32 bdf;
> +
> +	bdf = bdf_num(bus->number, devfn, pci_is_root_bus(bus));
> +
> +	/* Set the config packet devfn */
> +	dw_pcie_writel_dbi(dw, FUNC0_BDF_NUM, bdf);
> +	dw_pcie_readl_dbi(dw, FUNC0_BDF_NUM);

Can you add an explaination about this sequence write/read the same register ?

> +
> +	return pp->va_cfg0_base + where + (pci_is_root_bus(bus->parent) ? 0 : CFG_SPACE1_OFFSET);
> +}
> +
> +static struct pci_ops st_child_pcie_ops = {
> +	.map_bus = st_pcie_other_map_bus,
> +	.read = pci_generic_config_read,
> +	.write = pci_generic_config_write,
> +};
> +
> +static void st_pcie_hw_setup(struct dw_pcie *dw)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +
> +	/* Set up the config window to the top of the PCI address space */
> +	dw_pcie_writel_dbi(dw, CFG_BASE_ADDRESS, pcie->config_window_start);
> +
> +	/*
> +	 * Open up memory to the PCI controller. We could do slightly
> +	 * better than this and exclude the kernel text segment and bss etc.
> +	 * They are base/limit registers so can be of arbitrary alignment
> +	 * presumably
> +	 */
> +	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_START, pcie->lmi->start);
> +	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_LIMIT, pcie->lmi->end);
> +
> +	/* Disable the 2nd region */
> +	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_START, ~0);
> +	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_LIMIT, 0);
> +
> +	dw_pcie_writel_dbi(dw, TRANSLATION_CONTROL, RC_PASS_ADDR_RANGE);
> +}
> +
> +static int st_pcie_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int ret;
> +
> +	/* Set device type : Root Complex */
> +	ret = regmap_write(pcie->regmap, pcie->syscfg0, PCIE_TYPE_ROOT_COMPLEX);
> +	if (ret < 0) {
> +		dev_err(dw->dev, "unable to set device type\n");
> +		return ret;
> +	}
> +
> +	ret = reset_control_deassert(pcie->pwr);
> +	if (ret) {
> +		dev_err(dw->dev, "unable to bring out of powerdown\n");
> +		return ret;
> +	}
> +
> +	ret = reset_control_deassert(pcie->rst);
> +	if (ret) {
> +		dev_err(dw->dev, "unable to bring out of softreset\n");
> +		return ret;
> +	}
> +
> +	/* let the controller initialize in the proper mode (RC) after reset */
> +	usleep_range(1000, 2000);
> +
> +	return ret;
> +}
> +
> +static int st_pcie_control_ltssm(struct dw_pcie *dw, bool enable)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +
> +	return regmap_update_bits(pcie->regmap, pcie->syscfg1, PCIE_APP_LTSSM_ENABLE,
> +				  FIELD_PREP(PCIE_APP_LTSSM_ENABLE, enable));
> +}
> +
> +static int st_pcie_host_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int err;
> +
> +	pcie->config_window_start = pp->cfg0_base;
> +
> +	/*
> +	 * "Override" default ops provided by designware driver as STI

s/STI/STi

> +	 * PCIe uses its own translation unit rather than iATU
> +	 */
> +	pp->bridge->child_ops = &st_child_pcie_ops;
> +
> +	/*
> +	 * We have to initialise the PCIe cell on some hardware before we can
> +	 * talk to the phy
> +	 */
> +	err = st_pcie_init(pp);
> +	if (err)
> +		return err;
> +
> +	err = st_pcie_control_ltssm(dw, false);
> +	if (err) {
> +		dev_err(dw->dev, "disable ltssm failed, %d\n", err);
> +		return err;
> +	}
> +
> +	/* Init the associated miphy */
> +	err = phy_init(pcie->phy);
> +	if (err < 0) {
> +		dev_err(dw->dev, "Cannot init PHY: %d\n", err);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static int st_pcie_start_link(struct dw_pcie *dw)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int err;
> +
> +	/* Do all the register poking */
> +	st_pcie_hw_setup(dw);
> +
> +	if (pcie->reset_gpio) {
> +		/* Assert the PERST# signal */
> +		gpiod_set_value(pcie->reset_gpio, 1);
> +
> +		/* PERST# signal must stay asserted for at least 100us (Tperst-clk) */
> +		usleep_range(100, 200);
> +
> +		/* Release PERST# signal */
> +		gpiod_set_value(pcie->reset_gpio, 0);
> +	}
> +
> +	/* Re-enable the link, link training must begin shortly after reset */
> +	err = st_pcie_control_ltssm(dw, true);
> +	if (err) {
> +		dev_err(dw->dev, "enable ltssm failed, %d\n", err);
> +		return err;
> +	}
> +
> +	err = dw_pcie_wait_for_link(dw);
> +	if (err) {
> +		dev_err(dw->dev, "wait for link failed, %d\n", err);
> +		return err;
> +	}
> +
> +	/*
> +	 * PCIe specification states that you should not issue any config
> +	 * requests until 100ms after asserting reset, so we enforce that here
> +	 */
> +	if  (pcie->reset_gpio)
> +		msleep(100);
> +
> +	return 0;
> +}
> +
> +static struct dw_pcie_host_ops st_pcie_host_ops = {
> +	.host_init = st_pcie_host_init,
> +};
> +
> +static const struct dw_pcie_ops dw_pcie_ops = {
> +	.start_link = st_pcie_start_link,
> +};
> +
> +static int st_pcie_probe(struct platform_device *pdev)
> +{
> +	struct st_pcie *pcie;
> +	struct dw_pcie *dw;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct pcie_port *pp;
> +	int ret;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
> +	if (!dw)
> +		return -ENOMEM;
> +	pcie->dw = dw;
> +	dw->dev = &pdev->dev;
> +	dw->ops = &dw_pcie_ops;
> +
> +	pp = &dw->pp;
> +	pp->ops = &st_pcie_host_ops;
> +
> +	/* mem regions */
> +	pcie->lmi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem-window");
> +	if (!pcie->lmi)
> +		return -ENXIO;
> +
> +	/* regmap registers for PCIe IP configuration */
> +	pcie->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +	if (IS_ERR(pcie->regmap))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->regmap),
> +				     "No syscfg phandle specified\n");
> +
> +	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG0_REG, &pcie->syscfg0);
> +	if (ret) {
> +		dev_err(&pdev->dev, "can't get syscfg0 offset (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG1_REG, &pcie->syscfg1);
> +	if (ret) {
> +		dev_err(&pdev->dev, "can't get syscfg1 offset (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	/* powerdown / resets */
> +	pcie->pwr = devm_reset_control_get_optional(&pdev->dev, "powerdown");
> +	if (IS_ERR(pcie->pwr))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->pwr),
> +				     "Error getting powerdown reset control\n");
> +
> +	pcie->rst = devm_reset_control_get(&pdev->dev, "softreset");
> +	if (IS_ERR(pcie->rst))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->rst),
> +				     "Error getting softreset control\n");
> +
> +	/* phy */
> +	pcie->phy = devm_phy_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->phy))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy), "no PHY configured\n");
> +
> +	/* Claim the GPIO for PRST# if available, keep it de-asserted */
> +	pcie->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(pcie->reset_gpio))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reset_gpio),
> +				     "Cannot request reset-gpios\n");
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	ret = dw_pcie_host_init(pp);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "failed to initialize host\n");
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id st_pcie_of_match[] = {
> +	{ .compatible = "st,stih407-pcie", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, st_pcie_of_match);
> +
> +static struct platform_driver st_pcie_driver __refdata = {
> +	.probe  = st_pcie_probe,
> +	.driver = {
> +		.name = "st-pcie",
> +		.of_match_table = st_pcie_of_match,
> +	},
> +};
> +module_platform_driver(st_pcie_driver);
> +
> +MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier at foss.st.com>");
> +MODULE_AUTHOR("Alain Volmat <avolmat at me.com>");
> +MODULE_DESCRIPTION("STi PCIe Controller driver");
> +MODULE_LICENSE("GPL v2");


From patrice.chotard at foss.st.com  Mon Jan 24 04:46:50 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 24 Jan 2022 13:46:50 +0100
Subject: [PATCH RESEND v2 3/5] MAINTAINERS: add entry for ST STI PCIE
 driver
In-Reply-To: <20220103074731.3651-4-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
 <20220103074731.3651-4-avolmat@me.com>
Message-ID: <d198270b-9280-68d0-af70-5c6efcb4aac6@foss.st.com>

Hi Alain

On 1/3/22 08:47, Alain Volmat wrote:
> Add PCIE Driver entry for STI family from ST Microelectronics.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  MAINTAINERS | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 360e9aa0205d..081ccdfbd89c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -14666,6 +14666,12 @@ L:	linux-samsung-soc at vger.kernel.org
>  S:	Maintained
>  F:	drivers/pci/controller/dwc/pci-exynos.c
>  
> +PCI DRIVER FOR ST STI PLATFORM
> +M:	Alain Volmat <avolmat at me.com>
> +L:	linux-pci at vger.kernel.org
> +S:	Maintained
> +F:	drivers/pci/controller/dwc/pcie-sti.c
> +
>  PCI DRIVER FOR SYNOPSYS DESIGNWARE
>  M:	Jingoo Han <jingoohan1 at gmail.com>
>  M:	Gustavo Pimentel <gustavo.pimentel at synopsys.com>

Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>
Thanks
Patrice


From patrice.chotard at foss.st.com  Mon Jan 24 04:47:40 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 24 Jan 2022 13:47:40 +0100
Subject: [PATCH RESEND v2 4/5] ARM: dts: sti: add the PCIe controller node
 within stih407-family
In-Reply-To: <20220103074731.3651-5-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
 <20220103074731.3651-5-avolmat@me.com>
Message-ID: <6d45806f-d8f0-dabd-ae65-a820c1880ed4@foss.st.com>

Hi Alain

On 1/3/22 08:47, Alain Volmat wrote:
> Add the pcie1 entry within stih407-family dtsi.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih407-family.dtsi | 40 +++++++++++++++++++++++++++
>  1 file changed, 40 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih407-family.dtsi b/arch/arm/boot/dts/stih407-family.dtsi
> index 21f3347a91d6..fe4ea2d5b583 100644
> --- a/arch/arm/boot/dts/stih407-family.dtsi
> +++ b/arch/arm/boot/dts/stih407-family.dtsi
> @@ -631,6 +631,46 @@ spifsm: spifsm at 9022000{
>  			status = "disabled";
>  		};
>  
> +		pcie1: pcie at 9b10000 {
> +			compatible = "st,stih407-pcie";
> +			device_type = "pci";
> +			reg = <0x09b10000 0x00001000>,	/* cntrl registers */
> +			      <0x3fff0000 0x00010000>,	/* config space */
> +			      <0x40000000 0xc0000000>;	/* lmi mem window */
> +
> +			reg-names = "dbi",
> +				    "config",
> +				    "mem-window";
> +
> +			st,syscfg = <&syscfg_core 0xdc 0xe4>;
> +
> +			#interrupt-cells = <1>;
> +			interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>;
> +			interrupt-names = "msi";
> +			interrupt-map-mask = <0 0 0 7>;
> +			interrupt-map = <0 0 0 1 &intc GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 2 &intc GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 3 &intc GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
> +					<0 0 0 4 &intc GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
> +
> +			#address-cells = <3>;
> +			#size-cells = <2>;
> +			/* non-prefetchable and prefetchable */
> +			ranges = <0x82000000 0 0x30000000 0x30000000 0 0x05550000>,
> +				 <0xc2000000 0 0x35550000 0x35550000 0 0x0AAA0000>;
> +			bus-range = <0x00 0xff>;
> +
> +			resets = <&softreset STIH407_PCIE1_SOFTRESET>,
> +				 <&powerdown STIH407_PCIE1_POWERDOWN>;
> +
> +			reset-names = "softreset", "powerdown";
> +
> +			phys = <&phy_port1 PHY_TYPE_PCIE>;
> +			phy-names = "pcie";
> +
> +			status = "disabled";
> +		};
> +
>  		sata0: sata at 9b20000 {
>  			compatible = "st,ahci";
>  			reg = <0x9b20000 0x1000>;
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From patrice.chotard at foss.st.com  Mon Jan 24 04:48:05 2022
From: patrice.chotard at foss.st.com (Patrice CHOTARD)
Date: Mon, 24 Jan 2022 13:48:05 +0100
Subject: [PATCH RESEND v2 5/5] ARM: dts: sti: enable PCIe on the
 stih418-b2264 board
In-Reply-To: <20220103074731.3651-6-avolmat@me.com>
References: <20220103074731.3651-1-avolmat@me.com>
 <20220103074731.3651-6-avolmat@me.com>
Message-ID: <26d5410e-60c7-6f75-6624-a393ffcffe9a@foss.st.com>

Hi Alain

On 1/3/22 08:47, Alain Volmat wrote:
> Enable the PCIe controller with proper reset gpio pin for this board.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  arch/arm/boot/dts/stih418-b2264.dts | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/stih418-b2264.dts b/arch/arm/boot/dts/stih418-b2264.dts
> index a99604bebf8c..ed183292a669 100644
> --- a/arch/arm/boot/dts/stih418-b2264.dts
> +++ b/arch/arm/boot/dts/stih418-b2264.dts
> @@ -130,6 +130,11 @@ &ohci1 {
>  	status = "okay";
>  };
>  
> +&pcie1 {
> +	reset-gpios = <&pio34 5 GPIO_ACTIVE_LOW>;
> +	status = "okay";
> +};
> +
>  &pwm1 {
>  	status = "okay";
>  };
Reviewed-by: Patrice Chotard <patrice.chotard at foss.st.com>

Thanks
Patrice


From anshuman.khandual at arm.com  Mon Jan 24 04:56:42 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 18:26:42 +0530
Subject: [RFC V1 05/31] arm64/mm: Enable ARCH_HAS_VM_GET_PAGE_PROT
In-Reply-To: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
References: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643029028-12710-6-git-send-email-anshuman.khandual@arm.com>

This defines and exports a platform specific custom vm_get_page_prot() via
subscribing ARCH_HAS_VM_GET_PAGE_PROT. Subsequently all __SXXX and __PXXX
macros can be dropped which are no longer needed. This also localizes both
arch_filter_pgprot and arch_vm_get_page_prot() helpers, unsubscribing from
ARCH_HAS_FILTER_PGPROT as well.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                    |  2 +-
 arch/arm64/include/asm/mman.h         |  3 +-
 arch/arm64/include/asm/pgtable-prot.h | 18 ----------
 arch/arm64/include/asm/pgtable.h      |  2 +-
 arch/arm64/mm/mmap.c                  | 50 +++++++++++++++++++++++++++
 5 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cad609528e58..fce2d0fc4ecc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -23,7 +23,6 @@ config ARM64
 	select ARCH_HAS_DMA_PREP_COHERENT
 	select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
 	select ARCH_HAS_FAST_MULTIPLIER
-	select ARCH_HAS_FILTER_PGPROT
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_GIGANTIC_PAGE
@@ -44,6 +43,7 @@ config ARM64
 	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TEARDOWN_DMA_OPS if IOMMU_SUPPORT
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+	select ARCH_HAS_VM_GET_PAGE_PROT
 	select ARCH_HAS_ZONE_DMA_SET if EXPERT
 	select ARCH_HAVE_ELF_PROT
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h
index e3e28f7daf62..85f41f72a8b3 100644
--- a/arch/arm64/include/asm/mman.h
+++ b/arch/arm64/include/asm/mman.h
@@ -35,7 +35,7 @@ static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
 }
 #define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
 
-static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
+static inline pgprot_t arm64_arch_vm_get_page_prot(unsigned long vm_flags)
 {
 	pteval_t prot = 0;
 
@@ -57,7 +57,6 @@ static inline pgprot_t arch_vm_get_page_prot(unsigned long vm_flags)
 
 	return __pgprot(prot);
 }
-#define arch_vm_get_page_prot(vm_flags) arch_vm_get_page_prot(vm_flags)
 
 static inline bool arch_validate_prot(unsigned long prot,
 	unsigned long addr __always_unused)
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h
index 7032f04c8ac6..d8ee0aa7886d 100644
--- a/arch/arm64/include/asm/pgtable-prot.h
+++ b/arch/arm64/include/asm/pgtable-prot.h
@@ -88,24 +88,6 @@ extern bool arm64_use_ng_mappings;
 #define PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN)
 #define PAGE_EXECONLY		__pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
 
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_READONLY
-#define __P011  PAGE_READONLY
-#define __P100  PAGE_EXECONLY
-#define __P101  PAGE_READONLY_EXEC
-#define __P110  PAGE_READONLY_EXEC
-#define __P111  PAGE_READONLY_EXEC
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_EXECONLY
-#define __S101  PAGE_READONLY_EXEC
-#define __S110  PAGE_SHARED_EXEC
-#define __S111  PAGE_SHARED_EXEC
-
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_PGTABLE_PROT_H */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c4ba047a82d2..5a73501a45ed 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1017,7 +1017,7 @@ static inline bool arch_wants_old_prefaulted_pte(void)
 }
 #define arch_wants_old_prefaulted_pte	arch_wants_old_prefaulted_pte
 
-static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
+static inline pgprot_t arm64_arch_filter_pgprot(pgprot_t prot)
 {
 	if (cpus_have_const_cap(ARM64_HAS_EPAN))
 		return prot;
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index a38f54cd638c..ad605eb86d23 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -10,6 +10,7 @@
 #include <linux/types.h>
 
 #include <asm/page.h>
+#include <asm/mman.h>
 
 /*
  * You really shouldn't be using read() or write() on /dev/mem.  This might go
@@ -38,3 +39,52 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
 {
 	return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
 }
+
+static inline pgprot_t __vm_get_page_prot(unsigned long vm_flags)
+{
+	switch (vm_flags & (VM_READ | VM_WRITE | VM_EXEC | VM_SHARED)) {
+	case VM_NONE:
+		return PAGE_NONE;
+	case VM_READ:
+		return PAGE_READONLY;
+	case VM_WRITE:
+		return PAGE_READONLY;
+	case VM_READ | VM_WRITE:
+		return PAGE_READONLY;
+	case VM_EXEC:
+		return PAGE_EXECONLY;
+	case VM_EXEC | VM_READ:
+		return PAGE_READONLY_EXEC;
+	case VM_EXEC | VM_WRITE:
+		return PAGE_READONLY_EXEC;
+	case VM_EXEC | VM_READ | VM_WRITE:
+		return PAGE_READONLY_EXEC;
+	case VM_SHARED:
+		return PAGE_NONE;
+	case VM_SHARED | VM_READ:
+		return PAGE_READONLY;
+	case VM_SHARED | VM_WRITE:
+		return PAGE_SHARED;
+	case VM_SHARED | VM_READ | VM_WRITE:
+		return PAGE_SHARED;
+	case VM_SHARED | VM_EXEC:
+		return PAGE_EXECONLY;
+	case VM_SHARED | VM_EXEC | VM_READ:
+		return PAGE_READONLY_EXEC;
+	case VM_SHARED | VM_EXEC | VM_WRITE:
+		return PAGE_SHARED_EXEC;
+	case VM_SHARED | VM_EXEC | VM_READ | VM_WRITE:
+		return PAGE_SHARED_EXEC;
+	default:
+		BUILD_BUG();
+	}
+}
+
+pgprot_t vm_get_page_prot(unsigned long vm_flags)
+{
+	pgprot_t ret = __pgprot(pgprot_val(__vm_get_page_prot(vm_flags)) |
+			pgprot_val(arm64_arch_vm_get_page_prot(vm_flags)));
+
+	return arm64_arch_filter_pgprot(ret);
+}
+EXPORT_SYMBOL(vm_get_page_prot);
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 24 04:56:46 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Mon, 24 Jan 2022 18:26:46 +0530
Subject: [RFC V1 09/31] arm/mm: Enable ARCH_HAS_VM_GET_PAGE_PROT
In-Reply-To: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
References: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643029028-12710-10-git-send-email-anshuman.khandual@arm.com>

This defines and exports a platform specific custom vm_get_page_prot() via
subscribing ARCH_HAS_VM_GET_PAGE_PROT. Subsequently all __SXXX and __PXXX
macros can be dropped which are no longer needed.

Cc: Russell King <linux at armlinux.org.uk>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm/Kconfig               |  1 +
 arch/arm/include/asm/pgtable.h | 18 ------------
 arch/arm/mm/mmu.c              | 50 ++++++++++++++++++++++++++++++----
 3 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..c12362d20c44 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -23,6 +23,7 @@ config ARM
 	select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB || !MMU
 	select ARCH_HAS_TEARDOWN_DMA_OPS if MMU
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+	select ARCH_HAS_VM_GET_PAGE_PROT
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if CPU_V7 || CPU_V7M || CPU_V6K
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index cd1f84bb40ae..ec062dd6082a 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -137,24 +137,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
  *  2) If we could do execute protection, then read is implied
  *  3) write implies read permissions
  */
-#define __P000  __PAGE_NONE
-#define __P001  __PAGE_READONLY
-#define __P010  __PAGE_COPY
-#define __P011  __PAGE_COPY
-#define __P100  __PAGE_READONLY_EXEC
-#define __P101  __PAGE_READONLY_EXEC
-#define __P110  __PAGE_COPY_EXEC
-#define __P111  __PAGE_COPY_EXEC
-
-#define __S000  __PAGE_NONE
-#define __S001  __PAGE_READONLY
-#define __S010  __PAGE_SHARED
-#define __S011  __PAGE_SHARED
-#define __S100  __PAGE_READONLY_EXEC
-#define __S101  __PAGE_READONLY_EXEC
-#define __S110  __PAGE_SHARED_EXEC
-#define __S111  __PAGE_SHARED_EXEC
-
 #ifndef __ASSEMBLY__
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 274e4f73fd33..3007d07bc0e7 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -403,6 +403,8 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
 	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
 }
 
+static pteval_t user_pgprot;
+
 /*
  * Adjust the PMD section entries according to the CPU in use.
  */
@@ -410,7 +412,7 @@ static void __init build_mem_type_table(void)
 {
 	struct cachepolicy *cp;
 	unsigned int cr = get_cr();
-	pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
+	pteval_t kern_pgprot, vecs_pgprot;
 	int cpu_arch = cpu_architecture();
 	int i;
 
@@ -627,11 +629,6 @@ static void __init build_mem_type_table(void)
 	user_pgprot |= PTE_EXT_PXN;
 #endif
 
-	for (i = 0; i < 16; i++) {
-		pteval_t v = pgprot_val(protection_map[i]);
-		protection_map[i] = __pgprot(v | user_pgprot);
-	}
-
 	mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
 	mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
 
@@ -670,6 +667,47 @@ static void __init build_mem_type_table(void)
 	}
 }
 
+pgprot_t vm_get_page_prot(unsigned long vm_flags)
+{
+	switch (vm_flags & (VM_READ | VM_WRITE | VM_EXEC | VM_SHARED)) {
+	case VM_NONE:
+		return __pgprot(pgprot_val(__PAGE_NONE) | user_pgprot);
+	case VM_READ:
+		return __pgprot(pgprot_val(__PAGE_READONLY) | user_pgprot);
+	case VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_COPY) | user_pgprot);
+	case VM_READ | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_COPY) | user_pgprot);
+	case VM_EXEC:
+		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
+	case VM_EXEC | VM_READ:
+		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
+	case VM_EXEC | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_COPY_EXEC) | user_pgprot);
+	case VM_EXEC | VM_READ | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_COPY_EXEC) | user_pgprot);
+	case VM_SHARED:
+		return __pgprot(pgprot_val(__PAGE_NONE) | user_pgprot);
+	case VM_SHARED | VM_READ:
+		return __pgprot(pgprot_val(__PAGE_READONLY) | user_pgprot);
+	case VM_SHARED | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_SHARED) | user_pgprot);
+	case VM_SHARED | VM_READ | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_SHARED) | user_pgprot);
+	case VM_SHARED | VM_EXEC:
+		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
+	case VM_SHARED | VM_EXEC | VM_READ:
+		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
+	case VM_SHARED | VM_EXEC | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_SHARED_EXEC) | user_pgprot);
+	case VM_SHARED | VM_EXEC | VM_READ | VM_WRITE:
+		return __pgprot(pgprot_val(__PAGE_SHARED_EXEC) | user_pgprot);
+	default:
+		BUILD_BUG();
+	}
+}
+EXPORT_SYMBOL(vm_get_page_prot);
+
 #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
 pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 			      unsigned long size, pgprot_t vma_prot)
-- 
2.25.1



From broonie at kernel.org  Mon Jan 24 05:05:59 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 13:05:59 +0000
Subject: [PATCH] arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
In-Reply-To: <164301227374.1433152.12808232644267107415.stgit@devnote2>
References: <164301227374.1433152.12808232644267107415.stgit@devnote2>
Message-ID: <Ye6kNwFisZw2MwV1@sirena.org.uk>

On Mon, Jan 24, 2022 at 05:17:54PM +0900, Masami Hiramatsu wrote:
> Mark the start_backtrace() as notrace and NOKPROBE_SYMBOL
> because this function is called from ftrace and lockdep to
> get the caller address via return_address(). The lockdep
> is used in kprobes, it should also be NOKPROBE_SYMBOL.

Reviwed-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/9f6f5571/attachment.sig>

From lkp at intel.com  Mon Jan 24 05:08:14 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 24 Jan 2022 21:08:14 +0800
Subject: [PATCH V3 06/10] arm64: dts: imx8mq: Enable both G1 and G2 VPU's
 with vpu-blk-ctrl
In-Reply-To: <20220124023125.414794-7-aford173@gmail.com>
References: <20220124023125.414794-7-aford173@gmail.com>
Message-ID: <202201242024.Xqet4cvg-lkp@intel.com>

Hi Adam,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on e783362eb54cd99b2cac8b3a9aeac942e6f6ac07]

url:    https://github.com/0day-ci/linux/commits/Adam-Ford/media-hantro-imx8mq-imx8mm-Let-VPU-decoders-get-controlled-by-vpu-blk-ctrl/20220124-103340
base:   e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
config: arm64-buildonly-randconfig-r001-20220124 (https://download.01.org/0day-ci/archive/20220124/202201242024.Xqet4cvg-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/a74e6df1159d70d74f2a6988748f8e9648478d86
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Adam-Ford/media-hantro-imx8mq-imx8mm-Let-VPU-decoders-get-controlled-by-vpu-blk-ctrl/20220124-103340
        git checkout a74e6df1159d70d74f2a6988748f8e9648478d86
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> Error: arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi:275.1-5 Label or path vpu not found
   FATAL ERROR: Syntax error parsing input tree

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From yangyicong at hisilicon.com  Mon Jan 24 05:11:10 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:10 +0800
Subject: [PATCH v3 0/8] Add support for HiSilicon PCIe Tune and Trace device
Message-ID: <20220124131118.17887-1-yangyicong@hisilicon.com>

HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
integrated Endpoint (RCiEP) device, providing the capability
to dynamically monitor and tune the PCIe traffic (tune),
and trace the TLP headers (trace).

PTT tune is designed for monitoring and adjusting PCIe link parameters.
We provide several parameters of the PCIe link. Through the driver,
user can adjust the value of certain parameter to affect the PCIe link
for the purpose of enhancing the performance in certian situation.

PTT trace is designed for dumping the TLP headers to the memory, which
can be used to analyze the transactions and usage condition of the PCIe
Link. Users can choose filters to trace headers, by either requester
ID, or those downstream of a set of Root Ports on the same core of the
PTT device. It's also supported to trace the headers of certain type and
of certain direction.

The driver registers a PMU device for each PTT device. The trace can
be used through `perf record` and the traced headers can be decoded
by `perf report`. The perf command support for the device is also
added in this patchset. The tune can be used through the sysfs
attributes of related PMU device. See the documentation for the
detailed usage.

Change since v2:
- address the comments from Mathieu
  - rename the directory to ptt to match the function of the device
  - spinoff the declarations to a separate header
  - split the trace function to several patches
  - some other comments.
- make default smmu domain type of PTT device to identity
  Drop the RMR as it's not recommended and use an iommu_def_domain_type
  quirk to passthrough the device DMA as suggested by Robin. 
Link: https://lore.kernel.org/linux-pci/20211116090625.53702-1-yangyicong at hisilicon.com/

Change since v1:
- switch the user interface of trace to perf from debugfs
- switch the user interface of tune to sysfs from debugfs
- add perf tool support to start trace and decode the trace data
- address the comments of documentation from Bjorn
- add RMR[1] support of the device as trace works in RMR mode or
  direct DMA mode. RMR support is achieved by common APIs rather
  than the APIs implemented in [1].
Link: https://lore.kernel.org/lkml/1618654631-42454-1-git-send-email-yangyicong at hisilicon.com/

[1] https://lore.kernel.org/linux-acpi/20210805080724.480-1-shameerali.kolothum.thodi at huawei.com/

Qi Liu (1):
  perf tool: Add support for HiSilicon PCIe Tune and Trace device driver

Yicong Yang (7):
  hwtracing: Add trace function support for HiSilicon PCIe Tune and
    Trace device
  hisi_ptt: Register PMU device for PTT trace
  hisi_ptt: Add support for dynamically updating the filter list
  hisi_ptt: Add tune function support for HiSilicon PCIe Tune and Trace
    device
  docs: Add HiSilicon PTT device driver documentation
  MAINTAINERS: Add maintainer for HiSilicon PTT driver
  iommu/arm-smmu-v3: Make default domain type of HiSilicon PTT device to
    identity

 Documentation/trace/hisi-ptt.rst              |  304 +++++
 MAINTAINERS                                   |    7 +
 drivers/Makefile                              |    1 +
 drivers/hwtracing/Kconfig                     |    2 +
 drivers/hwtracing/ptt/Kconfig                 |   11 +
 drivers/hwtracing/ptt/Makefile                |    2 +
 drivers/hwtracing/ptt/hisi_ptt.c              | 1124 +++++++++++++++++
 drivers/hwtracing/ptt/hisi_ptt.h              |  239 ++++
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   |   16 +
 tools/perf/arch/arm/util/auxtrace.c           |   56 +-
 tools/perf/arch/arm/util/pmu.c                |    3 +
 tools/perf/arch/arm64/util/Build              |    2 +-
 tools/perf/arch/arm64/util/hisi_ptt.c         |  195 +++
 tools/perf/util/Build                         |    2 +
 tools/perf/util/auxtrace.c                    |    4 +
 tools/perf/util/auxtrace.h                    |    1 +
 tools/perf/util/hisi-ptt-decoder/Build        |    1 +
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c   |  170 +++
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h   |   28 +
 tools/perf/util/hisi_ptt.c                    |  228 ++++
 tools/perf/util/hisi_ptt.h                    |   28 +
 21 files changed, 2420 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/trace/hisi-ptt.rst
 create mode 100644 drivers/hwtracing/ptt/Kconfig
 create mode 100644 drivers/hwtracing/ptt/Makefile
 create mode 100644 drivers/hwtracing/ptt/hisi_ptt.c
 create mode 100644 drivers/hwtracing/ptt/hisi_ptt.h
 create mode 100644 tools/perf/arch/arm64/util/hisi_ptt.c
 create mode 100644 tools/perf/util/hisi-ptt-decoder/Build
 create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
 create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
 create mode 100644 tools/perf/util/hisi_ptt.c
 create mode 100644 tools/perf/util/hisi_ptt.h

-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:17 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:17 +0800
Subject: [PATCH v3 7/8] MAINTAINERS: Add maintainer for HiSilicon PTT driver
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-8-yangyicong@hisilicon.com>

Add maintainer for driver and documentation of HiSilicon PTT device.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..237c618a74d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8689,6 +8689,13 @@ F:	Documentation/admin-guide/perf/hisi-pcie-pmu.rst
 F:	Documentation/admin-guide/perf/hisi-pmu.rst
 F:	drivers/perf/hisilicon
 
+HISILICON PTT DRIVER
+M:	Yicong Yang <yangyicong at hisilicon.com>
+L:	linux-kernel at vger.kernel.org
+S:	Maintained
+F:	Documentation/trace/hisi-ptt.rst
+F:	drivers/hwtracing/ptt/
+
 HISILICON QM AND ZIP Controller DRIVER
 M:	Zhou Wang <wangzhou1 at hisilicon.com>
 L:	linux-crypto at vger.kernel.org
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:18 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:18 +0800
Subject: [PATCH v3 8/8] iommu/arm-smmu-v3: Make default domain type of
 HiSilicon PTT device to identity
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-9-yangyicong@hisilicon.com>

The DMA of HiSilicon PTT device can only work with identical
mapping. So add a quirk for the device to force the domain
passthrough.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 6dc6d8b6b368..6f67a2b1dd27 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2838,6 +2838,21 @@ static int arm_smmu_dev_disable_feature(struct device *dev,
 	}
 }
 
+#define IS_HISI_PTT_DEVICE(pdev)	((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \
+					 (pdev)->device == 0xa12e)
+
+static int arm_smmu_def_domain_type(struct device *dev)
+{
+	if (dev_is_pci(dev)) {
+		struct pci_dev *pdev = to_pci_dev(dev);
+
+		if (IS_HISI_PTT_DEVICE(pdev))
+			return IOMMU_DOMAIN_IDENTITY;
+	}
+
+	return 0;
+}
+
 static struct iommu_ops arm_smmu_ops = {
 	.capable		= arm_smmu_capable,
 	.domain_alloc		= arm_smmu_domain_alloc,
@@ -2863,6 +2878,7 @@ static struct iommu_ops arm_smmu_ops = {
 	.sva_unbind		= arm_smmu_sva_unbind,
 	.sva_get_pasid		= arm_smmu_sva_get_pasid,
 	.page_response		= arm_smmu_page_response,
+	.def_domain_type	= arm_smmu_def_domain_type,
 	.pgsize_bitmap		= -1UL, /* Restricted during device attach */
 	.owner			= THIS_MODULE,
 };
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:13 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:13 +0800
Subject: [PATCH v3 3/8] hisi_ptt: Add support for dynamically updating the
 filter list
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-4-yangyicong@hisilicon.com>

The PCIe devices supported by the PTT trace can be removed/rescanned
by hotplug or through sysfs.  Add support for dynamically updating
the available filter list by registering a PCI bus notifier block.
Then user can always get latest information about available tracing
filters and driver can block the invalid filters of which related
devices no longer exist in the system.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/hwtracing/ptt/hisi_ptt.c | 141 ++++++++++++++++++++++++++++---
 drivers/hwtracing/ptt/hisi_ptt.h |  39 +++++++++
 2 files changed, 167 insertions(+), 13 deletions(-)

diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
index eeb8afc65a56..2994354e690b 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.c
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
@@ -271,26 +271,120 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
 	return 0;
 }
 
-static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
+static void hisi_ptt_update_filters(struct work_struct *work)
 {
+	struct delayed_work *delayed_work = to_delayed_work(work);
+	struct hisi_ptt_filter_update_info info;
 	struct hisi_ptt_filter_desc *filter;
-	struct hisi_ptt *hisi_ptt = data;
 	struct list_head *target_list;
+	struct hisi_ptt *hisi_ptt;
 
-	target_list = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ?
-		      &hisi_ptt->port_filters : &hisi_ptt->req_filters;
+	hisi_ptt = container_of(delayed_work, struct hisi_ptt, work);
 
-	filter = kzalloc(sizeof(*filter), GFP_KERNEL);
-	if (!filter)
-		return -ENOMEM;
+	if (!mutex_trylock(&hisi_ptt->mutex)) {
+		schedule_delayed_work(&hisi_ptt->work, HISI_PTT_WORK_DELAY_MS);
+		return;
+	}
 
-	filter->pdev = pdev;
-	filter->val = hisi_ptt_get_filter_val(pdev);
-	list_add_tail(&filter->list, target_list);
+	while (kfifo_get(&hisi_ptt->filter_update_kfifo, &info)) {
+		target_list = info.is_port ? &hisi_ptt->port_filters :
+			      &hisi_ptt->req_filters;
+
+		if (info.is_add) {
+			filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+			if (!filter)
+				continue;
+
+			filter->pdev = info.pdev;
+			filter->val = info.val;
+
+			list_add_tail(&filter->list, target_list);
+		} else {
+			list_for_each_entry(filter, target_list, list)
+				if (filter->val == info.val) {
+					list_del(&filter->list);
+					kfree(filter);
+					break;
+				}
+		}
 
-	/* Update the available port mask */
-	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
-		hisi_ptt->port_mask |= filter->val;
+		/* Update the available port mask */
+		if (!info.is_port)
+			continue;
+
+		if (info.is_add)
+			hisi_ptt->port_mask |= info.val;
+		else
+			hisi_ptt->port_mask &= ~info.val;
+	}
+
+	mutex_unlock(&hisi_ptt->mutex);
+}
+
+static void hisi_ptt_update_fifo_in(struct hisi_ptt *hisi_ptt,
+				    struct hisi_ptt_filter_update_info *info)
+{
+	struct pci_dev *root_port = pcie_find_root_port(info->pdev);
+
+	if (!root_port)
+		return;
+
+	info->port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn);
+	if (info->port_devid < hisi_ptt->lower ||
+	    info->port_devid > hisi_ptt->upper)
+		return;
+
+	info->is_port = pci_pcie_type(info->pdev) == PCI_EXP_TYPE_ROOT_PORT;
+	info->val = hisi_ptt_get_filter_val(info->pdev);
+
+	if (kfifo_in_spinlocked(&hisi_ptt->filter_update_kfifo, info, 1,
+				&hisi_ptt->filter_update_lock))
+		schedule_delayed_work(&hisi_ptt->work, 0);
+	else
+		pci_warn(hisi_ptt->pdev,
+			 "filter update fifo overflow for target %s\n",
+			 pci_name(info->pdev));
+}
+
+/*
+ * A PCI bus notifier is used here for dynamically updating the filter
+ * list.
+ */
+static int hisi_ptt_notifier_call(struct notifier_block *nb, unsigned long action,
+				  void *data)
+{
+	struct hisi_ptt *hisi_ptt = container_of(nb, struct hisi_ptt, hisi_ptt_nb);
+	struct hisi_ptt_filter_update_info info;
+	struct device *dev = data;
+	struct pci_dev *pdev = to_pci_dev(dev);
+
+	info.pdev = pdev;
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		info.is_add = true;
+		break;
+	case BUS_NOTIFY_DEL_DEVICE:
+		info.is_add = false;
+		break;
+	default:
+		return 0;
+	}
+
+	hisi_ptt_update_fifo_in(hisi_ptt, &info);
+
+	return 0;
+}
+
+static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
+{
+	struct hisi_ptt_filter_update_info info = {
+		.pdev = pdev,
+		.is_add = true,
+	};
+	struct hisi_ptt *hisi_ptt = data;
+
+	hisi_ptt_update_fifo_in(hisi_ptt, &info);
 
 	return 0;
 }
@@ -316,6 +410,9 @@ static void hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
 	struct pci_bus *bus;
 	u32 reg;
 
+	INIT_DELAYED_WORK(&hisi_ptt->work, hisi_ptt_update_filters);
+	spin_lock_init(&hisi_ptt->filter_update_lock);
+	INIT_KFIFO(hisi_ptt->filter_update_kfifo);
 	INIT_LIST_HEAD(&hisi_ptt->port_filters);
 	INIT_LIST_HEAD(&hisi_ptt->req_filters);
 
@@ -336,6 +433,13 @@ static void hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
 	hisi_ptt->core_id = FIELD_GET(HISI_PTT_CORE_ID, reg);
 	hisi_ptt->sicl_id = FIELD_GET(HISI_PTT_SICL_ID, reg);
 
+	/*
+	 * No need to fail if the bus is NULL here as the device
+	 * maybe hotplugged after the PTT driver probe, in which
+	 * case we can detect the event and update the list as
+	 * we register a bus notifier for dynamically updating
+	 * the filter list.
+	 */
 	bus = pci_find_bus(pci_domain_nr(pdev->bus), PCI_BUS_NUM(hisi_ptt->upper));
 	if (bus)
 		pci_walk_bus(bus, hisi_ptt_init_filters, hisi_ptt);
@@ -822,6 +926,12 @@ static int hisi_ptt_probe(struct pci_dev *pdev,
 		return ret;
 	}
 
+	/* Register the bus notifier for dynamically updating the filter list */
+	hisi_ptt->hisi_ptt_nb.notifier_call = hisi_ptt_notifier_call;
+	ret = bus_register_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
+	if (ret)
+		pci_warn(pdev, "failed to register filter update notifier, ret = %d", ret);
+
 	return 0;
 }
 
@@ -829,6 +939,11 @@ void hisi_ptt_remove(struct pci_dev *pdev)
 {
 	struct hisi_ptt *hisi_ptt = pci_get_drvdata(pdev);
 
+	bus_unregister_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
+
+	/* Cancel any work that has been queued */
+	cancel_delayed_work_sync(&hisi_ptt->work);
+
 	if (hisi_ptt->trace_ctrl.status == HISI_PTT_TRACE_STATUS_ON)
 		hisi_ptt_trace_end(hisi_ptt);
 
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
index 002b64dfa42d..151e9e544653 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.h
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
@@ -10,11 +10,15 @@
 #define _HISI_PTT_H
 
 #include <linux/bits.h>
+#include <linux/kfifo.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
+#include <linux/notifier.h>
 #include <linux/pci.h>
 #include <linux/perf_event.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 /*
  * The definition of the device registers and register fields.
@@ -50,6 +54,10 @@
 #define HISI_PTT_TRACE_BUF_SIZE			SZ_4M
 #define HISI_PTT_TRACE_TOTAL_BUF_SIZE		(HISI_PTT_TRACE_BUF_SIZE * \
 						 HISI_PTT_TRACE_BUF_CNT)
+/* FIFO size for dynamically updating the PTT trace filter list. */
+#define HISI_PTT_FILTER_UPDATE_FIFO_SIZE	16
+/* Delay time for filter updating work */
+#define HISI_PTT_WORK_DELAY_MS		100UL
 /* Wait time for DMA hardware to reset */
 #define HISI_PTT_RESET_WAIT_MS		1000UL
 /* Poll timeout and interval for waiting hardware work to finish */
@@ -136,6 +144,22 @@ struct hisi_ptt_pmu_buf {
 	long pos;
 };
 
+/**
+ * struct hisi_ptt_filter_update_info - information for PTT filter updating
+ * @pdev:       the PCI device to update in the filter list
+ * @port_devid: the device ID of the PCI device
+ * @is_port:    whether the PCI device is a root port
+ * @is_add:     adding to the filter or not
+ * @val:        the filter value related to the PCI device
+ */
+struct hisi_ptt_filter_update_info {
+	struct pci_dev *pdev;
+	u32 port_devid;
+	bool is_port;
+	bool is_add;
+	u16 val;
+};
+
 /**
  * struct hisi_ptt - per PTT device data
  * @trace_ctrl:   the control information of PTT trace
@@ -151,9 +175,13 @@ struct hisi_ptt_pmu_buf {
  * @port_filters: the filter list of root ports
  * @req_filters:  the filter list of requester ID
  * @port_mask:    port mask of the managed root ports
+ * @work:         delayed work for filter updating
+ * @filter_update_lock: spinlock to protect the filter update fifo
+ * @filter_update_fifo: fifo of the filters waiting to update the filter list
  */
 struct hisi_ptt {
 	struct hisi_ptt_trace_ctrl trace_ctrl;
+	struct notifier_block hisi_ptt_nb;
 	struct pmu hisi_ptt_pmu;
 	void __iomem *iobase;
 	struct pci_dev *pdev;
@@ -174,6 +202,17 @@ struct hisi_ptt {
 	struct list_head port_filters;
 	struct list_head req_filters;
 	u16 port_mask;
+
+	/*
+	 * We use a delayed work here to avoid indefinitely waiting for
+	 * the hisi_ptt->mutex which protecting the filter list. The
+	 * work will be delayed only if the mutex can not be held,
+	 * otherwise no delay will be applied.
+	 */
+	struct delayed_work work;
+	spinlock_t filter_update_lock;
+	DECLARE_KFIFO(filter_update_kfifo, struct hisi_ptt_filter_update_info,
+		      HISI_PTT_FILTER_UPDATE_FIFO_SIZE);
 };
 
 #define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu)
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:14 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:14 +0800
Subject: [PATCH v3 4/8] hisi_ptt: Add tune function support for HiSilicon PCIe
 Tune and Trace device
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-5-yangyicong@hisilicon.com>

Add tune function for the HiSilicon Tune and Trace device. The interface
of tune is exposed through sysfs attributes of PTT PMU device.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/hwtracing/ptt/hisi_ptt.c | 154 +++++++++++++++++++++++++++++++
 drivers/hwtracing/ptt/hisi_ptt.h |  19 ++++
 2 files changed, 173 insertions(+)

diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
index 2994354e690b..b11e702eb506 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.c
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
@@ -21,6 +21,159 @@
 
 #include "hisi_ptt.h"
 
+static int hisi_ptt_wait_tuning_finish(struct hisi_ptt *hisi_ptt)
+{
+	u32 val;
+
+	return readl_poll_timeout(hisi_ptt->iobase + HISI_PTT_TUNING_INT_STAT,
+				  val, !(val & HISI_PTT_TUNING_INT_STAT_MASK),
+				  HISI_PTT_WAIT_POLL_INTERVAL_US,
+				  HISI_PTT_WAIT_TIMEOUT_US);
+}
+
+static int hisi_ptt_tune_data_get(struct hisi_ptt *hisi_ptt,
+				  u32 event, u16 *data)
+{
+	u32 reg;
+
+	reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
+	reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB);
+	reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB,
+			  event);
+	writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
+
+	/* Write all 1 to indicates it's the read process */
+	writel(~0UL, hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
+
+	if (hisi_ptt_wait_tuning_finish(hisi_ptt))
+		return -ETIMEDOUT;
+
+	reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
+	reg &= HISI_PTT_TUNING_DATA_VAL_MASK;
+	*data = (u16)reg;
+
+	return 0;
+}
+
+static int hisi_ptt_tune_data_set(struct hisi_ptt *hisi_ptt,
+				  u32 event, u16 data)
+{
+	u32 reg;
+
+	reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
+	reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB);
+	reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB,
+			  event);
+	writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
+
+	reg = data;
+	writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
+
+	if (hisi_ptt_wait_tuning_finish(hisi_ptt))
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static ssize_t hisi_ptt_tune_attr_show(struct device *dev,
+				       struct device_attribute *attr,
+				       char *buf)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
+	struct dev_ext_attribute *ext_attr;
+	struct hisi_ptt_tune_desc *desc;
+	int ret;
+	u16 val;
+
+	ext_attr = container_of(attr, struct dev_ext_attribute, attr);
+	desc = ext_attr->var;
+
+	if (!mutex_trylock(&hisi_ptt->mutex))
+		return -EBUSY;
+
+	ret = hisi_ptt_tune_data_get(hisi_ptt, desc->event_code, &val);
+
+	mutex_unlock(&hisi_ptt->mutex);
+	return ret ? ret : sysfs_emit(buf, "%u\n", val);
+}
+
+static ssize_t hisi_ptt_tune_attr_store(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
+	struct dev_ext_attribute *ext_attr;
+	struct hisi_ptt_tune_desc *desc;
+	int ret;
+	u16 val;
+
+	ext_attr = container_of(attr, struct dev_ext_attribute, attr);
+	desc = ext_attr->var;
+
+	if (kstrtou16(buf, 10, &val))
+		return -EINVAL;
+
+	if (!mutex_trylock(&hisi_ptt->mutex))
+		return -EBUSY;
+
+	ret = hisi_ptt_tune_data_set(hisi_ptt, desc->event_code, val);
+
+	mutex_unlock(&hisi_ptt->mutex);
+	return ret ? ret : count;
+}
+
+#define HISI_PTT_TUNE_ATTR(_name, _val, _show, _store)			\
+	static struct hisi_ptt_tune_desc _name##_desc = {		\
+		.name = #_name,						\
+		.event_code = _val,					\
+	};								\
+	static struct dev_ext_attribute hisi_ptt_##_name##_attr = {	\
+		.attr	= __ATTR(_name, 0600, _show, _store),		\
+		.var	= &_name##_desc,				\
+	}
+
+#define HISI_PTT_TUNE_ATTR_COMMON(_name, _val)		\
+	HISI_PTT_TUNE_ATTR(_name, _val,			\
+			   hisi_ptt_tune_attr_show,	\
+			   hisi_ptt_tune_attr_store)
+
+/*
+ * The value of the tuning event are composed of two parts: main event code in bit[0,15] and
+ * subevent code in bit[16,23]. For example, qox_tx_cpl is a subevent of 'Tx path QoS control'
+ * which for tuning the weight of Tx completion TLPs. See hisi_ptt.rst documentation for
+ * more information.
+ */
+#define HISI_PTT_TUNE_QOS_TX_CPL				(0x4 | (3 << 16))
+#define HISI_PTT_TUNE_QOS_TX_NP					(0x4 | (4 << 16))
+#define HISI_PTT_TUNE_QOS_TX_P					(0x4 | (5 << 16))
+#define HISI_PTT_TUNE_TX_PATH_IOB_RX_REQ_ALLOC_BUF_LEVEL	(0x5 | (6 << 16))
+#define HISI_PTT_TUNE_TX_PATH_TX_REQ_ALLOC_BUF_LEVEL		(0x5 | (7 << 16))
+
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_cpl,
+			  HISI_PTT_TUNE_QOS_TX_CPL);
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_np,
+			  HISI_PTT_TUNE_QOS_TX_NP);
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_p,
+			  HISI_PTT_TUNE_QOS_TX_P);
+HISI_PTT_TUNE_ATTR_COMMON(tx_path_iob_rx_req_alloc_buf_level,
+			  HISI_PTT_TUNE_TX_PATH_IOB_RX_REQ_ALLOC_BUF_LEVEL);
+HISI_PTT_TUNE_ATTR_COMMON(tx_path_tx_req_alloc_buf_level,
+			  HISI_PTT_TUNE_TX_PATH_TX_REQ_ALLOC_BUF_LEVEL);
+
+static struct attribute *hisi_ptt_tune_attrs[] = {
+	&hisi_ptt_qos_tx_cpl_attr.attr.attr,
+	&hisi_ptt_qos_tx_np_attr.attr.attr,
+	&hisi_ptt_qos_tx_p_attr.attr.attr,
+	&hisi_ptt_tx_path_iob_rx_req_alloc_buf_level_attr.attr.attr,
+	&hisi_ptt_tx_path_tx_req_alloc_buf_level_attr.attr.attr,
+	NULL,
+};
+
+static struct attribute_group hisi_ptt_tune_group = {
+	.attrs	= hisi_ptt_tune_attrs,
+	.name	= "tune",
+};
+
 static u16 hisi_ptt_get_filter_val(struct pci_dev *pdev)
 {
 	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
@@ -516,6 +669,7 @@ static struct attribute_group hisi_ptt_pmu_filter_group = {
 static const struct attribute_group *hisi_ptt_pmu_groups[] = {
 	&hisi_ptt_pmu_format_group,
 	&hisi_ptt_pmu_filter_group,
+	&hisi_ptt_tune_group,
 	NULL
 };
 
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
index 151e9e544653..c350f6d91c69 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.h
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
@@ -23,6 +23,11 @@
 /*
  * The definition of the device registers and register fields.
  */
+#define HISI_PTT_TUNING_CTRL		0x0000
+#define   HISI_PTT_TUNING_CTRL_CODE	GENMASK(15, 0)
+#define   HISI_PTT_TUNING_CTRL_SUB	GENMASK(23, 16)
+#define HISI_PTT_TUNING_DATA		0x0004
+#define   HISI_PTT_TUNING_DATA_VAL_MASK	GENMASK(15, 0)
 #define HISI_PTT_TRACE_ADDR_SIZE	0x0800
 #define HISI_PTT_TRACE_ADDR_BASE_LO_0	0x0810
 #define HISI_PTT_TRACE_ADDR_BASE_HI_0	0x0814
@@ -38,6 +43,8 @@
 #define HISI_PTT_TRACE_INT_STAT		0x0890
 #define   HISI_PTT_TRACE_INT_STAT_MASK	GENMASK(3, 0)
 #define HISI_PTT_TRACE_INT_MASK		0x0894
+#define HISI_PTT_TUNING_INT_STAT	0x0898
+#define   HISI_PTT_TUNING_INT_STAT_MASK	BIT(0)
 #define HISI_PTT_TRACE_WR_STS		0x08a0
 #define   HISI_PTT_TRACE_WR_STS_WRITE	GENMASK(27, 0)
 #define   HISI_PTT_TRACE_WR_STS_BUFFER	GENMASK(29, 28)
@@ -71,6 +78,18 @@ enum hisi_ptt_trace_status {
 	HISI_PTT_TRACE_STATUS_ON,
 };
 
+/**
+ * struct hisi_ptt_tune_desc - describe tune event for PTT tune
+ * @hisi_ptt:   PTT device this tune event belongs to
+ * @name:       name of this event
+ * @event_code: code of the event
+ */
+struct hisi_ptt_tune_desc {
+	struct hisi_ptt *hisi_ptt;
+	const char *name;
+	u32 event_code;
+};
+
 /**
  * struct hisi_ptt_dma_buffer - describe a single trace buffer of PTT trace.
  *                              The detail of the data format is described
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:11 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:11 +0800
Subject: [PATCH v3 1/8] hwtracing: Add trace function support for HiSilicon
 PCIe Tune and Trace device
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-2-yangyicong@hisilicon.com>

HiSilicon PCIe tune and trace device(PTT) is a PCIe Root Complex
integrated Endpoint(RCiEP) device, providing the capability
to dynamically monitor and tune the PCIe traffic, and trace
the TLP headers.

Add the driver for the device to enable the trace function.
This patch adds basic function of trace, including the device's
probe and initialization, functions for trace buffer allocation
and trace enable/disable, register an interrupt handler to
simply response to the DMA events. The user interface of trace
will be added in the following patch.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/Makefile                 |   1 +
 drivers/hwtracing/Kconfig        |   2 +
 drivers/hwtracing/ptt/Kconfig    |  11 +
 drivers/hwtracing/ptt/Makefile   |   2 +
 drivers/hwtracing/ptt/hisi_ptt.c | 398 +++++++++++++++++++++++++++++++
 drivers/hwtracing/ptt/hisi_ptt.h | 159 ++++++++++++
 6 files changed, 573 insertions(+)
 create mode 100644 drivers/hwtracing/ptt/Kconfig
 create mode 100644 drivers/hwtracing/ptt/Makefile
 create mode 100644 drivers/hwtracing/ptt/hisi_ptt.c
 create mode 100644 drivers/hwtracing/ptt/hisi_ptt.h

diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..ab3411e4eba5 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -175,6 +175,7 @@ obj-$(CONFIG_USB4)		+= thunderbolt/
 obj-$(CONFIG_CORESIGHT)		+= hwtracing/coresight/
 obj-y				+= hwtracing/intel_th/
 obj-$(CONFIG_STM)		+= hwtracing/stm/
+obj-$(CONFIG_HISI_PTT)		+= hwtracing/ptt/
 obj-$(CONFIG_ANDROID)		+= android/
 obj-$(CONFIG_NVMEM)		+= nvmem/
 obj-$(CONFIG_FPGA)		+= fpga/
diff --git a/drivers/hwtracing/Kconfig b/drivers/hwtracing/Kconfig
index 13085835a636..911ee977103c 100644
--- a/drivers/hwtracing/Kconfig
+++ b/drivers/hwtracing/Kconfig
@@ -5,4 +5,6 @@ source "drivers/hwtracing/stm/Kconfig"
 
 source "drivers/hwtracing/intel_th/Kconfig"
 
+source "drivers/hwtracing/ptt/Kconfig"
+
 endmenu
diff --git a/drivers/hwtracing/ptt/Kconfig b/drivers/hwtracing/ptt/Kconfig
new file mode 100644
index 000000000000..4f4f2459ac47
--- /dev/null
+++ b/drivers/hwtracing/ptt/Kconfig
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config HISI_PTT
+	tristate "HiSilicon PCIe Tune and Trace Device"
+	depends on ARM64 && PCI && HAS_DMA && HAS_IOMEM
+	help
+	  HiSilicon PCIe Tune and Trace Device exist as a PCIe RCiEP
+	  device, provides support for PCIe traffic tuning and
+	  tracing TLP headers to the memory.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called hisi_ptt.
diff --git a/drivers/hwtracing/ptt/Makefile b/drivers/hwtracing/ptt/Makefile
new file mode 100644
index 000000000000..908c09a98161
--- /dev/null
+++ b/drivers/hwtracing/ptt/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_HISI_PTT) += hisi_ptt.o
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
new file mode 100644
index 000000000000..6d0a0ca5c0a9
--- /dev/null
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
@@ -0,0 +1,398 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for HiSilicon PCIe tune and trace device
+ *
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ * Author: Yicong Yang <yangyicong at hisilicon.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/dma-iommu.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iommu.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/sysfs.h>
+
+#include "hisi_ptt.h"
+
+static u16 hisi_ptt_get_filter_val(struct pci_dev *pdev)
+{
+	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
+		return BIT(HISI_PCIE_CORE_PORT_ID(PCI_SLOT(pdev->devfn)));
+
+	return PCI_DEVID(pdev->bus->number, pdev->devfn);
+}
+
+static int hisi_ptt_wait_trace_hw_idle(struct hisi_ptt *hisi_ptt)
+{
+	u32 val;
+
+	return readl_poll_timeout(hisi_ptt->iobase + HISI_PTT_TRACE_STS, val,
+				  val & HISI_PTT_TRACE_IDLE,
+				  HISI_PTT_WAIT_POLL_INTERVAL_US,
+				  HISI_PTT_WAIT_TIMEOUT_US);
+}
+
+static void hisi_ptt_free_trace_buf(struct hisi_ptt *hisi_ptt)
+{
+	struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
+	struct device *dev = &hisi_ptt->pdev->dev;
+	struct hisi_ptt_dma_buffer *buffer, *tbuffer;
+
+	list_for_each_entry_safe(buffer, tbuffer, &ctrl->trace_buf, list) {
+		list_del(&buffer->list);
+		dma_free_coherent(dev, buffer->size, buffer->addr,
+				  buffer->dma);
+		kfree(buffer);
+	}
+}
+
+static int hisi_ptt_alloc_trace_buf(struct hisi_ptt *hisi_ptt)
+{
+	struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
+	struct device *dev = &hisi_ptt->pdev->dev;
+	struct hisi_ptt_dma_buffer *buffer;
+	int i, ret;
+
+	hisi_ptt->trace_ctrl.buf_index = 0;
+
+	/* Make sure the trace buffer is empty before allocating */
+	if (!list_empty(&ctrl->trace_buf)) {
+		list_for_each_entry(buffer, &ctrl->trace_buf, list)
+			memset(buffer->addr, 0, buffer->size);
+		return 0;
+	}
+
+	for (i = 0; i < HISI_PTT_TRACE_BUF_CNT; ++i) {
+		buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+		if (!buffer) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		buffer->addr = dma_alloc_coherent(dev, ctrl->buffer_size,
+						  &buffer->dma, GFP_KERNEL);
+		if (!buffer->addr) {
+			kfree(buffer);
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		memset(buffer->addr, 0, buffer->size);
+
+		buffer->index = i;
+		buffer->size = ctrl->buffer_size;
+		list_add_tail(&buffer->list, &ctrl->trace_buf);
+	}
+
+	return 0;
+err:
+	hisi_ptt_free_trace_buf(hisi_ptt);
+	return ret;
+}
+
+static void hisi_ptt_trace_end(struct hisi_ptt *hisi_ptt)
+{
+	writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+	hisi_ptt->trace_ctrl.status = HISI_PTT_TRACE_STATUS_OFF;
+}
+
+static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
+{
+	struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
+	struct hisi_ptt_dma_buffer *cur;
+	u32 val;
+
+	/* Check device idle before start trace */
+	if (hisi_ptt_wait_trace_hw_idle(hisi_ptt)) {
+		pci_err(hisi_ptt->pdev, "Failed to start trace, the device is still busy.\n");
+		return -EBUSY;
+	}
+
+	/* Reset the DMA before start tracing */
+	val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+	val |= HISI_PTT_TRACE_CTRL_RST;
+	writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+
+	/*
+	 * We'll be in the perf context where preemption is disabled,
+	 * so use busy loop here.
+	 */
+	mdelay(HISI_PTT_RESET_WAIT_MS);
+
+	val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+	val &= ~HISI_PTT_TRACE_CTRL_RST;
+	writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+
+	/* Clear the interrupt status */
+	writel(HISI_PTT_TRACE_INT_STAT_MASK, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
+	writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_INT_MASK);
+
+	/* Configure the trace DMA buffer */
+	list_for_each_entry(cur, &ctrl->trace_buf, list) {
+		writel(lower_32_bits(cur->dma),
+		       hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_BASE_LO_0 +
+		       cur->index * HISI_PTT_TRACE_ADDR_STRIDE);
+		writel(upper_32_bits(cur->dma),
+		       hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_BASE_HI_0 +
+		       cur->index * HISI_PTT_TRACE_ADDR_STRIDE);
+	}
+	writel(ctrl->buffer_size, hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_SIZE);
+
+	/* Set the trace control register */
+	val = FIELD_PREP(HISI_PTT_TRACE_CTRL_TYPE_SEL, ctrl->type);
+	val |= FIELD_PREP(HISI_PTT_TRACE_CTRL_RXTX_SEL, ctrl->direction);
+	val |= FIELD_PREP(HISI_PTT_TRACE_CTRL_DATA_FORMAT, ctrl->format);
+	val |= FIELD_PREP(HISI_PTT_TRACE_CTRL_TARGET_SEL, hisi_ptt->trace_ctrl.filter);
+	if (!hisi_ptt->trace_ctrl.is_port)
+		val |= HISI_PTT_TRACE_CTRL_FILTER_MODE;
+
+	/* Start the Trace */
+	val |= HISI_PTT_TRACE_CTRL_EN;
+	writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
+
+	ctrl->status = HISI_PTT_TRACE_STATUS_ON;
+
+	return 0;
+}
+
+static irqreturn_t hisi_ptt_isr(int irq, void *context)
+{
+	struct hisi_ptt *hisi_ptt = context;
+	u32 status;
+
+	status = readl(hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
+
+	/* Clear the interrupt status of buffer @buf_idx */
+	writel(status, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t hisi_ptt_irq(int irq, void *context)
+{
+	struct hisi_ptt *hisi_ptt = context;
+	u32 status;
+
+	status = readl(hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
+	if (!(status & HISI_PTT_TRACE_INT_STAT_MASK))
+		return IRQ_NONE;
+
+	return IRQ_WAKE_THREAD;
+}
+
+static void hisi_ptt_irq_free_vectors(void *pdev)
+{
+	pci_free_irq_vectors(pdev);
+}
+
+static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
+{
+	struct pci_dev *pdev = hisi_ptt->pdev;
+	int ret;
+
+	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+	if (ret < 0) {
+		pci_err(pdev, "failed to allocate irq vector, ret = %d.\n", ret);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&pdev->dev, hisi_ptt_irq_free_vectors, pdev);
+	if (ret < 0)
+		return ret;
+
+	ret = devm_request_threaded_irq(&pdev->dev,
+					pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ),
+					hisi_ptt_irq, hisi_ptt_isr, 0,
+					"hisi-ptt", hisi_ptt);
+	if (ret) {
+		pci_err(pdev, "failed to request irq %d, ret = %d.\n",
+			pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ), ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
+{
+	struct hisi_ptt_filter_desc *filter;
+	struct hisi_ptt *hisi_ptt = data;
+	struct list_head *target_list;
+
+	target_list = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ?
+		      &hisi_ptt->port_filters : &hisi_ptt->req_filters;
+
+	filter = kzalloc(sizeof(*filter), GFP_KERNEL);
+	if (!filter)
+		return -ENOMEM;
+
+	filter->pdev = pdev;
+	filter->val = hisi_ptt_get_filter_val(pdev);
+	list_add_tail(&filter->list, target_list);
+
+	/* Update the available port mask */
+	if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
+		hisi_ptt->port_mask |= filter->val;
+
+	return 0;
+}
+
+static void hisi_ptt_release_filters(struct hisi_ptt *hisi_ptt)
+{
+	struct hisi_ptt_filter_desc *filter, *tfilter;
+
+	list_for_each_entry_safe(filter, tfilter, &hisi_ptt->req_filters, list) {
+		list_del(&filter->list);
+		kfree(filter);
+	}
+
+	list_for_each_entry_safe(filter, tfilter, &hisi_ptt->port_filters, list) {
+		list_del(&filter->list);
+		kfree(filter);
+	}
+}
+
+static void hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
+{
+	struct pci_dev *pdev = hisi_ptt->pdev;
+	struct pci_bus *bus;
+	u32 reg;
+
+	INIT_LIST_HEAD(&hisi_ptt->port_filters);
+	INIT_LIST_HEAD(&hisi_ptt->req_filters);
+
+	/*
+	 * The device range register provides the information about the
+	 * root ports which the RCiEP can control and trace. The RCiEP
+	 * and the root ports it support are on the same PCIe core, with
+	 * same domain number but maybe different bus number. The device
+	 * range register will tell us which root ports we can support,
+	 * Bit[31:16] indicates the upper BDF numbers of the root port,
+	 * while Bit[15:0] indicates the lower.
+	 */
+	reg = readl(hisi_ptt->iobase + HISI_PTT_DEVICE_RANGE);
+	hisi_ptt->upper = reg >> 16;
+	hisi_ptt->lower = reg & 0xffff;
+
+	reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION);
+	hisi_ptt->core_id = FIELD_GET(HISI_PTT_CORE_ID, reg);
+	hisi_ptt->sicl_id = FIELD_GET(HISI_PTT_SICL_ID, reg);
+
+	bus = pci_find_bus(pci_domain_nr(pdev->bus), PCI_BUS_NUM(hisi_ptt->upper));
+	if (bus)
+		pci_walk_bus(bus, hisi_ptt_init_filters, hisi_ptt);
+
+	/* Initialize trace controls */
+	INIT_LIST_HEAD(&hisi_ptt->trace_ctrl.trace_buf);
+	hisi_ptt->trace_ctrl.buffer_size = HISI_PTT_TRACE_BUF_SIZE;
+	hisi_ptt->trace_ctrl.default_cpu = cpumask_first(cpumask_of_node(dev_to_node(&pdev->dev)));
+}
+
+/*
+ * The DMA of PTT trace can only use direct mapping, due to some
+ * hardware restriction. Check whether there is an iommu or the
+ * policy of the iommu domain is passthrough, otherwise the trace
+ * cannot work.
+ */
+static int hisi_ptt_check_iommu_mapping(struct hisi_ptt *hisi_ptt)
+{
+	struct pci_dev *pdev = hisi_ptt->pdev;
+	struct iommu_domain *iommu_domain;
+
+	iommu_domain = iommu_get_domain_for_dev(&pdev->dev);
+	if (!iommu_domain || iommu_domain->type == IOMMU_DOMAIN_IDENTITY)
+		return 0;
+
+	return -EOPNOTSUPP;
+}
+
+static int hisi_ptt_probe(struct pci_dev *pdev,
+			  const struct pci_device_id *id)
+{
+	struct hisi_ptt *hisi_ptt;
+	int ret;
+
+	hisi_ptt = devm_kzalloc(&pdev->dev, sizeof(*hisi_ptt), GFP_KERNEL);
+	if (!hisi_ptt)
+		return -ENOMEM;
+
+	mutex_init(&hisi_ptt->mutex);
+	hisi_ptt->pdev = pdev;
+
+	/*
+	 * Lifetime of pci_dev is longer than hisi_ptt,
+	 * so directly reference to the pci name string.
+	 */
+	hisi_ptt->name = pci_name(hisi_ptt->pdev);
+	pci_set_drvdata(pdev, hisi_ptt);
+
+	ret = pcim_enable_device(pdev);
+	if (ret) {
+		pci_err(pdev, "failed to enable device, ret = %d.\n", ret);
+		return ret;
+	}
+
+	ret = pcim_iomap_regions(pdev, BIT(2), hisi_ptt->name);
+	if (ret) {
+		pci_err(pdev, "failed to remap io memory, ret = %d.\n", ret);
+		return ret;
+	}
+
+	hisi_ptt->iobase = pcim_iomap_table(pdev)[2];
+
+	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret) {
+		pci_err(pdev, "failed to set 64 bit dma mask, ret = %d.\n", ret);
+		return ret;
+	}
+	pci_set_master(pdev);
+
+	ret = hisi_ptt_register_irq(hisi_ptt);
+	if (ret)
+		return ret;
+
+	hisi_ptt_init_ctrls(hisi_ptt);
+
+	ret = hisi_ptt_check_iommu_mapping(hisi_ptt);
+	if (ret) {
+		pci_err(pdev, "cannot work with non-direct DMA mapping.\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+void hisi_ptt_remove(struct pci_dev *pdev)
+{
+	struct hisi_ptt *hisi_ptt = pci_get_drvdata(pdev);
+
+	if (hisi_ptt->trace_ctrl.status == HISI_PTT_TRACE_STATUS_ON)
+		hisi_ptt_trace_end(hisi_ptt);
+
+	hisi_ptt_free_trace_buf(hisi_ptt);
+	hisi_ptt_release_filters(hisi_ptt);
+}
+
+static const struct pci_device_id hisi_ptt_id_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_HUAWEI, 0xa12e) },
+	{ }
+};
+MODULE_DEVICE_TABLE(pci, hisi_ptt_id_tbl);
+
+static struct pci_driver hisi_ptt_driver = {
+	.name = "hisi_ptt",
+	.id_table = hisi_ptt_id_tbl,
+	.probe = hisi_ptt_probe,
+	.remove = hisi_ptt_remove,
+};
+module_pci_driver(hisi_ptt_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Yicong Yang <yangyicong at hisilicon.com>");
+MODULE_DESCRIPTION("Driver for HiSilicon PCIe tune and trace device");
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
new file mode 100644
index 000000000000..8aa5d6b78cc5
--- /dev/null
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Driver for HiSilicon PCIe tune and trace device
+ *
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ * Author: Yicong Yang <yangyicong at hisilicon.com>
+ */
+
+#ifndef _HISI_PTT_H
+#define _HISI_PTT_H
+
+#include <linux/bits.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+
+/*
+ * The definition of the device registers and register fields.
+ */
+#define HISI_PTT_TRACE_ADDR_SIZE	0x0800
+#define HISI_PTT_TRACE_ADDR_BASE_LO_0	0x0810
+#define HISI_PTT_TRACE_ADDR_BASE_HI_0	0x0814
+#define HISI_PTT_TRACE_ADDR_STRIDE	0x8
+#define HISI_PTT_TRACE_CTRL		0x0850
+#define   HISI_PTT_TRACE_CTRL_EN	BIT(0)
+#define   HISI_PTT_TRACE_CTRL_RST	BIT(1)
+#define   HISI_PTT_TRACE_CTRL_RXTX_SEL	GENMASK(3, 2)
+#define   HISI_PTT_TRACE_CTRL_TYPE_SEL	GENMASK(7, 4)
+#define   HISI_PTT_TRACE_CTRL_DATA_FORMAT	BIT(14)
+#define   HISI_PTT_TRACE_CTRL_FILTER_MODE	BIT(15)
+#define   HISI_PTT_TRACE_CTRL_TARGET_SEL	GENMASK(31, 16)
+#define HISI_PTT_TRACE_INT_STAT		0x0890
+#define   HISI_PTT_TRACE_INT_STAT_MASK	GENMASK(3, 0)
+#define HISI_PTT_TRACE_INT_MASK		0x0894
+#define HISI_PTT_TRACE_WR_STS		0x08a0
+#define   HISI_PTT_TRACE_WR_STS_WRITE	GENMASK(27, 0)
+#define   HISI_PTT_TRACE_WR_STS_BUFFER	GENMASK(29, 28)
+#define HISI_PTT_TRACE_STS		0x08b0
+#define   HISI_PTT_TRACE_IDLE		BIT(0)
+#define HISI_PTT_DEVICE_RANGE		0x0fe0
+#define HISI_PTT_LOCATION		0x0fe8
+#define   HISI_PTT_CORE_ID		GENMASK(15, 0)
+#define   HISI_PTT_SICL_ID		GENMASK(31, 16)
+
+/* Parameters of PTT trace DMA part. */
+#define HISI_PTT_TRACE_DMA_IRQ			0
+#define HISI_PTT_TRACE_BUF_CNT			4
+#define HISI_PTT_TRACE_BUF_SIZE			SZ_4M
+#define HISI_PTT_TRACE_TOTAL_BUF_SIZE		(HISI_PTT_TRACE_BUF_SIZE * \
+						 HISI_PTT_TRACE_BUF_CNT)
+/* Wait time for DMA hardware to reset */
+#define HISI_PTT_RESET_WAIT_MS		1000UL
+/* Poll timeout and interval for waiting hardware work to finish */
+#define HISI_PTT_WAIT_TIMEOUT_US	1000000UL
+#define HISI_PTT_WAIT_POLL_INTERVAL_US	100UL
+
+#define HISI_PCIE_CORE_PORT_ID(devfn)	(PCI_FUNC(devfn) << 1)
+
+enum hisi_ptt_trace_status {
+	HISI_PTT_TRACE_STATUS_OFF = 0,
+	HISI_PTT_TRACE_STATUS_ON,
+};
+
+/**
+ * struct hisi_ptt_dma_buffer - describe a single trace buffer of PTT trace.
+ *                              The detail of the data format is described
+ *                              in the documentation of PTT device.
+ * @list:  entry of this buffer in the buffer list
+ * @size:  size of this buffer
+ * @dma:   DMA address of this buffer visible to the device
+ * @addr:  virtual address of this buffer visible to the cpu
+ * @index: index of this buffer in the buffer list
+ */
+struct hisi_ptt_dma_buffer {
+	struct list_head list;
+	unsigned int size;
+	dma_addr_t dma;
+	void *addr;
+	int index;
+};
+
+/**
+ * struct hisi_ptt_trace_ctrl - control and status of PTT trace
+ * @status:      current trace status
+ * @trace_buf:   the trace buffers for holding the trace data
+ * @default_cpu: default cpu to start the trace session
+ * @buffer_size: the size of each trace buffer in the list
+ * @buf_index:   the index of current using trace buffer
+ * @is_port:     whether we're tracing root port or not
+ * @direction:   direction of the TLP headers to trace
+ * @filter:      filter value for tracing the TLP headers
+ * @format:      format of the TLP headers to trace
+ * @type:        type of the TLP headers to trace
+ */
+struct hisi_ptt_trace_ctrl {
+	enum hisi_ptt_trace_status status;
+	struct list_head trace_buf;
+	int default_cpu;
+	u32 buffer_size;
+	u32 buf_index;
+	bool is_port;
+	u32 direction:2;
+	u32 filter:16;
+	u32 format:1;
+	u32 type:4;
+};
+
+/**
+ * struct hisi_ptt_filter_desc - descriptor of the PTT trace filter
+ * @list: entry of this descriptor in the filter list
+ * @pdev: pci_dev related to this filter
+ * @val:  filter value for the device
+ */
+struct hisi_ptt_filter_desc {
+	struct list_head list;
+	struct pci_dev *pdev;
+	u16 val;
+};
+
+/**
+ * struct hisi_ptt - per PTT device data
+ * @trace_ctrl:   the control information of PTT trace
+ * @iobase:       base IO address of the device
+ * @pdev:         pci_dev of this PTT device
+ * @mutex:        mutex to protect the filter list and serialize the perf process.
+ * @name:         name of the PTT device
+ * @core_id:      PCIe core ID this PTT device locates
+ * @sicl_id:      SICL ID this PTT device locates
+ * @upper:        the upper BDF range of the PCI devices managed by this PTT device
+ * @lower:        the lower BDF range of the PCI devices managed by this PTT device
+ * @port_filters: the filter list of root ports
+ * @req_filters:  the filter list of requester ID
+ * @port_mask:    port mask of the managed root ports
+ */
+struct hisi_ptt {
+	struct hisi_ptt_trace_ctrl trace_ctrl;
+	void __iomem *iobase;
+	struct pci_dev *pdev;
+	struct mutex mutex;
+	const char *name;
+	u16 core_id;
+	u16 sicl_id;
+	u32 upper;
+	u32 lower;
+
+	/*
+	 * The trace TLP headers can either be filtered by certain
+	 * root port, or by the requester ID. Organize the filters
+	 * by @port_filters and @req_filters here. The mask of all
+	 * the valid ports is also cached for doing sanity check
+	 * of user input.
+	 */
+	struct list_head port_filters;
+	struct list_head req_filters;
+	u16 port_mask;
+};
+
+#endif /* _HISI_PTT_H */
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:16 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:16 +0800
Subject: [PATCH v3 6/8] docs: Add HiSilicon PTT device driver documentation
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-7-yangyicong@hisilicon.com>

Document the introduction and usage of HiSilicon PTT device driver.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 Documentation/trace/hisi-ptt.rst | 304 +++++++++++++++++++++++++++++++
 1 file changed, 304 insertions(+)
 create mode 100644 Documentation/trace/hisi-ptt.rst

diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
new file mode 100644
index 000000000000..f3269b11a2f6
--- /dev/null
+++ b/Documentation/trace/hisi-ptt.rst
@@ -0,0 +1,304 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+======================================
+HiSilicon PCIe Tune and Trace device
+======================================
+
+Introduction
+============
+
+HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
+integrated Endpoint (RCiEP) device, providing the capability
+to dynamically monitor and tune the PCIe link's events (tune),
+and trace the TLP headers (trace). The two functions are independent,
+but is recommended to use them together to analyze and enhance the
+PCIe link's performance.
+
+On Kunpeng 930 SoC, the PCIe Root Complex is composed of several
+PCIe cores. Each PCIe core includes several Root Ports and a PTT
+RCiEP, like below. The PTT device is capable of tuning and
+tracing the link of the PCIe core.
+::
+          +--------------Core 0-------+
+          |       |       [   PTT   ] |
+          |       |       [Root Port]---[Endpoint]
+          |       |       [Root Port]---[Endpoint]
+          |       |       [Root Port]---[Endpoint]
+    Root Complex  |------Core 1-------+
+          |       |       [   PTT   ] |
+          |       |       [Root Port]---[ Switch ]---[Endpoint]
+          |       |       [Root Port]---[Endpoint] `-[Endpoint]
+          |       |       [Root Port]---[Endpoint]
+          +---------------------------+
+
+The PTT device driver registers PMU device for each PTT device.
+The name of each PTT device is composed of 'hisi_ptt' prefix with
+the id of the SICL and the Core where it locates. The Kunpeng 930
+SoC encapsulates multiple CPU dies (SCCL, Super CPU Cluster) and
+IO dies (SICL, Super I/O Cluster), where there's one PCIe Root
+Complex for each SICL.
+::
+    /sys/devices/hisi_ptt<sicl_id>_<core_id>
+
+Tune
+====
+
+PTT tune is designed for monitoring and adjusting PCIe link parameters (events).
+Currently we support events in 4 classes. The scope of the events
+covers the PCIe core to which the PTT device belongs.
+
+Each event is presented as a file under $(PTT PMU dir)/tune, and
+mostly a simple open/read/write/close cycle will be used to tune
+the event.
+::
+    $ cd /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune
+    $ ls
+    qos_tx_cpl    qos_tx_np    qos_tx_p
+    tx_path_rx_req_alloc_buf_level
+    tx_path_tx_req_alloc_buf_level
+    $ cat qos_tx_dp
+    1
+    $ echo 2 > qos_tx_dp
+    $ cat qos_tx_dp
+    2
+
+Current value (numerical value) of the event can be simply read
+from the file, and the desired value written to the file to tune.
+
+1. Tx path QoS control
+------------------------
+
+The following files are provided to tune the QoS of the tx path of
+the PCIe core.
+
+- qos_tx_cpl: weight of Tx completion TLPs
+- qos_tx_np: weight of Tx non-posted TLPs
+- qos_tx_p: weight of Tx posted TLPs
+
+The weight influences the proportion of certain packets on the PCIe link.
+For example, for the storage scenario, increase the proportion
+of the completion packets on the link to enhance the performance as
+more completions are consumed.
+
+The available tune data of these events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+2. Tx path buffer control
+-------------------------
+
+Following files are provided to tune the buffer of tx path of the PCIe core.
+
+- tx_path_rx_req_alloc_buf_level: watermark of Rx requested
+- tx_path_tx_req_alloc_buf_level: watermark of Tx requested
+
+These events influence the watermark of the buffer allocated for each
+type. Rx means the inbound while Tx means outbound. The packets will
+be stored in the buffer first and then posted either when the watermark
+reached or when timed out. For a busy direction, you should increase
+the related buffer watermark to avoid frequently posting and thus
+enhance the performance. In most cases just keep the default value.
+
+The available tune data of above events is [0, 1, 2].
+Writing a negative value will return an error, and out of range
+values will be converted to 2. Note that the event value just
+indicates a probable level, but is not precise.
+
+Trace
+=====
+
+PTT trace is designed for dumping the TLP headers to the memory, which
+can be used to analyze the transactions and usage condition of the PCIe
+Link. You can choose to filter the traced headers by either requester ID,
+or those downstream of a set of Root Ports on the same core of the PTT
+device. It's also supported to trace the headers of certain type and of
+certain direction.
+
+You can use the perf command `perf record` to set the parameters, start
+trace and get the data. It's also supported to decode the trace
+data with `perf report`. The control parameters for trace is inputted
+as event code for each events, which will be further illustracted later.
+An example usage is like
+::
+    $ perf record -e hisi_ptt0_2/filter=0x80001,type=1,direction=1,
+      format=1/ -- sleep 5
+
+This will trace the TLP headers downstream root port 0000:00:10.1 (event
+code for event 'filter' is 0x80001) with type of posted TLP requests,
+direction of inbound and traced data format of 8DW.
+
+1. filter
+---------
+
+The TLP headers to trace can be filtered by the Root Ports or the requester
+ID of the endpoints, which are locates on the same core of the PTT device.
+You can set the filter by spedifying the `filter` parameter which is required
+to start the trace. The parameter value is 20 bit. The supported filters and
+related values is outputted through `available_filters` sysfs attribute
+under related PTT PMU directory, classified as Root Ports and Requesters
+respectively.
+::
+    $ cat available_filters
+    #### Root Ports ####
+    0000:00:10.0	0x80001
+    0000:00:11.0	0x80004
+    #### Requesters ####
+    0000:01:00.0	0x00100
+    0000:01:00.1	0x00101
+
+Note that multiple Root Ports can be specified at one time, but only
+one Endpoint function can be specified in one trace. Specifying both
+Root Port and function at the same time is not supported.
+
+If no filter is available, reading the available_filters will get the hint.
+::
+    $ cat available_filters
+    #### No available filter ####
+
+The available_filters can be dynamically updated, which means you can always
+get correct filter information when hotplug events happen, or when you manually
+remove/rescan the devices.
+
+2. type
+-------
+
+You can trace the TLP headers of certain types by specifying the `type`
+parameter, which is required to start the trace. The parameter value is
+8 bit. Current supported types and related values are shown below:
+
+8'b00000001: posted requests (P)
+8'b00000010: non-posted requests (NP)
+8'b00000100: completions (CPL)
+
+You can specify multiple types when tracing inbound TLP headers, but can only
+specify one when tracing outbound TLP headers.
+
+3. direction
+------------
+
+You can trace the TLP headers from certain direction, which is relative
+to the Root Port or the PCIe core, by specifying the `direction` parameter.
+This is optional and the default parameter is inbound. The parameter value
+is 4 bit. When the desired format is 4DW, directions and related values
+supported are shown below:
+
+4'b0000: inbound TLPs (P, NP, CPL)
+4'b0001: outbound TLPs (P, NP, CPL)
+4'b0010: outbound TLPs (P, NP, CPL) and inbound TLPs (P, NP, CPL B)
+4'b0011: outbound TLPs (P, NP, CPL) and inbound TLPs (CPL A)
+
+When the desired format is 8DW, directions and related values supported are
+shown below:
+
+4'b0000: reserved
+4'b0001: outbound TLPs (P, NP, CPL)
+4'b0010: inbound TLPs (P, NP, CPL B)
+4'b0011: inbound TLPs (CPL A)
+
+Inbound completions are classifed into two types:
+
+completion A (CPL A): completion of CHI/DMA/Native non-posted requests, except for CPL B
+completion B (CPL B): completion of DMA remote2local and P2P non-posted requests
+
+4. format
+--------------
+
+You can change the format of the traced TLP headers by specifying the
+`format` parameter. This is optional and the default format is 4DW.
+The parameter value is 4 bit. Current supported formats and related
+values are shown below:
+
+4'b0000: 4DW length per TLP header
+4'b0001: 8DW length per TLP header
+
+The traced TLP header format is different from the PCIe standard.
+
+When using the 8DW data format, the entire TLP header is logged
+(Header DW0-3 shown below). For example, the TLP header for Memory
+Reads with 64-bit addresses is shown in PCIe r5.0, Figure 2-17;
+the header for Configuration Requests is shown in Figure 2.20, etc.
+
+In addition, 8DW trace buffer entries contain a timestamp and
+possibly a prefix for a PASID TLP prefix (see Figure 6-20, PCIe r5.0).
+Otherwise this field will be all 0.
+
+The bit[31:11] of DW0 is always 0x1fffff, which can be
+used to distinguish the data format. 8DW format is like
+::
+    bits [                 31:11                 ][       10:0       ]
+         |---------------------------------------|-------------------|
+     DW0 [                0x1fffff               ][ Reserved (0x7ff) ]
+     DW1 [                       Prefix                              ]
+     DW2 [                     Header DW0                            ]
+     DW3 [                     Header DW1                            ]
+     DW4 [                     Header DW2                            ]
+     DW5 [                     Header DW3                            ]
+     DW6 [                   Reserved (0x0)                          ]
+     DW7 [                        Time                               ]
+
+When using the 4DW data format, DW0 of the trace buffer entry
+contains selected fields of DW0 of the TLP, together with a
+timestamp.  DW1-DW3 of the trace buffer entry contain DW1-DW3
+directly from the TLP header.
+
+4DW format is like
+::
+    bits [31:30] [ 29:25 ][24][23][22][21][    20:11   ][    10:0    ]
+         |-----|---------|---|---|---|---|-------------|-------------|
+     DW0 [ Fmt ][  Type  ][T9][T8][TH][SO][   Length   ][    Time    ]
+     DW1 [                     Header DW1                            ]
+     DW2 [                     Header DW2                            ]
+     DW3 [                     Header DW3                            ]
+
+5. memory management
+--------------------
+
+The traced TLP headers will be written to the memory allocated
+by the driver. The hardware accepts 4 DMA address with same size,
+and writes the buffer sequentially like below. If DMA addr 3 is
+finished and the trace is still on, it will return to addr 0.
+::
+    +->[DMA addr 0]->[DMA addr 1]->[DMA addr 2]->[DMA addr 3]-+
+    +---------------------------------------------------------+
+
+Driver will allocate each DMA buffer of 4MiB. The finished buffer
+will be copied to the perf AUX buffer allocated by the perf core.
+Once the AUX buffer is full while the trace is still on, driver
+will commit the AUX buffer first and then apply for a new one with
+the same size. The size of AUX buffer is default to 16MiB. User can
+adjust the size by specifying the `-m` parameter of the perf command.
+
+Note that there is a gap between committing the old AUX buffer and
+applying a new one, which means the trace is stopped during the
+moment and TLPs transferred in the moment cannot be traced. To avoid
+this situation, you should begin the trace with large AUX buffer
+enough to avoid this gap.
+
+6. decoding
+-----------
+
+You can decode the traced data with `perf report -D` command (currently
+only support to dump the raw trace data). The traced data will be decoded
+according to the format described previously (take 8DW as an example):
+::
+    [...perf headers and other information]
+    . ... HISI PTT data: size 4194304 bytes
+    .  00000000: 00 00 00 00                                 Prefix
+    .  00000004: 01 00 00 60                                 Header DW0
+    .  00000008: 0f 1e 00 01                                 Header DW1
+    .  0000000c: 04 00 00 00                                 Header DW2
+    .  00000010: 40 00 81 02                                 Header DW3
+    .  00000014: 33 c0 04 00                                 Time
+    .  00000020: 00 00 00 00                                 Prefix
+    .  00000024: 01 00 00 60                                 Header DW0
+    .  00000028: 0f 1e 00 01                                 Header DW1
+    .  0000002c: 04 00 00 00                                 Header DW2
+    .  00000030: 40 00 81 02                                 Header DW3
+    .  00000034: 02 00 00 00                                 Time
+    .  00000040: 00 00 00 00                                 Prefix
+    .  00000044: 01 00 00 60                                 Header DW0
+    .  00000048: 0f 1e 00 01                                 Header DW1
+    .  0000004c: 04 00 00 00                                 Header DW2
+    .  00000050: 40 00 81 02                                 Header DW3
+    [...]
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:12 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:12 +0800
Subject: [PATCH v3 2/8] hisi_ptt: Register PMU device for PTT trace
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-3-yangyicong@hisilicon.com>

Register PMU device of PTT trace, then users can use
trace through perf command. The driver makes use of perf
AUX trace and support following events to configure the
trace:

- filter: select Root port or Endpoint to trace
- type: select the type of traced TLP headers
- direction: select the direction of traced TLP headers
- format: select the data format of the traced TLP headers

This patch adds the PMU driver part of PTT trace. The perf
command support of PTT trace is added in the following
patch.

Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 drivers/hwtracing/ptt/hisi_ptt.c | 459 ++++++++++++++++++++++++++++++-
 drivers/hwtracing/ptt/hisi_ptt.h |  22 ++
 2 files changed, 480 insertions(+), 1 deletion(-)

diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
index 6d0a0ca5c0a9..eeb8afc65a56 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.c
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
@@ -17,6 +17,7 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/sysfs.h>
+#include <linux/vmalloc.h>
 
 #include "hisi_ptt.h"
 
@@ -161,16 +162,67 @@ static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
 	return 0;
 }
 
+static int hisi_ptt_update_aux(struct hisi_ptt *hisi_ptt, int index, bool stop)
+{
+	struct perf_output_handle *handle = &hisi_ptt->trace_ctrl.handle;
+	struct perf_event *event = handle->event;
+	struct hisi_ptt_dma_buffer *cur;
+	struct hisi_ptt_pmu_buf *buf;
+
+	buf = perf_get_aux(handle);
+	if (!buf || !handle->size)
+		return -EINVAL;
+
+	list_for_each_entry(cur, &hisi_ptt->trace_ctrl.trace_buf, list)
+		if (cur->index == index)
+			break;
+
+	memcpy(buf->base + buf->pos, cur->addr, cur->size);
+	memset(cur->addr, 0, cur->size);
+	buf->pos += cur->size;
+
+	if (stop) {
+		perf_aux_output_end(handle, buf->pos);
+	} else if (buf->length - buf->pos < cur->size) {
+		perf_aux_output_skip(handle, buf->length - buf->pos);
+		perf_aux_output_end(handle, buf->pos);
+
+		buf = perf_aux_output_begin(handle, event);
+		if (!buf)
+			return -EINVAL;
+
+		buf->pos = handle->head % buf->length;
+		if (buf->length - buf->pos < cur->size) {
+			perf_aux_output_end(handle, 0);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static irqreturn_t hisi_ptt_isr(int irq, void *context)
 {
 	struct hisi_ptt *hisi_ptt = context;
-	u32 status;
+	u32 status, buf_idx;
 
 	status = readl(hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
+	buf_idx = ffs(status) - 1;
 
 	/* Clear the interrupt status of buffer @buf_idx */
 	writel(status, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
 
+	/*
+	 * Update the AUX buffer and cache the current buffer index,
+	 * as we need to know this and save the data when the trace
+	 * is ended out of the interrupt handler. End the trace
+	 * if the updating fails.
+	 */
+	if (hisi_ptt_update_aux(hisi_ptt, buf_idx, false))
+		hisi_ptt_trace_end(hisi_ptt);
+	else
+		hisi_ptt->trace_ctrl.buf_index = (buf_idx + 1) % HISI_PTT_TRACE_BUF_CNT;
+
 	return IRQ_HANDLED;
 }
 
@@ -294,6 +346,405 @@ static void hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
 	hisi_ptt->trace_ctrl.default_cpu = cpumask_first(cpumask_of_node(dev_to_node(&pdev->dev)));
 }
 
+#define HISI_PTT_PMU_FILTER_IS_PORT	BIT(19)
+#define HISI_PTT_PMU_FILTER_VAL_MASK	GENMASK(15, 0)
+#define HISI_PTT_PMU_DIRECTION_MASK	GENMASK(23, 20)
+#define HISI_PTT_PMU_TYPE_MASK		GENMASK(31, 24)
+#define HISI_PTT_PMU_FORMAT_MASK	GENMASK(35, 32)
+
+static ssize_t available_filters_show(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
+	struct hisi_ptt_filter_desc *filter;
+	int pos = 0;
+
+	if (list_empty(&hisi_ptt->port_filters))
+		return sysfs_emit(buf, "#### No available filter ####\n");
+
+	mutex_lock(&hisi_ptt->mutex);
+	pos += sysfs_emit_at(buf, pos, "#### Root Ports ####\n");
+	list_for_each_entry(filter, &hisi_ptt->port_filters, list)
+		pos += sysfs_emit_at(buf, pos, "%s	0x%05lx\n",
+				     pci_name(filter->pdev),
+				     hisi_ptt_get_filter_val(filter->pdev) |
+				     HISI_PTT_PMU_FILTER_IS_PORT);
+
+	pos += sysfs_emit_at(buf, pos, "#### Requesters ####\n");
+	list_for_each_entry(filter, &hisi_ptt->req_filters, list)
+		pos += sysfs_emit_at(buf, pos, "%s	0x%05x\n",
+				     pci_name(filter->pdev),
+				     hisi_ptt_get_filter_val(filter->pdev));
+
+	mutex_unlock(&hisi_ptt->mutex);
+	return pos;
+}
+static DEVICE_ATTR_ADMIN_RO(available_filters);
+
+PMU_FORMAT_ATTR(filter,		"config:0-19");
+PMU_FORMAT_ATTR(direction,	"config:20-23");
+PMU_FORMAT_ATTR(type,		"config:24-31");
+PMU_FORMAT_ATTR(format,		"config:32-35");
+
+static struct attribute *hisi_ptt_pmu_format_attrs[] = {
+	&format_attr_filter.attr,
+	&format_attr_direction.attr,
+	&format_attr_type.attr,
+	&format_attr_format.attr,
+	NULL
+};
+
+static struct attribute_group hisi_ptt_pmu_format_group = {
+	.name = "format",
+	.attrs = hisi_ptt_pmu_format_attrs,
+};
+
+static struct attribute *hisi_ptt_pmu_filter_attrs[] = {
+	&dev_attr_available_filters.attr,
+	NULL
+};
+
+static struct attribute_group hisi_ptt_pmu_filter_group = {
+	.attrs = hisi_ptt_pmu_filter_attrs,
+};
+
+static const struct attribute_group *hisi_ptt_pmu_groups[] = {
+	&hisi_ptt_pmu_format_group,
+	&hisi_ptt_pmu_filter_group,
+	NULL
+};
+
+/*
+ * The supported value of the direction parameter. See hisi_ptt.rst
+ * documentation for more details.
+ */
+static u32 hisi_ptt_trace_available_direction[] = {
+	0,
+	1,
+	2,
+	3,
+};
+
+/* Different types can be set simultaneously */
+static u32 hisi_ptt_trace_available_type[] = {
+	1,	/* posted_request */
+	2,	/* non-posted_request */
+	4,	/* completion */
+};
+
+static u32 hisi_ptt_trace_availble_format[] = {
+	0,	/* 4DW */
+	1,	/* 8DW */
+};
+
+/*
+ * Check whether the config is valid or not. Some configs are multi-selectable
+ * and can be set simultaneously, while some are single selectable (onehot).
+ * Use this function to check the non-onehot configs while
+ * hisi_ptt_trace_valid_config_onehot() for the onehot ones.
+ */
+static int hisi_ptt_trace_valid_config(u32 val, u32 *available_list, u32 list_size)
+{
+	int i;
+
+	/* The non-onehot configs cannot be 0. */
+	if (!val)
+		return -EINVAL;
+
+	/*
+	 * Walk the available list and clear the valid bits of
+	 * the config. If there is any resident bit after the
+	 * walk then the config is invalid.
+	 */
+	for (i = 0; i < list_size; i++)
+		val &= ~available_list[i];
+
+	return val ? -EINVAL : 0;
+}
+
+static int hisi_ptt_trace_valid_config_onehot(u32 val, u32 *available_list, u32 list_size)
+{
+	int i, ret = -EINVAL;
+
+	for (i = 0; i < list_size; i++)
+		if (val == available_list[i]) {
+			ret = 0;
+			break;
+		}
+
+	return ret;
+}
+
+static int hisi_ptt_trace_init_filter(struct hisi_ptt *hisi_ptt, u64 config)
+{
+	unsigned long val, port_mask = hisi_ptt->port_mask;
+	struct hisi_ptt_filter_desc *filter;
+	int ret = -EINVAL;
+
+	hisi_ptt->trace_ctrl.is_port = FIELD_GET(HISI_PTT_PMU_FILTER_IS_PORT, config);
+	val = FIELD_GET(HISI_PTT_PMU_FILTER_VAL_MASK, config);
+
+	/*
+	 * Port filters are defined as bit mask. For port filters, check
+	 * the bits in the @val are within the range of hisi_ptt->port_mask
+	 * and whether it's empty or not, otherwise user has specified
+	 * some unsupported root ports.
+	 *
+	 * For Requester ID filters, walk the available filter list to see
+	 * whether we have one matched.
+	 */
+	if (!hisi_ptt->trace_ctrl.is_port) {
+		list_for_each_entry(filter, &hisi_ptt->req_filters, list)
+			if (filter->val == val) {
+				ret = 0;
+				break;
+			}
+	} else if (bitmap_subset(&val, &port_mask, BITS_PER_LONG)) {
+		ret = 0;
+	}
+
+	if (ret)
+		return ret;
+
+	hisi_ptt->trace_ctrl.filter = val;
+	return 0;
+}
+
+static int hisi_ptt_pmu_event_init(struct perf_event *event)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
+	struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
+	int ret;
+	u32 val;
+
+	if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type)
+		return -ENOENT;
+
+	mutex_lock(&hisi_ptt->mutex);
+
+	ret = hisi_ptt_trace_init_filter(hisi_ptt, event->attr.config);
+	if (ret < 0)
+		goto out;
+
+	val = FIELD_GET(HISI_PTT_PMU_DIRECTION_MASK, event->attr.config);
+	ret = hisi_ptt_trace_valid_config_onehot(val, hisi_ptt_trace_available_direction,
+						 ARRAY_SIZE(hisi_ptt_trace_available_direction));
+	if (ret < 0)
+		goto out;
+	ctrl->direction = val;
+
+	val = FIELD_GET(HISI_PTT_PMU_TYPE_MASK, event->attr.config);
+
+	ret = hisi_ptt_trace_valid_config(val, hisi_ptt_trace_available_type,
+					  ARRAY_SIZE(hisi_ptt_trace_available_type));
+	if (ret < 0)
+		goto out;
+	ctrl->type = val;
+
+	val = FIELD_GET(HISI_PTT_PMU_FORMAT_MASK, event->attr.config);
+	ret = hisi_ptt_trace_valid_config_onehot(val, hisi_ptt_trace_availble_format,
+						 ARRAY_SIZE(hisi_ptt_trace_availble_format));
+	if (ret < 0)
+		goto out;
+	ctrl->format = val;
+
+out:
+	mutex_unlock(&hisi_ptt->mutex);
+	return ret;
+}
+
+static void *hisi_ptt_pmu_setup_aux(struct perf_event *event, void **pages,
+				    int nr_pages, bool overwrite)
+{
+	struct hisi_ptt_pmu_buf *buf;
+	struct page **pagelist;
+	int i;
+
+	if (overwrite) {
+		dev_warn(event->pmu->dev, "Overwrite mode is not supported\n");
+		return NULL;
+	}
+
+	/* If the pages size less than buffers, we cannot start trace */
+	if (nr_pages < HISI_PTT_TRACE_TOTAL_BUF_SIZE / PAGE_SIZE)
+		return NULL;
+
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		return NULL;
+
+	pagelist = kcalloc(nr_pages, sizeof(*pagelist), GFP_KERNEL);
+	if (!pagelist) {
+		kfree(buf);
+		return NULL;
+	}
+
+	for (i = 0; i < nr_pages; i++)
+		pagelist[i] = virt_to_page(pages[i]);
+
+	buf->base = vmap(pagelist, nr_pages, VM_MAP, PAGE_KERNEL);
+	if (!buf->base) {
+		kfree(pagelist);
+		kfree(buf);
+		return NULL;
+	}
+
+	buf->nr_pages = nr_pages;
+	buf->length = nr_pages * PAGE_SIZE;
+	buf->pos = 0;
+
+	kfree(pagelist);
+	return buf;
+}
+
+static void hisi_ptt_pmu_free_aux(void *aux)
+{
+	struct hisi_ptt_pmu_buf *buf = aux;
+
+	vunmap(buf->base);
+	kfree(buf);
+}
+
+static void hisi_ptt_pmu_start(struct perf_event *event, int flags)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
+	struct perf_output_handle *handle = &hisi_ptt->trace_ctrl.handle;
+	struct hw_perf_event *hwc = &event->hw;
+	struct hisi_ptt_pmu_buf *buf;
+	int cpu = event->cpu;
+	int ret;
+
+	hwc->state = 0;
+	mutex_lock(&hisi_ptt->mutex);
+	if (hisi_ptt->trace_ctrl.status == HISI_PTT_TRACE_STATUS_ON) {
+		pci_dbg(hisi_ptt->pdev, "trace has already started\n");
+		goto stop;
+	}
+
+	if (cpu == -1)
+		cpu = hisi_ptt->trace_ctrl.default_cpu;
+
+	/*
+	 * Handle the interrupt on the same cpu which starts the trace to avoid
+	 * context mismatch. Otherwise we'll trigger the WARN from the perf
+	 * core in event_function_local().
+	 */
+	WARN_ON(irq_set_affinity(pci_irq_vector(hisi_ptt->pdev, HISI_PTT_TRACE_DMA_IRQ),
+				 cpumask_of(cpu)));
+
+	ret = hisi_ptt_alloc_trace_buf(hisi_ptt);
+	if (ret) {
+		pci_dbg(hisi_ptt->pdev, "alloc trace buf failed, ret = %d\n", ret);
+		goto stop;
+	}
+
+	buf = perf_aux_output_begin(handle, event);
+	if (!buf) {
+		pci_dbg(hisi_ptt->pdev, "aux output begin failed\n");
+		goto stop;
+	}
+
+	buf->pos = handle->head % buf->length;
+
+	ret = hisi_ptt_trace_start(hisi_ptt);
+	if (ret) {
+		pci_dbg(hisi_ptt->pdev, "trace start failed, ret = %d\n", ret);
+		perf_aux_output_end(handle, 0);
+		goto stop;
+	}
+
+	mutex_unlock(&hisi_ptt->mutex);
+	return;
+stop:
+	event->hw.state |= PERF_HES_STOPPED;
+	mutex_unlock(&hisi_ptt->mutex);
+}
+
+static void hisi_ptt_pmu_stop(struct perf_event *event, int flags)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+
+	if (hwc->state & PERF_HES_STOPPED)
+		return;
+
+	mutex_lock(&hisi_ptt->mutex);
+	if (hisi_ptt->trace_ctrl.status == HISI_PTT_TRACE_STATUS_ON) {
+		hisi_ptt_trace_end(hisi_ptt);
+		WARN(hisi_ptt_wait_trace_hw_idle(hisi_ptt), "Device is still busy");
+		hisi_ptt_update_aux(hisi_ptt, hisi_ptt->trace_ctrl.buf_index, true);
+	}
+	mutex_unlock(&hisi_ptt->mutex);
+
+	hwc->state |= PERF_HES_STOPPED;
+	perf_event_update_userpage(event);
+	hwc->state |= PERF_HES_UPTODATE;
+}
+
+static int hisi_ptt_pmu_add(struct perf_event *event, int flags)
+{
+	struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
+	struct hw_perf_event *hwc = &event->hw;
+	int cpu = event->cpu;
+
+	if (cpu == -1 && smp_processor_id() != hisi_ptt->trace_ctrl.default_cpu)
+		return 0;
+
+	hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
+
+	if (flags & PERF_EF_START) {
+		hisi_ptt_pmu_start(event, PERF_EF_RELOAD);
+		if (hwc->state & PERF_HES_STOPPED)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void hisi_ptt_pmu_del(struct perf_event *event, int flags)
+{
+	hisi_ptt_pmu_stop(event, PERF_EF_UPDATE);
+}
+
+static void hisi_ptt_unregister_pmu(void *priv)
+{
+	perf_pmu_unregister(priv);
+}
+
+static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
+{
+	char *pmu_name;
+	int ret;
+
+	hisi_ptt->hisi_ptt_pmu = (struct pmu) {
+		.module		= THIS_MODULE,
+		.capabilities	= PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE,
+		.task_ctx_nr	= perf_sw_context,
+		.attr_groups	= hisi_ptt_pmu_groups,
+		.event_init	= hisi_ptt_pmu_event_init,
+		.setup_aux	= hisi_ptt_pmu_setup_aux,
+		.free_aux	= hisi_ptt_pmu_free_aux,
+		.start		= hisi_ptt_pmu_start,
+		.stop		= hisi_ptt_pmu_stop,
+		.add		= hisi_ptt_pmu_add,
+		.del		= hisi_ptt_pmu_del,
+	};
+
+	pmu_name = devm_kasprintf(&hisi_ptt->pdev->dev, GFP_KERNEL, "hisi_ptt%u_%u",
+				  hisi_ptt->sicl_id, hisi_ptt->core_id);
+	if (!pmu_name)
+		return -ENOMEM;
+
+	ret = perf_pmu_register(&hisi_ptt->hisi_ptt_pmu, pmu_name, -1);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(&hisi_ptt->pdev->dev,
+					hisi_ptt_unregister_pmu,
+					&hisi_ptt->hisi_ptt_pmu);
+}
+
 /*
  * The DMA of PTT trace can only use direct mapping, due to some
  * hardware restriction. Check whether there is an iommu or the
@@ -359,6 +810,12 @@ static int hisi_ptt_probe(struct pci_dev *pdev,
 
 	hisi_ptt_init_ctrls(hisi_ptt);
 
+	ret = hisi_ptt_register_pmu(hisi_ptt);
+	if (ret) {
+		pci_err(pdev, "failed to register pmu device, ret = %d", ret);
+		return ret;
+	}
+
 	ret = hisi_ptt_check_iommu_mapping(hisi_ptt);
 	if (ret) {
 		pci_err(pdev, "cannot work with non-direct DMA mapping.\n");
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
index 8aa5d6b78cc5..002b64dfa42d 100644
--- a/drivers/hwtracing/ptt/hisi_ptt.h
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
@@ -13,6 +13,7 @@
 #include <linux/list.h>
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/perf_event.h>
 #include <linux/types.h>
 
 /*
@@ -83,6 +84,7 @@ struct hisi_ptt_dma_buffer {
 /**
  * struct hisi_ptt_trace_ctrl - control and status of PTT trace
  * @status:      current trace status
+ * @handle:      perf output handle of current trace session
  * @trace_buf:   the trace buffers for holding the trace data
  * @default_cpu: default cpu to start the trace session
  * @buffer_size: the size of each trace buffer in the list
@@ -95,6 +97,7 @@ struct hisi_ptt_dma_buffer {
  */
 struct hisi_ptt_trace_ctrl {
 	enum hisi_ptt_trace_status status;
+	struct perf_output_handle handle;
 	struct list_head trace_buf;
 	int default_cpu;
 	u32 buffer_size;
@@ -118,9 +121,25 @@ struct hisi_ptt_filter_desc {
 	u16 val;
 };
 
+
+/**
+ * struct hisi_ptt_pmu_buf - descriptor of the AUX buffer of PTT trace
+ * @length:   size of the AUX buffer
+ * @nr_pages: number of pages of the AUX buffer
+ * @base:     start address of AUX buffer
+ * @pos:      position in the AUX buffer to commit traced data
+ */
+struct hisi_ptt_pmu_buf {
+	size_t length;
+	int nr_pages;
+	void *base;
+	long pos;
+};
+
 /**
  * struct hisi_ptt - per PTT device data
  * @trace_ctrl:   the control information of PTT trace
+ * @hisi_ptt_pmu: the pum device of trace
  * @iobase:       base IO address of the device
  * @pdev:         pci_dev of this PTT device
  * @mutex:        mutex to protect the filter list and serialize the perf process.
@@ -135,6 +154,7 @@ struct hisi_ptt_filter_desc {
  */
 struct hisi_ptt {
 	struct hisi_ptt_trace_ctrl trace_ctrl;
+	struct pmu hisi_ptt_pmu;
 	void __iomem *iobase;
 	struct pci_dev *pdev;
 	struct mutex mutex;
@@ -156,4 +176,6 @@ struct hisi_ptt {
 	u16 port_mask;
 };
 
+#define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu)
+
 #endif /* _HISI_PTT_H */
-- 
2.24.0



From yangyicong at hisilicon.com  Mon Jan 24 05:11:15 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Mon, 24 Jan 2022 21:11:15 +0800
Subject: [PATCH v3 5/8] perf tool: Add support for HiSilicon PCIe Tune and
 Trace device driver
In-Reply-To: <20220124131118.17887-1-yangyicong@hisilicon.com>
References: <20220124131118.17887-1-yangyicong@hisilicon.com>
Message-ID: <20220124131118.17887-6-yangyicong@hisilicon.com>

From: Qi Liu <liuqi115 at huawei.com>

'perf record' and 'perf report --dump-raw-trace' supported in this
patch.

Example usage:

Output will contain raw PTT data and its textual representation, such
as:

0 0 0x5810 [0x30]: PERF_RECORD_AUXTRACE size: 0x400000  offset: 0
ref: 0xa5d50c725  idx: 0  tid: -1  cpu: 0
.
. ... HISI PTT data: size 4194304 bytes
.  00000000: 00 00 00 00                                 Prefix
.  00000004: 08 20 00 60                                 Header DW0
.  00000008: ff 02 00 01                                 Header DW1
.  0000000c: 20 08 00 00                                 Header DW2
.  00000010: 10 e7 44 ab                                 Header DW3
.  00000014: 2a a8 1e 01                                 Time
.  00000020: 00 00 00 00                                 Prefix
.  00000024: 01 00 00 60                                 Header DW0
.  00000028: 0f 1e 00 01                                 Header DW1
.  0000002c: 04 00 00 00                                 Header DW2
.  00000030: 40 00 81 02                                 Header DW3
.  00000034: ee 02 00 00                                 Time
....

Signed-off-by: Qi Liu <liuqi115 at huawei.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 tools/perf/arch/arm/util/auxtrace.c           |  56 ++++-
 tools/perf/arch/arm/util/pmu.c                |   3 +
 tools/perf/arch/arm64/util/Build              |   2 +-
 tools/perf/arch/arm64/util/hisi_ptt.c         | 195 +++++++++++++++
 tools/perf/util/Build                         |   2 +
 tools/perf/util/auxtrace.c                    |   4 +
 tools/perf/util/auxtrace.h                    |   1 +
 tools/perf/util/hisi-ptt-decoder/Build        |   1 +
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.c   | 170 +++++++++++++
 .../hisi-ptt-decoder/hisi-ptt-pkt-decoder.h   |  28 +++
 tools/perf/util/hisi_ptt.c                    | 228 ++++++++++++++++++
 tools/perf/util/hisi_ptt.h                    |  28 +++
 12 files changed, 714 insertions(+), 4 deletions(-)
 create mode 100644 tools/perf/arch/arm64/util/hisi_ptt.c
 create mode 100644 tools/perf/util/hisi-ptt-decoder/Build
 create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
 create mode 100644 tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
 create mode 100644 tools/perf/util/hisi_ptt.c
 create mode 100644 tools/perf/util/hisi_ptt.h

diff --git a/tools/perf/arch/arm/util/auxtrace.c b/tools/perf/arch/arm/util/auxtrace.c
index 5fc6a2a3dbc5..dc9d2172464e 100644
--- a/tools/perf/arch/arm/util/auxtrace.c
+++ b/tools/perf/arch/arm/util/auxtrace.c
@@ -4,6 +4,7 @@
  * Author: Mathieu Poirier <mathieu.poirier at linaro.org>
  */
 
+#include <dirent.h>
 #include <stdbool.h>
 #include <linux/coresight-pmu.h>
 #include <linux/zalloc.h>
@@ -14,6 +15,7 @@
 #include "../../../util/pmu.h"
 #include "cs-etm.h"
 #include "arm-spe.h"
+#include "hisi_ptt.h"
 
 static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
 {
@@ -50,6 +52,39 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
 	return arm_spe_pmus;
 }
 
+static struct perf_pmu **find_all_hisi_ptt_pmus(int *nr_ptts, int *err)
+{
+	struct perf_pmu **hisi_ptt_pmus = NULL;
+	int nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
+	DIR *dir = NULL;
+	struct dirent *dent;
+
+	hisi_ptt_pmus = zalloc(sizeof(struct perf_pmu *) * nr_cpus);
+	if (!hisi_ptt_pmus) {
+		pr_err("hisi_ptt alloc failed\n");
+		*err = -ENOMEM;
+		return NULL;
+	}
+
+	dir = opendir("/sys/devices");
+	dent = readdir(dir);
+	while (dent) {
+		if (strstr(dent->d_name, HISI_PTT_PMU_NAME)) {
+			hisi_ptt_pmus[*nr_ptts] = perf_pmu__find(dent->d_name);
+			if (hisi_ptt_pmus[*nr_ptts]) {
+				pr_debug2("%s %d: arm_spe_pmu %d type %d name %s\n",
+					  __func__, __LINE__, *nr_ptts,
+					  hisi_ptt_pmus[*nr_ptts]->type,
+					  hisi_ptt_pmus[*nr_ptts]->name);
+				(*nr_ptts)++;
+			}
+		}
+		dent = readdir(dir);
+	}
+
+	return hisi_ptt_pmus;
+}
+
 struct auxtrace_record
 *auxtrace_record__init(struct evlist *evlist, int *err)
 {
@@ -57,8 +92,12 @@ struct auxtrace_record
 	struct evsel *evsel;
 	bool found_etm = false;
 	struct perf_pmu *found_spe = NULL;
+	struct perf_pmu *found_ptt = NULL;
 	struct perf_pmu **arm_spe_pmus = NULL;
+	struct perf_pmu **hisi_ptt_pmus = NULL;
+
 	int nr_spes = 0;
+	int nr_ptts = 0;
 	int i = 0;
 
 	if (!evlist)
@@ -66,13 +105,14 @@ struct auxtrace_record
 
 	cs_etm_pmu = perf_pmu__find(CORESIGHT_ETM_PMU_NAME);
 	arm_spe_pmus = find_all_arm_spe_pmus(&nr_spes, err);
+	hisi_ptt_pmus = find_all_hisi_ptt_pmus(&nr_ptts, err);
 
 	evlist__for_each_entry(evlist, evsel) {
 		if (cs_etm_pmu &&
 		    evsel->core.attr.type == cs_etm_pmu->type)
 			found_etm = true;
 
-		if (!nr_spes || found_spe)
+		if ((!nr_spes || found_spe) && (!nr_ptts || found_ptt))
 			continue;
 
 		for (i = 0; i < nr_spes; i++) {
@@ -81,11 +121,18 @@ struct auxtrace_record
 				break;
 			}
 		}
+
+		for (i = 0; i < nr_ptts; i++) {
+			if (evsel->core.attr.type == hisi_ptt_pmus[i]->type) {
+				found_ptt = hisi_ptt_pmus[i];
+				break;
+			}
+		}
 	}
 	free(arm_spe_pmus);
 
-	if (found_etm && found_spe) {
-		pr_err("Concurrent ARM Coresight ETM and SPE operation not currently supported\n");
+	if (found_etm && found_spe && found_ptt) {
+		pr_err("Concurrent ARM Coresight ETM ,SPE and HiSilicon PCIe Trace operation not currently supported\n");
 		*err = -EOPNOTSUPP;
 		return NULL;
 	}
@@ -96,6 +143,9 @@ struct auxtrace_record
 #if defined(__aarch64__)
 	if (found_spe)
 		return arm_spe_recording_init(err, found_spe);
+
+	if (found_ptt)
+		return hisi_ptt_recording_init(err, found_ptt);
 #endif
 
 	/*
diff --git a/tools/perf/arch/arm/util/pmu.c b/tools/perf/arch/arm/util/pmu.c
index b8b23b9dc598..89a3cedb4557 100644
--- a/tools/perf/arch/arm/util/pmu.c
+++ b/tools/perf/arch/arm/util/pmu.c
@@ -10,6 +10,7 @@
 #include <linux/string.h>
 
 #include "arm-spe.h"
+#include "hisi_ptt.h"
 #include "../../../util/pmu.h"
 
 struct perf_event_attr
@@ -22,6 +23,8 @@ struct perf_event_attr
 #if defined(__aarch64__)
 	} else if (strstarts(pmu->name, ARM_SPE_PMU_NAME)) {
 		return arm_spe_pmu_default_config(pmu);
+	} else if (strstarts(pmu->name, HISI_PTT_PMU_NAME)) {
+		pmu->selectable = true;
 #endif
 	}
 
diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build
index 9fcb4e68add9..8b7fd1dc9f37 100644
--- a/tools/perf/arch/arm64/util/Build
+++ b/tools/perf/arch/arm64/util/Build
@@ -11,4 +11,4 @@ perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
 perf-$(CONFIG_AUXTRACE) += ../../arm/util/pmu.o \
 			      ../../arm/util/auxtrace.o \
 			      ../../arm/util/cs-etm.o \
-			      arm-spe.o mem-events.o
+			      arm-spe.o mem-events.o hisi_ptt.o
diff --git a/tools/perf/arch/arm64/util/hisi_ptt.c b/tools/perf/arch/arm64/util/hisi_ptt.c
new file mode 100644
index 000000000000..de3a3523ffd5
--- /dev/null
+++ b/tools/perf/arch/arm64/util/hisi_ptt.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HiSilicon PCIe Trace and Tuning (PTT) support
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/log2.h>
+#include <linux/zalloc.h>
+#include <time.h>
+
+#include <internal/lib.h> // page_size
+#include "../../../util/auxtrace.h"
+#include "../../../util/cpumap.h"
+#include "../../../util/debug.h"
+#include "../../../util/event.h"
+#include "../../../util/evlist.h"
+#include "../../../util/evsel.h"
+#include "../../../util/hisi_ptt.h"
+#include "../../../util/pmu.h"
+#include "../../../util/record.h"
+#include "../../../util/session.h"
+#include "../../../util/tsc.h"
+
+#define DEFAULT_PAGE_SIZE 1024
+#define KiB(x) ((x) * DEFAULT_PAGE_SIZE)
+#define MiB(x) ((x) * DEFAULT_PAGE_SIZE * DEFAULT_PAGE_SIZE)
+
+struct hisi_ptt_recording {
+	struct auxtrace_record	itr;
+	struct perf_pmu *hisi_ptt_pmu;
+	struct evlist *evlist;
+};
+
+static size_t
+hisi_ptt_info_priv_size(struct auxtrace_record *itr __maybe_unused,
+			struct evlist *evlist __maybe_unused)
+{
+	return HISI_PTT_AUXTRACE_PRIV_SIZE;
+}
+
+static int hisi_ptt_info_fill(struct auxtrace_record *itr,
+			      struct perf_session *session,
+			      struct perf_record_auxtrace_info *auxtrace_info,
+			      size_t priv_size)
+{
+	struct hisi_ptt_recording *pttr =
+			container_of(itr, struct hisi_ptt_recording, itr);
+	struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu;
+
+	if (priv_size != HISI_PTT_AUXTRACE_PRIV_SIZE)
+		return -EINVAL;
+
+	if (!session->evlist->core.nr_mmaps)
+		return -EINVAL;
+
+	auxtrace_info->type = PERF_AUXTRACE_HISI_PTT;
+	auxtrace_info->priv[HISI_PTT_PMU_TYPE] = hisi_ptt_pmu->type;
+
+	return 0;
+}
+
+static int hisi_ptt_set_auxtrace_mmap_page(struct record_opts *opts)
+{
+	bool privileged = perf_event_paranoid_check(-1);
+
+	if (!opts->full_auxtrace)
+		return 0;
+
+	if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
+		if (privileged) {
+			opts->auxtrace_mmap_pages = MiB(16) / page_size;
+		} else {
+			opts->auxtrace_mmap_pages = KiB(128) / page_size;
+			if (opts->mmap_pages == UINT_MAX)
+				opts->mmap_pages = KiB(256) / page_size;
+		}
+	}
+
+	/* Validate auxtrace_mmap_pages */
+	if (opts->auxtrace_mmap_pages) {
+		size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
+		size_t min_sz = KiB(8);
+
+		if (sz < min_sz || !is_power_of_2(sz)) {
+			pr_err("Invalid mmap size for HISI PTT: must be at least %zuKiB and a power of 2\n",
+			       min_sz / DEFAULT_PAGE_SIZE);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+static int hisi_ptt_recording_options(struct auxtrace_record *itr,
+				      struct evlist *evlist,
+				      struct record_opts *opts)
+{
+	struct hisi_ptt_recording *pttr =
+			container_of(itr, struct hisi_ptt_recording, itr);
+	struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu;
+	struct perf_cpu_map *cpus = evlist->core.cpus;
+	struct evsel *evsel, *hisi_ptt_evsel = NULL;
+	struct evsel *tracking_evsel;
+	int err;
+
+	pttr->evlist = evlist;
+	evlist__for_each_entry(evlist, evsel) {
+		if (evsel->core.attr.type == hisi_ptt_pmu->type) {
+			if (hisi_ptt_evsel) {
+				pr_err("There may be only one " HISI_PTT_PMU_NAME "x event\n");
+				return -EINVAL;
+			}
+			evsel->core.attr.freq = 0;
+			evsel->core.attr.sample_period = 1;
+			hisi_ptt_evsel = evsel;
+			opts->full_auxtrace = true;
+		}
+	}
+
+	err = hisi_ptt_set_auxtrace_mmap_page(opts);
+	if (err)
+		return err;
+	/*
+	 * To obtain the auxtrace buffer file descriptor, the auxtrace event
+	 * must come first.
+	 */
+	evlist__to_front(evlist, hisi_ptt_evsel);
+
+	if (!perf_cpu_map__empty(cpus)) {
+		evsel__set_sample_bit(hisi_ptt_evsel, TIME);
+		evsel__set_sample_bit(hisi_ptt_evsel, CPU);
+	}
+
+	/* Add dummy event to keep tracking */
+	err = parse_events(evlist, "dummy:u", NULL);
+	if (err)
+		return err;
+
+	tracking_evsel = evlist__last(evlist);
+	evlist__set_tracking_event(evlist, tracking_evsel);
+
+	tracking_evsel->core.attr.freq = 0;
+	tracking_evsel->core.attr.sample_period = 1;
+
+	if (!perf_cpu_map__empty(cpus))
+		evsel__set_sample_bit(tracking_evsel, TIME);
+
+	return 0;
+}
+
+static u64 hisi_ptt_reference(struct auxtrace_record *itr __maybe_unused)
+{
+	return rdtsc();
+}
+
+static void hisi_ptt_recording_free(struct auxtrace_record *itr)
+{
+	struct hisi_ptt_recording *pttr =
+			container_of(itr, struct hisi_ptt_recording, itr);
+
+	free(pttr);
+}
+
+struct auxtrace_record *hisi_ptt_recording_init(int *err,
+						struct perf_pmu *hisi_ptt_pmu)
+{
+	struct hisi_ptt_recording *pttr;
+
+	if (!hisi_ptt_pmu) {
+		*err = -ENODEV;
+		return NULL;
+	}
+
+	pttr = zalloc(sizeof(struct hisi_ptt_recording));
+	if (!pttr) {
+		*err = -ENOMEM;
+		return NULL;
+	}
+
+	pttr->hisi_ptt_pmu = hisi_ptt_pmu;
+	pttr->itr.pmu = hisi_ptt_pmu;
+	pttr->itr.recording_options = hisi_ptt_recording_options;
+	pttr->itr.info_priv_size = hisi_ptt_info_priv_size;
+	pttr->itr.info_fill = hisi_ptt_info_fill;
+	pttr->itr.free = hisi_ptt_recording_free;
+	pttr->itr.reference = hisi_ptt_reference;
+	pttr->itr.read_finish = auxtrace_record__read_finish;
+	pttr->itr.alignment = 0;
+
+	*err = 0;
+	return &pttr->itr;
+}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 2a403cefcaf2..a32d1ef8ce29 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -115,6 +115,8 @@ perf-$(CONFIG_AUXTRACE) += intel-pt.o
 perf-$(CONFIG_AUXTRACE) += intel-bts.o
 perf-$(CONFIG_AUXTRACE) += arm-spe.o
 perf-$(CONFIG_AUXTRACE) += arm-spe-decoder/
+perf-$(CONFIG_AUXTRACE) += hisi_ptt.o
+perf-$(CONFIG_AUXTRACE) += hisi-ptt-decoder/
 perf-$(CONFIG_AUXTRACE) += s390-cpumsf.o
 
 ifdef CONFIG_LIBOPENCSD
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index 825336304a37..7f1ee06538a0 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -51,6 +51,7 @@
 #include "intel-pt.h"
 #include "intel-bts.h"
 #include "arm-spe.h"
+#include "hisi_ptt.h"
 #include "s390-cpumsf.h"
 #include "util/mmap.h"
 
@@ -1281,6 +1282,9 @@ int perf_event__process_auxtrace_info(struct perf_session *session,
 	case PERF_AUXTRACE_S390_CPUMSF:
 		err = s390_cpumsf_process_auxtrace_info(event, session);
 		break;
+	case PERF_AUXTRACE_HISI_PTT:
+		err = hisi_ptt_process_auxtrace_info(event, session);
+		break;
 	case PERF_AUXTRACE_UNKNOWN:
 	default:
 		return -EINVAL;
diff --git a/tools/perf/util/auxtrace.h b/tools/perf/util/auxtrace.h
index 19910b9011f3..0f7eaad4d8d0 100644
--- a/tools/perf/util/auxtrace.h
+++ b/tools/perf/util/auxtrace.h
@@ -48,6 +48,7 @@ enum auxtrace_type {
 	PERF_AUXTRACE_CS_ETM,
 	PERF_AUXTRACE_ARM_SPE,
 	PERF_AUXTRACE_S390_CPUMSF,
+	PERF_AUXTRACE_HISI_PTT,
 };
 
 enum itrace_period_type {
diff --git a/tools/perf/util/hisi-ptt-decoder/Build b/tools/perf/util/hisi-ptt-decoder/Build
new file mode 100644
index 000000000000..db3db8b75033
--- /dev/null
+++ b/tools/perf/util/hisi-ptt-decoder/Build
@@ -0,0 +1 @@
+perf-$(CONFIG_AUXTRACE) += hisi-ptt-pkt-decoder.o
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
new file mode 100644
index 000000000000..3fb7a6949209
--- /dev/null
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.c
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HiSilicon PCIe Trace and Tuning (PTT) support
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <endian.h>
+#include <byteswap.h>
+#include <linux/bitops.h>
+#include <stdarg.h>
+
+#include "../color.h"
+#include "hisi-ptt-pkt-decoder.h"
+
+/*
+ * For 8DW format, the bit[31:11] of DW0 is always 0x1fffff, which can be
+ * used to distinguish the data format.
+ * 8DW format is like:
+ *   bits [                 31:11                 ][       10:0       ]
+ *        |---------------------------------------|-------------------|
+ *    DW0 [                0x1fffff               ][ Reserved (0x7ff) ]
+ *    DW1 [                       Prefix                              ]
+ *    DW2 [                     Header DW0                            ]
+ *    DW3 [                     Header DW1                            ]
+ *    DW4 [                     Header DW2                            ]
+ *    DW5 [                     Header DW3                            ]
+ *    DW6 [                   Reserved (0x0)                          ]
+ *    DW7 [                        Time                               ]
+ *
+ * 4DW format is like:
+ *   bits [31:30] [ 29:25 ][24][23][22][21][    20:11   ][    10:0    ]
+ *        |-----|---------|---|---|---|---|-------------|-------------|
+ *    DW0 [ Fmt ][  Type  ][T9][T8][TH][SO][   Length   ][    Time    ]
+ *    DW1 [                     Header DW1                            ]
+ *    DW2 [                     Header DW2                            ]
+ *    DW3 [                     Header DW3                            ]
+ */
+
+enum hisi_ptt_8dw_pkt_field_type {
+	HISI_PTT_8DW_PREFIX,
+	HISI_PTT_8DW_HEAD0,
+	HISI_PTT_8DW_HEAD1,
+	HISI_PTT_8DW_HEAD2,
+	HISI_PTT_8DW_HEAD3,
+	HISI_PTT_8DW_TIME,
+	HISI_PTT_8DW_TYPE_MAX
+};
+
+enum hisi_ptt_4dw_pkt_field_type {
+	HISI_PTT_4DW_HEAD1,
+	HISI_PTT_4DW_HEAD2,
+	HISI_PTT_4DW_HEAD3,
+	HISI_PTT_4DW_TYPE_MAX
+};
+
+static const char * const hisi_ptt_8dw_pkt_field_name[] = {
+	[HISI_PTT_8DW_PREFIX]	= "Prefix",
+	[HISI_PTT_8DW_HEAD0]	= "Header DW0",
+	[HISI_PTT_8DW_HEAD1]	= "Header DW1",
+	[HISI_PTT_8DW_HEAD2]	= "Header DW2",
+	[HISI_PTT_8DW_HEAD3]	= "Header DW3",
+	[HISI_PTT_8DW_TIME]	= "Time",
+};
+
+static const char * const hisi_ptt_4dw_pkt_field_name[] = {
+	[HISI_PTT_4DW_HEAD1]	= "Header DW1",
+	[HISI_PTT_4DW_HEAD2]	= "Header DW2",
+	[HISI_PTT_4DW_HEAD3]	= "Header DW3",
+};
+
+/* offset of each member is determined by format of 8dw packet. */
+static uint32_t hisi_ptt_8dw_pkt_field_offset[] = {
+	[HISI_PTT_8DW_PREFIX]	= 4,
+	[HISI_PTT_8DW_HEAD0]	= 4,
+	[HISI_PTT_8DW_HEAD1]	= 4,
+	[HISI_PTT_8DW_HEAD2]	= 4,
+	[HISI_PTT_8DW_HEAD3]	= 4,
+	[HISI_PTT_8DW_TIME]	= 8,
+};
+
+union hisi_ptt_4dw {
+	struct {
+		uint32_t format : 2;
+		uint32_t type : 5;
+		uint32_t t9 : 1;
+		uint32_t t8 : 1;
+		uint32_t th : 1;
+		uint32_t so : 1;
+		uint32_t len : 10;
+		uint32_t time : 11;
+	};
+	uint32_t value;
+};
+
+static void hisi_ptt_print_pkt(const unsigned char *buf, int *pos, const char *desc)
+{
+	const char *color = PERF_COLOR_BLUE;
+	int field_len = sizeof(uint32_t);
+	int i;
+
+	printf(".");
+	color_fprintf(stdout, color, "  %08x: ", *pos);
+	for (i = 0; i < field_len; i++)
+		color_fprintf(stdout, color, "%02x ", buf[i]);
+	for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
+		color_fprintf(stdout, color, "   ");
+	color_fprintf(stdout, color, "  %s\n", desc);
+	*pos += field_len;
+}
+
+static int hisi_ptt_8dw_kpt_desc(const unsigned char *buf, int pos)
+{
+	int i;
+
+	for (i = HISI_PTT_8DW_PREFIX; i < HISI_PTT_8DW_TYPE_MAX; i++) {
+		buf += hisi_ptt_8dw_pkt_field_offset[i];
+		hisi_ptt_print_pkt(buf, &pos, hisi_ptt_8dw_pkt_field_name[i]);
+	}
+
+	return HISI_PTT_8DW_PKT_SIZE;
+}
+
+static void hisi_ptt_4dw_print_dw0(const unsigned char *buf, int *pos)
+{
+	const char *color = PERF_COLOR_BLUE;
+	int field_len = sizeof(uint32_t);
+	union hisi_ptt_4dw dw0;
+	int i;
+
+	dw0.value = *(uint32_t *)buf;
+	printf(".");
+	color_fprintf(stdout, color, "  %08x: ", *pos);
+	for (i = 0; i < field_len; i++)
+		color_fprintf(stdout, color, "%02x ", buf[i]);
+	for (i = 0; i < HISI_PTT_MAX_SPACE_LEN; i++)
+		color_fprintf(stdout, color, "   ");
+
+	color_fprintf(stdout, color,
+		      "  %s %x %s %x %s %x %s %x %s %x %s %x %s %x %s %x\n",
+		      "Format", dw0.format, "Type", dw0.type, "T9", dw0.t9,
+		      "T8", dw0.t8, "TH", dw0.th, "SO", dw0.so, "Length",
+		      dw0.len, "Time", dw0.time);
+
+	*pos += field_len;
+}
+
+static int hisi_ptt_4dw_kpt_desc(const unsigned char *buf, int pos)
+{
+	int i;
+
+	hisi_ptt_4dw_print_dw0(buf, &pos);
+
+	for (i = HISI_PTT_4DW_HEAD1; i < HISI_PTT_4DW_TYPE_MAX; i++) {
+		buf += sizeof(uint32_t);
+		hisi_ptt_print_pkt(buf, &pos, hisi_ptt_4dw_pkt_field_name[i]);
+	}
+
+	return HISI_PTT_4DW_PKT_SIZE;
+}
+
+int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, enum hisi_ptt_pkt_type type)
+{
+	if (type == HISI_PTT_8DW_PKT)
+		return hisi_ptt_8dw_kpt_desc(buf, pos);
+
+	return hisi_ptt_4dw_kpt_desc(buf, pos);
+}
diff --git a/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
new file mode 100644
index 000000000000..20c51f230cac
--- /dev/null
+++ b/tools/perf/util/hisi-ptt-decoder/hisi-ptt-pkt-decoder.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * HiSilicon PCIe Trace and Tuning (PTT) support
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ */
+
+#ifndef INCLUDE__HISI_PTT_PKT_DECODER_H__
+#define INCLUDE__HISI_PTT_PKT_DECODER_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define HISI_PTT_PKT_DESC_MAX		256
+#define HISI_PTT_NEED_MORE_BYTES	-1
+#define HISI_PTT_8DW_CHECK_MASK		GENMASK(31, 11)
+#define HISI_PTT_IS_8DW_PKT		GENMASK(31, 11)
+#define HISI_PTT_8DW_PKT_SIZE		32
+#define HISI_PTT_4DW_PKT_SIZE		16
+#define HISI_PTT_MAX_SPACE_LEN		10
+
+enum hisi_ptt_pkt_type {
+	HISI_PTT_4DW_PKT,
+	HISI_PTT_8DW_PKT,
+};
+
+int hisi_ptt_pkt_desc(const unsigned char *buf, int pos, enum hisi_ptt_pkt_type type);
+
+#endif
diff --git a/tools/perf/util/hisi_ptt.c b/tools/perf/util/hisi_ptt.c
new file mode 100644
index 000000000000..75fa89f3fae3
--- /dev/null
+++ b/tools/perf/util/hisi_ptt.c
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HiSilicon PCIe Trace and Tuning (PTT) support
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ */
+
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/types.h>
+#include <linux/zalloc.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "auxtrace.h"
+#include "color.h"
+#include "debug.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "hisi_ptt.h"
+#include "hisi-ptt-decoder/hisi-ptt-pkt-decoder.h"
+#include "machine.h"
+#include "session.h"
+#include "symbol.h"
+#include "tool.h"
+#include "util/synthetic-events.h"
+
+struct hisi_ptt {
+	struct auxtrace auxtrace;
+	struct auxtrace_queues queues;
+	u32 auxtrace_type;
+	struct perf_session *session;
+	struct machine *machine;
+	u32 pmu_type;
+};
+
+struct hisi_ptt_queue {
+	struct hisi_ptt *ptt;
+	struct auxtrace_buffer *buffer;
+};
+
+static enum hisi_ptt_pkt_type hisi_ptt_check_packet_type(unsigned char *buf)
+{
+	uint32_t head = *(uint32_t *)buf;
+
+	if ((HISI_PTT_8DW_CHECK_MASK & head) == HISI_PTT_IS_8DW_PKT)
+		return HISI_PTT_8DW_PKT;
+
+	return HISI_PTT_4DW_PKT;
+}
+
+static void hisi_ptt_dump(struct hisi_ptt *ptt __maybe_unused,
+			  unsigned char *buf, size_t len)
+{
+	const char *color = PERF_COLOR_BLUE;
+	enum hisi_ptt_pkt_type type;
+	size_t pos = 0;
+	int pkt_len;
+
+	color_fprintf(stdout, color, ". ... HISI PTT data: size %zu bytes\n",
+		      len);
+
+	type = hisi_ptt_check_packet_type(buf);
+	while (len) {
+		pkt_len = hisi_ptt_pkt_desc(buf, pos, type);
+		if (!pkt_len)
+			color_fprintf(stdout, color, " Bad packet!\n");
+
+		pos += pkt_len;
+		buf += pkt_len;
+		len -= pkt_len;
+	}
+}
+
+static void hisi_ptt_dump_event(struct hisi_ptt *ptt, unsigned char *buf,
+				size_t len)
+{
+	printf(".\n");
+
+	hisi_ptt_dump(ptt, buf, len);
+}
+
+static int hisi_ptt_process_event(struct perf_session *session __maybe_unused,
+				  union perf_event *event __maybe_unused,
+				  struct perf_sample *sample __maybe_unused,
+				  struct perf_tool *tool __maybe_unused)
+{
+	return 0;
+}
+
+static int hisi_ptt_process_auxtrace_event(struct perf_session *session,
+					   union perf_event *event,
+					   struct perf_tool *tool __maybe_unused)
+{
+	struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt,
+					    auxtrace);
+	struct auxtrace_buffer *buffer;
+	off_t data_offset;
+	int fd = perf_data__fd(session->data);
+	int err;
+
+	if (perf_data__is_pipe(session->data)) {
+		data_offset = 0;
+	} else {
+		data_offset = lseek(fd, 0, SEEK_CUR);
+		if (data_offset == -1)
+			return -errno;
+	}
+
+	err = auxtrace_queues__add_event(&ptt->queues, session, event,
+					 data_offset, &buffer);
+	if (err)
+		return err;
+
+	if (dump_trace) {
+		if (auxtrace_buffer__get_data(buffer, fd)) {
+			hisi_ptt_dump_event(ptt, buffer->data, buffer->size);
+			auxtrace_buffer__put_data(buffer);
+		}
+	}
+
+	return 0;
+}
+
+static int hisi_ptt_flush(struct perf_session *session __maybe_unused,
+			  struct perf_tool *tool __maybe_unused)
+{
+	return 0;
+}
+
+static void hisi_ptt_free_queue(void *priv)
+{
+	struct hisi_ptt_queue *pttq = priv;
+
+	if (!pttq)
+		return;
+
+	free(pttq);
+}
+
+static void hisi_ptt_free_events(struct perf_session *session)
+{
+	struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt,
+					    auxtrace);
+	struct auxtrace_queues *queues = &ptt->queues;
+	unsigned int i;
+
+	for (i = 0; i < queues->nr_queues; i++) {
+		hisi_ptt_free_queue(queues->queue_array[i].priv);
+		queues->queue_array[i].priv = NULL;
+	}
+	auxtrace_queues__free(queues);
+}
+
+static void hisi_ptt_free(struct perf_session *session)
+{
+	struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt,
+					    auxtrace);
+
+	hisi_ptt_free_events(session);
+	session->auxtrace = NULL;
+	free(ptt);
+}
+
+static bool hisi_ptt_evsel_is_auxtrace(struct perf_session *session,
+				       struct evsel *evsel)
+{
+	struct hisi_ptt *ptt = container_of(session->auxtrace, struct hisi_ptt, auxtrace);
+
+	return evsel->core.attr.type == ptt->pmu_type;
+}
+
+static const char * const hisi_ptt_info_fmts[] = {
+	[HISI_PTT_PMU_TYPE]		= "  PMU Type           %" PRId64 "\n",
+};
+
+static void hisi_ptt_print_info(__u64 *arr)
+{
+	if (!dump_trace)
+		return;
+
+	fprintf(stdout, hisi_ptt_info_fmts[HISI_PTT_PMU_TYPE], arr[HISI_PTT_PMU_TYPE]);
+}
+
+int hisi_ptt_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session)
+{
+	struct perf_record_auxtrace_info *auxtrace_info = &event->auxtrace_info;
+	struct hisi_ptt *ptt;
+	int err;
+
+	if (auxtrace_info->header.size < HISI_PTT_AUXTRACE_PRIV_SIZE +
+				sizeof(struct perf_record_auxtrace_info))
+		return -EINVAL;
+
+	ptt = zalloc(sizeof(struct hisi_ptt));
+	if (!ptt)
+		return -ENOMEM;
+
+	err = auxtrace_queues__init(&ptt->queues);
+	if (err)
+		goto err_free;
+
+	ptt->session = session;
+	ptt->machine = &session->machines.host; /* No kvm support */
+	ptt->auxtrace_type = auxtrace_info->type;
+	ptt->pmu_type = auxtrace_info->priv[HISI_PTT_PMU_TYPE];
+
+	ptt->auxtrace.process_event = hisi_ptt_process_event;
+	ptt->auxtrace.process_auxtrace_event = hisi_ptt_process_auxtrace_event;
+	ptt->auxtrace.flush_events = hisi_ptt_flush;
+	ptt->auxtrace.free_events = hisi_ptt_free_events;
+	ptt->auxtrace.free = hisi_ptt_free;
+	ptt->auxtrace.evsel_is_auxtrace = hisi_ptt_evsel_is_auxtrace;
+	session->auxtrace = &ptt->auxtrace;
+
+	hisi_ptt_print_info(&auxtrace_info->priv[0]);
+
+	return 0;
+
+err_free:
+	free(ptt);
+	return err;
+}
diff --git a/tools/perf/util/hisi_ptt.h b/tools/perf/util/hisi_ptt.h
new file mode 100644
index 000000000000..c0b6cbde1221
--- /dev/null
+++ b/tools/perf/util/hisi_ptt.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * HiSilicon PCIe Trace and Tuning (PTT) support
+ * Copyright (c) 2022 HiSilicon Technologies Co., Ltd.
+ */
+
+#ifndef INCLUDE__PERF_HISI_PTT_H__
+#define INCLUDE__PERF_HISI_PTT_H__
+
+#define HISI_PTT_PMU_NAME "hisi_ptt"
+enum {
+	HISI_PTT_PMU_TYPE,
+	HISI_PTT_PER_CPU_MMAPS,
+	HISI_PTT_AUXTRACE_PRIV_MAX,
+};
+
+#define HISI_PTT_AUXTRACE_PRIV_SIZE (HISI_PTT_AUXTRACE_PRIV_MAX * sizeof(u64))
+union perf_event;
+struct perf_session;
+struct perf_pmu;
+
+struct auxtrace_record *hisi_ptt_recording_init(int *err,
+						struct perf_pmu *hisi_ptt_pmu);
+
+int hisi_ptt_process_auxtrace_info(union perf_event *event,
+				   struct perf_session *session);
+
+#endif
-- 
2.24.0



From henrik at grimler.se  Mon Jan 24 05:12:39 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Mon, 24 Jan 2022 14:12:39 +0100
Subject: [PATCH 0/2] ARM: dts: exynos: Add support for Samsung Klimt WiFi
Message-ID: <20220124131241.29946-1-henrik@grimler.se>

Klimt WiFi has product name Samsung Galaxy Tab S 8.4" and was released
in 2014.  It has similar hardware to exynos5420-chagall-wifi and the
two devices can hence share a common base dtsi. 

Same issues as for Chagall Wifi applies: CCI has to be disabled and
only 4 out of 8 CPUs are brought up at boot (see
https://lore.kernel.org/r/20220118185746.299832-4-henrik at grimler.se).

Henrik Grimler (2):
  dt-bindings: arm: samsung: document Klimt WiFi board binding
  ARM: dts: Add support for Samsung Klimt WiFi

 .../bindings/arm/samsung/samsung-boards.yaml  |  1 +
 arch/arm/boot/dts/Makefile                    |  1 +
 arch/arm/boot/dts/exynos5420-klimt-wifi.dts   | 75 +++++++++++++++++++
 3 files changed, 77 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-klimt-wifi.dts


base-commit: e758cdb29e81cee1d53e1a06bb3db0a32fc8c347
-- 
2.34.1



From henrik at grimler.se  Mon Jan 24 05:12:41 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Mon, 24 Jan 2022 14:12:41 +0100
Subject: [PATCH 2/2] ARM: dts: exynos: Add support for Samsung Klimt WiFi
In-Reply-To: <20220124131241.29946-1-henrik@grimler.se>
References: <20220124131241.29946-1-henrik@grimler.se>
Message-ID: <20220124131241.29946-3-henrik@grimler.se>

Klimt WiFi has the product name Samsung Galaxy Tab S 8.4".  Board is
based on Exynos 5420, and has similar hardware to Chagall WiFi, but
with a smaller battery, smaller screen and another touchscreen
controller.

The device tree added here contains support for:

- UART access through a micro-usb cable with 619 kOhm between ID & GND
- Accessing the internal eMMC storage
- Accessing an external SD card
- USB, after configuration it is possible to ssh into the device
  through a usb cable

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 arch/arm/boot/dts/Makefile                  |  1 +
 arch/arm/boot/dts/exynos5420-klimt-wifi.dts | 75 +++++++++++++++++++++
 2 files changed, 76 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5420-klimt-wifi.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 28fbfda94cb9..21c4a3ad068a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -222,6 +222,7 @@ dtb-$(CONFIG_ARCH_EXYNOS5) += \
 	exynos5420-peach-pit.dtb \
 	exynos5420-smdk5420.dtb \
 	exynos5420-chagall-wifi.dtb \
+	exynos5420-klimt-wifi.dtb \
 	exynos5422-odroidhc1.dtb \
 	exynos5422-odroidxu3.dtb \
 	exynos5422-odroidxu3-lite.dtb \
diff --git a/arch/arm/boot/dts/exynos5420-klimt-wifi.dts b/arch/arm/boot/dts/exynos5420-klimt-wifi.dts
new file mode 100644
index 000000000000..011787b1bbf0
--- /dev/null
+++ b/arch/arm/boot/dts/exynos5420-klimt-wifi.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Samsung's Exynos5420 Klimt WiFi board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ * Copyright (c) 2022 Henrik Grimler
+ */
+
+/dts-v1/;
+#include "exynos5420-galaxy-tab-common.dtsi"
+
+/ {
+	model = "Samsung Klimt WiFi based on Exynos5420";
+	compatible = "samsung,klimt-wifi", "samsung,exynos5420", \
+		     "samsung,exynos5";
+};
+
+&ldo15_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO15";
+	regulator-min-microvolt = <3300000>;
+	regulator-max-microvolt = <3300000>;
+};
+
+&ldo17_reg {
+	regulator-name = "VDD_VCI_3V0";
+	regulator-min-microvolt = <3000000>;
+	regulator-max-microvolt = <3000000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo28_reg {
+	regulator-name = "VDD3_1V8";
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo29_reg {
+	regulator-name = "VDDR_1V6";
+	regulator-min-microvolt = <1600000>;
+	regulator-max-microvolt = <1600000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&ldo31_reg {
+	/* Unused */
+	regulator-name = "VDD_LDO31";
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+};
+
+&ldo32_reg {
+	regulator-name = "VDD_TSP_1V8";
+	regulator-min-microvolt = <1800000>;
+	regulator-max-microvolt = <1800000>;
+
+	regulator-state-mem {
+		regulator-off-in-suspend;
+	};
+};
+
+&mmc_2 {
+	sd-uhs-sdr104;
+};
-- 
2.34.1



From henrik at grimler.se  Mon Jan 24 05:12:40 2022
From: henrik at grimler.se (Henrik Grimler)
Date: Mon, 24 Jan 2022 14:12:40 +0100
Subject: [PATCH 1/2] dt-bindings: arm: samsung: document Klimt WiFi board
 binding
In-Reply-To: <20220124131241.29946-1-henrik@grimler.se>
References: <20220124131241.29946-1-henrik@grimler.se>
Message-ID: <20220124131241.29946-2-henrik@grimler.se>

Add binding for Galaxy Tab S 8.4", based on Exynos 5420 with codename
klimt-wifi.

Signed-off-by: Henrik Grimler <henrik at grimler.se>
---
 .../devicetree/bindings/arm/samsung/samsung-boards.yaml          | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
index a2a8bf44fe9b..faea33e4f731 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -141,6 +141,7 @@ properties:
           - enum:
               - insignal,arndale-octa           # Insignal Arndale Octa
               - samsung,chagall-wifi            # Samsung SM-T800
+              - samsung,klimt-wifi              # Samsung SM-T700
               - samsung,smdk5420                # Samsung SMDK5420 eval
           - const: samsung,exynos5420
           - const: samsung,exynos5
-- 
2.34.1



From andrew at lunn.ch  Mon Jan 24 05:15:23 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Mon, 24 Jan 2022 14:15:23 +0100
Subject: [PATCH net 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <20220124095951.23845-3-mohammad.athari.ismail@intel.com>
References: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
 <20220124095951.23845-3-mohammad.athari.ismail@intel.com>
Message-ID: <Ye6maxMtt68JlZ9l@lunn.ch>

> @@ -3308,13 +3309,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>  
>  	stmmac_mmc_setup(priv);
>  
> -	if (init_ptp) {
> -		ret = stmmac_init_ptp(priv);
> -		if (ret == -EOPNOTSUPP)
> -			netdev_warn(priv->dev, "PTP not supported by HW\n");
> -		else if (ret)
> -			netdev_warn(priv->dev, "PTP init failed\n");
> -	}
> +	ret = stmmac_init_ptp(priv, ptp_register);
> +	if (ret == -EOPNOTSUPP)
> +		netdev_warn(priv->dev, "PTP not supported by HW\n");
> +	else if (ret)
> +		netdev_warn(priv->dev, "PTP init failed\n");

The init_ptp parameter now seems unused? If so, please remove it.

    Andrew


From broonie at kernel.org  Mon Jan 24 05:18:56 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 13:18:56 +0000
Subject: [PATCH V3 1/2] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <20220124061238.7854-2-leilk.liu@mediatek.com>
References: <20220124061238.7854-1-leilk.liu@mediatek.com>
 <20220124061238.7854-2-leilk.liu@mediatek.com>
Message-ID: <Ye6nQIVoti5TKh+k@sirena.org.uk>

On Mon, Jan 24, 2022 at 02:12:37PM +0800, Leilk Liu wrote:
> Convert Mediatek ARM SOC's SPI Master controller binding
> to json-schema format.

Please make any YAML conversion patches the last patches in a series -
there's frequently a backlog in reviewing them so having the DT binding
patches first blocks any progress on everything else in the series.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/b740f348/attachment.sig>

From alexandru.elisei at arm.com  Mon Jan 24 05:36:32 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Mon, 24 Jan 2022 13:36:32 +0000
Subject: [BUG] rockpro64-v2: NULL pointer dereference when booting
In-Reply-To: <Ye6X0lgBBsk4Sd1X@kuha.fi.intel.com>
References: <Ye6S1PBAHtWj1lRp@monolith.localdoman>
 <Ye6X0lgBBsk4Sd1X@kuha.fi.intel.com>
Message-ID: <Ye6rYLzRXZHdjJul@monolith.localdoman>

Hi,

On Mon, Jan 24, 2022 at 02:13:06PM +0200, Heikki Krogerus wrote:
> On Mon, Jan 24, 2022 at 11:51:48AM +0000, Alexandru Elisei wrote:
> > Hi,
> > 
> > When booting a rockpro64-v2 with a kernel built from commit dd81e1c7d5fb
> > ("Merge tag 'powerpc-5.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux"),
> > which was the latest commit when ran the tests, I encounter a NULL pointer
> > dereference:
> > 
> > [..]
> > [    0.000000] Kernel command line: root=PARTUUID=7f4aab92-69d8-47f3-be10-624da40a71f9 rw earlycon rootwait
> > [..]
> > [    3.396944] hub 7-0:1.0: USB hub found
> > [    3.397575] hub 7-0:1.0: 1 port detected
> > [    3.406086] ohci-platform fe3e0000.usb: Generic Platform OHCI controller
> > [    3.406932] ohci-platform fe3e0000.usb: new USB bus registered, assigned bus number 8
> > [    3.408530] ohci-platform fe3e0000.usb: irq 38, io mem 0xfe3e0000
> > [    3.476869] hub 8-0:1.0: USB hub found
> > [    3.477501] hub 8-0:1.0: 1 port detected
> > [    3.483278] rk808 0-001b: chip id: 0x0
> > [    3.498495] random: fast init done
> > [    3.509322] rk808-regulator rk808-regulator: there is no dvs0 gpio
> > [    3.510143] rk808-regulator rk808-regulator: there is no dvs1 gpio
> > [    3.569278] OF: graph: no port node found in /i2c at ff3d0000/typec-portc at 22
> > [    3.573471] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
> > [    3.574466] Mem abort info:
> > [    3.574800]   ESR = 0x96000004
> > [    3.575163]   EC = 0x25: DABT (current EL), IL = 32 bits
> > [    3.575770]   SET = 0, FnV = 0
> > [    3.576204]   EA = 0, S1PTW = 0
> > [    3.576580]   FSC = 0x04: level 0 translation fault
> > [    3.577140] Data abort info:
> > [    3.577482]   ISV = 0, ISS = 0x00000004
> > [    3.577927]   CM = 0, WnR = 0
> > [    3.578279] [0000000000000000] user address but active_mm is swapper
> > [    3.579065] Internal error: Oops: 96000004 [#1] PREEMPT SMP
> > [    3.579586] Modules linked in:
> > [    3.579880] CPU: 5 PID: 7 Comm: kworker/u12:0 Not tainted 5.16.0-rc6-00081-g730b49aac426 #244
> > [    3.580667] Hardware name: Pine64 RockPro64 v2.0 (DT)
> > [    3.581135] Workqueue: events_unbound deferred_probe_work_func
> > [    3.581689] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [    3.582335] pc : component_master_add_with_match+0x20/0xfc
> > [    3.582850] lr : typec_link_ports+0x58/0x8c
> > [    3.583244] sp : ffff800013093980
> > [    3.583553] x29: ffff800013093980 x28: ffff80001212b000 x27: ffff00000041d00d
> > [    3.584223] x26: ffff0000063e85e0 x25: ffff800012fcb290 x24: ffff000001386820
> > [    3.584891] x23: ffff000006c2e808 x22: ffff800011416670 x21: ffff000006c2e808
> > [    3.585558] x20: 0000000000000000 x19: ffff000006c2e800 x18: ffffffffffffffff
> > [    3.586224] x17: 000000040044ffff x16: 00400034b5503510 x15: 0000000000005ff9
> > [    3.586890] x14: 0000000000000000 x13: 0000000000000003 x12: ffff0000063e8080
> > [    3.587557] x11: 0000000000000005 x10: ffff800012c13a60 x9 : 0000000000000000
> > [    3.588224] x8 : 0000200000000000 x7 : 0000000000000038 x6 : 000000000000004b
> > [    3.588892] x5 : 0000000000000000 x4 : ffff000000711800 x3 : ffff800010cd6390
> > [    3.589558] x2 : 0000000000000000 x1 : ffff800011416670 x0 : ffff000006c2e808
> > [    3.590224] Call trace:
> > [    3.590457]  component_master_add_with_match+0x20/0xfc
> > [    3.590938]  typec_link_ports+0x58/0x8c
> > [    3.591299]  typec_register_port+0x1ac/0x300
> > [    3.591705]  tcpm_register_port+0x62c/0x90c
> > [    3.592099]  fusb302_probe+0x260/0x430
> > [    3.592453]  i2c_device_probe+0x338/0x370
> > [    3.592835]  really_probe.part.0+0x9c/0x30c
> > [    3.593229]  __driver_probe_device+0x98/0x144
> > [    3.593639]  driver_probe_device+0xc8/0x160
> > [    3.594033]  __device_attach_driver+0xb8/0x120
> > [    3.594450]  bus_for_each_drv+0x78/0xd0
> > [    3.594810]  __device_attach+0xd8/0x180
> > [    3.595171]  device_initial_probe+0x14/0x20
> > [    3.595565]  bus_probe_device+0x9c/0xa4
> > [    3.595926]  deferred_probe_work_func+0x88/0xc4
> > [    3.596351]  process_one_work+0x288/0x6e0
> > [    3.596729]  worker_thread+0x220/0x464
> > [    3.597081]  kthread+0x17c/0x190
> > [    3.597392]  ret_from_fork+0x10/0x20
> > [    3.597737] Code: aa0203f4 a9025bf5 aa0003f5 aa0103f6 (a9400440) 
> > [    3.598301] ---[ end trace 823a8d1795013b55 ]---
> > 
> > The full log can be found at [1]; config file can be found at [2]. All
> > pastebins expire after 6 months.
> > 
> > I tried bisecting the bug and the first bad commit is 730b49aac426 ("usb:
> > typec: port-mapper: Convert to the component framework"). I tried to double
> > check that the patch is indeed responsible by reverting it from master, but
> > I got this build error:
> > 
> > drivers/usb/typec/port-mapper.c: In function 'typec_link_ports':
> > drivers/usb/typec/port-mapper.c:256:15: error: implicit declaration of function 'usb_for_each_port'; did you mean 'usb_for_each_dev'? [-Werror=implicit-function-declaration]
> >   256 |         ret = usb_for_each_port(&con->dev, each_port);
> >       |               ^~~~~~~~~~~~~~~~~
> >       |               usb_for_each_dev
> > 
> > I tried building and booting from the bad commit, and I got the same NULL
> > pointer dereference error. When building from the last good commit
> > (8c67d06f3fd9 ("usb: Link the ports to the connectors they are attached
> > to")), the board boots just fine. The log when booting from the good commit
> > can be found at [3].
> > 
> > I can help with debugging and testing, but I'm not familiar enough with the
> > USB subsystem to fix it myself.
> > 
> > [1] https://pastebin.com/w4tMNhve
> > [2] https://pastebin.com/SiUuLeMs
> > [3] https://pastebin.com/Pcm9xmL7
> 
> There is already a fix pending:
> https://lore.kernel.org/linux-usb/20220124090228.41396-3-heikki.krogerus at linux.intel.com/

Applied the patch, I can confirm that my rockpro64 is now booting. Thank
you for the patch!

Thanks,
Alex


From patchwork-bot+netdevbpf at kernel.org  Mon Jan 24 05:40:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Mon, 24 Jan 2022 13:40:10 +0000
Subject: [PATCH] net: stmmac: remove unused members in struct stmmac_priv
In-Reply-To: <20220123122758.2876-1-jszhang@kernel.org>
References: <20220123122758.2876-1-jszhang@kernel.org>
Message-ID: <164303161069.21877.8559780902897550675.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Sun, 23 Jan 2022 20:27:58 +0800 you wrote:
> The tx_coalesce and mii_irq are not used at all now, so remove them.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 --
>  1 file changed, 2 deletions(-)

Here is the summary with links:
  - net: stmmac: remove unused members in struct stmmac_priv
    https://git.kernel.org/netdev/net/c/de8a820df2ac

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From semen.protsenko at linaro.org  Mon Jan 24 05:50:41 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Mon, 24 Jan 2022 15:50:41 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <72a50afd-df9f-ceb3-898e-070d70dc0221@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
 <CAPLW+4k8=ymx56R7bKOt8kMVG_uUgrTsCkVd5wiY_rkYq8dYbQ@mail.gmail.com>
 <72a50afd-df9f-ceb3-898e-070d70dc0221@canonical.com>
Message-ID: <CAPLW+4=xaHA2a=-F4ikuUPDpoO8Waj7qrrfpgkift1aMi_hU+g@mail.gmail.com>

On Sun, 23 Jan 2022 at 21:27, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 22/01/2022 13:38, Sam Protsenko wrote:
> > On Wed, 19 Jan 2022 at 18:53, Olof Johansson <olof at lixom.net> wrote:
> >>
> >> On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
> >>>
> >>> On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
> >>> <semen.protsenko at linaro.org> wrote:
> >>>> On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
> >>>>
> >>>> Hi Olof, Arnd,
> >>>>
> >>>> Just want to check if it's possible for those patches to be applied in
> >>>> v5.17? Sorry for the noise, but that's important to me.
> >>>
> >>> I can see that Olof merged merged this into the "arm/late" branch in
> >>> the soc tree,
> >>> so I assume he still plans to send it in the next few days.
> >>
> >> Yep, will be sent up today most likely.
> >>
> >
> > Thanks for detailed answer! Glad to hear it's still a possibility.
> > Please let me know if you need any actions on my side (like rebasing,
> > etc).
> >
> >>> With the timing over Christmas, I sent out the large bulk of the
> >>> contents (anything
> >>> I merged before Dec 23) last year, and Linus already merged it, the rest ended
> >>> up in the "late" branch.
> >>>
> >>> As usual, there is no guarantee that late changes make it in, but I have seen
> >>> no indication of any problems so far.
> >>
> >> Correct. Been sitting on it for a while in case there were fixes
> >> coming in for the first pieces that got merged, but in traditional
> >> fashion I'm guessing those will start to show up a few days after the
> >> late branch gets merged. :)
>
> Olof,
> v5.17-rc1 came earlier, so I see this part did not make into it. Is
> there a chance for a past-rc1 pull to Linus with it?
>
> Sam,
> Anyway the patches wont' get lost (you mentioned such worry in previous
> email to me). They might just need to wait. Unfortunately if patch,
> especially with new feature, is coming in the end of cycle, there is a
> risk it won't make it. The patches have to wait a few days in my trees
> before I send them to Arnd/Olof, so if the patch is coming after rc6, I
> can push it to Arnd/Olof around rc7, you see there is very little time.
>

Should I send the patch fixing hard-coded clock numbers though? I
remember you said I should send it once -rc1 is out. But now that dts
patches are not merged in mainline, I'm not sure it can still be
applied?

> Best regards,
> Krzysztof


From mhocko at suse.com  Mon Jan 24 06:01:47 2022
From: mhocko at suse.com (Michal Hocko)
Date: Mon, 24 Jan 2022 15:01:47 +0100
Subject: [PATCH v6 6/9] mm: multigenerational lru: aging
In-Reply-To: <Ye3IfmZGwNYSCgV6@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <20220104202227.2903605-7-yuzhao@google.com>
 <YdhR4vWdWksBALtM@dhcp22.suse.cz> <Ydu6fXg2FmrseQOn@google.com>
 <YdwQcl6D5Mbp9Z4h@dhcp22.suse.cz> <Yee36hPfWSs+jR0m@google.com>
 <YefdFwcoX4+ZcDSY@dhcp22.suse.cz> <Ye3IfmZGwNYSCgV6@google.com>
Message-ID: <Ye6xS6xUD1SORdHJ@dhcp22.suse.cz>

On Sun 23-01-22 14:28:30, Yu Zhao wrote:
> On Wed, Jan 19, 2022 at 10:42:47AM +0100, Michal Hocko wrote:
> > On Wed 19-01-22 00:04:10, Yu Zhao wrote:
> > > On Mon, Jan 10, 2022 at 11:54:42AM +0100, Michal Hocko wrote:
> > > > On Sun 09-01-22 21:47:57, Yu Zhao wrote:
> > > > > On Fri, Jan 07, 2022 at 03:44:50PM +0100, Michal Hocko wrote:
> > > > > > On Tue 04-01-22 13:22:25, Yu Zhao wrote:
> > > > > > [...]
> > > > > > > +static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_mm_walk *walk)
> > > > > > > +{
> > > > > > > +	static const struct mm_walk_ops mm_walk_ops = {
> > > > > > > +		.test_walk = should_skip_vma,
> > > > > > > +		.p4d_entry = walk_pud_range,
> > > > > > > +	};
> > > > > > > +
> > > > > > > +	int err;
> > > > > > > +#ifdef CONFIG_MEMCG
> > > > > > > +	struct mem_cgroup *memcg = lruvec_memcg(lruvec);
> > > > > > > +#endif
> > > > > > > +
> > > > > > > +	walk->next_addr = FIRST_USER_ADDRESS;
> > > > > > > +
> > > > > > > +	do {
> > > > > > > +		unsigned long start = walk->next_addr;
> > > > > > > +		unsigned long end = mm->highest_vm_end;
> > > > > > > +
> > > > > > > +		err = -EBUSY;
> > > > > > > +
> > > > > > > +		rcu_read_lock();
> > > > > > > +#ifdef CONFIG_MEMCG
> > > > > > > +		if (memcg && atomic_read(&memcg->moving_account))
> > > > > > > +			goto contended;
> > > > > > > +#endif
> > > > > > > +		if (!mmap_read_trylock(mm))
> > > > > > > +			goto contended;
> > > > > > 
> > > > > > Have you evaluated the behavior under mmap_sem contention? I mean what
> > > > > > would be an effect of some mms being excluded from the walk? This path
> > > > > > is called from direct reclaim and we do allocate with exclusive mmap_sem
> > > > > > IIRC and the trylock can fail in a presence of pending writer if I am
> > > > > > not mistaken so even the read lock holder (e.g. an allocation from the #PF)
> > > > > > can bypass the walk.
> > > > > 
> > > > > You are right. Here it must be a trylock; otherwise it can deadlock.
> > > > 
> > > > Yeah, this is clear.
> > > > 
> > > > > I think there might be a misunderstanding: the aging doesn't
> > > > > exclusively rely on page table walks to gather the accessed bit. It
> > > > > prefers page table walks but it can also fallback to the rmap-based
> > > > > function, i.e., lru_gen_look_around(), which only gathers the accessed
> > > > > bit from at most 64 PTEs and therefore is less efficient. But it still
> > > > > retains about 80% of the performance gains.
> > > > 
> > > > I have to say that I really have hard time to understand the runtime
> > > > behavior depending on that interaction. How does the reclaim behave when
> > > > the virtual scan is enabled, partially enabled and almost completely
> > > > disabled due to different constrains? I do not see any such an
> > > > evaluation described in changelogs and I consider this to be a rather
> > > > important information to judge the overall behavior.
> > > 
> > > It doesn't have (partially) enabled/disabled states nor does its
> > > behavior change with different reclaim constraints. Having either
> > > would make its design too complex to implement or benchmark.
> > 
> > Let me clarify. By "partially enabled" I really meant behavior depedning
> > on runtime conditions. Say mmap_sem cannot be locked for half of scanned
> > tasks and/or allocation for the mm walker fails due to lack of memory.
> > How does this going to affect reclaim efficiency.
> 
> Understood. This is not only possible -- it's the default for our ARM
> hardware that doesn't support the accessed bit, i.e., CPUs that don't
> automatically set the accessed bit.
> 
> In try_to_inc_max_seq(), we have:
>     /*
>      * If the hardware doesn't automatically set the accessed bit, fallback
>      * to lru_gen_look_around(), which only clears the accessed bit in a
>      * handful of PTEs. Spreading the work out over a period of time usually
>      * is less efficient, but it avoids bursty page faults.
>      */
>     if the accessed bit is not supported
>         return
> 
>     if alloc_mm_walk() fails
>         return
> 
>     walk_mm()
>         if mmap_sem contented
>             return
> 
>         scan page tables
> 
> We have a microbenchmark that specifically measures this worst case
> scenario by entirely disabling page table scanning. Its results showed
> that this still retains more than 90% of the optimal performance. I'll
> share this microbenchmark in another email when answering Barry's
> questions regarding the accessed bit.
> 
> Our profiling infra also indirectly confirms this: it collects data
> from real users running on hardware with and without the accessed
> bit. Users running on hardware without the accessed bit indeed suffer
> a small performance degradation, compared with users running on
> hardware with it. But they still benefit almost as much, compared with
> users running on the same hardware but without MGLRU.

This definitely a good information to have in the cover letter.

> > How does a user/admin
> > know that the memory reclaim is in a "degraded" mode because of the
> > contention?
> 
> As we previously discussed here:
> https://lore.kernel.org/linux-mm/Ydu6fXg2FmrseQOn at google.com/
> there used to be a counter measuring the contention, and it was deemed
> unnecessary and removed in v4. But I don't have a problem if we want
> to revive it.

Well, counter might be rather tricky but few trace points would make some
sense to me.

-- 
Michal Hocko
SUSE Labs


From maz at kernel.org  Mon Jan 24 06:05:27 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 14:05:27 +0000
Subject: [RFC V1 02/11] arm64/perf: Add register definitions for BRBE
In-Reply-To: <1642998653-21377-3-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-3-git-send-email-anshuman.khandual@arm.com>
Message-ID: <877dap8c0o.wl-maz@kernel.org>

On Mon, 24 Jan 2022 04:30:44 +0000,
Anshuman Khandual <anshuman.khandual at arm.com> wrote:
> 
> This adds BRBE related register definitions and various other related field
> macros there in. These will be used subsequently in a BRBE driver which is
> being added later on.
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Marc Zyngier <maz at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/include/asm/sysreg.h | 216 ++++++++++++++++++++++++++++++++
>  1 file changed, 216 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 898bee0004ae..d8fd7e806a47 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -141,6 +141,218 @@
>  #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
>  #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
>  
> +/*
> + * BRBINF<N>_EL1 Encoding: [2, 1, 8, CRm, op2]
> + *
> + * derived as <CRm> = c{N<3:0>} <op2> = (N<4>x4 + 0)
> + */
> +#define SYS_BRBINF0_EL1			sys_reg(2, 1, 8, 0, 0)
> +#define SYS_BRBINF1_EL1			sys_reg(2, 1, 8, 1, 0)
> +#define SYS_BRBINF2_EL1			sys_reg(2, 1, 8, 2, 0)
> +#define SYS_BRBINF3_EL1			sys_reg(2, 1, 8, 3, 0)
> +#define SYS_BRBINF4_EL1			sys_reg(2, 1, 8, 4, 0)
> +#define SYS_BRBINF5_EL1			sys_reg(2, 1, 8, 5, 0)
> +#define SYS_BRBINF6_EL1			sys_reg(2, 1, 8, 6, 0)
> +#define SYS_BRBINF7_EL1			sys_reg(2, 1, 8, 7, 0)
> +#define SYS_BRBINF8_EL1			sys_reg(2, 1, 8, 8, 0)
> +#define SYS_BRBINF9_EL1			sys_reg(2, 1, 8, 9, 0)

[snip]

Since the architecture gives you the formula to build these, why do
you enumerate each and every register encoding? I'd rather see
something like:

#define __SYS_BRBINFO(n) sys_reg(2, 1, 8, ((n) & 0xf), (((n) & 0x10)) >> 2)
#define SYS_BRBINF0_EL1	__SYS_BRBINFO(0)
[...]

and something similar for all the new registers that come in packs of
32... We already have similar things for AMU, PMU, GIC and co.

Thanks,

	M.


-- 
Without deviation from the norm, progress is not possible.


From alim.akhtar at samsung.com  Mon Jan 24 06:16:28 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:28 +0530
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
Message-ID: <20220124141644.71052-1-alim.akhtar@samsung.com>

Adds basic support for the Tesla Full Self-Driving (FSD)
SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
as well as several IPs.

Patches 1 to 9 provide support for the clock controller
(which is designed similarly to Exynos SoCs).

The remaining changes provide pinmux support, initial device tree support.

- Changes since v4
* fixed 'make dtbs_check' warnings on patch 14/16

- Changes since v3
* Addressed Stefen's review comments on patch 14/16
* Fixed kernel test robot warning on patch 04/16
* rebsaed this series on Krzysztof's pinmux new binding schema work [1]

- Changes since v2
* Addressed Krzysztof's and Stephen's review comments
* Added Reviewed-by and Acked-by tags
* Rebased on next-20220120

- Changes since v1
* fixed make dt_binding_check error as pointed by Rob
* Addressed Krzysztof's and Rob's review comments
* Added Reviewed-by and Acked-by tags
* Dropped SPI, MCT and ADC from this series (to be posted in small sets)

NOTE: These patches are based on Krzysztof's pinmux for-next branch
commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups") 
[1] https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/log/?h=for-next


Alim Akhtar (16):
  dt-bindings: add vendor prefix for Tesla
  dt-bindings: clock: Add bindings definitions for FSD CMU blocks
  dt-bindings: clock: Document FSD CMU bindings
  clk: samsung: fsd: Add initial clock support
  clk: samsung: fsd: Add cmu_peric block clock information
  clk: samsung: fsd: Add cmu_fsys0 clock information
  clk: samsung: fsd: Add cmu_fsys1 clock information
  clk: samsung: fsd: Add cmu_imem block clock information
  clk: samsung: fsd: Add cmu_mfc block clock information
  clk: samsung: fsd: Add cam_csi block clock information
  dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
  pinctrl: samsung: add FSD SoC specific data
  dt-bindings: arm: add Tesla FSD ARM SoC
  arm64: dts: fsd: Add initial device tree support
  arm64: dts: fsd: Add initial pinctrl support
  arm64: defconfig: Enable Tesla FSD SoC

 .../devicetree/bindings/arm/tesla.yaml        |   27 +
 .../bindings/clock/tesla,fsd-clock.yaml       |  198 ++
 .../bindings/pinctrl/samsung,pinctrl.yaml     |    1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |    2 +
 MAINTAINERS                                   |    8 +
 arch/arm64/Kconfig.platforms                  |    6 +
 arch/arm64/boot/dts/Makefile                  |    1 +
 arch/arm64/boot/dts/tesla/Makefile            |    3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts         |   39 +
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi    |  335 +++
 arch/arm64/boot/dts/tesla/fsd.dtsi            |  674 ++++++
 arch/arm64/configs/defconfig                  |    1 +
 drivers/clk/samsung/Kconfig                   |    8 +
 drivers/clk/samsung/Makefile                  |    1 +
 drivers/clk/samsung/clk-fsd.c                 | 1803 +++++++++++++++++
 drivers/clk/samsung/clk-pll.c                 |    1 +
 drivers/clk/samsung/clk-pll.h                 |    1 +
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    |   71 +
 drivers/pinctrl/samsung/pinctrl-samsung.c     |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |    1 +
 include/dt-bindings/clock/fsd-clk.h           |  150 ++
 21 files changed, 3333 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi
 create mode 100644 drivers/clk/samsung/clk-fsd.c
 create mode 100644 include/dt-bindings/clock/fsd-clk.h


base-commit: 832ae134ccc1c78a2f5ec81b7010dd24c3c49535
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:29 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:29 +0530
Subject: [PATCH v5 01/16] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142857epcas5p4af44b43ce57414ad6667c84753c36f16@epcas5p4.samsung.com>
Message-ID: <20220124141644.71052-2-alim.akhtar@samsung.com>

Add vendor prefix for the Tesla (https://www.tesla.com)

Cc: linux-fsd at tesla.com
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 294093d45a23..e7a362c17df7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1205,6 +1205,8 @@ patternProperties:
     description: Shenzhen Techstar Electronics Co., Ltd.
   "^terasic,.*":
     description: Terasic Inc.
+  "^tesla,.*":
+    description: Tesla, Inc.
   "^tfc,.*":
     description: Three Five Corp
   "^thead,.*":
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:30 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:30 +0530
Subject: [PATCH v5 02/16] dt-bindings: clock: Add bindings definitions for
 FSD CMU blocks
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142901epcas5p3776232af7911abfbf08d82358350f57c@epcas5p3.samsung.com>
Message-ID: <20220124141644.71052-3-alim.akhtar@samsung.com>

Clock controller driver of FSD platform is designed to have separate
instances for each particular CMU. So clock IDs in this bindings header
also start from 1 for each CMU block.

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
[robot: reported missing #endif]
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 include/dt-bindings/clock/fsd-clk.h | 150 ++++++++++++++++++++++++++++
 1 file changed, 150 insertions(+)
 create mode 100644 include/dt-bindings/clock/fsd-clk.h

diff --git a/include/dt-bindings/clock/fsd-clk.h b/include/dt-bindings/clock/fsd-clk.h
new file mode 100644
index 000000000000..c8a2af1dd1ad
--- /dev/null
+++ b/include/dt-bindings/clock/fsd-clk.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2017 - 2022: Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * The constants defined in this header are being used in dts
+ * and fsd platform driver.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_FSD_H
+#define _DT_BINDINGS_CLOCK_FSD_H
+
+/* CMU */
+#define DOUT_CMU_PLL_SHARED0_DIV4		1
+#define DOUT_CMU_PERIC_SHARED1DIV36		2
+#define DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK	3
+#define DOUT_CMU_PERIC_SHARED0DIV20		4
+#define DOUT_CMU_PERIC_SHARED1DIV4_DMACLK	5
+#define DOUT_CMU_PLL_SHARED0_DIV6		6
+#define DOUT_CMU_FSYS0_SHARED1DIV4		7
+#define DOUT_CMU_FSYS0_SHARED0DIV4		8
+#define DOUT_CMU_FSYS1_SHARED0DIV8		9
+#define DOUT_CMU_FSYS1_SHARED0DIV4		10
+#define CMU_CPUCL_SWITCH_GATE			11
+#define DOUT_CMU_IMEM_TCUCLK			12
+#define DOUT_CMU_IMEM_ACLK			13
+#define DOUT_CMU_IMEM_DMACLK			14
+#define GAT_CMU_FSYS0_SHARED0DIV4		15
+#define CMU_NR_CLK				16
+
+/* PERIC */
+#define PERIC_SCLK_UART0			1
+#define PERIC_PCLK_UART0			2
+#define PERIC_SCLK_UART1			3
+#define PERIC_PCLK_UART1			4
+#define PERIC_DMA0_IPCLKPORT_ACLK		5
+#define PERIC_DMA1_IPCLKPORT_ACLK		6
+#define PERIC_PWM0_IPCLKPORT_I_PCLK_S0		7
+#define PERIC_PWM1_IPCLKPORT_I_PCLK_S0		8
+#define PERIC_PCLK_SPI0                         9
+#define PERIC_SCLK_SPI0                         10
+#define PERIC_PCLK_SPI1                         11
+#define PERIC_SCLK_SPI1                         12
+#define PERIC_PCLK_SPI2                         13
+#define PERIC_SCLK_SPI2                         14
+#define PERIC_PCLK_TDM0                         15
+#define PERIC_PCLK_HSI2C0			16
+#define PERIC_PCLK_HSI2C1			17
+#define PERIC_PCLK_HSI2C2			18
+#define PERIC_PCLK_HSI2C3			19
+#define PERIC_PCLK_HSI2C4			20
+#define PERIC_PCLK_HSI2C5			21
+#define PERIC_PCLK_HSI2C6			22
+#define PERIC_PCLK_HSI2C7			23
+#define PERIC_MCAN0_IPCLKPORT_CCLK		24
+#define PERIC_MCAN0_IPCLKPORT_PCLK		25
+#define PERIC_MCAN1_IPCLKPORT_CCLK		26
+#define PERIC_MCAN1_IPCLKPORT_PCLK		27
+#define PERIC_MCAN2_IPCLKPORT_CCLK		28
+#define PERIC_MCAN2_IPCLKPORT_PCLK		29
+#define PERIC_MCAN3_IPCLKPORT_CCLK		30
+#define PERIC_MCAN3_IPCLKPORT_PCLK		31
+#define PERIC_PCLK_ADCIF			32
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I  33
+#define PERIC_EQOS_TOP_IPCLKPORT_ACLK_I		34
+#define PERIC_EQOS_TOP_IPCLKPORT_HCLK_I		35
+#define PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	36
+#define PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I	37
+#define PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK	38
+#define PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK	39
+#define PERIC_HCLK_TDM0				40
+#define PERIC_PCLK_TDM1				41
+#define PERIC_HCLK_TDM1				42
+#define PERIC_EQOS_PHYRXCLK_MUX			43
+#define PERIC_EQOS_PHYRXCLK			44
+#define PERIC_DOUT_RGMII_CLK			45
+#define PERIC_NR_CLK				46
+
+/* FSYS0 */
+#define UFS0_MPHY_REFCLK_IXTAL24		1
+#define UFS0_MPHY_REFCLK_IXTAL26		2
+#define UFS1_MPHY_REFCLK_IXTAL24		3
+#define UFS1_MPHY_REFCLK_IXTAL26		4
+#define UFS0_TOP0_HCLK_BUS			5
+#define UFS0_TOP0_ACLK				6
+#define UFS0_TOP0_CLK_UNIPRO			7
+#define UFS0_TOP0_FMP_CLK			8
+#define UFS1_TOP1_HCLK_BUS			9
+#define UFS1_TOP1_ACLK				10
+#define UFS1_TOP1_CLK_UNIPRO			11
+#define UFS1_TOP1_FMP_CLK			12
+#define PCIE_SUBCTRL_INST0_DBI_ACLK_SOC		13
+#define PCIE_SUBCTRL_INST0_AUX_CLK_SOC		14
+#define PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC	15
+#define PCIE_SUBCTRL_INST0_SLV_ACLK_SOC		16
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I 17
+#define FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	18
+#define FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	19
+#define FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	20
+#define FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	21
+#define FSYS0_DOUT_FSYS0_PERIBUS_GRP		22
+#define FSYS0_NR_CLK				23
+
+/* FSYS1 */
+#define PCIE_LINK0_IPCLKPORT_DBI_ACLK		1
+#define PCIE_LINK0_IPCLKPORT_AUX_ACLK		2
+#define PCIE_LINK0_IPCLKPORT_MSTR_ACLK		3
+#define PCIE_LINK0_IPCLKPORT_SLV_ACLK		4
+#define PCIE_LINK1_IPCLKPORT_DBI_ACLK		5
+#define PCIE_LINK1_IPCLKPORT_AUX_ACLK		6
+#define PCIE_LINK1_IPCLKPORT_MSTR_ACLK		7
+#define PCIE_LINK1_IPCLKPORT_SLV_ACLK		8
+#define FSYS1_NR_CLK				9
+
+/* IMEM */
+#define IMEM_DMA0_IPCLKPORT_ACLK		1
+#define IMEM_DMA1_IPCLKPORT_ACLK		2
+#define IMEM_WDT0_IPCLKPORT_PCLK		3
+#define IMEM_WDT1_IPCLKPORT_PCLK		4
+#define IMEM_WDT2_IPCLKPORT_PCLK		5
+#define IMEM_MCT_PCLK				6
+#define IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS	7
+#define IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS	8
+#define IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		9
+#define IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		10
+#define IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		11
+#define IMEM_NR_CLK				12
+
+/* MFC */
+#define MFC_MFC_IPCLKPORT_ACLK			1
+#define MFC_NR_CLK				2
+
+/* CAM_CSI */
+#define CAM_CSI0_0_IPCLKPORT_I_ACLK		1
+#define CAM_CSI0_1_IPCLKPORT_I_ACLK		2
+#define CAM_CSI0_2_IPCLKPORT_I_ACLK		3
+#define CAM_CSI0_3_IPCLKPORT_I_ACLK		4
+#define CAM_CSI1_0_IPCLKPORT_I_ACLK		5
+#define CAM_CSI1_1_IPCLKPORT_I_ACLK		6
+#define CAM_CSI1_2_IPCLKPORT_I_ACLK		7
+#define CAM_CSI1_3_IPCLKPORT_I_ACLK		8
+#define CAM_CSI2_0_IPCLKPORT_I_ACLK		9
+#define CAM_CSI2_1_IPCLKPORT_I_ACLK		10
+#define CAM_CSI2_2_IPCLKPORT_I_ACLK		11
+#define CAM_CSI2_3_IPCLKPORT_I_ACLK		12
+#define CAM_CSI_NR_CLK				13
+
+#endif /*_DT_BINDINGS_CLOCK_FSD_H */
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:31 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:31 +0530
Subject: [PATCH v5 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142905epcas5p33a863799819fb904932d2e88c682940a@epcas5p3.samsung.com>
Message-ID: <20220124141644.71052-4-alim.akhtar@samsung.com>

Add dt-schema documentation for Tesla FSD SoC clock controller.

Cc: linux-fsd at tesla.com
Acked-by: Stephen Boyd <sboyd at kernel.org>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../bindings/clock/tesla,fsd-clock.yaml       | 198 ++++++++++++++++++
 1 file changed, 198 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml

diff --git a/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
new file mode 100644
index 000000000000..dc808e2f8327
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tesla,fsd-clock.yaml
@@ -0,0 +1,198 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/tesla,fsd-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla FSD (Full Self-Driving) SoC clock controller
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+description: |
+  FSD clock controller consist of several clock management unit
+  (CMU), which generates clocks for various inteernal SoC blocks.
+  The root clock comes from external OSC clock (24 MHz).
+
+  All available clocks are defined as preprocessor macros in
+  'dt-bindings/clock/fsd-clk.h' header.
+
+properties:
+  compatible:
+    enum:
+      - tesla,fsd-clock-cmu
+      - tesla,fsd-clock-imem
+      - tesla,fsd-clock-peric
+      - tesla,fsd-clock-fsys0
+      - tesla,fsd-clock-fsys1
+      - tesla,fsd-clock-mfc
+      - tesla,fsd-clock-cam_csi
+
+  clocks:
+    minItems: 1
+    maxItems: 6
+
+  clock-names:
+    minItems: 1
+    maxItems: 6
+
+  "#clock-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cmu
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-imem
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: IMEM TCU clock (from CMU_CMU)
+            - description: IMEM bus clock (from CMU_CMU)
+            - description: IMEM DMA clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_imem_tcuclk
+            - const: dout_cmu_imem_aclk
+            - const: dout_cmu_imem_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-peric
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div4 clock (from CMU_CMU)
+            - description: PERIC shared1 div36 clock (from CMU_CMU)
+            - description: PERIC shared0 div3 TBU clock (from CMU_CMU)
+            - description: PERIC shared0 div20 clock (from CMU_CMU)
+            - description: PERIC shared1 div4 DMAclock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div4
+            - const: dout_cmu_peric_shared1div36
+            - const: dout_cmu_peric_shared0div3_tbuclk
+            - const: dout_cmu_peric_shared0div20
+            - const: dout_cmu_peric_shared1div4_dmaclk
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys0
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: Shared0 PLL div6 clock (from CMU_CMU)
+            - description: FSYS0 shared1 div4 clock (from CMU_CMU)
+            - description: FSYS0 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_pll_shared0_div6
+            - const: dout_cmu_fsys0_shared1div4
+            - const: dout_cmu_fsys0_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-fsys1
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+            - description: FSYS1 shared0 div8 clock (from CMU_CMU)
+            - description: FSYS1 shared0 div4 clock (from CMU_CMU)
+        clock-names:
+          items:
+            - const: fin_pll
+            - const: dout_cmu_fsys1_shared0div8
+            - const: dout_cmu_fsys1_shared0div4
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-mfc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: tesla,fsd-clock-cam_csi
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (24 MHz)
+        clock-names:
+          items:
+            - const: fin_pll
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - reg
+
+additionalProperties: false
+
+examples:
+  # Clock controller node for CMU_FSYS1
+  - |
+    #include <dt-bindings/clock/fsd-clk.h>
+
+    clock_fsys1: clock-controller at 16810000 {
+          compatible = "tesla,fsd-clock-fsys1";
+          reg = <0x16810000 0x3000>;
+          #clock-cells = <1>;
+
+          clocks = <&fin_pll>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+                   <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+          clock-names = "fin_pll",
+                        "dout_cmu_fsys1_shared0div8",
+                        "dout_cmu_fsys1_shared0div4";
+    };
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:32 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:32 +0530
Subject: [PATCH v5 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142911epcas5p2e68f16158121a34e42e1763354ba8a4f@epcas5p2.samsung.com>
Message-ID: <20220124141644.71052-5-alim.akhtar@samsung.com>

Add initial clock support for FSD (Full Self-Driving) SoC
which is required to bring-up platforms based on this SoC.

Also, fix the build error reported by the kernel test robot [1].

[1] https://lkml.org/lkml/2022/1/21/836

Cc: linux-fsd at tesla.com
Reported-by: kernel test robot <lkp at intel.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/Kconfig   |   8 +
 drivers/clk/samsung/Makefile  |   1 +
 drivers/clk/samsung/clk-fsd.c | 310 ++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.c |   1 +
 drivers/clk/samsung/clk-pll.h |   1 +
 5 files changed, 321 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-fsd.c

diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig
index 0e18d6ff2916..5f64c58f120f 100644
--- a/drivers/clk/samsung/Kconfig
+++ b/drivers/clk/samsung/Kconfig
@@ -11,6 +11,7 @@ config COMMON_CLK_SAMSUNG
 	select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
 	select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
 	select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
+	select TESLA_FSD_COMMON_CLK if ARM64 && ARCH_TESLA_FSD
 
 config S3C64XX_COMMON_CLK
 	bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
@@ -124,3 +125,10 @@ config S3C2443_COMMON_CLK
 	help
 	  Support for the clock controller present on the Samsung
 	  S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
+
+config TESLA_FSD_COMMON_CLK
+	bool "Tesla FSD clock controller support" if COMPILE_TEST
+	depends on COMMON_CLK_SAMSUNG
+	help
+	  Support for the clock controller present on the Tesla FSD SoC.
+	  Choose Y here only if you build for this SoC.
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 0df74916a895..17e5d1cb9da2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_S3C64XX_COMMON_CLK)	+= clk-s3c64xx.o
 obj-$(CONFIG_S5PV210_COMMON_CLK)	+= clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_TESLA_FSD_COMMON_CLK)	+= clk-fsd.o
diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
new file mode 100644
index 000000000000..ae35c4303b55
--- /dev/null
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -0,0 +1,310 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *             https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *             https://www.tesla.com
+ *
+ * Common Clock Framework support for FSD SoC.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include <dt-bindings/clock/fsd-clk.h>
+
+#include "clk.h"
+
+/* Register Offset definitions for CMU_CMU (0x11c10000) */
+#define PLL_LOCKTIME_PLL_SHARED0			0x0
+#define PLL_LOCKTIME_PLL_SHARED1			0x4
+#define PLL_LOCKTIME_PLL_SHARED2			0x8
+#define PLL_LOCKTIME_PLL_SHARED3			0xc
+#define PLL_CON0_PLL_SHARED0				0x100
+#define PLL_CON0_PLL_SHARED1				0x120
+#define PLL_CON0_PLL_SHARED2				0x140
+#define PLL_CON0_PLL_SHARED3				0x160
+#define MUX_CMU_CIS0_CLKMUX				0x1000
+#define MUX_CMU_CIS1_CLKMUX				0x1004
+#define MUX_CMU_CIS2_CLKMUX				0x1008
+#define MUX_CMU_CPUCL_SWITCHMUX				0x100c
+#define MUX_CMU_FSYS1_ACLK_MUX				0x1014
+#define MUX_PLL_SHARED0_MUX				0x1020
+#define MUX_PLL_SHARED1_MUX				0x1024
+#define DIV_CMU_CIS0_CLK				0x1800
+#define DIV_CMU_CIS1_CLK				0x1804
+#define DIV_CMU_CIS2_CLK				0x1808
+#define DIV_CMU_CMU_ACLK				0x180c
+#define DIV_CMU_CPUCL_SWITCH				0x1810
+#define DIV_CMU_FSYS0_SHARED0DIV4			0x181c
+#define DIV_CMU_FSYS0_SHARED1DIV3			0x1820
+#define DIV_CMU_FSYS0_SHARED1DIV4			0x1824
+#define DIV_CMU_FSYS1_SHARED0DIV4			0x1828
+#define DIV_CMU_FSYS1_SHARED0DIV8			0x182c
+#define DIV_CMU_IMEM_ACLK				0x1834
+#define DIV_CMU_IMEM_DMACLK				0x1838
+#define DIV_CMU_IMEM_TCUCLK				0x183c
+#define DIV_CMU_PERIC_SHARED0DIV20			0x1844
+#define DIV_CMU_PERIC_SHARED0DIV3_TBUCLK		0x1848
+#define DIV_CMU_PERIC_SHARED1DIV36			0x184c
+#define DIV_CMU_PERIC_SHARED1DIV4_DMACLK		0x1850
+#define DIV_PLL_SHARED0_DIV2				0x1858
+#define DIV_PLL_SHARED0_DIV3				0x185c
+#define DIV_PLL_SHARED0_DIV4				0x1860
+#define DIV_PLL_SHARED0_DIV6				0x1864
+#define DIV_PLL_SHARED1_DIV3				0x1868
+#define DIV_PLL_SHARED1_DIV36				0x186c
+#define DIV_PLL_SHARED1_DIV4				0x1870
+#define DIV_PLL_SHARED1_DIV9				0x1874
+#define GAT_CMU_CIS0_CLKGATE				0x2000
+#define GAT_CMU_CIS1_CLKGATE				0x2004
+#define GAT_CMU_CIS2_CLKGATE				0x2008
+#define GAT_CMU_CPUCL_SWITCH_GATE			0x200c
+#define GAT_CMU_FSYS0_SHARED0DIV4_GATE			0x2018
+#define GAT_CMU_FSYS0_SHARED1DIV4_CLK			0x201c
+#define GAT_CMU_FSYS0_SHARED1DIV4_GATE			0x2020
+#define GAT_CMU_FSYS1_SHARED0DIV4_GATE			0x2024
+#define GAT_CMU_FSYS1_SHARED1DIV4_GATE			0x2028
+#define GAT_CMU_IMEM_ACLK_GATE				0x2030
+#define GAT_CMU_IMEM_DMACLK_GATE			0x2034
+#define GAT_CMU_IMEM_TCUCLK_GATE			0x2038
+#define GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE		0x2040
+#define GAT_CMU_PERIC_SHARED0DIVE4_GATE			0x2044
+#define GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE		0x2048
+#define GAT_CMU_PERIC_SHARED1DIVE4_GATE			0x204c
+#define GAT_CMU_CMU_CMU_IPCLKPORT_PCLK			0x2054
+#define GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK		0x2058
+#define GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU	0x205c
+#define GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK		0x2060
+
+static const unsigned long cmu_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_SHARED0,
+	PLL_LOCKTIME_PLL_SHARED1,
+	PLL_LOCKTIME_PLL_SHARED2,
+	PLL_LOCKTIME_PLL_SHARED3,
+	PLL_CON0_PLL_SHARED0,
+	PLL_CON0_PLL_SHARED1,
+	PLL_CON0_PLL_SHARED2,
+	PLL_CON0_PLL_SHARED3,
+	MUX_CMU_CIS0_CLKMUX,
+	MUX_CMU_CIS1_CLKMUX,
+	MUX_CMU_CIS2_CLKMUX,
+	MUX_CMU_CPUCL_SWITCHMUX,
+	MUX_CMU_FSYS1_ACLK_MUX,
+	MUX_PLL_SHARED0_MUX,
+	MUX_PLL_SHARED1_MUX,
+	DIV_CMU_CIS0_CLK,
+	DIV_CMU_CIS1_CLK,
+	DIV_CMU_CIS2_CLK,
+	DIV_CMU_CMU_ACLK,
+	DIV_CMU_CPUCL_SWITCH,
+	DIV_CMU_FSYS0_SHARED0DIV4,
+	DIV_CMU_FSYS0_SHARED1DIV3,
+	DIV_CMU_FSYS0_SHARED1DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV4,
+	DIV_CMU_FSYS1_SHARED0DIV8,
+	DIV_CMU_IMEM_ACLK,
+	DIV_CMU_IMEM_DMACLK,
+	DIV_CMU_IMEM_TCUCLK,
+	DIV_CMU_PERIC_SHARED0DIV20,
+	DIV_CMU_PERIC_SHARED0DIV3_TBUCLK,
+	DIV_CMU_PERIC_SHARED1DIV36,
+	DIV_CMU_PERIC_SHARED1DIV4_DMACLK,
+	DIV_PLL_SHARED0_DIV2,
+	DIV_PLL_SHARED0_DIV3,
+	DIV_PLL_SHARED0_DIV4,
+	DIV_PLL_SHARED0_DIV6,
+	DIV_PLL_SHARED1_DIV3,
+	DIV_PLL_SHARED1_DIV36,
+	DIV_PLL_SHARED1_DIV4,
+	DIV_PLL_SHARED1_DIV9,
+	GAT_CMU_CIS0_CLKGATE,
+	GAT_CMU_CIS1_CLKGATE,
+	GAT_CMU_CIS2_CLKGATE,
+	GAT_CMU_CPUCL_SWITCH_GATE,
+	GAT_CMU_FSYS0_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS0_SHARED1DIV4_CLK,
+	GAT_CMU_FSYS0_SHARED1DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED0DIV4_GATE,
+	GAT_CMU_FSYS1_SHARED1DIV4_GATE,
+	GAT_CMU_IMEM_ACLK_GATE,
+	GAT_CMU_IMEM_DMACLK_GATE,
+	GAT_CMU_IMEM_TCUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE,
+	GAT_CMU_PERIC_SHARED0DIVE4_GATE,
+	GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE,
+	GAT_CMU_PERIC_SHARED1DIVE4_GATE,
+	GAT_CMU_CMU_CMU_IPCLKPORT_PCLK,
+	GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK,
+	GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU,
+	GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_pll_rate_table pll_shared0_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2000000000U, 250, 3, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared1_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared2_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 2400000000U, 200, 2, 0),
+};
+
+static const struct samsung_pll_rate_table pll_shared3_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1800000000U, 150, 2, 0),
+};
+
+static const struct samsung_pll_clock cmu_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_shared0", "fin_pll", PLL_LOCKTIME_PLL_SHARED0,
+	    PLL_CON0_PLL_SHARED0, pll_shared0_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared1", "fin_pll", PLL_LOCKTIME_PLL_SHARED1,
+	    PLL_CON0_PLL_SHARED1, pll_shared1_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared2", "fin_pll", PLL_LOCKTIME_PLL_SHARED2,
+	    PLL_CON0_PLL_SHARED2, pll_shared2_rate_table),
+	PLL(pll_142xx, 0, "fout_pll_shared3", "fin_pll", PLL_LOCKTIME_PLL_SHARED3,
+	    PLL_CON0_PLL_SHARED3, pll_shared3_rate_table),
+};
+
+/* List of parent clocks for Muxes in CMU_CMU */
+PNAME(mout_cmu_shared0_pll_p) = { "fin_pll", "fout_pll_shared0" };
+PNAME(mout_cmu_shared1_pll_p) = { "fin_pll", "fout_pll_shared1" };
+PNAME(mout_cmu_shared2_pll_p) = { "fin_pll", "fout_pll_shared2" };
+PNAME(mout_cmu_shared3_pll_p) = { "fin_pll", "fout_pll_shared3" };
+PNAME(mout_cmu_cis0_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis1_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cis2_clkmux_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_cmu_cpucl_switchmux_p) = { "mout_cmu_pll_shared2", "mout_cmu_pll_shared0_mux" };
+PNAME(mout_cmu_fsys1_aclk_mux_p) = { "dout_cmu_pll_shared0_div4", "fin_pll" };
+PNAME(mout_cmu_pll_shared0_mux_p) = { "fin_pll", "mout_cmu_pll_shared0" };
+PNAME(mout_cmu_pll_shared1_mux_p) = { "fin_pll", "mout_cmu_pll_shared1" };
+
+static const struct samsung_mux_clock cmu_mux_clks[] __initconst = {
+	MUX(0, "mout_cmu_pll_shared0", mout_cmu_shared0_pll_p, PLL_CON0_PLL_SHARED0, 4, 1),
+	MUX(0, "mout_cmu_pll_shared1", mout_cmu_shared1_pll_p, PLL_CON0_PLL_SHARED1, 4, 1),
+	MUX(0, "mout_cmu_pll_shared2", mout_cmu_shared2_pll_p, PLL_CON0_PLL_SHARED2, 4, 1),
+	MUX(0, "mout_cmu_pll_shared3", mout_cmu_shared3_pll_p, PLL_CON0_PLL_SHARED3, 4, 1),
+	MUX(0, "mout_cmu_cis0_clkmux", mout_cmu_cis0_clkmux_p, MUX_CMU_CIS0_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis1_clkmux", mout_cmu_cis1_clkmux_p, MUX_CMU_CIS1_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cis2_clkmux", mout_cmu_cis2_clkmux_p, MUX_CMU_CIS2_CLKMUX, 0, 1),
+	MUX(0, "mout_cmu_cpucl_switchmux", mout_cmu_cpucl_switchmux_p,
+	    MUX_CMU_CPUCL_SWITCHMUX, 0, 1),
+	MUX(0, "mout_cmu_fsys1_aclk_mux", mout_cmu_fsys1_aclk_mux_p, MUX_CMU_FSYS1_ACLK_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared0_mux", mout_cmu_pll_shared0_mux_p, MUX_PLL_SHARED0_MUX, 0, 1),
+	MUX(0, "mout_cmu_pll_shared1_mux", mout_cmu_pll_shared1_mux_p, MUX_PLL_SHARED1_MUX, 0, 1),
+};
+
+static const struct samsung_div_clock cmu_div_clks[] __initconst = {
+	DIV(0, "dout_cmu_cis0_clk", "cmu_cis0_clkgate", DIV_CMU_CIS0_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis1_clk", "cmu_cis1_clkgate", DIV_CMU_CIS1_CLK, 0, 4),
+	DIV(0, "dout_cmu_cis2_clk", "cmu_cis2_clkgate", DIV_CMU_CIS2_CLK, 0, 4),
+	DIV(0, "dout_cmu_cmu_aclk", "dout_cmu_pll_shared1_div9", DIV_CMU_CMU_ACLK, 0, 4),
+	DIV(0, "dout_cmu_cpucl_switch", "cmu_cpucl_switch_gate", DIV_CMU_CPUCL_SWITCH, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED0DIV4, "dout_cmu_fsys0_shared0div4", "cmu_fsys0_shared0div4_gate",
+	    DIV_CMU_FSYS0_SHARED0DIV4, 0, 4),
+	DIV(0, "dout_cmu_fsys0_shared1div3", "cmu_fsys0_shared1div4_clk",
+	    DIV_CMU_FSYS0_SHARED1DIV3, 0, 4),
+	DIV(DOUT_CMU_FSYS0_SHARED1DIV4, "dout_cmu_fsys0_shared1div4", "cmu_fsys0_shared1div4_gate",
+	    DIV_CMU_FSYS0_SHARED1DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV4, "dout_cmu_fsys1_shared0div4", "cmu_fsys1_shared0div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV4, 0, 4),
+	DIV(DOUT_CMU_FSYS1_SHARED0DIV8, "dout_cmu_fsys1_shared0div8", "cmu_fsys1_shared1div4_gate",
+	    DIV_CMU_FSYS1_SHARED0DIV8, 0, 4),
+	DIV(DOUT_CMU_IMEM_ACLK, "dout_cmu_imem_aclk", "cmu_imem_aclk_gate",
+	    DIV_CMU_IMEM_ACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_DMACLK, "dout_cmu_imem_dmaclk", "cmu_imem_dmaclk_gate",
+	    DIV_CMU_IMEM_DMACLK, 0, 4),
+	DIV(DOUT_CMU_IMEM_TCUCLK, "dout_cmu_imem_tcuclk", "cmu_imem_tcuclk_gate",
+	    DIV_CMU_IMEM_TCUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV20, "dout_cmu_peric_shared0div20",
+	    "cmu_peric_shared0dive4_gate", DIV_CMU_PERIC_SHARED0DIV20, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK, "dout_cmu_peric_shared0div3_tbuclk",
+	    "cmu_peric_shared0dive3_tbuclk_gate", DIV_CMU_PERIC_SHARED0DIV3_TBUCLK, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV36, "dout_cmu_peric_shared1div36",
+	    "cmu_peric_shared1dive4_gate", DIV_CMU_PERIC_SHARED1DIV36, 0, 4),
+	DIV(DOUT_CMU_PERIC_SHARED1DIV4_DMACLK, "dout_cmu_peric_shared1div4_dmaclk",
+	    "cmu_peric_shared1div4_dmaclk_gate", DIV_CMU_PERIC_SHARED1DIV4_DMACLK, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div2", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV2, 0, 4),
+	DIV(0, "dout_cmu_pll_shared0_div3", "mout_cmu_pll_shared0_mux",
+	    DIV_PLL_SHARED0_DIV3, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV4, "dout_cmu_pll_shared0_div4", "dout_cmu_pll_shared0_div2",
+	    DIV_PLL_SHARED0_DIV4, 0, 4),
+	DIV(DOUT_CMU_PLL_SHARED0_DIV6, "dout_cmu_pll_shared0_div6", "dout_cmu_pll_shared0_div3",
+	    DIV_PLL_SHARED0_DIV6, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div3", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV3, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div36", "dout_cmu_pll_shared1_div9",
+	    DIV_PLL_SHARED1_DIV36, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div4", "mout_cmu_pll_shared1_mux",
+	    DIV_PLL_SHARED1_DIV4, 0, 4),
+	DIV(0, "dout_cmu_pll_shared1_div9", "dout_cmu_pll_shared1_div3",
+	    DIV_PLL_SHARED1_DIV9, 0, 4),
+};
+
+static const struct samsung_gate_clock cmu_gate_clks[] __initconst = {
+	GATE(0, "cmu_cis0_clkgate", "mout_cmu_cis0_clkmux", GAT_CMU_CIS0_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis1_clkgate", "mout_cmu_cis1_clkmux", GAT_CMU_CIS1_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_cis2_clkgate", "mout_cmu_cis2_clkmux", GAT_CMU_CIS2_CLKGATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(CMU_CPUCL_SWITCH_GATE, "cmu_cpucl_switch_gate", "mout_cmu_cpucl_switchmux",
+	     GAT_CMU_CPUCL_SWITCH_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(GAT_CMU_FSYS0_SHARED0DIV4, "cmu_fsys0_shared0div4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_FSYS0_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_clk", "dout_cmu_pll_shared1_div3",
+	     GAT_CMU_FSYS0_SHARED1DIV4_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys0_shared1div4_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_FSYS0_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared0div4_gate", "mout_cmu_fsys1_aclk_mux",
+	     GAT_CMU_FSYS1_SHARED0DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_fsys1_shared1div4_gate", "dout_cmu_fsys1_shared0div4",
+	     GAT_CMU_FSYS1_SHARED1DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_aclk_gate", "dout_cmu_pll_shared1_div9", GAT_CMU_IMEM_ACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_dmaclk_gate", "mout_cmu_pll_shared1_mux", GAT_CMU_IMEM_DMACLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_imem_tcuclk_gate", "dout_cmu_pll_shared0_div3", GAT_CMU_IMEM_TCUCLK_GATE, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive3_tbuclk_gate", "dout_cmu_pll_shared0_div3",
+	     GAT_CMU_PERIC_SHARED0DIVE3_TBUCLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared0dive4_gate", "dout_cmu_pll_shared0_div4",
+	     GAT_CMU_PERIC_SHARED0DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1div4_dmaclk_gate", "dout_cmu_pll_shared1_div4",
+	     GAT_CMU_PERIC_SHARED1DIV4_DMACLK_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_peric_shared1dive4_gate", "dout_cmu_pll_shared1_div36",
+	     GAT_CMU_PERIC_SHARED1DIVE4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_cmu_cmu_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_CMU_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_axi2apb_cmu_ipclkport_aclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_AXI2APB_CMU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_ns_brdg_cmu_ipclkport_clk__psoc_cmu__clk_cmu", "dout_cmu_cmu_aclk",
+	     GAT_CMU_NS_BRDG_CMU_IPCLKPORT_CLK__PSOC_CMU__CLK_CMU, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cmu_uid_sysreg_cmu_ipclkport_pclk", "dout_cmu_cmu_aclk",
+	     GAT_CMU_SYSREG_CMU_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cmu_cmu_info __initconst = {
+	.pll_clks		= cmu_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cmu_pll_clks),
+	.mux_clks		= cmu_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cmu_mux_clks),
+	.div_clks		= cmu_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cmu_div_clks),
+	.gate_clks		= cmu_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cmu_gate_clks),
+	.nr_clk_ids		= CMU_NR_CLK,
+	.clk_regs		= cmu_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cmu_clk_regs),
+};
+
+static void __init fsd_clk_cmu_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &cmu_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 70cdc87f714e..fe383471c5f0 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -1469,6 +1469,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_1450x:
 	case pll_1451x:
 	case pll_1452x:
+	case pll_142xx:
 		pll->enable_offs = PLL35XX_ENABLE_SHIFT;
 		pll->lock_offs = PLL35XX_LOCK_STAT_SHIFT;
 		if (!pll->rate_table)
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index c83a20195f6d..a9892c2d1f57 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -39,6 +39,7 @@ enum samsung_pll_type {
 	pll_1460x,
 	pll_0822x,
 	pll_0831x,
+	pll_142xx,
 };
 
 #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:33 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:33 +0530
Subject: [PATCH v5 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142915epcas5p2c112efe9f08ffa2a53122f4e2b8042e1@epcas5p2.samsung.com>
Message-ID: <20220124141644.71052-6-alim.akhtar@samsung.com>

Add CMU_PERIC block clock information needed for various IPs
functions found in this block.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 405 ++++++++++++++++++++++++++++++++++
 1 file changed, 405 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index ae35c4303b55..a3d328318814 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -8,14 +8,19 @@
  * Common Clock Framework support for FSD SoC.
  */
 
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
 
 #include <dt-bindings/clock/fsd-clk.h>
 
 #include "clk.h"
+#include "clk-exynos-arm64.h"
 
 /* Register Offset definitions for CMU_CMU (0x11c10000) */
 #define PLL_LOCKTIME_PLL_SHARED0			0x0
@@ -308,3 +313,403 @@ static void __init fsd_clk_cmu_init(struct device_node *np)
 }
 
 CLK_OF_DECLARE(fsd_clk_cmu, "tesla,fsd-clock-cmu", fsd_clk_cmu_init);
+
+/* Register Offset definitions for CMU_PERIC (0x14010000) */
+#define PLL_CON0_PERIC_DMACLK_MUX		0x100
+#define PLL_CON0_PERIC_EQOS_BUSCLK_MUX		0x120
+#define PLL_CON0_PERIC_PCLK_MUX			0x140
+#define PLL_CON0_PERIC_TBUCLK_MUX		0x160
+#define PLL_CON0_SPI_CLK			0x180
+#define PLL_CON0_SPI_PCLK			0x1a0
+#define PLL_CON0_UART_CLK			0x1c0
+#define PLL_CON0_UART_PCLK			0x1e0
+#define MUX_PERIC_EQOS_PHYRXCLK			0x1000
+#define DIV_EQOS_BUSCLK				0x1800
+#define DIV_PERIC_MCAN_CLK			0x1804
+#define DIV_RGMII_CLK				0x1808
+#define DIV_RII_CLK				0x180c
+#define DIV_RMII_CLK				0x1810
+#define DIV_SPI_CLK				0x1814
+#define DIV_UART_CLK				0x1818
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I	0x2000
+#define GAT_GPIO_PERIC_IPCLKPORT_OSCCLK		0x2004
+#define GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK	0x2008
+#define GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK	0x200c
+#define GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK	0x2010
+#define GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK	0x2014
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM	0x2018
+#define GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS	0x201c
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM	0x2020
+#define GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS	0x2024
+#define GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK	0x2028
+#define GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK	0x202c
+#define GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK	0x2030
+#define GAT_BUS_D_PERIC_IPCLKPORT_DMACLK	0x2034
+#define GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK	0x2038
+#define GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK	0x203c
+#define GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK	0x2040
+#define GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK	0x2044
+#define GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK	0x2048
+#define GAT_EQOS_TOP_IPCLKPORT_ACLK_I		0x204c
+#define GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I		0x2050
+#define GAT_EQOS_TOP_IPCLKPORT_HCLK_I		0x2054
+#define GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I	0x2058
+#define GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I	0x205c
+#define GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I	0x2060
+#define GAT_GPIO_PERIC_IPCLKPORT_PCLK		0x2064
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D	0x2068
+#define GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P	0x206c
+#define GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0	0x2070
+#define GAT_PERIC_DMA0_IPCLKPORT_ACLK		0x2074
+#define GAT_PERIC_DMA1_IPCLKPORT_ACLK		0x2078
+#define GAT_PERIC_I2C0_IPCLKPORT_I_PCLK		0x207c
+#define GAT_PERIC_I2C1_IPCLKPORT_I_PCLK		0x2080
+#define GAT_PERIC_I2C2_IPCLKPORT_I_PCLK		0x2084
+#define GAT_PERIC_I2C3_IPCLKPORT_I_PCLK		0x2088
+#define GAT_PERIC_I2C4_IPCLKPORT_I_PCLK		0x208c
+#define GAT_PERIC_I2C5_IPCLKPORT_I_PCLK		0x2090
+#define GAT_PERIC_I2C6_IPCLKPORT_I_PCLK		0x2094
+#define GAT_PERIC_I2C7_IPCLKPORT_I_PCLK		0x2098
+#define GAT_PERIC_MCAN0_IPCLKPORT_CCLK		0x209c
+#define GAT_PERIC_MCAN0_IPCLKPORT_PCLK		0x20a0
+#define GAT_PERIC_MCAN1_IPCLKPORT_CCLK		0x20a4
+#define GAT_PERIC_MCAN1_IPCLKPORT_PCLK		0x20a8
+#define GAT_PERIC_MCAN2_IPCLKPORT_CCLK		0x20ac
+#define GAT_PERIC_MCAN2_IPCLKPORT_PCLK		0x20b0
+#define GAT_PERIC_MCAN3_IPCLKPORT_CCLK		0x20b4
+#define GAT_PERIC_MCAN3_IPCLKPORT_PCLK		0x20b8
+#define GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0	0x20bc
+#define GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0	0x20c0
+#define GAT_PERIC_SMMU_IPCLKPORT_CCLK		0x20c4
+#define GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK	0x20c8
+#define GAT_PERIC_SPI0_IPCLKPORT_I_PCLK		0x20cc
+#define GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI	0x20d0
+#define GAT_PERIC_SPI1_IPCLKPORT_I_PCLK		0x20d4
+#define GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI	0x20d8
+#define GAT_PERIC_SPI2_IPCLKPORT_I_PCLK		0x20dc
+#define GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI	0x20e0
+#define GAT_PERIC_TDM0_IPCLKPORT_HCLK_M		0x20e4
+#define GAT_PERIC_TDM0_IPCLKPORT_PCLK		0x20e8
+#define GAT_PERIC_TDM1_IPCLKPORT_HCLK_M		0x20ec
+#define GAT_PERIC_TDM1_IPCLKPORT_PCLK		0x20f0
+#define GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART	0x20f4
+#define GAT_PERIC_UART0_IPCLKPORT_PCLK		0x20f8
+#define GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART	0x20fc
+#define GAT_PERIC_UART1_IPCLKPORT_PCLK		0x2100
+#define GAT_SYSREG_PERI_IPCLKPORT_PCLK		0x2104
+
+static const unsigned long peric_clk_regs[] __initconst = {
+	PLL_CON0_PERIC_DMACLK_MUX,
+	PLL_CON0_PERIC_EQOS_BUSCLK_MUX,
+	PLL_CON0_PERIC_PCLK_MUX,
+	PLL_CON0_PERIC_TBUCLK_MUX,
+	PLL_CON0_SPI_CLK,
+	PLL_CON0_SPI_PCLK,
+	PLL_CON0_UART_CLK,
+	PLL_CON0_UART_PCLK,
+	MUX_PERIC_EQOS_PHYRXCLK,
+	DIV_EQOS_BUSCLK,
+	DIV_PERIC_MCAN_CLK,
+	DIV_RGMII_CLK,
+	DIV_RII_CLK,
+	DIV_RMII_CLK,
+	DIV_SPI_CLK,
+	DIV_UART_CLK,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK,
+	GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM,
+	GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS,
+	GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK,
+	GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_DMACLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK,
+	GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK,
+	GAT_EQOS_TOP_IPCLKPORT_ACLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I,
+	GAT_EQOS_TOP_IPCLKPORT_HCLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I,
+	GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I,
+	GAT_GPIO_PERIC_IPCLKPORT_PCLK,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D,
+	GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P,
+	GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0,
+	GAT_PERIC_DMA0_IPCLKPORT_ACLK,
+	GAT_PERIC_DMA1_IPCLKPORT_ACLK,
+	GAT_PERIC_I2C0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C3_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C4_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C5_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C6_IPCLKPORT_I_PCLK,
+	GAT_PERIC_I2C7_IPCLKPORT_I_PCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN0_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN1_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN2_IPCLKPORT_PCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_CCLK,
+	GAT_PERIC_MCAN3_IPCLKPORT_PCLK,
+	GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0,
+	GAT_PERIC_SMMU_IPCLKPORT_CCLK,
+	GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI1_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_SPI2_IPCLKPORT_I_PCLK,
+	GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI,
+	GAT_PERIC_TDM0_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM0_IPCLKPORT_PCLK,
+	GAT_PERIC_TDM1_IPCLKPORT_HCLK_M,
+	GAT_PERIC_TDM1_IPCLKPORT_PCLK,
+	GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART0_IPCLKPORT_PCLK,
+	GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART,
+	GAT_PERIC_UART1_IPCLKPORT_PCLK,
+	GAT_SYSREG_PERI_IPCLKPORT_PCLK,
+};
+
+static const struct samsung_fixed_rate_clock peric_fixed_clks[] __initconst = {
+	FRATE(PERIC_EQOS_PHYRXCLK, "eqos_phyrxclk", NULL, 0, 125000000),
+};
+
+/* List of parent clocks for Muxes in CMU_PERIC */
+PNAME(mout_peric_dmaclk_p) = { "fin_pll", "cmu_peric_shared1div4_dmaclk_gate" };
+PNAME(mout_peric_eqos_busclk_p) = { "fin_pll", "dout_cmu_pll_shared0_div4" };
+PNAME(mout_peric_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_tbuclk_p) = { "fin_pll", "dout_cmu_peric_shared0div3_tbuclk" };
+PNAME(mout_peric_spi_clk_p) = { "fin_pll", "dout_cmu_peric_shared0div20" };
+PNAME(mout_peric_spi_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_uart_clk_p) = { "fin_pll", "dout_cmu_peric_shared1div4_dmaclk" };
+PNAME(mout_peric_uart_pclk_p) = { "fin_pll", "dout_cmu_peric_shared1div36" };
+PNAME(mout_peric_eqos_phyrxclk_p) = { "dout_peric_rgmii_clk", "eqos_phyrxclk" };
+
+static const struct samsung_mux_clock peric_mux_clks[] __initconst = {
+	MUX(0, "mout_peric_dmaclk", mout_peric_dmaclk_p, PLL_CON0_PERIC_DMACLK_MUX, 4, 1),
+	MUX(0, "mout_peric_eqos_busclk", mout_peric_eqos_busclk_p,
+	    PLL_CON0_PERIC_EQOS_BUSCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_pclk", mout_peric_pclk_p, PLL_CON0_PERIC_PCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_tbuclk", mout_peric_tbuclk_p, PLL_CON0_PERIC_TBUCLK_MUX, 4, 1),
+	MUX(0, "mout_peric_spi_clk", mout_peric_spi_clk_p, PLL_CON0_SPI_CLK, 4, 1),
+	MUX(0, "mout_peric_spi_pclk", mout_peric_spi_pclk_p, PLL_CON0_SPI_PCLK, 4, 1),
+	MUX(0, "mout_peric_uart_clk", mout_peric_uart_clk_p, PLL_CON0_UART_CLK, 4, 1),
+	MUX(0, "mout_peric_uart_pclk", mout_peric_uart_pclk_p, PLL_CON0_UART_PCLK, 4, 1),
+	MUX(PERIC_EQOS_PHYRXCLK_MUX, "mout_peric_eqos_phyrxclk", mout_peric_eqos_phyrxclk_p,
+		MUX_PERIC_EQOS_PHYRXCLK, 0, 1),
+};
+
+static const struct samsung_div_clock peric_div_clks[] __initconst = {
+	DIV(0, "dout_peric_eqos_busclk", "mout_peric_eqos_busclk", DIV_EQOS_BUSCLK, 0, 4),
+	DIV(0, "dout_peric_mcan_clk", "mout_peric_dmaclk", DIV_PERIC_MCAN_CLK, 0, 4),
+	DIV(PERIC_DOUT_RGMII_CLK, "dout_peric_rgmii_clk", "mout_peric_eqos_busclk",
+		DIV_RGMII_CLK, 0, 4),
+	DIV(0, "dout_peric_rii_clk", "dout_peric_rmii_clk", DIV_RII_CLK, 0, 4),
+	DIV(0, "dout_peric_rmii_clk", "dout_peric_rgmii_clk", DIV_RMII_CLK, 0, 4),
+	DIV(0, "dout_peric_spi_clk", "mout_peric_spi_clk", DIV_SPI_CLK, 0, 6),
+	DIV(0, "dout_peric_uart_clk", "mout_peric_uart_clk", DIV_UART_CLK, 0, 6),
+};
+
+static const struct samsung_gate_clock peric_gate_clks[] __initconst = {
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, "peric_eqos_top_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_EQOS_TOP_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_oscclk", "fin_pll", GAT_GPIO_PERIC_IPCLKPORT_OSCCLK,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_ADCIF, "peric_adc0_ipclkport_i_oscclk", "fin_pll",
+	     GAT_PERIC_ADC0_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_cmu_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_CMU_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm0_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM0_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_pwm1_ipclkport_i_oscclk", "fin_pll", GAT_PERIC_PWM1_IPCLKPORT_I_OSCCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma0_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclkm", "mout_peric_dmaclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_async_apb_dma1_ipclkport_pclks", "mout_peric_pclk",
+	     GAT_ASYNC_APB_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric0_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric1_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_axi2apb_peric2_ipclkport_aclk", "mout_peric_pclk",
+	     GAT_AXI2APB_PERIC2_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_dmaclk", "mout_peric_dmaclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_DMACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_D_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_d_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_D_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_d_peric_ipclkport_mainclk", "mout_peric_tbuclk",
+	     GAT_BUS_D_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_BUS_P_PERIC_IPCLKPORT_EQOSCLK, "peric_bus_p_peric_ipclkport_eqosclk",
+	     "dout_peric_eqos_busclk", GAT_BUS_P_PERIC_IPCLKPORT_EQOSCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_mainclk", "mout_peric_pclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_bus_p_peric_ipclkport_smmuclk", "mout_peric_tbuclk",
+	     GAT_BUS_P_PERIC_IPCLKPORT_SMMUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_ACLK_I, "peric_eqos_top_ipclkport_aclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_ACLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_CLK_RX_I, "peric_eqos_top_ipclkport_clk_rx_i",
+	     "mout_peric_eqos_phyrxclk", GAT_EQOS_TOP_IPCLKPORT_CLK_RX_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_HCLK_I, "peric_eqos_top_ipclkport_hclk_i",
+	     "dout_peric_eqos_busclk", GAT_EQOS_TOP_IPCLKPORT_HCLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, "peric_eqos_top_ipclkport_rgmii_clk_i",
+	     "dout_peric_rgmii_clk", GAT_EQOS_TOP_IPCLKPORT_RGMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rii_clk_i", "dout_peric_rii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_eqos_top_ipclkport_rmii_clk_i", "dout_peric_rmii_clk",
+	     GAT_EQOS_TOP_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_gpio_peric_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_GPIO_PERIC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_d", "mout_peric_tbuclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_ns_brdg_peric_ipclkport_clk__psoc_peric__clk_peric_p", "mout_peric_pclk",
+	     GAT_NS_BRDG_PERIC_IPCLKPORT_CLK__PSOC_PERIC__CLK_PERIC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_adc0_ipclkport_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_ADC0_IPCLKPORT_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA0_IPCLKPORT_ACLK, "peric_dma0_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_DMA1_IPCLKPORT_ACLK, "peric_dma1_ipclkport_aclk", "mout_peric_dmaclk",
+	     GAT_PERIC_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C0, "peric_i2c0_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C1, "peric_i2c1_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C2, "peric_i2c2_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C3, "peric_i2c3_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C4, "peric_i2c4_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C4_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C5, "peric_i2c5_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C5_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C6, "peric_i2c6_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C6_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_HSI2C7, "peric_i2c7_ipclkport_i_pclk", "mout_peric_pclk",
+	     GAT_PERIC_I2C7_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_CCLK, "peric_mcan0_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN0_IPCLKPORT_PCLK, "peric_mcan0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_CCLK, "peric_mcan1_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN1_IPCLKPORT_PCLK, "peric_mcan1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_CCLK, "peric_mcan2_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN2_IPCLKPORT_PCLK, "peric_mcan2_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_CCLK, "peric_mcan3_ipclkport_cclk", "dout_peric_mcan_clk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_MCAN3_IPCLKPORT_PCLK, "peric_mcan3_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_MCAN3_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM0_IPCLKPORT_I_PCLK_S0, "peric_pwm0_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM0_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PWM1_IPCLKPORT_I_PCLK_S0, "peric_pwm1_ipclkport_i_pclk_s0", "mout_peric_pclk",
+	     GAT_PERIC_PWM1_IPCLKPORT_I_PCLK_S0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_cclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_smmu_ipclkport_peric_bclk", "mout_peric_tbuclk",
+	     GAT_PERIC_SMMU_IPCLKPORT_PERIC_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI0, "peric_spi0_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI0, "peric_spi0_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI0_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI1, "peric_spi1_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI1, "peric_spi1_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI1_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_SPI2, "peric_spi2_ipclkport_i_pclk", "mout_peric_spi_pclk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_SPI2, "peric_spi2_ipclkport_i_sclk_spi", "dout_peric_spi_clk",
+	     GAT_PERIC_SPI2_IPCLKPORT_I_SCLK_SPI, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM0, "peric_tdm0_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM0, "peric_tdm0_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_HCLK_TDM1, "peric_tdm1_ipclkport_hclk_m", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_HCLK_M, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_TDM1, "peric_tdm1_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_PERIC_TDM1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART0, "peric_uart0_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART0_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART0, "peric_uart0_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_SCLK_UART1, "peric_uart1_ipclkport_i_sclk_uart", "dout_peric_uart_clk",
+	     GAT_PERIC_UART1_IPCLKPORT_I_SCLK_UART, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PERIC_PCLK_UART1, "peric_uart1_ipclkport_pclk", "mout_peric_uart_pclk",
+	     GAT_PERIC_UART1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "peric_sysreg_peri_ipclkport_pclk", "mout_peric_pclk",
+	     GAT_SYSREG_PERI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info peric_cmu_info __initconst = {
+	.mux_clks		= peric_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(peric_mux_clks),
+	.div_clks		= peric_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(peric_div_clks),
+	.gate_clks		= peric_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(peric_gate_clks),
+	.fixed_clks		= peric_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(peric_fixed_clks),
+	.nr_clk_ids		= PERIC_NR_CLK,
+	.clk_regs		= peric_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(peric_clk_regs),
+	.clk_name		= "dout_cmu_pll_shared0_div4",
+};
+
+/**
+ * fsd_cmu_probe - Probe function for FSD platform clocks
+ * @pdev: Pointer to platform device
+ *
+ * Configure clock hierarchy for clock domains of FSD platform
+ */
+static int __init fsd_cmu_probe(struct platform_device *pdev)
+{
+	const struct samsung_cmu_info *info;
+	struct device *dev = &pdev->dev;
+
+	info = of_device_get_match_data(dev);
+	exynos_arm64_register_cmu(dev, dev->of_node, info);
+
+	return 0;
+}
+
+/* CMUs which belong to Power Domains and need runtime PM to be implemented */
+static const struct of_device_id fsd_cmu_of_match[] = {
+	{
+		.compatible = "tesla,fsd-clock-peric",
+		.data = &peric_cmu_info,
+	}, {
+	},
+};
+
+static struct platform_driver fsd_cmu_driver __refdata = {
+	.driver	= {
+		.name = "fsd-cmu",
+		.of_match_table = fsd_cmu_of_match,
+		.suppress_bind_attrs = true,
+	},
+	.probe = fsd_cmu_probe,
+};
+
+static int __init fsd_cmu_init(void)
+{
+	return platform_driver_register(&fsd_cmu_driver);
+}
+core_initcall(fsd_cmu_init);
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:34 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:34 +0530
Subject: [PATCH v5 06/16] clk: samsung: fsd: Add cmu_fsys0 clock information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142919epcas5p3232941c11ef3c5ac8de2ca89b21131e2@epcas5p3.samsung.com>
Message-ID: <20220124141644.71052-7-alim.akhtar@samsung.com>

CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
the related clock information for the same.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Shradha Todi <shradha.t at samsung.com>
Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 302 ++++++++++++++++++++++++++++++++++
 1 file changed, 302 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index a3d328318814..785c493be2b6 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -673,6 +673,305 @@ static const struct samsung_cmu_info peric_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_pll_shared0_div4",
 };
 
+/* Register Offset definitions for CMU_FSYS0 (0x15010000) */
+#define PLL_CON0_CLKCMU_FSYS0_UNIPRO		0x100
+#define PLL_CON0_CLK_FSYS0_SLAVEBUSCLK		0x140
+#define PLL_CON0_EQOS_RGMII_125_MUX1		0x160
+#define DIV_CLK_UNIPRO				0x1800
+#define DIV_EQS_RGMII_CLK_125			0x1804
+#define DIV_PERIBUS_GRP				0x1808
+#define DIV_EQOS_RII_CLK2O5			0x180c
+#define DIV_EQOS_RMIICLK_25			0x1810
+#define DIV_PCIE_PHY_OSCCLK			0x1814
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I	0x2004
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I	0x2008
+#define GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK	0x200c
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK	0x2010
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO	0x2014
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK	0x2018
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC	0x201c
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2020
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x2024
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24	0x2028
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26	0x202c
+#define GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK	0x2038
+#define GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK	0x203c
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK	0x2044
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK	0x2048
+#define GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK	0x204c
+#define GAT_FSYS0_CPE425_IPCLKPORT_ACLK		0x2050
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I	0x2054
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I	0x2058
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I	0x205c
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I	0x2060
+#define GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I	0x2064
+#define GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK	0x2068
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D	0x206c
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1	0x2070
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P	0x2074
+#define GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S	0x2078
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK	0x207c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL	0x2080
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0	0x2084
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC	0x2088
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK	0x208c
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC	0x2090
+#define GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC	0x2094
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK	0x2098
+#define GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK	0x209c
+#define GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK	0x20a0
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS	0x20a4
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK	0x20a8
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO	0x20ac
+#define GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK	0x20b0
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS	0x20b4
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK	0x20b8
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO	0x20bc
+#define GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK	0x20c0
+#define GAT_FSYS0_RII_CLK_DIVGATE			0x20d4
+
+static const unsigned long fsys0_clk_regs[] __initconst = {
+	PLL_CON0_CLKCMU_FSYS0_UNIPRO,
+	PLL_CON0_CLK_FSYS0_SLAVEBUSCLK,
+	PLL_CON0_EQOS_RGMII_125_MUX1,
+	DIV_CLK_UNIPRO,
+	DIV_EQS_RGMII_CLK_125,
+	DIV_PERIBUS_GRP,
+	DIV_EQOS_RII_CLK2O5,
+	DIV_EQOS_RMIICLK_25,
+	DIV_PCIE_PHY_OSCCLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I,
+	GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26,
+	GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK,
+	GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK,
+	GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK,
+	GAT_FSYS0_CPE425_IPCLKPORT_ACLK,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I,
+	GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I,
+	GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P,
+	GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC,
+	GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK,
+	GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK,
+	GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO,
+	GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK,
+	GAT_FSYS0_RII_CLK_DIVGATE,
+};
+
+static const struct samsung_fixed_rate_clock fsys0_fixed_clks[] __initconst = {
+	FRATE(0, "pad_eqos0_phyrxclk", NULL, 0, 125000000),
+	FRATE(0, "i_mphy_refclk_ixtal26", NULL, 0, 26000000),
+	FRATE(0, "xtal_clk_pcie_phy", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS0 */
+PNAME(mout_fsys0_clkcmu_fsys0_unipro_p) = { "fin_pll", "dout_cmu_pll_shared0_div6" };
+PNAME(mout_fsys0_clk_fsys0_slavebusclk_p) = { "fin_pll", "dout_cmu_fsys0_shared1div4" };
+PNAME(mout_fsys0_eqos_rgmii_125_mux1_p) = { "fin_pll", "dout_cmu_fsys0_shared0div4" };
+
+static const struct samsung_mux_clock fsys0_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys0_clkcmu_fsys0_unipro", mout_fsys0_clkcmu_fsys0_unipro_p,
+	    PLL_CON0_CLKCMU_FSYS0_UNIPRO, 4, 1),
+	MUX(0, "mout_fsys0_clk_fsys0_slavebusclk", mout_fsys0_clk_fsys0_slavebusclk_p,
+	    PLL_CON0_CLK_FSYS0_SLAVEBUSCLK, 4, 1),
+	MUX(0, "mout_fsys0_eqos_rgmii_125_mux1", mout_fsys0_eqos_rgmii_125_mux1_p,
+	    PLL_CON0_EQOS_RGMII_125_MUX1, 4, 1),
+};
+
+static const struct samsung_div_clock fsys0_div_clks[] __initconst = {
+	DIV(0, "dout_fsys0_clk_unipro", "mout_fsys0_clkcmu_fsys0_unipro", DIV_CLK_UNIPRO, 0, 4),
+	DIV(0, "dout_fsys0_eqs_rgmii_clk_125", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQS_RGMII_CLK_125, 0, 4),
+	DIV(FSYS0_DOUT_FSYS0_PERIBUS_GRP, "dout_fsys0_peribus_grp",
+	    "mout_fsys0_clk_fsys0_slavebusclk", DIV_PERIBUS_GRP, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rii_clk2o5", "fsys0_rii_clk_divgate", DIV_EQOS_RII_CLK2O5, 0, 4),
+	DIV(0, "dout_fsys0_eqos_rmiiclk_25", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_EQOS_RMIICLK_25, 0, 5),
+	DIV(0, "dout_fsys0_pcie_phy_oscclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	    DIV_PCIE_PHY_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys0_gate_clks[] __initconst = {
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, "fsys0_eqos_top0_ipclkport_clk_rx_i",
+	     "pad_eqos0_phyrxclk", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_AUX_CLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_aux_clk_soc", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_AUX_CLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_fsys0_cmu_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_FSYS0_CMU_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_xo",
+	     "xtal_clk_pcie_phy",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_XO, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top0_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL24, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal24",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL24, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_MPHY_REFCLK_IXTAL26, "fsys0_ufs_top1_ipclkport_i_mphy_refclk_ixtal26",
+	     "i_mphy_refclk_ixtal26", GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_MPHY_REFCLK_IXTAL26, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ahbbr_fsys0_ipclkport_hclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AHBBR_FSYS0_IPCLKPORT_HCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_axi2apb_fsys0_ipclkport_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_AXI2APB_FSYS0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_mainclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_d_fsys0_ipclkport_periclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_D_FSYS0_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_mainclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_bus_p_fsys0_ipclkport_tcuclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_BUS_P_FSYS0_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_cpe425_ipclkport_aclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_CPE425_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, "fsys0_eqos_top0_ipclkport_aclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_ACLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, "fsys0_eqos_top0_ipclkport_hclk_i",
+	     "dout_fsys0_peribus_grp", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_HCLK_I, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, "fsys0_eqos_top0_ipclkport_rgmii_clk_i",
+	      "dout_fsys0_eqs_rgmii_clk_125", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I, 21,
+	      CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rii_clk_i", "dout_fsys0_eqos_rii_clk2o5",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_eqos_top0_ipclkport_rmii_clk_i", "dout_fsys0_eqos_rmiiclk_25",
+	     GAT_FSYS0_EQOS_TOP0_IPCLKPORT_RMII_CLK_I, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_gpio_fsys0_ipclkport_oscclk", "fin_pll",
+	     GAT_FSYS0_GPIO_FSYS0_IPCLKPORT_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_d1",
+	     "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_D1, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_p",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_ns_brdg_fsys0_ipclkport_clk__psoc_fsys0__clk_fsys0_s",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_NS_BRDG_FSYS0_IPCLKPORT_CLK__PSOC_FSYS0__CLK_FSYS0_S, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_i_apb_pclk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_I_APB_PCLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0,
+	     "fsys0_pcie_top_ipclkport_pcieg3_phy_x4_inst_0_pll_refclk_from_syspll",
+	     "dout_fsys0_pcie_phy_oscclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PCIEG3_PHY_X4_INST_0_PLL_REFCLK_FROM_SYSPLL,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_apb_pclk_0", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_APB_PCLK_0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_pipe_pal_inst_0_i_immortal_clk", "fin_pll",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_PIPE_PAL_INST_0_I_IMMORTAL_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_DBI_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_dbi_aclk_soc",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_DBI_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_i_driver_apb_clk",
+	     "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_I_DRIVER_APB_CLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_MSTR_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_mstr_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_MSTR_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_SUBCTRL_INST0_SLV_ACLK_SOC,
+	     "fsys0_pcie_top_ipclkport_fsd_pcie_sub_ctrl_inst_0_slv_aclk_soc",
+	     "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_PCIE_TOP_IPCLKPORT_FSD_PCIE_SUB_CTRL_INST_0_SLV_ACLK_SOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_cclk", "mout_fsys0_eqos_rgmii_125_mux1",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_CCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_smmu_fsys0_ipclkport_fsys0_bclk", "mout_fsys0_clk_fsys0_slavebusclk",
+	     GAT_FSYS0_SMMU_FSYS0_IPCLKPORT_FSYS0_BCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_sysreg_fsys0_ipclkport_pclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_SYSREG_FSYS0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_HCLK_BUS, "fsys0_ufs_top0_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_ACLK, "fsys0_ufs_top0_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_CLK_UNIPRO, "fsys0_ufs_top0_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS0_TOP0_FMP_CLK, "fsys0_ufs_top0_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP0_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_HCLK_BUS, "fsys0_ufs_top1_ipclkport_hclk_bus", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_HCLK_BUS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_ACLK, "fsys0_ufs_top1_ipclkport_i_aclk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_CLK_UNIPRO, "fsys0_ufs_top1_ipclkport_i_clk_unipro", "dout_fsys0_clk_unipro",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_CLK_UNIPRO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(UFS1_TOP1_FMP_CLK, "fsys0_ufs_top1_ipclkport_i_fmp_clk", "dout_fsys0_peribus_grp",
+	     GAT_FSYS0_UFS_TOP1_IPCLKPORT_I_FMP_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys0_rii_clk_divgate", "dout_fsys0_eqos_rmiiclk_25", GAT_FSYS0_RII_CLK_DIVGATE,
+	     21, CLK_IGNORE_UNUSED, 0),
+	GATE(FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, "fsys0_eqos_top0_ipclkport_clk_ptp_ref_i",
+	     "fin_pll", GAT_FSYS0_EQOS_TOP0_IPCLKPORT_CLK_PTP_REF_I, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
+	.mux_clks		= fsys0_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys0_mux_clks),
+	.div_clks		= fsys0_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys0_div_clks),
+	.gate_clks		= fsys0_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys0_gate_clks),
+	.fixed_clks		= fsys0_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys0_fixed_clks),
+	.nr_clk_ids		= FSYS0_NR_CLK,
+	.clk_regs		= fsys0_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys0_clk_regs),
+	.clk_name		= "dout_cmu_fsys0_shared1div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -695,6 +994,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	{
 		.compatible = "tesla,fsd-clock-peric",
 		.data = &peric_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys0",
+		.data = &fsys0_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:35 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:35 +0530
Subject: [PATCH v5 07/16] clk: samsung: fsd: Add cmu_fsys1 clock information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142923epcas5p17cffd89f734eda4c7e9515ac4ec79fb5@epcas5p1.samsung.com>
Message-ID: <20220124141644.71052-8-alim.akhtar@samsung.com>

Adds cmu_fsys1 block clock information which are needed
for PCIe IPs in block FSYS1.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 175 ++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 785c493be2b6..19c3ea35a6ea 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -972,6 +972,178 @@ static const struct samsung_cmu_info fsys0_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys0_shared1div4",
 };
 
+/* Register Offset definitions for CMU_FSYS1 (0x16810000) */
+#define PLL_CON0_ACLK_FSYS1_BUSP_MUX			0x100
+#define PLL_CON0_PCLKL_FSYS1_BUSP_MUX			0x180
+#define DIV_CLK_FSYS1_PHY0_OSCCLK			0x1800
+#define DIV_CLK_FSYS1_PHY1_OSCCLK			0x1804
+#define GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK	0x2000
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK		0x2004
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK	0x2008
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK		0x200c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL	0x202c
+#define GAT_FSYS1_PHY0_OSCCLLK				0x2034
+#define GAT_FSYS1_PHY1_OSCCLK				0x2038
+#define GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK		0x203c
+#define GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK	0x2040
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK	0x2048
+#define GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK	0x204c
+#define GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK		0x2054
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0	0x205c
+#define GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0	0x2064
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK		0x206c
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK	0x2070
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK	0x2074
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK	0x2078
+#define GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK		0x207c
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK		0x2080
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK	0x2084
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK	0x2088
+#define GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK		0x208c
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK		0x20a4
+#define GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL	0x20a8
+#define GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK		0x20b4
+#define GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK		0x20b8
+
+static const unsigned long fsys1_clk_regs[] __initconst = {
+	PLL_CON0_ACLK_FSYS1_BUSP_MUX,
+	PLL_CON0_PCLKL_FSYS1_BUSP_MUX,
+	DIV_CLK_FSYS1_PHY0_OSCCLK,
+	DIV_CLK_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL,
+	GAT_FSYS1_PHY0_OSCCLLK,
+	GAT_FSYS1_PHY1_OSCCLK,
+	GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK,
+	GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK,
+	GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0,
+	GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK,
+	GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK,
+	GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL,
+	GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK,
+	GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_fixed_rate_clock fsys1_fixed_clks[] __initconst = {
+	FRATE(0, "clk_fsys1_phy0_ref", NULL, 0, 100000000),
+	FRATE(0, "clk_fsys1_phy1_ref", NULL, 0, 100000000),
+};
+
+/* List of parent clocks for Muxes in CMU_FSYS1 */
+PNAME(mout_fsys1_pclkl_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div8" };
+PNAME(mout_fsys1_aclk_fsys1_busp_mux_p) = { "fin_pll", "dout_cmu_fsys1_shared0div4" };
+
+static const struct samsung_mux_clock fsys1_mux_clks[] __initconst = {
+	MUX(0, "mout_fsys1_pclkl_fsys1_busp_mux", mout_fsys1_pclkl_fsys1_busp_mux_p,
+	    PLL_CON0_PCLKL_FSYS1_BUSP_MUX, 4, 1),
+	MUX(0, "mout_fsys1_aclk_fsys1_busp_mux", mout_fsys1_aclk_fsys1_busp_mux_p,
+	    PLL_CON0_ACLK_FSYS1_BUSP_MUX, 4, 1),
+};
+
+static const struct samsung_div_clock fsys1_div_clks[] __initconst = {
+	DIV(0, "dout_fsys1_clk_fsys1_phy0_oscclk", "fsys1_phy0_osccllk",
+	    DIV_CLK_FSYS1_PHY0_OSCCLK, 0, 4),
+	DIV(0, "dout_fsys1_clk_fsys1_phy1_oscclk", "fsys1_phy1_oscclk",
+	    DIV_CLK_FSYS1_PHY1_OSCCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock fsys1_gate_clks[] __initconst = {
+	GATE(0, "fsys1_cmu_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_CMU_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_xtal", "clk_fsys1_phy0_ref",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_XTAL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy0_osccllk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY0_OSCCLLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_phy1_oscclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_PHY1_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_axi2apb_fsys1_ipclkport_aclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_AXI2APB_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_d0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_D0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_m250clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_M250CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_bus_s0_fsys1_ipclkport_mainclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_BUS_S0_FSYS1_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_cpe425_0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_CPE425_0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_d0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_D0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_ns_brdg_fsys1_ipclkport_clk__psoc_fsys1__clk_fsys1_s0",
+	     "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_NS_BRDG_FSYS1_IPCLKPORT_CLK__PSOC_FSYS1__CLK_FSYS1_S0, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link0_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_soc_ref_clk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_SOC_REF_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link0_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link0_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link0_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK0_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_DBI_ACLK, "fsys1_pcie_link1_ipclkport_dbi_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_DBI_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_link1_ipclkport_i_driver_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_I_DRIVER_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_MSTR_ACLK, "fsys1_pcie_link1_ipclkport_mstr_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_MSTR_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_SLV_ACLK, "fsys1_pcie_link1_ipclkport_slv_aclk",
+	     "mout_fsys1_aclk_fsys1_busp_mux", GAT_FSYS1_PCIE_LINK1_IPCLKPORT_SLV_ACLK, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_apb_clk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_APB_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK0_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link0_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK0_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(PCIE_LINK1_IPCLKPORT_AUX_ACLK, "fsys1_pcie_link1_ipclkport_auxclk", "fin_pll",
+	     GAT_FSYS1_PCIE_LINK1_IPCLKPORT_AUXCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_pcie_phy0_ipclkport_i_ref_soc_pll", "dout_fsys1_clk_fsys1_phy0_oscclk",
+	     GAT_FSYS1_PCIE_PHY0_IPCLKPORT_I_REF_SOC_PLL, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_sysreg_fsys1_ipclkport_pclk", "mout_fsys1_pclkl_fsys1_busp_mux",
+	     GAT_FSYS1_SYSREG_FSYS1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "fsys1_tbu0_fsys1_ipclkport_aclk", "mout_fsys1_aclk_fsys1_busp_mux",
+	     GAT_FSYS1_TBU0_FSYS1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
+	.mux_clks		= fsys1_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(fsys1_mux_clks),
+	.div_clks		= fsys1_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(fsys1_div_clks),
+	.gate_clks		= fsys1_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(fsys1_gate_clks),
+	.fixed_clks		= fsys1_fixed_clks,
+	.nr_fixed_clks		= ARRAY_SIZE(fsys1_fixed_clks),
+	.nr_clk_ids		= FSYS1_NR_CLK,
+	.clk_regs		= fsys1_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(fsys1_clk_regs),
+	.clk_name		= "dout_cmu_fsys1_shared0div4",
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -997,6 +1169,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys0",
 		.data = &fsys0_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-fsys1",
+		.data = &fsys1_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:36 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:36 +0530
Subject: [PATCH v5 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142928epcas5p4cb956c77eac815ff4347e8e3b09bfb54@epcas5p4.samsung.com>
Message-ID: <20220124141644.71052-9-alim.akhtar@samsung.com>

Adds cmu_imem clock related code, imem block contains IPs
like WDT, DMA, TMU etc, these clocks are required for such
IP function.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 283 ++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index 19c3ea35a6ea..f15b5b6b8eca 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1144,6 +1144,289 @@ static const struct samsung_cmu_info fsys1_cmu_info __initconst = {
 	.clk_name		= "dout_cmu_fsys1_shared0div4",
 };
 
+/* Register Offset definitions for CMU_IMEM (0x10010000) */
+#define PLL_CON0_CLK_IMEM_ACLK				0x100
+#define PLL_CON0_CLK_IMEM_INTMEMCLK			0x120
+#define PLL_CON0_CLK_IMEM_TCUCLK			0x140
+#define DIV_OSCCLK_IMEM_TMUTSCLK			0x1800
+#define GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK		0x2000
+#define GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO		0x2004
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK		0x2008
+#define GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK		0x200c
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK		0x2010
+#define GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS		0x2014
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK		0x2018
+#define GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS		0x201c
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK		0x2020
+#define GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS		0x2024
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK			0x2028
+#define GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS		0x202c
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK		0x2030
+#define GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS		0x2034
+#define GAT_IMEM_WDT0_IPCLKPORT_CLK			0x2038
+#define GAT_IMEM_WDT1_IPCLKPORT_CLK			0x203c
+#define GAT_IMEM_WDT2_IPCLKPORT_CLK			0x2040
+#define GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM	0x2044
+#define GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM	0x2048
+#define GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM	0x204c
+#define GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS	0x2050
+#define GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS	0x2054
+#define GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS	0x2058
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM		0x205c
+#define GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS		0x2060
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM		0x2064
+#define GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS		0x2068
+#define GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK		0x206c
+#define GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK		0x2070
+#define GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK		0x2074
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK		0x2078
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK		0x207c
+#define GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK		0x2080
+#define GAT_IMEM_DMA0_IPCLKPORT_ACLK			0x2084
+#define GAT_IMEM_DMA1_IPCLKPORT_ACLK			0x2088
+#define GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK	0x208c
+#define GAT_IMEM_GIC_IPCLKPORT_CLK			0x2090
+#define GAT_IMEM_INTMEM_IPCLKPORT_ACLK			0x2094
+#define GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK	0x2098
+#define GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK	0x209c
+#define GAT_IMEM_MCT_IPCLKPORT_PCLK			0x20a0
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D	0x20a4
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU	0x20a8
+#define GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P	0x20ac
+#define GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK		0x20b0
+#define GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK		0x20b4
+#define GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK	0x20b8
+#define GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK		0x20bc
+#define GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK		0x20c0
+#define GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK		0x20c4
+#define GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK		0x20c8
+#define GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK		0x20cc
+#define GAT_IMEM_TCU_IPCLKPORT_ACLK			0x20d0
+#define GAT_IMEM_WDT0_IPCLKPORT_PCLK			0x20d4
+#define GAT_IMEM_WDT1_IPCLKPORT_PCLK			0x20d8
+#define GAT_IMEM_WDT2_IPCLKPORT_PCLK			0x20dc
+
+static const unsigned long imem_clk_regs[] __initconst = {
+	PLL_CON0_CLK_IMEM_ACLK,
+	PLL_CON0_CLK_IMEM_INTMEMCLK,
+	PLL_CON0_CLK_IMEM_TCUCLK,
+	DIV_OSCCLK_IMEM_TMUTSCLK,
+	GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK,
+	GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK,
+	GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS,
+	GAT_IMEM_WDT0_IPCLKPORT_CLK,
+	GAT_IMEM_WDT1_IPCLKPORT_CLK,
+	GAT_IMEM_WDT2_IPCLKPORT_CLK,
+	GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM,
+	GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM,
+	GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS,
+	GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK,
+	GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK,
+	GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK,
+	GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK,
+	GAT_IMEM_DMA0_IPCLKPORT_ACLK,
+	GAT_IMEM_DMA1_IPCLKPORT_ACLK,
+	GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK,
+	GAT_IMEM_GIC_IPCLKPORT_CLK,
+	GAT_IMEM_INTMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK,
+	GAT_IMEM_MCT_IPCLKPORT_PCLK,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU,
+	GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P,
+	GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK,
+	GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK,
+	GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK,
+	GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK,
+	GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK,
+	GAT_IMEM_TCU_IPCLKPORT_ACLK,
+	GAT_IMEM_WDT0_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT1_IPCLKPORT_PCLK,
+	GAT_IMEM_WDT2_IPCLKPORT_PCLK,
+};
+
+PNAME(mout_imem_clk_imem_tcuclk_p) = { "fin_pll", "dout_cmu_imem_tcuclk" };
+PNAME(mout_imem_clk_imem_aclk_p) = { "fin_pll", "dout_cmu_imem_aclk" };
+PNAME(mout_imem_clk_imem_intmemclk_p) = { "fin_pll", "dout_cmu_imem_dmaclk" };
+
+static const struct samsung_mux_clock imem_mux_clks[] __initconst = {
+	MUX(0, "mout_imem_clk_imem_tcuclk", mout_imem_clk_imem_tcuclk_p,
+	    PLL_CON0_CLK_IMEM_TCUCLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_aclk", mout_imem_clk_imem_aclk_p, PLL_CON0_CLK_IMEM_ACLK, 4, 1),
+	MUX(0, "mout_imem_clk_imem_intmemclk", mout_imem_clk_imem_intmemclk_p,
+	    PLL_CON0_CLK_IMEM_INTMEMCLK, 4, 1),
+};
+
+static const struct samsung_div_clock imem_div_clks[] __initconst = {
+	DIV(0, "dout_imem_oscclk_imem_tmutsclk", "fin_pll", DIV_OSCCLK_IMEM_TMUTSCLK, 0, 4),
+};
+
+static const struct samsung_gate_clock imem_gate_clks[] __initconst = {
+	GATE(0, "imem_imem_cmu_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_IMEM_CMU_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_i_oscclk", "fin_pll",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_I_OSCCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_top_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gt_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu0_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_gpu_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mct_ipclkport_oscclk__alo", "fin_pll",
+	     GAT_IMEM_MCT_IPCLKPORT_OSCCLK__ALO, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt0_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt1_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_wdt2_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_WDT2_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu0_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU0_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, "imem_tmu_cpu2_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, "imem_tmu_gpu_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GPU_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, "imem_tmu_gt_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_GT_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, "imem_tmu_top_ipclkport_i_clk_ts",
+	     "dout_imem_oscclk_imem_tmutsclk",
+	     GAT_IMEM_TMU_TOP_IPCLKPORT_I_CLK_TS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i0_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I0_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i1_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I1_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_adm_axi4st_i2_imem_ipclkport_aclkm", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADM_AXI4ST_I2_IMEM_IPCLKPORT_ACLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i0_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I0_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i1_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I1_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ads_axi4st_i2_imem_ipclkport_aclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ADS_AXI4ST_I2_IMEM_IPCLKPORT_ACLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma0_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA0_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclkm", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_async_dma1_ipclkport_pclks", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_ASYNC_DMA1_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp0_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_axi2apb_imemp1_ipclkport_aclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_AXI2APB_IMEMP1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_d_imem_ipclkport_mainclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_D_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_mainclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_MAINCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_pericclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_PERICLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_bus_p_imem_ipclkport_tcuclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_BUS_P_IMEM_IPCLKPORT_TCUCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_DMA0_IPCLKPORT_ACLK, "imem_dma0_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(IMEM_DMA1_IPCLKPORT_ACLK, "imem_dma1_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_DMA1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED | CLK_IS_CRITICAL, 0),
+	GATE(0, "imem_gic500_input_sync_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC500_INPUT_SYNC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_gic_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_GIC_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_intmem_ipclkport_aclk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_INTMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_scs_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SCS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_mailbox_sms_ca72_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MAILBOX_SMS_CA72_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_MCT_PCLK, "imem_mct_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_MCT_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_d",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psco_imem__clk_imem_tcu",
+	     "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSCO_IMEM__CLK_IMEM_TCU, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_ns_brdg_imem_ipclkport_clk__psoc_imem__clk_imem_p", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_NS_BRDG_IMEM_IPCLKPORT_CLK__PSOC_IMEM__CLK_IMEM_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_otp_con_top_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_OTP_CON_TOP_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_aclk_ipclkport_clk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_RSTNSYNC_ACLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_oscclk_ipclkport_clk", "fin_pll",
+	     GAT_IMEM_RSTNSYNC_OSCCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_intmemclk_ipclkport_clk", "mout_imem_clk_imem_intmemclk",
+	     GAT_IMEM_RSTNSYNC_INTMEMCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_rstnsync_tcuclk_ipclkport_clk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_RSTNSYNC_TCUCLK_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu0_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU0_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sfrif_tmu1_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SFRIF_TMU1_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tmu_cpu2_ipclkport_i_clk", "fin_pll",
+	     GAT_IMEM_TMU_CPU2_IPCLKPORT_I_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_sysreg_imem_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_SYSREG_IMEM_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tbu_imem_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TBU_IMEM_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "imem_tcu_ipclkport_aclk", "mout_imem_clk_imem_tcuclk",
+	     GAT_IMEM_TCU_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT0_IPCLKPORT_PCLK, "imem_wdt0_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT1_IPCLKPORT_PCLK, "imem_wdt1_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(IMEM_WDT2_IPCLKPORT_PCLK, "imem_wdt2_ipclkport_pclk", "mout_imem_clk_imem_aclk",
+	     GAT_IMEM_WDT2_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info imem_cmu_info __initconst = {
+	.mux_clks		= imem_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(imem_mux_clks),
+	.div_clks		= imem_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(imem_div_clks),
+	.gate_clks		= imem_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(imem_gate_clks),
+	.nr_clk_ids		= IMEM_NR_CLK,
+	.clk_regs		= imem_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(imem_clk_regs),
+};
+
+static void __init fsd_clk_imem_init(struct device_node *np)
+{
+	samsung_cmu_register_one(np, &imem_cmu_info);
+}
+
+CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:37 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:37 +0530
Subject: [PATCH v5 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142933epcas5p4e69babee0d9ea6f94fef365d79329e20@epcas5p4.samsung.com>
Message-ID: <20220124141644.71052-10-alim.akhtar@samsung.com>

Adds cmu_mfc clock related code, these clocks are
required for MFC IP.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 121 ++++++++++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index f15b5b6b8eca..f9c4b4c5e0cb 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1427,6 +1427,124 @@ static void __init fsd_clk_imem_init(struct device_node *np)
 
 CLK_OF_DECLARE(fsd_clk_imem, "tesla,fsd-clock-imem", fsd_clk_imem_init);
 
+/* Register Offset definitions for CMU_MFC (0x12810000) */
+#define PLL_LOCKTIME_PLL_MFC					0x0
+#define PLL_CON0_PLL_MFC					0x100
+#define MUX_MFC_BUSD						0x1000
+#define MUX_MFC_BUSP						0x1008
+#define DIV_MFC_BUSD_DIV4					0x1800
+#define GAT_MFC_CMU_MFC_IPCLKPORT_PCLK				0x2000
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM			0x2004
+#define GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS			0x2008
+#define GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK			0x200c
+#define GAT_MFC_MFC_IPCLKPORT_ACLK				0x2010
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D	0x2018
+#define GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P	0x201c
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK			0x2028
+#define GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK			0x202c
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK			0x2030
+#define GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK			0x2034
+#define GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK			0x2038
+#define GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK				0x203c
+#define GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK				0x2040
+#define GAT_MFC_BUSD_DIV4_GATE					0x2044
+#define GAT_MFC_BUSD_GATE					0x2048
+
+static const unsigned long mfc_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_MFC,
+	PLL_CON0_PLL_MFC,
+	MUX_MFC_BUSD,
+	MUX_MFC_BUSP,
+	DIV_MFC_BUSD_DIV4,
+	GAT_MFC_CMU_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM,
+	GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS,
+	GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_MFC_IPCLKPORT_ACLK,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D,
+	GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK,
+	GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK,
+	GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK,
+	GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK,
+	GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK,
+	GAT_MFC_BUSD_DIV4_GATE,
+	GAT_MFC_BUSD_GATE,
+};
+
+static const struct samsung_pll_rate_table pll_mfc_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 666000000U, 111, 4, 0),
+};
+
+static const struct samsung_pll_clock mfc_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_mfc", "fin_pll",
+	    PLL_LOCKTIME_PLL_MFC, PLL_CON0_PLL_MFC, pll_mfc_rate_table),
+};
+
+PNAME(mout_mfc_pll_p) = { "fin_pll", "fout_pll_mfc" };
+PNAME(mout_mfc_busp_p) = { "fin_pll", "dout_mfc_busd_div4" };
+PNAME(mout_mfc_busd_p) = { "fin_pll", "mfc_busd_gate" };
+
+static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
+	MUX(0, "mout_mfc_pll", mout_mfc_pll_p, PLL_CON0_PLL_MFC, 4, 1),
+	MUX(0, "mout_mfc_busp", mout_mfc_busp_p, MUX_MFC_BUSP, 0, 1),
+	MUX(0, "mout_mfc_busd", mout_mfc_busd_p, MUX_MFC_BUSD, 0, 1),
+};
+
+static const struct samsung_div_clock mfc_div_clks[] __initconst = {
+	DIV(0, "dout_mfc_busd_div4", "mfc_busd_div4_gate", DIV_MFC_BUSD_DIV4, 0, 4),
+};
+
+static const struct samsung_gate_clock mfc_gate_clks[] __initconst = {
+	GATE(0, "mfc_cmu_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_CMU_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclkm", "mout_mfc_busd",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKM, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_as_p_mfc_ipclkport_pclks", "mout_mfc_busp",
+	     GAT_MFC_AS_P_MFC_IPCLKPORT_PCLKS, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_axi2apb_mfc_ipclkport_aclk", "mout_mfc_busp",
+	     GAT_MFC_AXI2APB_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(MFC_MFC_IPCLKPORT_ACLK, "mfc_mfc_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_MFC_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_d", "mout_mfc_busd",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_D, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ns_brdg_mfc_ipclkport_clk__pmfc__clk_mfc_p", "mout_mfc_busp",
+	     GAT_MFC_NS_BRDG_MFC_IPCLKPORT_CLK__PMFC__CLK_MFC_P, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd0_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD0_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_aclk", "mout_mfc_busd",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_ppmu_mfcd1_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_PPMU_MFCD1_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_sysreg_mfc_ipclkport_pclk", "mout_mfc_busp",
+	     GAT_MFC_SYSREG_MFC_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd0_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD0_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_tbu_mfcd1_ipclkport_clk", "mout_mfc_busd",
+	     GAT_MFC_TBU_MFCD1_IPCLKPORT_CLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_div4_gate", "mout_mfc_pll",
+	     GAT_MFC_BUSD_DIV4_GATE, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "mfc_busd_gate", "mout_mfc_pll", GAT_MFC_BUSD_GATE, 21, CLK_IS_CRITICAL, 0),
+};
+
+static const struct samsung_cmu_info mfc_cmu_info __initconst = {
+	.pll_clks		= mfc_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(mfc_pll_clks),
+	.mux_clks		= mfc_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(mfc_mux_clks),
+	.div_clks		= mfc_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(mfc_div_clks),
+	.gate_clks		= mfc_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(mfc_gate_clks),
+	.nr_clk_ids		= MFC_NR_CLK,
+	.clk_regs		= mfc_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1455,6 +1573,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-fsys1",
 		.data = &fsys1_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-mfc",
+		.data = &mfc_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:38 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:38 +0530
Subject: [PATCH v5 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142937epcas5p3bdce50bbaa02bbd762cf000401e03ade@epcas5p3.samsung.com>
Message-ID: <20220124141644.71052-11-alim.akhtar@samsung.com>

Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Sathyakam M <sathya at samsung.com>
Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 drivers/clk/samsung/clk-fsd.c | 207 ++++++++++++++++++++++++++++++++++
 1 file changed, 207 insertions(+)

diff --git a/drivers/clk/samsung/clk-fsd.c b/drivers/clk/samsung/clk-fsd.c
index f9c4b4c5e0cb..5d009c70e97d 100644
--- a/drivers/clk/samsung/clk-fsd.c
+++ b/drivers/clk/samsung/clk-fsd.c
@@ -1545,6 +1545,210 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
 	.nr_clk_regs		= ARRAY_SIZE(mfc_clk_regs),
 };
 
+/* Register Offset definitions for CMU_CAM_CSI (0x12610000) */
+#define PLL_LOCKTIME_PLL_CAM_CSI		0x0
+#define PLL_CON0_PLL_CAM_CSI			0x100
+#define DIV_CAM_CSI0_ACLK			0x1800
+#define DIV_CAM_CSI1_ACLK			0x1804
+#define DIV_CAM_CSI2_ACLK			0x1808
+#define DIV_CAM_CSI_BUSD			0x180c
+#define DIV_CAM_CSI_BUSP			0x1810
+#define GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK	0x2000
+#define GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK	0x2004
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0	0x2008
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1	0x200c
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2	0x2010
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC	0x2014
+#define GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC		0x2018
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK		0x201c
+#define GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK		0x2020
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK		0x2024
+#define GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK		0x2028
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK		0x202c
+#define GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK		0x2030
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK		0x2034
+#define GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK		0x2038
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK		0x203c
+#define GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK		0x2040
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK		0x2044
+#define GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK		0x2048
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK		0x204c
+#define GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK		0x2050
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK		0x2054
+#define GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK		0x2058
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK		0x205c
+#define GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK		0x2060
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK		0x2064
+#define GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK		0x2068
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK		0x206c
+#define GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK		0x2070
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK		0x2074
+#define GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK		0x2078
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D	0x207c
+#define GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P	0x2080
+#define GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK	0x2084
+#define GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK	0x2088
+
+static const unsigned long cam_csi_clk_regs[] __initconst = {
+	PLL_LOCKTIME_PLL_CAM_CSI,
+	PLL_CON0_PLL_CAM_CSI,
+	DIV_CAM_CSI0_ACLK,
+	DIV_CAM_CSI1_ACLK,
+	DIV_CAM_CSI2_ACLK,
+	DIV_CAM_CSI_BUSD,
+	DIV_CAM_CSI_BUSP,
+	GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC,
+	GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK,
+	GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D,
+	GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P,
+	GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK,
+	GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK,
+};
+
+static const struct samsung_pll_rate_table pll_cam_csi_rate_table[] __initconst = {
+	PLL_35XX_RATE(24 * MHZ, 1066000000U, 533, 12, 0),
+};
+
+static const struct samsung_pll_clock cam_csi_pll_clks[] __initconst = {
+	PLL(pll_142xx, 0, "fout_pll_cam_csi", "fin_pll",
+	    PLL_LOCKTIME_PLL_CAM_CSI, PLL_CON0_PLL_CAM_CSI, pll_cam_csi_rate_table),
+};
+
+PNAME(mout_cam_csi_pll_p) = { "fin_pll", "fout_pll_cam_csi" };
+
+static const struct samsung_mux_clock cam_csi_mux_clks[] __initconst = {
+	MUX(0, "mout_cam_csi_pll", mout_cam_csi_pll_p, PLL_CON0_PLL_CAM_CSI, 4, 1),
+};
+
+static const struct samsung_div_clock cam_csi_div_clks[] __initconst = {
+	DIV(0, "dout_cam_csi0_aclk", "mout_cam_csi_pll", DIV_CAM_CSI0_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi1_aclk", "mout_cam_csi_pll", DIV_CAM_CSI1_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi2_aclk", "mout_cam_csi_pll", DIV_CAM_CSI2_ACLK, 0, 4),
+	DIV(0, "dout_cam_csi_busd", "mout_cam_csi_pll", DIV_CAM_CSI_BUSD, 0, 4),
+	DIV(0, "dout_cam_csi_busp", "mout_cam_csi_pll", DIV_CAM_CSI_BUSP, 0, 4),
+};
+
+static const struct samsung_gate_clock cam_csi_gate_clks[] __initconst = {
+	GATE(0, "cam_csi_cmu_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI_CMU_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_axi2apb_cam_csi_ipclkport_aclk", "dout_cam_csi_busp",
+	     GAT_CAM_AXI2APB_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi0", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI0, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi1", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI1, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_csi2", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_CSI2, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__clk_soc_noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__CLK_SOC_NOC, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi_bus_d_cam_csi_ipclkport_clk__system__noc", "dout_cam_csi_busd",
+	     GAT_CAM_CSI_BUS_D_CAM_CSI_IPCLKPORT_CLK__SYSTEM__NOC, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_0_IPCLKPORT_I_ACLK, "cam_csi0_0_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_1_IPCLKPORT_I_ACLK, "cam_csi0_1_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_2_IPCLKPORT_I_ACLK, "cam_csi0_2_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI0_3_IPCLKPORT_I_ACLK, "cam_csi0_3_ipclkport_i_aclk", "dout_cam_csi0_aclk",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi0_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI0_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_0_IPCLKPORT_I_ACLK, "cam_csi1_0_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_1_IPCLKPORT_I_ACLK, "cam_csi1_1_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_2_IPCLKPORT_I_ACLK, "cam_csi1_2_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI1_3_IPCLKPORT_I_ACLK, "cam_csi1_3_ipclkport_i_aclk", "dout_cam_csi1_aclk",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi1_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI1_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_0_IPCLKPORT_I_ACLK, "cam_csi2_0_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_0_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_0_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_1_IPCLKPORT_I_ACLK, "cam_csi2_1_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_1_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_1_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_2_IPCLKPORT_I_ACLK, "cam_csi2_2_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_2_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_2_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(CAM_CSI2_3_IPCLKPORT_I_ACLK, "cam_csi2_3_ipclkport_i_aclk", "dout_cam_csi2_aclk",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_csi2_3_ipclkport_i_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_CSI2_3_IPCLKPORT_I_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_d",
+	     "dout_cam_csi_busd",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_D, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_ns_brdg_cam_csi_ipclkport_clk__psoc_cam_csi__clk_cam_csi_p",
+	     "dout_cam_csi_busp",
+	     GAT_CAM_NS_BRDG_CAM_CSI_IPCLKPORT_CLK__PSOC_CAM_CSI__CLK_CAM_CSI_P, 21,
+	     CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_sysreg_cam_csi_ipclkport_pclk", "dout_cam_csi_busp",
+	     GAT_CAM_SYSREG_CAM_CSI_IPCLKPORT_PCLK, 21, CLK_IGNORE_UNUSED, 0),
+	GATE(0, "cam_tbu_cam_csi_ipclkport_aclk", "dout_cam_csi_busd",
+	     GAT_CAM_TBU_CAM_CSI_IPCLKPORT_ACLK, 21, CLK_IGNORE_UNUSED, 0),
+};
+
+static const struct samsung_cmu_info cam_csi_cmu_info __initconst = {
+	.pll_clks		= cam_csi_pll_clks,
+	.nr_pll_clks		= ARRAY_SIZE(cam_csi_pll_clks),
+	.mux_clks		= cam_csi_mux_clks,
+	.nr_mux_clks		= ARRAY_SIZE(cam_csi_mux_clks),
+	.div_clks		= cam_csi_div_clks,
+	.nr_div_clks		= ARRAY_SIZE(cam_csi_div_clks),
+	.gate_clks		= cam_csi_gate_clks,
+	.nr_gate_clks		= ARRAY_SIZE(cam_csi_gate_clks),
+	.nr_clk_ids		= CAM_CSI_NR_CLK,
+	.clk_regs		= cam_csi_clk_regs,
+	.nr_clk_regs		= ARRAY_SIZE(cam_csi_clk_regs),
+};
+
 /**
  * fsd_cmu_probe - Probe function for FSD platform clocks
  * @pdev: Pointer to platform device
@@ -1576,6 +1780,9 @@ static const struct of_device_id fsd_cmu_of_match[] = {
 	}, {
 		.compatible = "tesla,fsd-clock-mfc",
 		.data = &mfc_cmu_info,
+	}, {
+		.compatible = "tesla,fsd-clock-cam_csi",
+		.data = &cam_csi_cmu_info,
 	}, {
 	},
 };
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:39 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:39 +0530
Subject: [PATCH v5 11/16] dt-bindings: pinctrl: samsung: Add compatible for
 Tesla FSD SoC
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142941epcas5p4bbba53cfc2fc9862da9fd85d44de6e79@epcas5p4.samsung.com>
Message-ID: <20220124141644.71052-12-alim.akhtar@samsung.com>

Add compatible for Tesla Full Self-Driving SoC. The
pinctrl hardware IP is similar to what found on most of the
Exynos series of SoC, so this new compatible is added in
Samsung pinctrl binding.

Cc: linux-fsd at tesla.com
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
index 28f0851d07bb..989e48c051cf 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
@@ -56,6 +56,7 @@ properties:
       - samsung,exynos7885-pinctrl
       - samsung,exynos850-pinctrl
       - samsung,exynosautov9-pinctrl
+      - tesla,fsd-pinctrl
 
   interrupts:
     description:
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:40 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:40 +0530
Subject: [PATCH v5 12/16] pinctrl: samsung: add FSD SoC specific data
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142946epcas5p11997a3c37546d37cac91f690a2a602bf@epcas5p1.samsung.com>
Message-ID: <20220124141644.71052-13-alim.akhtar@samsung.com>

Adds Tesla FSD SoC specific data to enable pinctrl.
FSD SoC has similar pinctrl controller as found in the most
Samsung/Exynos SoCs.

Cc: linux-fsd at tesla.com
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../pinctrl/samsung/pinctrl-exynos-arm64.c    | 71 +++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c     |  2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h     |  1 +
 3 files changed, 74 insertions(+)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
index 4102ce955bd7..d291819c2f77 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c
@@ -725,3 +725,74 @@ const struct samsung_pinctrl_of_match_data exynosautov9_of_data __initconst = {
 	.ctrl		= exynosautov9_pin_ctrl,
 	.num_ctrl	= ARRAY_SIZE(exynosautov9_pin_ctrl),
 };
+
+/*
+ * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three
+ * gpio/pin-mux/pinconfig controllers.
+ */
+
+/* pin banks of FSD pin-controller 0 (FSYS) */
+static const struct samsung_pin_bank_data fsd_pin_banks0[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(7, 0x00, "gpf0", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x20, "gpf1", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(3, 0x40, "gpf6", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(2, 0x60, "gpf4", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(6, 0x80, "gpf5", 0x10),
+};
+
+/* pin banks of FSD pin-controller 1 (PERIC) */
+static const struct samsung_pin_bank_data fsd_pin_banks1[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gpc8", 0x00),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x020, "gpf2", 0x04),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x040, "gpf3", 0x08),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x060, "gpd0", 0x0c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x080, "gpb0", 0x10),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0a0, "gpb1", 0x14),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x0c0, "gpb4", 0x18),
+	EXYNOS850_PIN_BANK_EINTG(4, 0x0e0, "gpb5", 0x1c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x100, "gpb6", 0x20),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x120, "gpb7", 0x24),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x140, "gpd1", 0x28),
+	EXYNOS850_PIN_BANK_EINTG(5, 0x160, "gpd2", 0x2c),
+	EXYNOS850_PIN_BANK_EINTG(7, 0x180, "gpd3", 0x30),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1a0, "gpg0", 0x34),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1c0, "gpg1", 0x38),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x1e0, "gpg2", 0x3c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x200, "gpg3", 0x40),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x220, "gpg4", 0x44),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x240, "gpg5", 0x48),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x260, "gpg6", 0x4c),
+	EXYNOS850_PIN_BANK_EINTG(8, 0x280, "gpg7", 0x50),
+};
+
+/* pin banks of FSD pin-controller 2 (PMU) */
+static const struct samsung_pin_bank_data fsd_pin_banks2[] __initconst = {
+	EXYNOS850_PIN_BANK_EINTN(3, 0x00, "gpq0"),
+};
+
+const struct samsung_pin_ctrl fsd_pin_ctrl[] __initconst = {
+	{
+		/* pin-controller instance 0 FSYS0 data */
+		.pin_banks	= fsd_pin_banks0,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks0),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 1 PERIC data */
+		.pin_banks	= fsd_pin_banks1,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks1),
+		.eint_gpio_init = exynos_eint_gpio_init,
+		.suspend	= exynos_pinctrl_suspend,
+		.resume		= exynos_pinctrl_resume,
+	}, {
+		/* pin-controller instance 2 PMU data */
+		.pin_banks	= fsd_pin_banks2,
+		.nr_banks	= ARRAY_SIZE(fsd_pin_banks2),
+	},
+};
+
+const struct samsung_pinctrl_of_match_data fsd_of_data __initconst = {
+	.ctrl		= fsd_pin_ctrl,
+	.num_ctrl	= ARRAY_SIZE(fsd_pin_ctrl),
+};
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c
index 568b6e65dfed..f610beab23a0 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.c
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.c
@@ -1320,6 +1320,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = &exynos850_of_data },
 	{ .compatible = "samsung,exynosautov9-pinctrl",
 		.data = &exynosautov9_of_data },
+	{ .compatible = "tesla,fsd-pinctrl",
+		.data = &fsd_of_data },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 1f8d30ba05af..5b32d3f30fcd 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -342,6 +342,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos7885_of_data;
 extern const struct samsung_pinctrl_of_match_data exynos850_of_data;
 extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data;
+extern const struct samsung_pinctrl_of_match_data fsd_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c64xx_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2412_of_data;
 extern const struct samsung_pinctrl_of_match_data s3c2416_of_data;
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:41 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:41 +0530
Subject: [PATCH v5 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142951epcas5p255712c3a9e37b9542687587d8114bda3@epcas5p2.samsung.com>
Message-ID: <20220124141644.71052-14-alim.akhtar@samsung.com>

Add device tree bindings for the Tesla FSD ARM SoC.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 .../devicetree/bindings/arm/tesla.yaml        | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/tesla.yaml

diff --git a/Documentation/devicetree/bindings/arm/tesla.yaml b/Documentation/devicetree/bindings/arm/tesla.yaml
new file mode 100644
index 000000000000..09856da657dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tesla.yaml
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/tesla.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tesla Full Self Driving(FSD) platforms device tree bindings
+
+maintainers:
+  - Alim Akhtar <alim.akhtar at samsung.com>
+  - linux-fsd at tesla.com
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: FSD SoC board
+        items:
+          - enum:
+              - tesla,fsd-evb   # Tesla FSD Evaluation
+          - const: tesla,fsd
+
+additionalProperties: true
+
+...
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:42 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:42 +0530
Subject: [PATCH v5 14/16] arm64: dts: fsd: Add initial device tree support
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142957epcas5p27ab08d4eb02fe53a03e2b36ab1d913f8@epcas5p2.samsung.com>
Message-ID: <20220124141644.71052-15-alim.akhtar@samsung.com>

Add initial device tree support for "Full Self-Driving" (FSD) SoC
This SoC contain three clusters of four cortex-a72 CPUs and various
peripheral IPs.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Arjun K V <arjun.kv at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 MAINTAINERS                           |   8 +
 arch/arm64/Kconfig.platforms          |   6 +
 arch/arm64/boot/dts/Makefile          |   1 +
 arch/arm64/boot/dts/tesla/Makefile    |   3 +
 arch/arm64/boot/dts/tesla/fsd-evb.dts |  39 ++
 arch/arm64/boot/dts/tesla/fsd.dtsi    | 652 ++++++++++++++++++++++++++
 6 files changed, 709 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/Makefile
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-evb.dts
 create mode 100644 arch/arm64/boot/dts/tesla/fsd.dtsi

diff --git a/MAINTAINERS b/MAINTAINERS
index 89f23af16451..d97d3a5d7f39 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2753,6 +2753,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/tegra-cec.txt
 F:	drivers/media/cec/platform/tegra/
 
+ARM/TESLA FSD SoC SUPPORT
+M:	Alim Akhtar <alim.akhtar at samsung.com>
+M:	linux-fsd at tesla.com
+L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
+L:	linux-samsung-soc at vger.kernel.org
+S:	Maintained
+F:	arch/arm64/boot/dts/tesla*
+
 ARM/TETON BGA MACHINE SUPPORT
 M:	"Mark F. Brown" <mark.brown314 at gmail.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..739254493d6a 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -268,6 +268,12 @@ config ARCH_TEGRA
 	help
 	  This enables support for the NVIDIA Tegra SoC family.
 
+config ARCH_TESLA_FSD
+	bool "ARMv8 based Tesla platform"
+	depends on ARCH_EXYNOS
+	help
+	  Support for ARMv8 based Tesla platforms.
+
 config ARCH_SPRD
 	bool "Spreadtrum SoC platform"
 	help
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
index 639e01a4d855..1ba04e31a438 100644
--- a/arch/arm64/boot/dts/Makefile
+++ b/arch/arm64/boot/dts/Makefile
@@ -27,6 +27,7 @@ subdir-y += rockchip
 subdir-y += socionext
 subdir-y += sprd
 subdir-y += synaptics
+subdir-y += tesla
 subdir-y += ti
 subdir-y += toshiba
 subdir-y += xilinx
diff --git a/arch/arm64/boot/dts/tesla/Makefile b/arch/arm64/boot/dts/tesla/Makefile
new file mode 100644
index 000000000000..a1ee50e2fd06
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+dtb-$(CONFIG_ARCH_TESLA_FSD) += \
+	fsd-evb.dtb
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts
new file mode 100644
index 000000000000..5af560c1b5e6
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/*
+ * Tesla FSD board device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+/dts-v1/;
+#include "fsd.dtsi"
+
+/ {
+	model = "Tesla Full Self-Driving (FSD) Evaluation board";
+	compatible = "tesla,fsd-evb", "tesla,fsd";
+
+	aliases {
+		serial0 = &serial_0;
+		serial1 = &serial_1;
+	};
+
+	chosen {
+		stdout-path = &serial_0;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x2 0x00000000>;
+	};
+};
+
+&fin_pll {
+	clock-frequency = <24000000>;
+};
+
+&serial_0 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
new file mode 100644
index 000000000000..25b480147541
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2022 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/clock/fsd-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	compatible = "tesla,fsd";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		i2c0 = &hsi2c_0;
+		i2c1 = &hsi2c_1;
+		i2c2 = &hsi2c_2;
+		i2c3 = &hsi2c_3;
+		i2c4 = &hsi2c_4;
+		i2c5 = &hsi2c_5;
+		i2c6 = &hsi2c_6;
+		i2c7 = &hsi2c_7;
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpucl0_0>;
+				};
+				core1 {
+					cpu = <&cpucl0_1>;
+				};
+				core2 {
+					cpu = <&cpucl0_2>;
+				};
+				core3 {
+					cpu = <&cpucl0_3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpucl1_0>;
+				};
+				core1 {
+					cpu = <&cpucl1_1>;
+				};
+				core2 {
+					cpu = <&cpucl1_2>;
+				};
+				core3 {
+					cpu = <&cpucl1_3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpucl2_0>;
+				};
+				core1 {
+					cpu = <&cpucl2_1>;
+				};
+				core2 {
+					cpu = <&cpucl2_2>;
+				};
+				core3 {
+					cpu = <&cpucl2_3>;
+				};
+			};
+		};
+
+		/* Cluster 0 */
+		cpucl0_0: cpu at 0 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x000>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_1: cpu at 1 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x001>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_2: cpu at 2 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x002>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl0_3: cpu at 3 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x003>;
+				enable-method = "psci";
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 1 */
+		cpucl1_0: cpu at 100 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x100>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_1: cpu at 101 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x101>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_2: cpu at 102 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x102>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl1_3: cpu at 103 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x103>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		/* Cluster 2 */
+		cpucl2_0: cpu at 200 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x200>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_1: cpu at 201 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x201>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_2: cpu at 202 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x202>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		cpucl2_3: cpu at 203 {
+				device_type = "cpu";
+				compatible = "arm,cortex-a72";
+				reg = <0x0 0x203>;
+				enable-method = "psci";
+				clock-frequency = <2400000000>;
+				cpu-idle-states = <&CPU_SLEEP>;
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			CPU_SLEEP: cpu-sleep {
+				idle-state-name = "c2";
+				compatible = "arm,idle-state";
+				local-timer-stop;
+				arm,psci-suspend-param = <0x0010000>;
+				entry-latency-us = <30>;
+				exit-latency-us = <75>;
+				min-residency-us = <300>;
+			};
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 385 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 387 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-affinity = <&cpucl0_0>, <&cpucl0_1>, <&cpucl0_2>,
+				     <&cpucl0_3>, <&cpucl1_0>, <&cpucl1_1>,
+				     <&cpucl1_2>, <&cpucl1_3>, <&cpucl2_0>,
+				     <&cpucl2_1>, <&cpucl2_2>, <&cpucl2_3>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	fin_pll: clock {
+		compatible = "fixed-clock";
+		clock-output-names = "fin_pll";
+		#clock-cells = <0>;
+	};
+
+	soc: soc at 0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>;
+		dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>;
+
+		gic: interrupt-controller at 10400000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			reg =	<0x0 0x10400000 0x0 0x10000>, /* GICD */
+				<0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		smmu_imem: iommu at 10200000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x10200000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <7>;
+			interrupts = <GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 441 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_0 */
+				     <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS1_1 */
+				     <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>, /* for IMEM_0  */
+				     /* Per context non-secure context interrupts, 0-3 interrupts */
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */
+		};
+
+		smmu_isp: iommu at 12100000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x12100000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <11>;
+			interrupts = <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_CSI   */
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_0  */
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_DP_1  */
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_0 */
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_ISP_1 */
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_0 */
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>, /* for CAM_MFC_1 */
+				     /* Per context non-secure context interrupts, 0-7 interrupts */
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_1 */
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_2 */
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_3 */
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_4 */
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_5 */
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_6 */
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */
+		};
+
+		smmu_peric: iommu at 14900000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x14900000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		smmu_fsys0: iommu at 15450000 {
+			compatible = "arm,mmu-500";
+			reg = <0x0 0x15450000 0x0 0x10000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <5>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */
+				     /* Performance counter interrupts */
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0   */
+				     /* Per context non-secure context interrupts, 0-1 interrupts */
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */
+		};
+
+		clock_imem: clock-controller at 10010000 {
+			compatible = "tesla,fsd-clock-imem";
+			reg = <0x0 0x10010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_IMEM_TCUCLK>,
+				<&clock_cmu DOUT_CMU_IMEM_ACLK>,
+				<&clock_cmu DOUT_CMU_IMEM_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_imem_tcuclk",
+				"dout_cmu_imem_aclk",
+				"dout_cmu_imem_dmaclk";
+		};
+
+		clock_cmu: clock-controller at 11c10000 {
+			compatible = "tesla,fsd-clock-cmu";
+			reg = <0x0 0x11c10000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_csi: clock-controller at 12610000 {
+			compatible = "tesla,fsd-clock-cam_csi";
+			reg = <0x0 0x12610000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_mfc: clock-controller at 12810000 {
+			compatible = "tesla,fsd-clock-mfc";
+			reg = <0x0 0x12810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>;
+			clock-names = "fin_pll";
+		};
+
+		clock_peric: clock-controller at 14010000 {
+			compatible = "tesla,fsd-clock-peric";
+			reg = <0x0 0x14010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV4>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV36>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV3_TBUCLK>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED0DIV20>,
+				<&clock_cmu DOUT_CMU_PERIC_SHARED1DIV4_DMACLK>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div4",
+				"dout_cmu_peric_shared1div36",
+				"dout_cmu_peric_shared0div3_tbuclk",
+				"dout_cmu_peric_shared0div20",
+				"dout_cmu_peric_shared1div4_dmaclk";
+		};
+
+		clock_fsys0: clock-controller at 15010000 {
+			compatible = "tesla,fsd-clock-fsys0";
+			reg = <0x0 0x15010000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>,
+				<&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_pll_shared0_div6",
+				"dout_cmu_fsys0_shared1div4",
+				"dout_cmu_fsys0_shared0div4";
+		};
+
+		clock_fsys1: clock-controller at 16810000 {
+			compatible = "tesla,fsd-clock-fsys1";
+			reg = <0x0 0x16810000 0x0 0x3000>;
+			#clock-cells = <1>;
+			clocks = <&fin_pll>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>,
+				<&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>;
+			clock-names = "fin_pll",
+				"dout_cmu_fsys1_shared0div8",
+				"dout_cmu_fsys1_shared0div4";
+		};
+
+		mdma0: dma-controller at 10100000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10100000 0x0 0x1000>;
+			interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x800 0x0>;
+		};
+
+		mdma1: dma-controller at 10110000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x10110000 0x0 0x1000>;
+			interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_imem 0x801 0x0>;
+		};
+
+		pdma0: dma-controller at 14280000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14280000 0x0 0x1000>;
+			interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x2 0x0>;
+		};
+
+		pdma1: dma-controller at 14290000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x0 0x14290000 0x0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			#dma-channels = <8>;
+			#dma-requests = <32>;
+			clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>;
+			clock-names = "apb_pclk";
+			iommus = <&smmu_peric 0x1 0x0>;
+		};
+
+		serial_0: serial at 14180000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14180000 0x0 0x100>;
+			interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 1>, <&pdma1 0>;
+			dma-names = "rx", "tx";
+			clocks = <&clock_peric PERIC_PCLK_UART0>,
+				 <&clock_peric PERIC_SCLK_UART0>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		serial_1: serial at 14190000 {
+			compatible = "samsung,exynos4210-uart";
+			reg = <0x0 0x14190000 0x0 0x100>;
+			interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 3>, <&pdma1 2>;
+			dma-names = "rx", "tx";
+			clocks = <&clock_peric PERIC_PCLK_UART1>,
+				 <&clock_peric PERIC_SCLK_UART1>;
+			clock-names = "uart", "clk_uart_baud0";
+			status = "disabled";
+		};
+
+		pmu_system_controller: system-controller at 11400000 {
+			compatible = "samsung,exynos7-pmu", "syscon";
+			reg = <0x0 0x11400000 0x0 0x5000>;
+		};
+
+		watchdog_0: watchdog at 100a0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100a0000 0x0 0x100>;
+			interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_1: watchdog at 100b0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100b0000 0x0 0x100>;
+			interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		watchdog_2: watchdog at 100c0000 {
+			compatible = "samsung,exynos7-wdt";
+			reg = <0x0 0x100c0000 0x0 0x100>;
+			interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
+			samsung,syscon-phandle = <&pmu_system_controller>;
+			clocks = <&fin_pll>;
+			clock-names = "watchdog";
+		};
+
+		pwm_0: pwm at 14100000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14100000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		pwm_1: pwm at 14110000 {
+			compatible = "samsung,exynos4210-pwm";
+			reg = <0x0 0x14110000 0x0 0x100>;
+			samsung,pwm-outputs = <0>, <1>, <2>, <3>;
+			#pwm-cells = <3>;
+			clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>;
+			clock-names = "timers";
+			status = "disabled";
+		};
+
+		hsi2c_0: i2c at 14200000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14200000 0x0 0x1000>;
+			interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c0_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C0>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_1: i2c at 14210000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14210000 0x0 0x1000>;
+			interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c1_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C1>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_2: i2c at 14220000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14220000 0x0 0x1000>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c2_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C2>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_3: i2c at 14230000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14230000 0x0 0x1000>;
+			interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c3_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C3>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_4: i2c at 14240000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14240000 0x0 0x1000>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c4_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C4>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_5: i2c at 14250000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14250000 0x0 0x1000>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c5_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C5>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_6: i2c at 14260000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14260000 0x0 0x1000>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c6_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C6>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+
+		hsi2c_7: i2c at 14270000 {
+			compatible = "samsung,exynos7-hsi2c";
+			reg = <0x0 0x14270000 0x0 0x1000>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&hs_i2c7_bus>;
+			clocks = <&clock_peric PERIC_PCLK_HSI2C7>;
+			clock-names = "hsi2c";
+			status = "disabled";
+		};
+	};
+};
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:43 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:43 +0530
Subject: [PATCH v5 15/16] arm64: dts: fsd: Add initial pinctrl support
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124143001epcas5p4c0aab0902709a24bbedadaa223fe7910@epcas5p4.samsung.com>
Message-ID: <20220124141644.71052-16-alim.akhtar@samsung.com>

Add initial pin configuration nodes for FSD SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Shashank Prashar <s.prashar at samsung.com>
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi | 335 +++++++++++++++++++++
 arch/arm64/boot/dts/tesla/fsd.dtsi         |  22 ++
 2 files changed, 357 insertions(+)
 create mode 100644 arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi

diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
new file mode 100644
index 000000000000..d4d0cb005712
--- /dev/null
+++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Tesla Full Self-Driving SoC device tree source
+ *
+ * Copyright (c) 2017-2021 Samsung Electronics Co., Ltd.
+ *		https://www.samsung.com
+ * Copyright (c) 2017-2021 Tesla, Inc.
+ *		https://www.tesla.com
+ */
+
+#include <dt-bindings/pinctrl/samsung.h>
+
+&pinctrl_fsys0 {
+	gpf0: gpf0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf1: gpf1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf6: gpf6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf4: gpf4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf5: gpf5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+};
+
+&pinctrl_peric {
+	gpc8: gpc8-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf2: gpf2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpf3: gpf3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd0: gpd0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb0: gpb0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb1: gpb1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb4: gpb4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb5: gpb5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb6: gpb6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpb7: gpb7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd1: gpd1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd2: gpd2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpd3: gpd3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg0: gpg0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg1: gpg1-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg2: gpg2-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg3: gpg3-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg4: gpg4-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg5: gpg5-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg6: gpg6-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	gpg7: gpg7-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+
+		interrupt-controller;
+		#interrupt-cells = <2>;
+	};
+
+	pwm0_out: pwm0-out-pins {
+		samsung,pins = "gpb6-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	pwm1_out: pwm1-out-pins {
+		samsung,pins = "gpb6-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV2>;
+	};
+
+	hs_i2c0_bus: hs-i2c0-bus-pins {
+		samsung,pins = "gpb0-0", "gpb0-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c1_bus: hs-i2c1-bus-pins {
+		samsung,pins = "gpb0-2", "gpb0-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c2_bus: hs-i2c2-bus-pins {
+		samsung,pins = "gpb0-4", "gpb0-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c3_bus: hs-i2c3-bus-pins {
+		samsung,pins = "gpb0-6", "gpb0-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c4_bus: hs-i2c4-bus-pins {
+		samsung,pins = "gpb1-0", "gpb1-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c5_bus: hs-i2c5-bus-pins {
+		samsung,pins = "gpb1-2", "gpb1-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c6_bus: hs-i2c6-bus-pins {
+		samsung,pins = "gpb1-4", "gpb1-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	hs_i2c7_bus: hs-i2c7-bus-pins {
+		samsung,pins = "gpb1-6", "gpb1-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart0_data: uart0-data-pins {
+		samsung,pins = "gpb7-0", "gpb7-1";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	uart1_data: uart1-data-pins {
+		samsung,pins = "gpb7-4", "gpb7-5";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi0_bus: spi0-bus-pins {
+		samsung,pins = "gpb4-0", "gpb4-2", "gpb4-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi1_bus: spi1-bus-pins {
+		samsung,pins = "gpb4-4", "gpb4-6", "gpb4-7";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+
+	spi2_bus: spi2-bus-pins {
+		samsung,pins = "gpb5-0", "gpb5-2", "gpb5-3";
+		samsung,pin-function = <EXYNOS_PIN_FUNC_2>;
+		samsung,pin-pud = <EXYNOS_PIN_PULL_UP>;
+		samsung,pin-drv = <EXYNOS4_PIN_DRV_LV1>;
+	};
+};
+
+&pinctrl_pmu {
+	gpq0: gpq0-gpio-bank {
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+};
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index 25b480147541..b7f05f78c601 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -26,6 +26,9 @@ aliases {
 		i2c5 = &hsi2c_5;
 		i2c6 = &hsi2c_6;
 		i2c7 = &hsi2c_7;
+		pinctrl0 = &pinctrl_fsys0;
+		pinctrl1 = &pinctrl_peric;
+		pinctrl2 = &pinctrl_pmu;
 	};
 
 	cpus {
@@ -648,5 +651,24 @@ hsi2c_7: i2c at 14270000 {
 			clock-names = "hsi2c";
 			status = "disabled";
 		};
+
+		pinctrl_pmu: pinctrl at 114f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x114f0000 0x0 0x1000>;
+		};
+
+		pinctrl_peric: pinctrl at 141f0000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x141f0000 0x0 0x1000>;
+			interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pinctrl_fsys0: pinctrl at 15020000 {
+			compatible = "tesla,fsd-pinctrl";
+			reg = <0x0 0x15020000 0x0 0x1000>;
+			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 };
+
+#include "fsd-pinctrl.dtsi"
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 06:16:44 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 19:46:44 +0530
Subject: [PATCH v5 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124143005epcas5p103598aa358ac35fe5e1ee762faf508b0@epcas5p1.samsung.com>
Message-ID: <20220124141644.71052-17-alim.akhtar@samsung.com>

This patch enables the Tesla FSD SoC in arm64 defconfig.

Cc: linux-fsd at tesla.com
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..415fb3aca4b3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -54,6 +54,7 @@ CONFIG_ARCH_SEATTLE=y
 CONFIG_ARCH_INTEL_SOCFPGA=y
 CONFIG_ARCH_SYNQUACER=y
 CONFIG_ARCH_TEGRA=y
+CONFIG_ARCH_TESLA_FSD=y
 CONFIG_ARCH_SPRD=y
 CONFIG_ARCH_THUNDER=y
 CONFIG_ARCH_THUNDER2=y
-- 
2.25.1



From dongas86 at gmail.com  Mon Jan 24 06:34:00 2022
From: dongas86 at gmail.com (Dong Aisheng)
Date: Mon, 24 Jan 2022 22:34:00 +0800
Subject: [PATCH v2 0/2] mm: fix cma allocation fail sometimes
In-Reply-To: <20220112131552.3329380-1-aisheng.dong@nxp.com>
References: <20220112131552.3329380-1-aisheng.dong@nxp.com>
Message-ID: <CAA+hA=T=kavt-zvrraXh+BJcSPVWtzyXhkycrmdtNCxzKsbaaQ@mail.gmail.com>

Gently Ping...

On Wed, Jan 12, 2022 at 9:17 PM Dong Aisheng <aisheng.dong at nxp.com> wrote:
>
> We observed an issue with NXP 5.15 LTS kernel that dma_alloc_coherent()
> may fail sometimes when there're multiple processes trying to allocate
> CMA memory.
>
> This issue can be very easily reproduced on MX6Q SDB board with latest
> linux-next kernel by writing a test module creating 16 or 32 threads
> allocating random size of CMA memory in parallel at the background.
> Or simply enabling CONFIG_CMA_DEBUG, you can see endless of CMA alloc
> retries during booting:
> [    1.452124] cma: cma_alloc(): memory range at (ptrval) is busy,retrying
> ....
> (thousands of reties)
> NOTE: MX6 has CONFIG_FORCE_MAX_ZONEORDER=14 which means MAX_ORDER is
> 13 (32M).
>
> The root cause of this issue is that since commit a4efc174b382
> ("mm/cma.c: remove redundant cma_mutex lock"), CMA supports concurrent
> memory allocation.
> It's possible that the pageblock process A try to alloc has already
> been isolated by the allocation of process B during memory migration.
>
> When there're multi process allocating CMA memory in parallel, it's
> likely that other the remain pageblocks may have also been isolated,
> then CMA alloc fail finally during the first round of scanning of the
> whole available CMA bitmap.
>
> This patchset introduces a retry mechanism to rescan CMA bitmap for -EBUSY
> error in case the target pageblock may has been temporarily isolated
> by others and released later.
> It also improves the CMA allocation performance by trying the next
> pageblock during reties rather than looping in the same pageblock
> which is in -EBUSY state.
>
> Theoretically, this issue can be easily reproduced on ARMv7 platforms
> with big MAX_ORDER/pageblock
> e.g. 1G RAM(320M reserved CMA) and 32M pageblock ARM platform:
> Page block order: 13
> Pages per block:  8192
>
> The following test is based on linux-next: next-20211213.
>
> Without the fix, it's easily fail.
> # insmod cma_alloc.ko pnum=16
> [  274.322369] CMA alloc test enter: thread number: 16
> [  274.329948] cpu: 0, pid: 692, index 4 pages 144
> [  274.330143] cpu: 1, pid: 694, index 2 pages 44
> [  274.330359] cpu: 2, pid: 695, index 7 pages 757
> [  274.330760] cpu: 2, pid: 696, index 4 pages 144
> [  274.330974] cpu: 2, pid: 697, index 6 pages 512
> [  274.331223] cpu: 2, pid: 698, index 6 pages 512
> [  274.331499] cpu: 2, pid: 699, index 2 pages 44
> [  274.332228] cpu: 2, pid: 700, index 0 pages 7
> [  274.337421] cpu: 0, pid: 701, index 1 pages 38
> [  274.337618] cpu: 2, pid: 702, index 0 pages 7
> [  274.344669] cpu: 1, pid: 703, index 0 pages 7
> [  274.344807] cpu: 3, pid: 704, index 6 pages 512
> [  274.348269] cpu: 2, pid: 705, index 5 pages 148
> [  274.349490] cma: cma_alloc: reserved: alloc failed, req-size: 38 pages, ret: -16
> [  274.366292] cpu: 1, pid: 706, index 4 pages 144
> [  274.366562] cpu: 0, pid: 707, index 3 pages 128
> [  274.367356] cma: cma_alloc: reserved: alloc failed, req-size: 128 pages, ret: -16
> [  274.367370] cpu: 0, pid: 707, index 3 pages 128 failed
> [  274.371148] cma: cma_alloc: reserved: alloc failed, req-size: 148 pages, ret: -16
> [  274.375348] cma: cma_alloc: reserved: alloc failed, req-size: 144 pages, ret: -16
> [  274.384256] cpu: 2, pid: 708, index 0 pages 7
> ....
>
> With the fix, 32 threads allocating in parallel can pass overnight
> stress test.
>
> root at imx6qpdlsolox:~# insmod cma_alloc.ko pnum=32
> [  112.976809] cma_alloc: loading out-of-tree module taints kernel.
> [  112.984128] CMA alloc test enter: thread number: 32
> [  112.989748] cpu: 2, pid: 707, index 6 pages 512
> [  112.994342] cpu: 1, pid: 708, index 6 pages 512
> [  112.995162] cpu: 0, pid: 709, index 3 pages 128
> [  112.995867] cpu: 2, pid: 710, index 0 pages 7
> [  112.995910] cpu: 3, pid: 711, index 2 pages 44
> [  112.996005] cpu: 3, pid: 712, index 7 pages 757
> [  112.996098] cpu: 3, pid: 713, index 7 pages 757
> ...
> [41877.368163] cpu: 1, pid: 737, index 2 pages 44
> [41877.369388] cpu: 1, pid: 736, index 3 pages 128
> [41878.486516] cpu: 0, pid: 737, index 2 pages 44
> [41878.486515] cpu: 2, pid: 739, index 4 pages 144
> [41878.486622] cpu: 1, pid: 736, index 3 pages 128
> [41878.486948] cpu: 2, pid: 735, index 7 pages 757
> [41878.487279] cpu: 2, pid: 738, index 4 pages 144
> [41879.526603] cpu: 1, pid: 739, index 3 pages 128
> [41879.606491] cpu: 2, pid: 737, index 3 pages 128
> [41879.606550] cpu: 0, pid: 736, index 0 pages 7
> [41879.612271] cpu: 2, pid: 738, index 4 pages 144
> ...
>
> v1:
> https://patchwork.kernel.org/project/linux-mm/cover/20211215080242.3034856-1-aisheng.dong at nxp.com/
>
> Dong Aisheng (2):
>   mm: cma: fix allocation may fail sometimes
>   mm: cma: try next MAX_ORDER_NR_PAGES during retry
>
>  mm/cma.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> --
> 2.25.1
>


From robh at kernel.org  Mon Jan 24 06:53:02 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 24 Jan 2022 08:53:02 -0600
Subject: [PATCH] arm64: dts: imx8qm: Drop CPU 'arm,armv8' compatible
In-Reply-To: <20211217173908.3201517-1-robh@kernel.org>
References: <20211217173908.3201517-1-robh@kernel.org>
Message-ID: <CAL_JsqLYXYNHRKM9hAhxZjheJZUxiXN3zCwsmwo1kxVvhKn9VA@mail.gmail.com>

On Fri, Dec 17, 2021 at 11:39 AM Rob Herring <robh at kernel.org> wrote:
>
> The CPU 'arm,armv8' compatible is only for s/w models, so remove it from
> i.MX8QM CPU nodes.
>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> Note that the PMU node is also wrong as it should have separate A72 and
> A53 nodes to get uarch specific events, but that needs some GIC changes.
> ---
>  arch/arm64/boot/dts/freescale/imx8qm.dtsi | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)

Ping

>
> diff --git a/arch/arm64/boot/dts/freescale/imx8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> index aebbe2b84aa1..b13f09ca0404 100644
> --- a/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8qm.dtsi
> @@ -54,7 +54,7 @@ core1 {
>
>                 A53_0: cpu at 0 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a53", "arm,armv8";
> +                       compatible = "arm,cortex-a53";
>                         reg = <0x0 0x0>;
>                         enable-method = "psci";
>                         next-level-cache = <&A53_L2>;
> @@ -62,7 +62,7 @@ A53_0: cpu at 0 {
>
>                 A53_1: cpu at 1 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a53", "arm,armv8";
> +                       compatible = "arm,cortex-a53";
>                         reg = <0x0 0x1>;
>                         enable-method = "psci";
>                         next-level-cache = <&A53_L2>;
> @@ -70,7 +70,7 @@ A53_1: cpu at 1 {
>
>                 A53_2: cpu at 2 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a53", "arm,armv8";
> +                       compatible = "arm,cortex-a53";
>                         reg = <0x0 0x2>;
>                         enable-method = "psci";
>                         next-level-cache = <&A53_L2>;
> @@ -78,7 +78,7 @@ A53_2: cpu at 2 {
>
>                 A53_3: cpu at 3 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a53", "arm,armv8";
> +                       compatible = "arm,cortex-a53";
>                         reg = <0x0 0x3>;
>                         enable-method = "psci";
>                         next-level-cache = <&A53_L2>;
> @@ -86,7 +86,7 @@ A53_3: cpu at 3 {
>
>                 A72_0: cpu at 100 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a72", "arm,armv8";
> +                       compatible = "arm,cortex-a72";
>                         reg = <0x0 0x100>;
>                         enable-method = "psci";
>                         next-level-cache = <&A72_L2>;
> @@ -94,7 +94,7 @@ A72_0: cpu at 100 {
>
>                 A72_1: cpu at 101 {
>                         device_type = "cpu";
> -                       compatible = "arm,cortex-a72", "arm,armv8";
> +                       compatible = "arm,cortex-a72";
>                         reg = <0x0 0x101>;
>                         enable-method = "psci";
>                         next-level-cache = <&A72_L2>;
> --
> 2.32.0
>


From broonie at kernel.org  Mon Jan 24 07:07:00 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:07:00 +0000
Subject: [PATCH v8 0/4] arm64: Enable BTI for the executable as well as the
 interpreter
Message-ID: <20220124150704.2559523-1-broonie@kernel.org>

Deployments of BTI on arm64 have run into issues interacting with
systemd's MemoryDenyWriteExecute feature.  Currently for dynamically
linked executables the kernel will only handle architecture specific
properties like BTI for the interpreter, the expectation is that the
interpreter will then handle any properties on the main executable.
For BTI this means remapping the executable segments PROT_EXEC |
PROT_BTI.

This interacts poorly with MemoryDenyWriteExecute since that is
implemented using a seccomp filter which prevents setting PROT_EXEC on
already mapped memory and lacks the context to be able to detect that
memory is already mapped with PROT_EXEC.  This series resolves this by
handling the BTI property for both the interpreter and the main
executable.

This does mean that we may get more code with BTI enabled if running on
a system without BTI support in the dynamic linker, this is expected to
be a safe configuration and testing seems to confirm that. It also
reduces the flexibility userspace has to disable BTI but it is expected
that for cases where there are problems which require BTI to be disabled
it is more likely that it will need to be disabled on a system level.

v8:
 - Rebase onto v5.17-rc1.
v7:
 - Rebase onto v5.16-rc1.
v6:
 - Rebase onto v5.15-rc1.
v5:
 - Rebase onto v5.14-rc2.
 - Tweak changelog on patch 1.
 - Use the helper for interpreter/executable flag in elf.h as well.
v4:
 - Rebase onto v5.14-rc1.
v3:
 - Fix passing of properties for parsing by the main executable.
 - Drop has_interp from arch_parse_elf_property().
 - Coding style tweaks.
v2:
 - Add a patch dropping has_interp from arch_adjust_elf_prot()
 - Fix bisection issue with static executables on arm64 in the first
   patch.

Mark Brown (4):
  elf: Allow architectures to parse properties on the main executable
  arm64: Enable BTI for main executable as well as the interpreter
  elf: Remove has_interp property from arch_adjust_elf_prot()
  elf: Remove has_interp property from arch_parse_elf_property()

 arch/arm64/include/asm/elf.h | 14 ++++++++++++--
 arch/arm64/kernel/process.c  | 16 +++-------------
 fs/binfmt_elf.c              | 29 ++++++++++++++++++++---------
 include/linux/elf.h          |  8 +++++---
 4 files changed, 40 insertions(+), 27 deletions(-)


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:07:01 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:07:01 +0000
Subject: [PATCH v8 1/4] elf: Allow architectures to parse properties on the
 main executable
In-Reply-To: <20220124150704.2559523-1-broonie@kernel.org>
References: <20220124150704.2559523-1-broonie@kernel.org>
Message-ID: <20220124150704.2559523-2-broonie@kernel.org>

Currently the ELF code only attempts to parse properties on the image
that will start execution, either the interpreter or for statically linked
executables the main executable. The expectation is that any property
handling for the main executable will be done by the interpreter. This is
a bit inconsistent since we do map the executable and is causing problems
for the arm64 BTI support when used in conjunction with systemd's use of
seccomp to implement MemoryDenyWriteExecute which stops the dynamic linker
adjusting the permissions of executable segments.

Allow architectures to handle properties for both the dynamic linker and
main executable, adjusting arch_parse_elf_properties() to have a new
flag is_interp flag as with arch_elf_adjust_prot() and calling it for
both the main executable and any intepreter.

The user of this code, arm64, is adapted to ensure that there is no
functional change.

Signed-off-by: Mark Brown <broonie at kernel.org>
Tested-by: Jeremy Linton <jeremy.linton at arm.com>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
---
 arch/arm64/include/asm/elf.h |  3 ++-
 fs/binfmt_elf.c              | 27 +++++++++++++++++++--------
 include/linux/elf.h          |  4 +++-
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 97932fbf973d..5cc002376abe 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -259,6 +259,7 @@ struct arch_elf_state {
 
 static inline int arch_parse_elf_property(u32 type, const void *data,
 					  size_t datasz, bool compat,
+					  bool has_interp, bool is_interp,
 					  struct arch_elf_state *arch)
 {
 	/* No known properties for AArch32 yet */
@@ -271,7 +272,7 @@ static inline int arch_parse_elf_property(u32 type, const void *data,
 		if (datasz != sizeof(*p))
 			return -ENOEXEC;
 
-		if (system_supports_bti() &&
+		if (system_supports_bti() && has_interp == is_interp &&
 		    (*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
 			arch->flags |= ARM64_ELF_BTI;
 	}
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 605017eb9349..eabd7e0f6592 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -716,8 +716,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
  */
 
 static int parse_elf_property(const char *data, size_t *off, size_t datasz,
-			      struct arch_elf_state *arch,
-			      bool have_prev_type, u32 *prev_type)
+			      struct arch_elf_state *arch, bool has_interp,
+			      bool is_interp, bool have_prev_type,
+			      u32 *prev_type)
 {
 	size_t o, step;
 	const struct gnu_property *pr;
@@ -751,7 +752,8 @@ static int parse_elf_property(const char *data, size_t *off, size_t datasz,
 	*prev_type = pr->pr_type;
 
 	ret = arch_parse_elf_property(pr->pr_type, data + o,
-				      pr->pr_datasz, ELF_COMPAT, arch);
+				      pr->pr_datasz, ELF_COMPAT,
+				      has_interp, is_interp, arch);
 	if (ret)
 		return ret;
 
@@ -764,6 +766,7 @@ static int parse_elf_property(const char *data, size_t *off, size_t datasz,
 #define NOTE_NAME_SZ (sizeof(GNU_PROPERTY_TYPE_0_NAME))
 
 static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr,
+				bool has_interp, bool is_interp,
 				struct arch_elf_state *arch)
 {
 	union {
@@ -813,7 +816,8 @@ static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr,
 	have_prev_type = false;
 	do {
 		ret = parse_elf_property(note.data, &off, datasz, arch,
-					 have_prev_type, &prev_type);
+					 has_interp, is_interp, have_prev_type,
+					 &prev_type);
 		have_prev_type = true;
 	} while (!ret);
 
@@ -828,6 +832,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
 	unsigned long error;
 	struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL;
 	struct elf_phdr *elf_property_phdata = NULL;
+	struct elf_phdr *interp_elf_property_phdata = NULL;
 	unsigned long elf_bss, elf_brk;
 	int bss_prot = 0;
 	int retval, i;
@@ -963,12 +968,11 @@ static int load_elf_binary(struct linux_binprm *bprm)
 			goto out_free_dentry;
 
 		/* Pass PT_LOPROC..PT_HIPROC headers to arch code */
-		elf_property_phdata = NULL;
 		elf_ppnt = interp_elf_phdata;
 		for (i = 0; i < interp_elf_ex->e_phnum; i++, elf_ppnt++)
 			switch (elf_ppnt->p_type) {
 			case PT_GNU_PROPERTY:
-				elf_property_phdata = elf_ppnt;
+				interp_elf_property_phdata = elf_ppnt;
 				break;
 
 			case PT_LOPROC ... PT_HIPROC:
@@ -979,10 +983,17 @@ static int load_elf_binary(struct linux_binprm *bprm)
 					goto out_free_dentry;
 				break;
 			}
+
+		retval = parse_elf_properties(interpreter,
+					      interp_elf_property_phdata,
+					      true, true, &arch_state);
+		if (retval)
+			goto out_free_dentry;
+
 	}
 
-	retval = parse_elf_properties(interpreter ?: bprm->file,
-				      elf_property_phdata, &arch_state);
+	retval = parse_elf_properties(bprm->file, elf_property_phdata,
+				      interpreter, false, &arch_state);
 	if (retval)
 		goto out_free_dentry;
 
diff --git a/include/linux/elf.h b/include/linux/elf.h
index c9a46c4e183b..1c45ecf29147 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -88,13 +88,15 @@ struct arch_elf_state;
 #ifndef CONFIG_ARCH_USE_GNU_PROPERTY
 static inline int arch_parse_elf_property(u32 type, const void *data,
 					  size_t datasz, bool compat,
+					  bool has_interp, bool is_interp,
 					  struct arch_elf_state *arch)
 {
 	return 0;
 }
 #else
 extern int arch_parse_elf_property(u32 type, const void *data, size_t datasz,
-				   bool compat, struct arch_elf_state *arch);
+				   bool compat, bool has_interp, bool is_interp,
+				   struct arch_elf_state *arch);
 #endif
 
 #ifdef CONFIG_ARCH_HAVE_ELF_PROT
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:07:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:07:02 +0000
Subject: [PATCH v8 2/4] arm64: Enable BTI for main executable as well as the
 interpreter
In-Reply-To: <20220124150704.2559523-1-broonie@kernel.org>
References: <20220124150704.2559523-1-broonie@kernel.org>
Message-ID: <20220124150704.2559523-3-broonie@kernel.org>

Currently for dynamically linked ELF executables we only enable BTI for
the interpreter, expecting the interpreter to do this for the main
executable. This is a bit inconsistent since we do map main executable and
is causing issues with systemd's MemoryDenyWriteExecute feature which is
implemented using a seccomp filter which prevents setting PROT_EXEC on
already mapped memory and lacks the context to be able to detect that
memory is already mapped with PROT_EXEC.

Resolve this by checking the BTI property for the main executable and
enabling BTI if it is present when doing the initial mapping. This does
mean that we may get more code with BTI enabled if running on a system
without BTI support in the dynamic linker, this is expected to be a safe
configuration and testing seems to confirm that. It also reduces the
flexibility userspace has to disable BTI but it is expected that for cases
where there are problems which require BTI to be disabled it is more likely
that it will need to be disabled on a system level.

Signed-off-by: Mark Brown <broonie at kernel.org>
Reviewed-by: Dave Martin <Dave.Martin at arm.com>
Tested-by: Jeremy Linton <jeremy.linton at arm.com>
---
 arch/arm64/include/asm/elf.h | 15 ++++++++++++---
 arch/arm64/kernel/process.c  | 14 ++------------
 2 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index 5cc002376abe..c4aa60db76a4 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -251,12 +251,21 @@ struct arch_elf_state {
 	int flags;
 };
 
-#define ARM64_ELF_BTI		(1 << 0)
+#define ARM64_ELF_INTERP_BTI		(1 << 0)
+#define ARM64_ELF_EXEC_BTI		(1 << 1)
 
 #define INIT_ARCH_ELF_STATE {			\
 	.flags = 0,				\
 }
 
+static inline int arm64_elf_bti_flag(bool is_interp)
+{
+	if (is_interp)
+		return ARM64_ELF_INTERP_BTI;
+	else
+		return ARM64_ELF_EXEC_BTI;
+}
+
 static inline int arch_parse_elf_property(u32 type, const void *data,
 					  size_t datasz, bool compat,
 					  bool has_interp, bool is_interp,
@@ -272,9 +281,9 @@ static inline int arch_parse_elf_property(u32 type, const void *data,
 		if (datasz != sizeof(*p))
 			return -ENOEXEC;
 
-		if (system_supports_bti() && has_interp == is_interp &&
+		if (system_supports_bti() &&
 		    (*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
-			arch->flags |= ARM64_ELF_BTI;
+			arch->flags |= arm64_elf_bti_flag(is_interp);
 	}
 
 	return 0;
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..8157910a4181 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -704,18 +704,8 @@ core_initcall(tagged_addr_init);
 int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state,
 			 bool has_interp, bool is_interp)
 {
-	/*
-	 * For dynamically linked executables the interpreter is
-	 * responsible for setting PROT_BTI on everything except
-	 * itself.
-	 */
-	if (is_interp != has_interp)
-		return prot;
-
-	if (!(state->flags & ARM64_ELF_BTI))
-		return prot;
-
-	if (prot & PROT_EXEC)
+	if ((prot & PROT_EXEC) &&
+	    (state->flags & arm64_elf_bti_flag(is_interp)))
 		prot |= PROT_BTI;
 
 	return prot;
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:07:04 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:07:04 +0000
Subject: [PATCH v8 4/4] elf: Remove has_interp property from
 arch_parse_elf_property()
In-Reply-To: <20220124150704.2559523-1-broonie@kernel.org>
References: <20220124150704.2559523-1-broonie@kernel.org>
Message-ID: <20220124150704.2559523-5-broonie@kernel.org>

Since all current users of arch_parse_elf_property() are able to treat the
interpreter and main executable orthogonaly the has_interp argument is now
redundant so remove it.

Signed-off-by: Mark Brown <broonie at kernel.org>
Tested-by: Jeremy Linton <jeremy.linton at arm.com>
Reviewed-By: Dave Martin <Dave.Martin at arm.com>
---
 arch/arm64/include/asm/elf.h | 2 +-
 fs/binfmt_elf.c              | 2 +-
 include/linux/elf.h          | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
index c4aa60db76a4..8009e8f07f1e 100644
--- a/arch/arm64/include/asm/elf.h
+++ b/arch/arm64/include/asm/elf.h
@@ -268,7 +268,7 @@ static inline int arm64_elf_bti_flag(bool is_interp)
 
 static inline int arch_parse_elf_property(u32 type, const void *data,
 					  size_t datasz, bool compat,
-					  bool has_interp, bool is_interp,
+					  bool is_interp,
 					  struct arch_elf_state *arch)
 {
 	/* No known properties for AArch32 yet */
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c1620358ab77..caedfdcead61 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -753,7 +753,7 @@ static int parse_elf_property(const char *data, size_t *off, size_t datasz,
 
 	ret = arch_parse_elf_property(pr->pr_type, data + o,
 				      pr->pr_datasz, ELF_COMPAT,
-				      has_interp, is_interp, arch);
+				      is_interp, arch);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/elf.h b/include/linux/elf.h
index d8392531899d..cdb080d4b34a 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -88,14 +88,14 @@ struct arch_elf_state;
 #ifndef CONFIG_ARCH_USE_GNU_PROPERTY
 static inline int arch_parse_elf_property(u32 type, const void *data,
 					  size_t datasz, bool compat,
-					  bool has_interp, bool is_interp,
+					  bool is_interp,
 					  struct arch_elf_state *arch)
 {
 	return 0;
 }
 #else
 extern int arch_parse_elf_property(u32 type, const void *data, size_t datasz,
-				   bool compat, bool has_interp, bool is_interp,
+				   bool compat, bool is_interp,
 				   struct arch_elf_state *arch);
 #endif
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:07:03 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:07:03 +0000
Subject: [PATCH v8 3/4] elf: Remove has_interp property from
 arch_adjust_elf_prot()
In-Reply-To: <20220124150704.2559523-1-broonie@kernel.org>
References: <20220124150704.2559523-1-broonie@kernel.org>
Message-ID: <20220124150704.2559523-4-broonie@kernel.org>

Since we have added an is_interp flag to arch_parse_elf_property() we can
drop the has_interp flag from arch_elf_adjust_prot(), the only user was
the arm64 code which no longer needs it and any future users will be able
to use arch_parse_elf_properties() to determine if an interpreter is in
use.

Signed-off-by: Mark Brown <broonie at kernel.org>
Tested-by: Jeremy Linton <jeremy.linton at arm.com>
Reviewed-By: Dave Martin <Dave.Martin at arm.com>
---
 arch/arm64/kernel/process.c | 2 +-
 fs/binfmt_elf.c             | 2 +-
 include/linux/elf.h         | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 8157910a4181..8017d963be3f 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -702,7 +702,7 @@ core_initcall(tagged_addr_init);
 
 #ifdef CONFIG_BINFMT_ELF
 int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state,
-			 bool has_interp, bool is_interp)
+			 bool is_interp)
 {
 	if ((prot & PROT_EXEC) &&
 	    (state->flags & arm64_elf_bti_flag(is_interp)))
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index eabd7e0f6592..c1620358ab77 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -580,7 +580,7 @@ static inline int make_prot(u32 p_flags, struct arch_elf_state *arch_state,
 	if (p_flags & PF_X)
 		prot |= PROT_EXEC;
 
-	return arch_elf_adjust_prot(prot, arch_state, has_interp, is_interp);
+	return arch_elf_adjust_prot(prot, arch_state, is_interp);
 }
 
 /* This is much more generalized than the library routine read function,
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 1c45ecf29147..d8392531899d 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -101,11 +101,11 @@ extern int arch_parse_elf_property(u32 type, const void *data, size_t datasz,
 
 #ifdef CONFIG_ARCH_HAVE_ELF_PROT
 int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state,
-			 bool has_interp, bool is_interp);
+			 bool is_interp);
 #else
 static inline int arch_elf_adjust_prot(int prot,
 				       const struct arch_elf_state *state,
-				       bool has_interp, bool is_interp)
+				       bool is_interp)
 {
 	return prot;
 }
-- 
2.30.2



From catalin.marinas at arm.com  Mon Jan 24 07:10:08 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 24 Jan 2022 15:10:08 +0000
Subject: [PATCH V2 0/2] coresight: trbe: Update existing errata for
 Cortex-X2
In-Reply-To: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
References: <1642994138-25887-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <164303699846.16509.8389008992406508241.b4-ty@arm.com>

On Mon, 24 Jan 2022 08:45:36 +0530, Anshuman Khandual wrote:
> Errata ARM64_ERRATUM_[2119858|2224489] also affect some Cortex-X2 ranges as
> well. This series updates the errata definition and detection as required.
> This series applies on v5.17-rc1.
> 
> Relevant identification document can be found here.
> 
> https://developer.arm.com/documentation/101803/0200/AArch64-system-registers/
> AArch64-identification-register-summary/MIDR-EL1--Main-ID-Register
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/2] arm64: Add Cortex-X2 CPU part definition
      https://git.kernel.org/arm64/c/72bb9dcb6c33
[2/2] arm64: errata: Update ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges
      https://git.kernel.org/arm64/c/eb30d838a44c

-- 
Catalin



From catalin.marinas at arm.com  Mon Jan 24 07:10:29 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 24 Jan 2022 15:10:29 +0000
Subject: [PATCH] arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
In-Reply-To: <164301227374.1433152.12808232644267107415.stgit@devnote2>
References: <164301227374.1433152.12808232644267107415.stgit@devnote2>
Message-ID: <164303699846.16509.12781762905211026351.b4-ty@arm.com>

On Mon, 24 Jan 2022 17:17:54 +0900, Masami Hiramatsu wrote:
> Mark the start_backtrace() as notrace and NOKPROBE_SYMBOL
> because this function is called from ftrace and lockdep to
> get the caller address via return_address(). The lockdep
> is used in kprobes, it should also be NOKPROBE_SYMBOL.

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL
      https://git.kernel.org/arm64/c/1e0924bd0991

-- 
Catalin



From catalin.marinas at arm.com  Mon Jan 24 07:10:50 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Mon, 24 Jan 2022 15:10:50 +0000
Subject: [PATCH] arm64: vdso: Fix "no previous prototype" warning
In-Reply-To: <20220121121234.47273-1-vincenzo.frascino@arm.com>
References: <20220109113504.1921017-1-mkl@pengutronix.de>
 <20220121121234.47273-1-vincenzo.frascino@arm.com>
Message-ID: <164303699846.16509.2701629147557731709.b4-ty@arm.com>

On Fri, 21 Jan 2022 12:12:34 +0000, Vincenzo Frascino wrote:
> If compiling the arm64 kernel with W=1 the following warning is produced:
> 
> | arch/arm64/kernel/vdso/vgettimeofday.c:9:5: error: no previous prototype for ?__kernel_clock_gettime? [-Werror=missing-prototypes]
> |     9 | int __kernel_clock_gettime(clockid_t clock,
> |       |     ^~~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:15:5: error: no previous prototype for ?__kernel_gettimeofday? [-Werror=missing-prototypes]
> |    15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> | arch/arm64/kernel/vdso/vgettimeofday.c:21:5: error: no previous prototype for ?__kernel_clock_getres? [-Werror=missing-prototypes]
> |    21 | int __kernel_clock_getres(clockid_t clock_id,
> |       |     ^~~~~~~~~~~~~~~~~~~~~
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: vdso: Fix "no previous prototype" warning
      https://git.kernel.org/arm64/c/58cd4a088e89

-- 
Catalin



From quic_kathirav at quicinc.com  Mon Jan 24 07:11:26 2022
From: quic_kathirav at quicinc.com (Kathiravan Thirumoorthy)
Date: Mon, 24 Jan 2022 20:41:26 +0530
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <871r12g0j2.fsf@tarshish>
References: <20220119002438.106079-1-sean.anderson@seco.com>
 <87ee53fv01.fsf@tarshish> <1965fc315525b8ab26cf9f71f939c24d@codeaurora.org>
 <871r12g0j2.fsf@tarshish>
Message-ID: <e1309c23-530b-c698-b7ba-4f1a5226fe8c@quicinc.com>

Hi Baruch,

On 1/20/2022 3:59 PM, Baruch Siach wrote:
> Hi Kathiravan,
>
> On Thu, Jan 20 2022, Kathiravan T wrote:
>> On 2022-01-19 23:44, Baruch Siach wrote:
>>> Hi Sean,
>>> On Tue, Jan 18 2022, Sean Anderson wrote:
>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly program
>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
>>>> we no longer need a special property duplicating this configuration,
>>>> snps,ref-clock-period-ns is deprecated.
>>>> Please test this! Patches 3/4 in this series have the effect of
>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already configure
>>>> the "ref" clock. I have build tested, but not much else.
>>> Tested here on IPQ6010 based system. USB still works. But the with
>>> "ref"
>>> clock at 24MHz, period is calculated as 0x29. Previous
>>> snps,ref-clock-period-ns value used to be 0x32.
>>> Is that expected?
>> Yes, it is 0x29 for IPQ60xx based SoCs. In downstream it was wrongly mentioned
>> as 0x32, which was corrected recently.
> Thanks for the update. This needs fixing in upstream kernel. I'll send a
> patch.
>
> For some reason USB appears to work here with both values. Is it because
> I only use USB2 signals? If this is the case them I can not actually
> test this series on my system.

I could recollect we did see some issue on USB2.0 port as well, but it 
wasn't fatal one. Anyways it is better to test it.

Thanks,

Kathiravan T.

>
> Thanks,
> baruch
>
>>>> [1]
>>>> https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/
>>>> Changes in v2:
>>>> - Document clock members
>>>> - Also program GFLADJ.240MHZDECR
>>>> - Don't program GFLADJ if the version is < 2.50a
>>>> - Add snps,ref-clock-frequency-hz property for ACPI
>>>> Sean Anderson (7):
>>>>    dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>>>>    usb: dwc3: Get clocks individually
>>>>    usb: dwc3: Calculate REFCLKPER based on reference clock
>>>>    usb: dwc3: Program GFLADJ
>>>>    usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
>>>>    arm64: dts: zynqmp: Move USB clocks to dwc3 node
>>>>    arm64: dts: ipq6018: Use reference clock to set dwc3 period
>>>>   .../devicetree/bindings/usb/snps,dwc3.yaml    |   7 +-
>>>>   arch/arm64/boot/dts/qcom/ipq6018.dtsi         |   3 +-
>>>>   .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |   4 +-
>>>>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |   4 +-
>>>>   drivers/usb/dwc3/core.c                       | 112 +++++++++++++++---
>>>>   drivers/usb/dwc3/core.h                       |  17 ++-
>>>>   6 files changed, 120 insertions(+), 27 deletions(-)
>


From jstephan at baylibre.com  Mon Jan 24 07:22:50 2022
From: jstephan at baylibre.com (Julien STEPHAN)
Date: Mon, 24 Jan 2022 16:22:50 +0100
Subject: [PATCH] drm/mediatek: allow commands to be sent during video mode
Message-ID: <20220124152250.441809-1-jstephan@baylibre.com>

When the DSI is in video mode, all commands are rejected.

Detect current DSI mode in mtk_dsi_host_transfer() and switch modes
temporarily to allow commands to be sent.

Signed-off-by: Julien STEPHAN <jstephan at baylibre.com>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 34 ++++++++++++++++++++++--------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..7d66fdc7f81d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -891,24 +891,34 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 	u8 read_data[16];
 	void *src_addr;
 	u8 irq_flag = CMD_DONE_INT_FLAG;
-
-	if (readl(dsi->regs + DSI_MODE_CTRL) & MODE) {
-		DRM_ERROR("dsi engine is not command mode\n");
-		return -EINVAL;
+	u32 dsi_mode;
+
+	dsi_mode = readl(dsi->regs + DSI_MODE_CTRL);
+	if (dsi_mode & MODE) {
+		mtk_dsi_stop(dsi);
+		if (mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
+			recv_cnt = -EINVAL;
+			goto restore_dsi_mode;
+		}
 	}
 
 	if (MTK_DSI_HOST_IS_READ(msg->type))
 		irq_flag |= LPRX_RD_RDY_INT_FLAG;
 
-	if (mtk_dsi_host_send_cmd(dsi, msg, irq_flag) < 0)
-		return -ETIME;
+	if (mtk_dsi_host_send_cmd(dsi, msg, irq_flag) < 0) {
+		recv_cnt = -ETIME;
+		goto restore_dsi_mode;
+	}
 
-	if (!MTK_DSI_HOST_IS_READ(msg->type))
-		return 0;
+	if (!MTK_DSI_HOST_IS_READ(msg->type)) {
+		recv_cnt = 0;
+		goto restore_dsi_mode;
+	}
 
 	if (!msg->rx_buf) {
 		DRM_ERROR("dsi receive buffer size may be NULL\n");
-		return -EINVAL;
+		recv_cnt = -EINVAL;
+		goto restore_dsi_mode;
 	}
 
 	for (i = 0; i < 16; i++)
@@ -933,6 +943,12 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 	DRM_INFO("dsi get %d byte data from the panel address(0x%x)\n",
 		 recv_cnt, *((u8 *)(msg->tx_buf)));
 
+restore_dsi_mode:
+	if (dsi_mode & MODE) {
+		mtk_dsi_set_mode(dsi);
+		mtk_dsi_start(dsi);
+	}
+
 	return recv_cnt;
 }
 
-- 
2.34.1



From robh at kernel.org  Mon Jan 24 07:24:18 2022
From: robh at kernel.org (Rob Herring)
Date: Mon, 24 Jan 2022 09:24:18 -0600
Subject: [PATCH] Revert "PCI: j721e: Drop redundant struct device *"
In-Reply-To: <20220124122132.435743-1-christian.gmeiner@gmail.com>
References: <20220124122132.435743-1-christian.gmeiner@gmail.com>
Message-ID: <CAL_JsqLwFvLJg+LCgANU6Mdx_=RkkLWPk+8nxsTNxb_sLi+nwQ@mail.gmail.com>

On Mon, Jan 24, 2022 at 6:21 AM Christian Gmeiner
<christian.gmeiner at gmail.com> wrote:
>
> This reverts commit 19e863828acf6d8ac8475ba1fd93c0fe17fdc4ef.
>
> Fixes the following oops:

Perhaps explain why the 2nd struct device was not redundant. Is this
not just a case of the dev pointer not getting set early enough?

>  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
>  Internal error: Oops: 96000004 [#1] PREEMPT SMP
>  Modules linked in:
>  CPU: 1 PID: 7 Comm: kworker/u4:0 Not tainted 5.17.0-rc1-00086-ge38b27816fea-dirty #71
>  Hardware name: CPE0108 (DT)
>  Workqueue: events_unbound deferred_probe_work_func
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : j721e_pcie_probe+0x184/0x600
>  lr : j721e_pcie_probe+0x170/0x600
>  sp : ffff80000957bae0
>  x29: ffff80000957bae0 x28: ffff800009357000 x27: ffff00000000c078
>  x26: ffff00003fe047a8 x25: 0000000000000000 x24: ffff0000000f5280
>  x23: ffff800008c98f78 x22: ffff800008f90ff0 x21: ffff000000231410
>  x20: ffff000002ef2780 x19: 0000000000000021 x18: 0000000000000001
>  x17: 0000000000000000 x16: 0000000000058c00 x15: ffffffffffffffff
>  x14: ffffffffffffffff x13: 0000000000000010 x12: 0101010101010101
>  x11: 0000000000000040 x10: ffff8000093e06c8 x9 : ffff8000093e06c0
>  x8 : ffff000000400270 x7 : 0000000000000000 x6 : ffff000000231590
>  x5 : ffff80000957b9e0 x4 : 0000000000000000 x3 : ffff0000002314f4
>  x2 : 0000000000000000 x1 : ffff0000000f5280 x0 : 0000000000000000
>  Call trace:
>   j721e_pcie_probe+0x184/0x600
>   platform_probe+0x68/0xe0
>   really_probe+0x144/0x320
>   __driver_probe_device+0xc4/0xe0
>   driver_probe_device+0x7c/0x110
>   __device_attach_driver+0x90/0xe0
>   bus_for_each_drv+0x78/0xd0
>   __device_attach+0xf0/0x150
>   device_initial_probe+0x14/0x20
>   bus_probe_device+0x9c/0xb0
>   deferred_probe_work_func+0x88/0xc0
>   process_one_work+0x1bc/0x340
>   worker_thread+0x1f8/0x420
>   kthread+0x110/0x120
>   ret_from_fork+0x10/0x20
>  Code: f9400280 a90573fb d0005396 913fc2d6 (f9400800)
>
> Fixes: 19e863828acf ("PCI: j721e: Drop redundant struct device *")
> Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 489586a4cdc7..cd43d1898482 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -51,10 +51,11 @@ enum link_status {
>  #define MAX_LANES                      2
>
>  struct j721e_pcie {
> -       struct cdns_pcie        *cdns_pcie;
> +       struct device           *dev;
>         struct clk              *refclk;
>         u32                     mode;
>         u32                     num_lanes;
> +       struct cdns_pcie        *cdns_pcie;
>         void __iomem            *user_cfg_base;
>         void __iomem            *intd_cfg_base;
>         u32                     linkdown_irq_regfield;
> @@ -98,7 +99,7 @@ static inline void j721e_pcie_intd_writel(struct j721e_pcie *pcie, u32 offset,
>  static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
>  {
>         struct j721e_pcie *pcie = priv;
> -       struct device *dev = pcie->cdns_pcie->dev;
> +       struct device *dev = pcie->dev;
>         u32 reg;
>
>         reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
> @@ -164,7 +165,7 @@ static const struct cdns_pcie_ops j721e_pcie_ops = {
>  static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
>                                unsigned int offset)
>  {
> -       struct device *dev = pcie->cdns_pcie->dev;
> +       struct device *dev = pcie->dev;
>         u32 mask = J721E_MODE_RC;
>         u32 mode = pcie->mode;
>         u32 val = 0;
> @@ -183,7 +184,7 @@ static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
>  static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
>                                      struct regmap *syscon, unsigned int offset)
>  {
> -       struct device *dev = pcie->cdns_pcie->dev;
> +       struct device *dev = pcie->dev;
>         struct device_node *np = dev->of_node;
>         int link_speed;
>         u32 val = 0;
> @@ -204,7 +205,7 @@ static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
>  static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
>                                      struct regmap *syscon, unsigned int offset)
>  {
> -       struct device *dev = pcie->cdns_pcie->dev;
> +       struct device *dev = pcie->dev;
>         u32 lanes = pcie->num_lanes;
>         u32 val = 0;
>         int ret;
> @@ -219,7 +220,7 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
>
>  static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
>  {
> -       struct device *dev = pcie->cdns_pcie->dev;
> +       struct device *dev = pcie->dev;
>         struct device_node *node = dev->of_node;
>         struct of_phandle_args args;
>         unsigned int offset = 0;
> @@ -376,6 +377,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>         if (!pcie)
>                 return -ENOMEM;
>
> +       pcie->dev = dev;
>         pcie->mode = mode;
>         pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
>
> --
> 2.34.1
>


From p.yadav at ti.com  Mon Jan 24 07:36:44 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Mon, 24 Jan 2022 21:06:44 +0530
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <d4ba6413-57ce-14c1-ed48-d00db2f74bd3@kaod.org>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com>
 <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com>
 <20220103171721.46c8e697@xps13> <YdSP6tKyQ2ZRUC+2@heinlein>
 <20220105063244.lno3xur64uepa7i5@ti.com>
 <d4ba6413-57ce-14c1-ed48-d00db2f74bd3@kaod.org>
Message-ID: <20220124153644.m3iwlvq5ld5cpbyz@ti.com>

On 23/01/22 11:44PM, C?dric Le Goater wrote:
> > > I had an offline discussion with someone who knew more history on this driver.
> > > My understanding is that the linux-aspeed team is aware of this being deprecated
> > > but that there was some missing support for interface training that nobody has
> > > gotten around to write?  If that is the case this really isn't even a "simple"
> > > port to a new API at this point.
> > 
> > Unless the controller needs some unique feature (I don't think it does
> > on a quick glance), the conversion should not be too difficult. For any
> > experienced developer, even if they are unfamiliar with the SPI MEM API,
> > I don't think it should take more than 2-3 days to do the conversion.
> > The code to program the registers would stay the same, all that needs to
> > change is the API through which it is accessed.
> 
> Writing a spimem driver is not a problem, I think people have done
> that in house. Aspeed has one for AST2600. We have one for u-boot
> I wrote sometime ago. I even have one for Linux but training comes
> with ugly hacks to fit in the current stack.
> 
> All Aspeed SoCs need training and that has been the problem for the
> last 4 years or so because we can not do training without knowing
> a minimum about the flash being trained :/ The previous framework
> offered a way to do a first scan and tune the delay settings
> afterwards. It worked pretty well on AST2400, AST2500 and AST2600
> even if more complex.
> 
> One alternative was to include the setting in the DT but the flash
> modules are not always soldered on the boards, at least on OpenPOWER
> systems which have sockets for them. The board are large, the wires
> long, the need is real, some chips freak out if not tuned correctly.
> 
> spimem needs an extension I think. Sorry I have not been able to
> push that forward. Lack of time and other tasks to address on the
> host side of the machine. This is really a software problem, we
> have the HW procedures ready. If a spimem expert could get involved
> to make a few proposals, I would be happy to help and do some testing.
> QEMU models are good enough for the software part. We can do the
> training validation on real HW when ready.

What information about the flash do you need for this training? I 
proposed a patch series [0] some time ago trying to implement training 
for TI SoCs. It did not get merged but I do intend to respin it and get 
it through. Would this API work for your tuning as well?

Also, I am curious how your training works. What data do you read for 
training delays? Where is it stored? In our case we need to flash a 
known pattern at some location (which is passed in via DT). Do you need 
to run it for every read transaction or just once after the flash is 
initialized?

[0] https://patchwork.ozlabs.org/project/linux-mtd/list/?series=233504&state=%2A&archive=both

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From olivier.moysan at foss.st.com  Mon Jan 24 07:35:25 2022
From: olivier.moysan at foss.st.com (Olivier Moysan)
Date: Mon, 24 Jan 2022 16:35:25 +0100
Subject: [PATCH 1/1] ARM: dts: stm32: fix AV96 board SAI2 pin muxing on
 stm32mp15
Message-ID: <20220124153525.17314-1-olivier.moysan@foss.st.com>

Replace sai2a-2 node name by sai2a-sleep-2, to avoid name
duplication.

Fixes: 1a9a9d226f0f ("ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15")

Signed-off-by: Olivier Moysan <olivier.moysan at foss.st.com>
---
 arch/arm/boot/dts/stm32mp15-pinctrl.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
index 3b65130affec..6161f5906ec1 100644
--- a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
+++ b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
@@ -1190,7 +1190,7 @@
 		};
 	};
 
-	sai2a_sleep_pins_c: sai2a-2 {
+	sai2a_sleep_pins_c: sai2a-sleep-2 {
 		pins {
 			pinmux = <STM32_PINMUX('D', 13, ANALOG)>, /* SAI2_SCK_A */
 				 <STM32_PINMUX('D', 11, ANALOG)>, /* SAI2_SD_A */
-- 
2.17.1



From broonie at kernel.org  Mon Jan 24 07:57:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:57:19 +0000
Subject: [PATCH v1 1/2] KVM: arm64: Add comments for context flush and sync
 callbacks
In-Reply-To: <20220124155720.3943374-1-broonie@kernel.org>
References: <20220124155720.3943374-1-broonie@kernel.org>
Message-ID: <20220124155720.3943374-2-broonie@kernel.org>

Add a little bit of information on where _ctxflush_fp() and _ctxsync_fp()
are called to help people unfamiliar with the code get up to speed.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/fpsimd.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 2f48fd362a8c..397fdac75cb1 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -84,6 +84,11 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 		vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
 }
 
+/*
+ * Called just before entering the guest once we are no longer
+ * preemptable. Syncs the host's TIF_FOREIGN_FPSTATE with the KVM
+ * mirror of the flag used by the hypervisor.
+ */
 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
 {
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
@@ -93,10 +98,11 @@ void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
 }
 
 /*
- * If the guest FPSIMD state was loaded, update the host's context
- * tracking data mark the CPU FPSIMD regs as dirty and belonging to vcpu
- * so that they will be written back if the kernel clobbers them due to
- * kernel-mode NEON before re-entry into the guest.
+ * Called just after exiting the guest. If the guest FPSIMD state
+ * was loaded, update the host's context tracking data mark the CPU
+ * FPSIMD regs as dirty and belonging to vcpu so that they will be
+ * written back if the kernel clobbers them due to kernel-mode NEON
+ * before re-entry into the guest.
  */
 void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 {
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:57:18 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:57:18 +0000
Subject: [PATCH v1 0/2] KVM: arm64: Additional documentation of the FP code
Message-ID: <20220124155720.3943374-1-broonie@kernel.org>

These couple of patches add a few more comments to the floating point
code which will hopefully help the next person who comes along and tries
to figure out what is going on.

Mark Brown (2):
  KVM: arm64: Add comments for context flush and sync callbacks
  KVM: arm64: Add some more comments in kvm_hyp_handle_fpsimd()

 arch/arm64/kvm/fpsimd.c                 | 14 ++++++++++----
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 ++++
 2 files changed, 14 insertions(+), 4 deletions(-)


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 07:57:20 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 15:57:20 +0000
Subject: [PATCH v1 2/2] KVM: arm64: Add some more comments in
 kvm_hyp_handle_fpsimd()
In-Reply-To: <20220124155720.3943374-1-broonie@kernel.org>
References: <20220124155720.3943374-1-broonie@kernel.org>
Message-ID: <20220124155720.3943374-3-broonie@kernel.org>

The handling for FPSIMD/SVE traps is multi stage and involves some trap
manipulation which isn't quite so immediately obvious as might be desired
so add a few more comments.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..1995808d8766 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -173,6 +173,8 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 		return false;
 
 	/* Valid trap.  Switch the context: */
+
+	/* First disable enough traps to allow us to update the registers */
 	if (has_vhe()) {
 		reg = CPACR_EL1_FPEN;
 		if (sve_guest)
@@ -188,11 +190,13 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 	}
 	isb();
 
+	/* Write out the host state if it's in the registers */
 	if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
 		__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
 		vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
 	}
 
+	/* Restore the guest state */
 	if (sve_guest)
 		__hyp_sve_restore_guest(vcpu);
 	else
-- 
2.30.2



From miles.chen at mediatek.com  Mon Jan 24 07:56:35 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Mon, 24 Jan 2022 23:56:35 +0800
Subject: [PATCH 01/31] clk: mediatek: Use %pe to print errors
In-Reply-To: <20220122091731.283592-2-wenst@chromium.org>
References: <20220122091731.283592-2-wenst@chromium.org>
Message-ID: <20220124155635.17514-1-miles.chen@mediatek.com>

> If %pe is used to print errors, a string representation of the error
> would be printed instead of a number as with %ld. Also, all the sites
> printing errors are deriving the error code from a pointer. Using %pe
> is more straightforward.

Reviewed-by: Miles Chen <miles.chen at mediatek.com>


From zajec5 at gmail.com  Mon Jan 24 08:02:57 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 24 Jan 2022 17:02:57 +0100
Subject: [PATCH 0/3] nvmem: allow specifying cells by just names in DT
Message-ID: <20220124160300.25131-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This is a simplified & cleaned up version of my:
[PATCH 0/5] nvmem: support more NVMEM cells variants

These changes will allow me to improve BCM5301X support with:

diff --git a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
index 24ae3c8a3..9efcb2424 100644
--- a/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
+++ b/arch/arm/boot/dts/bcm47094-luxul-xwr-3150-v1.dts
@@ -25,6 +25,9 @@ memory at 0 {
 	nvram at 1eff0000 {
 		compatible = "brcm,nvram";
 		reg = <0x1eff0000 0x10000>;
+
+		et0macaddr: et0macaddr {
+		};
 	};
 
 	leds {
@@ -72,6 +75,11 @@ restart {
 	};
 };
 
+&gmac0 {
+	nvmem-cells = <&et0macaddr>;
+	nvmem-cell-names = "mac-address";
+};
+
 &usb3 {
 	vcc-gpio = <&chipcommon 18 GPIO_ACTIVE_HIGH>;
 };

Rafa? Mi?ecki (3):
  dt-bindings: nvmem: make "reg" property optional
  dt-bindings: nvmem: brcm,nvram: add NVMEM cell to example
  nvmem: core: add cell name based matching of DT cell nodes

 .../devicetree/bindings/nvmem/brcm,nvram.yaml |  7 +++--
 .../devicetree/bindings/nvmem/nvmem.yaml      |  3 ---
 drivers/nvmem/core.c                          | 27 +++++++++++++++++++
 3 files changed, 32 insertions(+), 5 deletions(-)

-- 
2.31.1



From zajec5 at gmail.com  Mon Jan 24 08:02:58 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 24 Jan 2022 17:02:58 +0100
Subject: [PATCH 1/3] dt-bindings: nvmem: make "reg" property optional
In-Reply-To: <20220124160300.25131-1-zajec5@gmail.com>
References: <20220124160300.25131-1-zajec5@gmail.com>
Message-ID: <20220124160300.25131-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Most NVMEM providers have cells at hardcoded addresses however there are
some exceptions. Some devices store cells layout in internal structs
using custom formats.

It's important to allow NVMEM consumers to still reference such NVMEM
cells. Making "reg" optional allows defining NVMEM cells by their names
only and using them with phandles.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 Documentation/devicetree/bindings/nvmem/nvmem.yaml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
index 43ed7e32e5ac..3bb349c634cb 100644
--- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml
+++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
@@ -60,9 +60,6 @@ patternProperties:
             description:
               Size in bit within the address range specified by reg.
 
-    required:
-      - reg
-
 additionalProperties: true
 
 examples:
-- 
2.31.1



From zajec5 at gmail.com  Mon Jan 24 08:02:59 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 24 Jan 2022 17:02:59 +0100
Subject: [PATCH 2/3] dt-bindings: nvmem: brcm, nvram: add NVMEM cell to example
In-Reply-To: <20220124160300.25131-1-zajec5@gmail.com>
References: <20220124160300.25131-1-zajec5@gmail.com>
Message-ID: <20220124160300.25131-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

NVRAM doesn't have cells at hardcoded addresses. They are stored in
internal struct (custom & dynamic format) . It's still important to
define relevant cells in DT so NVMEM consumers can reference them.

One of cells set in almost every device is "et0macaddr" containing MAC
address. Add it to example to show how it can be referenced.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
index 8c3f0cd22821..ab14e3ae45c8 100644
--- a/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
+++ b/Documentation/devicetree/bindings/nvmem/brcm,nvram.yaml
@@ -32,6 +32,9 @@ unevaluatedProperties: false
 examples:
   - |
     nvram at 1eff0000 {
-            compatible = "brcm,nvram";
-            reg = <0x1eff0000 0x10000>;
+        compatible = "brcm,nvram";
+        reg = <0x1eff0000 0x10000>;
+
+        mac: et0macaddr {
+        };
     };
-- 
2.31.1



From zajec5 at gmail.com  Mon Jan 24 08:03:00 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Mon, 24 Jan 2022 17:03:00 +0100
Subject: [PATCH 3/3] nvmem: core: add cell name based matching of DT cell nodes
In-Reply-To: <20220124160300.25131-1-zajec5@gmail.com>
References: <20220124160300.25131-1-zajec5@gmail.com>
Message-ID: <20220124160300.25131-4-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

When adding NVMEM cells defined by driver it's important to match them
with DT nodes that specify matching names. That way other bindings &
drivers can reference such "dynamic" NVMEM cells.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 drivers/nvmem/core.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 23a38dcf0fc4..9a1299a7f46a 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -499,6 +499,31 @@ static int nvmem_cell_info_to_nvmem_cell_entry(struct nvmem_device *nvmem,
 	return 0;
 }
 
+/**
+ * nvmem_find_cell_of_node() - Find DT node matching nvmem cell
+ *
+ * @nvmem: nvmem provider
+ * @name: nvmem cell name
+ *
+ * Runtime created nvmem cells (those not coming from DT) may still need to be
+ * referenced in DT. This function allows finding DT node referencing nvmem cell
+ * by its name. Such a DT node can be then used by nvmem consumers.
+ *
+ * Return: NULL or pointer to DT node
+ */
+static struct device_node *nvmem_find_cell_of_node(struct nvmem_device *nvmem,
+						   const char *name)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(nvmem->dev.of_node, child) {
+		if (!strcmp(child->name, name))
+			return child;
+	}
+
+	return NULL;
+}
+
 /**
  * nvmem_add_cells() - Add cell information to an nvmem device
  *
@@ -532,6 +557,8 @@ static int nvmem_add_cells(struct nvmem_device *nvmem,
 			goto err;
 		}
 
+		cells[i]->np = nvmem_find_cell_of_node(nvmem, cells[i]->name);
+
 		nvmem_cell_entry_add(cells[i]);
 	}
 
-- 
2.31.1



From miles.chen at mediatek.com  Mon Jan 24 08:04:38 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 25 Jan 2022 00:04:38 +0800
Subject: [PATCH 02/31] clk: mediatek: gate: Consolidate gate type clk
 related code
In-Reply-To: <20220122091731.283592-3-wenst@chromium.org>
References: <20220122091731.283592-3-wenst@chromium.org>
Message-ID: <20220124160438.17755-1-miles.chen@mediatek.com>

> Right now some bits of the gate type clk code are in clk-gate.[ch], but
> other bits are in clk-mtk.[ch]. This is different from the cpumux and
> mux type clks, for which all of the code are found in the same files.
> 
> Move the functions that register multiple clks from a given list,
> mtk_clk_register_gates_with_dev() and mtk_clk_register_gates(), to
> clk-gate.[ch] to consolidate all the code for the gate type clks.
> 
> This commit only moves code with minor whitespace fixups to correct
> the code style. Further improvements, such as internalizing various
> functions and structures will be done in later commits.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>


From miles.chen at mediatek.com  Mon Jan 24 08:09:33 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 25 Jan 2022 00:09:33 +0800
Subject: [PATCH 03/31] clk: mediatek: gate: Internalize clk implementation
In-Reply-To: <20220122091731.283592-4-wenst@chromium.org>
References: <20220122091731.283592-4-wenst@chromium.org>
Message-ID: <20220124160933.17955-1-miles.chen@mediatek.com>

> struct mtk_clk_gate and mtk_clk_register_gate() are not used outside of
> the gate clk library. Only the API that handles a list of clks is used
> by the individual platform clk drivers.
> 
> Internalize the parts that aren't used outside of the implementation.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>


From broonie at kernel.org  Mon Jan 24 08:11:15 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 16:11:15 +0000
Subject: [PATCH] arm64/fpsimd: Clarify the purpose of using last in
 fpsimd_save()
Message-ID: <20220124161115.115200-1-broonie@kernel.org>

When saving the floating point context in fpsimd_save() we always reference
the state using last-> rather than using current->. Looking at the FP code
in isolation the reason for this is not entirely obvious, it's done because
when KVM is running it will bind the guest context and rely on the host
writing out the guest state on context switch away from the guest.

There's a slight trick here in that KVM still uses TIF_FOREIGN_FPSTATE and
TIF_SVE to communicate what needs to be saved, it maintains those flags
and restores them when it is done running the guest so that the normal
restore paths function when we return back to userspace.

Add a comment to explain this to help future readers work out what's going
on a bit faster.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 5280e098cfb5..47af76e53221 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -348,7 +348,13 @@ static void task_fpsimd_load(void)
 
 /*
  * Ensure FPSIMD/SVE storage in memory for the loaded context is up to
- * date with respect to the CPU registers.
+ * date with respect to the CPU registers. Note carefully that the
+ * current context is the context last bound to the CPU stored in
+ * last, if KVM is involved this may be the guest VM context rather
+ * than the host thread for the VM pointed to by current. This means
+ * that we must always reference the state storage via last rather
+ * than via current, other than the TIF_ flags which KVM will
+ * carefully maintain for us.
  */
 static void fpsimd_save(void)
 {
-- 
2.30.2



From tabba at google.com  Mon Jan 24 08:18:52 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 16:18:52 +0000
Subject: [RFC PATCH v4 00/26] KVM: arm64: Make CPU ID registers writable
 by userspace
In-Reply-To: <20220106042708.2869332-1-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
Message-ID: <CA+EHjTz1=Nwd97GzagkAqZ08m-yGUHeujmtX45mLDD1beF8Ykg@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:27 AM Reiji Watanabe <reijiw at google.com> wrote:

> The patch series is for both VHE and non-VHE, except for protected VMs,
> which have a different way of configuring ID registers based on its
> different requirements [1].

I am reviewing this patch series and I really like your approach. I
think that once it's through we might be able to generalize it for
protected VMs as well (I did some of the work for the ID registers for
those).

> The series is based on v5.16-rc8 with the patch [3] applied.

I tried to apply this series on v5.16-rc8 after applying
20220104194918.373612-2-rananta at google.com, and it didn't apply
cleanly. If you could point me to a working branch that I could
checkout I would like to test it and experiment with it a bit more.

Thanks,
/fuad




> v4:
>   - Make ID registers storage per VM instead of per vCPU. [Marc]
>   - Implement arm64_check_features() in arch/arm64/kernel/cpufeature.c
>     by using existing codes in the file. [Marc]
>   - Use a configuration function to enable traps for disabled
>     features. [Marc]
>   - Document ID registers become immutable after the first KVM_RUN [Eric]
>   - Update ID_AA64PFR0.GIC at the point where a GICv3 is created. [Marc]
>   - Get TGranX's bit position by substracting 12 from TGranX_2's bit
>     position. [Eric]
>   - Don't validate AArch32 ID registers when the system doesn't support
>     32bit EL0. [Eric]
>   - Add/fixes comments for patches. [Eric]
>   - Made bug fixes/improvements of the selftest. [Eric]
>   - Added .kunitconfig for arm64 KUnit tests
>
> v3: https://lore.kernel.org/all/20211117064359.2362060-1-reijiw at google.com/
>   - Remove ID register consistency checking across vCPUs. [Oliver]
>   - Change KVM_CAP_ARM_ID_REG_WRITABLE to
>     KVM_CAP_ARM_ID_REG_CONFIGURABLE. [Oliver]
>   - Add KUnit testing for ID register validation and trap initialization.
>   - Change read_id_reg() to take care of ID_AA64PFR0_EL1.GIC.
>   - Add a helper of read_id_reg() (__read_id_reg()) and use the helper
>     instead of directly using __vcpu_sys_reg().
>   - Change not to run kvm_id_regs_consistency_check() and
>     kvm_vcpu_init_traps() for protected VMs.
>   - Update selftest to remove test cases for ID register consistency.
>     checking across vCPUs and to add test cases for ID_AA64PFR0_EL1.GIC.
>
> v2: https://lore.kernel.org/all/20211103062520.1445832-1-reijiw at google.com/
>   - Remove unnecessary line breaks. [Andrew]
>   - Use @params for comments. [Andrew]
>   - Move arm64_check_features to arch/arm64/kvm/sys_regs.c and
>     change that KVM specific feature check function.  [Andrew]
>   - Remove unnecessary raz handling from __set_id_reg. [Andrew]
>   - Remove sys_val field from the initial id_reg_info and add it
>     in the later patch. [Andrew]
>   - Call id_reg->init() from id_reg_info_init(). [Andrew]
>   - Fix cpuid_feature_cap_perfmon_field() to convert 0xf to 0x0
>     (and use it in the following patches).
>   - Change kvm_vcpu_first_run_init to set has_run_once to false
>     when kvm_id_regs_consistency_check() fails.
>   - Add a patch to introduce id_reg_info for ID_AA64MMFR0_EL1,
>     which requires special validity checking for TGran*_2 fields.
>   - Add patches to introduce id_reg_info for ID_DFR1_EL1 and
>     ID_MMFR0_EL1, which are required due to arm64_check_features
>     implementation change.
>   - Add a new argument, which is a pointer to id_reg_info, for
>     id_reg_info's validate().
>
> v1: https://lore.kernel.org/all/20211012043535.500493-1-reijiw at google.com/
>
> [1] https://lore.kernel.org/kvmarm/20211010145636.1950948-1-tabba at google.com/
> [2] https://lore.kernel.org/kvm/20201102033422.657391-1-liangpeng10 at huawei.com/
> [3] https://lore.kernel.org/all/20220104194918.373612-2-rananta at google.com/
>
> Reiji Watanabe (26):
>   KVM: arm64: Introduce a validation function for an ID register
>   KVM: arm64: Save ID registers' sanitized value per guest
>   KVM: arm64: Introduce struct id_reg_info
>   KVM: arm64: Make ID_AA64PFR0_EL1 writable
>   KVM: arm64: Make ID_AA64PFR1_EL1 writable
>   KVM: arm64: Make ID_AA64ISAR0_EL1 writable
>   KVM: arm64: Make ID_AA64ISAR1_EL1 writable
>   KVM: arm64: Make ID_AA64MMFR0_EL1 writable
>   KVM: arm64: Hide IMPLEMENTATION DEFINED PMU support for the guest
>   KVM: arm64: Make ID_AA64DFR0_EL1 writable
>   KVM: arm64: Make ID_DFR0_EL1 writable
>   KVM: arm64: Make MVFR1_EL1 writable
>   KVM: arm64: Make ID registers without id_reg_info writable
>   KVM: arm64: Add consistency checking for frac fields of ID registers
>   KVM: arm64: Introduce KVM_CAP_ARM_ID_REG_CONFIGURABLE capability
>   KVM: arm64: Add kunit test for ID register validation
>   KVM: arm64: Use vcpu->arch cptr_el2 to track value of cptr_el2 for VHE
>   KVM: arm64: Use vcpu->arch.mdcr_el2 to track value of mdcr_el2
>   KVM: arm64: Introduce framework to trap disabled features
>   KVM: arm64: Trap disabled features of ID_AA64PFR0_EL1
>   KVM: arm64: Trap disabled features of ID_AA64PFR1_EL1
>   KVM: arm64: Trap disabled features of ID_AA64DFR0_EL1
>   KVM: arm64: Trap disabled features of ID_AA64MMFR1_EL1
>   KVM: arm64: Trap disabled features of ID_AA64ISAR1_EL1
>   KVM: arm64: Add kunit test for trap initialization
>   KVM: arm64: selftests: Introduce id_reg_test
>
>  Documentation/virt/kvm/api.rst                |   12 +
>  arch/arm64/include/asm/cpufeature.h           |    3 +-
>  arch/arm64/include/asm/kvm_arm.h              |   32 +
>  arch/arm64/include/asm/kvm_host.h             |   19 +
>  arch/arm64/include/asm/sysreg.h               |    3 +
>  arch/arm64/kernel/cpufeature.c                |  228 +++
>  arch/arm64/kvm/.kunitconfig                   |    4 +
>  arch/arm64/kvm/Kconfig                        |   11 +
>  arch/arm64/kvm/arm.c                          |   24 +-
>  arch/arm64/kvm/debug.c                        |   13 +-
>  arch/arm64/kvm/hyp/vhe/switch.c               |   14 +-
>  arch/arm64/kvm/sys_regs.c                     | 1329 +++++++++++++++--
>  arch/arm64/kvm/sys_regs_test.c                | 1247 ++++++++++++++++
>  arch/arm64/kvm/vgic/vgic-init.c               |    5 +
>  include/uapi/linux/kvm.h                      |    1 +
>  tools/arch/arm64/include/asm/sysreg.h         |    1 +
>  tools/testing/selftests/kvm/.gitignore        |    1 +
>  tools/testing/selftests/kvm/Makefile          |    1 +
>  .../selftests/kvm/aarch64/id_reg_test.c       | 1239 +++++++++++++++
>  19 files changed, 4041 insertions(+), 146 deletions(-)
>  create mode 100644 arch/arm64/kvm/.kunitconfig
>  create mode 100644 arch/arm64/kvm/sys_regs_test.c
>  create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c
>
>
> base-commit: d399b107ee49bf5ea0391bd7614d512809e927b0
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From tabba at google.com  Mon Jan 24 08:20:04 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 16:20:04 +0000
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function
 for an ID register
In-Reply-To: <20220106042708.2869332-2-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-2-reijiw@google.com>
Message-ID: <CA+EHjTx+b0ZVw30riW4OUVP4BCPeJZe+gr5_ycHkPbwU=y7sqA@mail.gmail.com>

Hi Reiji,

...

> +
> +/*
> + * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
> + * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
> + * ARM64_FTR_END (.width == 0).
> + */
> +static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,

s/overrite/override

> +                                       struct arm64_ftr_bits *new_ftrp)

Should this be const struct arm64_ftr_bits *new_ftrp, which would also
make it consistent with copy_arm64_ftr_bits()?

> +{
> +       struct arm64_ftr_bits *o_ftrp, *n_ftrp;
> +
> +       for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
> +               for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
> +                       if (o_ftrp->shift == n_ftrp->shift) {
> +                               *o_ftrp = *n_ftrp;
> +                               break;
> +                       }
> +               }
> +       }
> +}
> +

...

> +/*
> + * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
> + * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
> + * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
> + */
> +static int init_arm64_ftr_bits_kvm(void)
> +{
> +       struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
> +       static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
> +       int i, j, nent, ret;
> +
> +       mutex_lock(&arm64_ftr_bits_kvm_lock);
> +       if (arm64_ftr_bits_kvm) {
> +               /* Already initialized */
> +               ret = 0;
> +               goto unlock_exit;
> +       }
> +
> +       nent = ARRAY_SIZE(arm64_ftr_regs);
> +       reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
> +                                GFP_KERNEL);
> +       if (!reg_bits_array) {
> +               ret = ENOMEM;

Should this be -ENOMEM?


> +               goto unlock_exit;
> +       }
> +
> +       /* Copy entries from arm64_ftr_regs to reg_bits_array */
> +       for (i = 0; i < nent; i++) {
> +               bits = &reg_bits_array[i];
> +               bits->sys_id = arm64_ftr_regs[i].sys_id;
> +               bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
> +       };
> +
> +       /*
> +        * Override the entries in reg_bits_array with the ones in
> +        * arm64_ftr_bits_kvm_override.
> +        */
> +       for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
> +               o_bits = &arm64_ftr_bits_kvm_override[i];
> +               for (j = 0; j < nent; j++) {
> +                       bits = &reg_bits_array[j];
> +                       if (bits->sys_id != o_bits->sys_id)
> +                               continue;
> +
> +                       memset(ftr_temp, 0, sizeof(ftr_temp));
> +
> +                       /*
> +                        * Temporary save all entries in o_bits->ftr_bits
> +                        * to ftr_temp.
> +                        */
> +                       copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
> +
> +                       /*
> +                        * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
> +                        */
> +                       copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
> +
> +                       /*
> +                        * Override entries in o_bits->ftr_bits with the
> +                        * saved ones, and update bits->ftr_bits with
> +                        * o_bits->ftr_bits.
> +                        */
> +                       arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
> +                       bits->ftr_bits = o_bits->ftr_bits;
> +                       break;
> +               }
> +       }

Could you please explain using ftr_temp[] and changing the value in
arm64_ftr_bits_kvm_override, rather than just
arm64_ftr_reg_bits_overrite(bits->ftr_bits, o_bits->ftr_bits)?


> +static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
> +{
> +       const struct __ftr_reg_bits_entry *ret;
> +       int err;
> +
> +       if (!arm64_ftr_bits_kvm) {
> +               /* arm64_ftr_bits_kvm is not initialized yet. */
> +               err = init_arm64_ftr_bits_kvm();

Rather than doing this check, can we just initialize it earlier, maybe
(indirectly) via kvm_arch_init_vm() or around the same time?


> +               if (err)
> +                       return NULL;
> +       }
> +
> +       ret = bsearch((const void *)(unsigned long)sys_id,
> +                     arm64_ftr_bits_kvm,
> +                     arm64_ftr_bits_kvm_nentries,
> +                     sizeof(arm64_ftr_bits_kvm[0]),
> +                     search_cmp_ftr_reg_bits);
> +       if (ret)
> +               return ret->ftr_bits;
> +
> +       return NULL;
> +}
> +
> +/*
> + * Check if features (or levels of features) that are indicated in the ID
> + * register value @val are also indicated in @limit.
> + * This function is for KVM to check if features that are indicated in @val,
> + * which will be used as the ID register value for its guest, are supported
> + * on the host.
> + * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
> + * scheme, the function checks if values of the fields in @val are the same
> + * as the ones in @limit.
> + */
> +int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
> +{
> +       const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);
> +       u64 exposed_mask = 0;
> +
> +       if (!ftrp)
> +               return -ENOENT;
> +
> +       for (; ftrp->width; ftrp++) {
> +               s64 ftr_val = arm64_ftr_value(ftrp, val);
> +               s64 ftr_lim = arm64_ftr_value(ftrp, limit);
> +
> +               exposed_mask |= arm64_ftr_mask(ftrp);
> +
> +               if (ftr_val == ftr_lim)
> +                       continue;

At first I thought that this check isn't necessary, it should be
covered by the check below (arm64_ftr_safe_value. However, I think
that it's needed for the FTR_HIGHER_OR_ZERO_SAFE case. If my
understanding is correct, it might be worth adding a comment, or even
encapsulating this logic in a arm64_is_safe_value() function for
clarity.

> +
> +               if (ftr_val != arm64_ftr_safe_value(ftrp, ftr_val, ftr_lim))
> +                       return -E2BIG;
> +       }
> +
> +       /* Make sure that no unrecognized fields are set in @val. */
> +       if (val & ~exposed_mask)
> +               return -E2BIG;
> +
> +       return 0;
> +}

Thanks,
/fuad








> +#endif /* CONFIG_KVM */
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From linux at roeck-us.net  Mon Jan 24 08:21:05 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Mon, 24 Jan 2022 08:21:05 -0800
Subject: [PATCH v2] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <20220124120027.106754-1-alistair@alistair23.me>
References: <20220124120027.106754-1-alistair@alistair23.me>
Message-ID: <1a8ee480-b066-8da9-cd63-079e07b7d88a@roeck-us.net>

On 1/24/22 04:00, Alistair Francis wrote:
> The i.MX watchdog cannot be disabled by softwrae once it has been

s/softwrae/software/

> enabled. This means that it can't be stopped before suspend.
> 
> For systems that enter low power mode this is fine, as the watchdog will
> be automatically stopped by hardwrae in low power mode. Not all i.MX

s/hardwrae/hardware/

> platforms support low power mode in the mainline kernel. For example the
> i.MX7D does not enter low power mode and so will be rebooted 2 minutes
> after entering freeze or mem sleep states.

I don't think "mem" adds any value here. Just make it sleep states.

> 
> This patch introduces a device tree property "fsl,ping-during-suspend"
> that can be used to enable ping on suspend support for these systems.
> 
> Signed-off-by: Alistair Francis <alistair at alistair23.me>
> ---

Change log goes here.

>   drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
>   1 file changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
> index 51bfb796898b..d0c5d47ddede 100644
> --- a/drivers/watchdog/imx2_wdt.c
> +++ b/drivers/watchdog/imx2_wdt.c
> @@ -66,6 +66,7 @@ struct imx2_wdt_device {
>   	struct watchdog_device wdog;   
>   	bool ext_reset;
>   	bool clk_is_on;

I don't see the purpose of this variable. Unless I am missing something is is set
but never used.

> +	bool no_ping;
>   };
>   
>   static bool nowayout = WATCHDOG_NOWAYOUT;
> @@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
>   
>   	wdev->ext_reset = of_property_read_bool(dev->of_node,
>   						"fsl,ext-reset-output");
> +	/*
> +	 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
> +	 * during suspend.
> +	 */
> +	wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");

This is ok as long as there is only a single chip requiring this change.
If there are more, the 'data' field in struct of_device_id should be used
instead.

>   	platform_set_drvdata(pdev, wdog);
>   	watchdog_set_drvdata(wdog, wdev);
>   	watchdog_set_nowayout(wdog, nowayout);
>   	watchdog_set_restart_priority(wdog, 128);
>   	watchdog_init_timeout(wdog, timeout, dev);
> -	watchdog_stop_ping_on_suspend(wdog);
> +	if (wdev->no_ping)
> +		watchdog_stop_ping_on_suspend(wdog);
>   
>   	if (imx2_wdt_is_running(wdev)) {
>   		imx2_wdt_set_timeout(wdog, wdog->timeout);
> @@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
>   		imx2_wdt_ping(wdog);
>   	}
>   
> -	clk_disable_unprepare(wdev->clk);
> +	if (wdev->no_ping) {
> +		clk_disable_unprepare(wdev->clk);
>   
> -	wdev->clk_is_on = false;
> +		wdev->clk_is_on = false;
> +	}
>   
>   	return 0;
>   }
> @@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
>   	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
>   	int ret;
>   
> -	ret = clk_prepare_enable(wdev->clk);
> -	if (ret)
> -		return ret;
> +	if (wdev->no_ping) {
> +		ret = clk_prepare_enable(wdev->clk);
>   
> -	wdev->clk_is_on = true;
> +		if (ret)
> +			return ret;
> +
> +		wdev->clk_is_on = true;
> +	}
>   
>   	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
>   		/*
> @@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
>   
>   static const struct of_device_id imx2_wdt_dt_ids[] = {
>   	{ .compatible = "fsl,imx21-wdt", },
> +	{ .compatible = "fsl,imx7d-wdt", },
>   	{ /* sentinel */ }
>   };
>   MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);



From miles.chen at mediatek.com  Mon Jan 24 08:21:24 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 25 Jan 2022 00:21:24 +0800
Subject: [PATCH 04/31] clk: mediatek: gate: Implement unregister API
In-Reply-To: <20220122091731.283592-5-wenst@chromium.org>
References: <20220122091731.283592-5-wenst@chromium.org>
Message-ID: <20220124162124.18721-1-miles.chen@mediatek.com>

> The gate clk type within the MediaTek clk driver library only has a
> register function, and no corresponding unregister function. This
> means there is no way for its users to properly implement cleanup
> and removal.
> 
> Add a matching unregister function for the gate type clk.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>


From daniel at iogearbox.net  Mon Jan 24 08:21:26 2022
From: daniel at iogearbox.net (Daniel Borkmann)
Date: Mon, 24 Jan 2022 17:21:26 +0100
Subject: [PATCH bpf-next] bpf, arm64: enable kfunc call
In-Reply-To: <20220119144942.305568-1-houtao1@huawei.com>
References: <20220119144942.305568-1-houtao1@huawei.com>
Message-ID: <b54b3297-086c-1b64-1c25-01f70c6412af@iogearbox.net>

On 1/19/22 3:49 PM, Hou Tao wrote:
> Since commit b2eed9b58811 ("arm64/kernel: kaslr: reduce module
> randomization range to 2 GB"), for arm64 whether KASLR is enabled
> or not, the module is placed within 2GB of the kernel region, so
> s32 in bpf_kfunc_desc is sufficient to represente the offset of
> module function relative to __bpf_call_base. The only thing needed
> is to override bpf_jit_supports_kfunc_call().
> 
> Signed-off-by: Hou Tao <houtao1 at huawei.com>

Lgtm, could we also add a BPF selftest to assert that this assumption
won't break in future when bpf_jit_supports_kfunc_call() returns true?

E.g. extending lib/test_bpf.ko could be an option, wdyt?

> ---
>   arch/arm64/net/bpf_jit_comp.c | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index e96d4d87291f..74f9a9b6a053 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -1143,6 +1143,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
>   	return prog;
>   }
>   
> +bool bpf_jit_supports_kfunc_call(void)
> +{
> +	return true;
> +}
> +
>   u64 bpf_jit_alloc_exec_limit(void)
>   {
>   	return VMALLOC_END - VMALLOC_START;
> 



From tabba at google.com  Mon Jan 24 08:21:32 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 16:21:32 +0000
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <20220106042708.2869332-3-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
Message-ID: <CA+EHjTxVe3baCwpde+QFYKvyUaUGu9F37t-=r8k32JcHBOY61Q@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:28 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> Introduce id_regs[] in kvm_arch as a storage of guest's ID registers,
> and save ID registers' sanitized value in the array at KVM_CREATE_VM.
> Use the saved ones when ID registers are read by the guest or
> userspace (via KVM_GET_ONE_REG).
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 16 ++++++++
>  arch/arm64/kvm/arm.c              |  1 +
>  arch/arm64/kvm/sys_regs.c         | 62 ++++++++++++++++++++++---------
>  3 files changed, 62 insertions(+), 17 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2a5f7f38006f..c789a0137f58 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -102,6 +102,17 @@ struct kvm_s2_mmu {
>  struct kvm_arch_memory_slot {
>  };
>
> +/*
> + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> + * where 0<=crm<8, 0<=op2<8.
> + */
> +#define KVM_ARM_ID_REG_MAX_NUM 64
> +#define IDREG_IDX(id)          ((sys_reg_CRm(id) << 3) | sys_reg_Op2(id))
> +#define is_id_reg(id)  \
> +       (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&        \
> +        sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&        \
> +        sys_reg_CRm(id) < 8)
> +

This is consistent with the Arm ARM "Table D12-2 System instruction
encodings for non-Debug System register accesses".

Minor nit, would it be better to have IDREG_IDX and is_id_reg in
arch/arm64/kvm/sys_regs.h, since other similar and related ones are
there?

>  struct kvm_arch {
>         struct kvm_s2_mmu mmu;
>
> @@ -137,6 +148,9 @@ struct kvm_arch {
>
>         /* Memory Tagging Extension enabled for the guest */
>         bool mte_enabled;
> +
> +       /* ID registers for the guest. */
> +       u64 id_regs[KVM_ARM_ID_REG_MAX_NUM];
>  };
>
>  struct kvm_vcpu_fault_info {
> @@ -734,6 +748,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
>  long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>                                 struct kvm_arm_copy_mte_tags *copy_tags);
>
> +void set_default_id_regs(struct kvm *kvm);
> +
>  /* Guest/host FPSIMD coordination helpers */
>  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
>  void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e4727dc771bf..5f497a0af254 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>         kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
>
>         set_default_spectre(kvm);
> +       set_default_id_regs(kvm);
>
>         return ret;
>  out_free_stage2_pgd:
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index e3ec1a44f94d..80dc62f98ef0 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -33,6 +33,8 @@
>
>  #include "trace.h"
>
> +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
> +
>  /*
>   * All of this file is extremely similar to the ARM coproc.c, but the
>   * types are different. My gut feeling is that it should be pretty
> @@ -273,7 +275,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
>                           struct sys_reg_params *p,
>                           const struct sys_reg_desc *r)
>  {
> -       u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> +       u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
>         u32 sr = reg_to_encoding(r);
>
>         if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> @@ -1059,17 +1061,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
>         return true;
>  }
>
> -/* Read a sanitised cpufeature ID register by sys_reg_desc */
> -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> -               struct sys_reg_desc const *r, bool raz)
> +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>  {
> -       u32 id = reg_to_encoding(r);
> -       u64 val;
> -
> -       if (raz)
> -               return 0;
> -
> -       val = read_sanitised_ftr_reg(id);
> +       u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
>
>         switch (id) {
>         case SYS_ID_AA64PFR0_EL1:
> @@ -1119,6 +1113,14 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
>         return val;
>  }
>
> +static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> +                      struct sys_reg_desc const *r, bool raz)
> +{
> +       u32 id = reg_to_encoding(r);
> +
> +       return raz ? 0 : __read_id_reg(vcpu, id);
> +}
> +
>  static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
>                                   const struct sys_reg_desc *r)
>  {
> @@ -1223,9 +1225,8 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
>  /*
>   * cpufeature ID register user accessors
>   *
> - * For now, these registers are immutable for userspace, so no values
> - * are stored, and for set_id_reg() we don't allow the effective value
> - * to be changed.
> + * For now, these registers are immutable for userspace, so for set_id_reg()
> + * we don't allow the effective value to be changed.
>   */
>  static int __get_id_reg(const struct kvm_vcpu *vcpu,
>                         const struct sys_reg_desc *rd, void __user *uaddr,
> @@ -1237,7 +1238,7 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
>         return reg_to_user(uaddr, &val, id);
>  }
>
> -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> +static int __set_id_reg(struct kvm_vcpu *vcpu,
>                         const struct sys_reg_desc *rd, void __user *uaddr,
>                         bool raz)

Minor nit: why remove the const in this patch? This is required for a
future patch but not for this one.

Thanks,
/fuad


>  {
> @@ -1837,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
>         if (p->is_write) {
>                 return ignore_write(vcpu, p);
>         } else {
> -               u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
> -               u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +               u64 dfr = __read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> +               u64 pfr = __read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
>                 u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
>
>                 p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
> @@ -2850,3 +2851,30 @@ void kvm_sys_reg_table_init(void)
>         /* Clear all higher bits. */
>         cache_levels &= (1 << (i*3))-1;
>  }
> +
> +/*
> + * Set the guest's ID registers that are defined in sys_reg_descs[]
> + * with ID_SANITISED() to the host's sanitized value.
> + */
> +void set_default_id_regs(struct kvm *kvm)
> +{
> +       int i;
> +       u32 id;
> +       const struct sys_reg_desc *rd;
> +       u64 val;
> +
> +       for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> +               rd = &sys_reg_descs[i];
> +               if (rd->access != access_id_reg)
> +                       /* Not ID register, or hidden/reserved ID register */
> +                       continue;
> +
> +               id = reg_to_encoding(rd);
> +               if (WARN_ON_ONCE(!is_id_reg(id)))
> +                       /* Shouldn't happen */
> +                       continue;
> +
> +               val = read_sanitised_ftr_reg(id);
> +               kvm->arch.id_regs[IDREG_IDX(id)] = val;
> +       }
> +}
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From baruch at tkos.co.il  Mon Jan 24 08:27:29 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 24 Jan 2022 18:27:29 +0200
Subject: [PATCH v5 1/3] arm64: dts: qcom: ipq6018: add pcie max-link-speed
In-Reply-To: <cover.1643041464.git.baruch@tkos.co.il>
References: <cover.1643041464.git.baruch@tkos.co.il>
Message-ID: <a3c2914eb55d0e364611c56e1ef3ccbe2342ba3f.1643041464.git.baruch@tkos.co.il>

From: Baruch Siach <baruch.siach at siklu.com>

Add the generic 'max-link-speed' that correctly describes the IPQ6018
PCIe link generation limit. This allows the generic dwc code to
configure the link speed correctly.

Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
---
 arch/arm64/boot/dts/qcom/ipq6018.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
index a717fc17523d..665ee301b85d 100644
--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -438,6 +438,7 @@ pcie0: pci at 20000000 {
 			linux,pci-domain = <0>;
 			bus-range = <0x00 0xff>;
 			num-lanes = <1>;
+			max-link-speed = <3>;
 			#address-cells = <3>;
 			#size-cells = <2>;
 
-- 
2.34.1



From baruch at tkos.co.il  Mon Jan 24 08:27:28 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 24 Jan 2022 18:27:28 +0200
Subject: [PATCH v5 0/3] arm64: IPQ6018 PCIe support
Message-ID: <cover.1643041464.git.baruch@tkos.co.il>

This series adds support for the single PCIe lane on IPQ6018 SoCs. The code is 
ported from downstream Codeaurora v5.4 kernel. The main difference from 
downstream code is the split of PCIe registers configuration from .init to 
.post_init, since it requires phy_power_on().

Tested on IPQ6010 based hardware.

Changes in v5:

  * Remove comments from qcom_pcie_init_2_9_0() (Bjorn Andersson)

Changes in v4:

  * Drop applied DT bits

  * Add max-link-speed that was missing from the applied v2 patch

  * Rebase the driver on v5.16-rc3

Changes in v3:

  * Drop applied patches

  * Rely on generic code for speed setup

  * Drop unused macros

  * Formatting fixes

Changes in v2:

  * Add patch moving GEN3_RELATED macros to a common header

  * Drop ATU configuration from pcie-qcom

  * Remove local definition of common registers

  * Use bulk clk and reset APIs

  * Remove msi-parent from device-tree

Baruch Siach (2):
  arm64: dts: qcom: ipq6018: add pcie max-link-speed
  PCI: dwc: tegra: move GEN3_RELATED DBI register to common header

Selvam Sathappan Periakaruppan (1):
  PCI: qcom: add support for IPQ60xx PCIe controller

 arch/arm64/boot/dts/qcom/ipq6018.dtsi        |   1 +
 drivers/pci/controller/dwc/pcie-designware.h |   7 +
 drivers/pci/controller/dwc/pcie-qcom.c       | 137 +++++++++++++++++++
 drivers/pci/controller/dwc/pcie-tegra194.c   |   6 -
 4 files changed, 145 insertions(+), 6 deletions(-)

-- 
2.34.1



From baruch at tkos.co.il  Mon Jan 24 08:27:30 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 24 Jan 2022 18:27:30 +0200
Subject: [PATCH v5 2/3] PCI: dwc: tegra: move GEN3_RELATED DBI register to
 common header
In-Reply-To: <cover.1643041464.git.baruch@tkos.co.il>
References: <cover.1643041464.git.baruch@tkos.co.il>
Message-ID: <f29fc909bca5be189045b78308d14adc75dc6579.1643041464.git.baruch@tkos.co.il>

From: Baruch Siach <baruch.siach at siklu.com>

These are common dwc macros that will be used for other platforms.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
---
 drivers/pci/controller/dwc/pcie-designware.h | 6 ++++++
 drivers/pci/controller/dwc/pcie-tegra194.c   | 6 ------
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 7d6e9b7576be..ea87809ee298 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -74,6 +74,12 @@
 #define PCIE_MSI_INTR0_MASK		0x82C
 #define PCIE_MSI_INTR0_STATUS		0x830
 
+#define GEN3_RELATED_OFF			0x890
+#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
+#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
+#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
+
 #define PCIE_PORT_MULTI_LANE_CTRL	0x8C0
 #define PORT_MLTI_UPCFG_SUPPORT		BIT(7)
 
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c
index b1b5f836a806..74bf66d9afeb 100644
--- a/drivers/pci/controller/dwc/pcie-tegra194.c
+++ b/drivers/pci/controller/dwc/pcie-tegra194.c
@@ -193,12 +193,6 @@
 #define GEN3_EQ_CONTROL_OFF_PSET_REQ_VEC_MASK	GENMASK(23, 8)
 #define GEN3_EQ_CONTROL_OFF_FB_MODE_MASK	GENMASK(3, 0)
 
-#define GEN3_RELATED_OFF			0x890
-#define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
-#define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
-#define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
-
 #define PORT_LOGIC_AMBA_ERROR_RESPONSE_DEFAULT	0x8D0
 #define AMBA_ERROR_RESPONSE_CRS_SHIFT		3
 #define AMBA_ERROR_RESPONSE_CRS_MASK		GENMASK(1, 0)
-- 
2.34.1



From baruch at tkos.co.il  Mon Jan 24 08:27:31 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Mon, 24 Jan 2022 18:27:31 +0200
Subject: [PATCH v5 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <cover.1643041464.git.baruch@tkos.co.il>
References: <cover.1643041464.git.baruch@tkos.co.il>
Message-ID: <f69d32f08a890463a331567e5742f2d33fa8b2bb.1643041464.git.baruch@tkos.co.il>

From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>

IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
platform.

The code is based on downstream[1] Codeaurora kernel v5.4 (branch
win.linuxopenwrt.2.0).

Split out the DBI registers access part from .init into .post_init. DBI
registers are only accessible after phy_power_on().

[1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/

Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
---
v5:

  * Remove comments from qcom_pcie_init_2_9_0() (Bjorn Andersson)

v4:

  * Rebase on v5.16-rc1

v3:
  * Drop speed setup; rely on generic code (Rob Herring)

  * Drop unused CLK_RATE macros (Bjorn Helgaas)

  * Minor formatting fixes (Bjorn Helgaas)

  * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)

v2:
  * Drop ATU configuration; rely on common code instead

  * Use more common register macros

  * Use bulk clk and reset APIs
---
 drivers/pci/controller/dwc/pcie-designware.h |   1 +
 drivers/pci/controller/dwc/pcie-qcom.c       | 137 +++++++++++++++++++
 2 files changed, 138 insertions(+)

diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ea87809ee298..279c3778a13b 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -76,6 +76,7 @@
 
 #define GEN3_RELATED_OFF			0x890
 #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
+#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
 #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
 #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index c19cd506ed3f..5d47e572da44 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -52,6 +52,10 @@
 #define PCIE20_PARF_DBI_BASE_ADDR		0x168
 #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
 #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
+#define AHB_CLK_EN				BIT(0)
+#define MSTR_AXI_CLK_EN				BIT(1)
+#define BYPASS					BIT(4)
+
 #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
 #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
 #define PCIE20_PARF_LTSSM			0x1B0
@@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
 	struct clk *ref_clk_src;
 };
 
+struct qcom_pcie_resources_2_9_0 {
+	struct clk_bulk_data clks[5];
+	struct reset_control *rst;
+};
+
 union qcom_pcie_resources {
 	struct qcom_pcie_resources_1_0_0 v1_0_0;
 	struct qcom_pcie_resources_2_1_0 v2_1_0;
@@ -178,6 +187,7 @@ union qcom_pcie_resources {
 	struct qcom_pcie_resources_2_3_3 v2_3_3;
 	struct qcom_pcie_resources_2_4_0 v2_4_0;
 	struct qcom_pcie_resources_2_7_0 v2_7_0;
+	struct qcom_pcie_resources_2_9_0 v2_9_0;
 };
 
 struct qcom_pcie;
@@ -1297,6 +1307,119 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
 	clk_disable_unprepare(res->pipe_clk);
 }
 
+static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+	struct dw_pcie *pci = pcie->pci;
+	struct device *dev = pci->dev;
+	int ret;
+
+	res->clks[0].id = "iface";
+	res->clks[1].id = "axi_m";
+	res->clks[2].id = "axi_s";
+	res->clks[3].id = "axi_bridge";
+	res->clks[4].id = "rchng";
+
+	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+	if (ret < 0)
+		return ret;
+
+	res->rst = devm_reset_control_array_get_exclusive(dev);
+	if (IS_ERR(res->rst))
+		return PTR_ERR(res->rst);
+
+	return 0;
+}
+
+static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+
+	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
+}
+
+static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
+{
+	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+	struct device *dev = pcie->pci->dev;
+	int ret;
+
+	ret = reset_control_assert(res->rst);
+	if (ret) {
+		dev_err(dev, "reset assert failed (%d)\n", ret);
+		return ret;
+	}
+
+	usleep_range(2000, 2500);
+
+	ret = reset_control_deassert(res->rst);
+	if (ret) {
+		dev_err(dev, "reset deassert failed (%d)\n", ret);
+		return ret;
+	}
+
+	usleep_range(2000, 2500);
+
+	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
+	if (ret)
+		goto err_reset;
+
+	return 0;
+
+err_reset:
+	reset_control_assert(res->rst);
+
+	return ret;
+}
+
+static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+{
+	struct dw_pcie *pci = pcie->pci;
+	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+	u32 val;
+	int i;
+
+	writel(SLV_ADDR_SPACE_SZ,
+		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
+
+	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
+	val &= ~BIT(0);
+	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
+
+	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
+
+	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
+	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
+		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
+	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
+		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
+		pci->dbi_base + GEN3_RELATED_OFF);
+
+	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
+		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
+		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
+		pcie->parf + PCIE20_PARF_SYS_CTRL);
+
+	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
+
+	dw_pcie_dbi_ro_wr_en(pci);
+	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
+
+	/* Configure PCIe link capabilities for ASPM */
+	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
+	val &= ~PCI_EXP_LNKCAP_ASPMS;
+	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
+
+	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
+			PCI_EXP_DEVCTL2);
+
+	for (i = 0; i < 256; i++)
+		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
+				+ (4 * i));
+
+	return 0;
+}
+
 static int qcom_pcie_link_up(struct dw_pcie *pci)
 {
 	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
@@ -1487,6 +1610,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
 	.config_sid = qcom_pcie_config_sid_sm8250,
 };
 
+/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
+static const struct qcom_pcie_ops ops_2_9_0 = {
+	.get_resources = qcom_pcie_get_resources_2_9_0,
+	.init = qcom_pcie_init_2_9_0,
+	.post_init = qcom_pcie_post_init_2_9_0,
+	.deinit = qcom_pcie_deinit_2_9_0,
+	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
+};
+
 static const struct qcom_pcie_cfg apq8084_cfg = {
 	.ops = &ops_1_0_0,
 };
@@ -1520,6 +1652,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
 	.pipe_clk_need_muxing = true,
 };
 
+static const struct qcom_pcie_cfg ipq6018_cfg = {
+	.ops = &ops_2_9_0,
+};
+
 static const struct dw_pcie_ops dw_pcie_ops = {
 	.link_up = qcom_pcie_link_up,
 	.start_link = qcom_pcie_start_link,
@@ -1629,6 +1765,7 @@ static const struct of_device_id qcom_pcie_match[] = {
 	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
 	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
 	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
+	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
 	{ }
 };
 
-- 
2.34.1



From tabba at google.com  Mon Jan 24 08:28:33 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 16:28:33 +0000
Subject: [RFC PATCH v4 03/26] KVM: arm64: Introduce struct id_reg_info
In-Reply-To: <20220106042708.2869332-4-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-4-reijiw@google.com>
Message-ID: <CA+EHjTx65scqNVvHci6fge7C5qQ=fiqqHKGwOvOKySQwsCy8Jg@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:28 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> This patch lays the groundwork to make ID registers writable.
>
> Introduce struct id_reg_info for an ID register to manage the
> register specific control of its value for the guest, and provide set
> of functions commonly used for ID registers to make them writable.
>
> The id_reg_info is used to do register specific initialization,
> validation of the ID register and etc.  Not all ID registers must
> have the id_reg_info. ID registers that don't have the id_reg_info
> are handled in a common way that is applied to all ID registers.
>
> At present, changing an ID register from userspace is allowed only
> if the ID register has the id_reg_info, but that will be changed
> by the following patches.
>
> No ID register has the structure yet and the following patches
> will add the id_reg_info for some ID registers.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 243 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 230 insertions(+), 13 deletions(-)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 80dc62f98ef0..971018288bee 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -265,6 +265,101 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
>                 return read_zero(vcpu, p);
>  }
>
> +struct id_reg_info {
> +       u32     sys_reg;        /* Register ID */

Nit: Why not have the comment above, as for the other fields of this struct?

> +
> +       /*
> +        * Limit value of the register for a vcpu. The value is the sanitized
> +        * system value with bits cleared for unsupported features for the
> +        * guest.
> +        */

I think that rather than saying "with bits cleared for unsupported
features", it might be better to rephrase along the lines of "with
bits indicating" or "set/cleared to indicate", so that it applies to
signed fields as well.

> +       u64     vcpu_limit_val;
> +
> +       /* Fields that we don't to validate by arm64_check_features. */

Nit: Remove "to".

> +       u64     ignore_mask;
> +
> +       /* Initialization function of the id_reg_info */
> +       void (*init)(struct id_reg_info *id_reg);
> +       /*
> +        * This is an optional ID register specific validation function.
> +        * When userspace tries to set the ID register, arm64_check_features()
> +        * will check if the requested value indicates any features that cannot
> +        * be supported by KVM on the host.  But, some ID register fields need
> +        * a special checking, and this function can be used for such fields.
> +        * e.g. When SVE is configured for a vCPU by KVM_ARM_VCPU_INIT,
> +        * ID_AA64PFR0_EL1.SVE shouldn't be set to 0 for the vCPU.
> +        * The validation function for ID_AA64PFR0_EL1 could be used to check
> +        * the field is consistent with SVE configuration.
> +        */
> +       int (*validate)(struct kvm_vcpu *vcpu, const struct id_reg_info *id_reg,
> +                       u64 val);
> +
> +       /*
> +        * Return a bitmask of the vCPU's ID register fields that are not
> +        * synced with saved (per VM) ID register value, which usually
> +        * indicates opt-in CPU features that is not configured for the vCPU.

Nit: s/is/are


> +        * ID registers are saved per VM, but some opt-in CPU features can
> +        * be configured per vCPU.  The saved (per VM) values for such
> +        * features are for vCPUs with the features (and zero for
> +        * vCPUs without the features).
> +        * Return value of this function is used to handle such fields
> +        * for per vCPU ID register read/write request with saved per VM
> +        * ID register.  See the __write_id_reg's comment for more detail.
> +        */
> +       u64 (*vcpu_mask)(const struct kvm_vcpu *vcpu,
> +                        const struct id_reg_info *id_reg);
> +};
> +
> +static void id_reg_info_init(struct id_reg_info *id_reg)
> +{
> +       id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg);
> +       if (id_reg->init)

If there is an id_reg then the init function is necessary, isn't it?
Otherwise it doesn't seem to add more than the default handling. If
that's right, should we instead ensure that init is always set?

> +               id_reg->init(id_reg);
> +}
> +
> +/*
> + * An ID register that needs special handling to control the value for the
> + * guest must have its own id_reg_info in id_reg_info_table.
> + * (i.e. the reset value is different from the host's sanitized value,
> + * the value is affected by opt-in features, some fields need specific
> + * validation, etc.)
> + */
> +#define        GET_ID_REG_INFO(id)     (id_reg_info_table[IDREG_IDX(id)])
> +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
> +
> +static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> +{
> +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> +       u64 limit, tmp_val;
> +       int err;
> +
> +       if (id_reg) {
> +               limit = id_reg->vcpu_limit_val;
> +               /*
> +                * Replace the fields that are indicated in ignore_mask with
> +                * the value in the limit to not have arm64_check_features()
> +                * check the field in @val.
> +                */
> +               tmp_val = val & ~id_reg->ignore_mask;
> +               tmp_val |= (limit & id_reg->ignore_mask);
> +       } else {
> +               limit = read_sanitised_ftr_reg(id);
> +               tmp_val = val;
> +       }
> +
> +       /* Check if the value indicates any feature that is not in the limit. */
> +       err = arm64_check_features(id, tmp_val, limit);
> +       if (err)
> +               return err;
> +
> +       if (id_reg && id_reg->validate)
> +               /* Run the ID register specific validity check. */
> +               err = id_reg->validate(vcpu, id_reg, val);
> +
> +       return err;
> +}
> +
>  /*
>   * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
>   * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
> @@ -1061,9 +1156,81 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
>         return true;
>  }
>
> +static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
> +{
> +       return kvm->arch.id_regs[IDREG_IDX(id)];
> +}
> +
> +static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> +                            u64 preserve_mask)
> +{
> +       u64 old, new;
> +
> +       mutex_lock(&kvm->lock);
> +
> +       old = kvm->arch.id_regs[IDREG_IDX(id)];
> +
> +       /* Preserve the value at the bit position set in preserve_mask */
> +       new = old & preserve_mask;
> +       new |= (val & ~preserve_mask);
> +
> +       /* Don't allow to modify ID register value after KVM_RUN on any vCPUs */
> +       if (kvm_vm_has_started(kvm) && new != old)
> +               return -EBUSY;

This path doesn't release the lock. I see that it gets fixed in a
future patch, but it might be good to fix it here...

> +
> +       WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
> +       mutex_unlock(&kvm->lock);
> +
> +       return 0;
> +}
> +
> +static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
> +{
> +       return modify_kvm_id_reg(kvm, id, val, 0);
> +}
> +
> +
> +/*
> + * KVM basically forces all vCPUs of the guest to have a uniform value for
> + * each ID register (, which means KVM_SET_ONE_REG for a vCPU affects all
> + * the vCPUs of the guest), and the id_regs[] of kvm_arch holds values
> + * of ID registers for the guest.  However, there is an exception for
> + * ID register fields corresponding to CPU features that can be
> + * configured per vCPU by KVM_ARM_VCPU_INIT, or etc (e.g. PMUv3, SVE, etc).
> + * For such fields, all vCPUs that have the feature will have a non-zero
> + * uniform value (, which can be updated by userspace), but the vCPUs that

Nit: uneven nesting of parentheses and commas :)


> + * don't have the feature will have zero for the fields.
> + * Values that @id_regs holds are for vCPUs that have such features.  So,
> + * to get the ID register value for a vCPU that doesn't have those features,
> + * the corresponding fields in id_regs[] needs to be cleared.
> + * A bitmask of the fields are provided by id_reg_info's vcpu_mask(), and
> + * __write_id_reg() and __read_id_reg() take care of those fields using
> + * the bitmask.
> + */
> +static int __write_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> +{
> +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> +       u64 mask = 0;
> +
> +       if (id_reg && id_reg->vcpu_mask)
> +               mask = id_reg->vcpu_mask(vcpu, id_reg);
> +
> +       /*
> +        * Update the ID register for the guest with @val, except for fields
> +        * that are set in the mask, which indicates fields for opt-in
> +        * features that are not configured for the vCPU.
> +        */
> +       return modify_kvm_id_reg(vcpu->kvm, id, val, mask);
> +}
> +
>  static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>  {
> -       u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
> +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> +       u64 val = read_kvm_id_reg(vcpu->kvm, id);
> +
> +       if (id_reg && id_reg->vcpu_mask)
> +               /* Clear fields for opt-in features that are not configured. */
> +               val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
>         switch (id) {
>         case SYS_ID_AA64PFR0_EL1:
> @@ -1222,12 +1389,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
>         return 0;
>  }
>
> -/*
> - * cpufeature ID register user accessors
> - *
> - * For now, these registers are immutable for userspace, so for set_id_reg()
> - * we don't allow the effective value to be changed.
> - */
> +/* cpufeature ID register user accessors */
>  static int __get_id_reg(const struct kvm_vcpu *vcpu,
>                         const struct sys_reg_desc *rd, void __user *uaddr,
>                         bool raz)
> @@ -1238,11 +1400,31 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
>         return reg_to_user(uaddr, &val, id);
>  }
>
> +/*
> + * Check if the given id indicates AArch32 ID register encoding.
> + */
> +static bool is_aarch32_id_reg(u32 id)
> +{
> +       u32 crm, op2;
> +
> +       if (!is_id_reg(id))
> +               return false;
> +
> +       crm = sys_reg_CRm(id);
> +       op2 = sys_reg_Op2(id);
> +       if (crm == 1 || crm == 2 || (crm == 3 && (op2 != 3 && op2 != 7)))

Consistent with the Arm ARM "Table D12-2 System instruction encodings
for non-Debug System register accesses"

> +               /* AArch32 ID register */
> +               return true;
> +
> +       return false;
> +}
> +
>  static int __set_id_reg(struct kvm_vcpu *vcpu,
>                         const struct sys_reg_desc *rd, void __user *uaddr,
>                         bool raz)
>  {
>         const u64 id = sys_reg_to_index(rd);
> +       u32 encoding = reg_to_encoding(rd);
>         int err;
>         u64 val;
>
> @@ -1250,11 +1432,28 @@ static int __set_id_reg(struct kvm_vcpu *vcpu,
>         if (err)
>                 return err;
>
> -       /* This is what we mean by invariant: you can't change it. */
> -       if (val != read_id_reg(vcpu, rd, raz))
> +       if (val == read_id_reg(vcpu, rd, raz))
> +               /* The value is same as the current value. Nothing to do. */
> +               return 0;
> +
> +       /*
> +        * Don't allow to modify the register's value if the register is raz,
> +        * or the reg doesn't have the id_reg_info.
> +        */
> +       if (raz || !GET_ID_REG_INFO(encoding))
>                 return -EINVAL;
>
> -       return 0;
> +       /*
> +        * Skip the validation of AArch32 ID registers if the system doesn't
> +        * 32bit EL0 (their value are UNKNOWN).
> +        */
> +       if (system_supports_32bit_el0() || !is_aarch32_id_reg(encoding)) {
> +               err = validate_id_reg(vcpu, encoding, val);
> +               if (err)
> +                       return err;
> +       }
> +
> +       return __write_id_reg(vcpu, encoding, val);
>  }
>
>  static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> @@ -2816,6 +3015,20 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
>         return write_demux_regids(uindices);
>  }
>
> +static void id_reg_info_init_all(void)
> +{
> +       int i;
> +       struct id_reg_info *id_reg;
> +
> +       for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) {
> +               id_reg = (struct id_reg_info *)id_reg_info_table[i];
> +               if (!id_reg)
> +                       continue;
> +
> +               id_reg_info_init(id_reg);
> +       }
> +}
> +
>  void kvm_sys_reg_table_init(void)
>  {
>         unsigned int i;
> @@ -2850,6 +3063,8 @@ void kvm_sys_reg_table_init(void)
>                         break;
>         /* Clear all higher bits. */
>         cache_levels &= (1 << (i*3))-1;
> +
> +       id_reg_info_init_all();
>  }
>
>  /*
> @@ -2862,11 +3077,12 @@ void set_default_id_regs(struct kvm *kvm)
>         u32 id;
>         const struct sys_reg_desc *rd;
>         u64 val;
> +       struct id_reg_info *idr;
>
>         for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
>                 rd = &sys_reg_descs[i];
>                 if (rd->access != access_id_reg)
> -                       /* Not ID register, or hidden/reserved ID register */
> +                       /* Not ID register or hidden/reserved ID register */
>                         continue;
>
>                 id = reg_to_encoding(rd);
> @@ -2874,7 +3090,8 @@ void set_default_id_regs(struct kvm *kvm)
>                         /* Shouldn't happen */
>                         continue;
>
> -               val = read_sanitised_ftr_reg(id);
> -               kvm->arch.id_regs[IDREG_IDX(id)] = val;
> +               idr = GET_ID_REG_INFO(id);
> +               val = idr ? idr->vcpu_limit_val : read_sanitised_ftr_reg(id);
> +               (void)write_kvm_id_reg(kvm, id, val);

Rather than ignoring the return value of write_kvm_id_reg(), wouldn't
it be better if set_default_id_regs were to propagate it back to
kvm_arch_init_vm in case there's a problem?

Thanks,
/fuad





>         }
>  }
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From miles.chen at mediatek.com  Mon Jan 24 08:29:27 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Tue, 25 Jan 2022 00:29:27 +0800
Subject: [PATCH 05/31] clk: mediatek: gate: Clean up included headers
In-Reply-To: <20220122091731.283592-6-wenst@chromium.org>
References: <20220122091731.283592-6-wenst@chromium.org>
Message-ID: <20220124162927.18795-1-miles.chen@mediatek.com>

> Some included headers aren't actually used anywhere, while other headers
> with the declaration of functions and structures aren't directly
> included.
> 
> Get rid of the unused ones, and add the ones that should be included
> directly.
> 
> On the header side, replace headers that are included purely for data
> structure definitions with forward declarations. This decreases the
> amount of preprocessing and compilation effort required for each
> inclusion.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>


From tabba at google.com  Mon Jan 24 08:51:16 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 16:51:16 +0000
Subject: [RFC PATCH v4 04/26] KVM: arm64: Make ID_AA64PFR0_EL1 writable
In-Reply-To: <20220106042708.2869332-5-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-5-reijiw@google.com>
Message-ID: <CA+EHjTxCWe2pFNhq+9gRUJ0RnjX4OcuV2WazDbProUaJE2ZTBg@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:28 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> This patch adds id_reg_info for ID_AA64PFR0_EL1 to make it writable by
> userspace.
>
> Return an error if userspace tries to set SVE/GIC field of the register
> to a value that conflicts with SVE/GIC configuration for the guest.
> SIMD/FP/SVE fields of the requested value are validated according to
> Arm ARM.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |   1 +
>  arch/arm64/include/asm/sysreg.h   |   2 +
>  arch/arm64/kvm/sys_regs.c         | 177 +++++++++++++++++++-----------
>  arch/arm64/kvm/vgic/vgic-init.c   |   5 +
>  4 files changed, 123 insertions(+), 62 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index c789a0137f58..4509f9e7472d 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -749,6 +749,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>                                 struct kvm_arm_copy_mte_tags *copy_tags);
>
>  void set_default_id_regs(struct kvm *kvm);
> +int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
>
>  /* Guest/host FPSIMD coordination helpers */
>  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> index 16b3f1a1d468..e26027817171 100644
> --- a/arch/arm64/include/asm/sysreg.h
> +++ b/arch/arm64/include/asm/sysreg.h
> @@ -798,6 +798,7 @@
>  #define ID_AA64PFR0_ASIMD_SUPPORTED    0x0
>  #define ID_AA64PFR0_ELx_64BIT_ONLY     0x1
>  #define ID_AA64PFR0_ELx_32BIT_64BIT    0x2
> +#define ID_AA64PFR0_GIC3               0x1
>
>  /* id_aa64pfr1 */
>  #define ID_AA64PFR1_MPAMFRAC_SHIFT     16
> @@ -1197,6 +1198,7 @@
>  #define ICH_VTR_TDS_MASK       (1 << ICH_VTR_TDS_SHIFT)
>
>  #define ARM64_FEATURE_FIELD_BITS       4
> +#define ARM64_FEATURE_FIELD_MASK       ((1ull << ARM64_FEATURE_FIELD_BITS) - 1)
>
>  /* Create a mask for the feature bits of the specified feature. */
>  #define ARM64_FEATURE_MASK(x)  (GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT))
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 971018288bee..1eb5c5fb614f 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -318,6 +318,92 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
>                 id_reg->init(id_reg);
>  }
>
> +static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> +                                   const struct id_reg_info *id_reg, u64 val)
> +{
> +       int fp, simd;
> +       unsigned int gic;
> +       bool vcpu_has_sve = vcpu_has_sve(vcpu);
> +       bool pfr0_has_sve = id_aa64pfr0_sve(val);
> +
> +       simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_ASIMD_SHIFT);
> +       fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_FP_SHIFT);
> +       if (simd != fp)

Why is this the case? Could you add a comment?

> +               return -EINVAL;
> +
> +       /* fp must be supported when sve is supported */
> +       if (pfr0_has_sve && (fp < 0))
> +               return -EINVAL;
> +
> +       /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
> +       if (vcpu_has_sve ^ pfr0_has_sve)
> +               return -EPERM;
> +
> +       if ((irqchip_in_kernel(vcpu->kvm) &&
> +            vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)) {
> +               gic = cpuid_feature_extract_unsigned_field(val,
> +                                                       ID_AA64PFR0_GIC_SHIFT);
> +               if (gic == 0)
> +                       return -EPERM;
> +
> +               if (gic > ID_AA64PFR0_GIC3)
> +                       return -E2BIG;
> +       } else {
> +               u64 mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> +               int err = arm64_check_features(id_reg->sys_reg, val & mask,
> +                                              id_reg->vcpu_limit_val & mask);
> +               if (err)
> +                       return err;
> +       }
> +
> +       return 0;
> +}
> +
> +static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
> +{
> +       u64 limit = id_reg->vcpu_limit_val;
> +       unsigned int gic;
> +
> +       limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
> +       if (!system_supports_sve())
> +               limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> +
> +       /*
> +        * The default is to expose CSV2 == 1 and CSV3 == 1 if the HW
> +        * isn't affected.  Userspace can override this as long as it
> +        * doesn't promise the impossible.
> +        */
> +       limit &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2) |
> +                  ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3));
> +
> +       if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
> +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), 1);
> +       if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED)
> +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), 1);
> +
> +       gic = cpuid_feature_extract_unsigned_field(limit, ID_AA64PFR0_GIC_SHIFT);
> +       if (gic > 1) {
> +               /* Limit to GICv3.0/4.0 */
> +               limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), ID_AA64PFR0_GIC3);
> +       }
> +       id_reg->vcpu_limit_val = limit;
> +}
> +
> +static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
> +                                        const struct id_reg_info *idr)
> +{
> +       return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> +}
> +
> +static struct id_reg_info id_aa64pfr0_el1_info = {
> +       .sys_reg = SYS_ID_AA64PFR0_EL1,
> +       .ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
> +       .init = init_id_aa64pfr0_el1_info,
> +       .validate = validate_id_aa64pfr0_el1,
> +       .vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
> +};
> +
>  /*
>   * An ID register that needs special handling to control the value for the
>   * guest must have its own id_reg_info in id_reg_info_table.
> @@ -326,7 +412,9 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
>   * validation, etc.)
>   */
>  #define        GET_ID_REG_INFO(id)     (id_reg_info_table[IDREG_IDX(id)])
> -static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
> +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
> +       [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
> +};
>
>  static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
>  {
> @@ -1161,12 +1249,12 @@ static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
>         return kvm->arch.id_regs[IDREG_IDX(id)];
>  }
>
> -static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> +static int __modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
>                              u64 preserve_mask)
>  {
>         u64 old, new;
>
> -       mutex_lock(&kvm->lock);
> +       lockdep_assert_held(&kvm->lock);
>
>         old = kvm->arch.id_regs[IDREG_IDX(id)];
>
> @@ -1179,11 +1267,21 @@ static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
>                 return -EBUSY;
>
>         WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
> -       mutex_unlock(&kvm->lock);
>
>         return 0;
>  }
>
> +static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> +                            u64 preserve_mask)
> +{
> +       int ret;
> +
> +       mutex_lock(&kvm->lock);
> +       ret = __modify_kvm_id_reg(kvm, id, val, preserve_mask);
> +       mutex_unlock(&kvm->lock);
> +
> +       return ret;
> +}

I think you probably wanted these changes to modify_kvm_id_reg() to go
into the previous patch rather than in this one.


>  static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
>  {
>         return modify_kvm_id_reg(kvm, id, val, 0);
> @@ -1233,20 +1331,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>                 val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
>
>         switch (id) {
> -       case SYS_ID_AA64PFR0_EL1:
> -               if (!vcpu_has_sve(vcpu))
> -                       val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
> -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2);
> -               val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2);
> -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3);
> -               val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
> -               if (irqchip_in_kernel(vcpu->kvm) &&
> -                   vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
> -                       val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> -                       val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), 1);
> -               }
> -               break;
>         case SYS_ID_AA64PFR1_EL1:
>                 if (!kvm_has_mte(vcpu->kvm))
>                         val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
> @@ -1347,48 +1431,6 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
>         return REG_HIDDEN;
>  }
>
> -static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> -                              const struct sys_reg_desc *rd,
> -                              const struct kvm_one_reg *reg, void __user *uaddr)
> -{
> -       const u64 id = sys_reg_to_index(rd);
> -       u8 csv2, csv3;
> -       int err;
> -       u64 val;
> -
> -       err = reg_from_user(&val, uaddr, id);
> -       if (err)
> -               return err;
> -
> -       /*
> -        * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
> -        * it doesn't promise more than what is actually provided (the
> -        * guest could otherwise be covered in ectoplasmic residue).
> -        */
> -       csv2 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV2_SHIFT);
> -       if (csv2 > 1 ||
> -           (csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED))
> -               return -EINVAL;
> -
> -       /* Same thing for CSV3 */
> -       csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT);
> -       if (csv3 > 1 ||
> -           (csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED))
> -               return -EINVAL;
> -
> -       /* We can only differ with CSV[23], and anything else is an error */
> -       val ^= read_id_reg(vcpu, rd, false);
> -       val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) |
> -                (0xFUL << ID_AA64PFR0_CSV3_SHIFT));
> -       if (val)
> -               return -EINVAL;
> -
> -       vcpu->kvm->arch.pfr0_csv2 = csv2;
> -       vcpu->kvm->arch.pfr0_csv3 = csv3 ;
> -
> -       return 0;
> -}
> -
>  /* cpufeature ID register user accessors */
>  static int __get_id_reg(const struct kvm_vcpu *vcpu,
>                         const struct sys_reg_desc *rd, void __user *uaddr,
> @@ -1702,8 +1744,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>
>         /* AArch64 ID registers */
>         /* CRm=4 */
> -       { SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = access_id_reg,
> -         .get_user = get_id_reg, .set_user = set_id_aa64pfr0_el1, },
> +       ID_SANITISED(ID_AA64PFR0_EL1),
>         ID_SANITISED(ID_AA64PFR1_EL1),
>         ID_UNALLOCATED(4,2),
>         ID_UNALLOCATED(4,3),
> @@ -3095,3 +3136,15 @@ void set_default_id_regs(struct kvm *kvm)
>                 (void)write_kvm_id_reg(kvm, id, val);
>         }
>  }
> +
> +/*
> + * Update the ID register's field with @fval for the guest.
> + * The caller is expected to hold the kvm->lock.
> + */
> +int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval)
> +{
> +       u64 val = ((u64)fval & ARM64_FEATURE_FIELD_MASK) << field_shift;
> +       u64 preserve_mask = ~(ARM64_FEATURE_FIELD_MASK << field_shift);
> +
> +       return __modify_kvm_id_reg(kvm, id, val, preserve_mask);
> +}

This seems to me like it should also be in the previous patch or a
separate patch.

> diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> index 0a06d0648970..28d9bf0e178c 100644
> --- a/arch/arm64/kvm/vgic/vgic-init.c
> +++ b/arch/arm64/kvm/vgic/vgic-init.c
> @@ -116,6 +116,11 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
>         else
>                 INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
>
> +       if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
> +               /* Set ID_AA64PFR0_EL1.GIC to 1 */
> +               (void)kvm_set_id_reg_feature(kvm, SYS_ID_AA64PFR0_EL1,
> +                                    ID_AA64PFR0_GIC3, ID_AA64PFR0_GIC_SHIFT);
> +

If this fails wouldn't it be better to return the error?

Thanks,
/fuad


>  out_unlock:
>         unlock_all_vcpus(kvm);
>         return ret;
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From zhou1615 at umn.edu  Mon Jan 24 08:52:06 2022
From: zhou1615 at umn.edu (Zhou Qingyang)
Date: Tue, 25 Jan 2022 00:52:06 +0800
Subject: [PATCH] clk: imx: Fix a NULL pointer dereference in
 imx_register_uart_clocks()
Message-ID: <20220124165206.55059-1-zhou1615@umn.edu>

In imx_register_uart_clocks(), the global variable imx_uart_clocks is
assigned by kcalloc() and there is a dereference of in the next for loop,
which could introduce a NULL pointer dereference on failure of kcalloc().

Fix this by adding a NULL check of imx_uart_clocks.

This bug was found by a static analyzer.

Builds with 'make allyesconfig' show no new warnings,
and our static analyzer no longer warns about this code.

Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
---
The analysis employs differential checking to identify inconsistent 
security operations (e.g., checks or kfrees) between two code paths 
and confirms that the inconsistent operations are not recovered in the
current function or the callers, so they constitute bugs. 

Note that, as a bug found by static analysis, it can be a false
positive or hard to trigger. Multiple researchers have cross-reviewed
the bug.

 drivers/clk/imx/clk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
index 7cc669934253..99249ab361d2 100644
--- a/drivers/clk/imx/clk.c
+++ b/drivers/clk/imx/clk.c
@@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
 		int i;
 
 		imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
+		if (!imx_uart_clocks)
+			return;
 
 		if (!of_stdout)
 			return;
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 09:00:54 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Mon, 24 Jan 2022 22:30:54 +0530
Subject: [PATCH v2 3/3] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <YevfmeGwmwLml+6b@jack.zhora.eu>
References: <20220120192438.25555-1-alim.akhtar@samsung.com>
 <CGME20220120193622epcas5p3a65c8424c6a01aed9a87f5ac2a89eb06@epcas5p3.samsung.com>
 <20220120192438.25555-4-alim.akhtar@samsung.com>
 <YevfmeGwmwLml+6b@jack.zhora.eu>
Message-ID: <048801d81143$f5585ec0$e0091c40$@samsung.com>

Thanks Andi for review

>-----Original Message-----
>From: Andi Shyti [mailto:andi at etezian.org]
>Sent: Saturday, January 22, 2022 4:13 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>
>Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
>devicetree at vger.kernel.org; linus.walleij at linaro.org; robh+dt at kernel.org;
>krzysztof.kozlowski at canonical.com; linux-samsung-soc at vger.kernel.org;
>pankaj.dubey at samsung.com; broonie at kernel.org; andi at etezian.org; linux-
>spi at vger.kernel.org; Aswani Reddy <aswani.reddy at samsung.com>; linux-
>fsd at tesla.com
>Subject: Re: [PATCH v2 3/3] arm64: dts: fsd: Add SPI device nodes
>
>Hi Alim and Aswani,
>
>On Fri, Jan 21, 2022 at 12:54:38AM +0530, Alim Akhtar wrote:
>> From: Aswani Reddy <aswani.reddy at samsung.com>
>>
>> Adds device tree node for SPI IPs
>>
>> Cc: linux-fsd at tesla.com
>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>
>Reviewed-by: Andi Shyti <andi at etezian.org>
>
>Please, also allow me another nit-commnent for the next patches:
>the tag section is in chronological order. I suppose that first Aswani
wrote the
>patch, then you sent it to the mailing list and at the end Krzysztof has
>reviewed it, this means that the right order is:
>
>  Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
>  Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
>  Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>
Sure, will update it in the next version of the patch set.

>Thank you,
>Andi



From tabba at google.com  Mon Jan 24 09:00:38 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 17:00:38 +0000
Subject: [RFC PATCH v4 14/26] KVM: arm64: Add consistency checking for
 frac fields of ID registers
In-Reply-To: <20220106042708.2869332-15-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-15-reijiw@google.com>
Message-ID: <CA+EHjTzQK2kswrW3LDf0ybz4estOCdafCvtRZHWwvTv2nH-UVw@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> Feature fractional field of an ID register cannot be simply validated
> at KVM_SET_ONE_REG because its validity depends on its (main) feature
> field value, which could be in a different ID register (and might be
> set later).
> Validate fractional fields at the first KVM_RUN instead.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h |   1 +
>  arch/arm64/kvm/arm.c              |   3 +
>  arch/arm64/kvm/sys_regs.c         | 116 +++++++++++++++++++++++++++++-
>  3 files changed, 117 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 4509f9e7472d..7b3f86bd6a6b 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -750,6 +750,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>
>  void set_default_id_regs(struct kvm *kvm);
>  int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
> +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu);
>
>  /* Guest/host FPSIMD coordination helpers */
>  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index 5f497a0af254..16fc2ce32069 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -596,6 +596,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>         if (!kvm_arm_vcpu_is_finalized(vcpu))
>                 return -EPERM;
>
> +       if (!kvm_vm_is_protected(kvm) && kvm_id_regs_consistency_check(vcpu))
> +               return -EPERM;
> +
>         vcpu->arch.has_run_once = true;
>
>         kvm_arm_vcpu_init_debug(vcpu);
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index ddbeefc3881c..6adb7b04620c 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -756,9 +756,6 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
>
>  static struct id_reg_info id_aa64pfr1_el1_info = {
>         .sys_reg = SYS_ID_AA64PFR1_EL1,
> -       .ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR1_RASFRAC) |
> -                      ARM64_FEATURE_MASK(ID_AA64PFR1_MPAMFRAC) |
> -                      ARM64_FEATURE_MASK(ID_AA64PFR1_CSV2FRAC),
>         .init = init_id_aa64pfr1_el1_info,
>         .validate = validate_id_aa64pfr1_el1,
>         .vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
> @@ -3434,10 +3431,109 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
>         return write_demux_regids(uindices);
>  }
>
> +/* ID register's fractional field information with its feature field. */
> +struct feature_frac {
> +       u32     id;
> +       u32     shift;
> +       u32     frac_id;
> +       u32     frac_shift;
> +       u8      frac_ftr_check;
> +};

frac_ftr_check doesn't seem to be used. Also, it would be easier to
read if the ordering of the fields match the ordering you initialize
them below.

> +
> +static struct feature_frac feature_frac_table[] = {
> +       {
> +               .frac_id = SYS_ID_AA64PFR1_EL1,
> +               .frac_shift = ID_AA64PFR1_RASFRAC_SHIFT,
> +               .id = SYS_ID_AA64PFR0_EL1,
> +               .shift = ID_AA64PFR0_RAS_SHIFT,
> +       },
> +       {
> +               .frac_id = SYS_ID_AA64PFR1_EL1,
> +               .frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT,
> +               .id = SYS_ID_AA64PFR0_EL1,
> +               .shift = ID_AA64PFR0_MPAM_SHIFT,
> +       },
> +       {
> +               .frac_id = SYS_ID_AA64PFR1_EL1,
> +               .frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT,
> +               .id = SYS_ID_AA64PFR0_EL1,
> +               .shift = ID_AA64PFR0_CSV2_SHIFT,
> +       },
> +};
> +
> +/*
> + * Return non-zero if the feature/fractional fields pair are not
> + * supported. Return zero otherwise.
> + * This function validates only the fractional feature field,
> + * and relies on the fact the feature field is validated before
> + * through arm64_check_features.
> + */
> +static int vcpu_id_reg_feature_frac_check(const struct kvm_vcpu *vcpu,
> +                                         const struct feature_frac *ftr_frac)
> +{
> +       const struct id_reg_info *id_reg;
> +       u32 id;
> +       u64 val, lim, mask;
> +
> +       /* Check if the feature field value is same as the limit */
> +       id = ftr_frac->id;
> +       id_reg = GET_ID_REG_INFO(id);
> +
> +       mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->shift;
> +       val = __read_id_reg(vcpu, id) & mask;
> +       lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
> +       lim &= mask;
> +
> +       if (val != lim)
> +               /*
> +                * The feature level is lower than the limit.
> +                * Any fractional version should be fine.
> +                */
> +               return 0;
> +
> +       /* Check the fractional feature field */
> +       id = ftr_frac->frac_id;
> +       id_reg = GET_ID_REG_INFO(id);
> +
> +       mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->frac_shift;
> +       val = __read_id_reg(vcpu, id) & mask;
> +       lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
> +       lim &= mask;
> +
> +       if (val == lim)
> +               /*
> +                * Both the feature and fractional fields are the same
> +                * as limit.
> +                */
> +               return 0;
> +
> +       return arm64_check_features(id, val, lim);
> +}
> +
> +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu)

Nit: considering that this is only checking the fractional fields,
should the function name reflect that?

> +{
> +       int i, err;
> +       const struct feature_frac *frac;
> +
> +       /*
> +        * Check ID registers' fractional fields, which aren't checked
> +        * at KVM_SET_ONE_REG.
> +        */
> +       for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) {
> +               frac = &feature_frac_table[i];
> +               err = vcpu_id_reg_feature_frac_check(vcpu, frac);
> +               if (err)
> +                       return err;
> +       }
> +       return 0;
> +}
> +
>  static void id_reg_info_init_all(void)
>  {
>         int i;
>         struct id_reg_info *id_reg;
> +       struct feature_frac *frac;
> +       u64 ftr_mask = ARM64_FEATURE_FIELD_MASK;
>
>         for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) {
>                 id_reg = (struct id_reg_info *)id_reg_info_table[i];
> @@ -3446,6 +3542,20 @@ static void id_reg_info_init_all(void)
>
>                 id_reg_info_init(id_reg);
>         }
> +
> +       /*
> +        * Update ignore_mask of ID registers based on fractional fields
> +        * information.  Any ID register that have fractional fields
> +        * is expected to have its own id_reg_info.
> +        */
> +       for (i = 0; i < ARRAY_SIZE(feature_frac_table); i++) {
> +               frac = &feature_frac_table[i];
> +               id_reg = GET_ID_REG_INFO(frac->frac_id);
> +               if (WARN_ON_ONCE(!id_reg))
> +                       continue;
> +
> +               id_reg->ignore_mask |= ftr_mask << frac->frac_shift;
> +       }
>  }

Thanks,
/fuad


>
>  void kvm_sys_reg_table_init(void)
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From zhou1615 at umn.edu  Mon Jan 24 09:07:31 2022
From: zhou1615 at umn.edu (Zhou Qingyang)
Date: Tue, 25 Jan 2022 01:07:31 +0800
Subject: [PATCH] media: mtk-vcodec: Fix a NULL pointer dereference in
 mtk_vcodec_fw_scp_init()
Message-ID: <20220124170731.59240-1-zhou1615@umn.edu>

In mtk_vcodec_fw_scp_init(), devm_kzalloc() is assigned to fw and there is
a dereference of it right after that, which could lead to NULL pointer
dereference on failure of devm_kzalloc().

Fix this bug by adding a NULL check of fw.

This bug was found by a static analyzer.

Builds with 'make allyesconfig' show no new warnings,
and our static analyzer no longer warns about this code.

Fixes: 46233e91fa24 ("media: mtk-vcodec: move firmware implementations into their own files")
Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
---
The analysis employs differential checking to identify inconsistent 
security operations (e.g., checks or kfrees) between two code paths 
and confirms that the inconsistent operations are not recovered in the
current function or the callers, so they constitute bugs. 

Note that, as a bug found by static analysis, it can be a false
positive or hard to trigger. Multiple researchers have cross-reviewed
the bug.

 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
index d8e66b645bd8..aa36bee51d01 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
@@ -65,6 +65,9 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
 	}
 
 	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
+
 	fw->type = SCP;
 	fw->ops = &mtk_vcodec_rproc_msg;
 	fw->scp = scp;
-- 
2.25.1



From linux at armlinux.org.uk  Mon Jan 24 09:06:59 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 24 Jan 2022 17:06:59 +0000
Subject: [RFC V1 09/31] arm/mm: Enable ARCH_HAS_VM_GET_PAGE_PROT
In-Reply-To: <1643029028-12710-10-git-send-email-anshuman.khandual@arm.com>
References: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
 <1643029028-12710-10-git-send-email-anshuman.khandual@arm.com>
Message-ID: <Ye7cs4fNMGPZIV2U@shell.armlinux.org.uk>

On Mon, Jan 24, 2022 at 06:26:46PM +0530, Anshuman Khandual wrote:
> This defines and exports a platform specific custom vm_get_page_prot() via
> subscribing ARCH_HAS_VM_GET_PAGE_PROT. Subsequently all __SXXX and __PXXX
> macros can be dropped which are no longer needed.

What is the fundamental advantage of this approach?

> 
> Cc: Russell King <linux at armlinux.org.uk>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm/Kconfig               |  1 +
>  arch/arm/include/asm/pgtable.h | 18 ------------
>  arch/arm/mm/mmu.c              | 50 ++++++++++++++++++++++++++++++----
>  3 files changed, 45 insertions(+), 24 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index fabe39169b12..c12362d20c44 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -23,6 +23,7 @@ config ARM
>  	select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB || !MMU
>  	select ARCH_HAS_TEARDOWN_DMA_OPS if MMU
>  	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
> +	select ARCH_HAS_VM_GET_PAGE_PROT
>  	select ARCH_HAVE_CUSTOM_GPIO_H
>  	select ARCH_HAVE_NMI_SAFE_CMPXCHG if CPU_V7 || CPU_V7M || CPU_V6K
>  	select ARCH_HAS_GCOV_PROFILE_ALL
> diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
> index cd1f84bb40ae..ec062dd6082a 100644
> --- a/arch/arm/include/asm/pgtable.h
> +++ b/arch/arm/include/asm/pgtable.h
> @@ -137,24 +137,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
>   *  2) If we could do execute protection, then read is implied
>   *  3) write implies read permissions
>   */
> -#define __P000  __PAGE_NONE
> -#define __P001  __PAGE_READONLY
> -#define __P010  __PAGE_COPY
> -#define __P011  __PAGE_COPY
> -#define __P100  __PAGE_READONLY_EXEC
> -#define __P101  __PAGE_READONLY_EXEC
> -#define __P110  __PAGE_COPY_EXEC
> -#define __P111  __PAGE_COPY_EXEC
> -
> -#define __S000  __PAGE_NONE
> -#define __S001  __PAGE_READONLY
> -#define __S010  __PAGE_SHARED
> -#define __S011  __PAGE_SHARED
> -#define __S100  __PAGE_READONLY_EXEC
> -#define __S101  __PAGE_READONLY_EXEC
> -#define __S110  __PAGE_SHARED_EXEC
> -#define __S111  __PAGE_SHARED_EXEC
> -
>  #ifndef __ASSEMBLY__
>  /*
>   * ZERO_PAGE is a global shared page that is always zero: used
> diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
> index 274e4f73fd33..3007d07bc0e7 100644
> --- a/arch/arm/mm/mmu.c
> +++ b/arch/arm/mm/mmu.c
> @@ -403,6 +403,8 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
>  	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
>  }
>  
> +static pteval_t user_pgprot;
> +
>  /*
>   * Adjust the PMD section entries according to the CPU in use.
>   */
> @@ -410,7 +412,7 @@ static void __init build_mem_type_table(void)
>  {
>  	struct cachepolicy *cp;
>  	unsigned int cr = get_cr();
> -	pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
> +	pteval_t kern_pgprot, vecs_pgprot;
>  	int cpu_arch = cpu_architecture();
>  	int i;
>  
> @@ -627,11 +629,6 @@ static void __init build_mem_type_table(void)
>  	user_pgprot |= PTE_EXT_PXN;
>  #endif
>  
> -	for (i = 0; i < 16; i++) {
> -		pteval_t v = pgprot_val(protection_map[i]);
> -		protection_map[i] = __pgprot(v | user_pgprot);
> -	}
> -
>  	mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
>  	mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
>  
> @@ -670,6 +667,47 @@ static void __init build_mem_type_table(void)
>  	}
>  }
>  
> +pgprot_t vm_get_page_prot(unsigned long vm_flags)
> +{
> +	switch (vm_flags & (VM_READ | VM_WRITE | VM_EXEC | VM_SHARED)) {
> +	case VM_NONE:
> +		return __pgprot(pgprot_val(__PAGE_NONE) | user_pgprot);
> +	case VM_READ:
> +		return __pgprot(pgprot_val(__PAGE_READONLY) | user_pgprot);
> +	case VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_COPY) | user_pgprot);
> +	case VM_READ | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_COPY) | user_pgprot);
> +	case VM_EXEC:
> +		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
> +	case VM_EXEC | VM_READ:
> +		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
> +	case VM_EXEC | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_COPY_EXEC) | user_pgprot);
> +	case VM_EXEC | VM_READ | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_COPY_EXEC) | user_pgprot);
> +	case VM_SHARED:
> +		return __pgprot(pgprot_val(__PAGE_NONE) | user_pgprot);
> +	case VM_SHARED | VM_READ:
> +		return __pgprot(pgprot_val(__PAGE_READONLY) | user_pgprot);
> +	case VM_SHARED | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_SHARED) | user_pgprot);
> +	case VM_SHARED | VM_READ | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_SHARED) | user_pgprot);
> +	case VM_SHARED | VM_EXEC:
> +		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
> +	case VM_SHARED | VM_EXEC | VM_READ:
> +		return __pgprot(pgprot_val(__PAGE_READONLY_EXEC) | user_pgprot);
> +	case VM_SHARED | VM_EXEC | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_SHARED_EXEC) | user_pgprot);
> +	case VM_SHARED | VM_EXEC | VM_READ | VM_WRITE:
> +		return __pgprot(pgprot_val(__PAGE_SHARED_EXEC) | user_pgprot);
> +	default:
> +		BUILD_BUG();
> +	}
> +}
> +EXPORT_SYMBOL(vm_get_page_prot);
> +
>  #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
>  pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
>  			      unsigned long size, pgprot_t vma_prot)
> -- 
> 2.25.1
> 
> 

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From f.fainelli at gmail.com  Mon Jan 24 09:09:41 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Mon, 24 Jan 2022 09:09:41 -0800
Subject: [PATCH] net: dsa|ethernet: use bool values to pass bool param of
 phy_init_eee
In-Reply-To: <20220123152241.1480-1-jszhang@kernel.org>
References: <20220123152241.1480-1-jszhang@kernel.org>
Message-ID: <562d9627-fe34-fbef-e908-d06a1cdd7cb4@gmail.com>



On 1/23/2022 7:22 AM, Jisheng Zhang wrote:
> The 2nd param of phy_init_eee(): clk_stop_enable is a bool param, use
> true or false instead of 1/0.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>

Nit: for future changes, if your patch spans multiple 
subsystems/directories, just go with the top-most subject prefix, for 
instance here "net: " would have been sufficient. Thanks!
-- 
Florian


From zhou1615 at umn.edu  Mon Jan 24 09:15:03 2022
From: zhou1615 at umn.edu (Zhou Qingyang)
Date: Tue, 25 Jan 2022 01:15:03 +0800
Subject: [PATCH] media: mtk-vcodec: media: mtk-vcodec: Fix a NULL pointer
 dereference in mtk_vcodec_fw_vpu_init()
Message-ID: <20220124171503.61098-1-zhou1615@umn.edu>

In mtk_vcodec_fw_vpu_init(), devm_kzalloc() is assigned to fw and there is
a dereference of it right after that, which could lead to NULL pointer
dereference on failure of devm_kzalloc().

Fix this bug by adding a NULL check of fw.

This bug was found by a static analyzer.

Builds with 'make allyesconfig' show no new warnings,
and our static analyzer no longer warns about this code.

Fixes: 46233e91fa24 ("media: mtk-vcodec: move firmware implementations into their own files")
Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
---
The analysis employs differential checking to identify inconsistent 
security operations (e.g., checks or kfrees) between two code paths 
and confirms that the inconsistent operations are not recovered in the
current function or the callers, so they constitute bugs. 

Note that, as a bug found by static analysis, it can be a false
positive or hard to trigger. Multiple researchers have cross-reviewed
the bug.

 drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
index cd27f637dbe7..33ae88a9f9da 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
@@ -102,6 +102,9 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
 	vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id);
 
 	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
+
 	fw->type = VPU;
 	fw->ops = &mtk_vcodec_vpu_msg;
 	fw->pdev = fw_pdev;
-- 
2.25.1



From tabba at google.com  Mon Jan 24 09:16:55 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 17:16:55 +0000
Subject: [RFC PATCH v4 20/26] KVM: arm64: Trap disabled features of
 ID_AA64PFR0_EL1
In-Reply-To: <20220106042708.2869332-21-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-21-reijiw@google.com>
Message-ID: <CA+EHjTy4L37G89orJ+cPTTZdFUehxNSMy0Pd36PW41JKVB0ohA@mail.gmail.com>

Hi Reiji,

On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> Add feature_config_ctrl for RAS and AMU, which are indicated in
> ID_AA64PFR0_EL1, to program configuration registers to trap
> guest's using those features when they are not exposed to the guest.
>
> Introduce trap_ras_regs() to change a behavior of guest's access to
> the registers, which is currently raz/wi, depending on the feature's
> availability for the guest (and inject undefined instruction
> exception when guest's RAS register access are trapped and RAS is
> not exposed to the guest).  In order to keep the current visibility
> of the RAS registers from userspace (always visible), a visibility
> function for RAS registers is not added.
>
> No code is added for AMU's access/visibility handler because the
> current code already injects the exception for Guest's AMU register
> access unconditionally because AMU is never exposed to the guest.

I think it might be code to trap it anyway, in case AMU guest support
is added in the future.

>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 90 +++++++++++++++++++++++++++++++++++----
>  1 file changed, 82 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 33893a501475..015d67092d5e 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -304,6 +304,63 @@ struct feature_config_ctrl {
>         void    (*trap_activate)(struct kvm_vcpu *vcpu);
>  };
>
> +enum vcpu_config_reg {
> +       VCPU_HCR_EL2 = 1,
> +       VCPU_MDCR_EL2,
> +       VCPU_CPTR_EL2,
> +};
> +
> +static void feature_trap_activate(struct kvm_vcpu *vcpu,
> +                                 enum vcpu_config_reg cfg_reg,
> +                                 u64 cfg_set, u64 cfg_clear)
> +{
> +       u64 *reg_ptr, reg_val;
> +
> +       switch (cfg_reg) {
> +       case VCPU_HCR_EL2:
> +               reg_ptr = &vcpu->arch.hcr_el2;
> +               break;
> +       case VCPU_MDCR_EL2:
> +               reg_ptr = &vcpu->arch.mdcr_el2;
> +               break;
> +       case VCPU_CPTR_EL2:
> +               reg_ptr = &vcpu->arch.cptr_el2;
> +               break;
> +       }
> +
> +       /* Clear/Set fields that are indicated by cfg_clear/cfg_set. */
> +       reg_val = (*reg_ptr & ~cfg_clear);
> +       reg_val |= cfg_set;
> +       *reg_ptr = reg_val;
> +}
> +
> +static void feature_ras_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TERR | HCR_TEA, HCR_FIEN);

Covers all the flags for ras.

> +}
> +
> +static void feature_amu_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_CPTR_EL2, CPTR_EL2_TAM, 0);

Covers the CPTR flags for AMU, but as you mentioned, does not
explicitly clear HCR_AMVOFFEN.

Cheers,
/fuad


> +}
> +
> +/* For ID_AA64PFR0_EL1 */
> +static struct feature_config_ctrl ftr_ctrl_ras = {
> +       .ftr_reg = SYS_ID_AA64PFR0_EL1,
> +       .ftr_shift = ID_AA64PFR0_RAS_SHIFT,
> +       .ftr_min = ID_AA64PFR0_RAS_V1,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_ras_trap_activate,
> +};
> +
> +static struct feature_config_ctrl ftr_ctrl_amu = {
> +       .ftr_reg = SYS_ID_AA64PFR0_EL1,
> +       .ftr_shift = ID_AA64PFR0_AMU_SHIFT,
> +       .ftr_min = ID_AA64PFR0_AMU,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_amu_trap_activate,
> +};
> +
>  struct id_reg_info {
>         u32     sys_reg;        /* Register ID */
>         u64     sys_val;        /* Sanitized system value */
> @@ -778,6 +835,11 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
>         .init = init_id_aa64pfr0_el1_info,
>         .validate = validate_id_aa64pfr0_el1,
>         .vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
> +       .trap_features = &(const struct feature_config_ctrl *[]) {
> +               &ftr_ctrl_ras,
> +               &ftr_ctrl_amu,
> +               NULL,
> +       },
>  };
>
>  static struct id_reg_info id_aa64pfr1_el1_info = {
> @@ -901,6 +963,18 @@ static inline bool vcpu_feature_is_available(struct kvm_vcpu *vcpu,
>         return feature_avail(ctrl, val);
>  }
>
> +static bool trap_ras_regs(struct kvm_vcpu *vcpu,
> +                         struct sys_reg_params *p,
> +                         const struct sys_reg_desc *r)
> +{
> +       if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_ras)) {
> +               kvm_inject_undefined(vcpu);
> +               return false;
> +       }
> +
> +       return trap_raz_wi(vcpu, p, r);
> +}
> +
>  /*
>   * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
>   * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
> @@ -2265,14 +2339,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
>         { SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
>         { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
>
> -       { SYS_DESC(SYS_ERRIDR_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERRSELR_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXFR_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXCTLR_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXSTATUS_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXADDR_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXMISC0_EL1), trap_raz_wi },
> -       { SYS_DESC(SYS_ERXMISC1_EL1), trap_raz_wi },
> +       { SYS_DESC(SYS_ERRIDR_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERRSELR_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXFR_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXCTLR_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXSTATUS_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXADDR_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXMISC0_EL1), trap_ras_regs },
> +       { SYS_DESC(SYS_ERXMISC1_EL1), trap_ras_regs },
>
>         MTE_REG(TFSR_EL1),
>         MTE_REG(TFSRE0_EL1),
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From broonie at kernel.org  Mon Jan 24 09:17:48 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 17:17:48 +0000
Subject: [PATCH] kselftest/arm64: Remove local ARRAY_SIZE() definitions
Message-ID: <20220124171748.2195875-1-broonie@kernel.org>

An ARRAY_SIZE() has been added to kselftest.h so remove the local versions
in some of the arm64 selftests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/syscall-abi.c | 1 -
 tools/testing/selftests/arm64/fp/sve-ptrace.c   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index d8eeeafb50dc..1e13b7523918 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,7 +18,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
 extern void do_syscall(int sve_vl);
diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index af798b9d232c..90ba1d6a6781 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -21,8 +21,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
 #ifndef NT_ARM_SVE
 #define NT_ARM_SVE 0x405
-- 
2.30.2



From tabba at google.com  Mon Jan 24 09:19:57 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 17:19:57 +0000
Subject: [RFC PATCH v4 22/26] KVM: arm64: Trap disabled features of
 ID_AA64DFR0_EL1
In-Reply-To: <20220106042708.2869332-23-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-23-reijiw@google.com>
Message-ID: <CA+EHjTyimL8nuE0gH8B3V-MzoA9rz+n3KazqFxMtdJKgjefAag@mail.gmail.com>

.Hi Reiji,

On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> Add feature_config_ctrl for PMUv3, PMS and TraceFilt, which are
> indicated in ID_AA64DFR0_EL1, to program configuration registers
> to trap guest's using those features when they are not exposed to
> the guest.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 47 +++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 72e745c5a9c2..229671ec3abd 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -349,6 +349,22 @@ static void feature_mte_trap_activate(struct kvm_vcpu *vcpu)
>         feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TID5, HCR_DCT | HCR_ATA);
>  }
>
> +static void feature_pmuv3_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPM, 0);

I think that for full coverage it might be good to include setting
MDCR_EL2_TPMCR, and clearing MDCR_EL2_HPME | MDCR_EL2_MTPME |
MDCR_EL2_HPMN_MASK, even if redundant at this point.

> +}
> +
> +static void feature_pms_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPMS,
> +                             MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
> +}
> +
> +static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
> +}
> +
>  /* For ID_AA64PFR0_EL1 */
>  static struct feature_config_ctrl ftr_ctrl_ras = {
>         .ftr_reg = SYS_ID_AA64PFR0_EL1,
> @@ -375,6 +391,31 @@ static struct feature_config_ctrl ftr_ctrl_mte = {
>         .trap_activate = feature_mte_trap_activate,
>  };
>
> +/* For ID_AA64DFR0_EL1 */
> +static struct feature_config_ctrl ftr_ctrl_pmuv3 = {
> +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> +       .ftr_shift = ID_AA64DFR0_PMUVER_SHIFT,
> +       .ftr_min = ID_AA64DFR0_PMUVER_8_0,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_pmuv3_trap_activate,
> +};
> +
> +static struct feature_config_ctrl ftr_ctrl_pms = {
> +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> +       .ftr_shift = ID_AA64DFR0_PMSVER_SHIFT,
> +       .ftr_min = ID_AA64DFR0_PMSVER_8_2,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_pms_trap_activate,
> +};
> +
> +static struct feature_config_ctrl ftr_ctrl_tracefilt = {
> +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> +       .ftr_shift = ID_AA64DFR0_TRACE_FILT_SHIFT,
> +       .ftr_min = 1,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_tracefilt_trap_activate,
> +};

I think you might be missing trace, ID_AA64DFR0_TRACEVER -> CPTR_EL2_TTA.

Cheers,
/fuad


> +
>  struct id_reg_info {
>         u32     sys_reg;        /* Register ID */
>         u64     sys_val;        /* Sanitized system value */
> @@ -898,6 +939,12 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
>         .init = init_id_aa64dfr0_el1_info,
>         .validate = validate_id_aa64dfr0_el1,
>         .vcpu_mask = vcpu_mask_id_aa64dfr0_el1,
> +       .trap_features = &(const struct feature_config_ctrl *[]) {
> +               &ftr_ctrl_pmuv3,
> +               &ftr_ctrl_pms,
> +               &ftr_ctrl_tracefilt,
> +               NULL,
> +       },
>  };
>
>  static struct id_reg_info id_dfr0_el1_info = {
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From james.clark at arm.com  Mon Jan 24 09:24:25 2022
From: james.clark at arm.com (James Clark)
Date: Mon, 24 Jan 2022 17:24:25 +0000
Subject: [PATCH] perf arm-spe: Use SPE data source for neoverse cores
In-Reply-To: <20220121182456.13538-1-alisaidi@amazon.com>
References: <20220121182456.13538-1-alisaidi@amazon.com>
Message-ID: <0ba26f30-6978-36ad-f7d0-7b8465648e54@arm.com>



On 21/01/2022 18:24, Ali Saidi wrote:
> When synthesizing data from SPE, augment the type with source information
> for Arm Neoverse cores. The field is IMPLDEF but the Neoverse cores all use
> the same encoding. I can't find encoding information for any other SPE
> implementations to unify their choices with Arm's thus that is left for future
> work.
> 
> This changes enables the expected behavior of perf c2c on a system with SPE where
> lines that are shared among multiple cores show up in perf c2c output. 
> 
> Signed-off-by: Ali Saidi <alisaidi at amazon.com> 
> ---
>  .../util/arm-spe-decoder/arm-spe-decoder.c    |  1 +
>  .../util/arm-spe-decoder/arm-spe-decoder.h    | 12 +++++
>  tools/perf/util/arm-spe.c                     | 48 ++++++++++++++-----
>  3 files changed, 49 insertions(+), 12 deletions(-)
> 
[...]
> +static u64 arm_spe__synth_data_source(const struct arm_spe_record *record, u64 midr)
>  {
>  	union perf_mem_data_src	data_src = { 0 };
> +	bool is_neoverse = is_midr_in_range(midr, neoverse_spe);
>  
>  	if (record->op == ARM_SPE_LD)
>  		data_src.mem_op = PERF_MEM_OP_LOAD;
> @@ -409,19 +418,30 @@ static u64 arm_spe__synth_data_source(const struct arm_spe_record *record)
>  		data_src.mem_op = PERF_MEM_OP_STORE;
>  
>  	if (record->type & (ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS)) {
> -		data_src.mem_lvl = PERF_MEM_LVL_L3;
> +		if (is_neoverse && record->source == ARM_SPE_NV_DRAM) {
> +			data_src.mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT;
> +		} else if (is_neoverse && record->source == ARM_SPE_NV_PEER_CLSTR) {
> +			data_src.mem_snoop = PERF_MEM_SNOOP_HITM;

I'm not following how LLC_ACCESS | LLC_MISS ends up as HITM in this case (ARM_SPE_NV_PEER_CLSTR)?
I thought there was no way to determine a HITM from SPE. Wouldn't one of the other values
like PERF_MEM_SNOOP_MISS be more accurate?

> +			data_src.mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;

This one also adds PERF_MEM_LVL_HIT even though the check of "if (record->type & ARM_SPE_LLC_MISS)"
hasn't happened yet. Maybe some comments would make it a bit clearer, but at the moment it's
not obvious how the result is derived because there are some things that don't add up like
ARM_SPE_LLC_MISS == PERF_MEM_LVL_HIT.

> +		} else {
> +			data_src.mem_lvl = PERF_MEM_LVL_L3;>  
> -		if (record->type & ARM_SPE_LLC_MISS)
> -			data_src.mem_lvl |= PERF_MEM_LVL_MISS;
> -		else
> -			data_src.mem_lvl |= PERF_MEM_LVL_HIT;
> +			if (record->type & ARM_SPE_LLC_MISS)
> +				data_src.mem_lvl |= PERF_MEM_LVL_MISS;
> +			else
> +				data_src.mem_lvl |= PERF_MEM_LVL_HIT;
> +		}
>  	} else if (record->type & (ARM_SPE_L1D_ACCESS | ARM_SPE_L1D_MISS)) {
> -		data_src.mem_lvl = PERF_MEM_LVL_L1;
> +		if (is_neoverse && record->source == ARM_SPE_NV_L2) {
> +			data_src.mem_lvl = PERF_MEM_LVL_L2 | PERF_MEM_LVL_HIT;
> +		} else {
> +			data_src.mem_lvl = PERF_MEM_LVL_L1;
>  
> -		if (record->type & ARM_SPE_L1D_MISS)
> -			data_src.mem_lvl |= PERF_MEM_LVL_MISS;
> -		else
> -			data_src.mem_lvl |= PERF_MEM_LVL_HIT;
> +			if (record->type & ARM_SPE_L1D_MISS)
> +				data_src.mem_lvl |= PERF_MEM_LVL_MISS;
> +			else
> +				data_src.mem_lvl |= PERF_MEM_LVL_HIT;
> +		}
>  	}
>  
>  	if (record->type & ARM_SPE_REMOTE_ACCESS)
> @@ -446,7 +466,7 @@ static int arm_spe_sample(struct arm_spe_queue *speq)
>  	u64 data_src;
>  	int err;
>  
> -	data_src = arm_spe__synth_data_source(record);
> +	data_src = arm_spe__synth_data_source(record, spe->midr);
>  
>  	if (spe->sample_flc) {
>  		if (record->type & ARM_SPE_L1D_MISS) {
> @@ -796,6 +816,10 @@ static int arm_spe_process_event(struct perf_session *session,
>  	u64 timestamp;
>  	struct arm_spe *spe = container_of(session->auxtrace,
>  			struct arm_spe, auxtrace);
> +	const char *cpuid = perf_env__cpuid(session->evlist->env);
> +	u64 midr = strtol(cpuid, NULL, 16);
> +
> +	spe->midr = midr;
>  
>  	if (dump_trace)
>  		return 0;
> 


From tabba at google.com  Mon Jan 24 09:37:33 2022
From: tabba at google.com (Fuad Tabba)
Date: Mon, 24 Jan 2022 17:37:33 +0000
Subject: [RFC PATCH v4 23/26] KVM: arm64: Trap disabled features of
 ID_AA64MMFR1_EL1
In-Reply-To: <20220106042708.2869332-24-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-24-reijiw@google.com>
Message-ID: <CA+EHjTxYqPvyUz96hoJWe43raST1X7oKhdR7PeZDuwuuD9QcYQ@mail.gmail.com>

Hi Reiji,

The series might be missing an entry for ID_AA64MMFR0_EL1, Debug
Communications Channel registers, ID_AA64MMFR0_FGT -> MDCR_EL2_TDCC.

Cheers,
/fuad


On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> Add feature_config_ctrl for LORegions, which is indicated in
> ID_AA64MMFR1_EL1, to program configuration register to trap
> guest's using the feature when it is not exposed to the guest.
>
> Change trap_loregion() to use vcpu_feature_is_available()
> to simplify checking of the feature's availability.
>
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
>  1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index 229671ec3abd..f8a5ee927ecf 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -365,6 +365,11 @@ static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
>         feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
>  }
>
> +static void feature_lor_trap_activate(struct kvm_vcpu *vcpu)
> +{
> +       feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TLOR, 0);
> +}
> +
>  /* For ID_AA64PFR0_EL1 */
>  static struct feature_config_ctrl ftr_ctrl_ras = {
>         .ftr_reg = SYS_ID_AA64PFR0_EL1,
> @@ -416,6 +421,15 @@ static struct feature_config_ctrl ftr_ctrl_tracefilt = {
>         .trap_activate = feature_tracefilt_trap_activate,
>  };
>
> +/* For ID_AA64MMFR1_EL1 */
> +static struct feature_config_ctrl ftr_ctrl_lor = {
> +       .ftr_reg = SYS_ID_AA64MMFR1_EL1,
> +       .ftr_shift = ID_AA64MMFR1_LOR_SHIFT,
> +       .ftr_min = 1,
> +       .ftr_signed = FTR_UNSIGNED,
> +       .trap_activate = feature_lor_trap_activate,
> +};
> +
>  struct id_reg_info {
>         u32     sys_reg;        /* Register ID */
>         u64     sys_val;        /* Sanitized system value */
> @@ -947,6 +961,14 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
>         },
>  };
>
> +static struct id_reg_info id_aa64mmfr1_el1_info = {
> +       .sys_reg = SYS_ID_AA64MMFR1_EL1,
> +       .trap_features = &(const struct feature_config_ctrl *[]) {
> +               &ftr_ctrl_lor,
> +               NULL,
> +       },
> +};
> +
>  static struct id_reg_info id_dfr0_el1_info = {
>         .sys_reg = SYS_ID_DFR0_EL1,
>         .init = init_id_dfr0_el1_info,
> @@ -976,6 +998,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
>         [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
>         [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
>         [IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info,
> +       [IDREG_IDX(SYS_ID_AA64MMFR1_EL1)] = &id_aa64mmfr1_el1_info,
>  };
>
>  static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> @@ -1050,10 +1073,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
>                           struct sys_reg_params *p,
>                           const struct sys_reg_desc *r)
>  {
> -       u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
>         u32 sr = reg_to_encoding(r);
>
> -       if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> +       if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_lor)) {
>                 kvm_inject_undefined(vcpu);
>                 return false;
>         }
> --
> 2.34.1.448.ga2b2bfdf31-goog
>
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From ardb at kernel.org  Mon Jan 24 09:47:12 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:12 +0100
Subject: [PATCH v5 00/32] ARM vmap'ed and IRQ stacks roundup
Message-ID: <20220124174744.1054712-1-ardb@kernel.org>

This v5 series is a combined followup to

- IRQ stacks support for v7 SMP systems [0],
- vmap'ed stacks support for v7 SMP systems[1],
- extending support for both IRQ stacks and vmap'ed stacks for all
  remaining configurations, including v6/v7 SMP multiplatform kernels
  and uniprocessor configurations including v7-M [2]

[0] https://lore.kernel.org/linux-arm-kernel/20211115084732.3704393-1-ardb at kernel.org/
[1] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-1-ardb at kernel.org/
[2] https://lore.kernel.org/linux-arm-kernel/20211206164659.1495084-1-ardb at kernel.org/

This work was queued up in the ARM tree for a while, but due to problems
with the vmap'ed stacks code, which was difficult to revert in
isolation, the whole stack was dropped again.

In order to prevent similar problems from occurring this time around,
the series was reorganized so that the vmap'ed stacks changes appear at
the very end, which also results in a more natural progression of the
changes.

Changes since v4:
- incorporate fixups to avoid build failures on Clang related to
  literals in subsections,
- switch from the ID map to swapper_pg_dir as early as possible when
  onlining a CPU on !LPAE, to ensure that the stack is mapped,
- use SMP_ON_UP patching to elide HWCAP_TLS tests on SMP+v6,
- clean up __switch_to() for Thumb2 a bit more,
- add patch to make the vmalloc_seq counter SMP safe,
- use enter_lazy_tlb() hook on !LPAE to ensure that the active_mm used
  by a kernel thread has a mapping for its vmap'ed stack,

Code can be found under the arm-vmap-stacks-v5 tag at
git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git

Cc: Russell King <linux at armlinux.org.uk>
Cc: Nicolas Pitre <nico at fluxnic.net>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Kees Cook <keescook at chromium.org>
Cc: Keith Packard <keithpac at amazon.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Tony Lindgren <tony at atomide.com>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Vladimir Murzin <vladimir.murzin at arm.com>
Cc: Jesse Taube <mr.bossman075 at gmail.com>

Ard Biesheuvel (26):
  ARM: riscpc: drop support for IOMD_IRQREQC/IOMD_IRQREQD IRQ groups
  ARM: decompressor: disable stack protector
  ARM: stackprotector: prefer compiler for TLS based per-task protector
  ARM: entry: preserve thread_info pointer in switch_to
  ARM: module: implement support for PC-relative group relocations
  ARM: assembler: add optimized ldr/str macros to load variables from
    memory
  ARM: percpu: add SMP_ON_UP support
  ARM: use TLS register for 'current' on !SMP as well
  ARM: smp: defer TPIDRURO update for SMP v6 configurations too
  ARM: implement THREAD_INFO_IN_TASK for uniprocessor systems
  ARM: assembler: introduce bl_r macro
  ARM: unwind: support unwinding across multiple stacks
  ARM: export dump_mem() to other objects
  ARM: unwind: dump exception stack from calling frame
  ARM: backtrace-clang: avoid crash on bogus frame pointer
  ARM: implement IRQ stacks
  ARM: call_with_stack: add unwind support
  ARM: run softirqs on the per-CPU IRQ stack
  ARM: memcpy: use frame pointer as unwind anchor
  ARM: memmove: use frame pointer as unwind anchor
  ARM: memset: clean up unwind annotations
  ARM: unwind: disregard unwind info before stack frame is set up
  ARM: entry: rework stack realignment code in svc_entry
  ARM: switch_to: clean up Thumb2 code path
  ARM: mm: prepare vmalloc_seq handling for use under SMP
  ARM: implement support for vmap'ed stacks

Arnd Bergmann (5):
  ARM: riscpc: use GENERIC_IRQ_MULTI_HANDLER
  ARM: footbridge: use GENERIC_IRQ_MULTI_HANDLER
  ARM: iop32x: offset IRQ numbers by 1
  ARM: iop32x: use GENERIC_IRQ_MULTI_HANDLER
  ARM: remove old-style irq entry

Vladimir Murzin (1):
  irqchip: nvic: Use GENERIC_IRQ_MULTI_HANDLER

 arch/arm/Kconfig                                    |  39 ++--
 arch/arm/Makefile                                   |   9 +
 arch/arm/boot/compressed/Makefile                   |   6 +-
 arch/arm/boot/compressed/misc.c                     |   7 -
 arch/arm/include/asm/assembler.h                    | 209 ++++++++++++++++----
 arch/arm/include/asm/current.h                      |  47 +++--
 arch/arm/include/asm/elf.h                          |   3 +
 arch/arm/include/asm/entry-macro-multi.S            |  40 ----
 arch/arm/include/asm/hardware/entry-macro-iomd.S    | 131 ------------
 arch/arm/include/asm/insn.h                         |  17 ++
 arch/arm/include/asm/irq.h                          |   1 -
 arch/arm/include/asm/mach/arch.h                    |   2 -
 arch/arm/include/asm/mmu.h                          |   2 +-
 arch/arm/include/asm/mmu_context.h                  |  22 ++-
 arch/arm/include/asm/page.h                         |   3 +
 arch/arm/include/asm/percpu.h                       |  36 +++-
 arch/arm/include/asm/smp.h                          |   5 -
 arch/arm/include/asm/stacktrace.h                   |  12 ++
 arch/arm/include/asm/switch_to.h                    |   3 +-
 arch/arm/include/asm/thread_info.h                  |  35 +---
 arch/arm/include/asm/tls.h                          |  30 ++-
 arch/arm/include/asm/v7m.h                          |   3 +-
 arch/arm/kernel/asm-offsets.c                       |   3 -
 arch/arm/kernel/entry-armv.S                        | 208 +++++++++++++++----
 arch/arm/kernel/entry-common.S                      |  16 +-
 arch/arm/kernel/entry-header.S                      |  47 ++++-
 arch/arm/kernel/entry-v7m.S                         |  39 ++--
 arch/arm/kernel/head-common.S                       |   4 +-
 arch/arm/kernel/head.S                              |   7 +
 arch/arm/kernel/irq.c                               |  55 ++++--
 arch/arm/kernel/module.c                            |  90 +++++++++
 arch/arm/kernel/process.c                           |   7 +-
 arch/arm/kernel/setup.c                             |   8 +-
 arch/arm/kernel/sleep.S                             |  13 ++
 arch/arm/kernel/smp.c                               |  11 +-
 arch/arm/kernel/traps.c                             |  92 ++++++++-
 arch/arm/kernel/unwind.c                            |  50 +++--
 arch/arm/kernel/vmlinux.lds.S                       |   4 +-
 arch/arm/lib/backtrace-clang.S                      |  13 +-
 arch/arm/lib/backtrace.S                            |   7 +
 arch/arm/lib/call_with_stack.S                      |  33 +++-
 arch/arm/lib/copy_from_user.S                       |  13 +-
 arch/arm/lib/copy_template.S                        |  67 +++----
 arch/arm/lib/copy_to_user.S                         |  13 +-
 arch/arm/lib/memcpy.S                               |  13 +-
 arch/arm/lib/memmove.S                              |  60 ++----
 arch/arm/lib/memset.S                               |   7 +-
 arch/arm/mach-footbridge/common.c                   |  87 ++++++++
 arch/arm/mach-footbridge/include/mach/entry-macro.S | 107 ----------
 arch/arm/mach-iop32x/cp6.c                          |  10 +-
 arch/arm/mach-iop32x/include/mach/entry-macro.S     |  31 ---
 arch/arm/mach-iop32x/include/mach/irqs.h            |   2 +-
 arch/arm/mach-iop32x/iop3xx.h                       |   1 +
 arch/arm/mach-iop32x/irq.c                          |  29 ++-
 arch/arm/mach-iop32x/irqs.h                         |  60 +++---
 arch/arm/mach-rpc/fiq.S                             |   5 +-
 arch/arm/mach-rpc/include/mach/entry-macro.S        |  13 --
 arch/arm/mach-rpc/irq.c                             |  95 +++++++++
 arch/arm/mm/Kconfig                                 |   1 +
 arch/arm/mm/context.c                               |   3 +-
 arch/arm/mm/ioremap.c                               |  18 +-
 drivers/irqchip/Kconfig                             |   1 +
 drivers/irqchip/irq-nvic.c                          |  22 +--
 63 files changed, 1270 insertions(+), 757 deletions(-)
 delete mode 100644 arch/arm/include/asm/entry-macro-multi.S
 delete mode 100644 arch/arm/include/asm/hardware/entry-macro-iomd.S
 delete mode 100644 arch/arm/mach-footbridge/include/mach/entry-macro.S
 delete mode 100644 arch/arm/mach-iop32x/include/mach/entry-macro.S
 delete mode 100644 arch/arm/mach-rpc/include/mach/entry-macro.S

-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:13 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:13 +0100
Subject: [PATCH v5 01/32] ARM: riscpc: drop support for
 IOMD_IRQREQC/IOMD_IRQREQD IRQ groups
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-2-ardb@kernel.org>

IOMD_IRQREQC nor IOMD_IRQREQD are ever defined, so any conditionally
compiled code that depends on them is dead code, and can be removed.

Suggested-by: Russell King <linux at armlinux.org.uk>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/hardware/entry-macro-iomd.S | 47 --------------------
 1 file changed, 47 deletions(-)

diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
index f7692731e514..81441dfa5282 100644
--- a/arch/arm/include/asm/hardware/entry-macro-iomd.S
+++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S
@@ -24,16 +24,6 @@
 		ldrbeq	\irqstat, [\base, #IOMD_IRQREQA]	@ get low priority
 		addeq	\tmp, \tmp, #256		@ irq_prio_d table size
 		teqeq	\irqstat, #0
-#ifdef IOMD_IRQREQC
-		ldrbeq	\irqstat, [\base, #IOMD_IRQREQC]
-		addeq	\tmp, \tmp, #256		@ irq_prio_l table size
-		teqeq	\irqstat, #0
-#endif
-#ifdef IOMD_IRQREQD
-		ldrbeq	\irqstat, [\base, #IOMD_IRQREQD]
-		addeq	\tmp, \tmp, #256		@ irq_prio_lc table size
-		teqeq	\irqstat, #0
-#endif
 2406:		ldrbne	\irqnr, [\tmp, \irqstat]	@ get IRQ number
 		.endm
 
@@ -92,40 +82,3 @@ irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
 		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
 		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
 		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-#ifdef IOMD_IRQREQC
-irq_prio_lc:	.byte	24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
-		.byte	28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
-		.byte	30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-		.byte	31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-#endif
-#ifdef IOMD_IRQREQD
-irq_prio_ld:	.byte	40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
-		.byte	44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
-		.byte	46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-		.byte	47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-#endif
-
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:14 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:14 +0100
Subject: [PATCH v5 02/32] ARM: riscpc: use GENERIC_IRQ_MULTI_HANDLER
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-3-ardb@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

This is one of the last platforms using the old entry path.
While this code path is spread over a few files, it is fairly
straightforward to convert it into an equivalent C version,
leaving the existing algorithm and all the priority handling
the same.

Unlike most irqchip drivers, this means reading the status
register(s) in a loop and always handling the highest-priority
irq first.

The IOMD_IRQREQC and IOMD_IRQREQD registers are not actaully
used here, but I left the code in place for the time being,
to keep the conversion as direct as possible. It could be
removed in a cleanup on top.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
[ardb: drop obsolete IOMD_IRQREQC/IOMD_IRQREQD handling]
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig                                 |  1 +
 arch/arm/include/asm/hardware/entry-macro-iomd.S | 84 -----------------
 arch/arm/mach-rpc/fiq.S                          |  5 +-
 arch/arm/mach-rpc/include/mach/entry-macro.S     | 13 ---
 arch/arm/mach-rpc/irq.c                          | 95 ++++++++++++++++++++
 5 files changed, 99 insertions(+), 99 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..40193ec76f1a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -443,6 +443,7 @@ config ARCH_RPC
 	select ARM_HAS_SG_CHAIN
 	select CPU_SA110
 	select FIQ
+	select GENERIC_IRQ_MULTI_HANDLER
 	select HAVE_PATA_PLATFORM
 	select ISA_DMA_API
 	select LEGACY_TIMER_TICK
diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
deleted file mode 100644
index 81441dfa5282..000000000000
--- a/arch/arm/include/asm/hardware/entry-macro-iomd.S
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/entry-macro-iomd.S
- *
- * Low-level IRQ helper macros for IOC/IOMD based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-/* IOC / IOMD based hardware */
-#include <asm/hardware/iomd.h>
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldrb	\irqstat, [\base, #IOMD_IRQREQB]	@ get high priority first
-		ldr	\tmp, =irq_prio_h
-		teq	\irqstat, #0
-#ifdef IOMD_BASE
-		ldrbeq	\irqstat, [\base, #IOMD_DMAREQ]	@ get dma
-		addeq	\tmp, \tmp, #256		@ irq_prio_h table size
-		teqeq	\irqstat, #0
-		bne	2406f
-#endif
-		ldrbeq	\irqstat, [\base, #IOMD_IRQREQA]	@ get low priority
-		addeq	\tmp, \tmp, #256		@ irq_prio_d table size
-		teqeq	\irqstat, #0
-2406:		ldrbne	\irqnr, [\tmp, \irqstat]	@ get IRQ number
-		.endm
-
-/*
- * Interrupt table (incorporates priority).  Please note that we
- * rely on the order of these tables (see above code).
- */
-		.align	5
-irq_prio_h:	.byte	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-		.byte	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-#ifdef IOMD_BASE
-irq_prio_d:	.byte	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-		.byte	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-#endif
-irq_prio_l:	.byte	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-		.byte	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S
index 0de83e9b0b39..087bdf4bc093 100644
--- a/arch/arm/mach-rpc/fiq.S
+++ b/arch/arm/mach-rpc/fiq.S
@@ -2,10 +2,11 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 #include <mach/hardware.h>
-#include <mach/entry-macro.S>
 
-	.text
+	.equ	ioc_base_high, IOC_BASE & 0xff000000
+	.equ	ioc_base_low, IOC_BASE & 0x00ff0000
 
+	.text
 	.global	rpc_default_fiq_end
 ENTRY(rpc_default_fiq_start)
 	mov	r12, #ioc_base_high
diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
deleted file mode 100644
index a6d1a9f4bb79..000000000000
--- a/arch/arm/mach-rpc/include/mach/entry-macro.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <mach/hardware.h>
-#include <asm/hardware/entry-macro-iomd.S>
-
-	.equ	ioc_base_high, IOC_BASE & 0xff000000
-	.equ	ioc_base_low, IOC_BASE & 0x00ff0000
-
-	.macro  get_irqnr_preamble, base, tmp
-	mov	\base, #ioc_base_high		@ point at IOC
-	.if	ioc_base_low
-	orr	\base, \base, #ioc_base_low
-	.endif
-	.endm
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 803aeb126f0e..dc29384b6ef8 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -14,6 +14,99 @@
 #define CLR	0x04
 #define MASK	0x08
 
+static const u8 irq_prio_h[256] = {
+	 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+	12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+	14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+	15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+	13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+};
+
+static const u8 irq_prio_d[256] = {
+	 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+	21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+};
+
+static const u8 irq_prio_l[256] = {
+	 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+	 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+	 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+static int iomd_get_irq_nr(void)
+{
+	int irq;
+	u8 reg;
+
+	/* get highest priority first */
+	reg = readb(IOC_BASE + IOMD_IRQREQB);
+	irq = irq_prio_h[reg];
+	if (irq)
+		return irq;
+
+	/* get DMA  */
+	reg = readb(IOC_BASE + IOMD_DMAREQ);
+	irq = irq_prio_d[reg];
+	if (irq)
+		return irq;
+
+	/* get low priority */
+	reg = readb(IOC_BASE + IOMD_IRQREQA);
+	irq = irq_prio_l[reg];
+	if (irq)
+		return irq;
+	return 0;
+}
+
+static void iomd_handle_irq(struct pt_regs *regs)
+{
+	int irq;
+
+	do {
+		irq = iomd_get_irq_nr();
+		if (irq)
+			generic_handle_irq(irq);
+	} while (irq);
+}
+
 static void __iomem *iomd_get_base(struct irq_data *d)
 {
 	void *cd = irq_data_get_irq_chip_data(d);
@@ -82,6 +175,8 @@ void __init rpc_init_irq(void)
 	set_fiq_handler(&rpc_default_fiq_start,
 		&rpc_default_fiq_end - &rpc_default_fiq_start);
 
+	set_handle_irq(iomd_handle_irq);
+
 	for (irq = 0; irq < NR_IRQS; irq++) {
 		clr = IRQ_NOREQUEST;
 		set = 0;
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:15 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:15 +0100
Subject: [PATCH v5 03/32] ARM: footbridge: use GENERIC_IRQ_MULTI_HANDLER
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-4-ardb@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

Footbridge still uses the classic IRQ entry path in assembler,
but this is easily converted into an equivalent C version.

In this case, the correlation between IRQ numbers and bits in
the status register is non-obvious, and the priorities are
handled by manually checking each bit in a static order,
re-reading the status register after each handled event.

I moved the code into the new file and edited the syntax without
changing this sequence to keep the behavior as close as possible
to what it traditionally did.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig                                    |   1 +
 arch/arm/mach-footbridge/common.c                   |  87 ++++++++++++++++
 arch/arm/mach-footbridge/include/mach/entry-macro.S | 107 --------------------
 3 files changed, 88 insertions(+), 107 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 40193ec76f1a..bef5085f2ce7 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -361,6 +361,7 @@ config ARCH_FOOTBRIDGE
 	select FOOTBRIDGE
 	select NEED_MACH_IO_H if !MMU
 	select NEED_MACH_MEMORY_H
+	select GENERIC_IRQ_MULTI_HANDLER
 	help
 	  Support for systems based on the DC21285 companion chip
 	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index eee095f0e2f6..322495df271d 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -27,6 +27,91 @@
 
 #include "common.h"
 
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/hardware/dec21285.h>
+
+static int dc21285_get_irq(void)
+{
+	void __iomem *irqstatus = (void __iomem *)CSR_IRQ_STATUS;
+	u32 mask = readl(irqstatus);
+
+	if (mask & IRQ_MASK_SDRAMPARITY)
+		return IRQ_SDRAMPARITY;
+
+	if (mask & IRQ_MASK_UART_RX)
+		return IRQ_CONRX;
+
+	if (mask & IRQ_MASK_DMA1)
+		return IRQ_DMA1;
+
+	if (mask & IRQ_MASK_DMA2)
+		return IRQ_DMA2;
+
+	if (mask & IRQ_MASK_IN0)
+		return IRQ_IN0;
+
+	if (mask & IRQ_MASK_IN1)
+		return IRQ_IN1;
+
+	if (mask & IRQ_MASK_IN2)
+		return IRQ_IN2;
+
+	if (mask & IRQ_MASK_IN3)
+		return IRQ_IN3;
+
+	if (mask & IRQ_MASK_PCI)
+		return IRQ_PCI;
+
+	if (mask & IRQ_MASK_DOORBELLHOST)
+		return IRQ_DOORBELLHOST;
+
+	if (mask & IRQ_MASK_I2OINPOST)
+		return IRQ_I2OINPOST;
+
+	if (mask & IRQ_MASK_TIMER1)
+		return IRQ_TIMER1;
+
+	if (mask & IRQ_MASK_TIMER2)
+		return IRQ_TIMER2;
+
+	if (mask & IRQ_MASK_TIMER3)
+		return IRQ_TIMER3;
+
+	if (mask & IRQ_MASK_UART_TX)
+		return IRQ_CONTX;
+
+	if (mask & IRQ_MASK_PCI_ABORT)
+		return IRQ_PCI_ABORT;
+
+	if (mask & IRQ_MASK_PCI_SERR)
+		return IRQ_PCI_SERR;
+
+	if (mask & IRQ_MASK_DISCARD_TIMER)
+		return IRQ_DISCARD_TIMER;
+
+	if (mask & IRQ_MASK_PCI_DPERR)
+		return IRQ_PCI_DPERR;
+
+	if (mask & IRQ_MASK_PCI_PERR)
+		return IRQ_PCI_PERR;
+
+	return 0;
+}
+
+static void dc21285_handle_irq(struct pt_regs *regs)
+{
+	int irq;
+	do {
+		irq = dc21285_get_irq();
+		if (!irq)
+			break;
+
+		generic_handle_irq(irq);
+	} while (1);
+}
+
+
 unsigned int mem_fclk_21285 = 50000000;
 
 EXPORT_SYMBOL(mem_fclk_21285);
@@ -108,6 +193,8 @@ static void __init __fb_init_irq(void)
 
 void __init footbridge_init_irq(void)
 {
+	set_handle_irq(dc21285_handle_irq);
+
 	__fb_init_irq();
 
 	if (!footbridge_cfn_mode())
diff --git a/arch/arm/mach-footbridge/include/mach/entry-macro.S b/arch/arm/mach-footbridge/include/mach/entry-macro.S
deleted file mode 100644
index dabbd5c54a78..000000000000
--- a/arch/arm/mach-footbridge/include/mach/entry-macro.S
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * arch/arm/mach-footbridge/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for footbridge-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <asm/hardware/dec21285.h>
-
-		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
-		.equ	dc21285_low, ARMCSR_BASE & 0x00ffffff
-
-		.macro  get_irqnr_preamble, base, tmp
-		mov	\base, #dc21285_high
-		.if	dc21285_low
-		orr	\base, \base, #dc21285_low
-		.endif
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, [\base, #0x180]	@ get interrupts
-
-		mov	\irqnr, #IRQ_SDRAMPARITY
-		tst	\irqstat, #IRQ_MASK_SDRAMPARITY
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_UART_RX
-		movne	\irqnr, #IRQ_CONRX
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DMA1
-		movne	\irqnr, #IRQ_DMA1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DMA2
-		movne	\irqnr, #IRQ_DMA2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN0
-		movne	\irqnr, #IRQ_IN0
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN1
-		movne	\irqnr, #IRQ_IN1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN2
-		movne	\irqnr, #IRQ_IN2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_IN3
-		movne	\irqnr, #IRQ_IN3
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI
-		movne	\irqnr, #IRQ_PCI
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DOORBELLHOST
-		movne	\irqnr, #IRQ_DOORBELLHOST
-		bne     1001f
-
-		tst	\irqstat, #IRQ_MASK_I2OINPOST
-		movne	\irqnr, #IRQ_I2OINPOST
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER1
-		movne	\irqnr, #IRQ_TIMER1
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER2
-		movne	\irqnr, #IRQ_TIMER2
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_TIMER3
-		movne	\irqnr, #IRQ_TIMER3
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_UART_TX
-		movne	\irqnr, #IRQ_CONTX
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_ABORT
-		movne	\irqnr, #IRQ_PCI_ABORT
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_SERR
-		movne	\irqnr, #IRQ_PCI_SERR
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_DISCARD_TIMER
-		movne	\irqnr, #IRQ_DISCARD_TIMER
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_DPERR
-		movne	\irqnr, #IRQ_PCI_DPERR
-		bne	1001f
-
-		tst	\irqstat, #IRQ_MASK_PCI_PERR
-		movne	\irqnr, #IRQ_PCI_PERR
-1001:
-		.endm
-
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:16 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:16 +0100
Subject: [PATCH v5 04/32] ARM: iop32x: offset IRQ numbers by 1
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-5-ardb@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

iop32x is one of the last platforms to use IRQ 0, and this has apparently
stopped working in a 2014 cleanup without anyone noticing. This interrupt
is used for the DMA engine, so most likely this has not actually worked
in the past 7 years, but it's also not essential for using this board.

I'm splitting out this change from my GENERIC_IRQ_MULTI_HANDLER
conversion so it can be backported if anyone cares.

Fixes: a71b092a9c68 ("ARM: Convert handle_IRQ to use __handle_domain_irq")
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
[ardb: take +1 offset into account in mask/unmask and init as well]
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-iop32x/include/mach/entry-macro.S |  2 +-
 arch/arm/mach-iop32x/include/mach/irqs.h        |  2 +-
 arch/arm/mach-iop32x/irq.c                      |  6 +-
 arch/arm/mach-iop32x/irqs.h                     | 60 +++++++++++---------
 4 files changed, 37 insertions(+), 33 deletions(-)

diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
index 8e6766d4621e..341e5d9a6616 100644
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ b/arch/arm/mach-iop32x/include/mach/entry-macro.S
@@ -20,7 +20,7 @@
 	mrc     p6, 0, \irqstat, c8, c0, 0	@ Read IINTSRC
 	cmp     \irqstat, #0
 	clzne   \irqnr, \irqstat
-	rsbne   \irqnr, \irqnr, #31
+	rsbne   \irqnr, \irqnr, #32
 	.endm
 
 	.macro arch_ret_to_user, tmp1, tmp2
diff --git a/arch/arm/mach-iop32x/include/mach/irqs.h b/arch/arm/mach-iop32x/include/mach/irqs.h
index c4e78df428e8..e09ae5f48aec 100644
--- a/arch/arm/mach-iop32x/include/mach/irqs.h
+++ b/arch/arm/mach-iop32x/include/mach/irqs.h
@@ -9,6 +9,6 @@
 #ifndef __IRQS_H
 #define __IRQS_H
 
-#define NR_IRQS			32
+#define NR_IRQS			33
 
 #endif
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 2d48bf1398c1..d1e8824cbd82 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -32,14 +32,14 @@ static void intstr_write(u32 val)
 static void
 iop32x_irq_mask(struct irq_data *d)
 {
-	iop32x_mask &= ~(1 << d->irq);
+	iop32x_mask &= ~(1 << (d->irq - 1));
 	intctl_write(iop32x_mask);
 }
 
 static void
 iop32x_irq_unmask(struct irq_data *d)
 {
-	iop32x_mask |= 1 << d->irq;
+	iop32x_mask |= 1 << (d->irq - 1);
 	intctl_write(iop32x_mask);
 }
 
@@ -65,7 +65,7 @@ void __init iop32x_init_irq(void)
 	    machine_is_em7210())
 		*IOP3XX_PCIIRSR = 0x0f;
 
-	for (i = 0; i < NR_IRQS; i++) {
+	for (i = 1; i < NR_IRQS; i++) {
 		irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
 		irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
 	}
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
index 69858e4e905d..e1dfc8b4e7d7 100644
--- a/arch/arm/mach-iop32x/irqs.h
+++ b/arch/arm/mach-iop32x/irqs.h
@@ -7,36 +7,40 @@
 #ifndef __IOP32X_IRQS_H
 #define __IOP32X_IRQS_H
 
+/* Interrupts in Linux start at 1, hardware starts at 0 */
+
+#define IOP_IRQ(x) ((x) + 1)
+
 /*
  * IOP80321 chipset interrupts
  */
-#define IRQ_IOP32X_DMA0_EOT	0
-#define IRQ_IOP32X_DMA0_EOC	1
-#define IRQ_IOP32X_DMA1_EOT	2
-#define IRQ_IOP32X_DMA1_EOC	3
-#define IRQ_IOP32X_AA_EOT	6
-#define IRQ_IOP32X_AA_EOC	7
-#define IRQ_IOP32X_CORE_PMON	8
-#define IRQ_IOP32X_TIMER0	9
-#define IRQ_IOP32X_TIMER1	10
-#define IRQ_IOP32X_I2C_0	11
-#define IRQ_IOP32X_I2C_1	12
-#define IRQ_IOP32X_MESSAGING	13
-#define IRQ_IOP32X_ATU_BIST	14
-#define IRQ_IOP32X_PERFMON	15
-#define IRQ_IOP32X_CORE_PMU	16
-#define IRQ_IOP32X_BIU_ERR	17
-#define IRQ_IOP32X_ATU_ERR	18
-#define IRQ_IOP32X_MCU_ERR	19
-#define IRQ_IOP32X_DMA0_ERR	20
-#define IRQ_IOP32X_DMA1_ERR	21
-#define IRQ_IOP32X_AA_ERR	23
-#define IRQ_IOP32X_MSG_ERR	24
-#define IRQ_IOP32X_SSP		25
-#define IRQ_IOP32X_XINT0	27
-#define IRQ_IOP32X_XINT1	28
-#define IRQ_IOP32X_XINT2	29
-#define IRQ_IOP32X_XINT3	30
-#define IRQ_IOP32X_HPI		31
+#define IRQ_IOP32X_DMA0_EOT	IOP_IRQ(0)
+#define IRQ_IOP32X_DMA0_EOC	IOP_IRQ(1)
+#define IRQ_IOP32X_DMA1_EOT	IOP_IRQ(2)
+#define IRQ_IOP32X_DMA1_EOC	IOP_IRQ(3)
+#define IRQ_IOP32X_AA_EOT	IOP_IRQ(6)
+#define IRQ_IOP32X_AA_EOC	IOP_IRQ(7)
+#define IRQ_IOP32X_CORE_PMON	IOP_IRQ(8)
+#define IRQ_IOP32X_TIMER0	IOP_IRQ(9)
+#define IRQ_IOP32X_TIMER1	IOP_IRQ(10)
+#define IRQ_IOP32X_I2C_0	IOP_IRQ(11)
+#define IRQ_IOP32X_I2C_1	IOP_IRQ(12)
+#define IRQ_IOP32X_MESSAGING	IOP_IRQ(13)
+#define IRQ_IOP32X_ATU_BIST	IOP_IRQ(14)
+#define IRQ_IOP32X_PERFMON	IOP_IRQ(15)
+#define IRQ_IOP32X_CORE_PMU	IOP_IRQ(16)
+#define IRQ_IOP32X_BIU_ERR	IOP_IRQ(17)
+#define IRQ_IOP32X_ATU_ERR	IOP_IRQ(18)
+#define IRQ_IOP32X_MCU_ERR	IOP_IRQ(19)
+#define IRQ_IOP32X_DMA0_ERR	IOP_IRQ(20)
+#define IRQ_IOP32X_DMA1_ERR	IOP_IRQ(21)
+#define IRQ_IOP32X_AA_ERR	IOP_IRQ(23)
+#define IRQ_IOP32X_MSG_ERR	IOP_IRQ(24)
+#define IRQ_IOP32X_SSP		IOP_IRQ(25)
+#define IRQ_IOP32X_XINT0	IOP_IRQ(27)
+#define IRQ_IOP32X_XINT1	IOP_IRQ(28)
+#define IRQ_IOP32X_XINT2	IOP_IRQ(29)
+#define IRQ_IOP32X_XINT3	IOP_IRQ(30)
+#define IRQ_IOP32X_HPI		IOP_IRQ(31)
 
 #endif
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:17 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:17 +0100
Subject: [PATCH v5 05/32] ARM: iop32x: use GENERIC_IRQ_MULTI_HANDLER
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-6-ardb@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

iop32x uses the entry-macro.S file for both the IRQ entry and for
hooking into the arch_ret_to_user code path. This is done because the
cp6 registers have to be enabled before accessing any of the interrupt
controller registers but have to be disabled when running in user space.

There is also a lazy-enable logic in cp6.c, but during a hardirq, we
know it has to be enabled.

Both the cp6-enable code and the code to read the IRQ status can be
lifted into the normal generic_handle_arch_irq() path, but the
cp6-disable code has to remain in the user return code. As nothing
other than iop32x uses this hook, just open-code it there with an
ifdef for the platform that can eventually be removed when iop32x
has reached the end of its life.

The cp6-enable path in the IRQ entry has an extra cp_wait barrier that
the trap version does not have, but it is harmless to do it in both
cases to simplify the logic here at the cost of a few extra cycles
for the trap.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig                                |  5 +---
 arch/arm/kernel/entry-common.S                  | 16 +++++-----
 arch/arm/mach-iop32x/cp6.c                      | 10 ++++++-
 arch/arm/mach-iop32x/include/mach/entry-macro.S | 31 --------------------
 arch/arm/mach-iop32x/iop3xx.h                   |  1 +
 arch/arm/mach-iop32x/irq.c                      | 23 +++++++++++++++
 6 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bef5085f2ce7..ac2f88ce0b9a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -226,9 +226,6 @@ config GENERIC_ISA_DMA
 config FIQ
 	bool
 
-config NEED_RET_TO_USER
-	bool
-
 config ARCH_MTD_XIP
 	bool
 
@@ -370,9 +367,9 @@ config ARCH_IOP32X
 	bool "IOP32x-based"
 	depends on MMU
 	select CPU_XSCALE
+	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_IOP
 	select GPIOLIB
-	select NEED_RET_TO_USER
 	select FORCE_PCI
 	select PLAT_IOP
 	help
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index ac86c34682bb..c928d6b04cce 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -16,12 +16,14 @@
 
 	.equ	NR_syscalls, __NR_syscalls
 
-#ifdef CONFIG_NEED_RET_TO_USER
-#include <mach/entry-macro.S>
-#else
-	.macro  arch_ret_to_user, tmp1, tmp2
-	.endm
+	.macro  arch_ret_to_user, tmp
+#ifdef CONFIG_ARCH_IOP32X
+	mrc	p15, 0, \tmp, c15, c1, 0
+	tst	\tmp, #(1 << 6)
+	bicne	\tmp, \tmp, #(1 << 6)
+	mcrne	p15, 0, \tmp, c15, c1, 0	@ Disable cp6 access
 #endif
+	.endm
 
 #include "entry-header.S"
 
@@ -55,7 +57,7 @@ __ret_fast_syscall:
 
 
 	/* perform architecture specific actions before user return */
-	arch_ret_to_user r1, lr
+	arch_ret_to_user r1
 
 	restore_user_regs fast = 1, offset = S_OFF
  UNWIND(.fnend		)
@@ -128,7 +130,7 @@ no_work_pending:
 	asm_trace_hardirqs_on save = 0
 
 	/* perform architecture specific actions before user return */
-	arch_ret_to_user r1, lr
+	arch_ret_to_user r1
 	ct_user_enter save = 0
 
 	restore_user_regs fast = 0, offset = 0
diff --git a/arch/arm/mach-iop32x/cp6.c b/arch/arm/mach-iop32x/cp6.c
index ec74b07fb7e3..2882674a1c39 100644
--- a/arch/arm/mach-iop32x/cp6.c
+++ b/arch/arm/mach-iop32x/cp6.c
@@ -7,7 +7,7 @@
 #include <asm/traps.h>
 #include <asm/ptrace.h>
 
-static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+void iop_enable_cp6(void)
 {
 	u32 temp;
 
@@ -16,7 +16,15 @@ static int cp6_trap(struct pt_regs *regs, unsigned int instr)
 		"mrc	p15, 0, %0, c15, c1, 0\n\t"
 		"orr	%0, %0, #(1 << 6)\n\t"
 		"mcr	p15, 0, %0, c15, c1, 0\n\t"
+		"mrc	p15, 0, %0, c15, c1, 0\n\t"
+		"mov	%0, %0\n\t"
+		"sub	pc, pc, #4  @ cp_wait\n\t"
 		: "=r"(temp));
+}
+
+static int cp6_trap(struct pt_regs *regs, unsigned int instr)
+{
+	iop_enable_cp6();
 
 	return 0;
 }
diff --git a/arch/arm/mach-iop32x/include/mach/entry-macro.S b/arch/arm/mach-iop32x/include/mach/entry-macro.S
deleted file mode 100644
index 341e5d9a6616..000000000000
--- a/arch/arm/mach-iop32x/include/mach/entry-macro.S
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP32x-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-	.macro get_irqnr_preamble, base, tmp
-	mrc	p15, 0, \tmp, c15, c1, 0
-	orr	\tmp, \tmp, #(1 << 6)
-	mcr	p15, 0, \tmp, c15, c1, 0	@ Enable cp6 access
-	mrc	p15, 0, \tmp, c15, c1, 0
-	mov	\tmp, \tmp
-	sub	pc, pc, #4			@ cp_wait
-	.endm
-
-	.macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-	mrc     p6, 0, \irqstat, c8, c0, 0	@ Read IINTSRC
-	cmp     \irqstat, #0
-	clzne   \irqnr, \irqstat
-	rsbne   \irqnr, \irqnr, #32
-	.endm
-
-	.macro arch_ret_to_user, tmp1, tmp2
-	mrc	p15, 0, \tmp1, c15, c1, 0
-	ands	\tmp2, \tmp1, #(1 << 6)
-	bicne	\tmp1, \tmp1, #(1 << 6)
-	mcrne	p15, 0, \tmp1, c15, c1, 0	@ Disable cp6 access
-	.endm
diff --git a/arch/arm/mach-iop32x/iop3xx.h b/arch/arm/mach-iop32x/iop3xx.h
index 46b4b34a4ad2..a6ec7ebadb35 100644
--- a/arch/arm/mach-iop32x/iop3xx.h
+++ b/arch/arm/mach-iop32x/iop3xx.h
@@ -225,6 +225,7 @@ extern int iop3xx_get_init_atu(void);
 #include <linux/reboot.h>
 
 void iop3xx_map_io(void);
+void iop_enable_cp6(void);
 void iop_init_cp6_handler(void);
 void iop_init_time(unsigned long tickrate);
 void iop3xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index d1e8824cbd82..6dca7e97d81f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -29,6 +29,15 @@ static void intstr_write(u32 val)
 	asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val));
 }
 
+static u32 iintsrc_read(void)
+{
+	int irq;
+
+	asm volatile("mrc p6, 0, %0, c8, c0, 0" : "=r" (irq));
+
+	return irq;
+}
+
 static void
 iop32x_irq_mask(struct irq_data *d)
 {
@@ -50,11 +59,25 @@ struct irq_chip ext_chip = {
 	.irq_unmask	= iop32x_irq_unmask,
 };
 
+static void iop_handle_irq(struct pt_regs *regs)
+{
+	u32 mask;
+
+	iop_enable_cp6();
+
+	do {
+		mask = iintsrc_read();
+		if (mask)
+			generic_handle_irq(fls(mask));
+	} while (mask);
+}
+
 void __init iop32x_init_irq(void)
 {
 	int i;
 
 	iop_init_cp6_handler();
+	set_handle_irq(iop_handle_irq);
 
 	intctl_write(0);
 	intstr_write(0);
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:18 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:18 +0100
Subject: [PATCH v5 06/32] ARM: remove old-style irq entry
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-7-ardb@kernel.org>

From: Arnd Bergmann <arnd at arndb.de>

The last user of arch_irq_handler_default is gone now, so the
entry-macro-multi.S file and all references to mach/entry-macro.S can
be removed, as well as the asm_do_IRQ() entrypoint into the interrupt
handling routines implemented in C.

Note: The ARMv7-M entry still uses its own top-level IRQ entry, calling
nvic_handle_irq() from assembly. This could be changed to go through
generic_handle_arch_irq() as well, but it's unclear to me if there are
any benefits.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
[ardb: keep irq_handler macro as it will carry the IRQ stack handling]
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig                         | 12 +-----
 arch/arm/include/asm/entry-macro-multi.S | 40 --------------------
 arch/arm/include/asm/irq.h               |  1 -
 arch/arm/include/asm/mach/arch.h         |  2 -
 arch/arm/include/asm/smp.h               |  5 ---
 arch/arm/kernel/entry-armv.S             |  8 ----
 arch/arm/kernel/irq.c                    | 17 ---------
 arch/arm/kernel/smp.c                    |  5 ---
 8 files changed, 1 insertion(+), 89 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ac2f88ce0b9a..7528cbdb90a1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -58,6 +58,7 @@ config ARM
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_EARLY_IOREMAP
 	select GENERIC_IDLE_POLL_SETUP
+	select GENERIC_IRQ_MULTI_HANDLER if MMU
 	select GENERIC_IRQ_PROBE
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
@@ -319,7 +320,6 @@ config ARCH_MULTIPLATFORM
 	select AUTO_ZRELADDR
 	select TIMER_OF
 	select COMMON_CLK
-	select GENERIC_IRQ_MULTI_HANDLER
 	select HAVE_PCI
 	select PCI_DOMAINS_GENERIC if PCI
 	select SPARSE_IRQ
@@ -343,7 +343,6 @@ config ARCH_EP93XX
 	select ARM_AMBA
 	imply ARM_PATCH_PHYS_VIRT
 	select ARM_VIC
-	select GENERIC_IRQ_MULTI_HANDLER
 	select AUTO_ZRELADDR
 	select CLKSRC_MMIO
 	select CPU_ARM920T
@@ -358,7 +357,6 @@ config ARCH_FOOTBRIDGE
 	select FOOTBRIDGE
 	select NEED_MACH_IO_H if !MMU
 	select NEED_MACH_MEMORY_H
-	select GENERIC_IRQ_MULTI_HANDLER
 	help
 	  Support for systems based on the DC21285 companion chip
 	  ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
@@ -367,7 +365,6 @@ config ARCH_IOP32X
 	bool "IOP32x-based"
 	depends on MMU
 	select CPU_XSCALE
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_IOP
 	select GPIOLIB
 	select FORCE_PCI
@@ -383,7 +380,6 @@ config ARCH_IXP4XX
 	select ARCH_SUPPORTS_BIG_ENDIAN
 	select CPU_XSCALE
 	select DMABOUNCE if PCI
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_IXP4XX
 	select GPIOLIB
 	select HAVE_PCI
@@ -399,7 +395,6 @@ config ARCH_IXP4XX
 config ARCH_DOVE
 	bool "Marvell Dove"
 	select CPU_PJ4
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIOLIB
 	select HAVE_PCI
 	select MVEBU_MBUS
@@ -422,7 +417,6 @@ config ARCH_PXA
 	select CLKSRC_MMIO
 	select TIMER_OF
 	select CPU_XSCALE if !CPU_XSC3
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_PXA
 	select GPIOLIB
 	select IRQ_DOMAIN
@@ -441,7 +435,6 @@ config ARCH_RPC
 	select ARM_HAS_SG_CHAIN
 	select CPU_SA110
 	select FIQ
-	select GENERIC_IRQ_MULTI_HANDLER
 	select HAVE_PATA_PLATFORM
 	select ISA_DMA_API
 	select LEGACY_TIMER_TICK
@@ -462,7 +455,6 @@ config ARCH_SA1100
 	select COMMON_CLK
 	select CPU_FREQ
 	select CPU_SA1100
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIOLIB
 	select IRQ_DOMAIN
 	select ISA
@@ -477,7 +469,6 @@ config ARCH_S3C24XX
 	select CLKSRC_SAMSUNG_PWM
 	select GPIO_SAMSUNG
 	select GPIOLIB
-	select GENERIC_IRQ_MULTI_HANDLER
 	select NEED_MACH_IO_H
 	select S3C2410_WATCHDOG
 	select SAMSUNG_ATAGS
@@ -495,7 +486,6 @@ config ARCH_OMAP1
 	select ARCH_OMAP
 	select CLKSRC_MMIO
 	select GENERIC_IRQ_CHIP
-	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIOLIB
 	select HAVE_LEGACY_CLK
 	select IRQ_DOMAIN
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
deleted file mode 100644
index dfc6bfa43012..000000000000
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/assembler.h>
-
-/*
- * Interrupt handling.  Preserves r7, r8, r9
- */
-	.macro	arch_irq_handler_default
-	get_irqnr_preamble r6, lr
-1:	get_irqnr_and_base r0, r2, r6, lr
-	movne	r1, sp
-	@
-	@ routine called with r0 = irq number, r1 = struct pt_regs *
-	@
-	badrne	lr, 1b
-	bne	asm_do_IRQ
-
-#ifdef CONFIG_SMP
-	/*
-	 * XXX
-	 *
-	 * this macro assumes that irqstat (r2) and base (r6) are
-	 * preserved from get_irqnr_and_base above
-	 */
-	ALT_SMP(test_for_ipi r0, r2, r6, lr)
-	ALT_UP_B(9997f)
-	movne	r1, sp
-	badrne	lr, 1b
-	bne	do_IPI
-#endif
-9997:
-	.endm
-
-	.macro	arch_irq_handler, symbol_name
-	.align	5
-	.global \symbol_name
-\symbol_name:
-	mov	r8, lr
-	arch_irq_handler_default
-	ret	r8
-	.endm
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 1cbcc462b07e..a7c2337b0c7d 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -26,7 +26,6 @@
 struct irqaction;
 struct pt_regs;
 
-extern void asm_do_IRQ(unsigned int, struct pt_regs *);
 void handle_IRQ(unsigned int, struct pt_regs *);
 void init_IRQ(void);
 
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index eec0c0bda766..9349e7a82c9c 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -56,9 +56,7 @@ struct machine_desc {
 	void			(*init_time)(void);
 	void			(*init_machine)(void);
 	void			(*init_late)(void);
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
 	void			(*handle_irq)(struct pt_regs *);
-#endif
 	void			(*restart)(enum reboot_mode, const char *);
 };
 
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index f16cbbd5cda4..7c1c90d9f582 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -24,11 +24,6 @@ struct seq_file;
  */
 extern void show_ipi_list(struct seq_file *, int);
 
-/*
- * Called from assembly code, this handles an IPI.
- */
-asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
-
 /*
  * Called from C code, this handles an IPI.
  */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 5cd057859fe9..9d9372781408 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -19,9 +19,6 @@
 #include <asm/glue-df.h>
 #include <asm/glue-pf.h>
 #include <asm/vfpmacros.h>
-#ifndef CONFIG_GENERIC_IRQ_MULTI_HANDLER
-#include <mach/entry-macro.S>
-#endif
 #include <asm/thread_notify.h>
 #include <asm/unwind.h>
 #include <asm/unistd.h>
@@ -30,19 +27,14 @@
 #include <asm/uaccess-asm.h>
 
 #include "entry-header.S"
-#include <asm/entry-macro-multi.S>
 #include <asm/probes.h>
 
 /*
  * Interrupt handling.
  */
 	.macro	irq_handler
-#ifdef CONFIG_GENERIC_IRQ_MULTI_HANDLER
 	mov	r0, sp
 	bl	generic_handle_arch_irq
-#else
-	arch_irq_handler_default
-#endif
 	.endm
 
 	.macro	pabt_helper
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index b79975bd988c..5a1e52a4ee11 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -80,23 +80,6 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs)
 		ack_bad_irq(irq);
 }
 
-/*
- * asm_do_IRQ is the interface to be used from assembly code.
- */
-asmlinkage void __exception_irq_entry
-asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
-{
-	struct pt_regs *old_regs;
-
-	irq_enter();
-	old_regs = set_irq_regs(regs);
-
-	handle_IRQ(irq, regs);
-
-	set_irq_regs(old_regs);
-	irq_exit();
-}
-
 void __init init_IRQ(void)
 {
 	int ret;
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 97ee6b1567e9..ed2b168ff46c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -628,11 +628,6 @@ static void ipi_complete(unsigned int cpu)
 /*
  * Main handler for inter-processor interrupts
  */
-asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
-{
-	handle_IPI(ipinr, regs);
-}
-
 static void do_handle_IPI(int ipinr)
 {
 	unsigned int cpu = smp_processor_id();
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:19 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:19 +0100
Subject: [PATCH v5 07/32] irqchip: nvic: Use GENERIC_IRQ_MULTI_HANDLER
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-8-ardb@kernel.org>

From: Vladimir Murzin <vladimir.murzin at arm.com>

Rather then restructuring the ARMv7M entrly logic per TODO, just move
NVIC to GENERIC_IRQ_MULTI_HANDLER.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
Acked-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/v7m.h  |  3 ++-
 arch/arm/kernel/entry-v7m.S | 10 +++------
 drivers/irqchip/Kconfig     |  1 +
 drivers/irqchip/irq-nvic.c  | 22 +++++---------------
 4 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/arch/arm/include/asm/v7m.h b/arch/arm/include/asm/v7m.h
index 2cb00d15831b..4512f7e1918f 100644
--- a/arch/arm/include/asm/v7m.h
+++ b/arch/arm/include/asm/v7m.h
@@ -13,6 +13,7 @@
 #define V7M_SCB_ICSR_PENDSVSET			(1 << 28)
 #define V7M_SCB_ICSR_PENDSVCLR			(1 << 27)
 #define V7M_SCB_ICSR_RETTOBASE			(1 << 11)
+#define V7M_SCB_ICSR_VECTACTIVE			0x000001ff
 
 #define V7M_SCB_VTOR			0x08
 
@@ -38,7 +39,7 @@
 #define V7M_SCB_SHCSR_MEMFAULTENA		(1 << 16)
 
 #define V7M_xPSR_FRAMEPTRALIGN			0x00000200
-#define V7M_xPSR_EXCEPTIONNO			0x000001ff
+#define V7M_xPSR_EXCEPTIONNO			V7M_SCB_ICSR_VECTACTIVE
 
 /*
  * When branching to an address that has bits [31:28] == 0xf an exception return
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 7bde93c10962..520dd43e7e08 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -39,14 +39,10 @@ __irq_entry:
 	@
 	@ Invoke the IRQ handler
 	@
-	mrs	r0, ipsr
-	ldr	r1, =V7M_xPSR_EXCEPTIONNO
-	and	r0, r1
-	sub	r0, #16
-	mov	r1, sp
+	mov	r0, sp
 	stmdb	sp!, {lr}
-	@ routine called with r0 = irq number, r1 = struct pt_regs *
-	bl	nvic_handle_irq
+	@ routine called with r0 = struct pt_regs *
+	bl	generic_handle_arch_irq
 
 	pop	{lr}
 	@
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 7038957f4a77..488eaa14d3a7 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -58,6 +58,7 @@ config ARM_NVIC
 	bool
 	select IRQ_DOMAIN_HIERARCHY
 	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_MULTI_HANDLER
 
 config ARM_VIC
 	bool
diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index ba4759b3e269..125f9c1cf0c3 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -37,25 +37,12 @@
 
 static struct irq_domain *nvic_irq_domain;
 
-static void __nvic_handle_irq(irq_hw_number_t hwirq)
+static void __irq_entry nvic_handle_irq(struct pt_regs *regs)
 {
-	generic_handle_domain_irq(nvic_irq_domain, hwirq);
-}
+	unsigned long icsr = readl_relaxed(BASEADDR_V7M_SCB + V7M_SCB_ICSR);
+	irq_hw_number_t hwirq = (icsr & V7M_SCB_ICSR_VECTACTIVE) - 16;
 
-/*
- * TODO: restructure the ARMv7M entry logic so that this entry logic can live
- * in arch code.
- */
-asmlinkage void __exception_irq_entry
-nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
-{
-	struct pt_regs *old_regs;
-
-	irq_enter();
-	old_regs = set_irq_regs(regs);
-	__nvic_handle_irq(hwirq);
-	set_irq_regs(old_regs);
-	irq_exit();
+	generic_handle_domain_irq(nvic_irq_domain, hwirq);
 }
 
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
@@ -141,6 +128,7 @@ static int __init nvic_of_init(struct device_node *node,
 	for (i = 0; i < irqs; i += 4)
 		writel_relaxed(0, nvic_base + NVIC_IPR + i);
 
+	set_handle_irq(nvic_handle_irq);
 	return 0;
 }
 IRQCHIP_DECLARE(armv7m_nvic, "arm,armv7m-nvic", nvic_of_init);
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:20 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:20 +0100
Subject: [PATCH v5 08/32] ARM: decompressor: disable stack protector
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-9-ardb@kernel.org>

Enabling the stack protector in the decompressor is of dubious value,
given that it uses a fixed value for the canary, cannot print any output
unless CONFIG_DEBUG_LL is enabled (which relies on board specific build
time settings), and is already disabled for a good chunk of the code
(libfdt).

So let's just disable it in the decompressor. This will make it easier
in the future to manage the command line options that would need to be
removed again in this context for the TLS register based stack
protector.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/boot/compressed/Makefile | 6 +-----
 arch/arm/boot/compressed/misc.c   | 7 -------
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 954eee8a785a..187a187706cb 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -92,17 +92,13 @@ ifeq ($(CONFIG_USE_OF),y)
 OBJS	+= $(libfdt_objs) fdt_check_mem_start.o
 endif
 
-# -fstack-protector-strong triggers protection checks in this code,
-# but it is being used too early to link to meaningful stack_chk logic.
-$(foreach o, $(libfdt_objs) atags_to_fdt.o fdt_check_mem_start.o, \
-	$(eval CFLAGS_$(o) := -I $(srctree)/scripts/dtc/libfdt -fno-stack-protector))
-
 targets       := vmlinux vmlinux.lds piggy_data piggy.o \
 		 head.o $(OBJS)
 
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
 
 ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin \
+	     -I$(srctree)/scripts/dtc/libfdt -fno-stack-protector \
 	     -I$(obj) $(DISABLE_ARM_SSP_PER_TASK_PLUGIN)
 ccflags-remove-$(CONFIG_FUNCTION_TRACER) += -pg
 asflags-y := -DZIMAGE
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index e1e9a5dde853..c3c66ff2d696 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -128,13 +128,6 @@ asmlinkage void __div0(void)
 	error("Attempting division by 0!");
 }
 
-const unsigned long __stack_chk_guard = 0x000a0dff;
-
-void __stack_chk_fail(void)
-{
-	error("stack-protector: Kernel stack is corrupted\n");
-}
-
 extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
 
 
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:21 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:21 +0100
Subject: [PATCH v5 09/32] ARM: stackprotector: prefer compiler for TLS based
 per-task protector
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-10-ardb@kernel.org>

Currently, we implement the per-task stack protector for ARM using a GCC
plugin, due to lack of native compiler support. However, work is
underway to get this implemented in the compiler, which means we will be
able to deprecate the GCC plugin at some point.

In the meantime, we will need to support both, where the native compiler
implementation is obviously preferred. So let's wire this up in Kconfig
and the Makefile.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig  | 8 ++++++--
 arch/arm/Makefile | 9 +++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7528cbdb90a1..99ac5d75dcec 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1596,10 +1596,14 @@ config XEN
 	help
 	  Say Y if you want to run Linux in a Virtual Machine on Xen on ARM.
 
+config CC_HAVE_STACKPROTECTOR_TLS
+	def_bool $(cc-option,-mtp=cp15 -mstack-protector-guard=tls -mstack-protector-guard-offset=0)
+
 config STACKPROTECTOR_PER_TASK
 	bool "Use a unique stack canary value for each task"
-	depends on GCC_PLUGINS && STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
-	select GCC_PLUGIN_ARM_SSP_PER_TASK
+	depends on STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
+	depends on GCC_PLUGINS || CC_HAVE_STACKPROTECTOR_TLS
+	select GCC_PLUGIN_ARM_SSP_PER_TASK if !CC_HAVE_STACKPROTECTOR_TLS
 	default y
 	help
 	  Due to the fact that GCC uses an ordinary symbol reference from
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77172d555c7e..e943624cbf87 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -275,6 +275,14 @@ endif
 
 ifeq ($(CONFIG_STACKPROTECTOR_PER_TASK),y)
 prepare: stack_protector_prepare
+ifeq ($(CONFIG_CC_HAVE_STACKPROTECTOR_TLS),y)
+stack_protector_prepare: prepare0
+	$(eval KBUILD_CFLAGS += \
+		-mstack-protector-guard=tls \
+		-mstack-protector-guard-offset=$(shell	\
+			awk '{if ($$2 == "TSK_STACK_CANARY") print $$3;}'\
+				include/generated/asm-offsets.h))
+else
 stack_protector_prepare: prepare0
 	$(eval SSP_PLUGIN_CFLAGS := \
 		-fplugin-arg-arm_ssp_per_task_plugin-offset=$(shell	\
@@ -283,6 +291,7 @@ stack_protector_prepare: prepare0
 	$(eval KBUILD_CFLAGS += $(SSP_PLUGIN_CFLAGS))
 	$(eval GCC_PLUGINS_CFLAGS += $(SSP_PLUGIN_CFLAGS))
 endif
+endif
 
 all:	$(notdir $(KBUILD_IMAGE))
 
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:22 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:22 +0100
Subject: [PATCH v5 10/32] ARM: entry: preserve thread_info pointer in switch_to
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-11-ardb@kernel.org>

Tweak the UP stack protector handling code so that the thread info
pointer is preserved in R7 until set_current is called. This is needed
for a subsequent patch that implements THREAD_INFO_IN_TASK and
set_current for UP as well.

This also means we will prefer the per-task protector on UP systems that
implement the thread ID registers, so tweak the preprocessor
conditionals to reflect this.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/kernel/entry-armv.S | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 9d9372781408..5e01a34369a0 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -744,16 +744,16 @@ ENTRY(__switch_to)
 	ldr	r6, [r2, #TI_CPU_DOMAIN]
 #endif
 	switch_tls r1, r4, r5, r3, r7
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
-	ldr	r7, [r2, #TI_TASK]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+    !defined(CONFIG_STACKPROTECTOR_PER_TASK)
+	ldr	r9, [r2, #TI_TASK]
 	ldr	r8, =__stack_chk_guard
 	.if (TSK_STACK_CANARY > IMM12_MASK)
-	add	r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK
+	add	r9, r9, #TSK_STACK_CANARY & ~IMM12_MASK
 	.endif
-	ldr	r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]
-#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO)
-	mov	r7, r2				@ Preserve 'next'
+	ldr	r9, [r9, #TSK_STACK_CANARY & IMM12_MASK]
 #endif
+	mov	r7, r2				@ Preserve 'next'
 #ifdef CONFIG_CPU_USE_DOMAINS
 	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
 #endif
@@ -762,8 +762,9 @@ ENTRY(__switch_to)
 	ldr	r0, =thread_notify_head
 	mov	r1, #THREAD_NOTIFY_SWITCH
 	bl	atomic_notifier_call_chain
-#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
-	str	r7, [r8]
+#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
+    !defined(CONFIG_STACKPROTECTOR_PER_TASK)
+	str	r9, [r8]
 #endif
  THUMB(	mov	ip, r4			   )
 	mov	r0, r5
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:23 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:23 +0100
Subject: [PATCH v5 11/32] ARM: module: implement support for PC-relative group
 relocations
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-12-ardb@kernel.org>

Add support for the R_ARM_ALU_PC_Gn_NC and R_ARM_LDR_PC_G2 group
relocations [0] so we can use them in modules. These will be used to
load the current task pointer from a global variable without having to
rely on a literal pool entry to carry the address of this variable,
which may have a significant negative impact on cache utilization for
variables that are used often and in many different places, as each
occurrence will result in a literal pool entry and therefore a line in
the D-cache.

[0] 'ELF for the ARM architecture'
    https://github.com/ARM-software/abi-aa/releases

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/elf.h |  3 +
 arch/arm/kernel/module.c   | 90 ++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index b8102a6ddf16..d68101655b74 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -61,6 +61,9 @@ typedef struct user_fp elf_fpregset_t;
 #define R_ARM_MOVT_ABS		44
 #define R_ARM_MOVW_PREL_NC	45
 #define R_ARM_MOVT_PREL		46
+#define R_ARM_ALU_PC_G0_NC	57
+#define R_ARM_ALU_PC_G1_NC	59
+#define R_ARM_LDR_PC_G2		63
 
 #define R_ARM_THM_CALL		10
 #define R_ARM_THM_JUMP24	30
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index beac45e89ba6..49ff7fd18f0c 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -68,6 +68,44 @@ bool module_exit_section(const char *name)
 		strstarts(name, ".ARM.exidx.exit");
 }
 
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+/*
+ * This implements the partitioning algorithm for group relocations as
+ * documented in the ARM AArch32 ELF psABI (IHI 0044).
+ *
+ * A single PC-relative symbol reference is divided in up to 3 add or subtract
+ * operations, where the final one could be incorporated into a load/store
+ * instruction with immediate offset. E.g.,
+ *
+ *   ADD	Rd, PC, #...		or	ADD	Rd, PC, #...
+ *   ADD	Rd, Rd, #...			ADD	Rd, Rd, #...
+ *   LDR	Rd, [Rd, #...]			ADD	Rd, Rd, #...
+ *
+ * The latter has a guaranteed range of only 16 MiB (3x8 == 24 bits), so it is
+ * of limited use in the kernel. However, the ADD/ADD/LDR combo has a range of
+ * -/+ 256 MiB, (2x8 + 12 == 28 bits), which means it has sufficient range for
+ * any in-kernel symbol reference (unless module PLTs are being used).
+ *
+ * The main advantage of this approach over the typical pattern using a literal
+ * load is that literal loads may miss in the D-cache, and generally lead to
+ * lower cache efficiency for variables that are referenced often from many
+ * different places in the code.
+ */
+static u32 get_group_rem(u32 group, u32 *offset)
+{
+	u32 val = *offset;
+	u32 shift;
+	do {
+		shift = val ? (31 - __fls(val)) & ~1 : 32;
+		*offset = val;
+		if (!val)
+			break;
+		val &= 0xffffff >> shift;
+	} while (group--);
+	return shift;
+}
+#endif
+
 int
 apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 	       unsigned int relindex, struct module *module)
@@ -87,6 +125,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 #ifdef CONFIG_THUMB2_KERNEL
 		u32 upper, lower, sign, j1, j2;
 #endif
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+		u32 shift, group = 1;
+#endif
 
 		offset = ELF32_R_SYM(rel->r_info);
 		if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
@@ -331,6 +372,55 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			*(u16 *)(loc + 2) = __opcode_to_mem_thumb16(lower);
 			break;
 #endif
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
+		case R_ARM_ALU_PC_G0_NC:
+			group = 0;
+			fallthrough;
+		case R_ARM_ALU_PC_G1_NC:
+			tmp = __mem_to_opcode_arm(*(u32 *)loc);
+			offset = ror32(tmp & 0xff, (tmp & 0xf00) >> 7);
+			if (tmp & BIT(22))
+				offset = -offset;
+			offset += sym->st_value - loc;
+			if (offset < 0) {
+				offset = -offset;
+				tmp = (tmp & ~BIT(23)) | BIT(22); // SUB opcode
+			} else {
+				tmp = (tmp & ~BIT(22)) | BIT(23); // ADD opcode
+			}
+
+			shift = get_group_rem(group, &offset);
+			if (shift < 24) {
+				offset >>= 24 - shift;
+				offset |= (shift + 8) << 7;
+			}
+			*(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+			break;
+
+		case R_ARM_LDR_PC_G2:
+			tmp = __mem_to_opcode_arm(*(u32 *)loc);
+			offset = tmp & 0xfff;
+			if (~tmp & BIT(23))		// U bit cleared?
+				offset = -offset;
+			offset += sym->st_value - loc;
+			if (offset < 0) {
+				offset = -offset;
+				tmp &= ~BIT(23);	// clear U bit
+			} else {
+				tmp |= BIT(23);		// set U bit
+			}
+			get_group_rem(2, &offset);
+
+			if (offset > 0xfff) {
+				pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+				       module->name, relindex, i, symname,
+				       ELF32_R_TYPE(rel->r_info), loc,
+				       sym->st_value);
+				return -ENOEXEC;
+			}
+			*(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
+			break;
+#endif
 
 		default:
 			pr_err("%s: unknown relocation: %u\n",
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:24 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:24 +0100
Subject: [PATCH v5 12/32] ARM: assembler: add optimized ldr/str macros to load
 variables from memory
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-13-ardb@kernel.org>

We will be adding variable loads to various hot paths, so it makes sense
to add a helper macro that can load variables from asm code without the
use of literal pool entries. On v7 or later, we can simply use MOVW/MOVT
pairs, but on earlier cores, this requires a bit of hackery to emit a
instruction sequence that implements this using a sequence of ADD/LDR
instructions.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig                 | 11 +++++
 arch/arm/include/asm/assembler.h | 48 ++++++++++++++++++--
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 99ac5d75dcec..9586636289d2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -139,6 +139,17 @@ config ARM
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
+config ARM_HAS_GROUP_RELOCS
+	def_bool y
+	depends on !LD_IS_LLD || LLD_VERSION >= 140000
+	depends on !COMPILE_TEST
+	help
+	  Whether or not to use R_ARM_ALU_PC_Gn or R_ARM_LDR_PC_Gn group
+	  relocations, which have been around for a long time, but were not
+	  supported in LLD until version 14. The combined range is -/+ 256 MiB,
+	  which is usually sufficient, but not for allyesconfig, so we disable
+	  this feature when doing compile testing.
+
 config ARM_HAS_SG_CHAIN
 	bool
 
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7d23d4bb2168..7a4e292b68e4 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -564,12 +564,12 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	/*
 	 * mov_l - move a constant value or [relocated] address into a register
 	 */
-	.macro		mov_l, dst:req, imm:req
+	.macro		mov_l, dst:req, imm:req, cond
 	.if		__LINUX_ARM_ARCH__ < 7
-	ldr		\dst, =\imm
+	ldr\cond	\dst, =\imm
 	.else
-	movw		\dst, #:lower16:\imm
-	movt		\dst, #:upper16:\imm
+	movw\cond	\dst, #:lower16:\imm
+	movt\cond	\dst, #:upper16:\imm
 	.endif
 	.endm
 
@@ -607,6 +607,46 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	__adldst_l	str, \src, \sym, \tmp, \cond
 	.endm
 
+	.macro		__ldst_va, op, reg, tmp, sym, offset=0, cond
+#if __LINUX_ARM_ARCH__ >= 7 || \
+    !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+    (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+	mov_l		\tmp, \sym, \cond
+#else
+	/*
+	 * Avoid a literal load, by emitting a sequence of ADD/LDR instructions
+	 * with the appropriate relocations. The combined sequence has a range
+	 * of -/+ 256 MiB, which should be sufficient for the core kernel and
+	 * for modules loaded into the module region.
+	 */
+	.globl		\sym
+	.reloc		.L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+	.reloc		.L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+	.reloc		.L2_\@, R_ARM_LDR_PC_G2, \sym
+.L0_\@: sub\cond	\tmp, pc, #8 - \offset
+.L1_\@: sub\cond	\tmp, \tmp, #4 - \offset
+#endif
+.L2_\@: \op\cond	\reg, [\tmp, #\offset]
+	.endm
+
+	/*
+	 * ldr_va - load a 32-bit word from the virtual address of \sym
+	 */
+	.macro		ldr_va, rd:req, sym:req, cond, tmp, offset
+	.ifb		\tmp
+	__ldst_va	ldr, \rd, \rd, \sym, \offset, \cond
+	.else
+	__ldst_va	ldr, \rd, \tmp, \sym, \offset, \cond
+	.endif
+	.endm
+
+	/*
+	 * str_va - store a 32-bit word to the virtual address of \sym
+	 */
+	.macro		str_va, rn:req, sym:req, tmp:req
+	__ldst_va	str, \rn, \tmp, \sym
+	.endm
+
 	/*
 	 * rev_l - byte-swap a 32-bit value
 	 *
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:25 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:25 +0100
Subject: [PATCH v5 13/32] ARM: percpu: add SMP_ON_UP support
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-14-ardb@kernel.org>

Permit the use of the TPIDRPRW system register for carrying the per-CPU
offset in generic SMP configurations that also target non-SMP capable
ARMv6 cores. This uses the SMP_ON_UP code patching framework to turn all
TPIDRPRW accesses into reads/writes of entry #0 in the __per_cpu_offset
array.

While at it, switch over some existing direct TPIDRPRW accesses in asm
code to invocations of a new helper that is patched in the same way when
necessary.

Note that CPU_V6+SMP without SMP_ON_UP results in a kernel that does not
boot on v6 CPUs without SMP extensions, so add this dependency to
Kconfig as well.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/assembler.h | 61 +++++++++++++++++++-
 arch/arm/include/asm/insn.h      | 17 ++++++
 arch/arm/include/asm/percpu.h    | 36 ++++++++++--
 arch/arm/mm/Kconfig              |  1 +
 4 files changed, 108 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7a4e292b68e4..30752c4427d4 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -216,9 +216,7 @@
 
 	.macro	reload_current, t1:req, t2:req
 #ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
-	adr_l	\t1, __entry_task		@ get __entry_task base address
-	mrc	p15, 0, \t2, c13, c0, 4		@ get per-CPU offset
-	ldr	\t1, [\t1, \t2]			@ load variable
+	ldr_this_cpu \t1, __entry_task, \t1, \t2
 	mcr	p15, 0, \t1, c13, c0, 3		@ store in TPIDRURO
 #endif
 	.endm
@@ -308,6 +306,26 @@
 #define ALT_UP_B(label) b label
 #endif
 
+	/*
+	 * this_cpu_offset - load the per-CPU offset of this CPU into
+	 * 		     register 'rd'
+	 */
+	.macro		this_cpu_offset, rd:req
+#ifdef CONFIG_SMP
+ALT_SMP(mrc		p15, 0, \rd, c13, c0, 4)
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+	.subsection	1
+.L0_\@: ldr_va		\rd, __per_cpu_offset
+	b		.L1_\@
+	.previous
+.L1_\@:
+#endif
+#else
+	mov		\rd, #0
+#endif
+	.endm
+
 /*
  * Instruction barrier
  */
@@ -647,6 +665,43 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	__ldst_va	str, \rn, \tmp, \sym
 	.endm
 
+	/*
+	 * ldr_this_cpu_armv6 - Load a 32-bit word from the per-CPU variable 'sym',
+	 *			without using a temp register. Supported in ARM mode
+	 *			only.
+	 */
+	.macro		ldr_this_cpu_armv6, rd:req, sym:req
+	this_cpu_offset	\rd
+	.globl		\sym
+	.reloc		.L0_\@, R_ARM_ALU_PC_G0_NC, \sym
+	.reloc		.L1_\@, R_ARM_ALU_PC_G1_NC, \sym
+	.reloc		.L2_\@, R_ARM_LDR_PC_G2, \sym
+	add		\rd, \rd, pc
+.L0_\@: sub		\rd, \rd, #4
+.L1_\@: sub		\rd, \rd, #0
+.L2_\@: ldr		\rd, [\rd, #4]
+	.endm
+
+	/*
+	 * ldr_this_cpu - Load a 32-bit word from the per-CPU variable 'sym'
+	 *		  into register 'rd', which may be the stack pointer,
+	 *		  using 't1' and 't2' as general temp registers. These
+	 *		  are permitted to overlap with 'rd' if != sp
+	 */
+	.macro		ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
+#ifndef CONFIG_SMP
+	ldr_va		\rd, \sym,, \t1			@ CPU offset == 0x0
+#elif __LINUX_ARM_ARCH__ >= 7 || \
+      !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+      (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+	this_cpu_offset	\t1
+	mov_l		\t2, \sym
+	ldr		\rd, [\t1, \t2]
+#else
+	ldr_this_cpu_armv6 \rd, \sym
+#endif
+	.endm
+
 	/*
 	 * rev_l - byte-swap a 32-bit value
 	 *
diff --git a/arch/arm/include/asm/insn.h b/arch/arm/include/asm/insn.h
index 5475cbf9fb6b..faf3d1c28368 100644
--- a/arch/arm/include/asm/insn.h
+++ b/arch/arm/include/asm/insn.h
@@ -2,6 +2,23 @@
 #ifndef __ASM_ARM_INSN_H
 #define __ASM_ARM_INSN_H
 
+#include <linux/types.h>
+
+/*
+ * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
+ * appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
+ * which should be sufficient for the core kernel as well as modules loaded
+ * into the module region. (Not supported by LLD before release 14)
+ */
+#define LOAD_SYM_ARMV6(reg, sym)					\
+	"	.globl	" #sym "				\n\t"	\
+	"	.reloc	10f, R_ARM_ALU_PC_G0_NC, " #sym "	\n\t"	\
+	"	.reloc	11f, R_ARM_ALU_PC_G1_NC, " #sym "	\n\t"	\
+	"	.reloc	12f, R_ARM_LDR_PC_G2, " #sym "		\n\t"	\
+	"10:	sub	" #reg ", pc, #8			\n\t"	\
+	"11:	sub	" #reg ", " #reg ", #4			\n\t"	\
+	"12:	ldr	" #reg ", [" #reg ", #0]		\n\t"
+
 static inline unsigned long
 arm_gen_nop(void)
 {
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index e2fcb3cfd3de..7feba9d65e85 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -5,20 +5,27 @@
 #ifndef _ASM_ARM_PERCPU_H_
 #define _ASM_ARM_PERCPU_H_
 
+#include <asm/insn.h>
+
 register unsigned long current_stack_pointer asm ("sp");
 
 /*
  * Same as asm-generic/percpu.h, except that we store the per cpu offset
  * in the TPIDRPRW. TPIDRPRW only exists on V6K and V7
  */
-#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6)
+#ifdef CONFIG_SMP
 static inline void set_my_cpu_offset(unsigned long off)
 {
+	extern unsigned int smp_on_up;
+
+	if (IS_ENABLED(CONFIG_CPU_V6) && !smp_on_up)
+		return;
+
 	/* Set TPIDRPRW */
 	asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
 }
 
-static inline unsigned long __my_cpu_offset(void)
+static __always_inline unsigned long __my_cpu_offset(void)
 {
 	unsigned long off;
 
@@ -27,8 +34,29 @@ static inline unsigned long __my_cpu_offset(void)
 	 * We want to allow caching the value, so avoid using volatile and
 	 * instead use a fake stack read to hazard against barrier().
 	 */
-	asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off)
-		: "Q" (*(const unsigned long *)current_stack_pointer));
+	asm("0:	mrc p15, 0, %0, c13, c0, 4			\n\t"
+#ifdef CONFIG_CPU_V6
+	    "1:							\n\t"
+	    "	.subsection 1					\n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+    !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+	    "2: " LOAD_SYM_ARMV6(%0, __per_cpu_offset) "	\n\t"
+	    "	b	1b					\n\t"
+#else
+	    "2: ldr	%0, 3f					\n\t"
+	    "	ldr	%0, [%0]				\n\t"
+	    "	b	1b					\n\t"
+	    "3:	.long	__per_cpu_offset			\n\t"
+#endif
+	    "	.previous					\n\t"
+	    "	.pushsection \".alt.smp.init\", \"a\"		\n\t"
+	    "	.align	2					\n\t"
+	    "	.long	0b - .					\n\t"
+	    "	b	. + (2b - 0b)				\n\t"
+	    "	.popsection					\n\t"
+#endif
+	    : "=r" (off)
+	    : "Q" (*(const unsigned long *)current_stack_pointer));
 
 	return off;
 }
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 58afba346729..a91ff22c6c2e 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -386,6 +386,7 @@ config CPU_V6
 	select CPU_PABRT_V6
 	select CPU_THUMB_CAPABLE
 	select CPU_TLB_V6 if MMU
+	select SMP_ON_UP if SMP
 
 # ARMv6k
 config CPU_V6K
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:26 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:26 +0100
Subject: [PATCH v5 14/32] ARM: use TLS register for 'current' on !SMP as well
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-15-ardb@kernel.org>

Enable the use of the TLS register to hold the 'current' pointer also on
non-SMP configurations that target v6k or later CPUs. This will permit
the use of THREAD_INFO_IN_TASK as well as IRQ stacks and vmap'ed stacks
for such configurations.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Acked-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9586636289d2..0e1b93de10b4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1163,7 +1163,7 @@ config SMP_ON_UP
 
 config CURRENT_POINTER_IN_TPIDRURO
 	def_bool y
-	depends on SMP && CPU_32v6K && !CPU_V6
+	depends on CPU_32v6K && !CPU_V6
 
 config ARM_CPU_TOPOLOGY
 	bool "Support cpu topology definition"
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:27 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:27 +0100
Subject: [PATCH v5 15/32] ARM: smp: defer TPIDRURO update for SMP v6
 configurations too
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-16-ardb@kernel.org>

Defer TPIDURO updates for user space until exit also for CPU_V6+SMP
configurations so that we can decide at runtime whether to use it to
carry the current pointer, provided that we are running on a CPU that
actually implements this register. This is needed for
THREAD_INFO_IN_TASK support for UP systems, which requires that all SMP
capable systems use the TPIDRURO based access to 'current' as the only
remaining alternative will be a global variable which only works on UP.

Given that SMP implies support for HWCAP_TLS, we can patch away the
hwcap test entirely from the context switch path rather than just the
TPIDRURO assignment when running on SMP hardware.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/tls.h     | 30 +++++++++++++-------
 arch/arm/kernel/entry-header.S |  8 +++++-
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index c3296499176c..de254347acf6 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -18,21 +18,31 @@
 	.endm
 
 	.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
-	ldr	\tmp1, =elf_hwcap
-	ldr	\tmp1, [\tmp1, #0]
+#ifdef CONFIG_SMP
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+	.subsection 1
+#endif
+.L0_\@: ldr_va	\tmp1, elf_hwcap
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
-	mrcne	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
-	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
-	mcrne	p15, 0, \tpuser, c13, c0, 2	@ set user r/w register
-	strne	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+	beq	.L2_\@
+	mcr	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+#ifdef CONFIG_SMP
+	b	.L1_\@
+	.previous
+#endif
+.L1_\@: switch_tls_v6k \base, \tp, \tpuser, \tmp1, \tmp2
+.L2_\@:
 	.endm
 
 	.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
 	mov	\tmp1, #0xffff0fff
 	str	\tp, [\tmp1, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
+#else
+#include <asm/smp_plat.h>
 #endif
 
 #ifdef CONFIG_TLS_REG_EMUL
@@ -43,7 +53,7 @@
 #elif defined(CONFIG_CPU_V6)
 #define tls_emu		0
 #define has_tls_reg		(elf_hwcap & HWCAP_TLS)
-#define defer_tls_reg_update	0
+#define defer_tls_reg_update	is_smp()
 #define switch_tls	switch_tls_v6
 #elif defined(CONFIG_CPU_32v6K)
 #define tls_emu		0
@@ -81,11 +91,11 @@ static inline void set_tls(unsigned long val)
 	 */
 	barrier();
 
-	if (!tls_emu && !defer_tls_reg_update) {
-		if (has_tls_reg) {
+	if (!tls_emu) {
+		if (has_tls_reg && !defer_tls_reg_update) {
 			asm("mcr p15, 0, %0, c13, c0, 3"
 			    : : "r" (val));
-		} else {
+		} else if (!has_tls_reg) {
 #ifdef CONFIG_KUSER_HELPERS
 			/*
 			 * User space must never try to access this
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index ae24dd54e9ef..da206bd4f194 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -292,12 +292,18 @@
 
 
 	.macro	restore_user_regs, fast = 0, offset = 0
-#if defined(CONFIG_CPU_32v6K) && !defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_32v6K) && \
+    (!defined(CONFIG_CPU_V6) || defined(CONFIG_SMP))
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L1_\@)
+#endif
 	@ The TLS register update is deferred until return to user space so we
 	@ can use it for other things while running in the kernel
 	get_thread_info r1
 	ldr	r1, [r1, #TI_TP_VALUE]
 	mcr	p15, 0, r1, c13, c0, 3		@ set TLS register
+.L1_\@:
 #endif
 
 	uaccess_enable r1, isb=0
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:28 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:28 +0100
Subject: [PATCH v5 16/32] ARM: implement THREAD_INFO_IN_TASK for uniprocessor
 systems
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-17-ardb@kernel.org>

On UP systems, only a single task can be 'current' at the same time,
which means we can use a global variable to track it. This means we can
also enable THREAD_INFO_IN_TASK for those systems, as in that case,
thread_info is accessed via current rather than the other way around,
removing the need to store thread_info at the base of the task stack.
This, in turn, permits us to enable IRQ stacks and vmap'ed stacks on UP
systems as well.

To partially mitigate the performance overhead of this arrangement, use
a ADD/ADD/LDR sequence with the appropriate PC-relative group
relocations to load the value of current when needed. This means that
accessing current will still only require a single load as before,
avoiding the need for a literal to carry the address of the global
variable in each function. However, accessing thread_info will now
require this load as well.

Acked-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig                   |  4 +-
 arch/arm/include/asm/assembler.h   | 83 +++++++++++++-------
 arch/arm/include/asm/current.h     | 47 +++++++----
 arch/arm/include/asm/switch_to.h   |  3 +-
 arch/arm/include/asm/thread_info.h | 27 -------
 arch/arm/kernel/asm-offsets.c      |  3 -
 arch/arm/kernel/entry-armv.S       |  9 ++-
 arch/arm/kernel/entry-header.S     |  2 +-
 arch/arm/kernel/entry-v7m.S        | 10 ++-
 arch/arm/kernel/head-common.S      |  4 +-
 arch/arm/kernel/process.c          |  7 +-
 arch/arm/kernel/smp.c              |  6 ++
 12 files changed, 115 insertions(+), 90 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0e1b93de10b4..108a7a872084 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -127,7 +127,7 @@ config ARM
 	select PERF_USE_VMALLOC
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
-	select THREAD_INFO_IN_TASK if CURRENT_POINTER_IN_TPIDRURO
+	select THREAD_INFO_IN_TASK
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
@@ -1612,7 +1612,7 @@ config CC_HAVE_STACKPROTECTOR_TLS
 
 config STACKPROTECTOR_PER_TASK
 	bool "Use a unique stack canary value for each task"
-	depends on STACKPROTECTOR && THREAD_INFO_IN_TASK && !XIP_DEFLATED_DATA
+	depends on STACKPROTECTOR && CURRENT_POINTER_IN_TPIDRURO && !XIP_DEFLATED_DATA
 	depends on GCC_PLUGINS || CC_HAVE_STACKPROTECTOR_TLS
 	select GCC_PLUGIN_ARM_SSP_PER_TASK if !CC_HAVE_STACKPROTECTOR_TLS
 	default y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 30752c4427d4..bf304596f87e 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -199,41 +199,12 @@
 	.endm
 	.endr
 
-	.macro	get_current, rd
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
-	mrc	p15, 0, \rd, c13, c0, 3		@ get TPIDRURO register
-#else
-	get_thread_info \rd
-	ldr	\rd, [\rd, #TI_TASK]
-#endif
-	.endm
-
-	.macro	set_current, rn
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
-	mcr	p15, 0, \rn, c13, c0, 3		@ set TPIDRURO register
-#endif
-	.endm
-
-	.macro	reload_current, t1:req, t2:req
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
-	ldr_this_cpu \t1, __entry_task, \t1, \t2
-	mcr	p15, 0, \t1, c13, c0, 3		@ store in TPIDRURO
-#endif
-	.endm
-
 /*
  * Get current thread_info.
  */
 	.macro	get_thread_info, rd
-#ifdef CONFIG_THREAD_INFO_IN_TASK
 	/* thread_info is the first member of struct task_struct */
 	get_current \rd
-#else
- ARM(	mov	\rd, sp, lsr #THREAD_SIZE_ORDER + PAGE_SHIFT	)
- THUMB(	mov	\rd, sp			)
- THUMB(	lsr	\rd, \rd, #THREAD_SIZE_ORDER + PAGE_SHIFT	)
-	mov	\rd, \rd, lsl #THREAD_SIZE_ORDER + PAGE_SHIFT
-#endif
 	.endm
 
 /*
@@ -326,6 +297,60 @@ ALT_UP_B(.L0_\@)
 #endif
 	.endm
 
+	/*
+	 * set_current - store the task pointer of this CPU's current task
+	 */
+	.macro		set_current, rn:req, tmp:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998:	mcr		p15, 0, \rn, c13, c0, 3		@ set TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+	.subsection	1
+.L0_\@: str_va		\rn, __current, \tmp
+	b		.L1_\@
+	.previous
+.L1_\@:
+#endif
+#else
+	str_va		\rn, __current, \tmp
+#endif
+	.endm
+
+	/*
+	 * get_current - load the task pointer of this CPU's current task
+	 */
+	.macro		get_current, rd:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+9998:	mrc		p15, 0, \rd, c13, c0, 3		@ get TPIDRURO register
+#ifdef CONFIG_CPU_V6
+ALT_UP_B(.L0_\@)
+	.subsection	1
+.L0_\@: ldr_va		\rd, __current
+	b		.L1_\@
+	.previous
+.L1_\@:
+#endif
+#else
+	ldr_va		\rd, __current
+#endif
+	.endm
+
+	/*
+	 * reload_current - reload the task pointer of this CPU's current task
+	 *		    into the TLS register
+	 */
+	.macro		reload_current, t1:req, t2:req
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+#endif
+	ldr_this_cpu	\t1, __entry_task, \t1, \t2
+	mcr		p15, 0, \t1, c13, c0, 3		@ store in TPIDRURO
+.L0_\@:
+#endif
+	.endm
+
 /*
  * Instruction barrier
  */
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 6bf0aad672c3..c03706869384 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -8,25 +8,18 @@
 #define _ASM_ARM_CURRENT_H
 
 #ifndef __ASSEMBLY__
+#include <asm/insn.h>
 
 struct task_struct;
 
-static inline void set_current(struct task_struct *cur)
-{
-	if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO))
-		return;
-
-	/* Set TPIDRURO */
-	asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
-}
-
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+extern struct task_struct *__current;
 
-static inline struct task_struct *get_current(void)
+static __always_inline __attribute_const__ struct task_struct *get_current(void)
 {
 	struct task_struct *cur;
 
 #if __has_builtin(__builtin_thread_pointer) && \
+    defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) && \
     !(defined(CONFIG_THUMB2_KERNEL) && \
       defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 130001)
 	/*
@@ -39,16 +32,40 @@ static inline struct task_struct *get_current(void)
 	 * https://github.com/ClangBuiltLinux/linux/issues/1485
 	 */
 	cur = __builtin_thread_pointer();
+#elif defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
+	asm("0:	mrc p15, 0, %0, c13, c0, 3			\n\t"
+#ifdef CONFIG_CPU_V6
+	    "1:							\n\t"
+	    "	.subsection 1					\n\t"
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+    !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+	    "2: " LOAD_SYM_ARMV6(%0, __current) "		\n\t"
+	    "	b	1b					\n\t"
 #else
-	asm("mrc p15, 0, %0, c13, c0, 3" : "=r"(cur));
+	    "2:	ldr	%0, 3f					\n\t"
+	    "	ldr	%0, [%0]				\n\t"
+	    "	b	1b					\n\t"
+	    "3:	.long	__current				\n\t"
+#endif
+	    "	.previous					\n\t"
+	    "	.pushsection \".alt.smp.init\", \"a\"		\n\t"
+	    "	.align	2					\n\t"
+	    "	.long	0b - .					\n\t"
+	    "	b	. + (2b - 0b)				\n\t"
+	    "	.popsection					\n\t"
+#endif
+	    : "=r"(cur));
+#elif __LINUX_ARM_ARCH__>= 7 || \
+      !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+      (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
+	cur = __current;
+#else
+	asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur));
 #endif
 	return cur;
 }
 
 #define current get_current()
-#else
-#include <asm-generic/current.h>
-#endif /* CONFIG_CURRENT_POINTER_IN_TPIDRURO */
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
index 61e4a3c4ca6e..9372348516ce 100644
--- a/arch/arm/include/asm/switch_to.h
+++ b/arch/arm/include/asm/switch_to.h
@@ -3,6 +3,7 @@
 #define __ASM_ARM_SWITCH_TO_H
 
 #include <linux/thread_info.h>
+#include <asm/smp_plat.h>
 
 /*
  * For v7 SMP cores running a preemptible kernel we may be pre-empted
@@ -26,7 +27,7 @@ extern struct task_struct *__switch_to(struct task_struct *, struct thread_info
 #define switch_to(prev,next,last)					\
 do {									\
 	__complete_pending_tlbi();					\
-	if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO))		\
+	if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || is_smp())	\
 		__this_cpu_write(__entry_task, next);			\
 	last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));	\
 } while (0)
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index 164e15f26485..e039d8f12d9b 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -54,9 +54,6 @@ struct cpu_context_save {
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	int			preempt_count;	/* 0 => preemptable, <0 => bug */
-#ifndef CONFIG_THREAD_INFO_IN_TASK
-	struct task_struct	*task;		/* main task structure */
-#endif
 	__u32			cpu;		/* cpu */
 	__u32			cpu_domain;	/* cpu domain */
 	struct cpu_context_save	cpu_context;	/* cpu context */
@@ -72,39 +69,15 @@ struct thread_info {
 
 #define INIT_THREAD_INFO(tsk)						\
 {									\
-	INIT_THREAD_INFO_TASK(tsk)					\
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 }
 
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-#define INIT_THREAD_INFO_TASK(tsk)
-
 static inline struct task_struct *thread_task(struct thread_info* ti)
 {
 	return (struct task_struct *)ti;
 }
 
-#else
-#define INIT_THREAD_INFO_TASK(tsk)	.task = &(tsk),
-
-static inline struct task_struct *thread_task(struct thread_info* ti)
-{
-	return ti->task;
-}
-
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-static inline struct thread_info *current_thread_info(void)
-{
-	return (struct thread_info *)
-		(current_stack_pointer & ~(THREAD_SIZE - 1));
-}
-#endif
-
 #define thread_saved_pc(tsk)	\
 	((unsigned long)(task_thread_info(tsk)->cpu_context.pc))
 #define thread_saved_sp(tsk)	\
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 645845e4982a..2c8d76fd7c66 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -43,9 +43,6 @@ int main(void)
   BLANK();
   DEFINE(TI_FLAGS,		offsetof(struct thread_info, flags));
   DEFINE(TI_PREEMPT,		offsetof(struct thread_info, preempt_count));
-#ifndef CONFIG_THREAD_INFO_IN_TASK
-  DEFINE(TI_TASK,		offsetof(struct thread_info, task));
-#endif
   DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
   DEFINE(TI_CPU_DOMAIN,		offsetof(struct thread_info, cpu_domain));
   DEFINE(TI_CPU_SAVE,		offsetof(struct thread_info, cpu_context));
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 5e01a34369a0..2f912c509e0d 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -746,12 +746,13 @@ ENTRY(__switch_to)
 	switch_tls r1, r4, r5, r3, r7
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
     !defined(CONFIG_STACKPROTECTOR_PER_TASK)
-	ldr	r9, [r2, #TI_TASK]
 	ldr	r8, =__stack_chk_guard
 	.if (TSK_STACK_CANARY > IMM12_MASK)
-	add	r9, r9, #TSK_STACK_CANARY & ~IMM12_MASK
-	.endif
+	add	r9, r2, #TSK_STACK_CANARY & ~IMM12_MASK
 	ldr	r9, [r9, #TSK_STACK_CANARY & IMM12_MASK]
+	.else
+	ldr	r9, [r2, #TSK_STACK_CANARY & IMM12_MASK]
+	.endif
 #endif
 	mov	r7, r2				@ Preserve 'next'
 #ifdef CONFIG_CPU_USE_DOMAINS
@@ -768,7 +769,7 @@ ENTRY(__switch_to)
 #endif
  THUMB(	mov	ip, r4			   )
 	mov	r0, r5
-	set_current r7
+	set_current r7, r8
  ARM(	ldmia	r4, {r4 - sl, fp, sp, pc}  )	@ Load all regs saved previously
  THUMB(	ldmia	ip!, {r4 - sl, fp}	   )	@ Load all regs saved previously
  THUMB(	ldr	sp, [ip], #4		   )
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index da206bd4f194..9f01b229841a 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -300,7 +300,7 @@ ALT_UP_B(.L1_\@)
 #endif
 	@ The TLS register update is deferred until return to user space so we
 	@ can use it for other things while running in the kernel
-	get_thread_info r1
+	mrc	p15, 0, r1, c13, c0, 3		@ get current_thread_info
 	ldr	r1, [r1, #TI_TP_VALUE]
 	mcr	p15, 0, r1, c13, c0, 3		@ set TLS register
 .L1_\@:
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 520dd43e7e08..4e0d318b67c6 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -97,15 +97,17 @@ ENTRY(__switch_to)
 	str	sp, [ip], #4
 	str	lr, [ip], #4
 	mov	r5, r0
+	mov	r6, r2			@ Preserve 'next'
 	add	r4, r2, #TI_CPU_SAVE
 	ldr	r0, =thread_notify_head
 	mov	r1, #THREAD_NOTIFY_SWITCH
 	bl	atomic_notifier_call_chain
-	mov	ip, r4
 	mov	r0, r5
-	ldmia	ip!, {r4 - r11}		@ Load all regs saved previously
-	ldr	sp, [ip]
-	ldr	pc, [ip, #4]!
+	mov	r1, r6
+	ldmia	r4, {r4 - r12, lr}	@ Load all regs saved previously
+	set_current r1, r2
+	mov	sp, ip
+	bx	lr
 	.fnend
 ENDPROC(__switch_to)
 
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index da18e0a17dc2..42cae73fcc19 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -105,10 +105,8 @@ __mmap_switched:
 	mov	r1, #0
 	bl	__memset			@ clear .bss
 
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
 	adr_l	r0, init_task			@ get swapper task_struct
-	set_current r0
-#endif
+	set_current r0, r1
 
 	ldmia	r4, {r0, r1, r2, r3}
 	str	r9, [r0]			@ Save processor ID
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d47159f3791c..0617af11377f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -36,7 +36,7 @@
 
 #include "signal.h"
 
-#ifdef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+#if defined(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || defined(CONFIG_SMP)
 DEFINE_PER_CPU(struct task_struct *, __entry_task);
 #endif
 
@@ -46,6 +46,11 @@ unsigned long __stack_chk_guard __read_mostly;
 EXPORT_SYMBOL(__stack_chk_guard);
 #endif
 
+#ifndef CONFIG_CURRENT_POINTER_IN_TPIDRURO
+asmlinkage struct task_struct *__current;
+EXPORT_SYMBOL(__current);
+#endif
+
 static const char *processor_modes[] __maybe_unused = {
   "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
   "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ed2b168ff46c..73fc645fc4c7 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -400,6 +400,12 @@ static void smp_store_cpu_info(unsigned int cpuid)
 	check_cpu_icache_size(cpuid);
 }
 
+static void set_current(struct task_struct *cur)
+{
+	/* Set TPIDRURO */
+	asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
+}
+
 /*
  * This is the secondary CPU boot entry.  We're using this CPUs
  * idle thread stack, but a set of temporary page tables.
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:29 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:29 +0100
Subject: [PATCH v5 17/32] ARM: assembler: introduce bl_r macro
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-18-ardb@kernel.org>

Add a bl_r macro that abstract the difference between the ways indirect
calls are performed on older and newer ARM architecture revisions.

The main difference is to prefer blx instructions over explicit LR
assignments when possible, as these tend to confuse the prediction logic
in out-of-order cores when speculating across a function return.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/assembler.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index bf304596f87e..7242e9a56650 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -744,4 +744,19 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	.endif
 	.endm
 
+	/*
+	 * bl_r - branch and link to register
+	 *
+	 * @dst: target to branch to
+	 * @c: conditional opcode suffix
+	 */
+	.macro		bl_r, dst:req, c
+	.if		__LINUX_ARM_ARCH__ < 6
+	mov\c		lr, pc
+	mov\c		pc, \dst
+	.else
+	blx\c		\dst
+	.endif
+	.endm
+
 #endif /* __ASM_ASSEMBLER_H__ */
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:30 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:30 +0100
Subject: [PATCH v5 18/32] ARM: unwind: support unwinding across multiple stacks
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-19-ardb@kernel.org>

Implement support in the unwinder for dealing with multiple stacks.
This will be needed once we add support for IRQ stacks, or for the
overflow stack used by the vmap'ed stacks code.

This involves tracking the unwind opcodes that either update the virtual
stack pointer from another virtual register, or perform an explicit
subtract on the virtual stack pointer, and updating the low and high
bounds that we use to sanitize the stack pointer accordingly.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/kernel/unwind.c | 25 +++++++++++++-------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 59fdf257bf8b..9cb9af3fc433 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -52,6 +52,7 @@ EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
 struct unwind_ctrl_block {
 	unsigned long vrs[16];		/* virtual register set */
 	const unsigned long *insn;	/* pointer to the current instructions word */
+	unsigned long sp_low;		/* lowest value of sp allowed */
 	unsigned long sp_high;		/* highest value of sp allowed */
 	/*
 	 * 1 : check for stack overflow for each register pop.
@@ -256,8 +257,12 @@ static int unwind_exec_pop_subset_r4_to_r13(struct unwind_ctrl_block *ctrl,
 		mask >>= 1;
 		reg++;
 	}
-	if (!load_sp)
+	if (!load_sp) {
 		ctrl->vrs[SP] = (unsigned long)vsp;
+	} else {
+		ctrl->sp_low = ctrl->vrs[SP];
+		ctrl->sp_high = ALIGN(ctrl->sp_low, THREAD_SIZE);
+	}
 
 	return URC_OK;
 }
@@ -313,9 +318,10 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
 
 	if ((insn & 0xc0) == 0x00)
 		ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
-	else if ((insn & 0xc0) == 0x40)
+	else if ((insn & 0xc0) == 0x40) {
 		ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
-	else if ((insn & 0xf0) == 0x80) {
+		ctrl->sp_low = ctrl->vrs[SP];
+	} else if ((insn & 0xf0) == 0x80) {
 		unsigned long mask;
 
 		insn = (insn << 8) | unwind_get_byte(ctrl);
@@ -330,9 +336,11 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
 		if (ret)
 			goto error;
 	} else if ((insn & 0xf0) == 0x90 &&
-		   (insn & 0x0d) != 0x0d)
+		   (insn & 0x0d) != 0x0d) {
 		ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
-	else if ((insn & 0xf0) == 0xa0) {
+		ctrl->sp_low = ctrl->vrs[SP];
+		ctrl->sp_high = ALIGN(ctrl->sp_low, THREAD_SIZE);
+	} else if ((insn & 0xf0) == 0xa0) {
 		ret = unwind_exec_pop_r4_to_rN(ctrl, insn);
 		if (ret)
 			goto error;
@@ -375,13 +383,12 @@ static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
  */
 int unwind_frame(struct stackframe *frame)
 {
-	unsigned long low;
 	const struct unwind_idx *idx;
 	struct unwind_ctrl_block ctrl;
 
 	/* store the highest address on the stack to avoid crossing it*/
-	low = frame->sp;
-	ctrl.sp_high = ALIGN(low, THREAD_SIZE);
+	ctrl.sp_low = frame->sp;
+	ctrl.sp_high = ALIGN(ctrl.sp_low, THREAD_SIZE);
 
 	pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
 		 frame->pc, frame->lr, frame->sp);
@@ -437,7 +444,7 @@ int unwind_frame(struct stackframe *frame)
 		urc = unwind_exec_insn(&ctrl);
 		if (urc < 0)
 			return urc;
-		if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= ctrl.sp_high)
+		if (ctrl.vrs[SP] < ctrl.sp_low || ctrl.vrs[SP] > ctrl.sp_high)
 			return -URC_FAILURE;
 	}
 
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:31 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:31 +0100
Subject: [PATCH v5 19/32] ARM: export dump_mem() to other objects
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-20-ardb@kernel.org>

The unwind info based stack unwinder will make its own call to
dump_mem() to dump the exception stack, so give it external linkage.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/stacktrace.h | 2 ++
 arch/arm/kernel/traps.c           | 7 +++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index 8f54f9ad8a9b..33ee1aa4b8c0 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -36,5 +36,7 @@ void arm_get_current_stackframe(struct pt_regs *regs, struct stackframe *frame)
 extern int unwind_frame(struct stackframe *frame);
 extern void walk_stackframe(struct stackframe *frame,
 			    int (*fn)(struct stackframe *, void *), void *data);
+extern void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+		     unsigned long top);
 
 #endif	/* __ASM_STACKTRACE_H */
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index da04ed85855a..710306eac71f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -35,6 +35,7 @@
 #include <asm/ptrace.h>
 #include <asm/unwind.h>
 #include <asm/tls.h>
+#include <asm/stacktrace.h>
 #include <asm/system_misc.h>
 #include <asm/opcodes.h>
 
@@ -60,8 +61,6 @@ static int __init user_debug_setup(char *str)
 __setup("user_debug=", user_debug_setup);
 #endif
 
-static void dump_mem(const char *, const char *, unsigned long, unsigned long);
-
 void dump_backtrace_entry(unsigned long where, unsigned long from,
 			  unsigned long frame, const char *loglvl)
 {
@@ -120,8 +119,8 @@ static int verify_stack(unsigned long sp)
 /*
  * Dump out the contents of some memory nicely...
  */
-static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
-		     unsigned long top)
+void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+	      unsigned long top)
 {
 	unsigned long first;
 	int i;
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:32 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:32 +0100
Subject: [PATCH v5 20/32] ARM: unwind: dump exception stack from calling frame
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-21-ardb@kernel.org>

The existing code that dumps the contents of the pt_regs structure
passed to __entry routines does so while unwinding the callee frame, and
dereferences the stack pointer as a struct pt_regs*. This will no longer
work when we enable support for IRQ or overflow stacks, because the
struct pt_regs may live on the task stack, while we are executing from
another stack.

The unwinder has access to this information, but only while unwinding
the calling frame. So let's combine the exception stack dumping code
with the handling of the calling frame as well. By printing it before
dumping the caller/callee addresses, the output order is preserved.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/stacktrace.h | 10 ++++++++++
 arch/arm/kernel/traps.c           |  3 ++-
 arch/arm/kernel/unwind.c          |  8 +++++++-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index 33ee1aa4b8c0..d87d60532b86 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -18,6 +18,16 @@ struct stackframe {
 	struct llist_node *kr_cur;
 	struct task_struct *tsk;
 #endif
+#ifdef CONFIG_ARM_UNWIND
+	/*
+	 * This field is used to track the stack pointer value when calling
+	 * __entry routines. This is needed when IRQ stacks and overflow stacks
+	 * are used, because in that case, the struct pt_regs passed to these
+	 * __entry routines may be at the top of the task stack, while we are
+	 * executing from another stack.
+	 */
+	unsigned long sp_low;
+#endif
 };
 
 static __always_inline
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 710306eac71f..c51b87f6fc3e 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -76,7 +76,8 @@ void dump_backtrace_entry(unsigned long where, unsigned long from,
 	printk("%s %ps from %pS\n", loglvl, (void *)where, (void *)from);
 #endif
 
-	if (in_entry_text(from) && end <= ALIGN(frame, THREAD_SIZE))
+	if (!IS_ENABLED(CONFIG_UNWINDER_ARM) &&
+	    in_entry_text(from) && end <= ALIGN(frame, THREAD_SIZE))
 		dump_mem(loglvl, "Exception stack", frame + 4, end);
 }
 
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index 9cb9af3fc433..b7a6141c342f 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -29,6 +29,7 @@
 #include <linux/spinlock.h>
 #include <linux/list.h>
 
+#include <asm/sections.h>
 #include <asm/stacktrace.h>
 #include <asm/traps.h>
 #include <asm/unwind.h>
@@ -459,6 +460,7 @@ int unwind_frame(struct stackframe *frame)
 	frame->sp = ctrl.vrs[SP];
 	frame->lr = ctrl.vrs[LR];
 	frame->pc = ctrl.vrs[PC];
+	frame->sp_low = ctrl.sp_low;
 
 	return URC_OK;
 }
@@ -502,7 +504,11 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk,
 		urc = unwind_frame(&frame);
 		if (urc < 0)
 			break;
-		dump_backtrace_entry(where, frame.pc, frame.sp - 4, loglvl);
+		if (in_entry_text(where))
+			dump_mem(loglvl, "Exception stack", frame.sp_low,
+				 frame.sp_low + sizeof(struct pt_regs));
+
+		dump_backtrace_entry(where, frame.pc, 0, loglvl);
 	}
 }
 
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:33 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:33 +0100
Subject: [PATCH v5 21/32] ARM: backtrace-clang: avoid crash on bogus frame
 pointer
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-22-ardb@kernel.org>

The Clang backtrace code dereferences the link register value pulled
from the stack to decide whether the caller was a branch-and-link
instruction, in order to subsequently decode the offset to find the
start of the calling function. Unlike other loads in this routine, this
one is not protected by a fixup, and may therefore cause a crash if the
address in question is bogus.

So let's fix this, by treating the fault as a failure to decode the 'bl'
instruction. To avoid a label renum, reuse a fixup label that guards an
instruction that cannot fault to begin with.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/lib/backtrace-clang.S | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 5b2cdb1003e3..5b4bca85d06d 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -144,7 +144,7 @@ for_each_frame:	tst	frame, mask		@ Check for address exceptions
  */
 1003:		ldr	sv_lr, [sv_fp, #4]	@ get saved lr from next frame
 
-		ldr	r0, [sv_lr, #-4]	@ get call instruction
+1004:		ldr	r0, [sv_lr, #-4]	@ get call instruction
 		ldr	r3, .Lopcode+4
 		and	r2, r3, r0		@ is this a bl call
 		teq	r2, r3
@@ -164,7 +164,7 @@ finished_setup:
 /*
  * Print the function (sv_pc) and where it was called from (sv_lr).
  */
-1004:		mov	r0, sv_pc
+		mov	r0, sv_pc
 
 		mov	r1, sv_lr
 		mov	r2, frame
@@ -210,7 +210,7 @@ ENDPROC(c_backtrace)
 		.long	1001b, 1006b
 		.long	1002b, 1006b
 		.long	1003b, 1006b
-		.long	1004b, 1006b
+		.long	1004b, finished_setup
 		.long   1005b, 1006b
 		.popsection
 
-- 
2.30.2



From ezequiel at vanguardiasur.com.ar  Mon Jan 24 09:48:56 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 14:48:56 -0300
Subject: [PATCH V3 09/10] media: hantro: Add support for i.MX8MM Hantro-G1
In-Reply-To: <20220124023125.414794-10-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-10-aford173@gmail.com>
Message-ID: <Ye7miOjf0LUruuEk@eze-laptop>

Hi Adam,

On Sun, Jan 23, 2022 at 08:31:23PM -0600, Adam Ford wrote:
> The i.MX8MM has a Hantro G1 video decoder similar to the
> imx8mq but lacks the post-processor present in the imx8mq.
> Add support in the driver for it with the post-processing
> removed.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks a lot,
Ezequiel

> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
> index a670ddd29c4c..b281ac4fb79c 100644
> --- a/drivers/staging/media/hantro/hantro_drv.c
> +++ b/drivers/staging/media/hantro/hantro_drv.c
> @@ -615,6 +615,7 @@ static const struct of_device_id of_hantro_match[] = {
>  	{ .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
>  #endif
>  #ifdef CONFIG_VIDEO_HANTRO_IMX8M
> +	{ .compatible = "nxp,imx8mm-vpu-g1", .data = &imx8mm_vpu_g1_variant, },
>  	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
>  	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
>  	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
> index f0bd2ffe290b..c00b46e06055 100644
> --- a/drivers/staging/media/hantro/hantro_hw.h
> +++ b/drivers/staging/media/hantro/hantro_hw.h
> @@ -299,6 +299,7 @@ enum hantro_enc_fmt {
>  	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
>  };
>  
> +extern const struct hantro_variant imx8mm_vpu_g1_variant;
>  extern const struct hantro_variant imx8mq_vpu_g1_variant;
>  extern const struct hantro_variant imx8mq_vpu_g2_variant;
>  extern const struct hantro_variant imx8mq_vpu_variant;
> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> index 849ea7122d47..9802508bade2 100644
> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> @@ -327,3 +327,15 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
>  	.clk_names = imx8mq_g2_clk_names,
>  	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
>  };
> +
> +const struct hantro_variant imx8mm_vpu_g1_variant = {
> +	.dec_fmts = imx8m_vpu_dec_fmts,
> +	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
> +	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
> +		 HANTRO_H264_DECODER,
> +	.codec_ops = imx8mq_vpu_g1_codec_ops,
> +	.irqs = imx8mq_irqs,
> +	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
> +	.clk_names = imx8mq_g1_clk_names,
> +	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
> +};
> -- 
> 2.32.0
> 


From ardb at kernel.org  Mon Jan 24 09:47:34 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:34 +0100
Subject: [PATCH v5 22/32] ARM: implement IRQ stacks
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-23-ardb@kernel.org>

Now that we no longer rely on the stack pointer to access the current
task struct or thread info, we can implement support for IRQ stacks
cleanly as well.

Define a per-CPU IRQ stack and switch to this stack when taking an IRQ,
provided that we were not already using that stack in the interrupted
context. This is never the case for IRQs taken from user space, but ones
taken while running in the kernel could fire while one taken from user
space has not completed yet.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Acked-by: Nick Desaulniers <ndesaulniers at google.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/include/asm/assembler.h |  4 ++
 arch/arm/kernel/entry-armv.S     | 48 ++++++++++++++++++--
 arch/arm/kernel/entry-v7m.S      | 17 ++++++-
 arch/arm/kernel/irq.c            | 17 +++++++
 arch/arm/kernel/traps.c          | 15 +++++-
 arch/arm/lib/backtrace-clang.S   |  7 +++
 arch/arm/lib/backtrace.S         |  7 +++
 7 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 7242e9a56650..f961f99721dd 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -86,6 +86,10 @@
 
 #define IMM12_MASK 0xfff
 
+/* the frame pointer used for stack unwinding */
+ARM(	fpreg	.req	r11	)
+THUMB(	fpreg	.req	r7	)
+
 /*
  * Enable and disable interrupts
  */
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2f912c509e0d..38e3978a50a9 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -32,9 +32,51 @@
 /*
  * Interrupt handling.
  */
-	.macro	irq_handler
+	.macro	irq_handler, from_user:req
 	mov	r0, sp
+#ifdef CONFIG_UNWINDER_ARM
+	mov	fpreg, sp		@ Preserve original SP
+#else
+	mov	r7, fp			@ Preserve original FP
+	mov	r8, sp			@ Preserve original SP
+#endif
+	ldr_this_cpu sp, irq_stack_ptr, r2, r3
+	.if	\from_user == 0
+UNWIND( .setfp	fpreg, sp		)
+	@
+	@ If we took the interrupt while running in the kernel, we may already
+	@ be using the IRQ stack, so revert to the original value in that case.
+	@
+	subs	r2, sp, r0		@ SP above bottom of IRQ stack?
+	rsbscs	r2, r2, #THREAD_SIZE	@ ... and below the top?
+	movcs	sp, r0			@ If so, revert to incoming SP
+
+#ifndef CONFIG_UNWINDER_ARM
+	@
+	@ Inform the frame pointer unwinder where the next frame lives
+	@
+	movcc	lr, pc			@ Make LR point into .entry.text so
+					@ that we will get a dump of the
+					@ exception stack for this frame.
+#ifdef CONFIG_CC_IS_GCC
+	movcc	ip, r0			@ Store the old SP in the frame record.
+	stmdbcc	sp!, {fp, ip, lr, pc}	@ Push frame record
+	addcc	fp, sp, #12
+#else
+	stmdbcc	sp!, {fp, lr}		@ Push frame record
+	movcc	fp, sp
+#endif // CONFIG_CC_IS_GCC
+#endif // CONFIG_UNWINDER_ARM
+	.endif
+
 	bl	generic_handle_arch_irq
+
+#ifdef CONFIG_UNWINDER_ARM
+	mov	sp, fpreg		@ Restore original SP
+#else
+	mov	fp, r7			@ Restore original FP
+	mov	sp, r8			@ Restore original SP
+#endif // CONFIG_UNWINDER_ARM
 	.endm
 
 	.macro	pabt_helper
@@ -191,7 +233,7 @@ ENDPROC(__dabt_svc)
 	.align	5
 __irq_svc:
 	svc_entry
-	irq_handler
+	irq_handler from_user=0
 
 #ifdef CONFIG_PREEMPTION
 	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
@@ -418,7 +460,7 @@ ENDPROC(__dabt_usr)
 __irq_usr:
 	usr_entry
 	kuser_cmpxchg_check
-	irq_handler
+	irq_handler from_user=1
 	get_thread_info tsk
 	mov	why, #0
 	b	ret_to_user_from_irq
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 4e0d318b67c6..de8a60363c85 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -40,11 +40,24 @@ __irq_entry:
 	@ Invoke the IRQ handler
 	@
 	mov	r0, sp
-	stmdb	sp!, {lr}
+	ldr_this_cpu sp, irq_stack_ptr, r1, r2
+
+	@
+	@ If we took the interrupt while running in the kernel, we may already
+	@ be using the IRQ stack, so revert to the original value in that case.
+	@
+	subs	r2, sp, r0		@ SP above bottom of IRQ stack?
+	rsbscs	r2, r2, #THREAD_SIZE	@ ... and below the top?
+	movcs	sp, r0
+
+	push	{r0, lr}		@ preserve LR and original SP
+
 	@ routine called with r0 = struct pt_regs *
 	bl	generic_handle_arch_irq
 
-	pop	{lr}
+	pop	{r0, lr}
+	mov	sp, r0
+
 	@
 	@ Check for any pending work if returning to user
 	@
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 5a1e52a4ee11..92ae80a8e5b4 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -43,6 +43,21 @@
 
 unsigned long irq_err_count;
 
+asmlinkage DEFINE_PER_CPU_READ_MOSTLY(u8 *, irq_stack_ptr);
+
+static void __init init_irq_stacks(void)
+{
+	u8 *stack;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		stack = (u8 *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
+		if (WARN_ON(!stack))
+			break;
+		per_cpu(irq_stack_ptr, cpu) = &stack[THREAD_SIZE];
+	}
+}
+
 int arch_show_interrupts(struct seq_file *p, int prec)
 {
 #ifdef CONFIG_FIQ
@@ -84,6 +99,8 @@ void __init init_IRQ(void)
 {
 	int ret;
 
+	init_irq_stacks();
+
 	if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq)
 		irqchip_init();
 	else
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index c51b87f6fc3e..1b8bef286fbc 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -66,6 +66,19 @@ void dump_backtrace_entry(unsigned long where, unsigned long from,
 {
 	unsigned long end = frame + 4 + sizeof(struct pt_regs);
 
+	if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER) &&
+	    IS_ENABLED(CONFIG_CC_IS_GCC) &&
+	    end > ALIGN(frame, THREAD_SIZE)) {
+		/*
+		 * If we are walking past the end of the stack, it may be due
+		 * to the fact that we are on an IRQ or overflow stack. In this
+		 * case, we can load the address of the other stack from the
+		 * frame record.
+		 */
+		frame = ((unsigned long *)frame)[-2] - 4;
+		end = frame + 4 + sizeof(struct pt_regs);
+	}
+
 #ifndef CONFIG_KALLSYMS
 	printk("%sFunction entered at [<%08lx>] from [<%08lx>]\n",
 		loglvl, where, from);
@@ -280,7 +293,7 @@ static int __die(const char *str, int err, struct pt_regs *regs)
 
 	if (!user_mode(regs) || in_interrupt()) {
 		dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
-			 THREAD_SIZE + (unsigned long)task_stack_page(tsk));
+			 ALIGN(regs->ARM_sp, THREAD_SIZE));
 		dump_backtrace(regs, tsk, KERN_EMERG);
 		dump_instr(KERN_EMERG, regs);
 	}
diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 5b4bca85d06d..1f0814b41bcf 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -197,6 +197,13 @@ finished_setup:
 
 		cmp	sv_fp, frame		@ next frame must be
 		mov	frame, sv_fp		@ above the current frame
+
+		@
+		@ Kernel stacks may be discontiguous in memory. If the next
+		@ frame is below the previous frame, accept it as long as it
+		@ lives in kernel memory.
+		@
+		cmpls	sv_fp, #PAGE_OFFSET
 		bhi	for_each_frame
 
 1006:		adr	r0, .Lbad
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index e8408f22d4dc..e6e8451c5cb3 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -98,6 +98,13 @@ for_each_frame:	tst	frame, mask		@ Check for address exceptions
 
 		cmp	sv_fp, frame		@ next frame must be
 		mov	frame, sv_fp		@ above the current frame
+
+		@
+		@ Kernel stacks may be discontiguous in memory. If the next
+		@ frame is below the previous frame, accept it as long as it
+		@ lives in kernel memory.
+		@
+		cmpls	sv_fp, #PAGE_OFFSET
 		bhi	for_each_frame
 
 1006:		adr	r0, .Lbad
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:36 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:36 +0100
Subject: [PATCH v5 24/32] ARM: run softirqs on the per-CPU IRQ stack
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-25-ardb@kernel.org>

Now that we have enabled IRQ stacks, any softIRQs that are handled over
the back of a hard IRQ will run from the IRQ stack as well. However, any
synchronous softirq processing that happens when re-enabling softIRQs
from task context will still execute on that task's stack.

Since any call to local_bh_enable() at any level in the task's call
stack may trigger a softIRQ processing run, which could potentially
cause a task stack overflow if the combined stack footprints exceed the
stack's size, let's run these synchronous invocations of do_softirq() on
the IRQ stack as well.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig      |  2 ++
 arch/arm/kernel/irq.c | 14 ++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 108a7a872084..b959249dd716 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -128,6 +128,8 @@ config ARM
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select THREAD_INFO_IN_TASK
+	select HAVE_IRQ_EXIT_ON_IRQ_STACK
+	select HAVE_SOFTIRQ_ON_OWN_STACK
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 92ae80a8e5b4..380376f55554 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -36,11 +36,14 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/cache-uniphier.h>
 #include <asm/outercache.h>
+#include <asm/softirq_stack.h>
 #include <asm/exception.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
+#include "reboot.h"
+
 unsigned long irq_err_count;
 
 asmlinkage DEFINE_PER_CPU_READ_MOSTLY(u8 *, irq_stack_ptr);
@@ -58,6 +61,17 @@ static void __init init_irq_stacks(void)
 	}
 }
 
+static void ____do_softirq(void *arg)
+{
+	__do_softirq();
+}
+
+void do_softirq_own_stack(void)
+{
+	call_with_stack(____do_softirq, NULL,
+			__this_cpu_read(irq_stack_ptr));
+}
+
 int arch_show_interrupts(struct seq_file *p, int prec)
 {
 #ifdef CONFIG_FIQ
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:35 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:35 +0100
Subject: [PATCH v5 23/32] ARM: call_with_stack: add unwind support
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-24-ardb@kernel.org>

Restructure the code and add the unwind annotations so that both the
frame pointer unwinder as well as the EHABI unwind info based unwinder
will be able to follow the call stack through call_with_stack().

Since GCC and Clang use different formats for the stack frame, two
methods are implemented: a GCC version that pushes fp, sp, lr and pc for
compatibility with the frame pointer unwinder, and a second version that
works with Clang, as well as with the EHABI unwinder both in ARM and
Thumb2 modes.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/lib/call_with_stack.S | 33 +++++++++++++++-----
 1 file changed, 25 insertions(+), 8 deletions(-)

diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
index 28b0341ae786..0a268a6c513c 100644
--- a/arch/arm/lib/call_with_stack.S
+++ b/arch/arm/lib/call_with_stack.S
@@ -8,25 +8,42 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/unwind.h>
 
 /*
  * void call_with_stack(void (*fn)(void *), void *arg, void *sp)
  *
  * Change the stack to that pointed at by sp, then invoke fn(arg) with
  * the new stack.
+ *
+ * The sequence below follows the APCS frame convention for frame pointer
+ * unwinding, and implements the unwinder annotations needed by the EABI
+ * unwinder.
  */
-ENTRY(call_with_stack)
-	str	sp, [r2, #-4]!
-	str	lr, [r2, #-4]!
 
+ENTRY(call_with_stack)
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+	mov	ip, sp
+	push	{fp, ip, lr, pc}
+	sub	fp, ip, #4
+#else
+UNWIND( .fnstart		)
+UNWIND( .save	{fpreg, lr}	)
+	push	{fpreg, lr}
+UNWIND( .setfp	fpreg, sp	)
+	mov	fpreg, sp
+#endif
 	mov	sp, r2
 	mov	r2, r0
 	mov	r0, r1
 
-	badr	lr, 1f
-	ret	r2
+	bl_r	r2
 
-1:	ldr	lr, [sp]
-	ldr	sp, [sp, #4]
-	ret	lr
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+	ldmdb	fp, {fp, sp, pc}
+#else
+	mov	sp, fpreg
+	pop	{fpreg, pc}
+UNWIND( .fnend			)
+#endif
 ENDPROC(call_with_stack)
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:37 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:37 +0100
Subject: [PATCH v5 25/32] ARM: memcpy: use frame pointer as unwind anchor
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-26-ardb@kernel.org>

The memcpy template is a bit unusual in the way it manages the stack
pointer: depending on the execution path through the function, the SP
assumes different values as different subsets of the register file are
preserved and restored again. This is problematic when it comes to EHABI
unwind info, as it is not instruction accurate, and does not allow
tracking the SP value as it changes.

Commit 279f487e0b471 ("ARM: 8225/1: Add unwinding support for memory
copy functions") addressed this by carving up the function in different
chunks as far as the unwinder is concerned, and keeping a set of unwind
directives for each of them, each corresponding with the state of the
stack pointer during execution of the chunk in question. This not only
duplicates unwind info unnecessarily, but it also complicates unwinding
the stack upon overflow.

Instead, let's do what the compiler does when the SP is updated halfway
through a function, which is to use a frame pointer and emit the
appropriate unwind directives to communicate this to the unwinder.

Note that Thumb-2 uses R7 for this, while ARM uses R11 aka FP. So let's
avoid touching R7 in the body of the template, so that Thumb-2 can use
it as the frame pointer. R11 was not modified in the first place.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/lib/copy_from_user.S | 13 ++--
 arch/arm/lib/copy_template.S  | 67 +++++++-------------
 arch/arm/lib/copy_to_user.S   | 13 ++--
 arch/arm/lib/memcpy.S         | 13 ++--
 4 files changed, 38 insertions(+), 68 deletions(-)

diff --git a/arch/arm/lib/copy_from_user.S b/arch/arm/lib/copy_from_user.S
index 480a20766137..270de7debd0f 100644
--- a/arch/arm/lib/copy_from_user.S
+++ b/arch/arm/lib/copy_from_user.S
@@ -91,18 +91,15 @@
 	strb\cond \reg, [\ptr], #1
 	.endm
 
-	.macro enter reg1 reg2
+	.macro enter regs:vararg
 	mov	r3, #0
-	stmdb	sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save	{r0, r2, r3, \regs}		)
+	stmdb	sp!, {r0, r2, r3, \regs}
 	.endm
 
-	.macro usave reg1 reg2
-	UNWIND(	.save {r0, r2, r3, \reg1, \reg2}	)
-	.endm
-
-	.macro exit reg1 reg2
+	.macro exit regs:vararg
 	add	sp, sp, #8
-	ldmfd	sp!, {r0, \reg1, \reg2}
+	ldmfd	sp!, {r0, \regs}
 	.endm
 
 	.text
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
index 810a805d36dc..8fbafb074fe9 100644
--- a/arch/arm/lib/copy_template.S
+++ b/arch/arm/lib/copy_template.S
@@ -69,13 +69,10 @@
  *	than one 32bit instruction in Thumb-2)
  */
 
-
-	UNWIND(	.fnstart			)
-		enter	r4, lr
-	UNWIND(	.fnend				)
-
 	UNWIND(	.fnstart			)
-		usave	r4, lr			  @ in first stmdb block
+		enter	r4, UNWIND(fpreg,) lr
+	UNWIND(	.setfp	fpreg, sp		)
+	UNWIND(	mov	fpreg, sp		)
 
 		subs	r2, r2, #4
 		blt	8f
@@ -86,12 +83,7 @@
 		bne	10f
 
 1:		subs	r2, r2, #(28)
-		stmfd	sp!, {r5 - r8}
-	UNWIND(	.fnend				)
-
-	UNWIND(	.fnstart			)
-		usave	r4, lr
-	UNWIND(	.save	{r5 - r8}		) @ in second stmfd block
+		stmfd	sp!, {r5, r6, r8, r9}
 		blt	5f
 
 	CALGN(	ands	ip, r0, #31		)
@@ -110,9 +102,9 @@
 	PLD(	pld	[r1, #92]		)
 
 3:	PLD(	pld	[r1, #124]		)
-4:		ldr8w	r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+4:		ldr8w	r1, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
 		subs	r2, r2, #32
-		str8w	r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+		str8w	r0, r3, r4, r5, r6, r8, r9, ip, lr, abort=20f
 		bge	3b
 	PLD(	cmn	r2, #96			)
 	PLD(	bge	4b			)
@@ -132,8 +124,8 @@
 		ldr1w	r1, r4, abort=20f
 		ldr1w	r1, r5, abort=20f
 		ldr1w	r1, r6, abort=20f
-		ldr1w	r1, r7, abort=20f
 		ldr1w	r1, r8, abort=20f
+		ldr1w	r1, r9, abort=20f
 		ldr1w	r1, lr, abort=20f
 
 #if LDR1W_SHIFT < STR1W_SHIFT
@@ -150,17 +142,14 @@
 		str1w	r0, r4, abort=20f
 		str1w	r0, r5, abort=20f
 		str1w	r0, r6, abort=20f
-		str1w	r0, r7, abort=20f
 		str1w	r0, r8, abort=20f
+		str1w	r0, r9, abort=20f
 		str1w	r0, lr, abort=20f
 
 	CALGN(	bcs	2b			)
 
-7:		ldmfd	sp!, {r5 - r8}
-	UNWIND(	.fnend				) @ end of second stmfd block
+7:		ldmfd	sp!, {r5, r6, r8, r9}
 
-	UNWIND(	.fnstart			)
-		usave	r4, lr			  @ still in first stmdb block
 8:		movs	r2, r2, lsl #31
 		ldr1b	r1, r3, ne, abort=21f
 		ldr1b	r1, r4, cs, abort=21f
@@ -169,7 +158,7 @@
 		str1b	r0, r4, cs, abort=21f
 		str1b	r0, ip, cs, abort=21f
 
-		exit	r4, pc
+		exit	r4, UNWIND(fpreg,) pc
 
 9:		rsb	ip, ip, #4
 		cmp	ip, #2
@@ -189,13 +178,10 @@
 		ldr1w	r1, lr, abort=21f
 		beq	17f
 		bgt	18f
-	UNWIND(	.fnend				)
 
 
 		.macro	forward_copy_shift pull push
 
-	UNWIND(	.fnstart			)
-		usave	r4, lr			  @ still in first stmdb block
 		subs	r2, r2, #28
 		blt	14f
 
@@ -205,12 +191,8 @@
 	CALGN(	subcc	r2, r2, ip		)
 	CALGN(	bcc	15f			)
 
-11:		stmfd	sp!, {r5 - r9}
-	UNWIND(	.fnend				)
+11:		stmfd	sp!, {r5, r6, r8 - r10}
 
-	UNWIND(	.fnstart			)
-		usave	r4, lr
-	UNWIND(	.save	{r5 - r9}		) @ in new second stmfd block
 	PLD(	pld	[r1, #0]		)
 	PLD(	subs	r2, r2, #96		)
 	PLD(	pld	[r1, #28]		)
@@ -219,35 +201,32 @@
 	PLD(	pld	[r1, #92]		)
 
 12:	PLD(	pld	[r1, #124]		)
-13:		ldr4w	r1, r4, r5, r6, r7, abort=19f
+13:		ldr4w	r1, r4, r5, r6, r8, abort=19f
 		mov	r3, lr, lspull #\pull
 		subs	r2, r2, #32
-		ldr4w	r1, r8, r9, ip, lr, abort=19f
+		ldr4w	r1, r9, r10, ip, lr, abort=19f
 		orr	r3, r3, r4, lspush #\push
 		mov	r4, r4, lspull #\pull
 		orr	r4, r4, r5, lspush #\push
 		mov	r5, r5, lspull #\pull
 		orr	r5, r5, r6, lspush #\push
 		mov	r6, r6, lspull #\pull
-		orr	r6, r6, r7, lspush #\push
-		mov	r7, r7, lspull #\pull
-		orr	r7, r7, r8, lspush #\push
+		orr	r6, r6, r8, lspush #\push
 		mov	r8, r8, lspull #\pull
 		orr	r8, r8, r9, lspush #\push
 		mov	r9, r9, lspull #\pull
-		orr	r9, r9, ip, lspush #\push
+		orr	r9, r9, r10, lspush #\push
+		mov	r10, r10, lspull #\pull
+		orr	r10, r10, ip, lspush #\push
 		mov	ip, ip, lspull #\pull
 		orr	ip, ip, lr, lspush #\push
-		str8w	r0, r3, r4, r5, r6, r7, r8, r9, ip, abort=19f
+		str8w	r0, r3, r4, r5, r6, r8, r9, r10, ip, abort=19f
 		bge	12b
 	PLD(	cmn	r2, #96			)
 	PLD(	bge	13b			)
 
-		ldmfd	sp!, {r5 - r9}
-	UNWIND(	.fnend				) @ end of the second stmfd block
+		ldmfd	sp!, {r5, r6, r8 - r10}
 
-	UNWIND(	.fnstart			)
-		usave	r4, lr			  @ still in first stmdb block
 14:		ands	ip, r2, #28
 		beq	16f
 
@@ -262,7 +241,6 @@
 
 16:		sub	r1, r1, #(\push / 8)
 		b	8b
-	UNWIND(	.fnend				)
 
 		.endm
 
@@ -273,6 +251,7 @@
 
 18:		forward_copy_shift	pull=24	push=8
 
+	UNWIND(	.fnend				)
 
 /*
  * Abort preamble and completion macros.
@@ -282,13 +261,13 @@
  */
 
 	.macro	copy_abort_preamble
-19:	ldmfd	sp!, {r5 - r9}
+19:	ldmfd	sp!, {r5, r6, r8 - r10}
 	b	21f
-20:	ldmfd	sp!, {r5 - r8}
+20:	ldmfd	sp!, {r5, r6, r8, r9}
 21:
 	.endm
 
 	.macro	copy_abort_end
-	ldmfd	sp!, {r4, pc}
+	ldmfd	sp!, {r4, UNWIND(fpreg,) pc}
 	.endm
 
diff --git a/arch/arm/lib/copy_to_user.S b/arch/arm/lib/copy_to_user.S
index 842ea5ede485..fac49e57cc0b 100644
--- a/arch/arm/lib/copy_to_user.S
+++ b/arch/arm/lib/copy_to_user.S
@@ -90,18 +90,15 @@
 	strusr	\reg, \ptr, 1, \cond, abort=\abort
 	.endm
 
-	.macro enter reg1 reg2
+	.macro enter regs:vararg
 	mov	r3, #0
-	stmdb	sp!, {r0, r2, r3, \reg1, \reg2}
+UNWIND( .save	{r0, r2, r3, \regs}		)
+	stmdb	sp!, {r0, r2, r3, \regs}
 	.endm
 
-	.macro usave reg1 reg2
-	UNWIND(	.save {r0, r2, r3, \reg1, \reg2}	)
-	.endm
-
-	.macro exit reg1 reg2
+	.macro exit regs:vararg
 	add	sp, sp, #8
-	ldmfd	sp!, {r0, \reg1, \reg2}
+	ldmfd	sp!, {r0, \regs}
 	.endm
 
 	.text
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index e4caf48c089f..90f2b645aa0d 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -42,16 +42,13 @@
 	strb\cond \reg, [\ptr], #1
 	.endm
 
-	.macro enter reg1 reg2
-	stmdb sp!, {r0, \reg1, \reg2}
+	.macro enter regs:vararg
+UNWIND( .save	{r0, \regs}		)
+	stmdb sp!, {r0, \regs}
 	.endm
 
-	.macro usave reg1 reg2
-	UNWIND(	.save	{r0, \reg1, \reg2}	)
-	.endm
-
-	.macro exit reg1 reg2
-	ldmfd sp!, {r0, \reg1, \reg2}
+	.macro exit regs:vararg
+	ldmfd sp!, {r0, \regs}
 	.endm
 
 	.text
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:38 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:38 +0100
Subject: [PATCH v5 26/32] ARM: memmove: use frame pointer as unwind anchor
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-27-ardb@kernel.org>

The memmove routine is a bit unusual in the way it manages the stack
pointer: depending on the execution path through the function, the SP
assumes different values as different subsets of the register file are
preserved and restored again. This is problematic when it comes to EHABI
unwind info, as it is not instruction accurate, and does not allow
tracking the SP value as it changes.

Commit 207a6cb06990c ("ARM: 8224/1: Add unwinding support for memmove
function") addressed this by carving up the function in different chunks
as far as the unwinder is concerned, and keeping a set of unwind
directives for each of them, each corresponding with the state of the
stack pointer during execution of the chunk in question. This not only
duplicates unwind info unnecessarily, but it also complicates unwinding
the stack upon overflow.

Instead, let's do what the compiler does when the SP is updated halfway
through a function, which is to use a frame pointer and emit the
appropriate unwind directives to communicate this to the unwinder.

Note that Thumb-2 uses R7 for this, while ARM uses R11 aka FP. So let's
avoid touching R7 in the body of the function, so that Thumb-2 can use
it as the frame pointer. R11 was not modified in the first place.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/lib/memmove.S | 60 +++++++-------------
 1 file changed, 20 insertions(+), 40 deletions(-)

diff --git a/arch/arm/lib/memmove.S b/arch/arm/lib/memmove.S
index 6fecc12a1f51..6410554039fd 100644
--- a/arch/arm/lib/memmove.S
+++ b/arch/arm/lib/memmove.S
@@ -31,12 +31,13 @@ WEAK(memmove)
 		subs	ip, r0, r1
 		cmphi	r2, ip
 		bls	__memcpy
-
-		stmfd	sp!, {r0, r4, lr}
 	UNWIND(	.fnend				)
 
 	UNWIND(	.fnstart			)
-	UNWIND(	.save	{r0, r4, lr}		) @ in first stmfd block
+	UNWIND(	.save	{r0, r4, fpreg, lr}	)
+		stmfd	sp!, {r0, r4, UNWIND(fpreg,) lr}
+	UNWIND(	.setfp	fpreg, sp		)
+	UNWIND(	mov	fpreg, sp		)
 		add	r1, r1, r2
 		add	r0, r0, r2
 		subs	r2, r2, #4
@@ -48,12 +49,7 @@ WEAK(memmove)
 		bne	10f
 
 1:		subs	r2, r2, #(28)
-		stmfd	sp!, {r5 - r8}
-	UNWIND(	.fnend				)
-
-	UNWIND(	.fnstart			)
-	UNWIND(	.save	{r0, r4, lr}		)
-	UNWIND(	.save	{r5 - r8}		) @ in second stmfd block
+		stmfd	sp!, {r5, r6, r8, r9}
 		blt	5f
 
 	CALGN(	ands	ip, r0, #31		)
@@ -72,9 +68,9 @@ WEAK(memmove)
 	PLD(	pld	[r1, #-96]		)
 
 3:	PLD(	pld	[r1, #-128]		)
-4:		ldmdb	r1!, {r3, r4, r5, r6, r7, r8, ip, lr}
+4:		ldmdb	r1!, {r3, r4, r5, r6, r8, r9, ip, lr}
 		subs	r2, r2, #32
-		stmdb	r0!, {r3, r4, r5, r6, r7, r8, ip, lr}
+		stmdb	r0!, {r3, r4, r5, r6, r8, r9, ip, lr}
 		bge	3b
 	PLD(	cmn	r2, #96			)
 	PLD(	bge	4b			)
@@ -88,8 +84,8 @@ WEAK(memmove)
 		W(ldr)	r4, [r1, #-4]!
 		W(ldr)	r5, [r1, #-4]!
 		W(ldr)	r6, [r1, #-4]!
-		W(ldr)	r7, [r1, #-4]!
 		W(ldr)	r8, [r1, #-4]!
+		W(ldr)	r9, [r1, #-4]!
 		W(ldr)	lr, [r1, #-4]!
 
 		add	pc, pc, ip
@@ -99,17 +95,13 @@ WEAK(memmove)
 		W(str)	r4, [r0, #-4]!
 		W(str)	r5, [r0, #-4]!
 		W(str)	r6, [r0, #-4]!
-		W(str)	r7, [r0, #-4]!
 		W(str)	r8, [r0, #-4]!
+		W(str)	r9, [r0, #-4]!
 		W(str)	lr, [r0, #-4]!
 
 	CALGN(	bcs	2b			)
 
-7:		ldmfd	sp!, {r5 - r8}
-	UNWIND(	.fnend				) @ end of second stmfd block
-
-	UNWIND(	.fnstart			)
-	UNWIND(	.save	{r0, r4, lr}		) @ still in first stmfd block
+7:		ldmfd	sp!, {r5, r6, r8, r9}
 
 8:		movs	r2, r2, lsl #31
 		ldrbne	r3, [r1, #-1]!
@@ -118,7 +110,7 @@ WEAK(memmove)
 		strbne	r3, [r0, #-1]!
 		strbcs	r4, [r0, #-1]!
 		strbcs	ip, [r0, #-1]
-		ldmfd	sp!, {r0, r4, pc}
+		ldmfd	sp!, {r0, r4, UNWIND(fpreg,) pc}
 
 9:		cmp	ip, #2
 		ldrbgt	r3, [r1, #-1]!
@@ -137,13 +129,10 @@ WEAK(memmove)
 		ldr	r3, [r1, #0]
 		beq	17f
 		blt	18f
-	UNWIND(	.fnend				)
 
 
 		.macro	backward_copy_shift push pull
 
-	UNWIND(	.fnstart			)
-	UNWIND(	.save	{r0, r4, lr}		) @ still in first stmfd block
 		subs	r2, r2, #28
 		blt	14f
 
@@ -152,12 +141,7 @@ WEAK(memmove)
 	CALGN(	subcc	r2, r2, ip		)
 	CALGN(	bcc	15f			)
 
-11:		stmfd	sp!, {r5 - r9}
-	UNWIND(	.fnend				)
-
-	UNWIND(	.fnstart			)
-	UNWIND(	.save	{r0, r4, lr}		)
-	UNWIND(	.save	{r5 - r9}		) @ in new second stmfd block
+11:		stmfd	sp!, {r5, r6, r8 - r10}
 
 	PLD(	pld	[r1, #-4]		)
 	PLD(	subs	r2, r2, #96		)
@@ -167,35 +151,31 @@ WEAK(memmove)
 	PLD(	pld	[r1, #-96]		)
 
 12:	PLD(	pld	[r1, #-128]		)
-13:		ldmdb   r1!, {r7, r8, r9, ip}
+13:		ldmdb   r1!, {r8, r9, r10, ip}
 		mov     lr, r3, lspush #\push
 		subs    r2, r2, #32
 		ldmdb   r1!, {r3, r4, r5, r6}
 		orr     lr, lr, ip, lspull #\pull
 		mov     ip, ip, lspush #\push
-		orr     ip, ip, r9, lspull #\pull
+		orr     ip, ip, r10, lspull #\pull
+		mov     r10, r10, lspush #\push
+		orr     r10, r10, r9, lspull #\pull
 		mov     r9, r9, lspush #\push
 		orr     r9, r9, r8, lspull #\pull
 		mov     r8, r8, lspush #\push
-		orr     r8, r8, r7, lspull #\pull
-		mov     r7, r7, lspush #\push
-		orr     r7, r7, r6, lspull #\pull
+		orr     r8, r8, r6, lspull #\pull
 		mov     r6, r6, lspush #\push
 		orr     r6, r6, r5, lspull #\pull
 		mov     r5, r5, lspush #\push
 		orr     r5, r5, r4, lspull #\pull
 		mov     r4, r4, lspush #\push
 		orr     r4, r4, r3, lspull #\pull
-		stmdb   r0!, {r4 - r9, ip, lr}
+		stmdb   r0!, {r4 - r6, r8 - r10, ip, lr}
 		bge	12b
 	PLD(	cmn	r2, #96			)
 	PLD(	bge	13b			)
 
-		ldmfd	sp!, {r5 - r9}
-	UNWIND(	.fnend				) @ end of the second stmfd block
-
-	UNWIND(	.fnstart			)
-	UNWIND(	.save {r0, r4, lr}		) @ still in first stmfd block
+		ldmfd	sp!, {r5, r6, r8 - r10}
 
 14:		ands	ip, r2, #28
 		beq	16f
@@ -211,7 +191,6 @@ WEAK(memmove)
 
 16:		add	r1, r1, #(\pull / 8)
 		b	8b
-	UNWIND(	.fnend				)
 
 		.endm
 
@@ -222,5 +201,6 @@ WEAK(memmove)
 
 18:		backward_copy_shift	push=24	pull=8
 
+	UNWIND(	.fnend				)
 ENDPROC(memmove)
 ENDPROC(__memmove)
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:39 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:39 +0100
Subject: [PATCH v5 27/32] ARM: memset: clean up unwind annotations
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-28-ardb@kernel.org>

The memset implementation carves up the code in different sections, each
covered with their own unwind info. In this case, it is done in a way
similar to how the compiler might do it, to disambiguate between parts
where the return address is in LR and the SP is unmodified, and parts
where a stack frame is live, and the unwinder needs to know the size of
the stack frame and the location of the return address within it.

Only the placement of the unwind directives is slightly odd: the stack
pushes are placed in the wrong sections, which may confuse the unwinder
when attempting to unwind with PC pointing at the stack push in
question.

So let's fix this up, by reordering the directives and instructions as
appropriate.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/lib/memset.S | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index 9817cb258c1a..d71ab61430b2 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -28,16 +28,16 @@ UNWIND( .fnstart         )
 	mov	r3, r1
 7:	cmp	r2, #16
 	blt	4f
+UNWIND( .fnend              )
 
 #if ! CALGN(1)+0
 
 /*
  * We need 2 extra registers for this loop - use r8 and the LR
  */
-	stmfd	sp!, {r8, lr}
-UNWIND( .fnend              )
 UNWIND( .fnstart            )
 UNWIND( .save {r8, lr}      )
+	stmfd	sp!, {r8, lr}
 	mov	r8, r1
 	mov	lr, r3
 
@@ -66,10 +66,9 @@ UNWIND( .fnend              )
  * whole cache lines at once.
  */
 
-	stmfd	sp!, {r4-r8, lr}
-UNWIND( .fnend                 )
 UNWIND( .fnstart               )
 UNWIND( .save {r4-r8, lr}      )
+	stmfd	sp!, {r4-r8, lr}
 	mov	r4, r1
 	mov	r5, r3
 	mov	r6, r1
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:40 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:40 +0100
Subject: [PATCH v5 28/32] ARM: unwind: disregard unwind info before stack
 frame is set up
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-29-ardb@kernel.org>

When unwinding the stack from a stack overflow, we are likely to start
from a stack push instruction, given that this is the most common way to
grow the stack for compiler emitted code. This push instruction rarely
appears anywhere else than at offset 0x0 of the function, and if it
doesn't, the compiler tends to split up the unwind annotations, given
that the stack frame layout is apparently not the same throughout the
function.

This means that, in the general case, if the frame's PC points at the
first instruction covered by a certain unwind entry, there is no way the
stack frame that the unwind entry describes could have been created yet,
and so we are still on the stack frame of the caller in that case. So
treat this as a special case, and return with the new PC taken from the
frame's LR, without applying the unwind transformations to the virtual
register set.

This permits us to unwind the call stack on stack overflow when the
overflow was caused by a stack push on function entry.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/kernel/unwind.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index b7a6141c342f..e8d729975f12 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -411,7 +411,21 @@ int unwind_frame(struct stackframe *frame)
 	if (idx->insn == 1)
 		/* can't unwind */
 		return -URC_FAILURE;
-	else if ((idx->insn & 0x80000000) == 0)
+	else if (frame->pc == prel31_to_addr(&idx->addr_offset)) {
+		/*
+		 * Unwinding is tricky when we're halfway through the prologue,
+		 * since the stack frame that the unwinder expects may not be
+		 * fully set up yet. However, one thing we do know for sure is
+		 * that if we are unwinding from the very first instruction of
+		 * a function, we are still effectively in the stack frame of
+		 * the caller, and the unwind info has no relevance yet.
+		 */
+		if (frame->pc == frame->lr)
+			return -URC_FAILURE;
+		frame->sp_low = frame->sp;
+		frame->pc = frame->lr;
+		return URC_OK;
+	} else if ((idx->insn & 0x80000000) == 0)
 		/* prel31 to the unwind table */
 		ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
 	else if ((idx->insn & 0xff000000) == 0x80000000)
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:41 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:41 +0100
Subject: [PATCH v5 29/32] ARM: entry: rework stack realignment code in
 svc_entry
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-30-ardb@kernel.org>

The original Thumb-2 enablement patches updated the stack realignment
code in svc_entry to work around the lack of a STMIB instruction in
Thumb-2, by subtracting 4 from the frame size, inverting the sense of
the misaligment check, and changing to a STMIA instruction and a final
stack push of a 4 byte quantity that results in the stack becoming
aligned at the end of the sequence. It also pushes and pops R0 to the
stack in order to have a temp register that Thumb-2 allows in general
purpose ALU instructions, as TST using SP is not permitted.

Both are a bit problematic for vmap'ed stacks, as using the stack is
only permitted after we decide that we did not overflow the stack, or
have already switched to the overflow stack.

As for the alignment check: the current approach creates a corner case
where, if the initial SUB of SP ends up right at the start of the stack,
we will end up subtracting another 8 bytes and overflowing it.  This
means we would need to add the overflow check *after* the SUB that
deliberately misaligns the stack. However, this would require us to keep
local state (i.e., whether we performed the subtract or not) across the
overflow check, but without any GPRs or stack available.

So let's switch to an approach where we don't use the stack, and where
the alignment check of the stack pointer occurs in the usual way, as
this is guaranteed not to result in overflow. This means we will be able
to do the overflow check first.

While at it, switch to R1 so the mode stack pointer in R0 remains
accessible.

Acked-by: Nicolas Pitre <nico at fluxnic.net>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/kernel/entry-armv.S | 25 +++++++++++---------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 38e3978a50a9..a4009e4302bb 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -177,24 +177,27 @@ ENDPROC(__und_invalid)
 	.macro	svc_entry, stack_hole=0, trace=1, uaccess=1
  UNWIND(.fnstart		)
  UNWIND(.save {r0 - pc}		)
-	sub	sp, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
+	sub	sp, sp, #(SVC_REGS_SIZE + \stack_hole)
 #ifdef CONFIG_THUMB2_KERNEL
- SPFIX(	str	r0, [sp]	)	@ temporarily saved
- SPFIX(	mov	r0, sp		)
- SPFIX(	tst	r0, #4		)	@ test original stack alignment
- SPFIX(	ldr	r0, [sp]	)	@ restored
+	add	sp, r1			@ get SP in a GPR without
+	sub	r1, sp, r1		@ using a temp register
+	tst	r1, #4			@ test stack pointer alignment
+	sub	r1, sp, r1		@ restore original R1
+	sub	sp, r1			@ restore original SP
 #else
  SPFIX(	tst	sp, #4		)
 #endif
- SPFIX(	subeq	sp, sp, #4	)
-	stmia	sp, {r1 - r12}
+ SPFIX(	subne	sp, sp, #4	)
+
+ ARM(	stmib	sp, {r1 - r12}	)
+ THUMB(	stmia	sp, {r0 - r12}	)	@ No STMIB in Thumb-2
 
 	ldmia	r0, {r3 - r5}
-	add	r7, sp, #S_SP - 4	@ here for interlock avoidance
+	add	r7, sp, #S_SP		@ here for interlock avoidance
 	mov	r6, #-1			@  ""  ""      ""       ""
-	add	r2, sp, #(SVC_REGS_SIZE + \stack_hole - 4)
- SPFIX(	addeq	r2, r2, #4	)
-	str	r3, [sp, #-4]!		@ save the "real" r0 copied
+	add	r2, sp, #(SVC_REGS_SIZE + \stack_hole)
+ SPFIX(	addne	r2, r2, #4	)
+	str	r3, [sp]		@ save the "real" r0 copied
 					@ from the exception stack
 
 	mov	r3, lr
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:42 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:42 +0100
Subject: [PATCH v5 30/32] ARM: switch_to: clean up Thumb2 code path
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-31-ardb@kernel.org>

The load/store-multiple instructions that essentially perform the
switch_to operation in ARM mode, by loading/storing all callee save
registers as well the stack pointer and the link register or program
counter, is split into 3 separate loads or stores for Thumb-2, with the
IP register used as a temporary to capture the target address.

We can clean this up a bit, by sticking with a single STMIA or LDMIA
instruction, but one that uses IP instead of SP.

While at it, switch to a MOVW/MOVT pair to load thread_notify_head.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-armv.S | 24 +++++++++++---------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index a4009e4302bb..86be80159c14 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -773,14 +773,14 @@ ENDPROC(__fiq_usr)
  * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
  * previous and next are guaranteed not to be the same.
  */
+	.align	5
 ENTRY(__switch_to)
  UNWIND(.fnstart	)
  UNWIND(.cantunwind	)
-	add	ip, r1, #TI_CPU_SAVE
- ARM(	stmia	ip!, {r4 - sl, fp, sp, lr} )	@ Store most regs on stack
- THUMB(	stmia	ip!, {r4 - sl, fp}	   )	@ Store most regs on stack
- THUMB(	str	sp, [ip], #4		   )
- THUMB(	str	lr, [ip], #4		   )
+	add	r3, r1, #TI_CPU_SAVE
+ ARM(	stmia	r3, {r4 - sl, fp, sp, lr}  )	@ Store most regs on stack
+ THUMB( mov	ip, sp			   )
+ THUMB( stmia	r3, {r4 - sl, fp, ip, lr}  )	@ Thumb2 does not permit SP here
 	ldr	r4, [r2, #TI_TP_VALUE]
 	ldr	r5, [r2, #TI_TP_VALUE + 4]
 #ifdef CONFIG_CPU_USE_DOMAINS
@@ -805,20 +805,22 @@ ENTRY(__switch_to)
 #endif
 	mov	r5, r0
 	add	r4, r2, #TI_CPU_SAVE
-	ldr	r0, =thread_notify_head
+	mov_l	r0, thread_notify_head
 	mov	r1, #THREAD_NOTIFY_SWITCH
 	bl	atomic_notifier_call_chain
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP) && \
     !defined(CONFIG_STACKPROTECTOR_PER_TASK)
 	str	r9, [r8]
 #endif
- THUMB(	mov	ip, r4			   )
 	mov	r0, r5
 	set_current r7, r8
- ARM(	ldmia	r4, {r4 - sl, fp, sp, pc}  )	@ Load all regs saved previously
- THUMB(	ldmia	ip!, {r4 - sl, fp}	   )	@ Load all regs saved previously
- THUMB(	ldr	sp, [ip], #4		   )
- THUMB(	ldr	pc, [ip]		   )
+#if !defined(CONFIG_THUMB2_KERNEL)
+	ldmia	r4, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
+#else
+	ldmia	r4, {r4 - sl, fp, ip, lr}	@ Thumb2 does not permit SP here
+	mov	sp, ip
+	ret	lr
+#endif
  UNWIND(.fnend		)
 ENDPROC(__switch_to)
 
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:43 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:43 +0100
Subject: [PATCH v5 31/32] ARM: mm: prepare vmalloc_seq handling for use under
 SMP
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-32-ardb@kernel.org>

Currently, the vmalloc_seq counter is only used to keep track of changes
in the vmalloc region on !SMP builds, which means there is no need to
deal with concurrency explicitly.

However, in a subsequent patch, we will wire up this same mechanism for
ensuring that vmap'ed stacks are guaranteed to be mapped by the active
mm before switching to a task, and here we need to ensure that changes
to the page tables are visible to other CPUs when they observe a change
in the sequence count.

Since LPAE needs none of this, fold a check against it into the
vmalloc_seq counter check after breaking it out into a separate static
inline helper.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/mmu.h         |  2 +-
 arch/arm/include/asm/mmu_context.h | 13 +++++++++++--
 arch/arm/mm/context.c              |  3 +--
 arch/arm/mm/ioremap.c              | 18 +++++++++++-------
 4 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 1592a4264488..e049723840d3 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -10,7 +10,7 @@ typedef struct {
 #else
 	int		switch_pending;
 #endif
-	unsigned int	vmalloc_seq;
+	atomic_t	vmalloc_seq;
 	unsigned long	sigpage;
 #ifdef CONFIG_VDSO
 	unsigned long	vdso;
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 84e58956fcab..71a26986efb9 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -23,6 +23,16 @@
 
 void __check_vmalloc_seq(struct mm_struct *mm);
 
+#ifdef CONFIG_MMU
+static inline void check_vmalloc_seq(struct mm_struct *mm)
+{
+	if (!IS_ENABLED(CONFIG_ARM_LPAE) &&
+	    unlikely(atomic_read(&mm->context.vmalloc_seq) !=
+		     atomic_read(&init_mm.context.vmalloc_seq)))
+		__check_vmalloc_seq(mm);
+}
+#endif
+
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
@@ -52,8 +62,7 @@ static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
 static inline void check_and_switch_context(struct mm_struct *mm,
 					    struct task_struct *tsk)
 {
-	if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
-		__check_vmalloc_seq(mm);
+	check_vmalloc_seq(mm);
 
 	if (irqs_disabled())
 		/*
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 48091870db89..4204ffa2d104 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -240,8 +240,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
 	unsigned int cpu = smp_processor_id();
 	u64 asid;
 
-	if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
-		__check_vmalloc_seq(mm);
+	check_vmalloc_seq(mm);
 
 	/*
 	 * We cannot update the pgd and the ASID atomicly with classic
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 197f8eb3a775..aa08bcb72db9 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -117,16 +117,21 @@ EXPORT_SYMBOL(ioremap_page);
 
 void __check_vmalloc_seq(struct mm_struct *mm)
 {
-	unsigned int seq;
+	int seq;
 
 	do {
-		seq = init_mm.context.vmalloc_seq;
+		seq = atomic_read(&init_mm.context.vmalloc_seq);
 		memcpy(pgd_offset(mm, VMALLOC_START),
 		       pgd_offset_k(VMALLOC_START),
 		       sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
 					pgd_index(VMALLOC_START)));
-		mm->context.vmalloc_seq = seq;
-	} while (seq != init_mm.context.vmalloc_seq);
+		/*
+		 * Use a store-release so that other CPUs that observe the
+		 * counter's new value are guaranteed to see the results of the
+		 * memcpy as well.
+		 */
+		atomic_set_release(&mm->context.vmalloc_seq, seq);
+	} while (seq != atomic_read(&init_mm.context.vmalloc_seq));
 }
 
 #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
@@ -157,7 +162,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
 			 * Note: this is still racy on SMP machines.
 			 */
 			pmd_clear(pmdp);
-			init_mm.context.vmalloc_seq++;
+			atomic_inc_return_release(&init_mm.context.vmalloc_seq);
 
 			/*
 			 * Free the page table, if there was one.
@@ -174,8 +179,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
 	 * Ensure that the active_mm is up to date - we want to
 	 * catch any use-after-iounmap cases.
 	 */
-	if (current->active_mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)
-		__check_vmalloc_seq(current->active_mm);
+	check_vmalloc_seq(current->active_mm);
 
 	flush_tlb_kernel_range(virt, end);
 }
-- 
2.30.2



From ardb at kernel.org  Mon Jan 24 09:47:44 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:47:44 +0100
Subject: [PATCH v5 32/32] ARM: implement support for vmap'ed stacks
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <20220124174744.1054712-33-ardb@kernel.org>

Wire up the generic support for managing task stack allocations via vmalloc,
and implement the entry code that detects whether we faulted because of a
stack overrun (or future stack overrun caused by pushing the pt_regs array)

While this adds a fair amount of tricky entry asm code, it should be
noted that it only adds a TST + branch to the svc_entry path. The code
implementing the non-trivial handling of the overflow stack is emitted
out-of-line into the .text section.

Since on !LPAE, we rely on do_translation_fault() to keep PMD level page
table entries that cover the vmalloc region up to date, we need to
ensure that we don't hit such a stale PMD entry when accessing the
stack, as the fault handler itself needs a stack to run as well. So
let's bump the vmalloc_seq counter when PMD level entries in the vmalloc
range are modified, so that the MM switch fetches the latest version of
the entries. To ensure that kernel threads executing with an active_mm
other than init_mm are up to date, add an implementation of
enter_lazy_tlb() to handle this case.

Note that the page table walker is not an ordinary observer in terms of
concurrency, which means that memory barriers alone are not sufficient
to prevent spurious translation faults from occurring when accessing the
stack after a context switch. For this reason, a dummy read from the new
stack is added to __switch_to() right before switching to it, so that
any faults can be dealt with by do_translation_fault() while the old
stack is still active.

Also note that we need to increase the per-mode stack by 1 word, to gain
some space to stash a GPR until we know it is safe to touch the stack.
However, due to the cacheline alignment of the struct, this does not
actually increase the memory footprint of the struct stack array at all.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
Tested-by: Keith Packard <keithpac at amazon.com>
Tested-by: Marc Zyngier <maz at kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin at arm.com> # ARMv7M
---
 arch/arm/Kconfig                   |  1 +
 arch/arm/include/asm/mmu_context.h |  9 ++
 arch/arm/include/asm/page.h        |  3 +
 arch/arm/include/asm/thread_info.h |  8 ++
 arch/arm/kernel/entry-armv.S       | 91 ++++++++++++++++++--
 arch/arm/kernel/entry-header.S     | 37 ++++++++
 arch/arm/kernel/head.S             |  7 ++
 arch/arm/kernel/irq.c              |  9 +-
 arch/arm/kernel/setup.c            |  8 +-
 arch/arm/kernel/sleep.S            | 13 +++
 arch/arm/kernel/traps.c            | 69 ++++++++++++++-
 arch/arm/kernel/unwind.c           |  3 +-
 arch/arm/kernel/vmlinux.lds.S      |  4 +-
 13 files changed, 247 insertions(+), 15 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b959249dd716..cbbe38f55088 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -130,6 +130,7 @@ config ARM
 	select THREAD_INFO_IN_TASK
 	select HAVE_IRQ_EXIT_ON_IRQ_STACK
 	select HAVE_SOFTIRQ_ON_OWN_STACK
+	select HAVE_ARCH_VMAP_STACK if MMU && ARM_HAS_GROUP_RELOCS
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 71a26986efb9..db2cb06aa8cf 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -138,6 +138,15 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
 #endif
 }
 
+#ifdef CONFIG_VMAP_STACK
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+	if (mm != &init_mm)
+		check_vmalloc_seq(mm);
+}
+#define enter_lazy_tlb enter_lazy_tlb
+#endif
+
 #include <asm-generic/mmu_context.h>
 
 #endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 11b058a72a5b..5fcc8a600e36 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -147,6 +147,9 @@ extern void copy_page(void *to, const void *from);
 #include <asm/pgtable-3level-types.h>
 #else
 #include <asm/pgtable-2level-types.h>
+#ifdef CONFIG_VMAP_STACK
+#define ARCH_PAGE_TABLE_SYNC_MASK	PGTBL_PMD_MODIFIED
+#endif
 #endif
 
 #endif /* CONFIG_MMU */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index e039d8f12d9b..aecc403b2880 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -25,6 +25,14 @@
 #define THREAD_SIZE		(PAGE_SIZE << THREAD_SIZE_ORDER)
 #define THREAD_START_SP		(THREAD_SIZE - 8)
 
+#ifdef CONFIG_VMAP_STACK
+#define THREAD_ALIGN		(2 * THREAD_SIZE)
+#else
+#define THREAD_ALIGN		THREAD_SIZE
+#endif
+
+#define OVERFLOW_STACK_SIZE	SZ_4K
+
 #ifndef __ASSEMBLY__
 
 struct task_struct;
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 86be80159c14..e098cc4de426 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -49,6 +49,10 @@ UNWIND( .setfp	fpreg, sp		)
 	@
 	subs	r2, sp, r0		@ SP above bottom of IRQ stack?
 	rsbscs	r2, r2, #THREAD_SIZE	@ ... and below the top?
+#ifdef CONFIG_VMAP_STACK
+	ldr_va	r2, high_memory, cc	@ End of the linear region
+	cmpcc	r2, r0			@ Stack pointer was below it?
+#endif
 	movcs	sp, r0			@ If so, revert to incoming SP
 
 #ifndef CONFIG_UNWINDER_ARM
@@ -174,13 +178,18 @@ ENDPROC(__und_invalid)
 #define SPFIX(code...)
 #endif
 
-	.macro	svc_entry, stack_hole=0, trace=1, uaccess=1
+	.macro	svc_entry, stack_hole=0, trace=1, uaccess=1, overflow_check=1
  UNWIND(.fnstart		)
- UNWIND(.save {r0 - pc}		)
 	sub	sp, sp, #(SVC_REGS_SIZE + \stack_hole)
+ THUMB( add	sp, r1		)	@ get SP in a GPR without
+ THUMB( sub	r1, sp, r1	)	@ using a temp register
+
+	.if	\overflow_check
+ UNWIND(.save	{r0 - pc}	)
+	do_overflow_check (SVC_REGS_SIZE + \stack_hole)
+	.endif
+
 #ifdef CONFIG_THUMB2_KERNEL
-	add	sp, r1			@ get SP in a GPR without
-	sub	r1, sp, r1		@ using a temp register
 	tst	r1, #4			@ test stack pointer alignment
 	sub	r1, sp, r1		@ restore original R1
 	sub	sp, r1			@ restore original SP
@@ -814,16 +823,88 @@ ENTRY(__switch_to)
 #endif
 	mov	r0, r5
 	set_current r7, r8
-#if !defined(CONFIG_THUMB2_KERNEL)
+#if !defined(CONFIG_THUMB2_KERNEL) && \
+    !(defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE))
 	ldmia	r4, {r4 - sl, fp, sp, pc}	@ Load all regs saved previously
 #else
 	ldmia	r4, {r4 - sl, fp, ip, lr}	@ Thumb2 does not permit SP here
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Even though we take care to ensure that the previous task's active_mm
+	@ has the correct translation for next's task stack, the architecture
+	@ permits that a translation fault caused by a speculative access is
+	@ taken once the result of the access should become architecturally
+	@ visible. Usually, we rely on do_translation_fault() to fix this up
+	@ transparently, but that only works for the stack if we are not using
+	@ it when taking the fault. So do a dummy read from next's stack while
+	@ still running from prev's stack, so that any faults get taken here.
+	ldr	r2, [ip]
+#endif
 	mov	sp, ip
 	ret	lr
 #endif
  UNWIND(.fnend		)
 ENDPROC(__switch_to)
 
+#ifdef CONFIG_VMAP_STACK
+	.text
+	.align	2
+__bad_stack:
+	@
+	@ We've just detected an overflow. We need to load the address of this
+	@ CPU's overflow stack into the stack pointer register. We have only one
+	@ register available so let's switch to ARM mode and use the per-CPU
+	@ variable accessor that does not require any scratch registers.
+	@
+	@ We enter here with IP clobbered and its value stashed on the mode
+	@ stack.
+	@
+THUMB(	bx	pc		)
+THUMB(	nop			)
+THUMB(	.arm			)
+	ldr_this_cpu_armv6 ip, overflow_stack_ptr
+
+	str	sp, [ip, #-4]!			@ Preserve original SP value
+	mov	sp, ip				@ Switch to overflow stack
+	pop	{ip}				@ Original SP in IP
+
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+	mov	ip, ip				@ mov expected by unwinder
+	push	{fp, ip, lr, pc}		@ GCC flavor frame record
+#else
+	str	ip, [sp, #-8]!			@ store original SP
+	push	{fpreg, lr}			@ Clang flavor frame record
+#endif
+UNWIND( ldr	ip, [r0, #4]	)		@ load exception LR
+UNWIND( str	ip, [sp, #12]	)		@ store in the frame record
+	ldr	ip, [r0, #12]			@ reload IP
+
+	@ Store the original GPRs to the new stack.
+	svc_entry uaccess=0, overflow_check=0
+
+UNWIND( .save   {sp, pc}	)
+UNWIND( .save   {fpreg, lr}	)
+UNWIND( .setfp  fpreg, sp	)
+
+	ldr	fpreg, [sp, #S_SP]		@ Add our frame record
+						@ to the linked list
+#if defined(CONFIG_UNWINDER_FRAME_POINTER) && defined(CONFIG_CC_IS_GCC)
+	ldr	r1, [fp, #4]			@ reload SP at entry
+	add	fp, fp, #12
+#else
+	ldr	r1, [fpreg, #8]
+#endif
+	str	r1, [sp, #S_SP]			@ store in pt_regs
+
+	@ Stash the regs for handle_bad_stack
+	mov	r0, sp
+
+	@ Time to die
+	bl	handle_bad_stack
+	nop
+UNWIND( .fnend			)
+ENDPROC(__bad_stack)
+#endif
+
 	__INIT
 
 /*
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 9f01b229841a..347c975c5d9d 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -429,3 +429,40 @@ scno	.req	r7		@ syscall number
 tbl	.req	r8		@ syscall table pointer
 why	.req	r8		@ Linux syscall (!= 0)
 tsk	.req	r9		@ current thread_info
+
+	.macro	do_overflow_check, frame_size:req
+#ifdef CONFIG_VMAP_STACK
+	@
+	@ Test whether the SP has overflowed. Task and IRQ stacks are aligned
+	@ so that SP & BIT(THREAD_SIZE_ORDER + PAGE_SHIFT) should always be
+	@ zero.
+	@
+ARM(	tst	sp, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT)	)
+THUMB(	tst	r1, #1 << (THREAD_SIZE_ORDER + PAGE_SHIFT)	)
+THUMB(	it	ne						)
+	bne	.Lstack_overflow_check\@
+
+	.pushsection	.text
+.Lstack_overflow_check\@:
+	@
+	@ The stack pointer is not pointing to a valid vmap'ed stack, but it
+	@ may be pointing into the linear map instead, which may happen if we
+	@ are already running from the overflow stack. We cannot detect overflow
+	@ in such cases so just carry on.
+	@
+	str	ip, [r0, #12]			@ Stash IP on the mode stack
+	ldr_va	ip, high_memory			@ Start of VMALLOC space
+ARM(	cmp	sp, ip			)	@ SP in vmalloc space?
+THUMB(	cmp	r1, ip			)
+THUMB(	itt	lo			)
+	ldrlo	ip, [r0, #12]			@ Restore IP
+	blo	.Lout\@				@ Carry on
+
+THUMB(	sub	r1, sp, r1		)	@ Restore original R1
+THUMB(	sub	sp, r1			)	@ Restore original SP
+	add	sp, sp, #\frame_size		@ Undo svc_entry's SP change
+	b	__bad_stack			@ Handle VMAP stack overflow
+	.popsection
+.Lout\@:
+#endif
+	.endm
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index c04dd94630c7..500612d3da2e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -424,6 +424,13 @@ ENDPROC(secondary_startup)
 ENDPROC(secondary_startup_arm)
 
 ENTRY(__secondary_switched)
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+	@ as the ID map does not cover the vmalloc region.
+	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
+	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
+	instr_sync
+#endif
 	adr_l	r7, secondary_data + 12		@ get secondary_data.stack
 	ldr	sp, [r7]
 	ldr	r0, [r7, #4]			@ get secondary_data.task
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 380376f55554..74a1c878bc7a 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -54,7 +54,14 @@ static void __init init_irq_stacks(void)
 	int cpu;
 
 	for_each_possible_cpu(cpu) {
-		stack = (u8 *)__get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER);
+		if (!IS_ENABLED(CONFIG_VMAP_STACK))
+			stack = (u8 *)__get_free_pages(GFP_KERNEL,
+						       THREAD_SIZE_ORDER);
+		else
+			stack = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN,
+					       THREADINFO_GFP, NUMA_NO_NODE,
+					       __builtin_return_address(0));
+
 		if (WARN_ON(!stack))
 			break;
 		per_cpu(irq_stack_ptr, cpu) = &stack[THREAD_SIZE];
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 284a80c0b6e1..039feb7cd590 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -141,10 +141,10 @@ EXPORT_SYMBOL(outer_cache);
 int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
 
 struct stack {
-	u32 irq[3];
-	u32 abt[3];
-	u32 und[3];
-	u32 fiq[3];
+	u32 irq[4];
+	u32 abt[4];
+	u32 und[4];
+	u32 fiq[4];
 } ____cacheline_aligned;
 
 #ifndef CONFIG_CPU_V7M
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 43077e11dafd..a86a1d4f3461 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -67,6 +67,12 @@ ENTRY(__cpu_suspend)
 	ldr	r4, =cpu_suspend_size
 #endif
 	mov	r5, sp			@ current virtual SP
+#ifdef CONFIG_VMAP_STACK
+	@ Run the suspend code from the overflow stack so we don't have to rely
+	@ on vmalloc-to-phys conversions anywhere in the arch suspend code.
+	@ The original SP value captured in R5 will be restored on the way out.
+	ldr_this_cpu sp, overflow_stack_ptr, r6, r7
+#endif
 	add	r4, r4, #12		@ Space for pgd, virt sp, phys resume fn
 	sub	sp, sp, r4		@ allocate CPU state on stack
 	ldr	r3, =sleep_save_sp
@@ -113,6 +119,13 @@ ENTRY(cpu_resume_mmu)
 ENDPROC(cpu_resume_mmu)
 	.popsection
 cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+	@ as the ID map does not cover the vmalloc region.
+	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
+	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
+	instr_sync
+#endif
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1b8bef286fbc..8b076eaeaf61 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -123,7 +123,8 @@ void dump_backtrace_stm(u32 *stack, u32 instruction, const char *loglvl)
 static int verify_stack(unsigned long sp)
 {
 	if (sp < PAGE_OFFSET ||
-	    (sp > (unsigned long)high_memory && high_memory != NULL))
+	    (!IS_ENABLED(CONFIG_VMAP_STACK) &&
+	     sp > (unsigned long)high_memory && high_memory != NULL))
 		return -EFAULT;
 
 	return 0;
@@ -293,7 +294,8 @@ static int __die(const char *str, int err, struct pt_regs *regs)
 
 	if (!user_mode(regs) || in_interrupt()) {
 		dump_mem(KERN_EMERG, "Stack: ", regs->ARM_sp,
-			 ALIGN(regs->ARM_sp, THREAD_SIZE));
+			 ALIGN(regs->ARM_sp - THREAD_SIZE, THREAD_ALIGN)
+			 + THREAD_SIZE);
 		dump_backtrace(regs, tsk, KERN_EMERG);
 		dump_instr(KERN_EMERG, regs);
 	}
@@ -840,3 +842,66 @@ void __init early_trap_init(void *vectors_base)
 	 */
 #endif
 }
+
+#ifdef CONFIG_VMAP_STACK
+
+DECLARE_PER_CPU(u8 *, irq_stack_ptr);
+
+asmlinkage DEFINE_PER_CPU(u8 *, overflow_stack_ptr);
+
+static int __init allocate_overflow_stacks(void)
+{
+	u8 *stack;
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		stack = (u8 *)__get_free_page(GFP_KERNEL);
+		if (WARN_ON(!stack))
+			return -ENOMEM;
+		per_cpu(overflow_stack_ptr, cpu) = &stack[OVERFLOW_STACK_SIZE];
+	}
+	return 0;
+}
+early_initcall(allocate_overflow_stacks);
+
+asmlinkage void handle_bad_stack(struct pt_regs *regs)
+{
+	unsigned long tsk_stk = (unsigned long)current->stack;
+	unsigned long irq_stk = (unsigned long)this_cpu_read(irq_stack_ptr);
+	unsigned long ovf_stk = (unsigned long)this_cpu_read(overflow_stack_ptr);
+
+	console_verbose();
+	pr_emerg("Insufficient stack space to handle exception!");
+
+	pr_emerg("Task stack:     [0x%08lx..0x%08lx]\n",
+		 tsk_stk, tsk_stk + THREAD_SIZE);
+	pr_emerg("IRQ stack:      [0x%08lx..0x%08lx]\n",
+		 irq_stk - THREAD_SIZE, irq_stk);
+	pr_emerg("Overflow stack: [0x%08lx..0x%08lx]\n",
+		 ovf_stk - OVERFLOW_STACK_SIZE, ovf_stk);
+
+	die("kernel stack overflow", regs, 0);
+}
+
+#ifndef CONFIG_ARM_LPAE
+/*
+ * Normally, we rely on the logic in do_translation_fault() to update stale PMD
+ * entries covering the vmalloc space in a task's page tables when it first
+ * accesses the region in question. Unfortunately, this is not sufficient when
+ * the task stack resides in the vmalloc region, as do_translation_fault() is a
+ * C function that needs a stack to run.
+ *
+ * So we need to ensure that these PMD entries are up to date *before* the MM
+ * switch. As we already have some logic in the MM switch path that takes care
+ * of this, let's trigger it by bumping the counter every time the core vmalloc
+ * code modifies a PMD entry in the vmalloc region. Use release semantics on
+ * the store so that other CPUs observing the counter's new value are
+ * guaranteed to see the updated page table entries as well.
+ */
+void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
+{
+	if (start < VMALLOC_END && end > VMALLOC_START)
+		atomic_inc_return_release(&init_mm.context.vmalloc_seq);
+}
+#endif
+#endif
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index e8d729975f12..c5ea328c428d 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -389,7 +389,8 @@ int unwind_frame(struct stackframe *frame)
 
 	/* store the highest address on the stack to avoid crossing it*/
 	ctrl.sp_low = frame->sp;
-	ctrl.sp_high = ALIGN(ctrl.sp_low, THREAD_SIZE);
+	ctrl.sp_high = ALIGN(ctrl.sp_low - THREAD_SIZE, THREAD_ALIGN)
+		       + THREAD_SIZE;
 
 	pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
 		 frame->pc, frame->lr, frame->sp);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index f02d617e3359..aa12b65a7fd6 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -138,12 +138,12 @@ SECTIONS
 #ifdef CONFIG_STRICT_KERNEL_RWX
 	. = ALIGN(1<<SECTION_SHIFT);
 #else
-	. = ALIGN(THREAD_SIZE);
+	. = ALIGN(THREAD_ALIGN);
 #endif
 	__init_end = .;
 
 	_sdata = .;
-	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
 	_edata = .;
 
 	BSS_SECTION(0, 0, 0)
-- 
2.30.2



From ezequiel at vanguardiasur.com.ar  Mon Jan 24 09:55:12 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 14:55:12 -0300
Subject: [PATCH V3 06/10] arm64: dts: imx8mq: Enable both G1 and G2 VPU's
 with vpu-blk-ctrl
In-Reply-To: <202201242024.Xqet4cvg-lkp@intel.com>
References: <20220124023125.414794-7-aford173@gmail.com>
 <202201242024.Xqet4cvg-lkp@intel.com>
Message-ID: <Ye7oACMEBrGm+3E0@eze-laptop>

Hi Adam,

On Mon, Jan 24, 2022 at 09:08:14PM +0800, kernel test robot wrote:
> Hi Adam,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on e783362eb54cd99b2cac8b3a9aeac942e6f6ac07]
> 
> url:    https://github.com/0day-ci/linux/commits/Adam-Ford/media-hantro-imx8mq-imx8mm-Let-VPU-decoders-get-controlled-by-vpu-blk-ctrl/20220124-103340
> base:   e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
> config: arm64-buildonly-randconfig-r001-20220124 (https://download.01.org/0day-ci/archive/20220124/202201242024.Xqet4cvg-lkp at intel.com/config)
> compiler: aarch64-linux-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/0day-ci/linux/commit/a74e6df1159d70d74f2a6988748f8e9648478d86
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Adam-Ford/media-hantro-imx8mq-imx8mm-Let-VPU-decoders-get-controlled-by-vpu-blk-ctrl/20220124-103340
>         git checkout a74e6df1159d70d74f2a6988748f8e9648478d86
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All errors (new ones prefixed by >>):
> 
> >> Error: arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi:275.1-5 Label or path vpu not found

Would you mind including a patch that removes the vpu reference from arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi ?
Namely, removing:

&vpu {
	status = "okay";
};

Memory-to-memory devices are meant to be enabled by default at the top dtsi level.
This will then fix this issue, when you change the node labels to vpu_g1 and
vpu_g2.

Thanks!
Ezequiel

>    FATAL ERROR: Syntax error parsing input tree
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From ezequiel at vanguardiasur.com.ar  Mon Jan 24 09:55:46 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 14:55:46 -0300
Subject: [PATCH V3 08/10] dt-bindings: media: nxp, imx8mq-vpu: Add
 support for G1 on imx8mm
In-Reply-To: <20220124023125.414794-9-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-9-aford173@gmail.com>
Message-ID: <Ye7oIuzP6+7f/0hX@eze-laptop>

On Sun, Jan 23, 2022 at 08:31:22PM -0600, Adam Ford wrote:
> The i.MX8M mini appears to have a similar G1 decoder but the
> post-processing isn't present, so different compatible flag is required.
> Since all the other parameters are the same with imx8mq, just add
> the new compatible flag to nxp,imx8mq-vpu.yaml.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

> diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> index 9c28d562112b..7dc13a4b1805 100644
> --- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> @@ -5,7 +5,7 @@
>  $id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
>  $schema: "http://devicetree.org/meta-schemas/core.yaml#"
>  
> -title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
> +title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
>  
>  maintainers:
>    - Philipp Zabel <p.zabel at pengutronix.de>
> @@ -20,6 +20,7 @@ properties:
>          deprecated: true
>        - const: nxp,imx8mq-vpu-g1
>        - const: nxp,imx8mq-vpu-g2
> +      - const: nxp,imx8mm-vpu-g1
>  
>    reg:
>      maxItems: 1
> -- 
> 2.32.0
> 


From broonie at kernel.org  Mon Jan 24 09:55:25 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 17:55:25 +0000
Subject: [PATCH v1 0/2] kselftest/arm64: Small fixes for sve-ptrace test
Message-ID: <20220124175527.3260234-1-broonie@kernel.org>

A couple of fairly minor fixes for the sve-ptrace test, one output thing
and one for an issue which would generate spurious false positives.

Mark Brown (2):
  kselftest/arm64: Skip VL_INHERIT tests for unsupported vector types
  kselftest/arm64: Correct logging of FPSIMD register read via ptrace

 tools/testing/selftests/arm64/fp/sve-ptrace.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 09:55:26 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 17:55:26 +0000
Subject: [PATCH v1 1/2] kselftest/arm64: Skip VL_INHERIT tests for unsupported
 vector types
In-Reply-To: <20220124175527.3260234-1-broonie@kernel.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
Message-ID: <20220124175527.3260234-2-broonie@kernel.org>

Currently we unconditionally test the ability to set the vector length
inheritance flag via ptrace meaning that we generate false failures on
systems that don't support SVE when we attempt to set the vector length
there. Check the hwcap and mark the tests as skipped when it's not present.

Fixes: 0ba1ce1e86052d ("selftests: arm64: Add coverage of ptrace flags for SVE VL inheritance")
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index af798b9d232c..0cf78360c5bc 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -557,7 +557,14 @@ static int do_parent(pid_t child)
 		}
 
 		/* prctl() flags */
-		ptrace_set_get_inherit(child, &vec_types[i]);
+		if (getauxval(vec_types[i].hwcap_type) & vec_types[i].hwcap) {
+			ptrace_set_get_inherit(child, &vec_types[i]);
+		} else {
+			ksft_test_result_skip("%s SVE_PT_VL_INHERIT set\n",
+					      vec_types[i].name);
+			ksft_test_result_skip("%s SVE_PT_VL_INHERIT cleared\n",
+					      vec_types[i].name);
+		}
 
 		/* Step through every possible VQ */
 		for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 09:55:27 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 17:55:27 +0000
Subject: [PATCH v1 2/2] kselftest/arm64: Correct logging of FPSIMD register
 read via ptrace
In-Reply-To: <20220124175527.3260234-1-broonie@kernel.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
Message-ID: <20220124175527.3260234-3-broonie@kernel.org>

There's a cut'n'paste error in the logging for our test for reading register
state back via ptrace, correctly say that we did a read instead of a write.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index 0cf78360c5bc..a3c1e67441f9 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -261,7 +261,7 @@ static void ptrace_sve_fpsimd(pid_t child, const struct vec_type *type)
 	}
 
 	ksft_test_result((sve->flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD,
-			 "Set FPSIMD registers via %s\n", type->name);
+			 "Got FPSIMD registers via %s\n", type->name);
 	if ((sve->flags & SVE_PT_REGS_MASK) != SVE_PT_REGS_FPSIMD)
 		goto out;
 
-- 
2.30.2



From linux at armlinux.org.uk  Mon Jan 24 09:56:57 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Mon, 24 Jan 2022 17:56:57 +0000
Subject: [PATCH v5 00/32] ARM vmap'ed and IRQ stacks roundup
In-Reply-To: <20220124174744.1054712-1-ardb@kernel.org>
References: <20220124174744.1054712-1-ardb@kernel.org>
Message-ID: <Ye7oabF/ewS0pSKw@shell.armlinux.org.uk>

On Mon, Jan 24, 2022 at 06:47:12PM +0100, Ard Biesheuvel wrote:
> This v5 series is a combined followup to
> 
> - IRQ stacks support for v7 SMP systems [0],
> - vmap'ed stacks support for v7 SMP systems[1],
> - extending support for both IRQ stacks and vmap'ed stacks for all
>   remaining configurations, including v6/v7 SMP multiplatform kernels
>   and uniprocessor configurations including v7-M [2]
> 
> [0] https://lore.kernel.org/linux-arm-kernel/20211115084732.3704393-1-ardb at kernel.org/
> [1] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-1-ardb at kernel.org/
> [2] https://lore.kernel.org/linux-arm-kernel/20211206164659.1495084-1-ardb at kernel.org/
> 
> This work was queued up in the ARM tree for a while, but due to problems
> with the vmap'ed stacks code, which was difficult to revert in
> isolation, the whole stack was dropped again.
> 
> In order to prevent similar problems from occurring this time around,
> the series was reorganized so that the vmap'ed stacks changes appear at
> the very end, which also results in a more natural progression of the
> changes.
> 
> Changes since v4:
> - incorporate fixups to avoid build failures on Clang related to
>   literals in subsections,
> - switch from the ID map to swapper_pg_dir as early as possible when
>   onlining a CPU on !LPAE, to ensure that the stack is mapped,
> - use SMP_ON_UP patching to elide HWCAP_TLS tests on SMP+v6,
> - clean up __switch_to() for Thumb2 a bit more,
> - add patch to make the vmalloc_seq counter SMP safe,
> - use enter_lazy_tlb() hook on !LPAE to ensure that the active_mm used
>   by a kernel thread has a mapping for its vmap'ed stack,

Hi Ard,

I still have the original code in devel-stable, and being a guaranteed
stable branch, it's not something I'll be dropping... Please can I have
fixes on top of what is already there please?

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From robin.murphy at arm.com  Mon Jan 24 09:57:01 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Mon, 24 Jan 2022 17:57:01 +0000
Subject: [PATCH] arm64: dts: juno: Remove GICv2m dma-range
Message-ID: <856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com>

Although it is painstakingly honest to describe all 3 PCI windows in
"dma-ranges", it misses the the subtle distinction that the window for
the GICv2m range is normally programmed for Device memory attributes
rather than Normal Cacheable like the DRAM windows. Since MMU-401 only
offers stage 2 translation, this means that when the PCI SMMU is
enabled, accesses through that IPA range unexpectedly lose coherency if
mapped as cacheable at the SMMU, due to the attribute combining rules.
Since an extra 256KB is neither here nor there when we still have 10GB
worth of usable address space, rather than attempting to describe and
cope with this detail let's just remove the offending range. If the SMMU
is not used then it makes no difference anyway.

Fixes: 4ac4d146cb63 ("arm64: dts: juno: Describe PCI dma-ranges")
Reported-by: Anders Roxell <anders.roxell at linaro.org>
Signed-off-by: Robin Murphy <robin.murphy at arm.com>
---

Sorry it took a while to catch up on this...

 arch/arm64/boot/dts/arm/juno-base.dtsi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 6288e104a089..a2635b14da30 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -543,8 +543,7 @@ pcie_ctlr: pcie at 40000000 {
 			 <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
 			 <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
 		/* Standard AXI Translation entries as programmed by EDK2 */
-		dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
-			     <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
+		dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
 			     <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
 		#interrupt-cells = <1>;
 		interrupt-map-mask = <0 0 0 7>;
-- 
2.28.0.dirty



From ardb at kernel.org  Mon Jan 24 09:57:52 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Mon, 24 Jan 2022 18:57:52 +0100
Subject: [PATCH v5 00/32] ARM vmap'ed and IRQ stacks roundup
In-Reply-To: <Ye7oabF/ewS0pSKw@shell.armlinux.org.uk>
References: <20220124174744.1054712-1-ardb@kernel.org>
 <Ye7oabF/ewS0pSKw@shell.armlinux.org.uk>
Message-ID: <CAMj1kXErsMZr61+NxPrGRxGk0th7sAzCDRMwGcnf08GK7-7OOw@mail.gmail.com>

On Mon, 24 Jan 2022 at 18:57, Russell King (Oracle)
<linux at armlinux.org.uk> wrote:
>
> On Mon, Jan 24, 2022 at 06:47:12PM +0100, Ard Biesheuvel wrote:
> > This v5 series is a combined followup to
> >
> > - IRQ stacks support for v7 SMP systems [0],
> > - vmap'ed stacks support for v7 SMP systems[1],
> > - extending support for both IRQ stacks and vmap'ed stacks for all
> >   remaining configurations, including v6/v7 SMP multiplatform kernels
> >   and uniprocessor configurations including v7-M [2]
> >
> > [0] https://lore.kernel.org/linux-arm-kernel/20211115084732.3704393-1-ardb at kernel.org/
> > [1] https://lore.kernel.org/linux-arm-kernel/20211122092816.2865873-1-ardb at kernel.org/
> > [2] https://lore.kernel.org/linux-arm-kernel/20211206164659.1495084-1-ardb at kernel.org/
> >
> > This work was queued up in the ARM tree for a while, but due to problems
> > with the vmap'ed stacks code, which was difficult to revert in
> > isolation, the whole stack was dropped again.
> >
> > In order to prevent similar problems from occurring this time around,
> > the series was reorganized so that the vmap'ed stacks changes appear at
> > the very end, which also results in a more natural progression of the
> > changes.
> >
> > Changes since v4:
> > - incorporate fixups to avoid build failures on Clang related to
> >   literals in subsections,
> > - switch from the ID map to swapper_pg_dir as early as possible when
> >   onlining a CPU on !LPAE, to ensure that the stack is mapped,
> > - use SMP_ON_UP patching to elide HWCAP_TLS tests on SMP+v6,
> > - clean up __switch_to() for Thumb2 a bit more,
> > - add patch to make the vmalloc_seq counter SMP safe,
> > - use enter_lazy_tlb() hook on !LPAE to ensure that the active_mm used
> >   by a kernel thread has a mapping for its vmap'ed stack,
>
> Hi Ard,
>
> I still have the original code in devel-stable, and being a guaranteed
> stable branch, it's not something I'll be dropping... Please can I have
> fixes on top of what is already there please?
>

Sure.


From ezequiel at vanguardiasur.com.ar  Mon Jan 24 09:59:37 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 14:59:37 -0300
Subject: [PATCH V3 06/10] arm64: dts: imx8mq: Enable both G1 and G2 VPU's
 with vpu-blk-ctrl
In-Reply-To: <20220124023125.414794-7-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-7-aford173@gmail.com>
Message-ID: <Ye7pCfcasWunm8F3@eze-laptop>

On Sun, Jan 23, 2022 at 08:31:20PM -0600, Adam Ford wrote:
> With the Hantro G1 and G2 now setup to run independently, update
> the device tree to allow both to operate.  This requires the
> vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
> certain clock enabled to handle the gating of the G1 and G2
> fuses, the clock-parents and clock-rates for the various VPU's
> to be moved into the pgc_vpu because they cannot get re-parented
> once enabled, and the pgc_vpu is the highest in the chain.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks,
Ezequiel

> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 2df2510d0118..549b2440f55d 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
>  					pgc_vpu: power-domain at 6 {
>  						#power-domain-cells = <0>;
>  						reg = <IMX8M_POWER_DOMAIN_VPU>;
> -						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> +						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +						assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> +								  <&clk IMX8MQ_CLK_VPU_G2>,
> +								  <&clk IMX8MQ_CLK_VPU_BUS>,
> +								  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> +						assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_SYS1_PLL_800M>,
> +									 <&clk IMX8MQ_VPU_PLL>;
> +						assigned-clock-rates = <600000000>,
> +								       <600000000>,
> +								       <800000000>,
> +								       <0>;
>  					};
>  
>  					pgc_disp: power-domain at 7 {
> @@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
>  			status = "disabled";
>  		};
>  
> -		vpu: video-codec at 38300000 {
> -			compatible = "nxp,imx8mq-vpu";
> -			reg = <0x38300000 0x10000>,
> -			      <0x38310000 0x10000>,
> -			      <0x38320000 0x10000>;
> -			reg-names = "g1", "g2", "ctrl";
> -			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> -				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> -			interrupt-names = "g1", "g2";
> +		vpu_g1: video-codec at 38300000 {
> +			compatible = "nxp,imx8mq-vpu-g1";
> +			reg = <0x38300000 0x10000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> +		};
> +
> +		vpu_g2: video-codec at 38310000 {
> +			compatible = "nxp,imx8mq-vpu-g2";
> +			reg = <0x38310000 0x10000>;
> +			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> +		};
> +
> +		vpu_blk_ctrl: blk-ctrl at 38320000 {
> +			compatible = "fsl,imx8mq-vpu-blk-ctrl";
> +			reg = <0x38320000 0x100>;
> +			power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
> +			power-domain-names = "bus", "g1", "g2";
>  			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> -			clock-names = "g1", "g2", "bus";
> -			assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> -					  <&clk IMX8MQ_CLK_VPU_G2>,
> -					  <&clk IMX8MQ_CLK_VPU_BUS>,
> -					  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> -			assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_SYS1_PLL_800M>,
> -						 <&clk IMX8MQ_VPU_PLL>;
> -			assigned-clock-rates = <600000000>, <600000000>,
> -					       <800000000>, <0>;
> -			power-domains = <&pgc_vpu>;
> +				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			clock-names = "g1", "g2";
> +			#power-domain-cells = <1>;
>  		};
>  
>  		pcie0: pcie at 33800000 {
> -- 
> 2.32.0
> 


From james.clark at arm.com  Mon Jan 24 10:02:51 2022
From: james.clark at arm.com (James Clark)
Date: Mon, 24 Jan 2022 18:02:51 +0000
Subject: [RFC V1 08/11] arm64/perf: Enable branch stack sampling
In-Reply-To: <1642998653-21377-9-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-9-git-send-email-anshuman.khandual@arm.com>
Message-ID: <741d159d-fce4-377e-8817-f8a6462f3a71@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> Now that all the required pieces are already in place, just enable the perf
> branch stack sampling support on arm64 platform, by removing the gate which
> blocks it in armpmu_event_init().
> 
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu.c | 25 ++++++++++++++++++++++---
>  1 file changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
> index 0800c8858ed8..2117bf5d3232 100644
> --- a/drivers/perf/arm_pmu.c
> +++ b/drivers/perf/arm_pmu.c
> @@ -537,9 +537,28 @@ static int armpmu_event_init(struct perf_event *event)
>  		!cpumask_test_cpu(event->cpu, &armpmu->supported_cpus))
>  		return -ENOENT;
>  
> -	/* does not support taken branch sampling */
> -	if (has_branch_stack(event))
> -		return -EOPNOTSUPP;
> +	if (has_branch_stack(event)) {
> +		/*
> +		 * BRBE support is absent. Select CONFIG_ARM_BRBE_PMU
> +		 * in the config, before branch stack sampling events
> +		 * can be requested.
> +		 */
> +		if (!IS_ENABLED(CONFIG_ARM_BRBE_PMU)) {
> +			pr_warn_once("BRBE is disabled, select CONFIG_ARM_BRBE_PMU\n");
> +			return -EOPNOTSUPP;
> +		}
> +
> +		/*
> +		 * Branch stack sampling event can not be supported in
> +		 * case either the required driver itself is absent or
> +		 * BRBE buffer, is not supported. Besides checking for
> +		 * the callback prevents a crash in case it's absent.
> +		 */
> +		if (!armpmu->brbe_supported || !armpmu->brbe_supported(event)) {
> +			pr_warn_once("BRBE is not supported\n");
> +			return -EOPNOTSUPP;

brbe_supported() returns false for one permission case, rather than a "not supported" case
so EOPNOTSUPP is the wrong thing to return here for this case otherwise it makes perf
print confusing error messages. 

The brbe_supported() function needs to be split into two, one that handles support and one
that handles permissions and different errors need to be reported. Here is the permission
bit from that function:

  +	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_KERNEL) {
  +		if (!perfmon_capable()) {
  +			pr_warn_once("does not have permission for kernel branch filter\n");
  +			return false;
  +		}
  +	}

> +		}
> +	}
>  
>  	if (armpmu->map_event(event) == -ENOENT)
>  		return -ENOENT;
> 


From andrey.konovalov at linux.dev  Mon Jan 24 10:02:12 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:12 +0100
Subject: [PATCH v6 04/39] kasan,
 page_alloc: simplify kasan_poison_pages call site
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <ae4f9bcf071577258e786bcec4798c145d718c46.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Simplify the code around calling kasan_poison_pages() in
free_pages_prepare().

This patch does no functional changes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v1->v2:
- Don't reorder kasan_poison_pages() and free_pages_prepare().
---
 mm/page_alloc.c | 18 +++++-------------
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index e5f95c6ab0ac..60bc838a4d85 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1302,6 +1302,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 {
 	int bad = 0;
 	bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
+	bool init = want_init_on_free();
 
 	VM_BUG_ON_PAGE(PageTail(page), page);
 
@@ -1374,19 +1375,10 @@ static __always_inline bool free_pages_prepare(struct page *page,
 	 * With hardware tag-based KASAN, memory tags must be set before the
 	 * page becomes unavailable via debug_pagealloc or arch_free_page.
 	 */
-	if (kasan_has_integrated_init()) {
-		bool init = want_init_on_free();
-
-		if (!skip_kasan_poison)
-			kasan_poison_pages(page, order, init);
-	} else {
-		bool init = want_init_on_free();
-
-		if (init)
-			kernel_init_free_pages(page, 1 << order);
-		if (!skip_kasan_poison)
-			kasan_poison_pages(page, order, init);
-	}
+	if (init && !kasan_has_integrated_init())
+		kernel_init_free_pages(page, 1 << order);
+	if (!skip_kasan_poison)
+		kasan_poison_pages(page, order, init);
 
 	/*
 	 * arch_free_page() can make the page's contents inaccessible.  s390
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:11 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:11 +0100
Subject: [PATCH v6 03/39] kasan,
 page_alloc: merge kasan_free_pages into free_pages_prepare
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <303498d15840bb71905852955c6e2390ecc87139.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Currently, the code responsible for initializing and poisoning memory
in free_pages_prepare() is scattered across two locations:
kasan_free_pages() for HW_TAGS KASAN and free_pages_prepare() itself.
This is confusing.

This and a few following patches combine the code from these two
locations. Along the way, these patches also simplify the performed
checks to make them easier to follow.

Replaces the only caller of kasan_free_pages() with its implementation.

As kasan_has_integrated_init() is only true when CONFIG_KASAN_HW_TAGS
is enabled, moving the code does no functional changes.

This patch is not useful by itself but makes the simplifications in
the following patches easier to follow.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v2->v3:
- Update patch description.
---
 include/linux/kasan.h |  8 --------
 mm/kasan/common.c     |  2 +-
 mm/kasan/hw_tags.c    | 11 -----------
 mm/page_alloc.c       |  6 ++++--
 4 files changed, 5 insertions(+), 22 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 4a45562d8893..a8bfe9f157c9 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -96,7 +96,6 @@ static inline bool kasan_hw_tags_enabled(void)
 }
 
 void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags);
-void kasan_free_pages(struct page *page, unsigned int order);
 
 #else /* CONFIG_KASAN_HW_TAGS */
 
@@ -117,13 +116,6 @@ static __always_inline void kasan_alloc_pages(struct page *page,
 	BUILD_BUG();
 }
 
-static __always_inline void kasan_free_pages(struct page *page,
-					     unsigned int order)
-{
-	/* Only available for integrated init. */
-	BUILD_BUG();
-}
-
 #endif /* CONFIG_KASAN_HW_TAGS */
 
 static inline bool kasan_has_integrated_init(void)
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index 92196562687b..a0082fad48b1 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -387,7 +387,7 @@ static inline bool ____kasan_kfree_large(void *ptr, unsigned long ip)
 	}
 
 	/*
-	 * The object will be poisoned by kasan_free_pages() or
+	 * The object will be poisoned by kasan_poison_pages() or
 	 * kasan_slab_free_mempool().
 	 */
 
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 7355cb534e4f..0b8225add2e4 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -213,17 +213,6 @@ void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags)
 	}
 }
 
-void kasan_free_pages(struct page *page, unsigned int order)
-{
-	/*
-	 * This condition should match the one in free_pages_prepare() in
-	 * page_alloc.c.
-	 */
-	bool init = want_init_on_free();
-
-	kasan_poison_pages(page, order, init);
-}
-
 #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
 
 void kasan_enable_tagging_sync(void)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 012170b1c47a..e5f95c6ab0ac 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1368,15 +1368,17 @@ static __always_inline bool free_pages_prepare(struct page *page,
 
 	/*
 	 * As memory initialization might be integrated into KASAN,
-	 * kasan_free_pages and kernel_init_free_pages must be
+	 * KASAN poisoning and memory initialization code must be
 	 * kept together to avoid discrepancies in behavior.
 	 *
 	 * With hardware tag-based KASAN, memory tags must be set before the
 	 * page becomes unavailable via debug_pagealloc or arch_free_page.
 	 */
 	if (kasan_has_integrated_init()) {
+		bool init = want_init_on_free();
+
 		if (!skip_kasan_poison)
-			kasan_free_pages(page, order);
+			kasan_poison_pages(page, order, init);
 	} else {
 		bool init = want_init_on_free();
 
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:09 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:09 +0100
Subject: [PATCH v6 01/39] kasan,
 page_alloc: deduplicate should_skip_kasan_poison
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <658b79f5fb305edaf7dc16bc52ea870d3220d4a8.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Currently, should_skip_kasan_poison() has two definitions: one for when
CONFIG_DEFERRED_STRUCT_PAGE_INIT is enabled, one for when it's not.

Instead of duplicating the checks, add a deferred_pages_enabled()
helper and use it in a single should_skip_kasan_poison() definition.

Also move should_skip_kasan_poison() closer to its caller and clarify
all conditions in the comment.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v2->v3:
- Update patch description.
---
 mm/page_alloc.c | 55 +++++++++++++++++++++++++++++--------------------
 1 file changed, 33 insertions(+), 22 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3589febc6d31..25d4f9ad3525 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -378,25 +378,9 @@ int page_group_by_mobility_disabled __read_mostly;
  */
 static DEFINE_STATIC_KEY_TRUE(deferred_pages);
 
-/*
- * Calling kasan_poison_pages() only after deferred memory initialization
- * has completed. Poisoning pages during deferred memory init will greatly
- * lengthen the process and cause problem in large memory systems as the
- * deferred pages initialization is done with interrupt disabled.
- *
- * Assuming that there will be no reference to those newly initialized
- * pages before they are ever allocated, this should have no effect on
- * KASAN memory tracking as the poison will be properly inserted at page
- * allocation time. The only corner case is when pages are allocated by
- * on-demand allocation and then freed again before the deferred pages
- * initialization is done, but this is not likely to happen.
- */
-static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
+static inline bool deferred_pages_enabled(void)
 {
-	return static_branch_unlikely(&deferred_pages) ||
-	       (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
-		(fpi_flags & FPI_SKIP_KASAN_POISON)) ||
-	       PageSkipKASanPoison(page);
+	return static_branch_unlikely(&deferred_pages);
 }
 
 /* Returns true if the struct page for the pfn is uninitialised */
@@ -447,11 +431,9 @@ defer_init(int nid, unsigned long pfn, unsigned long end_pfn)
 	return false;
 }
 #else
-static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
+static inline bool deferred_pages_enabled(void)
 {
-	return (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
-		(fpi_flags & FPI_SKIP_KASAN_POISON)) ||
-	       PageSkipKASanPoison(page);
+	return false;
 }
 
 static inline bool early_page_uninitialised(unsigned long pfn)
@@ -1271,6 +1253,35 @@ static int free_tail_pages_check(struct page *head_page, struct page *page)
 	return ret;
 }
 
+/*
+ * Skip KASAN memory poisoning when either:
+ *
+ * 1. Deferred memory initialization has not yet completed,
+ *    see the explanation below.
+ * 2. Skipping poisoning is requested via FPI_SKIP_KASAN_POISON,
+ *    see the comment next to it.
+ * 3. Skipping poisoning is requested via __GFP_SKIP_KASAN_POISON,
+ *    see the comment next to it.
+ *
+ * Poisoning pages during deferred memory init will greatly lengthen the
+ * process and cause problem in large memory systems as the deferred pages
+ * initialization is done with interrupt disabled.
+ *
+ * Assuming that there will be no reference to those newly initialized
+ * pages before they are ever allocated, this should have no effect on
+ * KASAN memory tracking as the poison will be properly inserted at page
+ * allocation time. The only corner case is when pages are allocated by
+ * on-demand allocation and then freed again before the deferred pages
+ * initialization is done, but this is not likely to happen.
+ */
+static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
+{
+	return deferred_pages_enabled() ||
+	       (!IS_ENABLED(CONFIG_KASAN_GENERIC) &&
+		(fpi_flags & FPI_SKIP_KASAN_POISON)) ||
+	       PageSkipKASanPoison(page);
+}
+
 static void kernel_init_free_pages(struct page *page, int numpages, bool zero_tags)
 {
 	int i;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:10 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:10 +0100
Subject: [PATCH v6 02/39] kasan,
 page_alloc: move tag_clear_highpage out of kernel_init_free_pages
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <7719874e68b23902629c7cf19f966c4fd5f57979.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Currently, kernel_init_free_pages() serves two purposes: it either only
zeroes memory or zeroes both memory and memory tags via a different
code path. As this function has only two callers, each using only one
code path, this behaviour is confusing.

Pull the code that zeroes both memory and tags out of
kernel_init_free_pages().

As a result of this change, the code in free_pages_prepare() starts to
look complicated, but this is improved in the few following patches.
Those improvements are not integrated into this patch to make diffs
easier to read.

This patch does no functional changes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v2->v3:
- Update patch description.
---
 mm/page_alloc.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 25d4f9ad3525..012170b1c47a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1282,16 +1282,10 @@ static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags)
 	       PageSkipKASanPoison(page);
 }
 
-static void kernel_init_free_pages(struct page *page, int numpages, bool zero_tags)
+static void kernel_init_free_pages(struct page *page, int numpages)
 {
 	int i;
 
-	if (zero_tags) {
-		for (i = 0; i < numpages; i++)
-			tag_clear_highpage(page + i);
-		return;
-	}
-
 	/* s390's use of memset() could override KASAN redzones. */
 	kasan_disable_current();
 	for (i = 0; i < numpages; i++) {
@@ -1387,7 +1381,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 		bool init = want_init_on_free();
 
 		if (init)
-			kernel_init_free_pages(page, 1 << order, false);
+			kernel_init_free_pages(page, 1 << order);
 		if (!skip_kasan_poison)
 			kasan_poison_pages(page, order, init);
 	}
@@ -2430,9 +2424,17 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
 
 		kasan_unpoison_pages(page, order, init);
-		if (init)
-			kernel_init_free_pages(page, 1 << order,
-					       gfp_flags & __GFP_ZEROTAGS);
+
+		if (init) {
+			if (gfp_flags & __GFP_ZEROTAGS) {
+				int i;
+
+				for (i = 0; i < 1 << order; i++)
+					tag_clear_highpage(page + i);
+			} else {
+				kernel_init_free_pages(page, 1 << order);
+			}
+		}
 	}
 
 	set_page_owner(page, order, gfp_flags);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:08 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:08 +0100
Subject: [PATCH v6 00/39] kasan, vmalloc,
 arm64: add vmalloc tagging support for SW/HW_TAGS
Message-ID: <cover.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Hi,

This patchset adds vmalloc tagging support for SW_TAGS and HW_TAGS
KASAN modes.

The tree with patches is available here:

https://github.com/xairy/linux/tree/up-kasan-vmalloc-tags-v6

About half of patches are cleanups I went for along the way. None of
them seem to be important enough to go through stable, so I decided
not to split them out into separate patches/series.

The patchset is partially based on an early version of the HW_TAGS
patchset by Vincenzo that had vmalloc support. Thus, I added a
Co-developed-by tag into a few patches.

SW_TAGS vmalloc tagging support is straightforward. It reuses all of
the generic KASAN machinery, but uses shadow memory to store tags
instead of magic values. Naturally, vmalloc tagging requires adding
a few kasan_reset_tag() annotations to the vmalloc code.

HW_TAGS vmalloc tagging support stands out. HW_TAGS KASAN is based on
Arm MTE, which can only assigns tags to physical memory. As a result,
HW_TAGS KASAN only tags vmalloc() allocations, which are backed by
page_alloc memory. It ignores vmap() and others.

Thanks!

Changes in v5->v6:
- Rebased onto mainline/5.17-rc1.
- Drop unnecessary explicit checks for software KASAN modes from
  should_skip_init().

Changes in v4->v5:
- Rebase onto fresh mm.
- Mention optimization intention in the comment for __GFP_ZEROTAGS.
- Replace "kasan: simplify kasan_init_hw_tags" with "kasan: clean up
  feature flags for HW_TAGS mode".
- Use true as kasan_flag_vmalloc static key default.
- Cosmetic changes to __def_gfpflag_names_kasan and __GFP_BITS_SHIFT.

Changes in v3->v4:
- Rebase onto fresh mm.
- Rename KASAN_VMALLOC_NOEXEC to KASAN_VMALLOC_PROT_NORMAL.
- Compare prot with PAGE_KERNEL instead of using pgprot_nx() to
  indentify normal non-executable mappings.
- Rename arch_vmalloc_pgprot_modify() to arch_vmap_pgprot_tagged().
- Move checks from arch_vmap_pgprot_tagged() to __vmalloc_node_range()
  as the same condition is used for other things in subsequent patches.
- Use proper kasan_hw_tags_enabled() checks instead of
  IS_ENABLED(CONFIG_KASAN_HW_TAGS).
- Set __GFP_SKIP_KASAN_UNPOISON and __GFP_SKIP_ZERO flags instead of
  resetting.
- Only define KASAN GFP flags when when HW_TAGS KASAN is enabled.
- Move setting KASAN GFP flags to __vmalloc_node_range() and do it
  only for normal non-executable mapping when HW_TAGS KASAN is enabled.
- Add new GFP flags to include/trace/events/mmflags.h.
- Don't forget to save tagged addr to vm_struct->addr for VM_ALLOC
  so that find_vm_area(addr)->addr == addr for vmalloc().
- Reset pointer tag in change_memory_common().
- Add test checks for set_memory_*() on vmalloc() allocations.
- Minor patch descriptions and comments fixes.

Changes in v2->v3:
- Rebase onto mm.
- New patch: "kasan, arm64: reset pointer tags of vmapped stacks".
- New patch: "kasan, vmalloc: don't tag executable vmalloc allocations".
- New patch: "kasan, arm64: don't tag executable vmalloc allocations".
- Allowing enabling KASAN_VMALLOC with SW/HW_TAGS is moved to
  "kasan: allow enabling KASAN_VMALLOC and SW/HW_TAGS", as this can only
  be done once executable allocations are no longer tagged.
- Minor fixes, see patches for lists of changes.

Changes in v1->v2:
- Move memory init for vmalloc() into vmalloc code for HW_TAGS KASAN.
- Minor fixes and code reshuffling, see patches for lists of changes.

Acked-by: Marco Elver <elver at google.com>

Andrey Konovalov (39):
  kasan, page_alloc: deduplicate should_skip_kasan_poison
  kasan, page_alloc: move tag_clear_highpage out of
    kernel_init_free_pages
  kasan, page_alloc: merge kasan_free_pages into free_pages_prepare
  kasan, page_alloc: simplify kasan_poison_pages call site
  kasan, page_alloc: init memory of skipped pages on free
  kasan: drop skip_kasan_poison variable in free_pages_prepare
  mm: clarify __GFP_ZEROTAGS comment
  kasan: only apply __GFP_ZEROTAGS when memory is zeroed
  kasan, page_alloc: refactor init checks in post_alloc_hook
  kasan, page_alloc: merge kasan_alloc_pages into post_alloc_hook
  kasan, page_alloc: combine tag_clear_highpage calls in post_alloc_hook
  kasan, page_alloc: move SetPageSkipKASanPoison in post_alloc_hook
  kasan, page_alloc: move kernel_init_free_pages in post_alloc_hook
  kasan, page_alloc: rework kasan_unpoison_pages call site
  kasan: clean up metadata byte definitions
  kasan: define KASAN_VMALLOC_INVALID for SW_TAGS
  kasan, x86, arm64, s390: rename functions for modules shadow
  kasan, vmalloc: drop outdated VM_KASAN comment
  kasan: reorder vmalloc hooks
  kasan: add wrappers for vmalloc hooks
  kasan, vmalloc: reset tags in vmalloc functions
  kasan, fork: reset pointer tags of vmapped stacks
  kasan, arm64: reset pointer tags of vmapped stacks
  kasan, vmalloc: add vmalloc tagging for SW_TAGS
  kasan, vmalloc, arm64: mark vmalloc mappings as pgprot_tagged
  kasan, vmalloc: unpoison VM_ALLOC pages after mapping
  kasan, mm: only define ___GFP_SKIP_KASAN_POISON with HW_TAGS
  kasan, page_alloc: allow skipping unpoisoning for HW_TAGS
  kasan, page_alloc: allow skipping memory init for HW_TAGS
  kasan, vmalloc: add vmalloc tagging for HW_TAGS
  kasan, vmalloc: only tag normal vmalloc allocations
  kasan, arm64: don't tag executable vmalloc allocations
  kasan: mark kasan_arg_stacktrace as __initdata
  kasan: clean up feature flags for HW_TAGS mode
  kasan: add kasan.vmalloc command line flag
  kasan: allow enabling KASAN_VMALLOC and SW/HW_TAGS
  arm64: select KASAN_VMALLOC for SW/HW_TAGS modes
  kasan: documentation updates
  kasan: improve vmalloc tests

 Documentation/dev-tools/kasan.rst   |  17 ++-
 arch/arm64/Kconfig                  |   2 +-
 arch/arm64/include/asm/vmalloc.h    |   6 +
 arch/arm64/include/asm/vmap_stack.h |   5 +-
 arch/arm64/kernel/module.c          |   5 +-
 arch/arm64/mm/pageattr.c            |   2 +-
 arch/arm64/net/bpf_jit_comp.c       |   3 +-
 arch/s390/kernel/module.c           |   2 +-
 arch/x86/kernel/module.c            |   2 +-
 include/linux/gfp.h                 |  35 +++--
 include/linux/kasan.h               |  97 +++++++++-----
 include/linux/vmalloc.h             |  18 +--
 include/trace/events/mmflags.h      |  14 +-
 kernel/fork.c                       |   1 +
 kernel/scs.c                        |   4 +-
 lib/Kconfig.kasan                   |  20 +--
 lib/test_kasan.c                    | 189 ++++++++++++++++++++++++++-
 mm/kasan/common.c                   |   4 +-
 mm/kasan/hw_tags.c                  | 193 ++++++++++++++++++++++------
 mm/kasan/kasan.h                    |  18 ++-
 mm/kasan/shadow.c                   |  63 +++++----
 mm/page_alloc.c                     | 152 +++++++++++++++-------
 mm/vmalloc.c                        |  99 +++++++++++---
 23 files changed, 731 insertions(+), 220 deletions(-)

-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:13 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:13 +0100
Subject: [PATCH v6 05/39] kasan,
 page_alloc: init memory of skipped pages on free
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <1d97df75955e52727a3dc1c4e33b3b50506fc3fd.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Since commit 7a3b83537188 ("kasan: use separate (un)poison implementation
for integrated init"), when all init, kasan_has_integrated_init(), and
skip_kasan_poison are true, free_pages_prepare() doesn't initialize
the page. This is wrong.

Fix it by remembering whether kasan_poison_pages() performed
initialization, and call kernel_init_free_pages() if it didn't.

Reordering kasan_poison_pages() and kernel_init_free_pages() is OK,
since kernel_init_free_pages() can handle poisoned memory.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v2->v3:
- Drop Fixes tag, as the patch won't cleanly apply to older kernels
  anyway. The commit is mentioned in the patch description.

Changes v1->v2:
- Reorder kasan_poison_pages() and free_pages_prepare() in this patch
  instead of doing it in the previous one.
---
 mm/page_alloc.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 60bc838a4d85..f994fd68e3b1 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1375,11 +1375,16 @@ static __always_inline bool free_pages_prepare(struct page *page,
 	 * With hardware tag-based KASAN, memory tags must be set before the
 	 * page becomes unavailable via debug_pagealloc or arch_free_page.
 	 */
-	if (init && !kasan_has_integrated_init())
-		kernel_init_free_pages(page, 1 << order);
-	if (!skip_kasan_poison)
+	if (!skip_kasan_poison) {
 		kasan_poison_pages(page, order, init);
 
+		/* Memory is already initialized if KASAN did it internally. */
+		if (kasan_has_integrated_init())
+			init = false;
+	}
+	if (init)
+		kernel_init_free_pages(page, 1 << order);
+
 	/*
 	 * arch_free_page() can make the page's contents inaccessible.  s390
 	 * does this.  So nothing which can access the page's contents should
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:14 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:14 +0100
Subject: [PATCH v6 06/39] kasan: drop skip_kasan_poison variable in
 free_pages_prepare
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <1d33212e79bc9ef0b4d3863f903875823e89046f.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

skip_kasan_poison is only used in a single place.
Call should_skip_kasan_poison() directly for simplicity.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Suggested-by: Marco Elver <elver at google.com>

---

Changes v1->v2:
- Add this patch.
---
 mm/page_alloc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f994fd68e3b1..8481420d2502 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1301,7 +1301,6 @@ static __always_inline bool free_pages_prepare(struct page *page,
 			unsigned int order, bool check_free, fpi_t fpi_flags)
 {
 	int bad = 0;
-	bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags);
 	bool init = want_init_on_free();
 
 	VM_BUG_ON_PAGE(PageTail(page), page);
@@ -1375,7 +1374,7 @@ static __always_inline bool free_pages_prepare(struct page *page,
 	 * With hardware tag-based KASAN, memory tags must be set before the
 	 * page becomes unavailable via debug_pagealloc or arch_free_page.
 	 */
-	if (!skip_kasan_poison) {
+	if (!should_skip_kasan_poison(page, fpi_flags)) {
 		kasan_poison_pages(page, order, init);
 
 		/* Memory is already initialized if KASAN did it internally. */
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:16 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:16 +0100
Subject: [PATCH v6 08/39] kasan: only apply __GFP_ZEROTAGS when memory is
 zeroed
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <f4f4593f7f675262d29d07c1938db5bd0cd5e285.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

__GFP_ZEROTAGS should only be effective if memory is being zeroed.
Currently, hardware tag-based KASAN violates this requirement.

Fix by including an initialization check along with checking for
__GFP_ZEROTAGS.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 mm/kasan/hw_tags.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 0b8225add2e4..c643740b8599 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -199,11 +199,12 @@ void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags)
 	 * page_alloc.c.
 	 */
 	bool init = !want_init_on_free() && want_init_on_alloc(flags);
+	bool init_tags = init && (flags & __GFP_ZEROTAGS);
 
 	if (flags & __GFP_SKIP_KASAN_POISON)
 		SetPageSkipKASanPoison(page);
 
-	if (flags & __GFP_ZEROTAGS) {
+	if (init_tags) {
 		int i;
 
 		for (i = 0; i != 1 << order; ++i)
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:15 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:15 +0100
Subject: [PATCH v6 07/39] mm: clarify __GFP_ZEROTAGS comment
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <cdffde013973c5634a447513e10ec0d21e8eee29.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

__GFP_ZEROTAGS is intended as an optimization: if memory is zeroed during
allocation, it's possible to set memory tags at the same time with little
performance impact.

Clarify this intention of __GFP_ZEROTAGS in the comment.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v4->v5:
- Mention optimization intention in the comment.
---
 include/linux/gfp.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 80f63c862be5..581a1f47b8a2 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -232,8 +232,10 @@ struct vm_area_struct;
  *
  * %__GFP_ZERO returns a zeroed page on success.
  *
- * %__GFP_ZEROTAGS returns a page with zeroed memory tags on success, if
- * __GFP_ZERO is set.
+ * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
+ * is being zeroed (either via __GFP_ZERO or via init_on_alloc). This flag is
+ * intended for optimization: setting memory tags at the same time as zeroing
+ * memory has minimal additional performace impact.
  *
  * %__GFP_SKIP_KASAN_POISON returns a page which does not need to be poisoned
  * on deallocation. Typically used for userspace pages. Currently only has an
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:17 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:17 +0100
Subject: [PATCH v6 09/39] kasan,
 page_alloc: refactor init checks in post_alloc_hook
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <2283fde963adfd8a2b29a92066f106cc16661a3c.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Separate code for zeroing memory from the code clearing tags in
post_alloc_hook().

This patch is not useful by itself but makes the simplifications in
the following patches easier to follow.

This patch does no functional changes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v2->v3:
- Update patch description.
---
 mm/page_alloc.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8481420d2502..868480d463c7 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2420,19 +2420,21 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		kasan_alloc_pages(page, order, gfp_flags);
 	} else {
 		bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
+		bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
 
 		kasan_unpoison_pages(page, order, init);
 
-		if (init) {
-			if (gfp_flags & __GFP_ZEROTAGS) {
-				int i;
+		if (init_tags) {
+			int i;
 
-				for (i = 0; i < 1 << order; i++)
-					tag_clear_highpage(page + i);
-			} else {
-				kernel_init_free_pages(page, 1 << order);
-			}
+			for (i = 0; i < 1 << order; i++)
+				tag_clear_highpage(page + i);
+
+			init = false;
 		}
+
+		if (init)
+			kernel_init_free_pages(page, 1 << order);
 	}
 
 	set_page_owner(page, order, gfp_flags);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:18 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:18 +0100
Subject: [PATCH v6 10/39] kasan,
 page_alloc: merge kasan_alloc_pages into post_alloc_hook
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <5ac7e0b30f5cbb177ec363ddd7878a3141289592.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Currently, the code responsible for initializing and poisoning memory in
post_alloc_hook() is scattered across two locations: kasan_alloc_pages()
hook for HW_TAGS KASAN and post_alloc_hook() itself. This is confusing.

This and a few following patches combine the code from these two
locations. Along the way, these patches do a step-by-step restructure
the many performed checks to make them easier to follow.

Replace the only caller of kasan_alloc_pages() with its implementation.

As kasan_has_integrated_init() is only true when CONFIG_KASAN_HW_TAGS
is enabled, moving the code does no functional changes.

Also move init and init_tags variables definitions out of
kasan_has_integrated_init() clause in post_alloc_hook(), as they have
the same values regardless of what the if condition evaluates to.

This patch is not useful by itself but makes the simplifications in
the following patches easier to follow.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v2->v3:
- Update patch description.
---
 include/linux/kasan.h |  9 ---------
 mm/kasan/common.c     |  2 +-
 mm/kasan/hw_tags.c    | 22 ----------------------
 mm/page_alloc.c       | 20 +++++++++++++++-----
 4 files changed, 16 insertions(+), 37 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index a8bfe9f157c9..b88ca6b97ba3 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -95,8 +95,6 @@ static inline bool kasan_hw_tags_enabled(void)
 	return kasan_enabled();
 }
 
-void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags);
-
 #else /* CONFIG_KASAN_HW_TAGS */
 
 static inline bool kasan_enabled(void)
@@ -109,13 +107,6 @@ static inline bool kasan_hw_tags_enabled(void)
 	return false;
 }
 
-static __always_inline void kasan_alloc_pages(struct page *page,
-					      unsigned int order, gfp_t flags)
-{
-	/* Only available for integrated init. */
-	BUILD_BUG();
-}
-
 #endif /* CONFIG_KASAN_HW_TAGS */
 
 static inline bool kasan_has_integrated_init(void)
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index a0082fad48b1..d9079ec11f31 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -538,7 +538,7 @@ void * __must_check __kasan_kmalloc_large(const void *ptr, size_t size,
 		return NULL;
 
 	/*
-	 * The object has already been unpoisoned by kasan_alloc_pages() for
+	 * The object has already been unpoisoned by kasan_unpoison_pages() for
 	 * alloc_pages() or by kasan_krealloc() for krealloc().
 	 */
 
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index c643740b8599..76cf2b6229c7 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -192,28 +192,6 @@ void __init kasan_init_hw_tags(void)
 		kasan_stack_collection_enabled() ? "on" : "off");
 }
 
-void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags)
-{
-	/*
-	 * This condition should match the one in post_alloc_hook() in
-	 * page_alloc.c.
-	 */
-	bool init = !want_init_on_free() && want_init_on_alloc(flags);
-	bool init_tags = init && (flags & __GFP_ZEROTAGS);
-
-	if (flags & __GFP_SKIP_KASAN_POISON)
-		SetPageSkipKASanPoison(page);
-
-	if (init_tags) {
-		int i;
-
-		for (i = 0; i != 1 << order; ++i)
-			tag_clear_highpage(page + i);
-	} else {
-		kasan_unpoison_pages(page, order, init);
-	}
-}
-
 #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
 
 void kasan_enable_tagging_sync(void)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 868480d463c7..abed862d889d 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2398,6 +2398,9 @@ static bool check_new_pages(struct page *page, unsigned int order)
 inline void post_alloc_hook(struct page *page, unsigned int order,
 				gfp_t gfp_flags)
 {
+	bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
+	bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
+
 	set_page_private(page, 0);
 	set_page_refcounted(page);
 
@@ -2413,15 +2416,22 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 
 	/*
 	 * As memory initialization might be integrated into KASAN,
-	 * kasan_alloc_pages and kernel_init_free_pages must be
+	 * KASAN unpoisoning and memory initializion code must be
 	 * kept together to avoid discrepancies in behavior.
 	 */
 	if (kasan_has_integrated_init()) {
-		kasan_alloc_pages(page, order, gfp_flags);
-	} else {
-		bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
-		bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
+		if (gfp_flags & __GFP_SKIP_KASAN_POISON)
+			SetPageSkipKASanPoison(page);
+
+		if (init_tags) {
+			int i;
 
+			for (i = 0; i != 1 << order; ++i)
+				tag_clear_highpage(page + i);
+		} else {
+			kasan_unpoison_pages(page, order, init);
+		}
+	} else {
 		kasan_unpoison_pages(page, order, init);
 
 		if (init_tags) {
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:19 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:19 +0100
Subject: [PATCH v6 11/39] kasan,
 page_alloc: combine tag_clear_highpage calls in post_alloc_hook
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <587e3fc36358b88049320a89cc8dc6deaecb0cda.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Move tag_clear_highpage() loops out of the kasan_has_integrated_init()
clause as a code simplification.

This patch does no functional changes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v2->v3:
- Update patch description.
---
 mm/page_alloc.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index abed862d889d..b3959327e06c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2419,30 +2419,30 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 	 * KASAN unpoisoning and memory initializion code must be
 	 * kept together to avoid discrepancies in behavior.
 	 */
+
+	/*
+	 * If memory tags should be zeroed (which happens only when memory
+	 * should be initialized as well).
+	 */
+	if (init_tags) {
+		int i;
+
+		/* Initialize both memory and tags. */
+		for (i = 0; i != 1 << order; ++i)
+			tag_clear_highpage(page + i);
+
+		/* Note that memory is already initialized by the loop above. */
+		init = false;
+	}
 	if (kasan_has_integrated_init()) {
 		if (gfp_flags & __GFP_SKIP_KASAN_POISON)
 			SetPageSkipKASanPoison(page);
 
-		if (init_tags) {
-			int i;
-
-			for (i = 0; i != 1 << order; ++i)
-				tag_clear_highpage(page + i);
-		} else {
+		if (!init_tags)
 			kasan_unpoison_pages(page, order, init);
-		}
 	} else {
 		kasan_unpoison_pages(page, order, init);
 
-		if (init_tags) {
-			int i;
-
-			for (i = 0; i < 1 << order; i++)
-				tag_clear_highpage(page + i);
-
-			init = false;
-		}
-
 		if (init)
 			kernel_init_free_pages(page, 1 << order);
 	}
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:20 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:20 +0100
Subject: [PATCH v6 12/39] kasan,
 page_alloc: move SetPageSkipKASanPoison in post_alloc_hook
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <7214c1698b754ccfaa44a792113c95cc1f807c48.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Pull the SetPageSkipKASanPoison() call in post_alloc_hook() out of the
big if clause for better code readability. This also allows for more
simplifications in the following patches.

Also turn the kasan_has_integrated_init() check into the proper
kasan_hw_tags_enabled() one. These checks evaluate to the same value,
but logically skipping kasan poisoning has nothing to do with
integrated init.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v3->v4:
- Use proper kasan_hw_tags_enabled() check instead of
  IS_ENABLED(CONFIG_KASAN_HW_TAGS).
---
 mm/page_alloc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index b3959327e06c..c51d637cdab3 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2435,9 +2435,6 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		init = false;
 	}
 	if (kasan_has_integrated_init()) {
-		if (gfp_flags & __GFP_SKIP_KASAN_POISON)
-			SetPageSkipKASanPoison(page);
-
 		if (!init_tags)
 			kasan_unpoison_pages(page, order, init);
 	} else {
@@ -2446,6 +2443,9 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		if (init)
 			kernel_init_free_pages(page, 1 << order);
 	}
+	/* Propagate __GFP_SKIP_KASAN_POISON to page flags. */
+	if (kasan_hw_tags_enabled() && (gfp_flags & __GFP_SKIP_KASAN_POISON))
+		SetPageSkipKASanPoison(page);
 
 	set_page_owner(page, order, gfp_flags);
 	page_table_check_alloc(page, order);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:21 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:21 +0100
Subject: [PATCH v6 13/39] kasan,
 page_alloc: move kernel_init_free_pages in post_alloc_hook
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <a7a76456501eb37ddf9fca6529cee9555e59cdb1.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Pull the kernel_init_free_pages() call in post_alloc_hook() out of the
big if clause for better code readability. This also allows for more
simplifications in the following patch.

This patch does no functional changes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 mm/page_alloc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c51d637cdab3..2784bd478942 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2435,14 +2435,18 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		init = false;
 	}
 	if (kasan_has_integrated_init()) {
-		if (!init_tags)
+		if (!init_tags) {
 			kasan_unpoison_pages(page, order, init);
+
+			/* Note that memory is already initialized by KASAN. */
+			init = false;
+		}
 	} else {
 		kasan_unpoison_pages(page, order, init);
-
-		if (init)
-			kernel_init_free_pages(page, 1 << order);
 	}
+	/* If memory is still not initialized, do it now. */
+	if (init)
+		kernel_init_free_pages(page, 1 << order);
 	/* Propagate __GFP_SKIP_KASAN_POISON to page flags. */
 	if (kasan_hw_tags_enabled() && (gfp_flags & __GFP_SKIP_KASAN_POISON))
 		SetPageSkipKASanPoison(page);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:22 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:22 +0100
Subject: [PATCH v6 14/39] kasan,
 page_alloc: rework kasan_unpoison_pages call site
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <0ecebd0d7ccd79150e3620ea4185a32d3dfe912f.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Rework the checks around kasan_unpoison_pages() call in
post_alloc_hook().

The logical condition for calling this function is:

- If a software KASAN mode is enabled, we need to mark shadow memory.
- Otherwise, HW_TAGS KASAN is enabled, and it only makes sense to
  set tags if they haven't already been cleared by tag_clear_highpage(),
  which is indicated by init_tags.

This patch concludes the changes for post_alloc_hook().

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v3->v4:
- Make the confition checks more explicit.
- Update patch description.
---
 mm/page_alloc.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 2784bd478942..3af38e323391 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2434,15 +2434,20 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		/* Note that memory is already initialized by the loop above. */
 		init = false;
 	}
-	if (kasan_has_integrated_init()) {
-		if (!init_tags) {
-			kasan_unpoison_pages(page, order, init);
+	/*
+	 * If either a software KASAN mode is enabled, or,
+	 * in the case of hardware tag-based KASAN,
+	 * if memory tags have not been cleared via tag_clear_highpage().
+	 */
+	if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
+	    IS_ENABLED(CONFIG_KASAN_SW_TAGS) ||
+	    kasan_hw_tags_enabled() && !init_tags) {
+		/* Mark shadow memory or set memory tags. */
+		kasan_unpoison_pages(page, order, init);
 
-			/* Note that memory is already initialized by KASAN. */
+		/* Note that memory is already initialized by KASAN. */
+		if (kasan_has_integrated_init())
 			init = false;
-		}
-	} else {
-		kasan_unpoison_pages(page, order, init);
 	}
 	/* If memory is still not initialized, do it now. */
 	if (init)
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:23 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:23 +0100
Subject: [PATCH v6 15/39] kasan: clean up metadata byte definitions
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <ac11d6e9e007c95e472e8fdd22efb6074ef3c6d8.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Most of the metadata byte values are only used for Generic KASAN.

Remove KASAN_KMALLOC_FREETRACK definition for !CONFIG_KASAN_GENERIC
case, and put it along with other metadata values for the Generic
mode under a corresponding ifdef.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 mm/kasan/kasan.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index c17fa8d26ffe..952cd6f9ca46 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -71,15 +71,16 @@ static inline bool kasan_sync_fault_possible(void)
 #define KASAN_PAGE_REDZONE      0xFE  /* redzone for kmalloc_large allocations */
 #define KASAN_KMALLOC_REDZONE   0xFC  /* redzone inside slub object */
 #define KASAN_KMALLOC_FREE      0xFB  /* object was freed (kmem_cache_free/kfree) */
-#define KASAN_KMALLOC_FREETRACK 0xFA  /* object was freed and has free track set */
 #else
 #define KASAN_FREE_PAGE         KASAN_TAG_INVALID
 #define KASAN_PAGE_REDZONE      KASAN_TAG_INVALID
 #define KASAN_KMALLOC_REDZONE   KASAN_TAG_INVALID
 #define KASAN_KMALLOC_FREE      KASAN_TAG_INVALID
-#define KASAN_KMALLOC_FREETRACK KASAN_TAG_INVALID
 #endif
 
+#ifdef CONFIG_KASAN_GENERIC
+
+#define KASAN_KMALLOC_FREETRACK 0xFA  /* object was freed and has free track set */
 #define KASAN_GLOBAL_REDZONE    0xF9  /* redzone for global variable */
 #define KASAN_VMALLOC_INVALID   0xF8  /* unallocated space in vmapped page */
 
@@ -110,6 +111,8 @@ static inline bool kasan_sync_fault_possible(void)
 #define KASAN_ABI_VERSION 1
 #endif
 
+#endif /* CONFIG_KASAN_GENERIC */
+
 /* Metadata layout customization. */
 #define META_BYTES_PER_BLOCK 1
 #define META_BLOCKS_PER_ROW 16
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:02:24 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:02:24 +0100
Subject: [PATCH v6 16/39] kasan: define KASAN_VMALLOC_INVALID for SW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <1daaaafeb148a7ae8285265edc97d7ca07b6a07d.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

In preparation for adding vmalloc support to SW_TAGS KASAN,
provide a KASAN_VMALLOC_INVALID definition for it.

HW_TAGS KASAN won't be using this value, as it falls back onto
page_alloc for poisoning freed vmalloc() memory.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 mm/kasan/kasan.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 952cd6f9ca46..020f3e57a03f 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -71,18 +71,19 @@ static inline bool kasan_sync_fault_possible(void)
 #define KASAN_PAGE_REDZONE      0xFE  /* redzone for kmalloc_large allocations */
 #define KASAN_KMALLOC_REDZONE   0xFC  /* redzone inside slub object */
 #define KASAN_KMALLOC_FREE      0xFB  /* object was freed (kmem_cache_free/kfree) */
+#define KASAN_VMALLOC_INVALID   0xF8  /* unallocated space in vmapped page */
 #else
 #define KASAN_FREE_PAGE         KASAN_TAG_INVALID
 #define KASAN_PAGE_REDZONE      KASAN_TAG_INVALID
 #define KASAN_KMALLOC_REDZONE   KASAN_TAG_INVALID
 #define KASAN_KMALLOC_FREE      KASAN_TAG_INVALID
+#define KASAN_VMALLOC_INVALID   KASAN_TAG_INVALID /* only for SW_TAGS */
 #endif
 
 #ifdef CONFIG_KASAN_GENERIC
 
 #define KASAN_KMALLOC_FREETRACK 0xFA  /* object was freed and has free track set */
 #define KASAN_GLOBAL_REDZONE    0xF9  /* redzone for global variable */
-#define KASAN_VMALLOC_INVALID   0xF8  /* unallocated space in vmapped page */
 
 /*
  * Stack redzone shadow values
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:51 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:51 +0100
Subject: [PATCH v6 17/39] kasan, x86, arm64,
 s390: rename functions for modules shadow
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <36db32bde765d5d0b856f77d2d806e838513fe84.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Rename kasan_free_shadow to kasan_free_module_shadow and
kasan_module_alloc to kasan_alloc_module_shadow.

These functions are used to allocate/free shadow memory for kernel
modules when KASAN_VMALLOC is not enabled. The new names better
reflect their purpose.

Also reword the comment next to their declaration to improve clarity.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
---
 arch/arm64/kernel/module.c |  2 +-
 arch/s390/kernel/module.c  |  2 +-
 arch/x86/kernel/module.c   |  2 +-
 include/linux/kasan.h      | 14 +++++++-------
 mm/kasan/shadow.c          |  4 ++--
 mm/vmalloc.c               |  2 +-
 6 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index 309a27553c87..d3a1fa818348 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -58,7 +58,7 @@ void *module_alloc(unsigned long size)
 				PAGE_KERNEL, 0, NUMA_NO_NODE,
 				__builtin_return_address(0));
 
-	if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
+	if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
 		vfree(p);
 		return NULL;
 	}
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index d52d85367bf7..b16bebd9a8b9 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -45,7 +45,7 @@ void *module_alloc(unsigned long size)
 	p = __vmalloc_node_range(size, MODULE_ALIGN, MODULES_VADDR, MODULES_END,
 				 gfp_mask, PAGE_KERNEL_EXEC, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
 				 __builtin_return_address(0));
-	if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
+	if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
 		vfree(p);
 		return NULL;
 	}
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 95fa745e310a..c9eb8aa3b7b8 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -78,7 +78,7 @@ void *module_alloc(unsigned long size)
 				    MODULES_END, gfp_mask,
 				    PAGE_KERNEL, VM_DEFER_KMEMLEAK, NUMA_NO_NODE,
 				    __builtin_return_address(0));
-	if (p && (kasan_module_alloc(p, size, gfp_mask) < 0)) {
+	if (p && (kasan_alloc_module_shadow(p, size, gfp_mask) < 0)) {
 		vfree(p);
 		return NULL;
 	}
diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index b88ca6b97ba3..55f1d4edf6b5 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -454,17 +454,17 @@ static inline void kasan_populate_early_vm_area_shadow(void *start,
 		!defined(CONFIG_KASAN_VMALLOC)
 
 /*
- * These functions provide a special case to support backing module
- * allocations with real shadow memory. With KASAN vmalloc, the special
- * case is unnecessary, as the work is handled in the generic case.
+ * These functions allocate and free shadow memory for kernel modules.
+ * They are only required when KASAN_VMALLOC is not supported, as otherwise
+ * shadow memory is allocated by the generic vmalloc handlers.
  */
-int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask);
-void kasan_free_shadow(const struct vm_struct *vm);
+int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask);
+void kasan_free_module_shadow(const struct vm_struct *vm);
 
 #else /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
 
-static inline int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
-static inline void kasan_free_shadow(const struct vm_struct *vm) {}
+static inline int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask) { return 0; }
+static inline void kasan_free_module_shadow(const struct vm_struct *vm) {}
 
 #endif /* (CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS) && !CONFIG_KASAN_VMALLOC */
 
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 94136f84b449..e5c4393eb861 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -498,7 +498,7 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 
 #else /* CONFIG_KASAN_VMALLOC */
 
-int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask)
+int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask)
 {
 	void *ret;
 	size_t scaled_size;
@@ -534,7 +534,7 @@ int kasan_module_alloc(void *addr, size_t size, gfp_t gfp_mask)
 	return -ENOMEM;
 }
 
-void kasan_free_shadow(const struct vm_struct *vm)
+void kasan_free_module_shadow(const struct vm_struct *vm)
 {
 	if (vm->flags & VM_KASAN)
 		vfree(kasan_mem_to_shadow(vm->addr));
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 4165304d3547..b6712a25c996 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2526,7 +2526,7 @@ struct vm_struct *remove_vm_area(const void *addr)
 		va->vm = NULL;
 		spin_unlock(&vmap_area_lock);
 
-		kasan_free_shadow(vm);
+		kasan_free_module_shadow(vm);
 		free_unmap_vmap_area(va);
 
 		return vm;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:53 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:53 +0100
Subject: [PATCH v6 19/39] kasan: reorder vmalloc hooks
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <aeef49eb249c206c4c9acce2437728068da74c28.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Group functions that [de]populate shadow memory for vmalloc.
Group functions that [un]poison memory for vmalloc.

This patch does no functional changes but prepares KASAN code for
adding vmalloc support to HW_TAGS KASAN.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 include/linux/kasan.h | 20 +++++++++-----------
 mm/kasan/shadow.c     | 43 ++++++++++++++++++++++---------------------
 2 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 55f1d4edf6b5..46a63374c86f 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -418,34 +418,32 @@ static inline void kasan_init_hw_tags(void) { }
 
 #ifdef CONFIG_KASAN_VMALLOC
 
+void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
 int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
-void kasan_poison_vmalloc(const void *start, unsigned long size);
-void kasan_unpoison_vmalloc(const void *start, unsigned long size);
 void kasan_release_vmalloc(unsigned long start, unsigned long end,
 			   unsigned long free_region_start,
 			   unsigned long free_region_end);
 
-void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
+void kasan_unpoison_vmalloc(const void *start, unsigned long size);
+void kasan_poison_vmalloc(const void *start, unsigned long size);
 
 #else /* CONFIG_KASAN_VMALLOC */
 
+static inline void kasan_populate_early_vm_area_shadow(void *start,
+						       unsigned long size) { }
 static inline int kasan_populate_vmalloc(unsigned long start,
 					unsigned long size)
 {
 	return 0;
 }
-
-static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
-{ }
-static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size)
-{ }
 static inline void kasan_release_vmalloc(unsigned long start,
 					 unsigned long end,
 					 unsigned long free_region_start,
-					 unsigned long free_region_end) {}
+					 unsigned long free_region_end) { }
 
-static inline void kasan_populate_early_vm_area_shadow(void *start,
-						       unsigned long size)
+static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size)
+{ }
+static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
 { }
 
 #endif /* CONFIG_KASAN_VMALLOC */
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index e5c4393eb861..bf7ab62fbfb9 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -345,27 +345,6 @@ int kasan_populate_vmalloc(unsigned long addr, unsigned long size)
 	return 0;
 }
 
-/*
- * Poison the shadow for a vmalloc region. Called as part of the
- * freeing process at the time the region is freed.
- */
-void kasan_poison_vmalloc(const void *start, unsigned long size)
-{
-	if (!is_vmalloc_or_module_addr(start))
-		return;
-
-	size = round_up(size, KASAN_GRANULE_SIZE);
-	kasan_poison(start, size, KASAN_VMALLOC_INVALID, false);
-}
-
-void kasan_unpoison_vmalloc(const void *start, unsigned long size)
-{
-	if (!is_vmalloc_or_module_addr(start))
-		return;
-
-	kasan_unpoison(start, size, false);
-}
-
 static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
 					void *unused)
 {
@@ -496,6 +475,28 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 	}
 }
 
+
+void kasan_unpoison_vmalloc(const void *start, unsigned long size)
+{
+	if (!is_vmalloc_or_module_addr(start))
+		return;
+
+	kasan_unpoison(start, size, false);
+}
+
+/*
+ * Poison the shadow for a vmalloc region. Called as part of the
+ * freeing process at the time the region is freed.
+ */
+void kasan_poison_vmalloc(const void *start, unsigned long size)
+{
+	if (!is_vmalloc_or_module_addr(start))
+		return;
+
+	size = round_up(size, KASAN_GRANULE_SIZE);
+	kasan_poison(start, size, KASAN_VMALLOC_INVALID, false);
+}
+
 #else /* CONFIG_KASAN_VMALLOC */
 
 int kasan_alloc_module_shadow(void *addr, size_t size, gfp_t gfp_mask)
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:52 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:52 +0100
Subject: [PATCH v6 18/39] kasan, vmalloc: drop outdated VM_KASAN comment
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <780395afea83a147b3b5acc36cf2e38f7f8479f9.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

The comment about VM_KASAN in include/linux/vmalloc.c is outdated.
VM_KASAN is currently only used to mark vm_areas allocated for
kernel modules when CONFIG_KASAN_VMALLOC is disabled.

Drop the comment.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 include/linux/vmalloc.h | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 880227b9f044..87f8cfec50a0 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -35,17 +35,6 @@ struct notifier_block;		/* in notifier.h */
 #define VM_DEFER_KMEMLEAK	0
 #endif
 
-/*
- * VM_KASAN is used slightly differently depending on CONFIG_KASAN_VMALLOC.
- *
- * If IS_ENABLED(CONFIG_KASAN_VMALLOC), VM_KASAN is set on a vm_struct after
- * shadow memory has been mapped. It's used to handle allocation errors so that
- * we don't try to poison shadow on free if it was never allocated.
- *
- * Otherwise, VM_KASAN is set for kasan_module_alloc() allocations and used to
- * determine which allocations need the module shadow freed.
- */
-
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:55 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:55 +0100
Subject: [PATCH v6 21/39] kasan, vmalloc: reset tags in vmalloc functions
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <046003c5f683cacb0ba18e1079e9688bb3dca943.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

In preparation for adding vmalloc support to SW/HW_TAGS KASAN,
reset pointer tags in functions that use pointer values in
range checks.

vread() is a special case here. Despite the untagging of the addr
pointer in its prologue, the accesses performed by vread() are checked.

Instead of accessing the virtual mappings though addr directly, vread()
recovers the physical address via page_address(vmalloc_to_page()) and
acceses that. And as page_address() recovers the pointer tag, the
accesses get checked.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v1->v2:
- Clarified the description of untagging in vread().
---
 mm/vmalloc.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index b6712a25c996..38bf3b418b81 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -74,7 +74,7 @@ static const bool vmap_allow_huge = false;
 
 bool is_vmalloc_addr(const void *x)
 {
-	unsigned long addr = (unsigned long)x;
+	unsigned long addr = (unsigned long)kasan_reset_tag(x);
 
 	return addr >= VMALLOC_START && addr < VMALLOC_END;
 }
@@ -632,7 +632,7 @@ int is_vmalloc_or_module_addr(const void *x)
 	 * just put it in the vmalloc space.
 	 */
 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
-	unsigned long addr = (unsigned long)x;
+	unsigned long addr = (unsigned long)kasan_reset_tag(x);
 	if (addr >= MODULES_VADDR && addr < MODULES_END)
 		return 1;
 #endif
@@ -806,6 +806,8 @@ static struct vmap_area *find_vmap_area_exceed_addr(unsigned long addr)
 	struct vmap_area *va = NULL;
 	struct rb_node *n = vmap_area_root.rb_node;
 
+	addr = (unsigned long)kasan_reset_tag((void *)addr);
+
 	while (n) {
 		struct vmap_area *tmp;
 
@@ -827,6 +829,8 @@ static struct vmap_area *__find_vmap_area(unsigned long addr)
 {
 	struct rb_node *n = vmap_area_root.rb_node;
 
+	addr = (unsigned long)kasan_reset_tag((void *)addr);
+
 	while (n) {
 		struct vmap_area *va;
 
@@ -2145,7 +2149,7 @@ EXPORT_SYMBOL_GPL(vm_unmap_aliases);
 void vm_unmap_ram(const void *mem, unsigned int count)
 {
 	unsigned long size = (unsigned long)count << PAGE_SHIFT;
-	unsigned long addr = (unsigned long)mem;
+	unsigned long addr = (unsigned long)kasan_reset_tag(mem);
 	struct vmap_area *va;
 
 	might_sleep();
@@ -3404,6 +3408,8 @@ long vread(char *buf, char *addr, unsigned long count)
 	unsigned long buflen = count;
 	unsigned long n;
 
+	addr = kasan_reset_tag(addr);
+
 	/* Don't allow overflow */
 	if ((unsigned long) addr + count < count)
 		count = -(unsigned long) addr;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:54 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:54 +0100
Subject: [PATCH v6 20/39] kasan: add wrappers for vmalloc hooks
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <3b8728eac438c55389fb0f9a8a2145d71dd77487.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Add wrappers around functions that [un]poison memory for vmalloc
allocations. These functions will be used by HW_TAGS KASAN and
therefore need to be disabled when kasan=off command line argument
is provided.

This patch does no functional changes for software KASAN modes.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>
---
 include/linux/kasan.h | 17 +++++++++++++++--
 mm/kasan/shadow.c     |  5 ++---
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 46a63374c86f..da320069e7cf 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -424,8 +424,21 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 			   unsigned long free_region_start,
 			   unsigned long free_region_end);
 
-void kasan_unpoison_vmalloc(const void *start, unsigned long size);
-void kasan_poison_vmalloc(const void *start, unsigned long size);
+void __kasan_unpoison_vmalloc(const void *start, unsigned long size);
+static __always_inline void kasan_unpoison_vmalloc(const void *start,
+						   unsigned long size)
+{
+	if (kasan_enabled())
+		__kasan_unpoison_vmalloc(start, size);
+}
+
+void __kasan_poison_vmalloc(const void *start, unsigned long size);
+static __always_inline void kasan_poison_vmalloc(const void *start,
+						 unsigned long size)
+{
+	if (kasan_enabled())
+		__kasan_poison_vmalloc(start, size);
+}
 
 #else /* CONFIG_KASAN_VMALLOC */
 
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index bf7ab62fbfb9..39d0b32ebf70 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -475,8 +475,7 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 	}
 }
 
-
-void kasan_unpoison_vmalloc(const void *start, unsigned long size)
+void __kasan_unpoison_vmalloc(const void *start, unsigned long size)
 {
 	if (!is_vmalloc_or_module_addr(start))
 		return;
@@ -488,7 +487,7 @@ void kasan_unpoison_vmalloc(const void *start, unsigned long size)
  * Poison the shadow for a vmalloc region. Called as part of the
  * freeing process at the time the region is freed.
  */
-void kasan_poison_vmalloc(const void *start, unsigned long size)
+void __kasan_poison_vmalloc(const void *start, unsigned long size)
 {
 	if (!is_vmalloc_or_module_addr(start))
 		return;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:56 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:56 +0100
Subject: [PATCH v6 22/39] kasan, fork: reset pointer tags of vmapped stacks
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <c6c96f012371ecd80e1936509ebcd3b07a5956f7.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Once tag-based KASAN modes start tagging vmalloc() allocations,
kernel stacks start getting tagged if CONFIG_VMAP_STACK is enabled.

Reset the tag of kernel stack pointers after allocation in
alloc_thread_stack_node().

For SW_TAGS KASAN, when CONFIG_KASAN_STACK is enabled, the
instrumentation can't handle the SP register being tagged.

For HW_TAGS KASAN, there's no instrumentation-related issues. However,
the impact of having a tagged SP register needs to be properly evaluated,
so keep it non-tagged for now.

Note, that the memory for the stack allocation still gets tagged to
catch vmalloc-into-stack out-of-bounds accesses.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v2->v3:
- Update patch description.
---
 kernel/fork.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/fork.c b/kernel/fork.c
index d75a528f7b21..57d624f05182 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -254,6 +254,7 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
 	 * so cache the vm_struct.
 	 */
 	if (stack) {
+		stack = kasan_reset_tag(stack);
 		tsk->stack_vm_area = find_vm_area(stack);
 		tsk->stack = stack;
 	}
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:57 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:57 +0100
Subject: [PATCH v6 23/39] kasan, arm64: reset pointer tags of vmapped stacks
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <698c5ab21743c796d46c15d075b9481825973e34.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Once tag-based KASAN modes start tagging vmalloc() allocations,
kernel stacks start getting tagged if CONFIG_VMAP_STACK is enabled.

Reset the tag of kernel stack pointers after allocation in
arch_alloc_vmap_stack().

For SW_TAGS KASAN, when CONFIG_KASAN_STACK is enabled, the
instrumentation can't handle the SP register being tagged.

For HW_TAGS KASAN, there's no instrumentation-related issues. However,
the impact of having a tagged SP register needs to be properly evaluated,
so keep it non-tagged for now.

Note, that the memory for the stack allocation still gets tagged to
catch vmalloc-into-stack out-of-bounds accesses.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>

---

Changes v2->v3:
- Add this patch.
---
 arch/arm64/include/asm/vmap_stack.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/vmap_stack.h b/arch/arm64/include/asm/vmap_stack.h
index 894e031b28d2..20873099c035 100644
--- a/arch/arm64/include/asm/vmap_stack.h
+++ b/arch/arm64/include/asm/vmap_stack.h
@@ -17,10 +17,13 @@
  */
 static inline unsigned long *arch_alloc_vmap_stack(size_t stack_size, int node)
 {
+	void *p;
+
 	BUILD_BUG_ON(!IS_ENABLED(CONFIG_VMAP_STACK));
 
-	return __vmalloc_node(stack_size, THREAD_ALIGN, THREADINFO_GFP, node,
+	p = __vmalloc_node(stack_size, THREAD_ALIGN, THREADINFO_GFP, node,
 			__builtin_return_address(0));
+	return kasan_reset_tag(p);
 }
 
 #endif /* __ASM_VMAP_STACK_H */
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:58 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:58 +0100
Subject: [PATCH v6 24/39] kasan, vmalloc: add vmalloc tagging for SW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <4a78f3c064ce905e9070c29733aca1dd254a74f1.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Add vmalloc tagging support to SW_TAGS KASAN.

- __kasan_unpoison_vmalloc() now assigns a random pointer tag, poisons
  the virtual mapping accordingly, and embeds the tag into the returned
  pointer.

- __get_vm_area_node() (used by vmalloc() and vmap()) and
  pcpu_get_vm_areas() save the tagged pointer into vm_struct->addr
  (note: not into vmap_area->addr). This requires putting
  kasan_unpoison_vmalloc() after setup_vmalloc_vm[_locked]();
  otherwise the latter will overwrite the tagged pointer.
  The tagged pointer then is naturally propagateed to vmalloc()
  and vmap().

- vm_map_ram() returns the tagged pointer directly.

As a result of this change, vm_struct->addr is now tagged.

Enabling KASAN_VMALLOC with SW_TAGS is not yet allowed.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v2->v3:
- Drop accidentally added kasan_unpoison_vmalloc() argument for when
  KASAN is off.
- Drop __must_check for kasan_unpoison_vmalloc(), as its result is
  sometimes intentionally ignored.
- Move allowing enabling KASAN_VMALLOC with SW_TAGS into a separate
  patch.
- Update patch description.

Changes v1->v2:
- Allow enabling KASAN_VMALLOC with SW_TAGS in this patch.
---
 include/linux/kasan.h | 16 ++++++++++------
 mm/kasan/shadow.c     |  6 ++++--
 mm/vmalloc.c          | 14 ++++++++------
 3 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index da320069e7cf..92c5dfa29a35 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -424,12 +424,13 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 			   unsigned long free_region_start,
 			   unsigned long free_region_end);
 
-void __kasan_unpoison_vmalloc(const void *start, unsigned long size);
-static __always_inline void kasan_unpoison_vmalloc(const void *start,
-						   unsigned long size)
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size);
+static __always_inline void *kasan_unpoison_vmalloc(const void *start,
+						    unsigned long size)
 {
 	if (kasan_enabled())
-		__kasan_unpoison_vmalloc(start, size);
+		return __kasan_unpoison_vmalloc(start, size);
+	return (void *)start;
 }
 
 void __kasan_poison_vmalloc(const void *start, unsigned long size);
@@ -454,8 +455,11 @@ static inline void kasan_release_vmalloc(unsigned long start,
 					 unsigned long free_region_start,
 					 unsigned long free_region_end) { }
 
-static inline void kasan_unpoison_vmalloc(const void *start, unsigned long size)
-{ }
+static inline void *kasan_unpoison_vmalloc(const void *start,
+					   unsigned long size)
+{
+	return (void *)start;
+}
 static inline void kasan_poison_vmalloc(const void *start, unsigned long size)
 { }
 
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 39d0b32ebf70..5a866f6663fc 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -475,12 +475,14 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 	}
 }
 
-void __kasan_unpoison_vmalloc(const void *start, unsigned long size)
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size)
 {
 	if (!is_vmalloc_or_module_addr(start))
-		return;
+		return (void *)start;
 
+	start = set_tag(start, kasan_random_tag());
 	kasan_unpoison(start, size, false);
+	return (void *)start;
 }
 
 /*
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 38bf3b418b81..15e1a4fdfe0b 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2210,7 +2210,7 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node)
 		mem = (void *)addr;
 	}
 
-	kasan_unpoison_vmalloc(mem, size);
+	mem = kasan_unpoison_vmalloc(mem, size);
 
 	if (vmap_pages_range(addr, addr + size, PAGE_KERNEL,
 				pages, PAGE_SHIFT) < 0) {
@@ -2443,10 +2443,10 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 		return NULL;
 	}
 
-	kasan_unpoison_vmalloc((void *)va->va_start, requested_size);
-
 	setup_vmalloc_vm(area, va, flags, caller);
 
+	area->addr = kasan_unpoison_vmalloc(area->addr, requested_size);
+
 	return area;
 }
 
@@ -3795,9 +3795,6 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 	for (area = 0; area < nr_vms; area++) {
 		if (kasan_populate_vmalloc(vas[area]->va_start, sizes[area]))
 			goto err_free_shadow;
-
-		kasan_unpoison_vmalloc((void *)vas[area]->va_start,
-				       sizes[area]);
 	}
 
 	/* insert all vm's */
@@ -3810,6 +3807,11 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 	}
 	spin_unlock(&vmap_area_lock);
 
+	/* mark allocated areas as accessible */
+	for (area = 0; area < nr_vms; area++)
+		vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
+							 vms[area]->size);
+
 	kfree(vas);
 	return vms;
 
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:04:59 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:04:59 +0100
Subject: [PATCH v6 25/39] kasan, vmalloc,
 arm64: mark vmalloc mappings as pgprot_tagged
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <983fc33542db2f6b1e77b34ca23448d4640bbb9e.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

HW_TAGS KASAN relies on ARM Memory Tagging Extension (MTE). With MTE,
a memory region must be mapped as MT_NORMAL_TAGGED to allow setting
memory tags via MTE-specific instructions.

Add proper protection bits to vmalloc() allocations. These allocations
are always backed by page_alloc pages, so the tags will actually be
getting set on the corresponding physical memory.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Co-developed-by: Vincenzo Frascino <vincenzo.frascino at arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino at arm.com>

---

Changes v3->v4:
- Rename arch_vmalloc_pgprot_modify() to arch_vmap_pgprot_tagged()
  to be consistent with other arch vmalloc hooks.
- Move checks from arch_vmap_pgprot_tagged() to __vmalloc_node_range()
  as the same condition is used for other things in subsequent patches.

Changes v2->v3:
- Update patch description.
---
 arch/arm64/include/asm/vmalloc.h | 6 ++++++
 include/linux/vmalloc.h          | 7 +++++++
 mm/vmalloc.c                     | 9 +++++++++
 3 files changed, 22 insertions(+)

diff --git a/arch/arm64/include/asm/vmalloc.h b/arch/arm64/include/asm/vmalloc.h
index b9185503feae..38fafffe699f 100644
--- a/arch/arm64/include/asm/vmalloc.h
+++ b/arch/arm64/include/asm/vmalloc.h
@@ -25,4 +25,10 @@ static inline bool arch_vmap_pmd_supported(pgprot_t prot)
 
 #endif
 
+#define arch_vmap_pgprot_tagged arch_vmap_pgprot_tagged
+static inline pgprot_t arch_vmap_pgprot_tagged(pgprot_t prot)
+{
+	return pgprot_tagged(prot);
+}
+
 #endif /* _ASM_ARM64_VMALLOC_H */
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 87f8cfec50a0..7b879c77bec5 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -115,6 +115,13 @@ static inline int arch_vmap_pte_supported_shift(unsigned long size)
 }
 #endif
 
+#ifndef arch_vmap_pgprot_tagged
+static inline pgprot_t arch_vmap_pgprot_tagged(pgprot_t prot)
+{
+	return prot;
+}
+#endif
+
 /*
  *	Highlevel APIs for driver use
  */
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 15e1a4fdfe0b..92e635b7490c 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3108,6 +3108,15 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		goto fail;
 	}
 
+	/*
+	 * Modify protection bits to allow tagging.
+	 * This must be done before mapping by __vmalloc_area_node().
+	 */
+	if (kasan_hw_tags_enabled() &&
+	    pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
+		prot = arch_vmap_pgprot_tagged(prot);
+
+	/* Allocate physical pages and map them into vmalloc space. */
 	addr = __vmalloc_area_node(area, gfp_mask, prot, shift, node);
 	if (!addr)
 		goto fail;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:01 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:01 +0100
Subject: [PATCH v6 27/39] kasan,
 mm: only define ___GFP_SKIP_KASAN_POISON with HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <44e5738a584c11801b2b8f1231898918efc8634a.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Only define the ___GFP_SKIP_KASAN_POISON flag when CONFIG_KASAN_HW_TAGS
is enabled.

This patch it not useful by itself, but it prepares the code for
additions of new KASAN-specific GFP patches.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v3->v4:
- This is a new patch.
---
 include/linux/gfp.h            |  8 +++++++-
 include/trace/events/mmflags.h | 12 +++++++++---
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 581a1f47b8a2..96f707931770 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -54,7 +54,11 @@ struct vm_area_struct;
 #define ___GFP_THISNODE		0x200000u
 #define ___GFP_ACCOUNT		0x400000u
 #define ___GFP_ZEROTAGS		0x800000u
+#ifdef CONFIG_KASAN_HW_TAGS
 #define ___GFP_SKIP_KASAN_POISON	0x1000000u
+#else
+#define ___GFP_SKIP_KASAN_POISON	0
+#endif
 #ifdef CONFIG_LOCKDEP
 #define ___GFP_NOLOCKDEP	0x2000000u
 #else
@@ -251,7 +255,9 @@ struct vm_area_struct;
 #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP)
 
 /* Room for N __GFP_FOO bits */
-#define __GFP_BITS_SHIFT (25 + IS_ENABLED(CONFIG_LOCKDEP))
+#define __GFP_BITS_SHIFT (24 +					\
+			  IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
+			  IS_ENABLED(CONFIG_LOCKDEP))
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
 
 /**
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 116ed4d5d0f8..cb4520374e2c 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -49,12 +49,18 @@
 	{(unsigned long)__GFP_RECLAIM,		"__GFP_RECLAIM"},	\
 	{(unsigned long)__GFP_DIRECT_RECLAIM,	"__GFP_DIRECT_RECLAIM"},\
 	{(unsigned long)__GFP_KSWAPD_RECLAIM,	"__GFP_KSWAPD_RECLAIM"},\
-	{(unsigned long)__GFP_ZEROTAGS,		"__GFP_ZEROTAGS"},	\
-	{(unsigned long)__GFP_SKIP_KASAN_POISON,"__GFP_SKIP_KASAN_POISON"}\
+	{(unsigned long)__GFP_ZEROTAGS,		"__GFP_ZEROTAGS"}	\
+
+#ifdef CONFIG_KASAN_HW_TAGS
+#define __def_gfpflag_names_kasan					      \
+	, {(unsigned long)__GFP_SKIP_KASAN_POISON, "__GFP_SKIP_KASAN_POISON"}
+#else
+#define __def_gfpflag_names_kasan
+#endif
 
 #define show_gfp_flags(flags)						\
 	(flags) ? __print_flags(flags, "|",				\
-	__def_gfpflag_names						\
+	__def_gfpflag_names __def_gfpflag_names_kasan			\
 	) : "none"
 
 #ifdef CONFIG_MMU
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:02 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:02 +0100
Subject: [PATCH v6 28/39] kasan,
 page_alloc: allow skipping unpoisoning for HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <35c97d77a704f6ff971dd3bfe4be95855744108e.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Add a new GFP flag __GFP_SKIP_KASAN_UNPOISON that allows skipping KASAN
poisoning for page_alloc allocations. The flag is only effective with
HW_TAGS KASAN.

This flag will be used by vmalloc code for page_alloc allocations
backing vmalloc() mappings in a following patch. The reason to skip
KASAN poisoning for these pages in page_alloc is because vmalloc code
will be poisoning them instead.

Also reword the comment for __GFP_SKIP_KASAN_POISON.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v4->v5:
- Cosmetic changes to __def_gfpflag_names_kasan and __GFP_BITS_SHIFT.

Changes v3->v4:
- Only define __GFP_SKIP_KASAN_POISON when CONFIG_KASAN_HW_TAGS is
  enabled.

Changes v2->v3:
- Update patch description.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
---
 include/linux/gfp.h            | 21 +++++++++++++--------
 include/trace/events/mmflags.h |  5 +++--
 mm/page_alloc.c                | 31 ++++++++++++++++++++++---------
 3 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 96f707931770..7303d1064460 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -55,12 +55,14 @@ struct vm_area_struct;
 #define ___GFP_ACCOUNT		0x400000u
 #define ___GFP_ZEROTAGS		0x800000u
 #ifdef CONFIG_KASAN_HW_TAGS
-#define ___GFP_SKIP_KASAN_POISON	0x1000000u
+#define ___GFP_SKIP_KASAN_UNPOISON	0x1000000u
+#define ___GFP_SKIP_KASAN_POISON	0x2000000u
 #else
+#define ___GFP_SKIP_KASAN_UNPOISON	0
 #define ___GFP_SKIP_KASAN_POISON	0
 #endif
 #ifdef CONFIG_LOCKDEP
-#define ___GFP_NOLOCKDEP	0x2000000u
+#define ___GFP_NOLOCKDEP	0x4000000u
 #else
 #define ___GFP_NOLOCKDEP	0
 #endif
@@ -241,22 +243,25 @@ struct vm_area_struct;
  * intended for optimization: setting memory tags at the same time as zeroing
  * memory has minimal additional performace impact.
  *
- * %__GFP_SKIP_KASAN_POISON returns a page which does not need to be poisoned
- * on deallocation. Typically used for userspace pages. Currently only has an
- * effect in HW tags mode.
+ * %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page allocation.
+ * Only effective in HW_TAGS mode.
+ *
+ * %__GFP_SKIP_KASAN_POISON makes KASAN skip poisoning on page deallocation.
+ * Typically, used for userspace pages. Only effective in HW_TAGS mode.
  */
 #define __GFP_NOWARN	((__force gfp_t)___GFP_NOWARN)
 #define __GFP_COMP	((__force gfp_t)___GFP_COMP)
 #define __GFP_ZERO	((__force gfp_t)___GFP_ZERO)
 #define __GFP_ZEROTAGS	((__force gfp_t)___GFP_ZEROTAGS)
-#define __GFP_SKIP_KASAN_POISON	((__force gfp_t)___GFP_SKIP_KASAN_POISON)
+#define __GFP_SKIP_KASAN_UNPOISON ((__force gfp_t)___GFP_SKIP_KASAN_UNPOISON)
+#define __GFP_SKIP_KASAN_POISON   ((__force gfp_t)___GFP_SKIP_KASAN_POISON)
 
 /* Disable lockdep for GFP context tracking */
 #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP)
 
 /* Room for N __GFP_FOO bits */
-#define __GFP_BITS_SHIFT (24 +					\
-			  IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
+#define __GFP_BITS_SHIFT (24 +						\
+			  2 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
 			  IS_ENABLED(CONFIG_LOCKDEP))
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
 
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index cb4520374e2c..134c45e62d91 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -52,8 +52,9 @@
 	{(unsigned long)__GFP_ZEROTAGS,		"__GFP_ZEROTAGS"}	\
 
 #ifdef CONFIG_KASAN_HW_TAGS
-#define __def_gfpflag_names_kasan					      \
-	, {(unsigned long)__GFP_SKIP_KASAN_POISON, "__GFP_SKIP_KASAN_POISON"}
+#define __def_gfpflag_names_kasan ,					       \
+	{(unsigned long)__GFP_SKIP_KASAN_POISON,   "__GFP_SKIP_KASAN_POISON"}, \
+	{(unsigned long)__GFP_SKIP_KASAN_UNPOISON, "__GFP_SKIP_KASAN_UNPOISON"}
 #else
 #define __def_gfpflag_names_kasan
 #endif
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3af38e323391..94bfbc216ae9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2395,6 +2395,26 @@ static bool check_new_pages(struct page *page, unsigned int order)
 	return false;
 }
 
+static inline bool should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
+{
+	/* Don't skip if a software KASAN mode is enabled. */
+	if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
+	    IS_ENABLED(CONFIG_KASAN_SW_TAGS))
+		return false;
+
+	/* Skip, if hardware tag-based KASAN is not enabled. */
+	if (!kasan_hw_tags_enabled())
+		return true;
+
+	/*
+	 * With hardware tag-based KASAN enabled, skip if either:
+	 *
+	 * 1. Memory tags have already been cleared via tag_clear_highpage().
+	 * 2. Skipping has been requested via __GFP_SKIP_KASAN_UNPOISON.
+	 */
+	return init_tags || (flags & __GFP_SKIP_KASAN_UNPOISON);
+}
+
 inline void post_alloc_hook(struct page *page, unsigned int order,
 				gfp_t gfp_flags)
 {
@@ -2434,15 +2454,8 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
 		/* Note that memory is already initialized by the loop above. */
 		init = false;
 	}
-	/*
-	 * If either a software KASAN mode is enabled, or,
-	 * in the case of hardware tag-based KASAN,
-	 * if memory tags have not been cleared via tag_clear_highpage().
-	 */
-	if (IS_ENABLED(CONFIG_KASAN_GENERIC) ||
-	    IS_ENABLED(CONFIG_KASAN_SW_TAGS) ||
-	    kasan_hw_tags_enabled() && !init_tags) {
-		/* Mark shadow memory or set memory tags. */
+	if (!should_skip_kasan_unpoison(gfp_flags, init_tags)) {
+		/* Unpoison shadow memory or set memory tags. */
 		kasan_unpoison_pages(page, order, init);
 
 		/* Note that memory is already initialized by KASAN. */
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:00 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:00 +0100
Subject: [PATCH v6 26/39] kasan, vmalloc: unpoison VM_ALLOC pages after mapping
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <fcb98980e6fcd3c4be6acdcb5d6110898ef28548.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Make KASAN unpoison vmalloc mappings after they have been mapped in
when it's possible: for vmalloc() (indentified via VM_ALLOC) and
vm_map_ram().

The reasons for this are:

- For vmalloc() and vm_map_ram(): pages don't get unpoisoned in case
  mapping them fails.
- For vmalloc(): HW_TAGS KASAN needs pages to be mapped to set tags via
  kasan_unpoison_vmalloc().

As a part of these changes, the return value of __vmalloc_node_range()
is changed to area->addr. This is a non-functional change, as
__vmalloc_area_node() returns area->addr anyway.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Reviewed-by: Alexander Potapenko <glider at google.com>

---

Changes v3->v4:
- Don't forget to save tagged addr to vm_struct->addr for VM_ALLOC
  so that find_vm_area(addr)->addr == addr for vmalloc().
- Reword comments.
- Update patch description.

Changes v2->v3:
- Update patch description.
---
 mm/vmalloc.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 92e635b7490c..b65adac1cd80 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2210,14 +2210,15 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node)
 		mem = (void *)addr;
 	}
 
-	mem = kasan_unpoison_vmalloc(mem, size);
-
 	if (vmap_pages_range(addr, addr + size, PAGE_KERNEL,
 				pages, PAGE_SHIFT) < 0) {
 		vm_unmap_ram(mem, count);
 		return NULL;
 	}
 
+	/* Mark the pages as accessible, now that they are mapped. */
+	mem = kasan_unpoison_vmalloc(mem, size);
+
 	return mem;
 }
 EXPORT_SYMBOL(vm_map_ram);
@@ -2445,7 +2446,14 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 
 	setup_vmalloc_vm(area, va, flags, caller);
 
-	area->addr = kasan_unpoison_vmalloc(area->addr, requested_size);
+	/*
+	 * Mark pages for non-VM_ALLOC mappings as accessible. Do it now as a
+	 * best-effort approach, as they can be mapped outside of vmalloc code.
+	 * For VM_ALLOC mappings, the pages are marked as accessible after
+	 * getting mapped in __vmalloc_node_range().
+	 */
+	if (!(flags & VM_ALLOC))
+		area->addr = kasan_unpoison_vmalloc(area->addr, requested_size);
 
 	return area;
 }
@@ -3055,7 +3063,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 			const void *caller)
 {
 	struct vm_struct *area;
-	void *addr;
+	void *ret;
 	unsigned long real_size = size;
 	unsigned long real_align = align;
 	unsigned int shift = PAGE_SHIFT;
@@ -3117,10 +3125,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		prot = arch_vmap_pgprot_tagged(prot);
 
 	/* Allocate physical pages and map them into vmalloc space. */
-	addr = __vmalloc_area_node(area, gfp_mask, prot, shift, node);
-	if (!addr)
+	ret = __vmalloc_area_node(area, gfp_mask, prot, shift, node);
+	if (!ret)
 		goto fail;
 
+	/* Mark the pages as accessible, now that they are mapped. */
+	area->addr = kasan_unpoison_vmalloc(area->addr, real_size);
+
 	/*
 	 * In this function, newly allocated vm_struct has VM_UNINITIALIZED
 	 * flag. It means that vm_struct is not fully initialized.
@@ -3132,7 +3143,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 	if (!(vm_flags & VM_DEFER_KMEMLEAK))
 		kmemleak_vmalloc(area, size, gfp_mask);
 
-	return addr;
+	return area->addr;
 
 fail:
 	if (shift > PAGE_SHIFT) {
@@ -3816,7 +3827,10 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 	}
 	spin_unlock(&vmap_area_lock);
 
-	/* mark allocated areas as accessible */
+	/*
+	 * Mark allocated areas as accessible. Do it now as a best-effort
+	 * approach, as they can be mapped outside of vmalloc code.
+	 */
 	for (area = 0; area < nr_vms; area++)
 		vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
 							 vms[area]->size);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:03 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:03 +0100
Subject: [PATCH v6 29/39] kasan,
 page_alloc: allow skipping memory init for HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <0d53efeff345de7d708e0baa0d8829167772521e.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Add a new GFP flag __GFP_SKIP_ZERO that allows to skip memory
initialization. The flag is only effective with HW_TAGS KASAN.

This flag will be used by vmalloc code for page_alloc allocations
backing vmalloc() mappings in a following patch. The reason to skip
memory initialization for these pages in page_alloc is because vmalloc
code will be initializing them instead.

With the current implementation, when __GFP_SKIP_ZERO is provided,
__GFP_ZEROTAGS is ignored. This doesn't matter, as these two flags are
never provided at the same time. However, if this is changed in the
future, this particular implementation detail can be changed as well.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v5->v6:
- Drop unnecessary explicit checks for software KASAN modes from
  should_skip_init().

Changes v4->v5:
- Cosmetic changes to __def_gfpflag_names_kasan and __GFP_BITS_SHIFT.

Changes v3->v4:
- Only define __GFP_SKIP_ZERO when CONFIG_KASAN_HW_TAGS is enabled.
- Add __GFP_SKIP_ZERO to include/trace/events/mmflags.h.
- Use proper kasan_hw_tags_enabled() check instead of
  IS_ENABLED(CONFIG_KASAN_HW_TAGS). Also add explicit checks for
  software modes.

Changes v2->v3:
- Update patch description.

Changes v1->v2:
- Add this patch.
---
 include/linux/gfp.h            | 18 +++++++++++-------
 include/trace/events/mmflags.h |  1 +
 mm/page_alloc.c                | 13 ++++++++++++-
 3 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 7303d1064460..7797c915ce54 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -55,14 +55,16 @@ struct vm_area_struct;
 #define ___GFP_ACCOUNT		0x400000u
 #define ___GFP_ZEROTAGS		0x800000u
 #ifdef CONFIG_KASAN_HW_TAGS
-#define ___GFP_SKIP_KASAN_UNPOISON	0x1000000u
-#define ___GFP_SKIP_KASAN_POISON	0x2000000u
+#define ___GFP_SKIP_ZERO		0x1000000u
+#define ___GFP_SKIP_KASAN_UNPOISON	0x2000000u
+#define ___GFP_SKIP_KASAN_POISON	0x4000000u
 #else
+#define ___GFP_SKIP_ZERO		0
 #define ___GFP_SKIP_KASAN_UNPOISON	0
 #define ___GFP_SKIP_KASAN_POISON	0
 #endif
 #ifdef CONFIG_LOCKDEP
-#define ___GFP_NOLOCKDEP	0x4000000u
+#define ___GFP_NOLOCKDEP	0x8000000u
 #else
 #define ___GFP_NOLOCKDEP	0
 #endif
@@ -239,9 +241,10 @@ struct vm_area_struct;
  * %__GFP_ZERO returns a zeroed page on success.
  *
  * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
- * is being zeroed (either via __GFP_ZERO or via init_on_alloc). This flag is
- * intended for optimization: setting memory tags at the same time as zeroing
- * memory has minimal additional performace impact.
+ * is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
+ * __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
+ * memory tags at the same time as zeroing memory has minimal additional
+ * performace impact.
  *
  * %__GFP_SKIP_KASAN_UNPOISON makes KASAN skip unpoisoning on page allocation.
  * Only effective in HW_TAGS mode.
@@ -253,6 +256,7 @@ struct vm_area_struct;
 #define __GFP_COMP	((__force gfp_t)___GFP_COMP)
 #define __GFP_ZERO	((__force gfp_t)___GFP_ZERO)
 #define __GFP_ZEROTAGS	((__force gfp_t)___GFP_ZEROTAGS)
+#define __GFP_SKIP_ZERO ((__force gfp_t)___GFP_SKIP_ZERO)
 #define __GFP_SKIP_KASAN_UNPOISON ((__force gfp_t)___GFP_SKIP_KASAN_UNPOISON)
 #define __GFP_SKIP_KASAN_POISON   ((__force gfp_t)___GFP_SKIP_KASAN_POISON)
 
@@ -261,7 +265,7 @@ struct vm_area_struct;
 
 /* Room for N __GFP_FOO bits */
 #define __GFP_BITS_SHIFT (24 +						\
-			  2 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
+			  3 * IS_ENABLED(CONFIG_KASAN_HW_TAGS) +	\
 			  IS_ENABLED(CONFIG_LOCKDEP))
 #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
 
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index 134c45e62d91..6532119a6bf1 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -53,6 +53,7 @@
 
 #ifdef CONFIG_KASAN_HW_TAGS
 #define __def_gfpflag_names_kasan ,					       \
+	{(unsigned long)__GFP_SKIP_ZERO,	   "__GFP_SKIP_ZERO"},	       \
 	{(unsigned long)__GFP_SKIP_KASAN_POISON,   "__GFP_SKIP_KASAN_POISON"}, \
 	{(unsigned long)__GFP_SKIP_KASAN_UNPOISON, "__GFP_SKIP_KASAN_UNPOISON"}
 #else
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 94bfbc216ae9..368c6c5bf42a 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2415,10 +2415,21 @@ static inline bool should_skip_kasan_unpoison(gfp_t flags, bool init_tags)
 	return init_tags || (flags & __GFP_SKIP_KASAN_UNPOISON);
 }
 
+static inline bool should_skip_init(gfp_t flags)
+{
+	/* Don't skip, if hardware tag-based KASAN is not enabled. */
+	if (!kasan_hw_tags_enabled())
+		return false;
+
+	/* For hardware tag-based KASAN, skip if requested. */
+	return (flags & __GFP_SKIP_ZERO);
+}
+
 inline void post_alloc_hook(struct page *page, unsigned int order,
 				gfp_t gfp_flags)
 {
-	bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags);
+	bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
+			!should_skip_init(gfp_flags);
 	bool init_tags = init && (gfp_flags & __GFP_ZEROTAGS);
 
 	set_page_private(page, 0);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:05 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:05 +0100
Subject: [PATCH v6 31/39] kasan, vmalloc: only tag normal vmalloc allocations
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <fbfd9939a4dc375923c9a5c6b9e7ab05c26b8c6b.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

The kernel can use to allocate executable memory. The only supported way
to do that is via __vmalloc_node_range() with the executable bit set in
the prot argument. (vmap() resets the bit via pgprot_nx()).

Once tag-based KASAN modes start tagging vmalloc allocations, executing
code from such allocations will lead to the PC register getting a tag,
which is not tolerated by the kernel.

Only tag the allocations for normal kernel pages.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v3->v4:
- Rename KASAN_VMALLOC_NOEXEC to KASAN_VMALLOC_PROT_NORMAL.
- Compare with PAGE_KERNEL instead of using pgprot_nx().
- Update patch description.

Changes v2->v3:
- Add this patch.
---
 include/linux/kasan.h |  7 ++++---
 mm/kasan/hw_tags.c    |  7 +++++++
 mm/kasan/shadow.c     |  7 +++++++
 mm/vmalloc.c          | 49 +++++++++++++++++++++++++------------------
 4 files changed, 47 insertions(+), 23 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 499f1573dba4..3593c95d1fa5 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -27,9 +27,10 @@ struct kunit_kasan_expectation {
 
 typedef unsigned int __bitwise kasan_vmalloc_flags_t;
 
-#define KASAN_VMALLOC_NONE	0x00u
-#define KASAN_VMALLOC_INIT	0x01u
-#define KASAN_VMALLOC_VM_ALLOC	0x02u
+#define KASAN_VMALLOC_NONE		0x00u
+#define KASAN_VMALLOC_INIT		0x01u
+#define KASAN_VMALLOC_VM_ALLOC		0x02u
+#define KASAN_VMALLOC_PROT_NORMAL	0x04u
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 21104fd51872..2e9378a4f07f 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -247,6 +247,13 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
 	if (!(flags & KASAN_VMALLOC_VM_ALLOC))
 		return (void *)start;
 
+	/*
+	 * Don't tag executable memory.
+	 * The kernel doesn't tolerate having the PC register tagged.
+	 */
+	if (!(flags & KASAN_VMALLOC_PROT_NORMAL))
+		return (void *)start;
+
 	tag = kasan_random_tag();
 	start = set_tag(start, tag);
 
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index b958babc8fed..7272e248db87 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -488,6 +488,13 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
 	if (!is_vmalloc_or_module_addr(start))
 		return (void *)start;
 
+	/*
+	 * Don't tag executable memory.
+	 * The kernel doesn't tolerate having the PC register tagged.
+	 */
+	if (!(flags & KASAN_VMALLOC_PROT_NORMAL))
+		return (void *)start;
+
 	start = set_tag(start, kasan_random_tag());
 	kasan_unpoison(start, size, false);
 	return (void *)start;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 6dcdf815576b..375b53fd939f 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2221,7 +2221,7 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node)
 	 * With hardware tag-based KASAN, marking is skipped for
 	 * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
 	 */
-	mem = kasan_unpoison_vmalloc(mem, size, KASAN_VMALLOC_NONE);
+	mem = kasan_unpoison_vmalloc(mem, size, KASAN_VMALLOC_PROT_NORMAL);
 
 	return mem;
 }
@@ -2460,7 +2460,7 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 	 */
 	if (!(flags & VM_ALLOC))
 		area->addr = kasan_unpoison_vmalloc(area->addr, requested_size,
-							KASAN_VMALLOC_NONE);
+						    KASAN_VMALLOC_PROT_NORMAL);
 
 	return area;
 }
@@ -3071,7 +3071,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 {
 	struct vm_struct *area;
 	void *ret;
-	kasan_vmalloc_flags_t kasan_flags;
+	kasan_vmalloc_flags_t kasan_flags = KASAN_VMALLOC_NONE;
 	unsigned long real_size = size;
 	unsigned long real_align = align;
 	unsigned int shift = PAGE_SHIFT;
@@ -3124,21 +3124,28 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		goto fail;
 	}
 
-	/* Prepare arguments for __vmalloc_area_node(). */
-	if (kasan_hw_tags_enabled() &&
-	    pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
-		/*
-		 * Modify protection bits to allow tagging.
-		 * This must be done before mapping in __vmalloc_area_node().
-		 */
-		prot = arch_vmap_pgprot_tagged(prot);
+	/*
+	 * Prepare arguments for __vmalloc_area_node() and
+	 * kasan_unpoison_vmalloc().
+	 */
+	if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
+		if (kasan_hw_tags_enabled()) {
+			/*
+			 * Modify protection bits to allow tagging.
+			 * This must be done before mapping.
+			 */
+			prot = arch_vmap_pgprot_tagged(prot);
 
-		/*
-		 * Skip page_alloc poisoning and zeroing for physical pages
-		 * backing VM_ALLOC mapping. Memory is instead poisoned and
-		 * zeroed by kasan_unpoison_vmalloc().
-		 */
-		gfp_mask |= __GFP_SKIP_KASAN_UNPOISON | __GFP_SKIP_ZERO;
+			/*
+			 * Skip page_alloc poisoning and zeroing for physical
+			 * pages backing VM_ALLOC mapping. Memory is instead
+			 * poisoned and zeroed by kasan_unpoison_vmalloc().
+			 */
+			gfp_mask |= __GFP_SKIP_KASAN_UNPOISON | __GFP_SKIP_ZERO;
+		}
+
+		/* Take note that the mapping is PAGE_KERNEL. */
+		kasan_flags |= KASAN_VMALLOC_PROT_NORMAL;
 	}
 
 	/* Allocate physical pages and map them into vmalloc space. */
@@ -3152,10 +3159,13 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 	 * (except for the should_skip_init() check) to make sure that memory
 	 * is initialized under the same conditions regardless of the enabled
 	 * KASAN mode.
+	 * Tag-based KASAN modes only assign tags to normal non-executable
+	 * allocations, see __kasan_unpoison_vmalloc().
 	 */
-	kasan_flags = KASAN_VMALLOC_VM_ALLOC;
+	kasan_flags |= KASAN_VMALLOC_VM_ALLOC;
 	if (!want_init_on_free() && want_init_on_alloc(gfp_mask))
 		kasan_flags |= KASAN_VMALLOC_INIT;
+	/* KASAN_VMALLOC_PROT_NORMAL already set if required. */
 	area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
 
 	/*
@@ -3861,8 +3871,7 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 	 */
 	for (area = 0; area < nr_vms; area++)
 		vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
-							 vms[area]->size,
-							 KASAN_VMALLOC_NONE);
+				vms[area]->size, KASAN_VMALLOC_PROT_NORMAL);
 
 	kfree(vas);
 	return vms;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:04 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:04 +0100
Subject: [PATCH v6 30/39] kasan, vmalloc: add vmalloc tagging for HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <d19b2e9e59a9abc59d05b72dea8429dcaea739c6.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Add vmalloc tagging support to HW_TAGS KASAN.

The key difference between HW_TAGS and the other two KASAN modes
when it comes to vmalloc: HW_TAGS KASAN can only assign tags to
physical memory. The other two modes have shadow memory covering
every mapped virtual memory region.

Make __kasan_unpoison_vmalloc() for HW_TAGS KASAN:

- Skip non-VM_ALLOC mappings as HW_TAGS KASAN can only tag a single
  mapping of normal physical memory; see the comment in the function.
- Generate a random tag, tag the returned pointer and the allocation,
  and initialize the allocation at the same time.
- Propagate the tag into the page stucts to allow accesses through
  page_address(vmalloc_to_page()).

The rest of vmalloc-related KASAN hooks are not needed:

- The shadow-related ones are fully skipped.
- __kasan_poison_vmalloc() is kept as a no-op with a comment.

Poisoning and zeroing of physical pages that are backing vmalloc()
allocations are skipped via __GFP_SKIP_KASAN_UNPOISON and
__GFP_SKIP_ZERO: __kasan_unpoison_vmalloc() does that instead.

Enabling CONFIG_KASAN_VMALLOC with HW_TAGS is not yet allowed.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Co-developed-by: Vincenzo Frascino <vincenzo.frascino at arm.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino at arm.com>

---

Changes v3->v4:
- Fix comment style in __kasan_unpoison_vmalloc().
- Set __GFP_SKIP_KASAN_UNPOISON and __GFP_SKIP_ZERO flags instead of
  resetting.
- Move setting KASAN GFP flags to __vmalloc_node_range() and do it
  only for normal non-executable mapping when HW_TAGS KASAN is enabled.

Changes v2->v3:
- Switch kasan_unpoison_vmalloc() to using a single flags argument.
- Update kasan_unpoison_vmalloc() arguments in kernel/scs.c.
- Move allowing enabling KASAN_VMALLOC with SW_TAGS into a separate
  patch.
- Minor comments fixes.
- Update patch description.

Changes v1->v2:
- Allow enabling CONFIG_KASAN_VMALLOC with HW_TAGS in this patch.
- Move memory init for page_alloc pages backing vmalloc() into
  kasan_unpoison_vmalloc().
---
 include/linux/kasan.h | 36 +++++++++++++++--
 kernel/scs.c          |  4 +-
 mm/kasan/hw_tags.c    | 92 +++++++++++++++++++++++++++++++++++++++++++
 mm/kasan/shadow.c     | 10 ++++-
 mm/vmalloc.c          | 51 ++++++++++++++++++------
 5 files changed, 175 insertions(+), 18 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 92c5dfa29a35..499f1573dba4 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -25,6 +25,12 @@ struct kunit_kasan_expectation {
 
 #endif
 
+typedef unsigned int __bitwise kasan_vmalloc_flags_t;
+
+#define KASAN_VMALLOC_NONE	0x00u
+#define KASAN_VMALLOC_INIT	0x01u
+#define KASAN_VMALLOC_VM_ALLOC	0x02u
+
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
 #include <linux/pgtable.h>
@@ -418,18 +424,39 @@ static inline void kasan_init_hw_tags(void) { }
 
 #ifdef CONFIG_KASAN_VMALLOC
 
+#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
+
 void kasan_populate_early_vm_area_shadow(void *start, unsigned long size);
 int kasan_populate_vmalloc(unsigned long addr, unsigned long size);
 void kasan_release_vmalloc(unsigned long start, unsigned long end,
 			   unsigned long free_region_start,
 			   unsigned long free_region_end);
 
-void *__kasan_unpoison_vmalloc(const void *start, unsigned long size);
+#else /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+
+static inline void kasan_populate_early_vm_area_shadow(void *start,
+						       unsigned long size)
+{ }
+static inline int kasan_populate_vmalloc(unsigned long start,
+					unsigned long size)
+{
+	return 0;
+}
+static inline void kasan_release_vmalloc(unsigned long start,
+					 unsigned long end,
+					 unsigned long free_region_start,
+					 unsigned long free_region_end) { }
+
+#endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
+
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+			       kasan_vmalloc_flags_t flags);
 static __always_inline void *kasan_unpoison_vmalloc(const void *start,
-						    unsigned long size)
+						unsigned long size,
+						kasan_vmalloc_flags_t flags)
 {
 	if (kasan_enabled())
-		return __kasan_unpoison_vmalloc(start, size);
+		return __kasan_unpoison_vmalloc(start, size, flags);
 	return (void *)start;
 }
 
@@ -456,7 +483,8 @@ static inline void kasan_release_vmalloc(unsigned long start,
 					 unsigned long free_region_end) { }
 
 static inline void *kasan_unpoison_vmalloc(const void *start,
-					   unsigned long size)
+					   unsigned long size,
+					   kasan_vmalloc_flags_t flags)
 {
 	return (void *)start;
 }
diff --git a/kernel/scs.c b/kernel/scs.c
index 579841be8864..b83bc9251f99 100644
--- a/kernel/scs.c
+++ b/kernel/scs.c
@@ -32,7 +32,7 @@ static void *__scs_alloc(int node)
 	for (i = 0; i < NR_CACHED_SCS; i++) {
 		s = this_cpu_xchg(scs_cache[i], NULL);
 		if (s) {
-			kasan_unpoison_vmalloc(s, SCS_SIZE);
+			kasan_unpoison_vmalloc(s, SCS_SIZE, KASAN_VMALLOC_NONE);
 			memset(s, 0, SCS_SIZE);
 			return s;
 		}
@@ -78,7 +78,7 @@ void scs_free(void *s)
 		if (this_cpu_cmpxchg(scs_cache[i], 0, s) == NULL)
 			return;
 
-	kasan_unpoison_vmalloc(s, SCS_SIZE);
+	kasan_unpoison_vmalloc(s, SCS_SIZE, KASAN_VMALLOC_NONE);
 	vfree_atomic(s);
 }
 
diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 76cf2b6229c7..21104fd51872 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -192,6 +192,98 @@ void __init kasan_init_hw_tags(void)
 		kasan_stack_collection_enabled() ? "on" : "off");
 }
 
+#ifdef CONFIG_KASAN_VMALLOC
+
+static void unpoison_vmalloc_pages(const void *addr, u8 tag)
+{
+	struct vm_struct *area;
+	int i;
+
+	/*
+	 * As hardware tag-based KASAN only tags VM_ALLOC vmalloc allocations
+	 * (see the comment in __kasan_unpoison_vmalloc), all of the pages
+	 * should belong to a single area.
+	 */
+	area = find_vm_area((void *)addr);
+	if (WARN_ON(!area))
+		return;
+
+	for (i = 0; i < area->nr_pages; i++) {
+		struct page *page = area->pages[i];
+
+		page_kasan_tag_set(page, tag);
+	}
+}
+
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+				kasan_vmalloc_flags_t flags)
+{
+	u8 tag;
+	unsigned long redzone_start, redzone_size;
+
+	if (!is_vmalloc_or_module_addr(start))
+		return (void *)start;
+
+	/*
+	 * Skip unpoisoning and assigning a pointer tag for non-VM_ALLOC
+	 * mappings as:
+	 *
+	 * 1. Unlike the software KASAN modes, hardware tag-based KASAN only
+	 *    supports tagging physical memory. Therefore, it can only tag a
+	 *    single mapping of normal physical pages.
+	 * 2. Hardware tag-based KASAN can only tag memory mapped with special
+	 *    mapping protection bits, see arch_vmalloc_pgprot_modify().
+	 *    As non-VM_ALLOC mappings can be mapped outside of vmalloc code,
+	 *    providing these bits would require tracking all non-VM_ALLOC
+	 *    mappers.
+	 *
+	 * Thus, for VM_ALLOC mappings, hardware tag-based KASAN only tags
+	 * the first virtual mapping, which is created by vmalloc().
+	 * Tagging the page_alloc memory backing that vmalloc() allocation is
+	 * skipped, see ___GFP_SKIP_KASAN_UNPOISON.
+	 *
+	 * For non-VM_ALLOC allocations, page_alloc memory is tagged as usual.
+	 */
+	if (!(flags & KASAN_VMALLOC_VM_ALLOC))
+		return (void *)start;
+
+	tag = kasan_random_tag();
+	start = set_tag(start, tag);
+
+	/* Unpoison and initialize memory up to size. */
+	kasan_unpoison(start, size, flags & KASAN_VMALLOC_INIT);
+
+	/*
+	 * Explicitly poison and initialize the in-page vmalloc() redzone.
+	 * Unlike software KASAN modes, hardware tag-based KASAN doesn't
+	 * unpoison memory when populating shadow for vmalloc() space.
+	 */
+	redzone_start = round_up((unsigned long)start + size,
+				 KASAN_GRANULE_SIZE);
+	redzone_size = round_up(redzone_start, PAGE_SIZE) - redzone_start;
+	kasan_poison((void *)redzone_start, redzone_size, KASAN_TAG_INVALID,
+		     flags & KASAN_VMALLOC_INIT);
+
+	/*
+	 * Set per-page tag flags to allow accessing physical memory for the
+	 * vmalloc() mapping through page_address(vmalloc_to_page()).
+	 */
+	unpoison_vmalloc_pages(start, tag);
+
+	return (void *)start;
+}
+
+void __kasan_poison_vmalloc(const void *start, unsigned long size)
+{
+	/*
+	 * No tagging here.
+	 * The physical pages backing the vmalloc() allocation are poisoned
+	 * through the usual page_alloc paths.
+	 */
+}
+
+#endif
+
 #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST)
 
 void kasan_enable_tagging_sync(void)
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index 5a866f6663fc..b958babc8fed 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -475,8 +475,16 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
 	}
 }
 
-void *__kasan_unpoison_vmalloc(const void *start, unsigned long size)
+void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
+			       kasan_vmalloc_flags_t flags)
 {
+	/*
+	 * Software KASAN modes unpoison both VM_ALLOC and non-VM_ALLOC
+	 * mappings, so the KASAN_VMALLOC_VM_ALLOC flag is ignored.
+	 * Software KASAN modes can't optimize zeroing memory by combining it
+	 * with setting memory tags, so the KASAN_VMALLOC_INIT flag is ignored.
+	 */
+
 	if (!is_vmalloc_or_module_addr(start))
 		return (void *)start;
 
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index b65adac1cd80..6dcdf815576b 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2216,8 +2216,12 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node)
 		return NULL;
 	}
 
-	/* Mark the pages as accessible, now that they are mapped. */
-	mem = kasan_unpoison_vmalloc(mem, size);
+	/*
+	 * Mark the pages as accessible, now that they are mapped.
+	 * With hardware tag-based KASAN, marking is skipped for
+	 * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
+	 */
+	mem = kasan_unpoison_vmalloc(mem, size, KASAN_VMALLOC_NONE);
 
 	return mem;
 }
@@ -2451,9 +2455,12 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
 	 * best-effort approach, as they can be mapped outside of vmalloc code.
 	 * For VM_ALLOC mappings, the pages are marked as accessible after
 	 * getting mapped in __vmalloc_node_range().
+	 * With hardware tag-based KASAN, marking is skipped for
+	 * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
 	 */
 	if (!(flags & VM_ALLOC))
-		area->addr = kasan_unpoison_vmalloc(area->addr, requested_size);
+		area->addr = kasan_unpoison_vmalloc(area->addr, requested_size,
+							KASAN_VMALLOC_NONE);
 
 	return area;
 }
@@ -3064,6 +3071,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 {
 	struct vm_struct *area;
 	void *ret;
+	kasan_vmalloc_flags_t kasan_flags;
 	unsigned long real_size = size;
 	unsigned long real_align = align;
 	unsigned int shift = PAGE_SHIFT;
@@ -3116,21 +3124,39 @@ void *__vmalloc_node_range(unsigned long size, unsigned long align,
 		goto fail;
 	}
 
-	/*
-	 * Modify protection bits to allow tagging.
-	 * This must be done before mapping by __vmalloc_area_node().
-	 */
+	/* Prepare arguments for __vmalloc_area_node(). */
 	if (kasan_hw_tags_enabled() &&
-	    pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
+	    pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
+		/*
+		 * Modify protection bits to allow tagging.
+		 * This must be done before mapping in __vmalloc_area_node().
+		 */
 		prot = arch_vmap_pgprot_tagged(prot);
 
+		/*
+		 * Skip page_alloc poisoning and zeroing for physical pages
+		 * backing VM_ALLOC mapping. Memory is instead poisoned and
+		 * zeroed by kasan_unpoison_vmalloc().
+		 */
+		gfp_mask |= __GFP_SKIP_KASAN_UNPOISON | __GFP_SKIP_ZERO;
+	}
+
 	/* Allocate physical pages and map them into vmalloc space. */
 	ret = __vmalloc_area_node(area, gfp_mask, prot, shift, node);
 	if (!ret)
 		goto fail;
 
-	/* Mark the pages as accessible, now that they are mapped. */
-	area->addr = kasan_unpoison_vmalloc(area->addr, real_size);
+	/*
+	 * Mark the pages as accessible, now that they are mapped.
+	 * The init condition should match the one in post_alloc_hook()
+	 * (except for the should_skip_init() check) to make sure that memory
+	 * is initialized under the same conditions regardless of the enabled
+	 * KASAN mode.
+	 */
+	kasan_flags = KASAN_VMALLOC_VM_ALLOC;
+	if (!want_init_on_free() && want_init_on_alloc(gfp_mask))
+		kasan_flags |= KASAN_VMALLOC_INIT;
+	area->addr = kasan_unpoison_vmalloc(area->addr, real_size, kasan_flags);
 
 	/*
 	 * In this function, newly allocated vm_struct has VM_UNINITIALIZED
@@ -3830,10 +3856,13 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
 	/*
 	 * Mark allocated areas as accessible. Do it now as a best-effort
 	 * approach, as they can be mapped outside of vmalloc code.
+	 * With hardware tag-based KASAN, marking is skipped for
+	 * non-VM_ALLOC mappings, see __kasan_unpoison_vmalloc().
 	 */
 	for (area = 0; area < nr_vms; area++)
 		vms[area]->addr = kasan_unpoison_vmalloc(vms[area]->addr,
-							 vms[area]->size);
+							 vms[area]->size,
+							 KASAN_VMALLOC_NONE);
 
 	kfree(vas);
 	return vms;
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:06 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:06 +0100
Subject: [PATCH v6 32/39] kasan,
 arm64: don't tag executable vmalloc allocations
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <b7b2595423340cd7d76b770e5d519acf3b72f0ab.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Besides asking vmalloc memory to be executable via the prot argument
of __vmalloc_node_range() (see the previous patch), the kernel can skip
that bit and instead mark memory as executable via set_memory_x().

Once tag-based KASAN modes start tagging vmalloc allocations, executing
code from such allocations will lead to the PC register getting a tag,
which is not tolerated by the kernel.

Generic kernel code typically allocates memory via module_alloc() if
it intends to mark memory as executable. (On arm64 module_alloc()
uses __vmalloc_node_range() without setting the executable bit).

Thus, reset pointer tags of pointers returned from module_alloc().

However, on arm64 there's an exception: the eBPF subsystem. Instead of
using module_alloc(), it uses vmalloc() (via bpf_jit_alloc_exec())
to allocate its JIT region.

Thus, reset pointer tags of pointers returned from bpf_jit_alloc_exec().

Resetting tags for these pointers results in untagged pointers being
passed to set_memory_x(). This causes conflicts in arithmetic checks
in change_memory_common(), as vm_struct->addr pointer returned by
find_vm_area() is tagged.

Reset pointer tag of find_vm_area(addr)->addr in change_memory_common().

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>

---

Changes v3->v4:
- Reset pointer tag in change_memory_common().

Changes v2->v3:
- Add this patch.
---
 arch/arm64/kernel/module.c    | 3 ++-
 arch/arm64/mm/pageattr.c      | 2 +-
 arch/arm64/net/bpf_jit_comp.c | 3 ++-
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/module.c b/arch/arm64/kernel/module.c
index d3a1fa818348..f2d4bb14bfab 100644
--- a/arch/arm64/kernel/module.c
+++ b/arch/arm64/kernel/module.c
@@ -63,7 +63,8 @@ void *module_alloc(unsigned long size)
 		return NULL;
 	}
 
-	return p;
+	/* Memory is intended to be executable, reset the pointer tag. */
+	return kasan_reset_tag(p);
 }
 
 enum aarch64_reloc_op {
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index a3bacd79507a..64e985eaa52d 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -85,7 +85,7 @@ static int change_memory_common(unsigned long addr, int numpages,
 	 */
 	area = find_vm_area((void *)addr);
 	if (!area ||
-	    end > (unsigned long)area->addr + area->size ||
+	    end > (unsigned long)kasan_reset_tag(area->addr) + area->size ||
 	    !(area->flags & VM_ALLOC))
 		return -EINVAL;
 
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e96d4d87291f..2198af06ae6a 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1150,7 +1150,8 @@ u64 bpf_jit_alloc_exec_limit(void)
 
 void *bpf_jit_alloc_exec(unsigned long size)
 {
-	return vmalloc(size);
+	/* Memory is intended to be executable, reset the pointer tag. */
+	return kasan_reset_tag(vmalloc(size));
 }
 
 void bpf_jit_free_exec(void *addr)
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:07 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:07 +0100
Subject: [PATCH v6 33/39] kasan: mark kasan_arg_stacktrace as __initdata
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <7fa090865614f8e0c6c1265508efb1d429afaa50.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

As kasan_arg_stacktrace is only used in __init functions, mark it as
__initdata instead of __ro_after_init to allow it be freed after boot.

The other enums for KASAN args are used in kasan_init_hw_tags_cpu(),
which is not marked as __init as a CPU can be hot-plugged after boot.
Clarify this in a comment.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Suggested-by: Marco Elver <elver at google.com>

---

Changes v1->v2:
- Add this patch.
---
 mm/kasan/hw_tags.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 2e9378a4f07f..6509809dd5d8 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -40,7 +40,7 @@ enum kasan_arg_stacktrace {
 
 static enum kasan_arg kasan_arg __ro_after_init;
 static enum kasan_arg_mode kasan_arg_mode __ro_after_init;
-static enum kasan_arg_stacktrace kasan_arg_stacktrace __ro_after_init;
+static enum kasan_arg_stacktrace kasan_arg_stacktrace __initdata;
 
 /* Whether KASAN is enabled at all. */
 DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled);
@@ -116,7 +116,10 @@ static inline const char *kasan_mode_info(void)
 		return "sync";
 }
 
-/* kasan_init_hw_tags_cpu() is called for each CPU. */
+/*
+ * kasan_init_hw_tags_cpu() is called for each CPU.
+ * Not marked as __init as a CPU can be hot-plugged after boot.
+ */
 void kasan_init_hw_tags_cpu(void)
 {
 	/*
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:08 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:08 +0100
Subject: [PATCH v6 34/39] kasan: clean up feature flags for HW_TAGS mode
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <76ebb340265be57a218564a497e1f52ff36a3879.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

- Untie kasan_init_hw_tags() code from the default values of
  kasan_arg_mode and kasan_arg_stacktrace.

- Move static_branch_enable(&kasan_flag_enabled) to the end of
  kasan_init_hw_tags_cpu().

- Remove excessive comments in kasan_arg_mode switch.

- Add new comments.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v4->v5:
- Add this patch.
---
 mm/kasan/hw_tags.c | 38 +++++++++++++++++++++-----------------
 mm/kasan/kasan.h   |  2 +-
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 6509809dd5d8..6a3146d1ccc5 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -42,16 +42,22 @@ static enum kasan_arg kasan_arg __ro_after_init;
 static enum kasan_arg_mode kasan_arg_mode __ro_after_init;
 static enum kasan_arg_stacktrace kasan_arg_stacktrace __initdata;
 
-/* Whether KASAN is enabled at all. */
+/*
+ * Whether KASAN is enabled at all.
+ * The value remains false until KASAN is initialized by kasan_init_hw_tags().
+ */
 DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled);
 EXPORT_SYMBOL(kasan_flag_enabled);
 
-/* Whether the selected mode is synchronous/asynchronous/asymmetric.*/
+/*
+ * Whether the selected mode is synchronous, asynchronous, or asymmetric.
+ * Defaults to KASAN_MODE_SYNC.
+ */
 enum kasan_mode kasan_mode __ro_after_init;
 EXPORT_SYMBOL_GPL(kasan_mode);
 
 /* Whether to collect alloc/free stack traces. */
-DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
+DEFINE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
 
 /* kasan=off/on */
 static int __init early_kasan_flag(char *arg)
@@ -127,7 +133,11 @@ void kasan_init_hw_tags_cpu(void)
 	 * as this function is only called for MTE-capable hardware.
 	 */
 
-	/* If KASAN is disabled via command line, don't initialize it. */
+	/*
+	 * If KASAN is disabled via command line, don't initialize it.
+	 * When this function is called, kasan_flag_enabled is not yet
+	 * set by kasan_init_hw_tags(). Thus, check kasan_arg instead.
+	 */
 	if (kasan_arg == KASAN_ARG_OFF)
 		return;
 
@@ -154,42 +164,36 @@ void __init kasan_init_hw_tags(void)
 	if (kasan_arg == KASAN_ARG_OFF)
 		return;
 
-	/* Enable KASAN. */
-	static_branch_enable(&kasan_flag_enabled);
-
 	switch (kasan_arg_mode) {
 	case KASAN_ARG_MODE_DEFAULT:
-		/*
-		 * Default to sync mode.
-		 */
-		fallthrough;
+		/* Default is specified by kasan_mode definition. */
+		break;
 	case KASAN_ARG_MODE_SYNC:
-		/* Sync mode enabled. */
 		kasan_mode = KASAN_MODE_SYNC;
 		break;
 	case KASAN_ARG_MODE_ASYNC:
-		/* Async mode enabled. */
 		kasan_mode = KASAN_MODE_ASYNC;
 		break;
 	case KASAN_ARG_MODE_ASYMM:
-		/* Asymm mode enabled. */
 		kasan_mode = KASAN_MODE_ASYMM;
 		break;
 	}
 
 	switch (kasan_arg_stacktrace) {
 	case KASAN_ARG_STACKTRACE_DEFAULT:
-		/* Default to enabling stack trace collection. */
-		static_branch_enable(&kasan_flag_stacktrace);
+		/* Default is specified by kasan_flag_stacktrace definition. */
 		break;
 	case KASAN_ARG_STACKTRACE_OFF:
-		/* Do nothing, kasan_flag_stacktrace keeps its default value. */
+		static_branch_disable(&kasan_flag_stacktrace);
 		break;
 	case KASAN_ARG_STACKTRACE_ON:
 		static_branch_enable(&kasan_flag_stacktrace);
 		break;
 	}
 
+	/* KASAN is now initialized, enable it. */
+	static_branch_enable(&kasan_flag_enabled);
+
 	pr_info("KernelAddressSanitizer initialized (hw-tags, mode=%s, stacktrace=%s)\n",
 		kasan_mode_info(),
 		kasan_stack_collection_enabled() ? "on" : "off");
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 020f3e57a03f..efda13a9ce6a 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -12,7 +12,7 @@
 #include <linux/static_key.h>
 #include "../slab.h"
 
-DECLARE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
+DECLARE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
 
 enum kasan_mode {
 	KASAN_MODE_SYNC,
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:10 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:10 +0100
Subject: [PATCH v6 36/39] kasan: allow enabling KASAN_VMALLOC and SW/HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <bfa0fdedfe25f65e5caa4e410f074ddbac7a0b59.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Allow enabling CONFIG_KASAN_VMALLOC with SW_TAGS and HW_TAGS KASAN
modes.

Also adjust CONFIG_KASAN_VMALLOC description:

- Mention HW_TAGS support.
- Remove unneeded internal details: they have no place in Kconfig
  description and are already explained in the documentation.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
---
 lib/Kconfig.kasan | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index 879757b6dd14..1f3e620188a2 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -178,17 +178,17 @@ config KASAN_TAGS_IDENTIFY
 	  memory consumption.
 
 config KASAN_VMALLOC
-	bool "Back mappings in vmalloc space with real shadow memory"
-	depends on KASAN_GENERIC && HAVE_ARCH_KASAN_VMALLOC
+	bool "Check accesses to vmalloc allocations"
+	depends on HAVE_ARCH_KASAN_VMALLOC
 	help
-	  By default, the shadow region for vmalloc space is the read-only
-	  zero page. This means that KASAN cannot detect errors involving
-	  vmalloc space.
-
-	  Enabling this option will hook in to vmap/vmalloc and back those
-	  mappings with real shadow memory allocated on demand. This allows
-	  for KASAN to detect more sorts of errors (and to support vmapped
-	  stacks), but at the cost of higher memory usage.
+	  This mode makes KASAN check accesses to vmalloc allocations for
+	  validity.
+
+	  With software KASAN modes, checking is done for all types of vmalloc
+	  allocations. Enabling this option leads to higher memory usage.
+
+	  With hardware tag-based KASAN, only VM_ALLOC mappings are checked.
+	  There is no additional memory usage.
 
 config KASAN_KUNIT_TEST
 	tristate "KUnit-compatible tests of KASAN bug detection capabilities" if !KUNIT_ALL_TESTS
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:09 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:09 +0100
Subject: [PATCH v6 35/39] kasan: add kasan.vmalloc command line flag
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <904f6d4dfa94870cc5fc2660809e093fd0d27c3b.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Allow disabling vmalloc() tagging for HW_TAGS KASAN via a kasan.vmalloc
command line switch.

This is a fail-safe switch intended for production systems that enable
HW_TAGS KASAN. In case vmalloc() tagging ends up having an issue not
detected during testing but that manifests in production, kasan.vmalloc
allows to turn vmalloc() tagging off while leaving page_alloc/slab
tagging on.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>

---

Changes v4->v5:
- Use true as kasan_flag_vmalloc static key default.

Changes v1->v2:
- Mark kasan_arg_stacktrace as __initdata instead of __ro_after_init.
- Combine KASAN_ARG_VMALLOC_DEFAULT and KASAN_ARG_VMALLOC_ON switch
  cases.
---
 mm/kasan/hw_tags.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 mm/kasan/kasan.h   |  6 ++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c
index 6a3146d1ccc5..fad1887e54c0 100644
--- a/mm/kasan/hw_tags.c
+++ b/mm/kasan/hw_tags.c
@@ -32,6 +32,12 @@ enum kasan_arg_mode {
 	KASAN_ARG_MODE_ASYMM,
 };
 
+enum kasan_arg_vmalloc {
+	KASAN_ARG_VMALLOC_DEFAULT,
+	KASAN_ARG_VMALLOC_OFF,
+	KASAN_ARG_VMALLOC_ON,
+};
+
 enum kasan_arg_stacktrace {
 	KASAN_ARG_STACKTRACE_DEFAULT,
 	KASAN_ARG_STACKTRACE_OFF,
@@ -40,6 +46,7 @@ enum kasan_arg_stacktrace {
 
 static enum kasan_arg kasan_arg __ro_after_init;
 static enum kasan_arg_mode kasan_arg_mode __ro_after_init;
+static enum kasan_arg_vmalloc kasan_arg_vmalloc __initdata;
 static enum kasan_arg_stacktrace kasan_arg_stacktrace __initdata;
 
 /*
@@ -56,6 +63,9 @@ EXPORT_SYMBOL(kasan_flag_enabled);
 enum kasan_mode kasan_mode __ro_after_init;
 EXPORT_SYMBOL_GPL(kasan_mode);
 
+/* Whether to enable vmalloc tagging. */
+DEFINE_STATIC_KEY_TRUE(kasan_flag_vmalloc);
+
 /* Whether to collect alloc/free stack traces. */
 DEFINE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
 
@@ -95,6 +105,23 @@ static int __init early_kasan_mode(char *arg)
 }
 early_param("kasan.mode", early_kasan_mode);
 
+/* kasan.vmalloc=off/on */
+static int __init early_kasan_flag_vmalloc(char *arg)
+{
+	if (!arg)
+		return -EINVAL;
+
+	if (!strcmp(arg, "off"))
+		kasan_arg_vmalloc = KASAN_ARG_VMALLOC_OFF;
+	else if (!strcmp(arg, "on"))
+		kasan_arg_vmalloc = KASAN_ARG_VMALLOC_ON;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+early_param("kasan.vmalloc", early_kasan_flag_vmalloc);
+
 /* kasan.stacktrace=off/on */
 static int __init early_kasan_flag_stacktrace(char *arg)
 {
@@ -179,6 +206,18 @@ void __init kasan_init_hw_tags(void)
 		break;
 	}
 
+	switch (kasan_arg_vmalloc) {
+	case KASAN_ARG_VMALLOC_DEFAULT:
+		/* Default is specified by kasan_flag_vmalloc definition. */
+		break;
+	case KASAN_ARG_VMALLOC_OFF:
+		static_branch_disable(&kasan_flag_vmalloc);
+		break;
+	case KASAN_ARG_VMALLOC_ON:
+		static_branch_enable(&kasan_flag_vmalloc);
+		break;
+	}
+
 	switch (kasan_arg_stacktrace) {
 	case KASAN_ARG_STACKTRACE_DEFAULT:
 		/* Default is specified by kasan_flag_stacktrace definition. */
@@ -194,8 +233,9 @@ void __init kasan_init_hw_tags(void)
 	/* KASAN is now initialized, enable it. */
 	static_branch_enable(&kasan_flag_enabled);
 
-	pr_info("KernelAddressSanitizer initialized (hw-tags, mode=%s, stacktrace=%s)\n",
+	pr_info("KernelAddressSanitizer initialized (hw-tags, mode=%s, vmalloc=%s, stacktrace=%s)\n",
 		kasan_mode_info(),
+		kasan_vmalloc_enabled() ? "on" : "off",
 		kasan_stack_collection_enabled() ? "on" : "off");
 }
 
@@ -228,6 +268,9 @@ void *__kasan_unpoison_vmalloc(const void *start, unsigned long size,
 	u8 tag;
 	unsigned long redzone_start, redzone_size;
 
+	if (!kasan_vmalloc_enabled())
+		return (void *)start;
+
 	if (!is_vmalloc_or_module_addr(start))
 		return (void *)start;
 
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index efda13a9ce6a..4d67408e8407 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -12,6 +12,7 @@
 #include <linux/static_key.h>
 #include "../slab.h"
 
+DECLARE_STATIC_KEY_TRUE(kasan_flag_vmalloc);
 DECLARE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
 
 enum kasan_mode {
@@ -22,6 +23,11 @@ enum kasan_mode {
 
 extern enum kasan_mode kasan_mode __ro_after_init;
 
+static inline bool kasan_vmalloc_enabled(void)
+{
+	return static_branch_likely(&kasan_flag_vmalloc);
+}
+
 static inline bool kasan_stack_collection_enabled(void)
 {
 	return static_branch_unlikely(&kasan_flag_stacktrace);
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:11 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:11 +0100
Subject: [PATCH v6 37/39] arm64: select KASAN_VMALLOC for SW/HW_TAGS modes
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <99d6b3ebf57fc1930ff71f9a4a71eea19881b270.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Generic KASAN already selects KASAN_VMALLOC to allow VMAP_STACK to be
selected unconditionally, see commit acc3042d62cb9 ("arm64: Kconfig:
select KASAN_VMALLOC if KANSAN_GENERIC is enabled").

The same change is needed for SW_TAGS KASAN.

HW_TAGS KASAN does not require enabling KASAN_VMALLOC for VMAP_STACK,
they already work together as is. Still, selecting KASAN_VMALLOC still
makes sense to make vmalloc() always protected. In case any bugs in
KASAN's vmalloc() support are discovered, the command line kasan.vmalloc
flag can be used to disable vmalloc() checking.

Select KASAN_VMALLOC for all KASAN modes for arm64.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>

---

Changes v2->v3:
- Update patch description.

Changes v1->v2:
- Split out this patch.
---
 arch/arm64/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..beefec5c7b90 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -205,7 +205,7 @@ config ARM64
 	select IOMMU_DMA if IOMMU_SUPPORT
 	select IRQ_DOMAIN
 	select IRQ_FORCED_THREADING
-	select KASAN_VMALLOC if KASAN_GENERIC
+	select KASAN_VMALLOC if KASAN
 	select MODULES_USE_ELF_RELA
 	select NEED_DMA_MAP_STATE
 	select NEED_SG_DMA_LENGTH
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:12 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:12 +0100
Subject: [PATCH v6 38/39] kasan: documentation updates
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <a61189128fa3f9fbcfd9884ff653d401864b8e74.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Update KASAN documentation:

- Bump Clang version requirement for HW_TAGS as ARM64_MTE depends on
  AS_HAS_LSE_ATOMICS as of commit 2decad92f4731 ("arm64: mte: Ensure
  TIF_MTE_ASYNC_FAULT is set atomically"), which requires Clang 12.
- Add description of the new kasan.vmalloc command line flag.
- Mention that SW_TAGS and HW_TAGS modes now support vmalloc tagging.
- Explicitly say that the "Shadow memory" section is only applicable
  to software KASAN modes.
- Mention that shadow-based KASAN_VMALLOC is supported on arm64.

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
---
 Documentation/dev-tools/kasan.rst | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/Documentation/dev-tools/kasan.rst b/Documentation/dev-tools/kasan.rst
index 8089c559d339..7614a1fc30fa 100644
--- a/Documentation/dev-tools/kasan.rst
+++ b/Documentation/dev-tools/kasan.rst
@@ -30,7 +30,7 @@ Software tag-based KASAN mode is only supported in Clang.
 
 The hardware KASAN mode (#3) relies on hardware to perform the checks but
 still requires a compiler version that supports memory tagging instructions.
-This mode is supported in GCC 10+ and Clang 11+.
+This mode is supported in GCC 10+ and Clang 12+.
 
 Both software KASAN modes work with SLUB and SLAB memory allocators,
 while the hardware tag-based KASAN currently only supports SLUB.
@@ -206,6 +206,9 @@ additional boot parameters that allow disabling KASAN or controlling features:
   Asymmetric mode: a bad access is detected synchronously on reads and
   asynchronously on writes.
 
+- ``kasan.vmalloc=off`` or ``=on`` disables or enables tagging of vmalloc
+  allocations (default: ``on``).
+
 - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
   traces collection (default: ``on``).
 
@@ -279,8 +282,8 @@ Software tag-based KASAN uses 0xFF as a match-all pointer tag (accesses through
 pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
 reserved to tag freed memory regions.
 
-Software tag-based KASAN currently only supports tagging of slab and page_alloc
-memory.
+Software tag-based KASAN currently only supports tagging of slab, page_alloc,
+and vmalloc memory.
 
 Hardware tag-based KASAN
 ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -303,8 +306,8 @@ Hardware tag-based KASAN uses 0xFF as a match-all pointer tag (accesses through
 pointers with the 0xFF pointer tag are not checked). The value 0xFE is currently
 reserved to tag freed memory regions.
 
-Hardware tag-based KASAN currently only supports tagging of slab and page_alloc
-memory.
+Hardware tag-based KASAN currently only supports tagging of slab, page_alloc,
+and VM_ALLOC-based vmalloc memory.
 
 If the hardware does not support MTE (pre ARMv8.5), hardware tag-based KASAN
 will not be enabled. In this case, all KASAN boot parameters are ignored.
@@ -319,6 +322,8 @@ checking gets disabled.
 Shadow memory
 -------------
 
+The contents of this section are only applicable to software KASAN modes.
+
 The kernel maps memory in several different parts of the address space.
 The range of kernel virtual addresses is large: there is not enough real
 memory to support a real shadow region for every address that could be
@@ -349,7 +354,7 @@ CONFIG_KASAN_VMALLOC
 
 With ``CONFIG_KASAN_VMALLOC``, KASAN can cover vmalloc space at the
 cost of greater memory usage. Currently, this is supported on x86,
-riscv, s390, and powerpc.
+arm64, riscv, s390, and powerpc.
 
 This works by hooking into vmalloc and vmap and dynamically
 allocating real shadow memory to back the mappings.
-- 
2.25.1



From andrey.konovalov at linux.dev  Mon Jan 24 10:05:13 2022
From: andrey.konovalov at linux.dev (andrey.konovalov at linux.dev)
Date: Mon, 24 Jan 2022 19:05:13 +0100
Subject: [PATCH v6 39/39] kasan: improve vmalloc tests
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <bbdc1c0501c5275e7f26fdb8e2a7b14a40a9f36b.1643047180.git.andreyknvl@google.com>

From: Andrey Konovalov <andreyknvl at google.com>

Update the existing vmalloc_oob() test to account for the specifics
of the tag-based modes. Also add a few new checks and comments.

Add new vmalloc-related tests:

- vmalloc_helpers_tags() to check that exported vmalloc helpers can
  handle tagged pointers.
- vmap_tags() to check that SW_TAGS mode properly tags vmap() mappings.
- vm_map_ram_tags() to check that SW_TAGS mode properly tags
  vm_map_ram() mappings.
- vmalloc_percpu() to check that SW_TAGS mode tags regions allocated
  for __alloc_percpu(). The tagging of per-cpu mappings is best-effort;
  proper tagging is tracked in [1].

[1] https://bugzilla.kernel.org/show_bug.cgi?id=215019

Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
---
 lib/test_kasan.c | 189 +++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 183 insertions(+), 6 deletions(-)

diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 847cdbefab46..ae7b2e703f1b 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -19,6 +19,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/vmalloc.h>
+#include <linux/set_memory.h>
 
 #include <asm/page.h>
 
@@ -1049,21 +1050,181 @@ static void kmalloc_double_kzfree(struct kunit *test)
 	KUNIT_EXPECT_KASAN_FAIL(test, kfree_sensitive(ptr));
 }
 
+static void vmalloc_helpers_tags(struct kunit *test)
+{
+	void *ptr;
+	int rv;
+
+	/* This test is intended for tag-based modes. */
+	KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
+
+	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_VMALLOC);
+
+	ptr = vmalloc(PAGE_SIZE);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
+	/* Check that the returned pointer is tagged. */
+	KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
+	KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
+
+	/* Make sure exported vmalloc helpers handle tagged pointers. */
+	KUNIT_ASSERT_TRUE(test, is_vmalloc_addr(ptr));
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vmalloc_to_page(ptr));
+
+	/* Make sure vmalloc'ed memory permissions can be changed. */
+	rv = set_memory_ro((unsigned long)ptr, 1);
+	KUNIT_ASSERT_GE(test, rv, 0);
+	rv = set_memory_rw((unsigned long)ptr, 1);
+	KUNIT_ASSERT_GE(test, rv, 0);
+
+	vfree(ptr);
+}
+
 static void vmalloc_oob(struct kunit *test)
 {
-	void *area;
+	char *v_ptr, *p_ptr;
+	struct page *page;
+	size_t size = PAGE_SIZE / 2 - KASAN_GRANULE_SIZE - 5;
 
 	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_VMALLOC);
 
+	v_ptr = vmalloc(size);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, v_ptr);
+
 	/*
-	 * We have to be careful not to hit the guard page.
+	 * We have to be careful not to hit the guard page in vmalloc tests.
 	 * The MMU will catch that and crash us.
 	 */
-	area = vmalloc(3000);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, area);
 
-	KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)area)[3100]);
-	vfree(area);
+	/* Make sure in-bounds accesses are valid. */
+	v_ptr[0] = 0;
+	v_ptr[size - 1] = 0;
+
+	/*
+	 * An unaligned access past the requested vmalloc size.
+	 * Only generic KASAN can precisely detect these.
+	 */
+	if (IS_ENABLED(CONFIG_KASAN_GENERIC))
+		KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)v_ptr)[size]);
+
+	/* An aligned access into the first out-of-bounds granule. */
+	KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)v_ptr)[size + 5]);
+
+	/* Check that in-bounds accesses to the physical page are valid. */
+	page = vmalloc_to_page(v_ptr);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, page);
+	p_ptr = page_address(page);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p_ptr);
+	p_ptr[0] = 0;
+
+	vfree(v_ptr);
+
+	/*
+	 * We can't check for use-after-unmap bugs in this nor in the following
+	 * vmalloc tests, as the page might be fully unmapped and accessing it
+	 * will crash the kernel.
+	 */
+}
+
+static void vmap_tags(struct kunit *test)
+{
+	char *p_ptr, *v_ptr;
+	struct page *p_page, *v_page;
+	size_t order = 1;
+
+	/*
+	 * This test is specifically crafted for the software tag-based mode,
+	 * the only tag-based mode that poisons vmap mappings.
+	 */
+	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_SW_TAGS);
+
+	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_VMALLOC);
+
+	p_page = alloc_pages(GFP_KERNEL, order);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p_page);
+	p_ptr = page_address(p_page);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p_ptr);
+
+	v_ptr = vmap(&p_page, 1 << order, VM_MAP, PAGE_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, v_ptr);
+
+	/*
+	 * We can't check for out-of-bounds bugs in this nor in the following
+	 * vmalloc tests, as allocations have page granularity and accessing
+	 * the guard page will crash the kernel.
+	 */
+
+	KUNIT_EXPECT_GE(test, (u8)get_tag(v_ptr), (u8)KASAN_TAG_MIN);
+	KUNIT_EXPECT_LT(test, (u8)get_tag(v_ptr), (u8)KASAN_TAG_KERNEL);
+
+	/* Make sure that in-bounds accesses through both pointers work. */
+	*p_ptr = 0;
+	*v_ptr = 0;
+
+	/* Make sure vmalloc_to_page() correctly recovers the page pointer. */
+	v_page = vmalloc_to_page(v_ptr);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, v_page);
+	KUNIT_EXPECT_PTR_EQ(test, p_page, v_page);
+
+	vunmap(v_ptr);
+	free_pages((unsigned long)p_ptr, order);
+}
+
+static void vm_map_ram_tags(struct kunit *test)
+{
+	char *p_ptr, *v_ptr;
+	struct page *page;
+	size_t order = 1;
+
+	/*
+	 * This test is specifically crafted for the software tag-based mode,
+	 * the only tag-based mode that poisons vm_map_ram mappings.
+	 */
+	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_SW_TAGS);
+
+	page = alloc_pages(GFP_KERNEL, order);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, page);
+	p_ptr = page_address(page);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p_ptr);
+
+	v_ptr = vm_map_ram(&page, 1 << order, -1);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, v_ptr);
+
+	KUNIT_EXPECT_GE(test, (u8)get_tag(v_ptr), (u8)KASAN_TAG_MIN);
+	KUNIT_EXPECT_LT(test, (u8)get_tag(v_ptr), (u8)KASAN_TAG_KERNEL);
+
+	/* Make sure that in-bounds accesses through both pointers work. */
+	*p_ptr = 0;
+	*v_ptr = 0;
+
+	vm_unmap_ram(v_ptr, 1 << order);
+	free_pages((unsigned long)p_ptr, order);
+}
+
+static void vmalloc_percpu(struct kunit *test)
+{
+	char __percpu *ptr;
+	int cpu;
+
+	/*
+	 * This test is specifically crafted for the software tag-based mode,
+	 * the only tag-based mode that poisons percpu mappings.
+	 */
+	KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_SW_TAGS);
+
+	ptr = __alloc_percpu(PAGE_SIZE, PAGE_SIZE);
+
+	for_each_possible_cpu(cpu) {
+		char *c_ptr = per_cpu_ptr(ptr, cpu);
+
+		KUNIT_EXPECT_GE(test, (u8)get_tag(c_ptr), (u8)KASAN_TAG_MIN);
+		KUNIT_EXPECT_LT(test, (u8)get_tag(c_ptr), (u8)KASAN_TAG_KERNEL);
+
+		/* Make sure that in-bounds accesses don't crash the kernel. */
+		*c_ptr = 0;
+	}
+
+	free_percpu(ptr);
 }
 
 /*
@@ -1097,6 +1258,18 @@ static void match_all_not_assigned(struct kunit *test)
 		KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
 		free_pages((unsigned long)ptr, order);
 	}
+
+	if (!IS_ENABLED(CONFIG_KASAN_VMALLOC))
+		return;
+
+	for (i = 0; i < 256; i++) {
+		size = (get_random_int() % 1024) + 1;
+		ptr = vmalloc(size);
+		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+		KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
+		KUNIT_EXPECT_LT(test, (u8)get_tag(ptr), (u8)KASAN_TAG_KERNEL);
+		vfree(ptr);
+	}
 }
 
 /* Check that 0xff works as a match-all pointer tag for tag-based modes. */
@@ -1202,7 +1375,11 @@ static struct kunit_case kasan_kunit_test_cases[] = {
 	KUNIT_CASE(kasan_bitops_generic),
 	KUNIT_CASE(kasan_bitops_tags),
 	KUNIT_CASE(kmalloc_double_kzfree),
+	KUNIT_CASE(vmalloc_helpers_tags),
 	KUNIT_CASE(vmalloc_oob),
+	KUNIT_CASE(vmap_tags),
+	KUNIT_CASE(vm_map_ram_tags),
+	KUNIT_CASE(vmalloc_percpu),
 	KUNIT_CASE(match_all_not_assigned),
 	KUNIT_CASE(match_all_ptr_tag),
 	KUNIT_CASE(match_all_mem_tag),
-- 
2.25.1



From elver at google.com  Mon Jan 24 10:09:43 2022
From: elver at google.com (Marco Elver)
Date: Mon, 24 Jan 2022 19:09:43 +0100
Subject: [PATCH v6 00/39] kasan, vmalloc, arm64: add vmalloc tagging
 support for SW/HW_TAGS
In-Reply-To: <cover.1643047180.git.andreyknvl@google.com>
References: <cover.1643047180.git.andreyknvl@google.com>
Message-ID: <CANpmjNO2Lwq5+zy3pGj=cetMdB7qLmP0WWjbSCYucPVjEt4kWw@mail.gmail.com>

On Mon, 24 Jan 2022 at 19:02, <andrey.konovalov at linux.dev> wrote:
>
> From: Andrey Konovalov <andreyknvl at google.com>
>
> Hi,
>
> This patchset adds vmalloc tagging support for SW_TAGS and HW_TAGS
> KASAN modes.
[...]
>
> Acked-by: Marco Elver <elver at google.com>

FYI, my Ack may get lost here - on rebase you could apply it to all
patches to carry it forward. As-is, Andrew would still have to apply
it manually.

An Ack to the cover letter saves replying to each patch and thus
generating less emails, which I think is preferred.

My Ack is still valid, given v6 is mainly a rebase and I don't see any
major changes.

Thanks,
-- Marco

> Andrey Konovalov (39):
>   kasan, page_alloc: deduplicate should_skip_kasan_poison
>   kasan, page_alloc: move tag_clear_highpage out of
>     kernel_init_free_pages
>   kasan, page_alloc: merge kasan_free_pages into free_pages_prepare
>   kasan, page_alloc: simplify kasan_poison_pages call site
>   kasan, page_alloc: init memory of skipped pages on free
>   kasan: drop skip_kasan_poison variable in free_pages_prepare
>   mm: clarify __GFP_ZEROTAGS comment
>   kasan: only apply __GFP_ZEROTAGS when memory is zeroed
>   kasan, page_alloc: refactor init checks in post_alloc_hook
>   kasan, page_alloc: merge kasan_alloc_pages into post_alloc_hook
>   kasan, page_alloc: combine tag_clear_highpage calls in post_alloc_hook
>   kasan, page_alloc: move SetPageSkipKASanPoison in post_alloc_hook
>   kasan, page_alloc: move kernel_init_free_pages in post_alloc_hook
>   kasan, page_alloc: rework kasan_unpoison_pages call site
>   kasan: clean up metadata byte definitions
>   kasan: define KASAN_VMALLOC_INVALID for SW_TAGS
>   kasan, x86, arm64, s390: rename functions for modules shadow
>   kasan, vmalloc: drop outdated VM_KASAN comment
>   kasan: reorder vmalloc hooks
>   kasan: add wrappers for vmalloc hooks
>   kasan, vmalloc: reset tags in vmalloc functions
>   kasan, fork: reset pointer tags of vmapped stacks
>   kasan, arm64: reset pointer tags of vmapped stacks
>   kasan, vmalloc: add vmalloc tagging for SW_TAGS
>   kasan, vmalloc, arm64: mark vmalloc mappings as pgprot_tagged
>   kasan, vmalloc: unpoison VM_ALLOC pages after mapping
>   kasan, mm: only define ___GFP_SKIP_KASAN_POISON with HW_TAGS
>   kasan, page_alloc: allow skipping unpoisoning for HW_TAGS
>   kasan, page_alloc: allow skipping memory init for HW_TAGS
>   kasan, vmalloc: add vmalloc tagging for HW_TAGS
>   kasan, vmalloc: only tag normal vmalloc allocations
>   kasan, arm64: don't tag executable vmalloc allocations
>   kasan: mark kasan_arg_stacktrace as __initdata
>   kasan: clean up feature flags for HW_TAGS mode
>   kasan: add kasan.vmalloc command line flag
>   kasan: allow enabling KASAN_VMALLOC and SW/HW_TAGS
>   arm64: select KASAN_VMALLOC for SW/HW_TAGS modes
>   kasan: documentation updates
>   kasan: improve vmalloc tests
>
>  Documentation/dev-tools/kasan.rst   |  17 ++-
>  arch/arm64/Kconfig                  |   2 +-
>  arch/arm64/include/asm/vmalloc.h    |   6 +
>  arch/arm64/include/asm/vmap_stack.h |   5 +-
>  arch/arm64/kernel/module.c          |   5 +-
>  arch/arm64/mm/pageattr.c            |   2 +-
>  arch/arm64/net/bpf_jit_comp.c       |   3 +-
>  arch/s390/kernel/module.c           |   2 +-
>  arch/x86/kernel/module.c            |   2 +-
>  include/linux/gfp.h                 |  35 +++--
>  include/linux/kasan.h               |  97 +++++++++-----
>  include/linux/vmalloc.h             |  18 +--
>  include/trace/events/mmflags.h      |  14 +-
>  kernel/fork.c                       |   1 +
>  kernel/scs.c                        |   4 +-
>  lib/Kconfig.kasan                   |  20 +--
>  lib/test_kasan.c                    | 189 ++++++++++++++++++++++++++-
>  mm/kasan/common.c                   |   4 +-
>  mm/kasan/hw_tags.c                  | 193 ++++++++++++++++++++++------
>  mm/kasan/kasan.h                    |  18 ++-
>  mm/kasan/shadow.c                   |  63 +++++----
>  mm/page_alloc.c                     | 152 +++++++++++++++-------
>  mm/vmalloc.c                        |  99 +++++++++++---
>  23 files changed, 731 insertions(+), 220 deletions(-)
>
> --
> 2.25.1
>


From ezequiel at vanguardiasur.com.ar  Mon Jan 24 10:09:48 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 15:09:48 -0300
Subject: [PATCH V3 05/10] media: hantro: Allow i.MX8MQ G1 and G2 to run
 independently
In-Reply-To: <20220124023125.414794-6-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-6-aford173@gmail.com>
Message-ID: <Ye7rbLhM7OkjeiTz@eze-laptop>

Hi Adam,

On Sun, Jan 23, 2022 at 08:31:19PM -0600, Adam Ford wrote:
> The VPU in the i.MX8MQ is really the combination of Hantro G1 and
> Hantro G2. With the updated vpu-blk-ctrl, the power domains system
> can enable and disable them separately as well as pull them out of
> reset. This simplifies the code and lets them run independently
> while still retaining backwards compatibility with older device
> trees for those using G1.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 
> diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
> index 6a51f39dde56..a670ddd29c4c 100644
> --- a/drivers/staging/media/hantro/hantro_drv.c
> +++ b/drivers/staging/media/hantro/hantro_drv.c
> @@ -616,6 +616,7 @@ static const struct of_device_id of_hantro_match[] = {
>  #endif
>  #ifdef CONFIG_VIDEO_HANTRO_IMX8M
>  	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },

Since you might need to resend the series anyway due to the
issue with arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi,
could you add a small warning for the deprecated compatible string?

This will be a useful hint for kernel developers and system integrators
about the devicetree changes.

Something along these lines, maybe?

        match = of_match_node(of_hantro_match, pdev->dev.of_node);
        vpu->variant = match->data;

        /*
         * Support for nxp,imx8mq-vpu is kept for backwards compatibility
         * but it's deprecated. Please update your DTS file to use
         * nxp,imx8mq-vpu-g1 or nxp,imx8mq-vpu-g2 instead.
         */
        if (of_device_is_compatible(pdev->dev.of_node, "nxp,imx8mq-vpu"))
                dev_warn(&pdev->dev, "%s compatible is deprecated\n",
                         match->compatible);

In any case, the patch looks good:

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks,
Ezequiel


> +	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
>  	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
>  #endif
>  #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4
> diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
> index 4a19ae8940b9..f0bd2ffe290b 100644
> --- a/drivers/staging/media/hantro/hantro_hw.h
> +++ b/drivers/staging/media/hantro/hantro_hw.h
> @@ -299,6 +299,7 @@ enum hantro_enc_fmt {
>  	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
>  };
>  
> +extern const struct hantro_variant imx8mq_vpu_g1_variant;
>  extern const struct hantro_variant imx8mq_vpu_g2_variant;
>  extern const struct hantro_variant imx8mq_vpu_variant;
>  extern const struct hantro_variant px30_vpu_variant;
> diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> index f5991b8e553a..849ea7122d47 100644
> --- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
> +++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
> @@ -205,13 +205,6 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
>  	imx8m_soft_reset(vpu, RESET_G1);
>  }
>  
> -static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx)
> -{
> -	struct hantro_dev *vpu = ctx->dev;
> -
> -	imx8m_soft_reset(vpu, RESET_G2);
> -}
> -
>  /*
>   * Supported codec ops.
>   */
> @@ -237,17 +230,33 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
>  	},
>  };
>  
> +static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = {
> +	[HANTRO_MODE_MPEG2_DEC] = {
> +		.run = hantro_g1_mpeg2_dec_run,
> +		.init = hantro_mpeg2_dec_init,
> +		.exit = hantro_mpeg2_dec_exit,
> +	},
> +	[HANTRO_MODE_VP8_DEC] = {
> +		.run = hantro_g1_vp8_dec_run,
> +		.init = hantro_vp8_dec_init,
> +		.exit = hantro_vp8_dec_exit,
> +	},
> +	[HANTRO_MODE_H264_DEC] = {
> +		.run = hantro_g1_h264_dec_run,
> +		.init = hantro_h264_dec_init,
> +		.exit = hantro_h264_dec_exit,
> +	},
> +};
> +
>  static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
>  	[HANTRO_MODE_HEVC_DEC] = {
>  		.run = hantro_g2_hevc_dec_run,
> -		.reset = imx8m_vpu_g2_reset,
>  		.init = hantro_hevc_dec_init,
>  		.exit = hantro_hevc_dec_exit,
>  	},
>  	[HANTRO_MODE_VP9_DEC] = {
>  		.run = hantro_g2_vp9_dec_run,
>  		.done = hantro_g2_vp9_dec_done,
> -		.reset = imx8m_vpu_g2_reset,
>  		.init = hantro_vp9_dec_init,
>  		.exit = hantro_vp9_dec_exit,
>  	},
> @@ -267,6 +276,8 @@ static const struct hantro_irq imx8mq_g2_irqs[] = {
>  
>  static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
>  static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };
> +static const char * const imx8mq_g1_clk_names[] = { "g1" };
> +static const char * const imx8mq_g2_clk_names[] = { "g2" };
>  
>  const struct hantro_variant imx8mq_vpu_variant = {
>  	.dec_fmts = imx8m_vpu_dec_fmts,
> @@ -287,6 +298,21 @@ const struct hantro_variant imx8mq_vpu_variant = {
>  	.num_regs = ARRAY_SIZE(imx8mq_reg_names)
>  };
>  
> +const struct hantro_variant imx8mq_vpu_g1_variant = {
> +	.dec_fmts = imx8m_vpu_dec_fmts,
> +	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
> +	.postproc_fmts = imx8m_vpu_postproc_fmts,
> +	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
> +	.postproc_ops = &hantro_g1_postproc_ops,
> +	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
> +		 HANTRO_H264_DECODER,
> +	.codec_ops = imx8mq_vpu_g1_codec_ops,
> +	.irqs = imx8mq_irqs,
> +	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
> +	.clk_names = imx8mq_g1_clk_names,
> +	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
> +};
> +
>  const struct hantro_variant imx8mq_vpu_g2_variant = {
>  	.dec_offset = 0x0,
>  	.dec_fmts = imx8m_vpu_g2_dec_fmts,
> @@ -296,10 +322,8 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
>  	.postproc_ops = &hantro_g2_postproc_ops,
>  	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
>  	.codec_ops = imx8mq_vpu_g2_codec_ops,
> -	.init = imx8mq_vpu_hw_init,
> -	.runtime_resume = imx8mq_runtime_resume,
>  	.irqs = imx8mq_g2_irqs,
>  	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),
> -	.clk_names = imx8mq_clk_names,
> -	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),
> +	.clk_names = imx8mq_g2_clk_names,
> +	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
>  };
> -- 
> 2.32.0
> 


From ezequiel at vanguardiasur.com.ar  Mon Jan 24 10:10:53 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Mon, 24 Jan 2022 15:10:53 -0300
Subject: [PATCH V3 04/10] dt-bindings: media: nxp, imx8mq-vpu: Split G1
 and G2 nodes
In-Reply-To: <20220124023125.414794-5-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-5-aford173@gmail.com>
Message-ID: <Ye7rrQHtu1rnbdHm@eze-laptop>

On Sun, Jan 23, 2022 at 08:31:18PM -0600, Adam Ford wrote:
> The G1 and G2 are independent and separate decoder blocks
> that are enabled by the vpu-blk-ctrl power-domain controller,
> which now has a proper driver.
> 
> Because these blocks only share the power-domain, and can be
> independently fused out, update the bindings to support separate
> nodes for the G1 and G2 decoders with vpu-blk-ctrl power-domain
> support.
> 
> The new DT + old kernel isn't a supported configuration.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> 

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks,
Ezequiel

> diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> index 762be3f96ce9..9c28d562112b 100644
> --- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> @@ -15,33 +15,20 @@ description:
>  
>  properties:
>    compatible:
> -    const: nxp,imx8mq-vpu
> +    oneOf:
> +      - const: nxp,imx8mq-vpu
> +        deprecated: true
> +      - const: nxp,imx8mq-vpu-g1
> +      - const: nxp,imx8mq-vpu-g2
>  
>    reg:
> -    maxItems: 3
> -
> -  reg-names:
> -    items:
> -      - const: g1
> -      - const: g2
> -      - const: ctrl
> +    maxItems: 1
>  
>    interrupts:
> -    maxItems: 2
> -
> -  interrupt-names:
> -    items:
> -      - const: g1
> -      - const: g2
> +    maxItems: 1
>  
>    clocks:
> -    maxItems: 3
> -
> -  clock-names:
> -    items:
> -      - const: g1
> -      - const: g2
> -      - const: bus
> +    maxItems: 1
>  
>    power-domains:
>      maxItems: 1
> @@ -49,31 +36,33 @@ properties:
>  required:
>    - compatible
>    - reg
> -  - reg-names
>    - interrupts
> -  - interrupt-names
>    - clocks
> -  - clock-names
>  
>  additionalProperties: false
>  
>  examples:
>    - |
>          #include <dt-bindings/clock/imx8mq-clock.h>
> +        #include <dt-bindings/power/imx8mq-power.h>
> +        #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +        vpu_g1: video-codec at 38300000 {
> +                compatible = "nxp,imx8mq-vpu-g1";
> +                reg = <0x38300000 0x10000>;
> +                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> +                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> +        };
> +  - |
> +        #include <dt-bindings/clock/imx8mq-clock.h>
> +        #include <dt-bindings/power/imx8mq-power.h>
>          #include <dt-bindings/interrupt-controller/arm-gic.h>
>  
> -        vpu: video-codec at 38300000 {
> -                compatible = "nxp,imx8mq-vpu";
> -                reg = <0x38300000 0x10000>,
> -                      <0x38310000 0x10000>,
> -                      <0x38320000 0x10000>;
> -                reg-names = "g1", "g2", "ctrl";
> -                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> -                             <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> -                interrupt-names = "g1", "g2";
> -                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> -                         <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
> -                         <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> -                clock-names = "g1", "g2", "bus";
> -                power-domains = <&pgc_vpu>;
> +        vpu_g2: video-codec at 38300000 {
> +                compatible = "nxp,imx8mq-vpu-g2";
> +                reg = <0x38310000 0x10000>;
> +                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
>          };
> -- 
> 2.32.0
> 


From james.clark at arm.com  Mon Jan 24 10:11:01 2022
From: james.clark at arm.com (James Clark)
Date: Mon, 24 Jan 2022 18:11:01 +0000
Subject: [RFC V1 07/11] arm64/perf: Add BRBE driver
In-Reply-To: <1642998653-21377-8-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-8-git-send-email-anshuman.khandual@arm.com>
Message-ID: <e4b074e7-4e9b-bca3-e2f7-5d9411c6d392@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> This adds a BRBE driver which implements all the required helper functions
> for struct arm_pmu. Following functions are defined by this driver which
> will configure, enable, capture, reset and disable BRBE buffer HW as and
> when requested via perf branch stack sampling framework.
> 
> - arm64_pmu_brbe_filter()
> - arm64_pmu_brbe_enable()
> - arm64_pmu_brbe_disable()
> - arm64_pmu_brbe_read()
> - arm64_pmu_brbe_probe()
> - arm64_pmu_brbe_reset()
> - arm64_pmu_brbe_supported()
> 
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
[...]
> +static void perf_branch_to_brbcr(struct pmu_hw_events *cpuc, int branch_type)
> +{
> +	cpuc->brbcr = (BRBCR_CC | BRBCR_MPRED);
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_USER)
> +		cpuc->brbcr |= BRBCR_E0BRE;
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_KERNEL) {
> +		/*
> +		 * This should have been verified earlier.
> +		 */
> +		WARN_ON(!perfmon_capable());

If it's verified earlier than that value should be saved. At the moment this can
change depending on whichever process happens to be current when this is called.

I don't think perfmon_capable() should be called outside of the init function
of a PMU or outside of the perf core code. This function gets called on a path
from the PMU add function, where any process can be current.

See https://lore.kernel.org/lkml/20220118100702.GB16547 at willie-the-truck/T/#m42df3688e8afa299a7b8dfb7c3f4a785c52bcbed

> +		cpuc->brbcr |= BRBCR_E1BRE;
> +	}
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_NO_CYCLES)
> +		cpuc->brbcr &= ~BRBCR_CC;
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_NO_FLAGS)
> +		cpuc->brbcr &= ~BRBCR_MPRED;
> +
> +	if (!perfmon_capable())
> +		return;
> +

This will return here randomly depending on whether a user process or a kernel
process is 'current', resulting in exception samples randomly being enabled
and disabled.

> +	if (branch_type & PERF_SAMPLE_BRANCH_ANY) {
> +		cpuc->brbcr |= BRBCR_EXCEPTION;
> +		cpuc->brbcr |= BRBCR_ERTN;
> +		return;
> +	}
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_ANY_CALL)
> +		cpuc->brbcr |= BRBCR_EXCEPTION;
> +
> +	if (branch_type & PERF_SAMPLE_BRANCH_ANY_RETURN)
> +		cpuc->brbcr |= BRBCR_ERTN;
> +}
> +
> +
> +void arm64_pmu_brbe_filter(struct pmu_hw_events *cpuc, struct perf_event *event)
> +{
> +	u64 branch_type = event->attr.branch_sample_type;
> +
> +	if (brbe_disabled(cpuc))
> +		return;
> +
> +	perf_branch_to_brbfcr(cpuc, branch_type);
> +	perf_branch_to_brbcr(cpuc, branch_type);
> +}
> +
> +static int brbe_fetch_perf_type(u64 brbinf)
> +{
> +	int brbe_type = brbe_fetch_type(brbinf);
> +
> +	switch (brbe_type) {
> +	case BRBINF_TYPE_UNCOND_DIR:
> +		return PERF_BR_UNCOND;
> +	case BRBINF_TYPE_INDIR:
> +		return PERF_BR_IND;
> +	case BRBINF_TYPE_DIR_LINK:
> +		return PERF_BR_CALL;
> +	case BRBINF_TYPE_INDIR_LINK:
> +		return PERF_BR_IND_CALL;
> +	case BRBINF_TYPE_RET_SUB:
> +		return PERF_BR_RET;
> +	case BRBINF_TYPE_COND_DIR:
> +		return PERF_BR_COND;
> +	case BRBINF_TYPE_CALL:
> +		return PERF_BR_CALL;
> +	case BRBINF_TYPE_TRAP:
> +		return PERF_BR_SYSCALL;
> +	case BRBINF_TYPE_RET_EXCPT:
> +		return PERF_BR_UNKNOWN;
> +	case BRBINF_TYPE_IRQ:
> +		return PERF_BR_UNKNOWN;
> +	case BRBINF_TYPE_DEBUG_HALT:
> +	case BRBINF_TYPE_SERROR:
> +	case BRBINF_TYPE_INST_DEBUG:
> +	case BRBINF_TYPE_DATA_DEBUG:
> +	case BRBINF_TYPE_ALGN_FAULT:
> +	case BRBINF_TYPE_INST_FAULT:
> +	case BRBINF_TYPE_DATA_FAULT:
> +	case BRBINF_TYPE_FIQ:
> +	case BRBINF_TYPE_DEBUG_EXIT:
> +		return PERF_BR_UNKNOWN;
> +	default:
> +		pr_warn("unknown branch type captured\n");
> +		return PERF_BR_UNKNOWN;
> +	}
> +}
> +
> +static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *event,
> +			       u64 brbinf, int idx)
> +{
> +	int type = brbe_record_valid(brbinf);
> +
> +	if (!branch_sample_no_cycles(event))
> +		cpuc->brbe_entries[idx].cycles = brbe_fetch_cycles(brbinf);
> +
> +	if (branch_sample_type(event))
> +		cpuc->brbe_entries[idx].type = brbe_fetch_perf_type(brbinf);
> +
> +	if (!branch_sample_no_flags(event)) {
> +		/*
> +		 * BRBINF_LASTFAILED does not indicate that the last transaction
> +		 * got failed or aborted during the current branch record itself.
> +		 * Rather, this indicates that all the branch records which were
> +		 * in transaction until the curret branch record have failed. So
> +		 * the entire BRBE buffer needs to be processed later on to find
> +		 * all branch records which might have failed.
> +		 */
> +		cpuc->brbe_entries[idx].abort = brbinf & BRBINF_LASTFAILED;
> +
> +		/*
> +		 * All these information (i.e transaction state and mispredicts)
> +		 * are not available for target only branch records.
> +		 */
> +		if (type != BRBINF_VALID_TARGET) {
> +			cpuc->brbe_entries[idx].mispred = brbinf & BRBINF_MPRED;
> +			cpuc->brbe_entries[idx].predicted = !(brbinf & BRBINF_MPRED);
> +			cpuc->brbe_entries[idx].in_tx = brbinf & BRBINF_TX;
> +		}
> +	}
> +}
> +
> +/*
> + * A branch record with BRBINF_EL1.LASTFAILED set, implies that all
> + * preceding consecutive branch records, that were in a transaction
> + * (i.e their BRBINF_EL1.TX set) have been aborted.
> + *
> + * Similarly BRBFCR_EL1.LASTFAILED set, indicate that all preceding
> + * consecutive branch records upto the last record, which were in a
> + * transaction (i.e their BRBINF_EL1.TX set) have been aborted.
> + *
> + * --------------------------------- -------------------
> + * | 00 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX success]
> + * --------------------------------- -------------------
> + * | 01 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX success]
> + * --------------------------------- -------------------
> + * | 02 | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 0 |
> + * --------------------------------- -------------------
> + * | 03 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
> + * --------------------------------- -------------------
> + * | 04 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
> + * --------------------------------- -------------------
> + * | 05 | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 1 |
> + * --------------------------------- -------------------
> + * | .. | BRBSRC | BRBTGT | BRBINF | | TX = 0 | LF = 0 |
> + * --------------------------------- -------------------
> + * | 61 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
> + * --------------------------------- -------------------
> + * | 62 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
> + * --------------------------------- -------------------
> + * | 63 | BRBSRC | BRBTGT | BRBINF | | TX = 1 | LF = 0 | [TX failed]
> + * --------------------------------- -------------------
> + *
> + * BRBFCR_EL1.LASTFAILED == 1
> + *
> + * Here BRBFCR_EL1.LASTFAILED failes all those consecutive and also
> + * in transaction branches near the end of the BRBE buffer.
> + */
> +static void process_branch_aborts(struct pmu_hw_events *cpuc)
> +{
> +	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
> +	bool lastfailed = !!(brbfcr & BRBFCR_LASTFAILED);
> +	int idx = cpuc->brbe_nr - 1;
> +
> +	do {
> +		if (cpuc->brbe_entries[idx].in_tx) {
> +			cpuc->brbe_entries[idx].abort = lastfailed;
> +		} else {
> +			lastfailed = cpuc->brbe_entries[idx].abort;
> +			cpuc->brbe_entries[idx].abort = false;
> +		}
> +	} while (idx--, idx >= 0);
> +}
> +
> +void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event)
> +{
> +	u64 brbinf;
> +	int idx;
> +
> +	if (brbe_disabled(cpuc))
> +		return;
> +
> +	set_brbe_paused();
> +	for (idx = 0; idx < cpuc->brbe_nr; idx++) {
> +		select_brbe_bank_index(idx);
> +		brbinf = get_brbinf_reg(idx);
> +		/*
> +		 * There are no valid entries anymore on the buffer.
> +		 * Abort the branch record processing to save some
> +		 * cycles and also reduce the capture/process load
> +		 * for the user space as well.
> +		 */
> +		if (brbe_invalid(brbinf))
> +			break;
> +
> +		if (brbe_valid(brbinf)) {
> +			cpuc->brbe_entries[idx].from =  get_brbsrc_reg(idx);
> +			cpuc->brbe_entries[idx].to =  get_brbtgt_reg(idx);
> +		} else if (brbe_source(brbinf)) {
> +			cpuc->brbe_entries[idx].from =  get_brbsrc_reg(idx);
> +			cpuc->brbe_entries[idx].to = 0;
> +		} else if (brbe_target(brbinf)) {
> +			cpuc->brbe_entries[idx].from = 0;
> +			cpuc->brbe_entries[idx].to =  get_brbtgt_reg(idx);
> +		}
> +		capture_brbe_flags(cpuc, event, brbinf, idx);
> +	}
> +	cpuc->brbe_stack.nr = idx;
> +	cpuc->brbe_stack.hw_idx = -1ULL;
> +	process_branch_aborts(cpuc);
> +}
> +
> +void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc)
> +{
> +	if (brbe_disabled(cpuc))
> +		return;
> +
> +	asm volatile(BRB_IALL);
> +	isb();
> +}
> diff --git a/drivers/perf/arm_pmu_brbe.h b/drivers/perf/arm_pmu_brbe.h
> new file mode 100644
> index 000000000000..f04975cdc242
> --- /dev/null
> +++ b/drivers/perf/arm_pmu_brbe.h
> @@ -0,0 +1,259 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Branch Record Buffer Extension Helpers.
> + *
> + * Copyright (C) 2021 ARM Limited
> + *
> + * Author: Anshuman Khandual <anshuman.khandual at arm.com>
> + */
> +#define pr_fmt(fmt) "brbe: " fmt
> +
> +#include <linux/perf/arm_pmu.h>
> +
> +/*
> + * BRBE Instructions
> + *
> + * BRB_IALL : Invalidate the entire buffer
> + * BRB_INJ  : Inject latest branch record derived from [BRBSRCINJ, BRBTGTINJ, BRBINFINJ]
> + */
> +#define BRB_IALL __emit_inst(0xD5000000 | sys_insn(1, 1, 7, 2, 4) | (0x1f))
> +#define BRB_INJ  __emit_inst(0xD5000000 | sys_insn(1, 1, 7, 2, 5) | (0x1f))
> +
> +/*
> + * BRBE Buffer Organization
> + *
> + * BRBE buffer is arranged as multiple banks of 32 branch record
> + * entries each. An indivdial branch record in a given bank could
> + * be accessedi, after selecting the bank in BRBFCR_EL1.BANK and
> + * accessing the registers i.e [BRBSRC, BRBTGT, BRBINF] set with
> + * indices [0..31].
> + *
> + * Bank 0
> + *
> + *	---------------------------------	------
> + *	| 00 | BRBSRC | BRBTGT | BRBINF |	| 00 |
> + *	---------------------------------	------
> + *	| 01 | BRBSRC | BRBTGT | BRBINF |	| 01 |
> + *	---------------------------------	------
> + *	| .. | BRBSRC | BRBTGT | BRBINF |	| .. |
> + *	---------------------------------	------
> + *	| 31 | BRBSRC | BRBTGT | BRBINF |	| 31 |
> + *	---------------------------------	------
> + *
> + * Bank 1
> + *
> + *	---------------------------------	------
> + *	| 32 | BRBSRC | BRBTGT | BRBINF |	| 00 |
> + *	---------------------------------	------
> + *	| 33 | BRBSRC | BRBTGT | BRBINF |	| 01 |
> + *	---------------------------------	------
> + *	| .. | BRBSRC | BRBTGT | BRBINF |	| .. |
> + *	---------------------------------	------
> + *	| 63 | BRBSRC | BRBTGT | BRBINF |	| 31 |
> + *	---------------------------------	------
> + */
> +#define BRBE_BANK0_IDX_MIN 0
> +#define BRBE_BANK0_IDX_MAX 31
> +#define BRBE_BANK1_IDX_MIN 32
> +#define BRBE_BANK1_IDX_MAX 63
> +
> +#define RETURN_READ_BRBSRCN(n) \
> +	read_sysreg_s(SYS_BRBSRC##n##_EL1)
> +
> +#define RETURN_READ_BRBTGTN(n) \
> +	read_sysreg_s(SYS_BRBTGT##n##_EL1)
> +
> +#define RETURN_READ_BRBINFN(n) \
> +	read_sysreg_s(SYS_BRBINF##n##_EL1)
> +
> +#define BRBE_REGN_CASE(n, case_macro) \
> +	case n: return case_macro(n); break
> +
> +#define BRBE_REGN_SWITCH(x, case_macro)				\
> +	do {							\
> +		switch (x) {					\
> +		BRBE_REGN_CASE(0, case_macro);			\
> +		BRBE_REGN_CASE(1, case_macro);			\
> +		BRBE_REGN_CASE(2, case_macro);			\
> +		BRBE_REGN_CASE(3, case_macro);			\
> +		BRBE_REGN_CASE(4, case_macro);			\
> +		BRBE_REGN_CASE(5, case_macro);			\
> +		BRBE_REGN_CASE(6, case_macro);			\
> +		BRBE_REGN_CASE(7, case_macro);			\
> +		BRBE_REGN_CASE(8, case_macro);			\
> +		BRBE_REGN_CASE(9, case_macro);			\
> +		BRBE_REGN_CASE(10, case_macro);			\
> +		BRBE_REGN_CASE(11, case_macro);			\
> +		BRBE_REGN_CASE(12, case_macro);			\
> +		BRBE_REGN_CASE(13, case_macro);			\
> +		BRBE_REGN_CASE(14, case_macro);			\
> +		BRBE_REGN_CASE(15, case_macro);			\
> +		BRBE_REGN_CASE(16, case_macro);			\
> +		BRBE_REGN_CASE(17, case_macro);			\
> +		BRBE_REGN_CASE(18, case_macro);			\
> +		BRBE_REGN_CASE(19, case_macro);			\
> +		BRBE_REGN_CASE(20, case_macro);			\
> +		BRBE_REGN_CASE(21, case_macro);			\
> +		BRBE_REGN_CASE(22, case_macro);			\
> +		BRBE_REGN_CASE(23, case_macro);			\
> +		BRBE_REGN_CASE(24, case_macro);			\
> +		BRBE_REGN_CASE(25, case_macro);			\
> +		BRBE_REGN_CASE(26, case_macro);			\
> +		BRBE_REGN_CASE(27, case_macro);			\
> +		BRBE_REGN_CASE(28, case_macro);			\
> +		BRBE_REGN_CASE(29, case_macro);			\
> +		BRBE_REGN_CASE(30, case_macro);			\
> +		BRBE_REGN_CASE(31, case_macro);			\
> +		default:					\
> +			pr_warn("unknown register index\n");	\
> +			return -1;				\
> +		}						\
> +	} while (0)
> +
> +static inline int buffer_to_brbe_idx(int buffer_idx)
> +{
> +	return buffer_idx % 32;
> +}
> +
> +static inline u64 get_brbsrc_reg(int buffer_idx)
> +{
> +	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
> +
> +	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBSRCN);
> +}
> +
> +static inline u64 get_brbtgt_reg(int buffer_idx)
> +{
> +	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
> +
> +	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBTGTN);
> +}
> +
> +static inline u64 get_brbinf_reg(int buffer_idx)
> +{
> +	int brbe_idx = buffer_to_brbe_idx(buffer_idx);
> +
> +	BRBE_REGN_SWITCH(brbe_idx, RETURN_READ_BRBINFN);
> +}
> +
> +static inline u64 brbe_record_valid(u64 brbinf)
> +{
> +	return brbinf & (BRBINF_VALID_MASK << BRBINF_VALID_SHIFT);
> +}
> +
> +static inline bool brbe_invalid(u64 brbinf)
> +{
> +	return brbe_record_valid(brbinf) == BRBINF_VALID_INVALID;
> +}
> +
> +static inline bool brbe_valid(u64 brbinf)
> +{
> +	return brbe_record_valid(brbinf) == BRBINF_VALID_ALL;
> +}
> +
> +static inline bool brbe_source(u64 brbinf)
> +{
> +	return brbe_record_valid(brbinf) == BRBINF_VALID_SOURCE;
> +}
> +
> +static inline bool brbe_target(u64 brbinf)
> +{
> +	return brbe_record_valid(brbinf) == BRBINF_VALID_TARGET;
> +}
> +
> +static inline int brbe_fetch_cycles(u64 brbinf)
> +{
> +	/*
> +	 * Captured cycle count is unknown and hence
> +	 * should not be passed on the user space.
> +	 */
> +	if (brbinf & BRBINF_CCU)
> +		return 0;
> +
> +	return (brbinf >> BRBINF_CC_SHIFT) & BRBINF_CC_MASK;
> +}
> +
> +static inline int brbe_fetch_type(u64 brbinf)
> +{
> +	return (brbinf >> BRBINF_TYPE_SHIFT) & BRBINF_TYPE_MASK;
> +}
> +
> +static inline int brbe_fetch_el(u64 brbinf)
> +{
> +	return (brbinf >> BRBINF_EL_SHIFT) & BRBINF_EL_MASK;
> +}
> +
> +static inline int brbe_fetch_numrec(u64 brbidr)
> +{
> +	return (brbidr >> BRBIDR0_NUMREC_SHIFT) & BRBIDR0_NUMREC_MASK;
> +}
> +
> +static inline int brbe_fetch_format(u64 brbidr)
> +{
> +	return (brbidr >> BRBIDR0_FORMAT_SHIFT) & BRBIDR0_FORMAT_MASK;
> +}
> +
> +static inline int brbe_fetch_cc_bits(u64 brbidr)
> +{
> +	return (brbidr >> BRBIDR0_CC_SHIFT) & BRBIDR0_CC_MASK;
> +}
> +
> +static inline void select_brbe_bank(int bank)
> +{
> +	static int brbe_current_bank = -1;
> +	u64 brbfcr;
> +
> +	if (brbe_current_bank == bank)
> +		return;
> +
> +	WARN_ON(bank > 1);
> +	brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
> +	brbfcr &= ~(BRBFCR_BANK_MASK << BRBFCR_BANK_SHIFT);
> +	brbfcr |= ((bank & BRBFCR_BANK_MASK) << BRBFCR_BANK_SHIFT);
> +	write_sysreg_s(brbfcr, SYS_BRBFCR_EL1);
> +	isb();
> +	brbe_current_bank = bank;
> +}
> +
> +static inline void select_brbe_bank_index(int buffer_idx)
> +{
> +	switch (buffer_idx) {
> +	case BRBE_BANK0_IDX_MIN ... BRBE_BANK0_IDX_MAX:
> +		select_brbe_bank(0);
> +		break;
> +	case BRBE_BANK1_IDX_MIN ... BRBE_BANK1_IDX_MAX:
> +		select_brbe_bank(1);
> +		break;
> +	default:
> +		pr_warn("unsupported BRBE index\n");
> +	}
> +}
> +
> +static inline bool valid_brbe_nr(int brbe_nr)
> +{
> +	switch (brbe_nr) {
> +	case BRBIDR0_NUMREC_8:
> +	case BRBIDR0_NUMREC_16:
> +	case BRBIDR0_NUMREC_32:
> +	case BRBIDR0_NUMREC_64:
> +		return true;
> +	default:
> +		pr_warn("unsupported BRBE entries\n");
> +		return false;
> +	}
> +}
> +
> +static inline bool brbe_paused(void)
> +{
> +	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
> +
> +	return brbfcr & BRBFCR_PAUSED;
> +}
> +
> +static inline void set_brbe_paused(void)
> +{
> +	u64 brbfcr = read_sysreg_s(SYS_BRBFCR_EL1);
> +
> +	write_sysreg_s(brbfcr | BRBFCR_PAUSED, SYS_BRBFCR_EL1);
> +	isb();
> +}
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index c4a705d3d054..d401771e7767 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -146,6 +146,26 @@ struct arm_pmu {
>  	unsigned long acpi_cpuid;
>  };
>  
> +#ifdef CONFIG_ARM_BRBE_PMU
> +void arm64_pmu_brbe_filter(struct pmu_hw_events *hw_events, struct perf_event *event);
> +void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event);
> +void arm64_pmu_brbe_disable(struct pmu_hw_events *cpuc);
> +void arm64_pmu_brbe_enable(struct pmu_hw_events *cpuc);
> +void arm64_pmu_brbe_probe(struct pmu_hw_events *cpuc);
> +void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc);
> +bool arm64_pmu_brbe_supported(struct perf_event *event);
> +#else
> +static inline void arm64_pmu_brbe_filter(struct pmu_hw_events *hw_events, struct perf_event *event)
> +{
> +}
> +static inline void arm64_pmu_brbe_read(struct pmu_hw_events *cpuc, struct perf_event *event) { }
> +static inline void arm64_pmu_brbe_disable(struct pmu_hw_events *cpuc) { }
> +static inline void arm64_pmu_brbe_enable(struct pmu_hw_events *cpuc) { }
> +static inline void arm64_pmu_brbe_probe(struct pmu_hw_events *cpuc) { }
> +static inline void arm64_pmu_brbe_reset(struct pmu_hw_events *cpuc) { }
> +static inline bool arm64_pmu_brbe_supported(struct perf_event *event) {return false; }
> +#endif
> +
>  #define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))
>  
>  u64 armpmu_event_update(struct perf_event *event);
> 


From james.clark at arm.com  Mon Jan 24 10:15:30 2022
From: james.clark at arm.com (James Clark)
Date: Mon, 24 Jan 2022 18:15:30 +0000
Subject: [RFC V1 07/11] arm64/perf: Add BRBE driver
In-Reply-To: <1642998653-21377-8-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-8-git-send-email-anshuman.khandual@arm.com>
Message-ID: <774cac19-5907-0b35-92a4-ccfef3cc095d@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> This adds a BRBE driver which implements all the required helper functions
> for struct arm_pmu. Following functions are defined by this driver which
> will configure, enable, capture, reset and disable BRBE buffer HW as and
> when requested via perf branch stack sampling framework.
> 
> - arm64_pmu_brbe_filter()
> - arm64_pmu_brbe_enable()
> - arm64_pmu_brbe_disable()
> - arm64_pmu_brbe_read()
> - arm64_pmu_brbe_probe()
> - arm64_pmu_brbe_reset()
> - arm64_pmu_brbe_supported()
> 
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
[...]
> +bool arm64_pmu_brbe_supported(struct perf_event *event)
> +{
> +	struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
> +	struct pmu_hw_events *hw_events = per_cpu_ptr(armpmu->hw_events, event->cpu);
> +
> +	if (event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_KERNEL) {
> +		if (!perfmon_capable()) {
> +			pr_warn_once("does not have permission for kernel branch filter\n");
> +			return false;

Why not check perf_event_paranoid too? I would expect kernel sampling to be allowed for non
root users with paranoid <= 0.



From andreyknvl at gmail.com  Mon Jan 24 10:32:58 2022
From: andreyknvl at gmail.com (Andrey Konovalov)
Date: Mon, 24 Jan 2022 19:32:58 +0100
Subject: [PATCH v6 00/39] kasan, vmalloc, arm64: add vmalloc tagging
 support for SW/HW_TAGS
In-Reply-To: <CANpmjNO2Lwq5+zy3pGj=cetMdB7qLmP0WWjbSCYucPVjEt4kWw@mail.gmail.com>
References: <cover.1643047180.git.andreyknvl@google.com>
 <CANpmjNO2Lwq5+zy3pGj=cetMdB7qLmP0WWjbSCYucPVjEt4kWw@mail.gmail.com>
Message-ID: <CA+fCnZdxFnxXJyv6rqRgZynK5NC-PS1jSpAdwqVgymr2AL+63Q@mail.gmail.com>

On Mon, Jan 24, 2022 at 7:09 PM Marco Elver <elver at google.com> wrote:
>
> On Mon, 24 Jan 2022 at 19:02, <andrey.konovalov at linux.dev> wrote:
> >
> > From: Andrey Konovalov <andreyknvl at google.com>
> >
> > Hi,
> >
> > This patchset adds vmalloc tagging support for SW_TAGS and HW_TAGS
> > KASAN modes.
> [...]
> >
> > Acked-by: Marco Elver <elver at google.com>
>
> FYI, my Ack may get lost here - on rebase you could apply it to all
> patches to carry it forward. As-is, Andrew would still have to apply
> it manually.

Sounds good, will do if there is a v7.

> An Ack to the cover letter saves replying to each patch and thus
> generating less emails, which I think is preferred.
>
> My Ack is still valid, given v6 is mainly a rebase and I don't see any
> major changes.

Thanks, Marco!


From clg at kaod.org  Mon Jan 24 10:34:19 2022
From: clg at kaod.org (=?UTF-8?Q?C=c3=a9dric_Le_Goater?=)
Date: Mon, 24 Jan 2022 19:34:19 +0100
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <20220124153644.m3iwlvq5ld5cpbyz@ti.com>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com> <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com> <20220103171721.46c8e697@xps13>
 <YdSP6tKyQ2ZRUC+2@heinlein> <20220105063244.lno3xur64uepa7i5@ti.com>
 <d4ba6413-57ce-14c1-ed48-d00db2f74bd3@kaod.org>
 <20220124153644.m3iwlvq5ld5cpbyz@ti.com>
Message-ID: <b222361a-288a-55b2-fc02-04c0b93b4220@kaod.org>

>> spimem needs an extension I think. Sorry I have not been able to
>> push that forward. Lack of time and other tasks to address on the
>> host side of the machine. This is really a software problem, we
>> have the HW procedures ready. If a spimem expert could get involved
>> to make a few proposals, I would be happy to help and do some testing.
>> QEMU models are good enough for the software part. We can do the
>> training validation on real HW when ready.
> 
> What information about the flash do you need for this training? 

Last time I looked, we lacked some post_init handler to setup a slave:
configure the registers defining the AHB windows for each flash
slave and perform the read timing calibration. calibration should
only be done once.

See how the aspeed_spi_flash_init() routine doing the calibration
is hooked up under aspeed_spi_claim_bus() in the u-boot driver :

   https://github.com/openbmc/u-boot/blob/v2019.04-aspeed-openbmc/drivers/spi/aspeed_spi.c

Not good enough for upstream, Linux would be the same :/

> I proposed a patch series [0] some time ago trying to implement training
> for TI SoCs. It did not get merged but I do intend to respin it and get
> it through. Would this API work for your tuning as well?

I will take a look.
  
> Also, I am curious how your training works. What data do you read for
> training delays? Where is it stored? 

The driver reads the first 16K at slow speed (that's why we need a
basic minimal setup of the slave) and checks if the buffer is valid
enough for the calibration :

   https://github.com/openbmc/linux/blob/dev-5.15/drivers/mtd/spi-nor/controllers/aspeed-smc.c#L998

it then performs reads by changing the frequency and delays and
compares results with the initial default buffer.

if not, then the driver stays in a safe mode (slow).

> In our case we need to flash a
> known pattern at some location (which is passed in via DT). Do you need
> to run it for every read transaction or just once after the flash is
> initialized?

Just once because it is a heavy process. See the debug outputs below.
Once we have good read timings and frequency, there is no need to do
it each time.

> [0] https://patchwork.ozlabs.org/project/linux-mtd/list/?series=233504&state=%2A&archive=both
Thanks,

C.



There are 3 controllers, 1e620000/FMC is for the BMC. We keep
safe settings for it and normally u-boot has done the training
already . The other two controllers are for the SPI-NOR of the
host and for these we push the frequency higher.


AST2600 EVB:

[    0.689662] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency
[    0.696412] aspeed-smc 1e620000.spi: control register: 203b0641
[    0.696426] aspeed-smc 1e620000.spi: control register changed to: 00000600
[    0.696434] aspeed-smc 1e620000.spi: default control register: 00000600
[    0.696616] aspeed-smc 1e620000.spi: w25q512jv (65536 Kbytes)
[    0.703108] aspeed-smc 1e620000.spi: CE0 window [ 0x20000000 - 0x24000000 ] 64MB
[    0.711445] aspeed-smc 1e620000.spi: CE1 window [ 0x24000000 - 0x2c000000 ] 128MB
[    0.719864] aspeed-smc 1e620000.spi: write control register: 00120602
[    0.719873] aspeed-smc 1e620000.spi: read control register: 203c0641
[    0.727026] aspeed-smc 1e620000.spi: AHB frequency: 187 MHz
[    0.739247] aspeed-smc 1e620000.spi: Trying HCLK/5 [203c0d41] ...
[    0.767181] aspeed-smc 1e620000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    0.767196] aspeed-smc 1e620000.spi: Trying HCLK/4 [203c0641] ...
[    0.791559] aspeed-smc 1e620000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    0.791571] aspeed-smc 1e620000.spi: Found good read timings at HCLK/4
[    0.795729] 5 fixed-partitions partitions found on MTD device bmc
[    0.802636] Creating 5 MTD partitions on "bmc":
[    0.807739] 0x000000000000-0x0000000e0000 : "u-boot"
[    0.814367] 0x0000000e0000-0x000000100000 : "u-boot-env"
[    0.821306] 0x000000100000-0x000000a00000 : "kernel"
[    0.827755] 0x000000a00000-0x000002a00000 : "rofs"
[    0.834051] 0x000002a00000-0x000004000000 : "rwfs"
[    0.844040] aspeed-smc 1e630000.spi: Using 100 MHz SPI frequency
[    0.850912] aspeed-smc 1e630000.spi: control register: 00000400
[    0.850927] aspeed-smc 1e630000.spi: default control register: 00000400
[    0.851152] aspeed-smc 1e630000.spi: w25q256 (32768 Kbytes)
[    0.857427] aspeed-smc 1e630000.spi: CE0 window [ 0x30000000 - 0x32000000 ] 32MB
[    0.865792] aspeed-smc 1e630000.spi: CE1 window [ 0x32000000 - 0x32000000 ] 0MB (disabled)
[    0.875129] aspeed-smc 1e630000.spi: write control register: 00120402
[    0.875142] aspeed-smc 1e630000.spi: read control register: 203c0441
[    0.882296] aspeed-smc 1e630000.spi: AHB frequency: 187 MHz
[    0.894509] aspeed-smc 1e630000.spi: Trying HCLK/5 [203c0d41] ...
[    0.922417] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    0.922432] aspeed-smc 1e630000.spi: Trying HCLK/4 [203c0641] ...
[    0.946791] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    0.946803] aspeed-smc 1e630000.spi: Trying HCLK/3 [203c0e41] ...
[    0.967644] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    0.967655] aspeed-smc 1e630000.spi: Trying HCLK/2 [203c0741] ...
[    0.969325] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, DI delay none : FAIL
[    0.971007] aspeed-smc 1e630000.spi:   * [00000008] 0 HCLK delay, DI delay 0.5ns : FAIL
[    0.972679] aspeed-smc 1e630000.spi:   * [00000018] 0 HCLK delay, DI delay 1.5ns : FAIL
[    0.974350] aspeed-smc 1e630000.spi:   * [00000028] 0 HCLK delay, DI delay 1.5ns : FAIL
[    0.976021] aspeed-smc 1e630000.spi:   * [00000038] 0 HCLK delay, DI delay 2.5ns : FAIL
[    0.977692] aspeed-smc 1e630000.spi:   * [00000048] 0 HCLK delay, DI delay 2.5ns : FAIL
[    0.979363] aspeed-smc 1e630000.spi:   * [00000058] 0 HCLK delay, DI delay 3.5ns : FAIL
[    0.981042] aspeed-smc 1e630000.spi:   * [00000068] 0 HCLK delay, DI delay 3.5ns : FAIL
[    0.982714] aspeed-smc 1e630000.spi:   * [00000078] 0 HCLK delay, DI delay 4.5ns : FAIL
[    0.984385] aspeed-smc 1e630000.spi:   * [00000088] 0 HCLK delay, DI delay 4.5ns : FAIL
[    0.986056] aspeed-smc 1e630000.spi:   * [00000098] 0 HCLK delay, DI delay 5.5ns : FAIL
[    0.987727] aspeed-smc 1e630000.spi:   * [000000a8] 0 HCLK delay, DI delay 5.5ns : FAIL
[    0.989397] aspeed-smc 1e630000.spi:   * [000000b8] 0 HCLK delay, DI delay 6.5ns : FAIL
[    0.991084] aspeed-smc 1e630000.spi:   * [000000c8] 0 HCLK delay, DI delay 6.5ns : FAIL
[    0.992757] aspeed-smc 1e630000.spi:   * [000000d8] 0 HCLK delay, DI delay 7.5ns : FAIL
[    0.994428] aspeed-smc 1e630000.spi:   * [000000e8] 0 HCLK delay, DI delay 7.5ns : FAIL
[    0.996099] aspeed-smc 1e630000.spi:   * [000000f8] 0 HCLK delay, DI delay 8.5ns : FAIL
[    1.013874] aspeed-smc 1e630000.spi:   * [000000f1] 1 HCLK delay, DI delay none : PASS
[    1.013885] aspeed-smc 1e630000.spi: Found good read timings at HCLK/2
[    1.021498] aspeed-smc 1e631000.spi: Using 100 MHz SPI frequency
[    1.028291] aspeed-smc 1e631000.spi: control register: 00000400
[    1.028302] aspeed-smc 1e631000.spi: default control register: 00000400
[    1.028510] aspeed-smc 1e631000.spi: w25q256 (32768 Kbytes)
[    1.034848] aspeed-smc 1e631000.spi: CE0 window [ 0x50000000 - 0x52000000 ] 32MB
[    1.043197] aspeed-smc 1e631000.spi: CE1 window [ 0x52000000 - 0x52000000 ] 0MB (disabled)
[    1.052518] aspeed-smc 1e631000.spi: write control register: 00120402
[    1.052530] aspeed-smc 1e631000.spi: read control register: 203c0441
[    1.059677] aspeed-smc 1e631000.spi: AHB frequency: 187 MHz
[    1.071900] aspeed-smc 1e631000.spi: Trying HCLK/5 [203c0d41] ...
[    1.099805] aspeed-smc 1e631000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    1.099817] aspeed-smc 1e631000.spi: Trying HCLK/4 [203c0641] ...
[    1.124202] aspeed-smc 1e631000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    1.124219] aspeed-smc 1e631000.spi: Trying HCLK/3 [203c0e41] ...
[    1.145070] aspeed-smc 1e631000.spi:   * [00000000] 0 HCLK delay, DI delay none : PASS
[    1.145082] aspeed-smc 1e631000.spi: Trying HCLK/2 [203c0741] ...
[    1.146752] aspeed-smc 1e631000.spi:   * [00000000] 0 HCLK delay, DI delay none : FAIL
[    1.148422] aspeed-smc 1e631000.spi:   * [00000008] 0 HCLK delay, DI delay 0.5ns : FAIL
[    1.150093] aspeed-smc 1e631000.spi:   * [00000018] 0 HCLK delay, DI delay 1.5ns : FAIL
[    1.151778] aspeed-smc 1e631000.spi:   * [00000028] 0 HCLK delay, DI delay 1.5ns : FAIL
[    1.153451] aspeed-smc 1e631000.spi:   * [00000038] 0 HCLK delay, DI delay 2.5ns : FAIL
[    1.155122] aspeed-smc 1e631000.spi:   * [00000048] 0 HCLK delay, DI delay 2.5ns : FAIL
[    1.156793] aspeed-smc 1e631000.spi:   * [00000058] 0 HCLK delay, DI delay 3.5ns : FAIL
[    1.158464] aspeed-smc 1e631000.spi:   * [00000068] 0 HCLK delay, DI delay 3.5ns : FAIL
[    1.160135] aspeed-smc 1e631000.spi:   * [00000078] 0 HCLK delay, DI delay 4.5ns : FAIL
[    1.161818] aspeed-smc 1e631000.spi:   * [00000088] 0 HCLK delay, DI delay 4.5ns : FAIL
[    1.163490] aspeed-smc 1e631000.spi:   * [00000098] 0 HCLK delay, DI delay 5.5ns : FAIL
[    1.165161] aspeed-smc 1e631000.spi:   * [000000a8] 0 HCLK delay, DI delay 5.5ns : FAIL
[    1.166833] aspeed-smc 1e631000.spi:   * [000000b8] 0 HCLK delay, DI delay 6.5ns : FAIL
[    1.168504] aspeed-smc 1e631000.spi:   * [000000c8] 0 HCLK delay, DI delay 6.5ns : FAIL
[    1.170175] aspeed-smc 1e631000.spi:   * [000000d8] 0 HCLK delay, DI delay 7.5ns : FAIL
[    1.171863] aspeed-smc 1e631000.spi:   * [000000e8] 0 HCLK delay, DI delay 7.5ns : FAIL
[    1.173536] aspeed-smc 1e631000.spi:   * [000000f8] 0 HCLK delay, DI delay 8.5ns : FAIL
[    1.191318] aspeed-smc 1e631000.spi:   * [000000f1] 1 HCLK delay, DI delay none : PASS
[    1.191330] aspeed-smc 1e631000.spi: Found good read timings at HCLK/2


an ASTS2500 EVB :

[    1.220804] aspeed-smc 1e620000.spi: Using 50 MHz SPI frequency
[    1.226797] aspeed-smc 1e620000.spi: control register: 000b0641
[    1.226836] aspeed-smc 1e620000.spi: control register changed to: 00000600
[    1.226860] aspeed-smc 1e620000.spi: default control register: 00000600
[    1.227092] aspeed-smc 1e620000.spi: w25q256 (32768 Kbytes)
[    1.232806] aspeed-smc 1e620000.spi: CE0 window [ 0x20000000 - 0x22000000 ] 32MB
[    1.240329] aspeed-smc 1e620000.spi: CE1 window [ 0x22000000 - 0x2a000000 ] 128MB
[    1.247852] aspeed-smc 1e620000.spi: write control register: 00020602
[    1.247882] aspeed-smc 1e620000.spi: read control register: 203b0641
[    1.254315] aspeed-smc 1e620000.spi: AHB frequency: 198 MHz
[    1.265406] aspeed-smc 1e620000.spi: Trying HCLK/5 [203b0d41] ...
[    1.287111] aspeed-smc 1e620000.spi:   * [00080000] 0 HCLK delay, 4ns DI delay : PASS
[    1.309048] aspeed-smc 1e620000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : PASS
[    1.331223] aspeed-smc 1e620000.spi:   * [00090000] 1 HCLK delay, 4ns DI delay : PASS
[    1.331278] aspeed-smc 1e620000.spi:  * -> good is pass 1 [0x00000000]
[    1.331308] aspeed-smc 1e620000.spi: Trying HCLK/4 [203b0641] ...
[    1.349958] aspeed-smc 1e620000.spi:   * [00008000] 0 HCLK delay, 4ns DI delay : PASS
[    1.368473] aspeed-smc 1e620000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : PASS
[    1.387341] aspeed-smc 1e620000.spi:   * [00009000] 1 HCLK delay, 4ns DI delay : PASS
[    1.387397] aspeed-smc 1e620000.spi:  * -> good is pass 1 [0x00000000]
[    1.387435] aspeed-smc 1e620000.spi: Found good read timings at HCLK/4
[    1.858947] Freeing initrd memory: 1044K
[    1.906913] 5 fixed-partitions partitions found on MTD device bmc
[    1.913143] Creating 5 MTD partitions on "bmc":
[    1.917724] 0x000000000000-0x000000060000 : "u-boot"
[    1.925920] 0x000000060000-0x000000080000 : "u-boot-env"
[    1.937262] 0x000000080000-0x0000004c0000 : "kernel"
[    1.948189] 0x0000004c0000-0x000001c00000 : "rofs"
[    1.959196] 0x000001c00000-0x000002000000 : "rwfs"
[    1.971557] aspeed-smc 1e630000.spi: Using 100 MHz SPI frequency
[    1.977632] aspeed-smc 1e630000.spi: control register: 00000200
[    1.977669] aspeed-smc 1e630000.spi: default control register: 00000200
[    1.977961] aspeed-smc 1e630000.spi: w25q256 (32768 Kbytes)
[    1.983674] aspeed-smc 1e630000.spi: CE0 window [ 0x30000000 - 0x32000000 ] 32MB
[    1.991183] aspeed-smc 1e630000.spi: CE1 window [ 0x32000000 - 0x38000000 ] 96MB
[    1.998621] aspeed-smc 1e630000.spi: write control register: 00020202
[    1.998652] aspeed-smc 1e630000.spi: read control register: 203b0241
[    2.005086] aspeed-smc 1e630000.spi: AHB frequency: 198 MHz
[    2.016174] aspeed-smc 1e630000.spi: Trying HCLK/5 [203b0d41] ...
[    2.038011] aspeed-smc 1e630000.spi:   * [00080000] 0 HCLK delay, 4ns DI delay : PASS
[    2.060035] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : PASS
[    2.082211] aspeed-smc 1e630000.spi:   * [00090000] 1 HCLK delay, 4ns DI delay : PASS
[    2.082266] aspeed-smc 1e630000.spi:  * -> good is pass 1 [0x00000000]
[    2.082295] aspeed-smc 1e630000.spi: Trying HCLK/4 [203b0641] ...
[    2.100938] aspeed-smc 1e630000.spi:   * [00008000] 0 HCLK delay, 4ns DI delay : PASS
[    2.119623] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : PASS
[    2.138440] aspeed-smc 1e630000.spi:   * [00009000] 1 HCLK delay, 4ns DI delay : PASS
[    2.138491] aspeed-smc 1e630000.spi:  * -> good is pass 1 [0x00000000]
[    2.138521] aspeed-smc 1e630000.spi: Trying HCLK/3 [203b0e41] ...
[    2.139827] aspeed-smc 1e630000.spi:   * [00000800] 0 HCLK delay, 4ns DI delay : FAIL
[    2.155093] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : PASS
[    2.170627] aspeed-smc 1e630000.spi:   * [00000900] 1 HCLK delay, 4ns DI delay : PASS
[    2.186111] aspeed-smc 1e630000.spi:   * [00000100] 1 HCLK delay, 0ns DI delay : PASS
[    2.186164] aspeed-smc 1e630000.spi:  * -> good is pass 2 [0x00000900]
[    2.186195] aspeed-smc 1e630000.spi: Trying HCLK/2 [203b0741] ...
[    2.187103] aspeed-smc 1e630000.spi:   * [00000080] 0 HCLK delay, 4ns DI delay : FAIL
[    2.188010] aspeed-smc 1e630000.spi:   * [00000000] 0 HCLK delay, 0ns DI delay : FAIL
[    2.200197] aspeed-smc 1e630000.spi:   * [00000090] 1 HCLK delay, 4ns DI delay : PASS
[    2.212359] aspeed-smc 1e630000.spi:   * [00000010] 1 HCLK delay, 0ns DI delay : PASS
[    2.224725] aspeed-smc 1e630000.spi:   * [000000a0] 2 HCLK delay, 4ns DI delay : PASS
[    2.224777] aspeed-smc 1e630000.spi:  * -> good is pass 3 [0x00000010]
[    2.224810] aspeed-smc 1e630000.spi: Found good read timings at HCLK/2
[    2.244098] aspeed-smc 1e631000.spi: Aspeed SMC probe failed -19


From kuba at kernel.org  Mon Jan 24 10:43:51 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 24 Jan 2022 10:43:51 -0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and
 unprepare "stmmaceth" clk
In-Reply-To: <20220123132805.758-1-jszhang@kernel.org>
References: <20220123132805.758-1-jszhang@kernel.org>
Message-ID: <20220124104351.2d5cab46@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Sun, 23 Jan 2022 21:28:05 +0800 Jisheng Zhang wrote:
> Fix warnings on Allwinner D1 platform:
> 
> [    1.604695] ------------[ cut here ]------------
> [    1.609328] bus-emac already disabled

Reading Samuel's feedback it sounds like the change will have to be
reposted with a different commit message (either explaining why the
fixes indeed works or as a clean up not a fix). 
Marking Changes Requested in patchwork.


From gregkh at linuxfoundation.org  Mon Jan 24 10:43:52 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:43:52 +0100
Subject: [PATCH 4.14 157/186] crypto: stm32/crc32 - Fix kernel BUG triggered
 in probe()
In-Reply-To: <20220124183937.101330125@linuxfoundation.org>
References: <20220124183937.101330125@linuxfoundation.org>
Message-ID: <20220124183942.146431609@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32_crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32_crc32.c
+++ b/drivers/crypto/stm32/stm32_crc32.c
@@ -206,7 +206,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -228,7 +228,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From gregkh at linuxfoundation.org  Mon Jan 24 10:44:05 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:44:05 +0100
Subject: [PATCH 4.19 207/239] crypto: stm32/crc32 - Fix kernel BUG triggered
 in probe()
In-Reply-To: <20220124183943.102762895@linuxfoundation.org>
References: <20220124183943.102762895@linuxfoundation.org>
Message-ID: <20220124183949.688480674@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32_crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32_crc32.c
+++ b/drivers/crypto/stm32/stm32_crc32.c
@@ -230,7 +230,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -252,7 +252,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From lkp at intel.com  Mon Jan 24 11:24:01 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 25 Jan 2022 03:24:01 +0800
Subject: [PATCH 3/4] crypto: xilinx: Add Xilinx SHA3 driver
In-Reply-To: <1642931227-20706-4-git-send-email-harsha.harsha@xilinx.com>
References: <1642931227-20706-4-git-send-email-harsha.harsha@xilinx.com>
Message-ID: <202201250209.WqpE2vMF-lkp@intel.com>

Hi Harsha,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on herbert-cryptodev-2.6/master]
[also build test WARNING on herbert-crypto-2.6/master]
[cannot apply to xilinx-xlnx/master v5.17-rc1 next-20220124]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Harsha/crypto-Add-Xilinx-ZynqMP-SHA3-driver-support/20220123-175102
base:   https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master
config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20220125/202201250209.WqpE2vMF-lkp at intel.com/config)
compiler: s390-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/fc7aea6e3118ca7210454fdb7c9c588c05c1f171
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Harsha/crypto-Add-Xilinx-ZynqMP-SHA3-driver-support/20220123-175102
        git checkout fc7aea6e3118ca7210454fdb7c9c588c05c1f171
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=s390 SHELL=/bin/bash drivers/crypto/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   In file included from ./arch/s390/include/generated/asm/cacheflush.h:1,
                    from drivers/crypto/xilinx/zynqmp-sha.c:6:
>> include/asm-generic/cacheflush.h:53:46: warning: 'struct folio' declared inside parameter list will not be visible outside of this definition or declaration
      53 | static inline void flush_dcache_folio(struct folio *folio) { }
         |                                              ^~~~~


vim +53 include/asm-generic/cacheflush.h

08b0b0059bf1c2 Matthew Wilcox (Oracle  2020-12-16  52) 
08b0b0059bf1c2 Matthew Wilcox (Oracle  2020-12-16 @53) static inline void flush_dcache_folio(struct folio *folio) { }
76b3b58fac350c Christoph Hellwig       2020-06-07  54  #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
08b0b0059bf1c2 Matthew Wilcox (Oracle  2020-12-16  55) #define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO
4f0bd808134d73 Mike Rapoport           2019-12-23  56  #endif
c296d4dc13aefe Qian Cai                2019-07-16  57  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From Jason at zx2c4.com  Mon Jan 24 11:28:49 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Mon, 24 Jan 2022 20:28:49 +0100
Subject: [PATCH v2] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <20220119135450.564115-1-Jason@zx2c4.com>
References: <20220119135450.564115-1-Jason@zx2c4.com>
Message-ID: <20220124192849.14755-1-Jason@zx2c4.com>

blake2s_compress_generic is weakly aliased by blake2s_generic. The
current harness for function selection uses a function pointer, which is
ordinarily inlined and resolved at compile time. But when Clang's CFI is
enabled, CFI still triggers when making an indirect call via a weak
symbol. This seems like a bug in Clang's CFI, as though it's bucketing
weak symbols and strong symbols differently. It also only seems to
trigger when "full LTO" mode is used, rather than "thin LTO".

[    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
[    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
[    0.000000][    T0] Hardware name: MT6873 (DT)
[    0.000000][    T0] Call trace:
[    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
[    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
[    0.000000][    T0]  panic+0x194/0x464
[    0.000000][    T0]  __cfi_check_fail+0x54/0x58
[    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
[    0.000000][    T0]  blake2s_update+0x14c/0x178
[    0.000000][    T0]  _extract_entropy+0xf4/0x29c
[    0.000000][    T0]  crng_initialize_primary+0x24/0x94
[    0.000000][    T0]  rand_initialize+0x2c/0x6c
[    0.000000][    T0]  start_kernel+0x2f8/0x65c
[    0.000000][    T0]  __primary_switched+0xc4/0x7be4
[    0.000000][    T0] Rebooting in 5 seconds..

Nonetheless, the function pointer method isn't so terrific anyway, so
this patch replaces it with a simple boolean, which also gets inlined
away. This successfully works around the Clang bug.

In general, I'm not too keen on all of the indirection involved here; it
clearly does more harm than good. Hopefully the whole thing can get
cleaned up down the road when lib/crypto is overhauled more
comprehensively. But for now, we go with a simple bandaid.

Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
Reported-by: Miles Chen <miles.chen at mediatek.com>
Tested-by: Miles Chen <miles.chen at mediatek.com>
Tested-by: Nathan Chancellor <nathan at kernel.org>
Link: https://github.com/ClangBuiltLinux/linux/issues/1567
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Sami Tolvanen <samitolvanen at google.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
---
Changes v1->v2:
- Wrapped columns at 80 for Eric.

 arch/arm/crypto/blake2s-shash.c   |  4 ++--
 arch/x86/crypto/blake2s-shash.c   |  4 ++--
 crypto/blake2s_generic.c          |  4 ++--
 include/crypto/internal/blake2s.h | 40 +++++++++++++++++++------------
 lib/crypto/blake2s.c              |  4 ++--
 5 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
index 17c1c3bfe2f5..763c73beea2d 100644
--- a/arch/arm/crypto/blake2s-shash.c
+++ b/arch/arm/crypto/blake2s-shash.c
@@ -13,12 +13,12 @@
 static int crypto_blake2s_update_arm(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen, false);
 }
 
 static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out, false);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
index f9e2fecdb761..59ae28abe35c 100644
--- a/arch/x86/crypto/blake2s-shash.c
+++ b/arch/x86/crypto/blake2s-shash.c
@@ -18,12 +18,12 @@
 static int crypto_blake2s_update_x86(struct shash_desc *desc,
 				     const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
+	return crypto_blake2s_update(desc, in, inlen, false);
 }
 
 static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress);
+	return crypto_blake2s_final(desc, out, false);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
index 72fe480f9bd6..5f96a21f8788 100644
--- a/crypto/blake2s_generic.c
+++ b/crypto/blake2s_generic.c
@@ -15,12 +15,12 @@
 static int crypto_blake2s_update_generic(struct shash_desc *desc,
 					 const u8 *in, unsigned int inlen)
 {
-	return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
+	return crypto_blake2s_update(desc, in, inlen, true);
 }
 
 static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
 {
-	return crypto_blake2s_final(desc, out, blake2s_compress_generic);
+	return crypto_blake2s_final(desc, out, true);
 }
 
 #define BLAKE2S_ALG(name, driver_name, digest_size)			\
diff --git a/include/crypto/internal/blake2s.h b/include/crypto/internal/blake2s.h
index d39cfa0d333e..52363eee2b20 100644
--- a/include/crypto/internal/blake2s.h
+++ b/include/crypto/internal/blake2s.h
@@ -24,14 +24,11 @@ static inline void blake2s_set_lastblock(struct blake2s_state *state)
 	state->f[0] = -1;
 }
 
-typedef void (*blake2s_compress_t)(struct blake2s_state *state,
-				   const u8 *block, size_t nblocks, u32 inc);
-
 /* Helper functions for BLAKE2s shared by the library and shash APIs */
 
-static inline void __blake2s_update(struct blake2s_state *state,
-				    const u8 *in, size_t inlen,
-				    blake2s_compress_t compress)
+static __always_inline void
+__blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen,
+		 bool force_generic)
 {
 	const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
 
@@ -39,7 +36,12 @@ static inline void __blake2s_update(struct blake2s_state *state,
 		return;
 	if (inlen > fill) {
 		memcpy(state->buf + state->buflen, in, fill);
-		(*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
+		if (force_generic)
+			blake2s_compress_generic(state, state->buf, 1,
+						 BLAKE2S_BLOCK_SIZE);
+		else
+			blake2s_compress(state, state->buf, 1,
+					 BLAKE2S_BLOCK_SIZE);
 		state->buflen = 0;
 		in += fill;
 		inlen -= fill;
@@ -47,7 +49,12 @@ static inline void __blake2s_update(struct blake2s_state *state,
 	if (inlen > BLAKE2S_BLOCK_SIZE) {
 		const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
 		/* Hash one less (full) block than strictly possible */
-		(*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
+		if (force_generic)
+			blake2s_compress_generic(state, in, nblocks - 1,
+						 BLAKE2S_BLOCK_SIZE);
+		else
+			blake2s_compress(state, in, nblocks - 1,
+					 BLAKE2S_BLOCK_SIZE);
 		in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 		inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
 	}
@@ -55,13 +62,16 @@ static inline void __blake2s_update(struct blake2s_state *state,
 	state->buflen += inlen;
 }
 
-static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
-				   blake2s_compress_t compress)
+static __always_inline void
+__blake2s_final(struct blake2s_state *state, u8 *out, bool force_generic)
 {
 	blake2s_set_lastblock(state);
 	memset(state->buf + state->buflen, 0,
 	       BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
-	(*compress)(state, state->buf, 1, state->buflen);
+	if (force_generic)
+		blake2s_compress_generic(state, state->buf, 1, state->buflen);
+	else
+		blake2s_compress(state, state->buf, 1, state->buflen);
 	cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
 	memcpy(out, state->h, state->outlen);
 }
@@ -99,20 +109,20 @@ static inline int crypto_blake2s_init(struct shash_desc *desc)
 
 static inline int crypto_blake2s_update(struct shash_desc *desc,
 					const u8 *in, unsigned int inlen,
-					blake2s_compress_t compress)
+					bool force_generic)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);
 
-	__blake2s_update(state, in, inlen, compress);
+	__blake2s_update(state, in, inlen, force_generic);
 	return 0;
 }
 
 static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
-				       blake2s_compress_t compress)
+				       bool force_generic)
 {
 	struct blake2s_state *state = shash_desc_ctx(desc);
 
-	__blake2s_final(state, out, compress);
+	__blake2s_final(state, out, force_generic);
 	return 0;
 }
 
diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
index 9364f79937b8..c71c09621c09 100644
--- a/lib/crypto/blake2s.c
+++ b/lib/crypto/blake2s.c
@@ -18,14 +18,14 @@
 
 void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
 {
-	__blake2s_update(state, in, inlen, blake2s_compress);
+	__blake2s_update(state, in, inlen, false);
 }
 EXPORT_SYMBOL(blake2s_update);
 
 void blake2s_final(struct blake2s_state *state, u8 *out)
 {
 	WARN_ON(IS_ENABLED(DEBUG) && !out);
-	__blake2s_final(state, out, blake2s_compress);
+	__blake2s_final(state, out, false);
 	memzero_explicit(state, sizeof(*state));
 }
 EXPORT_SYMBOL(blake2s_final);
-- 
2.34.1



From gregkh at linuxfoundation.org  Mon Jan 24 10:43:51 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:43:51 +0100
Subject: [PATCH 5.4 247/320] crypto: stm32/crc32 - Fix kernel BUG triggered in
 probe()
In-Reply-To: <20220124183953.750177707@linuxfoundation.org>
References: <20220124183953.750177707@linuxfoundation.org>
Message-ID: <20220124184002.395346406@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -230,7 +230,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -252,7 +252,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From nm at ti.com  Mon Jan 24 11:38:11 2022
From: nm at ti.com (Nishanth Menon)
Date: Mon, 24 Jan 2022 13:38:11 -0600
Subject: [PATCH v2] arm64: defconfig: Enable USB drivers for TI K3 SoC
In-Reply-To: <20211221152140.15151-1-vigneshr@ti.com>
References: <20211221152140.15151-1-vigneshr@ti.com>
Message-ID: <20220124193811.rsjikgyl3zo5lthi@undress>

On 20:51-20211221, Vignesh Raghavendra wrote:
> Enable Cadence USB, TI USB and required SERDES drivers to support USB on
> TI K3 SoCs.
> 
> Reported-by: Tom Rini <trini at konsulko.com>
> Signed-off-by: Vignesh Raghavendra <vigneshr at ti.com>
> Reviewed-by: Tom Rini <trini at konsulko.com>
> ---
> 
> v2:
> Drop Cadence PCIe driver configs as they cannot be built as modules
> based on feedback at [1].
> 
> v1: https://lore.kernel.org/r/20211208060856.16106-1-vigneshr at ti.com
> 
> [1] https://lore.kernel.org/linux-arm-kernel/CAK8P3a2VSBvOn1o+q1PYZaQ6LS9U4cz+DZGuDbisHkwNs2dAAw at mail.gmail.com/
> 

Picked this up for the next window.

Confirmed with bloat-o-meter that there is no addition to vmlinux

-- 
Regards,
Nishanth Menon
Key (0xDDB5849D1736249D) / Fingerprint: F8A2 8693 54EB 8232 17A3  1A34 DDB5 849D 1736 249D


From khilman at baylibre.com  Mon Jan 24 11:58:04 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 11:58:04 -0800
Subject: [PATCH V6 0/5] Use CCF to describe the UART baud rate clock
In-Reply-To: <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>
References: <20220118030911.12815-1-yu.tu@amlogic.com>
 <7hfspjqrn7.fsf@baylibre.com>
 <cc3b971f-c630-4ce2-e6dd-c13bcba89d22@amlogic.com>
Message-ID: <7hbl00ykhf.fsf@baylibre.com>

Yu Tu <yu.tu at amlogic.com> writes:

> Hi Kevin,
> 	Thank you very much for your reply.
>
> On 2022/1/20 6:37, Kevin Hilman wrote:
>> [ EXTERNAL EMAIL ]
>> 
>> Hello,
>> 
>> Yu Tu <yu.tu at amlogic.com> writes:
>> 
>>> Using the common Clock code to describe the UART baud rate
>>> clock makes it easier for the UART driver to be compatible
>>> with the baud rate requirements of the UART IP on different
>>> meson chips. Add Meson S4 SoC compatible.
>> 
>> Could you describe how this was tested and on which SoCs?  There seem to
>> be some changes in this series that might affect previous SoCs.
>> 
> For me, the board starts normally and prints. My intention was to add 
> the S4 SOC UART compatible, but for the S4 our baud rate clock is 
> calculated at 12MHz by default.So a series of changes were made at your 
> suggestion.
>
> Since most SoCs are too old, I was able to find all the platforms myself 
> such as Meson6, Meson8, Meson8b, GXL and so on. I only tested it with 
> G12A and S4.But when I talked to Martin earlier he tried meson8b's log.
> The test patch is in the attachment.
>
> I have found that on some boards with this change, the initcall_debug 
> Uart driver takes longer to initialize. Running the stty command to 
> change the baud rate at the same time may cause a jam.

This kind of detail is important to document in the cover letter,
including a bit more detail on how to reproduce so that other can help
test or may have ideas for how to solve.

> I'd love to know what else you suggest.

I don't expect you to be able to test on all SoCs, but just to list what
SoCs and which boards you tested on.  This way, those who have other
boards can help test and we can have a better idea of how this was
tested before merging.

Thanks,

Kevin


From ndesaulniers at google.com  Mon Jan 24 11:57:50 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Mon, 24 Jan 2022 11:57:50 -0800
Subject: [PATCH] ARM: vdso: remove -nostdlib compiler flag
In-Reply-To: <20220120054418.409817-1-masahiroy@kernel.org>
References: <20220120054418.409817-1-masahiroy@kernel.org>
Message-ID: <CAKwvOdkoK8uZP_uutf68StKi3pZjC6_4DSstg=PFQ2onB5NrJQ@mail.gmail.com>

FWIW, it looks like this has been submitted to RMK's queue:
https://www.armlinux.org.uk/developer/patches/viewpatch.php?id=9181/1


On Wed, Jan 19, 2022 at 9:44 PM Masahiro Yamada <masahiroy at kernel.org> wrote:
>
> The -nostdlib option requests the compiler to not use the standard
> system startup files or libraries when linking. It is effective only
> when $(CC) is used as a linker driver.
>
> Since commit fe00e50b2db8 ("ARM: 8858/1: vdso: use $(LD) instead of
> $(CC) to link VDSO"), $(LD) is directly used, hence -nostdlib is
> unneeded.
>
> Signed-off-by: Masahiro Yamada <masahiroy at kernel.org>
> Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>
> ---
>
> KernelVersion: 5.16
>
>  arch/arm/vdso/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/vdso/Makefile b/arch/arm/vdso/Makefile
> index 7c9e395b77f7..ec52b776f926 100644
> --- a/arch/arm/vdso/Makefile
> +++ b/arch/arm/vdso/Makefile
> @@ -18,7 +18,7 @@ ccflags-y += -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO32
>
>  ldflags-$(CONFIG_CPU_ENDIAN_BE8) := --be8
>  ldflags-y := -Bsymbolic --no-undefined -soname=linux-vdso.so.1 \
> -           -z max-page-size=4096 -nostdlib -shared $(ldflags-y) \
> +           -z max-page-size=4096 -shared $(ldflags-y) \
>             --hash-style=sysv --build-id=sha1 \
>             -T
>
> --
> 2.32.0
>


-- 
Thanks,
~Nick Desaulniers


From ndesaulniers at google.com  Mon Jan 24 11:59:48 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Mon, 24 Jan 2022 11:59:48 -0800
Subject: [PATCH v2] lib/crypto: blake2s: avoid indirect calls to
 compression function for Clang CFI
In-Reply-To: <20220124192849.14755-1-Jason@zx2c4.com>
References: <20220119135450.564115-1-Jason@zx2c4.com>
 <20220124192849.14755-1-Jason@zx2c4.com>
Message-ID: <CAKwvOd=hGx4WEFTNKFSwkk_VZgNd01a+OZR78TMmKfK5stpBbQ@mail.gmail.com>

On Mon, Jan 24, 2022 at 11:29 AM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> blake2s_compress_generic is weakly aliased by blake2s_generic. The
> current harness for function selection uses a function pointer, which is
> ordinarily inlined and resolved at compile time. But when Clang's CFI is
> enabled, CFI still triggers when making an indirect call via a weak
> symbol. This seems like a bug in Clang's CFI, as though it's bucketing
> weak symbols and strong symbols differently. It also only seems to
> trigger when "full LTO" mode is used, rather than "thin LTO".
>
> [    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
> [    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
> [    0.000000][    T0] Hardware name: MT6873 (DT)
> [    0.000000][    T0] Call trace:
> [    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
> [    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
> [    0.000000][    T0]  panic+0x194/0x464
> [    0.000000][    T0]  __cfi_check_fail+0x54/0x58
> [    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
> [    0.000000][    T0]  blake2s_update+0x14c/0x178
> [    0.000000][    T0]  _extract_entropy+0xf4/0x29c
> [    0.000000][    T0]  crng_initialize_primary+0x24/0x94
> [    0.000000][    T0]  rand_initialize+0x2c/0x6c
> [    0.000000][    T0]  start_kernel+0x2f8/0x65c
> [    0.000000][    T0]  __primary_switched+0xc4/0x7be4
> [    0.000000][    T0] Rebooting in 5 seconds..
>
> Nonetheless, the function pointer method isn't so terrific anyway, so
> this patch replaces it with a simple boolean, which also gets inlined
> away. This successfully works around the Clang bug.

Acked-by: Nick Desaulniers <ndesaulniers at google.com>

Thanks for the report. Once we have a fix in hand for LLVM, we can
revisit removing this and raising the required LLVM version for CFI.

>
> In general, I'm not too keen on all of the indirection involved here; it
> clearly does more harm than good. Hopefully the whole thing can get
> cleaned up down the road when lib/crypto is overhauled more
> comprehensively. But for now, we go with a simple bandaid.
>
> Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
> Reported-by: Miles Chen <miles.chen at mediatek.com>
> Tested-by: Miles Chen <miles.chen at mediatek.com>
> Tested-by: Nathan Chancellor <nathan at kernel.org>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1567
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Cc: Sami Tolvanen <samitolvanen at google.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
> ---
> Changes v1->v2:
> - Wrapped columns at 80 for Eric.
>
>  arch/arm/crypto/blake2s-shash.c   |  4 ++--
>  arch/x86/crypto/blake2s-shash.c   |  4 ++--
>  crypto/blake2s_generic.c          |  4 ++--
>  include/crypto/internal/blake2s.h | 40 +++++++++++++++++++------------
>  lib/crypto/blake2s.c              |  4 ++--
>  5 files changed, 33 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm/crypto/blake2s-shash.c b/arch/arm/crypto/blake2s-shash.c
> index 17c1c3bfe2f5..763c73beea2d 100644
> --- a/arch/arm/crypto/blake2s-shash.c
> +++ b/arch/arm/crypto/blake2s-shash.c
> @@ -13,12 +13,12 @@
>  static int crypto_blake2s_update_arm(struct shash_desc *desc,
>                                      const u8 *in, unsigned int inlen)
>  {
> -       return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +       return crypto_blake2s_update(desc, in, inlen, false);
>  }
>
>  static int crypto_blake2s_final_arm(struct shash_desc *desc, u8 *out)
>  {
> -       return crypto_blake2s_final(desc, out, blake2s_compress);
> +       return crypto_blake2s_final(desc, out, false);
>  }
>
>  #define BLAKE2S_ALG(name, driver_name, digest_size)                    \
> diff --git a/arch/x86/crypto/blake2s-shash.c b/arch/x86/crypto/blake2s-shash.c
> index f9e2fecdb761..59ae28abe35c 100644
> --- a/arch/x86/crypto/blake2s-shash.c
> +++ b/arch/x86/crypto/blake2s-shash.c
> @@ -18,12 +18,12 @@
>  static int crypto_blake2s_update_x86(struct shash_desc *desc,
>                                      const u8 *in, unsigned int inlen)
>  {
> -       return crypto_blake2s_update(desc, in, inlen, blake2s_compress);
> +       return crypto_blake2s_update(desc, in, inlen, false);
>  }
>
>  static int crypto_blake2s_final_x86(struct shash_desc *desc, u8 *out)
>  {
> -       return crypto_blake2s_final(desc, out, blake2s_compress);
> +       return crypto_blake2s_final(desc, out, false);
>  }
>
>  #define BLAKE2S_ALG(name, driver_name, digest_size)                    \
> diff --git a/crypto/blake2s_generic.c b/crypto/blake2s_generic.c
> index 72fe480f9bd6..5f96a21f8788 100644
> --- a/crypto/blake2s_generic.c
> +++ b/crypto/blake2s_generic.c
> @@ -15,12 +15,12 @@
>  static int crypto_blake2s_update_generic(struct shash_desc *desc,
>                                          const u8 *in, unsigned int inlen)
>  {
> -       return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic);
> +       return crypto_blake2s_update(desc, in, inlen, true);
>  }
>
>  static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
>  {
> -       return crypto_blake2s_final(desc, out, blake2s_compress_generic);
> +       return crypto_blake2s_final(desc, out, true);
>  }
>
>  #define BLAKE2S_ALG(name, driver_name, digest_size)                    \
> diff --git a/include/crypto/internal/blake2s.h b/include/crypto/internal/blake2s.h
> index d39cfa0d333e..52363eee2b20 100644
> --- a/include/crypto/internal/blake2s.h
> +++ b/include/crypto/internal/blake2s.h
> @@ -24,14 +24,11 @@ static inline void blake2s_set_lastblock(struct blake2s_state *state)
>         state->f[0] = -1;
>  }
>
> -typedef void (*blake2s_compress_t)(struct blake2s_state *state,
> -                                  const u8 *block, size_t nblocks, u32 inc);
> -
>  /* Helper functions for BLAKE2s shared by the library and shash APIs */
>
> -static inline void __blake2s_update(struct blake2s_state *state,
> -                                   const u8 *in, size_t inlen,
> -                                   blake2s_compress_t compress)
> +static __always_inline void
> +__blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen,
> +                bool force_generic)
>  {
>         const size_t fill = BLAKE2S_BLOCK_SIZE - state->buflen;
>
> @@ -39,7 +36,12 @@ static inline void __blake2s_update(struct blake2s_state *state,
>                 return;
>         if (inlen > fill) {
>                 memcpy(state->buf + state->buflen, in, fill);
> -               (*compress)(state, state->buf, 1, BLAKE2S_BLOCK_SIZE);
> +               if (force_generic)
> +                       blake2s_compress_generic(state, state->buf, 1,
> +                                                BLAKE2S_BLOCK_SIZE);
> +               else
> +                       blake2s_compress(state, state->buf, 1,
> +                                        BLAKE2S_BLOCK_SIZE);
>                 state->buflen = 0;
>                 in += fill;
>                 inlen -= fill;
> @@ -47,7 +49,12 @@ static inline void __blake2s_update(struct blake2s_state *state,
>         if (inlen > BLAKE2S_BLOCK_SIZE) {
>                 const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE);
>                 /* Hash one less (full) block than strictly possible */
> -               (*compress)(state, in, nblocks - 1, BLAKE2S_BLOCK_SIZE);
> +               if (force_generic)
> +                       blake2s_compress_generic(state, in, nblocks - 1,
> +                                                BLAKE2S_BLOCK_SIZE);
> +               else
> +                       blake2s_compress(state, in, nblocks - 1,
> +                                        BLAKE2S_BLOCK_SIZE);
>                 in += BLAKE2S_BLOCK_SIZE * (nblocks - 1);
>                 inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1);
>         }
> @@ -55,13 +62,16 @@ static inline void __blake2s_update(struct blake2s_state *state,
>         state->buflen += inlen;
>  }
>
> -static inline void __blake2s_final(struct blake2s_state *state, u8 *out,
> -                                  blake2s_compress_t compress)
> +static __always_inline void
> +__blake2s_final(struct blake2s_state *state, u8 *out, bool force_generic)
>  {
>         blake2s_set_lastblock(state);
>         memset(state->buf + state->buflen, 0,
>                BLAKE2S_BLOCK_SIZE - state->buflen); /* Padding */
> -       (*compress)(state, state->buf, 1, state->buflen);
> +       if (force_generic)
> +               blake2s_compress_generic(state, state->buf, 1, state->buflen);
> +       else
> +               blake2s_compress(state, state->buf, 1, state->buflen);
>         cpu_to_le32_array(state->h, ARRAY_SIZE(state->h));
>         memcpy(out, state->h, state->outlen);
>  }
> @@ -99,20 +109,20 @@ static inline int crypto_blake2s_init(struct shash_desc *desc)
>
>  static inline int crypto_blake2s_update(struct shash_desc *desc,
>                                         const u8 *in, unsigned int inlen,
> -                                       blake2s_compress_t compress)
> +                                       bool force_generic)
>  {
>         struct blake2s_state *state = shash_desc_ctx(desc);
>
> -       __blake2s_update(state, in, inlen, compress);
> +       __blake2s_update(state, in, inlen, force_generic);
>         return 0;
>  }
>
>  static inline int crypto_blake2s_final(struct shash_desc *desc, u8 *out,
> -                                      blake2s_compress_t compress)
> +                                      bool force_generic)
>  {
>         struct blake2s_state *state = shash_desc_ctx(desc);
>
> -       __blake2s_final(state, out, compress);
> +       __blake2s_final(state, out, force_generic);
>         return 0;
>  }
>
> diff --git a/lib/crypto/blake2s.c b/lib/crypto/blake2s.c
> index 9364f79937b8..c71c09621c09 100644
> --- a/lib/crypto/blake2s.c
> +++ b/lib/crypto/blake2s.c
> @@ -18,14 +18,14 @@
>
>  void blake2s_update(struct blake2s_state *state, const u8 *in, size_t inlen)
>  {
> -       __blake2s_update(state, in, inlen, blake2s_compress);
> +       __blake2s_update(state, in, inlen, false);
>  }
>  EXPORT_SYMBOL(blake2s_update);
>
>  void blake2s_final(struct blake2s_state *state, u8 *out)
>  {
>         WARN_ON(IS_ENABLED(DEBUG) && !out);
> -       __blake2s_final(state, out, blake2s_compress);
> +       __blake2s_final(state, out, false);
>         memzero_explicit(state, sizeof(*state));
>  }
>  EXPORT_SYMBOL(blake2s_final);
> --
> 2.34.1
>


-- 
Thanks,
~Nick Desaulniers


From khilman at baylibre.com  Mon Jan 24 12:02:28 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 12:02:28 -0800
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <20220122073221.2398-1-christianshewitt@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
Message-ID: <7h7daoyka3.fsf@baylibre.com>

Christian Hewitt <christianshewitt at gmail.com> writes:

> This resolves a long-running issue where Beelink GT-King/Pro and
> GS-King-X wedge on boot or shortly after when booting from vendor
> u-boot. In some distros the issue is often reported as triggered
> by large file transfers to/from USB or SD cards. Reserving the
> BL32 memory region prevents the issue.

The BL32 is typically common for the SoC family, so this change should
probably go into the g12b.dtsi.  Or probably even
meson-g12-common.dtsi, which is where the BL31 reserved-memory is
described.

Kevin




From gregkh at linuxfoundation.org  Mon Jan 24 10:43:27 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:43:27 +0100
Subject: [PATCH 5.10 442/563] crypto: stm32/crc32 - Fix kernel BUG triggered
 in probe()
In-Reply-To: <20220124184024.407936072@linuxfoundation.org>
References: <20220124184024.407936072@linuxfoundation.org>
Message-ID: <20220124184039.729742844@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From helgaas at kernel.org  Mon Jan 24 12:06:41 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Jan 2022 14:06:41 -0600
Subject: [PATCH RESEND v2 1/5] dt-bindings: pci: st-pcie: PCIe controller
 found on STi platforms
In-Reply-To: <20220103074731.3651-2-avolmat@me.com>
Message-ID: <20220124200641.GA1546900@bhelgaas>

On Mon, Jan 03, 2022 at 08:47:27AM +0100, Alain Volmat wrote:
> Addition of the bindings for the Designware based PCIe controller
> that can be found on STi platforms such as STiH407, STiH410 or STiH418.
> 
> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
>  .../devicetree/bindings/pci/snps,dw-pcie.yaml |   2 +-
>  .../devicetree/bindings/pci/st,st-pcie.yaml   | 112 ++++++++++++++++++
>  2 files changed, 113 insertions(+), 1 deletion(-)
>  create mode 100644 Documentation/devicetree/bindings/pci/st,st-pcie.yaml
> 
> diff --git a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
> index 9ed0dfba7f89..3a92078128f7 100644
> --- a/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
> +++ b/Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml
> @@ -35,7 +35,7 @@ properties:
>      maxItems: 5
>      items:
>        enum: [ dbi, dbi2, config, atu, app, elbi, mgmt, ctrl, parf, cfg, link,
> -              ulreg, smu, mpu, apb, phy ]
> +              ulreg, smu, mpu, apb, phy, mem-window ]
>  
>    num-lanes:
>      description: |
> diff --git a/Documentation/devicetree/bindings/pci/st,st-pcie.yaml b/Documentation/devicetree/bindings/pci/st,st-pcie.yaml
> new file mode 100644
> index 000000000000..2fa686d573c3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pci/st,st-pcie.yaml
> @@ -0,0 +1,112 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/pci/st,st-pcie.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: PCIe RC controller on ST STi platform
> +
> +maintainers:
> +  - Alain Volmat <avolmat at me.com>
> +
> +allOf:
> +  - $ref: /schemas/pci/snps,dw-pcie.yaml#
> +
> +properties:
> +  compatible:
> +    const: st,stih407-pcie
> +
> +  reg:
> +    items:
> +      - description: Controller control and status registers.
> +      - description: PCIe configuration registers.
> +      - description: Memory made available to the controller
> +
> +  reg-names:
> +    items:
> +      - const: dbi
> +      - const: config
> +      - const: mem-window

I guess "mem-window" is the range for inbound DMA?  Other controllers
should have similar ranges.  Can we use the same DT reg names used by
other controllers instead of adding something new and STi-specific?

> +  interrupts:
> +    maxItems: 1
> +
> +  resets:
> +    items:
> +    - description: Controller reset
> +    - description: Powerdown reset (optional)
> +    minItems: 1
> +
> +  reset-names:
> +    items:
> +      - const: softreset
> +      - const: powerdown

"softreset" and "powerdown" appear only in this binding.  Are they
really unique to STi, or can we use the same names used for other
controllers?


From mathieu.poirier at linaro.org  Mon Jan 24 12:08:30 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Mon, 24 Jan 2022 13:08:30 -0700
Subject: [PATCH] coresight: tmc: change device registration from misc to
 cdev
In-Reply-To: <20220124110018.68485-1-jkchen@linux.alibaba.com>
References: <20220124110018.68485-1-jkchen@linux.alibaba.com>
Message-ID: <CANLsYkxTy3fWgKx2QotWsSC9WZSmAroiFhMkPa9HapvzZNDjRg@mail.gmail.com>

On Mon, 24 Jan 2022 at 04:00, Jay Chen <jkchen at linux.alibaba.com> wrote:
>
> Currently, there are 130 etr and etf on our machine,
> but the current coresight tmc driver uses misc_register
> to register the device, which leads to the error that
> the device number is not enough.
>
> coresight-tmc: probe of xxxxx failed with error -16
>
> This patch changes the device registration method
> to cdev's dynamic registration method to solve the
> problem of insufficient device numbers.

This patch is still not labelled properly and as such being dropped.

>
> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> ---
>  .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
>  drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
>  2 files changed, 91 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> index d0276af82494..0977f1ce6338 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> @@ -12,7 +12,6 @@
>  #include <linux/io.h>
>  #include <linux/err.h>
>  #include <linux/fs.h>
> -#include <linux/miscdevice.h>
>  #include <linux/mutex.h>
>  #include <linux/property.h>
>  #include <linux/uaccess.h>
> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>  DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>  DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>
> +static DEFINE_IDA(tmc_ida);
> +static dev_t tmc_major;
> +static struct class *tmc_class;
> +
> +#define TMC_DEV_MAX    (MINORMASK + 1)
> +
>  void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>  {
>         struct coresight_device *csdev = drvdata->csdev;
> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
>  static int tmc_open(struct inode *inode, struct file *file)
>  {
>         int ret;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>
>         ret = tmc_read_prepare(drvdata);
>         if (ret)
> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>  {
>         char *bufp;
>         ssize_t actual;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>         actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>         if (actual <= 0)
>                 return 0;
> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>  static int tmc_release(struct inode *inode, struct file *file)
>  {
>         int ret;
> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> -                                                  struct tmc_drvdata, miscdev);
> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> +                                            struct tmc_cdev, cdev);
> +       struct tmc_drvdata *drvdata = container_of(cdev,
> +                                                  struct tmc_drvdata, cdev);
>
>         ret = tmc_read_unprepare(drvdata);
>         if (ret)
> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>  {
>         int ret = 0;
>         u32 devid;
> +       dev_t devt;
>         void __iomem *base;
>         struct device *dev = &adev->dev;
>         struct coresight_platform_data *pdata = NULL;
> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>                 goto out;
>         }
>
> -       drvdata->miscdev.name = desc.name;
> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> -       drvdata->miscdev.fops = &tmc_fops;
> -       ret = misc_register(&drvdata->miscdev);
> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> +       if (ret < 0)
> +               goto err_coresight_unregister;
> +
> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> +       drvdata->cdev.cdev.owner = THIS_MODULE;
> +       devt = MKDEV(MAJOR(tmc_major), ret);
> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>         if (ret)
> -               coresight_unregister(drvdata->csdev);
> -       else
> +               goto err_free_tmc_ida;
> +
> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> +       if (IS_ERR(drvdata->cdev.dev)) {
> +               ret = PTR_ERR(drvdata->cdev.dev);
> +               goto err_delete_cdev;
> +       } else
>                 pm_runtime_put(&adev->dev);
> +
> +       return 0;
> +
> +err_delete_cdev:
> +       cdev_del(&drvdata->cdev.cdev);
> +err_free_tmc_ida:
> +       ida_simple_remove(&tmc_ida, MINOR(devt));
> +err_coresight_unregister:
> +       coresight_unregister(drvdata->csdev);
>  out:
>         return ret;
>  }
> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
>  static void tmc_remove(struct amba_device *adev)
>  {
>         struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +       struct device *dev = drvdata->cdev.dev;
>
> -       /*
> -        * Since misc_open() holds a refcount on the f_ops, which is
> -        * etb fops in this case, device is there until last file
> -        * handler to this device is closed.
> -        */
> -       misc_deregister(&drvdata->miscdev);
> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
> +       device_destroy(tmc_class, dev->devt);
> +       cdev_del(&drvdata->cdev.cdev);
>         coresight_unregister(drvdata->csdev);
>  }
>
> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
>         .id_table       = tmc_ids,
>  };
>
> -module_amba_driver(tmc_driver);
> +static int __init tmc_init(void)
> +{
> +       int ret;
> +
> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> +       if (ret < 0) {
> +               pr_err("tmc: failed to allocate char dev region\n");
> +               return ret;
> +       }
> +
> +       tmc_class = class_create(THIS_MODULE, "tmc");
> +       if (IS_ERR(tmc_class)) {
> +               pr_err("tmc: failed to create class\n");
> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +               return PTR_ERR(tmc_class);
> +       }
> +
> +       ret = amba_driver_register(&tmc_driver);
> +       if (ret) {
> +               pr_err("tmc: error registering amba driver\n");
> +               class_destroy(tmc_class);
> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +       }
> +
> +       return ret;
> +}
> +
> +static void __exit tmc_exit(void)
> +{
> +       amba_driver_unregister(&tmc_driver);
> +       class_destroy(tmc_class);
> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> +}
> +
> +module_init(tmc_init);
> +module_exit(tmc_exit);
>
>  MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>  MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> index 6bec20a392b3..11441c6b9c26 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc.h
> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> @@ -7,9 +7,9 @@
>  #ifndef _CORESIGHT_TMC_H
>  #define _CORESIGHT_TMC_H
>
> +#include <linux/cdev.h>
>  #include <linux/dma-mapping.h>
>  #include <linux/idr.h>
> -#include <linux/miscdevice.h>
>  #include <linux/mutex.h>
>  #include <linux/refcount.h>
>
> @@ -163,11 +163,16 @@ struct etr_buf {
>         void                            *private;
>  };
>
> +struct tmc_cdev {
> +       struct cdev cdev;
> +       struct device *dev;
> +};
> +
>  /**
>   * struct tmc_drvdata - specifics associated to an TMC component
>   * @base:      memory mapped base address for this component.
>   * @csdev:     component vitals needed by the framework.
> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
>   * @spinlock:  only one at a time pls.
>   * @pid:       Process ID of the process being monitored by the session
>   *             that is using this component.
> @@ -191,7 +196,7 @@ struct etr_buf {
>  struct tmc_drvdata {
>         void __iomem            *base;
>         struct coresight_device *csdev;
> -       struct miscdevice       miscdev;
> +       struct tmc_cdev         cdev;
>         spinlock_t              spinlock;
>         pid_t                   pid;
>         bool                    reading;
> --
> 2.27.0
>


From maz at kernel.org  Mon Jan 24 12:12:21 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:21 +0000
Subject: [PATCH v4 00/10] drivers/perf: CPU PMU driver for Apple M1
Message-ID: <20220124201231.298961-1-maz@kernel.org>

The M1 SoC embeds a per-CPU PMU that has a very different programming
interface compared to the architected PMUv3 that is normally present
on standard implementations.

This small series adds a driver for this HW by leveraging the arm_pmu
infrastructure, resulting in a rather simple driver.

Of course, we know next to nothing about the actual events this PMU
counts, aside from CPU cycles and instructions. Everything else is
undocumented (though as Dougall pointed out, someone could extract the
relevant information from a macOS install if they wanted -- I don't).
I'm looking at allowing the perf userspace tool to load the event
descriptions at runtime, which would probably help.

* From v3 [3]:
  - DT binding fixes
  - Typo fixes (and probably more added)
  - Rebased on 5.17-rc1

* From v2 [2]:
  - Reworked the way the FIQ virtual affinity is exposed (now coming
    from the DT instead of being internal to the irqchip driver)
  - Dropped the locking from the PMU driver after Mark's review
  - Required the exclude_guest flag to be set, as the PMU doesn't seem
    to be able to count guest events, at least by default
  - Dropped the counter-stop on interrupt and instead stop the whole
    PMU on interrupt
  - Dropped the kernel taint, as I couldn't find a good way to do that
    on first use
  - Collected RBs from Hector

* From v1 [1]:
  - Added a few comments clarifying the event mapping to counters
  - Spelling fixes
  - Collected Acks from Rob

[1] https://lore.kernel.org/r/20211113115429.4027571-1-maz at kernel.org
[2] https://lore.kernel.org/r/20211201134909.390490-1-maz at kernel.org
[3] https://lore.kernel.org/r/20211214182634.727330-1-maz at kernel.org

Marc Zyngier (10):
  dt-bindings: arm-pmu: Document Apple PMU compatible strings
  dt-bindings: apple,aic: Add CPU PMU per-cpu pseudo-interrupts
  dt-bindings: apple,aic: Add affinity description for per-cpu
    pseudo-interrupts
  irqchip/apple-aic: Parse FIQ affinities from device-tree
  irqchip/apple-aic: Wire PMU interrupts
  arm64: dts: apple: Add t8103 PMU interrupt affinities
  arm64: dts: apple: Add t8303 PMU nodes
  irqchip/apple-aic: Move PMU-specific registers to their own include
    file
  drivers/perf: arm_pmu: Handle 47 bit counters
  drivers/perf: Add Apple icestorm/firestorm CPU PMU driver

 .../devicetree/bindings/arm/pmu.yaml          |   2 +
 .../interrupt-controller/apple,aic.yaml       |  29 +
 arch/arm64/boot/dts/apple/t8103.dtsi          |  24 +
 arch/arm64/include/asm/apple_m1_pmu.h         |  64 ++
 drivers/irqchip/irq-apple-aic.c               |  94 ++-
 drivers/perf/Kconfig                          |   7 +
 drivers/perf/Makefile                         |   1 +
 drivers/perf/apple_m1_cpu_pmu.c               | 584 ++++++++++++++++++
 drivers/perf/arm_pmu.c                        |   2 +
 .../interrupt-controller/apple-aic.h          |   2 +
 include/linux/perf/arm_pmu.h                  |   2 +
 11 files changed, 789 insertions(+), 22 deletions(-)
 create mode 100644 arch/arm64/include/asm/apple_m1_pmu.h
 create mode 100644 drivers/perf/apple_m1_cpu_pmu.c

-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:22 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:22 +0000
Subject: [PATCH v4 01/10] dt-bindings: arm-pmu: Document Apple PMU compatible
 strings
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-2-maz@kernel.org>

As we are about to add support fur the Apple PMUs, document the compatible
strings associated with the two micro-architectures present in the Apple M1.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 Documentation/devicetree/bindings/arm/pmu.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml
index 981bac451698..7a04b8aaaec3 100644
--- a/Documentation/devicetree/bindings/arm/pmu.yaml
+++ b/Documentation/devicetree/bindings/arm/pmu.yaml
@@ -20,6 +20,8 @@ properties:
     items:
       - enum:
           - apm,potenza-pmu
+          - apple,firestorm-pmu
+          - apple,icestorm-pmu
           - arm,armv8-pmuv3 # Only for s/w models
           - arm,arm1136-pmu
           - arm,arm1176-pmu
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:23 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:23 +0000
Subject: [PATCH v4 02/10] dt-bindings: apple,
 aic: Add CPU PMU per-cpu pseudo-interrupts
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-3-maz@kernel.org>

Advertise the two pseudo-interrupts that tied to the two PMU
flavours present in the Apple M1 SoC.

We choose the expose two different pseudo-interrupts to the OS
as the e-core PMU is obviously different from the p-core one,
effectively presenting two different devices.

Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 .../devicetree/bindings/interrupt-controller/apple,aic.yaml     | 2 ++
 include/dt-bindings/interrupt-controller/apple-aic.h            | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
index 97359024709a..c7577d401786 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
@@ -56,6 +56,8 @@ properties:
           - 1: virtual HV timer
           - 2: physical guest timer
           - 3: virtual guest timer
+          - 4: 'efficient' CPU PMU
+          - 5: 'performance' CPU PMU
 
       The 3rd cell contains the interrupt flags. This is normally
       IRQ_TYPE_LEVEL_HIGH (4).
diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h
index 604f2bb30ac0..bf3aac0e5491 100644
--- a/include/dt-bindings/interrupt-controller/apple-aic.h
+++ b/include/dt-bindings/interrupt-controller/apple-aic.h
@@ -11,5 +11,7 @@
 #define AIC_TMR_HV_VIRT		1
 #define AIC_TMR_GUEST_PHYS	2
 #define AIC_TMR_GUEST_VIRT	3
+#define AIC_CPU_PMU_E		4
+#define AIC_CPU_PMU_P		5
 
 #endif
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:24 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:24 +0000
Subject: [PATCH v4 03/10] dt-bindings: apple,
 aic: Add affinity description for per-cpu pseudo-interrupts
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-4-maz@kernel.org>

Some of the FIQ per-cpu pseudo-interrupts are better described with
a specific affinity, the most obvious candidate being the CPU PMUs.

Augment the AIC binding to be able to specify that affinity in the
interrupt controller node.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 .../interrupt-controller/apple,aic.yaml       | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
index c7577d401786..d97683eb2c54 100644
--- a/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
+++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
@@ -70,6 +70,33 @@ properties:
   power-domains:
     maxItems: 1
 
+  affinities:
+    type: object
+    description:
+      FIQ affinity can be expressed as a single "affinities" node,
+      containing a set of sub-nodes, one per FIQ with a non-default
+      affinity.
+    patternProperties:
+      "^.+-affinity$":
+        type: object
+        properties:
+          fiq-index:
+            description:
+              The interrupt number specified as a FIQ, and for which
+              the affinity is not the default.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            maximum: 5
+
+          cpus:
+            $ref: /schemas/types.yaml#/definitions/phandle-array
+            description:
+              Should be a list of phandles to CPU nodes (as described in
+              Documentation/devicetree/bindings/arm/cpus.yaml).
+
+        required:
+          - fiq-index
+          - cpus
+
 required:
   - compatible
   - '#interrupt-cells'
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:25 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:25 +0000
Subject: [PATCH v4 04/10] irqchip/apple-aic: Parse FIQ affinities from
 device-tree
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-5-maz@kernel.org>

In order to be able to tell the core IRQ code about the affinity
of the PMU interrupt in later patches, parse the affinities kindly
provided in the device-tree.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-apple-aic.c | 49 +++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index 2543ef65825b..2d31ac605573 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -177,6 +177,9 @@ struct aic_irq_chip {
 	void __iomem *base;
 	struct irq_domain *hw_domain;
 	struct irq_domain *ipi_domain;
+	struct {
+		cpumask_t aff;
+	} *fiq_aff[AIC_NR_FIQ];
 	int nr_hw;
 	int ipi_hwirq;
 };
@@ -794,12 +797,50 @@ static struct gic_kvm_info vgic_info __initdata = {
 	.no_hw_deactivation	= true,
 };
 
+static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff)
+{
+	int i, n;
+	u32 fiq;
+
+	if (of_property_read_u32(aff, "fiq-index", &fiq) ||
+	    WARN_ON(fiq >= AIC_NR_FIQ) || ic->fiq_aff[fiq])
+		return;
+
+	n = of_property_count_elems_of_size(aff, "cpus", sizeof(u32));
+	if (WARN_ON(n < 0))
+		return;
+
+	ic->fiq_aff[fiq] = kzalloc(sizeof(ic->fiq_aff[fiq]), GFP_KERNEL);
+	if (!ic->fiq_aff[fiq])
+		return;
+
+	for (i = 0; i < n; i++) {
+		struct device_node *cpu_node;
+		u32 cpu_phandle;
+		int cpu;
+
+		if (of_property_read_u32_index(aff, "cpus", i, &cpu_phandle))
+			continue;
+
+		cpu_node = of_find_node_by_phandle(cpu_phandle);
+		if (WARN_ON(!cpu_node))
+			continue;
+
+		cpu = of_cpu_node_to_id(cpu_node);
+		if (WARN_ON(cpu < 0))
+			continue;
+
+		cpumask_set_cpu(cpu, &ic->fiq_aff[fiq]->aff);
+	}
+}
+
 static int __init aic_of_ic_init(struct device_node *node, struct device_node *parent)
 {
 	int i;
 	void __iomem *regs;
 	u32 info;
 	struct aic_irq_chip *irqc;
+	struct device_node *affs;
 
 	regs = of_iomap(node, 0);
 	if (WARN_ON(!regs))
@@ -833,6 +874,14 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p
 		return -ENODEV;
 	}
 
+	affs = of_get_child_by_name(node, "affinities");
+	if (affs) {
+		struct device_node *chld;
+
+		for_each_child_of_node(affs, chld)
+			build_fiq_affinity(irqc, chld);
+	}
+
 	set_handle_irq(aic_handle_irq);
 	set_handle_fiq(aic_handle_fiq);
 
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:28 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:28 +0000
Subject: [PATCH v4 07/10] arm64: dts: apple: Add t8303 PMU nodes
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-8-maz@kernel.org>

Advertise the two PMU nodes for the t8103 SoC.

Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/boot/dts/apple/t8103.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index ca856f9955d8..aa0768ecb800 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -97,6 +97,18 @@ timer {
 			     <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>;
 	};
 
+	pmu-e {
+		compatible = "apple,icestorm-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,firestorm-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	clkref: clock-ref {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:29 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:29 +0000
Subject: [PATCH v4 08/10] irqchip/apple-aic: Move PMU-specific registers to
 their own include file
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-9-maz@kernel.org>

As we are about to have a PMU driver, move the PMU bits from the AIC
driver into a common include file.

Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/apple_m1_pmu.h | 19 +++++++++++++++++++
 drivers/irqchip/irq-apple-aic.c       | 11 +----------
 2 files changed, 20 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/include/asm/apple_m1_pmu.h

diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
new file mode 100644
index 000000000000..b848af7faadc
--- /dev/null
+++ b/arch/arm64/include/asm/apple_m1_pmu.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef __ASM_APPLE_M1_PMU_h
+#define __ASM_APPLE_M1_PMU_h
+
+#include <linux/bits.h>
+#include <asm/sysreg.h>
+
+/* Core PMC control register */
+#define SYS_IMP_APL_PMCR0_EL1	sys_reg(3, 1, 15, 0, 0)
+#define PMCR0_IMODE		GENMASK(10, 8)
+#define PMCR0_IMODE_OFF		0
+#define PMCR0_IMODE_PMI		1
+#define PMCR0_IMODE_AIC		2
+#define PMCR0_IMODE_HALT	3
+#define PMCR0_IMODE_FIQ		4
+#define PMCR0_IACT		BIT(11)
+
+#endif /* __ASM_APPLE_M1_PMU_h */
diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index 9daa28c55fa1..69e1e6abcc38 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -55,6 +55,7 @@
 #include <linux/limits.h>
 #include <linux/of_address.h>
 #include <linux/slab.h>
+#include <asm/apple_m1_pmu.h>
 #include <asm/exception.h>
 #include <asm/sysreg.h>
 #include <asm/virt.h>
@@ -109,16 +110,6 @@
  * Note: sysreg-based IPIs are not supported yet.
  */
 
-/* Core PMC control register */
-#define SYS_IMP_APL_PMCR0_EL1		sys_reg(3, 1, 15, 0, 0)
-#define PMCR0_IMODE			GENMASK(10, 8)
-#define PMCR0_IMODE_OFF			0
-#define PMCR0_IMODE_PMI			1
-#define PMCR0_IMODE_AIC			2
-#define PMCR0_IMODE_HALT		3
-#define PMCR0_IMODE_FIQ			4
-#define PMCR0_IACT			BIT(11)
-
 /* IPI request registers */
 #define SYS_IMP_APL_IPI_RR_LOCAL_EL1	sys_reg(3, 5, 15, 0, 0)
 #define SYS_IMP_APL_IPI_RR_GLOBAL_EL1	sys_reg(3, 5, 15, 0, 1)
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:26 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:26 +0000
Subject: [PATCH v4 05/10] irqchip/apple-aic: Wire PMU interrupts
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-6-maz@kernel.org>

Add the necessary code to configure and P and E-core PMU interrupts
with their respective affinities. When such an interrupt fires, map
it onto the right pseudo-interrupt.

Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/irqchip/irq-apple-aic.c | 34 +++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c
index 2d31ac605573..9daa28c55fa1 100644
--- a/drivers/irqchip/irq-apple-aic.c
+++ b/drivers/irqchip/irq-apple-aic.c
@@ -155,7 +155,7 @@
 #define SYS_IMP_APL_UPMSR_EL1		sys_reg(3, 7, 15, 6, 4)
 #define UPMSR_IACT			BIT(0)
 
-#define AIC_NR_FIQ		4
+#define AIC_NR_FIQ		6
 #define AIC_NR_SWIPI		32
 
 /*
@@ -416,16 +416,15 @@ static void __exception_irq_entry aic_handle_fiq(struct pt_regs *regs)
 						  aic_irqc->nr_hw + AIC_TMR_EL02_VIRT);
 	}
 
-	if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
-			(FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
-		/*
-		 * Not supported yet, let's figure out how to handle this when
-		 * we implement these proprietary performance counters. For now,
-		 * just mask it and move on.
-		 */
-		pr_err_ratelimited("PMC FIQ fired. Masking.\n");
-		sysreg_clear_set_s(SYS_IMP_APL_PMCR0_EL1, PMCR0_IMODE | PMCR0_IACT,
-				   FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_OFF));
+	if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
+		int irq;
+		if (cpumask_test_cpu(smp_processor_id(),
+				     &aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
+			irq = AIC_CPU_PMU_P;
+		else
+			irq = AIC_CPU_PMU_E;
+		generic_handle_domain_irq(aic_irqc->hw_domain,
+					  aic_irqc->nr_hw + irq);
 	}
 
 	if (FIELD_GET(UPMCR0_IMODE, read_sysreg_s(SYS_IMP_APL_UPMCR0_EL1)) == UPMCR0_IMODE_FIQ &&
@@ -465,7 +464,18 @@ static int aic_irq_domain_map(struct irq_domain *id, unsigned int irq,
 				    handle_fasteoi_irq, NULL, NULL);
 		irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq)));
 	} else {
-		irq_set_percpu_devid(irq);
+		int fiq = hw - ic->nr_hw;
+
+		switch (fiq) {
+		case AIC_CPU_PMU_P:
+		case AIC_CPU_PMU_E:
+			irq_set_percpu_devid_partition(irq, &ic->fiq_aff[fiq]->aff);
+			break;
+		default:
+			irq_set_percpu_devid(irq);
+			break;
+		}
+
 		irq_domain_set_info(id, irq, hw, &fiq_chip, id->host_data,
 				    handle_percpu_devid_irq, NULL, NULL);
 	}
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:27 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:27 +0000
Subject: [PATCH v4 06/10] arm64: dts: apple: Add t8103 PMU interrupt affinities
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-7-maz@kernel.org>

The two PMU pseudo interrupts have specific affinities. One set
is affine to the small cores, and the other set affine to the
big ones.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/boot/dts/apple/t8103.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8103.dtsi b/arch/arm64/boot/dts/apple/t8103.dtsi
index 19afbc91020a..ca856f9955d8 100644
--- a/arch/arm64/boot/dts/apple/t8103.dtsi
+++ b/arch/arm64/boot/dts/apple/t8103.dtsi
@@ -213,6 +213,18 @@ aic: interrupt-controller at 23b100000 {
 			interrupt-controller;
 			reg = <0x2 0x3b100000 0x0 0x8000>;
 			power-domains = <&ps_aic>;
+
+			affinities {
+				e-core-pmu-affinity {
+					fiq-index = <AIC_CPU_PMU_E>;
+					cpus = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+
+				p-core-pmu-affinity {
+					fiq-index = <AIC_CPU_PMU_P>;
+					cpus = <&cpu4 &cpu5 &cpu6 &cpu7>;
+				};
+			};
 		};
 
 		pmgr: power-management at 23b700000 {
-- 
2.30.2



From maz at kernel.org  Mon Jan 24 12:12:30 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:30 +0000
Subject: [PATCH v4 09/10] drivers/perf: arm_pmu: Handle 47 bit counters
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-10-maz@kernel.org>

The current ARM PMU framework can only deal with 32 or 64bit counters.
Teach it about a 47bit flavour.

Yes, this is odd.

Reviewed-by: Hector Martin <marcan at marcan.st>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 drivers/perf/arm_pmu.c       | 2 ++
 include/linux/perf/arm_pmu.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
index 295cc7952d0e..0a9ed1a061ac 100644
--- a/drivers/perf/arm_pmu.c
+++ b/drivers/perf/arm_pmu.c
@@ -109,6 +109,8 @@ static inline u64 arm_pmu_event_max_period(struct perf_event *event)
 {
 	if (event->hw.flags & ARMPMU_EVT_64BIT)
 		return GENMASK_ULL(63, 0);
+	else if (event->hw.flags & ARMPMU_EVT_47BIT)
+		return GENMASK_ULL(46, 0);
 	else
 		return GENMASK_ULL(31, 0);
 }
diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
index 2512e2f9cd4e..0407a38b470a 100644
--- a/include/linux/perf/arm_pmu.h
+++ b/include/linux/perf/arm_pmu.h
@@ -26,6 +26,8 @@
  */
 /* Event uses a 64bit counter */
 #define ARMPMU_EVT_64BIT		1
+/* Event uses a 47bit counter */
+#define ARMPMU_EVT_47BIT		2
 
 #define HW_OP_UNSUPPORTED		0xFFFF
 #define C(_x)				PERF_COUNT_HW_CACHE_##_x
-- 
2.30.2



From helgaas at kernel.org  Mon Jan 24 12:15:54 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Jan 2022 14:15:54 -0600
Subject: [PATCH RESEND v2 2/5] pci: dwc: pcie-st: Add PCIe driver for STi
 platforms
In-Reply-To: <20220103074731.3651-3-avolmat@me.com>
Message-ID: <20220124201554.GA1545465@bhelgaas>

On Mon, Jan 03, 2022 at 08:47:28AM +0100, Alain Volmat wrote:
> Addition of the PCIe driver (supporting RC) for controllers
> found on some STi platforms such as STiH407, STiH410 or
> STiH418.
> The controller is based on the designware PCIe controller.

Please follow the subject and commit log conventions in
drivers/pci/controller.  Update capitalization, use imperative mood,
blank lines between paragraphs, etc.  Wrap to fill 75 columns in the
commit log.

Follow OEM usage ("DesignWare"), also below in Kconfig help text and
comments.

In commit logs, comments, etc, use "PCIe" consistently, not "PCI
express" or "pcie".  Similarly, use "PHY" instead of "phy"; "GPIO"
instead of "gpio".

> Signed-off-by: Alain Volmat <avolmat at me.com>
> ---
> v2: update of the pcie-st driver to add possibility to build as module
>     and remove the __init of the probe
> 
>  drivers/pci/controller/dwc/Kconfig    |  11 +
>  drivers/pci/controller/dwc/Makefile   |   1 +
>  drivers/pci/controller/dwc/pcie-sti.c | 386 ++++++++++++++++++++++++++
>  3 files changed, 398 insertions(+)
>  create mode 100644 drivers/pci/controller/dwc/pcie-sti.c
> 
> diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
> index 62ce3abf0f19..232b8ffd54af 100644
> --- a/drivers/pci/controller/dwc/Kconfig
> +++ b/drivers/pci/controller/dwc/Kconfig
> @@ -384,4 +384,15 @@ config PCIE_FU740
>  	  Say Y here if you want PCIe controller support for the SiFive
>  	  FU740.
>  
> +config PCIE_STI
> +	tristate "STMicroelectronics PCIe Controller for STi SoCs"
> +	depends on ARCH_STI || COMPILE_TEST
> +	depends on OF && PCI_MSI_IRQ_DOMAIN
> +	select PCIE_DW_HOST
> +	help
> +	  Enable PCIe controller support on STMicroelectronics STi SoCs.
> +	  This controller is based on Designware hardware and therefore
> +	  the driver re-uses the Designware core functions to implement
> +	  the driver.
> +
>  endmenu
> diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile
> index 8ba7b67f5e50..c98fa18714ce 100644
> --- a/drivers/pci/controller/dwc/Makefile
> +++ b/drivers/pci/controller/dwc/Makefile
> @@ -21,6 +21,7 @@ obj-$(CONFIG_PCIE_KEEMBAY) += pcie-keembay.o
>  obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o
>  obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o
>  obj-$(CONFIG_PCI_MESON) += pci-meson.o
> +obj-$(CONFIG_PCIE_STI) += pcie-sti.o
>  obj-$(CONFIG_PCIE_TEGRA194) += pcie-tegra194.o
>  obj-$(CONFIG_PCIE_UNIPHIER) += pcie-uniphier.o
>  obj-$(CONFIG_PCIE_UNIPHIER_EP) += pcie-uniphier-ep.o
> diff --git a/drivers/pci/controller/dwc/pcie-sti.c b/drivers/pci/controller/dwc/pcie-sti.c
> new file mode 100644
> index 000000000000..61da00a079ac
> --- /dev/null
> +++ b/drivers/pci/controller/dwc/pcie-sti.c
> @@ -0,0 +1,386 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 STMicroelectronics
> + *
> + * STMicroelectronics PCI express Driver for STi SoCs.
> + * ST PCIe IPs are built around a Synopsys IP Core.
> + *
> + * Authors: Fabrice Gasnier <fabrice.gasnier at foss.st.com>
> + *          Alain Volmat <avolmat at me.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_platform.h>
> +#include <linux/phy/phy.h>
> +#include <linux/regmap.h>
> +#include <linux/reset.h>
> +
> +#include "pcie-designware.h"
> +
> +/* RC_ADDRESS_TRANSLATION Registers */
> +#define TRANSLATION_CONTROL		0x900
> +/* Controls if area is inclusive or exclusive */
> +#define RC_PASS_ADDR_RANGE		BIT(1)
> +
> +/* Base of area reserved for config accesses. Fixed size of 64K. */
> +#define CFG_BASE_ADDRESS		0x92c
> +#define CFG_REGION_SIZE			65536
> +#define CFG_SPACE1_OFFSET		0x1000
> +
> +/* First 4K of config space has this BDF (bus,device,function) */
> +#define FUNC0_BDF_NUM			0x930
> +
> +/* Mem regions */
> +#define IN0_MEM_ADDR_START		0x964
> +#define IN0_MEM_ADDR_LIMIT		0x968
> +#define IN1_MEM_ADDR_START		0x974
> +#define IN1_MEM_ADDR_LIMIT		0x978
> +
> +/* syscfg1 bits */
> +#define PCIE_APP_LTSSM_ENABLE		BIT(2)
> +/* syscfg0 bits */
> +#define PCIE_TYPE_ROOT_COMPLEX		BIT(0)
> +
> +/* st,syscfg offsets */
> +#define SYSCFG0_REG	1
> +#define SYSCFG1_REG	2
> +
> +#define to_st_pcie(x)	dev_get_drvdata((x)->dev)
> +
> +/**
> + * struct st_pcie - private data of the controller
> + * @dw: designware pcie
> + * @syscfg0: PCIe conf register setting root complex, regmap offset
> + * @syscfg1: PCIe conf register for PCIE_APP_LTSSM_ENABLE, regmap offset
> + * @phy: associated pcie phy
> + * @lmi: memory made available to the controller
> + * @regmap: Syscfg registers bank in which PCIe port is configured
> + * @pwr: power control
> + * @rst: reset control
> + * @reset_gpio: optional reset gpio
> + * @config_window_start: start address of 64K config space area
> + */
> +struct st_pcie {
> +	struct dw_pcie *dw;
> +	int syscfg0;
> +	int syscfg1;
> +	struct phy *phy;
> +	struct resource	*lmi;
> +	struct regmap *regmap;
> +	struct reset_control *pwr;
> +	struct reset_control *rst;
> +	struct gpio_desc *reset_gpio;
> +	phys_addr_t config_window_start;
> +};
> +
> +/*
> + * The PCI express core IP expects the following arrangement on it's address

s/PCI express/PCIe/
s/it's/its/

> + * bus (slv_haddr) when driving config cycles.
> + * bus_number		[31:24]
> + * dev_number		[23:19]
> + * func_number		[18:16]
> + * unused		[15:12]
> + * ext_reg_number	[11:8]
> + * reg_number		[7:2]
> + *
> + * Bits [15:12] are unused.
> + *
> + * In the glue logic there is a 64K region of address space that can be
> + * written/read to generate config cycles. The base address of this is
> + * controlled by CFG_BASE_ADDRESS. There are 8 16 bit registers called
> + * FUNC0_BDF_NUM to FUNC8_BDF_NUM. These split the bottom half of the 64K
> + * window into 8 regions at 4K boundaries. These control the bus, device and
> + * function number you are trying to talk to.
> + *
> + * The decision on whether to generate a type 0 or type 1 access is controlled
> + * by bits 15:12 of the address you write to.  If they are zero, then a type 0
> + * is generated, if anything else it will be a type 1. Thus the bottom 4K
> + * region controlled by FUNC0_BDF_NUM can only generate type 0, all the others
> + * can only generate type 1.
> + *
> + * We only use FUNC0_BDF_NUM and FUNC1_BDF_NUM. Which one you use is selected
> + * by bit 12 of the address you write to. The selected register is then used
> + * for the top 16 bits of the slv_haddr to form the bus/dev/func, bit 15:12 are
> + * wired to zero, and bits 11:2 form the address of the register you want to
> + * read in config space.
> + *
> + * We always write FUNC0_BDF_NUM as a 32 bit write. So if we want type 1
> + * accesses we have to shift by 16 so in effect we are writing to FUNC1_BDF_NUM
> + */
> +static inline u32 bdf_num(int bus, int devfn, int is_root_bus)
> +{
> +	return ((bus << 8) | devfn) << (is_root_bus ? 0 : 16);
> +}
> +
> +static void __iomem *st_pcie_other_map_bus(struct pci_bus *bus, unsigned int devfn, int where)

Wrap to fit in 80 columns (see other drivers for examples).  Wrap rest
of file similarly.

> +{
> +	struct pcie_port *pp = bus->sysdata;
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	u32 bdf;
> +
> +	bdf = bdf_num(bus->number, devfn, pci_is_root_bus(bus));
> +
> +	/* Set the config packet devfn */
> +	dw_pcie_writel_dbi(dw, FUNC0_BDF_NUM, bdf);
> +	dw_pcie_readl_dbi(dw, FUNC0_BDF_NUM);
> +
> +	return pp->va_cfg0_base + where + (pci_is_root_bus(bus->parent) ? 0 : CFG_SPACE1_OFFSET);
> +}
> +
> +static struct pci_ops st_child_pcie_ops = {
> +	.map_bus = st_pcie_other_map_bus,
> +	.read = pci_generic_config_read,
> +	.write = pci_generic_config_write,
> +};
> +
> +static void st_pcie_hw_setup(struct dw_pcie *dw)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +
> +	/* Set up the config window to the top of the PCI address space */
> +	dw_pcie_writel_dbi(dw, CFG_BASE_ADDRESS, pcie->config_window_start);
> +
> +	/*
> +	 * Open up memory to the PCI controller. We could do slightly
> +	 * better than this and exclude the kernel text segment and bss etc.
> +	 * They are base/limit registers so can be of arbitrary alignment
> +	 * presumably
> +	 */
> +	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_START, pcie->lmi->start);
> +	dw_pcie_writel_dbi(dw, IN0_MEM_ADDR_LIMIT, pcie->lmi->end);
> +
> +	/* Disable the 2nd region */
> +	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_START, ~0);
> +	dw_pcie_writel_dbi(dw, IN1_MEM_ADDR_LIMIT, 0);
> +
> +	dw_pcie_writel_dbi(dw, TRANSLATION_CONTROL, RC_PASS_ADDR_RANGE);
> +}
> +
> +static int st_pcie_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int ret;
> +
> +	/* Set device type : Root Complex */
> +	ret = regmap_write(pcie->regmap, pcie->syscfg0, PCIE_TYPE_ROOT_COMPLEX);
> +	if (ret < 0) {
> +		dev_err(dw->dev, "unable to set device type\n");
> +		return ret;
> +	}
> +
> +	ret = reset_control_deassert(pcie->pwr);
> +	if (ret) {
> +		dev_err(dw->dev, "unable to bring out of powerdown\n");
> +		return ret;
> +	}
> +
> +	ret = reset_control_deassert(pcie->rst);
> +	if (ret) {
> +		dev_err(dw->dev, "unable to bring out of softreset\n");
> +		return ret;
> +	}
> +
> +	/* let the controller initialize in the proper mode (RC) after reset */

Capitalize comments consistently.  Not sure what this comment is
telling us anyway.  RC mode is determined above.  I assume this delay
an STi-specific thing?  A reference to how this was derived might be a
useful thing, e.g., a section number in the STi spec.

> +	usleep_range(1000, 2000);
> +
> +	return ret;
> +}
> +
> +static int st_pcie_control_ltssm(struct dw_pcie *dw, bool enable)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +
> +	return regmap_update_bits(pcie->regmap, pcie->syscfg1, PCIE_APP_LTSSM_ENABLE,
> +				  FIELD_PREP(PCIE_APP_LTSSM_ENABLE, enable));
> +}
> +
> +static int st_pcie_host_init(struct pcie_port *pp)
> +{
> +	struct dw_pcie *dw = to_dw_pcie_from_pp(pp);
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int err;
> +
> +	pcie->config_window_start = pp->cfg0_base;
> +
> +	/*
> +	 * "Override" default ops provided by designware driver as STI
> +	 * PCIe uses its own translation unit rather than iATU
> +	 */

No need for the scare quotes around "override".  You are in fact
overriding the ops.

> +	pp->bridge->child_ops = &st_child_pcie_ops;
> +
> +	/*
> +	 * We have to initialise the PCIe cell on some hardware before we can
> +	 * talk to the phy
> +	 */
> +	err = st_pcie_init(pp);
> +	if (err)
> +		return err;
> +
> +	err = st_pcie_control_ltssm(dw, false);
> +	if (err) {
> +		dev_err(dw->dev, "disable ltssm failed, %d\n", err);

s/ltssm/LTSSM/

> +		return err;
> +	}
> +
> +	/* Init the associated miphy */
> +	err = phy_init(pcie->phy);
> +	if (err < 0) {
> +		dev_err(dw->dev, "Cannot init PHY: %d\n", err);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static int st_pcie_start_link(struct dw_pcie *dw)
> +{
> +	struct st_pcie *pcie = to_st_pcie(dw);
> +	int err;
> +
> +	/* Do all the register poking */

Pointless comment.

> +	st_pcie_hw_setup(dw);
> +
> +	if (pcie->reset_gpio) {
> +		/* Assert the PERST# signal */
> +		gpiod_set_value(pcie->reset_gpio, 1);
> +
> +		/* PERST# signal must stay asserted for at least 100us (Tperst-clk) */

Thanks for this reference to a specific delay from the spec!

> +		usleep_range(100, 200);
> +		/* Release PERST# signal */
> +		gpiod_set_value(pcie->reset_gpio, 0);
> +	}
> +
> +	/* Re-enable the link, link training must begin shortly after reset */
> +	err = st_pcie_control_ltssm(dw, true);
> +	if (err) {
> +		dev_err(dw->dev, "enable ltssm failed, %d\n", err);
> +		return err;
> +	}
> +
> +	err = dw_pcie_wait_for_link(dw);
> +	if (err) {
> +		dev_err(dw->dev, "wait for link failed, %d\n", err);
> +		return err;
> +	}
> +
> +	/*
> +	 * PCIe specification states that you should not issue any config
> +	 * requests until 100ms after asserting reset, so we enforce that here
> +	 */
> +	if  (pcie->reset_gpio)
> +		msleep(100);
> +
> +	return 0;
> +}
> +
> +static struct dw_pcie_host_ops st_pcie_host_ops = {
> +	.host_init = st_pcie_host_init,
> +};
> +
> +static const struct dw_pcie_ops dw_pcie_ops = {
> +	.start_link = st_pcie_start_link,
> +};
> +
> +static int st_pcie_probe(struct platform_device *pdev)
> +{
> +	struct st_pcie *pcie;
> +	struct dw_pcie *dw;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct pcie_port *pp;
> +	int ret;
> +
> +	pcie = devm_kzalloc(&pdev->dev, sizeof(*pcie), GFP_KERNEL);
> +	if (!pcie)
> +		return -ENOMEM;
> +
> +	dw = devm_kzalloc(&pdev->dev, sizeof(*dw), GFP_KERNEL);
> +	if (!dw)
> +		return -ENOMEM;
> +	pcie->dw = dw;
> +	dw->dev = &pdev->dev;
> +	dw->ops = &dw_pcie_ops;
> +
> +	pp = &dw->pp;
> +	pp->ops = &st_pcie_host_ops;
> +
> +	/* mem regions */
> +	pcie->lmi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem-window");
> +	if (!pcie->lmi)
> +		return -ENXIO;
> +
> +	/* regmap registers for PCIe IP configuration */
> +	pcie->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
> +	if (IS_ERR(pcie->regmap))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->regmap),
> +				     "No syscfg phandle specified\n");

Make your error messages all capitalized or all uncapitalized.  I
think uncapitalized is more typical in drivers/pci/

> +	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG0_REG, &pcie->syscfg0);
> +	if (ret) {
> +		dev_err(&pdev->dev, "can't get syscfg0 offset (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	ret = of_property_read_u32_index(np, "st,syscfg", SYSCFG1_REG, &pcie->syscfg1);
> +	if (ret) {
> +		dev_err(&pdev->dev, "can't get syscfg1 offset (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	/* powerdown / resets */
> +	pcie->pwr = devm_reset_control_get_optional(&pdev->dev, "powerdown");
> +	if (IS_ERR(pcie->pwr))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->pwr),
> +				     "Error getting powerdown reset control\n");
> +
> +	pcie->rst = devm_reset_control_get(&pdev->dev, "softreset");
> +	if (IS_ERR(pcie->rst))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->rst),
> +				     "Error getting softreset control\n");
> +
> +	/* phy */
> +	pcie->phy = devm_phy_get(&pdev->dev, "pcie");
> +	if (IS_ERR(pcie->phy))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->phy), "no PHY configured\n");
> +
> +	/* Claim the GPIO for PRST# if available, keep it de-asserted */
> +	pcie->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(pcie->reset_gpio))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(pcie->reset_gpio),
> +				     "Cannot request reset-gpios\n");
> +
> +	platform_set_drvdata(pdev, pcie);
> +
> +	ret = dw_pcie_host_init(pp);
> +	if (ret)
> +		return dev_err_probe(&pdev->dev, ret, "failed to initialize host\n");
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id st_pcie_of_match[] = {
> +	{ .compatible = "st,stih407-pcie", },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, st_pcie_of_match);
> +
> +static struct platform_driver st_pcie_driver __refdata = {
> +	.probe  = st_pcie_probe,
> +	.driver = {
> +		.name = "st-pcie",
> +		.of_match_table = st_pcie_of_match,
> +	},
> +};
> +module_platform_driver(st_pcie_driver);
> +
> +MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier at foss.st.com>");
> +MODULE_AUTHOR("Alain Volmat <avolmat at me.com>");
> +MODULE_DESCRIPTION("STi PCIe Controller driver");
> +MODULE_LICENSE("GPL v2");
> -- 
> 2.25.1
> 


From maz at kernel.org  Mon Jan 24 12:12:31 2022
From: maz at kernel.org (Marc Zyngier)
Date: Mon, 24 Jan 2022 20:12:31 +0000
Subject: [PATCH v4 10/10] drivers/perf: Add Apple icestorm/firestorm CPU PMU
 driver
In-Reply-To: <20220124201231.298961-1-maz@kernel.org>
References: <20220124201231.298961-1-maz@kernel.org>
Message-ID: <20220124201231.298961-11-maz@kernel.org>

Add a new, weird and wonderful driver for the equally weird Apple
PMU HW. Although the PMU itself is functional, we don't know much
about the events yet, so this can be considered as yet another
random number generator...

Nonetheless, it can reliably count at least cycles and instructions
in the usually wonky big-little way. For anything else, it of course
supports raw event numbers.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/apple_m1_pmu.h |  45 ++
 drivers/perf/Kconfig                  |   7 +
 drivers/perf/Makefile                 |   1 +
 drivers/perf/apple_m1_cpu_pmu.c       | 584 ++++++++++++++++++++++++++
 4 files changed, 637 insertions(+)
 create mode 100644 drivers/perf/apple_m1_cpu_pmu.c

diff --git a/arch/arm64/include/asm/apple_m1_pmu.h b/arch/arm64/include/asm/apple_m1_pmu.h
index b848af7faadc..99483b19b99f 100644
--- a/arch/arm64/include/asm/apple_m1_pmu.h
+++ b/arch/arm64/include/asm/apple_m1_pmu.h
@@ -6,8 +6,21 @@
 #include <linux/bits.h>
 #include <asm/sysreg.h>
 
+/* Counters */
+#define SYS_IMP_APL_PMC0_EL1	sys_reg(3, 2, 15, 0, 0)
+#define SYS_IMP_APL_PMC1_EL1	sys_reg(3, 2, 15, 1, 0)
+#define SYS_IMP_APL_PMC2_EL1	sys_reg(3, 2, 15, 2, 0)
+#define SYS_IMP_APL_PMC3_EL1	sys_reg(3, 2, 15, 3, 0)
+#define SYS_IMP_APL_PMC4_EL1	sys_reg(3, 2, 15, 4, 0)
+#define SYS_IMP_APL_PMC5_EL1	sys_reg(3, 2, 15, 5, 0)
+#define SYS_IMP_APL_PMC6_EL1	sys_reg(3, 2, 15, 6, 0)
+#define SYS_IMP_APL_PMC7_EL1	sys_reg(3, 2, 15, 7, 0)
+#define SYS_IMP_APL_PMC8_EL1	sys_reg(3, 2, 15, 9, 0)
+#define SYS_IMP_APL_PMC9_EL1	sys_reg(3, 2, 15, 10, 0)
+
 /* Core PMC control register */
 #define SYS_IMP_APL_PMCR0_EL1	sys_reg(3, 1, 15, 0, 0)
+#define PMCR0_CNT_ENABLE_0_7	GENMASK(7, 0)
 #define PMCR0_IMODE		GENMASK(10, 8)
 #define PMCR0_IMODE_OFF		0
 #define PMCR0_IMODE_PMI		1
@@ -15,5 +28,37 @@
 #define PMCR0_IMODE_HALT	3
 #define PMCR0_IMODE_FIQ		4
 #define PMCR0_IACT		BIT(11)
+#define PMCR0_PMI_ENABLE_0_7	GENMASK(19, 12)
+#define PMCR0_STOP_CNT_ON_PMI	BIT(20)
+#define PMCR0_CNT_GLOB_L2C_EVT	BIT(21)
+#define PMCR0_DEFER_PMI_TO_ERET	BIT(22)
+#define PMCR0_ALLOW_CNT_EN_EL0	BIT(30)
+#define PMCR0_CNT_ENABLE_8_9	GENMASK(33, 32)
+#define PMCR0_PMI_ENABLE_8_9	GENMASK(45, 44)
+
+#define SYS_IMP_APL_PMCR1_EL1	sys_reg(3, 1, 15, 1, 0)
+#define PMCR1_COUNT_A64_EL0_0_7	GENMASK(15, 8)
+#define PMCR1_COUNT_A64_EL1_0_7	GENMASK(23, 16)
+#define PMCR1_COUNT_A64_EL0_8_9	GENMASK(41, 40)
+#define PMCR1_COUNT_A64_EL1_8_9	GENMASK(49, 48)
+
+#define SYS_IMP_APL_PMCR2_EL1	sys_reg(3, 1, 15, 2, 0)
+#define SYS_IMP_APL_PMCR3_EL1	sys_reg(3, 1, 15, 3, 0)
+#define SYS_IMP_APL_PMCR4_EL1	sys_reg(3, 1, 15, 4, 0)
+
+#define SYS_IMP_APL_PMESR0_EL1	sys_reg(3, 1, 15, 5, 0)
+#define PMESR0_EVT_CNT_2	GENMASK(7, 0)
+#define PMESR0_EVT_CNT_3	GENMASK(15, 8)
+#define PMESR0_EVT_CNT_4	GENMASK(23, 16)
+#define PMESR0_EVT_CNT_5	GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMESR1_EL1	sys_reg(3, 1, 15, 6, 0)
+#define PMESR1_EVT_CNT_6	GENMASK(7, 0)
+#define PMESR1_EVT_CNT_7	GENMASK(15, 8)
+#define PMESR1_EVT_CNT_8	GENMASK(23, 16)
+#define PMESR1_EVT_CNT_9	GENMASK(31, 24)
+
+#define SYS_IMP_APL_PMSR_EL1	sys_reg(3, 1, 15, 13, 0)
+#define PMSR_OVERFLOW		GENMASK(9, 0)
 
 #endif /* __ASM_APPLE_M1_PMU_h */
diff --git a/drivers/perf/Kconfig b/drivers/perf/Kconfig
index e1a0c44bc686..d4fa0dabb05f 100644
--- a/drivers/perf/Kconfig
+++ b/drivers/perf/Kconfig
@@ -146,6 +146,13 @@ config MARVELL_CN10K_TAD_PMU
 	  Provides support for Last-Level cache Tag-and-data Units (LLC-TAD)
 	  performance monitors on CN10K family silicons.
 
+config APPLE_M1_CPU_PMU
+	bool "Apple M1 CPU PMU support"
+	depends on ARM_PMU && ARCH_APPLE
+	help
+	  Provides support for the non-architectural CPU PMUs present on
+	  the Apple M1 SoCs and derivatives.
+
 source "drivers/perf/hisilicon/Kconfig"
 
 endmenu
diff --git a/drivers/perf/Makefile b/drivers/perf/Makefile
index 2db5418d5b0a..21ad0832e3d4 100644
--- a/drivers/perf/Makefile
+++ b/drivers/perf/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_XGENE_PMU) += xgene_pmu.o
 obj-$(CONFIG_ARM_SPE_PMU) += arm_spe_pmu.o
 obj-$(CONFIG_ARM_DMC620_PMU) += arm_dmc620_pmu.o
 obj-$(CONFIG_MARVELL_CN10K_TAD_PMU) += marvell_cn10k_tad_pmu.o
+obj-$(CONFIG_APPLE_M1_CPU_PMU) += apple_m1_cpu_pmu.o
diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
new file mode 100644
index 000000000000..979a7c2b4f56
--- /dev/null
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -0,0 +1,584 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * CPU PMU driver for the Apple M1 and derivatives
+ *
+ * Copyright (C) 2021 Google LLC
+ *
+ * Author: Marc Zyngier <maz at kernel.org>
+ *
+ * Most of the information used in this driver was provided by the
+ * Asahi Linux project. The rest was experimentally discovered.
+ */
+
+#include <linux/of.h>
+#include <linux/perf/arm_pmu.h>
+#include <linux/platform_device.h>
+
+#include <asm/apple_m1_pmu.h>
+#include <asm/irq_regs.h>
+#include <asm/perf_event.h>
+
+#define M1_PMU_NR_COUNTERS		10
+
+#define M1_PMU_CFG_EVENT		GENMASK(7, 0)
+
+#define ANY_BUT_0_1			GENMASK(9, 2)
+#define ONLY_2_TO_7			GENMASK(7, 2)
+#define ONLY_2_4_6			(BIT(2) | BIT(4) | BIT(6))
+#define ONLY_5_6_7			(BIT(5) | BIT(6) | BIT(7))
+
+/*
+ * Description of the events we actually know about, as well as those with
+ * a specific counter affinity. Yes, this is a grand total of two known
+ * counters, and the rest is anybody's guess.
+ *
+ * Not all counters can count all events. Counters #0 and #1 are wired to
+ * count cycles and instructions respectively, and some events have
+ * bizarre mappings (every other counter, or even *one* counter). These
+ * restrictions equally apply to both P and E cores.
+ *
+ * It is worth noting that the PMUs attached to P and E cores are likely
+ * to be different because the underlying uarches are different. At the
+ * moment, we don't really need to distinguish between the two because we
+ * know next to nothing about the events themselves, and we already have
+ * per cpu-type PMU abstractions.
+ *
+ * If we eventually find out that the events are different across
+ * implementations, we'll have to introduce per cpu-type tables.
+ */
+enum m1_pmu_events {
+	M1_PMU_PERFCTR_UNKNOWN_01	= 0x01,
+	M1_PMU_PERFCTR_CPU_CYCLES	= 0x02,
+	M1_PMU_PERFCTR_INSTRUCTIONS	= 0x8c,
+	M1_PMU_PERFCTR_UNKNOWN_8d	= 0x8d,
+	M1_PMU_PERFCTR_UNKNOWN_8e	= 0x8e,
+	M1_PMU_PERFCTR_UNKNOWN_8f	= 0x8f,
+	M1_PMU_PERFCTR_UNKNOWN_90	= 0x90,
+	M1_PMU_PERFCTR_UNKNOWN_93	= 0x93,
+	M1_PMU_PERFCTR_UNKNOWN_94	= 0x94,
+	M1_PMU_PERFCTR_UNKNOWN_95	= 0x95,
+	M1_PMU_PERFCTR_UNKNOWN_96	= 0x96,
+	M1_PMU_PERFCTR_UNKNOWN_97	= 0x97,
+	M1_PMU_PERFCTR_UNKNOWN_98	= 0x98,
+	M1_PMU_PERFCTR_UNKNOWN_99	= 0x99,
+	M1_PMU_PERFCTR_UNKNOWN_9a	= 0x9a,
+	M1_PMU_PERFCTR_UNKNOWN_9b	= 0x9b,
+	M1_PMU_PERFCTR_UNKNOWN_9c	= 0x9c,
+	M1_PMU_PERFCTR_UNKNOWN_9f	= 0x9f,
+	M1_PMU_PERFCTR_UNKNOWN_bf	= 0xbf,
+	M1_PMU_PERFCTR_UNKNOWN_c0	= 0xc0,
+	M1_PMU_PERFCTR_UNKNOWN_c1	= 0xc1,
+	M1_PMU_PERFCTR_UNKNOWN_c4	= 0xc4,
+	M1_PMU_PERFCTR_UNKNOWN_c5	= 0xc5,
+	M1_PMU_PERFCTR_UNKNOWN_c6	= 0xc6,
+	M1_PMU_PERFCTR_UNKNOWN_c8	= 0xc8,
+	M1_PMU_PERFCTR_UNKNOWN_ca	= 0xca,
+	M1_PMU_PERFCTR_UNKNOWN_cb	= 0xcb,
+	M1_PMU_PERFCTR_UNKNOWN_f5	= 0xf5,
+	M1_PMU_PERFCTR_UNKNOWN_f6	= 0xf6,
+	M1_PMU_PERFCTR_UNKNOWN_f7	= 0xf7,
+	M1_PMU_PERFCTR_UNKNOWN_f8	= 0xf8,
+	M1_PMU_PERFCTR_UNKNOWN_fd	= 0xfd,
+	M1_PMU_PERFCTR_LAST		= M1_PMU_CFG_EVENT,
+
+	/*
+	 * From this point onwards, these are not actual HW events,
+	 * but attributes that get stored in hw->config_base.
+	 */
+	M1_PMU_CFG_COUNT_USER		= BIT(8),
+	M1_PMU_CFG_COUNT_KERNEL		= BIT(9),
+};
+
+/*
+ * Per-event affinity table. Most events can be installed on counter
+ * 2-9, but there are a number of exceptions. Note that this table
+ * has been created experimentally, and I wouldn't be surprised if more
+ * counters had strange affinities.
+ */
+static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = {
+	[0 ... M1_PMU_PERFCTR_LAST]	= ANY_BUT_0_1,
+	[M1_PMU_PERFCTR_UNKNOWN_01]	= BIT(7),
+	[M1_PMU_PERFCTR_CPU_CYCLES]	= ANY_BUT_0_1 | BIT(0),
+	[M1_PMU_PERFCTR_INSTRUCTIONS]	= BIT(7) | BIT(1),
+	[M1_PMU_PERFCTR_UNKNOWN_8d]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_8e]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_8f]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_90]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_93]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_94]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_95]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_96]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_97]	= BIT(7),
+	[M1_PMU_PERFCTR_UNKNOWN_98]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_99]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_9a]	= BIT(7),
+	[M1_PMU_PERFCTR_UNKNOWN_9b]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_9c]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_9f]	= BIT(7),
+	[M1_PMU_PERFCTR_UNKNOWN_bf]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c0]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c1]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c4]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c5]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c6]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_c8]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_ca]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_cb]	= ONLY_5_6_7,
+	[M1_PMU_PERFCTR_UNKNOWN_f5]	= ONLY_2_4_6,
+	[M1_PMU_PERFCTR_UNKNOWN_f6]	= ONLY_2_4_6,
+	[M1_PMU_PERFCTR_UNKNOWN_f7]	= ONLY_2_4_6,
+	[M1_PMU_PERFCTR_UNKNOWN_f8]	= ONLY_2_TO_7,
+	[M1_PMU_PERFCTR_UNKNOWN_fd]	= ONLY_2_4_6,
+};
+
+static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
+	PERF_MAP_ALL_UNSUPPORTED,
+	[PERF_COUNT_HW_CPU_CYCLES]	= M1_PMU_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	= M1_PMU_PERFCTR_INSTRUCTIONS,
+	/* No idea about the rest yet */
+};
+
+/* sysfs definitions */
+static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
+					struct device_attribute *attr,
+					char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr;
+
+	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+
+	return sprintf(page, "event=0x%04llx\n", pmu_attr->id);
+}
+
+#define M1_PMU_EVENT_ATTR(name, config)					\
+	PMU_EVENT_ATTR_ID(name, m1_pmu_events_sysfs_show, config)
+
+static struct attribute *m1_pmu_event_attrs[] = {
+	M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CPU_CYCLES),
+	M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INSTRUCTIONS),
+	NULL,
+};
+
+static const struct attribute_group m1_pmu_events_attr_group = {
+	.name = "events",
+	.attrs = m1_pmu_event_attrs,
+};
+
+PMU_FORMAT_ATTR(event, "config:0-7");
+
+static struct attribute *m1_pmu_format_attrs[] = {
+	&format_attr_event.attr,
+	NULL,
+};
+
+static const struct attribute_group m1_pmu_format_attr_group = {
+	.name = "format",
+	.attrs = m1_pmu_format_attrs,
+};
+
+/* Low level accessors. No synchronisation. */
+#define PMU_READ_COUNTER(_idx)						\
+	case _idx:	return read_sysreg_s(SYS_IMP_APL_PMC## _idx ##_EL1)
+
+#define PMU_WRITE_COUNTER(_val, _idx)					\
+	case _idx:							\
+		write_sysreg_s(_val, SYS_IMP_APL_PMC## _idx ##_EL1);	\
+		return
+
+static u64 m1_pmu_read_hw_counter(unsigned int index)
+{
+	switch (index) {
+		PMU_READ_COUNTER(0);
+		PMU_READ_COUNTER(1);
+		PMU_READ_COUNTER(2);
+		PMU_READ_COUNTER(3);
+		PMU_READ_COUNTER(4);
+		PMU_READ_COUNTER(5);
+		PMU_READ_COUNTER(6);
+		PMU_READ_COUNTER(7);
+		PMU_READ_COUNTER(8);
+		PMU_READ_COUNTER(9);
+	}
+
+	BUG();
+}
+
+static void m1_pmu_write_hw_counter(u64 val, unsigned int index)
+{
+	switch (index) {
+		PMU_WRITE_COUNTER(val, 0);
+		PMU_WRITE_COUNTER(val, 1);
+		PMU_WRITE_COUNTER(val, 2);
+		PMU_WRITE_COUNTER(val, 3);
+		PMU_WRITE_COUNTER(val, 4);
+		PMU_WRITE_COUNTER(val, 5);
+		PMU_WRITE_COUNTER(val, 6);
+		PMU_WRITE_COUNTER(val, 7);
+		PMU_WRITE_COUNTER(val, 8);
+		PMU_WRITE_COUNTER(val, 9);
+	}
+
+	BUG();
+}
+
+#define get_bit_offset(index, mask)	(__ffs(mask) + (index))
+
+static void __m1_pmu_enable_counter(unsigned int index, bool en)
+{
+	u64 val, bit;
+
+	switch (index) {
+	case 0 ... 7:
+		bit = BIT(get_bit_offset(index, PMCR0_CNT_ENABLE_0_7));
+		break;
+	case 8 ... 9:
+		bit = BIT(get_bit_offset(index - 8, PMCR0_CNT_ENABLE_8_9));
+		break;
+	default:
+		BUG();
+	}
+
+	val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+
+	if (en)
+		val |= bit;
+	else
+		val &= ~bit;
+
+	write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+}
+
+static void m1_pmu_enable_counter(unsigned int index)
+{
+	__m1_pmu_enable_counter(index, true);
+}
+
+static void m1_pmu_disable_counter(unsigned int index)
+{
+	__m1_pmu_enable_counter(index, false);
+}
+
+static void __m1_pmu_enable_counter_interrupt(unsigned int index, bool en)
+{
+	u64 val, bit;
+
+	switch (index) {
+	case 0 ... 7:
+		bit = BIT(get_bit_offset(index, PMCR0_PMI_ENABLE_0_7));
+		break;
+	case 8 ... 9:
+		bit = BIT(get_bit_offset(index - 8, PMCR0_PMI_ENABLE_8_9));
+		break;
+	default:
+		BUG();
+	}
+
+	val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+
+	if (en)
+		val |= bit;
+	else
+		val &= ~bit;
+
+	write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+}
+
+static void m1_pmu_enable_counter_interrupt(unsigned int index)
+{
+	__m1_pmu_enable_counter_interrupt(index, true);
+}
+
+static void m1_pmu_disable_counter_interrupt(unsigned int index)
+{
+	__m1_pmu_enable_counter_interrupt(index, false);
+}
+
+static void m1_pmu_configure_counter(unsigned int index, u8 event,
+				     bool user, bool kernel)
+{
+	u64 val, user_bit, kernel_bit;
+	int shift;
+
+	switch (index) {
+	case 0 ... 7:
+		user_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL0_0_7));
+		kernel_bit = BIT(get_bit_offset(index, PMCR1_COUNT_A64_EL1_0_7));
+		break;
+	case 8 ... 9:
+		user_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL0_8_9));
+		kernel_bit = BIT(get_bit_offset(index - 8, PMCR1_COUNT_A64_EL1_8_9));
+		break;
+	default:
+		BUG();
+	}
+
+	val = read_sysreg_s(SYS_IMP_APL_PMCR1_EL1);
+
+	if (user)
+		val |= user_bit;
+	else
+		val &= ~user_bit;
+
+	if (kernel)
+		val |= kernel_bit;
+	else
+		val &= ~kernel_bit;
+
+	write_sysreg_s(val, SYS_IMP_APL_PMCR1_EL1);
+
+	/*
+	 * Counters 0 and 1 have fixed events. For anything else,
+	 * place the event at the expected location in the relevant
+	 * register (PMESR0 holds the event configuration for counters
+	 * 2-5, resp. PMESR1 for counters 6-9).
+	 */
+	switch (index) {
+	case 0 ... 1:
+		break;
+	case 2 ... 5:
+		shift = (index - 2) * 8;
+		val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
+		val &= ~((u64)0xff << shift);
+		val |= (u64)event << shift;
+		write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
+		break;
+	case 6 ... 9:
+		shift = (index - 6) * 8;
+		val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
+		val &= ~((u64)0xff << shift);
+		val |= (u64)event << shift;
+		write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
+		break;
+	}
+}
+
+/* arm_pmu backend */
+static void m1_pmu_enable_event(struct perf_event *event)
+{
+	bool user, kernel;
+	u8 evt;
+
+	evt = event->hw.config_base & M1_PMU_CFG_EVENT;
+	user = event->hw.config_base & M1_PMU_CFG_COUNT_USER;
+	kernel = event->hw.config_base & M1_PMU_CFG_COUNT_KERNEL;
+
+	m1_pmu_disable_counter_interrupt(event->hw.idx);
+	m1_pmu_disable_counter(event->hw.idx);
+	isb();
+
+	m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
+	m1_pmu_enable_counter(event->hw.idx);
+	m1_pmu_enable_counter_interrupt(event->hw.idx);
+	isb();
+}
+
+static void m1_pmu_disable_event(struct perf_event *event)
+{
+	m1_pmu_disable_counter_interrupt(event->hw.idx);
+	m1_pmu_disable_counter(event->hw.idx);
+	isb();
+}
+
+static irqreturn_t m1_pmu_handle_irq(struct arm_pmu *cpu_pmu)
+{
+	struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events);
+	struct pt_regs *regs;
+	u64 overflow, state;
+	int idx;
+
+	overflow = read_sysreg_s(SYS_IMP_APL_PMSR_EL1);
+	if (!overflow) {
+		/* Spurious interrupt? */
+		state = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+		state &= ~PMCR0_IACT;
+		write_sysreg_s(state, SYS_IMP_APL_PMCR0_EL1);
+		isb();
+		return IRQ_NONE;
+	}
+
+	cpu_pmu->stop(cpu_pmu);
+
+	regs = get_irq_regs();
+
+	for (idx = 0; idx < cpu_pmu->num_events; idx++) {
+		struct perf_event *event = cpuc->events[idx];
+		struct perf_sample_data data;
+
+		if (!event)
+			continue;
+
+		armpmu_event_update(event);
+		perf_sample_data_init(&data, 0, event->hw.last_period);
+		if (!armpmu_event_set_period(event))
+			continue;
+
+		if (perf_event_overflow(event, &data, regs))
+			m1_pmu_disable_event(event);
+	}
+
+	cpu_pmu->start(cpu_pmu);
+
+	return IRQ_HANDLED;
+}
+
+static u64 m1_pmu_read_counter(struct perf_event *event)
+{
+	return m1_pmu_read_hw_counter(event->hw.idx);
+}
+
+static void m1_pmu_write_counter(struct perf_event *event, u64 value)
+{
+	m1_pmu_write_hw_counter(value, event->hw.idx);
+	isb();
+}
+
+static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				struct perf_event *event)
+{
+	unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
+	unsigned long affinity = m1_pmu_event_affinity[evtype];
+	int idx;
+
+	/*
+	 * Place the event on the first free counter that can count
+	 * this event.
+	 *
+	 * We could do a better job if we had a view of all the events
+	 * counting on the PMU at any given time, and by placing the
+	 * most constraining events first.
+	 */
+	for_each_set_bit(idx, &affinity, M1_PMU_NR_COUNTERS) {
+		if (!test_and_set_bit(idx, cpuc->used_mask))
+			return idx;
+	}
+
+	return -EAGAIN;
+}
+
+static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+				   struct perf_event *event)
+{
+	clear_bit(event->hw.idx, cpuc->used_mask);
+}
+
+static void __m1_pmu_set_mode(u8 mode)
+{
+	u64 val;
+
+	val = read_sysreg_s(SYS_IMP_APL_PMCR0_EL1);
+	val &= ~(PMCR0_IMODE | PMCR0_IACT);
+	val |= FIELD_PREP(PMCR0_IMODE, mode);
+	write_sysreg_s(val, SYS_IMP_APL_PMCR0_EL1);
+	isb();
+}
+
+static void m1_pmu_start(struct arm_pmu *cpu_pmu)
+{
+	__m1_pmu_set_mode(PMCR0_IMODE_FIQ);
+}
+
+static void m1_pmu_stop(struct arm_pmu *cpu_pmu)
+{
+	__m1_pmu_set_mode(PMCR0_IMODE_OFF);
+}
+
+static int m1_pmu_map_event(struct perf_event *event)
+{
+	/*
+	 * Although the counters are 48bit wide, bit 47 is what
+	 * triggers the overflow interrupt. Advertise the counters
+	 * being 47bit wide to mimick the behaviour of the ARM PMU.
+	 */
+	event->hw.flags |= ARMPMU_EVT_47BIT;
+	return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+}
+
+static void m1_pmu_reset(void *info)
+{
+	int i;
+
+	__m1_pmu_set_mode(PMCR0_IMODE_OFF);
+
+	for (i = 0; i < M1_PMU_NR_COUNTERS; i++) {
+		m1_pmu_disable_counter(i);
+		m1_pmu_disable_counter_interrupt(i);
+		m1_pmu_write_hw_counter(0, i);
+	}
+
+	isb();
+}
+
+static int m1_pmu_set_event_filter(struct hw_perf_event *event,
+				   struct perf_event_attr *attr)
+{
+	unsigned long config_base = 0;
+
+	if (!attr->exclude_guest)
+		return -EINVAL;
+	if (!attr->exclude_kernel)
+		config_base |= M1_PMU_CFG_COUNT_KERNEL;
+	if (!attr->exclude_user)
+		config_base |= M1_PMU_CFG_COUNT_USER;
+
+	event->config_base = config_base;
+
+	return 0;
+}
+
+static int m1_pmu_init(struct arm_pmu *cpu_pmu)
+{
+	cpu_pmu->handle_irq	  = m1_pmu_handle_irq;
+	cpu_pmu->enable		  = m1_pmu_enable_event;
+	cpu_pmu->disable	  = m1_pmu_disable_event;
+	cpu_pmu->read_counter	  = m1_pmu_read_counter;
+	cpu_pmu->write_counter	  = m1_pmu_write_counter;
+	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
+	cpu_pmu->clear_event_idx  = m1_pmu_clear_event_idx;
+	cpu_pmu->start		  = m1_pmu_start;
+	cpu_pmu->stop		  = m1_pmu_stop;
+	cpu_pmu->map_event	  = m1_pmu_map_event;
+	cpu_pmu->reset		  = m1_pmu_reset;
+	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
+
+	cpu_pmu->num_events	  = M1_PMU_NR_COUNTERS;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
+	return 0;
+}
+
+/* Device driver gunk */
+static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
+{
+	cpu_pmu->name = "apple_icestorm_pmu";
+	return m1_pmu_init(cpu_pmu);
+}
+
+static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
+{
+	cpu_pmu->name = "apple_firestorm_pmu";
+	return m1_pmu_init(cpu_pmu);
+}
+
+static const struct of_device_id m1_pmu_of_device_ids[] = {
+	{ .compatible = "apple,icestorm-pmu",	.data = m1_pmu_ice_init, },
+	{ .compatible = "apple,firestorm-pmu",	.data = m1_pmu_fire_init, },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, m1_pmu_of_device_ids);
+
+static int m1_pmu_device_probe(struct platform_device *pdev)
+{
+	return arm_pmu_device_probe(pdev, m1_pmu_of_device_ids, NULL);
+}
+
+static struct platform_driver m1_pmu_driver = {
+	.driver		= {
+		.name			= "apple-m1-cpu-pmu",
+		.of_match_table		= m1_pmu_of_device_ids,
+		.suppress_bind_attrs	= true,
+	},
+	.probe		= m1_pmu_device_probe,
+};
+
+module_platform_driver(m1_pmu_driver);
+MODULE_LICENSE("GPL v2");
-- 
2.30.2



From gregkh at linuxfoundation.org  Mon Jan 24 10:39:04 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:39:04 +0100
Subject: [PATCH 5.15 427/846] of: fdt: Aggregate the processing of "linux,
 usable-memory-range"
In-Reply-To: <20220124184100.867127425@linuxfoundation.org>
References: <20220124184100.867127425@linuxfoundation.org>
Message-ID: <20220124184115.705813438@linuxfoundation.org>

From: Zhen Lei <thunder.leizhen at huawei.com>

[ Upstream commit 8347b41748c3019157312fbe7f8a6792ae396eb7 ]

Currently, we parse the "linux,usable-memory-range" property in
early_init_dt_scan_chosen(), to obtain the specified memory range of the
crash kernel. We then reserve the required memory after
early_init_dt_scan_memory() has identified all available physical memory.
Because the two pieces of code are separated far, the readability and
maintainability are reduced. So bring them together.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
(change the prototype of early_init_dt_check_for_usable_mem_range(), in
order to use it outside)
Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>
Acked-by: John Donnelly <john.p.donnelly at oracle.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
To: devicetree at vger.kernel.org
To: linux-efi at vger.kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/of/fdt.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 4546572af24bb..105b1a47905ab 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -969,18 +969,22 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
 		 elfcorehdr_addr, elfcorehdr_size);
 }
 
-static phys_addr_t cap_mem_addr;
-static phys_addr_t cap_mem_size;
+static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
 
 /**
  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
  * location from flat tree
- * @node: reference to node containing usable memory range location ('chosen')
  */
-static void __init early_init_dt_check_for_usable_mem_range(unsigned long node)
+static void __init early_init_dt_check_for_usable_mem_range(void)
 {
 	const __be32 *prop;
 	int len;
+	phys_addr_t cap_mem_addr;
+	phys_addr_t cap_mem_size;
+	unsigned long node = chosen_node_offset;
+
+	if ((long)node < 0)
+		return;
 
 	pr_debug("Looking for usable-memory-range property... ");
 
@@ -993,6 +997,8 @@ static void __init early_init_dt_check_for_usable_mem_range(unsigned long node)
 
 	pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
 		 &cap_mem_size);
+
+	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
 }
 
 #ifdef CONFIG_SERIAL_EARLYCON
@@ -1141,9 +1147,10 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
 		return 0;
 
+	chosen_node_offset = node;
+
 	early_init_dt_check_for_initrd(node);
 	early_init_dt_check_for_elfcorehdr(node);
-	early_init_dt_check_for_usable_mem_range(node);
 
 	/* Retrieve command line */
 	p = of_get_flat_dt_prop(node, "bootargs", &l);
@@ -1279,7 +1286,7 @@ void __init early_init_dt_scan_nodes(void)
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 
 	/* Handle linux,usable-memory-range property */
-	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
+	early_init_dt_check_for_usable_mem_range();
 }
 
 bool __init early_init_dt_scan(void *params)
-- 
2.34.1





From gregkh at linuxfoundation.org  Mon Jan 24 10:39:05 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:39:05 +0100
Subject: [PATCH 5.15 428/846] efi: apply memblock cap after memblock_add()
In-Reply-To: <20220124184100.867127425@linuxfoundation.org>
References: <20220124184100.867127425@linuxfoundation.org>
Message-ID: <20220124184115.739459776@linuxfoundation.org>

From: Pingfan Liu <kernelfans at gmail.com>

[ Upstream commit b398123bff3bcbc1facb0f29bf6e7b9f1bc55931 ]

On arm64, during kdump kernel saves vmcore, it runs into the following bug:
...
[   15.148919] usercopy: Kernel memory exposure attempt detected from SLUB object 'kmem_cache_node' (offset 0, size 4096)!
[   15.159707] ------------[ cut here ]------------
[   15.164311] kernel BUG at mm/usercopy.c:99!
[   15.168482] Internal error: Oops - BUG: 0 [#1] SMP
[   15.173261] Modules linked in: xfs libcrc32c crct10dif_ce ghash_ce sha2_ce sha256_arm64 sha1_ce sbsa_gwdt ast i2c_algo_bit drm_vram_helper drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm_ttm_helper ttm drm nvme nvme_core xgene_hwmon i2c_designware_platform i2c_designware_core dm_mirror dm_region_hash dm_log dm_mod overlay squashfs zstd_decompress loop
[   15.206186] CPU: 0 PID: 542 Comm: cp Not tainted 5.16.0-rc4 #1
[   15.212006] Hardware name: GIGABYTE R272-P30-JG/MP32-AR0-JG, BIOS F12 (SCP: 1.5.20210426) 05/13/2021
[   15.221125] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   15.228073] pc : usercopy_abort+0x9c/0xa0
[   15.232074] lr : usercopy_abort+0x9c/0xa0
[   15.236070] sp : ffff8000121abba0
[   15.239371] x29: ffff8000121abbb0 x28: 0000000000003000 x27: 0000000000000000
[   15.246494] x26: 0000000080000400 x25: 0000ffff885c7000 x24: 0000000000000000
[   15.253617] x23: 000007ff80400000 x22: ffff07ff80401000 x21: 0000000000000001
[   15.260739] x20: 0000000000001000 x19: ffff07ff80400000 x18: ffffffffffffffff
[   15.267861] x17: 656a626f2042554c x16: 53206d6f72662064 x15: 6574636574656420
[   15.274983] x14: 74706d6574746120 x13: 2129363930342065 x12: 7a6973202c302074
[   15.282105] x11: ffffc8b041d1b148 x10: 00000000ffff8000 x9 : ffffc8b04012812c
[   15.289228] x8 : 00000000ffff7fff x7 : ffffc8b041d1b148 x6 : 0000000000000000
[   15.296349] x5 : 0000000000000000 x4 : 0000000000007fff x3 : 0000000000000000
[   15.303471] x2 : 0000000000000000 x1 : ffff07ff8c064800 x0 : 000000000000006b
[   15.310593] Call trace:
[   15.313027]  usercopy_abort+0x9c/0xa0
[   15.316677]  __check_heap_object+0xd4/0xf0
[   15.320762]  __check_object_size.part.0+0x160/0x1e0
[   15.325628]  __check_object_size+0x2c/0x40
[   15.329711]  copy_oldmem_page+0x7c/0x140
[   15.333623]  read_from_oldmem.part.0+0xfc/0x1c0
[   15.338142]  __read_vmcore.constprop.0+0x23c/0x350
[   15.342920]  read_vmcore+0x28/0x34
[   15.346309]  proc_reg_read+0xb4/0xf0
[   15.349871]  vfs_read+0xb8/0x1f0
[   15.353088]  ksys_read+0x74/0x100
[   15.356390]  __arm64_sys_read+0x28/0x34
...

This bug introduced by commit b261dba2fdb2 ("arm64: kdump: Remove custom
linux,usable-memory-range handling"), which moves
memblock_cap_memory_range() to fdt, but it breaches the rules that
memblock_cap_memory_range() should come after memblock_add() etc as said
in commit e888fa7bb882 ("memblock: Check memory add/cap ordering").

As a consequence, the virtual address set up by copy_oldmem_page() does
not bail out from the test of virt_addr_valid() in check_heap_object(),
and finally hits the BUG_ON().

Since memblock allocator has no idea about when the memblock is fully
populated, while efi_init() is aware, so tackling this issue by calling the
interface early_init_dt_check_for_usable_mem_range() exposed by of/fdt.

Fixes: b261dba2fdb2 ("arm64: kdump: Remove custom linux,usable-memory-range handling")
Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Zhen Lei <thunder.leizhen at huawei.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Mike Rapoport <rppt at kernel.org>
Cc: Geert Uytterhoeven <geert+renesas at glider.be>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Nick Terrell <terrelln at fb.com>
Cc: linux-arm-kernel at lists.infradead.org
To: devicetree at vger.kernel.org
To: linux-efi at vger.kernel.org
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/r/20211215021348.8766-1-kernelfans at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/firmware/efi/efi-init.c | 5 +++++
 drivers/of/fdt.c                | 2 +-
 include/linux/of_fdt.h          | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index b19ce1a83f91a..b2c829e95bd14 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -235,6 +235,11 @@ void __init efi_init(void)
 	}
 
 	reserve_regions();
+	/*
+	 * For memblock manipulation, the cap should come after the memblock_add().
+	 * And now, memblock is fully populated, it is time to do capping.
+	 */
+	early_init_dt_check_for_usable_mem_range();
 	efi_esrt_init();
 	efi_mokvar_table_init();
 
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 105b1a47905ab..32e5e782d43da 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -975,7 +975,7 @@ static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
  * location from flat tree
  */
-static void __init early_init_dt_check_for_usable_mem_range(void)
+void __init early_init_dt_check_for_usable_mem_range(void)
 {
 	const __be32 *prop;
 	int len;
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index cf6a65b94d40e..6508b97dbf1d2 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -62,6 +62,7 @@ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 				     int depth, void *data);
 extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
 				     int depth, void *data);
+extern void early_init_dt_check_for_usable_mem_range(void);
 extern int early_init_dt_scan_chosen_stdout(void);
 extern void early_init_fdt_scan_reserved_mem(void);
 extern void early_init_fdt_reserve_self(void);
@@ -87,6 +88,7 @@ extern void unflatten_and_copy_device_tree(void);
 extern void early_init_devtree(void *);
 extern void early_get_first_memblock_info(void *, phys_addr_t *);
 #else /* CONFIG_OF_EARLY_FLATTREE */
+static inline void early_init_dt_check_for_usable_mem_range(void) {}
 static inline int early_init_dt_scan_chosen_stdout(void) { return -ENODEV; }
 static inline void early_init_fdt_scan_reserved_mem(void) {}
 static inline void early_init_fdt_reserve_self(void) {}
-- 
2.34.1





From p.yadav at ti.com  Mon Jan 24 12:37:08 2022
From: p.yadav at ti.com (Pratyush Yadav)
Date: Tue, 25 Jan 2022 02:07:08 +0530
Subject: [PATCH] mtd: aspeed-smc: improve probe resilience
In-Reply-To: <b222361a-288a-55b2-fc02-04c0b93b4220@kaod.org>
References: <20211229143334.297305-1-patrick@stwcx.xyz>
 <20211229173411.l2bipmi4x3arqjoo@ti.com>
 <Yc3Qav+ULNdF5zRT@heinlein>
 <20211231102623.izaqlzjvracbbgmp@ti.com>
 <20220103171721.46c8e697@xps13> <YdSP6tKyQ2ZRUC+2@heinlein>
 <20220105063244.lno3xur64uepa7i5@ti.com>
 <d4ba6413-57ce-14c1-ed48-d00db2f74bd3@kaod.org>
 <20220124153644.m3iwlvq5ld5cpbyz@ti.com>
 <b222361a-288a-55b2-fc02-04c0b93b4220@kaod.org>
Message-ID: <20220124203708.lm23sgsub234wlhq@ti.com>

On 24/01/22 07:34PM, C?dric Le Goater wrote:
> > > spimem needs an extension I think. Sorry I have not been able to
> > > push that forward. Lack of time and other tasks to address on the
> > > host side of the machine. This is really a software problem, we
> > > have the HW procedures ready. If a spimem expert could get involved
> > > to make a few proposals, I would be happy to help and do some testing.
> > > QEMU models are good enough for the software part. We can do the
> > > training validation on real HW when ready.
> > 
> > What information about the flash do you need for this training?
> 
> Last time I looked, we lacked some post_init handler to setup a slave:
> configure the registers defining the AHB windows for each flash
> slave and perform the read timing calibration. calibration should
> only be done once.
> 
> See how the aspeed_spi_flash_init() routine doing the calibration
> is hooked up under aspeed_spi_claim_bus() in the u-boot driver :

My patch series should provide a hook for doing the calibration _after_ 
the flash is initialized.

> 
>   https://github.com/openbmc/u-boot/blob/v2019.04-aspeed-openbmc/drivers/spi/aspeed_spi.c
> 
> Not good enough for upstream, Linux would be the same :/
> 
> > I proposed a patch series [0] some time ago trying to implement training
> > for TI SoCs. It did not get merged but I do intend to respin it and get
> > it through. Would this API work for your tuning as well?
> 
> I will take a look.
> > Also, I am curious how your training works. What data do you read for
> > training delays? Where is it stored?
> 
> The driver reads the first 16K at slow speed (that's why we need a
> basic minimal setup of the slave) and checks if the buffer is valid
> enough for the calibration :
> 
>   https://github.com/openbmc/linux/blob/dev-5.15/drivers/mtd/spi-nor/controllers/aspeed-smc.c#L998
> 
> it then performs reads by changing the frequency and delays and
> compares results with the initial default buffer.

This seems similar to the tuning I implemented, except mine uses a 
pre-defined pattern at a pre-defined location.

> 
> if not, then the driver stays in a safe mode (slow).

Same for my patches.

> 
> > In our case we need to flash a
> > known pattern at some location (which is passed in via DT). Do you need
> > to run it for every read transaction or just once after the flash is
> > initialized?
> 
> Just once because it is a heavy process. See the debug outputs below.
> Once we have good read timings and frequency, there is no need to do
> it each time.

It looks very similar to the tuning I implemented in my patch series. 
You should be able to use those APIs for your tuning as well. But it 
should not block the SPI MEM port. The current upstream driver does not 
seem to implement this tuning anyway.

> 
> > [0] https://patchwork.ozlabs.org/project/linux-mtd/list/?series=233504&state=%2A&archive=both
> Thanks,
> 
> C.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.


From helgaas at kernel.org  Mon Jan 24 12:42:52 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Mon, 24 Jan 2022 14:42:52 -0600
Subject: [PATCH v5 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <f69d32f08a890463a331567e5742f2d33fa8b2bb.1643041464.git.baruch@tkos.co.il>
Message-ID: <20220124204252.GA1552314@bhelgaas>

Capitalize subject line to match history, i.e.,

  $ git log --oneline drivers/pci/controller/dwc/pcie-qcom.c
  3f13d611aa6b PCI: qcom: Use __be16 type to store return value from cpu_to_be16()
  4e0e90539bb0 PCI: qcom: Fix an error handling path in 'qcom_pcie_probe()'
  45a3ec891370 PCI: qcom: Add sc8180x compatible
  aa9c0df98c29 PCI: qcom: Switch pcie_1_pipe_clk_src after PHY init in SC7280
  b89ff410253d PCI: qcom: Replace ops with struct pcie_cfg in pcie match data
  2cfef1971aea PCI: qcom: Use PHY_REFCLK_USE_PAD only for ipq8064
  7081556f81f7 PCI: qcom: Add support for ddrss_sf_tbu clock
  4c9398822106 PCI: qcom: Add support for configuring BDF to SID mapping for SM8250
  e1dd639e374a PCI: qcom: Add SM8250 SoC support

A good one would be:

  PCI: qcom: Add IPQ60xx support

We already know this is a PCIe controller, and it's nice to have the
important words like "IPQ60xx" early in the message so they don't get
truncated or wrapped.

On Mon, Jan 24, 2022 at 06:27:31PM +0200, Baruch Siach wrote:
> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> 
> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
> platform.
> 
> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
> win.linuxopenwrt.2.0).
> 
> Split out the DBI registers access part from .init into .post_init. DBI
> registers are only accessible after phy_power_on().
> 
> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
> 
> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> ---
> v5:
> 
>   * Remove comments from qcom_pcie_init_2_9_0() (Bjorn Andersson)
> 
> v4:
> 
>   * Rebase on v5.16-rc1
> 
> v3:
>   * Drop speed setup; rely on generic code (Rob Herring)
> 
>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
> 
>   * Minor formatting fixes (Bjorn Helgaas)
> 
>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
> 
> v2:
>   * Drop ATU configuration; rely on common code instead
> 
>   * Use more common register macros
> 
>   * Use bulk clk and reset APIs
> ---
>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>  drivers/pci/controller/dwc/pcie-qcom.c       | 137 +++++++++++++++++++
>  2 files changed, 138 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> index ea87809ee298..279c3778a13b 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.h
> +++ b/drivers/pci/controller/dwc/pcie-designware.h
> @@ -76,6 +76,7 @@
>  
>  #define GEN3_RELATED_OFF			0x890
>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index c19cd506ed3f..5d47e572da44 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -52,6 +52,10 @@
>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
> +#define AHB_CLK_EN				BIT(0)
> +#define MSTR_AXI_CLK_EN				BIT(1)
> +#define BYPASS					BIT(4)
> +
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
>  #define PCIE20_PARF_LTSSM			0x1B0
> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
>  	struct clk *ref_clk_src;
>  };
>  
> +struct qcom_pcie_resources_2_9_0 {
> +	struct clk_bulk_data clks[5];
> +	struct reset_control *rst;
> +};
> +
>  union qcom_pcie_resources {
>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
>  };
>  
>  struct qcom_pcie;
> @@ -1297,6 +1307,119 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>  	clk_disable_unprepare(res->pipe_clk);
>  }
>  
> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +	struct dw_pcie *pci = pcie->pci;
> +	struct device *dev = pci->dev;
> +	int ret;
> +
> +	res->clks[0].id = "iface";
> +	res->clks[1].id = "axi_m";
> +	res->clks[2].id = "axi_s";
> +	res->clks[3].id = "axi_bridge";
> +	res->clks[4].id = "rchng";
> +
> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
> +	if (ret < 0)
> +		return ret;
> +
> +	res->rst = devm_reset_control_array_get_exclusive(dev);
> +	if (IS_ERR(res->rst))
> +		return PTR_ERR(res->rst);
> +
> +	return 0;
> +}
> +
> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +
> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
> +}
> +
> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> +	struct device *dev = pcie->pci->dev;
> +	int ret;
> +
> +	ret = reset_control_assert(res->rst);
> +	if (ret) {
> +		dev_err(dev, "reset assert failed (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	usleep_range(2000, 2500);

Where do these sleep durations come from?  If they're specified
somewhere by PCIe, can you include a citation, e.g., a section number
in the spec.

> +	ret = reset_control_deassert(res->rst);
> +	if (ret) {
> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
> +		return ret;
> +	}
> +
> +	usleep_range(2000, 2500);
> +
> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
> +	if (ret)
> +		goto err_reset;
> +
> +	return 0;
> +
> +err_reset:
> +	reset_control_assert(res->rst);
> +
> +	return ret;
> +}
> +
> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
> +{
> +	struct dw_pcie *pci = pcie->pci;
> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> +	u32 val;
> +	int i;
> +
> +	writel(SLV_ADDR_SPACE_SZ,
> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
> +
> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> +	val &= ~BIT(0);
> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> +
> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> +
> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
> +		pci->dbi_base + GEN3_RELATED_OFF);
> +
> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
> +
> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
> +
> +	dw_pcie_dbi_ro_wr_en(pci);
> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);

Is "PCIE_CAP_LINK1_VAL" misnamed?  If it's being written to
PCI_EXP_SLTCAP, seems like it should be named something about a
*slot*, not a *link*.

Or is this an error and it should this be written to PCI_EXP_LNKCAP
instead?

Could PCIE_CAP_LINK1_VAL be defined in terms of PCI_EXP_SLTCAP_* or
PCI_EXP_LNKCAP_*?

> +	/* Configure PCIe link capabilities for ASPM */
> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);

Thanks for using the standard PCI_EXP_LNKCAP and similar #defines.
Does this mean you don't advertise any ASPM support on this platform?
If so, that's fine, but the comment could be more specific.
"Configure" doesn't give any hint about *how* they are configured.

> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
> +			PCI_EXP_DEVCTL2);
> +
> +	for (i = 0; i < 256; i++)
> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
> +				+ (4 * i));
> +
> +	return 0;
> +}
> +
>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>  {
>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> @@ -1487,6 +1610,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>  	.config_sid = qcom_pcie_config_sid_sm8250,
>  };
>  
> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
> +static const struct qcom_pcie_ops ops_2_9_0 = {
> +	.get_resources = qcom_pcie_get_resources_2_9_0,
> +	.init = qcom_pcie_init_2_9_0,
> +	.post_init = qcom_pcie_post_init_2_9_0,
> +	.deinit = qcom_pcie_deinit_2_9_0,
> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
> +};
> +
>  static const struct qcom_pcie_cfg apq8084_cfg = {
>  	.ops = &ops_1_0_0,
>  };
> @@ -1520,6 +1652,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
>  	.pipe_clk_need_muxing = true,
>  };
>  
> +static const struct qcom_pcie_cfg ipq6018_cfg = {
> +	.ops = &ops_2_9_0,
> +};
> +
>  static const struct dw_pcie_ops dw_pcie_ops = {
>  	.link_up = qcom_pcie_link_up,
>  	.start_link = qcom_pcie_start_link,
> @@ -1629,6 +1765,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
>  	{ }
>  };
>  
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From gregkh at linuxfoundation.org  Mon Jan 24 10:43:07 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:43:07 +0100
Subject: [PATCH 5.15 670/846] crypto: stm32/crc32 - Fix kernel BUG triggered
 in probe()
In-Reply-To: <20220124184100.867127425@linuxfoundation.org>
References: <20220124184100.867127425@linuxfoundation.org>
Message-ID: <20220124184124.185205895@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From fllinden at amazon.com  Mon Jan 24 13:05:38 2022
From: fllinden at amazon.com (Frank van der Linden)
Date: Mon, 24 Jan 2022 21:05:38 +0000
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <Yd1cnquQFZoNE7FP@kernel.org>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com> <Yd1cnquQFZoNE7FP@kernel.org>
Message-ID: <20220124210538.GA15943@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>

Meanwhile, it seems that this issue was already addressed in:

https://lore.kernel.org/all/20211215021348.8766-1-kernelfans at gmail.com/

..which has now been pulled in, and sent to stable@ for 5.15. I
somehow missed that message, and sent my change in a few weeks
later.

The fix to just reserve the ranges does seem a bit cleaner overall,
but this will do fine.

Thanks!

- Frank


From gregkh at linuxfoundation.org  Mon Jan 24 10:38:11 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:38:11 +0100
Subject: [PATCH 5.16 0502/1039] of: fdt: Aggregate the processing of "linux,
 usable-memory-range"
In-Reply-To: <20220124184125.121143506@linuxfoundation.org>
References: <20220124184125.121143506@linuxfoundation.org>
Message-ID: <20220124184142.136258100@linuxfoundation.org>

From: Zhen Lei <thunder.leizhen at huawei.com>

[ Upstream commit 8347b41748c3019157312fbe7f8a6792ae396eb7 ]

Currently, we parse the "linux,usable-memory-range" property in
early_init_dt_scan_chosen(), to obtain the specified memory range of the
crash kernel. We then reserve the required memory after
early_init_dt_scan_memory() has identified all available physical memory.
Because the two pieces of code are separated far, the readability and
maintainability are reduced. So bring them together.

Suggested-by: Rob Herring <robh at kernel.org>
Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
(change the prototype of early_init_dt_check_for_usable_mem_range(), in
order to use it outside)
Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>
Acked-by: John Donnelly <john.p.donnelly at oracle.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
To: devicetree at vger.kernel.org
To: linux-efi at vger.kernel.org
Signed-off-by: Rob Herring <robh at kernel.org>
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/of/fdt.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index bdca35284cebd..5a238a933eb29 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -965,18 +965,22 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
 		 elfcorehdr_addr, elfcorehdr_size);
 }
 
-static phys_addr_t cap_mem_addr;
-static phys_addr_t cap_mem_size;
+static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
 
 /**
  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
  * location from flat tree
- * @node: reference to node containing usable memory range location ('chosen')
  */
-static void __init early_init_dt_check_for_usable_mem_range(unsigned long node)
+static void __init early_init_dt_check_for_usable_mem_range(void)
 {
 	const __be32 *prop;
 	int len;
+	phys_addr_t cap_mem_addr;
+	phys_addr_t cap_mem_size;
+	unsigned long node = chosen_node_offset;
+
+	if ((long)node < 0)
+		return;
 
 	pr_debug("Looking for usable-memory-range property... ");
 
@@ -989,6 +993,8 @@ static void __init early_init_dt_check_for_usable_mem_range(unsigned long node)
 
 	pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
 		 &cap_mem_size);
+
+	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
 }
 
 #ifdef CONFIG_SERIAL_EARLYCON
@@ -1137,9 +1143,10 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
 		return 0;
 
+	chosen_node_offset = node;
+
 	early_init_dt_check_for_initrd(node);
 	early_init_dt_check_for_elfcorehdr(node);
-	early_init_dt_check_for_usable_mem_range(node);
 
 	/* Retrieve command line */
 	p = of_get_flat_dt_prop(node, "bootargs", &l);
@@ -1275,7 +1282,7 @@ void __init early_init_dt_scan_nodes(void)
 	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
 
 	/* Handle linux,usable-memory-range property */
-	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
+	early_init_dt_check_for_usable_mem_range();
 }
 
 bool __init early_init_dt_scan(void *params)
-- 
2.34.1





From gregkh at linuxfoundation.org  Mon Jan 24 10:38:12 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:38:12 +0100
Subject: [PATCH 5.16 0503/1039] efi: apply memblock cap after memblock_add()
In-Reply-To: <20220124184125.121143506@linuxfoundation.org>
References: <20220124184125.121143506@linuxfoundation.org>
Message-ID: <20220124184142.176957209@linuxfoundation.org>

From: Pingfan Liu <kernelfans at gmail.com>

[ Upstream commit b398123bff3bcbc1facb0f29bf6e7b9f1bc55931 ]

On arm64, during kdump kernel saves vmcore, it runs into the following bug:
...
[   15.148919] usercopy: Kernel memory exposure attempt detected from SLUB object 'kmem_cache_node' (offset 0, size 4096)!
[   15.159707] ------------[ cut here ]------------
[   15.164311] kernel BUG at mm/usercopy.c:99!
[   15.168482] Internal error: Oops - BUG: 0 [#1] SMP
[   15.173261] Modules linked in: xfs libcrc32c crct10dif_ce ghash_ce sha2_ce sha256_arm64 sha1_ce sbsa_gwdt ast i2c_algo_bit drm_vram_helper drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops cec drm_ttm_helper ttm drm nvme nvme_core xgene_hwmon i2c_designware_platform i2c_designware_core dm_mirror dm_region_hash dm_log dm_mod overlay squashfs zstd_decompress loop
[   15.206186] CPU: 0 PID: 542 Comm: cp Not tainted 5.16.0-rc4 #1
[   15.212006] Hardware name: GIGABYTE R272-P30-JG/MP32-AR0-JG, BIOS F12 (SCP: 1.5.20210426) 05/13/2021
[   15.221125] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   15.228073] pc : usercopy_abort+0x9c/0xa0
[   15.232074] lr : usercopy_abort+0x9c/0xa0
[   15.236070] sp : ffff8000121abba0
[   15.239371] x29: ffff8000121abbb0 x28: 0000000000003000 x27: 0000000000000000
[   15.246494] x26: 0000000080000400 x25: 0000ffff885c7000 x24: 0000000000000000
[   15.253617] x23: 000007ff80400000 x22: ffff07ff80401000 x21: 0000000000000001
[   15.260739] x20: 0000000000001000 x19: ffff07ff80400000 x18: ffffffffffffffff
[   15.267861] x17: 656a626f2042554c x16: 53206d6f72662064 x15: 6574636574656420
[   15.274983] x14: 74706d6574746120 x13: 2129363930342065 x12: 7a6973202c302074
[   15.282105] x11: ffffc8b041d1b148 x10: 00000000ffff8000 x9 : ffffc8b04012812c
[   15.289228] x8 : 00000000ffff7fff x7 : ffffc8b041d1b148 x6 : 0000000000000000
[   15.296349] x5 : 0000000000000000 x4 : 0000000000007fff x3 : 0000000000000000
[   15.303471] x2 : 0000000000000000 x1 : ffff07ff8c064800 x0 : 000000000000006b
[   15.310593] Call trace:
[   15.313027]  usercopy_abort+0x9c/0xa0
[   15.316677]  __check_heap_object+0xd4/0xf0
[   15.320762]  __check_object_size.part.0+0x160/0x1e0
[   15.325628]  __check_object_size+0x2c/0x40
[   15.329711]  copy_oldmem_page+0x7c/0x140
[   15.333623]  read_from_oldmem.part.0+0xfc/0x1c0
[   15.338142]  __read_vmcore.constprop.0+0x23c/0x350
[   15.342920]  read_vmcore+0x28/0x34
[   15.346309]  proc_reg_read+0xb4/0xf0
[   15.349871]  vfs_read+0xb8/0x1f0
[   15.353088]  ksys_read+0x74/0x100
[   15.356390]  __arm64_sys_read+0x28/0x34
...

This bug introduced by commit b261dba2fdb2 ("arm64: kdump: Remove custom
linux,usable-memory-range handling"), which moves
memblock_cap_memory_range() to fdt, but it breaches the rules that
memblock_cap_memory_range() should come after memblock_add() etc as said
in commit e888fa7bb882 ("memblock: Check memory add/cap ordering").

As a consequence, the virtual address set up by copy_oldmem_page() does
not bail out from the test of virt_addr_valid() in check_heap_object(),
and finally hits the BUG_ON().

Since memblock allocator has no idea about when the memblock is fully
populated, while efi_init() is aware, so tackling this issue by calling the
interface early_init_dt_check_for_usable_mem_range() exposed by of/fdt.

Fixes: b261dba2fdb2 ("arm64: kdump: Remove custom linux,usable-memory-range handling")
Signed-off-by: Pingfan Liu <kernelfans at gmail.com>
Cc: Rob Herring <robh+dt at kernel.org>
Cc: Zhen Lei <thunder.leizhen at huawei.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Mike Rapoport <rppt at kernel.org>
Cc: Geert Uytterhoeven <geert+renesas at glider.be>
Cc: Frank Rowand <frowand.list at gmail.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Nick Terrell <terrelln at fb.com>
Cc: linux-arm-kernel at lists.infradead.org
To: devicetree at vger.kernel.org
To: linux-efi at vger.kernel.org
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Signed-off-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/r/20211215021348.8766-1-kernelfans at gmail.com
Signed-off-by: Sasha Levin <sashal at kernel.org>
---
 drivers/firmware/efi/efi-init.c | 5 +++++
 drivers/of/fdt.c                | 2 +-
 include/linux/of_fdt.h          | 2 ++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c
index b19ce1a83f91a..b2c829e95bd14 100644
--- a/drivers/firmware/efi/efi-init.c
+++ b/drivers/firmware/efi/efi-init.c
@@ -235,6 +235,11 @@ void __init efi_init(void)
 	}
 
 	reserve_regions();
+	/*
+	 * For memblock manipulation, the cap should come after the memblock_add().
+	 * And now, memblock is fully populated, it is time to do capping.
+	 */
+	early_init_dt_check_for_usable_mem_range();
 	efi_esrt_init();
 	efi_mokvar_table_init();
 
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index 5a238a933eb29..65af475dfa950 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -971,7 +971,7 @@ static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
  * early_init_dt_check_for_usable_mem_range - Decode usable memory range
  * location from flat tree
  */
-static void __init early_init_dt_check_for_usable_mem_range(void)
+void __init early_init_dt_check_for_usable_mem_range(void)
 {
 	const __be32 *prop;
 	int len;
diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
index cf48983d3c867..ad09beb6d13c4 100644
--- a/include/linux/of_fdt.h
+++ b/include/linux/of_fdt.h
@@ -62,6 +62,7 @@ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname,
 				     int depth, void *data);
 extern int early_init_dt_scan_memory(unsigned long node, const char *uname,
 				     int depth, void *data);
+extern void early_init_dt_check_for_usable_mem_range(void);
 extern int early_init_dt_scan_chosen_stdout(void);
 extern void early_init_fdt_scan_reserved_mem(void);
 extern void early_init_fdt_reserve_self(void);
@@ -86,6 +87,7 @@ extern void unflatten_and_copy_device_tree(void);
 extern void early_init_devtree(void *);
 extern void early_get_first_memblock_info(void *, phys_addr_t *);
 #else /* CONFIG_OF_EARLY_FLATTREE */
+static inline void early_init_dt_check_for_usable_mem_range(void) {}
 static inline int early_init_dt_scan_chosen_stdout(void) { return -ENODEV; }
 static inline void early_init_fdt_scan_reserved_mem(void) {}
 static inline void early_init_fdt_reserve_self(void) {}
-- 
2.34.1





From skhan at linuxfoundation.org  Mon Jan 24 13:27:07 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Mon, 24 Jan 2022 14:27:07 -0700
Subject: [PATCH v1 1/2] kselftest/arm64: Skip VL_INHERIT tests for
 unsupported vector types
In-Reply-To: <20220124175527.3260234-2-broonie@kernel.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
 <20220124175527.3260234-2-broonie@kernel.org>
Message-ID: <e9849218-24aa-cccb-21c4-a0467cffd4fb@linuxfoundation.org>

On 1/24/22 10:55 AM, Mark Brown wrote:
> Currently we unconditionally test the ability to set the vector length
> inheritance flag via ptrace meaning that we generate false failures on
> systems that don't support SVE when we attempt to set the vector length
> there. Check the hwcap and mark the tests as skipped when it's not present.
> 
> Fixes: 0ba1ce1e86052d ("selftests: arm64: Add coverage of ptrace flags for SVE VL inheritance")
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>   tools/testing/selftests/arm64/fp/sve-ptrace.c | 9 ++++++++-
>   1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> index af798b9d232c..0cf78360c5bc 100644
> --- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
> +++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> @@ -557,7 +557,14 @@ static int do_parent(pid_t child)
>   		}
>   
>   		/* prctl() flags */
> -		ptrace_set_get_inherit(child, &vec_types[i]);
> +		if (getauxval(vec_types[i].hwcap_type) & vec_types[i].hwcap) {
> +			ptrace_set_get_inherit(child, &vec_types[i]);
> +		} else {
> +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT set\n",
> +					      vec_types[i].name);
> +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT cleared\n",
> +					      vec_types[i].name);

These messages are a bit confusing. Are we skipping two tests?
These messages can be combined into one like this one on lin 572:

ksft_test_result_skip("%s get/set VL %d\n", vec_types[i].name, vl);

> +		}
>   
>   		/* Step through every possible VQ */
>   		for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
> 

thanks,
-- Shuah


From skhan at linuxfoundation.org  Mon Jan 24 13:28:29 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Mon, 24 Jan 2022 14:28:29 -0700
Subject: [PATCH v1 2/2] kselftest/arm64: Correct logging of FPSIMD
 register read via ptrace
In-Reply-To: <20220124175527.3260234-3-broonie@kernel.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
 <20220124175527.3260234-3-broonie@kernel.org>
Message-ID: <a8ec61fd-45c0-96e2-5a58-7dd3caf22844@linuxfoundation.org>

On 1/24/22 10:55 AM, Mark Brown wrote:
> There's a cut'n'paste error in the logging for our test for reading register
> state back via ptrace, correctly say that we did a read instead of a write.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>   tools/testing/selftests/arm64/fp/sve-ptrace.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> index 0cf78360c5bc..a3c1e67441f9 100644
> --- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
> +++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> @@ -261,7 +261,7 @@ static void ptrace_sve_fpsimd(pid_t child, const struct vec_type *type)
>   	}
>   
>   	ksft_test_result((sve->flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD,
> -			 "Set FPSIMD registers via %s\n", type->name);
> +			 "Got FPSIMD registers via %s\n", type->name);
>   	if ((sve->flags & SVE_PT_REGS_MASK) != SVE_PT_REGS_FPSIMD)
>   		goto out;
>   
> 

Looks good to me. Assuming this is going through ARM tree

Reviewed-by: Shuah Khan <skhan at linuxfoundation.org>

thanks,
-- Shuah


From skhan at linuxfoundation.org  Mon Jan 24 13:30:09 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Mon, 24 Jan 2022 14:30:09 -0700
Subject: [PATCH] kselftest/arm64: Remove local ARRAY_SIZE() definitions
In-Reply-To: <20220124171748.2195875-1-broonie@kernel.org>
References: <20220124171748.2195875-1-broonie@kernel.org>
Message-ID: <e1b49cb1-31ad-0991-0ca8-46ce4c55d853@linuxfoundation.org>

On 1/24/22 10:17 AM, Mark Brown wrote:
> An ARRAY_SIZE() has been added to kselftest.h so remove the local versions
> in some of the arm64 selftests.
> 

Thank you for the patch removing duplicate defines.

> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>   tools/testing/selftests/arm64/abi/syscall-abi.c | 1 -
>   tools/testing/selftests/arm64/fp/sve-ptrace.c   | 2 --
>   2 files changed, 3 deletions(-)
> 
> diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
> index d8eeeafb50dc..1e13b7523918 100644
> --- a/tools/testing/selftests/arm64/abi/syscall-abi.c
> +++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
> @@ -18,7 +18,6 @@
>   
>   #include "../../kselftest.h"
>   
> -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
>   #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
>   
>   extern void do_syscall(int sve_vl);
> diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> index af798b9d232c..90ba1d6a6781 100644
> --- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
> +++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
> @@ -21,8 +21,6 @@
>   
>   #include "../../kselftest.h"
>   
> -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
> -
>   /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
>   #ifndef NT_ARM_SVE
>   #define NT_ARM_SVE 0x405
> 

Assuming this is going through ARM tree?

Reviewed-by: Shuah Khan <skhan at linuxfoundation.org>

thanks,
-- Shuah


From broonie at kernel.org  Mon Jan 24 13:33:29 2022
From: broonie at kernel.org (Mark Brown)
Date: Mon, 24 Jan 2022 21:33:29 +0000
Subject: [PATCH v1 1/2] kselftest/arm64: Skip VL_INHERIT tests for
 unsupported vector types
In-Reply-To: <e9849218-24aa-cccb-21c4-a0467cffd4fb@linuxfoundation.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
 <20220124175527.3260234-2-broonie@kernel.org>
 <e9849218-24aa-cccb-21c4-a0467cffd4fb@linuxfoundation.org>
Message-ID: <Ye8bKVurkVbhhEgz@sirena.org.uk>

On Mon, Jan 24, 2022 at 02:27:07PM -0700, Shuah Khan wrote:
> On 1/24/22 10:55 AM, Mark Brown wrote:

> > -		ptrace_set_get_inherit(child, &vec_types[i]);
> > +		if (getauxval(vec_types[i].hwcap_type) & vec_types[i].hwcap) {
> > +			ptrace_set_get_inherit(child, &vec_types[i]);
> > +		} else {
> > +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT set\n",
> > +					      vec_types[i].name);
> > +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT cleared\n",
> > +					      vec_types[i].name);

> These messages are a bit confusing. Are we skipping two tests?

ptrace_set_get_inherit() logs two test results (one for set, one for get).

> These messages can be combined into one like this one on lin 572:

> ksft_test_result_skip("%s get/set VL %d\n", vec_types[i].name, vl);

If we do that then the number of planned tests won't line up with the
number of expected tests.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220124/188256e8/attachment.sig>

From gregkh at linuxfoundation.org  Mon Jan 24 10:43:46 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Mon, 24 Jan 2022 19:43:46 +0100
Subject: [PATCH 5.16 0837/1039] crypto: stm32/crc32 - Fix kernel BUG triggered
 in probe()
In-Reply-To: <20220124184125.121143506@linuxfoundation.org>
References: <20220124184125.121143506@linuxfoundation.org>
Message-ID: <20220124184153.426827249@linuxfoundation.org>

From: Marek Vasut <marex at denx.de>

commit 29009604ad4e3ef784fd9b9fef6f23610ddf633d upstream.

The include/linux/crypto.h struct crypto_alg field cra_driver_name description
states "Unique name of the transformation provider. " ... " this contains the
name of the chip or provider and the name of the transformation algorithm."

In case of the stm32-crc driver, field cra_driver_name is identical for all
registered transformation providers and set to the name of the driver itself,
which is incorrect. This patch fixes it by assigning a unique cra_driver_name
to each registered transformation provider.

The kernel crash is triggered when the driver calls crypto_register_shashes()
which calls crypto_register_shash(), which calls crypto_register_alg(), which
calls __crypto_register_alg(), which returns -EEXIST, which is propagated
back through this call chain. Upon -EEXIST from crypto_register_shash(), the
crypto_register_shashes() starts unregistering the providers back, and calls
crypto_unregister_shash(), which calls crypto_unregister_alg(), and this is
where the BUG() triggers due to incorrect cra_refcnt.

Fixes: b51dbe90912a ("crypto: stm32 - Support for STM32 CRC32 crypto module")
Signed-off-by: Marek Vasut <marex at denx.de>
Cc: <stable at vger.kernel.org> # 4.12+
Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
Cc: Fabien Dessenne <fabien.dessenne at st.com>
Cc: Herbert Xu <herbert at gondor.apana.org.au>
Cc: Lionel Debieve <lionel.debieve at st.com>
Cc: Nicolas Toromanoff <nicolas.toromanoff at st.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-stm32 at st-md-mailman.stormreply.com
To: linux-crypto at vger.kernel.org
Acked-by: Nicolas Toromanoff <nicolas.toromanoff at foss.st.com>
Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/crypto/stm32/stm32-crc32.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/crypto/stm32/stm32-crc32.c
+++ b/drivers/crypto/stm32/stm32-crc32.c
@@ -279,7 +279,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,
@@ -301,7 +301,7 @@ static struct shash_alg algs[] = {
 		.digestsize     = CHKSUM_DIGEST_SIZE,
 		.base           = {
 			.cra_name               = "crc32c",
-			.cra_driver_name        = DRIVER_NAME,
+			.cra_driver_name        = "stm32-crc32-crc32c",
 			.cra_priority           = 200,
 			.cra_flags		= CRYPTO_ALG_OPTIONAL_KEY,
 			.cra_blocksize          = CHKSUM_BLOCK_SIZE,




From skhan at linuxfoundation.org  Mon Jan 24 13:39:32 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Mon, 24 Jan 2022 14:39:32 -0700
Subject: [PATCH v1 1/2] kselftest/arm64: Skip VL_INHERIT tests for
 unsupported vector types
In-Reply-To: <Ye8bKVurkVbhhEgz@sirena.org.uk>
References: <20220124175527.3260234-1-broonie@kernel.org>
 <20220124175527.3260234-2-broonie@kernel.org>
 <e9849218-24aa-cccb-21c4-a0467cffd4fb@linuxfoundation.org>
 <Ye8bKVurkVbhhEgz@sirena.org.uk>
Message-ID: <6a3032de-1a13-b25f-a33f-fb2d7a5777b7@linuxfoundation.org>

On 1/24/22 2:33 PM, Mark Brown wrote:
> On Mon, Jan 24, 2022 at 02:27:07PM -0700, Shuah Khan wrote:
>> On 1/24/22 10:55 AM, Mark Brown wrote:
> 
>>> -		ptrace_set_get_inherit(child, &vec_types[i]);
>>> +		if (getauxval(vec_types[i].hwcap_type) & vec_types[i].hwcap) {
>>> +			ptrace_set_get_inherit(child, &vec_types[i]);
>>> +		} else {
>>> +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT set\n",
>>> +					      vec_types[i].name);
>>> +			ksft_test_result_skip("%s SVE_PT_VL_INHERIT cleared\n",
>>> +					      vec_types[i].name);
> 
>> These messages are a bit confusing. Are we skipping two tests?
> 
> ptrace_set_get_inherit() logs two test results (one for set, one for get).
> 

Ah okay.

>> These messages can be combined into one like this one on lin 572:
> 
>> ksft_test_result_skip("%s get/set VL %d\n", vec_types[i].name, vl);
> 
> If we do that then the number of planned tests won't line up with the
> number of expected tests.
> 

Sounds good. Assuming this is going through ARM tree?

Reviewed-by: Shuah Khan <skhan at linuxfoundation.org>

thanks,
-- Shuah


From khilman at baylibre.com  Mon Jan 24 14:05:17 2022
From: khilman at baylibre.com (Kevin Hilman)
Date: Mon, 24 Jan 2022 14:05:17 -0800
Subject: [PATCH] mmc: meson: Fix usage of meson_mmc_post_req()
In-Reply-To: <20220106105453.3875119-1-rong.chen@amlogic.com>
References: <20220106105453.3875119-1-rong.chen@amlogic.com>
Message-ID: <7htudsx00y.fsf@baylibre.com>

Hello Rong,

First, thank you finding the issue and for submitting a fix!

Rong Chen <rong.chen at amlogic.com> writes:

> To ensure the DMA moves data correctly from memory to
> peripherals, DMA unmapping when the MMC request done
> with calls meson_mmc_post_req().
>
> Signed-off-by: Rong Chen <rong.chen at amlogic.com>

The patch looks correct, but I think I think the changelog could be
improved.  If I understand the code correctly, I think what you're doing
is:

"""
Currently meson_mmc_post_req() is called in meson_mmc_request() right
after _start_cmd().  This could lead to DMA unmapping before the request
is actually finished.

To fix, ton't call meson_mmc_post_req() until _request_done().
"""

Kevin

> ---
>  drivers/mmc/host/meson-gx-mmc.c | 14 +++++++-------
>  1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c
> index 8f36536cb1b6..6a9554ae4b1c 100644
> --- a/drivers/mmc/host/meson-gx-mmc.c
> +++ b/drivers/mmc/host/meson-gx-mmc.c
> @@ -173,6 +173,7 @@ struct meson_host {
>  	int irq;
>  
>  	bool vqmmc_enabled;
> +	bool needs_pre_post_req;
>  };
>  
>  #define CMD_CFG_LENGTH_MASK GENMASK(8, 0)
> @@ -663,6 +664,8 @@ static void meson_mmc_request_done(struct mmc_host *mmc,
>  	struct meson_host *host = mmc_priv(mmc);
>  
>  	host->cmd = NULL;
> +	if (host->needs_pre_post_req)
> +		meson_mmc_post_req(mmc, mrq, 0);
>  	mmc_request_done(host->mmc, mrq);
>  }
>  
> @@ -880,7 +883,7 @@ static int meson_mmc_validate_dram_access(struct mmc_host *mmc, struct mmc_data
>  static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  {
>  	struct meson_host *host = mmc_priv(mmc);
> -	bool needs_pre_post_req = mrq->data &&
> +	host->needs_pre_post_req = mrq->data &&
>  			!(mrq->data->host_cookie & SD_EMMC_PRE_REQ_DONE);
>  
>  	/*
> @@ -896,22 +899,19 @@ static void meson_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
>  		}
>  	}
>  
> -	if (needs_pre_post_req) {
> +	if (host->needs_pre_post_req) {
>  		meson_mmc_get_transfer_mode(mmc, mrq);
>  		if (!meson_mmc_desc_chain_mode(mrq->data))
> -			needs_pre_post_req = false;
> +			host->needs_pre_post_req = false;
>  	}
>  
> -	if (needs_pre_post_req)
> +	if (host->needs_pre_post_req)
>  		meson_mmc_pre_req(mmc, mrq);
>  
>  	/* Stop execution */
>  	writel(0, host->regs + SD_EMMC_START);
>  
>  	meson_mmc_start_cmd(mmc, mrq->sbc ?: mrq->cmd);
> -
> -	if (needs_pre_post_req)
> -		meson_mmc_post_req(mmc, mrq, 0);
>  }
>  
>  static void meson_mmc_read_resp(struct mmc_host *mmc, struct mmc_command *cmd)
>
> base-commit: 356f3f2c5756bbb67a515760966a40fc7043cdda
> -- 
> 2.25.1


From mohammad.athari.ismail at intel.com  Mon Jan 24 14:19:22 2022
From: mohammad.athari.ismail at intel.com (Ismail, Mohammad Athari)
Date: Mon, 24 Jan 2022 22:19:22 +0000
Subject: [PATCH net 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <Ye6maxMtt68JlZ9l@lunn.ch>
References: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
 <20220124095951.23845-3-mohammad.athari.ismail@intel.com>
 <Ye6maxMtt68JlZ9l@lunn.ch>
Message-ID: <CO1PR11MB47716D7115E85AC4649CD3A5D55E9@CO1PR11MB4771.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Andrew Lunn <andrew at lunn.ch>
> Sent: Monday, January 24, 2022 9:15 PM
> To: Ismail, Mohammad Athari <mohammad.athari.ismail at intel.com>
> Cc: Giuseppe Cavallaro <peppe.cavallaro at st.com>; Alexandre Torgue
> <alexandre.torgue at st.com>; Jose Abreu <joabreu at synopsys.com>; David
> S . Miller <davem at davemloft.net>; Jakub Kicinski <kuba at kernel.org>;
> Maxime Coquelin <mcoquelin.stm32 at gmail.com>; Ong, Boon Leong
> <boon.leong.ong at intel.com>; Voon, Weifeng <weifeng.voon at intel.com>;
> Wong, Vee Khee <vee.khee.wong at intel.com>; Huacai Chen
> <chenhuacai at kernel.org>; netdev at vger.kernel.org; linux-stm32 at st-md-
> mailman.stormreply.com; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org
> Subject: Re: [PATCH net 2/2] net: stmmac: skip only stmmac_ptp_register
> when resume from suspend
> 
> > @@ -3308,13 +3309,11 @@ static int stmmac_hw_setup(struct net_device
> *dev, bool init_ptp)
> >
> >  	stmmac_mmc_setup(priv);
> >
> > -	if (init_ptp) {
> > -		ret = stmmac_init_ptp(priv);
> > -		if (ret == -EOPNOTSUPP)
> > -			netdev_warn(priv->dev, "PTP not supported by
> HW\n");
> > -		else if (ret)
> > -			netdev_warn(priv->dev, "PTP init failed\n");
> > -	}
> > +	ret = stmmac_init_ptp(priv, ptp_register);
> > +	if (ret == -EOPNOTSUPP)
> > +		netdev_warn(priv->dev, "PTP not supported by HW\n");
> > +	else if (ret)
> > +		netdev_warn(priv->dev, "PTP init failed\n");
> 
> The init_ptp parameter now seems unused? If so, please remove it.

I believe you miss below diff. It is renamed to ptp_register.

-static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);


There are build warnings as below. I'll fix it in v2.

../drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:888: warning: Function parameter or member 'ptp_register' not described in 'stmmac_init_ptp'
../drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3256: warning: Excess function parameter 'init_ptp' description in 'stmmac_hw_setup

Thanks

-Athari-

> 
>     Andrew


From carltonshepherd at gmail.com  Mon Jan 24 14:33:18 2022
From: carltonshepherd at gmail.com (Carlton Shepherd)
Date: Mon, 24 Jan 2022 22:33:18 +0000
Subject: [BUG] dts: hi6220: PMU events not fully functional
Message-ID: <CABk+d1tuNMoedpHyA2WwtPv33RCXnui9430D5jysePX2ZPawDg@mail.gmail.com>

Hello,

The perf subsystem does not detect any PMU events for the HiSilicon
6220 SoC. (Tested on a HiKey 620 with 5.17.0-rc1.)

Based on [1] and [2], /arch/arm64/boot/dts/hisilicon/hi6220.dtsi is
missing a PMU node. This was patched for the hi3660 in
/arch/arm64/boot/dts/hisilicon/hi3660.dtsi [3], but remains defective
for the hi6220.

Could somebody please provide some assistance?

Kind regards,
Carlton Shepherd

1. https://www.96boards.org/documentation/consumer/hikey/hikey960/support/pmu-on-hikey960.md.html
2. https://discuss.96boards.org/t/linux-perf-list-failing-to-detect-hardware-events-on-hikey620/11752
3. https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1465696.html


From alisaidi at amazon.com  Mon Jan 24 14:53:33 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Mon, 24 Jan 2022 22:53:33 +0000
Subject: [PATCH] perf arm-spe: Use SPE data source for neoverse cores
In-Reply-To: <0ba26f30-6978-36ad-f7d0-7b8465648e54@arm.com>
References: <0ba26f30-6978-36ad-f7d0-7b8465648e54@arm.com>
Message-ID: <20220124225333.19864-1-alisaidi@amazon.com>

On 1/24/22, 11:24 AM, "James Clark" <james.clark at arm.com> wrote:
>On 21/01/2022 18:24, Ali Saidi wrote:
>> When synthesizing data from SPE, augment the type with source information
>> for Arm Neoverse cores. The field is IMPLDEF but the Neoverse cores all use
>> the same encoding. I can't find encoding information for any other SPE
>> implementations to unify their choices with Arm's thus that is left for future
>> work.
>> 
>> This changes enables the expected behavior of perf c2c on a system with SPE where
>> lines that are shared among multiple cores show up in perf c2c output. 
>> 
>> Signed-off-by: Ali Saidi <alisaidi at amazon.com> 
>> ---
>>  .../util/arm-spe-decoder/arm-spe-decoder.c    |  1 +
>>  .../util/arm-spe-decoder/arm-spe-decoder.h    | 12 +++++
>>  tools/perf/util/arm-spe.c                     | 48 ++++++++++++++-----
>>  3 files changed, 49 insertions(+), 12 deletions(-)
>> 
>[...]
>> +static u64 arm_spe__synth_data_source(const struct arm_spe_record *record, u64 midr)
>>  {
>>  	union perf_mem_data_src	data_src = { 0 };
>> +	bool is_neoverse = is_midr_in_range(midr, neoverse_spe);
>>  
>>  	if (record->op == ARM_SPE_LD)
>>  		data_src.mem_op = PERF_MEM_OP_LOAD;
>> @@ -409,19 +418,30 @@ static u64 arm_spe__synth_data_source(const struct arm_spe_record *record)
>>  		data_src.mem_op = PERF_MEM_OP_STORE;
>>  
>>  	if (record->type & (ARM_SPE_LLC_ACCESS | ARM_SPE_LLC_MISS)) {
>> -		data_src.mem_lvl = PERF_MEM_LVL_L3;
>> +		if (is_neoverse && record->source == ARM_SPE_NV_DRAM) {
>> +			data_src.mem_lvl = PERF_MEM_LVL_LOC_RAM | PERF_MEM_LVL_HIT;
>> +		} else if (is_neoverse && record->source == ARM_SPE_NV_PEER_CLSTR) {
>> +			data_src.mem_snoop = PERF_MEM_SNOOP_HITM;
>
>I'm not following how LLC_ACCESS | LLC_MISS ends up as HITM in this case (ARM_SPE_NV_PEER_CLSTR)?
>I thought there was no way to determine a HITM from SPE. Wouldn't one of the other values
>like PERF_MEM_SNOOP_MISS be more accurate?

Thanks for taking a look James.

I'd really like someone familiar with perf c2c output to also end up getting
similar output when running on an Arm system with SPE. There are obviously large
micro-architectural differences that have been abstracted away by the data_src
abstraction but fundamentally my understanding of x86 HITM is that the line
was found in the snoop filter of the LLC as being owned by another core and
therefore the request needs to go to another core to get the line.  I'm not
100% sure if on x86 it's really guaranteed to be dirty or not and it's not
always going to be dirty in a Neoverse system, but since the SPE source
indicates it was sourced from another core it is a core-2-core transfer of a
line which is currently owned by another cpu core and that is the interesting
data point that would be used to drive optimization and elimination of frequent
core-2-core transfers (true or false sharing).

>> +			data_src.mem_lvl = PERF_MEM_LVL_L3 | PERF_MEM_LVL_HIT;
>
>This one also adds PERF_MEM_LVL_HIT even though the check of "if (record->type & ARM_SPE_LLC_MISS)"
>hasn't happened yet. Maybe some comments would make it a bit clearer, but at the moment it's
>not obvious how the result is derived because there are some things that don't add up like
>ARM_SPE_LLC_MISS == PERF_MEM_LVL_HIT.

Assuming the above is correct, my reading of the existing code that creates the
c2c output is that when an access is marked as an LLC hit, that doesn't
necessarily mean that the data was present in the LLC. I don't see how it could
given that LLC_HIT + HITM means the line was dirty in another CPUs cache, and so
LLC_HIT + HITM seems to mean that it was a hit in the LLC snoop filter and
required a different core to provide the line. This and the above certainly
deserve a comment as to why the miss is being attributed in this way if it's
otherwise acceptable.

Thanks,
Ali



From Thinh.Nguyen at synopsys.com  Mon Jan 24 15:01:44 2022
From: Thinh.Nguyen at synopsys.com (Thinh Nguyen)
Date: Mon, 24 Jan 2022 23:01:44 +0000
Subject: [PATCH v2 0/7] usb: dwc3: Calculate REFCLKPER et. al. from
 reference clock
In-Reply-To: <e1309c23-530b-c698-b7ba-4f1a5226fe8c@quicinc.com>
References: <20220119002438.106079-1-sean.anderson@seco.com>
 <87ee53fv01.fsf@tarshish> <1965fc315525b8ab26cf9f71f939c24d@codeaurora.org>
 <871r12g0j2.fsf@tarshish> <e1309c23-530b-c698-b7ba-4f1a5226fe8c@quicinc.com>
Message-ID: <f4b22ec2-b3b5-21dd-bc21-f5292d5b138a@synopsys.com>

Kathiravan Thirumoorthy wrote:
> Hi Baruch,
> 
> On 1/20/2022 3:59 PM, Baruch Siach wrote:
>> Hi Kathiravan,
>>
>> On Thu, Jan 20 2022, Kathiravan T wrote:
>>> On 2022-01-19 23:44, Baruch Siach wrote:
>>>> Hi Sean,
>>>> On Tue, Jan 18 2022, Sean Anderson wrote:
>>>>> This is a rework of patches 3-5 of [1]. It attempts to correctly
>>>>> program
>>>>> REFCLKPER and REFCLK_FLADJ based on the reference clock frequency.
>>>>> Since
>>>>> we no longer need a special property duplicating this configuration,
>>>>> snps,ref-clock-period-ns is deprecated.
>>>>> Please test this! Patches 3/4 in this series have the effect of
>>>>> programming REFCLKPER and REFCLK_FLADJ on boards which already
>>>>> configure
>>>>> the "ref" clock. I have build tested, but not much else.
>>>> Tested here on IPQ6010 based system. USB still works. But the with
>>>> "ref"
>>>> clock at 24MHz, period is calculated as 0x29. Previous
>>>> snps,ref-clock-period-ns value used to be 0x32.
>>>> Is that expected?
>>> Yes, it is 0x29 for IPQ60xx based SoCs. In downstream it was wrongly
>>> mentioned
>>> as 0x32, which was corrected recently.
>> Thanks for the update. This needs fixing in upstream kernel. I'll send a
>> patch.
>>
>> For some reason USB appears to work here with both values. Is it because
>> I only use USB2 signals? If this is the case them I can not actually
>> test this series on my system.

The controller uses the GUCTL.REFCLKPER under specific conditions and
settings, and the conditions are different between host mode and device
mode. For example, if you're running as device-mode and not operating in
low power, and or not using periodic endpoints, you're not probably
testing this.

BR,
Thinh


> 
> I could recollect we did see some issue on USB2.0 port as well, but it
> wasn't fatal one. Anyways it is better to test it.
> 
> Thanks,
> 
> Kathiravan T.
> 
>>
>> Thanks,
>> baruch
>>
>>>>> [1]
>>>>> https://urldefense.com/v3/__https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/__;!!A4F2R9G_pg!MCqqTGYTR42-4_LUHhrSJjkUOkDZKb795I8lB3PY4dB-kVCBnR9YKucgzrwhlj0tZZm5$
>>>>> Changes in v2:
>>>>> - Document clock members
>>>>> - Also program GFLADJ.240MHZDECR
>>>>> - Don't program GFLADJ if the version is < 2.50a
>>>>> - Add snps,ref-clock-frequency-hz property for ACPI
>>>>> Sean Anderson (7):
>>>>> ?? dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
>>>>> ?? usb: dwc3: Get clocks individually
>>>>> ?? usb: dwc3: Calculate REFCLKPER based on reference clock
>>>>> ?? usb: dwc3: Program GFLADJ
>>>>> ?? usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
>>>>> ?? arm64: dts: zynqmp: Move USB clocks to dwc3 node
>>>>> ?? arm64: dts: ipq6018: Use reference clock to set dwc3 period
>>>>> ? .../devicetree/bindings/usb/snps,dwc3.yaml??? |?? 7 +-
>>>>> ? arch/arm64/boot/dts/qcom/ipq6018.dtsi???????? |?? 3 +-
>>>>> ? .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |?? 4 +-
>>>>> ? arch/arm64/boot/dts/xilinx/zynqmp.dtsi??????? |?? 4 +-
>>>>> ? drivers/usb/dwc3/core.c?????????????????????? | 112
>>>>> +++++++++++++++---
>>>>> ? drivers/usb/dwc3/core.h?????????????????????? |? 17 ++-
>>>>> ? 6 files changed, 120 insertions(+), 27 deletions(-)
>>


From vijayb at linux.microsoft.com  Mon Jan 24 15:03:48 2022
From: vijayb at linux.microsoft.com (Vijay Balakrishna)
Date: Mon, 24 Jan 2022 15:03:48 -0800
Subject: [arm64] kernel boot slowdown in v5.10.19 -> v5.10.42 update
Message-ID: <9a34ee9b-0ede-30a6-0898-d32fe81d5b0c@linux.microsoft.com>

We noticed 150ms kernel boot slowdown back in June, 2021, when moving 
from v5.10.19 to v5.10.42.  This on a 8GB SoC.  Only recently we 
investigated this issue and found the regression is introduced by a 
change in map_mem() (paging_init() -> map_mem() -> __map_memblock(), in 
particular "map all the memory banks" for loop) by patch

2687275a5843d1089687f08fc64eb3f3b026a169
arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required

above is a follow up to

0a30c53573b07d5561457e41fb0ab046cd857da5
arm64: mm: Move reserve_crashkernel() into mem_init())

which deferred crashkernel reservation into mem_init().

The ~150ms slowdown disappears on booting without "crashkernel=.." on 
kernel command-line.

Please let us know if it known/understood or addressed already or being 
looked into.  Any insight is appreciated.

Thanks,
Vijay

console output collected with debug prints --

[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
[    0.000000] Linux version 
5.10.42.6-xxx-standard-2008.3.0-local-snapshot-01210432 
(oe-user at oe-host) (clang version 10.[    0.000001] sched_clock: 64 bits 
at 125MHz, resolution 8ns, wraps every 4398046511100ns
[    0.000003]          2.560781952 MSFT: kernel boot start
[    0.000484] Machine model: xxx
[    0.009379] earlycon: uart8250 at MMIO32 0x0000000068a10000 (options '')
[    0.009383] printk: bootconsole [uart8250] enabled
[    0.009828] before paging_init()
[    0.009977] before map_mem()
[    0.009978] after memblock_mark_nomap()
[    0.152388] after __map_memblock() for loop
[    0.152391] after __map_memblock() kernel_start, kernel_end
[    0.152393] after memblock_clear_nomap
[    0.152394] after map_mem()
[    0.152401] after paging_init()
[    0.153273] NUMA: No NUMA configuration found
[    0.153278] NUMA: Faking a node at [mem 
0x0000000080000000-0x000000097fffffff]
[    0.153282] NUMA: NODE_DATA [mem 0x97efec5c0-0x97efedfff]
[    0.153316] Zone ranges:
[    0.153319]   Normal   [mem 0x0000000080000000-0x000000097fffffff]
[    0.153323]   Device   empty
[    0.153325] Movable zone start for each node
[    0.153326] Early memory node ranges
[    0.153328]   node   0: [mem 0x0000000080000000-0x000000008adfffff]
[    0.153330]   node   0: [mem 0x000000008ae00000-0x000000008f223fff]
[    0.153331]   node   0: [mem 0x000000008f224000-0x00000000ffffffff]
[    0.153333]   node   0: [mem 0x0000000880000000-0x00000008800fffff]
[    0.153334]   node   0: [mem 0x0000000880100000-0x000000097fffffff]
[    0.153337] Initmem setup node 0 [mem 
0x0000000080000000-0x000000097fffffff]
[    0.153340] On node 0 totalpages: 1572864
[    0.153342]   Normal zone: 24576 pages used for memmap
[    0.153343]   Normal zone: 0 pages reserved
[    0.153345]   Normal zone: 1572864 pages, LIFO batch:63
[    0.154507] crashkernel reserved: 0x0000000968e00000 - 
0x0000000978e00000 (256 MB)

Console output from PXE boot without "crashkernel=256M" boot parameter --
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd083]
[    0.000000] Linux version 
5.10.42.6-xxx-standard-2008.3.0-local-snapshot-01210432 
(oe-user at oe-host) (clang version 10.[    0.000001] sched_clock: 64 bits 
at 125MHz, resolution 8ns, wraps every 4398046511100ns
[    0.000003]         14.765446920 MSFT: kernel boot start
[    0.000484] Machine model: xxx
[    0.009400] earlycon: uart8250 at MMIO32 0x0000000068a10000 (options '')
[    0.009404] printk: bootconsole [uart8250] enabled
[    0.009835] before paging_init()
[    0.009986] before map_mem()
[    0.009987] after memblock_mark_nomap()
[    0.010154] after __map_memblock() for loop
[    0.010156] after __map_memblock() kernel_start, kernel_end
[    0.010158] after memblock_clear_nomap
[    0.010159] after map_mem()
[    0.010163] after paging_init()
[    0.011002] NUMA: No NUMA configuration found
[    0.011005] NUMA: Faking a node at [mem 
0x0000000080000000-0x000000097fffffff]
[    0.011009] NUMA: NODE_DATA [mem 0x97fbc65c0-0x97fbc7fff]
[    0.011037] Zone ranges:
[    0.011038]   Normal   [mem 0x0000000080000000-0x000000097fffffff]
[    0.011041]   Device   empty
[    0.011043] Movable zone start for each node
[    0.011044] Early memory node ranges
[    0.011046]   node   0: [mem 0x0000000080000000-0x000000008adfffff]
[    0.011048]   node   0: [mem 0x000000008ae00000-0x000000008f223fff]
[    0.011049]   node   0: [mem 0x000000008f224000-0x00000000ffffffff]
[    0.011050]   node   0: [mem 0x0000000880000000-0x00000008800fffff]
[    0.011052]   node   0: [mem 0x0000000880100000-0x000000097fffffff]
[    0.011054] Initmem setup node 0 [mem 
0x0000000080000000-0x000000097fffffff]
[    0.011056] On node 0 totalpages: 1572864
[    0.011058]   Normal zone: 24576 pages used for memmap
[    0.011060]   Normal zone: 0 pages reserved
[    0.011061]   Normal zone: 1572864 pages, LIFO batch:63


From quic_collinsd at quicinc.com  Mon Jan 24 15:20:01 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 15:20:01 -0800
Subject: [RESEND PATCH 1/2] dt-bindings: firmware: arm,
 scmi: define support for name based regulators
In-Reply-To: <cover.1639099631.git.quic_collinsd@quicinc.com>
References: <cover.1639099631.git.quic_collinsd@quicinc.com>
Message-ID: <2d78b0f19991f8028d9be913be0a5aefd7d1ee17.1639099631.git.quic_collinsd@quicinc.com>

Allow SCMI regulator subnodes to be specified either by ID using
the "reg" property or by name using the "regulator-name" property.

Name based SCMI regulator specification helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

Signed-off-by: David Collins <quic_collinsd at quicinc.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/firmware/arm,scmi.yaml        | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index 5c4c6782e052..bc4a84fe25d2 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -155,7 +155,7 @@ properties:
           The list of all regulators provided by this SCMI controller.
 
         patternProperties:
-          '^regulators@[0-9a-f]+$':
+          '^regulator.+$':
             type: object
             $ref: "../regulator/regulator.yaml#"
 
@@ -164,8 +164,13 @@ properties:
                 maxItems: 1
                 description: Identifier for the voltage regulator.
 
-            required:
-              - reg
+              regulator-name: true
+
+            anyOf:
+              - required:
+                  - reg
+              - required:
+                  - regulator-name
 
 additionalProperties: false
 
-- 
2.17.1



From quic_collinsd at quicinc.com  Mon Jan 24 15:20:00 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 15:20:00 -0800
Subject: [RESEND PATCH 0/2] regulator: scmi: add support for registering SCMI
 regulators by name
Message-ID: <cover.1639099631.git.quic_collinsd@quicinc.com>

Add support to register SCMI regulator subnodes based on an SCMI
Voltage Domain name specified via the 'regulator-name' device tree
property.  In doing so, make the 'reg' property optional with the
constraint that at least one of 'reg' or 'regulator-name' must be
specified.  If both are specified, then both must match the
Voltage Domain data exposed by the SCMI platform.

Name based SCMI regulator registration helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

David Collins (2):
  dt-bindings: firmware: arm,scmi: define support for name based
    regulators
  regulator: scmi: add support for registering SCMI regulators by name

 .../bindings/firmware/arm,scmi.yaml           | 11 +++-
 drivers/regulator/scmi-regulator.c            | 57 ++++++++++++++++++-
 2 files changed, 62 insertions(+), 6 deletions(-)

-- 
2.17.1



From quic_collinsd at quicinc.com  Mon Jan 24 15:20:02 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 15:20:02 -0800
Subject: [RESEND PATCH 2/2] regulator: scmi: add support for registering SCMI
 regulators by name
In-Reply-To: <cover.1639099631.git.quic_collinsd@quicinc.com>
References: <cover.1639099631.git.quic_collinsd@quicinc.com>
Message-ID: <916966958cc63e9509f94fb263ad8d3c3ec768da.1639099631.git.quic_collinsd@quicinc.com>

Add support to register SCMI regulator subnodes based on an SCMI
Voltage Domain name specified via the 'regulator-name' device tree
property.  In doing so, make the 'reg' property optional with the
constraint that at least one of 'reg' or 'regulator-name' must be
specified.  If both are specified, then both must match the
Voltage Domain data exposed by the SCMI platform.

Name based SCMI regulator registration helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

Signed-off-by: David Collins <quic_collinsd at quicinc.com>
---
 drivers/regulator/scmi-regulator.c | 57 ++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c
index 1f02f60ad136..c3287901975e 100644
--- a/drivers/regulator/scmi-regulator.c
+++ b/drivers/regulator/scmi-regulator.c
@@ -31,6 +31,7 @@
 #include <linux/regulator/of_regulator.h>
 #include <linux/scmi_protocol.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/types.h>
 
 static const struct scmi_voltage_proto_ops *voltage_ops;
@@ -252,16 +253,66 @@ static int scmi_regulator_common_init(struct scmi_regulator *sreg)
 	return 0;
 }
 
+static int scmi_regulator_map_name(struct scmi_protocol_handle *ph,
+				   struct scmi_regulator_info *rinfo,
+				   const char *name)
+{
+	const struct scmi_voltage_info *vinfo;
+	int i;
+
+	for (i = 0; i < rinfo->num_doms; i++) {
+		vinfo = voltage_ops->info_get(ph, i);
+		if (!vinfo)
+			continue;
+		if (!strncmp(vinfo->name, name, sizeof(vinfo->name)))
+			return i;
+	}
+
+	return -ENODEV;
+}
+
 static int process_scmi_regulator_of_node(struct scmi_device *sdev,
 					  struct scmi_protocol_handle *ph,
 					  struct device_node *np,
 					  struct scmi_regulator_info *rinfo)
 {
 	u32 dom, ret;
+	int name_dom;
+	const char *name;
 
-	ret = of_property_read_u32(np, "reg", &dom);
-	if (ret)
-		return ret;
+	dom = rinfo->num_doms;
+	if (of_find_property(np, "reg", NULL)) {
+		ret = of_property_read_u32(np, "reg", &dom);
+		if (ret)
+			return ret;
+
+		if (dom >= rinfo->num_doms)
+			return -ENODEV;
+	}
+
+	if (of_find_property(np, "regulator-name", NULL)) {
+		ret = of_property_read_string(np, "regulator-name", &name);
+		if (ret)
+			return ret;
+
+		name_dom = scmi_regulator_map_name(ph, rinfo, name);
+		if (name_dom < 0) {
+			dev_err(&sdev->dev,
+				"No SCMI Voltage Domain found named %s. Skipping: %s\n",
+				name, np->full_name);
+			return name_dom;
+		}
+
+		if (dom >= rinfo->num_doms)
+			dom = name_dom;
+
+		if (name_dom != dom) {
+			dev_err(&sdev->dev,
+				"SCMI Voltage Domain %s ID mismatch, %u (DT) != %d (firmware). Skipping: %s\n",
+				name, dom, name_dom, np->full_name);
+			return -EINVAL;
+		}
+	}
 
 	if (dom >= rinfo->num_doms)
 		return -ENODEV;
-- 
2.17.1



From broonie at kernel.org  Mon Jan 24 16:10:36 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:36 +0000
Subject: [PATCH v8 00/38] arm64/sme: Initial support for the Scalable Matrix
 Extension
Message-ID: <20220125001114.193425-1-broonie@kernel.org>

This series provides initial support for the ARMv9 Scalable Matrix
Extension (SME).  SME takes the approach used for vectors in SVE and
extends this to provide architectural support for matrix operations.  A
more detailed overview can be found in [1].

For the kernel SME can be thought of as a series of features which are
intended to be used together by applications but operate mostly
orthogonally:

 - The ZA matrix register.
 - Streaming mode, in which ZA can be accessed and a subset of SVE
   features are available.
 - A second vector length, used for streaming mode SVE and ZA and
   controlled using a similar interface to that for SVE.
 - TPIDR2, a new userspace controllable system register intended for use
   by the C library for storing context related to the ZA ABI.

A substantial part of the series is dedicated to refactoring the
existing SVE support so that we don't need to duplicate code for
handling vector lengths and the SVE registers, this involves creating an
array of vector types and making the users take the vector type as a
parameter.  I'm not 100% happy with this but wasn't able to come up with
anything better, duplicating code definitely felt like a bad idea so
this felt like the least bad thing.  If this approach makes sense to
people it might make sense to split this off into a separate series
and/or merge it while the rest is pending review to try to make things a
little more digestable, the series is very large so it'd probably make
things easier to digest if some of the preparatory refactoring could be
merged before the rest is ready.

One feature of the architecture of particular note is that switching
to and from streaming mode may change the size of and invalidate the
contents of the SVE registers, and when in streaming mode the FFR is not
accessible.  This complicates aspects of the ABI like signal handling
and ptrace.

This initial implementation is mainly intended to get the ABI in place,
there are several areas which will be worked on going forwards - some of
these will be blockers, others could be handled in followup serieses:

 - SME is currently not supported for KVM guests, this will be done as a
   followup series.  A host system can use SME and run KVM guests but
   SME is not available in the guests.
 - The KVM host support is done in a very simplistic way, were anyone to
   attempt to use it in production there would be performance impacts on
   hosts with SME support. As part of this we also add enumeration of
   fine grained traps.
 - There is not currently ptrace or signal support TPIDR2, this will be
   done as a followup series.
 - No support is currently provided for scheduler control of SME or SME
   applications, given the size of the SME register state the context
   switch overhead may be noticable so this may be needed especially for
   real time applications.  Similar concerns already exist for larger
   SVE vector lengths but are amplified for SME, particularly as the
   vector length increases.
 - There has been no work on optimising the performance of anything the
   kernel does.

It is not expected that any systems will be encountered that support SME
but not SVE, SME is an ARMv9 feature and SVE is mandatory for ARMv9.
The code attempts to handle any such systems that are encountered but
this hasn't been tested extensively.

v8:
 - Rebase onto v5.17-rc1.
 - Support interoperation with KVM, SME is disabled for KVM guests with
   minimal handling for cleaning up SME state when entering and leaving
   the guest.
 - Document and implement that signal handlers are invoked with ZA and
   streaming mode disabled.
 - Use the RDSVL instruction introduced in EAC2 of the architecture to
   obtain the streaming mode vector length during enumeration, ZA state
   loading/saving and in test programs.
 - Store a pointer to SVCR in fpsimd_last_state and use it in fpsimd_save()
   for interoperation with KVM.
 - Add a test case sme_trap_no_sm checking that we generate a SIGILL
   when using an instruction that requires streaming mode without
   enabling it.
 - Add basic ZA context form validation to testcases helper library.
 - Move signal tests over to validating streaming VL from ZA information.
 - Pulled in patch removing ARRAY_SIZE() so that kselftest builds
   cleanly and to avoid trivial conflicts.
v7:
 - Rebase onto v5.16-rc3.
 - Reduce indentation when supporting custom triggers for signal tests
   as suggested by Catalin.
 - Change to specifying a width for all CPU features rather than adding
   single bit specific infrastructure.
 - Don't require zeroing of non-shared SVE state during syscalls.
v6:
 - Rebase onto v5.16-rc1.
 - Return to disabling TIF_SVE on kernel entry even if we have SME
   state, this avoids the need for KVM to handle the case where TIF_SVE
   is set on guest entry.
 - Add syscall-abi.h to SME updates to syscall-abi, mistakenly omitted
   from commit.
v5:
 - Rebase onto currently merged SVE and kselftest patches.
 - Add support for the FA64 option, introduced in the recently published
   EAC1 update to the specification.
 - Pull in test program for the syscall ABI previously sent separately
   with some revisions and add coverage for the SME ABI.
 - Fix checking for options with 1 bit fields in ID_AA64SMFR0_EL1.
 - Minor fixes and clarifications to the ABI documentation.
v4:
 - Rebase onto merged patches.
 - Remove an uneeded NULL check in vec_proc_do_default_vl().
 - Include patch to factor out utility routines in kselftests written in
   assembler.
 - Specify -ffreestanding when building TPIDR2 test.
v3:
 - Skip FFR rather than predicate registers in sve_flush_live().
 - Don't assume a bool is all zeros in sve_flush_live() as per AAPCS.
 - Don't redundantly specify a zero index when clearing FFR.
v2:
 - Fix several issues with !SME and !SVE configurations.
 - Preserve TPIDR2 when creating a new thread/process unless
   CLONE_SETTLS is set.
 - Report traps due to using features in an invalid mode as SIGILL.
 - Spell out streaming mode behaviour in SVE ABI documentation more
   directly.
 - Document TPIDR2 in the ABI document.
 - Use SMSTART and SMSTOP rather than read/modify/write sequences.
 - Rework logic for exiting streaming mode on syscall.
 - Don't needlessly initialise SVCR on access trap.
 - Always restore SME VL for userspace if SME traps are disabled.
 - Only yield to encourage preemption every 128 iterations in za-test,
   otherwise do a getpid(), and validate SVCR after syscall.
 - Leave streaming mode disabled except when reading the vector length
   in za-test, and disable ZA after detecting a mismatch.
 - Add SME support to vlset.
 - Clarifications and typo fixes in comments.
 - Move sme_alloc() forward declaration back a patch.

[1] https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/scalable-matrix-extension-armv9-a-architecture

Mark Brown (38):
  arm64: cpufeature: Always specify and use a field width for
    capabilities
  arm64: Add feature detection for fine grained traps
  kselftest/arm64: Remove local ARRAY_SIZE() definitions
  arm64/sme: Provide ABI documentation for SME
  arm64/sme: System register and exception syndrome definitions
  arm64/sme: Manually encode SME instructions
  arm64/sme: Early CPU setup for SME
  arm64/sme: Basic enumeration support
  arm64/sme: Identify supported SME vector lengths at boot
  arm64/sme: Implement sysctl to set the default vector length
  arm64/sme: Implement vector length configuration prctl()s
  arm64/sme: Implement support for TPIDR2
  arm64/sme: Implement SVCR context switching
  arm64/sme: Implement streaming SVE context switching
  arm64/sme: Implement ZA context switching
  arm64/sme: Implement traps and syscall handling for SME
  arm64/sme: Disable ZA and streaming mode when handling signals
  arm64/sme: Implement streaming SVE signal handling
  arm64/sme: Implement ZA signal handling
  arm64/sme: Implement ptrace support for streaming mode SVE registers
  arm64/sme: Add ptrace support for ZA
  arm64/sme: Disable streaming mode and ZA when flushing CPU state
  arm64/sme: Save and restore streaming mode over EFI runtime calls
  KVM: arm64: Hide SME system registers from guests
  KVM: arm64: Trap SME usage in guest
  KVM: arm64: Handle SME host state when running guests
  arm64/sme: Provide Kconfig for SME
  kselftest/arm64: sme: Add streaming SME support to vlset
  kselftest/arm64: Add tests for TPIDR2
  kselftest/arm64: Extend vector configuration API tests to cover SME
  kselftest/arm64: sme: Provide streaming mode SVE stress test
  kselftest/arm64: signal: Allow tests to be incompatible with features
  kselftest/arm64: signal: Handle ZA signal context in core code
  kselftest/arm64: Add stress test for SME ZA context switching
  kselftest/arm64: signal: Add SME signal handling tests
  kselftest/arm64: Add streaming SVE to SVE ptrace tests
  kselftest/arm64: Add coverage for the ZA ptrace interface
  kselftest/arm64: Add SME support to syscall ABI test

 Documentation/arm64/elf_hwcaps.rst            |  33 +
 Documentation/arm64/index.rst                 |   1 +
 Documentation/arm64/sme.rst                   | 432 +++++++++++++
 Documentation/arm64/sve.rst                   |  70 ++-
 arch/arm64/Kconfig                            |  11 +
 arch/arm64/include/asm/cpu.h                  |   4 +
 arch/arm64/include/asm/cpufeature.h           |  25 +
 arch/arm64/include/asm/el2_setup.h            |  64 +-
 arch/arm64/include/asm/esr.h                  |  13 +-
 arch/arm64/include/asm/exception.h            |   1 +
 arch/arm64/include/asm/fpsimd.h               | 110 +++-
 arch/arm64/include/asm/fpsimdmacros.h         |  86 +++
 arch/arm64/include/asm/hwcap.h                |   8 +
 arch/arm64/include/asm/kvm_arm.h              |   1 +
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/processor.h            |  18 +-
 arch/arm64/include/asm/sysreg.h               |  64 ++
 arch/arm64/include/asm/thread_info.h          |   2 +
 arch/arm64/include/uapi/asm/hwcap.h           |   8 +
 arch/arm64/include/uapi/asm/ptrace.h          |  69 ++-
 arch/arm64/include/uapi/asm/sigcontext.h      |  55 +-
 arch/arm64/kernel/cpufeature.c                | 284 +++++++--
 arch/arm64/kernel/cpuinfo.c                   |  13 +
 arch/arm64/kernel/entry-common.c              |  11 +
 arch/arm64/kernel/entry-fpsimd.S              |  36 ++
 arch/arm64/kernel/fpsimd.c                    | 585 ++++++++++++++++--
 arch/arm64/kernel/process.c                   |  28 +-
 arch/arm64/kernel/ptrace.c                    | 356 +++++++++--
 arch/arm64/kernel/signal.c                    | 194 +++++-
 arch/arm64/kernel/syscall.c                   |  34 +-
 arch/arm64/kernel/traps.c                     |   1 +
 arch/arm64/kvm/fpsimd.c                       |  45 +-
 arch/arm64/kvm/hyp/nvhe/switch.c              |  30 +
 arch/arm64/kvm/hyp/vhe/switch.c               |  10 +-
 arch/arm64/kvm/sys_regs.c                     |   9 +-
 arch/arm64/tools/cpucaps                      |   3 +
 include/uapi/linux/elf.h                      |   2 +
 include/uapi/linux/prctl.h                    |   9 +
 kernel/sys.c                                  |  12 +
 tools/testing/selftests/arm64/abi/.gitignore  |   1 +
 tools/testing/selftests/arm64/abi/Makefile    |   9 +-
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 ++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 205 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 +
 tools/testing/selftests/arm64/abi/tpidr2.c    | 298 +++++++++
 tools/testing/selftests/arm64/fp/.gitignore   |   4 +
 tools/testing/selftests/arm64/fp/Makefile     |  12 +-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   |  14 +
 tools/testing/selftests/arm64/fp/rdvl.S       |   8 +
 tools/testing/selftests/arm64/fp/rdvl.h       |   1 +
 tools/testing/selftests/arm64/fp/ssve-stress  |  59 ++
 tools/testing/selftests/arm64/fp/sve-ptrace.c |  13 +-
 tools/testing/selftests/arm64/fp/sve-test.S   |  30 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c |  10 +
 tools/testing/selftests/arm64/fp/vlset.c      |  10 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c  | 354 +++++++++++
 tools/testing/selftests/arm64/fp/za-stress    |  59 ++
 tools/testing/selftests/arm64/fp/za-test.S    | 426 +++++++++++++
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   5 +
 .../arm64/signal/test_signals_utils.c         |  40 +-
 .../arm64/signal/test_signals_utils.h         |   2 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 ++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 ++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++
 .../arm64/signal/testcases/testcases.c        |  36 ++
 .../arm64/signal/testcases/testcases.h        |   3 +-
 70 files changed, 4590 insertions(+), 244 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:37 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:37 +0000
Subject: [PATCH v8 01/38] arm64: cpufeature: Always specify and use a field
 width for capabilities
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-2-broonie@kernel.org>

Since all the fields in the main ID registers are 4 bits wide we have up
until now not bothered specifying the width in the code. Since we now
wish to use this mechanism to enumerate features from the floating point
feature registers which do not follow this pattern add a width to the
table.  This means updating all the existing table entries but makes it
less likely that we run into issues in future due to implicitly assuming
a 4 bit width.

Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/cpufeature.h |   1 +
 arch/arm64/kernel/cpufeature.c      | 167 +++++++++++++++++-----------
 2 files changed, 102 insertions(+), 66 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..2728abd9cae4 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
 		struct {	/* Feature register checking */
 			u32 sys_reg;
 			u8 field_pos;
+			u8 field_width;
 			u8 min_field_value;
 			u8 hwcap_type;
 			bool sign;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..d9f09e40aaf6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1307,7 +1307,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
 {
-	int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
+	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+						    entry->field_width,
+						    entry->sign);
 
 	return val >= entry->min_field_value;
 }
@@ -1952,6 +1954,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR0_EL1,
 		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -1963,6 +1966,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_pan,
@@ -1976,6 +1980,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 3,
 	},
@@ -1988,6 +1993,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 2,
 	},
@@ -2012,6 +2018,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 #ifdef CONFIG_KVM
@@ -2023,6 +2030,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL1_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 	{
@@ -2043,6 +2051,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		 */
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_CSV3_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = unmap_kernel_at_el0,
 		.cpu_enable = kpti_install_ng_mappings,
@@ -2062,6 +2071,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2072,6 +2082,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 	},
 #endif
@@ -2083,6 +2094,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_SVE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_SVE,
 		.matches = has_cpuid_feature,
 		.cpu_enable = sve_kernel_enable,
@@ -2097,6 +2109,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
 		.cpu_enable = cpu_clear_disr,
 	},
@@ -2115,6 +2128,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_AMU_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_AMU,
 		.cpu_enable = cpu_amu_enable,
 	},
@@ -2139,6 +2153,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_FWB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 		.cpu_enable = cpu_has_fwb,
@@ -2150,6 +2165,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_TTL_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 	},
@@ -2160,6 +2176,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_TLB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64ISAR0_TLB_RANGE,
 	},
@@ -2178,6 +2195,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 		.matches = has_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
@@ -2190,6 +2208,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_CRC32_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2199,6 +2218,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_SSBS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
 	},
@@ -2211,6 +2231,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_CNP_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_cnp,
 	},
@@ -2222,6 +2243,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_SB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2233,6 +2255,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_APA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2243,6 +2266,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_API_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_API_IMP_DEF,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2258,6 +2282,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED,
 		.matches = has_cpuid_feature,
 	},
@@ -2268,6 +2293,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPI_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPI_IMP_DEF,
 		.matches = has_cpuid_feature,
 	},
@@ -2288,6 +2314,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = can_use_gic_priorities,
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_GIC_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2299,6 +2326,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
+		.field_width = 4,
 		.field_pos = ID_AA64MMFR2_E0PD_SHIFT,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
@@ -2313,6 +2341,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2330,6 +2359,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpu_enable = bti_enable,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_BT_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_BT_BTI,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2342,6 +2372,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE,
 		.sign = FTR_UNSIGNED,
 		.cpu_enable = cpu_enable_mte,
@@ -2353,6 +2384,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE_ASYMM,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2364,16 +2396,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+		.field_width = 4,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
 	{},
 };
 
-#define HWCAP_CPUID_MATCH(reg, field, s, min_value)				\
+#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value)			\
 		.matches = has_cpuid_feature,					\
 		.sys_reg = reg,							\
 		.field_pos = field,						\
+		.field_width = width,						\
 		.sign = s,							\
 		.min_field_value = min_value,
 
@@ -2383,10 +2417,10 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.hwcap_type = cap_type,						\
 		.hwcap = cap,							\
 
-#define HWCAP_CAP(reg, field, s, min_value, cap_type, cap)			\
+#define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap)		\
 	{									\
 		__HWCAP_CAP(#cap, cap_type, cap)				\
-		HWCAP_CPUID_MATCH(reg, field, s, min_value)			\
+		HWCAP_CPUID_MATCH(reg, field, width, s, min_value) 		\
 	}
 
 #define HWCAP_MULTI_CAP(list, cap_type, cap)					\
@@ -2406,11 +2440,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
+				  4, FTR_UNSIGNED,
+				  ID_AA64ISAR1_APA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
 	},
 	{},
 };
@@ -2418,77 +2453,77 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
 	},
 	{},
 };
 #endif
 
 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
-	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
 #endif
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
 #endif
 #ifdef CONFIG_ARM64_MTE
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
 #endif /* CONFIG_ARM64_MTE */
-	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
-	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
-	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
+	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
+	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
 	{},
 };
 
@@ -2517,15 +2552,15 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope)
 static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
 #ifdef CONFIG_COMPAT
 	HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON),
-	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
+	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
 	/* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
 #endif
 	{},
 };
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:38 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:38 +0000
Subject: [PATCH v8 02/38] arm64: Add feature detection for fine grained traps
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-3-broonie@kernel.org>

Some of the traps for nVHE SME support are provided as fine grained traps
so add detection of fine grained traps in order to allow us to guard usage.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/cpufeature.c | 11 +++++++++++
 arch/arm64/tools/cpucaps       |  1 +
 2 files changed, 12 insertions(+)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d9f09e40aaf6..ec060db1dcf0 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2400,6 +2400,17 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+	{
+		.desc = "Fine Grained Traps",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_HAS_FGT,
+		.sys_reg = SYS_ID_AA64MMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR0_FGT_SHIFT,
+		.field_width = 4,
+		.min_field_value = 1,
+		.matches = has_cpuid_feature,
+	},
 	{},
 };
 
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..b3ada80aa48d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -20,6 +20,7 @@ HAS_DCPOP
 HAS_E0PD
 HAS_ECV
 HAS_EPAN
+HAS_FGT
 HAS_GENERIC_AUTH
 HAS_GENERIC_AUTH_ARCH
 HAS_GENERIC_AUTH_IMP_DEF
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:39 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:39 +0000
Subject: [PATCH v8 03/38] kselftest/arm64: Remove local ARRAY_SIZE()
 definitions
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-4-broonie@kernel.org>

An ARRAY_SIZE() has been added to kselftest.h so remove the local versions
in some of the arm64 selftests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/syscall-abi.c | 1 -
 tools/testing/selftests/arm64/fp/sve-ptrace.c   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index d8eeeafb50dc..1e13b7523918 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,7 +18,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
 extern void do_syscall(int sve_vl);
diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index af798b9d232c..90ba1d6a6781 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -21,8 +21,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
 #ifndef NT_ARM_SVE
 #define NT_ARM_SVE 0x405
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:40 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:40 +0000
Subject: [PATCH v8 04/38] arm64/sme: Provide ABI documentation for SME
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-5-broonie@kernel.org>

Provide ABI documentation for SME similar to that for SVE. Due to the very
large overlap around streaming SVE mode in both implementation and
interfaces documentation for streaming mode SVE is added to the SVE
document rather than the SME one.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/index.rst |   1 +
 Documentation/arm64/sme.rst   | 432 ++++++++++++++++++++++++++++++++++
 Documentation/arm64/sve.rst   |  70 +++++-
 3 files changed, 493 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst

diff --git a/Documentation/arm64/index.rst b/Documentation/arm64/index.rst
index 4f840bac083e..ae21f8118830 100644
--- a/Documentation/arm64/index.rst
+++ b/Documentation/arm64/index.rst
@@ -21,6 +21,7 @@ ARM64 Architecture
     perf
     pointer-authentication
     silicon-errata
+    sme
     sve
     tagged-address-abi
     tagged-pointers
diff --git a/Documentation/arm64/sme.rst b/Documentation/arm64/sme.rst
new file mode 100644
index 000000000000..15df3157c592
--- /dev/null
+++ b/Documentation/arm64/sme.rst
@@ -0,0 +1,432 @@
+===================================================
+Scalable Matrix Extension support for AArch64 Linux
+===================================================
+
+This document outlines briefly the interface provided to userspace by Linux in
+order to support use of the ARM Scalable Matrix Extension (SME).
+
+This is an outline of the most important features and issues only and not
+intended to be exhaustive.  It should be read in conjunction with the SVE
+documentation in sve.rst which provides details on the Streaming SVE mode
+included in SME.
+
+This document does not aim to describe the SME architecture or programmer's
+model.  To aid understanding, a minimal description of relevant programmer's
+model features for SME is included in Appendix A.
+
+
+1.  General
+-----------
+
+* PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA
+  register state and TPIDR2_EL0 are tracked per thread.
+
+* The presence of SME is reported to userspace via HWCAP2_SME in the aux vector
+  AT_HWCAP2 entry.  Presence of this flag implies the presence of the SME
+  instructions and registers, and the Linux-specific system interfaces
+  described in this document.  SME is reported in /proc/cpuinfo as "sme".
+
+* Support for the execution of SME instructions in userspace can also be
+  detected by reading the CPU ID register ID_AA64PFR1_EL1 using an MRS
+  instruction, and checking that the value of the SME field is nonzero. [3]
+
+  It does not guarantee the presence of the system interfaces described in the
+  following sections: software that needs to verify that those interfaces are
+  present must check for HWCAP2_SME instead.
+
+* There are a number of optional SME features, presence of these is reported
+  through AT_HWCAP2 through:
+
+	HWCAP2_SME_I16I64
+	HWCAP2_SME_F64F64
+	HWCAP2_SME_I8I32
+	HWCAP2_SME_F16F32
+	HWCAP2_SME_B16F32
+	HWCAP2_SME_F32F32
+	HWCAP2_SME_FA64
+
+  This list may be extended over time as the SME architecture evolves.
+
+  These extensions are also reported via the CPU ID register ID_AA64SMFR0_EL1,
+  which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
+  cpu-feature-registers.txt for details.
+
+* Debuggers should restrict themselves to interacting with the target via the
+  NT_ARM_SVE, NT_ARM_SSVE and NT_ARM_ZA regsets.  The recommended way
+  of detecting support for these regsets is to connect to a target process
+  first and then attempt a
+
+	ptrace(PTRACE_GETREGSET, pid, NT_ARM_<regset>, &iov).
+
+* Whenever ZA register values are exchanged in memory between userspace and
+  the kernel, the register value is encoded in memory as a series of horizontal
+  vectors from 0 to VL/8-1 stored in the same endianness invariant format as is
+  used for SVE vectors.
+
+* On thread creation TPIDR2_EL0 is preserved unless CLONE_SETTLS is specified,
+  in which case it is set to 0.
+
+2.  Vector lengths
+------------------
+
+SME defines a second vector length similar to the SVE vector length which is
+controls the size of the streaming mode SVE vectors and the ZA matrix array.
+The ZA matrix is square with each side having as many bytes as a SVE vector.
+
+
+3.  Sharing of streaming and non-streaming mode SVE state
+---------------------------------------------------------
+
+It is implementation defined which if any parts of the SVE state are shared
+between streaming and non-streaming modes.  When switching between modes
+via software interfaces such as ptrace if no register content is provided as
+part of switching no state will be assumed to be shared and everything will
+be zeroed.
+
+
+4.  System call behaviour
+-------------------------
+
+* On syscall PSTATE.ZA is preserved, if PSTATE.ZA==1 then the contents of the
+  ZA matrix are preserved.
+
+* On syscall PSTATE.SM will be cleared and the SVE registers will be handled
+  as normal.
+
+* Neither the SVE registers nor ZA are used to pass arguments to or receive
+  results from any syscall.
+
+* On creation fork() or clone() the newly created process will have PSTATE.SM
+  and PSTATE.ZA cleared.
+
+* All other SME state of a thread, including the currently configured vector
+  length, the state of the PR_SME_VL_INHERIT flag, and the deferred vector
+  length (if any), is preserved across all syscalls, subject to the specific
+  exceptions for execve() described in section 6.
+
+
+5.  Signal handling
+-------------------
+
+* Signal handlers are invoked with streaming mode and ZA disabled.
+
+* A new signal frame record za_context encodes the ZA register contents on
+  signal delivery. [1]
+
+* The signal frame record for ZA always contains basic metadata, in particular
+  the thread's vector length (in za_context.vl).
+
+* The ZA matrix may or may not be included in the record, depending on
+  the value of PSTATE.ZA.  The registers are present if and only if:
+  za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+  in which case PSTATE.ZA == 1.
+
+* If matrix data is present, the remainder of the record has a vl-dependent
+  size and layout.  Macros ZA_SIG_* are defined [1] to facilitate access to
+  them.
+
+* The matrix is stored as a series of horizontal vectors in the same format as
+  is used for SVE vectors.
+
+* If the ZA context is too big to fit in sigcontext.__reserved[], then extra
+  space is allocated on the stack, an extra_context record is written in
+  __reserved[] referencing this space.  za_context is then written in the
+  extra space.  Refer to [1] for further details about this mechanism.
+
+
+5.  Signal return
+-----------------
+
+When returning from a signal handler:
+
+* If there is no za_context record in the signal frame, or if the record is
+  present but contains no register data as desribed in the previous section,
+  then ZA is disabled.
+
+* If za_context is present in the signal frame and contains matrix data then
+  PSTATE.ZA is set to 1 and ZA is populated with the specified data.
+
+* The vector length cannot be changed via signal return.  If za_context.vl in
+  the signal frame does not match the current vector length, the signal return
+  attempt is treated as illegal, resulting in a forced SIGSEGV.
+
+
+6.  prctl extensions
+--------------------
+
+Some new prctl() calls are added to allow programs to manage the SME vector
+length:
+
+prctl(PR_SME_SET_VL, unsigned long arg)
+
+    Sets the vector length of the calling thread and related flags, where
+    arg == vl | flags.  Other threads of the calling process are unaffected.
+
+    vl is the desired vector length, where sve_vl_valid(vl) must be true.
+
+    flags:
+
+	PR_SME_VL_INHERIT
+
+	    Inherit the current vector length across execve().  Otherwise, the
+	    vector length is reset to the system default at execve().  (See
+	    Section 9.)
+
+	PR_SME_SET_VL_ONEXEC
+
+	    Defer the requested vector length change until the next execve()
+	    performed by this thread.
+
+	    The effect is equivalent to implicit exceution of the following
+	    call immediately after the next execve() (if any) by the thread:
+
+		prctl(PR_SME_SET_VL, arg & ~PR_SME_SET_VL_ONEXEC)
+
+	    This allows launching of a new program with a different vector
+	    length, while avoiding runtime side effects in the caller.
+
+	    Without PR_SME_SET_VL_ONEXEC, the requested change takes effect
+	    immediately.
+
+
+    Return value: a nonnegative on success, or a negative value on error:
+	EINVAL: SME not supported, invalid vector length requested, or
+	    invalid flags.
+
+
+    On success:
+
+    * Either the calling thread's vector length or the deferred vector length
+      to be applied at the next execve() by the thread (dependent on whether
+      PR_SME_SET_VL_ONEXEC is present in arg), is set to the largest value
+      supported by the system that is less than or equal to vl.  If vl ==
+      SVE_VL_MAX, the value set will be the largest value supported by the
+      system.
+
+    * Any previously outstanding deferred vector length change in the calling
+      thread is cancelled.
+
+    * The returned value describes the resulting configuration, encoded as for
+      PR_SME_GET_VL.  The vector length reported in this value is the new
+      current vector length for this thread if PR_SME_SET_VL_ONEXEC was not
+      present in arg; otherwise, the reported vector length is the deferred
+      vector length that will be applied at the next execve() by the calling
+      thread.
+
+    * Changing the vector length causes all of ZA, P0..P15, FFR and all bits of
+      Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
+      unspecified, including both streaming and non-streaming SVE state.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+    * Changing the vector length causes PSTATE.ZA and PSTATE.SM to be cleared.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+
+prctl(PR_SME_GET_VL)
+
+    Gets the vector length of the calling thread.
+
+    The following flag may be OR-ed into the result:
+
+	PR_SME_VL_INHERIT
+
+	    Vector length will be inherited across execve().
+
+    There is no way to determine whether there is an outstanding deferred
+    vector length change (which would only normally be the case between a
+    fork() or vfork() and the corresponding execve() in typical use).
+
+    To extract the vector length from the result, bitwise and it with
+    PR_SME_VL_LEN_MASK.
+
+    Return value: a nonnegative value on success, or a negative value on error:
+	EINVAL: SME not supported.
+
+
+7.  ptrace extensions
+---------------------
+
+* A new regset NT_ARM_SSVE is defined for access to streaming mode SVE
+  state via PTRACE_GETREGSET and  PTRACE_SETREGSET, this is documented in
+  sve.rst.
+
+* A new regset NT_ARM_ZA is defined for ZA state for access to ZA state via
+  PTRACE_GETREGSET and PTRACE_SETREGSET.
+
+  Refer to [2] for definitions.
+
+The regset data starts with struct user_za_header, containing:
+
+    size
+
+	Size of the complete regset, in bytes.
+	This depends on vl and possibly on other things in the future.
+
+	If a call to PTRACE_GETREGSET requests less data than the value of
+	size, the caller can allocate a larger buffer and retry in order to
+	read the complete regset.
+
+    max_size
+
+	Maximum size in bytes that the regset can grow to for the target
+	thread.  The regset won't grow bigger than this even if the target
+	thread changes its vector length etc.
+
+    vl
+
+	Target thread's current streaming vector length, in bytes.
+
+    max_vl
+
+	Maximum possible streaming vector length for the target thread.
+
+    flags
+
+	Zero or more of the following flags, which have the same
+	meaning and behaviour as the corresponding PR_SET_VL_* flags:
+
+	    SME_PT_VL_INHERIT
+
+	    SME_PT_VL_ONEXEC (SETREGSET only).
+
+* The effects of changing the vector length and/or flags are equivalent to
+  those documented for PR_SME_SET_VL.
+
+  The caller must make a further GETREGSET call if it needs to know what VL is
+  actually set by SETREGSET, unless is it known in advance that the requested
+  VL is supported.
+
+* The size and layout of the payload depends on the header fields.  The
+  SME_PT_ZA_*() macros are provided to facilitate access to the data.
+
+* In either case, for SETREGSET it is permissible to omit the payload, in which
+  case the vector length and flags are changed and PSTATE.ZA is set to 0
+  (along with any consequences of those changes).  If a payload is provided
+  then PSTATE.ZA will be set to 1.
+
+* For SETREGSET, if the requested VL is not supported, the effect will be the
+  same as if the payload were omitted, except that an EIO error is reported.
+  No attempt is made to translate the payload data to the correct layout
+  for the vector length actually set.  It is up to the caller to translate the
+  payload layout for the actual VL and retry.
+
+* The effect of writing a partial, incomplete payload is unspecified.
+
+
+8.  ELF coredump extensions
+---------------------------
+
+* NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
+
+* A NT_ARM_ZA note will be added to each coredump for each thread of the
+  dumped process.  The contents will be equivalent to the data that would have
+  been read if a PTRACE_GETREGSET of NT_ARM_ZA were executed for each thread
+  when the coredump was generated.
+
+
+9.  System runtime configuration
+--------------------------------
+
+* To mitigate the ABI impact of expansion of the signal frame, a policy
+  mechanism is provided for administrators, distro maintainers and developers
+  to set the default vector length for userspace processes:
+
+/proc/sys/abi/sme_default_vector_length
+
+    Writing the text representation of an integer to this file sets the system
+    default vector length to the specified value, unless the value is greater
+    than the maximum vector length supported by the system in which case the
+    default vector length is set to that maximum.
+
+    The result can be determined by reopening the file and reading its
+    contents.
+
+    At boot, the default vector length is initially set to 32 or the maximum
+    supported vector length, whichever is smaller and supported.  This
+    determines the initial vector length of the init process (PID 1).
+
+    Reading this file returns the current system default vector length.
+
+* At every execve() call, the new vector length of the new process is set to
+  the system default vector length, unless
+
+    * PR_SME_VL_INHERIT (or equivalently SME_PT_VL_INHERIT) is set for the
+      calling thread, or
+
+    * a deferred vector length change is pending, established via the
+      PR_SME_SET_VL_ONEXEC flag (or SME_PT_VL_ONEXEC).
+
+* Modifying the system default vector length does not affect the vector length
+  of any existing process or thread that does not make an execve() call.
+
+
+Appendix A.  SME programmer's model (informative)
+=================================================
+
+This section provides a minimal description of the additions made by SVE to the
+ARMv8-A programmer's model that are relevant to this document.
+
+Note: This section is for information only and not intended to be complete or
+to replace any architectural specification.
+
+A.1.  Registers
+---------------
+
+In A64 state, SME adds the following:
+
+* A new mode, streaming mode, in which a subset of the normal FPSIMD and SVE
+  features are available.  When supported EL0 software may enter and leave
+  streaming mode at any time.
+
+  For best system performance it is strongly encouraged for software to enable
+  streaming mode only when it is actively being used.
+
+* A new vector length controlling the size of ZA and the Z registers when in
+  streaming mode, separately to the vector length used for SVE when not in
+  streaming mode.  There is no requirement that either the currently selected
+  vector length or the set of vector lengths supported for the two modes in
+  a given system have any relationship.  The streaming mode vector length
+  is referred to as SVL.
+
+* A new ZA matrix register.  This is a square matrix of SVLxSVL bits.  Most
+  operations on ZA require that streaming mode be enabled but ZA can be
+  enabled without streaming mode in order to load, save and retain data.
+
+  For best system performance it is strongly encouraged for software to enable
+  ZA only when it is actively being used.
+
+* Two new 1 bit fields in PSTATE which may be controlled via the SMSTART and
+  SMSTOP instructions or by access to the SVCR system register:
+
+  * PSTATE.ZA, if this is 1 then the ZA matrix is accessible and has valid
+    data while if it is 0 then ZA can not be accessed.  When PSTATE.ZA is
+    changed from 0 to 1 all bits in ZA are cleared.
+
+  * PSTATE.SM, if this is 1 then the PE is in streaming mode.  When the value
+    of PSTATE.SM is changed then it is implementation defined if the subset
+    of the floating point register bits valid in both modes may be retained.
+    Any other bits will be cleared.
+
+
+References
+==========
+
+[1] arch/arm64/include/uapi/asm/sigcontext.h
+    AArch64 Linux signal ABI definitions
+
+[2] arch/arm64/include/uapi/asm/ptrace.h
+    AArch64 Linux ptrace ABI definitions
+
+[3] Documentation/arm64/cpu-feature-registers.rst
+
+[4] ARM IHI0055C
+    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
+    http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+    Procedure Call Standard for the ARM 64-bit Architecture (AArch64)
diff --git a/Documentation/arm64/sve.rst b/Documentation/arm64/sve.rst
index 9d9a4de5bc34..93c2c2990584 100644
--- a/Documentation/arm64/sve.rst
+++ b/Documentation/arm64/sve.rst
@@ -7,7 +7,9 @@ Author: Dave Martin <Dave.Martin at arm.com>
 Date:   4 August 2017
 
 This document outlines briefly the interface provided to userspace by Linux in
-order to support use of the ARM Scalable Vector Extension (SVE).
+order to support use of the ARM Scalable Vector Extension (SVE), including
+interactions with Streaming SVE mode added by the Scalable Matrix Extension
+(SME).
 
 This is an outline of the most important features and issues only and not
 intended to be exhaustive.
@@ -23,6 +25,10 @@ model features for SVE is included in Appendix A.
 * SVE registers Z0..Z31, P0..P15 and FFR and the current vector length VL, are
   tracked per-thread.
 
+* In streaming mode FFR is not accessible unless HWCAP2_SME_FA64 is present
+  in the system, when it is not supported and these interfaces are used to
+  access streaming mode FFR is read and written as zero.
+
 * The presence of SVE is reported to userspace via HWCAP_SVE in the aux vector
   AT_HWCAP entry.  Presence of this flag implies the presence of the SVE
   instructions and registers, and the Linux-specific system interfaces
@@ -53,10 +59,19 @@ model features for SVE is included in Appendix A.
   which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
   cpu-feature-registers.txt for details.
 
+* On hardware that supports the SME extensions, HWCAP2_SME will also be
+  reported in the AT_HWCAP2 aux vector entry.  Among other things SME adds
+  streaming mode which provides a subset of the SVE feature set using a
+  separate SME vector length and the same Z/V registers.  See sme.rst
+  for more details.
+
 * Debuggers should restrict themselves to interacting with the target via the
   NT_ARM_SVE regset.  The recommended way of detecting support for this regset
   is to connect to a target process first and then attempt a
-  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).
+  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).  Note that when SME is
+  present and streaming SVE mode is in use the FPSIMD subset of registers
+  will be read via NT_ARM_SVE and NT_ARM_SVE writes will exit streaming mode
+  in the target.
 
 * Whenever SVE scalable register values (Zn, Pn, FFR) are exchanged in memory
   between userspace and the kernel, the register value is encoded in memory in
@@ -126,6 +141,11 @@ the SVE instruction set architecture.
   are only present in fpsimd_context.  For convenience, the content of V0..V31
   is duplicated between sve_context and fpsimd_context.
 
+* The record contains a flag field which includes a flag SVE_SIG_FLAG_SM which
+  if set indicates that the thread is in streaming mode and the vector length
+  and register data (if present) describe the streaming SVE data and vector
+  length.
+
 * The signal frame record for SVE always contains basic metadata, in particular
   the thread's vector length (in sve_context.vl).
 
@@ -170,6 +190,11 @@ When returning from a signal handler:
   the signal frame does not match the current vector length, the signal return
   attempt is treated as illegal, resulting in a forced SIGSEGV.
 
+* It is permitted to enter or leave streaming mode by setting or clearing
+  the SVE_SIG_FLAG_SM flag but applications should take care to ensure that
+  when doing so sve_context.vl and any register data are appropriate for the
+  vector length in the new mode.
+
 
 6.  prctl extensions
 --------------------
@@ -265,8 +290,14 @@ prctl(PR_SVE_GET_VL)
 7.  ptrace extensions
 ---------------------
 
-* A new regset NT_ARM_SVE is defined for use with PTRACE_GETREGSET and
-  PTRACE_SETREGSET.
+* New regsets NT_ARM_SVE and NT_ARM_SSVE are defined for use with
+  PTRACE_GETREGSET and PTRACE_SETREGSET. NT_ARM_SSVE describes the
+  streaming mode SVE registers and NT_ARM_SVE describes the
+  non-streaming mode SVE registers.
+
+  In this description a register set is referred to as being "live" when
+  the target is in the appropriate streaming or non-streaming mode and is
+  using data beyond the subset shared with the FPSIMD Vn registers.
 
   Refer to [2] for definitions.
 
@@ -297,7 +328,7 @@ The regset data starts with struct user_sve_header, containing:
 
     flags
 
-	either
+	at most one of
 
 	    SVE_PT_REGS_FPSIMD
 
@@ -331,6 +362,10 @@ The regset data starts with struct user_sve_header, containing:
 
 	    SVE_PT_VL_ONEXEC (SETREGSET only).
 
+	If neither FPSIMD nor SVE flags are provided then no register
+	payload is available, this is only possible when SME is implemented.
+
+
 * The effects of changing the vector length and/or flags are equivalent to
   those documented for PR_SVE_SET_VL.
 
@@ -346,6 +381,13 @@ The regset data starts with struct user_sve_header, containing:
   case only the vector length and flags are changed (along with any
   consequences of those changes).
 
+* In systems supporting SME when in streaming mode a GETREGSET for
+  NT_REG_SVE will return only the user_sve_header with no register data,
+  similarly a GETREGSET for NT_REG_SSVE will not return any register data
+  when not in streaming mode.
+
+* A GETREGSET for NT_ARM_SSVE will never return SVE_PT_REGS_FPSIMD.
+
 * For SETREGSET, if an SVE_PT_REGS_SVE payload is present and the
   requested VL is not supported, the effect will be the same as if the
   payload were omitted, except that an EIO error is reported.  No
@@ -355,17 +397,25 @@ The regset data starts with struct user_sve_header, containing:
   unspecified.  It is up to the caller to translate the payload layout
   for the actual VL and retry.
 
+* Where SME is implemented it is not possible to GETREGSET the register
+  state for normal SVE when in streaming mode, nor the streaming mode
+  register state when in normal mode, regardless of the implementation defined
+  behaviour of the hardware for sharing data between the two modes.
+
+* Any SETREGSET of NT_ARM_SVE will exit streaming mode if the target was in
+  streaming mode and any SETREGSET of NT_ARM_SSVE will enter streaming mode
+  if the target was not in streaming mode.
+
 * The effect of writing a partial, incomplete payload is unspecified.
 
 
 8.  ELF coredump extensions
 ---------------------------
 
-* A NT_ARM_SVE note will be added to each coredump for each thread of the
-  dumped process.  The contents will be equivalent to the data that would have
-  been read if a PTRACE_GETREGSET of NT_ARM_SVE were executed for each thread
-  when the coredump was generated.
-
+* NT_ARM_SVE and NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
 
 9.  System runtime configuration
 --------------------------------
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:41 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:41 +0000
Subject: [PATCH v8 05/38] arm64/sme: System register and exception syndrome
 definitions
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-6-broonie@kernel.org>

The arm64 Scalable Matrix Extension (SME) adds some new system registers,
fields in existing system registers and exception syndromes. This patch
adds definitions for these for use in future patches implementing support
for this extension.

Since SME will be the first user of FEAT_HCX in the kernel also include
the definitions for enumerating it and the HCRX system register it adds.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h     | 12 +++++-
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/include/asm/sysreg.h  | 64 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/traps.c        |  1 +
 4 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d52a0b269ee8..43872e0cfd1e 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -37,7 +37,8 @@
 #define ESR_ELx_EC_ERET		(0x1a)	/* EL2 only */
 /* Unallocated EC: 0x1B */
 #define ESR_ELx_EC_FPAC		(0x1C)	/* EL1 and above */
-/* Unallocated EC: 0x1D - 0x1E */
+#define ESR_ELx_EC_SME		(0x1D)
+/* Unallocated EC: 0x1E */
 #define ESR_ELx_EC_IMP_DEF	(0x1f)	/* EL3 only */
 #define ESR_ELx_EC_IABT_LOW	(0x20)
 #define ESR_ELx_EC_IABT_CUR	(0x21)
@@ -327,6 +328,15 @@
 #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ	(ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\
 					 ESR_ELx_CP15_32_ISS_DIR_READ)
 
+/*
+ * ISS values for SME traps
+ */
+
+#define ESR_ELx_SME_ISS_SME_DISABLED	0
+#define ESR_ELx_SME_ISS_ILL		1
+#define ESR_ELx_SME_ISS_SM_DISABLED	2
+#define ESR_ELx_SME_ISS_ZA_DISABLED	3
+
 #ifndef __ASSEMBLY__
 #include <asm/types.h>
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..a741b1e7823c 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -279,6 +279,7 @@
 #define CPTR_EL2_TCPAC	(1U << 31)
 #define CPTR_EL2_TAM	(1 << 30)
 #define CPTR_EL2_TTA	(1 << 20)
+#define CPTR_EL2_TSM	(1 << 12)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
 #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..189e2d637593 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -173,6 +173,7 @@
 #define SYS_ID_AA64PFR0_EL1		sys_reg(3, 0, 0, 4, 0)
 #define SYS_ID_AA64PFR1_EL1		sys_reg(3, 0, 0, 4, 1)
 #define SYS_ID_AA64ZFR0_EL1		sys_reg(3, 0, 0, 4, 4)
+#define SYS_ID_AA64SMFR0_EL1		sys_reg(3, 0, 0, 4, 5)
 
 #define SYS_ID_AA64DFR0_EL1		sys_reg(3, 0, 0, 5, 0)
 #define SYS_ID_AA64DFR1_EL1		sys_reg(3, 0, 0, 5, 1)
@@ -196,6 +197,8 @@
 
 #define SYS_ZCR_EL1			sys_reg(3, 0, 1, 2, 0)
 #define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
+#define SYS_SMPRI_EL1			sys_reg(3, 0, 1, 2, 4)
+#define SYS_SMCR_EL1			sys_reg(3, 0, 1, 2, 6)
 
 #define SYS_TTBR0_EL1			sys_reg(3, 0, 2, 0, 0)
 #define SYS_TTBR1_EL1			sys_reg(3, 0, 2, 0, 1)
@@ -388,6 +391,8 @@
 #define TRBIDR_ALIGN_MASK		GENMASK(3, 0)
 #define TRBIDR_ALIGN_SHIFT		0
 
+#define SMPRI_EL1_PRIORITY_MASK		0xf
+
 #define SYS_PMINTENSET_EL1		sys_reg(3, 0, 9, 14, 1)
 #define SYS_PMINTENCLR_EL1		sys_reg(3, 0, 9, 14, 2)
 
@@ -443,8 +448,13 @@
 #define SYS_CCSIDR_EL1			sys_reg(3, 1, 0, 0, 0)
 #define SYS_CLIDR_EL1			sys_reg(3, 1, 0, 0, 1)
 #define SYS_GMID_EL1			sys_reg(3, 1, 0, 0, 4)
+#define SYS_SMIDR_EL1			sys_reg(3, 1, 0, 0, 6)
 #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
 
+#define SYS_SMIDR_EL1_IMPLEMENTER_SHIFT	24
+#define SYS_SMIDR_EL1_SMPS_SHIFT	15
+#define SYS_SMIDR_EL1_AFFINITY_SHIFT	0
+
 #define SYS_CSSELR_EL1			sys_reg(3, 2, 0, 0, 0)
 
 #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
@@ -453,6 +463,10 @@
 #define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
 #define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
 
+#define SYS_SVCR_EL0			sys_reg(3, 3, 4, 2, 2)
+#define SYS_SVCR_EL0_ZA_MASK		2
+#define SYS_SVCR_EL0_SM_MASK		1
+
 #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
 #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
 #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
@@ -469,6 +483,7 @@
 
 #define SYS_TPIDR_EL0			sys_reg(3, 3, 13, 0, 2)
 #define SYS_TPIDRRO_EL0			sys_reg(3, 3, 13, 0, 3)
+#define SYS_TPIDR2_EL0			sys_reg(3, 3, 13, 0, 5)
 
 #define SYS_SCXTNUM_EL0			sys_reg(3, 3, 13, 0, 7)
 
@@ -538,6 +553,9 @@
 #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
 #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
+#define SYS_HCRX_EL2			sys_reg(3, 4, 1, 2, 2)
+#define SYS_SMPRIMAP_EL2		sys_reg(3, 4, 1, 2, 5)
+#define SYS_SMCR_EL2			sys_reg(3, 4, 1, 2, 6)
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
 #define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
 #define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
@@ -597,6 +615,7 @@
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
 #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+#define SYS_SMCR_EL12			sys_reg(3, 5, 1, 2, 6)
 #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
 #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
 #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
@@ -620,6 +639,7 @@
 #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
 
 /* Common SCTLR_ELx flags. */
+#define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
 
@@ -815,6 +835,7 @@
 #define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
 
 /* id_aa64pfr1 */
+#define ID_AA64PFR1_SME_SHIFT		24
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
 #define ID_AA64PFR1_RASFRAC_SHIFT	12
 #define ID_AA64PFR1_MTE_SHIFT		8
@@ -825,6 +846,7 @@
 #define ID_AA64PFR1_SSBS_PSTATE_ONLY	1
 #define ID_AA64PFR1_SSBS_PSTATE_INSNS	2
 #define ID_AA64PFR1_BT_BTI		0x1
+#define ID_AA64PFR1_SME			1
 
 #define ID_AA64PFR1_MTE_NI		0x0
 #define ID_AA64PFR1_MTE_EL0		0x1
@@ -853,6 +875,23 @@
 #define ID_AA64ZFR0_AES_PMULL		0x2
 #define ID_AA64ZFR0_SVEVER_SVE2		0x1
 
+/* id_aa64smfr0 */
+#define ID_AA64SMFR0_FA64_SHIFT		63
+#define ID_AA64SMFR0_I16I64_SHIFT	52
+#define ID_AA64SMFR0_F64F64_SHIFT	48
+#define ID_AA64SMFR0_I8I32_SHIFT	36
+#define ID_AA64SMFR0_F16F32_SHIFT	35
+#define ID_AA64SMFR0_B16F32_SHIFT	34
+#define ID_AA64SMFR0_F32F32_SHIFT	32
+
+#define ID_AA64SMFR0_FA64		0x1
+#define ID_AA64SMFR0_I16I64		0x4
+#define ID_AA64SMFR0_F64F64		0x1
+#define ID_AA64SMFR0_I8I32		0x4
+#define ID_AA64SMFR0_F16F32		0x1
+#define ID_AA64SMFR0_B16F32		0x1
+#define ID_AA64SMFR0_F32F32		0x1
+
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_ECV_SHIFT		60
 #define ID_AA64MMFR0_FGT_SHIFT		56
@@ -904,6 +943,7 @@
 #endif
 
 /* id_aa64mmfr1 */
+#define ID_AA64MMFR1_HCX_SHIFT		40
 #define ID_AA64MMFR1_AFP_SHIFT		44
 #define ID_AA64MMFR1_ETS_SHIFT		36
 #define ID_AA64MMFR1_TWED_SHIFT		32
@@ -1097,6 +1137,22 @@
 #define ZCR_ELx_LEN_SIZE	9
 #define ZCR_ELx_LEN_MASK	0x1ff
 
+#define SMCR_ELx_FA64_SHIFT	31
+#define SMCR_ELx_FA64_MASK	(1 << SMCR_ELx_FA64_SHIFT)
+
+/*
+ * The SMCR_ELx_LEN_* definitions intentionally include bits [8:4] which
+ * are reserved by the SME architecture for future expansion of the LEN
+ * field, with compatible semantics.
+ */
+#define SMCR_ELx_LEN_SHIFT	0
+#define SMCR_ELx_LEN_SIZE	9
+#define SMCR_ELx_LEN_MASK	0x1ff
+
+#define CPACR_EL1_SMEN_EL1EN	(BIT(24)) /* enable EL1 access */
+#define CPACR_EL1_SMEN_EL0EN	(BIT(25)) /* enable EL0 access, if EL1EN set */
+#define CPACR_EL1_SMEN		(CPACR_EL1_SMEN_EL1EN | CPACR_EL1_SMEN_EL0EN)
+
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 #define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
@@ -1150,6 +1206,8 @@
 #define TRFCR_ELx_ExTRE			BIT(1)
 #define TRFCR_ELx_E0TRE			BIT(0)
 
+/* HCRX_EL2 definitions */
+#define HCRX_EL2_SMPME_MASK		(1 << 5)
 
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
@@ -1213,6 +1271,12 @@
 #define ICH_VTR_TDS_SHIFT	19
 #define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
 
+/* HFG[WR]TR_EL2 bit definitions */
+#define HFGxTR_EL2_nTPIDR_EL0_SHIFT	55
+#define HFGxTR_EL2_nTPIDR_EL0_MASK	(1 << HFGxTR_EL2_nTPIDR_EL0_SHIFT)
+#define HFGxTR_EL2_nSMPRI_EL1_SHIFT	54
+#define HFGxTR_EL2_nSMPRI_EL1_MASK	(1 << HFGxTR_EL2_nSMPRI_EL1_SHIFT)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Create a mask for the feature bits of the specified feature. */
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 70fc42470f13..88effb25c399 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -822,6 +822,7 @@ static const char *esr_class_str[] = {
 	[ESR_ELx_EC_SVE]		= "SVE",
 	[ESR_ELx_EC_ERET]		= "ERET/ERETAA/ERETAB",
 	[ESR_ELx_EC_FPAC]		= "FPAC",
+	[ESR_ELx_EC_SME]		= "SME",
 	[ESR_ELx_EC_IMP_DEF]		= "EL3 IMP DEF",
 	[ESR_ELx_EC_IABT_LOW]		= "IABT (lower EL)",
 	[ESR_ELx_EC_IABT_CUR]		= "IABT (current EL)",
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:42 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:42 +0000
Subject: [PATCH v8 06/38] arm64/sme: Manually encode SME instructions
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-7-broonie@kernel.org>

As with SVE rather than impose ambitious toolchain requirements for SME
we manually encode the few instructions which we require in order to
perform the work the kernel needs to do. The instructions used to save
and restore context are provided as assembler macros while those for
entering and leaving streaming mode are done in asm volatile blocks
since they are expected to be used from C.

We could do the SMSTART and SMSTOP operations with read/modify/write
cycles on SVCR but using the aliases provided for individual field
accesses should be slightly faster. These instructions are aliases for
MSR but since our minimum toolchain requirements are old enough to mean
that we can't use the sX_X_cX_cX_X form and they always use xzr rather
than taking a value like write_sysreg_s() wants we just use .inst.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       | 25 +++++++++++++
 arch/arm64/include/asm/fpsimdmacros.h | 53 +++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index cb24385e3632..c90f7f99a768 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -249,6 +249,31 @@ static inline void sve_setup(void) { }
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static inline void sme_smstart_sm(void)
+{
+	asm volatile(".inst 0xd503437f");
+}
+
+static inline void sme_smstop_sm(void)
+{
+	asm volatile(".inst 0xd503427f");
+}
+
+static inline void sme_smstop(void)
+{
+	asm volatile(".inst 0xd503467f");
+}
+
+#else
+
+static inline void sme_smstart_sm(void) { }
+static inline void sme_smstop_sm(void) { }
+static inline void sme_smstop(void) { }
+
+#endif /* ! CONFIG_ARM64_SME */
+
 /* For use by EFI runtime services calls only */
 extern void __efi_fpsimd_begin(void);
 extern void __efi_fpsimd_end(void);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 2509d7dde55a..11c426ddd62c 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -93,6 +93,12 @@
 	.endif
 .endm
 
+.macro _sme_check_wv v
+	.if (\v) < 12 || (\v) > 15
+		.error "Bad vector select register \v."
+	.endif
+.endm
+
 /* SVE instruction encodings for non-SVE-capable assemblers */
 /* (pre binutils 2.28, all kernel capable clang versions support SVE) */
 
@@ -174,6 +180,53 @@
 		| (\np)
 .endm
 
+/* SME instruction encodings for non-SME-capable assemblers */
+
+/* RDSVL X\nx, #\imm */
+.macro _sme_rdsvl nx, imm
+	_check_general_reg \nx
+	_check_num (\imm), -0x20, 0x1f
+	.inst	0x04bf5800			\
+		| (\nx)				\
+		| (((\imm) & 0x3f) << 5)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_str_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_ldr_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * Zero the entire ZA array
+ *	ZERO ZA
+ */
+.macro zero_za
+	.inst 0xc00800ff
+.endm
+
 .macro __for from:req, to:req
 	.if (\from) == (\to)
 		_for__body %\from
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:43 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:43 +0000
Subject: [PATCH v8 07/38] arm64/sme: Early CPU setup for SME
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-8-broonie@kernel.org>

SME requires similar setup to that for SVE: disable traps to EL2 and
make sure that the maximum vector length is available to EL1, for SME we
have two traps - one for SME itself and one for TPIDR2.

In addition since we currently make no active use of priority control
for SCMUs we map all SME priorities lower ELs may configure to 0, the
architecture specified minimum priority, to ensure that nothing we
manage is able to configure itself to consume excessive resources.  This
will need to be revisited should there be a need to manage SME
priorities at runtime.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 64 ++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 3198acb2aad8..0e68b478bd94 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -143,6 +143,50 @@
 .Lskip_sve_\@:
 .endm
 
+/* SME register access and priority mapping */
+.macro __init_el2_nvhe_sme
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	bic	x0, x0, #CPTR_EL2_TSM		// Also disable SME traps
+	msr	cptr_el2, x0			// Disable copro. traps to EL2
+	isb
+
+	mrs	x1, sctlr_el2
+	orr	x1, x1, #SCTLR_ELx_ENTP2	// Disable TPIDR2 traps
+	msr	sctlr_el2, x1
+	isb
+
+	mov	x1, #0				// SMCR controls
+
+	mrs_s	x2, SYS_ID_AA64SMFR0_EL1
+	ubfx	x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
+	cbz	x2, .Lskip_sme_fa64_\@
+
+	orr	x1, x1, SMCR_ELx_FA64_MASK
+.Lskip_sme_fa64_\@:
+
+	orr	x1, x1, #SMCR_ELx_LEN_MASK	// Enable full SME vector
+	msr_s	SYS_SMCR_EL2, x1		// length for EL1.
+
+	mrs_s	x1, SYS_SMIDR_EL1		// Priority mapping supported?
+	ubfx    x1, x1, #SYS_SMIDR_EL1_SMPS_SHIFT, #1
+	cbz     x1, .Lskip_sme_\@
+
+	msr_s	SYS_SMPRIMAP_EL2, xzr		// Make all priorities equal
+
+	mrs	x1, id_aa64mmfr1_el1		// HCRX_EL2 present?
+	ubfx	x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	mrs_s	x1, SYS_HCRX_EL2
+	orr	x1, x1, #HCRX_EL2_SMPME_MASK	// Enable priority mapping
+	msr_s	SYS_HCRX_EL2, x1
+
+.Lskip_sme_\@:
+.endm
+
 /* Disable any fine grained traps */
 .macro __init_el2_fgt
 	mrs	x1, id_aa64mmfr0_el1
@@ -153,15 +197,26 @@
 	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
 	cmp	x1, #3
-	b.lt	.Lset_fgt_\@
+	b.lt	.Lset_debug_fgt_\@
 	/* Disable PMSNEVFR_EL1 read and write traps */
 	orr	x0, x0, #(1 << 62)
 
-.Lset_fgt_\@:
+.Lset_debug_fgt_\@:
 	msr_s	SYS_HDFGRTR_EL2, x0
 	msr_s	SYS_HDFGWTR_EL2, x0
-	msr_s	SYS_HFGRTR_EL2, xzr
-	msr_s	SYS_HFGWTR_EL2, xzr
+
+	mov	x0, xzr
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lset_fgt_\@
+
+	/* Disable nVHE traps of TPIDR2 and SMPRI */
+	orr	x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
+	orr	x0, x0, #HFGxTR_EL2_nTPIDR_EL0_MASK
+
+.Lset_fgt_\@:
+	msr_s	SYS_HFGRTR_EL2, x0
+	msr_s	SYS_HFGWTR_EL2, x0
 	msr_s	SYS_HFGITR_EL2, xzr
 
 	mrs	x1, id_aa64pfr0_el1		// AMU traps UNDEF without AMU
@@ -196,6 +251,7 @@
 	__init_el2_nvhe_idregs
 	__init_el2_nvhe_cptr
 	__init_el2_nvhe_sve
+	__init_el2_nvhe_sme
 	__init_el2_fgt
 	__init_el2_nvhe_prepare_eret
 .endm
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:44 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:44 +0000
Subject: [PATCH v8 08/38] arm64/sme: Basic enumeration support
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-9-broonie@kernel.org>

This patch introduces basic cpufeature support for discovering the presence
of the Scalable Matrix Extension and reporting hwcaps for the detected
features.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/elf_hwcaps.rst  | 33 +++++++++++++++++
 arch/arm64/include/asm/cpu.h        |  1 +
 arch/arm64/include/asm/cpufeature.h | 12 ++++++
 arch/arm64/include/asm/fpsimd.h     |  2 +
 arch/arm64/include/asm/hwcap.h      |  8 ++++
 arch/arm64/include/uapi/asm/hwcap.h |  8 ++++
 arch/arm64/kernel/cpufeature.c      | 57 +++++++++++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c         |  9 +++++
 arch/arm64/kernel/fpsimd.c          | 30 +++++++++++++++
 arch/arm64/tools/cpucaps            |  2 +
 10 files changed, 162 insertions(+)

diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index b72ff17d600a..5626cf208000 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -259,6 +259,39 @@ HWCAP2_RPRES
 
     Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
 
+HWCAP2_SME
+
+    Functionality implied by ID_AA64PFR1_EL1.SME == 0b0001, as described
+    by Documentation/arm64/sme.rst.
+
+HWCAP2_SME_I16I64
+
+    Functionality implied by ID_AA64SMFR0_EL1.I16I64 == 0b1111.
+
+HWCAP2_SME_F64F64
+
+    Functionality implied by ID_AA64SMFR0_EL1.F64F64 == 0b1.
+
+HWCAP2_SME_I8I32
+
+    Functionality implied by ID_AA64SMFR0_EL1.I8I32 == 0b1111.
+
+HWCAP2_SME_F16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F16F32 == 0b1.
+
+HWCAP2_SME_B16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.B16F32 == 0b1.
+
+HWCAP2_SME_F32F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F32F32 == 0b1.
+
+HWCAP2_SME_FA64
+
+    Functionality implied by ID_AA64SMFR0_EL1.FA64 == 0b1.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index a58e366f0b07..d08062bcb9c1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -58,6 +58,7 @@ struct cpuinfo_arm64 {
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr1;
 	u64		reg_id_aa64zfr0;
+	u64		reg_id_aa64smfr0;
 
 	struct cpuinfo_32bit	aarch32;
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 2728abd9cae4..f93b1442143f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -728,6 +728,18 @@ static __always_inline bool system_supports_sve(void)
 		cpus_have_const_cap(ARM64_SVE);
 }
 
+static __always_inline bool system_supports_sme(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME);
+}
+
+static __always_inline bool system_supports_fa64(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME_FA64);
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index c90f7f99a768..6b7eb6f2cecd 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -74,6 +74,8 @@ extern void sve_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f68fbb207473..76d9999527c5 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -108,6 +108,14 @@
 #define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
 #define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
 #define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_SME		__khwcap2_feature(SME)
+#define KERNEL_HWCAP_SME_I16I64		__khwcap2_feature(SME_I16I64)
+#define KERNEL_HWCAP_SME_F64F64		__khwcap2_feature(SME_F64F64)
+#define KERNEL_HWCAP_SME_I8I32		__khwcap2_feature(SME_I8I32)
+#define KERNEL_HWCAP_SME_F16F32		__khwcap2_feature(SME_F16F32)
+#define KERNEL_HWCAP_SME_B16F32		__khwcap2_feature(SME_B16F32)
+#define KERNEL_HWCAP_SME_F32F32		__khwcap2_feature(SME_F32F32)
+#define KERNEL_HWCAP_SME_FA64		__khwcap2_feature(SME_FA64)
 
 /*
  * This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index f03731847d9d..60de5626f8fb 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -78,5 +78,13 @@
 #define HWCAP2_ECV		(1 << 19)
 #define HWCAP2_AFP		(1 << 20)
 #define HWCAP2_RPRES		(1 << 21)
+#define HWCAP2_SME		(1 << 22)
+#define HWCAP2_SME_I16I64	(1 << 23)
+#define HWCAP2_SME_F64F64	(1 << 24)
+#define HWCAP2_SME_I8I32	(1 << 25)
+#define HWCAP2_SME_F16F32	(1 << 26)
+#define HWCAP2_SME_B16F32	(1 << 27)
+#define HWCAP2_SME_F32F32	(1 << 28)
+#define HWCAP2_SME_FA64		(1 << 29)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index ec060db1dcf0..6f574c9c1882 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -251,6 +251,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SME_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE),
@@ -283,6 +284,24 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_FA64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I16I64_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F64F64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I8I32_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_B16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F32F32_SHIFT, 1, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0),
@@ -634,6 +653,7 @@ static const struct __ftr_reg_entry {
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
 			       &id_aa64pfr1_override),
 	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
+	ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -947,6 +967,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
 	init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
 	init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
+	init_cpu_ftr_reg(SYS_ID_AA64SMFR0_EL1, info->reg_id_aa64smfr0);
 
 	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
 		init_32bit_cpu_features(&info->aarch32);
@@ -2411,6 +2432,32 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 	},
+#ifdef CONFIG_ARM64_SME
+	{
+		.desc = "Scalable Matrix Extension",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME,
+		.sys_reg = SYS_ID_AA64PFR1_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64PFR1_SME_SHIFT,
+		.field_width = 4,
+		.min_field_value = ID_AA64PFR1_SME,
+		.matches = has_cpuid_feature,
+		.cpu_enable = sme_kernel_enable,
+	},
+	{
+		.desc = "FA64",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME_FA64,
+		.sys_reg = SYS_ID_AA64SMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64SMFR0_FA64_SHIFT,
+		.field_width = 1,
+		.min_field_value = ID_AA64SMFR0_FA64,
+		.matches = has_cpuid_feature,
+		.cpu_enable = fa64_kernel_enable,
+	},
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
@@ -2535,6 +2582,16 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
 	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+#ifdef CONFIG_ARM64_SME
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SME_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SME, CAP_HWCAP, KERNEL_HWCAP_SME),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_FA64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_FA64, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I16I64_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I16I64, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F64F64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F64F64, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I8I32_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I8I32, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F16F32, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_B16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_B16F32, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F32F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F32F32, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..33ec182e872e 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -97,6 +97,14 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_ECV]		= "ecv",
 	[KERNEL_HWCAP_AFP]		= "afp",
 	[KERNEL_HWCAP_RPRES]		= "rpres",
+	[KERNEL_HWCAP_SME]		= "sme",
+	[KERNEL_HWCAP_SME_I16I64]	= "smei16i64",
+	[KERNEL_HWCAP_SME_F64F64]	= "smef64f64",
+	[KERNEL_HWCAP_SME_I8I32]	= "smei8i32",
+	[KERNEL_HWCAP_SME_F16F32]	= "smef16f32",
+	[KERNEL_HWCAP_SME_B16F32]	= "smeb16f32",
+	[KERNEL_HWCAP_SME_F32F32]	= "smef32f32",
+	[KERNEL_HWCAP_SME_FA64]		= "smefa64",
 };
 
 #ifdef CONFIG_COMPAT
@@ -400,6 +408,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 	info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
+	info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
 
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		info->reg_gmid = read_cpuid(GMID_EL1);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 5280e098cfb5..576490be3c2b 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -987,6 +987,32 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Set priority for all PEs to architecturally defined minimum */
+	write_sysreg_s(read_sysreg_s(SYS_SMPRI_EL1) & ~SMPRI_EL1_PRIORITY_MASK,
+		       SYS_SMPRI_EL1);
+
+	/* Allow SME in kernel */
+	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
+	isb();
+}
+
+/*
+ * This must be called after sme_kernel_enable(), we rely on the
+ * feature table being sorted to ensure this.
+ */
+void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Allow use of FA64 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
+		       SYS_SMCR_EL1);
+}
+
+#endif /* CONFIG_ARM64_SVE */
+
 /*
  * Trapped SVE access
  *
@@ -1532,6 +1558,10 @@ static int __init fpsimd_init(void)
 	if (!cpu_have_named_feature(ASIMD))
 		pr_notice("Advanced SIMD is not implemented\n");
 
+
+	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
+		pr_notice("SME is implemented but not SVE\n");
+
 	return sve_sysctl_init();
 }
 core_initcall(fpsimd_init);
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b3ada80aa48d..cd6e7c7c7a15 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -42,6 +42,8 @@ KVM_PROTECTED_MODE
 MISMATCHED_CACHE_TYPE
 MTE
 MTE_ASYMM
+SME
+SME_FA64
 SPECTRE_V2
 SPECTRE_V3A
 SPECTRE_V4
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:45 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:45 +0000
Subject: [PATCH v8 09/38] arm64/sme: Identify supported SME vector lengths at
 boot
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-10-broonie@kernel.org>

The vector lengths used for SME are controlled through a similar set of
registers to those for SVE and enumerated using a similar algorithm with
some slight differences due to the fact that unlike SVE there are no
restrictions on which combinations of vector lengths can be supported
nor any mandatory vector lengths which must be implemented.  Add a new
vector type and implement support for enumerating it.

One slightly awkward feature is that we need to read the current vector
length using a different instruction (or enter streaming mode which
would have the same issue and be higher cost).  Rather than add an ops
structure we add special cases directly in the otherwise generic
vec_probe_vqs() function, this is a bit inelegant but it's the only
place where this is an issue.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpu.h        |   3 +
 arch/arm64/include/asm/cpufeature.h |   7 ++
 arch/arm64/include/asm/fpsimd.h     |  26 ++++++
 arch/arm64/include/asm/processor.h  |   1 +
 arch/arm64/kernel/cpufeature.c      |  49 +++++++++++
 arch/arm64/kernel/cpuinfo.c         |   4 +
 arch/arm64/kernel/entry-fpsimd.S    |   9 ++
 arch/arm64/kernel/fpsimd.c          | 123 +++++++++++++++++++++++++++-
 8 files changed, 220 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index d08062bcb9c1..550e1fc4ae6c 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -64,6 +64,9 @@ struct cpuinfo_arm64 {
 
 	/* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */
 	u64		reg_zcr;
+
+	/* pseudo-SMCR for recording maximum ZCR_EL1 LEN value: */
+	u64		reg_smcr;
 };
 
 DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index f93b1442143f..9d36035acce3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -620,6 +620,13 @@ static inline bool id_aa64pfr0_sve(u64 pfr0)
 	return val > 0;
 }
 
+static inline bool id_aa64pfr1_sme(u64 pfr1)
+{
+	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_SME_SHIFT);
+
+	return val > 0;
+}
+
 static inline bool id_aa64pfr1_mte(u64 pfr1)
 {
 	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_MTE_SHIFT);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 6b7eb6f2cecd..8cb99b6fe565 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -78,6 +78,7 @@ extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
+extern u64 read_smcr_features(void);
 
 /*
  * Helpers to translate bit indices in sve_vq_map to VQ values (and
@@ -172,6 +173,12 @@ static inline void write_vl(enum vec_type type, u64 val)
 		tmp = read_sysreg_s(SYS_ZCR_EL1) & ~ZCR_ELx_LEN_MASK;
 		write_sysreg_s(tmp | val, SYS_ZCR_EL1);
 		break;
+#endif
+#ifdef CONFIG_ARM64_SME
+	case ARM64_VEC_SME:
+		tmp = read_sysreg_s(SYS_SMCR_EL1) & ~SMCR_ELx_LEN_MASK;
+		write_sysreg_s(tmp | val, SYS_SMCR_EL1);
+		break;
 #endif
 	default:
 		WARN_ON_ONCE(1);
@@ -268,12 +275,31 @@ static inline void sme_smstop(void)
 	asm volatile(".inst 0xd503467f");
 }
 
+extern void __init sme_setup(void);
+
+static inline int sme_max_vl(void)
+{
+	return vec_max_vl(ARM64_VEC_SME);
+}
+
+static inline int sme_max_virtualisable_vl(void)
+{
+	return vec_max_virtualisable_vl(ARM64_VEC_SME);
+}
+
+extern unsigned int sme_get_vl(void);
+
 #else
 
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_setup(void) { }
+static inline unsigned int sme_get_vl(void) { return 0; }
+static inline int sme_max_vl(void) { return 0; }
+static inline int sme_max_virtualisable_vl(void) { return 0; }
+
 #endif /* ! CONFIG_ARM64_SME */
 
 /* For use by EFI runtime services calls only */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..df68f0fb0ded 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -117,6 +117,7 @@ struct debug_info {
 
 enum vec_type {
 	ARM64_VEC_SVE = 0,
+	ARM64_VEC_SME,
 	ARM64_VEC_MAX,
 };
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 6f574c9c1882..9a39fdaae27b 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -570,6 +570,12 @@ static const struct arm64_ftr_bits ftr_zcr[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_smcr[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
+		SMCR_ELx_LEN_SHIFT, SMCR_ELx_LEN_SIZE, 0),	/* LEN */
+	ARM64_FTR_END,
+};
+
 /*
  * Common ftr bits for a 32bit register with all hidden, strict
  * attributes, with 4bit feature fields and a default safe value of
@@ -673,6 +679,7 @@ static const struct __ftr_reg_entry {
 
 	/* Op1 = 0, CRn = 1, CRm = 2 */
 	ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
+	ARM64_FTR_REG(SYS_SMCR_EL1, ftr_smcr),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
 	ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -977,6 +984,14 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 		vec_init_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		init_cpu_ftr_reg(SYS_SMCR_EL1, info->reg_smcr);
+		if (IS_ENABLED(CONFIG_ARM64_SME)) {
+			sme_kernel_enable(NULL);
+			vec_init_vq_map(ARM64_VEC_SME);
+		}
+	}
+
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
 
@@ -1203,6 +1218,9 @@ void update_cpu_features(int cpu,
 	taint |= check_update_ftr_reg(SYS_ID_AA64ZFR0_EL1, cpu,
 				      info->reg_id_aa64zfr0, boot->reg_id_aa64zfr0);
 
+	taint |= check_update_ftr_reg(SYS_ID_AA64SMFR0_EL1, cpu,
+				      info->reg_id_aa64smfr0, boot->reg_id_aa64smfr0);
+
 	if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
 		taint |= check_update_ftr_reg(SYS_ZCR_EL1, cpu,
 					info->reg_zcr, boot->reg_zcr);
@@ -1213,6 +1231,16 @@ void update_cpu_features(int cpu,
 			vec_update_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		taint |= check_update_ftr_reg(SYS_SMCR_EL1, cpu,
+					info->reg_smcr, boot->reg_smcr);
+
+		/* Probe vector lengths, unless we already gave up on SME */
+		if (id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1)) &&
+		    !system_capabilities_finalized())
+			vec_update_vq_map(ARM64_VEC_SME);
+	}
+
 	/*
 	 * The kernel uses the LDGM/STGM instructions and the number of tags
 	 * they read/write depends on the GMID_EL1.BS field. Check that the
@@ -2889,6 +2917,23 @@ static void verify_sve_features(void)
 	/* Add checks on other ZCR bits here if necessary */
 }
 
+static void verify_sme_features(void)
+{
+	u64 safe_smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	u64 smcr = read_smcr_features();
+
+	unsigned int safe_len = safe_smcr & SMCR_ELx_LEN_MASK;
+	unsigned int len = smcr & SMCR_ELx_LEN_MASK;
+
+	if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SME)) {
+		pr_crit("CPU%d: SME: vector length support mismatch\n",
+			smp_processor_id());
+		cpu_die_early();
+	}
+
+	/* Add checks on other SMCR bits here if necessary */
+}
+
 static void verify_hyp_capabilities(void)
 {
 	u64 safe_mmfr1, mmfr0, mmfr1;
@@ -2941,6 +2986,9 @@ static void verify_local_cpu_capabilities(void)
 	if (system_supports_sve())
 		verify_sve_features();
 
+	if (system_supports_sme())
+		verify_sme_features();
+
 	if (is_hyp_mode_available())
 		verify_hyp_capabilities();
 }
@@ -3058,6 +3106,7 @@ void __init setup_cpu_features(void)
 		pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
 
 	sve_setup();
+	sme_setup();
 	minsigstksz_setup();
 
 	/* Advertise that we have computed the system capabilities */
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 33ec182e872e..72dc155719b0 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -420,6 +420,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	    id_aa64pfr0_sve(info->reg_id_aa64pfr0))
 		info->reg_zcr = read_zcr_features();
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1))
+		info->reg_smcr = read_smcr_features();
+
 	cpuinfo_detect_icache_policy(info);
 }
 
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index dc242e269f9a..deee5f01462e 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -86,3 +86,12 @@ SYM_FUNC_START(sve_flush_live)
 SYM_FUNC_END(sve_flush_live)
 
 #endif /* CONFIG_ARM64_SVE */
+
+#ifdef CONFIG_ARM64_SME
+
+SYM_FUNC_START(sme_get_vl)
+	_sme_rdsvl	0, 1
+	ret
+SYM_FUNC_END(sme_get_vl)
+
+#endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 576490be3c2b..3fb2167f8af7 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -136,6 +136,12 @@ __ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
 		.max_virtualisable_vl	= SVE_VL_MIN,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[ARM64_VEC_SME] = {
+		.type			= ARM64_VEC_SME,
+		.name			= "SME",
+	},
+#endif
 };
 
 static unsigned int vec_vl_inherit_flag(enum vec_type type)
@@ -186,6 +192,20 @@ extern void __percpu *efi_sve_state;
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int get_sme_default_vl(void)
+{
+	return get_default_vl(ARM64_VEC_SME);
+}
+
+static void set_sme_default_vl(int val)
+{
+	set_default_vl(ARM64_VEC_SME, val);
+}
+
+#endif
+
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
 EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
 
@@ -403,6 +423,8 @@ static unsigned int find_supported_vector_length(enum vec_type type,
 
 	if (vl > max_vl)
 		vl = max_vl;
+	if (vl < info->min_vl)
+		vl = info->min_vl;
 
 	bit = find_next_bit(info->vq_map, SVE_VQ_MAX,
 			    __vq_to_bit(sve_vq_from_vl(vl)));
@@ -764,7 +786,23 @@ static void vec_probe_vqs(struct vl_info *info,
 
 	for (vq = SVE_VQ_MAX; vq >= SVE_VQ_MIN; --vq) {
 		write_vl(info->type, vq - 1); /* self-syncing */
-		vl = sve_get_vl();
+
+		switch (info->type) {
+		case ARM64_VEC_SVE:
+			vl = sve_get_vl();
+			break;
+		case ARM64_VEC_SME:
+			vl = sme_get_vl();
+			break;
+		default:
+			vl = 0;
+			break;
+		}
+
+		/* Minimum VL identified? */
+		if (sve_vq_from_vl(vl) > vq)
+			break;
+
 		vq = sve_vq_from_vl(vl); /* skip intervening lengths */
 		set_bit(__vq_to_bit(vq), map);
 	}
@@ -1011,7 +1049,88 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 		       SYS_SMCR_EL1);
 }
 
-#endif /* CONFIG_ARM64_SVE */
+/*
+ * Read the pseudo-SMCR used by cpufeatures to identify the supported
+ * vector length.
+ *
+ * Use only if SME is present.
+ * This function clobbers the SME vector length.
+ */
+u64 read_smcr_features(void)
+{
+	u64 smcr;
+	unsigned int vq_max;
+
+	sme_kernel_enable(NULL);
+	sme_smstart_sm();
+
+	/*
+	 * Set the maximum possible VL.
+	 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
+		       SYS_SMCR_EL1);
+
+	smcr = read_sysreg_s(SYS_SMCR_EL1);
+	smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */
+	vq_max = sve_vq_from_vl(sve_get_vl());
+	smcr |= vq_max - 1; /* set LEN field to maximum effective value */
+
+	sme_smstop_sm();
+
+	return smcr;
+}
+
+void __init sme_setup(void)
+{
+	struct vl_info *info = &vl_info[ARM64_VEC_SME];
+	u64 smcr;
+	int min_bit;
+
+	if (!system_supports_sme())
+		return;
+
+	/*
+	 * SME doesn't require any particular vector length be
+	 * supported but it does require at least one.  We should have
+	 * disabled the feature entirely while bringing up CPUs but
+	 * let's double check here.
+	 */
+	WARN_ON(bitmap_empty(info->vq_map, SVE_VQ_MAX));
+
+	min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);
+	info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));
+
+	smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	info->max_vl = sve_vl_from_vq((smcr & SMCR_ELx_LEN_MASK) + 1);
+
+	/*
+	 * Sanity-check that the max VL we determined through CPU features
+	 * corresponds properly to sme_vq_map.  If not, do our best:
+	 */
+	if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SME,
+								 info->max_vl)))
+		info->max_vl = find_supported_vector_length(ARM64_VEC_SME,
+							    info->max_vl);
+
+	WARN_ON(info->min_vl > info->max_vl);
+
+	/*
+	 * For the default VL, pick the maximum supported value <= 32
+	 * (256 bits) if there is one since this is guaranteed not to
+	 * grow the signal frame when in streaming mode, otherwise the
+	 * minimum available VL will be used.
+	 */
+	set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));
+
+	pr_info("SME: minimum available vector length %u bytes per vector\n",
+		info->min_vl);
+	pr_info("SME: maximum available vector length %u bytes per vector\n",
+		info->max_vl);
+	pr_info("SME: default vector length %u bytes per vector\n",
+		get_sme_default_vl());
+}
+
+#endif /* CONFIG_ARM64_SME */
 
 /*
  * Trapped SVE access
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:46 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:46 +0000
Subject: [PATCH v8 10/38] arm64/sme: Implement sysctl to set the default
 vector length
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-11-broonie@kernel.org>

As for SVE provide a sysctl which allows the default SME vector length to
be configured.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 3fb2167f8af7..841b9609342f 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -483,6 +483,30 @@ static int __init sve_sysctl_init(void)
 static int __init sve_sysctl_init(void) { return 0; }
 #endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
 
+#if defined(CONFIG_ARM64_SME) && defined(CONFIG_SYSCTL)
+static struct ctl_table sme_default_vl_table[] = {
+	{
+		.procname	= "sme_default_vector_length",
+		.mode		= 0644,
+		.proc_handler	= vec_proc_do_default_vl,
+		.extra1		= &vl_info[ARM64_VEC_SME],
+	},
+	{ }
+};
+
+static int __init sme_sysctl_init(void)
+{
+	if (system_supports_sme())
+		if (!register_sysctl("abi", sme_default_vl_table))
+			return -EINVAL;
+
+	return 0;
+}
+
+#else /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+static int __init sme_sysctl_init(void) { return 0; }
+#endif /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+
 #define ZREG(sve_state, vq, n) ((char *)(sve_state) +		\
 	(SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
 
@@ -1681,6 +1705,9 @@ static int __init fpsimd_init(void)
 	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
 		pr_notice("SME is implemented but not SVE\n");
 
-	return sve_sysctl_init();
+	sve_sysctl_init();
+	sme_sysctl_init();
+
+	return 0;
 }
 core_initcall(fpsimd_init);
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:47 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:47 +0000
Subject: [PATCH v8 11/38] arm64/sme: Implement vector length configuration
 prctl()s
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-12-broonie@kernel.org>

As for SVE provide a prctl() interface which allows processes to
configure their SME vector length.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  4 ++++
 arch/arm64/include/asm/processor.h   |  4 +++-
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 32 ++++++++++++++++++++++++++++
 include/uapi/linux/prctl.h           |  9 ++++++++
 kernel/sys.c                         | 12 +++++++++++
 6 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 8cb99b6fe565..babf944e7c0c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
 }
 
 extern unsigned int sme_get_vl(void);
+extern int sme_set_current_vl(unsigned long arg);
+extern int sme_get_current_vl(void);
 
 #else
 
@@ -299,6 +301,8 @@ static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
 static inline int sme_max_virtualisable_vl(void) { return 0; }
+static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
+static inline int sme_get_current_vl(void) { return -EINVAL; }
 
 #endif /* ! CONFIG_ARM64_SME */
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index df68f0fb0ded..f2c2ebd440e2 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -354,9 +354,11 @@ extern void __init minsigstksz_setup(void);
  */
 #include <asm/fpsimd.h>
 
-/* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */
+/* Userspace interface for PR_S[MV]E_{SET,GET}_VL prctl()s: */
 #define SVE_SET_VL(arg)	sve_set_current_vl(arg)
 #define SVE_GET_VL()	sve_get_current_vl()
+#define SME_SET_VL(arg)	sme_set_current_vl(arg)
+#define SME_GET_VL()	sme_get_current_vl()
 
 /* PR_PAC_RESET_KEYS prctl */
 #define PAC_RESET_KEYS(tsk, arg)	ptrauth_prctl_reset_keys(tsk, arg)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index e1317b7c4525..4e6b58dcd6f9 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 841b9609342f..1edb3996f9cf 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
 	switch (type) {
 	case ARM64_VEC_SVE:
 		return TIF_SVE_VL_INHERIT;
+	case ARM64_VEC_SME:
+		return TIF_SME_VL_INHERIT;
 	default:
 		WARN_ON_ONCE(1);
 		return 0;
@@ -801,6 +803,36 @@ int sve_get_current_vl(void)
 	return vec_prctl_status(ARM64_VEC_SVE, 0);
 }
 
+#ifdef CONFIG_ARM64_SME
+/* PR_SME_SET_VL */
+int sme_set_current_vl(unsigned long arg)
+{
+	unsigned long vl, flags;
+	int ret;
+
+	vl = arg & PR_SME_VL_LEN_MASK;
+	flags = arg & ~vl;
+
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
+	if (ret)
+		return ret;
+
+	return vec_prctl_status(ARM64_VEC_SME, flags);
+}
+
+/* PR_SME_GET_VL */
+int sme_get_current_vl(void)
+{
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	return vec_prctl_status(ARM64_VEC_SME, 0);
+}
+#endif /* CONFIG_ARM64_SME */
+
 static void vec_probe_vqs(struct vl_info *info,
 			  DECLARE_BITMAP(map, SVE_VQ_MAX))
 {
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index e998764f0262..a5e06dcbba13 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -272,6 +272,15 @@ struct prctl_mm_map {
 # define PR_SCHED_CORE_SCOPE_THREAD_GROUP	1
 # define PR_SCHED_CORE_SCOPE_PROCESS_GROUP	2
 
+/* arm64 Scalable Matrix Extension controls */
+/* Flag values must be in sync with SVE versions */
+#define PR_SME_SET_VL			63	/* set task vector length */
+# define PR_SME_SET_VL_ONEXEC		(1 << 18) /* defer effect until exec */
+#define PR_SME_GET_VL			64	/* get task vector length */
+/* Bits common to PR_SME_SET_VL and PR_SME_GET_VL */
+# define PR_SME_VL_LEN_MASK		0xffff
+# define PR_SME_VL_INHERIT		(1 << 17) /* inherit across exec */
+
 #define PR_SET_VMA		0x53564d41
 # define PR_SET_VMA_ANON_NAME		0
 
diff --git a/kernel/sys.c b/kernel/sys.c
index ecc4cf019242..5cd4fffc7cd0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -116,6 +116,12 @@
 #ifndef SVE_GET_VL
 # define SVE_GET_VL()		(-EINVAL)
 #endif
+#ifndef SME_SET_VL
+# define SME_SET_VL(a)		(-EINVAL)
+#endif
+#ifndef SME_GET_VL
+# define SME_GET_VL()		(-EINVAL)
+#endif
 #ifndef PAC_RESET_KEYS
 # define PAC_RESET_KEYS(a, b)	(-EINVAL)
 #endif
@@ -2523,6 +2529,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_SVE_GET_VL:
 		error = SVE_GET_VL();
 		break;
+	case PR_SME_SET_VL:
+		error = SME_SET_VL(arg2);
+		break;
+	case PR_SME_GET_VL:
+		error = SME_GET_VL();
+		break;
 	case PR_GET_SPECULATION_CTRL:
 		if (arg3 || arg4 || arg5)
 			return -EINVAL;
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:48 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:48 +0000
Subject: [PATCH v8 12/38] arm64/sme: Implement support for TPIDR2
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-13-broonie@kernel.org>

The Scalable Matrix Extension introduces support for a new thread specific
data register TPIDR2 intended for use by libc. The kernel must save the
value of TPIDR2 on context switch and should ensure that all new threads
start off with a default value of 0. Add a field to the thread_struct to
store TPIDR2 and context switch it with the other thread specific data.

In case there are future extensions which also use TPIDR2 we introduce
system_supports_tpidr2() and use that rather than system_supports_sme()
for TPIDR2 handling.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  5 +++++
 arch/arm64/include/asm/processor.h  |  1 +
 arch/arm64/kernel/fpsimd.c          |  4 ++++
 arch/arm64/kernel/process.c         | 14 ++++++++++++--
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9d36035acce3..12252352d2ee 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -747,6 +747,11 @@ static __always_inline bool system_supports_fa64(void)
 		cpus_have_const_cap(ARM64_SME_FA64);
 }
 
+static __always_inline bool system_supports_tpidr2(void)
+{
+	return system_supports_sme();
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index f2c2ebd440e2..008a1767ebff 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			tpidr2_el0;
 };
 
 static inline unsigned int thread_get_vl(struct thread_struct *thread,
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 1edb3996f9cf..40ef89120774 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1092,6 +1092,10 @@ void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 	/* Allow SME in kernel */
 	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
 	isb();
+
+	/* Allow EL0 to access TPIDR2 */
+	write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
+	isb();
 }
 
 /*
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..e69a3dcdb0d9 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -250,6 +250,8 @@ void show_regs(struct pt_regs *regs)
 static void tls_thread_flush(void)
 {
 	write_sysreg(0, tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(0, SYS_TPIDR2_EL0);
 
 	if (is_compat_task()) {
 		current->thread.uw.tp_value = 0;
@@ -343,6 +345,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 		 * out-of-sync with the saved value.
 		 */
 		*task_user_tls(p) = read_sysreg(tpidr_el0);
+		if (system_supports_tpidr2())
+			p->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 
 		if (stack_start) {
 			if (is_compat_thread(task_thread_info(p)))
@@ -353,10 +357,12 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 		/*
 		 * If a TLS pointer was passed to clone, use it for the new
-		 * thread.
+		 * thread.  We also reset TPIDR2 if it's in use.
 		 */
-		if (clone_flags & CLONE_SETTLS)
+		if (clone_flags & CLONE_SETTLS) {
 			p->thread.uw.tp_value = tls;
+			p->thread.tpidr2_el0 = 0;
+		}
 	} else {
 		/*
 		 * A kthread has no context to ERET to, so ensure any buggy
@@ -387,6 +393,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 void tls_preserve_current_state(void)
 {
 	*task_user_tls(current) = read_sysreg(tpidr_el0);
+	if (system_supports_tpidr2() && !is_compat_task())
+		current->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 }
 
 static void tls_thread_switch(struct task_struct *next)
@@ -399,6 +407,8 @@ static void tls_thread_switch(struct task_struct *next)
 		write_sysreg(0, tpidrro_el0);
 
 	write_sysreg(*task_user_tls(next), tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(next->thread.tpidr2_el0, SYS_TPIDR2_EL0);
 }
 
 /*
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:49 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:49 +0000
Subject: [PATCH v8 13/38] arm64/sme: Implement SVCR context switching
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-14-broonie@kernel.org>

In SME the use of both streaming SVE mode and ZA are tracked through
PSTATE.SM and PSTATE.ZA, visible through the system register SVCR.  In
order to context switch the floating point state for SME we need to
context switch the contents of this register as part of context
switching the floating point state.

Since changing the vector length exits streaming SVE mode and disables
ZA we also make sure we update SVCR appropriately when setting vector
length, and similarly ensure that new threads have streaming SVE mode
and ZA disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  3 ++-
 arch/arm64/include/asm/processor.h   |  1 +
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 18 +++++++++++++++++-
 arch/arm64/kernel/process.c          |  2 ++
 arch/arm64/kvm/fpsimd.c              |  4 ++++
 6 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index babf944e7c0c..d1bae65d3dba 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -46,7 +46,8 @@ extern void fpsimd_restore_current_state(void);
 extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
-				     void *sve_state, unsigned int sve_vl);
+				     void *sve_state, unsigned int sve_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 008a1767ebff..7e08a4d48c24 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			svcr;
 	u64			tpidr2_el0;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 4e6b58dcd6f9..848739c15de8 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME			27	/* SME in use */
 #define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 40ef89120774..a1918b71d335 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	u64 *svcr;
 	unsigned int sve_vl;
 };
 
@@ -359,6 +360,9 @@ static void task_fpsimd_load(void)
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
 		sve_load_state(sve_pffr(&current->thread),
@@ -384,6 +388,12 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    test_thread_flag(TIF_SME)) {
+		u64 *svcr = last->svcr;
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+	}
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
 	    test_thread_flag(TIF_SVE)) {
 		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
@@ -735,6 +745,10 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
 		sve_to_fpsimd(task);
 
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
+				       SYS_SVCR_EL0_ZA_MASK);
+
 	if (task == current)
 		put_cpu_fpsimd_context();
 
@@ -1398,6 +1412,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
 	if (system_supports_sve()) {
@@ -1412,7 +1427,7 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl)
+			      unsigned int sve_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1421,6 +1436,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	WARN_ON(!in_softirq() && !irqs_disabled());
 
 	last->st = st;
+	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
 }
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index e69a3dcdb0d9..f2d32a29641c 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -310,6 +310,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.svcr = 0;
+
 	/* clear any pending asynchronous tag fault raised by the parent */
 	clear_tsk_thread_flag(dst, TIF_MTE_ASYNC_FAULT);
 
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 2f48fd362a8c..04698c4bcd30 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -103,6 +103,10 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
+		/*
+		 * Currently we do not support SME guests so SVCR is
+		 * always 0 and we just need a variable to point to.
+		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl);
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:50 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:50 +0000
Subject: [PATCH v8 14/38] arm64/sme: Implement streaming SVE context switching
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-15-broonie@kernel.org>

When in streaming mode we need to save and restore the streaming mode
SVE register state rather than the regular SVE register state. This uses
the streaming mode vector length and omits FFR but is otherwise identical,
if TIF_SVE is enabled when we are in streaming mode then streaming mode
takes precedence.

This does not handle use of streaming SVE state with KVM, ptrace or
signals. This will be updated in further patches.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  22 +++++-
 arch/arm64/include/asm/fpsimdmacros.h |  11 +++
 arch/arm64/include/asm/processor.h    |  10 +++
 arch/arm64/kernel/entry-fpsimd.S      |   5 ++
 arch/arm64/kernel/fpsimd.c            | 109 +++++++++++++++++++++-----
 arch/arm64/kvm/fpsimd.c               |   3 +-
 6 files changed, 137 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index d1bae65d3dba..650ec642159c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,11 +47,21 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     u64 *svcr);
+				     unsigned int sme_vl, u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
 
+static inline bool thread_sm_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_SM_MASK);
+}
+
+static inline bool thread_za_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_ZA_MASK);
+}
+
 /* Maximum VL that SVE/SME VL-agnostic software can transparently support */
 #define VL_ARCH_MAX 0x100
 
@@ -63,7 +73,14 @@ static inline size_t sve_ffr_offset(int vl)
 
 static inline void *sve_pffr(struct thread_struct *thread)
 {
-	return (char *)thread->sve_state + sve_ffr_offset(thread_get_sve_vl(thread));
+	unsigned int vl;
+
+	if (system_supports_sme() && thread_sm_enabled(thread))
+		vl = thread_get_sme_vl(thread);
+	else
+		vl = thread_get_sve_vl(thread);
+
+	return (char *)thread->sve_state + sve_ffr_offset(vl);
 }
 
 extern void sve_save_state(void *state, u32 *pfpsr, int save_ffr);
@@ -72,6 +89,7 @@ extern void sve_load_state(void const *state, u32 const *pfpsr,
 extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
+extern void sme_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 11c426ddd62c..a50fa1eab730 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -261,6 +261,17 @@
 921:
 .endm
 
+/* Update SMCR_EL1.LEN with the new VQ */
+.macro sme_load_vq xvqminus1, xtmp, xtmp2
+		mrs_s		\xtmp, SYS_SMCR_EL1
+		bic		\xtmp2, \xtmp, SMCR_ELx_LEN_MASK
+		orr		\xtmp2, \xtmp2, \xvqminus1
+		cmp		\xtmp2, \xtmp
+		b.eq		921f
+		msr_s		SYS_SMCR_EL1, \xtmp2	//self-synchronising
+921:
+.endm
+
 /* Preserve the first 128-bits of Znz and zero the rest. */
 .macro _sve_flush_z nz
 	_sve_check_zreg \nz
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 7e08a4d48c24..6e2af9de153c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -183,6 +183,11 @@ static inline unsigned int thread_get_sve_vl(struct thread_struct *thread)
 	return thread_get_vl(thread, ARM64_VEC_SVE);
 }
 
+static inline unsigned int thread_get_sme_vl(struct thread_struct *thread)
+{
+	return thread_get_vl(thread, ARM64_VEC_SME);
+}
+
 unsigned int task_get_vl(const struct task_struct *task, enum vec_type type);
 void task_set_vl(struct task_struct *task, enum vec_type type,
 		 unsigned long vl);
@@ -196,6 +201,11 @@ static inline unsigned int task_get_sve_vl(const struct task_struct *task)
 	return task_get_vl(task, ARM64_VEC_SVE);
 }
 
+static inline unsigned int task_get_sme_vl(const struct task_struct *task)
+{
+	return task_get_vl(task, ARM64_VEC_SME);
+}
+
 static inline void task_set_sve_vl(struct task_struct *task, unsigned long vl)
 {
 	task_set_vl(task, ARM64_VEC_SVE, vl);
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index deee5f01462e..6f88c0f86d50 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -94,4 +94,9 @@ SYM_FUNC_START(sme_get_vl)
 	ret
 SYM_FUNC_END(sme_get_vl)
 
+SYM_FUNC_START(sme_set_vq)
+	sme_load_vq x0, x1, x2
+	ret
+SYM_FUNC_END(sme_set_vq)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a1918b71d335..12fef62cf07a 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -123,6 +123,7 @@ struct fpsimd_last_state_struct {
 	void *sve_state;
 	u64 *svcr;
 	unsigned int sve_vl;
+	unsigned int sme_vl;
 };
 
 static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
@@ -301,17 +302,28 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
 	task->thread.vl_onexec[type] = vl;
 }
 
+/*
+ * TIF_SME controls whether a task can use SME without trapping while
+ * in userspace, when TIF_SME is set then we must have storage
+ * alocated in sve_state and za_state to store the contents of both ZA
+ * and the SVE registers for both streaming and non-streaming modes.
+ *
+ * If both SVCR.ZA and SVCR.SM are disabled then at any point we
+ * may disable TIF_SME and reenable traps.
+ */
+
+
 /*
  * TIF_SVE controls whether a task can use SVE without trapping while
- * in userspace, and also the way a task's FPSIMD/SVE state is stored
- * in thread_struct.
+ * in userspace, and also (together with TIF_SME) the way a task's
+ * FPSIMD/SVE state is stored in thread_struct.
  *
  * The kernel uses this flag to track whether a user task is actively
  * using SVE, and therefore whether full SVE register state needs to
  * be tracked.  If not, the cheaper FPSIMD context handling code can
  * be used instead of the more costly SVE equivalents.
  *
- *  * TIF_SVE set:
+ *  * TIF_SVE or SVCR.SM set:
  *
  *    The task can execute SVE instructions while in userspace without
  *    trapping to the kernel.
@@ -319,7 +331,8 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  *    When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
  *    corresponding Zn), P0-P15 and FFR are encoded in in
  *    task->thread.sve_state, formatted appropriately for vector
- *    length task->thread.sve_vl.
+ *    length task->thread.sve_vl or, if SVCR.SM is set,
+ *    task->thread.sme_vl.
  *
  *    task->thread.sve_state must point to a valid buffer at least
  *    sve_state_size(task) bytes in size.
@@ -357,19 +370,40 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  */
 static void task_fpsimd_load(void)
 {
+	bool restore_sve_regs = false;
+	bool restore_ffr;
+
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
-		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
-
+	/* Check if we should restore SVE first */
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
+		restore_sve_regs = true;
+		restore_ffr = true;
+	}
+
+	/* Restore SME, override SVE register configuration if needed */
+	if (system_supports_sme()) {
+		unsigned long sme_vl = task_get_sme_vl(current);
+
+		if (test_thread_flag(TIF_SME))
+			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
+
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
+		if (thread_sm_enabled(&current->thread)) {
+			restore_sve_regs = true;
+			restore_ffr = system_supports_fa64();
+		}
+	}
+
+	if (restore_sve_regs)
 		sve_load_state(sve_pffr(&current->thread),
-			       &current->thread.uw.fpsimd_state.fpsr, true);
-	} else {
+			       &current->thread.uw.fpsimd_state.fpsr,
+			       restore_ffr);
+	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
-	}
 }
 
 /*
@@ -381,6 +415,9 @@ static void fpsimd_save(void)
 	struct fpsimd_last_state_struct const *last =
 		this_cpu_ptr(&fpsimd_last_state);
 	/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
+	bool save_sve_regs = false;
+	bool save_ffr;
+	unsigned int vl;
 
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
@@ -388,15 +425,33 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) &&
-	    test_thread_flag(TIF_SME)) {
+	if (test_thread_flag(TIF_SVE)) {
+		save_sve_regs = true;
+		save_ffr = true;
+		vl = last->sve_vl;
+	}
+
+	if (system_supports_sme()) {
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (thread_za_enabled(&current->thread)) {
+			/* ZA state managment is not implemented yet */
+			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
+			return;
+		}
+
+		/* If we are in streaming mode override regular SVE. */
+		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
+			save_sve_regs = true;
+			save_ffr = system_supports_fa64();
+			vl = last->sme_vl;
+		}
 	}
 
-	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
-	    test_thread_flag(TIF_SVE)) {
-		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
+	if (IS_ENABLED(CONFIG_ARM64_SVE) && save_sve_regs) {
+		/* Get the configured VL from RDVL, will account for SM */
+		if (WARN_ON(sve_get_vl() != vl)) {
 			/*
 			 * Can't save the user regs, so current would
 			 * re-enter user with corrupt state.
@@ -407,8 +462,8 @@ static void fpsimd_save(void)
 		}
 
 		sve_save_state((char *)last->sve_state +
-					sve_ffr_offset(last->sve_vl),
-			       &last->st->fpsr, true);
+					sve_ffr_offset(vl),
+			       &last->st->fpsr, save_ffr);
 	} else {
 		fpsimd_save_state(last->st);
 	}
@@ -613,7 +668,14 @@ static void sve_to_fpsimd(struct task_struct *task)
  */
 static size_t sve_state_size(struct task_struct const *task)
 {
-	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(task_get_sve_vl(task)));
+	unsigned int vl = 0;
+
+	if (system_supports_sve())
+		vl = task_get_sve_vl(task);
+	if (system_supports_sme())
+		vl = max(vl, task_get_sme_vl(task));
+
+	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl));
 }
 
 /*
@@ -742,7 +804,8 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	}
 
 	fpsimd_flush_task_state(task);
-	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
+	if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
+	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
 	if (system_supports_sme() && type == ARM64_VEC_SME)
@@ -1369,6 +1432,9 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
+	if (system_supports_sme())
+		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1412,6 +1478,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
@@ -1427,7 +1494,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, u64 *svcr)
+			      unsigned int sve_vl, unsigned int sme_vl,
+			      u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1439,6 +1507,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
+	last->sme_vl = sme_vl;
 }
 
 /*
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 04698c4bcd30..902c598b7ed2 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -109,7 +109,8 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
-					 vcpu->arch.sve_max_vl);
+					 vcpu->arch.sve_max_vl,
+					 0);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:51 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:51 +0000
Subject: [PATCH v8 15/38] arm64/sme: Implement ZA context switching
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-16-broonie@kernel.org>

Allocate space for storing ZA on first access to SME and use that to save
and restore ZA state when context switching. We do this by using the vector
form of the LDR and STR ZA instructions, these do not require streaming
mode and have implementation recommendations that they avoid contention
issues in shared SMCU implementations.

Since ZA is architecturally guaranteed to be zeroed when enabled we do not
need to explicitly zero ZA, either we will be restoring from a saved copy
or trapping on first use of SME so we know that ZA must be disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  5 ++++-
 arch/arm64/include/asm/fpsimdmacros.h | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/kvm_host.h     |  3 +++
 arch/arm64/include/asm/processor.h    |  1 +
 arch/arm64/kernel/entry-fpsimd.S      | 22 ++++++++++++++++++++++
 arch/arm64/kernel/fpsimd.c            | 20 +++++++++++++-------
 arch/arm64/kvm/fpsimd.c               |  2 +-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 650ec642159c..af404e5b8d82 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,7 +47,8 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     unsigned int sme_vl, u64 *svcr);
+				     void *za_state, unsigned int sme_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
@@ -90,6 +91,8 @@ extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
 extern void sme_set_vq(unsigned long vq_minus_1);
+extern void za_save_state(void *state);
+extern void za_load_state(void const *state);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index a50fa1eab730..35d67e393519 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -318,3 +318,25 @@
 		ldr		w\nxtmp, [\xpfpsr, #4]
 		msr		fpcr, x\nxtmp
 .endm
+
+.macro sme_save_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_str_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
+
+.macro sme_load_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_ldr_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..7dc85d5a6552 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -280,8 +280,11 @@ struct vcpu_reset_state {
 
 struct kvm_vcpu_arch {
 	struct kvm_cpu_context ctxt;
+
+	/* Guest floating point state */
 	void *sve_state;
 	unsigned int sve_max_vl;
+	u64 svcr;
 
 	/* Stage 2 paging state used by the hardware on next switch */
 	struct kvm_s2_mmu *hw_mmu;
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6e2af9de153c..5a5c5edd76df 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -153,6 +153,7 @@ struct thread_struct {
 
 	unsigned int		fpsimd_cpu;
 	void			*sve_state;	/* SVE registers, if any */
+	void			*za_state;	/* ZA register, if any */
 	unsigned int		vl[ARM64_VEC_MAX];	/* vector length */
 	unsigned int		vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */
 	unsigned long		fault_address;	/* fault info */
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index 6f88c0f86d50..229436f33df5 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -99,4 +99,26 @@ SYM_FUNC_START(sme_set_vq)
 	ret
 SYM_FUNC_END(sme_set_vq)
 
+/*
+ * Save the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_save_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_save_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_save_state)
+
+/*
+ * Load the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_load_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_load_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_load_state)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 12fef62cf07a..c9e8186e69c0 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	void *za_state;
 	u64 *svcr;
 	unsigned int sve_vl;
 	unsigned int sme_vl;
@@ -387,11 +388,15 @@ static void task_fpsimd_load(void)
 	if (system_supports_sme()) {
 		unsigned long sme_vl = task_get_sme_vl(current);
 
+		/* Ensure VL is set up for restoring data */
 		if (test_thread_flag(TIF_SME))
 			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
 
 		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
 
+		if (thread_za_enabled(&current->thread))
+			za_load_state(current->thread.za_state);
+
 		if (thread_sm_enabled(&current->thread)) {
 			restore_sve_regs = true;
 			restore_ffr = system_supports_fa64();
@@ -435,11 +440,10 @@ static void fpsimd_save(void)
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
 
-		if (thread_za_enabled(&current->thread)) {
-			/* ZA state managment is not implemented yet */
-			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
-			return;
-		}
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (*svcr & SYS_SVCR_EL0_ZA_MASK)
+			za_save_state(last->za_state);
 
 		/* If we are in streaming mode override regular SVE. */
 		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
@@ -1477,6 +1481,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	WARN_ON(!system_supports_fpsimd());
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
+	last->za_state = current->thread.za_state;
 	last->sve_vl = task_get_sve_vl(current);
 	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
@@ -1494,8 +1499,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, unsigned int sme_vl,
-			      u64 *svcr)
+			      unsigned int sve_vl, void *za_state,
+			      unsigned int sme_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1506,6 +1511,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->st = st;
 	last->svcr = svcr;
 	last->sve_state = sve_state;
+	last->za_state = za_state;
 	last->sve_vl = sve_vl;
 	last->sme_vl = sme_vl;
 }
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 902c598b7ed2..338733ac63f8 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -110,7 +110,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl,
-					 0);
+					 NULL, 0, &vcpu->arch.svcr);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:52 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:52 +0000
Subject: [PATCH v8 16/38] arm64/sme: Implement traps and syscall handling for
 SME
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-17-broonie@kernel.org>

By default all SME operations in userspace will trap.  When this happens
we allocate storage space for the SME register state, set up the SVE
registers and disable traps.  We do not need to initialize ZA since the
architecture guarantees that it will be zeroed when enabled and when we
trap ZA is disabled.

On syscall we exit streaming mode if we were previously in it and ensure
that all but the lower 128 bits of the registers are zeroed while
preserving the state of ZA. This follows the aarch64 PCS for SME, ZA
state is preserved over a function call and streaming mode is exited.
Since the traps for SME do not distinguish between streaming mode SVE
and ZA usage if ZA is in use rather than reenabling traps we instead
zero the parts of the SVE registers not shared with FPSIMD and leave SME
enabled, this simplifies handling SME traps. If ZA is not in use then we
reenable SME traps and fall through to normal handling of SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h       |   1 +
 arch/arm64/include/asm/exception.h |   1 +
 arch/arm64/include/asm/fpsimd.h    |  27 +++++
 arch/arm64/kernel/entry-common.c   |  11 ++
 arch/arm64/kernel/fpsimd.c         | 180 ++++++++++++++++++++++++++---
 arch/arm64/kernel/process.c        |  12 +-
 arch/arm64/kernel/syscall.c        |  34 +++++-
 7 files changed, 242 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 43872e0cfd1e..0467837fd66b 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -76,6 +76,7 @@
 #define ESR_ELx_IL_SHIFT	(25)
 #define ESR_ELx_IL		(UL(1) << ESR_ELx_IL_SHIFT)
 #define ESR_ELx_ISS_MASK	(ESR_ELx_IL - 1)
+#define ESR_ELx_ISS(esr)	((esr) & ESR_ELx_ISS_MASK)
 
 /* ISS field definitions shared by different classes */
 #define ESR_ELx_WNR_SHIFT	(6)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 339477dca551..2add7f33b7c2 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -64,6 +64,7 @@ void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr,
 			struct pt_regs *regs);
 void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs);
 void do_sve_acc(unsigned int esr, struct pt_regs *regs);
+void do_sme_acc(unsigned int esr, struct pt_regs *regs);
 void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs);
 void do_sysinstr(unsigned int esr, struct pt_regs *regs);
 void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index af404e5b8d82..3ca152aaf7c9 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -282,6 +282,16 @@ static inline void sve_setup(void) { }
 
 #ifdef CONFIG_ARM64_SME
 
+static inline void sme_user_disable(void)
+{
+	sysreg_clear_set(cpacr_el1, CPACR_EL1_SMEN_EL0EN, 0);
+}
+
+static inline void sme_user_enable(void)
+{
+	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_SMEN_EL0EN);
+}
+
 static inline void sme_smstart_sm(void)
 {
 	asm volatile(".inst 0xd503437f");
@@ -309,16 +319,33 @@ static inline int sme_max_virtualisable_vl(void)
 	return vec_max_virtualisable_vl(ARM64_VEC_SME);
 }
 
+extern void sme_alloc(struct task_struct *task);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
 
+/*
+ * Return how many bytes of memory are required to store the full SME
+ * specific state (currently just ZA) for task, given task's currently
+ * configured vector length.
+ */
+static inline size_t za_state_size(struct task_struct const *task)
+{
+	unsigned int vl = task_get_sme_vl(task);
+
+	return ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));
+}
+
 #else
 
+static inline void sme_user_disable(void) { BUILD_BUG(); }
+static inline void sme_user_enable(void) { BUILD_BUG(); }
+
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_alloc(struct task_struct *task) { }
 static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..b2ad525d6c87 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -524,6 +524,14 @@ static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
 	exit_to_user_mode(regs);
 }
 
+static void noinstr el0_sme_acc(struct pt_regs *regs, unsigned long esr)
+{
+	enter_from_user_mode(regs);
+	local_daif_restore(DAIF_PROCCTX);
+	do_sme_acc(esr, regs);
+	exit_to_user_mode(regs);
+}
+
 static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
 {
 	enter_from_user_mode(regs);
@@ -632,6 +640,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 	case ESR_ELx_EC_SVE:
 		el0_sve_acc(regs, esr);
 		break;
+	case ESR_ELx_EC_SME:
+		el0_sme_acc(regs, esr);
+		break;
 	case ESR_ELx_EC_FP_EXC64:
 		el0_fpsimd_exc(regs, esr);
 		break;
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c9e8186e69c0..33f80512753d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -209,6 +209,12 @@ static void set_sme_default_vl(int val)
 	set_default_vl(ARM64_VEC_SME, val);
 }
 
+static void sme_free(struct task_struct *);
+
+#else
+
+static inline void sme_free(struct task_struct *t) { }
+
 #endif
 
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
@@ -409,6 +415,21 @@ static void task_fpsimd_load(void)
 			       restore_ffr);
 	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
+
+	/*
+	 * If we didn't set up any SVE registers but we do have SME
+	 * enabled for userspace then ensure the SVE registers are
+	 * flushed since userspace can switch to streaming mode and
+	 * view the register state without trapping.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME) &&
+	    !restore_sve_regs) {
+		int sve_vq_minus_one;
+
+		sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(sve_vq_minus_one);
+		sve_flush_live(true, sve_vq_minus_one);
+	}
 }
 
 /*
@@ -812,18 +833,22 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
-	if (system_supports_sme() && type == ARM64_VEC_SME)
+	if (system_supports_sme() && type == ARM64_VEC_SME) {
 		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
 				       SYS_SVCR_EL0_ZA_MASK);
+		clear_thread_flag(TIF_SME);
+	}
 
 	if (task == current)
 		put_cpu_fpsimd_context();
 
 	/*
-	 * Force reallocation of task SVE state to the correct size
-	 * on next use:
+	 * Force reallocation of task SVE and SME state to the correct
+	 * size on next use:
 	 */
 	sve_free(task);
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		sme_free(task);
 
 	task_set_vl(task, type, vl);
 
@@ -1158,12 +1183,43 @@ void __init sve_setup(void)
 void fpsimd_release_task(struct task_struct *dead_task)
 {
 	__sve_free(dead_task);
+	sme_free(dead_task);
 }
 
 #endif /* CONFIG_ARM64_SVE */
 
 #ifdef CONFIG_ARM64_SME
 
+/* This will move to uapi/asm/sigcontext.h when signals are implemented */
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+/*
+ * Ensure that task->thread.za_state is allocated and sufficiently large.
+ *
+ * This function should be used only in preparation for replacing
+ * task->thread.za_state with new data.  The memory is always zeroed
+ * here to prevent stale data from showing through: this is done in
+ * the interest of testability and predictability, the architecture
+ * guarantees that when ZA is enabled it will be zeroed.
+ */
+void sme_alloc(struct task_struct *task)
+{
+	if (task->thread.za_state) {
+		memset(task->thread.za_state, 0, za_state_size(task));
+		return;
+	}
+
+	/* This could potentially be up to 64K. */
+	task->thread.za_state =
+		kzalloc(za_state_size(task), GFP_KERNEL);
+}
+
+static void sme_free(struct task_struct *task)
+{
+	kfree(task->thread.za_state);
+	task->thread.za_state = NULL;
+}
+
 void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 {
 	/* Set priority for all PEs to architecturally defined minimum */
@@ -1273,6 +1329,29 @@ void __init sme_setup(void)
 
 #endif /* CONFIG_ARM64_SME */
 
+static void sve_init_regs(void)
+{
+	/*
+	 * Convert the FPSIMD state to SVE, zeroing all the state that
+	 * is not shared with FPSIMD. If (as is likely) the current
+	 * state is live in the registers then do this there and
+	 * update our metadata for the current task including
+	 * disabling the trap, otherwise update our in-memory copy.
+	 * We are guaranteed to not be in streaming mode, we can only
+	 * take a SVE trap when not in streaming mode and we can't be
+	 * in streaming mode when taking a SME trap.
+	 */
+	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+		unsigned long vq_minus_one =
+			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(vq_minus_one);
+		sve_flush_live(true, vq_minus_one);
+		fpsimd_bind_task_to_cpu();
+	} else {
+		fpsimd_to_sve(current);
+	}
+}
+
 /*
  * Trapped SVE access
  *
@@ -1304,22 +1383,77 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 		WARN_ON(1); /* SVE access shouldn't have trapped */
 
 	/*
-	 * Convert the FPSIMD state to SVE, zeroing all the state that
-	 * is not shared with FPSIMD. If (as is likely) the current
-	 * state is live in the registers then do this there and
-	 * update our metadata for the current task including
-	 * disabling the trap, otherwise update our in-memory copy.
+	 * Even if the task can have used streaming mode we can only
+	 * generate SVE access traps in normal SVE mode and
+	 * transitioning out of streaming mode may discard any
+	 * streaming mode state.  Always clear the high bits to avoid
+	 * any potential errors tracking what is properly initialised.
 	 */
+	sve_init_regs();
+
+	put_cpu_fpsimd_context();
+}
+
+/*
+ * Trapped SME access
+ *
+ * Storage is allocated for the full SVE and SME state, the current
+ * FPSIMD register contents are migrated to SVE if SVE is not already
+ * active, and the access trap is disabled.
+ *
+ * TIF_SME should be clear on entry: otherwise, fpsimd_restore_current_state()
+ * would have disabled the SME access trap for userspace during
+ * ret_to_user, making an SVE access trap impossible in that case.
+ */
+void do_sme_acc(unsigned int esr, struct pt_regs *regs)
+{
+	/* Even if we chose not to use SME, the hardware could still trap: */
+	if (unlikely(!system_supports_sme()) || WARN_ON(is_compat_task())) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	/*
+	 * If this not a trap due to SME being disabled then something
+	 * is being used in the wrong mode, report as SIGILL.
+	 */
+	if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	sve_alloc(current);
+	sme_alloc(current);
+	if (!current->thread.sve_state || !current->thread.za_state) {
+		force_sig(SIGKILL);
+		return;
+	}
+
+	get_cpu_fpsimd_context();
+
+	/* With TIF_SME userspace shouldn't generate any traps */
+	if (test_and_set_thread_flag(TIF_SME))
+		WARN_ON(1);
+
 	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
 		unsigned long vq_minus_one =
-			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
-		sve_set_vq(vq_minus_one);
-		sve_flush_live(true, vq_minus_one);
+			sve_vq_from_vl(task_get_sme_vl(current)) - 1;
+		sme_set_vq(vq_minus_one);
+
 		fpsimd_bind_task_to_cpu();
-	} else {
-		fpsimd_to_sve(current);
 	}
 
+	/*
+	 * If SVE was not already active initialise the SVE registers,
+	 * any non-shared state between the streaming and regular SVE
+	 * registers is architecturally guaranteed to be zeroed when
+	 * we enter streaming mode.  We do not need to initialize ZA
+	 * since ZA must be disabled at this point and enabling ZA is
+	 * architecturally defined to zero ZA.
+	 */
+	if (system_supports_sve() && !test_thread_flag(TIF_SVE))
+		sve_init_regs();
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1436,8 +1570,11 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
-	if (system_supports_sme())
+	if (system_supports_sme()) {
+		clear_thread_flag(TIF_SME);
+		sme_free(current);
 		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+	}
 
 	put_cpu_fpsimd_context();
 }
@@ -1487,15 +1624,24 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
+	/*
+	 * Toggle SVE and SME trapping for userspace if needed, these
+	 * are serialsied by ret_to_user().
+	 */
+	if (system_supports_sme()) {
+		if (test_thread_flag(TIF_SME))
+			sme_user_enable();
+		else
+			sme_user_disable();
+	}
+
 	if (system_supports_sve()) {
-		/* Toggle SVE trapping for userspace if needed */
 		if (test_thread_flag(TIF_SVE))
 			sve_user_enable();
 		else
 			sve_user_disable();
-
-		/* Serialised by exception return to user */
 	}
+
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f2d32a29641c..f7fcc625ea0e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -299,17 +299,19 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
 
 	/*
-	 * Detach src's sve_state (if any) from dst so that it does not
-	 * get erroneously used or freed prematurely.  dst's sve_state
-	 * will be allocated on demand later on if dst uses SVE.
-	 * For consistency, also clear TIF_SVE here: this could be done
+	 * Detach src's sve/za_state (if any) from dst so that it does not
+	 * get erroneously used or freed prematurely.  dst's copies
+	 * will be allocated on demand later on if dst uses SVE/SME.
+	 * For consistency, also clear TIF_SVE/SME here: this could be done
 	 * later in copy_process(), but to avoid tripping up future
-	 * maintainers it is best not to leave TIF_SVE and sve_state in
+	 * maintainers it is best not to leave TIF flags and buffers in
 	 * an inconsistent state, even temporarily.
 	 */
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.za_state = NULL;
+	clear_tsk_thread_flag(dst, TIF_SME);
 	dst->thread.svcr = 0;
 
 	/* clear any pending asynchronous tag fault raised by the parent */
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index c938603b3ba0..958b2d926354 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -158,11 +158,41 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 	syscall_trace_exit(regs);
 }
 
-static inline void sve_user_discard(void)
+/*
+ * As per the ABI exit SME streaming mode and clear the SVE state not
+ * shared with FPSIMD on syscall entry.
+ */
+static inline void fp_user_discard(void)
 {
+	/*
+	 * If SME is active then exit streaming mode.  If ZA is active
+	 * then flush the SVE registers but leave userspace access to
+	 * both SVE and SME enabled, otherwise disable SME for the
+	 * task and fall through to disabling SVE too.  This means
+	 * that after a syscall we never have any SME register state
+	 * to track, if this changes the KVM code will need updating.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME)) {
+		u64 svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (svcr & SYS_SVCR_EL0_SM_MASK)
+			sme_smstop_sm();
+
+		if (!(svcr & SYS_SVCR_EL0_ZA_MASK)) {
+			clear_thread_flag(TIF_SME);
+			sme_user_disable();
+		}
+	}
+
+
 	if (!system_supports_sve())
 		return;
 
+	/*
+	 * If SME is not active then disable SVE, the registers will
+	 * be cleared when userspace next attempts to access them and
+	 * we do not need to track the SVE register state until then.
+	 */
 	clear_thread_flag(TIF_SVE);
 
 	/*
@@ -177,7 +207,7 @@ static inline void sve_user_discard(void)
 
 void do_el0_svc(struct pt_regs *regs)
 {
-	sve_user_discard();
+	fp_user_discard();
 	el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
 }
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:53 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:53 +0000
Subject: [PATCH v8 17/38] arm64/sme: Disable ZA and streaming mode when
 handling signals
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-18-broonie@kernel.org>

The ABI requires that streaming mode and ZA are disabled when invoking
signal handlers, do this in setup_return() when we prepare the task state
for the signal handler.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/signal.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index d8aaf4b6f432..cda04fd73333 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -758,6 +758,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 	/* TCO (Tag Check Override) always cleared for signal handlers */
 	regs->pstate &= ~PSR_TCO_BIT;
 
+	/* Signal handlers are invoked with ZA and streaming mode disabled */
+	if (system_supports_sme()) {
+		current->thread.svcr &= ~(SYS_SVCR_EL0_ZA_MASK |
+					  SYS_SVCR_EL0_SM_MASK);
+		sme_smstop();
+	}
+
 	if (ka->sa.sa_flags & SA_RESTORER)
 		sigtramp = ka->sa.sa_restorer;
 	else
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:54 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:54 +0000
Subject: [PATCH v8 18/38] arm64/sme: Implement streaming SVE signal handling
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-19-broonie@kernel.org>

When in streaming mode we have the same set of SVE registers as we do in
regular SVE mode with the exception of FFR and the use of the SME vector
length. Provide signal handling for these registers by taking one of the
reserved words in the SVE signal context as a flags field and defining a
flag with a flag which is set for streaming mode. When the flag is set the
vector length is set to the streaming mode vector length and we save and
restore streaming mode data. We support entering or leaving streaming mode
based on the value of the flag but do not support changing the vector
length, this is not currently supported SVE signal handling.

We could instead allocate a separate record in the signal frame for the
streaming mode SVE context but this inflates the size of the maximal signal
frame required and adds complication when validating signal frames from
userspace, especially given the current structure of the code.

Any implementation of support for streaming mode vectors in signals will
have some potential for causing issues for applications that attempt to
handle SVE vectors in signals, use streaming mode but do not understand
streaming mode in their signal handling code, it is hard to identify a
case that is clearly better than any other - they all have cases where
they could cause unexpected register corruption or faults.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h | 16 ++++++--
 arch/arm64/kernel/signal.c               | 48 ++++++++++++++++++------
 2 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 0c796c795dbe..3a3366d4fbc2 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -134,9 +134,12 @@ struct extra_context {
 struct sve_context {
 	struct _aarch64_ctx head;
 	__u16 vl;
-	__u16 __reserved[3];
+	__u16 flags;
+	__u16 __reserved[2];
 };
 
+#define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -186,9 +189,16 @@ struct sve_context {
  * sve_context.vl must equal the thread's current vector length when
  * doing a sigreturn.
  *
+ * On systems with support for SME the SVE register state may reflect either
+ * streaming or non-streaming mode.  In streaming mode the streaming mode
+ * vector length will be used and the flag SVE_SIG_FLAG_SM will be set in
+ * the flags field. It is permitted to enter or leave streaming mode in
+ * a signal return, applications should take care to ensure that any difference
+ * in vector length between the two modes is handled, including any resixing
+ * and movement of context blocks.
  *
- * Note: for all these macros, the "vq" argument denotes the SVE
- * vector length in quadwords (i.e., units of 128 bits).
+ * Note: for all these macros, the "vq" argument denotes the vector length
+ * in quadwords (i.e., units of 128 bits).
  *
  * The correct way to obtain vq is to use sve_vq_from_vl(vl).  The
  * result is valid if and only if sve_vl_valid(vl) is true.  This is
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index cda04fd73333..5e6ec6ed8a1c 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -227,11 +227,17 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 {
 	int err = 0;
 	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	u16 flags = 0;
 	unsigned int vl = task_get_sve_vl(current);
 	unsigned int vq = 0;
 
-	if (test_thread_flag(TIF_SVE))
+	if (thread_sm_enabled(&current->thread)) {
+		vl = task_get_sme_vl(current);
 		vq = sve_vq_from_vl(vl);
+		flags |= SVE_SIG_FLAG_SM;
+	} else if (test_thread_flag(TIF_SVE)) {
+		vq = sve_vq_from_vl(vl);
+	}
 
 	memset(reserved, 0, sizeof(reserved));
 
@@ -239,6 +245,7 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
 			 &ctx->head.size, err);
 	__put_user_error(vl, &ctx->vl, err);
+	__put_user_error(flags, &ctx->flags, err);
 	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
 	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
 
@@ -259,18 +266,28 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
 	int err;
-	unsigned int vq;
+	unsigned int vl, vq;
 	struct user_fpsimd_state fpsimd;
 	struct sve_context sve;
 
 	if (__copy_from_user(&sve, user->sve, sizeof(sve)))
 		return -EFAULT;
 
-	if (sve.vl != task_get_sve_vl(current))
+	if (sve.flags & SVE_SIG_FLAG_SM) {
+		if (!system_supports_sme())
+			return -EINVAL;
+
+		vl = task_get_sme_vl(current);
+	} else {
+		vl = task_get_sve_vl(current);
+	}
+
+	if (sve.vl != vl)
 		return -EINVAL;
 
 	if (sve.head.size <= sizeof(*user->sve)) {
 		clear_thread_flag(TIF_SVE);
+		current->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
 		goto fpsimd_only;
 	}
 
@@ -302,7 +319,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (err)
 		return -EFAULT;
 
-	set_thread_flag(TIF_SVE);
+	if (sve.flags & SVE_SIG_FLAG_SM)
+		current->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+	else
+		set_thread_flag(TIF_SVE);
 
 fpsimd_only:
 	/* copy the FP and status/control registers */
@@ -394,7 +414,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			break;
 
 		case SVE_MAGIC:
-			if (!system_supports_sve())
+			if (!system_supports_sve() && !system_supports_sme())
 				goto invalid;
 
 			if (user->sve)
@@ -593,11 +613,16 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 	if (system_supports_sve()) {
 		unsigned int vq = 0;
 
-		if (add_all || test_thread_flag(TIF_SVE)) {
-			int vl = sve_max_vl();
+		if (add_all || test_thread_flag(TIF_SVE) ||
+		    thread_sm_enabled(&current->thread)) {
+			int vl = max(sve_max_vl(), sme_max_vl());
 
-			if (!add_all)
-				vl = task_get_sve_vl(current);
+			if (!add_all) {
+				if (thread_sm_enabled(&current->thread))
+					vl = task_get_sme_vl(current);
+				else
+					vl = task_get_sve_vl(current);
+			}
 
 			vq = sve_vq_from_vl(vl);
 		}
@@ -648,8 +673,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
 	}
 
-	/* Scalable Vector Extension state, if present */
-	if (system_supports_sve() && err == 0 && user->sve_offset) {
+	/* Scalable Vector Extension state (including streaming), if present */
+	if ((system_supports_sve() || system_supports_sme()) &&
+	    err == 0 && user->sve_offset) {
 		struct sve_context __user *sve_ctx =
 			apply_user_offset(user, user->sve_offset);
 		err |= preserve_sve_context(sve_ctx);
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:55 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:55 +0000
Subject: [PATCH v8 19/38] arm64/sme: Implement ZA signal handling
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-20-broonie@kernel.org>

Implement support for ZA in signal handling in a very similar way to how
we implement support for SVE registers, using a signal context structure
with optional register state after it. Where present this register state
stores the ZA matrix as a series of horizontal vectors numbered from 0 to
VL/8 in the endinanness independent format used for vectors.

As with SVE we do not allow changes in the vector length during signal
return but we do allow ZA to be enabled or disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h |  41 +++++++
 arch/arm64/kernel/fpsimd.c               |   3 -
 arch/arm64/kernel/signal.c               | 139 +++++++++++++++++++++++
 3 files changed, 180 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 3a3366d4fbc2..d45bdf2c8b26 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -140,6 +140,14 @@ struct sve_context {
 
 #define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
 
+#define ZA_MAGIC	0x54366345
+
+struct za_context {
+	struct _aarch64_ctx head;
+	__u16 vl;
+	__u16 __reserved[3];
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -259,4 +267,37 @@ struct sve_context {
 #define SVE_SIG_CONTEXT_SIZE(vq) \
 		(SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 
+/*
+ * If the ZA register is enabled for the thread at signal delivery then,
+ * za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * and the register data may be accessed using the ZA_SIG_*() macros.
+ *
+ * If za_context.head.size < ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * then ZA was not enabled and no register data was included in which case
+ * ZA register was not enabled for the thread and no register data
+ * the ZA_SIG_*() macros should not be used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the za_context block if it wants to
+ * enable the ZA register when it was previously non-live or vice-versa.
+ * This may require the caller to allocate fresh memory and/or move other
+ * context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * za_context.vl must equal the thread's current SME vector length when
+ * doing a sigreturn.
+ */
+
+#define ZA_SIG_REGS_OFFSET					\
+	((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \
+				  (SVE_SIG_ZREG_SIZE(vq) * n))
+
+#define ZA_SIG_CONTEXT_SIZE(vq) \
+		(ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
+
 #endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 33f80512753d..2242c14a5a05 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1190,9 +1190,6 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #ifdef CONFIG_ARM64_SME
 
-/* This will move to uapi/asm/sigcontext.h when signals are implemented */
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
-
 /*
  * Ensure that task->thread.za_state is allocated and sufficiently large.
  *
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 5e6ec6ed8a1c..8efa78765cad 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -57,6 +57,7 @@ struct rt_sigframe_user_layout {
 	unsigned long fpsimd_offset;
 	unsigned long esr_offset;
 	unsigned long sve_offset;
+	unsigned long za_offset;
 	unsigned long extra_offset;
 	unsigned long end_offset;
 };
@@ -219,6 +220,7 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 struct user_ctxs {
 	struct fpsimd_context __user *fpsimd;
 	struct sve_context __user *sve;
+	struct za_context __user *za;
 };
 
 #ifdef CONFIG_ARM64_SVE
@@ -347,6 +349,101 @@ extern int restore_sve_fpsimd_context(struct user_ctxs *user);
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int preserve_za_context(struct za_context __user *ctx)
+{
+	int err = 0;
+	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	unsigned int vl = task_get_sme_vl(current);
+	unsigned int vq;
+
+	if (thread_za_enabled(&current->thread))
+		vq = sve_vq_from_vl(vl);
+	else
+		vq = 0;
+
+	memset(reserved, 0, sizeof(reserved));
+
+	__put_user_error(ZA_MAGIC, &ctx->head.magic, err);
+	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
+			 &ctx->head.size, err);
+	__put_user_error(vl, &ctx->vl, err);
+	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
+	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
+
+	if (vq) {
+		/*
+		 * This assumes that the ZA state has already been saved to
+		 * the task struct by calling the function
+		 * fpsimd_signal_preserve_current_state().
+		 */
+		err |= __copy_to_user((char __user *)ctx + ZA_SIG_REGS_OFFSET,
+				      current->thread.za_state,
+				      ZA_SIG_REGS_SIZE(vq));
+	}
+
+	return err ? -EFAULT : 0;
+}
+
+static int restore_za_context(struct user_ctxs __user *user)
+{
+	int err;
+	unsigned int vq;
+	struct za_context za;
+
+	if (__copy_from_user(&za, user->za, sizeof(za)))
+		return -EFAULT;
+
+	if (za.vl != task_get_sme_vl(current))
+		return -EINVAL;
+
+	if (za.head.size <= sizeof(*user->za)) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		return 0;
+	}
+
+	vq = sve_vq_from_vl(za.vl);
+
+	if (za.head.size < ZA_SIG_CONTEXT_SIZE(vq))
+		return -EINVAL;
+
+	/*
+	 * Careful: we are about __copy_from_user() directly into
+	 * thread.za_state with preemption enabled, so protection is
+	 * needed to prevent a racing context switch from writing stale
+	 * registers back over the new data.
+	 */
+
+	fpsimd_flush_task_state(current);
+	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
+
+	sme_alloc(current);
+	if (!current->thread.za_state) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		clear_thread_flag(TIF_SME);
+		return -ENOMEM;
+	}
+
+	err = __copy_from_user(current->thread.za_state,
+			       (char __user const *)user->za +
+					ZA_SIG_REGS_OFFSET,
+			       ZA_SIG_REGS_SIZE(vq));
+	if (err)
+		return -EFAULT;
+
+	set_thread_flag(TIF_SME);
+	current->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+	return 0;
+}
+#else /* ! CONFIG_ARM64_SME */
+
+/* Turn any non-optimised out attempts to use these into a link error: */
+extern int preserve_za_context(void __user *ctx);
+extern int restore_za_context(struct user_ctxs *user);
+
+#endif /* ! CONFIG_ARM64_SME */
 
 static int parse_user_sigframe(struct user_ctxs *user,
 			       struct rt_sigframe __user *sf)
@@ -361,6 +458,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 
 	user->fpsimd = NULL;
 	user->sve = NULL;
+	user->za = NULL;
 
 	if (!IS_ALIGNED((unsigned long)base, 16))
 		goto invalid;
@@ -426,6 +524,19 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			user->sve = (struct sve_context __user *)head;
 			break;
 
+		case ZA_MAGIC:
+			if (!system_supports_sme())
+				goto invalid;
+
+			if (user->za)
+				goto invalid;
+
+			if (size < sizeof(*user->za))
+				goto invalid;
+
+			user->za = (struct za_context __user *)head;
+			break;
+
 		case EXTRA_MAGIC:
 			if (have_extra_context)
 				goto invalid;
@@ -549,6 +660,9 @@ static int restore_sigframe(struct pt_regs *regs,
 		}
 	}
 
+	if (err == 0 && system_supports_sme() && user.za)
+		err = restore_za_context(&user);
+
 	return err;
 }
 
@@ -633,6 +747,24 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 			return err;
 	}
 
+	if (system_supports_sme()) {
+		unsigned int vl;
+		unsigned int vq = 0;
+
+		if (add_all)
+			vl = sme_max_vl();
+		else
+			vl = task_get_sme_vl(current);
+
+		if (thread_za_enabled(&current->thread))
+			vq = sve_vq_from_vl(vl);
+
+		err = sigframe_alloc(user, &user->za_offset,
+				     ZA_SIG_CONTEXT_SIZE(vq));
+		if (err)
+			return err;
+	}
+
 	return sigframe_alloc_end(user);
 }
 
@@ -681,6 +813,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		err |= preserve_sve_context(sve_ctx);
 	}
 
+	/* ZA state if present */
+	if (system_supports_sme() && err == 0 && user->za_offset) {
+		struct za_context __user *za_ctx =
+			apply_user_offset(user, user->za_offset);
+		err |= preserve_za_context(za_ctx);
+	}
+
 	if (err == 0 && user->extra_offset) {
 		char __user *sfp = (char __user *)user->sigframe;
 		char __user *userp =
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:56 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:56 +0000
Subject: [PATCH v8 20/38] arm64/sme: Implement ptrace support for streaming
 mode SVE registers
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-21-broonie@kernel.org>

The streaming mode SVE registers are represented using the same data
structures as for SVE but since the vector lengths supported and in use
may not be the same as SVE we represent them with a new type NT_ARM_SSVE.
Unfortunately we only have a single 16 bit reserved field available in
the header so there is no space to fit the current and maximum vector
length for both standard and streaming SVE mode without redefining the
structure in a way the creates a complicatd and fragile ABI. Since FFR
is not present in streaming mode it is read and written as zero.

Setting NT_ARM_SSVE registers will put the task into streaming mode,
similarly setting NT_ARM_SVE registers will exit it. Reads that do not
correspond to the current mode of the task will return the header with
no register data. For compatibility reasons on write setting no flag for
the register type will be interpreted as setting SVE registers, though
users can provide no register data as an alternative mechanism for doing
so.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  13 +-
 arch/arm64/kernel/fpsimd.c           |  21 ++-
 arch/arm64/kernel/ptrace.c           | 212 +++++++++++++++++++++------
 include/uapi/linux/elf.h             |   1 +
 4 files changed, 190 insertions(+), 57 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 758ae984ff97..522b925a78c1 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -109,7 +109,7 @@ struct user_hwdebug_state {
 	}		dbg_regs[16];
 };
 
-/* SVE/FP/SIMD state (NT_ARM_SVE) */
+/* SVE/FP/SIMD state (NT_ARM_SVE & NT_ARM_SSVE) */
 
 struct user_sve_header {
 	__u32 size; /* total meaningful regset content in bytes */
@@ -220,6 +220,7 @@ struct user_sve_header {
 	(SVE_PT_SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - \
 		SVE_PT_SVE_PREGS_OFFSET(vq))
 
+/* For streaming mode SVE (SSVE) FFR must be read and written as zero */
 #define SVE_PT_SVE_FFR_OFFSET(vq) \
 	(SVE_PT_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
 
@@ -240,10 +241,12 @@ struct user_sve_header {
 			- SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1))	\
 		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
-#define SVE_PT_SIZE(vq, flags)						\
-	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		\
-		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	\
-		: SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
+#define SVE_PT_SIZE(vq, flags)						  \
+	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		  \
+		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	  \
+		: ((((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD ?  \
+		    SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags) \
+		  : SVE_PT_REGS_OFFSET)))
 
 /* pointer authentication masks (NT_ARM_PAC_MASK) */
 
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2242c14a5a05..8b111b7f2006 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -645,14 +645,19 @@ static void __fpsimd_to_sve(void *sst, struct user_fpsimd_state const *fst,
  */
 static void fpsimd_to_sve(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void *sst = task->thread.sve_state;
 	struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
 
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	__fpsimd_to_sve(sst, fst, vq);
 }
 
@@ -669,7 +674,7 @@ static void fpsimd_to_sve(struct task_struct *task)
  */
 static void sve_to_fpsimd(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void const *sst = task->thread.sve_state;
 	struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
 	unsigned int i;
@@ -678,7 +683,12 @@ static void sve_to_fpsimd(struct task_struct *task)
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	for (i = 0; i < SVE_NUM_ZREGS; ++i) {
 		p = (__uint128_t const *)ZREG(sst, vq, i);
 		fst->vregs[i] = arm64_le128_to_cpu(*p);
@@ -819,8 +829,7 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	/*
 	 * To ensure the FPSIMD bits of the SVE vector registers are preserved,
 	 * write any live register state back to task_struct, and convert to a
-	 * regular FPSIMD thread.  Since the vector length can only be changed
-	 * with a syscall we can't be in streaming mode while reconfiguring.
+	 * regular FPSIMD thread.
 	 */
 	if (task == current) {
 		get_cpu_fpsimd_context();
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 39dbdfdc38d3..0b8324fa1abc 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -714,21 +714,51 @@ static int system_call_set(struct task_struct *target,
 #ifdef CONFIG_ARM64_SVE
 
 static void sve_init_header_from_task(struct user_sve_header *header,
-				      struct task_struct *target)
+				      struct task_struct *target,
+				      enum vec_type type)
 {
 	unsigned int vq;
+	bool active;
+	bool fpsimd_only;
+	enum vec_type task_type;
 
 	memset(header, 0, sizeof(*header));
 
-	header->flags = test_tsk_thread_flag(target, TIF_SVE) ?
-		SVE_PT_REGS_SVE : SVE_PT_REGS_FPSIMD;
-	if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
-		header->flags |= SVE_PT_VL_INHERIT;
+	/* Check if the requested registers are active for the task */
+	if (thread_sm_enabled(&target->thread))
+		task_type = ARM64_VEC_SME;
+	else
+		task_type = ARM64_VEC_SVE;
+	active = (task_type == type);
+
+	switch (type) {
+	case ARM64_VEC_SVE:
+		if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE);
+		break;
+	case ARM64_VEC_SME:
+		if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = false;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return;
+	}
 
-	header->vl = task_get_sve_vl(target);
+	if (active) {
+		if (fpsimd_only) {
+			header->flags |= SVE_PT_REGS_FPSIMD;
+		} else {
+			header->flags |= SVE_PT_REGS_SVE;
+		}
+	}
+
+	header->vl = task_get_vl(target, type);
 	vq = sve_vq_from_vl(header->vl);
 
-	header->max_vl = sve_max_vl();
+	header->max_vl = vec_max_vl(type);
 	header->size = SVE_PT_SIZE(vq, header->flags);
 	header->max_size = SVE_PT_SIZE(sve_vq_from_vl(header->max_vl),
 				      SVE_PT_REGS_SVE);
@@ -739,19 +769,17 @@ static unsigned int sve_size_from_header(struct user_sve_header const *header)
 	return ALIGN(header->size, SVE_VQ_BYTES);
 }
 
-static int sve_get(struct task_struct *target,
-		   const struct user_regset *regset,
-		   struct membuf to)
+static int sve_get_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  struct membuf to,
+			  enum vec_type type)
 {
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
-	sve_init_header_from_task(&header, target);
+	sve_init_header_from_task(&header, target, type);
 	vq = sve_vq_from_vl(header.vl);
 
 	membuf_write(&to, &header, sizeof(header));
@@ -759,49 +787,61 @@ static int sve_get(struct task_struct *target,
 	if (target == current)
 		fpsimd_preserve_current_state();
 
-	/* Registers: FPSIMD-only case */
-
 	BUILD_BUG_ON(SVE_PT_FPSIMD_OFFSET != sizeof(header));
-	if ((header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
+	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
+
+	switch ((header.flags & SVE_PT_REGS_MASK)) {
+	case SVE_PT_REGS_FPSIMD:
 		return __fpr_get(target, regset, to);
 
-	/* Otherwise: full SVE case */
+	case SVE_PT_REGS_SVE:
+		start = SVE_PT_SVE_OFFSET;
+		end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
+		membuf_write(&to, target->thread.sve_state, end - start);
 
-	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
-	start = SVE_PT_SVE_OFFSET;
-	end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
-	membuf_write(&to, target->thread.sve_state, end - start);
+		start = end;
+		end = SVE_PT_SVE_FPSR_OFFSET(vq);
+		membuf_zero(&to, end - start);
 
-	start = end;
-	end = SVE_PT_SVE_FPSR_OFFSET(vq);
-	membuf_zero(&to, end - start);
+		/*
+		 * Copy fpsr, and fpcr which must follow contiguously in
+		 * struct fpsimd_state:
+		 */
+		start = end;
+		end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
+		membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr,
+			     end - start);
 
-	/*
-	 * Copy fpsr, and fpcr which must follow contiguously in
-	 * struct fpsimd_state:
-	 */
-	start = end;
-	end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
-	membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr, end - start);
+		start = end;
+		end = sve_size_from_header(&header);
+		return membuf_zero(&to, end - start);
 
-	start = end;
-	end = sve_size_from_header(&header);
-	return membuf_zero(&to, end - start);
+	default:
+		return 0;
+	}
 }
 
-static int sve_set(struct task_struct *target,
+static int sve_get(struct task_struct *target,
 		   const struct user_regset *regset,
-		   unsigned int pos, unsigned int count,
-		   const void *kbuf, const void __user *ubuf)
+		   struct membuf to)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SVE);
+}
+
+static int sve_set_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  unsigned int pos, unsigned int count,
+			  const void *kbuf, const void __user *ubuf,
+			  enum vec_type type)
 {
 	int ret;
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
 	if (count < sizeof(header))
 		return -EINVAL;
@@ -814,13 +854,37 @@ static int sve_set(struct task_struct *target,
 	 * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
 	 * vec_set_vector_length(), which will also validate them for us:
 	 */
-	ret = vec_set_vector_length(target, ARM64_VEC_SVE, header.vl,
+	ret = vec_set_vector_length(target, type, header.vl,
 		((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
 	if (ret)
 		goto out;
 
 	/* Actual VL set may be less than the user asked for: */
-	vq = sve_vq_from_vl(task_get_sve_vl(target));
+	vq = sve_vq_from_vl(task_get_vl(target, type));
+
+	/* Enter/exit streaming mode */
+	if (system_supports_sme()) {
+		u64 old_svcr = target->thread.svcr;
+
+		switch (type) {
+		case ARM64_VEC_SVE:
+			target->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
+			break;
+		case ARM64_VEC_SME:
+			target->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+			break;
+		default:
+			WARN_ON_ONCE(1);
+			return -EINVAL;
+		}
+
+		/*
+		 * If we switched then invalidate any existing SVE
+		 * state and ensure there's storage.
+		 */
+		if (target->thread.svcr != old_svcr)
+			sve_alloc(target);
+	}
 
 	/* Registers: FPSIMD-only case */
 
@@ -832,7 +896,10 @@ static int sve_set(struct task_struct *target,
 		goto out;
 	}
 
-	/* Otherwise: full SVE case */
+	/*
+	 * Otherwise: no registers or full SVE case.  For backwards
+	 * compatibility reasons we treat empty flags as SVE registers.
+	 */
 
 	/*
 	 * If setting a different VL from the requested VL and there is
@@ -853,8 +920,9 @@ static int sve_set(struct task_struct *target,
 
 	/*
 	 * Ensure target->thread.sve_state is up to date with target's
-	 * FPSIMD regs, so that a short copyin leaves trailing registers
-	 * unmodified.
+	 * FPSIMD regs, so that a short copyin leaves trailing
+	 * registers unmodified.  Always enable SVE even if going into
+	 * streaming mode.
 	 */
 	fpsimd_sync_to_sve(target);
 	set_tsk_thread_flag(target, TIF_SVE);
@@ -890,8 +958,46 @@ static int sve_set(struct task_struct *target,
 	return ret;
 }
 
+static int sve_set(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SVE);
+}
+
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int ssve_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   struct membuf to)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SME);
+}
+
+static int ssve_set(struct task_struct *target,
+		    const struct user_regset *regset,
+		    unsigned int pos, unsigned int count,
+		    const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SME);
+}
+
+#endif /* CONFIG_ARM64_SME */
+
 #ifdef CONFIG_ARM64_PTR_AUTH
 static int pac_mask_get(struct task_struct *target,
 			const struct user_regset *regset,
@@ -1109,6 +1215,9 @@ enum aarch64_regset {
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SVE,
 #endif
+#ifdef CONFIG_ARM64_SVE
+	REGSET_SSVE,
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
 	REGSET_PAC_ENABLED_KEYS,
@@ -1189,6 +1298,17 @@ static const struct user_regset aarch64_regsets[] = {
 		.set = sve_set,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[REGSET_SSVE] = { /* Streaming mode SVE */
+		.core_note_type = NT_ARM_SSVE,
+		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
+				  SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = ssve_get,
+		.set = ssve_set,
+	},
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
 		.core_note_type = NT_ARM_PAC_MASK,
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61bf4774b8f2..61502388683f 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -427,6 +427,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_PACG_KEYS	0x408	/* ARM pointer authentication generic key */
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
+#define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:57 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:57 +0000
Subject: [PATCH v8 21/38] arm64/sme: Add ptrace support for ZA
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-22-broonie@kernel.org>

The ZA array can be read and written with the NT_ARM_ZA.  Similarly to
our interface for the SVE vector registers the regset consists of a
header with information on the current vector length followed by an
optional register data payload, represented as for signals as a series
of horizontal vectors from 0 to VL/8 in the endianness independent
format used for vectors.

On get if ZA is enabled then register data will be provided, otherwise
it will be omitted.  On set if register data is provided then ZA is
enabled and initialized using the provided data, otherwise it is
disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  56 +++++++++++
 arch/arm64/kernel/ptrace.c           | 144 +++++++++++++++++++++++++++
 include/uapi/linux/elf.h             |   1 +
 3 files changed, 201 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 522b925a78c1..7fa2f7036aa7 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -268,6 +268,62 @@ struct user_pac_generic_keys {
 	__uint128_t	apgakey;
 };
 
+/* ZA state (NT_ARM_ZA) */
+
+struct user_za_header {
+	__u32 size; /* total meaningful regset content in bytes */
+	__u32 max_size; /* maxmium possible size for this thread */
+	__u16 vl; /* current vector length */
+	__u16 max_vl; /* maximum possible vector length */
+	__u16 flags;
+	__u16 __reserved;
+};
+
+/*
+ * Common ZA_PT_* flags:
+ * These must be kept in sync with prctl interface in <linux/prctl.h>
+ */
+#define ZA_PT_VL_INHERIT		((1 << 17) /* PR_SME_VL_INHERIT */ >> 16)
+#define ZA_PT_VL_ONEXEC			((1 << 18) /* PR_SME_SET_VL_ONEXEC */ >> 16)
+
+
+/*
+ * The remainder of the ZA state follows struct user_za_header.  The
+ * total size of the ZA state (including header) depends on the
+ * metadata in the header:  ZA_PT_SIZE(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_za_header to the register data */
+#define ZA_PT_ZA_OFFSET						\
+	((sizeof(struct user_za_header) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+/*
+ * The payload starts at offset ZA_PT_ZA_OFFSET, and is of size
+ * ZA_PT_ZA_SIZE(vq, flags).
+ *
+ * The ZA array is stored as a sequence of horizontal vectors ZAV of SVL/8
+ * bytes each, starting from vector 0.
+ *
+ * Additional data might be appended in the future.
+ *
+ * The ZA matrix is represented in memory in an endianness-invariant layout
+ * which differs from the layout used for the FPSIMD V-registers on big-endian
+ * systems: see sigcontext.h for more explanation.
+ */
+
+#define ZA_PT_ZAV_OFFSET(vq, n) \
+	(ZA_PT_ZA_OFFSET + ((vq * __SVE_VQ_BYTES) * n))
+
+#define ZA_PT_ZA_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_PT_SIZE(vq)						\
+	(ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq))
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 0b8324fa1abc..d6f27d3bf6e7 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -996,6 +996,141 @@ static int ssve_set(struct task_struct *target,
 			      ARM64_VEC_SME);
 }
 
+static int za_get(struct task_struct *target,
+		  const struct user_regset *regset,
+		  struct membuf to)
+{
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	memset(&header, 0, sizeof(header));
+
+	if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+		header.flags |= ZA_PT_VL_INHERIT;
+
+	header.vl = task_get_sme_vl(target);
+	vq = sve_vq_from_vl(header.vl);
+	header.max_vl = sme_max_vl();
+	header.max_size = ZA_PT_SIZE(vq);
+
+	/* If ZA is not active there is only the header */
+	if (thread_za_enabled(&target->thread))
+		header.size = ZA_PT_SIZE(vq);
+	else
+		header.size = ZA_PT_ZA_OFFSET;
+
+	membuf_write(&to, &header, sizeof(header));
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	end = ZA_PT_ZA_OFFSET;
+;
+	if (target == current)
+		fpsimd_preserve_current_state();
+
+	/* Any register data to include? */
+	if (thread_za_enabled(&target->thread)) {
+		start = end;
+		end = ZA_PT_SIZE(vq);
+		membuf_write(&to, target->thread.za_state, end - start);
+	}
+
+	/* Zero any trailing padding */
+	start = end;
+	end = ALIGN(header.size, SVE_VQ_BYTES);
+	return membuf_zero(&to, end - start);
+}
+
+static int za_set(struct task_struct *target,
+		  const struct user_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	if (count < sizeof(header))
+		return -EINVAL;
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &header,
+				 0, sizeof(header));
+	if (ret)
+		goto out;
+
+	/*
+	 * All current ZA_PT_* flags are consumed by
+	 * vec_set_vector_length(), which will also validate them for
+	 * us:
+	 */
+	ret = vec_set_vector_length(target, ARM64_VEC_SME, header.vl,
+		((unsigned long)header.flags) << 16);
+	if (ret)
+		goto out;
+
+	/* Actual VL set may be less than the user asked for: */
+	vq = sve_vq_from_vl(task_get_sme_vl(target));
+
+	/* Ensure there is some SVE storage for streaming mode */
+	if (!target->thread.sve_state) {
+		sve_alloc(target);
+		if (!target->thread.sve_state) {
+			clear_thread_flag(TIF_SME);
+			ret = -ENOMEM;
+			goto out;
+		}
+	}
+
+	/* Allocate/reinit ZA storage */
+	sme_alloc(target);
+	if (!target->thread.za_state) {
+		ret = -ENOMEM;
+		clear_tsk_thread_flag(target, TIF_SME);
+		goto out;
+	}
+
+	/* If there is no data then disable ZA */
+	if (!count) {
+		target->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		goto out;
+	}
+
+	/*
+	 * If setting a different VL from the requested VL and there is
+	 * register data, the data layout will be wrong: don't even
+	 * try to set the registers in this case.
+	 */
+	if (vq != sve_vq_from_vl(header.vl)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	start = ZA_PT_ZA_OFFSET;
+	end = ZA_PT_SIZE(vq);
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 target->thread.za_state,
+				 start, end);
+	if (ret)
+		goto out;
+
+	/* Mark ZA as active and let userspace use it */
+	set_tsk_thread_flag(target, TIF_SME);
+	target->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+out:
+	fpsimd_flush_task_state(target);
+	return ret;
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 #ifdef CONFIG_ARM64_PTR_AUTH
@@ -1217,6 +1352,7 @@ enum aarch64_regset {
 #endif
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SSVE,
+	REGSET_ZA,
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
@@ -1308,6 +1444,14 @@ static const struct user_regset aarch64_regsets[] = {
 		.regset_get = ssve_get,
 		.set = ssve_set,
 	},
+	[REGSET_ZA] = { /* SME ZA */
+		.core_note_type = NT_ARM_ZA,
+		.n = DIV_ROUND_UP(ZA_PT_ZA_SIZE(SVE_VQ_MAX), SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = za_get,
+		.set = za_set,
+	},
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61502388683f..7ef574f3256a 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -428,6 +428,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
 #define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
+#define NT_ARM_ZA	0x40c		/* ARM SME ZA registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:58 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:58 +0000
Subject: [PATCH v8 22/38] arm64/sme: Disable streaming mode and ZA when
 flushing CPU state
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-23-broonie@kernel.org>

Both streaming mode and ZA may increase power consumption when they are
enabled and streaming mode makes many FPSIMD and SVE instructions undefined
which will cause problems for any kernel mode floating point so disable
both when we flush the CPU state. This covers both kernel_neon_begin() and
idle and after flushing the state a reload is always required anyway.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8b111b7f2006..e00d3a9e919c 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1762,6 +1762,15 @@ static void fpsimd_flush_cpu_state(void)
 {
 	WARN_ON(!system_supports_fpsimd());
 	__this_cpu_write(fpsimd_last_state.st, NULL);
+
+	/*
+	 * Leaving streaming mode enabled will cause issues for any kernel
+	 * NEON and leaving streaming mode or ZA enabled may increase power
+	 * consumption.
+	 */
+	if (system_supports_sme())
+		sme_smstop();
+
 	set_thread_flag(TIF_FOREIGN_FPSTATE);
 }
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:10:59 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:10:59 +0000
Subject: [PATCH v8 23/38] arm64/sme: Save and restore streaming mode over EFI
 runtime calls
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-24-broonie@kernel.org>

When saving and restoring the floating point state over an EFI runtime
call ensure that we handle streaming mode, only handling FFR if we are not
in streaming mode and ensuring that we are in normal mode over the call
into runtime services.

We currently assume that ZA will not be modified by runtime services, the
specification is not yet finalised so this may need updating if that
changes.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index e00d3a9e919c..a7077a5d1ed2 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1059,21 +1059,25 @@ int vec_verify_vq_map(enum vec_type type)
 
 static void __init sve_efi_setup(void)
 {
-	struct vl_info *info = &vl_info[ARM64_VEC_SVE];
+	int max_vl = 0;
+	int i;
 
 	if (!IS_ENABLED(CONFIG_EFI))
 		return;
 
+	for (i = 0; i < ARRAY_SIZE(vl_info); i++)
+		max_vl = max(vl_info[i].max_vl, max_vl);
+
 	/*
 	 * alloc_percpu() warns and prints a backtrace if this goes wrong.
 	 * This is evidence of a crippled system and we are returning void,
 	 * so no attempt is made to handle this situation here.
 	 */
-	if (!sve_vl_valid(info->max_vl))
+	if (!sve_vl_valid(max_vl))
 		goto fail;
 
 	efi_sve_state = __alloc_percpu(
-		SVE_SIG_REGS_SIZE(sve_vq_from_vl(info->max_vl)), SVE_VQ_BYTES);
+		SVE_SIG_REGS_SIZE(sve_vq_from_vl(max_vl)), SVE_VQ_BYTES);
 	if (!efi_sve_state)
 		goto fail;
 
@@ -1848,6 +1852,7 @@ EXPORT_SYMBOL(kernel_neon_end);
 static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state);
 static DEFINE_PER_CPU(bool, efi_fpsimd_state_used);
 static DEFINE_PER_CPU(bool, efi_sve_state_used);
+static DEFINE_PER_CPU(bool, efi_sm_state);
 
 /*
  * EFI runtime services support functions
@@ -1882,12 +1887,28 @@ void __efi_fpsimd_begin(void)
 		 */
 		if (system_supports_sve() && likely(efi_sve_state)) {
 			char *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+			u64 svcr;
 
 			__this_cpu_write(efi_sve_state_used, true);
 
+			/* If we are in streaming mode don't touch FFR */
+			if (system_supports_sme()) {
+				svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+				ffr = svcr & SYS_SVCR_EL0_SM_MASK;
+
+				__this_cpu_write(efi_sm_state, ffr);
+			}
+
 			sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
+
+			if (system_supports_sme())
+				sysreg_clear_set_s(SYS_SVCR_EL0,
+						   SYS_SVCR_EL0_SM_MASK, 0);
+
 		} else {
 			fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state));
 		}
@@ -1910,11 +1931,25 @@ void __efi_fpsimd_end(void)
 		if (system_supports_sve() &&
 		    likely(__this_cpu_read(efi_sve_state_used))) {
 			char const *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+
+			/*
+			 * Restore streaming mode; EFI calls are
+			 * normal function calls so should not return in
+			 * streaming mode.
+			 */
+			if (system_supports_sme()) {
+				if (__this_cpu_read(efi_sm_state)) {
+					sysreg_clear_set_s(SYS_SVCR_EL0,
+							   0,
+							   SYS_SVCR_EL0_SM_MASK);
+					ffr = false;
+				}
+			}
 
-			sve_set_vq(sve_vq_from_vl(sve_get_vl()) - 1);
 			sve_load_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
 
 			__this_cpu_write(efi_sve_state_used, false);
 		} else {
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:00 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:00 +0000
Subject: [PATCH v8 24/38] KVM: arm64: Hide SME system registers from guests
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-25-broonie@kernel.org>

For the time being we do not support use of SME by KVM guests, support for
this will be enabled in future. In order to prevent any side effects or
side channels via the new system registers, including the EL0 read/write
register TPIDR2, explicitly undefine all the system registers added by
SME and mask out the SME bitfield in SYS_ID_AA64PFR1.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba316ff..43516eda9143 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1089,6 +1089,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 	case SYS_ID_AA64PFR1_EL1:
 		if (!kvm_has_mte(vcpu->kvm))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
+
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_SME);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1508,7 +1510,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
 	ID_SANITISED(ID_AA64ZFR0_EL1),
-	ID_UNALLOCATED(4,5),
+	ID_HIDDEN(ID_AA64SMFR0_EL1),
 	ID_UNALLOCATED(4,6),
 	ID_UNALLOCATED(4,7),
 
@@ -1551,6 +1553,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
 	{ SYS_DESC(SYS_TRFCR_EL1), undef_access },
+	{ SYS_DESC(SYS_SMPRI_EL1), undef_access },
+	{ SYS_DESC(SYS_SMCR_EL1), undef_access },
 	{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
 	{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
 	{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
@@ -1633,8 +1637,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr },
 	{ SYS_DESC(SYS_CLIDR_EL1), access_clidr },
+	{ SYS_DESC(SYS_SMIDR_EL1), undef_access },
 	{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
 	{ SYS_DESC(SYS_CTR_EL0), access_ctr },
+	{ SYS_DESC(SYS_SVCR_EL0), undef_access },
 
 	{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
 	  .reset = reset_pmcr, .reg = PMCR_EL0 },
@@ -1674,6 +1680,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
 	{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
+	{ SYS_DESC(SYS_TPIDR2_EL0), undef_access },
 
 	{ SYS_DESC(SYS_SCXTNUM_EL0), undef_access },
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:01 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:01 +0000
Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-26-broonie@kernel.org>

SME defines two new traps which need to be enabled for guests to ensure
that they can't use SME, one for the main SME operations which mirrors the
traps for SVE and another for access to TPIDR2 in SCTLR_EL2.

For VHE manage SMEN along with ZEN in activate_traps() and the FP state
management callbacks.

For nVHE the value to be used for CPTR_EL2 in the guest is stored in
vcpu->arch.cptr_el2, set TSM there during initialisation. It will be
cleared in __deactivate_traps_common() by virtue of not being set in
CPTR_EL2_DEFAULT.

For both VHE and nVHE cases handle SCTLR_EL2.EnTPIDR2 in the shared
__active_traps_common() and __deactivate_traps_common(), there is no
existing dynamic management of SCTLR_EL2.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 30 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c  | 10 +++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 6410d21d8695..184bf6bd79b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -47,10 +47,25 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 		__activate_traps_fpsimd32(vcpu);
 	}
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		val |= CPTR_EL2_TSM;
 
 	write_sysreg(val, cptr_el2);
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
+	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
 
@@ -94,9 +109,24 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
+	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+		u64 val;
+
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	cptr = CPTR_EL2_DEFAULT;
 	if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED))
 		cptr |= CPTR_EL2_TZ;
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		cptr &= ~CPTR_EL2_TSM;
 
 	write_sysreg(cptr, cptr_el2);
 	write_sysreg(__kvm_hyp_host_vector, vbar_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 11d053fdd604..f5630579f577 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,7 +38,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
-	val &= ~CPACR_EL1_ZEN;
+	val &= ~(CPACR_EL1_ZEN | CPACR_EL1_SMEN);
 
 	/*
 	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -59,6 +59,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		__activate_traps_fpsimd32(vcpu);
 	}
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(val, cpacr_el1);
 
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
@@ -80,6 +84,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 	 */
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
 	write_sysreg(vectors, vbar_el1);
 }
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:02 +0000
Subject: [PATCH v8 26/38] KVM: arm64: Handle SME host state when running guests
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-27-broonie@kernel.org>

While we don't currently support SME in guests we do currently support it
for the host system so we need to take care of SME's impact, including
the floating point register state, when running guests. Simiarly to SVE
we need to manage the traps in CPACR_RL1, what is new is the handling of
streaming mode and ZA.

Normally we defer any handling of the floating point register state until
the guest first uses it however if the system is in streaming mode FPSIMD
and SVE operations may generate SME traps which we would need to distinguish
from actual attempts by the guest to use SME. Rather than do this for the
time being if we are in streaming mode when entering the guest we force
the floating point state to be saved immediately and exit streaming mode,
meaning that the guest won't generate SME traps for supported operations.

We could handle ZA in the access trap similarly to the FPSIMD/SVE state
without the disruption caused by streaming mode but for simplicity
handle it the same way as streaming mode for now.

This will be revisited when we support SME for guests (hopefully before SME
hardware becomes available), for now it will only incur additional cost on
systems with SME and even there only if streaming mode or ZA are enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/fpsimd.c           | 38 +++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7dc85d5a6552..404b7358ba96 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -438,6 +438,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
 #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
+#define KVM_ARM64_HOST_SME_ENABLED	(1 << 15) /* SME enabled for EL0 */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 338733ac63f8..cecaddb644ce 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -82,6 +82,26 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
 		vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
+
+	/*
+	 * We don't currently support SME guests but if we leave
+	 * things in streaming mode then when the guest starts running
+	 * FPSIMD or SVE code it may generate SME traps so as a
+	 * special case if we are in streaming mode we force the host
+	 * state to be saved now and exit streaming mode so that we
+	 * don't have to handle any SME traps for valid guest
+	 * operations. Do this for ZA as well for now for simplicity.
+	 */
+	if (system_supports_sme()) {
+		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
+			vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED;
+
+		if (read_sysreg_s(SYS_SVCR_EL0) &
+		    (SYS_SVCR_EL0_SM_MASK | SYS_SVCR_EL0_ZA_MASK)) {
+			vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
+			fpsimd_save_and_flush_cpu_state();
+		}
+	}
 }
 
 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
@@ -129,6 +149,24 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 
 	local_irq_save(flags);
 
+	/*
+	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
+	 * CPACR_EL1_DEFAULT and we need to reenable SME.
+	 */
+	if (has_vhe()) {
+		if (system_supports_sme()) {
+			/* Also restore EL0 state seen on entry */
+			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
+				sysreg_clear_set(CPACR_EL1, 0,
+						 CPACR_EL1_SMEN_EL0EN |
+						 CPACR_EL1_SMEN_EL1EN);
+			else
+				sysreg_clear_set(CPACR_EL1,
+						 CPACR_EL1_SMEN_EL0EN,
+						 CPACR_EL1_SMEN_EL1EN);
+		}
+	}
+
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
 		if (vcpu_has_sve(vcpu)) {
 			__vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:03 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:03 +0000
Subject: [PATCH v8 27/38] arm64/sme: Provide Kconfig for SME
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-28-broonie@kernel.org>

Now that basline support for the Scalable Matrix Extension (SME) is present
introduce the Kconfig option allowing it to be built. While the feature
registers don't impose a strong requirement for a system with SME to
support SVE at runtime the support for streaming mode SVE is mostly
shared with normal SVE so depend on SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..f60f3b04ddf5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1839,6 +1839,17 @@ config ARM64_SVE
 	  booting the kernel.  If unsure and you are not observing these
 	  symptoms, you should assume that it is safe to say Y.
 
+config ARM64_SME
+	bool "ARM Scalable Matrix Extension support"
+	default y
+	depends on ARM64_SVE
+	help
+	  The Scalable Matrix Extension (SME) is an extension to the AArch64
+	  execution state which utilises a substantial subset of the SVE
+	  instruction set, together with the addition of new architectural
+	  register state capable of holding two dimensional matrix tiles to
+	  enable various matrix operations.
+
 config ARM64_MODULE_PLTS
 	bool "Use PLTs to allow module memory to spill over into vmalloc area"
 	depends on MODULES
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:04 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:04 +0000
Subject: [PATCH v8 28/38] kselftest/arm64: sme: Add streaming SME support to
 vlset
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-29-broonie@kernel.org>

The Scalable Matrix Extenions (SME) introduces additional register state
with configurable vector lengths, similar to SVE but configured separately.
Extend vlset to support configuring this state with a --sme or -s command
line option.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/vlset.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/fp/vlset.c b/tools/testing/selftests/arm64/fp/vlset.c
index 308d27a68226..76912a581a95 100644
--- a/tools/testing/selftests/arm64/fp/vlset.c
+++ b/tools/testing/selftests/arm64/fp/vlset.c
@@ -22,12 +22,15 @@ static int inherit = 0;
 static int no_inherit = 0;
 static int force = 0;
 static unsigned long vl;
+static int set_ctl = PR_SVE_SET_VL;
+static int get_ctl = PR_SVE_GET_VL;
 
 static const struct option options[] = {
 	{ "force",	no_argument, NULL, 'f' },
 	{ "inherit",	no_argument, NULL, 'i' },
 	{ "max",	no_argument, NULL, 'M' },
 	{ "no-inherit",	no_argument, &no_inherit, 1 },
+	{ "sme",	no_argument, NULL, 's' },
 	{ "help",	no_argument, NULL, '?' },
 	{}
 };
@@ -50,6 +53,9 @@ static int parse_options(int argc, char **argv)
 		case 'M':	vl = SVE_VL_MAX; break;
 		case 'f':	force = 1; break;
 		case 'i':	inherit = 1; break;
+		case 's':	set_ctl = PR_SME_SET_VL;
+				get_ctl = PR_SME_GET_VL;
+				break;
 		case 0:		break;
 		default:	goto error;
 		}
@@ -125,14 +131,14 @@ int main(int argc, char **argv)
 	if (inherit)
 		flags |= PR_SVE_VL_INHERIT;
 
-	t = prctl(PR_SVE_SET_VL, vl | flags);
+	t = prctl(set_ctl, vl | flags);
 	if (t < 0) {
 		fprintf(stderr, "%s: PR_SVE_SET_VL: %s\n",
 			program_name, strerror(errno));
 		goto error;
 	}
 
-	t = prctl(PR_SVE_GET_VL);
+	t = prctl(get_ctl);
 	if (t == -1) {
 		fprintf(stderr, "%s: PR_SVE_GET_VL: %s\n",
 			program_name, strerror(errno));
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:05 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:05 +0000
Subject: [PATCH v8 29/38] kselftest/arm64: Add tests for TPIDR2
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-30-broonie@kernel.org>

The Scalable Matrix Extension adds a new system register TPIDR2 intended to
be used by libc for its own thread specific use, add some kselftests which
exercise the ABI for it.

Since this test should with some adjustment work for TPIDR and any other
similar registers added in future add tests for it in a separate
directory rather than placing it with the other floating point tests,
nothing existing looked suitable so I created a new test directory
called "abi".

Since this feature is intended to be used by libc the test is built as
freestanding code using nolibc so we don't end up with the test program
and libc both trying to manage the register simultaneously and
distrupting each other. As a result of being written using nolibc rather
than using hwcaps to identify if SME is available in the system we check
for the default SME vector length configuration in proc, adding hwcap
support to nolibc seems like disproportionate effort and didn't feel
entirely idiomatic for what nolibc is trying to do.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/.gitignore |   1 +
 tools/testing/selftests/arm64/abi/Makefile   |   9 +-
 tools/testing/selftests/arm64/abi/tpidr2.c   | 298 +++++++++++++++++++
 3 files changed, 307 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c

diff --git a/tools/testing/selftests/arm64/abi/.gitignore b/tools/testing/selftests/arm64/abi/.gitignore
index b79cf5814c23..b9e54417250d 100644
--- a/tools/testing/selftests/arm64/abi/.gitignore
+++ b/tools/testing/selftests/arm64/abi/.gitignore
@@ -1 +1,2 @@
 syscall-abi
+tpidr2
diff --git a/tools/testing/selftests/arm64/abi/Makefile b/tools/testing/selftests/arm64/abi/Makefile
index 96eba974ac8d..c8d7f2495eb2 100644
--- a/tools/testing/selftests/arm64/abi/Makefile
+++ b/tools/testing/selftests/arm64/abi/Makefile
@@ -1,8 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (C) 2021 ARM Limited
 
-TEST_GEN_PROGS := syscall-abi
+TEST_GEN_PROGS := syscall-abi tpidr2
 
 include ../../lib.mk
 
 $(OUTPUT)/syscall-abi: syscall-abi.c syscall-abi-asm.S
+
+# Build with nolibc since TPIDR2 is intended to be actively managed by
+# libc and we're trying to test the functionality that it depends on here.
+$(OUTPUT)/tpidr2: tpidr2.c
+	$(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+		-static -include ../../../../include/nolibc/nolibc.h \
+		-ffreestanding -Wall $^ -o $@ -lgcc
diff --git a/tools/testing/selftests/arm64/abi/tpidr2.c b/tools/testing/selftests/arm64/abi/tpidr2.c
new file mode 100644
index 000000000000..351a098b503a
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/tpidr2.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#define SYS_TPIDR2 "S3_3_C13_C0_5"
+
+#define EXPECTED_TESTS 5
+
+static void putstr(const char *str)
+{
+	write(1, str, strlen(str));
+}
+
+static void putnum(unsigned int num)
+{
+	char c;
+
+	if (num / 10)
+		putnum(num / 10);
+
+	c = '0' + (num % 10);
+	write(1, &c, 1);
+}
+
+static int tests_run;
+static int tests_passed;
+static int tests_failed;
+static int tests_skipped;
+
+static void set_tpidr2(uint64_t val)
+{
+	asm volatile (
+		"msr	" SYS_TPIDR2 ", %0\n"
+		:
+		: "r"(val)
+		: "cc");
+}
+
+static uint64_t get_tpidr2(void)
+{
+	uint64_t val;
+
+	asm volatile (
+		"mrs	%0, " SYS_TPIDR2 "\n"
+		: "=r"(val)
+		:
+		: "cc");
+
+	return val;
+}
+
+static void print_summary(void)
+{
+	if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS)
+		putstr("# UNEXPECTED TEST COUNT: ");
+
+	putstr("# Totals: pass:");
+	putnum(tests_passed);
+	putstr(" fail:");
+	putnum(tests_failed);
+	putstr(" xfail:0 xpass:0 skip:");
+	putnum(tests_skipped);
+	putstr(" error:0\n");
+}
+
+/* Processes should start with TPIDR2 == 0 */
+static int default_value(void)
+{
+	return get_tpidr2() == 0;
+}
+
+/* If we set TPIDR2 we should read that value */
+static int write_read(void)
+{
+	set_tpidr2(getpid());
+
+	return getpid() == get_tpidr2();
+}
+
+/* If we set a value we should read the same value after scheduling out */
+static int write_sleep_read(void)
+{
+	set_tpidr2(getpid());
+
+	msleep(100);
+
+	return getpid() == get_tpidr2();
+}
+
+/*
+ * If we fork the value in the parent should be unchanged and the
+ * child should start with the same value and be able to set its own
+ * value.
+ */
+static int write_fork_read(void)
+{
+	pid_t newpid, waiting, oldpid;
+	int status;
+
+	set_tpidr2(getpid());
+
+	oldpid = getpid();
+	newpid = fork();
+	if (newpid == 0) {
+		/* In child */
+		if (get_tpidr2() != oldpid) {
+			putstr("# TPIDR2 changed in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		set_tpidr2(getpid());
+		if (get_tpidr2() == getpid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+	if (newpid < 0) {
+		putstr("# fork() failed: -");
+		putnum(-newpid);
+		putstr("\n");
+		return 0;
+	}
+
+	for (;;) {
+		waiting = waitpid(newpid, &status, 0);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# waitpid() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != newpid) {
+			putstr("# waitpid() returned wrong PID\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (getpid() != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+/*
+ * sys_clone() has a lot of per architecture variation so just define
+ * it here rather than adding it to nolibc, plus the raw API is a
+ * little more convenient for this test.
+ */
+static int sys_clone(unsigned long clone_flags, unsigned long newsp,
+		     int *parent_tidptr, unsigned long tls,
+		     int *child_tidptr)
+{
+	return my_syscall5(__NR_clone, clone_flags, newsp, parent_tidptr, tls,
+			   child_tidptr);
+}
+
+/*
+ * If we clone with CLONE_SETTLS then the value in the parent should
+ * be unchanged and the child should start with zero and be able to
+ * set its own value.
+ */
+static int write_clone_read(void)
+{
+	int parent_tid, child_tid;
+	pid_t parent, waiting;
+	int ret, status;
+
+	parent = getpid();
+	set_tpidr2(parent);
+
+	ret = sys_clone(CLONE_SETTLS, 0, &parent_tid, 0, &child_tid);
+	if (ret == -1) {
+		putstr("# clone() failed\n");
+		putnum(errno);
+		putstr("\n");
+		return 0;
+	}
+
+	if (ret == 0) {
+		/* In child */
+		if (get_tpidr2() != 0) {
+			putstr("# TPIDR2 non-zero in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		if (gettid() == 0)
+			putstr("# Child TID==0\n");
+		set_tpidr2(gettid());
+		if (get_tpidr2() == gettid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+
+	for (;;) {
+		waiting = wait4(ret, &status, __WCLONE, NULL);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# wait4() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != ret) {
+			putstr("# wait4() returned wrong PID ");
+			putnum(waiting);
+			putstr("\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (parent != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+#define run_test(name)			     \
+	if (name()) {			     \
+		tests_passed++;		     \
+	} else {			     \
+		tests_failed++;		     \
+		putstr("not ");		     \
+	}				     \
+	putstr("ok ");			     \
+	putnum(++tests_run);		     \
+	putstr(" " #name "\n");
+
+int main(int argc, char **argv)
+{
+	int ret, i;
+
+	putstr("TAP version 13\n");
+	putstr("1..");
+	putnum(EXPECTED_TESTS);
+	putstr("\n");
+
+	putstr("# PID: ");
+	putnum(getpid());
+	putstr("\n");
+
+	/*
+	 * This test is run with nolibc which doesn't support hwcap and
+	 * it's probably disproportionate to implement so instead check
+	 * for the default vector length configuration in /proc.
+	 */
+	ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
+	if (ret >= 0) {
+		run_test(default_value);
+		run_test(write_read);
+		run_test(write_sleep_read);
+		run_test(write_fork_read);
+		run_test(write_clone_read);
+
+	} else {
+		putstr("# SME support not present\n");
+
+		for (i = 0; i < EXPECTED_TESTS; i++) {
+			putstr("ok ");
+			putnum(i);
+			putstr(" skipped, TPIDR2 not supported\n");
+		}
+
+		tests_skipped += EXPECTED_TESTS;
+	}
+
+	print_summary();
+
+	return 0;
+}
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:06 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:06 +0000
Subject: [PATCH v8 30/38] kselftest/arm64: Extend vector configuration API
 tests to cover SME
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-31-broonie@kernel.org>

Provide RDVL helpers for SME and extend the main vector configuration tests
to cover SME.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore   |  1 +
 tools/testing/selftests/arm64/fp/Makefile     |  3 ++-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   | 14 ++++++++++++++
 tools/testing/selftests/arm64/fp/rdvl.S       |  8 ++++++++
 tools/testing/selftests/arm64/fp/rdvl.h       |  1 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 10 ++++++++++
 6 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index c50d86331ed2..6e9a610c5e5d 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -1,5 +1,6 @@
 fp-pidbench
 fpsimd-test
+rdvl-sme
 rdvl-sve
 sve-probe-vls
 sve-ptrace
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 95f0b877a060..a224fff8082b 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -3,7 +3,7 @@
 CFLAGS += -I../../../../../usr/include/
 TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
-	rdvl-sve \
+	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	vlset
 
@@ -13,6 +13,7 @@ fp-pidbench: fp-pidbench.S asm-utils.o
 	$(CC) -nostdlib $^ -o $@
 fpsimd-test: fpsimd-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+rdvl-sme: rdvl-sme.o rdvl.o
 rdvl-sve: rdvl-sve.o rdvl.o
 sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
diff --git a/tools/testing/selftests/arm64/fp/rdvl-sme.c b/tools/testing/selftests/arm64/fp/rdvl-sme.c
new file mode 100644
index 000000000000..49b0b2e08bac
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl-sme.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <stdio.h>
+
+#include "rdvl.h"
+
+int main(void)
+{
+	int vl = rdvl_sme();
+
+	printf("%d\n", vl);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/arm64/fp/rdvl.S b/tools/testing/selftests/arm64/fp/rdvl.S
index c916c1c9defd..1a2ebf07a20c 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.S
+++ b/tools/testing/selftests/arm64/fp/rdvl.S
@@ -8,3 +8,11 @@ rdvl_sve:
 	hint	34			// BTI C
 	rdvl	x0, #1
 	ret
+
+.globl rdvl_sme
+rdvl_sme:
+	hint	34			// BTI C
+
+	.inst	0x4bf5820		// RDSVL x0, #1
+
+	ret
diff --git a/tools/testing/selftests/arm64/fp/rdvl.h b/tools/testing/selftests/arm64/fp/rdvl.h
index 7c9d953fc9e7..5d323679fbc9 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.h
+++ b/tools/testing/selftests/arm64/fp/rdvl.h
@@ -3,6 +3,7 @@
 #ifndef RDVL_H
 #define RDVL_H
 
+int rdvl_sme(void);
 int rdvl_sve(void);
 
 #endif
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index c90658811a83..9bcfcdc34ee9 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -51,6 +51,16 @@ static struct vec_data vec_data[] = {
 		.prctl_set = PR_SVE_SET_VL,
 		.default_vl_file = "/proc/sys/abi/sve_default_vector_length",
 	},
+	{
+		.name = "SME",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.rdvl = rdvl_sme,
+		.rdvl_binary = "./rdvl-sme",
+		.prctl_get = PR_SME_GET_VL,
+		.prctl_set = PR_SME_SET_VL,
+		.default_vl_file = "/proc/sys/abi/sme_default_vector_length",
+	},
 };
 
 static int stdio_read_integer(FILE *f, const char *what, int *val)
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:07 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:07 +0000
Subject: [PATCH v8 31/38] kselftest/arm64: sme: Provide streaming mode SVE
 stress test
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-32-broonie@kernel.org>

One of the features of SME is the addition of streaming mode, in which we
have access to a set of streaming mode SVE registers at the SME vector
length. Since these are accessed using the SVE instructions let's reuse
the existing SVE stress test for testing with a compile time option for
controlling the few small differences needed:

 - Enter streaming mode immediately on starting the program.
 - In streaming mode FFR is removed so skip reading and writing FFR.

In order to avoid requiring a cutting edge toolchain with SME support
use the op/CR form for specifying SVCR.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |  1 +
 tools/testing/selftests/arm64/fp/Makefile    |  3 +
 tools/testing/selftests/arm64/fp/ssve-stress | 59 ++++++++++++++++++++
 tools/testing/selftests/arm64/fp/sve-test.S  | 30 ++++++++++
 4 files changed, 93 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 6e9a610c5e5d..5729a5b1adfc 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -5,5 +5,6 @@ rdvl-sve
 sve-probe-vls
 sve-ptrace
 sve-test
+ssve-test
 vec-syscfg
 vlset
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index a224fff8082b..e6643c9b0474 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -5,6 +5,7 @@ TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
+	ssve-test ssve-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -19,6 +20,8 @@ sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
 sve-test: sve-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+ssve-test: sve-test.S asm-utils.o
+	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 
diff --git a/tools/testing/selftests/arm64/fp/ssve-stress b/tools/testing/selftests/arm64/fp/ssve-stress
new file mode 100644
index 000000000000..e2bd2cc184ad
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/ssve-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./ssve-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S
index f5b1b48ffff2..31764e8370db 100644
--- a/tools/testing/selftests/arm64/fp/sve-test.S
+++ b/tools/testing/selftests/arm64/fp/sve-test.S
@@ -156,6 +156,7 @@ endfunction
 // We fill the upper lanes of FFR with zeros.
 // Beware: corrupts P0.
 function setup_ffr
+#ifndef SSVE
 	mov	x4, x30
 
 	and	w0, w0, #0x3
@@ -178,6 +179,9 @@ function setup_ffr
 	wrffr	p0.b
 
 	ret	x4
+#else
+	ret
+#endif
 endfunction
 
 // Trivial memory compare: compare x2 bytes starting at address x0 with
@@ -260,6 +264,7 @@ endfunction
 // Beware -- corrupts P0.
 // Clobbers x0-x5.
 function check_ffr
+#ifndef SSVE
 	mov	x3, x30
 
 	ldr	x4, =scratch
@@ -280,6 +285,9 @@ function check_ffr
 	mov	x2, x5
 	mov	x30, x3
 	b	memcmp
+#else
+	ret
+#endif
 endfunction
 
 // Any SVE register modified here can cause corruption in the main
@@ -295,13 +303,26 @@ function irritator_handler
 	movi	v0.8b, #1
 	movi	v9.16b, #2
 	movi	v31.8b, #3
+#ifndef SSVE
 	// And P0
 	rdffr	p0.b
 	// And FFR
 	wrffr	p15.b
+#endif
+
+	ret
+endfunction
+
+#ifdef SSVE
+function enable_sm
+	// Set SVCR.SM to 1, equivalent to SMSTART SM but doesn't need a
+	// SME capable toolchain.
+	mov	x0, #1
+	msr	S3_3_C4_C2_2, x0
 
 	ret
 endfunction
+#endif
 
 function terminate_handler
 	mov	w21, w0
@@ -359,6 +380,11 @@ endfunction
 .globl _start
 function _start
 _start:
+#ifdef SSVE
+	puts	"Streaming mode "
+	bl	enable_sm
+#endif
+
 	// Sanity-check and report the vector length
 
 	rdvl	x19, #8
@@ -407,6 +433,10 @@ _start:
 	orr	w2, w2, #SA_NODEFER
 	bl	setsignal
 
+#ifdef SSVE
+	bl	enable_sm	// syscalls will have exited streaming mode
+#endif
+
 	mov	x22, #0		// generation number, increments per iteration
 .Ltest_loop:
 	rdvl	x0, #8
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:08 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:08 +0000
Subject: [PATCH v8 32/38] kselftest/arm64: signal: Allow tests to be
 incompatible with features
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-33-broonie@kernel.org>

Some features may invalidate some tests, for example by supporting an
operation which would trap otherwise. Allow tests to list features that
they are incompatible with so we can cover the case where a signal will
be generated without disruption on systems where that won't happen.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/signal/test_signals.h     |  1 +
 .../arm64/signal/test_signals_utils.c         | 34 ++++++++++++++-----
 .../arm64/signal/test_signals_utils.h         |  2 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index ebe8694dbef0..f909b70d9e98 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -53,6 +53,7 @@ struct tdescr {
 	char			*name;
 	char			*descr;
 	unsigned long		feats_required;
+	unsigned long		feats_incompatible;
 	/* bitmask of effectively supported feats: populated at run-time */
 	unsigned long		feats_supported;
 	bool			initialized;
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 2f8c23af3b5e..5743897984b0 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -36,6 +36,8 @@ static inline char *feats_to_string(unsigned long feats)
 {
 	size_t flen = MAX_FEATS_SZ - 1;
 
+	feats_string[0] = '\0';
+
 	for (int i = 0; i < FMAX_END; i++) {
 		if (feats & (1UL << i)) {
 			size_t tlen = strlen(feats_names[i]);
@@ -256,7 +258,7 @@ int test_init(struct tdescr *td)
 		td->minsigstksz = MINSIGSTKSZ;
 	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
 
-	if (td->feats_required) {
+	if (td->feats_required || td->feats_incompatible) {
 		td->feats_supported = 0;
 		/*
 		 * Checking for CPU required features using both the
@@ -267,15 +269,29 @@ int test_init(struct tdescr *td)
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
 		if (feats_ok(td)) {
-			fprintf(stderr,
-				"Required Features: [%s] supported\n",
-				feats_to_string(td->feats_required &
-						td->feats_supported));
+			if (td->feats_required & td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] supported\n",
+					feats_to_string(td->feats_required &
+							td->feats_supported));
+			if (!(td->feats_incompatible & td->feats_supported))
+				fprintf(stderr,
+					"Incompatible Features: [%s] absent\n",
+					feats_to_string(td->feats_incompatible));
 		} else {
-			fprintf(stderr,
-				"Required Features: [%s] NOT supported\n",
-				feats_to_string(td->feats_required &
-						~td->feats_supported));
+			if ((td->feats_required & td->feats_supported) !=
+			    td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] NOT supported\n",
+					feats_to_string(td->feats_required &
+							~td->feats_supported));
+			if (td->feats_incompatible & td->feats_supported)
+				fprintf(stderr,
+					"Incompatible Features: [%s] supported\n",
+					feats_to_string(td->feats_incompatible &
+							~td->feats_supported));
+
+
 			td->result = KSFT_SKIP;
 			return 0;
 		}
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 6772b5c8d274..f3aa99ba67bb 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -18,6 +18,8 @@ void test_result(struct tdescr *td);
 
 static inline bool feats_ok(struct tdescr *td)
 {
+	if (td->feats_incompatible & td->feats_supported)
+		return false;
 	return (td->feats_required & td->feats_supported) == td->feats_required;
 }
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:09 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:09 +0000
Subject: [PATCH v8 33/38] kselftest/arm64: signal: Handle ZA signal context in
 core code
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-34-broonie@kernel.org>

As part of the generic code for signal handling test cases we parse all
signal frames to make sure they have at least the basic form we expect
and that there are no unexpected frames present in the signal context.
Add coverage of the ZA signal frame to this code.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../arm64/signal/testcases/testcases.c        | 36 +++++++++++++++++++
 .../arm64/signal/testcases/testcases.h        |  3 +-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
index 8c2a57fc2f9c..84c36bee4d82 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
@@ -75,6 +75,31 @@ bool validate_sve_context(struct sve_context *sve, char **err)
 	return true;
 }
 
+bool validate_za_context(struct za_context *za, char **err)
+{
+	/* Size will be rounded up to a multiple of 16 bytes */
+	size_t regs_size
+		= ((ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za->vl)) + 15) / 16) * 16;
+
+	if (!za || !err)
+		return false;
+
+	/* Either a bare za_context or a za_context followed by regs data */
+	if ((za->head.size != sizeof(struct za_context)) &&
+	    (za->head.size != regs_size)) {
+		*err = "bad size for ZA context";
+		return false;
+	}
+
+	if (!sve_vl_valid(za->vl)) {
+		*err = "SME VL in ZA context invalid";
+
+		return false;
+	}
+
+	return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
 	bool terminated = false;
@@ -82,6 +107,7 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 	int flags = 0;
 	struct extra_context *extra = NULL;
 	struct sve_context *sve = NULL;
+	struct za_context *za = NULL;
 	struct _aarch64_ctx *head =
 		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
 
@@ -120,6 +146,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 			sve = (struct sve_context *)head;
 			flags |= SVE_CTX;
 			break;
+		case ZA_MAGIC:
+			if (flags & ZA_CTX)
+				*err = "Multiple ZA_MAGIC";
+			/* Size is validated in validate_za_context() */
+			za = (struct za_context *)head;
+			flags |= ZA_CTX;
+			break;
 		case EXTRA_MAGIC:
 			if (flags & EXTRA_CTX)
 				*err = "Multiple EXTRA_MAGIC";
@@ -165,6 +198,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 		if (flags & SVE_CTX)
 			if (!validate_sve_context(sve, err))
 				return false;
+		if (flags & ZA_CTX)
+			if (!validate_za_context(za, err))
+				return false;
 
 		head = GET_RESV_NEXT_HEAD(head);
 	}
diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
index ad884c135314..49f1d5de7b5b 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.h
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
@@ -16,7 +16,8 @@
 
 #define FPSIMD_CTX	(1 << 0)
 #define SVE_CTX		(1 << 1)
-#define EXTRA_CTX	(1 << 2)
+#define ZA_CTX		(1 << 2)
+#define EXTRA_CTX	(1 << 3)
 
 #define KSFT_BAD_MAGIC	0xdeadbeef
 
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:10 +0000
Subject: [PATCH v8 34/38] kselftest/arm64: Add stress test for SME ZA context
 switching
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-35-broonie@kernel.org>

Add a stress test for context switching of the ZA register state based on
the similar tests Dave Martin wrote for FPSIMD and SVE registers. The test
loops indefinitely writing a data pattern to ZA then reading it back and
verifying that it's what was expected.

Unlike the other tests we manually assemble the SME instructions since at
present no released toolchain has SME support integrated.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore |   1 +
 tools/testing/selftests/arm64/fp/Makefile   |   3 +
 tools/testing/selftests/arm64/fp/za-stress  |  59 +++
 tools/testing/selftests/arm64/fp/za-test.S  | 426 ++++++++++++++++++++
 4 files changed, 489 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 5729a5b1adfc..ead3197e720b 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,3 +8,4 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index e6643c9b0474..38d2d0d5a0eb 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -6,6 +6,7 @@ TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	ssve-test ssve-stress \
+	za-test za-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -24,5 +25,7 @@ ssve-test: sve-test.S asm-utils.o
 	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
+za-test: za-test.o asm-utils.o
+	$(CC) -nostdlib $^ -o $@
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-stress b/tools/testing/selftests/arm64/fp/za-stress
new file mode 100644
index 000000000000..5ac386b55b95
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./za-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/za-test.S b/tools/testing/selftests/arm64/fp/za-test.S
new file mode 100644
index 000000000000..99e1bb3b6b18
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-test.S
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2021 ARM Limited.
+// Original author: Mark Brown <broonie at kernel.org>
+//
+// Scalable Matrix Extension ZA context switch test
+// Repeatedly writes unique test patterns into each ZA tile
+// and reads them back to verify integrity.
+//
+// for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
+// (leave it running for as long as you want...)
+// kill $pids
+
+#include <asm/unistd.h>
+#include "assembler.h"
+#include "asm-offsets.h"
+
+.arch_extension sve
+
+#define MAXVL     2048
+#define MAXVL_B   (MAXVL / 8)
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * RDSVL X\nx, #\imm
+ */
+.macro rdsvl nx, imm
+	.inst	0x4bf5800			\
+		| (\imm << 5)			\
+		| (\nx)
+.endm
+
+.macro smstop
+	msr	S0_3_C4_C6_3, xzr
+.endm
+
+.macro smstart_za
+	msr	S0_3_C4_C5_3, xzr
+.endm
+
+// Declare some storage space to shadow ZA register contents and a
+// scratch buffer for a vector.
+.pushsection .text
+.data
+.align 4
+zaref:
+	.space	MAXVL_B * MAXVL_B
+scratch:
+	.space	MAXVL_B
+.popsection
+
+// Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
+// Clobbers x0-x3
+function memcpy
+	cmp	x2, #0
+	b.eq	1f
+0:	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	0b
+1:	ret
+endfunction
+
+// Generate a test pattern for storage in ZA
+// x0: pid
+// x1: row in ZA
+// x2: generation
+
+// These values are used to constuct a 32-bit pattern that is repeated in the
+// scratch buffer as many times as will fit:
+// bits 31:28	generation number (increments once per test_loop)
+// bits 27:16	pid
+// bits 15: 8	row number
+// bits  7: 0	32-bit lane index
+
+function pattern
+	mov	w3, wzr
+	bfi	w3, w0, #16, #12	// PID
+	bfi	w3, w1, #8, #8		// Row
+	bfi	w3, w2, #28, #4		// Generation
+
+	ldr	x0, =scratch
+	mov	w1, #MAXVL_B / 4
+
+0:	str	w3, [x0], #4
+	add	w3, w3, #1		// Lane
+	subs	w1, w1, #1
+	b.ne	0b
+
+	ret
+endfunction
+
+// Get the address of shadow data for ZA horizontal vector xn
+.macro _adrza xd, xn, nrtmp
+	ldr	\xd, =zaref
+	rdsvl	\nrtmp, 1
+	madd	\xd, x\nrtmp, \xn, \xd
+.endm
+
+// Set up test pattern in a ZA horizontal vector
+// x0: pid
+// x1: row number
+// x2: generation
+function setup_za
+	mov	x4, x30
+	mov	x12, x1			// Use x12 for vector select
+
+	bl	pattern			// Get pattern in scratch buffer
+	_adrza	x0, x12, 2		// Shadow buffer pointer to x0 and x5
+	mov	x5, x0
+	ldr	x1, =scratch
+	bl	memcpy			// length set up in x2 by _adrza
+
+	_ldr_za 12, 5			// load vector w12 from pointer x5
+
+	ret	x4
+endfunction
+
+// Trivial memory compare: compare x2 bytes starting at address x0 with
+// bytes starting at address x1.
+// Returns only if all bytes match; otherwise, the program is aborted.
+// Clobbers x0-x5.
+function memcmp
+	cbz	x2, 2f
+
+	stp	x0, x1, [sp, #-0x20]!
+	str	x2, [sp, #0x10]
+
+	mov	x5, #0
+0:	ldrb	w3, [x0, x5]
+	ldrb	w4, [x1, x5]
+	add	x5, x5, #1
+	cmp	w3, w4
+	b.ne	1f
+	subs	x2, x2, #1
+	b.ne	0b
+
+1:	ldr	x2, [sp, #0x10]
+	ldp	x0, x1, [sp], #0x20
+	b.ne	barf
+
+2:	ret
+endfunction
+
+// Verify that a ZA vector matches its shadow in memory, else abort
+// x0: row number
+// Clobbers x0-x7 and x12.
+function check_za
+	mov	x3, x30
+
+	mov	x12, x0
+	_adrza	x5, x0, 6		// pointer to expected value in x5
+	mov	x4, x0
+	ldr	x7, =scratch		// x7 is scratch
+
+	mov	x0, x7			// Poison scratch
+	mov	x1, x6
+	bl	memfill_ae
+
+	_str_za 12, 7			// save vector w12 to pointer x7
+
+	mov	x0, x5
+	mov	x1, x7
+	mov	x2, x6
+	mov	x30, x3
+	b	memcmp
+endfunction
+
+// Any SME register modified here can cause corruption in the main
+// thread -- but *only* the locations modified here.
+function irritator_handler
+	// Increment the irritation signal count (x23):
+	ldr	x0, [x2, #ucontext_regs + 8 * 23]
+	add	x0, x0, #1
+	str	x0, [x2, #ucontext_regs + 8 * 23]
+
+	// Corrupt some random ZA data
+#if 0
+	adr	x0, .text + (irritator_handler - .text) / 16 * 16
+	movi	v0.8b, #1
+	movi	v9.16b, #2
+	movi	v31.8b, #3
+#endif
+
+	ret
+endfunction
+
+function terminate_handler
+	mov	w21, w0
+	mov	x20, x2
+
+	puts	"Terminated by signal "
+	mov	w0, w21
+	bl	putdec
+	puts	", no error, iterations="
+	ldr	x0, [x20, #ucontext_regs + 8 * 22]
+	bl	putdec
+	puts	", signals="
+	ldr	x0, [x20, #ucontext_regs + 8 * 23]
+	bl	putdecn
+
+	mov	x0, #0
+	mov	x8, #__NR_exit
+	svc	#0
+endfunction
+
+// w0: signal number
+// x1: sa_action
+// w2: sa_flags
+// Clobbers x0-x6,x8
+function setsignal
+	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
+
+	mov	w4, w0
+	mov	x5, x1
+	mov	w6, w2
+
+	add	x0, sp, #16
+	mov	x1, #sa_sz
+	bl	memclr
+
+	mov	w0, w4
+	add	x1, sp, #16
+	str	w6, [x1, #sa_flags]
+	str	x5, [x1, #sa_handler]
+	mov	x2, #0
+	mov	x3, #sa_mask_sz
+	mov	x8, #__NR_rt_sigaction
+	svc	#0
+
+	cbz	w0, 1f
+
+	puts	"sigaction failure\n"
+	b	.Labort
+
+1:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
+	ret
+endfunction
+
+// Main program entry point
+.globl _start
+function _start
+_start:
+	puts	"Streaming mode "
+	smstart_za
+
+	// Sanity-check and report the vector length
+
+	rdsvl	19, 8
+	cmp	x19, #128
+	b.lo	1f
+	cmp	x19, #2048
+	b.hi	1f
+	tst	x19, #(8 - 1)
+	b.eq	2f
+
+1:	puts	"bad vector length: "
+	mov	x0, x19
+	bl	putdecn
+	b	.Labort
+
+2:	puts	"vector length:\t"
+	mov	x0, x19
+	bl	putdec
+	puts	" bits\n"
+
+	// Obtain our PID, to ensure test pattern uniqueness between processes
+	mov	x8, #__NR_getpid
+	svc	#0
+	mov	x20, x0
+
+	puts	"PID:\t"
+	mov	x0, x20
+	bl	putdecn
+
+	mov	x23, #0		// Irritation signal count
+
+	mov	w0, #SIGINT
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGTERM
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGUSR1
+	adr	x1, irritator_handler
+	mov	w2, #SA_SIGINFO
+	orr	w2, w2, #SA_NODEFER
+	bl	setsignal
+
+	mov	x22, #0		// generation number, increments per iteration
+.Ltest_loop:
+	rdsvl	0, 8
+	cmp	x0, x19
+	b.ne	vl_barf
+
+	rdsvl	21, 1		// Set up ZA & shadow with test pattern
+0:	mov	x0, x20
+	sub	x1, x21, #1
+	mov	x2, x22
+	bl	setup_za
+	subs	x21, x21, #1
+	b.ne	0b
+
+	and	x8, x22, #127		// Every 128 interations...
+	cbz	x8, 0f
+	mov	x8, #__NR_getpid	// (otherwise minimal syscall)
+	b	1f
+0:
+	mov	x8, #__NR_sched_yield	// ...encourage preemption
+1:
+	svc	#0
+
+	mrs	x0, S3_3_C4_C2_2	// SVCR should have ZA=1,SM=0
+	and	x1, x0, #3
+	cmp	x1, #2
+	b.ne	svcr_barf
+
+	rdsvl	21, 1			// Verify that the data made it through
+	rdsvl	24, 1			// Verify that the data made it through
+0:	sub	x0, x24, x21
+	bl	check_za
+	subs	x21, x21, #1
+	bne	0b
+
+	add	x22, x22, #1	// Everything still working
+	b	.Ltest_loop
+
+.Labort:
+	mov	x0, #0
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+endfunction
+
+function barf
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// end hack
+	smstop
+	mov	x10, x0	// expected data
+	mov	x11, x1	// actual data
+	mov	x12, x2	// data size
+
+	puts	"Mismatch: PID="
+	mov	x0, x20
+	bl	putdec
+	puts	", iteration="
+	mov	x0, x22
+	bl	putdec
+	puts	", row="
+	mov	x0, x21
+	bl	putdecn
+	puts	"\tExpected ["
+	mov	x0, x10
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n\tGot      ["
+	mov	x0, x11
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n"
+
+	mov	x8, #__NR_getpid
+	svc	#0
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// ^ end of hack
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+//	mov	x8, #__NR_exit
+//	mov	x1, #1
+//	svc	#0
+endfunction
+
+function vl_barf
+	mov	x10, x0
+
+	puts	"Bad active VL: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
+
+function svcr_barf
+	mov	x10, x0
+
+	puts	"Bad SVCR: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:11 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:11 +0000
Subject: [PATCH v8 35/38] kselftest/arm64: signal: Add SME signal handling
 tests
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-36-broonie@kernel.org>

Add test cases for the SME signal handing ABI patterned off the SVE tests.
Due to the small size of the tests and the differences in ABI (especially
around needing to account for both streaming SVE and ZA) there is some code
duplication here.

We currently cover:
 - Reporting of the vector length.
 - Lack of support for changing vector length.
 - Presence and size of register state for streaming SVE and ZA.

As with the SVE tests we do not yet have any validation of register
contents.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   4 +
 .../arm64/signal/test_signals_utils.c         |   6 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++++++++++++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++++++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++++++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 +++++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 +++++++++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++++++++++++++++
 9 files changed, 420 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index c1742755abb9..4de8eb26d4de 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mangle_*
 fake_sigreturn_*
+sme_*
+ssve_*
 sve_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index f909b70d9e98..c70fdec7d7c4 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -34,11 +34,15 @@
 enum {
 	FSSBS_BIT,
 	FSVE_BIT,
+	FSME_BIT,
+	FSME_FA64_BIT,
 	FMAX_END
 };
 
 #define FEAT_SSBS		(1UL << FSSBS_BIT)
 #define FEAT_SVE		(1UL << FSVE_BIT)
+#define FEAT_SME		(1UL << FSME_BIT)
+#define FEAT_SME_FA64		(1UL << FSME_FA64_BIT)
 
 /*
  * A descriptor used to describe and configure a test case.
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 5743897984b0..b588d10afd5b 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -27,6 +27,8 @@ static int sig_copyctx = SIGTRAP;
 static char const *const feats_names[FMAX_END] = {
 	" SSBS ",
 	" SVE ",
+	" SME ",
+	" FA64 ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -268,6 +270,10 @@ int test_init(struct tdescr *td)
 			td->feats_supported |= FEAT_SSBS;
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+			td->feats_supported |= FEAT_SME;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+			td->feats_supported |= FEAT_SME_FA64;
 		if (feats_ok(td)) {
 			if (td->feats_required & td->feats_supported)
 				fprintf(stderr,
diff --git a/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
new file mode 100644
index 000000000000..7ed762b7202f
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Attempt to change the streaming SVE vector length in a signal
+ * handler, this is not supported and is expected to segfault.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least two VLs */
+	if (nvls < 2) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static int fake_sigreturn_ssve_change_vl(struct tdescr *td,
+					 siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	/* Get a signal context with a SME ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	if (head->size != sizeof(struct sve_context)) {
+		fprintf(stderr, "Register data present, aborting\n");
+		return 1;
+	}
+
+	sve = (struct sve_context *)head;
+
+	/* No changes are supported; init left us at minimum VL so go to max */
+	fprintf(stderr, "Attempting to change VL from %d to %d\n",
+		sve->vl, vls[0]);
+	sve->vl = vls[0];
+
+	fake_sigreturn(&sf, sizeof(sf), 0);
+
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "FAKE_SIGRETURN_SSVE_CHANGE",
+	.descr = "Attempt to change Streaming SVE VL",
+	.feats_required = FEAT_SME,
+	.sig_ok = SIGSEGV,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = fake_sigreturn_ssve_change_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
new file mode 100644
index 000000000000..f9d76ae32bba
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using a streaming mode instruction without enabling it
+ * generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_no_sm_trigger(struct tdescr *td)
+{
+	/* SMSTART ZA ; ADDHA ZA0.S, P0/M, P0/M, Z0.S */
+	asm volatile(".inst 0xd503457f ; .inst 0xc0900000");
+
+	return 0;
+}
+
+int sme_trap_no_sm_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME trap without SM",
+	.descr = "Check that we get a SIGILL if we use streaming mode without enabling it",
+	.timeout = 3,
+	.feats_required = FEAT_SME,   /* We need a SMSTART ZA */
+	.sanity_disabled = true,
+	.trigger = sme_trap_no_sm_trigger,
+	.run = sme_trap_no_sm_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
new file mode 100644
index 000000000000..e469ae5348e3
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using an instruction not supported in streaming mode
+ * traps when in streaming mode.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_non_streaming_trigger(struct tdescr *td)
+{
+	/*
+	 * The framework will handle SIGILL so we need to exit SM to
+	 * stop any other code triggering a further SIGILL down the
+	 * line from using a streaming-illegal instruction.
+	 */
+	asm volatile(".inst 0xd503437f; /* SMSTART ZA */ \
+		      cnt v0.16b, v0.16b; \
+                      .inst 0xd503447f  /* SMSTOP ZA */");
+
+	return 0;
+}
+
+int sme_trap_non_streaming_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME SM trap unsupported instruction",
+	.descr = "Check that we get a SIGILL if we use an unsupported instruction in streaming mode",
+	.feats_required = FEAT_SME,
+	.feats_incompatible = FEAT_SME_FA64,
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_non_streaming_trigger,
+	.run = sme_trap_non_streaming_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
new file mode 100644
index 000000000000..3a7747af4715
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that accessing ZA without enabling it generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_za_trigger(struct tdescr *td)
+{
+	/* ZERO ZA */
+	asm volatile(".inst 0xc00800ff");
+
+	return 0;
+}
+
+int sme_trap_za_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME ZA trap",
+	.descr = "Check that we get a SIGILL if we access ZA without enabling",
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_za_trigger,
+	.run = sme_trap_za_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_vl.c b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
new file mode 100644
index 000000000000..13ff3b35cbaf
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Check that the SME vector length reported in signal contexts is the
+ * expected one.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+unsigned int vl;
+
+static bool get_sme_vl(struct tdescr *td)
+{
+	int ret = prctl(PR_SME_GET_VL);
+	if (ret == -1)
+		return false;
+
+	vl = ret;
+
+	return true;
+}
+
+static int sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct za_context *za;
+
+	/* Get a signal context which should have a ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, ZA_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No ZA context\n");
+		return 1;
+	}
+	za = (struct za_context *)head;
+
+	if (za->vl != vl) {
+		fprintf(stderr, "ZA sigframe VL %u, expected %u\n",
+			za->vl, vl);
+		return 1;
+	} else {
+		fprintf(stderr, "got expected VL %u\n", vl);
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "SME VL",
+	.descr = "Check that we get the right SME VL reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = get_sme_vl,
+	.run = sme_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
new file mode 100644
index 000000000000..44a08d43cd50
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that the streaming SVE register context in signal frames is
+ * set up as expected.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least one VL */
+	if (nvls < 1) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static void setup_ssve_regs(void)
+{
+	/* SMSTART SM */
+	asm volatile(".inst 0x7f4303d5");
+
+	/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
+	asm volatile(".inst 0x04bf5030" : : : "x16" );
+}
+
+static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
+			 unsigned int vl)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *ssve;
+
+	fprintf(stderr, "Testing VL %d\n", vl);
+
+	if (prctl(PR_SME_SET_VL, vl) == -1) {
+		fprintf(stderr, "Failed to set VL\n");
+		return 1;
+	}
+
+	/* 
+	 * Get a signal context which should have a SVE frame and registers
+	 * in it.
+	 */
+	setup_ssve_regs();
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	ssve = (struct sve_context *)head;
+	if (ssve->vl != vl) {
+		fprintf(stderr, "Got VL %d, expected %d\n", ssve->vl, vl);
+		return 1;
+	}
+
+	/* The actual size validation is done in get_current_context() */
+	fprintf(stderr, "Got expected size %u and VL %d\n",
+		head->size, ssve->vl);
+
+	return 0;
+}
+
+static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	int i;
+
+	for (i = 0; i < nvls; i++) {
+		/*
+		 * TODO: the signal test helpers can't currently cope
+		 * with signal frames bigger than struct sigcontext,
+		 * skip VLs that will trigger that.
+		 */
+		if (vls[i] > 64)
+			continue;
+
+		if (do_one_sme_vl(td, si, uc, vls[i]))
+			return 1;
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "Streaming SVE registers",
+	.descr = "Check that we get the right Streaming SVE registers reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = sme_regs,
+};
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:12 +0000
Subject: [PATCH v8 36/38] kselftest/arm64: Add streaming SVE to SVE ptrace
 tests
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-37-broonie@kernel.org>

In order to allow ptrace of streaming mode SVE registers we have added a
new regset for streaming mode which in isolation offers the same ABI as
regular SVE with a different vector type. Add this to the array of regsets
we handle, together with additional tests for the interoperation of the
two regsets.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index 90ba1d6a6781..fb74b11bab71 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -26,6 +26,10 @@
 #define NT_ARM_SVE 0x405
 #endif
 
+#ifndef NT_ARM_SSVE
+#define NT_ARM_SSVE 0x40b
+#endif
+
 struct vec_type {
 	const char *name;
 	unsigned long hwcap_type;
@@ -42,6 +46,13 @@ static const struct vec_type vec_types[] = {
 		.regset = NT_ARM_SVE,
 		.prctl_set = PR_SVE_SET_VL,
 	},
+	{
+		.name = "Streaming SVE",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.regset = NT_ARM_SSVE,
+		.prctl_set = PR_SME_SET_VL,
+	},
 };
 
 #define VL_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:13 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:13 +0000
Subject: [PATCH v8 37/38] kselftest/arm64: Add coverage for the ZA ptrace
 interface
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-38-broonie@kernel.org>

Add some basic coverage for the ZA ptrace interface, including walking
through all the vector lengths supported in the system. As with SVE we do
not currently validate the data all the way through to the running process.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |   1 +
 tools/testing/selftests/arm64/fp/Makefile    |   3 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c | 354 +++++++++++++++++++
 3 files changed, 357 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index ead3197e720b..d98d3d48b504 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,4 +8,5 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-ptrace
 za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 38d2d0d5a0eb..807a8faf8d57 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 CFLAGS += -I../../../../../usr/include/
-TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
+TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg za-ptrace
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
@@ -27,5 +27,6 @@ vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 za-test: za-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+za-ptrace: za-ptrace.o
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-ptrace.c b/tools/testing/selftests/arm64/fp/za-ptrace.c
new file mode 100644
index 000000000000..692c82624855
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-ptrace.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+#include "../../kselftest.h"
+
+/* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
+#ifndef NT_ARM_ZA
+#define NT_ARM_ZA 0x40c
+#endif
+
+#define EXPECTED_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
+
+static void fill_buf(char *buf, size_t size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		buf[i] = random();
+}
+
+static int do_child(void)
+{
+	if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
+		ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno));
+
+	if (raise(SIGSTOP))
+		ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno));
+
+	return EXIT_SUCCESS;
+}
+
+static struct user_za_header *get_za(pid_t pid, void **buf, size_t *size)
+{
+	struct user_za_header *za;
+	void *p;
+	size_t sz = sizeof(*za);
+	struct iovec iov;
+
+	while (1) {
+		if (*size < sz) {
+			p = realloc(*buf, sz);
+			if (!p) {
+				errno = ENOMEM;
+				goto error;
+			}
+
+			*buf = p;
+			*size = sz;
+		}
+
+		iov.iov_base = *buf;
+		iov.iov_len = sz;
+		if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZA, &iov))
+			goto error;
+
+		za = *buf;
+		if (za->size <= sz)
+			break;
+
+		sz = za->size;
+	}
+
+	return za;
+
+error:
+	return NULL;
+}
+
+static int set_za(pid_t pid, const struct user_za_header *za)
+{
+	struct iovec iov;
+
+	iov.iov_base = (void *)za;
+	iov.iov_len = za->size;
+	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZA, &iov);
+}
+
+/* Validate attempting to set the specfied VL via ptrace */
+static void ptrace_set_get_vl(pid_t child, unsigned int vl, bool *supported)
+{
+	struct user_za_header za;
+	struct user_za_header *new_za = NULL;
+	size_t new_za_size = 0;
+	int ret, prctl_vl;
+
+	*supported = false;
+
+	/* Check if the VL is supported in this process */
+	prctl_vl = prctl(PR_SME_SET_VL, vl);
+	if (prctl_vl == -1)
+		ksft_exit_fail_msg("prctl(PR_SME_SET_VL) failed: %s (%d)\n",
+				   strerror(errno), errno);
+
+	/* If the VL is not supported then a supported VL will be returned */
+	*supported = (prctl_vl == vl);
+
+	/* Set the VL by doing a set with no register payload */
+	memset(&za, 0, sizeof(za));
+	za.size = sizeof(za);
+	za.vl = vl;
+	ret = set_za(child, &za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u\n", vl);
+		return;
+	}
+
+	/*
+	 * Read back the new register state and verify that we have the
+	 * same VL that we got from prctl() on ourselves.
+	 */
+	if (!get_za(child, (void **)&new_za, &new_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u\n", vl);
+		return;
+	}
+
+	ksft_test_result(new_za->vl = prctl_vl, "Set VL %u\n", vl);
+
+	free(new_za);
+}
+
+/* Validate attempting to set no ZA data and read it back */
+static void ptrace_set_no_data(pid_t child, unsigned int vl)
+{
+	void *read_buf = NULL;
+	struct user_za_header write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	int ret;
+
+	/* Set up some data and write it out */
+	memset(&write_za, 0, sizeof(write_za));
+	write_za.size = ZA_PT_ZA_OFFSET;
+	write_za.vl = vl;
+
+	ret = set_za(child, &write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u no data\n", vl);
+		return;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u no data\n", vl);
+		return;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za.size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za.size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(read_za->size == write_za.size,
+			 "Disabled ZA for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+}
+
+/* Validate attempting to set data and read it back */
+static void ptrace_set_get_data(pid_t child, unsigned int vl)
+{
+	void *write_buf;
+	void *read_buf = NULL;
+	struct user_za_header *write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	unsigned int vq = sve_vq_from_vl(vl);
+	int ret;
+	size_t data_size;
+
+	data_size = ZA_PT_SIZE(vq);
+	write_buf = malloc(data_size);
+	if (!write_buf) {
+		ksft_test_result_fail("Error allocating %d byte buffer for VL %u\n",
+				      data_size, vl);
+		return;
+	}
+	write_za = write_buf;
+
+	/* Set up some data and write it out */
+	memset(write_za, 0, data_size);
+	write_za->size = data_size;
+	write_za->vl = vl;
+
+	fill_buf(write_buf + ZA_PT_ZA_OFFSET, ZA_PT_ZA_SIZE(vq));
+
+	ret = set_za(child, write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u data\n", vl);
+		goto out;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u data\n", vl);
+		goto out;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za->size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za->size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(memcmp(write_buf + ZA_PT_ZA_OFFSET,
+				read_buf + ZA_PT_ZA_OFFSET,
+				ZA_PT_ZA_SIZE(vq)) == 0,
+			 "Data match for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+out:
+	free(write_buf);
+}
+
+static int do_parent(pid_t child)
+{
+	int ret = EXIT_FAILURE;
+	pid_t pid;
+	int status;
+	siginfo_t si;
+	unsigned int vq, vl;
+	bool vl_supported;
+
+	/* Attach to the child */
+	while (1) {
+		int sig;
+
+		pid = wait(&status);
+		if (pid == -1) {
+			perror("wait");
+			goto error;
+		}
+
+		/*
+		 * This should never happen but it's hard to flag in
+		 * the framework.
+		 */
+		if (pid != child)
+			continue;
+
+		if (WIFEXITED(status) || WIFSIGNALED(status))
+			ksft_exit_fail_msg("Child died unexpectedly\n");
+
+		if (!WIFSTOPPED(status))
+			goto error;
+
+		sig = WSTOPSIG(status);
+
+		if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			if (errno == EINVAL) {
+				sig = 0; /* bust group-stop */
+				goto cont;
+			}
+
+			ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+
+		if (sig == SIGSTOP && si.si_code == SI_TKILL &&
+		    si.si_pid == pid)
+			break;
+
+	cont:
+		if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			ksft_test_result_fail("PTRACE_CONT: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+	}
+
+	/* Step through every possible VQ */
+	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
+		vl = sve_vl_from_vq(vq);
+
+		/* First, try to set this vector length */
+		ptrace_set_get_vl(child, vl, &vl_supported);
+
+		/* If the VL is supported validate data set/get */
+		if (vl_supported) {
+			ptrace_set_no_data(child, vl);
+			ptrace_set_get_data(child, vl);
+		} else {
+			ksft_test_result_skip("Disabled ZA for VL %u\n", vl);
+			ksft_test_result_skip("Get and set data for VL %u\n",
+					      vl);
+		}
+	}
+
+	ret = EXIT_SUCCESS;
+
+error:
+	kill(child, SIGKILL);
+
+disappeared:
+	return ret;
+}
+
+int main(void)
+{
+	int ret = EXIT_SUCCESS;
+	pid_t child;
+
+	srandom(getpid());
+
+	ksft_print_header();
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME)) {
+		ksft_set_plan(1);
+		ksft_exit_skip("SME not available\n");
+	}
+
+	ksft_set_plan(EXPECTED_TESTS);
+
+	child = fork();
+	if (!child)
+		return do_child();
+
+	if (do_parent(child))
+		ret = EXIT_FAILURE;
+
+	ksft_print_cnts();
+
+	return ret;
+}
-- 
2.30.2



From broonie at kernel.org  Mon Jan 24 16:11:14 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 00:11:14 +0000
Subject: [PATCH v8 38/38] kselftest/arm64: Add SME support to syscall ABI test
In-Reply-To: <20220125001114.193425-1-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
Message-ID: <20220125001114.193425-39-broonie@kernel.org>

For every possible combination of SVE and SME vector length verify that for
each possible value of SVCR after a syscall we leave streaming mode and ZA
is preserved. We don't need to take account of any streaming/non streaming
SVE vector length changes in the assembler code since the store instructions
will handle the vector length for us. We log if the system supports FA64 and
only try to set FFR in streaming mode if it does.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 204 ++++++++++++++++--
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 ++
 3 files changed, 265 insertions(+), 23 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
index 983467cfcee0..bc70e04224bf 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
+++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
@@ -9,15 +9,42 @@
 // invoked is configured in x8 of the input GPR data.
 //
 // x0:	SVE VL, 0 for FP only
+// x1:	SME VL
 //
 //	GPRs:	gpr_in, gpr_out
 //	FPRs:	fpr_in, fpr_out
 //	Zn:	z_in, z_out
 //	Pn:	p_in, p_out
 //	FFR:	ffr_in, ffr_out
+//	ZA:	za_in, za_out
+//	SVCR:	svcr_in, svcr_out
+
+#include "syscall-abi.h"
 
 .arch_extension sve
 
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
 .globl do_syscall
 do_syscall:
 	// Store callee saved registers x19-x29 (80 bytes) plus x0 and x1
@@ -30,6 +57,24 @@ do_syscall:
 	stp	x25, x26, [sp, #80]
 	stp	x27, x28, [sp, #96]
 
+	// Set SVCR if we're doing SME
+	cbz	x1, 1f
+	adrp	x2, svcr_in
+	ldr	x2, [x2, :lo12:svcr_in]
+	msr	S3_3_C4_C2_2, x2
+1:
+
+	// Load ZA if it's enabled - uses x12 as scratch due to SME LDR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_in
+2:	_ldr_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Load GPRs x8-x28, and save our SP/FP for later comparison
 	ldr	x2, =gpr_in
 	add	x2, x2, #64
@@ -68,7 +113,7 @@ do_syscall:
 	ldp	q30, q31, [x2, #16 * 30]
 1:
 
-	// Load the SVE registers if we're doing SVE
+	// Load the SVE registers if we're doing SVE/SME
 	cbz	x0, 1f
 
 	ldr	x2, =z_in
@@ -105,9 +150,13 @@ do_syscall:
 	ldr	z30, [x2, #30, MUL VL]
 	ldr	z31, [x2, #31, MUL VL]
 
+	// Only set a non-zero FFR, test patterns must be zero since the
+	// syscall should clear it - this lets us handle FA64.
 	ldr	x2, =ffr_in
+	cbz	x2, 2f
 	ldr	p0, [x2, #0]
 	wrffr	p0.b
+2:
 
 	ldr	x2, =p_in
 	ldr	p0, [x2, #0, MUL VL]
@@ -169,6 +218,24 @@ do_syscall:
 	stp	q28, q29, [x2, #16 * 28]
 	stp	q30, q31, [x2, #16 * 30]
 
+	// Save SVCR if we're doing SME
+	cbz	x1, 1f
+	mrs	x2, S3_3_C4_C2_2
+	adrp	x3, svcr_out
+	str	x2, [x3, :lo12:svcr_out]
+1:
+
+	// Save ZA if it's enabled - uses x12 as scratch due to SME STR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_out
+2:	_str_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Save the SVE state if we have some
 	cbz	x0, 1f
 
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index 1e13b7523918..b632bfe9e022 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,9 +18,13 @@
 
 #include "../../kselftest.h"
 
+#include "syscall-abi.h"
+
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
-extern void do_syscall(int sve_vl);
+static int default_sme_vl;
+
+extern void do_syscall(int sve_vl, int sme_vl);
 
 static void fill_random(void *buf, size_t size)
 {
@@ -48,14 +52,15 @@ static struct syscall_cfg {
 uint64_t gpr_in[NUM_GPR];
 uint64_t gpr_out[NUM_GPR];
 
-static void setup_gpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(gpr_in, sizeof(gpr_in));
 	gpr_in[8] = cfg->syscall_nr;
 	memset(gpr_out, 0, sizeof(gpr_out));
 }
 
-static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -79,13 +84,15 @@ static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
 uint64_t fpr_in[NUM_FPR * 2];
 uint64_t fpr_out[NUM_FPR * 2];
 
-static void setup_fpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(fpr_in, sizeof(fpr_in));
 	memset(fpr_out, 0, sizeof(fpr_out));
 }
 
-static int check_fpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -109,13 +116,15 @@ static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_z(struct syscall_cfg *cfg, int sve_vl)
+static void setup_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(z_in, sizeof(z_in));
 	fill_random(z_out, sizeof(z_out));
 }
 
-static int check_z(struct syscall_cfg *cfg, int sve_vl)
+static int check_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vl;
 	int errors = 0;
@@ -126,13 +135,17 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 
 	/*
 	 * After a syscall the low 128 bits of the Z registers should
-	 * be preserved and the rest be zeroed or preserved.
+	 * be preserved and the rest be zeroed or preserved, except if
+	 * we were in streaming mode in which case the low 128 bits may
+	 * also be cleared by the transition out of streaming mode.
 	 */
 	for (i = 0; i < SVE_NUM_ZREGS; i++) {
 		void *in = &z_in[reg_size * i];
 		void *out = &z_out[reg_size * i];
 
-		if (memcmp(in, out, SVE_VQ_BYTES) != 0) {
+		if ((memcmp(in, out, SVE_VQ_BYTES) != 0) &&
+		    !((svcr & SVCR_SM_MASK) &&
+		      memcmp(z_zero, out, SVE_VQ_BYTES) == 0)) {
 			ksft_print_msg("%s SVE VL %d Z%d low 128 bits changed\n",
 				       cfg->name, sve_vl, i);
 			errors++;
@@ -145,13 +158,15 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_p(struct syscall_cfg *cfg, int sve_vl)
+static void setup_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(p_in, sizeof(p_in));
 	fill_random(p_out, sizeof(p_out));
 }
 
-static int check_p(struct syscall_cfg *cfg, int sve_vl)
+static int check_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2; /* 1 bit per VL byte */
 
@@ -175,8 +190,19 @@ static int check_p(struct syscall_cfg *cfg, int sve_vl)
 uint8_t ffr_in[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t ffr_out[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
+	/*
+	 * If we are in streaming mode and do not have FA64 then FFR
+	 * is unavailable.
+	 */
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)) {
+		memset(&ffr_in, 0, sizeof(ffr_in));
+		return;
+	}
+
 	/*
 	 * It is only valid to set a contiguous set of bits starting
 	 * at 0.  For now since we're expecting this to be cleared by
@@ -186,7 +212,8 @@ static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
 	fill_random(ffr_out, sizeof(ffr_out));
 }
 
-static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
+static int check_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2;  /* 1 bit per VL byte */
 	int errors = 0;
@@ -195,6 +222,10 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	if (!sve_vl)
 		return 0;
 
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64))
+		return 0;
+
 	/* After a syscall the P registers should be preserved or zeroed */
 	for (i = 0; i < reg_size; i++)
 		if (ffr_out[i] && (ffr_in[i] != ffr_out[i]))
@@ -206,8 +237,65 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	return errors;
 }
 
-typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl);
-typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl);
+uint64_t svcr_in, svcr_out;
+
+static void setup_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	svcr_in = svcr;
+}
+
+static int check_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
+{
+	int errors = 0;
+
+	if (svcr_out & SVCR_SM_MASK) {
+		ksft_print_msg("%s Still in SM, SVCR %llx\n",
+			       cfg->name, svcr_out);
+		errors++;
+	}
+
+	if ((svcr_in & SVCR_ZA_MASK) != (svcr_out & SVCR_ZA_MASK)) {
+		ksft_print_msg("%s PSTATE.ZA changed, SVCR %llx != %llx\n",
+			       cfg->name, svcr_in, svcr_out);
+		errors++;
+	}
+
+	return errors;
+}
+
+uint8_t za_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+uint8_t za_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+
+static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
+{
+	fill_random(za_in, sizeof(za_in));
+	memset(za_out, 0, sizeof(za_out));
+}
+
+static int check_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	size_t reg_size = sme_vl * sme_vl;
+	int errors = 0;
+
+	if (!(svcr & SVCR_ZA_MASK))
+		return 0;
+
+	if (memcmp(za_in, za_out, reg_size) != 0) {
+		ksft_print_msg("SME VL %d ZA does not match\n", sme_vl);
+		errors++;
+	}
+
+	return errors;
+}
+
+typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			 uint64_t svcr);
+typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			uint64_t svcr);
 
 /*
  * Each set of registers has a setup function which is called before
@@ -225,20 +313,23 @@ static struct {
 	{ setup_z, check_z },
 	{ setup_p, check_p },
 	{ setup_ffr, check_ffr },
+	{ setup_svcr, check_svcr },
+	{ setup_za, check_za },
 };
 
-static bool do_test(struct syscall_cfg *cfg, int sve_vl)
+static bool do_test(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	int errors = 0;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		regset[i].setup(cfg, sve_vl);
+		regset[i].setup(cfg, sve_vl, sme_vl, svcr);
 
-	do_syscall(sve_vl);
+	do_syscall(sve_vl, sme_vl);
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		errors += regset[i].check(cfg, sve_vl);
+		errors += regset[i].check(cfg, sve_vl, sme_vl, svcr);
 
 	return errors == 0;
 }
@@ -246,9 +337,10 @@ static bool do_test(struct syscall_cfg *cfg, int sve_vl)
 static void test_one_syscall(struct syscall_cfg *cfg)
 {
 	int sve_vq, sve_vl;
+	int sme_vq, sme_vl;
 
 	/* FPSIMD only case */
-	ksft_test_result(do_test(cfg, 0),
+	ksft_test_result(do_test(cfg, 0, default_sme_vl, 0),
 			 "%s FPSIMD\n", cfg->name);
 
 	if (!(getauxval(AT_HWCAP) & HWCAP_SVE))
@@ -265,8 +357,36 @@ static void test_one_syscall(struct syscall_cfg *cfg)
 		if (sve_vq != sve_vq_from_vl(sve_vl))
 			sve_vq = sve_vq_from_vl(sve_vl);
 
-		ksft_test_result(do_test(cfg, sve_vl),
+		ksft_test_result(do_test(cfg, sve_vl, default_sme_vl, 0),
 				 "%s SVE VL %d\n", cfg->name, sve_vl);
+
+		if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+			continue;
+
+		for (sme_vq = SVE_VQ_MAX; sme_vq > 0; --sme_vq) {
+			sme_vl = prctl(PR_SME_SET_VL, sme_vq * 16);
+			if (sme_vl == -1)
+				ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+						   strerror(errno), errno);
+
+			sme_vl &= PR_SME_VL_LEN_MASK;
+
+			if (sme_vq != sve_vq_from_vl(sme_vl))
+				sme_vq = sve_vq_from_vl(sme_vl);
+
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK | SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM+ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK),
+					 "%s SVE VL %d/SME VL %d ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+		}
 	}
 }
 
@@ -299,14 +419,54 @@ int sve_count_vls(void)
 	return vl_count;
 }
 
+int sme_count_vls(void)
+{
+	unsigned int vq;
+	int vl_count = 0;
+	int vl;
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+		return 0;
+
+	/* Ensure we configure a SME VL, used to flag if SVCR is set */
+	default_sme_vl = 16;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SME_SET_VL, vq * 16);
+		if (vl == -1)
+			ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+					   strerror(errno), errno);
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		if (vq != sve_vq_from_vl(vl))
+			vq = sve_vq_from_vl(vl);
+
+		vl_count++;
+	}
+
+	return vl_count;
+}
+
 int main(void)
 {
 	int i;
+	int tests = 1;  /* FPSIMD */
 
 	srandom(getpid());
 
 	ksft_print_header();
-	ksft_set_plan(ARRAY_SIZE(syscalls) * (sve_count_vls() + 1));
+	tests += sve_count_vls();
+	tests += (sve_count_vls() * sme_count_vls()) * 3;
+	ksft_set_plan(ARRAY_SIZE(syscalls) * tests);
+
+	if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+		ksft_print_msg("SME with FA64\n");
+	else if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+		ksft_print_msg("SME without FA64\n");
 
 	for (i = 0; i < ARRAY_SIZE(syscalls); i++)
 		test_one_syscall(&syscalls[i]);
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.h b/tools/testing/selftests/arm64/abi/syscall-abi.h
new file mode 100644
index 000000000000..bda5a87ad381
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+
+#ifndef SYSCALL_ABI_H
+#define SYSCALL_ABI_H
+
+#define SVCR_ZA_MASK		2
+#define SVCR_SM_MASK		1
+
+#define SVCR_ZA_SHIFT		1
+#define SVCR_SM_SHIFT		0
+
+#endif
-- 
2.30.2



From linus.walleij at linaro.org  Mon Jan 24 16:27:43 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Jan 2022 01:27:43 +0100
Subject: [PATCH] ARM/pxa/mfd/power/sound: Switch Tosa to GPIO descriptors
In-Reply-To: <YPE6d4WWYAWgnsCH@google.com>
References: <20210715151625.394960-1-linus.walleij@linaro.org>
 <YPE6d4WWYAWgnsCH@google.com>
Message-ID: <CACRpkda3oaEguO5VgvMdVuLGpSU9rZbwCyT_cFj066NOCO4hcA@mail.gmail.com>

Hi Lee,

On Fri, Jul 16, 2021 at 9:51 AM Lee Jones <lee.jones at linaro.org> wrote:

Sorry for taking halfyears to get back to patches... cleanup tends
to get low prio. :/

Fixed most review comments.

> > +#define TOSA_GPIO_TG_ON                      0
> > +#define TOSA_GPIO_L_MUTE             1
> > +#define TOSA_GPIO_BL_C20MA           3
> > +#define TOSA_GPIO_CARD_VCC_ON                4
> > +#define TOSA_GPIO_CHARGE_OFF         6
> > +#define TOSA_GPIO_CHARGE_OFF_JC              7
> > +#define TOSA_GPIO_BAT0_V_ON          9
> > +#define TOSA_GPIO_BAT1_V_ON          10
> > +#define TOSA_GPIO_BU_CHRG_ON         11
> > +#define TOSA_GPIO_BAT_SW_ON          12
> > +#define TOSA_GPIO_BAT0_TH_ON         14
> > +#define TOSA_GPIO_BAT1_TH_ON         15
>
> Okay, I have to ask - what are 5, 8 and 13?

Apparently unused, just picked from:
arch/arm/mach-pxa/include/mach/tosa.h

Put there in commit 8459c159f7de832eaf888398d2abf466c388dfa6
"[ARM] 3088/1: PXA: Add machine support for the Sharp SL-6000x series of PDAs"
Dirk who authored the commit is on CC so maybe he can say.
I suppose he has access to the board documentation.
(I couldn't find any.)

> > +static struct gpiod_lookup_table tosa_audio_gpio_lookup = {
> > +     .dev_id = "tosa-audio",
> > +     .table = {
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH),
> > +             { },
> > +     },
> > +};
>
> Are these structures going to be peppered all over the kernel now?

Yeah well for legacy systems, for the reasons given in
drivers/gpio/TODO

It's not millions of occurences, just hundreds.
$ git grep GPIO_LOOKUP|wc -l
507

> Maybe a helper can be added to make these single line entries one line
> each?

Hmmm I will try to sketch something out for v2!

> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_CHARGE_OFF,
> > +                         "main charge off", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_CHARGE_OFF_JC,
> > +                         "jacket charge off", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BAT0_V_ON,
> > +                         "main battery", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BAT1_V_ON,
> > +                         "jacket battery", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BU_CHRG_ON,
> > +                         "backup battery", GPIO_ACTIVE_HIGH),
> > +             /* BAT1 and BAT0 thermistors appear to be swapped */
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BAT1_TH_ON,
> > +                         "main battery temp", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BAT0_TH_ON,
> > +                         "jacket battery temp", GPIO_ACTIVE_HIGH),
> > +             GPIO_LOOKUP(TOSA_GC_NAME, TOSA_GPIO_BAT_SW_ON,
> > +                         "battery switch", GPIO_ACTIVE_HIGH),
>
> These are soooo close to being <100 chars.
>
> What does Checkpatch currently warn on?  Is it 100 or 120?

100...

WARNING: line length of 104 exceeds 100 columns
#283: FILE: drivers/mfd/tc6393xb.c:532:
+        GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC, "jacket
charge off", GPIO_ACTIVE_HIGH),

WARNING: line length of 101 exceeds 100 columns
#288: FILE: drivers/mfd/tc6393xb.c:537:
+        GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON, "main battery
temp", GPIO_ACTIVE_HIGH),

(...)

If you want to, we can ignore it of course. Just tell me what to do.

> > +     gc->ngpio = 16;
> > +     gc->set = tc6393xb_gpio_set;
> > +     gc->get = tc6393xb_gpio_get;
> > +     gc->direction_input = tc6393xb_gpio_direction_input;
> > +     gc->direction_output = tc6393xb_gpio_direction_output;
> > +
> > +     ret = devm_gpiochip_add_data(dev, gc, tc6393xb);
> > +     if (ret)
> > +             return dev_err_probe(dev, ret, "failed to add GPIO chip\n");
> > +
> > +     /* Register descriptor look-ups for consumers */
> > +     gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups));
> > +
> > +     /* Request some of our own GPIOs */
> > +     tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON",
> > +                                                  GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
> > +     if (IS_ERR(tc6393xb->vcc_on))
> > +             return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on),
> > +                                  "failed to request VCC ON GPIO\n");
> > +
>
> So much more code to do the same thing?

Not quite the same thing.

The old code does not report any errors from gpiochip_add_data()
(hence all the dev_err_probe()).

The added gpiochip_request_own_desc() call moves the similar code out
of arch/arm
to here where the gpiochip is and is actually using fewer lines now.
(See higher up the patch.)

> > +     tc6393xb->dev = &dev->dev;
>
> That confused me at first.
>
> Please consider changing the platform_device to pdev (separately).

OK I can follow up with that once this looks like we want it,
this problem is a bit all over the kernel actually, especially
in legacy code from the early 2000s.

Have a look at v2 and see what you think!

Yours,
Linus Walleij


From quic_collinsd at quicinc.com  Mon Jan 24 16:27:34 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 16:27:34 -0800
Subject: [RESEND PATCH 0/2] regulator: scmi: add support for registering SCMI
 regulators by name
Message-ID: <cover.1643069954.git.quic_collinsd@quicinc.com>

Add support to register SCMI regulator subnodes based on an SCMI
Voltage Domain name specified via the 'regulator-name' device tree
property.  In doing so, make the 'reg' property optional with the
constraint that at least one of 'reg' or 'regulator-name' must be
specified.  If both are specified, then both must match the
Voltage Domain data exposed by the SCMI platform.

Name based SCMI regulator registration helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

David Collins (2):
  dt-bindings: firmware: arm,scmi: define support for name based
    regulators
  regulator: scmi: add support for registering SCMI regulators by name

 .../bindings/firmware/arm,scmi.yaml           | 11 +++-
 drivers/regulator/scmi-regulator.c            | 57 ++++++++++++++++++-
 2 files changed, 62 insertions(+), 6 deletions(-)

-- 
2.17.1



From quic_collinsd at quicinc.com  Mon Jan 24 16:27:36 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 16:27:36 -0800
Subject: [RESEND PATCH 2/2] regulator: scmi: add support for registering SCMI
 regulators by name
In-Reply-To: <cover.1643069954.git.quic_collinsd@quicinc.com>
References: <cover.1643069954.git.quic_collinsd@quicinc.com>
Message-ID: <c3f16fb1e71bd30cef41156769b8e1ce8c0de94a.1643069954.git.quic_collinsd@quicinc.com>

Add support to register SCMI regulator subnodes based on an SCMI
Voltage Domain name specified via the 'regulator-name' device tree
property.  In doing so, make the 'reg' property optional with the
constraint that at least one of 'reg' or 'regulator-name' must be
specified.  If both are specified, then both must match the
Voltage Domain data exposed by the SCMI platform.

Name based SCMI regulator registration helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

Signed-off-by: David Collins <quic_collinsd at quicinc.com>
---
 drivers/regulator/scmi-regulator.c | 57 ++++++++++++++++++++++++++++--
 1 file changed, 54 insertions(+), 3 deletions(-)

diff --git a/drivers/regulator/scmi-regulator.c b/drivers/regulator/scmi-regulator.c
index 1f02f60ad136..c3287901975e 100644
--- a/drivers/regulator/scmi-regulator.c
+++ b/drivers/regulator/scmi-regulator.c
@@ -31,6 +31,7 @@
 #include <linux/regulator/of_regulator.h>
 #include <linux/scmi_protocol.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/types.h>
 
 static const struct scmi_voltage_proto_ops *voltage_ops;
@@ -252,16 +253,66 @@ static int scmi_regulator_common_init(struct scmi_regulator *sreg)
 	return 0;
 }
 
+static int scmi_regulator_map_name(struct scmi_protocol_handle *ph,
+				   struct scmi_regulator_info *rinfo,
+				   const char *name)
+{
+	const struct scmi_voltage_info *vinfo;
+	int i;
+
+	for (i = 0; i < rinfo->num_doms; i++) {
+		vinfo = voltage_ops->info_get(ph, i);
+		if (!vinfo)
+			continue;
+		if (!strncmp(vinfo->name, name, sizeof(vinfo->name)))
+			return i;
+	}
+
+	return -ENODEV;
+}
+
 static int process_scmi_regulator_of_node(struct scmi_device *sdev,
 					  struct scmi_protocol_handle *ph,
 					  struct device_node *np,
 					  struct scmi_regulator_info *rinfo)
 {
 	u32 dom, ret;
+	int name_dom;
+	const char *name;
 
-	ret = of_property_read_u32(np, "reg", &dom);
-	if (ret)
-		return ret;
+	dom = rinfo->num_doms;
+	if (of_find_property(np, "reg", NULL)) {
+		ret = of_property_read_u32(np, "reg", &dom);
+		if (ret)
+			return ret;
+
+		if (dom >= rinfo->num_doms)
+			return -ENODEV;
+	}
+
+	if (of_find_property(np, "regulator-name", NULL)) {
+		ret = of_property_read_string(np, "regulator-name", &name);
+		if (ret)
+			return ret;
+
+		name_dom = scmi_regulator_map_name(ph, rinfo, name);
+		if (name_dom < 0) {
+			dev_err(&sdev->dev,
+				"No SCMI Voltage Domain found named %s. Skipping: %s\n",
+				name, np->full_name);
+			return name_dom;
+		}
+
+		if (dom >= rinfo->num_doms)
+			dom = name_dom;
+
+		if (name_dom != dom) {
+			dev_err(&sdev->dev,
+				"SCMI Voltage Domain %s ID mismatch, %u (DT) != %d (firmware). Skipping: %s\n",
+				name, dom, name_dom, np->full_name);
+			return -EINVAL;
+		}
+	}
 
 	if (dom >= rinfo->num_doms)
 		return -ENODEV;
-- 
2.17.1



From quic_collinsd at quicinc.com  Mon Jan 24 16:27:35 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Mon, 24 Jan 2022 16:27:35 -0800
Subject: [RESEND PATCH 1/2] dt-bindings: firmware: arm,
 scmi: define support for name based regulators
In-Reply-To: <cover.1643069954.git.quic_collinsd@quicinc.com>
References: <cover.1643069954.git.quic_collinsd@quicinc.com>
Message-ID: <fcd130891cc1d52cb09b8bfc866ab7ef1ce3b2a1.1643069954.git.quic_collinsd@quicinc.com>

Allow SCMI regulator subnodes to be specified either by ID using
the "reg" property or by name using the "regulator-name" property.

Name based SCMI regulator specification helps ensure that an SCMI
agent doesn't need to be aware of the numbering scheme used for
Voltage Domains by the SCMI platform.  It also ensures that the
correct Voltage Domain is selected for a given physical regulator.
This cannot be guaranteed with numeric Voltage Domain IDs alone.

Signed-off-by: David Collins <quic_collinsd at quicinc.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/firmware/arm,scmi.yaml        | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
index 5c4c6782e052..bc4a84fe25d2 100644
--- a/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
+++ b/Documentation/devicetree/bindings/firmware/arm,scmi.yaml
@@ -155,7 +155,7 @@ properties:
           The list of all regulators provided by this SCMI controller.
 
         patternProperties:
-          '^regulators@[0-9a-f]+$':
+          '^regulator.+$':
             type: object
             $ref: "../regulator/regulator.yaml#"
 
@@ -164,8 +164,13 @@ properties:
                 maxItems: 1
                 description: Identifier for the voltage regulator.
 
-            required:
-              - reg
+              regulator-name: true
+
+            anyOf:
+              - required:
+                  - reg
+              - required:
+                  - regulator-name
 
 additionalProperties: false
 
-- 
2.17.1



From yang.lee at linux.alibaba.com  Mon Jan 24 16:28:39 2022
From: yang.lee at linux.alibaba.com (Yang Li)
Date: Tue, 25 Jan 2022 08:28:39 +0800
Subject: [PATCH -next] media: mtk-vcodec: Remove duplicated include in
 mtk_vcodec_enc_drv.c
Message-ID: <20220125002839.92004-1-yang.lee@linux.alibaba.com>

Fix following includecheck warning:
./drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c:
linux/pm_runtime.h is included more than once.

Reported-by: Abaci Robot <abaci at linux.alibaba.com>
Signed-off-by: Yang Li <yang.lee at linux.alibaba.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
index 507ad1ea2104..a3870628c9f0 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c
@@ -15,7 +15,6 @@
 #include <media/v4l2-event.h>
 #include <media/v4l2-mem2mem.h>
 #include <media/videobuf2-dma-contig.h>
-#include <linux/pm_runtime.h>
 
 #include "mtk_vcodec_drv.h"
 #include "mtk_vcodec_enc.h"
-- 
2.20.1.7.g153144c



From linus.walleij at linaro.org  Mon Jan 24 16:37:41 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Jan 2022 01:37:41 +0100
Subject: [PATCH v2] ARM/pxa/mfd/power/sound: Switch Tosa to GPIO descriptors
Message-ID: <20220125003741.492954-1-linus.walleij@linaro.org>

The Tosa device (Sharp SL-6000) has a mishmash driver set-up
for the Toshiba TC6393xb MFD that includes a battery charger
and touchscreen and has some kind of relationship to the SoC
sound driver for the AC97 codec. Other devices define a chip
like this but seem only half-implemented, not really handling
battery charging etc.

This patch switches the Toshiba MFD device to provide GPIO
descriptors to the battery charger and SoC codec. As a result
some descriptors need to be moved out of the Tosa boardfile
and new one added: all SoC GPIO resources to these drivers
now comes from the main boardfile, while the MFD provide
GPIOs for its portions.

As a result we can request one GPIO from our own GPIO chip
and drop two hairy callbacks into the board file.

This platform badly needs to have its drivers split up and
converted to device tree probing to handle this quite complex
relationship in an orderly manner. I just do my best in solving
the GPIO descriptor part of the puzzle. Please don't ask me
to fix everything that is wrong with these driver to todays
standards, I am just trying to fix one aspect. I do try to
use modern devres resource management and handle deferred
probe using new functions where appropriate.

Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
Cc: Dirk Opfer <dirk at opfer-online.de>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Lee Jones <lee.jones at linaro.org>
Cc: Liam Girdwood <lgirdwood at gmail.com>
Acked-by: Mark Brown <broonie at kernel.org>
Acked-by: Sebastian Reichel <sebastian.reichel at collabora.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v1->v2:
- Rebase on v5.17-rc1
- Collect some ACKs.
- Drop comments on includes.
- Replace defined TOSA_GC_NAME with explicit string
- Add a macro GPIO_LOOKUP_SINGLE() and use it in the patch
- As we removed the only users of the .setup() and .teardown()
  callbacks in struct tc6393xb_platform_data these members
  can be removed.
Merging strategy: please provide ACKs and I will attempt
to merge this through the SoC tree.
---
 arch/arm/mach-pxa/eseries.c           |   2 -
 arch/arm/mach-pxa/include/mach/tosa.h |  18 ---
 arch/arm/mach-pxa/tosa.c              |  68 +++-------
 drivers/mfd/tc6393xb.c                | 130 ++++++++++++++------
 drivers/power/supply/tosa_battery.c   | 171 ++++++++++++++++----------
 include/linux/gpio/machine.h          |  12 ++
 include/linux/mfd/tc6393xb.h          |   3 -
 sound/soc/pxa/tosa.c                  |  20 ++-
 8 files changed, 241 insertions(+), 183 deletions(-)

diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index f37c44b6139d..9e9b5c78f8ad 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -699,7 +699,6 @@ static struct tc6393xb_platform_data e750_tc6393xb_info = {
 	.irq_base       = IRQ_BOARD_START,
 	.scr_pll2cr     = 0x0cc1,
 	.scr_gper       = 0,
-	.gpio_base      = -1,
 	.suspend        = &eseries_tmio_suspend,
 	.resume         = &eseries_tmio_resume,
 	.enable         = &eseries_tmio_enable,
@@ -918,7 +917,6 @@ static struct tc6393xb_platform_data e800_tc6393xb_info = {
 	.irq_base       = IRQ_BOARD_START,
 	.scr_pll2cr     = 0x0cc1,
 	.scr_gper       = 0,
-	.gpio_base      = -1,
 	.suspend        = &eseries_tmio_suspend,
 	.resume         = &eseries_tmio_resume,
 	.enable         = &eseries_tmio_enable,
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index 8bfaca3a8b64..3b3efa0a0e22 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -54,24 +54,6 @@
 /* GPIO Direction   1 : output mode / 0:input mode */
 #define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)
 
-/*
- * TC6393XB GPIOs
- */
-#define TOSA_TC6393XB_GPIO_BASE		(PXA_NR_BUILTIN_GPIO + 2 * 12)
-
-#define TOSA_GPIO_TG_ON			(TOSA_TC6393XB_GPIO_BASE + 0)
-#define TOSA_GPIO_L_MUTE		(TOSA_TC6393XB_GPIO_BASE + 1)
-#define TOSA_GPIO_BL_C20MA		(TOSA_TC6393XB_GPIO_BASE + 3)
-#define TOSA_GPIO_CARD_VCC_ON		(TOSA_TC6393XB_GPIO_BASE + 4)
-#define TOSA_GPIO_CHARGE_OFF		(TOSA_TC6393XB_GPIO_BASE + 6)
-#define TOSA_GPIO_CHARGE_OFF_JC		(TOSA_TC6393XB_GPIO_BASE + 7)
-#define TOSA_GPIO_BAT0_V_ON		(TOSA_TC6393XB_GPIO_BASE + 9)
-#define TOSA_GPIO_BAT1_V_ON		(TOSA_TC6393XB_GPIO_BASE + 10)
-#define TOSA_GPIO_BU_CHRG_ON		(TOSA_TC6393XB_GPIO_BASE + 11)
-#define TOSA_GPIO_BAT_SW_ON		(TOSA_TC6393XB_GPIO_BASE + 12)
-#define TOSA_GPIO_BAT0_TH_ON		(TOSA_TC6393XB_GPIO_BASE + 14)
-#define TOSA_GPIO_BAT1_TH_ON		(TOSA_TC6393XB_GPIO_BASE + 15)
-
 /*
  * PXA GPIOs
  */
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 431709725d02..bead2ff44d3e 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -616,6 +616,22 @@ static struct resource tc6393xb_resources[] = {
 	},
 };
 
+static struct gpiod_lookup_table tosa_battery_gpio_table = {
+	.dev_id = "wm97xx-battery",
+	.table = {
+		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_CRG,
+			    "main battery full", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_CRG,
+			    "jacket battery full", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_LOW,
+			    "main battery low", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_LOW,
+			    "jacket battery low", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_JACKET_DETECT,
+			    "jacket detect", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
 
 static int tosa_tc6393xb_enable(struct platform_device *dev)
 {
@@ -709,31 +725,6 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = {
 	.part_parsers = probes,
 };
 
-static int tosa_tc6393xb_setup(struct platform_device *dev)
-{
-	int rc;
-
-	rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
-	if (rc)
-		goto err_req;
-
-	rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
-	if (rc)
-		goto err_dir;
-
-	return rc;
-
-err_dir:
-	gpio_free(TOSA_GPIO_CARD_VCC_ON);
-err_req:
-	return rc;
-}
-
-static void tosa_tc6393xb_teardown(struct platform_device *dev)
-{
-	gpio_free(TOSA_GPIO_CARD_VCC_ON);
-}
-
 #ifdef CONFIG_MFD_TC6393XB
 static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
 	{
@@ -778,9 +769,6 @@ static struct tc6393xb_platform_data tosa_tc6393xb_data = {
 	.scr_gper	= 0x3300,
 
 	.irq_base	= IRQ_BOARD_START,
-	.gpio_base	= TOSA_TC6393XB_GPIO_BASE,
-	.setup		= tosa_tc6393xb_setup,
-	.teardown	= tosa_tc6393xb_teardown,
 
 	.enable		= tosa_tc6393xb_enable,
 	.disable	= tosa_tc6393xb_disable,
@@ -821,26 +809,6 @@ static struct pxa2xx_spi_controller pxa_ssp_master_info = {
 	.num_chipselect	= 1,
 };
 
-static struct gpiod_lookup_table tosa_lcd_gpio_table = {
-	.dev_id = "spi2.0",
-	.table = {
-		GPIO_LOOKUP("tc6393xb",
-			    TOSA_GPIO_TG_ON - TOSA_TC6393XB_GPIO_BASE,
-			    "tg #pwr", GPIO_ACTIVE_HIGH),
-		{ },
-	},
-};
-
-static struct gpiod_lookup_table tosa_lcd_bl_gpio_table = {
-	.dev_id = "i2c-tosa-bl",
-	.table = {
-		GPIO_LOOKUP("tc6393xb",
-			    TOSA_GPIO_BL_C20MA - TOSA_TC6393XB_GPIO_BASE,
-			    "backlight", GPIO_ACTIVE_HIGH),
-		{ },
-	},
-};
-
 static struct spi_board_info spi_board_info[] __initdata = {
 	{
 		.modalias	= "tosa-lcd",
@@ -943,6 +911,8 @@ static void __init tosa_init(void)
 	/* enable batt_fault */
 	PMCR = 0x01;
 
+	gpiod_add_lookup_table(&tosa_battery_gpio_table);
+
 	gpiod_add_lookup_table(&tosa_mci_gpio_table);
 	pxa_set_mci_info(&tosa_mci_platform_data);
 	pxa_set_ficp_info(&tosa_ficp_platform_data);
@@ -951,8 +921,6 @@ static void __init tosa_init(void)
 	platform_scoop_config = &tosa_pcmcia_config;
 
 	pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
-	gpiod_add_lookup_table(&tosa_lcd_gpio_table);
-	gpiod_add_lookup_table(&tosa_lcd_bl_gpio_table);
 	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
 
 	clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 3d5b14c60e20..886006144896 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -22,6 +22,8 @@
 #include <linux/mfd/tmio.h>
 #include <linux/mfd/tc6393xb.h>
 #include <linux/gpio/driver.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 
 #define SCR_REVID	0x08		/* b Revision ID	*/
@@ -87,8 +89,10 @@
 
 struct tc6393xb {
 	void __iomem		*scr;
+	struct device		*dev;
 
 	struct gpio_chip	gpio;
+	struct gpio_desc	*vcc_on;
 
 	struct clk		*clk; /* 3,6 Mhz */
 
@@ -497,17 +501,93 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
 	return 0;
 }
 
-static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
+/*
+ * TC6393XB GPIOs as used on TOSA, are the only user of this chip.
+ * The use of GPIOs 5, 8 and 14 is unknown.
+ */
+#define TOSA_GPIO_TG_ON			0
+#define TOSA_GPIO_L_MUTE		1
+#define TOSA_GPIO_BL_C20MA		3
+#define TOSA_GPIO_CARD_VCC_ON		4
+#define TOSA_GPIO_CHARGE_OFF		6
+#define TOSA_GPIO_CHARGE_OFF_JC		7
+#define TOSA_GPIO_BAT0_V_ON		9
+#define TOSA_GPIO_BAT1_V_ON		10
+#define TOSA_GPIO_BU_CHRG_ON		11
+#define TOSA_GPIO_BAT_SW_ON		12
+#define TOSA_GPIO_BAT0_TH_ON		14
+#define TOSA_GPIO_BAT1_TH_ON		15
+
+
+GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb",
+		   TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH);
+
+GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb",
+		   TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH);
+
+GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb",
+		   TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH);
+
+static struct gpiod_lookup_table tosa_battery_gpio_lookup = {
+	.dev_id = "wm97xx-battery",
+	.table = {
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF,
+			    "main charge off", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC,
+			    "jacket charge off", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON,
+			    "main battery", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON,
+			    "jacket battery", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON,
+			    "backup battery", GPIO_ACTIVE_HIGH),
+		/* BAT1 and BAT0 thermistors appear to be swapped */
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON,
+			    "main battery temp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON,
+			    "jacket battery temp", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON,
+			    "battery switch", GPIO_ACTIVE_HIGH),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = {
+	&tosa_lcd_gpio_lookup,
+	&tosa_lcd_bl_gpio_lookup,
+	&tosa_audio_gpio_lookup,
+	&tosa_battery_gpio_lookup,
+};
+
+static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb)
 {
-	tc6393xb->gpio.label = "tc6393xb";
-	tc6393xb->gpio.base = gpio_base;
-	tc6393xb->gpio.ngpio = 16;
-	tc6393xb->gpio.set = tc6393xb_gpio_set;
-	tc6393xb->gpio.get = tc6393xb_gpio_get;
-	tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
-	tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
-
-	return gpiochip_add_data(&tc6393xb->gpio, tc6393xb);
+	struct gpio_chip *gc = &tc6393xb->gpio;
+	struct device *dev = tc6393xb->dev;
+	int ret;
+
+	gc->label = "tc6393xb";
+	gc->base = -1; /* Dynamic allocation */
+	gc->ngpio = 16;
+	gc->set = tc6393xb_gpio_set;
+	gc->get = tc6393xb_gpio_get;
+	gc->direction_input = tc6393xb_gpio_direction_input;
+	gc->direction_output = tc6393xb_gpio_direction_output;
+
+	ret = devm_gpiochip_add_data(dev, gc, tc6393xb);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to add GPIO chip\n");
+
+	/* Register descriptor look-ups for consumers */
+	gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups));
+
+	/* Request some of our own GPIOs */
+	tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON",
+						     GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
+	if (IS_ERR(tc6393xb->vcc_on))
+		return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on),
+				     "failed to request VCC ON GPIO\n");
+
+	return 0;
 }
 
 /*--------------------------------------------------------------------------*/
@@ -617,6 +697,7 @@ static int tc6393xb_probe(struct platform_device *dev)
 		ret = -ENOMEM;
 		goto err_kzalloc;
 	}
+	tc6393xb->dev = &dev->dev;
 
 	raw_spin_lock_init(&tc6393xb->lock);
 
@@ -676,22 +757,12 @@ static int tc6393xb_probe(struct platform_device *dev)
 			tmio_ioread8(tc6393xb->scr + SCR_REVID),
 			(unsigned long) iomem->start, tc6393xb->irq);
 
-	tc6393xb->gpio.base = -1;
-
-	if (tcpd->gpio_base >= 0) {
-		ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
-		if (ret)
-			goto err_gpio_add;
-	}
+	ret = tc6393xb_register_gpio(tc6393xb);
+	if (ret)
+		goto err_gpio_add;
 
 	tc6393xb_attach_irq(dev);
 
-	if (tcpd->setup) {
-		ret = tcpd->setup(dev);
-		if (ret)
-			goto err_setup;
-	}
-
 	tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
 	tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
 						sizeof(*tcpd->nand_data);
@@ -705,15 +776,8 @@ static int tc6393xb_probe(struct platform_device *dev)
 	if (!ret)
 		return 0;
 
-	if (tcpd->teardown)
-		tcpd->teardown(dev);
-
-err_setup:
 	tc6393xb_detach_irq(dev);
-
 err_gpio_add:
-	if (tc6393xb->gpio.base != -1)
-		gpiochip_remove(&tc6393xb->gpio);
 	tcpd->disable(dev);
 err_enable:
 	clk_disable_unprepare(tc6393xb->clk);
@@ -738,14 +802,8 @@ static int tc6393xb_remove(struct platform_device *dev)
 
 	mfd_remove_devices(&dev->dev);
 
-	if (tcpd->teardown)
-		tcpd->teardown(dev);
-
 	tc6393xb_detach_irq(dev);
 
-	if (tc6393xb->gpio.base != -1)
-		gpiochip_remove(&tc6393xb->gpio);
-
 	ret = tcpd->disable(dev);
 	clk_disable_unprepare(tc6393xb->clk);
 	iounmap(tc6393xb->scr);
diff --git a/drivers/power/supply/tosa_battery.c b/drivers/power/supply/tosa_battery.c
index 32cc31cd4761..272d3ee44769 100644
--- a/drivers/power/supply/tosa_battery.c
+++ b/drivers/power/supply/tosa_battery.c
@@ -12,7 +12,7 @@
 #include <linux/delay.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach-types.h>
 #include <mach/tosa.h>
@@ -28,22 +28,23 @@ struct tosa_bat {
 	struct mutex work_lock; /* protects data */
 
 	bool (*is_present)(struct tosa_bat *bat);
-	int gpio_full;
-	int gpio_charge_off;
+	struct gpio_desc *gpiod_full;
+	struct gpio_desc *gpiod_charge_off;
 
 	int technology;
 
-	int gpio_bat;
+	struct gpio_desc *gpiod_bat;
 	int adc_bat;
 	int adc_bat_divider;
 	int bat_max;
 	int bat_min;
 
-	int gpio_temp;
+	struct gpio_desc *gpiod_temp;
 	int adc_temp;
 	int adc_temp_divider;
 };
 
+static struct gpio_desc *jacket_detect;
 static struct tosa_bat tosa_bat_main;
 static struct tosa_bat tosa_bat_jacket;
 
@@ -51,15 +52,15 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat)
 {
 	unsigned long value = 0;
 
-	if (bat->gpio_bat < 0 || bat->adc_bat < 0)
+	if (!bat->gpiod_bat || bat->adc_bat < 0)
 		return 0;
 
 	mutex_lock(&bat_lock);
-	gpio_set_value(bat->gpio_bat, 1);
+	gpiod_set_value(bat->gpiod_bat, 1);
 	msleep(5);
 	value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent),
 			bat->adc_bat);
-	gpio_set_value(bat->gpio_bat, 0);
+	gpiod_set_value(bat->gpiod_bat, 0);
 	mutex_unlock(&bat_lock);
 
 	value = value * 1000000 / bat->adc_bat_divider;
@@ -71,15 +72,15 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat)
 {
 	unsigned long value = 0;
 
-	if (bat->gpio_temp < 0 || bat->adc_temp < 0)
+	if (!bat->gpiod_temp || bat->adc_temp < 0)
 		return 0;
 
 	mutex_lock(&bat_lock);
-	gpio_set_value(bat->gpio_temp, 1);
+	gpiod_set_value(bat->gpiod_temp, 1);
 	msleep(5);
 	value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent),
 			bat->adc_temp);
-	gpio_set_value(bat->gpio_temp, 0);
+	gpiod_set_value(bat->gpiod_temp, 0);
 	mutex_unlock(&bat_lock);
 
 	value = value * 10000 / bat->adc_temp_divider;
@@ -136,7 +137,7 @@ static int tosa_bat_get_property(struct power_supply *psy,
 
 static bool tosa_jacket_bat_is_present(struct tosa_bat *bat)
 {
-	return gpio_get_value(TOSA_GPIO_JACKET_DETECT) == 0;
+	return gpiod_get_value(jacket_detect) == 0;
 }
 
 static void tosa_bat_external_power_changed(struct power_supply *psy)
@@ -166,23 +167,23 @@ static void tosa_bat_update(struct tosa_bat *bat)
 		bat->full_chrg = -1;
 	} else if (power_supply_am_i_supplied(psy)) {
 		if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) {
-			gpio_set_value(bat->gpio_charge_off, 0);
+			gpiod_set_value(bat->gpiod_charge_off, 0);
 			mdelay(15);
 		}
 
-		if (gpio_get_value(bat->gpio_full)) {
+		if (gpiod_get_value(bat->gpiod_full)) {
 			if (old == POWER_SUPPLY_STATUS_CHARGING ||
 					bat->full_chrg == -1)
 				bat->full_chrg = tosa_read_bat(bat);
 
-			gpio_set_value(bat->gpio_charge_off, 1);
+			gpiod_set_value(bat->gpiod_charge_off, 1);
 			bat->status = POWER_SUPPLY_STATUS_FULL;
 		} else {
-			gpio_set_value(bat->gpio_charge_off, 0);
+			gpiod_set_value(bat->gpiod_charge_off, 0);
 			bat->status = POWER_SUPPLY_STATUS_CHARGING;
 		}
 	} else {
-		gpio_set_value(bat->gpio_charge_off, 1);
+		gpiod_set_value(bat->gpiod_charge_off, 1);
 		bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
 	}
 
@@ -251,18 +252,18 @@ static struct tosa_bat tosa_bat_main = {
 	.full_chrg = -1,
 	.psy = NULL,
 
-	.gpio_full = TOSA_GPIO_BAT0_CRG,
-	.gpio_charge_off = TOSA_GPIO_CHARGE_OFF,
+	.gpiod_full = NULL,
+	.gpiod_charge_off = NULL,
 
 	.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
 
-	.gpio_bat = TOSA_GPIO_BAT0_V_ON,
+	.gpiod_bat = NULL,
 	.adc_bat = WM97XX_AUX_ID3,
 	.adc_bat_divider = 414,
 	.bat_max = 4310000,
 	.bat_min = 1551 * 1000000 / 414,
 
-	.gpio_temp = TOSA_GPIO_BAT1_TH_ON,
+	.gpiod_temp = NULL,
 	.adc_temp = WM97XX_AUX_ID2,
 	.adc_temp_divider = 10000,
 };
@@ -273,18 +274,18 @@ static struct tosa_bat tosa_bat_jacket = {
 	.psy = NULL,
 
 	.is_present = tosa_jacket_bat_is_present,
-	.gpio_full = TOSA_GPIO_BAT1_CRG,
-	.gpio_charge_off = TOSA_GPIO_CHARGE_OFF_JC,
+	.gpiod_full = NULL,
+	.gpiod_charge_off = NULL,
 
 	.technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
 
-	.gpio_bat = TOSA_GPIO_BAT1_V_ON,
+	.gpiod_bat = NULL,
 	.adc_bat = WM97XX_AUX_ID3,
 	.adc_bat_divider = 414,
 	.bat_max = 4310000,
 	.bat_min = 1551 * 1000000 / 414,
 
-	.gpio_temp = TOSA_GPIO_BAT0_TH_ON,
+	.gpiod_temp = NULL,
 	.adc_temp = WM97XX_AUX_ID2,
 	.adc_temp_divider = 10000,
 };
@@ -294,36 +295,20 @@ static struct tosa_bat tosa_bat_bu = {
 	.full_chrg = -1,
 	.psy = NULL,
 
-	.gpio_full = -1,
-	.gpio_charge_off = -1,
+	.gpiod_full = NULL,
+	.gpiod_charge_off = NULL,
 
 	.technology = POWER_SUPPLY_TECHNOLOGY_LiMn,
 
-	.gpio_bat = TOSA_GPIO_BU_CHRG_ON,
+	.gpiod_bat = NULL,
 	.adc_bat = WM97XX_AUX_ID4,
 	.adc_bat_divider = 1266,
 
-	.gpio_temp = -1,
+	.gpiod_temp = NULL,
 	.adc_temp = -1,
 	.adc_temp_divider = -1,
 };
 
-static struct gpio tosa_bat_gpios[] = {
-	{ TOSA_GPIO_CHARGE_OFF,	   GPIOF_OUT_INIT_HIGH, "main charge off" },
-	{ TOSA_GPIO_CHARGE_OFF_JC, GPIOF_OUT_INIT_HIGH, "jacket charge off" },
-	{ TOSA_GPIO_BAT_SW_ON,	   GPIOF_OUT_INIT_LOW,	"battery switch" },
-	{ TOSA_GPIO_BAT0_V_ON,	   GPIOF_OUT_INIT_LOW,	"main battery" },
-	{ TOSA_GPIO_BAT1_V_ON,	   GPIOF_OUT_INIT_LOW,	"jacket battery" },
-	{ TOSA_GPIO_BAT1_TH_ON,	   GPIOF_OUT_INIT_LOW,	"main battery temp" },
-	{ TOSA_GPIO_BAT0_TH_ON,	   GPIOF_OUT_INIT_LOW,	"jacket battery temp" },
-	{ TOSA_GPIO_BU_CHRG_ON,	   GPIOF_OUT_INIT_LOW,	"backup battery" },
-	{ TOSA_GPIO_BAT0_CRG,	   GPIOF_IN,		"main battery full" },
-	{ TOSA_GPIO_BAT1_CRG,	   GPIOF_IN,		"jacket battery full" },
-	{ TOSA_GPIO_BAT0_LOW,	   GPIOF_IN,		"main battery low" },
-	{ TOSA_GPIO_BAT1_LOW,	   GPIOF_IN,		"jacket battery low" },
-	{ TOSA_GPIO_JACKET_DETECT, GPIOF_IN,		"jacket detect" },
-};
-
 #ifdef CONFIG_PM
 static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state)
 {
@@ -343,19 +328,83 @@ static int tosa_bat_resume(struct platform_device *dev)
 #define tosa_bat_resume NULL
 #endif
 
-static int tosa_bat_probe(struct platform_device *dev)
+static int tosa_bat_probe(struct platform_device *pdev)
 {
 	int ret;
 	struct power_supply_config main_psy_cfg = {},
 				   jacket_psy_cfg = {},
 				   bu_psy_cfg = {};
+	struct device *dev = &pdev->dev;
+	struct gpio_desc *dummy;
 
 	if (!machine_is_tosa())
 		return -ENODEV;
 
-	ret = gpio_request_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
-	if (ret)
-		return ret;
+	/* Main charging control GPIOs */
+	tosa_bat_main.gpiod_charge_off = devm_gpiod_get(dev, "main charge off", GPIOD_OUT_HIGH);
+	if (IS_ERR(tosa_bat_main.gpiod_charge_off))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_charge_off),
+				     "no main charger GPIO\n");
+	tosa_bat_jacket.gpiod_charge_off = devm_gpiod_get(dev, "jacket charge off", GPIOD_OUT_HIGH);
+	if (IS_ERR(tosa_bat_jacket.gpiod_charge_off))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_charge_off),
+				     "no jacket charger GPIO\n");
+
+	/* Per-battery output check (routes battery voltage to ADC) */
+	tosa_bat_main.gpiod_bat = devm_gpiod_get(dev, "main battery", GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_bat_main.gpiod_bat))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_bat),
+				     "no main battery GPIO\n");
+	tosa_bat_jacket.gpiod_bat = devm_gpiod_get(dev, "jacket battery", GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_bat_jacket.gpiod_bat))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_bat),
+				     "no jacket battery GPIO\n");
+	tosa_bat_bu.gpiod_bat = devm_gpiod_get(dev, "backup battery", GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_bat_bu.gpiod_bat))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_bu.gpiod_bat),
+				     "no backup battery GPIO\n");
+
+	/* Battery full detect GPIOs (using PXA SoC GPIOs) */
+	tosa_bat_main.gpiod_full = devm_gpiod_get(dev, "main battery full", GPIOD_IN);
+	if (IS_ERR(tosa_bat_main.gpiod_full))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_full),
+				     "no main battery full GPIO\n");
+	tosa_bat_jacket.gpiod_full = devm_gpiod_get(dev, "jacket battery full", GPIOD_IN);
+	if (IS_ERR(tosa_bat_jacket.gpiod_full))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_full),
+				     "no jacket battery full GPIO\n");
+
+	/* Battery temperature GPIOs (routes thermistor voltage to ADC) */
+	tosa_bat_main.gpiod_temp = devm_gpiod_get(dev, "main battery temp", GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_bat_main.gpiod_temp))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_temp),
+				     "no main battery temp GPIO\n");
+	tosa_bat_jacket.gpiod_temp = devm_gpiod_get(dev, "jacket battery temp", GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_bat_jacket.gpiod_temp))
+		return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_temp),
+				     "no jacket battery temp GPIO\n");
+
+	/* Jacket detect GPIO */
+	jacket_detect = devm_gpiod_get(dev, "jacket detect", GPIOD_IN);
+	if (IS_ERR(jacket_detect))
+		return dev_err_probe(dev, PTR_ERR(jacket_detect),
+				     "no jacket detect GPIO\n");
+
+	/* Battery low indication GPIOs (not used, we just request them) */
+	dummy = devm_gpiod_get(dev, "main battery low", GPIOD_IN);
+	if (IS_ERR(dummy))
+		return dev_err_probe(dev, PTR_ERR(dummy),
+				     "no main battery low GPIO\n");
+	dummy = devm_gpiod_get(dev, "jacket battery low", GPIOD_IN);
+	if (IS_ERR(dummy))
+		return dev_err_probe(dev, PTR_ERR(dummy),
+				     "no jacket battery low GPIO\n");
+
+	/* Battery switch GPIO (not used just requested) */
+	dummy = devm_gpiod_get(dev, "battery switch", GPIOD_OUT_LOW);
+	if (IS_ERR(dummy))
+		return dev_err_probe(dev, PTR_ERR(dummy),
+				     "no battery switch GPIO\n");
 
 	mutex_init(&tosa_bat_main.work_lock);
 	mutex_init(&tosa_bat_jacket.work_lock);
@@ -363,7 +412,7 @@ static int tosa_bat_probe(struct platform_device *dev)
 	INIT_WORK(&bat_work, tosa_bat_work);
 
 	main_psy_cfg.drv_data = &tosa_bat_main;
-	tosa_bat_main.psy = power_supply_register(&dev->dev,
+	tosa_bat_main.psy = power_supply_register(dev,
 						  &tosa_bat_main_desc,
 						  &main_psy_cfg);
 	if (IS_ERR(tosa_bat_main.psy)) {
@@ -372,7 +421,7 @@ static int tosa_bat_probe(struct platform_device *dev)
 	}
 
 	jacket_psy_cfg.drv_data = &tosa_bat_jacket;
-	tosa_bat_jacket.psy = power_supply_register(&dev->dev,
+	tosa_bat_jacket.psy = power_supply_register(dev,
 						    &tosa_bat_jacket_desc,
 						    &jacket_psy_cfg);
 	if (IS_ERR(tosa_bat_jacket.psy)) {
@@ -381,28 +430,28 @@ static int tosa_bat_probe(struct platform_device *dev)
 	}
 
 	bu_psy_cfg.drv_data = &tosa_bat_bu;
-	tosa_bat_bu.psy = power_supply_register(&dev->dev, &tosa_bat_bu_desc,
+	tosa_bat_bu.psy = power_supply_register(dev, &tosa_bat_bu_desc,
 						&bu_psy_cfg);
 	if (IS_ERR(tosa_bat_bu.psy)) {
 		ret = PTR_ERR(tosa_bat_bu.psy);
 		goto err_psy_reg_bu;
 	}
 
-	ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG),
+	ret = request_irq(gpiod_to_irq(tosa_bat_main.gpiod_full),
 				tosa_bat_gpio_isr,
 				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				"main full", &tosa_bat_main);
 	if (ret)
 		goto err_req_main;
 
-	ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG),
+	ret = request_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full),
 				tosa_bat_gpio_isr,
 				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				"jacket full", &tosa_bat_jacket);
 	if (ret)
 		goto err_req_jacket;
 
-	ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT),
+	ret = request_irq(gpiod_to_irq(jacket_detect),
 				tosa_bat_gpio_isr,
 				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				"jacket detect", &tosa_bat_jacket);
@@ -411,9 +460,9 @@ static int tosa_bat_probe(struct platform_device *dev)
 		return 0;
 	}
 
-	free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
+	free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket);
 err_req_jacket:
-	free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
+	free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main);
 err_req_main:
 	power_supply_unregister(tosa_bat_bu.psy);
 err_psy_reg_bu:
@@ -425,15 +474,14 @@ static int tosa_bat_probe(struct platform_device *dev)
 	/* see comment in tosa_bat_remove */
 	cancel_work_sync(&bat_work);
 
-	gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
 	return ret;
 }
 
 static int tosa_bat_remove(struct platform_device *dev)
 {
-	free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
-	free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
-	free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
+	free_irq(gpiod_to_irq(jacket_detect), &tosa_bat_jacket);
+	free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket);
+	free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main);
 
 	power_supply_unregister(tosa_bat_bu.psy);
 	power_supply_unregister(tosa_bat_jacket.psy);
@@ -445,7 +493,6 @@ static int tosa_bat_remove(struct platform_device *dev)
 	 * unregistered now.
 	 */
 	cancel_work_sync(&bat_work);
-	gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
 	return 0;
 }
 
diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
index 2647dd10b541..4d55da28e664 100644
--- a/include/linux/gpio/machine.h
+++ b/include/linux/gpio/machine.h
@@ -63,6 +63,18 @@ struct gpiod_hog {
 	int dflags;
 };
 
+/*
+ * Helper for lookup tables with just one single lookup for a device.
+ */
+#define GPIO_LOOKUP_SINGLE(_name, _dev_id, _key, _chip_hwnum, _con_id, _flags) \
+static struct gpiod_lookup_table _name = {				\
+	.dev_id = _dev_id,						\
+	.table = {							\
+		GPIO_LOOKUP(_key, _chip_hwnum, _con_id, _flags),	\
+		{},							\
+	},								\
+}
+
 /*
  * Simple definition of a single GPIO under a con_id
  */
diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
index fcc8e74f0e8d..d336c541b7df 100644
--- a/include/linux/mfd/tc6393xb.h
+++ b/include/linux/mfd/tc6393xb.h
@@ -27,9 +27,6 @@ struct tc6393xb_platform_data {
 	int	(*resume)(struct platform_device *dev);
 
 	int	irq_base;	/* base for subdevice irqs */
-	int	gpio_base;
-	int	(*setup)(struct platform_device *dev);
-	void	(*teardown)(struct platform_device *dev);
 
 	struct tmio_nand_data	*nand_data;
 	struct tmio_fb_data	*fb_data;
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 3b40b5fa5de7..c2b05896e284 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -33,6 +33,7 @@
 #define TOSA_SPK_ON    0
 #define TOSA_SPK_OFF   1
 
+static struct gpio_desc *tosa_mute;
 static int tosa_jack_func;
 static int tosa_spk_func;
 
@@ -128,7 +129,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
 static int tosa_hp_event(struct snd_soc_dapm_widget *w,
 	struct snd_kcontrol *k, int event)
 {
-	gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
+	gpiod_set_value(tosa_mute, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
 	return 0;
 }
 
@@ -222,8 +223,11 @@ static int tosa_probe(struct platform_device *pdev)
 	struct snd_soc_card *card = &tosa;
 	int ret;
 
-	ret = gpio_request_one(TOSA_GPIO_L_MUTE, GPIOF_OUT_INIT_LOW,
-			       "Headphone Jack");
+	tosa_mute = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
+	if (IS_ERR(tosa_mute))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tosa_mute),
+				     "failed to get L_MUTE GPIO\n");
+	gpiod_set_consumer_name(tosa_mute, "Headphone Jack");
 	if (ret)
 		return ret;
 
@@ -233,24 +237,16 @@ static int tosa_probe(struct platform_device *pdev)
 	if (ret) {
 		dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
 			ret);
-		gpio_free(TOSA_GPIO_L_MUTE);
 	}
 	return ret;
 }
 
-static int tosa_remove(struct platform_device *pdev)
-{
-	gpio_free(TOSA_GPIO_L_MUTE);
-	return 0;
-}
-
 static struct platform_driver tosa_driver = {
 	.driver		= {
 		.name	= "tosa-audio",
 		.pm     = &snd_soc_pm_ops,
 	},
 	.probe		= tosa_probe,
-	.remove		= tosa_remove,
 };
 
 module_platform_driver(tosa_driver);
-- 
2.34.1



From sboyd at kernel.org  Mon Jan 24 16:56:05 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 16:56:05 -0800
Subject: [PATCH] clk: mediatek: add unregister logic to
 mtk_clk_simple_probe error path
In-Reply-To: <20220124052038.6242-1-miles.chen@mediatek.com>
References: <20220117090030.13064-1-miles.chen@mediatek.com>
 <20220124052038.6242-1-miles.chen@mediatek.com>
Message-ID: <20220125005607.5BFBAC340E4@smtp.kernel.org>

Quoting Miles Chen (2022-01-23 21:20:38)
> Hi Stephen,
> 
> > Stephen pointed out that there is no unregister logic in
> > mtk_clk_simple_probe() error path [1].
> > Fix it by adding unregister logic to mtk_clk_simple_probe().
> 
> Chen-Yu's work [1] already addresses this problem. So please ignore
> this patch.

Alright. Thanks.


From pcc at google.com  Mon Jan 24 16:58:50 2022
From: pcc at google.com (Peter Collingbourne)
Date: Mon, 24 Jan 2022 16:58:50 -0800
Subject: [PATCH v4] arm64: mte: avoid clearing PSTATE.TCO on entry unless
 necessary
Message-ID: <20220125005850.2500784-1-pcc@google.com>

On some microarchitectures, clearing PSTATE.TCO is expensive. Clearing
TCO is only necessary if in-kernel MTE is enabled, or if MTE is
enabled in the userspace process in synchronous (or, soon, asymmetric)
mode, because we do not report uaccess faults to userspace in none
or asynchronous modes. Therefore, adjust the kernel entry code to
clear TCO only if necessary.

Because it is now possible to switch to a task in which TCO needs to
be clear from a task in which TCO is set, we also need to do the same
thing on task switch.

Signed-off-by: Peter Collingbourne <pcc at google.com>
Link: https://linux-review.googlesource.com/id/I52d82a580bd0500d420be501af2c35fa8c90729e
Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
---
v4:
- some changes suggested by Catalin

v3:
- switch to a C implementation

v2:
- do the same thing in cpu_switch_to()

 arch/arm64/include/asm/mte.h     | 22 ++++++++++++++++++++++
 arch/arm64/kernel/entry-common.c |  3 +++
 arch/arm64/kernel/entry.S        |  7 -------
 arch/arm64/kernel/mte.c          |  3 +++
 4 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
index 075539f5f1c8..808349363625 100644
--- a/arch/arm64/include/asm/mte.h
+++ b/arch/arm64/include/asm/mte.h
@@ -11,7 +11,9 @@
 #ifndef __ASSEMBLY__
 
 #include <linux/bitfield.h>
+#include <linux/kasan.h>
 #include <linux/page-flags.h>
+#include <linux/sched.h>
 #include <linux/types.h>
 
 #include <asm/pgtable-types.h>
@@ -86,6 +88,26 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
 
 #endif /* CONFIG_ARM64_MTE */
 
+static inline void mte_disable_tco_entry(struct task_struct *task)
+{
+	if (!system_supports_mte())
+		return;
+
+	/*
+	 * Re-enable tag checking (TCO set on exception entry). This is only
+	 * necessary if MTE is enabled in either the kernel or the userspace
+	 * task in synchronous or asymmetric mode (SCTLR_EL1.TCF0 bit 0 is set
+	 * for both). With MTE disabled in the kernel and disabled or
+	 * asynchronous in userspace, tag check faults (including in uaccesses)
+	 * are not reported, therefore there is no need to re-enable checking.
+	 * This is beneficial on microarchitectures where re-enabling TCO is
+	 * expensive.
+	 */
+	if (kasan_hw_tags_enabled() ||
+	    (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT)))
+		asm volatile(SET_PSTATE_TCO(0));
+}
+
 #ifdef CONFIG_KASAN_HW_TAGS
 /* Whether the MTE asynchronous mode is enabled. */
 DECLARE_STATIC_KEY_FALSE(mte_async_or_asymm_mode);
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..7093b578e325 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/context_tracking.h>
+#include <linux/kasan.h>
 #include <linux/linkage.h>
 #include <linux/lockdep.h>
 #include <linux/ptrace.h>
@@ -56,6 +57,7 @@ static void noinstr enter_from_kernel_mode(struct pt_regs *regs)
 {
 	__enter_from_kernel_mode(regs);
 	mte_check_tfsr_entry();
+	mte_disable_tco_entry(current);
 }
 
 /*
@@ -103,6 +105,7 @@ static __always_inline void __enter_from_user_mode(void)
 	CT_WARN_ON(ct_state() != CONTEXT_USER);
 	user_exit_irqoff();
 	trace_hardirqs_off_finish();
+	mte_disable_tco_entry(current);
 }
 
 static __always_inline void enter_from_user_mode(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 772ec2ecf488..e1013a83d4f0 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -308,13 +308,6 @@ alternative_if ARM64_HAS_IRQ_PRIO_MASKING
 	msr_s	SYS_ICC_PMR_EL1, x20
 alternative_else_nop_endif
 
-	/* Re-enable tag checking (TCO set on exception entry) */
-#ifdef CONFIG_ARM64_MTE
-alternative_if ARM64_MTE
-	SET_PSTATE_TCO(0)
-alternative_else_nop_endif
-#endif
-
 	/*
 	 * Registers that may be useful after this macro is invoked:
 	 *
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index f418ebc65f95..f983795b5eda 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -253,6 +253,9 @@ void mte_thread_switch(struct task_struct *next)
 	mte_update_sctlr_user(next);
 	mte_update_gcr_excl(next);
 
+	/* TCO may not have been disabled on exception entry for the current task. */
+	mte_disable_tco_entry(next);
+
 	/*
 	 * Check if an async tag exception occurred at EL1.
 	 *
-- 
2.35.0.rc0.227.g00780c9af4-goog



From pcc at google.com  Mon Jan 24 16:59:03 2022
From: pcc at google.com (Peter Collingbourne)
Date: Mon, 24 Jan 2022 16:59:03 -0800
Subject: [PATCH v3] arm64: mte: avoid clearing PSTATE.TCO on entry unless
 necessary
In-Reply-To: <Ye6RSlb0LkegxSKa@arm.com>
References: <20220122010250.251885-1-pcc@google.com> <Ye6RSlb0LkegxSKa@arm.com>
Message-ID: <CAMn1gO7yY0qM3Bba_v-GOOe0GnryZq9s1jxe75yebu1Pa2cKpQ@mail.gmail.com>

On Mon, Jan 24, 2022 at 3:45 AM Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> On Fri, Jan 21, 2022 at 05:02:50PM -0800, Peter Collingbourne wrote:
> > diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h
> > index 075539f5f1c8..5352db4c0f45 100644
> > --- a/arch/arm64/include/asm/mte.h
> > +++ b/arch/arm64/include/asm/mte.h
> > @@ -11,7 +11,9 @@
> >  #ifndef __ASSEMBLY__
> >
> >  #include <linux/bitfield.h>
> > +#include <linux/kasan.h>
> >  #include <linux/page-flags.h>
> > +#include <linux/sched.h>
> >  #include <linux/types.h>
> >
> >  #include <asm/pgtable-types.h>
> > @@ -86,6 +88,23 @@ static inline int mte_ptrace_copy_tags(struct task_struct *child,
> >
> >  #endif /* CONFIG_ARM64_MTE */
> >
> > +static inline void mte_disable_tco_entry(struct task_struct *task)
> > +{
> > +     /*
> > +      * Re-enable tag checking (TCO set on exception entry). This is only
> > +      * necessary if MTE is enabled in either the kernel or the userspace
> > +      * task in synchronous mode. With MTE disabled in the kernel and
> > +      * disabled or asynchronous in userspace, tag check faults (including in
> > +      * uaccesses) are not reported, therefore there is no need to re-enable
> > +      * checking. This is beneficial on microarchitectures where re-enabling
> > +      * TCO is expensive.
> > +      */
>
> I'd add a note here that the 1ULL << SCTLR_EL1_TCF0_SHIFT is meant to
> check for both synchronous and asymmetric modes even if we don't have
> the latter supporting the user yet. We do have the definitions already.

Done in v4.

> > +     if (kasan_hw_tags_enabled() ||
> > +         (system_supports_mte() &&
> > +          (task->thread.sctlr_user & (1UL << SCTLR_EL1_TCF0_SHIFT))))
> > +             asm volatile(SET_PSTATE_TCO(0));
> > +}
>
> Does it make a difference in code generation if you place a:
>
>         if (!system_supports_mte())
>                 return;
>
> at the beginning of the function (and remove the subsequent check)? It's
> probably also easier to read, though the code generation depends on the
> likely/unlikely choices for the static branches involved.

Yes and this ends up making the patch cause a small speedup on the
DragonBoard: 245.1ns to 244.5ns on the small cores and 151.4ns to
148.4ns on the large cores. The numbers on the MTE-enabled hardware
don't change too much.

> > diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> > index f418ebc65f95..5345587f3384 100644
> > --- a/arch/arm64/kernel/mte.c
> > +++ b/arch/arm64/kernel/mte.c
> > @@ -252,6 +252,7 @@ void mte_thread_switch(struct task_struct *next)
> >
> >       mte_update_sctlr_user(next);
> >       mte_update_gcr_excl(next);
> > +     mte_disable_tco_entry(next);
>
> Maybe a one-line comment here that TCO may not have been disabled on
> exception entry for the current task.

Done in v4.

> Otherwise it looks good to me:
>
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>

Thanks.

Peter


From linus.walleij at linaro.org  Mon Jan 24 16:58:36 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Tue, 25 Jan 2022 01:58:36 +0100
Subject: [PATCH v2] spi: pxa2xx_spi: Convert to use GPIO descriptors
Message-ID: <20220125005836.494807-1-linus.walleij@linaro.org>

This converts the PXA2xx SPI driver to use GPIO descriptors
exclusively to retrieve GPIO chip select lines.

The device tree and ACPI paths of the driver already use
descriptors, hence ->use_gpio_descriptors is already set and
this codepath is well tested.

Convert all the PXA boards providing chip select GPIOs as
platform data and drop the old GPIO chipselect handling in
favor of the core managing it exclusively.

Cc: Marek Vasut <marek.vasut at gmail.com>
Cc: Daniel Mack <daniel at zonque.org>
Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
Cc: Robert Jarzmik <robert.jarzmik at free.fr>
Cc: linux-arm-kernel at lists.infradead.org
Acked-by: Jonathan Cameron <Jonathan.Cameron at huawei.com>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v1->v2:
- Drop a dangling err variable and some code which is now
  unused as we don't set up the GPIO lines in the driver
  anymore. (Found by the kernel test robot.)
- Drop excess newline.
- Collect Jonathan's ACK.
---
 Documentation/spi/pxa2xx.rst   |  3 --
 arch/arm/mach-pxa/corgi.c      | 26 ++++++--------
 arch/arm/mach-pxa/hx4700.c     | 10 +++++-
 arch/arm/mach-pxa/icontrol.c   | 26 +++++++++++---
 arch/arm/mach-pxa/littleton.c  | 10 +++++-
 arch/arm/mach-pxa/magician.c   | 12 +++++--
 arch/arm/mach-pxa/poodle.c     | 14 +++++---
 arch/arm/mach-pxa/spitz.c      | 26 ++++++--------
 arch/arm/mach-pxa/stargate2.c  | 20 +++++++++--
 arch/arm/mach-pxa/z2.c         | 20 +++++++++--
 drivers/spi/spi-pxa2xx.c       | 63 +---------------------------------
 include/linux/spi/pxa2xx_spi.h |  1 -
 12 files changed, 117 insertions(+), 114 deletions(-)

diff --git a/Documentation/spi/pxa2xx.rst b/Documentation/spi/pxa2xx.rst
index 6347580826be..716f65d87d04 100644
--- a/Documentation/spi/pxa2xx.rst
+++ b/Documentation/spi/pxa2xx.rst
@@ -101,7 +101,6 @@ device. All fields are optional.
 	u8 rx_threshold;
 	u8 dma_burst_size;
 	u32 timeout;
-	int gpio_cs;
   };
 
 The "pxa2xx_spi_chip.tx_threshold" and "pxa2xx_spi_chip.rx_threshold" fields are
@@ -146,7 +145,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
 	.rx_threshold = 8, /* SSP hardward FIFO threshold */
 	.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
 	.timeout = 235, /* See Intel documentation */
-	.gpio_cs = 2, /* Use external chip select */
   };
 
   static struct pxa2xx_spi_chip cs8405a_chip_info = {
@@ -154,7 +152,6 @@ field. Below is a sample configuration using the PXA255 NSSP.
 	.rx_threshold = 8, /* SSP hardward FIFO threshold */
 	.dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
 	.timeout = 235, /* See Intel documentation */
-	.gpio_cs = 3, /* Use external chip select */
   };
 
   static struct spi_board_info streetracer_spi_board_info[] __initdata = {
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 593c7f793da5..44659fbc37ba 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -530,6 +530,16 @@ static struct pxa2xx_spi_controller corgi_spi_info = {
 	.num_chipselect	= 3,
 };
 
+static struct gpiod_lookup_table corgi_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", CORGI_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void corgi_wait_for_hsync(void)
 {
 	while (gpio_get_value(CORGI_GPIO_HSYNC))
@@ -548,10 +558,6 @@ static struct ads7846_platform_data corgi_ads7846_info = {
 	.wait_for_sync		= corgi_wait_for_hsync,
 };
 
-static struct pxa2xx_spi_chip corgi_ads7846_chip = {
-	.gpio_cs	= CORGI_GPIO_ADS7846_CS,
-};
-
 static void corgi_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -580,14 +586,6 @@ static struct corgi_lcd_platform_data corgi_lcdcon_info = {
 	.kick_battery		= corgi_bl_kick_battery,
 };
 
-static struct pxa2xx_spi_chip corgi_lcdcon_chip = {
-	.gpio_cs	= CORGI_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip corgi_max1111_chip = {
-	.gpio_cs	= CORGI_GPIO_MAX1111_CS,
-};
-
 static struct spi_board_info corgi_spi_devices[] = {
 	{
 		.modalias	= "ads7846",
@@ -595,7 +593,6 @@ static struct spi_board_info corgi_spi_devices[] = {
 		.bus_num	= 1,
 		.chip_select	= 0,
 		.platform_data	= &corgi_ads7846_info,
-		.controller_data= &corgi_ads7846_chip,
 		.irq		= PXA_GPIO_TO_IRQ(CORGI_GPIO_TP_INT),
 	}, {
 		.modalias	= "corgi-lcd",
@@ -603,18 +600,17 @@ static struct spi_board_info corgi_spi_devices[] = {
 		.bus_num	= 1,
 		.chip_select	= 1,
 		.platform_data	= &corgi_lcdcon_info,
-		.controller_data= &corgi_lcdcon_chip,
 	}, {
 		.modalias	= "max1111",
 		.max_speed_hz	= 450000,
 		.bus_num	= 1,
 		.chip_select	= 2,
-		.controller_data= &corgi_max1111_chip,
 	},
 };
 
 static void __init corgi_init_spi(void)
 {
+	gpiod_add_lookup_table(&corgi_spi_gpio_table);
 	pxa2xx_set_spi_info(1, &corgi_spi_info);
 	gpiod_add_lookup_table(&corgi_lcdcon_gpio_table);
 	spi_register_board_info(ARRAY_AND_SIZE(corgi_spi_devices));
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index 1d4c5db54be2..e1870fbb19e7 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -616,7 +616,6 @@ static struct pxa2xx_spi_chip tsc2046_chip = {
 	.tx_threshold = 1,
 	.rx_threshold = 2,
 	.timeout      = 64,
-	.gpio_cs      = GPIO88_HX4700_TSC2046_CS,
 };
 
 static struct spi_board_info tsc2046_board_info[] __initdata = {
@@ -635,6 +634,14 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
 	.enable_dma     = 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_HX4700_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /*
  * External power
  */
@@ -896,6 +903,7 @@ static void __init hx4700_init(void)
 	pxa_set_i2c_info(NULL);
 	i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
 	i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
+	gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
 	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
 	spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
 
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c
index 04a12523cdee..753fe166ab68 100644
--- a/arch/arm/mach-pxa/icontrol.c
+++ b/arch/arm/mach-pxa/icontrol.c
@@ -13,7 +13,7 @@
 #include <linux/irq.h>
 #include <linux/platform_device.h>
 #include <linux/property.h>
-#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -42,7 +42,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS1
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
@@ -50,7 +49,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS2
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
@@ -58,7 +56,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS3
 };
 
 static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
@@ -66,7 +63,6 @@ static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
 	.rx_threshold   = 128,
 	.dma_burst_size = 8,
 	.timeout        = 235,
-	.gpio_cs        = ICONTROL_MCP251x_nCS4
 };
 
 static const struct property_entry mcp251x_properties[] = {
@@ -143,6 +139,24 @@ struct platform_device pxa_spi_ssp4 = {
 	}
 };
 
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+	.dev_id = "pxa2xx-spi.3",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
+	.dev_id = "pxa2xx-spi.4",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct platform_device *icontrol_spi_devices[] __initdata = {
 	&pxa_spi_ssp3,
 	&pxa_spi_ssp4,
@@ -175,6 +189,8 @@ static mfp_cfg_t mfp_can_cfg[] __initdata = {
 static void __init icontrol_can_init(void)
 {
 	pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
+	gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
 	platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
 	spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
 }
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 793f61375ee8..73f5953b3bb6 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -195,7 +195,6 @@ static struct pxa2xx_spi_controller littleton_spi_info = {
 static struct pxa2xx_spi_chip littleton_tdo24m_chip = {
 	.rx_threshold	= 1,
 	.tx_threshold	= 1,
-	.gpio_cs	= LITTLETON_GPIO_LCD_CS,
 };
 
 static struct spi_board_info littleton_spi_devices[] __initdata = {
@@ -208,8 +207,17 @@ static struct spi_board_info littleton_spi_devices[] __initdata = {
 	},
 };
 
+static struct gpiod_lookup_table littleton_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", LITTLETON_GPIO_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init littleton_init_spi(void)
 {
+	gpiod_add_lookup_table(&littleton_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &littleton_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(littleton_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index cd9fa465b9b2..200fd35168e0 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -938,8 +938,6 @@ struct pxa2xx_spi_chip tsc2046_chip_info = {
 	.tx_threshold	= 1,
 	.rx_threshold	= 2,
 	.timeout	= 64,
-	/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
-	.gpio_cs	= GPIO14_MAGICIAN_TSC2046_CS,
 };
 
 static struct pxa2xx_spi_controller magician_spi_info = {
@@ -947,6 +945,15 @@ static struct pxa2xx_spi_controller magician_spi_info = {
 	.enable_dma	= 1,
 };
 
+static struct gpiod_lookup_table magician_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		/* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO14_MAGICIAN_TSC2046_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct spi_board_info ads7846_spi_board_info[] __initdata = {
 	{
 		.modalias		= "ads7846",
@@ -1031,6 +1038,7 @@ static void __init magician_init(void)
 	} else
 		pr_err("LCD detection: CPLD mapping failed\n");
 
+	gpiod_add_lookup_table(&magician_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &magician_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info));
 
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 3a4ecc3c8f8b..58cfa434afde 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -197,6 +197,14 @@ static struct pxa2xx_spi_controller poodle_spi_info = {
 	.num_chipselect	= 1,
 };
 
+static struct gpiod_lookup_table poodle_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", POODLE_GPIO_TP_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static struct ads7846_platform_data poodle_ads7846_info = {
 	.model			= 7846,
 	.vref_delay_usecs	= 100,
@@ -205,23 +213,19 @@ static struct ads7846_platform_data poodle_ads7846_info = {
 	.gpio_pendown		= POODLE_GPIO_TP_INT,
 };
 
-static struct pxa2xx_spi_chip poodle_ads7846_chip = {
-	.gpio_cs		= POODLE_GPIO_TP_CS,
-};
-
 static struct spi_board_info poodle_spi_devices[] = {
 	{
 		.modalias	= "ads7846",
 		.max_speed_hz	= 10000,
 		.bus_num	= 1,
 		.platform_data	= &poodle_ads7846_info,
-		.controller_data= &poodle_ads7846_chip,
 		.irq		= PXA_GPIO_TO_IRQ(POODLE_GPIO_TP_INT),
 	},
 };
 
 static void __init poodle_init_spi(void)
 {
+	gpiod_add_lookup_table(&poodle_spi_gpio_table);
 	pxa2xx_set_spi_info(1, &poodle_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(poodle_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 371008e9bb02..a648e7094e84 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -510,10 +510,6 @@ static struct ads7846_platform_data spitz_ads7846_info = {
 	.wait_for_sync		= spitz_ads7846_wait_for_hsync,
 };
 
-static struct pxa2xx_spi_chip spitz_ads7846_chip = {
-	.gpio_cs		= SPITZ_GPIO_ADS7846_CS,
-};
-
 static void spitz_bl_kick_battery(void)
 {
 	void (*kick_batt)(void);
@@ -555,14 +551,6 @@ static struct corgi_lcd_platform_data spitz_lcdcon_info = {
 	.kick_battery		= spitz_bl_kick_battery,
 };
 
-static struct pxa2xx_spi_chip spitz_lcdcon_chip = {
-	.gpio_cs	= SPITZ_GPIO_LCDCON_CS,
-};
-
-static struct pxa2xx_spi_chip spitz_max1111_chip = {
-	.gpio_cs	= SPITZ_GPIO_MAX1111_CS,
-};
-
 static struct spi_board_info spitz_spi_devices[] = {
 	{
 		.modalias		= "ads7846",
@@ -570,7 +558,6 @@ static struct spi_board_info spitz_spi_devices[] = {
 		.bus_num		= 2,
 		.chip_select		= 0,
 		.platform_data		= &spitz_ads7846_info,
-		.controller_data	= &spitz_ads7846_chip,
 		.irq			= PXA_GPIO_TO_IRQ(SPITZ_GPIO_TP_INT),
 	}, {
 		.modalias		= "corgi-lcd",
@@ -578,13 +565,11 @@ static struct spi_board_info spitz_spi_devices[] = {
 		.bus_num		= 2,
 		.chip_select		= 1,
 		.platform_data		= &spitz_lcdcon_info,
-		.controller_data	= &spitz_lcdcon_chip,
 	}, {
 		.modalias		= "max1111",
 		.max_speed_hz		= 450000,
 		.bus_num		= 2,
 		.chip_select		= 2,
-		.controller_data	= &spitz_max1111_chip,
 	},
 };
 
@@ -592,6 +577,16 @@ static struct pxa2xx_spi_controller spitz_spi_info = {
 	.num_chipselect	= 3,
 };
 
+static struct gpiod_lookup_table spitz_spi_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_ADS7846_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_LCDCON_CS, "cs", 1, GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP_IDX("gpio-pxa", SPITZ_GPIO_MAX1111_CS, "cs", 2, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init spitz_spi_init(void)
 {
 	if (machine_is_akita())
@@ -599,6 +594,7 @@ static void __init spitz_spi_init(void)
 	else
 		gpiod_add_lookup_table(&spitz_lcdcon_gpio_table);
 
+	gpiod_add_lookup_table(&spitz_spi_gpio_table);
 	pxa2xx_set_spi_info(2, &spitz_spi_info);
 	spi_register_board_info(ARRAY_AND_SIZE(spitz_spi_devices));
 }
diff --git a/arch/arm/mach-pxa/stargate2.c b/arch/arm/mach-pxa/stargate2.c
index 8ca02ec1d44c..b43e2f4536a5 100644
--- a/arch/arm/mach-pxa/stargate2.c
+++ b/arch/arm/mach-pxa/stargate2.c
@@ -346,6 +346,22 @@ static struct pxa2xx_spi_controller pxa_ssp_master_2_info = {
 	.num_chipselect = 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", 24, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
+	.dev_id = "pxa2xx-spi.3",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", 39, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 /* An upcoming kernel change will scrap SFRM usage so these
  * drivers have been moved to use GPIOs */
 static struct pxa2xx_spi_chip staccel_chip_info = {
@@ -353,7 +369,6 @@ static struct pxa2xx_spi_chip staccel_chip_info = {
 	.rx_threshold = 8,
 	.dma_burst_size = 8,
 	.timeout = 235,
-	.gpio_cs = 24,
 };
 
 static struct pxa2xx_spi_chip cc2420_info = {
@@ -361,7 +376,6 @@ static struct pxa2xx_spi_chip cc2420_info = {
 	.rx_threshold = 8,
 	.dma_burst_size = 8,
 	.timeout = 235,
-	.gpio_cs = 39,
 };
 
 static struct spi_board_info spi_board_info[] __initdata = {
@@ -410,6 +424,8 @@ static void __init imote2_stargate2_init(void)
 	pxa_set_btuart_info(NULL);
 	pxa_set_stuart_info(NULL);
 
+	gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
 	pxa2xx_set_spi_info(1, &pxa_ssp_master_0_info);
 	pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info);
 	pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info);
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index 8e74fbb0a96e..7eaeda269927 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -570,7 +570,6 @@ static struct pxa2xx_spi_chip z2_lbs_chip_info = {
 	.rx_threshold	= 8,
 	.tx_threshold	= 8,
 	.timeout	= 1000,
-	.gpio_cs	= GPIO24_ZIPITZ2_WIFI_CS,
 };
 
 static struct libertas_spi_platform_data z2_lbs_pdata = {
@@ -584,7 +583,6 @@ static struct pxa2xx_spi_chip lms283_chip_info = {
 	.rx_threshold	= 1,
 	.tx_threshold	= 1,
 	.timeout	= 64,
-	.gpio_cs	= GPIO88_ZIPITZ2_LCD_CS,
 };
 
 static struct gpiod_lookup_table lms283_gpio_table = {
@@ -624,8 +622,26 @@ static struct pxa2xx_spi_controller pxa_ssp2_master_info = {
 	.num_chipselect	= 1,
 };
 
+static struct gpiod_lookup_table pxa_ssp1_gpio_table = {
+	.dev_id = "pxa2xx-spi.1",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO24_ZIPITZ2_WIFI_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
+static struct gpiod_lookup_table pxa_ssp2_gpio_table = {
+	.dev_id = "pxa2xx-spi.2",
+	.table = {
+		GPIO_LOOKUP_IDX("gpio-pxa", GPIO88_ZIPITZ2_LCD_CS, "cs", 0, GPIO_ACTIVE_LOW),
+		{ },
+	},
+};
+
 static void __init z2_spi_init(void)
 {
+	gpiod_add_lookup_table(&pxa_ssp1_gpio_table);
+	gpiod_add_lookup_table(&pxa_ssp2_gpio_table);
 	pxa2xx_set_spi_info(1, &pxa_ssp1_master_info);
 	pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
 	gpiod_add_lookup_table(&lms283_gpio_table);
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index e88f86274eeb..abb9f0ffd377 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -13,7 +13,6 @@
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/gpio/consumer.h>
-#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
@@ -1163,57 +1162,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_controller *controller)
 	return 0;
 }
 
-static void cleanup_cs(struct spi_device *spi)
-{
-	if (!gpio_is_valid(spi->cs_gpio))
-		return;
-
-	gpio_free(spi->cs_gpio);
-	spi->cs_gpio = -ENOENT;
-}
-
-static int setup_cs(struct spi_device *spi, struct chip_data *chip,
-		    struct pxa2xx_spi_chip *chip_info)
-{
-	struct driver_data *drv_data = spi_controller_get_devdata(spi->controller);
-
-	if (chip == NULL)
-		return 0;
-
-	if (chip_info == NULL)
-		return 0;
-
-	if (drv_data->ssp_type == CE4100_SSP)
-		return 0;
-
-	/*
-	 * NOTE: setup() can be called multiple times, possibly with
-	 * different chip_info, release previously requested GPIO.
-	 */
-	cleanup_cs(spi);
-
-	if (gpio_is_valid(chip_info->gpio_cs)) {
-		int gpio = chip_info->gpio_cs;
-		int err;
-
-		err = gpio_request(gpio, "SPI_CS");
-		if (err) {
-			dev_err(&spi->dev, "failed to request chip select GPIO%d\n", gpio);
-			return err;
-		}
-
-		err = gpio_direction_output(gpio, !(spi->mode & SPI_CS_HIGH));
-		if (err) {
-			gpio_free(gpio);
-			return err;
-		}
-
-		spi->cs_gpio = gpio;
-	}
-
-	return 0;
-}
-
 static int setup(struct spi_device *spi)
 {
 	struct pxa2xx_spi_chip *chip_info;
@@ -1222,7 +1170,6 @@ static int setup(struct spi_device *spi)
 	struct driver_data *drv_data =
 		spi_controller_get_devdata(spi->controller);
 	uint tx_thres, tx_hi_thres, rx_thres;
-	int err;
 
 	switch (drv_data->ssp_type) {
 	case QUARK_X1000_SSP:
@@ -1365,21 +1312,13 @@ static int setup(struct spi_device *spi)
 
 	spi_set_ctldata(spi, chip);
 
-	if (drv_data->ssp_type == CE4100_SSP)
-		return 0;
-
-	err = setup_cs(spi, chip, chip_info);
-	if (err)
-		kfree(chip);
-
-	return err;
+	return 0;
 }
 
 static void cleanup(struct spi_device *spi)
 {
 	struct chip_data *chip = spi_get_ctldata(spi);
 
-	cleanup_cs(spi);
 	kfree(chip);
 }
 
diff --git a/include/linux/spi/pxa2xx_spi.h b/include/linux/spi/pxa2xx_spi.h
index ca74dce36706..4658e7801b42 100644
--- a/include/linux/spi/pxa2xx_spi.h
+++ b/include/linux/spi/pxa2xx_spi.h
@@ -42,7 +42,6 @@ struct pxa2xx_spi_chip {
 	u8 rx_threshold;
 	u8 dma_burst_size;
 	u32 timeout;
-	int gpio_cs;
 };
 
 #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
-- 
2.34.1



From sboyd at kernel.org  Mon Jan 24 17:05:37 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:05:37 -0800
Subject: [PATCH] clk: at91: allow setting PMC_AUDIOPINCK clock parents via
 DT
In-Reply-To: <20220111142051.37957-1-admin@hifiphile.com>
References: <20220111142051.37957-1-admin@hifiphile.com>
Message-ID: <20220125010538.D5B04C340E4@smtp.kernel.org>

Quoting Zixun LI (2022-01-11 06:20:50)
> Make AUDIOPINCK accessible via phandle to select it
> as peripheral clock parent using assigned-clock-parents in DT
> where available.
> 
> Signed-off-by: Zixun LI <admin at hifiphile.com>
> Reviewed-by: Claudiu Beznea <Claudiu.Beznea at microchip.com>
> ---

Applied to clk-next


From sboyd at kernel.org  Mon Jan 24 17:05:53 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:05:53 -0800
Subject: [PATCH] clk: at91: sama7g5: Allow MCK1 to be exported and
 referenced in DT
In-Reply-To: <20220111125310.902856-1-tudor.ambarus@microchip.com>
References: <20220111125310.902856-1-tudor.ambarus@microchip.com>
Message-ID: <20220125010554.BB92BC340E4@smtp.kernel.org>

Quoting Tudor Ambarus (2022-01-11 04:53:10)
> MCK1 feeds the External Bus Interface (EBI). EBI's clock rate is used
> to translate EBI's timmings to SMC timings, thus we need to handle MCK1
> in the EBI driver. Allow MCK1 to be referenced as a PMC_TYPE_CORE clock
> from phandle in DT.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
> ---

Applied to clk-next


From kuba at kernel.org  Mon Jan 24 17:10:34 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Mon, 24 Jan 2022 17:10:34 -0800
Subject: [PATCH] net: dsa|ethernet: use bool values to pass bool param
 of phy_init_eee
In-Reply-To: <20220123152241.1480-1-jszhang@kernel.org>
References: <20220123152241.1480-1-jszhang@kernel.org>
Message-ID: <20220124171034.764bbf5e@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Sun, 23 Jan 2022 23:22:41 +0800 Jisheng Zhang wrote:
> The 2nd param of phy_init_eee(): clk_stop_enable is a bool param, use
> true or false instead of 1/0.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Applied, thanks!


From iwona.winiarska at intel.com  Mon Jan 24 17:10:51 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:51 +0100
Subject: [PATCH v6 00/13] Introduce PECI subsystem
Message-ID: <20220125011104.2480133-1-iwona.winiarska@intel.com>

Hi!

Small updates, mainly in ASPEED PECI driver.
Biggest one is replacing memcpy_toio/fromio with regular readl/writel,
to fix problems observed when PECI request/response are unaligned.

Here is the usual cover letter from the previous revision:

The Platform Environment Control Interface (PECI) is a communication
interface between Intel processors and management controllers (e.g.
Baseboard Management Controller, BMC).

This series adds a PECI subsystem and introduces drivers which run in
the Linux instance on the management controller (not the main Intel
processor) and is intended to be used by the OpenBMC [1], a Linux
distribution for BMC devices.
The information exposed over PECI (like processor and DIMM
temperature) refers to the Intel processor and can be consumed by
daemons running on the BMC to, for example, display the processor
temperature in its web interface.

The PECI bus is collection of code that provides interface support
between PECI devices (that actually represent processors) and PECI
controllers (such as the "peci-aspeed" controller) that allow to
access physical PECI interface. PECI devices are bound to PECI
drivers that provides access to PECI services. This series introduces
a generic "peci-cpu" driver that exposes hardware monitoring "cputemp"
and "dimmtemp" using the auxiliary bus.

Exposing "raw" PECI to userspace, either to write userspace drivers or
for debug/testing purpose was left out of this series to encourage
writing kernel drivers instead, but may be pursued in the future.

Introducing PECI to upstream Linux was already attempted before [2].
Since it's been over a year since last revision, and the series
changed quite a bit in the meantime, I've decided to start from v1.

I would also like to give credit to everyone who helped me with
different aspects of preliminary review:
- Pierre-Louis Bossart,
- Tony Luck, 
- Andy Shevchenko,
- Dave Hansen.

[1] https://github.com/openbmc/openbmc
[2] https://lore.kernel.org/openbmc/20191211194624.2872-1-jae.hyun.yoo at linux.intel.com/

Changes v5 -> v6:
* Added missing COMMON_CLK selection (lkp at intel.com)
* Fixed WARN_ON always evaluated to true (lkp at intel.com)
* Clean interrupt status unconditionally (Joel)
* Replaced memcpy_toio()/memcpy_fromio() with writel()/readl() to
  avoid issues when submitting unaligned PECI commands

Changes v4 -> v5:
* Added clk_aspeed_peci to express controller programming using common
  clock framework (Billy)
* Modified peci-aspeed DTS schema to match clock changes (Billy)
* Added workaround for peci-aspeed controller hang (Billy)
* Removed unnecessary "else after return" (Guenter)

Changes v3 -> v4:
* Fixed an issue where peci doesn't work after host shutdown (Zev)
* Replaced kill_device() with peci_device_del_lock (Greg)
* Fixed dts_valid() parameter type (Guenter)
* Removed Jae from MAINTAINERS file (Jae)

Changes v2 -> v3:

* Dropped x86/cpu patches (Boris)
* Dropped pr_fmt() for PECI module (Dan)
* Fixed releasing peci controller device flow (Dan) 
* Improved peci-aspeed commit-msg and Kconfig help (Dan)
* Fixed aspeed_peci_xfer() to use the proper spin_lock function (Dan) 
* Wrapped print_hex_dump_bytes() in CONFIG_DYNAMIC_DEBUG (Dan)
* Removed debug status logs from aspeed_peci_irq_handler() (Dan)
* Renamed functions using devres to start with "devm" (Dan)
* Changed request to be allocated on stack in peci_detect (Dan)
* Removed redundant WARN_ON on invalid PECI addr (Dan)
* Changed peci_device_create() to use device_initialize() + device_add() pattern (Dan)
* Fixed peci_device_destroy() to use kill_device() avoiding double-free (Dan)
* Renamed functions that perform xfer using "peci_xfer_*" prefix (Dan) 
* Renamed peci_request_data_dib(temp) -> peci_request_dib(temp)_read (Dan)
* Fixed thermal margin readings for older Intel processors (Zev) 
* Misc hwmon simplifications (Guenter)
* Used BIT_PER_TYPE to verify macro value constrains (Guenter)
* Improved WARN_ON message to print chan_rank_max and idx_dimm_max (Guenter)
* Improved dimmtemp to not reattempt probe if no dimms are populated

Changes v1 -> v2:

Biggest changes when it comes to diffstat are locking in HWMON
(I decided to clean things up a bit while adding it), switching to
devres usage in more places and exposing sysfs interface in separate patch.

* Moved extending X86 ARCHITECTURE MAINTAINERS earlier in series (Dan)
* Removed "default n" for GENERIC_LIB_X86 (Dan)
* Added vendor prefix for peci-aspeed specific properties (Rob)
* Refactored PECI to use devres consistently (Dan)
* Added missing sysfs documentation and excluded adding peci-sysfs to
  separate patch (Dan)
* Used module_init() instead of subsys_init() for peci module initialization (Dan)
* Removed redundant struct peci_device member (Dan)
* Improved PECI Kconfig help (Randy/Dan)
* Fixed/removed log messages (Dan, Guenter)
* Refactored peci-cputemp and peci-dimmtemp and added missing locks (Guenter)
* Removed unused dev_set_drvdata() in peci-cputemp and peci-dimmtemp (Guenter)
* Fixed used types, names, fixed broken and added additional comments
  to peci-hwmon (Guenter, Zev)
* Refactored peci-dimmtemp to not return -ETIMEDOUT (Guenter)
* Added sanity check for min_peci_revision in peci-hwmon drivers (Zev)
* Added assert for DIMM_NUMS_MAX and additional warning in peci-dimmtemp (Zev)
* Fixed macro names in peci-aspeed (Zev)
* Refactored peci-aspeed sanitizing properties to a single helper function (Zev)
* Fixed peci_cpu_device_ids definition for Broadwell Xeon D (David)
* Refactor peci_request to use a single allocation (Zev)
* Used min_t() to improve code readability (Zev)
* Added macro for PECI_RDENDPTCFG_MMIO_WR_LEN_BASE and fixed adev type
  array name to more descriptive (Zev)
* Fixed peci-hwmon commit-msg and documentation (Zev)

Thanks
-Iwona

Iwona Winiarska (11):
  dt-bindings: Add generic bindings for PECI
  dt-bindings: Add bindings for peci-aspeed
  ARM: dts: aspeed: Add PECI controller nodes
  peci: Add core infrastructure
  peci: Add device detection
  peci: Add sysfs interface for PECI bus
  peci: Add support for PECI device drivers
  peci: Add peci-cpu driver
  hwmon: peci: Add cputemp driver
  hwmon: peci: Add dimmtemp driver
  docs: Add PECI documentation

Jae Hyun Yoo (2):
  peci: Add peci-aspeed controller driver
  docs: hwmon: Document PECI drivers

 Documentation/ABI/testing/sysfs-bus-peci      |  16 +
 .../devicetree/bindings/peci/peci-aspeed.yaml |  72 ++
 .../bindings/peci/peci-controller.yaml        |  33 +
 Documentation/hwmon/index.rst                 |   2 +
 Documentation/hwmon/peci-cputemp.rst          |  90 +++
 Documentation/hwmon/peci-dimmtemp.rst         |  57 ++
 Documentation/index.rst                       |   1 +
 Documentation/peci/index.rst                  |  16 +
 Documentation/peci/peci.rst                   |  51 ++
 MAINTAINERS                                   |  26 +
 arch/arm/boot/dts/aspeed-g4.dtsi              |  11 +
 arch/arm/boot/dts/aspeed-g5.dtsi              |  11 +
 arch/arm/boot/dts/aspeed-g6.dtsi              |  11 +
 drivers/Kconfig                               |   3 +
 drivers/Makefile                              |   1 +
 drivers/hwmon/Kconfig                         |   2 +
 drivers/hwmon/Makefile                        |   1 +
 drivers/hwmon/peci/Kconfig                    |  31 +
 drivers/hwmon/peci/Makefile                   |   7 +
 drivers/hwmon/peci/common.h                   |  58 ++
 drivers/hwmon/peci/cputemp.c                  | 592 ++++++++++++++++
 drivers/hwmon/peci/dimmtemp.c                 | 630 ++++++++++++++++++
 drivers/peci/Kconfig                          |  36 +
 drivers/peci/Makefile                         |  10 +
 drivers/peci/controller/Kconfig               |  18 +
 drivers/peci/controller/Makefile              |   3 +
 drivers/peci/controller/peci-aspeed.c         | 599 +++++++++++++++++
 drivers/peci/core.c                           | 236 +++++++
 drivers/peci/cpu.c                            | 343 ++++++++++
 drivers/peci/device.c                         | 252 +++++++
 drivers/peci/internal.h                       | 136 ++++
 drivers/peci/request.c                        | 482 ++++++++++++++
 drivers/peci/sysfs.c                          |  82 +++
 include/linux/peci-cpu.h                      |  40 ++
 include/linux/peci.h                          | 112 ++++
 35 files changed, 4071 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c
 create mode 100644 drivers/hwmon/peci/dimmtemp.c
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 drivers/peci/request.c
 create mode 100644 drivers/peci/sysfs.c
 create mode 100644 include/linux/peci-cpu.h
 create mode 100644 include/linux/peci.h

-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:52 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:52 +0100
Subject: [PATCH v6 01/13] dt-bindings: Add generic bindings for PECI
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-2-iwona.winiarska@intel.com>

Add device tree bindings for the PECI controller.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 .../bindings/peci/peci-controller.yaml        | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-controller.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-controller.yaml b/Documentation/devicetree/bindings/peci/peci-controller.yaml
new file mode 100644
index 000000000000..bbc3d3f3a929
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-controller.yaml
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-controller.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Generic Device Tree Bindings for PECI
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+
+description:
+  PECI (Platform Environment Control Interface) is an interface that provides a
+  communication channel from Intel processors and chipset components to external
+  monitoring or control devices.
+
+properties:
+  $nodename:
+    pattern: "^peci-controller(@.*)?$"
+
+  cmd-timeout-ms:
+    description:
+      Command timeout in units of ms.
+
+additionalProperties: true
+
+examples:
+  - |
+    peci-controller at 1e78b000 {
+      reg = <0x1e78b000 0x100>;
+      cmd-timeout-ms = <500>;
+    };
+...
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:53 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:53 +0100
Subject: [PATCH v6 02/13] dt-bindings: Add bindings for peci-aspeed
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-3-iwona.winiarska@intel.com>

Add device tree bindings for the peci-aspeed controller driver.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 .../devicetree/bindings/peci/peci-aspeed.yaml | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/peci/peci-aspeed.yaml

diff --git a/Documentation/devicetree/bindings/peci/peci-aspeed.yaml b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
new file mode 100644
index 000000000000..1e68a801a92a
--- /dev/null
+++ b/Documentation/devicetree/bindings/peci/peci-aspeed.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/peci/peci-aspeed.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Aspeed PECI Bus Device Tree Bindings
+
+maintainers:
+  - Iwona Winiarska <iwona.winiarska at intel.com>
+  - Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+allOf:
+  - $ref: peci-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - aspeed,ast2400-peci
+      - aspeed,ast2500-peci
+      - aspeed,ast2600-peci
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    description:
+      Clock source for PECI controller. Should reference the external
+      oscillator clock.
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+  cmd-timeout-ms:
+    minimum: 1
+    maximum: 1000
+    default: 1000
+
+  clock-frequency:
+    description:
+      The desired operation frequency of PECI controller in Hz.
+    minimum: 2000
+    maximum: 2000000
+    default: 1000000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/clock/ast2600-clock.h>
+    peci-controller at 1e78b000 {
+      compatible = "aspeed,ast2600-peci";
+      reg = <0x1e78b000 0x100>;
+      interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+      resets = <&syscon ASPEED_RESET_PECI>;
+      cmd-timeout-ms = <1000>;
+      clock-frequency = <1000000>;
+    };
+...
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:54 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:54 +0100
Subject: [PATCH v6 03/13] ARM: dts: aspeed: Add PECI controller nodes
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-4-iwona.winiarska@intel.com>

Add PECI controller nodes with all required information.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 arch/arm/boot/dts/aspeed-g4.dtsi | 11 +++++++++++
 arch/arm/boot/dts/aspeed-g5.dtsi | 11 +++++++++++
 arch/arm/boot/dts/aspeed-g6.dtsi | 11 +++++++++++
 3 files changed, 33 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi
index f14dace34c5a..fa8b581c3d6c 100644
--- a/arch/arm/boot/dts/aspeed-g4.dtsi
+++ b/arch/arm/boot/dts/aspeed-g4.dtsi
@@ -392,6 +392,17 @@ uart_routing: uart-routing at 9c {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2400-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi
index 7495f93c5069..4147b397c883 100644
--- a/arch/arm/boot/dts/aspeed-g5.dtsi
+++ b/arch/arm/boot/dts/aspeed-g5.dtsi
@@ -516,6 +516,17 @@ ibt: ibt at 140 {
 				};
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2500-peci";
+				reg = <0x1e78b000 0x60>;
+				interrupts = <15>;
+				clocks = <&syscon ASPEED_CLK_GATE_REFCLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			uart2: serial at 1e78d000 {
 				compatible = "ns16550a";
 				reg = <0x1e78d000 0x20>;
diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index c32e87fad4dc..3d5ce9da42c3 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -512,6 +512,17 @@ wdt4: watchdog at 1e7850c0 {
 				status = "disabled";
 			};
 
+			peci0: peci-controller at 1e78b000 {
+				compatible = "aspeed,ast2600-peci";
+				reg = <0x1e78b000 0x100>;
+				interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&syscon ASPEED_CLK_GATE_REF0CLK>;
+				resets = <&syscon ASPEED_RESET_PECI>;
+				cmd-timeout-ms = <1000>;
+				clock-frequency = <1000000>;
+				status = "disabled";
+			};
+
 			lpc: lpc at 1e789000 {
 				compatible = "aspeed,ast2600-lpc-v2", "simple-mfd", "syscon";
 				reg = <0x1e789000 0x1000>;
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:55 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:55 +0100
Subject: [PATCH v6 04/13] peci: Add core infrastructure
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-5-iwona.winiarska@intel.com>

Intel processors provide access for various services designed to support
processor and DRAM thermal management, platform manageability and
processor interface tuning and diagnostics.
Those services are available via the Platform Environment Control
Interface (PECI) that provides a communication channel between the
processor and the Baseboard Management Controller (BMC) or other
platform management device.

This change introduces PECI subsystem by adding the initial core module
and API for controller drivers.

Co-developed-by: Jason M Bills <jason.m.bills at linux.intel.com>
Signed-off-by: Jason M Bills <jason.m.bills at linux.intel.com>
Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS             |   8 ++
 drivers/Kconfig         |   3 +
 drivers/Makefile        |   1 +
 drivers/peci/Kconfig    |  15 ++++
 drivers/peci/Makefile   |   5 ++
 drivers/peci/core.c     | 158 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  16 ++++
 include/linux/peci.h    |  99 +++++++++++++++++++++++++
 8 files changed, 305 insertions(+)
 create mode 100644 drivers/peci/Kconfig
 create mode 100644 drivers/peci/Makefile
 create mode 100644 drivers/peci/core.c
 create mode 100644 drivers/peci/internal.h
 create mode 100644 include/linux/peci.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..aa7ae643fdb0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15091,6 +15091,14 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI SUBSYSTEM
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/
+F:	drivers/peci/
+F:	include/linux/peci.h
+
 PENSANDO ETHERNET DRIVERS
 M:	Shannon Nelson <snelson at pensando.io>
 M:	drivers at pensando.io
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 0d399ddaa185..8d6cd5d08722 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -236,4 +236,7 @@ source "drivers/interconnect/Kconfig"
 source "drivers/counter/Kconfig"
 
 source "drivers/most/Kconfig"
+
+source "drivers/peci/Kconfig"
+
 endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index a110338c860c..020780b6b4d2 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -187,3 +187,4 @@ obj-$(CONFIG_GNSS)		+= gnss/
 obj-$(CONFIG_INTERCONNECT)	+= interconnect/
 obj-$(CONFIG_COUNTER)		+= counter/
 obj-$(CONFIG_MOST)		+= most/
+obj-$(CONFIG_PECI)		+= peci/
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
new file mode 100644
index 000000000000..71a4ad81225a
--- /dev/null
+++ b/drivers/peci/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+menuconfig PECI
+	tristate "PECI support"
+	help
+	  The Platform Environment Control Interface (PECI) is an interface
+	  that provides a communication channel to Intel processors and
+	  chipset components from external monitoring or control devices.
+
+	  If you are building a Baseboard Management Controller (BMC) kernel
+	  for Intel platform say Y here and also to the specific driver for
+	  your adapter(s) below. If unsure say N.
+
+	  This support is also available as a module. If so, the module
+	  will be called peci.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
new file mode 100644
index 000000000000..e789a354e842
--- /dev/null
+++ b/drivers/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Core functionality
+peci-y := core.o
+obj-$(CONFIG_PECI) += peci.o
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
new file mode 100644
index 000000000000..73ad0a47fa9d
--- /dev/null
+++ b/drivers/peci/core.c
@@ -0,0 +1,158 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/export.h>
+#include <linux/idr.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/pm_runtime.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+static DEFINE_IDA(peci_controller_ida);
+
+static void peci_controller_dev_release(struct device *dev)
+{
+	struct peci_controller *controller = to_peci_controller(dev);
+
+	mutex_destroy(&controller->bus_lock);
+	ida_free(&peci_controller_ida, controller->id);
+	kfree(controller);
+}
+
+struct device_type peci_controller_type = {
+	.release	= peci_controller_dev_release,
+};
+
+static struct peci_controller *peci_controller_alloc(struct device *dev,
+						     struct peci_controller_ops *ops)
+{
+	struct peci_controller *controller;
+	int ret;
+
+	if (!ops->xfer)
+		return ERR_PTR(-EINVAL);
+
+	controller = kzalloc(sizeof(*controller), GFP_KERNEL);
+	if (!controller)
+		return ERR_PTR(-ENOMEM);
+
+	ret = ida_alloc_max(&peci_controller_ida, U8_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err;
+	controller->id = ret;
+
+	controller->ops = ops;
+
+	controller->dev.parent = dev;
+	controller->dev.bus = &peci_bus_type;
+	controller->dev.type = &peci_controller_type;
+
+	device_initialize(&controller->dev);
+
+	mutex_init(&controller->bus_lock);
+
+	return controller;
+
+err:
+	kfree(controller);
+	return ERR_PTR(ret);
+}
+
+static void unregister_controller(void *_controller)
+{
+	struct peci_controller *controller = _controller;
+
+	device_unregister(&controller->dev);
+
+	fwnode_handle_put(controller->dev.fwnode);
+
+	pm_runtime_disable(&controller->dev);
+}
+
+/**
+ * devm_peci_controller_add() - add PECI controller
+ * @dev: device for devm operations
+ * @ops: pointer to controller specific methods
+ *
+ * In final stage of its probe(), peci_controller driver calls
+ * devm_peci_controller_add() to register itself with the PECI bus.
+ *
+ * Return: Pointer to the newly allocated controller or ERR_PTR() in case of failure.
+ */
+struct peci_controller *devm_peci_controller_add(struct device *dev,
+						 struct peci_controller_ops *ops)
+{
+	struct peci_controller *controller;
+	int ret;
+
+	controller = peci_controller_alloc(dev, ops);
+	if (IS_ERR(controller))
+		return controller;
+
+	ret = dev_set_name(&controller->dev, "peci-%d", controller->id);
+	if (ret)
+		goto err_put;
+
+	pm_runtime_no_callbacks(&controller->dev);
+	pm_suspend_ignore_children(&controller->dev, true);
+	pm_runtime_enable(&controller->dev);
+
+	device_set_node(&controller->dev, fwnode_handle_get(dev_fwnode(dev)));
+
+	ret = device_add(&controller->dev);
+	if (ret)
+		goto err_fwnode;
+
+	ret = devm_add_action_or_reset(dev, unregister_controller, controller);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return controller;
+
+err_fwnode:
+	fwnode_handle_put(controller->dev.fwnode);
+
+	pm_runtime_disable(&controller->dev);
+
+err_put:
+	put_device(&controller->dev);
+
+	return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
+
+struct bus_type peci_bus_type = {
+	.name		= "peci",
+};
+
+static int __init peci_init(void)
+{
+	int ret;
+
+	ret = bus_register(&peci_bus_type);
+	if (ret < 0) {
+		pr_err("peci: failed to register PECI bus type!\n");
+		return ret;
+	}
+
+	return 0;
+}
+module_init(peci_init);
+
+static void __exit peci_exit(void)
+{
+	bus_unregister(&peci_bus_type);
+}
+module_exit(peci_exit);
+
+MODULE_AUTHOR("Jason M Bills <jason.m.bills at linux.intel.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI bus core module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
new file mode 100644
index 000000000000..918dea745a86
--- /dev/null
+++ b/drivers/peci/internal.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __PECI_INTERNAL_H
+#define __PECI_INTERNAL_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+
+struct peci_controller;
+
+extern struct bus_type peci_bus_type;
+
+extern struct device_type peci_controller_type;
+
+#endif /* __PECI_INTERNAL_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
new file mode 100644
index 000000000000..26e0a4e73b50
--- /dev/null
+++ b/include/linux/peci.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2018-2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_H
+#define __LINUX_PECI_H
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+/*
+ * Currently we don't support any PECI command over 32 bytes.
+ */
+#define PECI_REQUEST_MAX_BUF_SIZE 32
+
+struct peci_controller;
+struct peci_request;
+
+/**
+ * struct peci_controller_ops - PECI controller specific methods
+ * @xfer: PECI transfer function
+ *
+ * PECI controllers may have different hardware interfaces - the drivers
+ * implementing PECI controllers can use this structure to abstract away those
+ * differences by exposing a common interface for PECI core.
+ */
+struct peci_controller_ops {
+	int (*xfer)(struct peci_controller *controller, u8 addr, struct peci_request *req);
+};
+
+/**
+ * struct peci_controller - PECI controller
+ * @dev: device object to register PECI controller to the device model
+ * @ops: pointer to device specific controller operations
+ * @bus_lock: lock used to protect multiple callers
+ * @id: PECI controller ID
+ *
+ * PECI controllers usually connect to their drivers using non-PECI bus,
+ * such as the platform bus.
+ * Each PECI controller can communicate with one or more PECI devices.
+ */
+struct peci_controller {
+	struct device dev;
+	struct peci_controller_ops *ops;
+	struct mutex bus_lock; /* held for the duration of xfer */
+	u8 id;
+};
+
+struct peci_controller *devm_peci_controller_add(struct device *parent,
+						 struct peci_controller_ops *ops);
+
+static inline struct peci_controller *to_peci_controller(void *d)
+{
+	return container_of(d, struct peci_controller, dev);
+}
+
+/**
+ * struct peci_device - PECI device
+ * @dev: device object to register PECI device to the device model
+ * @controller: manages the bus segment hosting this PECI device
+ * @addr: address used on the PECI bus connected to the parent controller
+ *
+ * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
+ * The behaviour exposed to the rest of the system is defined by the PECI driver
+ * managing the device.
+ */
+struct peci_device {
+	struct device dev;
+	u8 addr;
+};
+
+static inline struct peci_device *to_peci_device(struct device *d)
+{
+	return container_of(d, struct peci_device, dev);
+}
+
+/**
+ * struct peci_request - PECI request
+ * @device: PECI device to which the request is sent
+ * @tx: TX buffer specific data
+ * @tx.buf: TX buffer
+ * @tx.len: transfer data length in bytes
+ * @rx: RX buffer specific data
+ * @rx.buf: RX buffer
+ * @rx.len: received data length in bytes
+ *
+ * A peci_request represents a request issued by PECI originator (TX) and
+ * a response received from PECI responder (RX).
+ */
+struct peci_request {
+	struct peci_device *device;
+	struct {
+		u8 buf[PECI_REQUEST_MAX_BUF_SIZE];
+		u8 len;
+	} rx, tx;
+};
+
+#endif /* __LINUX_PECI_H */
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:56 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:56 +0100
Subject: [PATCH v6 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-6-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

ASPEED AST24xx/AST25xx/AST26xx SoCs support the PECI electrical
interface (a.k.a PECI wire) that provides a communication channel with
Intel processors.
This driver allows BMC to discover devices connected to it and
communicate with them using PECI protocol.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 MAINTAINERS                           |   8 +
 drivers/peci/Kconfig                  |   6 +
 drivers/peci/Makefile                 |   3 +
 drivers/peci/controller/Kconfig       |  18 +
 drivers/peci/controller/Makefile      |   3 +
 drivers/peci/controller/peci-aspeed.c | 599 ++++++++++++++++++++++++++
 6 files changed, 637 insertions(+)
 create mode 100644 drivers/peci/controller/Kconfig
 create mode 100644 drivers/peci/controller/Makefile
 create mode 100644 drivers/peci/controller/peci-aspeed.c

diff --git a/MAINTAINERS b/MAINTAINERS
index aa7ae643fdb0..6c9b12004e4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2985,6 +2985,14 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/net/asix,ax88796c.yaml
 F:	drivers/net/ethernet/asix/ax88796c_*
 
+ASPEED PECI CONTROLLER
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
+L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
+S:	Supported
+F:	Documentation/devicetree/bindings/peci/peci-aspeed.yaml
+F:	drivers/peci/controller/peci-aspeed.c
+
 ASPEED PINCTRL DRIVERS
 M:	Andrew Jeffery <andrew at aj.id.au>
 L:	linux-aspeed at lists.ozlabs.org (moderated for non-subscribers)
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 71a4ad81225a..99279df97a78 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -13,3 +13,9 @@ menuconfig PECI
 
 	  This support is also available as a module. If so, the module
 	  will be called peci.
+
+if PECI
+
+source "drivers/peci/controller/Kconfig"
+
+endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index e789a354e842..926d8df15cbd 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,3 +3,6 @@
 # Core functionality
 peci-y := core.o
 obj-$(CONFIG_PECI) += peci.o
+
+# Hardware specific bus drivers
+obj-y += controller/
diff --git a/drivers/peci/controller/Kconfig b/drivers/peci/controller/Kconfig
new file mode 100644
index 000000000000..32bd8d685c0d
--- /dev/null
+++ b/drivers/peci/controller/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config PECI_ASPEED
+	tristate "ASPEED PECI support"
+	depends on ARCH_ASPEED || COMPILE_TEST
+	depends on OF
+	depends on HAS_IOMEM
+	select COMMON_CLK
+	help
+	  This option enables PECI controller driver for ASPEED AST2400,
+	  AST2500 and AST2600 SoCs. It allows BMC to discover devices
+	  connected to it, and communicate with them using PECI protocol.
+
+	  Say Y here if your system runs on ASPEED SoC and you are using it
+	  as BMC for Intel platform.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called peci-aspeed.
diff --git a/drivers/peci/controller/Makefile b/drivers/peci/controller/Makefile
new file mode 100644
index 000000000000..022c28ef1bf0
--- /dev/null
+++ b/drivers/peci/controller/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-$(CONFIG_PECI_ASPEED)	+= peci-aspeed.o
diff --git a/drivers/peci/controller/peci-aspeed.c b/drivers/peci/controller/peci-aspeed.c
new file mode 100644
index 000000000000..1925ddc13f00
--- /dev/null
+++ b/drivers/peci/controller/peci-aspeed.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2012-2017 ASPEED Technology Inc.
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <asm/unaligned.h>
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/jiffies.h>
+#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/peci.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* ASPEED PECI Registers */
+/* Control Register */
+#define ASPEED_PECI_CTRL			0x00
+#define   ASPEED_PECI_CTRL_SAMPLING_MASK	GENMASK(19, 16)
+#define   ASPEED_PECI_CTRL_RD_MODE_MASK		GENMASK(13, 12)
+#define     ASPEED_PECI_CTRL_RD_MODE_DBG	BIT(13)
+#define     ASPEED_PECI_CTRL_RD_MODE_COUNT	BIT(12)
+#define   ASPEED_PECI_CTRL_CLK_SRC_HCLK		BIT(11)
+#define   ASPEED_PECI_CTRL_CLK_DIV_MASK		GENMASK(10, 8)
+#define   ASPEED_PECI_CTRL_INVERT_OUT		BIT(7)
+#define   ASPEED_PECI_CTRL_INVERT_IN		BIT(6)
+#define   ASPEED_PECI_CTRL_BUS_CONTENTION_EN	BIT(5)
+#define   ASPEED_PECI_CTRL_PECI_EN		BIT(4)
+#define   ASPEED_PECI_CTRL_PECI_CLK_EN		BIT(0)
+
+/* Timing Negotiation Register */
+#define ASPEED_PECI_TIMING_NEGOTIATION		0x04
+#define   ASPEED_PECI_T_NEGO_MSG_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_T_NEGO_ADDR_MASK		GENMASK(7, 0)
+
+/* Command Register */
+#define ASPEED_PECI_CMD				0x08
+#define   ASPEED_PECI_CMD_PIN_MONITORING	BIT(31)
+#define   ASPEED_PECI_CMD_STS_MASK		GENMASK(27, 24)
+#define     ASPEED_PECI_CMD_STS_ADDR_T_NEGO	0x3
+#define   ASPEED_PECI_CMD_IDLE_MASK		\
+	  (ASPEED_PECI_CMD_STS_MASK | ASPEED_PECI_CMD_PIN_MONITORING)
+#define   ASPEED_PECI_CMD_FIRE			BIT(0)
+
+/* Read/Write Length Register */
+#define ASPEED_PECI_RW_LENGTH			0x0c
+#define   ASPEED_PECI_AW_FCS_EN			BIT(31)
+#define   ASPEED_PECI_RD_LEN_MASK		GENMASK(23, 16)
+#define   ASPEED_PECI_WR_LEN_MASK		GENMASK(15, 8)
+#define   ASPEED_PECI_TARGET_ADDR_MASK		GENMASK(7, 0)
+
+/* Expected FCS Data Register */
+#define ASPEED_PECI_EXPECTED_FCS		0x10
+#define   ASPEED_PECI_EXPECTED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_EXPECTED_AW_FCS_AUTO_MASK	GENMASK(15, 8)
+#define   ASPEED_PECI_EXPECTED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Captured FCS Data Register */
+#define ASPEED_PECI_CAPTURED_FCS		0x14
+#define   ASPEED_PECI_CAPTURED_RD_FCS_MASK	GENMASK(23, 16)
+#define   ASPEED_PECI_CAPTURED_WR_FCS_MASK	GENMASK(7, 0)
+
+/* Interrupt Register */
+#define ASPEED_PECI_INT_CTRL			0x18
+#define   ASPEED_PECI_TIMING_NEGO_SEL_MASK	GENMASK(31, 30)
+#define     ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO	0
+#define     ASPEED_PECI_2ND_BIT_OF_ADDR_NEGO	1
+#define     ASPEED_PECI_MESSAGE_NEGO		2
+#define   ASPEED_PECI_INT_MASK			GENMASK(4, 0)
+#define     ASPEED_PECI_INT_BUS_TIMEOUT		BIT(4)
+#define     ASPEED_PECI_INT_BUS_CONTENTION	BIT(3)
+#define     ASPEED_PECI_INT_WR_FCS_BAD		BIT(2)
+#define     ASPEED_PECI_INT_WR_FCS_ABORT	BIT(1)
+#define     ASPEED_PECI_INT_CMD_DONE		BIT(0)
+
+/* Interrupt Status Register */
+#define ASPEED_PECI_INT_STS			0x1c
+#define   ASPEED_PECI_INT_TIMING_RESULT_MASK	GENMASK(29, 16)
+	  /* bits[4..0]: Same bit fields in the 'Interrupt Register' */
+
+/* Rx/Tx Data Buffer Registers */
+#define ASPEED_PECI_WR_DATA0			0x20
+#define ASPEED_PECI_WR_DATA1			0x24
+#define ASPEED_PECI_WR_DATA2			0x28
+#define ASPEED_PECI_WR_DATA3			0x2c
+#define ASPEED_PECI_RD_DATA0			0x30
+#define ASPEED_PECI_RD_DATA1			0x34
+#define ASPEED_PECI_RD_DATA2			0x38
+#define ASPEED_PECI_RD_DATA3			0x3c
+#define ASPEED_PECI_WR_DATA4			0x40
+#define ASPEED_PECI_WR_DATA5			0x44
+#define ASPEED_PECI_WR_DATA6			0x48
+#define ASPEED_PECI_WR_DATA7			0x4c
+#define ASPEED_PECI_RD_DATA4			0x50
+#define ASPEED_PECI_RD_DATA5			0x54
+#define ASPEED_PECI_RD_DATA6			0x58
+#define ASPEED_PECI_RD_DATA7			0x5c
+#define   ASPEED_PECI_DATA_BUF_SIZE_MAX		32
+
+/* Timing Negotiation */
+#define ASPEED_PECI_CLK_FREQUENCY_MIN		2000
+#define ASPEED_PECI_CLK_FREQUENCY_DEFAULT	1000000
+#define ASPEED_PECI_CLK_FREQUENCY_MAX		2000000
+#define ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT	8
+/* Timeout */
+#define ASPEED_PECI_IDLE_CHECK_TIMEOUT_US	(50 * USEC_PER_MSEC)
+#define ASPEED_PECI_IDLE_CHECK_INTERVAL_US	(10 * USEC_PER_MSEC)
+#define ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT	1000
+#define ASPEED_PECI_CMD_TIMEOUT_MS_MAX		1000
+
+#define ASPEED_PECI_CLK_DIV1(msg_timing) (4 * (msg_timing) + 1)
+#define ASPEED_PECI_CLK_DIV2(clk_div_exp) BIT(clk_div_exp)
+#define ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp) \
+	(4 * ASPEED_PECI_CLK_DIV1(msg_timing) * ASPEED_PECI_CLK_DIV2(clk_div_exp))
+
+struct aspeed_peci {
+	struct peci_controller *controller;
+	struct device *dev;
+	void __iomem *base;
+	struct reset_control *rst;
+	int irq;
+	spinlock_t lock; /* to sync completion status handling */
+	struct completion xfer_complete;
+	struct clk *clk;
+	u32 clk_frequency;
+	u32 status;
+	u32 cmd_timeout_ms;
+};
+
+struct clk_aspeed_peci {
+	struct clk_hw hw;
+	struct aspeed_peci *aspeed_peci;
+};
+
+static void aspeed_peci_controller_enable(struct aspeed_peci *priv)
+{
+	u32 val = readl(priv->base + ASPEED_PECI_CTRL);
+
+	val |= ASPEED_PECI_CTRL_PECI_CLK_EN;
+	val |= ASPEED_PECI_CTRL_PECI_EN;
+
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+}
+
+static void aspeed_peci_init_regs(struct aspeed_peci *priv)
+{
+	u32 val;
+
+	/* Clear interrupts */
+	writel(ASPEED_PECI_INT_MASK, priv->base + ASPEED_PECI_INT_STS);
+
+	/* Set timing negotiation mode and enable interrupts */
+	val = FIELD_PREP(ASPEED_PECI_TIMING_NEGO_SEL_MASK, ASPEED_PECI_1ST_BIT_OF_ADDR_NEGO);
+	val |= ASPEED_PECI_INT_MASK;
+	writel(val, priv->base + ASPEED_PECI_INT_CTRL);
+
+	val = FIELD_PREP(ASPEED_PECI_CTRL_SAMPLING_MASK, ASPEED_PECI_RD_SAMPLING_POINT_DEFAULT);
+	writel(val, priv->base + ASPEED_PECI_CTRL);
+}
+
+static int aspeed_peci_check_idle(struct aspeed_peci *priv)
+{
+	u32 cmd_sts = readl(priv->base + ASPEED_PECI_CMD);
+	int ret;
+
+	/*
+	 * Under normal circumstances, we expect to be idle here.
+	 * In case there were any errors/timeouts that led to the situation
+	 * where the hardware is not in idle state - we need to reset and
+	 * reinitialize it to avoid potential controller hang.
+	 */
+	if (FIELD_GET(ASPEED_PECI_CMD_STS_MASK, cmd_sts)) {
+		ret = reset_control_assert(priv->rst);
+		if (ret) {
+			dev_err(priv->dev, "cannot assert reset control\n");
+			return ret;
+		}
+
+		ret = reset_control_deassert(priv->rst);
+		if (ret) {
+			dev_err(priv->dev, "cannot deassert reset control\n");
+			return ret;
+		}
+
+		aspeed_peci_init_regs(priv);
+
+		ret = clk_set_rate(priv->clk, priv->clk_frequency);
+		if (ret < 0) {
+			dev_err(priv->dev, "cannot set clock frequency\n");
+			return ret;
+		}
+
+		aspeed_peci_controller_enable(priv);
+	}
+
+	return readl_poll_timeout(priv->base + ASPEED_PECI_CMD,
+				  cmd_sts,
+				  !(cmd_sts & ASPEED_PECI_CMD_IDLE_MASK),
+				  ASPEED_PECI_IDLE_CHECK_INTERVAL_US,
+				  ASPEED_PECI_IDLE_CHECK_TIMEOUT_US);
+}
+
+static int aspeed_peci_xfer(struct peci_controller *controller,
+			    u8 addr, struct peci_request *req)
+{
+	struct aspeed_peci *priv = dev_get_drvdata(controller->dev.parent);
+	unsigned long timeout = msecs_to_jiffies(priv->cmd_timeout_ms);
+	u32 peci_head;
+	int ret, i;
+
+	if (req->tx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX ||
+	    req->rx.len > ASPEED_PECI_DATA_BUF_SIZE_MAX)
+		return -EINVAL;
+
+	/* Check command sts and bus idle state */
+	ret = aspeed_peci_check_idle(priv);
+	if (ret)
+		return ret; /* -ETIMEDOUT */
+
+	spin_lock_irq(&priv->lock);
+	reinit_completion(&priv->xfer_complete);
+
+	peci_head = FIELD_PREP(ASPEED_PECI_TARGET_ADDR_MASK, addr) |
+		    FIELD_PREP(ASPEED_PECI_WR_LEN_MASK, req->tx.len) |
+		    FIELD_PREP(ASPEED_PECI_RD_LEN_MASK, req->rx.len);
+
+	writel(peci_head, priv->base + ASPEED_PECI_RW_LENGTH);
+
+	for (i = 0; i < req->tx.len; i += 4) {
+		u32 reg = (i < 16 ? ASPEED_PECI_WR_DATA0 : ASPEED_PECI_WR_DATA4) + i % 16;
+
+		writel(get_unaligned_le32(&req->tx.buf[i]), priv->base + reg);
+	}
+
+#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
+	dev_dbg(priv->dev, "HEAD : %#08x\n", peci_head);
+	print_hex_dump_bytes("TX : ", DUMP_PREFIX_NONE, req->tx.buf, req->tx.len);
+#endif
+
+	priv->status = 0;
+	writel(ASPEED_PECI_CMD_FIRE, priv->base + ASPEED_PECI_CMD);
+	spin_unlock_irq(&priv->lock);
+
+	ret = wait_for_completion_interruptible_timeout(&priv->xfer_complete, timeout);
+	if (ret < 0)
+		return ret;
+
+	if (ret == 0) {
+		dev_dbg(priv->dev, "timeout waiting for a response\n");
+		return -ETIMEDOUT;
+	}
+
+	spin_lock_irq(&priv->lock);
+
+	if (priv->status != ASPEED_PECI_INT_CMD_DONE) {
+		spin_unlock_irq(&priv->lock);
+		dev_dbg(priv->dev, "no valid response, status: %#02x\n", priv->status);
+		return -EIO;
+	}
+
+	spin_unlock_irq(&priv->lock);
+
+	/*
+	 * We need to use dword reads for register access, make sure that the
+	 * buffer size is multiple of 4-bytes.
+	 */
+	BUILD_BUG_ON(PECI_REQUEST_MAX_BUF_SIZE % 4);
+
+	for (i = 0; i < req->rx.len; i += 4) {
+		u32 reg = (i < 16 ? ASPEED_PECI_RD_DATA0 : ASPEED_PECI_RD_DATA4) + i % 16;
+		u32 rx_data = readl(priv->base + reg);
+
+		put_unaligned_le32(rx_data, &req->rx.buf[i]);
+	}
+
+#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG)
+	print_hex_dump_bytes("RX : ", DUMP_PREFIX_NONE, req->rx.buf, req->rx.len);
+#endif
+	return 0;
+}
+
+static irqreturn_t aspeed_peci_irq_handler(int irq, void *arg)
+{
+	struct aspeed_peci *priv = arg;
+	u32 status;
+
+	spin_lock(&priv->lock);
+	status = readl(priv->base + ASPEED_PECI_INT_STS);
+	writel(status, priv->base + ASPEED_PECI_INT_STS);
+	priv->status |= (status & ASPEED_PECI_INT_MASK);
+
+	/*
+	 * All commands should be ended up with a ASPEED_PECI_INT_CMD_DONE bit
+	 * set even in an error case.
+	 */
+	if (status & ASPEED_PECI_INT_CMD_DONE)
+		complete(&priv->xfer_complete);
+
+	writel(0, priv->base + ASPEED_PECI_CMD);
+
+	spin_unlock(&priv->lock);
+
+	return IRQ_HANDLED;
+}
+
+static void clk_aspeed_peci_find_div_values(unsigned long rate, int *msg_timing, int *clk_div_exp)
+{
+	unsigned long best_diff = ~0ul, diff;
+	int msg_timing_temp, clk_div_exp_temp, i, j;
+
+	for (i = 1; i <= 255; i++)
+		for (j = 0; j < 8; j++) {
+			diff = abs(rate - ASPEED_PECI_CLK_DIV1(i) * ASPEED_PECI_CLK_DIV2(j));
+			if (diff < best_diff) {
+				msg_timing_temp = i;
+				clk_div_exp_temp = j;
+				best_diff = diff;
+			}
+		}
+
+	*msg_timing = msg_timing_temp;
+	*clk_div_exp = clk_div_exp_temp;
+}
+
+static int clk_aspeed_peci_get_div(unsigned long rate, const unsigned long *prate)
+{
+	unsigned long this_rate = *prate / (4 * rate);
+	int msg_timing, clk_div_exp;
+
+	clk_aspeed_peci_find_div_values(this_rate, &msg_timing, &clk_div_exp);
+
+	return ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp);
+}
+
+static int clk_aspeed_peci_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long prate)
+{
+	struct clk_aspeed_peci *peci_clk = container_of(hw, struct clk_aspeed_peci, hw);
+	struct aspeed_peci *aspeed_peci = peci_clk->aspeed_peci;
+	unsigned long this_rate = prate / (4 * rate);
+	int clk_div_exp, msg_timing;
+	u32 val;
+
+	clk_aspeed_peci_find_div_values(this_rate, &msg_timing, &clk_div_exp);
+
+	val = readl(aspeed_peci->base + ASPEED_PECI_CTRL);
+	val |= FIELD_PREP(ASPEED_PECI_CTRL_CLK_DIV_MASK, clk_div_exp);
+	writel(val, aspeed_peci->base + ASPEED_PECI_CTRL);
+
+	val = FIELD_PREP(ASPEED_PECI_T_NEGO_MSG_MASK, msg_timing);
+	val |= FIELD_PREP(ASPEED_PECI_T_NEGO_ADDR_MASK, msg_timing);
+	writel(val, aspeed_peci->base + ASPEED_PECI_TIMING_NEGOTIATION);
+
+	return 0;
+}
+
+static long clk_aspeed_peci_round_rate(struct clk_hw *hw, unsigned long rate,
+				       unsigned long *prate)
+{
+	int div = clk_aspeed_peci_get_div(rate, prate);
+
+	return DIV_ROUND_UP_ULL(*prate, div);
+}
+
+static unsigned long clk_aspeed_peci_recalc_rate(struct clk_hw *hw, unsigned long prate)
+{
+	struct clk_aspeed_peci *peci_clk = container_of(hw, struct clk_aspeed_peci, hw);
+	struct aspeed_peci *aspeed_peci = peci_clk->aspeed_peci;
+	int div, msg_timing, addr_timing, clk_div_exp;
+	u32 reg;
+
+	reg = readl(aspeed_peci->base + ASPEED_PECI_TIMING_NEGOTIATION);
+	msg_timing = FIELD_GET(ASPEED_PECI_T_NEGO_MSG_MASK, reg);
+	addr_timing = FIELD_GET(ASPEED_PECI_T_NEGO_ADDR_MASK, reg);
+
+	if (msg_timing != addr_timing)
+		return 0;
+
+	reg = readl(aspeed_peci->base + ASPEED_PECI_CTRL);
+	clk_div_exp = FIELD_GET(ASPEED_PECI_CTRL_CLK_DIV_MASK, reg);
+
+	div = ASPEED_PECI_CLK_DIV(msg_timing, clk_div_exp);
+
+	return DIV_ROUND_UP_ULL(prate, div);
+}
+
+static const struct clk_ops clk_aspeed_peci_ops = {
+	.set_rate = clk_aspeed_peci_set_rate,
+	.round_rate = clk_aspeed_peci_round_rate,
+	.recalc_rate = clk_aspeed_peci_recalc_rate,
+};
+
+/*
+ * PECI HW contains a clock divider which is a combination of:
+ *  div0: 4 (fixed divider)
+ *  div1: x + 1
+ *  div2: 1 << y
+ * In other words, out_clk = in_clk / (div0 * div1 * div2)
+ * The resulting frequency is used by PECI Controller to drive the PECI bus to
+ * negotiate optimal transfer rate.
+ */
+static struct clk *devm_aspeed_peci_register_clk_div(struct device *dev, struct clk *parent,
+						     struct aspeed_peci *priv)
+{
+	struct clk_aspeed_peci *peci_clk;
+	struct clk_init_data init;
+	const char *parent_name;
+	char name[32];
+	int ret;
+
+	snprintf(name, sizeof(name), "%s_div", dev_name(dev));
+
+	parent_name = __clk_get_name(parent);
+
+	init.ops = &clk_aspeed_peci_ops;
+	init.name = name;
+	init.parent_names = (const char* []) { parent_name };
+	init.num_parents = 1;
+	init.flags = 0;
+
+	peci_clk = devm_kzalloc(dev, sizeof(struct clk_aspeed_peci), GFP_KERNEL);
+	if (!peci_clk)
+		return ERR_PTR(-ENOMEM);
+
+	peci_clk->hw.init = &init;
+	peci_clk->aspeed_peci = priv;
+
+	ret = devm_clk_hw_register(dev, &peci_clk->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return peci_clk->hw.clk;
+}
+
+static void aspeed_peci_property_sanitize(struct device *dev, const char *propname,
+					  u32 min, u32 max, u32 default_val, u32 *propval)
+{
+	u32 val;
+	int ret;
+
+	ret = device_property_read_u32(dev, propname, &val);
+	if (ret) {
+		val = default_val;
+	} else if (val > max || val < min) {
+		dev_warn(dev, "invalid %s: %u, falling back to: %u\n",
+			 propname, val, default_val);
+
+		val = default_val;
+	}
+
+	*propval = val;
+}
+
+static void aspeed_peci_property_setup(struct aspeed_peci *priv)
+{
+	aspeed_peci_property_sanitize(priv->dev, "clock-frequency",
+				      ASPEED_PECI_CLK_FREQUENCY_MIN, ASPEED_PECI_CLK_FREQUENCY_MAX,
+				      ASPEED_PECI_CLK_FREQUENCY_DEFAULT, &priv->clk_frequency);
+	aspeed_peci_property_sanitize(priv->dev, "cmd-timeout-ms",
+				      1, ASPEED_PECI_CMD_TIMEOUT_MS_MAX,
+				      ASPEED_PECI_CMD_TIMEOUT_MS_DEFAULT, &priv->cmd_timeout_ms);
+}
+
+static struct peci_controller_ops aspeed_ops = {
+	.xfer = aspeed_peci_xfer,
+};
+
+static void aspeed_peci_reset_control_release(void *data)
+{
+	reset_control_assert(data);
+}
+
+static int devm_aspeed_peci_reset_control_deassert(struct device *dev, struct reset_control *rst)
+{
+	int ret;
+
+	ret = reset_control_deassert(rst);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_reset_control_release, rst);
+}
+
+static void aspeed_peci_clk_release(void *data)
+{
+	clk_disable_unprepare(data);
+}
+
+static int devm_aspeed_peci_clk_enable(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = clk_prepare_enable(clk);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, aspeed_peci_clk_release, clk);
+}
+
+static int aspeed_peci_probe(struct platform_device *pdev)
+{
+	struct peci_controller *controller;
+	struct aspeed_peci *priv;
+	struct clk *ref_clk;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+	dev_set_drvdata(priv->dev, priv);
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	priv->irq = platform_get_irq(pdev, 0);
+	if (!priv->irq)
+		return priv->irq;
+
+	ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
+			       0, "peci-aspeed", priv);
+	if (ret)
+		return ret;
+
+	init_completion(&priv->xfer_complete);
+	spin_lock_init(&priv->lock);
+
+	priv->rst = devm_reset_control_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->rst))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->rst),
+				     "failed to get reset control\n");
+
+	ret = devm_aspeed_peci_reset_control_deassert(priv->dev, priv->rst);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "cannot deassert reset control\n");
+
+	aspeed_peci_property_setup(priv);
+
+	aspeed_peci_init_regs(priv);
+
+	ref_clk = devm_clk_get(priv->dev, NULL);
+	if (IS_ERR(ref_clk))
+		return dev_err_probe(priv->dev, PTR_ERR(ref_clk), "failed to get ref clock\n");
+
+	priv->clk = devm_aspeed_peci_register_clk_div(priv->dev, ref_clk, priv);
+	if (IS_ERR(priv->clk))
+		return dev_err_probe(priv->dev, PTR_ERR(priv->clk), "cannot register clock\n");
+
+	ret = clk_set_rate(priv->clk, priv->clk_frequency);
+	if (ret < 0)
+		return dev_err_probe(priv->dev, ret, "cannot set clock frequency\n");
+
+	ret = devm_aspeed_peci_clk_enable(priv->dev, priv->clk);
+	if (ret)
+		return dev_err_probe(priv->dev, ret, "failed to enable clock\n");
+
+	aspeed_peci_controller_enable(priv);
+
+	controller = devm_peci_controller_add(priv->dev, &aspeed_ops);
+	if (IS_ERR(controller))
+		return dev_err_probe(priv->dev, PTR_ERR(controller),
+				     "failed to add aspeed peci controller\n");
+
+	priv->controller = controller;
+
+	return 0;
+}
+
+static const struct of_device_id aspeed_peci_of_table[] = {
+	{ .compatible = "aspeed,ast2400-peci", },
+	{ .compatible = "aspeed,ast2500-peci", },
+	{ .compatible = "aspeed,ast2600-peci", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, aspeed_peci_of_table);
+
+static struct platform_driver aspeed_peci_driver = {
+	.probe  = aspeed_peci_probe,
+	.driver = {
+		.name           = "peci-aspeed",
+		.of_match_table = aspeed_peci_of_table,
+	},
+};
+module_platform_driver(aspeed_peci_driver);
+
+MODULE_AUTHOR("Ryan Chen <ryan_chen at aspeedtech.com>");
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_DESCRIPTION("ASPEED PECI driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:57 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:57 +0100
Subject: [PATCH v6 06/13] peci: Add device detection
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-7-iwona.winiarska@intel.com>

Since PECI devices are discoverable, we can dynamically detect devices
that are actually available in the system.

This change complements the earlier implementation by rescanning PECI
bus to detect available devices. For this purpose, it also introduces the
minimal API for PECI requests.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/Makefile   |   2 +-
 drivers/peci/core.c     |  33 +++++++++++
 drivers/peci/device.c   | 120 ++++++++++++++++++++++++++++++++++++++++
 drivers/peci/internal.h |  14 +++++
 drivers/peci/request.c  |  55 ++++++++++++++++++
 include/linux/peci.h    |   2 +
 6 files changed, 225 insertions(+), 1 deletion(-)
 create mode 100644 drivers/peci/device.c
 create mode 100644 drivers/peci/request.c

diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 926d8df15cbd..c5f9d3fe21bb 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o
+peci-y := core.o request.o device.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index 73ad0a47fa9d..c3361e6e043a 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,6 +29,20 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
+static int peci_controller_scan_devices(struct peci_controller *controller)
+{
+	int ret;
+	u8 addr;
+
+	for (addr = PECI_BASE_ADDR; addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX; addr++) {
+		ret = peci_device_create(controller, addr);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static struct peci_controller *peci_controller_alloc(struct device *dev,
 						     struct peci_controller_ops *ops)
 {
@@ -64,10 +78,23 @@ static struct peci_controller *peci_controller_alloc(struct device *dev,
 	return ERR_PTR(ret);
 }
 
+static int unregister_child(struct device *dev, void *dummy)
+{
+	peci_device_destroy(to_peci_device(dev));
+
+	return 0;
+}
+
 static void unregister_controller(void *_controller)
 {
 	struct peci_controller *controller = _controller;
 
+	/*
+	 * Detach any active PECI devices. This can't fail, thus we do not
+	 * check the returned value.
+	 */
+	device_for_each_child_reverse(&controller->dev, NULL, unregister_child);
+
 	device_unregister(&controller->dev);
 
 	fwnode_handle_put(controller->dev.fwnode);
@@ -113,6 +140,12 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 	if (ret)
 		return ERR_PTR(ret);
 
+	/*
+	 * Ignoring retval since failures during scan are non-critical for
+	 * controller itself.
+	 */
+	peci_controller_scan_devices(controller);
+
 	return controller;
 
 err_fwnode:
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
new file mode 100644
index 000000000000..2b3a2d893aaf
--- /dev/null
+++ b/drivers/peci/device.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/peci.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+/*
+ * PECI device can be removed using sysfs, but the removal can also happen as
+ * a result of controller being removed.
+ * Mutex is used to protect PECI device from being double-deleted.
+ */
+static DEFINE_MUTEX(peci_device_del_lock);
+
+static int peci_detect(struct peci_controller *controller, u8 addr)
+{
+	/*
+	 * PECI Ping is a command encoded by tx_len = 0, rx_len = 0.
+	 * We expect correct Write FCS if the device at the target address
+	 * is able to respond.
+	 */
+	struct peci_request req = { 0 };
+	int ret;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, addr, &req);
+	mutex_unlock(&controller->bus_lock);
+
+	return ret;
+}
+
+static bool peci_addr_valid(u8 addr)
+{
+	return addr >= PECI_BASE_ADDR && addr < PECI_BASE_ADDR + PECI_DEVICE_NUM_MAX;
+}
+
+static int peci_dev_exists(struct device *dev, void *data)
+{
+	struct peci_device *device = to_peci_device(dev);
+	u8 *addr = data;
+
+	if (device->addr == *addr)
+		return -EBUSY;
+
+	return 0;
+}
+
+int peci_device_create(struct peci_controller *controller, u8 addr)
+{
+	struct peci_device *device;
+	int ret;
+
+	if (!peci_addr_valid(addr))
+		return -EINVAL;
+
+	/* Check if we have already detected this device before. */
+	ret = device_for_each_child(&controller->dev, &addr, peci_dev_exists);
+	if (ret)
+		return 0;
+
+	ret = peci_detect(controller, addr);
+	if (ret) {
+		/*
+		 * Device not present or host state doesn't allow successful
+		 * detection at this time.
+		 */
+		if (ret == -EIO || ret == -ETIMEDOUT)
+			return 0;
+
+		return ret;
+	}
+
+	device = kzalloc(sizeof(*device), GFP_KERNEL);
+	if (!device)
+		return -ENOMEM;
+
+	device_initialize(&device->dev);
+
+	device->addr = addr;
+	device->dev.parent = &controller->dev;
+	device->dev.bus = &peci_bus_type;
+	device->dev.type = &peci_device_type;
+
+	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
+	if (ret)
+		goto err_put;
+
+	ret = device_add(&device->dev);
+	if (ret)
+		goto err_put;
+
+	return 0;
+
+err_put:
+	put_device(&device->dev);
+
+	return ret;
+}
+
+void peci_device_destroy(struct peci_device *device)
+{
+	mutex_lock(&peci_device_del_lock);
+	if (!device->deleted) {
+		device_unregister(&device->dev);
+		device->deleted = true;
+	}
+	mutex_unlock(&peci_device_del_lock);
+}
+
+static void peci_device_release(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+
+	kfree(device);
+}
+
+struct device_type peci_device_type = {
+	.release	= peci_device_release,
+};
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 918dea745a86..57d11a902c5d 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,20 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct peci_device;
+struct peci_request;
+
+/* PECI CPU address range 0x30-0x37 */
+#define PECI_BASE_ADDR		0x30
+#define PECI_DEVICE_NUM_MAX	8
+
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
+void peci_request_free(struct peci_request *req);
+
+extern struct device_type peci_device_type;
+
+int peci_device_create(struct peci_controller *controller, u8 addr);
+void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
 
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
new file mode 100644
index 000000000000..7dee51c50dd2
--- /dev/null
+++ b/drivers/peci/request.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/export.h>
+#include <linux/peci.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "internal.h"
+
+/**
+ * peci_request_alloc() - allocate &struct peci_requests
+ * @device: PECI device to which request is going to be sent
+ * @tx_len: TX length
+ * @rx_len: RX length
+ *
+ * Return: A pointer to a newly allocated &struct peci_request on success or NULL otherwise.
+ */
+struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len)
+{
+	struct peci_request *req;
+
+	/*
+	 * TX and RX buffers are fixed length members of peci_request, this is
+	 * just a warn for developers to make sure to expand the buffers (or
+	 * change the allocation method) if we go over the current limit.
+	 */
+	if (WARN_ON_ONCE(tx_len > PECI_REQUEST_MAX_BUF_SIZE || rx_len > PECI_REQUEST_MAX_BUF_SIZE))
+		return NULL;
+	/*
+	 * PECI controllers that we are using now don't support DMA, this
+	 * should be converted to DMA API once support for controllers that do
+	 * allow it is added to avoid an extra copy.
+	 */
+	req = kzalloc(sizeof(*req), GFP_KERNEL);
+	if (!req)
+		return NULL;
+
+	req->device = device;
+	req->tx.len = tx_len;
+	req->rx.len = rx_len;
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_alloc, PECI);
+
+/**
+ * peci_request_free() - free peci_request
+ * @req: the PECI request to be freed
+ */
+void peci_request_free(struct peci_request *req)
+{
+	kfree(req);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 26e0a4e73b50..7e35673f3786 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -60,6 +60,7 @@ static inline struct peci_controller *to_peci_controller(void *d)
  * @dev: device object to register PECI device to the device model
  * @controller: manages the bus segment hosting this PECI device
  * @addr: address used on the PECI bus connected to the parent controller
+ * @deleted: indicates that PECI device was already deleted
  *
  * A peci_device identifies a single device (i.e. CPU) connected to a PECI bus.
  * The behaviour exposed to the rest of the system is defined by the PECI driver
@@ -68,6 +69,7 @@ static inline struct peci_controller *to_peci_controller(void *d)
 struct peci_device {
 	struct device dev;
 	u8 addr;
+	bool deleted;
 };
 
 static inline struct peci_device *to_peci_device(struct device *d)
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:58 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:58 +0100
Subject: [PATCH v6 07/13] peci: Add sysfs interface for PECI bus
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-8-iwona.winiarska@intel.com>

PECI devices may not be discoverable at the time when PECI controller is
being added (e.g. BMC can boot up when the Host system is still in S5).
Since we currently don't have the capabilities to figure out the Host
system state inside the PECI subsystem itself, we have to rely on
userspace to do it for us.

In the future, PECI subsystem may be expanded with mechanisms that allow
us to avoid depending on userspace interaction (e.g. CPU presence could
be detected using GPIO, and the information on whether it's discoverable
could be obtained over IPMI).
Unfortunately, those methods may ultimately not be available (support
will vary from platform to platform), which means that we still need
platform independent method triggered by userspace.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
---
 Documentation/ABI/testing/sysfs-bus-peci | 16 +++++
 drivers/peci/Makefile                    |  2 +-
 drivers/peci/core.c                      |  3 +-
 drivers/peci/device.c                    |  1 +
 drivers/peci/internal.h                  |  5 ++
 drivers/peci/sysfs.c                     | 82 ++++++++++++++++++++++++
 6 files changed, 107 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-peci
 create mode 100644 drivers/peci/sysfs.c

diff --git a/Documentation/ABI/testing/sysfs-bus-peci b/Documentation/ABI/testing/sysfs-bus-peci
new file mode 100644
index 000000000000..56c2b2216bbd
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-peci
@@ -0,0 +1,16 @@
+What:		/sys/bus/peci/rescan
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		initiate scan for PECI devices on all PECI controllers
+		in the system.
+
+What:		/sys/bus/peci/devices/<controller_id>-<device_addr>/remove
+Date:		July 2021
+KernelVersion:	5.15
+Contact:	Iwona Winiarska <iwona.winiarska at intel.com>
+Description:
+		Writing a non-zero value to this attribute will
+		remove the PECI device and any of its children.
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index c5f9d3fe21bb..917f689e147a 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 # Core functionality
-peci-y := core.o request.o device.o
+peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
 
 # Hardware specific bus drivers
diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index c3361e6e043a..e993615cf521 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -29,7 +29,7 @@ struct device_type peci_controller_type = {
 	.release	= peci_controller_dev_release,
 };
 
-static int peci_controller_scan_devices(struct peci_controller *controller)
+int peci_controller_scan_devices(struct peci_controller *controller)
 {
 	int ret;
 	u8 addr;
@@ -162,6 +162,7 @@ EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.bus_groups	= peci_bus_groups,
 };
 
 static int __init peci_init(void)
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 2b3a2d893aaf..d10ed1cfcd48 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -116,5 +116,6 @@ static void peci_device_release(struct device *dev)
 }
 
 struct device_type peci_device_type = {
+	.groups		= peci_device_groups,
 	.release	= peci_device_release,
 };
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 57d11a902c5d..978e12c8e1d3 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 
 struct peci_controller;
+struct attribute_group;
 struct peci_device;
 struct peci_request;
 
@@ -19,12 +20,16 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u
 void peci_request_free(struct peci_request *req);
 
 extern struct device_type peci_device_type;
+extern const struct attribute_group *peci_device_groups[];
 
 int peci_device_create(struct peci_controller *controller, u8 addr);
 void peci_device_destroy(struct peci_device *device);
 
 extern struct bus_type peci_bus_type;
+extern const struct attribute_group *peci_bus_groups[];
 
 extern struct device_type peci_controller_type;
 
+int peci_controller_scan_devices(struct peci_controller *controller);
+
 #endif /* __PECI_INTERNAL_H */
diff --git a/drivers/peci/sysfs.c b/drivers/peci/sysfs.c
new file mode 100644
index 000000000000..db9ef05776e3
--- /dev/null
+++ b/drivers/peci/sysfs.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/peci.h>
+
+#include "internal.h"
+
+static int rescan_controller(struct device *dev, void *data)
+{
+	if (dev->type != &peci_controller_type)
+		return 0;
+
+	return peci_controller_scan_devices(to_peci_controller(dev));
+}
+
+static ssize_t rescan_store(struct bus_type *bus, const char *buf, size_t count)
+{
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (!res)
+		return count;
+
+	ret = bus_for_each_dev(&peci_bus_type, NULL, NULL, rescan_controller);
+	if (ret)
+		return ret;
+
+	return count;
+}
+static BUS_ATTR_WO(rescan);
+
+static struct attribute *peci_bus_attrs[] = {
+	&bus_attr_rescan.attr,
+	NULL
+};
+
+static const struct attribute_group peci_bus_group = {
+	.attrs = peci_bus_attrs,
+};
+
+const struct attribute_group *peci_bus_groups[] = {
+	&peci_bus_group,
+	NULL
+};
+
+static ssize_t remove_store(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct peci_device *device = to_peci_device(dev);
+	bool res;
+	int ret;
+
+	ret = kstrtobool(buf, &res);
+	if (ret)
+		return ret;
+
+	if (res && device_remove_file_self(dev, attr))
+		peci_device_destroy(device);
+
+	return count;
+}
+static DEVICE_ATTR_IGNORE_LOCKDEP(remove, 0200, NULL, remove_store);
+
+static struct attribute *peci_device_attrs[] = {
+	&dev_attr_remove.attr,
+	NULL
+};
+
+static const struct attribute_group peci_device_group = {
+	.attrs = peci_device_attrs,
+};
+
+const struct attribute_group *peci_device_groups[] = {
+	&peci_device_group,
+	NULL
+};
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:10:59 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:10:59 +0100
Subject: [PATCH v6 08/13] peci: Add support for PECI device drivers
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-9-iwona.winiarska@intel.com>

Add support for PECI device drivers, which unlike PECI controller
drivers are actually able to provide functionalities to userspace.

Also, extend peci_request API to allow querying more details about PECI
device (e.g. model/family), that's going to be used to find a compatible
peci_driver.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 drivers/peci/core.c     |  44 +++++++++
 drivers/peci/device.c   | 130 ++++++++++++++++++++++++
 drivers/peci/internal.h |  74 ++++++++++++++
 drivers/peci/request.c  | 214 ++++++++++++++++++++++++++++++++++++++++
 include/linux/peci.h    |  19 ++++
 5 files changed, 481 insertions(+)

diff --git a/drivers/peci/core.c b/drivers/peci/core.c
index e993615cf521..9c8cf07e51c7 100644
--- a/drivers/peci/core.c
+++ b/drivers/peci/core.c
@@ -160,8 +160,52 @@ struct peci_controller *devm_peci_controller_add(struct device *dev,
 }
 EXPORT_SYMBOL_NS_GPL(devm_peci_controller_add, PECI);
 
+static const struct peci_device_id *
+peci_bus_match_device_id(const struct peci_device_id *id, struct peci_device *device)
+{
+	while (id->family != 0) {
+		if (id->family == device->info.family &&
+		    id->model == device->info.model)
+			return id;
+		id++;
+	}
+
+	return NULL;
+}
+
+static int peci_bus_device_match(struct device *dev, struct device_driver *drv)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *peci_drv = to_peci_driver(drv);
+
+	if (dev->type != &peci_device_type)
+		return 0;
+
+	return !!peci_bus_match_device_id(peci_drv->id_table, device);
+}
+
+static int peci_bus_device_probe(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	return driver->probe(device, peci_bus_match_device_id(driver->id_table, device));
+}
+
+static void peci_bus_device_remove(struct device *dev)
+{
+	struct peci_device *device = to_peci_device(dev);
+	struct peci_driver *driver = to_peci_driver(dev->driver);
+
+	if (driver->remove)
+		driver->remove(device);
+}
+
 struct bus_type peci_bus_type = {
 	.name		= "peci",
+	.match		= peci_bus_device_match,
+	.probe		= peci_bus_device_probe,
+	.remove		= peci_bus_device_remove,
 	.bus_groups	= peci_bus_groups,
 };
 
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index d10ed1cfcd48..184b5e650b0b 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2018-2021 Intel Corporation
 
+#include <linux/bitfield.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 
@@ -13,6 +14,104 @@
  */
 static DEFINE_MUTEX(peci_device_del_lock);
 
+#define REVISION_NUM_MASK GENMASK(15, 8)
+static int peci_get_revision(struct peci_device *device, u8 *revision)
+{
+	struct peci_request *req;
+	u64 dib;
+
+	req = peci_xfer_get_dib(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	/*
+	 * PECI device may be in a state where it is unable to return a proper
+	 * DIB, in which case it returns 0 as DIB value.
+	 * Let's treat this as an error to avoid carrying on with the detection
+	 * using invalid revision.
+	 */
+	dib = peci_request_dib_read(req);
+	if (dib == 0) {
+		peci_request_free(req);
+		return -EIO;
+	}
+
+	*revision = FIELD_GET(REVISION_NUM_MASK, dib);
+
+	peci_request_free(req);
+
+	return 0;
+}
+
+static int peci_get_cpu_id(struct peci_device *device, u32 *cpu_id)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pkg_cfg_readl(device, PECI_PCS_PKG_ID, PECI_PKG_ID_CPU_ID);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*cpu_id = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+
+static unsigned int peci_x86_cpu_family(unsigned int sig)
+{
+	unsigned int x86;
+
+	x86 = (sig >> 8) & 0xf;
+
+	if (x86 == 0xf)
+		x86 += (sig >> 20) & 0xff;
+
+	return x86;
+}
+
+static unsigned int peci_x86_cpu_model(unsigned int sig)
+{
+	unsigned int fam, model;
+
+	fam = peci_x86_cpu_family(sig);
+
+	model = (sig >> 4) & 0xf;
+
+	if (fam >= 0x6)
+		model += ((sig >> 16) & 0xf) << 4;
+
+	return model;
+}
+
+static int peci_device_info_init(struct peci_device *device)
+{
+	u8 revision;
+	u32 cpu_id;
+	int ret;
+
+	ret = peci_get_cpu_id(device, &cpu_id);
+	if (ret)
+		return ret;
+
+	device->info.family = peci_x86_cpu_family(cpu_id);
+	device->info.model = peci_x86_cpu_model(cpu_id);
+
+	ret = peci_get_revision(device, &revision);
+	if (ret)
+		return ret;
+	device->info.peci_revision = revision;
+
+	device->info.socket_id = device->addr - PECI_BASE_ADDR;
+
+	return 0;
+}
+
 static int peci_detect(struct peci_controller *controller, u8 addr)
 {
 	/*
@@ -82,6 +181,10 @@ int peci_device_create(struct peci_controller *controller, u8 addr)
 	device->dev.bus = &peci_bus_type;
 	device->dev.type = &peci_device_type;
 
+	ret = peci_device_info_init(device);
+	if (ret)
+		goto err_put;
+
 	ret = dev_set_name(&device->dev, "%d-%02x", controller->id, device->addr);
 	if (ret)
 		goto err_put;
@@ -108,6 +211,33 @@ void peci_device_destroy(struct peci_device *device)
 	mutex_unlock(&peci_device_del_lock);
 }
 
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name)
+{
+	driver->driver.bus = &peci_bus_type;
+	driver->driver.owner = owner;
+	driver->driver.mod_name = mod_name;
+
+	if (!driver->probe) {
+		pr_err("peci: trying to register driver without probe callback\n");
+		return -EINVAL;
+	}
+
+	if (!driver->id_table) {
+		pr_err("peci: trying to register driver without device id table\n");
+		return -EINVAL;
+	}
+
+	return driver_register(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(__peci_driver_register, PECI);
+
+void peci_driver_unregister(struct peci_driver *driver)
+{
+	driver_unregister(&driver->driver);
+}
+EXPORT_SYMBOL_NS_GPL(peci_driver_unregister, PECI);
+
 static void peci_device_release(struct device *dev)
 {
 	struct peci_device *device = to_peci_device(dev);
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 978e12c8e1d3..52c02e12874f 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -19,6 +19,35 @@ struct peci_request;
 struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u8 rx_len);
 void peci_request_free(struct peci_request *req);
 
+int peci_request_status(struct peci_request *req);
+
+u64 peci_request_dib_read(struct peci_request *req);
+
+u8 peci_request_data_readb(struct peci_request *req);
+u16 peci_request_data_readw(struct peci_request *req);
+u32 peci_request_data_readl(struct peci_request *req);
+u64 peci_request_data_readq(struct peci_request *req);
+
+struct peci_request *peci_xfer_get_dib(struct peci_device *device);
+struct peci_request *peci_xfer_get_temp(struct peci_device *device);
+
+struct peci_request *peci_xfer_pkg_cfg_readb(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readw(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
+struct peci_request *peci_xfer_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
+
+/**
+ * struct peci_device_id - PECI device data to match
+ * @data: pointer to driver private data specific to device
+ * @family: device family
+ * @model: device model
+ */
+struct peci_device_id {
+	const void *data;
+	u16 family;
+	u8 model;
+};
+
 extern struct device_type peci_device_type;
 extern const struct attribute_group *peci_device_groups[];
 
@@ -28,6 +57,51 @@ void peci_device_destroy(struct peci_device *device);
 extern struct bus_type peci_bus_type;
 extern const struct attribute_group *peci_bus_groups[];
 
+/**
+ * struct peci_driver - PECI driver
+ * @driver: inherit device driver
+ * @probe: probe callback
+ * @remove: remove callback
+ * @id_table: PECI device match table to decide which device to bind
+ */
+struct peci_driver {
+	struct device_driver driver;
+	int (*probe)(struct peci_device *device, const struct peci_device_id *id);
+	void (*remove)(struct peci_device *device);
+	const struct peci_device_id *id_table;
+};
+
+static inline struct peci_driver *to_peci_driver(struct device_driver *d)
+{
+	return container_of(d, struct peci_driver, driver);
+}
+
+int __peci_driver_register(struct peci_driver *driver, struct module *owner,
+			   const char *mod_name);
+/**
+ * peci_driver_register() - register PECI driver
+ * @driver: the driver to be registered
+ *
+ * PECI drivers that don't need to do anything special in module init should
+ * use the convenience "module_peci_driver" macro instead
+ *
+ * Return: zero on success, else a negative error code.
+ */
+#define peci_driver_register(driver) \
+	__peci_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
+void peci_driver_unregister(struct peci_driver *driver);
+
+/**
+ * module_peci_driver() - helper macro for registering a modular PECI driver
+ * @__peci_driver: peci_driver struct
+ *
+ * Helper macro for PECI drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+#define module_peci_driver(__peci_driver) \
+	module_driver(__peci_driver, peci_driver_register, peci_driver_unregister)
+
 extern struct device_type peci_controller_type;
 
 int peci_controller_scan_devices(struct peci_controller *controller);
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index 7dee51c50dd2..a49eb351cda3 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -1,13 +1,140 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // Copyright (c) 2021 Intel Corporation
 
+#include <linux/bug.h>
 #include <linux/export.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include <asm/unaligned.h>
+
 #include "internal.h"
 
+#define PECI_GET_DIB_CMD		0xf7
+#define  PECI_GET_DIB_WR_LEN		1
+#define  PECI_GET_DIB_RD_LEN		8
+
+#define PECI_RDPKGCFG_CMD		0xa1
+#define  PECI_RDPKGCFG_WR_LEN		5
+#define  PECI_RDPKGCFG_RD_LEN_BASE	1
+#define PECI_WRPKGCFG_CMD		0xa5
+#define  PECI_WRPKGCFG_WR_LEN_BASE	6
+#define  PECI_WRPKGCFG_RD_LEN		1
+
+/* Device Specific Completion Code (CC) Definition */
+#define PECI_CC_SUCCESS				0x40
+#define PECI_CC_NEED_RETRY			0x80
+#define PECI_CC_OUT_OF_RESOURCE			0x81
+#define PECI_CC_UNAVAIL_RESOURCE		0x82
+#define PECI_CC_INVALID_REQ			0x90
+#define PECI_CC_MCA_ERROR			0x91
+#define PECI_CC_CATASTROPHIC_MCA_ERROR		0x93
+#define PECI_CC_FATAL_MCA_ERROR			0x94
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB		0x98
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR	0x9B
+#define PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA	0x9C
+
+#define PECI_RETRY_BIT			BIT(0)
+
+#define PECI_RETRY_TIMEOUT		msecs_to_jiffies(700)
+#define PECI_RETRY_INTERVAL_MIN		msecs_to_jiffies(1)
+#define PECI_RETRY_INTERVAL_MAX		msecs_to_jiffies(128)
+
+static u8 peci_request_data_cc(struct peci_request *req)
+{
+	return req->rx.buf[0];
+}
+
+/**
+ * peci_request_status() - return -errno based on PECI completion code
+ * @req: the PECI request that contains response data with completion code
+ *
+ * It can't be used for Ping(), GetDIB() and GetTemp() - for those commands we
+ * don't expect completion code in the response.
+ *
+ * Return: -errno
+ */
+int peci_request_status(struct peci_request *req)
+{
+	u8 cc = peci_request_data_cc(req);
+
+	if (cc != PECI_CC_SUCCESS)
+		dev_dbg(&req->device->dev, "ret: %#02x\n", cc);
+
+	switch (cc) {
+	case PECI_CC_SUCCESS:
+		return 0;
+	case PECI_CC_NEED_RETRY:
+	case PECI_CC_OUT_OF_RESOURCE:
+	case PECI_CC_UNAVAIL_RESOURCE:
+		return -EAGAIN;
+	case PECI_CC_INVALID_REQ:
+		return -EINVAL;
+	case PECI_CC_MCA_ERROR:
+	case PECI_CC_CATASTROPHIC_MCA_ERROR:
+	case PECI_CC_FATAL_MCA_ERROR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_IERR:
+	case PECI_CC_PARITY_ERR_GPSB_OR_PMSB_MCA:
+		return -EIO;
+	}
+
+	WARN_ONCE(1, "Unknown PECI completion code: %#02x\n", cc);
+
+	return -EIO;
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_status, PECI);
+
+static int peci_request_xfer(struct peci_request *req)
+{
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	int ret;
+
+	mutex_lock(&controller->bus_lock);
+	ret = controller->ops->xfer(controller, device->addr, req);
+	mutex_unlock(&controller->bus_lock);
+
+	return ret;
+}
+
+static int peci_request_xfer_retry(struct peci_request *req)
+{
+	long wait_interval = PECI_RETRY_INTERVAL_MIN;
+	struct peci_device *device = req->device;
+	struct peci_controller *controller = to_peci_controller(device->dev.parent);
+	unsigned long start = jiffies;
+	int ret;
+
+	/* Don't try to use it for ping */
+	if (WARN_ON(req->tx.len == 0))
+		return 0;
+
+	do {
+		ret = peci_request_xfer(req);
+		if (ret) {
+			dev_dbg(&controller->dev, "xfer error: %d\n", ret);
+			return ret;
+		}
+
+		if (peci_request_status(req) != -EAGAIN)
+			return 0;
+
+		/* Set the retry bit to indicate a retry attempt */
+		req->tx.buf[1] |= PECI_RETRY_BIT;
+
+		if (schedule_timeout_interruptible(wait_interval))
+			return -ERESTARTSYS;
+
+		wait_interval = min_t(long, wait_interval * 2, PECI_RETRY_INTERVAL_MAX);
+	} while (time_before(jiffies, start + PECI_RETRY_TIMEOUT));
+
+	dev_dbg(&controller->dev, "request timed out\n");
+
+	return -ETIMEDOUT;
+}
+
 /**
  * peci_request_alloc() - allocate &struct peci_requests
  * @device: PECI device to which request is going to be sent
@@ -53,3 +180,90 @@ void peci_request_free(struct peci_request *req)
 	kfree(req);
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_free, PECI);
+
+struct peci_request *peci_xfer_get_dib(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_DIB_WR_LEN, PECI_GET_DIB_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_DIB_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, PECI);
+
+static struct peci_request *
+__pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPKGCFG_WR_LEN, PECI_RDPKGCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDPKGCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = index;
+	put_unaligned_le16(param, &req->tx.buf[3]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+u8 peci_request_data_readb(struct peci_request *req)
+{
+	return req->rx.buf[1];
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readb, PECI);
+
+u16 peci_request_data_readw(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readw, PECI);
+
+u32 peci_request_data_readl(struct peci_request *req)
+{
+	return get_unaligned_le32(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readl, PECI);
+
+u64 peci_request_data_readq(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[1]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_data_readq, PECI);
+
+u64 peci_request_dib_read(struct peci_request *req)
+{
+	return get_unaligned_le64(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, PECI);
+
+#define __read_pkg_config(x, type) \
+struct peci_request *peci_xfer_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
+{ \
+	return __pkg_cfg_read(device, index, param, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_pkg_cfg_##x, PECI)
+
+__read_pkg_config(readb, u8);
+__read_pkg_config(readw, u16);
+__read_pkg_config(readl, u32);
+__read_pkg_config(readq, u64);
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 7e35673f3786..4eda423ba10c 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,6 +14,14 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+
 struct peci_controller;
 struct peci_request;
 
@@ -59,6 +67,11 @@ static inline struct peci_controller *to_peci_controller(void *d)
  * struct peci_device - PECI device
  * @dev: device object to register PECI device to the device model
  * @controller: manages the bus segment hosting this PECI device
+ * @info: PECI device characteristics
+ * @info.family: device family
+ * @info.model: device model
+ * @info.peci_revision: PECI revision supported by the PECI device
+ * @info.socket_id: the socket ID represented by the PECI device
  * @addr: address used on the PECI bus connected to the parent controller
  * @deleted: indicates that PECI device was already deleted
  *
@@ -68,6 +81,12 @@ static inline struct peci_controller *to_peci_controller(void *d)
  */
 struct peci_device {
 	struct device dev;
+	struct {
+		u16 family;
+		u8 model;
+		u8 peci_revision;
+		u8 socket_id;
+	} info;
 	u8 addr;
 	bool deleted;
 };
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:11:00 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:11:00 +0100
Subject: [PATCH v6 09/13] peci: Add peci-cpu driver
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-10-iwona.winiarska@intel.com>

PECI is an interface that may be used by different types of devices.
Add a peci-cpu driver compatible with Intel processors. The driver is
responsible for handling auxiliary devices that can subsequently be used
by other drivers (e.g. hwmons).

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 MAINTAINERS              |   1 +
 drivers/peci/Kconfig     |  15 ++
 drivers/peci/Makefile    |   2 +
 drivers/peci/cpu.c       | 343 +++++++++++++++++++++++++++++++++++++++
 drivers/peci/device.c    |   1 +
 drivers/peci/internal.h  |  27 +++
 drivers/peci/request.c   | 213 ++++++++++++++++++++++++
 include/linux/peci-cpu.h |  40 +++++
 include/linux/peci.h     |   8 -
 9 files changed, 642 insertions(+), 8 deletions(-)
 create mode 100644 drivers/peci/cpu.c
 create mode 100644 include/linux/peci-cpu.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6c9b12004e4e..7c31e29c885a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15105,6 +15105,7 @@ L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
 F:	drivers/peci/
+F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
 
 PENSANDO ETHERNET DRIVERS
diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig
index 99279df97a78..89872ad83320 100644
--- a/drivers/peci/Kconfig
+++ b/drivers/peci/Kconfig
@@ -16,6 +16,21 @@ menuconfig PECI
 
 if PECI
 
+config PECI_CPU
+	tristate "PECI CPU"
+	select AUXILIARY_BUS
+	help
+	  This option enables peci-cpu driver for Intel processors. It is
+	  responsible for creating auxiliary devices that can subsequently
+	  be used by other drivers in order to perform various
+	  functionalities such as e.g. temperature monitoring.
+
+	  Additional drivers must be enabled in order to use the functionality
+	  of the device.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cpu.
+
 source "drivers/peci/controller/Kconfig"
 
 endif # PECI
diff --git a/drivers/peci/Makefile b/drivers/peci/Makefile
index 917f689e147a..7de18137e738 100644
--- a/drivers/peci/Makefile
+++ b/drivers/peci/Makefile
@@ -3,6 +3,8 @@
 # Core functionality
 peci-y := core.o request.o device.o sysfs.o
 obj-$(CONFIG_PECI) += peci.o
+peci-cpu-y := cpu.o
+obj-$(CONFIG_PECI_CPU) += peci-cpu.o
 
 # Hardware specific bus drivers
 obj-y += controller/
diff --git a/drivers/peci/cpu.c b/drivers/peci/cpu.c
new file mode 100644
index 000000000000..68eb61c65d34
--- /dev/null
+++ b/drivers/peci/cpu.c
@@ -0,0 +1,343 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/slab.h>
+
+#include "internal.h"
+
+/**
+ * peci_temp_read() - read the maximum die temperature from PECI target device
+ * @device: PECI device to which request is going to be sent
+ * @temp_raw: where to store the read temperature
+ *
+ * It uses GetTemp PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_temp_read(struct peci_device *device, s16 *temp_raw)
+{
+	struct peci_request *req;
+
+	req = peci_xfer_get_temp(device);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	*temp_raw = peci_request_temp_read(req);
+
+	peci_request_free(req);
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(peci_temp_read, PECI_CPU);
+
+/**
+ * peci_pcs_read() - read PCS register
+ * @device: PECI device to which request is going to be sent
+ * @index: PCS index
+ * @param: PCS parameter
+ * @data: where to store the read data
+ *
+ * It uses RdPkgConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pcs_read(struct peci_device *device, u8 index, u16 param, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pkg_cfg_readl(device, index, param);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pcs_read, PECI_CPU);
+
+/**
+ * peci_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * It uses RdPCIConfigLocal PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func,
+			u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_pci_cfg_local_readl(device, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_pci_local_read, PECI_CPU);
+
+/**
+ * peci_ep_pci_local_read() - read 32-bit memory location using raw address
+ * @device: PECI device to which request is going to be sent
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @reg: register
+ * @data: where to store the read data
+ *
+ * Like &peci_pci_local_read, but it uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_ep_pci_cfg_local_readl(device, seg, bus, dev, func, reg);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_ep_pci_local_read, PECI_CPU);
+
+/**
+ * peci_mmio_read() - read 32-bit memory location using 64-bit bar offset address
+ * @device: PECI device to which request is going to be sent
+ * @bar: PCI bar
+ * @seg: PCI segment
+ * @bus: bus
+ * @dev: device
+ * @func: function
+ * @address: 64-bit MMIO address
+ * @data: where to store the read data
+ *
+ * It uses RdEndpointConfig PECI command.
+ *
+ * Return: 0 if succeeded, other values in case errors.
+ */
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_xfer_ep_mmio64_readl(device, bar, seg, bus, dev, func, address);
+	if (IS_ERR(req))
+		return PTR_ERR(req);
+
+	ret = peci_request_status(req);
+	if (ret)
+		goto out_req_free;
+
+	*data = peci_request_data_readl(req);
+out_req_free:
+	peci_request_free(req);
+
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(peci_mmio_read, PECI_CPU);
+
+static const char * const peci_adev_types[] = {
+	"cputemp",
+	"dimmtemp",
+};
+
+struct peci_cpu {
+	struct peci_device *device;
+	const struct peci_device_id *id;
+};
+
+static void adev_release(struct device *dev)
+{
+	struct auxiliary_device *adev = to_auxiliary_dev(dev);
+
+	auxiliary_device_uninit(adev);
+
+	kfree(adev->name);
+	kfree(adev);
+}
+
+static struct auxiliary_device *adev_alloc(struct peci_cpu *priv, int idx)
+{
+	struct peci_controller *controller = to_peci_controller(priv->device->dev.parent);
+	struct auxiliary_device *adev;
+	const char *name;
+	int ret;
+
+	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
+	if (!adev)
+		return ERR_PTR(-ENOMEM);
+
+	name = kasprintf(GFP_KERNEL, "%s.%s", peci_adev_types[idx], (const char *)priv->id->data);
+	if (!name) {
+		ret = -ENOMEM;
+		goto free_adev;
+	}
+
+	adev->name = name;
+	adev->dev.parent = &priv->device->dev;
+	adev->dev.release = adev_release;
+	adev->id = (controller->id << 16) | (priv->device->addr);
+
+	ret = auxiliary_device_init(adev);
+	if (ret)
+		goto free_name;
+
+	return adev;
+
+free_name:
+	kfree(name);
+free_adev:
+	kfree(adev);
+	return ERR_PTR(ret);
+}
+
+static void unregister_adev(void *_adev)
+{
+	struct auxiliary_device *adev = _adev;
+
+	auxiliary_device_delete(adev);
+}
+
+static int devm_adev_add(struct device *dev, int idx)
+{
+	struct peci_cpu *priv = dev_get_drvdata(dev);
+	struct auxiliary_device *adev;
+	int ret;
+
+	adev = adev_alloc(priv, idx);
+	if (IS_ERR(adev))
+		return PTR_ERR(adev);
+
+	ret = auxiliary_device_add(adev);
+	if (ret) {
+		auxiliary_device_uninit(adev);
+		return ret;
+	}
+
+	ret = devm_add_action_or_reset(&priv->device->dev, unregister_adev, adev);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void peci_cpu_add_adevices(struct peci_cpu *priv)
+{
+	struct device *dev = &priv->device->dev;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(peci_adev_types); i++) {
+		ret = devm_adev_add(dev, i);
+		if (ret) {
+			dev_warn(dev, "Failed to register PECI auxiliary: %s, ret = %d\n",
+				 peci_adev_types[i], ret);
+			continue;
+		}
+	}
+}
+
+static int
+peci_cpu_probe(struct peci_device *device, const struct peci_device_id *id)
+{
+	struct device *dev = &device->dev;
+	struct peci_cpu *priv;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, priv);
+	priv->device = device;
+	priv->id = id;
+
+	peci_cpu_add_adevices(priv);
+
+	return 0;
+}
+
+static const struct peci_device_id peci_cpu_device_ids[] = {
+	{ /* Haswell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_HASWELL_X,
+		.data	= "hsx",
+	},
+	{ /* Broadwell Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_X,
+		.data	= "bdx",
+	},
+	{ /* Broadwell Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_BROADWELL_D,
+		.data	= "bdxd",
+	},
+	{ /* Skylake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_SKYLAKE_X,
+		.data	= "skx",
+	},
+	{ /* Icelake Xeon */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_X,
+		.data	= "icx",
+	},
+	{ /* Icelake Xeon D */
+		.family	= 6,
+		.model	= INTEL_FAM6_ICELAKE_D,
+		.data	= "icxd",
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(peci, peci_cpu_device_ids);
+
+static struct peci_driver peci_cpu_driver = {
+	.probe		= peci_cpu_probe,
+	.id_table	= peci_cpu_device_ids,
+	.driver		= {
+		.name		= "peci-cpu",
+	},
+};
+module_peci_driver(peci_cpu_driver);
+
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI CPU driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI);
diff --git a/drivers/peci/device.c b/drivers/peci/device.c
index 184b5e650b0b..e6b0bffb14f4 100644
--- a/drivers/peci/device.c
+++ b/drivers/peci/device.c
@@ -3,6 +3,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/peci.h>
+#include <linux/peci-cpu.h>
 #include <linux/slab.h>
 
 #include "internal.h"
diff --git a/drivers/peci/internal.h b/drivers/peci/internal.h
index 52c02e12874f..9d75ea54504c 100644
--- a/drivers/peci/internal.h
+++ b/drivers/peci/internal.h
@@ -22,6 +22,7 @@ void peci_request_free(struct peci_request *req);
 int peci_request_status(struct peci_request *req);
 
 u64 peci_request_dib_read(struct peci_request *req);
+s16 peci_request_temp_read(struct peci_request *req);
 
 u8 peci_request_data_readb(struct peci_request *req);
 u16 peci_request_data_readw(struct peci_request *req);
@@ -36,6 +37,32 @@ struct peci_request *peci_xfer_pkg_cfg_readw(struct peci_device *device, u8 inde
 struct peci_request *peci_xfer_pkg_cfg_readl(struct peci_device *device, u8 index, u16 param);
 struct peci_request *peci_xfer_pkg_cfg_readq(struct peci_device *device, u8 index, u16 param);
 
+struct peci_request *peci_xfer_pci_cfg_local_readb(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_pci_cfg_local_readw(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_pci_cfg_local_readl(struct peci_device *device,
+						   u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_pci_cfg_local_readb(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_local_readw(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_local_readl(struct peci_device *device, u8 seg,
+						      u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_pci_cfg_readb(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_readw(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+struct peci_request *peci_xfer_ep_pci_cfg_readl(struct peci_device *device, u8 seg,
+						u8 bus, u8 dev, u8 func, u16 reg);
+
+struct peci_request *peci_xfer_ep_mmio32_readl(struct peci_device *device, u8 bar, u8 seg,
+					       u8 bus, u8 dev, u8 func, u64 offset);
+
+struct peci_request *peci_xfer_ep_mmio64_readl(struct peci_device *device, u8 bar, u8 seg,
+					       u8 bus, u8 dev, u8 func, u64 offset);
 /**
  * struct peci_device_id - PECI device data to match
  * @data: pointer to driver private data specific to device
diff --git a/drivers/peci/request.c b/drivers/peci/request.c
index a49eb351cda3..8d6dd7b6b559 100644
--- a/drivers/peci/request.c
+++ b/drivers/peci/request.c
@@ -3,6 +3,7 @@
 
 #include <linux/bug.h>
 #include <linux/export.h>
+#include <linux/pci.h>
 #include <linux/peci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -15,6 +16,10 @@
 #define  PECI_GET_DIB_WR_LEN		1
 #define  PECI_GET_DIB_RD_LEN		8
 
+#define PECI_GET_TEMP_CMD		0x01
+#define  PECI_GET_TEMP_WR_LEN		1
+#define  PECI_GET_TEMP_RD_LEN		2
+
 #define PECI_RDPKGCFG_CMD		0xa1
 #define  PECI_RDPKGCFG_WR_LEN		5
 #define  PECI_RDPKGCFG_RD_LEN_BASE	1
@@ -22,6 +27,45 @@
 #define  PECI_WRPKGCFG_WR_LEN_BASE	6
 #define  PECI_WRPKGCFG_RD_LEN		1
 
+#define PECI_RDIAMSR_CMD		0xb1
+#define  PECI_RDIAMSR_WR_LEN		5
+#define  PECI_RDIAMSR_RD_LEN		9
+#define PECI_WRIAMSR_CMD		0xb5
+#define PECI_RDIAMSREX_CMD		0xd1
+#define  PECI_RDIAMSREX_WR_LEN		6
+#define  PECI_RDIAMSREX_RD_LEN		9
+
+#define PECI_RDPCICFG_CMD		0x61
+#define  PECI_RDPCICFG_WR_LEN		6
+#define  PECI_RDPCICFG_RD_LEN		5
+#define  PECI_RDPCICFG_RD_LEN_MAX	24
+#define PECI_WRPCICFG_CMD		0x65
+
+#define PECI_RDPCICFGLOCAL_CMD			0xe1
+#define  PECI_RDPCICFGLOCAL_WR_LEN		5
+#define  PECI_RDPCICFGLOCAL_RD_LEN_BASE		1
+#define PECI_WRPCICFGLOCAL_CMD			0xe5
+#define  PECI_WRPCICFGLOCAL_WR_LEN_BASE		6
+#define  PECI_WRPCICFGLOCAL_RD_LEN		1
+
+#define PECI_ENDPTCFG_TYPE_LOCAL_PCI		0x03
+#define PECI_ENDPTCFG_TYPE_PCI			0x04
+#define PECI_ENDPTCFG_TYPE_MMIO			0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_PCI		0x04
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_D		0x05
+#define PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q		0x06
+#define PECI_RDENDPTCFG_CMD			0xc1
+#define  PECI_RDENDPTCFG_PCI_WR_LEN		12
+#define  PECI_RDENDPTCFG_MMIO_WR_LEN_BASE	10
+#define  PECI_RDENDPTCFG_MMIO_D_WR_LEN		14
+#define  PECI_RDENDPTCFG_MMIO_Q_WR_LEN		18
+#define  PECI_RDENDPTCFG_RD_LEN_BASE		1
+#define PECI_WRENDPTCFG_CMD			0xc5
+#define  PECI_WRENDPTCFG_PCI_WR_LEN_BASE	13
+#define  PECI_WRENDPTCFG_MMIO_D_WR_LEN_BASE	15
+#define  PECI_WRENDPTCFG_MMIO_Q_WR_LEN_BASE	19
+#define  PECI_WRENDPTCFG_RD_LEN			1
+
 /* Device Specific Completion Code (CC) Definition */
 #define PECI_CC_SUCCESS				0x40
 #define PECI_CC_NEED_RETRY			0x80
@@ -202,6 +246,27 @@ struct peci_request *peci_xfer_get_dib(struct peci_device *device)
 }
 EXPORT_SYMBOL_NS_GPL(peci_xfer_get_dib, PECI);
 
+struct peci_request *peci_xfer_get_temp(struct peci_device *device)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_GET_TEMP_WR_LEN, PECI_GET_TEMP_RD_LEN);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_GET_TEMP_CMD;
+
+	ret = peci_request_xfer(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+EXPORT_SYMBOL_NS_GPL(peci_xfer_get_temp, PECI);
+
 static struct peci_request *
 __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 {
@@ -226,6 +291,108 @@ __pkg_cfg_read(struct peci_device *device, u8 index, u16 param, u8 len)
 	return req;
 }
 
+static u32 __get_pci_addr(u8 bus, u8 dev, u8 func, u16 reg)
+{
+	return reg | PCI_DEVID(bus, PCI_DEVFN(dev, func)) << 12;
+}
+
+static struct peci_request *
+__pci_cfg_local_read(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDPCICFGLOCAL_WR_LEN,
+				 PECI_RDPCICFGLOCAL_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDPCICFGLOCAL_CMD;
+	req->tx.buf[1] = 0;
+	put_unaligned_le24(pci_addr, &req->tx.buf[2]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_pci_cfg_read(struct peci_device *device, u8 msg_type, u8 seg,
+		  u8 bus, u8 dev, u8 func, u16 reg, u8 len)
+{
+	struct peci_request *req;
+	u32 pci_addr;
+	int ret;
+
+	req = peci_request_alloc(device, PECI_RDENDPTCFG_PCI_WR_LEN,
+				 PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	pci_addr = __get_pci_addr(bus, dev, func, reg);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = msg_type;
+	req->tx.buf[3] = 0;
+	req->tx.buf[4] = 0;
+	req->tx.buf[5] = 0;
+	req->tx.buf[6] = PECI_ENDPTCFG_ADDR_TYPE_PCI;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	put_unaligned_le32(pci_addr, &req->tx.buf[8]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
+static struct peci_request *
+__ep_mmio_read(struct peci_device *device, u8 bar, u8 addr_type, u8 seg,
+	       u8 bus, u8 dev, u8 func, u64 offset, u8 tx_len, u8 len)
+{
+	struct peci_request *req;
+	int ret;
+
+	req = peci_request_alloc(device, tx_len, PECI_RDENDPTCFG_RD_LEN_BASE + len);
+	if (!req)
+		return ERR_PTR(-ENOMEM);
+
+	req->tx.buf[0] = PECI_RDENDPTCFG_CMD;
+	req->tx.buf[1] = 0;
+	req->tx.buf[2] = PECI_ENDPTCFG_TYPE_MMIO;
+	req->tx.buf[3] = 0; /* Endpoint ID */
+	req->tx.buf[4] = 0; /* Reserved */
+	req->tx.buf[5] = bar;
+	req->tx.buf[6] = addr_type;
+	req->tx.buf[7] = seg; /* PCI Segment */
+	req->tx.buf[8] = PCI_DEVFN(dev, func);
+	req->tx.buf[9] = bus; /* PCI Bus */
+
+	if (addr_type == PECI_ENDPTCFG_ADDR_TYPE_MMIO_D)
+		put_unaligned_le32(offset, &req->tx.buf[10]);
+	else
+		put_unaligned_le64(offset, &req->tx.buf[10]);
+
+	ret = peci_request_xfer_retry(req);
+	if (ret) {
+		peci_request_free(req);
+		return ERR_PTR(ret);
+	}
+
+	return req;
+}
+
 u8 peci_request_data_readb(struct peci_request *req)
 {
 	return req->rx.buf[1];
@@ -256,6 +423,12 @@ u64 peci_request_dib_read(struct peci_request *req)
 }
 EXPORT_SYMBOL_NS_GPL(peci_request_dib_read, PECI);
 
+s16 peci_request_temp_read(struct peci_request *req)
+{
+	return get_unaligned_le16(&req->rx.buf[0]);
+}
+EXPORT_SYMBOL_NS_GPL(peci_request_temp_read, PECI);
+
 #define __read_pkg_config(x, type) \
 struct peci_request *peci_xfer_pkg_cfg_##x(struct peci_device *device, u8 index, u16 param) \
 { \
@@ -267,3 +440,43 @@ __read_pkg_config(readb, u8);
 __read_pkg_config(readw, u16);
 __read_pkg_config(readl, u32);
 __read_pkg_config(readq, u64);
+
+#define __read_pci_config_local(x, type) \
+struct peci_request * \
+peci_xfer_pci_cfg_local_##x(struct peci_device *device, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __pci_cfg_local_read(device, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_pci_cfg_local_##x, PECI)
+
+__read_pci_config_local(readb, u8);
+__read_pci_config_local(readw, u16);
+__read_pci_config_local(readl, u32);
+
+#define __read_ep_pci_config(x, msg_type, type) \
+struct peci_request * \
+peci_xfer_ep_pci_cfg_##x(struct peci_device *device, u8 seg, u8 bus, u8 dev, u8 func, u16 reg) \
+{ \
+	return __ep_pci_cfg_read(device, msg_type, seg, bus, dev, func, reg, sizeof(type)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_pci_cfg_##x, PECI)
+
+__read_ep_pci_config(local_readb, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u8);
+__read_ep_pci_config(local_readw, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u16);
+__read_ep_pci_config(local_readl, PECI_ENDPTCFG_TYPE_LOCAL_PCI, u32);
+__read_ep_pci_config(readb, PECI_ENDPTCFG_TYPE_PCI, u8);
+__read_ep_pci_config(readw, PECI_ENDPTCFG_TYPE_PCI, u16);
+__read_ep_pci_config(readl, PECI_ENDPTCFG_TYPE_PCI, u32);
+
+#define __read_ep_mmio(x, y, addr_type, type1, type2) \
+struct peci_request *peci_xfer_ep_mmio##y##_##x(struct peci_device *device, u8 bar, u8 seg, \
+					   u8 bus, u8 dev, u8 func, u64 offset) \
+{ \
+	return __ep_mmio_read(device, bar, addr_type, seg, bus, dev, func, \
+			      offset, PECI_RDENDPTCFG_MMIO_WR_LEN_BASE + sizeof(type1), \
+			      sizeof(type2)); \
+} \
+EXPORT_SYMBOL_NS_GPL(peci_xfer_ep_mmio##y##_##x, PECI)
+
+__read_ep_mmio(readl, 32, PECI_ENDPTCFG_ADDR_TYPE_MMIO_D, u32, u32);
+__read_ep_mmio(readl, 64, PECI_ENDPTCFG_ADDR_TYPE_MMIO_Q, u64, u32);
diff --git a/include/linux/peci-cpu.h b/include/linux/peci-cpu.h
new file mode 100644
index 000000000000..ff8ae9c26c80
--- /dev/null
+++ b/include/linux/peci-cpu.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#ifndef __LINUX_PECI_CPU_H
+#define __LINUX_PECI_CPU_H
+
+#include <linux/types.h>
+
+#include "../../arch/x86/include/asm/intel-family.h"
+
+#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
+#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
+#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
+#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
+#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
+#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
+#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
+#define PECI_PCS_MODULE_TEMP		9  /* Per Core DTS Temperature Read */
+#define PECI_PCS_THERMAL_MARGIN		10 /* DTS thermal margin */
+#define PECI_PCS_DDR_DIMM_TEMP		14 /* DDR DIMM Temperature */
+#define PECI_PCS_TEMP_TARGET		16 /* Temperature Target Read */
+#define PECI_PCS_TDP_UNITS		30 /* Units for power/energy registers */
+
+struct peci_device;
+
+int peci_temp_read(struct peci_device *device, s16 *temp_raw);
+
+int peci_pcs_read(struct peci_device *device, u8 index,
+		  u16 param, u32 *data);
+
+int peci_pci_local_read(struct peci_device *device, u8 bus, u8 dev,
+			u8 func, u16 reg, u32 *data);
+
+int peci_ep_pci_local_read(struct peci_device *device, u8 seg,
+			   u8 bus, u8 dev, u8 func, u16 reg, u32 *data);
+
+int peci_mmio_read(struct peci_device *device, u8 bar, u8 seg,
+		   u8 bus, u8 dev, u8 func, u64 address, u32 *data);
+
+#endif /* __LINUX_PECI_CPU_H */
diff --git a/include/linux/peci.h b/include/linux/peci.h
index 4eda423ba10c..06e6ef935297 100644
--- a/include/linux/peci.h
+++ b/include/linux/peci.h
@@ -14,14 +14,6 @@
  */
 #define PECI_REQUEST_MAX_BUF_SIZE 32
 
-#define PECI_PCS_PKG_ID			0  /* Package Identifier Read */
-#define  PECI_PKG_ID_CPU_ID		0x0000  /* CPUID Info */
-#define  PECI_PKG_ID_PLATFORM_ID	0x0001  /* Platform ID */
-#define  PECI_PKG_ID_DEVICE_ID		0x0002  /* Uncore Device ID */
-#define  PECI_PKG_ID_MAX_THREAD_ID	0x0003  /* Max Thread ID */
-#define  PECI_PKG_ID_MICROCODE_REV	0x0004  /* CPU Microcode Update Revision */
-#define  PECI_PKG_ID_MCA_ERROR_LOG	0x0005  /* Machine Check Status */
-
 struct peci_controller;
 struct peci_request;
 
-- 
2.31.1



From sboyd at kernel.org  Mon Jan 24 17:16:29 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:16:29 -0800
Subject: [PATCH 2/5] clk: stm32mp1: Add parent_data to ETHRX clock
In-Reply-To: <20220118202958.1840431-2-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
 <20220118202958.1840431-2-marex@denx.de>
Message-ID: <20220125011631.A3B5FC340E4@smtp.kernel.org>

Quoting Marek Vasut (2022-01-18 12:29:55)
> Pass parent_data to ETHRX clock with new fw_name = "ETH_RX_CLK/ETH_REF_CLK".
> By default, this change has no impact on the operation of the clock driver.
> However, due to the fw_name, it permits DT to override ETHRX clock parent,
> which might be needed in case the ETHRX clock are supplied by external clock
> source.
> 
> Example of MCO2 supplying clock to ETH_RX_CLK via external pad-to-pad wire:
> &rcc {
>          clocks = <&rcc CK_MCO2>;
>          clock-names = "ETH_RX_CLK/ETH_REF_CLK";
> };
> 
> Note that while this patch permits to implement this rare usecase, the issue
> with ethernet RX and TX input clock modeling on MP1 is far more complex and
> requires more core plumbing.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>     Figure 83. Peripheral clock distribution for Ethernet
>     https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---

Applied to clk-next


From sboyd at kernel.org  Mon Jan 24 17:16:40 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:16:40 -0800
Subject: [PATCH 1/5] clk: stm32mp1: Split ETHCK_K into separate MUX and
 GATE clock
In-Reply-To: <20220118202958.1840431-1-marex@denx.de>
References: <20220118202958.1840431-1-marex@denx.de>
Message-ID: <20220125011642.3C7F1C340E4@smtp.kernel.org>

Quoting Marek Vasut (2022-01-18 12:29:54)
> The ETHCK_K are modeled as composite clock of MUX and GATE, however per
> STM32MP1 Reference Manual RM0436 Rev 3, Page 574, Figure 83. Peripheral
> clock distribution for Ethernet, ETHPTPDIV divider is attached past the
> ETHCK_K mux, and ETH_CLK/eth_clk_fb clock are output past ETHCKEN gate.
> Therefore, in case ETH_CLK/eth_clk_fb are not in use AND PTP clock are
> in use, ETHCKEN gate can be turned off. Current driver does not permit
> that, fix it.
> 
> This patch converts ETHCK_K from composite clock into a ETHCKEN gate,
> ETHPTP_K from composite clock into ETHPTPDIV divider, and adds another
> NO_ID clock "ck_ker_eth" which models the ETHSRC mux and is parent clock
> to both ETHCK_K and ETHPTP_K. Therefore, all references to ETHCK_K and
> ETHPTP_K remain functional as before.
> 
> [1] STM32MP1 Reference Manual RM0436 Rev 3, Page 574,
>     Figure 83. Peripheral clock distribution for Ethernet
>     https://www.st.com/resource/en/reference_manual/dm00327659-stm32mp157-advanced-armbased-32bit-mpus-stmicroelectronics.pdf
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Alexandre Torgue <alexandre.torgue at foss.st.com>
> Cc: Christophe Roullier <christophe.roullier at foss.st.com>
> Cc: Gabriel Fernandez <gabriel.fernandez at foss.st.com>
> Cc: Patrice Chotard <patrice.chotard at foss.st.com>
> Cc: Patrick Delaunay <patrick.delaunay at foss.st.com>
> Cc: Stephen Boyd <sboyd at kernel.org>
> Cc: linux-clk at vger.kernel.org
> Cc: linux-stm32 at st-md-mailman.stormreply.com
> To: linux-arm-kernel at lists.infradead.org
> ---

Applied to clk-next


From iwona.winiarska at intel.com  Mon Jan 24 17:11:01 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:11:01 +0100
Subject: [PATCH v6 10/13] hwmon: peci: Add cputemp driver
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-11-iwona.winiarska@intel.com>

Add peci-cputemp driver for Digital Thermal Sensor (DTS) thermal
readings of the processor package and processor cores that are
accessible via the PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain the DTS readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 MAINTAINERS                  |   6 +
 drivers/hwmon/Kconfig        |   2 +
 drivers/hwmon/Makefile       |   1 +
 drivers/hwmon/peci/Kconfig   |  18 ++
 drivers/hwmon/peci/Makefile  |   5 +
 drivers/hwmon/peci/common.h  |  58 ++++
 drivers/hwmon/peci/cputemp.c | 592 +++++++++++++++++++++++++++++++++++
 7 files changed, 682 insertions(+)
 create mode 100644 drivers/hwmon/peci/Kconfig
 create mode 100644 drivers/hwmon/peci/Makefile
 create mode 100644 drivers/hwmon/peci/common.h
 create mode 100644 drivers/hwmon/peci/cputemp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7c31e29c885a..369ac3524f33 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15099,6 +15099,12 @@ L:	platform-driver-x86 at vger.kernel.org
 S:	Maintained
 F:	drivers/platform/x86/peaq-wmi.c
 
+PECI HARDWARE MONITORING DRIVERS
+M:	Iwona Winiarska <iwona.winiarska at intel.com>
+L:	linux-hwmon at vger.kernel.org
+S:	Supported
+F:	drivers/hwmon/peci/
+
 PECI SUBSYSTEM
 M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 8df25f1079ba..af6c3bd65ebd 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1538,6 +1538,8 @@ config SENSORS_PCF8591
 	  These devices are hard to detect and rarely found on mainstream
 	  hardware. If unsure, say N.
 
+source "drivers/hwmon/peci/Kconfig"
+
 source "drivers/hwmon/pmbus/Kconfig"
 
 config SENSORS_PWM_FAN
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 185f946d698b..6139e5a5aa00 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -208,6 +208,7 @@ obj-$(CONFIG_SENSORS_WM8350)	+= wm8350-hwmon.o
 obj-$(CONFIG_SENSORS_XGENE)	+= xgene-hwmon.o
 
 obj-$(CONFIG_SENSORS_OCC)	+= occ/
+obj-$(CONFIG_SENSORS_PECI)	+= peci/
 obj-$(CONFIG_PMBUS)		+= pmbus/
 
 ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
new file mode 100644
index 000000000000..e10eed68d70a
--- /dev/null
+++ b/drivers/hwmon/peci/Kconfig
@@ -0,0 +1,18 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config SENSORS_PECI_CPUTEMP
+	tristate "PECI CPU temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI
+	  cputemp driver which provides Digital Thermal Sensor (DTS) thermal
+	  readings of the CPU package and CPU cores that are accessible via
+	  the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-cputemp.
+
+config SENSORS_PECI
+	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
new file mode 100644
index 000000000000..e8a0ada5ab1f
--- /dev/null
+++ b/drivers/hwmon/peci/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+peci-cputemp-y := cputemp.o
+
+obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
diff --git a/drivers/hwmon/peci/common.h b/drivers/hwmon/peci/common.h
new file mode 100644
index 000000000000..734506b0eca2
--- /dev/null
+++ b/drivers/hwmon/peci/common.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2021 Intel Corporation */
+
+#include <linux/mutex.h>
+#include <linux/types.h>
+
+#ifndef __PECI_HWMON_COMMON_H
+#define __PECI_HWMON_COMMON_H
+
+#define PECI_HWMON_UPDATE_INTERVAL	HZ
+
+/**
+ * struct peci_sensor_state - PECI state information
+ * @valid: flag to indicate the sensor value is valid
+ * @last_updated: time of the last update in jiffies
+ * @lock: mutex to protect sensor access
+ */
+struct peci_sensor_state {
+	bool valid;
+	unsigned long last_updated;
+	struct mutex lock; /* protect sensor access */
+};
+
+/**
+ * struct peci_sensor_data - PECI sensor information
+ * @value: sensor value in milli units
+ * @state: sensor update state
+ */
+
+struct peci_sensor_data {
+	s32 value;
+	struct peci_sensor_state state;
+};
+
+/**
+ * peci_sensor_need_update() - check whether sensor update is needed or not
+ * @sensor: pointer to sensor data struct
+ *
+ * Return: true if update is needed, false if not.
+ */
+
+static inline bool peci_sensor_need_update(struct peci_sensor_state *state)
+{
+	return !state->valid ||
+	       time_after(jiffies, state->last_updated + PECI_HWMON_UPDATE_INTERVAL);
+}
+
+/**
+ * peci_sensor_mark_updated() - mark the sensor is updated
+ * @sensor: pointer to sensor data struct
+ */
+static inline void peci_sensor_mark_updated(struct peci_sensor_state *state)
+{
+	state->valid = true;
+	state->last_updated = jiffies;
+}
+
+#endif /* __PECI_HWMON_COMMON_H */
diff --git a/drivers/hwmon/peci/cputemp.c b/drivers/hwmon/peci/cputemp.c
new file mode 100644
index 000000000000..12156328f5cf
--- /dev/null
+++ b/drivers/hwmon/peci/cputemp.c
@@ -0,0 +1,592 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+
+#include "common.h"
+
+#define CORE_NUMS_MAX		64
+
+#define BASE_CHANNEL_NUMS	5
+#define CPUTEMP_CHANNEL_NUMS	(BASE_CHANNEL_NUMS + CORE_NUMS_MAX)
+
+#define TEMP_TARGET_FAN_TEMP_MASK	GENMASK(15, 8)
+#define TEMP_TARGET_REF_TEMP_MASK	GENMASK(23, 16)
+#define TEMP_TARGET_TJ_OFFSET_MASK	GENMASK(29, 24)
+
+#define DTS_MARGIN_MASK		GENMASK(15, 0)
+#define PCS_MODULE_TEMP_MASK	GENMASK(15, 0)
+
+struct resolved_cores_reg {
+	u8 bus;
+	u8 dev;
+	u8 func;
+	u8 offset;
+};
+
+struct cpu_info {
+	struct resolved_cores_reg *reg;
+	u8 min_peci_revision;
+	s32 (*thermal_margin_to_millidegree)(u16 val);
+};
+
+struct peci_temp_target {
+	s32 tcontrol;
+	s32 tthrottle;
+	s32 tjmax;
+	struct peci_sensor_state state;
+};
+
+enum peci_temp_target_type {
+	tcontrol_type,
+	tthrottle_type,
+	tjmax_type,
+	crit_hyst_type,
+};
+
+struct peci_cputemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct cpu_info *gen_info;
+	struct {
+		struct peci_temp_target target;
+		struct peci_sensor_data die;
+		struct peci_sensor_data dts;
+		struct peci_sensor_data core[CORE_NUMS_MAX];
+	} temp;
+	const char **coretemp_label;
+	DECLARE_BITMAP(core_mask, CORE_NUMS_MAX);
+};
+
+enum cputemp_channels {
+	channel_die,
+	channel_dts,
+	channel_tcontrol,
+	channel_tthrottle,
+	channel_tjmax,
+	channel_core,
+};
+
+static const char * const cputemp_label[BASE_CHANNEL_NUMS] = {
+	"Die",
+	"DTS",
+	"Tcontrol",
+	"Tthrottle",
+	"Tjmax",
+};
+
+static int update_temp_target(struct peci_cputemp *priv)
+{
+	s32 tthrottle_offset, tcontrol_margin;
+	u32 pcs;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->temp.target.state))
+		return 0;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_TEMP_TARGET, 0, &pcs);
+	if (ret)
+		return ret;
+
+	priv->temp.target.tjmax =
+		FIELD_GET(TEMP_TARGET_REF_TEMP_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+
+	tcontrol_margin = FIELD_GET(TEMP_TARGET_FAN_TEMP_MASK, pcs);
+	tcontrol_margin = sign_extend32(tcontrol_margin, 7) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tcontrol = priv->temp.target.tjmax - tcontrol_margin;
+
+	tthrottle_offset = FIELD_GET(TEMP_TARGET_TJ_OFFSET_MASK, pcs) * MILLIDEGREE_PER_DEGREE;
+	priv->temp.target.tthrottle = priv->temp.target.tjmax - tthrottle_offset;
+
+	peci_sensor_mark_updated(&priv->temp.target.state);
+
+	return 0;
+}
+
+static int get_temp_target(struct peci_cputemp *priv, enum peci_temp_target_type type, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->temp.target.state.lock);
+
+	ret = update_temp_target(priv);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case tcontrol_type:
+		*val = priv->temp.target.tcontrol;
+		break;
+	case tthrottle_type:
+		*val = priv->temp.target.tthrottle;
+		break;
+	case tjmax_type:
+		*val = priv->temp.target.tjmax;
+		break;
+	case crit_hyst_type:
+		*val = priv->temp.target.tjmax - priv->temp.target.tcontrol;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->temp.target.state.lock);
+
+	return ret;
+}
+
+/*
+ * Error codes:
+ *   0x8000: General sensor error
+ *   0x8001: Reserved
+ *   0x8002: Underflow on reading value
+ *   0x8003-0x81ff: Reserved
+ */
+static bool dts_valid(u16 val)
+{
+	return val < 0x8000 || val > 0x81ff;
+}
+
+/*
+ * Processors return a value of DTS reading in S10.6 fixed point format
+ * (16 bits: 10-bit signed magnitude, 6-bit fraction).
+ */
+static s32 dts_ten_dot_six_to_millidegree(u16 val)
+{
+	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / 64;
+}
+
+/*
+ * For older processors, thermal margin reading is returned in S8.8 fixed
+ * point format (16 bits: 8-bit signed magnitude, 8-bit fraction).
+ */
+static s32 dts_eight_dot_eight_to_millidegree(u16 val)
+{
+	return sign_extend32(val, 15) * MILLIDEGREE_PER_DEGREE / 256;
+}
+
+static int get_die_temp(struct peci_cputemp *priv, long *val)
+{
+	int ret = 0;
+	long tjmax;
+	u16 temp;
+
+	mutex_lock(&priv->temp.die.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.die.state))
+		goto skip_update;
+
+	ret = peci_temp_read(priv->peci_dev, &temp);
+	if (ret)
+		goto err_unlock;
+
+	if (!dts_valid(temp)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	priv->temp.die.value = (s32)tjmax + dts_ten_dot_six_to_millidegree(temp);
+
+	peci_sensor_mark_updated(&priv->temp.die.state);
+
+skip_update:
+	*val = priv->temp.die.value;
+err_unlock:
+	mutex_unlock(&priv->temp.die.state.lock);
+	return ret;
+}
+
+static int get_dts(struct peci_cputemp *priv, long *val)
+{
+	int ret = 0;
+	u16 thermal_margin;
+	long tcontrol;
+	u32 pcs;
+
+	mutex_lock(&priv->temp.dts.state.lock);
+	if (!peci_sensor_need_update(&priv->temp.dts.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_THERMAL_MARGIN, 0, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	thermal_margin = FIELD_GET(DTS_MARGIN_MASK, pcs);
+	if (!dts_valid(thermal_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tcontrol_type, &tcontrol);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tcontrol should be available before calling it */
+	priv->temp.dts.value =
+		(s32)tcontrol - priv->gen_info->thermal_margin_to_millidegree(thermal_margin);
+
+	peci_sensor_mark_updated(&priv->temp.dts.state);
+
+skip_update:
+	*val = priv->temp.dts.value;
+err_unlock:
+	mutex_unlock(&priv->temp.dts.state.lock);
+	return ret;
+}
+
+static int get_core_temp(struct peci_cputemp *priv, int core_index, long *val)
+{
+	int ret = 0;
+	u16 core_dts_margin;
+	long tjmax;
+	u32 pcs;
+
+	mutex_lock(&priv->temp.core[core_index].state.lock);
+	if (!peci_sensor_need_update(&priv->temp.core[core_index].state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_MODULE_TEMP, core_index, &pcs);
+	if (ret)
+		goto err_unlock;
+
+	core_dts_margin = FIELD_GET(PCS_MODULE_TEMP_MASK, pcs);
+	if (!dts_valid(core_dts_margin)) {
+		ret = -EIO;
+		goto err_unlock;
+	}
+
+	ret = get_temp_target(priv, tjmax_type, &tjmax);
+	if (ret)
+		goto err_unlock;
+
+	/* Note that the tjmax should be available before calling it */
+	priv->temp.core[core_index].value =
+		(s32)tjmax + dts_ten_dot_six_to_millidegree(core_dts_margin);
+
+	peci_sensor_mark_updated(&priv->temp.core[core_index].state);
+
+skip_update:
+	*val = priv->temp.core[core_index].value;
+err_unlock:
+	mutex_unlock(&priv->temp.core[core_index].state.lock);
+	return ret;
+}
+
+static int cputemp_read_string(struct device *dev, enum hwmon_sensor_types type,
+			       u32 attr, int channel, const char **str)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = channel < channel_core ?
+		cputemp_label[channel] : priv->coretemp_label[channel - channel_core];
+
+	return 0;
+}
+
+static int cputemp_read(struct device *dev, enum hwmon_sensor_types type,
+			u32 attr, int channel, long *val)
+{
+	struct peci_cputemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		switch (channel) {
+		case channel_die:
+			return get_die_temp(priv, val);
+		case channel_dts:
+			return get_dts(priv, val);
+		case channel_tcontrol:
+			return get_temp_target(priv, tcontrol_type, val);
+		case channel_tthrottle:
+			return get_temp_target(priv, tthrottle_type, val);
+		case channel_tjmax:
+			return get_temp_target(priv, tjmax_type, val);
+		default:
+			return get_core_temp(priv, channel - channel_core, val);
+		}
+		break;
+	case hwmon_temp_max:
+		return get_temp_target(priv, tcontrol_type, val);
+	case hwmon_temp_crit:
+		return get_temp_target(priv, tjmax_type, val);
+	case hwmon_temp_crit_hyst:
+		return get_temp_target(priv, crit_hyst_type, val);
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+static umode_t cputemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				  u32 attr, int channel)
+{
+	const struct peci_cputemp *priv = data;
+
+	if (channel > CPUTEMP_CHANNEL_NUMS)
+		return 0;
+
+	if (channel < channel_core)
+		return 0444;
+
+	if (test_bit(channel - channel_core, priv->core_mask))
+		return 0444;
+
+	return 0;
+}
+
+static int init_core_mask(struct peci_cputemp *priv)
+{
+	struct peci_device *peci_dev = priv->peci_dev;
+	struct resolved_cores_reg *reg = priv->gen_info->reg;
+	u64 core_mask;
+	u32 data;
+	int ret;
+
+	/* Get the RESOLVED_CORES register value */
+	switch (peci_dev->info.model) {
+	case INTEL_FAM6_ICELAKE_X:
+	case INTEL_FAM6_ICELAKE_D:
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset + 4, &data);
+		if (ret)
+			return ret;
+
+		core_mask = (u64)data << 32;
+
+		ret = peci_ep_pci_local_read(peci_dev, 0, reg->bus, reg->dev,
+					     reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask |= data;
+
+		break;
+	default:
+		ret = peci_pci_local_read(peci_dev, reg->bus, reg->dev,
+					  reg->func, reg->offset, &data);
+		if (ret)
+			return ret;
+
+		core_mask = data;
+
+		break;
+	}
+
+	if (!core_mask)
+		return -EIO;
+
+	bitmap_from_u64(priv->core_mask, core_mask);
+
+	return 0;
+}
+
+static int create_temp_label(struct peci_cputemp *priv)
+{
+	unsigned long core_max = find_last_bit(priv->core_mask, CORE_NUMS_MAX);
+	int i;
+
+	priv->coretemp_label = devm_kzalloc(priv->dev, core_max * sizeof(char *), GFP_KERNEL);
+	if (!priv->coretemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX) {
+		priv->coretemp_label[i] = devm_kasprintf(priv->dev, GFP_KERNEL, "Core %d", i);
+		if (!priv->coretemp_label[i])
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
+static void check_resolved_cores(struct peci_cputemp *priv)
+{
+	/*
+	 * Failure to resolve cores is non-critical, we're still able to
+	 * provide other sensor data.
+	 */
+
+	if (init_core_mask(priv))
+		return;
+
+	if (create_temp_label(priv))
+		bitmap_zero(priv->core_mask, CORE_NUMS_MAX);
+}
+
+static void sensor_init(struct peci_cputemp *priv)
+{
+	int i;
+
+	mutex_init(&priv->temp.target.state.lock);
+	mutex_init(&priv->temp.die.state.lock);
+	mutex_init(&priv->temp.dts.state.lock);
+
+	for_each_set_bit(i, priv->core_mask, CORE_NUMS_MAX)
+		mutex_init(&priv->temp.core[i].state.lock);
+}
+
+static const struct hwmon_ops peci_cputemp_ops = {
+	.is_visible = cputemp_is_visible,
+	.read_string = cputemp_read_string,
+	.read = cputemp_read,
+};
+
+static const u32 peci_cputemp_temp_channel_config[] = {
+	/* Die temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* DTS margin */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST,
+	/* Tcontrol temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT,
+	/* Tthrottle temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Tjmax temperature */
+	HWMON_T_LABEL | HWMON_T_INPUT,
+	/* Core temperature - for all core channels */
+	[channel_core ... CPUTEMP_CHANNEL_NUMS - 1] = HWMON_T_LABEL | HWMON_T_INPUT,
+	0
+};
+
+static const struct hwmon_channel_info peci_cputemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_cputemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_cputemp_info[] = {
+	&peci_cputemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_cputemp_chip_info = {
+	.ops = &peci_cputemp_ops,
+	.info = peci_cputemp_info,
+};
+
+static int peci_cputemp_probe(struct auxiliary_device *adev,
+			      const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_cputemp *priv;
+	struct device *hwmon_dev;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_cputemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct cpu_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	check_resolved_cores(priv);
+
+	sensor_init(priv);
+
+	hwmon_dev = devm_hwmon_device_register_with_info(priv->dev, priv->name,
+							 priv, &peci_cputemp_chip_info, NULL);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+/*
+ * RESOLVED_CORES PCI configuration register may have different location on
+ * different platforms.
+ */
+static struct resolved_cores_reg resolved_cores_reg_hsx = {
+	.bus = 1,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xb4,
+};
+
+static struct resolved_cores_reg resolved_cores_reg_icx = {
+	.bus = 14,
+	.dev = 30,
+	.func = 3,
+	.offset = 0xd0,
+};
+
+static const struct cpu_info cpu_hsx = {
+	.reg		= &resolved_cores_reg_hsx,
+	.min_peci_revision = 0x33,
+	.thermal_margin_to_millidegree = &dts_eight_dot_eight_to_millidegree,
+};
+
+static const struct cpu_info cpu_icx = {
+	.reg		= &resolved_cores_reg_icx,
+	.min_peci_revision = 0x40,
+	.thermal_margin_to_millidegree = &dts_ten_dot_six_to_millidegree,
+};
+
+static const struct auxiliary_device_id peci_cputemp_ids[] = {
+	{
+		.name = "peci_cpu.cputemp.hsx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.bdxd",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.skx",
+		.driver_data = (kernel_ulong_t)&cpu_hsx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icx",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{
+		.name = "peci_cpu.cputemp.icxd",
+		.driver_data = (kernel_ulong_t)&cpu_icx,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_cputemp_ids);
+
+static struct auxiliary_driver peci_cputemp_driver = {
+	.probe		= peci_cputemp_probe,
+	.id_table	= peci_cputemp_ids,
+};
+
+module_auxiliary_driver(peci_cputemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI cputemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:11:02 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:11:02 +0100
Subject: [PATCH v6 11/13] hwmon: peci: Add dimmtemp driver
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-12-iwona.winiarska@intel.com>

Add peci-dimmtemp driver for Temperature Sensor on DIMM readings that
are accessible via the processor PECI interface.

The main use case for the driver (and PECI interface) is out-of-band
management, where we're able to obtain thermal readings from an external
entity connected with PECI, e.g. BMC on server platforms.

Co-developed-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 drivers/hwmon/peci/Kconfig    |  13 +
 drivers/hwmon/peci/Makefile   |   2 +
 drivers/hwmon/peci/dimmtemp.c | 630 ++++++++++++++++++++++++++++++++++
 3 files changed, 645 insertions(+)
 create mode 100644 drivers/hwmon/peci/dimmtemp.c

diff --git a/drivers/hwmon/peci/Kconfig b/drivers/hwmon/peci/Kconfig
index e10eed68d70a..9d32a57badfe 100644
--- a/drivers/hwmon/peci/Kconfig
+++ b/drivers/hwmon/peci/Kconfig
@@ -14,5 +14,18 @@ config SENSORS_PECI_CPUTEMP
 	  This driver can also be built as a module. If so, the module
 	  will be called peci-cputemp.
 
+config SENSORS_PECI_DIMMTEMP
+	tristate "PECI DIMM temperature monitoring client"
+	depends on PECI
+	select SENSORS_PECI
+	select PECI_CPU
+	help
+	  If you say yes here you get support for the generic Intel PECI hwmon
+	  driver which provides Temperature Sensor on DIMM readings that are
+	  accessible via the processor PECI interface.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called peci-dimmtemp.
+
 config SENSORS_PECI
 	tristate
diff --git a/drivers/hwmon/peci/Makefile b/drivers/hwmon/peci/Makefile
index e8a0ada5ab1f..191cfa0227f3 100644
--- a/drivers/hwmon/peci/Makefile
+++ b/drivers/hwmon/peci/Makefile
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 peci-cputemp-y := cputemp.o
+peci-dimmtemp-y := dimmtemp.o
 
 obj-$(CONFIG_SENSORS_PECI_CPUTEMP)	+= peci-cputemp.o
+obj-$(CONFIG_SENSORS_PECI_DIMMTEMP)	+= peci-dimmtemp.o
diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
new file mode 100644
index 000000000000..c8222354c005
--- /dev/null
+++ b/drivers/hwmon/peci/dimmtemp.c
@@ -0,0 +1,630 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2018-2021 Intel Corporation
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/peci.h>
+#include <linux/peci-cpu.h>
+#include <linux/units.h>
+#include <linux/workqueue.h>
+
+#include "common.h"
+
+#define DIMM_MASK_CHECK_DELAY_JIFFIES	msecs_to_jiffies(5000)
+
+/* Max number of channel ranks and DIMM index per channel */
+#define CHAN_RANK_MAX_ON_HSX	8
+#define DIMM_IDX_MAX_ON_HSX	3
+#define CHAN_RANK_MAX_ON_BDX	4
+#define DIMM_IDX_MAX_ON_BDX	3
+#define CHAN_RANK_MAX_ON_BDXD	2
+#define DIMM_IDX_MAX_ON_BDXD	2
+#define CHAN_RANK_MAX_ON_SKX	6
+#define DIMM_IDX_MAX_ON_SKX	2
+#define CHAN_RANK_MAX_ON_ICX	8
+#define DIMM_IDX_MAX_ON_ICX	2
+#define CHAN_RANK_MAX_ON_ICXD	4
+#define DIMM_IDX_MAX_ON_ICXD	2
+
+#define CHAN_RANK_MAX		CHAN_RANK_MAX_ON_HSX
+#define DIMM_IDX_MAX		DIMM_IDX_MAX_ON_HSX
+#define DIMM_NUMS_MAX		(CHAN_RANK_MAX * DIMM_IDX_MAX)
+
+#define CPU_SEG_MASK		GENMASK(23, 16)
+#define GET_CPU_SEG(x)		(((x) & CPU_SEG_MASK) >> 16)
+#define CPU_BUS_MASK		GENMASK(7, 0)
+#define GET_CPU_BUS(x)		((x) & CPU_BUS_MASK)
+
+#define DIMM_TEMP_MAX		GENMASK(15, 8)
+#define DIMM_TEMP_CRIT		GENMASK(23, 16)
+#define GET_TEMP_MAX(x)		(((x) & DIMM_TEMP_MAX) >> 8)
+#define GET_TEMP_CRIT(x)	(((x) & DIMM_TEMP_CRIT) >> 16)
+
+#define NO_DIMM_RETRY_COUNT_MAX	5
+
+struct peci_dimmtemp;
+
+struct dimm_info {
+	int chan_rank_max;
+	int dimm_idx_max;
+	u8 min_peci_revision;
+	int (*read_thresholds)(struct peci_dimmtemp *priv, int dimm_order,
+			       int chan_rank, u32 *data);
+};
+
+struct peci_dimm_thresholds {
+	long temp_max;
+	long temp_crit;
+	struct peci_sensor_state state;
+};
+
+enum peci_dimm_threshold_type {
+	temp_max_type,
+	temp_crit_type,
+};
+
+struct peci_dimmtemp {
+	struct peci_device *peci_dev;
+	struct device *dev;
+	const char *name;
+	const struct dimm_info *gen_info;
+	struct delayed_work detect_work;
+	struct {
+		struct peci_sensor_data temp;
+		struct peci_dimm_thresholds thresholds;
+	} dimm[DIMM_NUMS_MAX];
+	char **dimmtemp_label;
+	DECLARE_BITMAP(dimm_mask, DIMM_NUMS_MAX);
+	u8 no_dimm_retry_count;
+};
+
+static u8 __dimm_temp(u32 reg, int dimm_order)
+{
+	return (reg >> (dimm_order * 8)) & 0xff;
+}
+
+static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no, long *val)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	int ret = 0;
+	u32 data;
+
+	mutex_lock(&priv->dimm[dimm_no].temp.state.lock);
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].temp.state))
+		goto skip_update;
+
+	ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &data);
+	if (ret)
+		goto unlock;
+
+	priv->dimm[dimm_no].temp.value = __dimm_temp(data, dimm_order) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].temp.state);
+
+skip_update:
+	*val = priv->dimm[dimm_no].temp.value;
+unlock:
+	mutex_unlock(&priv->dimm[dimm_no].temp.state.lock);
+	return ret;
+}
+
+static int update_thresholds(struct peci_dimmtemp *priv, int dimm_no)
+{
+	int dimm_order = dimm_no % priv->gen_info->dimm_idx_max;
+	int chan_rank = dimm_no / priv->gen_info->dimm_idx_max;
+	u32 data;
+	int ret;
+
+	if (!peci_sensor_need_update(&priv->dimm[dimm_no].thresholds.state))
+		return 0;
+
+	ret = priv->gen_info->read_thresholds(priv, dimm_order, chan_rank, &data);
+	if (ret == -ENODATA) /* Use default or previous value */
+		return 0;
+	if (ret)
+		return ret;
+
+	priv->dimm[dimm_no].thresholds.temp_max = GET_TEMP_MAX(data) * MILLIDEGREE_PER_DEGREE;
+	priv->dimm[dimm_no].thresholds.temp_crit = GET_TEMP_CRIT(data) * MILLIDEGREE_PER_DEGREE;
+
+	peci_sensor_mark_updated(&priv->dimm[dimm_no].thresholds.state);
+
+	return 0;
+}
+
+static int get_dimm_thresholds(struct peci_dimmtemp *priv, enum peci_dimm_threshold_type type,
+			       int dimm_no, long *val)
+{
+	int ret;
+
+	mutex_lock(&priv->dimm[dimm_no].thresholds.state.lock);
+	ret = update_thresholds(priv, dimm_no);
+	if (ret)
+		goto unlock;
+
+	switch (type) {
+	case temp_max_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_max;
+		break;
+	case temp_crit_type:
+		*val = priv->dimm[dimm_no].thresholds.temp_crit;
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+unlock:
+	mutex_unlock(&priv->dimm[dimm_no].thresholds.state.lock);
+
+	return ret;
+}
+
+static int dimmtemp_read_string(struct device *dev,
+				enum hwmon_sensor_types type,
+				u32 attr, int channel, const char **str)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	if (attr != hwmon_temp_label)
+		return -EOPNOTSUPP;
+
+	*str = (const char *)priv->dimmtemp_label[channel];
+
+	return 0;
+}
+
+static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type,
+			 u32 attr, int channel, long *val)
+{
+	struct peci_dimmtemp *priv = dev_get_drvdata(dev);
+
+	switch (attr) {
+	case hwmon_temp_input:
+		return get_dimm_temp(priv, channel, val);
+	case hwmon_temp_max:
+		return get_dimm_thresholds(priv, temp_max_type, channel, val);
+	case hwmon_temp_crit:
+		return get_dimm_thresholds(priv, temp_crit_type, channel, val);
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static umode_t dimmtemp_is_visible(const void *data, enum hwmon_sensor_types type,
+				   u32 attr, int channel)
+{
+	const struct peci_dimmtemp *priv = data;
+
+	if (test_bit(channel, priv->dimm_mask))
+		return 0444;
+
+	return 0;
+}
+
+static const struct hwmon_ops peci_dimmtemp_ops = {
+	.is_visible = dimmtemp_is_visible,
+	.read_string = dimmtemp_read_string,
+	.read = dimmtemp_read,
+};
+
+static int check_populated_dimms(struct peci_dimmtemp *priv)
+{
+	int chan_rank_max = priv->gen_info->chan_rank_max;
+	int dimm_idx_max = priv->gen_info->dimm_idx_max;
+	u32 chan_rank_empty = 0;
+	u64 dimm_mask = 0;
+	int chan_rank, dimm_idx, ret;
+	u32 pcs;
+
+	BUILD_BUG_ON(BITS_PER_TYPE(chan_rank_empty) < CHAN_RANK_MAX);
+	BUILD_BUG_ON(BITS_PER_TYPE(dimm_mask) < DIMM_NUMS_MAX);
+	if (chan_rank_max * dimm_idx_max > DIMM_NUMS_MAX) {
+		WARN_ONCE(1, "Unsupported number of DIMMs - chan_rank_max: %d, dimm_idx_max: %d",
+			  chan_rank_max, dimm_idx_max);
+		return -EINVAL;
+	}
+
+	for (chan_rank = 0; chan_rank < chan_rank_max; chan_rank++) {
+		ret = peci_pcs_read(priv->peci_dev, PECI_PCS_DDR_DIMM_TEMP, chan_rank, &pcs);
+		if (ret) {
+			/*
+			 * Overall, we expect either success or -EINVAL in
+			 * order to determine whether DIMM is populated or not.
+			 * For anything else we fall back to deferring the
+			 * detection to be performed at a later point in time.
+			 */
+			if (ret == -EINVAL) {
+				chan_rank_empty |= BIT(chan_rank);
+				continue;
+			}
+
+			return -EAGAIN;
+		}
+
+		for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++)
+			if (__dimm_temp(pcs, dimm_idx))
+				dimm_mask |= BIT(chan_rank * dimm_idx_max + dimm_idx);
+	}
+
+	/*
+	 * If we got all -EINVALs, it means that the CPU doesn't have any
+	 * DIMMs. Unfortunately, it may also happen at the very start of
+	 * host platform boot. Retrying a couple of times lets us make sure
+	 * that the state is persistent.
+	 */
+	if (chan_rank_empty == GENMASK(chan_rank_max - 1, 0)) {
+		if (priv->no_dimm_retry_count < NO_DIMM_RETRY_COUNT_MAX) {
+			priv->no_dimm_retry_count++;
+
+			return -EAGAIN;
+		}
+
+		return -ENODEV;
+	}
+
+	/*
+	 * It's possible that memory training is not done yet. In this case we
+	 * defer the detection to be performed at a later point in time.
+	 */
+	if (!dimm_mask) {
+		priv->no_dimm_retry_count = 0;
+		return -EAGAIN;
+	}
+
+	dev_dbg(priv->dev, "Scanned populated DIMMs: %#llx\n", dimm_mask);
+
+	bitmap_from_u64(priv->dimm_mask, dimm_mask);
+
+	return 0;
+}
+
+static int create_dimm_temp_label(struct peci_dimmtemp *priv, int chan)
+{
+	int rank = chan / priv->gen_info->dimm_idx_max;
+	int idx = chan % priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label[chan] = devm_kasprintf(priv->dev, GFP_KERNEL,
+						    "DIMM %c%d", 'A' + rank,
+						    idx + 1);
+	if (!priv->dimmtemp_label[chan])
+		return -ENOMEM;
+
+	return 0;
+}
+
+static const u32 peci_dimmtemp_temp_channel_config[] = {
+	[0 ... DIMM_NUMS_MAX - 1] = HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT,
+	0
+};
+
+static const struct hwmon_channel_info peci_dimmtemp_temp_channel = {
+	.type = hwmon_temp,
+	.config = peci_dimmtemp_temp_channel_config,
+};
+
+static const struct hwmon_channel_info *peci_dimmtemp_temp_info[] = {
+	&peci_dimmtemp_temp_channel,
+	NULL
+};
+
+static const struct hwmon_chip_info peci_dimmtemp_chip_info = {
+	.ops = &peci_dimmtemp_ops,
+	.info = peci_dimmtemp_temp_info,
+};
+
+static int create_dimm_temp_info(struct peci_dimmtemp *priv)
+{
+	int ret, i, channels;
+	struct device *dev;
+
+	/*
+	 * We expect to either find populated DIMMs and carry on with creating
+	 * sensors, or find out that there are no DIMMs populated.
+	 * All other states mean that the platform never reached the state that
+	 * allows to check DIMM state - causing us to retry later on.
+	 */
+	ret = check_populated_dimms(priv);
+	if (ret == -ENODEV) {
+		dev_dbg(priv->dev, "No DIMMs found\n");
+		return 0;
+	} else if (ret) {
+		schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
+		dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
+		return ret;
+	}
+
+	channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
+
+	priv->dimmtemp_label = devm_kzalloc(priv->dev, channels * sizeof(char *), GFP_KERNEL);
+	if (!priv->dimmtemp_label)
+		return -ENOMEM;
+
+	for_each_set_bit(i, priv->dimm_mask, DIMM_NUMS_MAX) {
+		ret = create_dimm_temp_label(priv, i);
+		if (ret)
+			return ret;
+		mutex_init(&priv->dimm[i].thresholds.state.lock);
+		mutex_init(&priv->dimm[i].temp.state.lock);
+	}
+
+	dev = devm_hwmon_device_register_with_info(priv->dev, priv->name, priv,
+						   &peci_dimmtemp_chip_info, NULL);
+	if (IS_ERR(dev)) {
+		dev_err(priv->dev, "Failed to register hwmon device\n");
+		return PTR_ERR(dev);
+	}
+
+	dev_dbg(priv->dev, "%s: sensor '%s'\n", dev_name(dev), priv->name);
+
+	return 0;
+}
+
+static void create_dimm_temp_info_delayed(struct work_struct *work)
+{
+	struct peci_dimmtemp *priv = container_of(to_delayed_work(work),
+						  struct peci_dimmtemp,
+						  detect_work);
+	int ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN)
+		dev_err(priv->dev, "Failed to populate DIMM temp info\n");
+}
+
+static void remove_delayed_work(void *_priv)
+{
+	struct peci_dimmtemp *priv = _priv;
+
+	cancel_delayed_work_sync(&priv->detect_work);
+}
+
+static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct peci_device *peci_dev = to_peci_device(dev->parent);
+	struct peci_dimmtemp *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->name = devm_kasprintf(dev, GFP_KERNEL, "peci_dimmtemp.cpu%d",
+				    peci_dev->info.socket_id);
+	if (!priv->name)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->peci_dev = peci_dev;
+	priv->gen_info = (const struct dimm_info *)id->driver_data;
+
+	/*
+	 * This is just a sanity check. Since we're using commands that are
+	 * guaranteed to be supported on a given platform, we should never see
+	 * revision lower than expected.
+	 */
+	if (peci_dev->info.peci_revision < priv->gen_info->min_peci_revision)
+		dev_warn(priv->dev,
+			 "Unexpected PECI revision %#x, some features may be unavailable\n",
+			 peci_dev->info.peci_revision);
+
+	INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
+
+	ret = devm_add_action_or_reset(priv->dev, remove_delayed_work, priv);
+	if (ret)
+		return ret;
+
+	ret = create_dimm_temp_info(priv);
+	if (ret && ret != -EAGAIN) {
+		dev_err(dev, "Failed to populate DIMM temp info\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int
+read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 20, Function 0: IMC 0 channel 0 -> rank 0
+	 * Device 20, Function 1: IMC 0 channel 1 -> rank 1
+	 * Device 21, Function 0: IMC 0 channel 2 -> rank 2
+	 * Device 21, Function 1: IMC 0 channel 3 -> rank 3
+	 * Device 23, Function 0: IMC 1 channel 0 -> rank 4
+	 * Device 23, Function 1: IMC 1 channel 1 -> rank 5
+	 * Device 24, Function 0: IMC 1 channel 2 -> rank 6
+	 * Device 24, Function 1: IMC 1 channel 3 -> rank 7
+	 */
+	dev = 20 + chan_rank / 2 + chan_rank / 4;
+	func = chan_rank % 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 1, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_bdxd(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 2
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 3
+	 */
+	dev = 10 + chan_rank / 2 * 2;
+	func = (chan_rank % 2) ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_skx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u8 dev, func;
+	u16 reg;
+	int ret;
+
+	/*
+	 * Device 10, Function 2: IMC 0 channel 0 -> rank 0
+	 * Device 10, Function 6: IMC 0 channel 1 -> rank 1
+	 * Device 11, Function 2: IMC 0 channel 2 -> rank 2
+	 * Device 12, Function 2: IMC 1 channel 0 -> rank 3
+	 * Device 12, Function 6: IMC 1 channel 1 -> rank 4
+	 * Device 13, Function 2: IMC 1 channel 2 -> rank 5
+	 */
+	dev = 10 + chan_rank / 3 * 2 + (chan_rank % 3 == 2 ? 1 : 0);
+	func = chan_rank % 3 == 1 ? 6 : 2;
+	reg = 0x120 + dimm_order * 4;
+
+	ret = peci_pci_local_read(priv->peci_dev, 2, dev, func, reg, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int
+read_thresholds_icx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
+{
+	u32 reg_val;
+	u64 offset;
+	int ret;
+	u8 dev;
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd4, &reg_val);
+	if (ret || !(reg_val & BIT(31)))
+		return -ENODATA; /* Use default or previous value */
+
+	ret = peci_ep_pci_local_read(priv->peci_dev, 0, 13, 0, 2, 0xd0, &reg_val);
+	if (ret)
+		return -ENODATA; /* Use default or previous value */
+
+	/*
+	 * Device 26, Offset 224e0: IMC 0 channel 0 -> rank 0
+	 * Device 26, Offset 264e0: IMC 0 channel 1 -> rank 1
+	 * Device 27, Offset 224e0: IMC 1 channel 0 -> rank 2
+	 * Device 27, Offset 264e0: IMC 1 channel 1 -> rank 3
+	 * Device 28, Offset 224e0: IMC 2 channel 0 -> rank 4
+	 * Device 28, Offset 264e0: IMC 2 channel 1 -> rank 5
+	 * Device 29, Offset 224e0: IMC 3 channel 0 -> rank 6
+	 * Device 29, Offset 264e0: IMC 3 channel 1 -> rank 7
+	 */
+	dev = 26 + chan_rank / 2;
+	offset = 0x224e0 + dimm_order * 4 + (chan_rank % 2) * 0x4000;
+
+	ret = peci_mmio_read(priv->peci_dev, 0, GET_CPU_SEG(reg_val), GET_CPU_BUS(reg_val),
+			     dev, 0, offset, data);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct dimm_info dimm_hsx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_HSX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_HSX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_hsx,
+};
+
+static const struct dimm_info dimm_bdxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_BDXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_BDXD,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_bdxd,
+};
+
+static const struct dimm_info dimm_skx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_SKX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_SKX,
+	.min_peci_revision = 0x33,
+	.read_thresholds = &read_thresholds_skx,
+};
+
+static const struct dimm_info dimm_icx = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICX,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICX,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct dimm_info dimm_icxd = {
+	.chan_rank_max	= CHAN_RANK_MAX_ON_ICXD,
+	.dimm_idx_max	= DIMM_IDX_MAX_ON_ICXD,
+	.min_peci_revision = 0x40,
+	.read_thresholds = &read_thresholds_icx,
+};
+
+static const struct auxiliary_device_id peci_dimmtemp_ids[] = {
+	{
+		.name = "peci_cpu.dimmtemp.hsx",
+		.driver_data = (kernel_ulong_t)&dimm_hsx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdx",
+		.driver_data = (kernel_ulong_t)&dimm_bdx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.bdxd",
+		.driver_data = (kernel_ulong_t)&dimm_bdxd,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.skx",
+		.driver_data = (kernel_ulong_t)&dimm_skx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icx",
+		.driver_data = (kernel_ulong_t)&dimm_icx,
+	},
+	{
+		.name = "peci_cpu.dimmtemp.icxd",
+		.driver_data = (kernel_ulong_t)&dimm_icxd,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
+
+static struct auxiliary_driver peci_dimmtemp_driver = {
+	.probe		= peci_dimmtemp_probe,
+	.id_table	= peci_dimmtemp_ids,
+};
+
+module_auxiliary_driver(peci_dimmtemp_driver);
+
+MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>");
+MODULE_AUTHOR("Iwona Winiarska <iwona.winiarska at intel.com>");
+MODULE_DESCRIPTION("PECI dimmtemp driver");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(PECI_CPU);
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:11:03 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:11:03 +0100
Subject: [PATCH v6 12/13] docs: hwmon: Document PECI drivers
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-13-iwona.winiarska@intel.com>

From: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>

Add documentation for peci-cputemp driver that provides DTS thermal
readings for CPU packages and CPU cores, and peci-dimmtemp driver that
provides Temperature Sensor on DIMM readings.

Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
Co-developed-by: Iwona Winiarska <iwona.winiarska at intel.com>
Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Acked-by: Guenter Roeck <linux at roeck-us.net>
---
 Documentation/hwmon/index.rst         |  2 +
 Documentation/hwmon/peci-cputemp.rst  | 90 +++++++++++++++++++++++++++
 Documentation/hwmon/peci-dimmtemp.rst | 57 +++++++++++++++++
 MAINTAINERS                           |  2 +
 4 files changed, 151 insertions(+)
 create mode 100644 Documentation/hwmon/peci-cputemp.rst
 create mode 100644 Documentation/hwmon/peci-dimmtemp.rst

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index df20022c741f..f387f661e1d7 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -161,6 +161,8 @@ Hardware Monitoring Kernel Drivers
    pcf8591
    pim4328
    pm6764tr
+   peci-cputemp
+   peci-dimmtemp
    pmbus
    powr1220
    pxe1610
diff --git a/Documentation/hwmon/peci-cputemp.rst b/Documentation/hwmon/peci-cputemp.rst
new file mode 100644
index 000000000000..fe0422248dc5
--- /dev/null
+++ b/Documentation/hwmon/peci-cputemp.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+Kernel driver peci-cputemp
+==========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides Digital
+Thermal Sensor (DTS) thermal readings of the CPU package and CPU cores that are
+accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+temp1_label		"Die"
+temp1_input		Provides current die temperature of the CPU package.
+temp1_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp1_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp1_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp2_label		"DTS"
+temp2_input		Provides current temperature of the CPU package scaled
+			to match DTS thermal profile.
+temp2_max		Provides thermal control temperature of the CPU package
+			which is also known as Tcontrol.
+temp2_crit		Provides shutdown temperature of the CPU package which
+			is also known as the maximum processor junction
+			temperature, Tjmax or Tprochot.
+temp2_crit_hyst		Provides the hysteresis value from Tcontrol to Tjmax of
+			the CPU package.
+
+temp3_label		"Tcontrol"
+temp3_input		Provides current Tcontrol temperature of the CPU
+			package which is also known as Fan Temperature target.
+			Indicates the relative value from thermal monitor trip
+			temperature at which fans should be engaged.
+temp3_crit		Provides Tcontrol critical value of the CPU package
+			which is same to Tjmax.
+
+temp4_label		"Tthrottle"
+temp4_input		Provides current Tthrottle temperature of the CPU
+			package. Used for throttling temperature. If this value
+			is allowed and lower than Tjmax - the throttle will
+			occur and reported at lower than Tjmax.
+
+temp5_label		"Tjmax"
+temp5_input		Provides the maximum junction temperature, Tjmax of the
+			CPU package.
+
+temp[6-N]_label		Provides string "Core X", where X is resolved core
+			number.
+temp[6-N]_input		Provides current temperature of each core.
+
+======================= =======================================================
diff --git a/Documentation/hwmon/peci-dimmtemp.rst b/Documentation/hwmon/peci-dimmtemp.rst
new file mode 100644
index 000000000000..e562aed620de
--- /dev/null
+++ b/Documentation/hwmon/peci-dimmtemp.rst
@@ -0,0 +1,57 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver peci-dimmtemp
+===========================
+
+Supported chips:
+	One of Intel server CPUs listed below which is connected to a PECI bus.
+		* Intel Xeon E5/E7 v3 server processors
+			Intel Xeon E5-14xx v3 family
+			Intel Xeon E5-24xx v3 family
+			Intel Xeon E5-16xx v3 family
+			Intel Xeon E5-26xx v3 family
+			Intel Xeon E5-46xx v3 family
+			Intel Xeon E7-48xx v3 family
+			Intel Xeon E7-88xx v3 family
+		* Intel Xeon E5/E7 v4 server processors
+			Intel Xeon E5-16xx v4 family
+			Intel Xeon E5-26xx v4 family
+			Intel Xeon E5-46xx v4 family
+			Intel Xeon E7-48xx v4 family
+			Intel Xeon E7-88xx v4 family
+		* Intel Xeon Scalable server processors
+			Intel Xeon D family
+			Intel Xeon Bronze family
+			Intel Xeon Silver family
+			Intel Xeon Gold family
+			Intel Xeon Platinum family
+
+	Datasheet: Available from http://www.intel.com/design/literature.htm
+
+Author: Jae Hyun Yoo <jae.hyun.yoo at linux.intel.com>
+
+Description
+-----------
+
+This driver implements a generic PECI hwmon feature which provides
+Temperature sensor on DIMM readings that are accessible via the processor PECI interface.
+
+All temperature values are given in millidegree Celsius and will be measurable
+only when the target CPU is powered on.
+
+Sysfs interface
+-------------------
+
+======================= =======================================================
+
+temp[N]_label		Provides string "DIMM CI", where C is DIMM channel and
+			I is DIMM index of the populated DIMM.
+temp[N]_input		Provides current temperature of the populated DIMM.
+temp[N]_max		Provides thermal control temperature of the DIMM.
+temp[N]_crit		Provides shutdown temperature of the DIMM.
+
+======================= =======================================================
+
+Note:
+	DIMM temperature attributes will appear when the client CPU's BIOS
+	completes memory training and testing.
diff --git a/MAINTAINERS b/MAINTAINERS
index 369ac3524f33..d821aeaaa2d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15103,6 +15103,8 @@ PECI HARDWARE MONITORING DRIVERS
 M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	linux-hwmon at vger.kernel.org
 S:	Supported
+F:	Documentation/hwmon/peci-cputemp.rst
+F:	Documentation/hwmon/peci-dimmtemp.rst
 F:	drivers/hwmon/peci/
 
 PECI SUBSYSTEM
-- 
2.31.1



From iwona.winiarska at intel.com  Mon Jan 24 17:11:04 2022
From: iwona.winiarska at intel.com (Iwona Winiarska)
Date: Tue, 25 Jan 2022 02:11:04 +0100
Subject: [PATCH v6 13/13] docs: Add PECI documentation
In-Reply-To: <20220125011104.2480133-1-iwona.winiarska@intel.com>
References: <20220125011104.2480133-1-iwona.winiarska@intel.com>
Message-ID: <20220125011104.2480133-14-iwona.winiarska@intel.com>

Add a brief overview of PECI and PECI wire interface.
The documentation also contains kernel-doc for PECI subsystem internals
and PECI CPU Driver API.

Signed-off-by: Iwona Winiarska <iwona.winiarska at intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 Documentation/index.rst      |  1 +
 Documentation/peci/index.rst | 16 +++++++++++
 Documentation/peci/peci.rst  | 51 ++++++++++++++++++++++++++++++++++++
 MAINTAINERS                  |  1 +
 4 files changed, 69 insertions(+)
 create mode 100644 Documentation/peci/index.rst
 create mode 100644 Documentation/peci/peci.rst

diff --git a/Documentation/index.rst b/Documentation/index.rst
index 2b4de3926858..deaa7f669fcd 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -138,6 +138,7 @@ needed).
    scheduler/index
    mhi/index
    tty/index
+   peci/index
 
 Architecture-agnostic documentation
 -----------------------------------
diff --git a/Documentation/peci/index.rst b/Documentation/peci/index.rst
new file mode 100644
index 000000000000..989de10416e7
--- /dev/null
+++ b/Documentation/peci/index.rst
@@ -0,0 +1,16 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+====================
+Linux PECI Subsystem
+====================
+
+.. toctree::
+
+   peci
+
+.. only::  subproject and html
+
+   Indices
+   =======
+
+   * :ref:`genindex`
diff --git a/Documentation/peci/peci.rst b/Documentation/peci/peci.rst
new file mode 100644
index 000000000000..331b1ec00e22
--- /dev/null
+++ b/Documentation/peci/peci.rst
@@ -0,0 +1,51 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+========
+Overview
+========
+
+The Platform Environment Control Interface (PECI) is a communication
+interface between Intel processor and management controllers
+(e.g. Baseboard Management Controller, BMC).
+PECI provides services that allow the management controller to
+configure, monitor and debug platform by accessing various registers.
+It defines a dedicated command protocol, where the management
+controller is acting as a PECI originator and the processor - as
+a PECI responder.
+PECI can be used in both single processor and multiple-processor based
+systems.
+
+NOTE:
+Intel PECI specification is not released as a dedicated document,
+instead it is a part of External Design Specification (EDS) for given
+Intel CPU. External Design Specifications are usually not publicly
+available.
+
+PECI Wire
+---------
+
+PECI Wire interface uses a single wire for self-clocking and data
+transfer. It does not require any additional control lines - the
+physical layer is a self-clocked one-wire bus signal that begins each
+bit with a driven, rising edge from an idle near zero volts. The
+duration of the signal driven high allows to determine whether the bit
+value is logic '0' or logic '1'. PECI Wire also includes variable data
+rate established with every message.
+
+For PECI Wire, each processor package will utilize unique, fixed
+addresses within a defined range and that address should
+have a fixed relationship with the processor socket ID - if one of the
+processors is removed, it does not affect addresses of remaining
+processors.
+
+PECI subsystem internals
+------------------------
+
+.. kernel-doc:: include/linux/peci.h
+.. kernel-doc:: drivers/peci/internal.h
+.. kernel-doc:: drivers/peci/core.c
+.. kernel-doc:: drivers/peci/request.c
+
+PECI CPU Driver API
+-------------------
+.. kernel-doc:: drivers/peci/cpu.c
diff --git a/MAINTAINERS b/MAINTAINERS
index d821aeaaa2d3..06449cc42a10 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15112,6 +15112,7 @@ M:	Iwona Winiarska <iwona.winiarska at intel.com>
 L:	openbmc at lists.ozlabs.org (moderated for non-subscribers)
 S:	Supported
 F:	Documentation/devicetree/bindings/peci/
+F:	Documentation/peci/
 F:	drivers/peci/
 F:	include/linux/peci-cpu.h
 F:	include/linux/peci.h
-- 
2.31.1



From sboyd at kernel.org  Mon Jan 24 17:18:33 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:18:33 -0800
Subject: [PATCH v2] clk: zynqmp: replace warn_once with pr_debug for
 failed clock ops
In-Reply-To: <20220119115434.2042017-1-m.tretter@pengutronix.de>
References: <20220119115434.2042017-1-m.tretter@pengutronix.de>
Message-ID: <20220125011835.5D84FC340E4@smtp.kernel.org>

Quoting Michael Tretter (2022-01-19 03:54:34)
> The warning that a clock operation failed is only printed once. However,
> the function is called for various different clocks. The limit hides the
> warnings if different clocks are affected by the failures.
> 
> The clock ops might fail if the firmware that handles the clocks is
> misconfigured. Therefore, replace the pr_warn_once with pr_debug to
> allow the user to see all errors if necessary. By default, hide the
> error messages and let drivers handle the errors.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> ---

Applied to clk-next


From leilk.liu at mediatek.com  Mon Jan 24 17:18:51 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 25 Jan 2022 09:18:51 +0800
Subject: [PATCH V3 1/2] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <Ye6nQIVoti5TKh+k@sirena.org.uk>
References: <20220124061238.7854-1-leilk.liu@mediatek.com>
 <20220124061238.7854-2-leilk.liu@mediatek.com>
 <Ye6nQIVoti5TKh+k@sirena.org.uk>
Message-ID: <184823d40e24166246b2be1fc823a18d413e341d.camel@mediatek.com>

On Mon, 2022-01-24 at 13:18 +0000, Mark Brown wrote:
> On Mon, Jan 24, 2022 at 02:12:37PM +0800, Leilk Liu wrote:
> > Convert Mediatek ARM SOC's SPI Master controller binding
> > to json-schema format.
> 
> Please make any YAML conversion patches the last patches in a series
> -
> there's frequently a backlog in reviewing them so having the DT
> binding
> patches first blocks any progress on everything else in the series.

OK, I mistake to lost " dt-bindings: spi: Convert spi-slave-mt27xx to
json-schema" on V3 series, I'll send it again, thanks

> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

From leilk.liu at mediatek.com  Mon Jan 24 17:23:29 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 25 Jan 2022 09:23:29 +0800
Subject: [PATCH V4 2/3] dt-bindings: spi: Convert spi-mt65xx to json-schema
In-Reply-To: <20220125012330.13449-1-leilk.liu@mediatek.com>
References: <20220125012330.13449-1-leilk.liu@mediatek.com>
Message-ID: <20220125012330.13449-3-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Master controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 101 ++++++++++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    |  68 ------------
 2 files changed, 101 insertions(+), 68 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
new file mode 100644
index 000000000000..ea977fba49a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-mt65xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Bus controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: "/schemas/spi/spi-controller.yaml#"
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt7629-spi
+          - const: mediatek,mt7622-spi
+      - items:
+          - enum:
+              - mediatek,mt8516-spi
+          - const: mediatek,mt2712-spi
+      - items:
+          - enum:
+              - mediatek,mt6779-spi
+              - mediatek,mt8192-spi
+              - mediatek,mt8195-spi
+          - const: mediatek,mt6765-spi
+      - items:
+          - enum:
+              - mediatek,mt2701-spi
+              - mediatek,mt2712-spi
+              - mediatek,mt6589-spi
+              - mediatek,mt6765-spi
+              - mediatek,mt6893-spi
+              - mediatek,mt7622-spi
+              - mediatek,mt8135-spi
+              - mediatek,mt8173-spi
+              - mediatek,mt8183-spi
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: clock used for the parent clock
+      - description: clock used for the muxes clock
+      - description: clock used for the clock gate
+
+  clock-names:
+    items:
+      - const: parent-clk
+      - const: sel-clk
+      - const: spi-clk
+
+  mediatek,pad-select:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    maxItems: 4
+    items:
+      enum: [0, 1, 2, 3]
+    description:
+      specify which pins group(ck/mi/mo/cs) spi controller used.
+      This is an array.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#address-cells'
+  - '#size-cells'
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8173-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 1100a000 {
+      compatible = "mediatek,mt8173-spi";
+      #address-cells = <1>;
+      #size-cells = <0>;
+      reg = <0x1100a000 0x1000>;
+      interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+               <&topckgen CLK_TOP_SPI_SEL>,
+               <&pericfg CLK_PERI_SPI0>;
+      clock-names = "parent-clk", "sel-clk", "spi-clk";
+      cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
+      mediatek,pad-select = <1>, <0>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
deleted file mode 100644
index 2a24969159cc..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt
+++ /dev/null
@@ -1,68 +0,0 @@
-Binding for MTK SPI controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2701-spi: for mt2701 platforms
-    - mediatek,mt2712-spi: for mt2712 platforms
-    - mediatek,mt6589-spi: for mt6589 platforms
-    - mediatek,mt6765-spi: for mt6765 platforms
-    - mediatek,mt7622-spi: for mt7622 platforms
-    - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
-    - mediatek,mt8135-spi: for mt8135 platforms
-    - mediatek,mt8173-spi: for mt8173 platforms
-    - mediatek,mt8183-spi: for mt8183 platforms
-    - mediatek,mt6893-spi: for mt6893 platforms
-    - "mediatek,mt8192-spi", "mediatek,mt6765-spi": for mt8192 platforms
-    - "mediatek,mt8195-spi", "mediatek,mt6765-spi": for mt8195 platforms
-    - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms
-    - "mediatek,mt6779-spi", "mediatek,mt6765-spi": for mt6779 platforms
-
-- #address-cells: should be 1.
-
-- #size-cells: should be 0.
-
-- reg: Address and length of the register set for the device
-
-- interrupts: Should contain spi interrupt
-
-- clocks: phandles to input clocks.
-  The first should be one of the following. It's PLL.
-   -  <&clk26m>: specify parent clock 26MHZ.
-   -  <&topckgen CLK_TOP_SYSPLL3_D2>: specify parent clock 109MHZ.
-				      It's the default one.
-   -  <&topckgen CLK_TOP_SYSPLL4_D2>: specify parent clock 78MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-  The second should be <&topckgen CLK_TOP_SPI_SEL>. It's clock mux.
-  The third is <&pericfg CLK_PERI_SPI0>. It's clock gate.
-
-- clock-names: shall be "parent-clk" for the parent clock, "sel-clk" for the
-  muxes clock, and "spi-clk" for the clock gate.
-
-Optional properties:
--cs-gpios: see spi-bus.txt.
-
-- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi
-  controller used. This is an array, the element value should be 0~3,
-  only required for MT8173.
-    0: specify GPIO69,70,71,72 for spi pins.
-    1: specify GPIO102,103,104,105 for spi pins.
-    2: specify GPIO128,129,130,131 for spi pins.
-    3: specify GPIO5,6,7,8 for spi pins.
-
-Example:
-
-- SoC Specific Portion:
-spi: spi at 1100a000 {
-	compatible = "mediatek,mt8173-spi";
-	#address-cells = <1>;
-	#size-cells = <0>;
-	reg = <0 0x1100a000 0 0x1000>;
-	interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
-		 <&topckgen CLK_TOP_SPI_SEL>,
-		 <&pericfg CLK_PERI_SPI0>;
-	clock-names = "parent-clk", "sel-clk", "spi-clk";
-	cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
-	mediatek,pad-select = <1>, <0>;
-};
-- 
2.25.1



From leilk.liu at mediatek.com  Mon Jan 24 17:23:27 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 25 Jan 2022 09:23:27 +0800
Subject: [PATCH V4 0/3] Add compatible for Mediatek MT8186 
Message-ID: <20220125012330.13449-1-leilk.liu@mediatek.com>

Subject: [PATCH V4 0/3] Add compatible for Mediatek MT8186

V4:
1. add "dt-bindings: spi: Convert spi-slave-mt27xx to json-schema" to
this series again.

v3:
1. Fix Rob review comment in v2.

v2:
1. Fix Rob review comment.
2. split spi-mt65xx & spi-slave-mt27xx to 2 patches.

Leilk Liu (3):
  dt-bindings: spi: Convert spi-slave-mt27xx to json-schema
  dt-bindings: spi: Convert spi-mt65xx to json-schema
  dt-bindings: spi: Add compatible for Mediatek MT8186

 .../bindings/spi/mediatek,spi-mt65xx.yaml     | 102 ++++++++++++++++++
 .../spi/mediatek,spi-slave-mt27xx.yaml        |  58 ++++++++++
 .../devicetree/bindings/spi/spi-mt65xx.txt    |  68 ------------
 .../bindings/spi/spi-slave-mt27xx.txt         |  33 ------
 4 files changed, 160 insertions(+), 101 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

--
2.18.0




From leilk.liu at mediatek.com  Mon Jan 24 17:23:28 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 25 Jan 2022 09:23:28 +0800
Subject: [PATCH V4 1/3] dt-bindings: spi: Convert spi-slave-mt27xx to
 json-schema
In-Reply-To: <20220125012330.13449-1-leilk.liu@mediatek.com>
References: <20220125012330.13449-1-leilk.liu@mediatek.com>
Message-ID: <20220125012330.13449-2-leilk.liu@mediatek.com>

Convert Mediatek ARM SOC's SPI Slave controller binding
to json-schema format.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
---
 .../spi/mediatek,spi-slave-mt27xx.yaml        | 58 +++++++++++++++++++
 .../bindings/spi/spi-slave-mt27xx.txt         | 33 -----------
 2 files changed, 58 insertions(+), 33 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
 delete mode 100644 Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
new file mode 100644
index 000000000000..7977799a8ee1
--- /dev/null
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-slave-mt27xx.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/spi/mediatek,spi-slave-mt27xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SPI Slave controller for MediaTek ARM SoCs
+
+maintainers:
+  - Leilk Liu <leilk.liu at mediatek.com>
+
+allOf:
+  - $ref: "/schemas/spi/spi-controller.yaml#"
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt2712-spi-slave
+      - mediatek,mt8195-spi-slave
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: spi
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt2712-clk.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi at 10013000 {
+      compatible = "mediatek,mt2712-spi-slave";
+      reg = <0x10013000 0x100>;
+      interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
+      clocks = <&infracfg CLK_INFRA_AO_SPI1>;
+      clock-names = "spi";
+      assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
+      assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+    };
diff --git a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt b/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
deleted file mode 100644
index 9192724540fd..000000000000
--- a/Documentation/devicetree/bindings/spi/spi-slave-mt27xx.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Binding for MTK SPI Slave controller
-
-Required properties:
-- compatible: should be one of the following.
-    - mediatek,mt2712-spi-slave: for mt2712 platforms
-    - mediatek,mt8195-spi-slave: for mt8195 platforms
-- reg: Address and length of the register set for the device.
-- interrupts: Should contain spi interrupt.
-- clocks: phandles to input clocks.
-  It's clock gate, and should be <&infracfg CLK_INFRA_AO_SPI1>.
-- clock-names: should be "spi" for the clock gate.
-
-Optional properties:
-- assigned-clocks: it's mux clock, should be <&topckgen CLK_TOP_SPISLV_SEL>.
-- assigned-clock-parents: parent of mux clock.
-  It's PLL, and should be one of the following.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D2>: specify parent clock 312MHZ.
-				       It's the default one.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D4>: specify parent clock 156MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL2_D4>: specify parent clock 104MHZ.
-   -  <&topckgen CLK_TOP_UNIVPLL1_D8>: specify parent clock 78MHZ.
-
-Example:
-- SoC Specific Portion:
-spis1: spi at 10013000 {
-	compatible = "mediatek,mt2712-spi-slave";
-	reg = <0 0x10013000 0 0x100>;
-	interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_LOW>;
-	clocks = <&infracfg CLK_INFRA_AO_SPI1>;
-	clock-names = "spi";
-	assigned-clocks = <&topckgen CLK_TOP_SPISLV_SEL>;
-	assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
-};
-- 
2.25.1



From leilk.liu at mediatek.com  Mon Jan 24 17:23:30 2022
From: leilk.liu at mediatek.com (Leilk Liu)
Date: Tue, 25 Jan 2022 09:23:30 +0800
Subject: [PATCH V4 3/3] dt-bindings: spi: Add compatible for Mediatek MT8186
In-Reply-To: <20220125012330.13449-1-leilk.liu@mediatek.com>
References: <20220125012330.13449-1-leilk.liu@mediatek.com>
Message-ID: <20220125012330.13449-4-leilk.liu@mediatek.com>

This commit adds dt-binding documentation of spi bus for Mediatek MT8186 SoC
Platform.

Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
index ea977fba49a7..bfa44acb1bdd 100644
--- a/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
+++ b/Documentation/devicetree/bindings/spi/mediatek,spi-mt65xx.yaml
@@ -26,6 +26,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt6779-spi
+              - mediatek,mt8186-spi
               - mediatek,mt8192-spi
               - mediatek,mt8195-spi
           - const: mediatek,mt6765-spi
-- 
2.25.1



From andrew at lunn.ch  Mon Jan 24 17:32:40 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 25 Jan 2022 02:32:40 +0100
Subject: [PATCH net 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <CO1PR11MB47716D7115E85AC4649CD3A5D55E9@CO1PR11MB4771.namprd11.prod.outlook.com>
References: <20220124095951.23845-1-mohammad.athari.ismail@intel.com>
 <20220124095951.23845-3-mohammad.athari.ismail@intel.com>
 <Ye6maxMtt68JlZ9l@lunn.ch>
 <CO1PR11MB47716D7115E85AC4649CD3A5D55E9@CO1PR11MB4771.namprd11.prod.outlook.com>
Message-ID: <Ye9TOHoFJi3PjhNV@lunn.ch>

> > > @@ -3308,13 +3309,11 @@ static int stmmac_hw_setup(struct net_device
> > *dev, bool init_ptp)
...

> > The init_ptp parameter now seems unused? If so, please remove it.
> 
> I believe you miss below diff. It is renamed to ptp_register.

Ah, yes, sorry. I was looking at the context information diff gives
you, which still has the old name.

      Andrew


From jammy_huang at aspeedtech.com  Mon Jan 24 17:37:51 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 25 Jan 2022 09:37:51 +0800
Subject: [PATCH v2 4/4] media: aspeed: Fix timing polarity incorrect
In-Reply-To: <2ddda01a-3f1f-eff6-6ce1-a5b9354f2993@xs4all.nl>
References: <20211222082139.26933-1-jammy_huang@aspeedtech.com>
 <20211222082139.26933-5-jammy_huang@aspeedtech.com>
 <418fc1b2-ddbe-24e3-82cc-aa8ce74f4507@xs4all.nl>
 <b8707885-c10c-ca19-3f2c-f19f567e1f92@aspeedtech.com>
 <2ddda01a-3f1f-eff6-6ce1-a5b9354f2993@xs4all.nl>
Message-ID: <fbe1742c-2afd-bc09-b565-783b080a1418@aspeedtech.com>


On 2022/1/24 ?? 06:22, Hans Verkuil wrote:
> On 24/01/2022 03:29, Jammy Huang wrote:
>> On 2022/1/21 ?? 03:30, Hans Verkuil wrote:
>>> On 12/22/21 09:21, Jammy Huang wrote:
>>>> This is a workaround for sync polarity unstable.
>>>> Sync value get by VR09C counts from sync's rising edge, which means
>>>> sync's polarity is negative if sync value is bigger than total/2.
>>> Do you have an example of such a format, or is this mostly theoretical?
>>>
>>> Either provide the example or make a note that it is theoretical.
>> OK, I will update an example in next patch. Let me explain first.
>>
>> This is a must-be result. Please refer to the graph below as I sent in 3/4 of this
>> series. For negative sync, sync width equals to back porch + data enable + front porch.
>> Thus, sync would be bigger than 90% of total in most cases.
> Right, I suspected that might be the case.
>
> I think it would be better to combine patches 3 and 4 into a single
> patch, since they are closely related and it is actually easier to
> understand if it's just a single patch.
OK, I will combine 3/4 into a single patch in next series.
Thanks.

Best Regards,

 ??? ??? Jammy
>
> Regards,
>
> 	Hans
>
>>  ????????????????? +-------------------+
>>  ????????????????? |??? v i d e o????? |
>>  ????? +--+? +-----+?????????????????? +-----+? +---+
>>  ???????? |? |?????????????????????????????? |? |
>>  ???????? +--+?????????????????????????????? +--+
>>  ?????? vsync+-------------------------------+
>>  ?? frame_top+-----+
>> frame_bottom+-------------------------+
>>
>>
>> Following registers are what I got for 1920x1200 at 60.
>>
>> 1e700090: 07ee206f 04c9001a c4d3efff 04cc001f
>>
>> 1e7000a0: 0000081f 00000000 00000000 00000000
>>
>> vertical total = 0x4D3 (VR098[27:16]) = 1235
>> vertical sync = 0x4CC (VR09C[27:16]) = 1228
>>
>>> Regards,
>>>
>>>  ????Hans
>>>
>>>> Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
>>>> ---
>>>>  ? v2:
>>>>  ?? - Use 'total/2' rather than 'total<<1'
>>>>  ?? - Update comment
>>>> ---
>>>>  ? drivers/media/platform/aspeed-video.c | 20 ++++++++++++++++++++
>>>>  ? 1 file changed, 20 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
>>>> index 7c50567f5ab0..c3e3343d91e1 100644
>>>> --- a/drivers/media/platform/aspeed-video.c
>>>> +++ b/drivers/media/platform/aspeed-video.c
>>>> @@ -989,6 +989,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>>>  ? ????????? video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
>>>>  ????????? video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
>>>> +
>>>> +??????? /*
>>>> +???????? * This is a workaround for polarity detection when the sync
>>>> +???????? * value is larger than half.
>>>> +???????? */
>>>> +??????? if (vsync > (vtotal / 2))
>>>> +??????????? det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
>>>> +??????? else
>>>> +??????????? det->polarities |= V4L2_DV_VSYNC_POS_POL;
>>>> +
>>>>  ????????? if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
>>>>  ????????????? det->vbackporch = video->frame_top - vsync;
>>>>  ????????????? det->vfrontporch = vtotal - video->frame_bottom;
>>>> @@ -1003,6 +1013,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
>>>>  ? ????????? video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
>>>>  ????????? video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
>>>> +
>>>> +??????? /*
>>>> +???????? * This is a workaround for polarity detection when the sync
>>>> +???????? * value is larger than half.
>>>> +???????? */
>>>> +??????? if (hsync > (htotal / 2))
>>>> +??????????? det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
>>>> +??????? else
>>>> +??????????? det->polarities |= V4L2_DV_HSYNC_POS_POL;
>>>> +
>>>>  ????????? if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
>>>>  ????????????? det->hbackporch = video->frame_left - hsync;
>>>>  ????????????? det->hfrontporch = htotal - video->frame_right;


From sboyd at kernel.org  Mon Jan 24 17:39:35 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Mon, 24 Jan 2022 17:39:35 -0800
Subject: [PATCH v8 06/10] clk: Add Sunplus SP7021 clock driver
In-Reply-To: <34eeb839f4657491a704d00b532b2d8858eb35b6.1642751015.git.qinjian@cqplus1.com>
References: <cover.1642751015.git.qinjian@cqplus1.com>
 <34eeb839f4657491a704d00b532b2d8858eb35b6.1642751015.git.qinjian@cqplus1.com>
Message-ID: <20220125013936.D7A71C340E5@smtp.kernel.org>

Quoting Qin Jian (2022-01-20 23:53:14)
> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
> index c5b3dc973..91656de22 100644
> --- a/drivers/clk/Kconfig
> +++ b/drivers/clk/Kconfig
> @@ -334,6 +334,15 @@ config COMMON_CLK_VC5
>           This driver supports the IDT VersaClock 5 and VersaClock 6
>           programmable clock generators.
>  
> +config COMMON_CLK_SP7021
> +       bool "Clock driver for Sunplus SP7021 SoC"
> +       default SOC_SP7021

Also would be good to have

	depends on SOC_SP7021 || COMPILE_TEST

> +       help
> +         This driver supports the Sunplus SP7021 SoC clocks.
> +         It implements SP7021 PLLs/gate.
> +         Not all features of the PLL are currently supported
> +         by the driver.
> +
>  config COMMON_CLK_STM32MP157
>         def_bool COMMON_CLK && MACH_STM32MP157
>         help
> diff --git a/drivers/clk/clk-sp7021.c b/drivers/clk/clk-sp7021.c
> new file mode 100644
> index 000000000..8a3e28a2a
> --- /dev/null
> +++ b/drivers/clk/clk-sp7021.c
> @@ -0,0 +1,753 @@
> +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +/*
> + * Copyright (C) Sunplus Technology Co., Ltd.
> + *       All rights reserved.
> + */
> +//#define DEBUG
> +#include <linux/clk-provider.h>
> +#include <linux/clkdev.h>

IS the clkdev get path used? If not, please drop it.

> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/bitfield.h>
> +#include <linux/slab.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <dt-bindings/clock/sp-sp7021.h>
> +
> +#define REG(i)         (pll_regs + (i) * 4)
> +
> +#define PLLA_CTL       REG(7)
> +#define PLLE_CTL       REG(12)
> +#define PLLF_CTL       REG(13)
> +#define PLLTV_CTL      REG(14)
> +#define PLLSYS_CTL     REG(26)
> +
> +/* speical div_width values for PLLTV/PLLA */
> +#define DIV_TV         33
> +#define DIV_A          34
> +
> +/* PLLTV parameters */
> +enum {
> +       SEL_FRA,
> +       SDM_MOD,
> +       PH_SEL,
> +       NFRA,
> +       DIVR,
> +       DIVN,
> +       DIVM,
> +       P_MAX
> +};
> +
> +#define MASK_SEL_FRA   GENMASK(1, 1)
> +#define MASK_SDM_MOD   GENMASK(2, 2)
> +#define MASK_PH_SEL    GENMASK(4, 4)
> +#define MASK_NFRA      GENMASK(12, 6)
> +#define MASK_DIVR      GENMASK(8, 7)
> +#define MASK_DIVN      GENMASK(7, 0)
> +#define MASK_DIVM      GENMASK(14, 8)
> +
> +/* HIWORD_MASK FIELD_PREP */
> +#define HWM_FIELD_PREP(mask, value)            \
> +({                                             \
> +       u32 m = mask;                           \
> +       (m << 16) | FIELD_PREP(m, value);       \
> +})
> +
> +struct sp_pll {
> +       struct clk_hw hw;
> +       void __iomem *reg;
> +       spinlock_t *lock;       /* lock for reg */
> +       int div_shift;
> +       int div_width;
> +       int pd_bit;             /* power down bit idx */
> +       int bp_bit;             /* bypass bit idx */
> +       unsigned long brate;    /* base rate, TODO: replace brate with muldiv */
> +       u32 p[P_MAX];           /* for hold PLLTV/PLLA parameters */
> +};
> +
> +#define to_sp_pll(_hw) container_of(_hw, struct sp_pll, hw)
> +
> +#define clk_regs       (sp_clk_base + 0x000) /* G0 ~ CLKEN */
> +#define pll_regs       (sp_clk_base + 0x200) /* G4 ~ PLL */
> +static void __iomem *sp_clk_base;
> +static struct clk_hw_onecell_data *sp_clk_data;
> +
> +#define F_CRITICAL     BIT(31) /* clock is critical */
> +#define F_EXTCLK       BIT(16) /* parent clock is EXTCLK */
> +const struct clk_parent_data parents[] = {

static? 'parents' is too generic, and this is in the global namespace.
Please make it driver specific.

> +       { .name = "pllsys" },
> +       { .name = "extclk" },
> +       { .name = "plle" },

The .name member of clk_parent_data shouldn't be used for new drivers or
bindings. Instead, use .fw_name or the .index, preferably the index so
the struct is smaller.

> +};
> +
> +#define PD_PLLSYS      (&parents[0])
> +#define PD_EXTCLK      (&parents[1])
> +#define PD_PLLE                (&parents[2])
> +
> +static const u32 gates[] = {

'gates' is too generic, please name this something driver specific.

> +       CLK_SYSTEM                      | F_CRITICAL,
> +       CLK_RTC,
> +       CLK_IOCTL                       | F_CRITICAL,
> +       CLK_IOP                         | F_CRITICAL,
> +       CLK_OTPRX,
> +       CLK_NOC,
> +       CLK_BR,
> +       CLK_RBUS_L00                    | F_CRITICAL,
> +       CLK_SPIFL,
> +       CLK_SDCTRL0                     | F_CRITICAL,
> +       CLK_PERI0       | F_EXTCLK,
> +       CLK_A926                        | F_CRITICAL,
> +       CLK_UMCTL2                      | F_CRITICAL,
> +       CLK_PERI1       | F_EXTCLK,
> +
> +       CLK_DDR_PHY0                    | F_CRITICAL,
> +       CLK_ACHIP                       | F_CRITICAL,

Do these gates have children? What is the benefit of modeling critical
clks that have no children? It would be simpler to make sure they're
enabled at driver probe time and then not do anything else and skip
registering them with the clk framework when they'll do nothing.

> +       CLK_STC0,
> +       CLK_STC_AV0,
> +       CLK_STC_AV1,
> +       CLK_STC_AV2,
> +       CLK_UA0         | F_EXTCLK,
> +       CLK_UA1         | F_EXTCLK,
> +       CLK_UA2         | F_EXTCLK,
> +       CLK_UA3         | F_EXTCLK,
> +       CLK_UA4         | F_EXTCLK,
> +       CLK_HWUA        | F_EXTCLK,
> +       CLK_DDC0,
> +       CLK_UADMA       | F_EXTCLK,
> +
> +       CLK_CBDMA0,
> +       CLK_CBDMA1,
> +       CLK_SPI_COMBO_0,
> +       CLK_SPI_COMBO_1,
> +       CLK_SPI_COMBO_2,
> +       CLK_SPI_COMBO_3,
> +       CLK_AUD,
> +       CLK_USBC0,
> +       CLK_USBC1,
> +       CLK_UPHY0,
> +       CLK_UPHY1,
> +
> +       CLK_I2CM0,
> +       CLK_I2CM1,
> +       CLK_I2CM2,
> +       CLK_I2CM3,
> +       CLK_PMC,
> +       CLK_CARD_CTL0,
> +       CLK_CARD_CTL1,
> +
> +       CLK_CARD_CTL4,
> +       CLK_BCH,
> +       CLK_DDFCH,
> +       CLK_CSIIW0,
> +       CLK_CSIIW1,
> +       CLK_MIPICSI0,
> +       CLK_MIPICSI1,
> +
> +       CLK_HDMI_TX,
> +       CLK_VPOST,
> +
> +       CLK_TGEN,
> +       CLK_DMIX,
> +       CLK_TCON,
> +       CLK_INTERRUPT                   | F_CRITICAL,
> +
> +       CLK_RGST                        | F_CRITICAL,
> +       CLK_GPIO,
> +       CLK_RBUS_TOP                    | F_CRITICAL,
> +
> +       CLK_MAILBOX,
> +       CLK_SPIND,
> +       CLK_I2C2CBUS,
> +       CLK_SEC,
> +       CLK_GPOST0,
> +       CLK_DVE,
> +
> +       CLK_OSD0,
> +       CLK_DISP_PWM,
> +       CLK_UADBG,
> +       CLK_DUMMY_MASTER,
> +       CLK_FIO_CTL,
> +       CLK_FPGA,
> +       CLK_L2SW,
> +       CLK_ICM,
> +       CLK_AXI_GLOBAL,
> +};
> +
> +static DEFINE_SPINLOCK(plla_lock);
> +static DEFINE_SPINLOCK(plle_lock);
> +static DEFINE_SPINLOCK(pllf_lock);
> +static DEFINE_SPINLOCK(pllsys_lock);
> +static DEFINE_SPINLOCK(plltv_lock);
> +
> +#define _M             1000000UL
> +#define F_27M          (27 * _M)
> +
> +/*********************************** PLL_TV **********************************/
> +
> +/* TODO: set proper FVCO range */
> +#define FVCO_MIN       (100 * _M)
> +#define FVCO_MAX       (200 * _M)
> +
> +#define F_MIN          (FVCO_MIN / 8)
> +#define F_MAX          (FVCO_MAX)
> +
> +static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
> +{
> +       /* valid m values: 27M must be divisible by m, 0 means end */
> +       static const u32 m_table[] = {
> +               1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 0
> +       };
> +       u32 m, n, r;
> +       unsigned long fvco, nf;
> +
> +       /* check freq */
> +       if (freq < F_MIN) {
> +               pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
> +                       __func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
> +               freq = F_MIN;
> +       } else if (freq > F_MAX) {
> +               pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
> +                       __func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
> +               freq = F_MAX;
> +       }

Just use clamp() and ignore the warnings?

> +
> +       /* DIVR 0~3 */
> +       for (r = 0; r <= 3; r++) {
> +               fvco = freq << r;
> +               if (fvco <= FVCO_MAX)
> +                       break;
> +       }
> +
> +       /* DIVM */
> +       for (m = 0; m_table[m]; m++) {
> +               nf = fvco * m_table[m];
> +               n = nf / F_27M;
> +               if ((n * F_27M) == nf)
> +                       break;
> +       }
> +       m = m_table[m];
> +
> +       if (!m) {
> +               pr_err("%s: %s freq:%lu not found a valid setting\n",
> +                      __func__, clk_hw_get_name(&clk->hw), freq);
> +               return -EINVAL;
> +       }
> +
> +       /* save parameters */
> +       clk->p[SEL_FRA] = 0;
> +       clk->p[DIVR]    = r;
> +       clk->p[DIVN]    = n;
> +       clk->p[DIVM]    = m;
> +
> +       return freq;
> +}
> +
> +/* parameters for PLLTV fractional divider */
> +static const u32 pt[][5] = {
> +       /* conventional fractional */
> +       {
> +               1,                      // factor
> +               5,                      // 5 * p0 (nint)
> +               1,                      // 1 * p0
> +               F_27M,                  // F_27M / p0
> +               1,                      // p0 / p2
> +       },
> +       /* phase rotation */
> +       {
> +               10,                     // factor
> +               54,                     // 5.4 * p0 (nint)
> +               2,                      // 0.2 * p0
> +               F_27M / 10,             // F_27M / p0
> +               5,                      // p0 / p2
> +       },
> +};
> +
> +static const u32 mods[] = { 91, 55 }; /* SDM_MOD mod values */
> +
> +static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
> +{
> +       u32 m, r;
> +       u32 nint, nfra;
> +       u32 df_quotient_min = 210000000;
> +       u32 df_remainder_min = 0;
> +       unsigned long fvco, nf, f, fout = 0;
> +       int sdm, ph;
> +
> +       /* check freq */
> +       if (freq < F_MIN) {
> +               pr_warn("%s: %s freq:%lu < F_MIN:%lu, round up\n",
> +                       __func__, clk_hw_get_name(&clk->hw), freq, F_MIN);
> +               freq = F_MIN;
> +       } else if (freq > F_MAX) {
> +               pr_warn("%s: %s freq:%lu > F_MAX:%lu, round down\n",
> +                       __func__, clk_hw_get_name(&clk->hw), freq, F_MAX);
> +               freq = F_MAX;
> +       }

Just use clamp() and ignore the warnings?

> +
> +       /* DIVR 0~3 */
> +       for (r = 0; r <= 3; r++) {
> +               fvco = freq << r;
> +               if (fvco <= FVCO_MAX)
> +                       break;
> +       }
> +       f = F_27M >> r;
> +
> +       /* PH_SEL 1/0 */
> +       for (ph = 1; ph >= 0; ph--) {
> +               const u32 *pp = pt[ph];
> +               u32 ms = 1;
> +
> +               /* SDM_MOD 0/1 */
> +               for (sdm = 0; sdm <= 1; sdm++) {
> +                       u32 mod = mods[sdm];
> +
> +                       /* DIVM 1~32 */
> +                       for (m = ms; m <= 32; m++) {
> +                               u32 df; /* diff freq */
> +                               u32 df_quotient = 0, df_remainder = 0;

Please leave these unassigned.

> +
> +                               nf = fvco * m;
> +                               nint = nf / pp[3];
> +
> +                               if (nint < pp[1])
> +                                       continue;
> +                               if (nint > pp[1])
> +                                       break;
> +
> +                               nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
> +                               if (nfra)
> +                                       df = (f * (nint + pp[2]) / pp[0]) -
> +                                            (f * (mod - nfra) / mod / pp[4]);
> +                               else
> +                                       df = (f * (nint) / pp[0]);
> +
> +                               df_quotient  = df / m;
> +                               df_remainder = ((df % m) * 1000) / m;
> +
> +                               if (freq > df_quotient) {
> +                                       df_quotient  = freq - df_quotient - 1;
> +                                       df_remainder = 1000 - df_remainder;
> +                               } else {
> +                                       df_quotient = df_quotient - freq;
> +                               }
> +
> +                               if (df_quotient_min > df_quotient ||
> +                                   (df_quotient_min == df_quotient &&
> +                                   df_remainder_min > df_remainder)) {
> +                                       /* found a closer freq, save parameters */
> +                                       clk->p[SEL_FRA] = 1;
> +                                       clk->p[SDM_MOD] = sdm;
> +                                       clk->p[PH_SEL]  = ph;
> +                                       clk->p[NFRA]    = nfra;
> +                                       clk->p[DIVR]    = r;
> +                                       clk->p[DIVM]    = m;
> +
> +                                       fout = df / m;
> +                                       df_quotient_min = df_quotient;
> +                                       df_remainder_min = df_remainder;
> +                               }
> +                       }
> +               }
> +       }
> +
> +       if (!fout) {
> +               pr_err("%s: %s freq:%lu not found a valid setting\n",
> +                      __func__, clk_hw_get_name(&clk->hw), freq);
> +               return -EINVAL;
> +       }
> +
> +       return fout;
> +}
> +
> +static long plltv_div(struct sp_pll *clk, unsigned long freq)
> +{
> +       if (freq % 100)
> +               return plltv_fractional_div(clk, freq);
> +
> +       return plltv_integer_div(clk, freq);
> +}
> +
> +static void plltv_set_rate(struct sp_pll *clk)
> +{
> +       u32 reg;
> +
> +       reg  = HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
> +       reg |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
> +       reg |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
> +       reg |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
> +       writel(reg, clk->reg);
> +
> +       reg  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
> +       writel(reg, clk->reg + 4);
> +
> +       reg  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
> +       reg |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
> +       writel(reg, clk->reg + 8);
> +}
> +
> +/*********************************** PLL_A ***********************************/
> +
> +/* from Q628_PLLs_REG_setting.xlsx */
> +static const struct {
> +       u32 rate;
> +       u32 regs[5];
> +} pa[] = {
> +       {
> +               .rate = 135475200,
> +               .regs = {
> +                       0x4801,
> +                       0x02df,
> +                       0x248f,
> +                       0x0211,
> +                       0x33e9
> +               }
> +       },
> +       {
> +               .rate = 147456000,
> +               .regs = {
> +                       0x4801,
> +                       0x1adf,
> +                       0x2490,
> +                       0x0349,
> +                       0x33e9
> +               }
> +       },
> +       {
> +               .rate = 196608000,
> +               .regs = {
> +                       0x4801,
> +                       0x42ef,
> +                       0x2495,
> +                       0x01c6,
> +                       0x33e9
> +               }
> +       },
> +};
> +
> +static void plla_set_rate(struct sp_pll *clk)
> +{
> +       const u32 *pp = pa[clk->p[0]].regs;
> +       int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
> +               writel(0xffff0000 | pp[i], clk->reg + (i * 4));
> +}
> +
> +static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
> +{
> +       int i = ARRAY_SIZE(pa);
> +
> +       while (--i) {
> +               if (rate >= pa[i].rate)
> +                       break;
> +       }
> +       clk->p[0] = i;
> +
> +       return pa[i].rate;
> +}
> +
> +/********************************** SP_PLL ***********************************/
> +
> +static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
> +{
> +       u32 fbdiv;
> +       u32 max = 1 << clk->div_width;
> +
> +       fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
> +       if (fbdiv > max)
> +               fbdiv = max;
> +
> +       return fbdiv;
> +}
> +
> +static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
> +                             unsigned long *prate)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       long ret;
> +
> +       if (rate == *prate)
> +               ret = *prate; /* bypass */
> +       else if (clk->div_width == DIV_A) {
> +               ret = plla_round_rate(clk, rate);
> +       } else if (clk->div_width == DIV_TV) {
> +               ret = plltv_div(clk, rate);
> +               if (ret < 0)
> +                       ret = *prate;
> +       } else {
> +               ret = sp_pll_calc_div(clk, rate) * clk->brate;
> +       }
> +
> +       return ret;
> +}
> +
> +static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
> +                                       unsigned long prate)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       u32 reg = readl(clk->reg);
> +       unsigned long ret;
> +
> +       if (reg & BIT(clk->bp_bit))
> +               ret = prate; /* bypass */
> +       else if (clk->div_width == DIV_A)
> +               ret = pa[clk->p[0]].rate;
> +       else if (clk->div_width == DIV_TV) {
> +               u32 m, r, reg2;
> +
> +               r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
> +               reg2 = readl(clk->reg + 8);
> +               m = FIELD_GET(MASK_DIVM, reg2) + 1;
> +
> +               if (reg & BIT(1)) { /* SEL_FRA */
> +                       /* fractional divider */
> +                       u32 sdm  = FIELD_GET(MASK_SDM_MOD, reg);
> +                       u32 ph   = FIELD_GET(MASK_PH_SEL, reg);
> +                       u32 nfra = FIELD_GET(MASK_NFRA, reg);
> +                       const u32 *pp = pt[ph];
> +
> +                       ret = prate >> r;
> +                       ret = (ret * (pp[1] + pp[2]) / pp[0]) -
> +                                 (ret * (mods[sdm] - nfra) / mods[sdm] / pp[4]);
> +                       ret /= m;
> +               } else {
> +                       /* integer divider */
> +                       u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
> +
> +                       ret = (prate / m * n) >> r;
> +               }
> +       } else {
> +               u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
> +
> +               ret = clk->brate * fbdiv;
> +       }
> +
> +       return ret;
> +}
> +
> +static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
> +                          unsigned long prate)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +       u32 reg;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +
> +       reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
> +
> +       if (rate == prate)
> +               reg |= BIT(clk->bp_bit); /* bypass */
> +       else if (clk->div_width == DIV_A)
> +               plla_set_rate(clk);
> +       else if (clk->div_width == DIV_TV)
> +               plltv_set_rate(clk);

Please add braces to all these if arms, because the else if below has
one.

> +       else if (clk->div_width) {
> +               u32 fbdiv = sp_pll_calc_div(clk, rate);
> +               u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
> +
> +               reg |= (mask << 16) | (((fbdiv - 1) << clk->div_shift) & mask);
> +       }
> +
> +       writel(reg, clk->reg);
> +
> +       spin_unlock_irqrestore(clk->lock, flags);
> +
> +       return 0;
> +}
> +
> +static int sp_pll_enable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg); /* power up */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +
> +       return 0;
> +}
> +
> +static void sp_pll_disable(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +       unsigned long flags;
> +
> +       spin_lock_irqsave(clk->lock, flags);
> +       writel(BIT(clk->pd_bit + 16), clk->reg); /* power down */
> +       spin_unlock_irqrestore(clk->lock, flags);
> +}
> +
> +static int sp_pll_is_enabled(struct clk_hw *hw)
> +{
> +       struct sp_pll *clk = to_sp_pll(hw);
> +
> +       return readl(clk->reg) & BIT(clk->pd_bit);
> +}
> +
> +static const struct clk_ops sp_pll_ops = {
> +       .enable = sp_pll_enable,
> +       .disable = sp_pll_disable,
> +       .is_enabled = sp_pll_is_enabled,
> +       .round_rate = sp_pll_round_rate,
> +       .recalc_rate = sp_pll_recalc_rate,
> +       .set_rate = sp_pll_set_rate
> +};
> +
> +static const struct clk_ops sp_pll_sub_ops = {
> +       .enable = sp_pll_enable,
> +       .disable = sp_pll_disable,
> +       .is_enabled = sp_pll_is_enabled,
> +       .recalc_rate = sp_pll_recalc_rate,
> +};
> +
> +struct clk_hw *sp_pll_register(struct device *dev, const char *name,
> +                              const struct clk_parent_data *parent_data,
> +                              void __iomem *reg, int pd_bit, int bp_bit,
> +                              unsigned long brate, int shift, int width,
> +                              spinlock_t *lock)
> +{
> +       struct sp_pll *pll;
> +       struct clk_hw *hw;
> +       struct clk_init_data initd = {
> +               .name = name,
> +               .parent_data = parent_data,
> +               .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
> +               .num_parents = 1,
> +               /* system clock, should not be disabled */
> +               .flags = (reg == PLLSYS_CTL) ? CLK_IS_CRITICAL : 0,
> +       };
> +       int ret;
> +
> +       pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
> +       if (!pll)
> +               return ERR_PTR(-ENOMEM);
> +
> +       pll->hw.init = &initd;
> +       pll->reg = reg;
> +       pll->pd_bit = pd_bit;
> +       pll->bp_bit = bp_bit;
> +       pll->brate = brate;
> +       pll->div_shift = shift;
> +       pll->div_width = width;
> +       pll->lock = lock;
> +
> +       hw = &pll->hw;
> +       ret = devm_clk_hw_register(dev, hw);
> +       if (ret) {
> +               kfree(pll);
> +               hw = ERR_PTR(ret);
> +       } else {
> +               pr_debug("%-20s%lu\n", name, clk_hw_get_rate(hw));
> +               devm_clk_hw_register_clkdev(dev, hw, NULL, name);
> +       }
> +
> +       return hw;
> +}
> +
> +static int sp7021_clk_probe(struct platform_device *pdev)
> +{
> +       struct device *dev = &pdev->dev;
> +       int i, ret;
> +       struct clk_hw **hws;
> +       struct resource *res;
> +
> +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       sp_clk_base = devm_ioremap(dev, res->start, resource_size(res));

Use devm_platform_ioremap_resource()?

> +       if (WARN_ON(!sp_clk_base))

Drop the WARN_ON() as it already prints a stacktrace if things fail.

> +               return -ENXIO;
> +
> +       sp_clk_data = devm_kzalloc(dev, struct_size(sp_clk_data, hws, CLK_MAX),
> +                                  GFP_KERNEL);
> +       if (!sp_clk_data)
> +               return -ENOMEM;
> +
> +       hws = sp_clk_data->hws;
> +
> +       /* PLL_A */
> +       hws[PLL_A] = sp_pll_register(dev, "plla", PD_EXTCLK, PLLA_CTL,
> +                                    11, 12, 27000000, 0, DIV_A, &plla_lock);
> +       if (IS_ERR(hws[PLL_A]))
> +               return PTR_ERR(hws[PLL_A]);
> +
> +       /* PLL_E */
> +       hws[PLL_E] = sp_pll_register(dev, "plle", PD_EXTCLK, PLLE_CTL,
> +                                    6, 2, 50000000, 0, 0, &plle_lock);
> +       if (IS_ERR(hws[PLL_E]))
> +               return PTR_ERR(hws[PLL_E]);
> +       hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", PD_PLLE, PLLE_CTL,
> +                                        13, -1, 2500000, 0, 0, &plle_lock);
> +       if (IS_ERR(hws[PLL_E_2P5]))
> +               return PTR_ERR(hws[PLL_E_2P5]);
> +       hws[PLL_E_25] = sp_pll_register(dev, "plle_25", PD_PLLE, PLLE_CTL,
> +                                       12, -1, 25000000, 0, 0, &plle_lock);
> +       if (IS_ERR(hws[PLL_E_25]))
> +               return PTR_ERR(hws[PLL_E_25]);
> +       hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", PD_PLLE, PLLE_CTL,
> +                                          11, -1, 112500000, 0, 0, &plle_lock);
> +       if (IS_ERR(hws[PLL_E_112P5]))
> +               return PTR_ERR(hws[PLL_E_112P5]);
> +
> +       /* PLL_F */
> +       hws[PLL_F] = sp_pll_register(dev, "pllf", PD_EXTCLK, PLLF_CTL,
> +                                    0, 10, 13500000, 1, 4, &pllf_lock);
> +       if (IS_ERR(hws[PLL_F]))
> +               return PTR_ERR(hws[PLL_F]);
> +
> +       /* PLL_TV */
> +       hws[PLL_TV] = sp_pll_register(dev, "plltv", PD_EXTCLK, PLLTV_CTL,
> +                                     0, 15, 27000000, 0, DIV_TV, &plltv_lock);
> +       if (IS_ERR(hws[PLL_TV]))
> +               return PTR_ERR(hws[PLL_TV]);
> +       hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
> +                                                    PLLTV_CTL + 4, 5, 1,
> +                                                    CLK_DIVIDER_POWER_OF_TWO,
> +                                                    &plltv_lock);
> +       if (IS_ERR(hws[PLL_TV_A]))
> +               return PTR_ERR(hws[PLL_TV_A]);
> +       ret = devm_clk_hw_register_clkdev(dev, hws[PLL_TV_A], NULL, "plltv_a");
> +       if (ret)
> +               return ret;
> +
> +       /* PLL_SYS */
> +       hws[PLL_SYS] = sp_pll_register(dev, "pllsys", PD_EXTCLK, PLLSYS_CTL,
> +                                      10, 9, 13500000, 0, 4, &pllsys_lock);
> +       if (IS_ERR(hws[PLL_SYS]))
> +               return PTR_ERR(hws[PLL_SYS]);
> +
> +       /* gates */
> +       for (i = 0; i < ARRAY_SIZE(gates); i++) {
> +               u32 f = gates[i];
> +               const char *parent_name = parents[!!(f & F_EXTCLK)].name;
> +               bool critical = f & F_CRITICAL;
> +               int j = f & 0xffff;
> +               char s[10];
> +
> +               sprintf(s, "clken%02x", j);
> +               hws[j] = clk_hw_register_gate(dev, s, parent_name,
> +                                             critical ? CLK_IS_CRITICAL : 0,
> +                                             clk_regs + (j >> 4) * 4,
> +                                             j & 0x0f,
> +                                             CLK_GATE_HIWORD_MASK, NULL);
> +               if (IS_ERR(hws[j]))
> +                       return PTR_ERR(hws[j]);
> +       }
> +
> +       sp_clk_data->num = CLK_MAX;
> +       return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, sp_clk_data);
> +}
> +
> +static const struct of_device_id sp7021_clk_dt_ids[] = {
> +       { .compatible = "sunplus,sp7021-clkc", },
> +       { }
> +};
> +
> +static struct platform_driver sp7021_clk_driver = {
> +       .probe  = sp7021_clk_probe,
> +       .driver = {
> +               .name = "sp7021-clk",
> +               .of_match_table = sp7021_clk_dt_ids,
> +       },
> +};
> +builtin_platform_driver(sp7021_clk_driver);

Can it be a module?


From nhuck at google.com  Mon Jan 24 17:44:15 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:15 -0600
Subject: [RFC PATCH 0/7] crypto: HCTR2 support
Message-ID: <20220125014422.80552-1-nhuck@google.com>

HCTR2 is a length-preserving encryption mode that is efficient on
processors with instructions to accelerate AES and carryless
multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
processors with the ARMv8 Crypto Extensions.

HCTR2 is specified in https://ia.cr/2021/1441 ?Length-preserving
encryption with HCTR2? which shows that if AES is secure and HCTR2 is
instantiated with AES, then HCTR2 is secure.  Reference code and test
vectors are at https://github.com/google/hctr2.

As a length-preserving encryption mode, HCTR2 is suitable for applications
such as storage encryption where ciphertext expansion is not possible, and
thus authenticated encryption cannot be used.  Currently, such
applications usually use XTS, or in some cases Adiantum.  XTS has the
disadvantage that it is a narrow-block mode: a bitflip will only change 16
bytes in the resulting ciphertext or plaintext.  This reveals more
information to an attacker than necessary.

HCTR2 is a wide-block mode, so it provides a stronger security property: a
bitflip will change the entire message.  HCTR2 is somewhat similar to
Adiantum, which is also a wide-block mode.  However, HCTR2 is designed to
take advantage of existing crypto instructions, while Adiantum targets
devices without such hardware support.  Adiantum is also designed with
longer messages in mind, while HCTR2 is designed to be efficient even on
short messages.

The first intended use of this mode in the kernel is for the encryption of
filenames, where for efficiency reasons encryption must be fully
deterministic (only one ciphertext for each plaintext) and the existing
CBC solution leaks more information than necessary for filenames with
common prefixes.

HCTR2 uses two passes of an ?-almost-?-universal hash function called
POLYVAL and one pass of a block cipher mode called XCTR.  POLYVAL is a
polynomial hash designed for efficiency on modern processors and was
originally specified for use in AES-GCM-SIV (RFC 8452).  XCTR mode is a
variant of CTR mode that is more efficient on little-endian machines.

This patchset adds HCTR2 to Linux's crypto API, including generic
implementations of XCTR and POLYVAL, hardware accelerated implementations
of XCTR and POLYVAL for both x86-64 and ARM64, and a templated
implementation of HCTR2.

Nathan Huckleberry (7):
  crypto: xctr - Add XCTR support
  crypto: polyval - Add POLYVAL support
  crypto: hctr2 - Add HCTR2 support
  crypto: x86/aesni-xctr: Add accelerated implementation of XCTR
  crypto: arm64/aes-xctr: Add accelerated implementation of XCTR
  crypto: x86/polyval: Add PCLMULQDQ accelerated implementation of
    POLYVAL
  crypto: arm64/polyval: Add PMULL accelerated implementation of POLYVAL

 arch/arm64/crypto/Kconfig                    |   10 +-
 arch/arm64/crypto/Makefile                   |    3 +
 arch/arm64/crypto/aes-glue.c                 |   70 +-
 arch/arm64/crypto/aes-modes.S                |  128 ++
 arch/arm64/crypto/polyval-ce-core.S          |  317 ++++
 arch/arm64/crypto/polyval-ce-glue.c          |  164 ++
 arch/x86/crypto/Makefile                     |    5 +-
 arch/x86/crypto/aes_xctrby8_avx-x86_64.S     |  529 ++++++
 arch/x86/crypto/aesni-intel_asm.S            |   70 +
 arch/x86/crypto/aesni-intel_glue.c           |   88 +
 arch/x86/crypto/polyval-clmulni-intel_asm.S  |  319 ++++
 arch/x86/crypto/polyval-clmulni-intel_glue.c |  165 ++
 crypto/Kconfig                               |   37 +
 crypto/Makefile                              |    3 +
 crypto/hctr2.c                               |  475 +++++
 crypto/polyval-generic.c                     |  183 ++
 crypto/tcrypt.c                              |   10 +
 crypto/testmgr.c                             |   18 +
 crypto/testmgr.h                             | 1617 ++++++++++++++++++
 crypto/xctr.c                                |  202 +++
 include/crypto/polyval.h                     |   22 +
 include/crypto/xctr.h                        |   19 +
 22 files changed, 4449 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm64/crypto/polyval-ce-core.S
 create mode 100644 arch/arm64/crypto/polyval-ce-glue.c
 create mode 100644 arch/x86/crypto/aes_xctrby8_avx-x86_64.S
 create mode 100644 arch/x86/crypto/polyval-clmulni-intel_asm.S
 create mode 100644 arch/x86/crypto/polyval-clmulni-intel_glue.c
 create mode 100644 crypto/hctr2.c
 create mode 100644 crypto/polyval-generic.c
 create mode 100644 crypto/xctr.c
 create mode 100644 include/crypto/polyval.h
 create mode 100644 include/crypto/xctr.h

-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:16 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:16 -0600
Subject: [RFC PATCH 1/7] crypto: xctr - Add XCTR support
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-2-nhuck@google.com>

Add a generic implementation of XCTR mode as a template.  XCTR is a
blockcipher mode similar to CTR mode.  XCTR uses XORs and little-endian
addition rather than big-endian arithmetic which makes it slightly
faster on little-endian CPUs.  It is used as a component to implement
HCTR2.

More information on XCTR mode can be found in the HCTR2 paper:
https://eprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 crypto/Kconfig        |   9 +
 crypto/Makefile       |   1 +
 crypto/tcrypt.c       |   1 +
 crypto/testmgr.c      |   6 +
 crypto/testmgr.h      | 546 ++++++++++++++++++++++++++++++++++++++++++
 crypto/xctr.c         | 202 ++++++++++++++++
 include/crypto/xctr.h |  19 ++
 7 files changed, 784 insertions(+)
 create mode 100644 crypto/xctr.c
 create mode 100644 include/crypto/xctr.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 94bfa32cc6a1..b00de5f22eaf 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -452,6 +452,15 @@ config CRYPTO_PCBC
 	  PCBC: Propagating Cipher Block Chaining mode
 	  This block cipher algorithm is required for RxRPC.
 
+config CRYPTO_XCTR
+	tristate
+	select CRYPTO_SKCIPHER
+	select CRYPTO_MANAGER
+	help
+	  XCTR: XOR Counter mode. This blockcipher mode is a variant of CTR mode
+	  using XORs and little-endian addition rather than big-endian arithmetic.
+	  XCTR mode is used to implement HCTR2.
+
 config CRYPTO_XTS
 	tristate "XTS support"
 	select CRYPTO_SKCIPHER
diff --git a/crypto/Makefile b/crypto/Makefile
index d76bff8d0ffd..6b3fe3df1489 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_CRYPTO_CTS) += cts.o
 obj-$(CONFIG_CRYPTO_LRW) += lrw.o
 obj-$(CONFIG_CRYPTO_XTS) += xts.o
 obj-$(CONFIG_CRYPTO_CTR) += ctr.o
+obj-$(CONFIG_CRYPTO_XCTR) += xctr.o
 obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
 obj-$(CONFIG_CRYPTO_ADIANTUM) += adiantum.o
 obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 00149657a4bc..da7848f84d12 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1750,6 +1750,7 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
 		ret += tcrypt_test("rfc3686(ctr(aes))");
 		ret += tcrypt_test("ofb(aes)");
 		ret += tcrypt_test("cfb(aes)");
+		ret += tcrypt_test("xctr(aes)");
 		break;
 
 	case 11:
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 5831d4bbc64f..5acf92354543 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5454,6 +5454,12 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.cipher = __VECS(xchacha20_tv_template)
 		},
+	}, {
+		.alg = "xctr(aes)",
+		.test = alg_test_skcipher,
+		.suite = {
+			.cipher = __VECS(aes_xctr_tv_template)
+		}
 	}, {
 		.alg = "xts(aes)",
 		.generic_driver = "xts(ecb(aes-generic))",
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index a253d66ba1c1..e1ebbb3c4d4c 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -32800,4 +32800,550 @@ static const struct hash_testvec blakes2s_256_tv_template[] = {{
 			  0xd5, 0x06, 0xb5, 0x3a, 0x7c, 0x7a, 0x65, 0x1d, },
 }};
 
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ */
+static const struct cipher_testvec aes_xctr_tv_template[] = {
+	{
+		.key	= "\x06\x20\x5d\xba\x50\xb5\x12\x8e"
+			  "\xee\x65\x3c\x59\x80\xa1\xfe\xb1",
+		.iv	= "\x16\x52\x22\x0d\x1c\x76\x94\x9f"
+			  "\x74\xba\x41\x0c\xc4\xc4\xaf\xb9",
+		.ptext	= "\x02\x62\x54\x87\x28\x8f\xa1\xd3"
+			  "\x8f\xd8\xc6\xab\x08\xef\xea\x83"
+			  "\xa3\xbd\xf4\x85\x47\x66\x74\x11"
+			  "\xf1\x58\x9f\x9f\xe8\xb9\x95\xc9",
+		.ctext	= "\x11\xfe\xef\xb4\x9e\xed\x5b\xe5"
+			  "\x92\x9b\x03\xa7\x6d\x8e\xf9\x7a"
+			  "\xaa\xfa\x33\x4a\xf7\xd9\xb2\xeb"
+			  "\x73\xa1\x85\xbc\x45\xbc\x42\x70",
+		.klen	= 16,
+		.len	= 32,
+	},
+	{
+		.key	= "\x19\x0e\xea\x30\x59\x8e\x39\x35"
+			  "\x93\x63\xcc\x8b\x5f\x98\x4f\x43",
+		.iv	= "\x4b\x9f\xf4\xd8\xaa\xcf\x99\xdc"
+			  "\xc5\x07\xe0\xde\xb2\x6d\x85\x12",
+		.ptext	= "\x23\x2d\x48\x15\x89\x34\x54\xf9"
+			  "\x2b\x38\xd1\x62\x06\x98\x21\x59"
+			  "\xd4\x3a\x45\x6f\x12\x27\x08\xa9"
+			  "\x3e\x0f\x21\x3d\xda\x80\x92\x3f",
+		.ctext	= "\x01\xa7\xe5\x9e\xf8\x49\xbb\x36"
+			  "\x49\xb8\x59\x7a\x77\x3f\x5a\x10"
+			  "\x2e\x8f\xe7\xc9\xc4\xb8\xdb\x86"
+			  "\xe4\xc0\x6b\x60\x2f\x79\xa0\x91",
+		.klen	= 16,
+		.len	= 32,
+	},
+	{
+		.key	= "\x17\xa6\x01\x3d\x5d\xd6\xef\x2d"
+			  "\x69\x8f\x4c\x54\x5b\xae\x43\xf0",
+		.iv	= "\xa9\x1b\x47\x60\x26\x82\xf7\x1c"
+			  "\x80\xf8\x88\xdd\xfb\x44\xd9\xda",
+		.ptext	= "\xf7\x67\xcd\xa6\x04\x65\x53\x99"
+			  "\x90\x5c\xa2\x56\x74\xd7\x9d\xf2"
+			  "\x0b\x03\x7f\x4e\xa7\x84\x72\x2b"
+			  "\xf0\xa5\xbf\xe6\x9a\x62\x3a\xfe"
+			  "\x69\x5c\x93\x79\x23\x86\x64\x85"
+			  "\xeb\x13\xb1\x5a\xd5\x48\x39\xa0"
+			  "\x70\xfb\x06\x9a\xd7\x12\x5a\xb9"
+			  "\xbe\xed\x2c\x81\x64\xf7\xcf\x80"
+			  "\xee\xe6\x28\x32\x2d\x37\x4c\x32"
+			  "\xf4\x1f\x23\x21\xe9\xc8\xc9\xbf"
+			  "\x54\xbc\xcf\xb4\xc2\x65\x39\xdf"
+			  "\xa5\xfb\x14\x11\xed\x62\x38\xcf"
+			  "\x9b\x58\x11\xdd\xe9\xbd\x37\x57"
+			  "\x75\x4c\x9e\xd5\x67\x0a\x48\xc6"
+			  "\x0d\x05\x4e\xb1\x06\xd7\xec\x2e"
+			  "\x9e\x59\xde\x4f\xab\x38\xbb\xe5"
+			  "\x87\x04\x5a\x2c\x2a\xa2\x8f\x3c"
+			  "\xe7\xe1\x46\xa9\x49\x9f\x24\xad"
+			  "\x2d\xb0\x55\x40\x64\xd5\xda\x7e"
+			  "\x1e\x77\xb8\x29\x72\x73\xc3\x84"
+			  "\xcd\xf3\x94\x90\x58\x76\xc9\x2c"
+			  "\x2a\xad\x56\xde\x33\x18\xb6\x3b"
+			  "\x10\xe9\xe9\x8d\xf0\xa9\x7f\x05"
+			  "\xf7\xb5\x8c\x13\x7e\x11\x3d\x1e"
+			  "\x02\xbb\x5b\xea\x69\xff\x85\xcf"
+			  "\x6a\x18\x97\x45\xe3\x96\xba\x4d"
+			  "\x2d\x7a\x70\x78\x15\x2c\xe9\xdc"
+			  "\x4e\x09\x92\x57\x04\xd8\x0b\xa6"
+			  "\x20\x71\x76\x47\x76\x96\x89\xa0"
+			  "\xd9\x29\xa2\x5a\x06\xdb\x56\x39"
+			  "\x60\x33\x59\x04\x95\x89\xf6\x18"
+			  "\x1d\x70\x75\x85\x3a\xb7\x6e",
+		.ctext	= "\xe1\xe7\x3f\xd3\x6a\xb9\x2f\x64"
+			  "\x37\xc5\xa4\xe9\xca\x0a\xa1\xd6"
+			  "\xea\x7d\x39\xe5\xe6\xcc\x80\x54"
+			  "\x74\x31\x2a\x04\x33\x79\x8c\x8e"
+			  "\x4d\x47\x84\x28\x27\x9b\x3c\x58"
+			  "\x54\x58\x20\x4f\x70\x01\x52\x5b"
+			  "\xac\x95\x61\x49\x5f\xef\xba\xce"
+			  "\xd7\x74\x56\xe7\xbb\xe0\x3c\xd0"
+			  "\x7f\xa9\x23\x57\x33\x2a\xf6\xcb"
+			  "\xbe\x42\x14\x95\xa8\xf9\x7a\x7e"
+			  "\x12\x53\x3a\xe2\x13\xfe\x2d\x89"
+			  "\xeb\xac\xd7\xa8\xa5\xf8\x27\xf3"
+			  "\x74\x9a\x65\x63\xd1\x98\x3a\x7e"
+			  "\x27\x7b\xc0\x20\x00\x4d\xf4\xe5"
+			  "\x7b\x69\xa6\xa8\x06\x50\x85\xb6"
+			  "\x7f\xac\x7f\xda\x1f\xf5\x37\x56"
+			  "\x9b\x2f\xd3\x86\x6b\x70\xbd\x0e"
+			  "\x55\x9a\x9d\x4b\x08\xb5\x5b\x7b"
+			  "\xd4\x7c\xb4\x71\x49\x92\x4a\x1e"
+			  "\xed\x6d\x11\x09\x47\x72\x32\x6a"
+			  "\x97\x53\x36\xaf\xf3\x06\x06\x2c"
+			  "\x69\xf1\x59\x00\x36\x95\x28\x2a"
+			  "\xb6\xcd\x10\x21\x84\x73\x5c\x96"
+			  "\x86\x14\x2c\x3d\x02\xdb\x53\x9a"
+			  "\x61\xde\xea\x99\x84\x7a\x27\xf6"
+			  "\xf7\xc8\x49\x73\x4b\xb8\xeb\xd3"
+			  "\x41\x33\xdd\x09\x68\xe2\x64\xb8"
+			  "\x5f\x75\x74\x97\x91\x54\xda\xc2"
+			  "\x73\x2c\x1e\x5a\x84\x48\x01\x1a"
+			  "\x0d\x8b\x0a\xdf\x07\x2e\xee\x77"
+			  "\x1d\x17\x41\x7a\xc9\x33\x63\xfa"
+			  "\x9f\xc3\x74\x57\x5f\x03\x4c",
+		.klen	= 16,
+		.len	= 255,
+	},
+	{
+		.key	= "\xd1\x87\xd3\xa1\x97\x6a\x4b\xf9"
+			  "\x5d\xcb\x6c\x07\x6e\x2d\x48\xad",
+		.iv	= "\xe9\x8c\x88\x40\xa9\x52\xe0\xbc"
+			  "\x8a\x47\x3a\x09\x5d\x60\xdd\xb2",
+		.ptext	= "\x67\x80\x86\x46\x18\xc6\xed\xd2"
+			  "\x99\x0f\x7a\xc3\xa5\x0b\x80\xcb"
+			  "\x8d\xe4\x0b\x4c\x1e\x4c\x98\x46"
+			  "\x87\x8a\x8c\x76\x75\xce\x2c\x27"
+			  "\x74\x88\xdc\x37\xaa\x77\x53\x14"
+			  "\xd3\x01\xcf\xb5\xcb\xdd\xb4\x8e"
+			  "\x6b\x54\x68\x01\xc3\xdf\xbc\xdd"
+			  "\x1a\x08\x4c\x11\xab\x25\x4b\x69"
+			  "\x25\x21\x78\xb1\x91\x1b\x75\xfa"
+			  "\xd0\x10\xf3\x8a\x65\xd3\x8d\x2e"
+			  "\xf8\xb6\xce\x29\xf9\x1e\x45\x5f"
+			  "\x4e\x41\x63\x6f\xf9\xca\x59\xd7"
+			  "\xc8\x9c\x97\xda\xff\xab\x42\x47"
+			  "\xfb\x2b\xca\xed\xda\x6c\x96\xe4"
+			  "\x59\x0d\xc6\x4a\x26\xde\xa8\x50"
+			  "\xc5\xbb\x13\xf8\xd1\xb9\x6b\xf4"
+			  "\x19\x30\xfb\xc0\x4f\x6b\x96\xc4"
+			  "\x88\x0b\x57\xb3\x43\xbd\xdd\xe2"
+			  "\x06\xae\x88\x44\x41\xdf\xa4\x29"
+			  "\x31\xd3\x38\xeb\xe9\xf8\xa2\xe4"
+			  "\x6a\x55\x2f\x56\x58\x19\xeb\xf7"
+			  "\x5f\x4b\x15\x52\xe4\xaa\xdc\x31"
+			  "\x4a\x32\xc9\x31\x96\x68\x3b\x80"
+			  "\x20\x4f\xe5\x8f\x87\xc9\x37\x58"
+			  "\x79\xfd\xc9\xc1\x9a\x83\xe3\x8b"
+			  "\x6b\x57\x07\xef\x28\x8d\x55\xcb"
+			  "\x4e\xb6\xa2\xb6\xd3\x4f\x8b\x10"
+			  "\x70\x10\x02\xf6\x74\x71\x20\x5a"
+			  "\xe2\x2f\xb6\x46\xc5\x22\xa3\x29"
+			  "\xf5\xc1\x25\xb0\x4d\xda\xaf\x04"
+			  "\xca\x83\xe6\x3f\x66\x6e\x3b\xa4"
+			  "\x09\x40\x22\xd7\x97\x12\x1e",
+		.ctext	= "\xd4\x6d\xfa\xc8\x6e\x54\x31\x69"
+			  "\x47\x51\x0f\xb8\xfa\x03\xa2\xe1"
+			  "\x57\xa8\x4f\x2d\xc5\x4e\x8d\xcd"
+			  "\x92\x0f\x71\x08\xdd\xa4\x5b\xc7"
+			  "\x69\x3a\x3d\x93\x29\x1d\x87\x2c"
+			  "\xfa\x96\xd2\x4d\x72\x61\xb0\x9e"
+			  "\xa7\xf5\xd5\x09\x3d\x43\x32\x82"
+			  "\xd2\x9a\x58\xe3\x4c\x84\xc2\xad"
+			  "\x33\x77\x9c\x5d\x37\xc1\x4f\x95"
+			  "\x56\x55\xc6\x76\x62\x27\x6a\xc7"
+			  "\x45\x80\x9e\x7c\x48\xc8\x14\xbb"
+			  "\x32\xbf\x4a\xbb\x8d\xb4\x2c\x7c"
+			  "\x01\xfa\xc8\xde\x10\x55\xa0\xae"
+			  "\x29\xed\xe2\x3d\xd6\x26\xfa\x3c"
+			  "\x7a\x81\xae\xfd\xc3\x2f\xe5\x3a"
+			  "\x00\xa3\xf0\x66\x0f\x3a\xd2\xa3"
+			  "\xaf\x0e\x75\xbb\x79\xad\xcc\xe0"
+			  "\x98\x10\xfb\xf1\xc0\x0c\xb9\x03"
+			  "\x07\xee\x46\x6a\xc0\xf6\x17\x8f"
+			  "\x7f\xc9\xad\x16\x58\x54\xb0\xd5"
+			  "\x67\x73\x9f\xce\xea\x4b\x60\x57"
+			  "\x1d\x62\x72\xec\xab\xe3\xd8\x32"
+			  "\x29\x48\x37\x1b\x5c\xd6\xd0\xb7"
+			  "\xc3\x39\xef\xf6\x1b\x18\xf6\xd1"
+			  "\x2d\x76\x7c\x68\x50\x37\xfa\x8f"
+			  "\x16\x87\x5e\xf8\xb1\x79\x82\x52"
+			  "\xc7\x3e\x0e\xa3\x61\xb9\x00\xe0"
+			  "\x2e\x03\x80\x6e\xc0\xbf\x63\x78"
+			  "\xdf\xab\xc2\x3b\xf0\x4c\xb0\xcb"
+			  "\x91\x6a\x26\xe6\x3a\x86\xef\x1a"
+			  "\x4e\x4d\x23\x2d\x59\x3a\x02\x3a"
+			  "\xf3\xda\xd1\x9d\x68\xf6\xef",
+		.klen	= 16,
+		.len	= 255,
+	},
+	{
+		.key	= "\x17\xe6\xb1\x85\x40\x24\xbe\x80"
+			  "\x99\xc7\xa1\x0c\x0f\x72\x31\xb8"
+			  "\x10\xb5\x11\x21\x3a\x99\x9e\xc8",
+		.iv	= "\x6b\x5f\xe1\x6a\xe1\x21\xfc\x62"
+			  "\xd9\x85\x2e\x0b\xbd\x58\x79\xd1",
+		.ptext	= "\xea\x3c\xad\x9d\x92\x05\x50\xa4"
+			  "\x68\x56\x6b\x33\x95\xa8\x24\x6c"
+			  "\xa0\x9d\x91\x15\x3a\x26\xb7\xeb"
+			  "\xb4\x5d\xf7\x0c\xec\x91\xbe\x11",
+		.ctext	= "\x6a\xac\xfc\x24\x64\x98\x28\x33"
+			  "\xa4\x39\xfd\x72\x46\x56\x7e\xf7"
+			  "\xd0\x7f\xee\x95\xd8\x68\x44\x67"
+			  "\x70\x80\xd4\x69\x7a\xf5\x8d\xad",
+		.klen	= 24,
+		.len	= 32,
+	},
+	{
+		.key	= "\x02\x81\x0e\xb1\x97\xe0\x20\x0c"
+			  "\x46\x8c\x7b\xde\xac\xe6\xe0\xb5"
+			  "\x2e\xb3\xc0\x40\x0e\xb7\x3d\xd3",
+		.iv	= "\x37\x15\x1c\x61\xab\x95\x8f\xf3"
+			  "\x11\x3a\x79\xe2\xf7\x33\x96\xb3",
+		.ptext	= "\x05\xd9\x7a\xc7\x08\x79\xba\xd8"
+			  "\x4a\x63\x54\xf7\x4e\x0c\x98\x8a"
+			  "\x5d\x40\x05\xe4\x7a\x7a\x14\x0c"
+			  "\xa8\xa7\x53\xf4\x3e\x66\x81\x38",
+		.ctext	= "\x43\x66\x70\x51\xd9\x7c\x6f\x80"
+			  "\x82\x8e\x34\xda\x5d\x3c\x47\xd1"
+			  "\xe0\x67\x76\xb5\x78\x98\x47\x26"
+			  "\x41\x31\xfa\x97\xc9\x79\xeb\x15",
+		.klen	= 24,
+		.len	= 32,
+	},
+	{
+		.key	= "\x9a\xef\x58\x01\x4c\x1e\xa2\x33"
+			  "\xce\x1f\x32\xae\xc8\x69\x1f\xf5"
+			  "\x82\x1b\x74\xf4\x8b\x1b\xce\x30",
+		.iv	= "\xb1\x72\x52\xa8\xc4\x8f\xb5\xec"
+			  "\x95\x12\x14\x5f\xd2\x29\x14\x0f",
+		.ptext	= "\x8a\xbc\x20\xbd\x67\x76\x8d\xd8"
+			  "\xa6\x70\xf0\x74\x8c\x8d\x9c\x00"
+			  "\xdd\xaf\xef\x28\x5d\x8d\xfa\x87"
+			  "\x81\x39\x8c\xb1\x6e\x0a\xcf\x3c"
+			  "\xe8\x3b\xc0\xff\x6e\xe7\xd1\xc6"
+			  "\x70\xb8\xdf\x27\x62\x72\x8e\xb7"
+			  "\x6b\xa7\xb2\x74\xdd\xc6\xb4\xc9"
+			  "\x4c\xd8\x4f\x2c\x09\x75\x6e\xb7"
+			  "\x41\xb3\x8f\x96\x09\x0d\x40\x8e"
+			  "\x0f\x49\xc2\xad\xc4\xf7\x71\x0a"
+			  "\x76\xfb\x45\x97\x29\x7a\xaa\x98"
+			  "\x22\x55\x4f\x9c\x26\x01\xc8\xb9"
+			  "\x41\x42\x51\x9d\x00\x5c\x7f\x02"
+			  "\x9b\x00\xaa\xbd\x69\x47\x9c\x26"
+			  "\x5b\xcb\x08\xf3\x46\x33\xf9\xeb"
+			  "\x79\xdd\xfe\x38\x08\x84\x8c\x81"
+			  "\xb8\x51\xbd\xcd\x72\x00\xdb\xbd"
+			  "\xf5\xd6\xb4\x80\xf7\xd3\x49\xac"
+			  "\x9e\xf9\xea\xd5\xad\xd4\xaa\x8f"
+			  "\x97\x60\xce\x60\xa7\xdd\xc0\xb2"
+			  "\x51\x80\x9b\xae\xab\x0d\x62\xab"
+			  "\x78\x1a\xeb\x8c\x03\x6f\x30\xbf"
+			  "\xe0\xe1\x20\x65\x74\x65\x54\x43"
+			  "\x92\x57\xd2\x73\x8a\xeb\x99\x38"
+			  "\xca\x78\xc8\x11\xd7\x92\x1a\x05"
+			  "\x55\xb8\xfa\xa0\x82\xb7\xd6\x16"
+			  "\x84\x4d\x25\xc4\xd5\xe4\x55\xf3"
+			  "\x6c\xb3\xe4\x6e\x66\x31\x5c\x41"
+			  "\x98\x46\x28\xd8\x71\x05\xf2\x3b"
+			  "\xd1\x3e\x0f\x79\x7f\xf3\x30\x3f"
+			  "\xbe\x36\xf4\x50\xbd\x0c\x89\xd5"
+			  "\xcb\x53\x9f\xeb\x56\xf4\x3f",
+		.ctext	= "\xee\x90\xe1\x45\xf5\xab\x04\x23"
+			  "\x70\x0a\x54\x49\xac\x34\xb8\x69"
+			  "\x3f\xa8\xce\xef\x6e\x63\xc1\x20"
+			  "\x7a\x41\x43\x5d\xa2\x29\x71\x1d"
+			  "\xd2\xbb\xb1\xca\xb4\x3a\x5a\xf3"
+			  "\x0a\x68\x0b\x9d\x6f\x68\x60\x9e"
+			  "\x9d\xb9\x23\x68\xbb\xdd\x12\x31"
+			  "\xc6\xd6\xf9\xb3\x80\xe8\xb5\xab"
+			  "\x84\x2a\x8e\x7b\xb2\x4f\xee\x31"
+			  "\x83\xc4\x1c\x80\x89\xe4\xe7\xd2"
+			  "\x00\x65\x98\xd1\x57\xcc\xf6\x87"
+			  "\x14\xf1\x23\x22\x78\x61\xc7\xb6"
+			  "\xf5\x90\x97\xdd\xcd\x90\x98\xd8"
+			  "\xbb\x02\xfa\x2c\xf0\x89\xfc\x7e"
+			  "\xe7\xcd\xee\x41\x3f\x73\x4a\x08"
+			  "\xf8\x8f\xf3\xbf\x3a\xd5\xce\xb7"
+			  "\x7a\xf4\x49\xcd\x3f\xc7\x1f\x77"
+			  "\x98\xd0\x9d\x82\x20\x8a\x04\x5d"
+			  "\x9f\x77\xcb\xf4\x38\x92\x47\xce"
+			  "\x6d\xc3\x51\xc1\xd9\xf4\x2f\x65"
+			  "\x67\x01\xf4\x46\x3b\xd2\x90\x5d"
+			  "\x2a\xcb\xc5\x39\x1c\x72\xa5\xba"
+			  "\xaf\x80\x9b\x87\x01\x85\xa1\x02"
+			  "\xdf\x79\x4c\x27\x77\x3e\xfc\xb3"
+			  "\x96\xbc\x42\xad\xdf\xa4\x16\x1e"
+			  "\x77\xe7\x39\xcc\x78\x2c\xc1\x00"
+			  "\xe5\xa6\xb5\x9b\x0c\x12\x19\xc5"
+			  "\x8b\xbe\xae\x4b\xc3\xa3\x91\x8f"
+			  "\x5b\x82\x0f\x20\x30\x35\x45\x26"
+			  "\x29\x84\x2e\xc8\x2d\xce\xae\xac"
+			  "\xbe\x93\x50\x7a\x6a\x01\x08\x38"
+			  "\xf5\x49\x4d\x8b\x7e\x96\x70",
+		.klen	= 24,
+		.len	= 255,
+	},
+	{
+		.key	= "\x2c\x3c\x6c\x78\xaa\x83\xed\x14"
+			  "\x4e\xe5\xe2\x3e\x1e\x89\xcb\x2f"
+			  "\x19\x5a\x70\x50\x09\x81\x43\x75",
+		.iv	= "\xa5\x57\x8e\x3c\xba\x52\x87\x4f"
+			  "\xb7\x45\x26\xab\x31\xb9\x58\xfa",
+		.ptext	= "\x43\x29\x69\x02\xf0\xc0\x64\xf3"
+			  "\xe1\x85\x75\x25\x11\x5d\x18\xf8"
+			  "\xdc\x96\x82\x1b\xee\x4d\x01\xd2"
+			  "\x28\x83\xbb\xfe\xe1\x72\x14\x3c"
+			  "\xe9\xe5\x9f\x8c\x40\xb5\x0a\xaa"
+			  "\x9f\xb8\xc5\xf1\x01\x05\x65\x79"
+			  "\x90\x05\xeb\xac\xa8\x52\x35\xc4"
+			  "\x2d\x56\x0d\xe1\x37\x09\xb8\xec"
+			  "\x51\xd8\x79\x13\x5b\x85\x8c\x14"
+			  "\x77\xe3\x64\xea\x89\xb1\x04\x9d"
+			  "\x6c\x58\x1b\x51\x54\x1f\xc7\x2f"
+			  "\xc8\x3d\xa6\x93\x39\xce\x77\x3a"
+			  "\x93\xc2\xaa\x88\xcc\x09\xfa\xc4"
+			  "\x5e\x92\x3b\x46\xd2\xd6\xd4\x5d"
+			  "\x31\x58\xc5\xc6\x30\xb8\x7f\x77"
+			  "\x0f\x1b\xf8\x9a\x7d\x3f\x56\x90"
+			  "\x61\x8f\x08\x8f\x61\x64\x8e\xf4"
+			  "\xaa\x7c\xf8\x4c\x0b\xab\x47\x2a"
+			  "\x0d\xa7\x24\x36\x59\xfe\x94\xfc"
+			  "\x38\x38\x32\xdf\x73\x1b\x75\xb1"
+			  "\x6f\xa2\xd8\x0b\xa1\xd4\x31\x58"
+			  "\xaa\x24\x11\x22\xc9\xf7\x83\x3c"
+			  "\x6e\xee\x75\xc0\xdd\x3b\x21\x99"
+			  "\x9f\xde\x81\x9c\x2a\x70\xc4\xb8"
+			  "\xc6\x27\x4e\x5d\x9a\x4a\xe1\x75"
+			  "\x01\x95\x47\x87\x3f\x9a\x69\x20"
+			  "\xb4\x66\x70\x1a\xe2\xb3\x6c\xfa"
+			  "\x1f\x6e\xf9\xc3\x8a\x1f\x0b\x0b"
+			  "\xc5\x92\xba\xd9\xf8\x27\x6b\x97"
+			  "\x01\xe2\x38\x01\x7f\x06\xde\x54"
+			  "\xb7\x78\xbc\x7d\x6a\xa1\xf2\x6f"
+			  "\x62\x42\x30\xbf\xb1\x6d\xc7",
+		.ctext	= "\x53\xc0\xb3\x13\x8f\xbf\x88\x1a"
+			  "\x6f\xda\xad\x0b\x33\x8b\x82\x9d"
+			  "\xca\x17\x32\x65\xaa\x72\x24\x1b"
+			  "\x95\x33\xcc\x5b\x58\x5d\x08\x58"
+			  "\xe5\x52\xc0\xb7\xc6\x97\x77\x66"
+			  "\xbd\xf4\x50\xde\xe1\xf0\x70\x61"
+			  "\xc2\x05\xce\xe0\x90\x2f\x7f\xb3"
+			  "\x04\x7a\xee\xbe\xb3\xb7\xaf\xda"
+			  "\x3c\xb8\x95\xb4\x20\xba\x66\x0b"
+			  "\x97\xcc\x07\x3f\x22\x07\x0e\xea"
+			  "\x76\xd8\x32\xf9\x34\x47\xcb\xaa"
+			  "\xb3\x5a\x06\x68\xac\x94\x10\x39"
+			  "\xf2\x70\xe1\x7b\x98\x5c\x0c\xcb"
+			  "\x8f\xd8\x48\xfa\x2e\x15\xa1\xf1"
+			  "\x2f\x85\x55\x39\xd8\x24\xe6\xc1"
+			  "\x6f\xd7\x52\x97\x42\x7a\x2e\x14"
+			  "\x39\x74\x16\xf3\x8b\xbd\x38\xb9"
+			  "\x54\x20\xc6\x31\x1b\x4c\xb7\x26"
+			  "\xd4\x71\x63\x97\xaa\xbf\xf5\xb7"
+			  "\x17\x5e\xee\x14\x67\x38\x14\x11"
+			  "\xf6\x98\x3c\x70\x4a\x89\xf4\x27"
+			  "\xb4\x72\x7a\xc0\x5d\x58\x3d\x8b"
+			  "\xf6\xf7\x80\x7b\xa9\xa7\x4d\xf8"
+			  "\x1a\xbe\x07\x0c\x06\x97\x25\xc8"
+			  "\x5a\x18\xae\x21\xa6\xe4\x77\x13"
+			  "\x5a\xe5\xf5\xe0\xd5\x48\x73\x22"
+			  "\x68\xde\x70\x05\xc4\xdf\xd5\x7c"
+			  "\xa0\x2b\x99\x9c\xa8\x21\xd7\x6c"
+			  "\x55\x97\x09\xd6\xb0\x62\x93\x90"
+			  "\x14\xb1\xd1\x83\x5a\xb3\x17\xb9"
+			  "\xc7\xcc\x6b\x51\x23\x44\x4b\xef"
+			  "\x48\x0f\x0f\xf0\x0e\xa1\x8f",
+		.klen	= 24,
+		.len	= 255,
+	},
+	{
+		.key	= "\xed\xd1\xcf\x81\x1c\xf8\x9d\x56"
+			  "\xd4\x3b\x86\x4b\x65\x96\xfe\xe8"
+			  "\x8a\xd4\x3b\xd7\x76\x07\xab\xf4"
+			  "\xe9\xae\xd1\x4d\x50\x9b\x94\x1c",
+		.iv	= "\x09\x90\xf3\x7c\x15\x99\x7d\x94"
+			  "\x88\xf4\x99\x19\xd1\x62\xc4\x65",
+		.ptext	= "\xa2\x06\x41\x55\x60\x2c\xe3\x76"
+			  "\xa9\xaf\xf9\xe1\xd7\x0d\x65\x49"
+			  "\xda\x27\x0d\xf8\xec\xdc\x09\x2b"
+			  "\x06\x24\xe4\xd5\x15\x29\x6b\x5f",
+		.ctext	= "\xad\x5c\xd0\xc1\x03\x45\xba\x9d"
+			  "\xab\x6d\x82\xae\xf7\x8e\x2b\x8b"
+			  "\xd8\x61\xe6\x96\x5c\x5c\xe2\x70"
+			  "\xe5\x19\x0a\x04\x60\xca\x45\xfc",
+		.klen	= 32,
+		.len	= 32,
+	},
+	{
+		.key	= "\xf8\x75\xa6\xba\x7b\x00\xf0\x71"
+			  "\x24\x5d\xdf\x93\x8b\xa3\x7d\x6d"
+			  "\x8e\x0f\x65\xf4\xe2\xbe\x2b\xaa"
+			  "\x2a\x0d\x9e\x00\x6a\x94\x80\xa1",
+		.iv	= "\xb9\xb7\x55\x26\x5f\x96\x16\x68"
+			  "\x5c\x5f\x58\xbb\x4e\x5a\xe1\x3b",
+		.ptext	= "\x2f\xd9\x2c\xc2\x98\x1e\x81\x5e"
+			  "\x89\xc8\xec\x1f\x56\x3e\xd9\xa4"
+			  "\x92\x48\xec\xfc\x5d\xeb\x7f\xad"
+			  "\x7a\x47\xe6\xda\x71\x1b\x2e\xfa",
+		.ctext	= "\x25\x5e\x38\x20\xcf\xbe\x4c\x6c"
+			  "\xe6\xce\xfc\xe2\xca\x6a\xa1\x62"
+			  "\x3a\xb7\xdf\x21\x3e\x49\xa6\xb8"
+			  "\x22\xd2\xc8\x37\xa4\x55\x09\xe6",
+		.klen	= 32,
+		.len	= 32,
+	},
+	{
+		.key	= "\x32\x37\x2b\x8f\x7b\xb1\x23\x79"
+			  "\x05\x52\xde\x05\xf1\x68\x3f\x6c"
+			  "\xa4\xae\xbc\x21\xc2\xc6\xf0\xbd"
+			  "\x0f\x20\xb7\xa4\xc5\x05\x7b\x64",
+		.iv	= "\xff\x26\x4e\x67\x48\xdd\xcf\xfe"
+			  "\x42\x09\x04\x98\x5f\x1e\xfa\x80",
+		.ptext	= "\x99\xdc\x3b\x19\x41\xf9\xff\x6e"
+			  "\x76\xb5\x03\xfa\x61\xed\xf8\x44"
+			  "\x70\xb9\xf0\x83\x80\x6e\x31\x77"
+			  "\x77\xe4\xc7\xb4\x77\x02\xab\x91"
+			  "\x82\xc6\xf8\x7c\x46\x61\x03\x69"
+			  "\x09\xa0\xf7\x12\xb7\x81\x6c\xa9"
+			  "\x10\x5c\xbb\x55\xb3\x44\xed\xb5"
+			  "\xa2\x52\x48\x71\x90\x5d\xda\x40"
+			  "\x0b\x7f\x4a\x11\x6d\xa7\x3d\x8e"
+			  "\x1b\xcd\x9d\x4e\x75\x8b\x7d\x87"
+			  "\xe5\x39\x34\x32\x1e\xe6\x8d\x51"
+			  "\xd4\x1f\xe3\x1d\x50\xa0\x22\x37"
+			  "\x7c\xb0\xd9\xfb\xb6\xb2\x16\xf6"
+			  "\x6d\x26\xa0\x4e\x8c\x6a\xe6\xb6"
+			  "\xbe\x4c\x7c\xe3\x88\x10\x18\x90"
+			  "\x11\x50\x19\x90\xe7\x19\x3f\xd0"
+			  "\x31\x15\x0f\x06\x96\xfe\xa7\x7b"
+			  "\xc3\x32\x88\x69\xa4\x12\xe3\x64"
+			  "\x02\x30\x17\x74\x6c\x88\x7c\x9b"
+			  "\xd6\x6d\x75\xdf\x11\x86\x70\x79"
+			  "\x48\x7d\x34\x3e\x33\x58\x07\x8b"
+			  "\xd2\x50\xac\x35\x15\x45\x05\xb4"
+			  "\x4d\x31\x97\x19\x87\x23\x4b\x87"
+			  "\x53\xdc\xa9\x19\x78\xf1\xbf\x35"
+			  "\x30\x04\x14\xd4\xcf\xb2\x8c\x87"
+			  "\x7d\xdb\x69\xc9\xcd\xfe\x40\x3e"
+			  "\x8d\x66\x5b\x61\xe5\xf0\x2d\x87"
+			  "\x93\x3a\x0c\x2b\x04\x98\x05\xc2"
+			  "\x56\x4d\xc4\x6c\xcd\x7a\x98\x7e"
+			  "\xe2\x2d\x79\x07\x91\x9f\xdf\x2f"
+			  "\x72\xc9\x8f\xcb\x0b\x87\x1b\xb7"
+			  "\x04\x86\xcb\x47\xfa\x5d\x03",
+		.ctext	= "\x0b\x00\xf7\xf2\xc8\x6a\xba\x9a"
+			  "\x0a\x97\x18\x7a\x00\xa0\xdb\xf4"
+			  "\x5e\x8e\x4a\xb7\xe0\x51\xf1\x75"
+			  "\x17\x8b\xb4\xf1\x56\x11\x05\x9f"
+			  "\x2f\x2e\xba\x67\x04\xe1\xb4\xa5"
+			  "\xfc\x7c\x8c\xad\xc6\xb9\xd1\x64"
+			  "\xca\xbd\x5d\xaf\xdb\x65\x48\x4f"
+			  "\x1b\xb3\x94\x5c\x0b\xd0\xee\xcd"
+			  "\xb5\x7f\x43\x8a\xd8\x8b\x66\xde"
+			  "\xd2\x9c\x13\x65\xa4\x47\xa7\x03"
+			  "\xc5\xa1\x46\x8f\x2f\x84\xbc\xef"
+			  "\x48\x9d\x9d\xb5\xbd\x43\xff\xd2"
+			  "\xd2\x7a\x5a\x13\xbf\xb4\xf6\x05"
+			  "\x17\xcd\x01\x12\xf0\x35\x27\x96"
+			  "\xf4\xc1\x65\xf7\x69\xef\x64\x1b"
+			  "\x6e\x4a\xe8\x77\xce\x83\x01\xb7"
+			  "\x60\xe6\x45\x2a\xcd\x41\x4a\xb5"
+			  "\x8e\xcc\x45\x93\xf1\xd6\x64\x5f"
+			  "\x32\x60\xe4\x29\x4a\x82\x6c\x86"
+			  "\x16\xe4\xcc\xdb\x5f\xc8\x11\xa6"
+			  "\xfe\x88\xd6\xc3\xe5\x5c\xbb\x67"
+			  "\xec\xa5\x7b\xf5\xa8\x4f\x77\x25"
+			  "\x5d\x0c\x2a\x99\xf9\xb9\xd1\xae"
+			  "\x3c\x83\x2a\x93\x9b\x66\xec\x68"
+			  "\x2c\x93\x02\x8a\x8a\x1e\x2f\x50"
+			  "\x09\x37\x19\x5c\x2a\x3a\xc2\xcb"
+			  "\xcb\x89\x82\x81\xb7\xbb\xef\x73"
+			  "\x8b\xc9\xae\x42\x96\xef\x70\xc0"
+			  "\x89\xc7\x3e\x6a\x26\xc3\xe4\x39"
+			  "\x53\xa9\xcf\x63\x7d\x05\xf3\xff"
+			  "\x52\x04\xf6\x7f\x23\x96\xe9\xf7"
+			  "\xff\xd6\x50\xa3\x0e\x20\x71",
+		.klen	= 32,
+		.len	= 255,
+	},
+	{
+		.key	= "\x49\x85\x84\x69\xd4\x5f\xf9\xdb"
+			  "\xf2\xc4\x1c\x62\x20\x88\xea\x8a"
+			  "\x5b\x69\xe6\x3b\xe2\x5c\xfe\xce"
+			  "\xe1\x7a\x27\x7b\x1c\xc9\xb4\x43",
+		.iv	= "\xae\x98\xdb\xef\x5c\x6b\xe9\x27"
+			  "\x1a\x2f\x51\x17\x97\x7d\x4f\x10",
+		.ptext	= "\xbe\xf2\x8f\x8a\x51\x9e\x3d\xff"
+			  "\xd7\x68\x0f\xd2\xf2\x5b\xe3\xa5"
+			  "\x59\x3e\xcd\xab\x46\xc6\xe9\x24"
+			  "\x43\xbc\xb8\x37\x1f\x55\x7f\xb5"
+			  "\xc0\xa6\x68\xdf\xbf\x21\x1e\xed"
+			  "\x67\x73\xb7\x06\x47\xff\x67\x07"
+			  "\x5b\x94\xab\xef\x43\x95\x52\xce"
+			  "\xe7\x71\xbd\x72\x5b\x3a\x25\x01"
+			  "\xed\x7d\x02\x2d\x72\xd6\xc4\x3d"
+			  "\xd2\xf5\xe5\xb3\xf2\xd7\xa1\x8d"
+			  "\x12\x0d\x3b\x4a\x58\xf4\x1b\xfd"
+			  "\xcd\x2c\x13\x05\x07\x3d\x30\x8a"
+			  "\x1f\xc6\xed\xfc\x7c\x3c\xa6\x1c"
+			  "\x64\x2c\x36\xa8\x5d\xe2\xfa\x12"
+			  "\xd7\x17\xa9\x39\x43\x63\xbf\x44"
+			  "\xd0\xcb\x4c\xf0\xab\xe6\x75\xd6"
+			  "\x60\xd1\x64\x9e\x01\x2b\x97\x52"
+			  "\x97\x24\x32\xb0\xfa\x22\xf4\x04"
+			  "\xe6\x98\x6a\xbc\xba\xe8\x65\xad"
+			  "\x60\x08\xfc\xd7\x40\xf8\x2a\xf2"
+			  "\x5e\x32\x32\x82\x24\x12\xda\xbc"
+			  "\x8f\x1c\xd4\x06\x81\x08\x80\x35"
+			  "\x20\xa5\xa8\x3a\x6e\x3e\x2f\x78"
+			  "\xe4\x7d\x9e\x81\x43\xb8\xfe\xa7"
+			  "\x3b\xa9\x9b\x1a\xe7\xce\xd2\x3d"
+			  "\xc1\x27\x26\x22\x35\x12\xa2\xc6"
+			  "\x59\x51\x22\x31\x7b\xc8\xca\xa6"
+			  "\xa9\xf3\x16\x57\x72\x3d\xfa\x24"
+			  "\x66\x56\x5d\x21\x29\x9e\xf2\xff"
+			  "\xae\x0c\x71\xcf\xc5\xf0\x98\xe5"
+			  "\xa1\x05\x96\x94\x3e\x36\xed\x97"
+			  "\xc7\xee\xcd\xc2\x54\x35\x5c",
+		.ctext	= "\xde\x7f\x5e\xac\x6f\xec\xed\x2a"
+			  "\x3a\x3b\xb3\x36\x19\x46\x26\x27"
+			  "\x09\x7b\x49\x47\x1b\x88\x43\xb7"
+			  "\x65\x67\xef\x0b\xe4\xde\x0a\x97"
+			  "\x7f\xab\x32\x7c\xa2\xde\x4e\xba"
+			  "\x11\x9b\x19\x12\x7d\x03\x01\x15"
+			  "\xa3\x90\x9f\x52\x9d\x29\x3d\x5c"
+			  "\xc6\x71\x59\x2c\x44\x8f\xb7\x8c"
+			  "\x0d\x75\x81\x76\xe2\x11\x96\x41"
+			  "\xae\x48\x27\x0e\xbc\xaf\x1d\xf5"
+			  "\x51\x68\x5a\x34\xe5\x6d\xdf\x60"
+			  "\xc7\x9d\x4e\x1a\xaa\xb5\x1a\x57"
+			  "\x58\x6a\xa4\x79\x0a\xa9\x50\x8d"
+			  "\x93\x59\xef\x5b\x23\xdb\xc8\xb3"
+			  "\x38\x96\x8c\xdf\x7d\x6a\x3d\x53"
+			  "\x84\x9d\xb0\xf0\x07\x5f\xff\x67"
+			  "\xff\x5b\x3c\x8b\x1f\xa2\x3b\xcf"
+			  "\xf5\x86\x7c\xbc\x98\x38\x7a\xe5"
+			  "\x96\x56\xba\x44\x85\x29\x4f\x3a"
+			  "\x64\xde\xec\xc6\x53\xf0\x30\xca"
+			  "\xa4\x90\x4f\x9c\x2e\x0e\xec\x2d"
+			  "\x8c\x38\x1c\x93\x9a\x5d\x5d\x98"
+			  "\xf9\x2c\xf7\x27\x71\x3c\x69\xa9"
+			  "\x0b\xec\xd9\x9c\x6c\x69\x09\x47"
+			  "\xd9\xc2\x84\x6e\x3e\x2d\x9f\x1f"
+			  "\xb6\x13\x62\x4c\xf3\x33\x44\x13"
+			  "\x6c\x43\x0a\xae\x8e\x89\xd6\x27"
+			  "\xdd\xc3\x5b\x37\x62\x09\x47\x94"
+			  "\xe3\xea\x7d\x08\x14\x70\xb1\x8e"
+			  "\x83\x4a\xcb\xc0\xa9\xf2\xa3\x02"
+			  "\xe9\xa0\x44\xfe\xcf\x5a\x15\x50"
+			  "\xc4\x5a\x6f\xc8\xd6\xf1\x83",
+		.klen	= 32,
+		.len	= 255,
+	},
+};
+
 #endif	/* _CRYPTO_TESTMGR_H */
diff --git a/crypto/xctr.c b/crypto/xctr.c
new file mode 100644
index 000000000000..dfb44c092cc4
--- /dev/null
+++ b/crypto/xctr.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * XCTR: XOR Counter mode - Adapted from ctr.c
+ *
+ * (C) Copyright IBM Corp. 2007 - Joy Latten <latten at us.ibm.com>
+ * Copyright 2021 Google LLC
+ */
+
+/*
+ * XCTR mode is a blockcipher mode of operation used to implement HCTR2. XCTR is
+ * closely related to the CTR mode of operation; the main difference is that CTR
+ * generates the keystream using E(CTR + IV) whereas XCTR generates the
+ * keystream using E(CTR ^ IV).
+ *
+ * See the HCTR2 paper for more details:
+ *	Length-preserving encryption with HCTR2
+ *      (https://eprint.iacr.org/2021/1441.pdf)
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/xctr.h>
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+static void crypto_xctr_crypt_final(struct skcipher_walk *walk,
+				   struct crypto_cipher *tfm, u32 byte_ctr)
+{
+	unsigned int bsize = crypto_cipher_blocksize(tfm);
+	unsigned long alignmask = crypto_cipher_alignmask(tfm);
+	u8 ctr[MAX_CIPHER_BLOCKSIZE];
+	u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
+	u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
+	u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+	u8 *src = walk->src.virt.addr;
+	u8 *dst = walk->dst.virt.addr;
+	unsigned int nbytes = walk->nbytes;
+	u32 ctr32 = byte_ctr / bsize + 1;
+
+	u32_to_le_block(ctr, ctr32, bsize);
+	crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
+	crypto_cipher_encrypt_one(tfm, keystream, ctrblk);
+	crypto_xor_cpy(dst, keystream, src, nbytes);
+}
+
+static int crypto_xctr_crypt_segment(struct skcipher_walk *walk,
+				    struct crypto_cipher *tfm, u32 byte_ctr)
+{
+	void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+		   crypto_cipher_alg(tfm)->cia_encrypt;
+	unsigned int bsize = crypto_cipher_blocksize(tfm);
+	u8 ctr[MAX_CIPHER_BLOCKSIZE];
+	u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
+	u8 *src = walk->src.virt.addr;
+	u8 *dst = walk->dst.virt.addr;
+	unsigned int nbytes = walk->nbytes;
+	u32 ctr32 = byte_ctr / bsize + 1;
+
+	do {
+		/* create keystream */
+		u32_to_le_block(ctr, ctr32, bsize);
+		crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
+		fn(crypto_cipher_tfm(tfm), dst, ctrblk);
+		crypto_xor(dst, src, bsize);
+
+		ctr32++;
+
+		src += bsize;
+		dst += bsize;
+	} while ((nbytes -= bsize) >= bsize);
+
+	return nbytes;
+}
+
+static int crypto_xctr_crypt_inplace(struct skcipher_walk *walk,
+				    struct crypto_cipher *tfm, u32 byte_ctr)
+{
+	void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
+		   crypto_cipher_alg(tfm)->cia_encrypt;
+	unsigned int bsize = crypto_cipher_blocksize(tfm);
+	unsigned long alignmask = crypto_cipher_alignmask(tfm);
+	unsigned int nbytes = walk->nbytes;
+	u8 ctr[MAX_CIPHER_BLOCKSIZE];
+	u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
+	u8 *src = walk->src.virt.addr;
+	u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
+	u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
+	u32 ctr32 = byte_ctr / bsize + 1;
+
+	u32_to_le_block(ctr, ctr32, bsize);
+	do {
+		/* create keystream */
+		u32_to_le_block(ctr, ctr32, bsize);
+		crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
+		fn(crypto_cipher_tfm(tfm), keystream, ctrblk);
+		crypto_xor(src, keystream, bsize);
+
+		ctr32++;
+
+		src += bsize;
+	} while ((nbytes -= bsize) >= bsize);
+
+	return nbytes;
+}
+
+static int crypto_xctr_crypt(struct skcipher_request *req)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
+	const unsigned int bsize = crypto_cipher_blocksize(cipher);
+	struct skcipher_walk walk;
+	unsigned int nbytes;
+	int err;
+	u32 byte_ctr = 0;
+
+	err = skcipher_walk_virt(&walk, req, false);
+
+	while (walk.nbytes >= bsize) {
+		if (walk.src.virt.addr == walk.dst.virt.addr)
+			nbytes = crypto_xctr_crypt_inplace(&walk, cipher, byte_ctr);
+		else
+			nbytes = crypto_xctr_crypt_segment(&walk, cipher, byte_ctr);
+
+		byte_ctr += walk.nbytes - nbytes;
+		err = skcipher_walk_done(&walk, nbytes);
+	}
+
+	if (walk.nbytes) {
+		crypto_xctr_crypt_final(&walk, cipher, byte_ctr);
+		err = skcipher_walk_done(&walk, 0);
+	}
+
+	return err;
+}
+
+static int crypto_xctr_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+	struct skcipher_instance *inst;
+	struct crypto_alg *alg;
+	int err;
+
+	inst = skcipher_alloc_instance_simple(tmpl, tb);
+	if (IS_ERR(inst))
+		return PTR_ERR(inst);
+
+	alg = skcipher_ialg_simple(inst);
+
+	/* Block size must be >= 4 bytes. */
+	err = -EINVAL;
+	if (alg->cra_blocksize < 4)
+		goto out_free_inst;
+
+	/* XCTR mode is a stream cipher. */
+	inst->alg.base.cra_blocksize = 1;
+
+	/*
+	 * To simplify the implementation, configure the skcipher walk to only
+	 * give a partial block at the very end, never earlier.
+	 */
+	inst->alg.chunksize = alg->cra_blocksize;
+
+	inst->alg.encrypt = crypto_xctr_crypt;
+	inst->alg.decrypt = crypto_xctr_crypt;
+
+	err = skcipher_register_instance(tmpl, inst);
+	if (err) {
+out_free_inst:
+		inst->free(inst);
+	}
+
+	return err;
+}
+
+static struct crypto_template crypto_xctr_tmpl[] = {
+	{
+		.name = "xctr",
+		.create = crypto_xctr_create,
+		.module = THIS_MODULE,
+	}
+};
+
+static int __init crypto_xctr_module_init(void)
+{
+	return crypto_register_template(crypto_xctr_tmpl);
+}
+
+static void __exit crypto_xctr_module_exit(void)
+{
+	crypto_unregister_template(crypto_xctr_tmpl);
+}
+
+subsys_initcall(crypto_xctr_module_init);
+module_exit(crypto_xctr_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("XCTR block cipher mode of operation");
+MODULE_ALIAS_CRYPTO("xctr");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/include/crypto/xctr.h b/include/crypto/xctr.h
new file mode 100644
index 000000000000..0d025e08ca26
--- /dev/null
+++ b/include/crypto/xctr.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * XCTR: XOR Counter mode
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <asm/unaligned.h>
+
+#ifndef _CRYPTO_XCTR_H
+#define _CRYPTO_XCTR_H
+
+static inline void u32_to_le_block(u8 *a, u32 x, unsigned int size)
+{
+	memset(a, 0, size);
+	put_unaligned(cpu_to_le32(x), (u32 *)a);
+}
+
+#endif  /* _CRYPTO_XCTR_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:17 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:17 -0600
Subject: [RFC PATCH 2/7] crypto: polyval - Add POLYVAL support
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-3-nhuck@google.com>

Add support for POLYVAL, an ?-universal hash function similar to GHASH.
POLYVAL is used as a component to implement HCTR2 mode.

POLYVAL is implemented as an shash algorithm.  The implementation is
modified from ghash-generic.c.

More information on POLYVAL can be found in the HCTR2 paper:
https://eprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 crypto/Kconfig           |   8 ++
 crypto/Makefile          |   1 +
 crypto/polyval-generic.c | 183 +++++++++++++++++++++++++
 crypto/tcrypt.c          |   4 +
 crypto/testmgr.c         |   6 +
 crypto/testmgr.h         | 284 +++++++++++++++++++++++++++++++++++++++
 include/crypto/polyval.h |  22 +++
 7 files changed, 508 insertions(+)
 create mode 100644 crypto/polyval-generic.c
 create mode 100644 include/crypto/polyval.h

diff --git a/crypto/Kconfig b/crypto/Kconfig
index b00de5f22eaf..051060cd5e21 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -760,6 +760,14 @@ config CRYPTO_GHASH
 	  GHASH is the hash function used in GCM (Galois/Counter Mode).
 	  It is not a general-purpose cryptographic hash function.
 
+config CRYPTO_POLYVAL
+	tristate
+	select CRYPTO_GF128MUL
+	select CRYPTO_HASH
+	help
+	  POLYVAL is the hash function used in HCTR2.  It is not a general-purpose
+	  cryptographic hash function.
+
 config CRYPTO_POLY1305
 	tristate "Poly1305 authenticator algorithm"
 	select CRYPTO_HASH
diff --git a/crypto/Makefile b/crypto/Makefile
index 6b3fe3df1489..561f901a91d4 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -169,6 +169,7 @@ UBSAN_SANITIZE_jitterentropy.o = n
 jitterentropy_rng-y := jitterentropy.o jitterentropy-kcapi.o
 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
 obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
+obj-$(CONFIG_CRYPTO_POLYVAL) += polyval-generic.o
 obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
 obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
 obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
diff --git a/crypto/polyval-generic.c b/crypto/polyval-generic.c
new file mode 100644
index 000000000000..63e908697ea0
--- /dev/null
+++ b/crypto/polyval-generic.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * POLYVAL: hash function for HCTR2.
+ *
+ * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1 at iki.fi>
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang at intel.com>
+ * Copyright 2021 Google LLC
+ */
+
+/*
+ * Code based on crypto/ghash-generic.c
+ *
+ * POLYVAL is a keyed hash function similar to GHASH. POLYVAL uses a
+ * different modulus for finite field multiplication which makes hardware
+ * accelerated implementations on little-endian machines faster.
+ *
+ * Like GHASH, POLYVAL is not a cryptographic hash function and should
+ * not be used outside of crypto modes explicitly designed to use POLYVAL.
+ *
+ */
+
+#include <asm/unaligned.h>
+#include <crypto/algapi.h>
+#include <crypto/gf128mul.h>
+#include <crypto/polyval.h>
+#include <crypto/internal/hash.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+struct polyval_tfm_ctx {
+	struct gf128mul_4k *gf128;
+};
+
+static int polyval_init(struct shash_desc *desc)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static void reverse_block(u8 block[POLYVAL_BLOCK_SIZE])
+{
+	u64 *p1 = (u64 *)block;
+	u64 *p2 = (u64 *)&block[8];
+	u64 a = get_unaligned(p1);
+	u64 b = get_unaligned(p2);
+
+	put_unaligned(swab64(a), p2);
+	put_unaligned(swab64(b), p1);
+}
+
+static int polyval_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct polyval_tfm_ctx *ctx = crypto_shash_ctx(tfm);
+	be128 k;
+
+	if (keylen != POLYVAL_BLOCK_SIZE)
+		return -EINVAL;
+
+	gf128mul_free_4k(ctx->gf128);
+
+	BUILD_BUG_ON(sizeof(k) != POLYVAL_BLOCK_SIZE);
+	memcpy(&k, key, POLYVAL_BLOCK_SIZE); /* avoid violating alignment rules */
+
+	reverse_block((u8 *)&k);
+	gf128mul_x_lle(&k, &k);
+
+	ctx->gf128 = gf128mul_init_4k_lle(&k);
+	memzero_explicit(&k, POLYVAL_BLOCK_SIZE);
+
+	if (!ctx->gf128)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int polyval_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *dst = dctx->buffer;
+	u8 *pos;
+	u8 tmp[POLYVAL_BLOCK_SIZE];
+	int n;
+
+	if (dctx->bytes) {
+		n = min(srclen, dctx->bytes);
+		pos = dst + dctx->bytes - 1;
+
+		dctx->bytes -= n;
+		srclen -= n;
+
+		while (n--)
+			*pos-- ^= *src++;
+
+		if (!dctx->bytes)
+			gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+	}
+
+	while (srclen >= POLYVAL_BLOCK_SIZE) {
+		memcpy(tmp, src, POLYVAL_BLOCK_SIZE);
+		reverse_block(tmp);
+		crypto_xor(dst, tmp, POLYVAL_BLOCK_SIZE);
+		gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+		src += POLYVAL_BLOCK_SIZE;
+		srclen -= POLYVAL_BLOCK_SIZE;
+	}
+
+	if (srclen) {
+		dctx->bytes = POLYVAL_BLOCK_SIZE - srclen;
+		pos = dst + POLYVAL_BLOCK_SIZE - 1;
+		while (srclen--)
+			*pos-- ^= *src++;
+	}
+
+	return 0;
+}
+
+static int polyval_final(struct shash_desc *desc, u8 *dst)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	const struct polyval_tfm_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *buf = dctx->buffer;
+
+	if (dctx->bytes)
+		gf128mul_4k_lle((be128 *)dst, ctx->gf128);
+	dctx->bytes = 0;
+
+	reverse_block(buf);
+	memcpy(dst, buf, POLYVAL_BLOCK_SIZE);
+
+	return 0;
+}
+
+static void polyval_exit_tfm(struct crypto_tfm *tfm)
+{
+	struct polyval_tfm_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	gf128mul_free_4k(ctx->gf128);
+}
+
+static struct shash_alg polyval_alg = {
+	.digestsize	= POLYVAL_DIGEST_SIZE,
+	.init		= polyval_init,
+	.update		= polyval_update,
+	.final		= polyval_final,
+	.setkey		= polyval_setkey,
+	.descsize	= sizeof(struct polyval_desc_ctx),
+	.base		= {
+		.cra_name		= "polyval",
+		.cra_driver_name	= "polyval-generic",
+		.cra_priority		= 100,
+		.cra_blocksize		= POLYVAL_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct polyval_tfm_ctx),
+		.cra_module		= THIS_MODULE,
+		.cra_exit		= polyval_exit_tfm,
+	},
+};
+
+static int __init polyval_mod_init(void)
+{
+	return crypto_register_shash(&polyval_alg);
+}
+
+static void __exit polyval_mod_exit(void)
+{
+	crypto_unregister_shash(&polyval_alg);
+}
+
+subsys_initcall(polyval_mod_init);
+module_exit(polyval_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("POLYVAL hash function");
+MODULE_ALIAS_CRYPTO("polyval");
+MODULE_ALIAS_CRYPTO("polyval-generic");
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index da7848f84d12..b358a5141218 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -1924,6 +1924,10 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
 		ret += tcrypt_test("ccm(sm4)");
 		break;
 
+	case 57:
+		ret += tcrypt_test("polyval");
+		break;
+
 	case 100:
 		ret += tcrypt_test("hmac(md5)");
 		break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 5acf92354543..a3a24aa07492 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5248,6 +5248,12 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.hash = __VECS(poly1305_tv_template)
 		}
+	}, {
+		.alg = "polyval",
+		.test = alg_test_hash,
+		.suite = {
+			.hash = __VECS(polyval_tv_template)
+		}
 	}, {
 		.alg = "rfc3686(ctr(aes))",
 		.test = alg_test_skcipher,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index e1ebbb3c4d4c..da3736e51982 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -33346,4 +33346,288 @@ static const struct cipher_testvec aes_xctr_tv_template[] = {
 	},
 };
 
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ */
+static const struct hash_testvec polyval_tv_template[] = {
+	{
+		.key	= "\x31\x07\x28\xd9\x91\x1f\x1f\x38"
+			  "\x37\xb2\x43\x16\xc3\xfa\xb9\xa0",
+		.plaintext	= "\x65\x78\x61\x6d\x70\x6c\x65\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x48\x65\x6c\x6c\x6f\x20\x77\x6f"
+			  "\x72\x6c\x64\x00\x00\x00\x00\x00"
+			  "\x38\x00\x00\x00\x00\x00\x00\x00"
+			  "\x58\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\xad\x7f\xcf\x0b\x51\x69\x85\x16"
+			  "\x62\x67\x2f\x3c\x5f\x95\x13\x8f",
+		.psize	= 48,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.psize	= 16,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x40\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\xeb\x93\xb7\x74\x09\x62\xc5\xe4"
+			  "\x9d\x2a\x90\xa7\xdc\x5c\xec\x74",
+		.psize	= 32,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x60\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x48\xeb\x6c\x6c\x5a\x2d\xbe\x4a"
+			  "\x1d\xde\x50\x8f\xee\x06\x36\x1b",
+		.psize	= 32,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x01\x00\x00\x00\x00\x00\x00",
+		.digest	= "\xce\x6e\xdc\x9a\x50\xb3\x6d\x9a"
+			  "\x98\x98\x6b\xbf\x6a\x26\x1c\x3b",
+		.psize	= 48,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x03\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x80\x01\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x81\x38\x87\x46\xbc\x22\xd2\x6b"
+			  "\x2a\xbc\x3d\xcb\x15\x75\x42\x22",
+		.psize	= 64,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x03\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x04\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x02\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x1e\x39\xb6\xd3\x34\x4d\x34\x8f"
+			  "\x60\x44\xf8\x99\x35\xd1\xcf\x78",
+		.psize	= 80,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x03\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x08\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x01\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x2c\xe7\xda\xaf\x7c\x89\x49\x08"
+			  "\x22\x05\x12\x55\xb1\x2e\xca\x6b",
+		.psize	= 64,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x03\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x04\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x08\x00\x00\x00\x00\x00\x00\x00"
+			  "\x80\x01\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x9c\xa9\x87\x71\x5d\x69\xc1\x78"
+			  "\x67\x11\xdf\xcd\x22\xf8\x30\xfc",
+		.psize	= 80,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xd9\xb3\x60\x27\x96\x94\x94\x1a"
+			  "\xc5\xdb\xc6\x98\x7a\xda\x73\x77",
+		.plaintext	= "\x01\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x02\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x03\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x04\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x05\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x08\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x02\x00\x00\x00\x00\x00\x00",
+		.digest	= "\xff\xcd\x05\xd5\x77\x0f\x34\xad"
+			  "\x92\x67\xf0\xa5\x99\x94\xb1\x5a",
+		.psize	= 96,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\x03\x6e\xe1\xfe\x2d\x79\x26\xaf"
+			  "\x68\x89\x80\x95\xe5\x4e\x7b\x3c",
+		.plaintext	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.psize	= 16,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\x37\x24\xf5\x5f\x1d\x22\xac\x0a"
+			  "\xb8\x30\xda\x0b\x6a\x99\x5d\x74",
+		.plaintext	= "\x75\x76\xf7\x02\x8e\xc6\xeb\x5e"
+			  "\xa7\xe2\x98\x34\x2a\x94\xd4\xb2"
+			  "\x02\xb3\x70\xef\x97\x68\xec\x65"
+			  "\x61\xc4\xfe\x6b\x7e\x72\x96\xfa"
+			  "\x85\x9c\x21\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\xe4\x2a\x3c\x02\xc2\x5b\x64\x86"
+			  "\x9e\x14\x6d\x7b\x23\x39\x87\xbd"
+			  "\xdf\xc2\x40\x87\x1d\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x18\x01\x00\x00\x00\x00\x00\x00"
+			  "\xa8\x00\x00\x00\x00\x00\x00\x00",
+		.digest	= "\x4c\xbb\xa0\x90\xf0\x3f\x7d\x11"
+			  "\x88\xea\x55\x74\x9f\xa6\xc7\xbd",
+		.psize	= 96,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\x90\xcc\xac\xee\xba\xd7\xd4\x68"
+			  "\x98\xa6\x79\x70\xdf\x66\x15\x6c",
+		.plaintext	= "",
+		.digest	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.psize	= 0,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\x89\xc9\x4b\xde\x40\xa6\xf9\x62"
+			  "\x58\x04\x51\x26\xb4\xb1\x14\xe4",
+		.plaintext	= "",
+		.digest	= "\x00\x00\x00\x00\x00\x00\x00\x00"
+			  "\x00\x00\x00\x00\x00\x00\x00\x00",
+		.psize	= 0,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\x37\xbe\x68\x16\x50\xb9\x4e\xb0"
+			  "\x47\xde\xe2\xbd\xde\xe4\x48\x09",
+		.plaintext	= "\x87\xfc\x68\x9f\xff\xf2\x4a\x1e"
+			  "\x82\x3b\x73\x8f\xc1\xb2\x1b\x7a"
+			  "\x6c\x4f\x81\xbc\x88\x9b\x6c\xa3"
+			  "\x9c\xc2\xa5\xbc\x14\x70\x4c\x9b"
+			  "\x0c\x9f\x59\x92\x16\x4b\x91\x3d"
+			  "\x18\x55\x22\x68\x12\x8c\x63\xb2"
+			  "\x51\xcb\x85\x4b\xd2\xae\x0b\x1c"
+			  "\x5d\x28\x9d\x1d\xb1\xc8\xf0\x77"
+			  "\xe9\xb5\x07\x4e\x06\xc8\xee\xf8"
+			  "\x1b\xed\x72\x2a\x55\x7d\x16\xc9"
+			  "\xf2\x54\xe7\xe9\xe0\x44\x5b\x33"
+			  "\xb1\x49\xee\xff\x43\xfb\x82\xcd"
+			  "\x4a\x70\x78\x81\xa4\x34\x36\xe8"
+			  "\x4c\x28\x54\xa6\x6c\xc3\x6b\x78"
+			  "\xe7\xc0\x5d\xc6\x5d\x81\xab\x70"
+			  "\x08\x86\xa1\xfd\xf4\x77\x55\xfd"
+			  "\xa3\xe9\xe2\x1b\xdf\x99\xb7\x80"
+			  "\xf9\x0a\x4f\x72\x4a\xd3\xaf\xbb"
+			  "\xb3\x3b\xeb\x08\x58\x0f\x79\xce"
+			  "\xa5\x99\x05\x12\x34\xd4\xf4\x86"
+			  "\x37\x23\x1d\xc8\x49\xc0\x92\xae"
+			  "\xa6\xac\x9b\x31\x55\xed\x15\xc6"
+			  "\x05\x17\x37\x8d\x90\x42\xe4\x87"
+			  "\x89\x62\x88\x69\x1c\x6a\xfd\xe3"
+			  "\x00\x2b\x47\x1a\x73\xc1\x51\xc2"
+			  "\xc0\x62\x74\x6a\x9e\xb2\xe5\x21"
+			  "\xbe\x90\xb5\xb0\x50\xca\x88\x68"
+			  "\xe1\x9d\x7a\xdf\x6c\xb7\xb9\x98"
+			  "\xee\x28\x62\x61\x8b\xd1\x47\xf9"
+			  "\x04\x7a\x0b\x5d\xcd\x2b\x65\xf5"
+			  "\x12\xa3\xfe\x1a\xaa\x2c\x78\x42"
+			  "\xb8\xbe\x7d\x74\xeb\x59\xba\xba",
+		.digest	= "\xae\x11\xd4\x60\x2a\x5f\x9e\x42"
+			  "\x89\x04\xc2\x34\x8d\x55\x94\x0a",
+		.psize	= 256,
+		.ksize	= 16,
+	},
+	{
+		.key	= "\xc8\x53\xde\xaa\xb1\x4b\x6b\xd5"
+			  "\x88\xd6\x4c\xe9\xba\x35\x3d\x5a",
+		.plaintext	= "\xc1\xeb\xba\x8d\xb7\x20\x09\xe0"
+			  "\x28\x4f\x29\xf3\xd8\x26\x50\x40"
+			  "\xd9\x06\xa8\xa8\xc0\xbe\xf0\xfb"
+			  "\x75\x7c\x02\x86\x16\x83\x9d\x65"
+			  "\x8f\x5e\xc4\x58\xed\x6a\xb3\x10"
+			  "\xd2\xf7\x23\xc2\x4a\xb0\x00\x6a"
+			  "\x01\x7c\xf7\xf7\x69\x42\xb2\x12"
+			  "\xb0\xeb\x65\x07\xd7\x8e\x2d\x27"
+			  "\x67\xa2\x57\xf0\x49\x0f\x3f\x0e"
+			  "\xc9\xf7\x1b\xe0\x5b\xdd\x87\xfb"
+			  "\x89\xd1\xfa\xb1\x46\xaf\xa2\x93"
+			  "\x01\x65\xb6\x6f\xbe\x29\x7d\x9f"
+			  "\xfa\xf5\x58\xc6\xb5\x92\x55\x25"
+			  "\x4c\xb5\x0c\xc2\x61\x9f\xc4\xb1"
+			  "\x7f\xe3\x61\x18\x3f\x8c\xb2\xd6"
+			  "\xfd\x9f\xd8\xe5\x3d\x03\x05\xa2"
+			  "\x5d\x1a\xa8\xf0\x04\x41\xea\xa6"
+			  "\x07\x67\x86\x00\xe8\x86\xfc\xb1"
+			  "\xc3\x15\x3e\xc8\x84\x2e\x5e\x5f"
+			  "\x7b\x75\x6a\xc4\x48\xb4\xee\x5f"
+			  "\xe9\x76\xdf\xe6\x1a\xd4\x15\x92"
+			  "\x23\x03\x06\xc1\x2d\x0f\x94\xcb"
+			  "\xe6\x5e\x18\xa6\x3b\x38\x1f\xc2"
+			  "\x28\x73\x8a\xbd\x3a\x6f\xb0\x95"
+			  "\x0f\x1c\xc7\xdf\x10\x0b\x2a\x7d"
+			  "\xf9\x6b\xe1\x4a\xfb\xe1\x07\xc9"
+			  "\x69\x7b\x27\x65\xc0\x08\x49\xc0"
+			  "\xf3\x0b\x5b\xa6\x8b\xf7\x1a\xfe"
+			  "\xe3\x9f\x87\x1d\x68\x07\xf4\x53"
+			  "\x8d\x54\xe9\x3f\xd5\x02\x3a\x09"
+			  "\x72\xa9\x84\xdc\x25\xd3\xad\xdb"
+			  "\x4e\x45\x4f\x7f\xe8\x02\x69\x45",
+		.digest	= "\x7b\x4f\x29\xb3\x0b\x4d\x2b\xa3"
+			  "\x40\xc8\x56\x5a\x0a\xcf\xbd\x9b",
+		.psize	= 256,
+		.ksize	= 16,
+	},
+};
+
 #endif	/* _CRYPTO_TESTMGR_H */
diff --git a/include/crypto/polyval.h b/include/crypto/polyval.h
new file mode 100644
index 000000000000..fd0c6e124b65
--- /dev/null
+++ b/include/crypto/polyval.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common values for the Polyval hash algorithm
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#ifndef _CRYPTO_POLYVAL_H
+#define _CRYPTO_POLYVAL_H
+
+#include <linux/types.h>
+#include <linux/crypto.h>
+
+#define POLYVAL_BLOCK_SIZE	16
+#define POLYVAL_DIGEST_SIZE	16
+
+struct polyval_desc_ctx {
+	u8 buffer[POLYVAL_BLOCK_SIZE];
+	u32 bytes;
+};
+
+#endif
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:18 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:18 -0600
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-4-nhuck@google.com>

Add support for HCTR2 as a template.  HCTR2 is a length-preserving
encryption mode that is efficient on processors with instructions to
accelerate AES and carryless multiplication, e.g. x86 processors with
AES-NI and CLMUL, and ARM processors with the ARMv8 Crypto Extensions.

As a length-preserving encryption mode, HCTR2 is suitable for
applications such as storage encryption where ciphertext expansion is
not possible, and thus authenticated encryption cannot be used.
Currently, such applications usually use XTS, or in some cases Adiantum.
XTS has the disadvantage that it is a narrow-block mode: a bitflip will
only change 16 bytes in the resulting ciphertext or plaintext.  This
reveals more information to an attacker than necessary.

HCTR2 is a wide-block mode, so it provides a stronger security property:
a bitflip will change the entire message.  HCTR2 is somewhat similar to
Adiantum, which is also a wide-block mode.  However, HCTR2 is designed
to take advantage of existing crypto instructions, while Adiantum
targets devices without such hardware support.  Adiantum is also
designed with longer messages in mind, while HCTR2 is designed to be
efficient even on short messages.

HCTR2 requires POLYVAL and XCTR as components.  More information on
HCTR2 can be found here: Length-preserving encryption with HCTR2:
https://eprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 crypto/Kconfig   |  11 +
 crypto/Makefile  |   1 +
 crypto/hctr2.c   | 475 ++++++++++++++++++++++++++++
 crypto/tcrypt.c  |   5 +
 crypto/testmgr.c |   6 +
 crypto/testmgr.h | 787 +++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 1285 insertions(+)
 create mode 100644 crypto/hctr2.c

diff --git a/crypto/Kconfig b/crypto/Kconfig
index 051060cd5e21..3cdb6c351062 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -524,6 +524,17 @@ config CRYPTO_ADIANTUM
 
 	  If unsure, say N.
 
+config CRYPTO_HCTR2
+	tristate "HCTR2 support"
+	select CRYPTO_XCTR
+	select CRYPTO_POLYVAL
+	select CRYPTO_MANAGER
+	help
+	  HCTR2 is a length-preserving encryption mode that is efficient on
+	  processors with instructions to accelerate AES and carryless
+	  multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
+	  processors with the ARMv8 crypto extensions.
+
 config CRYPTO_ESSIV
 	tristate "ESSIV support for block encryption"
 	select CRYPTO_AUTHENC
diff --git a/crypto/Makefile b/crypto/Makefile
index 561f901a91d4..2dca9dbdede6 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_CRYPTO_LRW) += lrw.o
 obj-$(CONFIG_CRYPTO_XTS) += xts.o
 obj-$(CONFIG_CRYPTO_CTR) += ctr.o
 obj-$(CONFIG_CRYPTO_XCTR) += xctr.o
+obj-$(CONFIG_CRYPTO_HCTR2) += hctr2.o
 obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
 obj-$(CONFIG_CRYPTO_ADIANTUM) += adiantum.o
 obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
diff --git a/crypto/hctr2.c b/crypto/hctr2.c
new file mode 100644
index 000000000000..af43f81b68f3
--- /dev/null
+++ b/crypto/hctr2.c
@@ -0,0 +1,475 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * HCTR2 length-preserving encryption mode
+ *
+ * Copyright 2021 Google LLC
+ */
+
+
+/*
+ * HCTR2 is a length-preserving encryption mode that is efficient on
+ * processors with instructions to accelerate aes and carryless
+ * multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
+ * processors with the ARMv8 crypto extensions.
+ *
+ * Length-preserving encryption with HCTR2
+ *	(https://eprint.iacr.org/2021/1441.pdf)
+ *
+ *	HCTR2 has a strict set of requirements for the hash function. For this
+ *	purpose we only allow POLYVAL. To avoid misuse, XCTR is required as
+ *	specified in the HCTR2 paper, though theoretically there is a larger class
+ *	of algorithms that could be used.
+ */
+
+#include <crypto/internal/cipher.h>
+#include <crypto/internal/hash.h>
+#include <crypto/internal/skcipher.h>
+#include <crypto/polyval.h>
+#include <crypto/scatterwalk.h>
+#include <linux/module.h>
+
+#define BLOCKCIPHER_BLOCK_SIZE		16
+
+/*
+ * The specification allows variable-length tweaks, but Linux's crypto API
+ * currently only allows algorithms to support a single length.  The "natural"
+ * tweak length for HCTR2 is 16, since that fits into one POLYVAL block for
+ * the best performance.  But longer tweaks are useful for fscrypt, to avoid
+ * needing to derive per-file keys.  So instead we use two blocks, or 32 bytes.
+ */
+#define TWEAK_SIZE		32
+
+struct hctr2_instance_ctx {
+	struct crypto_cipher_spawn blockcipher_spawn;
+	struct crypto_skcipher_spawn streamcipher_spawn;
+	struct crypto_shash_spawn hash_spawn;
+};
+
+struct hctr2_tfm_ctx {
+	struct crypto_cipher *blockcipher;
+	struct crypto_skcipher *streamcipher;
+	struct crypto_shash *hash;
+	u8 L[BLOCKCIPHER_BLOCK_SIZE];
+};
+
+struct hctr2_request_ctx {
+	u8 first_block[BLOCKCIPHER_BLOCK_SIZE];
+	struct scatterlist *bulk_part_dst;
+	struct scatterlist *bulk_part_src;
+	struct scatterlist sg_src[2];
+	struct scatterlist sg_dst[2];
+	/* Sub-requests, must be last */
+	union {
+		struct shash_desc hash_desc;
+		struct skcipher_request streamcipher_req;
+	} u;
+};
+
+static int hctr2_setkey(struct crypto_skcipher *tfm, const u8 *key,
+			unsigned int keylen)
+{
+	struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+	u8 hbar[BLOCKCIPHER_BLOCK_SIZE];
+	int err;
+
+	crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
+	crypto_cipher_set_flags(tctx->blockcipher,
+				crypto_skcipher_get_flags(tfm) &
+				CRYPTO_TFM_REQ_MASK);
+	err = crypto_cipher_setkey(tctx->blockcipher, key, keylen);
+	if (err)
+		return err;
+
+	crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
+	crypto_skcipher_set_flags(tctx->streamcipher,
+				  crypto_skcipher_get_flags(tfm) &
+				  CRYPTO_TFM_REQ_MASK);
+	err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
+	if (err)
+		return err;
+
+	memset(tctx->L, 0, sizeof(tctx->L));
+	memset(hbar, 0, sizeof(hbar));
+	tctx->L[0] = 0x01;
+	crypto_cipher_encrypt_one(tctx->blockcipher, tctx->L, tctx->L);
+	crypto_cipher_encrypt_one(tctx->blockcipher, hbar, hbar);
+
+	crypto_shash_clear_flags(tctx->hash, CRYPTO_TFM_REQ_MASK);
+	crypto_shash_set_flags(tctx->hash, crypto_skcipher_get_flags(tfm) &
+			       CRYPTO_TFM_REQ_MASK);
+	err = crypto_shash_setkey(tctx->hash, hbar, BLOCKCIPHER_BLOCK_SIZE);
+	return err;
+}
+
+static int hctr2_hash_tweak(struct skcipher_request *req, u8 *iv)
+{
+	u64 tweak_length_part[2];
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+	struct shash_desc *hash_desc = &rctx->u.hash_desc;
+	int err;
+
+	memset(tweak_length_part, 0, sizeof(tweak_length_part));
+	if (req->cryptlen % POLYVAL_BLOCK_SIZE == 0)
+		tweak_length_part[0] = cpu_to_le64(TWEAK_SIZE * 8 * 2 + 2);
+	else
+		tweak_length_part[0] = cpu_to_le64(TWEAK_SIZE * 8 * 2 + 3);
+
+	hash_desc->tfm = tctx->hash;
+	err = crypto_shash_init(hash_desc);
+	if (err)
+		return err;
+
+	err = crypto_shash_update(hash_desc, (u8 *)tweak_length_part, sizeof(tweak_length_part));
+	if (err)
+		return err;
+	err = crypto_shash_update(hash_desc, iv, TWEAK_SIZE);
+	return err;
+}
+
+static int hctr2_hash_message(struct skcipher_request *req,
+			      struct scatterlist *sgl,
+			      u8 digest[POLYVAL_DIGEST_SIZE])
+{
+	u8 padding[BLOCKCIPHER_BLOCK_SIZE];
+	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+	struct shash_desc *hash_desc = &rctx->u.hash_desc;
+	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
+	struct sg_mapping_iter miter;
+	unsigned int remainder = bulk_len % BLOCKCIPHER_BLOCK_SIZE;
+	int err;
+
+	sg_miter_start(&miter, sgl, sg_nents(sgl),
+		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
+	while (sg_miter_next(&miter)) {
+		err = crypto_shash_update(hash_desc, miter.addr, miter.length);
+		if (err)
+			break;
+	}
+	sg_miter_stop(&miter);
+	if (err)
+		return err;
+
+	if (remainder) {
+		memset(padding, 0, BLOCKCIPHER_BLOCK_SIZE);
+		padding[0] = 0x01;
+		err = crypto_shash_update(hash_desc, padding, BLOCKCIPHER_BLOCK_SIZE - remainder);
+		if (err)
+			return err;
+	}
+	return crypto_shash_final(hash_desc, digest);
+}
+
+static int hctr2_finish(struct skcipher_request *req)
+{
+	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+	u8 digest[POLYVAL_DIGEST_SIZE];
+	int err;
+
+	err = hctr2_hash_tweak(req, req->iv);
+	if (err)
+		return err;
+	err = hctr2_hash_message(req, rctx->bulk_part_dst, digest);
+	if (err)
+		return err;
+	crypto_xor(rctx->first_block, digest, BLOCKCIPHER_BLOCK_SIZE);
+
+	scatterwalk_map_and_copy(rctx->first_block, req->dst,
+				 0, BLOCKCIPHER_BLOCK_SIZE, 1);
+	return 0;
+}
+
+static void hctr2_streamcipher_done(struct crypto_async_request *areq,
+				    int err)
+{
+	struct skcipher_request *req = areq->data;
+
+	if (!err)
+		err = hctr2_finish(req);
+
+	skcipher_request_complete(req, err);
+}
+
+static int hctr2_crypt(struct skcipher_request *req, bool enc)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
+	u8 digest[POLYVAL_DIGEST_SIZE];
+	int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
+	int err;
+
+	// Requests must be at least one block
+	if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
+		return -EINVAL;
+
+	scatterwalk_map_and_copy(rctx->first_block, req->src,
+				 0, BLOCKCIPHER_BLOCK_SIZE, 0);
+	rctx->bulk_part_src = scatterwalk_ffwd(rctx->sg_src, req->src, BLOCKCIPHER_BLOCK_SIZE);
+	rctx->bulk_part_dst = scatterwalk_ffwd(rctx->sg_dst, req->dst, BLOCKCIPHER_BLOCK_SIZE);
+
+	err = hctr2_hash_tweak(req, req->iv);
+	if (err)
+		return err;
+	err = hctr2_hash_message(req, rctx->bulk_part_src, digest);
+	if (err)
+		return err;
+	crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
+
+	if (enc)
+		crypto_cipher_encrypt_one(tctx->blockcipher, rctx->first_block, digest);
+	else
+		crypto_cipher_decrypt_one(tctx->blockcipher, rctx->first_block, digest);
+
+	crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
+	crypto_xor(digest, tctx->L, BLOCKCIPHER_BLOCK_SIZE);
+
+	skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
+	skcipher_request_set_crypt(&rctx->u.streamcipher_req, rctx->bulk_part_src,
+				   rctx->bulk_part_dst, bulk_len, digest);
+	skcipher_request_set_callback(&rctx->u.streamcipher_req,
+				      req->base.flags,
+				      hctr2_streamcipher_done, req);
+	return crypto_skcipher_encrypt(&rctx->u.streamcipher_req) ?:
+		hctr2_finish(req);
+}
+
+static int hctr2_encrypt(struct skcipher_request *req)
+{
+	return hctr2_crypt(req, true);
+}
+
+static int hctr2_decrypt(struct skcipher_request *req)
+{
+	return hctr2_crypt(req, false);
+}
+
+static int hctr2_init_tfm(struct crypto_skcipher *tfm)
+{
+	struct skcipher_instance *inst = skcipher_alg_instance(tfm);
+	struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
+	struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+	struct crypto_skcipher *streamcipher;
+	struct crypto_cipher *blockcipher;
+	struct crypto_shash *hash;
+	unsigned int subreq_size;
+	int err;
+
+	streamcipher = crypto_spawn_skcipher(&ictx->streamcipher_spawn);
+	if (IS_ERR(streamcipher))
+		return PTR_ERR(streamcipher);
+
+	blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
+	if (IS_ERR(blockcipher)) {
+		err = PTR_ERR(blockcipher);
+		goto err_free_streamcipher;
+	}
+
+	hash = crypto_spawn_shash(&ictx->hash_spawn);
+	if (IS_ERR(hash)) {
+		err = PTR_ERR(hash);
+		goto err_free_blockcipher;
+	}
+
+	tctx->streamcipher = streamcipher;
+	tctx->blockcipher = blockcipher;
+	tctx->hash = hash;
+
+	BUILD_BUG_ON(offsetofend(struct hctr2_request_ctx, u) !=
+				 sizeof(struct hctr2_request_ctx));
+	subreq_size = max(sizeof_field(struct hctr2_request_ctx, u.hash_desc) +
+			  crypto_shash_descsize(hash), sizeof_field(struct
+			  hctr2_request_ctx, u.streamcipher_req) +
+			  crypto_skcipher_reqsize(streamcipher));
+
+	crypto_skcipher_set_reqsize(tfm, offsetof(struct hctr2_request_ctx, u) +
+				    subreq_size);
+	return 0;
+
+err_free_blockcipher:
+	crypto_free_cipher(blockcipher);
+err_free_streamcipher:
+	crypto_free_skcipher(streamcipher);
+	return err;
+}
+
+static void hctr2_exit_tfm(struct crypto_skcipher *tfm)
+{
+	struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
+
+	crypto_free_cipher(tctx->blockcipher);
+	crypto_free_skcipher(tctx->streamcipher);
+	crypto_free_shash(tctx->hash);
+}
+
+static void hctr2_free_instance(struct skcipher_instance *inst)
+{
+	struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
+
+	crypto_drop_cipher(&ictx->blockcipher_spawn);
+	crypto_drop_skcipher(&ictx->streamcipher_spawn);
+	crypto_drop_shash(&ictx->hash_spawn);
+	kfree(inst);
+}
+
+/*
+ * Check for a supported set of inner algorithms.
+ * See the comment at the beginning of this file.
+ */
+static bool hctr2_supported_algorithms(struct skcipher_alg *streamcipher_alg,
+				       struct crypto_alg *blockcipher_alg,
+				       struct shash_alg *hash_alg)
+{
+	if (strncmp(streamcipher_alg->base.cra_name, "xctr(", 4) != 0)
+		return false;
+
+	if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
+		return false;
+
+	if (strcmp(hash_alg->base.cra_name, "polyval") != 0)
+		return false;
+
+	return true;
+}
+
+static int hctr2_create_common(struct crypto_template *tmpl,
+			       struct rtattr **tb,
+			       const char *blockcipher_name,
+			       const char *streamcipher_name,
+			       const char *polyval_name)
+{
+	u32 mask;
+	struct skcipher_instance *inst;
+	struct hctr2_instance_ctx *ictx;
+	struct skcipher_alg *streamcipher_alg;
+	struct crypto_alg *blockcipher_alg;
+	struct shash_alg *hash_alg;
+	int err;
+
+	err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
+	if (err)
+		return err;
+
+	inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
+	if (!inst)
+		return -ENOMEM;
+	ictx = skcipher_instance_ctx(inst);
+
+	/* Stream cipher, xctr(block_cipher) */
+	err = crypto_grab_skcipher(&ictx->streamcipher_spawn,
+				   skcipher_crypto_instance(inst),
+				   streamcipher_name, 0, mask);
+	if (err)
+		goto err_free_inst;
+	streamcipher_alg = crypto_spawn_skcipher_alg(&ictx->streamcipher_spawn);
+
+	/* Block cipher, e.g. "aes" */
+	err = crypto_grab_cipher(&ictx->blockcipher_spawn,
+				 skcipher_crypto_instance(inst),
+				 blockcipher_name, 0, mask);
+	if (err)
+		goto err_free_inst;
+	blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
+
+	/* Polyval ?-?U hash function */
+	err = crypto_grab_shash(&ictx->hash_spawn,
+				skcipher_crypto_instance(inst),
+				polyval_name, 0, mask);
+	if (err)
+		goto err_free_inst;
+	hash_alg = crypto_spawn_shash_alg(&ictx->hash_spawn);
+
+	/* Check the set of algorithms */
+	if (!hctr2_supported_algorithms(streamcipher_alg, blockcipher_alg,
+					hash_alg)) {
+		pr_warn("Unsupported HCTR2 instantiation: (%s,%s,%s)\n",
+			streamcipher_alg->base.cra_name,
+			blockcipher_alg->cra_name, hash_alg->base.cra_name);
+		err = -EINVAL;
+		goto err_free_inst;
+	}
+
+	/* Instance fields */
+
+	err = -ENAMETOOLONG;
+	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
+				 "hctr2(%s)", blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
+		goto err_free_inst;
+	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
+		     "hctr2(%s,%s,%s)",
+		     blockcipher_alg->cra_driver_name,
+		     streamcipher_alg->base.cra_driver_name,
+		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
+		goto err_free_inst;
+
+	inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
+	inst->alg.base.cra_ctxsize = sizeof(struct hctr2_tfm_ctx);
+	inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
+				       hash_alg->base.cra_alignmask;
+	/*
+	 * The hash function is called twice, so it is weighted higher than the
+	 * streamcipher and blockcipher.
+	 */
+	inst->alg.base.cra_priority = (2 * streamcipher_alg->base.cra_priority +
+				       4 * hash_alg->base.cra_priority +
+				       blockcipher_alg->cra_priority) / 7;
+
+	inst->alg.setkey = hctr2_setkey;
+	inst->alg.encrypt = hctr2_encrypt;
+	inst->alg.decrypt = hctr2_decrypt;
+	inst->alg.init = hctr2_init_tfm;
+	inst->alg.exit = hctr2_exit_tfm;
+	inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(streamcipher_alg);
+	inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(streamcipher_alg);
+	inst->alg.ivsize = TWEAK_SIZE;
+
+	inst->free = hctr2_free_instance;
+
+	err = skcipher_register_instance(tmpl, inst);
+	if (err) {
+err_free_inst:
+		hctr2_free_instance(inst);
+	}
+	return err;
+}
+
+static int hctr2_create(struct crypto_template *tmpl, struct rtattr **tb)
+{
+	const char *blockcipher_name;
+	char streamcipher_name[CRYPTO_MAX_ALG_NAME];
+
+	blockcipher_name = crypto_attr_alg_name(tb[1]);
+	if (IS_ERR(blockcipher_name))
+		return PTR_ERR(blockcipher_name);
+
+	if (snprintf(streamcipher_name, CRYPTO_MAX_ALG_NAME, "xctr(%s)",
+		    blockcipher_name) >= CRYPTO_MAX_ALG_NAME)
+		return -ENAMETOOLONG;
+	return hctr2_create_common(tmpl, tb, blockcipher_name, streamcipher_name, "polyval");
+}
+
+/* hctr2(blockcipher_name [, xctr(blockcipher_name)] [, polyval_name]) */
+static struct crypto_template hctr2_tmpl = {
+	.name = "hctr2",
+	.create = hctr2_create,
+	.module = THIS_MODULE,
+};
+
+static int __init hctr2_module_init(void)
+{
+	return crypto_register_template(&hctr2_tmpl);
+}
+
+static void __exit hctr2_module_exit(void)
+{
+	crypto_unregister_template(&hctr2_tmpl);
+}
+
+subsys_initcall(hctr2_module_init);
+module_exit(hctr2_module_exit);
+
+MODULE_DESCRIPTION("HCTR2 length-preserving encryption mode");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_CRYPTO("hctr2");
+MODULE_IMPORT_NS(CRYPTO_INTERNAL);
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index b358a5141218..5af2e859830a 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -2385,6 +2385,11 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
 				   16, 16, aead_speed_template_19, num_mb);
 		break;
 
+	case 226:
+		test_cipher_speed("hctr2(aes)", ENCRYPT, sec, NULL,
+				  0, speed_template_32);
+		break;
+
 	case 300:
 		if (alg) {
 			test_hash_speed(alg, sec, generic_hash_speed_template);
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index a3a24aa07492..fa8f33210358 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4994,6 +4994,12 @@ static const struct alg_test_desc alg_test_descs[] = {
 		.suite = {
 			.hash = __VECS(ghash_tv_template)
 		}
+	}, {
+		.alg = "hctr2(aes)",
+		.test = alg_test_skcipher,
+		.suite = {
+			.cipher = __VECS(aes_hctr2_tv_template)
+		}
 	}, {
 		.alg = "hmac(md5)",
 		.test = alg_test_hash,
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index da3736e51982..87e4df6f8ea9 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -33630,4 +33630,791 @@ static const struct hash_testvec polyval_tv_template[] = {
 	},
 };
 
+/*
+ * Test vectors generated using https://github.com/google/hctr2
+ */
+static const struct cipher_testvec aes_hctr2_tv_template[] = {
+	{
+		.key	= "\xe1\x15\x66\x3c\x8d\xc6\x3a\xff"
+			  "\xef\x41\xd7\x47\xa2\xcc\x8a\xba",
+		.iv	= "\xc3\xbe\x2a\xcb\xb5\x39\x86\xf1"
+			  "\x91\xad\x6c\xf4\xde\x74\x45\x63"
+			  "\x5c\x7a\xd5\xcc\x8b\x76\xef\x0e"
+			  "\xcf\x2c\x60\x69\x37\xfd\x07\x96",
+		.ptext	= "\x65\x75\xae\xd3\xe2\xbc\x43\x5c"
+			  "\xb3\x1a\xd8\x05\xc3\xd0\x56\x29",
+		.ctext	= "\x11\x91\xea\x74\x58\xcc\xd5\xa2"
+			  "\xd0\x55\x9e\x3d\xfe\x7f\xc8\xfe",
+		.klen	= 16,
+		.len	= 16,
+	},
+	{
+		.key	= "\x50\xcc\x28\x5c\xaf\x62\xa2\x4e"
+			  "\x02\xf0\xc0\x5e\xc1\x29\x80\xca",
+		.iv	= "\x64\xa5\xd5\xf9\xf4\x68\x26\xea"
+			  "\xce\xbb\x6c\xdd\xa5\xef\x39\xb5"
+			  "\x5c\x93\xdf\x1b\x93\x21\xbe\x49"
+			  "\xff\x9e\x86\x4f\x7c\x4d\x51\x15",
+		.ptext	= "\x34\xc1\x08\x3e\x9c\x28\x0a\xcf"
+			  "\x33\xdb\x3f\x0d\x05\x27\xa4\xed",
+		.ctext	= "\x7c\xae\xbb\x37\x4a\x55\x94\x5b"
+			  "\xc6\x6f\x8f\x9f\x68\x5f\xc7\x62",
+		.klen	= 16,
+		.len	= 16,
+	},
+	{
+		.key	= "\xda\xce\x30\x85\xe7\x06\xe6\x02"
+			  "\x8f\x02\xbf\x9a\x82\x6e\x54\xde",
+		.iv	= "\xf6\x7a\x28\xce\xfb\x6c\xb3\xc5"
+			  "\x47\x81\x58\x69\x07\xe5\x22\xdb"
+			  "\x66\x93\xd7\xe9\xbd\x5c\x7f\xf0"
+			  "\x8a\x0b\x07\x09\xbb\xf1\x48\xc4",
+		.ptext	= "\x01\xcd\xa4\x47\x8e\x4e\xbc\x7d"
+			  "\xfd\xd8\xe9\xaa\xc7\x37\x25\x3d"
+			  "\x56",
+		.ctext	= "\xf3\xb2\x9e\xde\x96\x5d\xf0\xf6"
+			  "\xb6\x43\x57\xc5\x53\xe8\xf9\x05"
+			  "\x87",
+		.klen	= 16,
+		.len	= 17,
+	},
+	{
+		.key	= "\xe1\x22\xee\x5b\x3c\x92\x0e\x52"
+			  "\xd7\x95\x88\xa3\x79\x6c\xf8\xd9",
+		.iv	= "\xb8\xd1\xe7\x32\x36\x96\xd6\x44"
+			  "\x9c\x36\xad\x31\x5c\xaa\xf0\x17"
+			  "\x33\x2f\x29\x04\x31\xf5\x46\xc1"
+			  "\x2f\x1b\xfa\xa1\xbd\x86\xc4\xd3",
+		.ptext	= "\x87\xd7\xb8\x2d\x12\x62\xed\x41"
+			  "\x30\x7e\xd4\x0c\xfd\xb9\x6d\x8e"
+			  "\x30",
+		.ctext	= "\xb6\x6a\x0c\x71\x96\x22\xb9\x40"
+			  "\xa2\x04\x56\x14\x22\xae\xaa\x94"
+			  "\x26",
+		.klen	= 16,
+		.len	= 17,
+	},
+	{
+		.key	= "\xf6\x2b\xab\xec\x04\x4a\x47\xa6"
+			  "\x37\xf0\x50\x3d\x56\xe5\x61\xac",
+		.iv	= "\xb7\x6d\x55\x7d\xe2\xf0\x10\x93"
+			  "\x07\x1e\x5a\x9d\xc3\x59\x6f\x98"
+			  "\x11\xde\xdb\x3a\x03\xf4\x0e\xcc"
+			  "\x15\xa4\x1c\xdf\x3c\x55\x89\x27",
+		.ptext	= "\xbe\xc6\x74\x4b\xb9\xa1\x43\x86"
+			  "\xc2\x4a\x65\x00\xbf\x43\xe4\x84"
+			  "\x6d\xae\x0a\x3c\xec\x6b\x3d\x43"
+			  "\xcf\x49\x36\x88\x14\x3d\x3c\xfc"
+			  "\xfb\xc1\x58\x1f\x39\x81\x88\xeb"
+			  "\x4e\xa1\xe2\x59\xad\x47\xa3\x61",
+		.ctext	= "\x80\x25\x8e\x11\xed\x58\x21\x6f"
+			  "\x34\xe3\xa1\xb8\xc0\x99\x6a\x50"
+			  "\xe0\x18\x23\x4f\x1b\x00\x68\x39"
+			  "\x75\x34\x95\xfb\x9e\xb4\x18\x89"
+			  "\x53\x12\x2c\xe2\xee\x59\x32\xa6"
+			  "\xc5\x3f\xd1\x37\xbc\x12\x40\xbd",
+		.klen	= 16,
+		.len	= 48,
+	},
+	{
+		.key	= "\x39\x4e\x4d\x5c\xd6\x63\xaf\x4b"
+			  "\xcf\xc3\x2c\x53\x8e\x3d\x7b\x3d",
+		.iv	= "\x1d\x4a\x01\xa0\x88\xac\xdf\x2c"
+			  "\x34\x88\x13\xef\xa4\xe7\xe5\x2e"
+			  "\x44\xf8\xdc\xff\x74\xd4\x8a\x81"
+			  "\x26\xfe\x50\x57\xca\x0b\x93\x54",
+		.ptext	= "\x55\x76\x17\x29\xc6\xd2\xbd\x9c"
+			  "\xf4\xde\x9b\x8e\x71\xf7\xe4\xfd"
+			  "\x60\xc0\xca\xbc\x8a\x70\x31\x9b"
+			  "\x2d\xfd\x92\x51\x31\x4d\x3e\x1b"
+			  "\xdf\x66\x46\xba\x28\x1f\x08\xc1"
+			  "\x1b\xd0\x8a\x5c\x8e\xe1\xcf\x79",
+		.ctext	= "\x34\x1f\x14\x61\x16\xd8\xf0\x73"
+			  "\x38\xe7\x5f\xc8\x64\x70\x28\x93"
+			  "\x9b\xb3\x1c\xfe\x62\xbf\x8e\x3c"
+			  "\xf5\x17\x2d\xfc\x0d\x3b\x61\xf7"
+			  "\x30\x25\x4d\x5b\x0c\x84\x5f\x86"
+			  "\x94\xa1\xbe\xa5\x6d\xa9\x10\x78",
+		.klen	= 16,
+		.len	= 48,
+	},
+	{
+		.key	= "\x3e\x08\x5d\x64\x6c\x98\xec\xec"
+			  "\x70\x0e\x0d\xa1\x41\x20\x99\x82",
+		.iv	= "\x11\xb7\x77\x91\x0d\x99\xd9\x8d"
+			  "\x35\x3a\xf7\x14\x6b\x09\x37\xe5"
+			  "\xad\x51\xf6\xc3\x96\x4b\x64\x56"
+			  "\xa8\xbd\x81\xcc\xbe\x94\xaf\xe4",
+		.ptext	= "\xff\x8d\xb9\xc0\xe3\x69\xb3\xb2"
+			  "\x8b\x11\x26\xb3\x11\xec\xfb\xb9"
+			  "\x9c\xc1\x71\xd6\xe3\x26\x0e\xe0"
+			  "\x68\x40\x60\xb9\x3a\x63\x56\x8a"
+			  "\x9e\xc1\xf0\x10\xb1\x64\x32\x70"
+			  "\xf8\xcd\xc6\xc4\x49\x4c\xe1\xce"
+			  "\xf3\xe1\x03\xf8\x35\xae\xe0\x5e"
+			  "\xef\x5f\xbc\x41\x75\x26\x13\xcc"
+			  "\x37\x85\xdf\xc0\x5d\xa6\x47\x98"
+			  "\xf1\x97\x52\x58\x04\xe6\xb5\x01"
+			  "\xc0\xb8\x17\x6d\x74\xbd\x9a\xdf"
+			  "\xa4\x37\x94\x86\xb0\x13\x83\x28"
+			  "\xc9\xa2\x07\x3f\xb5\xb2\x72\x40"
+			  "\x0e\x60\xdf\x57\x07\xb7\x2c\x66"
+			  "\x10\x3f\x8d\xdd\x30\x0a\x47\xd5"
+			  "\xe8\x9d\xfb\xa1\xaf\x53\xd7\x05"
+			  "\xc7\xd2\xba\xe7\x2c\xa0\xbf\xb8"
+			  "\xd1\x93\xe7\x41\x82\xa3\x41\x3a"
+			  "\xaf\x12\xd6\xf8\x34\xda\x92\x46"
+			  "\xad\xa2\x2f\xf6\x7e\x46\x96\xd8"
+			  "\x03\xf3\x49\x64\xde\xd8\x06\x8b"
+			  "\xa0\xbc\x63\x35\x38\xb6\x6b\xda"
+			  "\x5b\x50\x3f\x13\xa5\x84\x1b\x1b"
+			  "\x66\x89\x95\xb7\xc2\x16\x3c\xe9"
+			  "\x24\xb0\x8c\x6f\x49\xef\xf7\x28"
+			  "\x6a\x24\xfd\xbe\x25\xe2\xb4\x90"
+			  "\x77\x44\x08\xb8\xda\xd2\xde\x2c"
+			  "\xa0\x57\x45\x57\x29\x47\x6b\x89"
+			  "\x4a\xf6\xa7\x2a\xc3\x9e\x7b\xc8"
+			  "\xfd\x9f\x89\xab\xee\x6d\xa3\xb4"
+			  "\x23\x90\x7a\xe9\x89\xa0\xc7\xb3"
+			  "\x17\x41\x87\x91\xfc\x97\x42",
+		.ctext	= "\xfc\x9b\x96\x66\xc4\x82\x2a\x4a"
+			  "\xb1\x24\xba\xc7\x78\x5f\x79\xc1"
+			  "\x57\x2e\x47\x29\x4d\x7b\xd2\x9a"
+			  "\xbd\xc6\xc1\x26\x7b\x8e\x3f\x5d"
+			  "\xd4\xb4\x9f\x6a\x02\x24\x4a\xad"
+			  "\x0c\x00\x1b\xdf\x92\xc5\x8a\xe1"
+			  "\x77\x79\xcc\xd5\x20\xbf\x83\xf4"
+			  "\x4b\xad\x11\xbf\xdb\x47\x65\x70"
+			  "\x43\xf3\x65\xdf\xb7\xdc\xb2\xb9"
+			  "\xaa\x3f\xb3\xdf\x79\x69\x0d\xa0"
+			  "\x86\x1c\xba\x48\x0b\x01\xc1\x88"
+			  "\xdf\x03\xb1\x06\x3c\x1d\x56\xa1"
+			  "\x8e\x98\xc1\xa6\x95\xa2\x5b\x72"
+			  "\x76\x59\xd2\x26\x25\xcd\xef\x7c"
+			  "\xc9\x60\xea\x43\xd1\x12\x8a\x8a"
+			  "\x63\x12\x78\xcb\x2f\x88\x1e\x88"
+			  "\x78\x59\xde\xba\x4d\x2c\x78\x61"
+			  "\x75\x37\x54\xfd\x80\xc7\x5e\x98"
+			  "\xcf\x14\x62\x8e\xfb\x72\xee\x4d"
+			  "\x9f\xaf\x8b\x09\xe5\x21\x0a\x91"
+			  "\x8f\x88\x87\xd5\xb1\x84\xab\x18"
+			  "\x08\x57\xed\x72\x35\xa6\x0e\xc6"
+			  "\xff\xcb\xfe\x2c\x48\x39\x14\x44"
+			  "\xba\x59\x32\x3a\x2d\xc4\x5f\xcb"
+			  "\xbe\x68\x8e\x7b\xee\x21\xa4\x32"
+			  "\x11\xa0\x99\xfd\x90\xde\x59\x43"
+			  "\xeb\xed\xd5\x87\x68\x46\xc6\xde"
+			  "\x0b\x07\x17\x59\x6a\xab\xca\x15"
+			  "\x65\x02\x01\xb6\x71\x8c\x3b\xaa"
+			  "\x18\x3b\x30\xae\x38\x5b\x2c\x74"
+			  "\xd4\xee\x4a\xfc\xf7\x1b\x09\xd4"
+			  "\xda\x8b\x1d\x5d\x6f\x21\x6c",
+		.klen	= 16,
+		.len	= 255,
+	},
+	{
+		.key	= "\x9f\xd3\xd5\x1a\x0e\xba\x32\x0a"
+			  "\x1d\xa5\xd1\x14\x16\x58\xcd\xdd",
+		.iv	= "\x10\x52\x8d\x53\x3f\x54\x11\x01"
+			  "\x19\x3b\xd8\xa5\xe8\x38\x77\x3e"
+			  "\xd4\x58\xff\x0a\x13\xd2\x09\xe4"
+			  "\x77\x38\x28\x46\xf9\x16\xd3\xfc",
+		.ptext	= "\x5d\x3f\x4a\xa1\x16\x9a\x3c\xdf"
+			  "\xd8\x21\x51\xdc\xb7\x3c\x12\xda"
+			  "\xd1\xe1\xba\x38\xf1\xc1\x9c\x84"
+			  "\xc7\x48\xe1\xd5\xed\x84\x3b\xcd"
+			  "\xc7\x1b\xe1\x5d\x1b\xa5\x79\x3c"
+			  "\xe3\x7e\xab\xf7\xac\x71\x49\x1d"
+			  "\x25\x2b\x8f\x40\xe8\x89\x45\x67"
+			  "\x39\x33\xd3\x27\xd5\xff\x16\xb5"
+			  "\x46\x0f\x37\x05\x14\x87\xa7\xc2"
+			  "\x35\x7f\x66\x98\x48\x5c\x1a\x05"
+			  "\x6c\x0a\xd8\xe4\x28\x1e\x99\x6e"
+			  "\x84\x6c\x13\x07\xc8\x23\xcd\x22"
+			  "\x80\xb8\xc7\x9e\xbe\xcb\xed\x0b"
+			  "\xfa\x9d\xf5\x4b\x4f\x0c\x6e\x4e"
+			  "\x1b\xec\x8c\xb1\x9b\x64\xaa\x65"
+			  "\x5e\x91\x45\xda\x87\x14\x89\x43"
+			  "\x61\xb8\xc7\x68\xc6\xe0\x53\x0a"
+			  "\x71\xef\xac\xc2\xb2\x41\xd9\x4e"
+			  "\x41\xf8\xb3\xee\x2f\x59\xff\x05"
+			  "\x91\x77\x34\xe1\xb2\x1c\x46\x95"
+			  "\xf2\xea\x2a\x15\x70\x97\xa3\x7f"
+			  "\xc3\x68\x23\x73\xd4\x86\xf7\xe0"
+			  "\xc6\x6a\xbd\x70\x63\x0a\x5e\xe2"
+			  "\xba\xe6\x7c\x18\x71\xc4\x1d\x07"
+			  "\x40\xb0\x18\xd7\x52\xc1\x9e\x4e"
+			  "\x8a\x3a\x75\xc3\xf5\xf1\xf9\x8e"
+			  "\x00\x0e\x4f\x7f\x17\x16\x38\x73"
+			  "\xf6\x91\x29\x2a\xcb\xf8\xee\x1a"
+			  "\xf8\x09\x75\x0a\xaf\xb1\x47\x7c"
+			  "\xcf\xca\xd3\xbd\x28\x8b\xa6\xe5"
+			  "\x33\xd1\x63\xea\x89\x1d\xa3\x63"
+			  "\x9d\x1f\xb2\xc6\x02\x50\x1b",
+		.ctext	= "\xd3\x8c\xee\xa6\x45\x11\xaf\x8a"
+			  "\x21\x75\x1f\x84\x1d\x6f\x3f\xbe"
+			  "\xc6\x07\xdd\x64\x6c\x99\x9b\x8b"
+			  "\xfa\xef\x41\xf2\xe1\x04\xe2\x0a"
+			  "\x12\x88\x96\x98\x74\xd4\x6c\x5d"
+			  "\x6b\xf4\x8b\xfc\x87\x5f\x4b\x70"
+			  "\x29\x07\x13\x49\xad\x52\x3e\xa7"
+			  "\x88\x20\x8a\xdd\x5d\xe9\x2d\x86"
+			  "\x5c\x1e\x33\x82\x07\xe9\x04\xa4"
+			  "\x72\xbd\xa8\xb3\x67\x2e\xc0\x80"
+			  "\xea\x9d\x44\x55\x36\xca\xb6\xb4"
+			  "\x0d\x5e\xaf\x87\x63\x45\x65\xd8"
+			  "\x90\x58\xc3\xec\x27\x5a\x7f\x25"
+			  "\x1b\x14\x08\x2b\xed\x14\xe2\x80"
+			  "\x53\xc2\xed\xbf\x88\xf3\x74\x8d"
+			  "\x79\x99\x9e\x7f\x18\x2b\x1f\x70"
+			  "\x09\x46\x88\x41\x1b\xce\xc5\x69"
+			  "\xd8\xc8\x83\xfa\x32\xd8\xb7\xab"
+			  "\x87\xae\xda\x36\xc1\x75\xba\xf5"
+			  "\xd3\x22\xcc\x0a\x20\x62\x37\xfd"
+			  "\xc1\xe1\x6c\xc6\xac\x4b\x1e\x34"
+			  "\x4f\xbe\x09\xea\xb1\xd3\x30\xa6"
+			  "\xf1\xd8\x51\x0f\x83\xf7\x36\x83"
+			  "\x17\x23\x25\x6c\xb4\x5f\x4f\x76"
+			  "\xde\x0a\x09\x54\xf3\xd2\xca\x52"
+			  "\xc2\xec\x6a\x9c\x0a\xa0\x59\x8e"
+			  "\xbe\x09\x02\x83\xcf\x4e\xe3\x59"
+			  "\x6d\xff\x45\x49\x1f\xa7\x32\x67"
+			  "\x1d\xb4\xdf\x60\xb9\x30\xd4\x64"
+			  "\xfc\x47\xf7\xe7\xfa\x94\x23\x60"
+			  "\xd5\x47\xe4\x4e\x61\x45\x7e\x48"
+			  "\xd3\xad\xad\x97\x61\x1c\x32",
+		.klen	= 16,
+		.len	= 255,
+	},
+	{
+		.key	= "\xea\x2f\x51\x6f\x31\xe9\x2f\x7b"
+			  "\x68\xc8\x1a\xd5\xfa\x9c\xe1\x40"
+			  "\x95\xe9\x47\xcb\xa1\x9a\xf7\xee",
+		.iv	= "\xe6\x77\x52\x55\x9c\xa7\xc1\x91"
+			  "\x02\xa7\x32\x87\x76\x91\x72\x2e"
+			  "\xf3\xa4\x84\x33\xe8\xa5\xa3\x57"
+			  "\x42\x5d\xd5\x6c\xaa\xf1\xfd\x53",
+		.ptext	= "\x22\xd0\xff\xba\xad\x43\xaf\x63"
+			  "\x0e\xb1\x0c\x60\x0f\x64\x92\x5a",
+		.ctext	= "\x21\x85\xb9\xb8\xdf\x5e\x8b\x70"
+			  "\xfe\x79\xc0\x5d\x9d\x89\x30\xdc",
+		.klen	= 24,
+		.len	= 16,
+	},
+	{
+		.key	= "\x44\x18\xc4\xb2\x25\xe5\xa6\x90"
+			  "\x7a\x12\x8c\x35\x6a\x98\x44\x3c"
+			  "\x4b\x67\x18\x24\x34\xce\x30\x7e",
+		.iv	= "\x8e\xf9\x6d\xf5\x52\x06\xb5\x07"
+			  "\xd1\x13\xfe\x36\x87\xee\x6e\x13"
+			  "\xea\xde\x54\xaf\x49\xc6\x4f\xce"
+			  "\xe1\x86\x8e\xcd\x22\x12\xde\x39",
+		.ptext	= "\x34\x14\x8d\x92\xa6\x83\xd5\x87"
+			  "\x89\xfd\xf7\xb1\x8f\x93\x0b\x1c",
+		.ctext	= "\x4f\xdd\xc7\x22\x85\x33\x9d\x34"
+			  "\xc8\x9b\x88\xfd\x8f\x40\xab\x42",
+		.klen	= 24,
+		.len	= 16,
+	},
+	{
+		.key	= "\x24\xf6\xe1\x62\xe5\xaf\x99\xda"
+			  "\x84\xec\x41\xb0\xa3\x0b\xd5\xa8"
+			  "\xa0\x3e\x7b\xa6\xdd\x6c\x8f\xa8",
+		.iv	= "\x7f\x80\x24\x62\x32\xdd\xab\x66"
+			  "\xf2\x87\x29\x24\xec\xd2\x4b\x9f"
+			  "\x0c\x33\x52\xd9\xe0\xcc\x6e\xe4"
+			  "\x90\x85\x43\x97\xc4\x62\x14\x33",
+		.ptext	= "\xef\x58\xe7\x7f\xa9\xd9\xb8\xd7"
+			  "\xa2\x91\x97\x07\x27\x9e\xba\xe8"
+			  "\xaa",
+		.ctext	= "\xd7\xc3\x81\x91\xf2\x40\x17\x73"
+			  "\x3e\x3b\x1c\x2a\x8e\x11\x9c\x17"
+			  "\xf1",
+		.klen	= 24,
+		.len	= 17,
+	},
+	{
+		.key	= "\xa6\xc2\x58\x49\x28\x50\x8c\x88"
+			  "\x84\x9c\xb1\x70\x18\x99\x9c\x0d"
+			  "\x08\x60\x4f\xb1\xcf\x90\x66\x72",
+		.iv	= "\x80\x14\x7f\x97\x64\x17\x55\xef"
+			  "\x4b\x1b\xce\x2b\x09\x20\x5a\xed"
+			  "\x96\xdc\xa6\x6e\xb0\x59\x54\x00"
+			  "\x1d\x26\x3d\x96\xc2\x3e\x73\x05",
+		.ptext	= "\x49\x8b\x90\x34\x41\x63\xc6\x9a"
+			  "\x07\xe0\x9d\x86\x77\x54\x63\x6d"
+			  "\x6a",
+		.ctext	= "\xcb\x94\xfa\xc3\xeb\xf8\x37\xfe"
+			  "\x15\x76\x03\xd9\x67\xe4\x90\x28"
+			  "\x0c",
+		.klen	= 24,
+		.len	= 17,
+	},
+	{
+		.key	= "\xbf\xaf\xd7\x67\x8c\x47\xcf\x21"
+			  "\x8a\xa5\xdd\x32\x25\x47\xbe\x4f"
+			  "\xf1\x3a\x0b\xa6\xaa\x2d\xcf\x09",
+		.iv	= "\xd9\xe8\xf0\x92\x4e\xfc\x1d\xf2"
+			  "\x81\x37\x7c\x8f\xf1\x59\x09\x20"
+			  "\xf4\x46\x51\x86\x4f\x54\x8b\x32"
+			  "\x58\xd1\x99\x8b\x8c\x03\xeb\x5d",
+		.ptext	= "\xcd\x64\x90\xf9\x7c\xe5\x0e\x5a"
+			  "\x75\xe7\x8e\x39\x86\xec\x20\x43"
+			  "\x8a\x49\x09\x15\x47\xf4\x3c\x89"
+			  "\x21\xeb\xcf\x4e\xcf\x91\xb5\x40"
+			  "\xcd\xe5\x4d\x5c\x6f\xf2\xd2\x80"
+			  "\xfa\xab\xb3\x76\x9f\x7f\x84\x0a",
+		.ctext	= "\x44\x98\x64\x15\xb7\x0b\x80\xa3"
+			  "\xb9\xca\x23\xff\x3b\x0b\x68\x74"
+			  "\xbb\x3e\x20\x19\x9f\x28\x71\x2a"
+			  "\x48\x3c\x7c\xe2\xef\xb5\x10\xac"
+			  "\x82\x9f\xcd\x08\x8f\x6b\x16\x6f"
+			  "\xc3\xbb\x07\xfb\x3c\xb0\x1b\x27",
+		.klen	= 24,
+		.len	= 48,
+	},
+	{
+		.key	= "\xbe\xbb\x77\x46\x06\x9c\xf4\x4d"
+			  "\x37\x9a\xe6\x3f\x27\xa7\x3b\x6e"
+			  "\x7a\x36\xb8\xb3\xff\xba\x51\xcc",
+		.iv	= "\x06\xbc\x8f\x66\x6a\xbe\xed\x5e"
+			  "\x51\xf2\x72\x11\x3a\x56\x85\x21"
+			  "\x44\xfe\xec\x47\x2b\x09\xb8\x6f"
+			  "\x08\x85\x2a\x93\xa3\xc3\xab\x5e",
+		.ptext	= "\xc7\x74\x42\xf1\xea\xc5\x37\x2d"
+			  "\xc2\xa0\xf6\xd5\x5a\x9a\xbb\xa0"
+			  "\xb2\xfd\x54\x8e\x98\xa0\xea\xc7"
+			  "\x79\x09\x65\x63\xa0\x2e\x82\x4e"
+			  "\x49\x9c\x39\x67\xd0\x0d\x80\x3e"
+			  "\x1a\x86\x84\x2b\x20\x23\xdf\xa7",
+		.ctext	= "\x5f\xa3\x11\xca\x93\xfa\x24\x3a"
+			  "\x24\xb6\xcf\x1e\x76\xbc\xab\xc4"
+			  "\xf3\x24\xa0\x27\xac\x90\xec\xe9"
+			  "\x73\x28\x7d\x35\x67\xfe\x2e\xa8"
+			  "\x89\x77\xac\xeb\xc3\x68\x36\xf4"
+			  "\x8f\x80\x2c\xf1\x80\xef\x49\x49",
+		.klen	= 24,
+		.len	= 48,
+	},
+	{
+		.key	= "\x76\xe4\x8f\xf0\x60\x7b\xe4\x0d"
+			  "\xb9\x06\xfa\x90\x38\x55\x0a\x98"
+			  "\xaa\x7d\x97\xfe\x8d\x77\x39\x9f",
+		.iv	= "\xf7\x2c\x39\x70\xa4\x28\x66\x45"
+			  "\xea\x62\x1b\xdd\xb0\xfa\x6c\x50"
+			  "\xcf\xf7\x4a\x57\xdf\x1e\xa4\xf0"
+			  "\x0f\xf6\x8a\x71\x15\xcf\xa0\x29",
+		.ptext	= "\x9c\x15\x7c\xc0\x70\x49\x65\xac"
+			  "\x95\x67\x37\x40\x8b\x0e\x9d\xa9"
+			  "\x66\x0a\x5e\x32\x58\xa1\x40\x8d"
+			  "\x46\xa2\xbd\x4f\x5a\xb1\x5f\xd5"
+			  "\x9d\x8e\x55\x18\x7e\x43\x43\xa9"
+			  "\x55\x1a\x3f\x50\x51\x7a\xc9\x1b"
+			  "\x2f\xd8\x36\x35\x41\xf3\x3d\x42"
+			  "\x7e\x3e\xd5\x94\x6b\xa7\xa0\xc6"
+			  "\x02\x35\xba\x59\x7a\xc3\xda\xca"
+			  "\xa3\x73\x18\x6a\x57\x2f\xbd\xe8"
+			  "\xc8\x3a\x6c\x07\x0e\xea\x6c\x17"
+			  "\x4f\x3a\xcc\xc3\x70\x89\x99\x23"
+			  "\x78\x38\xd7\x60\x51\x5a\xe5\xec"
+			  "\x19\x98\x5b\x78\x9f\xb8\xb9\x00"
+			  "\x7c\xf8\xab\x23\x59\xf0\x71\xcf"
+			  "\x7f\x06\x11\x55\x85\x94\xe5\x50"
+			  "\x0d\x01\x93\xcb\xde\x58\x90\x00"
+			  "\xc5\x34\x7e\xda\x26\xbf\x58\x15"
+			  "\x80\x33\x34\x56\x86\xaa\xc8\x6e"
+			  "\x2b\x47\x98\xb6\xc9\x1c\xa4\xb6"
+			  "\xac\xf1\x76\xfe\x33\x57\x2d\xad"
+			  "\x42\x15\x34\xba\x71\x96\xfe\x0e"
+			  "\xba\xee\x68\x36\x3a\xe0\xe7\xc7"
+			  "\x3e\x6d\x54\xda\x77\x04\x26\x2c"
+			  "\xc1\x45\x16\xd9\xdd\x89\xd3\xf1"
+			  "\xcc\xfc\x19\x44\x6c\x99\xb2\x44"
+			  "\x1f\x89\x34\x21\xb1\x8d\x02\x5c"
+			  "\x76\x1e\x27\x84\xf9\xd4\xa3\x03"
+			  "\x1d\x26\xc1\x39\xb6\x67\x6c\xad"
+			  "\xb5\x69\x6b\x54\x65\xf6\x9c\xcf"
+			  "\xaf\x00\x12\x87\x21\x2f\x68\xcb"
+			  "\xd2\x76\xc1\x43\xce\x24\xc2",
+		.ctext	= "\x40\xff\x83\x8e\xef\x98\xa1\xcb"
+			  "\x57\x3f\xb6\xf3\x26\x99\x96\xe2"
+			  "\xd0\x68\x80\x32\x2c\x58\x9a\xd6"
+			  "\x24\xd0\x21\x17\xc0\x6e\x44\xb6"
+			  "\xa7\xa0\xdd\xde\xce\x18\x5a\x17"
+			  "\xf2\xc1\x98\xab\x61\xcd\x70\x0a"
+			  "\x4d\xef\x9f\xa6\x9d\x8b\x45\x81"
+			  "\x23\x90\x65\xe0\x45\x2c\x74\xc5"
+			  "\x7d\xe8\x43\xec\x5a\xfa\x54\x64"
+			  "\x6f\xfc\x4b\x6c\x83\xec\x1d\xbc"
+			  "\x39\x19\x2f\xa7\xe6\x46\x5a\x4e"
+			  "\x17\x6d\x0b\xf2\x7a\x14\x0c\x50"
+			  "\x8e\x83\x00\xb7\xbb\x65\x77\xfd"
+			  "\x72\xb3\xea\xe4\xde\x54\xd6\xc0"
+			  "\x8c\x02\xb2\xdb\xc3\xe6\x46\xd5"
+			  "\xfb\xb4\x03\x29\xdc\xa4\x64\xe3"
+			  "\xe8\x20\xb5\x4d\x81\x44\x20\xc8"
+			  "\x29\x41\xce\x05\x3a\xd6\xe3\x0e"
+			  "\x0b\xea\xdf\x50\xea\x91\xaa\x9b"
+			  "\xc4\x9c\x09\x4a\x42\xfa\xef\x38"
+			  "\x3b\xdf\xfb\x5b\x95\xa2\x9a\xbd"
+			  "\x10\x55\x61\x4a\xee\x8b\xda\x1f"
+			  "\x23\x69\xce\x6e\x92\x64\x3e\x32"
+			  "\x4d\x80\x23\xf1\x43\xd7\x01\x54"
+			  "\x6f\x18\x4c\x53\x91\xd5\xaa\xeb"
+			  "\x17\x73\x92\x7f\x10\x7b\x57\x02"
+			  "\x8e\x6f\xce\x63\x83\x6b\x12\xba"
+			  "\xbc\x23\xcb\x95\x3a\x1f\x16\xe5"
+			  "\x21\xf7\x52\x17\x43\x28\x52\xaf"
+			  "\x2e\x6f\x7f\x36\xe6\x0c\x31\x90"
+			  "\x57\xf7\x5f\x7c\x06\x3e\x47\x5f"
+			  "\xb8\xc4\x2a\xeb\xd7\x91\xf1",
+		.klen	= 24,
+		.len	= 255,
+	},
+	{
+		.key	= "\x87\x2b\xdd\x36\x2a\x76\x60\xce"
+			  "\xfb\x54\xa7\x5a\x3f\x40\xcd\x10"
+			  "\xc8\x88\x0e\xd8\x83\x31\xd5\x5e",
+		.iv	= "\x3b\x6c\x32\xde\x9c\x02\xb6\xa1"
+			  "\x13\xfe\x8d\x4a\x8d\xf8\x15\x8d"
+			  "\x0b\x2c\x14\x1c\x44\xd4\x1f\x7e"
+			  "\xcc\x33\xf0\x03\xa3\x41\x3e\x6d",
+		.ptext	= "\x6a\x0c\x6b\x8b\x44\x75\x77\x0b"
+			  "\x7d\x9f\xca\x35\x27\x36\xbf\xe3"
+			  "\xc2\x09\x3e\x6e\x42\xd4\x81\xc2"
+			  "\x4a\xd5\xa3\x00\x5d\x2b\x97\x0a"
+			  "\xe0\xd9\x8b\x10\x79\x74\xf4\x5f"
+			  "\xef\xf0\xc7\x3b\xbc\xbe\x69\xe4"
+			  "\x0f\xb8\xa2\x39\x15\x70\x3a\xa6"
+			  "\x20\x86\x8b\x3c\x6e\xca\xfc\x36"
+			  "\xea\x32\x5f\xa6\x17\x2b\xd3\x24"
+			  "\x65\x69\x9c\x13\x5c\x56\xb6\x14"
+			  "\x3a\x8f\x21\x40\xde\x23\x6f\x8b"
+			  "\x2f\xa8\xa4\x81\x91\xb6\xbe\x7c"
+			  "\x12\x25\x7c\x87\xb8\x74\x6a\xa7"
+			  "\x8d\xa5\xb9\x8c\xb4\xa9\xd2\x6a"
+			  "\xb2\xb3\x6e\x8b\x40\x9f\xf2\x38"
+			  "\xd8\x26\xf1\xfa\x6f\xb9\x29\xfe"
+			  "\x0f\xc1\x4d\x90\xf8\x49\xe1\x72"
+			  "\x70\x63\x35\xdc\xfe\xb4\x72\x06"
+			  "\xae\x7e\xbe\x36\x23\xa2\x4a\x03"
+			  "\x6c\xa8\xa0\x7a\x5c\x44\x60\xc4"
+			  "\x2b\x50\xa1\x19\xa4\x35\xfc\x00"
+			  "\xd1\x0a\x8f\x9c\x54\x5b\xdc\x53"
+			  "\x68\x7b\x7b\x1e\xd0\x8e\xd0\x93"
+			  "\x8f\xaf\xf5\xa2\x40\xe1\x15\x33"
+			  "\x49\x41\xaa\x57\xf3\x13\x1b\xa5"
+			  "\x8a\xab\x01\x2b\x28\xec\x63\x81"
+			  "\x34\x77\xf1\x3f\xc2\x47\x09\x31"
+			  "\xc2\x80\x1c\xa9\x16\x6b\xa5\x0a"
+			  "\x1c\xbe\x23\x0c\x41\x63\xd6\x92"
+			  "\x7f\x3a\x74\x71\x86\x5e\x30\xc1"
+			  "\xc5\xee\x5b\x41\x9a\xed\x43\xab"
+			  "\x10\x40\xc4\xe6\xf3\xaa\xc2",
+		.ctext	= "\x45\x61\x53\x5c\x56\x08\xc2\x78"
+			  "\x01\x23\x8d\x9d\x8e\xeb\xca\xcd"
+			  "\xf5\x1f\x01\x3f\xba\x9d\xea\x87"
+			  "\xca\x23\xc5\xa8\xb2\x92\x87\x0d"
+			  "\x62\x8c\x72\x9c\xe8\xa5\x3f\x75"
+			  "\xda\xa4\xd5\x92\x6f\xae\x4e\xeb"
+			  "\xfd\x21\xe6\xa9\x7e\xbf\xed\x85"
+			  "\xbd\x8c\x88\x18\xa8\x79\xd0\x09"
+			  "\x5b\x6b\x96\x32\x63\x1a\x6e\x27"
+			  "\x72\xa3\x7a\xc4\x48\xf3\xed\x04"
+			  "\x5d\xc7\x01\x23\x7c\x36\x57\x57"
+			  "\xf4\x45\xf6\xf6\xc7\x9a\xb2\x2f"
+			  "\x88\x79\xac\xaf\xfd\x52\xa7\x96"
+			  "\x83\x65\x5d\x6b\xa2\x3b\x2b\x17"
+			  "\x6c\xa7\xe3\x03\x2e\x6b\xa5\x80"
+			  "\x32\x0b\x7c\x86\x38\x64\x24\x64"
+			  "\x51\x61\xca\xa8\xdc\x67\x6a\x17"
+			  "\x96\xc8\xbd\xd0\x0f\x99\x78\x75"
+			  "\xbb\x81\xc8\x35\xc1\x5c\x48\x66"
+			  "\x75\x8a\xed\x44\x57\x10\xc9\xd8"
+			  "\x85\x91\xaf\x2b\xdd\xc0\xfc\x7f"
+			  "\x19\x9d\x22\x8f\x94\xe7\xb0\x86"
+			  "\x34\x17\xd3\xe1\x10\x2a\x30\x3a"
+			  "\x4d\x5b\xab\x99\xf5\xf8\x21\x78"
+			  "\x9d\x1b\xba\x1f\xb9\x18\x20\xfa"
+			  "\x12\x09\x65\xb0\x2c\xf0\x0c\x11"
+			  "\x4d\x91\xb0\xa0\x24\xb0\xf8\x61"
+			  "\xe0\x65\xc1\x21\x72\x98\xbc\x29"
+			  "\x92\x85\x2c\xfc\xa1\x0c\xa0\x04"
+			  "\x6d\x21\x3d\x40\x62\xda\x55\x71"
+			  "\xee\xa1\x1e\x5e\xc3\x42\x0b\xa0"
+			  "\x4b\xe5\xbd\x95\xa9\xdf\x70",
+		.klen	= 24,
+		.len	= 255,
+	},
+	{
+		.key	= "\x9e\xeb\xb2\x49\x3c\x1c\xf5\xf4"
+			  "\x6a\x99\xc2\xc4\xdf\xb1\xf4\xdd"
+			  "\x75\x20\x57\xea\x2c\x4f\xcd\xb2"
+			  "\xa5\x3d\x7b\x49\x1e\xab\xfd\x0f",
+		.iv	= "\xdf\x63\xd4\xab\xd2\x49\xf3\xd8"
+			  "\x33\x81\x37\x60\x7d\xfa\x73\x08"
+			  "\xd8\x49\x6d\x80\xe8\x2f\x62\x54"
+			  "\xeb\x0e\xa9\x39\x5b\x45\x7f\x8a",
+		.ptext	= "\x67\xc9\xf2\x30\x84\x41\x8e\x43"
+			  "\xfb\xf3\xb3\x3e\x79\x36\x7f\xe8",
+		.ctext	= "\x27\x38\x78\x47\x16\xd9\x71\x35"
+			  "\x2e\x7e\xdd\x7e\x43\x3c\xb8\x40",
+		.klen	= 32,
+		.len	= 16,
+	},
+	{
+		.key	= "\x50\x4a\xc8\x94\x01\x13\xd3\x0c"
+			  "\xd9\xaa\xf3\x4c\xf8\x3f\x2c\x39"
+			  "\x9e\xec\xc6\xa8\x97\xf2\x8e\x73"
+			  "\x94\xb8\x4c\x40\x03\x28\xaf\xc2",
+		.iv	= "\x9e\xaa\x0b\x7f\x12\x2a\xe3\xdf"
+			  "\x05\x03\x93\x1b\xda\xc8\xd7\x98"
+			  "\x8a\xf9\xdf\x63\xb1\xcd\x15\xaa"
+			  "\x02\x8e\x41\xa0\x75\x1d\x17\x0e",
+		.ptext	= "\xe2\x8a\x35\xa7\x10\x0d\x65\x6e"
+			  "\xad\x77\xce\x07\xbb\x67\x83\x03",
+		.ctext	= "\x81\xc1\x1c\x06\x73\xcb\xc1\xe6"
+			  "\xed\x1f\x5b\xf0\x7d\x8b\x12\xf8",
+		.klen	= 32,
+		.len	= 16,
+	},
+	{
+		.key	= "\x93\xfa\x7e\xe2\x0e\x67\xc4\x39"
+			  "\xe7\xca\x47\x95\x68\x9d\x5e\x5a"
+			  "\x7c\x26\x19\xab\xc6\xca\x6a\x4c"
+			  "\x45\xa6\x96\x42\xae\x6c\xff\xe7",
+		.iv	= "\xea\x82\x47\x95\x3b\x22\xa1\x3a"
+			  "\x6a\xca\x24\x4c\x50\x7e\x23\xcd"
+			  "\x0e\x50\xe5\x41\xb6\x65\x29\xd8"
+			  "\x30\x23\x00\xd2\x54\xa7\xd6\x56",
+		.ptext	= "\xdb\x1f\x1f\xec\xad\x83\x6e\x5d"
+			  "\x19\xa5\xf6\x3b\xb4\x93\x5a\x57"
+			  "\x6f",
+		.ctext	= "\xf1\x46\x6e\x9d\xb3\x01\xf0\x6b"
+			  "\xc2\xac\x57\x88\x48\x6d\x40\x72"
+			  "\x68",
+		.klen	= 32,
+		.len	= 17,
+	},
+	{
+		.key	= "\xbe\xa5\x63\xe5\x3d\xa6\xdd\x83"
+			  "\x12\x4e\x52\x3e\xb7\x47\x13\xc0"
+			  "\x98\x57\x14\x8c\xe9\xbe\x0d\xb4"
+			  "\xa7\x82\x0e\x99\x82\x94\x0f\x60",
+		.iv	= "\x36\xdf\x56\x4d\xcf\x6a\xd2\xf4"
+			  "\x35\x92\x3d\xd2\x31\x24\xf8\xa6"
+			  "\x27\x27\xe4\x55\xe2\xe0\xc3\xb5"
+			  "\xe7\x40\x31\xae\x98\xab\xab\x93",
+		.ptext	= "\xf4\x54\x01\xb5\x11\xe3\xed\x8d"
+			  "\xa4\xf0\xf7\x3f\xc8\x4b\xac\x7a"
+			  "\xb9",
+		.ctext	= "\xa7\xb5\xa4\xaa\x6b\x56\xdb\x79"
+			  "\x30\xa1\x6e\xfe\xa2\x60\xcb\xb3"
+			  "\x10",
+		.klen	= 32,
+		.len	= 17,
+	},
+	{
+		.key	= "\x03\x65\x03\x6e\x4d\xe6\xe8\x4e"
+			  "\x8b\xbe\x22\x19\x48\x31\xee\xd9"
+			  "\xa0\x91\x21\xbe\x62\x89\xde\x78"
+			  "\xd9\xb0\x36\xa3\x3c\xce\x43\xd5",
+		.iv	= "\xa9\xc3\x4b\xe7\x0f\xfc\x6d\xbf"
+			  "\x56\x27\x21\x1c\xfc\xd6\x04\x10"
+			  "\x5f\x43\xe2\x30\x35\x29\x6c\x10"
+			  "\x90\xf1\xbf\x61\xed\x0f\x8a\x91",
+		.ptext	= "\x07\xaa\x02\x26\xb4\x98\x11\x5e"
+			  "\x33\x41\x21\x51\x51\x63\x2c\x72"
+			  "\x00\xab\x32\xa7\x1c\xc8\x3c\x9c"
+			  "\x25\x0e\x8b\x9a\xdf\x85\xed\x2d"
+			  "\xf4\xf2\xbc\x55\xca\x92\x6d\x22"
+			  "\xfd\x22\x3b\x42\x4c\x0b\x74\xec",
+		.ctext	= "\x7b\xb1\x43\x6d\xd8\x72\x6c\xf6"
+			  "\x67\x6a\x00\xc4\xf1\xf0\xf5\xa4"
+			  "\xfc\x60\x91\xab\x46\x0b\x15\xfc"
+			  "\xd7\xc1\x28\x15\xa1\xfc\xf7\x68"
+			  "\x8e\xcc\x27\x62\x00\x64\x56\x72"
+			  "\xa6\x17\xd7\x3f\x67\x80\x10\x58",
+		.klen	= 32,
+		.len	= 48,
+	},
+	{
+		.key	= "\x93\x14\x30\x98\x95\xda\xad\xeb"
+			  "\xb8\x22\xb5\x98\x57\x7c\xfa\x14"
+			  "\x88\x8a\x70\x76\x09\x7d\x03\xb7"
+			  "\xf9\x1d\x5d\x30\x1f\x24\xb2\xce",
+		.iv	= "\x47\xb7\x08\xb9\xc1\xf5\x12\x57"
+			  "\x68\x4d\x74\x71\xc3\x0b\x05\xc5"
+			  "\x8d\x00\x48\x9d\x3a\xfc\x85\x05"
+			  "\x49\x82\x96\x95\x09\x1a\x17\x27",
+		.ptext	= "\x3f\xf5\x2c\x26\x53\x6c\xdc\x88"
+			  "\x5e\xf3\x2e\x0d\x22\xe4\xef\x4e"
+			  "\xad\xaf\xe5\xf7\x5c\xd3\x84\x0e"
+			  "\xe1\xbb\x19\x0a\xcf\x1e\xb6\xf3"
+			  "\x53\xf3\x25\xa2\x66\x7a\xd2\x97"
+			  "\x58\x39\x7a\xd6\x4b\x7f\x31\x76",
+		.ctext	= "\x75\x16\xb1\x9a\xa9\x9d\x12\x78"
+			  "\x5a\xd1\x36\xc5\x11\x4c\x1a\xc5"
+			  "\x9b\x21\x12\x0b\xef\x13\xbc\xd0"
+			  "\x31\x03\xcc\xd9\xf5\x59\x23\xb6"
+			  "\x70\xaf\xc2\x84\x57\x5c\xad\xc7"
+			  "\x89\x6a\xf4\x39\x14\x7e\x0d\x0d",
+		.klen	= 32,
+		.len	= 48,
+	},
+	{
+		.key	= "\x36\x45\x11\xa2\x98\x5f\x96\x7c"
+			  "\xc6\xb4\x94\x31\x0a\x67\x09\x32"
+			  "\x6c\x6f\x6f\x00\xf0\x17\xcb\xac"
+			  "\xa5\xa9\x47\x9e\x2e\x85\x2f\xfa",
+		.iv	= "\x28\x88\xaa\x9b\x59\x3b\x1e\x97"
+			  "\x82\xe5\x5c\x9e\x6d\x14\x11\x19"
+			  "\x6e\x38\x8f\xd5\x40\x2b\xca\xf9"
+			  "\x7b\x4c\xe4\xa3\xd0\xd2\x8a\x13",
+		.ptext	= "\x95\xd2\xf7\x71\x1b\xca\xa5\x86"
+			  "\xd9\x48\x01\x93\x2f\x79\x55\x29"
+			  "\x71\x13\x15\x0e\xe6\x12\xbc\x4d"
+			  "\x8a\x31\xe3\x40\x2a\xc6\x5e\x0d"
+			  "\x68\xbb\x4a\x62\x8d\xc7\x45\x77"
+			  "\xd2\xb8\xc7\x1d\xf1\xd2\x5d\x97"
+			  "\xcf\xac\x52\xe5\x32\x77\xb6\xda"
+			  "\x30\x85\xcf\x2b\x98\xe9\xaa\x34"
+			  "\x62\xb5\x23\x9e\xb7\xa6\xd4\xe0"
+			  "\xb4\x58\x18\x8c\x4d\xde\x4d\x01"
+			  "\x83\x89\x24\xca\xfb\x11\xd4\x82"
+			  "\x30\x7a\x81\x35\xa0\xb4\xd4\xb6"
+			  "\x84\xea\x47\x91\x8c\x19\x86\x25"
+			  "\xa6\x06\x8d\x78\xe6\xed\x87\xeb"
+			  "\xda\xea\x73\x7c\xbf\x66\xb8\x72"
+			  "\xe3\x0a\xb8\x0c\xcb\x1a\x73\xf1"
+			  "\xa7\xca\x0a\xde\x57\x2b\xbd\x2b"
+			  "\xeb\x8b\x24\x38\x22\xd3\x0e\x1f"
+			  "\x17\xa0\x84\x98\x31\x77\xfd\x34"
+			  "\x6a\x4e\x3d\x84\x4c\x0e\xfb\xed"
+			  "\xc8\x2a\x51\xfa\xd8\x73\x21\x8a"
+			  "\xdb\xb5\xfe\x1f\xee\xc4\xe8\x65"
+			  "\x54\x84\xdd\x96\x6d\xfd\xd3\x31"
+			  "\x77\x36\x52\x6b\x80\x4f\x9e\xb4"
+			  "\xa2\x55\xbf\x66\x41\x49\x4e\x87"
+			  "\xa7\x0c\xca\xe7\xa5\xc5\xf6\x6f"
+			  "\x27\x56\xe2\x48\x22\xdd\x5f\x59"
+			  "\x3c\xf1\x9f\x83\xe5\x2d\xfb\x71"
+			  "\xad\xd1\xae\x1b\x20\x5c\x47\xb7"
+			  "\x3b\xd3\x14\xce\x81\x42\xb1\x0a"
+			  "\xf0\x49\xfa\xc2\xe7\x86\xbf\xcd"
+			  "\xb0\x95\x9f\x8f\x79\x41\x54",
+		.ctext	= "\xf6\x57\x51\xc4\x25\x61\x2d\xfa"
+			  "\xd6\xd9\x3f\x9a\x81\x51\xdd\x8e"
+			  "\x3d\xe7\xaa\x2d\xb1\xda\xc8\xa6"
+			  "\x9d\xaa\x3c\xab\x62\xf2\x80\xc3"
+			  "\x2c\xe7\x58\x72\x1d\x44\xc5\x28"
+			  "\x7f\xb4\xf9\xbc\x9c\xb2\xab\x8e"
+			  "\xfa\xd1\x4d\x72\xd9\x79\xf5\xa0"
+			  "\x24\x3e\x90\x25\x31\x14\x38\x45"
+			  "\x59\xc8\xf6\xe2\xc6\xf6\xc1\xa7"
+			  "\xb2\xf8\xa7\xa9\x2b\x6f\x12\x3a"
+			  "\xb0\x81\xa4\x08\x57\x59\xb1\x56"
+			  "\x4c\x8f\x18\x55\x33\x5f\xd6\x6a"
+			  "\xc6\xa0\x4b\xd6\x6b\x64\x3e\x9e"
+			  "\xfd\x66\x16\xe2\xdb\xeb\x5f\xb3"
+			  "\x50\x50\x3e\xde\x8d\x72\x76\x01"
+			  "\xbe\xcc\xc9\x52\x09\x2d\x8d\xe7"
+			  "\xd6\xc3\x66\xdb\x36\x08\xd1\x77"
+			  "\xc8\x73\x46\x26\x24\x29\xbf\x68"
+			  "\x2d\x2a\x99\x43\x56\x55\xe4\x93"
+			  "\xaf\xae\x4d\xe7\x55\x4a\xc0\x45"
+			  "\x26\xeb\x3b\x12\x90\x7c\xdc\xd1"
+			  "\xd5\x6f\x0a\xd0\xa9\xd7\x4b\x89"
+			  "\x0b\x07\xd8\x86\xad\xa1\xc4\x69"
+			  "\x1f\x5e\x8b\xc4\x9e\x91\x41\x25"
+			  "\x56\x98\x69\x78\x3a\x9e\xae\x91"
+			  "\xd8\xd9\xfa\xfb\xff\x81\x25\x09"
+			  "\xfc\xed\x2d\x87\xbc\x04\x62\x97"
+			  "\x35\xe1\x26\xc2\x46\x1c\xcf\xd7"
+			  "\x14\xed\x02\x09\xa5\xb2\xb6\xaa"
+			  "\x27\x4e\x61\xb3\x71\x6b\x47\x16"
+			  "\xb7\xe8\xd4\xaf\x52\xeb\x6a\x6b"
+			  "\xdb\x4c\x65\x21\x9e\x1c\x36",
+		.klen	= 32,
+		.len	= 255,
+	},
+	{
+		.key	= "\x56\x33\x37\x21\xc4\xea\x8b\x88"
+			  "\x67\x5e\xee\xb8\x0b\x6c\x04\x43"
+			  "\x17\xc5\x2b\x8a\x37\x17\x8b\x37"
+			  "\x60\x57\x3f\xa7\x82\xcd\xb9\x09",
+		.iv	= "\x88\xee\x9b\x35\x21\x2d\x41\xa1"
+			  "\x16\x0d\x7f\xdf\x57\xc9\xb9\xc3"
+			  "\xf6\x30\x53\xbf\x89\x46\xe6\x87"
+			  "\x60\xc8\x5e\x59\xdd\x8a\x7b\xfe",
+		.ptext	= "\x49\xe2\x0a\x4f\x7a\x60\x75\x9b"
+			  "\x95\x98\x2c\xe7\x4f\xb4\x58\xb9"
+			  "\x24\x54\x46\x34\xdf\x58\x31\xe7"
+			  "\x23\xc6\xa2\x60\x4a\xd2\x59\xb6"
+			  "\xeb\x3e\xc2\xf8\xe5\x14\x3c\x6d"
+			  "\x4b\x72\xcb\x5f\xcb\xa7\x47\xb9"
+			  "\x7a\x49\xfc\xf1\xad\x92\x76\x55"
+			  "\xac\x59\xdc\x3a\xc6\x8b\x7c\xdb"
+			  "\x06\xcd\xea\x6a\x34\x51\xb7\xb2"
+			  "\xe5\x39\x3c\x87\x00\x90\xc2\xbb"
+			  "\xb2\xa5\x2c\x58\xc2\x9b\xe3\x77"
+			  "\x95\x82\x50\xcb\x23\xdc\x18\xd8"
+			  "\x4e\xbb\x13\x5d\x35\x3d\x9a\xda"
+			  "\xe4\x75\xa1\x75\x17\x59\x8c\x6a"
+			  "\xb2\x76\x7e\xd4\x45\x31\x0a\x45"
+			  "\x2e\x60\x83\x3d\xdc\x8d\x43\x20"
+			  "\x58\x24\xb2\x9d\xd5\x59\x64\x32"
+			  "\x4e\x6f\xb9\x9c\xde\x77\x4d\x65"
+			  "\xdf\xc0\x7a\xeb\x40\x80\xe8\xe5"
+			  "\xc7\xc1\x77\x3b\xae\x2b\x85\xce"
+			  "\x56\xfa\x43\x41\x96\x23\x8e\xab"
+			  "\xd3\xc8\x65\xef\x0b\xfe\x42\x4c"
+			  "\x3a\x8a\x54\x55\xab\xa3\xf9\x62"
+			  "\x9f\x8e\xbe\x33\x9a\xfe\x6b\x52"
+			  "\xd4\x4c\x93\x84\x7c\x7e\xb1\x5e"
+			  "\x32\xaf\x6e\x21\x44\xd2\x6b\x56"
+			  "\xcd\x2c\x9d\x03\x3b\x50\x1f\x0a"
+			  "\xc3\x98\xff\x3a\x1d\x36\x7e\x6d"
+			  "\xcf\xbc\xe7\xe8\xfc\x24\x55\xfd"
+			  "\x72\x3d\xa7\x3f\x09\xa7\x38\xe6"
+			  "\x57\x8d\xc4\x74\x7f\xd3\x26\x75"
+			  "\xda\xfa\x29\x35\xc1\x31\x82",
+		.ctext	= "\x02\x23\x74\x02\x56\xf4\x7b\xc8"
+			  "\x55\x61\xa0\x6b\x68\xff\xde\x87"
+			  "\x9d\x66\x77\x86\x98\x63\xab\xd5"
+			  "\xd6\xf4\x7e\x3b\xf4\xae\x97\x13"
+			  "\x79\xc0\x96\x75\x87\x33\x2a\x0e"
+			  "\xc2\x1a\x13\x90\x5f\x6e\x93\xed"
+			  "\x54\xfe\xee\x05\x48\xae\x20\x2d"
+			  "\xa9\x2b\x98\xa3\xc8\xaf\x17\x6b"
+			  "\x82\x4a\x9a\x7f\xf0\xce\xd9\x26"
+			  "\x16\x28\xeb\xf4\x4b\xab\x7d\x6e"
+			  "\x96\x27\xd2\x90\xbb\x8d\x98\xdc"
+			  "\xb8\x6f\x7a\x98\x67\xef\x1c\xfb"
+			  "\xd0\x23\x1a\x2f\xc9\x58\x4e\xc6"
+			  "\x38\x03\x53\x61\x8e\xff\x55\x46"
+			  "\x47\xe8\x1f\x9d\x66\x95\x9b\x7f"
+			  "\x26\xac\xf2\x61\xa4\x05\x15\xcb"
+			  "\x62\xb6\x6b\x7c\x57\x95\x9d\x25"
+			  "\x9e\x83\xb1\x88\x50\x39\xb5\x34"
+			  "\x8a\x04\x2b\x76\x1b\xb8\x8c\x57"
+			  "\x26\x21\x99\x2e\x93\xc8\x9b\xb2"
+			  "\x31\xe1\xe3\x27\xde\xc8\xf2\xc5"
+			  "\x01\x7a\x45\x38\x6f\xe7\xa0\x9d"
+			  "\x8c\x41\x99\xec\x3d\xb6\xaf\x66"
+			  "\x76\xac\xc8\x78\xb0\xdf\xcf\xce"
+			  "\xa1\x29\x46\x6f\xe3\x35\x4a\x67"
+			  "\x59\x27\x14\xcc\x04\xdb\xb3\x03"
+			  "\xb7\x2d\x8d\xf9\x75\x9e\x59\x42"
+			  "\xe3\xa4\xf8\xf4\x82\x27\xa3\xa9"
+			  "\x79\xac\x6b\x8a\xd8\xdb\x29\x73"
+			  "\x02\xbb\x6f\x85\x00\x92\xea\x59"
+			  "\x30\x1b\x19\xf3\xab\x6e\x99\x9a"
+			  "\xf2\x23\x27\xc6\x59\x5a\x9c",
+		.klen	= 32,
+		.len	= 255,
+	},
+
+};
+
 #endif	/* _CRYPTO_TESTMGR_H */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:19 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:19 -0600
Subject: [RFC PATCH 4/7] crypto: x86/aesni-xctr: Add accelerated
 implementation of XCTR
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-5-nhuck@google.com>

Add hardware accelerated versions of XCTR for x86-64 CPUs with AESNI
support.  These implementations are modified versions of the CTR
implementations found in aesni-intel_asm.S and aes_ctrby8_avx-x86_64.S.

More information on XCTR can be found in the HCTR2 paper:
Length-preserving encryption with HCTR2:
https://enterprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 arch/x86/crypto/Makefile                 |   2 +-
 arch/x86/crypto/aes_xctrby8_avx-x86_64.S | 529 +++++++++++++++++++++++
 arch/x86/crypto/aesni-intel_asm.S        |  70 +++
 arch/x86/crypto/aesni-intel_glue.c       |  88 ++++
 4 files changed, 688 insertions(+), 1 deletion(-)
 create mode 100644 arch/x86/crypto/aes_xctrby8_avx-x86_64.S

diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index c3af959648e6..ed187fcd0b01 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -48,7 +48,7 @@ chacha-x86_64-$(CONFIG_AS_AVX512) += chacha-avx512vl-x86_64.o
 
 obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
 aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
-aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o aes_ctrby8_avx-x86_64.o
+aesni-intel-$(CONFIG_64BIT) += aesni-intel_avx-x86_64.o aes_ctrby8_avx-x86_64.o aes_xctrby8_avx-x86_64.o
 
 obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
 sha1-ssse3-y := sha1_avx2_x86_64_asm.o sha1_ssse3_asm.o sha1_ssse3_glue.o
diff --git a/arch/x86/crypto/aes_xctrby8_avx-x86_64.S b/arch/x86/crypto/aes_xctrby8_avx-x86_64.S
new file mode 100644
index 000000000000..44aa83bee87a
--- /dev/null
+++ b/arch/x86/crypto/aes_xctrby8_avx-x86_64.S
@@ -0,0 +1,529 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-3-Clause */
+/*
+ * AES XCTR mode by8 optimization with AVX instructions. (x86_64)
+ *
+ * Copyright(c) 2014 Intel Corporation.
+ *
+ * Contact Information:
+ * James Guilford <james.guilford at intel.com>
+ * Sean Gulley <sean.m.gulley at intel.com>
+ * Chandramouli Narayanan <mouli at linux.intel.com>
+ */
+/*
+ * Implement AES XCTR mode with AVX instructions. This code is a modified
+ * version of the Linux kernel's AES CTR by8 implementation.
+ *
+ * This is AES128/192/256 XCTR mode optimization implementation. It requires
+ * the support of Intel(R) AESNI and AVX instructions.
+ *
+ * This work was inspired by the AES XCTR mode optimization published
+ * in Intel Optimized IPSEC Cryptographic library.
+ * Additional information on it can be found at:
+ *    https://github.com/intel/intel-ipsec-mb
+ */
+
+#include <linux/linkage.h>
+
+#define VMOVDQ		vmovdqu
+
+#define xdata0		%xmm0
+#define xdata1		%xmm1
+#define xdata2		%xmm2
+#define xdata3		%xmm3
+#define xdata4		%xmm4
+#define xdata5		%xmm5
+#define xdata6		%xmm6
+#define xdata7		%xmm7
+#define xiv      	%xmm8
+#define xbyteswap	%xmm9
+#define xkey0		%xmm10
+#define xkey4		%xmm11
+#define xkey8		%xmm12
+#define xkey12          %xmm13
+#define xkeyA		%xmm14
+#define xkeyB		%xmm15
+
+#define p_in		%rdi
+#define p_iv		%rsi
+#define p_keys		%rdx
+#define p_out		%rcx
+#define num_bytes	%r8
+#define counter         %r9
+
+#define tmp		%r10
+#define	DDQ_DATA	0
+#define	XDATA		1
+#define KEY_128		1
+#define KEY_192		2
+#define KEY_256		3
+
+.section .rodata
+.align 16
+
+byteswap_const:
+	.octa 0x000102030405060708090A0B0C0D0E0F
+ddq_low_msk:
+	.octa 0x0000000000000000FFFFFFFFFFFFFFFF
+ddq_high_add_1:
+	.octa 0x00000000000000010000000000000000
+ddq_add_1:
+	.octa 0x00000000000000000000000000000001
+ddq_add_2:
+	.octa 0x00000000000000000000000000000002
+ddq_add_3:
+	.octa 0x00000000000000000000000000000003
+ddq_add_4:
+	.octa 0x00000000000000000000000000000004
+ddq_add_5:
+	.octa 0x00000000000000000000000000000005
+ddq_add_6:
+	.octa 0x00000000000000000000000000000006
+ddq_add_7:
+	.octa 0x00000000000000000000000000000007
+ddq_add_8:
+	.octa 0x00000000000000000000000000000008
+
+.text
+
+/* generate a unique variable for ddq_add_x */
+
+/* generate a unique variable for xmm register */
+.macro setxdata n
+	var_xdata = %xmm\n
+.endm
+
+/* club the numeric 'id' to the symbol 'name' */
+
+.macro club name, id
+.altmacro
+	.if \name == XDATA
+		setxdata %\id
+	.endif
+.noaltmacro
+.endm
+
+/*
+ * do_aes num_in_par load_keys key_len
+ * This increments p_in, but not p_out
+ */
+.macro do_aes b, k, key_len
+	.set by, \b
+	.set load_keys, \k
+	.set klen, \key_len
+
+	.set i, 0
+	.rept (by)
+		club XDATA, i
+		movq counter, var_xdata
+		.set i, (i +1)
+	.endr
+
+	.if (load_keys)
+		vmovdqa	0*16(p_keys), xkey0
+	.endif
+
+	// next two blocks compute iv ^ block_index
+	.set i, 0
+	.rept (by)
+		club XDATA, i
+		vpaddq	(ddq_add_1 + 16 * i)(%rip), var_xdata, var_xdata
+		.set i, (i +1)
+	.endr
+	.set i, 0
+	.rept (by)
+		club XDATA, i
+		vpxor xiv, var_xdata, var_xdata
+		.set i, (i +1)
+	.endr
+
+	vmovdqa	1*16(p_keys), xkeyA
+
+	vpxor	xkey0, xdata0, xdata0
+	add $by, counter
+
+	.set i, 1
+	.rept (by - 1)
+		club XDATA, i
+		vpxor	xkey0, var_xdata, var_xdata
+		.set i, (i +1)
+	.endr
+
+	vmovdqa	2*16(p_keys), xkeyB
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		vaesenc	xkeyA, var_xdata, var_xdata		/* key 1 */
+		.set i, (i +1)
+	.endr
+
+	.if (klen == KEY_128)
+		.if (load_keys)
+			vmovdqa	3*16(p_keys), xkey4
+		.endif
+	.else
+		vmovdqa	3*16(p_keys), xkeyA
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		vaesenc	xkeyB, var_xdata, var_xdata		/* key 2 */
+		.set i, (i +1)
+	.endr
+
+	add	$(16*by), p_in
+
+	.if (klen == KEY_128)
+		vmovdqa	4*16(p_keys), xkeyB
+	.else
+		.if (load_keys)
+			vmovdqa	4*16(p_keys), xkey4
+		.endif
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 3 */
+		.if (klen == KEY_128)
+			vaesenc	xkey4, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyA, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	vmovdqa	5*16(p_keys), xkeyA
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 4 */
+		.if (klen == KEY_128)
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.else
+			vaesenc	xkey4, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	.if (klen == KEY_128)
+		.if (load_keys)
+			vmovdqa	6*16(p_keys), xkey8
+		.endif
+	.else
+		vmovdqa	6*16(p_keys), xkeyB
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		vaesenc	xkeyA, var_xdata, var_xdata		/* key 5 */
+		.set i, (i +1)
+	.endr
+
+	vmovdqa	7*16(p_keys), xkeyA
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 6 */
+		.if (klen == KEY_128)
+			vaesenc	xkey8, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	.if (klen == KEY_128)
+		vmovdqa	8*16(p_keys), xkeyB
+	.else
+		.if (load_keys)
+			vmovdqa	8*16(p_keys), xkey8
+		.endif
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		vaesenc	xkeyA, var_xdata, var_xdata		/* key 7 */
+		.set i, (i +1)
+	.endr
+
+	.if (klen == KEY_128)
+		.if (load_keys)
+			vmovdqa	9*16(p_keys), xkey12
+		.endif
+	.else
+		vmovdqa	9*16(p_keys), xkeyA
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 8 */
+		.if (klen == KEY_128)
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.else
+			vaesenc	xkey8, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	vmovdqa	10*16(p_keys), xkeyB
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 9 */
+		.if (klen == KEY_128)
+			vaesenc	xkey12, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyA, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	.if (klen != KEY_128)
+		vmovdqa	11*16(p_keys), xkeyA
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		/* key 10 */
+		.if (klen == KEY_128)
+			vaesenclast	xkeyB, var_xdata, var_xdata
+		.else
+			vaesenc	xkeyB, var_xdata, var_xdata
+		.endif
+		.set i, (i +1)
+	.endr
+
+	.if (klen != KEY_128)
+		.if (load_keys)
+			vmovdqa	12*16(p_keys), xkey12
+		.endif
+
+		.set i, 0
+		.rept by
+			club XDATA, i
+			vaesenc	xkeyA, var_xdata, var_xdata	/* key 11 */
+			.set i, (i +1)
+		.endr
+
+		.if (klen == KEY_256)
+			vmovdqa	13*16(p_keys), xkeyA
+		.endif
+
+		.set i, 0
+		.rept by
+			club XDATA, i
+			.if (klen == KEY_256)
+				/* key 12 */
+				vaesenc	xkey12, var_xdata, var_xdata
+			.else
+				vaesenclast xkey12, var_xdata, var_xdata
+			.endif
+			.set i, (i +1)
+		.endr
+
+		.if (klen == KEY_256)
+			vmovdqa	14*16(p_keys), xkeyB
+
+			.set i, 0
+			.rept by
+				club XDATA, i
+				/* key 13 */
+				vaesenc	xkeyA, var_xdata, var_xdata
+				.set i, (i +1)
+			.endr
+
+			.set i, 0
+			.rept by
+				club XDATA, i
+				/* key 14 */
+				vaesenclast	xkeyB, var_xdata, var_xdata
+				.set i, (i +1)
+			.endr
+		.endif
+	.endif
+
+	.set i, 0
+	.rept (by / 2)
+		.set j, (i+1)
+		VMOVDQ	(i*16 - 16*by)(p_in), xkeyA
+		VMOVDQ	(j*16 - 16*by)(p_in), xkeyB
+		club XDATA, i
+		vpxor	xkeyA, var_xdata, var_xdata
+		club XDATA, j
+		vpxor	xkeyB, var_xdata, var_xdata
+		.set i, (i+2)
+	.endr
+
+	.if (i < by)
+		VMOVDQ	(i*16 - 16*by)(p_in), xkeyA
+		club XDATA, i
+		vpxor	xkeyA, var_xdata, var_xdata
+	.endif
+
+	.set i, 0
+	.rept by
+		club XDATA, i
+		VMOVDQ	var_xdata, i*16(p_out)
+		.set i, (i+1)
+	.endr
+.endm
+
+.macro do_aes_load val, key_len
+	do_aes \val, 1, \key_len
+.endm
+
+.macro do_aes_noload val, key_len
+	do_aes \val, 0, \key_len
+.endm
+
+/* main body of aes xctr load */
+
+.macro do_aes_xctrmain key_len
+	andq	$(~0xf), num_bytes
+	cmp	$16, num_bytes
+	jb	.Ldo_return2\key_len
+
+	vmovdqa	byteswap_const(%rip), xbyteswap
+	shr	$4, counter
+	vmovdqu (p_iv), xiv
+
+	mov	num_bytes, tmp
+	and	$(7*16), tmp
+	jz	.Lmult_of_8_blks\key_len
+
+	/* 1 <= tmp <= 7 */
+	cmp	$(4*16), tmp
+	jg	.Lgt4\key_len
+	je	.Leq4\key_len
+
+.Llt4\key_len:
+	cmp	$(2*16), tmp
+	jg	.Leq3\key_len
+	je	.Leq2\key_len
+
+.Leq1\key_len:
+	do_aes_load	1, \key_len
+	add	$(1*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Leq2\key_len:
+	do_aes_load	2, \key_len
+	add	$(2*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+
+.Leq3\key_len:
+	do_aes_load	3, \key_len
+	add	$(3*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Leq4\key_len:
+	do_aes_load	4, \key_len
+	add	$(4*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Lgt4\key_len:
+	cmp	$(6*16), tmp
+	jg	.Leq7\key_len
+	je	.Leq6\key_len
+
+.Leq5\key_len:
+	do_aes_load	5, \key_len
+	add	$(5*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Leq6\key_len:
+	do_aes_load	6, \key_len
+	add	$(6*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Leq7\key_len:
+	do_aes_load	7, \key_len
+	add	$(7*16), p_out
+	and	$(~7*16), num_bytes
+	jz	.Ldo_return2\key_len
+	jmp	.Lmain_loop2\key_len
+
+.Lmult_of_8_blks\key_len:
+	.if (\key_len != KEY_128)
+		vmovdqa	0*16(p_keys), xkey0
+		vmovdqa	4*16(p_keys), xkey4
+		vmovdqa	8*16(p_keys), xkey8
+		vmovdqa	12*16(p_keys), xkey12
+	.else
+		vmovdqa	0*16(p_keys), xkey0
+		vmovdqa	3*16(p_keys), xkey4
+		vmovdqa	6*16(p_keys), xkey8
+		vmovdqa	9*16(p_keys), xkey12
+	.endif
+.align 16
+.Lmain_loop2\key_len:
+	/* num_bytes is a multiple of 8 and >0 */
+	do_aes_noload	8, \key_len
+	add	$(8*16), p_out
+	sub	$(8*16), num_bytes
+	jne	.Lmain_loop2\key_len
+
+.Ldo_return2\key_len:
+	ret
+.endm
+
+/*
+ * routine to do AES128 XCTR enc/decrypt "by8"
+ * XMM registers are clobbered.
+ * Saving/restoring must be done at a higher level
+ * aes_xctr_enc_128_avx_by8(const u8 *in, const u8 *iv, const aes_ctx *keys, u8 *out,
+ *			unsigned int num_bytes, unsigned int byte_ctr)
+ */
+SYM_FUNC_START(aes_xctr_enc_128_avx_by8)
+	/* call the aes main loop */
+	do_aes_xctrmain KEY_128
+
+SYM_FUNC_END(aes_xctr_enc_128_avx_by8)
+
+/*
+ * routine to do AES192 XCTR enc/decrypt "by8"
+ * XMM registers are clobbered.
+ * Saving/restoring must be done at a higher level
+ * aes_xctr_enc_192_avx_by8(const u8 *in, const u8 *iv, const aes_ctx *keys, u8 *out,
+ *			unsigned int num_bytes, unsigned int byte_ctr)
+ */
+SYM_FUNC_START(aes_xctr_enc_192_avx_by8)
+	/* call the aes main loop */
+	do_aes_xctrmain KEY_192
+
+SYM_FUNC_END(aes_xctr_enc_192_avx_by8)
+
+/*
+ * routine to do AES256 XCTR enc/decrypt "by8"
+ * XMM registers are clobbered.
+ * Saving/restoring must be done at a higher level
+ * aes_xctr_enc_256_avx_by8(void *in, void *iv, void *keys, void *out,
+ *			unsigned int num_bytes, unsigned int byte_ctr)
+ */
+SYM_FUNC_START(aes_xctr_enc_256_avx_by8)
+	/* call the aes main loop */
+	do_aes_xctrmain KEY_256
+
+SYM_FUNC_END(aes_xctr_enc_256_avx_by8)
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index 363699dd7220..ce17fe630150 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -2821,6 +2821,76 @@ SYM_FUNC_END(aesni_ctr_enc)
 
 #endif
 
+#ifdef __x86_64__
+/*
+ * void aesni_xctr_enc(struct crypto_aes_ctx *ctx, const u8 *dst, u8 *src,
+ *		      size_t len, u8 *iv, int byte_ctr)
+ */
+SYM_FUNC_START(aesni_xctr_enc)
+	FRAME_BEGIN
+	cmp $16, LEN
+	jb .Lxctr_ret
+	shr	$4, %arg6
+	movq %arg6, CTR
+	mov 480(KEYP), KLEN
+	movups (IVP), IV
+	cmp $64, LEN
+	jb .Lxctr_enc_loop1
+.align 4
+.Lxctr_enc_loop4:
+	movaps IV, STATE1
+	vpaddq ONE(%rip), CTR, CTR
+	vpxor CTR, STATE1, STATE1
+	movups (INP), IN1
+	movaps IV, STATE2
+	vpaddq ONE(%rip), CTR, CTR
+	vpxor CTR, STATE2, STATE2
+	movups 0x10(INP), IN2
+	movaps IV, STATE3
+	vpaddq ONE(%rip), CTR, CTR
+	vpxor CTR, STATE3, STATE3
+	movups 0x20(INP), IN3
+	movaps IV, STATE4
+	vpaddq ONE(%rip), CTR, CTR
+	vpxor CTR, STATE4, STATE4
+	movups 0x30(INP), IN4
+	call _aesni_enc4
+	pxor IN1, STATE1
+	movups STATE1, (OUTP)
+	pxor IN2, STATE2
+	movups STATE2, 0x10(OUTP)
+	pxor IN3, STATE3
+	movups STATE3, 0x20(OUTP)
+	pxor IN4, STATE4
+	movups STATE4, 0x30(OUTP)
+	sub $64, LEN
+	add $64, INP
+	add $64, OUTP
+	cmp $64, LEN
+	jge .Lxctr_enc_loop4
+	cmp $16, LEN
+	jb .Lxctr_ret
+.align 4
+.Lxctr_enc_loop1:
+	movaps IV, STATE
+	vpaddq ONE(%rip), CTR, CTR
+	vpxor CTR, STATE1, STATE1
+	movups (INP), IN
+	call _aesni_enc1
+	pxor IN, STATE
+	movups STATE, (OUTP)
+	sub $16, LEN
+	add $16, INP
+	add $16, OUTP
+	cmp $16, LEN
+	jge .Lxctr_enc_loop1
+.Lxctr_ret:
+	FRAME_END
+	RET
+SYM_FUNC_END(aesni_xctr_enc)
+
+#endif
+
 .section	.rodata.cst16.gf128mul_x_ble_mask, "aM", @progbits, 16
 .align 16
 .Lgf128mul_x_ble_mask:
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index 41901ba9d3a2..6537956592aa 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -24,6 +24,7 @@
 #include <crypto/ctr.h>
 #include <crypto/b128ops.h>
 #include <crypto/gcm.h>
+#include <crypto/xctr.h>
 #include <crypto/xts.h>
 #include <asm/cpu_device_id.h>
 #include <asm/simd.h>
@@ -112,6 +113,11 @@ asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out,
 			      const u8 *in, unsigned int len, u8 *iv);
 DEFINE_STATIC_CALL(aesni_ctr_enc_tfm, aesni_ctr_enc);
 
+asmlinkage void aesni_xctr_enc(struct crypto_aes_ctx *ctx, u8 *out,
+			       const u8 *in, unsigned int len, u8 *iv,
+			       unsigned int byte_ctr);
+DEFINE_STATIC_CALL(aesni_xctr_enc_tfm, aesni_xctr_enc);
+
 /* Scatter / Gather routines, with args similar to above */
 asmlinkage void aesni_gcm_init(void *ctx,
 			       struct gcm_context_data *gdata,
@@ -135,6 +141,16 @@ asmlinkage void aes_ctr_enc_192_avx_by8(const u8 *in, u8 *iv,
 		void *keys, u8 *out, unsigned int num_bytes);
 asmlinkage void aes_ctr_enc_256_avx_by8(const u8 *in, u8 *iv,
 		void *keys, u8 *out, unsigned int num_bytes);
+
+asmlinkage void aes_xctr_enc_128_avx_by8(const u8 *in, u8 *iv, void *keys, u8
+	*out, unsigned int num_bytes, unsigned int byte_ctr);
+
+asmlinkage void aes_xctr_enc_192_avx_by8(const u8 *in, u8 *iv, void *keys, u8
+	*out, unsigned int num_bytes, unsigned int byte_ctr);
+
+asmlinkage void aes_xctr_enc_256_avx_by8(const u8 *in, u8 *iv, void *keys, u8
+	*out, unsigned int num_bytes, unsigned int byte_ctr);
+
 /*
  * asmlinkage void aesni_gcm_init_avx_gen2()
  * gcm_data *my_ctx_data, context data
@@ -527,6 +543,59 @@ static int ctr_crypt(struct skcipher_request *req)
 	return err;
 }
 
+static void aesni_xctr_enc_avx_tfm(struct crypto_aes_ctx *ctx, u8 *out,
+			      const u8 *in, unsigned int len, u8 *iv, unsigned int byte_ctr)
+{
+	if (ctx->key_length == AES_KEYSIZE_128)
+		aes_xctr_enc_128_avx_by8(in, iv, (void *)ctx, out, len, byte_ctr);
+	else if (ctx->key_length == AES_KEYSIZE_192)
+		aes_xctr_enc_192_avx_by8(in, iv, (void *)ctx, out, len, byte_ctr);
+	else
+		aes_xctr_enc_256_avx_by8(in, iv, (void *)ctx, out, len, byte_ctr);
+}
+
+static int xctr_crypt(struct skcipher_request *req)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct crypto_aes_ctx *ctx = aes_ctx(crypto_skcipher_ctx(tfm));
+	u8 keystream[AES_BLOCK_SIZE];
+	u8 ctr[AES_BLOCK_SIZE];
+	u8 ctr_xor_iv[AES_BLOCK_SIZE];
+	struct skcipher_walk walk;
+	unsigned int nbytes;
+	unsigned int bsize = crypto_skcipher_chunksize(tfm);
+	unsigned int byte_ctr = 0;
+	int err;
+	u32 ctr32;
+
+	err = skcipher_walk_virt(&walk, req, false);
+
+	while ((nbytes = walk.nbytes) > 0) {
+		kernel_fpu_begin();
+		if (nbytes & AES_BLOCK_MASK)
+			static_call(aesni_xctr_enc_tfm)(ctx, walk.dst.virt.addr,
+				walk.src.virt.addr, nbytes & AES_BLOCK_MASK,
+				walk.iv, byte_ctr);
+		nbytes &= ~AES_BLOCK_MASK;
+		byte_ctr += walk.nbytes - nbytes;
+
+		if (walk.nbytes == walk.total && nbytes > 0) {
+			ctr32 = byte_ctr/bsize + 1;
+			u32_to_le_block(ctr, ctr32, bsize);
+			crypto_xor_cpy(ctr_xor_iv, ctr, walk.iv, bsize);
+			aesni_enc(ctx, keystream, ctr_xor_iv);
+			crypto_xor_cpy(walk.dst.virt.addr + walk.nbytes - nbytes,
+				       walk.src.virt.addr + walk.nbytes - nbytes,
+				       keystream, nbytes);
+			byte_ctr += nbytes;
+			nbytes = 0;
+		}
+		kernel_fpu_end();
+		err = skcipher_walk_done(&walk, nbytes);
+	}
+	return err;
+}
+
 static int
 rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len)
 {
@@ -1026,6 +1095,23 @@ static struct skcipher_alg aesni_skciphers[] = {
 		.setkey		= aesni_skcipher_setkey,
 		.encrypt	= ctr_crypt,
 		.decrypt	= ctr_crypt,
+	}, {
+		.base = {
+			.cra_name		= "__xctr(aes)",
+			.cra_driver_name	= "__xctr-aes-aesni",
+			.cra_priority		= 400,
+			.cra_flags		= CRYPTO_ALG_INTERNAL,
+			.cra_blocksize		= 1,
+			.cra_ctxsize		= CRYPTO_AES_CTX_SIZE,
+			.cra_module		= THIS_MODULE,
+		},
+		.min_keysize	= AES_MIN_KEY_SIZE,
+		.max_keysize	= AES_MAX_KEY_SIZE,
+		.ivsize		= AES_BLOCK_SIZE,
+		.chunksize	= AES_BLOCK_SIZE,
+		.setkey		= aesni_skcipher_setkey,
+		.encrypt	= xctr_crypt,
+		.decrypt	= xctr_crypt,
 #endif
 	}, {
 		.base = {
@@ -1162,6 +1248,8 @@ static int __init aesni_init(void)
 		/* optimize performance of ctr mode encryption transform */
 		static_call_update(aesni_ctr_enc_tfm, aesni_ctr_enc_avx_tfm);
 		pr_info("AES CTR mode by8 optimization enabled\n");
+		static_call_update(aesni_xctr_enc_tfm, aesni_xctr_enc_avx_tfm);
+		pr_info("AES XCTR mode by8 optimization enabled\n");
 	}
 #endif
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:20 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:20 -0600
Subject: [RFC PATCH 5/7] crypto: arm64/aes-xctr: Add accelerated
 implementation of XCTR
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-6-nhuck@google.com>

Add hardware accelerated version of XCTR for ARM64 CPUs with ARMv8
Crypto Extension support.  This XCTR implementation is based on the CTR
implementation in aes-modes.S.

More information on XCTR can be found in
the HCTR2 paper: Length-preserving encryption with HCTR2:
https://eprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 arch/arm64/crypto/Kconfig     |   4 +-
 arch/arm64/crypto/aes-glue.c  |  70 ++++++++++++++++++-
 arch/arm64/crypto/aes-modes.S | 128 ++++++++++++++++++++++++++++++++++
 3 files changed, 198 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index addfa413650b..cab469e279ec 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -84,13 +84,13 @@ config CRYPTO_AES_ARM64_CE_CCM
 	select CRYPTO_LIB_AES
 
 config CRYPTO_AES_ARM64_CE_BLK
-	tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
+	tristate "AES in ECB/CBC/CTR/XTS/XCTR modes using ARMv8 Crypto Extensions"
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_SKCIPHER
 	select CRYPTO_AES_ARM64_CE
 
 config CRYPTO_AES_ARM64_NEON_BLK
-	tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
+	tristate "AES in ECB/CBC/CTR/XTS/XCTR modes using NEON instructions"
 	depends on KERNEL_MODE_NEON
 	select CRYPTO_SKCIPHER
 	select CRYPTO_LIB_AES
diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 30b7cc6a7079..377f8d8369fb 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -35,10 +35,11 @@
 #define aes_essiv_cbc_encrypt	ce_aes_essiv_cbc_encrypt
 #define aes_essiv_cbc_decrypt	ce_aes_essiv_cbc_decrypt
 #define aes_ctr_encrypt		ce_aes_ctr_encrypt
+#define aes_xctr_encrypt	ce_aes_xctr_encrypt
 #define aes_xts_encrypt		ce_aes_xts_encrypt
 #define aes_xts_decrypt		ce_aes_xts_decrypt
 #define aes_mac_update		ce_aes_mac_update
-MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
+MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 Crypto Extensions");
 #else
 #define MODE			"neon"
 #define PRIO			200
@@ -52,16 +53,18 @@ MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
 #define aes_essiv_cbc_encrypt	neon_aes_essiv_cbc_encrypt
 #define aes_essiv_cbc_decrypt	neon_aes_essiv_cbc_decrypt
 #define aes_ctr_encrypt		neon_aes_ctr_encrypt
+#define aes_xctr_encrypt	neon_aes_xctr_encrypt
 #define aes_xts_encrypt		neon_aes_xts_encrypt
 #define aes_xts_decrypt		neon_aes_xts_decrypt
 #define aes_mac_update		neon_aes_mac_update
-MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON");
+MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 NEON");
 #endif
 #if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS)
 MODULE_ALIAS_CRYPTO("ecb(aes)");
 MODULE_ALIAS_CRYPTO("cbc(aes)");
 MODULE_ALIAS_CRYPTO("ctr(aes)");
 MODULE_ALIAS_CRYPTO("xts(aes)");
+MODULE_ALIAS_CRYPTO("xctr(aes)");
 #endif
 MODULE_ALIAS_CRYPTO("cts(cbc(aes))");
 MODULE_ALIAS_CRYPTO("essiv(cbc(aes),sha256)");
@@ -91,6 +94,10 @@ asmlinkage void aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
 asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
 				int rounds, int bytes, u8 ctr[], u8 finalbuf[]);
 
+asmlinkage void aes_xctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+				 int rounds, int bytes, u8 ctr[], u8 finalbuf[],
+				 int byte_ctr);
+
 asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[],
 				int rounds, int bytes, u32 const rk2[], u8 iv[],
 				int first);
@@ -444,6 +451,49 @@ static int __maybe_unused essiv_cbc_decrypt(struct skcipher_request *req)
 	return err ?: cbc_decrypt_walk(req, &walk);
 }
 
+static int __maybe_unused xctr_encrypt(struct skcipher_request *req)
+{
+	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
+	struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
+	int err, rounds = 6 + ctx->key_length / 4;
+	struct skcipher_walk walk;
+	unsigned int byte_ctr = 0;
+
+	err = skcipher_walk_virt(&walk, req, false);
+
+	while (walk.nbytes > 0) {
+		const u8 *src = walk.src.virt.addr;
+		unsigned int nbytes = walk.nbytes;
+		u8 *dst = walk.dst.virt.addr;
+		u8 buf[AES_BLOCK_SIZE];
+		unsigned int tail;
+
+		if (unlikely(nbytes < AES_BLOCK_SIZE))
+			src = memcpy(buf, src, nbytes);
+		else if (nbytes < walk.total)
+			nbytes &= ~(AES_BLOCK_SIZE - 1);
+
+		kernel_neon_begin();
+		aes_xctr_encrypt(dst, src, ctx->key_enc, rounds, nbytes,
+						 walk.iv, buf, byte_ctr);
+		kernel_neon_end();
+
+		tail = nbytes % (STRIDE * AES_BLOCK_SIZE);
+		if (tail > 0 && tail < AES_BLOCK_SIZE)
+			/*
+			 * The final partial block could not be returned using
+			 * an overlapping store, so it was passed via buf[]
+			 * instead.
+			 */
+			memcpy(dst + nbytes - tail, buf, tail);
+		byte_ctr += nbytes;
+
+		err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
+	}
+
+	return err;
+}
+
 static int __maybe_unused ctr_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -676,6 +726,22 @@ static struct skcipher_alg aes_algs[] = { {
 	.setkey		= skcipher_aes_setkey,
 	.encrypt	= ctr_encrypt,
 	.decrypt	= ctr_encrypt,
+}, {
+	.base = {
+		.cra_name		= "xctr(aes)",
+		.cra_driver_name	= "xctr-aes-" MODE,
+		.cra_priority		= PRIO,
+		.cra_blocksize		= 1,
+		.cra_ctxsize		= sizeof(struct crypto_aes_ctx),
+		.cra_module		= THIS_MODULE,
+	},
+	.min_keysize	= AES_MIN_KEY_SIZE,
+	.max_keysize	= AES_MAX_KEY_SIZE,
+	.ivsize		= AES_BLOCK_SIZE,
+	.chunksize	= AES_BLOCK_SIZE,
+	.setkey		= skcipher_aes_setkey,
+	.encrypt	= xctr_encrypt,
+	.decrypt	= xctr_encrypt,
 }, {
 	.base = {
 		.cra_name		= "xts(aes)",
diff --git a/arch/arm64/crypto/aes-modes.S b/arch/arm64/crypto/aes-modes.S
index ff01f0167ba2..7128907f8190 100644
--- a/arch/arm64/crypto/aes-modes.S
+++ b/arch/arm64/crypto/aes-modes.S
@@ -471,6 +471,134 @@ ST5(	mov		v3.16b, v4.16b			)
 	b		.Lctrout
 AES_FUNC_END(aes_ctr_encrypt)
 
+    /*
+	 * aes_xctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
+	 *		   int bytes, u8 const ctr[], u8 finalbuf[], int byte_ctr)
+	 */
+
+AES_FUNC_START(aes_xctr_encrypt)
+	stp		x29, x30, [sp, #-16]!
+	mov		x29, sp
+
+	enc_prepare	w3, x2, x12
+	ld1		{vctr.16b}, [x5]
+
+	umov		x12, vctr.d[0]		/* keep ctr in reg */
+	lsr		x7, x7, #4
+	add		x11, x7, #1
+
+.LxctrloopNx:
+	add		w7, w4, #15
+	sub		w4, w4, #MAX_STRIDE << 4
+	lsr		w7, w7, #4
+	mov		w8, #MAX_STRIDE
+	cmp		w7, w8
+	csel		w7, w7, w8, lt
+	add		x11, x11, x7
+
+	mov		v0.16b, vctr.16b
+	mov		v1.16b, vctr.16b
+	mov		v2.16b, vctr.16b
+	mov		v3.16b, vctr.16b
+ST5(	mov		v4.16b, vctr.16b		)
+
+	sub		x7, x11, #MAX_STRIDE
+	eor		x7, x12, x7
+	ins		v0.d[0], x7
+	sub		x7, x11, #MAX_STRIDE - 1
+	sub		x8, x11, #MAX_STRIDE - 2
+	eor		x7, x7, x12
+	sub		x9, x11, #MAX_STRIDE - 3
+	mov		v1.d[0], x7
+	eor		x8, x8, x12
+	eor		x9, x9, x12
+ST5(	sub		x10, x11, #MAX_STRIDE - 4)
+	mov		v2.d[0], x8
+	eor		x10, x10, x12
+	mov		v3.d[0], x9
+ST5(	mov		v4.d[0], x10			)
+	tbnz		w4, #31, .Lxctrtail
+	ld1		{v5.16b-v7.16b}, [x1], #48
+ST4(	bl		aes_encrypt_block4x		)
+ST5(	bl		aes_encrypt_block5x		)
+	eor		v0.16b, v5.16b, v0.16b
+ST4(	ld1		{v5.16b}, [x1], #16		)
+	eor		v1.16b, v6.16b, v1.16b
+ST5(	ld1		{v5.16b-v6.16b}, [x1], #32	)
+	eor		v2.16b, v7.16b, v2.16b
+	eor		v3.16b, v5.16b, v3.16b
+ST5(	eor		v4.16b, v6.16b, v4.16b		)
+	st1		{v0.16b-v3.16b}, [x0], #64
+ST5(	st1		{v4.16b}, [x0], #16		)
+	cbz		w4, .Lxctrout
+	b		.LxctrloopNx
+
+.Lxctrout:
+	ldp		x29, x30, [sp], #16
+	ret
+
+.Lxctrtail:
+	/* XOR up to MAX_STRIDE * 16 - 1 bytes of in/output with v0 ... v3/v4 */
+	mov		x17, #16
+	ands		x13, x4, #0xf
+	csel		x13, x13, x17, ne
+
+ST5(	cmp		w4, #64 - (MAX_STRIDE << 4))
+ST5(	csel		x14, x17, xzr, gt		)
+	cmp		w4, #48 - (MAX_STRIDE << 4)
+	csel		x15, x17, xzr, gt
+	cmp		w4, #32 - (MAX_STRIDE << 4)
+	csel		x16, x17, xzr, gt
+	cmp		w4, #16 - (MAX_STRIDE << 4)
+	ble		.Lxctrtail1x
+
+ST5(	mov		v4.d[0], x10			)
+
+	adr_l		x12, .Lcts_permute_table
+	add		x12, x12, x13
+
+ST5(	ld1		{v5.16b}, [x1], x14		)
+	ld1		{v6.16b}, [x1], x15
+	ld1		{v7.16b}, [x1], x16
+
+ST4(	bl		aes_encrypt_block4x		)
+ST5(	bl		aes_encrypt_block5x		)
+
+	ld1		{v8.16b}, [x1], x13
+	ld1		{v9.16b}, [x1]
+	ld1		{v10.16b}, [x12]
+
+ST4(	eor		v6.16b, v6.16b, v0.16b		)
+ST4(	eor		v7.16b, v7.16b, v1.16b		)
+ST4(	tbl		v3.16b, {v3.16b}, v10.16b	)
+ST4(	eor		v8.16b, v8.16b, v2.16b		)
+ST4(	eor		v9.16b, v9.16b, v3.16b		)
+
+ST5(	eor		v5.16b, v5.16b, v0.16b		)
+ST5(	eor		v6.16b, v6.16b, v1.16b		)
+ST5(	tbl		v4.16b, {v4.16b}, v10.16b	)
+ST5(	eor		v7.16b, v7.16b, v2.16b		)
+ST5(	eor		v8.16b, v8.16b, v3.16b		)
+ST5(	eor		v9.16b, v9.16b, v4.16b		)
+
+ST5(	st1		{v5.16b}, [x0], x14		)
+	st1		{v6.16b}, [x0], x15
+	st1		{v7.16b}, [x0], x16
+	add		x13, x13, x0
+	st1		{v9.16b}, [x13]		// overlapping stores
+	st1		{v8.16b}, [x0]
+	b		.Lxctrout
+
+.Lxctrtail1x:
+	csel		x0, x0, x6, eq		// use finalbuf if less than a full block
+	ld1		{v5.16b}, [x1]
+ST5(	mov		v3.16b, v4.16b			)
+	encrypt_block	v3, w3, x2, x8, w7
+	eor		v5.16b, v5.16b, v3.16b
+	st1		{v5.16b}, [x0]
+	b		.Lxctrout
+AES_FUNC_END(aes_xctr_encrypt)
+
 
 	/*
 	 * aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:21 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:21 -0600
Subject: [RFC PATCH 6/7] crypto: x86/polyval: Add PCLMULQDQ accelerated
 implementation of POLYVAL
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-7-nhuck@google.com>

Add hardware accelerated version of POLYVAL for x86-64 CPUs with
PCLMULQDQ support.

This implementation is accelerated using PCLMULQDQ instructions to
perform the finite field computations.  For added efficiency, 8 blocks
of the plaintext are processed simultaneously by precomputing the first
8 powers of the key.

Schoolbook multiplication is used instead of Karatsuba multiplication
because it was found to be slightly faster on x86-64 machines.
Montgomery reduction must be used instead of Barrett reduction due to
the difference in modulus between POLYVAL's field and other finite
fields.

More information on POLYVAL can be found in the HCTR2 paper:
Length-preserving encryption with HCTR2:
https://eprint.iacr.org/2021/1441.pdf

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 arch/x86/crypto/Makefile                     |   3 +
 arch/x86/crypto/polyval-clmulni-intel_asm.S  | 319 +++++++++++++++++++
 arch/x86/crypto/polyval-clmulni-intel_glue.c | 165 ++++++++++
 crypto/Kconfig                               |   9 +
 4 files changed, 496 insertions(+)
 create mode 100644 arch/x86/crypto/polyval-clmulni-intel_asm.S
 create mode 100644 arch/x86/crypto/polyval-clmulni-intel_glue.c

diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile
index ed187fcd0b01..0214c5f22606 100644
--- a/arch/x86/crypto/Makefile
+++ b/arch/x86/crypto/Makefile
@@ -69,6 +69,9 @@ libblake2s-x86_64-y := blake2s-core.o blake2s-glue.o
 obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
 
+obj-$(CONFIG_CRYPTO_POLYVAL_CLMUL_NI_INTEL) += polyval-clmulni-intel.o
+polyval-clmulni-intel-y := polyval-clmulni-intel_asm.o polyval-clmulni-intel_glue.o
+
 obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
 crc32c-intel-y := crc32c-intel_glue.o
 crc32c-intel-$(CONFIG_64BIT) += crc32c-pcl-intel-asm_64.o
diff --git a/arch/x86/crypto/polyval-clmulni-intel_asm.S b/arch/x86/crypto/polyval-clmulni-intel_asm.S
new file mode 100644
index 000000000000..4339b58e610d
--- /dev/null
+++ b/arch/x86/crypto/polyval-clmulni-intel_asm.S
@@ -0,0 +1,319 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT.
+ */
+/*
+ * This is an efficient implementation of POLYVAL using intel PCLMULQDQ-NI
+ * instructions. It works on 8 blocks at a time, computing the 256 degree
+ * polynomial p(x) = h^8m_0 + ... + h^1m_7. It then computes the modular
+ * reduction of p(x) and XORs p(x) with the current digest.
+ */
+
+#include <linux/linkage.h>
+#include <asm/frame.h>
+
+#define NUM_PRECOMPUTE_POWERS 8
+
+.align 16
+
+#define GSTAR %xmm7
+#define PL %xmm8
+#define PH %xmm9
+#define T %xmm10
+#define Z %xmm11
+#define C %xmm12
+#define D %xmm13
+#define EF %xmm14
+#define SUM %xmm15
+
+#define BLOCKS_LEFT %rdx
+#define OP1 %rdi
+#define OP2 %r10
+#define IDX %r11
+#define TMP %rax
+
+Lgstar:
+	.quad 0xc200000000000000, 0xc200000000000000
+
+.text
+
+/*
+ * Accepts operand lists of length b in rdi and rsi. Computes the product of
+ * each rdi,rsi pair then XORs the products into A, B, C, D.
+ *
+ * If first == 1 then XOR the value of SUM into the first block processed.
+ * This avoids an extra multication of SUM and h^N.
+ *
+ * XORs product into C, D, EF
+ * Preserves SUM
+ * All other xmm registers clobbered
+ */
+.macro schoolbook1 b
+	.set by, \b
+	.set i, 0
+	.rept (by)
+		schoolbook1_iteration i 0
+		.set i, (i +1)
+	.endr
+.endm
+
+.macro schoolbook1_iteration i first
+	.set first, \first
+	.set i, \i
+	movups (16*i)(OP1), %xmm0
+	.if(i == 0 && first == 1)
+		pxor SUM, %xmm0
+	.endif
+	vpclmulqdq $0x01, (16*i)(OP2), %xmm0, %xmm1
+	vpxor %xmm1, EF, EF
+	vpclmulqdq $0x00, (16*i)(OP2), %xmm0, %xmm2
+	vpxor %xmm2, C, C
+	vpclmulqdq $0x11, (16*i)(OP2), %xmm0, %xmm3
+	vpxor %xmm3, D, D
+	vpclmulqdq $0x10, (16*i)(OP2), %xmm0, %xmm4
+	vpxor %xmm4, EF, EF
+.endm
+
+/*
+ * Computes first schoolbook step of values loaded into xmm0 and xmm1. Used to
+ * multiply intermediate register values rather than memory stored values.
+ *
+ * XORs product into C, D, EF
+ * Preserves SUM
+ * All other xmm registers clobbered
+ */
+.macro schoolbook1_noload
+	vpclmulqdq $0x01, %xmm0, %xmm1, %xmm2
+	vpxor %xmm2, EF, EF
+	vpclmulqdq $0x00, %xmm0, %xmm1, %xmm3
+	vpxor %xmm3, C, C
+	vpclmulqdq $0x11, %xmm0, %xmm1, %xmm4
+	vpxor %xmm4, D, D
+	vpclmulqdq $0x10, %xmm0, %xmm1, %xmm5
+	vpxor %xmm5, EF, EF
+.endm
+
+/*
+ * Computes the 256-bit polynomial represented by C, D, EF. Stores
+ * the result in PL, PH.
+ *
+ * All other xmm registers are preserved.
+ */
+.macro schoolbook2
+	vpslldq $8, EF, PL
+	vpsrldq $8, EF, PH
+	pxor C, PL
+	pxor D, PH
+.endm
+
+/*
+ * Computes the 128-bit reduction of PL, PH. Stores the result in PH.
+ *
+ * PL, PH, Z, T.
+ * All other xmm registers are preserved.
+ */
+.macro montgomery_reduction
+	movdqa PL, T
+	pclmulqdq $0x00, GSTAR, T # T = [X0 * g*(x)]
+	pshufd $0b01001110, T, Z # Z = [T0 : T1]
+	pxor Z, PL # PL = [X1 ^ T0 : X0 ^ T1]
+	pxor PL, PH # PH = [X1 ^ T0 ^ X3 : X0 ^ T1 ^ X2]
+	pclmulqdq $0x11, GSTAR, PL # PL = [X1 ^ T0 * g*(x)]
+	pxor PL, PH
+.endm
+
+/*
+ * Compute schoolbook multiplication for 8 blocks
+ * (M_0h + REDUCE(PL, PH))h^8 + ... + M_{7}h^1 (no constant term)
+ *
+ * Sets PL, PH
+ * Clobbers C, D, E
+ *
+ * If reduce is set, computes the montgomery reduction of the
+ * previous full_stride call.
+ */
+.macro full_stride reduce
+	.set reduce, \reduce
+	mov %rsi, OP2
+	pxor C, C
+	pxor D, D
+	pxor EF, EF
+
+	schoolbook1_iteration 7 0
+	.if(reduce)
+		movdqa PL, T
+	.endif
+
+	schoolbook1_iteration 6 0
+	.if(reduce)
+		pclmulqdq $0x00, GSTAR, T # T = [X0 * g*(x)]
+	.endif
+
+	schoolbook1_iteration 5 0
+	.if(reduce)
+		pshufd $0b01001110, T, Z # Z = [T0 : T1]
+	.endif
+
+	schoolbook1_iteration 4 0
+	.if(reduce)
+		pxor Z, PL # PL = [X1 ^ T0 : X0 ^ T1]
+	.endif
+
+	schoolbook1_iteration 3 0
+	.if(reduce)
+		pxor PL, PH # PH = [X1 ^ T0 ^ X3 : X0 ^ T1 ^ X2]
+	.endif
+
+	schoolbook1_iteration 2 0
+	.if(reduce)
+		pclmulqdq $0x11, GSTAR, PL # PL = [X1 ^ T0 * g*(x)]
+	.endif
+
+	schoolbook1_iteration 1 0
+	.if(reduce)
+		pxor PL, PH
+		movdqa PH, SUM
+	.endif
+
+	schoolbook1_iteration 0 1
+
+	addq $(8*16), OP1
+	addq $(8*16), OP2
+	schoolbook2
+.endm
+
+/*
+ * Compute poly on window size of %rdx blocks
+ * 0 < %rdx < NUM_PRECOMPUTE_POWERS
+ */
+.macro partial_stride
+	pxor C, C
+	pxor D, D
+	pxor EF, EF
+	mov BLOCKS_LEFT, TMP
+	shlq $4, TMP
+	mov %rsi, OP2
+	addq $(16*NUM_PRECOMPUTE_POWERS), OP2
+	subq TMP, OP2
+	# Multiply sum by h^N
+	movups (OP2), %xmm0
+	movdqa SUM, %xmm1
+	schoolbook1_noload
+	schoolbook2
+	montgomery_reduction
+	movdqa PH, SUM
+	pxor C, C
+	pxor D, D
+	pxor EF, EF
+	xor IDX, IDX
+.LloopPartial:
+	cmpq BLOCKS_LEFT, IDX # IDX < rdx
+	jae .LloopExitPartial
+
+	movq BLOCKS_LEFT, TMP
+	subq IDX, TMP # TMP = rdx - IDX
+
+	cmp $4, TMP # TMP < 4 ?
+	jl .Llt4Partial
+	schoolbook1 4
+	addq $4, IDX
+	addq $(4*16), OP1
+	addq $(4*16), OP2
+	jmp .LoutPartial
+.Llt4Partial:
+	cmp $3, TMP # TMP < 3 ?
+	jl .Llt3Partial
+	schoolbook1 3
+	addq $3, IDX
+	addq $(3*16), OP1
+	addq $(3*16), OP2
+	jmp .LoutPartial
+.Llt3Partial:
+	cmp $2, TMP # TMP < 2 ?
+	jl .Llt2Partial
+	schoolbook1 2
+	addq $2, IDX
+	addq $(2*16), OP1
+	addq $(2*16), OP2
+	jmp .LoutPartial
+.Llt2Partial:
+	schoolbook1 1 # TMP < 1 ?
+	addq $1, IDX
+	addq $(1*16), OP1
+	addq $(1*16), OP2
+.LoutPartial:
+	jmp .LloopPartial
+.LloopExitPartial:
+	schoolbook2
+	montgomery_reduction
+	pxor PH, SUM
+.endm
+
+/*
+ * Perform montgomery multiplication in GF(2^128) and store result in op1.
+ *
+ * Computes op1*op2*x^{-128} mod x^128 + x^127 + x^126 + x^121 + 1
+ * If op1, op2 are in montgomery form,  this computes the montgomery
+ * form of op1*op2.
+ *
+ * void clmul_polyval_mul(ble128 *op1, const ble128 *op2);
+ */
+SYM_FUNC_START(clmul_polyval_mul)
+	FRAME_BEGIN
+	vmovdqa Lgstar(%rip), GSTAR
+	pxor C, C
+	pxor D, D
+	pxor EF, EF
+	mov %rsi, OP2
+	schoolbook1 1
+	schoolbook2
+	montgomery_reduction
+	movups PH, (%rdi)
+	FRAME_END
+	ret
+SYM_FUNC_END(clmul_polyval_mul)
+
+/*
+ * Perform polynomial evaluation as specified by POLYVAL. Multiplies the value
+ * stored at accumulator by h^k and XORs the evaluated polynomial into it.
+ *
+ * Computes h^k*accumulator + h^kM_0 + ... + h^1M_{k-1} (No constant term)
+ *
+ * rdi (OP1) - pointer to message blocks
+ * rsi - pointer to precomputed key struct
+ * rdx - number of blocks to hash
+ * rcx - location to XOR with evaluated polynomial
+ *
+ * void clmul_polyval_update(const u8 *in, const struct polyhash_key* keys,
+ *			     size_t nblocks, ble128* accumulator);
+ */
+SYM_FUNC_START(clmul_polyval_update)
+	FRAME_BEGIN
+	vmovdqa Lgstar(%rip), GSTAR
+	movups (%rcx), SUM
+	cmpq $NUM_PRECOMPUTE_POWERS, BLOCKS_LEFT
+	jb .LstrideLoopExit
+	full_stride 0
+	subq $NUM_PRECOMPUTE_POWERS, BLOCKS_LEFT
+.LstrideLoop:
+	cmpq $NUM_PRECOMPUTE_POWERS, BLOCKS_LEFT
+	jb .LstrideLoopExitReduce
+	full_stride 1
+	subq $NUM_PRECOMPUTE_POWERS, BLOCKS_LEFT
+	jmp .LstrideLoop
+.LstrideLoopExitReduce:
+	montgomery_reduction
+	movdqa PH, SUM
+.LstrideLoopExit:
+	test BLOCKS_LEFT, BLOCKS_LEFT
+	je .LskipPartial
+	partial_stride
+.LskipPartial:
+	movups SUM, (%rcx)
+	FRAME_END
+	ret
+SYM_FUNC_END(clmul_polyval_update)
diff --git a/arch/x86/crypto/polyval-clmulni-intel_glue.c b/arch/x86/crypto/polyval-clmulni-intel_glue.c
new file mode 100644
index 000000000000..64a432b67b49
--- /dev/null
+++ b/arch/x86/crypto/polyval-clmulni-intel_glue.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated POLYVAL implementation with Intel PCLMULQDQ-NI
+ * instructions. This file contains glue code.
+ *
+ * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1 at iki.fi>
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang at intel.com>
+ * Copyright 2021 Google LLC
+ */
+/*
+ * Glue code based on ghash-clmulni-intel_glue.c.
+ *
+ * This implementation of POLYVAL uses montgomery multiplication
+ * accelerated by PCLMULQDQ-NI to implement the finite field
+ * operations.
+ *
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/gf128mul.h>
+#include <crypto/internal/hash.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/simd.h>
+
+#define POLYVAL_BLOCK_SIZE	16
+#define POLYVAL_DIGEST_SIZE	16
+#define NUM_PRECOMPUTE_POWERS	8
+
+struct polyval_ctx {
+	be128 key_powers[NUM_PRECOMPUTE_POWERS];
+};
+
+struct polyval_desc_ctx {
+	u8 buffer[POLYVAL_BLOCK_SIZE];
+	u32 bytes;
+};
+
+asmlinkage void clmul_polyval_update(const u8 *in, const be128 *keys, size_t
+	nblocks, be128 *accumulator);
+asmlinkage void clmul_polyval_mul(be128 *op1, const be128 *op2);
+
+static int polyval_init(struct shash_desc *desc)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static int polyval_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct polyval_ctx *ctx = crypto_shash_ctx(tfm);
+	int i;
+
+	if (keylen != POLYVAL_BLOCK_SIZE)
+		return -EINVAL;
+
+	memcpy(&ctx->key_powers[NUM_PRECOMPUTE_POWERS-1], key, sizeof(be128));
+
+	for (i = NUM_PRECOMPUTE_POWERS-2; i >= 0; i--) {
+		memcpy(&ctx->key_powers[i], key, sizeof(be128));
+		clmul_polyval_mul(&ctx->key_powers[i], &ctx->key_powers[i+1]);
+	}
+
+	return 0;
+}
+
+static int polyval_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct polyval_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *dst = dctx->buffer;
+	u8 *pos;
+	unsigned int nblocks;
+	int n;
+
+	kernel_fpu_begin();
+	if (dctx->bytes) {
+		n = min(srclen, dctx->bytes);
+		pos = dst + POLYVAL_BLOCK_SIZE - dctx->bytes;
+
+		dctx->bytes -= n;
+		srclen -= n;
+
+		while (n--)
+			*pos++ ^= *src++;
+
+		if (!dctx->bytes)
+			clmul_polyval_mul((be128 *)dst, &ctx->key_powers[NUM_PRECOMPUTE_POWERS-1]);
+	}
+
+	nblocks = srclen/POLYVAL_BLOCK_SIZE;
+	clmul_polyval_update(src, ctx->key_powers, nblocks, (be128 *)dst);
+	srclen -= nblocks*POLYVAL_BLOCK_SIZE;
+	kernel_fpu_end();
+
+	if (srclen) {
+		dctx->bytes = POLYVAL_BLOCK_SIZE - srclen;
+		src += nblocks*POLYVAL_BLOCK_SIZE;
+		pos = dst;
+		while (srclen--)
+			*pos++ ^= *src++;
+	}
+
+	return 0;
+}
+
+static int polyval_final(struct shash_desc *desc, u8 *dst)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct polyval_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *buf = dctx->buffer;
+
+	if (dctx->bytes) {
+		kernel_fpu_begin();
+		clmul_polyval_mul((be128 *)dst, &ctx->key_powers[NUM_PRECOMPUTE_POWERS-1]);
+		kernel_fpu_end();
+	}
+
+	dctx->bytes = 0;
+	memcpy(dst, buf, POLYVAL_BLOCK_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg polyval_alg = {
+	.digestsize	= POLYVAL_DIGEST_SIZE,
+	.init		= polyval_init,
+	.update		= polyval_update,
+	.final		= polyval_final,
+	.setkey		= polyval_setkey,
+	.descsize	= sizeof(struct polyval_desc_ctx),
+	.base		= {
+		.cra_name		= "polyval",
+		.cra_driver_name	= "polyval-pclmulqdqni",
+		.cra_priority		= 200,
+		.cra_blocksize		= POLYVAL_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct polyval_ctx),
+		.cra_module		= THIS_MODULE,
+	},
+};
+
+static int __init polyval_mod_init(void)
+{
+	return crypto_register_shash(&polyval_alg);
+}
+
+static void __exit polyval_mod_exit(void)
+{
+	crypto_unregister_shash(&polyval_alg);
+}
+
+subsys_initcall(polyval_mod_init);
+module_exit(polyval_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("POLYVAL hash function accelerated by PCLMULQDQ-NI");
+MODULE_ALIAS_CRYPTO("polyval");
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 3cdb6c351062..ecff82b77b42 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -779,6 +779,15 @@ config CRYPTO_POLYVAL
 	  POLYVAL is the hash function used in HCTR2.  It is not a general-purpose
 	  cryptographic hash function.
 
+config CRYPTO_POLYVAL_CLMUL_NI_INTEL
+	tristate "POLYVAL hash function (CLMUL-NI accelerated)"
+	depends on X86 && 64BIT
+	select CRYPTO_POLYVAL
+	help
+	  This is the x86_64 CLMUL-NI accelerated implementation of POLYVAL. It is
+	  used to efficiently implement HCTR2 on x86-64 processors that support
+	  carry-less multiplication instructions.
+
 config CRYPTO_POLY1305
 	tristate "Poly1305 authenticator algorithm"
 	select CRYPTO_HASH
-- 
2.35.0.rc0.227.g00780c9af4-goog



From nhuck at google.com  Mon Jan 24 17:44:22 2022
From: nhuck at google.com (Nathan Huckleberry)
Date: Mon, 24 Jan 2022 19:44:22 -0600
Subject: [RFC PATCH 7/7] crypto: arm64/polyval: Add PMULL accelerated
 implementation of POLYVAL
In-Reply-To: <20220125014422.80552-1-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
Message-ID: <20220125014422.80552-8-nhuck@google.com>

Add hardware accelerated version of POLYVAL for ARM64 CPUs with
Crypto Extension support.

This implementation is accelerated using PMULL instructions to perform
the finite field computations.  For added efficiency, 8 blocks of the
plaintext are processed simultaneously by precomputing the first 8
powers of the key.

Karatsuba multiplication is used instead of Schoolbook multiplication
because it was found to be slightly faster on ARM64 CPUs.  Montgomery
reduction must be used instead of Barrett reduction due to the
difference in modulus between POLYVAL's field and other finite fields.

Signed-off-by: Nathan Huckleberry <nhuck at google.com>
---
 arch/arm64/crypto/Kconfig           |   6 +
 arch/arm64/crypto/Makefile          |   3 +
 arch/arm64/crypto/polyval-ce-core.S | 317 ++++++++++++++++++++++++++++
 arch/arm64/crypto/polyval-ce-glue.c | 164 ++++++++++++++
 4 files changed, 490 insertions(+)
 create mode 100644 arch/arm64/crypto/polyval-ce-core.S
 create mode 100644 arch/arm64/crypto/polyval-ce-glue.c

diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index cab469e279ec..b858f84b85eb 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -60,6 +60,12 @@ config CRYPTO_GHASH_ARM64_CE
 	select CRYPTO_GF128MUL
 	select CRYPTO_LIB_AES
 
+config CRYPTO_POLYVAL_ARM64_CE
+	tristate "POLYVAL using ARMv8 Crypto Extensions (for HCTR2)"
+	depends on KERNEL_MODE_NEON
+	select CRYPTO_HASH
+	select CRYPTO_POLYVAL
+
 config CRYPTO_CRCT10DIF_ARM64_CE
 	tristate "CRCT10DIF digest algorithm using PMULL instructions"
 	depends on KERNEL_MODE_NEON && CRC_T10DIF
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
index 09a805cc32d7..53f9af962b86 100644
--- a/arch/arm64/crypto/Makefile
+++ b/arch/arm64/crypto/Makefile
@@ -26,6 +26,9 @@ sm4-ce-y := sm4-ce-glue.o sm4-ce-core.o
 obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
 ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
 
+obj-$(CONFIG_CRYPTO_POLYVAL_ARM64_CE) += polyval-ce.o
+polyval-ce-y := polyval-ce-glue.o polyval-ce-core.o
+
 obj-$(CONFIG_CRYPTO_CRCT10DIF_ARM64_CE) += crct10dif-ce.o
 crct10dif-ce-y := crct10dif-ce-core.o crct10dif-ce-glue.o
 
diff --git a/arch/arm64/crypto/polyval-ce-core.S b/arch/arm64/crypto/polyval-ce-core.S
new file mode 100644
index 000000000000..04677c636aa1
--- /dev/null
+++ b/arch/arm64/crypto/polyval-ce-core.S
@@ -0,0 +1,317 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by an MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT.
+ */
+/*
+ * This is an efficient implementation of POLYVAL using ARMv8 Crypto Extension
+ * instructions. It works on 8 blocks at a time, computing the 256 degree
+ * polynomial p(x) = h^8m_0 + ... + h^1m_7. It then computes the modular
+ * reduction of p(x) and XORs with the current digest.
+ */
+
+#include <linux/linkage.h>
+#define NUM_PRECOMPUTE_POWERS 8
+
+BLOCKS_LEFT	.req	x2
+OP1	.req	x9
+KEY_START	.req	x10
+EXTRA_BYTES	.req	x11
+IDX	.req	x12
+TMP	.req	x13
+PARTIAL_LEFT	.req	x14
+
+M0	.req	v0
+M1	.req	v1
+M2	.req	v2
+M3	.req	v3
+M4	.req	v4
+M5	.req	v5
+M6	.req	v6
+M7	.req	v7
+KEY8	.req	v8
+KEY7	.req	v9
+KEY6	.req	v10
+KEY5	.req	v11
+KEY4	.req	v12
+KEY3	.req	v13
+KEY2	.req	v14
+KEY1	.req	v15
+PL	.req	v16
+PH	.req	v17
+T	.req	v18
+Z	.req	v19
+C	.req	v20
+D	.req	v21
+E	.req	v22
+SUM	.req	v23
+GSTAR	.req	v24
+
+	.text
+	.align	4
+
+	.arch	armv8-a+crypto
+	.align	4
+
+.Lgstar:
+	.quad	0xc200000000000000, 0xc200000000000000
+
+/*
+ * Computes the first step of Karatsuba multiplication of
+ * registers X, Y.
+ *
+ * Updates C, D, E
+ * Clobbers v25, v26, X, Y
+ */
+.macro karatsuba1 X Y
+	X .req \X
+	Y .req \Y
+	ext	v25.16b, X.16b, Y.16b, #8
+	eor	v25.16b, v25.16b, X.16b
+	ext	v26.16b, Y.16b, Y.16b, #8
+	eor	v26.16b, v26.16b, Y.16b
+	pmull	v26.1q, v25.1d, v26.1d
+	pmull2	v25.1q, X.2d, Y.2d
+	pmull	X.1q, X.1d, Y.1d
+	eor	E.16b, E.16b, v26.16b
+	eor	C.16b, C.16b, v25.16b
+	eor	D.16b, D.16b, X.16b
+	.unreq X
+	.unreq Y
+.endm
+
+/*
+ * Computes the 256-bit polynomial represented by C, D, E.
+ * Stores this polynomial in PH, PL.
+ *
+ * Sets PH, PL
+ * Clobbers C, D, E, v4
+ */
+.macro karatsuba2
+	ext	v4.16b, D.16b, C.16b, #8
+	eor	E.16b, E.16b, v4.16b //[E1 ^ C0 : E0 ^ D1]
+	eor	v4.16b, C.16b, D.16b //[C1 ^ D1 : C0 ^ D0]
+	eor	v4.16b, E.16b, v4.16b //[C0 ^ C1 ^ D1 ^ E1 : D1 ^ C0 ^ D0 ^ E0]
+	ext	C.16b, C.16b, C.16b, #8 // [C0 : C1]
+	ext	D.16b, D.16b, D.16b, #8 // [D0 : D1]
+	ext	PH.16b, v4.16b, C.16b, #8 //[C1 : C1 ^ D1 ^ E1 ^ C0]
+	ext	PL.16b, D.16b, v4.16b, #8 //[D1 ^ C0 ^ D0 ^ E0 : D0]
+.endm
+
+/*
+ * Perform montgomery reduction of the polynomial
+ * represented by PH, PL. Stores the reduced polynomial
+ * in PH.
+ *
+ * Sets PH
+ * Clobbers T, Z, PL
+ */
+.macro montgomery_reduction
+	pmull	T.1q, GSTAR.1d, PL.1d
+	ext	T.16b, T.16b, T.16b, #8
+	eor	PL.16b, PL.16b, T.16b
+	pmull2	Z.1q, GSTAR.2d, PL.2d
+	eor	Z.16b, PL.16b, Z.16b
+	eor	PH.16b, PH.16b, Z.16b
+.endm
+
+/*
+ * Compute Polyval on 8 blocks.
+ *
+ * If reduce is set, performs interleaved montgomery reduction
+ * on the last full_stride iteration's PL, PH.
+ *
+ * Sets PL, PH.
+ */
+.macro full_stride reduce
+	.set reduce, \reduce
+	eor		C.16b, C.16b, C.16b
+	eor		D.16b, D.16b, D.16b
+	eor		E.16b, E.16b, E.16b
+
+	ld1		{M0.16b, M1.16b, M2.16b, M3.16b}, [x0], #64
+	ld1		{M4.16b, M5.16b, M6.16b, M7.16b}, [x0], #64
+
+	karatsuba1 M7 KEY1
+	.if(reduce)
+	pmull	T.1q, GSTAR.1d, PL.1d
+	.endif
+
+	karatsuba1 M6 KEY2
+	.if(reduce)
+	ext	T.16b, T.16b, T.16b, #8
+	.endif
+
+	karatsuba1 M5 KEY3
+	.if(reduce)
+	eor	PL.16b, PL.16b, T.16b
+	.endif
+
+	karatsuba1 M4 KEY4
+	.if(reduce)
+	pmull2	Z.1q, GSTAR.2d, PL.2d
+	.endif
+
+	karatsuba1 M3 KEY5
+	.if(reduce)
+	eor	Z.16b, PL.16b, Z.16b
+	.endif
+
+	karatsuba1 M2 KEY6
+	.if(reduce)
+	eor	PH.16b, PH.16b, Z.16b
+	.endif
+
+	karatsuba1 M1 KEY7
+	.if(reduce)
+	mov	SUM.16b, PH.16b
+	.endif
+	eor	M0.16b, M0.16b, SUM.16b
+
+	karatsuba1 M0 KEY8
+
+	karatsuba2
+.endm
+
+/*
+ * Handle any extra blocks before
+ * full_stride loop.
+ */
+.macro partial_stride
+	eor		C.16b, C.16b, C.16b
+	eor		D.16b, D.16b, D.16b
+	eor		E.16b, E.16b, E.16b
+	add		KEY_START, x1, #(NUM_PRECOMPUTE_POWERS << 4)
+	sub		KEY_START, KEY_START, PARTIAL_LEFT, lsl #4
+	ld1		{v0.16b}, [KEY_START]
+	mov		v1.16b, SUM.16b
+	karatsuba1 v0 v1
+	karatsuba2
+	montgomery_reduction
+	mov		SUM.16b, PH.16b
+	eor		C.16b, C.16b, C.16b
+	eor		D.16b, D.16b, D.16b
+	eor		E.16b, E.16b, E.16b
+	mov		IDX, XZR
+.LloopPartial:
+	cmp		IDX, PARTIAL_LEFT
+	bge		.LloopExitPartial
+
+	sub		TMP, IDX, PARTIAL_LEFT
+
+	cmp		TMP, #-4
+	bgt		.Lgt4Partial
+	ld1		{M0.16b, M1.16b,  M2.16b, M3.16b}, [x0], #64
+	// Clobber key registers
+	ld1		{KEY8.16b, KEY7.16b, KEY6.16b,  KEY5.16b}, [KEY_START], #64
+	karatsuba1 M0 KEY8
+	karatsuba1 M1 KEY7
+	karatsuba1 M2 KEY6
+	karatsuba1 M3 KEY5
+	add		IDX, IDX, #4
+	b		.LoutPartial
+
+.Lgt4Partial:
+	cmp		TMP, #-3
+	bgt		.Lgt3Partial
+	ld1		{M0.16b, M1.16b, M2.16b}, [x0], #48
+	// Clobber key registers
+	ld1		{KEY8.16b, KEY7.16b, KEY6.16b}, [KEY_START], #48
+	karatsuba1 M0 KEY8
+	karatsuba1 M1 KEY7
+	karatsuba1 M2 KEY6
+	add		IDX, IDX, #3
+	b		.LoutPartial
+
+.Lgt3Partial:
+	cmp		TMP, #-2
+	bgt		.Lgt2Partial
+	ld1		{M0.16b, M1.16b}, [x0], #32
+	// Clobber key registers
+	ld1		{KEY8.16b, KEY7.16b}, [KEY_START], #32
+	karatsuba1 M0 KEY8
+	karatsuba1 M1 KEY7
+	add		IDX, IDX, #2
+	b		.LoutPartial
+
+.Lgt2Partial:
+	ld1		{M0.16b}, [x0], #16
+	// Clobber key registers
+	ld1		{KEY8.16b}, [KEY_START], #16
+	karatsuba1 M0 KEY8
+	add		IDX, IDX, #1
+.LoutPartial:
+	b .LloopPartial
+.LloopExitPartial:
+	karatsuba2
+	montgomery_reduction
+	eor		SUM.16b, SUM.16b, PH.16b
+.endm
+
+/*
+ * Perform montgomery multiplication in GF(2^128) and store result in op1.
+ *
+ * Computes op1*op2*x^{-128} mod x^128 + x^127 + x^126 + x^121 + 1
+ * If op1, op2 are in montgomery form,  this computes the montgomery
+ * form of op1*op2.
+ *
+ * void pmull_polyval_mul(ble128 *op1, const ble128 *op2);
+ */
+SYM_FUNC_START(pmull_polyval_mul)
+	adr		TMP, .Lgstar
+	ld1		{GSTAR.2d}, [TMP]
+	eor		C.16b, C.16b, C.16b
+	eor		D.16b, D.16b, D.16b
+	eor		E.16b, E.16b, E.16b
+	ld1		{v0.16b}, [x0]
+	ld1		{v1.16b}, [x1]
+	karatsuba1 v0 v1
+	karatsuba2
+	montgomery_reduction
+	st1		{PH.16b}, [x0]
+	ret
+SYM_FUNC_END(pmull_polyval_mul)
+
+/*
+ * Perform polynomial evaluation as specified by POLYVAL. Multiplies the value
+ * stored at accumulator by h^n and XORs the evaluated polynomial into it.
+ *
+ * Computes h^k*accumulator + h^kM_0 + ... + h^1M_{k-1} (No constant term)
+ *
+ * x0 (OP1) - pointer to message blocks
+ * x1 - pointer to precomputed key struct
+ * x2 - number of blocks to hash
+ * x3 - location to XOR with evaluated polynomial
+ *
+ * void pmull_polyval_update(const u8 *in, const struct polyhash_key *keys,
+ *			     size_t nblocks, ble128 *accumulator);
+ */
+SYM_FUNC_START(pmull_polyval_update)
+	adr		TMP, .Lgstar
+	ld1		{GSTAR.2d}, [TMP]
+	ld1		{SUM.16b}, [x3]
+	ands		PARTIAL_LEFT, BLOCKS_LEFT, #7
+	beq		.LskipPartial
+	partial_stride
+.LskipPartial:
+	subs		BLOCKS_LEFT, BLOCKS_LEFT, #NUM_PRECOMPUTE_POWERS
+	blt		.LstrideLoopExit
+	ld1		{KEY8.16b, KEY7.16b, KEY6.16b, KEY5.16b}, [x1], #64
+	ld1		{KEY4.16b, KEY3.16b, KEY2.16b, KEY1.16b}, [x1], #64
+	full_stride 0
+	subs		BLOCKS_LEFT, BLOCKS_LEFT, #NUM_PRECOMPUTE_POWERS
+	blt		.LstrideLoopExitReduce
+.LstrideLoop:
+	full_stride 1
+	subs		BLOCKS_LEFT, BLOCKS_LEFT, #NUM_PRECOMPUTE_POWERS
+	bge		.LstrideLoop
+.LstrideLoopExitReduce:
+	montgomery_reduction
+	mov		SUM.16b, PH.16b
+.LstrideLoopExit:
+	st1		{SUM.16b}, [x3]
+	ret
+SYM_FUNC_END(pmull_polyval_update)
diff --git a/arch/arm64/crypto/polyval-ce-glue.c b/arch/arm64/crypto/polyval-ce-glue.c
new file mode 100644
index 000000000000..2a83a931069a
--- /dev/null
+++ b/arch/arm64/crypto/polyval-ce-glue.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Accelerated POLYVAL implementation with ARMv8 Crypto Extension
+ * instructions. This file contains glue code.
+ *
+ * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1 at iki.fi>
+ * Copyright (c) 2009 Intel Corp.
+ *   Author: Huang Ying <ying.huang at intel.com>
+ * Copyright 2021 Google LLC
+ */
+/*
+ * Glue code based on ghash-clmulni-intel_glue.c.
+ *
+ * This implementation of POLYVAL uses montgomery multiplication accelerated by
+ * ARMv8 Crypto Extension instructions to implement the finite field operations.
+ *
+ */
+
+#include <crypto/algapi.h>
+#include <crypto/gf128mul.h>
+#include <crypto/internal/hash.h>
+#include <linux/crypto.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/neon.h>
+
+#define POLYVAL_BLOCK_SIZE	16
+#define POLYVAL_DIGEST_SIZE	16
+#define NUM_PRECOMPUTE_POWERS	8
+
+struct polyval_ctx {
+	be128 key_powers[NUM_PRECOMPUTE_POWERS];
+};
+
+struct polyval_desc_ctx {
+	u8 buffer[POLYVAL_BLOCK_SIZE];
+	u32 bytes;
+};
+
+asmlinkage void pmull_polyval_update(const u8 *in, const be128 *keys, size_t
+				     nblocks, be128 *accumulator);
+asmlinkage void pmull_polyval_mul(be128 *op1, const be128 *op2);
+
+static int polyval_init(struct shash_desc *desc)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static int polyval_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct polyval_ctx *ctx = crypto_shash_ctx(tfm);
+	int i;
+
+	if (keylen != POLYVAL_BLOCK_SIZE)
+		return -EINVAL;
+
+	memcpy(&ctx->key_powers[NUM_PRECOMPUTE_POWERS-1], key, sizeof(be128));
+
+	for (i = NUM_PRECOMPUTE_POWERS-2; i >= 0; i--) {
+		memcpy(&ctx->key_powers[i], key, sizeof(be128));
+		pmull_polyval_mul(&ctx->key_powers[i], &ctx->key_powers[i+1]);
+	}
+
+	return 0;
+}
+
+static int polyval_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct polyval_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *dst = dctx->buffer;
+	u8 *pos;
+	unsigned int nblocks;
+	unsigned int n;
+
+	kernel_neon_begin();
+	if (dctx->bytes) {
+		n = min(srclen, dctx->bytes);
+		pos = dst + POLYVAL_BLOCK_SIZE - dctx->bytes;
+
+		dctx->bytes -= n;
+		srclen -= n;
+
+		while (n--)
+			*pos++ ^= *src++;
+
+		if (!dctx->bytes)
+			pmull_polyval_mul((be128 *)dst, &ctx->key_powers[NUM_PRECOMPUTE_POWERS-1]);
+	}
+
+	nblocks = srclen/POLYVAL_BLOCK_SIZE;
+	pmull_polyval_update(src, ctx->key_powers, nblocks, (be128 *)dst);
+	srclen -= nblocks*POLYVAL_BLOCK_SIZE;
+	kernel_neon_end();
+
+	if (srclen) {
+		dctx->bytes = POLYVAL_BLOCK_SIZE - srclen;
+		src += nblocks*POLYVAL_BLOCK_SIZE;
+		pos = dst;
+		while (srclen--)
+			*pos++ ^= *src++;
+	}
+
+	return 0;
+}
+
+static int polyval_final(struct shash_desc *desc, u8 *dst)
+{
+	struct polyval_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct polyval_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	u8 *buf = dctx->buffer;
+
+	if (dctx->bytes) {
+		kernel_neon_begin();
+		pmull_polyval_mul((be128 *)dst, &ctx->key_powers[NUM_PRECOMPUTE_POWERS-1]);
+		kernel_neon_end();
+	}
+
+	dctx->bytes = 0;
+	memcpy(dst, buf, POLYVAL_BLOCK_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg polyval_alg = {
+	.digestsize	= POLYVAL_DIGEST_SIZE,
+	.init		= polyval_init,
+	.update		= polyval_update,
+	.final		= polyval_final,
+	.setkey		= polyval_setkey,
+	.descsize	= sizeof(struct polyval_desc_ctx),
+	.base		= {
+		.cra_name		= "polyval",
+		.cra_driver_name	= "polyval-ce",
+		.cra_priority		= 200,
+		.cra_blocksize		= POLYVAL_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct polyval_ctx),
+		.cra_module		= THIS_MODULE,
+	},
+};
+
+static int __init polyval_mod_init(void)
+{
+	return crypto_register_shash(&polyval_alg);
+}
+
+static void __exit polyval_mod_exit(void)
+{
+	crypto_unregister_shash(&polyval_alg);
+}
+
+subsys_initcall(polyval_mod_init);
+module_exit(polyval_mod_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("POLYVAL hash function accelerated by ARMv8 Crypto Extension");
+MODULE_ALIAS_CRYPTO("polyval");
-- 
2.35.0.rc0.227.g00780c9af4-goog



From ming.qian at nxp.com  Mon Jan 24 17:54:04 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 01:54:04 +0000
Subject: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
 skip
In-Reply-To: <a90c49239b86d8212045b1f2ef591c4bbf3cb8fd.camel@ndufresne.ca>
References: <cover.1631002447.git.ming.qian@nxp.com>
 <647f84c1e7c2a48d6492d38fa4f06586235500b8.1631002447.git.ming.qian@nxp.com>
 <fffd24d3374ecb2fbfafa9b85fa0ef8012fc7efa.camel@ndufresne.ca>
 <AM6PR04MB634124118288EC775F05AFC3E7D59@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <8984f8a3c0dfd3a5f83fb5cc7b0357dca4787274.camel@ndufresne.ca>
 <AM6PR04MB63417E126287421BCA133514E7539@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <a90c49239b86d8212045b1f2ef591c4bbf3cb8fd.camel@ndufresne.ca>
Message-ID: <AM6PR04MB63414D140EC922139260A8B4E75F9@AM6PR04MB6341.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Nicolas Dufresne [mailto:nicolas at ndufresne.ca]
> Sent: Saturday, January 22, 2022 6:25 AM
> To: Ming Qian <ming.qian at nxp.com>; mchehab at kernel.org;
> shawnguo at kernel.org; robh+dt at kernel.org; s.hauer at pengutronix.de
> Cc: hverkuil-cisco at xs4all.nl; kernel at pengutronix.de; festevam at gmail.com;
> dl-linux-imx <linux-imx at nxp.com>; linux-media at vger.kernel.org;
> linux-kernel at vger.kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org
> Subject: Re: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
> skip
> 
> Caution: EXT Email
> 
> Le jeudi 13 janvier 2022 ? 07:18 +0000, Ming Qian a ?crit :
> > Hi Nicolas,
> >
> >    I have question about skip event or similar concepts.
> > If the client control the input frame count, and it won't queue any more
> frames unless some frame is decoded.
> > But after seek, There is no requirement to begin queuing coded data starting
> exactly from a resume point (e.g. SPS or a keyframe). Any queued OUTPUT
> buffers will be processed and returned to the client until a suitable resume
> point is found. While looking for a resume point, the decoder should not
> produce any decoded frames into CAPTURE buffers.
> >
> > So client may have queued some frames but without any resume point, in
> this case the decoder won't produce any decoded frames into CAPTURE buffers,
> and the client won't queue frames into output buffers. This creates some kind
> of deadlock.
> >
> > In our previous solution, we send skip event to client to tell it that some
> frame is skipped instead of decoded, then the client can continue to queue
> frames.
> > But the skip event is flawed, so we need some solution to resolve it.
> > 1. decoder can produce an empty buffer with V4L2_BUF_FLAG_SKIPPED (or
> V4L2_BUF_FLAG_ERROR) as you advised, but this seems to conflict with the
> above description in specification.
> > 2. Define a notification mechanism to notify the client
> >
> > Can you give some advice?  This constraint of frame depth is common on
> > android
> 
> Without going against the spec, you can as of today pop a capture buffer and
> mark it done with error. As it has nothing valid in it, I would also set the
> payload size to 0.
> 
> So I'd say, for every unique input timestamp, that didn't yield a frame (skipped),
> pop a capture buffer, copy the timestamp, set the payload size to 0 and set it
> as done with error.
> 
> I'm not sure though if we that we can specify this, as I'm not sure this is
> possible with all the existing HW. I must admit, I don't myself had to deal with
> that issue as I'm not using a dummy framework. In GStreamer, we take care of
> locating the next sync point. So unless there was an error in the framework,
> this case does not exist for us.
> 
Hi Nicolas,
    If the decoder can detect the output buffer that may trigger a error, is it better setting error flag on the output buffer, but without producing an empty capture buffer with error flag set?, or we should return both output and capture buffer with error flag set?
    As I can see the following description in spec:

if the decoder is able to precisely report the OUTPUT buffer that triggered the error, such buffer will be returned with the V4L2_BUF_FLAG_ERROR flag set.


> >
> > Ming
> >
> > > > > > +    * - ``V4L2_EVENT_SKIP``
> > > > > > +      - 8
> > > > > > +      - This event is triggered when one frame is decoded,
> > > > > > + but it won't
> > > > > > be
> > > > > outputed
> > > > > > +     to the display. So the application can't get this frame,
> > > > > > + and the
> > > > > > input
> > > > > frame count
> > > > > > +     is dismatch with the output frame count. And this evevt
> > > > > > + is telling
> > > > > > the
> > > > > client to
> > > > > > +     handle this case.
> > > > >
> > > > > Similar to my previous comment, this event is flawed, since
> > > > > userspace cannot know were the skip is located in the queued
> > > > > buffers. Currently, all decoders are mandated to support
> > > > > V4L2_BUF_FLAG_TIMESTAMP_COPY. The timestamp must NOT be
> > > interpreted
> > > > > by the driver and must be reproduce as-is in the associated
> > > > > CAPTURE buffer. It is possible to "garbage" collect skipped
> > > > > frames with this method, though tedious.
> > > > >
> > > > > An alternative, and I think it would be much nicer then this,
> > > > > would be to use the v4l2_buffer.sequence counter, and just make
> > > > > it skip 1 on skips. Though, the down side is that userspace must
> > > > > also know how to reorder frames (a driver job for stateless
> > > > > codecs) in order to identify which frame was skipped. So this is
> > > > > perhaps not that useful, other then knowing something was skipped in
> the past.
> > > > >
> > > > > A third option would be to introduce V4L2_BUF_FLAG_SKIPPED. This
> > > > > way the driver could return an empty payload (bytesused = 0)
> > > > > buffer with this flag set, and the proper timestamp properly
> > > > > copied. This would let the driver communicate skipped frames in
> > > > > real-time. Note that this could break with existing userspace,
> > > > > so it would need to be opted-in somehow (a control or some flags).
> > > >
> > > > Hi Nicolas,
> > > >    The problem we meet is that userspace doesn't care which frame
> > > > is skipped, it just need to know that there are a frame is
> > > > skipped, the driver should promise the input frame count is equals
> > > > to the output frame
> > > count.
> > > >     Your first method is possible in theory, but we find the
> > > > timestamp may be unreliable, we meet many timestamp issues that
> > > > userspace may enqueue invalid timestamp or repeated timestamp and
> > > > so on, so we can't
> > > accept this solution.
> > >
> > > The driver should not interpret the provided timestamp, so it should
> > > not be able to say if the timestamp is valid or not, this is not the driver's
> task.
> > >
> > > The driver task is to match the timestamp to the CAPTURE buffer (if
> > > that buffer was produced), and reproduce it exactly.
> > >
> > > >     I think your second option is better. And there are only 1
> > > > question, we find some application prefer to use the
> > > > V4L2_EVENT_EOS to check the eos, not checking the empty buffer, if
> > > > we use this method to check skipped frame, the
> > >
> > > Checking the empty buffer is a legacy method, only available in
> > > Samsung MFC driver. The spec says that the last buffer should be
> > > flagged with _LAST, and any further attempt to poll should unblock and
> DQBUF return EPIPE.
> > >
> > > > application should check empty buffer instead of V4L2_EVENT_EOS,
> > > > otherwise if the last frame is skipped, the application will miss it.
> > > > Of course this is not a problem, it just increases the complexity
> > > > of the userspace implementation
> > >
> > > The EPIPE mechanism covers this issue, which we initially had with
> > > the LAST flag.
> > >
> > > >     I don't think your third method is feasible, the reasons are as below
> > > >               1. usually the empty payload means eos, and as you
> > > > say, it may introduce confusion.
> > > >       2. The driver may not have the opportunity to return an
> > > > empty payload during decoding, in our driver, driver will pass the
> > > > capture buffer to firmware, and when some frame is skipped, the
> > > > firmware won't return the buffer, driver may not find an available
> > > > capture buffer to return to userspace.
> > > >
> > > >    The requirement is that userspace need to match the input frame
> > > > count and output frame count. It doesn't care which frame is
> > > > skipped, so the V4L2_EVENT_SKIP is the easiest way for driver and
> userspace.
> > > >    If you think this event is really inappropriate, I prefer to
> > > > adopt your second option
> > >
> > > Please, drop SKIP from you driver and this patchset and fix your
> > > draining process handling to follow the spec. The Samsung OMX
> > > component is irrelevant to mainline submission, the OMX code should
> > > be updated to follow the spec.
> > >
> > > >


From gustavoars at kernel.org  Mon Jan 24 18:13:53 2022
From: gustavoars at kernel.org (Gustavo A. R. Silva)
Date: Mon, 24 Jan 2022 20:13:53 -0600
Subject: [PATCH][next] hwspinlock: stm32: Use struct_size() helper in
 devm_kzalloc()
Message-ID: <20220125021353.GA29777@embeddedor>

Make use of the struct_size() helper instead of an open-coded version,
in order to avoid any potential type mistakes or integer overflows that,
in the worst scenario, could lead to heap overflows.

Also, address the following sparse warnings:
drivers/hwspinlock/stm32_hwspinlock.c:84:32: warning: using sizeof on a flexible structure

Link: https://github.com/KSPP/linux/issues/174
Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
---
 drivers/hwspinlock/stm32_hwspinlock.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 5bd11a7fab65..716ad4401249 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -73,15 +73,14 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct stm32_hwspinlock *hw;
 	void __iomem *io_base;
-	size_t array_size;
 	int i, ret;
 
 	io_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(io_base))
 		return PTR_ERR(io_base);
 
-	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
-	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
+	hw = devm_kzalloc(dev, struct_size(hw, bank.lock, STM32_MUTEX_NUM_LOCKS),
+			  GFP_KERNEL);
 	if (!hw)
 		return -ENOMEM;
 
-- 
2.27.0



From benwolsieffer at gmail.com  Mon Jan 24 18:07:02 2022
From: benwolsieffer at gmail.com (Ben Wolsieffer)
Date: Mon, 24 Jan 2022 21:07:02 -0500
Subject: [PATCH 0/3] Add support for the HP TouchPad
Message-ID: <cover.1643075547.git.benwolsieffer@gmail.com>

This patchset adds basic support for the HP TouchPad (codename
"tenderloin") tablet. I started with a copy of the AQP8060 Dragonboard
device tree and made the necessary changes as a separate patch.

Ben Wolsieffer (3):
  ARM: dts: qcom: add HP TouchPad (tenderloin)
  dt-bindings: arm: qcom: document HP TouchPad
  ARM: dts: qcom: basic HP TouchPad support

 .../devicetree/bindings/arm/qcom.yaml         |   1 +
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/qcom-apq8060-tenderloin.dts | 478 ++++++++++++++++++
 3 files changed, 480 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-apq8060-tenderloin.dts

-- 
2.34.1



From benwolsieffer at gmail.com  Mon Jan 24 18:07:03 2022
From: benwolsieffer at gmail.com (Ben Wolsieffer)
Date: Mon, 24 Jan 2022 21:07:03 -0500
Subject: [PATCH 1/3] ARM: dts: qcom: add HP TouchPad (tenderloin)
In-Reply-To: <cover.1643075547.git.benwolsieffer@gmail.com>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
Message-ID: <e908c7e59f78c0e61cdd74e55da089fc51ac7fdc.1643075547.git.benwolsieffer@gmail.com>

The device tree is a copy of the Dragonboard, which uses the same SoC.
Therefore, it is not usuable in its current form. Instead, this patch
serves as a reference to make it easier to review the changes needed to
support the TouchPad.

Signed-off-by: Ben Wolsieffer <benwolsieffer at gmail.com>
---
 arch/arm/boot/dts/Makefile                    |   1 +
 arch/arm/boot/dts/qcom-apq8060-tenderloin.dts | 937 ++++++++++++++++++
 2 files changed, 938 insertions(+)
 create mode 100644 arch/arm/boot/dts/qcom-apq8060-tenderloin.dts

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 235ad559acb2..ce04c8b8b577 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -969,6 +969,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \
 	qcom-apq8016-sbc.dtb \
 	qcom-apq8026-lg-lenok.dtb \
 	qcom-apq8060-dragonboard.dtb \
+	qcom-apq8060-tenderloin.dtb \
 	qcom-apq8064-cm-qs600.dtb \
 	qcom-apq8064-ifc6410.dtb \
 	qcom-apq8064-sony-xperia-yuga.dtb \
diff --git a/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
new file mode 100644
index 000000000000..996e73aa0b0b
--- /dev/null
+++ b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
@@ -0,0 +1,937 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-mpp.h>
+#include "qcom-msm8660.dtsi"
+
+/ {
+	model = "HP TouchPad";
+	compatible = "qcom,apq8060-tenderloin", "qcom,msm8660";
+
+	aliases {
+		serial0 = &gsbi12_serial;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	regulators {
+		compatible = "simple-bus";
+
+		/* Main power of the board: 3.7V */
+		vph: regulator-fixed {
+			compatible = "regulator-fixed";
+			regulator-min-microvolt = <3700000>;
+			regulator-max-microvolt = <3700000>;
+			regulator-name = "VPH";
+			regulator-type = "voltage";
+			regulator-always-on;
+			regulator-boot-on;
+		};
+
+		/* GPIO controlled ethernet power regulator */
+		dragon_veth: xc622a331mrg {
+			compatible = "regulator-fixed";
+			regulator-name = "XC6222A331MR-G";
+			regulator-min-microvolt = <3300000>;
+			regulator-max-microvolt = <3300000>;
+			vin-supply = <&vph>;
+			gpio = <&pm8058_gpio 40 GPIO_ACTIVE_HIGH>;
+			enable-active-high;
+			pinctrl-names = "default";
+			pinctrl-0 = <&dragon_veth_gpios>;
+			regulator-always-on;
+		};
+
+		/* VDDvario fixed regulator */
+		dragon_vario: nds332p {
+			compatible = "regulator-fixed";
+			regulator-name = "NDS332P";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			vin-supply = <&pm8058_s3>;
+		};
+
+		/* This is a levelshifter for SDCC5 */
+		dragon_vio_txb: txb0104rgyr {
+			compatible = "regulator-fixed";
+			regulator-name = "Dragon SDCC levelshifter";
+			vin-supply = <&pm8058_l14>;
+			regulator-always-on;
+		};
+	};
+
+	/*
+	 * Capella CM3605 light and proximity sensor mounted directly
+	 * on the sensor board.
+	 */
+	cm3605 {
+		compatible = "capella,cm3605";
+		vdd-supply = <&pm8058_l14>; // 2.85V
+		aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>;
+		capella,aset-resistance-ohms = <100000>;
+		/* Trig on both edges - getting close or far away */
+		interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>;
+		/* MPP05 analog input to the XOADC */
+		io-channels = <&xoadc 0x00 0x05>;
+		io-channel-names = "aout";
+		pinctrl-names = "default";
+		pinctrl-0 = <&dragon_cm3605_gpios>, <&dragon_cm3605_mpps>;
+	};
+
+	soc {
+		pinctrl at 800000 {
+			/* eMMMC pins, all 8 data lines connected */
+			dragon_sdcc1_pins: sdcc1 {
+				mux {
+					pins = "gpio159", "gpio160", "gpio161",
+					     "gpio162", "gpio163", "gpio164",
+					     "gpio165", "gpio166", "gpio167",
+					     "gpio168";
+					     function = "sdc1";
+				};
+				clk {
+					pins = "gpio167"; /* SDC1 CLK */
+					drive-strength = <16>;
+					bias-disable;
+				};
+				cmd {
+					pins = "gpio168"; /* SDC1 CMD */
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+				data {
+					/* SDC1 D0 to D7 */
+					pins = "gpio159", "gpio160", "gpio161", "gpio162",
+					     "gpio163", "gpio164", "gpio165", "gpio166";
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+			};
+
+			/*
+			 * The SDCC3 pins are hardcoded (non-muxable) but need some pin
+			 * configuration.
+			 */
+			dragon_sdcc3_pins: sdcc3 {
+				clk {
+					pins = "sdc3_clk";
+					drive-strength = <8>;
+					bias-disable;
+				};
+				cmd {
+					pins = "sdc3_cmd";
+					drive-strength = <8>;
+					bias-pull-up;
+				};
+				data {
+					pins = "sdc3_data";
+					drive-strength = <8>;
+					bias-pull-up;
+				};
+			};
+
+			/* Second SD card slot pins */
+			dragon_sdcc5_pins: sdcc5 {
+				mux {
+					pins = "gpio95", "gpio96", "gpio97",
+					    "gpio98", "gpio99", "gpio100";
+					function = "sdc5";
+				};
+				clk {
+					pins = "gpio97"; /* SDC5 CLK */
+					drive-strength = <16>;
+					bias-disable;
+				};
+				cmd {
+					pins = "gpio95"; /* SDC5 CMD */
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+				data {
+					/* SDC5 D0 to D3 */
+					pins = "gpio96", "gpio98", "gpio99", "gpio100";
+					drive-strength = <10>;
+					bias-pull-up;
+				};
+			};
+
+			dragon_gsbi8_i2c_pins: gsbi8_i2c {
+				mux {
+					pins = "gpio64", "gpio65";
+					function = "gsbi8";
+				};
+				pinconf {
+					pins = "gpio64", "gpio65";
+					drive-strength = <16>;
+					/* These have external pull-up 2.2kOhm to 1.8V */
+					bias-disable;
+				};
+			};
+
+			dragon_gsbi12_i2c_pins: gsbi12_i2c {
+				mux {
+					pins = "gpio115", "gpio116";
+					function = "gsbi12";
+				};
+				pinconf {
+					pins = "gpio115", "gpio116";
+					drive-strength = <16>;
+					/* These have external pull-up 4.7kOhm to 1.8V */
+					bias-disable;
+				};
+			};
+
+			/* Primary serial port uart 0 pins */
+			dragon_gsbi12_serial_pins: gsbi12_serial {
+				mux {
+					pins = "gpio117", "gpio118";
+					function = "gsbi12";
+				};
+				tx {
+					pins = "gpio117";
+					drive-strength = <8>;
+					bias-disable;
+				};
+				rx {
+					pins = "gpio118";
+					drive-strength = <2>;
+					bias-pull-up;
+				};
+			};
+
+			dragon_ebi2_pins: ebi2 {
+				/*
+				 * Pins used by EBI2 on the Dragonboard, actually only
+				 * CS2 is used by a real peripheral. CS0 is just
+				 * routed to a test point.
+				 */
+				mux0 {
+					pins =
+					    /* "gpio39", CS1A_N this is not good to mux */
+					    "gpio40", /* CS2A_N */
+					    "gpio134"; /* CS0_N testpoint TP29 */
+					function = "ebi2cs";
+				};
+				mux1 {
+					pins =
+					    /* EBI2_ADDR_7 downto EBI2_ADDR_0 address bus */
+					    "gpio123", "gpio124", "gpio125", "gpio126",
+					    "gpio127", "gpio128", "gpio129", "gpio130",
+					    /* EBI2_DATA_15 downto EBI2_DATA_0 data bus */
+					    "gpio135", "gpio136", "gpio137", "gpio138",
+					    "gpio139", "gpio140", "gpio141", "gpio142",
+					    "gpio143", "gpio144", "gpio145", "gpio146",
+					    "gpio147", "gpio148", "gpio149", "gpio150",
+					    "gpio151", /* EBI2_OE_N */
+					    "gpio153", /* EBI2_ADV */
+					    "gpio157"; /* EBI2_WE_N */
+					function = "ebi2";
+				};
+			};
+
+			/* Interrupt line for the KXSD9 accelerometer */
+			dragon_kxsd9_gpios: kxsd9 {
+				irq {
+					pins = "gpio57"; /* IRQ line */
+					bias-pull-up;
+				};
+			};
+		};
+
+		qcom,ssbi at 500000 {
+			pmic at 0 {
+				keypad at 148 {
+					linux,keymap = <
+					MATRIX_KEY(0, 0, KEY_MENU)
+					MATRIX_KEY(0, 2, KEY_1)
+					MATRIX_KEY(0, 3, KEY_4)
+					MATRIX_KEY(0, 4, KEY_7)
+					MATRIX_KEY(1, 0, KEY_UP)
+					MATRIX_KEY(1, 1, KEY_LEFT)
+					MATRIX_KEY(1, 2, KEY_DOWN)
+					MATRIX_KEY(1, 3, KEY_5)
+					MATRIX_KEY(1, 3, KEY_8)
+					MATRIX_KEY(2, 0, KEY_HOME)
+					MATRIX_KEY(2, 1, KEY_REPLY)
+					MATRIX_KEY(2, 2, KEY_2)
+					MATRIX_KEY(2, 3, KEY_6)
+					MATRIX_KEY(3, 0, KEY_VOLUMEUP)
+					MATRIX_KEY(3, 1, KEY_RIGHT)
+					MATRIX_KEY(3, 2, KEY_3)
+					MATRIX_KEY(3, 3, KEY_9)
+					MATRIX_KEY(3, 4, KEY_SWITCHVIDEOMODE)
+					MATRIX_KEY(4, 0, KEY_VOLUMEDOWN)
+					MATRIX_KEY(4, 1, KEY_BACK)
+					MATRIX_KEY(4, 2, KEY_CAMERA)
+					MATRIX_KEY(4, 3, KEY_KBDILLUMTOGGLE)
+					>;
+					keypad,num-rows = <6>;
+					keypad,num-columns = <5>;
+				};
+
+				gpio at 150 {
+					dragon_ethernet_gpios: ethernet-gpios {
+						pinconf {
+							pins = "gpio7";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_bmp085_gpios: bmp085-gpios {
+						pinconf {
+							pins = "gpio16";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_mpu3050_gpios: mpu3050-gpios {
+						pinconf {
+							pins = "gpio17";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_sdcc3_gpios: sdcc3-gpios {
+						pinconf {
+							pins = "gpio22";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_sdcc5_gpios: sdcc5-gpios {
+						pinconf {
+							pins = "gpio26";
+							function = "normal";
+							input-enable;
+							bias-pull-up;
+							qcom,pull-up-strength = <PMIC_GPIO_PULL_UP_30>;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_ak8975_gpios: ak8975-gpios {
+						pinconf {
+							pins = "gpio33";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_cm3605_gpios: cm3605-gpios {
+						/* Pin 34 connected to the proxy IRQ */
+						pinconf_gpio34 {
+							pins = "gpio34";
+							function = "normal";
+							input-enable;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+						/* Pin 35 connected to ASET */
+						pinconf_gpio35 {
+							pins = "gpio35";
+							function = "normal";
+							output-high;
+							bias-disable;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+					dragon_veth_gpios: veth-gpios {
+						pinconf {
+							pins = "gpio40";
+							function = "normal";
+							bias-disable;
+							drive-push-pull;
+						};
+					};
+				};
+
+				mpps at 50 {
+					dragon_cm3605_mpps: cm3605-mpps-state {
+						pinconf {
+							pins = "mpp5";
+							function = "analog";
+							input-enable;
+							bias-high-impedance;
+							/* Let's use channel 5 */
+							qcom,amux-route = <PMIC_MPP_AMUX_ROUTE_CH5>;
+							power-source = <PM8058_GPIO_S3>;
+						};
+					};
+				};
+
+				xoadc at 197 {
+					/* Reference voltage 2.2 V */
+					xoadc-ref-supply = <&pm8058_l18>;
+
+					/* Board-specific channels */
+					mpp5 at 5 {
+						/* Connected to AOUT of ALS sensor */
+						reg = <0x00 0x05>;
+					};
+					mpp6 at 6 {
+						/* Connected to test point TP43 */
+						reg = <0x00 0x06>;
+					};
+					mpp7 at 7 {
+						/* Connected to battery thermistor */
+						reg = <0x00 0x07>;
+					};
+					mpp8 at 8 {
+						/* Connected to battery ID detector */
+						reg = <0x00 0x08>;
+					};
+					mpp9 at 9 {
+						/* Connected to XO thermistor */
+						reg = <0x00 0x09>;
+					};
+				};
+
+				led at 48 {
+					/*
+					 * The keypad LED @0x48 is routed to
+					 * the sensor board where it is
+					 * connected to an infrared LED
+					 * SFH4650 (60mW, @850nm) next to the
+					 * ambient light and proximity sensor
+					 * Capella Microsystems CM3605.
+					 */
+					compatible = "qcom,pm8058-keypad-led";
+					reg = <0x48>;
+					label = "pm8058:infrared:proximitysensor";
+					default-state = "off";
+					linux,default-trigger = "cm3605";
+				};
+				led at 131 {
+					compatible = "qcom,pm8058-led";
+					reg = <0x131>;
+					label = "pm8058:red";
+					default-state = "off";
+				};
+				led at 132 {
+					/*
+					 * This is actually green too on my
+					 * board, but documented as yellow.
+					 */
+					compatible = "qcom,pm8058-led";
+					reg = <0x132>;
+					label = "pm8058:yellow";
+					default-state = "off";
+					linux,default-trigger = "mmc0";
+				};
+				led at 133 {
+					compatible = "qcom,pm8058-led";
+					reg = <0x133>;
+					label = "pm8058:green";
+					default-state = "on";
+					linux,default-trigger = "heartbeat";
+				};
+			};
+		};
+
+		gsbi at 19800000 {
+			status = "okay";
+			qcom,mode = <GSBI_PROT_I2C>;
+
+			i2c at 19880000 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_gsbi8_i2c_pins>;
+
+				eeprom at 52 {
+					/* A 16KiB Platform ID EEPROM on the CPU carrier board */
+					compatible = "atmel,24c128";
+					reg = <0x52>;
+					vcc-supply = <&pm8058_s3>;
+					pagesize = <64>;
+				};
+				wm8903: wm8903 at 1a {
+					/* This Woolfson Micro device has an unrouted interrupt line */
+					compatible = "wlf,wm8903";
+					reg = <0x1a>;
+
+					AVDD-supply = <&pm8058_l16>;
+					CPVDD-supply = <&pm8058_l16>;
+					DBVDD-supply = <&pm8058_s3>;
+					DCVDD-supply = <&pm8058_l0>;
+
+					gpio-controller;
+					#gpio-cells = <2>;
+
+					micdet-cfg = <0>;
+					micdet-delay = <100>;
+					gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
+				};
+			};
+		};
+
+		gsbi at 19c00000 {
+			status = "okay";
+			qcom,mode = <GSBI_PROT_I2C_UART>;
+
+			serial at 19c40000 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_gsbi12_serial_pins>;
+			};
+
+			i2c at 19c80000 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_gsbi12_i2c_pins>;
+
+				ak8975 at c {
+					compatible = "asahi-kasei,ak8975";
+					reg = <0x0c>;
+					interrupt-parent = <&pm8058_gpio>;
+					interrupts = <33 IRQ_TYPE_EDGE_RISING>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&dragon_ak8975_gpios>;
+					vid-supply = <&pm8058_lvs0>; // 1.8V
+					vdd-supply = <&pm8058_l14>; // 2.85V
+				};
+				bmp085 at 77 {
+					compatible = "bosch,bmp085";
+					reg = <0x77>;
+					interrupt-parent = <&pm8058_gpio>;
+					interrupts = <16 IRQ_TYPE_EDGE_RISING>;
+					reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&dragon_bmp085_gpios>;
+					vddd-supply = <&pm8058_lvs0>; // 1.8V
+					vdda-supply = <&pm8058_l14>; // 2.85V
+				};
+				mpu3050 at 68 {
+					compatible = "invensense,mpu3050";
+					reg = <0x68>;
+					/*
+					 * GPIO17 is pulled high by a 10k
+					 * resistor to VLOGIC so needs to be
+					 * active low/falling edge.
+					 */
+					interrupts-extended = <&pm8058_gpio 17 IRQ_TYPE_EDGE_FALLING>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&dragon_mpu3050_gpios>;
+					vlogic-supply = <&pm8058_lvs0>; // 1.8V
+					vdd-supply = <&pm8058_l14>; // 2.85V
+
+					/*
+					 * The MPU-3050 acts as a hub for the
+					 * accelerometer.
+					 */
+					i2c-gate {
+						#address-cells = <1>;
+						#size-cells = <0>;
+
+						kxsd9 at 18 {
+							compatible = "kionix,kxsd9";
+							reg = <0x18>;
+							interrupt-parent = <&tlmm>;
+							interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
+							pinctrl-names = "default";
+							pinctrl-0 = <&dragon_kxsd9_gpios>;
+							iovdd-supply = <&pm8058_lvs0>; // 1.8V
+							vdd-supply = <&pm8058_l14>; // 2.85V
+						};
+					};
+				};
+			};
+		};
+
+		external-bus at 1a100000 {
+			/* The EBI2 will instantiate first, then populate its children */
+			status = "okay";
+			pinctrl-names = "default";
+			pinctrl-0 = <&dragon_ebi2_pins>;
+
+			/*
+			 * An on-board SMSC LAN9221 chip for "debug ethernet",
+			 * which is actually just an ordinary ethernet on the
+			 * EBI2. This has a 25MHz chrystal next to it, so no
+			 * clocking is needed.
+			 */
+			ethernet at 2,0 {
+				compatible = "smsc,lan9221", "smsc,lan9115";
+				reg = <2 0x0 0x100>;
+				/*
+				 * The second interrupt is the PME interrupt
+				 * for network wakeup, connected to the TLMM.
+				 */
+				interrupts-extended = <&pm8058_gpio 7 IRQ_TYPE_EDGE_FALLING>,
+						    <&tlmm 29 IRQ_TYPE_EDGE_RISING>;
+				reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
+				vdd33a-supply = <&dragon_veth>;
+				vddvario-supply = <&dragon_vario>;
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_ethernet_gpios>;
+				phy-mode = "mii";
+				reg-io-width = <2>;
+				smsc,force-external-phy;
+				smsc,irq-push-pull;
+
+				/*
+				 * SLOW chipselect config
+				 * Delay 9 cycles (140ns at 64MHz) between SMSC
+				 * LAN9221 Ethernet controller reads and writes
+				 * on CS2.
+				 */
+				qcom,xmem-recovery-cycles = <0>;
+				qcom,xmem-write-hold-cycles = <3>;
+				qcom,xmem-write-delta-cycles = <31>;
+				qcom,xmem-read-delta-cycles = <28>;
+				qcom,xmem-write-wait-cycles = <9>;
+				qcom,xmem-read-wait-cycles = <9>;
+			};
+		};
+
+		rpm at 104000 {
+			/*
+			 * Set up of the PMIC RPM regulators for this board
+			 * PM8901 supplies "preliminary regulators" whatever
+			 * that means
+			 */
+			pm8901-regulators {
+				vdd_l0-supply = <&pm8901_s4>;
+				vdd_l1-supply = <&vph>;
+				vdd_l2-supply = <&vph>;
+				vdd_l3-supply = <&vph>;
+				vdd_l4-supply = <&vph>;
+				vdd_l5-supply = <&vph>;
+				vdd_l6-supply = <&vph>;
+				/* vdd_s0-supply, vdd_s1-supply: SAW regulators */
+				vdd_s2-supply = <&vph>;
+				vdd_s3-supply = <&vph>;
+				vdd_s4-supply = <&vph>;
+				lvs0_in-supply = <&pm8058_s3>;
+				lvs1_in-supply = <&pm8901_s4>;
+				lvs2_in-supply = <&pm8058_l0>;
+				lvs3_in-supply = <&pm8058_s2>;
+				mvs_in-supply = <&pm8058_s3>;
+
+				l0 {
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+				l1 {
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					bias-pull-down;
+				};
+				l2 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <3300000>;
+					bias-pull-down;
+				};
+				l3 {
+					regulator-min-microvolt = <3300000>;
+					regulator-max-microvolt = <3300000>;
+					bias-pull-down;
+				};
+				l4 {
+					regulator-min-microvolt = <2600000>;
+					regulator-max-microvolt = <2600000>;
+					bias-pull-down;
+				};
+				l5 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
+					bias-pull-down;
+				};
+				l6 {
+					regulator-min-microvolt = <2200000>;
+					regulator-max-microvolt = <2200000>;
+					bias-pull-down;
+				};
+
+				/* s0 and s1 are SAW regulators controlled over SPM */
+				s2 {
+					regulator-min-microvolt = <1300000>;
+					regulator-max-microvolt = <1300000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+				s3 {
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt = <1100000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+				s4 {
+					regulator-min-microvolt = <1225000>;
+					regulator-max-microvolt = <1225000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+
+				/* LVS0 thru 3 and mvs0 are just switches */
+				lvs0 {
+					regulator-always-on;
+				};
+				lvs1 { };
+				lvs2 { };
+				lvs3 { };
+				mvs0 {};
+
+			};
+
+			pm8058-regulators {
+				vdd_l0_l1_lvs-supply = <&pm8058_s3>;
+				vdd_l2_l11_l12-supply = <&vph>;
+				vdd_l3_l4_l5-supply = <&vph>;
+				vdd_l6_l7-supply = <&vph>;
+				vdd_l8-supply = <&vph>;
+				vdd_l9-supply = <&vph>;
+				vdd_l10-supply = <&vph>;
+				vdd_l13_l16-supply = <&pm8058_s4>;
+				vdd_l14_l15-supply = <&vph>;
+				vdd_l17_l18-supply = <&vph>;
+				vdd_l19_l20-supply = <&vph>;
+				vdd_l21-supply = <&pm8058_s3>;
+				vdd_l22-supply = <&pm8058_s3>;
+				vdd_l23_l24_l25-supply = <&pm8058_s3>;
+				vdd_s0-supply = <&vph>;
+				vdd_s1-supply = <&vph>;
+				vdd_s2-supply = <&vph>;
+				vdd_s3-supply = <&vph>;
+				vdd_s4-supply = <&vph>;
+				vdd_ncp-supply = <&vph>;
+
+				l0 {
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+				l1 {
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+				l2 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <2600000>;
+					bias-pull-down;
+				};
+				l3 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					bias-pull-down;
+				};
+				l4 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
+					bias-pull-down;
+				};
+				l5 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
+					bias-pull-down;
+				};
+				l6 {
+					regulator-min-microvolt = <3000000>;
+					regulator-max-microvolt = <3600000>;
+					bias-pull-down;
+				};
+				l7 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					bias-pull-down;
+				};
+				l8 {
+					regulator-min-microvolt = <2900000>;
+					regulator-max-microvolt = <3050000>;
+					bias-pull-down;
+				};
+				l9 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					bias-pull-down;
+				};
+				l10 {
+					regulator-min-microvolt = <2600000>;
+					regulator-max-microvolt = <2600000>;
+					bias-pull-down;
+				};
+				l11 {
+					regulator-min-microvolt = <1500000>;
+					regulator-max-microvolt = <1500000>;
+					bias-pull-down;
+				};
+				l12 {
+					regulator-min-microvolt = <2900000>;
+					regulator-max-microvolt = <2900000>;
+					bias-pull-down;
+				};
+				l13 {
+					regulator-min-microvolt = <2050000>;
+					regulator-max-microvolt = <2050000>;
+					bias-pull-down;
+				};
+				l14 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
+				};
+				l15 {
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
+					bias-pull-down;
+				};
+				l16 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					bias-pull-down;
+					regulator-always-on;
+				};
+				l17 {
+					// 1.5V according to schematic
+					regulator-min-microvolt = <2600000>;
+					regulator-max-microvolt = <2600000>;
+					bias-pull-down;
+				};
+				l18 {
+					regulator-min-microvolt = <2200000>;
+					regulator-max-microvolt = <2200000>;
+					bias-pull-down;
+				};
+				l19 {
+					regulator-min-microvolt = <2500000>;
+					regulator-max-microvolt = <2500000>;
+					bias-pull-down;
+				};
+				l20 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					bias-pull-down;
+				};
+				l21 {
+					// 1.1 V according to schematic
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+					regulator-always-on;
+				};
+				l22 {
+					// 1.2 V according to schematic
+					regulator-min-microvolt = <1150000>;
+					regulator-max-microvolt = <1150000>;
+					bias-pull-down;
+				};
+				l23 {
+					// Unused
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+				l24 {
+					// Unused
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+				l25 {
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					bias-pull-down;
+				};
+
+				s0 {
+					// regulator-min-microvolt = <500000>;
+					// regulator-max-microvolt = <1325000>;
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt = <1100000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+				s1 {
+					// regulator-min-microvolt = <500000>;
+					// regulator-max-microvolt = <1250000>;
+					regulator-min-microvolt = <1100000>;
+					regulator-max-microvolt = <1100000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+				s2 {
+					// 1.3 V according to schematic
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1400000>;
+					qcom,switch-mode-frequency = <1600000>;
+					bias-pull-down;
+				};
+				s3 {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					qcom,switch-mode-frequency = <1600000>;
+					regulator-always-on;
+					bias-pull-down;
+				};
+				s4 {
+					regulator-min-microvolt = <2200000>;
+					regulator-max-microvolt = <2200000>;
+					qcom,switch-mode-frequency = <1600000>;
+					regulator-always-on;
+					bias-pull-down;
+				};
+
+				/* LVS0 and LVS1 are just switches */
+				lvs0 {
+					bias-pull-down;
+				};
+				lvs1 {
+					bias-pull-down;
+				};
+
+				ncp {
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
+					qcom,switch-mode-frequency = <1600000>;
+				};
+			};
+		};
+		amba {
+			/* Internal 3.69 GiB eMMC */
+			mmc at 12400000 {
+				status = "okay";
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_sdcc1_pins>;
+				vmmc-supply = <&pm8901_l5>;
+				vqmmc-supply = <&pm8901_lvs0>;
+			};
+
+			/* External micro SD card, directly connected, pulled up to 2.85 V */
+			mmc at 12180000 {
+				status = "okay";
+				/* Enable SSBI GPIO 22 as input, use for card detect */
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_sdcc3_pins>, <&dragon_sdcc3_gpios>;
+				cd-gpios = <&pm8058_gpio 22 GPIO_ACTIVE_LOW>;
+				wp-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
+				vmmc-supply = <&pm8058_l14>;
+			};
+
+			/*
+			 * Second external micro SD card, using two TXB104RGYR levelshifters
+			 * to lift from 1.8 V to 2.85 V
+			 */
+			mmc at 12200000 {
+				status = "okay";
+				/* Enable SSBI GPIO 26 as input, use for card detect */
+				pinctrl-names = "default";
+				pinctrl-0 = <&dragon_sdcc5_pins>, <&dragon_sdcc5_gpios>;
+				cd-gpios = <&pm8058_gpio 26 GPIO_ACTIVE_LOW>;
+				wp-gpios = <&tlmm 106 GPIO_ACTIVE_HIGH>;
+				vmmc-supply = <&pm8058_l14>;
+				vqmmc-supply = <&dragon_vio_txb>;
+			};
+		};
+	};
+};
-- 
2.34.1



From benwolsieffer at gmail.com  Mon Jan 24 18:07:04 2022
From: benwolsieffer at gmail.com (Ben Wolsieffer)
Date: Mon, 24 Jan 2022 21:07:04 -0500
Subject: [PATCH 2/3] dt-bindings: arm: qcom: document HP TouchPad
In-Reply-To: <cover.1643075547.git.benwolsieffer@gmail.com>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
Message-ID: <aa59002aeae45a95097300213fc34490aa8db250.1643075547.git.benwolsieffer@gmail.com>

Add binding documentation for the HP TouchPad.

Signed-off-by: Ben Wolsieffer <benwolsieffer at gmail.com>
---
 Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 370aab274cd1..f7418a8a49fc 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -119,6 +119,7 @@ properties:
       - items:
           - enum:
               - qcom,apq8060-dragonboard
+              - qcom,apq8060-tenderloin
               - qcom,msm8660-surf
           - const: qcom,msm8660
 
-- 
2.34.1



From benwolsieffer at gmail.com  Mon Jan 24 18:07:05 2022
From: benwolsieffer at gmail.com (Ben Wolsieffer)
Date: Mon, 24 Jan 2022 21:07:05 -0500
Subject: [PATCH 3/3] ARM: dts: qcom: basic HP TouchPad support
In-Reply-To: <cover.1643075547.git.benwolsieffer@gmail.com>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
Message-ID: <9f19df2a0017b71547445ac34df221e827c45bd0.1643075547.git.benwolsieffer@gmail.com>

Modify the Dragonboard device tree to support the most basic hardware on
the HP TouchPad. The headphone UART port and eMMC are supported.

Signed-off-by: Ben Wolsieffer <benwolsieffer at gmail.com>
---
 arch/arm/boot/dts/qcom-apq8060-tenderloin.dts | 549 ++----------------
 1 file changed, 45 insertions(+), 504 deletions(-)

diff --git a/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
index 996e73aa0b0b..e294f3920b9f 100644
--- a/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
+++ b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
@@ -14,6 +14,8 @@ aliases {
 	};
 
 	chosen {
+		/* Bootloader passes console=tty1, which overrides stdout-path */
+		bootargs = "console=ttyMSM0,115200 earlycon";
 		stdout-path = "serial0:115200n8";
 	};
 
@@ -30,67 +32,18 @@ vph: regulator-fixed {
 			regulator-always-on;
 			regulator-boot-on;
 		};
-
-		/* GPIO controlled ethernet power regulator */
-		dragon_veth: xc622a331mrg {
-			compatible = "regulator-fixed";
-			regulator-name = "XC6222A331MR-G";
-			regulator-min-microvolt = <3300000>;
-			regulator-max-microvolt = <3300000>;
-			vin-supply = <&vph>;
-			gpio = <&pm8058_gpio 40 GPIO_ACTIVE_HIGH>;
-			enable-active-high;
-			pinctrl-names = "default";
-			pinctrl-0 = <&dragon_veth_gpios>;
-			regulator-always-on;
-		};
-
-		/* VDDvario fixed regulator */
-		dragon_vario: nds332p {
-			compatible = "regulator-fixed";
-			regulator-name = "NDS332P";
-			regulator-min-microvolt = <1800000>;
-			regulator-max-microvolt = <1800000>;
-			vin-supply = <&pm8058_s3>;
-		};
-
-		/* This is a levelshifter for SDCC5 */
-		dragon_vio_txb: txb0104rgyr {
-			compatible = "regulator-fixed";
-			regulator-name = "Dragon SDCC levelshifter";
-			vin-supply = <&pm8058_l14>;
-			regulator-always-on;
-		};
-	};
-
-	/*
-	 * Capella CM3605 light and proximity sensor mounted directly
-	 * on the sensor board.
-	 */
-	cm3605 {
-		compatible = "capella,cm3605";
-		vdd-supply = <&pm8058_l14>; // 2.85V
-		aset-gpios = <&pm8058_gpio 35 GPIO_ACTIVE_LOW>;
-		capella,aset-resistance-ohms = <100000>;
-		/* Trig on both edges - getting close or far away */
-		interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>;
-		/* MPP05 analog input to the XOADC */
-		io-channels = <&xoadc 0x00 0x05>;
-		io-channel-names = "aout";
-		pinctrl-names = "default";
-		pinctrl-0 = <&dragon_cm3605_gpios>, <&dragon_cm3605_mpps>;
 	};
 
 	soc {
 		pinctrl at 800000 {
-			/* eMMMC pins, all 8 data lines connected */
-			dragon_sdcc1_pins: sdcc1 {
+			/* eMMC pins, all 8 data lines connected */
+			emmc_pins: sdcc1 {
 				mux {
 					pins = "gpio159", "gpio160", "gpio161",
 					     "gpio162", "gpio163", "gpio164",
 					     "gpio165", "gpio166", "gpio167",
 					     "gpio168";
-					     function = "sdc1";
+					function = "sdc1";
 				};
 				clk {
 					pins = "gpio167"; /* SDC1 CLK */
@@ -111,54 +64,7 @@ data {
 				};
 			};
 
-			/*
-			 * The SDCC3 pins are hardcoded (non-muxable) but need some pin
-			 * configuration.
-			 */
-			dragon_sdcc3_pins: sdcc3 {
-				clk {
-					pins = "sdc3_clk";
-					drive-strength = <8>;
-					bias-disable;
-				};
-				cmd {
-					pins = "sdc3_cmd";
-					drive-strength = <8>;
-					bias-pull-up;
-				};
-				data {
-					pins = "sdc3_data";
-					drive-strength = <8>;
-					bias-pull-up;
-				};
-			};
-
-			/* Second SD card slot pins */
-			dragon_sdcc5_pins: sdcc5 {
-				mux {
-					pins = "gpio95", "gpio96", "gpio97",
-					    "gpio98", "gpio99", "gpio100";
-					function = "sdc5";
-				};
-				clk {
-					pins = "gpio97"; /* SDC5 CLK */
-					drive-strength = <16>;
-					bias-disable;
-				};
-				cmd {
-					pins = "gpio95"; /* SDC5 CMD */
-					drive-strength = <10>;
-					bias-pull-up;
-				};
-				data {
-					/* SDC5 D0 to D3 */
-					pins = "gpio96", "gpio98", "gpio99", "gpio100";
-					drive-strength = <10>;
-					bias-pull-up;
-				};
-			};
-
-			dragon_gsbi8_i2c_pins: gsbi8_i2c {
+			gsbi8_i2c_pins: gsbi8_i2c {
 				mux {
 					pins = "gpio64", "gpio65";
 					function = "gsbi8";
@@ -171,205 +77,33 @@ pinconf {
 				};
 			};
 
-			dragon_gsbi12_i2c_pins: gsbi12_i2c {
-				mux {
-					pins = "gpio115", "gpio116";
-					function = "gsbi12";
-				};
-				pinconf {
-					pins = "gpio115", "gpio116";
-					drive-strength = <16>;
-					/* These have external pull-up 4.7kOhm to 1.8V */
-					bias-disable;
-				};
-			};
-
-			/* Primary serial port uart 0 pins */
-			dragon_gsbi12_serial_pins: gsbi12_serial {
+			/* Headphone UART pins */
+			headphone_uart_pins: gsbi12_serial {
 				mux {
 					pins = "gpio117", "gpio118";
 					function = "gsbi12";
 				};
-				tx {
-					pins = "gpio117";
-					drive-strength = <8>;
-					bias-disable;
-				};
 				rx {
-					pins = "gpio118";
+					pins = "gpio117";
 					drive-strength = <2>;
 					bias-pull-up;
 				};
-			};
-
-			dragon_ebi2_pins: ebi2 {
-				/*
-				 * Pins used by EBI2 on the Dragonboard, actually only
-				 * CS2 is used by a real peripheral. CS0 is just
-				 * routed to a test point.
-				 */
-				mux0 {
-					pins =
-					    /* "gpio39", CS1A_N this is not good to mux */
-					    "gpio40", /* CS2A_N */
-					    "gpio134"; /* CS0_N testpoint TP29 */
-					function = "ebi2cs";
-				};
-				mux1 {
-					pins =
-					    /* EBI2_ADDR_7 downto EBI2_ADDR_0 address bus */
-					    "gpio123", "gpio124", "gpio125", "gpio126",
-					    "gpio127", "gpio128", "gpio129", "gpio130",
-					    /* EBI2_DATA_15 downto EBI2_DATA_0 data bus */
-					    "gpio135", "gpio136", "gpio137", "gpio138",
-					    "gpio139", "gpio140", "gpio141", "gpio142",
-					    "gpio143", "gpio144", "gpio145", "gpio146",
-					    "gpio147", "gpio148", "gpio149", "gpio150",
-					    "gpio151", /* EBI2_OE_N */
-					    "gpio153", /* EBI2_ADV */
-					    "gpio157"; /* EBI2_WE_N */
-					function = "ebi2";
+				tx {
+					pins = "gpio118";
+					drive-strength = <8>;
+					bias-disable;
 				};
-			};
-
-			/* Interrupt line for the KXSD9 accelerometer */
-			dragon_kxsd9_gpios: kxsd9 {
-				irq {
-					pins = "gpio57"; /* IRQ line */
-					bias-pull-up;
+				/* Connect headphone jack to UART rather than audio */
+				enable {
+					pins = "gpio58";
+					function = "gpio";
+					output-high;
 				};
 			};
 		};
 
 		qcom,ssbi at 500000 {
 			pmic at 0 {
-				keypad at 148 {
-					linux,keymap = <
-					MATRIX_KEY(0, 0, KEY_MENU)
-					MATRIX_KEY(0, 2, KEY_1)
-					MATRIX_KEY(0, 3, KEY_4)
-					MATRIX_KEY(0, 4, KEY_7)
-					MATRIX_KEY(1, 0, KEY_UP)
-					MATRIX_KEY(1, 1, KEY_LEFT)
-					MATRIX_KEY(1, 2, KEY_DOWN)
-					MATRIX_KEY(1, 3, KEY_5)
-					MATRIX_KEY(1, 3, KEY_8)
-					MATRIX_KEY(2, 0, KEY_HOME)
-					MATRIX_KEY(2, 1, KEY_REPLY)
-					MATRIX_KEY(2, 2, KEY_2)
-					MATRIX_KEY(2, 3, KEY_6)
-					MATRIX_KEY(3, 0, KEY_VOLUMEUP)
-					MATRIX_KEY(3, 1, KEY_RIGHT)
-					MATRIX_KEY(3, 2, KEY_3)
-					MATRIX_KEY(3, 3, KEY_9)
-					MATRIX_KEY(3, 4, KEY_SWITCHVIDEOMODE)
-					MATRIX_KEY(4, 0, KEY_VOLUMEDOWN)
-					MATRIX_KEY(4, 1, KEY_BACK)
-					MATRIX_KEY(4, 2, KEY_CAMERA)
-					MATRIX_KEY(4, 3, KEY_KBDILLUMTOGGLE)
-					>;
-					keypad,num-rows = <6>;
-					keypad,num-columns = <5>;
-				};
-
-				gpio at 150 {
-					dragon_ethernet_gpios: ethernet-gpios {
-						pinconf {
-							pins = "gpio7";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_bmp085_gpios: bmp085-gpios {
-						pinconf {
-							pins = "gpio16";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_mpu3050_gpios: mpu3050-gpios {
-						pinconf {
-							pins = "gpio17";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_sdcc3_gpios: sdcc3-gpios {
-						pinconf {
-							pins = "gpio22";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_sdcc5_gpios: sdcc5-gpios {
-						pinconf {
-							pins = "gpio26";
-							function = "normal";
-							input-enable;
-							bias-pull-up;
-							qcom,pull-up-strength = <PMIC_GPIO_PULL_UP_30>;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_ak8975_gpios: ak8975-gpios {
-						pinconf {
-							pins = "gpio33";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_cm3605_gpios: cm3605-gpios {
-						/* Pin 34 connected to the proxy IRQ */
-						pinconf_gpio34 {
-							pins = "gpio34";
-							function = "normal";
-							input-enable;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-						/* Pin 35 connected to ASET */
-						pinconf_gpio35 {
-							pins = "gpio35";
-							function = "normal";
-							output-high;
-							bias-disable;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-					dragon_veth_gpios: veth-gpios {
-						pinconf {
-							pins = "gpio40";
-							function = "normal";
-							bias-disable;
-							drive-push-pull;
-						};
-					};
-				};
-
-				mpps at 50 {
-					dragon_cm3605_mpps: cm3605-mpps-state {
-						pinconf {
-							pins = "mpp5";
-							function = "analog";
-							input-enable;
-							bias-high-impedance;
-							/* Let's use channel 5 */
-							qcom,amux-route = <PMIC_MPP_AMUX_ROUTE_CH5>;
-							power-source = <PM8058_GPIO_S3>;
-						};
-					};
-				};
-
 				xoadc at 197 {
 					/* Reference voltage 2.2 V */
 					xoadc-ref-supply = <&pm8058_l18>;
@@ -396,46 +130,6 @@ mpp9 at 9 {
 						reg = <0x00 0x09>;
 					};
 				};
-
-				led at 48 {
-					/*
-					 * The keypad LED @0x48 is routed to
-					 * the sensor board where it is
-					 * connected to an infrared LED
-					 * SFH4650 (60mW, @850nm) next to the
-					 * ambient light and proximity sensor
-					 * Capella Microsystems CM3605.
-					 */
-					compatible = "qcom,pm8058-keypad-led";
-					reg = <0x48>;
-					label = "pm8058:infrared:proximitysensor";
-					default-state = "off";
-					linux,default-trigger = "cm3605";
-				};
-				led at 131 {
-					compatible = "qcom,pm8058-led";
-					reg = <0x131>;
-					label = "pm8058:red";
-					default-state = "off";
-				};
-				led at 132 {
-					/*
-					 * This is actually green too on my
-					 * board, but documented as yellow.
-					 */
-					compatible = "qcom,pm8058-led";
-					reg = <0x132>;
-					label = "pm8058:yellow";
-					default-state = "off";
-					linux,default-trigger = "mmc0";
-				};
-				led at 133 {
-					compatible = "qcom,pm8058-led";
-					reg = <0x133>;
-					label = "pm8058:green";
-					default-state = "on";
-					linux,default-trigger = "heartbeat";
-				};
 			};
 		};
 
@@ -446,151 +140,18 @@ gsbi at 19800000 {
 			i2c at 19880000 {
 				status = "okay";
 				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_gsbi8_i2c_pins>;
-
-				eeprom at 52 {
-					/* A 16KiB Platform ID EEPROM on the CPU carrier board */
-					compatible = "atmel,24c128";
-					reg = <0x52>;
-					vcc-supply = <&pm8058_s3>;
-					pagesize = <64>;
-				};
-				wm8903: wm8903 at 1a {
-					/* This Woolfson Micro device has an unrouted interrupt line */
-					compatible = "wlf,wm8903";
-					reg = <0x1a>;
-
-					AVDD-supply = <&pm8058_l16>;
-					CPVDD-supply = <&pm8058_l16>;
-					DBVDD-supply = <&pm8058_s3>;
-					DCVDD-supply = <&pm8058_l0>;
-
-					gpio-controller;
-					#gpio-cells = <2>;
-
-					micdet-cfg = <0>;
-					micdet-delay = <100>;
-					gpio-cfg = <0xffffffff 0xffffffff 0 0xffffffff 0xffffffff>;
-				};
+				pinctrl-0 = <&gsbi8_i2c_pins>;
 			};
 		};
 
 		gsbi at 19c00000 {
 			status = "okay";
-			qcom,mode = <GSBI_PROT_I2C_UART>;
+			qcom,mode = <GSBI_PROT_UART_W_FC>;
 
 			serial at 19c40000 {
 				status = "okay";
 				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_gsbi12_serial_pins>;
-			};
-
-			i2c at 19c80000 {
-				status = "okay";
-				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_gsbi12_i2c_pins>;
-
-				ak8975 at c {
-					compatible = "asahi-kasei,ak8975";
-					reg = <0x0c>;
-					interrupt-parent = <&pm8058_gpio>;
-					interrupts = <33 IRQ_TYPE_EDGE_RISING>;
-					pinctrl-names = "default";
-					pinctrl-0 = <&dragon_ak8975_gpios>;
-					vid-supply = <&pm8058_lvs0>; // 1.8V
-					vdd-supply = <&pm8058_l14>; // 2.85V
-				};
-				bmp085 at 77 {
-					compatible = "bosch,bmp085";
-					reg = <0x77>;
-					interrupt-parent = <&pm8058_gpio>;
-					interrupts = <16 IRQ_TYPE_EDGE_RISING>;
-					reset-gpios = <&tlmm 86 GPIO_ACTIVE_LOW>;
-					pinctrl-names = "default";
-					pinctrl-0 = <&dragon_bmp085_gpios>;
-					vddd-supply = <&pm8058_lvs0>; // 1.8V
-					vdda-supply = <&pm8058_l14>; // 2.85V
-				};
-				mpu3050 at 68 {
-					compatible = "invensense,mpu3050";
-					reg = <0x68>;
-					/*
-					 * GPIO17 is pulled high by a 10k
-					 * resistor to VLOGIC so needs to be
-					 * active low/falling edge.
-					 */
-					interrupts-extended = <&pm8058_gpio 17 IRQ_TYPE_EDGE_FALLING>;
-					pinctrl-names = "default";
-					pinctrl-0 = <&dragon_mpu3050_gpios>;
-					vlogic-supply = <&pm8058_lvs0>; // 1.8V
-					vdd-supply = <&pm8058_l14>; // 2.85V
-
-					/*
-					 * The MPU-3050 acts as a hub for the
-					 * accelerometer.
-					 */
-					i2c-gate {
-						#address-cells = <1>;
-						#size-cells = <0>;
-
-						kxsd9 at 18 {
-							compatible = "kionix,kxsd9";
-							reg = <0x18>;
-							interrupt-parent = <&tlmm>;
-							interrupts = <57 IRQ_TYPE_EDGE_FALLING>;
-							pinctrl-names = "default";
-							pinctrl-0 = <&dragon_kxsd9_gpios>;
-							iovdd-supply = <&pm8058_lvs0>; // 1.8V
-							vdd-supply = <&pm8058_l14>; // 2.85V
-						};
-					};
-				};
-			};
-		};
-
-		external-bus at 1a100000 {
-			/* The EBI2 will instantiate first, then populate its children */
-			status = "okay";
-			pinctrl-names = "default";
-			pinctrl-0 = <&dragon_ebi2_pins>;
-
-			/*
-			 * An on-board SMSC LAN9221 chip for "debug ethernet",
-			 * which is actually just an ordinary ethernet on the
-			 * EBI2. This has a 25MHz chrystal next to it, so no
-			 * clocking is needed.
-			 */
-			ethernet at 2,0 {
-				compatible = "smsc,lan9221", "smsc,lan9115";
-				reg = <2 0x0 0x100>;
-				/*
-				 * The second interrupt is the PME interrupt
-				 * for network wakeup, connected to the TLMM.
-				 */
-				interrupts-extended = <&pm8058_gpio 7 IRQ_TYPE_EDGE_FALLING>,
-						    <&tlmm 29 IRQ_TYPE_EDGE_RISING>;
-				reset-gpios = <&tlmm 30 GPIO_ACTIVE_LOW>;
-				vdd33a-supply = <&dragon_veth>;
-				vddvario-supply = <&dragon_vario>;
-				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_ethernet_gpios>;
-				phy-mode = "mii";
-				reg-io-width = <2>;
-				smsc,force-external-phy;
-				smsc,irq-push-pull;
-
-				/*
-				 * SLOW chipselect config
-				 * Delay 9 cycles (140ns at 64MHz) between SMSC
-				 * LAN9221 Ethernet controller reads and writes
-				 * on CS2.
-				 */
-				qcom,xmem-recovery-cycles = <0>;
-				qcom,xmem-write-hold-cycles = <3>;
-				qcom,xmem-write-delta-cycles = <31>;
-				qcom,xmem-read-delta-cycles = <28>;
-				qcom,xmem-write-wait-cycles = <9>;
-				qcom,xmem-read-wait-cycles = <9>;
+				pinctrl-0 = <&headphone_uart_pins>;
 			};
 		};
 
@@ -758,13 +319,13 @@ l9 {
 					bias-pull-down;
 				};
 				l10 {
-					regulator-min-microvolt = <2600000>;
-					regulator-max-microvolt = <2600000>;
+					regulator-min-microvolt = <3050000>;
+					regulator-max-microvolt = <3050000>;
 					bias-pull-down;
 				};
 				l11 {
-					regulator-min-microvolt = <1500000>;
-					regulator-max-microvolt = <1500000>;
+					regulator-min-microvolt = <2850000>;
+					regulator-max-microvolt = <2850000>;
 					bias-pull-down;
 				};
 				l12 {
@@ -790,10 +351,13 @@ l16 {
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					bias-pull-down;
-					regulator-always-on;
+					/*
+					 * RPM driver can't handle always-on regulators that are
+					 * supplied by regulators initialized after them.
+					 */
+					// regulator-always-on;
 				};
 				l17 {
-					// 1.5V according to schematic
 					regulator-min-microvolt = <2600000>;
 					regulator-max-microvolt = <2600000>;
 					bias-pull-down;
@@ -804,8 +368,8 @@ l18 {
 					bias-pull-down;
 				};
 				l19 {
-					regulator-min-microvolt = <2500000>;
-					regulator-max-microvolt = <2500000>;
+					regulator-min-microvolt = <1800000>;
+					regulator-max-microvolt = <1800000>;
 					bias-pull-down;
 				};
 				l20 {
@@ -814,14 +378,16 @@ l20 {
 					bias-pull-down;
 				};
 				l21 {
-					// 1.1 V according to schematic
 					regulator-min-microvolt = <1200000>;
 					regulator-max-microvolt = <1200000>;
 					bias-pull-down;
-					regulator-always-on;
+					/*
+					 * RPM driver can't handle always-on regulators that are
+					 * supplied by regulators initialized after them.
+					 */
+					// regulator-always-on;
 				};
 				l22 {
-					// 1.2 V according to schematic
 					regulator-min-microvolt = <1150000>;
 					regulator-max-microvolt = <1150000>;
 					bias-pull-down;
@@ -845,7 +411,7 @@ l25 {
 				};
 
 				s0 {
-					// regulator-min-microvolt = <500000>;
+					// regulator-min-microvolt = <800000>;
 					// regulator-max-microvolt = <1325000>;
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
@@ -853,8 +419,8 @@ s0 {
 					bias-pull-down;
 				};
 				s1 {
-					// regulator-min-microvolt = <500000>;
-					// regulator-max-microvolt = <1250000>;
+					// regulator-min-microvolt = <800000>;
+					// regulator-max-microvolt = <1325000>;
 					regulator-min-microvolt = <1100000>;
 					regulator-max-microvolt = <1100000>;
 					qcom,switch-mode-frequency = <1600000>;
@@ -871,15 +437,15 @@ s3 {
 					regulator-min-microvolt = <1800000>;
 					regulator-max-microvolt = <1800000>;
 					qcom,switch-mode-frequency = <1600000>;
-					regulator-always-on;
 					bias-pull-down;
+					regulator-always-on;
 				};
 				s4 {
 					regulator-min-microvolt = <2200000>;
 					regulator-max-microvolt = <2200000>;
 					qcom,switch-mode-frequency = <1600000>;
-					regulator-always-on;
 					bias-pull-down;
+					regulator-always-on;
 				};
 
 				/* LVS0 and LVS1 are just switches */
@@ -897,41 +463,16 @@ ncp {
 				};
 			};
 		};
+
 		amba {
-			/* Internal 3.69 GiB eMMC */
+			/* Internal 16/32 GiB eMMC */
 			mmc at 12400000 {
 				status = "okay";
 				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_sdcc1_pins>;
+				pinctrl-0 = <&emmc_pins>;
 				vmmc-supply = <&pm8901_l5>;
 				vqmmc-supply = <&pm8901_lvs0>;
 			};
-
-			/* External micro SD card, directly connected, pulled up to 2.85 V */
-			mmc at 12180000 {
-				status = "okay";
-				/* Enable SSBI GPIO 22 as input, use for card detect */
-				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_sdcc3_pins>, <&dragon_sdcc3_gpios>;
-				cd-gpios = <&pm8058_gpio 22 GPIO_ACTIVE_LOW>;
-				wp-gpios = <&tlmm 110 GPIO_ACTIVE_HIGH>;
-				vmmc-supply = <&pm8058_l14>;
-			};
-
-			/*
-			 * Second external micro SD card, using two TXB104RGYR levelshifters
-			 * to lift from 1.8 V to 2.85 V
-			 */
-			mmc at 12200000 {
-				status = "okay";
-				/* Enable SSBI GPIO 26 as input, use for card detect */
-				pinctrl-names = "default";
-				pinctrl-0 = <&dragon_sdcc5_pins>, <&dragon_sdcc5_gpios>;
-				cd-gpios = <&pm8058_gpio 26 GPIO_ACTIVE_LOW>;
-				wp-gpios = <&tlmm 106 GPIO_ACTIVE_HIGH>;
-				vmmc-supply = <&pm8058_l14>;
-				vqmmc-supply = <&dragon_vio_txb>;
-			};
 		};
 	};
 };
-- 
2.34.1



From dbaryshkov at gmail.com  Mon Jan 24 18:22:02 2022
From: dbaryshkov at gmail.com (Dmitry Baryshkov)
Date: Tue, 25 Jan 2022 05:22:02 +0300
Subject: [PATCH v2] ARM/pxa/mfd/power/sound: Switch Tosa to GPIO
 descriptors
In-Reply-To: <20220125003741.492954-1-linus.walleij@linaro.org>
References: <20220125003741.492954-1-linus.walleij@linaro.org>
Message-ID: <CALT56yN39Xa3suNS6i1VnOTHvG82qGFsQha=PkcsyoeFJ=kDRQ@mail.gmail.com>

??, 25 ???. 2022 ?. ? 03:39, Linus Walleij <linus.walleij at linaro.org>:
>
> The Tosa device (Sharp SL-6000) has a mishmash driver set-up
> for the Toshiba TC6393xb MFD that includes a battery charger
> and touchscreen and has some kind of relationship to the SoC
> sound driver for the AC97 codec. Other devices define a chip
> like this but seem only half-implemented, not really handling
> battery charging etc.
>
> This patch switches the Toshiba MFD device to provide GPIO
> descriptors to the battery charger and SoC codec. As a result
> some descriptors need to be moved out of the Tosa boardfile
> and new one added: all SoC GPIO resources to these drivers
> now comes from the main boardfile, while the MFD provide
> GPIOs for its portions.
>
> As a result we can request one GPIO from our own GPIO chip
> and drop two hairy callbacks into the board file.
>
> This platform badly needs to have its drivers split up and
> converted to device tree probing to handle this quite complex
> relationship in an orderly manner. I just do my best in solving
> the GPIO descriptor part of the puzzle. Please don't ask me
> to fix everything that is wrong with these driver to todays
> standards, I am just trying to fix one aspect. I do try to
> use modern devres resource management and handle deferred
> probe using new functions where appropriate.
>
> Cc: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>

Reviewed-by: Dmitry Baryshkov <dbaryshkov at gmail.com>

Minor nit bellow.

> Cc: Dirk Opfer <dirk at opfer-online.de>
> Cc: Robert Jarzmik <robert.jarzmik at free.fr>
> Cc: Daniel Mack <daniel at zonque.org>
> Cc: Haojian Zhuang <haojian.zhuang at gmail.com>
> Cc: Lee Jones <lee.jones at linaro.org>
> Cc: Liam Girdwood <lgirdwood at gmail.com>
> Acked-by: Mark Brown <broonie at kernel.org>
> Acked-by: Sebastian Reichel <sebastian.reichel at collabora.com>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> ChangeLog v1->v2:
> - Rebase on v5.17-rc1
> - Collect some ACKs.
> - Drop comments on includes.
> - Replace defined TOSA_GC_NAME with explicit string
> - Add a macro GPIO_LOOKUP_SINGLE() and use it in the patch
> - As we removed the only users of the .setup() and .teardown()
>   callbacks in struct tc6393xb_platform_data these members
>   can be removed.
> Merging strategy: please provide ACKs and I will attempt
> to merge this through the SoC tree.
> ---
>  arch/arm/mach-pxa/eseries.c           |   2 -
>  arch/arm/mach-pxa/include/mach/tosa.h |  18 ---
>  arch/arm/mach-pxa/tosa.c              |  68 +++-------
>  drivers/mfd/tc6393xb.c                | 130 ++++++++++++++------
>  drivers/power/supply/tosa_battery.c   | 171 ++++++++++++++++----------
>  include/linux/gpio/machine.h          |  12 ++
>  include/linux/mfd/tc6393xb.h          |   3 -
>  sound/soc/pxa/tosa.c                  |  20 ++-
>  8 files changed, 241 insertions(+), 183 deletions(-)
>
> diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
> index f37c44b6139d..9e9b5c78f8ad 100644
> --- a/arch/arm/mach-pxa/eseries.c
> +++ b/arch/arm/mach-pxa/eseries.c
> @@ -699,7 +699,6 @@ static struct tc6393xb_platform_data e750_tc6393xb_info = {
>         .irq_base       = IRQ_BOARD_START,
>         .scr_pll2cr     = 0x0cc1,
>         .scr_gper       = 0,
> -       .gpio_base      = -1,
>         .suspend        = &eseries_tmio_suspend,
>         .resume         = &eseries_tmio_resume,
>         .enable         = &eseries_tmio_enable,
> @@ -918,7 +917,6 @@ static struct tc6393xb_platform_data e800_tc6393xb_info = {
>         .irq_base       = IRQ_BOARD_START,
>         .scr_pll2cr     = 0x0cc1,
>         .scr_gper       = 0,
> -       .gpio_base      = -1,
>         .suspend        = &eseries_tmio_suspend,
>         .resume         = &eseries_tmio_resume,
>         .enable         = &eseries_tmio_enable,
> diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
> index 8bfaca3a8b64..3b3efa0a0e22 100644
> --- a/arch/arm/mach-pxa/include/mach/tosa.h
> +++ b/arch/arm/mach-pxa/include/mach/tosa.h
> @@ -54,24 +54,6 @@
>  /* GPIO Direction   1 : output mode / 0:input mode */
>  #define TOSA_SCOOP_JC_IO_DIR (TOSA_SCOOP_JC_CARD_LIMIT_SEL)
>
> -/*
> - * TC6393XB GPIOs
> - */
> -#define TOSA_TC6393XB_GPIO_BASE                (PXA_NR_BUILTIN_GPIO + 2 * 12)
> -
> -#define TOSA_GPIO_TG_ON                        (TOSA_TC6393XB_GPIO_BASE + 0)
> -#define TOSA_GPIO_L_MUTE               (TOSA_TC6393XB_GPIO_BASE + 1)
> -#define TOSA_GPIO_BL_C20MA             (TOSA_TC6393XB_GPIO_BASE + 3)
> -#define TOSA_GPIO_CARD_VCC_ON          (TOSA_TC6393XB_GPIO_BASE + 4)
> -#define TOSA_GPIO_CHARGE_OFF           (TOSA_TC6393XB_GPIO_BASE + 6)
> -#define TOSA_GPIO_CHARGE_OFF_JC                (TOSA_TC6393XB_GPIO_BASE + 7)
> -#define TOSA_GPIO_BAT0_V_ON            (TOSA_TC6393XB_GPIO_BASE + 9)
> -#define TOSA_GPIO_BAT1_V_ON            (TOSA_TC6393XB_GPIO_BASE + 10)
> -#define TOSA_GPIO_BU_CHRG_ON           (TOSA_TC6393XB_GPIO_BASE + 11)
> -#define TOSA_GPIO_BAT_SW_ON            (TOSA_TC6393XB_GPIO_BASE + 12)
> -#define TOSA_GPIO_BAT0_TH_ON           (TOSA_TC6393XB_GPIO_BASE + 14)
> -#define TOSA_GPIO_BAT1_TH_ON           (TOSA_TC6393XB_GPIO_BASE + 15)
> -
>  /*
>   * PXA GPIOs
>   */
> diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
> index 431709725d02..bead2ff44d3e 100644
> --- a/arch/arm/mach-pxa/tosa.c
> +++ b/arch/arm/mach-pxa/tosa.c
> @@ -616,6 +616,22 @@ static struct resource tc6393xb_resources[] = {
>         },
>  };
>
> +static struct gpiod_lookup_table tosa_battery_gpio_table = {
> +       .dev_id = "wm97xx-battery",
> +       .table = {
> +               GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_CRG,
> +                           "main battery full", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_CRG,
> +                           "jacket battery full", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_LOW,
> +                           "main battery low", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_LOW,
> +                           "jacket battery low", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_JACKET_DETECT,
> +                           "jacket detect", GPIO_ACTIVE_HIGH),
> +               { },
> +       },
> +};
>
>  static int tosa_tc6393xb_enable(struct platform_device *dev)
>  {
> @@ -709,31 +725,6 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = {
>         .part_parsers = probes,
>  };
>
> -static int tosa_tc6393xb_setup(struct platform_device *dev)
> -{
> -       int rc;
> -
> -       rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
> -       if (rc)
> -               goto err_req;
> -
> -       rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
> -       if (rc)
> -               goto err_dir;
> -
> -       return rc;
> -
> -err_dir:
> -       gpio_free(TOSA_GPIO_CARD_VCC_ON);
> -err_req:
> -       return rc;
> -}
> -
> -static void tosa_tc6393xb_teardown(struct platform_device *dev)
> -{
> -       gpio_free(TOSA_GPIO_CARD_VCC_ON);
> -}
> -
>  #ifdef CONFIG_MFD_TC6393XB
>  static struct fb_videomode tosa_tc6393xb_lcd_mode[] = {
>         {
> @@ -778,9 +769,6 @@ static struct tc6393xb_platform_data tosa_tc6393xb_data = {
>         .scr_gper       = 0x3300,
>
>         .irq_base       = IRQ_BOARD_START,
> -       .gpio_base      = TOSA_TC6393XB_GPIO_BASE,
> -       .setup          = tosa_tc6393xb_setup,
> -       .teardown       = tosa_tc6393xb_teardown,
>
>         .enable         = tosa_tc6393xb_enable,
>         .disable        = tosa_tc6393xb_disable,
> @@ -821,26 +809,6 @@ static struct pxa2xx_spi_controller pxa_ssp_master_info = {
>         .num_chipselect = 1,
>  };
>
> -static struct gpiod_lookup_table tosa_lcd_gpio_table = {
> -       .dev_id = "spi2.0",
> -       .table = {
> -               GPIO_LOOKUP("tc6393xb",
> -                           TOSA_GPIO_TG_ON - TOSA_TC6393XB_GPIO_BASE,
> -                           "tg #pwr", GPIO_ACTIVE_HIGH),
> -               { },
> -       },
> -};
> -
> -static struct gpiod_lookup_table tosa_lcd_bl_gpio_table = {
> -       .dev_id = "i2c-tosa-bl",
> -       .table = {
> -               GPIO_LOOKUP("tc6393xb",
> -                           TOSA_GPIO_BL_C20MA - TOSA_TC6393XB_GPIO_BASE,
> -                           "backlight", GPIO_ACTIVE_HIGH),
> -               { },
> -       },
> -};
> -
>  static struct spi_board_info spi_board_info[] __initdata = {
>         {
>                 .modalias       = "tosa-lcd",
> @@ -943,6 +911,8 @@ static void __init tosa_init(void)
>         /* enable batt_fault */
>         PMCR = 0x01;
>
> +       gpiod_add_lookup_table(&tosa_battery_gpio_table);
> +
>         gpiod_add_lookup_table(&tosa_mci_gpio_table);
>         pxa_set_mci_info(&tosa_mci_platform_data);
>         pxa_set_ficp_info(&tosa_ficp_platform_data);
> @@ -951,8 +921,6 @@ static void __init tosa_init(void)
>         platform_scoop_config = &tosa_pcmcia_config;
>
>         pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
> -       gpiod_add_lookup_table(&tosa_lcd_gpio_table);
> -       gpiod_add_lookup_table(&tosa_lcd_bl_gpio_table);
>         spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
>
>         clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
> diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
> index 3d5b14c60e20..886006144896 100644
> --- a/drivers/mfd/tc6393xb.c
> +++ b/drivers/mfd/tc6393xb.c
> @@ -22,6 +22,8 @@
>  #include <linux/mfd/tmio.h>
>  #include <linux/mfd/tc6393xb.h>
>  #include <linux/gpio/driver.h>
> +#include <linux/gpio/machine.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/slab.h>
>
>  #define SCR_REVID      0x08            /* b Revision ID        */
> @@ -87,8 +89,10 @@
>
>  struct tc6393xb {
>         void __iomem            *scr;
> +       struct device           *dev;
>
>         struct gpio_chip        gpio;
> +       struct gpio_desc        *vcc_on;
>
>         struct clk              *clk; /* 3,6 Mhz */
>
> @@ -497,17 +501,93 @@ static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
>         return 0;
>  }
>
> -static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb, int gpio_base)
> +/*
> + * TC6393XB GPIOs as used on TOSA, are the only user of this chip.
> + * The use of GPIOs 5, 8 and 14 is unknown.

2, 5, 8, 13 are not connected.

> + */
> +#define TOSA_GPIO_TG_ON                        0
> +#define TOSA_GPIO_L_MUTE               1
> +#define TOSA_GPIO_BL_C20MA             3
> +#define TOSA_GPIO_CARD_VCC_ON          4
> +#define TOSA_GPIO_CHARGE_OFF           6
> +#define TOSA_GPIO_CHARGE_OFF_JC                7
> +#define TOSA_GPIO_BAT0_V_ON            9
> +#define TOSA_GPIO_BAT1_V_ON            10
> +#define TOSA_GPIO_BU_CHRG_ON           11
> +#define TOSA_GPIO_BAT_SW_ON            12
> +#define TOSA_GPIO_BAT0_TH_ON           14
> +#define TOSA_GPIO_BAT1_TH_ON           15
> +
> +
> +GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb",
> +                  TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH);
> +
> +GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb",
> +                  TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH);
> +
> +GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb",
> +                  TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH);
> +
> +static struct gpiod_lookup_table tosa_battery_gpio_lookup = {
> +       .dev_id = "wm97xx-battery",
> +       .table = {
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF,
> +                           "main charge off", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC,
> +                           "jacket charge off", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON,
> +                           "main battery", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON,
> +                           "jacket battery", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON,
> +                           "backup battery", GPIO_ACTIVE_HIGH),
> +               /* BAT1 and BAT0 thermistors appear to be swapped */
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON,
> +                           "main battery temp", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON,
> +                           "jacket battery temp", GPIO_ACTIVE_HIGH),
> +               GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON,
> +                           "battery switch", GPIO_ACTIVE_HIGH),
> +               { },
> +       },
> +};
> +
> +static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = {
> +       &tosa_lcd_gpio_lookup,
> +       &tosa_lcd_bl_gpio_lookup,
> +       &tosa_audio_gpio_lookup,
> +       &tosa_battery_gpio_lookup,
> +};
> +
> +static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb)
>  {
> -       tc6393xb->gpio.label = "tc6393xb";
> -       tc6393xb->gpio.base = gpio_base;
> -       tc6393xb->gpio.ngpio = 16;
> -       tc6393xb->gpio.set = tc6393xb_gpio_set;
> -       tc6393xb->gpio.get = tc6393xb_gpio_get;
> -       tc6393xb->gpio.direction_input = tc6393xb_gpio_direction_input;
> -       tc6393xb->gpio.direction_output = tc6393xb_gpio_direction_output;
> -
> -       return gpiochip_add_data(&tc6393xb->gpio, tc6393xb);
> +       struct gpio_chip *gc = &tc6393xb->gpio;
> +       struct device *dev = tc6393xb->dev;
> +       int ret;
> +
> +       gc->label = "tc6393xb";
> +       gc->base = -1; /* Dynamic allocation */
> +       gc->ngpio = 16;
> +       gc->set = tc6393xb_gpio_set;
> +       gc->get = tc6393xb_gpio_get;
> +       gc->direction_input = tc6393xb_gpio_direction_input;
> +       gc->direction_output = tc6393xb_gpio_direction_output;
> +
> +       ret = devm_gpiochip_add_data(dev, gc, tc6393xb);
> +       if (ret)
> +               return dev_err_probe(dev, ret, "failed to add GPIO chip\n");
> +
> +       /* Register descriptor look-ups for consumers */
> +       gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups));
> +
> +       /* Request some of our own GPIOs */
> +       tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON",
> +                                                    GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
> +       if (IS_ERR(tc6393xb->vcc_on))
> +               return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on),
> +                                    "failed to request VCC ON GPIO\n");
> +
> +       return 0;
>  }
>
>  /*--------------------------------------------------------------------------*/
> @@ -617,6 +697,7 @@ static int tc6393xb_probe(struct platform_device *dev)
>                 ret = -ENOMEM;
>                 goto err_kzalloc;
>         }
> +       tc6393xb->dev = &dev->dev;
>
>         raw_spin_lock_init(&tc6393xb->lock);
>
> @@ -676,22 +757,12 @@ static int tc6393xb_probe(struct platform_device *dev)
>                         tmio_ioread8(tc6393xb->scr + SCR_REVID),
>                         (unsigned long) iomem->start, tc6393xb->irq);
>
> -       tc6393xb->gpio.base = -1;
> -
> -       if (tcpd->gpio_base >= 0) {
> -               ret = tc6393xb_register_gpio(tc6393xb, tcpd->gpio_base);
> -               if (ret)
> -                       goto err_gpio_add;
> -       }
> +       ret = tc6393xb_register_gpio(tc6393xb);
> +       if (ret)
> +               goto err_gpio_add;
>
>         tc6393xb_attach_irq(dev);
>
> -       if (tcpd->setup) {
> -               ret = tcpd->setup(dev);
> -               if (ret)
> -                       goto err_setup;
> -       }
> -
>         tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
>         tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
>                                                 sizeof(*tcpd->nand_data);
> @@ -705,15 +776,8 @@ static int tc6393xb_probe(struct platform_device *dev)
>         if (!ret)
>                 return 0;
>
> -       if (tcpd->teardown)
> -               tcpd->teardown(dev);
> -
> -err_setup:
>         tc6393xb_detach_irq(dev);
> -
>  err_gpio_add:
> -       if (tc6393xb->gpio.base != -1)
> -               gpiochip_remove(&tc6393xb->gpio);
>         tcpd->disable(dev);
>  err_enable:
>         clk_disable_unprepare(tc6393xb->clk);
> @@ -738,14 +802,8 @@ static int tc6393xb_remove(struct platform_device *dev)
>
>         mfd_remove_devices(&dev->dev);
>
> -       if (tcpd->teardown)
> -               tcpd->teardown(dev);
> -
>         tc6393xb_detach_irq(dev);
>
> -       if (tc6393xb->gpio.base != -1)
> -               gpiochip_remove(&tc6393xb->gpio);
> -
>         ret = tcpd->disable(dev);
>         clk_disable_unprepare(tc6393xb->clk);
>         iounmap(tc6393xb->scr);
> diff --git a/drivers/power/supply/tosa_battery.c b/drivers/power/supply/tosa_battery.c
> index 32cc31cd4761..272d3ee44769 100644
> --- a/drivers/power/supply/tosa_battery.c
> +++ b/drivers/power/supply/tosa_battery.c
> @@ -12,7 +12,7 @@
>  #include <linux/delay.h>
>  #include <linux/spinlock.h>
>  #include <linux/interrupt.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>
>  #include <asm/mach-types.h>
>  #include <mach/tosa.h>
> @@ -28,22 +28,23 @@ struct tosa_bat {
>         struct mutex work_lock; /* protects data */
>
>         bool (*is_present)(struct tosa_bat *bat);
> -       int gpio_full;
> -       int gpio_charge_off;
> +       struct gpio_desc *gpiod_full;
> +       struct gpio_desc *gpiod_charge_off;
>
>         int technology;
>
> -       int gpio_bat;
> +       struct gpio_desc *gpiod_bat;
>         int adc_bat;
>         int adc_bat_divider;
>         int bat_max;
>         int bat_min;
>
> -       int gpio_temp;
> +       struct gpio_desc *gpiod_temp;
>         int adc_temp;
>         int adc_temp_divider;
>  };
>
> +static struct gpio_desc *jacket_detect;
>  static struct tosa_bat tosa_bat_main;
>  static struct tosa_bat tosa_bat_jacket;
>
> @@ -51,15 +52,15 @@ static unsigned long tosa_read_bat(struct tosa_bat *bat)
>  {
>         unsigned long value = 0;
>
> -       if (bat->gpio_bat < 0 || bat->adc_bat < 0)
> +       if (!bat->gpiod_bat || bat->adc_bat < 0)
>                 return 0;
>
>         mutex_lock(&bat_lock);
> -       gpio_set_value(bat->gpio_bat, 1);
> +       gpiod_set_value(bat->gpiod_bat, 1);
>         msleep(5);
>         value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent),
>                         bat->adc_bat);
> -       gpio_set_value(bat->gpio_bat, 0);
> +       gpiod_set_value(bat->gpiod_bat, 0);
>         mutex_unlock(&bat_lock);
>
>         value = value * 1000000 / bat->adc_bat_divider;
> @@ -71,15 +72,15 @@ static unsigned long tosa_read_temp(struct tosa_bat *bat)
>  {
>         unsigned long value = 0;
>
> -       if (bat->gpio_temp < 0 || bat->adc_temp < 0)
> +       if (!bat->gpiod_temp || bat->adc_temp < 0)
>                 return 0;
>
>         mutex_lock(&bat_lock);
> -       gpio_set_value(bat->gpio_temp, 1);
> +       gpiod_set_value(bat->gpiod_temp, 1);
>         msleep(5);
>         value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent),
>                         bat->adc_temp);
> -       gpio_set_value(bat->gpio_temp, 0);
> +       gpiod_set_value(bat->gpiod_temp, 0);
>         mutex_unlock(&bat_lock);
>
>         value = value * 10000 / bat->adc_temp_divider;
> @@ -136,7 +137,7 @@ static int tosa_bat_get_property(struct power_supply *psy,
>
>  static bool tosa_jacket_bat_is_present(struct tosa_bat *bat)
>  {
> -       return gpio_get_value(TOSA_GPIO_JACKET_DETECT) == 0;
> +       return gpiod_get_value(jacket_detect) == 0;
>  }
>
>  static void tosa_bat_external_power_changed(struct power_supply *psy)
> @@ -166,23 +167,23 @@ static void tosa_bat_update(struct tosa_bat *bat)
>                 bat->full_chrg = -1;
>         } else if (power_supply_am_i_supplied(psy)) {
>                 if (bat->status == POWER_SUPPLY_STATUS_DISCHARGING) {
> -                       gpio_set_value(bat->gpio_charge_off, 0);
> +                       gpiod_set_value(bat->gpiod_charge_off, 0);
>                         mdelay(15);
>                 }
>
> -               if (gpio_get_value(bat->gpio_full)) {
> +               if (gpiod_get_value(bat->gpiod_full)) {
>                         if (old == POWER_SUPPLY_STATUS_CHARGING ||
>                                         bat->full_chrg == -1)
>                                 bat->full_chrg = tosa_read_bat(bat);
>
> -                       gpio_set_value(bat->gpio_charge_off, 1);
> +                       gpiod_set_value(bat->gpiod_charge_off, 1);
>                         bat->status = POWER_SUPPLY_STATUS_FULL;
>                 } else {
> -                       gpio_set_value(bat->gpio_charge_off, 0);
> +                       gpiod_set_value(bat->gpiod_charge_off, 0);
>                         bat->status = POWER_SUPPLY_STATUS_CHARGING;
>                 }
>         } else {
> -               gpio_set_value(bat->gpio_charge_off, 1);
> +               gpiod_set_value(bat->gpiod_charge_off, 1);
>                 bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
>         }
>
> @@ -251,18 +252,18 @@ static struct tosa_bat tosa_bat_main = {
>         .full_chrg = -1,
>         .psy = NULL,
>
> -       .gpio_full = TOSA_GPIO_BAT0_CRG,
> -       .gpio_charge_off = TOSA_GPIO_CHARGE_OFF,
> +       .gpiod_full = NULL,
> +       .gpiod_charge_off = NULL,
>
>         .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
>
> -       .gpio_bat = TOSA_GPIO_BAT0_V_ON,
> +       .gpiod_bat = NULL,
>         .adc_bat = WM97XX_AUX_ID3,
>         .adc_bat_divider = 414,
>         .bat_max = 4310000,
>         .bat_min = 1551 * 1000000 / 414,
>
> -       .gpio_temp = TOSA_GPIO_BAT1_TH_ON,
> +       .gpiod_temp = NULL,
>         .adc_temp = WM97XX_AUX_ID2,
>         .adc_temp_divider = 10000,
>  };
> @@ -273,18 +274,18 @@ static struct tosa_bat tosa_bat_jacket = {
>         .psy = NULL,
>
>         .is_present = tosa_jacket_bat_is_present,
> -       .gpio_full = TOSA_GPIO_BAT1_CRG,
> -       .gpio_charge_off = TOSA_GPIO_CHARGE_OFF_JC,
> +       .gpiod_full = NULL,
> +       .gpiod_charge_off = NULL,
>
>         .technology = POWER_SUPPLY_TECHNOLOGY_LIPO,
>
> -       .gpio_bat = TOSA_GPIO_BAT1_V_ON,
> +       .gpiod_bat = NULL,
>         .adc_bat = WM97XX_AUX_ID3,
>         .adc_bat_divider = 414,
>         .bat_max = 4310000,
>         .bat_min = 1551 * 1000000 / 414,
>
> -       .gpio_temp = TOSA_GPIO_BAT0_TH_ON,
> +       .gpiod_temp = NULL,
>         .adc_temp = WM97XX_AUX_ID2,
>         .adc_temp_divider = 10000,
>  };
> @@ -294,36 +295,20 @@ static struct tosa_bat tosa_bat_bu = {
>         .full_chrg = -1,
>         .psy = NULL,
>
> -       .gpio_full = -1,
> -       .gpio_charge_off = -1,
> +       .gpiod_full = NULL,
> +       .gpiod_charge_off = NULL,
>
>         .technology = POWER_SUPPLY_TECHNOLOGY_LiMn,
>
> -       .gpio_bat = TOSA_GPIO_BU_CHRG_ON,
> +       .gpiod_bat = NULL,
>         .adc_bat = WM97XX_AUX_ID4,
>         .adc_bat_divider = 1266,
>
> -       .gpio_temp = -1,
> +       .gpiod_temp = NULL,
>         .adc_temp = -1,
>         .adc_temp_divider = -1,
>  };
>
> -static struct gpio tosa_bat_gpios[] = {
> -       { TOSA_GPIO_CHARGE_OFF,    GPIOF_OUT_INIT_HIGH, "main charge off" },
> -       { TOSA_GPIO_CHARGE_OFF_JC, GPIOF_OUT_INIT_HIGH, "jacket charge off" },
> -       { TOSA_GPIO_BAT_SW_ON,     GPIOF_OUT_INIT_LOW,  "battery switch" },
> -       { TOSA_GPIO_BAT0_V_ON,     GPIOF_OUT_INIT_LOW,  "main battery" },
> -       { TOSA_GPIO_BAT1_V_ON,     GPIOF_OUT_INIT_LOW,  "jacket battery" },
> -       { TOSA_GPIO_BAT1_TH_ON,    GPIOF_OUT_INIT_LOW,  "main battery temp" },
> -       { TOSA_GPIO_BAT0_TH_ON,    GPIOF_OUT_INIT_LOW,  "jacket battery temp" },
> -       { TOSA_GPIO_BU_CHRG_ON,    GPIOF_OUT_INIT_LOW,  "backup battery" },
> -       { TOSA_GPIO_BAT0_CRG,      GPIOF_IN,            "main battery full" },
> -       { TOSA_GPIO_BAT1_CRG,      GPIOF_IN,            "jacket battery full" },
> -       { TOSA_GPIO_BAT0_LOW,      GPIOF_IN,            "main battery low" },
> -       { TOSA_GPIO_BAT1_LOW,      GPIOF_IN,            "jacket battery low" },
> -       { TOSA_GPIO_JACKET_DETECT, GPIOF_IN,            "jacket detect" },
> -};
> -
>  #ifdef CONFIG_PM
>  static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state)
>  {
> @@ -343,19 +328,83 @@ static int tosa_bat_resume(struct platform_device *dev)
>  #define tosa_bat_resume NULL
>  #endif
>
> -static int tosa_bat_probe(struct platform_device *dev)
> +static int tosa_bat_probe(struct platform_device *pdev)
>  {
>         int ret;
>         struct power_supply_config main_psy_cfg = {},
>                                    jacket_psy_cfg = {},
>                                    bu_psy_cfg = {};
> +       struct device *dev = &pdev->dev;
> +       struct gpio_desc *dummy;
>
>         if (!machine_is_tosa())
>                 return -ENODEV;
>
> -       ret = gpio_request_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
> -       if (ret)
> -               return ret;
> +       /* Main charging control GPIOs */
> +       tosa_bat_main.gpiod_charge_off = devm_gpiod_get(dev, "main charge off", GPIOD_OUT_HIGH);
> +       if (IS_ERR(tosa_bat_main.gpiod_charge_off))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_charge_off),
> +                                    "no main charger GPIO\n");
> +       tosa_bat_jacket.gpiod_charge_off = devm_gpiod_get(dev, "jacket charge off", GPIOD_OUT_HIGH);
> +       if (IS_ERR(tosa_bat_jacket.gpiod_charge_off))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_charge_off),
> +                                    "no jacket charger GPIO\n");
> +
> +       /* Per-battery output check (routes battery voltage to ADC) */
> +       tosa_bat_main.gpiod_bat = devm_gpiod_get(dev, "main battery", GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_bat_main.gpiod_bat))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_bat),
> +                                    "no main battery GPIO\n");
> +       tosa_bat_jacket.gpiod_bat = devm_gpiod_get(dev, "jacket battery", GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_bat_jacket.gpiod_bat))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_bat),
> +                                    "no jacket battery GPIO\n");
> +       tosa_bat_bu.gpiod_bat = devm_gpiod_get(dev, "backup battery", GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_bat_bu.gpiod_bat))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_bu.gpiod_bat),
> +                                    "no backup battery GPIO\n");
> +
> +       /* Battery full detect GPIOs (using PXA SoC GPIOs) */
> +       tosa_bat_main.gpiod_full = devm_gpiod_get(dev, "main battery full", GPIOD_IN);
> +       if (IS_ERR(tosa_bat_main.gpiod_full))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_full),
> +                                    "no main battery full GPIO\n");
> +       tosa_bat_jacket.gpiod_full = devm_gpiod_get(dev, "jacket battery full", GPIOD_IN);
> +       if (IS_ERR(tosa_bat_jacket.gpiod_full))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_full),
> +                                    "no jacket battery full GPIO\n");
> +
> +       /* Battery temperature GPIOs (routes thermistor voltage to ADC) */
> +       tosa_bat_main.gpiod_temp = devm_gpiod_get(dev, "main battery temp", GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_bat_main.gpiod_temp))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_main.gpiod_temp),
> +                                    "no main battery temp GPIO\n");
> +       tosa_bat_jacket.gpiod_temp = devm_gpiod_get(dev, "jacket battery temp", GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_bat_jacket.gpiod_temp))
> +               return dev_err_probe(dev, PTR_ERR(tosa_bat_jacket.gpiod_temp),
> +                                    "no jacket battery temp GPIO\n");
> +
> +       /* Jacket detect GPIO */
> +       jacket_detect = devm_gpiod_get(dev, "jacket detect", GPIOD_IN);
> +       if (IS_ERR(jacket_detect))
> +               return dev_err_probe(dev, PTR_ERR(jacket_detect),
> +                                    "no jacket detect GPIO\n");
> +
> +       /* Battery low indication GPIOs (not used, we just request them) */
> +       dummy = devm_gpiod_get(dev, "main battery low", GPIOD_IN);
> +       if (IS_ERR(dummy))
> +               return dev_err_probe(dev, PTR_ERR(dummy),
> +                                    "no main battery low GPIO\n");
> +       dummy = devm_gpiod_get(dev, "jacket battery low", GPIOD_IN);
> +       if (IS_ERR(dummy))
> +               return dev_err_probe(dev, PTR_ERR(dummy),
> +                                    "no jacket battery low GPIO\n");
> +
> +       /* Battery switch GPIO (not used just requested) */
> +       dummy = devm_gpiod_get(dev, "battery switch", GPIOD_OUT_LOW);
> +       if (IS_ERR(dummy))
> +               return dev_err_probe(dev, PTR_ERR(dummy),
> +                                    "no battery switch GPIO\n");
>
>         mutex_init(&tosa_bat_main.work_lock);
>         mutex_init(&tosa_bat_jacket.work_lock);
> @@ -363,7 +412,7 @@ static int tosa_bat_probe(struct platform_device *dev)
>         INIT_WORK(&bat_work, tosa_bat_work);
>
>         main_psy_cfg.drv_data = &tosa_bat_main;
> -       tosa_bat_main.psy = power_supply_register(&dev->dev,
> +       tosa_bat_main.psy = power_supply_register(dev,
>                                                   &tosa_bat_main_desc,
>                                                   &main_psy_cfg);
>         if (IS_ERR(tosa_bat_main.psy)) {
> @@ -372,7 +421,7 @@ static int tosa_bat_probe(struct platform_device *dev)
>         }
>
>         jacket_psy_cfg.drv_data = &tosa_bat_jacket;
> -       tosa_bat_jacket.psy = power_supply_register(&dev->dev,
> +       tosa_bat_jacket.psy = power_supply_register(dev,
>                                                     &tosa_bat_jacket_desc,
>                                                     &jacket_psy_cfg);
>         if (IS_ERR(tosa_bat_jacket.psy)) {
> @@ -381,28 +430,28 @@ static int tosa_bat_probe(struct platform_device *dev)
>         }
>
>         bu_psy_cfg.drv_data = &tosa_bat_bu;
> -       tosa_bat_bu.psy = power_supply_register(&dev->dev, &tosa_bat_bu_desc,
> +       tosa_bat_bu.psy = power_supply_register(dev, &tosa_bat_bu_desc,
>                                                 &bu_psy_cfg);
>         if (IS_ERR(tosa_bat_bu.psy)) {
>                 ret = PTR_ERR(tosa_bat_bu.psy);
>                 goto err_psy_reg_bu;
>         }
>
> -       ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG),
> +       ret = request_irq(gpiod_to_irq(tosa_bat_main.gpiod_full),
>                                 tosa_bat_gpio_isr,
>                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>                                 "main full", &tosa_bat_main);
>         if (ret)
>                 goto err_req_main;
>
> -       ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG),
> +       ret = request_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full),
>                                 tosa_bat_gpio_isr,
>                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>                                 "jacket full", &tosa_bat_jacket);
>         if (ret)
>                 goto err_req_jacket;
>
> -       ret = request_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT),
> +       ret = request_irq(gpiod_to_irq(jacket_detect),
>                                 tosa_bat_gpio_isr,
>                                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>                                 "jacket detect", &tosa_bat_jacket);
> @@ -411,9 +460,9 @@ static int tosa_bat_probe(struct platform_device *dev)
>                 return 0;
>         }
>
> -       free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
> +       free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket);
>  err_req_jacket:
> -       free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
> +       free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main);
>  err_req_main:
>         power_supply_unregister(tosa_bat_bu.psy);
>  err_psy_reg_bu:
> @@ -425,15 +474,14 @@ static int tosa_bat_probe(struct platform_device *dev)
>         /* see comment in tosa_bat_remove */
>         cancel_work_sync(&bat_work);
>
> -       gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
>         return ret;
>  }
>
>  static int tosa_bat_remove(struct platform_device *dev)
>  {
> -       free_irq(gpio_to_irq(TOSA_GPIO_JACKET_DETECT), &tosa_bat_jacket);
> -       free_irq(gpio_to_irq(TOSA_GPIO_BAT1_CRG), &tosa_bat_jacket);
> -       free_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), &tosa_bat_main);
> +       free_irq(gpiod_to_irq(jacket_detect), &tosa_bat_jacket);
> +       free_irq(gpiod_to_irq(tosa_bat_jacket.gpiod_full), &tosa_bat_jacket);
> +       free_irq(gpiod_to_irq(tosa_bat_main.gpiod_full), &tosa_bat_main);
>
>         power_supply_unregister(tosa_bat_bu.psy);
>         power_supply_unregister(tosa_bat_jacket.psy);
> @@ -445,7 +493,6 @@ static int tosa_bat_remove(struct platform_device *dev)
>          * unregistered now.
>          */
>         cancel_work_sync(&bat_work);
> -       gpio_free_array(tosa_bat_gpios, ARRAY_SIZE(tosa_bat_gpios));
>         return 0;
>  }
>
> diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h
> index 2647dd10b541..4d55da28e664 100644
> --- a/include/linux/gpio/machine.h
> +++ b/include/linux/gpio/machine.h
> @@ -63,6 +63,18 @@ struct gpiod_hog {
>         int dflags;
>  };
>
> +/*
> + * Helper for lookup tables with just one single lookup for a device.
> + */
> +#define GPIO_LOOKUP_SINGLE(_name, _dev_id, _key, _chip_hwnum, _con_id, _flags) \
> +static struct gpiod_lookup_table _name = {                             \
> +       .dev_id = _dev_id,                                              \
> +       .table = {                                                      \
> +               GPIO_LOOKUP(_key, _chip_hwnum, _con_id, _flags),        \
> +               {},                                                     \
> +       },                                                              \
> +}
> +
>  /*
>   * Simple definition of a single GPIO under a con_id
>   */
> diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
> index fcc8e74f0e8d..d336c541b7df 100644
> --- a/include/linux/mfd/tc6393xb.h
> +++ b/include/linux/mfd/tc6393xb.h
> @@ -27,9 +27,6 @@ struct tc6393xb_platform_data {
>         int     (*resume)(struct platform_device *dev);
>
>         int     irq_base;       /* base for subdevice irqs */
> -       int     gpio_base;
> -       int     (*setup)(struct platform_device *dev);
> -       void    (*teardown)(struct platform_device *dev);
>
>         struct tmio_nand_data   *nand_data;
>         struct tmio_fb_data     *fb_data;
> diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
> index 3b40b5fa5de7..c2b05896e284 100644
> --- a/sound/soc/pxa/tosa.c
> +++ b/sound/soc/pxa/tosa.c
> @@ -16,7 +16,7 @@
>  #include <linux/module.h>
>  #include <linux/moduleparam.h>
>  #include <linux/device.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>
>  #include <sound/core.h>
>  #include <sound/pcm.h>
> @@ -33,6 +33,7 @@
>  #define TOSA_SPK_ON    0
>  #define TOSA_SPK_OFF   1
>
> +static struct gpio_desc *tosa_mute;
>  static int tosa_jack_func;
>  static int tosa_spk_func;
>
> @@ -128,7 +129,7 @@ static int tosa_set_spk(struct snd_kcontrol *kcontrol,
>  static int tosa_hp_event(struct snd_soc_dapm_widget *w,
>         struct snd_kcontrol *k, int event)
>  {
> -       gpio_set_value(TOSA_GPIO_L_MUTE, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
> +       gpiod_set_value(tosa_mute, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0);
>         return 0;
>  }
>
> @@ -222,8 +223,11 @@ static int tosa_probe(struct platform_device *pdev)
>         struct snd_soc_card *card = &tosa;
>         int ret;
>
> -       ret = gpio_request_one(TOSA_GPIO_L_MUTE, GPIOF_OUT_INIT_LOW,
> -                              "Headphone Jack");
> +       tosa_mute = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW);
> +       if (IS_ERR(tosa_mute))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tosa_mute),
> +                                    "failed to get L_MUTE GPIO\n");
> +       gpiod_set_consumer_name(tosa_mute, "Headphone Jack");
>         if (ret)
>                 return ret;
>
> @@ -233,24 +237,16 @@ static int tosa_probe(struct platform_device *pdev)
>         if (ret) {
>                 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
>                         ret);
> -               gpio_free(TOSA_GPIO_L_MUTE);
>         }
>         return ret;
>  }
>
> -static int tosa_remove(struct platform_device *pdev)
> -{
> -       gpio_free(TOSA_GPIO_L_MUTE);
> -       return 0;
> -}
> -
>  static struct platform_driver tosa_driver = {
>         .driver         = {
>                 .name   = "tosa-audio",
>                 .pm     = &snd_soc_pm_ops,
>         },
>         .probe          = tosa_probe,
> -       .remove         = tosa_remove,
>  };
>
>  module_platform_driver(tosa_driver);
> --
> 2.34.1
>


-- 
With best wishes
Dmitry


From jkchen at linux.alibaba.com  Mon Jan 24 18:33:45 2022
From: jkchen at linux.alibaba.com (Jiankang Chen)
Date: Tue, 25 Jan 2022 10:33:45 +0800
Subject: [PATCH] coresight: tmc: change device registration from misc to
 cdev
In-Reply-To: <CANLsYkxTy3fWgKx2QotWsSC9WZSmAroiFhMkPa9HapvzZNDjRg@mail.gmail.com>
References: <20220124110018.68485-1-jkchen@linux.alibaba.com>
 <CANLsYkxTy3fWgKx2QotWsSC9WZSmAroiFhMkPa9HapvzZNDjRg@mail.gmail.com>
Message-ID: <117e6569-bd2e-830a-70e3-dd26dfae26c8@linux.alibaba.com>

Hi Mathieu

? 2022/1/25 04:08, Mathieu Poirier ??:
> On Mon, 24 Jan 2022 at 04:00, Jay Chen <jkchen at linux.alibaba.com> wrote:
>> Currently, there are 130 etr and etf on our machine,
>> but the current coresight tmc driver uses misc_register
>> to register the device, which leads to the error that
>> the device number is not enough.
>>
>> coresight-tmc: probe of xxxxx failed with error -16
>>
>> This patch changes the device registration method
>> to cdev's dynamic registration method to solve the
>> problem of insufficient device numbers.
> This patch is still not labelled properly and as such being dropped.

Hello, about the label of this patch, what kind of patch should I add?

Thanks very much

jay

>> Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
>> ---
>>   .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
>>   drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
>>   2 files changed, 91 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> index d0276af82494..0977f1ce6338 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
>> @@ -12,7 +12,6 @@
>>   #include <linux/io.h>
>>   #include <linux/err.h>
>>   #include <linux/fs.h>
>> -#include <linux/miscdevice.h>
>>   #include <linux/mutex.h>
>>   #include <linux/property.h>
>>   #include <linux/uaccess.h>
>> @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
>>   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
>>   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
>>
>> +static DEFINE_IDA(tmc_ida);
>> +static dev_t tmc_major;
>> +static struct class *tmc_class;
>> +
>> +#define TMC_DEV_MAX    (MINORMASK + 1)
>> +
>>   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
>>   {
>>          struct coresight_device *csdev = drvdata->csdev;
>> @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
>>   static int tmc_open(struct inode *inode, struct file *file)
>>   {
>>          int ret;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>
>>          ret = tmc_read_prepare(drvdata);
>>          if (ret)
>> @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>   {
>>          char *bufp;
>>          ssize_t actual;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>          actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
>>          if (actual <= 0)
>>                  return 0;
>> @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
>>   static int tmc_release(struct inode *inode, struct file *file)
>>   {
>>          int ret;
>> -       struct tmc_drvdata *drvdata = container_of(file->private_data,
>> -                                                  struct tmc_drvdata, miscdev);
>> +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
>> +                                            struct tmc_cdev, cdev);
>> +       struct tmc_drvdata *drvdata = container_of(cdev,
>> +                                                  struct tmc_drvdata, cdev);
>>
>>          ret = tmc_read_unprepare(drvdata);
>>          if (ret)
>> @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>   {
>>          int ret = 0;
>>          u32 devid;
>> +       dev_t devt;
>>          void __iomem *base;
>>          struct device *dev = &adev->dev;
>>          struct coresight_platform_data *pdata = NULL;
>> @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
>>                  goto out;
>>          }
>>
>> -       drvdata->miscdev.name = desc.name;
>> -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
>> -       drvdata->miscdev.fops = &tmc_fops;
>> -       ret = misc_register(&drvdata->miscdev);
>> +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
>> +       if (ret < 0)
>> +               goto err_coresight_unregister;
>> +
>> +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
>> +       drvdata->cdev.cdev.owner = THIS_MODULE;
>> +       devt = MKDEV(MAJOR(tmc_major), ret);
>> +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
>>          if (ret)
>> -               coresight_unregister(drvdata->csdev);
>> -       else
>> +               goto err_free_tmc_ida;
>> +
>> +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
>> +       if (IS_ERR(drvdata->cdev.dev)) {
>> +               ret = PTR_ERR(drvdata->cdev.dev);
>> +               goto err_delete_cdev;
>> +       } else
>>                  pm_runtime_put(&adev->dev);
>> +
>> +       return 0;
>> +
>> +err_delete_cdev:
>> +       cdev_del(&drvdata->cdev.cdev);
>> +err_free_tmc_ida:
>> +       ida_simple_remove(&tmc_ida, MINOR(devt));
>> +err_coresight_unregister:
>> +       coresight_unregister(drvdata->csdev);
>>   out:
>>          return ret;
>>   }
>> @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
>>   static void tmc_remove(struct amba_device *adev)
>>   {
>>          struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>> +       struct device *dev = drvdata->cdev.dev;
>>
>> -       /*
>> -        * Since misc_open() holds a refcount on the f_ops, which is
>> -        * etb fops in this case, device is there until last file
>> -        * handler to this device is closed.
>> -        */
>> -       misc_deregister(&drvdata->miscdev);
>> +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
>> +       device_destroy(tmc_class, dev->devt);
>> +       cdev_del(&drvdata->cdev.cdev);
>>          coresight_unregister(drvdata->csdev);
>>   }
>>
>> @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
>>          .id_table       = tmc_ids,
>>   };
>>
>> -module_amba_driver(tmc_driver);
>> +static int __init tmc_init(void)
>> +{
>> +       int ret;
>> +
>> +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
>> +       if (ret < 0) {
>> +               pr_err("tmc: failed to allocate char dev region\n");
>> +               return ret;
>> +       }
>> +
>> +       tmc_class = class_create(THIS_MODULE, "tmc");
>> +       if (IS_ERR(tmc_class)) {
>> +               pr_err("tmc: failed to create class\n");
>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +               return PTR_ERR(tmc_class);
>> +       }
>> +
>> +       ret = amba_driver_register(&tmc_driver);
>> +       if (ret) {
>> +               pr_err("tmc: error registering amba driver\n");
>> +               class_destroy(tmc_class);
>> +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +       }
>> +
>> +       return ret;
>> +}
>> +
>> +static void __exit tmc_exit(void)
>> +{
>> +       amba_driver_unregister(&tmc_driver);
>> +       class_destroy(tmc_class);
>> +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
>> +}
>> +
>> +module_init(tmc_init);
>> +module_exit(tmc_exit);
>>
>>   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
>>   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
>> diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
>> index 6bec20a392b3..11441c6b9c26 100644
>> --- a/drivers/hwtracing/coresight/coresight-tmc.h
>> +++ b/drivers/hwtracing/coresight/coresight-tmc.h
>> @@ -7,9 +7,9 @@
>>   #ifndef _CORESIGHT_TMC_H
>>   #define _CORESIGHT_TMC_H
>>
>> +#include <linux/cdev.h>
>>   #include <linux/dma-mapping.h>
>>   #include <linux/idr.h>
>> -#include <linux/miscdevice.h>
>>   #include <linux/mutex.h>
>>   #include <linux/refcount.h>
>>
>> @@ -163,11 +163,16 @@ struct etr_buf {
>>          void                            *private;
>>   };
>>
>> +struct tmc_cdev {
>> +       struct cdev cdev;
>> +       struct device *dev;
>> +};
>> +
>>   /**
>>    * struct tmc_drvdata - specifics associated to an TMC component
>>    * @base:      memory mapped base address for this component.
>>    * @csdev:     component vitals needed by the framework.
>> - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
>> + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
>>    * @spinlock:  only one at a time pls.
>>    * @pid:       Process ID of the process being monitored by the session
>>    *             that is using this component.
>> @@ -191,7 +196,7 @@ struct etr_buf {
>>   struct tmc_drvdata {
>>          void __iomem            *base;
>>          struct coresight_device *csdev;
>> -       struct miscdevice       miscdev;
>> +       struct tmc_cdev         cdev;
>>          spinlock_t              spinlock;
>>          pid_t                   pid;
>>          bool                    reading;
>> --
>> 2.27.0
>>


From marex at denx.de  Mon Jan 24 18:54:09 2022
From: marex at denx.de (Marek Vasut)
Date: Tue, 25 Jan 2022 03:54:09 +0100
Subject: [PATCH] arm64: dts: imx8mm: Add missing
 MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
Message-ID: <20220125025409.130667-1-marex@denx.de>

The i.MX8M Mini Application Processor Reference Manual, Rev. 3, 11/2020
documents AF MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B , add it into the
pinmux tables.

Signed-off-by: Marek Vasut <marex at denx.de>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: NXP Linux Team <linux-imx at nxp.com>
Cc: Peng Fan <peng.fan at nxp.com>
Cc: Shawn Guo <shawnguo at kernel.org>
---
 arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6af33533..a7411c800bef4 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -248,6 +248,7 @@
 #define MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15                                   0x130 0x398 0x000 0x5 0x0
 #define MX8MM_IOMUXC_NAND_RE_B_SIM_M_HADDR11                                0x130 0x398 0x000 0x7 0x0
 #define MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B                           0x134 0x39C 0x000 0x0 0x0
+#define MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B                               0x134 0x39C 0x000 0x2 0x0
 #define MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16                                0x134 0x39C 0x000 0x5 0x0
 #define MX8MM_IOMUXC_NAND_READY_B_SIM_M_HADDR12                             0x134 0x39C 0x000 0x7 0x0
 #define MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B                                 0x138 0x3A0 0x000 0x0 0x0
-- 
2.34.1



From anshuman.khandual at arm.com  Mon Jan 24 19:21:47 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 08:51:47 +0530
Subject: [PATCH V3 0/7] coresight: trbe: Workaround Cortex-A510 erratas
In-Reply-To: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <ec21e5da-7b2a-e99f-b24f-89b459e2d5cb@arm.com>



On 1/11/22 9:08 AM, Anshuman Khandual wrote:
> 	This series adds three different workarounds in the TRBE driver for
> Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
> part number definition in the platform. This series applies on 5.16.
> 
> Relevant errata documents can be found here.
> 
> https://developer.arm.com/documentation/SDEN2397239/900
> https://developer.arm.com/documentation/SDEN2397589/900
> 
> Changes in V3:
> 
> - Moved the comment inside trbe_needs_drain_after_disable()
> - Moved the comment inside trbe_needs_ctxt_sync_after_enable()
> 
> Changes in V2:
> 
> https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/
> 
> Accommodated most review comments from the previous version.
> 
> - Split all patches into CPU errata definition, detection and TRBE workarounds
> - s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
> - s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
> - s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
> - s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
> - Updated Kconfig help message for config ARM64_ERRATUM_1902691
> - Updated error message for trbe_is_broken() detection
> - Added new trblimitr parameter to set_trbe_enabled(), improving performance
> - Added COMPILE_TEST dependency in the errata, until TRBE part is available
> 
> Changes in V1:
> 
> https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> 
> Anshuman Khandual (7):
>   arm64: Add Cortex-A510 CPU part definition
>   arm64: errata: Add detection for TRBE ignored system register writes
>   arm64: errata: Add detection for TRBE invalid prohibited states
>   arm64: errata: Add detection for TRBE trace data corruption
>   coresight: trbe: Work around the ignored system register writes
>   coresight: trbe: Work around the invalid prohibited states
>   coresight: trbe: Work around the trace data corruption

Hello Catalin/Mathieu,

I am wondering how this series is going to be merged i.e via arm64 or coresight
tree ? Also will this require rebasing (and resend) against v5.17-rc1 release.
Please do suggest. Thank you.

- Anshuman


From mohammad.athari.ismail at intel.com  Mon Jan 24 19:23:22 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Tue, 25 Jan 2022 11:23:22 +0800
Subject: [PATCH net 0/2] Fix PTP issue in stmmac
Message-ID: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>

This patch series to fix PTP issue in stmmac related to:
1/ PTP clock source configuration during initialization.
2/ PTP initialization during resume from suspend.

Mohammad Athari Bin Ismail (2):
  net: stmmac: configure PTP clock source prior to PTP initialization
  net: stmmac: skip only stmmac_ptp_register when resume from suspend

 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++++--------
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  |  3 ---
 2 files changed, 14 insertions(+), 14 deletions(-)

-- 
2.17.1



From mohammad.athari.ismail at intel.com  Mon Jan 24 19:23:23 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Tue, 25 Jan 2022 11:23:23 +0800
Subject: [PATCH net 1/2] net: stmmac: configure PTP clock source prior to PTP
 initialization
In-Reply-To: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
References: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220125032324.4055-2-mohammad.athari.ismail@intel.com>

For Intel platform, it is required to configure PTP clock source prior PTP
initialization in MAC. So, need to move ptp_clk_freq_config execution from
stmmac_ptp_register() to stmmac_init_ptp().

Fixes: 76da35dc99af ("stmmac: intel: Add PSE and PCH PTP clock source selection")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..d7e261768f73 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -889,6 +889,9 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	int ret;
 
+	if (priv->plat->ptp_clk_freq_config)
+		priv->plat->ptp_clk_freq_config(priv);
+
 	ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE);
 	if (ret)
 		return ret;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0d24ebd37873..1c9f02f9c317 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -297,9 +297,6 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
 {
 	int i;
 
-	if (priv->plat->ptp_clk_freq_config)
-		priv->plat->ptp_clk_freq_config(priv);
-
 	for (i = 0; i < priv->dma_cap.pps_out_num; i++) {
 		if (i >= STMMAC_PPS_MAX)
 			break;
-- 
2.17.1



From mohammad.athari.ismail at intel.com  Mon Jan 24 19:23:24 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Tue, 25 Jan 2022 11:23:24 +0800
Subject: [PATCH net v2 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
References: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220125032324.4055-3-mohammad.athari.ismail@intel.com>

When resume from suspend, besides skipping PTP registration, it also
skipping PTP HW initialization. This could cause PTP clock not able to
operate properly when resume from suspend.

To fix this, only stmmac_ptp_register() is skipped when resume from
suspend.

Fixes: fe1319291150 ("stmmac: Don't init ptp again when resume from suspend/hibernation")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
v2 changelog:
- Fix build warning related to "function parameter or member not described".
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 22 +++++++++----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d7e261768f73..b8e5e19e6f7b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -880,11 +880,12 @@ EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter);
 /**
  * stmmac_init_ptp - init PTP
  * @priv: driver private structure
+ * @ptp_register: register PTP if set
  * Description: this is to verify if the HW supports the PTPv1 or PTPv2.
  * This is done by looking at the HW cap. register.
  * This function also registers the ptp driver.
  */
-static int stmmac_init_ptp(struct stmmac_priv *priv)
+static int stmmac_init_ptp(struct stmmac_priv *priv, bool ptp_register)
 {
 	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	int ret;
@@ -914,7 +915,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	priv->hwts_tx_en = 0;
 	priv->hwts_rx_en = 0;
 
-	stmmac_ptp_register(priv);
+	if (ptp_register)
+		stmmac_ptp_register(priv);
 
 	return 0;
 }
@@ -3241,7 +3243,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
 /**
  * stmmac_hw_setup - setup mac in a usable state.
  *  @dev : pointer to the device structure.
- *  @init_ptp: initialize PTP if set
+ *  @ptp_register: register PTP if set
  *  Description:
  *  this is the main function to setup the HW in a usable state because the
  *  dma engine is reset, the core registers are configured (e.g. AXI,
@@ -3251,7 +3253,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
  *  0 on success and an appropriate (-)ve integer as defined in errno.h
  *  file on failure.
  */
-static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	u32 rx_cnt = priv->plat->rx_queues_to_use;
@@ -3308,13 +3310,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 
 	stmmac_mmc_setup(priv);
 
-	if (init_ptp) {
-		ret = stmmac_init_ptp(priv);
-		if (ret == -EOPNOTSUPP)
-			netdev_warn(priv->dev, "PTP not supported by HW\n");
-		else if (ret)
-			netdev_warn(priv->dev, "PTP init failed\n");
-	}
+	ret = stmmac_init_ptp(priv, ptp_register);
+	if (ret == -EOPNOTSUPP)
+		netdev_warn(priv->dev, "PTP not supported by HW\n");
+	else if (ret)
+		netdev_warn(priv->dev, "PTP init failed\n");
 
 	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
 
-- 
2.17.1



From alim.akhtar at samsung.com  Mon Jan 24 19:16:02 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 25 Jan 2022 08:46:02 +0530
Subject: [PATCH v3 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <20220125031604.76009-1-alim.akhtar@samsung.com>
References: <20220125031604.76009-1-alim.akhtar@samsung.com>
 <CGME20220125032821epcas5p128c99ca3654fce0ec046943c90211849@epcas5p1.samsung.com>
Message-ID: <20220125031604.76009-2-alim.akhtar@samsung.com>

Adds spi controller dt-binding compatible information for
Tesla Full Self-Driving (FSD) SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Adithya K V <adithya.kv at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 Documentation/devicetree/bindings/spi/samsung,spi.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/spi/samsung,spi.yaml b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
index 61c77088e8ee..bf9a76d931d2 100644
--- a/Documentation/devicetree/bindings/spi/samsung,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/samsung,spi.yaml
@@ -21,6 +21,7 @@ properties:
           - samsung,s3c6410-spi
           - samsung,s5pv210-spi # for S5PV210 and S5PC110
           - samsung,exynos5433-spi
+          - tesla,fsd-spi
       - const: samsung,exynos7-spi
         deprecated: true
 
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 19:16:01 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 25 Jan 2022 08:46:01 +0530
Subject: [PATCH v3 0/3] Add FSD SPI support
References: <CGME20220125032811epcas5p3ef7b2f4e4906c1da8ccb4a0b3ed9a591@epcas5p3.samsung.com>
Message-ID: <20220125031604.76009-1-alim.akhtar@samsung.com>

Adds support for SPI controller found in Tesla FSD SoC

- Changes since v2
* Addressed review comments of Andi
* rebased on Krzysztof's v6 spi schema changes
* Added tags

-Changes since v1
* Splited SPI changes from a larger inital patch set
* Rebased on Krzysztof's latest (v5) SPI schema changes
* Added tag

Note: This series is depended on [1] patches which adds
support of FSD SoC and on Krzysztof's v6 [2] of spi schema changes

[1] https://lkml.org/lkml/2022/1/24/583
[2] https://lkml.org/lkml/2022/1/24/120


Alim Akhtar (2):
  spi: dt-bindings: samsung: Add fsd spi compatible
  spi: s3c64xx: Add spi port configuration for Tesla FSD SoC

Aswani Reddy (1):
  arm64: dts: fsd: Add SPI device nodes

 .../devicetree/bindings/spi/samsung,spi.yaml  |  1 +
 arch/arm64/boot/dts/tesla/fsd.dtsi            | 57 +++++++++++++++++++
 drivers/spi/spi-s3c64xx.c                     | 13 +++++
 3 files changed, 71 insertions(+)

-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 19:16:03 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 25 Jan 2022 08:46:03 +0530
Subject: [PATCH v3 2/3] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220125031604.76009-1-alim.akhtar@samsung.com>
References: <20220125031604.76009-1-alim.akhtar@samsung.com>
 <CGME20220125032825epcas5p2c5cf48a773fd26e089b31b0f6ddde83f@epcas5p2.samsung.com>
Message-ID: <20220125031604.76009-3-alim.akhtar@samsung.com>

Add compatible and port configuration for spi controller
for Tesla Full Self-Driving SoC.

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 drivers/spi/spi-s3c64xx.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index 386550fca81c..423518bf0270 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1440,6 +1440,16 @@ static const struct s3c64xx_spi_port_config exynos5433_spi_port_config = {
 	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
 };
 
+static struct s3c64xx_spi_port_config fsd_spi_port_config = {
+	.fifo_lvl_mask	= { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
+	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
+	.high_speed	= true,
+	.clk_from_cmu	= true,
+	.clk_ioclk	= false,
+	.quirks		= S3C64XX_SPI_QUIRK_CS_AUTO,
+};
+
 static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
 	{
 		.name		= "s3c2443-spi",
@@ -1470,6 +1480,9 @@ static const struct of_device_id s3c64xx_spi_dt_match[] = {
 	{ .compatible = "samsung,exynos5433-spi",
 			.data = (void *)&exynos5433_spi_port_config,
 	},
+	{ .compatible = "tesla,fsd-spi",
+			.data = (void *)&fsd_spi_port_config,
+	},
 	{ },
 };
 MODULE_DEVICE_TABLE(of, s3c64xx_spi_dt_match);
-- 
2.25.1



From alim.akhtar at samsung.com  Mon Jan 24 19:16:04 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Tue, 25 Jan 2022 08:46:04 +0530
Subject: [PATCH v3 3/3] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220125031604.76009-1-alim.akhtar@samsung.com>
References: <20220125031604.76009-1-alim.akhtar@samsung.com>
 <CGME20220125032828epcas5p22fbacf42ebfb1b78c1f74f48d37aa381@epcas5p2.samsung.com>
Message-ID: <20220125031604.76009-4-alim.akhtar@samsung.com>

From: Aswani Reddy <aswani.reddy at samsung.com>

Adds device tree node for SPI IPs

Cc: linux-fsd at tesla.com
Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Andi Shyti <andi at etezian.org>
---
 arch/arm64/boot/dts/tesla/fsd.dtsi | 57 ++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi
index b7f05f78c601..da4acd68b976 100644
--- a/arch/arm64/boot/dts/tesla/fsd.dtsi
+++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -29,6 +29,9 @@ aliases {
 		pinctrl0 = &pinctrl_fsys0;
 		pinctrl1 = &pinctrl_peric;
 		pinctrl2 = &pinctrl_pmu;
+		spi0 = &spi_0;
+		spi1 = &spi_1;
+		spi2 = &spi_2;
 	};
 
 	cpus {
@@ -668,6 +671,60 @@ pinctrl_fsys0: pinctrl at 15020000 {
 			reg = <0x0 0x15020000 0x0 0x1000>;
 			interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		spi_0: spi at 14140000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14140000 0x0 0x100>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 4>, <&pdma1 5>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI0>,
+				<&clock_peric PERIC_SCLK_SPI0>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi0_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_1: spi at 14150000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14150000 0x0 0x100>;
+			interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 6>, <&pdma1 7>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI1>,
+				<&clock_peric PERIC_SCLK_SPI1>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi1_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
+
+		spi_2: spi at 14160000 {
+			compatible = "tesla,fsd-spi";
+			reg = <0x0 0x14160000 0x0 0x100>;
+			interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&pdma1 8>, <&pdma1 9>;
+			dma-names = "tx", "rx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			clocks = <&clock_peric PERIC_PCLK_SPI2>,
+				<&clock_peric PERIC_SCLK_SPI2>;
+			clock-names = "spi", "spi_busclk0";
+			samsung,spi-src-clk = <0>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&spi2_bus>;
+			num-cs = <1>;
+			status = "disabled";
+		};
 	};
 };
 
-- 
2.25.1



From anshuman.khandual at arm.com  Mon Jan 24 19:36:46 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 09:06:46 +0530
Subject: [RFC V1 09/31] arm/mm: Enable ARCH_HAS_VM_GET_PAGE_PROT
In-Reply-To: <Ye7cs4fNMGPZIV2U@shell.armlinux.org.uk>
References: <1643029028-12710-1-git-send-email-anshuman.khandual@arm.com>
 <1643029028-12710-10-git-send-email-anshuman.khandual@arm.com>
 <Ye7cs4fNMGPZIV2U@shell.armlinux.org.uk>
Message-ID: <3bab7cde-f394-3e51-57a1-32be271762ae@arm.com>



On 1/24/22 10:36 PM, Russell King (Oracle) wrote:
> On Mon, Jan 24, 2022 at 06:26:46PM +0530, Anshuman Khandual wrote:
>> This defines and exports a platform specific custom vm_get_page_prot() via
>> subscribing ARCH_HAS_VM_GET_PAGE_PROT. Subsequently all __SXXX and __PXXX
>> macros can be dropped which are no longer needed.
>
> What is the fundamental advantage of this approach?
> 

Remove multiple 'core MM <--> platform' abstraction layers to map
vm_flags access permission combination into page protection. From
the cover letter ..

----------
Currently there are multiple layers of abstraction i.e __SXXX/__PXXX macros
, protection_map[], arch_vm_get_page_prot() and arch_filter_pgprot() built
between the platform and generic MM, finally defining vm_get_page_prot().

Hence this series proposes to drop all these abstraction levels and instead
just move the responsibility of defining vm_get_page_prot() to the platform
itself making it clean and simple.
----------



From chaotian.jing at mediatek.com  Mon Jan 24 19:33:35 2022
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Tue, 25 Jan 2022 11:33:35 +0800
Subject: [PATCH] mmc: mediatek: Add cmd polling mode
In-Reply-To: <20220124121814.17452-1-derong.liu@mediatek.com>
References: <20220124121814.17452-1-derong.liu@mediatek.com>
Message-ID: <f66964a5afd960fee6a2fecaf74fa902bb76a8d9.camel@mediatek.com>

On Mon, 2022-01-24 at 20:18 +0800, Derong Liu wrote:
> We found sdcard can gain more read/write performance
> when using cmd polling mode instead of interrupt mode, in the
> meantime,
> there are much more devices have equipped with high frequency cpu,
> so it is necessary to support cmd polling mode.
> 
Hi, I think you have not found the root cause of performace drop. if
the sdcard read/write performance is 100MB/s, which means that it can
complete 512KB of data xfer within 5ms, and if performance drop is 5%,
then means that your interrupt mode will take more than 250us.
Is it possible to clarify if the interrupt mode really takes 250us?

And, if you find that the polling mode is readlly fast then interrupt
mode and has no side effect(ie. cpu loading issue), then, We will drop
the interrupt mode of waiting response.
> Signed-off-by: Derong Liu <derong.liu at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 92 +++++++++++++++++++++++++++++++++++
> ----
>  1 file changed, 83 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 65037e1d7723..612f5115ca4b 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -465,6 +465,7 @@ struct msdc_host {
>  	bool hs400_tuning;	/* hs400 mode online tuning */
>  	bool internal_cd;	/* Use internal card-detect logic */
>  	bool cqhci;		/* support eMMC hw cmdq */
> +	bool cmd_polling_mode;	/* support cmd polling mode */
>  	struct msdc_save_para save_para; /* used when gate HCLK */
>  	struct msdc_tune_para def_tune_para; /* default tune setting */
>  	struct msdc_tune_para saved_tune_para; /* tune result of
> CMD21/CMD19 */
> @@ -1250,6 +1251,63 @@ static inline bool msdc_cmd_is_ready(struct
> msdc_host *host,
>  	return true;
>  }
>  
> +static inline int use_cmd_polling_mode(struct msdc_host *host,
> +	struct mmc_command *cmd)
> +{
> +	/* R1B use interrupt mode */
> +	return (host->cmd_polling_mode &&
> +			((mmc_from_priv(host))->caps2 &
> MMC_CAP2_NO_SDIO) &&
> +			(mmc_resp_type(cmd) != MMC_RSP_R1B));
> +}
> +
> +static bool msdc_command_resp_polling(struct msdc_host *host,
> +	struct mmc_request *mrq, struct mmc_command *cmd,
> +	unsigned long timeout)
> +{
> +	bool ret = false;
> +	unsigned long tmo;
> +	int events;
> +	unsigned long flags;
> +
> +	if (!use_cmd_polling_mode(host, cmd))
> +		goto exit;
> +
> +retry:
> +	tmo = jiffies + timeout;
> +	while (1) {
> +		spin_lock_irqsave(&host->lock, flags);
why need spin lock ? if there are no SDIO device irq, then there is no
race conditon of access MSDC register.
> +		events = readl(host->base + MSDC_INT);
> +		if (events & cmd_ints_mask) {
> +			/* clear all int flag */
> +			events &= cmd_ints_mask;
> +			writel(events, host->base + MSDC_INT);
> +			spin_unlock_irqrestore(&host->lock, flags);
> +			break;
> +		}
> +		spin_unlock_irqrestore(&host->lock, flags);
> +
> +		if (time_after(jiffies, tmo) &&
> +			((events & cmd_ints_mask) == 0)) {
> +			dev_info(host->dev, "[%s]: CMD<%d>
> polling_for_completion timeout ARG<0x%.8x>\n",
> +				__func__, cmd->opcode, cmd->arg);
> +			ret = msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq,
> cmd);
> +			goto exit;
> +		}
> +	}
> +
> +	if (cmd) {
> +		ret = msdc_cmd_done(host, events, mrq, cmd);
> +		/* if only autocmd23 done,
> +		 * it needs to polling the continue read/write cmd
> directly.
> +		 */
> +		if (!ret)
> +			goto retry;
> +	}
> +
> +exit:
> +	return ret;
> +}
> +
>  static void msdc_start_command(struct msdc_host *host,
>  		struct mmc_request *mrq, struct mmc_command *cmd)
>  {
> @@ -1273,7 +1331,10 @@ static void msdc_start_command(struct
> msdc_host *host,
>  	rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
>  
>  	spin_lock_irqsave(&host->lock, flags);
> -	sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> +	if (use_cmd_polling_mode(host, cmd))
> +		sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
> +	else
> +		sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
>  	spin_unlock_irqrestore(&host->lock, flags);
>  
>  	writel(cmd->arg, host->base + SDC_ARG);
> @@ -1290,9 +1351,11 @@ static void msdc_cmd_next(struct msdc_host
> *host,
>  	       host->hs400_tuning))) ||
>  	    (mrq->sbc && mrq->sbc->error))
>  		msdc_request_done(host, mrq);
> -	else if (cmd == mrq->sbc)
> +	else if (cmd == mrq->sbc) {
>  		msdc_start_command(host, mrq, mrq->cmd);
> -	else if (!cmd->data)
> +		msdc_command_resp_polling(host, mrq,
> +				mrq->cmd, CMD_TIMEOUT);
> +	} else if (!cmd->data)
>  		msdc_request_done(host, mrq);
>  	else
>  		msdc_start_data(host, cmd, cmd->data);
> @@ -1314,10 +1377,15 @@ static void msdc_ops_request(struct mmc_host
> *mmc, struct mmc_request *mrq)
>  	 * use HW option,  otherwise use SW option
>  	 */
>  	if (mrq->sbc && (!mmc_card_mmc(mmc->card) ||
> -	    (mrq->sbc->arg & 0xFFFF0000)))
> +	    (mrq->sbc->arg & 0xFFFF0000))) {
>  		msdc_start_command(host, mrq, mrq->sbc);
> -	else
> +		msdc_command_resp_polling(host, mrq,
> +				mrq->sbc, CMD_TIMEOUT);
> +	} else {
>  		msdc_start_command(host, mrq, mrq->cmd);
> +		msdc_command_resp_polling(host, mrq,
> +				mrq->cmd, CMD_TIMEOUT);
> +	}
>  }
>  
>  static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request
> *mrq)
> @@ -1350,9 +1418,11 @@ static void msdc_post_req(struct mmc_host
> *mmc, struct mmc_request *mrq,
>  static void msdc_data_xfer_next(struct msdc_host *host, struct
> mmc_request *mrq)
>  {
>  	if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop-
> >error &&
> -	    !mrq->sbc)
> +	    !mrq->sbc) {
>  		msdc_start_command(host, mrq, mrq->stop);
> -	else
> +		msdc_command_resp_polling(host, mrq,
> +				mrq->stop, CMD_TIMEOUT);
> +	} else
>  		msdc_request_done(host, mrq);
>  }
>  
> @@ -2492,11 +2562,15 @@ static void msdc_of_property_parse(struct
> platform_device *pdev,
>  	else
>  		host->hs400_cmd_resp_sel_rising = false;
>  
> -	if (of_property_read_bool(pdev->dev.of_node,
> -				  "supports-cqe"))
> +	if (of_property_read_bool(pdev->dev.of_node, "supports-cqe"))
>  		host->cqhci = true;
>  	else
>  		host->cqhci = false;
> +
> +	if (of_property_read_bool(pdev->dev.of_node, "mediatek,cmd-
> polling-mode"))
> +		host->cmd_polling_mode = true;
> +	else
> +		host->cmd_polling_mode = false;
>  }
>  
>  static int msdc_of_clock_parse(struct platform_device *pdev,

From rananta at google.com  Mon Jan 24 19:47:04 2022
From: rananta at google.com (Raghavendra Rao Ananta)
Date: Mon, 24 Jan 2022 19:47:04 -0800
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <CAOQ_QsjVk9n7X9E76ycWBNguydPE0sVvywvKW0jJ_O58A0NJHg@mail.gmail.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org> <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <877dg8ppnt.wl-maz@kernel.org> <YSfiN3Xq1vUzHeap@google.com>
 <20210827074011.ci2kzo4cnlp3qz7h@gator.home>
 <CAOQ_Qsg2dKLLanSx6nMbC1Er9DSO3peLVEAJNvU1ZcRVmwaXgQ@mail.gmail.com>
 <87ilyitt6e.wl-maz@kernel.org>
 <CAOQ_QshfXEGL691_MOJn0YbL94fchrngP8vuFReCW-=5UQtNKQ@mail.gmail.com>
 <87lf3drmvp.wl-maz@kernel.org>
 <CAOQ_QsjVk9n7X9E76ycWBNguydPE0sVvywvKW0jJ_O58A0NJHg@mail.gmail.com>
Message-ID: <CAJHc60wp4uCVQhigNrNxF3pPd_8RPHXQvK+gf7rSxCRfH6KwFg@mail.gmail.com>

Hello all,

Based on the recent discussion on the patch '[RFC PATCH v3 01/11] KVM:
Capture VM start' [1], Reiji, I (and others in the team) were
wondering, since the hypercall feature-map is technically per-VM and
not per-vCPU, would it make more sense to present it as a kvm_device,
rather than vCPU psuedo-registers to the userspace?

If I understand correctly, the original motivation for going with
pseudo-registers was to comply with QEMU, which uses KVM_GET_REG_LIST
and KVM_[GET|SET]_ONE_REG interface, but I'm guessing the VMMs doing
save/restore across migration might write the same values for every
vCPU.

Granted that we would be diverging from the existing implementation
(psci versioning and spectre WA registers), but this can be a cleaner
way forward for extending hypercall support. The kvm_device interface
can be made backward compatible with the way hypercalls are exposed
today, it can have the same registers/features discovery mechanisms
that we discussed above, and majorly the userspace has to configure it
only once per-VM. We can probably make the feature selection immutable
just before any vCPU is created.

Please let me know your thoughts or any disadvantages that I'm overlooking.

Thanks,
Raghavendra

[1]: https://lore.kernel.org/kvmarm/CAJHc60zhRyOad7AqtEFn-Ptro5BGVkfpB2wXWGw5EZMxOHUc=w at mail.gmail.com/



On Fri, Oct 1, 2021 at 8:38 AM Oliver Upton <oupton at google.com> wrote:
>
> On Fri, Oct 1, 2021 at 4:43 AM Marc Zyngier <maz at kernel.org> wrote:
> >
> > On Thu, 30 Sep 2021 18:24:23 +0100,
> > Oliver Upton <oupton at google.com> wrote:
> > >
> > > Hey Marc,
> > >
> > > On Thu, Sep 30, 2021 at 12:32 AM Marc Zyngier <maz at kernel.org> wrote:
> > > >
> > > > Hi Oliver,
> > > >
> > > > On Wed, 29 Sep 2021 19:22:05 +0100,
> > > > Oliver Upton <oupton at google.com> wrote:
> > > > >
> > > > > I have some lingering thoughts on this subject since we last spoke and
> > > > > wanted to discuss.
> > > > >
> > > > > I'm having a hard time figuring out how a VMM should handle a new
> > > > > hypercall identity register introduced on a newer kernel. In order to
> > > > > maintain guest ABI, the VMM would need to know about that register and
> > > > > zero it when restoring an older guest.
> > > >
> > > > Just as it would need to be able to discover any new system register
> > > > exposed by default, as it happens at all times. Which is why we have a
> > > > way to discover all the registers, architected or not.
> > > >
> > > > > Perhaps instead we could reserve a range of firmware registers as the
> > > > > 'hypercall identity' registers. Implement all of them as RAZ/WI by
> > > > > default, encouraging userspace to zero these registers away for older
> > > > > VMs but still allowing an old userspace to pick up new KVM features.
> > > > > Doing so would align the hypercall identity registers with the feature
> > > > > ID registers from the architecture.
> > > >
> > > > The range already exists in the form of the "coprocessor" 0x14. I
> > > > don't see the need to expose it as RAZ/WI, however. If userspace
> > > > doesn't know about how this pseudo-register works, it won't be able to
> > > > program it anyway.
> > > >
> > > > I don't buy the parallel with the ID-regs either. They are RAZ/WI by
> > > > default so that they don't UNDEF at runtime. The meaning of a RAZ
> > > > id-register is also well defined (feature not implemented), and the
> > > > CPU cannot write to them. In a way, the ID-regs *are* the enumeration
> > > > mechanism.
> > > >
> > > > Our firmware registers don't follow the same rules. Userspace can
> > > > write to them, and there is no such "not implemented" rule (case in
> > > > point, PSCI). We also have a separate enumeration mechanism
> > > > (GET_ONE_REG), which is (more or less) designed for userspace to find
> > > > what is implemented.
> > > >
> > > > For these reasons, I don't immediately see the point of advertising a
> > > > set of registers ahead of time, before userspace grows an
> > > > understanding of what these registers mean.
> > >
> > > Supposing we don't preallocate some hypercall ID registers, how can we
> > > safely migrate a guest from an older kernel to newer kernel? Ideally,
> > > we would preserve the hypercall feature set across the migration which
> > > could work for a while with the first set of registers that get
> > > defined, but whenever a new hypercall firmware register comes along
> > > then the VMM will be clueless to the new ABI.
> >
> > My expectations were that whenever userspace writes a set of firmware
> > register, all the defaults are invalidated. For example say that
> > host-A know about a single hypercall register, while host-B knows
> > about two. Upon writing to the first register, the host would clear
> > the set of available services in the second one. If userspace
> > eventually writes there, the value would stick if valid.
> >
> > Also, remember that pseudo-registers don't have to be 64bit. We could
> > define a new class of hypercall-specific registers that would be much
> > wider, and thus have a larger write granularity (KVM supports anything
> > from 8 to 2048 bits). This would make it pretty easy to implement the
> > above.
> >
> > > Fundamentally, I don't think userspace should need a patch to preserve
> > > ABI on a newer kernel. Despite that, it would seem that userspace will
> > > need to learn of any firmware registers that control hypercall
> > > features which come after the initial set that gets proposed. If
> > > KVM_GET_REG_LIST were to disambiguate between ID registers (hypercall,
> > > architectural feature ID registers) from other parts of the vCPU
> > > state, it would be clear to what registers to zero on a newer kernel.
> > > Apologies if it is distracting to mention the feature ID registers
> > > here, but both are on my mind currently and want to make sure there is
> > > some consistency in how features get handled on newer kernels,
> > > architected or not.
> >
> > The problem I see is that we will always need to grow the HC register
> > space one way or another, no matter how many we reserve. Your approach
> > only works if we don't exceed that particular range. Maybe it will
> > never be a problem, but it remains that this is not scalable.
> >
> > If we wanted to be safe, we'd reserve the whole of the possible space
> > as defined by the SMCCC spec. Given that we currently have two HC
> > spaces (the ARM-controlled one, and the KVM-specific one), the
> > function space being 16bits in each case, that's 16kB worth of zeroes
> > that userspace has to save/restore at all times... I'm not overly
> > enthusiastic.
>
> Yeah, that's definitely overkill.
>
> I agree with your position; we can solve the issue altogether by
> enforcing ordering on the hypercall registers. Userspace should read
> all hypercall registers to discover features, then write them. Given
> your suggestion, I don't know if there is much need for the guesswork
> to conclude on an appropriate register size for the hypercall bitmaps.
> 64 bits seems fine to me..
>
> --
> Thanks,
> Oliver


From ck.hu at mediatek.com  Mon Jan 24 19:44:00 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Tue, 25 Jan 2022 11:44:00 +0800
Subject: [PATCH v14 08/12] soc: mediatek: add mtk-mmsys support for
 mt8195 vdosys0
In-Reply-To: <20220107101425.6917-9-jason-jh.lin@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-9-jason-jh.lin@mediatek.com>
Message-ID: <72aa6c751db15e4aac813247c309fae622180056.camel@mediatek.com>

Hi, Jason:

On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> Add mt8195 vdosys0 clock driver name and routing table to
> the driver data of mtk-mmsys.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Acked-by: AngeloGioacchino Del Regno <
> angelogioacchino.delregno at collabora.com>
> ---
> The vdosys1 impelmentation patch [1] will be dependened on this
> patch.
> [1] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
> - 
> https://patchwork.kernel.org/project/linux-mediatek/patch/20211208024426.15595-6-nancy.lin at mediatek.com/
> ---
>  drivers/soc/mediatek/mt8195-mmsys.h    | 220
> +++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c       |  11 ++
>  include/linux/soc/mediatek/mtk-mmsys.h |   9 +
>  3 files changed, 240 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> 
> diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> b/drivers/soc/mediatek/mt8195-mmsys.h
> new file mode 100644
> index 000000000000..e04cabdfa2dc
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> @@ -0,0 +1,220 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> +
> +#define MT8195_VDO0_OVL_MOUT_EN					
> 0xf14
> +/*
> + * MT8195_VDO0_OVL_MOUT[2:0]: DISP_OVL0
> + *   BIT(0) : DISP_RDMA0
> + *   BIT(1) : DISP_WDMA0
> + *   BIT(2): DISP_OVL1

I think these information is not necessary because we could get these
information from mmsys_mt8195_routing_table[].

Regards,
CK

> + */
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
> +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> +/*
> + * MT8195_VDO0_OVL_MOUT[6:4]: DISP_OVL1
> + *   BIT(0) : DISP_RDMA1
> + *   BIT(1) : DISP_WDMA1
> + *   BIT(2): DISP_OVL0
> + */
> 

[snip]

> +
> +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] =
> {
> +	{
> +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
> +		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> +	}, {
> +		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
> +		MT8195_VDO0_OVL_MOUT_EN,
> MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
> +		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,
> +		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE,
> +		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
> +		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,
> +		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_IN,
> MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
> +		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
> +	}, {
> +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
> +		MT8195_SOUT_DISP_DITHER0_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
> +	}, {
> +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> +		MT8195_VDO0_SEL_OUT,
> MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
> +		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> +	}, {
> +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
> +		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
> +	}
> +};
> +



From christianshewitt at gmail.com  Mon Jan 24 20:03:09 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Tue, 25 Jan 2022 08:03:09 +0400
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <7h7daoyka3.fsf@baylibre.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
 <7h7daoyka3.fsf@baylibre.com>
Message-ID: <3A7E4C5F-AECB-4A3E-B074-E2E3419DD749@gmail.com>

> 
> On 25 Jan 2022, at 12:02 am, Kevin Hilman <khilman at baylibre.com> wrote:
> 
> Christian Hewitt <christianshewitt at gmail.com> writes:
> 
>> This resolves a long-running issue where Beelink GT-King/Pro and
>> GS-King-X wedge on boot or shortly after when booting from vendor
>> u-boot. In some distros the issue is often reported as triggered
>> by large file transfers to/from USB or SD cards. Reserving the
>> BL32 memory region prevents the issue.
> 
> The BL32 is typically common for the SoC family, so this change should
> probably go into the g12b.dtsi.  Or probably even
> meson-g12-common.dtsi, which is where the BL31 reserved-memory is
> described.

Hi Kevin,

Would you be okay with the same change applied to GX devices too? - I
normally have these two catch-all patches in my tree to deal with random
tv box hardware and it would be great to drop them:

https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc
https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9

Christian

From rex-bc.chen at mediatek.com  Mon Jan 24 20:13:57 2022
From: rex-bc.chen at mediatek.com (Rex-BC Chen)
Date: Tue, 25 Jan 2022 12:13:57 +0800
Subject: [v10,1/3] drm/dsi: transfer DSI HS packets ending at the same time
In-Reply-To: <dd84f8d4-097e-45b9-aa75-812b1fc524ff@intel.com>
References: <20220119022543.26093-1-rex-bc.chen@mediatek.com>
 <20220119022543.26093-2-rex-bc.chen@mediatek.com>
 <dd84f8d4-097e-45b9-aa75-812b1fc524ff@intel.com>
Message-ID: <fa61312ca706a52caf2baca398f3674d80f4cd0d.camel@mediatek.com>

Hello David and Daniel,

This patch is including modification of include/drm/drm_mipi_dsi.h.
Could you give us some suggestions for this patch?

Thanks for your big support!

BRs,
Rex-BC Chen

On Wed, 2022-01-19 at 09:34 +0100, Andrzej Hajda wrote:
> On 19.01.2022 03:25, Rex-BC Chen wrote:
> > Since a HS transmission is composed of an arbitrary number
> > of bytes that may not be an integer multiple of lanes, some
> > lanes may run out of data before others.
> > (Defined in 6.1.3 of mipi_DSI_specification_v.01-02-00)
> > 
> > However, for some DSI RX devices (for example, anx7625),
> > there is a limitation that packet number should be the same
> > on all DSI lanes. In other words, they need to end a HS at
> > the same time.
> > 
> > Because this limitation is for some specific DSI RX devices,
> > it is more reasonable to put the enable control in these
> > DSI RX drivers. If DSI TX driver knows the information,
> > they can adjust the setting for this situation.
> > 
> > Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> > Signed-off-by: Rex-BC Chen <rex-bc.chen at mediatek.com>
> > Acked-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> 
> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> 
> Regards
> 
> Andrzej
> 
> > ---
> >   include/drm/drm_mipi_dsi.h | 2 ++
> >   1 file changed, 2 insertions(+)
> > 
> > diff --git a/include/drm/drm_mipi_dsi.h
> > b/include/drm/drm_mipi_dsi.h
> > index 147e51b6d241..51e09a1a106a 100644
> > --- a/include/drm/drm_mipi_dsi.h
> > +++ b/include/drm/drm_mipi_dsi.h
> > @@ -137,6 +137,8 @@ struct mipi_dsi_host
> > *of_find_mipi_dsi_host_by_node(struct device_node *node);
> >   #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
> >   /* transmit data in low power */
> >   #define MIPI_DSI_MODE_LPM		BIT(11)
> > +/* transmit data ending at the same time for all lanes within one
> > hsync */
> > +#define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
> >   
> >   enum mipi_dsi_pixel_format {
> >   	MIPI_DSI_FMT_RGB888,



From anshuman.khandual at arm.com  Mon Jan 24 21:04:22 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 10:34:22 +0530
Subject: [RFC V1 02/11] arm64/perf: Add register definitions for BRBE
In-Reply-To: <877dap8c0o.wl-maz@kernel.org>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-3-git-send-email-anshuman.khandual@arm.com>
 <877dap8c0o.wl-maz@kernel.org>
Message-ID: <165b3f65-c92e-75e3-9485-548e1c862ec4@arm.com>



On 1/24/22 7:35 PM, Marc Zyngier wrote:
> On Mon, 24 Jan 2022 04:30:44 +0000,
> Anshuman Khandual <anshuman.khandual at arm.com> wrote:
>>
>> This adds BRBE related register definitions and various other related field
>> macros there in. These will be used subsequently in a BRBE driver which is
>> being added later on.
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/include/asm/sysreg.h | 216 ++++++++++++++++++++++++++++++++
>>  1 file changed, 216 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
>> index 898bee0004ae..d8fd7e806a47 100644
>> --- a/arch/arm64/include/asm/sysreg.h
>> +++ b/arch/arm64/include/asm/sysreg.h
>> @@ -141,6 +141,218 @@
>>  #define SYS_DBGDTRTX_EL0		sys_reg(2, 3, 0, 5, 0)
>>  #define SYS_DBGVCR32_EL2		sys_reg(2, 4, 0, 7, 0)
>>  
>> +/*
>> + * BRBINF<N>_EL1 Encoding: [2, 1, 8, CRm, op2]
>> + *
>> + * derived as <CRm> = c{N<3:0>} <op2> = (N<4>x4 + 0)
>> + */
>> +#define SYS_BRBINF0_EL1			sys_reg(2, 1, 8, 0, 0)
>> +#define SYS_BRBINF1_EL1			sys_reg(2, 1, 8, 1, 0)
>> +#define SYS_BRBINF2_EL1			sys_reg(2, 1, 8, 2, 0)
>> +#define SYS_BRBINF3_EL1			sys_reg(2, 1, 8, 3, 0)
>> +#define SYS_BRBINF4_EL1			sys_reg(2, 1, 8, 4, 0)
>> +#define SYS_BRBINF5_EL1			sys_reg(2, 1, 8, 5, 0)
>> +#define SYS_BRBINF6_EL1			sys_reg(2, 1, 8, 6, 0)
>> +#define SYS_BRBINF7_EL1			sys_reg(2, 1, 8, 7, 0)
>> +#define SYS_BRBINF8_EL1			sys_reg(2, 1, 8, 8, 0)
>> +#define SYS_BRBINF9_EL1			sys_reg(2, 1, 8, 9, 0)
> 
> [snip]
> 
> Since the architecture gives you the formula to build these, why do
> you enumerate each and every register encoding? I'd rather see
> something like:
> 
> #define __SYS_BRBINFO(n) sys_reg(2, 1, 8, ((n) & 0xf), (((n) & 0x10)) >> 2)
> #define SYS_BRBINF0_EL1	__SYS_BRBINFO(0)
> [...]
> 
> and something similar for all the new registers that come in packs of
> 32... We already have similar things for AMU, PMU, GIC and co.

Sure, above method seems like a better idea indeed. I will create these
constructs for BRBINF, BRBSRC and BRBTGT based registers set.

> 
> Thanks,
> 
> 	M.
> 
> 


From nobuta.keiya at fujitsu.com  Mon Jan 24 21:21:27 2022
From: nobuta.keiya at fujitsu.com (nobuta.keiya at fujitsu.com)
Date: Tue, 25 Jan 2022 05:21:27 +0000
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <20220117145608.6781-12-madvenka@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
Message-ID: <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>

Hi Madhavan,

> Select HAVE_RELIABLE_STACKTRACE in arm64/Kconfig to allow
> arch_stack_walk_reliable() to be used.
> 
> Note that this is conditional upon STACK_VALIDATION which will be added when frame pointer validation is implemented (say
> via objtool).

I know that Julien Thierry published objtool support for arm64 [1], but I'm not
sure if it has been updated. Could you tell me other threads if you know?

[1] https://lore.kernel.org/linux-arm-kernel/20210303170932.1838634-1-jthierry at redhat.com/


Thanks,
Keiya

> 
> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
> ---
>  arch/arm64/Kconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f6e333b59314..bc7b3514b563 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -223,6 +223,7 @@ config ARM64
>  	select THREAD_INFO_IN_TASK
>  	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
>  	select TRACE_IRQFLAGS_SUPPORT
> +	select HAVE_RELIABLE_STACKTRACE if FRAME_POINTER && STACK_VALIDATION
>  	help
>  	  ARM 64-bit (AArch64) Linux support.
> 
> --
> 2.25.1



From peng.fan at nxp.com  Mon Jan 24 21:22:15 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Tue, 25 Jan 2022 05:22:15 +0000
Subject: [PATCH] arm64: dts: imx8mm: Add missing
 MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
In-Reply-To: <20220125025409.130667-1-marex@denx.de>
References: <20220125025409.130667-1-marex@denx.de>
Message-ID: <DU0PR04MB9417B2546507165C815DB20E885F9@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH] arm64: dts: imx8mm: Add missing
> MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
> 
> The i.MX8M Mini Application Processor Reference Manual, Rev. 3, 11/2020
> documents AF MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B , add it
> into the pinmux tables.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

Reviewed-by: Peng Fan <peng.fan at nxp.com>

> ---
>  arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> index a003e6af33533..a7411c800bef4 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
> @@ -248,6 +248,7 @@
>  #define MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15
> 0x130 0x398 0x000 0x5 0x0
>  #define MX8MM_IOMUXC_NAND_RE_B_SIM_M_HADDR11
> 0x130 0x398 0x000 0x7 0x0
>  #define MX8MM_IOMUXC_NAND_READY_B_RAWNAND_READY_B
> 0x134 0x39C 0x000 0x0 0x0
> +#define MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
> 0x134 0x39C 0x000 0x2 0x0
>  #define MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16
> 0x134 0x39C 0x000 0x5 0x0
>  #define MX8MM_IOMUXC_NAND_READY_B_SIM_M_HADDR12
> 0x134 0x39C 0x000 0x7 0x0
>  #define MX8MM_IOMUXC_NAND_WE_B_RAWNAND_WE_B
> 0x138 0x3A0 0x000 0x0 0x0
> --
> 2.34.1



From tinghan.shen at mediatek.com  Mon Jan 24 22:21:33 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Tue, 25 Jan 2022 14:21:33 +0800
Subject: [PATCH v9 2/3] dt-bindings: pinctrl: mt8195: Add
 mediatek,drive-strength-adv property
In-Reply-To: <18f7a647-6153-6d38-dff1-727b9592b01e@gmail.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
 <20220112114724.1953-3-tinghan.shen@mediatek.com>
 <18f7a647-6153-6d38-dff1-727b9592b01e@gmail.com>
Message-ID: <102ea6303dd16fdf9ec931d0a1845a93afe92545.camel@mediatek.com>

On Thu, 2022-01-13 at 17:31 +0100, Matthias Brugger wrote:
> [dopping Maciej, Paolo and Sean Christopherson]
> 
> On 12/01/2022 12:47, Tinghan Shen wrote:
> > Extend driving support for I2C pins on SoC mt8195.
> > This property is already documented in mediatek,mt8183-pinctrl.yaml.
> > 
> > Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
> > Reviewed-by: Rob Herring <robh at kernel.org>
> 
> Looks good to me. Linus please let me know when you are queuing this patch and 
> I'll take the rest of the series. Another option is, that you provide an 
> Acked-by and I can take the whole set through my branch.
> 
> Regards,
> Matthias

Hi Matthias,

I want to send next version to update the CC list of this series, but I'm not sure 
whether this will break the conversation between you and Linus.

Is it ok to send next version? or waiting the response?

Best regards,
TingHan

> 
> > ---
> >   .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
> >   1 file changed, 35 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > index 328ea59c5466..4db4899af6b1 100644
> > --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
> > @@ -98,6 +98,32 @@ patternProperties:
> >             drive-strength:
> >               enum: [2, 4, 6, 8, 10, 12, 14, 16]
> >   
> > +          mediatek,drive-strength-adv:
> > +            description: |
> > +              Describe the specific driving setup property.
> > +              For I2C pins, the existing generic driving setup can only support
> > +              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
> > +              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
> > +              driving setup, the existing generic setup will be disabled.
> > +              The specific driving setup is controlled by E1E0EN.
> > +              When E1=0/E0=0, the strength is 0.125mA.
> > +              When E1=0/E0=1, the strength is 0.25mA.
> > +              When E1=1/E0=0, the strength is 0.5mA.
> > +              When E1=1/E0=1, the strength is 1mA.
> > +              EN is used to enable or disable the specific driving setup.
> > +              Valid arguments are described as below:
> > +              0: (E1, E0, EN) = (0, 0, 0)
> > +              1: (E1, E0, EN) = (0, 0, 1)
> > +              2: (E1, E0, EN) = (0, 1, 0)
> > +              3: (E1, E0, EN) = (0, 1, 1)
> > +              4: (E1, E0, EN) = (1, 0, 0)
> > +              5: (E1, E0, EN) = (1, 0, 1)
> > +              6: (E1, E0, EN) = (1, 1, 0)
> > +              7: (E1, E0, EN) = (1, 1, 1)
> > +              So the valid arguments are from 0 to 7.
> > +            $ref: /schemas/types.yaml#/definitions/uint32
> > +            enum: [0, 1, 2, 3, 4, 5, 6, 7]
> > +
> >             bias-pull-down:
> >               description: |
> >                 For pull down type is normal, it don't need add RSEL & R1R0 define
> > @@ -268,4 +294,13 @@ examples:
> >             bias-pull-down;
> >           };
> >         };
> > +
> > +      i2c0-pins {
> > +        pins {
> > +          pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
> > +                   <PINMUX_GPIO9__FUNC_SCL0>;
> > +          bias-disable;
> > +          mediatek,drive-strength-adv = <7>;
> > +        };
> > +      };
> >       };
> > 



From reijiw at google.com  Mon Jan 24 22:31:03 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Mon, 24 Jan 2022 22:31:03 -0800
Subject: [RFC PATCH v4 00/26] KVM: arm64: Make CPU ID registers writable
 by userspace
In-Reply-To: <CA+EHjTz1=Nwd97GzagkAqZ08m-yGUHeujmtX45mLDD1beF8Ykg@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <CA+EHjTz1=Nwd97GzagkAqZ08m-yGUHeujmtX45mLDD1beF8Ykg@mail.gmail.com>
Message-ID: <CAAeT=FzC4U380ZhhxFgZ0xa5xae2ZUf5uFOOfjT2RA6K2btX_w@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 8:19 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:27 AM Reiji Watanabe <reijiw at google.com> wrote:
>
> > The patch series is for both VHE and non-VHE, except for protected VMs,
> > which have a different way of configuring ID registers based on its
> > different requirements [1].
>
> I am reviewing this patch series and I really like your approach. I
> think that once it's through we might be able to generalize it for
> protected VMs as well (I did some of the work for the ID registers for
> those).

Thank you for the review and comments for the series.
I will be looking at your comments.

> > The series is based on v5.16-rc8 with the patch [3] applied.
>
> I tried to apply this series on v5.16-rc8 after applying
> 20220104194918.373612-2-rananta at google.com, and it didn't apply
> cleanly. If you could point me to a working branch that I could
> checkout I would like to test it and experiment with it a bit more.

I'm sorry for the inconvenience.  I'm not sure why though...
I tried that again (applied the series on v5.16-rc8 after applying
20220104194918.373612-2-rananta at google.com), and it worked fine.

Anyway, you can find the branch at:
 https://github.com/reijiw-kvm/kvmarm-idreg/tree/id-regs-v4-5.16-rc8

Thanks,
Reiji


>
>
>
>
> > v4:
> >   - Make ID registers storage per VM instead of per vCPU. [Marc]
> >   - Implement arm64_check_features() in arch/arm64/kernel/cpufeature.c
> >     by using existing codes in the file. [Marc]
> >   - Use a configuration function to enable traps for disabled
> >     features. [Marc]
> >   - Document ID registers become immutable after the first KVM_RUN [Eric]
> >   - Update ID_AA64PFR0.GIC at the point where a GICv3 is created. [Marc]
> >   - Get TGranX's bit position by substracting 12 from TGranX_2's bit
> >     position. [Eric]
> >   - Don't validate AArch32 ID registers when the system doesn't support
> >     32bit EL0. [Eric]
> >   - Add/fixes comments for patches. [Eric]
> >   - Made bug fixes/improvements of the selftest. [Eric]
> >   - Added .kunitconfig for arm64 KUnit tests
> >
> > v3: https://lore.kernel.org/all/20211117064359.2362060-1-reijiw at google.com/
> >   - Remove ID register consistency checking across vCPUs. [Oliver]
> >   - Change KVM_CAP_ARM_ID_REG_WRITABLE to
> >     KVM_CAP_ARM_ID_REG_CONFIGURABLE. [Oliver]
> >   - Add KUnit testing for ID register validation and trap initialization.
> >   - Change read_id_reg() to take care of ID_AA64PFR0_EL1.GIC.
> >   - Add a helper of read_id_reg() (__read_id_reg()) and use the helper
> >     instead of directly using __vcpu_sys_reg().
> >   - Change not to run kvm_id_regs_consistency_check() and
> >     kvm_vcpu_init_traps() for protected VMs.
> >   - Update selftest to remove test cases for ID register consistency.
> >     checking across vCPUs and to add test cases for ID_AA64PFR0_EL1.GIC.
> >
> > v2: https://lore.kernel.org/all/20211103062520.1445832-1-reijiw at google.com/
> >   - Remove unnecessary line breaks. [Andrew]
> >   - Use @params for comments. [Andrew]
> >   - Move arm64_check_features to arch/arm64/kvm/sys_regs.c and
> >     change that KVM specific feature check function.  [Andrew]
> >   - Remove unnecessary raz handling from __set_id_reg. [Andrew]
> >   - Remove sys_val field from the initial id_reg_info and add it
> >     in the later patch. [Andrew]
> >   - Call id_reg->init() from id_reg_info_init(). [Andrew]
> >   - Fix cpuid_feature_cap_perfmon_field() to convert 0xf to 0x0
> >     (and use it in the following patches).
> >   - Change kvm_vcpu_first_run_init to set has_run_once to false
> >     when kvm_id_regs_consistency_check() fails.
> >   - Add a patch to introduce id_reg_info for ID_AA64MMFR0_EL1,
> >     which requires special validity checking for TGran*_2 fields.
> >   - Add patches to introduce id_reg_info for ID_DFR1_EL1 and
> >     ID_MMFR0_EL1, which are required due to arm64_check_features
> >     implementation change.
> >   - Add a new argument, which is a pointer to id_reg_info, for
> >     id_reg_info's validate().
> >
> > v1: https://lore.kernel.org/all/20211012043535.500493-1-reijiw at google.com/
> >
> > [1] https://lore.kernel.org/kvmarm/20211010145636.1950948-1-tabba at google.com/
> > [2] https://lore.kernel.org/kvm/20201102033422.657391-1-liangpeng10 at huawei.com/
> > [3] https://lore.kernel.org/all/20220104194918.373612-2-rananta at google.com/
> >
> > Reiji Watanabe (26):
> >   KVM: arm64: Introduce a validation function for an ID register
> >   KVM: arm64: Save ID registers' sanitized value per guest
> >   KVM: arm64: Introduce struct id_reg_info
> >   KVM: arm64: Make ID_AA64PFR0_EL1 writable
> >   KVM: arm64: Make ID_AA64PFR1_EL1 writable
> >   KVM: arm64: Make ID_AA64ISAR0_EL1 writable
> >   KVM: arm64: Make ID_AA64ISAR1_EL1 writable
> >   KVM: arm64: Make ID_AA64MMFR0_EL1 writable
> >   KVM: arm64: Hide IMPLEMENTATION DEFINED PMU support for the guest
> >   KVM: arm64: Make ID_AA64DFR0_EL1 writable
> >   KVM: arm64: Make ID_DFR0_EL1 writable
> >   KVM: arm64: Make MVFR1_EL1 writable
> >   KVM: arm64: Make ID registers without id_reg_info writable
> >   KVM: arm64: Add consistency checking for frac fields of ID registers
> >   KVM: arm64: Introduce KVM_CAP_ARM_ID_REG_CONFIGURABLE capability
> >   KVM: arm64: Add kunit test for ID register validation
> >   KVM: arm64: Use vcpu->arch cptr_el2 to track value of cptr_el2 for VHE
> >   KVM: arm64: Use vcpu->arch.mdcr_el2 to track value of mdcr_el2
> >   KVM: arm64: Introduce framework to trap disabled features
> >   KVM: arm64: Trap disabled features of ID_AA64PFR0_EL1
> >   KVM: arm64: Trap disabled features of ID_AA64PFR1_EL1
> >   KVM: arm64: Trap disabled features of ID_AA64DFR0_EL1
> >   KVM: arm64: Trap disabled features of ID_AA64MMFR1_EL1
> >   KVM: arm64: Trap disabled features of ID_AA64ISAR1_EL1
> >   KVM: arm64: Add kunit test for trap initialization
> >   KVM: arm64: selftests: Introduce id_reg_test
> >
> >  Documentation/virt/kvm/api.rst                |   12 +
> >  arch/arm64/include/asm/cpufeature.h           |    3 +-
> >  arch/arm64/include/asm/kvm_arm.h              |   32 +
> >  arch/arm64/include/asm/kvm_host.h             |   19 +
> >  arch/arm64/include/asm/sysreg.h               |    3 +
> >  arch/arm64/kernel/cpufeature.c                |  228 +++
> >  arch/arm64/kvm/.kunitconfig                   |    4 +
> >  arch/arm64/kvm/Kconfig                        |   11 +
> >  arch/arm64/kvm/arm.c                          |   24 +-
> >  arch/arm64/kvm/debug.c                        |   13 +-
> >  arch/arm64/kvm/hyp/vhe/switch.c               |   14 +-
> >  arch/arm64/kvm/sys_regs.c                     | 1329 +++++++++++++++--
> >  arch/arm64/kvm/sys_regs_test.c                | 1247 ++++++++++++++++
> >  arch/arm64/kvm/vgic/vgic-init.c               |    5 +
> >  include/uapi/linux/kvm.h                      |    1 +
> >  tools/arch/arm64/include/asm/sysreg.h         |    1 +
> >  tools/testing/selftests/kvm/.gitignore        |    1 +
> >  tools/testing/selftests/kvm/Makefile          |    1 +
> >  .../selftests/kvm/aarch64/id_reg_test.c       | 1239 +++++++++++++++
> >  19 files changed, 4041 insertions(+), 146 deletions(-)
> >  create mode 100644 arch/arm64/kvm/.kunitconfig
> >  create mode 100644 arch/arm64/kvm/sys_regs_test.c
> >  create mode 100644 tools/testing/selftests/kvm/aarch64/id_reg_test.c
> >
> >
> > base-commit: d399b107ee49bf5ea0391bd7614d512809e927b0
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm at lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From ebiggers at kernel.org  Mon Jan 24 22:40:42 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Mon, 24 Jan 2022 22:40:42 -0800
Subject: [PATCH v2] lib/crypto: blake2s: avoid indirect calls to
 compression function for Clang CFI
In-Reply-To: <20220124192849.14755-1-Jason@zx2c4.com>
References: <20220119135450.564115-1-Jason@zx2c4.com>
 <20220124192849.14755-1-Jason@zx2c4.com>
Message-ID: <Ye+bam3aSIjz8n9E@sol.localdomain>

On Mon, Jan 24, 2022 at 08:28:49PM +0100, Jason A. Donenfeld wrote:
> blake2s_compress_generic is weakly aliased by blake2s_generic. The

Don't you mean "weakly aliased by blake2s_compress"?

> Fixes: 6048fdcc5f26 ("lib/crypto: blake2s: include as built-in")
> Reported-by: Miles Chen <miles.chen at mediatek.com>
> Tested-by: Miles Chen <miles.chen at mediatek.com>
> Tested-by: Nathan Chancellor <nathan at kernel.org>
> Link: https://github.com/ClangBuiltLinux/linux/issues/1567
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Cc: Sami Tolvanen <samitolvanen at google.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Signed-off-by: Jason A. Donenfeld <Jason at zx2c4.com>
> ---

Otherwise this looks fine, though it's unfortunate this is needed.  You can add:

	Reviewed-by: Eric Biggers <ebiggers at google.com>

> Changes v1->v2:
> - Wrapped columns at 80 for Eric.

It is the recommended coding style, so not just for me :-)

- Eric


From jammy_huang at aspeedtech.com  Mon Jan 24 22:44:06 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 25 Jan 2022 14:44:06 +0800
Subject: [PATCH v4 0/3] Correct timing report
Message-ID: <20220125064409.5502-1-jammy_huang@aspeedtech.com>

This series will correct the value of timing detected.

Changes in v4:
 - Combine patch 3 and 4
Changes in v3:
 - Add API, aspeed_video_get_timings(), for the calculation of timings
 - Use active rather than 'total/2' as critera for sync polarity workaround
Changes in v2:
 - code refined to improve readability

Jammy Huang (3):
  media: aspeed: Correct value for h-total-pixels
  media: aspeed: Use FIELD_GET to improve readability
  media: aspeed: Correct values for detected timing

 drivers/media/platform/aspeed-video.c | 137 ++++++++++++++++++++------
 1 file changed, 109 insertions(+), 28 deletions(-)

-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 22:44:07 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 25 Jan 2022 14:44:07 +0800
Subject: [PATCH v4 1/3] media: aspeed: Correct value for h-total-pixels
In-Reply-To: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
References: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
Message-ID: <20220125064409.5502-2-jammy_huang@aspeedtech.com>

Previous reg-field, 0x98[11:0], stands for the period of the detected
hsync signal.
Use the correct reg, 0xa0, to get h-total in pixels.

Fixes: d2b4387f3bdf ("media: platform: Add Aspeed Video Engine driver")
Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
v4:
 - no update
v3:
 - no update
v2:
 - no update
---
 drivers/media/platform/aspeed-video.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index b388bc56ce81..d5f77b205175 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -166,7 +166,7 @@
 #define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
 
 #define VE_MODE_DETECT_STATUS		0x098
-#define  VE_MODE_DETECT_H_PIXELS	GENMASK(11, 0)
+#define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
 #define  VE_MODE_DETECT_V_LINES_SHF	16
 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
@@ -177,6 +177,8 @@
 #define  VE_SYNC_STATUS_VSYNC_SHF	16
 #define  VE_SYNC_STATUS_VSYNC		GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
 
+#define VE_H_TOTAL_PIXELS		0x0A0
+
 #define VE_INTERRUPT_CTRL		0x304
 #define VE_INTERRUPT_STATUS		0x308
 #define  VE_INTERRUPT_MODE_DETECT_WD	BIT(0)
@@ -938,6 +940,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	u32 src_lr_edge;
 	u32 src_tb_edge;
 	u32 sync;
+	u32 htotal;
 	struct v4l2_bt_timings *det = &video->detected_timings;
 
 	det->width = MIN_WIDTH;
@@ -983,6 +986,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 		src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
 		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
 		sync = aspeed_video_read(video, VE_SYNC_STATUS);
+		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
 		video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
 			VE_SRC_TB_EDGE_DET_BOT_SHF;
@@ -999,8 +1003,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 			VE_SRC_LR_EDGE_DET_RT_SHF;
 		video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
 		det->hfrontporch = video->frame_left;
-		det->hbackporch = (mds & VE_MODE_DETECT_H_PIXELS) -
-			video->frame_right;
+		det->hbackporch = htotal - video->frame_right;
 		det->hsync = sync & VE_SYNC_STATUS_HSYNC;
 		if (video->frame_left > video->frame_right)
 			continue;
-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 22:44:09 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 25 Jan 2022 14:44:09 +0800
Subject: [PATCH v4 3/3] media: aspeed: Correct values for detected timing
In-Reply-To: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
References: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
Message-ID: <20220125064409.5502-4-jammy_huang@aspeedtech.com>

Correct timing's fp/sync/bp value based on the information below.
It should be noticed that the calculation formula should be changed
per sync polarity.

The sequence of signal: sync - backporch - video data - frontporch

The following registers start counting from sync's rising edge:
1. VR090: frame edge's left and right
2. VR094: frame edge's top and bottom
3. VR09C: counting from sync's rising edge to falling edge

[Vertical timing]
            +--+     +-------------------+     +--+
            |  |     |     v i d e o     |     |  |
         +--+  +-----+                   +-----+  +---+
       vsync+--+
   frame_top+--------+
frame_bottom+----------------------------+

                  +-------------------+
                  |     v i d e o     |
      +--+  +-----+                   +-----+  +---+
         |  |                               |  |
         +--+                               +--+
       vsync+-------------------------------+
   frame_top+-----+
frame_bottom+-------------------------+

[Horizontal timing]
            +--+     +-------------------+     +--+
            |  |     |     v i d e o     |     |  |
         +--+  +-----+                   +-----+  +---+
       hsync+--+
  frame_left+--------+
 frame_right+----------------------------+

                  +-------------------+
                  |     v i d e o     |
      +--+  +-----+                   +-----+  +---+
         |  |                               |  |
         +--+                               +--+
       hsync+-------------------------------+
  frame_left+-----+
 frame_right+-------------------------+

Ex. 1920x1200 at 60 whose vsync polarity is negative
  VR098: c4d3efff, VR09C: 04cc001f
  v-total = 0x4D3 (VR098[27:16]) = 1235
  v-sync  = 0x4CC (VR09C[27:16]) = 1228

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 v4:
  - Combine this one with patch 4
 v3:
  - Add API, aspeed_video_get_timings(), to handle the calculation of timings.
 v2:
  - Code refined per Joel's suggestion
  - Update commit message to have name matching variable
---
 drivers/media/platform/aspeed-video.c | 109 +++++++++++++++++++++++---
 1 file changed, 97 insertions(+), 12 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index c241038ee27c..90cdc6fe0caa 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -925,6 +925,99 @@ static void aspeed_video_calc_compressed_size(struct aspeed_video *video,
 		 video->max_compressed_size);
 }
 
+/*
+ * Update v4l2_bt_timings per current status.
+ * frame_top/frame_bottom/frame_left/frame_right need to be ready.
+ *
+ * The following registers start counting from sync's rising edge:
+ * 1. VR090: frame edge's left and right
+ * 2. VR094: frame edge's top and bottom
+ * 3. VR09C: counting from sync's rising edge to falling edge
+ *
+ * [Vertical timing]
+ *             +--+     +-------------------+     +--+
+ *             |  |     |     v i d e o     |     |  |
+ *          +--+  +-----+                   +-----+  +---+
+ *        vsync+--+
+ *    frame_top+--------+
+ * frame_bottom+----------------------------+
+ *
+ *                   +-------------------+
+ *                   |     v i d e o     |
+ *       +--+  +-----+                   +-----+  +---+
+ *          |  |                               |  |
+ *          +--+                               +--+
+ *        vsync+-------------------------------+
+ *    frame_top+-----+
+ * frame_bottom+-------------------------+
+ *
+ * [Horizontal timing]
+ *             +--+     +-------------------+     +--+
+ *             |  |     |     v i d e o     |     |  |
+ *          +--+  +-----+                   +-----+  +---+
+ *        hsync+--+
+ *   frame_left+--------+
+ *  frame_right+----------------------------+
+ *
+ *                   +-------------------+
+ *                   |     v i d e o     |
+ *       +--+  +-----+                   +-----+  +---+
+ *          |  |                               |  |
+ *          +--+                               +--+
+ *        hsync+-------------------------------+
+ *   frame_left+-----+
+ *  frame_right+-------------------------+
+ *
+ * @v: the struct of aspeed_video
+ * @det: v4l2_bt_timings to be updated.
+ */
+static void aspeed_video_get_timings(struct aspeed_video *v,
+				     struct v4l2_bt_timings *det)
+{
+	u32 mds, sync, htotal, vtotal, vsync, hsync;
+
+	mds = aspeed_video_read(v, VE_MODE_DETECT_STATUS);
+	sync = aspeed_video_read(v, VE_SYNC_STATUS);
+	htotal = aspeed_video_read(v, VE_H_TOTAL_PIXELS);
+	vtotal = FIELD_GET(VE_MODE_DETECT_V_LINES, mds);
+	vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
+	hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
+
+	/*
+	 * This is a workaround for polarity detection.
+	 * Because ast-soc counts sync from sync's rising edge, the reg value
+	 * of sync would be larger than video's active area if negative.
+	 */
+	if (vsync > det->height)
+		det->polarities &= ~V4L2_DV_VSYNC_POS_POL;
+	else
+		det->polarities |= V4L2_DV_VSYNC_POS_POL;
+	if (hsync > det->width)
+		det->polarities &= ~V4L2_DV_HSYNC_POS_POL;
+	else
+		det->polarities |= V4L2_DV_HSYNC_POS_POL;
+
+	if (det->polarities & V4L2_DV_VSYNC_POS_POL) {
+		det->vbackporch = v->frame_top - vsync;
+		det->vfrontporch = vtotal - v->frame_bottom;
+		det->vsync = vsync;
+	} else {
+		det->vbackporch = v->frame_top;
+		det->vfrontporch = vsync - v->frame_bottom;
+		det->vsync = vtotal - vsync;
+	}
+
+	if (det->polarities & V4L2_DV_HSYNC_POS_POL) {
+		det->hbackporch = v->frame_left - hsync;
+		det->hfrontporch = htotal - v->frame_right;
+		det->hsync = hsync;
+	} else {
+		det->hbackporch = v->frame_left;
+		det->hfrontporch = hsync - v->frame_right;
+		det->hsync = htotal - hsync;
+	}
+}
+
 #define res_check(v) test_and_clear_bit(VIDEO_MODE_DETECT_DONE, &(v)->flags)
 
 static void aspeed_video_get_resolution(struct aspeed_video *video)
@@ -935,8 +1028,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	u32 mds;
 	u32 src_lr_edge;
 	u32 src_tb_edge;
-	u32 sync;
-	u32 htotal;
 	struct v4l2_bt_timings *det = &video->detected_timings;
 
 	det->width = MIN_WIDTH;
@@ -980,24 +1071,16 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 
 		src_lr_edge = aspeed_video_read(video, VE_SRC_LR_EDGE_DET);
 		src_tb_edge = aspeed_video_read(video, VE_SRC_TB_EDGE_DET);
-		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
-		sync = aspeed_video_read(video, VE_SYNC_STATUS);
-		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
 		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
 		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
-		det->vfrontporch = video->frame_top;
-		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
-			video->frame_bottom;
-		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
+
 		if (video->frame_top > video->frame_bottom)
 			continue;
 
 		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
 		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
-		det->hfrontporch = video->frame_left;
-		det->hbackporch = htotal - video->frame_right;
-		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
+
 		if (video->frame_left > video->frame_right)
 			continue;
 
@@ -1013,6 +1096,8 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	det->width = (video->frame_right - video->frame_left) + 1;
 	video->v4l2_input_status = 0;
 
+	aspeed_video_get_timings(video, det);
+
 	/*
 	 * Enable mode-detect watchdog, resolution-change watchdog and
 	 * automatic compression after frame capture.
-- 
2.25.1



From jammy_huang at aspeedtech.com  Mon Jan 24 22:44:08 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Tue, 25 Jan 2022 14:44:08 +0800
Subject: [PATCH v4 2/3] media: aspeed: Use FIELD_GET to improve readability
In-Reply-To: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
References: <20220125064409.5502-1-jammy_huang@aspeedtech.com>
Message-ID: <20220125064409.5502-3-jammy_huang@aspeedtech.com>

Use the bitfield macro FIELD_GET, and GENMASK to do the shift and mask in
one go for reg values.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
Reviewed-by: Joel Stanley <joel at jms.id.au>
---
 v4:
  - no update
 v3:
  - no update
 v2:
  - Put some codes on one line
---
 drivers/media/platform/aspeed-video.c | 31 +++++++++++----------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index d5f77b205175..c241038ee27c 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -156,26 +156,22 @@
 #define  VE_SRC_LR_EDGE_DET_NO_H	BIT(13)
 #define  VE_SRC_LR_EDGE_DET_NO_DISP	BIT(14)
 #define  VE_SRC_LR_EDGE_DET_NO_CLK	BIT(15)
-#define  VE_SRC_LR_EDGE_DET_RT_SHF	16
-#define  VE_SRC_LR_EDGE_DET_RT		GENMASK(27, VE_SRC_LR_EDGE_DET_RT_SHF)
+#define  VE_SRC_LR_EDGE_DET_RT		GENMASK(27, 16)
 #define  VE_SRC_LR_EDGE_DET_INTERLACE	BIT(31)
 
 #define VE_SRC_TB_EDGE_DET		0x094
 #define  VE_SRC_TB_EDGE_DET_TOP		GENMASK(12, 0)
-#define  VE_SRC_TB_EDGE_DET_BOT_SHF	16
-#define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, VE_SRC_TB_EDGE_DET_BOT_SHF)
+#define  VE_SRC_TB_EDGE_DET_BOT		GENMASK(28, 16)
 
 #define VE_MODE_DETECT_STATUS		0x098
 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
-#define  VE_MODE_DETECT_V_LINES_SHF	16
-#define  VE_MODE_DETECT_V_LINES		GENMASK(27, VE_MODE_DETECT_V_LINES_SHF)
+#define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
 
 #define VE_SYNC_STATUS			0x09c
 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
-#define  VE_SYNC_STATUS_VSYNC_SHF	16
-#define  VE_SYNC_STATUS_VSYNC		GENMASK(27, VE_SYNC_STATUS_VSYNC_SHF)
+#define  VE_SYNC_STATUS_VSYNC		GENMASK(27, 16)
 
 #define VE_H_TOTAL_PIXELS		0x0A0
 
@@ -988,23 +984,20 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 		sync = aspeed_video_read(video, VE_SYNC_STATUS);
 		htotal = aspeed_video_read(video, VE_H_TOTAL_PIXELS);
 
-		video->frame_bottom = (src_tb_edge & VE_SRC_TB_EDGE_DET_BOT) >>
-			VE_SRC_TB_EDGE_DET_BOT_SHF;
-		video->frame_top = src_tb_edge & VE_SRC_TB_EDGE_DET_TOP;
+		video->frame_bottom = FIELD_GET(VE_SRC_TB_EDGE_DET_BOT, src_tb_edge);
+		video->frame_top = FIELD_GET(VE_SRC_TB_EDGE_DET_TOP, src_tb_edge);
 		det->vfrontporch = video->frame_top;
-		det->vbackporch = ((mds & VE_MODE_DETECT_V_LINES) >>
-			VE_MODE_DETECT_V_LINES_SHF) - video->frame_bottom;
-		det->vsync = (sync & VE_SYNC_STATUS_VSYNC) >>
-			VE_SYNC_STATUS_VSYNC_SHF;
+		det->vbackporch = FIELD_GET(VE_MODE_DETECT_V_LINES, mds) -
+			video->frame_bottom;
+		det->vsync = FIELD_GET(VE_SYNC_STATUS_VSYNC, sync);
 		if (video->frame_top > video->frame_bottom)
 			continue;
 
-		video->frame_right = (src_lr_edge & VE_SRC_LR_EDGE_DET_RT) >>
-			VE_SRC_LR_EDGE_DET_RT_SHF;
-		video->frame_left = src_lr_edge & VE_SRC_LR_EDGE_DET_LEFT;
+		video->frame_right = FIELD_GET(VE_SRC_LR_EDGE_DET_RT, src_lr_edge);
+		video->frame_left = FIELD_GET(VE_SRC_LR_EDGE_DET_LEFT, src_lr_edge);
 		det->hfrontporch = video->frame_left;
 		det->hbackporch = htotal - video->frame_right;
-		det->hsync = sync & VE_SYNC_STATUS_HSYNC;
+		det->hsync = FIELD_GET(VE_SYNC_STATUS_HSYNC, sync);
 		if (video->frame_left > video->frame_right)
 			continue;
 
-- 
2.25.1



From yuzhao at google.com  Mon Jan 24 22:48:30 2022
From: yuzhao at google.com (Yu Zhao)
Date: Mon, 24 Jan 2022 23:48:30 -0700
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <CAGsJ_4zULJ5vPwn73Z5Bap3eRkAX+Yv24c-n41+zC7fN8xG60g@mail.gmail.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <CAGsJ_4zULJ5vPwn73Z5Bap3eRkAX+Yv24c-n41+zC7fN8xG60g@mail.gmail.com>
Message-ID: <Ye+dPmO17JN2bNLL@google.com>

On Sun, Jan 23, 2022 at 06:43:06PM +1300, Barry Song wrote:
> On Wed, Jan 5, 2022 at 7:17 PM Yu Zhao <yuzhao at google.com> wrote:

<snipped>

> > Large-scale deployments
> > -----------------------
> > We've rolled out MGLRU to tens of millions of Chrome OS users and
> > about a million Android users. Google's fleetwide profiling [13] shows
> > an overall 40% decrease in kswapd CPU usage, in addition to
> 
> Hi Yu,
> 
> Was the overall 40% decrease of kswap CPU usgae seen on x86 or arm64?
> And I am curious how much we are taking advantage of NONLEAF_PMD_YOUNG.
> Does it help a lot in decreasing the cpu usage?

Hi Barry,

The fleet-wide profiling data I shared was from x86. For arm64, I only
have data from synthetic benchmarks at the moment, and it also shows
similar improvements.

For Chrome OS (individual users), walk_pte_range(), the function that
would benefit from ARCH_HAS_NONLEAF_PMD_YOUNG, only uses a small
portion (<4%) of kswapd CPU time. So ARCH_HAS_NONLEAF_PMD_YOUNG isn't
that helpful.

> If so, this might be
> a good proof that arm64 also needs this hardware feature?
> In short, I am curious how much the improvement in this patchset depends
> on the hardware ability of NONLEAF_PMD_YOUNG.

For data centers, I do think ARCH_HAS_NONLEAF_PMD_YOUNG has some value.
In addition to cold/hot memory scanning, there are other use cases like
dirty tracking, which can benefit from the accessed bit on non-leaf
entries. I know some proprietary software uses this capability on x86
for different purposes than this patchset does. And AFAIK, x86 is the
only arch that supports this capability, e.g., risc-v and ppc can only
set the accessed bit in PTEs.

In fact, I've discussed this with one of the arm maintainers Will. So
please check with him too if you are interested in moving forward with
the idea. I might be able to provide with additional data if you need
it to make a decision.

Thanks.


From leo.yan at linaro.org  Mon Jan 24 22:54:32 2022
From: leo.yan at linaro.org (Leo Yan)
Date: Tue, 25 Jan 2022 14:54:32 +0800
Subject: [PATCH] coresight: tmc: change device registration from misc to
 cdev
In-Reply-To: <117e6569-bd2e-830a-70e3-dd26dfae26c8@linux.alibaba.com>
References: <20220124110018.68485-1-jkchen@linux.alibaba.com>
 <CANLsYkxTy3fWgKx2QotWsSC9WZSmAroiFhMkPa9HapvzZNDjRg@mail.gmail.com>
 <117e6569-bd2e-830a-70e3-dd26dfae26c8@linux.alibaba.com>
Message-ID: <20220125065432.GA370774@leoy-ThinkPad-X240s>

Hi Jay,

On Tue, Jan 25, 2022 at 10:33:45AM +0800, Jiankang Chen wrote:
> Hi Mathieu
> 
> ? 2022/1/25 04:08, Mathieu Poirier ??:
> > On Mon, 24 Jan 2022 at 04:00, Jay Chen <jkchen at linux.alibaba.com> wrote:
> > > Currently, there are 130 etr and etf on our machine,
> > > but the current coresight tmc driver uses misc_register
> > > to register the device, which leads to the error that
> > > the device number is not enough.
> > > 
> > > coresight-tmc: probe of xxxxx failed with error -16
> > > 
> > > This patch changes the device registration method
> > > to cdev's dynamic registration method to solve the
> > > problem of insufficient device numbers.
> > This patch is still not labelled properly and as such being dropped.
> 
> Hello, about the label of this patch, what kind of patch should I add?

You could use "git format" command with option "-v" to add the version
number, e.g. if you are committing patch version 4, so you can generate
patch like:

  $ git format-patch HEAD~1 -v4

Or if you want to generate patch for a specific commit:

  $ git format-patch -1 patch_commit -v4

Every time when you generate a new version's patch, you could
increment the version number with option "-v4", "-v5", and so on.

P.s. I strongly suggest Marc Zyngier's great talk for how to upstream
kernel patch in a good way:
https://events19.linuxfoundation.org/wp-content/uploads/2017/12/Getting-Your-Patches-in-Mainline-Linux-What-Not-To-Do-and-a-Few-Things-You-Could-Try-Instead-Marc-Zyngier-ARM.pdf

Thanks,
Leo


From ming.qian at nxp.com  Mon Jan 24 23:11:20 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:20 +0800
Subject: [PATCH v15 04/13] media: amphion: add vpu core driver
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <a446b89c37732e68d0e849d515c3107bf70ca5c6.1643077283.git.ming.qian@nxp.com>

The vpu supports encoder and decoder.
it needs vpu core to handle it.
core will run either encoder or decoder firmware.

This driver is for support the vpu core.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_codec.h |  68 ++
 drivers/media/platform/amphion/vpu_core.c  | 870 +++++++++++++++++++++
 drivers/media/platform/amphion/vpu_core.h  |  15 +
 drivers/media/platform/amphion/vpu_dbg.c   | 495 ++++++++++++
 drivers/media/platform/amphion/vpu_rpc.c   | 257 ++++++
 drivers/media/platform/amphion/vpu_rpc.h   | 456 +++++++++++
 6 files changed, 2161 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_codec.h
 create mode 100644 drivers/media/platform/amphion/vpu_core.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.h
 create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.h

diff --git a/drivers/media/platform/amphion/vpu_codec.h b/drivers/media/platform/amphion/vpu_codec.h
new file mode 100644
index 000000000000..528a93f08ecd
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_codec.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CODEC_H
+#define _AMPHION_VPU_CODEC_H
+
+struct vpu_encode_params {
+	u32 input_format;
+	u32 codec_format;
+	u32 profile;
+	u32 tier;
+	u32 level;
+	struct v4l2_fract frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	struct v4l2_rect crop;
+	u32 out_width;
+	u32 out_height;
+
+	u32 gop_length;
+	u32 bframes;
+
+	u32 rc_enable;
+	u32 rc_mode;
+	u32 bitrate;
+	u32 bitrate_min;
+	u32 bitrate_max;
+
+	u32 i_frame_qp;
+	u32 p_frame_qp;
+	u32 b_frame_qp;
+	u32 qp_min;
+	u32 qp_max;
+	u32 qp_min_i;
+	u32 qp_max_i;
+
+	struct {
+		u32 enable;
+		u32 idc;
+		u32 width;
+		u32 height;
+	} sar;
+
+	struct {
+		u32 primaries;
+		u32 transfer;
+		u32 matrix;
+		u32 full_range;
+	} color;
+};
+
+struct vpu_decode_params {
+	u32 codec_format;
+	u32 output_format;
+	u32 b_dis_reorder;
+	u32 b_non_frame;
+	u32 frame_count;
+	u32 end_flag;
+	struct {
+		u32 base;
+		u32 size;
+	} udata;
+};
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
new file mode 100644
index 000000000000..608dda41d5a9
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_core.c
@@ -0,0 +1,870 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/firmware.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_rpc.h"
+#include "vpu_cmds.h"
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val)
+{
+	writel(val, core->base + reg);
+}
+
+u32 csr_readl(struct vpu_core *core, u32 reg)
+{
+	return readl(core->base + reg);
+}
+
+static int vpu_core_load_firmware(struct vpu_core *core)
+{
+	const struct firmware *pfw = NULL;
+	int ret = 0;
+
+	if (!core->fw.virt) {
+		dev_err(core->dev, "firmware buffer is not ready\n");
+		return -EINVAL;
+	}
+
+	ret = request_firmware(&pfw, core->res->fwname, core->dev);
+	dev_dbg(core->dev, "request_firmware %s : %d\n", core->res->fwname, ret);
+	if (ret) {
+		dev_err(core->dev, "request firmware %s failed, ret = %d\n",
+			core->res->fwname, ret);
+		return ret;
+	}
+
+	if (core->fw.length < pfw->size) {
+		dev_err(core->dev, "firmware buffer size want %zu, but %d\n",
+			pfw->size, core->fw.length);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	memset_io(core->fw.virt, 0, core->fw.length);
+	memcpy(core->fw.virt, pfw->data, pfw->size);
+	core->fw.bytesused = pfw->size;
+	ret = vpu_iface_on_firmware_loaded(core);
+exit:
+	release_firmware(pfw);
+	pfw = NULL;
+
+	return ret;
+}
+
+static int vpu_core_boot_done(struct vpu_core *core)
+{
+	u32 fw_version;
+
+	fw_version = vpu_iface_get_version(core);
+	dev_info(core->dev, "%s firmware version : %d.%d.%d\n",
+		 vpu_core_type_desc(core->type),
+		 (fw_version >> 16) & 0xff,
+		 (fw_version >> 8) & 0xff,
+		 fw_version & 0xff);
+	core->supported_instance_count = vpu_iface_get_max_instance_count(core);
+	if (core->res->act_size) {
+		u32 count = core->act.length / core->res->act_size;
+
+		core->supported_instance_count = min(core->supported_instance_count, count);
+	}
+	core->fw_version = fw_version;
+	core->state = VPU_CORE_ACTIVE;
+
+	return 0;
+}
+
+static int vpu_core_wait_boot_done(struct vpu_core *core)
+{
+	int ret;
+
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "boot timeout\n");
+		return -EINVAL;
+	}
+	return vpu_core_boot_done(core);
+}
+
+static int vpu_core_boot(struct vpu_core *core, bool load)
+{
+	int ret;
+
+	reinit_completion(&core->cmp);
+	if (load) {
+		ret = vpu_core_load_firmware(core);
+		if (ret)
+			return ret;
+	}
+
+	vpu_iface_boot_core(core);
+	return vpu_core_wait_boot_done(core);
+}
+
+static int vpu_core_shutdown(struct vpu_core *core)
+{
+	return vpu_iface_shutdown_core(core);
+}
+
+static int vpu_core_restore(struct vpu_core *core)
+{
+	int ret;
+
+	ret = vpu_core_sw_reset(core);
+	if (ret)
+		return ret;
+
+	vpu_core_boot_done(core);
+	return vpu_iface_restore_core(core);
+}
+
+static int __vpu_alloc_dma(struct device *dev, struct vpu_buffer *buf)
+{
+	gfp_t gfp = GFP_KERNEL | GFP_DMA32;
+
+	if (!buf->length)
+		return 0;
+
+	buf->virt = dma_alloc_coherent(dev, buf->length, &buf->phys, gfp);
+	if (!buf->virt)
+		return -ENOMEM;
+
+	buf->dev = dev;
+
+	return 0;
+}
+
+void vpu_free_dma(struct vpu_buffer *buf)
+{
+	if (!buf->virt || !buf->dev)
+		return;
+
+	dma_free_coherent(buf->dev, buf->length, buf->virt, buf->phys);
+	buf->virt = NULL;
+	buf->phys = 0;
+	buf->length = 0;
+	buf->bytesused = 0;
+	buf->dev = NULL;
+}
+
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+{
+	return __vpu_alloc_dma(core->dev, buf);
+}
+
+static void vpu_core_check_hang(struct vpu_core *core)
+{
+	if (core->hang_mask)
+		core->state = VPU_CORE_HANG;
+}
+
+static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *core = NULL;
+	int request_count = INT_MAX;
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state);
+		if (c->type != type)
+			continue;
+		if (c->state == VPU_CORE_DEINIT) {
+			core = c;
+			break;
+		}
+		vpu_core_check_hang(c);
+		if (c->state != VPU_CORE_ACTIVE)
+			continue;
+		if (c->request_count < request_count) {
+			request_count = c->request_count;
+			core = c;
+		}
+		if (!request_count)
+			break;
+	}
+
+	return core;
+}
+
+static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core)
+{
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c == core)
+			return true;
+	}
+
+	return false;
+}
+
+static void vpu_core_get_vpu(struct vpu_core *core)
+{
+	core->vpu->get_vpu(core->vpu);
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->get_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->get_dec(core->vpu);
+}
+
+static int vpu_core_register(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+	int ret = 0;
+
+	dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type));
+	if (vpu_core_is_exist(vpu, core))
+		return 0;
+
+	core->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!core->workqueue) {
+		dev_err(core->dev, "fail to alloc workqueue\n");
+		return -ENOMEM;
+	}
+	INIT_WORK(&core->msg_work, vpu_msg_run_work);
+	INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
+	core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
+	core->msg_buffer = vzalloc(core->msg_buffer_size);
+	if (!core->msg_buffer) {
+		dev_err(core->dev, "failed allocate buffer for fifo\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size);
+	if (ret) {
+		dev_err(core->dev, "failed init kfifo\n");
+		goto error;
+	}
+
+	list_add_tail(&core->list, &vpu->cores);
+
+	vpu_core_get_vpu(core);
+
+	if (vpu_iface_get_power_state(core))
+		ret = vpu_core_restore(core);
+	if (ret)
+		goto error;
+
+	return 0;
+error:
+	if (core->msg_buffer) {
+		vfree(core->msg_buffer);
+		core->msg_buffer = NULL;
+	}
+	if (core->workqueue) {
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+	return ret;
+}
+
+static void vpu_core_put_vpu(struct vpu_core *core)
+{
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->put_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->put_dec(core->vpu);
+	core->vpu->put_vpu(core->vpu);
+}
+
+static int vpu_core_unregister(struct device *dev, struct vpu_core *core)
+{
+	list_del_init(&core->list);
+
+	vpu_core_put_vpu(core);
+	core->vpu = NULL;
+	vfree(core->msg_buffer);
+	core->msg_buffer = NULL;
+
+	if (core->workqueue) {
+		cancel_work_sync(&core->msg_work);
+		cancel_delayed_work_sync(&core->msg_delayed_work);
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+
+	return 0;
+}
+
+static int vpu_core_acquire_instance(struct vpu_core *core)
+{
+	int id;
+
+	id = ffz(core->instance_mask);
+	if (id >= core->supported_instance_count)
+		return -EINVAL;
+
+	set_bit(id, &core->instance_mask);
+
+	return id;
+}
+
+static void vpu_core_release_instance(struct vpu_core *core, int id)
+{
+	if (id < 0 || id >= core->supported_instance_count)
+		return;
+
+	clear_bit(id, &core->instance_mask);
+}
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst)
+{
+	if (!inst)
+		return NULL;
+
+	atomic_inc(&inst->ref_count);
+
+	return inst;
+}
+
+void vpu_inst_put(struct vpu_inst *inst)
+{
+	if (!inst)
+		return;
+	if (atomic_dec_and_test(&inst->ref_count)) {
+		if (inst->release)
+			inst->release(inst);
+	}
+}
+
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_core *core = NULL;
+	int ret;
+
+	mutex_lock(&vpu->lock);
+
+	core = vpu_core_find_proper_by_type(vpu, type);
+	if (!core)
+		goto exit;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(core->dev);
+
+	if (core->state == VPU_CORE_DEINIT) {
+		ret = vpu_core_boot(core, true);
+		if (ret) {
+			pm_runtime_put_sync(core->dev);
+			mutex_unlock(&core->lock);
+			core = NULL;
+			goto exit;
+		}
+	}
+
+	core->request_count++;
+
+	mutex_unlock(&core->lock);
+exit:
+	mutex_unlock(&vpu->lock);
+
+	return core;
+}
+
+void vpu_release_core(struct vpu_core *core)
+{
+	if (!core)
+		return;
+
+	mutex_lock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+	if (core->request_count)
+		core->request_count--;
+	mutex_unlock(&core->lock);
+}
+
+int vpu_inst_register(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	struct vpu_core *core;
+	int ret = 0;
+
+	vpu = inst->vpu;
+	core = inst->core;
+	if (!core) {
+		core = vpu_request_core(vpu, inst->type);
+		if (!core) {
+			dev_err(vpu->dev, "there is no vpu core for %s\n",
+				vpu_core_type_desc(inst->type));
+			return -EINVAL;
+		}
+		inst->core = core;
+		inst->dev = get_device(core->dev);
+	}
+
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count)
+		goto exit;
+
+	ret = vpu_core_acquire_instance(core);
+	if (ret < 0)
+		goto exit;
+
+	vpu_trace(inst->dev, "[%d] %p\n", ret, inst);
+	inst->id = ret;
+	list_add_tail(&inst->list, &core->instances);
+	ret = 0;
+	if (core->res->act_size) {
+		inst->act.phys = core->act.phys + core->res->act_size * inst->id;
+		inst->act.virt = core->act.virt + core->res->act_size * inst->id;
+		inst->act.length = core->res->act_size;
+	}
+	vpu_inst_create_dbgfs_file(inst);
+exit:
+	mutex_unlock(&core->lock);
+
+	if (ret)
+		dev_err(core->dev, "register instance fail\n");
+	return ret;
+}
+
+int vpu_inst_unregister(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+
+	if (!inst->core)
+		return 0;
+
+	core = inst->core;
+	vpu_clear_request(inst);
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count) {
+		vpu_inst_remove_dbgfs_file(inst);
+		list_del_init(&inst->list);
+		vpu_core_release_instance(core, inst->id);
+		inst->id = VPU_INST_NULL_ID;
+	}
+	vpu_core_check_hang(core);
+	if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+		dev_info(core->dev, "reset hang core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index)
+{
+	struct vpu_inst *inst = NULL;
+	struct vpu_inst *tmp;
+
+	mutex_lock(&core->lock);
+	if (!test_bit(index, &core->instance_mask))
+		goto exit;
+	list_for_each_entry(tmp, &core->instances, list) {
+		if (tmp->id == index) {
+			inst = vpu_inst_get(tmp);
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->lock);
+
+	return inst;
+}
+
+const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	struct vpu_core *core = NULL;
+	const struct vpu_core_resources *res = NULL;
+
+	if (!inst || !inst->vpu)
+		return NULL;
+
+	if (inst->core && inst->core->res)
+		return inst->core->res;
+
+	vpu = inst->vpu;
+	mutex_lock(&vpu->lock);
+	list_for_each_entry(core, &vpu->cores, list) {
+		if (core->type == inst->type) {
+			res = core->res;
+			break;
+		}
+	}
+	mutex_unlock(&vpu->lock);
+
+	return res;
+}
+
+static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
+{
+	struct device_node *node;
+	struct resource res;
+	int ret;
+
+	if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) {
+		dev_err(core->dev, "need 2 memory-region for boot and rpc\n");
+		return -ENODEV;
+	}
+
+	node = of_parse_phandle(np, "memory-region", 0);
+	if (!node) {
+		dev_err(core->dev, "boot-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		dev_err(core->dev, "boot-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->fw.phys = res.start;
+	core->fw.length = resource_size(&res);
+
+	node = of_parse_phandle(np, "memory-region", 1);
+	if (!node) {
+		dev_err(core->dev, "rpc-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		dev_err(core->dev, "rpc-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->rpc.phys = res.start;
+	core->rpc.length = resource_size(&res);
+
+	if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) {
+		dev_err(core->dev, "the rpc-region <%pad, 0x%x> is not enough\n",
+			&core->rpc.phys, core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->fw.virt = ioremap_wc(core->fw.phys, core->fw.length);
+	core->rpc.virt = ioremap_wc(core->rpc.phys, core->rpc.length);
+	memset_io(core->rpc.virt, 0, core->rpc.length);
+
+	ret = vpu_iface_check_memory_region(core, core->rpc.phys, core->rpc.length);
+	if (ret != VPU_CORE_MEMORY_UNCACHED) {
+		dev_err(core->dev, "rpc region<%pad, 0x%x> isn't uncached\n",
+			&core->rpc.phys, core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->log.phys = core->rpc.phys + core->res->rpc_size;
+	core->log.virt = core->rpc.virt + core->res->rpc_size;
+	core->log.length = core->res->fwlog_size;
+	core->act.phys = core->log.phys + core->log.length;
+	core->act.virt = core->log.virt + core->log.length;
+	core->act.length = core->rpc.length - core->res->rpc_size - core->log.length;
+	core->rpc.length = core->res->rpc_size;
+
+	return 0;
+}
+
+static int vpu_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core;
+	struct vpu_dev *vpu = dev_get_drvdata(dev->parent);
+	struct vpu_shared_addr *iface;
+	u32 iface_data_size;
+	int ret;
+
+	dev_dbg(dev, "probe\n");
+	if (!vpu)
+		return -EINVAL;
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->pdev = pdev;
+	core->dev = dev;
+	platform_set_drvdata(pdev, core);
+	core->vpu = vpu;
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->lock);
+	mutex_init(&core->cmd_lock);
+	init_completion(&core->cmp);
+	init_waitqueue_head(&core->ack_wq);
+	core->state = VPU_CORE_DEINIT;
+
+	core->res = of_device_get_match_data(dev);
+	if (!core->res)
+		return -ENODEV;
+
+	core->type = core->res->type;
+	core->id = of_alias_get_id(dev->of_node, "vpu_core");
+	if (core->id < 0) {
+		dev_err(dev, "can't get vpu core id\n");
+		return core->id;
+	}
+	dev_info(core->dev, "[%d] = %s\n", core->id, vpu_core_type_desc(core->type));
+	ret = vpu_core_parse_dt(core, dev->of_node);
+	if (ret)
+		return ret;
+
+	core->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+
+	if (!vpu_iface_check_codec(core)) {
+		dev_err(core->dev, "is not supported\n");
+		return -EINVAL;
+	}
+
+	ret = vpu_mbox_init(core);
+	if (ret)
+		return ret;
+
+	iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL);
+	if (!iface)
+		return -ENOMEM;
+
+	iface_data_size = vpu_iface_get_data_size(core);
+	if (iface_data_size) {
+		iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL);
+		if (!iface->priv)
+			return -ENOMEM;
+	}
+
+	ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys);
+	if (ret) {
+		dev_err(core->dev, "init iface fail, ret = %d\n", ret);
+		return ret;
+	}
+
+	vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base);
+	vpu_iface_set_log_buf(core, &core->log);
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		pm_runtime_put_noidle(dev);
+		pm_runtime_set_suspended(dev);
+		goto err_runtime_disable;
+	}
+
+	ret = vpu_core_register(dev->parent, core);
+	if (ret)
+		goto err_core_register;
+	core->parent = dev->parent;
+
+	pm_runtime_put_sync(dev);
+	vpu_core_create_dbgfs_file(core);
+
+	return 0;
+
+err_core_register:
+	pm_runtime_put_sync(dev);
+err_runtime_disable:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_core_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core = platform_get_drvdata(pdev);
+	int ret;
+
+	vpu_core_remove_dbgfs_file(core);
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	vpu_core_shutdown(core);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	vpu_core_unregister(core->parent, core);
+	iounmap(core->fw.virt);
+	iounmap(core->rpc.virt);
+	mutex_destroy(&core->lock);
+	mutex_destroy(&core->cmd_lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_core_runtime_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	return vpu_mbox_request(core);
+}
+
+static int __maybe_unused vpu_core_runtime_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	vpu_mbox_free(core);
+	return 0;
+}
+
+static void vpu_core_cancel_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+
+	cancel_work_sync(&core->msg_work);
+	cancel_delayed_work_sync(&core->msg_delayed_work);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		cancel_work_sync(&inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static void vpu_core_resume_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+	unsigned long delay = msecs_to_jiffies(10);
+
+	queue_work(core->workqueue, &core->msg_work);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		queue_work(inst->workqueue, &inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static int __maybe_unused vpu_core_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(dev);
+	vpu_core_get_vpu(core);
+	if (core->state != VPU_CORE_SNAPSHOT)
+		goto exit;
+
+	if (!vpu_iface_get_power_state(core)) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_boot(core, false);
+			if (ret) {
+				dev_err(core->dev, "%s boot fail\n", __func__);
+				core->state = VPU_CORE_DEINIT;
+				goto exit;
+			}
+		} else {
+			core->state = VPU_CORE_DEINIT;
+		}
+	} else {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_sw_reset(core);
+			if (ret) {
+				dev_err(core->dev, "%s sw_reset fail\n", __func__);
+				core->state = VPU_CORE_HANG;
+				goto exit;
+			}
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+exit:
+	pm_runtime_put_sync(dev);
+	mutex_unlock(&core->lock);
+
+	vpu_core_resume_work(core);
+	return ret;
+}
+
+static int __maybe_unused vpu_core_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	if (core->state == VPU_CORE_ACTIVE) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_snapshot(core);
+			if (ret) {
+				mutex_unlock(&core->lock);
+				return ret;
+			}
+		}
+
+		core->state = VPU_CORE_SNAPSHOT;
+	}
+	mutex_unlock(&core->lock);
+
+	vpu_core_cancel_work(core);
+
+	mutex_lock(&core->lock);
+	vpu_core_put_vpu(core);
+	mutex_unlock(&core->lock);
+	return ret;
+}
+
+static const struct dev_pm_ops vpu_core_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume)
+};
+
+static struct vpu_core_resources imx8q_enc = {
+	.type = VPU_CORE_TYPE_ENC,
+	.fwname = "vpu/vpu_fw_imx8_enc.bin",
+	.stride = 16,
+	.max_width = 1920,
+	.max_height = 1920,
+	.min_width = 64,
+	.min_height = 48,
+	.step_width = 2,
+	.step_height = 2,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.act_size = 0xc0000,
+};
+
+static struct vpu_core_resources imx8q_dec = {
+	.type = VPU_CORE_TYPE_DEC,
+	.fwname = "vpu/vpu_fw_imx8_dec.bin",
+	.stride = 256,
+	.max_width = 8188,
+	.max_height = 8188,
+	.min_width = 16,
+	.min_height = 16,
+	.step_width = 1,
+	.step_height = 1,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+};
+
+static const struct of_device_id vpu_core_dt_match[] = {
+	{ .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc },
+	{ .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_core_dt_match);
+
+static struct platform_driver amphion_vpu_core_driver = {
+	.probe = vpu_core_probe,
+	.remove = vpu_core_remove,
+	.driver = {
+		.name = "amphion-vpu-core",
+		.of_match_table = vpu_core_dt_match,
+		.pm = &vpu_core_pm_ops,
+	},
+};
+
+int __init vpu_core_driver_init(void)
+{
+	return platform_driver_register(&amphion_vpu_core_driver);
+}
+
+void __exit vpu_core_driver_exit(void)
+{
+	platform_driver_unregister(&amphion_vpu_core_driver);
+}
diff --git a/drivers/media/platform/amphion/vpu_core.h b/drivers/media/platform/amphion/vpu_core.h
new file mode 100644
index 000000000000..00a662997da4
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_core.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CORE_H
+#define _AMPHION_VPU_CORE_H
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val);
+u32 csr_readl(struct vpu_core *core, u32 reg);
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+void vpu_free_dma(struct vpu_buffer *buf);
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
new file mode 100644
index 000000000000..23a01c0dbf9d
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_dbg.c
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-device.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_v4l2.h"
+
+struct print_buf_desc {
+	u32 start_h_phy;
+	u32 start_h_vir;
+	u32 start_m;
+	u32 bytes;
+	u32 read;
+	u32 write;
+	char buffer[0];
+};
+
+static char *vb2_stat_name[] = {
+	[VB2_BUF_STATE_DEQUEUED] = "dequeued",
+	[VB2_BUF_STATE_IN_REQUEST] = "in_request",
+	[VB2_BUF_STATE_PREPARING] = "preparing",
+	[VB2_BUF_STATE_QUEUED] = "queued",
+	[VB2_BUF_STATE_ACTIVE] = "active",
+	[VB2_BUF_STATE_DONE] = "done",
+	[VB2_BUF_STATE_ERROR] = "error",
+};
+
+static char *vpu_stat_name[] = {
+	[VPU_BUF_STATE_IDLE] = "idle",
+	[VPU_BUF_STATE_INUSE] = "inuse",
+	[VPU_BUF_STATE_DECODED] = "decoded",
+	[VPU_BUF_STATE_READY] = "ready",
+	[VPU_BUF_STATE_SKIP] = "skip",
+	[VPU_BUF_STATE_ERROR] = "error",
+};
+
+static int vpu_dbg_instance(struct seq_file *s, void *data)
+{
+	struct vpu_inst *inst = s->private;
+	char str[128];
+	int num;
+	struct vb2_queue *vq;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(inst->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "state = %d\n", inst->state);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"min_buffer_out = %d, min_buffer_cap = %d\n",
+			inst->min_buffer_out, inst->min_buffer_cap);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"output (%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			vq->num_buffers,
+			inst->out_format.pixfmt,
+			inst->out_format.pixfmt >> 8,
+			inst->out_format.pixfmt >> 16,
+			inst->out_format.pixfmt >> 24,
+			inst->out_format.width,
+			inst->out_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->out_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->out_format.sizeimage[i],
+				inst->out_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+
+	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"capture(%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			vq->num_buffers,
+			inst->cap_format.pixfmt,
+			inst->cap_format.pixfmt >> 8,
+			inst->cap_format.pixfmt >> 16,
+			inst->cap_format.pixfmt >> 24,
+			inst->cap_format.width,
+			inst->cap_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->cap_format.sizeimage[i],
+				inst->cap_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+	num = scnprintf(str, sizeof(str), "crop: (%d, %d) %d x %d\n",
+			inst->crop.left,
+			inst->crop.top,
+			inst->crop.width,
+			inst->crop.height);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"output [%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_get_buffer_state(vbuf)]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"capture[%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_get_buffer_state(vbuf)]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
+	if (seq_write(s, str, num))
+		return 0;
+
+	if (inst->use_stream_buffer) {
+		num = scnprintf(str, sizeof(str), "stream_buffer = %d / %d, <%pad, 0x%x>\n",
+				vpu_helper_get_used_space(inst),
+				inst->stream_buffer.length,
+				&inst->stream_buffer.phys,
+				inst->stream_buffer.length);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&inst->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "flow :\n");
+	if (seq_write(s, str, num))
+		return 0;
+
+	mutex_lock(&inst->core->cmd_lock);
+	for (i = 0; i < ARRAY_SIZE(inst->flows); i++) {
+		u32 idx = (inst->flow_idx + i) % (ARRAY_SIZE(inst->flows));
+
+		if (!inst->flows[idx])
+			continue;
+		num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n",
+				inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
+				inst->flows[idx]);
+		if (seq_write(s, str, num)) {
+			mutex_unlock(&inst->core->cmd_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+
+	i = 0;
+	while (true) {
+		num = call_vop(inst, get_debug_info, str, sizeof(str), i++);
+		if (num <= 0)
+			break;
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	return 0;
+}
+
+static int vpu_dbg_core(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct vpu_shared_addr *iface = core->iface;
+	char str[128];
+	int num;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(core->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "boot_region  = <%pad, 0x%x>\n",
+			&core->fw.phys, core->fw.length);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "rpc_region   = <%pad, 0x%x> used = 0x%x\n",
+			&core->rpc.phys, core->rpc.length, core->rpc.bytesused);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "fwlog_region = <%pad, 0x%x>\n",
+			&core->log.phys, core->log.length);
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+	if (seq_write(s, str, num))
+		return 0;
+	if (core->state == VPU_CORE_DEINIT)
+		return 0;
+	num = scnprintf(str, sizeof(str), "fw version = %d.%d.%d\n",
+			(core->fw_version >> 16) & 0xff,
+			(core->fw_version >> 8) & 0xff,
+			core->fw_version & 0xff);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "instances = %d/%d (0x%02lx), %d\n",
+			hweight32(core->instance_mask),
+			core->supported_instance_count,
+			core->instance_mask,
+			core->request_count);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&core->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"cmd_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->cmd_desc->start,
+			iface->cmd_desc->end,
+			iface->cmd_desc->wptr,
+			iface->cmd_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"msg_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->msg_desc->start,
+			iface->msg_desc->end,
+			iface->msg_desc->wptr,
+			iface->msg_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+
+	return 0;
+}
+
+static int vpu_dbg_fwlog(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct print_buf_desc *print_buf;
+	int length;
+	u32 rptr;
+	u32 wptr;
+	int ret = 0;
+
+	if (!core->log.virt || core->state == VPU_CORE_DEINIT)
+		return 0;
+
+	print_buf = core->log.virt;
+	rptr = print_buf->read;
+	wptr = print_buf->write;
+
+	if (rptr == wptr)
+		return 0;
+	else if (rptr < wptr)
+		length = wptr - rptr;
+	else
+		length = print_buf->bytes + wptr - rptr;
+
+	if (s->count + length >= s->size) {
+		s->count = s->size;
+		return 0;
+	}
+
+	if (rptr + length >= print_buf->bytes) {
+		int num = print_buf->bytes - rptr;
+
+		if (seq_write(s, print_buf->buffer + rptr, num))
+			ret = -1;
+		length -= num;
+		rptr = 0;
+	}
+
+	if (length) {
+		if (seq_write(s, print_buf->buffer + rptr, length))
+			ret = -1;
+		rptr += length;
+	}
+	if (!ret)
+		print_buf->read = rptr;
+
+	return 0;
+}
+
+static int vpu_dbg_inst_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_instance, inode->i_private);
+}
+
+static ssize_t vpu_dbg_inst_write(struct file *file,
+				  const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_inst *inst = s->private;
+
+	vpu_session_debug(inst);
+
+	return size;
+}
+
+static ssize_t vpu_dbg_core_write(struct file *file,
+				  const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_core *core = s->private;
+
+	pm_runtime_get_sync(core->dev);
+	mutex_lock(&core->lock);
+	if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
+		dev_info(core->dev, "reset\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+
+	return size;
+}
+
+static int vpu_dbg_core_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_core, inode->i_private);
+}
+
+static int vpu_dbg_fwlog_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_fwlog, inode->i_private);
+}
+
+static const struct file_operations vpu_dbg_inst_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_inst_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_inst_write,
+};
+
+static const struct file_operations vpu_dbg_core_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_core_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_core_write,
+};
+
+static const struct file_operations vpu_dbg_fwlog_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_fwlog_open,
+	.release = single_release,
+	.read = seq_read,
+};
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!inst || !inst->core || !inst->core->vpu)
+		return -EINVAL;
+
+	vpu = inst->core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (inst->debugfs)
+		return 0;
+
+	scnprintf(name, sizeof(name), "instance.%d.%d", inst->core->id, inst->id);
+	inst->debugfs = debugfs_create_file((const char *)name,
+					    VERIFY_OCTAL_PERMISSIONS(0644),
+					    vpu->debugfs,
+					    inst,
+					    &vpu_dbg_inst_fops);
+	if (!inst->debugfs) {
+		dev_err(inst->dev, "vpu create debugfs %s fail\n", name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst)
+{
+	if (!inst)
+		return 0;
+
+	debugfs_remove(inst->debugfs);
+	inst->debugfs = NULL;
+
+	return 0;
+}
+
+int vpu_core_create_dbgfs_file(struct vpu_core *core)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!core || !core->vpu)
+		return -EINVAL;
+
+	vpu = core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (!core->debugfs) {
+		scnprintf(name, sizeof(name), "core.%d", core->id);
+		core->debugfs = debugfs_create_file((const char *)name,
+						    VERIFY_OCTAL_PERMISSIONS(0644),
+						    vpu->debugfs,
+						    core,
+						    &vpu_dbg_core_fops);
+		if (!core->debugfs) {
+			dev_err(core->dev, "vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+	if (!core->debugfs_fwlog) {
+		scnprintf(name, sizeof(name), "fwlog.%d", core->id);
+		core->debugfs_fwlog = debugfs_create_file((const char *)name,
+							  VERIFY_OCTAL_PERMISSIONS(0444),
+							  vpu->debugfs,
+							  core,
+							  &vpu_dbg_fwlog_fops);
+		if (!core->debugfs_fwlog) {
+			dev_err(core->dev, "vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_core_remove_dbgfs_file(struct vpu_core *core)
+{
+	if (!core)
+		return 0;
+	debugfs_remove(core->debugfs);
+	core->debugfs = NULL;
+	debugfs_remove(core->debugfs_fwlog);
+	core->debugfs_fwlog = NULL;
+
+	return 0;
+}
+
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow)
+{
+	if (!inst)
+		return;
+
+	inst->flows[inst->flow_idx] = flow;
+	inst->flow_idx = (inst->flow_idx + 1) % (ARRAY_SIZE(inst->flows));
+}
diff --git a/drivers/media/platform/amphion/vpu_rpc.c b/drivers/media/platform/amphion/vpu_rpc.c
new file mode 100644
index 000000000000..16fb55927e0e
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_rpc.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+#include "vpu_malone.h"
+
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->check_memory_region)
+		return VPU_CORE_MEMORY_INVALID;
+
+	return ops->check_memory_region(core->fw.phys, addr, size);
+}
+
+static u32 vpu_rpc_check_buffer_space(struct vpu_rpc_buffer_desc *desc, bool write)
+{
+	u32 ptr1;
+	u32 ptr2;
+	u32 size;
+
+	size = desc->end - desc->start;
+	if (write) {
+		ptr1 = desc->wptr;
+		ptr2 = desc->rptr;
+	} else {
+		ptr1 = desc->rptr;
+		ptr2 = desc->wptr;
+	}
+
+	if (ptr1 == ptr2) {
+		if (!write)
+			return 0;
+		else
+			return size;
+	}
+
+	return (ptr2 + size - ptr1) % size;
+}
+
+static int vpu_rpc_send_cmd_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *cmd)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 *data;
+	u32 wptr;
+	u32 i;
+
+	desc = shared->cmd_desc;
+	space = vpu_rpc_check_buffer_space(desc, true);
+	if (space < (((cmd->hdr.num + 1) << 2) + 16))
+		return -EINVAL;
+	wptr = desc->wptr;
+	data = (u32 *)(shared->cmd_mem_vir + desc->wptr - desc->start);
+	*data = 0;
+	*data |= ((cmd->hdr.index & 0xff) << 24);
+	*data |= ((cmd->hdr.num & 0xff) << 16);
+	*data |= (cmd->hdr.id & 0x3fff);
+	wptr += 4;
+	data++;
+	if (wptr >= desc->end) {
+		wptr = desc->start;
+		data = shared->cmd_mem_vir;
+	}
+
+	for (i = 0; i < cmd->hdr.num; i++) {
+		*data = cmd->data[i];
+		wptr += 4;
+		data++;
+		if (wptr >= desc->end) {
+			wptr = desc->start;
+			data = shared->cmd_mem_vir;
+		}
+	}
+
+	/*update wptr after data is written*/
+	mb();
+	desc->wptr = wptr;
+
+	return 0;
+}
+
+static bool vpu_rpc_check_msg(struct vpu_shared_addr *shared)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 msgword;
+	u32 msgnum;
+
+	desc = shared->msg_desc;
+	space = vpu_rpc_check_buffer_space(desc, 0);
+	space = (space >> 2);
+
+	if (space) {
+		msgword = *(u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+		msgnum = (msgword & 0xff0000) >> 16;
+		if (msgnum <= space)
+			return true;
+	}
+
+	return false;
+}
+
+static int vpu_rpc_receive_msg_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *msg)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 *data;
+	u32 msgword;
+	u32 rptr;
+	u32 i;
+
+	if (!vpu_rpc_check_msg(shared))
+		return -EINVAL;
+
+	desc = shared->msg_desc;
+	data = (u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+	rptr = desc->rptr;
+	msgword = *data;
+	data++;
+	rptr += 4;
+	if (rptr >= desc->end) {
+		rptr = desc->start;
+		data = shared->msg_mem_vir;
+	}
+
+	msg->hdr.index = (msgword >> 24) & 0xff;
+	msg->hdr.num = (msgword >> 16) & 0xff;
+	msg->hdr.id = msgword & 0x3fff;
+
+	if (msg->hdr.num > ARRAY_SIZE(msg->data))
+		return -EINVAL;
+
+	for (i = 0; i < msg->hdr.num; i++) {
+		msg->data[i] = *data;
+		data++;
+		rptr += 4;
+		if (rptr >= desc->end) {
+			rptr = desc->start;
+			data = shared->msg_mem_vir;
+		}
+	}
+
+	/*update rptr after data is read*/
+	mb();
+	desc->rptr = rptr;
+
+	return 0;
+}
+
+struct vpu_iface_ops imx8q_rpc_ops[] = {
+	[VPU_CORE_TYPE_ENC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_windsor_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_windsor_init_rpc,
+		.set_log_buf = vpu_windsor_set_log_buf,
+		.set_system_cfg = vpu_windsor_set_system_cfg,
+		.get_version = vpu_windsor_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.pack_cmd = vpu_windsor_pack_cmd,
+		.convert_msg_id = vpu_windsor_convert_msg_id,
+		.unpack_msg_data = vpu_windsor_unpack_msg_data,
+		.config_memory_resource = vpu_windsor_config_memory_resource,
+		.get_stream_buffer_size = vpu_windsor_get_stream_buffer_size,
+		.config_stream_buffer = vpu_windsor_config_stream_buffer,
+		.get_stream_buffer_desc = vpu_windsor_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_windsor_update_stream_buffer,
+		.set_encode_params = vpu_windsor_set_encode_params,
+		.input_frame = vpu_windsor_input_frame,
+		.get_max_instance_count = vpu_windsor_get_max_instance_count,
+	},
+	[VPU_CORE_TYPE_DEC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_malone_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_malone_init_rpc,
+		.set_log_buf = vpu_malone_set_log_buf,
+		.set_system_cfg = vpu_malone_set_system_cfg,
+		.get_version = vpu_malone_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.get_stream_buffer_size = vpu_malone_get_stream_buffer_size,
+		.config_stream_buffer = vpu_malone_config_stream_buffer,
+		.set_decode_params = vpu_malone_set_decode_params,
+		.pack_cmd = vpu_malone_pack_cmd,
+		.convert_msg_id = vpu_malone_convert_msg_id,
+		.unpack_msg_data = vpu_malone_unpack_msg_data,
+		.get_stream_buffer_desc = vpu_malone_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_malone_update_stream_buffer,
+		.add_scode = vpu_malone_add_scode,
+		.input_frame = vpu_malone_input_frame,
+		.pre_send_cmd = vpu_malone_pre_cmd,
+		.post_send_cmd = vpu_malone_post_cmd,
+		.init_instance = vpu_malone_init_instance,
+		.get_max_instance_count = vpu_malone_get_max_instance_count,
+	},
+};
+
+static struct vpu_iface_ops *vpu_get_iface(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_iface_ops *rpc_ops = NULL;
+	u32 size = 0;
+
+	switch (vpu->res->plat_type) {
+	case IMX8QXP:
+	case IMX8QM:
+		rpc_ops = imx8q_rpc_ops;
+		size = ARRAY_SIZE(imx8q_rpc_ops);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (type >= size)
+		return NULL;
+
+	return &rpc_ops[type];
+}
+
+struct vpu_iface_ops *vpu_core_get_iface(struct vpu_core *core)
+{
+	return vpu_get_iface(core->vpu, core->type);
+}
+
+struct vpu_iface_ops *vpu_inst_get_iface(struct vpu_inst *inst)
+{
+	if (inst->core)
+		return vpu_core_get_iface(inst->core);
+
+	return vpu_get_iface(inst->vpu, inst->type);
+}
diff --git a/drivers/media/platform/amphion/vpu_rpc.h b/drivers/media/platform/amphion/vpu_rpc.h
new file mode 100644
index 000000000000..c764ff52d026
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_rpc.h
@@ -0,0 +1,456 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_RPC_H
+#define _AMPHION_VPU_RPC_H
+
+#include <media/videobuf2-core.h>
+#include "vpu_codec.h"
+
+struct vpu_rpc_buffer_desc {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+};
+
+struct vpu_shared_addr {
+	void *iface;
+	struct vpu_rpc_buffer_desc *cmd_desc;
+	void *cmd_mem_vir;
+	struct vpu_rpc_buffer_desc *msg_desc;
+	void *msg_mem_vir;
+
+	unsigned long boot_addr;
+	struct vpu_core *core;
+	void *priv;
+};
+
+struct vpu_rpc_event_header {
+	u32 index;
+	u32 id;
+	u32 num;
+};
+
+struct vpu_rpc_event {
+	struct vpu_rpc_event_header hdr;
+	u32 data[128];
+};
+
+struct vpu_iface_ops {
+	bool (*check_codec)(enum vpu_core_type type);
+	bool (*check_fmt)(enum vpu_core_type type, u32 pixelfmt);
+	u32 (*get_data_size)(void);
+	u32 (*check_memory_region)(dma_addr_t base, dma_addr_t addr, u32 size);
+	int (*boot_core)(struct vpu_core *core);
+	int (*shutdown_core)(struct vpu_core *core);
+	int (*restore_core)(struct vpu_core *core);
+	int (*get_power_state)(struct vpu_core *core);
+	int (*on_firmware_loaded)(struct vpu_core *core);
+	void (*init_rpc)(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr);
+	void (*set_log_buf)(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log);
+	void (*set_system_cfg)(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 index);
+	void (*set_stream_cfg)(struct vpu_shared_addr *shared, u32 index);
+	u32 (*get_version)(struct vpu_shared_addr *shared);
+	u32 (*get_max_instance_count)(struct vpu_shared_addr *shared);
+	int (*get_stream_buffer_size)(struct vpu_shared_addr *shared);
+	int (*send_cmd_buf)(struct vpu_shared_addr *shared,
+			    struct vpu_rpc_event *cmd);
+	int (*receive_msg_buf)(struct vpu_shared_addr *shared,
+			       struct vpu_rpc_event *msg);
+	int (*pack_cmd)(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+	int (*convert_msg_id)(u32 msg_id);
+	int (*unpack_msg_data)(struct vpu_rpc_event *pkt, void *data);
+	int (*input_frame)(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*config_memory_resource)(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      u32 type,
+				      u32 index,
+				      struct vpu_buffer *buf);
+	int (*config_stream_buffer)(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_buffer *buf);
+	int (*update_stream_buffer)(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write);
+	int (*get_stream_buffer_desc)(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc);
+	int (*set_encode_params)(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_encode_params *params,
+				 u32 update);
+	int (*set_decode_params)(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params,
+				 u32 update);
+	int (*add_scode)(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type);
+	int (*pre_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*post_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*init_instance)(struct vpu_shared_addr *shared, u32 instance);
+};
+
+enum {
+	VPU_CORE_MEMORY_INVALID = 0,
+	VPU_CORE_MEMORY_CACHED,
+	VPU_CORE_MEMORY_UNCACHED
+};
+
+struct vpu_rpc_region_t {
+	dma_addr_t start;
+	dma_addr_t end;
+	dma_addr_t type;
+};
+
+struct vpu_iface_ops *vpu_core_get_iface(struct vpu_core *core);
+struct vpu_iface_ops *vpu_inst_get_iface(struct vpu_inst *inst);
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size);
+
+static inline bool vpu_iface_check_codec(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->check_codec)
+		return ops->check_codec(core->type);
+
+	return true;
+}
+
+static inline bool vpu_iface_check_format(struct vpu_inst *inst, u32 pixelfmt)
+{
+	struct vpu_iface_ops *ops = vpu_inst_get_iface(inst);
+
+	if (ops && ops->check_fmt)
+		return ops->check_fmt(inst->type, pixelfmt);
+
+	return true;
+}
+
+static inline int vpu_iface_boot_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->boot_core)
+		return ops->boot_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_get_power_state(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->get_power_state)
+		return ops->get_power_state(core);
+	return 1;
+}
+
+static inline int vpu_iface_shutdown_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->shutdown_core)
+		return ops->shutdown_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_restore_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->restore_core)
+		return ops->restore_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_on_firmware_loaded(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->on_firmware_loaded)
+		return ops->on_firmware_loaded(core);
+
+	return 0;
+}
+
+static inline u32 vpu_iface_get_data_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_data_size)
+		return 0;
+
+	return ops->get_data_size();
+}
+
+static inline int vpu_iface_init(struct vpu_core *core,
+				 struct vpu_shared_addr *shared,
+				 struct vpu_buffer *rpc,
+				 dma_addr_t boot_addr)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->init_rpc)
+		return -EINVAL;
+
+	ops->init_rpc(shared, rpc, boot_addr);
+	core->iface = shared;
+	shared->core = core;
+	if (rpc->bytesused > rpc->length)
+		return -ENOSPC;
+	return 0;
+}
+
+static inline int vpu_iface_set_log_buf(struct vpu_core *core,
+					struct vpu_buffer *log)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops)
+		return -EINVAL;
+
+	if (ops->set_log_buf)
+		ops->set_log_buf(core->iface, log);
+
+	return 0;
+}
+
+static inline int vpu_iface_config_system(struct vpu_core *core, u32 regs_base, void __iomem *regs)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_system_cfg)
+		ops->set_system_cfg(core->iface, regs_base, regs, core->id);
+
+	return 0;
+}
+
+static inline int vpu_iface_get_stream_buffer_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_stream_buffer_size)
+		return 0;
+
+	return ops->get_stream_buffer_size(core->iface);
+}
+
+static inline int vpu_iface_config_stream(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || inst->id < 0)
+		return -EINVAL;
+	if (ops->set_stream_cfg)
+		ops->set_stream_cfg(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_send_cmd(struct vpu_core *core, struct vpu_rpc_event *cmd)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->send_cmd_buf)
+		return -EINVAL;
+
+	return ops->send_cmd_buf(core->iface, cmd);
+}
+
+static inline int vpu_iface_receive_msg(struct vpu_core *core, struct vpu_rpc_event *msg)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->receive_msg_buf)
+		return -EINVAL;
+
+	return ops->receive_msg_buf(core->iface, msg);
+}
+
+static inline int vpu_iface_pack_cmd(struct vpu_core *core,
+				     struct vpu_rpc_event *pkt,
+				     u32 index, u32 id, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->pack_cmd)
+		return -EINVAL;
+	return ops->pack_cmd(pkt, index, id, data);
+}
+
+static inline int vpu_iface_convert_msg_id(struct vpu_core *core, u32 msg_id)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->convert_msg_id)
+		return -EINVAL;
+
+	return ops->convert_msg_id(msg_id);
+}
+
+static inline int vpu_iface_unpack_msg_data(struct vpu_core *core,
+					    struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->unpack_msg_data)
+		return -EINVAL;
+
+	return ops->unpack_msg_data(pkt, data);
+}
+
+static inline int vpu_iface_input_frame(struct vpu_inst *inst,
+					struct vb2_buffer *vb)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->input_frame)
+		return -EINVAL;
+
+	return ops->input_frame(inst->core->iface, inst, vb);
+}
+
+static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
+						   u32 type,
+						   u32 index,
+						   struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->config_memory_resource || inst->id < 0)
+		return -EINVAL;
+
+	return ops->config_memory_resource(inst->core->iface,
+					inst->id,
+					type, index, buf);
+}
+
+static inline int vpu_iface_config_stream_buffer(struct vpu_inst *inst,
+						 struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->config_stream_buffer || inst->id < 0)
+		return -EINVAL;
+
+	return ops->config_stream_buffer(inst->core->iface, inst->id, buf);
+}
+
+static inline int vpu_iface_update_stream_buffer(struct vpu_inst *inst,
+						 u32 ptr, bool write)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->update_stream_buffer || inst->id < 0)
+		return -EINVAL;
+
+	return ops->update_stream_buffer(inst->core->iface, inst->id, ptr, write);
+}
+
+static inline int vpu_iface_get_stream_buffer_desc(struct vpu_inst *inst,
+						   struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->get_stream_buffer_desc || inst->id < 0)
+		return -EINVAL;
+
+	if (!desc)
+		return 0;
+
+	return ops->get_stream_buffer_desc(inst->core->iface, inst->id, desc);
+}
+
+static inline u32 vpu_iface_get_version(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_version)
+		return 0;
+
+	return ops->get_version(core->iface);
+}
+
+static inline u32 vpu_iface_get_max_instance_count(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_max_instance_count)
+		return 0;
+
+	return ops->get_max_instance_count(core->iface);
+}
+
+static inline int vpu_iface_set_encode_params(struct vpu_inst *inst,
+					      struct vpu_encode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->set_encode_params || inst->id < 0)
+		return -EINVAL;
+
+	return ops->set_encode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_set_decode_params(struct vpu_inst *inst,
+					      struct vpu_decode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->set_decode_params  || inst->id < 0)
+		return -EINVAL;
+
+	return ops->set_decode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_add_scode(struct vpu_inst *inst, u32 scode_type)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->add_scode  || inst->id < 0)
+		return -EINVAL;
+
+	return ops->add_scode(inst->core->iface, inst->id,
+				&inst->stream_buffer,
+				inst->out_format.pixfmt,
+				scode_type);
+}
+
+static inline int vpu_iface_pre_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->pre_send_cmd && inst->id >= 0)
+		return ops->pre_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_post_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->post_send_cmd && inst->id >= 0)
+		return ops->post_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_init_instance(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->init_instance && inst->id >= 0)
+		return ops->init_instance(inst->core->iface, inst->id);
+
+	return 0;
+}
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:21 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:21 +0800
Subject: [PATCH v15 05/13] media: amphion: implement vpu core communication
 based on mailbox
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <e79fdc909c88773516ef875bc07039af534ff182.1643077283.git.ming.qian@nxp.com>

driver use mailbox to communicate with vpu core.
and there are a command buffer and a message buffer.
driver will write commands to the command buffer,
then trigger a vpu core interrupt
vpu core will write messages to the message buffer,
then trigger a cpu interrupt.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_cmds.c | 436 ++++++++++++++++++++++
 drivers/media/platform/amphion/vpu_cmds.h |  25 ++
 drivers/media/platform/amphion/vpu_mbox.c | 118 ++++++
 drivers/media/platform/amphion/vpu_mbox.h |  16 +
 drivers/media/platform/amphion/vpu_msgs.c | 385 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_msgs.h |  14 +
 6 files changed, 994 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.h

diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
new file mode 100644
index 000000000000..51e404ebda8f
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_cmds.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+
+struct vpu_cmd_request {
+	u32 request;
+	u32 response;
+	u32 handled;
+};
+
+struct vpu_cmd_t {
+	struct list_head list;
+	u32 id;
+	struct vpu_cmd_request *request;
+	struct vpu_rpc_event *pkt;
+	unsigned long key;
+};
+
+static struct vpu_cmd_request vpu_cmd_requests[] = {
+	{
+		.request = VPU_CMD_ID_CONFIGURE_CODEC,
+		.response = VPU_MSG_ID_MEM_REQUEST,
+		.handled = 1,
+	},
+	{
+		.request = VPU_CMD_ID_START,
+		.response = VPU_MSG_ID_START_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_STOP,
+		.response = VPU_MSG_ID_STOP_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_ABORT,
+		.response = VPU_MSG_ID_ABORT_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_RST_BUF,
+		.response = VPU_MSG_ID_BUF_RST,
+		.handled = 1,
+	},
+};
+
+static int vpu_cmd_send(struct vpu_core *core, struct vpu_rpc_event *pkt)
+{
+	int ret = 0;
+
+	ret = vpu_iface_send_cmd(core, pkt);
+	if (ret)
+		return ret;
+
+	/*write cmd data to cmd buffer before trigger a cmd interrupt*/
+	mb();
+	vpu_mbox_send_type(core, COMMAND);
+
+	return ret;
+}
+
+static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	struct vpu_cmd_t *cmd;
+	int i;
+	int ret;
+
+	cmd = vzalloc(sizeof(*cmd));
+	if (!cmd)
+		return NULL;
+
+	cmd->pkt = vzalloc(sizeof(*cmd->pkt));
+	if (!cmd->pkt) {
+		vfree(cmd);
+		return NULL;
+	}
+
+	cmd->id = id;
+	ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
+	if (ret) {
+		dev_err(inst->dev, "iface pack cmd(%d) fail\n", id);
+		vfree(cmd->pkt);
+		vfree(cmd);
+		return NULL;
+	}
+	for (i = 0; i < ARRAY_SIZE(vpu_cmd_requests); i++) {
+		if (vpu_cmd_requests[i].request == id) {
+			cmd->request = &vpu_cmd_requests[i];
+			break;
+		}
+	}
+
+	return cmd;
+}
+
+static void vpu_free_cmd(struct vpu_cmd_t *cmd)
+{
+	if (!cmd)
+		return;
+	if (cmd->pkt)
+		vfree(cmd->pkt);
+	vfree(cmd);
+}
+
+static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)
+{
+	int ret;
+
+	if (!inst || !cmd || !cmd->pkt)
+		return -EINVAL;
+
+	dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id);
+	vpu_iface_pre_send_cmd(inst);
+	ret = vpu_cmd_send(inst->core, cmd->pkt);
+	if (!ret) {
+		vpu_iface_post_send_cmd(inst);
+		vpu_inst_record_flow(inst, cmd->id);
+	} else {
+		dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id);
+	}
+
+	return ret;
+}
+
+static void vpu_process_cmd_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	if (!inst || inst->pending)
+		return;
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		if (vpu_session_process_cmd(inst, cmd))
+			dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id);
+		if (cmd->request) {
+			inst->pending = (void *)cmd;
+			break;
+		}
+		vpu_free_cmd(cmd);
+	}
+}
+
+static int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data,
+			   unsigned long *key, int *sync)
+{
+	struct vpu_core *core;
+	struct vpu_cmd_t *cmd;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	cmd = vpu_alloc_cmd(inst, id, data);
+	if (!cmd)
+		return -ENOMEM;
+
+	mutex_lock(&core->cmd_lock);
+	cmd->key = core->cmd_seq++;
+	if (key)
+		*key = cmd->key;
+	if (sync)
+		*sync = cmd->request ? true : false;
+	list_add_tail(&cmd->list, &inst->cmd_q);
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+static void vpu_clear_pending(struct vpu_inst *inst)
+{
+	if (!inst || !inst->pending)
+		return;
+
+	vpu_free_cmd(inst->pending);
+	wake_up_all(&inst->core->ack_wq);
+	inst->pending = NULL;
+}
+
+static bool vpu_check_response(struct vpu_cmd_t *cmd, u32 response, u32 handled)
+{
+	struct vpu_cmd_request *request;
+
+	if (!cmd || !cmd->request)
+		return false;
+
+	request = cmd->request;
+	if (request->response != response)
+		return false;
+	if (request->handled != handled)
+		return false;
+
+	return true;
+}
+
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->cmd_lock);
+	if (vpu_check_response(inst->pending, response, handled))
+		vpu_clear_pending(inst);
+
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+void vpu_clear_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	mutex_lock(&inst->core->cmd_lock);
+	if (inst->pending)
+		vpu_clear_pending(inst);
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		vpu_free_cmd(cmd);
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+}
+
+static bool check_is_responsed(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core = inst->core;
+	struct vpu_cmd_t *cmd;
+	bool flag = true;
+
+	mutex_lock(&core->cmd_lock);
+	cmd = inst->pending;
+	if (cmd && key == cmd->key) {
+		flag = false;
+		goto exit;
+	}
+	list_for_each_entry(cmd, &inst->cmd_q, list) {
+		if (key == cmd->key) {
+			flag = false;
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->cmd_lock);
+
+	return flag;
+}
+
+static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	call_vop(inst, wait_prepare);
+	wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), VPU_TIMEOUT);
+	call_vop(inst, wait_finish);
+
+	if (!check_is_responsed(inst, key)) {
+		dev_err(inst->dev, "[%d] sync session timeout\n", inst->id);
+		set_bit(inst->id, &core->hang_mask);
+		mutex_lock(&inst->core->cmd_lock);
+		vpu_clear_pending(inst);
+		mutex_unlock(&inst->core->cmd_lock);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	unsigned long key;
+	int sync = false;
+	int ret = -EINVAL;
+
+	if (inst->id < 0)
+		return -EINVAL;
+
+	ret = vpu_request_cmd(inst, id, data, &key, &sync);
+	if (!ret && sync)
+		ret = sync_session_response(inst, key);
+
+	if (ret)
+		dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id);
+
+	return ret;
+}
+
+int vpu_session_configure_codec(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_CONFIGURE_CODEC, NULL);
+}
+
+int vpu_session_start(struct vpu_inst *inst)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_START, NULL);
+}
+
+int vpu_session_stop(struct vpu_inst *inst)
+{
+	int ret;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_STOP, NULL);
+	/* workaround for a firmware bug,
+	 * if the next command is too close after stop cmd,
+	 * the firmware may enter wfi wrongly.
+	 */
+	usleep_range(3000, 5000);
+	return ret;
+}
+
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FRAME_ENCODE, &timestamp);
+}
+
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_ALLOC, fs);
+}
+
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_RELEASE, fs);
+}
+
+int vpu_session_abort(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_ABORT, NULL);
+}
+
+int vpu_session_rst_buf(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_RST_BUF, NULL);
+}
+
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_TIMESTAMP, info);
+}
+
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg)
+{
+	if (inst->type & VPU_CORE_TYPE_DEC)
+		vpu_iface_set_decode_params(inst, arg, 1);
+	else
+		vpu_iface_set_encode_params(inst, arg, 1);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_UPDATE_PARAMETER, arg);
+}
+
+int vpu_session_debug(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_DEBUG, NULL);
+}
+
+int vpu_core_snapshot(struct vpu_core *core)
+{
+	struct vpu_inst *inst;
+	int ret;
+
+	if (!core || list_empty(&core->instances))
+		return 0;
+
+	inst = list_first_entry(&core->instances, struct vpu_inst, list);
+
+	reinit_completion(&core->cmp);
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_SNAPSHOT, NULL);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "snapshot timeout\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_core_sw_reset(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_FIRM_RESET, NULL);
+
+	reinit_completion(&core->cmp);
+	mutex_lock(&core->cmd_lock);
+	ret = vpu_cmd_send(core, &pkt);
+	mutex_unlock(&core->cmd_lock);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "sw reset timeout\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_cmds.h b/drivers/media/platform/amphion/vpu_cmds.h
new file mode 100644
index 000000000000..bc538d277bc9
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_cmds.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CMDS_H
+#define _AMPHION_VPU_CMDS_H
+
+int vpu_session_configure_codec(struct vpu_inst *inst);
+int vpu_session_start(struct vpu_inst *inst);
+int vpu_session_stop(struct vpu_inst *inst);
+int vpu_session_abort(struct vpu_inst *inst);
+int vpu_session_rst_buf(struct vpu_inst *inst);
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp);
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info);
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg);
+int vpu_core_snapshot(struct vpu_core *core);
+int vpu_core_sw_reset(struct vpu_core *core);
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled);
+void vpu_clear_request(struct vpu_inst *inst);
+int vpu_session_debug(struct vpu_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c
new file mode 100644
index 000000000000..bf759eb2fd46
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_mbox.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+
+static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
+{
+	struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
+	struct vpu_core *core = container_of(rx, struct vpu_core, rx);
+
+	vpu_isr(core, *(u32 *)msg);
+}
+
+static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
+{
+	struct mbox_chan *ch;
+	struct mbox_client *cl;
+
+	if (!dev || !mbox)
+		return -EINVAL;
+	if (mbox->ch)
+		return 0;
+
+	cl = &mbox->cl;
+	cl->dev = dev;
+	if (mbox->block) {
+		cl->tx_block = true;
+		cl->tx_tout = 1000;
+	} else {
+		cl->tx_block = false;
+	}
+	cl->knows_txdone = false;
+	cl->rx_callback = vpu_mbox_rx_callback;
+
+	ch = mbox_request_channel_byname(cl, mbox->name);
+	if (IS_ERR(ch)) {
+		dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n",
+			mbox->name, PTR_ERR(ch));
+		return PTR_ERR(ch);
+	}
+
+	mbox->ch = ch;
+	return 0;
+}
+
+int vpu_mbox_init(struct vpu_core *core)
+{
+	scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
+	core->tx_type.block = true;
+
+	scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
+	core->tx_data.block = false;
+
+	scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
+	core->rx.block = true;
+
+	return 0;
+}
+
+int vpu_mbox_request(struct vpu_core *core)
+{
+	int ret;
+
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->rx);
+	if (ret)
+		goto error;
+
+	dev_dbg(core->dev, "%s request mbox\n", vpu_core_type_desc(core->type));
+	return 0;
+error:
+	vpu_mbox_free(core);
+	return ret;
+}
+
+void vpu_mbox_free(struct vpu_core *core)
+{
+	mbox_free_channel(core->tx_type.ch);
+	mbox_free_channel(core->tx_data.ch);
+	mbox_free_channel(core->rx.ch);
+	core->tx_type.ch = NULL;
+	core->tx_data.ch = NULL;
+	core->rx.ch = NULL;
+	dev_dbg(core->dev, "%s free mbox\n", vpu_core_type_desc(core->type));
+}
+
+void vpu_mbox_send_type(struct vpu_core *core, u32 type)
+{
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
+{
+	mbox_send_message(core->tx_data.ch, &data);
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_enable_rx(struct vpu_dev *dev)
+{
+}
diff --git a/drivers/media/platform/amphion/vpu_mbox.h b/drivers/media/platform/amphion/vpu_mbox.h
new file mode 100644
index 000000000000..79cfd874e92b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_mbox.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MBOX_H
+#define _AMPHION_VPU_MBOX_H
+
+int vpu_mbox_init(struct vpu_core *core);
+int vpu_mbox_request(struct vpu_core *core);
+void vpu_mbox_free(struct vpu_core *core);
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
+void vpu_mbox_send_type(struct vpu_core *core, u32 type);
+void vpu_mbox_enable_rx(struct vpu_dev *dev);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
new file mode 100644
index 000000000000..a406ab08e490
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_msgs.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_msgs.h"
+#include "vpu_v4l2.h"
+
+#define VPU_PKT_HEADER_LENGTH		3
+
+struct vpu_msg_handler {
+	u32 id;
+	void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt);
+};
+
+static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+}
+
+static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_pkt_mem_req_data req_data;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
+	vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n",
+		  inst->id,
+		  req_data.enc_frame_size,
+		  req_data.enc_frame_num,
+		  req_data.ref_frame_size,
+		  req_data.ref_frame_num,
+		  req_data.act_buf_size,
+		  req_data.act_buf_num);
+	call_vop(inst, mem_request,
+		 req_data.enc_frame_size,
+		 req_data.enc_frame_num,
+		 req_data.ref_frame_size,
+		 req_data.ref_frame_num,
+		 req_data.act_buf_size,
+		 req_data.act_buf_num);
+}
+
+static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	call_vop(inst, stop_done);
+}
+
+static void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_codec_info info;
+	const struct vpu_core_resources *res;
+
+	memset(&info, 0, sizeof(info));
+	res = vpu_get_resource(inst);
+	info.stride = res ? res->stride : 1;
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info);
+}
+
+static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL);
+}
+
+static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_enc_pic_info info;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n",
+		inst->id, info.frame_id, info.wptr, info.frame_size);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_fs_info fs;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+	call_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
+}
+
+static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	if (inst->core->type == VPU_CORE_TYPE_ENC) {
+		struct vpu_frame_info info;
+
+		memset(&info, 0, sizeof(info));
+		vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence);
+		dev_dbg(inst->dev, "[%d] %d\n", inst->id, info.sequence);
+		info.type = inst->out_format.type;
+		call_vop(inst, buf_done, &info);
+	} else if (inst->core->type == VPU_CORE_TYPE_DEC) {
+		struct vpu_fs_info fs;
+
+		vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+		call_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
+	}
+}
+
+static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	dev_dbg(inst->dev, "[%d]\n", inst->id);
+	call_vop(inst, input_done);
+}
+
+static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+	struct vpu_frame_info frame;
+
+	memset(&frame, 0, sizeof(frame));
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	if (inst->core->type == VPU_CORE_TYPE_DEC)
+		frame.type = inst->cap_format.type;
+	frame.id = info.id;
+	frame.luma = info.luma;
+	frame.skipped = info.skipped;
+	frame.timestamp = info.timestamp;
+
+	call_vop(inst, buf_done, &frame);
+}
+
+static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL);
+}
+
+static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	dev_err(inst->dev, "unsupported stream\n");
+	call_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
+	vpu_v4l2_set_error(inst);
+}
+
+static void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	char *str = (char *)pkt->data;
+
+	dev_err(inst->dev, "%s firmware xcpt: %s\n",
+		vpu_core_type_desc(inst->core->type), str);
+	call_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL);
+	set_bit(inst->id, &inst->core->hang_mask);
+	vpu_v4l2_set_error(inst);
+}
+
+struct vpu_msg_handler handlers[] = {
+	{VPU_MSG_ID_START_DONE, vpu_session_handle_start_done},
+	{VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done},
+	{VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr},
+	{VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done},
+	{VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request},
+	{VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release},
+	{VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done},
+	{VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded},
+	{VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done},
+	{VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos},
+	{VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error},
+	{VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt},
+};
+
+static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg)
+{
+	int ret;
+	u32 msg_id;
+	struct vpu_msg_handler *handler = NULL;
+	unsigned int i;
+
+	ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id);
+	if (ret < 0)
+		return -EINVAL;
+
+	msg_id = ret;
+	dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id);
+
+	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+		if (handlers[i].id == msg_id) {
+			handler = &handlers[i];
+			break;
+		}
+	}
+
+	if (handler && handler->done)
+		handler->done(inst, msg);
+
+	vpu_response_cmd(inst, msg_id, 1);
+
+	return 0;
+}
+
+static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes = sizeof(struct vpu_rpc_event_header);
+	u32 ret;
+
+	memset(pkt, 0, sizeof(*pkt));
+	if (kfifo_len(&inst->msg_fifo) < bytes)
+		return false;
+
+	ret = kfifo_out(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		return false;
+
+	if (pkt->hdr.num > 0) {
+		bytes = pkt->hdr.num * sizeof(u32);
+		ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes);
+		if (ret != bytes)
+			return false;
+	}
+
+	return true;
+}
+
+void vpu_inst_run_work(struct work_struct *work)
+{
+	struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work);
+	struct vpu_rpc_event pkt;
+
+	while (vpu_inst_receive_msg(inst, &pkt))
+		vpu_session_handle_msg(inst, &pkt);
+}
+
+static void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes;
+	u32 id = pkt->hdr.id;
+	int ret;
+
+	if (!inst->workqueue)
+		return;
+
+	bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32);
+	ret = kfifo_in(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		dev_err(inst->dev, "[%d:%d]overflow: %d\n", inst->core->id, inst->id, id);
+	queue_work(inst->workqueue, &inst->msg_work);
+}
+
+static int vpu_handle_msg(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	struct vpu_inst *inst;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	while (!vpu_iface_receive_msg(core, &pkt)) {
+		dev_dbg(core->dev, "event index = %d, id = %d, num = %d\n",
+			pkt.hdr.index, pkt.hdr.id, pkt.hdr.num);
+
+		ret = vpu_iface_convert_msg_id(core, pkt.hdr.id);
+		if (ret < 0)
+			continue;
+
+		inst = vpu_core_find_instance(core, pkt.hdr.index);
+		if (inst) {
+			vpu_response_cmd(inst, ret, 0);
+			mutex_lock(&core->cmd_lock);
+			vpu_inst_record_flow(inst, ret);
+			mutex_unlock(&core->cmd_lock);
+
+			vpu_inst_handle_msg(inst, &pkt);
+			vpu_inst_put(inst);
+		}
+		memset(&pkt, 0, sizeof(pkt));
+	}
+
+	return 0;
+}
+
+static int vpu_isr_thread(struct vpu_core *core, u32 irq_code)
+{
+	dev_dbg(core->dev, "irq code = 0x%x\n", irq_code);
+	switch (irq_code) {
+	case VPU_IRQ_CODE_SYNC:
+		vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys);
+		vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys);
+		vpu_mbox_send_msg(core, INIT_DONE, 2);
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		break;
+	default:
+		vpu_handle_msg(core);
+		break;
+	}
+
+	return 0;
+}
+
+static void vpu_core_run_msg_work(struct vpu_core *core)
+{
+	const unsigned int SIZE = sizeof(u32);
+
+	while (kfifo_len(&core->msg_fifo) >= SIZE) {
+		u32 data;
+
+		if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE)
+			vpu_isr_thread(core, data);
+	}
+}
+
+void vpu_msg_run_work(struct work_struct *work)
+{
+	struct vpu_core *core = container_of(work, struct vpu_core, msg_work);
+	unsigned long delay = msecs_to_jiffies(10);
+
+	vpu_core_run_msg_work(core);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+}
+
+void vpu_msg_delayed_work(struct work_struct *work)
+{
+	struct vpu_core *core;
+	struct delayed_work *dwork;
+	u32 bytes = sizeof(bytes);
+	u32 i;
+
+	if (!work)
+		return;
+
+	dwork = to_delayed_work(work);
+	core = container_of(dwork, struct vpu_core, msg_delayed_work);
+	if (kfifo_len(&core->msg_fifo) >= bytes)
+		vpu_core_run_msg_work(core);
+
+	bytes = sizeof(struct vpu_rpc_event_header);
+	for (i = 0; i < core->supported_instance_count; i++) {
+		struct vpu_inst *inst = vpu_core_find_instance(core, i);
+
+		if (!inst)
+			continue;
+
+		if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes)
+			queue_work(inst->workqueue, &inst->msg_work);
+
+		vpu_inst_put(inst);
+	}
+}
+
+int vpu_isr(struct vpu_core *core, u32 irq)
+{
+	switch (irq) {
+	case VPU_IRQ_CODE_SYNC:
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		complete(&core->cmp);
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		complete(&core->cmp);
+		break;
+	default:
+		break;
+	}
+
+	if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq))
+		dev_err(core->dev, "[%d]overflow: %d\n", core->id, irq);
+	queue_work(core->workqueue, &core->msg_work);
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_msgs.h b/drivers/media/platform/amphion/vpu_msgs.h
new file mode 100644
index 000000000000..c466b4f62aad
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_msgs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MSGS_H
+#define _AMPHION_VPU_MSGS_H
+
+int vpu_isr(struct vpu_core *core, u32 irq);
+void vpu_inst_run_work(struct work_struct *work);
+void vpu_msg_run_work(struct work_struct *work);
+void vpu_msg_delayed_work(struct work_struct *work);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:22 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:22 +0800
Subject: [PATCH v15 06/13] media: amphion: add vpu v4l2 m2m support
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <778bc3b430f3b934f9c19b6243d5d11e0e86eb59.1643077283.git.ming.qian@nxp.com>

vpu_v4l2.c implements the v4l2 m2m driver methods.
vpu_helpers.c implements the common helper functions
vpu_color.c converts the v4l2 colorspace with
the VUI parameters that specified by ITU-T | ISO/IEC

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_color.c   | 183 +++++
 drivers/media/platform/amphion/vpu_helpers.c | 413 +++++++++++
 drivers/media/platform/amphion/vpu_helpers.h |  74 ++
 drivers/media/platform/amphion/vpu_v4l2.c    | 720 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_v4l2.h    |  55 ++
 5 files changed, 1445 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_color.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h

diff --git a/drivers/media/platform/amphion/vpu_color.c b/drivers/media/platform/amphion/vpu_color.c
new file mode 100644
index 000000000000..80b9a53fd1c1
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_color.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+#include "vpu.h"
+#include "vpu_helpers.h"
+
+static const u8 colorprimaries[] = {
+	0,
+	V4L2_COLORSPACE_REC709,         /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	V4L2_COLORSPACE_470_SYSTEM_M,   /*Rec. ITU-R BT.470-6 System M*/
+	V4L2_COLORSPACE_470_SYSTEM_BG,  /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_COLORSPACE_SMPTE170M,      /*SMPTE170M*/
+	V4L2_COLORSPACE_SMPTE240M,      /*SMPTE240M*/
+	0,                              /*Generic film*/
+	V4L2_COLORSPACE_BT2020,         /*Rec. ITU-R BT.2020-2*/
+	0,                              /*SMPTE ST 428-1*/
+};
+
+static const u8 colortransfers[] = {
+	0,
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                              /*Rec. ITU-R BT.470-6 System M*/
+	0,                              /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_XFER_FUNC_709,             /*SMPTE170M*/
+	V4L2_XFER_FUNC_SMPTE240M,       /*SMPTE240M*/
+	V4L2_XFER_FUNC_NONE,            /*Linear transfer characteristics*/
+	0,
+	0,
+	0,                              /*IEC 61966-2-4*/
+	0,                              /*Rec. ITU-R BT.1361-0 extended colour gamut*/
+	V4L2_XFER_FUNC_SRGB,            /*IEC 61966-2-1 sRGB or sYCC*/
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (10 bit system)*/
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (12 bit system)*/
+	V4L2_XFER_FUNC_SMPTE2084,       /*SMPTE ST 2084*/
+	0,                              /*SMPTE ST 428-1*/
+	0                               /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
+};
+
+static const u8 colormatrixcoefs[] = {
+	0,
+	V4L2_YCBCR_ENC_709,              /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                               /*Title 47 Code of Federal Regulations*/
+	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 625*/
+	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 525*/
+	V4L2_YCBCR_ENC_SMPTE240M,        /*SMPTE240M*/
+	0,
+	V4L2_YCBCR_ENC_BT2020,           /*Rec. ITU-R BT.2020-2*/
+	V4L2_YCBCR_ENC_BT2020_CONST_LUM  /*Rec. ITU-R BT.2020-2 constant*/
+};
+
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
+{
+	return vpu_helper_find_in_array_u8(colorprimaries, ARRAY_SIZE(colorprimaries), primaries);
+}
+
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
+{
+	return primaries < ARRAY_SIZE(colorprimaries) ? colorprimaries[primaries] : 0;
+}
+
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
+{
+	return vpu_helper_find_in_array_u8(colortransfers, ARRAY_SIZE(colortransfers), transfers);
+}
+
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
+{
+	return transfers < ARRAY_SIZE(colortransfers) ? colortransfers[transfers] : 0;
+}
+
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
+{
+	return vpu_helper_find_in_array_u8(colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), matrix);
+}
+
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
+{
+	return matrix < ARRAY_SIZE(colormatrixcoefs) ? colormatrixcoefs[matrix] : 0;
+}
+
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
+{
+	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
+}
+
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
+{
+	if (full_range)
+		return V4L2_QUANTIZATION_FULL_RANGE;
+
+	return V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+int vpu_color_check_primaries(u32 primaries)
+{
+	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_transfers(u32 transfers)
+{
+	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_matrix(u32 matrix)
+{
+	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_full_range(u32 full_range)
+{
+	int ret = -EINVAL;
+
+	switch (full_range) {
+	case V4L2_QUANTIZATION_FULL_RANGE:
+	case V4L2_QUANTIZATION_LIM_RANGE:
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
+{
+	u32 transfers;
+	u32 matrix;
+	u32 full_range;
+
+	switch (primaries) {
+	case V4L2_COLORSPACE_REC709:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+	case V4L2_COLORSPACE_SMPTE170M:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_601;
+		break;
+	case V4L2_COLORSPACE_SMPTE240M:
+		transfers = V4L2_XFER_FUNC_SMPTE240M;
+		matrix = V4L2_YCBCR_ENC_SMPTE240M;
+		break;
+	case V4L2_COLORSPACE_BT2020:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_BT2020;
+		break;
+	default:
+		transfers = V4L2_XFER_FUNC_DEFAULT;
+		matrix = V4L2_YCBCR_ENC_DEFAULT;
+		break;
+	}
+	full_range = V4L2_QUANTIZATION_LIM_RANGE;
+
+	if (ptransfers)
+		*ptransfers = transfers;
+	if (pmatrix)
+		*pmatrix = matrix;
+	if (pfull_range)
+		*pfull_range = full_range;
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c
new file mode 100644
index 000000000000..768abf89e606
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_helpers.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_helpers.h"
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (array[i] == x)
+			return i;
+	}
+
+	return 0;
+}
+
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
+{
+	const struct vpu_format *pfmt;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
+			continue;
+		if (pfmt->type == type)
+			return true;
+	}
+
+	return false;
+}
+
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
+{
+	const struct vpu_format *pfmt;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	if (!vpu_iface_check_format(inst, pixelfmt))
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
+			return pfmt;
+	}
+
+	return NULL;
+}
+
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
+{
+	const struct vpu_format *pfmt;
+	int i = 0;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->type == type) {
+			if (index == i)
+				return pfmt;
+			i++;
+		}
+	}
+
+	return NULL;
+}
+
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst)
+		return width;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return width;
+	if (res->max_width)
+		width = clamp(width, res->min_width, res->max_width);
+	if (res->step_width)
+		width = ALIGN(width, res->step_width);
+
+	return width;
+}
+
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst)
+		return height;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return height;
+	if (res->max_height)
+		height = clamp(height, res->min_height, res->max_height);
+	if (res->step_height)
+		height = ALIGN(height, res->step_height);
+
+	return height;
+}
+
+static u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
+			       u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	height = ALIGN(height, 2);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = bytesperline * height >> 1;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+				      u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 ws = 3;
+	u32 hs = 7;
+	u32 bitdepth = 8;
+	u32 bytesperline;
+	u32 size = 0;
+
+	if (interlaced)
+		hs++;
+	if (fmt == V4L2_PIX_FMT_NV12M_10BE_8L128)
+		bitdepth = 10;
+	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
+	bytesperline = ALIGN(bytesperline, 1 << ws);
+	bytesperline = ALIGN(bytesperline, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	height = ALIGN(height, 1 << hs);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_default_plane_size(u32 width, u32 height, int plane_no,
+				  u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
+			      u32 stride, u32 interlaced, u32 *pbl)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12M:
+		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	case V4L2_PIX_FMT_NV12M_8L128:
+	case V4L2_PIX_FMT_NV12M_10BE_8L128:
+		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
+	default:
+		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	}
+}
+
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+				       u32 *rptr, u32 size, void *dst)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !rptr || !dst)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *rptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memcpy(dst, virt + (offset - start), size);
+	} else {
+		memcpy(dst, virt + (offset - start), end - offset);
+		memcpy(dst + end - offset, virt, size + offset - end);
+	}
+
+	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
+	return size;
+}
+
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				     u32 *wptr, u32 size, void *src)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr || !src)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memcpy(virt + (offset - start), src, size);
+	} else {
+		memcpy(virt + (offset - start), src, end - offset);
+		memcpy(virt, src + end - offset, size + offset - end);
+	}
+
+	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
+
+	return size;
+}
+
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				    u32 *wptr, u8 val, u32 size)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memset(virt + (offset - start), val, size);
+	} else {
+		memset(virt + (offset - start), val, end - offset);
+		memset(virt, val, size + offset - end);
+	}
+
+	offset += size;
+	if (offset >= end)
+		offset -= stream_buffer->length;
+
+	*wptr = offset;
+
+	return size;
+}
+
+u32 vpu_helper_get_free_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.rptr > desc.wptr)
+		return desc.rptr - desc.wptr;
+	else if (desc.rptr < desc.wptr)
+		return (desc.end - desc.start + desc.rptr - desc.wptr);
+	else
+		return desc.end - desc.start;
+}
+
+u32 vpu_helper_get_used_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.wptr > desc.rptr)
+		return desc.wptr - desc.rptr;
+	else if (desc.wptr < desc.rptr)
+		return (desc.end - desc.start + desc.wptr - desc.rptr);
+	else
+		return 0;
+}
+
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		ctrl->val = inst->min_buffer_cap;
+		break;
+	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+		ctrl->val = inst->min_buffer_out;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			      u32 pixelformat, u32 offset, u32 bytesused)
+{
+	u32 start_code;
+	int start_code_size;
+	u32 val = 0;
+	int i;
+	int ret = -EINVAL;
+
+	if (!stream_buffer || !stream_buffer->virt)
+		return -EINVAL;
+
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		start_code_size = 4;
+		start_code = 0x00000001;
+		break;
+	default:
+		return 0;
+	}
+
+	for (i = 0; i < bytesused; i++) {
+		val = (val << 8) | vpu_helper_read_byte(stream_buffer, offset + i);
+		if (i < start_code_size - 1)
+			continue;
+		if (val == start_code) {
+			ret = i + 1 - start_code_size;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].src == src)
+			return pairs[i].dst;
+	}
+
+	return -EINVAL;
+}
+
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].dst == dst)
+			return pairs[i].src;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/media/platform/amphion/vpu_helpers.h b/drivers/media/platform/amphion/vpu_helpers.h
new file mode 100644
index 000000000000..3676cc83e85b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_helpers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_HELPERS_H
+#define _AMPHION_VPU_HELPERS_H
+
+struct vpu_pair {
+	u32 src;
+	u32 dst;
+};
+
+#define MAKE_TIMESTAMP(s, ns)		(((s32)(s) * NSEC_PER_SEC) + (ns))
+#define VPU_INVALID_TIMESTAMP		MAKE_TIMESTAMP(-1, 0)
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x);
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type);
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt);
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index);
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width);
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height);
+u32 vpu_helper_get_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+			      u32 stride, u32 interlaced, u32 *pbl);
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+				       u32 *rptr, u32 size, void *dst);
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				     u32 *wptr, u32 size, void *src);
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				    u32 *wptr, u8 val, u32 size);
+u32 vpu_helper_get_free_space(struct vpu_inst *inst);
+u32 vpu_helper_get_used_space(struct vpu_inst *inst);
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
+void vpu_helper_get_kmp_next(const u8 *pattern, int *next, int size);
+int vpu_helper_kmp_search(u8 *s, int s_len, const u8 *p, int p_len, int *next);
+int vpu_helper_kmp_search_in_stream_buffer(struct vpu_buffer *stream_buffer,
+					   u32 offset, int bytesused,
+					   const u8 *p, int p_len, int *next);
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			      u32 pixelformat, u32 offset, u32 bytesused);
+
+static inline u32 vpu_helper_step_walk(struct vpu_buffer *stream_buffer, u32 pos, u32 step)
+{
+	pos += step;
+	if (pos > stream_buffer->phys + stream_buffer->length)
+		pos -= stream_buffer->length;
+
+	return pos;
+}
+
+static inline u8 vpu_helper_read_byte(struct vpu_buffer *stream_buffer, u32 pos)
+{
+	u8 *pdata = (u8 *)stream_buffer->virt;
+
+	return pdata[pos % stream_buffer->length];
+}
+
+int vpu_color_check_primaries(u32 primaries);
+int vpu_color_check_transfers(u32 transfers);
+int vpu_color_check_matrix(u32 matrix);
+int vpu_color_check_full_range(u32 full_range);
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers);
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix);
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
+int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
+#endif
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
new file mode 100644
index 000000000000..9d3176c0f5eb
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -0,0 +1,720 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_v4l2.h"
+#include "vpu_msgs.h"
+#include "vpu_helpers.h"
+
+void vpu_inst_lock(struct vpu_inst *inst)
+{
+	mutex_lock(&inst->lock);
+}
+
+void vpu_inst_unlock(struct vpu_inst *inst)
+{
+	mutex_unlock(&inst->lock);
+}
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_dma_contig_plane_dma_addr(vb, plane_no) +
+			vb->planes[plane_no].data_offset;
+}
+
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_plane_size(vb, plane_no) - vb->planes[plane_no].data_offset;
+}
+
+void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state)
+{
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	vpu_buf->state = state;
+}
+
+unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
+{
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	return vpu_buf->state;
+}
+
+void vpu_v4l2_set_error(struct vpu_inst *inst)
+{
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	if (!inst)
+		return;
+
+	vpu_inst_lock(inst);
+	dev_err(inst->dev, "some error occurs in codec\n");
+	if (inst->fh.m2m_ctx) {
+		src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+		dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+		if (src_q)
+			src_q->error = 1;
+		if (dst_q)
+			dst_q->error = 1;
+	}
+	vpu_inst_unlock(inst);
+}
+
+int vpu_notify_eos(struct vpu_inst *inst)
+{
+	static const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_EOS
+	};
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_source_change(struct vpu_inst *inst)
+{
+	static const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+	};
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	return 0;
+}
+
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return -EINVAL;
+
+	if (q->last_buffer_dequeued)
+		return 0;
+	vpu_trace(inst->dev, "last buffer dequeued\n");
+	q->last_buffer_dequeued = true;
+	wake_up(&q->done_wq);
+	vpu_notify_eos(inst);
+	return 0;
+}
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	u32 type = f->type;
+	u32 stride = 1;
+	u32 bytesperline;
+	u32 sizeimage;
+	const struct vpu_format *fmt;
+	const struct vpu_core_resources *res;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, type, pixmp->pixelformat);
+	if (!fmt) {
+		fmt = vpu_helper_enum_format(inst, type, 0);
+		if (!fmt)
+			return NULL;
+		pixmp->pixelformat = fmt->pixfmt;
+	}
+
+	res = vpu_get_resource(inst);
+	if (res)
+		stride = res->stride;
+	if (pixmp->width)
+		pixmp->width = vpu_helper_valid_frame_width(inst, pixmp->width);
+	if (pixmp->height)
+		pixmp->height = vpu_helper_valid_frame_height(inst, pixmp->height);
+	pixmp->flags = fmt->flags;
+	pixmp->num_planes = fmt->num_planes;
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		bytesperline = max_t(s32, pixmp->plane_fmt[i].bytesperline, 0);
+		sizeimage = vpu_helper_get_plane_size(pixmp->pixelformat,
+						      pixmp->width,
+						      pixmp->height,
+						      i,
+						      stride,
+						      pixmp->field > V4L2_FIELD_NONE ? 1 : 0,
+						      &bytesperline);
+		sizeimage = max_t(s32, pixmp->plane_fmt[i].sizeimage, sizeimage);
+		pixmp->plane_fmt[i].bytesperline = bytesperline;
+		pixmp->plane_fmt[i].sizeimage = sizeimage;
+	}
+
+	return fmt;
+}
+
+static bool vpu_check_ready(struct vpu_inst *inst, u32 type)
+{
+	if (!inst)
+		return false;
+	if (inst->state == VPU_CODEC_STATE_DEINIT || inst->id < 0)
+		return false;
+	if (!inst->ops->check_ready)
+		return true;
+	return call_vop(inst, check_ready, type);
+}
+
+int vpu_process_output_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->out_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+		vbuf = &buf->vb;
+		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
+			break;
+		vbuf = NULL;
+	}
+
+	if (!vbuf)
+		return -EINVAL;
+
+	dev_dbg(inst->dev, "[%d]frame id = %d / %d\n",
+		inst->id, vbuf->sequence, inst->sequence);
+	return call_vop(inst, process_output, &vbuf->vb2_buf);
+}
+
+int vpu_process_capture_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->cap_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+		vbuf = &buf->vb;
+		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
+			break;
+		vbuf = NULL;
+	}
+	if (!vbuf)
+		return -EINVAL;
+
+	return call_vop(inst, process_capture, &vbuf->vb2_buf);
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	else
+		q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+
+	return q->num_buffers;
+}
+
+static void vpu_m2m_device_run(void *priv)
+{
+}
+
+static void vpu_m2m_job_abort(void *priv)
+{
+	struct vpu_inst *inst = priv;
+	struct v4l2_m2m_ctx *m2m_ctx = inst->fh.m2m_ctx;
+
+	v4l2_m2m_job_finish(m2m_ctx->m2m_dev, m2m_ctx);
+}
+
+static const struct v4l2_m2m_ops vpu_m2m_ops = {
+	.device_run = vpu_m2m_device_run,
+	.job_abort = vpu_m2m_job_abort
+};
+
+static int vpu_vb2_queue_setup(struct vb2_queue *vq,
+			       unsigned int *buf_count,
+			       unsigned int *plane_count,
+			       unsigned int psize[],
+			       struct device *allocators[])
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vq);
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, vq->type);
+
+	if (*plane_count) {
+		if (*plane_count != cur_fmt->num_planes)
+			return -EINVAL;
+		for (i = 0; i < cur_fmt->num_planes; i++) {
+			if (psize[i] < cur_fmt->sizeimage[i])
+				return -EINVAL;
+		}
+		return 0;
+	}
+
+	*plane_count = cur_fmt->num_planes;
+	for (i = 0; i < cur_fmt->num_planes; i++)
+		psize[i] = cur_fmt->sizeimage[i];
+
+	return 0;
+}
+
+static int vpu_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	return 0;
+}
+
+static int vpu_vb2_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vbuf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int vpu_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_format *cur_fmt;
+	u32 i;
+
+	cur_fmt = vpu_get_format(inst, vb->type);
+	for (i = 0; i < cur_fmt->num_planes; i++) {
+		if (vpu_get_vb_length(vb, i) < cur_fmt->sizeimage[i]) {
+			dev_dbg(inst->dev, "[%d] %s buf[%d] is invalid\n",
+				inst->id, vpu_type_name(vb->type), vb->index);
+			vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
+		}
+	}
+
+	return 0;
+}
+
+static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_queue *q = vb->vb2_queue;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_LAST)
+		vpu_notify_eos(inst);
+
+	if (list_empty(&q->done_list))
+		call_vop(inst, on_queue_empty, q->type);
+}
+
+void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *buf;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		while ((buf = v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else {
+		while ((buf = v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
+}
+
+static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+	struct vpu_format *fmt = vpu_get_format(inst, q->type);
+	int ret;
+
+	vpu_inst_unlock(inst);
+	ret = vpu_inst_register(inst);
+	vpu_inst_lock(inst);
+	if (ret) {
+		vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
+		return ret;
+	}
+
+	vpu_trace(inst->dev, "[%d] %s %c%c%c%c %dx%d %u(%u) %u(%u) %u(%u) %d\n",
+		  inst->id, vpu_type_name(q->type),
+		  fmt->pixfmt,
+		  fmt->pixfmt >> 8,
+		  fmt->pixfmt >> 16,
+		  fmt->pixfmt >> 24,
+		  fmt->width, fmt->height,
+		  fmt->sizeimage[0], fmt->bytesperline[0],
+		  fmt->sizeimage[1], fmt->bytesperline[1],
+		  fmt->sizeimage[2], fmt->bytesperline[2],
+		  q->num_buffers);
+	call_vop(inst, start, q->type);
+	vb2_clear_last_buffer_dequeued(q);
+
+	return 0;
+}
+
+static void vpu_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+
+	vpu_trace(inst->dev, "[%d] %s\n", inst->id, vpu_type_name(q->type));
+
+	call_vop(inst, stop, q->type);
+	vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_ERROR);
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		inst->sequence = 0;
+}
+
+static void vpu_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
+		vbuf->sequence = inst->sequence++;
+		if ((s64)vb->timestamp < 0)
+			vb->timestamp = VPU_INVALID_TIMESTAMP;
+	}
+
+	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
+	vpu_process_output_buffer(inst);
+	vpu_process_capture_buffer(inst);
+}
+
+static const struct vb2_ops vpu_vb2_ops = {
+	.queue_setup        = vpu_vb2_queue_setup,
+	.buf_init           = vpu_vb2_buf_init,
+	.buf_out_validate   = vpu_vb2_buf_out_validate,
+	.buf_prepare        = vpu_vb2_buf_prepare,
+	.buf_finish         = vpu_vb2_buf_finish,
+	.start_streaming    = vpu_vb2_start_streaming,
+	.stop_streaming     = vpu_vb2_stop_streaming,
+	.buf_queue          = vpu_vb2_buf_queue,
+	.wait_prepare       = vb2_ops_wait_prepare,
+	.wait_finish        = vb2_ops_wait_finish,
+};
+
+static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+{
+	struct vpu_inst *inst = priv;
+	int ret;
+
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	inst->out_format.type = src_vq->type;
+	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->ops = &vpu_vb2_ops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_DEC && inst->use_stream_buffer)
+		src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->drv_priv = inst;
+	src_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	src_vq->min_buffers_needed = 1;
+	src_vq->dev = inst->vpu->dev;
+	src_vq->lock = &inst->lock;
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	inst->cap_format.type = dst_vq->type;
+	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->ops = &vpu_vb2_ops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_ENC && inst->use_stream_buffer)
+		dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->drv_priv = inst;
+	dst_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	dst_vq->min_buffers_needed = 1;
+	dst_vq->dev = inst->vpu->dev;
+	dst_vq->lock = &inst->lock;
+	ret = vb2_queue_init(dst_vq);
+	if (ret) {
+		vb2_queue_release(src_vq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vpu_v4l2_release(struct vpu_inst *inst)
+{
+	vpu_trace(inst->vpu->dev, "%p\n", inst);
+
+	vpu_release_core(inst->core);
+	put_device(inst->dev);
+
+	if (inst->workqueue) {
+		cancel_work_sync(&inst->msg_work);
+		destroy_workqueue(inst->workqueue);
+		inst->workqueue = NULL;
+	}
+
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	mutex_destroy(&inst->lock);
+	v4l2_fh_del(&inst->fh);
+	v4l2_fh_exit(&inst->fh);
+
+	call_vop(inst, cleanup);
+
+	return 0;
+}
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct vpu_func *func;
+	int ret = 0;
+
+	if (!file || !inst || !inst->ops)
+		return -EINVAL;
+
+	if (inst->type == VPU_CORE_TYPE_ENC)
+		func = &vpu->encoder;
+	else
+		func = &vpu->decoder;
+
+	atomic_set(&inst->ref_count, 0);
+	vpu_inst_get(inst);
+	inst->vpu = vpu;
+	inst->core = vpu_request_core(vpu, inst->type);
+	if (inst->core)
+		inst->dev = get_device(inst->core->dev);
+	mutex_init(&inst->lock);
+	INIT_LIST_HEAD(&inst->cmd_q);
+	inst->id = VPU_INST_NULL_ID;
+	inst->release = vpu_v4l2_release;
+	inst->pid = current->pid;
+	inst->tgid = current->tgid;
+	inst->min_buffer_cap = 2;
+	inst->min_buffer_out = 2;
+	v4l2_fh_init(&inst->fh, func->vfd);
+	v4l2_fh_add(&inst->fh);
+
+	ret = call_vop(inst, ctrl_init);
+	if (ret)
+		goto error;
+
+	inst->fh.m2m_ctx = v4l2_m2m_ctx_init(func->m2m_dev, inst, vpu_m2m_queue_init);
+	if (IS_ERR(inst->fh.m2m_ctx)) {
+		dev_err(vpu->dev, "v4l2_m2m_ctx_init fail\n");
+		ret = PTR_ERR(func->m2m_dev);
+		goto error;
+	}
+
+	inst->fh.ctrl_handler = &inst->ctrl_handler;
+	file->private_data = &inst->fh;
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (inst->workqueue) {
+		INIT_WORK(&inst->msg_work, vpu_inst_run_work);
+		ret = kfifo_init(&inst->msg_fifo,
+				 inst->msg_buffer,
+				 rounddown_pow_of_two(sizeof(inst->msg_buffer)));
+		if (ret) {
+			destroy_workqueue(inst->workqueue);
+			inst->workqueue = NULL;
+		}
+	}
+	vpu_trace(vpu->dev, "tgid = %d, pid = %d, type = %s, inst = %p\n",
+		  inst->tgid, inst->pid, vpu_core_type_desc(inst->type), inst);
+
+	return 0;
+error:
+	vpu_inst_put(inst);
+	return ret;
+}
+
+int vpu_v4l2_close(struct file *file)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+
+	vpu_inst_lock(inst);
+	if (inst->fh.m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+		inst->fh.m2m_ctx = NULL;
+	}
+	vpu_inst_unlock(inst);
+
+	call_vop(inst, release);
+	vpu_inst_unregister(inst);
+	vpu_inst_put(inst);
+
+	return 0;
+}
+
+int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
+{
+	struct video_device *vfd;
+	int ret;
+
+	if (!vpu || !func)
+		return -EINVAL;
+
+	if (func->vfd)
+		return 0;
+
+	func->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
+	if (IS_ERR(func->m2m_dev)) {
+		dev_err(vpu->dev, "v4l2_m2m_init fail\n");
+		func->vfd = NULL;
+		return PTR_ERR(func->m2m_dev);
+	}
+
+	vfd = video_device_alloc();
+	if (!vfd) {
+		v4l2_m2m_release(func->m2m_dev);
+		dev_err(vpu->dev, "alloc vpu decoder video device fail\n");
+		return -ENOMEM;
+	}
+	vfd->release = video_device_release;
+	vfd->vfl_dir = VFL_DIR_M2M;
+	vfd->v4l2_dev = &vpu->v4l2_dev;
+	vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+	if (func->type == VPU_CORE_TYPE_ENC) {
+		strscpy(vfd->name, "amphion-vpu-encoder", sizeof(vfd->name));
+		vfd->fops = venc_get_fops();
+		vfd->ioctl_ops = venc_get_ioctl_ops();
+	} else {
+		strscpy(vfd->name, "amphion-vpu-decoder", sizeof(vfd->name));
+		vfd->fops = vdec_get_fops();
+		vfd->ioctl_ops = vdec_get_ioctl_ops();
+	}
+
+	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(vfd);
+		v4l2_m2m_release(func->m2m_dev);
+		return ret;
+	}
+	video_set_drvdata(vfd, vpu);
+	func->vfd = vfd;
+
+	ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);
+	if (ret) {
+		v4l2_m2m_release(func->m2m_dev);
+		func->m2m_dev = NULL;
+		video_unregister_device(func->vfd);
+		func->vfd = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void vpu_remove_func(struct vpu_func *func)
+{
+	if (!func)
+		return;
+
+	if (func->m2m_dev) {
+		v4l2_m2m_unregister_media_controller(func->m2m_dev);
+		v4l2_m2m_release(func->m2m_dev);
+		func->m2m_dev = NULL;
+	}
+	if (func->vfd) {
+		video_unregister_device(func->vfd);
+		func->vfd = NULL;
+	}
+}
diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h
new file mode 100644
index 000000000000..90fa7ea67495
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_v4l2.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_V4L2_H
+#define _AMPHION_VPU_V4L2_H
+
+#include <linux/videodev2.h>
+
+void vpu_inst_lock(struct vpu_inst *inst);
+void vpu_inst_unlock(struct vpu_inst *inst);
+void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state);
+unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf);
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst);
+int vpu_v4l2_close(struct file *file);
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
+int vpu_process_output_buffer(struct vpu_inst *inst);
+int vpu_process_capture_buffer(struct vpu_inst *inst);
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
+void vpu_v4l2_set_error(struct vpu_inst *inst);
+int vpu_notify_eos(struct vpu_inst *inst);
+int vpu_notify_source_change(struct vpu_inst *inst);
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst);
+void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state);
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
+static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return &inst->out_format;
+	else
+		return &inst->cap_format;
+}
+
+static inline char *vpu_type_name(u32 type)
+{
+	return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
+static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf)
+{
+#ifdef V4L2_BUF_FLAG_CODECCONFIG
+	return (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) ? 1 : 0;
+#else
+	return 0;
+#endif
+}
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:23 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:23 +0800
Subject: [PATCH v15 07/13] media: amphion: add v4l2 m2m vpu encoder stateful
 driver
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <b42d02b6572468483da10acb41807df8ed7ff8cd.1643077283.git.ming.qian@nxp.com>

This consists of video encoder implementation plus encoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/venc.c | 1364 +++++++++++++++++++++++++
 1 file changed, 1364 insertions(+)
 create mode 100644 drivers/media/platform/amphion/venc.c

diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
new file mode 100644
index 000000000000..3c9fc12802f4
--- /dev/null
+++ b/drivers/media/platform/amphion/venc.c
@@ -0,0 +1,1364 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/ktime.h>
+#include <linux/rational.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+
+#define VENC_OUTPUT_ENABLE	BIT(0)
+#define VENC_CAPTURE_ENABLE	BIT(1)
+#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
+#define VENC_MAX_BUF_CNT	8
+
+struct venc_t {
+	struct vpu_encode_params params;
+	u32 request_key_frame;
+	u32 input_ready;
+	u32 cpb_size;
+	bool bitrate_change;
+
+	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
+	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
+	struct vpu_buffer act[VENC_MAX_BUF_CNT];
+	struct list_head frames;
+	u32 frame_count;
+	u32 encode_count;
+	u32 ready_count;
+	u32 enable;
+	u32 stopped;
+
+	u32 skipped_count;
+	u32 skipped_bytes;
+
+	wait_queue_head_t wq;
+};
+
+struct venc_frame_t {
+	struct list_head list;
+	struct vpu_enc_pic_info info;
+	u32 bytesused;
+	s64 timestamp;
+};
+
+static const struct vpu_format venc_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{0, 0, 0, 0},
+};
+
+static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	fmt = vpu_helper_enum_format(inst, f->type, f->index);
+	if (!fmt)
+		return -EINVAL;
+
+	f->pixelformat = fmt->pixfmt;
+	f->flags = fmt->flags;
+
+	return 0;
+}
+
+static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+
+	if (!fsize || fsize->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
+		return -EINVAL;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.max_width = res->max_width;
+	fsize->stepwise.max_height = res->max_height;
+	fsize->stepwise.min_width = res->min_width;
+	fsize->stepwise.min_height = res->min_height;
+	fsize->stepwise.step_width = res->step_width;
+	fsize->stepwise.step_height = res->step_height;
+
+	return 0;
+}
+
+static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+
+	if (!fival || fival->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
+		return -EINVAL;
+
+	if (!fival->width || !fival->height)
+		return -EINVAL;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+	if (fival->width < res->min_width || fival->width > res->max_width ||
+	    fival->height < res->min_height || fival->height > res->max_height)
+		return -EINVAL;
+
+	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = USHRT_MAX;
+	fival->stepwise.max.numerator = USHRT_MAX;
+	fival->stepwise.max.denominator = 1;
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = 1;
+
+	return 0;
+}
+
+static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
+	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
+	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
+	f->fmt.pix_mp.quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_try_fmt_common(inst, f);
+
+	return 0;
+}
+
+static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->num_planes = fmt->num_planes;
+	cur_fmt->flags = fmt->flags;
+	cur_fmt->width = pix_mp->width;
+	cur_fmt->height = pix_mp->height;
+	for (i = 0; i < fmt->num_planes; i++) {
+		cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+		cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+	}
+
+	if (pix_mp->field != V4L2_FIELD_ANY)
+		cur_fmt->field = pix_mp->field;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		venc->params.input_format = cur_fmt->pixfmt;
+		venc->params.src_stride = cur_fmt->bytesperline[0];
+		venc->params.src_width = cur_fmt->width;
+		venc->params.src_height = cur_fmt->height;
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = cur_fmt->width;
+		venc->params.crop.height = cur_fmt->height;
+	} else {
+		venc->params.codec_format = cur_fmt->pixfmt;
+		venc->params.out_width = cur_fmt->width;
+		venc->params.out_height = cur_fmt->height;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		if (!vpu_color_check_primaries(pix_mp->colorspace)) {
+			venc->params.color.primaries = pix_mp->colorspace;
+			vpu_color_get_default(venc->params.color.primaries,
+					      &venc->params.color.transfer,
+					      &venc->params.color.matrix,
+					      &venc->params.color.full_range);
+		}
+		if (!vpu_color_check_transfers(pix_mp->xfer_func))
+			venc->params.color.transfer = pix_mp->xfer_func;
+		if (!vpu_color_check_matrix(pix_mp->ycbcr_enc))
+			venc->params.color.matrix = pix_mp->ycbcr_enc;
+		if (!vpu_color_check_full_range(pix_mp->quantization))
+			venc->params.color.full_range = pix_mp->quantization;
+	}
+
+	pix_mp->colorspace = venc->params.color.primaries;
+	pix_mp->xfer_func = venc->params.color.transfer;
+	pix_mp->ycbcr_enc = venc->params.color.matrix;
+	pix_mp->quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.readbuffers = 0;
+	timeperframe->numerator = venc->params.frame_rate.numerator;
+	timeperframe->denominator = venc->params.frame_rate.denominator;
+
+	return 0;
+}
+
+static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+	unsigned long n, d;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	if (!timeperframe->numerator)
+		timeperframe->numerator = venc->params.frame_rate.numerator;
+	if (!timeperframe->denominator)
+		timeperframe->denominator = venc->params.frame_rate.denominator;
+
+	venc->params.frame_rate.numerator = timeperframe->numerator;
+	venc->params.frame_rate.denominator = timeperframe->denominator;
+
+	rational_best_approximation(venc->params.frame_rate.numerator,
+				    venc->params.frame_rate.denominator,
+				    venc->params.frame_rate.numerator,
+				    venc->params.frame_rate.denominator,
+				    &n, &d);
+	venc->params.frame_rate.numerator = n;
+	venc->params.frame_rate.denominator = d;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved));
+
+	return 0;
+}
+
+static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->out_format.width;
+		s->r.height = inst->out_format.height;
+		break;
+	case V4L2_SEL_TGT_CROP:
+		s->r = venc->params.crop;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)
+{
+	struct v4l2_rect *rect = NULL;
+	u32 min_width;
+	u32 min_height;
+	u32 src_width;
+	u32 src_height;
+
+	rect = &venc->params.crop;
+	min_width = res->min_width;
+	min_height = res->min_height;
+	src_width = venc->params.src_width;
+	src_height = venc->params.src_height;
+
+	if (rect->width == 0 || rect->height == 0)
+		return -EINVAL;
+	if (rect->left > src_width - min_width || rect->top > src_height - min_height)
+		return -EINVAL;
+
+	rect->width = min(rect->width, src_width - rect->left);
+	rect->width = max_t(u32, rect->width, min_width);
+
+	rect->height = min(rect->height, src_height - rect->top);
+	rect->height = max_t(u32, rect->height, min_height);
+
+	return 0;
+}
+
+static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+	struct venc_t *venc = inst->priv;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+	if (s->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
+	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
+	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
+	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
+	if (venc_valid_crop(venc, res)) {
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = venc->params.src_width;
+		venc->params.crop.height = venc->params.src_height;
+	}
+
+	inst->crop = venc->params.crop;
+
+	return 0;
+}
+
+static int venc_drain(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state != VPU_CODEC_STATE_DRAIN)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
+		return 0;
+
+	if (!venc->input_ready)
+		return 0;
+
+	venc->input_ready = false;
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	ret = vpu_session_stop(inst);
+	if (ret)
+		return ret;
+	inst->state = VPU_CODEC_STATE_STOP;
+	wake_up_all(&venc->wq);
+
+	return 0;
+}
+
+static int venc_request_eos(struct vpu_inst *inst)
+{
+	inst->state = VPU_CODEC_STATE_DRAIN;
+	venc_drain(inst);
+
+	return 0;
+}
+
+static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+		if (inst->state == VPU_CODEC_STATE_DEINIT)
+			vpu_set_last_buffer_dequeued(inst);
+		else
+			venc_request_eos(inst);
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct v4l2_ioctl_ops venc_ioctl_ops = {
+	.vidioc_querycap               = venc_querycap,
+	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
+	.vidioc_enum_framesizes        = venc_enum_framesizes,
+	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
+	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
+	.vidioc_g_parm                 = venc_g_parm,
+	.vidioc_s_parm                 = venc_s_parm,
+	.vidioc_g_selection            = venc_g_selection,
+	.vidioc_s_selection            = venc_s_selection,
+	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
+	.vidioc_encoder_cmd            = venc_encoder_cmd,
+	.vidioc_subscribe_event        = venc_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+	struct venc_t *venc = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		venc->params.profile = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		venc->params.level = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+		venc->params.rc_enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		venc->params.rc_mode = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		if (ctrl->val != venc->params.bitrate)
+			venc->bitrate_change = true;
+		venc->params.bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		venc->params.bitrate_max = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		venc->params.gop_length = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		venc->params.bframes = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		venc->params.i_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		venc->params.p_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		venc->params.b_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+		venc->request_key_frame = 1;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
+		venc->cpb_size = ctrl->val * 1024;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+		venc->params.sar.enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+		venc->params.sar.idc = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+		venc->params.sar.width = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+		venc->params.sar.height = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops venc_ctrl_ops = {
+	.s_ctrl = venc_op_s_ctrl,
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int venc_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			       ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
+			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+			       0x0,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+			       ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+				 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
+			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_BITRATE,
+			  BITRATE_MIN,
+			  BITRATE_MAX,
+			  BITRATE_STEP,
+			  BITRATE_DEFAULT);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+			  BITRATE_MIN, BITRATE_MAX,
+			  BITRATE_STEP,
+			  BITRATE_DEFAULT_PEAK);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+			       0x0,
+			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+			  0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+			  0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+			       ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
+			return false;
+		return venc->input_ready;
+	}
+
+	if (list_empty(&venc->frames))
+		return false;
+	return true;
+}
+
+static u32 venc_get_enable_mask(u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return VENC_OUTPUT_ENABLE;
+	else
+		return VENC_CAPTURE_ENABLE;
+}
+
+static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
+{
+	u32 mask = venc_get_enable_mask(type);
+
+	if (enable)
+		venc->enable |= mask;
+	else
+		venc->enable &= ~mask;
+}
+
+static u32 venc_get_enable(struct venc_t *venc, u32 type)
+{
+	return venc->enable & venc_get_enable_mask(type);
+}
+
+static void venc_input_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->input_ready = true;
+	vpu_process_output_buffer(inst);
+	if (inst->state == VPU_CODEC_STATE_DRAIN)
+		venc_drain(inst);
+	vpu_inst_unlock(inst);
+}
+
+/*
+ * It's hardware limitation, that there may be several bytes
+ * redundant data at the beginning of frame.
+ * For android platform, the redundant data may cause cts test fail
+ * So driver will strip them
+ */
+static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
+{
+	struct venc_t *venc;
+	int skipped;
+
+	if (!inst || !frame || !frame->bytesused)
+		return -EINVAL;
+
+	venc = inst->priv;
+	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
+					    inst->cap_format.pixfmt,
+					    frame->info.wptr - inst->stream_buffer.phys,
+					    frame->bytesused);
+	if (skipped > 0) {
+		frame->bytesused -= skipped;
+		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
+							frame->info.wptr, skipped);
+		venc->skipped_bytes += skipped;
+		venc->skipped_count++;
+	}
+
+	return 0;
+}
+
+static int venc_get_one_encoded_frame(struct vpu_inst *inst,
+				      struct venc_frame_t *frame,
+				      struct vb2_v4l2_buffer *vbuf)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (!vbuf)
+		return -EAGAIN;
+
+	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return 0;
+	}
+	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return -ENOMEM;
+	}
+
+	venc_precheck_encoded_frame(inst, frame);
+
+	if (frame->bytesused) {
+		u32 rptr = frame->info.wptr;
+		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+
+		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
+						   &rptr, frame->bytesused, dst);
+		vpu_iface_update_stream_buffer(inst, rptr, 0);
+	}
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
+	vbuf->sequence = frame->info.frame_id;
+	vbuf->vb2_buf.timestamp = frame->info.timestamp;
+	vbuf->field = inst->cap_format.field;
+	vbuf->flags |= frame->info.pic_type;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->info.timestamp);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	venc->ready_count++;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);
+
+	return 0;
+}
+
+static int venc_get_encoded_frames(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!inst || !inst->priv || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	venc = inst->priv;
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		if (venc_get_one_encoded_frame(inst, frame,
+					       v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
+			break;
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+
+	return 0;
+}
+
+static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
+{
+	struct vpu_enc_pic_info *info = arg;
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+	int ret = 0;
+
+	if (!inst || !info)
+		return -EINVAL;
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	memcpy(&frame->info, info, sizeof(frame->info));
+	frame->bytesused = info->frame_size;
+
+	vpu_inst_lock(inst);
+	list_add_tail(&frame->list, &venc->frames);
+	venc->encode_count++;
+	venc_get_encoded_frames(inst);
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!inst || !frame || !inst->fh.m2m_ctx)
+		return;
+
+	vpu_inst_lock(inst);
+	if (!venc_get_enable(inst->priv, frame->type))
+		goto exit;
+	vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
+	if (!vbuf) {
+		dev_err(inst->dev, "[%d] can't find buf: type %d, sequence %d\n",
+			inst->id, frame->type, frame->sequence);
+		goto exit;
+	}
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	if (V4L2_TYPE_IS_OUTPUT(frame->type))
+		v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	else
+		v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (venc->stopped && list_empty(&venc->frames))
+		vpu_set_last_buffer_dequeued(inst);
+}
+
+static void venc_stop_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->stopped = true;
+	venc_set_last_buffer_dequeued(inst);
+	vpu_inst_unlock(inst);
+
+	wake_up_all(&venc->wq);
+}
+
+static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+}
+
+static void venc_release(struct vpu_inst *inst)
+{
+}
+
+static void venc_cleanup(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+
+	if (!inst)
+		return;
+
+	venc = inst->priv;
+	if (venc)
+		vfree(venc);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static int venc_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	venc_set_enable(venc, type, 1);
+	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
+		return 0;
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret)
+			goto error;
+
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
+	if (ret)
+		goto error;
+	ret = vpu_session_configure_codec(inst);
+	if (ret)
+		goto error;
+
+	inst->state = VPU_CODEC_STATE_CONFIGURED;
+	/*vpu_iface_config_memory_resource*/
+
+	/*config enc expert mode parameter*/
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
+	if (ret)
+		goto error;
+
+	ret = vpu_session_start(inst);
+	if (ret)
+		goto error;
+	inst->state = VPU_CODEC_STATE_STARTED;
+
+	venc->bitrate_change = false;
+	venc->input_ready = true;
+	venc->frame_count = 0;
+	venc->encode_count = 0;
+	venc->ready_count = 0;
+	venc->stopped = false;
+	vpu_process_output_buffer(inst);
+	if (venc->frame_count == 0)
+		dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
+
+	return 0;
+error:
+	venc_set_enable(venc, type, 0);
+	inst->state = VPU_CODEC_STATE_DEINIT;
+
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static void venc_cleanup_mem_resource(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	u32 i;
+
+	venc = inst->priv;
+
+	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
+		vpu_free_dma(&venc->enc[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
+		vpu_free_dma(&venc->ref[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->act); i++)
+		vpu_free_dma(&venc->act[i]);
+}
+
+static void venc_request_mem_resource(struct vpu_inst *inst,
+				      u32 enc_frame_size,
+				      u32 enc_frame_num,
+				      u32 ref_frame_size,
+				      u32 ref_frame_num,
+				      u32 act_frame_size,
+				      u32 act_frame_num)
+{
+	struct venc_t *venc;
+	u32 i;
+	int ret;
+
+	venc = inst->priv;
+	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
+		dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num);
+		return;
+	}
+	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
+		dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num);
+		return;
+	}
+	if (act_frame_num > ARRAY_SIZE(venc->act)) {
+		dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num);
+		return;
+	}
+
+	for (i = 0; i < enc_frame_num; i++) {
+		venc->enc[i].length = enc_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	for (i = 0; i < ref_frame_num; i++) {
+		venc->ref[i].length = ref_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
+		venc_cleanup_mem_resource(inst);
+		return;
+	}
+	venc->act[0].length = act_frame_size;
+	venc->act[0].phys = inst->act.phys;
+	venc->act[0].virt = inst->act.virt;
+
+	for (i = 0; i < enc_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
+	for (i = 0; i < ref_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
+	for (i = 0; i < act_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
+}
+
+static void venc_cleanup_frames(struct venc_t *venc)
+{
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+}
+
+static int venc_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	venc_set_enable(venc, type, 0);
+	if (venc->enable & VENC_ENABLE_MASK)
+		return 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (inst->state != VPU_CODEC_STATE_STOP)
+		venc_request_eos(inst);
+
+	call_vop(inst, wait_prepare);
+	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
+		set_bit(inst->id, &inst->core->hang_mask);
+		vpu_session_debug(inst);
+	}
+	call_vop(inst, wait_finish);
+
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	venc_cleanup_frames(inst->priv);
+	vpu_free_dma(&inst->stream_buffer);
+	venc_cleanup_mem_resource(inst);
+
+	return 0;
+}
+
+static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 flags;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		inst->state = VPU_CODEC_STATE_ACTIVE;
+
+	flags = vbuf->flags;
+	if (venc->request_key_frame) {
+		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		venc->request_key_frame = 0;
+	}
+	if (venc->bitrate_change) {
+		vpu_session_update_parameters(inst, &venc->params);
+		venc->bitrate_change = false;
+	}
+	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
+	vpu_iface_input_frame(inst, vb);
+	vbuf->flags = flags;
+	venc->input_ready = false;
+	venc->frame_count++;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
+
+	return 0;
+}
+
+static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame = NULL;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	venc = inst->priv;
+	if (list_empty(&venc->frames))
+		return -EINVAL;
+
+	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
+	vbuf = to_vb2_v4l2_buffer(vb);
+	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
+	if (ret)
+		return ret;
+
+	list_del_init(&frame->list);
+	vfree(frame);
+	return 0;
+}
+
+static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	if (venc->stopped)
+		venc_set_last_buffer_dequeued(inst);
+}
+
+static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct venc_t *venc = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
+		break;
+	case 1:
+		num = scnprintf(str, size, "level = %d\n", venc->params.level);
+		break;
+	case 2:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				venc->params.frame_rate.numerator,
+				venc->params.frame_rate.denominator);
+		break;
+	case 3:
+		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
+				venc->params.src_width,
+				venc->params.src_height,
+				venc->params.out_width,
+				venc->params.out_height);
+		break;
+	case 4:
+		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
+				venc->params.crop.left,
+				venc->params.crop.top,
+				venc->params.crop.width,
+				venc->params.crop.height);
+		break;
+	case 5:
+		num = scnprintf(str, size,
+				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
+				venc->enable,
+				venc->frame_count, venc->encode_count,
+				venc->ready_count,
+				venc->stopped);
+		break;
+	case 6:
+		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
+		break;
+	case 7:
+		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
+		break;
+	case 8:
+		num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n",
+				venc->params.rc_enable ? "enable" : "disable",
+				venc->params.rc_mode,
+				venc->params.bitrate,
+				venc->params.bitrate_max,
+				venc->params.i_frame_qp);
+		break;
+	case 9:
+		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
+				venc->params.sar.enable,
+				venc->params.sar.idc,
+				venc->params.sar.width,
+				venc->params.sar.height);
+
+		break;
+	case 10:
+		num = scnprintf(str, size,
+				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
+				venc->params.color.primaries,
+				venc->params.color.transfer,
+				venc->params.color.matrix,
+				venc->params.color.full_range);
+		break;
+	case 11:
+		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
+				venc->skipped_count, venc->skipped_bytes);
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops venc_inst_ops = {
+	.ctrl_init = venc_ctrl_init,
+	.check_ready = venc_check_ready,
+	.input_done = venc_input_done,
+	.get_one_frame = venc_frame_encoded,
+	.buf_done = venc_buf_done,
+	.stop_done = venc_stop_done,
+	.event_notify = venc_event_notify,
+	.release = venc_release,
+	.cleanup = venc_cleanup,
+	.start = venc_start_session,
+	.mem_request = venc_request_mem_resource,
+	.stop = venc_stop_session,
+	.process_output = venc_process_output,
+	.process_capture = venc_process_capture,
+	.on_queue_empty = venc_on_queue_empty,
+	.get_debug_info = venc_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void venc_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc;
+	struct v4l2_format f;
+	struct v4l2_streamparm parm;
+
+	venc = inst->priv;
+	venc->params.qp_min = 1;
+	venc->params.qp_max = 51;
+	venc->params.qp_min_i = 1;
+	venc->params.qp_max_i = 51;
+	venc->params.bitrate_min = BITRATE_MIN;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&parm, 0, sizeof(parm));
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	parm.parm.capture.timeperframe.numerator = 1;
+	parm.parm.capture.timeperframe.denominator = 30;
+	venc_s_parm(file, &inst->fh, &parm);
+}
+
+static int venc_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct venc_t *venc;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	venc = vzalloc(sizeof(*venc));
+	if (!venc) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &venc_inst_ops;
+	inst->formats = venc_formats;
+	inst->type = VPU_CORE_TYPE_ENC;
+	inst->priv = venc;
+	INIT_LIST_HEAD(&venc->frames);
+	init_waitqueue_head(&venc->wq);
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret)
+		return ret;
+
+	venc_init(file);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations venc_fops = {
+	.owner = THIS_MODULE,
+	.open = venc_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = v4l2_m2m_fop_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
+{
+	return &venc_ioctl_ops;
+}
+
+const struct v4l2_file_operations *venc_get_fops(void)
+{
+	return &venc_fops;
+}
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:24 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:24 +0800
Subject: [PATCH v15 08/13] media: amphion: add v4l2 m2m vpu decoder stateful
 driver
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <33db5d6269e6e85820062cfe81eb0fcededd96cc.1643077283.git.ming.qian@nxp.com>

This consists of video decoder implementation plus decoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vdec.c | 1694 +++++++++++++++++++++++++
 1 file changed, 1694 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vdec.c

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
new file mode 100644
index 000000000000..e45e12b65a3a
--- /dev/null
+++ b/drivers/media/platform/amphion/vdec.c
@@ -0,0 +1,1694 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+
+#define VDEC_FRAME_DEPTH		256
+#define VDEC_MIN_BUFFER_CAP		8
+
+struct vdec_fs_info {
+	char name[8];
+	u32 type;
+	u32 max_count;
+	u32 req_count;
+	u32 count;
+	u32 index;
+	u32 size;
+	struct vpu_buffer buffer[32];
+	u32 tag;
+};
+
+struct vdec_t {
+	u32 seq_hdr_found;
+	struct vpu_buffer udata;
+	struct vpu_decode_params params;
+	struct vpu_dec_codec_info codec_info;
+	enum vpu_codec_state state;
+
+	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	u32 req_frame_count;
+	struct vdec_fs_info mbi;
+	struct vdec_fs_info dcp;
+	u32 seq_tag;
+
+	bool reset_codec;
+	bool fixed_fmt;
+	u32 decoded_frame_count;
+	u32 display_frame_count;
+	u32 sequence;
+	u32 eos_received;
+	bool is_source_changed;
+	u32 source_change;
+	u32 drain;
+	u32 ts_pre_count;
+	u32 frame_depth;
+	s64 ts_start;
+	s64 ts_input;
+	s64 timestamp;
+};
+
+static const struct vpu_format vdec_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264_MVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_HEVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_XVID,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{0, 0, 0, 0},
+};
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int vdec_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (vdec->eos_received) {
+		if (!vpu_set_last_buffer_dequeued(inst))
+			vdec->eos_received--;
+	}
+}
+
+static void vdec_handle_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+
+	if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return;
+	if (!vdec->source_change)
+		return;
+
+	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return;
+
+	vdec->source_change--;
+	vpu_notify_source_change(inst);
+}
+
+static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
+{
+	struct vdec_t *vdec = inst->priv;
+	enum vpu_codec_state pre_state = inst->state;
+
+	if (state == VPU_CODEC_STATE_SEEK) {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec->state = inst->state;
+		else
+			vdec->state = VPU_CODEC_STATE_ACTIVE;
+	}
+	if (inst->state != VPU_CODEC_STATE_SEEK || force)
+		inst->state = state;
+	else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
+
+	if (inst->state != pre_state)
+		vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state);
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec_handle_resolution_change(inst);
+
+	return 0;
+}
+
+static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "amphion vpu decoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int ret = -EINVAL;
+
+	vpu_inst_lock(inst);
+	if (!V4L2_TYPE_IS_OUTPUT(f->type) && vdec->fixed_fmt) {
+		if (f->index == 0) {
+			f->pixelformat = inst->cap_format.pixfmt;
+			f->flags = inst->cap_format.flags;
+			ret = 0;
+		}
+	} else {
+		fmt = vpu_helper_enum_format(inst, f->type, f->index);
+		memset(f->reserved, 0, sizeof(f->reserved));
+		if (!fmt)
+			goto exit;
+
+		f->pixelformat = fmt->pixfmt;
+		f->flags = fmt->flags;
+		ret = 0;
+	}
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+	return 0;
+}
+
+static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_try_fmt_common(inst, f);
+
+	vpu_inst_lock(inst);
+	if (vdec->fixed_fmt) {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	} else {
+		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+		f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+		f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+		f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_s_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+	if (V4L2_TYPE_IS_OUTPUT(f->type) && inst->state != VPU_CODEC_STATE_DEINIT) {
+		if (cur_fmt->pixfmt != fmt->pixfmt) {
+			vdec->reset_codec = true;
+			vdec->fixed_fmt = false;
+		}
+	}
+	cur_fmt->pixfmt = fmt->pixfmt;
+	if (V4L2_TYPE_IS_OUTPUT(f->type) || !vdec->fixed_fmt) {
+		cur_fmt->num_planes = fmt->num_planes;
+		cur_fmt->flags = fmt->flags;
+		cur_fmt->width = pixmp->width;
+		cur_fmt->height = pixmp->height;
+		for (i = 0; i < fmt->num_planes; i++) {
+			cur_fmt->sizeimage[i] = pixmp->plane_fmt[i].sizeimage;
+			cur_fmt->bytesperline[i] = pixmp->plane_fmt[i].bytesperline;
+		}
+		if (pixmp->field != V4L2_FIELD_ANY)
+			cur_fmt->field = pixmp->field;
+	} else {
+		pixmp->num_planes = cur_fmt->num_planes;
+		pixmp->width = cur_fmt->width;
+		pixmp->height = cur_fmt->height;
+		for (i = 0; i < pixmp->num_planes; i++) {
+			pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+			pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+		}
+		pixmp->field = cur_fmt->field;
+	}
+
+	if (!vdec->fixed_fmt) {
+		if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+			vdec->params.codec_format = cur_fmt->pixfmt;
+			vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
+			vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
+			vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
+			vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
+		} else {
+			vdec->params.output_format = cur_fmt->pixfmt;
+			inst->crop.left = 0;
+			inst->crop.top = 0;
+			inst->crop.width = cur_fmt->width;
+			inst->crop.height = cur_fmt->height;
+		}
+	}
+
+	vpu_trace(inst->dev, "[%d] %c%c%c%c %dx%d\n", inst->id,
+		  f->fmt.pix_mp.pixelformat,
+		  f->fmt.pix_mp.pixelformat >> 8,
+		  f->fmt.pix_mp.pixelformat >> 16,
+		  f->fmt.pix_mp.pixelformat >> 24,
+		  f->fmt.pix_mp.width,
+		  f->fmt.pix_mp.height);
+
+	return 0;
+}
+
+static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	ret = vdec_s_fmt_common(inst, f);
+	if (ret)
+		goto exit;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type) && !vdec->fixed_fmt) {
+		struct v4l2_format fc;
+
+		memset(&fc, 0, sizeof(fc));
+		fc.type = inst->cap_format.type;
+		fc.fmt.pix_mp.pixelformat = inst->cap_format.pixfmt;
+		fc.fmt.pix_mp.width = pixmp->width;
+		fc.fmt.pix_mp.height = pixmp->height;
+		vdec_s_fmt_common(inst, &fc);
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_PADDED:
+		s->r = inst->crop;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->cap_format.width;
+		s->r.height = inst->cap_format.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_drain(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vdec->drain)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
+		return 0;
+
+	if (!vdec->params.frame_count) {
+		vpu_set_last_buffer_dequeued(inst);
+		return 0;
+	}
+
+	vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+	vdec->drain = 0;
+	vpu_trace(inst->dev, "[%d] frame_count = %d\n", inst->id, vdec->params.frame_count);
+
+	return 0;
+}
+
+static int vdec_cmd_start(struct vpu_inst *inst)
+{
+	switch (inst->state) {
+	case VPU_CODEC_STATE_STARTED:
+	case VPU_CODEC_STATE_DRAIN:
+	case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE:
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+		break;
+	default:
+		break;
+	}
+	vpu_process_capture_buffer(inst);
+	return 0;
+}
+
+static int vdec_cmd_stop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		vpu_set_last_buffer_dequeued(inst);
+	} else {
+		vdec->drain = 1;
+		vdec_drain(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	switch (cmd->cmd) {
+	case V4L2_DEC_CMD_START:
+		vdec_cmd_start(inst);
+		break;
+	case V4L2_DEC_CMD_STOP:
+		vdec_cmd_stop(inst);
+		break;
+	default:
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_src_change_event_subscribe(fh, sub);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
+	.vidioc_querycap               = vdec_querycap,
+	.vidioc_enum_fmt_vid_cap       = vdec_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = vdec_enum_fmt,
+	.vidioc_g_fmt_vid_cap_mplane   = vdec_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = vdec_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = vdec_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = vdec_s_fmt,
+	.vidioc_g_selection            = vdec_g_selection,
+	.vidioc_try_decoder_cmd        = v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd            = vdec_decoder_cmd,
+	.vidioc_subscribe_event        = vdec_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->ts_pre_count >= vdec->frame_depth)
+			return false;
+		return true;
+	}
+
+	if (vdec->req_frame_count)
+		return true;
+
+	return false;
+}
+
+static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_dec_pic_info *info = arg;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret = 0;
+
+	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+		return -EINVAL;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[info->id];
+	if (!vpu_buf) {
+		dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
+		ret = -EINVAL;
+		goto exit;
+	}
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
+		dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+	vdec->decoded_frame_count++;
+	if (vdec->ts_pre_count >= info->consumed_count)
+		vdec->ts_pre_count -= info->consumed_count;
+	else
+		vdec->ts_pre_count = 0;
+exit:
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+		if (luma == vdec->slots[i]->luma)
+			return vdec->slots[i];
+	}
+
+	return NULL;
+}
+
+static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 sequence;
+
+	if (!frame)
+		return;
+
+	vpu_inst_lock(inst);
+	sequence = vdec->sequence++;
+	vpu_buf = vdec_find_buffer(inst, frame->luma);
+	vpu_inst_unlock(inst);
+	if (!vpu_buf) {
+		dev_err(inst->dev, "[%d] can't find buffer, id = %d, addr = 0x%x\n",
+			inst->id, frame->id, frame->luma);
+		return;
+	}
+	if (frame->skipped) {
+		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
+		return;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vbuf->vb2_buf.index != frame->id)
+		dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
+			inst->id, vbuf->vb2_buf.index, frame->id);
+
+	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
+		dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
+	vbuf->vb2_buf.timestamp = frame->timestamp;
+	vbuf->field = inst->cap_format.field;
+	vbuf->sequence = sequence;
+	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->timestamp);
+
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	vpu_inst_lock(inst);
+	vdec->timestamp = frame->timestamp;
+	vdec->display_frame_count++;
+	vpu_inst_unlock(inst);
+	dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
+		inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
+}
+
+static void vdec_stop_done(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
+	vdec->seq_hdr_found = 0;
+	vdec->req_frame_count = 0;
+	vdec->reset_codec = false;
+	vdec->fixed_fmt = false;
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+	vdec->sequence = 0;
+	vdec->eos_received = 0;
+	vdec->is_source_changed = false;
+	vdec->source_change = 0;
+	vpu_inst_unlock(inst);
+}
+
+static bool vdec_check_source_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return false;
+	if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
+		return true;
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
+		return true;
+	if (inst->cap_format.width != vdec->codec_info.decoded_width)
+		return true;
+	if (inst->cap_format.height != vdec->codec_info.decoded_height)
+		return true;
+	if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
+		return true;
+	if (inst->crop.left != vdec->codec_info.offset_x)
+		return true;
+	if (inst->crop.top != vdec->codec_info.offset_y)
+		return true;
+	if (inst->crop.width != vdec->codec_info.width)
+		return true;
+	if (inst->crop.height != vdec->codec_info.height)
+		return true;
+	if (fmt && inst->cap_format.num_planes != fmt->num_planes)
+		return true;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		if (inst->cap_format.bytesperline[i] != vdec->codec_info.bytesperline[i])
+			return true;
+		if (inst->cap_format.sizeimage[i] != vdec->codec_info.sizeimage[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void vdec_init_fmt(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	inst->out_format.width = vdec->codec_info.width;
+	inst->out_format.height = vdec->codec_info.height;
+	inst->cap_format.width = vdec->codec_info.decoded_width;
+	inst->cap_format.height = vdec->codec_info.decoded_height;
+	inst->cap_format.pixfmt = vdec->codec_info.pixfmt;
+	if (fmt) {
+		inst->cap_format.num_planes = fmt->num_planes;
+		inst->cap_format.flags = fmt->flags;
+	}
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		inst->cap_format.bytesperline[i] = vdec->codec_info.bytesperline[i];
+		inst->cap_format.sizeimage[i] = vdec->codec_info.sizeimage[i];
+	}
+	if (vdec->codec_info.progressive)
+		inst->cap_format.field = V4L2_FIELD_NONE;
+	else
+		inst->cap_format.field = V4L2_FIELD_SEQ_BT;
+	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+static void vdec_init_crop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst->crop.left = vdec->codec_info.offset_x;
+	inst->crop.top = vdec->codec_info.offset_y;
+	inst->crop.width = vdec->codec_info.width;
+	inst->crop.height = vdec->codec_info.height;
+}
+
+static void vdec_init_mbi(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->mbi.size = vdec->codec_info.mbi_size;
+	vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
+	scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
+	vdec->mbi.type = MEM_RES_MBI;
+	vdec->mbi.tag = vdec->seq_tag;
+}
+
+static void vdec_init_dcp(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->dcp.size = vdec->codec_info.dcp_size;
+	vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
+	scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
+	vdec->dcp.type = MEM_RES_DCP;
+	vdec->dcp.tag = vdec->seq_tag;
+}
+
+static void vdec_request_one_fs(struct vdec_fs_info *fs)
+{
+	fs->req_count++;
+	if (fs->req_count > fs->max_count)
+		fs->req_count = fs->max_count;
+}
+
+static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_buffer *buffer;
+
+	if (!inst || !fs || !fs->size)
+		return -EINVAL;
+
+	if (fs->count >= fs->req_count)
+		return -EINVAL;
+
+	buffer = &fs->buffer[fs->count];
+	if (buffer->virt && buffer->length >= fs->size)
+		return 0;
+
+	vpu_free_dma(buffer);
+	buffer->length = fs->size;
+	return vpu_alloc_dma(inst->core, buffer);
+}
+
+static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	int ret;
+
+	while (fs->count < fs->req_count) {
+		ret = vdec_alloc_fs_buffer(inst, fs);
+		if (ret)
+			break;
+		fs->count++;
+	}
+}
+
+static void vdec_clear_fs(struct vdec_fs_info *fs)
+{
+	u32 i;
+
+	if (!fs)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
+		vpu_free_dma(&fs->buffer[i]);
+	memset(fs, 0, sizeof(*fs));
+}
+
+static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_fs_info info;
+	int ret;
+
+	if (fs->index >= fs->count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.id = fs->index;
+	info.type = fs->type;
+	info.tag = fs->tag;
+	info.luma_addr = fs->buffer[fs->index].phys;
+	info.luma_size = fs->buffer[fs->index].length;
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	fs->index++;
+	return 0;
+}
+
+static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_fs_info info;
+
+	if (!vdec->req_frame_count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag + 0xf0;
+	vpu_session_alloc_fs(inst, &info);
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_fs_info info;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_ACTIVE)
+		return -EINVAL;
+
+	if (!vdec->req_frame_count)
+		return -EINVAL;
+
+	if (!vbuf)
+		return -EINVAL;
+
+	if (vdec->slots[vbuf->vb2_buf.index]) {
+		dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
+			inst->id, vbuf->vb2_buf.index);
+		return -EINVAL;
+	}
+
+	dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n",
+		inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	memset(&info, 0, sizeof(info));
+	info.id = vbuf->vb2_buf.index;
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag;
+	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
+	info.luma_size = inst->cap_format.sizeimage[0];
+	info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
+	info.chromau_size = inst->cap_format.sizeimage[1];
+	info.bytesperline = inst->cap_format.bytesperline[0];
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	vpu_buf->tag = info.tag;
+	vpu_buf->luma = info.luma_addr;
+	vpu_buf->chroma_u = info.chromau_size;
+	vpu_buf->chroma_v = 0;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
+	vdec->slots[info.id] = vpu_buf;
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+	int ret;
+
+	if (force) {
+		for (i = vdec->req_frame_count; i > 0; i--)
+			vdec_response_frame_abnormal(inst);
+		return;
+	}
+
+	for (i = vdec->req_frame_count; i > 0; i--) {
+		ret = vpu_process_capture_buffer(inst);
+		if (ret)
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+
+	for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
+		if (vdec_response_fs(inst, &vdec->mbi))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+	for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
+		if (vdec_response_fs(inst, &vdec->dcp))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+}
+
+static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
+{
+	struct vpu_fs_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.id = id;
+	info.tag = tag;
+	vpu_session_release_fs(inst, &info);
+}
+
+static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	if (!inst || !vbuf || !inst->fh.m2m_ctx)
+		return;
+
+	if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
+		return;
+	if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
+		return;
+	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+
+		vpu_buf = vdec->slots[i];
+		vbuf = &vpu_buf->m2m_buf.vb;
+
+		vdec_recycle_buffer(inst, vbuf);
+		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
+		vdec->slots[i] = NULL;
+	}
+}
+
+static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
+
+	vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
+		  inst->id,
+		  vdec->codec_info.decoded_width,
+		  vdec->codec_info.decoded_height,
+		  vdec->codec_info.offset_x,
+		  vdec->codec_info.offset_y,
+		  vdec->codec_info.width,
+		  vdec->codec_info.height,
+		  hdr->num_ref_frms,
+		  hdr->num_dpb_frms);
+	inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
+	vdec->is_source_changed = vdec_check_source_change(inst);
+	vdec_init_fmt(inst);
+	vdec_init_crop(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (!vdec->seq_hdr_found) {
+		vdec->seq_tag = vdec->codec_info.tag;
+		if (vdec->is_source_changed) {
+			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+			vpu_notify_source_change(inst);
+			vdec->is_source_changed = false;
+		}
+	}
+	if (vdec->seq_tag != vdec->codec_info.tag) {
+		vdec_response_fs_request(inst, true);
+		vpu_trace(inst->dev, "[%d] seq tag change: %d -> %d\n",
+			  inst->id, vdec->seq_tag, vdec->codec_info.tag);
+	}
+	vdec->seq_hdr_found++;
+	vdec->fixed_fmt = true;
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	vpu_inst_lock(inst);
+	vdec->seq_tag = vdec->codec_info.tag;
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vdec_clear_slots(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (vdec->is_source_changed) {
+		vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+		vdec->source_change++;
+		vdec_handle_resolution_change(inst);
+		vdec->is_source_changed = false;
+	}
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!fs)
+		return;
+
+	vpu_inst_lock(inst);
+
+	switch (fs->type) {
+	case MEM_RES_FRAME:
+		vdec->req_frame_count++;
+		break;
+	case MEM_RES_MBI:
+		vdec_request_one_fs(&vdec->mbi);
+		break;
+	case MEM_RES_DCP:
+		vdec_request_one_fs(&vdec->dcp);
+		break;
+	default:
+		break;
+	}
+
+	vdec_alloc_fs(inst, &vdec->mbi);
+	vdec_alloc_fs(inst, &vdec->dcp);
+
+	vdec_response_fs_request(inst, false);
+
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+		return;
+	if (fs->type != MEM_RES_FRAME)
+		return;
+
+	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+		dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
+		return;
+	}
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[fs->id];
+	vdec->slots[fs->id] = NULL;
+
+	if (!vpu_buf) {
+		dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
+		goto exit;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
+		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
+		vdec->sequence++;
+	}
+
+	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
+	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
+		vdec_recycle_buffer(inst, vbuf);
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	vpu_process_capture_buffer(inst);
+
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
+		  inst->id,
+		  vdec->params.frame_count,
+		  vdec->decoded_frame_count,
+		  vdec->display_frame_count,
+		  vdec->sequence);
+	vpu_inst_lock(inst);
+	vdec->eos_received++;
+	vdec->fixed_fmt = false;
+	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+	vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
+	vdec_set_last_buffer_dequeued(inst);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+	switch (event) {
+	case VPU_MSG_ID_SEQ_HDR_FOUND:
+		vdec_event_seq_hdr(inst, data);
+		break;
+	case VPU_MSG_ID_RES_CHANGE:
+		vdec_event_resolution_change(inst);
+		break;
+	case VPU_MSG_ID_FRAME_REQ:
+		vdec_event_req_fs(inst, data);
+		break;
+	case VPU_MSG_ID_FRAME_RELEASE:
+		vdec_evnet_rel_fs(inst, data);
+		break;
+	case VPU_MSG_ID_PIC_EOS:
+		vdec_event_eos(inst);
+		break;
+	default:
+		break;
+	}
+}
+
+static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_rpc_buffer_desc desc;
+	s64 timestamp;
+	u32 free_space;
+	int ret;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	dev_dbg(inst->dev, "[%d] dec output [%d] %d : %ld\n",
+		inst->id, vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+	if (vdec->reset_codec)
+		return -EINVAL;
+
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (ret)
+		return ret;
+
+	free_space = vpu_helper_get_free_space(inst);
+	if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
+		return -ENOMEM;
+
+	timestamp = vb->timestamp;
+	if (timestamp >= 0 && vdec->ts_start < 0)
+		vdec->ts_start = timestamp;
+	if (vdec->ts_input < timestamp)
+		vdec->ts_input = timestamp;
+
+	ret = vpu_iface_input_frame(inst, vb);
+	if (ret < 0)
+		return -ENOMEM;
+
+	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
+	vdec->ts_pre_count++;
+	vdec->params.frame_count++;
+
+	v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+
+	if (vdec->drain)
+		vdec_drain(inst);
+
+	return 0;
+}
+
+static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return -EINVAL;
+	if (vdec->reset_codec)
+		return -EINVAL;
+
+	ret = vdec_response_frame(inst, vbuf);
+	if (ret)
+		return ret;
+	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	return 0;
+}
+
+static void vdec_on_queue_empty(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	vdec_handle_resolution_change(inst);
+	if (vdec->eos_received)
+		vdec_set_last_buffer_dequeued(inst);
+}
+
+static void vdec_abort(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_rpc_buffer_desc desc;
+	int ret;
+
+	vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state);
+	vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+
+	vpu_session_abort(inst);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (!ret)
+		vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
+
+	vpu_session_rst_buf(inst);
+	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
+		  inst->id,
+		  vdec->params.frame_count,
+		  vdec->decoded_frame_count,
+		  vdec->display_frame_count,
+		  vdec->sequence);
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+	vdec->sequence = 0;
+}
+
+static void vdec_stop(struct vpu_inst *inst, bool free)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec_clear_slots(inst);
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		vpu_session_stop(inst);
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	if (free) {
+		vpu_free_dma(&vdec->udata);
+		vpu_free_dma(&inst->stream_buffer);
+	}
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
+	vdec->reset_codec = false;
+}
+
+static void vdec_release(struct vpu_inst *inst)
+{
+	if (inst->id != VPU_INST_NULL_ID)
+		vpu_trace(inst->dev, "[%d]\n", inst->id);
+	vpu_inst_lock(inst);
+	vdec_stop(inst, true);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_cleanup(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec;
+
+	if (!inst)
+		return;
+
+	vdec = inst->priv;
+	if (vdec)
+		vfree(vdec);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static void vdec_init_params(struct vdec_t *vdec)
+{
+	vdec->params.frame_count = 0;
+	vdec->params.end_flag = 0;
+}
+
+static int vdec_start(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	if (!vdec->udata.virt) {
+		vdec->udata.length = 0x1000;
+		ret = vpu_alloc_dma(inst->core, &vdec->udata);
+		if (ret) {
+			dev_err(inst->dev, "[%d] alloc udata fail\n", inst->id);
+			goto error;
+		}
+	}
+
+	if (!inst->stream_buffer.virt) {
+		stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+		if (stream_buffer_size > 0) {
+			inst->stream_buffer.length = stream_buffer_size;
+			ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+			if (ret) {
+				dev_err(inst->dev, "[%d] alloc stream buffer fail\n", inst->id);
+				goto error;
+			}
+			inst->use_stream_buffer = true;
+		}
+	}
+
+	if (inst->use_stream_buffer)
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	vpu_iface_init_instance(inst);
+	vdec->params.udata.base = vdec->udata.phys;
+	vdec->params.udata.size = vdec->udata.length;
+	ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
+	if (ret) {
+		dev_err(inst->dev, "[%d] set decode params fail\n", inst->id);
+		goto error;
+	}
+
+	vdec_init_params(vdec);
+	ret = vpu_session_start(inst);
+	if (ret) {
+		dev_err(inst->dev, "[%d] start fail\n", inst->id);
+		goto error;
+	}
+
+	vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
+
+	return 0;
+error:
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static int vdec_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->reset_codec)
+			vdec_stop(inst, false);
+		if (inst->state == VPU_CODEC_STATE_DEINIT) {
+			ret = vdec_start(inst);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (inst->state == VPU_CODEC_STATE_SEEK)
+			vdec_update_state(inst, vdec->state, 1);
+		vdec->eos_received = 0;
+		vpu_process_output_buffer(inst);
+	} else {
+		vdec_cmd_start(inst);
+	}
+	if (inst->state == VPU_CODEC_STATE_ACTIVE)
+		vdec_response_fs_request(inst, false);
+
+	return ret;
+}
+
+static int vdec_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
+		vdec->drain = 0;
+	} else {
+		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_abort(inst);
+
+		vdec->eos_received = 0;
+		vdec_clear_slots(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size,
+				"req_frame_count = %d\ninterlaced = %d\n",
+				vdec->req_frame_count,
+				vdec->codec_info.progressive ? 0 : 1);
+		break;
+	case 1:
+		num = scnprintf(str, size,
+				"mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->mbi.size,
+				vdec->mbi.req_count,
+				vdec->mbi.count,
+				vdec->mbi.index);
+		break;
+	case 2:
+		num = scnprintf(str, size,
+				"dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->dcp.size,
+				vdec->dcp.req_count,
+				vdec->dcp.count,
+				vdec->dcp.index);
+		break;
+	case 3:
+		num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
+		break;
+	case 4:
+		num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
+		break;
+	case 5:
+		num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
+		break;
+	case 6:
+		num = scnprintf(str, size, "sequence = %d\n", vdec->sequence);
+		break;
+	case 7:
+		num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
+				vdec->drain, vdec->eos_received, vdec->source_change);
+		break;
+	case 8:
+		num = scnprintf(str, size, "ts_pre_count = %d, frame_depth = %d\n",
+				vdec->ts_pre_count, vdec->frame_depth);
+		break;
+	case 9:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				vdec->codec_info.frame_rate.numerator,
+				vdec->codec_info.frame_rate.denominator);
+		break;
+	case 10:
+	{
+		s64 timestamp = vdec->timestamp;
+		s64 ts_start = vdec->ts_start;
+		s64 ts_input = vdec->ts_input;
+
+		num = scnprintf(str, size, "timestamp = %9lld.%09lld(%9lld.%09lld, %9lld.%09lld)\n",
+				timestamp / NSEC_PER_SEC,
+				timestamp % NSEC_PER_SEC,
+				ts_start / NSEC_PER_SEC,
+				ts_start % NSEC_PER_SEC,
+				ts_input / NSEC_PER_SEC,
+				ts_input % NSEC_PER_SEC);
+	}
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops vdec_inst_ops = {
+	.ctrl_init = vdec_ctrl_init,
+	.check_ready = vdec_check_ready,
+	.buf_done = vdec_buf_done,
+	.get_one_frame = vdec_frame_decoded,
+	.stop_done = vdec_stop_done,
+	.event_notify = vdec_event_notify,
+	.release = vdec_release,
+	.cleanup = vdec_cleanup,
+	.start = vdec_start_session,
+	.stop = vdec_stop_session,
+	.process_output = vdec_process_output,
+	.process_capture = vdec_process_capture,
+	.on_queue_empty = vdec_on_queue_empty,
+	.get_debug_info = vdec_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void vdec_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec;
+	struct v4l2_format f;
+
+	vdec = inst->priv;
+	vdec->frame_depth = VDEC_FRAME_DEPTH;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M_8L128;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+}
+
+static int vdec_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct vdec_t *vdec;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	vdec = vzalloc(sizeof(*vdec));
+	if (!vdec) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &vdec_inst_ops;
+	inst->formats = vdec_formats;
+	inst->type = VPU_CORE_TYPE_DEC;
+	inst->priv = vdec;
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret)
+		return ret;
+
+	vdec->fixed_fmt = false;
+	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+	vdec_init(file);
+
+	return 0;
+}
+
+static __poll_t vdec_poll(struct file *file, poll_table *wait)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q, *dst_q;
+	__poll_t ret;
+
+	ret = v4l2_m2m_fop_poll(file, wait);
+	src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (vb2_is_streaming(src_q) && !vb2_is_streaming(dst_q))
+		ret &= (~EPOLLERR);
+	if (!src_q->error && !dst_q->error &&
+	    (vb2_is_streaming(src_q) && list_empty(&src_q->queued_list)) &&
+	    (vb2_is_streaming(dst_q) && list_empty(&dst_q->queued_list)))
+		ret &= (~EPOLLERR);
+
+	return ret;
+}
+
+static const struct v4l2_file_operations vdec_fops = {
+	.owner = THIS_MODULE,
+	.open = vdec_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vdec_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void)
+{
+	return &vdec_ioctl_ops;
+}
+
+const struct v4l2_file_operations *vdec_get_fops(void)
+{
+	return &vdec_fops;
+}
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:25 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:25 +0800
Subject: [PATCH v15 09/13] media: amphion: implement windsor encoder rpc
 interface
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <77476005fd2eb09a07636b3f0c64dc58c85d702b.1643077283.git.ming.qian@nxp.com>

This part implements the windsor encoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_windsor.c | 1169 ++++++++++++++++++
 drivers/media/platform/amphion/vpu_windsor.h |   37 +
 2 files changed, 1206 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.h

diff --git a/drivers/media/platform/amphion/vpu_windsor.c b/drivers/media/platform/amphion/vpu_windsor.c
new file mode 100644
index 000000000000..e8852dd8535b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_windsor.c
@@ -0,0 +1,1169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_v4l2.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+
+#define CMD_SIZE				2560
+#define MSG_SIZE				25600
+#define WINDSOR_USER_DATA_WORDS			16
+#define WINDSOR_MAX_SRC_FRAMES			0x6
+#define WINDSOR_MAX_REF_FRAMES			0x3
+#define WINDSOR_BITRATE_UNIT			1024
+#define WINDSOR_H264_EXTENDED_SAR		255
+
+enum {
+	GTB_ENC_CMD_NOOP        = 0x0,
+	GTB_ENC_CMD_STREAM_START,
+	GTB_ENC_CMD_FRAME_ENCODE,
+	GTB_ENC_CMD_FRAME_SKIP,
+	GTB_ENC_CMD_STREAM_STOP,
+	GTB_ENC_CMD_PARAMETER_UPD,
+	GTB_ENC_CMD_TERMINATE,
+	GTB_ENC_CMD_SNAPSHOT,
+	GTB_ENC_CMD_ROLL_SNAPSHOT,
+	GTB_ENC_CMD_LOCK_SCHEDULER,
+	GTB_ENC_CMD_UNLOCK_SCHEDULER,
+	GTB_ENC_CMD_CONFIGURE_CODEC,
+	GTB_ENC_CMD_DEAD_MARK,
+	GTB_ENC_CMD_FIRM_RESET,
+	GTB_ENC_CMD_FW_STATUS,
+	GTB_ENC_CMD_RESERVED
+};
+
+enum {
+	VID_API_EVENT_UNDEFINED = 0x0,
+	VID_API_ENC_EVENT_RESET_DONE = 0x1,
+	VID_API_ENC_EVENT_START_DONE,
+	VID_API_ENC_EVENT_STOP_DONE,
+	VID_API_ENC_EVENT_TERMINATE_DONE,
+	VID_API_ENC_EVENT_FRAME_INPUT_DONE,
+	VID_API_ENC_EVENT_FRAME_DONE,
+	VID_API_ENC_EVENT_FRAME_RELEASE,
+	VID_API_ENC_EVENT_PARA_UPD_DONE,
+	VID_API_ENC_EVENT_MEM_REQUEST,
+	VID_API_ENC_EVENT_FIRMWARE_XCPT,
+	VID_API_ENC_EVENT_RESERVED
+};
+
+enum {
+	MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+	MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+};
+
+struct windsor_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_rpc_buffer_desc cmd_buffer_desc;
+	struct vpu_rpc_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 mvd_fw_offset;
+	u32 max_streams;
+	u32 ctrl_iface[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_config;
+	u32 api_version;
+	struct vpu_rpc_buffer_desc log_buffer_desc;
+};
+
+struct windsor_ctrl_iface {
+	u32 enc_yuv_buffer_desc;
+	u32 enc_stream_buffer_desc;
+	u32 enc_expert_mode_param;
+	u32 enc_param;
+	u32 enc_mem_pool;
+	u32 enc_encoding_status;
+	u32 enc_dsa_status;
+};
+
+struct vpu_enc_yuv_desc {
+	u32 frame_id;
+	u32 luma_base;
+	u32 chroma_base;
+	u32 param_idx;
+	u32 key_frame;
+};
+
+struct vpu_enc_calib_params {
+	u32 use_ame;
+
+	u32 cme_mvx_max;
+	u32 cme_mvy_max;
+	u32 ame_prefresh_y0;
+	u32 ame_prefresh_y1;
+	u32 fme_min_sad;
+	u32 cme_min_sad;
+
+	u32 fme_pred_int_weight;
+	u32 fme_pred_hp_weight;
+	u32 fme_pred_qp_weight;
+	u32 fme_cost_weight;
+	u32 fme_act_thold;
+	u32 fme_sad_thold;
+	u32 fme_zero_sad_thold;
+
+	u32 fme_lrg_mvx_lmt;
+	u32 fme_lrg_mvy_lmt;
+	u32 fme_force_mode;
+	u32 fme_force4mvcost;
+	u32 fme_force2mvcost;
+
+	u32 h264_inter_thrd;
+
+	u32 i16x16_mode_cost;
+	u32 i4x4_mode_lambda;
+	u32 i8x8_mode_lambda;
+
+	u32 inter_mod_mult;
+	u32 inter_sel_mult;
+	u32 inter_bid_cost;
+	u32 inter_bwd_cost;
+	u32 inter_4mv_cost;
+	s32 one_mv_i16_cost;
+	s32 one_mv_i4x4_cost;
+	s32 one_mv_i8x8_cost;
+	s32 two_mv_i16_cost;
+	s32 two_mv_i4x4_cost;
+	s32 two_mv_i8x8_cost;
+	s32 four_mv_i16_cost;
+	s32 four_mv_i4x4_cost;
+	s32 four_mv_i8x8_cost;
+
+	u32 intra_pred_enab;
+	u32 intra_chr_pred;
+	u32 intra16_pred;
+	u32 intra4x4_pred;
+	u32 intra8x8_pred;
+
+	u32 cb_base;
+	u32 cb_size;
+	u32 cb_head_room;
+
+	u32 mem_page_width;
+	u32 mem_page_height;
+	u32 mem_total_size;
+	u32 mem_chunk_phys_addr;
+	u32 mem_chunk_virt_addr;
+	u32 mem_chunk_size;
+	u32 mem_y_stride;
+	u32 mem_uv_stride;
+
+	u32 split_wr_enab;
+	u32 split_wr_req_size;
+	u32 split_rd_enab;
+	u32 split_rd_req_size;
+};
+
+struct vpu_enc_config_params {
+	u32 param_change;
+	u32 start_frame;
+	u32 end_frame;
+	u32 userdata_enable;
+	u32 userdata_id[4];
+	u32 userdata_message[WINDSOR_USER_DATA_WORDS];
+	u32 userdata_length;
+	u32 h264_profile_idc;
+	u32 h264_level_idc;
+	u32 h264_au_delimiter;
+	u32 h264_seq_end_code;
+	u32 h264_recovery_points;
+	u32 h264_vui_parameters;
+	u32 h264_aspect_ratio_present;
+	u32 h264_aspect_ratio_sar_width;
+	u32 h264_aspect_ratio_sar_height;
+	u32 h264_overscan_present;
+	u32 h264_video_type_present;
+	u32 h264_video_format;
+	u32 h264_video_full_range;
+	u32 h264_video_colour_descriptor;
+	u32 h264_video_colour_primaries;
+	u32 h264_video_transfer_char;
+	u32 h264_video_matrix_coeff;
+	u32 h264_chroma_loc_info_present;
+	u32 h264_chroma_loc_type_top;
+	u32 h264_chroma_loc_type_bot;
+	u32 h264_timing_info_present;
+	u32 h264_buffering_period_present;
+	u32 h264_low_delay_hrd_flag;
+	u32 aspect_ratio;
+	u32 test_mode;                  // Automated firmware test mode
+	u32 dsa_test_mode;              // Automated test mode for the DSA.
+	u32 fme_test_mode;              // Automated test mode for the fme
+	u32 cbr_row_mode;               //0: FW mode; 1: HW mode
+	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+	u32 encode_mode;                // H264, VC1, MPEG2, DIVX
+	u32 frame_width;                // display width
+	u32 frame_height;               // display height
+	u32 enc_frame_width;            // encoding width, should be 16-pix align
+	u32 enc_frame_height;           // encoding height, should be 16-pix aligned
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 vi_field_source;
+	u32 vi_frame_width;
+	u32 vi_frame_height;
+	u32 crop_frame_width;
+	u32 crop_frame_height;
+	u32 crop_x_start_posn;
+	u32 crop_y_start_posn;
+	u32 mode422;
+	u32 mode_yuy2;
+	u32 dsa_luma_en;
+	u32 dsa_chroma_en;
+	u32 dsa_ext_hfilt_en;
+	u32 dsa_di_en;
+	u32 dsa_di_top_ref;
+	u32 dsa_vertf_disable;
+	u32 dsa_disable_pwb;
+	u32 dsa_hor_phase;
+	u32 dsa_ver_phase;
+	u32 dsa_iac_enable;
+	u32 iac_sc_threshold;
+	u32 iac_vm_threshold;
+	u32 iac_skip_mode;
+	u32 iac_grp_width;
+	u32 iac_grp_height;
+	u32 rate_control_mode;
+	u32 rate_control_resolution;
+	u32 buffer_size;
+	u32 buffer_level_init;
+	u32 buffer_I_bit_budget;
+	u32 top_field_first;
+	u32 intra_lum_qoffset;
+	u32 intra_chr_qoffset;
+	u32 inter_lum_qoffset;
+	u32 inter_chr_qoffset;
+	u32 use_def_scaling_mtx;
+	u32 inter_8x8_enab;
+	u32 inter_4x4_enab;
+	u32 fme_enable_qpel;
+	u32 fme_enable_hpel;
+	u32 fme_nozeromv;
+	u32 fme_predmv_en;
+	u32 fme_pred_2mv4mv;
+	u32 fme_smallsadthresh;
+	u32 ame_en_lmvc;
+	u32 ame_x_mult;
+	u32 cme_enable_4mv;
+	u32 cme_enable_1mv;
+	u32 hme_enable_16x8mv;
+	u32 hme_enable_8x16mv;
+	u32 cme_mv_weight;
+	u32 cme_mv_cost;
+	u32 ame_mult_mv;
+	u32 ame_shift_mv;
+	u32 hme_forceto1mv_en;
+	u32 hme_2mv_cost;
+	u32 hme_pred_mode;
+	u32 hme_sc_rnge;
+	u32 hme_sw_rnge;
+	u32 output_format;
+	u32 timestamp_enab;
+	u32 initial_pts_enab;
+	u32 initial_pts;
+};
+
+struct vpu_enc_static_params {
+	u32 param_change;
+	u32 gop_length;
+	u32 rate_control_bitrate;
+	u32 rate_control_bitrate_min;
+	u32 rate_control_bitrate_max;
+	u32 rate_control_content_models;
+	u32 rate_control_iframe_maxsize;
+	u32 rate_control_qp_init;
+	u32 rate_control_islice_qp;
+	u32 rate_control_pslice_qp;
+	u32 rate_control_bslice_qp;
+	u32 adaptive_quantization;
+	u32 aq_variance;
+	u32 cost_optimization;
+	u32 fdlp_mode;
+	u32 enable_isegbframes;
+	u32 enable_adaptive_keyratio;
+	u32 keyratio_imin;
+	u32 keyratio_imax;
+	u32 keyratio_pmin;
+	u32 keyratio_pmax;
+	u32 keyratio_bmin;
+	u32 keyratio_bmax;
+	s32 keyratio_istep;
+	s32 keyratio_pstep;
+	s32 keyratio_bstep;
+	u32 enable_paff;
+	u32 enable_b_frame_ref;
+	u32 enable_adaptive_gop;
+	u32 enable_closed_gop;
+	u32 open_gop_refresh_freq;
+	u32 enable_adaptive_sc;
+	u32 enable_fade_detection;
+	s32 fade_detection_threshold;
+	u32 enable_repeat_b;
+	u32 enable_low_delay_b;
+};
+
+struct vpu_enc_dynamic_params {
+	u32 param_change;
+	u32 rows_per_slice;
+	u32 mbaff_enable;
+	u32 dbf_enable;
+	u32 field_source;
+	u32 gop_b_length;
+	u32 mb_group_size;
+	u32 cbr_rows_per_group;
+	u32 skip_enable;
+	u32 pts_bits_0_to_31;
+	u32 pts_bit_32;
+	u32 rm_expsv_cff;
+	u32 const_ipred;
+	s32 chr_qp_offset;
+	u32 intra_mb_qp_offset;
+	u32 h264_cabac_init_method;
+	u32 h264_cabac_init_idc;
+	u32 h264_cabac_enable;
+	s32 alpha_c0_offset_div2;
+	s32 beta_offset_div2;
+	u32 intra_prefresh_y0;
+	u32 intra_prefresh_y1;
+	u32 dbg_dump_rec_src;
+};
+
+struct vpu_enc_expert_mode_param {
+	struct vpu_enc_calib_params calib_param;
+	struct vpu_enc_config_params config_param;
+	struct vpu_enc_static_params static_param;
+	struct vpu_enc_dynamic_params dynamic_param;
+};
+
+enum MEDIAIP_ENC_FMT {
+	MEDIAIP_ENC_FMT_H264 = 0,
+	MEDIAIP_ENC_FMT_VC1,
+	MEDIAIP_ENC_FMT_MPEG2,
+	MEDIAIP_ENC_FMT_MPEG4SP,
+	MEDIAIP_ENC_FMT_H263,
+	MEDIAIP_ENC_FMT_MPEG1,
+	MEDIAIP_ENC_FMT_SHORT_HEADER,
+	MEDIAIP_ENC_FMT_NULL
+};
+
+enum MEDIAIP_ENC_PROFILE {
+	MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+	MEDIAIP_ENC_PROF_MPEG2_MP,
+	MEDIAIP_ENC_PROF_MPEG2_HP,
+	MEDIAIP_ENC_PROF_H264_BP,
+	MEDIAIP_ENC_PROF_H264_MP,
+	MEDIAIP_ENC_PROF_H264_HP,
+	MEDIAIP_ENC_PROF_MPEG4_SP,
+	MEDIAIP_ENC_PROF_MPEG4_ASP,
+	MEDIAIP_ENC_PROF_VC1_SP,
+	MEDIAIP_ENC_PROF_VC1_MP,
+	MEDIAIP_ENC_PROF_VC1_AP
+};
+
+enum MEDIAIP_ENC_BITRATE_MODE {
+	MEDIAIP_ENC_BITRATE_MODE_VBR          = 0x00000001,
+	MEDIAIP_ENC_BITRATE_MODE_CBR          = 0x00000002,
+	MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP  = 0x00000004
+};
+
+struct vpu_enc_memory_resource {
+	u32 phys;
+	u32 virt;
+	u32 size;
+};
+
+struct vpu_enc_param {
+	enum MEDIAIP_ENC_FMT codec_mode;
+	enum MEDIAIP_ENC_PROFILE profile;
+	u32 level;
+
+	struct vpu_enc_memory_resource enc_mem_desc;
+
+	u32 frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	u32 src_offset_x;
+	u32 src_offset_y;
+	u32 src_crop_width;
+	u32 src_crop_height;
+	u32 out_width;
+	u32 out_height;
+	u32 iframe_interval;
+	u32 bframes;
+	u32 low_latency_mode;
+
+	enum MEDIAIP_ENC_BITRATE_MODE  bitrate_mode;
+	u32 target_bitrate;
+	u32 max_bitrate;
+	u32 min_bitrate;
+	u32 init_slice_qp;
+};
+
+struct vpu_enc_mem_pool {
+	struct vpu_enc_memory_resource enc_frames[WINDSOR_MAX_SRC_FRAMES];
+	struct vpu_enc_memory_resource ref_frames[WINDSOR_MAX_REF_FRAMES];
+	struct vpu_enc_memory_resource act_frame;
+};
+
+struct vpu_enc_encoding_status {
+	u32   frame_id;
+	u32   error_flag;   //Error type
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[12];
+
+};
+
+struct vpu_enc_dsa_status {
+	u32   frame_id;
+	u32   dsa_cyle;
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[4];
+};
+
+struct vpu_enc_ctrl {
+	struct vpu_enc_yuv_desc *yuv_desc;
+	struct vpu_rpc_buffer_desc *stream_desc;
+	struct vpu_enc_expert_mode_param *expert;
+	struct vpu_enc_param *param;
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_encoding_status *status;
+	struct vpu_enc_dsa_status *dsa;
+};
+
+struct vpu_enc_host_ctrls {
+	struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS];
+};
+
+struct windsor_pic_info {
+	u32 frame_id;
+	u32 pic_encod_done;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 flush_done;
+	u32 mb_y;
+	u32 mb_x;
+	u32 frame_size;
+	u32 frame_enc_ttl_cycles;
+	u32 frame_enc_ttl_frm_cycles;
+	u32 frame_enc_ttl_slc_cycles;
+	u32 frame_enc_ttl_enc_cycles;
+	u32 frame_enc_ttl_hme_cycles;
+	u32 frame_enc_ttl_dsa_cycles;
+	u32 frame_enc_fw_cycles;
+	u32 frame_crc;
+	u32 num_interrupts_1;
+	u32 num_interrupts_2;
+	u32 poc;
+	u32 ref_info;
+	u32 pic_num;
+	u32 pic_activity;
+	u32 scene_change;
+	u32 mb_stats;
+	u32 enc_cache_count0;
+	u32 enc_cache_count1;
+	u32 mtl_wr_strb_cnt;
+	u32 mtl_rd_strb_cnt;
+	u32 str_buff_wptr;
+	u32 diagnosticEvents;
+	u32 proc_iacc_tot_rd_cnt;
+	u32 proc_dacc_tot_rd_cnt;
+	u32 proc_dacc_tot_wr_cnt;
+	u32 proc_dacc_reg_rd_cnt;
+	u32 proc_dacc_reg_wr_cnt;
+	u32 proc_dacc_rng_rd_cnt;
+	u32 proc_dacc_rng_wr_cnt;
+	s32 tv_s;
+	u32 tv_ns;
+};
+
+u32 vpu_windsor_get_data_size(void)
+{
+	return sizeof(struct vpu_enc_host_ctrls);
+}
+
+static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared,
+					     u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].yuv_desc;
+}
+
+static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared,
+					     u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].pool;
+}
+
+static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared,
+						       u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].stream_desc;
+}
+
+static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared,
+							  u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].expert;
+}
+
+static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].param;
+}
+
+static u32 get_ptr(u32 ptr)
+{
+	return (ptr | 0x80000000);
+}
+
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			  struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	struct windsor_iface *iface;
+	struct windsor_ctrl_iface *ctrl;
+	struct vpu_enc_host_ctrls *hcs;
+	unsigned int i;
+
+	if (rpc->phys < boot_addr)
+		return;
+
+	base_phy_addr = rpc->phys - boot_addr;
+	iface = rpc->virt;
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+	hcs = shared->priv;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct windsor_iface);
+	phy_addr = base_phy_addr + offset;
+	shared->cmd_desc = &iface->cmd_buffer_desc;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.start =
+	iface->cmd_buffer_desc.rptr =
+	iface->cmd_buffer_desc.wptr = phy_addr;
+	iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE;
+
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+	shared->msg_desc = &iface->msg_buffer_desc;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.start =
+	iface->msg_buffer_desc.wptr =
+	iface->msg_buffer_desc.rptr = phy_addr;
+	iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE;
+
+	offset += MSG_SIZE;
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		iface->ctrl_iface[i] = base_phy_addr + offset;
+		offset += sizeof(struct windsor_ctrl_iface);
+	}
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr);
+
+		ctrl->enc_yuv_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].yuv_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_yuv_desc);
+
+		ctrl->enc_stream_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].stream_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_rpc_buffer_desc);
+
+		ctrl->enc_expert_mode_param = base_phy_addr + offset;
+		hcs->ctrls[i].expert = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_expert_mode_param);
+
+		ctrl->enc_param = base_phy_addr + offset;
+		hcs->ctrls[i].param = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_param);
+
+		ctrl->enc_mem_pool = base_phy_addr + offset;
+		hcs->ctrls[i].pool = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_mem_pool);
+
+		ctrl->enc_encoding_status = base_phy_addr + offset;
+		hcs->ctrls[i].status = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_encoding_status);
+
+		ctrl->enc_dsa_status = base_phy_addr + offset;
+		hcs->ctrls[i].dsa = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_dsa_status);
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	iface->log_buffer_desc.start =
+	iface->log_buffer_desc.wptr =
+	iface->log_buffer_desc.rptr = log->phys - shared->boot_addr;
+	iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length;
+}
+
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct windsor_iface *iface = shared->iface;
+	struct vpu_rpc_system_config *config = &iface->system_config;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+}
+
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0x300000;
+}
+
+static struct vpu_pair windsor_cmds[] = {
+	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+	{VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE},
+	{VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET},
+	{VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD},
+	{VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS}
+};
+
+static struct vpu_pair windsor_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE},
+	{VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE},
+	{VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST},
+	{VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT},
+};
+
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+	s64 timestamp;
+
+	ret = vpu_find_dst_by_src(windsor_cmds, ARRAY_SIZE(windsor_cmds), id);
+	if (ret < 0)
+		return ret;
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+	if (id == VPU_CMD_ID_FRAME_ENCODE) {
+		pkt->hdr.num = 2;
+		timestamp = *(s64 *)data;
+		if (timestamp < 0) {
+			pkt->data[0] = (u32)-1;
+			pkt->data[1] = 0;
+		} else {
+			pkt->data[0] = timestamp / NSEC_PER_SEC;
+			pkt->data[1] = timestamp % NSEC_PER_SEC;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_windsor_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(windsor_msgs, ARRAY_SIZE(windsor_msgs), id);
+}
+
+static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_enc_pic_info *info = data;
+	struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data;
+
+	info->frame_id = windsor->frame_id;
+	switch (windsor->pic_type) {
+	case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+	case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_KEYFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_PFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_BFRAME;
+		break;
+	default:
+		break;
+	}
+	info->skipped_frame = windsor->skipped_frame;
+	info->error_flag = windsor->error_flag;
+	info->psnr = windsor->psnr;
+	info->frame_size = windsor->frame_size;
+	info->wptr = get_ptr(windsor->str_buff_wptr);
+	info->crc = windsor->frame_crc;
+	info->timestamp = MAKE_TIMESTAMP(windsor->tv_s, windsor->tv_ns);
+}
+
+static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_pkt_mem_req_data *req_data = data;
+
+	req_data->enc_frame_size = pkt->data[0];
+	req_data->enc_frame_num = pkt->data[1];
+	req_data->ref_frame_size = pkt->data[2];
+	req_data->ref_frame_num = pkt->data[3];
+	req_data->act_buf_size = pkt->data[4];
+	req_data->act_buf_num = 1;
+}
+
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_ENC_EVENT_FRAME_DONE:
+		vpu_windsor_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_MEM_REQUEST:
+		vpu_windsor_unpack_mem_req(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_FRAME_RELEASE:
+		*(u32 *)data = pkt->data[0];
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vb2_buffer *vb)
+{
+	struct vpu_enc_yuv_desc *desc;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (instance >= VID_API_NUM_STREAMS)
+		return -EINVAL;
+
+	desc = get_yuv_desc(shared, instance);
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	desc->frame_id = vbuf->sequence;
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		desc->key_frame = 1;
+	else
+		desc->key_frame = 0;
+	desc->luma_base = vpu_get_vb_phy_addr(vb, 0);
+	desc->chroma_base = vpu_get_vb_phy_addr(vb, 1);
+
+	return 0;
+}
+
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			    struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	vpu_windsor_fill_yuv_frame(shared, inst->id, vb);
+	return vpu_session_encode_frame(inst, vb->timestamp);
+}
+
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+				       u32 instance,
+				       u32 type,
+				       u32 index,
+				       struct vpu_buffer *buf)
+{
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_memory_resource *res;
+
+	if (instance >= VID_API_NUM_STREAMS)
+		return -EINVAL;
+
+	pool = get_mem_pool(shared, instance);
+
+	switch (type) {
+	case MEM_RES_ENC:
+		res = &pool->enc_frames[index];
+		break;
+	case MEM_RES_REF:
+		res = &pool->ref_frames[index];
+		break;
+	case MEM_RES_ACT:
+		res = &pool->act_frame;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	res->phys = buf->phys;
+	res->virt = buf->phys - shared->boot_addr;
+	res->size = buf->length;
+
+	return 0;
+}
+
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance,
+				     struct vpu_buffer *buf)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	struct vpu_enc_expert_mode_param *expert;
+
+	desc = get_stream_buf_desc(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	desc->start = buf->phys;
+	desc->wptr = buf->phys;
+	desc->rptr = buf->phys;
+	desc->end = buf->phys + buf->length;
+
+	expert->calib_param.mem_chunk_phys_addr = 0;
+	expert->calib_param.mem_chunk_virt_addr = 0;
+	expert->calib_param.mem_chunk_size = 0;
+	expert->calib_param.cb_base = buf->phys;
+	expert->calib_param.cb_size = buf->length;
+
+	return 0;
+}
+
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, u32 ptr, bool write)
+{
+	struct vpu_rpc_buffer_desc *desc;
+
+	desc = get_stream_buf_desc(shared, instance);
+
+	/*update wptr/rptr after data is written or read*/
+	mb();
+	if (write)
+		desc->wptr = ptr;
+	else
+		desc->rptr = ptr;
+
+	return 0;
+}
+
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				       u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_rpc_buffer_desc *rpc_desc;
+
+	rpc_desc = get_stream_buf_desc(shared, instance);
+	if (desc) {
+		desc->wptr = get_ptr(rpc_desc->wptr);
+		desc->rptr = get_ptr(rpc_desc->rptr);
+		desc->start = get_ptr(rpc_desc->start);
+		desc->end = get_ptr(rpc_desc->end);
+	}
+
+	return 0;
+}
+
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	return iface->fw_version;
+}
+
+static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert,
+				      struct vpu_encode_params *params)
+{
+	expert->config_param.frame_rate_num = params->frame_rate.numerator;
+	expert->config_param.frame_rate_den = params->frame_rate.denominator;
+
+	return 0;
+}
+
+static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat)
+{
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		param->codec_mode = MEDIAIP_ENC_FMT_H264;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile)
+{
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		param->profile = MEDIAIP_ENC_PROF_H264_BP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		param->profile = MEDIAIP_ENC_PROF_H264_MP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		param->profile = MEDIAIP_ENC_PROF_H264_HP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const u32 h264_level[] = {
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1B]  = 14,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
+};
+
+static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level)
+{
+	if (level >= ARRAY_SIZE(h264_level))
+		return -EINVAL;
+
+	param->level = h264_level[level];
+
+	return 0;
+}
+
+static int vpu_windsor_set_size(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->src_stride = params->src_stride;
+	windsor->src_width = params->src_width;
+	windsor->src_height = params->src_height;
+	windsor->src_offset_x = params->crop.left;
+	windsor->src_offset_y = params->crop.top;
+	windsor->src_crop_width = params->crop.width;
+	windsor->src_crop_height = params->crop.height;
+	windsor->out_width = params->out_width;
+	windsor->out_height = params->out_height;
+
+	return 0;
+}
+
+static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop)
+{
+	param->iframe_interval = gop;
+
+	return 0;
+}
+
+static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes)
+{
+	if (bframes) {
+		param->low_latency_mode = 0;
+		param->bframes = bframes;
+	} else {
+		param->low_latency_mode = 1;
+		param->bframes = 0;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 rc_enable, u32 mode)
+{
+	if (!rc_enable)
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP;
+	else if (mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_VBR;
+	else
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR;
+
+	return 0;
+}
+
+static u32 vpu_windsor_bitrate(u32 bitrate)
+{
+	return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT);
+}
+
+static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor,
+				   struct vpu_encode_params *params)
+{
+	windsor->target_bitrate = vpu_windsor_bitrate(params->bitrate);
+	windsor->min_bitrate = vpu_windsor_bitrate(params->bitrate_min);
+	windsor->max_bitrate = vpu_windsor_bitrate(params->bitrate_max);
+
+	return 0;
+}
+
+static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert,
+			      struct vpu_encode_params *params)
+{
+	expert->static_param.rate_control_islice_qp = params->i_frame_qp;
+	expert->static_param.rate_control_pslice_qp = params->p_frame_qp;
+	expert->static_param.rate_control_bslice_qp = params->b_frame_qp;
+
+	return 0;
+}
+
+static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert,
+			       struct vpu_encode_params *params)
+{
+	expert->config_param.h264_aspect_ratio_present = params->sar.enable;
+	if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED)
+		expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR;
+	else
+		expert->config_param.aspect_ratio = params->sar.idc;
+	expert->config_param.h264_aspect_ratio_sar_width = params->sar.width;
+	expert->config_param.h264_aspect_ratio_sar_height = params->sar.height;
+
+	return 0;
+}
+
+static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert,
+				 struct vpu_encode_params *params)
+{
+	expert->config_param.h264_video_type_present = 1;
+	expert->config_param.h264_video_format = 5;
+	expert->config_param.h264_video_colour_descriptor = 1;
+	expert->config_param.h264_video_colour_primaries =
+		vpu_color_cvrt_primaries_v2i(params->color.primaries);
+	expert->config_param.h264_video_transfer_char =
+		vpu_color_cvrt_transfers_v2i(params->color.transfer);
+	expert->config_param.h264_video_matrix_coeff =
+		vpu_color_cvrt_matrix_v2i(params->color.matrix);
+	expert->config_param.h264_video_full_range =
+		vpu_color_cvrt_full_range_v2i(params->color.full_range);
+	return 0;
+}
+
+static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared,
+				      u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	struct vpu_enc_expert_mode_param *expert;
+
+	windsor = get_enc_param(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR)
+		return 0;
+	if (!params->rc_enable)
+		return 0;
+	if (vpu_windsor_bitrate(params->bitrate) == windsor->target_bitrate)
+		return 0;
+
+	vpu_windsor_set_bitrate(windsor, params);
+	expert->static_param.rate_control_bitrate = windsor->target_bitrate;
+	expert->static_param.rate_control_bitrate_min = windsor->min_bitrate;
+	expert->static_param.rate_control_bitrate_max = windsor->max_bitrate;
+
+	return 0;
+}
+
+static int vpu_windsor_set_params(struct vpu_shared_addr *shared,
+				  u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	int ret;
+
+	windsor = get_enc_param(shared, instance);
+
+	if (params->input_format != V4L2_PIX_FMT_NV12 &&
+	    params->input_format != V4L2_PIX_FMT_NV12M)
+		return -EINVAL;
+
+	ret = vpu_windsor_set_format(windsor, params->codec_format);
+	if (ret)
+		return ret;
+	vpu_windsor_set_profile(windsor, params->profile);
+	vpu_windsor_set_level(windsor, params->level);
+	vpu_windsor_set_size(windsor, params);
+	vpu_windsor_set_gop(windsor, params->gop_length);
+	vpu_windsor_set_bframes(windsor, params->bframes);
+	vpu_windsor_set_bitrate_mode(windsor, params->rc_enable, params->rc_mode);
+	vpu_windsor_set_bitrate(windsor, params);
+	windsor->init_slice_qp = params->i_frame_qp;
+
+	if (!params->frame_rate.numerator)
+		return -EINVAL;
+	windsor->frame_rate = params->frame_rate.denominator / params->frame_rate.numerator;
+
+	return 0;
+}
+
+static int vpu_windsor_update_params(struct vpu_shared_addr *shared,
+				     u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_expert_mode_param *expert;
+
+	expert = get_expert_param(shared, instance);
+
+	vpu_windsor_set_frame_rate(expert, params);
+	vpu_windsor_set_qp(expert, params);
+	vpu_windsor_set_sar(expert, params);
+	vpu_windsor_set_color(expert, params);
+	vpu_windsor_update_bitrate(shared, instance, params);
+	/*expert->config_param.iac_sc_threshold = 0;*/
+
+	return 0;
+}
+
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+				  u32 instance, struct vpu_encode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_windsor_set_params(shared, instance, params);
+	else
+		return vpu_windsor_update_params(shared, instance, params);
+}
+
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/amphion/vpu_windsor.h b/drivers/media/platform/amphion/vpu_windsor.h
new file mode 100644
index 000000000000..3fbb6556dbca
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_windsor.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_WINDSOR_H
+#define _AMPHION_VPU_WINDSOR_H
+
+u32 vpu_windsor_get_data_size(void);
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			  struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log);
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_windsor_convert_msg_id(u32 msg_id);
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+				       u32 instance, u32 type, u32 index,
+				       struct vpu_buffer *buf);
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, struct vpu_buffer *buf);
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, u32 ptr, bool write);
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				       u32 instance, struct vpu_rpc_buffer_desc *desc);
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared);
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+				  u32 instance,
+				  struct vpu_encode_params *params,
+				  u32 update);
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			    struct vpu_inst *inst, struct vb2_buffer *vb);
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:26 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:26 +0800
Subject: [PATCH v15 10/13] media: amphion: implement malone decoder rpc
 interface
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <547f2801903a0b7678be2f1cd4d934e88a04273f.1643077283.git.ming.qian@nxp.com>

This part implements the malone decoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_malone.c | 1625 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_malone.h |   44 +
 2 files changed, 1669 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_malone.c
 create mode 100644 drivers/media/platform/amphion/vpu_malone.h

diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
new file mode 100644
index 000000000000..76085b69af6d
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -0,0 +1,1625 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/rational.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <linux/videodev2.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_imx8q.h"
+#include "vpu_malone.h"
+
+#define CMD_SIZE			25600
+#define MSG_SIZE			25600
+#define CODEC_SIZE			0x1000
+#define JPEG_SIZE			0x1000
+#define SEQ_SIZE			0x1000
+#define GOP_SIZE			0x1000
+#define PIC_SIZE			0x1000
+#define QMETER_SIZE			0x1000
+#define DBGLOG_SIZE			0x10000
+#define DEBUG_SIZE			0x80000
+#define ENG_SIZE			0x1000
+#define MALONE_SKIPPED_FRAME_ID		0x555
+
+#define MALONE_ALIGN_MBI		0x800
+#define MALONE_DCP_CHUNK_BIT		16
+#define MALONE_DCP_SIZE_MAX		0x3000000
+#define MALONE_DCP_SIZE_MIN		0x100000
+#define MALONE_DCP_FIXED_MB_ALLOC	250
+
+#define CONFIG_SET(val, cfg, pos, mask)		\
+		(*(cfg) |= (((val) << (pos)) & (mask)))
+//x means source data , y means destination data
+#define STREAM_CONFIG_FORMAT_SET(x, y)		CONFIG_SET(x, y, 0, 0x0000000F)
+#define STREAM_CONFIG_STRBUFIDX_SET(x, y)	CONFIG_SET(x, y, 8, 0x00000300)
+#define STREAM_CONFIG_NOSEQ_SET(x, y)		CONFIG_SET(x, y, 10, 0x00000400)
+#define STREAM_CONFIG_DEBLOCK_SET(x, y)		CONFIG_SET(x, y, 11, 0x00000800)
+#define STREAM_CONFIG_DERING_SET(x, y)		CONFIG_SET(x, y, 12, 0x00001000)
+#define STREAM_CONFIG_IBWAIT_SET(x, y)		CONFIG_SET(x, y, 13, 0x00002000)
+#define STREAM_CONFIG_FBC_SET(x, y)		CONFIG_SET(x, y, 14, 0x00004000)
+#define STREAM_CONFIG_PLAY_MODE_SET(x, y)	CONFIG_SET(x, y, 16, 0x00030000)
+#define STREAM_CONFIG_ENABLE_DCP_SET(x, y)	CONFIG_SET(x, y, 20, 0x00100000)
+#define STREAM_CONFIG_NUM_STR_BUF_SET(x, y)	CONFIG_SET(x, y, 21, 0x00600000)
+#define STREAM_CONFIG_MALONE_USAGE_SET(x, y)	CONFIG_SET(x, y, 23, 0x01800000)
+#define STREAM_CONFIG_MULTI_VID_SET(x, y)	CONFIG_SET(x, y, 25, 0x02000000)
+#define STREAM_CONFIG_OBFUSC_EN_SET(x, y)	CONFIG_SET(x, y, 26, 0x04000000)
+#define STREAM_CONFIG_RC4_EN_SET(x, y)		CONFIG_SET(x, y, 27, 0x08000000)
+#define STREAM_CONFIG_MCX_SET(x, y)		CONFIG_SET(x, y, 28, 0x10000000)
+#define STREAM_CONFIG_PES_SET(x, y)		CONFIG_SET(x, y, 29, 0x20000000)
+#define STREAM_CONFIG_NUM_DBE_SET(x, y)		CONFIG_SET(x, y, 30, 0x40000000)
+#define STREAM_CONFIG_FS_CTRL_MODE_SET(x, y)	CONFIG_SET(x, y, 31, 0x80000000)
+
+enum vpu_malone_stream_input_mode {
+	INVALID_MODE = 0,
+	FRAME_LVL,
+	NON_FRAME_LVL
+};
+
+enum vpu_malone_format {
+	MALONE_FMT_NULL = 0x0,
+	MALONE_FMT_AVC  = 0x1,
+	MALONE_FMT_MP2  = 0x2,
+	MALONE_FMT_VC1  = 0x3,
+	MALONE_FMT_AVS  = 0x4,
+	MALONE_FMT_ASP  = 0x5,
+	MALONE_FMT_JPG  = 0x6,
+	MALONE_FMT_RV   = 0x7,
+	MALONE_FMT_VP6  = 0x8,
+	MALONE_FMT_SPK  = 0x9,
+	MALONE_FMT_VP8  = 0xA,
+	MALONE_FMT_HEVC = 0xB,
+	MALONE_FMT_LAST = MALONE_FMT_HEVC
+};
+
+enum {
+	VID_API_CMD_NULL              = 0x00,
+	VID_API_CMD_PARSE_NEXT_SEQ    = 0x01,
+	VID_API_CMD_PARSE_NEXT_I      = 0x02,
+	VID_API_CMD_PARSE_NEXT_IP     = 0x03,
+	VID_API_CMD_PARSE_NEXT_ANY    = 0x04,
+	VID_API_CMD_DEC_PIC           = 0x05,
+	VID_API_CMD_UPDATE_ES_WR_PTR  = 0x06,
+	VID_API_CMD_UPDATE_ES_RD_PTR  = 0x07,
+	VID_API_CMD_UPDATE_UDATA      = 0x08,
+	VID_API_CMD_GET_FSINFO        = 0x09,
+	VID_API_CMD_SKIP_PIC          = 0x0a,
+	VID_API_CMD_DEC_CHUNK         = 0x0b,
+	VID_API_CMD_START             = 0x10,
+	VID_API_CMD_STOP              = 0x11,
+	VID_API_CMD_ABORT             = 0x12,
+	VID_API_CMD_RST_BUF           = 0x13,
+	VID_API_CMD_FS_RELEASE        = 0x15,
+	VID_API_CMD_MEM_REGION_ATTACH = 0x16,
+	VID_API_CMD_MEM_REGION_DETACH = 0x17,
+	VID_API_CMD_MVC_VIEW_SELECT   = 0x18,
+	VID_API_CMD_FS_ALLOC          = 0x19,
+	VID_API_CMD_DBG_GET_STATUS    = 0x1C,
+	VID_API_CMD_DBG_START_LOG     = 0x1D,
+	VID_API_CMD_DBG_STOP_LOG      = 0x1E,
+	VID_API_CMD_DBG_DUMP_LOG      = 0x1F,
+	VID_API_CMD_YUV_READY         = 0x20,
+	VID_API_CMD_TS                = 0x21,
+
+	VID_API_CMD_FIRM_RESET        = 0x40,
+
+	VID_API_CMD_SNAPSHOT          = 0xAA,
+	VID_API_CMD_ROLL_SNAPSHOT     = 0xAB,
+	VID_API_CMD_LOCK_SCHEDULER    = 0xAC,
+	VID_API_CMD_UNLOCK_SCHEDULER  = 0xAD,
+	VID_API_CMD_CQ_FIFO_DUMP      = 0xAE,
+	VID_API_CMD_DBG_FIFO_DUMP     = 0xAF,
+	VID_API_CMD_SVC_ILP           = 0xBB,
+	VID_API_CMD_FW_STATUS         = 0xF0,
+	VID_API_CMD_INVALID           = 0xFF
+};
+
+enum {
+	VID_API_EVENT_NULL			= 0x00,
+	VID_API_EVENT_RESET_DONE		= 0x01,
+	VID_API_EVENT_SEQ_HDR_FOUND		= 0x02,
+	VID_API_EVENT_PIC_HDR_FOUND		= 0x03,
+	VID_API_EVENT_PIC_DECODED		= 0x04,
+	VID_API_EVENT_FIFO_LOW			= 0x05,
+	VID_API_EVENT_FIFO_HIGH			= 0x06,
+	VID_API_EVENT_FIFO_EMPTY		= 0x07,
+	VID_API_EVENT_FIFO_FULL			= 0x08,
+	VID_API_EVENT_BS_ERROR			= 0x09,
+	VID_API_EVENT_UDATA_FIFO_UPTD		= 0x0A,
+	VID_API_EVENT_RES_CHANGE		= 0x0B,
+	VID_API_EVENT_FIFO_OVF			= 0x0C,
+	VID_API_EVENT_CHUNK_DECODED		= 0x0D,
+	VID_API_EVENT_REQ_FRAME_BUFF		= 0x10,
+	VID_API_EVENT_FRAME_BUFF_RDY		= 0x11,
+	VID_API_EVENT_REL_FRAME_BUFF		= 0x12,
+	VID_API_EVENT_STR_BUF_RST		= 0x13,
+	VID_API_EVENT_RET_PING			= 0x14,
+	VID_API_EVENT_QMETER			= 0x15,
+	VID_API_EVENT_STR_FMT_CHANGE		= 0x16,
+	VID_API_EVENT_FIRMWARE_XCPT		= 0x17,
+	VID_API_EVENT_START_DONE		= 0x18,
+	VID_API_EVENT_STOPPED			= 0x19,
+	VID_API_EVENT_ABORT_DONE		= 0x1A,
+	VID_API_EVENT_FINISHED			= 0x1B,
+	VID_API_EVENT_DBG_STAT_UPDATE		= 0x1C,
+	VID_API_EVENT_DBG_LOG_STARTED		= 0x1D,
+	VID_API_EVENT_DBG_LOG_STOPPED		= 0x1E,
+	VID_API_EVENT_DBG_LOG_UPDATED		= 0x1F,
+	VID_API_EVENT_DBG_MSG_DEC		= 0x20,
+	VID_API_EVENT_DEC_SC_ERR		= 0x21,
+	VID_API_EVENT_CQ_FIFO_DUMP		= 0x22,
+	VID_API_EVENT_DBG_FIFO_DUMP		= 0x23,
+	VID_API_EVENT_DEC_CHECK_RES		= 0x24,
+	VID_API_EVENT_DEC_CFG_INFO		= 0x25,
+	VID_API_EVENT_UNSUPPORTED_STREAM	= 0x26,
+	VID_API_EVENT_STR_SUSPENDED		= 0x30,
+	VID_API_EVENT_SNAPSHOT_DONE		= 0x40,
+	VID_API_EVENT_FW_STATUS                 = 0xF0,
+	VID_API_EVENT_INVALID			= 0xFF
+};
+
+struct vpu_malone_buffer_desc {
+	struct vpu_rpc_buffer_desc buffer;
+	u32 low;
+	u32 high;
+};
+
+struct vpu_malone_str_buffer {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+	u32 lwm;
+};
+
+struct vpu_malone_picth_info {
+	u32 frame_pitch;
+};
+
+struct vpu_malone_table_desc {
+	u32 array_base;
+	u32 size;
+};
+
+struct vpu_malone_dbglog_desc {
+	u32 addr;
+	u32 size;
+	u32 level;
+	u32 reserved;
+};
+
+struct vpu_malone_frame_buffer {
+	u32 addr;
+	u32 size;
+};
+
+struct vpu_malone_udata {
+	u32 base;
+	u32 total_size;
+	u32 slot_size;
+};
+
+struct vpu_malone_buffer_info {
+	u32 stream_input_mode;
+	u32 stream_pic_input_count;
+	u32 stream_pic_parsed_count;
+	u32 stream_buffer_threshold;
+	u32 stream_pic_end_flag;
+};
+
+struct vpu_malone_encrypt_info {
+	u32 rec4key[8];
+	u32 obfusc;
+};
+
+struct malone_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_malone_buffer_desc cmd_buffer_desc;
+	struct vpu_malone_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	struct vpu_malone_picth_info stream_pitch_info[VID_API_NUM_STREAMS];
+	u32 stream_config[VID_API_NUM_STREAMS];
+	struct vpu_malone_table_desc codec_param_tab_desc;
+	struct vpu_malone_table_desc jpeg_param_tab_desc;
+	u32 stream_buffer_desc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
+	struct vpu_malone_table_desc seq_info_tab_desc;
+	struct vpu_malone_table_desc pic_info_tab_desc;
+	struct vpu_malone_table_desc gop_info_tab_desc;
+	struct vpu_malone_table_desc qmeter_info_tab_desc;
+	u32 stream_error[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 fw_offset;
+	u32 max_streams;
+	struct vpu_malone_dbglog_desc dbglog_desc;
+	struct vpu_rpc_buffer_desc api_cmd_buffer_desc[VID_API_NUM_STREAMS];
+	struct vpu_malone_udata udata_buffer[VID_API_NUM_STREAMS];
+	struct vpu_malone_buffer_desc debug_buffer_desc;
+	struct vpu_malone_buffer_desc eng_access_buff_desc[VID_API_NUM_STREAMS];
+	u32 encrypt_info[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_cfg;
+	u32 api_version;
+	struct vpu_malone_buffer_info stream_buff_info[VID_API_NUM_STREAMS];
+};
+
+struct malone_jpg_params {
+	u32 rotation_angle;
+	u32 horiz_scale_factor;
+	u32 vert_scale_factor;
+	u32 rotation_mode;
+	u32 rgb_mode;
+	u32 chunk_mode; /* 0 ~ 1 */
+	u32 last_chunk; /* 0 ~ 1 */
+	u32 chunk_rows; /* 0 ~ 255 */
+	u32 num_bytes;
+	u32 jpg_crop_x;
+	u32 jpg_crop_y;
+	u32 jpg_crop_width;
+	u32 jpg_crop_height;
+	u32 jpg_mjpeg_mode;
+	u32 jpg_mjpeg_interlaced;
+};
+
+struct malone_codec_params {
+	u32 disp_imm;
+	u32 fourcc;
+	u32 codec_version;
+	u32 frame_rate;
+	u32 dbglog_enable;
+	u32 bsdma_lwm;
+	u32 bbd_coring;
+	u32 bbd_s_thr_row;
+	u32 bbd_p_thr_row;
+	u32 bbd_s_thr_logo_row;
+	u32 bbd_p_thr_logo_row;
+	u32 bbd_s_thr_col;
+	u32 bbd_p_thr_col;
+	u32 bbd_chr_thr_row;
+	u32 bbd_chr_thr_col;
+	u32 bbd_uv_mid_level;
+	u32 bbd_excl_win_mb_left;
+	u32 bbd_excl_win_mb_right;
+};
+
+struct malone_padding_scode {
+	u32 scode_type;
+	u32 pixelformat;
+	u32 data[2];
+};
+
+struct malone_fmt_mapping {
+	u32 pixelformat;
+	enum vpu_malone_format malone_format;
+};
+
+struct malone_scode_t {
+	struct vpu_inst *inst;
+	struct vb2_buffer *vb;
+	u32 wptr;
+	u32 need_data;
+};
+
+struct malone_scode_handler {
+	u32 pixelformat;
+	int (*insert_scode_seq)(struct malone_scode_t *scode);
+	int (*insert_scode_pic)(struct malone_scode_t *scode);
+};
+
+struct vpu_dec_ctrl {
+	struct malone_codec_params *codec_param;
+	struct malone_jpg_params *jpg;
+	void *seq_mem;
+	void *pic_mem;
+	void *gop_mem;
+	void *qmeter_mem;
+	void *dbglog_mem;
+	struct vpu_malone_str_buffer *str_buf[VID_API_NUM_STREAMS];
+	u32 buf_addr[VID_API_NUM_STREAMS];
+};
+
+u32 vpu_malone_get_data_size(void)
+{
+	return sizeof(struct vpu_dec_ctrl);
+}
+
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	unsigned int i;
+
+	if (rpc->phys < boot_addr)
+		return;
+
+	iface = rpc->virt;
+	base_phy_addr = rpc->phys - boot_addr;
+	hc = shared->priv;
+
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct malone_iface);
+	phy_addr = base_phy_addr + offset;
+
+	shared->cmd_desc = &iface->cmd_buffer_desc.buffer;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.buffer.start =
+	iface->cmd_buffer_desc.buffer.rptr =
+	iface->cmd_buffer_desc.buffer.wptr = phy_addr;
+	iface->cmd_buffer_desc.buffer.end = iface->cmd_buffer_desc.buffer.start + CMD_SIZE;
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	shared->msg_desc = &iface->msg_buffer_desc.buffer;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.buffer.start =
+	iface->msg_buffer_desc.buffer.wptr =
+	iface->msg_buffer_desc.buffer.rptr = phy_addr;
+	iface->msg_buffer_desc.buffer.end = iface->msg_buffer_desc.buffer.start + MSG_SIZE;
+	offset += MSG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->codec_param_tab_desc.array_base = phy_addr;
+	hc->codec_param = rpc->virt + offset;
+	offset += CODEC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->jpeg_param_tab_desc.array_base = phy_addr;
+	hc->jpg = rpc->virt + offset;
+	offset += JPEG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->seq_info_tab_desc.array_base = phy_addr;
+	hc->seq_mem = rpc->virt + offset;
+	offset += SEQ_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->pic_info_tab_desc.array_base = phy_addr;
+	hc->pic_mem = rpc->virt + offset;
+	offset += PIC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->gop_info_tab_desc.array_base = phy_addr;
+	hc->gop_mem = rpc->virt + offset;
+	offset += GOP_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->qmeter_info_tab_desc.array_base = phy_addr;
+	hc->qmeter_mem = rpc->virt + offset;
+	offset += QMETER_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->dbglog_desc.addr = phy_addr;
+	iface->dbglog_desc.size = DBGLOG_SIZE;
+	hc->dbglog_mem = rpc->virt + offset;
+	offset += DBGLOG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->eng_access_buff_desc[i].buffer.start =
+		iface->eng_access_buff_desc[i].buffer.wptr =
+		iface->eng_access_buff_desc[i].buffer.rptr = phy_addr;
+		iface->eng_access_buff_desc[i].buffer.end =
+			iface->eng_access_buff_desc[i].buffer.start + ENG_SIZE;
+		offset += ENG_SIZE;
+		phy_addr = base_phy_addr + offset;
+	}
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->encrypt_info[i] = phy_addr;
+		offset += sizeof(struct vpu_malone_encrypt_info);
+		phy_addr = base_phy_addr + offset;
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log)
+{
+	struct malone_iface *iface = shared->iface;
+
+	iface->debug_buffer_desc.buffer.start =
+	iface->debug_buffer_desc.buffer.wptr =
+	iface->debug_buffer_desc.buffer.rptr = log->phys - shared->boot_addr;
+	iface->debug_buffer_desc.buffer.end = iface->debug_buffer_desc.buffer.start + log->length;
+}
+
+static u32 get_str_buffer_offset(u32 instance)
+{
+	return DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * instance;
+}
+
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_system_config *config = &iface->system_cfg;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	int i;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		u32 offset = get_str_buffer_offset(i);
+
+		hc->buf_addr[i] = regs_base + offset;
+		hc->str_buf[i] = regs + offset;
+	}
+}
+
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->fw_version;
+}
+
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0xc00000;
+}
+
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_buffer *buf)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	str_buf->start = buf->phys;
+	str_buf->rptr = buf->phys;
+	str_buf->wptr = buf->phys;
+	str_buf->end = buf->phys + buf->length;
+	str_buf->lwm = 0x1;
+
+	iface->stream_buffer_desc[instance][0] = hc->buf_addr[instance];
+
+	return 0;
+}
+
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	if (desc) {
+		desc->wptr = str_buf->wptr;
+		desc->rptr = str_buf->rptr;
+		desc->start = str_buf->start;
+		desc->end = str_buf->end;
+	}
+
+	return 0;
+}
+
+static void vpu_malone_update_wptr(struct vpu_malone_str_buffer *str_buf, u32 wptr)
+{
+	/*update wptr after data is written*/
+	mb();
+	str_buf->wptr = wptr;
+}
+
+static void vpu_malone_update_rptr(struct vpu_malone_str_buffer *str_buf, u32 rptr)
+{
+	/*update rptr after data is read*/
+	mb();
+	str_buf->rptr = rptr;
+}
+
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	if (write)
+		vpu_malone_update_wptr(str_buf, ptr);
+	else
+		vpu_malone_update_rptr(str_buf, ptr);
+
+	return 0;
+}
+
+static struct malone_fmt_mapping fmt_mappings[] = {
+	{V4L2_PIX_FMT_H264,        MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_H264_MVC,    MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_HEVC,        MALONE_FMT_HEVC},
+	{V4L2_PIX_FMT_VC1_ANNEX_G, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_VC1_ANNEX_L, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_MPEG2,       MALONE_FMT_MP2},
+	{V4L2_PIX_FMT_MPEG4,       MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_XVID,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_H263,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_JPEG,        MALONE_FMT_JPG},
+	{V4L2_PIX_FMT_VP8,         MALONE_FMT_VP8},
+};
+
+static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) {
+		if (pixelformat == fmt_mappings[i].pixelformat)
+			return fmt_mappings[i].malone_format;
+	}
+
+	return MALONE_FMT_NULL;
+}
+
+static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      enum vpu_malone_format malone_format)
+{
+	struct malone_iface *iface = shared->iface;
+	u32 *curr_str_cfg = &iface->stream_config[instance];
+
+	*curr_str_cfg = 0;
+	STREAM_CONFIG_FORMAT_SET(malone_format, curr_str_cfg);
+	STREAM_CONFIG_STRBUFIDX_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NOSEQ_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DEBLOCK_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DERING_SET(0, curr_str_cfg);
+	STREAM_CONFIG_PLAY_MODE_SET(0x3, curr_str_cfg);
+	STREAM_CONFIG_FS_CTRL_MODE_SET(0x1, curr_str_cfg);
+	STREAM_CONFIG_ENABLE_DCP_SET(1, curr_str_cfg);
+	STREAM_CONFIG_NUM_STR_BUF_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MALONE_USAGE_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MULTI_VID_SET(0, curr_str_cfg);
+	STREAM_CONFIG_OBFUSC_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_RC4_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_MCX_SET(1, curr_str_cfg);
+	STREAM_CONFIG_PES_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NUM_DBE_SET(1, curr_str_cfg);
+}
+
+static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	enum vpu_malone_format malone_format;
+
+	malone_format = vpu_malone_format_remap(params->codec_format);
+	iface->udata_buffer[instance].base = params->udata.base;
+	iface->udata_buffer[instance].slot_size = params->udata.size;
+
+	vpu_malone_set_stream_cfg(shared, instance, malone_format);
+
+	if (malone_format == MALONE_FMT_JPG) {
+		//1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B
+		hc->jpg[instance].jpg_mjpeg_mode = 1;
+		//0: JPGD_MJPEG_PROGRESSIVE
+		hc->jpg[instance].jpg_mjpeg_interlaced = 0;
+	}
+
+	hc->codec_param[instance].disp_imm = params->b_dis_reorder ? 1 : 0;
+	hc->codec_param[instance].dbglog_enable = 0;
+	iface->dbglog_desc.level = 0;
+
+	if (params->b_non_frame)
+		iface->stream_buff_info[instance].stream_input_mode = NON_FRAME_LVL;
+	else
+		iface->stream_buff_info[instance].stream_input_mode = FRAME_LVL;
+	iface->stream_buff_info[instance].stream_buffer_threshold = 0;
+	iface->stream_buff_info[instance].stream_pic_input_count = 0;
+
+	return 0;
+}
+
+static bool vpu_malone_is_non_frame_mode(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+
+	if (iface->stream_buff_info[instance].stream_input_mode == NON_FRAME_LVL)
+		return true;
+
+	return false;
+}
+
+static int vpu_malone_update_params(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_decode_params *params)
+{
+	struct malone_iface *iface = shared->iface;
+
+	if (params->end_flag)
+		iface->stream_buff_info[instance].stream_pic_end_flag = params->end_flag;
+	params->end_flag = 0;
+
+	return 0;
+}
+
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params,
+				 u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_malone_set_params(shared, instance, params);
+	else
+		return vpu_malone_update_params(shared, instance, params);
+}
+
+static struct vpu_pair malone_cmds[] = {
+	{VPU_CMD_ID_START, VID_API_CMD_START},
+	{VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+	{VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+	{VPU_CMD_ID_RST_BUF, VID_API_CMD_RST_BUF},
+	{VPU_CMD_ID_SNAPSHOT, VID_API_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, VID_API_CMD_FIRM_RESET},
+	{VPU_CMD_ID_FS_ALLOC, VID_API_CMD_FS_ALLOC},
+	{VPU_CMD_ID_FS_RELEASE, VID_API_CMD_FS_RELEASE},
+	{VPU_CMD_ID_TIMESTAMP, VID_API_CMD_TS},
+	{VPU_CMD_ID_DEBUG, VID_API_CMD_FW_STATUS},
+};
+
+static struct vpu_pair malone_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_EVENT_STOPPED},
+	{VPU_MSG_ID_ABORT_DONE, VID_API_EVENT_ABORT_DONE},
+	{VPU_MSG_ID_BUF_RST, VID_API_EVENT_STR_BUF_RST},
+	{VPU_MSG_ID_PIC_EOS, VID_API_EVENT_FINISHED},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, VID_API_EVENT_SEQ_HDR_FOUND},
+	{VPU_MSG_ID_RES_CHANGE, VID_API_EVENT_RES_CHANGE},
+	{VPU_MSG_ID_PIC_HDR_FOUND, VID_API_EVENT_PIC_HDR_FOUND},
+	{VPU_MSG_ID_PIC_DECODED, VID_API_EVENT_PIC_DECODED},
+	{VPU_MSG_ID_DEC_DONE, VID_API_EVENT_FRAME_BUFF_RDY},
+	{VPU_MSG_ID_FRAME_REQ, VID_API_EVENT_REQ_FRAME_BUFF},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_EVENT_REL_FRAME_BUFF},
+	{VPU_MSG_ID_FIFO_LOW, VID_API_EVENT_FIFO_LOW},
+	{VPU_MSG_ID_BS_ERROR, VID_API_EVENT_BS_ERROR},
+	{VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT},
+};
+
+static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt,
+				     struct vpu_fs_info *fs)
+{
+	const u32 fs_type[] = {
+		[MEM_RES_FRAME] = 0,
+		[MEM_RES_MBI] = 1,
+		[MEM_RES_DCP] = 2,
+	};
+
+	pkt->hdr.num = 7;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+	pkt->data[1] = fs->luma_addr;
+	if (fs->type == MEM_RES_FRAME) {
+		/*
+		 * if luma_addr equal to chroma_addr,
+		 * means luma(plane[0]) and chromau(plane[1]) used the
+		 * same fd -- usage of NXP codec2. Need to manually
+		 * offset chroma addr.
+		 */
+		if (fs->luma_addr == fs->chroma_addr)
+			fs->chroma_addr = fs->luma_addr + fs->luma_size;
+		pkt->data[2] = fs->luma_addr + fs->luma_size / 2;
+		pkt->data[3] = fs->chroma_addr;
+		pkt->data[4] = fs->chroma_addr + fs->chromau_size / 2;
+		pkt->data[5] = fs->bytesperline;
+	} else {
+		pkt->data[2] = fs->luma_size;
+		pkt->data[3] = 0;
+		pkt->data[4] = 0;
+		pkt->data[5] = 0;
+	}
+	pkt->data[6] = fs_type[fs->type];
+}
+
+static void vpu_malone_pack_fs_release(struct vpu_rpc_event *pkt,
+				       struct vpu_fs_info *fs)
+{
+	pkt->hdr.num = 1;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+}
+
+static void vpu_malone_pack_timestamp(struct vpu_rpc_event *pkt,
+				      struct vpu_ts_info *info)
+{
+	pkt->hdr.num = 3;
+	if (info->timestamp < 0) {
+		pkt->data[0] = (u32)-1;
+		pkt->data[1] = 0;
+	} else {
+		pkt->data[0] = info->timestamp / NSEC_PER_SEC;
+		pkt->data[1] = info->timestamp % NSEC_PER_SEC;
+	}
+	pkt->data[2] = info->size;
+}
+
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+
+	ret = vpu_find_dst_by_src(malone_cmds, ARRAY_SIZE(malone_cmds), id);
+	if (ret < 0)
+		return ret;
+
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+
+	switch (id) {
+	case VPU_CMD_ID_FS_ALLOC:
+		vpu_malone_pack_fs_alloc(pkt, data);
+		break;
+	case VPU_CMD_ID_FS_RELEASE:
+		vpu_malone_pack_fs_release(pkt, data);
+		break;
+	case VPU_CMD_ID_TIMESTAMP:
+		vpu_malone_pack_timestamp(pkt, data);
+		break;
+	}
+
+	pkt->hdr.index = index;
+	return 0;
+}
+
+int vpu_malone_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(malone_msgs, ARRAY_SIZE(malone_msgs), id);
+}
+
+static void vpu_malone_fill_planes(struct vpu_dec_codec_info *info)
+{
+	u32 interlaced = info->progressive ? 0 : 1;
+
+	info->bytesperline[0] = 0;
+	info->sizeimage[0] = vpu_helper_get_plane_size(info->pixfmt,
+						       info->decoded_width,
+						       info->decoded_height,
+						       0,
+						       info->stride,
+						       interlaced,
+						       &info->bytesperline[0]);
+	info->bytesperline[1] = 0;
+	info->sizeimage[1] = vpu_helper_get_plane_size(info->pixfmt,
+						       info->decoded_width,
+						       info->decoded_height,
+						       1,
+						       info->stride,
+						       interlaced,
+						       &info->bytesperline[1]);
+}
+
+static void vpu_malone_init_seq_hdr(struct vpu_dec_codec_info *info)
+{
+	u32 chunks = info->num_dfe_area >> MALONE_DCP_CHUNK_BIT;
+
+	vpu_malone_fill_planes(info);
+
+	info->mbi_size = (info->sizeimage[0] + info->sizeimage[1]) >> 2;
+	info->mbi_size = ALIGN(info->mbi_size, MALONE_ALIGN_MBI);
+
+	info->dcp_size = MALONE_DCP_SIZE_MAX;
+	if (chunks) {
+		u32 mb_num;
+		u32 mb_w;
+		u32 mb_h;
+
+		mb_w = DIV_ROUND_UP(info->decoded_width, 16);
+		mb_h = DIV_ROUND_UP(info->decoded_height, 16);
+		mb_num = mb_w * mb_h;
+		info->dcp_size = mb_num * MALONE_DCP_FIXED_MB_ALLOC * chunks;
+		info->dcp_size = clamp_t(u32, info->dcp_size,
+					 MALONE_DCP_SIZE_MIN, MALONE_DCP_SIZE_MAX);
+	}
+}
+
+static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt,
+				      struct vpu_dec_codec_info *info)
+{
+	info->num_ref_frms = pkt->data[0];
+	info->num_dpb_frms = pkt->data[1];
+	info->num_dfe_area = pkt->data[2];
+	info->progressive = pkt->data[3];
+	info->width = pkt->data[5];
+	info->height = pkt->data[4];
+	info->decoded_width = pkt->data[12];
+	info->decoded_height = pkt->data[11];
+	info->frame_rate.numerator = 1000;
+	info->frame_rate.denominator = pkt->data[8];
+	info->dsp_asp_ratio = pkt->data[9];
+	info->level_idc = pkt->data[10];
+	info->bit_depth_luma = pkt->data[13];
+	info->bit_depth_chroma = pkt->data[14];
+	info->chroma_fmt = pkt->data[15];
+	info->color_primaries = vpu_color_cvrt_primaries_i2v(pkt->data[16]);
+	info->transfer_chars = vpu_color_cvrt_transfers_i2v(pkt->data[17]);
+	info->matrix_coeffs = vpu_color_cvrt_matrix_i2v(pkt->data[18]);
+	info->full_range = vpu_color_cvrt_full_range_i2v(pkt->data[19]);
+	info->vui_present = pkt->data[20];
+	info->mvc_num_views = pkt->data[21];
+	info->offset_x = pkt->data[23];
+	info->offset_y = pkt->data[25];
+	info->tag = pkt->data[27];
+	if (info->bit_depth_luma > 8)
+		info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128;
+	else
+		info->pixfmt = V4L2_PIX_FMT_NV12M_8L128;
+	if (info->frame_rate.numerator && info->frame_rate.denominator) {
+		unsigned long n, d;
+
+		rational_best_approximation(info->frame_rate.numerator,
+					    info->frame_rate.denominator,
+					    info->frame_rate.numerator,
+					    info->frame_rate.denominator,
+					    &n, &d);
+		info->frame_rate.numerator = n;
+		info->frame_rate.denominator = d;
+	}
+	vpu_malone_init_seq_hdr(info);
+}
+
+static void vpu_malone_unpack_pic_info(struct vpu_rpc_event *pkt,
+				       struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[7];
+	info->luma = pkt->data[0];
+	info->start = pkt->data[10];
+	info->end = pkt->data[12];
+	info->pic_size = pkt->data[11];
+	info->stride = pkt->data[5];
+	info->consumed_count = pkt->data[13];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+}
+
+static void vpu_malone_unpack_req_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->type = pkt->data[1];
+}
+
+static void vpu_malone_unpack_rel_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->id = pkt->data[0];
+	info->type = pkt->data[1];
+	info->not_displayed = pkt->data[2];
+}
+
+static void vpu_malone_unpack_buff_rdy(struct vpu_rpc_event *pkt,
+				       struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[0];
+	info->luma = pkt->data[1];
+	info->stride = pkt->data[3];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+	info->timestamp = MAKE_TIMESTAMP(pkt->data[9], pkt->data[10]);
+}
+
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_EVENT_SEQ_HDR_FOUND:
+		vpu_malone_unpack_seq_hdr(pkt, data);
+		break;
+	case VID_API_EVENT_PIC_DECODED:
+		vpu_malone_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_EVENT_REQ_FRAME_BUFF:
+		vpu_malone_unpack_req_frame(pkt, data);
+		break;
+	case VID_API_EVENT_REL_FRAME_BUFF:
+		vpu_malone_unpack_rel_frame(pkt, data);
+		break;
+	case VID_API_EVENT_FRAME_BUFF_RDY:
+		vpu_malone_unpack_buff_rdy(pkt, data);
+		break;
+	}
+
+	return 0;
+}
+
+static const struct malone_padding_scode padding_scodes[] = {
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG2,       {0xCC010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0xefff0000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG2,       {0xb7010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0x0, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264,        {0x15010000, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC,    {0x15010000, 0x0}},
+};
+
+static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0};
+
+static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt)
+{
+	const struct malone_padding_scode *s;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(padding_scodes); i++) {
+		s = &padding_scodes[i];
+
+		if (s->scode_type == type && s->pixelformat == fmt)
+			return s;
+	}
+
+	if (type != SCODE_PADDING_BUFFLUSH)
+		return &padding_scode_dft;
+
+	return NULL;
+}
+
+static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer,
+					struct vpu_malone_str_buffer *str_buf,
+					u32 pixelformat, u32 scode_type)
+{
+	u32 wptr;
+	u32 size;
+	u32 total_size = 0;
+	const struct malone_padding_scode *ps;
+	const u32 padding_size = 4096;
+	int ret;
+
+	ps = get_padding_scode(scode_type, pixelformat);
+	if (!ps)
+		return -EINVAL;
+
+	wptr = str_buf->wptr;
+	size = ALIGN(wptr, 4) - wptr;
+	if (size)
+		vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	size = sizeof(ps->data);
+	ret = vpu_helper_copy_to_stream_buffer(stream_buffer, &wptr, size, (void *)ps->data);
+	if (ret < size)
+		return -EINVAL;
+	total_size += size;
+
+	size = padding_size - sizeof(ps->data);
+	vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+	return total_size;
+}
+
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+	int ret = -EINVAL;
+
+	switch (scode_type) {
+	case SCODE_PADDING_EOS:
+	case SCODE_PADDING_ABORT:
+	case SCODE_PADDING_BUFFLUSH:
+		ret = vpu_malone_add_padding_scode(stream_buffer, str_buf, pixelformat, scode_type);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+#define MALONE_PAYLOAD_HEADER_SIZE		16
+#define MALONE_CODEC_VERSION_ID			0x1
+#define MALONE_CODEC_ID_VC1_SIMPLE		0x10
+#define MALONE_CODEC_ID_VC1_MAIN		0x11
+#define MALONE_CODEC_ID_ARV8			0x28
+#define MALONE_CODEC_ID_ARV9			0x29
+#define MALONE_CODEC_ID_VP6			0x36
+#define MALONE_CODEC_ID_VP8			0x36
+#define MALONE_CODEC_ID_DIVX3			0x38
+#define MALONE_CODEC_ID_SPK			0x39
+
+#define MALONE_VP8_IVF_SEQ_HEADER_LEN		32
+#define MALONE_VP8_IVF_FRAME_HEADER_LEN		8
+
+#define MALONE_VC1_RCV_CODEC_V1_VERSION		0x85
+#define MALONE_VC1_RCV_CODEC_V2_VERSION		0xC5
+#define MALONE_VC1_RCV_NUM_FRAMES		0xFF
+#define MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE	4
+#define MALONE_VC1_RCV_SEQ_HEADER_LEN		20
+#define MALONE_VC1_RCV_PIC_HEADER_LEN		4
+#define MALONE_VC1_NAL_HEADER_LEN		4
+#define MALONE_VC1_CONTAIN_NAL(data)		(((data) & 0x00FFFFFF) == 0x00010000)
+
+static void set_payload_hdr(u8 *dst, u32 scd_type, u32 codec_id,
+			    u32 buffer_size, u32 width, u32 height)
+{
+	unsigned int payload_size;
+	/* payload_size = buffer_size + itself_size(16) - start_code(4) */
+	payload_size = buffer_size + 12;
+
+	dst[0] = 0x00;
+	dst[1] = 0x00;
+	dst[2] = 0x01;
+	dst[3] = scd_type;
+
+	/* length */
+	dst[4] = ((payload_size >> 16) & 0xff);
+	dst[5] = ((payload_size >> 8) & 0xff);
+	dst[6] = 0x4e;
+	dst[7] = ((payload_size >> 0) & 0xff);
+
+	/* Codec ID and Version */
+	dst[8] = codec_id;
+	dst[9] = MALONE_CODEC_VERSION_ID;
+
+	/* width */
+	dst[10] = ((width >> 8) & 0xff);
+	dst[11] = ((width >> 0) & 0xff);
+	dst[12] = 0x58;
+
+	/* height */
+	dst[13] = ((height >> 8) & 0xff);
+	dst[14] = ((height >> 0) & 0xff);
+	dst[15] = 0x50;
+}
+
+static void set_vp8_ivf_seqhdr(u8 *dst, u32 width, u32 height)
+{
+	/* 0-3byte signature "DKIF" */
+	dst[0] = 0x44;
+	dst[1] = 0x4b;
+	dst[2] = 0x49;
+	dst[3] = 0x46;
+	/* 4-5byte version: should be 0*/
+	dst[4] = 0x00;
+	dst[5] = 0x00;
+	/* 6-7 length of Header */
+	dst[6] = MALONE_VP8_IVF_SEQ_HEADER_LEN;
+	dst[7] = MALONE_VP8_IVF_SEQ_HEADER_LEN >> 8;
+	/* 8-11 VP8 fourcc */
+	dst[8] = 0x56;
+	dst[9] = 0x50;
+	dst[10] = 0x38;
+	dst[11] = 0x30;
+	/* 12-13 width in pixels */
+	dst[12] = width;
+	dst[13] = width >> 8;
+	/* 14-15 height in pixels */
+	dst[14] = height;
+	dst[15] = height >> 8;
+	/* 16-19 frame rate */
+	dst[16] = 0xe8;
+	dst[17] = 0x03;
+	dst[18] = 0x00;
+	dst[19] = 0x00;
+	/* 20-23 time scale */
+	dst[20] = 0x01;
+	dst[21] = 0x00;
+	dst[22] = 0x00;
+	dst[23] = 0x00;
+	/* 24-27 number frames */
+	dst[24] = 0xdf;
+	dst[25] = 0xf9;
+	dst[26] = 0x09;
+	dst[27] = 0x00;
+	/* 28-31 reserved */
+}
+
+static void set_vp8_ivf_pichdr(u8 *dst, u32 frame_size)
+{
+	/*
+	 * firmware just parse 64-bit timestamp(8 bytes).
+	 * As not transfer timestamp to firmware, use default value(ZERO).
+	 * No need to do anything here
+	 */
+}
+
+static void set_vc1_rcv_seqhdr(u8 *dst, u8 *src, u32 width, u32 height)
+{
+	u32 frames = MALONE_VC1_RCV_NUM_FRAMES;
+	u32 ext_data_size = MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE;
+
+	/* 0-2 Number of frames, used default value 0xFF */
+	dst[0] = frames;
+	dst[1] = frames >> 8;
+	dst[2] = frames >> 16;
+
+	/* 3 RCV version, used V1 */
+	dst[3] = MALONE_VC1_RCV_CODEC_V1_VERSION;
+
+	/* 4-7 extension data size */
+	dst[4] = ext_data_size;
+	dst[5] = ext_data_size >> 8;
+	dst[6] = ext_data_size >> 16;
+	dst[7] = ext_data_size >> 24;
+	/* 8-11 extension data */
+	dst[8] = src[0];
+	dst[9] = src[1];
+	dst[10] = src[2];
+	dst[11] = src[3];
+
+	/* height */
+	dst[12] = height;
+	dst[13] = (height >> 8) & 0xff;
+	dst[14] = (height >> 16) & 0xff;
+	dst[15] = (height >> 24) & 0xff;
+	/* width */
+	dst[16] = width;
+	dst[17] = (width >> 8) & 0xff;
+	dst[18] = (width >> 16) & 0xff;
+	dst[19] = (width >> 24) & 0xff;
+}
+
+static void set_vc1_rcv_pichdr(u8 *dst, u32 buffer_size)
+{
+	dst[0] = buffer_size;
+	dst[1] = buffer_size >> 8;
+	dst[2] = buffer_size >> 16;
+	dst[3] = buffer_size >> 24;
+}
+
+static void create_vc1_nal_pichdr(u8 *dst)
+{
+	/* need insert nal header: special ID */
+	dst[0] = 0x0;
+	dst[1] = 0x0;
+	dst[2] = 0x01;
+	dst[3] = 0x0D;
+}
+
+static int vpu_malone_insert_scode_seq(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+	int ret;
+
+	set_payload_hdr(hdr,
+			SCODE_SEQUENCE,
+			codec_id,
+			ext_size,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(hdr),
+					       hdr);
+	return ret;
+}
+
+static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+
+	set_payload_hdr(hdr,
+			SCODE_PICTURE,
+			codec_id,
+			ext_size + vb2_get_plane_payload(scode->vb, 0),
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN];
+	u32 *data = NULL;
+
+	vbuf = to_vb2_v4l2_buffer(scode->vb);
+	data = vb2_plane_vaddr(scode->vb, 0);
+
+	if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
+		return 0;
+	if (MALONE_VC1_CONTAIN_NAL(*data))
+		return 0;
+
+	create_vc1_nal_pichdr(nal_hdr);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(nal_hdr),
+						nal_hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+
+	scode->need_data = 0;
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_seqhdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_seqhdr(rcv_seqhdr,
+			   vb2_plane_vaddr(scode->vb, 0),
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(rcv_seqhdr),
+					       rcv_seqhdr);
+
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vc1_l_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_pichdr[MALONE_VC1_RCV_PIC_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_pichdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_pichdr(rcv_pichdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(rcv_pichdr),
+					       rcv_pichdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_SEQ_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_seqhdr(ivf_hdr,
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(ivf_hdr),
+					       ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_FRAME_HEADER_LEN] = {0};
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_pichdr(ivf_hdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(ivf_hdr),
+					       ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static const struct malone_scode_handler scode_handlers[] = {
+	{
+		/* fix me, need to swap return operation after gstreamer swap */
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.insert_scode_seq = vpu_malone_insert_scode_vc1_l_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_l_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VP8,
+		.insert_scode_seq = vpu_malone_insert_scode_vp8_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vp8_pic,
+	},
+};
+
+static const struct malone_scode_handler *get_scode_handler(u32 pixelformat)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(scode_handlers); i++) {
+		if (scode_handlers[i].pixelformat == pixelformat)
+			return &scode_handlers[i];
+	}
+
+	return NULL;
+}
+
+static int vpu_malone_insert_scode(struct malone_scode_t *scode, u32 type)
+{
+	const struct malone_scode_handler *handler;
+	int ret = 0;
+
+	if (!scode || !scode->inst || !scode->vb)
+		return 0;
+
+	scode->need_data = 1;
+	handler = get_scode_handler(scode->inst->out_format.pixfmt);
+	if (!handler)
+		return 0;
+
+	switch (type) {
+	case SCODE_SEQUENCE:
+		if (handler->insert_scode_seq)
+			ret = handler->insert_scode_seq(scode);
+		break;
+	case SCODE_PICTURE:
+		if (handler->insert_scode_pic)
+			ret = handler->insert_scode_pic(scode);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer *str_buf,
+				       struct vpu_inst *inst, struct vb2_buffer *vb,
+				       u32 disp_imm)
+{
+	struct malone_scode_t scode;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	u32 wptr = str_buf->wptr;
+	int size = 0;
+	int ret = 0;
+
+	/*add scode: SCODE_SEQUENCE, SCODE_PICTURE, SCODE_SLICE*/
+	scode.inst = inst;
+	scode.vb = vb;
+	scode.wptr = wptr;
+	scode.need_data = 1;
+	if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
+		ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE);
+
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+	if (!scode.need_data) {
+		vpu_malone_update_wptr(str_buf, wptr);
+		return size;
+	}
+
+	ret = vpu_malone_insert_scode(&scode, SCODE_PICTURE);
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+					       &wptr,
+					       vb2_get_plane_payload(vb, 0),
+					       vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+	size += ret;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) {
+		ret = vpu_malone_add_scode(inst->core->iface,
+					   inst->id,
+					   &inst->stream_buffer,
+					   inst->out_format.pixfmt,
+					   SCODE_PADDING_BUFFLUSH);
+		if (ret < 0)
+			return ret;
+		size += ret;
+	}
+
+	return size;
+}
+
+static int vpu_malone_input_stream_data(struct vpu_malone_str_buffer *str_buf,
+					struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	u32 wptr = str_buf->wptr;
+	int ret = 0;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+					       &wptr,
+					       vb2_get_plane_payload(vb, 0),
+					       vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	return ret;
+}
+
+static int vpu_malone_input_ts(struct vpu_inst *inst, s64  timestamp, u32 size)
+{
+	struct vpu_ts_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.timestamp = timestamp;
+	info.size = size;
+
+	return vpu_session_fill_timestamp(inst, &info);
+}
+
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[inst->id];
+	u32 disp_imm = hc->codec_param[inst->id].disp_imm;
+	u32 size;
+	int ret;
+
+	if (vpu_malone_is_non_frame_mode(shared, inst->id))
+		ret = vpu_malone_input_stream_data(str_buf, inst, vb);
+	else
+		ret = vpu_malone_input_frame_data(str_buf, inst, vb, disp_imm);
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	/*
+	 * if buffer only contain codec data, and the timestamp is invalid,
+	 * don't put the invalid timestamp to resync
+	 * merge the data to next frame
+	 */
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if (vpu_vb_is_codecconfig(vbuf) && (s64)vb->timestamp < 0) {
+		inst->extra_size += size;
+		return 0;
+	}
+	if (inst->extra_size) {
+		size += inst->extra_size;
+		inst->extra_size = 0;
+	}
+
+	ret = vpu_malone_input_ts(inst, vb->timestamp, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static bool vpu_malone_check_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+	u32 size = desc->end - desc->start;
+	u32 rptr = desc->rptr;
+	u32 wptr = desc->wptr;
+	u32 used = (wptr + size - rptr) % size;
+
+	if (!size || used < size / 2)
+		return true;
+
+	return false;
+}
+
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	u32 cnt = 0;
+
+	while (!vpu_malone_check_ready(shared, instance)) {
+		if (cnt > 30)
+			return false;
+		mdelay(1);
+		cnt++;
+	}
+	return true;
+}
+
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	if (!vpu_malone_is_ready(shared, instance))
+		return -EINVAL;
+
+	return 0;
+}
+
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+
+	desc->wptr++;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+
+	desc->wptr = desc->rptr;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/amphion/vpu_malone.h b/drivers/media/platform/amphion/vpu_malone.h
new file mode 100644
index 000000000000..e5a5cbe9843e
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_malone.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MALONE_H
+#define _AMPHION_VPU_MALONE_H
+
+u32 vpu_malone_get_data_size(void);
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log);
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 core_id);
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared);
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, struct vpu_buffer *buf);
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc);
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write);
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params, u32 update);
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_malone_convert_msg_id(u32 msg_id);
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type);
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb);
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance);
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:27 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:27 +0800
Subject: [PATCH v15 11/13] ARM64: dts: freescale: imx8q: add imx vpu codec
 entries
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <2fe32dd3aa85e1cb8e913939e71c673671524d7d.1643077283.git.ming.qian@nxp.com>

Add the Video Processing Unit node for IMX8Q SoC.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi | 72 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 17 +++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    | 24 +++++++
 3 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
new file mode 100644
index 000000000000..f2dde6d14ca3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *	Dong Aisheng <aisheng.dong at nxp.com>
+ */
+
+vpu: vpu at 2c000000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x2c000000 0x0 0x2c000000 0x2000000>;
+	reg = <0 0x2c000000 0 0x1000000>;
+	power-domains = <&pd IMX_SC_R_VPU>;
+	status = "disabled";
+
+	mu_m0: mailbox at 2d000000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d000000 0x20000>;
+		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+		status = "okay";
+	};
+
+	mu1_m0: mailbox at 2d020000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d020000 0x20000>;
+		interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+		status = "okay";
+	};
+
+	mu2_m0: mailbox at 2d040000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d040000 0x20000>;
+		interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+		status = "disabled";
+	};
+
+	vpu_core0: vpu_core at 2d080000 {
+		reg = <0x2d080000 0x10000>;
+		compatible = "nxp,imx8q-vpu-decoder";
+		power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu_m0 0 0>,
+			<&mu_m0 0 1>,
+			<&mu_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core1: vpu_core at 2d090000 {
+		reg = <0x2d090000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu1_m0 0 0>,
+			<&mu1_m0 0 1>,
+			<&mu1_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core2: vpu_core at 2d0a0000 {
+		reg = <0x2d0a0000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu2_m0 0 0>,
+			<&mu2_m0 0 1>,
+			<&mu2_m0 1 0>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 863232a47004..05495b60beb8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -196,6 +196,23 @@ &usdhc2 {
 	status = "okay";
 };
 
+&vpu {
+	compatible = "nxp,imx8qxp-vpu";
+	status = "okay";
+};
+
+&vpu_core0 {
+	reg = <0x2d040000 0x10000>;
+	memory-region = <&decoder_boot>, <&decoder_rpc>;
+	status = "okay";
+};
+
+&vpu_core1 {
+	reg = <0x2d050000 0x10000>;
+	memory-region = <&encoder_boot>, <&encoder_rpc>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index dbec7c106e0b..a041b85d612b 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -46,6 +46,9 @@ aliases {
 		serial1 = &lpuart1;
 		serial2 = &lpuart2;
 		serial3 = &lpuart3;
+		vpu_core0 = &vpu_core0;
+		vpu_core1 = &vpu_core1;
+		vpu_core2 = &vpu_core2;
 	};
 
 	cpus {
@@ -162,10 +165,30 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
+		decoder_boot: decoder-boot at 84000000 {
+			reg = <0 0x84000000 0 0x2000000>;
+			no-map;
+		};
+
+		encoder_boot: encoder-boot at 86000000 {
+			reg = <0 0x86000000 0 0x200000>;
+			no-map;
+		};
+
+		decoder_rpc: decoder-rpc at 0x92000000 {
+			reg = <0 0x92000000 0 0x100000>;
+			no-map;
+		};
+
 		dsp_reserved: dsp at 92400000 {
 			reg = <0 0x92400000 0 0x2000000>;
 			no-map;
 		};
+
+		encoder_rpc: encoder-rpc at 0x94400000 {
+			reg = <0 0x94400000 0 0x700000>;
+			no-map;
+		};
 	};
 
 	pmu {
@@ -287,6 +310,7 @@ map0 {
 
 	/* sorted in register address */
 	#include "imx8-ss-img.dtsi"
+	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:28 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:28 +0800
Subject: [PATCH v15 12/13] firmware: imx: scu-pd: imx8q: add vpu mu resources
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <8717d91000002047c7d0925f5eae66fc7f795e27.1643077283.git.ming.qian@nxp.com>

the vpu core depends on the mu resources.
if they're missed, the vpu can't work.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/firmware/imx/scu-pd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index ff6569c4a53b..af3d057e6421 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
 	{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
 	{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
 	{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
+	{ "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
+	{ "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
+	{ "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
+	{ "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
 
 	/* GPU SS */
 	{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:29 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:29 +0800
Subject: [PATCH v15 13/13] MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <2f695f6a597a4372842d75105b654fba6db27d59.1643077283.git.ming.qian@nxp.com>

Add AMPHION VPU CODEC v4l2 driver entry

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..69478da4f64a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13913,6 +13913,15 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
 F:	drivers/media/platform/imx-jpeg
 
+AMPHION VPU CODEC V4L2 DRIVER
+M:	Ming Qian <ming.qian at nxp.com>
+M:	Shijie Qin <shijie.qin at nxp.com>
+M:	Zhou Peng <eagle.zhou at nxp.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/amphion,vpu.yaml
+F:	drivers/media/platform/amphion/
+
 NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
 M:	Jonas Malaco <jonas at protocubo.io>
 L:	linux-hwmon at vger.kernel.org
-- 
2.33.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:06 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:06 +0900
Subject: [PATCH 0/8] Add hardware prefetch control driver for arm64 and x86
Message-ID: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>

This patch series add sysfs interface to control CPU's hardware
prefetch behavior for performance tuning from userspace for arm64 and
x86 (on supported CPU).

[Background]
============
A64FX and some Intel processors have implementation-dependent register
for controlling CPU's hardware prefetch behavior. A64FX has
IMP_PF_STREAM_DETECT_CTRL_EL0[1], and Intel processors have MSR 0x1a4
(MSR_MISC_FEATURE_CONTROL)[2]. These registers cannot be accessed from
userspace.

[1]https://github.com/fujitsu/A64FX/tree/master/doc/
   A64FX_Specification_HPC_Extension_v1_EN.pdf

[2]https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
    Volume 4

The advantage of using this is improved performance. As an example of
performance improvements, the results of running the Stream benchmark
on the A64FX are described in section [Merit].

For MSR 0x1a4, it is also possible to change the value from userspace
via the MSR driver. However, using MSR driver is not recommended, so
it needs a proper kernel interface[3].

[3]https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/about/

For these reasons, we provide a new proper kernel interface to control
both IMP_PF_STREAM_DETECT_CTRL_EL0 and MSR 0x1a4.

[Overall design]
================
The following changes have been made based on feedback received in
earlier RFC PATCH[4].

[4]https://lore.kernel.org/lkml/20211104052122.553868-1-tarumizu.kohei at fujitsu.com/

- create attribute file under
  /sys/devices/system/cpu/cpu*/cache/index[0,2]
- provide a one-to-one option to control all the tunable parameters
  the CPU provides.
- use x86_match_cpu() to identify the kind of model

The source code for this driver is divided into common parts
(driver/base/pfctl.c) and architecture parts (arch/XXX/XXX/pfctl.c).
Common parts is described architecture-independent processing, such as
creating sysfs.
Architecture parts is described architecture-dependent processing. It
must contain at least the what type of hardware prefetcher is supported
and how to read/write to the register. These information are set
through registration function in common parts.

This driver creates an attribute file named "prefetch_control?in
every CPU's cache/index[0,2] directory, if CPU supports hardware
prefetch control behavior. Each attribute file corresponds to the
cache level of the parent index directory. The attribute file can be
used to modify one or more options by writing a string.

Detailed description of this sysfs interface is in
Documentation/ABI/testing/sysfs-devices-system-cpu (patch8).

This driver needs cache sysfs directory and cache level/type
information. In ARM processor, these information can be obtained
from registers even without ACPI PPTT.
We add processing to create a cache/index directory using only the
information from the register if the machine does not support ACPI
PPTT and Kconfig for hardware prefetch control (CONFIG_HWPF_CONTROL)
is true in patch5.
This action caused a problem and is described in [Known problem].

[Examples]
==========
As an example of dealing with multiple options, the x86's model of
INTEL_FAM6_BROADWELL_X defines the register specifications as follows:

[0]    L2 Hardware Prefetcher Disable (R/W)
[1]    L2 Adjacent Cache Line Prefetcher Disable (R/W)
[2]    DCU Hardware Prefetcher Disable (R/W)
[3]    DCU IP Prefetcher Disable (R/W)
[63:4] Reserved

In this case, index0 (L1d cache) corresponds to bit[2,3] and index2
(L2 cache) corresponds to bit [0,1]. If you would like to disable the
setting of "L2 Adjacent Cache Line Prefetcher Disable (R/W)" in CPU1,
do the following:

```
# echo "adjacent_cache_line_prefetcher_enable=disable" > /sys/devices/system/cpu/cpu1/cache/index2/prefetch_control
```

When this attribute file is read, the current settings of the available
parameters are output as follows:

```
# cat /sys/devices/system/cpu/cpu1/cache/index2/prefetch_control

hardware_prefetcher_enable=enable
adjacent_cache_line_prefetcher_enable=disable
```

In the case of index0 at BROADWELL_X:

```
# cat /sys/devices/system/cpu/cpu1/cache/index0/prefetch_control

hardware_prefetcher_enable=enable
ip_prefetcher_enable=enable
```

In the case of index0 at A64FX:

```
# cat /sys/devices/system/cpu/cpu1/cache/index0/prefetch_control

stream_detect_prefetcher_enable=enable
stream_detect_prefetcher_dist=auto
stream_detect_prefetcher_strong=strong
```

[Patch organizations]
=====================
This patch series add hardware prefetch control core driver for ARM64
and x86. Also, we add support for FUJITSU_CPU_PART_A64FX at ARM64 and
BROADWELL_X at x86.

- patch1: Add hardware prefetch core driver

  This driver provides a register/unregister function to create the
  sysfs interface with attribute "prefetch_control".
  If the architecture has control of the CPU's hardware prefetch
  behavior, use this function to create sysfs. When registering, it
  is necessary to provide what type of Hardware Prefetcher is
  supported and how to read/write to the register.

- patch2: Add Kconfig/Makefile to build hardware prefetch control core driver

- patch3: Add support for ARM64

  This adds module init/exit code, and creates sysfs attribute file
  "prefetch_control" for ARM64. This driver works only if part number is
  FUJITSU_CPU_PART_A64FX at this point.

- patch4: Add Kconfig/Makefile to build driver for arm64

- patch5: Create cache sysfs directory without ACPI PPTT for hardware prefetch control

  Hardware Prefetch control driver needs cache sysfs directory and cache
  level/type information. In ARM processor, these information can be
  obtained from registers even without PPTT. Therefore, we set the
  cpu_map_populated to true to create cache sysfs directory, if the
  machine doesn't have PPTT.

- patch6: Add support for x86

  This adds module init/exit code, and creates sysfs attribute file
  "prefetch_control" for x86. This driver works only if the model is
  INTEL_FAM6_BROADWELL_X at this point.

- patch7: Add Kconfig/Makefile to build driver for x86

- patch8: Add documentation for the new sysfs interface


[Known problem]
===============
- `lscpu` command terminates with -ENOENT because cache/index directory
  is exists but shared_cpu_map file does not exist. This is due to
  patch5, which creates a cache/index directory containing only level
  and type without ACPI PPTT.

[Merit]
=======
For reference, here is the result of STREAM Triad when tuning with
the "s file in L1 and L2 cache on A64FX.

| dist combination  | Pattern A   | Pattern B   |
|-------------------|-------------|-------------|
| L1:256,  L2:1024  | 234505.2144 | 114600.0801 |
| L1:1536, L2:1024  | 279172.8742 | 118979.4542 |
| L1:256,  L2:10240 | 247716.7757 | 127364.1533 |
| L1:1536, L2:10240 | 283675.6625 | 125950.6847 |

In pattern A, we set the size of the array to 174720, which is about
half the size of the L1d cache. In pattern B, we set the size of the
array to 10485120, which is about twice the size of the L2 cache.

In pattern A, a change of dist at L1 has a larger effect. On the other
hand, in pattern B, the change of dist at L2 has a larger effect.
As described above, the optimal dist combination depends on the
characteristics of the application. Therefore, such a sysfs interface
is useful for performance tuning.

Best regards,
Kohei Tarumizu

Kohei Tarumizu (8):
  drivers: base: Add hardware prefetch control core driver
  drivers: base: Add Kconfig/Makefile to build hardware prefetch control
    core driver
  arm64: Add hardware prefetch control support for ARM64
  arm64: Add Kconfig/Makefile to build hardware prefetch control driver
  arm64: Create cache sysfs directory without ACPI PPTT for hardware
    prefetch control
  x86: Add hardware prefetch control support for x86
  x86: Add Kconfig/Makefile to build hardware prefetch control driver
  docs: ABI: Add sysfs documentation interface of hardware prefetch
    control driver

 .../ABI/testing/sysfs-devices-system-cpu      |  93 +++
 MAINTAINERS                                   |   8 +
 arch/arm64/Kconfig                            |   8 +
 arch/arm64/kernel/Makefile                    |   1 +
 arch/arm64/kernel/cacheinfo.c                 |  29 +
 arch/arm64/kernel/pfctl.c                     | 324 +++++++++++
 arch/x86/Kconfig                              |   7 +
 arch/x86/kernel/cpu/Makefile                  |   2 +
 arch/x86/kernel/cpu/pfctl.c                   | 292 ++++++++++
 drivers/base/Kconfig                          |  13 +
 drivers/base/Makefile                         |   1 +
 drivers/base/pfctl.c                          | 541 ++++++++++++++++++
 include/linux/pfctl.h                         |  42 ++
 13 files changed, 1361 insertions(+)
 create mode 100644 arch/arm64/kernel/pfctl.c
 create mode 100644 arch/x86/kernel/cpu/pfctl.c
 create mode 100644 drivers/base/pfctl.c
 create mode 100644 include/linux/pfctl.h

-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:07 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:07 +0900
Subject: [PATCH 1/8] drivers: base: Add hardware prefetch control core driver
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-2-tarumizu.kohei@fujitsu.com>

This driver provides a register/unregister function to create the
sysfs interface with an attribute file named "prefetch_control" in
every CPU's cache/index[0,2] directory.

If the architecture has control of the CPU's hardware prefetcher
behavior, use this function to create sysfs. When registering, it is
necessary to provide what type of hardware prefetcher is supported
and how to read/write to the register.

Following patches add support for ARM64 and x86.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 drivers/base/pfctl.c  | 541 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pfctl.h |  42 ++++
 2 files changed, 583 insertions(+)
 create mode 100644 drivers/base/pfctl.c
 create mode 100644 include/linux/pfctl.h

diff --git a/drivers/base/pfctl.c b/drivers/base/pfctl.c
new file mode 100644
index 000000000000..4bc3c2826d69
--- /dev/null
+++ b/drivers/base/pfctl.c
@@ -0,0 +1,541 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 FUJITSU LIMITED
+ *
+ * This driver provides tunable sysfs interface for Hardware Prefetch Control.
+ * See Documentation/ABI/testing/sysfs-devices-system-cpu for more information.
+ *
+ * This code provides architecture-independent functions such as create and
+ * remove attribute file.
+ * The implementation of reads and writes to the Hardware Prefetch Control
+ * register is architecture-dependent. Therefore, each architecture register
+ * a callback to read and write the register via pfctl_register_driver().
+ */
+
+#include <linux/cacheinfo.h>
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/pfctl.h>
+#include <linux/parser.h>
+#include <linux/slab.h>
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+enum {
+	OPT_HWPF_ENABLE,
+	OPT_IPPF_ENABLE,
+	OPT_ACLPF_ENABLE,
+	OPT_SDPF_ENABLE,
+	OPT_SDPF_DIST,
+	OPT_SDPF_DIST_AUTO,
+	OPT_SDPF_STRONG,
+	OPT_ERR,
+};
+
+static const char hwpf_enable_fmt[]	= "hardware_prefetcher_enable=%s";
+static const char ippf_enable_fmt[]	= "ip_prefetcher_enable=%s";
+static const char aclpf_enable_fmt[]	=
+	"adjacent_cache_line_prefetcher_enable=%s";
+static const char sdpf_enable_fmt[]	= "stream_detect_prefetcher_enable=%s";
+static const char sdpf_dist_fmt[]	= "stream_detect_prefetcher_dist=%d";
+static const char sdpf_dist_auto_fmt[]	= "stream_detect_prefetcher_dist=%s";
+static const char sdpf_strong_fmt[]	= "stream_detect_prefetcher_strong=%s";
+
+static const match_table_t pfctl_opt_tokens = {
+	{OPT_HWPF_ENABLE,	hwpf_enable_fmt},
+	{OPT_IPPF_ENABLE,	ippf_enable_fmt},
+	{OPT_ACLPF_ENABLE,	aclpf_enable_fmt},
+	{OPT_SDPF_ENABLE,	sdpf_enable_fmt},
+	{OPT_SDPF_DIST,		sdpf_dist_fmt},
+	{OPT_SDPF_DIST_AUTO,	sdpf_dist_auto_fmt},
+	{OPT_SDPF_STRONG,	sdpf_strong_fmt},
+	{OPT_ERR,		NULL},
+};
+
+static DEFINE_PER_CPU(struct device *, cache_device_pcpu);
+#define per_cpu_cache_device(cpu) (per_cpu(cache_device_pcpu, cpu))
+
+struct pfctl_driver *pdriver;
+enum cpuhp_state hp_online;
+
+static bool prefetcher_is_available(unsigned int level, enum cache_type type,
+				    int prefetcher)
+{
+	if ((level == 1) && (type == CACHE_TYPE_DATA))
+		if (pdriver->supported_l1d_prefetcher & prefetcher)
+			return true;
+		else
+			return false;
+	else if ((level == 2) &&
+		 (type == CACHE_TYPE_UNIFIED))
+		if (pdriver->supported_l2_prefetcher & prefetcher)
+			return true;
+		else
+			return false;
+	else
+		return false;
+}
+
+static int parse_prefetch_options(struct prefetcher_options *opts,
+				  const char *buf, unsigned int level,
+				  enum cache_type type)
+{
+	char *options, *sep_opt, *p;
+	substring_t args[MAX_OPT_ARGS];
+	int opt_mask = 0;
+	int token;
+	int ret = 0;
+
+	options = kstrdup(buf, GFP_KERNEL);
+	if (!options)
+		return -ENOMEM;
+
+	sep_opt = strstrip(options);
+	while ((p = strsep(&sep_opt, " ")) != NULL) {
+		unsigned int val;
+
+		if (!*p)
+			continue;
+
+		token = match_token(p, pfctl_opt_tokens, args);
+		opt_mask |= token;
+
+		switch (token) {
+		case OPT_HWPF_ENABLE:
+			if (!prefetcher_is_available(level, type, HWPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "enable")) {
+				opts->hwpf_enable = PFCTL_ENABLE_VAL;
+			} else if (!strcmp(p, "disable")) {
+				opts->hwpf_enable = PFCTL_DISABLE_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		case OPT_IPPF_ENABLE:
+			if (!prefetcher_is_available(level, type, IPPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "enable")) {
+				opts->ippf_enable = PFCTL_ENABLE_VAL;
+			} else if (!strcmp(p, "disable")) {
+				opts->ippf_enable = PFCTL_DISABLE_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		case OPT_ACLPF_ENABLE:
+			if (!prefetcher_is_available(level, type, ACLPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "enable")) {
+				opts->aclpf_enable = PFCTL_ENABLE_VAL;
+			} else if (!strcmp(p, "disable")) {
+				opts->aclpf_enable = PFCTL_DISABLE_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		case OPT_SDPF_ENABLE:
+			if (!prefetcher_is_available(level, type, SDPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "enable")) {
+				opts->sdpf_enable = PFCTL_ENABLE_VAL;
+			} else if (!strcmp(p, "disable")) {
+				opts->sdpf_enable = PFCTL_DISABLE_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		case OPT_SDPF_DIST:
+			if (!prefetcher_is_available(level, type, SDPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+			ret = match_uint(args, &val);
+			if (ret < 0) {
+				pr_err("Invalid value: '%s'\n", p);
+				goto out;
+			}
+
+			opts->sdpf_dist = val;
+			break;
+		case OPT_SDPF_DIST_AUTO:
+			if (!prefetcher_is_available(level, type, SDPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "auto")) {
+				opts->sdpf_dist = PFCTL_DIST_AUTO_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		case OPT_SDPF_STRONG:
+			if (!prefetcher_is_available(level, type, SDPF)) {
+				pr_err("Unsupported parameter: '%s'\n", p);
+				ret = -EINVAL;
+				goto out;
+			}
+			p = match_strdup(args);
+			if (!p) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if (!strcmp(p, "strong")) {
+				opts->sdpf_strong = PFCTL_STRONG_VAL;
+			} else if (!strcmp(p, "weak")) {
+				opts->sdpf_strong = PFCTL_WEAK_VAL;
+			} else {
+				pr_err("Invalid value: '%s'\n", p);
+				ret = -EINVAL;
+				kfree(p);
+				goto out;
+			}
+
+			kfree(p);
+			break;
+		default:
+			pr_err("Unknown parameter or missing value '%s'\n", p);
+			ret = -EINVAL;
+			goto out;
+		}
+	}
+
+out:
+	kfree(options);
+	return ret;
+}
+
+static ssize_t prefetch_control_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	int ret;
+	unsigned int cpu;
+	ssize_t len = 0;
+	struct prefetcher_options opts;
+	struct cacheinfo *this_leaf = dev_get_drvdata(dev);
+
+	cpu = dev->parent->parent->id;
+
+	ret = pdriver->read_pfreg(cpu, this_leaf->level, &opts);
+	if (ret < 0)
+		return ret;
+
+	if (prefetcher_is_available(this_leaf->level, this_leaf->type, HWPF)) {
+		if (opts.hwpf_enable == PFCTL_ENABLE_VAL)
+			len += sysfs_emit_at(buf, len, hwpf_enable_fmt,
+					     "enable");
+		else
+			len += sysfs_emit_at(buf, len, hwpf_enable_fmt,
+					     "disable");
+		len += sysfs_emit_at(buf, len, "\n");
+	}
+
+	if (prefetcher_is_available(this_leaf->level, this_leaf->type, IPPF)) {
+		if (opts.ippf_enable == PFCTL_ENABLE_VAL)
+			len += sysfs_emit_at(buf, len, ippf_enable_fmt,
+					     "enable");
+		else
+			len += sysfs_emit_at(buf, len, ippf_enable_fmt,
+					     "disable");
+		len += sysfs_emit_at(buf, len, "\n");
+	}
+
+	if (prefetcher_is_available(this_leaf->level, this_leaf->type, ACLPF)) {
+		if (opts.aclpf_enable == PFCTL_ENABLE_VAL)
+			len += sysfs_emit_at(buf, len, aclpf_enable_fmt,
+					     "enable");
+		else
+			len += sysfs_emit_at(buf, len, aclpf_enable_fmt,
+					     "disable");
+		len += sysfs_emit_at(buf, len, "\n");
+	}
+
+	if (prefetcher_is_available(this_leaf->level, this_leaf->type, SDPF)) {
+		if (opts.sdpf_enable == PFCTL_ENABLE_VAL)
+			len += sysfs_emit_at(buf, len, sdpf_enable_fmt,
+					     "enable");
+		else
+			len += sysfs_emit_at(buf, len, sdpf_enable_fmt,
+					     "disable");
+		len += sysfs_emit_at(buf, len, "\n");
+
+		if (opts.sdpf_dist == PFCTL_DIST_AUTO_VAL)
+			len += sysfs_emit_at(buf, len, sdpf_dist_auto_fmt,
+					     "auto");
+		else
+			len += sysfs_emit_at(buf, len, sdpf_dist_fmt,
+					     opts.sdpf_dist);
+		len += sysfs_emit_at(buf, len, "\n");
+
+		if (opts.sdpf_strong == PFCTL_STRONG_VAL)
+			len += sysfs_emit_at(buf, len, sdpf_strong_fmt,
+					     "strong");
+		else
+			len += sysfs_emit_at(buf, len, sdpf_strong_fmt,
+					     "weak");
+		len += sysfs_emit_at(buf, len, "\n");
+	}
+
+	return len;
+}
+
+static ssize_t prefetch_control_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	int ret;
+	unsigned int cpu;
+	struct cacheinfo *this_leaf = dev_get_drvdata(dev);
+	struct prefetcher_options opts = {
+		.hwpf_enable	= PFCTL_PARAM_UNSET,
+		.ippf_enable	= PFCTL_PARAM_UNSET,
+		.aclpf_enable	= PFCTL_PARAM_UNSET,
+		.sdpf_enable	= PFCTL_PARAM_UNSET,
+		.sdpf_dist	= PFCTL_PARAM_UNSET,
+		.sdpf_strong	= PFCTL_PARAM_UNSET,
+	};
+
+	cpu = dev->parent->parent->id;
+
+	ret = parse_prefetch_options(&opts, buf, this_leaf->level,
+				     this_leaf->type);
+	if (ret < 0)
+		return ret;
+
+	ret = pdriver->write_pfreg(cpu, this_leaf->level, &opts);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static DEVICE_ATTR_ADMIN_RW(prefetch_control);
+
+static int find_cache_device(unsigned int cpu)
+{
+	struct device *cpu_dev = get_cpu_device(cpu);
+	struct device *cache_dev;
+
+	cache_dev = device_find_child_by_name(cpu_dev, "cache");
+	if (!cache_dev)
+		return -ENODEV;
+	per_cpu_cache_device(cpu) = cache_dev;
+
+	return 0;
+}
+
+static int _create_pfctl_attr(struct device *dev, void *data)
+{
+	int ret;
+	struct cacheinfo *leaf = dev_get_drvdata(dev);
+
+	if (!prefetcher_is_available(leaf->level, leaf->type, ANYPF))
+		return 0;
+
+	ret = sysfs_create_file(&dev->kobj, &dev_attr_prefetch_control.attr);
+	if (ret < 0) {
+		pr_err("sysfs_create_file failed: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int create_pfctl_attr(unsigned int cpu)
+{
+	int ret;
+	struct device *cache_dev = per_cpu_cache_device(cpu);
+
+	if (!cache_dev)
+		return -ENODEV;
+
+	ret = device_for_each_child(cache_dev, NULL, _create_pfctl_attr);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int _remove_pfctl_attr(struct device *dev, void *data)
+{
+	struct cacheinfo *leaf = dev_get_drvdata(dev);
+
+	if (!prefetcher_is_available(leaf->level, leaf->type, ANYPF))
+		return 0;
+
+	sysfs_remove_file(&dev->kobj, &dev_attr_prefetch_control.attr);
+
+	return 0;
+}
+
+static void remove_pfctl_attr(unsigned int cpu)
+{
+	struct device *cache_dev = per_cpu_cache_device(cpu);
+
+	if (!cache_dev)
+		return;
+
+	device_for_each_child(cache_dev, NULL, _remove_pfctl_attr);
+}
+
+static int pfctl_online(unsigned int cpu)
+{
+	int ret;
+
+	ret = find_cache_device(cpu);
+	if (ret < 0)
+		return ret;
+
+	ret = create_pfctl_attr(cpu);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int pfctl_prepare_down(unsigned int cpu)
+{
+	remove_pfctl_attr(cpu);
+
+	return 0;
+}
+
+/**
+ * pfctl_register_driver - register a Hardware Prefetch Control driver
+ * @driver_data: struct pfctl_driver must contain the supported prefetcher type
+ *               and function pointer for reading and writing hardware prefetch
+ *               register. If these are not defined this function return error.
+ *
+ * Note: This function must be called after the cache device is initialized
+ * because it requires access to the cache device.
+ * (e.g. Call at the late_initcall)
+ *
+ * Context: Any context.
+ * Return: 0 on success, negative error code on failure.
+ */
+int pfctl_register_driver(struct pfctl_driver *driver_data)
+{
+	int ret;
+
+	if (pdriver)
+		return -EEXIST;
+
+	if ((driver_data->supported_l1d_prefetcher == 0) &&
+	    (driver_data->supported_l2_prefetcher == 0))
+		return -EINVAL;
+
+	if (!driver_data->read_pfreg || !driver_data->write_pfreg)
+		return -EINVAL;
+
+	pdriver = driver_data;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "base/pfctl:online",
+				pfctl_online, pfctl_prepare_down);
+	if (ret < 0) {
+		pr_err("failed to register hotplug callbacks\n");
+		pdriver = NULL;
+		return ret;
+	}
+
+	hp_online = ret;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pfctl_register_driver);
+
+/**
+ * pfctl_unregister_driver - unregister the Hardware Prefetch Control driver
+ * @driver_data: Used to verify that this function is called by the driver that
+ *               called pfctl_register_driver by determining if driver_data is
+ *               the same.
+ *
+ * Context: Any context.
+ * Return: nothing.
+ */
+void pfctl_unregister_driver(struct pfctl_driver *driver_data)
+{
+	if (!pdriver || (driver_data != pdriver))
+		return;
+
+	cpuhp_remove_state(hp_online);
+
+	pdriver = NULL;
+}
+EXPORT_SYMBOL_GPL(pfctl_unregister_driver);
diff --git a/include/linux/pfctl.h b/include/linux/pfctl.h
new file mode 100644
index 000000000000..7a05e2f4a4f7
--- /dev/null
+++ b/include/linux/pfctl.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_PFCTL_H
+#define _LINUX_PFCTL_H
+
+#define PFCTL_ENABLE_VAL		0
+#define PFCTL_DISABLE_VAL		1
+#define PFCTL_DIST_AUTO_VAL		0
+#define PFCTL_STRONG_VAL		0
+#define PFCTL_WEAK_VAL			1
+#define PFCTL_PARAM_UNSET		-1
+
+struct prefetcher_options {
+	int hwpf_enable;
+	int ippf_enable;
+	int aclpf_enable;
+	int sdpf_enable;
+	int sdpf_dist;
+	int sdpf_strong;
+};
+
+enum prefetcher {
+	HWPF	= BIT(0), /* Hardware Prefetcher */
+	IPPF	= BIT(1), /* IP Prefetcher */
+	ACLPF	= BIT(2), /* Adjacent Cache Line Prefetcher */
+	SDPF	= BIT(3), /* Stream Detect Prefetcher */
+	ANYPF	= HWPF|IPPF|ACLPF|SDPF,
+};
+
+struct pfctl_driver {
+	unsigned int supported_l1d_prefetcher;
+	unsigned int supported_l2_prefetcher;
+
+	int (*read_pfreg)(unsigned int cpu, unsigned int level,
+			  struct prefetcher_options *opt);
+	int (*write_pfreg)(unsigned int cpu, unsigned int level,
+			   struct prefetcher_options *opt);
+};
+
+int pfctl_register_driver(struct pfctl_driver *driver_data);
+void pfctl_unregister_driver(struct pfctl_driver *driver_data);
+
+#endif
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:08 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:08 +0900
Subject: [PATCH 2/8] drivers: base: Add Kconfig/Makefile to build hardware
 prefetch control core driver
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-3-tarumizu.kohei@fujitsu.com>

This adds Kconfig/Makefile to build hardware prefetch control core
driver. This also adds a MAINTAINERS entry.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 MAINTAINERS           |  6 ++++++
 drivers/base/Kconfig  | 13 +++++++++++++
 drivers/base/Makefile |  1 +
 3 files changed, 20 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..b474051c41e7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8444,6 +8444,12 @@ F:	include/linux/hwmon*.h
 F:	include/trace/events/hwmon*.h
 K:	(devm_)?hwmon_device_(un)?register(|_with_groups|_with_info)
 
+HARDWARE PREFETCH CONTROL DRIVERS
+M:	Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
+S:	Maintained
+F:	drivers/base/pfctl.c
+F:	include/linux/pfctl.h
+
 HARDWARE RANDOM NUMBER GENERATOR CORE
 M:	Matt Mackall <mpm at selenic.com>
 M:	Herbert Xu <herbert at gondor.apana.org.au>
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 6f04b831a5c0..d146604b5b3a 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -230,4 +230,17 @@ config GENERIC_ARCH_NUMA
 	  Enable support for generic NUMA implementation. Currently, RISC-V
 	  and ARM64 use it.
 
+config ARCH_HAS_HWPF_CONTROL
+	bool
+
+config HWPF_CONTROL
+	bool "Hardware Prefetch Control driver"
+	depends on ARCH_HAS_HWPF_CONTROL && SYSFS
+	help
+	  This driver allows user to control CPU's Hardware Prefetch behavior.
+	  If the machine supports this behavior, it provides a sysfs interface.
+
+	  See Documentation/ABI/testing/sysfs-devices-system-cpu for more
+	  information.
+
 endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 02f7f1358e86..13f3a0ddf3d1 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
 obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o
 obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o
 obj-$(CONFIG_GENERIC_ARCH_NUMA) += arch_numa.o
+obj-$(CONFIG_HWPF_CONTROL)	+= pfctl.o
 
 obj-y			+= test/
 
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:09 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:09 +0900
Subject: [PATCH 3/8] arm64: Add hardware prefetch control support for ARM64
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-4-tarumizu.kohei@fujitsu.com>

This adds module init/exit code, and creates sysfs attribute files for
"prefetch_control". This driver works only if part number is
FUJITSU_CPU_PART_A64FX at this point. The details of the registers to
be read and written in this patch are described below.

"https://github.com/fujitsu/A64FX/tree/master/doc/"
    A64FX_Specification_HPC_Extension_v1_EN.pdf

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 arch/arm64/kernel/pfctl.c | 324 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 324 insertions(+)
 create mode 100644 arch/arm64/kernel/pfctl.c

diff --git a/arch/arm64/kernel/pfctl.c b/arch/arm64/kernel/pfctl.c
new file mode 100644
index 000000000000..14f4b8248280
--- /dev/null
+++ b/arch/arm64/kernel/pfctl.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 FUJITSU LIMITED
+ *
+ * ARM64 Hardware Prefetch Control support
+ */
+
+#include <asm/cputype.h>
+#include <linux/bitfield.h>
+#include <linux/cacheinfo.h>
+#include <linux/module.h>
+#include <linux/pfctl.h>
+#include <linux/parser.h>
+
+struct pfctl_driver arm64_pfctl_driver;
+
+/**************************************
+ * FUJITSU A64FX support
+ **************************************/
+
+/*
+ * Constants for these add the "A64FX_SDPF" prefix to the name described in
+ * section "1.3.4.2. IMP_PF_STREAM_DETECT_CTRL_EL0" of "A64FX specification".
+ * (https://github.com/fujitsu/A64FX/tree/master/doc/A64FX_Specification_HPC_Extension_v1_EN.pdf")
+ * See this document for register specification details.
+ */
+#define A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0	sys_reg(3, 3, 11, 4, 0)
+#define A64FX_SDPF_V					BIT_ULL(63)
+#define A64FX_SDPF_L1PF_DIS				BIT_ULL(59)
+#define A64FX_SDPF_L2PF_DIS				BIT_ULL(58)
+#define A64FX_SDPF_L1W					BIT_ULL(55)
+#define A64FX_SDPF_L2W					BIT_ULL(54)
+#define A64FX_SDPF_L1_DIST				GENMASK_ULL(27, 24)
+#define A64FX_SDPF_L2_DIST				GENMASK_ULL(19, 16)
+
+#define A64FX_SDPF_MIN_DIST_L1				256
+#define A64FX_SDPF_MIN_DIST_L2				1024
+
+struct a64fx_read_info {
+	struct prefetcher_options *opts;
+	unsigned int level;
+	int ret;
+};
+
+struct a64fx_write_info {
+	struct prefetcher_options *opts;
+	unsigned int level;
+	int ret;
+};
+
+static int a64fx_get_sdpf_enable(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 1:
+		return FIELD_GET(A64FX_SDPF_L1PF_DIS, reg);
+	case 2:
+		return FIELD_GET(A64FX_SDPF_L2PF_DIS, reg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int a64fx_modify_sdpf_enable(u64 *reg, unsigned int level, int val)
+{
+	switch (level) {
+	case 1:
+		*reg &= ~A64FX_SDPF_L1PF_DIS;
+		*reg |= FIELD_PREP(A64FX_SDPF_L1PF_DIS, val);
+		break;
+	case 2:
+		*reg &= ~A64FX_SDPF_L2PF_DIS;
+		*reg |= FIELD_PREP(A64FX_SDPF_L2PF_DIS, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int a64fx_get_sdpf_dist(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 1:
+		return FIELD_GET(A64FX_SDPF_L1_DIST, reg) *
+			A64FX_SDPF_MIN_DIST_L1;
+	case 2:
+		return FIELD_GET(A64FX_SDPF_L2_DIST, reg) *
+			A64FX_SDPF_MIN_DIST_L2;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int a64fx_modify_sdpf_dist(u64 *reg, unsigned int level, int val)
+{
+	switch (level) {
+	case 1:
+		val = roundup(val, A64FX_SDPF_MIN_DIST_L1) /
+			A64FX_SDPF_MIN_DIST_L1;
+		if (!FIELD_FIT(A64FX_SDPF_L1_DIST, val))
+			return -EINVAL;
+		*reg &= ~A64FX_SDPF_L1_DIST;
+		*reg |= FIELD_PREP(A64FX_SDPF_L1_DIST, val);
+		break;
+	case 2:
+		val = roundup(val, A64FX_SDPF_MIN_DIST_L2) /
+			A64FX_SDPF_MIN_DIST_L2;
+		if (!FIELD_FIT(A64FX_SDPF_L2_DIST, val))
+			return -EINVAL;
+		*reg &= ~A64FX_SDPF_L2_DIST;
+		*reg |= FIELD_PREP(A64FX_SDPF_L2_DIST, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int a64fx_get_sdpf_strong(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 1:
+		return FIELD_GET(A64FX_SDPF_L1W, reg);
+	case 2:
+		return FIELD_GET(A64FX_SDPF_L2W, reg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int a64fx_modify_sdpf_strong(u64 *reg, unsigned int level, int val)
+{
+	switch (level) {
+	case 1:
+		*reg &= ~A64FX_SDPF_L1W;
+		*reg |= FIELD_PREP(A64FX_SDPF_L1W, val);
+		break;
+	case 2:
+		*reg &= ~A64FX_SDPF_L2W;
+		*reg |= FIELD_PREP(A64FX_SDPF_L2W, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void a64fx_enable_sdpf_verify(u64 *reg)
+{
+	*reg &= ~A64FX_SDPF_V;
+	*reg |= FIELD_PREP(A64FX_SDPF_V, 1);
+}
+
+static int a64fx_get_sdpf_params(struct prefetcher_options *opts, u64 reg,
+			    unsigned int level)
+{
+	int ret;
+
+	ret = a64fx_get_sdpf_enable(reg, level);
+	if (ret < 0)
+		return ret;
+	opts->sdpf_enable = ret;
+
+	ret = a64fx_get_sdpf_dist(reg, level);
+	if (ret < 0)
+		return ret;
+	opts->sdpf_dist = ret;
+
+	ret = a64fx_get_sdpf_strong(reg, level);
+	if (ret < 0)
+		return ret;
+	opts->sdpf_strong = ret;
+
+	return 0;
+}
+
+static int a64fx_modify_pfreg_val(u64 *reg, struct prefetcher_options *opts,
+			 unsigned int level)
+{
+	int ret;
+
+	if (opts->sdpf_enable != PFCTL_PARAM_UNSET) {
+		ret = a64fx_modify_sdpf_enable(reg, level, opts->sdpf_enable);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (opts->sdpf_dist != PFCTL_PARAM_UNSET) {
+		ret = a64fx_modify_sdpf_dist(reg, level, opts->sdpf_dist);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (opts->sdpf_strong != PFCTL_PARAM_UNSET) {
+		ret = a64fx_modify_sdpf_strong(reg, level, opts->sdpf_strong);
+		if (ret < 0)
+			return ret;
+	}
+
+	a64fx_enable_sdpf_verify(reg);
+
+	return 0;
+}
+
+static void _a64fx_read_pfreg(void *info)
+{
+	u64 reg;
+	struct a64fx_read_info *rinfo = info;
+
+	reg = read_sysreg_s(A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0);
+
+	rinfo->ret = a64fx_get_sdpf_params(rinfo->opts, reg, rinfo->level);
+}
+
+static int a64fx_read_pfreg(unsigned int cpu, unsigned int level,
+		      struct prefetcher_options *opt)
+{
+	struct a64fx_read_info info = {
+		.level = level,
+		.opts = opt,
+	};
+
+	smp_call_function_single(cpu, _a64fx_read_pfreg, &info, true);
+	return info.ret;
+}
+
+static void _a64fx_write_pfreg(void *info)
+{
+	int ret;
+	u64 reg;
+	struct a64fx_write_info *winfo = info;
+
+	reg = read_sysreg_s(A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0);
+
+	ret = a64fx_modify_pfreg_val(&reg, winfo->opts, winfo->level);
+	if (ret < 0) {
+		winfo->ret = ret;
+		return;
+	}
+
+	write_sysreg_s(reg, A64FX_SDPF_IMP_PF_STREAM_DETECT_CTRL_EL0);
+
+	winfo->ret = 0;
+}
+
+static int a64fx_write_pfreg(unsigned int cpu, unsigned int level,
+		       struct prefetcher_options *opt)
+{
+	struct a64fx_write_info info = {
+		.level = level,
+		.opts = opt,
+	};
+
+	smp_call_function_single(cpu, _a64fx_write_pfreg, &info, true);
+	return info.ret;
+}
+
+/***** end of FUJITSU A64FX support *****/
+
+/*
+ * This driver returns a negative value if it does not support the Hardware
+ * Prefetch Control or if it is running on a VM guest.
+ */
+static int __init setup_pfctl_driver_params(void)
+{
+	unsigned long implementor = read_cpuid_implementor();
+	unsigned long part_number = read_cpuid_part_number();
+
+	if (!is_kernel_in_hyp_mode())
+		return -EINVAL;
+
+	switch (implementor) {
+	case ARM_CPU_IMP_FUJITSU:
+		switch (part_number) {
+		case FUJITSU_CPU_PART_A64FX:
+			/* A64FX register requires EL2 access */
+			if (!has_vhe())
+				return -EINVAL;
+
+			arm64_pfctl_driver.supported_l1d_prefetcher = SDPF;
+			arm64_pfctl_driver.supported_l2_prefetcher = SDPF;
+			arm64_pfctl_driver.read_pfreg = a64fx_read_pfreg;
+			arm64_pfctl_driver.write_pfreg = a64fx_write_pfreg;
+			break;
+		default:
+			return -ENODEV;
+		}
+		break;
+	default:
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __init arm64_pfctl_init(void)
+{
+	int ret;
+
+	ret = setup_pfctl_driver_params();
+	if (ret < 0)
+		return ret;
+
+	ret = pfctl_register_driver(&arm64_pfctl_driver);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void __exit arm64_pfctl_exit(void)
+{
+	pfctl_unregister_driver(&arm64_pfctl_driver);
+}
+
+late_initcall(arm64_pfctl_init);
+module_exit(arm64_pfctl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("FUJITSU LIMITED");
+MODULE_DESCRIPTION("ARM64 Prefetch Control Driver");
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:10 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:10 +0900
Subject: [PATCH 4/8] arm64: Add Kconfig/Makefile to build hardware prefetch
 control driver
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-5-tarumizu.kohei@fujitsu.com>

This adds Kconfig/Makefile to build hardware prefetch control driver
for arm64 support. This also adds a MAINTAINERS entry.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 MAINTAINERS                | 1 +
 arch/arm64/Kconfig         | 8 ++++++++
 arch/arm64/kernel/Makefile | 1 +
 3 files changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b474051c41e7..0eaee76438e9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8447,6 +8447,7 @@ K:	(devm_)?hwmon_device_(un)?register(|_with_groups|_with_info)
 HARDWARE PREFETCH CONTROL DRIVERS
 M:	Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
 S:	Maintained
+F:	arch/arm64/kernel/pfctl.c
 F:	drivers/base/pfctl.c
 F:	include/linux/pfctl.h
 
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..c2256dbb0243 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -36,6 +36,7 @@ config ARM64
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_STACKWALK
+	select ARCH_HAS_HWPF_CONTROL
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
 	select ARCH_HAS_SYNC_DMA_FOR_DEVICE
@@ -1941,6 +1942,13 @@ config STACKPROTECTOR_PER_TASK
 	def_bool y
 	depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG
 
+config ARM64_HWPF_CONTROL
+	tristate "ARM64 Hardware Prefetch Control support"
+	depends on HWPF_CONTROL
+	default m
+	help
+	  This adds Hardware Prefetch Control driver support for ARM64.
+
 endmenu
 
 menu "Boot options"
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 88b3e2a21408..d5eb1dc6bfa6 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_ARM64_PTR_AUTH)		+= pointer_auth.o
 obj-$(CONFIG_ARM64_MTE)			+= mte.o
 obj-y					+= vdso-wrap.o
 obj-$(CONFIG_COMPAT_VDSO)		+= vdso32-wrap.o
+obj-$(CONFIG_ARM64_HWPF_CONTROL)	+= pfctl.o
 
 obj-y					+= probes/
 head-y					:= head.o
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:11 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:11 +0900
Subject: [PATCH 5/8] arm64: Create cache sysfs directory without ACPI PPTT for
 hardware prefetch control
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-6-tarumizu.kohei@fujitsu.com>

This patch will create a cache sysfs directory without ACPI PPTT if
the CONFIG_HWPF_CONTROL is true.

Hardware prefetch control driver need cache sysfs directory and cache
level/type information. In ARM processor, these information can be
obtained from the register even without PPTT. Therefore, we set the
cpu_map_populated to true to create cache sysfs directory if the
machine doesn't have PPTT.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 arch/arm64/kernel/cacheinfo.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/kernel/cacheinfo.c b/arch/arm64/kernel/cacheinfo.c
index 587543c6c51c..039ec32d0b3d 100644
--- a/arch/arm64/kernel/cacheinfo.c
+++ b/arch/arm64/kernel/cacheinfo.c
@@ -43,6 +43,21 @@ static void ci_leaf_init(struct cacheinfo *this_leaf,
 	this_leaf->type = type;
 }
 
+#if defined(CONFIG_HWPF_CONTROL)
+static bool acpi_has_pptt(void)
+{
+	struct acpi_table_header *table;
+	acpi_status status;
+
+	status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+	if (ACPI_FAILURE(status))
+		return false;
+
+	acpi_put_table(table);
+	return true;
+}
+#endif
+
 int init_cache_level(unsigned int cpu)
 {
 	unsigned int ctype, level, leaves, fw_level;
@@ -95,5 +110,19 @@ int populate_cache_leaves(unsigned int cpu)
 			ci_leaf_init(this_leaf++, type, level);
 		}
 	}
+
+#if defined(CONFIG_HWPF_CONTROL)
+	/*
+	 * Hardware prefetch functions need cache sysfs directory and cache
+	 * level/type information. In ARM processor, these information can be
+	 * obtained from registers even without PPTT. Therefore, we set the
+	 * cpu_map_populated to true to create cache sysfs directory, if the
+	 * machine doesn't have PPTT.
+	 **/
+	if (!acpi_disabled)
+		if (!acpi_has_pptt())
+			this_cpu_ci->cpu_map_populated = true;
+#endif
+
 	return 0;
 }
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:12 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:12 +0900
Subject: [PATCH 6/8] x86: Add hardware prefetch control support for x86
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-7-tarumizu.kohei@fujitsu.com>

This adds module init/exit code, and creates sysfs attribute file
"prefetch_control" for x86. This driver works only if the model is
INTEL_FAM6_BROADWELL_X at this point.

If you would like to support a new model with the same register
specifications as INTEL_FAM6_BROADWELL_X, it is possible to add the
model settings to array of broadwell_cpu_ids[].

The details of the registers to be read and written in this patch are
described below:

"https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html"
Volume 4

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 arch/x86/kernel/cpu/pfctl.c | 292 ++++++++++++++++++++++++++++++++++++
 1 file changed, 292 insertions(+)
 create mode 100644 arch/x86/kernel/cpu/pfctl.c

diff --git a/arch/x86/kernel/cpu/pfctl.c b/arch/x86/kernel/cpu/pfctl.c
new file mode 100644
index 000000000000..02628f6d2c05
--- /dev/null
+++ b/arch/x86/kernel/cpu/pfctl.c
@@ -0,0 +1,292 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2022 FUJITSU LIMITED
+ *
+ * x86 Hardware Prefetch Control support
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cacheinfo.h>
+#include <linux/pfctl.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+#include <asm/msr.h>
+
+struct pfctl_driver x86_pfctl_driver;
+
+/**************************************
+ * Intle BROADWELL support
+ **************************************/
+
+/*
+ * The register specification for each bits of Intel BROADWELL is as
+ * follow:
+ *
+ * [0]    L2 Hardware Prefetcher Disable (R/W)
+ * [1]    L2 Adjacent Cache Line Prefetcher Disable (R/W)
+ * [2]    DCU Hardware Prefetcher Disable (R/W)
+ * [3]    DCU IP Prefetcher Disable (R/W)
+ * [63:4] Reserved
+ *
+ * See "Intel 64 and IA-32 Architectures Software Developer's Manual"
+ * (https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)
+ * for register specification details.
+ */
+#define BROADWELL_L2_HWPF_FIELD		BIT_ULL(0)
+#define BROADWELL_L2_ACLPF_FIELD	BIT_ULL(1)
+#define BROADWELL_DCU_HWPF_FIELD	BIT_ULL(2)
+#define BROADWELL_DCU_IPPF_FIELD	BIT_ULL(3)
+
+static int broadwell_get_hwpf_enable(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 1:
+		return FIELD_GET(BROADWELL_DCU_HWPF_FIELD, reg);
+	case 2:
+		return FIELD_GET(BROADWELL_L2_HWPF_FIELD, reg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int broadwell_modify_hwpf_enable(u64 *reg, unsigned int level,
+					unsigned int val)
+{
+	switch (level) {
+	case 1:
+		*reg &= ~BROADWELL_DCU_HWPF_FIELD;
+		*reg |= FIELD_PREP(BROADWELL_DCU_HWPF_FIELD, val);
+		break;
+	case 2:
+		*reg &= ~BROADWELL_L2_HWPF_FIELD;
+		*reg |= FIELD_PREP(BROADWELL_L2_HWPF_FIELD, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int broadwell_get_ippf_enable(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 1:
+		return FIELD_GET(BROADWELL_DCU_IPPF_FIELD, reg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int broadwell_modify_ippf_enable(u64 *reg, unsigned int level,
+					unsigned int val)
+{
+	switch (level) {
+	case 1:
+		*reg &= ~BROADWELL_DCU_IPPF_FIELD;
+		*reg |= FIELD_PREP(BROADWELL_DCU_IPPF_FIELD, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int broadwell_get_aclpf_enable(u64 reg, unsigned int level)
+{
+	switch (level) {
+	case 2:
+		return FIELD_GET(BROADWELL_L2_ACLPF_FIELD, reg);
+	default:
+		return -EINVAL;
+	}
+}
+
+static int broadwell_modify_aclpf_enable(u64 *reg, unsigned int level,
+					 unsigned int val)
+{
+	switch (level) {
+	case 2:
+		*reg &= ~BROADWELL_L2_ACLPF_FIELD;
+		*reg |= FIELD_PREP(BROADWELL_L2_ACLPF_FIELD, val);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int _broadwell_get_pfctl_params(struct prefetcher_options *opts, u64 reg,
+				   unsigned int level, int supported_prefetcher)
+{
+	int ret;
+
+	if (supported_prefetcher & HWPF) {
+		ret = broadwell_get_hwpf_enable(reg, level);
+		if (ret < 0)
+			return ret;
+		opts->hwpf_enable = ret;
+	}
+
+	if (supported_prefetcher & IPPF) {
+		ret = broadwell_get_ippf_enable(reg, level);
+		if (ret < 0)
+			return ret;
+		opts->ippf_enable = ret;
+	}
+
+	if (supported_prefetcher & ACLPF) {
+		ret = broadwell_get_aclpf_enable(reg, level);
+		if (ret < 0)
+			return ret;
+		opts->aclpf_enable = ret;
+	}
+
+	return 0;
+}
+
+static int broadwell_get_pfctl_params(struct prefetcher_options *opts, u64 reg,
+				   unsigned int level)
+{
+	int ret, supported_prefetcher;
+
+	if (level == 1)
+		supported_prefetcher =
+			x86_pfctl_driver.supported_l1d_prefetcher;
+	else if (level == 2)
+		supported_prefetcher =
+			x86_pfctl_driver.supported_l2_prefetcher;
+	else
+		return -EINVAL;
+
+	ret = _broadwell_get_pfctl_params(opts, reg, level, supported_prefetcher);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int broadwell_modify_pfreg(u64 *reg, struct prefetcher_options *opts,
+				  unsigned int level)
+{
+	int ret;
+
+	if (opts->hwpf_enable != PFCTL_PARAM_UNSET) {
+		ret = broadwell_modify_hwpf_enable(reg, level,
+						   opts->hwpf_enable);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (opts->ippf_enable != PFCTL_PARAM_UNSET) {
+		ret = broadwell_modify_ippf_enable(reg, level,
+						   opts->ippf_enable);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (opts->aclpf_enable != PFCTL_PARAM_UNSET) {
+		ret = broadwell_modify_aclpf_enable(reg, level,
+						    opts->aclpf_enable);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int broadwell_read_pfreg(unsigned int cpu, unsigned int level,
+				struct prefetcher_options *opts)
+{
+	int ret;
+	u64 reg;
+
+	ret = rdmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, &reg);
+	if (ret)
+		return ret;
+
+	ret = broadwell_get_pfctl_params(opts, reg, level);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int broadwell_write_pfreg(unsigned int cpu, unsigned int level,
+				 struct prefetcher_options *opts)
+{
+	int ret;
+	u64 reg;
+
+	ret = rdmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, &reg);
+	if (ret)
+		return ret;
+
+	ret = broadwell_modify_pfreg(&reg, opts, level);
+	if (ret < 0)
+		return ret;
+
+	ret = wrmsrl_on_cpu(cpu, MSR_MISC_FEATURE_CONTROL, reg);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ * In addition to BROADWELL_X, NEHALEM and others have same register
+ * specifications as those represented by BROADWELL_XXX_FIELD.
+ * If you want to add support for these processor, add the new target model
+ * here.
+ */
+static const struct x86_cpu_id broadwell_cpu_ids[] = {
+	X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X, NULL),
+	{}
+};
+
+/***** end of Intel BROADWELL support *****/
+
+static int __init setup_pfctl_driver_params(void)
+{
+	if (x86_match_cpu(broadwell_cpu_ids)) {
+		x86_pfctl_driver.supported_l1d_prefetcher = HWPF|IPPF;
+		x86_pfctl_driver.supported_l2_prefetcher = HWPF|ACLPF;
+		x86_pfctl_driver.read_pfreg = broadwell_read_pfreg;
+		x86_pfctl_driver.write_pfreg = broadwell_write_pfreg;
+	} else {
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int __init x86_pfctl_init(void)
+{
+	int ret;
+
+	ret = setup_pfctl_driver_params();
+	if (ret < 0)
+		return ret;
+
+	ret = pfctl_register_driver(&x86_pfctl_driver);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static void __exit x86_pfctl_exit(void)
+{
+	pfctl_unregister_driver(&x86_pfctl_driver);
+}
+
+late_initcall(x86_pfctl_init);
+module_exit(x86_pfctl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("FUJITSU LIMITED");
+MODULE_DESCRIPTION("x86 Hardware Prefetch Control Driver");
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:13 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:13 +0900
Subject: [PATCH 7/8] x86: Add Kconfig/Makefile to build hardware prefetch
 control driver
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-8-tarumizu.kohei@fujitsu.com>

This adds Kconfig/Makefile to build hardware prefetch control driver
for x86 support. This also adds a MAINTAINERS entry.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 MAINTAINERS                  | 1 +
 arch/x86/Kconfig             | 7 +++++++
 arch/x86/kernel/cpu/Makefile | 2 ++
 3 files changed, 10 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0eaee76438e9..ea049bddc4e6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8448,6 +8448,7 @@ HARDWARE PREFETCH CONTROL DRIVERS
 M:	Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
 S:	Maintained
 F:	arch/arm64/kernel/pfctl.c
+F:	arch/x86/kernel/pfctl.c
 F:	drivers/base/pfctl.c
 F:	include/linux/pfctl.h
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ebe8fc76949a..069aee252ba3 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -26,6 +26,7 @@ config X86_64
 	depends on 64BIT
 	# Options that are inherently 64-bit kernel only:
 	select ARCH_HAS_GIGANTIC_PAGE
+	select ARCH_HAS_HWPF_CONTROL
 	select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select HAVE_ARCH_SOFT_DIRTY
@@ -1377,6 +1378,12 @@ config X86_CPUID
 	  with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
 	  /dev/cpu/31/cpuid.
 
+config X86_HWPF_CONTROL
+	tristate "x86 Hardware Prefetch Control support"
+	depends on HWPF_CONTROL
+	help
+	  This adds Hardware Prefetch Control driver support for X86.
+
 choice
 	prompt "High Memory Support"
 	default HIGHMEM4G
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile
index 9661e3e802be..aec62a6b37d2 100644
--- a/arch/x86/kernel/cpu/Makefile
+++ b/arch/x86/kernel/cpu/Makefile
@@ -56,6 +56,8 @@ obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o
 obj-$(CONFIG_HYPERVISOR_GUEST)		+= vmware.o hypervisor.o mshyperv.o
 obj-$(CONFIG_ACRN_GUEST)		+= acrn.o
 
+obj-$(CONFIG_X86_HWPF_CONTROL)		+= pfctl.o
+
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
       cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $@ $^
-- 
2.27.0



From tarumizu.kohei at fujitsu.com  Mon Jan 24 23:14:14 2022
From: tarumizu.kohei at fujitsu.com (Kohei Tarumizu)
Date: Tue, 25 Jan 2022 16:14:14 +0900
Subject: [PATCH 8/8] docs: ABI: Add sysfs documentation interface of hardware
 prefetch control driver
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <20220125071414.811344-9-tarumizu.kohei@fujitsu.com>

This describes the sysfs interface implemented on the hardware prefetch
control driver.

Signed-off-by: Kohei Tarumizu <tarumizu.kohei at fujitsu.com>
---
 .../ABI/testing/sysfs-devices-system-cpu      | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index 61f5676a7429..66b4023b2ed1 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -681,3 +681,96 @@ Description:
 		(RO) the list of CPUs that are isolated and don't
 		participate in load balancing. These CPUs are set by
 		boot parameter "isolcpus=".
+
+What:		/sys/devices/system/cpu/cpu*/cache/index[0,2]/prefetch_control
+Date:		January 2022
+Contact:	Linux kernel mailing list <linux-kernel at vger.kernel.org>
+Description:	Parameters for CPU's hardware prefetch control
+
+		This sysfs interface provides Hardware Prefetch control
+		attribute file by using implementation defined registers.
+		This file exists in every CPU's cache/index[0,2] directory.
+		Each attribute file corresponds to the cache level of the
+		parent index directory.
+
+		prefetch_control: (RW) This file allows user to control
+		several options described below. Which options are available
+		depends on the CPU.
+
+		  * hardware_prefetcher_enable:
+		    The enablement status of prefetcher, "enable" or "disable".
+
+		  * ip_prefetcher_enable:
+		    The enablement status of prefetcher, "enable" or "disable".
+
+		  * adjacent_cache_line_prefetcher_enable:
+		    The enablement status of prefetcher, "enable" or "disable".
+
+		  * stream_detect_prefetcher_enable:
+		    The enablement status of prefetcher, "enable" or "disable".
+
+		  * stream_detect_prefetcher_strong:
+		    The strongness status of prefetcher, "strong" or "weak".
+
+		  * stream_detect_prefetcher_dist:
+		    The current prefetcher distance value in bytes or the "auto".
+		    This value is a multiples of a specific value, depending on
+		    the CPU.
+
+		    Write either a value in byte or the string "auto" to this
+		    parameter. If you write a value less than multiples of a
+		    specific value, it is rounded up.
+
+		- Supported processors
+
+		    This sysfs interface is available on several processors, x86
+		    and ARM64. Currently, the following processors are supported:
+
+			- x86 processor
+			    - INTEL_FAM6_BROADWELL_X
+
+			- ARM64 processor
+			    - FUJITSU_CPU_PART_A64FX
+
+		- Attribute mapping
+
+		    Some Intel processors have MSR 0x1a4. This register has several
+		    specifications depending on the model. This interface provides
+		    a one-to-one option to control all the tunable parameters the
+		    CPU provides of the following.
+
+			- "* Hardware Prefetcher Disable (R/W)"
+			    corresponds to the attribute "hardware_prefetcher_enable"
+
+			- "* Adjacent Cache Line Prefetcher Disable (R/W)"
+			    corresponds to the attribute "adjacent_cache_line_prefetcher_enable"
+
+			- "* IP Prefetcher Disable (R/W)"
+			    corresponds to the attribute "ip_prefetcher_enable"
+
+		    The processor A64FX has register IMP_PF_STREAM_DETECT_CTRL_EL0
+		    for Hardware Prefetch Control. This attribute maps each
+		    specification to the following.
+
+			- "L*PF_DIS": enablement of hardware prefetcher
+			    corresponds to the attribute "stream_detect_prefetcher_enable"
+
+			- "L*W": strongness of hardware prefetcher
+			    corresponds to the attribute "stream_detect_prefetcher_strong"
+
+			- "L*_DIST": distance of hardware prefetcher
+			    corresponds to the attribute "stream_detect_prefetcher_dist"
+
+		- Example::
+
+		    # cat /sys/devices/system/cpu/cpu0/cache/index0/prefetch_control
+
+		    > hardware_prefetcher_enable=enable
+		    > ip_prefetcher_enable=enable
+
+		    # echo "hardware_prefetcher_enable=disable" > /sys/devices/system/cpu/cpu0/cache/index0/prefetch_control
+
+		    # cat /sys/devices/system/cpu/cpu0/cache/index2/prefetch_control
+
+		    > hardware_prefetcher_enable=disable
+		    > ip_prefetcher_enable=enable
-- 
2.27.0



From ming.qian at nxp.com  Mon Jan 24 23:11:17 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:17 +0800
Subject: [PATCH v15 01/13] dt-bindings: media: amphion: add amphion video
 codec bindings
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <5dbf63cd1f73be49d45126393a88a1968de7d73e.1643077283.git.ming.qian@nxp.com>

Add devicetree binding documentation for amphion
Video Processing Unit IP presents on NXP i.MX8Q

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/media/amphion,vpu.yaml           | 180 ++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml

diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
new file mode 100644
index 000000000000..a9d80eaeeeb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -0,0 +1,180 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amphion VPU codec IP
+
+maintainers:
+  - Ming Qian <ming.qian at nxp.com>
+  - Shijie Qin <shijie.qin at nxp.com>
+
+description: |-
+  The Amphion MXC video encoder(Windsor) and decoder(Malone) accelerators present
+  on NXP i.MX8Q SoCs.
+
+properties:
+  $nodename:
+    pattern: "^vpu@[0-9a-f]+$"
+
+  compatible:
+    items:
+      - enum:
+          - nxp,imx8qm-vpu
+          - nxp,imx8qxp-vpu
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^mailbox@[0-9a-f]+$":
+    description:
+      Each vpu encoder or decoder correspond a MU, which used for communication
+      between driver and firmware. Implement via mailbox on driver.
+    $ref: ../mailbox/fsl,mu.yaml#
+
+
+  "^vpu_core@[0-9a-f]+$":
+    description:
+      Each core correspond a decoder or encoder, need to configure them
+      separately. NXP i.MX8QM SoC has one decoder and two encoder, i.MX8QXP SoC
+      has one decoder and one encoder.
+    type: object
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - nxp,imx8q-vpu-decoder
+              - nxp,imx8q-vpu-encoder
+
+      reg:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+      mbox-names:
+        items:
+          - const: tx0
+          - const: tx1
+          - const: rx
+
+      mboxes:
+        description:
+          List of phandle of 2 MU channels for tx, 1 MU channel for rx.
+        maxItems: 3
+
+      memory-region:
+        description:
+          Phandle to the reserved memory nodes to be associated with the
+          remoteproc device. The reserved memory nodes should be carveout nodes,
+          and should be defined as per the bindings in
+          Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+        items:
+          - description: region reserved for firmware image sections.
+          - description: region used for RPC shared memory between firmware and
+                         driver.
+
+    required:
+      - compatible
+      - reg
+      - power-domains
+      - mbox-names
+      - mboxes
+      - memory-region
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  # Device node example for i.MX8QM platform:
+  - |
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    vpu: vpu at 2c000000 {
+      compatible = "nxp,imx8qm-vpu";
+      ranges = <0x2c000000 0x2c000000 0x2000000>;
+      reg = <0x2c000000 0x1000000>;
+      #address-cells = <1>;
+      #size-cells = <1>;
+      power-domains = <&pd IMX_SC_R_VPU>;
+
+      mu_m0: mailbox at 2d000000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d000000 0x20000>;
+        interrupts = <0 472 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+      };
+
+      mu1_m0: mailbox at 2d020000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d020000 0x20000>;
+        interrupts = <0 473 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+      };
+
+      mu2_m0: mailbox at 2d040000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d040000 0x20000>;
+        interrupts = <0 474 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+      };
+
+      vpu_core0: vpu_core at 2d080000 {
+        compatible = "nxp,imx8q-vpu-decoder";
+        reg = <0x2d080000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu_m0 0 0>,
+                 <&mu_m0 0 1>,
+                 <&mu_m0 1 0>;
+        memory-region = <&decoder_boot>, <&decoder_rpc>;
+      };
+
+      vpu_core1: vpu_core at 2d090000 {
+        compatible = "nxp,imx8q-vpu-encoder";
+        reg = <0x2d090000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu1_m0 0 0>,
+                 <&mu1_m0 0 1>,
+                 <&mu1_m0 1 0>;
+        memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+      };
+
+      vpu_core2: vpu_core at 2d0a0000 {
+        reg = <0x2d0a0000 0x10000>;
+        compatible = "nxp,imx8q-vpu-encoder";
+        power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu2_m0 0 0>,
+                 <&mu2_m0 0 1>,
+                 <&mu2_m0 1 0>;
+        memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+      };
+    };
+
+...
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:19 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:19 +0800
Subject: [PATCH v15 03/13] media: amphion: add amphion vpu device driver
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <e2c24babbc6b1a73ef6ab464237f08d3d2212ee9.1643077283.git.ming.qian@nxp.com>

The amphion vpu codec ip contains encoder and decoder.
Windsor is the encoder, it supports to encode H.264.
Malone is the decoder, it features a powerful
video processing unit able to decode many formats,
such as H.264, HEVC, and other formats.

This Driver is for this IP that is based on the v4l2 mem2mem framework.

Supported SoCs are: IMX8QXP, IMX8QM

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 arch/arm64/configs/defconfig               |   1 +
 drivers/media/platform/Kconfig             |  19 ++
 drivers/media/platform/Makefile            |   2 +
 drivers/media/platform/amphion/Makefile    |  20 ++
 drivers/media/platform/amphion/vpu.h       | 356 +++++++++++++++++++++
 drivers/media/platform/amphion/vpu_defs.h  | 187 +++++++++++
 drivers/media/platform/amphion/vpu_drv.c   | 260 +++++++++++++++
 drivers/media/platform/amphion/vpu_imx8q.c | 271 ++++++++++++++++
 drivers/media/platform/amphion/vpu_imx8q.h | 115 +++++++
 9 files changed, 1231 insertions(+)
 create mode 100644 drivers/media/platform/amphion/Makefile
 create mode 100644 drivers/media/platform/amphion/vpu.h
 create mode 100644 drivers/media/platform/amphion/vpu_defs.h
 create mode 100644 drivers/media/platform/amphion/vpu_drv.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..5423075730f8 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -662,6 +662,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
+CONFIG_VIDEO_AMPHION_VPU=m
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
 CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 9fbdba0fd1e7..947ae16c73f5 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -216,6 +216,25 @@ config VIDEO_RCAR_ISP
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-isp.
 
+config VIDEO_AMPHION_VPU
+	tristate "Amphion VPU (Video Processing Unit) Codec IP"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on MEDIA_SUPPORT
+	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select V4L2_MEM2MEM_DEV
+	select VIDEOBUF2_DMA_CONTIG
+	select VIDEOBUF2_VMALLOC
+	help
+	  Amphion VPU Codec IP contains two parts: Windsor and Malone.
+	  Windsor is encoder that supports H.264, and Malone is decoder
+	  that supports H.264, HEVC, and other video formats.
+	  This is a V4L2 driver for NXP MXC 8Q video accelerator hardware.
+	  It accelerates encoding and decoding operations on
+	  various NXP SoCs.
+	  To compile this driver as a module choose m here.
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 19bcbced7382..53709df654ee 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -88,3 +88,5 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
+
+obj-$(CONFIG_VIDEO_AMPHION_VPU)		+= amphion/
diff --git a/drivers/media/platform/amphion/Makefile b/drivers/media/platform/amphion/Makefile
new file mode 100644
index 000000000000..80717312835f
--- /dev/null
+++ b/drivers/media/platform/amphion/Makefile
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for NXP VPU driver
+
+amphion-vpu-objs += vpu_drv.o \
+			vpu_core.o \
+			vpu_mbox.o \
+			vpu_v4l2.o \
+			vpu_helpers.o \
+			vpu_cmds.o \
+			vpu_msgs.o \
+			vpu_rpc.o \
+			vpu_imx8q.o \
+			vpu_windsor.o \
+			vpu_malone.o \
+			vpu_color.o \
+			vdec.o  \
+			venc.o \
+			vpu_dbg.o
+
+obj-$(CONFIG_VIDEO_AMPHION_VPU) += amphion-vpu.o
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
new file mode 100644
index 000000000000..6c6cdfcf5535
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu.h
@@ -0,0 +1,356 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_H
+#define _AMPHION_VPU_H
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
+#include <linux/kfifo.h>
+
+#define VPU_TIMEOUT		msecs_to_jiffies(1000)
+#define VPU_INST_NULL_ID	(-1L)
+#define VPU_MSG_BUFFER_SIZE	(8192)
+
+enum imx_plat_type {
+	IMX8QXP = 0,
+	IMX8QM  = 1,
+	IMX8DM,
+	IMX8DX,
+	PLAT_TYPE_RESERVED
+};
+
+enum vpu_core_type {
+	VPU_CORE_TYPE_ENC = 0,
+	VPU_CORE_TYPE_DEC = 0x10,
+};
+
+struct vpu_dev;
+struct vpu_resources {
+	enum imx_plat_type plat_type;
+	u32 mreg_base;
+	int (*setup)(struct vpu_dev *vpu);
+	int (*setup_encoder)(struct vpu_dev *vpu);
+	int (*setup_decoder)(struct vpu_dev *vpu);
+	int (*reset)(struct vpu_dev *vpu);
+};
+
+struct vpu_buffer {
+	void *virt;
+	dma_addr_t phys;
+	u32 length;
+	u32 bytesused;
+	struct device *dev;
+};
+
+struct vpu_func {
+	struct video_device *vfd;
+	struct v4l2_m2m_dev *m2m_dev;
+	enum vpu_core_type type;
+	int function;
+};
+
+struct vpu_dev {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct mutex lock; /* protect vpu device */
+	const struct vpu_resources *res;
+	struct list_head cores;
+
+	struct v4l2_device v4l2_dev;
+	struct vpu_func encoder;
+	struct vpu_func decoder;
+	struct media_device mdev;
+
+	struct delayed_work watchdog_work;
+	void (*get_vpu)(struct vpu_dev *vpu);
+	void (*put_vpu)(struct vpu_dev *vpu);
+	void (*get_enc)(struct vpu_dev *vpu);
+	void (*put_enc)(struct vpu_dev *vpu);
+	void (*get_dec)(struct vpu_dev *vpu);
+	void (*put_dec)(struct vpu_dev *vpu);
+	atomic_t ref_vpu;
+	atomic_t ref_enc;
+	atomic_t ref_dec;
+
+	struct dentry *debugfs;
+};
+
+struct vpu_format {
+	u32 pixfmt;
+	unsigned int num_planes;
+	u32 type;
+	u32 flags;
+	u32 width;
+	u32 height;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 field;
+};
+
+struct vpu_core_resources {
+	enum vpu_core_type type;
+	const char *fwname;
+	u32 stride;
+	u32 max_width;
+	u32 min_width;
+	u32 step_width;
+	u32 max_height;
+	u32 min_height;
+	u32 step_height;
+	u32 rpc_size;
+	u32 fwlog_size;
+	u32 act_size;
+};
+
+struct vpu_mbox {
+	char name[20];
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	bool block;
+};
+
+enum vpu_core_state {
+	VPU_CORE_DEINIT = 0,
+	VPU_CORE_ACTIVE,
+	VPU_CORE_SNAPSHOT,
+	VPU_CORE_HANG
+};
+
+struct vpu_core {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct device *parent;
+	struct device *pd;
+	struct device_link *pd_link;
+	struct mutex lock;     /* protect vpu core */
+	struct mutex cmd_lock; /* Lock vpu command */
+	struct list_head list;
+	enum vpu_core_type type;
+	int id;
+	const struct vpu_core_resources *res;
+	unsigned long instance_mask;
+	u32 supported_instance_count;
+	unsigned long hang_mask;
+	u32 request_count;
+	struct list_head instances;
+	enum vpu_core_state state;
+	u32 fw_version;
+
+	struct vpu_buffer fw;
+	struct vpu_buffer rpc;
+	struct vpu_buffer log;
+	struct vpu_buffer act;
+
+	struct vpu_mbox tx_type;
+	struct vpu_mbox tx_data;
+	struct vpu_mbox rx;
+	unsigned long cmd_seq;
+
+	wait_queue_head_t ack_wq;
+	struct completion cmp;
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct delayed_work msg_delayed_work;
+	struct kfifo msg_fifo;
+	void *msg_buffer;
+	unsigned int msg_buffer_size;
+
+	struct vpu_dev *vpu;
+	void *iface;
+
+	struct dentry *debugfs;
+	struct dentry *debugfs_fwlog;
+};
+
+enum vpu_codec_state {
+	VPU_CODEC_STATE_DEINIT = 1,
+	VPU_CODEC_STATE_CONFIGURED,
+	VPU_CODEC_STATE_START,
+	VPU_CODEC_STATE_STARTED,
+	VPU_CODEC_STATE_ACTIVE,
+	VPU_CODEC_STATE_SEEK,
+	VPU_CODEC_STATE_STOP,
+	VPU_CODEC_STATE_DRAIN,
+	VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE,
+};
+
+struct vpu_frame_info {
+	u32 type;
+	u32 id;
+	u32 sequence;
+	u32 luma;
+	u32 chroma_u;
+	u32 chroma_v;
+	u32 data_offset;
+	u32 flags;
+	u32 skipped;
+	s64 timestamp;
+};
+
+struct vpu_inst;
+struct vpu_inst_ops {
+	int (*ctrl_init)(struct vpu_inst *inst);
+	int (*start)(struct vpu_inst *inst, u32 type);
+	int (*stop)(struct vpu_inst *inst, u32 type);
+	int (*abort)(struct vpu_inst *inst);
+	bool (*check_ready)(struct vpu_inst *inst, unsigned int type);
+	void (*buf_done)(struct vpu_inst *inst, struct vpu_frame_info *frame);
+	void (*event_notify)(struct vpu_inst *inst, u32 event, void *data);
+	void (*release)(struct vpu_inst *inst);
+	void (*cleanup)(struct vpu_inst *inst);
+	void (*mem_request)(struct vpu_inst *inst,
+			    u32 enc_frame_size,
+			    u32 enc_frame_num,
+			    u32 ref_frame_size,
+			    u32 ref_frame_num,
+			    u32 act_frame_size,
+			    u32 act_frame_num);
+	void (*input_done)(struct vpu_inst *inst);
+	void (*stop_done)(struct vpu_inst *inst);
+	int (*process_output)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*process_capture)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*get_one_frame)(struct vpu_inst *inst, void *info);
+	void (*on_queue_empty)(struct vpu_inst *inst, u32 type);
+	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
+	void (*wait_prepare)(struct vpu_inst *inst);
+	void (*wait_finish)(struct vpu_inst *inst);
+};
+
+struct vpu_inst {
+	struct list_head list;
+	struct mutex lock; /* v4l2 and videobuf2 lock */
+	struct vpu_dev *vpu;
+	struct vpu_core *core;
+	struct device *dev;
+	int id;
+
+	struct v4l2_fh fh;
+	struct v4l2_ctrl_handler ctrl_handler;
+	atomic_t ref_count;
+	int (*release)(struct vpu_inst *inst);
+
+	enum vpu_codec_state state;
+	enum vpu_core_type type;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct kfifo msg_fifo;
+	u8 msg_buffer[VPU_MSG_BUFFER_SIZE];
+
+	struct vpu_buffer stream_buffer;
+	bool use_stream_buffer;
+	struct vpu_buffer act;
+
+	struct list_head cmd_q;
+	void *pending;
+
+	struct vpu_inst_ops *ops;
+	const struct vpu_format *formats;
+	struct vpu_format out_format;
+	struct vpu_format cap_format;
+	u32 min_buffer_cap;
+	u32 min_buffer_out;
+
+	struct v4l2_rect crop;
+	u32 colorspace;
+	u8 ycbcr_enc;
+	u8 quantization;
+	u8 xfer_func;
+	u32 sequence;
+	u32 extra_size;
+
+	u32 flows[16];
+	u32 flow_idx;
+
+	pid_t pid;
+	pid_t tgid;
+	struct dentry *debugfs;
+
+	void *priv;
+};
+
+#define call_vop(inst, op, args...)					\
+	((inst)->ops->op ? (inst)->ops->op(inst, ##args) : 0)		\
+
+enum {
+	VPU_BUF_STATE_IDLE = 0,
+	VPU_BUF_STATE_INUSE,
+	VPU_BUF_STATE_DECODED,
+	VPU_BUF_STATE_READY,
+	VPU_BUF_STATE_SKIP,
+	VPU_BUF_STATE_ERROR
+};
+
+struct vpu_vb2_buffer {
+	struct v4l2_m2m_buffer m2m_buf;
+	dma_addr_t luma;
+	dma_addr_t chroma_u;
+	dma_addr_t chroma_v;
+	unsigned int state;
+	u32 tag;
+};
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg);
+
+static inline struct vpu_vb2_buffer *to_vpu_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
+{
+	struct v4l2_m2m_buffer *m2m_buf = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+
+	return container_of(m2m_buf, struct vpu_vb2_buffer, m2m_buf);
+}
+
+static inline const char *vpu_core_type_desc(enum vpu_core_type type)
+{
+	return type == VPU_CORE_TYPE_ENC ? "encoder" : "decoder";
+}
+
+static inline struct vpu_inst *to_inst(struct file *filp)
+{
+	return container_of(filp->private_data, struct vpu_inst, fh);
+}
+
+#define ctrl_to_inst(ctrl)	\
+	container_of((ctrl)->handler, struct vpu_inst, ctrl_handler)
+
+const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void);
+const struct v4l2_file_operations *venc_get_fops(void);
+const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void);
+const struct v4l2_file_operations *vdec_get_fops(void);
+
+int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func);
+void vpu_remove_func(struct vpu_func *func);
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst);
+void vpu_inst_put(struct vpu_inst *inst);
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type);
+void vpu_release_core(struct vpu_core *core);
+int vpu_inst_register(struct vpu_inst *inst);
+int vpu_inst_unregister(struct vpu_inst *inst);
+const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst);
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst);
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst);
+int vpu_core_create_dbgfs_file(struct vpu_core *core);
+int vpu_core_remove_dbgfs_file(struct vpu_core *core);
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow);
+
+int vpu_core_driver_init(void);
+void vpu_core_driver_exit(void);
+
+extern bool debug;
+#define vpu_trace(dev, fmt, arg...)					\
+	do {								\
+		if (debug)						\
+			dev_info(dev, "%s: " fmt, __func__, ## arg);	\
+	} while (0)
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_defs.h b/drivers/media/platform/amphion/vpu_defs.h
new file mode 100644
index 000000000000..282664202dcf
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_defs.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_DEFS_H
+#define _AMPHION_VPU_DEFS_H
+
+enum MSG_TYPE {
+	INIT_DONE = 1,
+	PRC_BUF_OFFSET,
+	BOOT_ADDRESS,
+	COMMAND,
+	EVENT,
+};
+
+enum {
+	VPU_IRQ_CODE_BOOT_DONE = 0x55,
+	VPU_IRQ_CODE_SNAPSHOT_DONE = 0xa5,
+	VPU_IRQ_CODE_SYNC = 0xaa,
+};
+
+enum {
+	VPU_CMD_ID_NOOP = 0x0,
+	VPU_CMD_ID_CONFIGURE_CODEC,
+	VPU_CMD_ID_START,
+	VPU_CMD_ID_STOP,
+	VPU_CMD_ID_ABORT,
+	VPU_CMD_ID_RST_BUF,
+	VPU_CMD_ID_SNAPSHOT,
+	VPU_CMD_ID_FIRM_RESET,
+	VPU_CMD_ID_UPDATE_PARAMETER,
+	VPU_CMD_ID_FRAME_ENCODE,
+	VPU_CMD_ID_SKIP,
+	VPU_CMD_ID_PARSE_NEXT_SEQ,
+	VPU_CMD_ID_PARSE_NEXT_I,
+	VPU_CMD_ID_PARSE_NEXT_IP,
+	VPU_CMD_ID_PARSE_NEXT_ANY,
+	VPU_CMD_ID_DEC_PIC,
+	VPU_CMD_ID_FS_ALLOC,
+	VPU_CMD_ID_FS_RELEASE,
+	VPU_CMD_ID_TIMESTAMP,
+	VPU_CMD_ID_DEBUG
+};
+
+enum {
+	VPU_MSG_ID_NOOP = 0x100,
+	VPU_MSG_ID_RESET_DONE,
+	VPU_MSG_ID_START_DONE,
+	VPU_MSG_ID_STOP_DONE,
+	VPU_MSG_ID_ABORT_DONE,
+	VPU_MSG_ID_BUF_RST,
+	VPU_MSG_ID_MEM_REQUEST,
+	VPU_MSG_ID_PARAM_UPD_DONE,
+	VPU_MSG_ID_FRAME_INPUT_DONE,
+	VPU_MSG_ID_ENC_DONE,
+	VPU_MSG_ID_DEC_DONE,
+	VPU_MSG_ID_FRAME_REQ,
+	VPU_MSG_ID_FRAME_RELEASE,
+	VPU_MSG_ID_SEQ_HDR_FOUND,
+	VPU_MSG_ID_RES_CHANGE,
+	VPU_MSG_ID_PIC_HDR_FOUND,
+	VPU_MSG_ID_PIC_DECODED,
+	VPU_MSG_ID_PIC_EOS,
+	VPU_MSG_ID_FIFO_LOW,
+	VPU_MSG_ID_FIFO_HIGH,
+	VPU_MSG_ID_FIFO_EMPTY,
+	VPU_MSG_ID_FIFO_FULL,
+	VPU_MSG_ID_BS_ERROR,
+	VPU_MSG_ID_UNSUPPORTED,
+	VPU_MSG_ID_TIMESTAMP_INFO,
+
+	VPU_MSG_ID_FIRMWARE_XCPT,
+};
+
+enum VPU_ENC_MEMORY_RESOURSE {
+	MEM_RES_ENC,
+	MEM_RES_REF,
+	MEM_RES_ACT
+};
+
+enum VPU_DEC_MEMORY_RESOURCE {
+	MEM_RES_FRAME,
+	MEM_RES_MBI,
+	MEM_RES_DCP
+};
+
+enum VPU_SCODE_TYPE {
+	SCODE_PADDING_EOS = 1,
+	SCODE_PADDING_BUFFLUSH = 2,
+	SCODE_PADDING_ABORT = 3,
+	SCODE_SEQUENCE = 0x31,
+	SCODE_PICTURE = 0x32,
+	SCODE_SLICE = 0x33
+};
+
+struct vpu_pkt_mem_req_data {
+	u32 enc_frame_size;
+	u32 enc_frame_num;
+	u32 ref_frame_size;
+	u32 ref_frame_num;
+	u32 act_buf_size;
+	u32 act_buf_num;
+};
+
+struct vpu_enc_pic_info {
+	u32 frame_id;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 frame_size;
+	u32 wptr;
+	u32 crc;
+	s64 timestamp;
+};
+
+struct vpu_dec_codec_info {
+	u32 pixfmt;
+	u32 num_ref_frms;
+	u32 num_dpb_frms;
+	u32 num_dfe_area;
+	u32 color_primaries;
+	u32 transfer_chars;
+	u32 matrix_coeffs;
+	u32 full_range;
+	u32 vui_present;
+	u32 progressive;
+	u32 width;
+	u32 height;
+	u32 decoded_width;
+	u32 decoded_height;
+	struct v4l2_fract frame_rate;
+	u32 dsp_asp_ratio;
+	u32 level_idc;
+	u32 bit_depth_luma;
+	u32 bit_depth_chroma;
+	u32 chroma_fmt;
+	u32 mvc_num_views;
+	u32 offset_x;
+	u32 offset_y;
+	u32 tag;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 mbi_size;
+	u32 dcp_size;
+	u32 stride;
+};
+
+struct vpu_dec_pic_info {
+	u32 id;
+	u32 luma;
+	u32 start;
+	u32 end;
+	u32 pic_size;
+	u32 stride;
+	u32 skipped;
+	s64 timestamp;
+	u32 consumed_count;
+};
+
+struct vpu_fs_info {
+	u32 id;
+	u32 type;
+	u32 tag;
+	u32 luma_addr;
+	u32 luma_size;
+	u32 chroma_addr;
+	u32 chromau_size;
+	u32 chromav_addr;
+	u32 chromav_size;
+	u32 bytesperline;
+	u32 not_displayed;
+};
+
+struct vpu_ts_info {
+	s64 timestamp;
+	u32 size;
+};
+
+#define BITRATE_STEP		(1024)
+#define BITRATE_MIN		(16 * BITRATE_STEP)
+#define BITRATE_MAX		(240 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT		(2 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT_PEAK	(BITRATE_DEFAULT * 2)
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c
new file mode 100644
index 000000000000..83ca04452c02
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_drv.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/of_reserved_mem.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+bool debug;
+module_param(debug, bool, 0644);
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val)
+{
+	writel(val, vpu->base + reg);
+}
+
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg)
+{
+	return readl(vpu->base + reg);
+}
+
+static void vpu_dev_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_vpu) == 1 && vpu->res->setup)
+		vpu->res->setup(vpu);
+}
+
+static void vpu_dev_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_vpu);
+}
+
+static void vpu_enc_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_enc) == 1 && vpu->res->setup_encoder)
+		vpu->res->setup_encoder(vpu);
+}
+
+static void vpu_enc_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_enc);
+}
+
+static void vpu_dec_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_dec) == 1 && vpu->res->setup_decoder)
+		vpu->res->setup_decoder(vpu);
+}
+
+static void vpu_dec_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_dec);
+}
+
+static int vpu_init_media_device(struct vpu_dev *vpu)
+{
+	vpu->mdev.dev = vpu->dev;
+	strscpy(vpu->mdev.model, "amphion-vpu", sizeof(vpu->mdev.model));
+	strscpy(vpu->mdev.bus_info, "platform: amphion-vpu", sizeof(vpu->mdev.bus_info));
+	media_device_init(&vpu->mdev);
+	vpu->v4l2_dev.mdev = &vpu->mdev;
+
+	return 0;
+}
+
+static int vpu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_dev *vpu;
+	int ret;
+
+	dev_dbg(dev, "probe\n");
+	vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
+	if (!vpu)
+		return -ENOMEM;
+
+	vpu->pdev = pdev;
+	vpu->dev = dev;
+	mutex_init(&vpu->lock);
+	INIT_LIST_HEAD(&vpu->cores);
+	platform_set_drvdata(pdev, vpu);
+	atomic_set(&vpu->ref_vpu, 0);
+	atomic_set(&vpu->ref_enc, 0);
+	atomic_set(&vpu->ref_dec, 0);
+	vpu->get_vpu = vpu_dev_get;
+	vpu->put_vpu = vpu_dev_put;
+	vpu->get_enc = vpu_enc_get;
+	vpu->put_enc = vpu_enc_put;
+	vpu->get_dec = vpu_dec_get;
+	vpu->put_dec = vpu_dec_put;
+
+	vpu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(vpu->base))
+		return PTR_ERR(vpu->base);
+
+	vpu->res = of_device_get_match_data(dev);
+	if (!vpu->res)
+		return -ENODEV;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	pm_runtime_put_sync(dev);
+
+	ret = v4l2_device_register(dev, &vpu->v4l2_dev);
+	if (ret)
+		goto err_vpu_deinit;
+
+	vpu_init_media_device(vpu);
+	vpu->encoder.type = VPU_CORE_TYPE_ENC;
+	vpu->encoder.function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
+	vpu->decoder.type = VPU_CORE_TYPE_DEC;
+	vpu->decoder.function = MEDIA_ENT_F_PROC_VIDEO_DECODER;
+	vpu_add_func(vpu, &vpu->decoder);
+	vpu_add_func(vpu, &vpu->encoder);
+	ret = media_device_register(&vpu->mdev);
+	if (ret)
+		goto err_vpu_media;
+	vpu->debugfs = debugfs_create_dir("amphion_vpu", NULL);
+
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+	return 0;
+
+err_vpu_media:
+	vpu_remove_func(&vpu->encoder);
+	vpu_remove_func(&vpu->decoder);
+	v4l2_device_unregister(&vpu->v4l2_dev);
+err_vpu_deinit:
+err_runtime_disable:
+	pm_runtime_set_suspended(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_remove(struct platform_device *pdev)
+{
+	struct vpu_dev *vpu = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	debugfs_remove_recursive(vpu->debugfs);
+	vpu->debugfs = NULL;
+
+	pm_runtime_disable(dev);
+
+	media_device_unregister(&vpu->mdev);
+	vpu_remove_func(&vpu->decoder);
+	vpu_remove_func(&vpu->encoder);
+	media_device_cleanup(&vpu->mdev);
+	v4l2_device_unregister(&vpu->v4l2_dev);
+	mutex_destroy(&vpu->lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+struct vpu_resources imx8qxp_res = {
+	.plat_type = IMX8QXP,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+struct vpu_resources imx8qm_res = {
+	.plat_type = IMX8QM,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+static const struct of_device_id vpu_dt_match[] = {
+	{ .compatible = "nxp,imx8qxp-vpu", .data = &imx8qxp_res },
+	{ .compatible = "nxp,imx8qm-vpu", .data = &imx8qm_res },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_dt_match);
+
+static struct platform_driver amphion_vpu_driver = {
+	.probe = vpu_probe,
+	.remove = vpu_remove,
+	.driver = {
+		.name = "amphion-vpu",
+		.of_match_table = vpu_dt_match,
+		.pm = &vpu_pm_ops,
+	},
+};
+
+static int __init vpu_driver_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&amphion_vpu_driver);
+	if (ret)
+		return ret;
+
+	return vpu_core_driver_init();
+}
+
+static void __exit vpu_driver_exit(void)
+{
+	vpu_core_driver_exit();
+	platform_driver_unregister(&amphion_vpu_driver);
+}
+module_init(vpu_driver_init);
+module_exit(vpu_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX8Q");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/amphion/vpu_imx8q.c b/drivers/media/platform/amphion/vpu_imx8q.c
new file mode 100644
index 000000000000..606cc53125f8
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_imx8q.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_imx8q.h"
+#include "vpu_rpc.h"
+
+#define IMX8Q_CSR_CM0Px_ADDR_OFFSET			0x00000000
+#define IMX8Q_CSR_CM0Px_CPUWAIT				0x00000004
+
+#ifdef CONFIG_IMX_SCU
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+
+#define VPU_DISABLE_BITS			0x7
+#define VPU_IMX_DECODER_FUSE_OFFSET		14
+#define VPU_ENCODER_MASK			0x1
+#define VPU_DECODER_MASK			0x3UL
+#define VPU_DECODER_H264_MASK			0x2UL
+#define VPU_DECODER_HEVC_MASK			0x1UL
+
+static u32 imx8q_fuse;
+
+struct vpu_sc_msg_misc {
+	struct imx_sc_rpc_msg hdr;
+	u32 word;
+} __packed;
+#endif
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET, 0x1f);
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_SET, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+int vpu_imx8q_setup(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_readl(vpu, offset + 0x108);
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0x1);
+	vpu_writel(vpu, offset + 0x190, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_XMEM_RESET_SET, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0xE);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_SET, 0x7);
+	vpu_writel(vpu, XMEM_CONTROL, 0x102);
+
+	vpu_readl(vpu, offset + 0x108);
+
+	return 0;
+}
+
+static int vpu_imx8q_reset_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+static int vpu_imx8q_reset_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_CLR, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_reset(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_CLR, 0x7);
+	vpu_imx8q_reset_enc(vpu);
+	vpu_imx8q_reset_dec(vpu);
+
+	return 0;
+}
+
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config, u32 regs, u32 core_id)
+{
+	if (!config)
+		return -EINVAL;
+
+	switch (core_id) {
+	case 0:
+		config->malone_base_addr[0] = regs + DEC_MFD_XREG_SLV_BASE;
+		config->num_malones = 1;
+		config->num_windsors = 0;
+		break;
+	case 1:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_0_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	case 2:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_1_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (config->num_windsors) {
+		config->windsor_irq_pin[0x0][0x0] = WINDSOR_PAL_IRQ_PIN_L;
+		config->windsor_irq_pin[0x0][0x1] = WINDSOR_PAL_IRQ_PIN_H;
+	}
+
+	config->malone_base_addr[0x1] = 0x0;
+	config->hif_offset[0x0] = MFD_HIF;
+	config->hif_offset[0x1] = 0x0;
+
+	config->dpv_base_addr = 0x0;
+	config->dpv_irq_pin = 0x0;
+	config->pixif_base_addr = regs + DEC_MFD_XREG_SLV_BASE + MFD_PIX_IF;
+	config->cache_base_addr[0] = regs + MC_CACHE_0_BASE;
+	config->cache_base_addr[1] = regs + MC_CACHE_1_BASE;
+
+	return 0;
+}
+
+int vpu_imx8q_boot_core(struct vpu_core *core)
+{
+	csr_writel(core, IMX8Q_CSR_CM0Px_ADDR_OFFSET, core->fw.phys);
+	csr_writel(core, IMX8Q_CSR_CM0Px_CPUWAIT, 0);
+	return 0;
+}
+
+int vpu_imx8q_get_power_state(struct vpu_core *core)
+{
+	if (csr_readl(core, IMX8Q_CSR_CM0Px_CPUWAIT) == 1)
+		return 0;
+	return 1;
+}
+
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core)
+{
+	u8 *p;
+
+	p = core->fw.virt;
+	p[16] = core->vpu->res->plat_type;
+	p[17] = core->id;
+	p[18] = 1;
+
+	return 0;
+}
+
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size)
+{
+	const struct vpu_rpc_region_t imx8q_regions[] = {
+		{0x00000000, 0x08000000, VPU_CORE_MEMORY_CACHED},
+		{0x08000000, 0x10000000, VPU_CORE_MEMORY_UNCACHED},
+		{0x10000000, 0x20000000, VPU_CORE_MEMORY_CACHED},
+		{0x20000000, 0x40000000, VPU_CORE_MEMORY_UNCACHED}
+	};
+	int i;
+
+	if (addr < base)
+		return VPU_CORE_MEMORY_INVALID;
+
+	addr -= base;
+	for (i = 0; i < ARRAY_SIZE(imx8q_regions); i++) {
+		const struct vpu_rpc_region_t *region = &imx8q_regions[i];
+
+		if (addr >= region->start && addr + size < region->end)
+			return region->type;
+	}
+
+	return VPU_CORE_MEMORY_INVALID;
+}
+
+#ifdef CONFIG_IMX_SCU
+static u32 vpu_imx8q_get_fuse(void)
+{
+	static u32 fuse_got;
+	struct imx_sc_ipc *ipc;
+	struct vpu_sc_msg_misc msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	if (fuse_got)
+		return imx8q_fuse;
+
+	ret = imx_scu_get_handle(&ipc);
+	if (ret) {
+		pr_err("error: get sct handle fail: %d\n", ret);
+		return 0;
+	}
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_MISC;
+	hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+	hdr->size = 2;
+
+	msg.word = VPU_DISABLE_BITS;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return 0;
+
+	imx8q_fuse = msg.word;
+	fuse_got = 1;
+	return imx8q_fuse;
+}
+
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_ENC) {
+		if (fuse & VPU_ENCODER_MASK)
+			return false;
+	} else if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_HEVC_MASK && pixelfmt == V4L2_PIX_FMT_HEVC)
+			return false;
+		if (fuse == VPU_DECODER_H264_MASK && pixelfmt == V4L2_PIX_FMT_H264)
+			return false;
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+
+	return true;
+}
+#else
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	return true;
+}
+#endif
diff --git a/drivers/media/platform/amphion/vpu_imx8q.h b/drivers/media/platform/amphion/vpu_imx8q.h
new file mode 100644
index 000000000000..d63a2747e29c
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_imx8q.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_IMX8Q_H
+#define _AMPHION_VPU_IMX8Q_H
+
+#define SCB_XREG_SLV_BASE                               0x00000000
+#define SCB_SCB_BLK_CTRL                                0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET                     0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET                    0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR                    0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET                 0x00000100
+
+#define XMEM_CONTROL                                    0x00041000
+
+#define	MC_CACHE_0_BASE					0x00060000
+#define	MC_CACHE_1_BASE					0x00068000
+
+#define DEC_MFD_XREG_SLV_BASE                           0x00180000
+#define ENC_MFD_XREG_SLV_0_BASE				0x00800000
+#define ENC_MFD_XREG_SLV_1_BASE				0x00A00000
+
+#define MFD_HIF                                         0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS                0x00000018
+#define MFD_SIF                                         0x0001D000
+#define MFD_SIF_CTRL_STATUS                             0x000000F0
+#define MFD_SIF_INTR_STATUS                             0x000000F4
+#define MFD_MCX                                         0x00020800
+#define MFD_MCX_OFF                                     0x00000020
+#define MFD_PIX_IF					0x00020000
+
+#define MFD_BLK_CTRL                                    0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET                  0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR                  0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET           0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR           0x00000104
+
+#define VID_API_NUM_STREAMS				8
+#define VID_API_MAX_BUF_PER_STR				3
+#define VID_API_MAX_NUM_MVC_VIEWS			4
+#define MEDIAIP_MAX_NUM_MALONES				2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_WINDSORS			1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS		2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS			1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS			4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS			4
+
+#define WINDSOR_PAL_IRQ_PIN_L				0x4
+#define WINDSOR_PAL_IRQ_PIN_H				0x5
+
+struct vpu_rpc_system_config {
+	u32 cfg_cookie;
+
+	u32 num_malones;
+	u32 malone_base_addr[MEDIAIP_MAX_NUM_MALONES];
+	u32 hif_offset[MEDIAIP_MAX_NUM_MALONES];
+	u32 malone_irq_pin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+	u32 malone_irq_target[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+	u32 num_windsors;
+	u32 windsor_base_addr[MEDIAIP_MAX_NUM_WINDSORS];
+	u32 windsor_irq_pin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+	u32 windsor_irq_target[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+	u32 cmd_irq_pin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+	u32 cmd_irq_target[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+	u32 msg_irq_pin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+	u32 msg_irq_target[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+	u32 sys_clk_freq;
+	u32 num_timers;
+	u32 timer_base_addr;
+	u32 timer_irq_pin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_irq_target[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_slots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+	u32 gic_base_addr;
+	u32 uart_base_addr;
+
+	u32 dpv_base_addr;
+	u32 dpv_irq_pin;
+	u32 dpv_irq_target;
+
+	u32 pixif_base_addr;
+
+	u32 pal_trace_level;
+	u32 pal_trace_destination;
+
+	u32 pal_trace_level1;
+	u32 pal_trace_destination1;
+
+	u32 heap_base;
+	u32 heap_size;
+
+	u32 cache_base_addr[2];
+};
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu);
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu);
+int vpu_imx8q_setup(struct vpu_dev *vpu);
+int vpu_imx8q_reset(struct vpu_dev *vpu);
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config, u32 regs, u32 core_id);
+int vpu_imx8q_boot_core(struct vpu_core *core);
+int vpu_imx8q_get_power_state(struct vpu_core *core);
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core);
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size);
+bool vpu_imx8q_check_codec(enum vpu_core_type type);
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:16 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:16 +0800
Subject: [PATCH v15 00/13] amphion video decoder/encoder driver
Message-ID: <cover.1643077283.git.ming.qian@nxp.com>

Hi all,

This patch series adds support for
the amphion video encoder and decoder
via the VPU block present in imx8q platforms.
Currently, support for IMX8QXP and IMX8QM is included.

It features decoding for the following formats:
- H.264
- HEVC
- MPEG4
- MPEG2
- VC1
- VP8

It features encoding for the following formats:
- H.264

The driver creates a separate device node for the encoder and decoder.

This driver is dependent on vpu firmwares.
The firmwares have been submitted to linux-firmware.
The firmware patch is since commit
b563148fd28623f6b6ce68bb06c3dd3bd138b058:
linux-firmware: Update firmware file for Intel Bluetooth 9462
(Fri Oct 8 16:30:14 2021 +0530)

and it's available in the git repository at:
    https://github.com/mingqian-0/linux-firmware.git

for you to fetch changes up to bb3eee4f99589d4910dee4c053a3a685546b5dbb:
amphion: add VPU firmwares for NXP i.MX8Q SoCs
(Tue Oct 12 15:09:57 2021 +0800)

encoder is tested with gstreamer
decoder is tested with gstreamer, but the following patches are required:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1379
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1381


Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>


Changelog:

v15
- fix issues detected by "checkpatch.pl --strict"
- encoder add ctrl V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE

v14
- fix some errors according to Hans's comments

v13
- make a workaround that avoid firmware entering wfi wrongly

v12
- support reset decoder when starting a new stream
- don't append an empty last buffer, set last_buffer_dequeued
- improve the resolution change flow
- return all buffers if start_streaming fail
- fill encoder capture buffer's filed to none
- fix a bug in calculating bytesperline

v11
- fix dt_binding_check error after upgrade dtschema
- remove "default y"
- add media device

v10
- refine vpu log, remove custom logging infrastructure
- support non contiguous planes format nv12m instead of nv12
- rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
- rename V4L2_PIX_FMT_NV12_10BE_8L128 to V4L2_PIX_FMT_NV12MT_10BE_8L128
- merge two module into one
- fix kernel panic in rmmod

v9
- drop V4L2_BUF_FLAG_CODECCONFIG
- drop V4L2_EVENT_CODEC_ERROR
- drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
- fix some build warnings with W=1 reported by kernel test robot

v8
- move driver from driver/media/platform/imx/vpu-8q to
  driver/media/platform/amphion
- rename driver name to amphion
- remove imx_vpu.h
- move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
- move the definition of V4L2_EVENT_SKIP to videodev2.h

v7
- fix build warnings with W=1 reported by kernel test robot

v6:
- rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
- rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128

v5:
- move some definition from imx_vph.h to videodev2.h
- remove some unnecessary content
- add some documentation descriptions
- pass the lateset v4l2-compliance test

v4:
- redefine the memory-region in devicetree bindings documentation
- use v4l2's mechanism to implement synchronize queuing ioctl
- remove the unnecessary mutex ioctl_sync
- don't notify source change event if the parameters are same as previously established
- add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format

v3:
- don't make vpu device node a simple-bus
- trigger probing vpu core in the driver
- remove unnecessary vpu core index property

v2:
- fix dt bindings build error
- split driver patch into several parts to avoid exceeding bytes limit

Compliance
==========
# v4l2-compliance -d /dev/video0
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/video0:

Driver Info:
	Driver name      : amphion-vpu
	Card type        : amphion vpu decoder
	Bus info         : platform: amphion-vpu
	Driver version   : 5.15.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Decoder
Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0
Interface Info:
	ID               : 0x0300000c
	Type             : V4L Video
Entity Info:
	ID               : 0x00000001 (1)
	Name             : amphion-vpu-decoder-source
	Function         : V4L2 I/O
	Pad 0x01000002   : 0: Source
	  Link 0x02000008: to remote pad 0x1000004 of entity 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video0 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 3 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/video1
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/video1:

Driver Info:
	Driver name      : amphion-vpu
	Card type        : amphion vpu encoder
	Bus info         : platform: amphion-vpu
	Driver version   : 5.15.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Encoder
Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0
Interface Info:
	ID               : 0x0300001a
	Type             : V4L Video
Entity Info:
	ID               : 0x0000000f (15)
	Name             : amphion-vpu-encoder-source
	Function         : V4L2 I/O
	Pad 0x01000010   : 0: Source
	  Link 0x02000016: to remote pad 0x1000012 of entity 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video1 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 20 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK
	test Composing: OK (Not Supported)
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/media0
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/media0:

Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0

Required ioctls:
	test MEDIA_IOC_DEVICE_INFO: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/media0 open: OK
	test MEDIA_IOC_DEVICE_INFO: OK
	test for unlimited opens: OK

Media Controller ioctls:
	test MEDIA_IOC_G_TOPOLOGY: OK
	Entities: 6 Interfaces: 2 Pads: 8 Links: 8
	test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
	test MEDIA_IOC_SETUP_LINK: OK

Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0

Ming Qian (13):
  dt-bindings: media: amphion: add amphion video codec bindings
  media: add nv12m_8l128 and nv12m_10be_8l128 video format.
  media: amphion: add amphion vpu device driver
  media: amphion: add vpu core driver
  media: amphion: implement vpu core communication based on mailbox
  media: amphion: add vpu v4l2 m2m support
  media: amphion: add v4l2 m2m vpu encoder stateful driver
  media: amphion: add v4l2 m2m vpu decoder stateful driver
  media: amphion: implement windsor encoder rpc interface
  media: amphion: implement malone decoder rpc interface
  ARM64: dts: freescale: imx8q: add imx vpu codec entries
  firmware: imx: scu-pd: imx8q: add vpu mu resources
  MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry

 .../bindings/media/amphion,vpu.yaml           |  180 ++
 .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
 MAINTAINERS                                   |    9 +
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
 arch/arm64/configs/defconfig                  |    1 +
 drivers/firmware/imx/scu-pd.c                 |    4 +
 drivers/media/platform/Kconfig                |   19 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/amphion/Makefile       |   20 +
 drivers/media/platform/amphion/vdec.c         | 1694 +++++++++++++++++
 drivers/media/platform/amphion/venc.c         | 1364 +++++++++++++
 drivers/media/platform/amphion/vpu.h          |  356 ++++
 drivers/media/platform/amphion/vpu_cmds.c     |  436 +++++
 drivers/media/platform/amphion/vpu_cmds.h     |   25 +
 drivers/media/platform/amphion/vpu_codec.h    |   68 +
 drivers/media/platform/amphion/vpu_color.c    |  183 ++
 drivers/media/platform/amphion/vpu_core.c     |  870 +++++++++
 drivers/media/platform/amphion/vpu_core.h     |   15 +
 drivers/media/platform/amphion/vpu_dbg.c      |  495 +++++
 drivers/media/platform/amphion/vpu_defs.h     |  187 ++
 drivers/media/platform/amphion/vpu_drv.c      |  260 +++
 drivers/media/platform/amphion/vpu_helpers.c  |  413 ++++
 drivers/media/platform/amphion/vpu_helpers.h  |   74 +
 drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
 drivers/media/platform/amphion/vpu_imx8q.h    |  115 ++
 drivers/media/platform/amphion/vpu_malone.c   | 1625 ++++++++++++++++
 drivers/media/platform/amphion/vpu_malone.h   |   44 +
 drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
 drivers/media/platform/amphion/vpu_mbox.h     |   16 +
 drivers/media/platform/amphion/vpu_msgs.c     |  385 ++++
 drivers/media/platform/amphion/vpu_msgs.h     |   14 +
 drivers/media/platform/amphion/vpu_rpc.c      |  257 +++
 drivers/media/platform/amphion/vpu_rpc.h      |  456 +++++
 drivers/media/platform/amphion/vpu_v4l2.c     |  720 +++++++
 drivers/media/platform/amphion/vpu_v4l2.h     |   55 +
 drivers/media/platform/amphion/vpu_windsor.c  | 1169 ++++++++++++
 drivers/media/platform/amphion/vpu_windsor.h  |   37 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
 include/uapi/linux/videodev2.h                |    2 +
 41 files changed, 12099 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
 create mode 100644 drivers/media/platform/amphion/Makefile
 create mode 100644 drivers/media/platform/amphion/vdec.c
 create mode 100644 drivers/media/platform/amphion/venc.c
 create mode 100644 drivers/media/platform/amphion/vpu.h
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
 create mode 100644 drivers/media/platform/amphion/vpu_codec.h
 create mode 100644 drivers/media/platform/amphion/vpu_color.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.h
 create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
 create mode 100644 drivers/media/platform/amphion/vpu_defs.h
 create mode 100644 drivers/media/platform/amphion/vpu_drv.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
 create mode 100644 drivers/media/platform/amphion/vpu_malone.c
 create mode 100644 drivers/media/platform/amphion/vpu_malone.h
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.h


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.33.0



From ming.qian at nxp.com  Mon Jan 24 23:11:18 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 15:11:18 +0800
Subject: [PATCH v15 02/13] media: add nv12m_8l128 and nv12m_10be_8l128 video
 format.
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <3fd0d09d382b827ddc7f97ca6e4d7b3e4c1bf4fc.1643077283.git.ming.qian@nxp.com>

nv12m_8l128 is 8-bit tiled nv12 format used by amphion decoder.
nv12m_10be_8l128 is 10-bit tiled format used by amphion decoder.
The tile size is 8x128

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../media/v4l/pixfmt-yuv-planar.rst           | 28 +++++++++++++++++--
 drivers/media/v4l2-core/v4l2-ioctl.c          |  2 ++
 include/uapi/linux/videodev2.h                |  2 ++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index 3a09d93d405b..8b2ff1d29639 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -257,6 +257,8 @@ of the luma plane.
 .. _V4L2-PIX-FMT-NV12-4L4:
 .. _V4L2-PIX-FMT-NV12-16L16:
 .. _V4L2-PIX-FMT-NV12-32L32:
+.. _V4L2_PIX_FMT_NV12M_8L128:
+.. _V4L2_PIX_FMT_NV12M_10BE_8L128:
 
 Tiled NV12
 ----------
@@ -281,21 +283,41 @@ If the vertical resolution is an odd number of tiles, the last row of
 tiles is stored in linear order. The layouts of the luma and chroma
 planes are identical.
 
-``V4L2_PIX_FMT_NV12_4L4`` stores pixel in 4x4 tiles, and stores
+``V4L2_PIX_FMT_NV12_4L4`` stores pixels in 4x4 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 4. The layouts of the luma and chroma planes are
 identical.
 
-``V4L2_PIX_FMT_NV12_16L16`` stores pixel in 16x16 tiles, and stores
+``V4L2_PIX_FMT_NV12_16L16`` stores pixels in 16x16 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 16. The layouts of the luma and chroma planes are
 identical.
 
-``V4L2_PIX_FMT_NV12_32L32`` stores pixel in 32x32 tiles, and stores
+``V4L2_PIX_FMT_NV12_32L32`` stores pixels in 32x32 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 32. The layouts of the luma and chroma planes are
 identical.
 
+``V4L2_PIX_FMT_NV12M_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+
+``V4L2_PIX_FMT_NV12M_10BE_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+10 bits pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+the data is arranged in big endian order.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+Note the tile size is 8bytes multiplied by 128 bytes,
+it means that the low bits and high bits of one pixel may be in different tiles.
+The 10 bit pixels are packed, so 5 bytes contain 4 10-bit pixels layout like
+this (for luma):
+byte 0: Y0(bits 9-2)
+byte 1: Y0(bits 1-0) Y1(bits 9-4)
+byte 2: Y1(bits 3-0) Y2(bits 9-6)
+byte 3: Y2(bits 5-0) Y3(bits 9-8)
+byte 4: Y3(bits 7-0)
+
 .. _nv12mt:
 
 .. kernel-figure:: nv12mt.svg
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 9ac557b8e146..efbfda9ec3ce 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1388,6 +1388,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
+	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
+	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
 
 	default:
 		/* Compressed formats */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index df8b9c486ba1..3768a0a80830 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -632,6 +632,8 @@ struct v4l2_pix_format {
 /* Tiled YUV formats, non contiguous planes */
 #define V4L2_PIX_FMT_NV12MT  v4l2_fourcc('T', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 64x32 tiles */
 #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 16x16 tiles */
+#define V4L2_PIX_FMT_NV12M_8L128      v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
+#define V4L2_PIX_FMT_NV12M_10BE_8L128 v4l2_fourcc_be('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
 
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
-- 
2.33.0



From m.tretter at pengutronix.de  Tue Jan 25 00:02:07 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Tue, 25 Jan 2022 09:02:07 +0100
Subject: [PATCH 1/4] arm64: dts: zynqmp: add AMS driver to device tree
In-Reply-To: <20220120010246.3794962-2-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-2-robert.hancock@calian.com>
Message-ID: <20220125080207.GC25856@pengutronix.de>

On Wed, 19 Jan 2022 19:02:43 -0600, Robert Hancock wrote:
> Add an entry to the ZynqMP device tree to support the AMS device which
> now has a driver in mainline.
> 
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>

Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

> ---
>  .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +++
>  arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 26 +++++++++++++++++++
>  2 files changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> index 1e0b1bca7c94..108592104a1b 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> @@ -239,6 +239,10 @@ &lpd_watchdog {
>  	clocks = <&zynqmp_clk LPD_WDT>;
>  };
>  
> +&xilinx_ams {
> +	clocks = <&zynqmp_clk AMS_REF>;
> +};
> +
>  &zynqmp_dpdma {
>  	clocks = <&zynqmp_clk DPDMA_REF>;
>  };
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 74e66443e4ce..d1fe1e5b46c1 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -878,6 +878,32 @@ lpd_watchdog: watchdog at ff150000 {
>  			timeout-sec = <10>;
>  		};
>  
> +		xilinx_ams: ams at ffa50000 {
> +			compatible = "xlnx,zynqmp-ams";
> +			status = "disabled";
> +			interrupt-parent = <&gic>;
> +			interrupts = <0 56 4>;
> +			reg = <0x0 0xffa50000 0x0 0x800>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			#io-channel-cells = <1>;
> +			ranges = <0 0 0xffa50800 0x800>;
> +
> +			ams_ps: ams_ps at 0 {
> +				compatible = "xlnx,zynqmp-ams-ps";
> +				status = "disabled";
> +				reg = <0x0 0x400>;
> +			};
> +
> +			ams_pl: ams_pl at 400 {
> +				compatible = "xlnx,zynqmp-ams-pl";
> +				status = "disabled";
> +				reg = <0x400 0x400>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
>  		zynqmp_dpdma: dma-controller at fd4c0000 {
>  			compatible = "xlnx,zynqmp-dpdma";
>  			status = "disabled";
> -- 
> 2.31.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From baruch at tkos.co.il  Mon Jan 24 23:41:45 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 25 Jan 2022 09:41:45 +0200
Subject: [PATCH v5 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <20220124204252.GA1552314@bhelgaas>
References: <f69d32f08a890463a331567e5742f2d33fa8b2bb.1643041464.git.baruch@tkos.co.il>
 <20220124204252.GA1552314@bhelgaas>
Message-ID: <8735lc9r9d.fsf@tarshish>

Hi Bjorn,

Thanks for your review comments.

On Mon, Jan 24 2022, Bjorn Helgaas wrote:
> Capitalize subject line to match history, i.e.,
>
>   $ git log --oneline drivers/pci/controller/dwc/pcie-qcom.c
>   3f13d611aa6b PCI: qcom: Use __be16 type to store return value from cpu_to_be16()
>   4e0e90539bb0 PCI: qcom: Fix an error handling path in 'qcom_pcie_probe()'
>   45a3ec891370 PCI: qcom: Add sc8180x compatible
>   aa9c0df98c29 PCI: qcom: Switch pcie_1_pipe_clk_src after PHY init in SC7280
>   b89ff410253d PCI: qcom: Replace ops with struct pcie_cfg in pcie match data
>   2cfef1971aea PCI: qcom: Use PHY_REFCLK_USE_PAD only for ipq8064
>   7081556f81f7 PCI: qcom: Add support for ddrss_sf_tbu clock
>   4c9398822106 PCI: qcom: Add support for configuring BDF to SID mapping for SM8250
>   e1dd639e374a PCI: qcom: Add SM8250 SoC support
>
> A good one would be:
>
>   PCI: qcom: Add IPQ60xx support
>
> We already know this is a PCIe controller, and it's nice to have the
> important words like "IPQ60xx" early in the message so they don't get
> truncated or wrapped.
>
> On Mon, Jan 24, 2022 at 06:27:31PM +0200, Baruch Siach wrote:
>> From: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> 
>> IPQ60xx series of SoCs have one port of PCIe gen 3. Add support for that
>> platform.
>> 
>> The code is based on downstream[1] Codeaurora kernel v5.4 (branch
>> win.linuxopenwrt.2.0).
>> 
>> Split out the DBI registers access part from .init into .post_init. DBI
>> registers are only accessible after phy_power_on().
>> 
>> [1] https://source.codeaurora.org/quic/qsdk/oss/kernel/linux-ipq-5.4/
>> 
>> Signed-off-by: Selvam Sathappan Periakaruppan <speriaka at codeaurora.org>
>> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
>> ---
>> v5:
>> 
>>   * Remove comments from qcom_pcie_init_2_9_0() (Bjorn Andersson)
>> 
>> v4:
>> 
>>   * Rebase on v5.16-rc1
>> 
>> v3:
>>   * Drop speed setup; rely on generic code (Rob Herring)
>> 
>>   * Drop unused CLK_RATE macros (Bjorn Helgaas)
>> 
>>   * Minor formatting fixes (Bjorn Helgaas)
>> 
>>   * Add reference to downstream Codeaurora kernel tree (Bjorn Helgaas)
>> 
>> v2:
>>   * Drop ATU configuration; rely on common code instead
>> 
>>   * Use more common register macros
>> 
>>   * Use bulk clk and reset APIs
>> ---
>>  drivers/pci/controller/dwc/pcie-designware.h |   1 +
>>  drivers/pci/controller/dwc/pcie-qcom.c       | 137 +++++++++++++++++++
>>  2 files changed, 138 insertions(+)
>> 
>> diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
>> index ea87809ee298..279c3778a13b 100644
>> --- a/drivers/pci/controller/dwc/pcie-designware.h
>> +++ b/drivers/pci/controller/dwc/pcie-designware.h
>> @@ -76,6 +76,7 @@
>>  
>>  #define GEN3_RELATED_OFF			0x890
>>  #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL	BIT(0)
>> +#define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS	BIT(13)
>>  #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE	BIT(16)
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT	24
>>  #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK	GENMASK(25, 24)
>> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
>> index c19cd506ed3f..5d47e572da44 100644
>> --- a/drivers/pci/controller/dwc/pcie-qcom.c
>> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
>> @@ -52,6 +52,10 @@
>>  #define PCIE20_PARF_DBI_BASE_ADDR		0x168
>>  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE		0x16C
>>  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL	0x174
>> +#define AHB_CLK_EN				BIT(0)
>> +#define MSTR_AXI_CLK_EN				BIT(1)
>> +#define BYPASS					BIT(4)
>> +
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT	0x178
>>  #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2	0x1A8
>>  #define PCIE20_PARF_LTSSM			0x1B0
>> @@ -171,6 +175,11 @@ struct qcom_pcie_resources_2_7_0 {
>>  	struct clk *ref_clk_src;
>>  };
>>  
>> +struct qcom_pcie_resources_2_9_0 {
>> +	struct clk_bulk_data clks[5];
>> +	struct reset_control *rst;
>> +};
>> +
>>  union qcom_pcie_resources {
>>  	struct qcom_pcie_resources_1_0_0 v1_0_0;
>>  	struct qcom_pcie_resources_2_1_0 v2_1_0;
>> @@ -178,6 +187,7 @@ union qcom_pcie_resources {
>>  	struct qcom_pcie_resources_2_3_3 v2_3_3;
>>  	struct qcom_pcie_resources_2_4_0 v2_4_0;
>>  	struct qcom_pcie_resources_2_7_0 v2_7_0;
>> +	struct qcom_pcie_resources_2_9_0 v2_9_0;
>>  };
>>  
>>  struct qcom_pcie;
>> @@ -1297,6 +1307,119 @@ static void qcom_pcie_post_deinit_2_7_0(struct qcom_pcie *pcie)
>>  	clk_disable_unprepare(res->pipe_clk);
>>  }
>>  
>> +static int qcom_pcie_get_resources_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +	struct dw_pcie *pci = pcie->pci;
>> +	struct device *dev = pci->dev;
>> +	int ret;
>> +
>> +	res->clks[0].id = "iface";
>> +	res->clks[1].id = "axi_m";
>> +	res->clks[2].id = "axi_s";
>> +	res->clks[3].id = "axi_bridge";
>> +	res->clks[4].id = "rchng";
>> +
>> +	ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
>> +	if (ret < 0)
>> +		return ret;
>> +
>> +	res->rst = devm_reset_control_array_get_exclusive(dev);
>> +	if (IS_ERR(res->rst))
>> +		return PTR_ERR(res->rst);
>> +
>> +	return 0;
>> +}
>> +
>> +static void qcom_pcie_deinit_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +
>> +	clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
>> +}
>> +
>> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
>> +	struct device *dev = pcie->pci->dev;
>> +	int ret;
>> +
>> +	ret = reset_control_assert(res->rst);
>> +	if (ret) {
>> +		dev_err(dev, "reset assert failed (%d)\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	usleep_range(2000, 2500);
>
> Where do these sleep durations come from?  If they're specified
> somewhere by PCIe, can you include a citation, e.g., a section number
> in the spec.

As I mentioned before, I have no access to hardware documentation. I'm
only porting working code from downstream kernel.

In a comment on v4 Bjorn Andersson mentioned "datasheet stating the
minimum timing of the operations to be performed to get the PCIe
controller into a known (clean) state".

  https://lore.kernel.org/all/Ydd5Wh0KeADBQ%2Fh1 at ripper/

I have no further details.

>> +	ret = reset_control_deassert(res->rst);
>> +	if (ret) {
>> +		dev_err(dev, "reset deassert failed (%d)\n", ret);
>> +		return ret;
>> +	}
>> +
>> +	usleep_range(2000, 2500);
>> +
>> +	ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
>> +	if (ret)
>> +		goto err_reset;
>> +
>> +	return 0;
>> +
>> +err_reset:
>> +	reset_control_assert(res->rst);
>> +
>> +	return ret;
>> +}
>> +
>> +static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
>> +{
>> +	struct dw_pcie *pci = pcie->pci;
>> +	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> +	u32 val;
>> +	int i;
>> +
>> +	writel(SLV_ADDR_SPACE_SZ,
>> +		pcie->parf + PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE);
>> +
>> +	val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +	val &= ~BIT(0);
>> +	writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
>> +
>> +	writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
>> +
>> +	writel(DEVICE_TYPE_RC, pcie->parf + PCIE20_PARF_DEVICE_TYPE);
>> +	writel(BYPASS | MSTR_AXI_CLK_EN | AHB_CLK_EN,
>> +		pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
>> +	writel(GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS
>> +		| GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL,
>> +		pci->dbi_base + GEN3_RELATED_OFF);
>> +
>> +	writel(MST_WAKEUP_EN | SLV_WAKEUP_EN | MSTR_ACLK_CGC_DIS
>> +		| SLV_ACLK_CGC_DIS | CORE_CLK_CGC_DIS |
>> +		AUX_PWR_DET | L23_CLK_RMV_DIS | L1_CLK_RMV_DIS,
>> +		pcie->parf + PCIE20_PARF_SYS_CTRL);
>> +
>> +	writel(0, pcie->parf + PCIE20_PARF_Q2A_FLUSH);
>> +
>> +	dw_pcie_dbi_ro_wr_en(pci);
>> +	writel(PCIE_CAP_LINK1_VAL, pci->dbi_base + offset + PCI_EXP_SLTCAP);
>
> Is "PCIE_CAP_LINK1_VAL" misnamed?  If it's being written to
> PCI_EXP_SLTCAP, seems like it should be named something about a
> *slot*, not a *link*.
>
> Or is this an error and it should this be written to PCI_EXP_LNKCAP
> instead?

As above, I don't know. I can only mention that the exact same
assignment is currently also in qcom_pcie_init_2_3_3().

> Could PCIE_CAP_LINK1_VAL be defined in terms of PCI_EXP_SLTCAP_* or
> PCI_EXP_LNKCAP_*?

It surely can. Whether it makes sense I can't tell.

>> +	/* Configure PCIe link capabilities for ASPM */
>> +	val = readl(pci->dbi_base + offset + PCI_EXP_LNKCAP);
>> +	val &= ~PCI_EXP_LNKCAP_ASPMS;
>> +	writel(val, pci->dbi_base + offset + PCI_EXP_LNKCAP);
>
> Thanks for using the standard PCI_EXP_LNKCAP and similar #defines.
> Does this mean you don't advertise any ASPM support on this platform?
> If so, that's fine, but the comment could be more specific.
> "Configure" doesn't give any hint about *how* they are configured.

Again, the same code is in qcom_pcie_init_2_3_3(). I'll just drop the
comment in the next submission.

Thanks,
baruch

>> +	writel(PCI_EXP_DEVCTL2_COMP_TMOUT_DIS, pci->dbi_base + offset +
>> +			PCI_EXP_DEVCTL2);
>> +
>> +	for (i = 0; i < 256; i++)
>> +		writel(0x0, pcie->parf + PCIE20_PARF_BDF_TO_SID_TABLE_N
>> +				+ (4 * i));
>> +
>> +	return 0;
>> +}
>> +
>>  static int qcom_pcie_link_up(struct dw_pcie *pci)
>>  {
>>  	u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>> @@ -1487,6 +1610,15 @@ static const struct qcom_pcie_ops ops_1_9_0 = {
>>  	.config_sid = qcom_pcie_config_sid_sm8250,
>>  };
>>  
>> +/* Qcom IP rev.: 2.9.0  Synopsys IP rev.: 5.00a */
>> +static const struct qcom_pcie_ops ops_2_9_0 = {
>> +	.get_resources = qcom_pcie_get_resources_2_9_0,
>> +	.init = qcom_pcie_init_2_9_0,
>> +	.post_init = qcom_pcie_post_init_2_9_0,
>> +	.deinit = qcom_pcie_deinit_2_9_0,
>> +	.ltssm_enable = qcom_pcie_2_3_2_ltssm_enable,
>> +};
>> +
>>  static const struct qcom_pcie_cfg apq8084_cfg = {
>>  	.ops = &ops_1_0_0,
>>  };
>> @@ -1520,6 +1652,10 @@ static const struct qcom_pcie_cfg sc7280_cfg = {
>>  	.pipe_clk_need_muxing = true,
>>  };
>>  
>> +static const struct qcom_pcie_cfg ipq6018_cfg = {
>> +	.ops = &ops_2_9_0,
>> +};
>> +
>>  static const struct dw_pcie_ops dw_pcie_ops = {
>>  	.link_up = qcom_pcie_link_up,
>>  	.start_link = qcom_pcie_start_link,
>> @@ -1629,6 +1765,7 @@ static const struct of_device_id qcom_pcie_match[] = {
>>  	{ .compatible = "qcom,pcie-sm8250", .data = &sm8250_cfg },
>>  	{ .compatible = "qcom,pcie-sc8180x", .data = &sm8250_cfg },
>>  	{ .compatible = "qcom,pcie-sc7280", .data = &sc7280_cfg },
>> +	{ .compatible = "qcom,pcie-ipq6018", .data = &ipq6018_cfg },
>>  	{ }
>>  };
>>  
>> -- 
>> 2.34.1

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From m.tretter at pengutronix.de  Tue Jan 25 00:06:34 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Tue, 25 Jan 2022 09:06:34 +0100
Subject: [PATCH 2/4] iio: adc: xilinx-ams: Fixed missing PS channels
In-Reply-To: <c615acdc4f0a818e070705e1f3f5d82660fb4c8a.camel@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-3-robert.hancock@calian.com>
 <c615acdc4f0a818e070705e1f3f5d82660fb4c8a.camel@calian.com>
Message-ID: <20220125080634.GD25856@pengutronix.de>

On Thu, 20 Jan 2022 01:09:39 +0000, Robert Hancock wrote:
> On Wed, 2022-01-19 at 19:02 -0600, Robert Hancock wrote:
> > The code forgot to increment num_channels for the PS channel inputs,
> > resulting in them not being enabled as they should.
> > 
> > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > ---
> >  drivers/iio/adc/xilinx-ams.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > index 8343c5f74121..b93864362dac 100644
> > --- a/drivers/iio/adc/xilinx-ams.c
> > +++ b/drivers/iio/adc/xilinx-ams.c
> > @@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
> >  
> >  		/* add PS channels to iio device channels */
> >  		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
> > +		num_channels = ARRAY_SIZE(ams_ps_channels);
> >  	} else if (fwnode_property_match_string(fwnode, "compatible",
> >  						"xlnx,zynqmp-ams-pl") == 0) {
> >  		ams->pl_base = fwnode_iomap(fwnode, 0);
> 
> Looks like this is the same change just submitted by Michael Tretter ("iio:
> adc: xilinx-ams: Fix num_channels for PS channels").

Thanks for pointing me here.

Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

Michael


From moudy.ho at mediatek.com  Tue Jan 25 00:20:05 2022
From: moudy.ho at mediatek.com (moudy ho)
Date: Tue, 25 Jan 2022 16:20:05 +0800
Subject: [PATCH v11 2/3] dts: arm64: mt8183: add Mediatek MDP3 nodes
In-Reply-To: <d61ec481-8059-a897-504a-0125f88fad61@collabora.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-3-moudy.ho@mediatek.com>
 <d61ec481-8059-a897-504a-0125f88fad61@collabora.com>
Message-ID: <356f512b549f90b329775e249fd48eb2954ade02.camel@mediatek.com>

On Fri, 2022-01-21 at 12:58 +0100, AngeloGioacchino Del Regno wrote:
> Il 05/01/22 10:37, Moudy Ho ha scritto:
> > Add device nodes for Media Data Path 3 (MDP3) modules.
> > 
> > Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> > ---
> >   arch/arm64/boot/dts/mediatek/mt8183.dtsi | 108
> > ++++++++++++++++++++++-
> >   1 file changed, 107 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > index ba4584faca5a..b872ef1ff6b3 100644
> > --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
> > @@ -1325,6 +1325,79 @@
> >   			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX
> > 0 0x1000>;
> >   		};
> >   
> > +		mdp3_rdma0: mdp3_rdma0 at 14001000 {
> > +			compatible = "mediatek,mt8183-mdp3",
> > +				     "mediatek,mt8183-mdp3-rdma0";
> > +			mediatek,scp = <&scp>;
> > +			mediatek,mdp3-comps = "mediatek,mt8183-mdp3-
> > dl1",
> > +					      "mediatek,mt8183-mdp3-
> > dl2",
> > +					      "mediatek,mt8183-mdp3-
> > path1",
> > +					      "mediatek,mt8183-mdp3-
> > path2",
> > +					      "mediatek,mt8183-mdp3-
> > imgi",
> > +					      "mediatek,mt8183-mdp3-
> > exto";
> > +			reg = <0 0x14001000 0 0x1000>,
> > +			      <0 0x14000000 0 0x1000>,
> > +			      <0 0x14005000 0 0x1000>,
> > +			      <0 0x14006000 0 0x1000>,
> > +			      <0 0x15020000 0 0x1000>;
> > +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX
> > 0x1000 0x1000>,
> > +						  <&gce SUBSYS_1400XXXX
> > 0 0x1000>,
> > +						  <&gce SUBSYS_1400XXXX
> > 0x5000 0x1000>,
> > +						  <&gce SUBSYS_1400XXXX
> > 0x6000 0x1000>,
> > +						  <&gce SUBSYS_1502XXXX
> > 0 0x1000>;
> > +			power-domains = <&spm
> > MT8183_POWER_DOMAIN_DISP>;
> > +			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> > +				 <&mmsys CLK_MM_MDP_RSZ1>,
> > +				 <&mmsys CLK_MM_MDP_DL_TXCK>,
> > +				 <&mmsys CLK_MM_MDP_DL_RX>,
> > +				 <&mmsys CLK_MM_IPU_DL_TXCK>,
> > +				 <&mmsys CLK_MM_IPU_DL_RX>;
> > +			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
> > +			mediatek,mmsys = <&mmsys>;
> > +			mediatek,mm-mutex = <&mutex>;
> > +			mediatek,mailbox-gce = <&gce>;
> > +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
> > +				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
> > +				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
> > +				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;
> 
> Hello Moudy,
> the mboxes for gce 21, 22, 23 are missing the third cell. Please fix.
> 
> Regards,
> Angelo

Hi Angelo,
Thanks for the reminder, but I'm a bit confused, the previous
version(v10) mentioned that the current upstream mbox has only 2
cells.
So I should follow this rule to remove the extra 0 in the first item as
follows:
 +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
 +				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
 +				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
 +				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;

Thanks,
Moudy Ho
> 
> > +			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> > +				     <&gce 0x14010000 SUBSYS_1401XXXX>,
> > +				     <&gce 0x14020000 SUBSYS_1402XXXX>,
> > +				     <&gce 0x15020000 SUBSYS_1502XXXX>;
> > +		};
> > +
> 
> 



From m.tretter at pengutronix.de  Tue Jan 25 00:21:08 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Tue, 25 Jan 2022 09:21:08 +0100
Subject: [PATCH 3/4] iio: adc: xilinx-ams: Fixed wrong sequencer register
 settings
In-Reply-To: <20220120010246.3794962-4-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-4-robert.hancock@calian.com>
Message-ID: <20220125082108.GE25856@pengutronix.de>

On Wed, 19 Jan 2022 19:02:45 -0600, Robert Hancock wrote:
> Register settings used for the sequencer configuration register
> were incorrect, causing some inputs to not be read properly.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>  drivers/iio/adc/xilinx-ams.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index b93864362dac..199027c93cdc 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -91,8 +91,8 @@
>  
>  #define AMS_CONF1_SEQ_MASK		GENMASK(15, 12)
>  #define AMS_CONF1_SEQ_DEFAULT		FIELD_PREP(AMS_CONF1_SEQ_MASK, 0)
> -#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 1)
> -#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
> +#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
> +#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK, 3)

The TRM states that Continuous Loop Mode is 2, but Single Pass Sequence Mode
is 1, not 3. Is there a reason, why you need to set both bits?

Michael

>  
>  #define AMS_REG_SEQ0_MASK		GENMASK(15, 0)
>  #define AMS_REG_SEQ2_MASK		GENMASK(21, 16)
> -- 
> 2.31.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 


From maz at kernel.org  Tue Jan 25 00:45:54 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 08:45:54 +0000
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <CAJHc60wp4uCVQhigNrNxF3pPd_8RPHXQvK+gf7rSxCRfH6KwFg@mail.gmail.com>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org>
 <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <877dg8ppnt.wl-maz@kernel.org> <YSfiN3Xq1vUzHeap@google.com>
 <20210827074011.ci2kzo4cnlp3qz7h@gator.home>
 <CAOQ_Qsg2dKLLanSx6nMbC1Er9DSO3peLVEAJNvU1ZcRVmwaXgQ@mail.gmail.com>
 <87ilyitt6e.wl-maz@kernel.org>
 <CAOQ_QshfXEGL691_MOJn0YbL94fchrngP8vuFReCW-=5UQtNKQ@mail.gmail.com>
 <87lf3drmvp.wl-maz@kernel.org>
 <CAOQ_QsjVk9n7X9E76ycWBNguydPE0sVvywvKW0jJ_O58A0NJHg@mail.gmail.com>
 <CAJHc60wp4uCVQhigNrNxF3pPd_8RPHXQvK+gf7rSxCRfH6KwFg@mail.gmail.com>
Message-ID: <875yq88app.wl-maz@kernel.org>

On Tue, 25 Jan 2022 03:47:04 +0000,
Raghavendra Rao Ananta <rananta at google.com> wrote:
> 
> Hello all,
> 
> Based on the recent discussion on the patch '[RFC PATCH v3 01/11] KVM:
> Capture VM start' [1], Reiji, I (and others in the team) were
> wondering, since the hypercall feature-map is technically per-VM and
> not per-vCPU, would it make more sense to present it as a kvm_device,
> rather than vCPU psuedo-registers to the userspace?

I really don't think so.

> If I understand correctly, the original motivation for going with
> pseudo-registers was to comply with QEMU, which uses KVM_GET_REG_LIST
> and KVM_[GET|SET]_ONE_REG interface, but I'm guessing the VMMs doing
> save/restore across migration might write the same values for every
> vCPU.

KVM currently restricts the vcpu features to be unified across vcpus,
but that's only an implementation choice. The ARM architecture doesn't
mandate that these registers are all the same, and it isn't impossible
that we'd allow for the feature set to become per-vcpu at some point
in time. So this argument doesn't really hold.

Furthermore, compatibility with QEMU's save/restore model is
essential, and AFAICT, there is no open source alternative.

> Granted that we would be diverging from the existing implementation
> (psci versioning and spectre WA registers), but this can be a cleaner
> way forward for extending hypercall support.

Cleaner? Why? How? You'd have the exact same constraints, plus the
disadvantages of having to maintain a new interface concurrently with
the existing ones.

> The kvm_device interface
> can be made backward compatible with the way hypercalls are exposed
> today, it can have the same registers/features discovery mechanisms
> that we discussed above, and majorly the userspace has to configure it
> only once per-VM. We can probably make the feature selection immutable
> just before any vCPU is created.

What is the problem with immutability on first run? Or even with a
'finalize' ioctl (we already have one)?

> 
> Please let me know your thoughts or any disadvantages that I'm overlooking.

A device means yet another configuration and migration API. Don't you
think we have enough of those? The complexity of KVM/arm64 userspace
API is already insane, and extremely fragile. Adding to it will be a
validation nightmare (it already is, and I don't see anyone actively
helping with it).

So no, I have no plan to consider anything but the GET/SET_ONE_REG
interface, and until someone writes another open source VMM that has
the same save/restore capabilities and proves that this interface
isn't fit for purpose, I see no incentive in deviating from a model
that is known to work.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ceggers at arri.de  Tue Jan 25 00:52:00 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:52:00 +0100
Subject: [PATCH 0/6] clk: imx6*: avoid GPMI clock glitches on
 reparenting/divider change
Message-ID: <20220125085206.8508-1-ceggers@arri.de>

On the i.MX6 series (but not on i.MX7/8), most clock multiplexers and
switchable dividers are not "glitch safe", so switching them while a
consumer is connected can cause glitches with a higher frequency than
supported by the consuming peripheral.

Without fixes, peripherals can fail occasionally. One example is
that system boot fails due to lockup of the GPMI NAND controller:

f53d4c109a66 ("mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings")

The conditions where this can appear also depend on the device
from which the system is booted and whether the bootloader has already
performed all reparenting of the clocks.

To avoid these problems, the clock subsystem must:
 - Gate consumer clocks during reparenting
 - Enforce that all consumer clocks are gated before client drivers can change the divider 




From ceggers at arri.de  Tue Jan 25 00:52:01 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:52:01 +0100
Subject: [PATCH 1/6] clk: imx6ul: disable gpmi_io clock before changing parent
 clock
In-Reply-To: <20220125085206.8508-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
Message-ID: <20220125085206.8508-2-ceggers@arri.de>

gpmi_io clock may have been enabled by the boot loader. All children of
enfc_clk_root must be gated in order to prevent glitches during parent
change.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6ul.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 520b100bff4b..f599ae50dd9f 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -514,6 +514,15 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	else if (clk_on_imx6ull())
 		clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk);
 
+	/*
+	 * gpmi_io clock may have been enabled by the boot loader. All children of
+	 * enfc_clk_root must be gated in order to prevent glitches during parent
+	 * change. The task of re-enabling is left to the gpmi-nand driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6UL_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6UL_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6UL_CLK_GPMI_IO]->clk);
+	}
 	clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
 }
 
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 00:52:02 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:52:02 +0100
Subject: [PATCH 2/6] clk: imx6ul: enforce gating of gpmi_io clock
In-Reply-To: <20220125085206.8508-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
Message-ID: <20220125085206.8508-3-ceggers@arri.de>

Clock parent and divider changes are both glitchy for enfc_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6ul.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index f599ae50dd9f..5443b5a0dc75 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -256,7 +256,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	if (clk_on_imx6ull())
 		hws[IMX6ULL_CLK_ESAI_SEL]	  = imx_clk_hw_mux("esai_sel",	base + 0x20, 19, 2, esai_sels, ARRAY_SIZE(esai_sels));
 	hws[IMX6UL_CLK_UART_SEL]	  = imx_clk_hw_mux("uart_sel",	base + 0x24, 6,  1, uart_sels, ARRAY_SIZE(uart_sels));
-	hws[IMX6UL_CLK_ENFC_SEL]	  = imx_clk_hw_mux("enfc_sel",	base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels));
+	hws[IMX6UL_CLK_ENFC_SEL]	  = imx_clk_hw_mux_flags("enfc_sel",	base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels), CLK_SET_PARENT_GATE);
 	hws[IMX6UL_CLK_LDB_DI0_SEL]	  = imx_clk_hw_mux("ldb_di0_sel",	base + 0x2c, 9,  3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
 	hws[IMX6UL_CLK_SPDIF_SEL]	  = imx_clk_hw_mux("spdif_sel",	base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
 	if (clk_on_imx6ul()) {
@@ -424,7 +424,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	hws[IMX6UL_CLK_PWM4]		= imx_clk_hw_gate2("pwm4",		"perclk",	base + 0x78,	22);
 	hws[IMX6UL_CLK_GPMI_BCH_APB]	= imx_clk_hw_gate2("gpmi_bch_apb",	"bch_podf",	base + 0x78,	24);
 	hws[IMX6UL_CLK_GPMI_BCH]	= imx_clk_hw_gate2("gpmi_bch",	"gpmi_podf",	base + 0x78,	26);
-	hws[IMX6UL_CLK_GPMI_IO]	= imx_clk_hw_gate2("gpmi_io",	"enfc_podf",	base + 0x78,	28);
+	hws[IMX6UL_CLK_GPMI_IO]	= imx_clk_hw_gate2_flags("gpmi_io",	"enfc_podf",	base + 0x78,	28, CLK_SET_RATE_GATE);
 	hws[IMX6UL_CLK_GPMI_APB]	= imx_clk_hw_gate2("gpmi_apb",	"bch_podf",	base + 0x78,	30);
 
 	/* CCGR5 */
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 00:52:03 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:52:03 +0100
Subject: [PATCH 3/6] clk: imx6q: disable gpmi_io and ipt_io clocks before
 changing parent
In-Reply-To: <20220125085206.8508-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
Message-ID: <20220125085206.8508-4-ceggers@arri.de>

gpmi_io and ipt_io clocks may have been enabled by the boot loader. All
children of enfc_clk_root must be gated in order to prevent glitches
during parent change.

Reparenting of enfc_clk_root may disable pll3_usb_otg. In order to avoid
immediately re-enabling it in imx_register_uart_clocks(), the whole
section has been moved to the bottom of imx6q_clocks_init().

Signed-off-by: Christian Eggers <ceggers at arri.de>
Co-developed-by: Stefan Riedmueller <S.Riedmueller at phytec.de>
Signed-off-by: Stefan Riedmueller <S.Riedmueller at phytec.de>
---
 drivers/clk/imx/clk-imx6q.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index de36f58d551c..fd5c37095ed0 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -927,13 +927,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI0_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI0_PRE]->clk);
 	clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI1_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI1_PRE]->clk);
 
-	/*
-	 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
-	 * We can not get the 100MHz from the pll2_pfd0_352m.
-	 * So choose pll2_pfd2_396m as enfc_sel's parent.
-	 */
-	clk_set_parent(hws[IMX6QDL_CLK_ENFC_SEL]->clk, hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk);
-
 	if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
 		clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY1_GATE]->clk);
 		clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY2_GATE]->clk);
@@ -975,5 +968,25 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	}
 
 	imx_register_uart_clocks(2);
+
+	/*
+	 * The gpmi needs 100MHz frequency in the EDO/Sync mode. We can not get
+	 * the 100MHz from the pll2_pfd0_352m. So choose pll2_pfd2_396m as
+	 * enfc_sel's parent.
+	 *
+	 * gpmi_io and ipt_clk_io clocks may have been enabled by the boot
+	 * loader. All children of enfc_clk_root must be gated in order to
+	 * prevent glitches during parent change. The task of re-enabling
+	 * gpio_io is left to the gpmi-nand driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6QDL_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6QDL_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6QDL_CLK_GPMI_IO]->clk);
+	}
+	if (clk_hw_is_enabled(hws[IMX6QDL_CLK_ENFC])) {
+		clk_prepare_enable(hws[IMX6QDL_CLK_ENFC]->clk);
+		clk_disable_unprepare(hws[IMX6QDL_CLK_ENFC]->clk);
+	}
+	clk_set_parent(hws[IMX6QDL_CLK_ENFC_SEL]->clk, hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk);
 }
 CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 00:54:39 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:54:39 +0100
Subject: [PATCH 5/6] clk: imx6sx: disable gpmi_io clock before changing parent
 clock
In-Reply-To: <20220125085206.8508-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
Message-ID: <20220125085440.8768-1-ceggers@arri.de>

gpmi_io clocks may have been enabled by the boot loader. All children of
qspi2_clk_root must be gated in order to prevent glitches during parent
change.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6sx.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index fc1bd23d4583..cf1c1fad45f9 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -546,8 +546,19 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(hws[IMX6SX_CLK_GPU_AXI_SEL]->clk, hws[IMX6SX_CLK_PLL3_PFD0]->clk);
 
 	clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
-	clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
 
 	imx_register_uart_clocks(2);
+
+	/*
+	 * gpmi_io clock may have been enabled by the boot loader. All children
+	 * of qspi2_clk_root must be gated in order to prevent glitches during
+	 * parent change. The task of re-enabling is left to the gpmi-nand
+	 * driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6SX_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6SX_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6SX_CLK_GPMI_IO]->clk);
+	}
+	clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
 }
 CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 00:54:40 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:54:40 +0100
Subject: [PATCH 6/6] clk: imx6sx: enforce gating of gpmi_io clock
In-Reply-To: <20220125085440.8768-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
 <20220125085440.8768-1-ceggers@arri.de>
Message-ID: <20220125085440.8768-2-ceggers@arri.de>

Clock parent and divider changes are both glitchy for qspi2_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6sx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index cf1c1fad45f9..023a18594ebe 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -286,7 +286,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	hws[IMX6SX_CLK_ESAI_SEL]           = imx_clk_hw_mux("esai_sel",         base + 0x20,  19,     2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_CAN_SEL]            = imx_clk_hw_mux("can_sel",          base + 0x20,  8,      2,      can_sels,          ARRAY_SIZE(can_sels));
 	hws[IMX6SX_CLK_UART_SEL]           = imx_clk_hw_mux("uart_sel",         base + 0x24,  6,      1,      uart_sels,         ARRAY_SIZE(uart_sels));
-	hws[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
+	hws[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
 	hws[IMX6SX_CLK_SPDIF_SEL]          = imx_clk_hw_mux("spdif_sel",        base + 0x30,  20,     2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_AUDIO_SEL]          = imx_clk_hw_mux("audio_sel",        base + 0x30,  7,      2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_ENET_PRE_SEL]       = imx_clk_hw_mux("enet_pre_sel",     base + 0x34,  15,     3,      enet_pre_sels,     ARRAY_SIZE(enet_pre_sels));
@@ -441,7 +441,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	hws[IMX6SX_CLK_PWM4]         = imx_clk_hw_gate2("pwm4",          "perclk",            base + 0x78, 22);
 	hws[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
 	hws[IMX6SX_CLK_GPMI_BCH]     = imx_clk_hw_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	hws[IMX6SX_CLK_GPMI_IO]      = imx_clk_hw_gate2("gpmi_io",       "qspi2_podf",        base + 0x78, 28);
+	hws[IMX6SX_CLK_GPMI_IO]      = imx_clk_hw_gate2_flags("gpmi_io",       "qspi2_podf",        base + 0x78, 28, CLK_SET_RATE_GATE);
 	hws[IMX6SX_CLK_GPMI_APB]     = imx_clk_hw_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
 
 	/* CCGR5 */
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From yong.wu at mediatek.com  Tue Jan 25 00:56:10 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:10 +0800
Subject: [PATCH v4 11/35] iommu/mediatek: Add a flag DCM_DISABLE
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-12-yong.wu@mediatek.com>

In the infra iommu, we should disable DCM. add a new flag for this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 4a24977274e3..b2361e8b06d9 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -51,6 +51,8 @@
 #define F_MMU_STANDARD_AXI_MODE_MASK		(BIT(3) | BIT(19))
 
 #define REG_MMU_DCM_DIS				0x050
+#define F_MMU_DCM				BIT(8)
+
 #define REG_MMU_WR_LEN_CTRL			0x054
 #define F_MMU_WR_THROT_DIS_MASK			(BIT(5) | BIT(21))
 
@@ -119,6 +121,7 @@
 #define HAS_LEGACY_IVRP_PADDR		BIT(7)
 #define IOVA_34_EN			BIT(8)
 #define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
+#define DCM_DISABLE			BIT(10)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -733,7 +736,11 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		regval = F_MMU_VLD_PA_RNG(7, 4);
 		writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
 	}
-	writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE))
+		writel_relaxed(F_MMU_DCM, data->base + REG_MMU_DCM_DIS);
+	else
+		writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
 		/* write command throttling mode */
 		regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:03 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:03 +0800
Subject: [PATCH v4 04/35] iommu/mediatek: Add list_del in mtk_iommu_remove
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-5-yong.wu@mediatek.com>

Lack the list_del in the mtk_iommu_remove, and remove
bus_set_iommu(*, NULL) since there may be several iommu HWs.
we can not bus_set_iommu null when one iommu driver unbind.

This could be a fix for mt2712 which support 2 M4U HW and list them.

Fixes: 7c3a2ec02806 ("iommu/mediatek: Merge 2 M4U HWs into one iommu domain")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index a92b01805232..6ccfd7bac9df 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -919,8 +919,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
 
-	if (iommu_present(&platform_bus_type))
-		bus_set_iommu(&platform_bus_type, NULL);
+	list_del(&data->list);
 
 	clk_disable_unprepare(data->bclk);
 	device_link_remove(data->smicomm_dev, &pdev->dev);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:22 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:22 +0800
Subject: [PATCH v4 23/35] iommu/mediatek: Add mt8195 support
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-24-yong.wu@mediatek.com>

mt8195 has 3 IOMMU, containing 2 MM IOMMUs, one is for vdo, the other
is for vpp. and 1 INFRA IOMMU.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 43 +++++++++++++++++++++++++++++++++++++++
 drivers/iommu/mtk_iommu.h |  1 +
 2 files changed, 44 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index fe3da530f77e..68de89eff9db 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1195,6 +1195,46 @@ static const struct mtk_iommu_plat_data mt8192_data = {
 			   {0, 14, 16}, {0, 13, 18, 17}},
 };
 
+static const struct mtk_iommu_plat_data mt8195_data_infra = {
+	.m4u_plat	  = M4U_MT8195,
+	.flags            = WR_THROT_EN | DCM_DISABLE | PM_CLK_AO |
+			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIE_SUPPORT,
+	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
+	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
+	.iova_region      = single_domain,
+	.iova_region_nr   = ARRAY_SIZE(single_domain),
+};
+
+static const struct mtk_iommu_plat_data mt8195_data_vdo = {
+	.m4u_plat	= M4U_MT8195,
+	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
+			  WR_THROT_EN | NOT_STD_AXI_MODE | IOVA_34_EN |
+			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
+	.hw_list        = &m4ulist,
+	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.iova_region	= mt8192_multi_dom,
+	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
+	.larbid_remap   = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11},
+			   {13, 17, 15/* 17b */, 25}, {5}},
+};
+
+static const struct mtk_iommu_plat_data mt8195_data_vpp = {
+	.m4u_plat	= M4U_MT8195,
+	.flags          = HAS_BCLK | HAS_SUB_COMM_3BITS | OUT_ORDER_WR_EN |
+			  WR_THROT_EN | NOT_STD_AXI_MODE | IOVA_34_EN |
+			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
+	.hw_list        = &m4ulist,
+	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.iova_region	= mt8192_multi_dom,
+	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
+	.larbid_remap   = {{1}, {3},
+			   {22, MTK_INVALID_LARBID, MTK_INVALID_LARBID, MTK_INVALID_LARBID, 23},
+			   {8}, {20}, {12},
+			   /* 16: 16a; 29: 16b; 30: CCUtop0; 31: CCUtop1 */
+			   {14, 16, 29, 26, 30, 31, 18},
+			   {4, MTK_INVALID_LARBID, MTK_INVALID_LARBID, MTK_INVALID_LARBID, 6}},
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
 	{ .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data},
 	{ .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data},
@@ -1202,6 +1242,9 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
 	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
 	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
 	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
+	{ .compatible = "mediatek,mt8195-iommu-infra", .data = &mt8195_data_infra},
+	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data = &mt8195_data_vdo},
+	{ .compatible = "mediatek,mt8195-iommu-vpp",   .data = &mt8195_data_vpp},
 	{}
 };
 
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 04e5e5e7fd62..9dba98bb12eb 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -46,6 +46,7 @@ enum mtk_iommu_plat {
 	M4U_MT8173,
 	M4U_MT8183,
 	M4U_MT8192,
+	M4U_MT8195,
 };
 
 struct mtk_iommu_iova_region;
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:12 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:12 +0800
Subject: [PATCH v4 13/35] iommu/mediatek: Remove the granule in the tlb flush
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-14-yong.wu@mediatek.com>

The MediaTek IOMMU don't care about granule when tlb flushing.
Remove this variable.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 80d8333797fd..028b2192c414 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -219,7 +219,6 @@ static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-					   size_t granule,
 					   struct mtk_iommu_data *data)
 {
 	struct list_head *head = data->hw_list;
@@ -541,8 +540,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	size_t length = gather->end - gather->start + 1;
 
-	mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize,
-				       dom->data);
+	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->data);
 }
 
 static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
@@ -550,7 +548,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_range_sync(iova, size, size, dom->data);
+	mtk_iommu_tlb_flush_range_sync(iova, size, dom->data);
 }
 
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:18 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:18 +0800
Subject: [PATCH v4 19/35] iommu/mediatek: Allow IOMMU_DOMAIN_UNMANAGED for
 PCIe VFIO
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-20-yong.wu@mediatek.com>

Allow the type IOMMU_DOMAIN_UNMANAGED since vfio_iommu_type1.c always call
iommu_domain_alloc. The PCIe EP works ok when going through vfio.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f676085af13d..cf042ab74fa7 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -446,7 +446,7 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
 {
 	struct mtk_iommu_domain *dom;
 
-	if (type != IOMMU_DOMAIN_DMA)
+	if (type != IOMMU_DOMAIN_DMA && type != IOMMU_DOMAIN_UNMANAGED)
 		return NULL;
 
 	dom = kzalloc(sizeof(*dom), GFP_KERNEL);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:21 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:21 +0800
Subject: [PATCH v4 22/35] iommu/mediatek: Add PCIe support
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-23-yong.wu@mediatek.com>

Currently the code for of_iommu_configure_dev_id is like this:

static int of_iommu_configure_dev_id(struct device_node *master_np,
                                     struct device *dev,
                                     const u32 *id)
{
       struct of_phandle_args iommu_spec = { .args_count = 1 };

       err = of_map_id(master_np, *id, "iommu-map",
                       "iommu-map-mask", &iommu_spec.np,
                       iommu_spec.args);
...
}

It supports only one id output. BUT our PCIe HW has two ID(one is for
writing, the other is for reading). I'm not sure if we should change
of_map_id to support output MAX_PHANDLE_ARGS.

Here add the solution in ourselve drivers. If it's pcie case, enable one
more bit.

Not all infra iommu support PCIe, thus add a PCIe support flag here.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 7176c212037f..fe3da530f77e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -20,6 +20,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
@@ -134,6 +135,7 @@
 #define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
 /* PM and clock always on. e.g. infra iommu */
 #define PM_CLK_AO			BIT(15)
+#define IFA_IOMMU_PCIE_SUPPORT		BIT(16)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
 
@@ -420,8 +422,11 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
 		} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
 			peri_mmuen_msk = BIT(portid);
-			peri_mmuen = enable ? peri_mmuen_msk : 0;
+			/* PCI dev has only one output id, enable the next writing bit for PCIe */
+			if (dev_is_pci(dev))
+				peri_mmuen_msk |= BIT(portid + 1);
 
+			peri_mmuen = enable ? peri_mmuen_msk : 0;
 			ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
 						 peri_mmuen_msk, peri_mmuen);
 			if (ret)
@@ -1013,6 +1018,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
 		if (ret)
 			goto out_bus_set_null;
+	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+		   MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) {
+#ifdef CONFIG_PCI
+		if (!iommu_present(&pci_bus_type)) {
+			ret = bus_set_iommu(&pci_bus_type, &mtk_iommu_ops);
+			if (ret) /* PCIe fail don't affect platform_bus. */
+				goto out_list_del;
+		}
+#endif
 	}
 	return ret;
 
@@ -1043,6 +1057,11 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
 		device_link_remove(data->smicomm_dev, &pdev->dev);
 		component_master_del(&pdev->dev, &mtk_iommu_com_ops);
+	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+		   MTK_IOMMU_HAS_FLAG(data->plat_data, IFA_IOMMU_PCIE_SUPPORT)) {
+#ifdef CONFIG_PCI
+		bus_set_iommu(&pci_bus_type, NULL);
+#endif
 	}
 	pm_runtime_disable(&pdev->dev);
 	devm_free_irq(&pdev->dev, data->irq, data);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:14 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:14 +0800
Subject: [PATCH v4 15/35] iommu/mediatek: Add SUB_COMMON_3BITS flag
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-16-yong.wu@mediatek.com>

In prevous SoC, the sub common id occupy 2 bits. the mt8195's sub common
id has 3bits. Add a new flag for this. and rename the previous flag to
_2BITS. For readable, I put these two flags together, then move the
other flags. no functional change.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 26 ++++++++++++++++----------
 drivers/iommu/mtk_iommu.h |  2 +-
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 548fa8448a6e..47d5f34f4db0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -105,6 +105,8 @@
 #define REG_MMU1_INT_ID				0x154
 #define F_MMU_INT_ID_COMM_ID(a)			(((a) >> 9) & 0x7)
 #define F_MMU_INT_ID_SUB_COMM_ID(a)		(((a) >> 7) & 0x3)
+#define F_MMU_INT_ID_COMM_ID_EXT(a)		(((a) >> 10) & 0x7)
+#define F_MMU_INT_ID_SUB_COMM_ID_EXT(a)		(((a) >> 7) & 0x7)
 #define F_MMU_INT_ID_LARB_ID(a)			(((a) >> 7) & 0x7)
 #define F_MMU_INT_ID_PORT_ID(a)			(((a) >> 2) & 0x1f)
 
@@ -116,13 +118,14 @@
 #define HAS_VLD_PA_RNG			BIT(2)
 #define RESET_AXI			BIT(3)
 #define OUT_ORDER_WR_EN			BIT(4)
-#define HAS_SUB_COMM			BIT(5)
-#define WR_THROT_EN			BIT(6)
-#define HAS_LEGACY_IVRP_PADDR		BIT(7)
-#define IOVA_34_EN			BIT(8)
-#define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
-#define DCM_DISABLE			BIT(10)
-#define NOT_STD_AXI_MODE		BIT(11)
+#define HAS_SUB_COMM_2BITS		BIT(5)
+#define HAS_SUB_COMM_3BITS		BIT(6)
+#define WR_THROT_EN			BIT(7)
+#define HAS_LEGACY_IVRP_PADDR		BIT(8)
+#define IOVA_34_EN			BIT(9)
+#define SHARE_PGTABLE			BIT(10) /* 2 HW share pgtable */
+#define DCM_DISABLE			BIT(11)
+#define NOT_STD_AXI_MODE		BIT(12)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -290,9 +293,12 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	fault_pa |= (u64)pa34_32 << 32;
 
 	fault_port = F_MMU_INT_ID_PORT_ID(regval);
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
 		fault_larb = F_MMU_INT_ID_COMM_ID(regval);
 		sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
+	} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+		fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
+		sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
 	} else {
 		fault_larb = F_MMU_INT_ID_LARB_ID(regval);
 	}
@@ -1033,7 +1039,7 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
-	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN |
+	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
 			 NOT_STD_AXI_MODE,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
@@ -1071,7 +1077,7 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
-	.flags          = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN |
+	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
 			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index c10f5630e55d..82c51a034e6b 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -20,7 +20,7 @@
 #include <dt-bindings/memory/mtk-memory-port.h>
 
 #define MTK_LARB_COM_MAX	8
-#define MTK_LARB_SUBCOM_MAX	4
+#define MTK_LARB_SUBCOM_MAX	8
 
 #define MTK_IOMMU_GROUP_MAX	8
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:06 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:06 +0800
Subject: [PATCH v4 07/35] iommu/mediatek: Add mutex for data in the
 mtk_iommu_domain
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-8-yong.wu@mediatek.com>

Same with the previous patch, add a mutex for the "data" in the
mtk_iommu_domain. Just improve the safety for multi devices
enter attach_device at the same time. We don't get the real issue
for this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 095736bfb7b4..e6e4ee471867 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -128,6 +128,8 @@ struct mtk_iommu_domain {
 
 	struct mtk_iommu_data		*data;
 	struct iommu_domain		domain;
+
+	struct mutex			mutex; /* Protect "data" in this structure */
 };
 
 static const struct iommu_ops mtk_iommu_ops;
@@ -434,6 +436,7 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
 	dom = kzalloc(sizeof(*dom), GFP_KERNEL);
 	if (!dom)
 		return NULL;
+	mutex_init(&dom->mutex);
 
 	return &dom->domain;
 }
@@ -455,14 +458,19 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	if (domid < 0)
 		return domid;
 
+	mutex_lock(&dom->mutex);
 	if (!dom->data) {
 		/* Data is in the frstdata in sharing pgtable case. */
 		frstdata = mtk_iommu_get_m4u_data();
 
-		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
+		ret = mtk_iommu_domain_finalise(dom, frstdata, domid);
+		if (ret) {
+			mutex_unlock(&dom->mutex);
 			return -ENODEV;
+		}
 		dom->data = data;
 	}
+	mutex_unlock(&dom->mutex);
 
 	mutex_lock(&data->mutex);
 	if (!data->m4u_dom) { /* Initialize the M4U HW */
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:55:59 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:55:59 +0800
Subject: [PATCH v4 00/35] MT8195 IOMMU SUPPORT
Message-ID: <20220125085634.17972-1-yong.wu@mediatek.com>

This patchset adds MT8195 iommu support.

MT8195 have 3 IOMMU HWs. 2 IOMMU HW is for multimedia, and 1 IOMMU HW is
for infra-master, like PCIe/USB.

About the 2 MM IOMMU HW, something like this:

        IOMMU(VDO)          IOMMU(VPP)
           |                   |
      SMI_COMMON(VDO)      SMI_COMMON(VPP)
      ---------------     ----------------
      |      |   ...      |      |     ...
    larb0 larb2  ...    larb1 larb3    ...

these two MM IOMMU HW share a pgtable.

About the INFRA IOMMU, it don't have larbs, the master connects the iommu
directly. It use a independent pgtable.

Also, mt8195 IOMMU bank supports. Normally the IOMMU register size only
is 0x1000. In this IOMMU HW, the register size is 5 * 0x1000. each 0x1000
is a bank. the banks' register look like this:
     ----------------------------------------
     |bank0  | bank1 | bank2 | bank3 | bank4|
     ----------------------------------------
     |global |
     |control|         null
     |regs   |
     -----------------------------------------
     |bank   |bank   |bank   |bank   |bank   |
     |regs   |regs   |regs   |regs   |regs   |
     |       |       |       |       |       |
     -----------------------------------------
All the banks share some global control registers, and each bank have its
special bank registers, like pgtable base register, tlb operation registers,
the fault status registers.
 
In mt8195, we enable this bank feature for infra iommu, We put PCIe in bank0
and USB in bank4. they have independent pgtable.

Change note:
v4:1) Base on v5.16-rc1
   2) Base on tlb logic 2, some patches in v3 has already gone through in that
   patchset.
   https://lore.kernel.org/linux-mediatek/20211208120744.2415-1-dafna.hirschfeld at collabora.com/  
   3) Due to the unreadable union for v1/v2(comment in 26/33 of v3), I
   separate mtk_iommu_data for v1 and v2 totally, then remove mtk_iommu.h.
   please see patch[26/35][27/35].
   4) add two mutex for the internal data. patch[6/35][7/35].
   5) add a new flag PM_CLK_AO.

v3: https://lore.kernel.org/linux-mediatek/20210923115840.17813-1-yong.wu at mediatek.com/
    1) base on v5.15-rc1
    2) Adjust devlink with smi-common, not use the property(sub-sommon).
    3) Adjust tlb_flush_all flow,
       a) Fix tlb_flush_all only is supported in bank0.
       b) add tlb-flush-all in the resume callback.
       c) remove the pm status checking in tlb-flush-all.
       The reason are showed in the commit message.
    4) Allow IOMMU_DOMAIN_UNMANAGED since PCIe VFIO use that.
    5) Fix a clk warning and a null abort when unbind the iommu driver.

v2: https://lore.kernel.org/linux-mediatek/20210813065324.29220-1-yong.wu at mediatek.com/
    1) Base on v5.14-rc1.
    2) Fix build fail for arm32.
    3) Fix dt-binding issue from Rob.
    4) Fix the bank issue when tlb flush. v1 always use bank->base.
    5) adjust devlink with smi-common since the node may be smi-sub-common.
    6) other changes: like reword some commit message(removing many
       "This patch..."); seperate serveral patches.

v1: https://lore.kernel.org/linux-mediatek/20210630023504.18177-1-yong.wu at mediatek.com/
    Base on v5.13-rc1

Yong Wu (35):
  dt-bindings: mediatek: mt8195: Add binding for MM IOMMU
  dt-bindings: mediatek: mt8195: Add binding for infra IOMMU
  iommu/mediatek: Fix 2 HW sharing pgtable issue
  iommu/mediatek: Add list_del in mtk_iommu_remove
  iommu/mediatek: Remove clk_disable in mtk_iommu_remove
  iommu/mediatek: Add mutex for m4u_group and m4u_dom in data
  iommu/mediatek: Add mutex for data in the mtk_iommu_domain
  iommu/mediatek: Use kmalloc for protect buffer
  iommu/mediatek: Adapt sharing and non-sharing pgtable case
  iommu/mediatek: Add 12G~16G support for multi domains
  iommu/mediatek: Add a flag DCM_DISABLE
  iommu/mediatek: Add a flag NON_STD_AXI
  iommu/mediatek: Remove the granule in the tlb flush
  iommu/mediatek: Always enable output PA over 32bits in isr
  iommu/mediatek: Add SUB_COMMON_3BITS flag
  iommu/mediatek: Add IOMMU_TYPE flag
  iommu/mediatek: Contain MM IOMMU flow with the MM TYPE
  iommu/mediatek: Adjust device link when it is sub-common
  iommu/mediatek: Allow IOMMU_DOMAIN_UNMANAGED for PCIe VFIO
  iommu/mediatek: Add a PM_CLK_AO flag for infra iommu
  iommu/mediatek: Add infra iommu support
  iommu/mediatek: Add PCIe support
  iommu/mediatek: Add mt8195 support
  iommu/mediatek: Only adjust code about register base
  iommu/mediatek: Just move code position in hw_init
  iommu/mediatek: Separate mtk_iommu_data for v1 and v2
  iommu/mediatek: Remove mtk_iommu.h
  iommu/mediatek-v1: Just rename mtk_iommu to mtk_iommu_v1
  iommu/mediatek: Add mtk_iommu_bank_data structure
  iommu/mediatek: Initialise bank HW for each a bank
  iommu/mediatek: Change the domid to iova_region_id
  iommu/mediatek: Get the proper bankid for multi banks
  iommu/mediatek: Initialise/Remove for multi bank dev
  iommu/mediatek: Backup/restore regsiters for multi banks
  iommu/mediatek: mt8195: Enable multi banks for infra iommu

 .../bindings/iommu/mediatek,iommu.yaml        |  20 +-
 drivers/iommu/mtk_iommu.c                     | 951 +++++++++++++-----
 drivers/iommu/mtk_iommu.h                     | 111 --
 drivers/iommu/mtk_iommu_v1.c                  | 243 +++--
 .../dt-bindings/memory/mt8195-memory-port.h   | 408 ++++++++
 include/dt-bindings/memory/mtk-memory-port.h  |   2 +
 6 files changed, 1255 insertions(+), 480 deletions(-)
 delete mode 100644 drivers/iommu/mtk_iommu.h
 create mode 100644 include/dt-bindings/memory/mt8195-memory-port.h

-- 
2.18.0




From yong.wu at mediatek.com  Tue Jan 25 00:56:27 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:27 +0800
Subject: [PATCH v4 28/35] iommu/mediatek-v1: Just rename mtk_iommu to
 mtk_iommu_v1
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-29-yong.wu@mediatek.com>

No functional change. Just rename this for readable.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu_v1.c | 209 +++++++++++++++++------------------
 1 file changed, 102 insertions(+), 107 deletions(-)

diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index 23c3bc175153..72d5cbeeaecf 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -85,34 +85,34 @@
  */
 #define M2701_IOMMU_PGT_SIZE			SZ_4M
 
-struct mtk_iommu_suspend_reg {
+struct mtk_iommu_v1_suspend_reg {
 	u32			standard_axi_mode;
 	u32			dcm_dis;
 	u32			ctrl_reg;
 	u32			int_control0;
 };
 
-struct mtk_iommu_data {
+struct mtk_iommu_v1_data {
 	void __iomem			*base;
 	int				irq;
 	struct device			*dev;
 	struct clk			*bclk;
 	phys_addr_t			protect_base; /* protect memory base */
-	struct mtk_iommu_domain		*m4u_dom;
+	struct mtk_iommu_v1_domain	*m4u_dom;
 
 	struct iommu_device		iommu;
 	struct dma_iommu_mapping	*mapping;
 	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
 
-	struct mtk_iommu_suspend_reg	reg;
+	struct mtk_iommu_v1_suspend_reg	reg;
 };
 
-struct mtk_iommu_domain {
+struct mtk_iommu_v1_domain {
 	spinlock_t			pgtlock; /* lock for page table */
 	struct iommu_domain		domain;
 	u32				*pgt_va;
 	dma_addr_t			pgt_pa;
-	struct mtk_iommu_data		*data;
+	struct mtk_iommu_v1_data	*data;
 };
 
 static inline int compare_of(struct device *dev, void *data)
@@ -125,23 +125,23 @@ static inline void release_of(struct device *dev, void *data)
 	of_node_put(data);
 }
 
-static inline int mtk_iommu_bind(struct device *dev)
+static inline int mtk_iommu_v1_bind(struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+	struct mtk_iommu_v1_data *data = dev_get_drvdata(dev);
 
 	return component_bind_all(dev, &data->larb_imu);
 }
 
-static inline void mtk_iommu_unbind(struct device *dev)
+static inline void mtk_iommu_v1_unbind(struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+	struct mtk_iommu_v1_data *data = dev_get_drvdata(dev);
 
 	component_unbind_all(dev, &data->larb_imu);
 }
 
-static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
+static struct mtk_iommu_v1_domain *to_mtk_domain(struct iommu_domain *dom)
 {
-	return container_of(dom, struct mtk_iommu_domain, domain);
+	return container_of(dom, struct mtk_iommu_v1_domain, domain);
 }
 
 static const int mt2701_m4u_in_larb[] = {
@@ -167,7 +167,7 @@ static inline int mt2701_m4u_to_port(int id)
 	return id - mt2701_m4u_in_larb[larb];
 }
 
-static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
+static void mtk_iommu_v1_tlb_flush_all(struct mtk_iommu_v1_data *data)
 {
 	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
 			data->base + REG_MMU_INV_SEL);
@@ -175,8 +175,8 @@ static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 	wmb(); /* Make sure the tlb flush all done */
 }
 
-static void mtk_iommu_tlb_flush_range(struct mtk_iommu_data *data,
-				unsigned long iova, size_t size)
+static void mtk_iommu_v1_tlb_flush_range(struct mtk_iommu_v1_data *data,
+					 unsigned long iova, size_t size)
 {
 	int ret;
 	u32 tmp;
@@ -194,16 +194,16 @@ static void mtk_iommu_tlb_flush_range(struct mtk_iommu_data *data,
 	if (ret) {
 		dev_warn(data->dev,
 			 "Partial TLB flush timed out, falling back to full flush\n");
-		mtk_iommu_tlb_flush_all(data);
+		mtk_iommu_v1_tlb_flush_all(data);
 	}
 	/* Clear the CPE status */
 	writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
 }
 
-static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
+static irqreturn_t mtk_iommu_v1_isr(int irq, void *dev_id)
 {
-	struct mtk_iommu_data *data = dev_id;
-	struct mtk_iommu_domain *dom = data->m4u_dom;
+	struct mtk_iommu_v1_data *data = dev_id;
+	struct mtk_iommu_v1_domain *dom = data->m4u_dom;
 	u32 int_state, regval, fault_iova, fault_pa;
 	unsigned int fault_larb, fault_port;
 
@@ -233,13 +233,13 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	regval |= F_INT_CLR_BIT;
 	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL);
 
-	mtk_iommu_tlb_flush_all(data);
+	mtk_iommu_v1_tlb_flush_all(data);
 
 	return IRQ_HANDLED;
 }
 
-static void mtk_iommu_config(struct mtk_iommu_data *data,
-			     struct device *dev, bool enable)
+static void mtk_iommu_v1_config(struct mtk_iommu_v1_data *data,
+				struct device *dev, bool enable)
 {
 	struct mtk_smi_larb_iommu    *larb_mmu;
 	unsigned int                 larbid, portid;
@@ -261,9 +261,9 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
 	}
 }
 
-static int mtk_iommu_domain_finalise(struct mtk_iommu_data *data)
+static int mtk_iommu_v1_domain_finalise(struct mtk_iommu_v1_data *data)
 {
-	struct mtk_iommu_domain *dom = data->m4u_dom;
+	struct mtk_iommu_v1_domain *dom = data->m4u_dom;
 
 	spin_lock_init(&dom->pgtlock);
 
@@ -279,9 +279,9 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_data *data)
 	return 0;
 }
 
-static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
+static struct iommu_domain *mtk_iommu_v1_domain_alloc(unsigned type)
 {
-	struct mtk_iommu_domain *dom;
+	struct mtk_iommu_v1_domain *dom;
 
 	if (type != IOMMU_DOMAIN_UNMANAGED)
 		return NULL;
@@ -293,21 +293,20 @@ static struct iommu_domain *mtk_iommu_domain_alloc(unsigned type)
 	return &dom->domain;
 }
 
-static void mtk_iommu_domain_free(struct iommu_domain *domain)
+static void mtk_iommu_v1_domain_free(struct iommu_domain *domain)
 {
-	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
-	struct mtk_iommu_data *data = dom->data;
+	struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain);
+	struct mtk_iommu_v1_data *data = dom->data;
 
 	dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE,
 			dom->pgt_va, dom->pgt_pa);
 	kfree(to_mtk_domain(domain));
 }
 
-static int mtk_iommu_attach_device(struct iommu_domain *domain,
-				   struct device *dev)
+static int mtk_iommu_v1_attach_device(struct iommu_domain *domain, struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
-	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev);
+	struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain);
 	struct dma_iommu_mapping *mtk_mapping;
 	int ret;
 
@@ -318,29 +317,28 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 
 	if (!data->m4u_dom) {
 		data->m4u_dom = dom;
-		ret = mtk_iommu_domain_finalise(data);
+		ret = mtk_iommu_v1_domain_finalise(data);
 		if (ret) {
 			data->m4u_dom = NULL;
 			return ret;
 		}
 	}
 
-	mtk_iommu_config(data, dev, true);
+	mtk_iommu_v1_config(data, dev, true);
 	return 0;
 }
 
-static void mtk_iommu_detach_device(struct iommu_domain *domain,
-				    struct device *dev)
+static void mtk_iommu_v1_detach_device(struct iommu_domain *domain, struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
+	struct mtk_iommu_v1_data *data = dev_iommu_priv_get(dev);
 
-	mtk_iommu_config(data, dev, false);
+	mtk_iommu_v1_config(data, dev, false);
 }
 
-static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
-			 phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+static int mtk_iommu_v1_map(struct iommu_domain *domain, unsigned long iova,
+			    phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
 {
-	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain);
 	unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT;
 	unsigned long flags;
 	unsigned int i;
@@ -361,16 +359,15 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
 
 	spin_unlock_irqrestore(&dom->pgtlock, flags);
 
-	mtk_iommu_tlb_flush_range(dom->data, iova, size);
+	mtk_iommu_v1_tlb_flush_range(dom->data, iova, size);
 
 	return map_size == size ? 0 : -EEXIST;
 }
 
-static size_t mtk_iommu_unmap(struct iommu_domain *domain,
-			      unsigned long iova, size_t size,
-			      struct iommu_iotlb_gather *gather)
+static size_t mtk_iommu_v1_unmap(struct iommu_domain *domain, unsigned long iova,
+				 size_t size, struct iommu_iotlb_gather *gather)
 {
-	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain);
 	unsigned long flags;
 	u32 *pgt_base_iova = dom->pgt_va + (iova  >> MT2701_IOMMU_PAGE_SHIFT);
 	unsigned int page_num = size >> MT2701_IOMMU_PAGE_SHIFT;
@@ -379,15 +376,14 @@ static size_t mtk_iommu_unmap(struct iommu_domain *domain,
 	memset(pgt_base_iova, 0, page_num * sizeof(u32));
 	spin_unlock_irqrestore(&dom->pgtlock, flags);
 
-	mtk_iommu_tlb_flush_range(dom->data, iova, size);
+	mtk_iommu_v1_tlb_flush_range(dom->data, iova, size);
 
 	return size;
 }
 
-static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
-					  dma_addr_t iova)
+static phys_addr_t mtk_iommu_v1_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova)
 {
-	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct mtk_iommu_v1_domain *dom = to_mtk_domain(domain);
 	unsigned long flags;
 	phys_addr_t pa;
 
@@ -399,17 +395,16 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
 	return pa;
 }
 
-static const struct iommu_ops mtk_iommu_ops;
+static const struct iommu_ops mtk_iommu_v1_ops;
 
 /*
  * MTK generation one iommu HW only support one iommu domain, and all the client
  * sharing the same iova address space.
  */
-static int mtk_iommu_create_mapping(struct device *dev,
-				    struct of_phandle_args *args)
+static int mtk_iommu_v1_create_mapping(struct device *dev, struct of_phandle_args *args)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
-	struct mtk_iommu_data *data;
+	struct mtk_iommu_v1_data *data;
 	struct platform_device *m4updev;
 	struct dma_iommu_mapping *mtk_mapping;
 	int ret;
@@ -421,11 +416,11 @@ static int mtk_iommu_create_mapping(struct device *dev,
 	}
 
 	if (!fwspec) {
-		ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_ops);
+		ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_v1_ops);
 		if (ret)
 			return ret;
 		fwspec = dev_iommu_fwspec_get(dev);
-	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {
+	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_v1_ops) {
 		return -EINVAL;
 	}
 
@@ -457,23 +452,23 @@ static int mtk_iommu_create_mapping(struct device *dev,
 	return 0;
 }
 
-static int mtk_iommu_def_domain_type(struct device *dev)
+static int mtk_iommu_v1_def_domain_type(struct device *dev)
 {
 	return IOMMU_DOMAIN_UNMANAGED;
 }
 
-static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
+static struct iommu_device *mtk_iommu_v1_probe_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	struct of_phandle_args iommu_spec;
-	struct mtk_iommu_data *data;
+	struct mtk_iommu_v1_data *data;
 	int err, idx = 0;
 
 	while (!of_parse_phandle_with_args(dev->of_node, "iommus",
 					   "#iommu-cells",
 					   idx, &iommu_spec)) {
 
-		err = mtk_iommu_create_mapping(dev, &iommu_spec);
+		err = mtk_iommu_v1_create_mapping(dev, &iommu_spec);
 		of_node_put(iommu_spec.np);
 		if (err)
 			return ERR_PTR(err);
@@ -483,7 +478,7 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 		idx++;
 	}
 
-	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
+	if (!fwspec || fwspec->ops != &mtk_iommu_v1_ops)
 		return ERR_PTR(-ENODEV); /* Not a iommu client device */
 
 	data = dev_iommu_priv_get(dev);
@@ -491,10 +486,10 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
 	return &data->iommu;
 }
 
-static void mtk_iommu_probe_finalize(struct device *dev)
+static void mtk_iommu_v1_probe_finalize(struct device *dev)
 {
 	struct dma_iommu_mapping *mtk_mapping;
-	struct mtk_iommu_data *data;
+	struct mtk_iommu_v1_data *data;
 	int err;
 
 	data        = dev_iommu_priv_get(dev);
@@ -505,17 +500,17 @@ static void mtk_iommu_probe_finalize(struct device *dev)
 		dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n");
 }
 
-static void mtk_iommu_release_device(struct device *dev)
+static void mtk_iommu_v1_release_device(struct device *dev)
 {
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 
-	if (!fwspec || fwspec->ops != &mtk_iommu_ops)
+	if (!fwspec || fwspec->ops != &mtk_iommu_v1_ops)
 		return;
 
 	iommu_fwspec_free(dev);
 }
 
-static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
+static int mtk_iommu_v1_hw_init(const struct mtk_iommu_v1_data *data)
 {
 	u32 regval;
 	int ret;
@@ -545,7 +540,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 
 	writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM);
 
-	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
+	if (devm_request_irq(data->dev, data->irq, mtk_iommu_v1_isr, 0,
 			     dev_name(data->dev), (void *)data)) {
 		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
 		clk_disable_unprepare(data->bclk);
@@ -556,36 +551,36 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	return 0;
 }
 
-static const struct iommu_ops mtk_iommu_ops = {
-	.domain_alloc	= mtk_iommu_domain_alloc,
-	.domain_free	= mtk_iommu_domain_free,
-	.attach_dev	= mtk_iommu_attach_device,
-	.detach_dev	= mtk_iommu_detach_device,
-	.map		= mtk_iommu_map,
-	.unmap		= mtk_iommu_unmap,
-	.iova_to_phys	= mtk_iommu_iova_to_phys,
-	.probe_device	= mtk_iommu_probe_device,
-	.probe_finalize = mtk_iommu_probe_finalize,
-	.release_device	= mtk_iommu_release_device,
-	.def_domain_type = mtk_iommu_def_domain_type,
+static const struct iommu_ops mtk_iommu_v1_ops = {
+	.domain_alloc	= mtk_iommu_v1_domain_alloc,
+	.domain_free	= mtk_iommu_v1_domain_free,
+	.attach_dev	= mtk_iommu_v1_attach_device,
+	.detach_dev	= mtk_iommu_v1_detach_device,
+	.map		= mtk_iommu_v1_map,
+	.unmap		= mtk_iommu_v1_unmap,
+	.iova_to_phys	= mtk_iommu_v1_iova_to_phys,
+	.probe_device	= mtk_iommu_v1_probe_device,
+	.probe_finalize = mtk_iommu_v1_probe_finalize,
+	.release_device	= mtk_iommu_v1_release_device,
+	.def_domain_type = mtk_iommu_v1_def_domain_type,
 	.device_group	= generic_device_group,
 	.pgsize_bitmap	= ~0UL << MT2701_IOMMU_PAGE_SHIFT,
 	.owner          = THIS_MODULE,
 };
 
-static const struct of_device_id mtk_iommu_of_ids[] = {
+static const struct of_device_id mtk_iommu_v1_of_ids[] = {
 	{ .compatible = "mediatek,mt2701-m4u", },
 	{}
 };
 
-static const struct component_master_ops mtk_iommu_com_ops = {
-	.bind		= mtk_iommu_bind,
-	.unbind		= mtk_iommu_unbind,
+static const struct component_master_ops mtk_iommu_v1_com_ops = {
+	.bind		= mtk_iommu_v1_bind,
+	.unbind		= mtk_iommu_v1_unbind,
 };
 
-static int mtk_iommu_probe(struct platform_device *pdev)
+static int mtk_iommu_v1_probe(struct platform_device *pdev)
 {
-	struct mtk_iommu_data		*data;
+	struct mtk_iommu_v1_data	*data;
 	struct device			*dev = &pdev->dev;
 	struct resource			*res;
 	struct component_match		*match = NULL;
@@ -649,7 +644,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, data);
 
-	ret = mtk_iommu_hw_init(data);
+	ret = mtk_iommu_v1_hw_init(data);
 	if (ret)
 		return ret;
 
@@ -658,17 +653,17 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	ret = iommu_device_register(&data->iommu, &mtk_iommu_ops, dev);
+	ret = iommu_device_register(&data->iommu, &mtk_iommu_v1_ops, dev);
 	if (ret)
 		goto out_sysfs_remove;
 
 	if (!iommu_present(&platform_bus_type)) {
-		ret = bus_set_iommu(&platform_bus_type,  &mtk_iommu_ops);
+		ret = bus_set_iommu(&platform_bus_type,  &mtk_iommu_v1_ops);
 		if (ret)
 			goto out_dev_unreg;
 	}
 
-	ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+	ret = component_master_add_with_match(dev, &mtk_iommu_v1_com_ops, match);
 	if (ret)
 		goto out_bus_set_null;
 	return ret;
@@ -682,9 +677,9 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	return ret;
 }
 
-static int mtk_iommu_remove(struct platform_device *pdev)
+static int mtk_iommu_v1_remove(struct platform_device *pdev)
 {
-	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
+	struct mtk_iommu_v1_data *data = platform_get_drvdata(pdev);
 
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
@@ -694,14 +689,14 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 
 	clk_disable_unprepare(data->bclk);
 	devm_free_irq(&pdev->dev, data->irq, data);
-	component_master_del(&pdev->dev, &mtk_iommu_com_ops);
+	component_master_del(&pdev->dev, &mtk_iommu_v1_com_ops);
 	return 0;
 }
 
-static int __maybe_unused mtk_iommu_suspend(struct device *dev)
+static int __maybe_unused mtk_iommu_v1_suspend(struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
-	struct mtk_iommu_suspend_reg *reg = &data->reg;
+	struct mtk_iommu_v1_data *data = dev_get_drvdata(dev);
+	struct mtk_iommu_v1_suspend_reg *reg = &data->reg;
 	void __iomem *base = data->base;
 
 	reg->standard_axi_mode = readl_relaxed(base +
@@ -712,10 +707,10 @@ static int __maybe_unused mtk_iommu_suspend(struct device *dev)
 	return 0;
 }
 
-static int __maybe_unused mtk_iommu_resume(struct device *dev)
+static int __maybe_unused mtk_iommu_v1_resume(struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
-	struct mtk_iommu_suspend_reg *reg = &data->reg;
+	struct mtk_iommu_v1_data *data = dev_get_drvdata(dev);
+	struct mtk_iommu_v1_suspend_reg *reg = &data->reg;
 	void __iomem *base = data->base;
 
 	writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR);
@@ -728,20 +723,20 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
 	return 0;
 }
 
-static const struct dev_pm_ops mtk_iommu_pm_ops = {
-	SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
+static const struct dev_pm_ops mtk_iommu_v1_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mtk_iommu_v1_suspend, mtk_iommu_v1_resume)
 };
 
-static struct platform_driver mtk_iommu_driver = {
-	.probe	= mtk_iommu_probe,
-	.remove	= mtk_iommu_remove,
+static struct platform_driver mtk_iommu_v1_driver = {
+	.probe	= mtk_iommu_v1_probe,
+	.remove	= mtk_iommu_v1_remove,
 	.driver	= {
 		.name = "mtk-iommu-v1",
-		.of_match_table = mtk_iommu_of_ids,
-		.pm = &mtk_iommu_pm_ops,
+		.of_match_table = mtk_iommu_v1_of_ids,
+		.pm = &mtk_iommu_v1_pm_ops,
 	}
 };
-module_platform_driver(mtk_iommu_driver);
+module_platform_driver(mtk_iommu_v1_driver);
 
 MODULE_DESCRIPTION("IOMMU API for MediaTek M4U v1 implementations");
 MODULE_LICENSE("GPL v2");
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:28 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:28 +0800
Subject: [PATCH v4 29/35] iommu/mediatek: Add mtk_iommu_bank_data structure
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-30-yong.wu@mediatek.com>

Prepare for supporting multi-banks for the IOMMU HW, No functional change.

Add a new structure(mtk_iommu_bank_data) for each a bank. Each a bank have
the independent HW base/IRQ/tlb-range ops, and each a bank has its special
iommu-domain(independent pgtable), thus, also move the domain information
into it.

In previous SoC, we have only one bank which could be treated as bank0(
bankid always is 0 for the previous SoC).

After adding this structure, the tlb operations and irq could use
bank_data as parameter.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 179 +++++++++++++++++++++++++-------------
 1 file changed, 117 insertions(+), 62 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index f88c7bb235bf..dc47dc0e3163 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -151,6 +151,7 @@
 #define MTK_LARB_SUBCOM_MAX	8
 
 #define MTK_IOMMU_GROUP_MAX	8
+#define MTK_IOMMU_BANK_MAX	5
 
 enum mtk_iommu_plat {
 	M4U_MT2712,
@@ -187,25 +188,36 @@ struct mtk_iommu_plat_data {
 	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
+
+	u8                  banks_num;
+	bool                banks_enable[MTK_IOMMU_BANK_MAX];
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
 };
 
-struct mtk_iommu_data {
+struct mtk_iommu_bank_data {
 	void __iomem			*base;
 	int				irq;
+	u8				id;
+	struct device			*parent_dev;
+	struct mtk_iommu_data		*parent_data;
+	spinlock_t			tlb_lock; /* lock for tlb range flush */
+	struct mtk_iommu_domain		*m4u_dom; /* Each bank has a domain */
+};
+
+struct mtk_iommu_data {
 	struct device			*dev;
 	struct clk			*bclk;
 	phys_addr_t			protect_base; /* protect memory base */
 	struct mtk_iommu_suspend_reg	reg;
-	struct mtk_iommu_domain		*m4u_dom;
 	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
 	bool                            enable_4GB;
-	spinlock_t			tlb_lock; /* lock for tlb range flush */
 
 	struct iommu_device		iommu;
 	const struct mtk_iommu_plat_data *plat_data;
 	struct device			*smicomm_dev;
 
+	struct mtk_iommu_bank_data	*bank;
+
 	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
 	struct regmap			*pericfg;
 
@@ -225,7 +237,7 @@ struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
 	struct io_pgtable_ops		*iop;
 
-	struct mtk_iommu_data		*data;
+	struct mtk_iommu_bank_data	*bank;
 	struct iommu_domain		domain;
 
 	struct mutex			mutex; /* Protect "data" in this structure */
@@ -322,20 +334,24 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 
 static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
-	void __iomem *base = data->base;
+	/* Tlb flush all always is in bank0. */
+	struct mtk_iommu_bank_data *bank = &data->bank[0];
+	void __iomem *base = bank->base;
 	unsigned long flags;
 
-	spin_lock_irqsave(&data->tlb_lock, flags);
+	spin_lock_irqsave(&bank->tlb_lock, flags);
 	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + data->plat_data->inv_sel_reg);
 	writel_relaxed(F_ALL_INVLD, base + REG_MMU_INVALIDATE);
 	wmb(); /* Make sure the tlb flush all done */
-	spin_unlock_irqrestore(&data->tlb_lock, flags);
+	spin_unlock_irqrestore(&bank->tlb_lock, flags);
 }
 
 static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
-					   struct mtk_iommu_data *data)
+					   struct mtk_iommu_bank_data *bank)
 {
-	struct list_head *head = data->hw_list;
+	struct list_head *head = bank->parent_data->hw_list;
+	struct mtk_iommu_bank_data *curbank;
+	struct mtk_iommu_data *data;
 	bool check_pm_status;
 	unsigned long flags;
 	void __iomem *base;
@@ -365,9 +381,10 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 				continue;
 		}
 
-		base = data->base;
+		curbank = &data->bank[bank->id];
+		base = curbank->base;
 
-		spin_lock_irqsave(&data->tlb_lock, flags);
+		spin_lock_irqsave(&curbank->tlb_lock, flags);
 		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
 			       base + data->plat_data->inv_sel_reg);
 
@@ -382,7 +399,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 
 		/* Clear the CPE status */
 		writel_relaxed(0, base + REG_MMU_CPE_DONE);
-		spin_unlock_irqrestore(&data->tlb_lock, flags);
+		spin_unlock_irqrestore(&curbank->tlb_lock, flags);
 
 		if (ret) {
 			dev_warn(data->dev,
@@ -397,12 +414,13 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 
 static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
-	struct mtk_iommu_data *data = dev_id;
-	struct mtk_iommu_domain *dom = data->m4u_dom;
+	struct mtk_iommu_bank_data *bank = dev_id;
+	struct mtk_iommu_data *data = bank->parent_data;
+	struct mtk_iommu_domain *dom = bank->m4u_dom;
 	unsigned int fault_larb = MTK_INVALID_LARBID, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
 	const struct mtk_iommu_plat_data *plat_data = data->plat_data;
-	void __iomem *base = data->base;
+	void __iomem *base = bank->base;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
 
@@ -441,10 +459,10 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 	}
 
-	if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
+	if (report_iommu_fault(&dom->domain, bank->parent_dev, fault_iova,
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
 		dev_err_ratelimited(
-			data->dev,
+			bank->parent_dev,
 			"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
 			int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
 			layer, write ? "write" : "read");
@@ -541,12 +559,14 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 				     unsigned int domid)
 {
 	const struct mtk_iommu_iova_region *region;
-
-	/* Use the exist domain as there is only one pgtable here. */
-	if (data->m4u_dom) {
-		dom->iop = data->m4u_dom->iop;
-		dom->cfg = data->m4u_dom->cfg;
-		dom->domain.pgsize_bitmap = data->m4u_dom->cfg.pgsize_bitmap;
+	struct mtk_iommu_domain	*m4u_dom;
+
+	/* Always use bank0 in sharing pgtable case */
+	m4u_dom = data->bank[0].m4u_dom;
+	if (m4u_dom) {
+		dom->iop = m4u_dom->iop;
+		dom->cfg = m4u_dom->cfg;
+		dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap;
 		goto update_iova_region;
 	}
 
@@ -609,6 +629,8 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	struct list_head *hw_list = data->hw_list;
 	struct device *m4udev = data->dev;
+	struct mtk_iommu_bank_data *bank;
+	unsigned int bankid = 0;
 	int ret, domid;
 
 	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
@@ -616,7 +638,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		return domid;
 
 	mutex_lock(&dom->mutex);
-	if (!dom->data) {
+	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
 		frstdata = mtk_iommu_get_frst_data(hw_list);
 
@@ -625,12 +647,13 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 			mutex_unlock(&dom->mutex);
 			return -ENODEV;
 		}
-		dom->data = data;
+		dom->bank = &data->bank[bankid];
 	}
 	mutex_unlock(&dom->mutex);
 
 	mutex_lock(&data->mutex);
-	if (!data->m4u_dom) { /* Initialize the M4U HW */
+	bank = &data->bank[bankid];
+	if (!bank->m4u_dom) { /* Initialize the M4U HW */
 		ret = pm_runtime_resume_and_get(m4udev);
 		if (ret < 0)
 			goto data_unlock;
@@ -640,9 +663,9 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 			pm_runtime_put(m4udev);
 			goto data_unlock;
 		}
-		data->m4u_dom = dom;
+		bank->m4u_dom = dom;
 		writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
-		       data->base + REG_MMU_PT_BASE_ADDR);
+		       bank->base + REG_MMU_PT_BASE_ADDR);
 
 		pm_runtime_put(m4udev);
 	}
@@ -669,7 +692,7 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
 	/* The "4GB mode" M4U physically can not use the lower remap of Dram. */
-	if (dom->data->enable_4GB)
+	if (dom->bank->parent_data->enable_4GB)
 		paddr |= BIT_ULL(32);
 
 	/* Synchronize with the tlb_lock */
@@ -690,7 +713,7 @@ static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain)
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_all(dom->data);
+	mtk_iommu_tlb_flush_all(dom->bank->parent_data);
 }
 
 static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
@@ -699,7 +722,7 @@ static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	size_t length = gather->end - gather->start + 1;
 
-	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->data);
+	mtk_iommu_tlb_flush_range_sync(gather->start, length, dom->bank);
 }
 
 static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
@@ -707,7 +730,7 @@ static void mtk_iommu_sync_map(struct iommu_domain *domain, unsigned long iova,
 {
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 
-	mtk_iommu_tlb_flush_range_sync(iova, size, dom->data);
+	mtk_iommu_tlb_flush_range_sync(iova, size, dom->bank);
 }
 
 static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -718,7 +741,7 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
 
 	pa = dom->iop->iova_to_phys(dom->iop, iova);
 	if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
-	    dom->data->enable_4GB &&
+	    dom->bank->parent_data->enable_4GB &&
 	    pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
 		pa &= ~BIT_ULL(32);
 
@@ -850,16 +873,17 @@ static const struct iommu_ops mtk_iommu_ops = {
 
 static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 {
+	const struct mtk_iommu_bank_data *bank0 = &data->bank[0];
 	u32 regval;
 
 	if (data->plat_data->m4u_plat == M4U_MT8173) {
 		regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
 			 F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU_CTRL_REG);
+		regval = readl_relaxed(bank0->base + REG_MMU_CTRL_REG);
 		regval |= F_MMU_TF_PROT_TO_PROGRAM_ADDR;
 	}
-	writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
+	writel_relaxed(regval, bank0->base + REG_MMU_CTRL_REG);
 
 	if (data->enable_4GB &&
 	    MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) {
@@ -868,31 +892,31 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		 * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30].
 		 */
 		regval = F_MMU_VLD_PA_RNG(7, 4);
-		writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG);
+		writel_relaxed(regval, bank0->base + REG_MMU_VLD_PA_RNG);
 	}
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, DCM_DISABLE))
-		writel_relaxed(F_MMU_DCM, data->base + REG_MMU_DCM_DIS);
+		writel_relaxed(F_MMU_DCM, bank0->base + REG_MMU_DCM_DIS);
 	else
-		writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
+		writel_relaxed(0, bank0->base + REG_MMU_DCM_DIS);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) {
 		/* write command throttling mode */
-		regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL);
+		regval = readl_relaxed(bank0->base + REG_MMU_WR_LEN_CTRL);
 		regval &= ~F_MMU_WR_THROT_DIS_MASK;
-		writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL);
+		writel_relaxed(regval, bank0->base + REG_MMU_WR_LEN_CTRL);
 	}
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) {
 		/* The register is called STANDARD_AXI_MODE in this case */
 		regval = 0;
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL);
+		regval = readl_relaxed(bank0->base + REG_MMU_MISC_CTRL);
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, NOT_STD_AXI_MODE))
 			regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN))
 			regval &= ~F_MMU_IN_ORDER_WR_EN_MASK;
 	}
-	writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL);
+	writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL);
 
 	regval = F_L2_MULIT_HIT_EN |
 		F_TABLE_WALK_FAULT_INT_EN |
@@ -900,7 +924,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_MISS_FIFO_OVERFLOW_INT_EN |
 		F_PREFETCH_FIFO_ERR_INT_EN |
 		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, bank0->base + REG_MMU_INT_CONTROL0);
 
 	regval = F_INT_TRANSLATION_FAULT |
 		F_INT_MAIN_MULTI_HIT_FAULT |
@@ -909,19 +933,19 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_INT_TLB_MISS_FAULT |
 		F_INT_MISS_TRANSACTION_FIFO_FAULT |
 		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
+	writel_relaxed(regval, bank0->base + REG_MMU_INT_MAIN_CONTROL);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
 		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
 	else
 		regval = lower_32_bits(data->protect_base) |
 			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
+	writel_relaxed(regval, bank0->base + REG_MMU_IVRP_PADDR);
 
-	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
-			     dev_name(data->dev), (void *)data)) {
-		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
-		dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq);
+	if (devm_request_irq(bank0->parent_dev, bank0->irq, mtk_iommu_isr, 0,
+			     dev_name(bank0->parent_dev), (void *)bank0)) {
+		writel_relaxed(0, bank0->base + REG_MMU_PT_BASE_ADDR);
+		dev_err(bank0->parent_dev, "Failed @ IRQ-%d Request\n", bank0->irq);
 		return -ENODEV;
 	}
 
@@ -1011,9 +1035,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	struct component_match  *match = NULL;
 	struct regmap		*infracfg;
 	void                    *protect;
-	int                     ret;
+	int                     ret, banks_num;
 	u32			val;
 	char                    *p;
+	struct mtk_iommu_bank_data *bank;
+	void __iomem		*base;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
@@ -1051,14 +1077,26 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(data->base))
-		return PTR_ERR(data->base);
+	base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
 	ioaddr = res->start;
 
-	data->irq = platform_get_irq(pdev, 0);
-	if (data->irq < 0)
-		return data->irq;
+	banks_num = data->plat_data->banks_num;
+	data->bank = devm_kmalloc(dev, banks_num * sizeof(*data->bank), GFP_KERNEL);
+	if (!data->bank)
+		return -ENOMEM;
+
+	bank = &data->bank[0];
+	bank->id = 0;
+	bank->base = base;
+	bank->m4u_dom = NULL;
+	bank->irq = platform_get_irq(pdev, 0);
+	if (bank->irq < 0)
+		return bank->irq;
+	bank->parent_dev = dev;
+	bank->parent_data = data;
+	spin_lock_init(&bank->tlb_lock);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
 		data->bclk = devm_clk_get(dev, "bclk");
@@ -1095,8 +1133,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	if (ret)
 		goto out_sysfs_remove;
 
-	spin_lock_init(&data->tlb_lock);
-
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
 		list_add_tail(&data->list, data->plat_data->hw_list);
 		data->hw_list = data->plat_data->hw_list;
@@ -1146,6 +1182,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 static int mtk_iommu_remove(struct platform_device *pdev)
 {
 	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
+	struct mtk_iommu_bank_data *bank = &data->bank[0];
 
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
@@ -1162,7 +1199,7 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 #endif
 	}
 	pm_runtime_disable(&pdev->dev);
-	devm_free_irq(&pdev->dev, data->irq, data);
+	devm_free_irq(&pdev->dev, bank->irq, bank);
 	return 0;
 }
 
@@ -1170,7 +1207,7 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	void __iomem *base = data->base;
+	void __iomem *base = data->bank[0].base;
 
 	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
 	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
@@ -1188,8 +1225,8 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	struct mtk_iommu_domain *m4u_dom = data->m4u_dom;
-	void __iomem *base = data->base;
+	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
+	void __iomem *base = data->bank[0].base;
 	int ret;
 
 	ret = clk_prepare_enable(data->bclk);
@@ -1237,6 +1274,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
+	.banks_num    = 1,
+	.banks_enable = {true},
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}},
 };
@@ -1246,6 +1285,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
 			 NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
+	.banks_num    = 1,
+	.banks_enable = {true},
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap  = {{0}, {1}, {2}, {3}, {5}, {7, 8}, {10}, {9}},
@@ -1256,6 +1297,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
 			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.banks_num    = 1,
+	.banks_enable = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}}, /* Linear mapping. */
@@ -1267,6 +1310,8 @@ static const struct mtk_iommu_plat_data mt8173_data = {
 			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
 			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.banks_num    = 1,
+	.banks_enable = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {1}, {2}, {3}, {4}, {5}}, /* Linear mapping. */
@@ -1276,6 +1321,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 	.m4u_plat     = M4U_MT8183,
 	.flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
+	.banks_num    = 1,
+	.banks_enable = {true},
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
 	.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
@@ -1287,6 +1334,8 @@ static const struct mtk_iommu_plat_data mt8192_data = {
 			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
 			  MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.banks_num      = 1,
+	.banks_enable   = {true},
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{0}, {1}, {4, 5}, {7}, {2}, {9, 11, 19, 20},
@@ -1299,6 +1348,8 @@ static const struct mtk_iommu_plat_data mt8195_data_infra = {
 			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIE_SUPPORT,
 	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
 	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
+	.banks_num        = 1,
+	.banks_enable     = {true},
 	.iova_region      = single_domain,
 	.iova_region_nr   = ARRAY_SIZE(single_domain),
 };
@@ -1310,6 +1361,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vdo = {
 			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
 	.hw_list        = &m4ulist,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.banks_num      = 1,
+	.banks_enable   = {true},
 	.iova_region	= mt8192_multi_dom,
 	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{2, 0}, {21}, {24}, {7}, {19}, {9, 10, 11},
@@ -1323,6 +1376,8 @@ static const struct mtk_iommu_plat_data mt8195_data_vpp = {
 			  SHARE_PGTABLE | MTK_IOMMU_TYPE_MM,
 	.hw_list        = &m4ulist,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.banks_num      = 1,
+	.banks_enable   = {true},
 	.iova_region	= mt8192_multi_dom,
 	.iova_region_nr	= ARRAY_SIZE(mt8192_multi_dom),
 	.larbid_remap   = {{1}, {3},
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:30 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:30 +0800
Subject: [PATCH v4 31/35] iommu/mediatek: Change the domid to iova_region_id
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-32-yong.wu@mediatek.com>

Prepare for adding bankid, also no functional change.

In the previous SoC, each a iova_region is a domain; In the multi-banks
case, each a bank is a domain, then the original function name
"mtk_iommu_get_domain_id" is not proper. Use "iova_region_id" instead of
"domain_id".

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 46 +++++++++++++++++++--------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c0843c67b5a7..22586d1aed72 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -478,8 +478,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int mtk_iommu_get_domain_id(struct device *dev,
-				   const struct mtk_iommu_plat_data *plat_data)
+static int mtk_iommu_get_iova_region_id(struct device *dev,
+					const struct mtk_iommu_plat_data *plat_data)
 {
 	const struct mtk_iommu_iova_region *rgn = plat_data->iova_region;
 	const struct bus_dma_region *dma_rgn = dev->dma_range_map;
@@ -509,7 +509,7 @@ static int mtk_iommu_get_domain_id(struct device *dev,
 }
 
 static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
-			    bool enable, unsigned int domid)
+			    bool enable, unsigned int regionid)
 {
 	struct mtk_smi_larb_iommu    *larb_mmu;
 	unsigned int                 larbid, portid;
@@ -525,12 +525,12 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 		if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
 			larb_mmu = &data->larb_imu[larbid];
 
-			region = data->plat_data->iova_region + domid;
+			region = data->plat_data->iova_region + regionid;
 			larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
 
-			dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
+			dev_dbg(dev, "%s iommu for larb(%s) port %d region %d rgn-bank %d.\n",
 				enable ? "enable" : "disable", dev_name(larb_mmu->dev),
-				portid, domid, larb_mmu->bank[portid]);
+				portid, regionid, larb_mmu->bank[portid]);
 
 			if (enable)
 				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
@@ -556,7 +556,7 @@ static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 				     struct mtk_iommu_data *data,
-				     unsigned int domid)
+				     unsigned int region_id)
 {
 	const struct mtk_iommu_iova_region *region;
 	struct mtk_iommu_domain	*m4u_dom;
@@ -595,7 +595,7 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
 
 update_iova_region:
 	/* Update the iova region for this domain */
-	region = data->plat_data->iova_region + domid;
+	region = data->plat_data->iova_region + region_id;
 	dom->domain.geometry.aperture_start = region->iova_base;
 	dom->domain.geometry.aperture_end = region->iova_base + region->size - 1;
 	dom->domain.geometry.force_aperture = true;
@@ -631,18 +631,18 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct device *m4udev = data->dev;
 	struct mtk_iommu_bank_data *bank;
 	unsigned int bankid = 0;
-	int ret, domid;
+	int ret, region_id;
 
-	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
-	if (domid < 0)
-		return domid;
+	region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data);
+	if (region_id < 0)
+		return region_id;
 
 	mutex_lock(&dom->mutex);
 	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
 		frstdata = mtk_iommu_get_frst_data(hw_list);
 
-		ret = mtk_iommu_domain_finalise(dom, frstdata, domid);
+		ret = mtk_iommu_domain_finalise(dom, frstdata, region_id);
 		if (ret) {
 			mutex_unlock(&dom->mutex);
 			return -ENODEV;
@@ -673,7 +673,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	}
 	mutex_unlock(&data->mutex);
 
-	return mtk_iommu_config(data, dev, true, domid);
+	return mtk_iommu_config(data, dev, true, region_id);
 
 data_unlock:
 	mutex_unlock(&data->mutex);
@@ -778,22 +778,22 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
 	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
-	int domid;
+	int regionid;
 
 	data = mtk_iommu_get_frst_data(hw_list);
 	if (!data)
 		return ERR_PTR(-ENODEV);
 
-	domid = mtk_iommu_get_domain_id(dev, data->plat_data);
-	if (domid < 0)
-		return ERR_PTR(domid);
+	regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data);
+	if (regionid < 0)
+		return ERR_PTR(regionid);
 
 	mutex_lock(&data->mutex);
-	group = data->m4u_group[domid];
+	group = data->m4u_group[regionid];
 	if (!group) {
 		group = iommu_group_alloc();
 		if (!IS_ERR(group))
-			data->m4u_group[domid] = group;
+			data->m4u_group[regionid] = group;
 	} else {
 		iommu_group_ref_get(group);
 	}
@@ -827,14 +827,14 @@ static void mtk_iommu_get_resv_regions(struct device *dev,
 				       struct list_head *head)
 {
 	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
-	unsigned int domid = mtk_iommu_get_domain_id(dev, data->plat_data), i;
+	unsigned int regionid = mtk_iommu_get_iova_region_id(dev, data->plat_data), i;
 	const struct mtk_iommu_iova_region *resv, *curdom;
 	struct iommu_resv_region *region;
 	int prot = IOMMU_WRITE | IOMMU_READ;
 
-	if ((int)domid < 0)
+	if ((int)regionid < 0)
 		return;
-	curdom = data->plat_data->iova_region + domid;
+	curdom = data->plat_data->iova_region + regionid;
 	for (i = 0; i < data->plat_data->iova_region_nr; i++) {
 		resv = data->plat_data->iova_region + i;
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:07 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:07 +0800
Subject: [PATCH v4 08/35] iommu/mediatek: Use kmalloc for protect buffer
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-9-yong.wu@mediatek.com>

No need zero for the protect buffer that is only accessed by the IOMMU HW
translation fault happened.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index e6e4ee471867..d982dfd815c6 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -794,7 +794,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	data->plat_data = of_device_get_match_data(dev);
 
 	/* Protect memory. HW will access here while translation fault.*/
-	protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL);
+	protect = devm_kmalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL);
 	if (!protect)
 		return -ENOMEM;
 	data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:15 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:15 +0800
Subject: [PATCH v4 16/35] iommu/mediatek: Add IOMMU_TYPE flag
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-17-yong.wu@mediatek.com>

Add IOMMU_TYPE definition. In the mt8195, we have another IOMMU_TYPE:
infra iommu, also there will be another APU_IOMMU, thus, use 2bits for the
IOMMU_TYPE.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 47d5f34f4db0..418ec0b7a43b 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -126,9 +126,17 @@
 #define SHARE_PGTABLE			BIT(10) /* 2 HW share pgtable */
 #define DCM_DISABLE			BIT(11)
 #define NOT_STD_AXI_MODE		BIT(12)
+/* 2 bits: iommu type */
+#define MTK_IOMMU_TYPE_MM		(0x0 << 13)
+#define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
+#define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
 
-#define MTK_IOMMU_HAS_FLAG(pdata, _x) \
-		((((pdata)->flags) & (_x)) == (_x))
+#define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
+
+#define MTK_IOMMU_HAS_FLAG_MASK(pdata, _x, mask)	\
+				((((pdata)->flags) & (mask)) == (_x))
+#define MTK_IOMMU_IS_TYPE(pdata, _x)	MTK_IOMMU_HAS_FLAG_MASK(pdata, _x,\
+							MTK_IOMMU_TYPE_MASK)
 
 struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:01 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:01 +0800
Subject: [PATCH v4 02/35] dt-bindings: mediatek: mt8195: Add binding for infra
 IOMMU
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-3-yong.wu@mediatek.com>

In mt8195, we have a new IOMMU that is for INFRA IOMMU. its masters
mainly are PCIe and USB. Different with MM IOMMU, all these masters
connect with IOMMU directly, there is no mediatek,larbs property for
infra IOMMU.

Another thing is about PCIe ports. currently the function
"of_iommu_configure_dev_id" only support the id number is 1, But our
PCIe have two ports, one is for reading and the other is for writing.
see more about the PCIe patch in this patchset. Thus, I only list
the reading id here and add the other id in our driver.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/iommu/mediatek,iommu.yaml         | 13 ++++++++++++-
 .../dt-bindings/memory/mt8195-memory-port.h    | 18 ++++++++++++++++++
 include/dt-bindings/memory/mtk-memory-port.h   |  2 ++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index 9b04630158c8..c528a299afa9 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -79,6 +79,7 @@ properties:
           - mediatek,mt8192-m4u  # generation two
           - mediatek,mt8195-iommu-vdo        # generation two
           - mediatek,mt8195-iommu-vpp        # generation two
+          - mediatek,mt8195-iommu-infra      # generation two
 
       - description: mt7623 generation one
         items:
@@ -129,7 +130,6 @@ required:
   - compatible
   - reg
   - interrupts
-  - mediatek,larbs
   - '#iommu-cells'
 
 allOf:
@@ -161,6 +161,17 @@ allOf:
       required:
         - power-domains
 
+  - if: # The IOMMUs don't have larbs.
+      not:
+        properties:
+          compatible:
+            contains:
+              const: mediatek,mt8195-iommu-infra
+
+    then:
+      required:
+        - mediatek,larbs
+
 additionalProperties: false
 
 examples:
diff --git a/include/dt-bindings/memory/mt8195-memory-port.h b/include/dt-bindings/memory/mt8195-memory-port.h
index eeafad451a1d..fe948fec0688 100644
--- a/include/dt-bindings/memory/mt8195-memory-port.h
+++ b/include/dt-bindings/memory/mt8195-memory-port.h
@@ -387,4 +387,22 @@
 #define M4U_PORT_L28_CAM_DRZS4NO_R1		MTK_M4U_ID(28, 5)
 #define M4U_PORT_L28_CAM_TNCSO_R1		MTK_M4U_ID(28, 6)
 
+/* Infra iommu ports */
+/* PCIe1: read: BIT16; write BIT17. */
+#define IOMMU_PORT_INFRA_PCIE1			MTK_IFAIOMMU_PERI_ID(16)
+/* PCIe0: read: BIT18; write BIT19. */
+#define IOMMU_PORT_INFRA_PCIE0			MTK_IFAIOMMU_PERI_ID(18)
+#define IOMMU_PORT_INFRA_SSUSB_P3_R		MTK_IFAIOMMU_PERI_ID(20)
+#define IOMMU_PORT_INFRA_SSUSB_P3_W		MTK_IFAIOMMU_PERI_ID(21)
+#define IOMMU_PORT_INFRA_SSUSB_P2_R		MTK_IFAIOMMU_PERI_ID(22)
+#define IOMMU_PORT_INFRA_SSUSB_P2_W		MTK_IFAIOMMU_PERI_ID(23)
+#define IOMMU_PORT_INFRA_SSUSB_P1_1_R		MTK_IFAIOMMU_PERI_ID(24)
+#define IOMMU_PORT_INFRA_SSUSB_P1_1_W		MTK_IFAIOMMU_PERI_ID(25)
+#define IOMMU_PORT_INFRA_SSUSB_P1_0_R		MTK_IFAIOMMU_PERI_ID(26)
+#define IOMMU_PORT_INFRA_SSUSB_P1_0_W		MTK_IFAIOMMU_PERI_ID(27)
+#define IOMMU_PORT_INFRA_SSUSB2_R		MTK_IFAIOMMU_PERI_ID(28)
+#define IOMMU_PORT_INFRA_SSUSB2_W		MTK_IFAIOMMU_PERI_ID(29)
+#define IOMMU_PORT_INFRA_SSUSB_R		MTK_IFAIOMMU_PERI_ID(30)
+#define IOMMU_PORT_INFRA_SSUSB_W		MTK_IFAIOMMU_PERI_ID(31)
+
 #endif
diff --git a/include/dt-bindings/memory/mtk-memory-port.h b/include/dt-bindings/memory/mtk-memory-port.h
index 7d64103209af..2f68a0511a25 100644
--- a/include/dt-bindings/memory/mtk-memory-port.h
+++ b/include/dt-bindings/memory/mtk-memory-port.h
@@ -12,4 +12,6 @@
 #define MTK_M4U_TO_LARB(id)		(((id) >> 5) & 0x1f)
 #define MTK_M4U_TO_PORT(id)		((id) & 0x1f)
 
+#define MTK_IFAIOMMU_PERI_ID(port)	MTK_M4U_ID(0, port)
+
 #endif
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:24 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:24 +0800
Subject: [PATCH v4 25/35] iommu/mediatek: Just move code position in hw_init
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-26-yong.wu@mediatek.com>

No functional change too, prepare for mt8195 IOMMU support bank functions.
Some global control settings are in bank0 while the other banks have
their bank independent setting. Here only move the global control
settings and the independent registers together.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 48 +++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index fdc14db5b4c0..496ed9ecd23a 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -766,30 +766,6 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
 
-	regval = F_L2_MULIT_HIT_EN |
-		F_TABLE_WALK_FAULT_INT_EN |
-		F_PREETCH_FIFO_OVERFLOW_INT_EN |
-		F_MISS_FIFO_OVERFLOW_INT_EN |
-		F_PREFETCH_FIFO_ERR_INT_EN |
-		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
-
-	regval = F_INT_TRANSLATION_FAULT |
-		F_INT_MAIN_MULTI_HIT_FAULT |
-		F_INT_INVALID_PA_FAULT |
-		F_INT_ENTRY_REPLACEMENT_FAULT |
-		F_INT_TLB_MISS_FAULT |
-		F_INT_MISS_TRANSACTION_FIFO_FAULT |
-		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
-
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
-		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
-	else
-		regval = lower_32_bits(data->protect_base) |
-			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
-
 	if (data->enable_4GB &&
 	    MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) {
 		/*
@@ -823,6 +799,30 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL);
 
+	regval = F_L2_MULIT_HIT_EN |
+		F_TABLE_WALK_FAULT_INT_EN |
+		F_PREETCH_FIFO_OVERFLOW_INT_EN |
+		F_MISS_FIFO_OVERFLOW_INT_EN |
+		F_PREFETCH_FIFO_ERR_INT_EN |
+		F_MISS_FIFO_ERR_INT_EN;
+	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+
+	regval = F_INT_TRANSLATION_FAULT |
+		F_INT_MAIN_MULTI_HIT_FAULT |
+		F_INT_INVALID_PA_FAULT |
+		F_INT_ENTRY_REPLACEMENT_FAULT |
+		F_INT_TLB_MISS_FAULT |
+		F_INT_MISS_TRANSACTION_FIFO_FAULT |
+		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
+	writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
+
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
+		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
+	else
+		regval = lower_32_bits(data->protect_base) |
+			 upper_32_bits(data->protect_base);
+	writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
+
 	if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
 			     dev_name(data->dev), (void *)data)) {
 		writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:29 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:29 +0800
Subject: [PATCH v4 30/35] iommu/mediatek: Initialise bank HW for each a bank
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-31-yong.wu@mediatek.com>

The mt8195 IOMMU HW max support 5 banks, and regarding the banks'
registers, it looks like:

 ----------------------------------------
 |bank0  | bank1 | bank2 | bank3 | bank4|
 ----------------------------------------
 |global |
 |control|         null
 |regs   |
 -----------------------------------------
 |bank   |bank   |bank   |bank   |bank   |
 |regs   |regs   |regs   |regs   |regs   |
 |       |       |       |       |       |
 -----------------------------------------

Each bank has some special bank registers and it share bank0's global
control registers. this patch initialise the bank hw with the bankid.

In the hw_init, we always initialise bank0's control register since
we don't know if the bank0 is initialised.

Additionally, About each bank's register base, always delta 0x1000.
like bank[x + 1] = bank[x] + 0x1000.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index dc47dc0e3163..c0843c67b5a7 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -270,7 +270,7 @@ static inline void mtk_iommu_unbind(struct device *dev)
 
 static const struct iommu_ops mtk_iommu_ops;
 
-static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
+static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid);
 
 #define MTK_IOMMU_TLB_ADDR(iova) ({					\
 	dma_addr_t _addr = iova;					\
@@ -653,12 +653,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 
 	mutex_lock(&data->mutex);
 	bank = &data->bank[bankid];
-	if (!bank->m4u_dom) { /* Initialize the M4U HW */
+	if (!bank->m4u_dom) { /* Initialize the M4U HW for each a BANK */
 		ret = pm_runtime_resume_and_get(m4udev);
-		if (ret < 0)
+		if (ret < 0) {
+			dev_err(m4udev, "pm get fail(%d) in attach.\n", ret);
 			goto data_unlock;
+		}
 
-		ret = mtk_iommu_hw_init(data);
+		ret = mtk_iommu_hw_init(data, bankid);
 		if (ret) {
 			pm_runtime_put(m4udev);
 			goto data_unlock;
@@ -871,11 +873,16 @@ static const struct iommu_ops mtk_iommu_ops = {
 	.owner		= THIS_MODULE,
 };
 
-static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
+static int mtk_iommu_hw_init(const struct mtk_iommu_data *data, unsigned int bankid)
 {
+	const struct mtk_iommu_bank_data *bankx = &data->bank[bankid];
 	const struct mtk_iommu_bank_data *bank0 = &data->bank[0];
 	u32 regval;
 
+	/*
+	 * Global control settings are in bank0. May re-init these global registers
+	 * since no sure if there is bank0 consumers.
+	 */
 	if (data->plat_data->m4u_plat == M4U_MT8173) {
 		regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
 			 F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
@@ -918,13 +925,14 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 	}
 	writel_relaxed(regval, bank0->base + REG_MMU_MISC_CTRL);
 
+	/* Independent settings for each bank */
 	regval = F_L2_MULIT_HIT_EN |
 		F_TABLE_WALK_FAULT_INT_EN |
 		F_PREETCH_FIFO_OVERFLOW_INT_EN |
 		F_MISS_FIFO_OVERFLOW_INT_EN |
 		F_PREFETCH_FIFO_ERR_INT_EN |
 		F_MISS_FIFO_ERR_INT_EN;
-	writel_relaxed(regval, bank0->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, bankx->base + REG_MMU_INT_CONTROL0);
 
 	regval = F_INT_TRANSLATION_FAULT |
 		F_INT_MAIN_MULTI_HIT_FAULT |
@@ -933,19 +941,19 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		F_INT_TLB_MISS_FAULT |
 		F_INT_MISS_TRANSACTION_FIFO_FAULT |
 		F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
-	writel_relaxed(regval, bank0->base + REG_MMU_INT_MAIN_CONTROL);
+	writel_relaxed(regval, bankx->base + REG_MMU_INT_MAIN_CONTROL);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR))
 		regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
 	else
 		regval = lower_32_bits(data->protect_base) |
 			 upper_32_bits(data->protect_base);
-	writel_relaxed(regval, bank0->base + REG_MMU_IVRP_PADDR);
+	writel_relaxed(regval, bankx->base + REG_MMU_IVRP_PADDR);
 
-	if (devm_request_irq(bank0->parent_dev, bank0->irq, mtk_iommu_isr, 0,
-			     dev_name(bank0->parent_dev), (void *)bank0)) {
-		writel_relaxed(0, bank0->base + REG_MMU_PT_BASE_ADDR);
-		dev_err(bank0->parent_dev, "Failed @ IRQ-%d Request\n", bank0->irq);
+	if (devm_request_irq(bankx->parent_dev, bankx->irq, mtk_iommu_isr, 0,
+			     dev_name(bankx->parent_dev), (void *)bankx)) {
+		writel_relaxed(0, bankx->base + REG_MMU_PT_BASE_ADDR);
+		dev_err(bankx->parent_dev, "Failed @ IRQ-%d Request\n", bankx->irq);
 		return -ENODEV;
 	}
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:19 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:19 +0800
Subject: [PATCH v4 20/35] iommu/mediatek: Add a PM_CLK_AO flag for infra iommu
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-21-yong.wu@mediatek.com>

The power/clock of infra iommu is always on, and it doesn't have the
device link with the master devices, then the infra iommu device's pm
statua is not active, thus we add A PM_CLK_AO flag for infra iommu.

The tlb operation is a bit not clear in this file, Comment them in the
code here.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index cf042ab74fa7..531f4750c721 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -130,6 +130,8 @@
 #define MTK_IOMMU_TYPE_MM		(0x0 << 13)
 #define MTK_IOMMU_TYPE_INFRA		(0x1 << 13)
 #define MTK_IOMMU_TYPE_MASK		(0x3 << 13)
+/* PM and clock always on. e.g. infra iommu */
+#define PM_CLK_AO			BIT(15)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x)	(!!(((pdata)->flags) & (_x)))
 
@@ -235,13 +237,33 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 					   struct mtk_iommu_data *data)
 {
 	struct list_head *head = data->hw_list;
+	bool check_pm_status;
 	unsigned long flags;
 	int ret;
 	u32 tmp;
 
 	for_each_m4u(data, head) {
-		if (pm_runtime_get_if_in_use(data->dev) <= 0)
-			continue;
+		/*
+		 * To avoid resume the iommu device frequently when the iommu device
+		 * is not active, it doesn't always call pm_runtime_get here, then tlb
+		 * flush depends on the tlb flush all in the runtime resume.
+		 *
+		 * There are 2 special cases:
+		 *
+		 * Case1: The iommu dev doesn't have power domain but has bclk. This case
+		 * should also avoid the tlb flush while the dev is not active to mute
+		 * the tlb timeout log. like mt8173.
+		 *
+		 * Case2: The power/clock of infra iommu is always on, and it doesn't
+		 * have the device link with the master devices. This case should avoid
+		 * the PM status check.
+		 */
+		check_pm_status = !MTK_IOMMU_HAS_FLAG(data->plat_data, PM_CLK_AO);
+
+		if (check_pm_status) {
+			if (pm_runtime_get_if_in_use(data->dev) <= 0)
+				continue;
+		}
 
 		spin_lock_irqsave(&data->tlb_lock, flags);
 		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
@@ -268,7 +290,8 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 			mtk_iommu_tlb_flush_all(data);
 		}
 
-		pm_runtime_put(data->dev);
+		if (check_pm_status)
+			pm_runtime_put(data->dev);
 	}
 }
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:04 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:04 +0800
Subject: [PATCH v4 05/35] iommu/mediatek: Remove clk_disable in
 mtk_iommu_remove
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-6-yong.wu@mediatek.com>

After the commit b34ea31fe013 ("iommu/mediatek: Always enable the clk on
resume"), the iommu clock is controlled by the runtime callback.
thus remove the clk control in the mtk_iommu_remove.

Otherwise, it will warning like:

echo 14018000.iommu > /sys/bus/platform/drivers/mtk-iommu/unbind

[   51.413044] ------------[ cut here ]------------
[   51.413648] vpp0_smi_iommu already disabled
[   51.414233] WARNING: CPU: 2 PID: 157 at */v5.15-rc1/kernel/mediatek/
                          drivers/clk/clk.c:952 clk_core_disable+0xb0/0xb8
[   51.417174] Hardware name: MT8195V/C(ENG) (DT)
[   51.418635] pc : clk_core_disable+0xb0/0xb8
[   51.419177] lr : clk_core_disable+0xb0/0xb8
...
[   51.429375] Call trace:
[   51.429694]  clk_core_disable+0xb0/0xb8
[   51.430193]  clk_core_disable_lock+0x24/0x40
[   51.430745]  clk_disable+0x20/0x30
[   51.431189]  mtk_iommu_remove+0x58/0x118
[   51.431705]  platform_remove+0x28/0x60
[   51.432197]  device_release_driver_internal+0x110/0x1f0
[   51.432873]  device_driver_detach+0x18/0x28
[   51.433418]  unbind_store+0xd4/0x108
[   51.433886]  drv_attr_store+0x24/0x38
[   51.434363]  sysfs_kf_write+0x40/0x58
[   51.434843]  kernfs_fop_write_iter+0x164/0x1e0

Fixes: b34ea31fe013 ("iommu/mediatek: Always enable the clk on resume")
Reported-by: Hsin-Yi Wang <hsinyi at chromium.org>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 6ccfd7bac9df..ec2c387abf60 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -921,7 +921,6 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 
 	list_del(&data->list);
 
-	clk_disable_unprepare(data->bclk);
 	device_link_remove(data->smicomm_dev, &pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	devm_free_irq(&pdev->dev, data->irq, data);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:11 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:11 +0800
Subject: [PATCH v4 12/35] iommu/mediatek: Add a flag NON_STD_AXI
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-13-yong.wu@mediatek.com>

Add a new flag NON_STD_AXI, All the previous SoC support this flag.
Prepare for adding infra and apu iommu which don't support this.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index b2361e8b06d9..80d8333797fd 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -122,6 +122,7 @@
 #define IOVA_34_EN			BIT(8)
 #define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
 #define DCM_DISABLE			BIT(10)
+#define NOT_STD_AXI_MODE		BIT(11)
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -753,7 +754,8 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
 		regval = 0;
 	} else {
 		regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL);
-		regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
+		if (MTK_IOMMU_HAS_FLAG(data->plat_data, NOT_STD_AXI_MODE))
+			regval &= ~F_MMU_STANDARD_AXI_MODE_MASK;
 		if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN))
 			regval &= ~F_MMU_IN_ORDER_WR_EN_MASK;
 	}
@@ -1022,7 +1024,8 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
-	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE,
+	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE |
+			NOT_STD_AXI_MODE,
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
@@ -1032,7 +1035,8 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
-	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN,
+	.flags         = HAS_SUB_COMM | OUT_ORDER_WR_EN | WR_THROT_EN |
+			 NOT_STD_AXI_MODE,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1041,7 +1045,7 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 
 static const struct mtk_iommu_plat_data mt8167_data = {
 	.m4u_plat     = M4U_MT8167,
-	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR,
+	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1051,7 +1055,7 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 static const struct mtk_iommu_plat_data mt8173_data = {
 	.m4u_plat     = M4U_MT8173,
 	.flags	      = HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
-			HAS_LEGACY_IVRP_PADDR,
+			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1070,7 +1074,7 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
 	.flags          = HAS_BCLK | HAS_SUB_COMM | OUT_ORDER_WR_EN |
-			  WR_THROT_EN | IOVA_34_EN,
+			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:00 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:00 +0800
Subject: [PATCH v4 01/35] dt-bindings: mediatek: mt8195: Add binding for MM
 IOMMU
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-2-yong.wu@mediatek.com>

This patch adds descriptions for mt8195 IOMMU which also use ARM
Short-Descriptor translation table format.

In mt8195, there are two smi-common HW and IOMMU, one is for vdo(video
output), the other is for vpp(video processing pipe). They connects
with different smi-larbs, then some setting(larbid_remap) is different.
Differentiate them with the compatible string.

Something like this:

    IOMMU(VDO)          IOMMU(VPP)
       |                   |
  SMI_COMMON_VDO      SMI_COMMON_VPP
  ---------------     ----------------
  |      |   ...      |      |     ...
larb0 larb2  ...    larb1 larb3    ...

Another change is that we have a new IOMMU that is for infra master like
PCIe and USB. The infra master don't have the larb and ports, thus we
rename the port header file to mt8195-memory-port.h rather than
mt8195-larb-port.h.

Also, the IOMMU is not only for MM, thus, we don't call it "m4u" which
means "MultiMedia Memory Management UNIT". thus, use the "iommu" as the
compatiable string.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/iommu/mediatek,iommu.yaml        |   7 +
 .../dt-bindings/memory/mt8195-memory-port.h   | 390 ++++++++++++++++++
 2 files changed, 397 insertions(+)
 create mode 100644 include/dt-bindings/memory/mt8195-memory-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index 0f26fe14c8e2..9b04630158c8 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -77,6 +77,8 @@ properties:
           - mediatek,mt8173-m4u  # generation two
           - mediatek,mt8183-m4u  # generation two
           - mediatek,mt8192-m4u  # generation two
+          - mediatek,mt8195-iommu-vdo        # generation two
+          - mediatek,mt8195-iommu-vpp        # generation two
 
       - description: mt7623 generation one
         items:
@@ -118,6 +120,7 @@ properties:
       dt-binding/memory/mt8173-larb-port.h for mt8173,
       dt-binding/memory/mt8183-larb-port.h for mt8183,
       dt-binding/memory/mt8192-larb-port.h for mt8192.
+      dt-binding/memory/mt8195-memory-port.h for mt8195.
 
   power-domains:
     maxItems: 1
@@ -139,6 +142,8 @@ allOf:
               - mediatek,mt2712-m4u
               - mediatek,mt8173-m4u
               - mediatek,mt8192-m4u
+              - mediatek,mt8195-iommu-vdo
+              - mediatek,mt8195-iommu-vpp
 
     then:
       required:
@@ -149,6 +154,8 @@ allOf:
         compatible:
           enum:
             - mediatek,mt8192-m4u
+            - mediatek,mt8195-iommu-vdo
+            - mediatek,mt8195-iommu-vpp
 
     then:
       required:
diff --git a/include/dt-bindings/memory/mt8195-memory-port.h b/include/dt-bindings/memory/mt8195-memory-port.h
new file mode 100644
index 000000000000..eeafad451a1d
--- /dev/null
+++ b/include/dt-bindings/memory/mt8195-memory-port.h
@@ -0,0 +1,390 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Yong Wu <yong.wu at mediatek.com>
+ */
+#ifndef _DT_BINDINGS_MEMORY_MT8195_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8195_LARB_PORT_H_
+
+#include <dt-bindings/memory/mtk-memory-port.h>
+
+/*
+ * MM IOMMU supports 16GB dma address. We separate it to four ranges:
+ * 0 ~ 4G; 4G ~ 8G; 8G ~ 12G; 12G ~ 16G, we could adjust these masters
+ * locate in anyone bank. BUT:
+ * a) Make sure all the ports inside a larb are in one range.
+ * b) The iova of any master can NOT cross the 4G/8G/12G boundary.
+ *
+ * This is the suggested mapping in this SoC:
+ *
+ * modules    dma-address-region	larbs-ports
+ * disp         0 ~ 4G                  larb0/1/2/3
+ * vcodec      4G ~ 8G                  larb19/20/21/22/23/24
+ * cam/mdp     8G ~ 12G                 the other larbs.
+ * N/A         12G ~ 16G
+ * CCU0   0x24000_0000 ~ 0x243ff_ffff   larb18: port 0/1
+ * CCU1   0x24400_0000 ~ 0x247ff_ffff   larb18: port 2/3
+ *
+ * This SoC have two IOMMU HWs, this is the detailed connected information:
+ * iommu-vdo: larb0/2/5/7/9/10/11/13/17/19/21/24/25/28
+ * iommu-vpp: larb1/3/4/6/8/12/14/16/18/20/22/23/26/27
+ */
+
+/* MM IOMMU ports */
+/* larb0 */
+#define M4U_PORT_L0_DISP_RDMA0			MTK_M4U_ID(0, 0)
+#define M4U_PORT_L0_DISP_WDMA0			MTK_M4U_ID(0, 1)
+#define M4U_PORT_L0_DISP_OVL0_RDMA0		MTK_M4U_ID(0, 2)
+#define M4U_PORT_L0_DISP_OVL0_RDMA1		MTK_M4U_ID(0, 3)
+#define M4U_PORT_L0_DISP_OVL0_HDR		MTK_M4U_ID(0, 4)
+#define M4U_PORT_L0_DISP_FAKE0			MTK_M4U_ID(0, 5)
+
+/* larb1 */
+#define M4U_PORT_L1_DISP_RDMA0			MTK_M4U_ID(1, 0)
+#define M4U_PORT_L1_DISP_WDMA0			MTK_M4U_ID(1, 1)
+#define M4U_PORT_L1_DISP_OVL0_RDMA0		MTK_M4U_ID(1, 2)
+#define M4U_PORT_L1_DISP_OVL0_RDMA1		MTK_M4U_ID(1, 3)
+#define M4U_PORT_L1_DISP_OVL0_HDR		MTK_M4U_ID(1, 4)
+#define M4U_PORT_L1_DISP_FAKE0			MTK_M4U_ID(1, 5)
+
+/* larb2 */
+#define M4U_PORT_L2_MDP_RDMA0			MTK_M4U_ID(2, 0)
+#define M4U_PORT_L2_MDP_RDMA2			MTK_M4U_ID(2, 1)
+#define M4U_PORT_L2_MDP_RDMA4			MTK_M4U_ID(2, 2)
+#define M4U_PORT_L2_MDP_RDMA6			MTK_M4U_ID(2, 3)
+#define M4U_PORT_L2_DISP_FAKE1			MTK_M4U_ID(2, 4)
+
+/* larb3 */
+#define M4U_PORT_L3_MDP_RDMA1			MTK_M4U_ID(3, 0)
+#define M4U_PORT_L3_MDP_RDMA3			MTK_M4U_ID(3, 1)
+#define M4U_PORT_L3_MDP_RDMA5			MTK_M4U_ID(3, 2)
+#define M4U_PORT_L3_MDP_RDMA7			MTK_M4U_ID(3, 3)
+#define M4U_PORT_L3_HDR_DS			MTK_M4U_ID(3, 4)
+#define M4U_PORT_L3_HDR_ADL			MTK_M4U_ID(3, 5)
+#define M4U_PORT_L3_DISP_FAKE1			MTK_M4U_ID(3, 6)
+
+/* larb4 */
+#define M4U_PORT_L4_MDP_RDMA			MTK_M4U_ID(4, 0)
+#define M4U_PORT_L4_MDP_FG			MTK_M4U_ID(4, 1)
+#define M4U_PORT_L4_MDP_OVL			MTK_M4U_ID(4, 2)
+#define M4U_PORT_L4_MDP_WROT			MTK_M4U_ID(4, 3)
+#define M4U_PORT_L4_FAKE			MTK_M4U_ID(4, 4)
+
+/* larb5 */
+#define M4U_PORT_L5_SVPP1_MDP_RDMA		MTK_M4U_ID(5, 0)
+#define M4U_PORT_L5_SVPP1_MDP_FG		MTK_M4U_ID(5, 1)
+#define M4U_PORT_L5_SVPP1_MDP_OVL		MTK_M4U_ID(5, 2)
+#define M4U_PORT_L5_SVPP1_MDP_WROT		MTK_M4U_ID(5, 3)
+#define M4U_PORT_L5_SVPP2_MDP_RDMA		MTK_M4U_ID(5, 4)
+#define M4U_PORT_L5_SVPP2_MDP_FG		MTK_M4U_ID(5, 5)
+#define M4U_PORT_L5_SVPP2_MDP_WROT		MTK_M4U_ID(5, 6)
+#define M4U_PORT_L5_FAKE			MTK_M4U_ID(5, 7)
+
+/* larb6 */
+#define M4U_PORT_L6_SVPP3_MDP_RDMA		MTK_M4U_ID(6, 0)
+#define M4U_PORT_L6_SVPP3_MDP_FG		MTK_M4U_ID(6, 1)
+#define M4U_PORT_L6_SVPP3_MDP_WROT		MTK_M4U_ID(6, 2)
+#define M4U_PORT_L6_FAKE			MTK_M4U_ID(6, 3)
+
+/* larb7 */
+#define M4U_PORT_L7_IMG_WPE_RDMA0		MTK_M4U_ID(7, 0)
+#define M4U_PORT_L7_IMG_WPE_RDMA1		MTK_M4U_ID(7, 1)
+#define M4U_PORT_L7_IMG_WPE_WDMA0		MTK_M4U_ID(7, 2)
+
+/* larb8 */
+#define M4U_PORT_L8_IMG_WPE_RDMA0		MTK_M4U_ID(8, 0)
+#define M4U_PORT_L8_IMG_WPE_RDMA1		MTK_M4U_ID(8, 1)
+#define M4U_PORT_L8_IMG_WPE_WDMA0		MTK_M4U_ID(8, 2)
+
+/* larb9 */
+#define M4U_PORT_L9_IMG_IMGI_T1_A		MTK_M4U_ID(9, 0)
+#define M4U_PORT_L9_IMG_IMGBI_T1_A		MTK_M4U_ID(9, 1)
+#define M4U_PORT_L9_IMG_IMGCI_T1_A		MTK_M4U_ID(9, 2)
+#define M4U_PORT_L9_IMG_SMTI_T1_A		MTK_M4U_ID(9, 3)
+#define M4U_PORT_L9_IMG_TNCSTI_T1_A		MTK_M4U_ID(9, 4)
+#define M4U_PORT_L9_IMG_TNCSTI_T4_A		MTK_M4U_ID(9, 5)
+#define M4U_PORT_L9_IMG_YUVO_T1_A		MTK_M4U_ID(9, 6)
+#define M4U_PORT_L9_IMG_TIMGO_T1_A		MTK_M4U_ID(9, 7)
+#define M4U_PORT_L9_IMG_YUVO_T2_A		MTK_M4U_ID(9, 8)
+#define M4U_PORT_L9_IMG_IMGI_T1_B		MTK_M4U_ID(9, 9)
+#define M4U_PORT_L9_IMG_IMGBI_T1_B		MTK_M4U_ID(9, 10)
+#define M4U_PORT_L9_IMG_IMGCI_T1_B		MTK_M4U_ID(9, 11)
+#define M4U_PORT_L9_IMG_YUVO_T5_A		MTK_M4U_ID(9, 12)
+#define M4U_PORT_L9_IMG_SMTI_T1_B		MTK_M4U_ID(9, 13)
+#define M4U_PORT_L9_IMG_TNCSO_T1_A		MTK_M4U_ID(9, 14)
+#define M4U_PORT_L9_IMG_SMTO_T1_A		MTK_M4U_ID(9, 15)
+#define M4U_PORT_L9_IMG_TNCSTO_T1_A		MTK_M4U_ID(9, 16)
+#define M4U_PORT_L9_IMG_YUVO_T2_B		MTK_M4U_ID(9, 17)
+#define M4U_PORT_L9_IMG_YUVO_T5_B		MTK_M4U_ID(9, 18)
+#define M4U_PORT_L9_IMG_SMTO_T1_B		MTK_M4U_ID(9, 19)
+
+/* larb10 */
+#define M4U_PORT_L10_IMG_IMGI_D1_A		MTK_M4U_ID(10, 0)
+#define M4U_PORT_L10_IMG_IMGCI_D1_A		MTK_M4U_ID(10, 1)
+#define M4U_PORT_L10_IMG_DEPI_D1_A		MTK_M4U_ID(10, 2)
+#define M4U_PORT_L10_IMG_DMGI_D1_A		MTK_M4U_ID(10, 3)
+#define M4U_PORT_L10_IMG_VIPI_D1_A		MTK_M4U_ID(10, 4)
+#define M4U_PORT_L10_IMG_TNRWI_D1_A		MTK_M4U_ID(10, 5)
+#define M4U_PORT_L10_IMG_RECI_D1_A		MTK_M4U_ID(10, 6)
+#define M4U_PORT_L10_IMG_SMTI_D1_A		MTK_M4U_ID(10, 7)
+#define M4U_PORT_L10_IMG_SMTI_D6_A		MTK_M4U_ID(10, 8)
+#define M4U_PORT_L10_IMG_PIMGI_P1_A		MTK_M4U_ID(10, 9)
+#define M4U_PORT_L10_IMG_PIMGBI_P1_A		MTK_M4U_ID(10, 10)
+#define M4U_PORT_L10_IMG_PIMGCI_P1_A		MTK_M4U_ID(10, 11)
+#define M4U_PORT_L10_IMG_PIMGI_P1_B		MTK_M4U_ID(10, 12)
+#define M4U_PORT_L10_IMG_PIMGBI_P1_B		MTK_M4U_ID(10, 13)
+#define M4U_PORT_L10_IMG_PIMGCI_P1_B		MTK_M4U_ID(10, 14)
+#define M4U_PORT_L10_IMG_IMG3O_D1_A		MTK_M4U_ID(10, 15)
+#define M4U_PORT_L10_IMG_IMG4O_D1_A		MTK_M4U_ID(10, 16)
+#define M4U_PORT_L10_IMG_IMG3CO_D1_A		MTK_M4U_ID(10, 17)
+#define M4U_PORT_L10_IMG_FEO_D1_A		MTK_M4U_ID(10, 18)
+#define M4U_PORT_L10_IMG_IMG2O_D1_A		MTK_M4U_ID(10, 19)
+#define M4U_PORT_L10_IMG_TNRWO_D1_A		MTK_M4U_ID(10, 20)
+#define M4U_PORT_L10_IMG_SMTO_D1_A		MTK_M4U_ID(10, 21)
+#define M4U_PORT_L10_IMG_WROT_P1_A		MTK_M4U_ID(10, 22)
+#define M4U_PORT_L10_IMG_WROT_P1_B		MTK_M4U_ID(10, 23)
+
+/* larb11 */
+#define M4U_PORT_L11_IMG_WPE_EIS_RDMA0_A	MTK_M4U_ID(11, 0)
+#define M4U_PORT_L11_IMG_WPE_EIS_RDMA1_A	MTK_M4U_ID(11, 1)
+#define M4U_PORT_L11_IMG_WPE_EIS_WDMA0_A	MTK_M4U_ID(11, 2)
+#define M4U_PORT_L11_IMG_WPE_TNR_RDMA0_A	MTK_M4U_ID(11, 3)
+#define M4U_PORT_L11_IMG_WPE_TNR_RDMA1_A	MTK_M4U_ID(11, 4)
+#define M4U_PORT_L11_IMG_WPE_TNR_WDMA0_A	MTK_M4U_ID(11, 5)
+#define M4U_PORT_L11_IMG_WPE_EIS_CQ0_A		MTK_M4U_ID(11, 6)
+#define M4U_PORT_L11_IMG_WPE_EIS_CQ1_A		MTK_M4U_ID(11, 7)
+#define M4U_PORT_L11_IMG_WPE_TNR_CQ0_A		MTK_M4U_ID(11, 8)
+#define M4U_PORT_L11_IMG_WPE_TNR_CQ1_A		MTK_M4U_ID(11, 9)
+
+/* larb12 */
+#define M4U_PORT_L12_IMG_FDVT_RDA		MTK_M4U_ID(12, 0)
+#define M4U_PORT_L12_IMG_FDVT_RDB		MTK_M4U_ID(12, 1)
+#define M4U_PORT_L12_IMG_FDVT_WRA		MTK_M4U_ID(12, 2)
+#define M4U_PORT_L12_IMG_FDVT_WRB		MTK_M4U_ID(12, 3)
+#define M4U_PORT_L12_IMG_ME_RDMA		MTK_M4U_ID(12, 4)
+#define M4U_PORT_L12_IMG_ME_WDMA		MTK_M4U_ID(12, 5)
+#define M4U_PORT_L12_IMG_DVS_RDMA		MTK_M4U_ID(12, 6)
+#define M4U_PORT_L12_IMG_DVS_WDMA		MTK_M4U_ID(12, 7)
+#define M4U_PORT_L12_IMG_DVP_RDMA		MTK_M4U_ID(12, 8)
+#define M4U_PORT_L12_IMG_DVP_WDMA		MTK_M4U_ID(12, 9)
+
+/* larb13 */
+#define M4U_PORT_L13_CAM_CAMSV_CQI_E1		MTK_M4U_ID(13, 0)
+#define M4U_PORT_L13_CAM_CAMSV_CQI_E2		MTK_M4U_ID(13, 1)
+#define M4U_PORT_L13_CAM_GCAMSV_A_IMGO_0	MTK_M4U_ID(13, 2)
+#define M4U_PORT_L13_CAM_SCAMSV_A_IMGO_0	MTK_M4U_ID(13, 3)
+#define M4U_PORT_L13_CAM_GCAMSV_B_IMGO_0	MTK_M4U_ID(13, 4)
+#define M4U_PORT_L13_CAM_GCAMSV_B_IMGO_1	MTK_M4U_ID(13, 5)
+#define M4U_PORT_L13_CAM_GCAMSV_A_UFEO_0	MTK_M4U_ID(13, 6)
+#define M4U_PORT_L13_CAM_GCAMSV_B_UFEO_0	MTK_M4U_ID(13, 7)
+#define M4U_PORT_L13_CAM_PDAI_0			MTK_M4U_ID(13, 8)
+#define M4U_PORT_L13_CAM_FAKE			MTK_M4U_ID(13, 9)
+
+/* larb14 */
+#define M4U_PORT_L14_CAM_GCAMSV_A_IMGO_1	MTK_M4U_ID(14, 0)
+#define M4U_PORT_L14_CAM_SCAMSV_A_IMGO_1	MTK_M4U_ID(14, 1)
+#define M4U_PORT_L14_CAM_GCAMSV_B_IMGO_0	MTK_M4U_ID(14, 2)
+#define M4U_PORT_L14_CAM_GCAMSV_B_IMGO_1	MTK_M4U_ID(14, 3)
+#define M4U_PORT_L14_CAM_SCAMSV_B_IMGO_0	MTK_M4U_ID(14, 4)
+#define M4U_PORT_L14_CAM_SCAMSV_B_IMGO_1	MTK_M4U_ID(14, 5)
+#define M4U_PORT_L14_CAM_IPUI			MTK_M4U_ID(14, 6)
+#define M4U_PORT_L14_CAM_IPU2I			MTK_M4U_ID(14, 7)
+#define M4U_PORT_L14_CAM_IPUO			MTK_M4U_ID(14, 8)
+#define M4U_PORT_L14_CAM_IPU2O			MTK_M4U_ID(14, 9)
+#define M4U_PORT_L14_CAM_IPU3O			MTK_M4U_ID(14, 10)
+#define M4U_PORT_L14_CAM_GCAMSV_A_UFEO_1	MTK_M4U_ID(14, 11)
+#define M4U_PORT_L14_CAM_GCAMSV_B_UFEO_1	MTK_M4U_ID(14, 12)
+#define M4U_PORT_L14_CAM_PDAI_1			MTK_M4U_ID(14, 13)
+#define M4U_PORT_L14_CAM_PDAO			MTK_M4U_ID(14, 14)
+
+/* larb15: null */
+
+/* larb16 */
+#define M4U_PORT_L16_CAM_IMGO_R1		MTK_M4U_ID(16, 0)
+#define M4U_PORT_L16_CAM_CQI_R1			MTK_M4U_ID(16, 1)
+#define M4U_PORT_L16_CAM_CQI_R2			MTK_M4U_ID(16, 2)
+#define M4U_PORT_L16_CAM_BPCI_R1		MTK_M4U_ID(16, 3)
+#define M4U_PORT_L16_CAM_LSCI_R1		MTK_M4U_ID(16, 4)
+#define M4U_PORT_L16_CAM_RAWI_R2		MTK_M4U_ID(16, 5)
+#define M4U_PORT_L16_CAM_RAWI_R3		MTK_M4U_ID(16, 6)
+#define M4U_PORT_L16_CAM_UFDI_R2		MTK_M4U_ID(16, 7)
+#define M4U_PORT_L16_CAM_UFDI_R3		MTK_M4U_ID(16, 8)
+#define M4U_PORT_L16_CAM_RAWI_R4		MTK_M4U_ID(16, 9)
+#define M4U_PORT_L16_CAM_RAWI_R5		MTK_M4U_ID(16, 10)
+#define M4U_PORT_L16_CAM_AAI_R1			MTK_M4U_ID(16, 11)
+#define M4U_PORT_L16_CAM_FHO_R1			MTK_M4U_ID(16, 12)
+#define M4U_PORT_L16_CAM_AAO_R1			MTK_M4U_ID(16, 13)
+#define M4U_PORT_L16_CAM_TSFSO_R1		MTK_M4U_ID(16, 14)
+#define M4U_PORT_L16_CAM_FLKO_R1		MTK_M4U_ID(16, 15)
+
+/* larb17 */
+#define M4U_PORT_L17_CAM_YUVO_R1		MTK_M4U_ID(17, 0)
+#define M4U_PORT_L17_CAM_YUVO_R3		MTK_M4U_ID(17, 1)
+#define M4U_PORT_L17_CAM_YUVCO_R1		MTK_M4U_ID(17, 2)
+#define M4U_PORT_L17_CAM_YUVO_R2		MTK_M4U_ID(17, 3)
+#define M4U_PORT_L17_CAM_RZH1N2TO_R1		MTK_M4U_ID(17, 4)
+#define M4U_PORT_L17_CAM_DRZS4NO_R1		MTK_M4U_ID(17, 5)
+#define M4U_PORT_L17_CAM_TNCSO_R1		MTK_M4U_ID(17, 6)
+
+/* larb18 */
+#define M4U_PORT_L18_CAM_CCUI			MTK_M4U_ID(18, 0)
+#define M4U_PORT_L18_CAM_CCUO			MTK_M4U_ID(18, 1)
+#define M4U_PORT_L18_CAM_CCUI2			MTK_M4U_ID(18, 2)
+#define M4U_PORT_L18_CAM_CCUO2			MTK_M4U_ID(18, 3)
+
+/* larb19 */
+#define M4U_PORT_L19_VENC_RCPU			MTK_M4U_ID(19, 0)
+#define M4U_PORT_L19_VENC_REC			MTK_M4U_ID(19, 1)
+#define M4U_PORT_L19_VENC_BSDMA			MTK_M4U_ID(19, 2)
+#define M4U_PORT_L19_VENC_SV_COMV		MTK_M4U_ID(19, 3)
+#define M4U_PORT_L19_VENC_RD_COMV		MTK_M4U_ID(19, 4)
+#define M4U_PORT_L19_VENC_NBM_RDMA		MTK_M4U_ID(19, 5)
+#define M4U_PORT_L19_VENC_NBM_RDMA_LITE		MTK_M4U_ID(19, 6)
+#define M4U_PORT_L19_JPGENC_Y_RDMA		MTK_M4U_ID(19, 7)
+#define M4U_PORT_L19_JPGENC_C_RDMA		MTK_M4U_ID(19, 8)
+#define M4U_PORT_L19_JPGENC_Q_TABLE		MTK_M4U_ID(19, 9)
+#define M4U_PORT_L19_VENC_SUB_W_LUMA		MTK_M4U_ID(19, 10)
+#define M4U_PORT_L19_VENC_FCS_NBM_RDMA		MTK_M4U_ID(19, 11)
+#define M4U_PORT_L19_JPGENC_BSDMA		MTK_M4U_ID(19, 12)
+#define M4U_PORT_L19_JPGDEC_WDMA0		MTK_M4U_ID(19, 13)
+#define M4U_PORT_L19_JPGDEC_BSDMA0		MTK_M4U_ID(19, 14)
+#define M4U_PORT_L19_VENC_NBM_WDMA		MTK_M4U_ID(19, 15)
+#define M4U_PORT_L19_VENC_NBM_WDMA_LITE		MTK_M4U_ID(19, 16)
+#define M4U_PORT_L19_VENC_FCS_NBM_WDMA		MTK_M4U_ID(19, 17)
+#define M4U_PORT_L19_JPGDEC_WDMA1		MTK_M4U_ID(19, 18)
+#define M4U_PORT_L19_JPGDEC_BSDMA1		MTK_M4U_ID(19, 19)
+#define M4U_PORT_L19_JPGDEC_BUFF_OFFSET1	MTK_M4U_ID(19, 20)
+#define M4U_PORT_L19_JPGDEC_BUFF_OFFSET0	MTK_M4U_ID(19, 21)
+#define M4U_PORT_L19_VENC_CUR_LUMA		MTK_M4U_ID(19, 22)
+#define M4U_PORT_L19_VENC_CUR_CHROMA		MTK_M4U_ID(19, 23)
+#define M4U_PORT_L19_VENC_REF_LUMA		MTK_M4U_ID(19, 24)
+#define M4U_PORT_L19_VENC_REF_CHROMA		MTK_M4U_ID(19, 25)
+#define M4U_PORT_L19_VENC_SUB_R_CHROMA		MTK_M4U_ID(19, 26)
+
+/* larb20 */
+#define M4U_PORT_L20_VENC_RCPU			MTK_M4U_ID(20, 0)
+#define M4U_PORT_L20_VENC_REC			MTK_M4U_ID(20, 1)
+#define M4U_PORT_L20_VENC_BSDMA			MTK_M4U_ID(20, 2)
+#define M4U_PORT_L20_VENC_SV_COMV		MTK_M4U_ID(20, 3)
+#define M4U_PORT_L20_VENC_RD_COMV		MTK_M4U_ID(20, 4)
+#define M4U_PORT_L20_VENC_NBM_RDMA		MTK_M4U_ID(20, 5)
+#define M4U_PORT_L20_VENC_NBM_RDMA_LITE		MTK_M4U_ID(20, 6)
+#define M4U_PORT_L20_JPGENC_Y_RDMA		MTK_M4U_ID(20, 7)
+#define M4U_PORT_L20_JPGENC_C_RDMA		MTK_M4U_ID(20, 8)
+#define M4U_PORT_L20_JPGENC_Q_TABLE		MTK_M4U_ID(20, 9)
+#define M4U_PORT_L20_VENC_SUB_W_LUMA		MTK_M4U_ID(20, 10)
+#define M4U_PORT_L20_VENC_FCS_NBM_RDMA		MTK_M4U_ID(20, 11)
+#define M4U_PORT_L20_JPGENC_BSDMA		MTK_M4U_ID(20, 12)
+#define M4U_PORT_L20_JPGDEC_WDMA0		MTK_M4U_ID(20, 13)
+#define M4U_PORT_L20_JPGDEC_BSDMA0		MTK_M4U_ID(20, 14)
+#define M4U_PORT_L20_VENC_NBM_WDMA		MTK_M4U_ID(20, 15)
+#define M4U_PORT_L20_VENC_NBM_WDMA_LITE		MTK_M4U_ID(20, 16)
+#define M4U_PORT_L20_VENC_FCS_NBM_WDMA		MTK_M4U_ID(20, 17)
+#define M4U_PORT_L20_JPGDEC_WDMA1		MTK_M4U_ID(20, 18)
+#define M4U_PORT_L20_JPGDEC_BSDMA1		MTK_M4U_ID(20, 19)
+#define M4U_PORT_L20_JPGDEC_BUFF_OFFSET1	MTK_M4U_ID(20, 20)
+#define M4U_PORT_L20_JPGDEC_BUFF_OFFSET0	MTK_M4U_ID(20, 21)
+#define M4U_PORT_L20_VENC_CUR_LUMA		MTK_M4U_ID(20, 22)
+#define M4U_PORT_L20_VENC_CUR_CHROMA		MTK_M4U_ID(20, 23)
+#define M4U_PORT_L20_VENC_REF_LUMA		MTK_M4U_ID(20, 24)
+#define M4U_PORT_L20_VENC_REF_CHROMA		MTK_M4U_ID(20, 25)
+#define M4U_PORT_L20_VENC_SUB_R_CHROMA		MTK_M4U_ID(20, 26)
+
+/* larb21 */
+#define M4U_PORT_L21_VDEC_MC_EXT		MTK_M4U_ID(21, 0)
+#define M4U_PORT_L21_VDEC_UFO_EXT		MTK_M4U_ID(21, 1)
+#define M4U_PORT_L21_VDEC_PP_EXT		MTK_M4U_ID(21, 2)
+#define M4U_PORT_L21_VDEC_PRED_RD_EXT		MTK_M4U_ID(21, 3)
+#define M4U_PORT_L21_VDEC_PRED_WR_EXT		MTK_M4U_ID(21, 4)
+#define M4U_PORT_L21_VDEC_PPWRAP_EXT		MTK_M4U_ID(21, 5)
+#define M4U_PORT_L21_VDEC_TILE_EXT		MTK_M4U_ID(21, 6)
+#define M4U_PORT_L21_VDEC_VLD_EXT		MTK_M4U_ID(21, 7)
+#define M4U_PORT_L21_VDEC_VLD2_EXT		MTK_M4U_ID(21, 8)
+#define M4U_PORT_L21_VDEC_AVC_MV_EXT		MTK_M4U_ID(21, 9)
+
+/* larb22 */
+#define M4U_PORT_L22_VDEC_MC_EXT		MTK_M4U_ID(22, 0)
+#define M4U_PORT_L22_VDEC_UFO_EXT		MTK_M4U_ID(22, 1)
+#define M4U_PORT_L22_VDEC_PP_EXT		MTK_M4U_ID(22, 2)
+#define M4U_PORT_L22_VDEC_PRED_RD_EXT		MTK_M4U_ID(22, 3)
+#define M4U_PORT_L22_VDEC_PRED_WR_EXT		MTK_M4U_ID(22, 4)
+#define M4U_PORT_L22_VDEC_PPWRAP_EXT		MTK_M4U_ID(22, 5)
+#define M4U_PORT_L22_VDEC_TILE_EXT		MTK_M4U_ID(22, 6)
+#define M4U_PORT_L22_VDEC_VLD_EXT		MTK_M4U_ID(22, 7)
+#define M4U_PORT_L22_VDEC_VLD2_EXT		MTK_M4U_ID(22, 8)
+#define M4U_PORT_L22_VDEC_AVC_MV_EXT		MTK_M4U_ID(22, 9)
+
+/* larb23 */
+#define M4U_PORT_L23_VDEC_UFO_ENC_EXT		MTK_M4U_ID(23, 0)
+#define M4U_PORT_L23_VDEC_RDMA_EXT		MTK_M4U_ID(23, 1)
+
+/* larb24 */
+#define M4U_PORT_L24_VDEC_LAT0_VLD_EXT		MTK_M4U_ID(24, 0)
+#define M4U_PORT_L24_VDEC_LAT0_VLD2_EXT		MTK_M4U_ID(24, 1)
+#define M4U_PORT_L24_VDEC_LAT0_AVC_MC_EXT	MTK_M4U_ID(24, 2)
+#define M4U_PORT_L24_VDEC_LAT0_PRED_RD_EXT	MTK_M4U_ID(24, 3)
+#define M4U_PORT_L24_VDEC_LAT0_TILE_EXT		MTK_M4U_ID(24, 4)
+#define M4U_PORT_L24_VDEC_LAT0_WDMA_EXT		MTK_M4U_ID(24, 5)
+#define M4U_PORT_L24_VDEC_LAT1_VLD_EXT		MTK_M4U_ID(24, 6)
+#define M4U_PORT_L24_VDEC_LAT1_VLD2_EXT		MTK_M4U_ID(24, 7)
+#define M4U_PORT_L24_VDEC_LAT1_AVC_MC_EXT	MTK_M4U_ID(24, 8)
+#define M4U_PORT_L24_VDEC_LAT1_PRED_RD_EXT	MTK_M4U_ID(24, 9)
+#define M4U_PORT_L24_VDEC_LAT1_TILE_EXT		MTK_M4U_ID(24, 10)
+#define M4U_PORT_L24_VDEC_LAT1_WDMA_EXT		MTK_M4U_ID(24, 11)
+
+/* larb25 */
+#define M4U_PORT_L25_CAM_MRAW0_LSCI_M1		MTK_M4U_ID(25, 0)
+#define M4U_PORT_L25_CAM_MRAW0_CQI_M1		MTK_M4U_ID(25, 1)
+#define M4U_PORT_L25_CAM_MRAW0_CQI_M2		MTK_M4U_ID(25, 2)
+#define M4U_PORT_L25_CAM_MRAW0_IMGO_M1		MTK_M4U_ID(25, 3)
+#define M4U_PORT_L25_CAM_MRAW0_IMGBO_M1		MTK_M4U_ID(25, 4)
+#define M4U_PORT_L25_CAM_MRAW2_LSCI_M1		MTK_M4U_ID(25, 5)
+#define M4U_PORT_L25_CAM_MRAW2_CQI_M1		MTK_M4U_ID(25, 6)
+#define M4U_PORT_L25_CAM_MRAW2_CQI_M2		MTK_M4U_ID(25, 7)
+#define M4U_PORT_L25_CAM_MRAW2_IMGO_M1		MTK_M4U_ID(25, 8)
+#define M4U_PORT_L25_CAM_MRAW2_IMGBO_M1		MTK_M4U_ID(25, 9)
+#define M4U_PORT_L25_CAM_MRAW0_AFO_M1		MTK_M4U_ID(25, 10)
+#define M4U_PORT_L25_CAM_MRAW2_AFO_M1		MTK_M4U_ID(25, 11)
+
+/* larb26 */
+#define M4U_PORT_L26_CAM_MRAW1_LSCI_M1		MTK_M4U_ID(26, 0)
+#define M4U_PORT_L26_CAM_MRAW1_CQI_M1		MTK_M4U_ID(26, 1)
+#define M4U_PORT_L26_CAM_MRAW1_CQI_M2		MTK_M4U_ID(26, 2)
+#define M4U_PORT_L26_CAM_MRAW1_IMGO_M1		MTK_M4U_ID(26, 3)
+#define M4U_PORT_L26_CAM_MRAW1_IMGBO_M1		MTK_M4U_ID(26, 4)
+#define M4U_PORT_L26_CAM_MRAW3_LSCI_M1		MTK_M4U_ID(26, 5)
+#define M4U_PORT_L26_CAM_MRAW3_CQI_M1		MTK_M4U_ID(26, 6)
+#define M4U_PORT_L26_CAM_MRAW3_CQI_M2		MTK_M4U_ID(26, 7)
+#define M4U_PORT_L26_CAM_MRAW3_IMGO_M1		MTK_M4U_ID(26, 8)
+#define M4U_PORT_L26_CAM_MRAW3_IMGBO_M1		MTK_M4U_ID(26, 9)
+#define M4U_PORT_L26_CAM_MRAW1_AFO_M1		MTK_M4U_ID(26, 10)
+#define M4U_PORT_L26_CAM_MRAW3_AFO_M1		MTK_M4U_ID(26, 11)
+
+/* larb27 */
+#define M4U_PORT_L27_CAM_IMGO_R1		MTK_M4U_ID(27, 0)
+#define M4U_PORT_L27_CAM_CQI_R1			MTK_M4U_ID(27, 1)
+#define M4U_PORT_L27_CAM_CQI_R2			MTK_M4U_ID(27, 2)
+#define M4U_PORT_L27_CAM_BPCI_R1		MTK_M4U_ID(27, 3)
+#define M4U_PORT_L27_CAM_LSCI_R1		MTK_M4U_ID(27, 4)
+#define M4U_PORT_L27_CAM_RAWI_R2		MTK_M4U_ID(27, 5)
+#define M4U_PORT_L27_CAM_RAWI_R3		MTK_M4U_ID(27, 6)
+#define M4U_PORT_L27_CAM_UFDI_R2		MTK_M4U_ID(27, 7)
+#define M4U_PORT_L27_CAM_UFDI_R3		MTK_M4U_ID(27, 8)
+#define M4U_PORT_L27_CAM_RAWI_R4		MTK_M4U_ID(27, 9)
+#define M4U_PORT_L27_CAM_RAWI_R5		MTK_M4U_ID(27, 10)
+#define M4U_PORT_L27_CAM_AAI_R1			MTK_M4U_ID(27, 11)
+#define M4U_PORT_L27_CAM_FHO_R1			MTK_M4U_ID(27, 12)
+#define M4U_PORT_L27_CAM_AAO_R1			MTK_M4U_ID(27, 13)
+#define M4U_PORT_L27_CAM_TSFSO_R1		MTK_M4U_ID(27, 14)
+#define M4U_PORT_L27_CAM_FLKO_R1		MTK_M4U_ID(27, 15)
+
+/* larb28 */
+#define M4U_PORT_L28_CAM_YUVO_R1		MTK_M4U_ID(28, 0)
+#define M4U_PORT_L28_CAM_YUVO_R3		MTK_M4U_ID(28, 1)
+#define M4U_PORT_L28_CAM_YUVCO_R1		MTK_M4U_ID(28, 2)
+#define M4U_PORT_L28_CAM_YUVO_R2		MTK_M4U_ID(28, 3)
+#define M4U_PORT_L28_CAM_RZH1N2TO_R1		MTK_M4U_ID(28, 4)
+#define M4U_PORT_L28_CAM_DRZS4NO_R1		MTK_M4U_ID(28, 5)
+#define M4U_PORT_L28_CAM_TNCSO_R1		MTK_M4U_ID(28, 6)
+
+#endif
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:23 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:23 +0800
Subject: [PATCH v4 24/35] iommu/mediatek: Only adjust code about register base
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-25-yong.wu@mediatek.com>

No functional change. Use "base" instead of the data->base. This is
avoid to touch too many lines in the next patches.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 51 +++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 68de89eff9db..fdc14db5b4c0 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -227,12 +227,12 @@ static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 
 static void mtk_iommu_tlb_flush_all(struct mtk_iommu_data *data)
 {
+	void __iomem *base = data->base;
 	unsigned long flags;
 
 	spin_lock_irqsave(&data->tlb_lock, flags);
-	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
-		       data->base + data->plat_data->inv_sel_reg);
-	writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE);
+	writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0, base + data->plat_data->inv_sel_reg);
+	writel_relaxed(F_ALL_INVLD, base + REG_MMU_INVALIDATE);
 	wmb(); /* Make sure the tlb flush all done */
 	spin_unlock_irqrestore(&data->tlb_lock, flags);
 }
@@ -243,6 +243,7 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 	struct list_head *head = data->hw_list;
 	bool check_pm_status;
 	unsigned long flags;
+	void __iomem *base;
 	int ret;
 	u32 tmp;
 
@@ -269,23 +270,23 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 				continue;
 		}
 
+		base = data->base;
+
 		spin_lock_irqsave(&data->tlb_lock, flags);
 		writel_relaxed(F_INVLD_EN1 | F_INVLD_EN0,
-			       data->base + data->plat_data->inv_sel_reg);
+			       base + data->plat_data->inv_sel_reg);
 
-		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova),
-			       data->base + REG_MMU_INVLD_START_A);
+		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova), base + REG_MMU_INVLD_START_A);
 		writel_relaxed(MTK_IOMMU_TLB_ADDR(iova + size - 1),
-			       data->base + REG_MMU_INVLD_END_A);
-		writel_relaxed(F_MMU_INV_RANGE,
-			       data->base + REG_MMU_INVALIDATE);
+			       base + REG_MMU_INVLD_END_A);
+		writel_relaxed(F_MMU_INV_RANGE, base + REG_MMU_INVALIDATE);
 
 		/* tlb sync */
-		ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE,
+		ret = readl_poll_timeout_atomic(base + REG_MMU_CPE_DONE,
 						tmp, tmp != 0, 10, 1000);
 
 		/* Clear the CPE status */
-		writel_relaxed(0, data->base + REG_MMU_CPE_DONE);
+		writel_relaxed(0, base + REG_MMU_CPE_DONE);
 		spin_unlock_irqrestore(&data->tlb_lock, flags);
 
 		if (ret) {
@@ -305,23 +306,25 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	struct mtk_iommu_domain *dom = data->m4u_dom;
 	unsigned int fault_larb = MTK_INVALID_LARBID, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
+	const struct mtk_iommu_plat_data *plat_data = data->plat_data;
+	void __iomem *base = data->base;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
 
 	/* Read error info from registers */
-	int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
+	int_state = readl_relaxed(base + REG_MMU_FAULT_ST1);
 	if (int_state & F_REG_MMU0_FAULT_MASK) {
-		regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
-		fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
-		fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
+		regval = readl_relaxed(base + REG_MMU0_INT_ID);
+		fault_iova = readl_relaxed(base + REG_MMU0_FAULT_VA);
+		fault_pa = readl_relaxed(base + REG_MMU0_INVLD_PA);
 	} else {
-		regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
-		fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
-		fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
+		regval = readl_relaxed(base + REG_MMU1_INT_ID);
+		fault_iova = readl_relaxed(base + REG_MMU1_FAULT_VA);
+		fault_pa = readl_relaxed(base + REG_MMU1_INVLD_PA);
 	}
 	layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
 	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
+	if (MTK_IOMMU_HAS_FLAG(plat_data, IOVA_34_EN)) {
 		va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
 		fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
 		fault_iova |= (u64)va34_32 << 32;
@@ -329,12 +332,12 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 	fault_pa |= (u64)pa34_32 << 32;
 
-	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+	if (MTK_IOMMU_IS_TYPE(plat_data, MTK_IOMMU_TYPE_MM)) {
 		fault_port = F_MMU_INT_ID_PORT_ID(regval);
-		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
+		if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_2BITS)) {
 			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
 			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
-		} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+		} else if (MTK_IOMMU_HAS_FLAG(plat_data, HAS_SUB_COMM_3BITS)) {
 			fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
 			sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
 		} else {
@@ -353,9 +356,9 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	}
 
 	/* Interrupt clear */
-	regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0);
+	regval = readl_relaxed(base + REG_MMU_INT_CONTROL0);
 	regval |= F_INT_CLR_BIT;
-	writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0);
+	writel_relaxed(regval, base + REG_MMU_INT_CONTROL0);
 
 	mtk_iommu_tlb_flush_all(data);
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:31 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:31 +0800
Subject: [PATCH v4 32/35] iommu/mediatek: Get the proper bankid for multi banks
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-33-yong.wu@mediatek.com>

We preassign some ports in a special bank via the new defined
banks_portmsk. Put it in the plat_data means it is not expected to be
adjusted dynamically.

If the iommu id in the iommu consumer's dtsi node is inside this
banks_portmsk, then we switch it to this special iommu bank, and
initialise the IOMMU bank HW.

Each a bank has the independent pgtable(4GB iova range). Each a bank
is a independent iommu domain/group. Currently we don't separate different
iova ranges inside a bank.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 39 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 22586d1aed72..c6de9304bbc6 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -191,6 +191,7 @@ struct mtk_iommu_plat_data {
 
 	u8                  banks_num;
 	bool                banks_enable[MTK_IOMMU_BANK_MAX];
+	unsigned int        banks_portmsk[MTK_IOMMU_BANK_MAX];
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
 };
 
@@ -478,6 +479,30 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+static unsigned int mtk_iommu_get_bank_id(struct device *dev,
+					  const struct mtk_iommu_plat_data *plat_data)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	unsigned int i, portmsk = 0, bankid = 0;
+
+	if (plat_data->banks_num == 1)
+		return bankid;
+
+	for (i = 0; i < fwspec->num_ids; i++)
+		portmsk |= BIT(MTK_M4U_TO_PORT(fwspec->ids[i]));
+
+	for (i = 0; i < plat_data->banks_num && i < MTK_IOMMU_BANK_MAX; i++) {
+		if (!plat_data->banks_enable[i])
+			continue;
+
+		if (portmsk & plat_data->banks_portmsk[i]) {
+			bankid = i;
+			break;
+		}
+	}
+	return bankid; /* default is 0 */
+}
+
 static int mtk_iommu_get_iova_region_id(struct device *dev,
 					const struct mtk_iommu_plat_data *plat_data)
 {
@@ -630,13 +655,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	struct list_head *hw_list = data->hw_list;
 	struct device *m4udev = data->dev;
 	struct mtk_iommu_bank_data *bank;
-	unsigned int bankid = 0;
+	unsigned int bankid;
 	int ret, region_id;
 
 	region_id = mtk_iommu_get_iova_region_id(dev, data->plat_data);
 	if (region_id < 0)
 		return region_id;
 
+	bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
 	mutex_lock(&dom->mutex);
 	if (!dom->bank) {
 		/* Data is in the frstdata in sharing pgtable case. */
@@ -778,6 +804,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
 	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
+	unsigned int bankid, groupid;
 	int regionid;
 
 	data = mtk_iommu_get_frst_data(hw_list);
@@ -788,12 +815,18 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	if (regionid < 0)
 		return ERR_PTR(regionid);
 
+	bankid = mtk_iommu_get_bank_id(dev, data->plat_data);
 	mutex_lock(&data->mutex);
-	group = data->m4u_group[regionid];
+	/*
+	 * If the bank function is enabled, each a bank is a iommu group/domain.
+	 * otherwise, each a iova region is a iommu group/domain.
+	 */
+	groupid = bankid ? bankid : regionid;
+	group = data->m4u_group[groupid];
 	if (!group) {
 		group = iommu_group_alloc();
 		if (!IS_ERR(group))
-			data->m4u_group[regionid] = group;
+			data->m4u_group[groupid] = group;
 	} else {
 		iommu_group_ref_get(group);
 	}
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:25 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:25 +0800
Subject: [PATCH v4 26/35] iommu/mediatek: Separate mtk_iommu_data for v1 and v2
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-27-yong.wu@mediatek.com>

Prepare for adding the structure "mtk_iommu_bank_data". No functional
change. The mtk_iommu_domain in v1 and v2 are different, we could not add
current data as bank[0] in v1 simplistically.

Currently we have no plan to add new SoC for v1, in order to avoid affect
v1 when we add many new features for v2, I totally separate v1 and v2 in
this patch, there are many structures only for v2.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c    | 82 +++++++++++++++++++++++++++++++++---
 drivers/iommu/mtk_iommu.h    | 81 -----------------------------------
 drivers/iommu/mtk_iommu_v1.c | 29 +++++++++++++
 3 files changed, 106 insertions(+), 86 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 496ed9ecd23a..80c1e5a75868 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -146,6 +146,69 @@
 
 #define MTK_INVALID_LARBID		MTK_LARB_NR_MAX
 
+#define MTK_LARB_COM_MAX	8
+#define MTK_LARB_SUBCOM_MAX	8
+
+#define MTK_IOMMU_GROUP_MAX	8
+
+enum mtk_iommu_plat {
+	M4U_MT2712,
+	M4U_MT6779,
+	M4U_MT8167,
+	M4U_MT8173,
+	M4U_MT8183,
+	M4U_MT8192,
+	M4U_MT8195,
+};
+
+struct mtk_iommu_iova_region {
+	dma_addr_t		iova_base;
+	unsigned long long	size;
+};
+
+struct mtk_iommu_plat_data {
+	enum mtk_iommu_plat			m4u_plat;
+	u32					flags;
+	u32					inv_sel_reg;
+
+	char					*pericfg_comp_str;
+	struct list_head			*hw_list;
+	unsigned int				iova_region_nr;
+	const struct mtk_iommu_iova_region	*iova_region;
+	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
+};
+
+struct mtk_iommu_data {
+	void __iomem			*base;
+	int				irq;
+	struct device			*dev;
+	struct clk			*bclk;
+	phys_addr_t			protect_base; /* protect memory base */
+	struct mtk_iommu_suspend_reg	reg;
+	struct mtk_iommu_domain		*m4u_dom;
+	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
+	bool                            enable_4GB;
+	spinlock_t			tlb_lock; /* lock for tlb range flush */
+
+	struct iommu_device		iommu;
+	const struct mtk_iommu_plat_data *plat_data;
+	struct device			*smicomm_dev;
+
+	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
+	struct regmap			*pericfg;
+
+	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
+
+	/*
+	 * In the sharing pgtable case, list data->list to the global list like m4ulist.
+	 * In the non-sharing pgtable case, list data->list to the itself hw_list_head.
+	 */
+	struct list_head		*hw_list;
+	struct list_head		hw_list_head;
+	struct list_head		list;
+	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
+};
+
 struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
 	struct io_pgtable_ops		*iop;
@@ -156,6 +219,20 @@ struct mtk_iommu_domain {
 	struct mutex			mutex; /* Protect "data" in this structure */
 };
 
+static inline int mtk_iommu_bind(struct device *dev)
+{
+	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+
+	return component_bind_all(dev, &data->larb_imu);
+}
+
+static inline void mtk_iommu_unbind(struct device *dev)
+{
+	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+
+	component_unbind_all(dev, &data->larb_imu);
+}
+
 static const struct iommu_ops mtk_iommu_ops;
 
 static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
@@ -193,11 +270,6 @@ static LIST_HEAD(m4ulist);	/* List all the M4U HWs */
 
 #define for_each_m4u(data, head)  list_for_each_entry(data, head, list)
 
-struct mtk_iommu_iova_region {
-	dma_addr_t		iova_base;
-	unsigned long long	size;
-};
-
 static const struct mtk_iommu_iova_region single_domain[] = {
 	{.iova_base = 0,		.size = SZ_4G},
 };
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 9dba98bb12eb..d332f9769f83 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -7,23 +7,14 @@
 #ifndef _MTK_IOMMU_H_
 #define _MTK_IOMMU_H_
 
-#include <linux/clk.h>
-#include <linux/component.h>
 #include <linux/device.h>
 #include <linux/io.h>
 #include <linux/io-pgtable.h>
 #include <linux/iommu.h>
-#include <linux/list.h>
 #include <linux/spinlock.h>
-#include <linux/dma-mapping.h>
 #include <soc/mediatek/smi.h>
 #include <dt-bindings/memory/mtk-memory-port.h>
 
-#define MTK_LARB_COM_MAX	8
-#define MTK_LARB_SUBCOM_MAX	8
-
-#define MTK_IOMMU_GROUP_MAX	8
-
 struct mtk_iommu_suspend_reg {
 	union {
 		u32			standard_axi_mode;/* v1 */
@@ -38,64 +29,6 @@ struct mtk_iommu_suspend_reg {
 	u32				wr_len_ctrl;
 };
 
-enum mtk_iommu_plat {
-	M4U_MT2701,
-	M4U_MT2712,
-	M4U_MT6779,
-	M4U_MT8167,
-	M4U_MT8173,
-	M4U_MT8183,
-	M4U_MT8192,
-	M4U_MT8195,
-};
-
-struct mtk_iommu_iova_region;
-
-struct mtk_iommu_plat_data {
-	enum mtk_iommu_plat m4u_plat;
-	u32                 flags;
-	u32                 inv_sel_reg;
-
-	char					*pericfg_comp_str;
-	struct list_head			*hw_list;
-	unsigned int				iova_region_nr;
-	const struct mtk_iommu_iova_region	*iova_region;
-	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
-};
-
-struct mtk_iommu_domain;
-
-struct mtk_iommu_data {
-	void __iomem			*base;
-	int				irq;
-	struct device			*dev;
-	struct clk			*bclk;
-	phys_addr_t			protect_base; /* protect memory base */
-	struct mtk_iommu_suspend_reg	reg;
-	struct mtk_iommu_domain		*m4u_dom;
-	struct iommu_group		*m4u_group[MTK_IOMMU_GROUP_MAX];
-	bool                            enable_4GB;
-	spinlock_t			tlb_lock; /* lock for tlb range flush */
-
-	struct iommu_device		iommu;
-	const struct mtk_iommu_plat_data *plat_data;
-	struct device			*smicomm_dev;
-
-	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
-	struct regmap			*pericfg;
-
-	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
-
-	/*
-	 * In the sharing pgtable case, list data->list to the global list like m4ulist.
-	 * In the non-sharing pgtable case, list data->list to the itself hw_list_head.
-	 */
-	struct list_head		*hw_list;
-	struct list_head		hw_list_head;
-	struct list_head		list;
-	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
-};
-
 static inline int compare_of(struct device *dev, void *data)
 {
 	return dev->of_node == data;
@@ -106,18 +39,4 @@ static inline void release_of(struct device *dev, void *data)
 	of_node_put(data);
 }
 
-static inline int mtk_iommu_bind(struct device *dev)
-{
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-	return component_bind_all(dev, &data->larb_imu);
-}
-
-static inline void mtk_iommu_unbind(struct device *dev)
-{
-	struct mtk_iommu_data *data = dev_get_drvdata(dev);
-
-	component_unbind_all(dev, &data->larb_imu);
-}
-
 #endif
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index be22fcf988ce..b762a05328d4 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -87,6 +87,21 @@
  */
 #define M2701_IOMMU_PGT_SIZE			SZ_4M
 
+struct mtk_iommu_data {
+	void __iomem			*base;
+	int				irq;
+	struct device			*dev;
+	struct clk			*bclk;
+	phys_addr_t			protect_base; /* protect memory base */
+	struct mtk_iommu_domain		*m4u_dom;
+
+	struct iommu_device		iommu;
+	struct dma_iommu_mapping	*mapping;
+	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
+
+	struct mtk_iommu_suspend_reg	reg;
+};
+
 struct mtk_iommu_domain {
 	spinlock_t			pgtlock; /* lock for page table */
 	struct iommu_domain		domain;
@@ -95,6 +110,20 @@ struct mtk_iommu_domain {
 	struct mtk_iommu_data		*data;
 };
 
+static inline int mtk_iommu_bind(struct device *dev)
+{
+	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+
+	return component_bind_all(dev, &data->larb_imu);
+}
+
+static inline void mtk_iommu_unbind(struct device *dev)
+{
+	struct mtk_iommu_data *data = dev_get_drvdata(dev);
+
+	component_unbind_all(dev, &data->larb_imu);
+}
+
 static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
 {
 	return container_of(dom, struct mtk_iommu_domain, domain);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:26 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:26 +0800
Subject: [PATCH v4 27/35] iommu/mediatek: Remove mtk_iommu.h
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-28-yong.wu@mediatek.com>

Currently there is only compare_of/release_of/a suspend structure in the
header file. I think it is no need to keep a header file only for these.
Move these into the c file and rm this header file.

I think there should be a common helper for compare_of and release_of.
There is many copy in drm, it should be another topic.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c    | 25 ++++++++++++++++++++-
 drivers/iommu/mtk_iommu.h    | 42 ------------------------------------
 drivers/iommu/mtk_iommu_v1.c | 21 +++++++++++++++---
 3 files changed, 42 insertions(+), 46 deletions(-)
 delete mode 100644 drivers/iommu/mtk_iommu.h

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 80c1e5a75868..f88c7bb235bf 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
+#include <linux/io-pgtable.h>
 #include <linux/list.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -30,7 +31,7 @@
 #include <asm/barrier.h>
 #include <soc/mediatek/smi.h>
 
-#include "mtk_iommu.h"
+#include <dt-bindings/memory/mtk-memory-port.h>
 
 #define REG_MMU_PT_BASE_ADDR			0x000
 #define MMU_PT_ADDR_MASK			GENMASK(31, 7)
@@ -166,6 +167,17 @@ struct mtk_iommu_iova_region {
 	unsigned long long	size;
 };
 
+struct mtk_iommu_suspend_reg {
+	u32			misc_ctrl;
+	u32			dcm_dis;
+	u32			ctrl_reg;
+	u32			int_control0;
+	u32			int_main_control;
+	u32			ivrp_paddr;
+	u32			vld_pa_rng;
+	u32			wr_len_ctrl;
+};
+
 struct mtk_iommu_plat_data {
 	enum mtk_iommu_plat			m4u_plat;
 	u32					flags;
@@ -219,6 +231,17 @@ struct mtk_iommu_domain {
 	struct mutex			mutex; /* Protect "data" in this structure */
 };
 
+/* TODO: A common helper is expected. */
+static inline int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
 static inline int mtk_iommu_bind(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
deleted file mode 100644
index d332f9769f83..000000000000
--- a/drivers/iommu/mtk_iommu.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2015-2016 MediaTek Inc.
- * Author: Honghui Zhang <honghui.zhang at mediatek.com>
- */
-
-#ifndef _MTK_IOMMU_H_
-#define _MTK_IOMMU_H_
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/io-pgtable.h>
-#include <linux/iommu.h>
-#include <linux/spinlock.h>
-#include <soc/mediatek/smi.h>
-#include <dt-bindings/memory/mtk-memory-port.h>
-
-struct mtk_iommu_suspend_reg {
-	union {
-		u32			standard_axi_mode;/* v1 */
-		u32			misc_ctrl;/* v2 */
-	};
-	u32				dcm_dis;
-	u32				ctrl_reg;
-	u32				int_control0;
-	u32				int_main_control;
-	u32				ivrp_paddr;
-	u32				vld_pa_rng;
-	u32				wr_len_ctrl;
-};
-
-static inline int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
-static inline void release_of(struct device *dev, void *data)
-{
-	of_node_put(data);
-}
-
-#endif
diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
index b762a05328d4..23c3bc175153 100644
--- a/drivers/iommu/mtk_iommu_v1.c
+++ b/drivers/iommu/mtk_iommu_v1.c
@@ -7,7 +7,6 @@
  *
  * Based on driver/iommu/mtk_iommu.c
  */
-#include <linux/memblock.h>
 #include <linux/bug.h>
 #include <linux/clk.h>
 #include <linux/component.h>
@@ -28,10 +27,9 @@
 #include <linux/spinlock.h>
 #include <asm/barrier.h>
 #include <asm/dma-iommu.h>
-#include <linux/init.h>
+#include <dt-bindings/memory/mtk-memory-port.h>
 #include <dt-bindings/memory/mt2701-larb-port.h>
 #include <soc/mediatek/smi.h>
-#include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR			0x000
 
@@ -87,6 +85,13 @@
  */
 #define M2701_IOMMU_PGT_SIZE			SZ_4M
 
+struct mtk_iommu_suspend_reg {
+	u32			standard_axi_mode;
+	u32			dcm_dis;
+	u32			ctrl_reg;
+	u32			int_control0;
+};
+
 struct mtk_iommu_data {
 	void __iomem			*base;
 	int				irq;
@@ -110,6 +115,16 @@ struct mtk_iommu_domain {
 	struct mtk_iommu_data		*data;
 };
 
+static inline int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
 static inline int mtk_iommu_bind(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:32 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:32 +0800
Subject: [PATCH v4 33/35] iommu/mediatek: Initialise/Remove for multi bank dev
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-34-yong.wu@mediatek.com>

The registers for each bank of the IOMMU base are in order, delta is
0x1000. Initialise the base for each bank.

For all the previous SoC, we only have bank0. thus use "do {} while()"
to allow bank0 always go.

When removing the device, Not always all the banks are initialised, it
depend on if there is masters for that bank.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 44 ++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index c6de9304bbc6..3a2907c19bd8 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -113,6 +113,7 @@
 #define F_MMU_INT_ID_PORT_ID(a)			(((a) >> 2) & 0x1f)
 
 #define MTK_PROTECT_PA_ALIGN			256
+#define MTK_IOMMU_BANK_SZ			0x1000
 
 #define PERICFG_IOMMU_1				0x714
 
@@ -1076,7 +1077,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	struct component_match  *match = NULL;
 	struct regmap		*infracfg;
 	void                    *protect;
-	int                     ret, banks_num;
+	int                     ret, banks_num, i = 0;
 	u32			val;
 	char                    *p;
 	struct mtk_iommu_bank_data *bank;
@@ -1117,27 +1118,36 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN);
 	}
 
+	banks_num = data->plat_data->banks_num;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (resource_size(res) < banks_num * MTK_IOMMU_BANK_SZ) {
+		dev_err(dev, "banknr %d. res %pR is not enough.\n", banks_num, res);
+		return -EINVAL;
+	}
 	base = devm_ioremap_resource(dev, res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 	ioaddr = res->start;
 
-	banks_num = data->plat_data->banks_num;
 	data->bank = devm_kmalloc(dev, banks_num * sizeof(*data->bank), GFP_KERNEL);
 	if (!data->bank)
 		return -ENOMEM;
 
-	bank = &data->bank[0];
-	bank->id = 0;
-	bank->base = base;
-	bank->m4u_dom = NULL;
-	bank->irq = platform_get_irq(pdev, 0);
-	if (bank->irq < 0)
-		return bank->irq;
-	bank->parent_dev = dev;
-	bank->parent_data = data;
-	spin_lock_init(&bank->tlb_lock);
+	do {
+		if (!data->plat_data->banks_enable[i])
+			continue;
+		bank = &data->bank[i];
+		bank->id = i;
+		bank->base = base + i * MTK_IOMMU_BANK_SZ;
+		bank->m4u_dom = NULL;
+
+		bank->irq = platform_get_irq(pdev, i);
+		if (bank->irq < 0)
+			return bank->irq;
+		bank->parent_dev = dev;
+		bank->parent_data = data;
+		spin_lock_init(&bank->tlb_lock);
+	} while (++i < banks_num);
 
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) {
 		data->bclk = devm_clk_get(dev, "bclk");
@@ -1223,7 +1233,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 static int mtk_iommu_remove(struct platform_device *pdev)
 {
 	struct mtk_iommu_data *data = platform_get_drvdata(pdev);
-	struct mtk_iommu_bank_data *bank = &data->bank[0];
+	struct mtk_iommu_bank_data *bank;
+	int i;
 
 	iommu_device_sysfs_remove(&data->iommu);
 	iommu_device_unregister(&data->iommu);
@@ -1240,7 +1251,12 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 #endif
 	}
 	pm_runtime_disable(&pdev->dev);
-	devm_free_irq(&pdev->dev, bank->irq, bank);
+	for (i = 0; i < data->plat_data->banks_num; i++) {
+		bank = &data->bank[i];
+		if (!bank->m4u_dom)
+			continue;
+		devm_free_irq(&pdev->dev, bank->irq, bank);
+	}
 	return 0;
 }
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:05 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:05 +0800
Subject: [PATCH v4 06/35] iommu/mediatek: Add mutex for m4u_group and m4u_dom
 in data
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-7-yong.wu@mediatek.com>

Add a mutex to protect the data in the structure mtk_iommu_data,
like ->"m4u_group" ->"m4u_dom". For the internal data, we should
protect it in ourselves driver. Add a mutex for this.
This could be a fix for the multi-groups support.

Fixes: c3045f39244e ("iommu/mediatek: Support for multi domains")
Signed-off-by: Yunfei Wang <yf.wang at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 13 +++++++++++--
 drivers/iommu/mtk_iommu.h |  2 ++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index ec2c387abf60..095736bfb7b4 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -464,15 +464,16 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		dom->data = data;
 	}
 
+	mutex_lock(&data->mutex);
 	if (!data->m4u_dom) { /* Initialize the M4U HW */
 		ret = pm_runtime_resume_and_get(m4udev);
 		if (ret < 0)
-			return ret;
+			goto data_unlock;
 
 		ret = mtk_iommu_hw_init(data);
 		if (ret) {
 			pm_runtime_put(m4udev);
-			return ret;
+			goto data_unlock;
 		}
 		data->m4u_dom = dom;
 		writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
@@ -480,9 +481,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 
 		pm_runtime_put(m4udev);
 	}
+	mutex_unlock(&data->mutex);
 
 	mtk_iommu_config(data, dev, true, domid);
 	return 0;
+
+data_unlock:
+	mutex_unlock(&data->mutex);
+	return ret;
 }
 
 static void mtk_iommu_detach_device(struct iommu_domain *domain,
@@ -592,6 +598,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	if (domid < 0)
 		return ERR_PTR(domid);
 
+	mutex_lock(&data->mutex);
 	group = data->m4u_group[domid];
 	if (!group) {
 		group = iommu_group_alloc();
@@ -600,6 +607,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 	} else {
 		iommu_group_ref_get(group);
 	}
+	mutex_unlock(&data->mutex);
 	return group;
 }
 
@@ -874,6 +882,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 	}
 
 	platform_set_drvdata(pdev, data);
+	mutex_init(&data->mutex);
 
 	ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
 				     "mtk-iommu.%pa", &ioaddr);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index f81fa8862ed0..f413546ac6e5 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -80,6 +80,8 @@ struct mtk_iommu_data {
 
 	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
 
+	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
+
 	struct list_head		list;
 	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
 };
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:13 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:13 +0800
Subject: [PATCH v4 14/35] iommu/mediatek: Always enable output PA over 32bits
 in isr
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-15-yong.wu@mediatek.com>

Currently the output PA[32:33] is contained by the flag IOVA_34.
This is not right. the iova_34 has no relation with pa[32:33], the 32bits
iova still could map to pa[32:33]. Move it out from the flag.

No need fix tag since currently only mt8192 use the calulation and it
always has this IOVA_34 flag.

Prepare for the IOMMU that still use IOVA 32bits but its dram size may be
over 4GB.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 028b2192c414..548fa8448a6e 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -283,11 +283,11 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, IOVA_34_EN)) {
 		va34_32 = FIELD_GET(F_MMU_INVAL_VA_34_32_MASK, fault_iova);
-		pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 		fault_iova = fault_iova & F_MMU_INVAL_VA_31_12_MASK;
 		fault_iova |= (u64)va34_32 << 32;
-		fault_pa |= (u64)pa34_32 << 32;
 	}
+	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
+	fault_pa |= (u64)pa34_32 << 32;
 
 	fault_port = F_MMU_INT_ID_PORT_ID(regval);
 	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) {
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:17 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:17 +0800
Subject: [PATCH v4 18/35] iommu/mediatek: Adjust device link when it is
 sub-common
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-19-yong.wu@mediatek.com>

For MM IOMMU, We always add device link between smi-common and IOMMU HW.
In mt8195, we add smi-sub-common. Thus, if the node is sub-common, we still
need find again to get smi-common, then do device link.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 71f3acd00d8c..f676085af13d 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -798,9 +798,9 @@ static int mtk_iommu_mm_dts_parse(struct device *dev,
 				  struct component_match **match,
 				  struct mtk_iommu_data *data)
 {
+	struct device_node *larbnode, *smicomm_node, *smi_subcomm_node;
 	struct platform_device	*plarbdev;
 	struct device_link	*link;
-	struct device_node *larbnode, *smicomm_node;
 	int i, larb_nr, ret;
 
 	larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL);
@@ -834,11 +834,21 @@ static int mtk_iommu_mm_dts_parse(struct device *dev,
 					    compare_of, larbnode);
 	}
 
-	/* Get smi-common dev from the last larb. */
-	smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
-	if (!smicomm_node)
+	/* Get smi-(sub)-common dev from the last larb. */
+	smi_subcomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+	if (!smi_subcomm_node)
 		return -EINVAL;
 
+	/*
+	 * It may have two level smi-common. the node is smi-sub-common if it
+	 * has a new mediatek,smi property. otherwise it is smi-commmon.
+	 */
+	smicomm_node = of_parse_phandle(smi_subcomm_node, "mediatek,smi", 0);
+	if (smicomm_node)
+		of_node_put(smi_subcomm_node);
+	else
+		smicomm_node = smi_subcomm_node;
+
 	plarbdev = of_find_device_by_node(smicomm_node);
 	of_node_put(smicomm_node);
 	data->smicomm_dev = &plarbdev->dev;
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:20 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:20 +0800
Subject: [PATCH v4 21/35] iommu/mediatek: Add infra iommu support
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-22-yong.wu@mediatek.com>

The infra iommu enable bits in mt8195 is in the pericfg register segment,
use regmap to update it.

If infra iommu master translation fault, It doesn't have the larbid/portid,
thus print out the whole register value.

Since regmap_update_bits may fail, add return value for mtk_iommu_config.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 36 +++++++++++++++++++++++++++++-------
 drivers/iommu/mtk_iommu.h |  2 ++
 2 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 531f4750c721..7176c212037f 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -112,6 +112,8 @@
 
 #define MTK_PROTECT_PA_ALIGN			256
 
+#define PERICFG_IOMMU_1				0x714
+
 #define HAS_4GB_MODE			BIT(0)
 /* HW will use the EMI clock if there isn't the "bclk". */
 #define HAS_BCLK			BIT(1)
@@ -343,8 +345,8 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
 		dev_err_ratelimited(
 			data->dev,
-			"fault type=0x%x iova=0x%llx pa=0x%llx larb=%d port=%d layer=%d %s\n",
-			int_state, fault_iova, fault_pa, fault_larb, fault_port,
+			"fault type=0x%x iova=0x%llx pa=0x%llx master=0x%x(larb=%d port=%d) layer=%d %s\n",
+			int_state, fault_iova, fault_pa, regval, fault_larb, fault_port,
 			layer, write ? "write" : "read");
 	}
 
@@ -388,14 +390,15 @@ static int mtk_iommu_get_domain_id(struct device *dev,
 	return -EINVAL;
 }
 
-static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
-			     bool enable, unsigned int domid)
+static int mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
+			    bool enable, unsigned int domid)
 {
 	struct mtk_smi_larb_iommu    *larb_mmu;
 	unsigned int                 larbid, portid;
 	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
 	const struct mtk_iommu_iova_region *region;
-	int i;
+	u32 peri_mmuen, peri_mmuen_msk;
+	int i, ret = 0;
 
 	for (i = 0; i < fwspec->num_ids; ++i) {
 		larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
@@ -415,8 +418,19 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
 			else
 				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+		} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA)) {
+			peri_mmuen_msk = BIT(portid);
+			peri_mmuen = enable ? peri_mmuen_msk : 0;
+
+			ret = regmap_update_bits(data->pericfg, PERICFG_IOMMU_1,
+						 peri_mmuen_msk, peri_mmuen);
+			if (ret)
+				dev_err(dev, "%s iommu(%s) inframaster 0x%x fail(%d).\n",
+					enable ? "enable" : "disable",
+					dev_name(data->dev), peri_mmuen_msk, ret);
 		}
 	}
+	return ret;
 }
 
 static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom,
@@ -531,8 +545,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	}
 	mutex_unlock(&data->mutex);
 
-	mtk_iommu_config(data, dev, true, domid);
-	return 0;
+	return mtk_iommu_config(data, dev, true, domid);
 
 data_unlock:
 	mutex_unlock(&data->mutex);
@@ -956,6 +969,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		ret = mtk_iommu_mm_dts_parse(dev, &match, data);
 		if (ret)
 			goto out_runtime_disable;
+	} else if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_INFRA) &&
+		   data->plat_data->pericfg_comp_str) {
+		infracfg = syscon_regmap_lookup_by_compatible(data->plat_data->pericfg_comp_str);
+		if (IS_ERR(infracfg)) {
+			ret = PTR_ERR(infracfg);
+			goto out_runtime_disable;
+		}
+
+		data->pericfg = infracfg;
 	}
 
 	platform_set_drvdata(pdev, data);
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index 82c51a034e6b..04e5e5e7fd62 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
 	u32                 flags;
 	u32                 inv_sel_reg;
 
+	char					*pericfg_comp_str;
 	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
@@ -80,6 +81,7 @@ struct mtk_iommu_data {
 	struct device			*smicomm_dev;
 
 	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
+	struct regmap			*pericfg;
 
 	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
 
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:09 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:09 +0800
Subject: [PATCH v4 10/35] iommu/mediatek: Add 12G~16G support for multi domains
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-11-yong.wu@mediatek.com>

In mt8192, we preassign 0-4G; 4G-8G; 8G-12G for different multimedia
engines. This depends on the "dma-ranges=" in the iommu consumer's dtsi
node.

Adds 12G-16G region here. and reword the previous comment. we don't limit
which master locate in which region.

CCU still is 8G-12G. Don't change it here.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 1712f5fcdcab..4a24977274e3 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -180,10 +180,12 @@ static const struct mtk_iommu_iova_region single_domain[] = {
 };
 
 static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {
-	{ .iova_base = 0x0,		.size = SZ_4G},		/* disp: 0 ~ 4G */
+	{ .iova_base = 0x0,		.size = SZ_4G},		/* 0 ~ 4G */
 	#if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
-	{ .iova_base = SZ_4G,		.size = SZ_4G},		/* vdec: 4G ~ 8G */
-	{ .iova_base = SZ_4G * 2,	.size = SZ_4G},		/* CAM/MDP: 8G ~ 12G */
+	{ .iova_base = SZ_4G,		.size = SZ_4G},		/* 4G ~ 8G */
+	{ .iova_base = SZ_4G * 2,	.size = SZ_4G},		/* 8G ~ 12G */
+	{ .iova_base = SZ_4G * 3,	.size = SZ_4G},		/* 12G ~ 16G */
+
 	{ .iova_base = 0x240000000ULL,	.size = 0x4000000},	/* CCU0 */
 	{ .iova_base = 0x244000000ULL,	.size = 0x4000000},	/* CCU1 */
 	#endif
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:02 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:02 +0800
Subject: [PATCH v4 03/35] iommu/mediatek: Fix 2 HW sharing pgtable issue
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-4-yong.wu@mediatek.com>

In the commit 4f956c97d26b ("iommu/mediatek: Move domain_finalise into
attach_device"), I overlooked the sharing pgtable case.
After that commit, the "data" in the mtk_iommu_domain_finalise always is
the data of the current IOMMU HW. Fix this for the sharing pgtable case.

Only affect mt2712 which is the only SoC that share pgtable currently.

Fixes: 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device")
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index eb43e7edb9dc..a92b01805232 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -446,7 +446,7 @@ static void mtk_iommu_domain_free(struct iommu_domain *domain)
 static int mtk_iommu_attach_device(struct iommu_domain *domain,
 				   struct device *dev)
 {
-	struct mtk_iommu_data *data = dev_iommu_priv_get(dev);
+	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
 	struct device *m4udev = data->dev;
 	int ret, domid;
@@ -456,7 +456,10 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 		return domid;
 
 	if (!dom->data) {
-		if (mtk_iommu_domain_finalise(dom, data, domid))
+		/* Data is in the frstdata in sharing pgtable case. */
+		frstdata = mtk_iommu_get_m4u_data();
+
+		if (mtk_iommu_domain_finalise(dom, frstdata, domid))
 			return -ENODEV;
 		dom->data = data;
 	}
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:16 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:16 +0800
Subject: [PATCH v4 17/35] iommu/mediatek: Contain MM IOMMU flow with the MM
 TYPE
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-18-yong.wu@mediatek.com>

Prepare for supporting INFRA_IOMMU, and APU_IOMMU later.

For Infra IOMMU/APU IOMMU, it doesn't have the "larb""port". thus, Use
the MM flag contain the MM_IOMMU special flow, Also, it moves a big
chunk code about parsing the mediatek,larbs into a function, this is
only needed for MM IOMMU. and all the current SoC are MM_IOMMU.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 195 ++++++++++++++++++++++----------------
 1 file changed, 111 insertions(+), 84 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 418ec0b7a43b..71f3acd00d8c 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -138,6 +138,8 @@
 #define MTK_IOMMU_IS_TYPE(pdata, _x)	MTK_IOMMU_HAS_FLAG_MASK(pdata, _x,\
 							MTK_IOMMU_TYPE_MASK)
 
+#define MTK_INVALID_LARBID		MTK_LARB_NR_MAX
+
 struct mtk_iommu_domain {
 	struct io_pgtable_cfg		cfg;
 	struct io_pgtable_ops		*iop;
@@ -274,7 +276,7 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 {
 	struct mtk_iommu_data *data = dev_id;
 	struct mtk_iommu_domain *dom = data->m4u_dom;
-	unsigned int fault_larb, fault_port, sub_comm = 0;
+	unsigned int fault_larb = MTK_INVALID_LARBID, fault_port = 0, sub_comm = 0;
 	u32 int_state, regval, va34_32, pa34_32;
 	u64 fault_iova, fault_pa;
 	bool layer, write;
@@ -300,17 +302,19 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 	pa34_32 = FIELD_GET(F_MMU_INVAL_PA_34_32_MASK, fault_iova);
 	fault_pa |= (u64)pa34_32 << 32;
 
-	fault_port = F_MMU_INT_ID_PORT_ID(regval);
-	if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
-		fault_larb = F_MMU_INT_ID_COMM_ID(regval);
-		sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
-	} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
-		fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
-		sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
-	} else {
-		fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		fault_port = F_MMU_INT_ID_PORT_ID(regval);
+		if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_2BITS)) {
+			fault_larb = F_MMU_INT_ID_COMM_ID(regval);
+			sub_comm = F_MMU_INT_ID_SUB_COMM_ID(regval);
+		} else if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM_3BITS)) {
+			fault_larb = F_MMU_INT_ID_COMM_ID_EXT(regval);
+			sub_comm = F_MMU_INT_ID_SUB_COMM_ID_EXT(regval);
+		} else {
+			fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+		}
+		fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 	}
-	fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm];
 
 	if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
 			       write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
@@ -374,19 +378,21 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, struct device *dev,
 		larbid = MTK_M4U_TO_LARB(fwspec->ids[i]);
 		portid = MTK_M4U_TO_PORT(fwspec->ids[i]);
 
-		larb_mmu = &data->larb_imu[larbid];
+		if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+			larb_mmu = &data->larb_imu[larbid];
 
-		region = data->plat_data->iova_region + domid;
-		larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
+			region = data->plat_data->iova_region + domid;
+			larb_mmu->bank[portid] = upper_32_bits(region->iova_base);
 
-		dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
-			enable ? "enable" : "disable", dev_name(larb_mmu->dev),
-			portid, domid, larb_mmu->bank[portid]);
+			dev_dbg(dev, "%s iommu for larb(%s) port %d dom %d bank %d.\n",
+				enable ? "enable" : "disable", dev_name(larb_mmu->dev),
+				portid, domid, larb_mmu->bank[portid]);
 
-		if (enable)
-			larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
-		else
-			larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+			if (enable)
+				larb_mmu->mmu |= MTK_SMI_MMU_EN(portid);
+			else
+				larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid);
+		}
 	}
 }
 
@@ -788,19 +794,75 @@ static const struct component_master_ops mtk_iommu_com_ops = {
 	.unbind		= mtk_iommu_unbind,
 };
 
+static int mtk_iommu_mm_dts_parse(struct device *dev,
+				  struct component_match **match,
+				  struct mtk_iommu_data *data)
+{
+	struct platform_device	*plarbdev;
+	struct device_link	*link;
+	struct device_node *larbnode, *smicomm_node;
+	int i, larb_nr, ret;
+
+	larb_nr = of_count_phandle_with_args(dev->of_node, "mediatek,larbs", NULL);
+	if (larb_nr < 0)
+		return larb_nr;
+
+	for (i = 0; i < larb_nr; i++) {
+		u32 id;
+
+		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
+		if (!larbnode)
+			return -EINVAL;
+
+		if (!of_device_is_available(larbnode)) {
+			of_node_put(larbnode);
+			continue;
+		}
+
+		ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
+		if (ret)/* The id is consecutive if there is no this property */
+			id = i;
+
+		plarbdev = of_find_device_by_node(larbnode);
+		if (!plarbdev) {
+			of_node_put(larbnode);
+			return -EPROBE_DEFER;
+		}
+		data->larb_imu[id].dev = &plarbdev->dev;
+
+		component_match_add_release(dev, match, release_of,
+					    compare_of, larbnode);
+	}
+
+	/* Get smi-common dev from the last larb. */
+	smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
+	if (!smicomm_node)
+		return -EINVAL;
+
+	plarbdev = of_find_device_by_node(smicomm_node);
+	of_node_put(smicomm_node);
+	data->smicomm_dev = &plarbdev->dev;
+
+	link = device_link_add(data->smicomm_dev, dev,
+			       DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
+
+	if (!link) {
+		dev_err(dev, "Unable link %s.\n", dev_name(data->smicomm_dev));
+		return PTR_ERR(link);
+	}
+	return 0;
+}
+
 static int mtk_iommu_probe(struct platform_device *pdev)
 {
 	struct mtk_iommu_data   *data;
 	struct device           *dev = &pdev->dev;
-	struct device_node	*larbnode, *smicomm_node;
-	struct platform_device	*plarbdev;
-	struct device_link	*link;
 	struct resource         *res;
 	resource_size_t		ioaddr;
 	struct component_match  *match = NULL;
 	struct regmap		*infracfg;
 	void                    *protect;
-	int                     i, larb_nr, ret;
+	int                     ret;
 	u32			val;
 	char                    *p;
 
@@ -855,55 +917,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			return PTR_ERR(data->bclk);
 	}
 
-	larb_nr = of_count_phandle_with_args(dev->of_node,
-					     "mediatek,larbs", NULL);
-	if (larb_nr < 0)
-		return larb_nr;
-
-	for (i = 0; i < larb_nr; i++) {
-		u32 id;
-
-		larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i);
-		if (!larbnode)
-			return -EINVAL;
-
-		if (!of_device_is_available(larbnode)) {
-			of_node_put(larbnode);
-			continue;
-		}
-
-		ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id);
-		if (ret)/* The id is consecutive if there is no this property */
-			id = i;
-
-		plarbdev = of_find_device_by_node(larbnode);
-		if (!plarbdev) {
-			of_node_put(larbnode);
-			return -EPROBE_DEFER;
-		}
-		data->larb_imu[id].dev = &plarbdev->dev;
-
-		component_match_add_release(dev, &match, release_of,
-					    compare_of, larbnode);
-	}
-
-	/* Get smi-common dev from the last larb. */
-	smicomm_node = of_parse_phandle(larbnode, "mediatek,smi", 0);
-	if (!smicomm_node)
-		return -EINVAL;
-
-	plarbdev = of_find_device_by_node(smicomm_node);
-	of_node_put(smicomm_node);
-	data->smicomm_dev = &plarbdev->dev;
-
 	pm_runtime_enable(dev);
 
-	link = device_link_add(data->smicomm_dev, dev,
-			DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
-	if (!link) {
-		dev_err(dev, "Unable to link %s.\n", dev_name(data->smicomm_dev));
-		ret = -EINVAL;
-		goto out_runtime_disable;
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		ret = mtk_iommu_mm_dts_parse(dev, &match, data);
+		if (ret)
+			goto out_runtime_disable;
 	}
 
 	platform_set_drvdata(pdev, data);
@@ -935,9 +954,11 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 			goto out_list_del;
 	}
 
-	ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
-	if (ret)
-		goto out_bus_set_null;
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+		if (ret)
+			goto out_bus_set_null;
+	}
 	return ret;
 
 out_bus_set_null:
@@ -948,7 +969,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 out_sysfs_remove:
 	iommu_device_sysfs_remove(&data->iommu);
 out_link_remove:
-	device_link_remove(data->smicomm_dev, dev);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+		device_link_remove(data->smicomm_dev, dev);
 out_runtime_disable:
 	pm_runtime_disable(dev);
 	return ret;
@@ -963,10 +985,12 @@ static int mtk_iommu_remove(struct platform_device *pdev)
 
 	list_del(&data->list);
 
-	device_link_remove(data->smicomm_dev, &pdev->dev);
+	if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+		device_link_remove(data->smicomm_dev, &pdev->dev);
+		component_master_del(&pdev->dev, &mtk_iommu_com_ops);
+	}
 	pm_runtime_disable(&pdev->dev);
 	devm_free_irq(&pdev->dev, data->irq, data);
-	component_master_del(&pdev->dev, &mtk_iommu_com_ops);
 	return 0;
 }
 
@@ -1037,7 +1061,7 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
 	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE |
-			NOT_STD_AXI_MODE,
+			NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
@@ -1048,7 +1072,7 @@ static const struct mtk_iommu_plat_data mt2712_data = {
 static const struct mtk_iommu_plat_data mt6779_data = {
 	.m4u_plat      = M4U_MT6779,
 	.flags         = HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN | WR_THROT_EN |
-			 NOT_STD_AXI_MODE,
+			 NOT_STD_AXI_MODE | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg   = REG_MMU_INV_SEL_GEN2,
 	.iova_region   = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1057,7 +1081,8 @@ static const struct mtk_iommu_plat_data mt6779_data = {
 
 static const struct mtk_iommu_plat_data mt8167_data = {
 	.m4u_plat     = M4U_MT8167,
-	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+	.flags        = RESET_AXI | HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1067,7 +1092,8 @@ static const struct mtk_iommu_plat_data mt8167_data = {
 static const struct mtk_iommu_plat_data mt8173_data = {
 	.m4u_plat     = M4U_MT8173,
 	.flags	      = HAS_4GB_MODE | HAS_BCLK | RESET_AXI |
-			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE,
+			HAS_LEGACY_IVRP_PADDR | NOT_STD_AXI_MODE |
+			MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1076,7 +1102,7 @@ static const struct mtk_iommu_plat_data mt8173_data = {
 
 static const struct mtk_iommu_plat_data mt8183_data = {
 	.m4u_plat     = M4U_MT8183,
-	.flags        = RESET_AXI,
+	.flags        = RESET_AXI | MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
@@ -1086,7 +1112,8 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
 	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
-			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE,
+			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
+			  MTK_IOMMU_TYPE_MM,
 	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
 	.iova_region    = mt8192_multi_dom,
 	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:08 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:08 +0800
Subject: [PATCH v4 09/35] iommu/mediatek: Adapt sharing and non-sharing
 pgtable case
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-10-yong.wu@mediatek.com>

In previous mt2712, Both IOMMUs are MM IOMMU, and they will share pgtable.
However in the latest SoC, another is infra IOMMU, there is no reason to
share pgtable between MM with INFRA IOMMU. This patch manage to
implement the two case(sharing and non-sharing pgtable).

Currently we use for_each_m4u to loop the 2 HWs. Add the list_head into
this macro.
In the sharing pgtable case, the list_head is the global "m4ulist".
In the non-sharing pgtable case, the list_head is hw_list_head which is a
variable in the "data". then for_each_m4u will only loop itself.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/iommu/mtk_iommu.c | 43 +++++++++++++++++++++------------------
 drivers/iommu/mtk_iommu.h |  7 +++++++
 2 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index d982dfd815c6..1712f5fcdcab 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -118,6 +118,7 @@
 #define WR_THROT_EN			BIT(6)
 #define HAS_LEGACY_IVRP_PADDR		BIT(7)
 #define IOVA_34_EN			BIT(8)
+#define SHARE_PGTABLE			BIT(9) /* 2 HW share pgtable */
 
 #define MTK_IOMMU_HAS_FLAG(pdata, _x) \
 		((((pdata)->flags) & (_x)) == (_x))
@@ -167,7 +168,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data);
 
 static LIST_HEAD(m4ulist);	/* List all the M4U HWs */
 
-#define for_each_m4u(data)	list_for_each_entry(data, &m4ulist, list)
+#define for_each_m4u(data, head)  list_for_each_entry(data, head, list)
 
 struct mtk_iommu_iova_region {
 	dma_addr_t		iova_base;
@@ -188,21 +189,10 @@ static const struct mtk_iommu_iova_region mt8192_multi_dom[] = {
 	#endif
 };
 
-/*
- * There may be 1 or 2 M4U HWs, But we always expect they are in the same domain
- * for the performance.
- *
- * Here always return the mtk_iommu_data of the first probed M4U where the
- * iommu domain information is recorded.
- */
-static struct mtk_iommu_data *mtk_iommu_get_m4u_data(void)
+/* If 2 M4U share a domain(use the same hwlist), Put the corresponding info in first data.*/
+static struct mtk_iommu_data *mtk_iommu_get_frst_data(struct list_head *hwlist)
 {
-	struct mtk_iommu_data *data;
-
-	for_each_m4u(data)
-		return data;
-
-	return NULL;
+	return list_first_entry(hwlist, struct mtk_iommu_data, list);
 }
 
 static struct mtk_iommu_domain *to_mtk_domain(struct iommu_domain *dom)
@@ -226,11 +216,12 @@ static void mtk_iommu_tlb_flush_range_sync(unsigned long iova, size_t size,
 					   size_t granule,
 					   struct mtk_iommu_data *data)
 {
+	struct list_head *head = data->hw_list;
 	unsigned long flags;
 	int ret;
 	u32 tmp;
 
-	for_each_m4u(data) {
+	for_each_m4u(data, head) {
 		if (pm_runtime_get_if_in_use(data->dev) <= 0)
 			continue;
 
@@ -451,6 +442,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 {
 	struct mtk_iommu_data *data = dev_iommu_priv_get(dev), *frstdata;
 	struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+	struct list_head *hw_list = data->hw_list;
 	struct device *m4udev = data->dev;
 	int ret, domid;
 
@@ -461,7 +453,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
 	mutex_lock(&dom->mutex);
 	if (!dom->data) {
 		/* Data is in the frstdata in sharing pgtable case. */
-		frstdata = mtk_iommu_get_m4u_data();
+		frstdata = mtk_iommu_get_frst_data(hw_list);
 
 		ret = mtk_iommu_domain_finalise(dom, frstdata, domid);
 		if (ret) {
@@ -595,10 +587,12 @@ static void mtk_iommu_release_device(struct device *dev)
 
 static struct iommu_group *mtk_iommu_device_group(struct device *dev)
 {
-	struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
+	struct mtk_iommu_data *c_data = dev_iommu_priv_get(dev), *data;
+	struct list_head *hw_list = c_data->hw_list;
 	struct iommu_group *group;
 	int domid;
 
+	data = mtk_iommu_get_frst_data(hw_list);
 	if (!data)
 		return ERR_PTR(-ENODEV);
 
@@ -902,7 +896,15 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 		goto out_sysfs_remove;
 
 	spin_lock_init(&data->tlb_lock);
-	list_add_tail(&data->list, &m4ulist);
+
+	if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
+		list_add_tail(&data->list, data->plat_data->hw_list);
+		data->hw_list = data->plat_data->hw_list;
+	} else {
+		INIT_LIST_HEAD(&data->hw_list_head);
+		list_add_tail(&data->list, &data->hw_list_head);
+		data->hw_list = &data->hw_list_head;
+	}
 
 	if (!iommu_present(&platform_bus_type)) {
 		ret = bus_set_iommu(&platform_bus_type, &mtk_iommu_ops);
@@ -1011,7 +1013,8 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
 
 static const struct mtk_iommu_plat_data mt2712_data = {
 	.m4u_plat     = M4U_MT2712,
-	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG,
+	.flags        = HAS_4GB_MODE | HAS_BCLK | HAS_VLD_PA_RNG | SHARE_PGTABLE,
+	.hw_list      = &m4ulist,
 	.inv_sel_reg  = REG_MMU_INV_SEL_GEN1,
 	.iova_region  = single_domain,
 	.iova_region_nr = ARRAY_SIZE(single_domain),
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index f413546ac6e5..c10f5630e55d 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -55,6 +55,7 @@ struct mtk_iommu_plat_data {
 	u32                 flags;
 	u32                 inv_sel_reg;
 
+	struct list_head			*hw_list;
 	unsigned int				iova_region_nr;
 	const struct mtk_iommu_iova_region	*iova_region;
 	unsigned char       larbid_remap[MTK_LARB_COM_MAX][MTK_LARB_SUBCOM_MAX];
@@ -82,6 +83,12 @@ struct mtk_iommu_data {
 
 	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
 
+	/*
+	 * In the sharing pgtable case, list data->list to the global list like m4ulist.
+	 * In the non-sharing pgtable case, list data->list to the itself hw_list_head.
+	 */
+	struct list_head		*hw_list;
+	struct list_head		hw_list_head;
 	struct list_head		list;
 	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
 };
-- 
2.18.0



From ceggers at arri.de  Tue Jan 25 00:52:04 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 09:52:04 +0100
Subject: [PATCH 4/6] clk: imx6q: enforce gating of gpmi_io clock
In-Reply-To: <20220125085206.8508-1-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
Message-ID: <20220125085206.8508-5-ceggers@arri.de>

Clock parent and divider changes are both glitchy for enfc_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6q.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index fd5c37095ed0..390566fca054 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -674,7 +674,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 		hws[IMX6QDL_CLK_USDHC2_SEL]       = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
 		hws[IMX6QDL_CLK_USDHC3_SEL]       = imx_clk_hw_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
 		hws[IMX6QDL_CLK_USDHC4_SEL]       = imx_clk_hw_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-		hws[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_hw_mux("enfc_sel",         base + 0x2c, 15, 3, enfc_sels_2,         ARRAY_SIZE(enfc_sels_2));
+		hws[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_hw_mux_flags("enfc_sel",         base + 0x2c, 15, 3, enfc_sels_2,         ARRAY_SIZE(enfc_sels_2), CLK_SET_PARENT_GATE);
 		hws[IMX6QDL_CLK_EIM_SEL]          = imx_clk_hw_mux("eim_sel",      base + 0x1c, 27, 2, eim_sels,        ARRAY_SIZE(eim_sels));
 		hws[IMX6QDL_CLK_EIM_SLOW_SEL]     = imx_clk_hw_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels,   ARRAY_SIZE(eim_slow_sels));
 		hws[IMX6QDL_CLK_PRE_AXI]	  = imx_clk_hw_mux("pre_axi",	base + 0x18, 1,  1, pre_axi_sels,    ARRAY_SIZE(pre_axi_sels));
@@ -864,7 +864,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	hws[IMX6QDL_CLK_PWM4]         = imx_clk_hw_gate2("pwm4",          "ipg_per",           base + 0x78, 22);
 	hws[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
 	hws[IMX6QDL_CLK_GPMI_BCH]     = imx_clk_hw_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	hws[IMX6QDL_CLK_GPMI_IO]      = imx_clk_hw_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
+	hws[IMX6QDL_CLK_GPMI_IO]      = imx_clk_hw_gate2_flags("gpmi_io",       "enfc",              base + 0x78, 28, CLK_SET_RATE_GATE);
 	hws[IMX6QDL_CLK_GPMI_APB]     = imx_clk_hw_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
 	hws[IMX6QDL_CLK_ROM]          = imx_clk_hw_gate2_flags("rom",     "ahb",               base + 0x7c, 0, CLK_IS_CRITICAL);
 	hws[IMX6QDL_CLK_SATA]         = imx_clk_hw_gate2("sata",          "ahb",               base + 0x7c, 4);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From yong.wu at mediatek.com  Tue Jan 25 00:56:34 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:34 +0800
Subject: [PATCH v4 35/35] iommu/mediatek: mt8195: Enable multi banks for infra
 iommu
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-36-yong.wu@mediatek.com>

Enable the multi-bank functions for infra-iommu. We put PCIE in bank0
and USB in the last bank(bank4). and we don't use the other banks
currently, disable them.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index a17610434868..be36e73e4bcc 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -1421,8 +1421,11 @@ static const struct mtk_iommu_plat_data mt8195_data_infra = {
 			    MTK_IOMMU_TYPE_INFRA | IFA_IOMMU_PCIE_SUPPORT,
 	.pericfg_comp_str = "mediatek,mt8195-pericfg_ao",
 	.inv_sel_reg      = REG_MMU_INV_SEL_GEN2,
-	.banks_num        = 1,
-	.banks_enable     = {true},
+	.banks_num	  = 5,
+	.banks_enable     = {true, false, false, false, true},
+	.banks_portmsk    = {[0] = GENMASK(19, 16),     /* PCIe */
+			     [4] = GENMASK(31, 20),     /* USB */
+			    },
 	.iova_region      = single_domain,
 	.iova_region_nr   = ARRAY_SIZE(single_domain),
 };
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 00:56:33 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 16:56:33 +0800
Subject: [PATCH v4 34/35] iommu/mediatek: Backup/restore regsiters for multi
 banks
In-Reply-To: <20220125085634.17972-1-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
Message-ID: <20220125085634.17972-35-yong.wu@mediatek.com>

Each bank has some independent registers. thus backup/restore them for
each a bank when suspend and resume.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 46 ++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index 3a2907c19bd8..a17610434868 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -173,11 +173,12 @@ struct mtk_iommu_suspend_reg {
 	u32			misc_ctrl;
 	u32			dcm_dis;
 	u32			ctrl_reg;
-	u32			int_control0;
-	u32			int_main_control;
-	u32			ivrp_paddr;
 	u32			vld_pa_rng;
 	u32			wr_len_ctrl;
+
+	u32			int_control[MTK_IOMMU_BANK_MAX];
+	u32			int_main_control[MTK_IOMMU_BANK_MAX];
+	u32			ivrp_paddr[MTK_IOMMU_BANK_MAX];
 };
 
 struct mtk_iommu_plat_data {
@@ -1264,16 +1265,23 @@ static int __maybe_unused mtk_iommu_runtime_suspend(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	void __iomem *base = data->bank[0].base;
+	void __iomem *base;
+	int i = 0;
 
+	base = data->bank[i].base;
 	reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL);
 	reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL);
 	reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS);
 	reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG);
-	reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
-	reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
-	reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
 	reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
+	do {
+		if (!data->plat_data->banks_enable[i])
+			continue;
+		base = data->bank[i].base;
+		reg->int_control[i] = readl_relaxed(base + REG_MMU_INT_CONTROL0);
+		reg->int_main_control[i] = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
+		reg->ivrp_paddr[i] = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+	} while (++i < data->plat_data->banks_num);
 	clk_disable_unprepare(data->bclk);
 	return 0;
 }
@@ -1282,9 +1290,9 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
 	struct mtk_iommu_suspend_reg *reg = &data->reg;
-	struct mtk_iommu_domain *m4u_dom = data->bank[0].m4u_dom;
-	void __iomem *base = data->bank[0].base;
-	int ret;
+	struct mtk_iommu_domain *m4u_dom;
+	void __iomem *base;
+	int ret, i = 0;
 
 	ret = clk_prepare_enable(data->bclk);
 	if (ret) {
@@ -1296,18 +1304,26 @@ static int __maybe_unused mtk_iommu_runtime_resume(struct device *dev)
 	 * Uppon first resume, only enable the clk and return, since the values of the
 	 * registers are not yet set.
 	 */
-	if (!m4u_dom)
+	if (!reg->wr_len_ctrl)
 		return 0;
 
+	base = data->bank[i].base;
 	writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL);
 	writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL);
 	writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS);
 	writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG);
-	writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
-	writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
-	writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
 	writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
-	writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, base + REG_MMU_PT_BASE_ADDR);
+	do {
+		m4u_dom = data->bank[i].m4u_dom;
+		if (!data->plat_data->banks_enable[i] || !m4u_dom)
+			continue;
+		base = data->bank[i].base;
+		writel_relaxed(reg->int_control[i], base + REG_MMU_INT_CONTROL0);
+		writel_relaxed(reg->int_main_control[i], base + REG_MMU_INT_MAIN_CONTROL);
+		writel_relaxed(reg->ivrp_paddr[i], base + REG_MMU_IVRP_PADDR);
+		writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
+		       base + REG_MMU_PT_BASE_ADDR);
+	} while (++i < data->plat_data->banks_num);
 
 	/*
 	 * Users may allocate dma buffer before they call pm_runtime_get,
-- 
2.18.0



From brgl at bgdev.pl  Tue Jan 25 01:13:05 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 25 Jan 2022 10:13:05 +0100
Subject: [PATCH v2 02/11] dt-bindings: gpio: fix gpio-hog example
In-Reply-To: <20220114141507.395271-3-marcel@ziswiler.com>
References: <20220114141507.395271-1-marcel@ziswiler.com>
 <20220114141507.395271-3-marcel@ziswiler.com>
Message-ID: <CAMRc=MdHeGPNMcp23aY+YTH0rz-1WjPPqozWjZE8Onnwz0V5Yg@mail.gmail.com>

On Fri, Jan 14, 2022 at 3:15 PM Marcel Ziswiler <marcel at ziswiler.com> wrote:
>
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
>
> Even if this is no yaml yet at least fix the example to be compliant to
> later schema as e.g. found in gpio-pca95xx.yaml, fairchild,74hc595.yaml
> and gpio/fsl-imx-gpio.yaml.
>
> Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Acked-by: Rob Herring <robh at kernel.org>
>
> ---
>
> Changes in v2:
> - Added Rob's ack.
>
>  Documentation/devicetree/bindings/gpio/gpio.txt | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/gpio/gpio.txt b/Documentation/devicetree/bindings/gpio/gpio.txt
> index a8895d339bfe..5663e71b751f 100644
> --- a/Documentation/devicetree/bindings/gpio/gpio.txt
> +++ b/Documentation/devicetree/bindings/gpio/gpio.txt
> @@ -213,7 +213,7 @@ Example of two SOC GPIO banks defined as gpio-controller nodes:
>                 gpio-controller;
>                 #gpio-cells = <2>;
>
> -               line_b {
> +               line_b-hog {
>                         gpio-hog;
>                         gpios = <6 0>;
>                         output-low;
> --
> 2.33.1
>

Applied, thanks!

Bart


From ardb at kernel.org  Tue Jan 25 01:14:45 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:45 +0100
Subject: [PATCH v6 0/8] ARM vmap'ed and IRQ stacks roundup
Message-ID: <20220125091453.1475246-1-ardb@kernel.org>

This v6 series is a followup to [0], and presents the proposed changes
as a set of delta patches against the v4 that was already taken into
rmk/devel-stable, and dropped from v5.17 when it turned out that were
unresolved issues related to suspend/resume.

These patches apply onto rmk/devel-stable directly, which means there is
an unresolved conflict with the changes that landed in v5.17-rc1 via the
ARM tree: these will need to be handled by the maintainer.

Code can be found under the arm-vmap-stacks-v6 tag at
git://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git

[0] https://lore.kernel.org/linux-arm-kernel/20220124174744.1054712-1-ardb at kernel.org/

Cc: Russell King <linux at armlinux.org.uk>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Kees Cook <keescook at chromium.org>
Cc: Keith Packard <keithpac at amazon.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Nick Desaulniers <ndesaulniers at google.com>
Cc: Marc Zyngier <maz at kernel.org>

Ard Biesheuvel (8):
  ARM: mm: switch to swapper_pg_dir early for vmap'ed stack
  ARM: assembler: define a Kconfig symbol for group relocation support
  ARM: smp: elide HWCAP_TLS checks or __entry_task updates on SMP+v6
  ARM: entry: avoid clobbering R9 in IRQ handler
  ARM: mm: make vmalloc_seq handling SMP safe
  ARM: iop: make iop_handle_irq() static
  ARM: drop pointless SMP check on secondary startup path
  ARM: make get_current() and __my_cpu_offset() __always_inline

 arch/arm/Kconfig                   | 13 +++++++++-
 arch/arm/include/asm/assembler.h   |  8 +++----
 arch/arm/include/asm/current.h     | 10 ++++----
 arch/arm/include/asm/mmu.h         |  2 +-
 arch/arm/include/asm/mmu_context.h | 22 +++++++++++++++--
 arch/arm/include/asm/page.h        |  3 +--
 arch/arm/include/asm/percpu.h      |  6 ++---
 arch/arm/include/asm/switch_to.h   |  4 ++--
 arch/arm/include/asm/tls.h         | 22 ++++++++++++-----
 arch/arm/kernel/entry-armv.S       |  9 ++++---
 arch/arm/kernel/entry-header.S     | 17 ++++++-------
 arch/arm/kernel/head.S             |  7 ++++++
 arch/arm/kernel/module.c           |  7 +++++-
 arch/arm/kernel/sleep.S            |  7 ++++++
 arch/arm/kernel/smp.c              |  5 ----
 arch/arm/kernel/traps.c            | 25 ++++++--------------
 arch/arm/mach-iop32x/irq.c         |  2 +-
 arch/arm/mm/context.c              |  3 +--
 arch/arm/mm/ioremap.c              | 18 ++++++++------
 19 files changed, 115 insertions(+), 75 deletions(-)

-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:46 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:46 +0100
Subject: [PATCH v6 1/8] ARM: mm: switch to swapper_pg_dir early for vmap'ed
 stack
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-2-ardb@kernel.org>

When onlining a CPU, switch to swapper_pg_dir as soon as possible so
that it is guaranteed that the vmap'ed stack is mapped before it is
used.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig        | 2 +-
 arch/arm/kernel/head.S  | 7 +++++++
 arch/arm/kernel/sleep.S | 7 +++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c32b79453ddf..359a3b85c8b3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -128,7 +128,7 @@ config ARM
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select THREAD_INFO_IN_TASK
-	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000) && !PM_SLEEP_SMP
+	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000)
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index c04dd94630c7..500612d3da2e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -424,6 +424,13 @@ ENDPROC(secondary_startup)
 ENDPROC(secondary_startup_arm)
 
 ENTRY(__secondary_switched)
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+	@ as the ID map does not cover the vmalloc region.
+	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
+	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
+	instr_sync
+#endif
 	adr_l	r7, secondary_data + 12		@ get secondary_data.stack
 	ldr	sp, [r7]
 	ldr	r0, [r7, #4]			@ get secondary_data.task
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index f909baf17912..a86a1d4f3461 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -119,6 +119,13 @@ ENTRY(cpu_resume_mmu)
 ENDPROC(cpu_resume_mmu)
 	.popsection
 cpu_resume_after_mmu:
+#if defined(CONFIG_VMAP_STACK) && !defined(CONFIG_ARM_LPAE)
+	@ Before using the vmap'ed stack, we have to switch to swapper_pg_dir
+	@ as the ID map does not cover the vmalloc region.
+	mrc	p15, 0, ip, c2, c0, 1	@ read TTBR1
+	mcr	p15, 0, ip, c2, c0, 0	@ set TTBR0
+	instr_sync
+#endif
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:47 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:47 +0100
Subject: [PATCH v6 2/8] ARM: assembler: define a Kconfig symbol for group
 relocation support
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-3-ardb@kernel.org>

Nathan reports the group relocations go out of range in pathological
cases such as allyesconfig kernels, which have little chance of actually
booting but are still used in validation.

So add a Kconfig symbol for this feature, and make it depend on
!COMPILE_TEST.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig                 | 13 ++++++++++++-
 arch/arm/include/asm/assembler.h |  8 ++++----
 arch/arm/include/asm/current.h   |  8 ++++----
 arch/arm/include/asm/percpu.h    |  4 ++--
 arch/arm/kernel/module.c         |  7 ++++++-
 5 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 359a3b85c8b3..70ab8d807032 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -128,7 +128,7 @@ config ARM
 	select RTC_LIB
 	select SYS_SUPPORTS_APM_EMULATION
 	select THREAD_INFO_IN_TASK
-	select HAVE_ARCH_VMAP_STACK if MMU && (!LD_IS_LLD || LLD_VERSION >= 140000)
+	select HAVE_ARCH_VMAP_STACK if MMU && ARM_HAS_GROUP_RELOCS
 	select TRACE_IRQFLAGS_SUPPORT if !CPU_V7M
 	# Above selects are sorted alphabetically; please add new ones
 	# according to that.  Thanks.
@@ -140,6 +140,17 @@ config ARM
 	  Europe.  There is an ARM Linux project with a web page at
 	  <http://www.arm.linux.org.uk/>.
 
+config ARM_HAS_GROUP_RELOCS
+	def_bool y
+	depends on !LD_IS_LLD || LLD_VERSION >= 140000
+	depends on !COMPILE_TEST
+	help
+	  Whether or not to use R_ARM_ALU_PC_Gn or R_ARM_LDR_PC_Gn group
+	  relocations, which have been around for a long time, but were not
+	  supported in LLD until version 14. The combined range is -/+ 256 MiB,
+	  which is usually sufficient, but not for allyesconfig, so we disable
+	  this feature when doing compile testing.
+
 config ARM_HAS_SG_CHAIN
 	bool
 
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 59d7b9e81934..9998718a49ca 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -656,8 +656,8 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 
 	.macro		__ldst_va, op, reg, tmp, sym, cond
 #if __LINUX_ARM_ARCH__ >= 7 || \
-    (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) || \
-    (defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000)
+    !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+    (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
 	mov_l		\tmp, \sym, \cond
 	\op\cond	\reg, [\tmp]
 #else
@@ -716,8 +716,8 @@ THUMB(	orr	\reg , \reg , #PSR_T_BIT	)
 	 */
 	.macro		ldr_this_cpu, rd:req, sym:req, t1:req, t2:req
 #if __LINUX_ARM_ARCH__ >= 7 || \
-    (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) || \
-    (defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000)
+    !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+    (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
 	this_cpu_offset	\t1
 	mov_l		\t2, \sym
 	ldr		\rd, [\t1, \t2]
diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 2f9d79214b25..131a89bbec6b 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -37,8 +37,8 @@ static inline __attribute_const__ struct task_struct *get_current(void)
 #ifdef CONFIG_CPU_V6
 	    "1:							\n\t"
 	    "	.subsection 1					\n\t"
-#if !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) && \
-    !(defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000)
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+    !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
 	    "2: " LOAD_SYM_ARMV6(%0, __current) "		\n\t"
 	    "	b	1b					\n\t"
 #else
@@ -55,8 +55,8 @@ static inline __attribute_const__ struct task_struct *get_current(void)
 #endif
 	    : "=r"(cur));
 #elif __LINUX_ARM_ARCH__>= 7 || \
-      (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) || \
-      (defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000)
+      !defined(CONFIG_ARM_HAS_GROUP_RELOCS) || \
+      (defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
 	cur = __current;
 #else
 	asm(LOAD_SYM_ARMV6(%0, __current) : "=r"(cur));
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index 28961d60877d..a09034ae45a1 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -38,8 +38,8 @@ static inline unsigned long __my_cpu_offset(void)
 #ifdef CONFIG_CPU_V6
 	    "1:							\n\t"
 	    "	.subsection 1					\n\t"
-#if !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS)) && \
-    !(defined(CONFIG_LD_IS_LLD) && CONFIG_LLD_VERSION < 140000)
+#if defined(CONFIG_ARM_HAS_GROUP_RELOCS) && \
+    !(defined(MODULE) && defined(CONFIG_ARM_MODULE_PLTS))
 	    "2: " LOAD_SYM_ARMV6(%0, __per_cpu_offset) "	\n\t"
 	    "	b	1b					\n\t"
 #else
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 4d33a7acf617..549abcedf795 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -68,6 +68,7 @@ bool module_exit_section(const char *name)
 		strstarts(name, ".ARM.exidx.exit");
 }
 
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
 /*
  * This implements the partitioning algorithm for group relocations as
  * documented in the ARM AArch32 ELF psABI (IHI 0044).
@@ -103,6 +104,7 @@ static u32 get_group_rem(u32 group, u32 *offset)
 	} while (group--);
 	return shift;
 }
+#endif
 
 int
 apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
@@ -118,7 +120,9 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 		unsigned long loc;
 		Elf32_Sym *sym;
 		const char *symname;
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
 		u32 shift, group = 1;
+#endif
 		s32 offset;
 		u32 tmp;
 #ifdef CONFIG_THUMB2_KERNEL
@@ -249,6 +253,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			*(u32 *)loc = __opcode_to_mem_arm(tmp);
 			break;
 
+#ifdef CONFIG_ARM_HAS_GROUP_RELOCS
 		case R_ARM_ALU_PC_G0_NC:
 			group = 0;
 			fallthrough;
@@ -296,7 +301,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
 			}
 			*(u32 *)loc = __opcode_to_mem_arm((tmp & ~0xfff) | offset);
 			break;
-
+#endif
 #ifdef CONFIG_THUMB2_KERNEL
 		case R_ARM_THM_CALL:
 		case R_ARM_THM_JUMP24:
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:48 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:48 +0100
Subject: [PATCH v6 3/8] ARM: smp: elide HWCAP_TLS checks or __entry_task
 updates on SMP+v6
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-4-ardb@kernel.org>

Use the SMP_ON_UP patching framework to elide HWCAP_TLS tests from the
context switch and return to userspace code paths, as SMP systems are
guaranteed to have this h/w capability.

At the same time, omit the update of __entry_task if the system is
detected to be UP at runtime, as in that case, the value is never used.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/switch_to.h |  4 ++--
 arch/arm/include/asm/tls.h       | 22 ++++++++++++++------
 arch/arm/kernel/entry-header.S   | 17 +++++++--------
 3 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
index a482c99934ff..f67ae946a3c6 100644
--- a/arch/arm/include/asm/switch_to.h
+++ b/arch/arm/include/asm/switch_to.h
@@ -3,6 +3,7 @@
 #define __ASM_ARM_SWITCH_TO_H
 
 #include <linux/thread_info.h>
+#include <asm/smp_plat.h>
 
 /*
  * For v7 SMP cores running a preemptible kernel we may be pre-empted
@@ -40,8 +41,7 @@ static inline void set_ti_cpu(struct task_struct *p)
 do {									\
 	__complete_pending_tlbi();					\
 	set_ti_cpu(next);						\
-	if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) ||		\
-	    IS_ENABLED(CONFIG_SMP))					\
+	if (IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) || is_smp())	\
 		__this_cpu_write(__entry_task, next);			\
 	last = __switch_to(prev,task_thread_info(prev), task_thread_info(next));	\
 } while (0)
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index d712c170c095..3dcd0f71a0da 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -18,22 +18,32 @@
 	.endm
 
 	.macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
+#ifdef CONFIG_SMP
+ALT_SMP(nop)
+ALT_UP_B(.L0_\@)
+	.subsection 1
+#endif
+.L0_\@:
 	ldr_va	\tmp1, elf_hwcap
 	mov	\tmp2, #0xffff0fff
 	tst	\tmp1, #HWCAP_TLS		@ hardware TLS available?
 	streq	\tp, [\tmp2, #-15]		@ set TLS value at 0xffff0ff0
-	mrcne	p15, 0, \tmp2, c13, c0, 2	@ get the user r/w register
-#ifndef CONFIG_SMP
-	mcrne	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+	beq	.L2_\@
+	mcr	p15, 0, \tp, c13, c0, 3		@ yes, set TLS register
+#ifdef CONFIG_SMP
+	b	.L1_\@
+	.previous
 #endif
-	mcrne	p15, 0, \tpuser, c13, c0, 2	@ set user r/w register
-	strne	\tmp2, [\base, #TI_TP_VALUE + 4] @ save it
+.L1_\@: switch_tls_v6k \base, \tp, \tpuser, \tmp1, \tmp2
+.L2_\@:
 	.endm
 
 	.macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
 	mov	\tmp1, #0xffff0fff
 	str	\tp, [\tmp1, #-15]		@ set TLS value at 0xffff0ff0
 	.endm
+#else
+#include <asm/smp_plat.h>
 #endif
 
 #ifdef CONFIG_TLS_REG_EMUL
@@ -44,7 +54,7 @@
 #elif defined(CONFIG_CPU_V6)
 #define tls_emu		0
 #define has_tls_reg		(elf_hwcap & HWCAP_TLS)
-#define defer_tls_reg_update	IS_ENABLED(CONFIG_SMP)
+#define defer_tls_reg_update	is_smp()
 #define switch_tls	switch_tls_v6
 #elif defined(CONFIG_CPU_32v6K)
 #define tls_emu		0
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index cb82ff5adec1..9a1dc142f782 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -292,21 +292,18 @@
 
 
 	.macro	restore_user_regs, fast = 0, offset = 0
-#if defined(CONFIG_CPU_32v6K) || defined(CONFIG_SMP)
-#if defined(CONFIG_CPU_V6) && defined(CONFIG_SMP)
-ALT_SMP(b	.L1_\@	)
-ALT_UP( nop		)
-	ldr_va	r1, elf_hwcap
-	tst	r1, #HWCAP_TLS			@ hardware TLS available?
-	beq	.L2_\@
-.L1_\@:
+#if defined(CONFIG_CPU_32v6K) && \
+    (!defined(CONFIG_CPU_V6) || defined(CONFIG_SMP))
+#ifdef CONFIG_CPU_V6
+ALT_SMP(nop)
+ALT_UP_B(.L1_\@)
 #endif
 	@ The TLS register update is deferred until return to user space so we
 	@ can use it for other things while running in the kernel
-	get_thread_info r1
+	mrc	p15, 0, r1, c13, c0, 3		@ get current_thread_info pointer
 	ldr	r1, [r1, #TI_TP_VALUE]
 	mcr	p15, 0, r1, c13, c0, 3		@ set TLS register
-.L2_\@:
+.L1_\@:
 #endif
 
 	uaccess_enable r1, isb=0
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:50 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:50 +0100
Subject: [PATCH v6 5/8] ARM: mm: make vmalloc_seq handling SMP safe
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-6-ardb@kernel.org>

Rework the vmalloc_seq handling so it can be used safely under SMP, as
we started using it to ensure that vmap'ed stacks are guaranteed to be
mapped by the active mm before switching to a task, and here we need to
ensure that changes to the page tables are visible to other CPUs when
they observe a change in the sequence count.

Since LPAE needs none of this, fold a check against it into the
vmalloc_seq counter check after breaking it out into a separate static
inline helper.

Given that vmap'ed stacks are now also supported on !SMP configurations,
let's drop the WARN() that could potentially now fire spuriously.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/mmu.h         |  2 +-
 arch/arm/include/asm/mmu_context.h | 22 +++++++++++++++--
 arch/arm/include/asm/page.h        |  3 +--
 arch/arm/kernel/traps.c            | 25 ++++++--------------
 arch/arm/mm/context.c              |  3 +--
 arch/arm/mm/ioremap.c              | 18 ++++++++------
 6 files changed, 41 insertions(+), 32 deletions(-)

diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 1592a4264488..e049723840d3 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -10,7 +10,7 @@ typedef struct {
 #else
 	int		switch_pending;
 #endif
-	unsigned int	vmalloc_seq;
+	atomic_t	vmalloc_seq;
 	unsigned long	sigpage;
 #ifdef CONFIG_VDSO
 	unsigned long	vdso;
diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h
index 84e58956fcab..db2cb06aa8cf 100644
--- a/arch/arm/include/asm/mmu_context.h
+++ b/arch/arm/include/asm/mmu_context.h
@@ -23,6 +23,16 @@
 
 void __check_vmalloc_seq(struct mm_struct *mm);
 
+#ifdef CONFIG_MMU
+static inline void check_vmalloc_seq(struct mm_struct *mm)
+{
+	if (!IS_ENABLED(CONFIG_ARM_LPAE) &&
+	    unlikely(atomic_read(&mm->context.vmalloc_seq) !=
+		     atomic_read(&init_mm.context.vmalloc_seq)))
+		__check_vmalloc_seq(mm);
+}
+#endif
+
 #ifdef CONFIG_CPU_HAS_ASID
 
 void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
@@ -52,8 +62,7 @@ static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
 static inline void check_and_switch_context(struct mm_struct *mm,
 					    struct task_struct *tsk)
 {
-	if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
-		__check_vmalloc_seq(mm);
+	check_vmalloc_seq(mm);
 
 	if (irqs_disabled())
 		/*
@@ -129,6 +138,15 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
 #endif
 }
 
+#ifdef CONFIG_VMAP_STACK
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
+{
+	if (mm != &init_mm)
+		check_vmalloc_seq(mm);
+}
+#define enter_lazy_tlb enter_lazy_tlb
+#endif
+
 #include <asm-generic/mmu_context.h>
 
 #endif
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 7b871ed99ccf..5fcc8a600e36 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -147,11 +147,10 @@ extern void copy_page(void *to, const void *from);
 #include <asm/pgtable-3level-types.h>
 #else
 #include <asm/pgtable-2level-types.h>
-#endif
-
 #ifdef CONFIG_VMAP_STACK
 #define ARCH_PAGE_TABLE_SYNC_MASK	PGTBL_PMD_MODIFIED
 #endif
+#endif
 
 #endif /* CONFIG_MMU */
 
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3f38357efc46..08612032aefe 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -885,6 +885,7 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
 	die("kernel stack overflow", regs, 0);
 }
 
+#ifndef CONFIG_ARM_LPAE
 /*
  * Normally, we rely on the logic in do_translation_fault() to update stale PMD
  * entries covering the vmalloc space in a task's page tables when it first
@@ -895,26 +896,14 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs)
  * So we need to ensure that these PMD entries are up to date *before* the MM
  * switch. As we already have some logic in the MM switch path that takes care
  * of this, let's trigger it by bumping the counter every time the core vmalloc
- * code modifies a PMD entry in the vmalloc region.
+ * code modifies a PMD entry in the vmalloc region. Use release semantics on
+ * the store so that other CPUs observing the counter's new value are
+ * guaranteed to see the updated page table entries as well.
  */
 void arch_sync_kernel_mappings(unsigned long start, unsigned long end)
 {
-	if (start > VMALLOC_END || end < VMALLOC_START)
-		return;
-
-	/*
-	 * This hooks into the core vmalloc code to receive notifications of
-	 * any PMD level changes that have been made to the kernel page tables.
-	 * This means it should only be triggered once for every MiB worth of
-	 * vmalloc space, given that we don't support huge vmalloc/vmap on ARM,
-	 * and that kernel PMD level table entries are rarely (if ever)
-	 * updated.
-	 *
-	 * This means that the counter is going to max out at ~250 for the
-	 * typical case. If it overflows, something entirely unexpected has
-	 * occurred so let's throw a warning if that happens.
-	 */
-	WARN_ON(++init_mm.context.vmalloc_seq == UINT_MAX);
+	if (start < VMALLOC_END && end > VMALLOC_START)
+		atomic_inc_return_release(&init_mm.context.vmalloc_seq);
 }
-
+#endif
 #endif
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 48091870db89..4204ffa2d104 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -240,8 +240,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
 	unsigned int cpu = smp_processor_id();
 	u64 asid;
 
-	if (unlikely(mm->context.vmalloc_seq != init_mm.context.vmalloc_seq))
-		__check_vmalloc_seq(mm);
+	check_vmalloc_seq(mm);
 
 	/*
 	 * We cannot update the pgd and the ASID atomicly with classic
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 6e830b9418c9..8963c8c63471 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -117,16 +117,21 @@ EXPORT_SYMBOL(ioremap_page);
 
 void __check_vmalloc_seq(struct mm_struct *mm)
 {
-	unsigned int seq;
+	int seq;
 
 	do {
-		seq = init_mm.context.vmalloc_seq;
+		seq = atomic_read(&init_mm.context.vmalloc_seq);
 		memcpy(pgd_offset(mm, VMALLOC_START),
 		       pgd_offset_k(VMALLOC_START),
 		       sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
 					pgd_index(VMALLOC_START)));
-		mm->context.vmalloc_seq = seq;
-	} while (seq != init_mm.context.vmalloc_seq);
+		/*
+		 * Use a store-release so that other CPUs that observe the
+		 * counter's new value are guaranteed to see the results of the
+		 * memcpy as well.
+		 */
+		atomic_set_release(&mm->context.vmalloc_seq, seq);
+	} while (seq != atomic_read(&init_mm.context.vmalloc_seq));
 }
 
 #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
@@ -157,7 +162,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
 			 * Note: this is still racy on SMP machines.
 			 */
 			pmd_clear(pmdp);
-			init_mm.context.vmalloc_seq++;
+			atomic_inc_return_release(&init_mm.context.vmalloc_seq);
 
 			/*
 			 * Free the page table, if there was one.
@@ -174,8 +179,7 @@ static void unmap_area_sections(unsigned long virt, unsigned long size)
 	 * Ensure that the active_mm is up to date - we want to
 	 * catch any use-after-iounmap cases.
 	 */
-	if (current->active_mm->context.vmalloc_seq != init_mm.context.vmalloc_seq)
-		__check_vmalloc_seq(current->active_mm);
+	check_vmalloc_seq(current->active_mm);
 
 	flush_tlb_kernel_range(virt, end);
 }
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:49 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:49 +0100
Subject: [PATCH v6 4/8] ARM: entry: avoid clobbering R9 in IRQ handler
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-5-ardb@kernel.org>

Avoid using R9 in the IRQ handler code, as the entry code uses it for
tsk, and expects it to remain untouched between the IRQ entry and exit
code.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-armv.S | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index b58bda51e4b8..038aabb6578f 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -38,11 +38,10 @@
 #ifdef CONFIG_UNWINDER_ARM
 	mov	fpreg, sp		@ Preserve original SP
 #else
-	mov	r8, fp			@ Preserve original FP
-	mov	r9, sp			@ Preserve original SP
+	mov	r7, fp			@ Preserve original FP
+	mov	r8, sp			@ Preserve original SP
 #endif
 	ldr_this_cpu sp, irq_stack_ptr, r2, r3
-
 	.if	\from_user == 0
 UNWIND(	.setfp	fpreg, sp		)
 	@
@@ -82,8 +81,8 @@ UNWIND(	.setfp	fpreg, sp		)
 #ifdef CONFIG_UNWINDER_ARM
 	mov	sp, fpreg		@ Restore original SP
 #else
-	mov	fp, r8			@ Restore original FP
-	mov	sp, r9			@ Restore original SP
+	mov	fp, r7			@ Restore original FP
+	mov	sp, r8			@ Restore original SP
 #endif // CONFIG_UNWINDER_ARM
 #endif // CONFIG_IRQSTACKS
 	.endm
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:51 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:51 +0100
Subject: [PATCH v6 6/8] ARM: iop: make iop_handle_irq() static
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-7-ardb@kernel.org>

The build bots complain about iop_handle_irq() not being declared so
let's make it static instead.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/mach-iop32x/irq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index b820839eaae8..6dca7e97d81f 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -59,7 +59,7 @@ struct irq_chip ext_chip = {
 	.irq_unmask	= iop32x_irq_unmask,
 };
 
-void iop_handle_irq(struct pt_regs *regs)
+static void iop_handle_irq(struct pt_regs *regs)
 {
 	u32 mask;
 
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:52 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:52 +0100
Subject: [PATCH v6 7/8] ARM: drop pointless SMP check on secondary startup path
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-8-ardb@kernel.org>

Only SMP systems use the secondary startup path by definition, so there
is no need for SMP conditionals there.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/smp.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 951559e5bea3..e34efa96cea1 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -405,11 +405,6 @@ static void smp_store_cpu_info(unsigned int cpuid)
 
 static void set_current(struct task_struct *cur)
 {
-	if (!IS_ENABLED(CONFIG_CURRENT_POINTER_IN_TPIDRURO) && !is_smp()) {
-		__current = cur;
-		return;
-	}
-
 	/* Set TPIDRURO */
 	asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory");
 }
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 01:14:53 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 10:14:53 +0100
Subject: [PATCH v6 8/8] ARM: make get_current() and __my_cpu_offset()
 __always_inline
In-Reply-To: <20220125091453.1475246-1-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
Message-ID: <20220125091453.1475246-9-ardb@kernel.org>

The get_current() and __my_cpu_offset() accessors evaluate to only a
single instruction emitted inline, but due to the size of the asm string
that is created for SMP+v6 configurations, the compiler assumes
otherwise, and may emit the functions out of line instead.

So use __always_inline to avoid this.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/current.h | 2 +-
 arch/arm/include/asm/percpu.h  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
index 131a89bbec6b..1e1178bf176d 100644
--- a/arch/arm/include/asm/current.h
+++ b/arch/arm/include/asm/current.h
@@ -14,7 +14,7 @@ struct task_struct;
 
 extern struct task_struct *__current;
 
-static inline __attribute_const__ struct task_struct *get_current(void)
+static __always_inline __attribute_const__ struct task_struct *get_current(void)
 {
 	struct task_struct *cur;
 
diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
index a09034ae45a1..7545c87c251f 100644
--- a/arch/arm/include/asm/percpu.h
+++ b/arch/arm/include/asm/percpu.h
@@ -25,7 +25,7 @@ static inline void set_my_cpu_offset(unsigned long off)
 	asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
 }
 
-static inline unsigned long __my_cpu_offset(void)
+static __always_inline unsigned long __my_cpu_offset(void)
 {
 	unsigned long off;
 
-- 
2.30.2



From maciej.nitycz at belongsenergy.pl  Tue Jan 25 01:15:27 2022
From: maciej.nitycz at belongsenergy.pl (Maciej Nitycz)
Date: Tue, 25 Jan 2022 09:15:27 GMT
Subject: Wycena paneli fotowoltaicznych
Message-ID: <20220125074500-0.1.7.2zh.0.dg60bf5sic@belongsenergy.pl>

Dzie? dobry,

dostrzegam mo?liwo?? wsp??pracy z Pa?stwa firm?.

?wiadczymy kompleksow? obs?ug? inwestycji w fotowoltaik?, kt?ra obni?a koszty energii elektrycznej nawet o 90%.

Czy s? Pa?stwo zainteresowani weryfikacj? wst?pnych propozycji?


Pozdrawiam,
Maciej Nitycz


From alexander.stein at ew.tq-group.com  Tue Jan 25 01:16:46 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 10:16:46 +0100
Subject: [PATCH 1/1] arm64: dts: imx8mq: fix lcdif port node
Message-ID: <20220125091646.2845111-1-alexander.stein@ew.tq-group.com>

The port node does not have a unit-address, remove it.
This fixes the warnings:
lcd-controller at 30320000: 'port' is a required property
lcd-controller at 30320000: 'port at 0' does not match any of the regexes:
'pinctrl-[0-9]+'

Fixes: commit d0081bd02a03 ("arm64: dts: imx8mq: Add NWL MIPI DSI controller")
Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index bacdeb29ad9f..7b887861bea5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -554,7 +554,7 @@ lcdif: lcd-controller at 30320000 {
 				assigned-clock-rates = <0>, <0>, <0>, <1032000000>;
 				status = "disabled";
 
-				port at 0 {
+				port {
 					lcdif_mipi_dsi: endpoint {
 						remote-endpoint = <&mipi_dsi_lcdif_in>;
 					};
-- 
2.25.1



From maz at kernel.org  Tue Jan 25 01:30:34 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 09:30:34 +0000
Subject: [PATCHv9 2/5] irqchip/tegra: Fix overflow implicit truncation
 warnings
In-Reply-To: <2cd67f7eee96e062ea479b7406799f7a2daa5b1b.1642482334.git.quic_saipraka@quicinc.com>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
 <2cd67f7eee96e062ea479b7406799f7a2daa5b1b.1642482334.git.quic_saipraka@quicinc.com>
Message-ID: <8735lc88n9.wl-maz@kernel.org>

On Mon, 24 Jan 2022 06:33:31 +0000,
Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
> 
> Fix -Woverflow warnings for tegra irqchip driver which is a result
> of moving arm64 custom MMIO accessor macros to asm-generic function
> implementations giving a bonus type-checking now and uncovering these
> overflow warnings.
> 
> drivers/irqchip/irq-tegra.c: In function ?tegra_ictlr_suspend?:
> drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>    writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
>                   ^
> 
> Cc: Marc Zyngier <maz at kernel.org>
> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
> ---
>  drivers/irqchip/irq-tegra.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
> index e1f771c72fc4..9e4e5b39c701 100644
> --- a/drivers/irqchip/irq-tegra.c
> +++ b/drivers/irqchip/irq-tegra.c
> @@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void)
>  		lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
>  
>  		/* Disable COP interrupts */
> -		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
> +		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);

Aside from the 'l' in writel really meaning 'long' (a historical
artefact), it would probably be better to lift the ambiguity entirely
and write this as GENMASK(31, 0), making it clear what is being set,
no matter what the revision of the architecture is (this driver also
works on 32bit machines).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From yong.wu at mediatek.com  Tue Jan 25 01:32:43 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 17:32:43 +0800
Subject: [PATCH 1/2] dt-bindings: mediatek: mt8186: Add binding for MM iommu
In-Reply-To: <20220125093244.18230-1-yong.wu@mediatek.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
Message-ID: <20220125093244.18230-2-yong.wu@mediatek.com>

Add mt8186 iommu binding. "-mm" means the iommu is for Multimedia.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 .../bindings/iommu/mediatek,iommu.yaml        |   4 +
 .../dt-bindings/memory/mt8186-memory-port.h   | 217 ++++++++++++++++++
 2 files changed, 221 insertions(+)
 create mode 100644 include/dt-bindings/memory/mt8186-memory-port.h

diff --git a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
index c528a299afa9..6cc886eb55af 100644
--- a/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
+++ b/Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
@@ -76,6 +76,7 @@ properties:
           - mediatek,mt8167-m4u  # generation two
           - mediatek,mt8173-m4u  # generation two
           - mediatek,mt8183-m4u  # generation two
+          - mediatek,mt8186-iommu-mm # generation two
           - mediatek,mt8192-m4u  # generation two
           - mediatek,mt8195-iommu-vdo        # generation two
           - mediatek,mt8195-iommu-vpp        # generation two
@@ -120,6 +121,7 @@ properties:
       dt-binding/memory/mt8167-larb-port.h for mt8167,
       dt-binding/memory/mt8173-larb-port.h for mt8173,
       dt-binding/memory/mt8183-larb-port.h for mt8183,
+      dt-binding/memory/mt8186-memory-port.h for mt8186,
       dt-binding/memory/mt8192-larb-port.h for mt8192.
       dt-binding/memory/mt8195-memory-port.h for mt8195.
 
@@ -141,6 +143,7 @@ allOf:
               - mediatek,mt2701-m4u
               - mediatek,mt2712-m4u
               - mediatek,mt8173-m4u
+              - mediatek,mt8186-iommu-mm
               - mediatek,mt8192-m4u
               - mediatek,mt8195-iommu-vdo
               - mediatek,mt8195-iommu-vpp
@@ -153,6 +156,7 @@ allOf:
       properties:
         compatible:
           enum:
+            - mediatek,mt8186-iommu-mm
             - mediatek,mt8192-m4u
             - mediatek,mt8195-iommu-vdo
             - mediatek,mt8195-iommu-vpp
diff --git a/include/dt-bindings/memory/mt8186-memory-port.h b/include/dt-bindings/memory/mt8186-memory-port.h
new file mode 100644
index 000000000000..bda265725870
--- /dev/null
+++ b/include/dt-bindings/memory/mt8186-memory-port.h
@@ -0,0 +1,217 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ *
+ * Author: Anan Sun <anan.sun at mediatek.com>
+ * Author: Yong Wu <yong.wu at mediatek.com>
+ */
+#ifndef _DT_BINDINGS_MEMORY_MT8186_LARB_PORT_H_
+#define _DT_BINDINGS_MEMORY_MT8186_LARB_PORT_H_
+
+#include <dt-bindings/memory/mtk-memory-port.h>
+
+/*
+ * MM IOMMU supports 16GB dma address. We separate it to four ranges:
+ * 0 ~ 4G; 4G ~ 8G; 8G ~ 12G; 12G ~ 16G, we could adjust these masters
+ * locate in anyone bank. BUT:
+ * a) Make sure all the ports inside a larb are in one range.
+ * b) The iova of any master can NOT cross the 4G/8G/12G boundary.
+ *
+ * This is the suggested mapping in this SoC:
+ *
+ * modules    dma-address-region	larbs-ports
+ * disp         0 ~ 4G                  larb0/1/2
+ * vcodec      4G ~ 8G                  larb4/7
+ * cam/mdp     8G ~ 12G                 the other larbs.
+ * N/A         12G ~ 16G
+ * CCU0   0x24000_0000 ~ 0x243ff_ffff   larb13: port 9/10
+ * CCU1   0x24400_0000 ~ 0x247ff_ffff   larb14: port 4/5
+ */
+
+/* MM IOMMU ports */
+/* LARB 0 -- MMSYS */
+#define IOMMU_PORT_L0_DISP_POSTMASK0	MTK_M4U_ID(0, 0)
+#define IOMMU_PORT_L0_REVERSED		MTK_M4U_ID(0, 1)
+#define IOMMU_PORT_L0_OVL_RDMA0		MTK_M4U_ID(0, 2)
+#define IOMMU_PORT_L0_DISP_FAKE0	MTK_M4U_ID(0, 3)
+
+/* LARB 1 -- MMSYS */
+#define IOMMU_PORT_L1_DISP_RDMA1	MTK_M4U_ID(1, 0)
+#define IOMMU_PORT_L1_OVL_2L_RDMA0	MTK_M4U_ID(1, 1)
+#define IOMMU_PORT_L1_DISP_RDMA0	MTK_M4U_ID(1, 2)
+#define IOMMU_PORT_L1_DISP_WDMA0	MTK_M4U_ID(1, 3)
+#define IOMMU_PORT_L1_DISP_FAKE1	MTK_M4U_ID(1, 4)
+
+/* LARB 2 -- MMSYS */
+#define IOMMU_PORT_L2_MDP_RDMA0		MTK_M4U_ID(2, 0)
+#define IOMMU_PORT_L2_MDP_RDMA1		MTK_M4U_ID(2, 1)
+#define IOMMU_PORT_L2_MDP_WROT0		MTK_M4U_ID(2, 2)
+#define IOMMU_PORT_L2_MDP_WROT1		MTK_M4U_ID(2, 3)
+#define IOMMU_PORT_L2_DISP_FAKE0	MTK_M4U_ID(2, 4)
+
+/* LARB 4 -- VDEC */
+#define IOMMU_PORT_L4_HW_VDEC_MC_EXT		MTK_M4U_ID(4, 0)
+#define IOMMU_PORT_L4_HW_VDEC_UFO_EXT		MTK_M4U_ID(4, 1)
+#define IOMMU_PORT_L4_HW_VDEC_PP_EXT		MTK_M4U_ID(4, 2)
+#define IOMMU_PORT_L4_HW_VDEC_PRED_RD_EXT	MTK_M4U_ID(4, 3)
+#define IOMMU_PORT_L4_HW_VDEC_PRED_WR_EXT	MTK_M4U_ID(4, 4)
+#define IOMMU_PORT_L4_HW_VDEC_PPWRAP_EXT	MTK_M4U_ID(4, 5)
+#define IOMMU_PORT_L4_HW_VDEC_TILE_EXT		MTK_M4U_ID(4, 6)
+#define IOMMU_PORT_L4_HW_VDEC_VLD_EXT		MTK_M4U_ID(4, 7)
+#define IOMMU_PORT_L4_HW_VDEC_VLD2_EXT		MTK_M4U_ID(4, 8)
+#define IOMMU_PORT_L4_HW_VDEC_AVC_MV_EXT	MTK_M4U_ID(4, 9)
+#define IOMMU_PORT_L4_HW_VDEC_UFO_ENC_EXT	MTK_M4U_ID(4, 10)
+#define IOMMU_PORT_L4_HW_VDEC_RG_CTRL_DMA_EXT	MTK_M4U_ID(4, 11)
+#define IOMMU_PORT_L4_HW_MINI_MDP_R0_EXT	MTK_M4U_ID(4, 12)
+#define IOMMU_PORT_L4_HW_MINI_MDP_W0_EXT	MTK_M4U_ID(4, 13)
+
+/* LARB 7 -- VENC */
+#define IOMMU_PORT_L7_VENC_RCPU		MTK_M4U_ID(7, 0)
+#define IOMMU_PORT_L7_VENC_REC		MTK_M4U_ID(7, 1)
+#define IOMMU_PORT_L7_VENC_BSDMA	MTK_M4U_ID(7, 2)
+#define IOMMU_PORT_L7_VENC_SV_COMV	MTK_M4U_ID(7, 3)
+#define IOMMU_PORT_L7_VENC_RD_COMV	MTK_M4U_ID(7, 4)
+#define IOMMU_PORT_L7_VENC_CUR_LUMA	MTK_M4U_ID(7, 5)
+#define IOMMU_PORT_L7_VENC_CUR_CHROMA	MTK_M4U_ID(7, 6)
+#define IOMMU_PORT_L7_VENC_REF_LUMA	MTK_M4U_ID(7, 7)
+#define IOMMU_PORT_L7_VENC_REF_CHROMA	MTK_M4U_ID(7, 8)
+#define IOMMU_PORT_L7_JPGENC_Y_RDMA	MTK_M4U_ID(7, 9)
+#define IOMMU_PORT_L7_JPGENC_C_RDMA	MTK_M4U_ID(7, 10)
+#define IOMMU_PORT_L7_JPGENC_Q_TABLE	MTK_M4U_ID(7, 11)
+#define IOMMU_PORT_L7_JPGENC_BSDMA	MTK_M4U_ID(7, 12)
+
+/* LARB 8 -- WPE */
+#define IOMMU_PORT_L8_WPE_RDMA_0	MTK_M4U_ID(8, 0)
+#define IOMMU_PORT_L8_WPE_RDMA_1	MTK_M4U_ID(8, 1)
+#define IOMMU_PORT_L8_WPE_WDMA_0	MTK_M4U_ID(8, 2)
+
+/* LARB 9 -- IMG-1 */
+#define IOMMU_PORT_L9_IMG_IMGI_D1	MTK_M4U_ID(9, 0)
+#define IOMMU_PORT_L9_IMG_IMGBI_D1	MTK_M4U_ID(9, 1)
+#define IOMMU_PORT_L9_IMG_DMGI_D1	MTK_M4U_ID(9, 2)
+#define IOMMU_PORT_L9_IMG_DEPI_D1	MTK_M4U_ID(9, 3)
+#define IOMMU_PORT_L9_IMG_LCE_D1	MTK_M4U_ID(9, 4)
+#define IOMMU_PORT_L9_IMG_SMTI_D1	MTK_M4U_ID(9, 5)
+#define IOMMU_PORT_L9_IMG_SMTO_D2	MTK_M4U_ID(9, 6)
+#define IOMMU_PORT_L9_IMG_SMTO_D1	MTK_M4U_ID(9, 7)
+#define IOMMU_PORT_L9_IMG_CRZO_D1	MTK_M4U_ID(9, 8)
+#define IOMMU_PORT_L9_IMG_IMG3O_D1	MTK_M4U_ID(9, 9)
+#define IOMMU_PORT_L9_IMG_VIPI_D1	MTK_M4U_ID(9, 10)
+#define IOMMU_PORT_L9_IMG_SMTI_D5	MTK_M4U_ID(9, 11)
+#define IOMMU_PORT_L9_IMG_TIMGO_D1	MTK_M4U_ID(9, 12)
+#define IOMMU_PORT_L9_IMG_UFBC_W0	MTK_M4U_ID(9, 13)
+#define IOMMU_PORT_L9_IMG_UFBC_R0	MTK_M4U_ID(9, 14)
+#define IOMMU_PORT_L9_IMG_WPE_RDMA1	MTK_M4U_ID(9, 15)
+#define IOMMU_PORT_L9_IMG_WPE_RDMA0	MTK_M4U_ID(9, 16)
+#define IOMMU_PORT_L9_IMG_WPE_WDMA	MTK_M4U_ID(9, 17)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA0	MTK_M4U_ID(9, 18)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA1	MTK_M4U_ID(9, 19)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA2	MTK_M4U_ID(9, 20)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA3	MTK_M4U_ID(9, 21)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA4	MTK_M4U_ID(9, 22)
+#define IOMMU_PORT_L9_IMG_MFB_RDMA5	MTK_M4U_ID(9, 23)
+#define IOMMU_PORT_L9_IMG_MFB_WDMA0	MTK_M4U_ID(9, 24)
+#define IOMMU_PORT_L9_IMG_MFB_WDMA1	MTK_M4U_ID(9, 25)
+#define IOMMU_PORT_L9_IMG_RESERVE6	MTK_M4U_ID(9, 26)
+#define IOMMU_PORT_L9_IMG_RESERVE7	MTK_M4U_ID(9, 27)
+#define IOMMU_PORT_L9_IMG_RESERVE8	MTK_M4U_ID(9, 28)
+
+/* LARB 11 -- IMG-2 */
+#define IOMMU_PORT_L11_IMG_IMGI_D1	MTK_M4U_ID(11, 0)
+#define IOMMU_PORT_L11_IMG_IMGBI_D1	MTK_M4U_ID(11, 1)
+#define IOMMU_PORT_L11_IMG_DMGI_D1	MTK_M4U_ID(11, 2)
+#define IOMMU_PORT_L11_IMG_DEPI_D1	MTK_M4U_ID(11, 3)
+#define IOMMU_PORT_L11_IMG_LCE_D1	MTK_M4U_ID(11, 4)
+#define IOMMU_PORT_L11_IMG_SMTI_D1	MTK_M4U_ID(11, 5)
+#define IOMMU_PORT_L11_IMG_SMTO_D2	MTK_M4U_ID(11, 6)
+#define IOMMU_PORT_L11_IMG_SMTO_D1	MTK_M4U_ID(11, 7)
+#define IOMMU_PORT_L11_IMG_CRZO_D1	MTK_M4U_ID(11, 8)
+#define IOMMU_PORT_L11_IMG_IMG3O_D1	MTK_M4U_ID(11, 9)
+#define IOMMU_PORT_L11_IMG_VIPI_D1	MTK_M4U_ID(11, 10)
+#define IOMMU_PORT_L11_IMG_SMTI_D5	MTK_M4U_ID(11, 11)
+#define IOMMU_PORT_L11_IMG_TIMGO_D1	MTK_M4U_ID(11, 12)
+#define IOMMU_PORT_L11_IMG_UFBC_W0	MTK_M4U_ID(11, 13)
+#define IOMMU_PORT_L11_IMG_UFBC_R0	MTK_M4U_ID(11, 14)
+#define IOMMU_PORT_L11_IMG_WPE_RDMA1	MTK_M4U_ID(11, 15)
+#define IOMMU_PORT_L11_IMG_WPE_RDMA0	MTK_M4U_ID(11, 16)
+#define IOMMU_PORT_L11_IMG_WPE_WDMA	MTK_M4U_ID(11, 17)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA0	MTK_M4U_ID(11, 18)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA1	MTK_M4U_ID(11, 19)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA2	MTK_M4U_ID(11, 20)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA3	MTK_M4U_ID(11, 21)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA4	MTK_M4U_ID(11, 22)
+#define IOMMU_PORT_L11_IMG_MFB_RDMA5	MTK_M4U_ID(11, 23)
+#define IOMMU_PORT_L11_IMG_MFB_WDMA0	MTK_M4U_ID(11, 24)
+#define IOMMU_PORT_L11_IMG_MFB_WDMA1	MTK_M4U_ID(11, 25)
+#define IOMMU_PORT_L11_IMG_RESERVE6	MTK_M4U_ID(11, 26)
+#define IOMMU_PORT_L11_IMG_RESERVE7	MTK_M4U_ID(11, 27)
+#define IOMMU_PORT_L11_IMG_RESERVE8	MTK_M4U_ID(11, 28)
+
+/* LARB 13 -- CAM */
+#define IOMMU_PORT_L13_CAM_MRAWI	MTK_M4U_ID(13, 0)
+#define IOMMU_PORT_L13_CAM_MRAWO_0	MTK_M4U_ID(13, 1)
+#define IOMMU_PORT_L13_CAM_MRAWO_1	MTK_M4U_ID(13, 2)
+#define IOMMU_PORT_L13_CAM_CAMSV_4	MTK_M4U_ID(13, 6)
+#define IOMMU_PORT_L13_CAM_CAMSV_5	MTK_M4U_ID(13, 7)
+#define IOMMU_PORT_L13_CAM_CAMSV_6	MTK_M4U_ID(13, 8)
+#define IOMMU_PORT_L13_CAM_CCUI		MTK_M4U_ID(13, 9)
+#define IOMMU_PORT_L13_CAM_CCUO		MTK_M4U_ID(13, 10)
+#define IOMMU_PORT_L13_CAM_FAKE		MTK_M4U_ID(13, 11)
+
+/* LARB 14 -- CAM */
+#define IOMMU_PORT_L14_CAM_CCUI		MTK_M4U_ID(14, 4)
+#define IOMMU_PORT_L14_CAM_CCUO		MTK_M4U_ID(14, 5)
+
+/* LARB 16 -- RAW-A */
+#define IOMMU_PORT_L16_CAM_IMGO_R1_A	MTK_M4U_ID(16, 0)
+#define IOMMU_PORT_L16_CAM_RRZO_R1_A	MTK_M4U_ID(16, 1)
+#define IOMMU_PORT_L16_CAM_CQI_R1_A	MTK_M4U_ID(16, 2)
+#define IOMMU_PORT_L16_CAM_BPCI_R1_A	MTK_M4U_ID(16, 3)
+#define IOMMU_PORT_L16_CAM_YUVO_R1_A	MTK_M4U_ID(16, 4)
+#define IOMMU_PORT_L16_CAM_UFDI_R2_A	MTK_M4U_ID(16, 5)
+#define IOMMU_PORT_L16_CAM_RAWI_R2_A	MTK_M4U_ID(16, 6)
+#define IOMMU_PORT_L16_CAM_RAWI_R3_A	MTK_M4U_ID(16, 7)
+#define IOMMU_PORT_L16_CAM_AAO_R1_A	MTK_M4U_ID(16, 8)
+#define IOMMU_PORT_L16_CAM_AFO_R1_A	MTK_M4U_ID(16, 9)
+#define IOMMU_PORT_L16_CAM_FLKO_R1_A	MTK_M4U_ID(16, 10)
+#define IOMMU_PORT_L16_CAM_LCESO_R1_A	MTK_M4U_ID(16, 11)
+#define IOMMU_PORT_L16_CAM_CRZO_R1_A	MTK_M4U_ID(16, 12)
+#define IOMMU_PORT_L16_CAM_LTMSO_R1_A	MTK_M4U_ID(16, 13)
+#define IOMMU_PORT_L16_CAM_RSSO_R1_A	MTK_M4U_ID(16, 14)
+#define IOMMU_PORT_L16_CAM_AAHO_R1_A	MTK_M4U_ID(16, 15)
+#define IOMMU_PORT_L16_CAM_LSCI_R1_A	MTK_M4U_ID(16, 16)
+
+/* LARB 17 -- RAW-B */
+#define IOMMU_PORT_L17_CAM_IMGO_R1_B	MTK_M4U_ID(17, 0)
+#define IOMMU_PORT_L17_CAM_RRZO_R1_B	MTK_M4U_ID(17, 1)
+#define IOMMU_PORT_L17_CAM_CQI_R1_B	MTK_M4U_ID(17, 2)
+#define IOMMU_PORT_L17_CAM_BPCI_R1_B	MTK_M4U_ID(17, 3)
+#define IOMMU_PORT_L17_CAM_YUVO_R1_B	MTK_M4U_ID(17, 4)
+#define IOMMU_PORT_L17_CAM_UFDI_R2_B	MTK_M4U_ID(17, 5)
+#define IOMMU_PORT_L17_CAM_RAWI_R2_B	MTK_M4U_ID(17, 6)
+#define IOMMU_PORT_L17_CAM_RAWI_R3_B	MTK_M4U_ID(17, 7)
+#define IOMMU_PORT_L17_CAM_AAO_R1_B	MTK_M4U_ID(17, 8)
+#define IOMMU_PORT_L17_CAM_AFO_R1_B	MTK_M4U_ID(17, 9)
+#define IOMMU_PORT_L17_CAM_FLKO_R1_B	MTK_M4U_ID(17, 10)
+#define IOMMU_PORT_L17_CAM_LCESO_R1_B	MTK_M4U_ID(17, 11)
+#define IOMMU_PORT_L17_CAM_CRZO_R1_B	MTK_M4U_ID(17, 12)
+#define IOMMU_PORT_L17_CAM_LTMSO_R1_B	MTK_M4U_ID(17, 13)
+#define IOMMU_PORT_L17_CAM_RSSO_R1_B	MTK_M4U_ID(17, 14)
+#define IOMMU_PORT_L17_CAM_AAHO_R1_B	MTK_M4U_ID(17, 15)
+#define IOMMU_PORT_L17_CAM_LSCI_R1_B	MTK_M4U_ID(17, 16)
+
+/* LARB 19 -- IPE */
+#define IOMMU_PORT_L19_IPE_DVS_RDMA	MTK_M4U_ID(19, 0)
+#define IOMMU_PORT_L19_IPE_DVS_WDMA	MTK_M4U_ID(19, 1)
+#define IOMMU_PORT_L19_IPE_DVP_RDMA	MTK_M4U_ID(19, 2)
+#define IOMMU_PORT_L19_IPE_DVP_WDMA	MTK_M4U_ID(19, 3)
+
+/* LARB 20 -- IPE */
+#define IOMMU_PORT_L20_IPE_FDVT_RDA	MTK_M4U_ID(20, 0)
+#define IOMMU_PORT_L20_IPE_FDVT_RDB	MTK_M4U_ID(20, 1)
+#define IOMMU_PORT_L20_IPE_FDVT_WRA	MTK_M4U_ID(20, 2)
+#define IOMMU_PORT_L20_IPE_FDVT_WRB	MTK_M4U_ID(20, 3)
+#define IOMMU_PORT_L20_IPE_RSC_RDMA0	MTK_M4U_ID(20, 4)
+#define IOMMU_PORT_L20_IPE_RSC_WDMA	MTK_M4U_ID(20, 5)
+
+#endif
-- 
2.18.0



From michal.simek at xilinx.com  Tue Jan 25 01:42:42 2022
From: michal.simek at xilinx.com (Michal Simek)
Date: Tue, 25 Jan 2022 10:42:42 +0100
Subject: [PATCH 1/4] arm64: dts: zynqmp: add AMS driver to device tree
In-Reply-To: <20220120010246.3794962-2-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-2-robert.hancock@calian.com>
Message-ID: <03258e6a-3623-0123-ade1-0635fca351e9@xilinx.com>



On 1/20/22 02:02, Robert Hancock wrote:
> Add an entry to the ZynqMP device tree to support the AMS device which
> now has a driver in mainline.
> 
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> ---
>   .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |  4 +++
>   arch/arm64/boot/dts/xilinx/zynqmp.dtsi        | 26 +++++++++++++++++++
>   2 files changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> index 1e0b1bca7c94..108592104a1b 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
> @@ -239,6 +239,10 @@ &lpd_watchdog {
>   	clocks = <&zynqmp_clk LPD_WDT>;
>   };
>   
> +&xilinx_ams {
> +	clocks = <&zynqmp_clk AMS_REF>;
> +};

Please send this patch out of the series. It should go via soc tree not via iio 
tree.
And unfortunately clock is not listed in DT binding document and needs to be 
added there.
Can you please send that patch too? dtbs_check reports it as issue.

> +
>   &zynqmp_dpdma {
>   	clocks = <&zynqmp_clk DPDMA_REF>;
>   };
> diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> index 74e66443e4ce..d1fe1e5b46c1 100644
> --- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> +++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
> @@ -878,6 +878,32 @@ lpd_watchdog: watchdog at ff150000 {
>   			timeout-sec = <10>;
>   		};
>   
> +		xilinx_ams: ams at ffa50000 {
> +			compatible = "xlnx,zynqmp-ams";
> +			status = "disabled";
> +			interrupt-parent = <&gic>;
> +			interrupts = <0 56 4>;
> +			reg = <0x0 0xffa50000 0x0 0x800>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			#io-channel-cells = <1>;
> +			ranges = <0 0 0xffa50800 0x800>;
> +
> +			ams_ps: ams_ps at 0 {
> +				compatible = "xlnx,zynqmp-ams-ps";
> +				status = "disabled";
> +				reg = <0x0 0x400>;
> +			};
> +
> +			ams_pl: ams_pl at 400 {
> +				compatible = "xlnx,zynqmp-ams-pl";
> +				status = "disabled";
> +				reg = <0x400 0x400>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
>   		zynqmp_dpdma: dma-controller at fd4c0000 {
>   			compatible = "xlnx,zynqmp-dpdma";
>   			status = "disabled";

And this second piece is completely aligned with dt binding that's why it is fine.

Thanks,
Michal


From yong.wu at mediatek.com  Tue Jan 25 01:32:44 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 17:32:44 +0800
Subject: [PATCH 2/2] iommu/mediatek: Add mt8186 iommu support
In-Reply-To: <20220125093244.18230-1-yong.wu@mediatek.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
Message-ID: <20220125093244.18230-3-yong.wu@mediatek.com>

Add mt8186 iommu supports.

Signed-off-by: Anan Sun <anan.sun at mediatek.com>
Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
 drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
index be36e73e4bcc..a3124f48f9e1 100644
--- a/drivers/iommu/mtk_iommu.c
+++ b/drivers/iommu/mtk_iommu.c
@@ -160,6 +160,7 @@ enum mtk_iommu_plat {
 	M4U_MT8167,
 	M4U_MT8173,
 	M4U_MT8183,
+	M4U_MT8186,
 	M4U_MT8192,
 	M4U_MT8195,
 };
@@ -1401,6 +1402,21 @@ static const struct mtk_iommu_plat_data mt8183_data = {
 	.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
 };
 
+static const struct mtk_iommu_plat_data mt8186_data_mm = {
+	.m4u_plat       = M4U_MT8186,
+	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
+			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
+			  MTK_IOMMU_TYPE_MM,
+	.larbid_remap   = {{0}, {1, MTK_INVALID_LARBID, 8}, {4}, {7}, {2}, {9, 11, 19, 20},
+			   {MTK_INVALID_LARBID, 14, 16},
+			   {MTK_INVALID_LARBID, 13, MTK_INVALID_LARBID, 17}},
+	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
+	.banks_num      = 1,
+	.banks_enable   = {true},
+	.iova_region    = mt8192_multi_dom,
+	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
+};
+
 static const struct mtk_iommu_plat_data mt8192_data = {
 	.m4u_plat       = M4U_MT8192,
 	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
@@ -1470,6 +1486,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
 	{ .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data},
 	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
 	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
+	{ .compatible = "mediatek,mt8186-iommu-mm", .data = &mt8186_data_mm},
 	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
 	{ .compatible = "mediatek,mt8195-iommu-infra", .data = &mt8195_data_infra},
 	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data = &mt8195_data_vdo},
-- 
2.18.0



From yong.wu at mediatek.com  Tue Jan 25 01:32:42 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Tue, 25 Jan 2022 17:32:42 +0800
Subject: [PATCH 0/2] MT8186 IOMMU SUPPORT
Message-ID: <20220125093244.18230-1-yong.wu@mediatek.com>

This patchset adds mt8186 iommu support.

Base on v5.16-rc1 and mt8195 iommu v4[1].

[1] https://lore.kernel.org/linux-mediatek/20220125085634.17972-1-yong.wu at mediatek.com/

Yong Wu (2):
  dt-bindings: mediatek: mt8186: Add binding for MM iommu
  iommu/mediatek: Add mt8186 iommu support

 .../bindings/iommu/mediatek,iommu.yaml        |   4 +
 drivers/iommu/mtk_iommu.c                     |  17 ++
 .../dt-bindings/memory/mt8186-memory-port.h   | 217 ++++++++++++++++++
 3 files changed, 238 insertions(+)
 create mode 100644 include/dt-bindings/memory/mt8186-memory-port.h

-- 
2.18.0




From brgl at bgdev.pl  Tue Jan 25 01:50:54 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 25 Jan 2022 10:50:54 +0100
Subject: [PATCH net-next v1 1/9] net: ethernet: mtk-star-emac: store
 bit_clk_div in compat structure
In-Reply-To: <20220120070226.1492-2-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-2-biao.huang@mediatek.com>
Message-ID: <CAMRc=Mc+DqcQFGqxoYXYG-VCuaKkJusoVGSHb0G-MtYsiVCxVw@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com> wrote:
>
> From: Fabien Parent <fparent at baylibre.com>
>
> Not all the SoC are using the same clock divider. Move the divider into
> a compat structure specific to the SoCs.
>
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> Signed-off-by: Fabien Parent <fparent at baylibre.com>
> ---
>  drivers/net/ethernet/mediatek/mtk_star_emac.c | 23 +++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index 1d5dd2015453..26f5020f2e9c 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -17,6 +17,7 @@
>  #include <linux/module.h>
>  #include <linux/netdevice.h>
>  #include <linux/of.h>
> +#include <linux/of_device.h>
>  #include <linux/of_mdio.h>
>  #include <linux/of_net.h>
>  #include <linux/platform_device.h>
> @@ -232,6 +233,10 @@ struct mtk_star_ring {
>         unsigned int tail;
>  };
>
> +struct mtk_star_compat {
> +       unsigned char bit_clk_div;
> +};
> +
>  struct mtk_star_priv {
>         struct net_device *ndev;
>
> @@ -257,6 +262,8 @@ struct mtk_star_priv {
>         int duplex;
>         int pause;
>
> +       const struct mtk_star_compat *compat_data;
> +
>         /* Protects against concurrent descriptor access. */
>         spinlock_t lock;
>
> @@ -899,7 +906,7 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
>         regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
>         regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
>                            MTK_STAR_MSK_MAC_CLK_CONF,
> -                          MTK_STAR_BIT_CLK_DIV_10);
> +                          priv->compat_data->bit_clk_div);
>  }
>
>  static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> @@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct platform_device *pdev)
>
>         priv = netdev_priv(ndev);
>         priv->ndev = ndev;
> +       priv->compat_data = of_device_get_match_data(&pdev->dev);
>         SET_NETDEV_DEV(ndev, dev);
>         platform_set_drvdata(pdev, ndev);
>
> @@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct platform_device *pdev)
>         return devm_register_netdev(dev, ndev);
>  }
>
> +static struct mtk_star_compat mtk_star_mt8516_compat = {

static const ... ?

> +       .bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
> +};
> +
>  static const struct of_device_id mtk_star_of_match[] = {
> -       { .compatible = "mediatek,mt8516-eth", },
> -       { .compatible = "mediatek,mt8518-eth", },
> -       { .compatible = "mediatek,mt8175-eth", },
> +       { .compatible = "mediatek,mt8516-eth",
> +         .data = &mtk_star_mt8516_compat },
> +       { .compatible = "mediatek,mt8518-eth",
> +         .data = &mtk_star_mt8516_compat },
> +       { .compatible = "mediatek,mt8175-eth",
> +         .data = &mtk_star_mt8516_compat },
>         { }
>  };
>  MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> --
> 2.25.1
>


From suzuki.poulose at arm.com  Tue Jan 25 02:02:31 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 25 Jan 2022 10:02:31 +0000
Subject: [PATCH V3 0/7] coresight: trbe: Workaround Cortex-A510 erratas
In-Reply-To: <ec21e5da-7b2a-e99f-b24f-89b459e2d5cb@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
 <ec21e5da-7b2a-e99f-b24f-89b459e2d5cb@arm.com>
Message-ID: <8a348786-d028-a991-178f-60b17d3d6554@arm.com>

On 25/01/2022 03:21, Anshuman Khandual wrote:
> 
> 
> On 1/11/22 9:08 AM, Anshuman Khandual wrote:
>> 	This series adds three different workarounds in the TRBE driver for
>> Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
>> part number definition in the platform. This series applies on 5.16.
>>
>> Relevant errata documents can be found here.
>>
>> https://developer.arm.com/documentation/SDEN2397239/900
>> https://developer.arm.com/documentation/SDEN2397589/900
>>
>> Changes in V3:
>>
>> - Moved the comment inside trbe_needs_drain_after_disable()
>> - Moved the comment inside trbe_needs_ctxt_sync_after_enable()
>>
>> Changes in V2:
>>
>> https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/
>>
>> Accommodated most review comments from the previous version.
>>
>> - Split all patches into CPU errata definition, detection and TRBE workarounds
>> - s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
>> - s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
>> - s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
>> - s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
>> - Updated Kconfig help message for config ARM64_ERRATUM_1902691
>> - Updated error message for trbe_is_broken() detection
>> - Added new trblimitr parameter to set_trbe_enabled(), improving performance
>> - Added COMPILE_TEST dependency in the errata, until TRBE part is available
>>
>> Changes in V1:
>>
>> https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/
>>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>> Cc: coresight at lists.linaro.org
>> Cc: linux-doc at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>>
>> Anshuman Khandual (7):
>>    arm64: Add Cortex-A510 CPU part definition
>>    arm64: errata: Add detection for TRBE ignored system register writes
>>    arm64: errata: Add detection for TRBE invalid prohibited states
>>    arm64: errata: Add detection for TRBE trace data corruption
>>    coresight: trbe: Work around the ignored system register writes
>>    coresight: trbe: Work around the invalid prohibited states
>>    coresight: trbe: Work around the trace data corruption
> 
> Hello Catalin/Mathieu,
> 
> I am wondering how this series is going to be merged i.e via arm64 or coresight
> tree ? Also will this require rebasing (and resend) against v5.17-rc1 release.
> Please do suggest. Thank you.

I would recommend rebasing on rc1.

Thanks
Suzuki


From xiongx18 at fudan.edu.cn  Tue Jan 25 02:12:15 2022
From: xiongx18 at fudan.edu.cn (Xin Xiong)
Date: Tue, 25 Jan 2022 18:12:15 +0800
Subject: [PATCH] spi: uniphier: fix reference count leak in
 uniphier_spi_probe()
Message-ID: <20220125101214.35677-1-xiongx18@fudan.edu.cn>

The issue happens in several error paths in uniphier_spi_probe().
When either dma_get_slave_caps() or devm_spi_register_master() returns
an error code, the function forgets to decrease the refcount of both
`dma_rx` and `dma_tx` objects, which may lead to refcount leaks.

Fix it by decrementing the reference count of specific objects in
those error paths.

Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>
---
 drivers/spi/spi-uniphier.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index 342ee8d2c..cc0da4822 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -726,7 +726,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 		if (ret) {
 			dev_err(&pdev->dev, "failed to get TX DMA capacities: %d\n",
 				ret);
-			goto out_disable_clk;
+			goto out_release_dma;
 		}
 		dma_tx_burst = caps.max_burst;
 	}
@@ -735,7 +735,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 	if (IS_ERR_OR_NULL(master->dma_rx)) {
 		if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) {
 			ret = -EPROBE_DEFER;
-			goto out_disable_clk;
+			goto out_release_dma;
 		}
 		master->dma_rx = NULL;
 		dma_rx_burst = INT_MAX;
@@ -744,7 +744,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 		if (ret) {
 			dev_err(&pdev->dev, "failed to get RX DMA capacities: %d\n",
 				ret);
-			goto out_disable_clk;
+			goto out_release_dma;
 		}
 		dma_rx_burst = caps.max_burst;
 	}
@@ -753,10 +753,20 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 
 	ret = devm_spi_register_master(&pdev->dev, master);
 	if (ret)
-		goto out_disable_clk;
+		goto out_release_dma;
 
 	return 0;
 
+out_release_dma:
+	if (!IS_ERR_OR_NULL(master->dma_rx)) {
+		dma_release_channel(master->dma_rx);
+		master->dma_rx = NULL;
+	}
+	if (!IS_ERR_OR_NULL(master->dma_tx)) {
+		dma_release_channel(master->dma_tx);
+		master->dma_tx = NULL;
+	}
+
 out_disable_clk:
 	clk_disable_unprepare(priv->clk);
 
-- 
2.25.1



From broonie at kernel.org  Tue Jan 25 02:20:59 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 10:20:59 +0000
Subject: [PATCH 0/3] RK356x/Quartz64 Model A SPI
In-Reply-To: <20211126154344.724316-1-frattaroli.nicolas@gmail.com>
References: <20211126154344.724316-1-frattaroli.nicolas@gmail.com>
Message-ID: <164310605968.75043.351730606633700396.b4-ty@kernel.org>

On Fri, 26 Nov 2021 16:43:41 +0100, Nicolas Frattaroli wrote:
> The first patch of this series adds a compatible for rk3568-spi
> to the DT bindings.
> 
> The second adds the SPI nodes for RK3566 and RK3568 SoCs. The nodes
> were lifted from the downstream vendor kernel's devicetree, and were
> double-checked for correctness.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/3] dt-bindings: spi: spi-rockchip: Add rk3568-spi compatible
      commit: bdac3bbd0dc63873a9c606b8e4f814e6d61d288d
[2/3] arm64: dts: rockchip: Add spi nodes on rk356x
      (no commit info)
[3/3] arm64: dts: rockchip: Add spi1 pins on Quartz64 A
      (no commit info)

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From brgl at bgdev.pl  Tue Jan 25 02:21:01 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 25 Jan 2022 11:21:01 +0100
Subject: [PATCH net-next v1 3/9] net: ethernet: mtk-star-emac: add support
 for MT8365 SoC
In-Reply-To: <20220120070226.1492-4-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-4-biao.huang@mediatek.com>
Message-ID: <CAMRc=MefKOmdKbm5KT=zQLORwm7oYe1oUy_XW3heqAqFqbE5NQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com> wrote:
>
> Add Ethernet driver support for MT8365 SoC.
>
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
> Signed-off-by: Fabien Parent <fparent at baylibre.com>
> ---
>  drivers/net/ethernet/mediatek/mtk_star_emac.c | 75 ++++++++++++++++---
>  1 file changed, 64 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index 7c2af775d601..403439782db9 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>  #define MTK_STAR_REG_MAC_CLK_CONF              0x00ac
>  #define MTK_STAR_MSK_MAC_CLK_CONF              GENMASK(7, 0)
>  #define MTK_STAR_BIT_CLK_DIV_10                        0x0a
> +#define MTK_STAR_BIT_CLK_DIV_50                        0x32
>
>  /* Counter registers. */
>  #define MTK_STAR_REG_C_RXOKPKT                 0x0100
> @@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
>  #define MTK_STAR_REG_C_RX_TWIST                        0x0218
>
>  /* Ethernet CFG Control */
> -#define MTK_PERICFG_REG_NIC_CFG_CON            0x03c4
> -#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII    GENMASK(3, 0)
> -#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII       BIT(0)
> +#define MTK_PERICFG_REG_NIC_CFG0_CON           0x03c4
> +#define MTK_PERICFG_REG_NIC_CFG1_CON           0x03c8
> +#define MTK_PERICFG_REG_NIC_CFG_CON_V2         0x0c10
> +#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF   GENMASK(3, 0)
> +#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII       1
>
>  /* Represents the actual structure of descriptors used by the MAC. We can
>   * reuse the same structure for both TX and RX - the layout is the same, only
> @@ -234,6 +237,7 @@ struct mtk_star_ring {
>  };
>
>  struct mtk_star_compat {
> +       int (*set_interface_mode)(struct net_device *ndev);
>         unsigned char bit_clk_div;
>  };
>
> @@ -909,13 +913,6 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
>                            priv->compat_data->bit_clk_div);
>  }
>
> -static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> -{
> -       regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON,
> -                          MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
> -                          MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
> -}
> -
>  static int mtk_star_enable(struct net_device *ndev)
>  {
>         struct mtk_star_priv *priv = netdev_priv(ndev);
> @@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct platform_device *pdev)
>                 return -ENODEV;
>         }
>
> -       mtk_star_set_mode_rmii(priv);
> +       if (priv->compat_data->set_interface_mode) {
> +               ret = priv->compat_data->set_interface_mode(ndev);
> +               if (ret) {
> +                       dev_err(dev, "Failed to set phy interface, err = %d\n", ret);
> +                       return -EINVAL;
> +               }
> +       }

Shouldn't you still call mtk_star_set_mode_rmii(priv) if there's no callback?

>
>         ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
>         if (ret) {
> @@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct platform_device *pdev)
>         return devm_register_netdev(dev, ndev);
>  }
>
> +static int mt8516_set_interface_mode(struct net_device *ndev)
> +{
> +       struct mtk_star_priv *priv = netdev_priv(ndev);
> +       struct device *dev = mtk_star_get_dev(priv);
> +       unsigned int intf_val = 0;

No need to initialize.

> +
> +       switch (priv->phy_intf) {
> +       case PHY_INTERFACE_MODE_RMII:
> +               intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +               break;
> +       default:
> +               dev_err(dev, "This interface not supported\n");
> +               return -EINVAL;
> +       }
> +
> +       regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG0_CON,
> +                          MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> +                          intf_val);
> +       return 0;

You can directly return regmap_update_bits().

> +}
> +
> +static int mt8365_set_interface_mode(struct net_device *ndev)
> +{
> +       struct mtk_star_priv *priv = netdev_priv(ndev);
> +       struct device *dev = mtk_star_get_dev(priv);
> +       unsigned int intf_val = 0;
> +
> +       switch (priv->phy_intf) {
> +       case PHY_INTERFACE_MODE_RMII:
> +               intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> +               break;
> +       default:
> +               dev_err(dev, "This interface not supported\n");
> +               return -EINVAL;
> +       }
> +
> +       regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON_V2,
> +                          MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> +                          intf_val);
> +       return 0;
> +}

Same as above.

> +
>  static struct mtk_star_compat mtk_star_mt8516_compat = {
> +       .set_interface_mode = mt8516_set_interface_mode,
>         .bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
>  };
>
> +static struct mtk_star_compat mtk_star_mt8365_compat = {
> +       .set_interface_mode = mt8365_set_interface_mode,
> +       .bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
> +};
> +
>  static const struct of_device_id mtk_star_of_match[] = {
>         { .compatible = "mediatek,mt8516-eth",
>           .data = &mtk_star_mt8516_compat },
> @@ -1575,6 +1626,8 @@ static const struct of_device_id mtk_star_of_match[] = {
>           .data = &mtk_star_mt8516_compat },
>         { .compatible = "mediatek,mt8175-eth",
>           .data = &mtk_star_mt8516_compat },
> +       { .compatible = "mediatek,mt8365-eth",
> +         .data = &mtk_star_mt8365_compat },
>         { }
>  };
>  MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> --
> 2.25.1
>

Bart


From brgl at bgdev.pl  Tue Jan 25 02:22:48 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 25 Jan 2022 11:22:48 +0100
Subject: [PATCH net-next v1 2/9] net: ethernet: mtk-star-emac: modify IRQ
 trigger flags
In-Reply-To: <20220120070226.1492-3-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-3-biao.huang@mediatek.com>
Message-ID: <CAMRc=McZTped08HwbM+pr-xtsDyddTLjpsCc_f7ucoDM2DNXaw@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com> wrote:
>
> If the flags in request_irq() is IRQF_TRIGGER_NONE, the trigger method
> is determined by "interrupt" property in dts.
> So, modify the flag from IRQF_TRIGGER_FALLING to IRQF_TRIGGER_NONE.
>
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
> ---
>  drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> index 26f5020f2e9c..7c2af775d601 100644
> --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> @@ -959,7 +959,7 @@ static int mtk_star_enable(struct net_device *ndev)
>
>         /* Request the interrupt */
>         ret = request_irq(ndev->irq, mtk_star_handle_irq,
> -                         IRQF_TRIGGER_FALLING, ndev->name, ndev);
> +                         IRQF_TRIGGER_NONE, ndev->name, ndev);
>         if (ret)
>                 goto err_free_skbs;
>
> --
> 2.25.1
>

Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>


From brgl at bgdev.pl  Tue Jan 25 02:23:28 2022
From: brgl at bgdev.pl (Bartosz Golaszewski)
Date: Tue, 25 Jan 2022 11:23:28 +0100
Subject: [PATCH net-next v1 4/9] dt-bindings: net: mtk-star-emac: add
 support for MT8365
In-Reply-To: <20220120070226.1492-5-biao.huang@mediatek.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-5-biao.huang@mediatek.com>
Message-ID: <CAMRc=MdVKdXcK0gdBSpaaSm5fx1o5Sy_0-JJBPK0=Xp7UmQnqQ@mail.gmail.com>

On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com> wrote:
>
> Add binding document for Ethernet on MT8365.
>
> Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> ---
>  Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
> index e6a5ff208253..87a8b25b03a6 100644
> --- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
> +++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
> @@ -23,6 +23,7 @@ properties:
>        - mediatek,mt8516-eth
>        - mediatek,mt8518-eth
>        - mediatek,mt8175-eth
> +      - mediatek,mt8365-eth
>
>    reg:
>      maxItems: 1
> --
> 2.25.1
>

Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>


From zajec5 at gmail.com  Tue Jan 25 02:24:52 2022
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 25 Jan 2022 11:24:52 +0100
Subject: [PATCH 5/8] net: add helper eth_addr_add()
In-Reply-To: <20211228142549.1275412-6-michael@walle.cc>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-6-michael@walle.cc>
Message-ID: <0d9a0ce5-ab34-cf05-158e-e25fc5595b4d@gmail.com>

On 28.12.2021 15:25, Michael Walle wrote:
> Add a helper to add an offset to a ethernet address. This comes in handy
> if you have a base ethernet address for multiple interfaces.
> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
>   include/linux/etherdevice.h | 14 ++++++++++++++
>   1 file changed, 14 insertions(+)
> 
> diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h
> index 2ad71cc90b37..9d621dc85290 100644
> --- a/include/linux/etherdevice.h
> +++ b/include/linux/etherdevice.h
> @@ -486,6 +486,20 @@ static inline void eth_addr_inc(u8 *addr)
>   	u64_to_ether_addr(u, addr);
>   }
>   
> +/**
> + * eth_addr_add() - Add (or subtract) and offset to/from the given MAC address.
> + *
> + * @offset: Offset to add.
> + * @addr: Pointer to a six-byte array containing Ethernet address to increment.
> + */
> +static inline void eth_addr_add(u8 *addr, long offset)
> +{
> +	u64 u = ether_addr_to_u64(addr);
> +
> +	u += offset;
> +	u64_to_ether_addr(u, addr);
> +}

Please check eth_hw_addr_gen() which contains identical code +
eth_hw_addr_set().

You should probably make eth_hw_addr_gen() use your new function as a
helper.


From hverkuil at xs4all.nl  Tue Jan 25 02:43:10 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Jan 2022 11:43:10 +0100
Subject: [PATCH v4 0/2] Fix incorrect resolution detected
In-Reply-To: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
References: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
Message-ID: <c3202b1f-ff8f-8108-e8a3-8710c8c74d10@xs4all.nl>

Hi Jammy,

On 18/01/2022 11:07, Jammy Huang wrote:
> This series fixes incorrect resolution detected.
> We found this problem happened occasionally in the switch between bios
> and bootloader.

Can you rebase this on top of:

https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=for-v5.18f

This series doesn't apply cleanly.

Regards,

	Hans

> 
> Changes in v4:
>  - Correct the subject of patch
> 
> Changes in v3:
>  - In v2, we tried to increase the min-required-count of stable signal
>    to avoid incorrect transient state in timing detection. But it is
>    not working for all conditions.
>    Thus, we go another way in v3. Use regs, which can represent the
>    signal status, to decide if we needs to do detection again.
>  
> Changes in v2:
>  - Separate the patch into two patches
> 
> Jammy Huang (2):
>   media: aspeed: Add macro for the fields of the mode-detect registers
>   media: aspeed: Fix unstable timing detection
> 
>  drivers/media/platform/aspeed-video.c | 25 ++++++++++++++++++++++++-
>  1 file changed, 24 insertions(+), 1 deletion(-)
> 



From anshuman.khandual at arm.com  Tue Jan 25 02:46:03 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 16:16:03 +0530
Subject: [PATCH V3 0/7] coresight: trbe: Workaround Cortex-A510 erratas
In-Reply-To: <8a348786-d028-a991-178f-60b17d3d6554@arm.com>
References: <1641872346-3270-1-git-send-email-anshuman.khandual@arm.com>
 <ec21e5da-7b2a-e99f-b24f-89b459e2d5cb@arm.com>
 <8a348786-d028-a991-178f-60b17d3d6554@arm.com>
Message-ID: <94430fa0-0cac-79f4-f167-1ac77077ad23@arm.com>



On 1/25/22 3:32 PM, Suzuki K Poulose wrote:
> On 25/01/2022 03:21, Anshuman Khandual wrote:
>>
>>
>> On 1/11/22 9:08 AM, Anshuman Khandual wrote:
>>> ????This series adds three different workarounds in the TRBE driver for
>>> Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
>>> part number definition in the platform. This series applies on 5.16.
>>>
>>> Relevant errata documents can be found here.
>>>
>>> https://developer.arm.com/documentation/SDEN2397239/900
>>> https://developer.arm.com/documentation/SDEN2397589/900
>>>
>>> Changes in V3:
>>>
>>> - Moved the comment inside trbe_needs_drain_after_disable()
>>> - Moved the comment inside trbe_needs_ctxt_sync_after_enable()
>>>
>>> Changes in V2:
>>>
>>> https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/
>>>
>>> Accommodated most review comments from the previous version.
>>>
>>> - Split all patches into CPU errata definition, detection and TRBE workarounds
>>> - s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
>>> - s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
>>> - s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
>>> - s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
>>> - Updated Kconfig help message for config ARM64_ERRATUM_1902691
>>> - Updated error message for trbe_is_broken() detection
>>> - Added new trblimitr parameter to set_trbe_enabled(), improving performance
>>> - Added COMPILE_TEST dependency in the errata, until TRBE part is available
>>>
>>> Changes in V1:
>>>
>>> https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/
>>>
>>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>>> Cc: Will Deacon <will at kernel.org>
>>> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
>>> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
>>> Cc: coresight at lists.linaro.org
>>> Cc: linux-doc at vger.kernel.org
>>> Cc: linux-arm-kernel at lists.infradead.org
>>> Cc: linux-kernel at vger.kernel.org
>>>
>>> Anshuman Khandual (7):
>>> ?? arm64: Add Cortex-A510 CPU part definition
>>> ?? arm64: errata: Add detection for TRBE ignored system register writes
>>> ?? arm64: errata: Add detection for TRBE invalid prohibited states
>>> ?? arm64: errata: Add detection for TRBE trace data corruption
>>> ?? coresight: trbe: Work around the ignored system register writes
>>> ?? coresight: trbe: Work around the invalid prohibited states
>>> ?? coresight: trbe: Work around the trace data corruption
>>
>> Hello Catalin/Mathieu,
>>
>> I am wondering how this series is going to be merged i.e via arm64 or coresight
>> tree ? Also will this require rebasing (and resend) against v5.17-rc1 release.
>> Please do suggest. Thank you.
> 
> I would recommend rebasing on rc1.

Sure, will do.


From suzuki.poulose at arm.com  Tue Jan 25 02:57:47 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Tue, 25 Jan 2022 10:57:47 +0000
Subject: [PATCH v8 01/38] arm64: cpufeature: Always specify and use a
 field width for capabilities
In-Reply-To: <20220125001114.193425-2-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-2-broonie@kernel.org>
Message-ID: <edc0a8a0-5439-ff34-3de0-89ae0a4e60f4@arm.com>

On 25/01/2022 00:10, Mark Brown wrote:
> Since all the fields in the main ID registers are 4 bits wide we have up
> until now not bothered specifying the width in the code. Since we now
> wish to use this mechanism to enumerate features from the floating point
> feature registers which do not follow this pattern add a width to the
> table.  This means updating all the existing table entries but makes it
> less likely that we run into issues in future due to implicitly assuming
> a 4 bit width.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
> ---
>   arch/arm64/include/asm/cpufeature.h |   1 +
>   arch/arm64/kernel/cpufeature.c      | 167 +++++++++++++++++-----------
>   2 files changed, 102 insertions(+), 66 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef6be92b1921..2728abd9cae4 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
>   		struct {	/* Feature register checking */
>   			u32 sys_reg;
>   			u8 field_pos;
> +			u8 field_width;
>   			u8 min_field_value;
>   			u8 hwcap_type;
>   			bool sign;


> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index a46ab3b1c4d5..d9f09e40aaf6 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1307,7 +1307,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
>   static bool
>   feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
>   {
> -	int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
> +	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
> +						    entry->field_width,
> +						    entry->sign);
>   

Could we do something like :

+ int val = cpuid_feature_extract_field_width(reg, 		entry->field_pos,
		entry->field_width ? : 4,
		..
		);

and leave the existing structures as they are ?

>   	return val >= entry->min_field_value;
>   }
> @@ -1952,6 +1954,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {

There is arm64_errata[] array in cpu_errata.c. So, if we use the above
proposal we could leave things unchanged for all existing uses.

>   		.matches = has_cpuid_feature,
>   		.sys_reg = SYS_ID_AA64MMFR0_EL1,
>   		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
> +		.field_width = 4,
>   		.sign = FTR_UNSIGNED,
>   		.min_field_value = 1,
>   	},
...

> -#define HWCAP_CPUID_MATCH(reg, field, s, min_value)				\
> +#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value)			\
>   		.matches = has_cpuid_feature,					\
>   		.sys_reg = reg,							\
>   		.field_pos = field,						\
> +		.field_width = width,						\
>   		.sign = s,							\
>   		.min_field_value = min_value,

And that could avoid these changes too. We could add :

#define HWCAP_CPUID_MATCH_WIDTH(...)

when/if we need one, which sets the width.

Cheers
Suzuki


From festevam at gmail.com  Tue Jan 25 02:59:29 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 25 Jan 2022 07:59:29 -0300
Subject: [PATCH 1/1] arm64: dts: imx8mq: fix lcdif port node
In-Reply-To: <20220125091646.2845111-1-alexander.stein@ew.tq-group.com>
References: <20220125091646.2845111-1-alexander.stein@ew.tq-group.com>
Message-ID: <CAOMZO5CmNDPAMqx5wwtSd20BXmAwi23hvo5uadSL8Jan2kw1Vg@mail.gmail.com>

Hi Alexander,

On Tue, Jan 25, 2022 at 6:16 AM Alexander Stein
<alexander.stein at ew.tq-group.com> wrote:
>
> The port node does not have a unit-address, remove it.
> This fixes the warnings:
> lcd-controller at 30320000: 'port' is a required property
> lcd-controller at 30320000: 'port at 0' does not match any of the regexes:
> 'pinctrl-[0-9]+'
>
> Fixes: commit d0081bd02a03 ("arm64: dts: imx8mq: Add NWL MIPI DSI controller")
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From festevam at gmail.com  Tue Jan 25 03:00:34 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 25 Jan 2022 08:00:34 -0300
Subject: [PATCH] arm64: dts: imx8mm: Add missing
 MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
In-Reply-To: <20220125025409.130667-1-marex@denx.de>
References: <20220125025409.130667-1-marex@denx.de>
Message-ID: <CAOMZO5AhoSSMLHMWV130zAY2vs1ZzTMfi2V6zxb3GViENNfxQw@mail.gmail.com>

On Mon, Jan 24, 2022 at 11:54 PM Marek Vasut <marex at denx.de> wrote:
>
> The i.MX8M Mini Application Processor Reference Manual, Rev. 3, 11/2020
> documents AF MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B , add it into the
> pinmux tables.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From kewei.xu at mediatek.com  Tue Jan 25 03:04:13 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 25 Jan 2022 19:04:13 +0800
Subject: [v2 2/2] i2c: mediatek: Add i2c compatible for Mediatek MT8186
In-Reply-To: <20220125110413.18988-1-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
Message-ID: <20220125110413.18988-3-kewei.xu@mediatek.com>

Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
MT8186 doesn't need handshake signal witch apdma.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c
index 9ea427f53083..aa4d21838e14 100644
--- a/drivers/i2c/busses/i2c-mt65xx.c
+++ b/drivers/i2c/busses/i2c-mt65xx.c
@@ -397,6 +397,19 @@ static const struct mtk_i2c_compatible mt8183_compat = {
 	.max_dma_support = 33,
 };
 
+static const struct mtk_i2c_compatible mt8186_compat = {
+	.regs = mt_i2c_regs_v2,
+	.pmic_i2c = 0,
+	.dcm = 0,
+	.auto_restart = 1,
+	.aux_len_reg = 1,
+	.timing_adjust = 1,
+	.dma_sync = 0,
+	.ltiming_adjust = 1,
+	.apdma_sync = 0,
+	.max_dma_support = 36,
+};
+
 static const struct mtk_i2c_compatible mt8192_compat = {
 	.quirks = &mt8183_i2c_quirks,
 	.regs = mt_i2c_regs_v2,
@@ -418,6 +431,7 @@ static const struct of_device_id mtk_i2c_of_match[] = {
 	{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat },
 	{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat },
 	{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat },
+	{ .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat },
 	{ .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat },
 	{}
 };
-- 
2.25.1



From kewei.xu at mediatek.com  Tue Jan 25 03:04:11 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 25 Jan 2022 19:04:11 +0800
Subject: [v2 0/2] add i2c support for mt8186
Message-ID: <20220125110413.18988-1-kewei.xu@mediatek.com>

V1:
Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
MT8186 doesn't need handshake signal with apdma.

Kewei Xu (2):
  dt-bindings: i2c: update bindings for MT8186 SoC
  i2c: mediatek: Add i2c compatible for Mediatek MT8186

 .../devicetree/bindings/i2c/i2c-mt65xx.txt         |  1 +
 drivers/i2c/busses/i2c-mt65xx.c                    | 14 ++++++++++++++
 2 files changed, 15 insertions(+)

--
2.18.0



From kewei.xu at mediatek.com  Tue Jan 25 03:04:12 2022
From: kewei.xu at mediatek.com (Kewei Xu)
Date: Tue, 25 Jan 2022 19:04:12 +0800
Subject: [v2 1/2] dt-bindings: i2c: update bindings for MT8186 SoC
In-Reply-To: <20220125110413.18988-1-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
Message-ID: <20220125110413.18988-2-kewei.xu@mediatek.com>

Add a DT binding documentation for the MT8186 soc.

Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>
---
 Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
index 5ea216ae7084..88f74a3c81ec 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
@@ -14,6 +14,7 @@ Required properties:
       "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek MT7629
       "mediatek,mt8173-i2c": for MediaTek MT8173
       "mediatek,mt8183-i2c": for MediaTek MT8183
+      "mediatek,mt8186-i2c": for MediaTek MT8186
       "mediatek,mt8192-i2c": for MediaTek MT8192
       "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek MT8195
       "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek MT8516
-- 
2.25.1



From maz at kernel.org  Tue Jan 25 03:25:31 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 11:25:31 +0000
Subject: [PATCH v8 05/38] arm64/sme: System register and exception
 syndrome definitions
In-Reply-To: <20220125001114.193425-6-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-6-broonie@kernel.org>
Message-ID: <87zgnk6or8.wl-maz@kernel.org>

On Tue, 25 Jan 2022 00:10:41 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> +/* HFG[WR]TR_EL2 bit definitions */
> +#define HFGxTR_EL2_nTPIDR_EL0_SHIFT	55
> +#define HFGxTR_EL2_nTPIDR_EL0_MASK	(1 << HFGxTR_EL2_nTPIDR_EL0_SHIFT)

This annoyingly clashes with bit 35 of the same registers, which maps
to TPIDR_EL0. I have the feeling that this really should be TPIDR2_EL0.

	M.

-- 
Without deviation from the norm, progress is not possible.


From qii.wang at mediatek.com  Tue Jan 25 03:26:40 2022
From: qii.wang at mediatek.com (Qii Wang)
Date: Tue, 25 Jan 2022 19:26:40 +0800
Subject: [v2 1/2] dt-bindings: i2c: update bindings for MT8186 SoC
In-Reply-To: <20220125110413.18988-2-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
 <20220125110413.18988-2-kewei.xu@mediatek.com>
Message-ID: <2262446371d8cdbc1b9653325d6faa067f12b2ac.camel@mediatek.com>

On Tue, 2022-01-25 at 19:04 +0800, Kewei Xu wrote:
> Add a DT binding documentation for the MT8186 soc.
> 
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>

Reviewed-by: Qii Wang <qii.wang at mediatek.com>

> ---
>  Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> index 5ea216ae7084..88f74a3c81ec 100644
> --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.txt
> @@ -14,6 +14,7 @@ Required properties:
>        "mediatek,mt7629-i2c", "mediatek,mt2712-i2c": for MediaTek
> MT7629
>        "mediatek,mt8173-i2c": for MediaTek MT8173
>        "mediatek,mt8183-i2c": for MediaTek MT8183
> +      "mediatek,mt8186-i2c": for MediaTek MT8186
>        "mediatek,mt8192-i2c": for MediaTek MT8192
>        "mediatek,mt8195-i2c", "mediatek,mt8192-i2c": for MediaTek
> MT8195
>        "mediatek,mt8516-i2c", "mediatek,mt2712-i2c": for MediaTek
> MT8516

From maz at kernel.org  Tue Jan 25 03:27:55 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 11:27:55 +0000
Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest
In-Reply-To: <20220125001114.193425-26-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-26-broonie@kernel.org>
Message-ID: <87y2346on8.wl-maz@kernel.org>

On Tue, 25 Jan 2022 00:11:01 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> SME defines two new traps which need to be enabled for guests to ensure
> that they can't use SME, one for the main SME operations which mirrors the
> traps for SVE and another for access to TPIDR2 in SCTLR_EL2.
> 
> For VHE manage SMEN along with ZEN in activate_traps() and the FP state
> management callbacks.
> 
> For nVHE the value to be used for CPTR_EL2 in the guest is stored in
> vcpu->arch.cptr_el2, set TSM there during initialisation. It will be
> cleared in __deactivate_traps_common() by virtue of not being set in
> CPTR_EL2_DEFAULT.
> 
> For both VHE and nVHE cases handle SCTLR_EL2.EnTPIDR2 in the shared
> __active_traps_common() and __deactivate_traps_common(), there is no
> existing dynamic management of SCTLR_EL2.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/kvm/hyp/nvhe/switch.c | 30 ++++++++++++++++++++++++++++++
>  arch/arm64/kvm/hyp/vhe/switch.c  | 10 +++++++++-
>  2 files changed, 39 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
> index 6410d21d8695..184bf6bd79b9 100644
> --- a/arch/arm64/kvm/hyp/nvhe/switch.c
> +++ b/arch/arm64/kvm/hyp/nvhe/switch.c
> @@ -47,10 +47,25 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
>  		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
>  		__activate_traps_fpsimd32(vcpu);
>  	}
> +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))

Please drop the IS_ENABLED(). We purposely avoid conditional
compilation in KVM in order to avoid bitrot, and the amount of code
you save isn't significant. Having a static key is more than enough to
avoid runtime costs.

> +		val |= CPTR_EL2_TSM;
>  
>  	write_sysreg(val, cptr_el2);
>  	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
>  
> +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
> +	    cpus_have_final_cap(ARM64_HAS_FGT)) {
> +		val = read_sysreg_s(SYS_HFGRTR_EL2);
> +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> +		write_sysreg_s(val, SYS_HFGRTR_EL2);
> +
> +		val = read_sysreg_s(SYS_HFGWTR_EL2);
> +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> +		write_sysreg_s(val, SYS_HFGWTR_EL2);
> +	}

If the CPUs do not have FGT, what provides the equivalent trapping?
If FGT is mandatory when SME exists, then you should simplify the
condition.

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Tue Jan 25 03:31:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:53 +0000
Subject: [PATCH v2 0/7] linkage: better symbol aliasing
Message-ID: <20220125113200.3829108-1-mark.rutland@arm.com>

This series aims to make symbol aliasing simpler and more consistent.
The basic idea is to replace SYM_FUNC_START_ALIAS(alias) and
SYM_FUNC_END_ALIAS(alias) with a new SYM_FUNC_ALIAS(alias, name), so
that e.g.

    SYM_FUNC_START(func)
    SYM_FUNC_START_ALIAS(alias1)
    SYM_FUNC_START_ALIAS(alias2)
        ... asm insns ...
    SYM_FUNC_END(func)
    SYM_FUNC_END_ALIAS(alias1)
    SYM_FUNC_END_ALIAS(alias2)
    EXPORT_SYMBOL(alias1)
    EXPORT_SYMBOL(alias2)

... can become:

    SYM_FUNC_START(name)
        ... asm insns ...
    SYM_FUNC_END(name)

    SYM_FUNC_ALIAS(alias1, func)
    EXPORT_SYMBOL(alias1)

    SYM_FUNC_ALIAS(alias2, func)
    EXPORT_SYMBOL(alias2)

This avoids repetition and hopefully make it easier to ensure
consistency (e.g. so each function has a single canonical name and
associated metadata).

I've build+boot tested arm64 defconfig without issues, and also build
tested arm/i386/x86_64 defconfig without issues. I've pushed the series
to my `linkage/alias-rework` branch on git.kernel.org, atop v5.17-rc1:

  git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git linkage/alias-rework
  https://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git/log/?h=linkage/alias-rework

Since RFCv1 [1]:
* Drop arm64 dma alias removal (taken via arm64 for v5.17)
* Rename SYM_FUNC_LOCAL_ALIAS() -> SYM_FUNC_ALIAS_LOCAL()
* Update the tools/ copies of x86 routines
* Add preparatory fix for 32-bit arm
* Rebase to v5.17-rc1

[1] https://lore.kernel.org/r/20211206124715.4101571-1-mark.rutland at arm.com/

Thanks,
Mark.

Mark Rutland (7):
  arm: lib: remove leading whitespace in bitop macro
  linkage: add SYM_{ENTRY,START,END}_AT()
  linkage: add SYM_FUNC_ALIAS{,_LOCAL,_WEAK}()
  arm64: clean up symbol aliasing
  x86: clean up symbol aliasing
  linkage: remove SYM_FUNC_{START,END}_ALIAS()
  tools: update x86 string routines

 Documentation/asm-annotations.rst       | 11 ++--
 arch/arm/lib/bitops.h                   |  8 +--
 arch/arm64/include/asm/linkage.h        | 24 -------
 arch/arm64/kvm/hyp/nvhe/cache.S         |  5 +-
 arch/arm64/lib/clear_page.S             |  5 +-
 arch/arm64/lib/copy_page.S              |  5 +-
 arch/arm64/lib/memchr.S                 |  5 +-
 arch/arm64/lib/memcmp.S                 |  6 +-
 arch/arm64/lib/memcpy.S                 | 21 +++---
 arch/arm64/lib/memset.S                 | 12 ++--
 arch/arm64/lib/strchr.S                 |  6 +-
 arch/arm64/lib/strcmp.S                 |  6 +-
 arch/arm64/lib/strlen.S                 |  6 +-
 arch/arm64/lib/strncmp.S                |  6 +-
 arch/arm64/lib/strnlen.S                |  6 +-
 arch/arm64/lib/strrchr.S                |  5 +-
 arch/arm64/mm/cache.S                   | 35 ++++++----
 arch/x86/boot/compressed/head_32.S      |  3 +-
 arch/x86/boot/compressed/head_64.S      |  3 +-
 arch/x86/crypto/aesni-intel_asm.S       |  4 +-
 arch/x86/lib/memcpy_64.S                | 10 +--
 arch/x86/lib/memmove_64.S               |  4 +-
 arch/x86/lib/memset_64.S                |  6 +-
 include/linux/linkage.h                 | 87 +++++++++++++++----------
 tools/arch/x86/lib/memcpy_64.S          | 10 +--
 tools/arch/x86/lib/memset_64.S          |  6 +-
 tools/perf/util/include/linux/linkage.h | 80 +++++++++++++++--------
 27 files changed, 209 insertions(+), 176 deletions(-)

-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:54 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:54 +0000
Subject: [PATCH v2 1/7] arm: lib: remove leading whitespace in bitop macro
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-2-mark.rutland@arm.com>

The `bitop` macro is used to create assembly functions for bit
operations, handling all the boilderplate such as ENTRY(), ENDPROC(),
etc.

Within the `bitop` macro, the argument to ENTRY() has leading whitespace
for alignment, but there is no leading whitespace for the argument to
ENDPROC().

The leading whitespace in the argument to ENTRY() prevents the value
from safely being token-pasted to form a longer symbol name, as
subsequent patches will need to do, where the value will be passed into
a new SYM_ENTRY_AT() macro:

  ENTRY(name)
  -> SYM_FUNC_START(name)
  -> SYM_START(name, [...])
  -> SYM_START_AT(name, [...])
  -> SYM_ENTRY_AT(name, [...])

... where SYM_ENTRY_AT() will token-paste name to form a local label
used by later macros:

| .set .L____sym_entry__##name, location ASM_NL

... but as this happens before assembler macros are evaluated, and
`name` will expand to `\name`, the token-pasting will retain the leading
space:

| .L____sym_entry__ \name

... and when evaluated within an assembler macro this will result in
build errors:

| [mark at lakrids:~/src/linux]% git clean -qfdx
| [mark at lakrids:~/src/linux]% usekorg 10.3.0 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -s multi_v7_defconfig
| [mark at lakrids:~/src/linux]% usekorg 10.3.0 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -s arch/arm/lib
| arch/arm/lib/changebit.S: Assembler messages:
| arch/arm/lib/changebit.S:12: Error: expected comma after ".L____sym_entry__"
| make[1]: *** [scripts/Makefile.build:388: arch/arm/lib/changebit.o] Error 1
| make: *** [Makefile:1846: arch/arm/lib] Error 2

This patch removes the leading space such that the name can be
token-pasted.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm/lib/bitops.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index 95bd359912889..36195edeb0b9f 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -4,7 +4,7 @@
 
 #if __LINUX_ARM_ARCH__ >= 6
 	.macro	bitop, name, instr
-ENTRY(	\name		)
+ENTRY(\name		)
 UNWIND(	.fnstart	)
 	ands	ip, r1, #3
 	strbne	r1, [ip]		@ assert word-aligned
@@ -29,7 +29,7 @@ ENDPROC(\name		)
 	.endm
 
 	.macro	testop, name, instr, store
-ENTRY(	\name		)
+ENTRY(\name		)
 UNWIND(	.fnstart	)
 	ands	ip, r1, #3
 	strbne	r1, [ip]		@ assert word-aligned
@@ -59,7 +59,7 @@ ENDPROC(\name		)
 	.endm
 #else
 	.macro	bitop, name, instr
-ENTRY(	\name		)
+ENTRY(\name		)
 UNWIND(	.fnstart	)
 	ands	ip, r1, #3
 	strbne	r1, [ip]		@ assert word-aligned
@@ -86,7 +86,7 @@ ENDPROC(\name		)
  * to avoid dirtying the data cache.
  */
 	.macro	testop, name, instr, store
-ENTRY(	\name		)
+ENTRY(\name		)
 UNWIND(	.fnstart	)
 	ands	ip, r1, #3
 	strbne	r1, [ip]		@ assert word-aligned
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:55 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:55 +0000
Subject: [PATCH v2 2/7] linkage: add SYM_{ENTRY,START,END}_AT()
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-3-mark.rutland@arm.com>

Currently, the SYM_{ENTRY,START,END}() helpers define symbols in terms
of the current position within the section. In subsequent patches we'll
need to define symbols after moving this position.

This patch splits the core out of SYM_{ENTRY,START,END}() into
SYM_{ENTRY,START,END}_AT() macros which take a location argument,
with SYM_{ENTRY,START,END}() passing the current position.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Brown <broonie at kernel.org>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Jiri Slaby <jslaby at suse.cz>
Cc: Josh Poimboeuf <jpoimboe at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 include/linux/linkage.h | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index dbf8506decca0..d87c2acda2540 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -147,25 +147,43 @@
 
 /* === generic annotations === */
 
+#ifndef SYM_ENTRY_AT
+#define SYM_ENTRY_AT(name, location, linkage)		\
+	linkage(name) ASM_NL				\
+	.set name, location ASM_NL
+#endif
+
 /* SYM_ENTRY -- use only if you have to for non-paired symbols */
 #ifndef SYM_ENTRY
 #define SYM_ENTRY(name, linkage, align...)		\
-	linkage(name) ASM_NL				\
 	align ASM_NL					\
-	name:
+	SYM_ENTRY_AT(name, ., linkage)
+#endif
+
+/* SYM_START_AT -- use only if you have to */
+#ifndef SYM_START_AT
+#define SYM_START_AT(name, location, linkage)		\
+	SYM_ENTRY_AT(name, location, linkage)
 #endif
 
 /* SYM_START -- use only if you have to */
 #ifndef SYM_START
 #define SYM_START(name, linkage, align...)		\
-	SYM_ENTRY(name, linkage, align)
+	align ASM_NL					\
+	SYM_START_AT(name, ., linkage)
+#endif
+
+/* SYM_END_AT -- use only if you have to */
+#ifndef SYM_END_AT
+#define SYM_END_AT(name, location, sym_type)		\
+	.type name sym_type ASM_NL			\
+	.size name, location-name ASM_NL
 #endif
 
 /* SYM_END -- use only if you have to */
 #ifndef SYM_END
 #define SYM_END(name, sym_type)				\
-	.type name sym_type ASM_NL			\
-	.size name, .-name
+	SYM_END_AT(name, ., sym_type)
 #endif
 
 /* === code annotations === */
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:56 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:56 +0000
Subject: [PATCH v2 3/7] linkage: add SYM_FUNC_ALIAS{,_LOCAL,_WEAK}()
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-4-mark.rutland@arm.com>

Currently aliasing an asm function requires adding START and END
annotations for each name, as per Documentation/asm-annotations.rst:

	SYM_FUNC_START_ALIAS(__memset)
	SYM_FUNC_START(memset)
	    ... asm insns ...
	SYM_FUNC_END(memset)
	SYM_FUNC_END_ALIAS(__memset)

This is more painful than necessary to maintain, especially where a
function has many aliases, some of which we may wish to define
conditionally. For example, arm64's memcpy/memmove implementation (which
uses some arch-specific SYM_*() helpers) has:

	SYM_FUNC_START_ALIAS(__memmove)
	SYM_FUNC_START_ALIAS_WEAK_PI(memmove)
	SYM_FUNC_START_ALIAS(__memcpy)
	SYM_FUNC_START_WEAK_PI(memcpy)
	    ... asm insns ...
	SYM_FUNC_END_PI(memcpy)
	EXPORT_SYMBOL(memcpy)
	SYM_FUNC_END_ALIAS(__memcpy)
	EXPORT_SYMBOL(__memcpy)
	SYM_FUNC_END_ALIAS_PI(memmove)
	EXPORT_SYMBOL(memmove)
	SYM_FUNC_END_ALIAS(__memmove)
	EXPORT_SYMBOL(__memmove)
	SYM_FUNC_START(name)

It would be much nicer if we could define the aliases *after* the
standard function definition. This would avoid the need to specify each
symbol name twice, and would make it easier to spot the canonical
function definition. This patch adds new macros to allow us to do so,
which allows the above example to be rewritten more succinctly as:

	SYM_FUNC_START(__pi_memcpy)
	    ... asm insns ...
	SYM_FUNC_END(__pi_memcpy)

	SYM_FUNC_ALIAS(__memcpy, __pi_memcpy)
	EXPORT_SYMBOL(__memcpy)
	SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
	EXPORT_SYMBOL(memcpy)

	SYM_FUNC_ALIAS(__pi_memmove, __pi_memcpy)
	SYM_FUNC_ALIAS(__memmove, __pi_memmove)
	EXPORT_SYMBOL(__memmove)
	SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
	EXPORT_SYMBOL(memmove)

The reduction in duplication will also make it possible to replace some
uses of WEAK with more accurate Kconfig guards, e.g.

	#ifndef CONFIG_KASAN
	SYM_FUNC_ALIAS(memmove, __memmove)
	EXPORT_SYMBOL(memmove)
	#endif

... which should make it easier to ensure that symbols are neither used
nor overidden unexpectedly.

The existing SYM_FUNC_START_ALIAS() and SYM_FUNC_START_LOCAL_ALIAS() are
marked as deprecated, and will be removed once existing users are moved
over to the new scheme.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Brown <broonie at kernel.org>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Jiri Slaby <jslaby at suse.cz>
Cc: Josh Poimboeuf <jpoimboe at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 Documentation/asm-annotations.rst | 16 ++++++++++++++--
 include/linux/linkage.h           | 29 +++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst
index f4bf0f6395fb9..4868b58c60fb1 100644
--- a/Documentation/asm-annotations.rst
+++ b/Documentation/asm-annotations.rst
@@ -130,8 +130,20 @@ denoting a range of code via ``SYM_*_START/END`` annotations.
   In fact, this kind of annotation corresponds to the now deprecated ``ENTRY``
   and ``ENDPROC`` macros.
 
-* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` serve for those
-  who decided to have two or more names for one function. The typical use is::
+* ``SYM_FUNC_ALIAS``, ``SYM_FUNC_ALIAS_LOCAL``, and ``SYM_FUNC_ALIAS_WEAK`` can
+  be used to define multiple names for a function. The typical use is::
+
+    SYM_FUNC_START(__memset)
+        ... asm insns ...
+    SYN_FUNC_END(__memset)
+    SYM_FUNC_ALIAS(memset, __memset)
+
+  In this example, one can call ``__memset`` or ``memset`` with the same
+  result, except the debug information for the instructions is generated to
+  the object file only once -- for the non-``ALIAS`` case.
+
+* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` are deprecated
+    ways to define two or more names for one function. The typical use is::
 
     SYM_FUNC_START_ALIAS(__memset)
     SYM_FUNC_START(memset)
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index d87c2acda2540..becd64e9e5b18 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -150,6 +150,7 @@
 #ifndef SYM_ENTRY_AT
 #define SYM_ENTRY_AT(name, location, linkage)		\
 	linkage(name) ASM_NL				\
+	.set .L____sym_entry__##name, location ASM_NL	\
 	.set name, location ASM_NL
 #endif
 
@@ -177,6 +178,7 @@
 #ifndef SYM_END_AT
 #define SYM_END_AT(name, location, sym_type)		\
 	.type name sym_type ASM_NL			\
+	.set .L____sym_end__##name, location ASM_NL	\
 	.size name, location-name ASM_NL
 #endif
 
@@ -293,6 +295,33 @@
 	SYM_END(name, SYM_T_FUNC)
 #endif
 
+/*
+ * SYM_FUNC_ALIAS_LOCAL -- define a local alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_LOCAL
+#define SYM_FUNC_ALIAS_LOCAL(alias, name)				\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_LOCAL)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS -- define a global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS
+#define SYM_FUNC_ALIAS(alias, name)					\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_GLOBAL)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_WEAK -- define a weak global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_WEAK
+#define SYM_FUNC_ALIAS_WEAK(alias, name)				\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_WEAK)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
 /* SYM_CODE_START -- use for non-C (special) functions */
 #ifndef SYM_CODE_START
 #define SYM_CODE_START(name)				\
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:58 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:58 +0000
Subject: [PATCH v2 5/7] x86: clean up symbol aliasing
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-6-mark.rutland@arm.com>

Now that we have SYM_FUNC_ALIAS() and SYM_FUNC_ALIAS_WEAK(), use those
to simplify the definition of function aliases across arch/x86.

For clarity, where there are multiple annotations such as
EXPORT_SYMBOL(), I've tried to keep annotations grouped by symbol. For
example, where a function has a name and an alias which are both
exported, this is organised as:

	SYM_FUNC_START(func)
	    ... asm insns ...
	SYM_FUNC_END(func)
	EXPORT_SYMBOL(func)

	SYM_FUNC_ALIAS(alias, func)
	EXPORT_SYMBOL(alias)

Where there are only aliases and no exports or other annotations, I have
not bothered with line spacing, e.g.

	SYM_FUNC_START(func)
	    ... asm insns ...
	SYM_FUNC_END(func)
	SYM_FUNC_ALAIAS(alias, func)

There should be no functional change as a result of this patch.

The x86 string routines under tools/ will be handled by a subsequent
patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Brown <broonie at kernel.org>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Dave Hansen <dave.hansen at linux.intel.com>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Jiri Slaby <jslaby at suse.cz>
Cc: Josh Poimboeuf <jpoimboe at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Thomas Gleixner <tglx at linutronix.de>
---
 arch/x86/boot/compressed/head_32.S |  3 +--
 arch/x86/boot/compressed/head_64.S |  3 +--
 arch/x86/crypto/aesni-intel_asm.S  |  4 +---
 arch/x86/lib/memcpy_64.S           | 10 +++++-----
 arch/x86/lib/memmove_64.S          |  4 ++--
 arch/x86/lib/memset_64.S           |  6 +++---
 6 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index 659fad53ca823..3b354eb9516df 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -152,14 +152,13 @@ SYM_FUNC_END(startup_32)
 
 #ifdef CONFIG_EFI_STUB
 SYM_FUNC_START(efi32_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
 	add	$0x4, %esp
 	movl	8(%esp), %esi	/* save boot_params pointer */
 	call	efi_main
 	/* efi_main returns the possibly relocated address of startup_32 */
 	jmp	*%eax
 SYM_FUNC_END(efi32_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi32_stub_entry)
 #endif
 
 	.text
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index fd9441f404570..dea95301196b8 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -535,7 +535,6 @@ SYM_CODE_END(startup_64)
 #ifdef CONFIG_EFI_STUB
 	.org 0x390
 SYM_FUNC_START(efi64_stub_entry)
-SYM_FUNC_START_ALIAS(efi_stub_entry)
 	and	$~0xf, %rsp			/* realign the stack */
 	movq	%rdx, %rbx			/* save boot_params pointer */
 	call	efi_main
@@ -543,7 +542,7 @@ SYM_FUNC_START_ALIAS(efi_stub_entry)
 	leaq	rva(startup_64)(%rax), %rax
 	jmp	*%rax
 SYM_FUNC_END(efi64_stub_entry)
-SYM_FUNC_END_ALIAS(efi_stub_entry)
+SYM_FUNC_ALIAS(efi_stub_entry, efi64_stub_entry)
 #endif
 
 	.text
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index 363699dd72206..837c1e0aa0217 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -1751,8 +1751,6 @@ SYM_FUNC_END(aesni_gcm_finalize)
 
 #endif
 
-
-SYM_FUNC_START_LOCAL_ALIAS(_key_expansion_128)
 SYM_FUNC_START_LOCAL(_key_expansion_256a)
 	pshufd $0b11111111, %xmm1, %xmm1
 	shufps $0b00010000, %xmm0, %xmm4
@@ -1764,7 +1762,7 @@ SYM_FUNC_START_LOCAL(_key_expansion_256a)
 	add $0x10, TKEYP
 	RET
 SYM_FUNC_END(_key_expansion_256a)
-SYM_FUNC_END_ALIAS(_key_expansion_128)
+SYM_FUNC_ALIAS_LOCAL(_key_expansion_128, _key_expansion_256a)
 
 SYM_FUNC_START_LOCAL(_key_expansion_192a)
 	pshufd $0b01010101, %xmm1, %xmm1
diff --git a/arch/x86/lib/memcpy_64.S b/arch/x86/lib/memcpy_64.S
index 59cf2343f3d90..d0d7b9bc6cad3 100644
--- a/arch/x86/lib/memcpy_64.S
+++ b/arch/x86/lib/memcpy_64.S
@@ -27,8 +27,7 @@
  * Output:
  * rax original destination
  */
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK(memcpy)
+SYM_FUNC_START(__memcpy)
 	ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
 		      "jmp memcpy_erms", X86_FEATURE_ERMS
 
@@ -40,11 +39,12 @@ SYM_FUNC_START_WEAK(memcpy)
 	movl %edx, %ecx
 	rep movsb
 	RET
-SYM_FUNC_END(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
-EXPORT_SYMBOL(memcpy)
+SYM_FUNC_END(__memcpy)
 EXPORT_SYMBOL(__memcpy)
 
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
 /*
  * memcpy_erms() - enhanced fast string memcpy. This is faster and
  * simpler than memcpy. Use memcpy_erms when possible.
diff --git a/arch/x86/lib/memmove_64.S b/arch/x86/lib/memmove_64.S
index 50ea390df7128..d83cba364e31d 100644
--- a/arch/x86/lib/memmove_64.S
+++ b/arch/x86/lib/memmove_64.S
@@ -24,7 +24,6 @@
  * Output:
  * rax: dest
  */
-SYM_FUNC_START_WEAK(memmove)
 SYM_FUNC_START(__memmove)
 
 	mov %rdi, %rax
@@ -207,6 +206,7 @@ SYM_FUNC_START(__memmove)
 13:
 	RET
 SYM_FUNC_END(__memmove)
-SYM_FUNC_END_ALIAS(memmove)
 EXPORT_SYMBOL(__memmove)
+
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
 EXPORT_SYMBOL(memmove)
diff --git a/arch/x86/lib/memset_64.S b/arch/x86/lib/memset_64.S
index d624f2bc42f16..fc9ffd3ff3b21 100644
--- a/arch/x86/lib/memset_64.S
+++ b/arch/x86/lib/memset_64.S
@@ -17,7 +17,6 @@
  *
  * rax   original destination
  */
-SYM_FUNC_START_WEAK(memset)
 SYM_FUNC_START(__memset)
 	/*
 	 * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
@@ -42,10 +41,11 @@ SYM_FUNC_START(__memset)
 	movq %r9,%rax
 	RET
 SYM_FUNC_END(__memset)
-SYM_FUNC_END_ALIAS(memset)
-EXPORT_SYMBOL(memset)
 EXPORT_SYMBOL(__memset)
 
+SYM_FUNC_ALIAS_WEAK(memset, __memset)
+EXPORT_SYMBOL(memset)
+
 /*
  * ISO C memset - set a memory block to a byte value. This function uses
  * enhanced rep stosb to override the fast string function.
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:57 +0000
Subject: [PATCH v2 4/7] arm64: clean up symbol aliasing
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-5-mark.rutland@arm.com>

Now that we have SYM_FUNC_ALIAS() and SYM_FUNC_ALIAS_WEAK(), use those
to simplify and more consistently define function aliases across
arch/arm64.

Aliases are now defined in terms of a canonical function name. For
position-independent functions I've made the __pi_<func> name the
canonical name, and defined other alises in terms of this.

The SYM_FUNC_{START,END}_PI(func) macros obscure the __pi_<func> name,
and make this hard to seatch for. The SYM_FUNC_START_WEAK_PI() macro
also obscures the fact that the __pi_<func> fymbol is global and the
<func> symbol is weak. For clarity, I have removed these macros and used
SYM_FUNC_{START,END}() directly with the __pi_<func> name.

For example:

    SYM_FUNC_START_WEAK_PI(func)
        ... asm insns ...
    SYM_FUNC_END_PI(func)
    EXPORT_SYMBOL(func)

... becomes:

    SYM_FUNC_START(__pi_func)
        ... asm insns ...
    SYM_FUNC_END(__pi_func)

    SYM_FUNC_ALIAS_WEAK(func, __pi_func)
    EXPORT_SYMBOL(func)

For clarity, where there are multiple annotations such as
EXPORT_SYMBOL(), I've tried to keep annotations grouped by symbol. For
example, where a function has a name and an alias which are both
exported, this is organised as:

    SYM_FUNC_START(func)
	... asm insns ...
    SYM_FUNC_END(func)
    EXPORT_SYMBOL(func)

    SYM_FUNC_ALAIAS(alias, func)
    EXPORT_SYMBOL(alias)

For consistency with the other string functions, I've defined strrchr as
a position-independent function, as it can safely be used as such even
though we have no users today.

As we no longer use SYM_FUNC_{START,END}_ALIAS(), our local copies are
removed. The common versions will be removed by a subsequent patch.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Brown <broonie at kernel.org>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 arch/arm64/include/asm/linkage.h | 24 ----------------------
 arch/arm64/kvm/hyp/nvhe/cache.S  |  5 +++--
 arch/arm64/lib/clear_page.S      |  5 +++--
 arch/arm64/lib/copy_page.S       |  5 +++--
 arch/arm64/lib/memchr.S          |  5 +++--
 arch/arm64/lib/memcmp.S          |  6 +++---
 arch/arm64/lib/memcpy.S          | 21 ++++++++++---------
 arch/arm64/lib/memset.S          | 12 ++++++-----
 arch/arm64/lib/strchr.S          |  6 ++++--
 arch/arm64/lib/strcmp.S          |  6 +++---
 arch/arm64/lib/strlen.S          |  6 +++---
 arch/arm64/lib/strncmp.S         |  6 +++---
 arch/arm64/lib/strnlen.S         |  6 ++++--
 arch/arm64/lib/strrchr.S         |  5 +++--
 arch/arm64/mm/cache.S            | 35 +++++++++++++++++++-------------
 15 files changed, 74 insertions(+), 79 deletions(-)

diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h
index b77e9b3f5371c..43f8c25b3fda6 100644
--- a/arch/arm64/include/asm/linkage.h
+++ b/arch/arm64/include/asm/linkage.h
@@ -39,28 +39,4 @@
 	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)		\
 	bti c ;
 
-/*
- * Annotate a function as position independent, i.e., safe to be called before
- * the kernel virtual mapping is activated.
- */
-#define SYM_FUNC_START_PI(x)			\
-		SYM_FUNC_START_ALIAS(__pi_##x);	\
-		SYM_FUNC_START(x)
-
-#define SYM_FUNC_START_WEAK_PI(x)		\
-		SYM_FUNC_START_ALIAS(__pi_##x);	\
-		SYM_FUNC_START_WEAK(x)
-
-#define SYM_FUNC_START_WEAK_ALIAS_PI(x)		\
-		SYM_FUNC_START_ALIAS(__pi_##x);	\
-		SYM_START(x, SYM_L_WEAK, SYM_A_ALIGN)
-
-#define SYM_FUNC_END_PI(x)			\
-		SYM_FUNC_END(x);		\
-		SYM_FUNC_END_ALIAS(__pi_##x)
-
-#define SYM_FUNC_END_ALIAS_PI(x)		\
-		SYM_FUNC_END_ALIAS(x);		\
-		SYM_FUNC_END_ALIAS(__pi_##x)
-
 #endif
diff --git a/arch/arm64/kvm/hyp/nvhe/cache.S b/arch/arm64/kvm/hyp/nvhe/cache.S
index 958734f4d6b0e..0c367eb5f4e28 100644
--- a/arch/arm64/kvm/hyp/nvhe/cache.S
+++ b/arch/arm64/kvm/hyp/nvhe/cache.S
@@ -7,7 +7,8 @@
 #include <asm/assembler.h>
 #include <asm/alternative.h>
 
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
 	dcache_by_line_op civac, sy, x0, x1, x2, x3
 	ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S
index 1fd5d790ab800..ebde40e7fa2b2 100644
--- a/arch/arm64/lib/clear_page.S
+++ b/arch/arm64/lib/clear_page.S
@@ -14,7 +14,7 @@
  * Parameters:
  *	x0 - dest
  */
-SYM_FUNC_START_PI(clear_page)
+SYM_FUNC_START(__pi_clear_page)
 	mrs	x1, dczid_el0
 	tbnz	x1, #4, 2f	/* Branch if DC ZVA is prohibited */
 	and	w1, w1, #0xf
@@ -35,5 +35,6 @@ SYM_FUNC_START_PI(clear_page)
 	tst	x0, #(PAGE_SIZE - 1)
 	b.ne	2b
 	ret
-SYM_FUNC_END_PI(clear_page)
+SYM_FUNC_END(__pi_clear_page)
+SYM_FUNC_ALIAS(clear_page, __pi_clear_page)
 EXPORT_SYMBOL(clear_page)
diff --git a/arch/arm64/lib/copy_page.S b/arch/arm64/lib/copy_page.S
index 29144f4cd4492..c336d2ffdec55 100644
--- a/arch/arm64/lib/copy_page.S
+++ b/arch/arm64/lib/copy_page.S
@@ -17,7 +17,7 @@
  *	x0 - dest
  *	x1 - src
  */
-SYM_FUNC_START_PI(copy_page)
+SYM_FUNC_START(__pi_copy_page)
 alternative_if ARM64_HAS_NO_HW_PREFETCH
 	// Prefetch three cache lines ahead.
 	prfm	pldl1strm, [x1, #128]
@@ -75,5 +75,6 @@ alternative_else_nop_endif
 	stnp	x16, x17, [x0, #112 - 256]
 
 	ret
-SYM_FUNC_END_PI(copy_page)
+SYM_FUNC_END(__pi_copy_page)
+SYM_FUNC_ALIAS(copy_page, __pi_copy_page)
 EXPORT_SYMBOL(copy_page)
diff --git a/arch/arm64/lib/memchr.S b/arch/arm64/lib/memchr.S
index 7c2276fdab543..37a9f2a4f7f4b 100644
--- a/arch/arm64/lib/memchr.S
+++ b/arch/arm64/lib/memchr.S
@@ -38,7 +38,7 @@
 
 	.p2align 4
 	nop
-SYM_FUNC_START_WEAK_PI(memchr)
+SYM_FUNC_START(__pi_memchr)
 	and	chrin, chrin, #0xff
 	lsr	wordcnt, cntin, #3
 	cbz	wordcnt, L(byte_loop)
@@ -71,5 +71,6 @@ CPU_LE(	rev	tmp, tmp)
 L(not_found):
 	mov	result, #0
 	ret
-SYM_FUNC_END_PI(memchr)
+SYM_FUNC_END(__pi_memchr)
+SYM_FUNC_ALIAS_WEAK(memchr, __pi_memchr)
 EXPORT_SYMBOL_NOKASAN(memchr)
diff --git a/arch/arm64/lib/memcmp.S b/arch/arm64/lib/memcmp.S
index 7d956384222ff..a5ccf2c55f911 100644
--- a/arch/arm64/lib/memcmp.S
+++ b/arch/arm64/lib/memcmp.S
@@ -32,7 +32,7 @@
 #define tmp1		x7
 #define tmp2		x8
 
-SYM_FUNC_START_WEAK_PI(memcmp)
+SYM_FUNC_START(__pi_memcmp)
 	subs	limit, limit, 8
 	b.lo	L(less8)
 
@@ -134,6 +134,6 @@ L(byte_loop):
 	b.eq	L(byte_loop)
 	sub	result, data1w, data2w
 	ret
-
-SYM_FUNC_END_PI(memcmp)
+SYM_FUNC_END(__pi_memcmp)
+SYM_FUNC_ALIAS_WEAK(memcmp, __pi_memcmp)
 EXPORT_SYMBOL_NOKASAN(memcmp)
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
index b82fd64ee1e1c..4ab48d49c4515 100644
--- a/arch/arm64/lib/memcpy.S
+++ b/arch/arm64/lib/memcpy.S
@@ -57,10 +57,7 @@
    The loop tail is handled by always copying 64 bytes from the end.
 */
 
-SYM_FUNC_START_ALIAS(__memmove)
-SYM_FUNC_START_WEAK_ALIAS_PI(memmove)
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK_PI(memcpy)
+SYM_FUNC_START(__pi_memcpy)
 	add	srcend, src, count
 	add	dstend, dstin, count
 	cmp	count, 128
@@ -241,12 +238,16 @@ L(copy64_from_start):
 	stp	B_l, B_h, [dstin, 16]
 	stp	C_l, C_h, [dstin]
 	ret
+SYM_FUNC_END(__pi_memcpy)
 
-SYM_FUNC_END_PI(memcpy)
-EXPORT_SYMBOL(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
+SYM_FUNC_ALIAS(__memcpy, __pi_memcpy)
 EXPORT_SYMBOL(__memcpy)
-SYM_FUNC_END_ALIAS_PI(memmove)
-EXPORT_SYMBOL(memmove)
-SYM_FUNC_END_ALIAS(__memmove)
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
+SYM_FUNC_ALIAS(__pi_memmove, __pi_memcpy)
+
+SYM_FUNC_ALIAS(__memmove, __pi_memmove)
 EXPORT_SYMBOL(__memmove)
+SYM_FUNC_ALIAS_WEAK(memmove, __memmove)
+EXPORT_SYMBOL(memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
index a9c1c9a01ea90..a5aebe82ad73b 100644
--- a/arch/arm64/lib/memset.S
+++ b/arch/arm64/lib/memset.S
@@ -42,8 +42,7 @@ dst		.req	x8
 tmp3w		.req	w9
 tmp3		.req	x9
 
-SYM_FUNC_START_ALIAS(__memset)
-SYM_FUNC_START_WEAK_PI(memset)
+SYM_FUNC_START(__pi_memset)
 	mov	dst, dstin	/* Preserve return value.  */
 	and	A_lw, val, #255
 	orr	A_lw, A_lw, A_lw, lsl #8
@@ -202,7 +201,10 @@ SYM_FUNC_START_WEAK_PI(memset)
 	ands	count, count, zva_bits_x
 	b.ne	.Ltail_maybe_long
 	ret
-SYM_FUNC_END_PI(memset)
-EXPORT_SYMBOL(memset)
-SYM_FUNC_END_ALIAS(__memset)
+SYM_FUNC_END(__pi_memset)
+
+SYM_FUNC_ALIAS(__memset, __pi_memset)
 EXPORT_SYMBOL(__memset)
+
+SYM_FUNC_ALIAS_WEAK(memset, __pi_memset)
+EXPORT_SYMBOL(memset)
diff --git a/arch/arm64/lib/strchr.S b/arch/arm64/lib/strchr.S
index 1f47eae3b0d6d..94ee67a6b212c 100644
--- a/arch/arm64/lib/strchr.S
+++ b/arch/arm64/lib/strchr.S
@@ -18,7 +18,7 @@
  * Returns:
  *	x0 - address of first occurrence of 'c' or 0
  */
-SYM_FUNC_START_WEAK(strchr)
+SYM_FUNC_START(__pi_strchr)
 	and	w1, w1, #0xff
 1:	ldrb	w2, [x0], #1
 	cmp	w2, w1
@@ -28,5 +28,7 @@ SYM_FUNC_START_WEAK(strchr)
 	cmp	w2, w1
 	csel	x0, x0, xzr, eq
 	ret
-SYM_FUNC_END(strchr)
+SYM_FUNC_END(__pi_strchr)
+
+SYM_FUNC_ALIAS_WEAK(strchr, __pi_strchr)
 EXPORT_SYMBOL_NOKASAN(strchr)
diff --git a/arch/arm64/lib/strcmp.S b/arch/arm64/lib/strcmp.S
index 83bcad72ec972..cda7de747efcf 100644
--- a/arch/arm64/lib/strcmp.S
+++ b/arch/arm64/lib/strcmp.S
@@ -41,7 +41,7 @@
 
 	/* Start of performance-critical section  -- one 64B cache line.  */
 	.align 6
-SYM_FUNC_START_WEAK_PI(strcmp)
+SYM_FUNC_START(__pi_strcmp)
 	eor	tmp1, src1, src2
 	mov	zeroones, #REP8_01
 	tst	tmp1, #7
@@ -171,6 +171,6 @@ L(loop_misaligned):
 L(done):
 	sub	result, data1, data2
 	ret
-
-SYM_FUNC_END_PI(strcmp)
+SYM_FUNC_END(__pi_strcmp)
+SYM_FUNC_ALIAS_WEAK(strcmp, __pi_strcmp)
 EXPORT_SYMBOL_NOHWKASAN(strcmp)
diff --git a/arch/arm64/lib/strlen.S b/arch/arm64/lib/strlen.S
index 1648790e91b3c..4919fe81ae540 100644
--- a/arch/arm64/lib/strlen.S
+++ b/arch/arm64/lib/strlen.S
@@ -79,7 +79,7 @@
 	   whether the first fetch, which may be misaligned, crosses a page
 	   boundary.  */
 
-SYM_FUNC_START_WEAK_PI(strlen)
+SYM_FUNC_START(__pi_strlen)
 	and	tmp1, srcin, MIN_PAGE_SIZE - 1
 	mov	zeroones, REP8_01
 	cmp	tmp1, MIN_PAGE_SIZE - 16
@@ -208,6 +208,6 @@ L(page_cross):
 	csel	data1, data1, tmp4, eq
 	csel	data2, data2, tmp2, eq
 	b	L(page_cross_entry)
-
-SYM_FUNC_END_PI(strlen)
+SYM_FUNC_END(__pi_strlen)
+SYM_FUNC_ALIAS_WEAK(strlen, __pi_strlen)
 EXPORT_SYMBOL_NOKASAN(strlen)
diff --git a/arch/arm64/lib/strncmp.S b/arch/arm64/lib/strncmp.S
index e42bcfcd37e6f..a848abcec975e 100644
--- a/arch/arm64/lib/strncmp.S
+++ b/arch/arm64/lib/strncmp.S
@@ -44,7 +44,7 @@
 #define endloop		x15
 #define count		mask
 
-SYM_FUNC_START_WEAK_PI(strncmp)
+SYM_FUNC_START(__pi_strncmp)
 	cbz	limit, L(ret0)
 	eor	tmp1, src1, src2
 	mov	zeroones, #REP8_01
@@ -256,6 +256,6 @@ L(done_loop):
 L(ret0):
 	mov	result, #0
 	ret
-
-SYM_FUNC_END_PI(strncmp)
+SYM_FUNC_END(__pi_strncmp)
+SYM_FUNC_ALIAS_WEAK(strncmp, __pi_strncmp)
 EXPORT_SYMBOL_NOHWKASAN(strncmp)
diff --git a/arch/arm64/lib/strnlen.S b/arch/arm64/lib/strnlen.S
index b72913a990389..d5ac0e10a01db 100644
--- a/arch/arm64/lib/strnlen.S
+++ b/arch/arm64/lib/strnlen.S
@@ -47,7 +47,7 @@ limit_wd	.req	x14
 #define REP8_7f 0x7f7f7f7f7f7f7f7f
 #define REP8_80 0x8080808080808080
 
-SYM_FUNC_START_WEAK_PI(strnlen)
+SYM_FUNC_START(__pi_strnlen)
 	cbz	limit, .Lhit_limit
 	mov	zeroones, #REP8_01
 	bic	src, srcin, #15
@@ -156,5 +156,7 @@ CPU_LE( lsr	tmp2, tmp2, tmp4 )	/* Shift (tmp1 & 63).  */
 .Lhit_limit:
 	mov	len, limit
 	ret
-SYM_FUNC_END_PI(strnlen)
+SYM_FUNC_END(__pi_strnlen)
+
+SYM_FUNC_ALIAS_WEAK(strnlen, __pi_strnlen)
 EXPORT_SYMBOL_NOKASAN(strnlen)
diff --git a/arch/arm64/lib/strrchr.S b/arch/arm64/lib/strrchr.S
index 13132d1ed6d12..a5123cf0ce125 100644
--- a/arch/arm64/lib/strrchr.S
+++ b/arch/arm64/lib/strrchr.S
@@ -18,7 +18,7 @@
  * Returns:
  *	x0 - address of last occurrence of 'c' or 0
  */
-SYM_FUNC_START_WEAK_PI(strrchr)
+SYM_FUNC_START(__pi_strrchr)
 	mov	x3, #0
 	and	w1, w1, #0xff
 1:	ldrb	w2, [x0], #1
@@ -29,5 +29,6 @@ SYM_FUNC_START_WEAK_PI(strrchr)
 	b	1b
 2:	mov	x0, x3
 	ret
-SYM_FUNC_END_PI(strrchr)
+SYM_FUNC_END(__pi_strrchr)
+SYM_FUNC_ALIAS_WEAK(strrchr, __pi_strrchr)
 EXPORT_SYMBOL_NOKASAN(strrchr)
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index 7d0563db42014..0ea6cc25dc663 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -107,10 +107,11 @@ SYM_FUNC_END(icache_inval_pou)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_inval_poc)
+SYM_FUNC_START(__pi_dcache_clean_inval_poc)
 	dcache_by_line_op civac, sy, x0, x1, x2, x3
 	ret
-SYM_FUNC_END_PI(dcache_clean_inval_poc)
+SYM_FUNC_END(__pi_dcache_clean_inval_poc)
+SYM_FUNC_ALIAS(dcache_clean_inval_poc, __pi_dcache_clean_inval_poc)
 
 /*
  *	dcache_clean_pou(start, end)
@@ -140,7 +141,7 @@ SYM_FUNC_END(dcache_clean_pou)
  *	- start   - kernel start address of region
  *	- end     - kernel end address of region
  */
-SYM_FUNC_START_PI(dcache_inval_poc)
+SYM_FUNC_START(__pi_dcache_inval_poc)
 	dcache_line_size x2, x3
 	sub	x3, x2, #1
 	tst	x1, x3				// end cache line aligned?
@@ -158,7 +159,8 @@ SYM_FUNC_START_PI(dcache_inval_poc)
 	b.lo	2b
 	dsb	sy
 	ret
-SYM_FUNC_END_PI(dcache_inval_poc)
+SYM_FUNC_END(__pi_dcache_inval_poc)
+SYM_FUNC_ALIAS(dcache_inval_poc, __pi_dcache_inval_poc)
 
 /*
  *	dcache_clean_poc(start, end)
@@ -169,10 +171,11 @@ SYM_FUNC_END_PI(dcache_inval_poc)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_poc)
+SYM_FUNC_START(__pi_dcache_clean_poc)
 	dcache_by_line_op cvac, sy, x0, x1, x2, x3
 	ret
-SYM_FUNC_END_PI(dcache_clean_poc)
+SYM_FUNC_END(__pi_dcache_clean_poc)
+SYM_FUNC_ALIAS(dcache_clean_poc, __pi_dcache_clean_poc)
 
 /*
  *	dcache_clean_pop(start, end)
@@ -183,13 +186,14 @@ SYM_FUNC_END_PI(dcache_clean_poc)
  *	- start   - virtual start address of region
  *	- end     - virtual end address of region
  */
-SYM_FUNC_START_PI(dcache_clean_pop)
+SYM_FUNC_START(__pi_dcache_clean_pop)
 	alternative_if_not ARM64_HAS_DCPOP
 	b	dcache_clean_poc
 	alternative_else_nop_endif
 	dcache_by_line_op cvap, sy, x0, x1, x2, x3
 	ret
-SYM_FUNC_END_PI(dcache_clean_pop)
+SYM_FUNC_END(__pi_dcache_clean_pop)
+SYM_FUNC_ALIAS(dcache_clean_pop, __pi_dcache_clean_pop)
 
 /*
  *	__dma_flush_area(start, size)
@@ -199,11 +203,12 @@ SYM_FUNC_END_PI(dcache_clean_pop)
  *	- start   - virtual start address of region
  *	- size    - size in question
  */
-SYM_FUNC_START_PI(__dma_flush_area)
+SYM_FUNC_START(__pi___dma_flush_area)
 	add	x1, x0, x1
 	dcache_by_line_op civac, sy, x0, x1, x2, x3
 	ret
-SYM_FUNC_END_PI(__dma_flush_area)
+SYM_FUNC_END(__pi___dma_flush_area)
+SYM_FUNC_ALIAS(__dma_flush_area, __pi___dma_flush_area)
 
 /*
  *	__dma_map_area(start, size, dir)
@@ -211,12 +216,13 @@ SYM_FUNC_END_PI(__dma_flush_area)
  *	- size	- size of region
  *	- dir	- DMA direction
  */
-SYM_FUNC_START_PI(__dma_map_area)
+SYM_FUNC_START(__pi___dma_map_area)
 	add	x1, x0, x1
 	cmp	w2, #DMA_FROM_DEVICE
 	b.eq	__pi_dcache_inval_poc
 	b	__pi_dcache_clean_poc
-SYM_FUNC_END_PI(__dma_map_area)
+SYM_FUNC_END(__pi___dma_map_area)
+SYM_FUNC_ALIAS(__dma_map_area, __pi___dma_map_area)
 
 /*
  *	__dma_unmap_area(start, size, dir)
@@ -224,9 +230,10 @@ SYM_FUNC_END_PI(__dma_map_area)
  *	- size	- size of region
  *	- dir	- DMA direction
  */
-SYM_FUNC_START_PI(__dma_unmap_area)
+SYM_FUNC_START(__pi___dma_unmap_area)
 	add	x1, x0, x1
 	cmp	w2, #DMA_TO_DEVICE
 	b.ne	__pi_dcache_inval_poc
 	ret
-SYM_FUNC_END_PI(__dma_unmap_area)
+SYM_FUNC_END(__pi___dma_unmap_area)
+SYM_FUNC_ALIAS(__dma_unmap_area, __pi___dma_unmap_area)
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:31:59 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:31:59 +0000
Subject: [PATCH v2 6/7] linkage: remove SYM_FUNC_{START,END}_ALIAS()
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-7-mark.rutland@arm.com>

Now that all aliases are defined using SYM_FUNC_ALIAS(), remove the old
SYM_FUNC_{START,END}_ALIAS() macros.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Acked-by: Ard Biesheuvel <ardb at kernel.org>
Acked-by: Mark Brown <broonie at kernel.org>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Jiri Slaby <jslaby at suse.cz>
Cc: Josh Poimboeuf <jpoimboe at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
---
 Documentation/asm-annotations.rst | 13 -------------
 include/linux/linkage.h           | 30 ------------------------------
 2 files changed, 43 deletions(-)

diff --git a/Documentation/asm-annotations.rst b/Documentation/asm-annotations.rst
index 4868b58c60fb1..a64f2ca469d45 100644
--- a/Documentation/asm-annotations.rst
+++ b/Documentation/asm-annotations.rst
@@ -142,19 +142,6 @@ denoting a range of code via ``SYM_*_START/END`` annotations.
   result, except the debug information for the instructions is generated to
   the object file only once -- for the non-``ALIAS`` case.
 
-* ``SYM_FUNC_START_ALIAS`` and ``SYM_FUNC_START_LOCAL_ALIAS`` are deprecated
-    ways to define two or more names for one function. The typical use is::
-
-    SYM_FUNC_START_ALIAS(__memset)
-    SYM_FUNC_START(memset)
-        ... asm insns ...
-    SYM_FUNC_END(memset)
-    SYM_FUNC_END_ALIAS(__memset)
-
-  In this example, one can call ``__memset`` or ``memset`` with the same
-  result, except the debug information for the instructions is generated to
-  the object file only once -- for the non-``ALIAS`` case.
-
 * ``SYM_CODE_START`` and ``SYM_CODE_START_LOCAL`` should be used only in
   special cases -- if you know what you are doing. This is used exclusively
   for interrupt handlers and similar where the calling convention is not the C
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index becd64e9e5b18..960d9a032861e 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -220,30 +220,8 @@
 	SYM_ENTRY(name, linkage, SYM_A_NONE)
 #endif
 
-/*
- * SYM_FUNC_START_LOCAL_ALIAS -- use where there are two local names for one
- * function
- */
-#ifndef SYM_FUNC_START_LOCAL_ALIAS
-#define SYM_FUNC_START_LOCAL_ALIAS(name)		\
-	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
-#endif
-
-/*
- * SYM_FUNC_START_ALIAS -- use where there are two global names for one
- * function
- */
-#ifndef SYM_FUNC_START_ALIAS
-#define SYM_FUNC_START_ALIAS(name)			\
-	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
-#endif
-
 /* SYM_FUNC_START -- use for global functions */
 #ifndef SYM_FUNC_START
-/*
- * The same as SYM_FUNC_START_ALIAS, but we will need to distinguish these two
- * later.
- */
 #define SYM_FUNC_START(name)				\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
 #endif
@@ -256,7 +234,6 @@
 
 /* SYM_FUNC_START_LOCAL -- use for local functions */
 #ifndef SYM_FUNC_START_LOCAL
-/* the same as SYM_FUNC_START_LOCAL_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_START_LOCAL(name)			\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
 #endif
@@ -279,18 +256,11 @@
 	SYM_START(name, SYM_L_WEAK, SYM_A_NONE)
 #endif
 
-/* SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function */
-#ifndef SYM_FUNC_END_ALIAS
-#define SYM_FUNC_END_ALIAS(name)			\
-	SYM_END(name, SYM_T_FUNC)
-#endif
-
 /*
  * SYM_FUNC_END -- the end of SYM_FUNC_START_LOCAL, SYM_FUNC_START,
  * SYM_FUNC_START_WEAK, ...
  */
 #ifndef SYM_FUNC_END
-/* the same as SYM_FUNC_END_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_END(name)				\
 	SYM_END(name, SYM_T_FUNC)
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 03:32:00 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 11:32:00 +0000
Subject: [PATCH v2 7/7] tools: update x86 string routines
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <20220125113200.3829108-8-mark.rutland@arm.com>

When building the perf tool the build system complains that the x86
string routines are out-of-date:

| Warning: Kernel ABI header at 'tools/arch/x86/lib/memcpy_64.S' differs from latest version at 'arch/x86/lib/memcpy_64.S'
| diff -u tools/arch/x86/lib/memcpy_64.S arch/x86/lib/memcpy_64.S
| Warning: Kernel ABI header at 'tools/arch/x86/lib/memset_64.S' differs from latest version at 'arch/x86/lib/memset_64.S'
| diff -u tools/arch/x86/lib/memset_64.S arch/x86/lib/memset_64.S

This is due to the way the asm-annotations for symbol aliasing were
reworked, which should have no functional/performance impact.

Import the latest versions, adding the new style SYM_FUNC_ALIAS(),
SYM_FUNC_ALIAS_LOAD(), SYM_FUNC_ALIAS_WEAK() macros into the perf
<linux/linkage.h> header. The old style SYM_FUNC_START_ALIAS() and
SYM_FUNC_END_ALIAS() macros are removed.

Other than removign the build-time warning, there should be no
functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Arnaldo Carvalho de Melo <acme at redhat.com>
Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
---
 tools/arch/x86/lib/memcpy_64.S          | 10 ++--
 tools/arch/x86/lib/memset_64.S          |  6 +-
 tools/perf/util/include/linux/linkage.h | 80 ++++++++++++++++---------
 3 files changed, 61 insertions(+), 35 deletions(-)

diff --git a/tools/arch/x86/lib/memcpy_64.S b/tools/arch/x86/lib/memcpy_64.S
index 59cf2343f3d90..d0d7b9bc6cad3 100644
--- a/tools/arch/x86/lib/memcpy_64.S
+++ b/tools/arch/x86/lib/memcpy_64.S
@@ -27,8 +27,7 @@
  * Output:
  * rax original destination
  */
-SYM_FUNC_START_ALIAS(__memcpy)
-SYM_FUNC_START_WEAK(memcpy)
+SYM_FUNC_START(__memcpy)
 	ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
 		      "jmp memcpy_erms", X86_FEATURE_ERMS
 
@@ -40,11 +39,12 @@ SYM_FUNC_START_WEAK(memcpy)
 	movl %edx, %ecx
 	rep movsb
 	RET
-SYM_FUNC_END(memcpy)
-SYM_FUNC_END_ALIAS(__memcpy)
-EXPORT_SYMBOL(memcpy)
+SYM_FUNC_END(__memcpy)
 EXPORT_SYMBOL(__memcpy)
 
+SYM_FUNC_ALIAS_WEAK(memcpy, __memcpy)
+EXPORT_SYMBOL(memcpy)
+
 /*
  * memcpy_erms() - enhanced fast string memcpy. This is faster and
  * simpler than memcpy. Use memcpy_erms when possible.
diff --git a/tools/arch/x86/lib/memset_64.S b/tools/arch/x86/lib/memset_64.S
index d624f2bc42f16..fc9ffd3ff3b21 100644
--- a/tools/arch/x86/lib/memset_64.S
+++ b/tools/arch/x86/lib/memset_64.S
@@ -17,7 +17,6 @@
  *
  * rax   original destination
  */
-SYM_FUNC_START_WEAK(memset)
 SYM_FUNC_START(__memset)
 	/*
 	 * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
@@ -42,10 +41,11 @@ SYM_FUNC_START(__memset)
 	movq %r9,%rax
 	RET
 SYM_FUNC_END(__memset)
-SYM_FUNC_END_ALIAS(memset)
-EXPORT_SYMBOL(memset)
 EXPORT_SYMBOL(__memset)
 
+SYM_FUNC_ALIAS_WEAK(memset, __memset)
+EXPORT_SYMBOL(memset)
+
 /*
  * ISO C memset - set a memory block to a byte value. This function uses
  * enhanced rep stosb to override the fast string function.
diff --git a/tools/perf/util/include/linux/linkage.h b/tools/perf/util/include/linux/linkage.h
index 5acf053fca7d4..b8edb5059bd6d 100644
--- a/tools/perf/util/include/linux/linkage.h
+++ b/tools/perf/util/include/linux/linkage.h
@@ -32,59 +32,59 @@
 
 /* === generic annotations === */
 
+#ifndef SYM_ENTRY_AT
+#define SYM_ENTRY_AT(name, location, linkage)		\
+	linkage(name) ASM_NL				\
+	.set .L____sym_entry__##name, location ASM_NL	\
+	.set name, location ASM_NL
+#endif
+
 /* SYM_ENTRY -- use only if you have to for non-paired symbols */
 #ifndef SYM_ENTRY
 #define SYM_ENTRY(name, linkage, align...)		\
-	linkage(name) ASM_NL				\
 	align ASM_NL					\
-	name:
+	SYM_ENTRY_AT(name, ., linkage)
+#endif
+
+/* SYM_START_AT -- use only if you have to */
+#ifndef SYM_START_AT
+#define SYM_START_AT(name, location, linkage)		\
+	SYM_ENTRY_AT(name, location, linkage)
 #endif
 
 /* SYM_START -- use only if you have to */
 #ifndef SYM_START
 #define SYM_START(name, linkage, align...)		\
-	SYM_ENTRY(name, linkage, align)
+	align ASM_NL					\
+	SYM_START_AT(name, ., linkage)
 #endif
 
-/* SYM_END -- use only if you have to */
-#ifndef SYM_END
-#define SYM_END(name, sym_type)				\
+/* SYM_END_AT -- use only if you have to */
+#ifndef SYM_END_AT
+#define SYM_END_AT(name, location, sym_type)		\
 	.type name sym_type ASM_NL			\
-	.size name, .-name
+	.set .L____sym_end__##name, location ASM_NL	\
+	.size name, location-name ASM_NL
 #endif
 
-/*
- * SYM_FUNC_START_ALIAS -- use where there are two global names for one
- * function
- */
-#ifndef SYM_FUNC_START_ALIAS
-#define SYM_FUNC_START_ALIAS(name)			\
-	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
+/* SYM_END -- use only if you have to */
+#ifndef SYM_END
+#define SYM_END(name, sym_type)				\
+	SYM_END_AT(name, ., sym_type)
 #endif
 
 /* SYM_FUNC_START -- use for global functions */
 #ifndef SYM_FUNC_START
-/*
- * The same as SYM_FUNC_START_ALIAS, but we will need to distinguish these two
- * later.
- */
 #define SYM_FUNC_START(name)				\
 	SYM_START(name, SYM_L_GLOBAL, SYM_A_ALIGN)
 #endif
 
 /* SYM_FUNC_START_LOCAL -- use for local functions */
 #ifndef SYM_FUNC_START_LOCAL
-/* the same as SYM_FUNC_START_LOCAL_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_START_LOCAL(name)			\
 	SYM_START(name, SYM_L_LOCAL, SYM_A_ALIGN)
 #endif
 
-/* SYM_FUNC_END_ALIAS -- the end of LOCAL_ALIASed or ALIASed function */
-#ifndef SYM_FUNC_END_ALIAS
-#define SYM_FUNC_END_ALIAS(name)			\
-	SYM_END(name, SYM_T_FUNC)
-#endif
-
 /* SYM_FUNC_START_WEAK -- use for weak functions */
 #ifndef SYM_FUNC_START_WEAK
 #define SYM_FUNC_START_WEAK(name)			\
@@ -96,9 +96,35 @@
  * SYM_FUNC_START_WEAK, ...
  */
 #ifndef SYM_FUNC_END
-/* the same as SYM_FUNC_END_ALIAS, see comment near SYM_FUNC_START */
 #define SYM_FUNC_END(name)				\
 	SYM_END(name, SYM_T_FUNC)
 #endif
 
-#endif	/* PERF_LINUX_LINKAGE_H_ */
+/*
+ * SYM_FUNC_ALIAS_LOCAL -- define a local alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_LOCAL
+#define SYM_FUNC_ALIAS_LOCAL(alias, name)				\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_LOCAL)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS -- define a global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS
+#define SYM_FUNC_ALIAS(alias, name)					\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_GLOBAL)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
+/*
+ * SYM_FUNC_ALIAS_WEAK -- define a weak global alias for an existing function
+ */
+#ifndef SYM_FUNC_ALIAS_WEAK
+#define SYM_FUNC_ALIAS_WEAK(alias, name)				\
+	SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_WEAK)	\
+	SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
+#endif
+
+#endif /* PERF_LINUX_LINKAGE_H */
-- 
2.30.2



From qii.wang at mediatek.com  Tue Jan 25 03:27:44 2022
From: qii.wang at mediatek.com (Qii Wang)
Date: Tue, 25 Jan 2022 19:27:44 +0800
Subject: [v2 2/2] i2c: mediatek: Add i2c compatible for Mediatek MT8186
In-Reply-To: <20220125110413.18988-3-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
 <20220125110413.18988-3-kewei.xu@mediatek.com>
Message-ID: <1d9b53a22e307ca90cafbd6fe08fbae3c4c58531.camel@mediatek.com>

On Tue, 2022-01-25 at 19:04 +0800, Kewei Xu wrote:
> Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
> MT8186 doesn't need handshake signal witch apdma.
> 
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>

Reviewed-by: Qii Wang <qii.wang at mediatek.com>

> ---
>  drivers/i2c/busses/i2c-mt65xx.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-mt65xx.c
> b/drivers/i2c/busses/i2c-mt65xx.c
> index 9ea427f53083..aa4d21838e14 100644
> --- a/drivers/i2c/busses/i2c-mt65xx.c
> +++ b/drivers/i2c/busses/i2c-mt65xx.c
> @@ -397,6 +397,19 @@ static const struct mtk_i2c_compatible
> mt8183_compat = {
>  	.max_dma_support = 33,
>  };
>  
> +static const struct mtk_i2c_compatible mt8186_compat = {
> +	.regs = mt_i2c_regs_v2,
> +	.pmic_i2c = 0,
> +	.dcm = 0,
> +	.auto_restart = 1,
> +	.aux_len_reg = 1,
> +	.timing_adjust = 1,
> +	.dma_sync = 0,
> +	.ltiming_adjust = 1,
> +	.apdma_sync = 0,
> +	.max_dma_support = 36,
> +};
> +
>  static const struct mtk_i2c_compatible mt8192_compat = {
>  	.quirks = &mt8183_i2c_quirks,
>  	.regs = mt_i2c_regs_v2,
> @@ -418,6 +431,7 @@ static const struct of_device_id
> mtk_i2c_of_match[] = {
>  	{ .compatible = "mediatek,mt7622-i2c", .data = &mt7622_compat
> },
>  	{ .compatible = "mediatek,mt8173-i2c", .data = &mt8173_compat
> },
>  	{ .compatible = "mediatek,mt8183-i2c", .data = &mt8183_compat
> },
> +	{ .compatible = "mediatek,mt8186-i2c", .data = &mt8186_compat
> },
>  	{ .compatible = "mediatek,mt8192-i2c", .data = &mt8192_compat
> },
>  	{}
>  };

From john at metanate.com  Tue Jan 25 03:50:07 2022
From: john at metanate.com (John Keeping)
Date: Tue, 25 Jan 2022 11:50:07 +0000
Subject: [PATCH] ARM: dts: rockchip: fix MMC compatibles for rk3288
Message-ID: <20220125115007.3138311-1-john@metanate.com>

Prior to commit 4bac670aa5cb ("mmc: dw_mmc: rockchip: use common_caps")
the mshcN aliases were used in an unusual way by the dw_mmc driver and
affected behaviour.  Now that this has been fixed, rename the mmc
aliases to use the standard form.

Signed-off-by: John Keeping <john at metanate.com>
---
 arch/arm/boot/dts/rk3288.dtsi | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index aaaa61875701..50fa0a4652b5 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -25,10 +25,10 @@ aliases {
 		i2c3 = &i2c3;
 		i2c4 = &i2c4;
 		i2c5 = &i2c5;
-		mshc0 = &emmc;
-		mshc1 = &sdmmc;
-		mshc2 = &sdio0;
-		mshc3 = &sdio1;
+		mmc0 = &emmc;
+		mmc1 = &sdmmc;
+		mmc2 = &sdio0;
+		mmc3 = &sdio1;
 		serial0 = &uart0;
 		serial1 = &uart1;
 		serial2 = &uart2;
-- 
2.35.0



From maz at kernel.org  Tue Jan 25 03:59:02 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 11:59:02 +0000
Subject: [PATCH v8 26/38] KVM: arm64: Handle SME host state when running
 guests
In-Reply-To: <20220125001114.193425-27-broonie@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-27-broonie@kernel.org>
Message-ID: <87wnio6n7d.wl-maz@kernel.org>

On Tue, 25 Jan 2022 00:11:02 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> While we don't currently support SME in guests we do currently support it
> for the host system so we need to take care of SME's impact, including
> the floating point register state, when running guests. Simiarly to SVE
> we need to manage the traps in CPACR_RL1, what is new is the handling of
> streaming mode and ZA.
> 
> Normally we defer any handling of the floating point register state until
> the guest first uses it however if the system is in streaming mode FPSIMD
> and SVE operations may generate SME traps which we would need to distinguish
> from actual attempts by the guest to use SME. Rather than do this for the
> time being if we are in streaming mode when entering the guest we force
> the floating point state to be saved immediately and exit streaming mode,
> meaning that the guest won't generate SME traps for supported operations.
> 
> We could handle ZA in the access trap similarly to the FPSIMD/SVE state
> without the disruption caused by streaming mode but for simplicity
> handle it the same way as streaming mode for now.
> 
> This will be revisited when we support SME for guests (hopefully before SME
> hardware becomes available), for now it will only incur additional cost on
> systems with SME and even there only if streaming mode or ZA are enabled.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  arch/arm64/include/asm/kvm_host.h |  1 +
>  arch/arm64/kvm/fpsimd.c           | 38 +++++++++++++++++++++++++++++++
>  2 files changed, 39 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 7dc85d5a6552..404b7358ba96 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -438,6 +438,7 @@ struct kvm_vcpu_arch {
>  #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
>  #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
>  #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
> +#define KVM_ARM64_HOST_SME_ENABLED	(1 << 15) /* SME enabled for EL0 */
>  
>  #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
>  				 KVM_GUESTDBG_USE_SW_BP | \
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index 338733ac63f8..cecaddb644ce 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -82,6 +82,26 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
>  
>  	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
>  		vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
> +
> +	/*
> +	 * We don't currently support SME guests but if we leave
> +	 * things in streaming mode then when the guest starts running
> +	 * FPSIMD or SVE code it may generate SME traps so as a
> +	 * special case if we are in streaming mode we force the host
> +	 * state to be saved now and exit streaming mode so that we
> +	 * don't have to handle any SME traps for valid guest
> +	 * operations. Do this for ZA as well for now for simplicity.
> +	 */
> +	if (system_supports_sme()) {
> +		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
> +			vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED;
> +
> +		if (read_sysreg_s(SYS_SVCR_EL0) &
> +		    (SYS_SVCR_EL0_SM_MASK | SYS_SVCR_EL0_ZA_MASK)) {
> +			vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
> +			fpsimd_save_and_flush_cpu_state();
> +		}
> +	}
>  }
>  
>  void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
> @@ -129,6 +149,24 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
>  
>  	local_irq_save(flags);
>  
> +	/*
> +	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
> +	 * CPACR_EL1_DEFAULT and we need to reenable SME.
> +	 */
> +	if (has_vhe()) {
> +		if (system_supports_sme()) {

nit:	if (has_vhe() && system_supports_sme()) {

saves you one level of indentation.

> +			/* Also restore EL0 state seen on entry */
> +			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
> +				sysreg_clear_set(CPACR_EL1, 0,
> +						 CPACR_EL1_SMEN_EL0EN |
> +						 CPACR_EL1_SMEN_EL1EN);
> +			else
> +				sysreg_clear_set(CPACR_EL1,
> +						 CPACR_EL1_SMEN_EL0EN,
> +						 CPACR_EL1_SMEN_EL1EN);

I find the use of CPACR_EL1_SMEN in some cases and its individual bits
in some others pretty confusing. I understand that you have modelled
it after the SVE code, but maybe this is a mistake we don't need to
repeat. I'd be in favour of directly exposing the individual bits in
all cases.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From hverkuil-cisco at xs4all.nl  Tue Jan 25 04:07:49 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Jan 2022 13:07:49 +0100
Subject: [PATCH v15 00/13] amphion video decoder/encoder driver
In-Reply-To: <cover.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
Message-ID: <2c3fcd05-35da-02e4-cd69-4a6e369d7005@xs4all.nl>

Hi Ming,

Can you take a look at the kernel test robot warnings? I suspect you're missing
a header (linux/vmalloc.h?) for vzalloc et al that the alpha architecture doesn't
automatically include.

If it is just adding a single include in a single patch, then just post a 15.1 for
that patch. If it is more complicated, then posting a v16 is easier.

Regards,

	Hans

On 25/01/2022 08:11, Ming Qian wrote:
> Hi all,
> 
> This patch series adds support for
> the amphion video encoder and decoder
> via the VPU block present in imx8q platforms.
> Currently, support for IMX8QXP and IMX8QM is included.
> 
> It features decoding for the following formats:
> - H.264
> - HEVC
> - MPEG4
> - MPEG2
> - VC1
> - VP8
> 
> It features encoding for the following formats:
> - H.264
> 
> The driver creates a separate device node for the encoder and decoder.
> 
> This driver is dependent on vpu firmwares.
> The firmwares have been submitted to linux-firmware.
> The firmware patch is since commit
> b563148fd28623f6b6ce68bb06c3dd3bd138b058:
> linux-firmware: Update firmware file for Intel Bluetooth 9462
> (Fri Oct 8 16:30:14 2021 +0530)
> 
> and it's available in the git repository at:
>     https://github.com/mingqian-0/linux-firmware.git
> 
> for you to fetch changes up to bb3eee4f99589d4910dee4c053a3a685546b5dbb:
> amphion: add VPU firmwares for NXP i.MX8Q SoCs
> (Tue Oct 12 15:09:57 2021 +0800)
> 
> encoder is tested with gstreamer
> decoder is tested with gstreamer, but the following patches are required:
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1379
> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1381
> 
> 
> Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> 
> 
> Changelog:
> 
> v15
> - fix issues detected by "checkpatch.pl --strict"
> - encoder add ctrl V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
> 
> v14
> - fix some errors according to Hans's comments
> 
> v13
> - make a workaround that avoid firmware entering wfi wrongly
> 
> v12
> - support reset decoder when starting a new stream
> - don't append an empty last buffer, set last_buffer_dequeued
> - improve the resolution change flow
> - return all buffers if start_streaming fail
> - fill encoder capture buffer's filed to none
> - fix a bug in calculating bytesperline
> 
> v11
> - fix dt_binding_check error after upgrade dtschema
> - remove "default y"
> - add media device
> 
> v10
> - refine vpu log, remove custom logging infrastructure
> - support non contiguous planes format nv12m instead of nv12
> - rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
> - rename V4L2_PIX_FMT_NV12_10BE_8L128 to V4L2_PIX_FMT_NV12MT_10BE_8L128
> - merge two module into one
> - fix kernel panic in rmmod
> 
> v9
> - drop V4L2_BUF_FLAG_CODECCONFIG
> - drop V4L2_EVENT_CODEC_ERROR
> - drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
> - fix some build warnings with W=1 reported by kernel test robot
> 
> v8
> - move driver from driver/media/platform/imx/vpu-8q to
>   driver/media/platform/amphion
> - rename driver name to amphion
> - remove imx_vpu.h
> - move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
> - move the definition of V4L2_EVENT_SKIP to videodev2.h
> 
> v7
> - fix build warnings with W=1 reported by kernel test robot
> 
> v6:
> - rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
> - rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128
> 
> v5:
> - move some definition from imx_vph.h to videodev2.h
> - remove some unnecessary content
> - add some documentation descriptions
> - pass the lateset v4l2-compliance test
> 
> v4:
> - redefine the memory-region in devicetree bindings documentation
> - use v4l2's mechanism to implement synchronize queuing ioctl
> - remove the unnecessary mutex ioctl_sync
> - don't notify source change event if the parameters are same as previously established
> - add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format
> 
> v3:
> - don't make vpu device node a simple-bus
> - trigger probing vpu core in the driver
> - remove unnecessary vpu core index property
> 
> v2:
> - fix dt bindings build error
> - split driver patch into several parts to avoid exceeding bytes limit
> 
> Compliance
> ==========
> # v4l2-compliance -d /dev/video0
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/video0:
> 
> Driver Info:
> 	Driver name      : amphion-vpu
> 	Card type        : amphion vpu decoder
> 	Bus info         : platform: amphion-vpu
> 	Driver version   : 5.15.0
> 	Capabilities     : 0x84204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 		Device Capabilities
> 	Device Caps      : 0x04204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 	Detected Stateful Decoder
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> Interface Info:
> 	ID               : 0x0300000c
> 	Type             : V4L Video
> Entity Info:
> 	ID               : 0x00000001 (1)
> 	Name             : amphion-vpu-decoder-source
> 	Function         : V4L2 I/O
> 	Pad 0x01000002   : 0: Source
> 	  Link 0x02000008: to remote pad 0x1000004 of entity 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable
> 
> Required ioctls:
> 	test MC information (see 'Media Driver Info' above): OK
> 	test VIDIOC_QUERYCAP: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/video0 open: OK
> 	test VIDIOC_QUERYCAP: OK
> 	test VIDIOC_G/S_PRIORITY: OK
> 	test for unlimited opens: OK
> 
> Debug ioctls:
> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
> 
> Input ioctls:
> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
> 
> Output ioctls:
> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
> 
> Input/Output configuration ioctls:
> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> 	test VIDIOC_G/S_EDID: OK (Not Supported)
> 
> Control ioctls:
> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> 	test VIDIOC_QUERYCTRL: OK
> 	test VIDIOC_G/S_CTRL: OK
> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> 	Standard Controls: 3 Private Controls: 0
> 
> Format ioctls:
> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> 	test VIDIOC_G/S_PARM: OK (Not Supported)
> 	test VIDIOC_G_FBUF: OK (Not Supported)
> 	test VIDIOC_G_FMT: OK
> 	test VIDIOC_TRY_FMT: OK
> 	test VIDIOC_S_FMT: OK
> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> 	test Cropping: OK (Not Supported)
> 	test Composing: OK
> 	test Scaling: OK (Not Supported)
> 
> Codec ioctls:
> 	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> 	test VIDIOC_(TRY_)DECODER_CMD: OK
> 
> Buffer ioctls:
> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> 	test VIDIOC_EXPBUF: OK
> 	test Requests: OK (Not Supported)
> 
> Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0
> 
> # v4l2-compliance -d /dev/video1
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/video1:
> 
> Driver Info:
> 	Driver name      : amphion-vpu
> 	Card type        : amphion vpu encoder
> 	Bus info         : platform: amphion-vpu
> 	Driver version   : 5.15.0
> 	Capabilities     : 0x84204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 		Device Capabilities
> 	Device Caps      : 0x04204000
> 		Video Memory-to-Memory Multiplanar
> 		Streaming
> 		Extended Pix Format
> 	Detected Stateful Encoder
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> Interface Info:
> 	ID               : 0x0300001a
> 	Type             : V4L Video
> Entity Info:
> 	ID               : 0x0000000f (15)
> 	Name             : amphion-vpu-encoder-source
> 	Function         : V4L2 I/O
> 	Pad 0x01000010   : 0: Source
> 	  Link 0x02000016: to remote pad 0x1000012 of entity 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable
> 
> Required ioctls:
> 	test MC information (see 'Media Driver Info' above): OK
> 	test VIDIOC_QUERYCAP: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/video1 open: OK
> 	test VIDIOC_QUERYCAP: OK
> 	test VIDIOC_G/S_PRIORITY: OK
> 	test for unlimited opens: OK
> 
> Debug ioctls:
> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
> 
> Input ioctls:
> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
> 
> Output ioctls:
> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
> 
> Input/Output configuration ioctls:
> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> 	test VIDIOC_G/S_EDID: OK (Not Supported)
> 
> Control ioctls:
> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> 	test VIDIOC_QUERYCTRL: OK
> 	test VIDIOC_G/S_CTRL: OK
> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> 	Standard Controls: 20 Private Controls: 0
> 
> Format ioctls:
> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> 	test VIDIOC_G/S_PARM: OK
> 	test VIDIOC_G_FBUF: OK (Not Supported)
> 	test VIDIOC_G_FMT: OK
> 	test VIDIOC_TRY_FMT: OK
> 	test VIDIOC_S_FMT: OK
> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> 	test Cropping: OK
> 	test Composing: OK (Not Supported)
> 	test Scaling: OK (Not Supported)
> 
> Codec ioctls:
> 	test VIDIOC_(TRY_)ENCODER_CMD: OK
> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> 	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
> 
> Buffer ioctls:
> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> 	test VIDIOC_EXPBUF: OK
> 	test Requests: OK (Not Supported)
> 
> Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed: 0, Warnings: 0
> 
> # v4l2-compliance -d /dev/media0
> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
> 
> Compliance test for amphion-vpu device /dev/media0:
> 
> Media Driver Info:
> 	Driver name      : amphion-vpu
> 	Model            : amphion-vpu
> 	Serial           :
> 	Bus info         : platform: amphion-vpu
> 	Media version    : 5.15.0
> 	Hardware revision: 0x00000000 (0)
> 	Driver version   : 5.15.0
> 
> Required ioctls:
> 	test MEDIA_IOC_DEVICE_INFO: OK
> 	test invalid ioctls: OK
> 
> Allow for multiple opens:
> 	test second /dev/media0 open: OK
> 	test MEDIA_IOC_DEVICE_INFO: OK
> 	test for unlimited opens: OK
> 
> Media Controller ioctls:
> 	test MEDIA_IOC_G_TOPOLOGY: OK
> 	Entities: 6 Interfaces: 2 Pads: 8 Links: 8
> 	test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
> 	test MEDIA_IOC_SETUP_LINK: OK
> 
> Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0
> 
> Ming Qian (13):
>   dt-bindings: media: amphion: add amphion video codec bindings
>   media: add nv12m_8l128 and nv12m_10be_8l128 video format.
>   media: amphion: add amphion vpu device driver
>   media: amphion: add vpu core driver
>   media: amphion: implement vpu core communication based on mailbox
>   media: amphion: add vpu v4l2 m2m support
>   media: amphion: add v4l2 m2m vpu encoder stateful driver
>   media: amphion: add v4l2 m2m vpu decoder stateful driver
>   media: amphion: implement windsor encoder rpc interface
>   media: amphion: implement malone decoder rpc interface
>   ARM64: dts: freescale: imx8q: add imx vpu codec entries
>   firmware: imx: scu-pd: imx8q: add vpu mu resources
>   MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
> 
>  .../bindings/media/amphion,vpu.yaml           |  180 ++
>  .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
>  MAINTAINERS                                   |    9 +
>  .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
>  arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
>  arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
>  arch/arm64/configs/defconfig                  |    1 +
>  drivers/firmware/imx/scu-pd.c                 |    4 +
>  drivers/media/platform/Kconfig                |   19 +
>  drivers/media/platform/Makefile               |    2 +
>  drivers/media/platform/amphion/Makefile       |   20 +
>  drivers/media/platform/amphion/vdec.c         | 1694 +++++++++++++++++
>  drivers/media/platform/amphion/venc.c         | 1364 +++++++++++++
>  drivers/media/platform/amphion/vpu.h          |  356 ++++
>  drivers/media/platform/amphion/vpu_cmds.c     |  436 +++++
>  drivers/media/platform/amphion/vpu_cmds.h     |   25 +
>  drivers/media/platform/amphion/vpu_codec.h    |   68 +
>  drivers/media/platform/amphion/vpu_color.c    |  183 ++
>  drivers/media/platform/amphion/vpu_core.c     |  870 +++++++++
>  drivers/media/platform/amphion/vpu_core.h     |   15 +
>  drivers/media/platform/amphion/vpu_dbg.c      |  495 +++++
>  drivers/media/platform/amphion/vpu_defs.h     |  187 ++
>  drivers/media/platform/amphion/vpu_drv.c      |  260 +++
>  drivers/media/platform/amphion/vpu_helpers.c  |  413 ++++
>  drivers/media/platform/amphion/vpu_helpers.h  |   74 +
>  drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
>  drivers/media/platform/amphion/vpu_imx8q.h    |  115 ++
>  drivers/media/platform/amphion/vpu_malone.c   | 1625 ++++++++++++++++
>  drivers/media/platform/amphion/vpu_malone.h   |   44 +
>  drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
>  drivers/media/platform/amphion/vpu_mbox.h     |   16 +
>  drivers/media/platform/amphion/vpu_msgs.c     |  385 ++++
>  drivers/media/platform/amphion/vpu_msgs.h     |   14 +
>  drivers/media/platform/amphion/vpu_rpc.c      |  257 +++
>  drivers/media/platform/amphion/vpu_rpc.h      |  456 +++++
>  drivers/media/platform/amphion/vpu_v4l2.c     |  720 +++++++
>  drivers/media/platform/amphion/vpu_v4l2.h     |   55 +
>  drivers/media/platform/amphion/vpu_windsor.c  | 1169 ++++++++++++
>  drivers/media/platform/amphion/vpu_windsor.h  |   37 +
>  drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
>  include/uapi/linux/videodev2.h                |    2 +
>  41 files changed, 12099 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
>  create mode 100644 drivers/media/platform/amphion/Makefile
>  create mode 100644 drivers/media/platform/amphion/vdec.c
>  create mode 100644 drivers/media/platform/amphion/venc.c
>  create mode 100644 drivers/media/platform/amphion/vpu.h
>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
>  create mode 100644 drivers/media/platform/amphion/vpu_codec.h
>  create mode 100644 drivers/media/platform/amphion/vpu_color.c
>  create mode 100644 drivers/media/platform/amphion/vpu_core.c
>  create mode 100644 drivers/media/platform/amphion/vpu_core.h
>  create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
>  create mode 100644 drivers/media/platform/amphion/vpu_defs.h
>  create mode 100644 drivers/media/platform/amphion/vpu_drv.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
>  create mode 100644 drivers/media/platform/amphion/vpu_malone.c
>  create mode 100644 drivers/media/platform/amphion/vpu_malone.h
>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.h
> 
> 
> base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07



From zajec5 at gmail.com  Tue Jan 25 04:08:58 2022
From: zajec5 at gmail.com (=?UTF-8?B?UmFmYcWCIE1pxYJlY2tp?=)
Date: Tue, 25 Jan 2022 13:08:58 +0100
Subject: [PATCH 6/8] nvmem: transformations: ethernet address offset
 support
In-Reply-To: <20211228142549.1275412-7-michael@walle.cc>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-7-michael@walle.cc>
Message-ID: <455f4360-34fe-7fee-66d5-fd945fe1e086@gmail.com>

On 28.12.2021 15:25, Michael Walle wrote:
> An nvmem cell might just contain a base MAC address. To generate a
> address of a specific interface, add a transformation to add an offset
> to this base address.
> 
> Add a generic implementation and the first user of it, namely the sl28
> vpd storage.
> 
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
>   drivers/nvmem/transformations.c | 45 +++++++++++++++++++++++++++++++++
>   1 file changed, 45 insertions(+)
> 
> diff --git a/drivers/nvmem/transformations.c b/drivers/nvmem/transformations.c
> index 61642a9feefb..15cd26da1f83 100644
> --- a/drivers/nvmem/transformations.c
> +++ b/drivers/nvmem/transformations.c
> @@ -12,7 +12,52 @@ struct nvmem_transformations {
>   	nvmem_cell_post_process_t pp;
>   };
>   
> +/**
> + * nvmem_transform_mac_address_offset() - Add an offset to a mac address cell
> + *
> + * A simple transformation which treats the index argument as an offset and add
> + * it to a mac address. This is useful, if the nvmem cell stores a base
> + * ethernet address.
> + *
> + * @index: nvmem cell index
> + * @data: nvmem data
> + * @bytes: length of the data
> + *
> + * Return: 0 or negative error code on failure.
> + */
> +static int nvmem_transform_mac_address_offset(int index, unsigned int offset,
> +					      void *data, size_t bytes)
> +{
> +	if (bytes != ETH_ALEN)
> +		return -EINVAL;
> +
> +	if (index < 0)
> +		return -EINVAL;
> +
> +	if (!is_valid_ether_addr(data))
> +		return -EINVAL;
> +
> +	eth_addr_add(data, index);
> +
> +	return 0;
> +}
> +
> +static int nvmem_kontron_sl28_vpd_pp(void *priv, const char *id, int index,
> +				     unsigned int offset, void *data,
> +				     size_t bytes)
> +{
> +	if (!id)
> +		return 0;
> +
> +	if (!strcmp(id, "mac-address"))
> +		return nvmem_transform_mac_address_offset(index, offset, data,
> +							  bytes);
> +
> +	return 0;
> +}
> +
>   static const struct nvmem_transformations nvmem_transformations[] = {
> +	{ .compatible = "kontron,sl28-vpd", .pp = nvmem_kontron_sl28_vpd_pp },
>   	{}
>   };

I think it's a rather bad solution that won't scale well at all.

You'll end up with a lot of NVMEM device specific strings and code in a
NVMEM core.

You'll have a lot of duplicated code (many device specific functions
calling e.g. nvmem_transform_mac_address_offset()).

I think it also ignores fact that one NVMEM device can be reused in
multiple platforms / device models using different (e.g. vendor / device
specific) cells.


What if we have:
1. Foo company using "kontron,sl28-vpd" with NVMEM cells:
    a. "mac-address"
    b. "mac-address-2"
    c. "mac-address-3"
2. Bar company using "kontron,sl28-vpd" with NVMEM cell:
    a. "mac-address"

In the first case you don't want any transformation.


If you consider using transformations for ASCII formats too then it
causes another conflict issue. Consider two devices:

1. Foo company device with BIN format of MAC
2. Bar company device with ASCII format of MAC

Both may use exactly the same binding:

partition at 0 {
         compatible = "nvmem-cells";
         reg = <0x0 0x100000>;
         label = "bootloader";

         #address-cells = <1>;
         #size-cells = <1>;

         mac-address at 100 {
                 reg = <0x100 0x6>;
         };
};

how are you going to handle them with proposed implementation? You can't
support both if you share "nvmem-cells" compatible string.


I think that what can solve those problems is assing "compatible" to
NVMEM cells.

Let me think about details of that possible solution.


From broonie at kernel.org  Tue Jan 25 04:10:28 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 12:10:28 +0000
Subject: [PATCH v8 01/38] arm64: cpufeature: Always specify and use a
 field width for capabilities
In-Reply-To: <edc0a8a0-5439-ff34-3de0-89ae0a4e60f4@arm.com>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-2-broonie@kernel.org>
 <edc0a8a0-5439-ff34-3de0-89ae0a4e60f4@arm.com>
Message-ID: <Ye/otP4coRNRxS5P@sirena.org.uk>

On Tue, Jan 25, 2022 at 10:57:47AM +0000, Suzuki K Poulose wrote:
> On 25/01/2022 00:10, Mark Brown wrote:

> > +	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
> > +						    entry->field_width,
> > +						    entry->sign);

> Could we do something like :

> + int val = cpuid_feature_extract_field_width(reg, 		entry->field_pos,
> 		entry->field_width ? : 4,
> 		..
> 		);

> and leave the existing structures as they are ?

Obviously we *could* (ideally without the ternery operator) but having
the implicit default like that makes me nervous that it's too easy to
just forget to fill it in and get the wrong default.

> And that could avoid these changes too. We could add :

> #define HWCAP_CPUID_MATCH_WIDTH(...)

> when/if we need one, which sets the width.

I'd originally had a completely separate set of definitions for single
bit fields but Catlain wanted to get everything in one.  I'm not sure I
see a huge advantage in sharing the match function and not also sharing
the macro TBH.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/c9d8ca7a/attachment.sig>

From jbx6244 at gmail.com  Tue Jan 25 04:14:21 2022
From: jbx6244 at gmail.com (Johan Jonker)
Date: Tue, 25 Jan 2022 13:14:21 +0100
Subject: [PATCH] ARM: dts: rockchip: fix MMC compatibles for rk3288
In-Reply-To: <20220125115007.3138311-1-john@metanate.com>
References: <20220125115007.3138311-1-john@metanate.com>
Message-ID: <7e935740-66a3-da07-a196-0584dab310b9@gmail.com>

Hi John,

MMC aliases should go in the dts board files.
Sort on reg address, based on availability and without number gab.
(For rk3288 a lot of boards to change. That's why it wasn't done
yet...Could someone pick that up?)

Johan

On 1/25/22 12:50, John Keeping wrote:
> Prior to commit 4bac670aa5cb ("mmc: dw_mmc: rockchip: use common_caps")
> the mshcN aliases were used in an unusual way by the dw_mmc driver and
> affected behaviour.  Now that this has been fixed, rename the mmc
> aliases to use the standard form.
> 
> Signed-off-by: John Keeping <john at metanate.com>
> ---
>  arch/arm/boot/dts/rk3288.dtsi | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> index aaaa61875701..50fa0a4652b5 100644
> --- a/arch/arm/boot/dts/rk3288.dtsi
> +++ b/arch/arm/boot/dts/rk3288.dtsi
> @@ -25,10 +25,10 @@ aliases {
>  		i2c3 = &i2c3;
>  		i2c4 = &i2c4;
>  		i2c5 = &i2c5;
> -		mshc0 = &emmc;
> -		mshc1 = &sdmmc;
> -		mshc2 = &sdio0;
> -		mshc3 = &sdio1;
> +		mmc0 = &emmc;
> +		mmc1 = &sdmmc;
> +		mmc2 = &sdio0;
> +		mmc3 = &sdio1;
>  		serial0 = &uart0;
>  		serial1 = &uart1;
>  		serial2 = &uart2;


From broonie at kernel.org  Tue Jan 25 04:15:29 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 12:15:29 +0000
Subject: [PATCH v8 05/38] arm64/sme: System register and exception
 syndrome definitions
In-Reply-To: <87zgnk6or8.wl-maz@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-6-broonie@kernel.org>
 <87zgnk6or8.wl-maz@kernel.org>
Message-ID: <Ye/p4YpWWnZSPFaZ@sirena.org.uk>

On Tue, Jan 25, 2022 at 11:25:31AM +0000, Marc Zyngier wrote:
> On Tue, 25 Jan 2022 00:10:41 +0000,
> Mark Brown <broonie at kernel.org> wrote:

> > +/* HFG[WR]TR_EL2 bit definitions */
> > +#define HFGxTR_EL2_nTPIDR_EL0_SHIFT	55
> > +#define HFGxTR_EL2_nTPIDR_EL0_MASK	(1 << HFGxTR_EL2_nTPIDR_EL0_SHIFT)

> This annoyingly clashes with bit 35 of the same registers, which maps
> to TPIDR_EL0. I have the feeling that this really should be TPIDR2_EL0.

Yes, it should be.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/3a3bb06c/attachment.sig>

From Jason at zx2c4.com  Tue Jan 25 04:23:34 2022
From: Jason at zx2c4.com (Jason A. Donenfeld)
Date: Tue, 25 Jan 2022 13:23:34 +0100
Subject: [PATCH v2] lib/crypto: blake2s: avoid indirect calls to
 compression function for Clang CFI
In-Reply-To: <Ye+bam3aSIjz8n9E@sol.localdomain>
References: <20220119135450.564115-1-Jason@zx2c4.com>
 <20220124192849.14755-1-Jason@zx2c4.com>
 <Ye+bam3aSIjz8n9E@sol.localdomain>
Message-ID: <CAHmME9oQuKLo2D_OGMy-8PS-u=a-ERvP+1L7RvpjJ2_xBaM5eQ@mail.gmail.com>

On 1/25/22, Eric Biggers <ebiggers at kernel.org> wrote:
> On Mon, Jan 24, 2022 at 08:28:49PM +0100, Jason A. Donenfeld wrote:
>> blake2s_compress_generic is weakly aliased by blake2s_generic. The
>
> Don't you mean "weakly aliased by blake2s_compress"?

Grrrr. Thanks.

>> Changes v1->v2:
>> - Wrapped columns at 80 for Eric.
>
> It is the recommended coding style, so not just for me :-)

I was under the impression this increased to 100 mid-2020 or so, and
checkpatch.pl now makes noise at that width instead.


From hverkuil-cisco at xs4all.nl  Tue Jan 25 04:24:25 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Jan 2022 13:24:25 +0100
Subject: [PATCH v15 12/13] firmware: imx: scu-pd: imx8q: add vpu mu
 resources
In-Reply-To: <8717d91000002047c7d0925f5eae66fc7f795e27.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
 <8717d91000002047c7d0925f5eae66fc7f795e27.1643077283.git.ming.qian@nxp.com>
Message-ID: <7e49399a-beb1-9dda-8bae-b715162f4fb9@xs4all.nl>

Shawn, can you Ack this? I think it makes sense if I take this one through the
media subsystem.

Alternatively, if you prefer to take this patch yourself, then let me know.

Regards,

	Hans

On 25/01/2022 08:11, Ming Qian wrote:
> the vpu core depends on the mu resources.
> if they're missed, the vpu can't work.
> 
> Signed-off-by: Ming Qian <ming.qian at nxp.com>
> Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
> Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
> ---
>  drivers/firmware/imx/scu-pd.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
> index ff6569c4a53b..af3d057e6421 100644
> --- a/drivers/firmware/imx/scu-pd.c
> +++ b/drivers/firmware/imx/scu-pd.c
> @@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
>  	{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
>  	{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
>  	{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
> +	{ "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
> +	{ "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
> +	{ "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
> +	{ "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
>  
>  	/* GPU SS */
>  	{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },



From hverkuil-cisco at xs4all.nl  Tue Jan 25 04:25:35 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Tue, 25 Jan 2022 13:25:35 +0100
Subject: [PATCH v15 00/13] amphion video decoder/encoder driver
In-Reply-To: <2c3fcd05-35da-02e4-cd69-4a6e369d7005@xs4all.nl>
References: <cover.1643077283.git.ming.qian@nxp.com>
 <2c3fcd05-35da-02e4-cd69-4a6e369d7005@xs4all.nl>
Message-ID: <1f886665-45c4-a94d-a417-d75504fcda44@xs4all.nl>

On 25/01/2022 13:07, Hans Verkuil wrote:
> Hi Ming,
> 
> Can you take a look at the kernel test robot warnings? I suspect you're missing
> a header (linux/vmalloc.h?) for vzalloc et al that the alpha architecture doesn't
> automatically include.
> 
> If it is just adding a single include in a single patch, then just post a 15.1 for
> that patch. If it is more complicated, then posting a v16 is easier.

Follow up: checkpatch.pl --strict is now OK, and so are sparse and smatch. So it's
just this and an Ack for the firmware patch that needs to be resolved.

Regards,

	Hans

> 
> Regards,
> 
> 	Hans
> 
> On 25/01/2022 08:11, Ming Qian wrote:
>> Hi all,
>>
>> This patch series adds support for
>> the amphion video encoder and decoder
>> via the VPU block present in imx8q platforms.
>> Currently, support for IMX8QXP and IMX8QM is included.
>>
>> It features decoding for the following formats:
>> - H.264
>> - HEVC
>> - MPEG4
>> - MPEG2
>> - VC1
>> - VP8
>>
>> It features encoding for the following formats:
>> - H.264
>>
>> The driver creates a separate device node for the encoder and decoder.
>>
>> This driver is dependent on vpu firmwares.
>> The firmwares have been submitted to linux-firmware.
>> The firmware patch is since commit
>> b563148fd28623f6b6ce68bb06c3dd3bd138b058:
>> linux-firmware: Update firmware file for Intel Bluetooth 9462
>> (Fri Oct 8 16:30:14 2021 +0530)
>>
>> and it's available in the git repository at:
>>     https://github.com/mingqian-0/linux-firmware.git
>>
>> for you to fetch changes up to bb3eee4f99589d4910dee4c053a3a685546b5dbb:
>> amphion: add VPU firmwares for NXP i.MX8Q SoCs
>> (Tue Oct 12 15:09:57 2021 +0800)
>>
>> encoder is tested with gstreamer
>> decoder is tested with gstreamer, but the following patches are required:
>> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1379
>> https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1381
>>
>>
>> Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
>>
>>
>> Changelog:
>>
>> v15
>> - fix issues detected by "checkpatch.pl --strict"
>> - encoder add ctrl V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
>>
>> v14
>> - fix some errors according to Hans's comments
>>
>> v13
>> - make a workaround that avoid firmware entering wfi wrongly
>>
>> v12
>> - support reset decoder when starting a new stream
>> - don't append an empty last buffer, set last_buffer_dequeued
>> - improve the resolution change flow
>> - return all buffers if start_streaming fail
>> - fill encoder capture buffer's filed to none
>> - fix a bug in calculating bytesperline
>>
>> v11
>> - fix dt_binding_check error after upgrade dtschema
>> - remove "default y"
>> - add media device
>>
>> v10
>> - refine vpu log, remove custom logging infrastructure
>> - support non contiguous planes format nv12m instead of nv12
>> - rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
>> - rename V4L2_PIX_FMT_NV12_10BE_8L128 to V4L2_PIX_FMT_NV12MT_10BE_8L128
>> - merge two module into one
>> - fix kernel panic in rmmod
>>
>> v9
>> - drop V4L2_BUF_FLAG_CODECCONFIG
>> - drop V4L2_EVENT_CODEC_ERROR
>> - drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
>> - fix some build warnings with W=1 reported by kernel test robot
>>
>> v8
>> - move driver from driver/media/platform/imx/vpu-8q to
>>   driver/media/platform/amphion
>> - rename driver name to amphion
>> - remove imx_vpu.h
>> - move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
>> - move the definition of V4L2_EVENT_SKIP to videodev2.h
>>
>> v7
>> - fix build warnings with W=1 reported by kernel test robot
>>
>> v6:
>> - rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
>> - rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128
>>
>> v5:
>> - move some definition from imx_vph.h to videodev2.h
>> - remove some unnecessary content
>> - add some documentation descriptions
>> - pass the lateset v4l2-compliance test
>>
>> v4:
>> - redefine the memory-region in devicetree bindings documentation
>> - use v4l2's mechanism to implement synchronize queuing ioctl
>> - remove the unnecessary mutex ioctl_sync
>> - don't notify source change event if the parameters are same as previously established
>> - add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format
>>
>> v3:
>> - don't make vpu device node a simple-bus
>> - trigger probing vpu core in the driver
>> - remove unnecessary vpu core index property
>>
>> v2:
>> - fix dt bindings build error
>> - split driver patch into several parts to avoid exceeding bytes limit
>>
>> Compliance
>> ==========
>> # v4l2-compliance -d /dev/video0
>> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
>> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
>>
>> Compliance test for amphion-vpu device /dev/video0:
>>
>> Driver Info:
>> 	Driver name      : amphion-vpu
>> 	Card type        : amphion vpu decoder
>> 	Bus info         : platform: amphion-vpu
>> 	Driver version   : 5.15.0
>> 	Capabilities     : 0x84204000
>> 		Video Memory-to-Memory Multiplanar
>> 		Streaming
>> 		Extended Pix Format
>> 		Device Capabilities
>> 	Device Caps      : 0x04204000
>> 		Video Memory-to-Memory Multiplanar
>> 		Streaming
>> 		Extended Pix Format
>> 	Detected Stateful Decoder
>> Media Driver Info:
>> 	Driver name      : amphion-vpu
>> 	Model            : amphion-vpu
>> 	Serial           :
>> 	Bus info         : platform: amphion-vpu
>> 	Media version    : 5.15.0
>> 	Hardware revision: 0x00000000 (0)
>> 	Driver version   : 5.15.0
>> Interface Info:
>> 	ID               : 0x0300000c
>> 	Type             : V4L Video
>> Entity Info:
>> 	ID               : 0x00000001 (1)
>> 	Name             : amphion-vpu-decoder-source
>> 	Function         : V4L2 I/O
>> 	Pad 0x01000002   : 0: Source
>> 	  Link 0x02000008: to remote pad 0x1000004 of entity 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable
>>
>> Required ioctls:
>> 	test MC information (see 'Media Driver Info' above): OK
>> 	test VIDIOC_QUERYCAP: OK
>> 	test invalid ioctls: OK
>>
>> Allow for multiple opens:
>> 	test second /dev/video0 open: OK
>> 	test VIDIOC_QUERYCAP: OK
>> 	test VIDIOC_G/S_PRIORITY: OK
>> 	test for unlimited opens: OK
>>
>> Debug ioctls:
>> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
>> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
>>
>> Input ioctls:
>> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
>> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
>> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
>> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
>> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
>> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
>>
>> Output ioctls:
>> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
>> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
>> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
>> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
>> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
>>
>> Input/Output configuration ioctls:
>> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
>> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
>> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
>> 	test VIDIOC_G/S_EDID: OK (Not Supported)
>>
>> Control ioctls:
>> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
>> 	test VIDIOC_QUERYCTRL: OK
>> 	test VIDIOC_G/S_CTRL: OK
>> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
>> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
>> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
>> 	Standard Controls: 3 Private Controls: 0
>>
>> Format ioctls:
>> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
>> 	test VIDIOC_G/S_PARM: OK (Not Supported)
>> 	test VIDIOC_G_FBUF: OK (Not Supported)
>> 	test VIDIOC_G_FMT: OK
>> 	test VIDIOC_TRY_FMT: OK
>> 	test VIDIOC_S_FMT: OK
>> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
>> 	test Cropping: OK (Not Supported)
>> 	test Composing: OK
>> 	test Scaling: OK (Not Supported)
>>
>> Codec ioctls:
>> 	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
>> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
>> 	test VIDIOC_(TRY_)DECODER_CMD: OK
>>
>> Buffer ioctls:
>> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
>> 	test VIDIOC_EXPBUF: OK
>> 	test Requests: OK (Not Supported)
>>
>> Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0
>>
>> # v4l2-compliance -d /dev/video1
>> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
>> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
>>
>> Compliance test for amphion-vpu device /dev/video1:
>>
>> Driver Info:
>> 	Driver name      : amphion-vpu
>> 	Card type        : amphion vpu encoder
>> 	Bus info         : platform: amphion-vpu
>> 	Driver version   : 5.15.0
>> 	Capabilities     : 0x84204000
>> 		Video Memory-to-Memory Multiplanar
>> 		Streaming
>> 		Extended Pix Format
>> 		Device Capabilities
>> 	Device Caps      : 0x04204000
>> 		Video Memory-to-Memory Multiplanar
>> 		Streaming
>> 		Extended Pix Format
>> 	Detected Stateful Encoder
>> Media Driver Info:
>> 	Driver name      : amphion-vpu
>> 	Model            : amphion-vpu
>> 	Serial           :
>> 	Bus info         : platform: amphion-vpu
>> 	Media version    : 5.15.0
>> 	Hardware revision: 0x00000000 (0)
>> 	Driver version   : 5.15.0
>> Interface Info:
>> 	ID               : 0x0300001a
>> 	Type             : V4L Video
>> Entity Info:
>> 	ID               : 0x0000000f (15)
>> 	Name             : amphion-vpu-encoder-source
>> 	Function         : V4L2 I/O
>> 	Pad 0x01000010   : 0: Source
>> 	  Link 0x02000016: to remote pad 0x1000012 of entity 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable
>>
>> Required ioctls:
>> 	test MC information (see 'Media Driver Info' above): OK
>> 	test VIDIOC_QUERYCAP: OK
>> 	test invalid ioctls: OK
>>
>> Allow for multiple opens:
>> 	test second /dev/video1 open: OK
>> 	test VIDIOC_QUERYCAP: OK
>> 	test VIDIOC_G/S_PRIORITY: OK
>> 	test for unlimited opens: OK
>>
>> Debug ioctls:
>> 	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
>> 	test VIDIOC_LOG_STATUS: OK (Not Supported)
>>
>> Input ioctls:
>> 	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
>> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>> 	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
>> 	test VIDIOC_ENUMAUDIO: OK (Not Supported)
>> 	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
>> 	test VIDIOC_G/S_AUDIO: OK (Not Supported)
>> 	Inputs: 0 Audio Inputs: 0 Tuners: 0
>>
>> Output ioctls:
>> 	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
>> 	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
>> 	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
>> 	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
>> 	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
>> 	Outputs: 0 Audio Outputs: 0 Modulators: 0
>>
>> Input/Output configuration ioctls:
>> 	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
>> 	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
>> 	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
>> 	test VIDIOC_G/S_EDID: OK (Not Supported)
>>
>> Control ioctls:
>> 	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
>> 	test VIDIOC_QUERYCTRL: OK
>> 	test VIDIOC_G/S_CTRL: OK
>> 	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
>> 	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
>> 	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
>> 	Standard Controls: 20 Private Controls: 0
>>
>> Format ioctls:
>> 	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
>> 	test VIDIOC_G/S_PARM: OK
>> 	test VIDIOC_G_FBUF: OK (Not Supported)
>> 	test VIDIOC_G_FMT: OK
>> 	test VIDIOC_TRY_FMT: OK
>> 	test VIDIOC_S_FMT: OK
>> 	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
>> 	test Cropping: OK
>> 	test Composing: OK (Not Supported)
>> 	test Scaling: OK (Not Supported)
>>
>> Codec ioctls:
>> 	test VIDIOC_(TRY_)ENCODER_CMD: OK
>> 	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
>> 	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
>>
>> Buffer ioctls:
>> 	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
>> 	test VIDIOC_EXPBUF: OK
>> 	test Requests: OK (Not Supported)
>>
>> Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed: 0, Warnings: 0
>>
>> # v4l2-compliance -d /dev/media0
>> v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
>> v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11
>>
>> Compliance test for amphion-vpu device /dev/media0:
>>
>> Media Driver Info:
>> 	Driver name      : amphion-vpu
>> 	Model            : amphion-vpu
>> 	Serial           :
>> 	Bus info         : platform: amphion-vpu
>> 	Media version    : 5.15.0
>> 	Hardware revision: 0x00000000 (0)
>> 	Driver version   : 5.15.0
>>
>> Required ioctls:
>> 	test MEDIA_IOC_DEVICE_INFO: OK
>> 	test invalid ioctls: OK
>>
>> Allow for multiple opens:
>> 	test second /dev/media0 open: OK
>> 	test MEDIA_IOC_DEVICE_INFO: OK
>> 	test for unlimited opens: OK
>>
>> Media Controller ioctls:
>> 	test MEDIA_IOC_G_TOPOLOGY: OK
>> 	Entities: 6 Interfaces: 2 Pads: 8 Links: 8
>> 	test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
>> 	test MEDIA_IOC_SETUP_LINK: OK
>>
>> Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0
>>
>> Ming Qian (13):
>>   dt-bindings: media: amphion: add amphion video codec bindings
>>   media: add nv12m_8l128 and nv12m_10be_8l128 video format.
>>   media: amphion: add amphion vpu device driver
>>   media: amphion: add vpu core driver
>>   media: amphion: implement vpu core communication based on mailbox
>>   media: amphion: add vpu v4l2 m2m support
>>   media: amphion: add v4l2 m2m vpu encoder stateful driver
>>   media: amphion: add v4l2 m2m vpu decoder stateful driver
>>   media: amphion: implement windsor encoder rpc interface
>>   media: amphion: implement malone decoder rpc interface
>>   ARM64: dts: freescale: imx8q: add imx vpu codec entries
>>   firmware: imx: scu-pd: imx8q: add vpu mu resources
>>   MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
>>
>>  .../bindings/media/amphion,vpu.yaml           |  180 ++
>>  .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
>>  MAINTAINERS                                   |    9 +
>>  .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
>>  arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
>>  arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
>>  arch/arm64/configs/defconfig                  |    1 +
>>  drivers/firmware/imx/scu-pd.c                 |    4 +
>>  drivers/media/platform/Kconfig                |   19 +
>>  drivers/media/platform/Makefile               |    2 +
>>  drivers/media/platform/amphion/Makefile       |   20 +
>>  drivers/media/platform/amphion/vdec.c         | 1694 +++++++++++++++++
>>  drivers/media/platform/amphion/venc.c         | 1364 +++++++++++++
>>  drivers/media/platform/amphion/vpu.h          |  356 ++++
>>  drivers/media/platform/amphion/vpu_cmds.c     |  436 +++++
>>  drivers/media/platform/amphion/vpu_cmds.h     |   25 +
>>  drivers/media/platform/amphion/vpu_codec.h    |   68 +
>>  drivers/media/platform/amphion/vpu_color.c    |  183 ++
>>  drivers/media/platform/amphion/vpu_core.c     |  870 +++++++++
>>  drivers/media/platform/amphion/vpu_core.h     |   15 +
>>  drivers/media/platform/amphion/vpu_dbg.c      |  495 +++++
>>  drivers/media/platform/amphion/vpu_defs.h     |  187 ++
>>  drivers/media/platform/amphion/vpu_drv.c      |  260 +++
>>  drivers/media/platform/amphion/vpu_helpers.c  |  413 ++++
>>  drivers/media/platform/amphion/vpu_helpers.h  |   74 +
>>  drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
>>  drivers/media/platform/amphion/vpu_imx8q.h    |  115 ++
>>  drivers/media/platform/amphion/vpu_malone.c   | 1625 ++++++++++++++++
>>  drivers/media/platform/amphion/vpu_malone.h   |   44 +
>>  drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
>>  drivers/media/platform/amphion/vpu_mbox.h     |   16 +
>>  drivers/media/platform/amphion/vpu_msgs.c     |  385 ++++
>>  drivers/media/platform/amphion/vpu_msgs.h     |   14 +
>>  drivers/media/platform/amphion/vpu_rpc.c      |  257 +++
>>  drivers/media/platform/amphion/vpu_rpc.h      |  456 +++++
>>  drivers/media/platform/amphion/vpu_v4l2.c     |  720 +++++++
>>  drivers/media/platform/amphion/vpu_v4l2.h     |   55 +
>>  drivers/media/platform/amphion/vpu_windsor.c  | 1169 ++++++++++++
>>  drivers/media/platform/amphion/vpu_windsor.h  |   37 +
>>  drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
>>  include/uapi/linux/videodev2.h                |    2 +
>>  41 files changed, 12099 insertions(+), 3 deletions(-)
>>  create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
>>  create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
>>  create mode 100644 drivers/media/platform/amphion/Makefile
>>  create mode 100644 drivers/media/platform/amphion/vdec.c
>>  create mode 100644 drivers/media/platform/amphion/venc.c
>>  create mode 100644 drivers/media/platform/amphion/vpu.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_codec.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_color.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_core.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_core.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_defs.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_drv.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_malone.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_malone.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
>>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
>>  create mode 100644 drivers/media/platform/amphion/vpu_windsor.h
>>
>>
>> base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
> 



From broonie at kernel.org  Tue Jan 25 04:25:47 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 12:25:47 +0000
Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest
In-Reply-To: <87y2346on8.wl-maz@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-26-broonie@kernel.org>
 <87y2346on8.wl-maz@kernel.org>
Message-ID: <Ye/sS0jEXnBuumeG@sirena.org.uk>

On Tue, Jan 25, 2022 at 11:27:55AM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))

> Please drop the IS_ENABLED(). We purposely avoid conditional
> compilation in KVM in order to avoid bitrot, and the amount of code
> you save isn't significant. Having a static key is more than enough to
> avoid runtime costs.

Sure, I wanted to be extra careful here as this is all in hot paths and
going to get moved elsewhere when we have real guest support.

> > +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
> > +	    cpus_have_final_cap(ARM64_HAS_FGT)) {
> > +		val = read_sysreg_s(SYS_HFGRTR_EL2);
> > +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> > +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> > +		write_sysreg_s(val, SYS_HFGRTR_EL2);
> > +
> > +		val = read_sysreg_s(SYS_HFGWTR_EL2);
> > +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> > +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> > +		write_sysreg_s(val, SYS_HFGWTR_EL2);
> > +	}

> If the CPUs do not have FGT, what provides the equivalent trapping?

Nothing for nVHE mode.

> If FGT is mandatory when SME exists, then you should simplify the
> condition.

OK, I'll remove the defensiveness here.  FGT is mandatory from v8.6 and
SME is a v9 feature so people shouldn't build a SME implementation that
lacks FGT.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/6f709741/attachment.sig>

From xiongx18 at fudan.edu.cn  Tue Jan 25 04:31:56 2022
From: xiongx18 at fudan.edu.cn (Xin Xiong)
Date: Tue, 25 Jan 2022 20:31:56 +0800
Subject: [PATCH] mtd: rawnand: atmel: fix refcount leaks in
 atmel_nand_controller_init
Message-ID: <20220125123155.36891-1-xiongx18@fudan.edu.cn>

The reference counting issue happens in several error handling paths
on a refcounted object "nc->dmac". In these paths, the function simply
returns the error code, forgetting to balance the reference count
increased earlier by dma_request_channel(), which may cause refcount
leaks. What's more, the "nc->mck" object also needs to be handled
correctly.

Fix it by adding specific error handling code in those error paths.

Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 22 +++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index f3276ee9e..b3801ebd2 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -2060,13 +2060,15 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
 	nc->mck = of_clk_get(dev->parent->of_node, 0);
 	if (IS_ERR(nc->mck)) {
 		dev_err(dev, "Failed to retrieve MCK clk\n");
-		return PTR_ERR(nc->mck);
+		ret = PTR_ERR(nc->mck);
+		goto out_release_dma;
 	}
 
 	np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
 	if (!np) {
 		dev_err(dev, "Missing or invalid atmel,smc property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_put_clk;
 	}
 
 	nc->smc = syscon_node_to_regmap(np);
@@ -2074,10 +2076,24 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
 	if (IS_ERR(nc->smc)) {
 		ret = PTR_ERR(nc->smc);
 		dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
-		return ret;
+		goto out_put_clk;
 	}
 
 	return 0;
+
+out_put_clk:
+	clk_put(nc->mck);
+	nc->mck = NULL;
+
+out_release_dma:
+	if (nc->caps->has_dma && !atmel_nand_avoid_dma) {
+		if (!IS_ERR_OR_NULL(nc->dmac)) {
+			dma_release_channel(nc->dmac);
+			nc->dmac = NULL;
+		}
+	}
+
+	return ret;
 }
 
 static int
-- 
2.25.1



From johnson.wang at mediatek.com  Tue Jan 25 04:51:09 2022
From: johnson.wang at mediatek.com (Johnson Wang)
Date: Tue, 25 Jan 2022 20:51:09 +0800
Subject: [PATCH v2 1/2] soc: mediatek: pwrap: add pwrap driver for
 MT8186 SoC
In-Reply-To: <f5486d12-b048-c062-e571-cf39da7e4c1b@gmail.com>
References: <20220107104633.7500-1-johnson.wang@mediatek.com>
 <20220107104633.7500-2-johnson.wang@mediatek.com>
 <9949a1f7-1ed5-a137-c7b9-2ef8d8e1caf8@gmail.com>
 <544f5085fc8597ce9ce3eb7dc1b5d08fb1ac8755.camel@mediatek.com>
 <f5486d12-b048-c062-e571-cf39da7e4c1b@gmail.com>
Message-ID: <cb048ff99e4bd20eb8b3b70de13baf5a27f52138.camel@mediatek.com>

Hi Matthias,

On Tue, 2022-01-18 at 14:17 +0100, Matthias Brugger wrote:
> 
> On 18/01/2022 10:25, Johnson Wang wrote:
> > Hi Matthias,
> > 
> > On Fri, 2022-01-14 at 16:46 +0100, Matthias Brugger wrote:
> > > 
> > > On 07/01/2022 11:46, Johnson Wang wrote:
> > > > MT8186 are highly integrated SoC and use PMIC_MT6366 for
> > > > power management. This patch adds pwrap master driver to
> > > > access PMIC_MT6366.
> > > > 
> > > 
> > > It seems this new arbiter is significantly different from the
> > > version
> > > 1. Please
> > > explain that in the commit message.
> > > 
> > > > Signed-off-by: Johnson Wang <johnson.wang at mediatek.com>
> > > > ---
> > > >    drivers/soc/mediatek/mtk-pmic-wrap.c | 72
> > > > ++++++++++++++++++++++++++++
> > > >    1 file changed, 72 insertions(+)
> > > > 
> > > > diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > > > b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > > > index 952bc554f443..78866ebf7f04 100644
> > > > --- a/drivers/soc/mediatek/mtk-pmic-wrap.c
> > > > +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c
> > > > @@ -30,6 +30,7 @@
> > > >    #define PWRAP_GET_WACS_REQ(x)		(((x) >> 19) &
> > > > 0x00000001)
> > > >    #define PWRAP_STATE_SYNC_IDLE0		BIT(20)
> > > >    #define PWRAP_STATE_INIT_DONE0		BIT(21)
> > > > +#define PWRAP_STATE_INIT_DONE0_V2	BIT(22)
> > > 
> > > That's a strange name, does it come from the datasheet
> > > description?
> > 
> > Thanks for your review.
> > 
> > No, there is only PWRAP_STATE_INIT_DONE0 in MT8186 datasheet.
> > However, it's the 22nd bit in MT8186 and the 21st bit in other
> > SoCs.
> > So we changed its name to avoid redefinition of
> > PWRAP_STATE_INIT_DONE0.
> > 
> > Could you give us some suggestion on proper definition naming?
> > Do you think PWRAP_STATE_INIT_DONE0_MT8186 will be a better choice?
> > 
> 
> Is this a difference that only will show up on the PMIC-wrapper of
> MT8186 or 
> will other SoCs include the same IP? If not, then
> PWRAP_STATE_INIT_DONE0_MT8186 
> should be fine. Otherwise we would need a better name.
> 

In fact, we don't know whether following SoCs will include
the same IP in the future.

Can we just replace _V2 with _MT8186 this time or
please give us some suggestion on it. 

Thanks for your response.

> > > 
> > > >    #define PWRAP_STATE_INIT_DONE1		BIT(15)
> > > >    
> > > >    /* macro for WACS FSM */
> > > > @@ -77,6 +78,8 @@
> > > >    #define PWRAP_CAP_INT1_EN	BIT(3)
> > > >    #define PWRAP_CAP_WDT_SRC1	BIT(4)
> > > >    #define PWRAP_CAP_ARB		BIT(5)
> > > > +#define PWRAP_CAP_MONITOR_V2	BIT(6)
> > > 
> > > Not used capability, please delete.
> > > 
> > > 
> > > Regards,
> > > Matthias
> > 
> > PWRAP_CAP_MONITOR_V2 is not used right now.
> > We can remove it in next version.
> > But this capability will be added when we need it.
> > 
> 
> That's OK, we should add capability definitions once they are added
> to the 
> driver, not before that.
> 
> Thanks,
> Matthias



From broonie at kernel.org  Tue Jan 25 04:52:18 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 12:52:18 +0000
Subject: [PATCH v8 26/38] KVM: arm64: Handle SME host state when running
 guests
In-Reply-To: <87wnio6n7d.wl-maz@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-27-broonie@kernel.org>
 <87wnio6n7d.wl-maz@kernel.org>
Message-ID: <Ye/ygvnlzPKYT2z6@sirena.org.uk>

On Tue, Jan 25, 2022 at 11:59:02AM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > +	if (has_vhe()) {
> > +		if (system_supports_sme()) {

> nit:	if (has_vhe() && system_supports_sme()) {

> saves you one level of indentation.

Yes, for now.  IIRC there was some other stuff there when I had some of
the code for doing the register switching properly.

> > +			/* Also restore EL0 state seen on entry */
> > +			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
> > +				sysreg_clear_set(CPACR_EL1, 0,
> > +						 CPACR_EL1_SMEN_EL0EN |
> > +						 CPACR_EL1_SMEN_EL1EN);
> > +			else
> > +				sysreg_clear_set(CPACR_EL1,
> > +						 CPACR_EL1_SMEN_EL0EN,
> > +						 CPACR_EL1_SMEN_EL1EN);

> I find the use of CPACR_EL1_SMEN in some cases and its individual bits
> in some others pretty confusing. I understand that you have modelled
> it after the SVE code, but maybe this is a mistake we don't need to
> repeat. I'd be in favour of directly exposing the individual bits in
> all cases.

OK, it is just the KVM code that uses the plain ZEN.  I'll add a cleanup
patch for that at the start of the series for ZEN I guess otherwise it
looks worse, though that will inflate the size of the series a bit.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/88346d43/attachment.sig>

From shameerali.kolothum.thodi at huawei.com  Tue Jan 25 05:00:30 2022
From: shameerali.kolothum.thodi at huawei.com (Shameerali Kolothum Thodi)
Date: Tue, 25 Jan 2022 13:00:30 +0000
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
Message-ID: <9da65c2504b944398188e468eac1abff@huawei.com>

Hi Robin/Lorenzo,

> -----Original Message-----
> From: iommu [mailto:iommu-bounces at lists.linux-foundation.org] On Behalf
> Of Shameer Kolothum
> Sent: 05 August 2021 09:07
> To: linux-arm-kernel at lists.infradead.org; linux-acpi at vger.kernel.org;
> iommu at lists.linux-foundation.org
> Cc: robin.murphy at arm.com; jon at solid-run.com; Linuxarm
> <linuxarm at huawei.com>; steven.price at arm.com; Guohanjun (Hanjun Guo)
> <guohanjun at huawei.com>; yangyicong <yangyicong at huawei.com>;
> Sami.Mujawar at arm.com; will at kernel.org; wanghuiqiang
> <wanghuiqiang at huawei.com>
> Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
> 
> Hi,
> 
> The series adds support to IORT RMR nodes specified in IORT
> Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
> memory ranges that are used by endpoints and require a unity
> mapping in SMMU.
> 
> We have faced issues with 3408iMR RAID controller cards which
> fail to boot when SMMU is enabled. This is because these
> controllers make use of host memory for various caching related
> purposes and when SMMU is enabled the iMR firmware fails to
> access these memory regions as there is no mapping for them.
> IORT RMR provides a way for UEFI to describe and report these
> memory regions so that the kernel can make a unity mapping for
> these in SMMU.
> 
> Change History:
> 
> v6 --> v7
> 
> The only change from v6 is the fix pointed out by Steve to
> the SMMUv2 SMR bypass install in patch #8.
> 
> Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
> Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
> yet as the series still needs more review[1].
> 
> Feedback and tests on this series is very much appreciated.

Since we have an update to IORT spec(E.c) now[1] and includes additional
attributes/flags for the RMR node, I am planning to respin this series soon.

Going through the new spec, I have a few queries,

The memory range attributes can now be described as one of the following,

0x00: Device-nGnRnE memory
0x01: Device-nGnRE memory
0x02: Device-nGRE memory
0x03: Device-GRE memory
0x04: Normal Inner Non-cacheable Outer Non-cacheable
0x05: Normal Inner Write-back Outer Write-back Inner Shareable

I am not sure how this needs to be captured and used in the kernel. Is there
any intention of using these fine-grained attributes in the kernel now
or a generic mapping of the above to the struct iommu_rev_region prot field
is enough? i.e., something like,

{
    ....
    prot = IOMMU_READ | IOMMU_WRITE;

    if (rmr_attr == normal_mem) // 0x05
        prot |= IOMMU_CACHE;
    
    if (rmr_attr == device_mem) { //0x00 - 0x03
        prot |= IOMMU_MMIO;
        prot |= IOMMU_NOEXEC;
    }
    ....
}

Similarly for the 'flags' field, the new 'Access Privilege' is intended to set the
IOMMU_PRIV ?
  
Please let me know.

Thanks,
Shameer

[1] https://developer.arm.com/documentation/den0049/ec/?lang=en


From krishnar at ami.com  Tue Jan 25 05:01:16 2022
From: krishnar at ami.com (krishnar4)
Date: Tue, 25 Jan 2022 18:31:16 +0530
Subject: [PATCH linux dev-5.15] hwmon: (pmbus) modify PSU fan_target convert
 value to false
Message-ID: <20220125130116.18646-1-krishnar@ami.com>

Description: PSU can't use sysfs fan_target to control PSU fan duty.

Signed-off-by: krishnar4 <krishnar at ami.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 776ee2237be2..a56c2e1c4079 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1889,7 +1889,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
 
 	sensor = pmbus_add_sensor(data, "fan", "target", index, page,
 				  0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
-				  false, false, true);
+				  false, false, false);
 
 	if (!sensor)
 		return -ENOMEM;
-- 
2.17.1



From ming.qian at nxp.com  Tue Jan 25 05:10:55 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Tue, 25 Jan 2022 13:10:55 +0000
Subject: =?gb2312?B?u9i4tDogW0VYVF0gUmU6IFtQQVRDSCB2MTUgMDAvMTNdIGFtcGhpb24gdmlk?=
 =?gb2312?Q?eo_decoder/encoder_driver?=
In-Reply-To: <2c3fcd05-35da-02e4-cd69-4a6e369d7005@xs4all.nl>
References: <cover.1643077283.git.ming.qian@nxp.com>
 <2c3fcd05-35da-02e4-cd69-4a6e369d7005@xs4all.nl>
Message-ID: <AM6PR04MB63413B586A60FB6F11FD703AE75F9@AM6PR04MB6341.eurprd04.prod.outlook.com>

> Hi Ming,
> 
> Can you take a look at the kernel test robot warnings? I suspect you're
> missing a header (linux/vmalloc.h?) for vzalloc et al that the alpha
> architecture doesn't automatically include.
> 
> If it is just adding a single include in a single patch, then just post a 15.1 for
> that patch. If it is more complicated, then posting a v16 is easier.
> 
> Regards,
> 
>         Hans

Got it, I'll deal with it asap

> 
> On 25/01/2022 08:11, Ming Qian wrote:
> > Hi all,
> >
> > This patch series adds support for
> > the amphion video encoder and decoder
> > via the VPU block present in imx8q platforms.
> > Currently, support for IMX8QXP and IMX8QM is included.
> >
> > It features decoding for the following formats:
> > - H.264
> > - HEVC
> > - MPEG4
> > - MPEG2
> > - VC1
> > - VP8
> >
> > It features encoding for the following formats:
> > - H.264
> >
> > The driver creates a separate device node for the encoder and decoder.
> >
> > This driver is dependent on vpu firmwares.
> > The firmwares have been submitted to linux-firmware.
> > The firmware patch is since commit
> > b563148fd28623f6b6ce68bb06c3dd3bd138b058:
> > linux-firmware: Update firmware file for Intel Bluetooth 9462 (Fri Oct
> > 8 16:30:14 2021 +0530)
> >
> > and it's available in the git repository at:
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Fmingqian-0%2Flinux-
> firmware.git&amp;data=04%7C01%7Cming.qian%
> >
> 40nxp.com%7C8f3d9dd4d58542650ac808d9dffb4ef4%7C686ea1d3bc2b4c6fa9
> 2cd99
> >
> c5c301635%7C0%7C0%7C637787092725815979%7CUnknown%7CTWFpbGZsb
> 3d8eyJWIjo
> >
> iMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C30
> 00&amp
> > ;sdata=csybemVdVslZ%2FJx%2BLSD4dPU8WZzXcKcs35fYlf7u0oU%3D&amp
> ;reserved
> > =0
> >
> > for you to fetch changes up to
> bb3eee4f99589d4910dee4c053a3a685546b5dbb:
> > amphion: add VPU firmwares for NXP i.MX8Q SoCs (Tue Oct 12 15:09:57
> > 2021 +0800)
> >
> > encoder is tested with gstreamer
> > decoder is tested with gstreamer, but the following patches are required:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> > ab.freedesktop.org%2Fgstreamer%2Fgstreamer%2F-
> %2Fmerge_requests%2F1379
> >
> &amp;data=04%7C01%7Cming.qian%40nxp.com%7C8f3d9dd4d58542650ac80
> 8d9dffb
> >
> 4ef4%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63778709272581
> 5979%7
> >
> CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ
> BTiI6Ik1
> >
> haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=NsYaJTd%2F8iyxR43T5l8plOL4
> Fc0ZPnC
> > XctWhp2nVyyY%3D&amp;reserved=0
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl
> > ab.freedesktop.org%2Fgstreamer%2Fgstreamer%2F-
> %2Fmerge_requests%2F1381
> >
> &amp;data=04%7C01%7Cming.qian%40nxp.com%7C8f3d9dd4d58542650ac80
> 8d9dffb
> >
> 4ef4%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C63778709272581
> 5979%7
> >
> CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ
> BTiI6Ik1
> >
> haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=EpF9to1WlTCtvwQRFLqmBOe
> d0v7UxgJqW
> > TZOjvyYydY%3D&amp;reserved=0
> >
> >
> > Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
> >
> >
> > Changelog:
> >
> > v15
> > - fix issues detected by "checkpatch.pl --strict"
> > - encoder add ctrl V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE
> >
> > v14
> > - fix some errors according to Hans's comments
> >
> > v13
> > - make a workaround that avoid firmware entering wfi wrongly
> >
> > v12
> > - support reset decoder when starting a new stream
> > - don't append an empty last buffer, set last_buffer_dequeued
> > - improve the resolution change flow
> > - return all buffers if start_streaming fail
> > - fill encoder capture buffer's filed to none
> > - fix a bug in calculating bytesperline
> >
> > v11
> > - fix dt_binding_check error after upgrade dtschema
> > - remove "default y"
> > - add media device
> >
> > v10
> > - refine vpu log, remove custom logging infrastructure
> > - support non contiguous planes format nv12m instead of nv12
> > - rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
> > - rename V4L2_PIX_FMT_NV12_10BE_8L128 to
> > V4L2_PIX_FMT_NV12MT_10BE_8L128
> > - merge two module into one
> > - fix kernel panic in rmmod
> >
> > v9
> > - drop V4L2_BUF_FLAG_CODECCONFIG
> > - drop V4L2_EVENT_CODEC_ERROR
> > - drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
> > - fix some build warnings with W=1 reported by kernel test robot
> >
> > v8
> > - move driver from driver/media/platform/imx/vpu-8q to
> >   driver/media/platform/amphion
> > - rename driver name to amphion
> > - remove imx_vpu.h
> > - move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
> > - move the definition of V4L2_EVENT_SKIP to videodev2.h
> >
> > v7
> > - fix build warnings with W=1 reported by kernel test robot
> >
> > v6:
> > - rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
> > - rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128
> >
> > v5:
> > - move some definition from imx_vph.h to videodev2.h
> > - remove some unnecessary content
> > - add some documentation descriptions
> > - pass the lateset v4l2-compliance test
> >
> > v4:
> > - redefine the memory-region in devicetree bindings documentation
> > - use v4l2's mechanism to implement synchronize queuing ioctl
> > - remove the unnecessary mutex ioctl_sync
> > - don't notify source change event if the parameters are same as
> > previously established
> > - add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format
> >
> > v3:
> > - don't make vpu device node a simple-bus
> > - trigger probing vpu core in the driver
> > - remove unnecessary vpu core index property
> >
> > v2:
> > - fix dt bindings build error
> > - split driver patch into several parts to avoid exceeding bytes limit
> >
> > Compliance
> > ==========
> > # v4l2-compliance -d /dev/video0
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/video0:
> >
> > Driver Info:
> >       Driver name      : amphion-vpu
> >       Card type        : amphion vpu decoder
> >       Bus info         : platform: amphion-vpu
> >       Driver version   : 5.15.0
> >       Capabilities     : 0x84204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >               Device Capabilities
> >       Device Caps      : 0x04204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >       Detected Stateful Decoder
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> > Interface Info:
> >       ID               : 0x0300000c
> >       Type             : V4L Video
> > Entity Info:
> >       ID               : 0x00000001 (1)
> >       Name             : amphion-vpu-decoder-source
> >       Function         : V4L2 I/O
> >       Pad 0x01000002   : 0: Source
> >         Link 0x02000008: to remote pad 0x1000004 of entity
> > 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable
> >
> > Required ioctls:
> >       test MC information (see 'Media Driver Info' above): OK
> >       test VIDIOC_QUERYCAP: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/video0 open: OK
> >       test VIDIOC_QUERYCAP: OK
> >       test VIDIOC_G/S_PRIORITY: OK
> >       test for unlimited opens: OK
> >
> > Debug ioctls:
> >       test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> >       test VIDIOC_LOG_STATUS: OK (Not Supported)
> >
> > Input ioctls:
> >       test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> >       test VIDIOC_ENUMAUDIO: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDIO: OK (Not Supported)
> >       Inputs: 0 Audio Inputs: 0 Tuners: 0
> >
> > Output ioctls:
> >       test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> >       Outputs: 0 Audio Outputs: 0 Modulators: 0
> >
> > Input/Output configuration ioctls:
> >       test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> >       test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> >       test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> >       test VIDIOC_G/S_EDID: OK (Not Supported)
> >
> > Control ioctls:
> >       test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> >       test VIDIOC_QUERYCTRL: OK
> >       test VIDIOC_G/S_CTRL: OK
> >       test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> >       test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> >       test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> >       Standard Controls: 3 Private Controls: 0
> >
> > Format ioctls:
> >       test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> >       test VIDIOC_G/S_PARM: OK (Not Supported)
> >       test VIDIOC_G_FBUF: OK (Not Supported)
> >       test VIDIOC_G_FMT: OK
> >       test VIDIOC_TRY_FMT: OK
> >       test VIDIOC_S_FMT: OK
> >       test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> >       test Cropping: OK (Not Supported)
> >       test Composing: OK
> >       test Scaling: OK (Not Supported)
> >
> > Codec ioctls:
> >       test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
> >       test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> >       test VIDIOC_(TRY_)DECODER_CMD: OK
> >
> > Buffer ioctls:
> >       test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> >       test VIDIOC_EXPBUF: OK
> >       test Requests: OK (Not Supported)
> >
> > Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed:
> > 0, Warnings: 0
> >
> > # v4l2-compliance -d /dev/video1
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/video1:
> >
> > Driver Info:
> >       Driver name      : amphion-vpu
> >       Card type        : amphion vpu encoder
> >       Bus info         : platform: amphion-vpu
> >       Driver version   : 5.15.0
> >       Capabilities     : 0x84204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >               Device Capabilities
> >       Device Caps      : 0x04204000
> >               Video Memory-to-Memory Multiplanar
> >               Streaming
> >               Extended Pix Format
> >       Detected Stateful Encoder
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> > Interface Info:
> >       ID               : 0x0300001a
> >       Type             : V4L Video
> > Entity Info:
> >       ID               : 0x0000000f (15)
> >       Name             : amphion-vpu-encoder-source
> >       Function         : V4L2 I/O
> >       Pad 0x01000010   : 0: Source
> >         Link 0x02000016: to remote pad 0x1000012 of entity
> > 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable
> >
> > Required ioctls:
> >       test MC information (see 'Media Driver Info' above): OK
> >       test VIDIOC_QUERYCAP: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/video1 open: OK
> >       test VIDIOC_QUERYCAP: OK
> >       test VIDIOC_G/S_PRIORITY: OK
> >       test for unlimited opens: OK
> >
> > Debug ioctls:
> >       test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
> >       test VIDIOC_LOG_STATUS: OK (Not Supported)
> >
> > Input ioctls:
> >       test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
> >       test VIDIOC_ENUMAUDIO: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDIO: OK (Not Supported)
> >       Inputs: 0 Audio Inputs: 0 Tuners: 0
> >
> > Output ioctls:
> >       test VIDIOC_G/S_MODULATOR: OK (Not Supported)
> >       test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
> >       test VIDIOC_ENUMAUDOUT: OK (Not Supported)
> >       test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
> >       test VIDIOC_G/S_AUDOUT: OK (Not Supported)
> >       Outputs: 0 Audio Outputs: 0 Modulators: 0
> >
> > Input/Output configuration ioctls:
> >       test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
> >       test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
> >       test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
> >       test VIDIOC_G/S_EDID: OK (Not Supported)
> >
> > Control ioctls:
> >       test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
> >       test VIDIOC_QUERYCTRL: OK
> >       test VIDIOC_G/S_CTRL: OK
> >       test VIDIOC_G/S/TRY_EXT_CTRLS: OK
> >       test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
> >       test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
> >       Standard Controls: 20 Private Controls: 0
> >
> > Format ioctls:
> >       test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
> >       test VIDIOC_G/S_PARM: OK
> >       test VIDIOC_G_FBUF: OK (Not Supported)
> >       test VIDIOC_G_FMT: OK
> >       test VIDIOC_TRY_FMT: OK
> >       test VIDIOC_S_FMT: OK
> >       test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
> >       test Cropping: OK
> >       test Composing: OK (Not Supported)
> >       test Scaling: OK (Not Supported)
> >
> > Codec ioctls:
> >       test VIDIOC_(TRY_)ENCODER_CMD: OK
> >       test VIDIOC_G_ENC_INDEX: OK (Not Supported)
> >       test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
> >
> > Buffer ioctls:
> >       test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
> >       test VIDIOC_EXPBUF: OK
> >       test Requests: OK (Not Supported)
> >
> > Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed:
> > 0, Warnings: 0
> >
> > # v4l2-compliance -d /dev/media0
> > v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t v4l2-compliance
> > SHA: 493af03f3c57 2021-10-08 17:23:11
> >
> > Compliance test for amphion-vpu device /dev/media0:
> >
> > Media Driver Info:
> >       Driver name      : amphion-vpu
> >       Model            : amphion-vpu
> >       Serial           :
> >       Bus info         : platform: amphion-vpu
> >       Media version    : 5.15.0
> >       Hardware revision: 0x00000000 (0)
> >       Driver version   : 5.15.0
> >
> > Required ioctls:
> >       test MEDIA_IOC_DEVICE_INFO: OK
> >       test invalid ioctls: OK
> >
> > Allow for multiple opens:
> >       test second /dev/media0 open: OK
> >       test MEDIA_IOC_DEVICE_INFO: OK
> >       test for unlimited opens: OK
> >
> > Media Controller ioctls:
> >       test MEDIA_IOC_G_TOPOLOGY: OK
> >       Entities: 6 Interfaces: 2 Pads: 8 Links: 8
> >       test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
> >       test MEDIA_IOC_SETUP_LINK: OK
> >
> > Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0,
> > Warnings: 0
> >
> > Ming Qian (13):
> >   dt-bindings: media: amphion: add amphion video codec bindings
> >   media: add nv12m_8l128 and nv12m_10be_8l128 video format.
> >   media: amphion: add amphion vpu device driver
> >   media: amphion: add vpu core driver
> >   media: amphion: implement vpu core communication based on mailbox
> >   media: amphion: add vpu v4l2 m2m support
> >   media: amphion: add v4l2 m2m vpu encoder stateful driver
> >   media: amphion: add v4l2 m2m vpu decoder stateful driver
> >   media: amphion: implement windsor encoder rpc interface
> >   media: amphion: implement malone decoder rpc interface
> >   ARM64: dts: freescale: imx8q: add imx vpu codec entries
> >   firmware: imx: scu-pd: imx8q: add vpu mu resources
> >   MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry
> >
> >  .../bindings/media/amphion,vpu.yaml           |  180 ++
> >  .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
> >  MAINTAINERS                                   |    9 +
> >  .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
> >  arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
> >  arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
> >  arch/arm64/configs/defconfig                  |    1 +
> >  drivers/firmware/imx/scu-pd.c                 |    4 +
> >  drivers/media/platform/Kconfig                |   19 +
> >  drivers/media/platform/Makefile               |    2 +
> >  drivers/media/platform/amphion/Makefile       |   20 +
> >  drivers/media/platform/amphion/vdec.c         | 1694 +++++++++++++++++
> >  drivers/media/platform/amphion/venc.c         | 1364 +++++++++++++
> >  drivers/media/platform/amphion/vpu.h          |  356 ++++
> >  drivers/media/platform/amphion/vpu_cmds.c     |  436 +++++
> >  drivers/media/platform/amphion/vpu_cmds.h     |   25 +
> >  drivers/media/platform/amphion/vpu_codec.h    |   68 +
> >  drivers/media/platform/amphion/vpu_color.c    |  183 ++
> >  drivers/media/platform/amphion/vpu_core.c     |  870 +++++++++
> >  drivers/media/platform/amphion/vpu_core.h     |   15 +
> >  drivers/media/platform/amphion/vpu_dbg.c      |  495 +++++
> >  drivers/media/platform/amphion/vpu_defs.h     |  187 ++
> >  drivers/media/platform/amphion/vpu_drv.c      |  260 +++
> >  drivers/media/platform/amphion/vpu_helpers.c  |  413 ++++
> >  drivers/media/platform/amphion/vpu_helpers.h  |   74 +
> >  drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
> >  drivers/media/platform/amphion/vpu_imx8q.h    |  115 ++
> >  drivers/media/platform/amphion/vpu_malone.c   | 1625
> ++++++++++++++++
> >  drivers/media/platform/amphion/vpu_malone.h   |   44 +
> >  drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
> >  drivers/media/platform/amphion/vpu_mbox.h     |   16 +
> >  drivers/media/platform/amphion/vpu_msgs.c     |  385 ++++
> >  drivers/media/platform/amphion/vpu_msgs.h     |   14 +
> >  drivers/media/platform/amphion/vpu_rpc.c      |  257 +++
> >  drivers/media/platform/amphion/vpu_rpc.h      |  456 +++++
> >  drivers/media/platform/amphion/vpu_v4l2.c     |  720 +++++++
> >  drivers/media/platform/amphion/vpu_v4l2.h     |   55 +
> >  drivers/media/platform/amphion/vpu_windsor.c  | 1169 ++++++++++++
> >  drivers/media/platform/amphion/vpu_windsor.h  |   37 +
> >  drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
> >  include/uapi/linux/videodev2.h                |    2 +
> >  41 files changed, 12099 insertions(+), 3 deletions(-)  create mode
> > 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
> >  create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
> >  create mode 100644 drivers/media/platform/amphion/Makefile
> >  create mode 100644 drivers/media/platform/amphion/vdec.c
> >  create mode 100644 drivers/media/platform/amphion/venc.c
> >  create mode 100644 drivers/media/platform/amphion/vpu.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_codec.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_color.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_core.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_core.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_defs.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_drv.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_malone.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_malone.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
> >  create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
> >  create mode 100644 drivers/media/platform/amphion/vpu_windsor.h
> >
> >
> > base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07


From festevam at gmail.com  Tue Jan 25 05:11:17 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Tue, 25 Jan 2022 10:11:17 -0300
Subject: [PATCH 1/6] clk: imx6ul: disable gpmi_io clock before changing
 parent clock
In-Reply-To: <20220125085206.8508-2-ceggers@arri.de>
References: <20220125085206.8508-1-ceggers@arri.de>
 <20220125085206.8508-2-ceggers@arri.de>
Message-ID: <CAOMZO5A2c1seLDHzb3HL58_cThM5LGB7n0Atywu_BhTCXAThyg@mail.gmail.com>

Hi Christian,

On Tue, Jan 25, 2022 at 5:53 AM Christian Eggers <ceggers at arri.de> wrote:
>
> gpmi_io clock may have been enabled by the boot loader. All children of
> enfc_clk_root must be gated in order to prevent glitches during parent
> change.
>
> Signed-off-by: Christian Eggers <ceggers at arri.de>
> ---
> drivers/clk/imx/clk-imx6ul.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
> index 520b100bff4b..f599ae50dd9f 100644
> --- a/drivers/clk/imx/clk-imx6ul.c
> +++ b/drivers/clk/imx/clk-imx6ul.c
> @@ -514,6 +514,15 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
> else if (clk_on_imx6ull())
> clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk);
>
> + /*
> + * gpmi_io clock may have been enabled by the boot loader. All children of
> + * enfc_clk_root must be gated in order to prevent glitches during parent
> + * change. The task of re-enabling is left to the gpmi-nand driver.
> + */
> + if (clk_hw_is_enabled(hws[IMX6UL_CLK_GPMI_IO])) {
> + clk_prepare_enable(hws[IMX6UL_CLK_GPMI_IO]->clk);
> + clk_disable_unprepare(hws[IMX6UL_CLK_GPMI_IO]->clk);
> + }

It seems your patch series was corrupted.

Could you please try sending it via git send-mail?


From krzysztof.kozlowski at canonical.com  Tue Jan 25 05:19:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 14:19:36 +0100
Subject: [PATCH 1/2] dt-bindings: mediatek: mt8186: Add binding for MM
 iommu
In-Reply-To: <20220125093244.18230-2-yong.wu@mediatek.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
 <20220125093244.18230-2-yong.wu@mediatek.com>
Message-ID: <9ce18ea8-caed-7d46-8f79-725561429f57@canonical.com>

On 25/01/2022 10:32, Yong Wu wrote:
> Add mt8186 iommu binding. "-mm" means the iommu is for Multimedia.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>  .../bindings/iommu/mediatek,iommu.yaml        |   4 +
>  .../dt-bindings/memory/mt8186-memory-port.h   | 217 ++++++++++++++++++
>  2 files changed, 221 insertions(+)
>  create mode 100644 include/dt-bindings/memory/mt8186-memory-port.h
> 


Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From baruch at tkos.co.il  Tue Jan 25 05:03:08 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 25 Jan 2022 15:03:08 +0200
Subject: [PATCH v10 1/3] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <20220119172439.be4xpaqgwzdy26oh@pengutronix.de>
References: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
 <20220119172439.be4xpaqgwzdy26oh@pengutronix.de>
Message-ID: <87tuds7y09.fsf@tarshish>

Hi Uwe,

Thanks for your detailed review and comments. Please find my comments
below.

On Wed, Jan 19 2022, Uwe Kleine-K?nig wrote:
> On Tue, Dec 14, 2021 at 06:27:17PM +0200, Baruch Siach wrote:
>> From: Baruch Siach <baruch.siach at siklu.com>
>> 
>> Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
>> driver from downstream Codeaurora kernel tree. Removed support for older
>> (V1) variants because I have no access to that hardware.
>> 
>> Tested on IPQ6010 based hardware.
>> 
>> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
>> ---
>> v10:
>> 
>>   Restore round up in pwm_div calculation; otherwise diff is always <=
>>   0, so only bingo match works
>> 
>>   Don't overwrite min_diff on every loop iteration
>> 
>> v9:
>> 
>> Address comment from Uwe Kleine-K?nig:
>> 
>>   Use period_ns*rate in dividers calculation for better accuracy
>> 
>>   Round down pre_div and pwm_div
>> 
>>   Add a comment explaining why pwm_div can't underflow
>> 
>>   Add a comment explaining why pre_div > pwm_div end the search loop
>> 
>>   Drop 'CFG_' from register macros
>> 
>>   Rename to_ipq_pwm_chip() to ipq_pwm_from_chip()
>> 
>>   Change bare 'unsigned' to 'unsigned int'
>> 
>>   Clarify the comment on separate REG1 write for enable/disable
>> 
>>   Round up the period value in .get_state
>> 
>>   Use direct readl/writel so no need to check for regmap errors
>> 
>> v7:
>> 
>>   Change 'offset' to 'reg' for the tcsr offset (Rob)
>> 
>>   Drop clock name; there is only one clock (Bjorn)
>> 
>>   Simplify probe failure code path (Bjorn)
>> 
>> v6:
>> 
>> Address Uwe Kleine-K?nig review comments:
>> 
>>   Drop IPQ_PWM_MAX_DEVICES
>> 
>>   Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ
>> 
>>   Simplify register offset calculation
>> 
>>   Calculate duty cycle more precisely
>> 
>>   Refuse to set inverted polarity
>> 
>>   Drop redundant IPQ_PWM_REG1_ENABLE bit clear
>> 
>>   Remove x1000 factor in pwm_div calculation, use rate directly, and round up
>> 
>>   Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV
>> 
>>   Ensure pre_div <= pwm_div
>> 
>>   Rename close_ to best_
>> 
>>   Explain in comment why effective_div doesn't overflow
>> 
>>   Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle
>> 
>>   Disable clock only after pwmchip_remove()
>> 
>>   const pwm_ops
>> 
>> Other changes:
>> 
>>   Add missing linux/bitfield.h header include (kernel test robot)
>> 
>>   Adjust code for PWM device node under TCSR (Rob Herring)
>> 
>> v5:
>> 
>> Use &tcsr_q6 syscon to access registers (Bjorn Andersson)
>> 
>> Address Uwe Kleine-K?nig review comments:
>> 
>>   Implement .get_state()
>> 
>>   Add IPQ_PWM_ prefix to local macros
>> 
>>   Use GENMASK/BIT/FIELD_PREP for register fields access
>> 
>>   Make type of config_div_and_duty() parameters consistent
>> 
>>   Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ
>> 
>>   Integrate enable/disable into config_div_and_duty() to save register read,
>>   and reduce frequency glitch on update
>> 
>>   Use min() instead of min_t()
>> 
>>   Fix comment format
>> 
>>   Use dev_err_probe() to indicate probe step failure
>> 
>>   Add missing clk_disable_unprepare() in .remove
>> 
>>   Don't set .owner
>> 
>> v4:
>> 
>>   Use div64_u64() to fix link for 32-bit targets ((kernel test robot
>>   <lkp at intel.com>, Uwe Kleine-K?nig)
>> 
>> v3:
>> 
>>   s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
>> 
>>   Fix integer overflow on 32-bit targets (kernel test robot <lkp at intel.com>)
>> 
>> v2:
>> 
>> Address Uwe Kleine-K?nig review comments:
>> 
>>   Fix period calculation when out of range
>> 
>>   Don't set period larger than requested
>> 
>>   Remove PWM disable on configuration change
>> 
>>   Implement .apply instead of non-atomic .config/.enable/.disable
>> 
>>   Don't modify PWM on .request/.free
>> 
>>   Check pwm_div underflow
>> 
>>   Fix various code and comment formatting issues
>> 
>> Other changes:
>> 
>>   Use u64 divisor safe division
>> 
>>   Remove now empty .request/.free
>> ---
>>  drivers/pwm/Kconfig   |  12 ++
>>  drivers/pwm/Makefile  |   1 +
>>  drivers/pwm/pwm-ipq.c | 275 ++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 288 insertions(+)
>>  create mode 100644 drivers/pwm/pwm-ipq.c
>> 
>> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
>> index 21e3b05a5153..e39718137ecd 100644
>> --- a/drivers/pwm/Kconfig
>> +++ b/drivers/pwm/Kconfig
>> @@ -260,6 +260,18 @@ config PWM_INTEL_LGM
>>  	  To compile this driver as a module, choose M here: the module
>>  	  will be called pwm-intel-lgm.
>>  
>> +config PWM_IPQ
>> +	tristate "IPQ PWM support"
>> +	depends on ARCH_QCOM || COMPILE_TEST
>> +	depends on HAVE_CLK && HAS_IOMEM
>> +	help
>> +	  Generic PWM framework driver for IPQ PWM block which supports
>> +	  4 pwm channels. Each of the these channels can be configured
>> +	  independent of each other.
>> +
>> +	  To compile this driver as a module, choose M here: the module
>> +	  will be called pwm-ipq.
>> +
>>  config PWM_IQS620A
>>  	tristate "Azoteq IQS620A PWM support"
>>  	depends on MFD_IQS62X || COMPILE_TEST
>> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
>> index 708840b7fba8..7402feae4b36 100644
>> --- a/drivers/pwm/Makefile
>> +++ b/drivers/pwm/Makefile
>> @@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
>>  obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
>>  obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
>>  obj-$(CONFIG_PWM_INTEL_LGM)	+= pwm-intel-lgm.o
>> +obj-$(CONFIG_PWM_IPQ)		+= pwm-ipq.o
>>  obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
>>  obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
>>  obj-$(CONFIG_PWM_KEEMBAY)	+= pwm-keembay.o
>> diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
>> new file mode 100644
>> index 000000000000..3764010808f0
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-ipq.c
>> @@ -0,0 +1,275 @@
>> +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
>> +/*
>> + * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
>> + */
>> +
>> +#include <linux/module.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pwm.h>
>> +#include <linux/clk.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +#include <linux/math64.h>
>> +#include <linux/of_device.h>
>> +#include <linux/bitfield.h>
>> +
>> +/* The frequency range supported is 1 Hz to clock rate */
>> +#define IPQ_PWM_MAX_PERIOD_NS	((u64)NSEC_PER_SEC)
>> +
>> +/*
>> + * The max value specified for each field is based on the number of bits
>> + * in the pwm control register for that field
>> + */
>> +#define IPQ_PWM_MAX_DIV		0xFFFF
>> +
>> +/*
>> + * Two 32-bit registers for each PWM: REG0, and REG1.
>> + * Base offset for PWM #i is at 8 * #i.
>> + */
>> +#define IPQ_PWM_REG0			0 /*PWM_DIV PWM_HI*/
>> +#define IPQ_PWM_REG0_PWM_DIV		GENMASK(15, 0)
>> +#define IPQ_PWM_REG0_HI_DURATION	GENMASK(31, 16)
>
> PWM_HI in the comment of IPQ_PWM_REG0 vs. HI_DURATION? Should this
> match? I'd say the comment is redundant.
>
>> +#define IPQ_PWM_REG1			4 /*ENABLE UPDATE PWM_PRE_DIV*/
>> +#define IPQ_PWM_REG1_PRE_DIV		GENMASK(15, 0)
>> +/*
>> + * Enable bit is set to enable output toggling in pwm device.
>> + * Update bit is set to reflect the changed divider and high duration
>> + * values in register.
>> + */
>> +#define IPQ_PWM_REG1_UPDATE		BIT(30)
>> +#define IPQ_PWM_REG1_ENABLE		BIT(31)
>> +
>> +
>> +struct ipq_pwm_chip {
>> +	struct pwm_chip chip;
>> +	struct clk *clk;
>> +	void __iomem *mem;
>> +};
>> +
>> +static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip)
>> +{
>> +	return container_of(chip, struct ipq_pwm_chip, chip);
>> +}
>> +
>> +static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg)
>> +{
>> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
>> +	unsigned int off = 8 * pwm->hwpwm + reg;
>> +
>> +	return readl(ipq_chip->mem + off);
>> +}
>> +
>> +static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg,
>> +			      unsigned int val)
>> +{
>> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
>> +	unsigned int off = 8 * pwm->hwpwm + reg;
>> +
>> +	writel(val, ipq_chip->mem + off);
>> +}
>> +
>> +static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
>> +			unsigned int pwm_div, unsigned long rate, u64 duty_ns,
>> +			bool enable)
>> +{
>> +	unsigned long hi_dur;
>> +	unsigned long val = 0;
>> +
>> +	/*
>> +	 * high duration = pwm duty * (pwm div + 1)
>> +	 * pwm duty = duty_ns / period_ns
>> +	 */
>> +	hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
>> +
>> +	val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
>> +		FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
>> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val);
>> +
>> +	val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
>> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
>> +
>> +	/* PWM enable toggle needs a separate write to REG1 */
>> +	val |= IPQ_PWM_REG1_UPDATE;
>> +	if (enable)
>> +		val |= IPQ_PWM_REG1_ENABLE;
>> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
>> +}
>> +
>> +static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>> +			 const struct pwm_state *state)
>> +{
>> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
>> +	unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
>> +	unsigned long rate = clk_get_rate(ipq_chip->clk);
>> +	u64 period_ns, duty_ns, period_rate;
>> +	u64 min_diff;
>> +
>> +	if (state->polarity != PWM_POLARITY_NORMAL)
>> +		return -EINVAL;
>> +
>> +	if (state->period < div64_u64(NSEC_PER_SEC, rate))
>> +		return -ERANGE;
>
> NSEC_PER_SEC / rate is the smallest period you can achieve, right?
> Consider rate = 33333 (Hz), then the minimal period is
> 30000.30000300003 ns. So you should refuse a request to configure
> state->period = 30000, but as div64_u64(1000000000, 33333) is 30000 you
> don't.
>
>> +	period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
>> +	duty_ns = min(state->duty_cycle, period_ns);
>> +
>> +	/*
>> +	 * period_ns is 1G or less. As long as rate is less than 16 GHz this
>> +	 * does not overflow.
>
> Well, rate cannot be bigger than 4294967295 because an unsigned long
> cannot hold a bigger value.

On 64-bit systems __SIZEOF_LONG__ is 8, which can hold more than 2^32.

>> +	 */
>> +	period_rate = period_ns * rate;
>> +	best_pre_div = IPQ_PWM_MAX_DIV;
>> +	best_pwm_div = IPQ_PWM_MAX_DIV;
>> +	/* Initial pre_div value such that pwm_div < IPQ_PWM_MAX_DIV */

Note this comment.

>> +	pre_div = div64_u64(period_rate,
>> +			(u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));
>
> Hmmm, we want 
>
> 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
> 	-------------------------------------------- <= period_ns
> 	                  rate
>
> , right? Resolving that for pre_div this gives:
>
> 	                period_ns * rate
> 	pre_div <= ----------------------------
> 	           NSEC_PER_SEC * (pwm_div + 1)
>
> The term on the right hand side is maximal for pwm_div == 0 so the
> possible values for pre_div are
>
> 	0 ... min(div64_u64(period_rate / NSEC_PER_SEC), IPQ_PWM_MAX_DIV)
>
> isn't it?

I don't think so. pre_div == 0 will produce pwm_div larger than
IPQ_PWM_MAX_DIV for a large period_rate value. The initial pre_div here is the
smallest value that produces pwm_div within it limit.

> If so, your algorithm is wrong as you're iterating over
>
> 	div64_u64(period_rate, NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)) ... IPQ_PWM_MAX_DIV

The loop stops when pre_div > pwm_div. That should be before pre_div ==
IPQ_PWM_MAX_DIV because pwm_div <= IPQ_PWM_MAX_DIV. Should I put the pre_div >
pwm_div condition directly in the for statement?

>> +	min_diff = period_rate;
>> +
>> +	for (; pre_div <= IPQ_PWM_MAX_DIV; pre_div++) {
>> +		long long diff;
>> +
>> +		pwm_div = DIV64_U64_ROUND_UP(period_rate,
>> +				(u64)NSEC_PER_SEC * (pre_div + 1));
>> +		/* pwm_div is unsigned; the check below catches underflow */
>> +		pwm_div--;
>
> What underflow? DIV64_U64_ROUND_UP returns > 0 assuming period_rate > 0.
> So pwm_div - 1 doesn't underflow?!

I'll update the comment.

> The task here is to calculate the biggest pwm_div for a given pre_div
> such that
>
>
> 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
> 	-------------------------------------------- <= period_ns
> 	                   rate
>
> right?
>
> This is equivalent to:
>
> 	                  period_ns * rate
> 	pre_div <= ---------------------------- - 1
> 	           (pre_div + 1) * NSEC_PER_SEC
>
> As pre_div is integer, rounding down should be fine?!

I can't follow. With round down (as in v8) the result is always:

  NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1) <= period_rate

As a result, 'diff' calculation below will always produce diff <= 0. When
there is no diff == 0 result (bingo) we get IPQ_PWM_MAX_DIV in both best_
values at the end of the loop.

Do we actually need diff > 0 in the condition below?

>> +		/*
>> +		 * pre_div and pwm_div values swap produces the same
>> +		 * result. This loop goes over all pre_div <= pwm_div
>> +		 * combinations. The rest are equivalent.
>> +		 */
>
> I'd write:
>
> 	/*
> 	 * Swapping values for pre_div and pwm_div produces the same
> 	 * period length. So we can skip all settings with pre_div <
> 	 * pwm_div which results in bigger constraints for selecting the
> 	 * duty_cycle than with the two values swapped.
> 	 */

I'll take your wording with inverted inequality sign.

Thanks,
baruch

>> +		if (pre_div > pwm_div)
>> +			break;
>> +
>> +		/*
>> +		 * Make sure we can do 100% duty cycle where
>> +		 * hi_dur == pwm_div + 1
>> +		 */
>> +		if (pwm_div > IPQ_PWM_MAX_DIV - 1)
>> +			continue;
>> +
>> +		diff = ((uint64_t)NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1))
>> +			- period_rate;
>> +
>> +		if (diff < 0) /* period larger than requested */
>> +			continue;
>
> This shouldn't happen if the above calculation is correct.
>
>> +		if (diff == 0) { /* bingo */
>> +			best_pre_div = pre_div;
>> +			best_pwm_div = pwm_div;
>> +			break;
>> +		}
>> +		if (diff < min_diff) {
>> +			min_diff = diff;
>> +			best_pre_div = pre_div;
>> +			best_pwm_div = pwm_div;
>> +		}
>
> This can be simplified as:
>
> 		if (diff < min_diff) {
> 			best_pre_div = pre_div;
> 			best_pwm_div = pwm_div;
> 			min_diff = diff;
>
> 			if (min_diff == 0)
> 				/* bingo! */
> 				break;
> 		}
>
>> +	}
>> +
>> +	/* config divider values for the closest possible frequency */
>> +	config_div_and_duty(pwm, best_pre_div, best_pwm_div,
>> +			    rate, duty_ns, state->enabled);
>> +
>> +	return 0;
>> +}
>> +
>> +static void ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
>> +			      struct pwm_state *state)
>> +{
>> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
>> +	unsigned long rate = clk_get_rate(ipq_chip->clk);
>> +	unsigned int pre_div, pwm_div, hi_dur;
>> +	u64 effective_div, hi_div;
>> +	u32 reg0, reg1;
>> +
>> +	reg0 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG0);
>> +	reg1 = ipq_pwm_reg_read(pwm, IPQ_PWM_REG1);
>> +
>> +	state->polarity = PWM_POLARITY_NORMAL;
>> +	state->enabled = reg1 & IPQ_PWM_REG1_ENABLE;
>> +
>> +	pwm_div = FIELD_GET(IPQ_PWM_REG0_PWM_DIV, reg0);
>> +	hi_dur = FIELD_GET(IPQ_PWM_REG0_HI_DURATION, reg0);
>> +	pre_div = FIELD_GET(IPQ_PWM_REG1_PRE_DIV, reg1);
>> +
>> +	/* No overflow here, both pre_div and pwm_div <= 0xffff */
>> +	effective_div = (u64)(pre_div + 1) * (pwm_div + 1);
>> +	state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC, rate);
>> +
>> +	hi_div = hi_dur * (pre_div + 1);
>> +	state->duty_cycle = div64_u64(hi_div * NSEC_PER_SEC, rate);
>
> This must be round up for the same reasons as for period.
>
>> +}
>
> Best regards
> Uwe


-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From maz at kernel.org  Tue Jan 25 05:21:47 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 13:21:47 +0000
Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest
In-Reply-To: <Ye/sS0jEXnBuumeG@sirena.org.uk>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-26-broonie@kernel.org>
 <87y2346on8.wl-maz@kernel.org> <Ye/sS0jEXnBuumeG@sirena.org.uk>
Message-ID: <87v8y86jdg.wl-maz@kernel.org>

On Tue, 25 Jan 2022 12:25:47 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> On Tue, Jan 25, 2022 at 11:27:55AM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
> 
> > Please drop the IS_ENABLED(). We purposely avoid conditional
> > compilation in KVM in order to avoid bitrot, and the amount of code
> > you save isn't significant. Having a static key is more than enough to
> > avoid runtime costs.
> 
> Sure, I wanted to be extra careful here as this is all in hot paths and
> going to get moved elsewhere when we have real guest support.
> 
> > > +	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
> > > +	    cpus_have_final_cap(ARM64_HAS_FGT)) {
> > > +		val = read_sysreg_s(SYS_HFGRTR_EL2);
> > > +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> > > +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> > > +		write_sysreg_s(val, SYS_HFGRTR_EL2);
> > > +
> > > +		val = read_sysreg_s(SYS_HFGWTR_EL2);
> > > +		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
> > > +			 HFGxTR_EL2_nSMPRI_EL1_MASK);
> > > +		write_sysreg_s(val, SYS_HFGWTR_EL2);
> > > +	}
> 
> > If the CPUs do not have FGT, what provides the equivalent trapping?
> 
> Nothing for nVHE mode.

That's what I feared.

> 
> > If FGT is mandatory when SME exists, then you should simplify the
> > condition.
> 
> OK, I'll remove the defensiveness here.  FGT is mandatory from v8.6 and
> SME is a v9 feature so people shouldn't build a SME implementation that
> lacks FGT.

Can you then please make it that SME doesn't get enabled at all if FGT
isn't present? It would also be good to have a clarification in the
architecture that it isn't allowed to build SME without FGT (specially
given that v9.0 is congruent to v8.5, and thus doesn't have FGT).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Tue Jan 25 05:21:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 14:21:54 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAPLW+4=xaHA2a=-F4ikuUPDpoO8Waj7qrrfpgkift1aMi_hU+g@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <CAPLW+4n-1H5Yu3wQaus-UJ_VW_TjHrNUHaPCGCMURXg8EqxjyA@mail.gmail.com>
 <CAK8P3a1ou-ZdrXN0MHQoJ+gGbvhXT-e2qt96_f9M8VwrdX0pAg@mail.gmail.com>
 <CAOesGMgF3S5_XsWjEqq=-zfYXwOWFpFNA6afL81wceRUA_0FeQ@mail.gmail.com>
 <CAPLW+4k8=ymx56R7bKOt8kMVG_uUgrTsCkVd5wiY_rkYq8dYbQ@mail.gmail.com>
 <72a50afd-df9f-ceb3-898e-070d70dc0221@canonical.com>
 <CAPLW+4=xaHA2a=-F4ikuUPDpoO8Waj7qrrfpgkift1aMi_hU+g@mail.gmail.com>
Message-ID: <d79e19e8-e15d-fe09-6ebc-c1f8aaacfc00@canonical.com>

On 24/01/2022 14:50, Sam Protsenko wrote:
> On Sun, 23 Jan 2022 at 21:27, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 22/01/2022 13:38, Sam Protsenko wrote:
>>> On Wed, 19 Jan 2022 at 18:53, Olof Johansson <olof at lixom.net> wrote:
>>>>
>>>> On Wed, Jan 19, 2022 at 8:07 AM Arnd Bergmann <arnd at arndb.de> wrote:
>>>>>
>>>>> On Wed, Jan 19, 2022 at 4:11 PM Sam Protsenko
>>>>> <semen.protsenko at linaro.org> wrote:
>>>>>> On Mon, 27 Dec 2021 at 13:30, Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com> wrote:
>>>>>>
>>>>>> Hi Olof, Arnd,
>>>>>>
>>>>>> Just want to check if it's possible for those patches to be applied in
>>>>>> v5.17? Sorry for the noise, but that's important to me.
>>>>>
>>>>> I can see that Olof merged merged this into the "arm/late" branch in
>>>>> the soc tree,
>>>>> so I assume he still plans to send it in the next few days.
>>>>
>>>> Yep, will be sent up today most likely.
>>>>
>>>
>>> Thanks for detailed answer! Glad to hear it's still a possibility.
>>> Please let me know if you need any actions on my side (like rebasing,
>>> etc).
>>>
>>>>> With the timing over Christmas, I sent out the large bulk of the
>>>>> contents (anything
>>>>> I merged before Dec 23) last year, and Linus already merged it, the rest ended
>>>>> up in the "late" branch.
>>>>>
>>>>> As usual, there is no guarantee that late changes make it in, but I have seen
>>>>> no indication of any problems so far.
>>>>
>>>> Correct. Been sitting on it for a while in case there were fixes
>>>> coming in for the first pieces that got merged, but in traditional
>>>> fashion I'm guessing those will start to show up a few days after the
>>>> late branch gets merged. :)
>>
>> Olof,
>> v5.17-rc1 came earlier, so I see this part did not make into it. Is
>> there a chance for a past-rc1 pull to Linus with it?
>>
>> Sam,
>> Anyway the patches wont' get lost (you mentioned such worry in previous
>> email to me). They might just need to wait. Unfortunately if patch,
>> especially with new feature, is coming in the end of cycle, there is a
>> risk it won't make it. The patches have to wait a few days in my trees
>> before I send them to Arnd/Olof, so if the patch is coming after rc6, I
>> can push it to Arnd/Olof around rc7, you see there is very little time.
>>
> 
> Should I send the patch fixing hard-coded clock numbers though? I
> remember you said I should send it once -rc1 is out. But now that dts
> patches are not merged in mainline, I'm not sure it can still be
> applied?

Yeah, please wait.

We have few patches following that pull-request, so it will be actually
easier not to merge it to soc-tree but resend soon with the follow-ups.


Best regards,
Krzysztof


From maz at kernel.org  Tue Jan 25 05:22:51 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 13:22:51 +0000
Subject: [PATCH v8 26/38] KVM: arm64: Handle SME host state when running
 guests
In-Reply-To: <Ye/ygvnlzPKYT2z6@sirena.org.uk>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-27-broonie@kernel.org>
 <87wnio6n7d.wl-maz@kernel.org> <Ye/ygvnlzPKYT2z6@sirena.org.uk>
Message-ID: <87tuds6jbo.wl-maz@kernel.org>

On Tue, 25 Jan 2022 12:52:18 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> On Tue, Jan 25, 2022 at 11:59:02AM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > +	if (has_vhe()) {
> > > +		if (system_supports_sme()) {
> 
> > nit:	if (has_vhe() && system_supports_sme()) {
> 
> > saves you one level of indentation.
> 
> Yes, for now.  IIRC there was some other stuff there when I had some of
> the code for doing the register switching properly.
> 
> > > +			/* Also restore EL0 state seen on entry */
> > > +			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
> > > +				sysreg_clear_set(CPACR_EL1, 0,
> > > +						 CPACR_EL1_SMEN_EL0EN |
> > > +						 CPACR_EL1_SMEN_EL1EN);
> > > +			else
> > > +				sysreg_clear_set(CPACR_EL1,
> > > +						 CPACR_EL1_SMEN_EL0EN,
> > > +						 CPACR_EL1_SMEN_EL1EN);
> 
> > I find the use of CPACR_EL1_SMEN in some cases and its individual bits
> > in some others pretty confusing. I understand that you have modelled
> > it after the SVE code, but maybe this is a mistake we don't need to
> > repeat. I'd be in favour of directly exposing the individual bits in
> > all cases.
> 
> OK, it is just the KVM code that uses the plain ZEN.  I'll add a cleanup
> patch for that at the start of the series for ZEN I guess otherwise it
> looks worse, though that will inflate the size of the series a bit.

I'm happy to merge such a patch early if that helps.

	M.

-- 
Without deviation from the norm, progress is not possible.


From lkp at intel.com  Tue Jan 25 05:31:32 2022
From: lkp at intel.com (kernel test robot)
Date: Tue, 25 Jan 2022 21:31:32 +0800
Subject: [PATCH v6 05/13] peci: Add peci-aspeed controller driver
In-Reply-To: <20220125011104.2480133-6-iwona.winiarska@intel.com>
References: <20220125011104.2480133-6-iwona.winiarska@intel.com>
Message-ID: <202201252130.U4qxBhmg-lkp@intel.com>

Hi Iwona,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on groeck-staging/hwmon-next]
[also build test ERROR on linux/master linus/master v5.17-rc1 next-20220125]
[cannot apply to joel-aspeed/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Iwona-Winiarska/Introduce-PECI-subsystem/20220125-115946
base:   https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220125/202201252130.U4qxBhmg-lkp at intel.com/config)
compiler: sh4-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/35075a61a26913806122a9b500915dc66ad678bd
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Iwona-Winiarska/Introduce-PECI-subsystem/20220125-115946
        git checkout 35075a61a26913806122a9b500915dc66ad678bd
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=sh SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/clk/clk.c:856:6: error: redefinition of 'clk_unprepare'
     856 | void clk_unprepare(struct clk *clk)
         |      ^~~~~~~~~~~~~
   In file included from drivers/clk/clk.c:9:
   include/linux/clk.h:303:20: note: previous definition of 'clk_unprepare' with type 'void(struct clk *)'
     303 | static inline void clk_unprepare(struct clk *clk)
         |                    ^~~~~~~~~~~~~
>> drivers/clk/clk.c:937:5: error: redefinition of 'clk_prepare'
     937 | int clk_prepare(struct clk *clk)
         |     ^~~~~~~~~~~
   In file included from drivers/clk/clk.c:9:
   include/linux/clk.h:271:19: note: previous definition of 'clk_prepare' with type 'int(struct clk *)'
     271 | static inline int clk_prepare(struct clk *clk)
         |                   ^~~~~~~~~~~
>> drivers/clk/clk.c:1183:6: error: redefinition of 'clk_is_enabled_when_prepared'
    1183 | bool clk_is_enabled_when_prepared(struct clk *clk)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/clk/clk.c:9:
   include/linux/clk.h:284:20: note: previous definition of 'clk_is_enabled_when_prepared' with type 'bool(struct clk *)' {aka '_Bool(struct clk *)'}
     284 | static inline bool clk_is_enabled_when_prepared(struct clk *clk)
         |                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for COMMON_CLK
   Depends on !HAVE_LEGACY_CLK
   Selected by
   - PECI_ASPEED && PECI && (ARCH_ASPEED || COMPILE_TEST && OF && HAS_IOMEM


vim +/clk_unprepare +856 drivers/clk/clk.c

a6adc30ba7bef8 Dong Aisheng     2016-06-30  844  
4dff95dc9477a3 Stephen Boyd     2015-04-30  845  /**
4dff95dc9477a3 Stephen Boyd     2015-04-30  846   * clk_unprepare - undo preparation of a clock source
4dff95dc9477a3 Stephen Boyd     2015-04-30  847   * @clk: the clk being unprepared
4dff95dc9477a3 Stephen Boyd     2015-04-30  848   *
4dff95dc9477a3 Stephen Boyd     2015-04-30  849   * clk_unprepare may sleep, which differentiates it from clk_disable.  In a
4dff95dc9477a3 Stephen Boyd     2015-04-30  850   * simple case, clk_unprepare can be used instead of clk_disable to gate a clk
4dff95dc9477a3 Stephen Boyd     2015-04-30  851   * if the operation may sleep.  One example is a clk which is accessed over
4dff95dc9477a3 Stephen Boyd     2015-04-30  852   * I2c.  In the complex case a clk gate operation may require a fast and a slow
4dff95dc9477a3 Stephen Boyd     2015-04-30  853   * part.  It is this reason that clk_unprepare and clk_disable are not mutually
4dff95dc9477a3 Stephen Boyd     2015-04-30  854   * exclusive.  In fact clk_disable must be called before clk_unprepare.
4dff95dc9477a3 Stephen Boyd     2015-04-30  855   */
4dff95dc9477a3 Stephen Boyd     2015-04-30 @856  void clk_unprepare(struct clk *clk)
b2476490ef1113 Mike Turquette   2012-03-15  857  {
4dff95dc9477a3 Stephen Boyd     2015-04-30  858  	if (IS_ERR_OR_NULL(clk))
4dff95dc9477a3 Stephen Boyd     2015-04-30  859  		return;
b2476490ef1113 Mike Turquette   2012-03-15  860  
a6adc30ba7bef8 Dong Aisheng     2016-06-30  861  	clk_core_unprepare_lock(clk->core);
1e435256d625c2 Olof Johansson   2013-04-27  862  }
4dff95dc9477a3 Stephen Boyd     2015-04-30  863  EXPORT_SYMBOL_GPL(clk_unprepare);
1e435256d625c2 Olof Johansson   2013-04-27  864  
4dff95dc9477a3 Stephen Boyd     2015-04-30  865  static int clk_core_prepare(struct clk_core *core)
4dff95dc9477a3 Stephen Boyd     2015-04-30  866  {
4dff95dc9477a3 Stephen Boyd     2015-04-30  867  	int ret = 0;
b2476490ef1113 Mike Turquette   2012-03-15  868  
a63347251907d7 Stephen Boyd     2015-05-06  869  	lockdep_assert_held(&prepare_lock);
a63347251907d7 Stephen Boyd     2015-05-06  870  
4dff95dc9477a3 Stephen Boyd     2015-04-30  871  	if (!core)
4dff95dc9477a3 Stephen Boyd     2015-04-30  872  		return 0;
b2476490ef1113 Mike Turquette   2012-03-15  873  
4dff95dc9477a3 Stephen Boyd     2015-04-30  874  	if (core->prepare_count == 0) {
9a34b45397e5a3 Marek Szyprowski 2017-08-21  875  		ret = clk_pm_runtime_get(core);
4dff95dc9477a3 Stephen Boyd     2015-04-30  876  		if (ret)
4dff95dc9477a3 Stephen Boyd     2015-04-30  877  			return ret;
b2476490ef1113 Mike Turquette   2012-03-15  878  
9a34b45397e5a3 Marek Szyprowski 2017-08-21  879  		ret = clk_core_prepare(core->parent);
9a34b45397e5a3 Marek Szyprowski 2017-08-21  880  		if (ret)
9a34b45397e5a3 Marek Szyprowski 2017-08-21  881  			goto runtime_put;
9a34b45397e5a3 Marek Szyprowski 2017-08-21  882  
4dff95dc9477a3 Stephen Boyd     2015-04-30  883  		trace_clk_prepare(core);
1c155b3dfe0835 Ulf Hansson      2013-03-12  884  
4dff95dc9477a3 Stephen Boyd     2015-04-30  885  		if (core->ops->prepare)
4dff95dc9477a3 Stephen Boyd     2015-04-30  886  			ret = core->ops->prepare(core->hw);
1c155b3dfe0835 Ulf Hansson      2013-03-12  887  
4dff95dc9477a3 Stephen Boyd     2015-04-30  888  		trace_clk_prepare_complete(core);
b2476490ef1113 Mike Turquette   2012-03-15  889  
9a34b45397e5a3 Marek Szyprowski 2017-08-21  890  		if (ret)
9a34b45397e5a3 Marek Szyprowski 2017-08-21  891  			goto unprepare;
b2476490ef1113 Mike Turquette   2012-03-15  892  	}
b2476490ef1113 Mike Turquette   2012-03-15  893  
4dff95dc9477a3 Stephen Boyd     2015-04-30  894  	core->prepare_count++;
b2476490ef1113 Mike Turquette   2012-03-15  895  
9461f7b33d11cb Jerome Brunet    2018-06-19  896  	/*
9461f7b33d11cb Jerome Brunet    2018-06-19  897  	 * CLK_SET_RATE_GATE is a special case of clock protection
9461f7b33d11cb Jerome Brunet    2018-06-19  898  	 * Instead of a consumer claiming exclusive rate control, it is
9461f7b33d11cb Jerome Brunet    2018-06-19  899  	 * actually the provider which prevents any consumer from making any
9461f7b33d11cb Jerome Brunet    2018-06-19  900  	 * operation which could result in a rate change or rate glitch while
9461f7b33d11cb Jerome Brunet    2018-06-19  901  	 * the clock is prepared.
9461f7b33d11cb Jerome Brunet    2018-06-19  902  	 */
9461f7b33d11cb Jerome Brunet    2018-06-19  903  	if (core->flags & CLK_SET_RATE_GATE)
9461f7b33d11cb Jerome Brunet    2018-06-19  904  		clk_core_rate_protect(core);
9461f7b33d11cb Jerome Brunet    2018-06-19  905  
4dff95dc9477a3 Stephen Boyd     2015-04-30  906  	return 0;
9a34b45397e5a3 Marek Szyprowski 2017-08-21  907  unprepare:
9a34b45397e5a3 Marek Szyprowski 2017-08-21  908  	clk_core_unprepare(core->parent);
9a34b45397e5a3 Marek Szyprowski 2017-08-21  909  runtime_put:
9a34b45397e5a3 Marek Szyprowski 2017-08-21  910  	clk_pm_runtime_put(core);
9a34b45397e5a3 Marek Szyprowski 2017-08-21  911  	return ret;
b2476490ef1113 Mike Turquette   2012-03-15  912  }
b2476490ef1113 Mike Turquette   2012-03-15  913  
a6adc30ba7bef8 Dong Aisheng     2016-06-30  914  static int clk_core_prepare_lock(struct clk_core *core)
a6adc30ba7bef8 Dong Aisheng     2016-06-30  915  {
a6adc30ba7bef8 Dong Aisheng     2016-06-30  916  	int ret;
a6adc30ba7bef8 Dong Aisheng     2016-06-30  917  
a6adc30ba7bef8 Dong Aisheng     2016-06-30  918  	clk_prepare_lock();
a6adc30ba7bef8 Dong Aisheng     2016-06-30  919  	ret = clk_core_prepare(core);
a6adc30ba7bef8 Dong Aisheng     2016-06-30  920  	clk_prepare_unlock();
a6adc30ba7bef8 Dong Aisheng     2016-06-30  921  
a6adc30ba7bef8 Dong Aisheng     2016-06-30  922  	return ret;
a6adc30ba7bef8 Dong Aisheng     2016-06-30  923  }
a6adc30ba7bef8 Dong Aisheng     2016-06-30  924  
4dff95dc9477a3 Stephen Boyd     2015-04-30  925  /**
4dff95dc9477a3 Stephen Boyd     2015-04-30  926   * clk_prepare - prepare a clock source
4dff95dc9477a3 Stephen Boyd     2015-04-30  927   * @clk: the clk being prepared
4dff95dc9477a3 Stephen Boyd     2015-04-30  928   *
4dff95dc9477a3 Stephen Boyd     2015-04-30  929   * clk_prepare may sleep, which differentiates it from clk_enable.  In a simple
4dff95dc9477a3 Stephen Boyd     2015-04-30  930   * case, clk_prepare can be used instead of clk_enable to ungate a clk if the
4dff95dc9477a3 Stephen Boyd     2015-04-30  931   * operation may sleep.  One example is a clk which is accessed over I2c.  In
4dff95dc9477a3 Stephen Boyd     2015-04-30  932   * the complex case a clk ungate operation may require a fast and a slow part.
4dff95dc9477a3 Stephen Boyd     2015-04-30  933   * It is this reason that clk_prepare and clk_enable are not mutually
4dff95dc9477a3 Stephen Boyd     2015-04-30  934   * exclusive.  In fact clk_prepare must be called before clk_enable.
4dff95dc9477a3 Stephen Boyd     2015-04-30  935   * Returns 0 on success, -EERROR otherwise.
4dff95dc9477a3 Stephen Boyd     2015-04-30  936   */
4dff95dc9477a3 Stephen Boyd     2015-04-30 @937  int clk_prepare(struct clk *clk)
b2476490ef1113 Mike Turquette   2012-03-15  938  {
035a61c314eb3d Tomeu Vizoso     2015-01-23  939  	if (!clk)
4dff95dc9477a3 Stephen Boyd     2015-04-30  940  		return 0;
035a61c314eb3d Tomeu Vizoso     2015-01-23  941  
a6adc30ba7bef8 Dong Aisheng     2016-06-30  942  	return clk_core_prepare_lock(clk->core);
7ef3dcc8145263 James Hogan      2013-07-29  943  }
4dff95dc9477a3 Stephen Boyd     2015-04-30  944  EXPORT_SYMBOL_GPL(clk_prepare);
035a61c314eb3d Tomeu Vizoso     2015-01-23  945  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From mark.rutland at arm.com  Tue Jan 25 05:32:48 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 13:32:48 +0000
Subject: [bootwrapper PATCH v2 06/13] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220118123741.5f367d1f@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-7-mark.rutland@arm.com>
 <20220114181247.7b366f45@donnerap.cambridge.arm.com>
 <20220117121557.GA87485@C02TD0UTHF1T.local>
 <20220117130554.GB87485@C02TD0UTHF1T.local>
 <20220118123741.5f367d1f@donnerap.cambridge.arm.com>
Message-ID: <Ye/8ALjEB+0Y4w6f@FVFF77S0Q05N>

On Tue, Jan 18, 2022 at 12:37:41PM +0000, Andre Przywara wrote:
> On Mon, 17 Jan 2022 13:05:54 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > On Mon, Jan 17, 2022 at 12:15:57PM +0000, Mark Rutland wrote:
> > > On Fri, Jan 14, 2022 at 06:12:47PM +0000, Andre Przywara wrote:  
> > > > On Fri, 14 Jan 2022 10:56:46 +0000
> > > > Mark Rutland <mark.rutland at arm.com> wrote:
> > > > 
> > > > Hi Mark,  
> > > 
> > > Hi Andre,  
> >  
> > > > > +
> > > > > +#define SCTLR_EL1_RES1		(BIT(29) | BIT(28) | BIT(23) | BIT(22) | \
> > > > > +				 BIT(11) | BIT(8) | BIT(7) | BIT(4))  
> > 
> > > > > -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
> > > > >  
> > > > >  #ifdef KERNEL_32
> > > > >  /* 32-bit kernel decompressor uses CP15 barriers */
> > > > > #define SCTLR_EL1_KERNEL        (SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)  
> > > > 
> > > > So I wonder if this actually works? The ARMv7 version of SCTLR
> > > > differs in some bits from both the ARMv8 AArch32 version and more
> > > > importantly the AArch64 version.  
> > 
> > > > I had troubles the other day running the
> > > > arm32 Linux kernel decompressor with some ARMv8 SCTLR_EL1 reset value. The
> > > > decompressor code does only read-modify-write of SCTLR (probably to
> > > > cover multiple architecture revisions), so some bits might stay wrong. In
> > > > particular I think having bits 28 and 29 set caused problems.
> > > > By looking at the ARMv7 ARM and with experimentation I came up
> > > > with 0x00c00878 as a safe and working value.  
> > 
> > Having re-read all of this, I believe you're right; I'll rework the
> > AArch32-kernel SCTLR_EL1_KERNEL to not use the AArch64 bit definitions,
> > and I'll add some commentary explaining that we're writing to the AArch32
> > format.
> > 
> > > > Shall we have a separate reset value for 32bit?  
> > 
> > Assuming you meant to alter the SCTLR_ELx_KERNEL definition, yes.
> > 
> > The idea of splitting the SCTLR_ELx_RESET and SCTLR_ELx_KERNEL
> > definitions was that the former would be whatever the boot-wrapper
> > needed to run at ELx, and the latter was whatever we must initialize for
> > the kernel to run at ELx, so I don't want to put the AArch32 kernel bits
> > into SCTLR_EL1_RESET.
> > 
> > My only remaining concern is exactly what we must initialize. If there's
> > any documentation we can refer to, that'd be great, otherwise I'll dig
> > through your prior suggestion.
> 
> I don't know of any recommendation what to initialise, though the ARMv7
> ARM speaks a bit about reset values.
> So the SCTLR_KERNEL value we use in arch/aarch32/include/asm/cpu.h seems
> to work (although it's not perfect), but we should use the same in the
> KERNEL_32 case in arch/aarch64/include/asm/cpu.h.

Ok; for now I'm going to copy the SCTLR_KERNEL definition as-is from the
aarch32 header, and add a comment that we should restructure things to share a
single definition in future.

The rest of the reply is mostly for future reference.

> Going through the SCTLR description in the ARMv8 *and* ARMv7 ARM again,
> I think a safe and sane init value would be to set bits
> [23,22,18,16,11,5,4,3] to one. This differs slightly from the value I told
> you above, which I think was what I observed on an Cortex-A7 when dumping
> SCTLR in the decompressor code.

Having delved through the ARM ARM, those bits look right to me. Below is
expanded detail for each bit to save having to delve into the ARM ARM again.

Looking at the latest ARM ARM (ARM DDI 0487G.b), section G8.2.126 "SCTLR,
System Control Register" starting on page G8-6810:

* Bit 25 / EE
  RES0/RES1 in depending on implemented endianness support. Currently the
  boot-wrapper doesn't handle missin support for either BE or LE, so I'm going
  to ignore this for now and just assume LE is present (so 0 is a legitimate
  value).

* Bit 23 / SPAN
  RES1 where FEAT_PAN is not implemented.

* Bit 22 
  RES1 always.

* Bit 18 / nTWE
  Not RESx, but warm-resets to 1.

* Bit 16 / nTWI
  Not RESx, but warm-resets to 1.

* Bit 11 
  RES1 always.

* Bit 5 / CP15BEN
  Not RESx, but warm-resets to 1.

* Bit 4 / LSMAOE
  RES1 where FEAT_LSMAOC is not implemented.
  Warm-resets to 1 where FEAT_LSMAOC is implemented.

* Bit 3 / nTLSMD
  RES1 where FEAT_LSMAOC is not implemented.
  Warm-resets to 1 where FEAT_LSMAOC is implemented.

... with all other bits being UNKNOWN, RES0, or warm-rest to 0.

> I became aware of the issue when I tried to start an ARM kernel on a
> Cortex-A53 board, with U-Boot dropping from AArch64-EL2 to AArch32-EL1.
> SCTLR_EL1 there got initialised according to the ARMv8 ARM (bits
> [29,28,23,22,20,11] set), but this made the kernel decompressor hang as
> soon as the MMU got enabled. I *think* I bisected it down to bits 28 and
> 29, which are RES1 in AArch64, but enable TEX remap and the Access Flag in
> v7, and both reset to 0 there. I haven't tried that on the model with the
> boot-wrapper, but I guess we see the same problem there.
> 
> In any case it seems to be already broken, so a fix or discussion doesn't
> need to block this series.

Sure; I think I'll save the AArch32 cleanup for a follow-up and go for a simple
change to jsut avoid making it worse in this patch.

Thanks,
Mark.


From broonie at kernel.org  Tue Jan 25 05:34:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 13:34:02 +0000
Subject: [PATCH v8 26/38] KVM: arm64: Handle SME host state when running
 guests
In-Reply-To: <87tuds6jbo.wl-maz@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-27-broonie@kernel.org>
 <87wnio6n7d.wl-maz@kernel.org> <Ye/ygvnlzPKYT2z6@sirena.org.uk>
 <87tuds6jbo.wl-maz@kernel.org>
Message-ID: <Ye/8SoZn2TJeShrl@sirena.org.uk>

On Tue, Jan 25, 2022 at 01:22:51PM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > > I find the use of CPACR_EL1_SMEN in some cases and its individual bits
> > > in some others pretty confusing. I understand that you have modelled
> > > it after the SVE code, but maybe this is a mistake we don't need to
> > > repeat. I'd be in favour of directly exposing the individual bits in
> > > all cases.

> > OK, it is just the KVM code that uses the plain ZEN.  I'll add a cleanup
> > patch for that at the start of the series for ZEN I guess otherwise it
> > looks worse, though that will inflate the size of the series a bit.

> I'm happy to merge such a patch early if that helps.

That'd be good.  There's also similar stuff going on with FPEN BTW
(which is I imagine where the SVE stuff came from).
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/78d6cbdc/attachment.sig>

From quic_saipraka at quicinc.com  Tue Jan 25 05:35:27 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Tue, 25 Jan 2022 19:05:27 +0530
Subject: [PATCHv9 2/5] irqchip/tegra: Fix overflow implicit truncation
 warnings
In-Reply-To: <8735lc88n9.wl-maz@kernel.org>
References: <cover.1642482334.git.quic_saipraka@quicinc.com>
 <2cd67f7eee96e062ea479b7406799f7a2daa5b1b.1642482334.git.quic_saipraka@quicinc.com>
 <8735lc88n9.wl-maz@kernel.org>
Message-ID: <dc36531d-0e03-94f3-3e77-0108fbe41e63@quicinc.com>

On 1/25/2022 3:00 PM, Marc Zyngier wrote:
> On Mon, 24 Jan 2022 06:33:31 +0000,
> Sai Prakash Ranjan <quic_saipraka at quicinc.com> wrote:
>> Fix -Woverflow warnings for tegra irqchip driver which is a result
>> of moving arm64 custom MMIO accessor macros to asm-generic function
>> implementations giving a bonus type-checking now and uncovering these
>> overflow warnings.
>>
>> drivers/irqchip/irq-tegra.c: In function ?tegra_ictlr_suspend?:
>> drivers/irqchip/irq-tegra.c:151:18: warning: large integer implicitly truncated to unsigned type [-Woverflow]
>>     writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
>>                    ^
>>
>> Cc: Marc Zyngier <maz at kernel.org>
>> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
>> Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
>> ---
>>   drivers/irqchip/irq-tegra.c | 10 +++++-----
>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c
>> index e1f771c72fc4..9e4e5b39c701 100644
>> --- a/drivers/irqchip/irq-tegra.c
>> +++ b/drivers/irqchip/irq-tegra.c
>> @@ -148,10 +148,10 @@ static int tegra_ictlr_suspend(void)
>>   		lic->cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
>>   
>>   		/* Disable COP interrupts */
>> -		writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
>> +		writel_relaxed(~0u, ictlr + ICTLR_COP_IER_CLR);
> Aside from the 'l' in writel really meaning 'long' (a historical
> artefact), it would probably be better to lift the ambiguity entirely
> and write this as GENMASK(31, 0), making it clear what is being set,
> no matter what the revision of the architecture is (this driver also
> works on 32bit machines).
>

Sure, I will make this change.

Thanks,
Sai


From anders.roxell at linaro.org  Tue Jan 25 05:41:48 2022
From: anders.roxell at linaro.org (Anders Roxell)
Date: Tue, 25 Jan 2022 14:41:48 +0100
Subject: [4.9 PATCH] ARM: 8800/1: use choice for kernel unwinders
Message-ID: <20220125134148.3390940-1-anders.roxell@linaro.org>

From: Stefan Agner <stefan at agner.ch>

commit f9b58e8c7d031b0daa5c9a9ee27f5a4028ba53ac upstream.

While in theory multiple unwinders could be compiled in, it does
not make sense in practise. Use a choice to make the unwinder
selection mutually exclusive and mandatory.

Already before this commit it has not been possible to deselect
FRAME_POINTER. Remove the obsolete comment.

Furthermore, to produce a meaningful backtrace with FRAME_POINTER
enabled the kernel needs a specific function prologue:
    mov    ip, sp
    stmfd    sp!, {fp, ip, lr, pc}
    sub    fp, ip, #4

To get to the required prologue gcc uses apcs and no-sched-prolog.
This compiler options are not available on clang, and clang is not
able to generate the required prologue. Make the FRAME_POINTER
config symbol depending on !clang.

Suggested-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Stefan Agner <stefan at agner.ch>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
---
 arch/arm/Kconfig.debug | 44 +++++++++++++++++++++++++++---------------
 lib/Kconfig.debug      |  6 +++---
 2 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 8349a171a8f3..e1d21c6449ea 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -15,30 +15,42 @@ config ARM_PTDUMP
 	  kernel.
 	  If in doubt, say "N"
 
-# RMK wants arm kernels compiled with frame pointers or stack unwinding.
-# If you know what you are doing and are willing to live without stack
-# traces, you can get a slightly smaller kernel by setting this option to
-# n, but then RMK will have to kill you ;).
-config FRAME_POINTER
-	bool
-	depends on !THUMB2_KERNEL
-	default y if !ARM_UNWIND || FUNCTION_GRAPH_TRACER
+choice
+	prompt "Choose kernel unwinder"
+	default UNWINDER_ARM if AEABI && !FUNCTION_GRAPH_TRACER
+	default UNWINDER_FRAME_POINTER if !AEABI || FUNCTION_GRAPH_TRACER
+	help
+	  This determines which method will be used for unwinding kernel stack
+	  traces for panics, oopses, bugs, warnings, perf, /proc/<pid>/stack,
+	  livepatch, lockdep, and more.
+
+config UNWINDER_FRAME_POINTER
+	bool "Frame pointer unwinder"
+	depends on !THUMB2_KERNEL && !CC_IS_CLANG
+	select ARCH_WANT_FRAME_POINTERS
+	select FRAME_POINTER
 	help
-	  If you say N here, the resulting kernel will be slightly smaller and
-	  faster. However, if neither FRAME_POINTER nor ARM_UNWIND are enabled,
-	  when a problem occurs with the kernel, the information that is
-	  reported is severely limited.
+	  This option enables the frame pointer unwinder for unwinding
+	  kernel stack traces.
 
-config ARM_UNWIND
-	bool "Enable stack unwinding support (EXPERIMENTAL)"
+config UNWINDER_ARM
+	bool "ARM EABI stack unwinder"
 	depends on AEABI
-	default y
+	select ARM_UNWIND
 	help
 	  This option enables stack unwinding support in the kernel
 	  using the information automatically generated by the
 	  compiler. The resulting kernel image is slightly bigger but
 	  the performance is not affected. Currently, this feature
-	  only works with EABI compilers. If unsure say Y.
+	  only works with EABI compilers.
+
+endchoice
+
+config ARM_UNWIND
+	bool
+
+config FRAME_POINTER
+	bool
 
 config OLD_MCOUNT
 	bool
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index bc5ff3a53d4a..e7addfcd302f 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1091,7 +1091,7 @@ config LOCKDEP
 	bool
 	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select STACKTRACE
-	select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !ARC && !SCORE
+	select FRAME_POINTER if !MIPS && !PPC && !ARM && !S390 && !MICROBLAZE && !ARC && !SCORE
 	select KALLSYMS
 	select KALLSYMS_ALL
 
@@ -1670,7 +1670,7 @@ config FAULT_INJECTION_STACKTRACE_FILTER
 	depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
 	depends on !X86_64
 	select STACKTRACE
-	select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC && !SCORE
+	select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC && !SCORE
 	help
 	  Provide stacktrace filter for fault-injection capabilities
 
@@ -1679,7 +1679,7 @@ config LATENCYTOP
 	depends on DEBUG_KERNEL
 	depends on STACKTRACE_SUPPORT
 	depends on PROC_FS
-	select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !ARC
+	select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC
 	select KALLSYMS
 	select KALLSYMS_ALL
 	select STACKTRACE
-- 
2.34.1



From madvenka at linux.microsoft.com  Tue Jan 25 05:43:51 2022
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Tue, 25 Jan 2022 07:43:51 -0600
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
 <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
Message-ID: <825b8b72-c746-ba24-7142-3fff481e82d6@linux.microsoft.com>

I have not seen any activity on that in a long time. IIRC, Julien quit RedHat.
I don't know if anyone else has taken over this work in RedHat.

Sorry, I don't have any more information.

Madhavan

On 1/24/22 23:21, nobuta.keiya at fujitsu.com wrote:
> Hi Madhavan,
> 
>> Select HAVE_RELIABLE_STACKTRACE in arm64/Kconfig to allow
>> arch_stack_walk_reliable() to be used.
>>
>> Note that this is conditional upon STACK_VALIDATION which will be added when frame pointer validation is implemented (say
>> via objtool).
> 
> I know that Julien Thierry published objtool support for arm64 [1], but I'm not
> sure if it has been updated. Could you tell me other threads if you know?
> 
> [1] https://lore.kernel.org/linux-arm-kernel/20210303170932.1838634-1-jthierry at redhat.com/
> 
> 
> Thanks,
> Keiya
> 
>>
>> Signed-off-by: Madhavan T. Venkataraman <madvenka at linux.microsoft.com>
>> ---
>>  arch/arm64/Kconfig | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f6e333b59314..bc7b3514b563 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -223,6 +223,7 @@ config ARM64
>>  	select THREAD_INFO_IN_TASK
>>  	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
>>  	select TRACE_IRQFLAGS_SUPPORT
>> +	select HAVE_RELIABLE_STACKTRACE if FRAME_POINTER && STACK_VALIDATION
>>  	help
>>  	  ARM 64-bit (AArch64) Linux support.
>>
>> --
>> 2.25.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From quic_schowdhu at quicinc.com  Tue Jan 25 05:44:45 2022
From: quic_schowdhu at quicinc.com (Souradeep Chowdhury)
Date: Tue, 25 Jan 2022 19:14:45 +0530
Subject: [PATCH V6 2/7] soc: qcom: dcc:Add driver support for Data Capture
 and Compare unit(DCC)
In-Reply-To: <c0f792f4-522e-f1fd-5b58-579389c2c48d@quicinc.com>
References: <cover.1628617260.git.schowdhu@codeaurora.org>
 <fc69469f26983d373d5ad7dc2dc83df207967eda.1628617260.git.schowdhu@codeaurora.org>
 <YbzvD+FFHuDWzCtZ@yoga> <caccb6da-2024-db4e-700c-9b4c13946ca0@quicinc.com>
 <YdeC456prDBG7tBA@ripper> <77a2ef02-384d-ce67-ae84-02c385eccd60@quicinc.com>
 <Ydhi1/SH5ySDLNfI@ripper> <c0f792f4-522e-f1fd-5b58-579389c2c48d@quicinc.com>
Message-ID: <66470ed1-8fc5-9f8d-02bb-efe02c882ab4@quicinc.com>


On 1/17/2022 11:19 AM, Souradeep Chowdhury wrote:
>
> On 1/7/2022 9:27 PM, Bjorn Andersson wrote:
>> On Fri 07 Jan 07:27 PST 2022, Souradeep Chowdhury wrote:
>>
>>> On 1/7/2022 5:31 AM, Bjorn Andersson wrote:
>>>> On Wed 05 Jan 23:57 PST 2022, Souradeep Chowdhury wrote:
>>>>
>>>>> On 12/18/2021 1:41 AM, Bjorn Andersson wrote:
>>>>>> On Tue 10 Aug 12:54 CDT 2021, Souradeep Chowdhury wrote:
>>>>>>
>>>>>>> The DCC is a DMA Engine designed to capture and store data
>>>>>>> during system crash or software triggers.The DCC operates
>>>>>> Please include a space after '.'
>>>>> Ack
>>>>>>> based on user inputs via the sysfs interface.The user gives
>>>>>>> addresses as inputs and these addresses are stored in the
>>>>>>> form of linkedlists.In case of a system crash or a manual
>>>>>> I think the user configures the DCC hardware with "a sequence of
>>>>>> operations to be performed as DCC is triggered".
>>>>>>
>>>>>> Afaict the sequence is stored just as a sequence of operations in 
>>>>>> SRAM,
>>>>>> there's no linked list involved - except in your intermediate
>>>>>> implementation.
>>>>> The user just enters the addresses as input whereas the sequence of
>>>>> operations takes
>>>>>
>>>>> place as per configuration code inside the driver. The end result 
>>>>> is storage
>>>>> of these
>>>>>
>>>>> addresses inside the DCC SRAM. The DCC hardware will capture the 
>>>>> value at
>>>>> these
>>>>>
>>>>> addresses on a crash or manual trigger by the user.
>>>>>
>>>>>>> software trigger by the user through the sysfs interface,
>>>>>>> the dcc captures and stores the values at these addresses.
>>>>>>> This patch contains the driver which has all the methods
>>>>>>> pertaining to the sysfs interface, auxiliary functions to
>>>>>>> support all the four fundamental operations of dcc namely
>>>>>>> read, write, first read then write and loop.The probe method
>>>>>> "first read then write" is called "read/modify/write"
>>>>> Ack
>>>>>>> here instantiates all the resources necessary for dcc to
>>>>>>> operate mainly the dedicated dcc sram where it stores the
>>>>>>> values.The DCC driver can be used for debugging purposes
>>>>>>> without going for a reboot since it can perform manual
>>>>>>> triggers.
>>>>>>>
>>>>>>> Also added the documentation for sysfs entries
>>>>>>> and explained the functionalities of each sysfs file that
>>>>>>> has been created for dcc.
>>>>>>>
>>>>>>> The following is the justification of using sysfs interface
>>>>>>> over the other alternatives like ioctls
>>>>>>>
>>>>>>> i) As can be seen from the sysfs attribute descriptions,
>>>>>>> most of it does basic hardware manipulations like dcc_enable,
>>>>>>> dcc_disable, config reset etc. As a result sysfs is preferred
>>>>>>> over ioctl as we just need to enter a 0 or 1.
>>>>>>>
>>>>>> As I mentioned in our chat, using sysfs allows us to operate the
>>>>>> interface using the shell without additional tools.
>>>>>>
>>>>>> But I don't think that it's easy to implement 
>>>>>> enable/disable/reset using
>>>>>> sysfs is a strong argument. The difficult part of this ABI is the
>>>>>> operations to manipulate the sequence of operations, so that's 
>>>>>> what you
>>>>>> need to have a solid plan for.
>>>>> The sysfs interface is being used to get the addresses values 
>>>>> entered by the
>>>>> user
>>>>>
>>>>> and to also go for manual triggers. The sequence of operations are 
>>>>> kept as a
>>>>> part of
>>>>>
>>>>> fixed driver code which is called when the user enters the data.
>>>>>
>>>> But does the hardware really just operate on "addresses values entered
>>>> by the user". Given the various types of operations: read, write,
>>>> read-modify-write and loop I get the feeling that the hardware
>>>> "executes" a series of actions.
>>>>
>>>> I'm don't think the proposed sysfs interface best exposes this to the
>>>> user and I don't think that "it's easy to implement enable/disable
>>>> attributes in sysfs" is reason enough to go with that approach.
>>> So the sysfs interface here has been introduced keeping in mind how the
>>> DCC_SRAM needs to be
>>>
>>> programmed for the dcc hardware to work. We are maintaining a list here
>>> based on the address
>>>
>>> entry. The 4 cases for the type of addresses are as follows-:
>>>
>>> i) READ ADDRESSES
>>>
>>> user enters something like "echo <addr> <len> > config"
>>>
>>> DCC driver stores the <addr> along with the length information in the
>>> DCC_SRAM.
>>>
>>> ii) WRITE ADDRESSES
>>>
>>> User enters something like "echo <addr> <write_val> 1? > config_write"
>>>
>>> DCC stores the <addr> first in sram followed by <write_val>.
>>>
>>> For the above 2 type of addresses there won't be much difference if 
>>> we use
>>> IOCTL.
>>>
>>> However, for the next 2 type of addresses
>>>
>>> iii) LOOP ADDRESSES
>>>
>>> user has to enter something like below
>>>
>>> echo 9 > loop
>>> echo 0x01741010 1 > config
>>> echo 0x01741014 1 > config
>>> echo 1 > loop
>>>
>>> The DCC SRAM will be programmed precisely like the above entries 
>>> where the
>>> loop count will be stored first
>>>
>>> followed by loop addresses and then again a "echo 1 > loop " marks 
>>> the end
>>> of loop addresses.
>>>
>>> in DCC_SRAM.
>>>
>>> iv) READ_WRITE ADDRESSES
>>>
>>> User has to enter something like below
>>>
>>> echo <addr> > /sys/bus/platform/devices/../config
>>>
>>> echo <mask> <val> > /sys/bus/platform/devices/../rd_mod_wr
>>>
>>> Here first the? <addr> is stored in DCC_SRAM followed by <mask> and 
>>> then the
>>> <val>.
>>>
>>> The above representation to the user space is consistent with the dcc
>>> hardware in terms of
>>>
>>> the way the sequence of values are programmed in the DCC SRAM . 
>>> Moving to
>>> IOCTL will
>>>
>>> only change the way the READ_WRITE address is represented although 
>>> user will
>>> have to enter
>>>
>>> multiple parameters at once, let me know if we still need to go for the
>>> same.
>>>
>> So if I understand correctly, my concern is that if I would like to
>> perform something like (in pseudo code):
>>
>> readl(X)
>> write(1, Y)
>> readl(Z) 5 times
>>
>> then I will do this as:
>>
>> echo X > config
>> echo Y 1 > config_write
>> echo 5 > loop
>> echo Z > config
>> echo 1 > loop
>>
>> And the DCC driver will then write this to SRAM as something like:
>>
>> read X
>> write Y, 1
>> loop 5
>> read Z
>> loop
>>
>>
>> In other words, my mind and the DCC has the same representation of this
>> sequence of operations, but I have to shuffle the information into 4
>> different sysfs attributes to get there.
>>
>> The design guideline for sysfs is that each attribute should hold one
>> value per attribute, but in your model the attributes are tangled and
>> writing things to them depends on what has been written in that or other
>> attributes previously.
>>
>> I simply don't think that's a good ABI.
>
> Ack.
>
> Should I change this to have separate sysfs files dealing with 
> separate type of instructions?
>
> For example I can have separate files like config_read, 
> config_write(already exists), config_loop
>
> and config_read_write to handle 4 different type of instructions with 
> inputs like
>
> echo <loop_offset> <loop_address_numbers> <loop_address_1> 
> <loop_address_2>.. > config_loop
>
> echo <address> <mask> <val> > config_read_write
>
> and so on

Hi Bjorn,


Further to this, since in case of sysfs , we cannot have multiple values 
for a single sysfs file,

handling loop instructions become? difficult.

So can I go for debugfs for the above implementation?

I can have separate debugfs files to handle config_loop , config_read, 
config_write, config_read_write

with inputs as follows

->? echo <read_address>? >? config_read

->? echo <write_address> <write_val>? > config_write

->? echo <loop_counter> <loop_address_number> <loop_address1> 
<loop_address2>..? >? config_loop

->? echo <read_write_address> <write_mask> <write_val>? >? config_read_write

Let me know your thoughts regarding this.


Thanks,

Souradeep


>
>>
>> [..]
>>>>>>> +??????? The address argument should
>>>>>>> +??????? be given of the form <mask> <value>.For debugging
>>>>>>> +??????? purposes sometimes we need to first read from a register
>>>>>>> +??????? and then set some values to the register.
>>>>>>> +??????? Example:
>>>>>>> +??????? echo 0x80000000 > /sys/bus/platform/devices/.../config
>>>>>>> +??????? (Set the address in config file)
>>>>>>> +??????? echo 0xF 0xA > /sys/bus/platform/devices/.../rd_mod_wr
>>>>>>> +??????? (Provide the mask and the value to write)
>>>>>>> +
>>>>>>> +What:?????????? /sys/bus/platform/devices/.../ready
>>>>>>> +Date:?????????? March 2021
>>>>>>> +Contact:??????? Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>>>>> +Description:
>>>>>>> +??????? This file is used to check the status of the dcc
>>>>>>> +??????? hardware if it's ready to take the inputs.
>>>>>> When will this read "false"?
>>>>> This will give false if the DCC hardware is not in an operational 
>>>>> state.
>>>>>
>>>>> Will update accordingly.
>>>>>
>>>>>>> +??????? Example:
>>>>>>> +??????? cat /sys/bus/platform/devices/.../ready
>>>>>>> +
>>>>>>> +What:??????? /sys/bus/platform/devices/.../curr_list
>>>>>>> +Date:??????? February 2021
>>>>>>> +Contact:??? Souradeep Chowdhury<schowdhu at codeaurora.org>
>>>>>>> +Description:
>>>>>>> +??????? This attribute is used to enter the linklist to be
>>>>>> I think it would be more appropriate to use the verb "select" 
>>>>>> here and
>>>>>> afaict it's a "list" as the "linked" part only relates to your
>>>>>> implementation).
>>>>>>
>>>>>> But that said, I don't like this ABI. I think it would be cleaner 
>>>>>> if you
>>>>>> had specific attributes for each of the lists. That way it would be
>>>>>> clear that you have N lists and they can be configured and enabled
>>>>>> independently, and there's no possible race conditions.
>>>>> So we do have attributes for independent lists in this case. The 
>>>>> user is
>>>>> given the option
>>>>>
>>>>> to configure multiple lists at one go. For example I can do
>>>>>
>>>>> echo 1 > curr_list
>>>>>
>>>>> echo 0x18000010 1 > config
>>>>> echo 0x18000024 1 > config
>>>>>
>>>>> Then followed by
>>>>>
>>>>> echo 2 > curr_list
>>>>>
>>>>> echo 0x18010038 6 > config
>>>>> echo 0x18020010 1 > config
>>>>>
>>>>> We will get the output in terms of two separate list of registers 
>>>>> values.
>>>>>
>>>> I understand that this will define two lists of operations and that we
>>>> will get 2 and 7 registers dumped, respectively. Perhaps unlikely, but
>>>> what happens if you try to do these two operations concurrently?
>>>>
>>>>
>>>> What I'm suggesting here is that if you have N contexts, you should 
>>>> have
>>>> N interfaces to modify each one independently - simply because that's
>>>> generally a very good thing.
>>> Not sure if there will ever be a concurrency issue in this case.
>>> This is just about programming the DCC SRAM from the user entries
>>> sequentially.
>> So you've decided that two such sequences must not happen at the same
>> time. (I know it's unlikely, but there's nothing preventing me from
>> running the two snippets of echos concurrently and the outcome will be
>> unexpected)
>
> So as per the dcc hardware configuration document, parallel 
> programming of lists are not
>
> supported for dcc. We program the lists sequentially one after the other.
>
>>
>>> The curr_list number is nothing but some register writes
>>> done in the dcc so that the dcc_hardware knows the beginning and end
>>> of a particular list and can dump the captured data according. Even if
>>> an user chooses multiple curr_list entries, it will be programmed
>>> sequentially in DCC_SRAM.
>>>
>> So there's no separation between the lists in the hardware?
>>
>> Looking at the driver I get a sense that we have N lists that can be
>> configured independently and will be run "independently" upon a trigger.
>>
>> If this isn't the case, what's the purpose of the multiple lists?
>
> Lists are programmed sequentially from the driver perspective.
>
> We have multiple lists in case of dcc because multiple software 
> components may be using
>
> dcc hardware at once in which case there are individual lists allotted 
> for each individual components.
>
> For example kernel might have a few lists to access whereas the rest 
> maybe used by SDI which is a
>
> separate component. Each list is of arbitrary length as entered by the 
> user and one list can be updated
>
> with it's base address after the previous list has been programmed in 
> DCC_SRAM like below :-
>
> ??????????????? ret = __dcc_ll_cfg(drvdata, list);
> ??????????????? if (ret) {
> ??????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
> ??????????????????????? goto err;
> ??????????????? }
>
> ??????????????? /* 3. program DCC_RAM_CFG reg */
> ??????????????? dcc_writel(drvdata, ram_cfg_base +
> ??????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
>
>
>>
>>>>>>> +??????? used while appending addresses.The range of values
>>>>>>> +??????? for this can be from 0 to 3.This feature is given in
>>>>>>> +??????? order to use certain linkedlist for certain debugging
>>>>>>> +??????? purposes.
>>>>>>> +??????? Example:
>>>>>>> +??????? echo 0 > /sys/bus/platform/devices/10a2000.dcc/curr_list
>>>>>>> +
>>>> [..]
>>>>>>> diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
>>>> [..]
>>>>>>> +static int dcc_valid_list(struct dcc_drvdata *drvdata, int 
>>>>>>> curr_list)
>>>>>>> +{
>>>>>>> +??? u32 lock_reg;
>>>>>>> +
>>>>>>> +??? if (list_empty(&drvdata->cfg_head[curr_list]))
>>>>>>> +??????? return -EINVAL;
>>>>>>> +
>>>>>>> +??? if (drvdata->enable[curr_list]) {
>>>>>>> +??????? dev_err(drvdata->dev, "List %d is already enabled\n",
>>>>>>> +??????????????? curr_list);
>>>>>>> +??????? return -EINVAL;
>>>>>>> +??? }
>>>>>>> +
>>>>>>> +??? lock_reg = dcc_readl(drvdata, DCC_LL_LOCK(curr_list));
>>>>>> Under what circumstances would this differ from
>>>>>> drvdata->enable[curr_list}?
>>>>> So locking the list is done on the register as soon as the user 
>>>>> enters the
>>>>> curr_list entry whereas
>>>>>
>>>>> the list is marked as enabled only on successfully programming the 
>>>>> SRAM
>>>>> contents. So a list can
>>>>>
>>>>> be locked and not marked enabled in certain cases. The first is 
>>>>> used so that
>>>>> the user doesn't
>>>>>
>>>>> mistakenly enter the same curr_list twice whereas the later is 
>>>>> used to mark
>>>>> that the list has been
>>>>>
>>>>> successfully configured.
>>>>>
>>>> So this will mark the list as "actively in use, but disabled"? Why is
>>>> this kept in the hardware? When is this not the same as the list of
>>>> operations for that list being non-empty?
>>> So this is in accordance with the dcc hardware configuration
>>> requirement. We have to lock the list first and after that proceed
>>> with the subsequent writes.
>> But what does this mean? What happens when I lock a list?
>>
>> Afacit we have a "lock" bit and an "enable" bit. So in what circumstance
>> does the hardware care about a list being locked? Wouldn't it be
>> sufficient to just have the enable bit?
>
> As explained above multiple software components might be using DCC 
> hardware for which lock bit is
>
> necessary. From only kernel perspective enable bit alone suffices for 
> the operation.
>
>>
>>> As per the driver code below
>>>
>>> ??????????????? /* 1. Take ownership of the list */
>>> ???????????????? dcc_writel(drvdata, BIT(0), DCC_LL_LOCK(list));
>>>
>>> ???????????????? /* 2. Program linked-list in the SRAM */
>>> ???????????????? ram_cfg_base = drvdata->ram_cfg;
>>> ???????????????? ret = __dcc_ll_cfg(drvdata, list);
>>> ???????????????? if (ret) {
>>> ???????????????????????? dcc_writel(drvdata, 0, DCC_LL_LOCK(list));
>>> ???????????????????????? goto err;
>>> ???????????????? }
>>>
>>> ???????????????? /* 3. program DCC_RAM_CFG reg */
>>> ???????????????? dcc_writel(drvdata, ram_cfg_base +
>>> ???????????????????????? drvdata->ram_offset/4, DCC_LL_BASE(list));
>>> ???????????????? dcc_writel(drvdata, drvdata->ram_start +
>>> ???????????????????????? drvdata->ram_offset/4, DCC_FD_BASE(list));
>>> ???????????????? dcc_writel(drvdata, 0xFFF, DCC_LL_TIMEOUT(list));
>>>
>>> ???????????????? /* 4. Clears interrupt status register */
>>> ???????????????? dcc_writel(drvdata, 0, DCC_LL_INT_ENABLE(list));
>>> ???????????????? dcc_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
>>> DCC_LL_INT_STATUS(list));
>>>
>>> In case of any errors we again unlock the list before exiting.
>>>
>> So it needs to be locked while SRAM contains a valid sequence of
>> operations?
>>
>> Or does it need to be locked while we write to SRAM? If so, why is that?
>
> So it needs to be locked while SRAM contains a valid sequence of 
> operations.
>
> The reason has been explained as above.
>
>> Regards,
>> Bjorn


From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:06 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:06 +0100
Subject: [PATCH 0/8] various imx6ul DT fixes
Message-ID: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>

This patch set fixes several, but not all, dt_binding_check warnings. Some are
missing properties or their format, others address issues regarding to
compatible names. I only touched those where compatibles are stated in the yaml
bindings.
There are several imx6ul compatible names used by imx6ul.dtsi, but which are
not listed in the bindings. Namely:
* "fsl,imx6ul-gpt", "fsl,imx6sx-gpt"
* "fsl,imx6ul-tempmon", "fsl,imx6sx-tempmon"
* "fsl,imx6ul-gpc", "fsl,imx6q-gpc"
* "fsl,imx6ul-usdhc", "fsl,imx6sx-usdhc"

Despite GPC, the others are apperently compatible to imx6sx. I'm not sure how
to fix the DTB check warning. Add the imx6ul compatible to bindings and drivers?
Or change the .dtsi to use only the imx6sx compatible.

The GPC on imx6ul apparently does only support power gating for ARM CPU, so
this would require actually a new compatible which supports only 1 domain.

Alexander Stein (8):
  ARM: dts: imx6ul: add missing properties for sram
  ARM: dts: imx6ul: change operating-points to uint32-matrix
  ARM: dts: imx6ul: fix keypad compatible
  ARM: dts: imx6ul: fix adc node compatible
  ARM: dts: imx6ul: remove unsupported adc property
  ARM: dts: imx6ul: fix csi node compatible
  ARM: dts: imx6ul: fix lcdif node compatible
  ARM: dts: imx6ul: fix qspi node compatible

 arch/arm/boot/dts/imx6ul.dtsi | 36 +++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:07 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:07 +0100
Subject: [PATCH 1/8] ARM: dts: imx6ul: add missing properties for sram
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-2-alexander.stein@ew.tq-group.com>

All 3 properties are required by sram.yaml. Fixes the dt_binding_check
warning:
sram at 900000: '#address-cells' is a required property
sram at 900000: '#size-cells' is a required property
sram at 900000: 'ranges' is a required property

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index afeec01f6522..1d435a46fc5c 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -149,6 +149,9 @@ soc {
 		ocram: sram at 900000 {
 			compatible = "mmio-sram";
 			reg = <0x00900000 0x20000>;
+			ranges = <0 0x00900000 0x20000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
 		};
 
 		intc: interrupt-controller at a01000 {
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:08 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:08 +0100
Subject: [PATCH 2/8] ARM: dts: imx6ul: change operating-points to uint32-matrix
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-3-alexander.stein@ew.tq-group.com>

operating-points is a uint32-matrix as per opp-v1.yaml. Change it
accordingly. While at it, change fsl,soc-operating-points as well,
although there is no bindings file (yet). But they should have the same
format. Fixes the dt_binding_check warning:
cpu at 0: operating-points:0: [696000, 1275000, 528000, 1175000, 396000,
1025000, 198000, 950000] is too long
cpu at 0: operating-points:0: Additional items are not allowed (528000,
1175000, 396000, 1025000, 198000, 950000 were unexpected)

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 22 ++++++++++------------
 1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 1d435a46fc5c..2fcbd9d91521 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -64,20 +64,18 @@ cpu0: cpu at 0 {
 			clock-frequency = <696000000>;
 			clock-latency = <61036>; /* two CLK32 periods */
 			#cooling-cells = <2>;
-			operating-points = <
+			operating-points =
 				/* kHz	uV */
-				696000	1275000
-				528000	1175000
-				396000	1025000
-				198000	950000
-			>;
-			fsl,soc-operating-points = <
+				<696000	1275000>,
+				<528000	1175000>,
+				<396000	1025000>,
+				<198000	950000>;
+			fsl,soc-operating-points =
 				/* KHz	uV */
-				696000	1275000
-				528000	1175000
-				396000	1175000
-				198000	1175000
-			>;
+				<696000	1275000>,
+				<528000	1175000>,
+				<396000	1175000>,
+				<198000	1175000>;
 			clocks = <&clks IMX6UL_CLK_ARM>,
 				 <&clks IMX6UL_CLK_PLL2_BUS>,
 				 <&clks IMX6UL_CLK_PLL2_PFD2>,
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:09 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:09 +0100
Subject: [PATCH 3/8] ARM: dts: imx6ul: fix keypad compatible
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-4-alexander.stein@ew.tq-group.com>

According to binding, the compatible shall only contain imx6ul and imx21
compatibles. Fixes the dt_binding_check warning:
keypad at 20b8000: compatible: 'oneOf' conditional failed, one must be fixed:
['fsl,imx6ul-kpp', 'fsl,imx6q-kpp', 'fsl,imx21-kpp'] is too long
Additional items are not allowed ('fsl,imx6q-kpp', 'fsl,imx21-kpp' were
unexpected)
Additional items are not allowed ('fsl,imx21-kpp' was unexpected)
'fsl,imx21-kpp' was expected

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 2fcbd9d91521..df8b4ad62418 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -544,7 +544,7 @@ fec2: ethernet at 20b4000 {
 			};
 
 			kpp: keypad at 20b8000 {
-				compatible = "fsl,imx6ul-kpp", "fsl,imx6q-kpp", "fsl,imx21-kpp";
+				compatible = "fsl,imx6ul-kpp", "fsl,imx21-kpp";
 				reg = <0x020b8000 0x4000>;
 				interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_KPP>;
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:10 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:10 +0100
Subject: [PATCH 4/8] ARM: dts: imx6ul: fix adc node compatible
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-5-alexander.stein@ew.tq-group.com>

fsl,imx6ul-adc is not listed in the binding, so remove it. Fixes the
dt_binding_check warning:
adc at 2198000: compatible:0: 'fsl,vf610-adc' was expected
adc at 2198000: compatible: ['fsl,imx6ul-adc', 'fsl,vf610-adc'] is too long
adc at 2198000: compatible: Additional items are not allowed ('fsl,vf610-adc'
was unexpected)

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index df8b4ad62418..d6c2b0ad3eac 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -920,7 +920,7 @@ usdhc2: mmc at 2194000 {
 			};
 
 			adc1: adc at 2198000 {
-				compatible = "fsl,imx6ul-adc", "fsl,vf610-adc";
+				compatible = "fsl,vf610-adc";
 				reg = <0x02198000 0x4000>;
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_ADC1>;
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:11 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:11 +0100
Subject: [PATCH 5/8] ARM: dts: imx6ul: remove unsupported adc property
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-6-alexander.stein@ew.tq-group.com>

'num-channels' is not supported by binding, nor driver, remove it. Fixes
the dt_binding_check warning:
adc at 2198000: 'num-channels' does not match any of the regexes:
'pinctrl-[0-9]+'

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index d6c2b0ad3eac..8d7d6cfc2c38 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -924,7 +924,6 @@ adc1: adc at 2198000 {
 				reg = <0x02198000 0x4000>;
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_ADC1>;
-				num-channels = <2>;
 				clock-names = "adc";
 				fsl,adck-max-frequency = <30000000>, <40000000>,
 							 <20000000>;
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:12 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:12 +0100
Subject: [PATCH 6/8] ARM: dts: imx6ul: fix csi node compatible
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-7-alexander.stein@ew.tq-group.com>

"fsl,imx6ul-csi" was never listed as compatible to "fsl,imx7-csi", neither
in yaml bindings, nor previous txt binding. Remove the imx7 part. Fixes
the dt schema check warning:
csi at 21c4000: compatible: 'oneOf' conditional failed, one must be fixed:
['fsl,imx6ul-csi', 'fsl,imx7-csi'] is too long
Additional items are not allowed ('fsl,imx7-csi' was unexpected)
'fsl,imx8mm-csi' was expected

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 8d7d6cfc2c38..e75c2e164551 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -998,7 +998,7 @@ cpu_speed_grade: speed-grade at 10 {
 			};
 
 			csi: csi at 21c4000 {
-				compatible = "fsl,imx6ul-csi", "fsl,imx7-csi";
+				compatible = "fsl,imx6ul-csi";
 				reg = <0x021c4000 0x4000>;
 				interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_CSI>;
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:13 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:13 +0100
Subject: [PATCH 7/8] ARM: dts: imx6ul: fix lcdif node compatible
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-8-alexander.stein@ew.tq-group.com>

In yaml binding "fsl,imx6ul-lcdif" is listed as compatible to imx6sx-lcdif,
but not imx28-lcdif. Change the list accordingly. Fixes the
dt_binding_check warning:
lcdif at 21c8000: compatible: 'oneOf' conditional failed, one must be fixed:
['fsl,imx6ul-lcdif', 'fsl,imx28-lcdif'] is too long
Additional items are not allowed ('fsl,imx28-lcdif' was unexpected)
'fsl,imx6ul-lcdif' is not one of ['fsl,imx23-lcdif', 'fsl,imx28-lcdif',
'fsl,imx6sx-lcdif']
'fsl,imx6sx-lcdif' was expected

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index e75c2e164551..4d19ba7cb342 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -1007,7 +1007,7 @@ csi: csi at 21c4000 {
 			};
 
 			lcdif: lcdif at 21c8000 {
-				compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
+				compatible = "fsl,imx6ul-lcdif", "fsl,imx6sx-lcdif";
 				reg = <0x021c8000 0x4000>;
 				interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&clks IMX6UL_CLK_LCDIF_PIX>,
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Tue Jan 25 05:50:14 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Tue, 25 Jan 2022 14:50:14 +0100
Subject: [PATCH 8/8] ARM: dts: imx6ul: fix qspi node compatible
In-Reply-To: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
References: <20220125135014.3041002-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220125135014.3041002-9-alexander.stein@ew.tq-group.com>

imx6ul is not compatible to imx6sx, both have different erratas.
Fixes the dt_binding_check warning:
spi at 21e0000: compatible: 'oneOf' conditional failed, one must be fixed:
['fsl,imx6ul-qspi', 'fsl,imx6sx-qspi'] is too long
Additional items are not allowed ('fsl,imx6sx-qspi' was unexpected)
'fsl,imx6ul-qspi' is not one of ['fsl,ls1043a-qspi']
'fsl,imx6ul-qspi' is not one of ['fsl,imx8mq-qspi']
'fsl,ls1021a-qspi' was expected
'fsl,imx7d-qspi' was expected

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm/boot/dts/imx6ul.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 4d19ba7cb342..36be13bf1439 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -1028,7 +1028,7 @@ pxp: pxp at 21cc000 {
 			qspi: spi at 21e0000 {
 				#address-cells = <1>;
 				#size-cells = <0>;
-				compatible = "fsl,imx6ul-qspi", "fsl,imx6sx-qspi";
+				compatible = "fsl,imx6ul-qspi";
 				reg = <0x021e0000 0x4000>, <0x60000000 0x10000000>;
 				reg-names = "QuadSPI", "QuadSPI-memory";
 				interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From broonie at kernel.org  Tue Jan 25 05:54:36 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 13:54:36 +0000
Subject: [PATCH v3 0/3] Add FSD SPI support
In-Reply-To: <20220125031604.76009-1-alim.akhtar@samsung.com>
References: <CGME20220125032811epcas5p3ef7b2f4e4906c1da8ccb4a0b3ed9a591@epcas5p3.samsung.com>
 <20220125031604.76009-1-alim.akhtar@samsung.com>
Message-ID: <YfABHDjdTgxytcUY@sirena.org.uk>

On Tue, Jan 25, 2022 at 08:46:01AM +0530, Alim Akhtar wrote:

> Note: This series is depended on [1] patches which adds
> support of FSD SoC and on Krzysztof's v6 [2] of spi schema changes
> 
> [1] https://lkml.org/lkml/2022/1/24/583
> [2] https://lkml.org/lkml/2022/1/24/120

Please resend this when it can be applied, either wait until the
dependencies are in place or rebase on top of current code.  In general
only build time dependencies matter here, the SoC support being merged
shouldn't be an issue one way or another.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/97e2ae70/attachment.sig>

From mark.rutland at arm.com  Tue Jan 25 06:00:56 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 14:00:56 +0000
Subject: [bootwrapper PATCH v2 12/13] Rework bootmethod initialization
In-Reply-To: <20220117174300.0a91fcf6@donnerap.cambridge.arm.com>
References: <20220114105653.3003399-1-mark.rutland@arm.com>
 <20220114105653.3003399-13-mark.rutland@arm.com>
 <20220117174300.0a91fcf6@donnerap.cambridge.arm.com>
Message-ID: <YfACmOnQXbmE3QIf@FVFF77S0Q05N>

On Mon, Jan 17, 2022 at 05:43:00PM +0000, Andre Przywara wrote:
> On Fri, 14 Jan 2022 10:56:52 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi Mark,
> 
> > We currently initialize the bootmethod late, in assembly code. This
> > requires us to maintain the el3/no_el3 distintion late into the boot
> > process, and means we cannot produce any helpful diagnostic when booted
> > at an unexpected exception level.
> > 
> > Rework things so that we initialize the bootmethod early, with a warning
> > when things are wrong. The el3/no_el3 distinction is now irrelevant to
> > the bootmethod code, and can be removed in subsequent patches.
> > 
> > When a boot-wrapper configured for PSCI is entered at EL2, a warning is
> > looged to the serial console as:
> > 
> > | Boot-wrapper v0.2
> > | Entered at EL2
> > | Memory layout:
> > | [0000000080000000..0000000080001f90] => boot-wrapper
> > | [000000008000fff8..0000000080010000] => mbox
> > | [0000000080200000..00000000822af200] => kernel
> > | [0000000088000000..0000000088002857] => dtb
> > |
> > | WARNING: PSCI could not be initialized. Boot may fail
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>

> > diff --git a/arch/aarch64/include/asm/psci.h b/arch/aarch64/include/asm/psci.h
> > new file mode 100644
> > index 0000000..491e685
> > --- /dev/null
> > +++ b/arch/aarch64/include/asm/psci.h
> > @@ -0,0 +1,28 @@
> > +/*
> > + * arch/aarch64/include/asm/psci.h
> > + *
> > + * Copyright (C) 2021 ARM Limited. All rights reserved.
> > + *
> > + * Use of this source code is governed by a BSD-style license that can be
> > + * found in the LICENSE.txt file.
> > + */
> > +#ifndef __ASM_AARCH64_PSCI_H
> > +#define __ASM_AARCH64_PSCI_H
> > +
> > +#include <cpu.h>
> > +#include <stdbool.h>
> > +
> > +extern char psci_vectors[];
> > +
> > +static inline bool cpu_init_psci_arch(void)
> > +{
> > +	if (mrs(CurrentEL) != CURRENTEL_EL3)
> > +		return false;
> > +
> > +	msr(VBAR_EL3, (unsigned long)psci_vectors);
> > +	isb();
> > +
> > +	return true;
> > +}
> > +
> > +#endif
> 
> Is there any particular reason that needs to live as a static inline in a
> header file? Can't we have the prototype in, say include/boot.h, and then
> have this in a proper C file, for instance arch/aarch<xx>/init.c?

At the time I originally wrote it, I had thought that this was the simplest
option, but you're right that it's cleaner to place this in the relevant init.c
file -- done. :)

Thanks,
Mark.


From anshuman.khandual at arm.com  Tue Jan 25 06:20:30 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:30 +0530
Subject: [PATCH V3 RESEND 0/7] coresight: trbe: Workaround Cortex-A510 erratas
Message-ID: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>

	This series adds three different workarounds in the TRBE driver for
Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
part number definition in the platform. This series applies on 5.17-rc1.

Relevant errata documents can be found here.

https://developer.arm.com/documentation/SDEN2397239/900
https://developer.arm.com/documentation/SDEN2397589/900

Changes in V3:

https://lore.kernel.org/all/1641872346-3270-1-git-send-email-anshuman.khandual at arm.com/

- Moved the comment inside trbe_needs_drain_after_disable()
- Moved the comment inside trbe_needs_ctxt_sync_after_enable()

Changes in V2:

https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/

Accommodated most review comments from the previous version.

- Split all patches into CPU errata definition, detection and TRBE workarounds
- s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
- s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
- s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
- s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
- Updated Kconfig help message for config ARM64_ERRATUM_1902691
- Updated error message for trbe_is_broken() detection
- Added new trblimitr parameter to set_trbe_enabled(), improving performance
- Added COMPILE_TEST dependency in the errata, until TRBE part is available

Changes in V1:

https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (7):
  arm64: Add Cortex-A510 CPU part definition
  arm64: errata: Add detection for TRBE ignored system register writes
  arm64: errata: Add detection for TRBE invalid prohibited states
  arm64: errata: Add detection for TRBE trace data corruption
  coresight: trbe: Work around the ignored system register writes
  coresight: trbe: Work around the invalid prohibited states
  coresight: trbe: Work around the trace data corruption

 Documentation/arm64/silicon-errata.rst       |   6 +
 arch/arm64/Kconfig                           |  59 ++++++++++
 arch/arm64/include/asm/cputype.h             |   2 +
 arch/arm64/kernel/cpu_errata.c               |  27 +++++
 arch/arm64/tools/cpucaps                     |   3 +
 drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
 drivers/hwtracing/coresight/coresight-trbe.h |   8 --
 7 files changed, 183 insertions(+), 36 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:31 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:31 +0530
Subject: [PATCH V3 RESEND 1/7] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-2-git-send-email-anshuman.khandual@arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:32 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:32 +0530
Subject: [PATCH V3 RESEND 2/7] arm64: errata: Add detection for TRBE ignored
 system register writes
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-3-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected. This adds a new errata ARM64_ERRATUM_2064142
in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..c9b30e6c2b6c 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -52,6 +52,8 @@ stable kernels.
 | Allwinner      | A64/R18         | UNKNOWN1        | SUN50I_ERRATUM_UNKNOWN1     |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..0033436e3416 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -778,6 +778,24 @@ config ARM64_ERRATUM_2224489
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2064142
+	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
+
+	  Affected Cortex-A510 core might fail to write into system registers after the
+	  TRBE has been disabled. Under some conditions after the TRBE has been disabled
+	  writes into TRBE registers TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1,
+	  and TRBTRG_EL1 will be ignored and will not be effected.
+
+	  Work around this in the driver by executing TSB CSYNC and DSB after collection
+	  is stopped and before performing a system register write to one of the affected
+	  registers.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..cbb7d5a9aee7 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2064142
+	{
+		.desc = "ARM erratum 2064142",
+		.capability = ARM64_WORKAROUND_2064142,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..fca3cb329e1d 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2064142
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:33 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:33 +0530
Subject: [PATCH V3 RESEND 3/7] arm64: errata: Add detection for TRBE invalid
 prohibited states
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-4-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted. This adds a new errata
ARM64_ERRATUM_2038923 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 23 +++++++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 35 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index c9b30e6c2b6c..e0ef3e9a4b8b 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2064142        | ARM64_ERRATUM_2064142       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 0033436e3416..fecf2b09e870 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -796,6 +796,29 @@ config ARM64_ERRATUM_2064142
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_2038923
+	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
+
+	  Affected Cortex-A510 core might cause an inconsistent view on whether trace is
+	  prohibited within the CPU. As a result, the trace buffer or trace buffer state
+	  might be corrupted. This happens after TRBE buffer has been enabled by setting
+	  TRBLIMITR_EL1.E, followed by just a single context synchronization event before
+	  execution changes from a context, in which trace is prohibited to one where it
+	  isn't, or vice versa. In these mentioned conditions, the view of whether trace
+	  is prohibited is inconsistent between parts of the CPU, and the trace buffer or
+	  the trace buffer state might be corrupted.
+
+	  Work around this in the driver by preventing an inconsistent view of whether the
+	  trace is prohibited or not based on TRBLIMITR_EL1.E by immediately following a
+	  change to TRBLIMITR_EL1.E with at least one ISB instruction before an ERET, or
+	  two ISB instructions if no ERET is to take place.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index cbb7d5a9aee7..60b0c1f1d912 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -607,6 +607,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_2038923
+	{
+		.desc = "ARM erratum 2038923",
+		.capability = ARM64_WORKAROUND_2038923,
+
+		/* Cortex-A510 r0p0 - r0p2 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
+	},
+#endif
 	{
 	}
 };
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index fca3cb329e1d..45a06d36d080 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -56,6 +56,7 @@ WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
+WORKAROUND_2038923
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:34 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:34 +0530
Subject: [PATCH V3 RESEND 4/7] arm64: errata: Add detection for TRBE trace
 data corruption
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-5-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. So effectively
TRBE is broken and hence cannot be used to capture trace data. This adds
a new errata ARM64_ERRATUM_1902691 in arm64 errata framework.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 18 ++++++++++++++++++
 arch/arm64/kernel/cpu_errata.c         |  9 +++++++++
 arch/arm64/tools/cpucaps               |  1 +
 4 files changed, 30 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index e0ef3e9a4b8b..50018f60c4d4 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -56,6 +56,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2038923        | ARM64_ERRATUM_2038923       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #1902691        | ARM64_ERRATUM_1902691       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #827319         | ARM64_ERRATUM_827319        |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index fecf2b09e870..9c3cf3875785 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -819,6 +819,24 @@ config ARM64_ERRATUM_2038923
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_1902691
+	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
+	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
+
+	  Affected Cortex-A510 core might cause trace data corruption, when being written
+	  into the memory. Effectively TRBE is broken and hence cannot be used to capture
+	  trace data.
+
+	  Work around this problem in the driver by just preventing TRBE initialization on
+	  affected cpus. The firmware must have disabled the access to TRBE for the kernel
+	  on such implementations. This will cover the kernel for any firmware that doesn't
+	  do this already.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 60b0c1f1d912..a3336dfb5a8a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -615,6 +615,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		/* Cortex-A510 r0p0 - r0p2 */
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2)
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1902691
+	{
+		.desc = "ARM erratum 1902691",
+		.capability = ARM64_WORKAROUND_1902691,
+
+		/* Cortex-A510 r0p0 - r0p1 */
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 1)
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 45a06d36d080..e7719e8f18de 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -57,6 +57,7 @@ WORKAROUND_1508412
 WORKAROUND_1542419
 WORKAROUND_2064142
 WORKAROUND_2038923
+WORKAROUND_1902691
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:35 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:35 +0530
Subject: [PATCH V3 RESEND 5/7] coresight: trbe: Work around the ignored system
 register writes
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-6-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2064142 might fail to write
into certain system registers after the TRBE has been disabled. Under some
conditions after TRBE has been disabled, writes into certain TRBE registers
TRBLIMITR_EL1, TRBPTR_EL1, TRBBASER_EL1, TRBSR_EL1 and TRBTRG_EL1 will be
ignored and not be effected.

Work around this problem in the TRBE driver by executing TSB CSYNC and DSB
just after the trace collection has stopped and before performing a system
register write to one of the affected registers. This just updates the TRBE
driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 54 ++++++++++++++------
 drivers/hwtracing/coresight/coresight-trbe.h |  8 ---
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 9c3cf3875785..823f7cb128dc 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -780,7 +780,7 @@ config ARM64_ERRATUM_2224489
 
 config ARM64_ERRATUM_2064142
 	bool "Cortex-A510: 2064142: workaround TRBE register writes while disabled"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2064142.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 276862c07e32..4ef944971d8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -91,10 +91,12 @@ struct trbe_buf {
  */
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
+#define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
+	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -167,6 +169,16 @@ static inline bool trbe_may_write_out_of_range(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_WORKAROUND_WRITE_OUT_OF_RANGE);
 }
 
+static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
+{
+	/*
+	 * Errata affected TRBE implementation will need TSB CSYNC and
+	 * DSB in order to prevent subsequent writes into certain TRBE
+	 * system registers from being ignored and not effected.
+	 */
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -174,30 +186,37 @@ static int trbe_alloc_node(struct perf_event *event)
 	return cpu_to_node(event->cpu);
 }
 
-static void trbe_drain_buffer(void)
+static inline void trbe_drain_buffer(void)
 {
 	tsb_csync();
 	dsb(nsh);
 }
 
-static void trbe_drain_and_disable_local(void)
+static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
-	trbe_drain_buffer();
-
 	/*
 	 * Disable the TRBE without clearing LIMITPTR which
 	 * might be required for fetching the buffer limits.
 	 */
 	trblimitr &= ~TRBLIMITR_ENABLE;
 	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	if (trbe_needs_drain_after_disable(cpudata))
+		trbe_drain_buffer();
 	isb();
 }
 
-static void trbe_reset_local(void)
+static void trbe_drain_and_disable_local(struct trbe_cpudata *cpudata)
 {
-	trbe_drain_and_disable_local();
+	trbe_drain_buffer();
+	set_trbe_disabled(cpudata);
+}
+
+static void trbe_reset_local(struct trbe_cpudata *cpudata)
+{
+	trbe_drain_and_disable_local(cpudata);
 	write_sysreg_s(0, SYS_TRBLIMITR_EL1);
 	write_sysreg_s(0, SYS_TRBPTR_EL1);
 	write_sysreg_s(0, SYS_TRBBASER_EL1);
@@ -234,7 +253,7 @@ static void trbe_stop_and_truncate_event(struct perf_output_handle *handle)
 	 * at event_stop(). So disable the TRBE here and leave
 	 * the update_buffer() to return a 0 size.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
 	perf_aux_output_end(handle, 0);
 	*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
@@ -579,8 +598,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	WARN_ON(buf->trbe_hw_base < buf->trbe_base);
 	WARN_ON(buf->trbe_write < buf->trbe_hw_base);
 	WARN_ON(buf->trbe_write >= buf->trbe_limit);
-	set_trbe_disabled();
-	isb();
+	set_trbe_disabled(buf->cpudata);
 	clr_trbe_status();
 	set_trbe_base_pointer(buf->trbe_hw_base);
 	set_trbe_write_pointer(buf->trbe_write);
@@ -775,7 +793,7 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev,
 	 * the TRBE here will ensure that no IRQ could be generated when the perf
 	 * handle gets freed in etm_event_stop().
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 
 	/* Check if there is a pending interrupt and handle it here */
 	status = read_sysreg_s(SYS_TRBSR_EL1);
@@ -986,7 +1004,7 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 	if (cpudata->mode != CS_MODE_PERF)
 		return -EINVAL;
 
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(cpudata);
 	buf->cpudata = NULL;
 	cpudata->buf = NULL;
 	cpudata->mode = CS_MODE_DISABLED;
@@ -1028,7 +1046,7 @@ static int trbe_handle_overflow(struct perf_output_handle *handle)
 		 * is able to detect this with a disconnected handle
 		 * (handle->event = NULL).
 		 */
-		trbe_drain_and_disable_local();
+		trbe_drain_and_disable_local(buf->cpudata);
 		*this_cpu_ptr(buf->cpudata->drvdata->handle) = NULL;
 		return -EINVAL;
 	}
@@ -1062,6 +1080,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 {
 	struct perf_output_handle **handle_ptr = dev;
 	struct perf_output_handle *handle = *handle_ptr;
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
 	enum trbe_fault_action act;
 	u64 status;
 	bool truncated = false;
@@ -1082,7 +1101,7 @@ static irqreturn_t arm_trbe_irq_handler(int irq, void *dev)
 	 * Ensure the trace is visible to the CPUs and
 	 * any external aborts have been resolved.
 	 */
-	trbe_drain_and_disable_local();
+	trbe_drain_and_disable_local(buf->cpudata);
 	clr_trbe_irq();
 	isb();
 
@@ -1167,8 +1186,9 @@ static const struct attribute_group *arm_trbe_groups[] = {
 static void arm_trbe_enable_cpu(void *info)
 {
 	struct trbe_drvdata *drvdata = info;
+	struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata);
 
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE);
 }
 
@@ -1276,7 +1296,7 @@ static void arm_trbe_remove_coresight_cpu(void *info)
 	struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu);
 
 	disable_percpu_irq(drvdata->irq);
-	trbe_reset_local();
+	trbe_reset_local(cpudata);
 	if (trbe_csdev) {
 		coresight_unregister(trbe_csdev);
 		cpudata->drvdata = NULL;
@@ -1349,8 +1369,10 @@ static int arm_trbe_cpu_teardown(unsigned int cpu, struct hlist_node *node)
 	struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node);
 
 	if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) {
+		struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu);
+
 		disable_percpu_irq(drvdata->irq);
-		trbe_reset_local();
+		trbe_reset_local(cpudata);
 	}
 	return 0;
 }
diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h
index abf3e36082f0..30e4d7db4f8e 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.h
+++ b/drivers/hwtracing/coresight/coresight-trbe.h
@@ -91,14 +91,6 @@ static inline bool is_trbe_running(u64 trbsr)
 #define TRBE_FILL_MODE_WRAP		1
 #define TRBE_FILL_MODE_CIRCULAR_BUFFER	3
 
-static inline void set_trbe_disabled(void)
-{
-	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
-
-	trblimitr &= ~TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-}
-
 static inline bool get_trbe_flag_update(u64 trbidr)
 {
 	return trbidr & TRBIDR_FLAG;
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:36 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:36 +0530
Subject: [PATCH V3 RESEND 6/7] coresight: trbe: Work around the invalid
 prohibited states
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-7-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #2038923 might get TRBE into
an inconsistent view on whether trace is prohibited within the CPU. As a
result, the trace buffer or trace buffer state might be corrupted. This
happens after TRBE buffer has been enabled by setting TRBLIMITR_EL1.E,
followed by just a single context synchronization event before execution
changes from a context, in which trace is prohibited to one where it isn't,
or vice versa. In these mentioned conditions, the view of whether trace is
prohibited is inconsistent between parts of the CPU, and the trace buffer
or the trace buffer state might be corrupted.

Work around this problem in the TRBE driver by preventing an inconsistent
view of whether the trace is prohibited or not based on TRBLIMITR_EL1.E by
immediately following a change to TRBLIMITR_EL1.E with at least one ISB
instruction before an ERET, or two ISB instructions if no ERET is to take
place. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 48 +++++++++++++++-----
 2 files changed, 37 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 823f7cb128dc..f37c9d2d697d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -798,7 +798,7 @@ config ARM64_ERRATUM_2064142
 
 config ARM64_ERRATUM_2038923
 	bool "Cortex-A510: 2038923: workaround TRBE corruption with enable"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 2038923.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 4ef944971d8e..6254ba598df2 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -92,11 +92,13 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_OVERWRITE_FILL_MODE	0
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
+#define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
+	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -179,6 +181,17 @@ static inline bool trbe_needs_drain_after_disable(struct trbe_cpudata *cpudata)
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_DRAIN_AFTER_DISABLE);
 }
 
+static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudata)
+{
+	/*
+	 * Errata affected TRBE implementation will need an additional
+	 * context synchronization in order to prevent an inconsistent
+	 * TRBE prohibited region view on the CPU which could possibly
+	 * corrupt the TRBE buffer or the TRBE state.
+	 */
+	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -192,6 +205,22 @@ static inline void trbe_drain_buffer(void)
 	dsb(nsh);
 }
 
+static inline void set_trbe_enabled(struct trbe_cpudata *cpudata, u64 trblimitr)
+{
+	/*
+	 * Enable the TRBE without clearing LIMITPTR which
+	 * might be required for fetching the buffer limits.
+	 */
+	trblimitr |= TRBLIMITR_ENABLE;
+	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
+
+	/* Synchronize the TRBE enable event */
+	isb();
+
+	if (trbe_needs_ctxt_sync_after_enable(cpudata))
+		isb();
+}
+
 static inline void set_trbe_disabled(struct trbe_cpudata *cpudata)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
@@ -555,9 +584,10 @@ static void clr_trbe_status(void)
 	write_sysreg_s(trbsr, SYS_TRBSR_EL1);
 }
 
-static void set_trbe_limit_pointer_enabled(unsigned long addr)
+static void set_trbe_limit_pointer_enabled(struct trbe_buf *buf)
 {
 	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	unsigned long addr = buf->trbe_limit;
 
 	WARN_ON(!IS_ALIGNED(addr, (1UL << TRBLIMITR_LIMIT_SHIFT)));
 	WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE));
@@ -585,12 +615,7 @@ static void set_trbe_limit_pointer_enabled(unsigned long addr)
 	trblimitr |= (TRBE_TRIG_MODE_IGNORE & TRBLIMITR_TRIG_MODE_MASK) <<
 		      TRBLIMITR_TRIG_MODE_SHIFT;
 	trblimitr |= (addr & PAGE_MASK);
-
-	trblimitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(trblimitr, SYS_TRBLIMITR_EL1);
-
-	/* Synchronize the TRBE enable event */
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static void trbe_enable_hw(struct trbe_buf *buf)
@@ -608,7 +633,7 @@ static void trbe_enable_hw(struct trbe_buf *buf)
 	 * till now before enabling the TRBE.
 	 */
 	isb();
-	set_trbe_limit_pointer_enabled(buf->trbe_limit);
+	set_trbe_limit_pointer_enabled(buf);
 }
 
 static enum trbe_fault_action trbe_get_fault_act(struct perf_output_handle *handle,
@@ -1013,16 +1038,15 @@ static int arm_trbe_disable(struct coresight_device *csdev)
 
 static void trbe_handle_spurious(struct perf_output_handle *handle)
 {
-	u64 limitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
+	struct trbe_buf *buf = etm_perf_sink_config(handle);
+	u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1);
 
 	/*
 	 * If the IRQ was spurious, simply re-enable the TRBE
 	 * back without modifying the buffer parameters to
 	 * retain the trace collected so far.
 	 */
-	limitr |= TRBLIMITR_ENABLE;
-	write_sysreg_s(limitr, SYS_TRBLIMITR_EL1);
-	isb();
+	set_trbe_enabled(buf->cpudata, trblimitr);
 }
 
 static int trbe_handle_overflow(struct perf_output_handle *handle)
-- 
2.25.1



From anshuman.khandual at arm.com  Tue Jan 25 06:20:37 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 19:50:37 +0530
Subject: [PATCH V3 RESEND 7/7] coresight: trbe: Work around the trace data
 corruption
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643120437-14352-8-git-send-email-anshuman.khandual@arm.com>

TRBE implementations affected by Arm erratum #1902691 might corrupt trace
data or deadlock, when it's being written into the memory. Workaround this
problem in the driver, by preventing TRBE initialization on affected cpus.
The firmware must have disabled the access to TRBE for the kernel on such
implementations. This will cover the kernel for any firmware that doesn't
do this already. This just updates the TRBE driver as required.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: coresight at lists.linaro.org
Cc: linux-doc at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/arm64/Kconfig                           |  2 +-
 drivers/hwtracing/coresight/coresight-trbe.c | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index f37c9d2d697d..ee0fe8a04b9b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -821,7 +821,7 @@ config ARM64_ERRATUM_2038923
 
 config ARM64_ERRATUM_1902691
 	bool "Cortex-A510: 1902691: workaround TRBE trace corruption"
-	depends on COMPILE_TEST # Until the CoreSight TRBE driver changes are in
+	depends on CORESIGHT_TRBE
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A510 erratum 1902691.
diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c
index 6254ba598df2..75b608bc400b 100644
--- a/drivers/hwtracing/coresight/coresight-trbe.c
+++ b/drivers/hwtracing/coresight/coresight-trbe.c
@@ -93,12 +93,14 @@ struct trbe_buf {
 #define TRBE_WORKAROUND_WRITE_OUT_OF_RANGE	1
 #define TRBE_NEEDS_DRAIN_AFTER_DISABLE		2
 #define TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE	3
+#define TRBE_IS_BROKEN				4
 
 static int trbe_errata_cpucaps[] = {
 	[TRBE_WORKAROUND_OVERWRITE_FILL_MODE] = ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE,
 	[TRBE_WORKAROUND_WRITE_OUT_OF_RANGE] = ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE,
 	[TRBE_NEEDS_DRAIN_AFTER_DISABLE] = ARM64_WORKAROUND_2064142,
 	[TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE] = ARM64_WORKAROUND_2038923,
+	[TRBE_IS_BROKEN] = ARM64_WORKAROUND_1902691,
 	-1,		/* Sentinel, must be the last entry */
 };
 
@@ -192,6 +194,11 @@ static inline bool trbe_needs_ctxt_sync_after_enable(struct trbe_cpudata *cpudat
 	return trbe_has_erratum(cpudata, TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE);
 }
 
+static inline bool trbe_is_broken(struct trbe_cpudata *cpudata)
+{
+	return trbe_has_erratum(cpudata, TRBE_IS_BROKEN);
+}
+
 static int trbe_alloc_node(struct perf_event *event)
 {
 	if (event->cpu == -1)
@@ -1288,6 +1295,11 @@ static void arm_trbe_probe_cpu(void *info)
 	 */
 	trbe_check_errata(cpudata);
 
+	if (trbe_is_broken(cpudata)) {
+		pr_err("Disabling TRBE on cpu%d due to erratum\n", cpu);
+		goto cpu_clear;
+	}
+
 	/*
 	 * If the TRBE is affected by erratum TRBE_WORKAROUND_OVERWRITE_FILL_MODE,
 	 * we must always program the TBRPTR_EL1, 256bytes from a page
-- 
2.25.1



From broonie at kernel.org  Tue Jan 25 06:25:38 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 14:25:38 +0000
Subject: [PATCH v8 25/38] KVM: arm64: Trap SME usage in guest
In-Reply-To: <87v8y86jdg.wl-maz@kernel.org>
References: <20220125001114.193425-1-broonie@kernel.org>
 <20220125001114.193425-26-broonie@kernel.org>
 <87y2346on8.wl-maz@kernel.org> <Ye/sS0jEXnBuumeG@sirena.org.uk>
 <87v8y86jdg.wl-maz@kernel.org>
Message-ID: <YfAIYp1m/zLKkmbd@sirena.org.uk>

On Tue, Jan 25, 2022 at 01:21:47PM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > OK, I'll remove the defensiveness here.  FGT is mandatory from v8.6 and
> > SME is a v9 feature so people shouldn't build a SME implementation that
> > lacks FGT.

> Can you then please make it that SME doesn't get enabled at all if FGT
> isn't present? It would also be good to have a clarification in the
> architecture that it isn't allowed to build SME without FGT (specially
> given that v9.0 is congruent to v8.5, and thus doesn't have FGT).

Right, this should be handled by the time the full spec is published -
it's an issue people are aware of and it's not something that should
ever get built.

It would be good to explicitly handle the dependency in the cpufeature
stuff, we'll have other issues like this, but I'd like to handle that
separately since at first look doing it properly is a bit of surgery on
cpufeature and the series is already rather large.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/6faa7f7c/attachment.sig>

From wanngchenng at gmail.com  Tue Jan 25 06:35:41 2022
From: wanngchenng at gmail.com (Wang Cheng)
Date: Tue, 25 Jan 2022 22:35:41 +0800
Subject: [BUG] drivers/perf: hisi: kernel fails to boot since commit
 ac4511c9364c "drivers/perf: hisi: Add identifier sysfs file"
Message-ID: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>

Hi respected kernel committers,

After upgrading from v5.10 to 5.17.0-rc1, my kernel fails to boot. By
bisectionally compiling and installing kernel a few times, the boot
problem first appears when upgrading from v5.10 to v5.11-rc1. Here are
boot messages of v5.11-rc1:
[2.126166] workingset: timestamp_bits=42 max_order=21 bucket_order=0
[2.127807] zbud: loaded
[2.128010] integrity: Platform Keyring initialized
[2.128014] Key type asymmetric registered
[2.128017] Asymmetric key parser 'x509' registered
[2.128026] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
[2.128092] io scheduler mq-deadline registered
[2.130976] pcieport 0000:00:01.0: can't derive routing for PCI INT A
[2.130982] pcieport 0000:00:01.0: PCI INT A: no GSI
[2.131272] pcieport 0000:00:01.0: can't derive routing for PCI INT A
[2.131276] pcieport 0000:00:01.0: PCI INT A: no GSI
[2.132188] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
[2.132192] ACPI: IORT: [Firmware Bug]: applying workaround.
[2.132259] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
[2.132263] ACPI: IORT: [Firmware Bug]: applying workaround.
[2.132285] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
[2.132850] efifb: probing for efifb
[2.132875] efifb: framebuffer at 0x80000000000, using 3072k, total 3072k
[2.132878] efifb: mode is 1024x768x32, linelength=4096, pages=1
[2.132881] efifb: scrolling: redraw
[2.132883] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
[2.135097] Console: switching to colour frame buffer device 128x48
[2.137221] fb0: EFI VGA frame buffer device
[2.137655] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
[2.137715] ACPI: Power Button [PWRB]
[2.138153] ACPI GTDT: found 1 SBSA generic Watchdog(s).
[2.140587] Serial: 8250/16550 deiver, 4 ports, IRQ sharing enabled
[2.141685] Serial: AMBA driver
[2.141828] msm_serial: driver initialized
[2.142785] mousedev: PS/2 mouse device common for all mice
[2.186108] rtc-efi rtc-efi.0: registered as rtc0
[2.198458] rtc-efi rtc-efi.0: setting system clock to 2022-01-23T13:49:49 UTC(1642945789)
[2.199157] ledtrig-cpu: registered to indicate activity on CPUs
_
Boot messages stop here. After about 2 seconds, the cpu fan runs in the
fastest mode all the time. I have to press the power button to turn the
machine off.

By bisectionally test, I found commit ac4511c9364c9a6390e8585cdd4596103bca16eb
"drivers/perf: hisi: Add identifier sysfs file" is suspect of resulting
the boot problem. If I revert this commit on v5.11-rc1, kernel boots
fine. That is:
$ git checkout v5.11-rc1
$ git revert ac4511c9364c9a6390e8585cdd4596103bca16eb
$ "compile and install kernel"
kernel boots fine.

I tested a bit more. I think hisi_uncore_ddrc_pmu.c or function
hisi_uncore_pmu_identifier_attr_show(...) is suspect in commit ac4511c9364c.
Commit ac4511c9364c modified 5 files:
	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.h
As I understand, a new function hisi_uncore_pmu_identifier_attr_show(...)
is declared and defined in hisi_uncore_pmu.h and hisi_uncore_pmu.c, the
new function is called in hisi_uncore_ddrc_pmu.c, hisi_uncore_hha_pmu.c
and hisi_uncore_l3c_pmu.c. I tested that, if I restore the change in
hisi_uncore_ddrc_pmu.c, kernel boots fine; if I restore the change in
hisi_uncore_hha_pmu.c and hisi_uncore_l3c_pmu.c, kernel fails to boot.
That is:
	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.h
compile and install, kernel boots fine.

	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.c
	drivers/perf/hisilicon/hisi_uncore_pmu.h
compile and install, kernel fails to boot.

$ sudo lshw
cpu version: HUAWEI Kunpeng 920 2251K
cores=8 enabledcores=8 threads=8
8Gib RAM
$ uname -a
Linux armdebian 5.10.0-9-arm64 #1 SMP Debian 5.10.70-1 (2021-09-30)
aarch64 GNU/Linux

Do I understand right? What else I could do to solve this?

Regards,

--
Cheng


From anshuman.khandual at arm.com  Tue Jan 25 06:38:33 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Tue, 25 Jan 2022 20:08:33 +0530
Subject: [PATCH] arm64/mm: Consolidate TCR_EL1 fields
Message-ID: <1643121513-21854-1-git-send-email-anshuman.khandual@arm.com>

This renames and moves SYS_TCR_EL1_TCMA1 and SYS_TCR_EL1_TCMA0 definitions
into pgtable-hwdef.h thus consolidating all TCR fields in a single header.
This does not cause any functional change.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
This applies on v5.17-rc1

This was earlier posted with FEAT_LPA2 series.

https://lore.kernel.org/all/1632998116-11552-3-git-send-email-anshuman.khandual at arm.com/

 arch/arm64/include/asm/pgtable-hwdef.h | 2 ++
 arch/arm64/include/asm/sysreg.h        | 4 ----
 arch/arm64/mm/proc.S                   | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
index 40085e53f573..66671ff05183 100644
--- a/arch/arm64/include/asm/pgtable-hwdef.h
+++ b/arch/arm64/include/asm/pgtable-hwdef.h
@@ -273,6 +273,8 @@
 #define TCR_NFD1		(UL(1) << 54)
 #define TCR_E0PD0		(UL(1) << 55)
 #define TCR_E0PD1		(UL(1) << 56)
+#define TCR_TCMA0		(UL(1) << 57)
+#define TCR_TCMA1		(UL(1) << 58)
 
 /*
  * TTBR.
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..34800d264f69 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1101,10 +1101,6 @@
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 #define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
 
-/* TCR EL1 Bit Definitions */
-#define SYS_TCR_EL1_TCMA1	(BIT(58))
-#define SYS_TCR_EL1_TCMA0	(BIT(57))
-
 /* GCR_EL1 Definitions */
 #define SYS_GCR_EL1_RRND	(BIT(16))
 #define SYS_GCR_EL1_EXCL_MASK	0xffffUL
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index d35c90d2e47a..50bbed947bec 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -46,7 +46,7 @@
 #endif
 
 #ifdef CONFIG_KASAN_HW_TAGS
-#define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1
+#define TCR_MTE_FLAGS TCR_TCMA1 | TCR_TBI1 | TCR_TBID1
 #else
 /*
  * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on
-- 
2.20.1



From ceggers at arri.de  Tue Jan 25 06:44:35 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:44:35 +0100
Subject: [PATCH RESEND 0/6] clk: imx6*: avoid GPMI clock glitches on
 reparenting/divider change
Message-ID: <20220125144441.17750-1-ceggers@arri.de>

RESEND because the series got corrupted on first tranmission

On the i.MX6 series (but not on i.MX7/8), most clock multiplexers and
switchable dividers are not "glitch safe", so switching them while a
consumer is connected can cause glitches with a higher frequency than
supported by the consuming peripheral.

Without fixes, peripherals can fail occasionally. One example is
that system boot fails due to lockup of the GPMI NAND controller:

f53d4c109a66 ("mtd: rawnand: gpmi: Add ERR007117 protection for nfc_apply_timings")

The conditions where this can appear also depend on the device
from which the system is booted and whether the bootloader has already
performed all reparenting of the clocks.

To avoid these problems, the clock subsystem must:
 - Gate consumer clocks during reparenting
 - Enforce that all consumer clocks are gated before client drivers can change the divider




From ceggers at arri.de  Tue Jan 25 06:44:36 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:44:36 +0100
Subject: [PATCH RESEND 1/6] clk: imx6ul: disable gpmi_io clock before changing
 parent clock
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144441.17750-2-ceggers@arri.de>

gpmi_io clock may have been enabled by the boot loader. All children of
enfc_clk_root must be gated in order to prevent glitches during parent
change.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6ul.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index 520b100bff4b..f599ae50dd9f 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -514,6 +514,15 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	else if (clk_on_imx6ull())
 		clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk);
 
+	/*
+	 * gpmi_io clock may have been enabled by the boot loader. All children of
+	 * enfc_clk_root must be gated in order to prevent glitches during parent
+	 * change. The task of re-enabling is left to the gpmi-nand driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6UL_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6UL_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6UL_CLK_GPMI_IO]->clk);
+	}
 	clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
 }
 
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 06:44:37 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:44:37 +0100
Subject: [PATCH RESEND 2/6] clk: imx6ul: enforce gating of gpmi_io clock
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144441.17750-3-ceggers@arri.de>

Clock parent and divider changes are both glitchy for enfc_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6ul.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index f599ae50dd9f..5443b5a0dc75 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -256,7 +256,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	if (clk_on_imx6ull())
 		hws[IMX6ULL_CLK_ESAI_SEL]	  = imx_clk_hw_mux("esai_sel",	base + 0x20, 19, 2, esai_sels, ARRAY_SIZE(esai_sels));
 	hws[IMX6UL_CLK_UART_SEL]	  = imx_clk_hw_mux("uart_sel",	base + 0x24, 6,  1, uart_sels, ARRAY_SIZE(uart_sels));
-	hws[IMX6UL_CLK_ENFC_SEL]	  = imx_clk_hw_mux("enfc_sel",	base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels));
+	hws[IMX6UL_CLK_ENFC_SEL]	  = imx_clk_hw_mux_flags("enfc_sel",	base + 0x2c, 15, 3, enfc_sels, ARRAY_SIZE(enfc_sels), CLK_SET_PARENT_GATE);
 	hws[IMX6UL_CLK_LDB_DI0_SEL]	  = imx_clk_hw_mux("ldb_di0_sel",	base + 0x2c, 9,  3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels));
 	hws[IMX6UL_CLK_SPDIF_SEL]	  = imx_clk_hw_mux("spdif_sel",	base + 0x30, 20, 2, spdif_sels, ARRAY_SIZE(spdif_sels));
 	if (clk_on_imx6ul()) {
@@ -424,7 +424,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
 	hws[IMX6UL_CLK_PWM4]		= imx_clk_hw_gate2("pwm4",		"perclk",	base + 0x78,	22);
 	hws[IMX6UL_CLK_GPMI_BCH_APB]	= imx_clk_hw_gate2("gpmi_bch_apb",	"bch_podf",	base + 0x78,	24);
 	hws[IMX6UL_CLK_GPMI_BCH]	= imx_clk_hw_gate2("gpmi_bch",	"gpmi_podf",	base + 0x78,	26);
-	hws[IMX6UL_CLK_GPMI_IO]	= imx_clk_hw_gate2("gpmi_io",	"enfc_podf",	base + 0x78,	28);
+	hws[IMX6UL_CLK_GPMI_IO]	= imx_clk_hw_gate2_flags("gpmi_io",	"enfc_podf",	base + 0x78,	28, CLK_SET_RATE_GATE);
 	hws[IMX6UL_CLK_GPMI_APB]	= imx_clk_hw_gate2("gpmi_apb",	"bch_podf",	base + 0x78,	30);
 
 	/* CCGR5 */
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 06:44:38 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:44:38 +0100
Subject: [PATCH RESEND 3/6] clk: imx6q: disable gpmi_io and ipt_io clocks
 before changing parent
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144441.17750-4-ceggers@arri.de>

gpmi_io and ipt_io clocks may have been enabled by the boot loader. All
children of enfc_clk_root must be gated in order to prevent glitches
during parent change.

Reparenting of enfc_clk_root may disable pll3_usb_otg. In order to avoid
immediately re-enabling it in imx_register_uart_clocks(), the whole
section has been moved to the bottom of imx6q_clocks_init().

Signed-off-by: Christian Eggers <ceggers at arri.de>
Co-developed-by: Stefan Riedmueller <S.Riedmueller at phytec.de>
Signed-off-by: Stefan Riedmueller <S.Riedmueller at phytec.de>
---
 drivers/clk/imx/clk-imx6q.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index de36f58d551c..fd5c37095ed0 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -927,13 +927,6 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI0_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI0_PRE]->clk);
 	clk_set_parent(hws[IMX6QDL_CLK_IPU2_DI1_SEL]->clk, hws[IMX6QDL_CLK_IPU2_DI1_PRE]->clk);
 
-	/*
-	 * The gpmi needs 100MHz frequency in the EDO/Sync mode,
-	 * We can not get the 100MHz from the pll2_pfd0_352m.
-	 * So choose pll2_pfd2_396m as enfc_sel's parent.
-	 */
-	clk_set_parent(hws[IMX6QDL_CLK_ENFC_SEL]->clk, hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk);
-
 	if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
 		clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY1_GATE]->clk);
 		clk_prepare_enable(hws[IMX6QDL_CLK_USBPHY2_GATE]->clk);
@@ -975,5 +968,25 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	}
 
 	imx_register_uart_clocks(2);
+
+	/*
+	 * The gpmi needs 100MHz frequency in the EDO/Sync mode. We can not get
+	 * the 100MHz from the pll2_pfd0_352m. So choose pll2_pfd2_396m as
+	 * enfc_sel's parent.
+	 *
+	 * gpmi_io and ipt_clk_io clocks may have been enabled by the boot
+	 * loader. All children of enfc_clk_root must be gated in order to
+	 * prevent glitches during parent change. The task of re-enabling
+	 * gpio_io is left to the gpmi-nand driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6QDL_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6QDL_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6QDL_CLK_GPMI_IO]->clk);
+	}
+	if (clk_hw_is_enabled(hws[IMX6QDL_CLK_ENFC])) {
+		clk_prepare_enable(hws[IMX6QDL_CLK_ENFC]->clk);
+		clk_disable_unprepare(hws[IMX6QDL_CLK_ENFC]->clk);
+	}
+	clk_set_parent(hws[IMX6QDL_CLK_ENFC_SEL]->clk, hws[IMX6QDL_CLK_PLL2_PFD2_396M]->clk);
 }
 CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 06:44:39 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:44:39 +0100
Subject: [PATCH RESEND 4/6] clk: imx6q: enforce gating of gpmi_io clock
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144441.17750-5-ceggers@arri.de>

Clock parent and divider changes are both glitchy for enfc_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6q.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index fd5c37095ed0..390566fca054 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -674,7 +674,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 		hws[IMX6QDL_CLK_USDHC2_SEL]       = imx_clk_hw_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
 		hws[IMX6QDL_CLK_USDHC3_SEL]       = imx_clk_hw_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
 		hws[IMX6QDL_CLK_USDHC4_SEL]       = imx_clk_hw_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels,        ARRAY_SIZE(usdhc_sels));
-		hws[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_hw_mux("enfc_sel",         base + 0x2c, 15, 3, enfc_sels_2,         ARRAY_SIZE(enfc_sels_2));
+		hws[IMX6QDL_CLK_ENFC_SEL]         = imx_clk_hw_mux_flags("enfc_sel",         base + 0x2c, 15, 3, enfc_sels_2,         ARRAY_SIZE(enfc_sels_2), CLK_SET_PARENT_GATE);
 		hws[IMX6QDL_CLK_EIM_SEL]          = imx_clk_hw_mux("eim_sel",      base + 0x1c, 27, 2, eim_sels,        ARRAY_SIZE(eim_sels));
 		hws[IMX6QDL_CLK_EIM_SLOW_SEL]     = imx_clk_hw_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels,   ARRAY_SIZE(eim_slow_sels));
 		hws[IMX6QDL_CLK_PRE_AXI]	  = imx_clk_hw_mux("pre_axi",	base + 0x18, 1,  1, pre_axi_sels,    ARRAY_SIZE(pre_axi_sels));
@@ -864,7 +864,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
 	hws[IMX6QDL_CLK_PWM4]         = imx_clk_hw_gate2("pwm4",          "ipg_per",           base + 0x78, 22);
 	hws[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
 	hws[IMX6QDL_CLK_GPMI_BCH]     = imx_clk_hw_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	hws[IMX6QDL_CLK_GPMI_IO]      = imx_clk_hw_gate2("gpmi_io",       "enfc",              base + 0x78, 28);
+	hws[IMX6QDL_CLK_GPMI_IO]      = imx_clk_hw_gate2_flags("gpmi_io",       "enfc",              base + 0x78, 28, CLK_SET_RATE_GATE);
 	hws[IMX6QDL_CLK_GPMI_APB]     = imx_clk_hw_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
 	hws[IMX6QDL_CLK_ROM]          = imx_clk_hw_gate2_flags("rom",     "ahb",               base + 0x7c, 0, CLK_IS_CRITICAL);
 	hws[IMX6QDL_CLK_SATA]         = imx_clk_hw_gate2("sata",          "ahb",               base + 0x7c, 4);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From linux at roeck-us.net  Tue Jan 25 06:46:28 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Tue, 25 Jan 2022 06:46:28 -0800
Subject: [PATCH linux dev-5.15] hwmon: (pmbus) modify PSU fan_target
 convert value to false
In-Reply-To: <20220125130116.18646-1-krishnar@ami.com>
References: <20220125130116.18646-1-krishnar@ami.com>
Message-ID: <4e7ca9d8-c545-160a-5578-cf1438223759@roeck-us.net>

On 1/25/22 05:01, krishnar4 wrote:
> Description: PSU can't use sysfs fan_target to control PSU fan duty.
> 

This is neither a proper subject nor a proper description.
"modify PSU fan_target convert value to false" means that the
value reported from the attribute is used directly without
conversion. The subject should reflect this.
"Description:" should not be part of the description, and
the description should describe the reason for the change
(ie explain clearly what is wrong).
"PSU can't use sysfs fan_target to control PSU fan duty"
doesn't explain anything and doesn't match the subject.

> Signed-off-by: krishnar4 <krishnar at ami.com>

"krishnar4" is not an acceptable name. This needs to be a real name.

Guenter

> ---
>   drivers/hwmon/pmbus/pmbus_core.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
> index 776ee2237be2..a56c2e1c4079 100644
> --- a/drivers/hwmon/pmbus/pmbus_core.c
> +++ b/drivers/hwmon/pmbus/pmbus_core.c
> @@ -1889,7 +1889,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
>   
>   	sensor = pmbus_add_sensor(data, "fan", "target", index, page,
>   				  0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
> -				  false, false, true);
> +				  false, false, false);
>   
>   	if (!sensor)
>   		return -ENOMEM;



From ceggers at arri.de  Tue Jan 25 06:47:35 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:47:35 +0100
Subject: [PATCH RESEND 5/6] clk: imx6sx: disable gpmi_io clock before changing
 parent clock
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144735.18091-1-ceggers@arri.de>

gpmi_io clocks may have been enabled by the boot loader. All children of
qspi2_clk_root must be gated in order to prevent glitches during parent
change.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6sx.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index fc1bd23d4583..cf1c1fad45f9 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -546,8 +546,19 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	clk_set_parent(hws[IMX6SX_CLK_GPU_AXI_SEL]->clk, hws[IMX6SX_CLK_PLL3_PFD0]->clk);
 
 	clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
-	clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
 
 	imx_register_uart_clocks(2);
+
+	/*
+	 * gpmi_io clock may have been enabled by the boot loader. All children
+	 * of qspi2_clk_root must be gated in order to prevent glitches during
+	 * parent change. The task of re-enabling is left to the gpmi-nand
+	 * driver.
+	 */
+	if (clk_hw_is_enabled(hws[IMX6SX_CLK_GPMI_IO])) {
+		clk_prepare_enable(hws[IMX6SX_CLK_GPMI_IO]->clk);
+		clk_disable_unprepare(hws[IMX6SX_CLK_GPMI_IO]->clk);
+	}
+	clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
 }
 CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From ceggers at arri.de  Tue Jan 25 06:48:01 2022
From: ceggers at arri.de (Christian Eggers)
Date: Tue, 25 Jan 2022 15:48:01 +0100
Subject: [PATCH RESEND 6/6] clk: imx6sx: enforce gating of gpmi_io clock
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125144801.18158-1-ceggers@arri.de>

Clock parent and divider changes are both glitchy for qspi2_clock_root.
Enforce that the child clock is gated.

Signed-off-by: Christian Eggers <ceggers at arri.de>
---
 drivers/clk/imx/clk-imx6sx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c
index cf1c1fad45f9..023a18594ebe 100644
--- a/drivers/clk/imx/clk-imx6sx.c
+++ b/drivers/clk/imx/clk-imx6sx.c
@@ -286,7 +286,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	hws[IMX6SX_CLK_ESAI_SEL]           = imx_clk_hw_mux("esai_sel",         base + 0x20,  19,     2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_CAN_SEL]            = imx_clk_hw_mux("can_sel",          base + 0x20,  8,      2,      can_sels,          ARRAY_SIZE(can_sels));
 	hws[IMX6SX_CLK_UART_SEL]           = imx_clk_hw_mux("uart_sel",         base + 0x24,  6,      1,      uart_sels,         ARRAY_SIZE(uart_sels));
-	hws[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT);
+	hws[IMX6SX_CLK_QSPI2_SEL]          = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
 	hws[IMX6SX_CLK_SPDIF_SEL]          = imx_clk_hw_mux("spdif_sel",        base + 0x30,  20,     2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_AUDIO_SEL]          = imx_clk_hw_mux("audio_sel",        base + 0x30,  7,      2,      audio_sels,        ARRAY_SIZE(audio_sels));
 	hws[IMX6SX_CLK_ENET_PRE_SEL]       = imx_clk_hw_mux("enet_pre_sel",     base + 0x34,  15,     3,      enet_pre_sels,     ARRAY_SIZE(enet_pre_sels));
@@ -441,7 +441,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
 	hws[IMX6SX_CLK_PWM4]         = imx_clk_hw_gate2("pwm4",          "perclk",            base + 0x78, 22);
 	hws[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_hw_gate2("gpmi_bch_apb",  "usdhc3",            base + 0x78, 24);
 	hws[IMX6SX_CLK_GPMI_BCH]     = imx_clk_hw_gate2("gpmi_bch",      "usdhc4",            base + 0x78, 26);
-	hws[IMX6SX_CLK_GPMI_IO]      = imx_clk_hw_gate2("gpmi_io",       "qspi2_podf",        base + 0x78, 28);
+	hws[IMX6SX_CLK_GPMI_IO]      = imx_clk_hw_gate2_flags("gpmi_io",       "qspi2_podf",        base + 0x78, 28, CLK_SET_RATE_GATE);
 	hws[IMX6SX_CLK_GPMI_APB]     = imx_clk_hw_gate2("gpmi_apb",      "usdhc3",            base + 0x78, 30);
 
 	/* CCGR5 */
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler



From john.garry at huawei.com  Tue Jan 25 06:48:40 2022
From: john.garry at huawei.com (John Garry)
Date: Tue, 25 Jan 2022 14:48:40 +0000
Subject: [BUG] drivers/perf: hisi: kernel fails to boot since commit
 ac4511c9364c "drivers/perf: hisi: Add identifier sysfs file"
In-Reply-To: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
References: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
Message-ID: <be7554e5-8051-6003-c11b-d7f418f0fb04@huawei.com>

On 25/01/2022 14:35, Wang Cheng wrote:

We had a similar report some time ago:

https://lore.kernel.org/linux-arm-kernel/ada98c97-1e06-5f71-0487-638f679eebf7 at hisilicon.com/

Seems to be a BIOS issue. Shaokun?

Thanks,
John


> Hi respected kernel committers,
> 
> After upgrading from v5.10 to 5.17.0-rc1, my kernel fails to boot. By
> bisectionally compiling and installing kernel a few times, the boot
> problem first appears when upgrading from v5.10 to v5.11-rc1. Here are
> boot messages of v5.11-rc1:
> [2.126166] workingset: timestamp_bits=42 max_order=21 bucket_order=0
> [2.127807] zbud: loaded
> [2.128010] integrity: Platform Keyring initialized
> [2.128014] Key type asymmetric registered
> [2.128017] Asymmetric key parser 'x509' registered
> [2.128026] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
> [2.128092] io scheduler mq-deadline registered
> [2.130976] pcieport 0000:00:01.0: can't derive routing for PCI INT A
> [2.130982] pcieport 0000:00:01.0: PCI INT A: no GSI
> [2.131272] pcieport 0000:00:01.0: can't derive routing for PCI INT A
> [2.131276] pcieport 0000:00:01.0: PCI INT A: no GSI
> [2.132188] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
> [2.132192] ACPI: IORT: [Firmware Bug]: applying workaround.
> [2.132259] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
> [2.132263] ACPI: IORT: [Firmware Bug]: applying workaround.
> [2.132285] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
> [2.132850] efifb: probing for efifb
> [2.132875] efifb: framebuffer at 0x80000000000, using 3072k, total 3072k
> [2.132878] efifb: mode is 1024x768x32, linelength=4096, pages=1
> [2.132881] efifb: scrolling: redraw
> [2.132883] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
> [2.135097] Console: switching to colour frame buffer device 128x48
> [2.137221] fb0: EFI VGA frame buffer device
> [2.137655] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
> [2.137715] ACPI: Power Button [PWRB]
> [2.138153] ACPI GTDT: found 1 SBSA generic Watchdog(s).
> [2.140587] Serial: 8250/16550 deiver, 4 ports, IRQ sharing enabled
> [2.141685] Serial: AMBA driver
> [2.141828] msm_serial: driver initialized
> [2.142785] mousedev: PS/2 mouse device common for all mice
> [2.186108] rtc-efi rtc-efi.0: registered as rtc0
> [2.198458] rtc-efi rtc-efi.0: setting system clock to 2022-01-23T13:49:49 UTC(1642945789)
> [2.199157] ledtrig-cpu: registered to indicate activity on CPUs
> _.
> Boot messages stop here. After about 2 seconds, the cpu fan runs in the
> fastest mode all the time. I have to press the power button to turn the
> machine off.
> 
> By bisectionally test, I found commit ac4511c9364c9a6390e8585cdd4596103bca16eb
> "drivers/perf: hisi: Add identifier sysfs file" is suspect of resulting
> the boot problem. If I revert this commit on v5.11-rc1, kernel boots
> fine. That is:
> $ git checkout v5.11-rc1
> $ git revert ac4511c9364c9a6390e8585cdd4596103bca16eb
> $ "compile and install kernel"
> kernel boots fine.
> 
> I tested a bit more. I think hisi_uncore_ddrc_pmu.c or function
> hisi_uncore_pmu_identifier_attr_show(...) is suspect in commit ac4511c9364c.
> Commit ac4511c9364c modified 5 files:
> 	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> As I understand, a new function hisi_uncore_pmu_identifier_attr_show(...)
> is declared and defined in hisi_uncore_pmu.h and hisi_uncore_pmu.c, the
> new function is called in hisi_uncore_ddrc_pmu.c, hisi_uncore_hha_pmu.c
> and hisi_uncore_l3c_pmu.c. I tested that, if I restore the change in
> hisi_uncore_ddrc_pmu.c, kernel boots fine; if I restore the change in
> hisi_uncore_hha_pmu.c and hisi_uncore_l3c_pmu.c, kernel fails to boot.
> That is:
> 	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> compile and install, kernel boots fine.
> 
> 	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> compile and install, kernel fails to boot.
> 
> $ sudo lshw
> cpu version: HUAWEI Kunpeng 920 2251K
> cores=8 enabledcores=8 threads=8
> 8Gib RAM
> $ uname -a
> Linux armdebian 5.10.0-9-arm64 #1 SMP Debian 5.10.70-1 (2021-09-30)
> aarch64 GNU/Linux
> 
> Do I understand right? What else I could do to solve this?
> 
> Regards,
> 
> --
> Cheng
> .
> 



From narmstrong at baylibre.com  Tue Jan 25 06:54:34 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 25 Jan 2022 15:54:34 +0100
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <20220121074508.42168-1-liang.yang@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
Message-ID: <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>

Hi Liang,

On 21/01/2022 08:45, Liang Yang wrote:
> This driver will add a MMC clock controller driver support.
> The original idea about adding a clock controller is during the
> discussion in the NAND driver mainline effort[1].
> 
> This driver is tested in the S400 board (AXG platform) with NAND driver.

Thanks a lot for providing a fixed and updated version of this serie.

After some chat with Jerome and Kevin, it seems the way the eMMC clock reuse
for NAND was designed nearly 4 years doesn't look accurate anymore.

Having a separate clk driver designed to replace the eMMC node when NAND is
used on the board seems over engineered.

Actually having the clock code you add in this serie _but_ directly in
the NAND looks far better, and more coherent since having Linux runtime
detection of eMMC vs NAND will never happen and even this serie required
some DT modification from the bootloader.

I'll let Jerome or Kevin add more details if they want, but I think you should resurrect
the work you pushed in [1] & [2] but:
- passing the eMMC clk registers as a third "reg" cell
- passing the same "clocks" phandle as the eMMC node
- adding the eMMC clock code in the NAND driver directly

I'm open to discussions if you consider the current approach is still superior.

Thanks,
Neil

[1] https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
[2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com

> 
> Changes since v9 [10]
>  - use clk_parent_data instead of parent_names
> 
> Changes since v8 [9]
>  - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>  - use struct_size to caculate onecell_data
>  - add clk-phase-delay.h
>  - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
> 
> Changes since v7 [8]
>  - move meson_clk_get_phase_delay_data() from header to driver
>  - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>  - remove onecell date and ID for internal MUX clk
>  - use helper for functions for ONE_BASED in sclk-div
>  - add ONE_BASED support for duty cycle
> 
> Changes since v6 [7]:
>  - add one based support for sclk divier
>  - alloc sclk in probe for multiple instance
>  - fix coding styles
> 
> Changes since v5 [6]:
>  - remove divider ops with .init and use sclk_div instead
>  - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>  - drop the useless type cast 
> 
> Changes since v4 [5]:
>  - use struct parm in phase delay driver
>  - remove 0 delay releted part in phase delay driver
>  - don't rebuild the parent name once again
>  - add divider ops with .init
> 
> Changes since v3 [4]:
>  - separate clk-phase-delay driver
>  - replace clk_get_rate() with clk_hw_get_rate()
>  - collect Rob's R-Y
>  - drop 'meson-' prefix from compatible string
> 
>  Changes since v2 [3]:
>  - squash dt-binding clock-id patch
>  - update license
>  - fix alignment
>  - construct a clk register helper() function
> 
> Changes since v1 [2]:
>  - implement phase clock
>  - update compatible name
>  - adjust file name
>  - divider probe() into small functions, and re-use them
> 
> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
> Liang Yang (4):
>   clk: meson: add one based divider support for sclk
>   clk: meson: add emmc sub clock phase delay driver
>   clk: meson: add DT documentation for emmc clock controller
>   clk: meson: add sub MMC clock controller driver
> 
>  .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>  drivers/clk/meson/Kconfig                     |  18 ++
>  drivers/clk/meson/Makefile                    |   2 +
>  drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>  drivers/clk/meson/clk-phase-delay.h           |  20 ++
>  drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>  drivers/clk/meson/sclk-div.c                  |  59 ++--
>  drivers/clk/meson/sclk-div.h                  |   3 +
>  include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>  9 files changed, 529 insertions(+), 22 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>  create mode 100644 drivers/clk/meson/clk-phase-delay.c
>  create mode 100644 drivers/clk/meson/clk-phase-delay.h
>  create mode 100644 drivers/clk/meson/mmc-clkc.c
>  create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
> 



From michael at walle.cc  Tue Jan 25 06:59:07 2022
From: michael at walle.cc (Michael Walle)
Date: Tue, 25 Jan 2022 15:59:07 +0100
Subject: [PATCH 6/8] nvmem: transformations: ethernet address offset
 support
In-Reply-To: <455f4360-34fe-7fee-66d5-fd945fe1e086@gmail.com>
References: <20211228142549.1275412-1-michael@walle.cc>
 <20211228142549.1275412-7-michael@walle.cc>
 <455f4360-34fe-7fee-66d5-fd945fe1e086@gmail.com>
Message-ID: <19d7206a42c7616d45733e44c9e52878@walle.cc>

Hi,

Am 2022-01-25 13:08, schrieb Rafa? Mi?ecki:
> On 28.12.2021 15:25, Michael Walle wrote:
>> An nvmem cell might just contain a base MAC address. To generate a
>> address of a specific interface, add a transformation to add an offset
>> to this base address.
>> 
>> Add a generic implementation and the first user of it, namely the sl28
>> vpd storage.
>> 
>> Signed-off-by: Michael Walle <michael at walle.cc>
>> ---
>>   drivers/nvmem/transformations.c | 45 
>> +++++++++++++++++++++++++++++++++
>>   1 file changed, 45 insertions(+)
>> 
>> diff --git a/drivers/nvmem/transformations.c 
>> b/drivers/nvmem/transformations.c
>> index 61642a9feefb..15cd26da1f83 100644
>> --- a/drivers/nvmem/transformations.c
>> +++ b/drivers/nvmem/transformations.c
>> @@ -12,7 +12,52 @@ struct nvmem_transformations {
>>   	nvmem_cell_post_process_t pp;
>>   };
>>   +/**
>> + * nvmem_transform_mac_address_offset() - Add an offset to a mac 
>> address cell
>> + *
>> + * A simple transformation which treats the index argument as an 
>> offset and add
>> + * it to a mac address. This is useful, if the nvmem cell stores a 
>> base
>> + * ethernet address.
>> + *
>> + * @index: nvmem cell index
>> + * @data: nvmem data
>> + * @bytes: length of the data
>> + *
>> + * Return: 0 or negative error code on failure.
>> + */
>> +static int nvmem_transform_mac_address_offset(int index, unsigned int 
>> offset,
>> +					      void *data, size_t bytes)
>> +{
>> +	if (bytes != ETH_ALEN)
>> +		return -EINVAL;
>> +
>> +	if (index < 0)
>> +		return -EINVAL;
>> +
>> +	if (!is_valid_ether_addr(data))
>> +		return -EINVAL;
>> +
>> +	eth_addr_add(data, index);
>> +
>> +	return 0;
>> +}
>> +
>> +static int nvmem_kontron_sl28_vpd_pp(void *priv, const char *id, int 
>> index,
>> +				     unsigned int offset, void *data,
>> +				     size_t bytes)
>> +{
>> +	if (!id)
>> +		return 0;
>> +
>> +	if (!strcmp(id, "mac-address"))
>> +		return nvmem_transform_mac_address_offset(index, offset, data,
>> +							  bytes);
>> +
>> +	return 0;
>> +}
>> +
>>   static const struct nvmem_transformations nvmem_transformations[] = 
>> {
>> +	{ .compatible = "kontron,sl28-vpd", .pp = nvmem_kontron_sl28_vpd_pp 
>> },
>>   	{}
>>   };
> 
> I think it's a rather bad solution that won't scale well at all.
> 
> You'll end up with a lot of NVMEM device specific strings and code in a
> NVMEM core.

They must not be in the core, but they have to be somewhere. That is
because Rob isn't fond of describing the actual transformation in
the device tree but to have it a specific compatible [1]. Thus you have
to have these strings somewhere in the driver code.

> You'll have a lot of duplicated code (many device specific functions
> calling e.g. nvmem_transform_mac_address_offset()).

If there will be multiple formats using the same transformation for
different compatible strings, you could just use the same function
for all compatibles.

But we have to first agree on the device tree representation because
that is then fixed. The driver code can change over time.

> I think it also ignores fact that one NVMEM device can be reused in
> multiple platforms / device models using different (e.g. vendor / 
> device
> specific) cells.
> 
> 
> What if we have:
> 1. Foo company using "kontron,sl28-vpd" with NVMEM cells:
>    a. "mac-address"
>    b. "mac-address-2"
>    c. "mac-address-3"
> 2. Bar company using "kontron,sl28-vpd" with NVMEM cell:
>    a. "mac-address"
> 
> In the first case you don't want any transformation.

I can't follow you here. The "kontron,sl28-vpd" specifies one
particular format, namely, that there is a base address
rather than individual ones.

> If you consider using transformations for ASCII formats too then it
> causes another conflict issue. Consider two devices:
> 
> 1. Foo company device with BIN format of MAC
> 2. Bar company device with ASCII format of MAC
> 
> Both may use exactly the same binding:
> 
> partition at 0 {
>         compatible = "nvmem-cells";
>         reg = <0x0 0x100000>;
>         label = "bootloader";
> 
>         #address-cells = <1>;
>         #size-cells = <1>;
> 
>         mac-address at 100 {
>                 reg = <0x100 0x6>;
>         };
> };
> 
> how are you going to handle them with proposed implementation? You 
> can't
> support both if you share "nvmem-cells" compatible string.

No, you'd need two different compatible strings. Again, that all boils
down to what the device tree should describe and what not.

But if you have the u-boot environment as an nvmem provider, you already
know that the mac address is in ascii representation and you'd need
to transform it to the kernel representation.

> I think that what can solve those problems is assing "compatible" to
> NVMEM cells.
> 
> Let me think about details of that possible solution.

See [2].

-michael

[1] 
https://lore.kernel.org/linux-devicetree/YaZ5JNCFeKcdIfu8 at robh.at.kernel.org/
[2] 
https://lore.kernel.org/linux-devicetree/CAL_JsqL55mZJ6jUyQACer2pKMNDV08-FgwBREsJVgitnuF18Cg at mail.gmail.com/


From mark.rutland at arm.com  Tue Jan 25 07:00:42 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:42 +0000
Subject: [bootwrapper PATCH v3 00/15] Cleanups and improvements
Message-ID: <20220125150057.3936090-1-mark.rutland@arm.com>

This series reworks the aarch64 boot-wrapper, moving a fair amount of
initialization code to C. This has a few benefits:

1) This makes the code more legible and easier to maintain.

    Current feature detection and system register configuration is
    written in assembly, requiring runs of *almost* identical blocks of
    assembly to read ID registers and conditionally initialize register
    values. This requires a bunch of labels (which are all named
    numerically), and all the magic numbers are hard coded, so this gets
    pretty painful to read:
    
    |	mrs	x1, id_aa64isar0_el1
    |	ubfx	x1, x1, #24, #4
    |	cbz	x1, 1f
    |
    |	orr	x0, x0, #(1 << 34)		// TME enable
    |
    | 1:
    
    In C, it's much easier to add helpers which use mnemonics, which
    makes the code much easier to read, and avoids the need to manually
    allocate registers, etc:
    
    |	if (mrs_field(ID_AA64ISAR0_EL1, TME))
    |		scr |= SCR_EL3_TME;

    This should make it easier to handle new architectural extensions
    (and/or architecture variants such as ARMv8-R) in future.
    
2) This allows for better diagnostics.

    Currently a mis-configured boot-wrapper is rather unforgiving, and
    provides no indication as to what might have gone wrong. By moving
    initialization to C, we can make use to the UART code to log
    diagnostic information, and we can more easily add additional error
    handling and conditional logic.
    
    This series adds diagnostic information and error handling that can
    be used to identify problems such as the boot-wrapper being launched
    at the wrong exception level:
    
    | Boot-wrapper v0.2
    | Entered at EL2
    | Memory layout:
    | [0000000080000000..0000000080001f90] => boot-wrapper
    | [000000008000fff8..0000000080010000] => mbox
    | [0000000080200000..00000000822af200] => kernel
    | [0000000088000000..0000000088002857] => dtb
    |
    | WARNING: PSCI could not be initialized. Boot may fail

Originally I had planned for this to be a more expansive set of changes,
unifying some early control-flow, fixing some latent bugs, and making
the boot-wrapper dynamically handle being entered at any of EL{3,2,1}
with automated selection of a suitable DT. As the series has already
become pretty long, I'd like to get this preparatory cleanup out of the
way first, and handle those cases with subsequent patches.

If there are no objections I'll apply this by the end of this week. 

I've pushed the series to the `cleanup` branch in the boot-wrapper repo:

  https://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git/
  git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

... and it should apply cleanup atop the `master` branch.

Since v1 [1]:
* Add comments for bit-field macros
* Use BIT() for *_RES1 definitions
* Complete start_el3/start_no_el3 cleanup
* Remove extraneous macro definition

Since v2 [2]:
* Accumulate tags
* Rebase atop other recent patches
* Correct ZCR_EL3.LEN initialization
* Drop BITS_INSERT()
* Split SCTLR_EL1 values used for AArch32 kernels
* Add missing SCTLR_EL1 RES1 bits
* Refactor print_ulong_hex()
* Refactor PSCI arch initialization

[1] https://lore.kernel.org/r/20220111130653.2331827-1-mark.rutland at arm.com/
[2] https://lore.kernel.org/r/20220114105653.3003399-1-mark.rutland at arm.com/
Thanks,
Mark.

Mark Rutland (15):
  aarch64: correct ZCR_EL3.LEN initialization
  aarch64: correct SCTLR_EL1_KERNEL for AA32 kernels
  Document entry requirements
  Add bit-field macros
  aarch64: add system register accessors
  aarch32: add coprocessor accessors
  aarch64: add mov_64 macro
  aarch64: initialize SCTLR_ELx for the boot-wrapper
  Rework common init C code
  Announce boot-wrapper mode / exception level
  aarch64: move the bulk of EL3 initialization to C
  aarch32: move the bulk of Secure PL1 initialization to C
  Announce locations of memory objects
  Rework bootmethod initialization
  Unify start_el3 & start_no_el3

 Makefile.am                       |   7 +-
 arch/aarch32/boot.S               |  33 ++++--
 arch/aarch32/include/asm/cpu.h    |  62 ++++++++---
 arch/aarch32/include/asm/gic-v3.h |   6 +-
 arch/aarch32/init.c               |  57 ++++++++++
 arch/aarch32/psci.S               |  16 +--
 arch/aarch32/utils.S              |   9 --
 arch/aarch64/boot.S               | 177 ++++++++++++------------------
 arch/aarch64/common.S             |  10 +-
 arch/aarch64/include/asm/cpu.h    | 117 +++++++++++++++++---
 arch/aarch64/include/asm/gic-v3.h |  10 +-
 arch/aarch64/init.c               | 106 ++++++++++++++++++
 arch/aarch64/psci.S               |  22 +---
 arch/aarch64/spin.S               |   6 +-
 arch/aarch64/utils.S              |   9 --
 common/boot.c                     |   4 -
 common/init.c                     |  60 ++++++++++
 common/platform.c                 |  45 +++++---
 common/psci.c                     |  20 +++-
 include/bits.h                    |  66 +++++++++++
 include/boot.h                    |   7 ++
 include/platform.h                |  20 ++++
 model.lds.S                       |  20 +++-
 23 files changed, 648 insertions(+), 241 deletions(-)
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/init.c
 create mode 100644 common/init.c
 create mode 100644 include/bits.h
 create mode 100644 include/platform.h

-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:43 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:43 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-2-mark.rutland@arm.com>

The ZCR_ELx.LEN field covers bits[3:0] of ZCR_ELx, and bits[8:4] are
RAZ/WI, likely so that in future these can be used to extend LEN without
complicating the probing of the maximum available vector length.

Currently ZCR_EL3_LEN_MASK is defined as 0x1ff, covering both the LEN
field and the RAZ/WI bits.

To match the architecture as documented, reduce this down to 0xf, only
covering the bits currently allocated to the LEN field. We can extend
this in future if the LEN field is widened.

As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
used as a value rather than as a bit mask.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Andre Przywara <andre.przywara at arm.com>
Cc: Mark Brown <broonie at kernel.org>
---
 arch/aarch64/boot.S            | 2 +-
 arch/aarch64/include/asm/cpu.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 72c6b79..ee9ddaa 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -123,7 +123,7 @@ ASM_FUNC(_start)
 	msr	cptr_el3, x0
 	isb
 
-	mov	x0, #ZCR_EL3_LEN_MASK		// SVE: Enable full vector len
+	mov	x0, #ZCR_EL3_LEN_MAX		// SVE: Enable full vector len
 	msr	ZCR_EL3, x0			// for EL2.
 
 1:
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 63eb1c3..e3269b8 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -30,7 +30,7 @@
 #define CPTR_EL3_EZ		(1 << 8)
 
 #define ZCR_EL3			s3_6_c1_c2_0
-#define ZCR_EL3_LEN_MASK	0x1ff
+#define ZCR_EL3_LEN_MAX		0xf
 
 #define SCTLR_EL1_CP15BEN	(1 << 5)
 #define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:44 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:44 +0000
Subject: [bootwrapper PATCH v3 02/15] aarch64: correct SCTLR_EL1_KERNEL for
 AA32 kernels
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-3-mark.rutland@arm.com>

Bits [31:0] of the AArch64 SCTLR_EL1 register are architecturally mapped
to bits [31:0] of the AArch32 SCTLR register. This means that any
individual bit always has the same value across the two registers.

Across the two registers, the same bit may have distinct meanings,
distinct RESx behaviour, and distinct reset behaviour. For example,
SCTLR_EL1[28] is nTLSMD, which we wich to initialize to 0b1, whereas
SCTLR[28] is TRE, which we wish to initialize to 0b0.

To avoid setting bits which we did not intend to, and in preparation for
configuring more AArch64 RES1 bits, this patch decouples the
SCTLR_EL1_KERNEL value used for AArch32 kernels from the SCTLR_EL1_RES1
definitions such that is does not inherit AArch64 SCTLR_EL1 bits which
would be problematic in the AArch32 SCTLR. For now we open-code a copy
of the bits defined in arch/aarch64/include/asm/cpu.h.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Cc: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch64/include/asm/cpu.h | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index e3269b8..49d3f86 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -36,8 +36,15 @@
 #define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
 
 #ifdef KERNEL_32
-/* 32-bit kernel decompressor uses CP15 barriers */
-#define SCTLR_EL1_KERNEL	(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
+/*
+ * When booting a 32-bit kernel, EL1 uses AArch32 and registers which are
+ * architecturally mapped must be configured with the AArch32 layout.
+ *
+ * We copy the AArch32 definition of SCTLR_KERNEL here.
+ *
+ * TODO: restructure the headers to share a single definition.
+ */
+#define SCTLR_EL1_KERNEL	(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
 #define SPSR_KERNEL		(SPSR_A | SPSR_I | SPSR_F | SPSR_HYP)
 #else
 #define SCTLR_EL1_KERNEL	SCTLR_EL1_RES1
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:45 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:45 +0000
Subject: [bootwrapper PATCH v3 03/15] Document entry requirements
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-4-mark.rutland@arm.com>

Currently the boot-wrapper only supports some combinations of exception
levels, with other combinations not being supported.

While we generally expect the boot-wrapper to be entered at the highest
implemented exception level, the AArch32 boot-wrapper has a comment
implying it supports being entered with something else owning EL3. As
this would require such EL3 firmware to always be in sync with the
boot-wrapper's requirements, which change over time, we don't actually
support such a configuration.

Some CPU state (such as CNTFRQ/CNTFRQ_EL0) needs to be initialized at
the highest implemented exception level, but today the boot-wrapper only
does so when entered at EL3 / Secure-PL1. Thus, today the only
completely supported configurations are EL3 / Secure-PL1, and entering
in other configurations is not entirely supported.

The aarch64 `jump_kernel` function always writes to SCTLR_EL2, which is
UNDEFINED at EL1. Hence, the aarch64 boot-wrapper does not support being
entered at EL1.

The aarch32 code assumes that any non-hyp mode is Secure PL1, and
attempt to switch to monitor mode. If entered on a system without the
security extensions, where the highest privileged mode is Non-secure
PL1, this will not work. Hence the aarch32 boot-wrapper does not support
being entered at Non-secure PL1.

Actually supporting all of these configurations requires restructuring
much of the boot-wrapper. For now, document the supported configurations
in each architecture's boot.S, and remove the misleading comment from
arch/aarch32/boot.S. Subsequent patches will improve the support and add
support for additional configurations.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/boot.S | 14 ++++++++++++++
 arch/aarch32/psci.S |  5 -----
 arch/aarch64/boot.S | 13 +++++++++++++
 3 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 4add338..00c432d 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -16,6 +16,20 @@
 	.arch_extension virt
 
 	.section .init
+
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered in the following modes:
+	 *
+	 * - PL1 / EL3 (Secure) Supervisor mode
+	 *   Entering in this mode is strongly recommended.
+	 *   PL2 must be implemented.
+	 *
+	 * - PL2 / EL2 (Non-secure) Hypervisor mode
+	 *   Entering in this mode is partially supported.
+	 *   PSCI is not supported when entered in this mode.
+	 */
 ASM_FUNC(_start)
 	/* Stack initialisation */
 	cpuid	r0, r1
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index dc7aeb7..e0d2972 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -44,11 +44,6 @@ ASM_FUNC(start_el3)
 	/* pass through */
 
 ASM_FUNC(start_no_el3)
-	/*
-	 * For no-el3, we assume that firmware launched the boot-wrapper in
-	 * non-secure EL2 or EL1. We assume it has its own PSCI implementation
-	 * sitting at EL3, and that this path is only taken by primary CPU.
-	 */
 	cpuid	r0, r1
 	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index ee9ddaa..d682ba5 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -12,6 +12,19 @@
 
 	.section .init
 
+	/*
+	 * The boot-wrapper must be entered from the reset vector at the
+	 * highest implemented exception level. The boot-wrapper only supports
+	 * being entered at the following exception levels:
+	 *
+	 * - EL3 (Secure)
+	 *   Entering at EL3 is strongly recommended.
+	 *   EL2 must be implemented.
+	 *
+	 * - EL2 (Non-secure)
+	 *   Entering at EL2 is partially supported.
+	 *   PSCI is not supported when entered in this exception level.
+	 */
 ASM_FUNC(_start)
 	cpuid	x0, x1
 	bl	find_logical_id
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:46 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:46 +0000
Subject: [bootwrapper PATCH v3 04/15] Add bit-field macros
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-5-mark.rutland@arm.com>

Arm architectural documentation typically defines bit-fields as
`[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
helpful if we could define fields in the same way.

Add helpers so that we can do so, along with helper to extract/insert
bit-field values.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 include/bits.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 include/bits.h

diff --git a/include/bits.h b/include/bits.h
new file mode 100644
index 0000000..5f0ad8f
--- /dev/null
+++ b/include/bits.h
@@ -0,0 +1,66 @@
+/*
+ * include/bits.h - helpers for bit-field definitions.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __BITS_H
+#define __BITS_H
+
+#ifdef __ASSEMBLY__
+#define UL(x)	x
+#define ULL(x)	x
+#else
+#define UL(x)	x##UL
+#define ULL(x)	x##ULL
+#endif
+
+/*
+ * Define a contiguous mask of bits with `msb` as the most significant bit and
+ * `lsb` as the least significant bit. The `msb` value must be greater than or
+ * equal to `lsb`.
+ *
+ * For example:
+ * - BITS(63, 63) is 0x8000000000000000
+ * - BITS(63, 0)  is 0xFFFFFFFFFFFFFFFF
+ * - BITS(0, 0)   is 0x0000000000000001
+ * - BITS(49, 17) is 0x0001FFFFFFFE0000
+ */
+#define BITS(msb, lsb) \
+	((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
+
+/*
+ * Define a mask of a single set bit `b`.
+ *
+ * For example:
+ * - BIT(63) is 0x8000000000000000
+ * - BIT(0)  is 0x0000000000000001
+ * - BIT(32) is 0x0000000100000000
+ */
+#define BIT(b)	BITS(b, b)
+
+/*
+ * Find the least significant set bit in the contiguous set of bits in `mask`.
+ *
+ * For example:
+ * - BITS_LSB(0x0000000000000001) is 0
+ * - BITS_LSB(0x000000000000ff00) is 8
+ * - BITS_LSB(0x8000000000000000) is 63
+ */
+#define BITS_LSB(mask)	(__builtin_ffsll(mask) - 1)
+
+/*
+ * Extract a bit-field out of `val` described by the contiguous set of bits in
+ * `mask`.
+ *
+ * For example:
+ * - BITS_EXTRACT(0xABCD, BITS(15, 12)) is 0xA
+ * - BITS_EXTRACT(0xABCD, BITS(11, 8))  is 0xB
+ * - BITS_EXTRACT(0xABCD, BIT(7))       is 0x1
+ */
+#define BITS_EXTRACT(val, mask) \
+	(((val) & (mask)) >> BITS_LSB(mask))
+
+#endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:47 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:47 +0000
Subject: [bootwrapper PATCH v3 05/15] aarch64: add system register accessors
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-6-mark.rutland@arm.com>

We open code the use of mrs/msr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch64/include/asm/cpu.h    | 41 ++++++++++++++++++++++---------
 arch/aarch64/include/asm/gic-v3.h | 10 +++-----
 2 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 49d3f86..341a545 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -9,10 +9,14 @@
 #ifndef __ASM_AARCH64_CPU_H
 #define __ASM_AARCH64_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
 
+#define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
+
 /*
  * RES1 bits,  little-endian, caches and MMU off, no alignment checking,
  * no WXN.
@@ -29,6 +33,12 @@
 
 #define CPTR_EL3_EZ		(1 << 8)
 
+#define ICC_SRE_EL2		S3_4_C12_C9_5
+#define ICC_SRE_EL3		S3_6_C12_C12_5
+#define ICC_CTLR_EL1		S3_0_C12_C12_4
+#define ICC_CTLR_EL3		S3_6_C12_C12_4
+#define ICC_PMR_EL1		S3_0_C4_C6_0
+
 #define ZCR_EL3			s3_6_c1_c2_0
 #define ZCR_EL3_LEN_MAX		0xf
 
@@ -57,20 +67,27 @@
 
 #define sevl()		asm volatile ("sevl\n" : : : "memory")
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define __str(def)	#def
 
-	asm volatile ("mrs	%0, mpidr_el1\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define mrs(reg)							\
+({									\
+	unsigned long __mrs_val;					\
+	asm volatile("mrs %0, " __str(reg) : "=r" (__mrs_val));		\
+	__mrs_val;							\
+})
 
-static inline uint64_t read_id_aa64pfr0(void)
-{
-	uint64_t val;
+#define msr(reg, val)							\
+do {									\
+	unsigned long __msr_val = val;					\
+	asm volatile("msr " __str(reg) ", %0" : : "r" (__msr_val));	\
+} while (0)
+
+#define mrs_field(reg, field) \
+	BITS_EXTRACT(mrs(reg), (reg##_##field))
 
-	asm volatile ("mrs	%0, id_aa64pfr0_el1\n" : "=r" (val));
-	return val;
+static inline unsigned long read_mpidr(void)
+{
+	return mrs(mpidr_el1) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
@@ -80,7 +97,7 @@ static inline void iciallu(void)
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_aa64pfr0() >> 24) & 0xf);
+	return !!mrs_field(ID_AA64PFR0_EL1, GIC);
 }
 
 #endif /* !__ASSEMBLY__ */
diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
index 5b32380..2447480 100644
--- a/arch/aarch64/include/asm/gic-v3.h
+++ b/arch/aarch64/include/asm/gic-v3.h
@@ -9,20 +9,16 @@
 #ifndef __ASM_AARCH64_GICV3_H
 #define __ASM_AARCH64_GICV3_H
 
-#define ICC_SRE_EL2	"S3_4_C12_C9_5"
-#define ICC_SRE_EL3	"S3_6_C12_C12_5"
-#define ICC_CTLR_EL1	"S3_0_C12_C12_4"
-#define ICC_CTLR_EL3	"S3_6_C12_C12_4"
-#define ICC_PMR_EL1	"S3_0_C4_C6_0"
+#include <asm/cpu.h>
 
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
+	msr(ICC_SRE_EL3, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
+	msr(ICC_CTLR_EL3, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:48 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:48 +0000
Subject: [bootwrapper PATCH v3 06/15] aarch32: add coprocessor accessors
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-7-mark.rutland@arm.com>

We open code the use of mrc/mcr for specific registers, which is
somewhat tedious. Add macros to do this generically, along with a helper
to extract a specific register field. Existing C usage is converted to
the new helpers, and register definitions moved to a common location.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch32/include/asm/cpu.h    | 45 ++++++++++++++++++++-----------
 arch/aarch32/include/asm/gic-v3.h |  6 +++--
 2 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index 105cae5..d691c7b 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -9,9 +9,13 @@
 #ifndef __ASM_AARCH32_CPU_H
 #define __ASM_AARCH32_CPU_H
 
+#include <bits.h>
+
 #define MPIDR_ID_BITS		0x00ffffff
 #define MPIDR_INVALID		(-1)
 
+#define ID_PFR1_GIC		BITS(31, 28)
+
 /* Only RES1 bits and CP15 barriers for the kernel */
 #define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
 #define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
@@ -40,32 +44,43 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
-static inline unsigned long read_mpidr(void)
-{
-	unsigned long mpidr;
+#define MPIDR		"p15, 0, %0, c0, c0, 5"
+#define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
-	asm volatile ("mrc	p15, 0, %0, c0, c0, 5\n" : "=r" (mpidr));
-	return mpidr & MPIDR_ID_BITS;
-}
+#define ICC_SRE		"p15, 6, %0, c12, c12, 5"
+#define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
-static inline uint32_t read_id_pfr1(void)
-{
-	uint32_t val;
+#define mrc(reg)						\
+({								\
+	unsigned long __mrc_val;				\
+	asm volatile("mrc " reg : "=r" (__mrc_val));		\
+	__mrc_val;						\
+})
 
-	asm volatile ("mrc	p15, 0, %0, c0, c1, 1\n" : "=r" (val));
-	return val;
+#define mcr(reg, val)						\
+do {								\
+	unsigned long __mcr_val = val;				\
+	asm volatile("mcr " reg : : "r" (__mcr_val));		\
+} while (0)
+
+
+#define mrc_field(reg, field) \
+	BITS_EXTRACT(mrc(reg), (reg##_##field))
+
+static inline unsigned long read_mpidr(void)
+{
+	return mrc(MPIDR) & MPIDR_ID_BITS;
 }
 
 static inline void iciallu(void)
 {
-	uint32_t val = 0;
-
-	asm volatile ("mcr	p15, 0, %0, c7, c5, 0" : : "r" (val));
+	mcr(ICIALLU, 0);
 }
 
 static inline int has_gicv3_sysreg(void)
 {
-	return !!((read_id_pfr1() >> 28) & 0xf);
+	return !!mrc_field(ID_PFR1, GIC);
 }
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
index 65f38de..b28136a 100644
--- a/arch/aarch32/include/asm/gic-v3.h
+++ b/arch/aarch32/include/asm/gic-v3.h
@@ -9,14 +9,16 @@
 #ifndef __ASM_AARCH32_GICV3_H
 #define __ASM_AARCH32_GICV3_H
 
+#include <asm/cpu.h>
+
 static inline void gic_write_icc_sre(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
+	mcr(ICC_SRE, val);
 }
 
 static inline void gic_write_icc_ctlr(uint32_t val)
 {
-	asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
+	mcr(ICC_CTLR, val);
 }
 
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:49 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:49 +0000
Subject: [bootwrapper PATCH v3 07/15] aarch64: add mov_64 macro
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-8-mark.rutland@arm.com>

In subsequent patches we'll need to load 64-bit values into GPRs before
the CPU is in a known endianness, where we cannot use literal pools.

In preparation for that, this patch adds a new `mov_64` macro to load a
64-bit value into a GPR using a sequence of MOV and MOVKs, which will
function the same regardless of the CPU's endianness.

At the same time, move the `cpuid` macro to use `mov_64` internally.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch64/common.S | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/aarch64/common.S b/arch/aarch64/common.S
index c7171a9..3279fa9 100644
--- a/arch/aarch64/common.S
+++ b/arch/aarch64/common.S
@@ -9,9 +9,17 @@
 
 #include <cpu.h>
 
+	/* Load a 64-bit value using immediates */
+	.macro	mov_64 dest, val
+	mov	\dest, #(((\val) >>  0) & 0xffff)
+	movk	\dest, #(((\val) >> 16) & 0xffff), lsl #16
+	movk	\dest, #(((\val) >> 32) & 0xffff), lsl #32
+	movk	\dest, #(((\val) >> 48) & 0xffff), lsl #48
+	.endm
+
 	/* Put MPIDR into \dest, clobber \tmp and flags */
 	.macro cpuid dest, tmp
 	mrs	\dest, mpidr_el1
-	ldr	\tmp, =MPIDR_ID_BITS
+	mov_64	\tmp, MPIDR_ID_BITS
 	ands	\dest, \dest, \tmp
 	.endm
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:50 +0000
Subject: [bootwrapper PATCH v3 08/15] aarch64: initialize SCTLR_ELx for the
 boot-wrapper
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-9-mark.rutland@arm.com>

The SCTLR_ELx registers contain fields which are UNKNOWN or
IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
defines the endianness of memory accesses (e.g. reads from literal
pools). Due to this, portions of boot-wrapper code are not guaranteed
to work correctly.

Rework the startup code to explicitly initialize SCTLR_ELx for the
exception level the boot-wrapper was entered at. When entered at EL2
it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
which would break the initialization performed in jump_kernel.

As we plan to eventually support the highest implemented EL being any of
EL3/EL2/EL1, code is added to handle all of these exception levels, even
though we do not currently support starting at EL1.

We'll initialize other registers in subsequent patches.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
 arch/aarch64/include/asm/cpu.h | 30 +++++++++++++-
 2 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index d682ba5..204c199 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -26,26 +26,26 @@
 	 *   PSCI is not supported when entered in this exception level.
 	 */
 ASM_FUNC(_start)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cmp	x0, #MPIDR_INVALID
-	beq	err_invalid_id
-	bl	setup_stack
-
-	/*
-	 * EL3 initialisation
-	 */
 	mrs	x0, CurrentEL
 	cmp	x0, #CURRENTEL_EL3
-	b.eq	1f
+	b.eq	reset_at_el3
+	cmp	x0, #CURRENTEL_EL2
+	b.eq	reset_at_el2
+	cmp	x0, #CURRENTEL_EL1
+	b.eq	reset_at_el1
 
-	mov	w0, #1
-	ldr	x1, =flag_no_el3
-	str	w0, [x1]
+	/* Booting at EL0 is not supported */
+	b	.
 
-	b	start_no_el3
+	/*
+	 * EL3 initialisation
+	 */
+reset_at_el3:
+	mov_64	x0, SCTLR_EL3_RESET
+	msr	sctlr_el3, x0
+	isb
 
-1:	mov	x0, #0x30			// RES1
+	mov	x0, #0x30			// RES1
 	orr	x0, x0, #(1 << 0)		// Non-secure EL1
 	orr	x0, x0, #(1 << 8)		// HVC enable
 
@@ -143,10 +143,54 @@ ASM_FUNC(_start)
 	ldr	x0, =COUNTER_FREQ
 	msr	cntfrq_el0, x0
 
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
 	bl	gic_secure_init
 
 	b	start_el3
 
+	/*
+	 * EL2 initialization
+	 */
+reset_at_el2:
+	// Ensure E2H is not in use
+	mov_64	x0, HCR_EL2_RESET
+	msr	hcr_el2, x0
+	isb
+
+	mov_64	x0, SCTLR_EL2_RESET
+	msr	sctlr_el2, x0
+	isb
+
+	b	reset_no_el3
+
+	/*
+	 * EL1 initialization
+	 */
+reset_at_el1:
+	mov_64	x0, SCTLR_EL1_RESET
+	msr	sctlr_el1, x0
+	isb
+
+	b	reset_no_el3
+
+reset_no_el3:
+	cpuid	x0, x1
+	bl	find_logical_id
+	cmp	x0, #MPIDR_INVALID
+	b.eq	err_invalid_id
+	bl	setup_stack
+
+	mov	w0, #1
+	ldr	x1, =flag_no_el3
+	str	w0, [x1]
+
+	b	start_no_el3
+
 err_invalid_id:
 	b	.
 
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 341a545..0a4085b 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -14,6 +14,35 @@
 #define MPIDR_ID_BITS		0xff00ffffff
 
 #define CURRENTEL_EL3		(3 << 2)
+#define CURRENTEL_EL2		(2 << 2)
+#define CURRENTEL_EL1		(1 << 2)
+
+/*
+ * RES1 bit definitions definitions as of ARM DDI 0487G.b
+ *
+ * These includes bits which are RES1 in some configurations.
+ */
+#define SCTLR_EL3_RES1							\
+	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(18) | BIT(16) |	\
+	 BIT(11) | BIT(5) | BIT(4))
+
+#define SCTLR_EL2_RES1							\
+	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(18) |	\
+	 BIT(16) | BIT(11) | BIT(5) | BIT(4))
+
+#define SCTLR_EL1_RES1							\
+	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(11) |	\
+	 BIT(8) | BIT(7) | BIT(4))
+
+#define HCR_EL2_RES1		(BIT(1))
+
+/*
+ * Initial register values required for the boot-wrapper to run out-of-reset.
+ */
+#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
+#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
+#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
+#define HCR_EL2_RESET		HCR_EL2_RES1
 
 #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
 
@@ -43,7 +72,6 @@
 #define ZCR_EL3_LEN_MAX		0xf
 
 #define SCTLR_EL1_CP15BEN	(1 << 5)
-#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
 
 #ifdef KERNEL_32
 /*
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:51 +0000
Subject: [bootwrapper PATCH v3 09/15] Rework common init C code
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-10-mark.rutland@arm.com>

In init_platform() we initialize a UART and announce the presence of the
bootwrapper to the world. We do this relatively late in the boot-flow,
and prior to this will silently ignore errors (e.g. in gic_secure_init).

To make it possible to provide improved diagnostics, and to allow us to
move more initialization into C, this patch reworks the init code to
call a C function earlier, where we can announce the presence of the
boot-wrapper and perform other initialization.

In subsequent patches this will be expanded with more CPU
initialization.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 Makefile.am         |  2 +-
 arch/aarch32/boot.S |  5 +++++
 arch/aarch64/boot.S |  4 ++++
 common/boot.c       |  4 ----
 common/init.c       | 24 ++++++++++++++++++++++++
 common/platform.c   | 12 +++++++-----
 include/platform.h  | 17 +++++++++++++++++
 7 files changed, 58 insertions(+), 10 deletions(-)
 create mode 100644 common/init.c
 create mode 100644 include/platform.h

diff --git a/Makefile.am b/Makefile.am
index 5731a19..91a6a02 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -34,7 +34,7 @@ endif
 PSCI_CPU_OFF	:= 0x84000002
 
 COMMON_SRC	:= common/
-COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o
+COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
 ARCH_OBJ	:= boot.o stack.o utils.o
 
diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 00c432d..ee073ea 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -48,6 +48,9 @@ ASM_FUNC(_start)
 	mov	r0, #1
 	ldr	r1, =flag_no_el3
 	str	r0, [r1]
+
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 _switch_monitor:
@@ -71,6 +74,8 @@ _monitor:
 	ldr	r0, =COUNTER_FREQ
 	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	/* Initialise boot method */
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 204c199..7872daf 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -149,6 +149,8 @@ reset_at_el3:
 	b.eq	err_invalid_id
 	bl	setup_stack
 
+	bl	cpu_init_bootwrapper
+
 	bl	gic_secure_init
 
 	b	start_el3
@@ -189,6 +191,8 @@ reset_no_el3:
 	ldr	x1, =flag_no_el3
 	str	w0, [x1]
 
+	bl	cpu_init_bootwrapper
+
 	b	start_no_el3
 
 err_invalid_id:
diff --git a/common/boot.c b/common/boot.c
index c74d34c..29d53a4 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -12,8 +12,6 @@
 extern unsigned long entrypoint;
 extern unsigned long dtb;
 
-void init_platform(void);
-
 void __noreturn jump_kernel(unsigned long address,
 			    unsigned long a0,
 			    unsigned long a1,
@@ -62,8 +60,6 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid)
 {
 	if (cpu == 0) {
-		init_platform();
-
 		*mbox = (unsigned long)&entrypoint;
 		sevl();
 		spin(mbox, invalid, 1);
diff --git a/common/init.c b/common/init.c
new file mode 100644
index 0000000..9c471c9
--- /dev/null
+++ b/common/init.c
@@ -0,0 +1,24 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+static void announce_bootwrapper(void)
+{
+	print_string("Boot-wrapper v0.2\r\n\r\n");
+}
+
+void cpu_init_bootwrapper(void)
+{
+	if (this_cpu_logical_id() == 0) {
+		init_uart();
+		announce_bootwrapper();
+		init_platform();
+	}
+}
diff --git a/common/platform.c b/common/platform.c
index d11f568..47bf547 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -1,5 +1,5 @@
 /*
- * platform.c - code to initialise everything required when first booting.
+ * platform.c - Platform initialization and I/O.
  *
  * Copyright (C) 2015 ARM Limited. All rights reserved.
  *
@@ -7,6 +7,7 @@
  * found in the LICENSE.txt file.
  */
 
+#include <cpu.h>
 #include <stdint.h>
 
 #include <asm/io.h>
@@ -30,7 +31,7 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-static void print_string(const char *str)
+void print_string(const char *str)
 {
 	uint32_t flags;
 
@@ -47,7 +48,7 @@ static void print_string(const char *str)
 	}
 }
 
-void init_platform(void)
+void init_uart(void)
 {
 	/*
 	 * UART initialisation (38400 8N1)
@@ -58,9 +59,10 @@ void init_platform(void)
 	raw_writel(0x70,	PL011(UART_LCR_H));
 	/* Enable the UART, TXen and RXen */
 	raw_writel(0x301,	PL011(UARTCR));
+}
 
-	print_string("Boot-wrapper v0.2\r\n\r\n");
-
+void init_platform(void)
+{
 #ifdef SYSREGS_BASE
 	/*
 	 * CLCD output site MB
diff --git a/include/platform.h b/include/platform.h
new file mode 100644
index 0000000..e5248e1
--- /dev/null
+++ b/include/platform.h
@@ -0,0 +1,17 @@
+/*
+ * include/platform.h - Platform initialization and I/O.
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#ifndef __PLATFORM_H
+#define __PLATFORM_H
+
+void print_string(const char *str);
+void init_uart(void);
+
+void init_platform(void);
+
+#endif /* __PLATFORM_H */
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:52 +0000
Subject: [bootwrapper PATCH v3 10/15] Announce boot-wrapper mode / exception
 level
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-11-mark.rutland@arm.com>

When something goes wrong within the boot-wrapper, it can be very
helpful to know where we started from. Add an arch_announce() function
to log this early in the boot process. More information can be added
here in future.

This is logged ot the serial console as:

| Boot-wrapper v0.2
| Entered at EL3

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 Makefile.am                    |  2 +-
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 29 +++++++++++++++++++++++++++++
 arch/aarch64/init.c            | 19 +++++++++++++++++++
 common/init.c                  |  6 +++++-
 common/platform.c              | 24 ++++++++++++++----------
 include/platform.h             |  1 +
 7 files changed, 78 insertions(+), 12 deletions(-)
 create mode 100644 arch/aarch32/init.c
 create mode 100644 arch/aarch64/init.c

diff --git a/Makefile.am b/Makefile.am
index 91a6a02..5a0ebd2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -36,7 +36,7 @@ PSCI_CPU_OFF	:= 0x84000002
 COMMON_SRC	:= common/
 COMMON_OBJ	:= boot.o bakery_lock.o platform.o lib.o init.o
 
-ARCH_OBJ	:= boot.o stack.o utils.o
+ARCH_OBJ	:= boot.o stack.o utils.o init.o
 
 if BOOTWRAPPER_32
 CPPFLAGS	+= -DBOOTWRAPPER_32
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index d691c7b..aa72204 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -44,6 +44,15 @@
 #define sevl()		asm volatile ("sev" : : : "memory")
 #endif
 
+static inline unsigned long read_cpsr(void)
+{
+	unsigned long cpsr;
+	asm volatile ("mrs      %0, cpsr\n" : "=r" (cpsr));
+	return cpsr;
+}
+
+#define read_cpsr_mode()       (read_cpsr() & PSR_MODE_MASK)
+
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
new file mode 100644
index 0000000..785a428
--- /dev/null
+++ b/arch/aarch32/init.c
@@ -0,0 +1,29 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+static const char *mode_string(void)
+{
+	switch (read_cpsr_mode()) {
+	case PSR_MON:
+		return "PL1";
+	case PSR_HYP:
+		return "PL2 (Non-secure)";
+	default:
+		return "<UNKNOWN MODE>";
+	}
+}
+
+void announce_arch(void)
+{
+	print_string("Entered at ");
+	print_string(mode_string());
+	print_string("\r\n");
+}
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
new file mode 100644
index 0000000..82816e7
--- /dev/null
+++ b/arch/aarch64/init.c
@@ -0,0 +1,19 @@
+/*
+ * init.c - common boot-wrapper initialization
+ *
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE.txt file.
+ */
+#include <cpu.h>
+#include <platform.h>
+
+void announce_arch(void)
+{
+	unsigned char el = mrs(CurrentEl) >> 2;
+
+	print_string("Entered at EL");
+	print_char('0' + el);
+	print_string("\r\n");
+}
diff --git a/common/init.c b/common/init.c
index 9c471c9..2600f73 100644
--- a/common/init.c
+++ b/common/init.c
@@ -11,14 +11,18 @@
 
 static void announce_bootwrapper(void)
 {
-	print_string("Boot-wrapper v0.2\r\n\r\n");
+	print_string("Boot-wrapper v0.2\r\n");
 }
 
+void announce_arch(void);
+
 void cpu_init_bootwrapper(void)
 {
 	if (this_cpu_logical_id() == 0) {
 		init_uart();
 		announce_bootwrapper();
+		announce_arch();
+		print_string("\r\n");
 		init_platform();
 	}
 }
diff --git a/common/platform.c b/common/platform.c
index 47bf547..80d0562 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -31,21 +31,25 @@
 #define V2M_SYS(reg)	((void *)SYSREGS_BASE + V2M_SYS_##reg)
 #endif
 
-void print_string(const char *str)
+void print_char(char c)
 {
 	uint32_t flags;
 
-	while (*str) {
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_FIFO_FULL);
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_FIFO_FULL);
+
+	raw_writel(c, PL011(UARTDR));
 
-		raw_writel(*str++, PL011(UARTDR));
+	do {
+		flags = raw_readl(PL011(UARTFR));
+	} while (flags & PL011_UARTFR_BUSY);
+}
 
-		do
-			flags = raw_readl(PL011(UARTFR));
-		while (flags & PL011_UARTFR_BUSY);
-	}
+void print_string(const char *str)
+{
+	while (*str)
+		print_char(*str++);
 }
 
 void init_uart(void)
diff --git a/include/platform.h b/include/platform.h
index e5248e1..237b481 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -9,6 +9,7 @@
 #ifndef __PLATFORM_H
 #define __PLATFORM_H
 
+void print_char(char c);
 void print_string(const char *str);
 void init_uart(void);
 
-- 
2.30.2



From narmstrong at baylibre.com  Tue Jan 25 07:01:18 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Tue, 25 Jan 2022 16:01:18 +0100
Subject: [PATCH 0/3] arm64: dts: meson: add BL32 reserved region to
 Beelink g12b devices
In-Reply-To: <C8B4EA0E-6593-4C42-B116-F9C043D29452@gmail.com>
References: <20220122073221.2398-1-christianshewitt@gmail.com>
 <7h7daoyka3.fsf@baylibre.com>
 <C8B4EA0E-6593-4C42-B116-F9C043D29452@gmail.com>
Message-ID: <4a8727f4-fbdd-33f7-1f1b-c4baf92ad986@baylibre.com>

Hi,

On 25/01/2022 05:02, Christian Hewitt wrote:
> 
>> On 25 Jan 2022, at 12:02 am, Kevin Hilman <khilman at baylibre.com <mailto:khilman at baylibre.com>> wrote:
>>
>> Christian Hewitt <christianshewitt at gmail.com <mailto:christianshewitt at gmail.com>> writes:
>>
>>> This resolves a long-running issue where Beelink GT-King/Pro and
>>> GS-King-X wedge on boot or shortly after when booting from vendor
>>> u-boot. In some distros the issue is often reported as triggered
>>> by large file transfers to/from USB or SD cards. Reserving the
>>> BL32 memory region prevents the issue.
>>
>> The BL32 is typically common for the SoC family, so this change should
>> probably go into the g12b.dtsi. ?Or probably even
>> meson-g12-common.dtsi, which is where the BL31 reserved-memory is
>> described.
> 
> Hi Kevin,
> 
> Would you be okay with the same change applied to GX devices too? - I
> normally have these two catch-all patches in my tree to deal with random
> tv box hardware and it would be great to drop them:
> 
> https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc <https://github.com/chewitt/linux/commit/4315ea4612389fc08d0a008b562cafbda96374fc>
> https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9 <https://github.com/chewitt/linux/commit/3c0df794baa7ea9d32d8ad54530b5a056c770ea9>

Sure, it has been done in a similar way for bl31:
https://github.com/torvalds/linux/commit/48e21ded0432ee1e2359d4143d7a6925cefee1b5

in a perfect work we wouldn't need this since mainline U-Boot does the job by reserving these
memory zones, but vendor u-boot exists and isn't avoidable.

Neil

> 
> Christian



From mark.rutland at arm.com  Tue Jan 25 07:00:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:53 +0000
Subject: [bootwrapper PATCH v3 11/15] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-12-mark.rutland@arm.com>

The majority of state that we initialize at EL3 is necessary for code at
lower ELs to function, but isnt' necessary for the boot-wrapper itself.
Given that, it would be better to write this in C where it can be
written mode clearly, and where it will be possible to add logging/debug
logic.

This patch migrates the AArch64 EL3 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |   2 +-
 arch/aarch64/boot.S            | 100 +--------------------------------
 arch/aarch64/include/asm/cpu.h |  35 +++++++++++-
 arch/aarch64/init.c            |  72 ++++++++++++++++++++++++
 4 files changed, 109 insertions(+), 100 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 5a0ebd2..a5e8e8b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -155,7 +155,7 @@ $(COMMON_SRC):
 %.o: %.S Makefile | $(ARCH_SRC)
 	$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
 
-%.o: %.c Makefile | $(COMMON_SRC)
+%.o: %.c Makefile | $(ARCH_SRC) $(COMMON_SRC)
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
 
 model.lds: $(LD_SCRIPT) Makefile
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 7872daf..c0ec518 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -45,104 +45,6 @@ reset_at_el3:
 	msr	sctlr_el3, x0
 	isb
 
-	mov	x0, #0x30			// RES1
-	orr	x0, x0, #(1 << 0)		// Non-secure EL1
-	orr	x0, x0, #(1 << 8)		// HVC enable
-
-	/* Enable pointer authentication if present */
-	mrs	x1, id_aa64isar1_el1
-	/* We check for APA+API and GPA+GPI */
-	ldr	x2, =((0xff << 24) | (0xff << 4))
-	and	x1, x1, x2
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 16)		// AP key enable
-	orr	x0, x0, #(1 << 17)		// AP insn enable
-1:
-	/* Enable TME if present */
-	mrs	x1, id_aa64isar0_el1
-	ubfx	x1, x1, #24, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 34)		// TME enable
-1:
-	/* Enable FGT if present */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #56, #4
-	cbz	x1, 1f
-
-	orr	x0, x0, #(1 << 27)		// FGT enable
-1:
-	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
-	mrs	x1, id_aa64mmfr0_el1
-	ubfx	x1, x1, #60, #4
-	cmp	x1, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 28)		// ECV enable
-1:
-	/* Enable MTE if present */
-	mrs	x10, id_aa64pfr1_el1
-	ubfx	x10, x10, #8, #4
-	cmp	x10, #2
-	b.lt	1f
-
-	orr	x0, x0, #(1 << 26)		// ATA enable
-1:
-#ifndef KERNEL_32
-	orr	x0, x0, #(1 << 10)		// 64-bit EL2
-#endif
-	msr	scr_el3, x0
-
-	msr	cptr_el3, xzr			// Disable copro. traps to EL3
-
-	mov	x0, xzr
-	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #32, #4
-	cbz	x1, 1f
-
-	// Enable SPE for the non-secure world.
-	orr	x0, x0, #(0x3 << 12)
-
-	// Do not trap PMSNEVFR_EL1 if present
-	cmp	x1, #3
-	b.lt	1f
-	orr	x0, x0, #(1 << 36)
-
-1:	mrs	x1, id_aa64dfr0_el1
-	ubfx	x1, x1, #44, #4
-	cbz	x1, 1f
-
-	// Enable TRBE for the non-secure world.
-	ldr	x1, =(0x3 << 24)
-	orr	x0, x0, x1
-
-1:	mrs     x1, id_aa64dfr0_el1
-	ubfx    x1, x1, #52, #4
-	cbz     x1, 1f
-
-	// Enable BRBE for the non-secure world.
-	ldr     x1, =(0x3 << 32)
-	orr     x0, x0, x1
-
-1:	msr	mdcr_el3, x0			// Disable traps to EL3
-
-	mrs	x0, id_aa64pfr0_el1
-	ubfx	x0, x0, #32, #4			// SVE present?
-	cbz	x0, 1f				// Skip SVE init if not
-
-	mrs	x0, cptr_el3
-	orr	x0, x0, #CPTR_EL3_EZ		// enable SVE
-	msr	cptr_el3, x0
-	isb
-
-	mov	x0, #ZCR_EL3_LEN_MAX		// SVE: Enable full vector len
-	msr	ZCR_EL3, x0			// for EL2.
-
-1:
-	ldr	x0, =COUNTER_FREQ
-	msr	cntfrq_el0, x0
-
 	cpuid	x0, x1
 	bl	find_logical_id
 	cmp	x0, #MPIDR_INVALID
@@ -151,6 +53,8 @@ reset_at_el3:
 
 	bl	cpu_init_bootwrapper
 
+	bl	cpu_init_el3
+
 	bl	gic_secure_init
 
 	b	start_el3
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 0a4085b..1be2d54 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -34,7 +34,40 @@
 	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(11) |	\
 	 BIT(8) | BIT(7) | BIT(4))
 
-#define HCR_EL2_RES1		(BIT(1))
+#define MDCR_EL3_NSPB_NS_NOTRAP			(UL(3) << 12)
+#define MDCR_EL3_NSTB_NS_NOTRAP			(UL(3) << 24)
+#define MDCR_EL3_SBRBE_NOTRAP_NOPROHIBIT	(UL(3) << 32)
+#define MDCR_EL3_ENPMSN				BIT(36)
+
+#define SCR_EL3_RES1			BITS(5, 4)
+#define SCR_EL3_NS			BIT(0)
+#define SCR_EL3_HCE			BIT(8)
+#define SCR_EL3_RW			BIT(10)
+#define SCR_EL3_APK			BIT(16)
+#define SCR_EL3_API			BIT(17)
+#define SCR_EL3_ATA			BIT(26)
+#define SCR_EL3_FGTEN			BIT(27)
+#define SCR_EL3_ECVEN			BIT(28)
+#define SCR_EL3_TME			BIT(34)
+
+#define HCR_EL2_RES1			BIT(1)
+
+#define ID_AA64DFR0_EL1_PMSVER		BITS(35, 32)
+#define ID_AA64DFR0_EL1_TRACEBUFFER	BITS(47, 44)
+#define ID_AA64DFR0_EL1_BRBE		BITS(55, 52)
+
+#define ID_AA64ISAR0_EL1_TME		BITS(27, 24)
+
+#define ID_AA64ISAR1_EL1_APA		BITS(7, 4)
+#define ID_AA64ISAR1_EL1_API		BITS(11, 8)
+#define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
+#define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
+
+#define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
+#define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
+
+#define ID_AA64PFR1_EL1_MTE		BITS(11, 8)
+#define ID_AA64PFR0_EL1_SVE		BITS(35, 32)
 
 /*
  * Initial register values required for the boot-wrapper to run out-of-reset.
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 82816e7..74190be 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -8,6 +8,7 @@
  */
 #include <cpu.h>
 #include <platform.h>
+#include <stdbool.h>
 
 void announce_arch(void)
 {
@@ -17,3 +18,74 @@ void announce_arch(void)
 	print_char('0' + el);
 	print_string("\r\n");
 }
+
+static inline bool kernel_is_32bit(void)
+{
+#ifdef KERNEL_32
+	return true;
+#else
+	return false;
+#endif
+}
+
+static inline bool cpu_has_pauth(void)
+{
+	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
+				       ID_AA64ISAR1_EL1_API |
+				       ID_AA64ISAR1_EL1_GPA |
+				       ID_AA64ISAR1_EL1_GPI;
+
+	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
+}
+
+void cpu_init_el3(void)
+{
+	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
+	unsigned long mdcr = 0;
+	unsigned long cptr = 0;
+
+	if (cpu_has_pauth())
+		scr |= SCR_EL3_APK | SCR_EL3_API;
+
+	if (mrs_field(ID_AA64ISAR0_EL1, TME))
+		scr |= SCR_EL3_TME;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
+		scr |= SCR_EL3_FGTEN;
+
+	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
+		scr |= SCR_EL3_ECVEN;
+
+	if (mrs_field(ID_AA64PFR1_EL1, MTE) >= 2)
+		scr |= SCR_EL3_ATA;
+
+	if (!kernel_is_32bit())
+		scr |= SCR_EL3_RW;
+
+	msr(SCR_EL3, scr);
+
+	msr(CPTR_EL3, cptr);
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER))
+		mdcr |= MDCR_EL3_NSPB_NS_NOTRAP;
+
+	if (mrs_field(ID_AA64DFR0_EL1, PMSVER) >= 3)
+		mdcr |= MDCR_EL3_ENPMSN;
+
+	if (mrs_field(ID_AA64DFR0_EL1, TRACEBUFFER))
+		mdcr |= MDCR_EL3_NSTB_NS_NOTRAP;
+
+	if (mrs_field(ID_AA64DFR0_EL1, BRBE))
+		mdcr |= MDCR_EL3_SBRBE_NOTRAP_NOPROHIBIT;
+
+	msr(MDCR_EL3, mdcr);
+
+	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
+		cptr |= CPTR_EL3_EZ;
+		msr(CPTR_EL3, cptr);
+		isb();
+		msr(ZCR_EL3, ZCR_EL3_LEN_MAX);
+	}
+
+	msr(CNTFRQ_EL0, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:54 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:54 +0000
Subject: [bootwrapper PATCH v3 12/15] aarch32: move the bulk of Secure PL1
 initialization to C
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-13-mark.rutland@arm.com>

The majority of state that we initialize at Secure PL1 is necessary for
code at lower PLs to function, but isnt' necessary for the boot-wrapper
itself.  Given that, it would be better to write this in C where it can
be written mode clearly, and where it will be possible to add
logging/debug logic.

This patch migrates the AArch32 Secure PL1 initialization to C.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch32/boot.S            | 11 +----------
 arch/aarch32/include/asm/cpu.h |  9 +++++++++
 arch/aarch32/init.c            | 12 ++++++++++++
 3 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index ee073ea..820957b 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -63,16 +63,7 @@ _monitor:
 	/* Move the stack to Monitor mode*/
 	mrs	sp, sp_svc
 
-	/* Setup secure registers and devices */
-	mov	r0, #1				@ Non-secure lower level
-	orr	r0, #(1 << 8)			@ HVC enable
-	mcr	p15, 0, r0, c1, c1, 0		@ SCR
-
-	mov	r0, #(1 << 10 | 1 << 11)	@ Enable NS access to CPACR
-	mcr	p15, 0, r0, c1, c1, 2		@ NSACR
-
-	ldr	r0, =COUNTER_FREQ
-	mcr	p15, 0, r0, c14, c0, 0		@ CNTFRQ
+	bl	cpu_init_secure_pl1
 
 	bl	cpu_init_bootwrapper
 
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index aa72204..c1bce9a 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -30,6 +30,11 @@
 #define PSR_I			(1 << 7)
 #define PSR_A			(1 << 8)
 
+#define SCR_NS			BIT(0)
+#define SCR_HCE			BIT(8)
+
+#define NSACR_CP10		BIT(10)
+#define NSACR_CP11		BIT(11)
 
 #define SPSR_KERNEL		(PSR_A | PSR_I | PSR_F | PSR_HYP)
 
@@ -55,11 +60,15 @@ static inline unsigned long read_cpsr(void)
 
 #define MPIDR		"p15, 0, %0, c0, c0, 5"
 #define ID_PFR1		"p15, 0, %0, c0, c1, 1"
+#define SCR		"p15, 0, %0, c1, c1, 0"
+#define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
 
+#define CNTFRQ		"p15, 0, %0, c14, c0, 0"
+
 #define mrc(reg)						\
 ({								\
 	unsigned long __mrc_val;				\
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
index 785a428..7143c66 100644
--- a/arch/aarch32/init.c
+++ b/arch/aarch32/init.c
@@ -27,3 +27,15 @@ void announce_arch(void)
 	print_string(mode_string());
 	print_string("\r\n");
 }
+
+void cpu_init_secure_pl1(void)
+{
+	unsigned long scr = SCR_NS | SCR_HCE;
+	unsigned long nsacr = NSACR_CP10 | NSACR_CP11;
+
+	mcr(SCR, scr);
+
+	mcr(NSACR, nsacr);
+
+	mcr(CNTFRQ, COUNTER_FREQ);
+}
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:55 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:55 +0000
Subject: [bootwrapper PATCH v3 13/15] Announce locations of memory objects
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-14-mark.rutland@arm.com>

To make it easier to debug boot failures, log the location of memory
objects at boot time.

This is logged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL3
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 common/init.c      | 27 +++++++++++++++++++++++++++
 common/platform.c  | 13 +++++++++++++
 include/platform.h |  2 ++
 model.lds.S        | 20 ++++++++++++++------
 4 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/common/init.c b/common/init.c
index 2600f73..fc74b9e 100644
--- a/common/init.c
+++ b/common/init.c
@@ -14,6 +14,32 @@ static void announce_bootwrapper(void)
 	print_string("Boot-wrapper v0.2\r\n");
 }
 
+#define announce_object(object, desc)				\
+do {								\
+	extern char object##__start[];				\
+	extern char object##__end[];				\
+	print_string("[");					\
+	print_ulong_hex((unsigned long)object##__start);	\
+	print_string("..");					\
+	print_ulong_hex((unsigned long)object##__end);		\
+	print_string("] => " desc "\r\n");			\
+} while (0)
+
+static void announce_objects(void)
+{
+	print_string("Memory layout:\r\n");
+	announce_object(text, "boot-wrapper");
+	announce_object(mbox, "mbox");
+	announce_object(kernel, "kernel");
+#ifdef XEN
+	announce_object(xen, "xen");
+#endif
+	announce_object(dtb, "dtb");
+#ifdef USE_INITRD
+	announce_object(filesystem, "initrd");
+#endif
+}
+
 void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
@@ -22,6 +48,7 @@ void cpu_init_bootwrapper(void)
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
+		announce_objects();
 		print_string("\r\n");
 		init_platform();
 	}
diff --git a/common/platform.c b/common/platform.c
index 80d0562..1607ee6 100644
--- a/common/platform.c
+++ b/common/platform.c
@@ -52,6 +52,19 @@ void print_string(const char *str)
 		print_char(*str++);
 }
 
+#define HEX_CHARS_PER_LONG	(2 * sizeof(long))
+#define HEX_CHARS		"0123456789abcdef"
+
+void print_ulong_hex(unsigned long val)
+{
+	int i;
+
+	for (i = HEX_CHARS_PER_LONG - 1; i >= 0; i--) {
+		int v = (val >> (4 * i)) & 0xf;
+		print_char(HEX_CHARS[v]);
+	}
+}
+
 void init_uart(void)
 {
 	/*
diff --git a/include/platform.h b/include/platform.h
index 237b481..c88e124 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -11,6 +11,8 @@
 
 void print_char(char c);
 void print_string(const char *str);
+void print_ulong_hex(unsigned long val);
+
 void init_uart(void);
 
 void init_platform(void);
diff --git a/model.lds.S b/model.lds.S
index d4e7e13..dacaa25 100644
--- a/model.lds.S
+++ b/model.lds.S
@@ -35,46 +35,54 @@ SECTIONS
 	 * the boot section's *(.data)
 	 */
 	.kernel (PHYS_OFFSET + KERNEL_OFFSET): {
-		kernel = .;
+		kernel__start = .;
 		KERNEL
+		kernel__end = .;
 	}
 
 #ifdef XEN
 	.xen (PHYS_OFFSET + XEN_OFFSET): {
-		xen = .;
+		xen__start = .;
 		XEN
+		xen__end = .;
 	}
 
-	entrypoint = xen;
+	entrypoint = xen__start;
 #else
-	entrypoint = kernel;
+	entrypoint = kernel__start;
 #endif
 
 	.dtb (PHYS_OFFSET + FDT_OFFSET): {
+		dtb__start = .;
 		dtb = .;
 		./fdt.dtb
+		dtb__end = .;
 	}
 
 #ifdef USE_INITRD
 	.filesystem (PHYS_OFFSET + FS_OFFSET): {
-		filesystem = .;
+		filesystem__start = .;
 		FILESYSTEM
-		fs_size = . - filesystem;
+		filesystem__end = .;
 	}
 #endif
 
 	.boot PHYS_OFFSET: {
+		text__start = .;
 		*(.init)
 		*(.text*)
 		*(.data* .rodata* .bss* COMMON)
 		*(.vectors)
 		*(.stack)
 		PROVIDE(etext = .);
+		text__end = .;
 	}
 
 	.mbox (PHYS_OFFSET + MBOX_OFFSET): {
+		mbox__start = .;
 		mbox = .;
 		QUAD(0x0)
+		mbox__end = .;
 	}
 
 	ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:56 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:56 +0000
Subject: [bootwrapper PATCH v3 14/15] Rework bootmethod initialization
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-15-mark.rutland@arm.com>

We currently initialize the bootmethod late, in assembly code. This
requires us to maintain the el3/no_el3 distintion late into the boot
process, and means we cannot produce any helpful diagnostic when booted
at an unexpected exception level.

Rework things so that we initialize the bootmethod early, with a warning
when things are wrong. The el3/no_el3 distinction is now irrelevant to
the bootmethod code, and can be removed in subsequent patches.

When a boot-wrapper configured for PSCI is entered at EL2, a warning is
looged to the serial console as:

| Boot-wrapper v0.2
| Entered at EL2
| Memory layout:
| [0000000080000000..0000000080001f90] => boot-wrapper
| [000000008000fff8..0000000080010000] => mbox
| [0000000080200000..00000000822af200] => kernel
| [0000000088000000..0000000088002857] => dtb
|
| WARNING: PSCI could not be initialized. Boot may fail

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
---
 Makefile.am                    |  1 +
 arch/aarch32/include/asm/cpu.h |  1 +
 arch/aarch32/init.c            | 16 ++++++++++++++++
 arch/aarch32/psci.S            |  8 +-------
 arch/aarch32/utils.S           |  9 ---------
 arch/aarch64/init.c            | 15 +++++++++++++++
 arch/aarch64/psci.S            | 21 ++-------------------
 arch/aarch64/spin.S            |  3 +++
 arch/aarch64/utils.S           |  9 ---------
 common/init.c                  |  7 ++++++-
 common/psci.c                  | 20 +++++++++++++++++---
 include/boot.h                 |  7 +++++++
 12 files changed, 69 insertions(+), 48 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index a5e8e8b..40bc5d6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -48,6 +48,7 @@ ARCH_SRC	:= arch/aarch64/
 endif
 
 if PSCI
+DEFINES		+= -DPSCI
 ARCH_OBJ	+= psci.o
 COMMON_OBJ	+= psci.o
 PSCI_NODE	:= psci {				\
diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
index c1bce9a..3426075 100644
--- a/arch/aarch32/include/asm/cpu.h
+++ b/arch/aarch32/include/asm/cpu.h
@@ -63,6 +63,7 @@ static inline unsigned long read_cpsr(void)
 #define SCR		"p15, 0, %0, c1, c1, 0"
 #define NSACR		"p15, 0, %0, c1, c1, 2"
 #define ICIALLU		"p15, 0, %0, c7, c5, 0"
+#define MVBAR		"p15, 0, %0, c12, c0, 1"
 
 #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
 #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
index 7143c66..e25f0c7 100644
--- a/arch/aarch32/init.c
+++ b/arch/aarch32/init.c
@@ -8,6 +8,7 @@
  */
 #include <cpu.h>
 #include <platform.h>
+#include <stdbool.h>
 
 static const char *mode_string(void)
 {
@@ -39,3 +40,18 @@ void cpu_init_secure_pl1(void)
 
 	mcr(CNTFRQ, COUNTER_FREQ);
 }
+
+#ifdef PSCI
+extern char psci_vectors[];
+
+bool cpu_init_psci_arch(void)
+{
+	if (read_cpsr_mode() != PSR_MON)
+		return false;
+
+	mcr(MVBAR, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+#endif
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index e0d2972..cdc36b0 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -15,7 +15,7 @@
 
 	.section .vectors
 	.align 6
-smc_vectors:
+ASM_DATA(psci_vectors)
 	b	err_exception			@ Reset
 	b	err_exception			@ Undef
 	b	handle_smc			@ SMC
@@ -39,11 +39,5 @@ handle_smc:
 	movs	pc, lr
 
 ASM_FUNC(start_el3)
-	ldr	r0, =smc_vectors
-	blx	setup_vector
-	/* pass through */
-
 ASM_FUNC(start_no_el3)
-	cpuid	r0, r1
-	blx	find_logical_id
 	b	psci_first_spin
diff --git a/arch/aarch32/utils.S b/arch/aarch32/utils.S
index 5809f48..58279aa 100644
--- a/arch/aarch32/utils.S
+++ b/arch/aarch32/utils.S
@@ -35,12 +35,3 @@ ASM_FUNC(find_logical_id)
 	bx	lr
 3:	mov	r0, #MPIDR_INVALID
 	bx	lr
-
-/*
- * Setup EL3 vectors.
- * r0: vector address
- */
-ASM_FUNC(setup_vector)
-	mcr	p15, 0, r0, c12, c0, 1	@ MVBAR
-	isb
-	bx	lr
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 74190be..6677f2b 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -89,3 +89,18 @@ void cpu_init_el3(void)
 
 	msr(CNTFRQ_EL0, COUNTER_FREQ);
 }
+
+#ifdef PSCI
+extern char psci_vectors[];
+
+bool cpu_init_psci_arch(void)
+{
+	if (mrs(CurrentEL) != CURRENTEL_EL3)
+		return false;
+
+	msr(VBAR_EL3, (unsigned long)psci_vectors);
+	isb();
+
+	return true;
+}
+#endif
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index 8bd224b..d6ca2eb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -19,7 +19,7 @@
 	.section .vectors, "w"
 
 	.align 11
-vector:
+ASM_DATA(psci_vectors)
 	// current EL, SP_EL0
 	ventry	err_exception	// synchronous
 	ventry	err_exception	// IRQ
@@ -80,22 +80,5 @@ smc_exit:
 	eret
 
 ASM_FUNC(start_el3)
-	ldr	x0, =vector
-	bl	setup_vector
-
-	/* only boot the primary cpu (entry 0 in the table) */
-	cpuid	x0, x1
-	bl	find_logical_id
-	b	psci_first_spin
-
-/*
- * This PSCI implementation requires EL3. Without EL3 we'll only boot the
- * primary cpu, all others will be trapped in an infinite loop.
- */
 ASM_FUNC(start_no_el3)
-	cpuid	x0, x1
-	bl	find_logical_id
-	cbz	x0, psci_first_spin
-spin_dead:
-	wfe
-	b	spin_dead
+	b	psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 1ea1c0b..764c532 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -12,6 +12,9 @@
 
 	.text
 
+ASM_FUNC(cpu_init_bootmethod)
+	ret
+
 ASM_FUNC(start_el3)
 ASM_FUNC(start_no_el3)
 	cpuid	x0, x1
diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
index 85c7f8a..32393cc 100644
--- a/arch/aarch64/utils.S
+++ b/arch/aarch64/utils.S
@@ -32,12 +32,3 @@ ASM_FUNC(find_logical_id)
 	ret
 3:	mov	x0, #MPIDR_INVALID
 	ret
-
-/*
- * Setup EL3 vectors
- * x0: vector address
- */
-ASM_FUNC(setup_vector)
-	msr	VBAR_EL3, x0
-	isb
-	ret
diff --git a/common/init.c b/common/init.c
index fc74b9e..3c05ac3 100644
--- a/common/init.c
+++ b/common/init.c
@@ -6,6 +6,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE.txt file.
  */
+#include <boot.h>
 #include <cpu.h>
 #include <platform.h>
 
@@ -44,7 +45,9 @@ void announce_arch(void);
 
 void cpu_init_bootwrapper(void)
 {
-	if (this_cpu_logical_id() == 0) {
+	unsigned int cpu = this_cpu_logical_id();
+
+	if (cpu == 0) {
 		init_uart();
 		announce_bootwrapper();
 		announce_arch();
@@ -52,4 +55,6 @@ void cpu_init_bootwrapper(void)
 		print_string("\r\n");
 		init_platform();
 	}
+
+	cpu_init_bootmethod(cpu);
 }
diff --git a/common/psci.c b/common/psci.c
index a0e8700..5ae4255 100644
--- a/common/psci.c
+++ b/common/psci.c
@@ -12,6 +12,7 @@
 #include <bakery_lock.h>
 #include <boot.h>
 #include <cpu.h>
+#include <platform.h>
 #include <psci.h>
 
 #ifndef CPU_IDS
@@ -78,12 +79,25 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
 	}
 }
 
-void __noreturn psci_first_spin(unsigned int cpu)
+void __noreturn psci_first_spin(void)
 {
-	if (cpu == MPIDR_INVALID)
-		while (1);
+	unsigned int cpu = this_cpu_logical_id();
 
 	first_spin(cpu, branch_table + cpu, PSCI_ADDR_INVALID);
 
 	unreachable();
 }
+
+void cpu_init_bootmethod(unsigned int cpu)
+{
+	if (cpu_init_psci_arch())
+		return;
+
+	if (cpu == 0) {
+		print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
+		return;
+	}
+
+	while (1)
+		wfe();
+}
diff --git a/include/boot.h b/include/boot.h
index d75e013..459d1d5 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -10,10 +10,17 @@
 #define __BOOT_H
 
 #include <compiler.h>
+#include <stdbool.h>
 
 void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
 
 void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
 			   unsigned long invalid_addr);
 
+void cpu_init_bootmethod(unsigned int cpu);
+
+#ifdef PSCI
+bool cpu_init_psci_arch(void);
+#endif
+
 #endif
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:00:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:00:57 +0000
Subject: [bootwrapper PATCH v3 15/15] Unify start_el3 & start_no_el3
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <20220125150057.3936090-16-mark.rutland@arm.com>

Now that the start_el3 and start_no_el3 labels point at the same place,
unify them into a start_bootmethod label and update callers.

There should be no functional change as a result of this patch.

Signed-off-by: Mark Rutland <mark.rutland at arm.com>
Reviewed-by: Andre Przywara <andre.przywara at arm.com>
---
 arch/aarch32/boot.S | 5 ++---
 arch/aarch32/psci.S | 3 +--
 arch/aarch64/boot.S | 4 ++--
 arch/aarch64/psci.S | 3 +--
 arch/aarch64/spin.S | 3 +--
 5 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
index 820957b..4d16c9c 100644
--- a/arch/aarch32/boot.S
+++ b/arch/aarch32/boot.S
@@ -51,7 +51,7 @@ ASM_FUNC(_start)
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 _switch_monitor:
 	adr	lr, _monitor
@@ -69,8 +69,7 @@ _monitor:
 
 	bl	gic_secure_init
 
-	/* Initialise boot method */
-	b	start_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
index cdc36b0..6613b6f 100644
--- a/arch/aarch32/psci.S
+++ b/arch/aarch32/psci.S
@@ -38,6 +38,5 @@ handle_smc:
 	pop	{r4 - r12, lr}
 	movs	pc, lr
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	b	psci_first_spin
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index c0ec518..da5fa65 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -57,7 +57,7 @@ reset_at_el3:
 
 	bl	gic_secure_init
 
-	b	start_el3
+	b	start_bootmethod
 
 	/*
 	 * EL2 initialization
@@ -97,7 +97,7 @@ reset_no_el3:
 
 	bl	cpu_init_bootwrapper
 
-	b	start_no_el3
+	b	start_bootmethod
 
 err_invalid_id:
 	b	.
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index d6ca2eb..9709dbb 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -79,6 +79,5 @@ smc_exit:
 	ldp	x18, x19, [sp], #16
 	eret
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	b	psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 764c532..375f732 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -15,8 +15,7 @@
 ASM_FUNC(cpu_init_bootmethod)
 	ret
 
-ASM_FUNC(start_el3)
-ASM_FUNC(start_no_el3)
+ASM_FUNC(start_bootmethod)
 	cpuid	x0, x1
 	bl	find_logical_id
 
-- 
2.30.2



From joey.gouly at arm.com  Tue Jan 25 07:09:13 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:13 +0000
Subject: [PATCH v1 0/7] add more tests to MTE kselftests
Message-ID: <20220125150920.23955-1-joey.gouly@arm.com>

This is a series which refactors and then adds some extra tests for MTE
in the kselftest framework.

The issue that these tests are for was was fixed by Robin in
295cf156231c ("arm64: Avoid premature usercopy failure") and based on a
simplified example by Catalin [1].

They test some combinations of pointer offsets, sizes and syscalls to
exercise different paths in the kernel.

Thanks,
Joey

[1] https://lore.kernel.org/all/20210624150911.GA25097 at arm.com/

Joey Gouly (7):
  kselftest/arm64: mte: user_mem: introduce tag_offset and tag_len
  kselftest/arm64: mte: user_mem: add tests using tag_offset
  kselftest/arm64: mte: user_mem: add test with mte tag inside a page
  kselftest/arm64: mte: user_mem: rework error handling
  kselftest/arm64: mte: user_mem: check different offsets and sizes
  kselftest/arm64: mte: add test type enum
  kselftest/arm64: mte: add more test types

 .../selftests/arm64/mte/check_user_mem.c      | 145 ++++++++++++++----
 1 file changed, 112 insertions(+), 33 deletions(-)

-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:16 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:16 +0000
Subject: [PATCH v1 3/7] kselftest/arm64: mte: user_mem: add test with mte tag
 inside a page
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-4-joey.gouly@arm.com>

This new test has a tag that is only a single MT_GRANULE_SIZE large.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 tools/testing/selftests/arm64/mte/check_user_mem.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index d33b262ccdb0..3497960851a9 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -107,7 +107,7 @@ int main(int argc, char *argv[])
 	mte_register_signal(SIGSEGV, mte_default_handler);
 
 	/* Set test plan */
-	ksft_set_plan(8);
+	ksft_set_plan(9);
 
 	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz),
 		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: page_sz)\n");
@@ -129,6 +129,10 @@ int main(int argc, char *argv[])
 	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE),
 		"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
 
+	// In this test, the tag only covers MT_GRANULE_SIZE.
+	evaluate_test(check_usermem_access_fault_helper(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE, MT_GRANULE_SIZE),
+		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE, tag_len: MT_GRANULE_SIZE)\n");
+
 	mte_restore_setup();
 	ksft_print_cnts();
 	return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL;
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:15 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:15 +0000
Subject: [PATCH v1 2/7] kselftest/arm64: mte: user_mem: add tests using
 tag_offset
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-3-joey.gouly@arm.com>

Add some tests that place the different tag at MT_GRANULE_SIZE to check
that less than a full page can also be read.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../selftests/arm64/mte/check_user_mem.c      | 38 ++++++++++++-------
 1 file changed, 25 insertions(+), 13 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index 3ad9d85ca9b7..d33b262ccdb0 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -84,8 +84,10 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	return err;
 }
 
-static int check_usermem_access_fault(int mem_type, int mode, int mapping) {
-	return check_usermem_access_fault_helper(mem_type, mode, mapping, page_sz, 0);
+static int check_usermem_access_fault(int mem_type, int mode, int mapping,
+                                      int tag_offset) {
+	return check_usermem_access_fault_helper(mem_type, mode, mapping,
+	                                         tag_offset, 0);
 }
 
 int main(int argc, char *argv[])
@@ -105,17 +107,27 @@ int main(int argc, char *argv[])
 	mte_register_signal(SIGSEGV, mte_default_handler);
 
 	/* Set test plan */
-	ksft_set_plan(4);
-
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE),
-		"Check memory access from kernel in sync mode, private mapping and mmap memory\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED),
-		"Check memory access from kernel in sync mode, shared mapping and mmap memory\n");
-
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE),
-		"Check memory access from kernel in async mode, private mapping and mmap memory\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED),
-		"Check memory access from kernel in async mode, shared mapping and mmap memory\n");
+	ksft_set_plan(8);
+
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz),
+		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: page_sz)\n");
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, page_sz),
+		"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
+
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, page_sz),
+		"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: page_sz)\n");
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, page_sz),
+		"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
+
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE),
+		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE),
+		"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE),
+		"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE),
+		"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
 
 	mte_restore_setup();
 	ksft_print_cnts();
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:14 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:14 +0000
Subject: [PATCH v1 1/7] kselftest/arm64: mte: user_mem: introduce tag_offset
 and tag_len
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-2-joey.gouly@arm.com>

These can be used to place a different tag not at a page size boundary.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../testing/selftests/arm64/mte/check_user_mem.c  | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index 1de7a0abd0ae..3ad9d85ca9b7 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -19,7 +19,8 @@
 
 static size_t page_sz;
 
-static int check_usermem_access_fault(int mem_type, int mode, int mapping)
+static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping,
+                                             int tag_offset, int tag_len)
 {
 	int fd, i, err;
 	char val = 'A';
@@ -54,10 +55,12 @@ static int check_usermem_access_fault(int mem_type, int mode, int mapping)
 	if (i < len)
 		goto usermem_acc_err;
 
-	/* Tag the next half of memory with different value */
-	ptr_next = (void *)((unsigned long)ptr + page_sz);
+	if (!tag_len)
+		tag_len = len - tag_offset;
+	/* Tag a part of memory with different value */
+	ptr_next = (void *)((unsigned long)ptr + tag_offset);
 	ptr_next = mte_insert_new_tag(ptr_next);
-	mte_set_tag_address_range(ptr_next, page_sz);
+	mte_set_tag_address_range(ptr_next, tag_len);
 
 	lseek(fd, 0, 0);
 	/* Copy from file into buffer with invalid tag */
@@ -81,6 +84,10 @@ static int check_usermem_access_fault(int mem_type, int mode, int mapping)
 	return err;
 }
 
+static int check_usermem_access_fault(int mem_type, int mode, int mapping) {
+	return check_usermem_access_fault_helper(mem_type, mode, mapping, page_sz, 0);
+}
+
 int main(int argc, char *argv[])
 {
 	int err;
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:18 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:18 +0000
Subject: [PATCH v1 5/7] kselftest/arm64: mte: user_mem: check different
 offsets and sizes
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-6-joey.gouly@arm.com>

Iterate over different file offsets, pointer offsets and buffer sizes to exercise
and test different behaviour.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../selftests/arm64/mte/check_user_mem.c      | 49 +++++++++++--------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index f54143ec057a..8b1b586f3df8 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -26,6 +26,8 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	char val = 'A';
 	size_t len, read_len;
 	void *ptr, *ptr_next;
+	int fileoff, ptroff, size;
+	int sizes[] = {1, 2, 3, 8, 16, 32, 4096};
 
 	err = KSFT_PASS;
 	len = 2 * page_sz;
@@ -66,26 +68,33 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	ptr_next = mte_insert_new_tag(ptr_next);
 	mte_set_tag_address_range(ptr_next, tag_len);
 
-	lseek(fd, 0, 0);
-	/* Copy from file into buffer with invalid tag */
-	read_len = read(fd, ptr, len);
-	mte_wait_after_trig();
-	/*
-	 * Accessing user memory in kernel with invalid tag should fail in sync
-	 * mode without fault but may not fail in async mode as per the
-	 * implemented MTE userspace support in Arm64 kernel.
-	 */
-	if (cur_mte_cxt.fault_valid) {
-		err = KSFT_FAIL;
-		goto usermem_acc_err;
-	}
-	if (mode == MTE_SYNC_ERR && read_len < len) {
-		/* test passed */
-	} else if (mode == MTE_ASYNC_ERR && read_len == len) {
-		/* test passed */
-	} else {
-		err = KSFT_FAIL;
-		goto usermem_acc_err;
+	for (fileoff = 0; fileoff < 16; fileoff++) {
+		for (ptroff = 0; ptroff < 16; ptroff++) {
+			for (i = 0; i < ARRAY_SIZE(sizes); i++) {
+				size = sizes[i];
+				lseek(fd, 0, 0);
+				/* Copy from file into buffer with invalid tag */
+				read_len = read(fd, ptr + ptroff, size);
+				mte_wait_after_trig();
+				/*
+				 * Accessing user memory in kernel with invalid tag should fail in sync
+				 * mode without fault but may not fail in async mode as per the
+				 * implemented MTE userspace support in Arm64 kernel.
+				 */
+				if (cur_mte_cxt.fault_valid) {
+					err = KSFT_FAIL;
+					goto usermem_acc_err;
+				}
+				if (mode == MTE_SYNC_ERR && read_len < len) {
+					/* test passed */
+				} else if (mode == MTE_ASYNC_ERR && read_len == size) {
+					/* test passed */
+				} else {
+					err = KSFT_FAIL;
+					goto usermem_acc_err;
+				}
+			}
+		}
 	}
 usermem_acc_err:
 	mte_free_memory((void *)ptr, len, mem_type, true);
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:17 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:17 +0000
Subject: [PATCH v1 4/7] kselftest/arm64: mte: user_mem: rework error handling
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-5-joey.gouly@arm.com>

This makes it easier to have multiple iterations in the test.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../selftests/arm64/mte/check_user_mem.c      | 27 ++++++++++++-------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index 3497960851a9..f54143ec057a 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -27,7 +27,7 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	size_t len, read_len;
 	void *ptr, *ptr_next;
 
-	err = KSFT_FAIL;
+	err = KSFT_PASS;
 	len = 2 * page_sz;
 	mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG);
 	fd = create_temp_file();
@@ -46,14 +46,18 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	/* Copy from file into buffer with valid tag */
 	read_len = read(fd, ptr, len);
 	mte_wait_after_trig();
-	if (cur_mte_cxt.fault_valid || read_len < len)
+	if (cur_mte_cxt.fault_valid || read_len < len) {
+		err = KSFT_FAIL;
 		goto usermem_acc_err;
+	}
 	/* Verify same pattern is read */
 	for (i = 0; i < len; i++)
 		if (*(char *)(ptr + i) != val)
 			break;
-	if (i < len)
+	if (i < len) {
+		err = KSFT_FAIL;
 		goto usermem_acc_err;
+	}
 
 	if (!tag_len)
 		tag_len = len - tag_offset;
@@ -71,12 +75,17 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	 * mode without fault but may not fail in async mode as per the
 	 * implemented MTE userspace support in Arm64 kernel.
 	 */
-	if (mode == MTE_SYNC_ERR &&
-	    !cur_mte_cxt.fault_valid && read_len < len) {
-		err = KSFT_PASS;
-	} else if (mode == MTE_ASYNC_ERR &&
-		   !cur_mte_cxt.fault_valid && read_len == len) {
-		err = KSFT_PASS;
+	if (cur_mte_cxt.fault_valid) {
+		err = KSFT_FAIL;
+		goto usermem_acc_err;
+	}
+	if (mode == MTE_SYNC_ERR && read_len < len) {
+		/* test passed */
+	} else if (mode == MTE_ASYNC_ERR && read_len == len) {
+		/* test passed */
+	} else {
+		err = KSFT_FAIL;
+		goto usermem_acc_err;
 	}
 usermem_acc_err:
 	mte_free_memory((void *)ptr, len, mem_type, true);
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:19 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:19 +0000
Subject: [PATCH v1 6/7] kselftest/arm64: mte: add test type enum
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-7-joey.gouly@arm.com>

This enum will be used to parameterise the test to perform other syscalls
than 'read'.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../selftests/arm64/mte/check_user_mem.c      | 83 +++++++++++--------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index 8b1b586f3df8..d104feab4e86 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -19,12 +19,18 @@
 
 static size_t page_sz;
 
+enum test_type {
+	READ_TEST,
+	LAST_TEST,
+};
+
 static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping,
-                                             int tag_offset, int tag_len)
+                                             int tag_offset, int tag_len,
+                                             enum test_type test_type)
 {
 	int fd, i, err;
 	char val = 'A';
-	size_t len, read_len;
+	ssize_t len, syscall_len;
 	void *ptr, *ptr_next;
 	int fileoff, ptroff, size;
 	int sizes[] = {1, 2, 3, 8, 16, 32, 4096};
@@ -46,9 +52,9 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 	}
 	mte_initialize_current_context(mode, (uintptr_t)ptr, len);
 	/* Copy from file into buffer with valid tag */
-	read_len = read(fd, ptr, len);
+	syscall_len = read(fd, ptr, len);
 	mte_wait_after_trig();
-	if (cur_mte_cxt.fault_valid || read_len < len) {
+	if (cur_mte_cxt.fault_valid || syscall_len < len) {
 		err = KSFT_FAIL;
 		goto usermem_acc_err;
 	}
@@ -73,8 +79,16 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 			for (i = 0; i < ARRAY_SIZE(sizes); i++) {
 				size = sizes[i];
 				lseek(fd, 0, 0);
-				/* Copy from file into buffer with invalid tag */
-				read_len = read(fd, ptr + ptroff, size);
+
+				/* perform file operation on buffer with invalid tag */
+				switch (test_type) {
+				case READ_TEST:
+					syscall_len = read(fd, ptr + ptroff, size);
+					break;
+				case LAST_TEST:
+					goto usermem_acc_err;
+				}
+
 				mte_wait_after_trig();
 				/*
 				 * Accessing user memory in kernel with invalid tag should fail in sync
@@ -85,9 +99,9 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 					err = KSFT_FAIL;
 					goto usermem_acc_err;
 				}
-				if (mode == MTE_SYNC_ERR && read_len < len) {
+				if (mode == MTE_SYNC_ERR && syscall_len < len) {
 					/* test passed */
-				} else if (mode == MTE_ASYNC_ERR && read_len == size) {
+				} else if (mode == MTE_ASYNC_ERR && syscall_len == size) {
 					/* test passed */
 				} else {
 					err = KSFT_FAIL;
@@ -103,14 +117,15 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 }
 
 static int check_usermem_access_fault(int mem_type, int mode, int mapping,
-                                      int tag_offset) {
+                                      int tag_offset, enum test_type test_type) {
 	return check_usermem_access_fault_helper(mem_type, mode, mapping,
-	                                         tag_offset, 0);
+	                                         tag_offset, 0, test_type);
 }
 
 int main(int argc, char *argv[])
 {
 	int err;
+	int t;
 
 	page_sz = getpagesize();
 	if (!page_sz) {
@@ -127,29 +142,31 @@ int main(int argc, char *argv[])
 	/* Set test plan */
 	ksft_set_plan(9);
 
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz),
-		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: page_sz)\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, page_sz),
-		"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
-
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, page_sz),
-		"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: page_sz)\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, page_sz),
-		"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
-
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE),
-		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE),
-		"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
-
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE),
-		"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
-	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE),
-		"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
-
-	// In this test, the tag only covers MT_GRANULE_SIZE.
-	evaluate_test(check_usermem_access_fault_helper(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE, MT_GRANULE_SIZE),
-		"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE, tag_len: MT_GRANULE_SIZE)\n");
+	for (t = 0; t < LAST_TEST; t++) {
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz, t),
+			"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: page_sz)\n");
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, page_sz, t),
+			"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
+
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, page_sz, t),
+			"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: page_sz)\n");
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, page_sz, t),
+			"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: page_sz)\n");
+
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE, t),
+			"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE, t),
+			"Check memory access from kernel in sync mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE, t),
+			"Check memory access from kernel in async mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_ASYNC_ERR, MAP_SHARED, MT_GRANULE_SIZE, t),
+			"Check memory access from kernel in async mode, shared mapping and mmap memory (tag_offset: MT_GRANULE_SIZE)\n");
+
+		// In this test, the tag only covers MT_GRANULE_SIZE.
+		evaluate_test(check_usermem_access_fault_helper(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, MT_GRANULE_SIZE, MT_GRANULE_SIZE, t),
+			"Check memory access from kernel in sync mode, private mapping and mmap memory (tag_offset: MT_GRANULE_SIZE, tag_len: MT_GRANULE_SIZE)\n");
+	}
 
 	mte_restore_setup();
 	ksft_print_cnts();
-- 
2.17.1



From joey.gouly at arm.com  Tue Jan 25 07:09:20 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Tue, 25 Jan 2022 15:09:20 +0000
Subject: [PATCH v1 7/7] kselftest/arm64: mte: add more test types
In-Reply-To: <20220125150920.23955-1-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
Message-ID: <20220125150920.23955-8-joey.gouly@arm.com>

Add test support for write, readv, and writev.

Signed-off-by: Joey Gouly <joey.gouly at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
---
 .../selftests/arm64/mte/check_user_mem.c      | 23 ++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/mte/check_user_mem.c b/tools/testing/selftests/arm64/mte/check_user_mem.c
index d104feab4e86..df4c8d8c9c17 100644
--- a/tools/testing/selftests/arm64/mte/check_user_mem.c
+++ b/tools/testing/selftests/arm64/mte/check_user_mem.c
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <ucontext.h>
 #include <unistd.h>
+#include <sys/uio.h>
 #include <sys/mman.h>
 
 #include "kselftest.h"
@@ -21,6 +22,9 @@ static size_t page_sz;
 
 enum test_type {
 	READ_TEST,
+	WRITE_TEST,
+	READV_TEST,
+	WRITEV_TEST,
 	LAST_TEST,
 };
 
@@ -85,6 +89,23 @@ static int check_usermem_access_fault_helper(int mem_type, int mode, int mapping
 				case READ_TEST:
 					syscall_len = read(fd, ptr + ptroff, size);
 					break;
+				case WRITE_TEST:
+					syscall_len = write(fd, ptr + ptroff, size);
+					break;
+				case READV_TEST: {
+					struct iovec iov[1];
+					iov[0].iov_base = ptr + ptroff;
+					iov[0].iov_len = size;
+					syscall_len = readv(fd, iov, 1);
+					break;
+				}
+				case WRITEV_TEST: {
+					struct iovec iov[1];
+					iov[0].iov_base = ptr + ptroff;
+					iov[0].iov_len = size;
+					syscall_len = writev(fd, iov, 1);
+					break;
+				}
 				case LAST_TEST:
 					goto usermem_acc_err;
 				}
@@ -140,7 +161,7 @@ int main(int argc, char *argv[])
 	mte_register_signal(SIGSEGV, mte_default_handler);
 
 	/* Set test plan */
-	ksft_set_plan(9);
+	ksft_set_plan(36);
 
 	for (t = 0; t < LAST_TEST; t++) {
 		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz, t),
-- 
2.17.1



From maz at kernel.org  Tue Jan 25 07:10:52 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 15:10:52 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YeBfj89mIf8SezfD@google.com>
References: <20220104194918.373612-1-rananta@google.com>
 <20220104194918.373612-2-rananta@google.com>
 <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
Message-ID: <87pmof7sw3.wl-maz@kernel.org>

It's probably time I jump on this thread

On Thu, 13 Jan 2022 17:21:19 +0000,
Sean Christopherson <seanjc at google.com> wrote:
> 
> On Wed, Jan 12, 2022, Raghavendra Rao Ananta wrote:
> > On Tue, Jan 11, 2022 at 11:16 AM Jim Mattson <jmattson at google.com> wrote:
> > > Perhaps it would help if you explained *why* you are doing this. It
> > > sounds like you are either trying to protect against a malicious
> > > userspace, or you are trying to keep userspace from doing something
> > > stupid. In general, kvm only enforces constraints that are necessary
> > > to protect the host. If that's what you're doing, I don't understand
> > > why live migration doesn't provide an end-run around your protections.
> > It's mainly to safeguard the guests. With respect to migration, KVM
> > and the userspace are collectively playing a role here. It's up to the
> > userspace to ensure that the registers are configured the same across
> > migrations and KVM ensures that the userspace doesn't modify the
> > registers after KVM_RUN so that they don't see features turned OFF/ON
> > during execution. I'm not sure if it falls into the definition of
> > protecting the host. Do you see a value in adding this extra
> > protection from KVM?
> 
> Short answer: probably not?

Well, I beg to defer.

> There is precedent for disallowing userspace from doing stupid
> things, but that's either for KVM's protection (as Jim pointed out),
> or because KVM can't honor the change, e.g. x86 is currently in the
> process of disallowing most CPUID changes after KVM_RUN because KVM
> itself consumes the CPUID information and KVM doesn't support
> updating some of it's own internal state (because removing features
> like GB hugepage support is nonsensical and would require a large
> pile of complicated, messy code).

We provide quite a lot of CPU emulation based on the feature
registers exposed to the guest. Allowing userspace to change this
stuff once the guest is running is a massive attack vector.

> Restricing CPUID changes does offer some "protection" to the guest, but that's
> not the goal.  E.g. KVM won't detect CPUID misconfiguration in the migration
> case, and trying to do so is a fool's errand.
> 
> If restricting updates in the arm64 is necessary to ensure KVM provides sane
> behavior, then it could be justified.  But if it's purely a sanity check on
> behalf of the guest, then it's not justified.

No. This is about preventing userspace from tripping the kernel into
doing things it really shouldn't by flipping bits of configuration
that should be set in stone.

	M.

-- 
Without deviation from the norm, progress is not possible.


From dave.hansen at intel.com  Tue Jan 25 07:12:58 2022
From: dave.hansen at intel.com (Dave Hansen)
Date: Tue, 25 Jan 2022 07:12:58 -0800
Subject: [PATCH 0/8] Add hardware prefetch control driver for arm64 and x86
In-Reply-To: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
Message-ID: <931f6d2a-9001-e736-e7e2-7f86f87539cc@intel.com>

On 1/24/22 23:14, Kohei Tarumizu wrote:
> # cat /sys/devices/system/cpu/cpu1/cache/index2/prefetch_control
> 
> hardware_prefetcher_enable=enable
> adjacent_cache_line_prefetcher_enable=disable

Doesn't this break the one-value-per-file sysfs rules?



From maz at kernel.org  Tue Jan 25 07:15:54 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 15:15:54 +0000
Subject: [RFC PATCH v3 01/11] KVM: Capture VM start
In-Reply-To: <YedWUJNnQK3HFrWC@google.com>
References: <CAAeT=Fxyct=WLUvfbpROKwB9huyt+QdJnKTaj8c5NKk+UY51WQ@mail.gmail.com>
 <CAJHc60za+E-zEO5v2QeKuifoXznPnt5n--g1dAN5jgsuq+SxrA@mail.gmail.com>
 <CALMp9eQDzqoJMck=_agEZNU9FJY9LB=iW-8hkrRc20NtqN=gDA@mail.gmail.com>
 <CAJHc60xZ9emY9Rs9ZbV+AH-Mjmkyg4JZU7V16TF48C-HJn+n4A@mail.gmail.com>
 <CALMp9eTPJZDtMiHZ5XRiYw2NR9EBKSfcP5CYddzyd2cgWsJ9hw@mail.gmail.com>
 <CAJHc60xD2U36pM4+Dq3yZw6Cokk-16X83JHMPXj4aFnxOJ3BUQ@mail.gmail.com>
 <CALMp9eR+evJ+w9VTSvR2KHciQDgTsnS=bh=1OUL4yy8gG6O51A@mail.gmail.com>
 <CAJHc60zw1o=JdUJ+sNNtv3mc_JTRMKG3kPp=-cchWkHm74hUYA@mail.gmail.com>
 <YeBfj89mIf8SezfD@google.com>
 <CAAeT=Fz2q4PfJMXes3A9f+c01NnyORbvUrzJZO=ew-LsjPq2jQ@mail.gmail.com>
 <YedWUJNnQK3HFrWC@google.com>
Message-ID: <87o83z7snp.wl-maz@kernel.org>

On Wed, 19 Jan 2022 00:07:44 +0000,
Sean Christopherson <seanjc at google.com> wrote:
> 
> On Fri, Jan 14, 2022, Reiji Watanabe wrote:
> > The restriction, with which KVM doesn't need to worry about the changes
> > in the registers after KVM_RUN, could potentially protect or be useful
> > to protect KVM and simplify future changes/maintenance of the KVM codes
> > that consumes the values.
> 
> That sort of protection is definitely welcome, the previously mentioned CPUID mess
> on x86 would have benefit greatly by KVM being restrictive in the past.  That said,
> hooking KVM_RUN is likely the wrong way to go about implementing any restrictions.
> Running a vCPU is where much of the vCPU's state is explicitly consumed, but it's
> all too easy for KVM to implicity/indirectly consume state via a different ioctl(),
> e.g. if there are side effects that are visible in other registers, than an update
> can also be visible to userspace via KVM_{G,S}ET_{S,}REGS, at which point disallowing
> modifying state after KVM_RUN but not after reading/writing regs is arbitrary and
> inconsitent.
> 
> If possible, preventing modification if kvm->created_vcpus > 0 is
> ideal as it's a relatively common pattern in KVM, and provides a
> clear boundary to userpace regarding what is/isn't allowed.

No, that's way too late. The configuration is in general per-CPU, and
I really don't want to expand the surface of the userspace API to
allow all sort of magic trick depending on the nature of what you
save/restore.

The "first run" crap is already there. We have it on a per-CPU basis,
and we need it at the VM level for other reasons (see the recent
discussion about PMU filtering vs binding to a specific PMU
implementation).

	M.

-- 
Without deviation from the norm, progress is not possible.


From mark.rutland at arm.com  Tue Jan 25 07:23:20 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:23:20 +0000
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
In-Reply-To: <20220122023447.1480995-1-eugenis@google.com>
References: <20220122023447.1480995-1-eugenis@google.com>
Message-ID: <YfAV6FTN5g6jZGj7@FVFF77S0Q05N>

On Fri, Jan 21, 2022 at 06:34:47PM -0800, Evgenii Stepanov wrote:
> ex_handler_load_unaligned_zeropad extracts the source and data register
> numbers from the wrong field of the exception table.

Ouch. Did you find this by inspection, or did this show up in testing?

Sorry about this.

I think we should be a little more explicit as to exactly what goes wrong. How
about:

| In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
| addr register indices from ex->type rather than ex->data. As ex->type will
| contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
| 
| * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
|   extracted from bits [9:5]. Thus, we may attempt to dereference an arbitrary
|   address as X0 may hold an arbitary value.
| 
| * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
|   extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
|   behaviour within load_unaligned_zeropad() and its caller.
| 
| Fix this by extracting both values from ex->data as originally intended.

> Fixes: 753b3236

That should be expanded, e.g.

  Fixes: 753b32368705c396 ("arm64: extable: add load_unaligned_zeropad() handler")

With those changes:

Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Thanks,
Mark.

> Signed-off-by: Evgenii Stepanov <eugenis at google.com>
> ---
>  arch/arm64/mm/extable.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
> index c0181e60cc98..489455309695 100644
> --- a/arch/arm64/mm/extable.c
> +++ b/arch/arm64/mm/extable.c
> @@ -40,8 +40,8 @@ static bool
>  ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex,
>  				  struct pt_regs *regs)
>  {
> -	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->type);
> -	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->type);
> +	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data);
> +	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data);
>  	unsigned long data, addr, offset;
>  
>  	addr = pt_regs_read_reg(regs, reg_addr);
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 


From liviu.dudau at arm.com  Tue Jan 25 07:24:24 2022
From: liviu.dudau at arm.com (Liviu Dudau)
Date: Tue, 25 Jan 2022 15:24:24 +0000
Subject: [PATCH] arm64: dts: juno: Remove GICv2m dma-range
In-Reply-To: <856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com>
References: <856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com>
Message-ID: <YfAWKL86ofCxUYul@e110455-lin.cambridge.arm.com>

On Mon, Jan 24, 2022 at 05:57:01PM +0000, Robin Murphy wrote:
> Although it is painstakingly honest to describe all 3 PCI windows in
> "dma-ranges", it misses the the subtle distinction that the window for
> the GICv2m range is normally programmed for Device memory attributes
> rather than Normal Cacheable like the DRAM windows. Since MMU-401 only
> offers stage 2 translation, this means that when the PCI SMMU is
> enabled, accesses through that IPA range unexpectedly lose coherency if
> mapped as cacheable at the SMMU, due to the attribute combining rules.
> Since an extra 256KB is neither here nor there when we still have 10GB
> worth of usable address space, rather than attempting to describe and
> cope with this detail let's just remove the offending range. If the SMMU
> is not used then it makes no difference anyway.
> 
> Fixes: 4ac4d146cb63 ("arm64: dts: juno: Describe PCI dma-ranges")
> Reported-by: Anders Roxell <anders.roxell at linaro.org>
> Signed-off-by: Robin Murphy <robin.murphy at arm.com>

Looks like a good idea.

Acked-by: Liviu Dudau <liviu.dudau at arm.com>

Sudeep, can you pick this one up through your tree?

Best regards,
Liviu

> ---
> 
> Sorry it took a while to catch up on this...
> 
>  arch/arm64/boot/dts/arm/juno-base.dtsi | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
> index 6288e104a089..a2635b14da30 100644
> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi
> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
> @@ -543,8 +543,7 @@ pcie_ctlr: pcie at 40000000 {
>  			 <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
>  			 <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
>  		/* Standard AXI Translation entries as programmed by EDK2 */
> -		dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
> -			     <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
> +		dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
>  			     <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
>  		#interrupt-cells = <1>;
>  		interrupt-map-mask = <0 0 0 7>;
> -- 
> 2.28.0.dirty
> 

-- 
====================
| I would like to |
| fix the world,  |
| but they're not |
| giving me the   |
 \ source code!  /
  ---------------
    ?\_(?)_/?


From ardb at kernel.org  Tue Jan 25 07:28:11 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:28:11 +0100
Subject: [PATCH v2 0/7] linkage: better symbol aliasing
In-Reply-To: <20220125113200.3829108-1-mark.rutland@arm.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
Message-ID: <CAMj1kXGCFFHzZAqhfmJthGCe6uhFsrHwzK0QyOfrGw7_kNbjWQ@mail.gmail.com>

On Tue, 25 Jan 2022 at 12:32, Mark Rutland <mark.rutland at arm.com> wrote:
>
> This series aims to make symbol aliasing simpler and more consistent.
> The basic idea is to replace SYM_FUNC_START_ALIAS(alias) and
> SYM_FUNC_END_ALIAS(alias) with a new SYM_FUNC_ALIAS(alias, name), so
> that e.g.
>
>     SYM_FUNC_START(func)
>     SYM_FUNC_START_ALIAS(alias1)
>     SYM_FUNC_START_ALIAS(alias2)
>         ... asm insns ...
>     SYM_FUNC_END(func)
>     SYM_FUNC_END_ALIAS(alias1)
>     SYM_FUNC_END_ALIAS(alias2)
>     EXPORT_SYMBOL(alias1)
>     EXPORT_SYMBOL(alias2)
>
> ... can become:
>
>     SYM_FUNC_START(name)
>         ... asm insns ...
>     SYM_FUNC_END(name)
>
>     SYM_FUNC_ALIAS(alias1, func)
>     EXPORT_SYMBOL(alias1)
>
>     SYM_FUNC_ALIAS(alias2, func)
>     EXPORT_SYMBOL(alias2)
>
> This avoids repetition and hopefully make it easier to ensure
> consistency (e.g. so each function has a single canonical name and
> associated metadata).
>

I take it this affects the sizes of the alias ELF symbols? Does that matter?


From ardb at kernel.org  Tue Jan 25 07:36:48 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:48 +0100
Subject: [PATCH 0/8] ARM: ftrace fixes and cleanups
Message-ID: <20220125153656.1802079-1-ardb@kernel.org>

This series addresses a number of issues in the ARM support code for
ftrace, mostly related to Thumb2 but affecting other configurations as
well.

Cc: Russell King <linux at armlinux.org.uk>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Linus Walleij <linus.walleij at linaro.org>
Cc: Nick Desaulniers <ndesaulniers at google.com>

Ard Biesheuvel (8):
  ARM: ftrace: ensure that ADR take Thumb bit into account
  ARM: ftrace: use ADD not POP to counter PUSH at entry
  ARM: ftrace: use trampolines to keep .init.text in branching range
  ARM: ftrace: avoid redundant loads or clobbering IP
  ARM: ftrace: avoid unnecessary literal loads
  ARM: ftrace: enable HAVE_FUNCTION_GRAPH_FP_TEST
  ARM: unwind: track location of LR value in stack frame
  ARM: ftrace: enable the graph tracer with the EABI unwinder

 arch/arm/Kconfig                  |   2 +-
 arch/arm/Kconfig.debug            |   2 +-
 arch/arm/include/asm/ftrace.h     |  20 +--
 arch/arm/include/asm/stacktrace.h |   2 +
 arch/arm/kernel/Makefile          |   6 +-
 arch/arm/kernel/entry-ftrace.S    | 128 +++++++++++---------
 arch/arm/kernel/ftrace.c          |  47 ++++++-
 arch/arm/kernel/unwind.c          |   7 +-
 8 files changed, 125 insertions(+), 89 deletions(-)

-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:49 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:49 +0100
Subject: [PATCH 1/8] ARM: ftrace: ensure that ADR take Thumb bit into account
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-2-ardb@kernel.org>

Using ADR to take the address of 'ftrace_stub' via a local label
produces an address that has the Thumb bit cleared, which means the
subsequent comparison is guaranteed to fail. Instead, use the badr
macro, which forces the Thumb bit to be set.

Fixes: a3ba87a61499 ("ARM: 6316/1: ftrace: add Thumb-2 support")
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-ftrace.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index a74289ebc803..f4886fb6e9ba 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -40,7 +40,7 @@
 	mcount_enter
 	ldr	r0, =ftrace_trace_function
 	ldr	r2, [r0]
-	adr	r0, .Lftrace_stub
+	badr	r0, .Lftrace_stub
 	cmp	r0, r2
 	bne	1f
 
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:51 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:51 +0100
Subject: [PATCH 3/8] ARM: ftrace: use trampolines to keep .init.text in
 branching range
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-4-ardb@kernel.org>

Kernel images that are large in comparison to the range of a direct
branch may fail to work as expected with ftrace, as patching a direct
branch to one of the core ftrace routines may not be possible from the
.init.text section, if it is emitted too far away from the normal .text
section.

This is more likely to affect Thumb2 builds, given that its range is
only -/+ 16 MiB (as opposed to ARM which has -/+ 32 MiB), but may occur
in either ISA.

To work around this, add a couple of trampolines to .init.text and
swap these in when the ftrace patching code is operating on callers in
.init.text.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-ftrace.S | 16 ++++++++++++++++
 arch/arm/kernel/ftrace.c       | 19 +++++++++++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index dca12a09322a..237d435e29aa 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -270,3 +270,19 @@ ENTRY(ftrace_stub)
 .Lftrace_stub:
 	ret	lr
 ENDPROC(ftrace_stub)
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+
+	__INIT
+
+	.macro	init_tramp, dst:req
+ENTRY(\dst\()_from_init)
+	ldr	pc, =\dst
+ENDPROC(\dst\()_from_init)
+	.endm
+
+	init_tramp	ftrace_caller
+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
+	init_tramp	ftrace_regs_caller
+#endif
+#endif
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index db72d3a6522d..d2326794fd09 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -51,9 +51,18 @@ static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
 	return NOP;
 }
 
+void ftrace_caller_from_init(void);
+void ftrace_regs_caller_from_init(void);
+
 static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
 {
-	return addr;
+	if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE) ||
+	    likely(!is_kernel_inittext(rec->ip)))
+		return addr;
+	if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) ||
+	    addr == (unsigned long)&ftrace_caller)
+		return (unsigned long)&ftrace_caller_from_init;
+	return (unsigned long)&ftrace_regs_caller_from_init;
 }
 
 int ftrace_arch_code_modify_prepare(void)
@@ -189,7 +198,13 @@ int ftrace_make_nop(struct module *mod,
 #endif
 
 	new = ftrace_nop_replace(rec);
-	ret = ftrace_modify_code(ip, old, new, true);
+	/*
+	 * Locations in .init.text may call __gnu_mcount_mc via a linker
+	 * emitted veneer if they are too far away from its implementation, and
+	 * so validation may fail spuriously in such cases. Let's work around
+	 * this by omitting those from validation.
+	 */
+	ret = ftrace_modify_code(ip, old, new, !is_kernel_inittext(ip));
 
 	return ret;
 }
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:50 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:50 +0100
Subject: [PATCH 2/8] ARM: ftrace: use ADD not POP to counter PUSH at entry
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-3-ardb@kernel.org>

The compiler emitted hook used for ftrace consists of a PUSH {LR} to
preserve the link register, followed by a branch-and-link (BL) to
__gnu_mount_nc. Dynamic ftrace patches away the latter to turn the
combined sequence into a NOP, using a POP {LR} instruction.

This is not necessary, since the link register does not get clobbered in
this case, and simply adding #4 to the stack pointer is sufficient, and
avoids a memory access that may take a few cycles to resolve depending
on the micro-architecture.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-ftrace.S | 2 +-
 arch/arm/kernel/ftrace.c       | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index f4886fb6e9ba..dca12a09322a 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -27,7 +27,7 @@
  * allows it to be clobbered in subroutines and doesn't use it to hold
  * parameters.)
  *
- * When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
+ * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
  * instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
  */
 
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index a006585e1c09..db72d3a6522d 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -25,9 +25,9 @@
 #include <asm/patch.h>
 
 #ifdef CONFIG_THUMB2_KERNEL
-#define	NOP		0xf85deb04	/* pop.w {lr} */
+#define	NOP		0xf10d0d04	/* add.w sp, sp, #4 */
 #else
-#define	NOP		0xe8bd4000	/* pop {lr} */
+#define	NOP		0xe28dd004	/* add   sp, sp, #4 */
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:52 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:52 +0100
Subject: [PATCH 4/8] ARM: ftrace: avoid redundant loads or clobbering IP
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-5-ardb@kernel.org>

Tweak the ftrace return paths to avoid redundant loads of SP, as well as
unnecessary clobbering of IP.

This also fixes the inconsistency of using MOV to perform a function
return, which is sub-optimal on recent micro-architectures but more
importantly, does not perform an interworking return, unlike compiler
generated function returns in Thumb2 builds.

Let's fix this by popping PC from the stack like most ordinary code
does.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-ftrace.S | 51 +++++++++-----------
 1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index 237d435e29aa..67548c38a567 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -22,10 +22,7 @@
  * mcount can be thought of as a function called in the middle of a subroutine
  * call.  As such, it needs to be transparent for both the caller and the
  * callee: the original lr needs to be restored when leaving mcount, and no
- * registers should be clobbered.  (In the __gnu_mcount_nc implementation, we
- * clobber the ip register.  This is OK because the ARM calling convention
- * allows it to be clobbered in subroutines and doesn't use it to hold
- * parameters.)
+ * registers should be clobbered.
  *
  * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
  * instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
@@ -70,26 +67,25 @@
 
 .macro __ftrace_regs_caller
 
-	sub	sp, sp, #8	@ space for PC and CPSR OLD_R0,
+	str	lr, [sp, #-8]!	@ store LR as PC and make space for CPSR/OLD_R0,
 				@ OLD_R0 will overwrite previous LR
 
-	add 	ip, sp, #12	@ move in IP the value of SP as it was
-				@ before the push {lr} of the mcount mechanism
+	ldr	lr, [sp, #8]    @ get previous LR
 
-	str     lr, [sp, #0]    @ store LR instead of PC
+	str	r0, [sp, #8]	@ write r0 as OLD_R0 over previous LR
 
-	ldr     lr, [sp, #8]    @ get previous LR
+	str	lr, [sp, #-4]!	@ store previous LR as LR
 
-	str	r0, [sp, #8]	@ write r0 as OLD_R0 over previous LR
+	add 	lr, sp, #16	@ move in LR the value of SP as it was
+				@ before the push {lr} of the mcount mechanism
 
-	stmdb   sp!, {ip, lr}
-	stmdb   sp!, {r0-r11, lr}
+	push	{r0-r11, ip, lr}
 
 	@ stack content at this point:
 	@ 0  4          48   52       56            60   64    68       72
-	@ R0 | R1 | ... | LR | SP + 4 | previous LR | LR | PSR | OLD_R0 |
+	@ R0 | R1 | ... | IP | SP + 4 | previous LR | LR | PSR | OLD_R0 |
 
-	mov r3, sp				@ struct pt_regs*
+	mov	r3, sp				@ struct pt_regs*
 
 	ldr r2, =function_trace_op
 	ldr r2, [r2]				@ pointer to the current
@@ -112,11 +108,9 @@ ftrace_graph_regs_call:
 #endif
 
 	@ pop saved regs
-	ldmia   sp!, {r0-r12}			@ restore r0 through r12
-	ldr	ip, [sp, #8]			@ restore PC
-	ldr	lr, [sp, #4]			@ restore LR
-	ldr	sp, [sp, #0]			@ restore SP
-	mov	pc, ip				@ return
+	pop	{r0-r11, ip, lr}		@ restore r0 through r12
+	ldr	lr, [sp], #4			@ restore LR
+	ldr	pc, [sp], #12
 .endm
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -132,11 +126,9 @@ ftrace_graph_regs_call:
 	bl	prepare_ftrace_return
 
 	@ pop registers saved in ftrace_regs_caller
-	ldmia   sp!, {r0-r12}			@ restore r0 through r12
-	ldr	ip, [sp, #8]			@ restore PC
-	ldr	lr, [sp, #4]			@ restore LR
-	ldr	sp, [sp, #0]			@ restore SP
-	mov	pc, ip				@ return
+	pop	{r0-r11, ip, lr}		@ restore r0 through r12
+	ldr	lr, [sp], #4			@ restore LR
+	ldr	pc, [sp], #12
 
 .endm
 #endif
@@ -202,16 +194,17 @@ ftrace_graph_call\suffix:
 .endm
 
 .macro mcount_exit
-	ldmia	sp!, {r0-r3, ip, lr}
-	ret	ip
+	ldmia	sp!, {r0-r3}
+	ldr	lr, [sp, #4]
+	ldr	pc, [sp], #8
 .endm
 
 ENTRY(__gnu_mcount_nc)
 UNWIND(.fnstart)
 #ifdef CONFIG_DYNAMIC_FTRACE
-	mov	ip, lr
-	ldmia	sp!, {lr}
-	ret	ip
+	push	{lr}
+	ldr	lr, [sp, #4]
+	ldr	pc, [sp], #8
 #else
 	__mcount
 #endif
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:53 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:53 +0100
Subject: [PATCH 5/8] ARM: ftrace: avoid unnecessary literal loads
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-6-ardb@kernel.org>

Avoid explicit literal loads and instead, use accessor macros that
generate the optimal sequence depending on the architecture revision
being targeted.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/kernel/entry-ftrace.S | 27 ++++++++------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index 67548c38a567..99720064a4c5 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -35,23 +35,20 @@
 
 .macro __mcount suffix
 	mcount_enter
-	ldr	r0, =ftrace_trace_function
-	ldr	r2, [r0]
+	ldr_va	r2, ftrace_trace_function
 	badr	r0, .Lftrace_stub
 	cmp	r0, r2
 	bne	1f
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-	ldr     r1, =ftrace_graph_return
-	ldr     r2, [r1]
-	cmp     r0, r2
-	bne     ftrace_graph_caller\suffix
-
-	ldr     r1, =ftrace_graph_entry
-	ldr     r2, [r1]
-	ldr     r0, =ftrace_graph_entry_stub
-	cmp     r0, r2
-	bne     ftrace_graph_caller\suffix
+	ldr_va	r2, ftrace_graph_return
+	cmp	r0, r2
+	bne	ftrace_graph_caller\suffix
+
+	ldr_va	r2, ftrace_graph_entry
+	mov_l	r0, ftrace_graph_entry_stub
+	cmp	r0, r2
+	bne	ftrace_graph_caller\suffix
 #endif
 
 	mcount_exit
@@ -87,8 +84,7 @@
 
 	mov	r3, sp				@ struct pt_regs*
 
-	ldr r2, =function_trace_op
-	ldr r2, [r2]				@ pointer to the current
+	ldr_va	r2, function_trace_op		@ pointer to the current
 						@ function tracing op
 
 	ldr	r1, [sp, #S_LR]			@ lr of instrumented func
@@ -141,8 +137,7 @@ ftrace_graph_regs_call:
 	mcount_adjust_addr	r0, lr		@ instrumented function
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
-	ldr r2, =function_trace_op
-	ldr r2, [r2]				@ pointer to the current
+	ldr_va	r2, function_trace_op		@ pointer to the current
 						@ function tracing op
 	mov r3, #0				@ regs is NULL
 #endif
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:54 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:54 +0100
Subject: [PATCH 6/8] ARM: ftrace: enable HAVE_FUNCTION_GRAPH_FP_TEST
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-7-ardb@kernel.org>

Fix the frame pointer handling in the function graph tracer entry and
exit code so we can enable HAVE_FUNCTION_GRAPH_FP_TEST. Instead of using
FP directly (which will have different values between the entry and exit
pieces of the function graph tracer), use the value of SP at entry and
exit, as we can derive the former value from the frame pointer.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/ftrace.h  | 2 ++
 arch/arm/kernel/entry-ftrace.S | 2 +-
 arch/arm/kernel/ftrace.c       | 5 +++++
 3 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index a4dbac07e4ef..b4f5fab6b04e 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -2,6 +2,8 @@
 #ifndef _ASM_ARM_FTRACE
 #define _ASM_ARM_FTRACE
 
+#define HAVE_FUNCTION_GRAPH_FP_TEST
+
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
 #define ARCH_SUPPORTS_FTRACE_OPS 1
 #endif
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index 99720064a4c5..bbfa0954c385 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -247,7 +247,7 @@ ENDPROC(ftrace_graph_regs_caller)
 	.globl return_to_handler
 return_to_handler:
 	stmdb	sp!, {r0-r3}
-	mov	r0, fp			@ frame pointer
+	add	r0, sp, #16		@ sp at exit of instrumented routine
 	bl	ftrace_return_to_handler
 	mov	lr, r0			@ r0 has real ret addr
 	ldmia	sp!, {r0-r3}
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index d2326794fd09..988525b274e3 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -220,6 +220,11 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 	if (unlikely(atomic_read(&current->tracing_graph_pause)))
 		return;
 
+	if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
+		/* FP points one word below parent's top of stack */
+		frame_pointer += 4;
+	}
+
 	old = *parent;
 	*parent = return_hooker;
 
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:56 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:56 +0100
Subject: [PATCH 8/8] ARM: ftrace: enable the graph tracer with the EABI
 unwinder
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-9-ardb@kernel.org>

Enable the function graph tracer in combination with the EABI unwinder,
so that Thumb2 builds or Clang ARM builds can make use of it.

This involves using the unwinder to locate the return address of an
instrumented function on the stack, so that it can be overridden and
made to refer to the ftrace handling routines that need to be called at
function return.

Given that for these builds, it is not guaranteed that the value of the
link register is stored on the stack, fall back to the stack slot that
will be used by the ftrace exit code to restore LR in the instrumented
function's execution context.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/Kconfig               |  2 +-
 arch/arm/Kconfig.debug         |  2 +-
 arch/arm/include/asm/ftrace.h  | 18 -------------
 arch/arm/kernel/Makefile       |  5 +---
 arch/arm/kernel/entry-ftrace.S | 28 ++++++++++++++------
 arch/arm/kernel/ftrace.c       | 19 +++++++++++--
 6 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index cbbe38f55088..e3c1a76d0a42 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -92,7 +92,7 @@ config ARM
 	select HAVE_EXIT_THREAD
 	select HAVE_FAST_GUP if ARM_LPAE
 	select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
-	select HAVE_FUNCTION_GRAPH_TRACER if !THUMB2_KERNEL && !CC_IS_CLANG
+	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !(THUMB2_KERNEL && CC_IS_CLANG)
 	select HAVE_GCC_PLUGINS
 	select HAVE_HW_BREAKPOINT if PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7)
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 976315dea958..0c9497d549e3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -65,7 +65,7 @@ config UNWINDER_FRAME_POINTER
 
 config UNWINDER_ARM
 	bool "ARM EABI stack unwinder"
-	depends on AEABI && !FUNCTION_GRAPH_TRACER
+	depends on AEABI
 	select ARM_UNWIND
 	help
 	  This option enables stack unwinding support in the kernel
diff --git a/arch/arm/include/asm/ftrace.h b/arch/arm/include/asm/ftrace.h
index b4f5fab6b04e..5358aad67831 100644
--- a/arch/arm/include/asm/ftrace.h
+++ b/arch/arm/include/asm/ftrace.h
@@ -35,26 +35,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
 
 #ifndef __ASSEMBLY__
 
-#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
-/*
- * return_address uses walk_stackframe to do it's work.  If both
- * CONFIG_FRAME_POINTER=y and CONFIG_ARM_UNWIND=y walk_stackframe uses unwind
- * information.  For this to work in the function tracer many functions would
- * have to be marked with __notrace.  So for now just depend on
- * !CONFIG_ARM_UNWIND.
- */
-
 void *return_address(unsigned int);
 
-#else
-
-static inline void *return_address(unsigned int level)
-{
-	return NULL;
-}
-
-#endif
-
 #define ftrace_return_address(n) return_address(n)
 
 #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 56511856ff9d..5cebb8d5a1d6 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -25,10 +25,7 @@ obj-y		:= elf.o entry-common.o irq.o opcodes.o \
 KASAN_SANITIZE_stacktrace.o := n
 KASAN_SANITIZE_traps.o := n
 
-ifneq ($(CONFIG_ARM_UNWIND),y)
-obj-$(CONFIG_FRAME_POINTER)	+= return_address.o
-endif
-
+obj-y				+= return_address.o
 obj-$(CONFIG_ATAGS)		+= atags_parse.o
 obj-$(CONFIG_ATAGS_PROC)	+= atags_proc.o
 obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o
diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
index bbfa0954c385..3e7bcaca5e07 100644
--- a/arch/arm/kernel/entry-ftrace.S
+++ b/arch/arm/kernel/entry-ftrace.S
@@ -100,7 +100,8 @@ ftrace_regs_call:
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	.globl ftrace_graph_regs_call
 ftrace_graph_regs_call:
-	mov	r0, r0
+ARM(	mov	r0, r0	)
+THUMB(	nop.w		)
 #endif
 
 	@ pop saved regs
@@ -112,13 +113,18 @@ ftrace_graph_regs_call:
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 .macro __ftrace_graph_regs_caller
 
-	sub     r0, fp, #4              @ lr of instrumented routine (parent)
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
+	sub	r0, fp, #4		@ lr of instrumented routine (parent)
+#else
+	add	r0, sp, #S_LR
+#endif
 
 	@ called from __ftrace_regs_caller
-	ldr     r1, [sp, #S_PC]		@ instrumented routine (func)
+	ldr	r1, [sp, #S_PC]		@ instrumented routine (func)
 	mcount_adjust_addr	r1, r1
 
-	mov	r2, fp			@ frame pointer
+	mov	r2, fpreg		@ frame pointer
+	add	r3, sp, #PT_REGS_SIZE
 	bl	prepare_ftrace_return
 
 	@ pop registers saved in ftrace_regs_caller
@@ -149,14 +155,19 @@ ftrace_call\suffix:
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	.globl ftrace_graph_call\suffix
 ftrace_graph_call\suffix:
-	mov	r0, r0
+ARM(	mov	r0, r0	)
+THUMB(	nop.w		)
 #endif
 
 	mcount_exit
 .endm
 
 .macro __ftrace_graph_caller
+#ifdef CONFIG_UNWINDER_FRAME_POINTER
 	sub	r0, fp, #4		@ &lr of instrumented routine (&parent)
+#else
+	add	r0, sp, #20
+#endif
 #ifdef CONFIG_DYNAMIC_FTRACE
 	@ called from __ftrace_caller, saved in mcount_enter
 	ldr	r1, [sp, #16]		@ instrumented routine (func)
@@ -165,7 +176,8 @@ ftrace_graph_call\suffix:
 	@ called from __mcount, untouched in lr
 	mcount_adjust_addr	r1, lr	@ instrumented routine (func)
 #endif
-	mov	r2, fp			@ frame pointer
+	mov	r2, fpreg		@ frame pointer
+	add	r3, sp, #24
 	bl	prepare_ftrace_return
 	mcount_exit
 .endm
@@ -244,14 +256,14 @@ ENDPROC(ftrace_graph_regs_caller)
 .purgem mcount_exit
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
-	.globl return_to_handler
-return_to_handler:
+ENTRY(return_to_handler)
 	stmdb	sp!, {r0-r3}
 	add	r0, sp, #16		@ sp at exit of instrumented routine
 	bl	ftrace_return_to_handler
 	mov	lr, r0			@ r0 has real ret addr
 	ldmia	sp!, {r0-r3}
 	ret	lr
+ENDPROC(return_to_handler)
 #endif
 
 ENTRY(ftrace_stub)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 988525b274e3..65aa9e1eface 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -22,6 +22,7 @@
 #include <asm/ftrace.h>
 #include <asm/insn.h>
 #include <asm/set_memory.h>
+#include <asm/stacktrace.h>
 #include <asm/patch.h>
 
 #ifdef CONFIG_THUMB2_KERNEL
@@ -211,8 +212,10 @@ int ftrace_make_nop(struct module *mod,
 #endif /* CONFIG_DYNAMIC_FTRACE */
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+asmlinkage
 void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
-			   unsigned long frame_pointer)
+			   unsigned long frame_pointer,
+			   unsigned long stack_pointer)
 {
 	unsigned long return_hooker = (unsigned long) &return_to_handler;
 	unsigned long old;
@@ -223,6 +226,18 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
 	if (IS_ENABLED(CONFIG_UNWINDER_FRAME_POINTER)) {
 		/* FP points one word below parent's top of stack */
 		frame_pointer += 4;
+	} else {
+		struct stackframe frame = {
+			.fp = frame_pointer,
+			.sp = stack_pointer,
+			.lr = self_addr,
+			.pc = self_addr,
+		};
+		if (unwind_frame(&frame) < 0)
+			return;
+		if (frame.lr != self_addr)
+			parent = frame.lr_addr;
+		frame_pointer = frame.sp;
 	}
 
 	old = *parent;
@@ -245,7 +260,7 @@ static int __ftrace_modify_caller(unsigned long *callsite,
 	unsigned long caller_fn = (unsigned long) func;
 	unsigned long pc = (unsigned long) callsite;
 	unsigned long branch = arm_gen_branch(pc, caller_fn);
-	unsigned long nop = 0xe1a00000;	/* mov r0, r0 */
+	unsigned long nop = arm_gen_nop();
 	unsigned long old = enable ? nop : branch;
 	unsigned long new = enable ? branch : nop;
 
-- 
2.30.2



From ardb at kernel.org  Tue Jan 25 07:36:55 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:36:55 +0100
Subject: [PATCH 7/8] ARM: unwind: track location of LR value in stack frame
In-Reply-To: <20220125153656.1802079-1-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
Message-ID: <20220125153656.1802079-8-ardb@kernel.org>

The ftrace graph tracer needs to override the return address of an
instrumented function, in order to install a hook that gets invoked when
the function returns again.

Currently, we only support this when building for ARM using GCC with
frame pointers, as in this case, it is guaranteed that the function will
reload LR from [FP, #-4] in all cases, and we can simply pass that
address to the ftrace code.

In order to support this for configurations that rely on the EABI
unwinder, such as Thumb2 builds, make the unwinder keep track of the
address from which LR was unwound, permitting ftrace to make use of this
in a subsequent patch.

Drop the call to is_kernel_text_address(), which is problematic in terms
of ftrace recursion, given that it may be instrumented itself. The call
is redundant anyway, as no unwind directives will be found unless the PC
points to memory that is known to contain executable code.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/include/asm/stacktrace.h | 2 ++
 arch/arm/kernel/Makefile          | 1 +
 arch/arm/kernel/unwind.c          | 7 ++++---
 3 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h
index d87d60532b86..e5ce7440cba8 100644
--- a/arch/arm/include/asm/stacktrace.h
+++ b/arch/arm/include/asm/stacktrace.h
@@ -27,6 +27,8 @@ struct stackframe {
 	 * executing from another stack.
 	 */
 	unsigned long sp_low;
+	/* address of the LR value on the stack */
+	unsigned long *lr_addr;
 #endif
 };
 
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index ae295a3bcfef..56511856ff9d 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -10,6 +10,7 @@ ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_insn.o = -pg
 CFLAGS_REMOVE_patch.o = -pg
+CFLAGS_REMOVE_unwind.o = -pg
 endif
 
 CFLAGS_REMOVE_return_address.o = -pg
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index c5ea328c428d..b4e468a7674b 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -55,6 +55,7 @@ struct unwind_ctrl_block {
 	const unsigned long *insn;	/* pointer to the current instructions word */
 	unsigned long sp_low;		/* lowest value of sp allowed */
 	unsigned long sp_high;		/* highest value of sp allowed */
+	unsigned long *lr_addr;		/* address of LR value on the stack */
 	/*
 	 * 1 : check for stack overflow for each register pop.
 	 * 0 : save overhead if there is plenty of stack remaining.
@@ -239,6 +240,8 @@ static int unwind_pop_register(struct unwind_ctrl_block *ctrl,
 	 * from being tracked by KASAN.
 	 */
 	ctrl->vrs[reg] = READ_ONCE_NOCHECK(*(*vsp));
+	if (reg == 14)
+		ctrl->lr_addr = *vsp;
 	(*vsp)++;
 	return URC_OK;
 }
@@ -395,9 +398,6 @@ int unwind_frame(struct stackframe *frame)
 	pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
 		 frame->pc, frame->lr, frame->sp);
 
-	if (!kernel_text_address(frame->pc))
-		return -URC_FAILURE;
-
 	idx = unwind_find_idx(frame->pc);
 	if (!idx) {
 		pr_warn("unwind: Index not found %08lx\n", frame->pc);
@@ -476,6 +476,7 @@ int unwind_frame(struct stackframe *frame)
 	frame->lr = ctrl.vrs[LR];
 	frame->pc = ctrl.vrs[PC];
 	frame->sp_low = ctrl.sp_low;
+	frame->lr_addr = ctrl.lr_addr;
 
 	return URC_OK;
 }
-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:37:59 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:37:59 +0000
Subject: [PATCH 0/4] KVM: arm64: A510 errata workaround and fixes for
 fixup_guest_exit()
Message-ID: <20220125153803.549084-1-james.morse@arm.com>

Hello!

Early Cortex-A510 parts have a nasty erratum where two ERETs,
pointer-auth and software step conspire to corrupt SPSR_EL2. A
guest can only trigger this when it is being stepped by EL2, which
gives EL2 the opportunity to work around the erratum. Patch 4 does
this, the SDEN is available from:
https://developer.arm.com/documentation/SDEN2397239/900

Patches 2 and 3 fix two issues with the adjacent code where a stale
esr value could be used to alter the ELR_EL2 when an IRQ synchronises
an SError, and when an HVC synchronises an SError, the HVC may be
handled twice, (not just execute twice).


There are three series that would add the Cortex-A510 part macros. I've picked
Anshuman's patch that does this, on the assumption that makes someone's life
easier. I haven't spotted that patch on the arm64/for-next/fixes branch, so
I've not included the hash in the prerequisite field of the CC-stable.

Let me know if you want this reposted once that value is known.

This series is based on v5.17-rc1 and can be retrieved from:
https://git.gitlab.arm.com/linux-arm/linux-jm.git a510_errata/kvm_bits/v1


Thanks,

James

Anshuman Khandual (1):
  arm64: Add Cortex-A510 CPU part definition

James Morse (3):
  KVM: arm64: Avoid consuming a stale esr value when SError occur
  KVM: arm64: Stop handle_exit() from handling HVC twice when an SError
    occurs
  KVM: arm64: Workaround Cortex-A510's single-step and PAC trap errata

 Documentation/arm64/silicon-errata.rst  |  2 ++
 arch/arm64/Kconfig                      | 16 +++++++++++++++
 arch/arm64/include/asm/cputype.h        |  2 ++
 arch/arm64/kernel/cpu_errata.c          |  8 ++++++++
 arch/arm64/kvm/handle_exit.c            |  8 ++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 27 +++++++++++++++++++++----
 arch/arm64/tools/cpucaps                |  1 +
 7 files changed, 60 insertions(+), 4 deletions(-)

-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:38:00 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:38:00 +0000
Subject: [PATCH 1/4] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <20220125153803.549084-1-james.morse@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
Message-ID: <20220125153803.549084-2-james.morse@arm.com>

From: Anshuman Khandual <anshuman.khandual at arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:38:01 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:38:01 +0000
Subject: [PATCH 2/4] KVM: arm64: Avoid consuming a stale esr value when SError
 occur
In-Reply-To: <20220125153803.549084-1-james.morse@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
Message-ID: <20220125153803.549084-3-james.morse@arm.com>

When any exception other than an IRQ occurs, the CPU updates the ESR_EL2
register with the exception syndrome. An SError may also become pending,
and will be synchronised by KVM. KVM notes the exception type, and whether
an SError was synchronised in exit_code.

When an exception other than an IRQ occurs, fixup_guest_exit() updates
vcpu->arch.fault.esr_el2 from the hardware register. When an SError was
synchronised, the vcpu esr value is used to determine if the exception
was due to an HVC. If so, ELR_EL2 is moved back one instruction. This
is so that KVM can process the SError first, and re-execute the HVC if
the guest survives the SError.

But if an IRQ synchronises an SError, the vcpu's esr value is stale.
If the previous non-IRQ exception was an HVC, KVM will corrupt ELR_EL2,
causing an unrelated guest instruction to be executed twice.

Check ARM_EXCEPTION_CODE() before messing with ELR_EL2, IRQs don't
update this register so don't need to check.

Fixes: defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to HYP")
Cc: stable at vger.kernel.org
Reported-by: Steven Price <steven.price at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..331dd10821df 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -424,7 +424,8 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
 		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
 
-	if (ARM_SERROR_PENDING(*exit_code)) {
+	if (ARM_SERROR_PENDING(*exit_code) &&
+	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
 		u8 esr_ec = kvm_vcpu_trap_get_class(vcpu);
 
 		/*
-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:38:02 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:38:02 +0000
Subject: [PATCH 3/4] KVM: arm64: Stop handle_exit() from handling HVC twice
 when an SError occurs
In-Reply-To: <20220125153803.549084-1-james.morse@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
Message-ID: <20220125153803.549084-4-james.morse@arm.com>

Prior to commit defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to
HYP"), when an SError is synchronised due to another exception, KVM
handles the SError first. If the guest survives, the instruction that
triggered the original exception is re-exectued to handle the first
exception. HVC is treated as a special case as the instruction wouldn't
normally be re-exectued, as its not a trap.

Commit defe21f49bc9 didn't preserve the behaviour of the 'return 1'
that skips the rest of handle_exit().

Since commit defe21f49bc9, KVM will try to handle the SError and the
original exception at the same time. When the exception was an HVC,
fixup_guest_exit() has already rolled back ELR_EL2, meaning if the
guest has virtual SError masked, it will execute and handle the HVC
twice.

Restore the original behaviour.

Fixes: defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to HYP")
Cc: stable at vger.kernel.org
Signed-off-by: James Morse <james.morse at arm.com>
---
It may be possible to remove both this patch, and the HVC handling code
in fixup_guest_exit(). This means KVM would always handle the exception
and the SError. This may result in unnecessary work if the guest takes
the virtual SError when it is next restarted, but should be harmless if
SError are always re-injected using HCR_EL2.VSE.
---
 arch/arm64/kvm/handle_exit.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fd2dd26caf91..e3140abd2e2e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -228,6 +228,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
 {
 	struct kvm_run *run = vcpu->run;
 
+	if (ARM_SERROR_PENDING(exception_index)) {
+		/*
+		 * The SError is handled by handle_exit_early(). If the guest
+		 * survives it will re-execute the original instruction.
+		 */
+		return 1;
+	}
+
 	exception_index = ARM_EXCEPTION_CODE(exception_index);
 
 	switch (exception_index) {
-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:38:03 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:38:03 +0000
Subject: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and PAC
 trap errata
In-Reply-To: <20220125153803.549084-1-james.morse@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
Message-ID: <20220125153803.549084-5-james.morse@arm.com>

Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
single-stepping authenticated ERET instructions. A single step is
expected, but a pointer authentication trap is taken instead. The
erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
EL1 to cause a return to EL2 with a guest controlled ELR_EL2.

Because the conditions require an ERET into active-not-pending state,
this is only a problem for the EL2 when EL2 is stepping EL1. In this case
the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
restored.

Cc: stable at vger.kernel.org # ${GITHASHHERE}: arm64: Add Cortex-A510 CPU part definition
Cc: stable at vger.kernel.org
Signed-off-by: James Morse <james.morse at arm.com>
---
 Documentation/arm64/silicon-errata.rst  |  2 ++
 arch/arm64/Kconfig                      | 16 ++++++++++++++++
 arch/arm64/kernel/cpu_errata.c          |  8 ++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 24 +++++++++++++++++++++---
 arch/arm64/tools/cpucaps                |  1 +
 5 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..ac1ae34564c9 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -92,6 +92,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2077057        | ARM64_ERRATUM_2077057       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..02b542ec18c8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -670,6 +670,22 @@ config ARM64_ERRATUM_1508412
 config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	bool
 
+config ARM64_ERRATUM_2077057
+	bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2"
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2077057.
+	  Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is
+	  expected, but a Pointer Authentication trap is taken instead. The
+	  erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
+	  EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
+
+	  This can only happen when EL2 is stepping EL1.
+
+	  When these conditions occur, the SPSR_EL2 value is unchanged from the
+	  previous guest entry, and can be restored from the in-memory copy.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_2119858
 	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..04a014c63251 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2077057
+	{
+		.desc = "ARM erratum 2077057",
+		.capability = ARM64_WORKAROUND_2077057,
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 331dd10821df..93bf140cc972 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -409,6 +409,8 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
  */
 static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
+	u8 esr_ec;
+
 	/*
 	 * Save PSTATE early so that we can evaluate the vcpu mode
 	 * early on.
@@ -421,13 +423,13 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	 */
 	early_exit_filter(vcpu, exit_code);
 
-	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
+	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
 		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
+		esr_ec = kvm_vcpu_trap_get_class(vcpu);
+	}
 
 	if (ARM_SERROR_PENDING(*exit_code) &&
 	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
-		u8 esr_ec = kvm_vcpu_trap_get_class(vcpu);
-
 		/*
 		 * HVC already have an adjusted PC, which we need to
 		 * correct in order to return to after having injected
@@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
 	}
 
+	/*
+	 * Check for the conditions of Cortex-A510's #2077057. When these occur
+	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
+	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
+	 * Did we just take a PAC exception when a step exception was expected?
+	 */
+	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&
+	    cpus_have_const_cap(ARM64_WORKAROUND_2077057) &&
+	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ &&
+	    esr_ec == ESR_ELx_EC_PAC &&
+	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
+		/* Active-not-pending? */
+		if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+	}
+
 	/*
 	 * We're using the raw exception code in order to only process
 	 * the trap if no SError is pending. We will come back to the
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..2e7cd3fecca6 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2077057
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.30.2



From james.clark at arm.com  Tue Jan 25 07:39:24 2022
From: james.clark at arm.com (James Clark)
Date: Tue, 25 Jan 2022 15:39:24 +0000
Subject: [RFC V1 11/11] perf: Capture branch privilege information
In-Reply-To: <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>
Message-ID: <82d586d3-358b-724b-0eac-7fb5c6e03efb@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> Platforms like arm64 could capture privilege level information for all the
> branch records. Hence this adds a new element in the struct branch_entry to
> record the privilege level information, which could be requested through a
> new event.attr.branch_sample_type flag PERF_SAMPLE_BRANCH_PRIV_SAVE. While
> here, update the BRBE driver as required.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu_brbe.c              | 28 ++++++++++++++++++++++++
>  include/linux/perf_event.h               |  5 +++++
>  include/uapi/linux/perf_event.h          | 13 ++++++++++-
>  tools/include/uapi/linux/perf_event.h    | 13 ++++++++++-
>  tools/perf/Documentation/perf-record.txt |  1 +
>  tools/perf/util/parse-branch-options.c   |  1 +
>  6 files changed, 59 insertions(+), 2 deletions(-)
> 
[...]
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 361fdc6b87a0..4d77710f7a4e 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */

privillege -> privilege

> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +

Can you also add the new entry to the perf verbose printer otherwise it looks like
it's not being set on branch_sample_type
(as in when using ./perf record -j any_call,u,priv -vvv):

	static void __p_branch_sample_type(char *buf, size_t size, u64 value)
	{
	#define bit_name(n) { PERF_SAMPLE_BRANCH_##n, #n }
		struct bit_names bits[] = {
			bit_name(USER), bit_name(KERNEL), bit_name(HV), bit_name(ANY),
			bit_name(ANY_CALL), bit_name(ANY_RETURN), bit_name(IND_CALL),
			bit_name(ABORT_TX), bit_name(IN_TX), bit_name(NO_TX),
			bit_name(COND), bit_name(CALL_STACK), bit_name(IND_JUMP),
			bit_name(CALL), bit_name(NO_FLAGS), bit_name(NO_CYCLES),
			bit_name(HW_INDEX),
			{ .name = NULL, }
		};
	#undef bit_name
		__p_bits(buf, size, value, bits);
	}

PERF_SAMPLE_BRANCH_TYPE_SAVE_SHIFT is also missing so it probably makes sense to add it
at the same time as that was expanded for BRBE.

>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER	= 0,
> +	PERF_BR_KERNEL	= 1,
> +	PERF_BR_HV	= 2,
> +};
> +
>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */
> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index 9a82b8aaed93..a2208400b0b9 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +
>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER    = 0,
> +	PERF_BR_KERNEL  = 1,
> +	PERF_BR_HV      = 2,
> +};
> +
>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */
> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index 9ccc75935bc5..3e33686977a1 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -387,6 +387,7 @@ following filters are defined:
>  	- abort_tx: only when the target is a hardware transaction abort
>  	- cond: conditional branches
>  	- save_type: save branch type during sampling in case binary is not available later
> +	- priv: save privilege state during sampling in case binary is not available later
>  
>  +
>  The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
> diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
> index bb4aa88c50a8..00588b9db474 100644
> --- a/tools/perf/util/parse-branch-options.c
> +++ b/tools/perf/util/parse-branch-options.c
> @@ -32,6 +32,7 @@ static const struct branch_mode branch_modes[] = {
>  	BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
>  	BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE),
>  	BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK),
> +	BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE),
>  	BRANCH_END
>  };
>  
> 


From james.morse at arm.com  Tue Jan 25 07:40:38 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:40:38 +0000
Subject: [PATCH 0/2] arm64: cpufeature: List early Cortex-A510 parts as having
 broken dbm
Message-ID: <20220125154040.549272-1-james.morse@arm.com>

Hello,

Early Cortex-A510 parts have broken dbm. Add them to the list of CPUs with
broken dbm.

The SDEN is available here:
https://developer.arm.com/documentation/SDEN2397239/900


There are three series that would add the Cortex-A510 part macros. I've picked
Anshuman's patch that does this, on the assumption that makes Catalin's life
easier. I haven't spotted that patch on the arm64/for-next/fixes branch, so
I've not included the hash in the prerequisite field of the CC-stable.

That patch may need to go on a stable branch, as the the third series will
likely go via the KVM tree.

Let me know if you want this reposted once that value is known.

This series is based on v5.17-rc1 and can be retrieved from:
https://git.gitlab.arm.com/linux-arm/linux-jm.git a510_errata/dbm/v1


Thanks,

James


Anshuman Khandual (1):
  arm64: Add Cortex-A510 CPU part definition

James Morse (1):
  arm64: cpufeature: List early Cortex-A510 parts as having broken dbm

 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 11 +++++++++++
 arch/arm64/include/asm/cputype.h       |  2 ++
 arch/arm64/kernel/cpufeature.c         |  3 +++
 4 files changed, 18 insertions(+)

-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:40:39 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:40:39 +0000
Subject: [PATCH 1/2] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <20220125154040.549272-1-james.morse@arm.com>
References: <20220125154040.549272-1-james.morse@arm.com>
Message-ID: <20220125154040.549272-2-james.morse@arm.com>

From: Anshuman Khandual <anshuman.khandual at arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.30.2



From james.morse at arm.com  Tue Jan 25 07:40:40 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 15:40:40 +0000
Subject: [PATCH 2/2] arm64: cpufeature: List early Cortex-A510 parts as having
 broken dbm
In-Reply-To: <20220125154040.549272-1-james.morse@arm.com>
References: <20220125154040.549272-1-james.morse@arm.com>
Message-ID: <20220125154040.549272-3-james.morse@arm.com>

Versions of Cortex-A510 before r0p3 are affected by a hardware erratum
where the hardware update of the dirty bit is not correctly ordered.

Add these cpus to the cpu_has_broken_dbm list.

Cc: stable at vger.kernel.org # ${GITHASHHERE}: arm64: Add Cortex-A510 CPU part definition
Cc: stable at vger.kernel.org
Signed-off-by: James Morse <james.morse at arm.com>
---
 Documentation/arm64/silicon-errata.rst |  2 ++
 arch/arm64/Kconfig                     | 11 +++++++++++
 arch/arm64/kernel/cpufeature.c         |  3 +++
 3 files changed, 16 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..dcd346d209b5 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -92,6 +92,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2051678        | ARM64_ERRATUM_2051678       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..a8aca96918b2 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -670,6 +670,17 @@ config ARM64_ERRATUM_1508412
 config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	bool
 
+config ARM64_ERRATUM_2051678
+	bool "Cortex-A510: 2051678: disable Hardware Update of the page table's dirty bit"
+	help
+	  This options adds the workaround for ARM Cortex-A510 erratum ARM64_ERRATUM_2051678.
+	  Affected Coretex-A510 might not respect the ordering rules for
+	  hardware update of the page table's dirty bit. The workaround
+	  is to not enable the feature on affected CPUs.
+
+	  If unsure, say Y.
+
+
 config ARM64_ERRATUM_2119858
 	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
 	default y
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..e5f23dab1c8d 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1645,6 +1645,9 @@ static bool cpu_has_broken_dbm(void)
 		MIDR_ALL_VERSIONS(MIDR_CORTEX_A55),
 		/* Kryo4xx Silver (rdpe => r1p0) */
 		MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe),
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2051678
+		MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
 #endif
 		{},
 	};
-- 
2.30.2



From mark.rutland at arm.com  Tue Jan 25 07:45:53 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:45:53 +0000
Subject: [PATCH v2 0/7] linkage: better symbol aliasing
In-Reply-To: <CAMj1kXGCFFHzZAqhfmJthGCe6uhFsrHwzK0QyOfrGw7_kNbjWQ@mail.gmail.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
 <CAMj1kXGCFFHzZAqhfmJthGCe6uhFsrHwzK0QyOfrGw7_kNbjWQ@mail.gmail.com>
Message-ID: <YfAbMY6U4UpyrerB@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 04:28:11PM +0100, Ard Biesheuvel wrote:
> On Tue, 25 Jan 2022 at 12:32, Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > This series aims to make symbol aliasing simpler and more consistent.
> > The basic idea is to replace SYM_FUNC_START_ALIAS(alias) and
> > SYM_FUNC_END_ALIAS(alias) with a new SYM_FUNC_ALIAS(alias, name), so
> > that e.g.
> >
> >     SYM_FUNC_START(func)
> >     SYM_FUNC_START_ALIAS(alias1)
> >     SYM_FUNC_START_ALIAS(alias2)
> >         ... asm insns ...
> >     SYM_FUNC_END(func)
> >     SYM_FUNC_END_ALIAS(alias1)
> >     SYM_FUNC_END_ALIAS(alias2)
> >     EXPORT_SYMBOL(alias1)
> >     EXPORT_SYMBOL(alias2)
> >
> > ... can become:
> >
> >     SYM_FUNC_START(name)
> >         ... asm insns ...
> >     SYM_FUNC_END(name)
> >
> >     SYM_FUNC_ALIAS(alias1, func)
> >     EXPORT_SYMBOL(alias1)
> >
> >     SYM_FUNC_ALIAS(alias2, func)
> >     EXPORT_SYMBOL(alias2)
> >
> > This avoids repetition and hopefully make it easier to ensure
> > consistency (e.g. so each function has a single canonical name and
> > associated metadata).
> >
> 
> I take it this affects the sizes of the alias ELF symbols? Does that matter?

The alias should be given the same size as the original symbol, unless I've
made an error. If you look at patch 3:

* In SYM_FUNC_START(name), via SYM_ENTRY_AT(name, ...), we create a local label
  for the start of the function: .L____sym_entry__##name

* In SYM_FUNC_END(name), via SYM_END_AT(name, ...), we create a local label for
  the end of the function: .L____sym_end__##name

* In SYM_FUNC_ALIAS*(alias,name), we define the start and end of the alias as
  the start and end of the original symbol using those local labels, e.g.

  | #define SYM_FUNC_ALIAS(alias, name)                                     \
  |         SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_GLOBAL)      \
  |         SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)

Note that:

* SYM_FUNC_START() uses SYM_START(), which uses SYM_ENTRY_AT()
* SYM_FUNC_END() uses SYM_END(), which uses SYM_END_AT()

... so the definition of tha alias is ultimately structurally identical to the
definition of the canoncial name, at least for now.

Thanks,
Mark.


From ardb at kernel.org  Tue Jan 25 07:49:03 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 16:49:03 +0100
Subject: [PATCH v2 0/7] linkage: better symbol aliasing
In-Reply-To: <YfAbMY6U4UpyrerB@FVFF77S0Q05N>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
 <CAMj1kXGCFFHzZAqhfmJthGCe6uhFsrHwzK0QyOfrGw7_kNbjWQ@mail.gmail.com>
 <YfAbMY6U4UpyrerB@FVFF77S0Q05N>
Message-ID: <CAMj1kXEyzNMWiQFiZW1_QTApmuHfot82USC=Q8nP27sVm+WMMw@mail.gmail.com>

On Tue, 25 Jan 2022 at 16:46, Mark Rutland <mark.rutland at arm.com> wrote:
>
> On Tue, Jan 25, 2022 at 04:28:11PM +0100, Ard Biesheuvel wrote:
> > On Tue, 25 Jan 2022 at 12:32, Mark Rutland <mark.rutland at arm.com> wrote:
> > >
> > > This series aims to make symbol aliasing simpler and more consistent.
> > > The basic idea is to replace SYM_FUNC_START_ALIAS(alias) and
> > > SYM_FUNC_END_ALIAS(alias) with a new SYM_FUNC_ALIAS(alias, name), so
> > > that e.g.
> > >
> > >     SYM_FUNC_START(func)
> > >     SYM_FUNC_START_ALIAS(alias1)
> > >     SYM_FUNC_START_ALIAS(alias2)
> > >         ... asm insns ...
> > >     SYM_FUNC_END(func)
> > >     SYM_FUNC_END_ALIAS(alias1)
> > >     SYM_FUNC_END_ALIAS(alias2)
> > >     EXPORT_SYMBOL(alias1)
> > >     EXPORT_SYMBOL(alias2)
> > >
> > > ... can become:
> > >
> > >     SYM_FUNC_START(name)
> > >         ... asm insns ...
> > >     SYM_FUNC_END(name)
> > >
> > >     SYM_FUNC_ALIAS(alias1, func)
> > >     EXPORT_SYMBOL(alias1)
> > >
> > >     SYM_FUNC_ALIAS(alias2, func)
> > >     EXPORT_SYMBOL(alias2)
> > >
> > > This avoids repetition and hopefully make it easier to ensure
> > > consistency (e.g. so each function has a single canonical name and
> > > associated metadata).
> > >
> >
> > I take it this affects the sizes of the alias ELF symbols? Does that matter?
>
> The alias should be given the same size as the original symbol, unless I've
> made an error. If you look at patch 3:
>
> * In SYM_FUNC_START(name), via SYM_ENTRY_AT(name, ...), we create a local label
>   for the start of the function: .L____sym_entry__##name
>
> * In SYM_FUNC_END(name), via SYM_END_AT(name, ...), we create a local label for
>   the end of the function: .L____sym_end__##name
>
> * In SYM_FUNC_ALIAS*(alias,name), we define the start and end of the alias as
>   the start and end of the original symbol using those local labels, e.g.
>
>   | #define SYM_FUNC_ALIAS(alias, name)                                     \
>   |         SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_GLOBAL)      \
>   |         SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
>
> Note that:
>
> * SYM_FUNC_START() uses SYM_START(), which uses SYM_ENTRY_AT()
> * SYM_FUNC_END() uses SYM_END(), which uses SYM_END_AT()
>
> ... so the definition of tha alias is ultimately structurally identical to the
> definition of the canoncial name, at least for now.
>

Ah right, apologies for not looking more carefully - I assumed the
changed placement implied that the aliases had zero size.

And ultimately, I don't think there is an obviously correct answer
anyway, it's just the [apparently non-existent] change in behavior I
was curious about.


From mark.rutland at arm.com  Tue Jan 25 07:50:01 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:50:01 +0000
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
In-Reply-To: <YfAV6FTN5g6jZGj7@FVFF77S0Q05N>
References: <20220122023447.1480995-1-eugenis@google.com>
 <YfAV6FTN5g6jZGj7@FVFF77S0Q05N>
Message-ID: <YfAcKZpDWmKMZy8q@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 03:23:20PM +0000, Mark Rutland wrote:
> On Fri, Jan 21, 2022 at 06:34:47PM -0800, Evgenii Stepanov wrote:
> > ex_handler_load_unaligned_zeropad extracts the source and data register
> > numbers from the wrong field of the exception table.
> 
> Ouch. Did you find this by inspection, or did this show up in testing?
> 
> Sorry about this.
> 
> I think we should be a little more explicit as to exactly what goes wrong. How
> about:
> 
> | In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
> | addr register indices from ex->type rather than ex->data. As ex->type will
> | contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
> | 
> | * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
> |   extracted from bits [9:5]. Thus, we may attempt to dereference an arbitrary
> |   address as X0 may hold an arbitary value.
> | 
> | * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
> |   extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
> |   behaviour within load_unaligned_zeropad() and its caller.
> | 
> | Fix this by extracting both values from ex->data as originally intended.
> 
> > Fixes: 753b3236
> 
> That should be expanded, e.g.
> 
>   Fixes: 753b32368705c396 ("arm64: extable: add load_unaligned_zeropad() handler")
> 
> With those changes:
> 
> Reviewed-by: Mark Rutland <mark.rutland at arm.com>

Looking again, sicne this isn't jsut a null-deref, can we also rework the
title, something like:

| arm64: extable: fix load_unaligned_zeropad() reg indices

Thanks,
Mark.


From mark.rutland at arm.com  Tue Jan 25 07:58:51 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 15:58:51 +0000
Subject: [PATCH v2 0/7] linkage: better symbol aliasing
In-Reply-To: <CAMj1kXEyzNMWiQFiZW1_QTApmuHfot82USC=Q8nP27sVm+WMMw@mail.gmail.com>
References: <20220125113200.3829108-1-mark.rutland@arm.com>
 <CAMj1kXGCFFHzZAqhfmJthGCe6uhFsrHwzK0QyOfrGw7_kNbjWQ@mail.gmail.com>
 <YfAbMY6U4UpyrerB@FVFF77S0Q05N>
 <CAMj1kXEyzNMWiQFiZW1_QTApmuHfot82USC=Q8nP27sVm+WMMw@mail.gmail.com>
Message-ID: <YfAeO+8R+XiYtr8l@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 04:49:03PM +0100, Ard Biesheuvel wrote:
> On Tue, 25 Jan 2022 at 16:46, Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > On Tue, Jan 25, 2022 at 04:28:11PM +0100, Ard Biesheuvel wrote:
> > > On Tue, 25 Jan 2022 at 12:32, Mark Rutland <mark.rutland at arm.com> wrote:
> > > >
> > > > This series aims to make symbol aliasing simpler and more consistent.
> > > > The basic idea is to replace SYM_FUNC_START_ALIAS(alias) and
> > > > SYM_FUNC_END_ALIAS(alias) with a new SYM_FUNC_ALIAS(alias, name), so
> > > > that e.g.
> > > >
> > > >     SYM_FUNC_START(func)
> > > >     SYM_FUNC_START_ALIAS(alias1)
> > > >     SYM_FUNC_START_ALIAS(alias2)
> > > >         ... asm insns ...
> > > >     SYM_FUNC_END(func)
> > > >     SYM_FUNC_END_ALIAS(alias1)
> > > >     SYM_FUNC_END_ALIAS(alias2)
> > > >     EXPORT_SYMBOL(alias1)
> > > >     EXPORT_SYMBOL(alias2)
> > > >
> > > > ... can become:
> > > >
> > > >     SYM_FUNC_START(name)
> > > >         ... asm insns ...
> > > >     SYM_FUNC_END(name)
> > > >
> > > >     SYM_FUNC_ALIAS(alias1, func)
> > > >     EXPORT_SYMBOL(alias1)
> > > >
> > > >     SYM_FUNC_ALIAS(alias2, func)
> > > >     EXPORT_SYMBOL(alias2)
> > > >
> > > > This avoids repetition and hopefully make it easier to ensure
> > > > consistency (e.g. so each function has a single canonical name and
> > > > associated metadata).
> > > >
> > >
> > > I take it this affects the sizes of the alias ELF symbols? Does that matter?
> >
> > The alias should be given the same size as the original symbol, unless I've
> > made an error. If you look at patch 3:
> >
> > * In SYM_FUNC_START(name), via SYM_ENTRY_AT(name, ...), we create a local label
> >   for the start of the function: .L____sym_entry__##name
> >
> > * In SYM_FUNC_END(name), via SYM_END_AT(name, ...), we create a local label for
> >   the end of the function: .L____sym_end__##name
> >
> > * In SYM_FUNC_ALIAS*(alias,name), we define the start and end of the alias as
> >   the start and end of the original symbol using those local labels, e.g.
> >
> >   | #define SYM_FUNC_ALIAS(alias, name)                                     \
> >   |         SYM_START_AT(alias, .L____sym_entry__##name, SYM_L_GLOBAL)      \
> >   |         SYM_END_AT(alias, .L____sym_end__##name, SYM_T_FUNC)
> >
> > Note that:
> >
> > * SYM_FUNC_START() uses SYM_START(), which uses SYM_ENTRY_AT()
> > * SYM_FUNC_END() uses SYM_END(), which uses SYM_END_AT()
> >
> > ... so the definition of tha alias is ultimately structurally identical to the
> > definition of the canoncial name, at least for now.
> >
> 
> Ah right, apologies for not looking more carefully - I assumed the
> changed placement implied that the aliases had zero size.

NP; I didn't make that clear in the cover letter, and now it's written up and
archived for future reference. :)

> And ultimately, I don't think there is an obviously correct answer
> anyway, it's just the [apparently non-existent] change in behavior I
> was curious about.

FWIW, I hadn't really considered whether we actually need that for the aliases;
it was jsut the path of least resistance implementation-wise, and I'd like to
be able to use the local labls for the bounds in future for other annotations
and sanity-checks.

Thanks,
Mark.


From broonie at kernel.org  Tue Jan 25 07:59:38 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 15:59:38 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <20220125150057.3936090-2-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
Message-ID: <YfAeal8MmLsUIJpo@sirena.org.uk>

On Tue, Jan 25, 2022 at 03:00:43PM +0000, Mark Rutland wrote:

> As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
> used as a value rather than as a bit mask.

Well, it's both and we do call it a mask in both the kernel and TF-A
too...
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/78467a6c/attachment.sig>

From linux at armlinux.org.uk  Tue Jan 25 08:08:24 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:08:24 +0000
Subject: [PATCH net-next 0/2] net: axienet: modernise pcs implementation
Message-ID: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>

Hi,

These two patches modernise the Xilinx axienet PCS implementation to
use the phylink split PCS support.

The first patch adds split PCS support and makes use of the newly
introduced mac_select_pcs() function, which is the preferred way to
conditionally attach a PCS.

The second patch cleans up the use of mdiobus_write() since we now have
bus accessors for mdio devices.

There should be no functional change to the driver.

This series was previously sent CFT on the 16th December (message ID
Ybs1cdM3KUTsq4Vx at shell.armlinux.org.uk), and feedback addressed. CFT v2
sent 4th January (message ID YdQlI8gcVwg2sR+5 at shell.armlinux.org.uk).

 drivers/net/ethernet/xilinx/xilinx_axienet.h      |   2 +
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 108 +++++++++++-----------
 2 files changed, 55 insertions(+), 55 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:10:11 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:10:11 +0000
Subject: [PATCH net-next 1/2] net: axienet: convert to phylink_pcs
In-Reply-To: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
References: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
Message-ID: <E1nCOOZ-005L8t-F1@rmk-PC.armlinux.org.uk>

Convert axienet to use the phylink_pcs layer, resulting in it no longer
being a legacy driver.

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/xilinx/xilinx_axienet.h  |   2 +
 .../net/ethernet/xilinx/xilinx_axienet_main.c | 107 +++++++++---------
 2 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h
index 5b4d153b1492..40108968b350 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -386,6 +386,7 @@ struct axidma_bd {
  * @phylink:	Pointer to phylink instance
  * @phylink_config: phylink configuration settings
  * @pcs_phy:	Reference to PCS/PMA PHY if used
+ * @pcs:	phylink pcs structure for PCS PHY
  * @switch_x_sgmii: Whether switchable 1000BaseX/SGMII mode is enabled in the core
  * @axi_clk:	AXI4-Lite bus clock
  * @misc_clks:	Misc ethernet clocks (AXI4-Stream, Ref, MGT clocks)
@@ -434,6 +435,7 @@ struct axienet_local {
 	struct phylink_config phylink_config;
 
 	struct mdio_device *pcs_phy;
+	struct phylink_pcs pcs;
 
 	bool switch_x_sgmii;
 
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 377c94ec2486..1ebdf1c62db8 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1537,78 +1537,79 @@ static const struct ethtool_ops axienet_ethtool_ops = {
 	.nway_reset	= axienet_ethtools_nway_reset,
 };
 
-static void axienet_mac_pcs_get_state(struct phylink_config *config,
-				      struct phylink_link_state *state)
+static struct axienet_local *pcs_to_axienet_local(struct phylink_pcs *pcs)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
-	struct axienet_local *lp = netdev_priv(ndev);
+	return container_of(pcs, struct axienet_local, pcs);
+}
 
-	switch (state->interface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		phylink_mii_c22_pcs_get_state(lp->pcs_phy, state);
-		break;
-	default:
-		break;
-	}
+static void axienet_pcs_get_state(struct phylink_pcs *pcs,
+				  struct phylink_link_state *state)
+{
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
+
+	phylink_mii_c22_pcs_get_state(pcs_phy, state);
 }
 
-static void axienet_mac_an_restart(struct phylink_config *config)
+static void axienet_pcs_an_restart(struct phylink_pcs *pcs)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
-	struct axienet_local *lp = netdev_priv(ndev);
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
 
-	phylink_mii_c22_pcs_an_restart(lp->pcs_phy);
+	phylink_mii_c22_pcs_an_restart(pcs_phy);
 }
 
-static int axienet_mac_prepare(struct phylink_config *config, unsigned int mode,
-			       phy_interface_t iface)
+static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+			      phy_interface_t interface,
+			      const unsigned long *advertising,
+			      bool permit_pause_to_mac)
 {
-	struct net_device *ndev = to_net_dev(config->dev);
+	struct mdio_device *pcs_phy = pcs_to_axienet_local(pcs)->pcs_phy;
+	struct net_device *ndev = pcs_to_axienet_local(pcs)->ndev;
 	struct axienet_local *lp = netdev_priv(ndev);
 	int ret;
 
-	switch (iface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		if (!lp->switch_x_sgmii)
-			return 0;
-
-		ret = mdiobus_write(lp->pcs_phy->bus,
-				    lp->pcs_phy->addr,
+	if (lp->switch_x_sgmii) {
+		ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
 				    XLNX_MII_STD_SELECT_REG,
-				    iface == PHY_INTERFACE_MODE_SGMII ?
+				    interface == PHY_INTERFACE_MODE_SGMII ?
 					XLNX_MII_STD_SELECT_SGMII : 0);
-		if (ret < 0)
-			netdev_warn(ndev, "Failed to switch PHY interface: %d\n",
+		if (ret < 0) {
+			netdev_warn(ndev,
+				    "Failed to switch PHY interface: %d\n",
 				    ret);
-		return ret;
-	default:
-		return 0;
+			return ret;
+		}
 	}
+
+	ret = phylink_mii_c22_pcs_config(pcs_phy, mode, interface, advertising);
+	if (ret < 0)
+		netdev_warn(ndev, "Failed to configure PCS: %d\n", ret);
+
+	return ret;
 }
 
-static void axienet_mac_config(struct phylink_config *config, unsigned int mode,
-			       const struct phylink_link_state *state)
+static const struct phylink_pcs_ops axienet_pcs_ops = {
+	.pcs_get_state = axienet_pcs_get_state,
+	.pcs_config = axienet_pcs_config,
+	.pcs_an_restart = axienet_pcs_an_restart,
+};
+
+static struct phylink_pcs *axienet_mac_select_pcs(struct phylink_config *config,
+						  phy_interface_t interface)
 {
 	struct net_device *ndev = to_net_dev(config->dev);
 	struct axienet_local *lp = netdev_priv(ndev);
-	int ret;
 
-	switch (state->interface) {
-	case PHY_INTERFACE_MODE_SGMII:
-	case PHY_INTERFACE_MODE_1000BASEX:
-		ret = phylink_mii_c22_pcs_config(lp->pcs_phy, mode,
-						 state->interface,
-						 state->advertising);
-		if (ret < 0)
-			netdev_warn(ndev, "Failed to configure PCS: %d\n",
-				    ret);
-		break;
+	if (interface == PHY_INTERFACE_MODE_1000BASEX ||
+	    interface ==  PHY_INTERFACE_MODE_SGMII)
+		return &lp->pcs;
 
-	default:
-		break;
-	}
+	return NULL;
+}
+
+static void axienet_mac_config(struct phylink_config *config, unsigned int mode,
+			       const struct phylink_link_state *state)
+{
+	/* nothing meaningful to do */
 }
 
 static void axienet_mac_link_down(struct phylink_config *config,
@@ -1663,9 +1664,7 @@ static void axienet_mac_link_up(struct phylink_config *config,
 
 static const struct phylink_mac_ops axienet_phylink_ops = {
 	.validate = phylink_generic_validate,
-	.mac_pcs_get_state = axienet_mac_pcs_get_state,
-	.mac_an_restart = axienet_mac_an_restart,
-	.mac_prepare = axienet_mac_prepare,
+	.mac_select_pcs = axienet_mac_select_pcs,
 	.mac_config = axienet_mac_config,
 	.mac_link_down = axienet_mac_link_down,
 	.mac_link_up = axienet_mac_link_up,
@@ -2079,12 +2078,12 @@ static int axienet_probe(struct platform_device *pdev)
 			ret = -EPROBE_DEFER;
 			goto cleanup_mdio;
 		}
-		lp->phylink_config.pcs_poll = true;
+		lp->pcs.ops = &axienet_pcs_ops;
+		lp->pcs.poll = true;
 	}
 
 	lp->phylink_config.dev = &ndev->dev;
 	lp->phylink_config.type = PHYLINK_NETDEV;
-	lp->phylink_config.legacy_pre_march2020 = true;
 	lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
 		MAC_10FD | MAC_100FD | MAC_1000FD;
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:10:16 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:10:16 +0000
Subject: [PATCH net-next 2/2] net: axienet: replace mdiobus_write() with
 mdiodev_write()
In-Reply-To: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
References: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
Message-ID: <E1nCOOe-005L92-JE@rmk-PC.armlinux.org.uk>

Commit 0ebecb2644c8 ("net: mdio: Add helper functions for accessing
MDIO devices") added support for mdiodev accessor operations that
neatly wrap the mdiobus accessor operations. Since we are dealing with
a mdio device here, update the driver to use mdiodev_write().

Tested-by: Harini Katakam <harini.katakam at xilinx.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
index 1ebdf1c62db8..de0a6372ae0e 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -1568,8 +1568,7 @@ static int axienet_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
 	int ret;
 
 	if (lp->switch_x_sgmii) {
-		ret = mdiobus_write(pcs_phy->bus, pcs_phy->addr,
-				    XLNX_MII_STD_SELECT_REG,
+		ret = mdiodev_write(pcs_phy, XLNX_MII_STD_SELECT_REG,
 				    interface == PHY_INTERFACE_MODE_SGMII ?
 					XLNX_MII_STD_SELECT_SGMII : 0);
 		if (ret < 0) {
-- 
2.30.2



From horatiu.vultur at microchip.com  Tue Jan 25 08:12:45 2022
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Tue, 25 Jan 2022 17:12:45 +0100
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
Message-ID: <20220125161245.418882-1-horatiu.vultur@microchip.com>

Initially the driver accessed the registers using u32 __iomem but then
in the blamed commit it changed it to use regmap. The problem is that now
the offset of the registers is not calculated anymore at word offset but
at byte offset. Therefore make sure to multiply the offset with word size.

Fixes: 2afbbab45c261a ("pinctrl: microchip-sgpio: update to support regmap")
Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
---
 drivers/pinctrl/pinctrl-microchip-sgpio.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
index 8e081c90bdb2..2999c98bbdee 100644
--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
+++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
@@ -98,6 +98,12 @@ static const struct sgpio_properties properties_sparx5 = {
 	.regoff = { 0x00, 0x06, 0x26, 0x04, 0x05, 0x2a, 0x32, 0x3a, 0x3e, 0x42 },
 };
 
+static const struct regmap_config regmap_config = {
+		.reg_bits = 32,
+		.val_bits = 32,
+		.reg_stride = 4,
+};
+
 static const char * const functions[] = { "gpio" };
 
 struct sgpio_bank {
@@ -137,7 +143,7 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
 
 static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
 {
-	return priv->properties->regoff[rno] + off;
+	return (priv->properties->regoff[rno] + off) * regmap_config.reg_stride;
 }
 
 static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
@@ -821,11 +827,6 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
 	struct clk *clk;
 	u32 __iomem *regs;
 	u32 val;
-	struct regmap_config regmap_config = {
-		.reg_bits = 32,
-		.val_bits = 32,
-		.reg_stride = 4,
-	};
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
-- 
2.33.0



From u.kleine-koenig at pengutronix.de  Tue Jan 25 08:12:04 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 25 Jan 2022 17:12:04 +0100
Subject: [PATCH v10 1/3] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <87tuds7y09.fsf@tarshish>
References: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
 <20220119172439.be4xpaqgwzdy26oh@pengutronix.de>
 <87tuds7y09.fsf@tarshish>
Message-ID: <20220125161204.hx5foivny6iupjke@pengutronix.de>

Hello Baruch,

On Tue, Jan 25, 2022 at 03:03:08PM +0200, Baruch Siach wrote:
> On Wed, Jan 19 2022, Uwe Kleine-K?nig wrote:
> > On Tue, Dec 14, 2021 at 06:27:17PM +0200, Baruch Siach wrote:
> >> From: Baruch Siach <baruch.siach at siklu.com>
> >> 
> >> Driver for the PWM block in Qualcomm IPQ6018 line of SoCs. Based on
> >> driver from downstream Codeaurora kernel tree. Removed support for older
> >> (V1) variants because I have no access to that hardware.
> >> 
> >> Tested on IPQ6010 based hardware.
> >> 
> >> Signed-off-by: Baruch Siach <baruch.siach at siklu.com>
> >> ---
> >> v10:
> >> 
> >>   Restore round up in pwm_div calculation; otherwise diff is always <=
> >>   0, so only bingo match works
> >> 
> >>   Don't overwrite min_diff on every loop iteration
> >> 
> >> v9:
> >> 
> >> Address comment from Uwe Kleine-K?nig:
> >> 
> >>   Use period_ns*rate in dividers calculation for better accuracy
> >> 
> >>   Round down pre_div and pwm_div
> >> 
> >>   Add a comment explaining why pwm_div can't underflow
> >> 
> >>   Add a comment explaining why pre_div > pwm_div end the search loop
> >> 
> >>   Drop 'CFG_' from register macros
> >> 
> >>   Rename to_ipq_pwm_chip() to ipq_pwm_from_chip()
> >> 
> >>   Change bare 'unsigned' to 'unsigned int'
> >> 
> >>   Clarify the comment on separate REG1 write for enable/disable
> >> 
> >>   Round up the period value in .get_state
> >> 
> >>   Use direct readl/writel so no need to check for regmap errors
> >> 
> >> v7:
> >> 
> >>   Change 'offset' to 'reg' for the tcsr offset (Rob)
> >> 
> >>   Drop clock name; there is only one clock (Bjorn)
> >> 
> >>   Simplify probe failure code path (Bjorn)
> >> 
> >> v6:
> >> 
> >> Address Uwe Kleine-K?nig review comments:
> >> 
> >>   Drop IPQ_PWM_MAX_DEVICES
> >> 
> >>   Rely on assigned-clock-rates; drop IPQ_PWM_CLK_SRC_FREQ
> >> 
> >>   Simplify register offset calculation
> >> 
> >>   Calculate duty cycle more precisely
> >> 
> >>   Refuse to set inverted polarity
> >> 
> >>   Drop redundant IPQ_PWM_REG1_ENABLE bit clear
> >> 
> >>   Remove x1000 factor in pwm_div calculation, use rate directly, and round up
> >> 
> >>   Choose initial pre_div such that pwm_div < IPQ_PWM_MAX_DIV
> >> 
> >>   Ensure pre_div <= pwm_div
> >> 
> >>   Rename close_ to best_
> >> 
> >>   Explain in comment why effective_div doesn't overflow
> >> 
> >>   Limit pwm_div to IPQ_PWM_MAX_DIV - 1 to allow 100% duty cycle
> >> 
> >>   Disable clock only after pwmchip_remove()
> >> 
> >>   const pwm_ops
> >> 
> >> Other changes:
> >> 
> >>   Add missing linux/bitfield.h header include (kernel test robot)
> >> 
> >>   Adjust code for PWM device node under TCSR (Rob Herring)
> >> 
> >> v5:
> >> 
> >> Use &tcsr_q6 syscon to access registers (Bjorn Andersson)
> >> 
> >> Address Uwe Kleine-K?nig review comments:
> >> 
> >>   Implement .get_state()
> >> 
> >>   Add IPQ_PWM_ prefix to local macros
> >> 
> >>   Use GENMASK/BIT/FIELD_PREP for register fields access
> >> 
> >>   Make type of config_div_and_duty() parameters consistent
> >> 
> >>   Derive IPQ_PWM_MIN_PERIOD_NS from IPQ_PWM_CLK_SRC_FREQ
> >> 
> >>   Integrate enable/disable into config_div_and_duty() to save register read,
> >>   and reduce frequency glitch on update
> >> 
> >>   Use min() instead of min_t()
> >> 
> >>   Fix comment format
> >> 
> >>   Use dev_err_probe() to indicate probe step failure
> >> 
> >>   Add missing clk_disable_unprepare() in .remove
> >> 
> >>   Don't set .owner
> >> 
> >> v4:
> >> 
> >>   Use div64_u64() to fix link for 32-bit targets ((kernel test robot
> >>   <lkp at intel.com>, Uwe Kleine-K?nig)
> >> 
> >> v3:
> >> 
> >>   s/qcom,pwm-ipq6018/qcom,ipq6018-pwm/ (Rob Herring)
> >> 
> >>   Fix integer overflow on 32-bit targets (kernel test robot <lkp at intel.com>)
> >> 
> >> v2:
> >> 
> >> Address Uwe Kleine-K?nig review comments:
> >> 
> >>   Fix period calculation when out of range
> >> 
> >>   Don't set period larger than requested
> >> 
> >>   Remove PWM disable on configuration change
> >> 
> >>   Implement .apply instead of non-atomic .config/.enable/.disable
> >> 
> >>   Don't modify PWM on .request/.free
> >> 
> >>   Check pwm_div underflow
> >> 
> >>   Fix various code and comment formatting issues
> >> 
> >> Other changes:
> >> 
> >>   Use u64 divisor safe division
> >> 
> >>   Remove now empty .request/.free
> >> ---
> >>  drivers/pwm/Kconfig   |  12 ++
> >>  drivers/pwm/Makefile  |   1 +
> >>  drivers/pwm/pwm-ipq.c | 275 ++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 288 insertions(+)
> >>  create mode 100644 drivers/pwm/pwm-ipq.c
> >> 
> >> diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
> >> index 21e3b05a5153..e39718137ecd 100644
> >> --- a/drivers/pwm/Kconfig
> >> +++ b/drivers/pwm/Kconfig
> >> @@ -260,6 +260,18 @@ config PWM_INTEL_LGM
> >>  	  To compile this driver as a module, choose M here: the module
> >>  	  will be called pwm-intel-lgm.
> >>  
> >> +config PWM_IPQ
> >> +	tristate "IPQ PWM support"
> >> +	depends on ARCH_QCOM || COMPILE_TEST
> >> +	depends on HAVE_CLK && HAS_IOMEM
> >> +	help
> >> +	  Generic PWM framework driver for IPQ PWM block which supports
> >> +	  4 pwm channels. Each of the these channels can be configured
> >> +	  independent of each other.
> >> +
> >> +	  To compile this driver as a module, choose M here: the module
> >> +	  will be called pwm-ipq.
> >> +
> >>  config PWM_IQS620A
> >>  	tristate "Azoteq IQS620A PWM support"
> >>  	depends on MFD_IQS62X || COMPILE_TEST
> >> diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
> >> index 708840b7fba8..7402feae4b36 100644
> >> --- a/drivers/pwm/Makefile
> >> +++ b/drivers/pwm/Makefile
> >> @@ -22,6 +22,7 @@ obj-$(CONFIG_PWM_IMX1)		+= pwm-imx1.o
> >>  obj-$(CONFIG_PWM_IMX27)		+= pwm-imx27.o
> >>  obj-$(CONFIG_PWM_IMX_TPM)	+= pwm-imx-tpm.o
> >>  obj-$(CONFIG_PWM_INTEL_LGM)	+= pwm-intel-lgm.o
> >> +obj-$(CONFIG_PWM_IPQ)		+= pwm-ipq.o
> >>  obj-$(CONFIG_PWM_IQS620A)	+= pwm-iqs620a.o
> >>  obj-$(CONFIG_PWM_JZ4740)	+= pwm-jz4740.o
> >>  obj-$(CONFIG_PWM_KEEMBAY)	+= pwm-keembay.o
> >> diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c
> >> new file mode 100644
> >> index 000000000000..3764010808f0
> >> --- /dev/null
> >> +++ b/drivers/pwm/pwm-ipq.c
> >> @@ -0,0 +1,275 @@
> >> +// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
> >> +/*
> >> + * Copyright (c) 2016-2017, 2020 The Linux Foundation. All rights reserved.
> >> + */
> >> +
> >> +#include <linux/module.h>
> >> +#include <linux/platform_device.h>
> >> +#include <linux/pwm.h>
> >> +#include <linux/clk.h>
> >> +#include <linux/io.h>
> >> +#include <linux/of.h>
> >> +#include <linux/math64.h>
> >> +#include <linux/of_device.h>
> >> +#include <linux/bitfield.h>
> >> +
> >> +/* The frequency range supported is 1 Hz to clock rate */
> >> +#define IPQ_PWM_MAX_PERIOD_NS	((u64)NSEC_PER_SEC)
> >> +
> >> +/*
> >> + * The max value specified for each field is based on the number of bits
> >> + * in the pwm control register for that field
> >> + */
> >> +#define IPQ_PWM_MAX_DIV		0xFFFF
> >> +
> >> +/*
> >> + * Two 32-bit registers for each PWM: REG0, and REG1.
> >> + * Base offset for PWM #i is at 8 * #i.
> >> + */
> >> +#define IPQ_PWM_REG0			0 /*PWM_DIV PWM_HI*/
> >> +#define IPQ_PWM_REG0_PWM_DIV		GENMASK(15, 0)
> >> +#define IPQ_PWM_REG0_HI_DURATION	GENMASK(31, 16)
> >
> > PWM_HI in the comment of IPQ_PWM_REG0 vs. HI_DURATION? Should this
> > match? I'd say the comment is redundant.
> >
> >> +#define IPQ_PWM_REG1			4 /*ENABLE UPDATE PWM_PRE_DIV*/
> >> +#define IPQ_PWM_REG1_PRE_DIV		GENMASK(15, 0)
> >> +/*
> >> + * Enable bit is set to enable output toggling in pwm device.
> >> + * Update bit is set to reflect the changed divider and high duration
> >> + * values in register.
> >> + */
> >> +#define IPQ_PWM_REG1_UPDATE		BIT(30)
> >> +#define IPQ_PWM_REG1_ENABLE		BIT(31)
> >> +
> >> +
> >> +struct ipq_pwm_chip {
> >> +	struct pwm_chip chip;
> >> +	struct clk *clk;
> >> +	void __iomem *mem;
> >> +};
> >> +
> >> +static struct ipq_pwm_chip *ipq_pwm_from_chip(struct pwm_chip *chip)
> >> +{
> >> +	return container_of(chip, struct ipq_pwm_chip, chip);
> >> +}
> >> +
> >> +static unsigned int ipq_pwm_reg_read(struct pwm_device *pwm, unsigned int reg)
> >> +{
> >> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
> >> +	unsigned int off = 8 * pwm->hwpwm + reg;
> >> +
> >> +	return readl(ipq_chip->mem + off);
> >> +}
> >> +
> >> +static void ipq_pwm_reg_write(struct pwm_device *pwm, unsigned int reg,
> >> +			      unsigned int val)
> >> +{
> >> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(pwm->chip);
> >> +	unsigned int off = 8 * pwm->hwpwm + reg;
> >> +
> >> +	writel(val, ipq_chip->mem + off);
> >> +}
> >> +
> >> +static void config_div_and_duty(struct pwm_device *pwm, unsigned int pre_div,
> >> +			unsigned int pwm_div, unsigned long rate, u64 duty_ns,
> >> +			bool enable)
> >> +{
> >> +	unsigned long hi_dur;
> >> +	unsigned long val = 0;
> >> +
> >> +	/*
> >> +	 * high duration = pwm duty * (pwm div + 1)
> >> +	 * pwm duty = duty_ns / period_ns
> >> +	 */
> >> +	hi_dur = div64_u64(duty_ns * rate, (pre_div + 1) * NSEC_PER_SEC);
> >> +
> >> +	val = FIELD_PREP(IPQ_PWM_REG0_HI_DURATION, hi_dur) |
> >> +		FIELD_PREP(IPQ_PWM_REG0_PWM_DIV, pwm_div);
> >> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG0, val);
> >> +
> >> +	val = FIELD_PREP(IPQ_PWM_REG1_PRE_DIV, pre_div);
> >> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
> >> +
> >> +	/* PWM enable toggle needs a separate write to REG1 */
> >> +	val |= IPQ_PWM_REG1_UPDATE;
> >> +	if (enable)
> >> +		val |= IPQ_PWM_REG1_ENABLE;
> >> +	ipq_pwm_reg_write(pwm, IPQ_PWM_REG1, val);
> >> +}
> >> +
> >> +static int ipq_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> >> +			 const struct pwm_state *state)
> >> +{
> >> +	struct ipq_pwm_chip *ipq_chip = ipq_pwm_from_chip(chip);
> >> +	unsigned int pre_div, pwm_div, best_pre_div, best_pwm_div;
> >> +	unsigned long rate = clk_get_rate(ipq_chip->clk);
> >> +	u64 period_ns, duty_ns, period_rate;
> >> +	u64 min_diff;
> >> +
> >> +	if (state->polarity != PWM_POLARITY_NORMAL)
> >> +		return -EINVAL;
> >> +
> >> +	if (state->period < div64_u64(NSEC_PER_SEC, rate))
> >> +		return -ERANGE;
> >
> > NSEC_PER_SEC / rate is the smallest period you can achieve, right?
> > Consider rate = 33333 (Hz), then the minimal period is
> > 30000.30000300003 ns. So you should refuse a request to configure
> > state->period = 30000, but as div64_u64(1000000000, 33333) is 30000 you
> > don't.
> >
> >> +	period_ns = min(state->period, IPQ_PWM_MAX_PERIOD_NS);
> >> +	duty_ns = min(state->duty_cycle, period_ns);
> >> +
> >> +	/*
> >> +	 * period_ns is 1G or less. As long as rate is less than 16 GHz this
> >> +	 * does not overflow.
> >
> > Well, rate cannot be bigger than 4294967295 because an unsigned long
> > cannot hold a bigger value.
> 
> On 64-bit systems __SIZEOF_LONG__ is 8, which can hold more than 2^32.

Ah right, then I suggest to check that in code to make it more explicit
than in a comment.

> >> +	 */
> >> +	period_rate = period_ns * rate;
> >> +	best_pre_div = IPQ_PWM_MAX_DIV;
> >> +	best_pwm_div = IPQ_PWM_MAX_DIV;
> >> +	/* Initial pre_div value such that pwm_div < IPQ_PWM_MAX_DIV */
> 
> Note this comment.

<= ?

> 
> >> +	pre_div = div64_u64(period_rate,
> >> +			(u64)NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1));
> >
> > Hmmm, we want 
> >
> > 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
> > 	-------------------------------------------- <= period_ns
> > 	                  rate
> >
> > , right? Resolving that for pre_div this gives:
> >
> > 	                period_ns * rate
> > 	pre_div <= ----------------------------
> > 	           NSEC_PER_SEC * (pwm_div + 1)
> >
> > The term on the right hand side is maximal for pwm_div == 0 so the
> > possible values for pre_div are
> >
> > 	0 ... min(div64_u64(period_rate / NSEC_PER_SEC), IPQ_PWM_MAX_DIV)
> >
> > isn't it?
> 
> I don't think so. pre_div == 0 will produce pwm_div larger than
> IPQ_PWM_MAX_DIV for a large period_rate value. The initial pre_div here is the
> smallest value that produces pwm_div within it limit.

Ah, got your reasoning. If a pre_div is picked that is smaller than the
value you calculate, a bigger pre_div results in a better approximation.

What strikes me is that if you pick a smaller pre_div, you can still use
pwm_div = IPQ_PWM_MAX_DIV which yields an allowed setting. So while your
argument is right, I'd need a better comment to actually understand it.
Something like:

	/*
	 * We don't need to consider pre_div values smaller than
	 *
	 *                              period_rate
	 *  pre_div_min := ------------------------------------
	 *                 NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)
	 *
	 * because pre_div = pre_div_min results in a better
	 * approximation.
	 */


> > If so, your algorithm is wrong as you're iterating over
> >
> > 	div64_u64(period_rate, NSEC_PER_SEC * (IPQ_PWM_MAX_DIV + 1)) ... IPQ_PWM_MAX_DIV
> 
> The loop stops when pre_div > pwm_div. That should be before pre_div ==
> IPQ_PWM_MAX_DIV because pwm_div <= IPQ_PWM_MAX_DIV. Should I put the pre_div >
> pwm_div condition directly in the for statement?

OK, moving the check isn't necessary.

> > The task here is to calculate the biggest pwm_div for a given pre_div
> > such that
> >
> >
> > 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
> > 	-------------------------------------------- <= period_ns
> > 	                   rate
> >
> > right?
> >
> > This is equivalent to:
> >
> > 	                  period_ns * rate
> > 	pre_div <= ---------------------------- - 1
> > 	           (pre_div + 1) * NSEC_PER_SEC
> >
> > As pre_div is integer, rounding down should be fine?!
> 
> I can't follow. With round down (as in v8) the result is always:
> 
>   NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1) <= period_rate

Yes, that's the condition that a valid configuration should fulfill
because then the configured period is never bigger than the requested
period.
 
> As a result, 'diff' calculation below will always produce diff <= 0. When
> there is no diff == 0 result (bingo) we get IPQ_PWM_MAX_DIV in both best_
> values at the end of the loop.

Looking again, your check is wrong. I think you need:

	diff = period_rate - NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1)

. Given the calculations for pre_div and pwm_div this should never be
negative and you should pick values that minimize diff.

> Do we actually need diff > 0 in the condition below?
> 
> >> +		/*
> >> +		 * pre_div and pwm_div values swap produces the same
> >> +		 * result. This loop goes over all pre_div <= pwm_div
> >> +		 * combinations. The rest are equivalent.
> >> +		 */
> >
> > I'd write:
> >
> > 	/*
> > 	 * Swapping values for pre_div and pwm_div produces the same
> > 	 * period length. So we can skip all settings with pre_div <
> > 	 * pwm_div which results in bigger constraints for selecting the
> > 	 * duty_cycle than with the two values swapped.
> > 	 */
> 
> I'll take your wording with inverted inequality sign.

Right.

Looking forward to your next iteration.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/7e92e2c3/attachment-0001.sig>

From robert.hancock at calian.com  Tue Jan 25 08:15:05 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Tue, 25 Jan 2022 16:15:05 +0000
Subject: [PATCH 3/4] iio: adc: xilinx-ams: Fixed wrong sequencer register
 settings
In-Reply-To: <20220125082108.GE25856@pengutronix.de>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-4-robert.hancock@calian.com>
 <20220125082108.GE25856@pengutronix.de>
Message-ID: <4c5fb3899a8aafa34106a668bcb2807b6f073036.camel@calian.com>

On Tue, 2022-01-25 at 09:21 +0100, Michael Tretter wrote:
> On Wed, 19 Jan 2022 19:02:45 -0600, Robert Hancock wrote:
> > Register settings used for the sequencer configuration register
> > were incorrect, causing some inputs to not be read properly.
> > 
> > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > ---
> >  drivers/iio/adc/xilinx-ams.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > index b93864362dac..199027c93cdc 100644
> > --- a/drivers/iio/adc/xilinx-ams.c
> > +++ b/drivers/iio/adc/xilinx-ams.c
> > @@ -91,8 +91,8 @@
> >  
> >  #define AMS_CONF1_SEQ_MASK		GENMASK(15, 12)
> >  #define AMS_CONF1_SEQ_DEFAULT		FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > 0)
> > -#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 1)
> > -#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > 2)
> > +#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
> > +#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > 3)
> 
> The TRM states that Continuous Loop Mode is 2, but Single Pass Sequence Mode
> is 1, not 3. Is there a reason, why you need to set both bits?

Single pass sequence mode (1) just runs the same sequence only once. To read
these values it needs to switch to single channel mode (3).

The register bits are defined in Table 3-8 of 
https://www.xilinx.com/support/documentation/user_guides/ug580-ultrascale-sysmon.pdf
 .

> 
> Michael
> 
> >  
> >  #define AMS_REG_SEQ0_MASK		GENMASK(15, 0)
> >  #define AMS_REG_SEQ2_MASK		GENMASK(21, 16)
> > -- 
> > 2.31.1
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-arm-kernel__;!!IOGos0k!yGFEjSC1BL20lwurby914len0HCLXyzarwxKJP9Jx30qv_qrERSkRJUiVo_2MdusMVA$ 
> > 
-- 
Robert Hancock
Senior Hardware Designer, Calian Advanced Technologies
www.calian.com

From baruch at tkos.co.il  Tue Jan 25 08:22:45 2022
From: baruch at tkos.co.il (Baruch Siach)
Date: Tue, 25 Jan 2022 18:22:45 +0200
Subject: [PATCH v10 1/3] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <20220125161204.hx5foivny6iupjke@pengutronix.de>
References: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
 <20220119172439.be4xpaqgwzdy26oh@pengutronix.de> <87tuds7y09.fsf@tarshish>
 <20220125161204.hx5foivny6iupjke@pengutronix.de>
Message-ID: <87pmof93wf.fsf@tarshish>

Hi Uwe,

On Tue, Jan 25 2022, Uwe Kleine-K?nig wrote:
> On Tue, Jan 25, 2022 at 03:03:08PM +0200, Baruch Siach wrote:
>> On Wed, Jan 19 2022, Uwe Kleine-K?nig wrote:
>> > The task here is to calculate the biggest pwm_div for a given pre_div
>> > such that
>> >
>> >
>> > 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
>> > 	-------------------------------------------- <= period_ns
>> > 	                   rate
>> >
>> > right?
>> >
>> > This is equivalent to:
>> >
>> > 	                  period_ns * rate
>> > 	pre_div <= ---------------------------- - 1
>> > 	           (pre_div + 1) * NSEC_PER_SEC
>> >
>> > As pre_div is integer, rounding down should be fine?!
>> 
>> I can't follow. With round down (as in v8) the result is always:
>> 
>>   NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1) <= period_rate
>
> Yes, that's the condition that a valid configuration should fulfill
> because then the configured period is never bigger than the requested
> period.
>  
>> As a result, 'diff' calculation below will always produce diff <= 0. When
>> there is no diff == 0 result (bingo) we get IPQ_PWM_MAX_DIV in both best_
>> values at the end of the loop.
>
> Looking again, your check is wrong. I think you need:
>
> 	diff = period_rate - NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1)
>
> . Given the calculations for pre_div and pwm_div this should never be
> negative and you should pick values that minimize diff.

So, if I understand correctly, you suggest to leave round up as in v10,
and invert the diff calculation. Is that correct?

Thanks,
baruch

-- 
                                                     ~. .~   Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
   - baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -


From broonie at kernel.org  Tue Jan 25 08:33:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 16:33:12 +0000
Subject: [PATCH v1 5/7] kselftest/arm64: mte: user_mem: check different
 offsets and sizes
In-Reply-To: <20220125150920.23955-6-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
 <20220125150920.23955-6-joey.gouly@arm.com>
Message-ID: <YfAmSPPjRCpxg6zB@sirena.org.uk>

On Tue, Jan 25, 2022 at 03:09:18PM +0000, Joey Gouly wrote:

> +	int fileoff, ptroff, size;
> +	int sizes[] = {1, 2, 3, 8, 16, 32, 4096};

Assuming the goal is to go up to PAGE_SIZE might it be worth extending
this to cover the case where the kernel has been built for 64K pages?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/4a211650/attachment.sig>

From mark.rutland at arm.com  Tue Jan 25 08:33:39 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 16:33:39 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfAeal8MmLsUIJpo@sirena.org.uk>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk>
Message-ID: <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 03:59:38PM +0000, Mark Brown wrote:
> On Tue, Jan 25, 2022 at 03:00:43PM +0000, Mark Rutland wrote:
> 
> > As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
> > used as a value rather than as a bit mask.
> 
> Well, it's both and we do call it a mask in both the kernel and TF-A
> too...

Here specifically in the boot-wrapper I'm just using it as a value, so I don't
see that those are relevant?

The idea was to be consistent with the <register>_<field>_<valuename> naming,
and avoiding the "why are you programming a mask as the value" questions from
last time around, where the unambiguous options are:

a) Use <register>_<field>_<valuename> definition, as here.

b) Use <register>_<field>_MASK, and add comments at each usage as to why we use
   a mask as a value, to explain why that isn't a bug.

c) Have both <register>_<field>_MASK and some value definition, and use some
   insertion helper to insert the value.

... and I went with (a) because it was the simplest.

Is there a problem with this?

Thanks,
Mark.


From david at redhat.com  Tue Jan 25 08:33:49 2022
From: david at redhat.com (David Hildenbrand)
Date: Tue, 25 Jan 2022 17:33:49 +0100
Subject: [PATCH v2 2/2] mm: cma: try next MAX_ORDER_NR_PAGES during retry
In-Reply-To: <20220112131552.3329380-3-aisheng.dong@nxp.com>
References: <20220112131552.3329380-1-aisheng.dong@nxp.com>
 <20220112131552.3329380-3-aisheng.dong@nxp.com>
Message-ID: <517e1ea1-f826-228b-16a0-da1dc76017cc@redhat.com>

On 12.01.22 14:15, Dong Aisheng wrote:
> On an ARMv7 platform with 32M pageblock(MAX_ORDER 14), we observed a

Did you actually intend to talk about pageblocks here (and below)?

I assume you have to be clearer here that you talk about the maximum
allocation granularity, which is usually bigger than actual pageblock size.

> huge number of repeat retries of CMA allocation (1k+) during booting
> when allocating one page for each of 3 mmc instance probe.
> 
> This is caused by CMA now supports cocurrent allocation since commit
> a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock").
> The pageblock or (MAX_ORDER -1) from which we are trying to allocate
> memory may have already been acquired and isolated by others.
> Current cma_alloc() will then retry the next area by the step of
> bitmap_no + mask + 1 which are very likely within the same isolated range
> and fail again. So when the pageblock or MAX_ORDER is big (e.g. 8192),
> keep retrying in a small step become meaningless because it will be known
> to fail at a huge number of times due to the pageblock has been isolated
> by others, especially when allocating only one or two pages.
> 
> Instread of looping in the same pageblock and wasting CPU mips a lot,
> especially for big pageblock system (e.g. 16M or 32M),
> we try the next MAX_ORDER_NR_PAGES directly.
> 
> Doing this way can greatly mitigate the situtation.
> 
> Below is the original error log during booting:
> [    2.004804] cma: cma_alloc(cma (ptrval), count 1, align 0)
> [    2.010318] cma: cma_alloc(cma (ptrval), count 1, align 0)
> [    2.010776] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> [    2.010785] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> [    2.010793] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> [    2.010800] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> [    2.010807] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> [    2.010814] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> .... (+1K retries)
> 
> After fix, the 1200+ reties can be reduced to 0.
> Another test running 8 VPU decoder in parallel shows that 1500+ retries
> dropped to ~145.
> 
> IOW this patch can improve the CMA allocation speed a lot when there're
> enough CMA memory by reducing retries significantly.
> 
> Cc: Andrew Morton <akpm at linux-foundation.org>
> Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> Cc: Lecopzer Chen <lecopzer.chen at mediatek.com>
> Cc: David Hildenbrand <david at redhat.com>
> Cc: Vlastimil Babka <vbabka at suse.cz>
> CC: stable at vger.kernel.org # 5.11+
> Fixes: a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock")
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> ---
> v1->v2:
>  * change to align with MAX_ORDER_NR_PAGES instead of pageblock_nr_pages
> ---
>  mm/cma.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/mm/cma.c b/mm/cma.c
> index 1c13a729d274..1251f65e2364 100644
> --- a/mm/cma.c
> +++ b/mm/cma.c
> @@ -500,7 +500,9 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
>  		trace_cma_alloc_busy_retry(cma->name, pfn, pfn_to_page(pfn),
>  					   count, align);
>  		/* try again with a bit different memory target */
> -		start = bitmap_no + mask + 1;
> +		start = ALIGN(bitmap_no + mask + 1,
> +			      MAX_ORDER_NR_PAGES >> cma->order_per_bit);

Mind giving the reader a hint in the code why we went for
MAX_ORDER_NR_PAGES?

What would happen if the CMA granularity is bigger than
MAX_ORDER_NR_PAGES? I'd assume no harm done, as we'd try aligning to 0.

-- 
Thanks,

David / dhildenb



From chunkuang.hu at kernel.org  Tue Jan 25 08:36:46 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Wed, 26 Jan 2022 00:36:46 +0800
Subject: [PATCH 1/2] drm: mediatek: mtk_drm_plane: Use kmalloc in
 mtk_plane_duplicate_state
In-Reply-To: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>
References: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAAOTY__59-tYZNAQqFytdZgAYs+hmFxHUrF1FAj4zphiguv12g@mail.gmail.com>

Hi, AngeloGioacchino:

AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
2022?1?18? ?? ??9:38???
>
> There is no need to zero out the newly allocated memory because we are
> duplicating all members of struct mtk_plane_state: switch to kmalloc
> to save some overhead.

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_plane.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> index c74cb94e445e..39cb9a80d976 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c
> @@ -57,7 +57,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane
>         struct mtk_plane_state *old_state = to_mtk_plane_state(plane->state);
>         struct mtk_plane_state *state;
>
> -       state = kzalloc(sizeof(*state), GFP_KERNEL);
> +       state = kmalloc(sizeof(*state), GFP_KERNEL);
>         if (!state)
>                 return NULL;
>
> --
> 2.33.1
>


From chunkuang.hu at kernel.org  Tue Jan 25 08:37:35 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Wed, 26 Jan 2022 00:37:35 +0800
Subject: [PATCH 2/2] drm: mediatek: mtk_drm_crtc: Use kmalloc in
 mtk_drm_crtc_duplicate_state
In-Reply-To: <20220118133759.112458-2-angelogioacchino.delregno@collabora.com>
References: <20220118133759.112458-1-angelogioacchino.delregno@collabora.com>
 <20220118133759.112458-2-angelogioacchino.delregno@collabora.com>
Message-ID: <CAAOTY_9PTK1HoHruvX_6n010aADA5_Rd72TFTMsn4hrH8dts=A@mail.gmail.com>

Hi, AngeloGioacchino:

AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
2022?1?18? ?? ??9:41???
>
> Optimize mtk_drm_crtc_duplicate_state() by switching from kzalloc() to
> kmalloc(): the only variable of this struct that gets checked in other
> functions is `pending_config`, but if that's set to false, then all of
> the remaining variables will only ever be set, but not read - so, also
> set `pending_config` to false.
> This saves us some small overhead.

Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

>
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> index 09fc9ad02c7a..f536a0a927e4 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
> @@ -185,7 +185,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
>  {
>         struct mtk_crtc_state *state;
>
> -       state = kzalloc(sizeof(*state), GFP_KERNEL);
> +       state = kmalloc(sizeof(*state), GFP_KERNEL);
>         if (!state)
>                 return NULL;
>
> @@ -193,6 +193,7 @@ static struct drm_crtc_state *mtk_drm_crtc_duplicate_state(struct drm_crtc *crtc
>
>         WARN_ON(state->base.crtc != crtc);
>         state->base.crtc = crtc;
> +       state->pending_config = false;
>
>         return &state->base;
>  }
> --
> 2.33.1
>


From linux at armlinux.org.uk  Tue Jan 25 08:38:42 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:38:42 +0000
Subject: [PATCH net-next 0/7] net: stmmac/xpcs: modernise PCS support
Message-ID: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>

Hi,

This series updates xpcs and stmmac for the recent changes to phylink
to better support split PCS and to get rid of private MAC validation
functions.

This series is slightly more involved than other conversions as stmmac
has already had optional proper split PCS support.

The first six patches of this series were originally posted on 16th
December for CFT, and Wong Vee Khee reported his Intel Elkhart Lake
setup was fine the first six these. However, no tested-by was given.

The patches:

1) Provide a function to query the xpcs for the interface modes that
   are supported.

2) Populates the MAC capabilities and switches stmmac_validate() to use
   phylink_get_linkmodes(). We do not use phylink_generic_validate() yet
   as (a) we do not always have the supported interfaces populated, and
   (b) the existing code does not restrict based on interface. There
   should be no functional effect from this patch.

3) Populates phylink's supported interfaces from the xpcs when the xpcs
   is configured by firmware and also the firmware configured interface
   mode. Note: this will restrict stmmac to only supporting these
   interfaces modes - stmmac maintainers need to verify that this
   behaviour is acceptable.

4) stmmac_validate() tail-calls xpcs_validate(), but we don't need it to
   now that PCS have their own validation method. Convert stmmac and
   xpcs to use this method instead.

5) xpcs sets the poll field of phylink_pcs to true, meaning xpcs
   requires its status to be polled. There is no need to also set the
   phylink_config.pcs_poll. Remove this.

6) Switch to phylink_generic_validate(). This is probably the most
   contravertial change in this patch set as this will cause the MAC to
   restrict link modes based on the interface mode. From an inspection
   of the xpcs driver, this should be safe, as XPCS only further
   restricts the link modes to a subset of these (whether that is
   correct or not is not an issue I am addressing here.) For
   implementations that do not use xpcs, this is a more open question
   and needs feedback from stmmac maintainers.

7) Convert to use mac_select_pcs() rather than phylink_set_pcs() to set
   the PCS - the intention is to eventually remove phylink_set_pcs()
   once there are no more users of this.

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 147 +++++++---------------
 drivers/net/pcs/pcs-xpcs.c                        |  41 +++---
 include/linux/pcs/pcs-xpcs.h                      |   3 +-
 3 files changed, 73 insertions(+), 118 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:25 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:25 +0000
Subject: [PATCH net-next 1/7] net: xpcs: add support for retrieving supported
 interface modes
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOrp-005LSS-6Z@rmk-PC.armlinux.org.uk>

Add a function to the xpcs driver to retrieve the supported PHY
interface modes, which can be used by drivers to fill in phylink's
supported_interfaces mask.

We validate the interface bit index to ensure that it fits within the
bitmap as xpcs lists PHY_INTERFACE_MODE_MAX in an entry.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-xpcs.c   | 14 ++++++++++++++
 include/linux/pcs/pcs-xpcs.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index cd6742e6ba8b..f45821524fab 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -662,6 +662,20 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 }
 EXPORT_SYMBOL_GPL(xpcs_validate);
 
+void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
+{
+	int i, j;
+
+	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
+		const struct xpcs_compat *compat = &xpcs->id->compat[i];
+
+		for (j = 0; j < compat->num_interfaces; j++)
+			if (compat->interface[j] < PHY_INTERFACE_MODE_MAX)
+				__set_bit(compat->interface[j], interfaces);
+	}
+}
+EXPORT_SYMBOL_GPL(xpcs_get_interfaces);
+
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
 {
 	int ret;
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..3126a4924d92 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -33,6 +33,7 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 		   unsigned int mode);
 void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 		   struct phylink_link_state *state);
+void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:30 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:30 +0000
Subject: [PATCH net-next 2/7] net: stmmac: convert to phylink_get_linkmodes()
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOru-005LSd-9d@rmk-PC.armlinux.org.uk>

Add the MAC speed, duplex and pause capabilities to the phylink_config
structure, and switch stmmac_validate() to use phylink_get_linkmodes()
to generate the mask of supported ethtool link modes.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 125 ++++++------------
 1 file changed, 42 insertions(+), 83 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..e85ca75d394d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -942,95 +942,22 @@ static void stmmac_validate(struct phylink_config *config,
 {
 	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-	int tx_cnt = priv->plat->tx_queues_to_use;
-	int max_speed = priv->plat->max_speed;
-
-	phylink_set(mac_supported, 10baseT_Half);
-	phylink_set(mac_supported, 10baseT_Full);
-	phylink_set(mac_supported, 100baseT_Half);
-	phylink_set(mac_supported, 100baseT_Full);
-	phylink_set(mac_supported, 1000baseT_Half);
-	phylink_set(mac_supported, 1000baseT_Full);
-	phylink_set(mac_supported, 1000baseKX_Full);
 
+	/* This is very similar to phylink_generic_validate() except that
+	 * we always use PHY_INTERFACE_MODE_INTERNAL to get all capabilities.
+	 * This is because we don't always have config->supported_interfaces
+	 * populated (only when we have the XPCS.)
+	 *
+	 * When we do have an XPCS, we could pass state->interface, as XPCS
+	 * limits to a subset of the ethtool link modes allowed here.
+	 */
 	phylink_set(mac_supported, Autoneg);
-	phylink_set(mac_supported, Pause);
-	phylink_set(mac_supported, Asym_Pause);
 	phylink_set_port_modes(mac_supported);
-
-	/* Cut down 1G if asked to */
-	if ((max_speed > 0) && (max_speed < 1000)) {
-		phylink_set(mask, 1000baseT_Full);
-		phylink_set(mask, 1000baseX_Full);
-	} else if (priv->plat->has_gmac4) {
-		if (!max_speed || max_speed >= 2500) {
-			phylink_set(mac_supported, 2500baseT_Full);
-			phylink_set(mac_supported, 2500baseX_Full);
-		}
-	} else if (priv->plat->has_xgmac) {
-		if (!max_speed || (max_speed >= 2500)) {
-			phylink_set(mac_supported, 2500baseT_Full);
-			phylink_set(mac_supported, 2500baseX_Full);
-		}
-		if (!max_speed || (max_speed >= 5000)) {
-			phylink_set(mac_supported, 5000baseT_Full);
-		}
-		if (!max_speed || (max_speed >= 10000)) {
-			phylink_set(mac_supported, 10000baseSR_Full);
-			phylink_set(mac_supported, 10000baseLR_Full);
-			phylink_set(mac_supported, 10000baseER_Full);
-			phylink_set(mac_supported, 10000baseLRM_Full);
-			phylink_set(mac_supported, 10000baseT_Full);
-			phylink_set(mac_supported, 10000baseKX4_Full);
-			phylink_set(mac_supported, 10000baseKR_Full);
-		}
-		if (!max_speed || (max_speed >= 25000)) {
-			phylink_set(mac_supported, 25000baseCR_Full);
-			phylink_set(mac_supported, 25000baseKR_Full);
-			phylink_set(mac_supported, 25000baseSR_Full);
-		}
-		if (!max_speed || (max_speed >= 40000)) {
-			phylink_set(mac_supported, 40000baseKR4_Full);
-			phylink_set(mac_supported, 40000baseCR4_Full);
-			phylink_set(mac_supported, 40000baseSR4_Full);
-			phylink_set(mac_supported, 40000baseLR4_Full);
-		}
-		if (!max_speed || (max_speed >= 50000)) {
-			phylink_set(mac_supported, 50000baseCR2_Full);
-			phylink_set(mac_supported, 50000baseKR2_Full);
-			phylink_set(mac_supported, 50000baseSR2_Full);
-			phylink_set(mac_supported, 50000baseKR_Full);
-			phylink_set(mac_supported, 50000baseSR_Full);
-			phylink_set(mac_supported, 50000baseCR_Full);
-			phylink_set(mac_supported, 50000baseLR_ER_FR_Full);
-			phylink_set(mac_supported, 50000baseDR_Full);
-		}
-		if (!max_speed || (max_speed >= 100000)) {
-			phylink_set(mac_supported, 100000baseKR4_Full);
-			phylink_set(mac_supported, 100000baseSR4_Full);
-			phylink_set(mac_supported, 100000baseCR4_Full);
-			phylink_set(mac_supported, 100000baseLR4_ER4_Full);
-			phylink_set(mac_supported, 100000baseKR2_Full);
-			phylink_set(mac_supported, 100000baseSR2_Full);
-			phylink_set(mac_supported, 100000baseCR2_Full);
-			phylink_set(mac_supported, 100000baseLR2_ER2_FR2_Full);
-			phylink_set(mac_supported, 100000baseDR2_Full);
-		}
-	}
-
-	/* Half-Duplex can only work with single queue */
-	if (tx_cnt > 1) {
-		phylink_set(mask, 10baseT_Half);
-		phylink_set(mask, 100baseT_Half);
-		phylink_set(mask, 1000baseT_Half);
-	}
+	phylink_get_linkmodes(mac_supported, PHY_INTERFACE_MODE_INTERNAL,
+			      config->mac_capabilities);
 
 	linkmode_and(supported, supported, mac_supported);
-	linkmode_andnot(supported, supported, mask);
-
 	linkmode_and(state->advertising, state->advertising, mac_supported);
-	linkmode_andnot(state->advertising, state->advertising, mask);
 
 	/* If PCS is supported, check which modes it supports. */
 	if (priv->hw->xpcs)
@@ -1253,6 +1180,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 {
 	struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
 	struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
+	int max_speed = priv->plat->max_speed;
 	int mode = priv->plat->phy_interface;
 	struct phylink *phylink;
 
@@ -1266,6 +1194,37 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (!fwnode)
 		fwnode = dev_fwnode(priv->device);
 
+	priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+		MAC_10 | MAC_100;
+
+	if (!max_speed || max_speed >= 1000)
+		priv->phylink_config.mac_capabilities |= MAC_1000;
+
+	if (priv->plat->has_gmac4) {
+		if (!max_speed || max_speed >= 2500)
+			priv->phylink_config.mac_capabilities |= MAC_2500FD;
+	} else if (priv->plat->has_xgmac) {
+		if (!max_speed || max_speed >= 2500)
+			priv->phylink_config.mac_capabilities |= MAC_2500FD;
+		if (!max_speed || max_speed >= 5000)
+			priv->phylink_config.mac_capabilities |= MAC_5000FD;
+		if (!max_speed || max_speed >= 10000)
+			priv->phylink_config.mac_capabilities |= MAC_10000FD;
+		if (!max_speed || max_speed >= 25000)
+			priv->phylink_config.mac_capabilities |= MAC_25000FD;
+		if (!max_speed || max_speed >= 40000)
+			priv->phylink_config.mac_capabilities |= MAC_40000FD;
+		if (!max_speed || max_speed >= 50000)
+			priv->phylink_config.mac_capabilities |= MAC_50000FD;
+		if (!max_speed || max_speed >= 100000)
+			priv->phylink_config.mac_capabilities |= MAC_100000FD;
+	}
+
+	/* Half-Duplex can only work with single queue */
+	if (priv->plat->tx_queues_to_use > 1)
+		priv->phylink_config.mac_capabilities &=
+			~(MAC_10HD | MAC_100HD | MAC_1000HD);
+
 	phylink = phylink_create(&priv->phylink_config, fwnode,
 				 mode, &stmmac_phylink_mac_ops);
 	if (IS_ERR(phylink))
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:35 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:35 +0000
Subject: [PATCH net-next 3/7] net: stmmac: fill in supported_interfaces
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOrz-005LSj-Dc@rmk-PC.armlinux.org.uk>

Fill in phylink's supported_interfaces bitmap with the PHY interface
modes which can be used to talk to the PHY.

We indicate that the PHY interface mode passed in platform data is
always supported, as this is the initial mode passed into phylink.
When there is no PCS specified, we assume that this is the only mode
that is supported - indeed, the driver appears not to support dynamic
switching of interface types at present.

When a xpcs is present, it defines the PHY interface modes that the
stmmac driver can support. Request the supported interfaces from the
xpcs driver, and pass them to phylink.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e85ca75d394d..bd20920daf7b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1194,6 +1194,14 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (!fwnode)
 		fwnode = dev_fwnode(priv->device);
 
+	/* Set the platform/firmware specified interface mode */
+	__set_bit(mode, priv->phylink_config.supported_interfaces);
+
+	/* If we have an xpcs, it defines which PHY interfaces are supported. */
+	if (priv->hw->xpcs)
+		xpcs_get_interfaces(priv->hw->xpcs,
+				    priv->phylink_config.supported_interfaces);
+
 	priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100;
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:40 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:40 +0000
Subject: [PATCH net-next 4/7] net: stmmac/xpcs: convert to pcs_validate()
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOs4-005LSp-HF@rmk-PC.armlinux.org.uk>

stmmac explicitly calls the xpcs driver to validate the ethtool
linkmodes. This is no longer necessary as phylink now supports
validation through a PCS method. Convert both drivers to use this
new mechanism.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  4 ---
 drivers/net/pcs/pcs-xpcs.c                    | 27 ++++++++-----------
 include/linux/pcs/pcs-xpcs.h                  |  2 --
 3 files changed, 11 insertions(+), 22 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bd20920daf7b..6c270785cf68 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -958,10 +958,6 @@ static void stmmac_validate(struct phylink_config *config,
 
 	linkmode_and(supported, supported, mac_supported);
 	linkmode_and(state->advertising, state->advertising, mac_supported);
-
-	/* If PCS is supported, check which modes it supports. */
-	if (priv->hw->xpcs)
-		xpcs_validate(priv->hw->xpcs, supported, state);
 }
 
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index f45821524fab..61418d4dc0cd 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -632,35 +632,29 @@ static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
 	}
 }
 
-void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
-		   struct phylink_link_state *state)
+static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+			 const struct phylink_link_state *state)
 {
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported);
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
 	const struct xpcs_compat *compat;
+	struct dw_xpcs *xpcs;
 	int i;
 
-	/* phylink expects us to report all supported modes with
-	 * PHY_INTERFACE_MODE_NA, just don't limit the supported and
-	 * advertising masks and exit.
-	 */
-	if (state->interface == PHY_INTERFACE_MODE_NA)
-		return;
-
-	linkmode_zero(xpcs_supported);
-
+	xpcs = phylink_pcs_to_xpcs(pcs);
 	compat = xpcs_find_compat(xpcs->id, state->interface);
 
-	/* Populate the supported link modes for this
-	 * PHY interface type
+	/* Populate the supported link modes for this PHY interface type.
+	 * FIXME: what about the port modes and autoneg bit? This masks
+	 * all those away.
 	 */
 	if (compat)
 		for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
 			set_bit(compat->supported[i], xpcs_supported);
 
 	linkmode_and(supported, supported, xpcs_supported);
-	linkmode_and(state->advertising, state->advertising, xpcs_supported);
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(xpcs_validate);
 
 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
 {
@@ -1120,6 +1114,7 @@ static const struct xpcs_id xpcs_id_list[] = {
 };
 
 static const struct phylink_pcs_ops xpcs_phylink_ops = {
+	.pcs_validate = xpcs_validate,
 	.pcs_config = xpcs_config,
 	.pcs_get_state = xpcs_get_state,
 	.pcs_link_up = xpcs_link_up,
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index 3126a4924d92..266eb26fb029 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -31,8 +31,6 @@ void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
 		  phy_interface_t interface, int speed, int duplex);
 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 		   unsigned int mode);
-void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
-		   struct phylink_link_state *state);
 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:45 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:45 +0000
Subject: [PATCH net-next 5/7] net: stmmac: remove phylink_config.pcs_poll usage
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOs9-005LSz-KX@rmk-PC.armlinux.org.uk>

Phylink will use PCS polling whenever the PCS's poll member is set, so
setting phylink_config.pcs_poll as well is redundant.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6c270785cf68..243016400aba 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1182,7 +1182,6 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 
 	priv->phylink_config.dev = &priv->dev->dev;
 	priv->phylink_config.type = PHYLINK_NETDEV;
-	priv->phylink_config.pcs_poll = true;
 	if (priv->plat->mdio_bus_data)
 		priv->phylink_config.ovr_an_inband =
 			mdio_bus_data->xpcs_an_inband;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:50 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:50 +0000
Subject: [PATCH net-next 6/7] net: stmmac: convert to
 phylink_generic_validate()
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOsE-005LT5-NU@rmk-PC.armlinux.org.uk>

Convert stmmac to use phylink_generic_validate() now that we have the
MAC capabilities and supported interfaces filled in, and we have the
PCS validation handled via the PCS operations.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 26 +------------------
 1 file changed, 1 insertion(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 243016400aba..0fd96a98f489 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -936,30 +936,6 @@ static void stmmac_mac_flow_ctrl(struct stmmac_priv *priv, u32 duplex)
 			priv->pause, tx_cnt);
 }
 
-static void stmmac_validate(struct phylink_config *config,
-			    unsigned long *supported,
-			    struct phylink_link_state *state)
-{
-	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
-
-	/* This is very similar to phylink_generic_validate() except that
-	 * we always use PHY_INTERFACE_MODE_INTERNAL to get all capabilities.
-	 * This is because we don't always have config->supported_interfaces
-	 * populated (only when we have the XPCS.)
-	 *
-	 * When we do have an XPCS, we could pass state->interface, as XPCS
-	 * limits to a subset of the ethtool link modes allowed here.
-	 */
-	phylink_set(mac_supported, Autoneg);
-	phylink_set_port_modes(mac_supported);
-	phylink_get_linkmodes(mac_supported, PHY_INTERFACE_MODE_INTERNAL,
-			      config->mac_capabilities);
-
-	linkmode_and(supported, supported, mac_supported);
-	linkmode_and(state->advertising, state->advertising, mac_supported);
-}
-
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
 			      const struct phylink_link_state *state)
 {
@@ -1096,7 +1072,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 }
 
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
-	.validate = stmmac_validate,
+	.validate = phylink_generic_validate,
 	.mac_config = stmmac_mac_config,
 	.mac_link_down = stmmac_mac_link_down,
 	.mac_link_up = stmmac_mac_link_up,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Tue Jan 25 08:40:55 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Tue, 25 Jan 2022 16:40:55 +0000
Subject: [PATCH net-next 7/7] net: stmmac: use .mac_select_pcs() interface
In-Reply-To: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
Message-ID: <E1nCOsJ-005LTB-R6@rmk-PC.armlinux.org.uk>

Convert stmmac to use the mac_select_pcs() interface rather than using
phylink_set_pcs(). The intention here is to unify the approach for PCS
and eventually to remove phylink_set_pcs().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0fd96a98f489..e4381e13dae5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -936,6 +936,17 @@ static void stmmac_mac_flow_ctrl(struct stmmac_priv *priv, u32 duplex)
 			priv->pause, tx_cnt);
 }
 
+static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config,
+						 phy_interface_t interface)
+{
+	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
+
+	if (!priv->hw->xpcs)
+		return NULL;
+
+	return &priv->hw->xpcs->pcs;
+}
+
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
 			      const struct phylink_link_state *state)
 {
@@ -1073,6 +1084,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
 	.validate = phylink_generic_validate,
+	.mac_select_pcs = stmmac_mac_select_pcs,
 	.mac_config = stmmac_mac_config,
 	.mac_link_down = stmmac_mac_link_down,
 	.mac_link_up = stmmac_mac_link_up,
@@ -1209,9 +1221,6 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (IS_ERR(phylink))
 		return PTR_ERR(phylink);
 
-	if (priv->hw->xpcs)
-		phylink_set_pcs(phylink, &priv->hw->xpcs->pcs);
-
 	priv->phylink = phylink;
 	return 0;
 }
-- 
2.30.2



From chunkuang.hu at kernel.org  Tue Jan 25 08:44:14 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Wed, 26 Jan 2022 00:44:14 +0800
Subject: [PATCH] drm/mediatek: DP HPD Detect with debounce
In-Reply-To: <20220112150133.11275-1-jitao.shi@mediatek.com>
References: <20220112150133.11275-1-jitao.shi@mediatek.com>
Message-ID: <CAAOTY_8v6UvcVcLL2ba-pOXD2UwF=qoTNNk9FNtK7CYDBQOfhQ@mail.gmail.com>

Hi, Jitao:

Jitao Shi <jitao.shi at mediatek.com> ? 2022?1?12? ?? ??11:01???
>
> DP Spec 1.4a 3.3 requires dp detect the hpd with debounce.
>
> Upstream implementations should implement HPD signal de-bouncing on
> an external connection. A period of 100ms should be used for
> detecting an HPD connect event (i.e., the event, ?HPD high,? is
> confirmed only after HPD has been continuously asserted for 100ms).
> Care should be taken to not implement de-bouncing on an IRQ_HPD and
> on a downstream device-generated pair of HPD disconnect/reconnect
> events (typically HPD shall be de-asserted for more than 2ms, but
> less than 100ms in this case). To cover these cases, HPD de-bounce
> should be implemented only after HPD low has been detected for 100ms.
>  Timing requirements in this Standard related to the detection of
> HPD high are to be interpreted as applying from the completion of an
> implementation-dependent de-bounce period.
>
> Signed-off-by: Jitao Shi <jitao.shi at mediatek.com>
> ---

mtk dp driver has not been upstreamed yet. This patch seems depend on
another series [1]. Please describe the dependency information here.

[1] https://patchwork.kernel.org/project/linux-mediatek/list/?series=597485

Regards,
Chun-Kuang.

>  drivers/gpu/drm/mediatek/mtk_dp.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c
> index a256d55346a2..05f401a024a4 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dp.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dp.c
> @@ -193,6 +193,8 @@ struct mtk_dp {
>         struct mutex eld_lock;
>         u8 connector_eld[MAX_ELD_BYTES];
>         struct drm_connector *conn;
> +       bool need_debounce;
> +       struct timer_list debounce_timer;
>  };
>
>  enum mtk_dp_sdp_type {
> @@ -2217,6 +2219,9 @@ static irqreturn_t mtk_dp_hpd_event_thread(int hpd, void *dev)
>         if (event < 0)
>                 return IRQ_HANDLED;
>
> +       if (mtk_dp->need_debounce && mtk_dp->train_info.cable_plugged_in)
> +               msleep(100);
> +
>         if (mtk_dp->drm_dev) {
>                 dev_info(mtk_dp->dev, "drm_helper_hpd_irq_event\n");
>                 drm_helper_hpd_irq_event(mtk_dp->bridge.dev);
> @@ -2296,6 +2301,14 @@ static irqreturn_t mtk_dp_hpd_isr_handler(struct mtk_dp *mtk_dp)
>                 mtk_dp->train_state = MTK_DP_TRAIN_STATE_STARTUP;
>         }
>         train_info->cable_state_change = true;
> +
> +       if (train_info->cable_state_change) {
> +               if (!train_info->cable_plugged_in) {
> +                       mod_timer(&mtk_dp->debounce_timer, jiffies + msecs_to_jiffies(100) - 1);
> +                       mtk_dp->need_debounce = false;
> +               }
> +       }
> +
>         return IRQ_WAKE_THREAD;
>  }
>
> @@ -2903,6 +2916,13 @@ static int mtk_dp_register_audio_driver(struct device *dev)
>         return 0;
>  }
>
> +static void mtk_dp_debounce_timer(struct timer_list *t)
> +{
> +       struct mtk_dp *mtk_dp = from_timer(mtk_dp, t, debounce_timer);
> +
> +       mtk_dp->need_debounce = true;
> +}
> +
>  static int mtk_dp_probe(struct platform_device *pdev)
>  {
>         struct mtk_dp *mtk_dp;
> @@ -2990,6 +3010,9 @@ static int mtk_dp_probe(struct platform_device *pdev)
>         else
>                 mtk_dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
>
> +       mtk_dp->need_debounce = true;
> +       timer_setup(&mtk_dp->debounce_timer, mtk_dp_debounce_timer, 0);
> +
>         mtk_dp->bridge.ops =
>                 DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD;
>         drm_bridge_add(&mtk_dp->bridge);
> @@ -3008,6 +3031,7 @@ static int mtk_dp_remove(struct platform_device *pdev)
>
>         mtk_dp_video_mute(mtk_dp, true);
>         mtk_dp_audio_mute(mtk_dp, true);
> +       del_timer_sync(&mtk_dp->debounce_timer);
>
>         pm_runtime_disable(&pdev->dev);
>
> --
> 2.12.5
>


From patchwork-bot+netdevbpf at kernel.org  Tue Jan 25 08:46:14 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Tue, 25 Jan 2022 16:46:14 +0000
Subject: [PATCH] net: stmmac: reduce unnecessary wakeups from eee sw timer
In-Reply-To: <20220123155458.2288-1-jszhang@kernel.org>
References: <20220123155458.2288-1-jszhang@kernel.org>
Message-ID: <164312917420.15904.15680846947944122595.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Sun, 23 Jan 2022 23:54:58 +0800 you wrote:
> Currently, on EEE capable platforms, if EEE SW timer is used, the SW
> timer cause 1 wakeup/s even if the TX has successfully entered EEE.
> Remove this unnecessary wakeup by only calling mod_timer() if we
> haven't successfully entered EEE.
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> 
> [...]

Here is the summary with links:
  - net: stmmac: reduce unnecessary wakeups from eee sw timer
    https://git.kernel.org/netdev/net/c/c74ead223deb

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From mathieu.poirier at linaro.org  Tue Jan 25 08:46:25 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Tue, 25 Jan 2022 09:46:25 -0700
Subject: [PATCH] coresight: tmc: change device registration from misc to
 cdev
In-Reply-To: <117e6569-bd2e-830a-70e3-dd26dfae26c8@linux.alibaba.com>
References: <20220124110018.68485-1-jkchen@linux.alibaba.com>
 <CANLsYkxTy3fWgKx2QotWsSC9WZSmAroiFhMkPa9HapvzZNDjRg@mail.gmail.com>
 <117e6569-bd2e-830a-70e3-dd26dfae26c8@linux.alibaba.com>
Message-ID: <20220125164625.GA2089782@p14s>

On Tue, Jan 25, 2022 at 10:33:45AM +0800, Jiankang Chen wrote:
> Hi Mathieu
> 
> ? 2022/1/25 04:08, Mathieu Poirier ??:
> > On Mon, 24 Jan 2022 at 04:00, Jay Chen <jkchen at linux.alibaba.com> wrote:
> > > Currently, there are 130 etr and etf on our machine,
> > > but the current coresight tmc driver uses misc_register
> > > to register the device, which leads to the error that
> > > the device number is not enough.
> > > 
> > > coresight-tmc: probe of xxxxx failed with error -16
> > > 
> > > This patch changes the device registration method
> > > to cdev's dynamic registration method to solve the
> > > problem of insufficient device numbers.
> > This patch is still not labelled properly and as such being dropped.
> 
> Hello, about the label of this patch, what kind of patch should I add?
>

So far you've sent 6 different version of this patch...  Wouldn't it make sense
to label this one "PATCH v7" ?

Leo has pointed out a good presentation from Marc Zingier - I also suggest you
invest time reading it.

> Thanks very much
> 
> jay
> 
> > > Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
> > > ---
> > >   .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
> > >   drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
> > >   2 files changed, 91 insertions(+), 23 deletions(-)
> > > 
> > > diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > > index d0276af82494..0977f1ce6338 100644
> > > --- a/drivers/hwtracing/coresight/coresight-tmc-core.c
> > > +++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
> > > @@ -12,7 +12,6 @@
> > >   #include <linux/io.h>
> > >   #include <linux/err.h>
> > >   #include <linux/fs.h>
> > > -#include <linux/miscdevice.h>
> > >   #include <linux/mutex.h>
> > >   #include <linux/property.h>
> > >   #include <linux/uaccess.h>
> > > @@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
> > >   DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
> > >   DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
> > > 
> > > +static DEFINE_IDA(tmc_ida);
> > > +static dev_t tmc_major;
> > > +static struct class *tmc_class;
> > > +
> > > +#define TMC_DEV_MAX    (MINORMASK + 1)
> > > +
> > >   void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
> > >   {
> > >          struct coresight_device *csdev = drvdata->csdev;
> > > @@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
> > >   static int tmc_open(struct inode *inode, struct file *file)
> > >   {
> > >          int ret;
> > > -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> > > -                                                  struct tmc_drvdata, miscdev);
> > > +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> > > +                                            struct tmc_cdev, cdev);
> > > +       struct tmc_drvdata *drvdata = container_of(cdev,
> > > +                                                  struct tmc_drvdata, cdev);
> > > 
> > >          ret = tmc_read_prepare(drvdata);
> > >          if (ret)
> > > @@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
> > >   {
> > >          char *bufp;
> > >          ssize_t actual;
> > > -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> > > -                                                  struct tmc_drvdata, miscdev);
> > > +       struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
> > > +                                            struct tmc_cdev, cdev);
> > > +       struct tmc_drvdata *drvdata = container_of(cdev,
> > > +                                                  struct tmc_drvdata, cdev);
> > >          actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
> > >          if (actual <= 0)
> > >                  return 0;
> > > @@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
> > >   static int tmc_release(struct inode *inode, struct file *file)
> > >   {
> > >          int ret;
> > > -       struct tmc_drvdata *drvdata = container_of(file->private_data,
> > > -                                                  struct tmc_drvdata, miscdev);
> > > +       struct tmc_cdev *cdev = container_of(inode->i_cdev,
> > > +                                            struct tmc_cdev, cdev);
> > > +       struct tmc_drvdata *drvdata = container_of(cdev,
> > > +                                                  struct tmc_drvdata, cdev);
> > > 
> > >          ret = tmc_read_unprepare(drvdata);
> > >          if (ret)
> > > @@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
> > >   {
> > >          int ret = 0;
> > >          u32 devid;
> > > +       dev_t devt;
> > >          void __iomem *base;
> > >          struct device *dev = &adev->dev;
> > >          struct coresight_platform_data *pdata = NULL;
> > > @@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
> > >                  goto out;
> > >          }
> > > 
> > > -       drvdata->miscdev.name = desc.name;
> > > -       drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
> > > -       drvdata->miscdev.fops = &tmc_fops;
> > > -       ret = misc_register(&drvdata->miscdev);
> > > +       ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
> > > +       if (ret < 0)
> > > +               goto err_coresight_unregister;
> > > +
> > > +       cdev_init(&drvdata->cdev.cdev, &tmc_fops);
> > > +       drvdata->cdev.cdev.owner = THIS_MODULE;
> > > +       devt = MKDEV(MAJOR(tmc_major), ret);
> > > +       ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
> > >          if (ret)
> > > -               coresight_unregister(drvdata->csdev);
> > > -       else
> > > +               goto err_free_tmc_ida;
> > > +
> > > +       drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
> > > +       if (IS_ERR(drvdata->cdev.dev)) {
> > > +               ret = PTR_ERR(drvdata->cdev.dev);
> > > +               goto err_delete_cdev;
> > > +       } else
> > >                  pm_runtime_put(&adev->dev);
> > > +
> > > +       return 0;
> > > +
> > > +err_delete_cdev:
> > > +       cdev_del(&drvdata->cdev.cdev);
> > > +err_free_tmc_ida:
> > > +       ida_simple_remove(&tmc_ida, MINOR(devt));
> > > +err_coresight_unregister:
> > > +       coresight_unregister(drvdata->csdev);
> > >   out:
> > >          return ret;
> > >   }
> > > @@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
> > >   static void tmc_remove(struct amba_device *adev)
> > >   {
> > >          struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > +       struct device *dev = drvdata->cdev.dev;
> > > 
> > > -       /*
> > > -        * Since misc_open() holds a refcount on the f_ops, which is
> > > -        * etb fops in this case, device is there until last file
> > > -        * handler to this device is closed.
> > > -        */
> > > -       misc_deregister(&drvdata->miscdev);
> > > +       ida_simple_remove(&tmc_ida, MINOR(dev->devt));
> > > +       device_destroy(tmc_class, dev->devt);
> > > +       cdev_del(&drvdata->cdev.cdev);
> > >          coresight_unregister(drvdata->csdev);
> > >   }
> > > 
> > > @@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
> > >          .id_table       = tmc_ids,
> > >   };
> > > 
> > > -module_amba_driver(tmc_driver);
> > > +static int __init tmc_init(void)
> > > +{
> > > +       int ret;
> > > +
> > > +       ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
> > > +       if (ret < 0) {
> > > +               pr_err("tmc: failed to allocate char dev region\n");
> > > +               return ret;
> > > +       }
> > > +
> > > +       tmc_class = class_create(THIS_MODULE, "tmc");
> > > +       if (IS_ERR(tmc_class)) {
> > > +               pr_err("tmc: failed to create class\n");
> > > +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> > > +               return PTR_ERR(tmc_class);
> > > +       }
> > > +
> > > +       ret = amba_driver_register(&tmc_driver);
> > > +       if (ret) {
> > > +               pr_err("tmc: error registering amba driver\n");
> > > +               class_destroy(tmc_class);
> > > +               unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> > > +       }
> > > +
> > > +       return ret;
> > > +}
> > > +
> > > +static void __exit tmc_exit(void)
> > > +{
> > > +       amba_driver_unregister(&tmc_driver);
> > > +       class_destroy(tmc_class);
> > > +       unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
> > > +}
> > > +
> > > +module_init(tmc_init);
> > > +module_exit(tmc_exit);
> > > 
> > >   MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
> > >   MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
> > > diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
> > > index 6bec20a392b3..11441c6b9c26 100644
> > > --- a/drivers/hwtracing/coresight/coresight-tmc.h
> > > +++ b/drivers/hwtracing/coresight/coresight-tmc.h
> > > @@ -7,9 +7,9 @@
> > >   #ifndef _CORESIGHT_TMC_H
> > >   #define _CORESIGHT_TMC_H
> > > 
> > > +#include <linux/cdev.h>
> > >   #include <linux/dma-mapping.h>
> > >   #include <linux/idr.h>
> > > -#include <linux/miscdevice.h>
> > >   #include <linux/mutex.h>
> > >   #include <linux/refcount.h>
> > > 
> > > @@ -163,11 +163,16 @@ struct etr_buf {
> > >          void                            *private;
> > >   };
> > > 
> > > +struct tmc_cdev {
> > > +       struct cdev cdev;
> > > +       struct device *dev;
> > > +};
> > > +
> > >   /**
> > >    * struct tmc_drvdata - specifics associated to an TMC component
> > >    * @base:      memory mapped base address for this component.
> > >    * @csdev:     component vitals needed by the framework.
> > > - * @miscdev:   specifics to handle "/dev/xyz.tmc" entry.
> > > + * @tmc_cdev:  specifics to handle "/dev/xyz.tmc" entry.
> > >    * @spinlock:  only one at a time pls.
> > >    * @pid:       Process ID of the process being monitored by the session
> > >    *             that is using this component.
> > > @@ -191,7 +196,7 @@ struct etr_buf {
> > >   struct tmc_drvdata {
> > >          void __iomem            *base;
> > >          struct coresight_device *csdev;
> > > -       struct miscdevice       miscdev;
> > > +       struct tmc_cdev         cdev;
> > >          spinlock_t              spinlock;
> > >          pid_t                   pid;
> > >          bool                    reading;
> > > --
> > > 2.27.0
> > > 


From colin.foster at in-advantage.com  Tue Jan 25 08:46:59 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Tue, 25 Jan 2022 08:46:59 -0800
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
In-Reply-To: <20220125161245.418882-1-horatiu.vultur@microchip.com>
References: <20220125161245.418882-1-horatiu.vultur@microchip.com>
Message-ID: <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>

Hi Horatiu,

On Tue, Jan 25, 2022 at 05:12:45PM +0100, Horatiu Vultur wrote:
> Initially the driver accessed the registers using u32 __iomem but then
> in the blamed commit it changed it to use regmap. The problem is that now
> the offset of the registers is not calculated anymore at word offset but
> at byte offset. Therefore make sure to multiply the offset with word size.
> 

Sorry about this one. I see it must have slipped through the cracks
because I had made the same change in my tree. The only difference is I
had copied reg_stride into sgpio_priv instead of making regmap_config
file-scope. For what its worth, with apologies:

Reviewed-by: Colin Foster <colin.foster at in-advantage.com>

> Fixes: 2afbbab45c261a ("pinctrl: microchip-sgpio: update to support regmap")
> Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> ---
>  drivers/pinctrl/pinctrl-microchip-sgpio.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
> index 8e081c90bdb2..2999c98bbdee 100644
> --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
> +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
> @@ -98,6 +98,12 @@ static const struct sgpio_properties properties_sparx5 = {
>  	.regoff = { 0x00, 0x06, 0x26, 0x04, 0x05, 0x2a, 0x32, 0x3a, 0x3e, 0x42 },
>  };
>  
> +static const struct regmap_config regmap_config = {
> +		.reg_bits = 32,
> +		.val_bits = 32,
> +		.reg_stride = 4,
> +};
> +
>  static const char * const functions[] = { "gpio" };
>  
>  struct sgpio_bank {
> @@ -137,7 +143,7 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
>  
>  static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
>  {
> -	return priv->properties->regoff[rno] + off;
> +	return (priv->properties->regoff[rno] + off) * regmap_config.reg_stride;
>  }
>  
>  static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
> @@ -821,11 +827,6 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
>  	struct clk *clk;
>  	u32 __iomem *regs;
>  	u32 val;
> -	struct regmap_config regmap_config = {
> -		.reg_bits = 32,
> -		.val_bits = 32,
> -		.reg_stride = 4,
> -	};
>  
>  	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>  	if (!priv)
> -- 
> 2.33.0
> 


From ezequiel at vanguardiasur.com.ar  Tue Jan 25 08:48:00 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 25 Jan 2022 13:48:00 -0300
Subject: [PATCH V3 10/10] arm64: dts: imx8mm: Enable Hantro G1 and G2
 video decoders
In-Reply-To: <20220124023125.414794-11-aford173@gmail.com>
References: <20220124023125.414794-1-aford173@gmail.com>
 <20220124023125.414794-11-aford173@gmail.com>
Message-ID: <YfApwHMi5IYxHtq8@eze-laptop>

Hi Adam,

On Sun, Jan 23, 2022 at 08:31:24PM -0600, Adam Ford wrote:
> There are two decoders on the i.MX8M Mini controlled by the
> vpu-blk-ctrl.  The G1 supports H264 and VP8 while the
> G2 support HEVC and VP9.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 

Looks good.

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Thanks,
Ezequiel

> diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> index 0c7a72c51a31..98aec4421713 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> @@ -1272,6 +1272,22 @@ gpu_2d: gpu at 38008000 {
>  			power-domains = <&pgc_gpu>;
>  		};
>  
> +		vpu_g1: video-codec at 38300000 {
> +			compatible = "nxp,imx8mm-vpu-g1";
> +			reg = <0x38300000 0x10000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G1>;
> +		};
> +
> +		vpu_g2: video-codec at 38310000 {
> +			compatible = "nxp,imx8mq-vpu-g2";
> +			reg = <0x38310000 0x10000>;
> +			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G2>;
> +		};
> +
>  		vpu_blk_ctrl: blk-ctrl at 38330000 {
>  			compatible = "fsl,imx8mm-vpu-blk-ctrl", "syscon";
>  			reg = <0x38330000 0x100>;
> @@ -1282,6 +1298,12 @@ vpu_blk_ctrl: blk-ctrl at 38330000 {
>  				 <&clk IMX8MM_CLK_VPU_G2_ROOT>,
>  				 <&clk IMX8MM_CLK_VPU_H1_ROOT>;
>  			clock-names = "g1", "g2", "h1";
> +			assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>,
> +					  <&clk IMX8MM_CLK_VPU_G2>;
> +			assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>,
> +						 <&clk IMX8MM_VPU_PLL_OUT>;
> +			assigned-clock-rates = <600000000>,
> +					       <600000000>;
>  			#power-domain-cells = <1>;
>  		};
>  
> -- 
> 2.32.0
> 


From maz at kernel.org  Tue Jan 25 08:51:45 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 16:51:45 +0000
Subject: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and
 PAC trap errata
In-Reply-To: <20220125153803.549084-5-james.morse@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
 <20220125153803.549084-5-james.morse@arm.com>
Message-ID: <87mtjj7o7y.wl-maz@kernel.org>

Hi James,

Thanks for this. I guess.

On Tue, 25 Jan 2022 15:38:03 +0000,
James Morse <james.morse at arm.com> wrote:
> 
> Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
> single-stepping authenticated ERET instructions. A single step is
> expected, but a pointer authentication trap is taken instead. The
> erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
> EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
> 
> Because the conditions require an ERET into active-not-pending state,
> this is only a problem for the EL2 when EL2 is stepping EL1. In this case
> the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
> restored.

Urgh. That's pretty nasty :-(.

> 
> Cc: stable at vger.kernel.org # ${GITHASHHERE}: arm64: Add Cortex-A510 CPU part definition
> Cc: stable at vger.kernel.org
> Signed-off-by: James Morse <james.morse at arm.com>
> ---
>  Documentation/arm64/silicon-errata.rst  |  2 ++
>  arch/arm64/Kconfig                      | 16 ++++++++++++++++
>  arch/arm64/kernel/cpu_errata.c          |  8 ++++++++
>  arch/arm64/kvm/hyp/include/hyp/switch.h | 24 +++++++++++++++++++++---
>  arch/arm64/tools/cpucaps                |  1 +
>  5 files changed, 48 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 5342e895fb60..ac1ae34564c9 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -92,6 +92,8 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A510     | #2077057        | ARM64_ERRATUM_2077057       |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 6978140edfa4..02b542ec18c8 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -670,6 +670,22 @@ config ARM64_ERRATUM_1508412
>  config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  	bool
>  
> +config ARM64_ERRATUM_2077057
> +	bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2"
> +	help
> +	  This option adds the workaround for ARM Cortex-A510 erratum 2077057.
> +	  Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is
> +	  expected, but a Pointer Authentication trap is taken instead. The
> +	  erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
> +	  EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
> +
> +	  This can only happen when EL2 is stepping EL1.
> +
> +	  When these conditions occur, the SPSR_EL2 value is unchanged from the
> +	  previous guest entry, and can be restored from the in-memory copy.
> +
> +	  If unsure, say Y.
> +
>  config ARM64_ERRATUM_2119858
>  	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
>  	default y
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..04a014c63251 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -597,6 +597,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>  		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>  		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>  	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_2077057
> +	{
> +		.desc = "ARM erratum 2077057",
> +		.capability = ARM64_WORKAROUND_2077057,
> +		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
> +		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
> +	},
>  #endif
>  	{
>  	}
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 331dd10821df..93bf140cc972 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -409,6 +409,8 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>   */
>  static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  {
> +	u8 esr_ec;
> +
>  	/*
>  	 * Save PSTATE early so that we can evaluate the vcpu mode
>  	 * early on.
> @@ -421,13 +423,13 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  	 */
>  	early_exit_filter(vcpu, exit_code);
>  
> -	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
> +	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
>  		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
> +		esr_ec = kvm_vcpu_trap_get_class(vcpu);
> +	}
>  
>  	if (ARM_SERROR_PENDING(*exit_code) &&
>  	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
> -		u8 esr_ec = kvm_vcpu_trap_get_class(vcpu);
> -
>  		/*
>  		 * HVC already have an adjusted PC, which we need to
>  		 * correct in order to return to after having injected
> @@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
>  	}
>  
> +	/*
> +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
> +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
> +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
> +	 * Did we just take a PAC exception when a step exception was expected?
> +	 */
> +	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&

nit: we can drop this IS_ENABLED()...

> +	    cpus_have_const_cap(ARM64_WORKAROUND_2077057) &&

and make this a final cap. Being a ARM64_CPUCAP_LOCAL_CPU_ERRATUM, we
won't accept late CPUs on a system that wasn't affected until then.

> +	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ &&
> +	    esr_ec == ESR_ELx_EC_PAC &&
> +	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
> +		/* Active-not-pending? */
> +		if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
> +			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);

Err... Isn't this way too late? The function starts with:

	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);

which is just another way to write:

	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);

By that time, the vcpu's PSTATE is terminally corrupted.

I think you need to hoist this workaround way up, before we call into
early_exit_filter() as it will assume that the guest pstate is correct
(this is used by both pKVM and the NV code).

Something like this (untested):

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 93bf140cc972..a8a1502db237 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -402,6 +402,26 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return false;
 }
 
+static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu,
+					   u64 *exit_code)
+{
+	/*
+	 * Check for the conditions of Cortex-A510's #2077057. When these occur
+	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
+	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
+	 * Did we just take a PAC exception when a step exception (being in the
+	 * Active-not-pending state) was expected?
+	 */
+	if (cpus_have_final_cap(ARM64_WORKAROUND_2077057)	&&
+	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ	&&
+	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_PAC	&&
+	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP		&&
+	    *vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+		write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+
+	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -415,7 +435,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	 * Save PSTATE early so that we can evaluate the vcpu mode
 	 * early on.
 	 */
-	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
+	synchronize_vcpu_pstate(vcpu, exit_code);
 
 	/*
 	 * Check whether we want to repaint the state one way or
@@ -442,22 +462,6 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
 	}
 
-	/*
-	 * Check for the conditions of Cortex-A510's #2077057. When these occur
-	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
-	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
-	 * Did we just take a PAC exception when a step exception was expected?
-	 */
-	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&
-	    cpus_have_const_cap(ARM64_WORKAROUND_2077057) &&
-	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ &&
-	    esr_ec == ESR_ELx_EC_PAC &&
-	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
-		/* Active-not-pending? */
-		if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
-			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
-	}
-
 	/*
 	 * We're using the raw exception code in order to only process
 	 * the trap if no SError is pending. We will come back to the

> +	}
> +
>  	/*
>  	 * We're using the raw exception code in order to only process
>  	 * the trap if no SError is pending. We will come back to the
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..2e7cd3fecca6 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>  WORKAROUND_1463225
>  WORKAROUND_1508412
>  WORKAROUND_1542419
> +WORKAROUND_2077057
>  WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  WORKAROUND_TSB_FLUSH_FAILURE
>  WORKAROUND_TRBE_WRITE_OUT_OF_RANGE

Other than that, I'm happy to take the series as a whole ASAP, if only
for the two pretty embarrassing bug fixes. If you can respin it
shortly and address the comments above, I'd like it into -rc2.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From krzysztof.kozlowski at canonical.com  Tue Jan 25 08:55:38 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 17:55:38 +0100
Subject: [PATCH v3 0/7] MT8186 SMI SUPPORT
In-Reply-To: <20220113111057.29918-1-yong.wu@mediatek.com>
References: <20220113111057.29918-1-yong.wu@mediatek.com>
Message-ID: <164312972455.77587.5523685649094227634.b4-ty@canonical.com>

On Thu, 13 Jan 2022 19:10:50 +0800, Yong Wu wrote:
> This patchset adds mt8186 smi support.
> mainly adds a sleep control function.
> 
> Change note:
> v3: a) Add a new binding patch for renaming "clock" to "clocks".
>     b) Reword the title for the binding patches, more detailed.
>     c) Add the sleep control error path: if err, return directly.
>        also change the log from dev_warn to dev_err.
> 
> [...]

Applied, thanks!

[1/7] dt-bindings: memory: mtk-smi: Rename clock to clocks
      commit: 5bf7fa48374eafe29dbb30448a0b0c083853583f
[2/7] dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167
      commit: ddc3a324889686ec9b358de20fdeec0d2668c7a8
[3/7] dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals clocks
      commit: 996ebc0e332bfb3091395f9bd286d8349a57be62
[4/7] dt-bindings: memory: mediatek: Add mt8186 support
      commit: 6d86f23c35fe7b479ceef4d3f1eef925996945fd
[5/7] memory: mtk-smi: Fix the return value for clk_bulk_prepare_enable
      commit: a6945f4566d4f77a4054720f6649ff921fe1ae64
[6/7] memory: mtk-smi: Add sleep ctrl function
      commit: 8956500e5d5bf541a945299999b0bf4866dc0daf
[7/7] memory: mtk-smi: mt8186: Add smi support
      commit: 86a010bfc73983aa8cd914f1e5f73962b0406678

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From helgaas at kernel.org  Tue Jan 25 08:57:48 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Tue, 25 Jan 2022 10:57:48 -0600
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220123033306.29799-1-qizhong.cheng@mediatek.com>
Message-ID: <20220125165748.GA1458116@bhelgaas>

All patches change *something*.  Can you update the subject line so it
says something specific about the change?

Maybe something like "Clear MSI status before dispatching handler"?

On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> As an edge-triggered interrupts, its interrupt status should be cleared
> before dispatch to the handler of device.

I'm not an IRQ expert, but the reasoning that "we should clear the MSI
interrupt status before dispatching the handler because MSI is an
edge-triggered interrupt" doesn't seem completely convincing because
your code will now look like this:

  /* Clear the INTx */
  writel(1 << bit, port->base + PCIE_INT_STATUS);
  generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
  ...

  /* Clear MSI interrupt status */
  writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
  generic_handle_domain_irq(port->inner_domain, bit);

You clear interrupt status before dispatching the handler for *both*
level-triggered INTx interrupts and edge-triggered MSI interrupts.

So it doesn't seem that simply being edge-triggered is the critical
factor here.

> Signed-off-by: qizhong cheng <qizhong.cheng at mediatek.com>
> ---
>  drivers/pci/controller/pcie-mediatek.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> index 2f3f974977a3..705ea33758b1 100644
> --- a/drivers/pci/controller/pcie-mediatek.c
> +++ b/drivers/pci/controller/pcie-mediatek.c
> @@ -624,12 +624,12 @@ static void mtk_pcie_intr_handler(struct irq_desc *desc)
>  		if (status & MSI_STATUS){
>  			unsigned long imsi_status;
>  
> +			/* Clear MSI interrupt status */
> +			writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
>  			while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
>  				for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM)
>  					generic_handle_domain_irq(port->inner_domain, bit);
>  			}
> -			/* Clear MSI interrupt status */
> -			writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
>  		}
>  	}
>  
> -- 
> 2.25.1
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek


From james.clark at arm.com  Tue Jan 25 08:58:20 2022
From: james.clark at arm.com (James Clark)
Date: Tue, 25 Jan 2022 16:58:20 +0000
Subject: [RFC V1 10/11] perf: Expand perf_branch_entry.type
In-Reply-To: <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
Message-ID: <2d7297b3-9a22-626b-9840-a4eaab4b94e8@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> Current perf_branch_entry.type is a 4 bits field just enough to accommodate
> 16 generic branch types. This is insufficient to accommodate platforms like
> arm64 which has much more branch types. Lets just expands this field into a
> 6 bits one, which can now hold 64 generic branch types. This also adds more
> generic branch types and updates the BRBE driver as required.
> 
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu_brbe.c           |  7 ++++++-
>  include/uapi/linux/perf_event.h       | 10 ++++++++--
>  tools/include/uapi/linux/perf_event.h | 10 ++++++++--
>  tools/perf/util/branch.c              |  8 +++++++-
>  4 files changed, 29 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
> index 8d27ad868359..7cd1208c6c58 100644
> --- a/drivers/perf/arm_pmu_brbe.c
> +++ b/drivers/perf/arm_pmu_brbe.c
> @@ -253,12 +253,17 @@ static int brbe_fetch_perf_type(u64 brbinf)
>  	case BRBINF_TYPE_DEBUG_EXIT:
>  		return PERF_BR_DEBUG_EXIT;
>  	case BRBINF_TYPE_SERROR:
> +		return PERF_BR_SERROR;
>  	case BRBINF_TYPE_INST_DEBUG:
> +		return PERF_BR_DEBUG_INST;
>  	case BRBINF_TYPE_DATA_DEBUG:
> +		return PERF_BR_DEBUG_DATA;
>  	case BRBINF_TYPE_ALGN_FAULT:
> +		return PERF_BR_FAULT_ALGN;
>  	case BRBINF_TYPE_INST_FAULT:
> +		return PERF_BR_FAULT_INST;
>  	case BRBINF_TYPE_DATA_FAULT:
> -		return PERF_BR_UNKNOWN;
> +		return PERF_BR_FAULT_DATA;
>  	default:
>  		pr_warn("unknown branch type captured\n");
>  		return PERF_BR_UNKNOWN;
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index b91d0f575d0c..361fdc6b87a0 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -256,6 +256,12 @@ enum {
>  	PERF_BR_FIQ		= 13,	/* fiq */
>  	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
>  	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
> +	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
> +	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
> +	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
> +	PERF_BR_FAULT_DATA	= 19,	/* data fault */
> +	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
> +	PERF_BR_SERROR		= 21,	/* system error */
>  	PERF_BR_MAX,
>  };
>  
> @@ -1370,8 +1376,8 @@ struct perf_branch_entry {
>  		in_tx:1,    /* in transaction */
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
> -		type:4,     /* branch type */
> -		reserved:40;
> +		type:6,     /* branch type */
> +		reserved:38;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index 1882054e8684..9a82b8aaed93 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -256,6 +256,12 @@ enum {
>  	PERF_BR_FIQ		= 13,	/* fiq */
>  	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
>  	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
> +	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
> +	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
> +	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
> +	PERF_BR_FAULT_DATA	= 19,	/* data fault */
> +	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
> +	PERF_BR_SERROR		= 21,	/* system error */
>  	PERF_BR_MAX,
>  };
>  
> @@ -1370,8 +1376,8 @@ struct perf_branch_entry {
>  		in_tx:1,    /* in transaction */
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
> -		type:4,     /* branch type */
> -		reserved:40;
> +		type:6,     /* branch type */
> +		reserved:38;
>  };

There's another copy of this struct in branch.h that is used to access the same data in
perf which also needs updating:

	struct branch_flags {
		union {
			u64 value;
			struct {
				u64 mispred:1;
				u64 predicted:1;
				u64 in_tx:1;
				u64 abort:1;
				u64 cycles:16;
				u64 type:4;
				u64 reserved:40;
			};
		};
	};

It's never assigned directly but there is some casting stuff going on in
evsel__parse_sample() and it eventually ends up being used to access branch
records. Same applies to the privilege data change.

>  
>  union perf_sample_weight {
> diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
> index 74e5e67b1779..1e216ea2e2a8 100644
> --- a/tools/perf/util/branch.c
> +++ b/tools/perf/util/branch.c
> @@ -54,7 +54,13 @@ const char *branch_type_name(int type)
>  		"IRQ",
>  		"FIQ",
>  		"DEBUG_HALT",
> -		"DEBUG_EXIT"
> +		"DEBUG_EXIT",
> +		"DEBUG_INST",
> +		"DEBUG_DATA",
> +		"FAULT_ALGN",
> +		"FAULT_DATA",
> +		"FAULT_INST",
> +		"SERROR"
>  	};
>  
>  	if (type >= 0 && type < PERF_BR_MAX)
> 


From eugenis at google.com  Tue Jan 25 08:59:07 2022
From: eugenis at google.com (Evgenii Stepanov)
Date: Tue, 25 Jan 2022 08:59:07 -0800
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
In-Reply-To: <YfAcKZpDWmKMZy8q@FVFF77S0Q05N>
References: <20220122023447.1480995-1-eugenis@google.com>
 <YfAV6FTN5g6jZGj7@FVFF77S0Q05N> <YfAcKZpDWmKMZy8q@FVFF77S0Q05N>
Message-ID: <CAFKCwrjbn3e2w-LikMY5bOvUKbUBi7_4iwBOD7KQUn8QHPwbng@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:50 AM Mark Rutland <mark.rutland at arm.com> wrote:
>
> On Tue, Jan 25, 2022 at 03:23:20PM +0000, Mark Rutland wrote:
> > On Fri, Jan 21, 2022 at 06:34:47PM -0800, Evgenii Stepanov wrote:
> > > ex_handler_load_unaligned_zeropad extracts the source and data register
> > > numbers from the wrong field of the exception table.
> >
> > Ouch. Did you find this by inspection, or did this show up in testing?
> >
> > Sorry about this.
> >
> > I think we should be a little more explicit as to exactly what goes wrong. How
> > about:
> >
> > | In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
> > | addr register indices from ex->type rather than ex->data. As ex->type will
> > | contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
> > |
> > | * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
> > |   extracted from bits [9:5]. Thus, we may attempt to dereference an arbitrary
> > |   address as X0 may hold an arbitary value.
> > |
> > | * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
> > |   extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
> > |   behaviour within load_unaligned_zeropad() and its caller.
> > |
> > | Fix this by extracting both values from ex->data as originally intended.
> >
> > > Fixes: 753b3236
> >
> > That should be expanded, e.g.
> >
> >   Fixes: 753b32368705c396 ("arm64: extable: add load_unaligned_zeropad() handler")
> >
> > With those changes:
> >
> > Reviewed-by: Mark Rutland <mark.rutland at arm.com>
>
> Looking again, sicne this isn't jsut a null-deref, can we also rework the
> title, something like:
>
> | arm64: extable: fix load_unaligned_zeropad() reg indices

That's a much better commit message, thank you! I'll upload v2 shortly.

This was found by updating to a newer QEMU that correctly delivers MTE
faults from unaligned memory accesses, and triggers this bug reliably
during Android boot. I'll add a stack trace to v2.

>
> Thanks,
> Mark.


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:02:29 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:02:29 +0100
Subject: [PATCH 0/2] ARM: dts: exynos: Add support for Samsung Klimt WiFi
In-Reply-To: <20220124131241.29946-1-henrik@grimler.se>
References: <20220124131241.29946-1-henrik@grimler.se>
Message-ID: <164313008959.78836.16815768434682839337.b4-ty@canonical.com>

On Mon, 24 Jan 2022 14:12:39 +0100, Henrik Grimler wrote:
> Klimt WiFi has product name Samsung Galaxy Tab S 8.4" and was released
> in 2014.  It has similar hardware to exynos5420-chagall-wifi and the
> two devices can hence share a common base dtsi.
> 
> Same issues as for Chagall Wifi applies: CCI has to be disabled and
> only 4 out of 8 CPUs are brought up at boot (see
> https://lore.kernel.org/r/20220118185746.299832-4-henrik at grimler.se).
> 
> [...]

Applied, thanks!

[1/2] dt-bindings: arm: samsung: document Klimt WiFi board binding
      commit: 8d4d0d7c43e6f87df02a0acac206b50c265962d1
[2/2] ARM: dts: exynos: Add support for Samsung Klimt WiFi
      commit: 21fc732222559c7b5a8731571d30501d5fcb631c

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:02:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:02:30 +0100
Subject: [PATCH 00/12] usb: dt-bindings: samsung: convert to dtschema
 (subset)
In-Reply-To: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164313008959.78836.16134870344795249201.b4-ty@canonical.com>

On Sun, 23 Jan 2022 12:16:32 +0100, Krzysztof Kozlowski wrote:
> Dependencies
> ============
> None.
> 
> The DTS patches are independent and I will take them via Samsung SoC tree.
> I am including them here just so automatic robot checks won't complain about
> DTS differences against newly dtschema.
> 
> [...]

Applied subset, thanks!

[01/12] arm64: dts: exynos: add USB DWC3 supplies to Espresso board
        commit: 31c33503fdb3965d6aaf0db4a8c42e7d8cef1dff
[02/12] ARM: dts: exynos: add USB DWC3 supplies to Arndale
        commit: 52d53d937da8889964c60216a0333cb19fe0812d
[03/12] ARM: dts: exynos: add USB DWC3 supplies to SMDK5250
        commit: ebbb07b8d349fc2eccb67780850d2d1bbfc918d6
[04/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook Snow
        commit: 9745be7b5a3be39a00e6bbda3305e2d789ee4082
[05/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook Spring
        commit: 111ea2d6dd217684db4e7a97a2bda3bf14734427
[06/12] ARM: dts: exynos: add USB DWC3 supplies to ArndaleOcta
        commit: 0a14272479627bb9388ece3b0ebac72a3928062d
[07/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook Peach Pit
        commit: 7adf978462dadc41ea7d4138de53bc9a15922191
[08/12] ARM: dts: exynos: add USB DWC3 supplies to Chromebook Peach Pi
        commit: 72477416ac12e88384a96575c5f2e4bd7ac8feeb
[09/12] ARM: dts: exynos: add USB DWC3 supplies to SMDK5420
        commit: c441d2d73107fcb45c0affb345fe6b9bc3fd3bab
[10/12] ARM: dts: exynos: add fake USB DWC3 supplies to SMDK5410
        commit: 4043114504cc05d0a7ca2a061838699b500599cd

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:04:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:04:54 +0100
Subject: (subset) [PATCH 1/3] ARM: dts: exynos: drop old thermal
 properties from Exynos4210
In-Reply-To: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164313029072.79782.14492454091056440886.b4-ty@canonical.com>

On Sat, 22 Jan 2022 14:25:52 +0100, Krzysztof Kozlowski wrote:
> The samsung,tmu_gain and samsung,tmu_reference_voltage properties of
> Exynos Thermal Management Unit driver are not used since April 2018.
> They were removed with commit fccfe0993b5d ("thermal: exynos: remove
> parsing of samsung,tmu_gain property") and commit 61020d189dbc
> ("thermal: exynos: remove parsing of samsung, tmu_reference_voltage
> property"), so drop them also from Exynos4210 DTS.
> 
> [...]

Applied, thanks!

[1/3] ARM: dts: exynos: drop old thermal properties from Exynos4210
      commit: e20bd06fc421fba4099be51d3f56b9b1741b499b

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:04:55 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:04:55 +0100
Subject: [PATCH] ARM: dts: exynos: use define for TMU clock on Exynos4412
In-Reply-To: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>
References: <20220122131457.63304-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164313029072.79782.9597131661612342819.b4-ty@canonical.com>

On Sat, 22 Jan 2022 14:14:57 +0100, Krzysztof Kozlowski wrote:
> Replace clock hard-coded number with a define from bindings.  No
> functional change.
> 
> 

Applied, thanks!

[1/1] ARM: dts: exynos: use define for TMU clock on Exynos4412
      commit: 86955cb6ba16cd35323f498acbf0f07f8671c1b4

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From mark.rutland at arm.com  Tue Jan 25 09:07:29 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Tue, 25 Jan 2022 17:07:29 +0000
Subject: [PATCH] arm64: extable: fix null deref in load_unaligned_zeropad.
In-Reply-To: <CAFKCwrjbn3e2w-LikMY5bOvUKbUBi7_4iwBOD7KQUn8QHPwbng@mail.gmail.com>
References: <20220122023447.1480995-1-eugenis@google.com>
 <YfAV6FTN5g6jZGj7@FVFF77S0Q05N> <YfAcKZpDWmKMZy8q@FVFF77S0Q05N>
 <CAFKCwrjbn3e2w-LikMY5bOvUKbUBi7_4iwBOD7KQUn8QHPwbng@mail.gmail.com>
Message-ID: <YfAuUYovRP7BpUIa@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 08:59:07AM -0800, Evgenii Stepanov wrote:
> On Tue, Jan 25, 2022 at 7:50 AM Mark Rutland <mark.rutland at arm.com> wrote:
> >
> > On Tue, Jan 25, 2022 at 03:23:20PM +0000, Mark Rutland wrote:
> > > On Fri, Jan 21, 2022 at 06:34:47PM -0800, Evgenii Stepanov wrote:
> > > > ex_handler_load_unaligned_zeropad extracts the source and data register
> > > > numbers from the wrong field of the exception table.
> > >
> > > Ouch. Did you find this by inspection, or did this show up in testing?
> > >
> > > Sorry about this.
> > >
> > > I think we should be a little more explicit as to exactly what goes wrong. How
> > > about:
> > >
> > > | In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
> > > | addr register indices from ex->type rather than ex->data. As ex->type will
> > > | contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
> > > |
> > > | * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
> > > |   extracted from bits [9:5]. Thus, we may attempt to dereference an arbitrary
> > > |   address as X0 may hold an arbitary value.
> > > |
> > > | * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
> > > |   extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
> > > |   behaviour within load_unaligned_zeropad() and its caller.
> > > |
> > > | Fix this by extracting both values from ex->data as originally intended.
> > >
> > > > Fixes: 753b3236
> > >
> > > That should be expanded, e.g.
> > >
> > >   Fixes: 753b32368705c396 ("arm64: extable: add load_unaligned_zeropad() handler")
> > >
> > > With those changes:
> > >
> > > Reviewed-by: Mark Rutland <mark.rutland at arm.com>
> >
> > Looking again, sicne this isn't jsut a null-deref, can we also rework the
> > title, something like:
> >
> > | arm64: extable: fix load_unaligned_zeropad() reg indices
> 
> That's a much better commit message, thank you! I'll upload v2 shortly.
> 
> This was found by updating to a newer QEMU that correctly delivers MTE
> faults from unaligned memory accesses, and triggers this bug reliably
> during Android boot. I'll add a stack trace to v2.

That'd be great, thanks!

Mark.


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:03 +0100
Subject: (subset) [PATCH v5 11/16] dt-bindings: pinctrl: samsung: Add
 compatible for Tesla FSD SoC
In-Reply-To: <20220124141644.71052-12-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142941epcas5p4bbba53cfc2fc9862da9fd85d44de6e79@epcas5p4.samsung.com>
 <20220124141644.71052-12-alim.akhtar@samsung.com>
Message-ID: <164313066043.81586.10760195237607935843.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:39 +0530, Alim Akhtar wrote:
> Add compatible for Tesla Full Self-Driving SoC. The
> pinctrl hardware IP is similar to what found on most of the
> Exynos series of SoC, so this new compatible is added in
> Samsung pinctrl binding.
> 
> 

Applied, thanks!

[11/16] dt-bindings: pinctrl: samsung: Add compatible for Tesla FSD SoC
        commit: 98ed04b33f43a80c0d9e218023abce3b47ca3539

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:04 +0100
Subject: (subset) [PATCH v5 12/16] pinctrl: samsung: add FSD SoC specific
 data
In-Reply-To: <20220124141644.71052-13-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142946epcas5p11997a3c37546d37cac91f690a2a602bf@epcas5p1.samsung.com>
 <20220124141644.71052-13-alim.akhtar@samsung.com>
Message-ID: <164313066043.81586.3206885780884369059.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:40 +0530, Alim Akhtar wrote:
> Adds Tesla FSD SoC specific data to enable pinctrl.
> FSD SoC has similar pinctrl controller as found in the most
> Samsung/Exynos SoCs.
> 
> 

Applied, thanks!

[12/16] pinctrl: samsung: add FSD SoC specific data
        commit: 0d1b662c374c54bcf68bbcff3b71e6d6e945a7cf

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:03 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:03 +0100
Subject: (subset) [PATCH v5 01/16] dt-bindings: add vendor prefix for Tesla
In-Reply-To: <20220124141644.71052-2-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142857epcas5p4af44b43ce57414ad6667c84753c36f16@epcas5p4.samsung.com>
 <20220124141644.71052-2-alim.akhtar@samsung.com>
Message-ID: <164313065135.81319.13219734487510623073.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:29 +0530, Alim Akhtar wrote:
> Add vendor prefix for the Tesla (https://www.tesla.com)
> 
> 

Applied, thanks!

[01/16] dt-bindings: add vendor prefix for Tesla
        commit: a5a93e9b9ab9b4f367a773b32bbe1687006d75b7

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:04 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:04 +0100
Subject: (subset) [PATCH v5 13/16] dt-bindings: arm: add Tesla FSD ARM SoC
In-Reply-To: <20220124141644.71052-14-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142951epcas5p255712c3a9e37b9542687587d8114bda3@epcas5p2.samsung.com>
 <20220124141644.71052-14-alim.akhtar@samsung.com>
Message-ID: <164313065136.81319.902005401446620690.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:41 +0530, Alim Akhtar wrote:
> Add device tree bindings for the Tesla FSD ARM SoC.
> 
> 

Applied, thanks!

[13/16] dt-bindings: arm: add Tesla FSD ARM SoC
        commit: d25c5eb511df3439cd91517bcbce4b274f8972b9

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:05 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:05 +0100
Subject: (subset) [PATCH v5 14/16] arm64: dts: fsd: Add initial device
 tree support
In-Reply-To: <20220124141644.71052-15-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142957epcas5p27ab08d4eb02fe53a03e2b36ab1d913f8@epcas5p2.samsung.com>
 <20220124141644.71052-15-alim.akhtar@samsung.com>
Message-ID: <164313065136.81319.1739143646413756082.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:42 +0530, Alim Akhtar wrote:
> Add initial device tree support for "Full Self-Driving" (FSD) SoC
> This SoC contain three clusters of four cortex-a72 CPUs and various
> peripheral IPs.
> 
> 

Applied, thanks!

[14/16] arm64: dts: fsd: Add initial device tree support
        commit: f984dabdb5e16afb0f69b05a11ca9eeffa5b9a73

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:06 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:06 +0100
Subject: (subset) [PATCH v5 15/16] arm64: dts: fsd: Add initial pinctrl
 support
In-Reply-To: <20220124141644.71052-16-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124143001epcas5p4c0aab0902709a24bbedadaa223fe7910@epcas5p4.samsung.com>
 <20220124141644.71052-16-alim.akhtar@samsung.com>
Message-ID: <164313065136.81319.15871986388224953551.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:43 +0530, Alim Akhtar wrote:
> Add initial pin configuration nodes for FSD SoC.
> 
> 

Applied, thanks!

[15/16] arm64: dts: fsd: Add initial pinctrl support
        commit: 773d685fd406514af4b365aaa54fe493cf523602

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:11:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:11:07 +0100
Subject: (subset) [PATCH v5 16/16] arm64: defconfig: Enable Tesla FSD SoC
In-Reply-To: <20220124141644.71052-17-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124143005epcas5p103598aa358ac35fe5e1ee762faf508b0@epcas5p1.samsung.com>
 <20220124141644.71052-17-alim.akhtar@samsung.com>
Message-ID: <164313065136.81319.934364321640879263.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:44 +0530, Alim Akhtar wrote:
> This patch enables the Tesla FSD SoC in arm64 defconfig.
> 
> 

Applied, thanks!

[16/16] arm64: defconfig: Enable Tesla FSD SoC
        commit: aeb62e360c0fffd9cf218a314647d0c7254becbe

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:12:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:12:02 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
Message-ID: <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>

On 24/01/2022 15:16, Alim Akhtar wrote:
> Adds basic support for the Tesla Full Self-Driving (FSD)
> SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> as well as several IPs.
> 
> Patches 1 to 9 provide support for the clock controller
> (which is designed similarly to Exynos SoCs).
> 
> The remaining changes provide pinmux support, initial device tree support.
> 
> - Changes since v4
> * fixed 'make dtbs_check' warnings on patch 14/16
> 
> - Changes since v3
> * Addressed Stefen's review comments on patch 14/16
> * Fixed kernel test robot warning on patch 04/16
> * rebsaed this series on Krzysztof's pinmux new binding schema work [1]
> 
> - Changes since v2
> * Addressed Krzysztof's and Stephen's review comments
> * Added Reviewed-by and Acked-by tags
> * Rebased on next-20220120
> 
> - Changes since v1
> * fixed make dt_binding_check error as pointed by Rob
> * Addressed Krzysztof's and Rob's review comments
> * Added Reviewed-by and Acked-by tags
> * Dropped SPI, MCT and ADC from this series (to be posted in small sets)
> 
> NOTE: These patches are based on Krzysztof's pinmux for-next branch
> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups") 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/log/?h=for-next
> 
> 

Thanks, applied DTS/soc and pinctrl patches.

I expect Sylwester will pick up the clock ones. Otherwise please let me
know to pick it up as well.


Best regards,
Krzysztof


From miles.chen at mediatek.com  Tue Jan 25 09:11:48 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:11:48 +0800
Subject: [PATCH 06/31] clk: mediatek: cpumux: Implement unregister API
In-Reply-To: <20220122091731.283592-7-wenst@chromium.org>
References: <20220122091731.283592-7-wenst@chromium.org>
Message-ID: <20220125171148.31102-1-miles.chen@mediatek.com>

> The cpumux clk type within the MediaTek clk driver library only has
> a register function, and no corresponding unregister function. This
> means there is no way for its users to properly implement cleanup
> and removal.
> 
> Add a matching unregister function for the cpumux type clk.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-cpumux.c | 31 +++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-cpumux.h |  3 +++
>  2 files changed, 34 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> index cab5095416b6..99a819e3673f 100644
> --- a/drivers/clk/mediatek/clk-cpumux.c
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -77,6 +77,21 @@ mtk_clk_register_cpumux(const struct mtk_composite *mux,
>  	return clk;
>  }
>  
> +static void mtk_clk_unregister_cpumux(struct clk *clk)
> +{
> +	struct mtk_clk_cpumux *cpumux;
> +	struct clk_hw *hw;
> +
> +	hw = __clk_get_hw(clk);
> +	if (!hw)
> +		return;
> +
> +	cpumux = to_mtk_clk_cpumux(hw);
> +
> +	clk_unregister(clk);
> +	kfree(cpumux);
> +}
> +
>  int mtk_clk_register_cpumuxes(struct device_node *node,
>  			      const struct mtk_composite *clks, int num,
>  			      struct clk_onecell_data *clk_data)
> @@ -106,4 +121,20 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
>  	return 0;
>  }
>  
> +void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
> +				 struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_composite *mux = &clks[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
> +
> +		mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
> +		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +
>  MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
> index 2aaf1afd4e5f..fda7770fd803 100644
> --- a/drivers/clk/mediatek/clk-cpumux.h
> +++ b/drivers/clk/mediatek/clk-cpumux.h
> @@ -19,4 +19,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
>  			      const struct mtk_composite *clks, int num,
>  			      struct clk_onecell_data *clk_data);
>  
> +void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
> +				 struct clk_onecell_data *clk_data);
> +
>  #endif /* __DRV_CLK_CPUMUX_H */
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From aford173 at gmail.com  Tue Jan 25 09:11:17 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:17 -0600
Subject: [PATCH V4 00/11] media: hantro: imx8mq/imx8mm: Let VPU decoders get
 controlled by vpu-blk-ctrl
Message-ID: <20220125171129.472775-1-aford173@gmail.com>

Both the i.MX8MQ and i.MX8MM have G1 and G2 decoders.
The two decoders are similar, but the imx8mm lacks the
post-processor, so they will have distinct compatible flags.

>From what I can tell, the G2 decoder wasn't working, so splitting
the i.MX8MQ VPU into G1 and G2 makes it easier to control them
independently since the TRM of both the i.MX8MQ and
i.MX8MM list them as distinct IP blocks. This also allowed G2 to
become available.

With them being split, the power-domain can shift to the
vpu-blk-ctrl which is available on both i.MX8MQ and i.MX8MM,
but some of bits are different, so they'll have separate bindings.

Lastly, with the G1 and G2 operational, enable the i.MX8MM.
On the i.MX8MM, the clock speed of 600MHz was chosen to match
the default of the kernel repo from NXP and can be overwritten
by board files for anyone who under/over volts the power rail.

There seems to be some disagreement between the TRM and the Datasheet
for the imx8mq as to whether the speed should be 300MHz (TRM) or
600MHz (datasheet), so feedback from NXP would be very much
appreciated.

The repo used as the starting point was:
5.17-rc1

Fluster was run on both i.MX8MM and i.MX8MQ

At 600 MHz, the i.MX8MM had the following:

./fluster.py run -d GStreamer-VP8-V4L2SL-Gst1.0
Ran 55/61 tests successfully               in 8.299 secs

./fluster.py run -dGStreamer-H.264-V4L2SL-Gst1.0
Ran 90/135 tests successfully               in 71.200 secs

./fluster.py run -d GStreamer-VP9-V4L2SL-Gst1.0
Ran 139/303 tests successfully               in 218.079 secs

The i.MX8MQ had the following:

./fluster.py run -d GStreamer-VP8-V4L2SL-Gst1.0
Ran 55/61 tests successfully               in 7.732 secs

./fluster.py run -dGStreamer-H.264-V4L2SL-Gst1.0
Ran 90/135 tests successfully               in 58.558 secs

./fluster.py run -d GStreamer-VP9-V4L2SL-Gst1.0
Ran 144/303 tests successfully               in 271.373 secs

V4:  Add a comment and a notice based on feedback from Ezequiel Garcia
     if the older compatible flag is used.
     Add new patch which removes a reference to vpu from imx8mq-tqma8mq
     because the VPU is enabled by default and it's not needed.  Without
     this change, its device tree would fail to build.

V3:  Rebase on 5.17-RC1.
     Remove imx8mm-vpu-g2 since it's identical to imx8mq-vpu-g2
     Remove unnecessary examples in YAML files.
     Remove some unused variables.

V2:  Remove references to legacy dt-binding from YAML, but keep
     it in the driver so older device trees can still be used.
     Fix typos in YAML
     Remove reg-names, interrupt-names, and clock-names from YAML,
     since each node will only have one of each, they're not necessary
     Add Fluster scores to cover letter for i.MX8MQ



Adam Ford (8):
  arm64: dts: imx8mq-tqma8mq: Remove redundant vpu reference
  dt-bindings: media: nxp, imx8mq-vpu: Split G1 and G2 nodes
  media: hantro: Allow i.MX8MQ G1 and G2 to run independently
  arm64: dts: imx8mq: Enable both G1 and G2 VPU's with vpu-blk-ctrl
  arm64: dts: imx8mm: Fix VPU Hanging
  dt-bindings: media: nxp, imx8mq-vpu: Add support for G1 on imx8mm
  media: hantro: Add support for i.MX8MM Hantro-G1
  arm64: dts: imx8mm: Enable Hantro G1 and G2 video decoders

Lucas Stach (3):
  dt-bindings: power: imx8mq: add defines for VPU blk-ctrl domains
  dt-bindings: soc: add binding for i.MX8MQ VPU blk-ctrl
  soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl

 .../bindings/media/nxp,imx8mq-vpu.yaml        | 68 ++++++++----------
 .../soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml      | 71 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mm.dtsi     | 23 +++++-
 .../boot/dts/freescale/imx8mq-tqma8mq.dtsi    |  4 --
 arch/arm64/boot/dts/freescale/imx8mq.dtsi     | 63 +++++++++-------
 drivers/soc/imx/imx8m-blk-ctrl.c              | 66 +++++++++++++++++
 drivers/staging/media/hantro/hantro_drv.c     | 11 +++
 drivers/staging/media/hantro/hantro_hw.h      |  2 +
 drivers/staging/media/hantro/imx8m_vpu_hw.c   | 62 ++++++++++++----
 include/dt-bindings/power/imx8mq-power.h      |  3 +
 10 files changed, 292 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:18 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:18 -0600
Subject: [PATCH V4 01/11] arm64: dts: imx8mq-tqma8mq: Remove redundant vpu
 reference
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-2-aford173@gmail.com>

The vpu is enabled by default, so there is no need to manually
enable it.

Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
index 8aedcddfeab8..38ffcd145b33 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
@@ -272,10 +272,6 @@ &usdhc1 {
 	status = "okay";
 };
 
-&vpu {
-	status = "okay";
-};
-
 /* Attention: wdog reset forcing POR needs baseboard support */
 &wdog1 {
 	status = "okay";
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:19 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:19 -0600
Subject: [PATCH V4 02/11] dt-bindings: power: imx8mq: add defines for VPU
 blk-ctrl domains
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-3-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the defines for the power domains provided by the VPU
blk-ctrl on the i.MX8MQ.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Acked-by: Rob Herring <robh at kernel.org>

diff --git a/include/dt-bindings/power/imx8mq-power.h b/include/dt-bindings/power/imx8mq-power.h
index 8a513bd9166e..9f7d0f1e7c32 100644
--- a/include/dt-bindings/power/imx8mq-power.h
+++ b/include/dt-bindings/power/imx8mq-power.h
@@ -18,4 +18,7 @@
 #define IMX8M_POWER_DOMAIN_MIPI_CSI2	9
 #define IMX8M_POWER_DOMAIN_PCIE2	10
 
+#define IMX8MQ_VPUBLK_PD_G1		0
+#define IMX8MQ_VPUBLK_PD_G2		1
+
 #endif
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:20 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:20 -0600
Subject: [PATCH V4 03/11] dt-bindings: soc: add binding for i.MX8MQ VPU
 blk-ctrl
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-4-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the DT binding for the i.MX8MQ VPU blk-ctrl.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Rob Herring <robh at kernel.org>

diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
new file mode 100644
index 000000000000..7263ebedf09f
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/imx/fsl,imx8mq-vpu-blk-ctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8MQ VPU blk-ctrl
+
+maintainers:
+  - Lucas Stach <l.stach at pengutronix.de>
+
+description:
+  The i.MX8MQ VPU blk-ctrl is a top-level peripheral providing access to
+  the NoC and ensuring proper power sequencing of the VPU peripherals
+  located in the VPU domain of the SoC.
+
+properties:
+  compatible:
+    items:
+      - const: fsl,imx8mq-vpu-blk-ctrl
+
+  reg:
+    maxItems: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  power-domains:
+    minItems: 3
+    maxItems: 3
+
+  power-domain-names:
+    items:
+      - const: bus
+      - const: g1
+      - const: g2
+
+  clocks:
+    minItems: 2
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: g1
+      - const: g2
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - power-domain-names
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/power/imx8mq-power.h>
+
+    vpu_blk_ctrl: blk-ctrl at 38320000 {
+      compatible = "fsl,imx8mq-vpu-blk-ctrl";
+      reg = <0x38320000 0x100>;
+      power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+      power-domain-names = "bus", "g1", "g2";
+      clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+               <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+      clock-names = "g1", "g2";
+      #power-domain-cells = <1>;
+    };
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:21 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:21 -0600
Subject: [PATCH V4 04/11] soc: imx: imx8m-blk-ctrl: add i.MX8MQ VPU blk-ctrl
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-5-aford173@gmail.com>

From: Lucas Stach <l.stach at pengutronix.de>

This adds the necessary bits to drive the VPU blk-ctrl on the i.MX8MQ, to
avoid putting more of this functionality into the decoder driver.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c
index 511e74f0db8a..122f9c884b38 100644
--- a/drivers/soc/imx/imx8m-blk-ctrl.c
+++ b/drivers/soc/imx/imx8m-blk-ctrl.c
@@ -15,6 +15,7 @@
 
 #include <dt-bindings/power/imx8mm-power.h>
 #include <dt-bindings/power/imx8mn-power.h>
+#include <dt-bindings/power/imx8mq-power.h>
 
 #define BLK_SFT_RSTN	0x0
 #define BLK_CLK_EN	0x4
@@ -589,6 +590,68 @@ static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = {
 	.num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data),
 };
 
+static int imx8mq_vpu_power_notifier(struct notifier_block *nb,
+				     unsigned long action, void *data)
+{
+	struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl,
+						 power_nb);
+
+	if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF)
+		return NOTIFY_OK;
+
+	/*
+	 * The ADB in the VPUMIX domain has no separate reset and clock
+	 * enable bits, but is ungated and reset together with the VPUs. The
+	 * reset and clock enable inputs to the ADB is a logical OR of the
+	 * VPU bits. In order to set the G2 fuse bits, the G2 clock must
+	 * also be enabled.
+	 */
+	regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1));
+	regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1));
+
+	if (action == GENPD_NOTIFY_ON) {
+		/*
+		 * On power up we have no software backchannel to the GPC to
+		 * wait for the ADB handshake to happen, so we just delay for a
+		 * bit. On power down the GPC driver waits for the handshake.
+		 */
+		udelay(5);
+
+		/* set "fuse" bits to enable the VPUs */
+		regmap_set_bits(bc->regmap, 0x8, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0xc, 0xffffffff);
+		regmap_set_bits(bc->regmap, 0x10, 0xffffffff);
+	}
+
+	return NOTIFY_OK;
+}
+
+static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = {
+	[IMX8MQ_VPUBLK_PD_G1] = {
+		.name = "vpublk-g1",
+		.clk_names = (const char *[]){ "g1", },
+		.num_clks = 1,
+		.gpc_name = "g1",
+		.rst_mask = BIT(1),
+		.clk_mask = BIT(1),
+	},
+	[IMX8MQ_VPUBLK_PD_G2] = {
+		.name = "vpublk-g2",
+		.clk_names = (const char *[]){ "g2", },
+		.num_clks = 1,
+		.gpc_name = "g2",
+		.rst_mask = BIT(0),
+		.clk_mask = BIT(0),
+	},
+};
+
+static const struct imx8m_blk_ctrl_data imx8mq_vpu_blk_ctl_dev_data = {
+	.max_reg = 0x14,
+	.power_notifier_fn = imx8mq_vpu_power_notifier,
+	.domains = imx8mq_vpu_blk_ctl_domain_data,
+	.num_domains = ARRAY_SIZE(imx8mq_vpu_blk_ctl_domain_data),
+};
+
 static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
 	{
 		.compatible = "fsl,imx8mm-vpu-blk-ctrl",
@@ -599,6 +662,9 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = {
 	}, {
 		.compatible = "fsl,imx8mn-disp-blk-ctrl",
 		.data = &imx8mn_disp_blk_ctl_dev_data
+	}, {
+		.compatible = "fsl,imx8mq-vpu-blk-ctrl",
+		.data = &imx8mq_vpu_blk_ctl_dev_data
 	}, {
 		/* Sentinel */
 	}
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:22 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:22 -0600
Subject: [PATCH V4 05/11] dt-bindings: media: nxp,
 imx8mq-vpu: Split G1 and G2 nodes
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-6-aford173@gmail.com>

The G1 and G2 are independent and separate decoder blocks
that are enabled by the vpu-blk-ctrl power-domain controller,
which now has a proper driver.

Because these blocks only share the power-domain, and can be
independently fused out, update the bindings to support separate
nodes for the G1 and G2 decoders with vpu-blk-ctrl power-domain
support.

The new DT + old kernel isn't a supported configuration.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 762be3f96ce9..9c28d562112b 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -15,33 +15,20 @@ description:
 
 properties:
   compatible:
-    const: nxp,imx8mq-vpu
+    oneOf:
+      - const: nxp,imx8mq-vpu
+        deprecated: true
+      - const: nxp,imx8mq-vpu-g1
+      - const: nxp,imx8mq-vpu-g2
 
   reg:
-    maxItems: 3
-
-  reg-names:
-    items:
-      - const: g1
-      - const: g2
-      - const: ctrl
+    maxItems: 1
 
   interrupts:
-    maxItems: 2
-
-  interrupt-names:
-    items:
-      - const: g1
-      - const: g2
+    maxItems: 1
 
   clocks:
-    maxItems: 3
-
-  clock-names:
-    items:
-      - const: g1
-      - const: g2
-      - const: bus
+    maxItems: 1
 
   power-domains:
     maxItems: 1
@@ -49,31 +36,33 @@ properties:
 required:
   - compatible
   - reg
-  - reg-names
   - interrupts
-  - interrupt-names
   - clocks
-  - clock-names
 
 additionalProperties: false
 
 examples:
   - |
         #include <dt-bindings/clock/imx8mq-clock.h>
+        #include <dt-bindings/power/imx8mq-power.h>
+        #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+        vpu_g1: video-codec at 38300000 {
+                compatible = "nxp,imx8mq-vpu-g1";
+                reg = <0x38300000 0x10000>;
+                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+        };
+  - |
+        #include <dt-bindings/clock/imx8mq-clock.h>
+        #include <dt-bindings/power/imx8mq-power.h>
         #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-        vpu: video-codec at 38300000 {
-                compatible = "nxp,imx8mq-vpu";
-                reg = <0x38300000 0x10000>,
-                      <0x38310000 0x10000>,
-                      <0x38320000 0x10000>;
-                reg-names = "g1", "g2", "ctrl";
-                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-                             <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-                interrupt-names = "g1", "g2";
-                clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
-                         <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
-                         <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
-                clock-names = "g1", "g2", "bus";
-                power-domains = <&pgc_vpu>;
+        vpu_g2: video-codec at 38300000 {
+                compatible = "nxp,imx8mq-vpu-g2";
+                reg = <0x38310000 0x10000>;
+                interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+                power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
         };
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:23 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:23 -0600
Subject: [PATCH V4 06/11] media: hantro: Allow i.MX8MQ G1 and G2 to run
 independently
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-7-aford173@gmail.com>

The VPU in the i.MX8MQ is really the combination of Hantro G1 and
Hantro G2. With the updated vpu-blk-ctrl, the power domains system
can enable and disable them separately as well as pull them out of
reset. This simplifies the code and lets them run independently
while still retaining backwards compatibility with older device
trees for those using G1.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index 6a51f39dde56..f56e8b3efada 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -616,6 +616,7 @@ static const struct of_device_id of_hantro_match[] = {
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_IMX8M
 	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
+	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
 	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_SAMA5D4
@@ -890,6 +891,15 @@ static int hantro_probe(struct platform_device *pdev)
 	match = of_match_node(of_hantro_match, pdev->dev.of_node);
 	vpu->variant = match->data;
 
+	/*
+	 * Support for nxp,imx8mq-vpu is kept for backwards compatibility
+	 * but it's deprecated. Please update your DTS file to use
+	 * nxp,imx8mq-vpu-g1 or nxp,imx8mq-vpu-g2 instead.
+	 */
+	if (of_device_is_compatible(pdev->dev.of_node, "nxp,imx8mq-vpu"))
+		dev_warn(&pdev->dev, "%s compatible is deprecated\n",
+			 match->compatible);
+
 	INIT_DELAYED_WORK(&vpu->watchdog_work, hantro_watchdog);
 
 	vpu->clocks = devm_kcalloc(&pdev->dev, vpu->variant->num_clocks,
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index 4a19ae8940b9..f0bd2ffe290b 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -299,6 +299,7 @@ enum hantro_enc_fmt {
 	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
 };
 
+extern const struct hantro_variant imx8mq_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g2_variant;
 extern const struct hantro_variant imx8mq_vpu_variant;
 extern const struct hantro_variant px30_vpu_variant;
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index f5991b8e553a..849ea7122d47 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -205,13 +205,6 @@ static void imx8m_vpu_g1_reset(struct hantro_ctx *ctx)
 	imx8m_soft_reset(vpu, RESET_G1);
 }
 
-static void imx8m_vpu_g2_reset(struct hantro_ctx *ctx)
-{
-	struct hantro_dev *vpu = ctx->dev;
-
-	imx8m_soft_reset(vpu, RESET_G2);
-}
-
 /*
  * Supported codec ops.
  */
@@ -237,17 +230,33 @@ static const struct hantro_codec_ops imx8mq_vpu_codec_ops[] = {
 	},
 };
 
+static const struct hantro_codec_ops imx8mq_vpu_g1_codec_ops[] = {
+	[HANTRO_MODE_MPEG2_DEC] = {
+		.run = hantro_g1_mpeg2_dec_run,
+		.init = hantro_mpeg2_dec_init,
+		.exit = hantro_mpeg2_dec_exit,
+	},
+	[HANTRO_MODE_VP8_DEC] = {
+		.run = hantro_g1_vp8_dec_run,
+		.init = hantro_vp8_dec_init,
+		.exit = hantro_vp8_dec_exit,
+	},
+	[HANTRO_MODE_H264_DEC] = {
+		.run = hantro_g1_h264_dec_run,
+		.init = hantro_h264_dec_init,
+		.exit = hantro_h264_dec_exit,
+	},
+};
+
 static const struct hantro_codec_ops imx8mq_vpu_g2_codec_ops[] = {
 	[HANTRO_MODE_HEVC_DEC] = {
 		.run = hantro_g2_hevc_dec_run,
-		.reset = imx8m_vpu_g2_reset,
 		.init = hantro_hevc_dec_init,
 		.exit = hantro_hevc_dec_exit,
 	},
 	[HANTRO_MODE_VP9_DEC] = {
 		.run = hantro_g2_vp9_dec_run,
 		.done = hantro_g2_vp9_dec_done,
-		.reset = imx8m_vpu_g2_reset,
 		.init = hantro_vp9_dec_init,
 		.exit = hantro_vp9_dec_exit,
 	},
@@ -267,6 +276,8 @@ static const struct hantro_irq imx8mq_g2_irqs[] = {
 
 static const char * const imx8mq_clk_names[] = { "g1", "g2", "bus" };
 static const char * const imx8mq_reg_names[] = { "g1", "g2", "ctrl" };
+static const char * const imx8mq_g1_clk_names[] = { "g1" };
+static const char * const imx8mq_g2_clk_names[] = { "g2" };
 
 const struct hantro_variant imx8mq_vpu_variant = {
 	.dec_fmts = imx8m_vpu_dec_fmts,
@@ -287,6 +298,21 @@ const struct hantro_variant imx8mq_vpu_variant = {
 	.num_regs = ARRAY_SIZE(imx8mq_reg_names)
 };
 
+const struct hantro_variant imx8mq_vpu_g1_variant = {
+	.dec_fmts = imx8m_vpu_dec_fmts,
+	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
+	.postproc_fmts = imx8m_vpu_postproc_fmts,
+	.num_postproc_fmts = ARRAY_SIZE(imx8m_vpu_postproc_fmts),
+	.postproc_ops = &hantro_g1_postproc_ops,
+	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
+		 HANTRO_H264_DECODER,
+	.codec_ops = imx8mq_vpu_g1_codec_ops,
+	.irqs = imx8mq_irqs,
+	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
+	.clk_names = imx8mq_g1_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
+};
+
 const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.dec_offset = 0x0,
 	.dec_fmts = imx8m_vpu_g2_dec_fmts,
@@ -296,10 +322,8 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.postproc_ops = &hantro_g2_postproc_ops,
 	.codec = HANTRO_HEVC_DECODER | HANTRO_VP9_DECODER,
 	.codec_ops = imx8mq_vpu_g2_codec_ops,
-	.init = imx8mq_vpu_hw_init,
-	.runtime_resume = imx8mq_runtime_resume,
 	.irqs = imx8mq_g2_irqs,
 	.num_irqs = ARRAY_SIZE(imx8mq_g2_irqs),
-	.clk_names = imx8mq_clk_names,
-	.num_clocks = ARRAY_SIZE(imx8mq_clk_names),
+	.clk_names = imx8mq_g2_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
 };
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:24 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:24 -0600
Subject: [PATCH V4 07/11] arm64: dts: imx8mq: Enable both G1 and G2 VPU's with
 vpu-blk-ctrl
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-8-aford173@gmail.com>

With the Hantro G1 and G2 now setup to run independently, update
the device tree to allow both to operate.  This requires the
vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
certain clock enabled to handle the gating of the G1 and G2
fuses, the clock-parents and clock-rates for the various VPU's
to be moved into the pgc_vpu because they cannot get re-parented
once enabled, and the pgc_vpu is the highest in the chain.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reported-by: kernel test robot <lkp at intel.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 2df2510d0118..549b2440f55d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
 					pgc_vpu: power-domain at 6 {
 						#power-domain-cells = <0>;
 						reg = <IMX8M_POWER_DOMAIN_VPU>;
-						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
+						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
+							 <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
+							 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+						assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
+								  <&clk IMX8MQ_CLK_VPU_G2>,
+								  <&clk IMX8MQ_CLK_VPU_BUS>,
+								  <&clk IMX8MQ_VPU_PLL_BYPASS>;
+						assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
+									 <&clk IMX8MQ_VPU_PLL_OUT>,
+									 <&clk IMX8MQ_SYS1_PLL_800M>,
+									 <&clk IMX8MQ_VPU_PLL>;
+						assigned-clock-rates = <600000000>,
+								       <600000000>,
+								       <800000000>,
+								       <0>;
 					};
 
 					pgc_disp: power-domain at 7 {
@@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
 			status = "disabled";
 		};
 
-		vpu: video-codec at 38300000 {
-			compatible = "nxp,imx8mq-vpu";
-			reg = <0x38300000 0x10000>,
-			      <0x38310000 0x10000>,
-			      <0x38320000 0x10000>;
-			reg-names = "g1", "g2", "ctrl";
-			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "g1", "g2";
+		vpu_g1: video-codec at 38300000 {
+			compatible = "nxp,imx8mq-vpu-g1";
+			reg = <0x38300000 0x10000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
+		};
+
+		vpu_g2: video-codec at 38310000 {
+			compatible = "nxp,imx8mq-vpu-g2";
+			reg = <0x38310000 0x10000>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
+		};
+
+		vpu_blk_ctrl: blk-ctrl at 38320000 {
+			compatible = "fsl,imx8mq-vpu-blk-ctrl";
+			reg = <0x38320000 0x100>;
+			power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
+			power-domain-names = "bus", "g1", "g2";
 			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
-				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
-				 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
-			clock-names = "g1", "g2", "bus";
-			assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
-					  <&clk IMX8MQ_CLK_VPU_G2>,
-					  <&clk IMX8MQ_CLK_VPU_BUS>,
-					  <&clk IMX8MQ_VPU_PLL_BYPASS>;
-			assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
-						 <&clk IMX8MQ_VPU_PLL_OUT>,
-						 <&clk IMX8MQ_SYS1_PLL_800M>,
-						 <&clk IMX8MQ_VPU_PLL>;
-			assigned-clock-rates = <600000000>, <600000000>,
-					       <800000000>, <0>;
-			power-domains = <&pgc_vpu>;
+				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
+			clock-names = "g1", "g2";
+			#power-domain-cells = <1>;
 		};
 
 		pcie0: pcie at 33800000 {
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:25 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:25 -0600
Subject: [PATCH V4 08/11] arm64: dts: imx8mm: Fix VPU Hanging
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-9-aford173@gmail.com>

The vpumix power domain has a reset assigned to it, however
when used, it causes a system hang.  Testing has shown that
it does not appear to be needed anywhere.

Fixes: d39d4bb15310 ("arm64: dts: imx8mm: add GPC node")
Signed-off-by: Adam Ford <aford173 at gmail.com>

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index f77f90ed416f..0c7a72c51a31 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -707,7 +707,6 @@ pgc_vpumix: power-domain at 6 {
 						clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
 						assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
 						assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
-						resets = <&src IMX8MQ_RESET_VPU_RESET>;
 					};
 
 					pgc_vpu_g1: power-domain at 7 {
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:26 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:26 -0600
Subject: [PATCH V4 09/11] dt-bindings: media: nxp,
 imx8mq-vpu: Add support for G1 on imx8mm
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-10-aford173@gmail.com>

The i.MX8M mini appears to have a similar G1 decoder but the
post-processing isn't present, so different compatible flag is required.
Since all the other parameters are the same with imx8mq, just add
the new compatible flag to nxp,imx8mq-vpu.yaml.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
index 9c28d562112b..7dc13a4b1805 100644
--- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
+++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
@@ -5,7 +5,7 @@
 $id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
-title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
+title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
 
 maintainers:
   - Philipp Zabel <p.zabel at pengutronix.de>
@@ -20,6 +20,7 @@ properties:
         deprecated: true
       - const: nxp,imx8mq-vpu-g1
       - const: nxp,imx8mq-vpu-g2
+      - const: nxp,imx8mm-vpu-g1
 
   reg:
     maxItems: 1
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:27 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:27 -0600
Subject: [PATCH V4 10/11] media: hantro: Add support for i.MX8MM Hantro-G1
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-11-aford173@gmail.com>

The i.MX8MM has a Hantro G1 video decoder similar to the
imx8mq but lacks the post-processor present in the imx8mq.
Add support in the driver for it with the post-processing
removed.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c
index f56e8b3efada..8f020ba15194 100644
--- a/drivers/staging/media/hantro/hantro_drv.c
+++ b/drivers/staging/media/hantro/hantro_drv.c
@@ -615,6 +615,7 @@ static const struct of_device_id of_hantro_match[] = {
 	{ .compatible = "rockchip,rk3399-vpu", .data = &rk3399_vpu_variant, },
 #endif
 #ifdef CONFIG_VIDEO_HANTRO_IMX8M
+	{ .compatible = "nxp,imx8mm-vpu-g1", .data = &imx8mm_vpu_g1_variant, },
 	{ .compatible = "nxp,imx8mq-vpu", .data = &imx8mq_vpu_variant, },
 	{ .compatible = "nxp,imx8mq-vpu-g1", .data = &imx8mq_vpu_g1_variant },
 	{ .compatible = "nxp,imx8mq-vpu-g2", .data = &imx8mq_vpu_g2_variant },
diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h
index f0bd2ffe290b..c00b46e06055 100644
--- a/drivers/staging/media/hantro/hantro_hw.h
+++ b/drivers/staging/media/hantro/hantro_hw.h
@@ -299,6 +299,7 @@ enum hantro_enc_fmt {
 	ROCKCHIP_VPU_ENC_FMT_UYVY422 = 3,
 };
 
+extern const struct hantro_variant imx8mm_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g1_variant;
 extern const struct hantro_variant imx8mq_vpu_g2_variant;
 extern const struct hantro_variant imx8mq_vpu_variant;
diff --git a/drivers/staging/media/hantro/imx8m_vpu_hw.c b/drivers/staging/media/hantro/imx8m_vpu_hw.c
index 849ea7122d47..9802508bade2 100644
--- a/drivers/staging/media/hantro/imx8m_vpu_hw.c
+++ b/drivers/staging/media/hantro/imx8m_vpu_hw.c
@@ -327,3 +327,15 @@ const struct hantro_variant imx8mq_vpu_g2_variant = {
 	.clk_names = imx8mq_g2_clk_names,
 	.num_clocks = ARRAY_SIZE(imx8mq_g2_clk_names),
 };
+
+const struct hantro_variant imx8mm_vpu_g1_variant = {
+	.dec_fmts = imx8m_vpu_dec_fmts,
+	.num_dec_fmts = ARRAY_SIZE(imx8m_vpu_dec_fmts),
+	.codec = HANTRO_MPEG2_DECODER | HANTRO_VP8_DECODER |
+		 HANTRO_H264_DECODER,
+	.codec_ops = imx8mq_vpu_g1_codec_ops,
+	.irqs = imx8mq_irqs,
+	.num_irqs = ARRAY_SIZE(imx8mq_irqs),
+	.clk_names = imx8mq_g1_clk_names,
+	.num_clocks = ARRAY_SIZE(imx8mq_g1_clk_names),
+};
-- 
2.32.0



From aford173 at gmail.com  Tue Jan 25 09:11:28 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 11:11:28 -0600
Subject: [PATCH V4 11/11] arm64: dts: imx8mm: Enable Hantro G1 and G2 video
 decoders
In-Reply-To: <20220125171129.472775-1-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
Message-ID: <20220125171129.472775-12-aford173@gmail.com>

There are two decoders on the i.MX8M Mini controlled by the
vpu-blk-ctrl.  The G1 supports H264 and VP8 while the
G2 support HEVC and VP9.

Signed-off-by: Adam Ford <aford173 at gmail.com>
Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
index 0c7a72c51a31..98aec4421713 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
@@ -1272,6 +1272,22 @@ gpu_2d: gpu at 38008000 {
 			power-domains = <&pgc_gpu>;
 		};
 
+		vpu_g1: video-codec at 38300000 {
+			compatible = "nxp,imx8mm-vpu-g1";
+			reg = <0x38300000 0x10000>;
+			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G1>;
+		};
+
+		vpu_g2: video-codec at 38310000 {
+			compatible = "nxp,imx8mq-vpu-g2";
+			reg = <0x38310000 0x10000>;
+			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
+			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G2>;
+		};
+
 		vpu_blk_ctrl: blk-ctrl at 38330000 {
 			compatible = "fsl,imx8mm-vpu-blk-ctrl", "syscon";
 			reg = <0x38330000 0x100>;
@@ -1282,6 +1298,12 @@ vpu_blk_ctrl: blk-ctrl at 38330000 {
 				 <&clk IMX8MM_CLK_VPU_G2_ROOT>,
 				 <&clk IMX8MM_CLK_VPU_H1_ROOT>;
 			clock-names = "g1", "g2", "h1";
+			assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>,
+					  <&clk IMX8MM_CLK_VPU_G2>;
+			assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>,
+						 <&clk IMX8MM_VPU_PLL_OUT>;
+			assigned-clock-rates = <600000000>,
+					       <600000000>;
 			#power-domain-cells = <1>;
 		};
 
-- 
2.32.0



From u.kleine-koenig at pengutronix.de  Tue Jan 25 09:15:11 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Tue, 25 Jan 2022 18:15:11 +0100
Subject: [PATCH v10 1/3] pwm: driver for qualcomm ipq6018 pwm block
In-Reply-To: <87pmof93wf.fsf@tarshish>
References: <ab2a4c345844f66aa22a847e522b2f4ee0786d8b.1639499239.git.baruch@tkos.co.il>
 <20220119172439.be4xpaqgwzdy26oh@pengutronix.de>
 <87tuds7y09.fsf@tarshish>
 <20220125161204.hx5foivny6iupjke@pengutronix.de>
 <87pmof93wf.fsf@tarshish>
Message-ID: <20220125171511.zoyuiflb6utlkng5@pengutronix.de>

Hello Baruch,

On Tue, Jan 25, 2022 at 06:22:45PM +0200, Baruch Siach wrote:
> On Tue, Jan 25 2022, Uwe Kleine-K?nig wrote:
> > On Tue, Jan 25, 2022 at 03:03:08PM +0200, Baruch Siach wrote:
> >> On Wed, Jan 19 2022, Uwe Kleine-K?nig wrote:
> >> > The task here is to calculate the biggest pwm_div for a given pre_div
> >> > such that
> >> >
> >> >
> >> > 	(pre_div + 1) * (pwm_div + 1) * NSEC_PER_SEC
> >> > 	-------------------------------------------- <= period_ns
> >> > 	                   rate
> >> >
> >> > right?
> >> >
> >> > This is equivalent to:
> >> >
> >> > 	                  period_ns * rate
> >> > 	pre_div <= ---------------------------- - 1
> >> > 	           (pre_div + 1) * NSEC_PER_SEC
> >> >
> >> > As pre_div is integer, rounding down should be fine?!
> >> 
> >> I can't follow. With round down (as in v8) the result is always:
> >> 
> >>   NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1) <= period_rate
> >
> > Yes, that's the condition that a valid configuration should fulfill
> > because then the configured period is never bigger than the requested
> > period.
> >  
> >> As a result, 'diff' calculation below will always produce diff <= 0. When
> >> there is no diff == 0 result (bingo) we get IPQ_PWM_MAX_DIV in both best_
> >> values at the end of the loop.
> >
> > Looking again, your check is wrong. I think you need:
> >
> > 	diff = period_rate - NSEC_PER_SEC * (pre_div + 1) * (pwm_div + 1)
> >
> > . Given the calculations for pre_div and pwm_div this should never be
> > negative and you should pick values that minimize diff.
> 
> So, if I understand correctly, you suggest to leave round up as in v10,
> and invert the diff calculation. Is that correct?

If you agree that this results in the intended setting and keeps dmesg
clean even with PWM_DEBUG enabled: yes.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/76076ea3/attachment.sig>

From daniel.lezcano at linaro.org  Tue Jan 25 09:18:09 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Tue, 25 Jan 2022 18:18:09 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for rk3399
In-Reply-To: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
Message-ID: <20220125171809.1273269-6-daniel.lezcano@linaro.org>

The DTPM framework does support now the hierarchy description.

The platform specific code can call the hierarchy creation function
with an array of struct dtpm_node pointing to their parent.

This patch provides a description of the big / Little CPUs and the
GPU and tie them together under a virtual 'package' name. Only rk3399 is
described now.

The description could be extended in the future with the memory
controller with devfreq.

The description is always a module and it describes the soft
dependencies. The userspace has to load the softdeps module in the
right order.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/soc/rockchip/Kconfig  |  8 +++++
 drivers/soc/rockchip/Makefile |  1 +
 drivers/soc/rockchip/dtpm.c   | 59 +++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 drivers/soc/rockchip/dtpm.c

diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
index 25eb2c1e31bb..6dc017f02431 100644
--- a/drivers/soc/rockchip/Kconfig
+++ b/drivers/soc/rockchip/Kconfig
@@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS
 
           If unsure, say N.
 
+config ROCKCHIP_DTPM
+	tristate "Rockchip DTPM hierarchy"
+	depends on DTPM && DRM_PANFROST && m
+	help
+	 Describe the hierarchy for the Dynamic Thermal Power
+	 Management tree on this platform. That will create all the
+	 power capping capable devices.
+
 endif
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
index 875032f7344e..05f31a4e743c 100644
--- a/drivers/soc/rockchip/Makefile
+++ b/drivers/soc/rockchip/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
 obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
 obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
+obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
new file mode 100644
index 000000000000..0b73a9cba954
--- /dev/null
+++ b/drivers/soc/rockchip/dtpm.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2021 Linaro Limited
+ *
+ * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
+ *
+ * DTPM hierarchy description
+ */
+#include <linux/dtpm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static struct dtpm_node __initdata rk3399_hierarchy[] = {
+	[0]{ .name = "rk3399",
+	     .type = DTPM_NODE_VIRTUAL },
+	[1]{ .name = "package",
+	     .type = DTPM_NODE_VIRTUAL,
+	     .parent = &rk3399_hierarchy[0] },
+	[2]{ .name = "/cpus/cpu at 0",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[3]{ .name = "/cpus/cpu at 1",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[4]{ .name = "/cpus/cpu at 2",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[5]{ .name = "/cpus/cpu at 3",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[6]{ .name = "/cpus/cpu at 100",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[7]{ .name = "/cpus/cpu at 101",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[8]{ .name = "/gpu at ff9a0000",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[9]{ },
+};
+
+static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
+        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
+        {},
+};
+
+static int __init rockchip_dtpm_init(void)
+{
+	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
+}
+module_init(rockchip_dtpm_init);
+
+MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
+MODULE_DESCRIPTION("Rockchip DTPM driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dtpm");
+MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano at kernel.org");
-- 
2.25.1



From joe at perches.com  Tue Jan 25 09:19:02 2022
From: joe at perches.com (Joe Perches)
Date: Tue, 25 Jan 2022 09:19:02 -0800
Subject: [PATCH v15 13/13] MAINTAINERS: add AMPHION VPU CODEC V4L2
 driver entry
In-Reply-To: <2f695f6a597a4372842d75105b654fba6db27d59.1643077283.git.ming.qian@nxp.com>
References: <cover.1643077283.git.ming.qian@nxp.com>
 <2f695f6a597a4372842d75105b654fba6db27d59.1643077283.git.ming.qian@nxp.com>
Message-ID: <afcc70baa10003ce89c70b7b310981672547218b.camel@perches.com>

On Tue, 2022-01-25 at 15:11 +0800, Ming Qian wrote:
> Add AMPHION VPU CODEC v4l2 driver entry
[]
> diff --git a/MAINTAINERS b/MAINTAINERS
[]
> @@ -13913,6 +13913,15 @@ S:	Maintained
>  F:	Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
>  F:	drivers/media/platform/imx-jpeg
>  
> +AMPHION VPU CODEC V4L2 DRIVER
> +M:	Ming Qian <ming.qian at nxp.com>
> +M:	Shijie Qin <shijie.qin at nxp.com>
> +M:	Zhou Peng <eagle.zhou at nxp.com>
> +L:	linux-media at vger.kernel.org
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/media/amphion,vpu.yaml
> +F:	drivers/media/platform/amphion/
> +

Alphabetic section ordering please.

>  NZXT-KRAKEN2 HARDWARE MONITORING DRIVER
>  M:	Jonas Malaco <jonas at protocubo.io>
>  L:	linux-hwmon at vger.kernel.org




From maz at kernel.org  Tue Jan 25 09:21:21 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 17:21:21 +0000
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220125165748.GA1458116@bhelgaas>
References: <20220125165748.GA1458116@bhelgaas>
Message-ID: <e8e42eba6e7cf49bc2260f20844a7849@kernel.org>

On 2022-01-25 16:57, Bjorn Helgaas wrote:
> All patches change *something*.  Can you update the subject line so it
> says something specific about the change?
> 
> Maybe something like "Clear MSI status before dispatching handler"?
> 
> On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
>> As an edge-triggered interrupts, its interrupt status should be 
>> cleared
>> before dispatch to the handler of device.
> 
> I'm not an IRQ expert, but the reasoning that "we should clear the MSI
> interrupt status before dispatching the handler because MSI is an
> edge-triggered interrupt" doesn't seem completely convincing because
> your code will now look like this:
> 
>   /* Clear the INTx */
>   writel(1 << bit, port->base + PCIE_INT_STATUS);
>   generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
>   ...
> 
>   /* Clear MSI interrupt status */
>   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
>   generic_handle_domain_irq(port->inner_domain, bit);
> 
> You clear interrupt status before dispatching the handler for *both*
> level-triggered INTx interrupts and edge-triggered MSI interrupts.
> 
> So it doesn't seem that simply being edge-triggered is the critical
> factor here.

This is the usual problem with these half-baked implementations.
The signalling to the primary interrupt controller is level, as
they take a multitude of input and (crucially) latch the MSI
edges. Effectively, this is an edge-to-level converter, with
all the problems that this creates.

By clearing the status *after* the handling, you lose edges that
have been received and coalesced after the read of the status
register. By clearing it *before*, you are acknowledging the
interrupts early, and allowing them to be coalesced independently
of the ones that have been received earlier.

This is however mostly an educated guess. Someone with access
to the TRM should verify this.

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...


From miles.chen at mediatek.com  Tue Jan 25 09:22:58 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:22:58 +0800
Subject: [PATCH 10/31] clk: mediatek: mux: Internalize struct mtk_clk_mux
In-Reply-To: <20220122091731.283592-11-wenst@chromium.org>
References: <20220122091731.283592-11-wenst@chromium.org>
Message-ID: <20220125172258.5469-1-miles.chen@mediatek.com>

> struct mtk_clk_mux is an implementation detail of the mux clk type,
> and is not used outside of the implementation.
> 
> Internalize the definition to minimize leakage of details and shrink
> the header file.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mux.c | 8 ++++++++
>  drivers/clk/mediatek/clk-mux.h | 8 --------
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> index 6f0c22a699c3..2d4d8dc0120a 100644
> --- a/drivers/clk/mediatek/clk-mux.c
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -13,6 +13,14 @@
>  #include "clk-mtk.h"
>  #include "clk-mux.h"
>  
> +struct mtk_clk_mux {
> +	struct clk_hw hw;
> +	struct regmap *regmap;
> +	const struct mtk_mux *data;
> +	spinlock_t *lock;
> +	bool reparent;
> +};
> +
>  static inline struct mtk_clk_mux *to_mtk_clk_mux(struct clk_hw *hw)
>  {
>  	return container_of(hw, struct mtk_clk_mux, hw);
> diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
> index cb2ac4f04c58..38a2b6014b08 100644
> --- a/drivers/clk/mediatek/clk-mux.h
> +++ b/drivers/clk/mediatek/clk-mux.h
> @@ -9,14 +9,6 @@
>  
>  #include <linux/clk-provider.h>
>  
> -struct mtk_clk_mux {
> -	struct clk_hw hw;
> -	struct regmap *regmap;
> -	const struct mtk_mux *data;
> -	spinlock_t *lock;
> -	bool reparent;
> -};
> -
>  struct mtk_mux {
>  	int id;
>  	const char *name;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Tue Jan 25 09:16:04 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:16:04 +0800
Subject: [PATCH 08/31] clk: mediatek: cpumux: Clean up included headers
In-Reply-To: <20220122091731.283592-9-wenst@chromium.org>
References: <20220122091731.283592-9-wenst@chromium.org>
Message-ID: <20220125171604.1548-1-miles.chen@mediatek.com>

> Some headers with the declaration of functions and structures aren't
> directly included. Explicitly include them so that future changes to
> other headers would not result in an unexpected build break.
> 
> On the header side, add forward declarations for any data structures
> whose pointers are used in function signatures. No headers are
> required.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-cpumux.c | 3 +++
>  drivers/clk/mediatek/clk-cpumux.h | 4 ++++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> index 344c6399b22f..658aee789f44 100644
> --- a/drivers/clk/mediatek/clk-cpumux.c
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -5,8 +5,11 @@
>   */
>  
>  #include <linux/clk-provider.h>
> +#include <linux/container_of.h>
> +#include <linux/err.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/module.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
>  
>  #include "clk-mtk.h"
> diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
> index a538f2bbef0d..b07e89f7c283 100644
> --- a/drivers/clk/mediatek/clk-cpumux.h
> +++ b/drivers/clk/mediatek/clk-cpumux.h
> @@ -7,6 +7,10 @@
>  #ifndef __DRV_CLK_CPUMUX_H
>  #define __DRV_CLK_CPUMUX_H
>  
> +struct clk_onecell_data;
> +struct device_node;
> +struct mtk_composite;
> +
>  int mtk_clk_register_cpumuxes(struct device_node *node,
>  			      const struct mtk_composite *clks, int num,
>  			      struct clk_onecell_data *clk_data);
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Tue Jan 25 09:14:07 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:14:07 +0800
Subject: [PATCH 07/31] clk: mediatek: cpumux: Internalize struct
 mtk_clk_cpumux
In-Reply-To: <20220122091731.283592-8-wenst@chromium.org>
References: <20220122091731.283592-8-wenst@chromium.org>
Message-ID: <20220125171407.32525-1-miles.chen@mediatek.com>

> struct mtk_clk_cpumux is an implementation detail of the cpumux clk
> type, and is not used outside of the implementation.
> 
> Internalize the definition to minimize leakage of details and shrink
> the header file.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-cpumux.c | 8 ++++++++
>  drivers/clk/mediatek/clk-cpumux.h | 8 --------
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> index 99a819e3673f..344c6399b22f 100644
> --- a/drivers/clk/mediatek/clk-cpumux.c
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -12,6 +12,14 @@
>  #include "clk-mtk.h"
>  #include "clk-cpumux.h"
>  
> +struct mtk_clk_cpumux {
> +	struct clk_hw	hw;
> +	struct regmap	*regmap;
> +	u32		reg;
> +	u32		mask;
> +	u8		shift;
> +};
> +
>  static inline struct mtk_clk_cpumux *to_mtk_clk_cpumux(struct clk_hw *_hw)
>  {
>  	return container_of(_hw, struct mtk_clk_cpumux, hw);
> diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h
> index fda7770fd803..a538f2bbef0d 100644
> --- a/drivers/clk/mediatek/clk-cpumux.h
> +++ b/drivers/clk/mediatek/clk-cpumux.h
> @@ -7,14 +7,6 @@
>  #ifndef __DRV_CLK_CPUMUX_H
>  #define __DRV_CLK_CPUMUX_H
>  
> -struct mtk_clk_cpumux {
> -	struct clk_hw	hw;
> -	struct regmap	*regmap;
> -	u32		reg;
> -	u32		mask;
> -	u8		shift;
> -};
> -
>  int mtk_clk_register_cpumuxes(struct device_node *node,
>  			      const struct mtk_composite *clks, int num,
>  			      struct clk_onecell_data *clk_data);
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From krzysztof.kozlowski at canonical.com  Tue Jan 25 09:26:13 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 18:26:13 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
Message-ID: <4cfcde38-50cb-646a-0d17-c2cb2977a2e4@canonical.com>

On 25/01/2022 18:12, Krzysztof Kozlowski wrote:
> On 24/01/2022 15:16, Alim Akhtar wrote:
>> Adds basic support for the Tesla Full Self-Driving (FSD)
>> SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
>> as well as several IPs.
>>
>> Patches 1 to 9 provide support for the clock controller
>> (which is designed similarly to Exynos SoCs).
>>
>> The remaining changes provide pinmux support, initial device tree support.
>>
>> - Changes since v4
>> * fixed 'make dtbs_check' warnings on patch 14/16
>>
>> - Changes since v3
>> * Addressed Stefen's review comments on patch 14/16
>> * Fixed kernel test robot warning on patch 04/16
>> * rebsaed this series on Krzysztof's pinmux new binding schema work [1]
>>
>> - Changes since v2
>> * Addressed Krzysztof's and Stephen's review comments
>> * Added Reviewed-by and Acked-by tags
>> * Rebased on next-20220120
>>
>> - Changes since v1
>> * fixed make dt_binding_check error as pointed by Rob
>> * Addressed Krzysztof's and Rob's review comments
>> * Added Reviewed-by and Acked-by tags
>> * Dropped SPI, MCT and ADC from this series (to be posted in small sets)
>>
>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups") 
>> [1] https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/log/?h=for-next
>>
>>
> 
> Thanks, applied DTS/soc and pinctrl patches.
> 
> I expect Sylwester will pick up the clock ones. Otherwise please let me
> know to pick it up as well.

I forgot that clock macros are used in DTS. This does not compile and I
cannot take drivers into DTS branch.

Alim,
DTS changes dropped. Please resend with the same trick we did for
Exynos850 board - hard-coded clock IDs as defines. See:

https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/diff/arch/arm64/boot/dts/exynos/exynos850.dtsi?h=samsung-dt64-5.17-2&id=e3493220fd3e474abcdcefbe14fb60485097ce06


Best regards,
Krzysztof


From oupton at google.com  Tue Jan 25 09:29:13 2022
From: oupton at google.com (Oliver Upton)
Date: Tue, 25 Jan 2022 09:29:13 -0800
Subject: KVM/arm64: Guest ABI changes do not appear rollback-safe
In-Reply-To: <875yq88app.wl-maz@kernel.org>
References: <YSVhV+UIMY12u2PW@google.com> <87mtp5q3gx.wl-maz@kernel.org>
 <CAOQ_QshSaEm_cMYQfRTaXJwnVqeoN29rMLBej-snWd6_0HsgGw@mail.gmail.com>
 <87fsuxq049.wl-maz@kernel.org> <20210825150713.5rpwzm4grfn7akcw@gator.home>
 <CAOQ_QsgWiw9-BuGTUFpHqBw3simUaM4Tweb9y5_oz1UHdr4ELg@mail.gmail.com>
 <877dg8ppnt.wl-maz@kernel.org> <YSfiN3Xq1vUzHeap@google.com>
 <20210827074011.ci2kzo4cnlp3qz7h@gator.home>
 <CAOQ_Qsg2dKLLanSx6nMbC1Er9DSO3peLVEAJNvU1ZcRVmwaXgQ@mail.gmail.com>
 <87ilyitt6e.wl-maz@kernel.org>
 <CAOQ_QshfXEGL691_MOJn0YbL94fchrngP8vuFReCW-=5UQtNKQ@mail.gmail.com>
 <87lf3drmvp.wl-maz@kernel.org>
 <CAOQ_QsjVk9n7X9E76ycWBNguydPE0sVvywvKW0jJ_O58A0NJHg@mail.gmail.com>
 <CAJHc60wp4uCVQhigNrNxF3pPd_8RPHXQvK+gf7rSxCRfH6KwFg@mail.gmail.com>
 <875yq88app.wl-maz@kernel.org>
Message-ID: <CAOQ_QshL2MCc8-vkYRTDhtZXug20OnMg=qedhSGDrp_VUnX+5g@mail.gmail.com>

Hi Marc,

On Tue, Jan 25, 2022 at 12:46 AM Marc Zyngier <maz at kernel.org> wrote:
> > If I understand correctly, the original motivation for going with
> > pseudo-registers was to comply with QEMU, which uses KVM_GET_REG_LIST
> > and KVM_[GET|SET]_ONE_REG interface, but I'm guessing the VMMs doing
> > save/restore across migration might write the same values for every
> > vCPU.
>
> KVM currently restricts the vcpu features to be unified across vcpus,
> but that's only an implementation choice.

But that implementation choice has become ABI, no? How could support
for asymmetry be added without requiring userspace opt-in or breaking
existing VMMs that depend on feature unification?

> The ARM architecture doesn't
> mandate that these registers are all the same, and it isn't impossible
> that we'd allow for the feature set to become per-vcpu at some point
> in time. So this argument doesn't really hold.

Accessing per-VM state N times is bound to increase VM blackout time
during migrations ~linearly as the number of vCPUs in a VM increases,
since a VM scoped lock is necessary to serialize guest accesses. It
could be tolerable at present scale, but seems like in the future it
could become a real problem.

> Furthermore, compatibility with QEMU's save/restore model is
> essential, and AFAICT, there is no open source alternative.

Agree fundamentally, but I believe it is entirely reasonable to
require a userspace change to adopt a new KVM feature. Otherwise, we
may be trying to shoehorn new features into existing UAPI that may not
be a precise fit..

In order to cure the serialization mentioned above, two options are
top of mind: accessing the VM state with the VM FD or informing
userspace that a set of registers need only be written once for an
entire VM. If we add support for asymmetry later down the road, that
would become an opt-in such that userspace will do the access
per-vCPU.

> A device means yet another configuration and migration API. Don't you
> think we have enough of those? The complexity of KVM/arm64 userspace
> API is already insane, and extremely fragile. Adding to it will be a
> validation nightmare (it already is, and I don't see anyone actively
> helping with it).

It seems equally fragile to introduce VM-wide serialization to vCPU
UAPI that we know is in the live migration critical path for _any_
VMM. Without requiring userspace changes for all the new widgets under
discussion we're effectively forcing VMMs to do something suboptimal.

--
Thanks,
Oliver


From miles.chen at mediatek.com  Tue Jan 25 09:20:48 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:20:48 +0800
Subject: [PATCH 09/31] clk: mediatek: mux: Implement unregister API
In-Reply-To: <20220122091731.283592-10-wenst@chromium.org>
References: <20220122091731.283592-10-wenst@chromium.org>
Message-ID: <20220125172048.4239-1-miles.chen@mediatek.com>

> The mux clk type within the MediaTek clk driver library only has a
> register function, and no corresponding unregister function. This
> means there is no way for its users to properly implement cleanup
> and removal.
> 
> Add a matching unregister function for the mux type clk.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mux.c | 35 ++++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-mux.h |  3 +++
>  2 files changed, 38 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> index 89f23e111d91..6f0c22a699c3 100644
> --- a/drivers/clk/mediatek/clk-mux.c
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -164,6 +164,21 @@ static struct clk *mtk_clk_register_mux(const struct mtk_mux *mux,
>  	return clk;
>  }
>  
> +static void mtk_clk_unregister_mux(struct clk *clk)
> +{
> +	struct mtk_clk_mux *mux;
> +	struct clk_hw *hw;
> +
> +	hw = __clk_get_hw(clk);
> +	if (!hw)
> +		return;
> +
> +	mux = to_mtk_clk_mux(hw);
> +
> +	clk_unregister(clk);
> +	kfree(mux);
> +}
> +
>  int mtk_clk_register_muxes(const struct mtk_mux *muxes,
>  			   int num, struct device_node *node,
>  			   spinlock_t *lock,
> @@ -198,4 +213,24 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
>  
> +void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
> +			      struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_mux *mux = &muxes[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
> +
> +		mtk_clk_unregister_mux(clk_data->clks[mux->id]);
> +		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(mtk_clk_unregister_muxes);
> +
>  MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
> index 27841d649118..cb2ac4f04c58 100644
> --- a/drivers/clk/mediatek/clk-mux.h
> +++ b/drivers/clk/mediatek/clk-mux.h
> @@ -88,4 +88,7 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
>  			   spinlock_t *lock,
>  			   struct clk_onecell_data *clk_data);
>  
> +void mtk_clk_unregister_muxes(const struct mtk_mux *muxes, int num,
> +			      struct clk_onecell_data *clk_data);
> +
>  #endif /* __DRV_CLK_MTK_MUX_H */
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From robin.murphy at arm.com  Tue Jan 25 09:35:30 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 25 Jan 2022 17:35:30 +0000
Subject: [BUG] dts: hi6220: PMU events not fully functional
In-Reply-To: <CABk+d1tuNMoedpHyA2WwtPv33RCXnui9430D5jysePX2ZPawDg@mail.gmail.com>
References: <CABk+d1tuNMoedpHyA2WwtPv33RCXnui9430D5jysePX2ZPawDg@mail.gmail.com>
Message-ID: <5e141317-3100-a22f-2db6-c5a41c1abf06@arm.com>

On 2022-01-24 22:33, Carlton Shepherd wrote:
> Hello,
> 
> The perf subsystem does not detect any PMU events for the HiSilicon
> 6220 SoC. (Tested on a HiKey 620 with 5.17.0-rc1.)
> 
> Based on [1] and [2], /arch/arm64/boot/dts/hisilicon/hi6220.dtsi is
> missing a PMU node. This was patched for the hi3660 in
> /arch/arm64/boot/dts/hisilicon/hi3660.dtsi [3], but remains defective
> for the hi6220.
> 
> Could somebody please provide some assistance?

According to the SoC functional description linked from [4], the PMU 
interrupts for all the CPUs appear to be combined into a single IRQ 
line, which means we'll never be able to support it in Linux anyway.

Cheers,
Robin.

[4] 
https://www.96boards.org/documentation/consumer/hikey/hikey620/hardware-docs/

> 
> Kind regards,
> Carlton Shepherd
> 
> 1. https://www.96boards.org/documentation/consumer/hikey/hikey960/support/pmu-on-hikey960.md.html
> 2. https://discuss.96boards.org/t/linux-perf-list-failing-to-detect-hardware-events-on-hikey620/11752
> 3. https://www.mail-archive.com/linux-kernel at vger.kernel.org/msg1465696.html
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From miles.chen at mediatek.com  Tue Jan 25 09:38:36 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:38:36 +0800
Subject: [PATCH 11/31] clk: mediatek: mux: Clean up included headers
In-Reply-To: <20220122091731.283592-12-wenst@chromium.org>
References: <20220122091731.283592-12-wenst@chromium.org>
Message-ID: <20220125173836.14548-1-miles.chen@mediatek.com>

> Some included headers aren't actually used anywhere, while other headers
> with the declaration of functions and structures aren't directly
> included.
> 
> Get rid of the unused ones, and add the ones that should be included
> directly.
> 
> On the header side, replace headers that are included purely for data
> structure definitions with forward declarations. This decreases the
> amount of preprocessing and compilation effort required for each
> inclusion.

Is this inspired by [1]?
[1] https://lore.kernel.org/lkml/YdIfz+LMewetSaEB at gmail.com/ 

> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mux.c | 11 +++++++----
>  drivers/clk/mediatek/clk-mux.h |  8 +++++++-
>  2 files changed, 14 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> index 2d4d8dc0120a..01af6a52711a 100644
> --- a/drivers/clk/mediatek/clk-mux.c
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -4,13 +4,16 @@
>   * Author: Owen Chen <owen.chen at mediatek.com>
>   */
>  
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> -#include <linux/slab.h>
> +#include <linux/clk-provider.h>
> +#include <linux/compiler_types.h>
> +#include <linux/container_of.h>
> +#include <linux/err.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/spinlock.h>
> +#include <linux/slab.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-mux.h"
>  
>  struct mtk_clk_mux {
> diff --git a/drivers/clk/mediatek/clk-mux.h b/drivers/clk/mediatek/clk-mux.h
> index 38a2b6014b08..903a3c937959 100644
> --- a/drivers/clk/mediatek/clk-mux.h
> +++ b/drivers/clk/mediatek/clk-mux.h
> @@ -7,7 +7,13 @@
>  #ifndef __DRV_CLK_MTK_MUX_H
>  #define __DRV_CLK_MTK_MUX_H
>  
> -#include <linux/clk-provider.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
> +
> +struct clk;
> +struct clk_onecell_data;
> +struct clk_ops;
> +struct device_node;
>  
>  struct mtk_mux {
>  	int id;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From broonie at kernel.org  Tue Jan 25 09:44:47 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 17:44:47 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk> <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
Message-ID: <YfA3D3c+lOyybNT3@sirena.org.uk>

On Tue, Jan 25, 2022 at 04:33:39PM +0000, Mark Rutland wrote:
> On Tue, Jan 25, 2022 at 03:59:38PM +0000, Mark Brown wrote:
> > On Tue, Jan 25, 2022 at 03:00:43PM +0000, Mark Rutland wrote:

> > > As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
> > > used as a value rather than as a bit mask.

> > Well, it's both and we do call it a mask in both the kernel and TF-A
> > too...

> Here specifically in the boot-wrapper I'm just using it as a value, so I don't
> see that those are relevant?

That's also a bunch of the other usage - the kernel uses it to set the
maximum available value by virtue of setting every possible bit in the
bitfield, though it does also use it as a mask in places.

> The idea was to be consistent with the <register>_<field>_<valuename> naming,
> and avoiding the "why are you programming a mask as the value" questions from
> last time around, where the unambiguous options are:

I've not seen that - I did see that there had been some discussion as to
why the code had been including the reserved bits but hadn't seen any
discussion of confusion between mask and max.

> a) Use <register>_<field>_<valuename> definition, as here.

> b) Use <register>_<field>_MASK, and add comments at each usage as to why we use
>    a mask as a value, to explain why that isn't a bug.

> c) Have both <register>_<field>_MASK and some value definition, and use some
>    insertion helper to insert the value.

> ... and I went with (a) because it was the simplest.

> Is there a problem with this?

My concern is continuity of the enumeration algorithm between the
various implementations we have, it's something we're not currently
great with and this creates a separation between the kernel and the boot
wrapper implementations.  There's no change in what's actually being
done but it creates some additional effort to figure out why we're
setting a maximum here and not trying to set all the bits as we do in
the kernel.  TF-A is doing something else again (actually two different
things if you include SME which uses the same algorithm for the
streaming vector length), for SVE it uses a maximum length too but it
uses a lower length than the maximum representable one that's used here.

It may be that the best thing to do is to make this change but also
update the kernel to have separate but identical mask and maximum
definitions, though TBH I'd rather not actually have that update happen
while the SME series is pending.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 484 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220125/6e49e689/attachment-0001.sig>

From miles.chen at mediatek.com  Tue Jan 25 09:54:55 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 01:54:55 +0800
Subject: [PATCH] pinctrl: fix a discarded-qualifiers build error
Message-ID: <20220125175457.23728-1-miles.chen@mediatek.com>

Fix COMPILER=gcc ARCH=arm64 DEFCONFIG=allyesconfig build:

log:
drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards
'const' qualifier from pointer target type [-Werror=discarded-qualifiers]

Fixes: 12422af8194d ("pinctrl: Add Intel Thunder Bay pinctrl driver")
Signed-off-by: Miles Chen <miles.chen at mediatek.com>
---
 drivers/pinctrl/pinctrl-thunderbay.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-thunderbay.c b/drivers/pinctrl/pinctrl-thunderbay.c
index b5b47f4dd774..4e6d718c03fc 100644
--- a/drivers/pinctrl/pinctrl-thunderbay.c
+++ b/drivers/pinctrl/pinctrl-thunderbay.c
@@ -812,7 +812,7 @@ static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct funct
 				}
 			}
 
-			grp = func->group_names;
+			grp = (const char **)func->group_names;
 			while (*grp)
 				grp++;
 
-- 
2.18.0



From miquel.raynal at bootlin.com  Tue Jan 25 09:55:56 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Tue, 25 Jan 2022 18:55:56 +0100
Subject: [PATCH] mtd: rawnand: atmel: fix refcount leaks in
 atmel_nand_controller_init
In-Reply-To: <20220125123155.36891-1-xiongx18@fudan.edu.cn>
References: <20220125123155.36891-1-xiongx18@fudan.edu.cn>
Message-ID: <20220125185556.6afb7eba@xps13>

Hi Xin,

xiongx18 at fudan.edu.cn wrote on Tue, 25 Jan 2022 20:31:56 +0800:

> The reference counting issue happens in several error handling paths
> on a refcounted object "nc->dmac". In these paths, the function simply
> returns the error code, forgetting to balance the reference count
> increased earlier by dma_request_channel(), which may cause refcount
> leaks. What's more, the "nc->mck" object also needs to be handled
> correctly.

You might want to split this into two commits.

> 
> Fix it by adding specific error handling code in those error paths.

You need a Fixes tag here.

> Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
> Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
> Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>

You can't do that. The patch is rather straightforward, so 3
authorship seem a little bit too much.

If someone suggested you a change, or sent you a proposal, you should
use a Suggested-by. If it was reported by a colleague, use Reported-by.
If it was co-developped, use the right tag and the right Signed-off-by
as documented in the submitted-process.rst file. If you picked the
patch from someone else, you must preserve the authorship and just add
your SoB.

> ---
>  drivers/mtd/nand/raw/atmel/nand-controller.c | 22 +++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
> index f3276ee9e..b3801ebd2 100644
> --- a/drivers/mtd/nand/raw/atmel/nand-controller.c
> +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
> @@ -2060,13 +2060,15 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
>  	nc->mck = of_clk_get(dev->parent->of_node, 0);
>  	if (IS_ERR(nc->mck)) {
>  		dev_err(dev, "Failed to retrieve MCK clk\n");
> -		return PTR_ERR(nc->mck);
> +		ret = PTR_ERR(nc->mck);
> +		goto out_release_dma;
>  	}
>  
>  	np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
>  	if (!np) {
>  		dev_err(dev, "Missing or invalid atmel,smc property\n");
> -		return -EINVAL;
> +		ret = -EINVAL;
> +		goto out_put_clk;
>  	}
>  
>  	nc->smc = syscon_node_to_regmap(np);
> @@ -2074,10 +2076,24 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
>  	if (IS_ERR(nc->smc)) {
>  		ret = PTR_ERR(nc->smc);
>  		dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
> -		return ret;
> +		goto out_put_clk;
>  	}
>  
>  	return 0;
> +
> +out_put_clk:
> +	clk_put(nc->mck);
> +	nc->mck = NULL;
> +
> +out_release_dma:
> +	if (nc->caps->has_dma && !atmel_nand_avoid_dma) {
> +		if (!IS_ERR_OR_NULL(nc->dmac)) {

	   && !IS_ERR...

> +			dma_release_channel(nc->dmac);
> +			nc->dmac = NULL;
> +		}
> +	}
> +
> +	return ret;
>  }
>  
>  static int


Thanks,
Miqu?l


From zajec5 at gmail.com  Tue Jan 25 10:01:12 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 25 Jan 2022 19:01:12 +0100
Subject: [PATCH 0/2] dt-bindings: nvmem: support describing cells
Message-ID: <20220125180114.12286-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

Michael has recently posted a cleaned up patchset for NVMEM
transformations support:
[PATCH 0/8] nvmem: add ethernet address offset support
https://lore.kernel.org/lkml/20211228142549.1275412-1-michael at walle.cc/T/
https://patchwork.ozlabs.org/project/linux-mtd/list/?series=278644&state=*

I find it very important & fully support it. In home routers we very
often deal with just one MAC address that:
1. Is a base for calculating multiple Ethernet addresses
2. Can be stored in binary as well as ASCII format

I'd like to suggest just a slightly different solution though. I think
that using something like:

otp-1 {
        compatible = "kontron,sl28-vpd", "user-otp";
        #address-cells = <1>;
        #size-cells = <1>;

        base_mac_address: base-mac-address at 17 {
                #nvmem-cell-cells = <1>;
                reg = <17 6>;
        };
};

isn't clear enough and requires too much conditional code in Linux /
whatever implementation. DT doesn't make it clear which NVMEM cells
are used for what and how should be handled. That has to be hardcoded in
a Linux / whatever driver.

My idea is to add "compatible" & additional flags to NVMEM cells.
Example:

otp-1 {
        compatible = "user-otp";
        #address-cells = <1>;
        #size-cells = <1>;

        base_mac_address: base-mac-address at 17 {
                compatible = "mac-address";
                reg = <17 6>;
                #nvmem-cell-cells = <1>;
        };
};

(for more examples see PATCH 2/2 and its mac-address.yaml .

Rafa? Mi?ecki (2):
  dt-bindings: nvmem: extract NVMEM cell to separated file
  dt-bindings: nvmem: cells: add MAC address cell

 .../devicetree/bindings/nvmem/cells/cell.yaml | 35 +++++++
 .../bindings/nvmem/cells/mac-address.yaml     | 94 +++++++++++++++++++
 .../devicetree/bindings/nvmem/nvmem.yaml      | 25 +----
 3 files changed, 131 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/cell.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml

-- 
2.31.1



From zajec5 at gmail.com  Tue Jan 25 10:01:13 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 25 Jan 2022 19:01:13 +0100
Subject: [PATCH 1/2] dt-bindings: nvmem: extract NVMEM cell to separated file
In-Reply-To: <20220125180114.12286-1-zajec5@gmail.com>
References: <20220125180114.12286-1-zajec5@gmail.com>
Message-ID: <20220125180114.12286-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This will allow adding binding for more specific cells and reusing
(sharing) common code.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../devicetree/bindings/nvmem/cells/cell.yaml | 35 +++++++++++++++++++
 .../devicetree/bindings/nvmem/nvmem.yaml      | 25 ++-----------
 2 files changed, 37 insertions(+), 23 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/cell.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/cells/cell.yaml b/Documentation/devicetree/bindings/nvmem/cells/cell.yaml
new file mode 100644
index 000000000000..5d62d0c8f1e1
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/cells/cell.yaml
@@ -0,0 +1,35 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/cells/cell.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM cell
+
+maintainers:
+  - Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
+
+description: NVMEM cell is a data entry of NVMEM device.
+
+properties:
+  reg:
+    maxItems: 1
+    description:
+      Offset and size in bytes within the storage device.
+
+  bits:
+    maxItems: 1
+    items:
+      items:
+        - minimum: 0
+          maximum: 7
+          description:
+            Offset in bit within the address range specified by reg.
+        - minimum: 1
+          description:
+            Size in bit within the address range specified by reg.
+
+required:
+  - reg
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
index 456fb808100a..6b075c1db446 100644
--- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml
+++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
@@ -40,29 +40,8 @@ properties:
     maxItems: 1
 
 patternProperties:
-  "@[0-9a-f]+(,[0-7])?$":
-    type: object
-
-    properties:
-      reg:
-        maxItems: 1
-        description:
-          Offset and size in bytes within the storage device.
-
-      bits:
-        maxItems: 1
-        items:
-          items:
-            - minimum: 0
-              maximum: 7
-              description:
-                Offset in bit within the address range specified by reg.
-            - minimum: 1
-              description:
-                Size in bit within the address range specified by reg.
-
-    required:
-      - reg
+  "@[0-9a-f]+$":
+    $ref: cells/cell.yaml#
 
 additionalProperties: true
 
-- 
2.31.1



From zajec5 at gmail.com  Tue Jan 25 10:01:14 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Tue, 25 Jan 2022 19:01:14 +0100
Subject: [PATCH 2/2] dt-bindings: nvmem: cells: add MAC address cell
In-Reply-To: <20220125180114.12286-1-zajec5@gmail.com>
References: <20220125180114.12286-1-zajec5@gmail.com>
Message-ID: <20220125180114.12286-3-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This adds support for describing details of NVMEM cell containing MAC
address. Those are often device specific and could be nicely stored in
DT.

Initial documentation includes support for describing:
1. Cell data format (e.g. Broadcom's NVRAM uses ASCII to store MAC)
2. Reversed bytes flash (required for i.MX6/i.MX7 OCOTP support)
3. Source for multiple addresses (very common in home routers)

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/nvmem/cells/mac-address.yaml     | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml b/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml
new file mode 100644
index 000000000000..f8d19e87cdf0
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/cells/mac-address.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM cell containing a MAC address
+
+maintainers:
+  - Rafa? Mi?ecki <rafal at milecki.pl>
+
+properties:
+  compatible:
+    const: mac-address
+
+  format:
+    description: |
+      Some NVMEM cells contain MAC in a non-binary format.
+
+      ASCII should be specified if MAC is string formatted like:
+      - "01:23:45:67:89:AB" (30 31 3a 32 33 3a 34 35 3a 36 37 3a 38 39 3a 41 42)
+      - "01-23-45-67-89-AB"
+      - "0123456789AB"
+    enum:
+      - ascii
+
+  reversed-bytes:
+    type: boolean
+    description: |
+      MAC is stored in reversed bytes order. Example:
+      Stored value: AB 89 67 45 23 01
+      Actual MAC: 01 23 45 67 89 AB
+
+  base-address:
+    type: boolean
+    description: |
+      Marks NVMEM cell as provider of multiple addresses that are relative to
+      the one actually stored physically. Respective addresses can be requested
+      by specifying cell index of NVMEM cell.
+
+allOf:
+  - $ref: cell.yaml#
+  - if:
+      required:
+        - base-address
+    then:
+      properties:
+        "#nvmem-cell-cells":
+          const: 1
+      required:
+        - "#nvmem-cell-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    partitions {
+        compatible = "fixed-partitions";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        partition at f00000 {
+            compatible = "nvmem-cells";
+            label = "calibration";
+            reg = <0xf00000 0x100000>;
+            ranges = <0 0xf00000 0x100000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            mac at 100 {
+                compatible = "mac-address";
+                reg = <0x100 0x6>;
+            };
+
+            mac at 200 {
+                compatible = "mac-address";
+                reg = <0x200 0x6>;
+                reversed-bytes;
+            };
+
+            mac at 300 {
+                compatible = "mac-address";
+                reg = <0x300 0x11>;
+                format = "ascii";
+            };
+
+            mac at 400 {
+                compatible = "mac-address";
+                reg = <0x400 0x6>;
+                base-address;
+                #nvmem-cell-cells = <1>;
+            };
+        };
+    };
-- 
2.31.1



From l.stach at pengutronix.de  Tue Jan 25 10:19:16 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Jan 2022 19:19:16 +0100
Subject: [PATCH V4 08/11] arm64: dts: imx8mm: Fix VPU Hanging
In-Reply-To: <20220125171129.472775-9-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-9-aford173@gmail.com>
Message-ID: <3b1c784ac4e21c2e6d5a645fdf673aa47348c6f4.camel@pengutronix.de>

Am Dienstag, dem 25.01.2022 um 11:11 -0600 schrieb Adam Ford:
> The vpumix power domain has a reset assigned to it, however
> when used, it causes a system hang.  Testing has shown that
> it does not appear to be needed anywhere.
> 
> Fixes: d39d4bb15310 ("arm64: dts: imx8mm: add GPC node")
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> index f77f90ed416f..0c7a72c51a31 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> @@ -707,7 +707,6 @@ pgc_vpumix: power-domain at 6 {
>  						clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
>  						assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
>  						assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
> -						resets = <&src IMX8MQ_RESET_VPU_RESET>;
>  					};
>  
>  					pgc_vpu_g1: power-domain at 7 {




From james.morse at arm.com  Tue Jan 25 10:19:45 2022
From: james.morse at arm.com (James Morse)
Date: Tue, 25 Jan 2022 18:19:45 +0000
Subject: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and
 PAC trap errata
In-Reply-To: <87mtjj7o7y.wl-maz@kernel.org>
References: <20220125153803.549084-1-james.morse@arm.com>
 <20220125153803.549084-5-james.morse@arm.com> <87mtjj7o7y.wl-maz@kernel.org>
Message-ID: <711e16a1-c853-10e8-43d5-31890f0d4c7c@arm.com>

Hi Marc,

On 25/01/2022 16:51, Marc Zyngier wrote:
> On Tue, 25 Jan 2022 15:38:03 +0000,
> James Morse <james.morse at arm.com> wrote:
>>
>> Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
>> single-stepping authenticated ERET instructions. A single step is
>> expected, but a pointer authentication trap is taken instead. The
>> erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
>> EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
>>
>> Because the conditions require an ERET into active-not-pending state,
>> this is only a problem for the EL2 when EL2 is stepping EL1. In this case
>> the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
>> restored.

> Urgh. That's pretty nasty :-(.

>> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
>> index 331dd10821df..93bf140cc972 100644
>> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
>> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
>> @@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>>  			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
>>  	}
>>  
>> +	/*
>> +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
>> +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
>> +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
>> +	 * Did we just take a PAC exception when a step exception was expected?
>> +	 */
>> +	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&
> 
> nit: we can drop this IS_ENABLED()...

Hmmm, I thought dead code elimination was a good thing!
Without the cpu_errata.c match, (which is also guarded by #ifdef), the cap will never be
true, even if an affected CPU showed up. This way the compiler knows it can remove all this.


>> +	    cpus_have_const_cap(ARM64_WORKAROUND_2077057) &&
> 
> and make this a final cap. Being a ARM64_CPUCAP_LOCAL_CPU_ERRATUM, we
> won't accept late CPUs on a system that wasn't affected until then.
> 
>> +	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ &&
>> +	    esr_ec == ESR_ELx_EC_PAC &&
>> +	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
>> +		/* Active-not-pending? */
>> +		if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
>> +			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> 
> Err... Isn't this way too late? The function starts with:
> 
> 	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
> 
> which is just another way to write:
> 
> 	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> 
> By that time, the vcpu's PSTATE is terminally corrupted.

Yes -  bother. Staring at it didn't let me spot that!
I can hit the conditions to test this, but due to lack of imagination the model doesn't
corrupt the SPSR.


> I think you need to hoist this workaround way up, before we call into
> early_exit_filter() as it will assume that the guest pstate is correct
> (this is used by both pKVM and the NV code).
> 
> Something like this (untested):
> 
> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> index 93bf140cc972..a8a1502db237 100644
> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> @@ -402,6 +402,26 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  	return false;
>  }
>  
> +static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu,
> +					   u64 *exit_code)
> +{
> +	/*
> +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
> +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
> +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
> +	 * Did we just take a PAC exception when a step exception (being in the
> +	 * Active-not-pending state) was expected?
> +	 */
> +	if (cpus_have_final_cap(ARM64_WORKAROUND_2077057)	&&
> +	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ	&&

> +	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_PAC	&&

The vcpu's esr_el2 isn't yet set:
| ESR_ELx_EC(read_sysreg_el2(SYS_ESR)) == ESR_ELx_EC_PAC

(and I'll shuffle the order so this is last as its an extra sysreg read)


> +	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP		&&
> +	    *vcpu_cpsr(vcpu) & DBG_SPSR_SS)
> +		write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> +
> +	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> +}
> +
>  /*
>   * Return true when we were able to fixup the guest exit and should return to
>   * the guest, false when we should restore the host state and return to the
> @@ -415,7 +435,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>  	 * Save PSTATE early so that we can evaluate the vcpu mode
>  	 * early on.
>  	 */
> -	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
> +	synchronize_vcpu_pstate(vcpu, exit_code);

Even better, that saves the noise from moving esr_ec around!


> Other than that, I'm happy to take the series as a whole ASAP, if only
> for the two pretty embarrassing bug fixes. If you can respin it
> shortly and address the comments above, I'd like it into -rc2.

Will do. Shout if you strongly care about the IS_ENABLED().


Thanks,

James


From l.stach at pengutronix.de  Tue Jan 25 10:20:57 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Jan 2022 19:20:57 +0100
Subject: [PATCH V4 07/11] arm64: dts: imx8mq: Enable both G1 and G2
 VPU's with vpu-blk-ctrl
In-Reply-To: <20220125171129.472775-8-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-8-aford173@gmail.com>
Message-ID: <3c88964a10f2e0b523191ca2f66602c6644efd7c.camel@pengutronix.de>

Am Dienstag, dem 25.01.2022 um 11:11 -0600 schrieb Adam Ford:
> With the Hantro G1 and G2 now setup to run independently, update
> the device tree to allow both to operate.  This requires the
> vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
> certain clock enabled to handle the gating of the G1 and G2
> fuses, the clock-parents and clock-rates for the various VPU's
> to be moved into the pgc_vpu because they cannot get re-parented
> once enabled, and the pgc_vpu is the highest in the chain.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reported-by: kernel test robot <lkp at intel.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 2df2510d0118..549b2440f55d 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
>  					pgc_vpu: power-domain at 6 {
>  						#power-domain-cells = <0>;
>  						reg = <IMX8M_POWER_DOMAIN_VPU>;
> -						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> +						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +						assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> +								  <&clk IMX8MQ_CLK_VPU_G2>,
> +								  <&clk IMX8MQ_CLK_VPU_BUS>,
> +								  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> +						assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_SYS1_PLL_800M>,
> +									 <&clk IMX8MQ_VPU_PLL>;
> +						assigned-clock-rates = <600000000>,
> +								       <600000000>,
> +								       <800000000>,
> +								       <0>;
>  					};
>  
>  					pgc_disp: power-domain at 7 {
> @@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
>  			status = "disabled";
>  		};
>  
> -		vpu: video-codec at 38300000 {
> -			compatible = "nxp,imx8mq-vpu";
> -			reg = <0x38300000 0x10000>,
> -			      <0x38310000 0x10000>,
> -			      <0x38320000 0x10000>;
> -			reg-names = "g1", "g2", "ctrl";
> -			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> -				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> -			interrupt-names = "g1", "g2";
> +		vpu_g1: video-codec at 38300000 {
> +			compatible = "nxp,imx8mq-vpu-g1";
> +			reg = <0x38300000 0x10000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> +		};
> +
> +		vpu_g2: video-codec at 38310000 {
> +			compatible = "nxp,imx8mq-vpu-g2";
> +			reg = <0x38310000 0x10000>;
> +			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> +		};
> +
> +		vpu_blk_ctrl: blk-ctrl at 38320000 {
> +			compatible = "fsl,imx8mq-vpu-blk-ctrl";
> +			reg = <0x38320000 0x100>;
> +			power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
> +			power-domain-names = "bus", "g1", "g2";
>  			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> -			clock-names = "g1", "g2", "bus";
> -			assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> -					  <&clk IMX8MQ_CLK_VPU_G2>,
> -					  <&clk IMX8MQ_CLK_VPU_BUS>,
> -					  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> -			assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_SYS1_PLL_800M>,
> -						 <&clk IMX8MQ_VPU_PLL>;
> -			assigned-clock-rates = <600000000>, <600000000>,
> -					       <800000000>, <0>;
> -			power-domains = <&pgc_vpu>;
> +				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			clock-names = "g1", "g2";
> +			#power-domain-cells = <1>;
>  		};
>  
>  		pcie0: pcie at 33800000 {




From l.stach at pengutronix.de  Tue Jan 25 10:21:44 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Jan 2022 19:21:44 +0100
Subject: [PATCH V4 11/11] arm64: dts: imx8mm: Enable Hantro G1 and G2
 video decoders
In-Reply-To: <20220125171129.472775-12-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-12-aford173@gmail.com>
Message-ID: <19c4213b279992363080a9f36668562ddd17d1e0.camel@pengutronix.de>

Am Dienstag, dem 25.01.2022 um 11:11 -0600 schrieb Adam Ford:
> There are two decoders on the i.MX8M Mini controlled by the
> vpu-blk-ctrl.  The G1 supports H264 and VP8 while the
> G2 support HEVC and VP9.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> index 0c7a72c51a31..98aec4421713 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
> @@ -1272,6 +1272,22 @@ gpu_2d: gpu at 38008000 {
>  			power-domains = <&pgc_gpu>;
>  		};
>  
> +		vpu_g1: video-codec at 38300000 {
> +			compatible = "nxp,imx8mm-vpu-g1";
> +			reg = <0x38300000 0x10000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MM_CLK_VPU_G1_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G1>;
> +		};
> +
> +		vpu_g2: video-codec at 38310000 {
> +			compatible = "nxp,imx8mq-vpu-g2";
> +			reg = <0x38310000 0x10000>;
> +			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MM_CLK_VPU_G2_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MM_VPUBLK_PD_G2>;
> +		};
> +
>  		vpu_blk_ctrl: blk-ctrl at 38330000 {
>  			compatible = "fsl,imx8mm-vpu-blk-ctrl", "syscon";
>  			reg = <0x38330000 0x100>;
> @@ -1282,6 +1298,12 @@ vpu_blk_ctrl: blk-ctrl at 38330000 {
>  				 <&clk IMX8MM_CLK_VPU_G2_ROOT>,
>  				 <&clk IMX8MM_CLK_VPU_H1_ROOT>;
>  			clock-names = "g1", "g2", "h1";
> +			assigned-clocks = <&clk IMX8MM_CLK_VPU_G1>,
> +					  <&clk IMX8MM_CLK_VPU_G2>;
> +			assigned-clock-parents = <&clk IMX8MM_VPU_PLL_OUT>,
> +						 <&clk IMX8MM_VPU_PLL_OUT>;
> +			assigned-clock-rates = <600000000>,
> +					       <600000000>;
>  			#power-domain-cells = <1>;
>  		};
>  




From l.stach at pengutronix.de  Tue Jan 25 10:22:06 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Tue, 25 Jan 2022 19:22:06 +0100
Subject: [PATCH V4 01/11] arm64: dts: imx8mq-tqma8mq: Remove redundant
 vpu reference
In-Reply-To: <20220125171129.472775-2-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-2-aford173@gmail.com>
Message-ID: <176f57f1c2c2c32bd937130aad9f1aeb9255c35b.camel@pengutronix.de>

Am Dienstag, dem 25.01.2022 um 11:11 -0600 schrieb Adam Ford:
> The vpu is enabled by default, so there is no need to manually
> enable it.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> index 8aedcddfeab8..38ffcd145b33 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> @@ -272,10 +272,6 @@ &usdhc1 {
>  	status = "okay";
>  };
>  
> -&vpu {
> -	status = "okay";
> -};
> -
>  /* Attention: wdog reset forcing POR needs baseboard support */
>  &wdog1 {
>  	status = "okay";




From eugenis at google.com  Tue Jan 25 10:22:17 2022
From: eugenis at google.com (Evgenii Stepanov)
Date: Tue, 25 Jan 2022 10:22:17 -0800
Subject: [PATCH v2] arm64: extable: fix load_unaligned_zeropad() reg indices
Message-ID: <20220125182217.2605202-1-eugenis@google.com>

In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
addr register indices from ex->type rather than ex->data. As ex->type will
contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
 * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
   extracted from bits [9:5]. Thus, we may attempt to dereference an
   arbitrary address as X0 may hold an arbitrary value.
 * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
   extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
   behaviour within load_unaligned_zeropad() and its caller.

Fix this by extracting both values from ex->data as originally intended.

On an MTE-enabled QEMU image we are hitting the following crash:
 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
 Call trace:
  fixup_exception+0xc4/0x108
  __do_kernel_fault+0x3c/0x268
  do_tag_check_fault+0x3c/0x104
  do_mem_abort+0x44/0xf4
  el1_abort+0x40/0x64
  el1h_64_sync_handler+0x60/0xa0
  el1h_64_sync+0x7c/0x80
  link_path_walk+0x150/0x344
  path_openat+0xa0/0x7dc
  do_filp_open+0xb8/0x168
  do_sys_openat2+0x88/0x17c
  __arm64_sys_openat+0x74/0xa0
  invoke_syscall+0x48/0x148
  el0_svc_common+0xb8/0xf8
  do_el0_svc+0x28/0x88
  el0_svc+0x24/0x84
  el0t_64_sync_handler+0x88/0xec
  el0t_64_sync+0x1b4/0x1b8
 Code: f8695a69 71007d1f 540000e0 927df12a (f940014a)

Fixes: 753b32368705 ("arm64: extable: add load_unaligned_zeropad() handler")
Cc: <stable at vger.kernel.org> # 5.16.x
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Signed-off-by: Evgenii Stepanov <eugenis at google.com>
---
 arch/arm64/mm/extable.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/extable.c b/arch/arm64/mm/extable.c
index c0181e60cc98..489455309695 100644
--- a/arch/arm64/mm/extable.c
+++ b/arch/arm64/mm/extable.c
@@ -40,8 +40,8 @@ static bool
 ex_handler_load_unaligned_zeropad(const struct exception_table_entry *ex,
 				  struct pt_regs *regs)
 {
-	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->type);
-	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->type);
+	int reg_data = FIELD_GET(EX_DATA_REG_DATA, ex->data);
+	int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data);
 	unsigned long data, addr, offset;
 
 	addr = pt_regs_read_reg(regs, reg_addr);
-- 
2.35.0.rc0.227.g00780c9af4-goog



From maz at kernel.org  Tue Jan 25 10:36:47 2022
From: maz at kernel.org (Marc Zyngier)
Date: Tue, 25 Jan 2022 18:36:47 +0000
Subject: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and
 PAC trap errata
In-Reply-To: <711e16a1-c853-10e8-43d5-31890f0d4c7c@arm.com>
References: <20220125153803.549084-1-james.morse@arm.com>
 <20220125153803.549084-5-james.morse@arm.com>
 <87mtjj7o7y.wl-maz@kernel.org>
 <711e16a1-c853-10e8-43d5-31890f0d4c7c@arm.com>
Message-ID: <87k0en7jcw.wl-maz@kernel.org>

On Tue, 25 Jan 2022 18:19:45 +0000,
James Morse <james.morse at arm.com> wrote:
> 
> Hi Marc,
> 
> On 25/01/2022 16:51, Marc Zyngier wrote:
> > On Tue, 25 Jan 2022 15:38:03 +0000,
> > James Morse <james.morse at arm.com> wrote:
> >>
> >> Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
> >> single-stepping authenticated ERET instructions. A single step is
> >> expected, but a pointer authentication trap is taken instead. The
> >> erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
> >> EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
> >>
> >> Because the conditions require an ERET into active-not-pending state,
> >> this is only a problem for the EL2 when EL2 is stepping EL1. In this case
> >> the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
> >> restored.
> 
> > Urgh. That's pretty nasty :-(.
> 
> >> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> >> index 331dd10821df..93bf140cc972 100644
> >> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> >> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> >> @@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
> >>  			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
> >>  	}
> >>  
> >> +	/*
> >> +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
> >> +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
> >> +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
> >> +	 * Did we just take a PAC exception when a step exception was expected?
> >> +	 */
> >> +	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&
> > 
> > nit: we can drop this IS_ENABLED()...
> 
> Hmmm, I thought dead code elimination was a good thing!
> Without the cpu_errata.c match, (which is also guarded by #ifdef),
> the cap will never be true, even if an affected CPU showed up. This
> way the compiler knows it can remove all this.

I don't dispute that. However, experience shows that the more of these
we sprinkle around, the quicker this code bitrots as we don't build
for all the possible configurations. In general, we hardly have any
dependency on configuration symbols, and rely on static keys got
things not be terribly sucky.

> 
> 
> >> +	    cpus_have_const_cap(ARM64_WORKAROUND_2077057) &&
> > 
> > and make this a final cap. Being a ARM64_CPUCAP_LOCAL_CPU_ERRATUM, we
> > won't accept late CPUs on a system that wasn't affected until then.
> > 
> >> +	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ &&
> >> +	    esr_ec == ESR_ELx_EC_PAC &&
> >> +	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP) {
> >> +		/* Active-not-pending? */
> >> +		if (*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
> >> +			write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> > 
> > Err... Isn't this way too late? The function starts with:
> > 
> > 	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
> > 
> > which is just another way to write:
> > 
> > 	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> > 
> > By that time, the vcpu's PSTATE is terminally corrupted.
> 
> Yes -  bother. Staring at it didn't let me spot that!
> I can hit the conditions to test this, but due to lack of
> imagination the model doesn't corrupt the SPSR.

Bad model. ;-)

> 
> 
> > I think you need to hoist this workaround way up, before we call into
> > early_exit_filter() as it will assume that the guest pstate is correct
> > (this is used by both pKVM and the NV code).
> > 
> > Something like this (untested):
> > 
> > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > index 93bf140cc972..a8a1502db237 100644
> > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
> > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
> > @@ -402,6 +402,26 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
> >  	return false;
> >  }
> >  
> > +static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu,
> > +					   u64 *exit_code)
> > +{
> > +	/*
> > +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
> > +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
> > +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
> > +	 * Did we just take a PAC exception when a step exception (being in the
> > +	 * Active-not-pending state) was expected?
> > +	 */
> > +	if (cpus_have_final_cap(ARM64_WORKAROUND_2077057)	&&
> > +	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ	&&
> 
> > +	    kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_PAC	&&
> 
> The vcpu's esr_el2 isn't yet set:
> | ESR_ELx_EC(read_sysreg_el2(SYS_ESR)) == ESR_ELx_EC_PAC

Ah, well spotted!

> 
> (and I'll shuffle the order so this is last as its an extra sysreg read)
> 
> 
> > +	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP		&&
> > +	    *vcpu_cpsr(vcpu) & DBG_SPSR_SS)
> > +		write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
> > +
> > +	*vcpu_cpsr(vcpu) = read_sysreg_el2(SYS_SPSR);
> > +}
> > +
> >  /*
> >   * Return true when we were able to fixup the guest exit and should return to
> >   * the guest, false when we should restore the host state and return to the
> > @@ -415,7 +435,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
> >  	 * Save PSTATE early so that we can evaluate the vcpu mode
> >  	 * early on.
> >  	 */
> > -	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
> > +	synchronize_vcpu_pstate(vcpu, exit_code);
> 
> Even better, that saves the noise from moving esr_ec around!

Yup, the patch becomes marginally smaller.

> 
> 
> > Other than that, I'm happy to take the series as a whole ASAP, if only
> > for the two pretty embarrassing bug fixes. If you can respin it
> > shortly and address the comments above, I'd like it into -rc2.
> 
> Will do. Shout if you strongly care about the IS_ENABLED().

I'd really like it gone. Otherwise, I'll never compile that code.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From bjorn.andersson at linaro.org  Tue Jan 25 10:47:35 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Tue, 25 Jan 2022 12:47:35 -0600
Subject: [GIT PULL 0/5] SoC changes for 5.17
In-Reply-To: <CAOesGMjArmB1J7KasjHZRTNXoZvtUXkTOQAyg5yd29qC8PeS9g@mail.gmail.com>
References: <CAK8P3a0RDZpLtWjMEU1QVWSjOoqRAH6QxQ+ZQnJc8LwaV7m+JQ@mail.gmail.com>
 <7e480da8-0d54-2d62-0a8e-184901c974b6@gmail.com>
 <ee2c92da-030c-b92f-0f41-1fdbbeed47c7@gmail.com>
 <CAOesGMgx99GJ3gQmdgauSs3aF8xr4FgcgsELRz4HSVXmujHJnQ@mail.gmail.com>
 <CAK8P3a3sBADt4Cu=LGbjHQpQ32O-BtFk1aQFwhL8Ar=M_gj6Xw@mail.gmail.com>
 <CAOesGMjArmB1J7KasjHZRTNXoZvtUXkTOQAyg5yd29qC8PeS9g@mail.gmail.com>
Message-ID: <CAOCOHw43DC5P0p0U+C57JHo1YCicWA37y+gbEMEuJwsZB0NC=Q@mail.gmail.com>

On Mon, Jan 10, 2022 at 12:34 PM Olof Johansson <olof at lixom.net> wrote:
>
> On Tue, Jan 4, 2022 at 5:40 PM Arnd Bergmann <arnd at kernel.org> wrote:
> >
> > On Tue, Jan 4, 2022 at 7:40 PM Olof Johansson <olof at lixom.net> wrote:
> > > On Tue, Jan 4, 2022 at 1:58 PM Florian Fainelli <f.fainelli at gmail.com> wrote:
> > > > On 12/24/21 9:11 AM, Florian Fainelli wrote:
> > > > >
> > > > > Should I resend or fix something in those? Thanks!
> > > >
> > > >
> > > > Arnd, Olof, do I need to resend the 3 pull requests mentioned above?
> > > > Thanks and happy new year.
> > >
> > > I'm about to make a pass of merges, likely tomorrow -- I had to get my
> > > Honeycomb working again since it hosts all the trees and mailboxes for
> > > me.
> > >
> > > No need to resend at this time.
> >
> > It's possible that I had accidentally merged them in the end but tagged
> > the branch without those merge commits, so have a look if it's in there.
>
> Yeah, it looks like there were a few merges not part of the pull
> request (Linus just merged them, so these showed up in
> regen-contents). I'll fold them into arm/late.
>

It seems these (at the last the qcom ones) didn't make it into v5.17-rc1?

Are you planning to pick up the qcom patches for v5.18 or should I
just carry them and include them as I send my next PR?

Regards,
Bjorn

> arm/defconfig
>         broadcom/defconfig [sign: Y Arnd Bergmann <arnd at arndb.de>]
>                 https://github.com/Broadcom/stblinux
> tags/arm-soc/for-5.17/defconfig
>         broadcom/defconfig64 [sign: Y Arnd Bergmann <arnd at arndb.de>]
>                 https://github.com/Broadcom/stblinux
> tags/arm-soc/for-5.17/defconfig-arm64
>         qcom/defconfig [sign: N ]
>
> git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux
> tags/qcom-arm64-defconfig-for-5.17
>         patch
>                 ARM: multi_v7_defconfig: Enable drivers for
> DragonBoard 410c [sign: N ]
>
>
> -Olof
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From nathan at kernel.org  Tue Jan 25 10:50:43 2022
From: nathan at kernel.org (Nathan Chancellor)
Date: Tue, 25 Jan 2022 11:50:43 -0700
Subject: [PATCH] ARM: stackprotector: prefer compiler for TLS based
 per-task protector
In-Reply-To: <20211021142516.1843042-1-ardb@kernel.org>
References: <20211021142516.1843042-1-ardb@kernel.org>
Message-ID: <YfBGg+zmIlHmTIm/@dev-arch.archlinux-ax161>

On Thu, Oct 21, 2021 at 04:25:16PM +0200, Ard Biesheuvel wrote:
> Currently, we implement the per-task stack protector for ARM using a GCC
> plugin, due to lack of native compiler support. However, work is
> underway to get this implemented in the compiler, which means we will be
> able to deprecate the GCC plugin at some point.
> 
> In the meantime, we will need to support both, where the native compiler
> implementation is obviously preferred. So let's wire this up in Kconfig
> and the Makefile.
> 
> Cc: Kees Cook <keescook at chromium.org>
> Cc: Nick Desaulniers <ndesaulniers at google.com>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

I see this patch in the KSPP tree as commit 151bbc8be85e ("ARM:
stackprotector: prefer compiler for TLS based per-task protector"),
which breaks booting aspeed_g5_defconfig in QEMU with clang-14. It seems
like this patch depends on Ard's patch "ARM: decompressor: disable stack
protector" [1]; applying that on top of next-20220125 allows me to boot
again.

This patch is still queued up in Russell's devel-stable branch as
commit f05eb1d24eb5 ("ARM: stackprotector: prefer compiler for TLS based
per-task protector") so perhaps this patch should be dropped from the
KSPP tree? I assume once Ard's recent fixes series [2] is applied to
devel-stable, it will be added back to for-next?

[1]: https://lore.kernel.org/r/20220124174744.1054712-9-ardb at kernel.org/
[2]: https://lore.kernel.org/r/20220125091453.1475246-1-ardb at kernel.org/

Cheers,
Nathan


From kuba at kernel.org  Tue Jan 25 10:53:03 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 10:53:03 -0800
Subject: [PATCH net-next 4/7] net: stmmac/xpcs: convert to pcs_validate()
In-Reply-To: <E1nCOs4-005LSp-HF@rmk-PC.armlinux.org.uk>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
 <E1nCOs4-005LSp-HF@rmk-PC.armlinux.org.uk>
Message-ID: <20220125105303.2025dfae@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Tue, 25 Jan 2022 16:40:40 +0000 Russell King (Oracle) wrote:
> stmmac explicitly calls the xpcs driver to validate the ethtool
> linkmodes. This is no longer necessary as phylink now supports
> validation through a PCS method. Convert both drivers to use this
> new mechanism.
> 
> Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Sign-offs got scrambled.

Transient warning from here to patch 6:

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:943:22: warning: unused variable 'priv' [-Wunused-variable]
        struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
                            ^


From ardb at kernel.org  Tue Jan 25 10:55:37 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Tue, 25 Jan 2022 19:55:37 +0100
Subject: [PATCH] ARM: stackprotector: prefer compiler for TLS based
 per-task protector
In-Reply-To: <YfBGg+zmIlHmTIm/@dev-arch.archlinux-ax161>
References: <20211021142516.1843042-1-ardb@kernel.org>
 <YfBGg+zmIlHmTIm/@dev-arch.archlinux-ax161>
Message-ID: <CAMj1kXFgcoWU2XnL-arTKoA0Sk2AoQVjZ-xVLryGR=fkS89FVA@mail.gmail.com>

On Tue, 25 Jan 2022 at 19:50, Nathan Chancellor <nathan at kernel.org> wrote:
>
> On Thu, Oct 21, 2021 at 04:25:16PM +0200, Ard Biesheuvel wrote:
> > Currently, we implement the per-task stack protector for ARM using a GCC
> > plugin, due to lack of native compiler support. However, work is
> > underway to get this implemented in the compiler, which means we will be
> > able to deprecate the GCC plugin at some point.
> >
> > In the meantime, we will need to support both, where the native compiler
> > implementation is obviously preferred. So let's wire this up in Kconfig
> > and the Makefile.
> >
> > Cc: Kees Cook <keescook at chromium.org>
> > Cc: Nick Desaulniers <ndesaulniers at google.com>
> > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
>
> I see this patch in the KSPP tree as commit 151bbc8be85e ("ARM:
> stackprotector: prefer compiler for TLS based per-task protector"),
> which breaks booting aspeed_g5_defconfig in QEMU with clang-14. It seems
> like this patch depends on Ard's patch "ARM: decompressor: disable stack
> protector" [1]; applying that on top of next-20220125 allows me to boot
> again.
>
> This patch is still queued up in Russell's devel-stable branch as
> commit f05eb1d24eb5 ("ARM: stackprotector: prefer compiler for TLS based
> per-task protector") so perhaps this patch should be dropped from the
> KSPP tree? I assume once Ard's recent fixes series [2] is applied to
> devel-stable, it will be added back to for-next?
>
> [1]: https://lore.kernel.org/r/20220124174744.1054712-9-ardb at kernel.org/
> [2]: https://lore.kernel.org/r/20220125091453.1475246-1-ardb at kernel.org/
>

Yeah. better drop it from KSPP.

The problem is that the compiler version of the per-task
stackprotector feature does not get disabled when building the
decompressor, which means it ends up dereferencing bogus TLS register
values.


From ezequiel at vanguardiasur.com.ar  Tue Jan 25 10:57:10 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 25 Jan 2022 15:57:10 -0300
Subject: [PATCH V4 01/11] arm64: dts: imx8mq-tqma8mq: Remove redundant
 vpu reference
In-Reply-To: <20220125171129.472775-2-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-2-aford173@gmail.com>
Message-ID: <YfBIBlK2LAvjftUE@eze-laptop>

On Tue, Jan 25, 2022 at 11:11:18AM -0600, Adam Ford wrote:
> The vpu is enabled by default, so there is no need to manually
> enable it.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> 

Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>

> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> index 8aedcddfeab8..38ffcd145b33 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> @@ -272,10 +272,6 @@ &usdhc1 {
>  	status = "okay";
>  };
>  
> -&vpu {
> -	status = "okay";
> -};
> -
>  /* Attention: wdog reset forcing POR needs baseboard support */
>  &wdog1 {
>  	status = "okay";
> -- 
> 2.32.0
> 


From ezequiel at vanguardiasur.com.ar  Tue Jan 25 11:04:38 2022
From: ezequiel at vanguardiasur.com.ar (Ezequiel Garcia)
Date: Tue, 25 Jan 2022 16:04:38 -0300
Subject: [PATCH V4 07/11] arm64: dts: imx8mq: Enable both G1 and G2 VPU's
 with vpu-blk-ctrl
In-Reply-To: <20220125171129.472775-8-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-8-aford173@gmail.com>
Message-ID: <YfBJxmgwLGbVqGba@eze-laptop>

On Tue, Jan 25, 2022 at 11:11:24AM -0600, Adam Ford wrote:
> With the Hantro G1 and G2 now setup to run independently, update
> the device tree to allow both to operate.  This requires the
> vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
> certain clock enabled to handle the gating of the G1 and G2
> fuses, the clock-parents and clock-rates for the various VPU's
> to be moved into the pgc_vpu because they cannot get re-parented
> once enabled, and the pgc_vpu is the highest in the chain.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reported-by: kernel test robot <lkp at intel.com>

It doesn't seem correct to have the Reported-by on this commit.

Thanks,
Ezequiel

> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index 2df2510d0118..549b2440f55d 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
>  					pgc_vpu: power-domain at 6 {
>  						#power-domain-cells = <0>;
>  						reg = <IMX8M_POWER_DOMAIN_VPU>;
> -						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> +						clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> +							 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +						assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> +								  <&clk IMX8MQ_CLK_VPU_G2>,
> +								  <&clk IMX8MQ_CLK_VPU_BUS>,
> +								  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> +						assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_VPU_PLL_OUT>,
> +									 <&clk IMX8MQ_SYS1_PLL_800M>,
> +									 <&clk IMX8MQ_VPU_PLL>;
> +						assigned-clock-rates = <600000000>,
> +								       <600000000>,
> +								       <800000000>,
> +								       <0>;
>  					};
>  
>  					pgc_disp: power-domain at 7 {
> @@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
>  			status = "disabled";
>  		};
>  
> -		vpu: video-codec at 38300000 {
> -			compatible = "nxp,imx8mq-vpu";
> -			reg = <0x38300000 0x10000>,
> -			      <0x38310000 0x10000>,
> -			      <0x38320000 0x10000>;
> -			reg-names = "g1", "g2", "ctrl";
> -			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> -				     <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> -			interrupt-names = "g1", "g2";
> +		vpu_g1: video-codec at 38300000 {
> +			compatible = "nxp,imx8mq-vpu-g1";
> +			reg = <0x38300000 0x10000>;
> +			interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> +		};
> +
> +		vpu_g2: video-codec at 38310000 {
> +			compatible = "nxp,imx8mq-vpu-g2";
> +			reg = <0x38310000 0x10000>;
> +			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> +			clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> +		};
> +
> +		vpu_blk_ctrl: blk-ctrl at 38320000 {
> +			compatible = "fsl,imx8mq-vpu-blk-ctrl";
> +			reg = <0x38320000 0x100>;
> +			power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
> +			power-domain-names = "bus", "g1", "g2";
>  			clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
> -				 <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> -			clock-names = "g1", "g2", "bus";
> -			assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> -					  <&clk IMX8MQ_CLK_VPU_G2>,
> -					  <&clk IMX8MQ_CLK_VPU_BUS>,
> -					  <&clk IMX8MQ_VPU_PLL_BYPASS>;
> -			assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_VPU_PLL_OUT>,
> -						 <&clk IMX8MQ_SYS1_PLL_800M>,
> -						 <&clk IMX8MQ_VPU_PLL>;
> -			assigned-clock-rates = <600000000>, <600000000>,
> -					       <800000000>, <0>;
> -			power-domains = <&pgc_vpu>;
> +				 <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> +			clock-names = "g1", "g2";
> +			#power-domain-cells = <1>;
>  		};
>  
>  		pcie0: pcie at 33800000 {
> -- 
> 2.32.0
> 


From aford173 at gmail.com  Tue Jan 25 11:08:28 2022
From: aford173 at gmail.com (Adam Ford)
Date: Tue, 25 Jan 2022 13:08:28 -0600
Subject: [PATCH V4 07/11] arm64: dts: imx8mq: Enable both G1 and G2 VPU's
 with vpu-blk-ctrl
In-Reply-To: <YfBJxmgwLGbVqGba@eze-laptop>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-8-aford173@gmail.com>
 <YfBJxmgwLGbVqGba@eze-laptop>
Message-ID: <CAHCN7xL-c4rXFW3cO4c0QmnqtaRpU_HfPb46UQFzPzb2RojChw@mail.gmail.com>

On Tue, Jan 25, 2022 at 1:04 PM Ezequiel Garcia
<ezequiel at vanguardiasur.com.ar> wrote:
>
> On Tue, Jan 25, 2022 at 11:11:24AM -0600, Adam Ford wrote:
> > With the Hantro G1 and G2 now setup to run independently, update
> > the device tree to allow both to operate.  This requires the
> > vpu-blk-ctrl node to be configured.  Since vpu-blk-ctrl needs
> > certain clock enabled to handle the gating of the G1 and G2
> > fuses, the clock-parents and clock-rates for the various VPU's
> > to be moved into the pgc_vpu because they cannot get re-parented
> > once enabled, and the pgc_vpu is the highest in the chain.
> >
> > Signed-off-by: Adam Ford <aford173 at gmail.com>
> > Reported-by: kernel test robot <lkp at intel.com>
>
> It doesn't seem correct to have the Reported-by on this commit.

I didn't put it here, because I fixed it in a whole different patch
(Patch 1/11).  This patch remains unchanged.  I probably should have
put in the other patch, but I didn't think it was essential.  Sorry
about that. Do I need to resend to just add the r-b tag?

adam

>
> Thanks,
> Ezequiel
>
> > Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
> >
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > index 2df2510d0118..549b2440f55d 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> > @@ -737,7 +737,21 @@ pgc_gpu: power-domain at 5 {
> >                                       pgc_vpu: power-domain at 6 {
> >                                               #power-domain-cells = <0>;
> >                                               reg = <IMX8M_POWER_DOMAIN_VPU>;
> > -                                             clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> > +                                             clocks = <&clk IMX8MQ_CLK_VPU_DEC_ROOT>,
> > +                                                      <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> > +                                                      <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> > +                                             assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> > +                                                               <&clk IMX8MQ_CLK_VPU_G2>,
> > +                                                               <&clk IMX8MQ_CLK_VPU_BUS>,
> > +                                                               <&clk IMX8MQ_VPU_PLL_BYPASS>;
> > +                                             assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> > +                                                                      <&clk IMX8MQ_VPU_PLL_OUT>,
> > +                                                                      <&clk IMX8MQ_SYS1_PLL_800M>,
> > +                                                                      <&clk IMX8MQ_VPU_PLL>;
> > +                                             assigned-clock-rates = <600000000>,
> > +                                                                    <600000000>,
> > +                                                                    <800000000>,
> > +                                                                    <0>;
> >                                       };
> >
> >                                       pgc_disp: power-domain at 7 {
> > @@ -1457,30 +1471,31 @@ usb3_phy1: usb-phy at 382f0040 {
> >                       status = "disabled";
> >               };
> >
> > -             vpu: video-codec at 38300000 {
> > -                     compatible = "nxp,imx8mq-vpu";
> > -                     reg = <0x38300000 0x10000>,
> > -                           <0x38310000 0x10000>,
> > -                           <0x38320000 0x10000>;
> > -                     reg-names = "g1", "g2", "ctrl";
> > -                     interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
> > -                                  <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > -                     interrupt-names = "g1", "g2";
> > +             vpu_g1: video-codec at 38300000 {
> > +                     compatible = "nxp,imx8mq-vpu-g1";
> > +                     reg = <0x38300000 0x10000>;
> > +                     interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>;
> > +                     power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G1>;
> > +             };
> > +
> > +             vpu_g2: video-codec at 38310000 {
> > +                     compatible = "nxp,imx8mq-vpu-g2";
> > +                     reg = <0x38310000 0x10000>;
> > +                     interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
> > +                     clocks = <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> > +                     power-domains = <&vpu_blk_ctrl IMX8MQ_VPUBLK_PD_G2>;
> > +             };
> > +
> > +             vpu_blk_ctrl: blk-ctrl at 38320000 {
> > +                     compatible = "fsl,imx8mq-vpu-blk-ctrl";
> > +                     reg = <0x38320000 0x100>;
> > +                     power-domains = <&pgc_vpu>, <&pgc_vpu>, <&pgc_vpu>;
> > +                     power-domain-names = "bus", "g1", "g2";
> >                       clocks = <&clk IMX8MQ_CLK_VPU_G1_ROOT>,
> > -                              <&clk IMX8MQ_CLK_VPU_G2_ROOT>,
> > -                              <&clk IMX8MQ_CLK_VPU_DEC_ROOT>;
> > -                     clock-names = "g1", "g2", "bus";
> > -                     assigned-clocks = <&clk IMX8MQ_CLK_VPU_G1>,
> > -                                       <&clk IMX8MQ_CLK_VPU_G2>,
> > -                                       <&clk IMX8MQ_CLK_VPU_BUS>,
> > -                                       <&clk IMX8MQ_VPU_PLL_BYPASS>;
> > -                     assigned-clock-parents = <&clk IMX8MQ_VPU_PLL_OUT>,
> > -                                              <&clk IMX8MQ_VPU_PLL_OUT>,
> > -                                              <&clk IMX8MQ_SYS1_PLL_800M>,
> > -                                              <&clk IMX8MQ_VPU_PLL>;
> > -                     assigned-clock-rates = <600000000>, <600000000>,
> > -                                            <800000000>, <0>;
> > -                     power-domains = <&pgc_vpu>;
> > +                              <&clk IMX8MQ_CLK_VPU_G2_ROOT>;
> > +                     clock-names = "g1", "g2";
> > +                     #power-domain-cells = <1>;
> >               };
> >
> >               pcie0: pcie at 33800000 {
> > --
> > 2.32.0
> >


From bot at kernelci.org  Tue Jan 25 11:12:16 2022
From: bot at kernelci.org (kernelci.org bot)
Date: Tue, 25 Jan 2022 11:12:16 -0800 (PST)
Subject: arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 1 error,
 1 warning (v5.17-rc1)
Message-ID: <61f04b90.1c69fb81.9ccc2.30f4@mx.google.com>

arm64/for-kernelci build: 2 builds: 1 failed, 1 passed, 1 error, 1 warning (v5.17-rc1)

Full Build Summary: https://kernelci.org/build/arm64/branch/for-kernelci/kernel/v5.17-rc1/

Tree: arm64
Branch: for-kernelci
Git Describe: v5.17-rc1
Git Commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
Git URL: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
Built: 1 unique architecture

Build Failure Detected:

arm64:
    allmodconfig: (gcc-10) FAIL

Errors and Warnings Detected:

arm64:
    allmodconfig (gcc-10): 1 error, 1 warning

Errors summary:

    1    drivers/pinctrl/pinctrl-thunderbay.c:815:8: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]

Warnings summary:

    1    cc1: all warnings being treated as errors

================================================================================

Detailed per-defconfig build reports:

--------------------------------------------------------------------------------
allmodconfig (arm64, gcc-10) ? FAIL, 1 error, 1 warning, 0 section mismatches

Errors:
    drivers/pinctrl/pinctrl-thunderbay.c:815:8: error: assignment discards ?const? qualifier from pointer target type [-Werror=discarded-qualifiers]

Warnings:
    cc1: all warnings being treated as errors

--------------------------------------------------------------------------------
defconfig (arm64, gcc-10) ? PASS, 0 errors, 0 warnings, 0 section mismatches

---
For more info write to <info at kernelci.org>


From ndesaulniers at google.com  Tue Jan 25 11:14:12 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 11:14:12 -0800
Subject: [PATCH 1/8] ARM: ftrace: ensure that ADR take Thumb bit into
 account
In-Reply-To: <20220125153656.1802079-2-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
 <20220125153656.1802079-2-ardb@kernel.org>
Message-ID: <CAKwvOdm1G2tb=Zjvak4RYH+vjpW7fS0is1kyegHpGcFX1t7QAA@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:37 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> Using ADR to take the address of 'ftrace_stub' via a local label
> produces an address that has the Thumb bit cleared, which means the
> subsequent comparison is guaranteed to fail. Instead, use the badr
> macro, which forces the Thumb bit to be set.
>
> Fixes: a3ba87a61499 ("ARM: 6316/1: ftrace: add Thumb-2 support")
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

> ---
>  arch/arm/kernel/entry-ftrace.S | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
> index a74289ebc803..f4886fb6e9ba 100644
> --- a/arch/arm/kernel/entry-ftrace.S
> +++ b/arch/arm/kernel/entry-ftrace.S
> @@ -40,7 +40,7 @@
>         mcount_enter
>         ldr     r0, =ftrace_trace_function
>         ldr     r2, [r0]
> -       adr     r0, .Lftrace_stub
> +       badr    r0, .Lftrace_stub
>         cmp     r0, r2
>         bne     1f
>
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers


From ndesaulniers at google.com  Tue Jan 25 11:23:05 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 11:23:05 -0800
Subject: [PATCH 2/8] ARM: ftrace: use ADD not POP to counter PUSH at entry
In-Reply-To: <20220125153656.1802079-3-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
 <20220125153656.1802079-3-ardb@kernel.org>
Message-ID: <CAKwvOd=88SKSz-UzO7EDycStNoHDdWHGCy2bAhZYmR6Ci9fCEg@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:37 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> The compiler emitted hook used for ftrace consists of a PUSH {LR} to
> preserve the link register, followed by a branch-and-link (BL) to
> __gnu_mount_nc. Dynamic ftrace patches away the latter to turn the
> combined sequence into a NOP, using a POP {LR} instruction.
>
> This is not necessary, since the link register does not get clobbered in
> this case, and simply adding #4 to the stack pointer is sufficient, and
> avoids a memory access that may take a few cycles to resolve depending
> on the micro-architecture.

Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm/kernel/entry-ftrace.S | 2 +-
>  arch/arm/kernel/ftrace.c       | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
> index f4886fb6e9ba..dca12a09322a 100644
> --- a/arch/arm/kernel/entry-ftrace.S
> +++ b/arch/arm/kernel/entry-ftrace.S
> @@ -27,7 +27,7 @@
>   * allows it to be clobbered in subroutines and doesn't use it to hold
>   * parameters.)
>   *
> - * When using dynamic ftrace, we patch out the mcount call by a "pop {lr}"
> + * When using dynamic ftrace, we patch out the mcount call by a "add sp, #4"
>   * instead of the __gnu_mcount_nc call (see arch/arm/kernel/ftrace.c).
>   */
>
> diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
> index a006585e1c09..db72d3a6522d 100644
> --- a/arch/arm/kernel/ftrace.c
> +++ b/arch/arm/kernel/ftrace.c
> @@ -25,9 +25,9 @@
>  #include <asm/patch.h>
>
>  #ifdef CONFIG_THUMB2_KERNEL
> -#define        NOP             0xf85deb04      /* pop.w {lr} */
> +#define        NOP             0xf10d0d04      /* add.w sp, sp, #4 */
>  #else
> -#define        NOP             0xe8bd4000      /* pop {lr} */
> +#define        NOP             0xe28dd004      /* add   sp, sp, #4 */
>  #endif
>
>  #ifdef CONFIG_DYNAMIC_FTRACE
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers


From broonie at kernel.org  Tue Jan 25 11:28:51 2022
From: broonie at kernel.org (Mark Brown)
Date: Tue, 25 Jan 2022 19:28:51 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a vgic-v3
Message-ID: <20220125192851.3907611-1-broonie@kernel.org>

The arch_timer and vgic_irq kselftests assume that they can create a
vgic-v3, using the library function vgic_v3_setup() which aborts with a
test failure if it is not possible to do so. Since vgic-v3 can only be
instantiated on systems where the host has GICv3 this leads to false
positives on older systems where that is not the case.

Fix this by changing vgic_v3_setup() to return an error if the vgic can't
be instantiated and have the callers skip if this happens. We could also
exit flagging a skip in vgic_v3_setup() but this would prevent future test
cases conditionally deciding which GIC to use or generally doing more
complex output.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
 tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 5 +++++
 tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index 9ad38bd360a4..791d38404652 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
 {
 	struct kvm_vm *vm;
 	unsigned int i;
+	int ret;
 	int nr_vcpus = test_args.nr_vcpus;
 
 	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
@@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
 
 	ucall_init(vm, NULL);
 	test_init_timer_irq(vm);
-	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	if (ret < 0) {
+		pr_info("Failed to create vgic-v3, skipping\n");
+		exit(KSFT_SKIP);
+	}
 
 	/* Make all the test's cmdline args visible to the guest */
 	sync_global_to_guest(vm, test_args);
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
index e6c7d7f8fbd1..8c6b61b8e6aa 100644
--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
@@ -761,6 +761,11 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
 
 	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
 			GICD_BASE_GPA, GICR_BASE_GPA);
+	if (gic_fd < 0) {
+		pr_info("Failed to create vgic-v3, skipping\n");
+		exit(KSFT_SKIP);
+	}
+
 
 	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
 		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
index b3a0fca0d780..647c18733e1b 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
@@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
 			nr_vcpus, nr_vcpus_created);
 
 	/* Distributor setup */
-	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
+	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
+	if (gic_fd == -1)
+		return -1;
 
 	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
 			0, &nr_irqs, true);
-- 
2.30.2



From robin.murphy at arm.com  Tue Jan 25 11:30:43 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Tue, 25 Jan 2022 19:30:43 +0000
Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
In-Reply-To: <9da65c2504b944398188e468eac1abff@huawei.com>
References: <20210805080724.480-1-shameerali.kolothum.thodi@huawei.com>
 <9da65c2504b944398188e468eac1abff@huawei.com>
Message-ID: <93374408-9522-8648-3417-0d8750d652bb@arm.com>

On 2022-01-25 13:00, Shameerali Kolothum Thodi wrote:
> Hi Robin/Lorenzo,
> 
>> -----Original Message-----
>> From: iommu [mailto:iommu-bounces at lists.linux-foundation.org] On Behalf
>> Of Shameer Kolothum
>> Sent: 05 August 2021 09:07
>> To: linux-arm-kernel at lists.infradead.org; linux-acpi at vger.kernel.org;
>> iommu at lists.linux-foundation.org
>> Cc: robin.murphy at arm.com; jon at solid-run.com; Linuxarm
>> <linuxarm at huawei.com>; steven.price at arm.com; Guohanjun (Hanjun Guo)
>> <guohanjun at huawei.com>; yangyicong <yangyicong at huawei.com>;
>> Sami.Mujawar at arm.com; will at kernel.org; wanghuiqiang
>> <wanghuiqiang at huawei.com>
>> Subject: [PATCH v7 0/9] ACPI/IORT: Support for IORT RMR node
>>
>> Hi,
>>
>> The series adds support to IORT RMR nodes specified in IORT
>> Revision E.b -ARM DEN 0049E[0]. RMR nodes are used to describe
>> memory ranges that are used by endpoints and require a unity
>> mapping in SMMU.
>>
>> We have faced issues with 3408iMR RAID controller cards which
>> fail to boot when SMMU is enabled. This is because these
>> controllers make use of host memory for various caching related
>> purposes and when SMMU is enabled the iMR firmware fails to
>> access these memory regions as there is no mapping for them.
>> IORT RMR provides a way for UEFI to describe and report these
>> memory regions so that the kernel can make a unity mapping for
>> these in SMMU.
>>
>> Change History:
>>
>> v6 --> v7
>>
>> The only change from v6 is the fix pointed out by Steve to
>> the SMMUv2 SMR bypass install in patch #8.
>>
>> Thanks to the Tested-by tags by Laurentiu with SMMUv2 and
>> Hanjun/Huiqiang with SMMUv3 for v6. I haven't added the tags
>> yet as the series still needs more review[1].
>>
>> Feedback and tests on this series is very much appreciated.
> 
> Since we have an update to IORT spec(E.c) now[1] and includes additional
> attributes/flags for the RMR node, I am planning to respin this series soon.
> 
> Going through the new spec, I have a few queries,
> 
> The memory range attributes can now be described as one of the following,
> 
> 0x00: Device-nGnRnE memory
> 0x01: Device-nGnRE memory
> 0x02: Device-nGRE memory
> 0x03: Device-GRE memory
> 0x04: Normal Inner Non-cacheable Outer Non-cacheable
> 0x05: Normal Inner Write-back Outer Write-back Inner Shareable
> 
> I am not sure how this needs to be captured and used in the kernel. Is there
> any intention of using these fine-grained attributes in the kernel now
> or a generic mapping of the above to the struct iommu_rev_region prot field
> is enough? i.e., something like,
> 
> {
>      ....
>      prot = IOMMU_READ | IOMMU_WRITE;
> 
>      if (rmr_attr == normal_mem) // 0x05
>          prot |= IOMMU_CACHE;
>      
>      if (rmr_attr == device_mem) { //0x00 - 0x03
>          prot |= IOMMU_MMIO;
>          prot |= IOMMU_NOEXEC;
>      }
>      ....
> }

Yup, pretty much that, except don't bother with IOMMU_NOEXEC. We can't 
reliably infer it - e.g. on an AXI-based interconnect AxCACHE and AxPROT 
are entirely orthogonal, so a Device-type read with the "Instruction 
access" hint is perfectly legal - and in the common IORT code we're not 
in a position to second-guess what any given RMR might represent for 
whatever agent is accessing it.

All we can reasonably do here is map the Device types to IOMMU_MMIO and 
Write-back to IOMMU_CACHE, and if anyone ever does want to insist that 
that's not sufficient, then they're welcome to send patches to make the 
IOMMU API more expressive :)

> Similarly for the 'flags' field, the new 'Access Privilege' is intended to set the
> IOMMU_PRIV ?

Yes, exactly!

Cheers,
Robin.

>    
> Please let me know.
> 
> Thanks,
> Shameer
> 
> [1] https://developer.arm.com/documentation/den0049/ec/?lang=en
> 


From alisaidi at amazon.com  Tue Jan 25 11:20:08 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Tue, 25 Jan 2022 19:20:08 +0000
Subject: [PATCH 0/2] Allow perf scripts to process SPE raw data
Message-ID: <20220125192016.20538-1-alisaidi@amazon.com>

These two changes first expose the arm_spe_record as raw data to the 
synthesized perf sample and second decode more of the operation and event
types that aren't used for existing perf tools into the arm_spe_record. 

This allows perf scripts to process the decoded SPE records instead of
parsing the raw-trace back into some type of structure.

Ali Saidi (2):
  perf arm-spe: Add arm_spe_record to synthesized sample as raw_data
  perf arm-spe: Parse more SPE fields

 .../util/arm-spe-decoder/arm-spe-decoder.c    | 23 +++++++++++++++++++
 .../util/arm-spe-decoder/arm-spe-decoder.h    |  9 ++++++++
 tools/perf/util/arm-spe.c                     |  6 +++++
 3 files changed, 38 insertions(+)

-- 
2.24.4.AMZN



From alisaidi at amazon.com  Tue Jan 25 11:20:09 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Tue, 25 Jan 2022 19:20:09 +0000
Subject: [PATCH 1/2] perf arm-spe: Add arm_spe_record to synthesized sample
In-Reply-To: <20220125192016.20538-1-alisaidi@amazon.com>
References: <20220125192016.20538-1-alisaidi@amazon.com>
Message-ID: <20220125192016.20538-2-alisaidi@amazon.com>

Providing the arm_spe_record as raw data to the synthesized SPE samples
allows perf scripts to read and separately process the data in ways
existing perf tools don't support and mirrors functionality available
for PEBS.

Signed-off-by: Ali Saidi <alisaidi at amazon.com>
---
 tools/perf/util/arm-spe.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
index d2b64e3f588b..a7499cde6fc0 100644
--- a/tools/perf/util/arm-spe.c
+++ b/tools/perf/util/arm-spe.c
@@ -336,6 +336,8 @@ static int arm_spe__synth_mem_sample(struct arm_spe_queue *speq,
 	sample.phys_addr = record->phys_addr;
 	sample.data_src = data_src;
 	sample.weight = record->latency;
+	sample.raw_size = sizeof(*record);
+	sample.raw_data = record;
 
 	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
 }
@@ -354,6 +356,8 @@ static int arm_spe__synth_branch_sample(struct arm_spe_queue *speq,
 	sample.stream_id = spe_events_id;
 	sample.addr = record->to_ip;
 	sample.weight = record->latency;
+	sample.raw_size = sizeof(*record);
+	sample.raw_data = record;
 
 	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
 }
@@ -383,6 +387,8 @@ static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq,
 	sample.data_src = data_src;
 	sample.period = spe->instructions_sample_period;
 	sample.weight = record->latency;
+	sample.raw_size = sizeof(*record);
+	sample.raw_data = record;
 
 	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
 }
-- 
2.24.4.AMZN



From alisaidi at amazon.com  Tue Jan 25 11:20:10 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Tue, 25 Jan 2022 19:20:10 +0000
Subject: [PATCH 2/2] perf arm-spe: Parse more SPE fields and store source
In-Reply-To: <20220125192016.20538-1-alisaidi@amazon.com>
References: <20220125192016.20538-1-alisaidi@amazon.com>
Message-ID: <20220125192016.20538-3-alisaidi@amazon.com>

Decode more SPE events and op types to allow for processing by perf
scripts. For example looking for branches which may indicate candidates
for conversion to a CSEL, store exclusives that are candidates for
conversion to LSE atomics and record the source information for memory
ops.

Signed-off-by: Ali Saidi <alisaidi at amazon.com>
---
 .../util/arm-spe-decoder/arm-spe-decoder.c     | 18 ++++++++++++++++++
 .../util/arm-spe-decoder/arm-spe-decoder.h     |  8 ++++++++
 2 files changed, 26 insertions(+)

diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
index 5e390a1a79ab..177bac0f7128 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
@@ -191,6 +191,20 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
 					decoder->record.op = ARM_SPE_ST;
 				else
 					decoder->record.op = ARM_SPE_LD;
+				if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
+					if (payload & SPE_OP_PKT_AT)
+						decoder->record.op |= ARM_SPE_LDST_ATOMIC;
+					if (payload & SPE_OP_PKT_EXCL)
+						decoder->record.op |= ARM_SPE_LDST_EXCL;
+					if (payload & SPE_OP_PKT_AR)
+						decoder->record.op |= ARM_SPE_LDST_ACQREL;
+				}
+			} else if (idx == SPE_OP_PKT_HDR_CLASS_BR_ERET) {
+				decoder->record.op = ARM_SPE_BR;
+				if (payload & SPE_OP_PKT_COND)
+					decoder->record.op |= ARM_SPE_BR_COND;
+				if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload))
+					decoder->record.op |= ARM_SPE_BR_IND;
 			}
 			break;
 		case ARM_SPE_EVENTS:
@@ -218,8 +232,12 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
 			if (payload & BIT(EV_MISPRED))
 				decoder->record.type |= ARM_SPE_BRANCH_MISS;
 
+			if (payload & BIT(EV_NOT_TAKEN))
+				decoder->record.type |= ARM_SPE_BR_NOT_TAKEN;
+
 			break;
 		case ARM_SPE_DATA_SOURCE:
+			decoder->record.source = payload;
 			break;
 		case ARM_SPE_BAD:
 			break;
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
index 69b31084d6be..113e427afe99 100644
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
@@ -22,11 +22,18 @@ enum arm_spe_sample_type {
 	ARM_SPE_TLB_MISS	= 1 << 5,
 	ARM_SPE_BRANCH_MISS	= 1 << 6,
 	ARM_SPE_REMOTE_ACCESS	= 1 << 7,
+	ARM_SPE_BR_NOT_TAKEN	= 1 << 8,
 };
 
 enum arm_spe_op_type {
 	ARM_SPE_LD		= 1 << 0,
 	ARM_SPE_ST		= 1 << 1,
+	ARM_SPE_LDST_EXCL	= 1 << 2,
+	ARM_SPE_LDST_ATOMIC	= 1 << 3,
+	ARM_SPE_LDST_ACQREL	= 1 << 4,
+	ARM_SPE_BR		= 1 << 5,
+	ARM_SPE_BR_COND		= 1 << 6,
+	ARM_SPE_BR_IND		= 1 << 7,
 };
 
 struct arm_spe_record {
@@ -40,6 +47,7 @@ struct arm_spe_record {
 	u64 virt_addr;
 	u64 phys_addr;
 	u64 context_id;
+	u16 source;
 };
 
 struct arm_spe_insn;
-- 
2.24.4.AMZN



From f.fainelli at gmail.com  Tue Jan 25 11:39:18 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:39:18 -0800
Subject: DTB backward/forward compatibility with "pinctrl: bcm2835: Change
 init order for gpio hogs"
Message-ID: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>

Hi,

I am a bit frustrated by this commit, we picked it up via the stable 
5.10 and 5.15 trees into our downstream tree, and in the absence of a 
suitable 'gpio-ranges' property for the GPIO controller, the SPI 
controller keeps getting -EPROBE_DEFER for its chip select. If the 
property is present, then all is well.

Now the problem in my case is that the boot loader is responsible for 
providing the DTB to the kernel, and until recently, we did not update 
it to contain a suitable 'gpio-ranges' property. Now that it has been 
updated however, older kernels which *do not* have said change in the 
subject are also getting -EPROBE_DEFER for the SPI chip select.

So this is just breaking backward/forward compatibility with the DTB 
unless both are updated in lock steps which is *extremely* inconvenient.

This is death by a thousand cuts.

So how do we remedy this?
-- 
Florian


From f.fainelli at gmail.com  Tue Jan 25 11:42:15 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:15 -0800
Subject: [PATCH stable 5.4 0/7] pinctrl-bcm2835 gpio-ranges bugfix
Message-ID: <20220125194222.12783-1-f.fainelli@gmail.com>

Hi all,

This patch series is intended to backport the fix from Phil "pinctrl:
bcm2835: Change init order for gpio hogs" into the 5.4 tree since the
blamed commit:

73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")

is in 5.4. To get there, I did backport a number of changes in order for
the commit "pinctrl: bcm2835: Change init order for gpio hogs" to apply
cleanly with no hunks.

Those should have no functional impact since we do not have support for
7211 or 2711 in the upstream stable 5.4.

Both the pinctrl *and* the DTS changes must be taken in lockstep
otherwise the GPIO pins are simply not usable unfortunately.

Thanks!

Florian Fainelli (2):
  pinctrl: bcm2835: Match BCM7211 compatible string
  pinctrl: bcm2835: Add support for wake-up interrupts

Phil Elwell (2):
  pinctrl: bcm2835: Change init order for gpio hogs
  ARM: dts: gpio-ranges property is now required

Stefan Wahren (3):
  pinctrl: bcm2835: Drop unused define
  pinctrl: bcm2835: Refactor platform data
  pinctrl: bcm2835: Add support for all GPIOs on BCM2711

 arch/arm/boot/dts/bcm283x.dtsi        |   1 +
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 209 +++++++++++++++++++++-----
 2 files changed, 175 insertions(+), 35 deletions(-)

-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:16 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:16 -0800
Subject: [PATCH stable 5.4 1/7] pinctrl: bcm2835: Drop unused define
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-2-f.fainelli@gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit be30d5de0a5a52c6ee2cc453a51301037ab94aa upstream

There is no usage for this define, so drop it.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1580148908-4863-2-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 0de1a3a96984..3fc26389a573 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -40,9 +40,6 @@
 #define BCM2835_NUM_BANKS 2
 #define BCM2835_NUM_IRQS  3
 
-#define BCM2835_PIN_BITMAP_SZ \
-	DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
-
 /* GPIO register offsets */
 #define GPFSEL0		0x0	/* Function Select */
 #define GPSET0		0x1c	/* Pin Output Set */
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:17 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:17 -0800
Subject: [PATCH stable 5.4 2/7] pinctrl: bcm2835: Refactor platform data
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-3-f.fainelli@gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit 90bfaf028d61a6d523c685b63c2bcc94eebb8057 upstream

This prepares the platform data to be easier to extend for more GPIOs.
Except of this there is no functional change.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1581166975-22949-3-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 57 +++++++++++++++++++++------
 1 file changed, 44 insertions(+), 13 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 3fc26389a573..7f0a9c647927 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -82,6 +82,7 @@ struct bcm2835_pinctrl {
 
 	struct pinctrl_dev *pctl_dev;
 	struct gpio_chip gpio_chip;
+	struct pinctrl_desc pctl_desc;
 	struct pinctrl_gpio_range gpio_range;
 
 	raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
@@ -1051,7 +1052,7 @@ static const struct pinconf_ops bcm2711_pinconf_ops = {
 	.pin_config_set = bcm2711_pinconf_set,
 };
 
-static struct pinctrl_desc bcm2835_pinctrl_desc = {
+static const struct pinctrl_desc bcm2835_pinctrl_desc = {
 	.name = MODULE_NAME,
 	.pins = bcm2835_gpio_pins,
 	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
@@ -1061,19 +1062,47 @@ static struct pinctrl_desc bcm2835_pinctrl_desc = {
 	.owner = THIS_MODULE,
 };
 
-static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
+static const struct pinctrl_desc bcm2711_pinctrl_desc = {
+	.name = MODULE_NAME,
+	.pins = bcm2835_gpio_pins,
+	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.pctlops = &bcm2835_pctl_ops,
+	.pmxops = &bcm2835_pmx_ops,
+	.confops = &bcm2711_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
 	.name = MODULE_NAME,
 	.npins = BCM2835_NUM_GPIOS,
 };
 
+struct bcm_plat_data {
+	const struct gpio_chip *gpio_chip;
+	const struct pinctrl_desc *pctl_desc;
+	const struct pinctrl_gpio_range *gpio_range;
+};
+
+static const struct bcm_plat_data bcm2835_plat_data = {
+	.gpio_chip = &bcm2835_gpio_chip,
+	.pctl_desc = &bcm2835_pinctrl_desc,
+	.gpio_range = &bcm2835_pinctrl_gpio_range,
+};
+
+static const struct bcm_plat_data bcm2711_plat_data = {
+	.gpio_chip = &bcm2835_gpio_chip,
+	.pctl_desc = &bcm2711_pinctrl_desc,
+	.gpio_range = &bcm2835_pinctrl_gpio_range,
+};
+
 static const struct of_device_id bcm2835_pinctrl_match[] = {
 	{
 		.compatible = "brcm,bcm2835-gpio",
-		.data = &bcm2835_pinconf_ops,
+		.data = &bcm2835_plat_data,
 	},
 	{
 		.compatible = "brcm,bcm2711-gpio",
-		.data = &bcm2711_pinconf_ops,
+		.data = &bcm2711_plat_data,
 	},
 	{}
 };
@@ -1082,6 +1111,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
+	const struct bcm_plat_data *pdata;
 	struct bcm2835_pinctrl *pc;
 	struct gpio_irq_chip *girq;
 	struct resource iomem;
@@ -1108,7 +1138,13 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	if (IS_ERR(pc->base))
 		return PTR_ERR(pc->base);
 
-	pc->gpio_chip = bcm2835_gpio_chip;
+	match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
+	if (!match)
+		return -EINVAL;
+
+	pdata = match->data;
+
+	pc->gpio_chip = *pdata->gpio_chip;
 	pc->gpio_chip.parent = dev;
 	pc->gpio_chip.of_node = np;
 
@@ -1159,19 +1195,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
-	if (match) {
-		bcm2835_pinctrl_desc.confops =
-			(const struct pinconf_ops *)match->data;
-	}
-
-	pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
+	pc->pctl_desc = *pdata->pctl_desc;
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
 	if (IS_ERR(pc->pctl_dev)) {
 		gpiochip_remove(&pc->gpio_chip);
 		return PTR_ERR(pc->pctl_dev);
 	}
 
-	pc->gpio_range = bcm2835_pinctrl_gpio_range;
+	pc->gpio_range = *pdata->gpio_range;
 	pc->gpio_range.base = pc->gpio_chip.base;
 	pc->gpio_range.gc = &pc->gpio_chip;
 	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:18 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:18 -0800
Subject: [PATCH stable 5.4 3/7] pinctrl: bcm2835: Add support for all GPIOs on
 BCM2711
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-4-f.fainelli@gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit b1d84a3d0a26c5844a22bc09a42704b9371208bb upstream

The BCM2711 supports 58 GPIOs. So extend pinctrl and GPIOs accordingly.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1581166975-22949-4-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 54 +++++++++++++++++++++------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 7f0a9c647927..061e70ed17a7 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -37,6 +37,7 @@
 
 #define MODULE_NAME "pinctrl-bcm2835"
 #define BCM2835_NUM_GPIOS 54
+#define BCM2711_NUM_GPIOS 58
 #define BCM2835_NUM_BANKS 2
 #define BCM2835_NUM_IRQS  3
 
@@ -78,7 +79,7 @@ struct bcm2835_pinctrl {
 
 	/* note: locking assumes each bank will have its own unsigned long */
 	unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
-	unsigned int irq_type[BCM2835_NUM_GPIOS];
+	unsigned int irq_type[BCM2711_NUM_GPIOS];
 
 	struct pinctrl_dev *pctl_dev;
 	struct gpio_chip gpio_chip;
@@ -145,6 +146,10 @@ static struct pinctrl_pin_desc bcm2835_gpio_pins[] = {
 	BCM2835_GPIO_PIN(51),
 	BCM2835_GPIO_PIN(52),
 	BCM2835_GPIO_PIN(53),
+	BCM2835_GPIO_PIN(54),
+	BCM2835_GPIO_PIN(55),
+	BCM2835_GPIO_PIN(56),
+	BCM2835_GPIO_PIN(57),
 };
 
 /* one pin per group */
@@ -203,6 +208,10 @@ static const char * const bcm2835_gpio_groups[] = {
 	"gpio51",
 	"gpio52",
 	"gpio53",
+	"gpio54",
+	"gpio55",
+	"gpio56",
+	"gpio57",
 };
 
 enum bcm2835_fsel {
@@ -353,6 +362,22 @@ static const struct gpio_chip bcm2835_gpio_chip = {
 	.can_sleep = false,
 };
 
+static const struct gpio_chip bcm2711_gpio_chip = {
+	.label = "pinctrl-bcm2711",
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.direction_input = bcm2835_gpio_direction_input,
+	.direction_output = bcm2835_gpio_direction_output,
+	.get_direction = bcm2835_gpio_get_direction,
+	.get = bcm2835_gpio_get,
+	.set = bcm2835_gpio_set,
+	.set_config = gpiochip_generic_config,
+	.base = -1,
+	.ngpio = BCM2711_NUM_GPIOS,
+	.can_sleep = false,
+};
+
 static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
 					 unsigned int bank, u32 mask)
 {
@@ -399,7 +424,7 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
 		bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
 		bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
 		break;
-	case 2: /* IRQ2 covers GPIOs 46-53 */
+	case 2: /* IRQ2 covers GPIOs 46-57 */
 		bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
 		break;
 	}
@@ -618,7 +643,7 @@ static struct irq_chip bcm2835_gpio_irq_chip = {
 
 static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(bcm2835_gpio_groups);
+	return BCM2835_NUM_GPIOS;
 }
 
 static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
@@ -776,7 +801,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev,
 		err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
 		if (err)
 			goto out;
-		if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) {
+		if (pin >= pc->pctl_desc.npins) {
 			dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
 				np, pin);
 			err = -EINVAL;
@@ -852,7 +877,7 @@ static int bcm2835_pmx_get_function_groups(struct pinctrl_dev *pctldev,
 {
 	/* every pin can do every function */
 	*groups = bcm2835_gpio_groups;
-	*num_groups = ARRAY_SIZE(bcm2835_gpio_groups);
+	*num_groups = BCM2835_NUM_GPIOS;
 
 	return 0;
 }
@@ -1055,7 +1080,7 @@ static const struct pinconf_ops bcm2711_pinconf_ops = {
 static const struct pinctrl_desc bcm2835_pinctrl_desc = {
 	.name = MODULE_NAME,
 	.pins = bcm2835_gpio_pins,
-	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.npins = BCM2835_NUM_GPIOS,
 	.pctlops = &bcm2835_pctl_ops,
 	.pmxops = &bcm2835_pmx_ops,
 	.confops = &bcm2835_pinconf_ops,
@@ -1063,9 +1088,9 @@ static const struct pinctrl_desc bcm2835_pinctrl_desc = {
 };
 
 static const struct pinctrl_desc bcm2711_pinctrl_desc = {
-	.name = MODULE_NAME,
+	.name = "pinctrl-bcm2711",
 	.pins = bcm2835_gpio_pins,
-	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.npins = BCM2711_NUM_GPIOS,
 	.pctlops = &bcm2835_pctl_ops,
 	.pmxops = &bcm2835_pmx_ops,
 	.confops = &bcm2711_pinconf_ops,
@@ -1077,6 +1102,11 @@ static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
 	.npins = BCM2835_NUM_GPIOS,
 };
 
+static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
+	.name = "pinctrl-bcm2711",
+	.npins = BCM2711_NUM_GPIOS,
+};
+
 struct bcm_plat_data {
 	const struct gpio_chip *gpio_chip;
 	const struct pinctrl_desc *pctl_desc;
@@ -1090,9 +1120,9 @@ static const struct bcm_plat_data bcm2835_plat_data = {
 };
 
 static const struct bcm_plat_data bcm2711_plat_data = {
-	.gpio_chip = &bcm2835_gpio_chip,
+	.gpio_chip = &bcm2711_gpio_chip,
 	.pctl_desc = &bcm2711_pinctrl_desc,
-	.gpio_range = &bcm2835_pinctrl_gpio_range,
+	.gpio_range = &bcm2711_pinctrl_gpio_range,
 };
 
 static const struct of_device_id bcm2835_pinctrl_match[] = {
@@ -1118,8 +1148,8 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	int err, i;
 	const struct of_device_id *match;
 
-	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
-	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
+	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
+	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
 
 	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
 	if (!pc)
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:19 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:19 -0800
Subject: [PATCH stable 5.4 4/7] pinctrl: bcm2835: Match BCM7211 compatible
 string
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-5-f.fainelli@gmail.com>

commit 562c856f96d22ef1204b0a314bc52e85617199b4 upstream

The BCM7211 SoC uses the same pinconf_ops as the ones defined for the
BCM2711 SoC, match the compatible string and use the correct set of
options.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20200531001101.24945-4-f.fainelli at gmail.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 061e70ed17a7..e763c680b9c2 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1134,6 +1134,10 @@ static const struct of_device_id bcm2835_pinctrl_match[] = {
 		.compatible = "brcm,bcm2711-gpio",
 		.data = &bcm2711_plat_data,
 	},
+	{
+		.compatible = "brcm,bcm7211-gpio",
+		.data = &bcm2711_plat_data,
+	},
 	{}
 };
 
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:20 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:20 -0800
Subject: [PATCH stable 5.4 5/7] pinctrl: bcm2835: Add support for wake-up
 interrupts
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-6-f.fainelli@gmail.com>

commit 920fecc1aa4591da27ef9dcb338fc5da86b404d7 upstream

Leverage the IRQCHIP_MASK_ON_SUSPEND flag in order to avoid having to
specifically treat the GPIO interrupts during suspend and resume, and
simply implement an irq_set_wake() callback that is responsible for
enabling the parent wake-up interrupt as a wake-up interrupt.

To avoid allocating unnecessary resources for other chips, the wake-up
interrupts are only initialized if we have a brcm,bcm7211-gpio
compatibility string.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20200531001101.24945-5-f.fainelli at gmail.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 76 ++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index e763c680b9c2..436184ebd2ef 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -19,6 +19,7 @@
 #include <linux/irq.h>
 #include <linux/irqdesc.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -76,6 +77,7 @@
 struct bcm2835_pinctrl {
 	struct device *dev;
 	void __iomem *base;
+	int *wake_irq;
 
 	/* note: locking assumes each bank will have its own unsigned long */
 	unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
@@ -432,6 +434,11 @@ static void bcm2835_gpio_irq_handler(struct irq_desc *desc)
 	chained_irq_exit(host_chip, desc);
 }
 
+static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
 static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
 	unsigned reg, unsigned offset, bool enable)
 {
@@ -631,6 +638,34 @@ static void bcm2835_gpio_irq_ack(struct irq_data *data)
 	bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
 }
 
+static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
+	unsigned gpio = irqd_to_hwirq(data);
+	unsigned int irqgroup;
+	int ret = -EINVAL;
+
+	if (!pc->wake_irq)
+		return ret;
+
+	if (gpio <= 27)
+		irqgroup = 0;
+	else if (gpio >= 28 && gpio <= 45)
+		irqgroup = 1;
+	else if (gpio >= 46 && gpio <= 57)
+		irqgroup = 2;
+	else
+		return ret;
+
+	if (on)
+		ret = enable_irq_wake(pc->wake_irq[irqgroup]);
+	else
+		ret = disable_irq_wake(pc->wake_irq[irqgroup]);
+
+	return ret;
+}
+
 static struct irq_chip bcm2835_gpio_irq_chip = {
 	.name = MODULE_NAME,
 	.irq_enable = bcm2835_gpio_irq_enable,
@@ -639,6 +674,8 @@ static struct irq_chip bcm2835_gpio_irq_chip = {
 	.irq_ack = bcm2835_gpio_irq_ack,
 	.irq_mask = bcm2835_gpio_irq_disable,
 	.irq_unmask = bcm2835_gpio_irq_enable,
+	.irq_set_wake = bcm2835_gpio_irq_set_wake,
+	.flags = IRQCHIP_MASK_ON_SUSPEND,
 };
 
 static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
@@ -1151,6 +1188,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	struct resource iomem;
 	int err, i;
 	const struct of_device_id *match;
+	int is_7211 = 0;
 
 	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
 	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
@@ -1177,6 +1215,7 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 		return -EINVAL;
 
 	pdata = match->data;
+	is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio");
 
 	pc->gpio_chip = *pdata->gpio_chip;
 	pc->gpio_chip.parent = dev;
@@ -1211,6 +1250,15 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 				     GFP_KERNEL);
 	if (!girq->parents)
 		return -ENOMEM;
+
+	if (is_7211) {
+		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
+					    sizeof(*pc->wake_irq),
+					    GFP_KERNEL);
+		if (!pc->wake_irq)
+			return -ENOMEM;
+	}
+
 	/*
 	 * Use the same handler for all groups: this is necessary
 	 * since we use one gpiochip to cover all lines - the
@@ -1218,8 +1266,34 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	 * bank that was firing the IRQ and look up the per-group
 	 * and bank data.
 	 */
-	for (i = 0; i < BCM2835_NUM_IRQS; i++)
+	for (i = 0; i < BCM2835_NUM_IRQS; i++) {
+		int len;
+		char *name;
+
 		girq->parents[i] = irq_of_parse_and_map(np, i);
+		if (!is_7211)
+			continue;
+
+		/* Skip over the all banks interrupts */
+		pc->wake_irq[i] = irq_of_parse_and_map(np, i +
+						       BCM2835_NUM_IRQS + 1);
+
+		len = strlen(dev_name(pc->dev)) + 16;
+		name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
+		if (!name)
+			return -ENOMEM;
+
+		snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
+
+		/* These are optional interrupts */
+		err = devm_request_irq(dev, pc->wake_irq[i],
+				       bcm2835_gpio_wake_irq_handler,
+				       IRQF_SHARED, name, pc);
+		if (err)
+			dev_warn(dev, "unable to request wake IRQ %d\n",
+				 pc->wake_irq[i]);
+	}
+
 	girq->default_type = IRQ_TYPE_NONE;
 	girq->handler = handle_level_irq;
 
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:21 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:21 -0800
Subject: [PATCH stable 5.4 6/7] pinctrl: bcm2835: Change init order for gpio
 hogs
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-7-f.fainelli@gmail.com>

From: Phil Elwell <phil at raspberrypi.com>

commit 266423e60ea1b953fcc0cd97f3dad85857e434d1 upstream

...and gpio-ranges

pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
side is registered first, but this breaks gpio hogs (which are
configured during gpiochip_add_data). Part of the hog initialisation
is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
yet been registered this results in an -EPROBE_DEFER from which it can
never recover.

Change the initialisation sequence to register the pinctrl driver
first.

This also solves a similar problem with the gpio-ranges property, which
is required in order for released pins to be returned to inputs.

Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
Signed-off-by: Phil Elwell <phil at raspberrypi.com>
Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20211206092237.4105895-2-phil at raspberrypi.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 29 +++++++++++++++------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index 436184ebd2ef..fa742535f679 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1241,6 +1241,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 		raw_spin_lock_init(&pc->irq_lock[i]);
 	}
 
+	pc->pctl_desc = *pdata->pctl_desc;
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+	if (IS_ERR(pc->pctl_dev)) {
+		gpiochip_remove(&pc->gpio_chip);
+		return PTR_ERR(pc->pctl_dev);
+	}
+
+	pc->gpio_range = *pdata->gpio_range;
+	pc->gpio_range.base = pc->gpio_chip.base;
+	pc->gpio_range.gc = &pc->gpio_chip;
+	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
 	girq = &pc->gpio_chip.irq;
 	girq->chip = &bcm2835_gpio_irq_chip;
 	girq->parent_handler = bcm2835_gpio_irq_handler;
@@ -1248,8 +1260,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
 				     sizeof(*girq->parents),
 				     GFP_KERNEL);
-	if (!girq->parents)
+	if (!girq->parents) {
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return -ENOMEM;
+	}
 
 	if (is_7211) {
 		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
@@ -1300,21 +1314,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	err = gpiochip_add_data(&pc->gpio_chip, pc);
 	if (err) {
 		dev_err(dev, "could not add GPIO chip\n");
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return err;
 	}
 
-	pc->pctl_desc = *pdata->pctl_desc;
-	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
-	if (IS_ERR(pc->pctl_dev)) {
-		gpiochip_remove(&pc->gpio_chip);
-		return PTR_ERR(pc->pctl_dev);
-	}
-
-	pc->gpio_range = *pdata->gpio_range;
-	pc->gpio_range.base = pc->gpio_chip.base;
-	pc->gpio_range.gc = &pc->gpio_chip;
-	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
-
 	return 0;
 }
 
-- 
2.25.1



From f.fainelli at gmail.com  Tue Jan 25 11:42:22 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:42:22 -0800
Subject: [PATCH stable 5.4 7/7] ARM: dts: gpio-ranges property is now required
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <20220125194222.12783-8-f.fainelli@gmail.com>

From: Phil Elwell <phil at raspberrypi.com>

commit c8013355ead68dce152cf426686f8a5f80d88b40 upstream

Since [1], added in 5.7, the absence of a gpio-ranges property has
prevented GPIOs from being restored to inputs when released.
Add those properties for BCM283x and BCM2711 devices.

[1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
    pin-ranges")

Link: https://lore.kernel.org/r/20220104170247.956760-1-linus.walleij at linaro.org
Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
Reported-by: Florian Fainelli <f.fainelli at gmail.com>
Reported-by: Jan Kiszka <jan.kiszka at web.de>
Signed-off-by: Phil Elwell <phil at raspberrypi.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Olof Johansson <olof at lixom.net>
[florian: Remove bcm2711.dtsi hunk which does not exist in 5.4]
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 arch/arm/boot/dts/bcm283x.dtsi | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi
index 50c64146d492..af81f386793c 100644
--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -183,6 +183,7 @@
 
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			gpio-ranges = <&gpio 0 0 54>;
 
 			/* Defines pin muxing groups according to
 			 * BCM2835-ARM-Peripherals.pdf page 102.
-- 
2.25.1



From skhan at linuxfoundation.org  Tue Jan 25 11:48:00 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Tue, 25 Jan 2022 12:48:00 -0700
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220125192851.3907611-1-broonie@kernel.org>
References: <20220125192851.3907611-1-broonie@kernel.org>
Message-ID: <a7215f00-2ffd-d3ec-eb02-e7fc8e527715@linuxfoundation.org>

On 1/25/22 12:28 PM, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>   tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>   tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 5 +++++
>   tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>   3 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 9ad38bd360a4..791d38404652 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
>   {
>   	struct kvm_vm *vm;
>   	unsigned int i;
> +	int ret;
>   	int nr_vcpus = test_args.nr_vcpus;
>   
>   	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
> @@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
>   
>   	ucall_init(vm, NULL);
>   	test_init_timer_irq(vm);
> -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (ret < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");
> +		exit(KSFT_SKIP);
> +	}
>   
>   	/* Make all the test's cmdline args visible to the guest */
>   	sync_global_to_guest(vm, test_args);
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> index e6c7d7f8fbd1..8c6b61b8e6aa 100644
> --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> @@ -761,6 +761,11 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
>   
>   	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
>   			GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (gic_fd < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");
> +		exit(KSFT_SKIP);
> +	}
> +
>   
>   	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
>   		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..647c18733e1b 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>   			nr_vcpus, nr_vcpus_created);
>   
>   	/* Distributor setup */
> -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);

Assume the flag change is intentional. The reason isn't obvious in the
change log
  
> +	if (gic_fd == -1)
> +		return -1;
>   
>   	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
>   			0, &nr_irqs, true);
> 

Looks good to me otherwise - thanks for adding the skips

Reviewed-by: Shuah Khan <skhan at linuxfoundation.org>

thanks,
-- Shuah


From phil at raspberrypi.com  Tue Jan 25 11:48:37 2022
From: phil at raspberrypi.com (Phil Elwell)
Date: Tue, 25 Jan 2022 19:48:37 +0000
Subject: DTB backward/forward compatibility with "pinctrl: bcm2835: Change
 init order for gpio hogs"
In-Reply-To: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>
References: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>
Message-ID: <c04d26a5-16e9-44a7-8b75-a04df9f7bfb6@raspberrypi.com>

Florian,

On 25/01/2022 19:39, Florian Fainelli wrote:
> Hi,
> 
> I am a bit frustrated by this commit, we picked it up via the stable 5.10 and 
> 5.15 trees into our downstream tree, and in the absence of a suitable 
> 'gpio-ranges' property for the GPIO controller, the SPI controller keeps getting 
> -EPROBE_DEFER for its chip select. If the property is present, then all is well.
> 
> Now the problem in my case is that the boot loader is responsible for providing 
> the DTB to the kernel, and until recently, we did not update it to contain a 
> suitable 'gpio-ranges' property. Now that it has been updated however, older 
> kernels which *do not* have said change in the subject are also getting 
> -EPROBE_DEFER for the SPI chip select.
> 
> So this is just breaking backward/forward compatibility with the DTB unless both 
> are updated in lock steps which is *extremely* inconvenient.
> 
> This is death by a thousand cuts.
> 
> So how do we remedy this?

It's unfortunate that both the DTS and driver were incorrect, and that the fixes 
were inter-dependent. At Raspberry Pi we make a point of treating the DTBs as 
part of the kernel, updating them at the same time. Is that not possible in your 
situation? You don't specify which bootloader you are using (or even which 
platform), but U-boot can be configured to use the DTB loaded and adjusted by 
the firmware.

Phil


From nick.hawkins at hpe.com  Tue Jan 25 11:46:00 2022
From: nick.hawkins at hpe.com (nick.hawkins at hpe.com)
Date: Tue, 25 Jan 2022 13:46:00 -0600
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is the
 first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
Message-ID: <20220125194609.32314-1-nick.hawkins@hpe.com>

From: Nick Hawkins <nick.hawkins at hpe.com>

Signed-off-by: Nick Hawkins <nick.hawkins at hpe.com>
---
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |   8 +
 arch/arm/Kconfig                              |   2 +
 arch/arm/boot/dts/gxp.dts                     | 700 ++++++++++++++++++
 arch/arm/configs/gxp_defconfig                | 243 ++++++
 arch/arm/mach-hpe/Kconfig                     |  20 +
 arch/arm/mach-hpe/Makefile                    |   1 +
 arch/arm/mach-hpe/gxp.c                       |  63 ++
 8 files changed, 1039 insertions(+)
 create mode 100644 arch/arm/boot/dts/gxp.dts
 create mode 100644 arch/arm/configs/gxp_defconfig
 create mode 100644 arch/arm/mach-hpe/Kconfig
 create mode 100644 arch/arm/mach-hpe/Makefile
 create mode 100644 arch/arm/mach-hpe/gxp.c

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 294093d45a23..e8b0ec874aed 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -515,6 +515,8 @@ patternProperties:
     description: Jiangsu HopeRun Software Co., Ltd.
   "^hp,.*":
     description: Hewlett Packard
+  "^hpe,.*":
+    description: Hewlett Packard Enterprise
   "^hsg,.*":
     description: HannStar Display Co.
   "^holtek,.*":
diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..007d99734dd1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8382,6 +8382,14 @@ L:	linux-efi at vger.kernel.org
 S:	Maintained
 F:	block/partitions/efi.*
 
+GXP ARCHITECTURE
+M:	Jean-Marie Verdun <verdun at hpe.com>
+M:	Nick Hawkins <nick.hawkins at hpe.com>
+S:	Maintained
+F:	arch/arm/boot/dts/gxp.dts
+F:	arch/arm/configs/gxp_defconfig
+F:	arch/arm/mach-hpe/gxp.c
+
 H8/300 ARCHITECTURE
 M:	Yoshinori Sato <ysato at users.sourceforge.jp>
 L:	uclinux-h8-devel at lists.sourceforge.jp (moderated for non-subscribers)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..d428d0d35889 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -708,6 +708,8 @@ source "arch/arm/mach-vt8500/Kconfig"
 
 source "arch/arm/mach-zynq/Kconfig"
 
+source "arch/arm/mach-hpe/Kconfig"
+
 # ARMv7-M architecture
 config ARCH_LPC18XX
 	bool "NXP LPC18xx/LPC43xx"
diff --git a/arch/arm/boot/dts/gxp.dts b/arch/arm/boot/dts/gxp.dts
new file mode 100644
index 000000000000..7bd814ecaaee
--- /dev/null
+++ b/arch/arm/boot/dts/gxp.dts
@@ -0,0 +1,700 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree file for HPE GXP
+ */
+
+/dts-v1/;
+/ {
+  #address-cells = <1>;
+  #size-cells = <1>;
+	compatible = "HPE,GXP";
+	model = "GXP";
+
+	chosen {
+		bootargs = "earlyprintk console=ttyS0,115200 user_debug=31";
+	};
+
+	aliases {
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0x40000000 0x20000000>;
+	};
+
+	ahb at 80000000 {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		vic0: vic at ceff0000 {
+			compatible = "arm,pl192-vic";
+			interrupt-controller;
+			reg = <0xceff0000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+
+		vic1: vic at 80f00000 {
+			compatible = "arm,pl192-vic";
+			interrupt-controller;
+			reg = <0x80f00000 0x1000>;
+			#interrupt-cells = <1>;
+		};
+
+		timer0: timer at c0000080 {
+			compatible = "hpe,gxp-timer";
+			reg = <0xc0000080 0x1>, <0xc0000094 0x01>, <0xc0000088 0x08>;
+			interrupts = <0>;
+			interrupt-parent = <&vic0>;
+			clock-frequency = <400000000>;
+		};
+
+		watchdog: watchdog at c0000090 {
+			compatible = "hpe,gxp-wdt";
+			reg = <0xc0000090 0x02>, <0xc0000096 0x01>;
+		};
+
+		uartc: serial at c00000f0 {
+			compatible = "ns16550a";
+			reg = <0xc00000f0 0x8>;
+			interrupts = <19>;
+			interrupt-parent = <&vic0>;
+			clock-frequency = <1846153>;
+			reg-shift = <0>;
+		};
+
+		uarta: serial at c00000e0 {
+			compatible = "ns16550a";
+			reg = <0xc00000e0 0x8>;
+			interrupts = <17>;
+			interrupt-parent = <&vic0>;
+			clock-frequency = <1846153>;
+			reg-shift = <0>;
+		};
+
+		uartb: serial at c00000e8 {
+			compatible = "ns16550a";
+			reg = <0xc00000e8 0x8>;
+			interrupts = <18>;
+			interrupt-parent = <&vic0>;
+			clock-frequency = <1846153>;
+			reg-shift = <0>;
+		};
+
+		vuart_a_cfg: vuarta_cfg at 80fc0230 {
+			compatible = "hpe,gxp-vuarta_cfg", "simple-mfd", "syscon";
+			reg = <0x80fc0230 0x100>;
+			reg-io-width = <1>;
+		};
+
+		vuart_a: vuart_a at 80fd0200 {
+			compatible = "hpe,gxp-vuart";
+			reg = <0x80fd0200 0x100>;
+			interrupts = <2>;
+			interrupt-parent = <&vic1>;
+			clock-frequency = <1846153>;
+			reg-shift = <0>;
+			status = "okay";
+			serial-line = <3>;
+			vuart_cfg = <&vuart_a_cfg>;
+		};
+
+		usb0: ehci at cefe0000 {
+			compatible = "generic-ehci";
+			reg = <0xcefe0000 0x100>;
+			interrupts = <7>;
+			interrupt-parent = <&vic0>;
+		};
+
+		usb1: ohci at cefe0100 {
+			compatible = "generic-ohci";
+			reg = <0xcefe0100 0x110>;
+			interrupts = <6>;
+			interrupt-parent = <&vic0>;
+		};
+
+		spifi0: spifi at c0000200 {
+			compatible = "hpe,gxp-spifi";
+			reg = <0xc0000200 0x80>, <0xc000c000 0x100>, <0xf8000000 0x8000000>;
+			interrupts = <20>;
+			interrupt-parent = <&vic0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			flash at 0 {
+				compatible = "jedec,spi-nor";
+				reg = <0>;
+				partitions {
+					compatible = "fixed-partitions";
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					bmc at 0 {
+						label = "bmc";
+						reg = <0x0 0x2000000>;
+					};
+					u-boot at 0 {
+						label = "u-boot";
+						reg = <0x0 0x60000>;
+					};
+					u-boot-env at 60000 {
+						label = "u-boot-env";
+						reg = <0x60000 0x20000>;
+					};
+					kernel at 80000 {
+						label = "kernel";
+						reg = <0x80000 0x4c0000>;
+					};
+					rofs at 540000 {
+						label = "rofs";
+						reg = <0x540000 0x1740000>;
+					};
+					rwfs at 1c80000 {
+						label = "rwfs";
+						reg = <0x1c80000 0x250000>;
+					};
+					section at 1edf000{
+						label = "section";
+						reg = <0x1ed0000 0x130000>;
+					};
+				};
+			};
+
+			flash at 1 {
+				compatible = "jedec,spi-nor";
+				reg = <1>;
+				partitions {
+					compatible = "fixed-partitions";
+					#address-cells = <1>;
+					#size-cells = <1>;
+					host-prime at 0 {
+						label = "host-prime";
+						reg = <0x0 0x02000000>;
+					};
+					host-second at 0 {
+						label = "host-second";
+						reg = <0x02000000 0x02000000>;
+					};
+				};
+			};
+		};
+
+		sram at d0000000 {
+			compatible = "mtd-ram";
+			reg = <0xd0000000 0x80000>;
+			bank-width = <1>;
+			erase-size =<1>;
+			partition at 0 {
+				label = "host-reserved";
+				reg = <0x0 0x10000>;
+			};
+			partition at 10000 {
+				label = "nvram";
+				reg = <0x10000 0x70000>;
+			};
+		};
+
+		srom at 80fc0000 {
+			compatible = "hpe,gxp-srom", "simple-mfd", "syscon";
+			reg = <0x80fc0000 0x100>;
+		};
+
+		vrom at 58000000 {
+			compatible = "mtd-ram";
+			bank-width = <4>;
+			reg = <0x58000000 0x4000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			partition at 0 {
+				label = "vrom-prime";
+				reg = <0x0 0x2000000>;
+			};
+			partition at 2000000 {
+				label = "vrom-second";
+				reg = <0x2000000 0x2000000>;
+			};
+		};
+
+		i2cg: i2cg at c00000f8 {
+			compatible = "syscon";
+			reg = <0xc00000f8 0x08>;
+		};
+
+		i2c0: i2c at c0002000 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002000 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c1: i2c at c0002100 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002100 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c2: i2c at c0002200 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002200 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			24c02 at 50 {
+				compatible = "atmel,24c02";
+				pagesize = <8>;
+				reg = <0x50>;
+			};
+		};
+
+		i2c3: i2c at c0002300 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002300 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c4: i2c at c0002400 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002400 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c5: i2c at c0002500 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002500 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+		};
+
+		i2c6: i2c at c0002600 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002600 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c7: i2c at c0002700 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002700 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			psu1: psu at 58 {
+				compatible = "hpe,gxp-psu";
+				reg = <0x58>;
+			};
+
+			psu2: psu at 59 {
+				compatible = "hpe,gxp-psu";
+				reg = <0x59>;
+			};
+		};
+
+		i2c8: i2c at c0002800 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002800 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2c9: i2c at c0002900 {
+			compatible = "hpe,gxp-i2c";
+			reg = <0xc0002900 0x70>;
+			interrupts = <9>;
+			interrupt-parent = <&vic0>;
+			i2cg-handle = <&i2cg>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		i2cmux at 4 {
+			compatible = "i2c-mux-reg";
+			i2c-parent = <&i2c4>;
+			reg = <0xd1000074 1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			i2c4 at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c4 at 3 {
+				reg = <3>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c4 at 4 {
+				reg = <4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		i2cmux at 6 {
+			compatible = "i2c-mux-reg";
+			i2c-parent = <&i2c6>;
+			reg = <0xd1000076 1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			i2c6 at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c6 at 2 {
+				reg = <2>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c6 at 3 {
+				reg = <3>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c6 at 4 {
+				reg = <4>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			i2c6 at 5 {
+				reg = <5>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+
+		mdio0: mdio at c0004080 {
+			compatible = "hpe,gxp-umac-mdio";
+			reg = <0xc0004080 0x10>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			ext_phy0: ethernt-phy at 0 {
+				compatible = "ethernet-phy-ieee802.3-c22";
+				phy-mode = "sgmii";
+				reg = <0>;
+			};
+		};
+
+		mdio1: mdio at c0005080 {
+			compatible = "hpe,gxp-umac-mdio";
+			reg = <0xc0005080 0x10>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			int_phy0: ethernt-phy at 0 {
+				compatible = "ethernet-phy-ieee802.3-c22";
+				phy-mode = "gmii";
+				reg = <0>;
+			};
+			int_phy1: ethernt-phy at 1 {
+				compatible = "ethernet-phy-ieee802.3-c22";
+				phy-mode = "gmii";
+				reg = <1>;
+			};
+		};
+
+		umac0: umac at c0004000 {
+			compatible = "hpe, gxp-umac";
+			reg = <0xc0004000 0x80>;
+			interrupts = <10>;
+			interrupt-parent = <&vic0>;
+			mac-address = [94 18 82 16 04 d8];
+			phy-handle = <&ext_phy0>;
+			int-phy-handle = <&int_phy0>;
+		};
+
+		umac1: umac at c0005000 {
+			compatible = "hpe, gxp-umac";
+			use-ncsi;
+			reg = <0xc0005000 0x80>;
+			interrupts = <11>;
+			interrupt-parent = <&vic0>;
+			mac-address = [94 18 82 16 04 d9];
+			phy-handle = <&int_phy1>;
+		};
+
+		kcs_conf: kcs_conf at 80fc0430 {
+			compatible = "hpe,gxp-kcs-bmc-cfg", "simple-mfd", "syscon";
+			reg = <0x80fc0430 0x100>;
+		};
+
+		kcs_reg: kcs_reg at 080fd0400 {
+			compatible = "hpe,gxp-kcs-bmc";
+			reg = <0x80fd0400 0x8>;
+			interrupts = <6>;
+			interrupt-parent = <&vic1>;
+			kcs_chan = <1>;
+			status = "okay";
+			kcs-bmc-cfg = <&kcs_conf>;
+		};
+
+		thumbnail: thumbnail at c0000500 {
+			compatible = "hpe,gxp-thumbnail";
+			reg = <0xc0000500 0x20>;
+			bits-per-pixel = <32>;
+			width = <800>;
+			height = <600>;
+		};
+
+		xreg: xreg at d1000000 {
+			compatible = "hpe,gxp-xreg", "simple-mfd", "syscon";
+			reg = <0xd1000000 0xFF>;
+			interrupts = <26>;
+			interrupt-parent = <&vic0>;
+			#gpio-cells = <2>;
+			gpio-line-names =
+			"", "", "", "", "", "", "POWER", "HEARTBEAT", "FAN1_INST", "FAN2_INST",
+			"FAN3_INST", "FAN4_INST", "FAN5_INST", "FAN6_INST", "FAN7_INST",
+			"FAN8_INST", "FAN9_INST", "FAN10_INST", "FAN11_INST", "FAN12_INST",
+			"FAN13_INST", "FAN14_INST", "FAN15_INST", "FAN16_INST", "FAN1_FAIL",
+			"FAN2_FAIL", "FAN3_FAIL", "FAN4_FAIL", "FAN5_FAIL", "FAN6_FAIL",
+			"FAN7_FAIL", "FAN8_FAIL", "FAN9_FAIL", "FAN10_FAIL", "FAN11_FAIL",
+			"FAN12_FAIL", "FAN13_FAIL", "FAN14_FAIL", "FAN15_FAIL", "FAN16_FAIL",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "IDENTIFY", "HEALTH_RED", "HEALTH_AMBER",
+			"POWER_BUTTON", "", "SIO_POWER_GOOD", "NMI_BUTTON", "RESET_BUTTON",
+			"SIO_S5", "SIO_ONCONTROL", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "";
+		};
+
+		fanctrl: fanctrl at c1000c00 {
+			compatible = "hpe,gxp-fan-ctrl";
+			reg = <0xc1000c00 0x200>;
+			xreg_handle = <&xreg>;
+			fn2_handle = <&fn2>;
+		};
+
+		fn2: fn2 at 80200000 {
+			compatible = "hpe,gxp-fn2", "simple-mfd", "syscon";
+			reg = <0x80200000 0x100000>;
+			xreg_handle = <&xreg>;
+			interrupts = <0>;
+			interrupt-parent = <&vic1>;
+			#gpio-cells = <2>;
+			gpio-line-names =
+			"POWER_OUT", "PS_PWROK", "PCIERST", "POST_COMPLETE", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "";
+			chif {
+				compatible = "hpe,gxp-chif";
+				interrupts = <12>;
+			};
+		};
+
+		csm: csm at 80000000 {
+			compatible = "hpe,gxp-csm", "simple-mfd", "syscon";
+			reg = <0x80000000 0x400>;
+		};
+
+		gpio: gpio at 0 {
+			compatible = "hpe,gxp-gpio";
+			#gpio-cells = <2>;
+			csm_handle = <&csm>;
+			vuhc0_handle = <&vuhc0>;
+			gpio-line-names =
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "RESET_OUT", "NMI_OUT", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "",
+			"", "", "", "", "", "", "", "", "", "";
+		};
+
+		leds: leds {
+			compatible = "gpio-leds";
+
+			power {
+				gpios = <&xreg 6 0>;
+				default-state = "off";
+			};
+
+			heartbeat {
+				gpios = <&xreg 7 0>;
+				default-state = "off";
+			};
+
+			identify {
+				gpios = <&xreg 56 0>;
+				default-state = "off";
+			};
+
+			health_red {
+				gpios = <&xreg 57 0>;
+				default-state = "off";
+			};
+
+			health_amber {
+				gpios = <&xreg 58 0>;
+				default-state = "off";
+			};
+		};
+
+		xreg_kyes: xreg_keys {
+			compatible = "gpio-keys-polled";
+			poll-interval = <100>;
+
+			IdButton {
+				label = "ID Button";
+				linux,code = <200>;
+				gpios = <&xreg 60 1>;
+			};
+		};
+
+		vuhc: vuhc {
+			compatible = "gpio-keys-polled";
+			poll-interval = <100>;
+
+			PortOwner at 0 {
+				label = "Port Owner";
+				linux,code = <200>;
+				gpios = <&gpio 250 1>;
+			};
+
+			PortOwner at 1 {
+				label = "Port Owner";
+				linux,code = <201>;
+				gpios = <&gpio 251 1>;
+			};
+		};
+
+		vuhc0: vuhc at 80400080 {
+			compatible = "syscon";
+			reg = <0x80400000 0x80>;
+		};
+
+		udcg: udcg at 80400800 {
+			compatible = "syscon";
+			reg = <0x80400800 0x200>;
+		};
+
+		udc0: udc at 80401000 {
+			compatible = "hpe, gxp-udc";
+			reg = <0x80401000 0x1000>;
+			interrupts = <13>;
+			interrupt-parent = <&vic1>;
+			vdevnum = <0>;
+			fepnum = <7>;
+			udcg-handle = <&udcg>;
+		};
+
+		udc1: udc at 80402000 {
+			compatible = "hpe, gxp-udc";
+			reg = <0x80402000 0x1000>;
+			interrupts = <13>;
+			interrupt-parent = <&vic1>;
+			vdevnum = <1>;
+			fepnum = <7>;
+			udcg-handle = <&udcg>;
+		};
+
+		coretemp: coretemp at c0000130 {
+			compatible = "hpe,gxp-coretemp";
+			reg = <0xc0000130 0x8>;
+		};
+
+		syspower: syspower {
+			compatible = "hpe,gxp-power";
+			psu_phandle = <&psu1>, <&psu2>;
+		};
+
+		peci: peci at 80000400 {
+			compatible = "hpe,gxp-peci";
+			reg = <0x80000400 0x200>;
+			interrupts = <22>;
+			interrupt-parent = <&vic1>;
+		};
+	};
+
+	clocks {
+		osc: osc {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-output-names = "osc";
+			clock-frequency = <33333333>;
+		};
+
+		iopclk: iopclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clocks = <&osc>;
+			clock-out-put-names = "iopclk";
+			clock-frequency = <400000000>;
+		};
+
+		memclk: memclk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clocks = <&osc>;
+			clock-out-put-names = "memclk";
+			clock-frequency = <800000000>;
+		};
+	};
+};
diff --git a/arch/arm/configs/gxp_defconfig b/arch/arm/configs/gxp_defconfig
new file mode 100644
index 000000000000..f37c6630e06d
--- /dev/null
+++ b/arch/arm/configs/gxp_defconfig
@@ -0,0 +1,243 @@
+CONFIG_KERNEL_XZ=y
+CONFIG_DEFAULT_HOSTNAME="gxp"
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_NAMESPACES=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+CONFIG_ARCH_MULTI_V6=y
+CONFIG_ARCH_HPE=y
+CONFIG_ARCH_HPE_GXP=y
+CONFIG_SECCOMP=y
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+# CONFIG_SUSPEND is not set
+CONFIG_JUMP_LABEL=y
+# CONFIG_STRICT_KERNEL_RWX is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_KSM=y
+CONFIG_CLEANCACHE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_INET=y
+CONFIG_VLAN_8021Q=y
+CONFIG_NETLINK_DIAG=y
+CONFIG_NET_NCSI=y
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_MTD=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_OF=y
+CONFIG_MTD_PLATRAM=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_GXP_SPIFI=y
+CONFIG_BLK_DEV_NULL_BLK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_AURORA is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CADENCE is not set
+# CONFIG_NET_VENDOR_CAVIUM is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_CORTINA is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_GOOGLE is not set
+# CONFIG_NET_VENDOR_HISILICON is not set
+# CONFIG_NET_VENDOR_HUAWEI is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_MICROSEMI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NI is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_SOCIONEXT is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_UMAC=y
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_LEDS is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_GPIO_POLLED=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIO_LIBPS2=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_RUNTIME_UARTS=6
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_GXP_VUART=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_TTY_PRINTK=y
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_DEVICE_INTERFACE=y
+CONFIG_IPMI_SI=y
+CONFIG_IPMI_SSIF=y
+CONFIG_HPE_KCS_IPMI_BMC=y
+CONFIG_HW_RANDOM_TIMERIOMEM=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GXP=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I2C_SLAVE_EEPROM=y
+CONFIG_SPI=y
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GXP=y
+CONFIG_SENSORS_EMC1403=y
+CONFIG_SENSORS_GXP_FAN_CTRL=y
+CONFIG_SENSORS_GXP_CORETEMP=y
+CONFIG_SENSORS_GXP_PSU=y
+CONFIG_SENSORS_GXP_POWER=y
+CONFIG_WATCHDOG=y
+CONFIG_GXP_WATCHDOG=y
+CONFIG_MFD_SYSCON=y
+CONFIG_FB=y
+CONFIG_FB_THUMBNAIL=y
+CONFIG_FB_SIMPLE=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GXP_UDC=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_HID=y
+CONFIG_USB_CONFIGFS_F_PRINTER=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_MTD=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_HPE_GXP_XREG=y
+CONFIG_HPE_GXP_FN2=y
+CONFIG_HPE_GXP_CSM=y
+CONFIG_HPE_GXP_SROM=y
+CONFIG_FANOTIFY=y
+CONFIG_OVERLAY_FS=y
+CONFIG_OVERLAY_FS_REDIRECT_DIR=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_JFFS2_FS=y
+# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+# CONFIG_JFFS2_FS_POSIX_ACL is not set
+# CONFIG_JFFS2_FS_SECURITY is not set
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_CRYPTO_CCM=y
+CONFIG_CRYPTO_GCM=y
+CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_ZSTD=y
+CONFIG_CRYPTO_USER_API_HASH=y
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC16=y
+# CONFIG_XZ_DEC_ARM is not set
+# CONFIG_XZ_DEC_ARMTHUMB is not set
+CONFIG_DMA_API_DEBUG=y
+CONFIG_PRINTK_TIME=y
+CONFIG_BOOT_PRINTK_DELAY=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_FUNCTION_PROFILER=y
+CONFIG_STACK_TRACER=y
+CONFIG_SCHED_TRACER=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
+CONFIG_DEBUG_UART_PHYS=0xC00000F0
+CONFIG_DEBUG_UART_VIRT=0xF00000F0
+CONFIG_DEBUG_UART_8250_SHIFT=0
+CONFIG_EARLY_PRINTK=y
+CONFIG_TEST_KSTRTOX=y
diff --git a/arch/arm/mach-hpe/Kconfig b/arch/arm/mach-hpe/Kconfig
new file mode 100644
index 000000000000..9b27f97c6536
--- /dev/null
+++ b/arch/arm/mach-hpe/Kconfig
@@ -0,0 +1,20 @@
+menuconfig ARCH_HPE
+	bool "HPE SoC support"
+	help
+	  This enables support for HPE ARM based SoC chips
+if ARCH_HPE
+
+config ARCH_HPE_GXP
+	bool "HPE GXP SoC"
+	select ARM_VIC
+	select PINCTRL
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_CHIP
+	select MULTI_IRQ_HANDLER
+	select SPARSE_IRQ
+	select CLKSRC_MMIO
+	depends on ARCH_MULTI_V7
+	help
+	  Support for GXP SoCs
+
+endif
diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
new file mode 100644
index 000000000000..8b0a91234df4
--- /dev/null
+++ b/arch/arm/mach-hpe/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
new file mode 100644
index 000000000000..b58f25fbae5a
--- /dev/null
+++ b/arch/arm/mach-hpe/gxp.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/init.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+#define IOP_REGS_PHYS_BASE 0xc0000000
+#define IOP_REGS_VIRT_BASE 0xf0000000
+#define IOP_REGS_SIZE (240*SZ_1M)
+
+#define IOP_EHCI_USBCMD 0x0efe0010
+
+static struct map_desc gxp_io_desc[] __initdata = {
+	{
+	.virtual	= (unsigned long)IOP_REGS_VIRT_BASE,
+	.pfn		= __phys_to_pfn(IOP_REGS_PHYS_BASE),
+	.length		= IOP_REGS_SIZE,
+	.type		= MT_DEVICE,
+	},
+};
+
+void __init gxp_map_io(void)
+{
+	iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
+}
+
+static void __init gxp_dt_init(void)
+{
+	//reset EHCI host controller for clear start
+	__raw_writel(0x00080002,
+		(void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));
+	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+}
+
+static void gxp_restart(enum reboot_mode mode, const char *cmd)
+{
+	pr_info("gpx restart");
+	__raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
+}
+
+static const char * const gxp_board_dt_compat[] = {
+	"HPE,GXP",
+	NULL,
+};
+
+DT_MACHINE_START(GXP_DT, "HPE GXP")
+	.init_machine	= gxp_dt_init,
+	.map_io		= gxp_map_io,
+	.restart	= gxp_restart,
+	.dt_compat	= gxp_board_dt_compat,
+MACHINE_END
-- 
2.17.1



From f.fainelli at gmail.com  Tue Jan 25 11:58:33 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 11:58:33 -0800
Subject: DTB backward/forward compatibility with "pinctrl: bcm2835: Change
 init order for gpio hogs"
In-Reply-To: <c04d26a5-16e9-44a7-8b75-a04df9f7bfb6@raspberrypi.com>
References: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>
 <c04d26a5-16e9-44a7-8b75-a04df9f7bfb6@raspberrypi.com>
Message-ID: <63cecd52-6808-d31e-3eb6-a17e692a4190@gmail.com>



On 1/25/2022 11:48 AM, Phil Elwell wrote:
> Florian,
> 
> On 25/01/2022 19:39, Florian Fainelli wrote:
>> Hi,
>>
>> I am a bit frustrated by this commit, we picked it up via the stable 
>> 5.10 and 5.15 trees into our downstream tree, and in the absence of a 
>> suitable 'gpio-ranges' property for the GPIO controller, the SPI 
>> controller keeps getting -EPROBE_DEFER for its chip select. If the 
>> property is present, then all is well.
>>
>> Now the problem in my case is that the boot loader is responsible for 
>> providing the DTB to the kernel, and until recently, we did not update 
>> it to contain a suitable 'gpio-ranges' property. Now that it has been 
>> updated however, older kernels which *do not* have said change in the 
>> subject are also getting -EPROBE_DEFER for the SPI chip select.
>>
>> So this is just breaking backward/forward compatibility with the DTB 
>> unless both are updated in lock steps which is *extremely* inconvenient.
>>
>> This is death by a thousand cuts.
>>
>> So how do we remedy this?
> 
> It's unfortunate that both the DTS and driver were incorrect, and that 
> the fixes were inter-dependent. At Raspberry Pi we make a point of 
> treating the DTBs as part of the kernel, updating them at the same time. 
> Is that not possible in your situation? You don't specify which 
> bootloader you are using (or even which platform), but U-boot can be 
> configured to use the DTB loaded and adjusted by the firmware.

We use a boot loader called BOLT which has an offline DTS generation 
part an a runtime patching part. At no point in time has it been 
necessary, desirable or even reliably possible to look at the kernel 
version and mangle the Device Tree such that "things" work. I do not 
even want to fathom what the code doing that would look like other than 
a big pile of mess. This is utterly error prone and completely breaks 
the boot loader/kernel abstraction.

We strive to be able to update the boot loader and the kernel seemingly 
independently from one another even though obviously there are times 
where locksteps are necessary. What I like to do is:

- put the changes in the DTB that are necessary for a *future* kernel 
well in advance such that by the time that newer kernel gets used these 
properties are already there

- adding new properties does not break older kernels, they simply ignore 
them

And this allows us to define a combination that always works while 
having a sliding window of backward/forward compatibility if we have 
locksteps in between.

I can make changes in the downstream kernel such that we prune DT 
properties, but once we open that door, the list goes on and on and it 
is just a damage control strategy anyway.

Why cannot the pinctrl framework infer that we have a 1:1 mapping in the 
absence of a 'gpio-ranges' property, but instead does the following:

# cat /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
GPIO ranges handled:
0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
#

clearly it determined the end GPIO but it is not able to determine the 
start GPIO?

And now, on a 5.10 kernel which does contain both the 'gpio-ranges' 
property and the said change to pinctrl-bcm2835.c I have this:

# cat /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
GPIO ranges handled:
0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
0: pinctrl-bcm2711 GPIOS [454 - 511] PINS [0 - 57]
#

What the heck?
-- 
Florian


From ndesaulniers at google.com  Tue Jan 25 12:20:10 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 12:20:10 -0800
Subject: [PATCH 3/8] ARM: ftrace: use trampolines to keep .init.text in
 branching range
In-Reply-To: <20220125153656.1802079-4-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
 <20220125153656.1802079-4-ardb@kernel.org>
Message-ID: <CAKwvOdm=1qi7Hs1r-g6jGeRdisRTb=Fvij5-C0gsSAMZMQW=gg@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:37 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> Kernel images that are large in comparison to the range of a direct
> branch may fail to work as expected with ftrace, as patching a direct
> branch to one of the core ftrace routines may not be possible from the
> .init.text section, if it is emitted too far away from the normal .text
> section.
>
> This is more likely to affect Thumb2 builds, given that its range is
> only -/+ 16 MiB (as opposed to ARM which has -/+ 32 MiB), but may occur
> in either ISA.
>
> To work around this, add a couple of trampolines to .init.text and
> swap these in when the ftrace patching code is operating on callers in
> .init.text.
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm/kernel/entry-ftrace.S | 16 ++++++++++++++++
>  arch/arm/kernel/ftrace.c       | 19 +++++++++++++++++--
>  2 files changed, 33 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
> index dca12a09322a..237d435e29aa 100644
> --- a/arch/arm/kernel/entry-ftrace.S
> +++ b/arch/arm/kernel/entry-ftrace.S
> @@ -270,3 +270,19 @@ ENTRY(ftrace_stub)
>  .Lftrace_stub:
>         ret     lr
>  ENDPROC(ftrace_stub)
> +
> +#ifdef CONFIG_DYNAMIC_FTRACE
> +
> +       __INIT
> +
> +       .macro  init_tramp, dst:req
> +ENTRY(\dst\()_from_init)
> +       ldr     pc, =\dst
> +ENDPROC(\dst\()_from_init)
> +       .endm
> +
> +       init_tramp      ftrace_caller
> +#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
> +       init_tramp      ftrace_regs_caller
> +#endif

Consider adding __FINIT here; while it's not necessary now, folks who
append new code to this file might be surprised to find new code in
.init.text.  I would also tighten up the __INIT/__FINIT to only
surround the invocations of init_tramp and not the macro definition
itself.

Either way,
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

> +#endif
> diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
> index db72d3a6522d..d2326794fd09 100644
> --- a/arch/arm/kernel/ftrace.c
> +++ b/arch/arm/kernel/ftrace.c
> @@ -51,9 +51,18 @@ static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
>         return NOP;
>  }
>
> +void ftrace_caller_from_init(void);
> +void ftrace_regs_caller_from_init(void);
> +
>  static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
>  {
> -       return addr;
> +       if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE) ||
> +           likely(!is_kernel_inittext(rec->ip)))
> +               return addr;
> +       if (!IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_REGS) ||
> +           addr == (unsigned long)&ftrace_caller)
> +               return (unsigned long)&ftrace_caller_from_init;
> +       return (unsigned long)&ftrace_regs_caller_from_init;
>  }
>
>  int ftrace_arch_code_modify_prepare(void)
> @@ -189,7 +198,13 @@ int ftrace_make_nop(struct module *mod,
>  #endif
>
>         new = ftrace_nop_replace(rec);
> -       ret = ftrace_modify_code(ip, old, new, true);
> +       /*
> +        * Locations in .init.text may call __gnu_mcount_mc via a linker
> +        * emitted veneer if they are too far away from its implementation, and
> +        * so validation may fail spuriously in such cases. Let's work around
> +        * this by omitting those from validation.
> +        */
> +       ret = ftrace_modify_code(ip, old, new, !is_kernel_inittext(ip));
>
>         return ret;
>  }
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers


From nicolas at ndufresne.ca  Tue Jan 25 12:23:44 2022
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Tue, 25 Jan 2022 15:23:44 -0500
Subject: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
 skip
In-Reply-To: <AM6PR04MB63414D140EC922139260A8B4E75F9@AM6PR04MB6341.eurprd04.prod.outlook.com>
References: <cover.1631002447.git.ming.qian@nxp.com>
 <647f84c1e7c2a48d6492d38fa4f06586235500b8.1631002447.git.ming.qian@nxp.com>
 <fffd24d3374ecb2fbfafa9b85fa0ef8012fc7efa.camel@ndufresne.ca>
 <AM6PR04MB634124118288EC775F05AFC3E7D59@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <8984f8a3c0dfd3a5f83fb5cc7b0357dca4787274.camel@ndufresne.ca>
 <AM6PR04MB63417E126287421BCA133514E7539@AM6PR04MB6341.eurprd04.prod.outlook.com>
 <a90c49239b86d8212045b1f2ef591c4bbf3cb8fd.camel@ndufresne.ca>
 <AM6PR04MB63414D140EC922139260A8B4E75F9@AM6PR04MB6341.eurprd04.prod.outlook.com>
Message-ID: <9c3c6cda32480416273b10f0ddbff4332e8f25f6.camel@ndufresne.ca>

Le mardi 25 janvier 2022 ? 01:54 +0000, Ming Qian a ?crit?:
> > -----Original Message-----
> > From: Nicolas Dufresne [mailto:nicolas at ndufresne.ca]
> > Sent: Saturday, January 22, 2022 6:25 AM
> > To: Ming Qian <ming.qian at nxp.com>; mchehab at kernel.org;
> > shawnguo at kernel.org; robh+dt at kernel.org; s.hauer at pengutronix.de
> > Cc: hverkuil-cisco at xs4all.nl; kernel at pengutronix.de; festevam at gmail.com;
> > dl-linux-imx <linux-imx at nxp.com>; linux-media at vger.kernel.org;
> > linux-kernel at vger.kernel.org; devicetree at vger.kernel.org;
> > linux-arm-kernel at lists.infradead.org
> > Subject: Re: [EXT] Re: [PATCH v8 04/15] media:Add v4l2 event codec_error and
> > skip
> > 
> > Caution: EXT Email
> > 
> > Le jeudi 13 janvier 2022 ? 07:18 +0000, Ming Qian a ?crit :
> > > Hi Nicolas,
> > > 
> > > ???I have question about skip event or similar concepts.
> > > If the client control the input frame count, and it won't queue any more
> > frames unless some frame is decoded.
> > > But after seek, There is no requirement to begin queuing coded data
> > > starting
> > exactly from a resume point (e.g. SPS or a keyframe). Any queued OUTPUT
> > buffers will be processed and returned to the client until a suitable resume
> > point is found. While looking for a resume point, the decoder should not
> > produce any decoded frames into CAPTURE buffers.
> > > 
> > > So client may have queued some frames but without any resume point, in
> > this case the decoder won't produce any decoded frames into CAPTURE buffers,
> > and the client won't queue frames into output buffers. This creates some
> > kind
> > of deadlock.
> > > 
> > > In our previous solution, we send skip event to client to tell it that
> > > some
> > frame is skipped instead of decoded, then the client can continue to queue
> > frames.
> > > But the skip event is flawed, so we need some solution to resolve it.
> > > 1. decoder can produce an empty buffer with V4L2_BUF_FLAG_SKIPPED (or
> > V4L2_BUF_FLAG_ERROR) as you advised, but this seems to conflict with the
> > above description in specification.
> > > 2. Define a notification mechanism to notify the client
> > > 
> > > Can you give some advice?  This constraint of frame depth is common on
> > > android
> > 
> > Without going against the spec, you can as of today pop a capture buffer and
> > mark it done with error. As it has nothing valid in it, I would also set the
> > payload size to 0.
> > 
> > So I'd say, for every unique input timestamp, that didn't yield a frame
> > (skipped),
> > pop a capture buffer, copy the timestamp, set the payload size to 0 and set
> > it
> > as done with error.
> > 
> > I'm not sure though if we that we can specify this, as I'm not sure this is
> > possible with all the existing HW. I must admit, I don't myself had to deal
> > with
> > that issue as I'm not using a dummy framework. In GStreamer, we take care of
> > locating the next sync point. So unless there was an error in the framework,
> > this case does not exist for us.
> > 
> Hi Nicolas,
> ????If the decoder can detect the output buffer that may trigger a error, is
> it better setting error flag on the output buffer, but without producing an
> empty capture buffer with error flag set?, or we should return both output and
> capture buffer with error flag set?
> ????As I can see the following description in spec:
> 
> if the decoder is able to precisely report the OUTPUT buffer that triggered
> the error, such buffer will be returned with the V4L2_BUF_FLAG_ERROR flag set.

Interesting, I never noticed this one. I suppose this would mean some early
notification of decode error. I have always assumed that for m2m, the flags
after DQBUF had no meaning, considering we are just getting back an empty
buffer. I do see possible enhancement of error handling if that was to be
implemented.

For more context, if a reordered frame failed, we will only know after we had
notice failures / errors on dependent frame that are earlier in display order.
Such mechanism would tell us earlier. I wonder if it could not also be earlier
still when no reordering take place ? In general, the main goal with such
mechanism is to request a new keyframe (typically in WebRTC / RTP use cases).

To answer you question, the spec says "if the decoder is able", which looks like
a MAY in specification terminology. So if you don't also produce a capture
buffer for the error, I would be worried existing userland will not notice and
keep waiting for the lost frame. Adding Alexandre Courbot in CC, he may have
more context around this, and perhaps Chromium is using that.

> 
> 
> > > 
> > > Ming
> > > 
> > > > > > > +    * - ``V4L2_EVENT_SKIP``
> > > > > > > +      - 8
> > > > > > > +      - This event is triggered when one frame is decoded,
> > > > > > > + but it won't
> > > > > > > be
> > > > > > outputed
> > > > > > > +     to the display. So the application can't get this frame,
> > > > > > > + and the
> > > > > > > input
> > > > > > frame count
> > > > > > > +     is dismatch with the output frame count. And this evevt
> > > > > > > + is telling
> > > > > > > the
> > > > > > client to
> > > > > > > +     handle this case.
> > > > > > 
> > > > > > Similar to my previous comment, this event is flawed, since
> > > > > > userspace cannot know were the skip is located in the queued
> > > > > > buffers. Currently, all decoders are mandated to support
> > > > > > V4L2_BUF_FLAG_TIMESTAMP_COPY. The timestamp must NOT be
> > > > interpreted
> > > > > > by the driver and must be reproduce as-is in the associated
> > > > > > CAPTURE buffer. It is possible to "garbage" collect skipped
> > > > > > frames with this method, though tedious.
> > > > > > 
> > > > > > An alternative, and I think it would be much nicer then this,
> > > > > > would be to use the v4l2_buffer.sequence counter, and just make
> > > > > > it skip 1 on skips. Though, the down side is that userspace must
> > > > > > also know how to reorder frames (a driver job for stateless
> > > > > > codecs) in order to identify which frame was skipped. So this is
> > > > > > perhaps not that useful, other then knowing something was skipped in
> > the past.
> > > > > > 
> > > > > > A third option would be to introduce V4L2_BUF_FLAG_SKIPPED. This
> > > > > > way the driver could return an empty payload (bytesused = 0)
> > > > > > buffer with this flag set, and the proper timestamp properly
> > > > > > copied. This would let the driver communicate skipped frames in
> > > > > > real-time. Note that this could break with existing userspace,
> > > > > > so it would need to be opted-in somehow (a control or some flags).
> > > > > 
> > > > > Hi Nicolas,
> > > > > ???The problem we meet is that userspace doesn't care which frame
> > > > > is skipped, it just need to know that there are a frame is
> > > > > skipped, the driver should promise the input frame count is equals
> > > > > to the output frame
> > > > count.
> > > > > ????Your first method is possible in theory, but we find the
> > > > > timestamp may be unreliable, we meet many timestamp issues that
> > > > > userspace may enqueue invalid timestamp or repeated timestamp and
> > > > > so on, so we can't
> > > > accept this solution.
> > > > 
> > > > The driver should not interpret the provided timestamp, so it should
> > > > not be able to say if the timestamp is valid or not, this is not the
> > > > driver's
> > task.
> > > > 
> > > > The driver task is to match the timestamp to the CAPTURE buffer (if
> > > > that buffer was produced), and reproduce it exactly.
> > > > 
> > > > > ????I think your second option is better. And there are only 1
> > > > > question, we find some application prefer to use the
> > > > > V4L2_EVENT_EOS to check the eos, not checking the empty buffer, if
> > > > > we use this method to check skipped frame, the
> > > > 
> > > > Checking the empty buffer is a legacy method, only available in
> > > > Samsung MFC driver. The spec says that the last buffer should be
> > > > flagged with _LAST, and any further attempt to poll should unblock and
> > DQBUF return EPIPE.
> > > > 
> > > > > application should check empty buffer instead of V4L2_EVENT_EOS,
> > > > > otherwise if the last frame is skipped, the application will miss it.
> > > > > Of course this is not a problem, it just increases the complexity
> > > > > of the userspace implementation
> > > > 
> > > > The EPIPE mechanism covers this issue, which we initially had with
> > > > the LAST flag.
> > > > 
> > > > > ????I don't think your third method is feasible, the reasons are as
> > > > > below
> > > > > ??????????????1. usually the empty payload means eos, and as you
> > > > > say, it may introduce confusion.
> > > > > ??????2. The driver may not have the opportunity to return an
> > > > > empty payload during decoding, in our driver, driver will pass the
> > > > > capture buffer to firmware, and when some frame is skipped, the
> > > > > firmware won't return the buffer, driver may not find an available
> > > > > capture buffer to return to userspace.
> > > > > 
> > > > > ???The requirement is that userspace need to match the input frame
> > > > > count and output frame count. It doesn't care which frame is
> > > > > skipped, so the V4L2_EVENT_SKIP is the easiest way for driver and
> > userspace.
> > > > > ???If you think this event is really inappropriate, I prefer to
> > > > > adopt your second option
> > > > 
> > > > Please, drop SKIP from you driver and this patchset and fix your
> > > > draining process handling to follow the spec. The Samsung OMX
> > > > component is irrelevant to mainline submission, the OMX code should
> > > > be updated to follow the spec.
> > > > 
> > > > > 
> 



From ndesaulniers at google.com  Tue Jan 25 12:27:28 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 12:27:28 -0800
Subject: [PATCH 5/8] ARM: ftrace: avoid unnecessary literal loads
In-Reply-To: <20220125153656.1802079-6-ardb@kernel.org>
References: <20220125153656.1802079-1-ardb@kernel.org>
 <20220125153656.1802079-6-ardb@kernel.org>
Message-ID: <CAKwvOd=UHj8+BhmkYD1QKkZY2r6uExSaUeN31tDhHFPPMSNHWg@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:37 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> Avoid explicit literal loads and instead, use accessor macros that
> generate the optimal sequence depending on the architecture revision
> being targeted.
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Note to fellow reviewers, Ard pointed out to me that the definition of
ldr_va depends on his vmapped stack series:
https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/commit/?h=arm-up-ti-in-task-v4&id=4e918ab13eaf40f19938659cb5a22c93172778a8
("ARM: assembler: add optimized ldr/str macros to load variables from memory")

Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

> ---
>  arch/arm/kernel/entry-ftrace.S | 27 ++++++++------------
>  1 file changed, 11 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm/kernel/entry-ftrace.S b/arch/arm/kernel/entry-ftrace.S
> index 67548c38a567..99720064a4c5 100644
> --- a/arch/arm/kernel/entry-ftrace.S
> +++ b/arch/arm/kernel/entry-ftrace.S
> @@ -35,23 +35,20 @@
>
>  .macro __mcount suffix
>         mcount_enter
> -       ldr     r0, =ftrace_trace_function
> -       ldr     r2, [r0]
> +       ldr_va  r2, ftrace_trace_function
>         badr    r0, .Lftrace_stub
>         cmp     r0, r2
>         bne     1f
>
>  #ifdef CONFIG_FUNCTION_GRAPH_TRACER
> -       ldr     r1, =ftrace_graph_return
> -       ldr     r2, [r1]
> -       cmp     r0, r2
> -       bne     ftrace_graph_caller\suffix
> -
> -       ldr     r1, =ftrace_graph_entry
> -       ldr     r2, [r1]
> -       ldr     r0, =ftrace_graph_entry_stub
> -       cmp     r0, r2
> -       bne     ftrace_graph_caller\suffix
> +       ldr_va  r2, ftrace_graph_return
> +       cmp     r0, r2
> +       bne     ftrace_graph_caller\suffix
> +
> +       ldr_va  r2, ftrace_graph_entry
> +       mov_l   r0, ftrace_graph_entry_stub
> +       cmp     r0, r2
> +       bne     ftrace_graph_caller\suffix
>  #endif
>
>         mcount_exit
> @@ -87,8 +84,7 @@
>
>         mov     r3, sp                          @ struct pt_regs*
>
> -       ldr r2, =function_trace_op
> -       ldr r2, [r2]                            @ pointer to the current
> +       ldr_va  r2, function_trace_op           @ pointer to the current
>                                                 @ function tracing op
>
>         ldr     r1, [sp, #S_LR]                 @ lr of instrumented func
> @@ -141,8 +137,7 @@ ftrace_graph_regs_call:
>         mcount_adjust_addr      r0, lr          @ instrumented function
>
>  #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
> -       ldr r2, =function_trace_op
> -       ldr r2, [r2]                            @ pointer to the current
> +       ldr_va  r2, function_trace_op           @ pointer to the current
>                                                 @ function tracing op
>         mov r3, #0                              @ regs is NULL
>  #endif
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers


From sboyd at kernel.org  Tue Jan 25 12:40:04 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 25 Jan 2022 12:40:04 -0800
Subject: [PATCH v7 3/6] dt-bindings: mvebu-uart: document DT bindings for
 marvell, armada-3700-uart-clock
In-Reply-To: <20220120092641.o4ffzeyakhuuf3c7@pali>
References: <20211015093701.pfvkighxsndj4ujg@pali>
 <20211016064210.7ahqfqcvf66wtt66@pali>
 <20220115080213.0CCAFC36AE3@smtp.kernel.org>
 <20220115115018.he4hnnhlvrb6kann@pali> <20220115130509.4a240730@thinkpad>
 <20220115122618.plhiqnjh2755bv5h@pali>
 <20220119231655.EFFF3C004E1@smtp.kernel.org>
 <20220120000651.in7s6nazif5qjkme@pali>
 <20220120060149.0FF24C340E0@smtp.kernel.org>
 <20220120092641.o4ffzeyakhuuf3c7@pali>
Message-ID: <20220125204006.A6D09C340E0@smtp.kernel.org>

Quoting Pali Roh?r (2022-01-20 01:26:41)
> On Wednesday 19 January 2022 22:01:47 Stephen Boyd wrote:
> > > 
> > > Ok, now I see what you mean.
> > > 
> > > But problem is that this is not backward compatible change. And would
> > > not work per existing DT bindings definitions, which defines how
> > > bootloader should set configured clocks.
> > > 
> > > As I wrote in emails 3 months ago, this new "proposed" DTS definition is
> > > something which I would have chosen if I had designed this driver and
> > > bindings in past. But that did not happen and different approach is
> > > already widely in used.
> > > 
> > > To support existing DTS definitions and bootloaders, it is really
> > > required to have current structure backward compatible like it is
> > > defined in current DT bindings document. And my changes in this patch
> > > series are backward compatible.
> > 
> > I'm lost. Is the bootloader the one that's expecting some particular
> > serial node format and updating something? What is the bootloader doing?
> 
> If bootloader uses or configures UART to different clock it needs to
> update "clocks" property in DT. Otherwise UART would be unusable and
> there would be no dmesg output.

Got it! I didn't see that part mentioned anywhere in the commit text
though. To the uninformed reviewer like me it is hard to know about this
bootloader design unless the commit text explains that there's no other
way to do this.

> 
> A3720 heavily depends that bootloader patches at boot time DTB file to
> the layout of the current hardware.
> 
> > > 
> > > To change DTS structure, it would be needed to provide uart nodes in DTS
> > > files two times: once in old style (the current one) and second time in
> > > this new style.
> > 
> > That's not a good idea. Why do we need to support both at the same time?
> 
> Because old bootloaders do not and will never support this new style. It
> is not only linux kernel project who provides DTB files. Also bootloader
> itself has own DTB files and use it for booting (e.g kernel). For some
> boards is in-kernel-tree DTS file only as a reference. So it is
> important that kernel can use and support DTS files from old version and
> also from the new patched version. Gregory (A3720 DTS files maintainer)
> always ask me what happens if I try to boot new patched kernel drivers
> with old unmodified DTS files and wants to know if nothing is broken by
> introduced changed.
> 
> > > 
> > > But such thing would even more complicate updating driver and it needs
> > > to be implemented.
> > > 
> > > Plus this would open a question how to define default stdout-path if
> > > there would be 4 serial nodes, where one pair would describe old style
> > > and second pair new style; meaning that 2 cross nodes would describe
> > > same define.
> > 
> > Huh? We shouldn't have both bindings present in the DTB.
> 
> Ideally yes, I would like to see to prevent it. But for backward
> compatibility we really need old bindings still present (as explained
> above).
> 
> So really I see two options here: Make changes in patches backward
> compatible (old nodes stay in DT and also kernel would be able to use
> old DT). Or let old bindings untouched in DT and new backward
> incompatible definitions would have to be in separate nodes.

Ok I understand now. We have to keep both the serial nodes because the
bootloader is patching them. To make matters worse, one or the other
node may be disabled so we can't even add the new bits to the uart1
node. Can you update the commit text to record this sad state of affairs
and indicate that the only way to support this is to make a new node in
DT that the bootloader doesn't know about?


From krzysztof.kozlowski at canonical.com  Tue Jan 25 12:41:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Tue, 25 Jan 2022 21:41:21 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <20220125194609.32314-1-nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
Message-ID: <2a5ab61e-76ae-390d-7a9f-948d99d0e561@canonical.com>

On 25/01/2022 20:46, nick.hawkins at hpe.com wrote:
> From: Nick Hawkins <nick.hawkins at hpe.com>
> 

Thanks for the patches. The commit should come with description. Please
check other commits adding new sub-arch or boards for nice examples.

> Signed-off-by: Nick Hawkins <nick.hawkins at hpe.com>
> ---
>  .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
>  MAINTAINERS                                   |   8 +
>  arch/arm/Kconfig                              |   2 +
>  arch/arm/boot/dts/gxp.dts                     | 700 ++++++++++++++++++

DTS goes separately.

>  arch/arm/configs/gxp_defconfig                | 243 ++++++

Defconfig is separate commit.

>  arch/arm/mach-hpe/Kconfig                     |  20 +
>  arch/arm/mach-hpe/Makefile                    |   1 +
>  arch/arm/mach-hpe/gxp.c                       |  63 ++
>  8 files changed, 1039 insertions(+)
>  create mode 100644 arch/arm/boot/dts/gxp.dts
>  create mode 100644 arch/arm/configs/gxp_defconfig
>  create mode 100644 arch/arm/mach-hpe/Kconfig
>  create mode 100644 arch/arm/mach-hpe/Makefile
>  create mode 100644 arch/arm/mach-hpe/gxp.c
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 294093d45a23..e8b0ec874aed 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -515,6 +515,8 @@ patternProperties:
>      description: Jiangsu HopeRun Software Co., Ltd.
>    "^hp,.*":
>      description: Hewlett Packard

Is Hewlett Packard not an Enterprise?

> +  "^hpe,.*":
> +    description: Hewlett Packard Enterprise

...

>    "^hsg,.*":
>      description: HannStar Display Co.
>    "^holtek,.*":
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ea3e6c914384..007d99734dd1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -8382,6 +8382,14 @@ L:	linux-efi at vger.kernel.org
>  S:	Maintained
>  F:	block/partitions/efi.*
>  
> +GXP ARCHITECTURE
> +M:	Jean-Marie Verdun <verdun at hpe.com>
> +M:	Nick Hawkins <nick.hawkins at hpe.com>
> +S:	Maintained
> +F:	arch/arm/boot/dts/gxp.dts
> +F:	arch/arm/configs/gxp_defconfig
> +F:	arch/arm/mach-hpe/gxp.c
> +
>  H8/300 ARCHITECTURE
>  M:	Yoshinori Sato <ysato at users.sourceforge.jp>
>  L:	uclinux-h8-devel at lists.sourceforge.jp (moderated for non-subscribers)
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index fabe39169b12..d428d0d35889 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -708,6 +708,8 @@ source "arch/arm/mach-vt8500/Kconfig"
>  
>  source "arch/arm/mach-zynq/Kconfig"
>  
> +source "arch/arm/mach-hpe/Kconfig"

All entries in that secion are ordered alphabetically, so mach-hp or
mach-hpe should not stick out.

> +
>  # ARMv7-M architecture
>  config ARCH_LPC18XX
>  	bool "NXP LPC18xx/LPC43xx"
> diff --git a/arch/arm/boot/dts/gxp.dts b/arch/arm/boot/dts/gxp.dts

This needs some better, longer name than just gxp... Look how other
files are named in that directory.

> new file mode 100644
> index 000000000000..7bd814ecaaee
> --- /dev/null
> +++ b/arch/arm/boot/dts/gxp.dts

Where is DTSI? What is this file about? Why there is no description?
What's the purpose?

Where is the dts Makefile change? How do you compile it?

> @@ -0,0 +1,700 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Device Tree file for HPE GXP
> + */
> +
> +/dts-v1/;
> +/ {
> +  #address-cells = <1>;
> +  #size-cells = <1>;
> +	compatible = "HPE,GXP";

Didn't checkpatch complain about undocumented compatible?

If even if it did not, you need to document it. And solve all the issues
like - why uppercase, where is DTSI or SoC compatible... and what is it
exactly?

> +	model = "GXP";

So informative... Model GXP like compatible.

> +
> +	chosen {
> +		bootargs = "earlyprintk console=ttyS0,115200 user_debug=31";

earlyprint is a debugging feature, not suitable for mainline DTS. The
same seems with "user_debug=31". Remove both.

Console should go to chosen stdout-path node instead.

> +	};
> +
> +	aliases {
> +	};

No need for an empty node.

> +
> +	memory at 40000000 {
> +		device_type = "memory";
> +		reg = <0x40000000 0x20000000>;
> +	};
> +
> +	ahb at 80000000 {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges;
> +
> +		vic0: vic at ceff0000 {

Node names should be generic, so this is interrupt-controller.

> +			compatible = "arm,pl192-vic";
> +			interrupt-controller;
> +			reg = <0xceff0000 0x1000>;
> +			#interrupt-cells = <1>;
> +		};
> +
> +		vic1: vic at 80f00000 {
> +			compatible = "arm,pl192-vic";
> +			interrupt-controller;
> +			reg = <0x80f00000 0x1000>;
> +			#interrupt-cells = <1>;
> +		};
> +
> +		timer0: timer at c0000080 {
> +			compatible = "hpe,gxp-timer";

Undocumented compatible. Also looks too generic.

> +			reg = <0xc0000080 0x1>, <0xc0000094 0x01>, <0xc0000088 0x08>;
> +			interrupts = <0>;
> +			interrupt-parent = <&vic0>;
> +			clock-frequency = <400000000>;
> +		};
> +
> +		watchdog: watchdog at c0000090 {
> +			compatible = "hpe,gxp-wdt";

Undocumented compatible. Also looks too generic.

> +			reg = <0xc0000090 0x02>, <0xc0000096 0x01>;
> +		};
> +
> +		uartc: serial at c00000f0 {
> +			compatible = "ns16550a";
> +			reg = <0xc00000f0 0x8>;
> +			interrupts = <19>;
> +			interrupt-parent = <&vic0>;
> +			clock-frequency = <1846153>;
> +			reg-shift = <0>;
> +		};
> +
> +		uarta: serial at c00000e0 {
> +			compatible = "ns16550a";
> +			reg = <0xc00000e0 0x8>;
> +			interrupts = <17>;
> +			interrupt-parent = <&vic0>;
> +			clock-frequency = <1846153>;
> +			reg-shift = <0>;
> +		};
> +
> +		uartb: serial at c00000e8 {
> +			compatible = "ns16550a";
> +			reg = <0xc00000e8 0x8>;
> +			interrupts = <18>;
> +			interrupt-parent = <&vic0>;
> +			clock-frequency = <1846153>;
> +			reg-shift = <0>;
> +		};
> +
> +		vuart_a_cfg: vuarta_cfg at 80fc0230 {
> +			compatible = "hpe,gxp-vuarta_cfg", "simple-mfd", "syscon";
> +			reg = <0x80fc0230 0x100>;
> +			reg-io-width = <1>;
> +		};
> +
> +		vuart_a: vuart_a at 80fd0200 {
> +			compatible = "hpe,gxp-vuart";
> +			reg = <0x80fd0200 0x100>;
> +			interrupts = <2>;
> +			interrupt-parent = <&vic1>;
> +			clock-frequency = <1846153>;
> +			reg-shift = <0>;
> +			status = "okay";
> +			serial-line = <3>;
> +			vuart_cfg = <&vuart_a_cfg>;
> +		};
> +
> +		usb0: ehci at cefe0000 {
> +			compatible = "generic-ehci";
> +			reg = <0xcefe0000 0x100>;
> +			interrupts = <7>;
> +			interrupt-parent = <&vic0>;
> +		};
> +
> +		usb1: ohci at cefe0100 {
> +			compatible = "generic-ohci";
> +			reg = <0xcefe0100 0x110>;
> +			interrupts = <6>;
> +			interrupt-parent = <&vic0>;
> +		};
> +
> +		spifi0: spifi at c0000200 {

What is spifi? Maybe "spi"?

> +			compatible = "hpe,gxp-spifi";

Undocumented compatible. Also looks too generic.

> +			reg = <0xc0000200 0x80>, <0xc000c000 0x100>, <0xf8000000 0x8000000>;
> +			interrupts = <20>;
> +			interrupt-parent = <&vic0>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			flash at 0 {
> +				compatible = "jedec,spi-nor";
> +				reg = <0>;
> +				partitions {
> +					compatible = "fixed-partitions";
> +					#address-cells = <1>;
> +					#size-cells = <1>;
> +
> +					bmc at 0 {
> +						label = "bmc";
> +						reg = <0x0 0x2000000>;
> +					};
> +					u-boot at 0 {
> +						label = "u-boot";
> +						reg = <0x0 0x60000>;
> +					};
> +					u-boot-env at 60000 {
> +						label = "u-boot-env";
> +						reg = <0x60000 0x20000>;
> +					};
> +					kernel at 80000 {
> +						label = "kernel";
> +						reg = <0x80000 0x4c0000>;
> +					};
> +					rofs at 540000 {
> +						label = "rofs";
> +						reg = <0x540000 0x1740000>;
> +					};
> +					rwfs at 1c80000 {
> +						label = "rwfs";
> +						reg = <0x1c80000 0x250000>;
> +					};
> +					section at 1edf000{
> +						label = "section";
> +						reg = <0x1ed0000 0x130000>;
> +					};
> +				};
> +			};
> +
> +			flash at 1 {
> +				compatible = "jedec,spi-nor";
> +				reg = <1>;
> +				partitions {
> +					compatible = "fixed-partitions";
> +					#address-cells = <1>;
> +					#size-cells = <1>;
> +					host-prime at 0 {
> +						label = "host-prime";
> +						reg = <0x0 0x02000000>;
> +					};
> +					host-second at 0 {
> +						label = "host-second";
> +						reg = <0x02000000 0x02000000>;
> +					};
> +				};
> +			};
> +		};
> +
> +		sram at d0000000 {
> +			compatible = "mtd-ram";
> +			reg = <0xd0000000 0x80000>;
> +			bank-width = <1>;
> +			erase-size =<1>;
> +			partition at 0 {
> +				label = "host-reserved";
> +				reg = <0x0 0x10000>;
> +			};
> +			partition at 10000 {
> +				label = "nvram";
> +				reg = <0x10000 0x70000>;
> +			};
> +		};
> +
> +		srom at 80fc0000 {
> +			compatible = "hpe,gxp-srom", "simple-mfd", "syscon";
> +			reg = <0x80fc0000 0x100>;
> +		};
> +
> +		vrom at 58000000 {
> +			compatible = "mtd-ram";
> +			bank-width = <4>;
> +			reg = <0x58000000 0x4000000>;
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			partition at 0 {
> +				label = "vrom-prime";
> +				reg = <0x0 0x2000000>;
> +			};
> +			partition at 2000000 {
> +				label = "vrom-second";
> +				reg = <0x2000000 0x2000000>;
> +			};
> +		};
> +
> +		i2cg: i2cg at c00000f8 {

What's this exactly?

> +			compatible = "syscon";
> +			reg = <0xc00000f8 0x08>;
> +		};
> +
> +		i2c0: i2c at c0002000 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002000 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c1: i2c at c0002100 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002100 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c2: i2c at c0002200 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002200 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			24c02 at 50 {
> +				compatible = "atmel,24c02";
> +				pagesize = <8>;
> +				reg = <0x50>;
> +			};
> +		};
> +
> +		i2c3: i2c at c0002300 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002300 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c4: i2c at c0002400 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002400 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c5: i2c at c0002500 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002500 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +		};
> +
> +		i2c6: i2c at c0002600 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002600 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c7: i2c at c0002700 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002700 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			psu1: psu at 58 {
> +				compatible = "hpe,gxp-psu";
> +				reg = <0x58>;
> +			};
> +
> +			psu2: psu at 59 {
> +				compatible = "hpe,gxp-psu";
> +				reg = <0x59>;
> +			};
> +		};
> +
> +		i2c8: i2c at c0002800 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002800 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2c9: i2c at c0002900 {
> +			compatible = "hpe,gxp-i2c";
> +			reg = <0xc0002900 0x70>;
> +			interrupts = <9>;
> +			interrupt-parent = <&vic0>;
> +			i2cg-handle = <&i2cg>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
> +		i2cmux at 4 {

Does it even compile with W=1? The unit address looks quite different
than what is below.

Also - node name should be generic.

> +			compatible = "i2c-mux-reg";
> +			i2c-parent = <&i2c4>;
> +			reg = <0xd1000074 1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			i2c4 at 1 {
> +				reg = <1>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c4 at 3 {
> +				reg = <3>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c4 at 4 {
> +				reg = <4>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
> +		i2cmux at 6 {
> +			compatible = "i2c-mux-reg";
> +			i2c-parent = <&i2c6>;
> +			reg = <0xd1000076 1>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			i2c6 at 1 {
> +				reg = <1>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c6 at 2 {
> +				reg = <2>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c6 at 3 {
> +				reg = <3>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c6 at 4 {
> +				reg = <4>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +
> +			i2c6 at 5 {
> +				reg = <5>;
> +				#address-cells = <1>;
> +				#size-cells = <0>;
> +			};
> +		};
> +
> +		mdio0: mdio at c0004080 {
> +			compatible = "hpe,gxp-umac-mdio";
> +			reg = <0xc0004080 0x10>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			ext_phy0: ethernt-phy at 0 {
> +				compatible = "ethernet-phy-ieee802.3-c22";
> +				phy-mode = "sgmii";
> +				reg = <0>;
> +			};
> +		};
> +
> +		mdio1: mdio at c0005080 {
> +			compatible = "hpe,gxp-umac-mdio";
> +			reg = <0xc0005080 0x10>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			int_phy0: ethernt-phy at 0 {
> +				compatible = "ethernet-phy-ieee802.3-c22";
> +				phy-mode = "gmii";
> +				reg = <0>;
> +			};
> +			int_phy1: ethernt-phy at 1 {
> +				compatible = "ethernet-phy-ieee802.3-c22";
> +				phy-mode = "gmii";
> +				reg = <1>;
> +			};
> +		};
> +
> +		umac0: umac at c0004000 {
> +			compatible = "hpe, gxp-umac";

No spaces in compatibles. Previous comments about compatibles also
apply. About node name as well.

I'll stop on DTS now, because it does not look much better below.

> +			reg = <0xc0004000 0x80>;
> +			interrupts = <10>;
> +			interrupt-parent = <&vic0>;
> +			mac-address = [94 18 82 16 04 d8];
> +			phy-handle = <&ext_phy0>;
> +			int-phy-handle = <&int_phy0>;
> +		};
> +

(...)

> diff --git a/arch/arm/configs/gxp_defconfig b/arch/arm/configs/gxp_defconfig
> new file mode 100644
> index 000000000000..f37c6630e06d
> --- /dev/null
> +++ b/arch/arm/configs/gxp_defconfig
> @@ -0,0 +1,243 @@
> +CONFIG_KERNEL_XZ=y
> +CONFIG_DEFAULT_HOSTNAME="gxp"
> +CONFIG_SYSVIPC=y
> +CONFIG_NO_HZ=y
> +CONFIG_HIGH_RES_TIMERS=y
> +CONFIG_BSD_PROCESS_ACCT=y
> +CONFIG_BSD_PROCESS_ACCT_V3=y
> +CONFIG_LOG_BUF_SHIFT=18
> +CONFIG_CFS_BANDWIDTH=y
> +CONFIG_RT_GROUP_SCHED=y
> +CONFIG_CGROUP_FREEZER=y
> +CONFIG_CGROUP_DEVICE=y
> +CONFIG_CGROUP_CPUACCT=y
> +CONFIG_NAMESPACES=y
> +CONFIG_SCHED_AUTOGROUP=y
> +CONFIG_RELAY=y
> +CONFIG_BLK_DEV_INITRD=y
> +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
> +CONFIG_KALLSYMS_ALL=y
> +CONFIG_EMBEDDED=y
> +# CONFIG_COMPAT_BRK is not set
> +CONFIG_SLAB=y
> +CONFIG_ARCH_MULTI_V6=y
> +CONFIG_ARCH_HPE=y
> +CONFIG_ARCH_HPE_GXP=y
> +CONFIG_SECCOMP=y
> +# CONFIG_ATAGS is not set
> +CONFIG_ZBOOT_ROM_TEXT=0x0
> +CONFIG_ZBOOT_ROM_BSS=0x0
> +# CONFIG_SUSPEND is not set
> +CONFIG_JUMP_LABEL=y
> +# CONFIG_STRICT_KERNEL_RWX is not set
> +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
> +CONFIG_KSM=y
> +CONFIG_CLEANCACHE=y
> +CONFIG_NET=y
> +CONFIG_PACKET=y
> +CONFIG_PACKET_DIAG=y
> +CONFIG_UNIX=y
> +CONFIG_UNIX_DIAG=y
> +CONFIG_XFRM_USER=y
> +CONFIG_XFRM_STATISTICS=y
> +CONFIG_INET=y
> +CONFIG_VLAN_8021Q=y
> +CONFIG_NETLINK_DIAG=y
> +CONFIG_NET_NCSI=y
> +# CONFIG_WIRELESS is not set
> +CONFIG_DEVTMPFS=y
> +CONFIG_DEVTMPFS_MOUNT=y
> +# CONFIG_STANDALONE is not set
> +CONFIG_MTD=y
> +CONFIG_MTD_BLOCK=y
> +CONFIG_MTD_PHYSMAP=y
> +CONFIG_MTD_PHYSMAP_OF=y
> +CONFIG_MTD_PLATRAM=y
> +CONFIG_MTD_SPI_NOR=y
> +CONFIG_SPI_GXP_SPIFI=y
> +CONFIG_BLK_DEV_NULL_BLK=y
> +CONFIG_BLK_DEV_LOOP=y
> +CONFIG_BLK_DEV_NBD=y
> +CONFIG_BLK_DEV_RAM=y
> +CONFIG_EEPROM_AT24=y
> +CONFIG_SCSI=y
> +CONFIG_BLK_DEV_SD=y
> +# CONFIG_SCSI_LOWLEVEL is not set
> +CONFIG_NETDEVICES=y
> +# CONFIG_NET_VENDOR_ALACRITECH is not set
> +# CONFIG_NET_VENDOR_AMAZON is not set
> +# CONFIG_NET_VENDOR_AQUANTIA is not set
> +# CONFIG_NET_VENDOR_ARC is not set
> +# CONFIG_NET_VENDOR_AURORA is not set
> +# CONFIG_NET_VENDOR_BROADCOM is not set
> +# CONFIG_NET_VENDOR_CADENCE is not set
> +# CONFIG_NET_VENDOR_CAVIUM is not set
> +# CONFIG_NET_VENDOR_CIRRUS is not set
> +# CONFIG_NET_VENDOR_CORTINA is not set
> +# CONFIG_NET_VENDOR_EZCHIP is not set
> +# CONFIG_NET_VENDOR_FARADAY is not set
> +# CONFIG_NET_VENDOR_GOOGLE is not set
> +# CONFIG_NET_VENDOR_HISILICON is not set
> +# CONFIG_NET_VENDOR_HUAWEI is not set
> +# CONFIG_NET_VENDOR_INTEL is not set
> +# CONFIG_NET_VENDOR_MARVELL is not set
> +# CONFIG_NET_VENDOR_MELLANOX is not set
> +# CONFIG_NET_VENDOR_MICREL is not set
> +# CONFIG_NET_VENDOR_MICROCHIP is not set
> +# CONFIG_NET_VENDOR_MICROSEMI is not set
> +# CONFIG_NET_VENDOR_NATSEMI is not set
> +# CONFIG_NET_VENDOR_NETRONOME is not set
> +# CONFIG_NET_VENDOR_NI is not set
> +# CONFIG_NET_VENDOR_QUALCOMM is not set
> +# CONFIG_NET_VENDOR_RENESAS is not set
> +# CONFIG_NET_VENDOR_ROCKER is not set
> +# CONFIG_NET_VENDOR_SAMSUNG is not set
> +# CONFIG_NET_VENDOR_SEEQ is not set
> +# CONFIG_NET_VENDOR_SOLARFLARE is not set
> +# CONFIG_NET_VENDOR_SMSC is not set
> +# CONFIG_NET_VENDOR_SOCIONEXT is not set
> +# CONFIG_NET_VENDOR_STMICRO is not set
> +# CONFIG_NET_VENDOR_SYNOPSYS is not set
> +# CONFIG_NET_VENDOR_VIA is not set
> +# CONFIG_NET_VENDOR_WIZNET is not set
> +# CONFIG_NET_VENDOR_XILINX is not set
> +CONFIG_UMAC=y
> +# CONFIG_USB_NET_DRIVERS is not set
> +# CONFIG_WLAN is not set
> +# CONFIG_INPUT_LEDS is not set
> +CONFIG_INPUT_EVDEV=y
> +# CONFIG_KEYBOARD_ATKBD is not set
> +CONFIG_KEYBOARD_GPIO=y
> +CONFIG_KEYBOARD_GPIO_POLLED=y
> +# CONFIG_INPUT_MOUSE is not set
> +CONFIG_SERIO_LIBPS2=y
> +CONFIG_VT_HW_CONSOLE_BINDING=y
> +# CONFIG_LEGACY_PTYS is not set
> +CONFIG_SERIAL_8250=y
> +# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
> +CONFIG_SERIAL_8250_CONSOLE=y
> +CONFIG_SERIAL_8250_NR_UARTS=6
> +CONFIG_SERIAL_8250_RUNTIME_UARTS=6
> +CONFIG_SERIAL_8250_EXTENDED=y
> +CONFIG_SERIAL_8250_SHARE_IRQ=y
> +CONFIG_SERIAL_8250_GXP_VUART=y
> +CONFIG_SERIAL_OF_PLATFORM=y
> +CONFIG_TTY_PRINTK=y
> +CONFIG_IPMI_HANDLER=y
> +CONFIG_IPMI_DEVICE_INTERFACE=y
> +CONFIG_IPMI_SI=y
> +CONFIG_IPMI_SSIF=y
> +CONFIG_HPE_KCS_IPMI_BMC=y
> +CONFIG_HW_RANDOM_TIMERIOMEM=y
> +CONFIG_I2C_CHARDEV=y
> +CONFIG_I2C_GXP=y
> +CONFIG_I2C_SLAVE=y
> +CONFIG_I2C_SLAVE_EEPROM=y
> +CONFIG_SPI=y
> +CONFIG_GPIOLIB=y
> +CONFIG_GPIO_SYSFS=y
> +CONFIG_GPIO_GXP=y
> +CONFIG_SENSORS_EMC1403=y
> +CONFIG_SENSORS_GXP_FAN_CTRL=y
> +CONFIG_SENSORS_GXP_CORETEMP=y
> +CONFIG_SENSORS_GXP_PSU=y
> +CONFIG_SENSORS_GXP_POWER=y
> +CONFIG_WATCHDOG=y
> +CONFIG_GXP_WATCHDOG=y
> +CONFIG_MFD_SYSCON=y
> +CONFIG_FB=y
> +CONFIG_FB_THUMBNAIL=y
> +CONFIG_FB_SIMPLE=y
> +CONFIG_USB=y
> +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
> +CONFIG_USB_EHCI_HCD=y
> +CONFIG_USB_EHCI_ROOT_HUB_TT=y
> +CONFIG_USB_OHCI_HCD=y
> +CONFIG_USB_OHCI_HCD_PLATFORM=y
> +CONFIG_USB_STORAGE=y
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_GXP_UDC=y
> +CONFIG_USB_CONFIGFS=y
> +CONFIG_USB_CONFIGFS_SERIAL=y
> +CONFIG_USB_CONFIGFS_ACM=y
> +CONFIG_USB_CONFIGFS_OBEX=y
> +CONFIG_USB_CONFIGFS_NCM=y
> +CONFIG_USB_CONFIGFS_ECM=y
> +CONFIG_USB_CONFIGFS_ECM_SUBSET=y
> +CONFIG_USB_CONFIGFS_RNDIS=y
> +CONFIG_USB_CONFIGFS_EEM=y
> +CONFIG_USB_CONFIGFS_MASS_STORAGE=y
> +CONFIG_USB_CONFIGFS_F_LB_SS=y
> +CONFIG_USB_CONFIGFS_F_FS=y
> +CONFIG_USB_CONFIGFS_F_HID=y
> +CONFIG_USB_CONFIGFS_F_PRINTER=y
> +CONFIG_NEW_LEDS=y
> +CONFIG_LEDS_CLASS=y
> +CONFIG_LEDS_GPIO=y
> +CONFIG_LEDS_TRIGGERS=y
> +CONFIG_LEDS_TRIGGER_TIMER=y
> +CONFIG_LEDS_TRIGGER_ONESHOT=y
> +CONFIG_LEDS_TRIGGER_MTD=y
> +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
> +CONFIG_LEDS_TRIGGER_CPU=y
> +CONFIG_LEDS_TRIGGER_GPIO=y
> +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
> +CONFIG_LEDS_TRIGGER_TRANSIENT=y
> +CONFIG_LEDS_TRIGGER_PANIC=y
> +# CONFIG_VIRTIO_MENU is not set
> +# CONFIG_IOMMU_SUPPORT is not set
> +CONFIG_HPE_GXP_XREG=y
> +CONFIG_HPE_GXP_FN2=y
> +CONFIG_HPE_GXP_CSM=y
> +CONFIG_HPE_GXP_SROM=y
> +CONFIG_FANOTIFY=y
> +CONFIG_OVERLAY_FS=y
> +CONFIG_OVERLAY_FS_REDIRECT_DIR=y
> +CONFIG_TMPFS=y
> +CONFIG_TMPFS_POSIX_ACL=y
> +CONFIG_JFFS2_FS=y
> +# CONFIG_JFFS2_FS_WRITEBUFFER is not set
> +CONFIG_JFFS2_SUMMARY=y
> +CONFIG_JFFS2_FS_XATTR=y
> +# CONFIG_JFFS2_FS_POSIX_ACL is not set
> +# CONFIG_JFFS2_FS_SECURITY is not set
> +CONFIG_SQUASHFS=y
> +CONFIG_SQUASHFS_XZ=y
> +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y
> +# CONFIG_NETWORK_FILESYSTEMS is not set
> +CONFIG_NLS_CODEPAGE_437=y
> +CONFIG_NLS_ASCII=y
> +CONFIG_NLS_ISO8859_1=y
> +CONFIG_NLS_UTF8=y
> +CONFIG_CRYPTO_CCM=y
> +CONFIG_CRYPTO_GCM=y
> +CONFIG_CRYPTO_CRC32C=y
> +CONFIG_CRYPTO_ARC4=y
> +CONFIG_CRYPTO_DEFLATE=y
> +CONFIG_CRYPTO_LZO=y
> +CONFIG_CRYPTO_ZSTD=y
> +CONFIG_CRYPTO_USER_API_HASH=y
> +# CONFIG_CRYPTO_HW is not set
> +CONFIG_CRC16=y
> +# CONFIG_XZ_DEC_ARM is not set
> +# CONFIG_XZ_DEC_ARMTHUMB is not set
> +CONFIG_DMA_API_DEBUG=y
> +CONFIG_PRINTK_TIME=y
> +CONFIG_BOOT_PRINTK_DELAY=y
> +CONFIG_DYNAMIC_DEBUG=y
> +CONFIG_DEBUG_INFO=y
> +# CONFIG_ENABLE_MUST_CHECK is not set
> +CONFIG_MAGIC_SYSRQ=y
> +CONFIG_PANIC_ON_OOPS=y
> +CONFIG_FUNCTION_PROFILER=y
> +CONFIG_STACK_TRACER=y
> +CONFIG_SCHED_TRACER=y
> +CONFIG_STRICT_DEVMEM=y
> +CONFIG_DEBUG_USER=y
> +CONFIG_DEBUG_LL=y
> +CONFIG_DEBUG_LL_UART_8250=y
> +CONFIG_DEBUG_UART_PHYS=0xC00000F0
> +CONFIG_DEBUG_UART_VIRT=0xF00000F0
> +CONFIG_DEBUG_UART_8250_SHIFT=0
> +CONFIG_EARLY_PRINTK=y
> +CONFIG_TEST_KSTRTOX=y
> diff --git a/arch/arm/mach-hpe/Kconfig b/arch/arm/mach-hpe/Kconfig
> new file mode 100644
> index 000000000000..9b27f97c6536
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Kconfig
> @@ -0,0 +1,20 @@
> +menuconfig ARCH_HPE
> +	bool "HPE SoC support"
> +	help
> +	  This enables support for HPE ARM based SoC chips
> +if ARCH_HPE
> +
> +config ARCH_HPE_GXP
> +	bool "HPE GXP SoC"
> +	select ARM_VIC
> +	select PINCTRL
> +	select IRQ_DOMAIN
> +	select GENERIC_IRQ_CHIP
> +	select MULTI_IRQ_HANDLER
> +	select SPARSE_IRQ
> +	select CLKSRC_MMIO
> +	depends on ARCH_MULTI_V7
> +	help
> +	  Support for GXP SoCs
> +
> +endif
> diff --git a/arch/arm/mach-hpe/Makefile b/arch/arm/mach-hpe/Makefile
> new file mode 100644
> index 000000000000..8b0a91234df4
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_ARCH_HPE_GXP) += gxp.o
> diff --git a/arch/arm/mach-hpe/gxp.c b/arch/arm/mach-hpe/gxp.c
> new file mode 100644
> index 000000000000..b58f25fbae5a
> --- /dev/null
> +++ b/arch/arm/mach-hpe/gxp.c
> @@ -0,0 +1,63 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/* Copyright (C) 2022 Hewlett-Packard Enterprise Development Company, L.P.
> + *
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +
> +#include <linux/init.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/map.h>
> +#include <linux/of.h>
> +#include <linux/of_platform.h>
> +#include <linux/clk-provider.h>
> +#include <linux/clocksource.h>
> +
> +#define IOP_REGS_PHYS_BASE 0xc0000000
> +#define IOP_REGS_VIRT_BASE 0xf0000000
> +#define IOP_REGS_SIZE (240*SZ_1M)
> +
> +#define IOP_EHCI_USBCMD 0x0efe0010
> +
> +static struct map_desc gxp_io_desc[] __initdata = {
> +	{
> +	.virtual	= (unsigned long)IOP_REGS_VIRT_BASE,
> +	.pfn		= __phys_to_pfn(IOP_REGS_PHYS_BASE),
> +	.length		= IOP_REGS_SIZE,
> +	.type		= MT_DEVICE,
> +	},
> +};
> +
> +void __init gxp_map_io(void)
> +{
> +	iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
> +}
> +
> +static void __init gxp_dt_init(void)
> +{
> +	//reset EHCI host controller for clear start

Linux style comments please, so /*.

> +	__raw_writel(0x00080002,

What is this magic value?

> +		(void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));

Why do you need the cast?

> +	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
> +}
> +
> +static void gxp_restart(enum reboot_mode mode, const char *cmd)
> +{
> +	pr_info("gpx restart");

Skip it.

> +	__raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
> +}
> +
> +static const char * const gxp_board_dt_compat[] = {
> +	"HPE,GXP",
> +	NULL,
> +};
> +
> +DT_MACHINE_START(GXP_DT, "HPE GXP")
> +	.init_machine	= gxp_dt_init,
> +	.map_io		= gxp_map_io,
> +	.restart	= gxp_restart,
> +	.dt_compat	= gxp_board_dt_compat,
> +MACHINE_END


Best regards,
Krzysztof


From german.gomez at arm.com  Tue Jan 25 12:47:39 2022
From: german.gomez at arm.com (German Gomez)
Date: Tue, 25 Jan 2022 20:47:39 +0000
Subject: [PATCH 1/2] perf arm-spe: Add arm_spe_record to synthesized sample
In-Reply-To: <20220125192016.20538-2-alisaidi@amazon.com>
References: <20220125192016.20538-1-alisaidi@amazon.com>
 <20220125192016.20538-2-alisaidi@amazon.com>
Message-ID: <5ca990a5-eedd-0edb-26d3-b5e16c36ac34@arm.com>

Hi Ali,

On 25/01/2022 19:20, Ali Saidi wrote:
> Providing the arm_spe_record as raw data to the synthesized SPE samples
> allows perf scripts to read and separately process the data in ways
> existing perf tools don't support and mirrors functionality available
> for PEBS.
> Signed-off-by: Ali Saidi <alisaidi at amazon.com>
> ---
>  tools/perf/util/arm-spe.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
> index d2b64e3f588b..a7499cde6fc0 100644
> --- a/tools/perf/util/arm-spe.c
> +++ b/tools/perf/util/arm-spe.c
> @@ -336,6 +336,8 @@ static int arm_spe__synth_mem_sample(struct arm_spe_queue *speq,
>  	sample.phys_addr = record->phys_addr;
>  	sample.data_src = data_src;
>  	sample.weight = record->latency;
> +	sample.raw_size = sizeof(*record);
> +	sample.raw_data = record;

Have you tried this with perf-inject? I think it would need the PERF_SAMPLE_RAW bit in the sample_type,

Although I quickly looked over the perf inject code and it looks like it's expecting some type of padding:

? // synthetic-events.c
? if (type & PERF_SAMPLE_RAW) {
??? result += sizeof(u32);
??? result += sample->raw_size;
? }

I'm seeing some comments in utils/event.h related to this on the intel events.

>  
>  	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
>  }
> @@ -354,6 +356,8 @@ static int arm_spe__synth_branch_sample(struct arm_spe_queue *speq,
>  	sample.stream_id = spe_events_id;
>  	sample.addr = record->to_ip;
>  	sample.weight = record->latency;
> +	sample.raw_size = sizeof(*record);
> +	sample.raw_data = record;
>  
>  	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
>  }
> @@ -383,6 +387,8 @@ static int arm_spe__synth_instruction_sample(struct arm_spe_queue *speq,
>  	sample.data_src = data_src;
>  	sample.period = spe->instructions_sample_period;
>  	sample.weight = record->latency;
> +	sample.raw_size = sizeof(*record);
> +	sample.raw_data = record;
>  
>  	return arm_spe_deliver_synth_event(spe, speq, event, &sample);
>  }


From ndesaulniers at google.com  Tue Jan 25 12:48:29 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 12:48:29 -0800
Subject: [PATCH v6 8/8] ARM: make get_current() and __my_cpu_offset()
 __always_inline
In-Reply-To: <20220125091453.1475246-9-ardb@kernel.org>
References: <20220125091453.1475246-1-ardb@kernel.org>
 <20220125091453.1475246-9-ardb@kernel.org>
Message-ID: <CAKwvOdnV6ndTYjNN5CzYx_4LQpB4A6Qhfe21Vos192pUj=Hwmg@mail.gmail.com>

On Tue, Jan 25, 2022 at 1:15 AM Ard Biesheuvel <ardb at kernel.org> wrote:
>
> The get_current() and __my_cpu_offset() accessors evaluate to only a
> single instruction emitted inline, but due to the size of the asm string
> that is created for SMP+v6 configurations, the compiler assumes
> otherwise, and may emit the functions out of line instead.
>
> So use __always_inline to avoid this.
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>

Alternatively, you could use the inline qualifier on the asm stmt.
i.e. `asm inline ("my asm string")`. Only supported since gcc-8.3+ and
all kernel-supported versions of clang though. See `asm_inline` in
include/linux/compiler_types.h.
Either way,
Reviewed-by: Nick Desaulniers <ndesaulniers at google.com>

> ---
>  arch/arm/include/asm/current.h | 2 +-
>  arch/arm/include/asm/percpu.h  | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h
> index 131a89bbec6b..1e1178bf176d 100644
> --- a/arch/arm/include/asm/current.h
> +++ b/arch/arm/include/asm/current.h
> @@ -14,7 +14,7 @@ struct task_struct;
>
>  extern struct task_struct *__current;
>
> -static inline __attribute_const__ struct task_struct *get_current(void)
> +static __always_inline __attribute_const__ struct task_struct *get_current(void)
>  {
>         struct task_struct *cur;
>
> diff --git a/arch/arm/include/asm/percpu.h b/arch/arm/include/asm/percpu.h
> index a09034ae45a1..7545c87c251f 100644
> --- a/arch/arm/include/asm/percpu.h
> +++ b/arch/arm/include/asm/percpu.h
> @@ -25,7 +25,7 @@ static inline void set_my_cpu_offset(unsigned long off)
>         asm volatile("mcr p15, 0, %0, c13, c0, 4" : : "r" (off) : "memory");
>  }
>
> -static inline unsigned long __my_cpu_offset(void)
> +static __always_inline unsigned long __my_cpu_offset(void)
>  {
>         unsigned long off;
>
> --
> 2.30.2
>


-- 
Thanks,
~Nick Desaulniers


From keescook at chromium.org  Tue Jan 25 12:58:20 2022
From: keescook at chromium.org (Kees Cook)
Date: Tue, 25 Jan 2022 12:58:20 -0800
Subject: [PATCH] ARM: stackprotector: prefer compiler for TLS based
 per-task protector
In-Reply-To: <CAMj1kXFgcoWU2XnL-arTKoA0Sk2AoQVjZ-xVLryGR=fkS89FVA@mail.gmail.com>
References: <20211021142516.1843042-1-ardb@kernel.org>
 <YfBGg+zmIlHmTIm/@dev-arch.archlinux-ax161>
 <CAMj1kXFgcoWU2XnL-arTKoA0Sk2AoQVjZ-xVLryGR=fkS89FVA@mail.gmail.com>
Message-ID: <202201251258.35AAAB07E5@keescook>

On Tue, Jan 25, 2022 at 07:55:37PM +0100, Ard Biesheuvel wrote:
> On Tue, 25 Jan 2022 at 19:50, Nathan Chancellor <nathan at kernel.org> wrote:
> >
> > On Thu, Oct 21, 2021 at 04:25:16PM +0200, Ard Biesheuvel wrote:
> > > Currently, we implement the per-task stack protector for ARM using a GCC
> > > plugin, due to lack of native compiler support. However, work is
> > > underway to get this implemented in the compiler, which means we will be
> > > able to deprecate the GCC plugin at some point.
> > >
> > > In the meantime, we will need to support both, where the native compiler
> > > implementation is obviously preferred. So let's wire this up in Kconfig
> > > and the Makefile.
> > >
> > > Cc: Kees Cook <keescook at chromium.org>
> > > Cc: Nick Desaulniers <ndesaulniers at google.com>
> > > Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> >
> > I see this patch in the KSPP tree as commit 151bbc8be85e ("ARM:
> > stackprotector: prefer compiler for TLS based per-task protector"),
> > which breaks booting aspeed_g5_defconfig in QEMU with clang-14. It seems
> > like this patch depends on Ard's patch "ARM: decompressor: disable stack
> > protector" [1]; applying that on top of next-20220125 allows me to boot
> > again.
> >
> > This patch is still queued up in Russell's devel-stable branch as
> > commit f05eb1d24eb5 ("ARM: stackprotector: prefer compiler for TLS based
> > per-task protector") so perhaps this patch should be dropped from the
> > KSPP tree? I assume once Ard's recent fixes series [2] is applied to
> > devel-stable, it will be added back to for-next?
> >
> > [1]: https://lore.kernel.org/r/20220124174744.1054712-9-ardb at kernel.org/
> > [2]: https://lore.kernel.org/r/20220125091453.1475246-1-ardb at kernel.org/
> >
> 
> Yeah. better drop it from KSPP.
> 
> The problem is that the compiler version of the per-task
> stackprotector feature does not get disabled when building the
> decompressor, which means it ends up dereferencing bogus TLS register
> values.

Ooh! Whoops, sorry. Dropping.

-- 
Kees Cook


From clabbe at baylibre.com  Tue Jan 25 13:08:11 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Tue, 25 Jan 2022 21:08:11 +0000
Subject: [PATCH v2] net: ethernet: cortina: permit to set mac address in DT
Message-ID: <20220125210811.54350-1-clabbe@baylibre.com>

Add ability of setting mac address in DT for cortina ethernet driver.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
---
Changes since v1:
- fixed reverse christmas tree of the mac variable

 drivers/net/ethernet/cortina/gemini.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index c78b99a497df..8014eb33937c 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -2363,11 +2363,13 @@ static void gemini_port_save_mac_addr(struct gemini_ethernet_port *port)
 static int gemini_ethernet_port_probe(struct platform_device *pdev)
 {
 	char *port_names[2] = { "ethernet0", "ethernet1" };
+	struct device_node *np = pdev->dev.of_node;
 	struct gemini_ethernet_port *port;
 	struct device *dev = &pdev->dev;
 	struct gemini_ethernet *geth;
 	struct net_device *netdev;
 	struct device *parent;
+	u8 mac[ETH_ALEN];
 	unsigned int id;
 	int irq;
 	int ret;
@@ -2473,6 +2475,12 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev)
 	netif_napi_add(netdev, &port->napi, gmac_napi_poll,
 		       DEFAULT_NAPI_WEIGHT);
 
+	ret = of_get_mac_address(np, mac);
+	if (!ret) {
+		dev_info(dev, "Setting macaddr from DT %pM\n", mac);
+		memcpy(port->mac_addr, mac, ETH_ALEN);
+	}
+
 	if (is_valid_ether_addr((void *)port->mac_addr)) {
 		eth_hw_addr_set(netdev, (u8 *)port->mac_addr);
 	} else {
-- 
2.34.1



From ndesaulniers at google.com  Tue Jan 25 13:10:34 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 13:10:34 -0800
Subject: [PATCH] ep93xx: clock: Fix UAF in ep93xx_clk_register_gate()
In-Reply-To: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>
References: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>
Message-ID: <YfBm/xBJLDtU/fo5@google.com>

On Thu, Jan 20, 2022 at 02:37:38PM +0100, Alexander Sverdlin wrote:
> arch/arm/mach-ep93xx/clock.c:151:2: note: Taking true branch
> if (IS_ERR(clk))
> ^
> arch/arm/mach-ep93xx/clock.c:152:3: note: Memory is released
> kfree(psc);
> ^~~~~~~~~~
> arch/arm/mach-ep93xx/clock.c:154:2: note: Use of memory after it is freed
> return &psc->hw;
> ^ ~~~~~~~~
> 
> Link: https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org/thread/B5YCO2NJEXINCYE26Y255LCVMO55BGWW/
> Reported-by: kernel test robot <lkp at intel.com>
> Fixes: 9645ccc7bd7a ("ep93xx: clock: convert in-place to COMMON_CLK")
> Cc: stable at vger.kernel.org
> Signed-off-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
> ---
>  arch/arm/mach-ep93xx/clock.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
> index cc75087134d3..4aee14f18123 100644
> --- a/arch/arm/mach-ep93xx/clock.c
> +++ b/arch/arm/mach-ep93xx/clock.c
> @@ -148,8 +148,10 @@ static struct clk_hw *ep93xx_clk_register_gate(const char *name,
>  	psc->lock = &clk_lock;
>  
>  	clk = clk_register(NULL, &psc->hw);
> -	if (IS_ERR(clk))
> +	if (IS_ERR(clk)) {
>  		kfree(psc);
> +		return (void *)clk;

Prefer ERR_CAST to the raw cast. I think that's nicer when we're already
using the IS_ERR macros.

> +	}
>  
>  	return &psc->hw;
>  }
> -- 
> 2.34.1
> 


From ndesaulniers at google.com  Tue Jan 25 13:12:17 2022
From: ndesaulniers at google.com (Nick Desaulniers)
Date: Tue, 25 Jan 2022 13:12:17 -0800
Subject: [PATCH] ep93xx: clock: Fix UAF in ep93xx_clk_register_gate()
In-Reply-To: <YfBm/xBJLDtU/fo5@google.com>
References: <20220120133739.4170298-1-alexander.sverdlin@gmail.com>
 <YfBm/xBJLDtU/fo5@google.com>
Message-ID: <CAKwvOdno9jyF4Kmy3ygHANZCsqygQk0gW32Mc59j0Xe16rv6=w@mail.gmail.com>

On Tue, Jan 25, 2022 at 1:10 PM Nick Desaulniers
<ndesaulniers at google.com> wrote:
>
> On Thu, Jan 20, 2022 at 02:37:38PM +0100, Alexander Sverdlin wrote:

Also, consider adding the first line of the warning to your commit
message, please:
arch/arm/mach-ep93xx/clock.c:154:2: warning: Use of memory after it is
freed [clang-analyzer-unix.Malloc]

> > arch/arm/mach-ep93xx/clock.c:151:2: note: Taking true branch
> > if (IS_ERR(clk))
> > ^
> > arch/arm/mach-ep93xx/clock.c:152:3: note: Memory is released
> > kfree(psc);
> > ^~~~~~~~~~
> > arch/arm/mach-ep93xx/clock.c:154:2: note: Use of memory after it is freed
> > return &psc->hw;
> > ^ ~~~~~~~~
> >
> > Link: https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org/thread/B5YCO2NJEXINCYE26Y255LCVMO55BGWW/
> > Reported-by: kernel test robot <lkp at intel.com>
> > Fixes: 9645ccc7bd7a ("ep93xx: clock: convert in-place to COMMON_CLK")
> > Cc: stable at vger.kernel.org
> > Signed-off-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
> > ---
> >  arch/arm/mach-ep93xx/clock.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
> > index cc75087134d3..4aee14f18123 100644
> > --- a/arch/arm/mach-ep93xx/clock.c
> > +++ b/arch/arm/mach-ep93xx/clock.c
> > @@ -148,8 +148,10 @@ static struct clk_hw *ep93xx_clk_register_gate(const char *name,
> >       psc->lock = &clk_lock;
> >
> >       clk = clk_register(NULL, &psc->hw);
> > -     if (IS_ERR(clk))
> > +     if (IS_ERR(clk)) {
> >               kfree(psc);
> > +             return (void *)clk;
>
> Prefer ERR_CAST to the raw cast. I think that's nicer when we're already
> using the IS_ERR macros.
>
> > +     }
> >
> >       return &psc->hw;
> >  }
> > --
> > 2.34.1
> >



-- 
Thanks,
~Nick Desaulniers


From David.Laight at ACULAB.COM  Tue Jan 25 14:17:38 2022
From: David.Laight at ACULAB.COM (David Laight)
Date: Tue, 25 Jan 2022 22:17:38 +0000
Subject: [PATCH] pinctrl: fix a discarded-qualifiers build error
In-Reply-To: <20220125175457.23728-1-miles.chen@mediatek.com>
References: <20220125175457.23728-1-miles.chen@mediatek.com>
Message-ID: <693a71e17b364afd987f2d2178b7e5cb@AcuMS.aculab.com>

From: Miles Chen
> Sent: 25 January 2022 17:55
> 
> Fix COMPILER=gcc ARCH=arm64 DEFCONFIG=allyesconfig build:
> 
> log:
> drivers/pinctrl/pinctrl-thunderbay.c:815:29: error: assignment discards
> 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> 
> Fixes: 12422af8194d ("pinctrl: Add Intel Thunder Bay pinctrl driver")
> Signed-off-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/pinctrl/pinctrl-thunderbay.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-thunderbay.c b/drivers/pinctrl/pinctrl-thunderbay.c
> index b5b47f4dd774..4e6d718c03fc 100644
> --- a/drivers/pinctrl/pinctrl-thunderbay.c
> +++ b/drivers/pinctrl/pinctrl-thunderbay.c
> @@ -812,7 +812,7 @@ static int thunderbay_add_functions(struct thunderbay_pinctrl *tpc, struct funct
>  				}
>  			}
> 
> -			grp = func->group_names;
> +			grp = (const char **)func->group_names;

You should change the type of 'grp' not add a cast.
The compiler can warn about casts removing 'const' as well.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)



From sboyd at kernel.org  Tue Jan 25 14:19:31 2022
From: sboyd at kernel.org (Stephen Boyd)
Date: Tue, 25 Jan 2022 14:19:31 -0800
Subject: [PATCH RESEND 0/6] clk: imx6*: avoid GPMI clock glitches on
 reparenting/divider change
In-Reply-To: <20220125144441.17750-1-ceggers@arri.de>
References: <20220125144441.17750-1-ceggers@arri.de>
Message-ID: <20220125221933.8DDFEC340E0@smtp.kernel.org>

Quoting Christian Eggers (2022-01-25 06:44:35)
> RESEND because the series got corrupted on first tranmission

Still looks corrupted :(


From andrew at lunn.ch  Tue Jan 25 14:30:59 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 25 Jan 2022 23:30:59 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <20220125194609.32314-1-nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
Message-ID: <YfB6I5PRPlHPxwLP@lunn.ch>

> +		mdio0: mdio at c0004080 {
> +			compatible = "hpe,gxp-umac-mdio";
> +			reg = <0xc0004080 0x10>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			ext_phy0: ethernt-phy at 0 {
> +				compatible = "ethernet-phy-ieee802.3-c22";

c22 is the default, so you don't strictly need this.

> +				phy-mode = "sgmii";
> +				reg = <0>;
> +			};
> +		};
> +
> +		mdio1: mdio at c0005080 {
> +			compatible = "hpe,gxp-umac-mdio";
> +			reg = <0xc0005080 0x10>;
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			int_phy0: ethernt-phy at 0 {
> +				compatible = "ethernet-phy-ieee802.3-c22";
> +				phy-mode = "gmii";
> +				reg = <0>;
> +			};
> +			int_phy1: ethernt-phy at 1 {
> +				compatible = "ethernet-phy-ieee802.3-c22";
> +				phy-mode = "gmii";
> +				reg = <1>;
> +			};
> +		};
> +
> +		umac0: umac at c0004000 {
> +			compatible = "hpe, gxp-umac";

A space in a compatible? 

> +			reg = <0xc0004000 0x80>;
> +			interrupts = <10>;
> +			interrupt-parent = <&vic0>;
> +			mac-address = [94 18 82 16 04 d8];

That is pretty unusual. Normally you leave the bootloader to fill this
in with a per board MAC address. The danger with listing it here is
that you have multiple boards in the same network using this MAC
address, and then bad things happen.

> +			phy-handle = <&ext_phy0>;
> +			int-phy-handle = <&int_phy0>;

Two phy-handles? Some very odd going on here!

> +		xreg_kyes: xreg_keys {
> +			compatible = "gpio-keys-polled";
> +			poll-interval = <100>;
> +
> +			IdButton {
> +				label = "ID Button";
> +				linux,code = <200>;

include/dt-bindings/input/linux-event-codes.h 

However

#define KEY_PLAYCD              200

A BMC has a CD player? Maybe i have this wrong?

> +			PortOwner at 0 {
> +				label = "Port Owner";
> +				linux,code = <200>;
> +				gpios = <&gpio 250 1>;

Two CD players?

> +			};
> +
> +			PortOwner at 1 {
> +				label = "Port Owner";
> +				linux,code = <201>;

#define KEY_PAUSECD             201

And you can pause the second player?

    Andrew


From andrew at lunn.ch  Tue Jan 25 14:46:46 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Tue, 25 Jan 2022 23:46:46 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <20220125194609.32314-1-nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
Message-ID: <YfB91lWAtBgNLaGQ@lunn.ch>

> +		umac0: umac at c0004000 {
> +			compatible = "hpe, gxp-umac";
> +			reg = <0xc0004000 0x80>;
> +			interrupts = <10>;
> +			interrupt-parent = <&vic0>;
> +			mac-address = [94 18 82 16 04 d8];
> +			phy-handle = <&ext_phy0>;
> +			int-phy-handle = <&int_phy0>;
> +		};

I suggest you don't add any DT for drivers which have not been
accepted yet. When you MAC driver is posted to netdev, the DT binding
will get reviewed. And i expect int-phy-handle will be rejected.

Often the first dtsi and dts submission for a new SoC have just the
CPUs and the serial port, since none of the other drivers have been
reviewed yet, unless they reuse existing drivers. The additional nodes
are then added one by one as the drivers get accepted.

	 Andrew


From ilkka at os.amperecomputing.com  Tue Jan 25 15:04:13 2022
From: ilkka at os.amperecomputing.com (Ilkka Koskinen)
Date: Tue, 25 Jan 2022 15:04:13 -0800 (PST)
Subject: [PATCH v3 2/2] ACPI: AGDI: Add driver for Arm Generic Diagnostic
 Dump and Reset device
In-Reply-To: <20220120163819.GA8187@lpieralisi>
References: <20211231033725.21109-1-ilkka@os.amperecomputing.com>
 <20211231033725.21109-3-ilkka@os.amperecomputing.com>
 <20220105104602.GA4752@lpieralisi>
 <alpine.DEB.2.22.394.2201051530290.2489@ubuntu200401>
 <alpine.DEB.2.22.394.2201131801380.3166@ubuntu200401>
 <20220120163819.GA8187@lpieralisi>
Message-ID: <alpine.DEB.2.22.394.2201251458550.2578@ubuntu200401>



On Thu, 20 Jan 2022, Lorenzo Pieralisi wrote:

> On Thu, Jan 13, 2022 at 06:17:13PM -0800, Ilkka Koskinen wrote:
>>
>> Hi Lorenzo,
>>
>> On Wed, 5 Jan 2022, Ilkka Koskinen wrote:
>>>
>>> Hi Lorenzo,
>>>
>>> On Wed, 5 Jan 2022, Lorenzo Pieralisi wrote:
>>>> [+James, for SDEI bits]
>>>>
>>>> On Thu, Dec 30, 2021 at 07:37:25PM -0800, Ilkka Koskinen wrote:
>>>>> ACPI for Arm Components 1.1 Platform Design Document v1.1 [0] specifices
>>>>> Arm Generic Diagnostic Device Interface (AGDI). It allows an admin to
>>>>> issue diagnostic dump and reset via an SDEI event or an interrupt.
>>>>> This patch implements SDEI path.
>>>>>
>>>>> [0] https://developer.arm.com/documentation/den0093/latest/
>>>>>
>>>>> Signed-off-by: Ilkka Koskinen <ilkka at os.amperecomputing.com>
>>>>> ---
>>>>>  drivers/acpi/arm64/Kconfig  |   8 +++
>>>>>  drivers/acpi/arm64/Makefile |   1 +
>>>>>  drivers/acpi/arm64/agdi.c   | 125 ++++++++++++++++++++++++++++++++++++
>>>>>  3 files changed, 134 insertions(+)
>>>>>  create mode 100644 drivers/acpi/arm64/agdi.c
>>
>> <snip>
>>
>>>>> diff --git a/drivers/acpi/arm64/agdi.c b/drivers/acpi/arm64/agdi.c
>>>>> new file mode 100644
>>>>> index 000000000000..6525ccbae5c1
>>>>> --- /dev/null
>>>>> +++ b/drivers/acpi/arm64/agdi.c
>>
>> <snip>
>>
>>>>>
>>>>> +static int __init agdi_init(void)
>>>>> +{
>>>>> +	int ret;
>>>>> +	acpi_status status;
>>>>> +	struct acpi_table_agdi *agdi_table;
>>>>> +	struct agdi_data pdata;
>>>>> +	struct platform_device *pdev;
>>>>> +
>>>>> +	if (acpi_disabled)
>>>>> +		return 0;
>>>>
>>>> Why don't we call agdi_init() from acpi_init() as we do for IORT/VIOT ?
>>>>
>>>> I don't think it is necessary to add a device_initcall(), with related
>>>> ordering dependencies.
>>>
>>> That's a good point. I change it.
>>
>> Actually, I looked at this more carefully. acpi_init() is called in
>> subsys_initcall() while sdei_init() is called in subsys_initcall_sync().
>> That is, if I call this function in acpi_init(), SDEI driver won't be ready
>> and this driver fails to register the event.
>
> Maybe this will help:
>
> https://lore.kernel.org/linux-arm-kernel/20220120050522.23689-1-xueshuai at linux.alibaba.com/

Yep, that should work. I'll wait for his patch to get approved and make 
the needed changes to mine before submitting the v5.

Cheers, Ilkka


From arnd at arndb.de  Tue Jan 25 16:22:27 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Wed, 26 Jan 2022 01:22:27 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <20220125194609.32314-1-nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
Message-ID: <CAK8P3a0ccoH_sNE9eWxQnWHEWNBPFL6k4k6mku=cHs_fRfnL-w@mail.gmail.com>

'On Tue, Jan 25, 2022 at 8:46 PM <nick.hawkins at hpe.com> wrote:
>
> From: Nick Hawkins <nick.hawkins at hpe.com>
>
> Signed-off-by: Nick Hawkins <nick.hawkins at hpe.com>

Hi Nick,

Thanks for your submission, it's always nice to see support for a new platform.

I assume that you have a number of other drivers that are required for
an initial
support, at least to get you booting into a shell. I recommend to keep
those together
as a series, and we can merge them through the soc tree initially, with an Ack
from the corresponding subsystem maintainers. For later updates to the drivers,
you should send them to the maintainers directly, same for any
non-essential drivers

Krzysztof already commented on most issues I see, here are a few more things
to consider:

>
> +GXP ARCHITECTURE

Make this "ARM/HPE GXP ARCHITECTURE", so it does not get mistaken
for a separate instruction set architecture, or something else with that three
letter acronym.

> +
> +/dts-v1/;
> +/ {
> +  #address-cells = <1>;
> +  #size-cells = <1>;
> +       compatible = "HPE,GXP";
> +       model = "GXP";

Make this the specific machine rather than the SoC, unless you can guarantee
that there won't ever be another board revision made from the same SoC (family).

> +       chosen {
> +               bootargs = "earlyprintk console=ttyS0,115200 user_debug=31";
> +       };

The bootargs should be set by the bootloader. In particular there should be
not 'earlyprintk' by default, and the console should be selected using the
'stdout-path' property.

You seem to be missing CPU nodes.

> +
> +               usb0: ehci at cefe0000 {
> +                       compatible = "generic-ehci";
> +                       reg = <0xcefe0000 0x100>;
> +                       interrupts = <7>;
> +                       interrupt-parent = <&vic0>;
> +               };
> +
> +               usb1: ohci at cefe0100 {
> +                       compatible = "generic-ohci";
> +                       reg = <0xcefe0100 0x110>;
> +                       interrupts = <6>;
> +                       interrupt-parent = <&vic0>;
> +               };

Add a custom compatible string as a specialization in case you ever
need to work around some quirk on these devices.

> +               spifi0: spifi at c0000200 {
> +                       compatible = "hpe,gxp-spifi";
> +                       reg = <0xc0000200 0x80>, <0xc000c000 0x100>, <0xf8000000 0x8000000>;
> +                       interrupts = <20>;
> +                       interrupt-parent = <&vic0>;
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       flash at 0 {
> +                               compatible = "jedec,spi-nor";
> +                               reg = <0>;
> +                               partitions {
> +                                       compatible = "fixed-partitions";
> +                                       #address-cells = <1>;
> +                                       #size-cells = <1>;
> +
> +                                       bmc at 0 {
> +                                               label = "bmc";
> +                                               reg = <0x0 0x2000000>;
> +                                       };
> +                                       u-boot at 0 {
> +                                               label = "u-boot";
> +                                               reg = <0x0 0x60000>;
> +                                       };


The partitions should ideally be set by the bootloader as well, or
at least be in the .dts file separately from the soc .dtsi file.

> diff --git a/arch/arm/configs/gxp_defconfig b/arch/arm/configs/gxp_defconfig
> new file mode 100644
> index 000000000000..f37c6630e06d
> --- /dev/null
> +++ b/arch/arm/configs/gxp_defconfig

Do you have a strong reason for needing a custom defconfig file?
Usually this should
work with the normal multi_v7_defconfig.


> diff --git a/arch/arm/mach-hpe/Kconfig b/arch/arm/mach-hpe/Kconfig
> new file mode 100644
> index 000000000000..9b27f97c6536
> --- /dev/null
> +++ b/arch/arm/mach-hpe/Kconfig
> @@ -0,0 +1,20 @@
> +menuconfig ARCH_HPE
> +       bool "HPE SoC support"
> +       help
> +         This enables support for HPE ARM based SoC chips
> +if ARCH_HPE
> +
> +config ARCH_HPE_GXP
> +       bool "HPE GXP SoC"
> +       select ARM_VIC
> +       select PINCTRL
> +       select IRQ_DOMAIN
> +       select GENERIC_IRQ_CHIP
> +       select MULTI_IRQ_HANDLER
> +       select SPARSE_IRQ
> +       select CLKSRC_MMIO
> +       depends on ARCH_MULTI_V7


Most of the symbols you select are implied by ARCH_MULTI_V7, so you
can remove them here.

> +#define IOP_REGS_PHYS_BASE 0xc0000000
> +#define IOP_REGS_VIRT_BASE 0xf0000000
> +#define IOP_REGS_SIZE (240*SZ_1M)

We don't normally do custom mappings any more, these should come from
the device tree and get mapped by the corresponding drivers.

> +#define IOP_EHCI_USBCMD 0x0efe0010
> +
> +static struct map_desc gxp_io_desc[] __initdata = {
> +       {
> +       .virtual        = (unsigned long)IOP_REGS_VIRT_BASE,
> +       .pfn            = __phys_to_pfn(IOP_REGS_PHYS_BASE),
> +       .length         = IOP_REGS_SIZE,
> +       .type           = MT_DEVICE,
> +       },
> +};
> +
> +void __init gxp_map_io(void)
> +{
> +       iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
> +}
> +
> +static void __init gxp_dt_init(void)
> +{
> +       //reset EHCI host controller for clear start
> +       __raw_writel(0x00080002,
> +               (void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));

This belongs into the bootloader, or the EHCI driver, see the comment about a
custom compatible value above ;-)

> +static void gxp_restart(enum reboot_mode mode, const char *cmd)
> +{
> +       pr_info("gpx restart");
> +       __raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
> +}

This should be a reset driver, see
drivers/power/reset/syscon-reboot.c either as an example, or something you
can use directly.

         Arnd


From kuba at kernel.org  Tue Jan 25 16:37:55 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:37:55 -0800
Subject: [PATCH net v2 0/6] ethernet: fix some esoteric drivers after
 netdev->dev_addr constification
Message-ID: <20220126003801.1736586-1-kuba@kernel.org>

Looking at recent fixes for drivers which don't get included with
allmodconfig builds I thought it's worth grepping for more instances of:

  dev->dev_addr\[.*\] = 

This set contains the fixes.

v2: add last 3 patches which fix drivers for the RiscPC ARM platform.
Thanks to Arnd Bergmann for explaining how to build test that.

Jakub Kicinski (6):
  ethernet: 3com/typhoon: don't write directly to netdev->dev_addr
  ethernet: tundra: don't write directly to netdev->dev_addr
  ethernet: broadcom/sb1250-mac: don't write directly to
    netdev->dev_addr
  ethernet: i825xx: don't write directly to netdev->dev_addr
  ethernet: 8390/etherh: don't write directly to netdev->dev_addr
  ethernet: seeq/ether3: don't write directly to netdev->dev_addr

 drivers/net/ethernet/3com/typhoon.c        |  6 ++--
 drivers/net/ethernet/8390/etherh.c         |  6 ++--
 drivers/net/ethernet/broadcom/sb1250-mac.c |  4 +--
 drivers/net/ethernet/i825xx/ether1.c       |  4 ++-
 drivers/net/ethernet/seeq/ether3.c         |  4 ++-
 drivers/net/ethernet/tundra/tsi108_eth.c   | 35 +++++++++++-----------
 6 files changed, 33 insertions(+), 26 deletions(-)

-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:37:58 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:37:58 -0800
Subject: [PATCH net v2 3/6] ethernet: broadcom/sb1250-mac: don't write
 directly to netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-4-kuba@kernel.org>

netdev->dev_addr is const now.

Compile tested bigsur_defconfig and sb1250_swarm_defconfig.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/broadcom/sb1250-mac.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c
index f38f40eb966e..a1a38456c9a3 100644
--- a/drivers/net/ethernet/broadcom/sb1250-mac.c
+++ b/drivers/net/ethernet/broadcom/sb1250-mac.c
@@ -2183,9 +2183,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
 		ea_reg >>= 8;
 	}
 
-	for (i = 0; i < 6; i++) {
-		dev->dev_addr[i] = eaddr[i];
-	}
+	eth_hw_addr_set(dev, eaddr);
 
 	/*
 	 * Initialize context (get pointers to registers and stuff), then
-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:37:59 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:37:59 -0800
Subject: [PATCH net v2 4/6] ethernet: i825xx: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-5-kuba@kernel.org>

netdev->dev_addr is const now.

Compile tested rpc_defconfig w/ GCC 8.5.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/i825xx/ether1.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/i825xx/ether1.c b/drivers/net/ethernet/i825xx/ether1.c
index c612ef526d16..3e7d7c4bafdc 100644
--- a/drivers/net/ethernet/i825xx/ether1.c
+++ b/drivers/net/ethernet/i825xx/ether1.c
@@ -986,6 +986,7 @@ static int
 ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
 	struct net_device *dev;
+	u8 addr[ETH_ALEN];
 	int i, ret = 0;
 
 	ether1_banner();
@@ -1015,7 +1016,8 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
 	}
 
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(IDPROM_ADDRESS + (i << 2));
+		addr[i] = readb(IDPROM_ADDRESS + (i << 2));
+	eth_hw_addr_set(dev, addr);
 
 	if (ether1_init_2(dev)) {
 		ret = -ENODEV;
-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:38:00 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:38:00 -0800
Subject: [PATCH net v2 5/6] ethernet: 8390/etherh: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-6-kuba@kernel.org>

netdev->dev_addr is const now.

Compile tested rpc_defconfig w/ GCC 8.5.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/8390/etherh.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c
index bd22a534b1c0..e7b879123bb1 100644
--- a/drivers/net/ethernet/8390/etherh.c
+++ b/drivers/net/ethernet/8390/etherh.c
@@ -655,6 +655,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
 	struct ei_device *ei_local;
 	struct net_device *dev;
 	struct etherh_priv *eh;
+	u8 addr[ETH_ALEN];
 	int ret;
 
 	ret = ecard_request_resources(ec);
@@ -724,12 +725,13 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
 	spin_lock_init(&ei_local->page_lock);
 
 	if (ec->cid.product == PROD_ANT_ETHERM) {
-		etherm_addr(dev->dev_addr);
+		etherm_addr(addr);
 		ei_local->reg_offset = etherm_regoffsets;
 	} else {
-		etherh_addr(dev->dev_addr, ec);
+		etherh_addr(addr, ec);
 		ei_local->reg_offset = etherh_regoffsets;
 	}
+	eth_hw_addr_set(dev, addr);
 
 	ei_local->name          = dev->name;
 	ei_local->word16        = 1;
-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:37:57 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:37:57 -0800
Subject: [PATCH net v2 2/6] ethernet: tundra: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-3-kuba@kernel.org>

netdev->dev_addr is const now.

Maintain the questionable offsetting in ndo_set_mac_address.

Compile tested holly_defconfig and mpc7448_hpc2_defconfig.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/tundra/tsi108_eth.c | 35 ++++++++++++------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c
index cf0917b29e30..5251fc324221 100644
--- a/drivers/net/ethernet/tundra/tsi108_eth.c
+++ b/drivers/net/ethernet/tundra/tsi108_eth.c
@@ -1091,20 +1091,22 @@ static int tsi108_get_mac(struct net_device *dev)
 	struct tsi108_prv_data *data = netdev_priv(dev);
 	u32 word1 = TSI_READ(TSI108_MAC_ADDR1);
 	u32 word2 = TSI_READ(TSI108_MAC_ADDR2);
+	u8 addr[ETH_ALEN];
 
 	/* Note that the octets are reversed from what the manual says,
 	 * producing an even weirder ordering...
 	 */
 	if (word2 == 0 && word1 == 0) {
-		dev->dev_addr[0] = 0x00;
-		dev->dev_addr[1] = 0x06;
-		dev->dev_addr[2] = 0xd2;
-		dev->dev_addr[3] = 0x00;
-		dev->dev_addr[4] = 0x00;
+		addr[0] = 0x00;
+		addr[1] = 0x06;
+		addr[2] = 0xd2;
+		addr[3] = 0x00;
+		addr[4] = 0x00;
 		if (0x8 == data->phy)
-			dev->dev_addr[5] = 0x01;
+			addr[5] = 0x01;
 		else
-			dev->dev_addr[5] = 0x02;
+			addr[5] = 0x02;
+		eth_hw_addr_set(dev, addr);
 
 		word2 = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 24);
 
@@ -1114,12 +1116,13 @@ static int tsi108_get_mac(struct net_device *dev)
 		TSI_WRITE(TSI108_MAC_ADDR1, word1);
 		TSI_WRITE(TSI108_MAC_ADDR2, word2);
 	} else {
-		dev->dev_addr[0] = (word2 >> 16) & 0xff;
-		dev->dev_addr[1] = (word2 >> 24) & 0xff;
-		dev->dev_addr[2] = (word1 >> 0) & 0xff;
-		dev->dev_addr[3] = (word1 >> 8) & 0xff;
-		dev->dev_addr[4] = (word1 >> 16) & 0xff;
-		dev->dev_addr[5] = (word1 >> 24) & 0xff;
+		addr[0] = (word2 >> 16) & 0xff;
+		addr[1] = (word2 >> 24) & 0xff;
+		addr[2] = (word1 >> 0) & 0xff;
+		addr[3] = (word1 >> 8) & 0xff;
+		addr[4] = (word1 >> 16) & 0xff;
+		addr[5] = (word1 >> 24) & 0xff;
+		eth_hw_addr_set(dev, addr);
 	}
 
 	if (!is_valid_ether_addr(dev->dev_addr)) {
@@ -1136,14 +1139,12 @@ static int tsi108_set_mac(struct net_device *dev, void *addr)
 {
 	struct tsi108_prv_data *data = netdev_priv(dev);
 	u32 word1, word2;
-	int i;
 
 	if (!is_valid_ether_addr(addr))
 		return -EADDRNOTAVAIL;
 
-	for (i = 0; i < 6; i++)
-		/* +2 is for the offset of the HW addr type */
-		dev->dev_addr[i] = ((unsigned char *)addr)[i + 2];
+	/* +2 is for the offset of the HW addr type */
+	eth_hw_addr_set(dev, ((unsigned char *)addr) + 2);
 
 	word2 = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 24);
 
-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:37:56 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:37:56 -0800
Subject: [PATCH net v2 1/6] ethernet: 3com/typhoon: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-2-kuba@kernel.org>

This driver casts off the const and writes directly to netdev->dev_addr.
This will result in a MAC address tree corruption and a warning.

Compile tested ppc6xx_defconfig.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/3com/typhoon.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/3com/typhoon.c b/drivers/net/ethernet/3com/typhoon.c
index 481f1df3106c..8aec5d9fbfef 100644
--- a/drivers/net/ethernet/3com/typhoon.c
+++ b/drivers/net/ethernet/3com/typhoon.c
@@ -2278,6 +2278,7 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	struct net_device *dev;
 	struct typhoon *tp;
 	int card_id = (int) ent->driver_data;
+	u8 addr[ETH_ALEN] __aligned(4);
 	void __iomem *ioaddr;
 	void *shared;
 	dma_addr_t shared_dma;
@@ -2409,8 +2410,9 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto error_out_reset;
 	}
 
-	*(__be16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1));
-	*(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
+	*(__be16 *)&addr[0] = htons(le16_to_cpu(xp_resp[0].parm1));
+	*(__be32 *)&addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2));
+	eth_hw_addr_set(dev, addr);
 
 	if (!is_valid_ether_addr(dev->dev_addr)) {
 		err_msg = "Could not obtain valid ethernet address, aborting";
-- 
2.34.1



From kuba at kernel.org  Tue Jan 25 16:38:01 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 16:38:01 -0800
Subject: [PATCH net v2 6/6] ethernet: seeq/ether3: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <20220126003801.1736586-7-kuba@kernel.org>

netdev->dev_addr is const now.

Compile tested rpc_defconfig w/ GCC 8.5.

Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
Signed-off-by: Jakub Kicinski <kuba at kernel.org>
---
 drivers/net/ethernet/seeq/ether3.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c
index 16a4cbae9326..c672f92d65e9 100644
--- a/drivers/net/ethernet/seeq/ether3.c
+++ b/drivers/net/ethernet/seeq/ether3.c
@@ -749,6 +749,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 	const struct ether3_data *data = id->data;
 	struct net_device *dev;
 	int bus_type, ret;
+	u8 addr[ETH_ALEN];
 
 	ether3_banner();
 
@@ -776,7 +777,8 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
 	priv(dev)->seeq = priv(dev)->base + data->base_offset;
 	dev->irq = ec->irq;
 
-	ether3_addr(dev->dev_addr, ec);
+	ether3_addr(addr, ec);
+	eth_hw_addr_set(dev, addr);
 
 	priv(dev)->dev = dev;
 	timer_setup(&priv(dev)->timer, ether3_ledoff, 0);
-- 
2.34.1



From hayashi.kunihiko at socionext.com  Tue Jan 25 17:19:13 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Wed, 26 Jan 2022 10:19:13 +0900
Subject: [PATCH] spi: uniphier: fix reference count leak in
 uniphier_spi_probe()
In-Reply-To: <20220125101214.35677-1-xiongx18@fudan.edu.cn>
References: <20220125101214.35677-1-xiongx18@fudan.edu.cn>
Message-ID: <e3283f14-adf1-ac3c-3454-80ff68b7d71f@socionext.com>

On 2022/01/25 19:12, Xin Xiong wrote:
> The issue happens in several error paths in uniphier_spi_probe().
> When either dma_get_slave_caps() or devm_spi_register_master() returns
> an error code, the function forgets to decrease the refcount of both
> `dma_rx` and `dma_tx` objects, which may lead to refcount leaks.
> 
> Fix it by decrementing the reference count of specific objects in
> those error paths.

Looks good to me.

Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>

And it is necessary to add the following line to this according to
Documentation/process/submitting-patches.rst.

Fixes: 28d1dddc59f6 ("spi: uniphier: Add DMA transfer mode support")

Thank you,

> Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
> Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
> Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>
> ---
>   drivers/spi/spi-uniphier.c | 18 ++++++++++++++----
>   1 file changed, 14 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
> index 342ee8d2c..cc0da4822 100644
> --- a/drivers/spi/spi-uniphier.c
> +++ b/drivers/spi/spi-uniphier.c
> @@ -726,7 +726,7 @@ static int uniphier_spi_probe(struct platform_device
> *pdev)
>   		if (ret) {
>   			dev_err(&pdev->dev, "failed to get TX DMA
> capacities: %d\n",
>   				ret);
> -			goto out_disable_clk;
> +			goto out_release_dma;
>   		}
>   		dma_tx_burst = caps.max_burst;
>   	}
> @@ -735,7 +735,7 @@ static int uniphier_spi_probe(struct platform_device
> *pdev)
>   	if (IS_ERR_OR_NULL(master->dma_rx)) {
>   		if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) {
>   			ret = -EPROBE_DEFER;
> -			goto out_disable_clk;
> +			goto out_release_dma;
>   		}
>   		master->dma_rx = NULL;
>   		dma_rx_burst = INT_MAX;
> @@ -744,7 +744,7 @@ static int uniphier_spi_probe(struct platform_device
> *pdev)
>   		if (ret) {
>   			dev_err(&pdev->dev, "failed to get RX DMA
> capacities: %d\n",
>   				ret);
> -			goto out_disable_clk;
> +			goto out_release_dma;
>   		}
>   		dma_rx_burst = caps.max_burst;
>   	}
> @@ -753,10 +753,20 @@ static int uniphier_spi_probe(struct platform_device
> *pdev)
>   
>   	ret = devm_spi_register_master(&pdev->dev, master);
>   	if (ret)
> -		goto out_disable_clk;
> +		goto out_release_dma;
>   
>   	return 0;
>   
> +out_release_dma:
> +	if (!IS_ERR_OR_NULL(master->dma_rx)) {
> +		dma_release_channel(master->dma_rx);
> +		master->dma_rx = NULL;
> +	}
> +	if (!IS_ERR_OR_NULL(master->dma_tx)) {
> +		dma_release_channel(master->dma_tx);
> +		master->dma_tx = NULL;
> +	}
> +
>   out_disable_clk:
>   	clk_disable_unprepare(priv->clk);
>   
> 

-- 
---
Best Regards
Kunihiko Hayashi


From ricarkol at google.com  Tue Jan 25 17:23:00 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Tue, 25 Jan 2022 17:23:00 -0800
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220125192851.3907611-1-broonie@kernel.org>
References: <20220125192851.3907611-1-broonie@kernel.org>
Message-ID: <YfCidIboLDMb/Hy3@google.com>

On Tue, Jan 25, 2022 at 07:28:51PM +0000, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 5 +++++
>  tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>  3 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 9ad38bd360a4..791d38404652 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
>  {
>  	struct kvm_vm *vm;
>  	unsigned int i;
> +	int ret;
>  	int nr_vcpus = test_args.nr_vcpus;
>  
>  	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
> @@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
>  
>  	ucall_init(vm, NULL);
>  	test_init_timer_irq(vm);
> -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (ret < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");
> +		exit(KSFT_SKIP);
> +	}
>  
>  	/* Make all the test's cmdline args visible to the guest */
>  	sync_global_to_guest(vm, test_args);
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> index e6c7d7f8fbd1..8c6b61b8e6aa 100644
> --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> @@ -761,6 +761,11 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
>  
>  	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
>  			GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (gic_fd < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");
> +		exit(KSFT_SKIP);
> +	}
> +
>  
>  	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
>  		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..647c18733e1b 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>  			nr_vcpus, nr_vcpus_created);
>  
>  	/* Distributor setup */
> -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
> +	if (gic_fd == -1)
> +		return -1;
>  
>  	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
>  			0, &nr_irqs, true);
> -- 
> 2.30.2
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Reviewed-by: Ricardo Koller <ricarkol at google.com>


From f.fainelli at gmail.com  Tue Jan 25 17:33:02 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Tue, 25 Jan 2022 17:33:02 -0800
Subject: DTB backward/forward compatibility with "pinctrl: bcm2835: Change
 init order for gpio hogs"
In-Reply-To: <63cecd52-6808-d31e-3eb6-a17e692a4190@gmail.com>
References: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>
 <c04d26a5-16e9-44a7-8b75-a04df9f7bfb6@raspberrypi.com>
 <63cecd52-6808-d31e-3eb6-a17e692a4190@gmail.com>
Message-ID: <e1f1dcec-3cfb-8f7f-f3de-04c586ee30d9@gmail.com>



On 1/25/2022 11:58 AM, Florian Fainelli wrote:
> 
> 
> On 1/25/2022 11:48 AM, Phil Elwell wrote:
>> Florian,
>>
>> On 25/01/2022 19:39, Florian Fainelli wrote:
>>> Hi,
>>>
>>> I am a bit frustrated by this commit, we picked it up via the stable 
>>> 5.10 and 5.15 trees into our downstream tree, and in the absence of a 
>>> suitable 'gpio-ranges' property for the GPIO controller, the SPI 
>>> controller keeps getting -EPROBE_DEFER for its chip select. If the 
>>> property is present, then all is well.
>>>
>>> Now the problem in my case is that the boot loader is responsible for 
>>> providing the DTB to the kernel, and until recently, we did not 
>>> update it to contain a suitable 'gpio-ranges' property. Now that it 
>>> has been updated however, older kernels which *do not* have said 
>>> change in the subject are also getting -EPROBE_DEFER for the SPI chip 
>>> select.
>>>
>>> So this is just breaking backward/forward compatibility with the DTB 
>>> unless both are updated in lock steps which is *extremely* inconvenient.
>>>
>>> This is death by a thousand cuts.
>>>
>>> So how do we remedy this?
>>
>> It's unfortunate that both the DTS and driver were incorrect, and that 
>> the fixes were inter-dependent. At Raspberry Pi we make a point of 
>> treating the DTBs as part of the kernel, updating them at the same 
>> time. Is that not possible in your situation? You don't specify which 
>> bootloader you are using (or even which platform), but U-boot can be 
>> configured to use the DTB loaded and adjusted by the firmware.
> 
> We use a boot loader called BOLT which has an offline DTS generation 
> part an a runtime patching part. At no point in time has it been 
> necessary, desirable or even reliably possible to look at the kernel 
> version and mangle the Device Tree such that "things" work. I do not 
> even want to fathom what the code doing that would look like other than 
> a big pile of mess. This is utterly error prone and completely breaks 
> the boot loader/kernel abstraction.
> 
> We strive to be able to update the boot loader and the kernel seemingly 
> independently from one another even though obviously there are times 
> where locksteps are necessary. What I like to do is:
> 
> - put the changes in the DTB that are necessary for a *future* kernel 
> well in advance such that by the time that newer kernel gets used these 
> properties are already there
> 
> - adding new properties does not break older kernels, they simply ignore 
> them
> 
> And this allows us to define a combination that always works while 
> having a sliding window of backward/forward compatibility if we have 
> locksteps in between.
> 
> I can make changes in the downstream kernel such that we prune DT 
> properties, but once we open that door, the list goes on and on and it 
> is just a damage control strategy anyway.
> 
> Why cannot the pinctrl framework infer that we have a 1:1 mapping in the 
> absence of a 'gpio-ranges' property, but instead does the following:
> 
> # cat /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
> GPIO ranges handled:
> 0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
> #
> 
> clearly it determined the end GPIO but it is not able to determine the 
> start GPIO?
> 
> And now, on a 5.10 kernel which does contain both the 'gpio-ranges' 
> property and the said change to pinctrl-bcm2835.c I have this:
> 
> # cat /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
> GPIO ranges handled:
> 0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
> 0: pinctrl-bcm2711 GPIOS [454 - 511] PINS [0 - 57]
> #
> 
> What the heck?

And just to be clear, at this point I understand that the old kernel, 
new DTB/DTS is not something we can obviously fix, however new kernel 
old DTB/DTS *without* 'gpio-ranges' is something that should still work 
to ease the pain.

I will dig more into why we have this duplicated debugfs output (most 
likely we are not unwinding an error path when we get -EPROBE_DEFER) and 
also why pinctrl is not able to figure out the gpio start properly 
without 'gpio-ranges'.
-- 
Florian


From jammy_huang at aspeedtech.com  Tue Jan 25 17:41:27 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 26 Jan 2022 09:41:27 +0800
Subject: [PATCH v4 0/2] Fix incorrect resolution detected
In-Reply-To: <c3202b1f-ff8f-8108-e8a3-8710c8c74d10@xs4all.nl>
References: <20220118100729.7651-1-jammy_huang@aspeedtech.com>
 <c3202b1f-ff8f-8108-e8a3-8710c8c74d10@xs4all.nl>
Message-ID: <8681fe29-69c2-f701-aff4-c27cef2d32d7@aspeedtech.com>


On 2022/1/25 ?? 06:43, Hans Verkuil wrote:
> Hi Jammy,
>
> On 18/01/2022 11:07, Jammy Huang wrote:
>> This series fixes incorrect resolution detected.
>> We found this problem happened occasionally in the switch between bios
>> and bootloader.
> Can you rebase this on top of:
>
> https://git.linuxtv.org/hverkuil/media_tree.git/log/?h=for-v5.18f
>
> This series doesn't apply cleanly.

OK, I will update patch based on this code base.

Regards,

	Jammy

>
> Regards,
>
> 	Hans
>
>> Changes in v4:
>>   - Correct the subject of patch
>>
>> Changes in v3:
>>   - In v2, we tried to increase the min-required-count of stable signal
>>     to avoid incorrect transient state in timing detection. But it is
>>     not working for all conditions.
>>     Thus, we go another way in v3. Use regs, which can represent the
>>     signal status, to decide if we needs to do detection again.
>>   
>> Changes in v2:
>>   - Separate the patch into two patches
>>
>> Jammy Huang (2):
>>    media: aspeed: Add macro for the fields of the mode-detect registers
>>    media: aspeed: Fix unstable timing detection
>>
>>   drivers/media/platform/aspeed-video.c | 25 ++++++++++++++++++++++++-
>>   1 file changed, 24 insertions(+), 1 deletion(-)
>>
-- 
Best Regards
Jammy



From jammy_huang at aspeedtech.com  Tue Jan 25 17:47:23 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 26 Jan 2022 09:47:23 +0800
Subject: [PATCH v5 0/2] Fix incorrect resolution detected
Message-ID: <20220126014725.1511-1-jammy_huang@aspeedtech.com>

This series fixes incorrect resolution detected.
We found this problem happened occasionally in the switch between bios
and bootloader.

Changes in v5:
 - Rebase on top of 5.18f

Changes in v4:
 - Correct the subject of patch

Changes in v3:
 - In v2, we tried to increase the min-required-count of stable signal
   to avoid incorrect transient state in timing detection. But it is
   not working for all conditions.
   Thus, we go another way in v3. Use regs, which can represent the
   signal status, to decide if we needs to do detection again.
 
Changes in v2:
 - Separate the patch into two patches

Jammy Huang (2):
  media: aspeed: Add macro for the fields of the mode-detect registers
  media: aspeed: Fix unstable timing detection

 drivers/media/platform/aspeed-video.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 25 17:47:24 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 26 Jan 2022 09:47:24 +0800
Subject: [PATCH v5 1/2] media: aspeed: Add macro for the fields of the
 mode-detect registers
In-Reply-To: <20220126014725.1511-1-jammy_huang@aspeedtech.com>
References: <20220126014725.1511-1-jammy_huang@aspeedtech.com>
Message-ID: <20220126014725.1511-2-jammy_huang@aspeedtech.com>

VE_MODE_DT_HOR_TOLER: the tolerance in detecting for stable horizontal
signal.
VE_MODE_DT_VER_TOLER: the tolerance in detecting for stable vertical
signal.
VE_MODE_DT_HOR_STABLE: the minimum required count in detecting stable
HSYNC signal to set mode detection horizontal signal stable.
VE_MODE_DT_VER_STABLE: the minimum required count in detecting stable
VSYNC signal to set mode detection vertical signal stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 51fb18453b81..5d1ec3de50ad 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -178,6 +178,12 @@
 #define  VE_INTERRUPT_VSYNC_DESC	BIT(11)
 
 #define VE_MODE_DETECT			0x30c
+#define  VE_MODE_DT_HOR_TOLER		GENMASK(31, 28)
+#define  VE_MODE_DT_VER_TOLER		GENMASK(27, 24)
+#define  VE_MODE_DT_HOR_STABLE		GENMASK(23, 20)
+#define  VE_MODE_DT_VER_STABLE		GENMASK(19, 16)
+#define  VE_MODE_DT_EDG_THROD		GENMASK(15, 8)
+
 #define VE_MEM_RESTRICT_START		0x310
 #define VE_MEM_RESTRICT_END		0x314
 
@@ -1105,7 +1111,12 @@ static void aspeed_video_init_regs(struct aspeed_video *video)
 	aspeed_video_write(video, VE_SCALING_FILTER3, 0x00200000);
 
 	/* Set mode detection defaults */
-	aspeed_video_write(video, VE_MODE_DETECT, 0x22666500);
+	aspeed_video_write(video, VE_MODE_DETECT,
+			   FIELD_PREP(VE_MODE_DT_HOR_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_VER_TOLER, 2) |
+			   FIELD_PREP(VE_MODE_DT_HOR_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_VER_STABLE, 6) |
+			   FIELD_PREP(VE_MODE_DT_EDG_THROD, 0x65));
 }
 
 static void aspeed_video_start(struct aspeed_video *video)
-- 
2.25.1



From jammy_huang at aspeedtech.com  Tue Jan 25 17:47:25 2022
From: jammy_huang at aspeedtech.com (Jammy Huang)
Date: Wed, 26 Jan 2022 09:47:25 +0800
Subject: [PATCH v5 2/2] media: aspeed: Fix unstable timing detection
In-Reply-To: <20220126014725.1511-1-jammy_huang@aspeedtech.com>
References: <20220126014725.1511-1-jammy_huang@aspeedtech.com>
Message-ID: <20220126014725.1511-3-jammy_huang@aspeedtech.com>

Using stable-signal in resolution detection, and try detection again
if unstable.

VE_MODE_DETECT_EXTSRC_ADC: 1 if video source is from ADC output.
VE_MODE_DETECT_H_STABLE: 1 if horizontal signal detection is stable.
VE_MODE_DETECT_V_STABLE: 1 if vertical signal detection is stable.

Signed-off-by: Jammy Huang <jammy_huang at aspeedtech.com>
---
 drivers/media/platform/aspeed-video.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c
index 5d1ec3de50ad..eb9c17ac0e14 100644
--- a/drivers/media/platform/aspeed-video.c
+++ b/drivers/media/platform/aspeed-video.c
@@ -153,9 +153,14 @@
 
 #define VE_MODE_DETECT_STATUS		0x098
 #define  VE_MODE_DETECT_H_PERIOD	GENMASK(11, 0)
+#define  VE_MODE_DETECT_EXTSRC_ADC	BIT(12)
+#define  VE_MODE_DETECT_H_STABLE	BIT(13)
+#define  VE_MODE_DETECT_V_STABLE	BIT(14)
 #define  VE_MODE_DETECT_V_LINES		GENMASK(27, 16)
 #define  VE_MODE_DETECT_STATUS_VSYNC	BIT(28)
 #define  VE_MODE_DETECT_STATUS_HSYNC	BIT(29)
+#define  VE_MODE_DETECT_VSYNC_RDY	BIT(30)
+#define  VE_MODE_DETECT_HSYNC_RDY	BIT(31)
 
 #define VE_SYNC_STATUS			0x09c
 #define  VE_SYNC_STATUS_HSYNC		GENMASK(11, 0)
@@ -909,6 +914,7 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 	bool invalid_resolution = true;
 	int rc;
 	int tries = 0;
+	u32 mds;
 	u32 src_lr_edge;
 	u32 src_tb_edge;
 	struct v4l2_bt_timings *det = &video->detected_timings;
@@ -939,6 +945,13 @@ static void aspeed_video_get_resolution(struct aspeed_video *video)
 			return;
 		}
 
+		mds = aspeed_video_read(video, VE_MODE_DETECT_STATUS);
+		// try detection again if current signal isn't stable
+		if (!(mds & VE_MODE_DETECT_H_STABLE) ||
+		    !(mds & VE_MODE_DETECT_V_STABLE) ||
+		    (mds & VE_MODE_DETECT_EXTSRC_ADC))
+			continue;
+
 		aspeed_video_check_and_set_polarity(video);
 
 		aspeed_video_enable_mode_detect(video);
-- 
2.25.1



From verdun at hpe.com  Tue Jan 25 17:49:08 2022
From: verdun at hpe.com (Verdun, Jean-Marie)
Date: Wed, 26 Jan 2022 01:49:08 +0000
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <CAK8P3a0ccoH_sNE9eWxQnWHEWNBPFL6k4k6mku=cHs_fRfnL-w@mail.gmail.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
 <CAK8P3a0ccoH_sNE9eWxQnWHEWNBPFL6k4k6mku=cHs_fRfnL-w@mail.gmail.com>
Message-ID: <CA8148A1-578E-4621-9714-45AB391C353A@hpe.com>

Hello Arnd,

I work with Nick on upstreaming the initial code for our GXP asic. Many thanks for your feedbacks.

We will update accordingly. I must admit that I am a little bit lost regarding the process we shall follow to introduce a new SoC. We took the path to send first the DT side and then the drivers through a set of patch per driver. Andrew, seems to guide us into a direction where we shall have a very small DT initially and we will expand it in a step by step manner when we will get drivers approved, this might lead us into a process which might be very sequential. What is the best recommendation to follow ? Either way is ok on our side, I am just looking at the easiest solution for the code Maintainers.

Most of this code is intended to be used with OpenBMC and u-boot. We didn't have yet upstream anything into the bootloader, and wanted to follow a step by step approach by initially publishing into the kernel (that explain why some init also are still hardcoded in the case the bootloader doesn't provide the data, that is still work in progress, but we can have end user testing the infrastructure). We have a very small user space environment to validate that the kernel boot properly by using u-root, before getting OpenBMC fully loaded. Last but not least, as this is a BMC code, which is new to our end users, it would be just great to have default fall back if the u-boot environment is not properly setup (roughly we could code the MAC address into the umac driver, or the DT to address such cases). We plan to update uboot in the next couple of days by the way. 

We do not use dtsi at all for the moment, as we are generating a dtb out of the dts file and load it into our SPI image. Probably not the best approach, but this is the way it is implemented currently. The dtb is compiled outside the kernel tree for the moment using dtc compiler. We will add that step into the dts boot Makefile, it make sense. Does the dtsi is mandatory for every SoC ? I can build one if needed. But as this SoC is a BMC, the current dts is an example of what shall be configured. Many other datas related to the hardware target platform are defined into OpenBMC layers while we build for various ProLiant servers. We wanted our kernel code being readily testable that is why we have that generic dts. (GPIOS mapping is machine dependent)

vejmarie

?On 1/25/22, 4:22 PM, "Arnd Bergmann" <arnd at arndb.de> wrote:

    'On Tue, Jan 25, 2022 at 8:46 PM <nick.hawkins at hpe.com> wrote:
    >
    > From: Nick Hawkins <nick.hawkins at hpe.com>
    >
    > Signed-off-by: Nick Hawkins <nick.hawkins at hpe.com>

    Hi Nick,

    Thanks for your submission, it's always nice to see support for a new platform.

    I assume that you have a number of other drivers that are required for
    an initial
    support, at least to get you booting into a shell. I recommend to keep
    those together
    as a series, and we can merge them through the soc tree initially, with an Ack
    from the corresponding subsystem maintainers. For later updates to the drivers,
    you should send them to the maintainers directly, same for any
    non-essential drivers

    Krzysztof already commented on most issues I see, here are a few more things
    to consider:

    >
    > +GXP ARCHITECTURE

    Make this "ARM/HPE GXP ARCHITECTURE", so it does not get mistaken
    for a separate instruction set architecture, or something else with that three
    letter acronym.

    > +
    > +/dts-v1/;
    > +/ {
    > +  #address-cells = <1>;
    > +  #size-cells = <1>;
    > +       compatible = "HPE,GXP";
    > +       model = "GXP";

    Make this the specific machine rather than the SoC, unless you can guarantee
    that there won't ever be another board revision made from the same SoC (family).

    > +       chosen {
    > +               bootargs = "earlyprintk console=ttyS0,115200 user_debug=31";
    > +       };

    The bootargs should be set by the bootloader. In particular there should be
    not 'earlyprintk' by default, and the console should be selected using the
    'stdout-path' property.

    You seem to be missing CPU nodes.

    > +
    > +               usb0: ehci at cefe0000 {
    > +                       compatible = "generic-ehci";
    > +                       reg = <0xcefe0000 0x100>;
    > +                       interrupts = <7>;
    > +                       interrupt-parent = <&vic0>;
    > +               };
    > +
    > +               usb1: ohci at cefe0100 {
    > +                       compatible = "generic-ohci";
    > +                       reg = <0xcefe0100 0x110>;
    > +                       interrupts = <6>;
    > +                       interrupt-parent = <&vic0>;
    > +               };

    Add a custom compatible string as a specialization in case you ever
    need to work around some quirk on these devices.

    > +               spifi0: spifi at c0000200 {
    > +                       compatible = "hpe,gxp-spifi";
    > +                       reg = <0xc0000200 0x80>, <0xc000c000 0x100>, <0xf8000000 0x8000000>;
    > +                       interrupts = <20>;
    > +                       interrupt-parent = <&vic0>;
    > +                       #address-cells = <1>;
    > +                       #size-cells = <0>;
    > +
    > +                       flash at 0 {
    > +                               compatible = "jedec,spi-nor";
    > +                               reg = <0>;
    > +                               partitions {
    > +                                       compatible = "fixed-partitions";
    > +                                       #address-cells = <1>;
    > +                                       #size-cells = <1>;
    > +
    > +                                       bmc at 0 {
    > +                                               label = "bmc";
    > +                                               reg = <0x0 0x2000000>;
    > +                                       };
    > +                                       u-boot at 0 {
    > +                                               label = "u-boot";
    > +                                               reg = <0x0 0x60000>;
    > +                                       };


    The partitions should ideally be set by the bootloader as well, or
    at least be in the .dts file separately from the soc .dtsi file.

    > diff --git a/arch/arm/configs/gxp_defconfig b/arch/arm/configs/gxp_defconfig
    > new file mode 100644
    > index 000000000000..f37c6630e06d
    > --- /dev/null
    > +++ b/arch/arm/configs/gxp_defconfig

    Do you have a strong reason for needing a custom defconfig file?
    Usually this should
    work with the normal multi_v7_defconfig.


    > diff --git a/arch/arm/mach-hpe/Kconfig b/arch/arm/mach-hpe/Kconfig
    > new file mode 100644
    > index 000000000000..9b27f97c6536
    > --- /dev/null
    > +++ b/arch/arm/mach-hpe/Kconfig
    > @@ -0,0 +1,20 @@
    > +menuconfig ARCH_HPE
    > +       bool "HPE SoC support"
    > +       help
    > +         This enables support for HPE ARM based SoC chips
    > +if ARCH_HPE
    > +
    > +config ARCH_HPE_GXP
    > +       bool "HPE GXP SoC"
    > +       select ARM_VIC
    > +       select PINCTRL
    > +       select IRQ_DOMAIN
    > +       select GENERIC_IRQ_CHIP
    > +       select MULTI_IRQ_HANDLER
    > +       select SPARSE_IRQ
    > +       select CLKSRC_MMIO
    > +       depends on ARCH_MULTI_V7


    Most of the symbols you select are implied by ARCH_MULTI_V7, so you
    can remove them here.

    > +#define IOP_REGS_PHYS_BASE 0xc0000000
    > +#define IOP_REGS_VIRT_BASE 0xf0000000
    > +#define IOP_REGS_SIZE (240*SZ_1M)

    We don't normally do custom mappings any more, these should come from
    the device tree and get mapped by the corresponding drivers.

    > +#define IOP_EHCI_USBCMD 0x0efe0010
    > +
    > +static struct map_desc gxp_io_desc[] __initdata = {
    > +       {
    > +       .virtual        = (unsigned long)IOP_REGS_VIRT_BASE,
    > +       .pfn            = __phys_to_pfn(IOP_REGS_PHYS_BASE),
    > +       .length         = IOP_REGS_SIZE,
    > +       .type           = MT_DEVICE,
    > +       },
    > +};
    > +
    > +void __init gxp_map_io(void)
    > +{
    > +       iotable_init(gxp_io_desc, ARRAY_SIZE(gxp_io_desc));
    > +}
    > +
    > +static void __init gxp_dt_init(void)
    > +{
    > +       //reset EHCI host controller for clear start
    > +       __raw_writel(0x00080002,
    > +               (void __iomem *)(IOP_REGS_VIRT_BASE + IOP_EHCI_USBCMD));

    This belongs into the bootloader, or the EHCI driver, see the comment about a
    custom compatible value above ;-)

    > +static void gxp_restart(enum reboot_mode mode, const char *cmd)
    > +{
    > +       pr_info("gpx restart");
    > +       __raw_writel(1, (void __iomem *) IOP_REGS_VIRT_BASE);
    > +}

    This should be a reset driver, see
    drivers/power/reset/syscon-reboot.c either as an example, or something you
    can use directly.

             Arnd


From shawnguo at kernel.org  Tue Jan 25 18:05:08 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 10:05:08 +0800
Subject: [PATCH v1 4/4] ARM: dts: imx6dl: plym2m, prtvt7, victgo:  make
 use of new resistive-adc-touch driver
In-Reply-To: <20220105110434.GG303@pengutronix.de>
References: <20211122124310.2796505-1-o.rempel@pengutronix.de>
 <20211122124310.2796505-4-o.rempel@pengutronix.de>
 <20211206010627.GK4216@dragon>
 <20220105110434.GG303@pengutronix.de>
Message-ID: <20220126020507.GA4686@dragon>

On Wed, Jan 05, 2022 at 12:04:34PM +0100, Oleksij Rempel wrote:
> Hi Shawn,
> 
> sorry for the delay, I just came back to work.
> 
> On Mon, Dec 06, 2021 at 09:06:28AM +0800, Shawn Guo wrote:
> > On Mon, Nov 22, 2021 at 01:43:10PM +0100, Oleksij Rempel wrote:
> > > The tsc2046 is an ADC used as touchscreen controller. To share as mach
> > > code as possible, we should use it as actual ADC + virtual tochscreen
> > > controller.
> > > With this patch we make use of the new kernel IIO and HID infrastructure.
> > > 
> > > Signed-off-by: Oleksij Rempel <o.rempel at pengutronix.de>
> > 
> > One space is enough in subject "victgo:  make".
> 
> done.
> 
> > > ---
> > >  arch/arm/boot/dts/imx6dl-plym2m.dts | 55 ++++++++++++++++++++---------
> > >  arch/arm/boot/dts/imx6dl-prtvt7.dts | 53 ++++++++++++++++++++-------
> > >  arch/arm/boot/dts/imx6dl-victgo.dts | 55 +++++++++++++++++++++--------
> > >  3 files changed, 120 insertions(+), 43 deletions(-)
> > > 
> > > diff --git a/arch/arm/boot/dts/imx6dl-plym2m.dts b/arch/arm/boot/dts/imx6dl-plym2m.dts
> > > index 60fe5f14666e..e2afedae85cb 100644
> > > --- a/arch/arm/boot/dts/imx6dl-plym2m.dts
> > > +++ b/arch/arm/boot/dts/imx6dl-plym2m.dts
> > > @@ -101,6 +101,17 @@ reg_12v0: regulator-12v0 {
> > >  		regulator-min-microvolt = <12000000>;
> > >  		regulator-max-microvolt = <12000000>;
> > >  	};
> > > +
> > > +	touchscreen {
> > > +		compatible = "resistive-adc-touch";
> > > +		io-channels = <&adc 1>, <&adc 3>, <&adc 4>, <&adc 5>;
> > > +		io-channel-names = "y", "z1", "z2", "x";
> > > +		touchscreen-min-pressure = <64687>;
> > > +		touchscreen-inverted-x;
> > > +		touchscreen-inverted-y;
> > > +		touchscreen-x-plate-ohms = <300>;
> > > +		touchscreen-y-plate-ohms = <800>;
> > > +	};
> > >  };
> > >  
> > >  &can1 {
> > > @@ -129,26 +140,38 @@ &ecspi2 {
> > >  	pinctrl-0 = <&pinctrl_ecspi2>;
> > >  	status = "okay";
> > >  
> > > -	touchscreen at 0 {
> > > -		compatible = "ti,tsc2046";
> > > +	adc: adc at 0 {
> > 
> > Isn't label name "adc" too generic?
> 
> I do not have strong opinion about this. Currently we have no
> restrictions for the node names:
> Documentation/devicetree/bindings/iio/adc/ti,tsc2046.yaml
> Documentation/devicetree/bindings/iio/adc/adc.yaml
> 
> I can name it touchscreen-adc at 0 or something like this. What are your
> preferences?

I wasn't talking about node name but label.

Shawn


From zhangshaokun at hisilicon.com  Tue Jan 25 18:24:21 2022
From: zhangshaokun at hisilicon.com (Shaokun Zhang)
Date: Wed, 26 Jan 2022 10:24:21 +0800
Subject: [BUG] drivers/perf: hisi: kernel fails to boot since commit
 ac4511c9364c "drivers/perf: hisi: Add identifier sysfs file"
In-Reply-To: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
References: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
Message-ID: <2508ac09-0722-1d86-9eed-883ccded199c@hisilicon.com>

Hi Wang Cheng,

On 2022/1/25 22:35, Wang Cheng wrote:
> Hi respected kernel committers,
> 
> After upgrading from v5.10 to 5.17.0-rc1, my kernel fails to boot. By
> bisectionally compiling and installing kernel a few times, the boot
> problem first appears when upgrading from v5.10 to v5.11-rc1. Here are
> boot messages of v5.11-rc1:
> [2.126166] workingset: timestamp_bits=42 max_order=21 bucket_order=0
> [2.127807] zbud: loaded
> [2.128010] integrity: Platform Keyring initialized
> [2.128014] Key type asymmetric registered
> [2.128017] Asymmetric key parser 'x509' registered
> [2.128026] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
> [2.128092] io scheduler mq-deadline registered
> [2.130976] pcieport 0000:00:01.0: can't derive routing for PCI INT A
> [2.130982] pcieport 0000:00:01.0: PCI INT A: no GSI
> [2.131272] pcieport 0000:00:01.0: can't derive routing for PCI INT A
> [2.131276] pcieport 0000:00:01.0: PCI INT A: no GSI
> [2.132188] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
> [2.132192] ACPI: IORT: [Firmware Bug]: applying workaround.
> [2.132259] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
> [2.132263] ACPI: IORT: [Firmware Bug]: applying workaround.
> [2.132285] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
> [2.132850] efifb: probing for efifb
> [2.132875] efifb: framebuffer at 0x80000000000, using 3072k, total 3072k
> [2.132878] efifb: mode is 1024x768x32, linelength=4096, pages=1
> [2.132881] efifb: scrolling: redraw
> [2.132883] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
> [2.135097] Console: switching to colour frame buffer device 128x48
> [2.137221] fb0: EFI VGA frame buffer device
> [2.137655] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
> [2.137715] ACPI: Power Button [PWRB]
> [2.138153] ACPI GTDT: found 1 SBSA generic Watchdog(s).
> [2.140587] Serial: 8250/16550 deiver, 4 ports, IRQ sharing enabled
> [2.141685] Serial: AMBA driver
> [2.141828] msm_serial: driver initialized
> [2.142785] mousedev: PS/2 mouse device common for all mice
> [2.186108] rtc-efi rtc-efi.0: registered as rtc0
> [2.198458] rtc-efi rtc-efi.0: setting system clock to 2022-01-23T13:49:49 UTC(1642945789)
> [2.199157] ledtrig-cpu: registered to indicate activity on CPUs
> _
> Boot messages stop here. After about 2 seconds, the cpu fan runs in the
> fastest mode all the time. I have to press the power button to turn the
> machine off.
> 
> By bisectionally test, I found commit ac4511c9364c9a6390e8585cdd4596103bca16eb
> "drivers/perf: hisi: Add identifier sysfs file" is suspect of resulting
> the boot problem. If I revert this commit on v5.11-rc1, kernel boots
> fine. That is:
> $ git checkout v5.11-rc1
> $ git revert ac4511c9364c9a6390e8585cdd4596103bca16eb
> $ "compile and install kernel"
> kernel boots fine.
> 
> I tested a bit more. I think hisi_uncore_ddrc_pmu.c or function
> hisi_uncore_pmu_identifier_attr_show(...) is suspect in commit ac4511c9364c.

The DDRC nodes enumerated in the UEFI are more than the SoC chip has, so
the superfluous node will be suspended when the PMU driver is initializated.

> Commit ac4511c9364c modified 5 files:
> 	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> As I understand, a new function hisi_uncore_pmu_identifier_attr_show(...)
> is declared and defined in hisi_uncore_pmu.h and hisi_uncore_pmu.c, the
> new function is called in hisi_uncore_ddrc_pmu.c, hisi_uncore_hha_pmu.c
> and hisi_uncore_l3c_pmu.c. I tested that, if I restore the change in
> hisi_uncore_ddrc_pmu.c, kernel boots fine; if I restore the change in
> hisi_uncore_hha_pmu.c and hisi_uncore_l3c_pmu.c, kernel fails to boot.
> That is:
> 	drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> compile and install, kernel boots fine.
> 

Without the commit ac4511c9364 ("drivers/perf: hisi: Add identifier sysfs file"),
the driver can be loaded successfully that driver doesn't access any physical
register, but it will be suspended if you use the all DDRC nodes perf.

> 	drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.c
> 	drivers/perf/hisilicon/hisi_uncore_pmu.h
> compile and install, kernel fails to boot.
> 
> $ sudo lshw
> cpu version: HUAWEI Kunpeng 920 2251K
> cores=8 enabledcores=8 threads=8

As John said that some guys has reported the similiar issue on this
chip.

> 8Gib RAM
> $ uname -a
> Linux armdebian 5.10.0-9-arm64 #1 SMP Debian 5.10.70-1 (2021-09-30)
> aarch64 GNU/Linux
> 
> Do I understand right? What else I could do to solve this?

I'm checking with the BIOS guy and which version they fix the issue.
I will give the right BIOS and can you help to try it?

Thanks,
Shaokun

> 
> Regards,
> 
> --
> Cheng
> .
> 


From shawnguo at kernel.org  Tue Jan 25 18:25:25 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 10:25:25 +0800
Subject: [PATCH v7 4/8] arm64: dts: imx8mm: Add the pcie phy support
In-Reply-To: <1638432158-4119-5-git-send-email-hongxing.zhu@nxp.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
 <1638432158-4119-5-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <20220126022524.GB4686@dragon>

On Thu, Dec 02, 2021 at 04:02:34PM +0800, Richard Zhu wrote:
> Add the PCIe PHY support on iMX8MM platforms.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Reviewed-by: Tim Harvey <tharvey at gateworks.com>
> Tested-by: Tim Harvey <tharvey at gateworks.com>

Applied, thanks!


From akpm at linux-foundation.org  Tue Jan 25 18:25:50 2022
From: akpm at linux-foundation.org (Andrew Morton)
Date: Tue, 25 Jan 2022 18:25:50 -0800
Subject: [PATCH v2] vmap(): don't allow invalid pages
In-Reply-To: <20220119012109.551931-1-yury.norov@gmail.com>
References: <20220119012109.551931-1-yury.norov@gmail.com>
Message-ID: <20220125182550.7c693c76fe6520047c2e4f26@linux-foundation.org>

On Tue, 18 Jan 2022 17:21:09 -0800 Yury Norov <yury.norov at gmail.com> wrote:

> vmap() takes struct page *pages as one of arguments, and user may provide
> an invalid pointer which would lead to data abort at address translation
> later.

Does "user" mean userspace code?

If so, please tell us much more about the means by which userspace can
trigger this problem.



From shawnguo at kernel.org  Tue Jan 25 18:25:52 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 10:25:52 +0800
Subject: [PATCH v7 6/8] arm64: dts: imx8mm: Add the pcie support
In-Reply-To: <1638432158-4119-7-git-send-email-hongxing.zhu@nxp.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
 <1638432158-4119-7-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <20220126022552.GC4686@dragon>

On Thu, Dec 02, 2021 at 04:02:36PM +0800, Richard Zhu wrote:
> Add the PCIe support on i.MX8MM platforms.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Reviewed-by: Tim Harvey <tharvey at gateworks.com>
> Tested-by: Tim Harvey <tharvey at gateworks.com>

Applied, thanks!


From zhangshaokun at hisilicon.com  Tue Jan 25 18:26:22 2022
From: zhangshaokun at hisilicon.com (Shaokun Zhang)
Date: Wed, 26 Jan 2022 10:26:22 +0800
Subject: [BUG] drivers/perf: hisi: kernel fails to boot since commit
 ac4511c9364c "drivers/perf: hisi: Add identifier sysfs file"
In-Reply-To: <be7554e5-8051-6003-c11b-d7f418f0fb04@huawei.com>
References: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
 <be7554e5-8051-6003-c11b-d7f418f0fb04@huawei.com>
Message-ID: <972c3747-80e4-a6ba-a9ba-c78075cebd44@hisilicon.com>

Hi John,

On 2022/1/25 22:48, John Garry wrote:
> On 25/01/2022 14:35, Wang Cheng wrote:
> 
> We had a similar report some time ago:
> 
> https://lore.kernel.org/linux-arm-kernel/ada98c97-1e06-5f71-0487-638f679eebf7 at hisilicon.com/
> 
> Seems to be a BIOS issue. Shaokun?

Right,
I'm checking this and which version has this issue,
will fix the BIOS table.

Shaokun.

> 
> Thanks,
> John
> 
> 
>> Hi respected kernel committers,
>>
>> After upgrading from v5.10 to 5.17.0-rc1, my kernel fails to boot. By
>> bisectionally compiling and installing kernel a few times, the boot
>> problem first appears when upgrading from v5.10 to v5.11-rc1. Here are
>> boot messages of v5.11-rc1:
>> [2.126166] workingset: timestamp_bits=42 max_order=21 bucket_order=0
>> [2.127807] zbud: loaded
>> [2.128010] integrity: Platform Keyring initialized
>> [2.128014] Key type asymmetric registered
>> [2.128017] Asymmetric key parser 'x509' registered
>> [2.128026] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 249)
>> [2.128092] io scheduler mq-deadline registered
>> [2.130976] pcieport 0000:00:01.0: can't derive routing for PCI INT A
>> [2.130982] pcieport 0000:00:01.0: PCI INT A: no GSI
>> [2.131272] pcieport 0000:00:01.0: can't derive routing for PCI INT A
>> [2.131276] pcieport 0000:00:01.0: PCI INT A: no GSI
>> [2.132188] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
>> [2.132192] ACPI: IORT: [Firmware Bug]: applying workaround.
>> [2.132259] ACPI: IORT: [Firmware Bug]: [map (____ptrval____)] conflicting mapping for input ID 0x7c00
>> [2.132263] ACPI: IORT: [Firmware Bug]: applying workaround.
>> [2.132285] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
>> [2.132850] efifb: probing for efifb
>> [2.132875] efifb: framebuffer at 0x80000000000, using 3072k, total 3072k
>> [2.132878] efifb: mode is 1024x768x32, linelength=4096, pages=1
>> [2.132881] efifb: scrolling: redraw
>> [2.132883] efifb: Truecolor: size=8:8:8:8, shift=24:16:8:0
>> [2.135097] Console: switching to colour frame buffer device 128x48
>> [2.137221] fb0: EFI VGA frame buffer device
>> [2.137655] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0
>> [2.137715] ACPI: Power Button [PWRB]
>> [2.138153] ACPI GTDT: found 1 SBSA generic Watchdog(s).
>> [2.140587] Serial: 8250/16550 deiver, 4 ports, IRQ sharing enabled
>> [2.141685] Serial: AMBA driver
>> [2.141828] msm_serial: driver initialized
>> [2.142785] mousedev: PS/2 mouse device common for all mice
>> [2.186108] rtc-efi rtc-efi.0: registered as rtc0
>> [2.198458] rtc-efi rtc-efi.0: setting system clock to 2022-01-23T13:49:49 UTC(1642945789)
>> [2.199157] ledtrig-cpu: registered to indicate activity on CPUs
>> _.
>> Boot messages stop here. After about 2 seconds, the cpu fan runs in the
>> fastest mode all the time. I have to press the power button to turn the
>> machine off.
>>
>> By bisectionally test, I found commit ac4511c9364c9a6390e8585cdd4596103bca16eb
>> "drivers/perf: hisi: Add identifier sysfs file" is suspect of resulting
>> the boot problem. If I revert this commit on v5.11-rc1, kernel boots
>> fine. That is:
>> $ git checkout v5.11-rc1
>> $ git revert ac4511c9364c9a6390e8585cdd4596103bca16eb
>> $ "compile and install kernel"
>> kernel boots fine.
>>
>> I tested a bit more. I think hisi_uncore_ddrc_pmu.c or function
>> hisi_uncore_pmu_identifier_attr_show(...) is suspect in commit ac4511c9364c.
>> Commit ac4511c9364c modified 5 files:
>> ????drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.h
>> As I understand, a new function hisi_uncore_pmu_identifier_attr_show(...)
>> is declared and defined in hisi_uncore_pmu.h and hisi_uncore_pmu.c, the
>> new function is called in hisi_uncore_ddrc_pmu.c, hisi_uncore_hha_pmu.c
>> and hisi_uncore_l3c_pmu.c. I tested that, if I restore the change in
>> hisi_uncore_ddrc_pmu.c, kernel boots fine; if I restore the change in
>> hisi_uncore_hha_pmu.c and hisi_uncore_l3c_pmu.c, kernel fails to boot.
>> That is:
>> ????drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.h
>> compile and install, kernel boots fine.
>>
>> ????drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.c
>> ????drivers/perf/hisilicon/hisi_uncore_pmu.h
>> compile and install, kernel fails to boot.
>>
>> $ sudo lshw
>> cpu version: HUAWEI Kunpeng 920 2251K
>> cores=8 enabledcores=8 threads=8
>> 8Gib RAM
>> $ uname -a
>> Linux armdebian 5.10.0-9-arm64 #1 SMP Debian 5.10.70-1 (2021-09-30)
>> aarch64 GNU/Linux
>>
>> Do I understand right? What else I could do to solve this?
>>
>> Regards,
>>
>> -- 
>> Cheng
>> .
>>
> 
> .


From shawnguo at kernel.org  Tue Jan 25 18:26:52 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 10:26:52 +0800
Subject: [PATCH v7 7/8] arm64: dts: imx8mm-evk: Add the pcie support on
 imx8mm evk board
In-Reply-To: <1638432158-4119-8-git-send-email-hongxing.zhu@nxp.com>
References: <1638432158-4119-1-git-send-email-hongxing.zhu@nxp.com>
 <1638432158-4119-8-git-send-email-hongxing.zhu@nxp.com>
Message-ID: <20220126022651.GD4686@dragon>

On Thu, Dec 02, 2021 at 04:02:37PM +0800, Richard Zhu wrote:
> Add the PCIe support on iMX8MM EVK boards.
> And set the default reference clock mode.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu at nxp.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> Reviewed-by: Tim Harvey <tharvey at gateworks.com>
> Tested-by: Tim Harvey <tharvey at gateworks.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi | 55 +++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> index e033d0257b5a..87a30daf0b3c 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-evk.dtsi
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  
> +#include <dt-bindings/phy/phy-imx8-pcie.h>
>  #include <dt-bindings/usb/pd.h>
>  #include "imx8mm.dtsi"
>  
> @@ -30,6 +31,23 @@ status {
>  		};
>  	};
>  
> +	pcie0_refclk: pcie0-refclk {
> +		compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <100000000>;

Incorrect indent.  Fixed them up and applied.

Shawn

> +	};
> +
> +	reg_pcie0: regulator-pcie {
> +		compatible = "regulator-fixed";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_pcie0_reg>;
> +		regulator-name = "MPCIE_3V3";
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +	};
> +
>  	reg_usdhc2_vmmc: regulator-usdhc2 {
>  		compatible = "regulator-fixed";
>  		pinctrl-names = "default";
> @@ -289,6 +307,30 @@ pca6416: gpio at 20 {
>  	};
>  };
>  
> +&pcie_phy {
> +	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
> +	fsl,tx-deemph-gen1 = <0x2d>;
> +	fsl,tx-deemph-gen2 = <0xf>;
> +	clocks = <&pcie0_refclk>;
> +	status = "okay";
> +};
> +
> +&pcie0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_pcie0>;
> +	reset-gpio = <&gpio4 21 GPIO_ACTIVE_LOW>;
> +	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
> +		 <&pcie0_refclk>;
> +	clock-names = "pcie", "pcie_aux", "pcie_bus";
> +	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
> +			  <&clk IMX8MM_CLK_PCIE1_CTRL>;
> +	assigned-clock-rates = <10000000>, <250000000>;
> +	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
> +				 <&clk IMX8MM_SYS_PLL2_250M>;
> +	vpcie-supply = <&reg_pcie0>;
> +	status = "okay";
> +};
> +
>  &sai3 {
>  	pinctrl-names = "default";
>  	pinctrl-0 = <&pinctrl_sai3>;
> @@ -406,6 +448,19 @@ MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400001c3
>  		>;
>  	};
>  
> +	pinctrl_pcie0: pcie0grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B    0x61
> +			MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21       0x41
> +		>;
> +	};
> +
> +	pinctrl_pcie0_reg: pcie0reggrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5       0x41
> +		>;
> +	};
> +
>  	pinctrl_pmic: pmicirqgrp {
>  		fsl,pins = <
>  			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x141
> -- 
> 2.25.1
> 


From yury.norov at gmail.com  Tue Jan 25 18:29:04 2022
From: yury.norov at gmail.com (Yury Norov)
Date: Tue, 25 Jan 2022 18:29:04 -0800
Subject: [PATCH v2] vmap(): don't allow invalid pages
In-Reply-To: <20220125182550.7c693c76fe6520047c2e4f26@linux-foundation.org>
References: <20220119012109.551931-1-yury.norov@gmail.com>
 <20220125182550.7c693c76fe6520047c2e4f26@linux-foundation.org>
Message-ID: <CAAH8bW9s9ENa7QOExV3rOqn-LAEu1RrQd+ijor9o=jhGxm=6ew@mail.gmail.com>

On Tue, Jan 25, 2022 at 6:25 PM Andrew Morton <akpm at linux-foundation.org> wrote:
>
> On Tue, 18 Jan 2022 17:21:09 -0800 Yury Norov <yury.norov at gmail.com> wrote:
>
> > vmap() takes struct page *pages as one of arguments, and user may provide
> > an invalid pointer which would lead to data abort at address translation
> > later.
>
> Does "user" mean userspace code?
>
> If so, please tell us much more about the means by which userspace can
> trigger this problem.

User means user of vmap() API. The discussion is here:

https://lore.kernel.org/linux-mm/20220118235244.540103-1-yury.norov at gmail.com/

I'll send v3 soon with more details in the patch description.


From shawnguo at kernel.org  Tue Jan 25 18:34:48 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 10:34:48 +0800
Subject: [PATCH] soc: imx: Remove Layerscape check
In-Reply-To: <20211208201211.1866158-1-festevam@gmail.com>
References: <20211208201211.1866158-1-festevam@gmail.com>
Message-ID: <20220126023447.GE4686@dragon>

On Wed, Dec 08, 2021 at 05:12:11PM -0300, Fabio Estevam wrote:
> Since commit 4ebd29f91629 ("soc: imx: Register SoC device only on i.MX
> boards") the soc-imx driver is only registered on i.MX platforms as
> intended.
> 
> This means that we no longer need to do a specific check for
> Layerscape.
> 
> Remove the now unneeded "fsl,ls1021a" check.
> 
> Signed-off-by: Fabio Estevam <festevam at gmail.com>

Applied, thanks!


From willy at infradead.org  Tue Jan 25 18:50:51 2022
From: willy at infradead.org (Matthew Wilcox)
Date: Wed, 26 Jan 2022 02:50:51 +0000
Subject: [PATCH] vmap(): don't allow invalid pages
In-Reply-To: <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
References: <20220118235244.540103-1-yury.norov@gmail.com>
 <f85b3cac-29e7-4179-e078-fd859040c294@arm.com>
Message-ID: <YfC3C5MiyKzSX4Sg@casper.infradead.org>

On Wed, Jan 19, 2022 at 01:28:14PM +0000, Robin Murphy wrote:
> Is it page_to_pfn() guaranteed to work without blowing up if page is invalid
> in the first place? Looking at the CONFIG_SPARSEMEM case I'm not sure that's
> true...

Something that all the ARM people weighing in on this don't understand
is that basically nobody uses SPARSEMEM without SPARSEMEM_VMEMMAP.
So all this complicated code to do page_to_pfn() is never tested.
Real users all do a simple subtraction and so the simple pfn_valid()
works fine.


From ming.qian at nxp.com  Tue Jan 25 19:09:19 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:19 +0800
Subject: [PATCH v15.1 00/13] amphion video decoder/encoder driver
Message-ID: <cover.1643165764.git.ming.qian@nxp.com>

Hi all,

This patch series adds support for
the amphion video encoder and decoder
via the VPU block present in imx8q platforms.
Currently, support for IMX8QXP and IMX8QM is included.

It features decoding for the following formats:
- H.264
- HEVC
- MPEG4
- MPEG2
- VC1
- VP8

It features encoding for the following formats:
- H.264

The driver creates a separate device node for the encoder and decoder.

This driver is dependent on vpu firmwares.
The firmwares have been submitted to linux-firmware.
The firmware patch is since commit
b563148fd28623f6b6ce68bb06c3dd3bd138b058:
linux-firmware: Update firmware file for Intel Bluetooth 9462
(Fri Oct 8 16:30:14 2021 +0530)

and it's available in the git repository at:
    https://github.com/mingqian-0/linux-firmware.git

for you to fetch changes up to bb3eee4f99589d4910dee4c053a3a685546b5dbb:
amphion: add VPU firmwares for NXP i.MX8Q SoCs
(Tue Oct 12 15:09:57 2021 +0800)

encoder is tested with gstreamer
decoder is tested with gstreamer, but the following patches are required:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1379
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1381


Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>


Changelog:

v15.1
- include linux/vmalloc.h to avoid build warning by kernel test robot
- add entry in MAINTAINERS alphabetically

v15
- fix issues detected by "checkpatch.pl --strict"
- encoder add ctrl V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE

v14
- fix some errors according to Hans's comments

v13
- make a workaround that avoid firmware entering wfi wrongly

v12
- support reset decoder when starting a new stream
- don't append an empty last buffer, set last_buffer_dequeued
- improve the resolution change flow
- return all buffers if start_streaming fail
- fill encoder capture buffer's filed to none
- fix a bug in calculating bytesperline

v11
- fix dt_binding_check error after upgrade dtschema
- remove "default y"
- add media device

v10
- refine vpu log, remove custom logging infrastructure
- support non contiguous planes format nv12m instead of nv12
- rename V4L2_PIX_FMT_NV12_8L128 to V4L2_PIX_FMT_NV12MT_8L128
- rename V4L2_PIX_FMT_NV12_10BE_8L128 to V4L2_PIX_FMT_NV12MT_10BE_8L128
- merge two module into one
- fix kernel panic in rmmod

v9
- drop V4L2_BUF_FLAG_CODECCONFIG
- drop V4L2_EVENT_CODEC_ERROR
- drop V4L2_EVENT_SKIP - use the v4l2_buffer.sequence counter
- fix some build warnings with W=1 reported by kernel test robot

v8
- move driver from driver/media/platform/imx/vpu-8q to
  driver/media/platform/amphion
- rename driver name to amphion
- remove imx_vpu.h
- move the definition of V4L2_EVENT_CODEC_ERROR to videodev2.h
- move the definition of V4L2_EVENT_SKIP to videodev2.h

v7
- fix build warnings with W=1 reported by kernel test robot

v6:
- rename V4L2_PIX_FMT_NT8 to V4L2_PIX_FMT_NV12_8L128
- rename V4L2_PIX_FMT_NT10 to V4L2_PIX_FMT_NV12_10BE_8L128

v5:
- move some definition from imx_vph.h to videodev2.h
- remove some unnecessary content
- add some documentation descriptions
- pass the lateset v4l2-compliance test

v4:
- redefine the memory-region in devicetree bindings documentation
- use v4l2's mechanism to implement synchronize queuing ioctl
- remove the unnecessary mutex ioctl_sync
- don't notify source change event if the parameters are same as previously established
- add flag V4L2_FMT_FLAG_DYN_RESOLUTION to decoder's capture format

v3:
- don't make vpu device node a simple-bus
- trigger probing vpu core in the driver
- remove unnecessary vpu core index property

v2:
- fix dt bindings build error
- split driver patch into several parts to avoid exceeding bytes limit

Compliance
==========
# v4l2-compliance -d /dev/video0
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/video0:

Driver Info:
	Driver name      : amphion-vpu
	Card type        : amphion vpu decoder
	Bus info         : platform: amphion-vpu
	Driver version   : 5.15.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Decoder
Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0
Interface Info:
	ID               : 0x0300000c
	Type             : V4L Video
Entity Info:
	ID               : 0x00000001 (1)
	Name             : amphion-vpu-decoder-source
	Function         : V4L2 I/O
	Pad 0x01000002   : 0: Source
	  Link 0x02000008: to remote pad 0x1000004 of entity 'amphion-vpu-decoder-proc' (Video Decoder): Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video0 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 3 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK (Not Supported)
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK (Not Supported)
	test Composing: OK
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for amphion-vpu device /dev/video0: 46, Succeeded: 46, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/video1
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/video1:

Driver Info:
	Driver name      : amphion-vpu
	Card type        : amphion vpu encoder
	Bus info         : platform: amphion-vpu
	Driver version   : 5.15.0
	Capabilities     : 0x84204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
		Device Capabilities
	Device Caps      : 0x04204000
		Video Memory-to-Memory Multiplanar
		Streaming
		Extended Pix Format
	Detected Stateful Encoder
Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0
Interface Info:
	ID               : 0x0300001a
	Type             : V4L Video
Entity Info:
	ID               : 0x0000000f (15)
	Name             : amphion-vpu-encoder-source
	Function         : V4L2 I/O
	Pad 0x01000010   : 0: Source
	  Link 0x02000016: to remote pad 0x1000012 of entity 'amphion-vpu-encoder-proc' (Video Encoder): Data, Enabled, Immutable

Required ioctls:
	test MC information (see 'Media Driver Info' above): OK
	test VIDIOC_QUERYCAP: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/video1 open: OK
	test VIDIOC_QUERYCAP: OK
	test VIDIOC_G/S_PRIORITY: OK
	test for unlimited opens: OK

Debug ioctls:
	test VIDIOC_DBG_G/S_REGISTER: OK (Not Supported)
	test VIDIOC_LOG_STATUS: OK (Not Supported)

Input ioctls:
	test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
	test VIDIOC_ENUMAUDIO: OK (Not Supported)
	test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDIO: OK (Not Supported)
	Inputs: 0 Audio Inputs: 0 Tuners: 0

Output ioctls:
	test VIDIOC_G/S_MODULATOR: OK (Not Supported)
	test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
	test VIDIOC_ENUMAUDOUT: OK (Not Supported)
	test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
	test VIDIOC_G/S_AUDOUT: OK (Not Supported)
	Outputs: 0 Audio Outputs: 0 Modulators: 0

Input/Output configuration ioctls:
	test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
	test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
	test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
	test VIDIOC_G/S_EDID: OK (Not Supported)

Control ioctls:
	test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
	test VIDIOC_QUERYCTRL: OK
	test VIDIOC_G/S_CTRL: OK
	test VIDIOC_G/S/TRY_EXT_CTRLS: OK
	test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
	test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
	Standard Controls: 20 Private Controls: 0

Format ioctls:
	test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK
	test VIDIOC_G/S_PARM: OK
	test VIDIOC_G_FBUF: OK (Not Supported)
	test VIDIOC_G_FMT: OK
	test VIDIOC_TRY_FMT: OK
	test VIDIOC_S_FMT: OK
	test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
	test Cropping: OK
	test Composing: OK (Not Supported)
	test Scaling: OK (Not Supported)

Codec ioctls:
	test VIDIOC_(TRY_)ENCODER_CMD: OK
	test VIDIOC_G_ENC_INDEX: OK (Not Supported)
	test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)

Buffer ioctls:
	test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK
	test VIDIOC_EXPBUF: OK
	test Requests: OK (Not Supported)

Total for amphion-vpu device /dev/video1: 46, Succeeded: 46, Failed: 0, Warnings: 0

# v4l2-compliance -d /dev/media0
v4l2-compliance 1.21.0-4859, 64 bits, 64-bit time_t
v4l2-compliance SHA: 493af03f3c57 2021-10-08 17:23:11

Compliance test for amphion-vpu device /dev/media0:

Media Driver Info:
	Driver name      : amphion-vpu
	Model            : amphion-vpu
	Serial           :
	Bus info         : platform: amphion-vpu
	Media version    : 5.15.0
	Hardware revision: 0x00000000 (0)
	Driver version   : 5.15.0

Required ioctls:
	test MEDIA_IOC_DEVICE_INFO: OK
	test invalid ioctls: OK

Allow for multiple opens:
	test second /dev/media0 open: OK
	test MEDIA_IOC_DEVICE_INFO: OK
	test for unlimited opens: OK

Media Controller ioctls:
	test MEDIA_IOC_G_TOPOLOGY: OK
	Entities: 6 Interfaces: 2 Pads: 8 Links: 8
	test MEDIA_IOC_ENUM_ENTITIES/LINKS: OK
	test MEDIA_IOC_SETUP_LINK: OK

Total for amphion-vpu device /dev/media0: 8, Succeeded: 8, Failed: 0, Warnings: 0

Ming Qian (13):
  dt-bindings: media: amphion: add amphion video codec bindings
  media: add nv12m_8l128 and nv12m_10be_8l128 video format.
  media: amphion: add amphion vpu device driver
  media: amphion: add vpu core driver
  media: amphion: implement vpu core communication based on mailbox
  media: amphion: add vpu v4l2 m2m support
  media: amphion: add v4l2 m2m vpu encoder stateful driver
  media: amphion: add v4l2 m2m vpu decoder stateful driver
  media: amphion: implement windsor encoder rpc interface
  media: amphion: implement malone decoder rpc interface
  ARM64: dts: freescale: imx8q: add imx vpu codec entries
  firmware: imx: scu-pd: imx8q: add vpu mu resources
  MAINTAINERS: add AMPHION VPU CODEC V4L2 driver entry

 .../bindings/media/amphion,vpu.yaml           |  180 ++
 .../media/v4l/pixfmt-yuv-planar.rst           |   28 +-
 MAINTAINERS                                   |    9 +
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi |   72 +
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts |   17 +
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    |   24 +
 arch/arm64/configs/defconfig                  |    1 +
 drivers/firmware/imx/scu-pd.c                 |    4 +
 drivers/media/platform/Kconfig                |   19 +
 drivers/media/platform/Makefile               |    2 +
 drivers/media/platform/amphion/Makefile       |   20 +
 drivers/media/platform/amphion/vdec.c         | 1695 +++++++++++++++++
 drivers/media/platform/amphion/venc.c         | 1365 +++++++++++++
 drivers/media/platform/amphion/vpu.h          |  356 ++++
 drivers/media/platform/amphion/vpu_cmds.c     |  436 +++++
 drivers/media/platform/amphion/vpu_cmds.h     |   25 +
 drivers/media/platform/amphion/vpu_codec.h    |   68 +
 drivers/media/platform/amphion/vpu_color.c    |  183 ++
 drivers/media/platform/amphion/vpu_core.c     |  871 +++++++++
 drivers/media/platform/amphion/vpu_core.h     |   15 +
 drivers/media/platform/amphion/vpu_dbg.c      |  495 +++++
 drivers/media/platform/amphion/vpu_defs.h     |  187 ++
 drivers/media/platform/amphion/vpu_drv.c      |  260 +++
 drivers/media/platform/amphion/vpu_helpers.c  |  413 ++++
 drivers/media/platform/amphion/vpu_helpers.h  |   74 +
 drivers/media/platform/amphion/vpu_imx8q.c    |  271 +++
 drivers/media/platform/amphion/vpu_imx8q.h    |  115 ++
 drivers/media/platform/amphion/vpu_malone.c   | 1625 ++++++++++++++++
 drivers/media/platform/amphion/vpu_malone.h   |   44 +
 drivers/media/platform/amphion/vpu_mbox.c     |  118 ++
 drivers/media/platform/amphion/vpu_mbox.h     |   16 +
 drivers/media/platform/amphion/vpu_msgs.c     |  385 ++++
 drivers/media/platform/amphion/vpu_msgs.h     |   14 +
 drivers/media/platform/amphion/vpu_rpc.c      |  257 +++
 drivers/media/platform/amphion/vpu_rpc.h      |  456 +++++
 drivers/media/platform/amphion/vpu_v4l2.c     |  720 +++++++
 drivers/media/platform/amphion/vpu_v4l2.h     |   55 +
 drivers/media/platform/amphion/vpu_windsor.c  | 1169 ++++++++++++
 drivers/media/platform/amphion/vpu_windsor.h  |   37 +
 drivers/media/v4l2-core/v4l2-ioctl.c          |    2 +
 include/uapi/linux/videodev2.h                |    2 +
 41 files changed, 12102 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
 create mode 100644 drivers/media/platform/amphion/Makefile
 create mode 100644 drivers/media/platform/amphion/vdec.c
 create mode 100644 drivers/media/platform/amphion/venc.c
 create mode 100644 drivers/media/platform/amphion/vpu.h
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
 create mode 100644 drivers/media/platform/amphion/vpu_codec.h
 create mode 100644 drivers/media/platform/amphion/vpu_color.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.h
 create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
 create mode 100644 drivers/media/platform/amphion/vpu_defs.h
 create mode 100644 drivers/media/platform/amphion/vpu_drv.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h
 create mode 100644 drivers/media/platform/amphion/vpu_malone.c
 create mode 100644 drivers/media/platform/amphion/vpu_malone.h
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.h
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.h
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.h


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:20 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:20 +0800
Subject: [PATCH v15.1 01/13] dt-bindings: media: amphion: add amphion video
 codec bindings
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <5dbf63cd1f73be49d45126393a88a1968de7d73e.1643165765.git.ming.qian@nxp.com>

Add devicetree binding documentation for amphion
Video Processing Unit IP presents on NXP i.MX8Q

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/media/amphion,vpu.yaml           | 180 ++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/media/amphion,vpu.yaml

diff --git a/Documentation/devicetree/bindings/media/amphion,vpu.yaml b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
new file mode 100644
index 000000000000..a9d80eaeeeb6
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/amphion,vpu.yaml
@@ -0,0 +1,180 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/amphion,vpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amphion VPU codec IP
+
+maintainers:
+  - Ming Qian <ming.qian at nxp.com>
+  - Shijie Qin <shijie.qin at nxp.com>
+
+description: |-
+  The Amphion MXC video encoder(Windsor) and decoder(Malone) accelerators present
+  on NXP i.MX8Q SoCs.
+
+properties:
+  $nodename:
+    pattern: "^vpu@[0-9a-f]+$"
+
+  compatible:
+    items:
+      - enum:
+          - nxp,imx8qm-vpu
+          - nxp,imx8qxp-vpu
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^mailbox@[0-9a-f]+$":
+    description:
+      Each vpu encoder or decoder correspond a MU, which used for communication
+      between driver and firmware. Implement via mailbox on driver.
+    $ref: ../mailbox/fsl,mu.yaml#
+
+
+  "^vpu_core@[0-9a-f]+$":
+    description:
+      Each core correspond a decoder or encoder, need to configure them
+      separately. NXP i.MX8QM SoC has one decoder and two encoder, i.MX8QXP SoC
+      has one decoder and one encoder.
+    type: object
+
+    properties:
+      compatible:
+        items:
+          - enum:
+              - nxp,imx8q-vpu-decoder
+              - nxp,imx8q-vpu-encoder
+
+      reg:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+      mbox-names:
+        items:
+          - const: tx0
+          - const: tx1
+          - const: rx
+
+      mboxes:
+        description:
+          List of phandle of 2 MU channels for tx, 1 MU channel for rx.
+        maxItems: 3
+
+      memory-region:
+        description:
+          Phandle to the reserved memory nodes to be associated with the
+          remoteproc device. The reserved memory nodes should be carveout nodes,
+          and should be defined as per the bindings in
+          Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+        items:
+          - description: region reserved for firmware image sections.
+          - description: region used for RPC shared memory between firmware and
+                         driver.
+
+    required:
+      - compatible
+      - reg
+      - power-domains
+      - mbox-names
+      - mboxes
+      - memory-region
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  # Device node example for i.MX8QM platform:
+  - |
+    #include <dt-bindings/firmware/imx/rsrc.h>
+
+    vpu: vpu at 2c000000 {
+      compatible = "nxp,imx8qm-vpu";
+      ranges = <0x2c000000 0x2c000000 0x2000000>;
+      reg = <0x2c000000 0x1000000>;
+      #address-cells = <1>;
+      #size-cells = <1>;
+      power-domains = <&pd IMX_SC_R_VPU>;
+
+      mu_m0: mailbox at 2d000000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d000000 0x20000>;
+        interrupts = <0 472 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+      };
+
+      mu1_m0: mailbox at 2d020000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d020000 0x20000>;
+        interrupts = <0 473 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+      };
+
+      mu2_m0: mailbox at 2d040000 {
+        compatible = "fsl,imx6sx-mu";
+        reg = <0x2d040000 0x20000>;
+        interrupts = <0 474 4>;
+        #mbox-cells = <2>;
+        power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+      };
+
+      vpu_core0: vpu_core at 2d080000 {
+        compatible = "nxp,imx8q-vpu-decoder";
+        reg = <0x2d080000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu_m0 0 0>,
+                 <&mu_m0 0 1>,
+                 <&mu_m0 1 0>;
+        memory-region = <&decoder_boot>, <&decoder_rpc>;
+      };
+
+      vpu_core1: vpu_core at 2d090000 {
+        compatible = "nxp,imx8q-vpu-encoder";
+        reg = <0x2d090000 0x10000>;
+        power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu1_m0 0 0>,
+                 <&mu1_m0 0 1>,
+                 <&mu1_m0 1 0>;
+        memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+      };
+
+      vpu_core2: vpu_core at 2d0a0000 {
+        reg = <0x2d0a0000 0x10000>;
+        compatible = "nxp,imx8q-vpu-encoder";
+        power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+        mbox-names = "tx0", "tx1", "rx";
+        mboxes = <&mu2_m0 0 0>,
+                 <&mu2_m0 0 1>,
+                 <&mu2_m0 1 0>;
+        memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+      };
+    };
+
+...
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:21 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:21 +0800
Subject: [PATCH v15.1 02/13] media: add nv12m_8l128 and nv12m_10be_8l128 video
 format.
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <3fd0d09d382b827ddc7f97ca6e4d7b3e4c1bf4fc.1643165765.git.ming.qian@nxp.com>

nv12m_8l128 is 8-bit tiled nv12 format used by amphion decoder.
nv12m_10be_8l128 is 10-bit tiled format used by amphion decoder.
The tile size is 8x128

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../media/v4l/pixfmt-yuv-planar.rst           | 28 +++++++++++++++++--
 drivers/media/v4l2-core/v4l2-ioctl.c          |  2 ++
 include/uapi/linux/videodev2.h                |  2 ++
 3 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
index 3a09d93d405b..8b2ff1d29639 100644
--- a/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
+++ b/Documentation/userspace-api/media/v4l/pixfmt-yuv-planar.rst
@@ -257,6 +257,8 @@ of the luma plane.
 .. _V4L2-PIX-FMT-NV12-4L4:
 .. _V4L2-PIX-FMT-NV12-16L16:
 .. _V4L2-PIX-FMT-NV12-32L32:
+.. _V4L2_PIX_FMT_NV12M_8L128:
+.. _V4L2_PIX_FMT_NV12M_10BE_8L128:
 
 Tiled NV12
 ----------
@@ -281,21 +283,41 @@ If the vertical resolution is an odd number of tiles, the last row of
 tiles is stored in linear order. The layouts of the luma and chroma
 planes are identical.
 
-``V4L2_PIX_FMT_NV12_4L4`` stores pixel in 4x4 tiles, and stores
+``V4L2_PIX_FMT_NV12_4L4`` stores pixels in 4x4 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 4. The layouts of the luma and chroma planes are
 identical.
 
-``V4L2_PIX_FMT_NV12_16L16`` stores pixel in 16x16 tiles, and stores
+``V4L2_PIX_FMT_NV12_16L16`` stores pixels in 16x16 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 16. The layouts of the luma and chroma planes are
 identical.
 
-``V4L2_PIX_FMT_NV12_32L32`` stores pixel in 32x32 tiles, and stores
+``V4L2_PIX_FMT_NV12_32L32`` stores pixels in 32x32 tiles, and stores
 tiles linearly in memory. The line stride and image height must be
 aligned to a multiple of 32. The layouts of the luma and chroma planes are
 identical.
 
+``V4L2_PIX_FMT_NV12M_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+
+``V4L2_PIX_FMT_NV12M_10BE_8L128`` is similar to ``V4L2_PIX_FMT_NV12M`` but stores
+10 bits pixels in 2D 8x128 tiles, and stores tiles linearly in memory.
+the data is arranged in big endian order.
+The image height must be aligned to a multiple of 128.
+The layouts of the luma and chroma planes are identical.
+Note the tile size is 8bytes multiplied by 128 bytes,
+it means that the low bits and high bits of one pixel may be in different tiles.
+The 10 bit pixels are packed, so 5 bytes contain 4 10-bit pixels layout like
+this (for luma):
+byte 0: Y0(bits 9-2)
+byte 1: Y0(bits 1-0) Y1(bits 9-4)
+byte 2: Y1(bits 3-0) Y2(bits 9-6)
+byte 3: Y2(bits 5-0) Y3(bits 9-8)
+byte 4: Y3(bits 7-0)
+
 .. _nv12mt:
 
 .. kernel-figure:: nv12mt.svg
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 9ac557b8e146..efbfda9ec3ce 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1388,6 +1388,8 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt)
 	case V4L2_META_FMT_VIVID:       descr = "Vivid Metadata"; break;
 	case V4L2_META_FMT_RK_ISP1_PARAMS:	descr = "Rockchip ISP1 3A Parameters"; break;
 	case V4L2_META_FMT_RK_ISP1_STAT_3A:	descr = "Rockchip ISP1 3A Statistics"; break;
+	case V4L2_PIX_FMT_NV12M_8L128:	descr = "NV12M (8x128 Linear)"; break;
+	case V4L2_PIX_FMT_NV12M_10BE_8L128:	descr = "10-bit NV12M (8x128 Linear, BE)"; break;
 
 	default:
 		/* Compressed formats */
diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
index df8b9c486ba1..3768a0a80830 100644
--- a/include/uapi/linux/videodev2.h
+++ b/include/uapi/linux/videodev2.h
@@ -632,6 +632,8 @@ struct v4l2_pix_format {
 /* Tiled YUV formats, non contiguous planes */
 #define V4L2_PIX_FMT_NV12MT  v4l2_fourcc('T', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 64x32 tiles */
 #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 16x16 tiles */
+#define V4L2_PIX_FMT_NV12M_8L128      v4l2_fourcc('N', 'A', '1', '2') /* Y/CbCr 4:2:0 8x128 tiles */
+#define V4L2_PIX_FMT_NV12M_10BE_8L128 v4l2_fourcc_be('N', 'T', '1', '2') /* Y/CbCr 4:2:0 10-bit 8x128 tiles */
 
 /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
 #define V4L2_PIX_FMT_SBGGR8  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:22 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:22 +0800
Subject: [PATCH v15.1 03/13] media: amphion: add amphion vpu device driver
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <e2c24babbc6b1a73ef6ab464237f08d3d2212ee9.1643165765.git.ming.qian@nxp.com>

The amphion vpu codec ip contains encoder and decoder.
Windsor is the encoder, it supports to encode H.264.
Malone is the decoder, it features a powerful
video processing unit able to decode many formats,
such as H.264, HEVC, and other formats.

This Driver is for this IP that is based on the v4l2 mem2mem framework.

Supported SoCs are: IMX8QXP, IMX8QM

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 arch/arm64/configs/defconfig               |   1 +
 drivers/media/platform/Kconfig             |  19 ++
 drivers/media/platform/Makefile            |   2 +
 drivers/media/platform/amphion/Makefile    |  20 ++
 drivers/media/platform/amphion/vpu.h       | 356 +++++++++++++++++++++
 drivers/media/platform/amphion/vpu_defs.h  | 187 +++++++++++
 drivers/media/platform/amphion/vpu_drv.c   | 260 +++++++++++++++
 drivers/media/platform/amphion/vpu_imx8q.c | 271 ++++++++++++++++
 drivers/media/platform/amphion/vpu_imx8q.h | 115 +++++++
 9 files changed, 1231 insertions(+)
 create mode 100644 drivers/media/platform/amphion/Makefile
 create mode 100644 drivers/media/platform/amphion/vpu.h
 create mode 100644 drivers/media/platform/amphion/vpu_defs.h
 create mode 100644 drivers/media/platform/amphion/vpu_drv.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.c
 create mode 100644 drivers/media/platform/amphion/vpu_imx8q.h

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..5423075730f8 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -662,6 +662,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
+CONFIG_VIDEO_AMPHION_VPU=m
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
 CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index 9fbdba0fd1e7..947ae16c73f5 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -216,6 +216,25 @@ config VIDEO_RCAR_ISP
 	  To compile this driver as a module, choose M here: the
 	  module will be called rcar-isp.
 
+config VIDEO_AMPHION_VPU
+	tristate "Amphion VPU (Video Processing Unit) Codec IP"
+	depends on ARCH_MXC || COMPILE_TEST
+	depends on MEDIA_SUPPORT
+	depends on VIDEO_DEV
+	depends on VIDEO_V4L2
+	select MEDIA_CONTROLLER
+	select V4L2_MEM2MEM_DEV
+	select VIDEOBUF2_DMA_CONTIG
+	select VIDEOBUF2_VMALLOC
+	help
+	  Amphion VPU Codec IP contains two parts: Windsor and Malone.
+	  Windsor is encoder that supports H.264, and Malone is decoder
+	  that supports H.264, HEVC, and other video formats.
+	  This is a V4L2 driver for NXP MXC 8Q video accelerator hardware.
+	  It accelerates encoding and decoding operations on
+	  various NXP SoCs.
+	  To compile this driver as a module choose m here.
+
 endif # V4L_PLATFORM_DRIVERS
 
 menuconfig V4L_MEM2MEM_DRIVERS
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 19bcbced7382..53709df654ee 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -88,3 +88,5 @@ obj-$(CONFIG_VIDEO_QCOM_VENUS)		+= qcom/venus/
 obj-y					+= sunxi/
 
 obj-$(CONFIG_VIDEO_MESON_GE2D)		+= meson/ge2d/
+
+obj-$(CONFIG_VIDEO_AMPHION_VPU)		+= amphion/
diff --git a/drivers/media/platform/amphion/Makefile b/drivers/media/platform/amphion/Makefile
new file mode 100644
index 000000000000..80717312835f
--- /dev/null
+++ b/drivers/media/platform/amphion/Makefile
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for NXP VPU driver
+
+amphion-vpu-objs += vpu_drv.o \
+			vpu_core.o \
+			vpu_mbox.o \
+			vpu_v4l2.o \
+			vpu_helpers.o \
+			vpu_cmds.o \
+			vpu_msgs.o \
+			vpu_rpc.o \
+			vpu_imx8q.o \
+			vpu_windsor.o \
+			vpu_malone.o \
+			vpu_color.o \
+			vdec.o  \
+			venc.o \
+			vpu_dbg.o
+
+obj-$(CONFIG_VIDEO_AMPHION_VPU) += amphion-vpu.o
diff --git a/drivers/media/platform/amphion/vpu.h b/drivers/media/platform/amphion/vpu.h
new file mode 100644
index 000000000000..6c6cdfcf5535
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu.h
@@ -0,0 +1,356 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_H
+#define _AMPHION_VPU_H
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-mem2mem.h>
+#include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
+#include <linux/kfifo.h>
+
+#define VPU_TIMEOUT		msecs_to_jiffies(1000)
+#define VPU_INST_NULL_ID	(-1L)
+#define VPU_MSG_BUFFER_SIZE	(8192)
+
+enum imx_plat_type {
+	IMX8QXP = 0,
+	IMX8QM  = 1,
+	IMX8DM,
+	IMX8DX,
+	PLAT_TYPE_RESERVED
+};
+
+enum vpu_core_type {
+	VPU_CORE_TYPE_ENC = 0,
+	VPU_CORE_TYPE_DEC = 0x10,
+};
+
+struct vpu_dev;
+struct vpu_resources {
+	enum imx_plat_type plat_type;
+	u32 mreg_base;
+	int (*setup)(struct vpu_dev *vpu);
+	int (*setup_encoder)(struct vpu_dev *vpu);
+	int (*setup_decoder)(struct vpu_dev *vpu);
+	int (*reset)(struct vpu_dev *vpu);
+};
+
+struct vpu_buffer {
+	void *virt;
+	dma_addr_t phys;
+	u32 length;
+	u32 bytesused;
+	struct device *dev;
+};
+
+struct vpu_func {
+	struct video_device *vfd;
+	struct v4l2_m2m_dev *m2m_dev;
+	enum vpu_core_type type;
+	int function;
+};
+
+struct vpu_dev {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct mutex lock; /* protect vpu device */
+	const struct vpu_resources *res;
+	struct list_head cores;
+
+	struct v4l2_device v4l2_dev;
+	struct vpu_func encoder;
+	struct vpu_func decoder;
+	struct media_device mdev;
+
+	struct delayed_work watchdog_work;
+	void (*get_vpu)(struct vpu_dev *vpu);
+	void (*put_vpu)(struct vpu_dev *vpu);
+	void (*get_enc)(struct vpu_dev *vpu);
+	void (*put_enc)(struct vpu_dev *vpu);
+	void (*get_dec)(struct vpu_dev *vpu);
+	void (*put_dec)(struct vpu_dev *vpu);
+	atomic_t ref_vpu;
+	atomic_t ref_enc;
+	atomic_t ref_dec;
+
+	struct dentry *debugfs;
+};
+
+struct vpu_format {
+	u32 pixfmt;
+	unsigned int num_planes;
+	u32 type;
+	u32 flags;
+	u32 width;
+	u32 height;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 field;
+};
+
+struct vpu_core_resources {
+	enum vpu_core_type type;
+	const char *fwname;
+	u32 stride;
+	u32 max_width;
+	u32 min_width;
+	u32 step_width;
+	u32 max_height;
+	u32 min_height;
+	u32 step_height;
+	u32 rpc_size;
+	u32 fwlog_size;
+	u32 act_size;
+};
+
+struct vpu_mbox {
+	char name[20];
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	bool block;
+};
+
+enum vpu_core_state {
+	VPU_CORE_DEINIT = 0,
+	VPU_CORE_ACTIVE,
+	VPU_CORE_SNAPSHOT,
+	VPU_CORE_HANG
+};
+
+struct vpu_core {
+	void __iomem *base;
+	struct platform_device *pdev;
+	struct device *dev;
+	struct device *parent;
+	struct device *pd;
+	struct device_link *pd_link;
+	struct mutex lock;     /* protect vpu core */
+	struct mutex cmd_lock; /* Lock vpu command */
+	struct list_head list;
+	enum vpu_core_type type;
+	int id;
+	const struct vpu_core_resources *res;
+	unsigned long instance_mask;
+	u32 supported_instance_count;
+	unsigned long hang_mask;
+	u32 request_count;
+	struct list_head instances;
+	enum vpu_core_state state;
+	u32 fw_version;
+
+	struct vpu_buffer fw;
+	struct vpu_buffer rpc;
+	struct vpu_buffer log;
+	struct vpu_buffer act;
+
+	struct vpu_mbox tx_type;
+	struct vpu_mbox tx_data;
+	struct vpu_mbox rx;
+	unsigned long cmd_seq;
+
+	wait_queue_head_t ack_wq;
+	struct completion cmp;
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct delayed_work msg_delayed_work;
+	struct kfifo msg_fifo;
+	void *msg_buffer;
+	unsigned int msg_buffer_size;
+
+	struct vpu_dev *vpu;
+	void *iface;
+
+	struct dentry *debugfs;
+	struct dentry *debugfs_fwlog;
+};
+
+enum vpu_codec_state {
+	VPU_CODEC_STATE_DEINIT = 1,
+	VPU_CODEC_STATE_CONFIGURED,
+	VPU_CODEC_STATE_START,
+	VPU_CODEC_STATE_STARTED,
+	VPU_CODEC_STATE_ACTIVE,
+	VPU_CODEC_STATE_SEEK,
+	VPU_CODEC_STATE_STOP,
+	VPU_CODEC_STATE_DRAIN,
+	VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE,
+};
+
+struct vpu_frame_info {
+	u32 type;
+	u32 id;
+	u32 sequence;
+	u32 luma;
+	u32 chroma_u;
+	u32 chroma_v;
+	u32 data_offset;
+	u32 flags;
+	u32 skipped;
+	s64 timestamp;
+};
+
+struct vpu_inst;
+struct vpu_inst_ops {
+	int (*ctrl_init)(struct vpu_inst *inst);
+	int (*start)(struct vpu_inst *inst, u32 type);
+	int (*stop)(struct vpu_inst *inst, u32 type);
+	int (*abort)(struct vpu_inst *inst);
+	bool (*check_ready)(struct vpu_inst *inst, unsigned int type);
+	void (*buf_done)(struct vpu_inst *inst, struct vpu_frame_info *frame);
+	void (*event_notify)(struct vpu_inst *inst, u32 event, void *data);
+	void (*release)(struct vpu_inst *inst);
+	void (*cleanup)(struct vpu_inst *inst);
+	void (*mem_request)(struct vpu_inst *inst,
+			    u32 enc_frame_size,
+			    u32 enc_frame_num,
+			    u32 ref_frame_size,
+			    u32 ref_frame_num,
+			    u32 act_frame_size,
+			    u32 act_frame_num);
+	void (*input_done)(struct vpu_inst *inst);
+	void (*stop_done)(struct vpu_inst *inst);
+	int (*process_output)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*process_capture)(struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*get_one_frame)(struct vpu_inst *inst, void *info);
+	void (*on_queue_empty)(struct vpu_inst *inst, u32 type);
+	int (*get_debug_info)(struct vpu_inst *inst, char *str, u32 size, u32 i);
+	void (*wait_prepare)(struct vpu_inst *inst);
+	void (*wait_finish)(struct vpu_inst *inst);
+};
+
+struct vpu_inst {
+	struct list_head list;
+	struct mutex lock; /* v4l2 and videobuf2 lock */
+	struct vpu_dev *vpu;
+	struct vpu_core *core;
+	struct device *dev;
+	int id;
+
+	struct v4l2_fh fh;
+	struct v4l2_ctrl_handler ctrl_handler;
+	atomic_t ref_count;
+	int (*release)(struct vpu_inst *inst);
+
+	enum vpu_codec_state state;
+	enum vpu_core_type type;
+
+	struct workqueue_struct *workqueue;
+	struct work_struct msg_work;
+	struct kfifo msg_fifo;
+	u8 msg_buffer[VPU_MSG_BUFFER_SIZE];
+
+	struct vpu_buffer stream_buffer;
+	bool use_stream_buffer;
+	struct vpu_buffer act;
+
+	struct list_head cmd_q;
+	void *pending;
+
+	struct vpu_inst_ops *ops;
+	const struct vpu_format *formats;
+	struct vpu_format out_format;
+	struct vpu_format cap_format;
+	u32 min_buffer_cap;
+	u32 min_buffer_out;
+
+	struct v4l2_rect crop;
+	u32 colorspace;
+	u8 ycbcr_enc;
+	u8 quantization;
+	u8 xfer_func;
+	u32 sequence;
+	u32 extra_size;
+
+	u32 flows[16];
+	u32 flow_idx;
+
+	pid_t pid;
+	pid_t tgid;
+	struct dentry *debugfs;
+
+	void *priv;
+};
+
+#define call_vop(inst, op, args...)					\
+	((inst)->ops->op ? (inst)->ops->op(inst, ##args) : 0)		\
+
+enum {
+	VPU_BUF_STATE_IDLE = 0,
+	VPU_BUF_STATE_INUSE,
+	VPU_BUF_STATE_DECODED,
+	VPU_BUF_STATE_READY,
+	VPU_BUF_STATE_SKIP,
+	VPU_BUF_STATE_ERROR
+};
+
+struct vpu_vb2_buffer {
+	struct v4l2_m2m_buffer m2m_buf;
+	dma_addr_t luma;
+	dma_addr_t chroma_u;
+	dma_addr_t chroma_v;
+	unsigned int state;
+	u32 tag;
+};
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val);
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg);
+
+static inline struct vpu_vb2_buffer *to_vpu_vb2_buffer(struct vb2_v4l2_buffer *vbuf)
+{
+	struct v4l2_m2m_buffer *m2m_buf = container_of(vbuf, struct v4l2_m2m_buffer, vb);
+
+	return container_of(m2m_buf, struct vpu_vb2_buffer, m2m_buf);
+}
+
+static inline const char *vpu_core_type_desc(enum vpu_core_type type)
+{
+	return type == VPU_CORE_TYPE_ENC ? "encoder" : "decoder";
+}
+
+static inline struct vpu_inst *to_inst(struct file *filp)
+{
+	return container_of(filp->private_data, struct vpu_inst, fh);
+}
+
+#define ctrl_to_inst(ctrl)	\
+	container_of((ctrl)->handler, struct vpu_inst, ctrl_handler)
+
+const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void);
+const struct v4l2_file_operations *venc_get_fops(void);
+const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void);
+const struct v4l2_file_operations *vdec_get_fops(void);
+
+int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func);
+void vpu_remove_func(struct vpu_func *func);
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst);
+void vpu_inst_put(struct vpu_inst *inst);
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type);
+void vpu_release_core(struct vpu_core *core);
+int vpu_inst_register(struct vpu_inst *inst);
+int vpu_inst_unregister(struct vpu_inst *inst);
+const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst);
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst);
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst);
+int vpu_core_create_dbgfs_file(struct vpu_core *core);
+int vpu_core_remove_dbgfs_file(struct vpu_core *core);
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow);
+
+int vpu_core_driver_init(void);
+void vpu_core_driver_exit(void);
+
+extern bool debug;
+#define vpu_trace(dev, fmt, arg...)					\
+	do {								\
+		if (debug)						\
+			dev_info(dev, "%s: " fmt, __func__, ## arg);	\
+	} while (0)
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_defs.h b/drivers/media/platform/amphion/vpu_defs.h
new file mode 100644
index 000000000000..282664202dcf
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_defs.h
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_DEFS_H
+#define _AMPHION_VPU_DEFS_H
+
+enum MSG_TYPE {
+	INIT_DONE = 1,
+	PRC_BUF_OFFSET,
+	BOOT_ADDRESS,
+	COMMAND,
+	EVENT,
+};
+
+enum {
+	VPU_IRQ_CODE_BOOT_DONE = 0x55,
+	VPU_IRQ_CODE_SNAPSHOT_DONE = 0xa5,
+	VPU_IRQ_CODE_SYNC = 0xaa,
+};
+
+enum {
+	VPU_CMD_ID_NOOP = 0x0,
+	VPU_CMD_ID_CONFIGURE_CODEC,
+	VPU_CMD_ID_START,
+	VPU_CMD_ID_STOP,
+	VPU_CMD_ID_ABORT,
+	VPU_CMD_ID_RST_BUF,
+	VPU_CMD_ID_SNAPSHOT,
+	VPU_CMD_ID_FIRM_RESET,
+	VPU_CMD_ID_UPDATE_PARAMETER,
+	VPU_CMD_ID_FRAME_ENCODE,
+	VPU_CMD_ID_SKIP,
+	VPU_CMD_ID_PARSE_NEXT_SEQ,
+	VPU_CMD_ID_PARSE_NEXT_I,
+	VPU_CMD_ID_PARSE_NEXT_IP,
+	VPU_CMD_ID_PARSE_NEXT_ANY,
+	VPU_CMD_ID_DEC_PIC,
+	VPU_CMD_ID_FS_ALLOC,
+	VPU_CMD_ID_FS_RELEASE,
+	VPU_CMD_ID_TIMESTAMP,
+	VPU_CMD_ID_DEBUG
+};
+
+enum {
+	VPU_MSG_ID_NOOP = 0x100,
+	VPU_MSG_ID_RESET_DONE,
+	VPU_MSG_ID_START_DONE,
+	VPU_MSG_ID_STOP_DONE,
+	VPU_MSG_ID_ABORT_DONE,
+	VPU_MSG_ID_BUF_RST,
+	VPU_MSG_ID_MEM_REQUEST,
+	VPU_MSG_ID_PARAM_UPD_DONE,
+	VPU_MSG_ID_FRAME_INPUT_DONE,
+	VPU_MSG_ID_ENC_DONE,
+	VPU_MSG_ID_DEC_DONE,
+	VPU_MSG_ID_FRAME_REQ,
+	VPU_MSG_ID_FRAME_RELEASE,
+	VPU_MSG_ID_SEQ_HDR_FOUND,
+	VPU_MSG_ID_RES_CHANGE,
+	VPU_MSG_ID_PIC_HDR_FOUND,
+	VPU_MSG_ID_PIC_DECODED,
+	VPU_MSG_ID_PIC_EOS,
+	VPU_MSG_ID_FIFO_LOW,
+	VPU_MSG_ID_FIFO_HIGH,
+	VPU_MSG_ID_FIFO_EMPTY,
+	VPU_MSG_ID_FIFO_FULL,
+	VPU_MSG_ID_BS_ERROR,
+	VPU_MSG_ID_UNSUPPORTED,
+	VPU_MSG_ID_TIMESTAMP_INFO,
+
+	VPU_MSG_ID_FIRMWARE_XCPT,
+};
+
+enum VPU_ENC_MEMORY_RESOURSE {
+	MEM_RES_ENC,
+	MEM_RES_REF,
+	MEM_RES_ACT
+};
+
+enum VPU_DEC_MEMORY_RESOURCE {
+	MEM_RES_FRAME,
+	MEM_RES_MBI,
+	MEM_RES_DCP
+};
+
+enum VPU_SCODE_TYPE {
+	SCODE_PADDING_EOS = 1,
+	SCODE_PADDING_BUFFLUSH = 2,
+	SCODE_PADDING_ABORT = 3,
+	SCODE_SEQUENCE = 0x31,
+	SCODE_PICTURE = 0x32,
+	SCODE_SLICE = 0x33
+};
+
+struct vpu_pkt_mem_req_data {
+	u32 enc_frame_size;
+	u32 enc_frame_num;
+	u32 ref_frame_size;
+	u32 ref_frame_num;
+	u32 act_buf_size;
+	u32 act_buf_num;
+};
+
+struct vpu_enc_pic_info {
+	u32 frame_id;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 frame_size;
+	u32 wptr;
+	u32 crc;
+	s64 timestamp;
+};
+
+struct vpu_dec_codec_info {
+	u32 pixfmt;
+	u32 num_ref_frms;
+	u32 num_dpb_frms;
+	u32 num_dfe_area;
+	u32 color_primaries;
+	u32 transfer_chars;
+	u32 matrix_coeffs;
+	u32 full_range;
+	u32 vui_present;
+	u32 progressive;
+	u32 width;
+	u32 height;
+	u32 decoded_width;
+	u32 decoded_height;
+	struct v4l2_fract frame_rate;
+	u32 dsp_asp_ratio;
+	u32 level_idc;
+	u32 bit_depth_luma;
+	u32 bit_depth_chroma;
+	u32 chroma_fmt;
+	u32 mvc_num_views;
+	u32 offset_x;
+	u32 offset_y;
+	u32 tag;
+	u32 sizeimage[VIDEO_MAX_PLANES];
+	u32 bytesperline[VIDEO_MAX_PLANES];
+	u32 mbi_size;
+	u32 dcp_size;
+	u32 stride;
+};
+
+struct vpu_dec_pic_info {
+	u32 id;
+	u32 luma;
+	u32 start;
+	u32 end;
+	u32 pic_size;
+	u32 stride;
+	u32 skipped;
+	s64 timestamp;
+	u32 consumed_count;
+};
+
+struct vpu_fs_info {
+	u32 id;
+	u32 type;
+	u32 tag;
+	u32 luma_addr;
+	u32 luma_size;
+	u32 chroma_addr;
+	u32 chromau_size;
+	u32 chromav_addr;
+	u32 chromav_size;
+	u32 bytesperline;
+	u32 not_displayed;
+};
+
+struct vpu_ts_info {
+	s64 timestamp;
+	u32 size;
+};
+
+#define BITRATE_STEP		(1024)
+#define BITRATE_MIN		(16 * BITRATE_STEP)
+#define BITRATE_MAX		(240 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT		(2 * 1024 * BITRATE_STEP)
+#define BITRATE_DEFAULT_PEAK	(BITRATE_DEFAULT * 2)
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_drv.c b/drivers/media/platform/amphion/vpu_drv.c
new file mode 100644
index 000000000000..83ca04452c02
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_drv.c
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/dma-map-ops.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <linux/of_reserved_mem.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_imx8q.h"
+
+bool debug;
+module_param(debug, bool, 0644);
+
+void vpu_writel(struct vpu_dev *vpu, u32 reg, u32 val)
+{
+	writel(val, vpu->base + reg);
+}
+
+u32 vpu_readl(struct vpu_dev *vpu, u32 reg)
+{
+	return readl(vpu->base + reg);
+}
+
+static void vpu_dev_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_vpu) == 1 && vpu->res->setup)
+		vpu->res->setup(vpu);
+}
+
+static void vpu_dev_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_vpu);
+}
+
+static void vpu_enc_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_enc) == 1 && vpu->res->setup_encoder)
+		vpu->res->setup_encoder(vpu);
+}
+
+static void vpu_enc_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_enc);
+}
+
+static void vpu_dec_get(struct vpu_dev *vpu)
+{
+	if (atomic_inc_return(&vpu->ref_dec) == 1 && vpu->res->setup_decoder)
+		vpu->res->setup_decoder(vpu);
+}
+
+static void vpu_dec_put(struct vpu_dev *vpu)
+{
+	atomic_dec(&vpu->ref_dec);
+}
+
+static int vpu_init_media_device(struct vpu_dev *vpu)
+{
+	vpu->mdev.dev = vpu->dev;
+	strscpy(vpu->mdev.model, "amphion-vpu", sizeof(vpu->mdev.model));
+	strscpy(vpu->mdev.bus_info, "platform: amphion-vpu", sizeof(vpu->mdev.bus_info));
+	media_device_init(&vpu->mdev);
+	vpu->v4l2_dev.mdev = &vpu->mdev;
+
+	return 0;
+}
+
+static int vpu_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_dev *vpu;
+	int ret;
+
+	dev_dbg(dev, "probe\n");
+	vpu = devm_kzalloc(dev, sizeof(*vpu), GFP_KERNEL);
+	if (!vpu)
+		return -ENOMEM;
+
+	vpu->pdev = pdev;
+	vpu->dev = dev;
+	mutex_init(&vpu->lock);
+	INIT_LIST_HEAD(&vpu->cores);
+	platform_set_drvdata(pdev, vpu);
+	atomic_set(&vpu->ref_vpu, 0);
+	atomic_set(&vpu->ref_enc, 0);
+	atomic_set(&vpu->ref_dec, 0);
+	vpu->get_vpu = vpu_dev_get;
+	vpu->put_vpu = vpu_dev_put;
+	vpu->get_enc = vpu_enc_get;
+	vpu->put_enc = vpu_enc_put;
+	vpu->get_dec = vpu_dec_get;
+	vpu->put_dec = vpu_dec_put;
+
+	vpu->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(vpu->base))
+		return PTR_ERR(vpu->base);
+
+	vpu->res = of_device_get_match_data(dev);
+	if (!vpu->res)
+		return -ENODEV;
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	pm_runtime_put_sync(dev);
+
+	ret = v4l2_device_register(dev, &vpu->v4l2_dev);
+	if (ret)
+		goto err_vpu_deinit;
+
+	vpu_init_media_device(vpu);
+	vpu->encoder.type = VPU_CORE_TYPE_ENC;
+	vpu->encoder.function = MEDIA_ENT_F_PROC_VIDEO_ENCODER;
+	vpu->decoder.type = VPU_CORE_TYPE_DEC;
+	vpu->decoder.function = MEDIA_ENT_F_PROC_VIDEO_DECODER;
+	vpu_add_func(vpu, &vpu->decoder);
+	vpu_add_func(vpu, &vpu->encoder);
+	ret = media_device_register(&vpu->mdev);
+	if (ret)
+		goto err_vpu_media;
+	vpu->debugfs = debugfs_create_dir("amphion_vpu", NULL);
+
+	of_platform_populate(dev->of_node, NULL, NULL, dev);
+
+	return 0;
+
+err_vpu_media:
+	vpu_remove_func(&vpu->encoder);
+	vpu_remove_func(&vpu->decoder);
+	v4l2_device_unregister(&vpu->v4l2_dev);
+err_vpu_deinit:
+err_runtime_disable:
+	pm_runtime_set_suspended(dev);
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_remove(struct platform_device *pdev)
+{
+	struct vpu_dev *vpu = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	debugfs_remove_recursive(vpu->debugfs);
+	vpu->debugfs = NULL;
+
+	pm_runtime_disable(dev);
+
+	media_device_unregister(&vpu->mdev);
+	vpu_remove_func(&vpu->decoder);
+	vpu_remove_func(&vpu->encoder);
+	media_device_cleanup(&vpu->mdev);
+	v4l2_device_unregister(&vpu->v4l2_dev);
+	mutex_destroy(&vpu->lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int __maybe_unused vpu_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static const struct dev_pm_ops vpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_runtime_suspend, vpu_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_suspend, vpu_resume)
+};
+
+struct vpu_resources imx8qxp_res = {
+	.plat_type = IMX8QXP,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+struct vpu_resources imx8qm_res = {
+	.plat_type = IMX8QM,
+	.mreg_base = 0x40000000,
+	.setup = vpu_imx8q_setup,
+	.setup_encoder = vpu_imx8q_setup_enc,
+	.setup_decoder = vpu_imx8q_setup_dec,
+	.reset = vpu_imx8q_reset
+};
+
+static const struct of_device_id vpu_dt_match[] = {
+	{ .compatible = "nxp,imx8qxp-vpu", .data = &imx8qxp_res },
+	{ .compatible = "nxp,imx8qm-vpu", .data = &imx8qm_res },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_dt_match);
+
+static struct platform_driver amphion_vpu_driver = {
+	.probe = vpu_probe,
+	.remove = vpu_remove,
+	.driver = {
+		.name = "amphion-vpu",
+		.of_match_table = vpu_dt_match,
+		.pm = &vpu_pm_ops,
+	},
+};
+
+static int __init vpu_driver_init(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&amphion_vpu_driver);
+	if (ret)
+		return ret;
+
+	return vpu_core_driver_init();
+}
+
+static void __exit vpu_driver_exit(void)
+{
+	vpu_core_driver_exit();
+	platform_driver_unregister(&amphion_vpu_driver);
+}
+module_init(vpu_driver_init);
+module_exit(vpu_driver_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("Linux VPU driver for Freescale i.MX8Q");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/amphion/vpu_imx8q.c b/drivers/media/platform/amphion/vpu_imx8q.c
new file mode 100644
index 000000000000..606cc53125f8
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_imx8q.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_imx8q.h"
+#include "vpu_rpc.h"
+
+#define IMX8Q_CSR_CM0Px_ADDR_OFFSET			0x00000000
+#define IMX8Q_CSR_CM0Px_CPUWAIT				0x00000004
+
+#ifdef CONFIG_IMX_SCU
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+
+#define VPU_DISABLE_BITS			0x7
+#define VPU_IMX_DECODER_FUSE_OFFSET		14
+#define VPU_ENCODER_MASK			0x1
+#define VPU_DECODER_MASK			0x3UL
+#define VPU_DECODER_H264_MASK			0x2UL
+#define VPU_DECODER_HEVC_MASK			0x1UL
+
+static u32 imx8q_fuse;
+
+struct vpu_sc_msg_misc {
+	struct imx_sc_rpc_msg hdr;
+	u32 word;
+} __packed;
+#endif
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET, 0x1f);
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_SET, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+int vpu_imx8q_setup(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_readl(vpu, offset + 0x108);
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0x1);
+	vpu_writel(vpu, offset + 0x190, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_XMEM_RESET_SET, 0xffffffff);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_SCB_CLK_ENABLE_SET, 0xE);
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_SET, 0x7);
+	vpu_writel(vpu, XMEM_CONTROL, 0x102);
+
+	vpu_readl(vpu, offset + 0x108);
+
+	return 0;
+}
+
+static int vpu_imx8q_reset_enc(struct vpu_dev *vpu)
+{
+	return 0;
+}
+
+static int vpu_imx8q_reset_dec(struct vpu_dev *vpu)
+{
+	const off_t offset = DEC_MFD_XREG_SLV_BASE + MFD_BLK_CTRL;
+
+	vpu_writel(vpu, offset + MFD_BLK_CTRL_MFD_SYS_RESET_CLR, 0xffffffff);
+
+	return 0;
+}
+
+int vpu_imx8q_reset(struct vpu_dev *vpu)
+{
+	const off_t offset = SCB_XREG_SLV_BASE + SCB_SCB_BLK_CTRL;
+
+	vpu_writel(vpu, offset + SCB_BLK_CTRL_CACHE_RESET_CLR, 0x7);
+	vpu_imx8q_reset_enc(vpu);
+	vpu_imx8q_reset_dec(vpu);
+
+	return 0;
+}
+
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config, u32 regs, u32 core_id)
+{
+	if (!config)
+		return -EINVAL;
+
+	switch (core_id) {
+	case 0:
+		config->malone_base_addr[0] = regs + DEC_MFD_XREG_SLV_BASE;
+		config->num_malones = 1;
+		config->num_windsors = 0;
+		break;
+	case 1:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_0_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	case 2:
+		config->windsor_base_addr[0] = regs + ENC_MFD_XREG_SLV_1_BASE;
+		config->num_windsors = 1;
+		config->num_malones = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if (config->num_windsors) {
+		config->windsor_irq_pin[0x0][0x0] = WINDSOR_PAL_IRQ_PIN_L;
+		config->windsor_irq_pin[0x0][0x1] = WINDSOR_PAL_IRQ_PIN_H;
+	}
+
+	config->malone_base_addr[0x1] = 0x0;
+	config->hif_offset[0x0] = MFD_HIF;
+	config->hif_offset[0x1] = 0x0;
+
+	config->dpv_base_addr = 0x0;
+	config->dpv_irq_pin = 0x0;
+	config->pixif_base_addr = regs + DEC_MFD_XREG_SLV_BASE + MFD_PIX_IF;
+	config->cache_base_addr[0] = regs + MC_CACHE_0_BASE;
+	config->cache_base_addr[1] = regs + MC_CACHE_1_BASE;
+
+	return 0;
+}
+
+int vpu_imx8q_boot_core(struct vpu_core *core)
+{
+	csr_writel(core, IMX8Q_CSR_CM0Px_ADDR_OFFSET, core->fw.phys);
+	csr_writel(core, IMX8Q_CSR_CM0Px_CPUWAIT, 0);
+	return 0;
+}
+
+int vpu_imx8q_get_power_state(struct vpu_core *core)
+{
+	if (csr_readl(core, IMX8Q_CSR_CM0Px_CPUWAIT) == 1)
+		return 0;
+	return 1;
+}
+
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core)
+{
+	u8 *p;
+
+	p = core->fw.virt;
+	p[16] = core->vpu->res->plat_type;
+	p[17] = core->id;
+	p[18] = 1;
+
+	return 0;
+}
+
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size)
+{
+	const struct vpu_rpc_region_t imx8q_regions[] = {
+		{0x00000000, 0x08000000, VPU_CORE_MEMORY_CACHED},
+		{0x08000000, 0x10000000, VPU_CORE_MEMORY_UNCACHED},
+		{0x10000000, 0x20000000, VPU_CORE_MEMORY_CACHED},
+		{0x20000000, 0x40000000, VPU_CORE_MEMORY_UNCACHED}
+	};
+	int i;
+
+	if (addr < base)
+		return VPU_CORE_MEMORY_INVALID;
+
+	addr -= base;
+	for (i = 0; i < ARRAY_SIZE(imx8q_regions); i++) {
+		const struct vpu_rpc_region_t *region = &imx8q_regions[i];
+
+		if (addr >= region->start && addr + size < region->end)
+			return region->type;
+	}
+
+	return VPU_CORE_MEMORY_INVALID;
+}
+
+#ifdef CONFIG_IMX_SCU
+static u32 vpu_imx8q_get_fuse(void)
+{
+	static u32 fuse_got;
+	struct imx_sc_ipc *ipc;
+	struct vpu_sc_msg_misc msg;
+	struct imx_sc_rpc_msg *hdr = &msg.hdr;
+	int ret;
+
+	if (fuse_got)
+		return imx8q_fuse;
+
+	ret = imx_scu_get_handle(&ipc);
+	if (ret) {
+		pr_err("error: get sct handle fail: %d\n", ret);
+		return 0;
+	}
+
+	hdr->ver = IMX_SC_RPC_VERSION;
+	hdr->svc = IMX_SC_RPC_SVC_MISC;
+	hdr->func = IMX_SC_MISC_FUNC_OTP_FUSE_READ;
+	hdr->size = 2;
+
+	msg.word = VPU_DISABLE_BITS;
+
+	ret = imx_scu_call_rpc(ipc, &msg, true);
+	if (ret)
+		return 0;
+
+	imx8q_fuse = msg.word;
+	fuse_got = 1;
+	return imx8q_fuse;
+}
+
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_ENC) {
+		if (fuse & VPU_ENCODER_MASK)
+			return false;
+	} else if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	u32 fuse = vpu_imx8q_get_fuse();
+
+	if (type == VPU_CORE_TYPE_DEC) {
+		fuse >>= VPU_IMX_DECODER_FUSE_OFFSET;
+		fuse &= VPU_DECODER_MASK;
+
+		if (fuse == VPU_DECODER_HEVC_MASK && pixelfmt == V4L2_PIX_FMT_HEVC)
+			return false;
+		if (fuse == VPU_DECODER_H264_MASK && pixelfmt == V4L2_PIX_FMT_H264)
+			return false;
+		if (fuse == VPU_DECODER_MASK)
+			return false;
+	}
+
+	return true;
+}
+#else
+bool vpu_imx8q_check_codec(enum vpu_core_type type)
+{
+	return true;
+}
+
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt)
+{
+	return true;
+}
+#endif
diff --git a/drivers/media/platform/amphion/vpu_imx8q.h b/drivers/media/platform/amphion/vpu_imx8q.h
new file mode 100644
index 000000000000..d63a2747e29c
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_imx8q.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_IMX8Q_H
+#define _AMPHION_VPU_IMX8Q_H
+
+#define SCB_XREG_SLV_BASE                               0x00000000
+#define SCB_SCB_BLK_CTRL                                0x00070000
+#define SCB_BLK_CTRL_XMEM_RESET_SET                     0x00000090
+#define SCB_BLK_CTRL_CACHE_RESET_SET                    0x000000A0
+#define SCB_BLK_CTRL_CACHE_RESET_CLR                    0x000000A4
+#define SCB_BLK_CTRL_SCB_CLK_ENABLE_SET                 0x00000100
+
+#define XMEM_CONTROL                                    0x00041000
+
+#define	MC_CACHE_0_BASE					0x00060000
+#define	MC_CACHE_1_BASE					0x00068000
+
+#define DEC_MFD_XREG_SLV_BASE                           0x00180000
+#define ENC_MFD_XREG_SLV_0_BASE				0x00800000
+#define ENC_MFD_XREG_SLV_1_BASE				0x00A00000
+
+#define MFD_HIF                                         0x0001C000
+#define MFD_HIF_MSD_REG_INTERRUPT_STATUS                0x00000018
+#define MFD_SIF                                         0x0001D000
+#define MFD_SIF_CTRL_STATUS                             0x000000F0
+#define MFD_SIF_INTR_STATUS                             0x000000F4
+#define MFD_MCX                                         0x00020800
+#define MFD_MCX_OFF                                     0x00000020
+#define MFD_PIX_IF					0x00020000
+
+#define MFD_BLK_CTRL                                    0x00030000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_SET                  0x00000000
+#define MFD_BLK_CTRL_MFD_SYS_RESET_CLR                  0x00000004
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_SET           0x00000100
+#define MFD_BLK_CTRL_MFD_SYS_CLOCK_ENABLE_CLR           0x00000104
+
+#define VID_API_NUM_STREAMS				8
+#define VID_API_MAX_BUF_PER_STR				3
+#define VID_API_MAX_NUM_MVC_VIEWS			4
+#define MEDIAIP_MAX_NUM_MALONES				2
+#define MEDIAIP_MAX_NUM_MALONE_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_WINDSORS			1
+#define MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS		2
+#define MEDIAIP_MAX_NUM_CMD_IRQ_PINS			2
+#define MEDIAIP_MAX_NUM_MSG_IRQ_PINS			1
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_PINS			4
+#define MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS			4
+
+#define WINDSOR_PAL_IRQ_PIN_L				0x4
+#define WINDSOR_PAL_IRQ_PIN_H				0x5
+
+struct vpu_rpc_system_config {
+	u32 cfg_cookie;
+
+	u32 num_malones;
+	u32 malone_base_addr[MEDIAIP_MAX_NUM_MALONES];
+	u32 hif_offset[MEDIAIP_MAX_NUM_MALONES];
+	u32 malone_irq_pin[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+	u32 malone_irq_target[MEDIAIP_MAX_NUM_MALONES][MEDIAIP_MAX_NUM_MALONE_IRQ_PINS];
+
+	u32 num_windsors;
+	u32 windsor_base_addr[MEDIAIP_MAX_NUM_WINDSORS];
+	u32 windsor_irq_pin[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+	u32 windsor_irq_target[MEDIAIP_MAX_NUM_WINDSORS][MEDIAIP_MAX_NUM_WINDSOR_IRQ_PINS];
+
+	u32 cmd_irq_pin[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+	u32 cmd_irq_target[MEDIAIP_MAX_NUM_CMD_IRQ_PINS];
+
+	u32 msg_irq_pin[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+	u32 msg_irq_target[MEDIAIP_MAX_NUM_MSG_IRQ_PINS];
+
+	u32 sys_clk_freq;
+	u32 num_timers;
+	u32 timer_base_addr;
+	u32 timer_irq_pin[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_irq_target[MEDIAIP_MAX_NUM_TIMER_IRQ_PINS];
+	u32 timer_slots[MEDIAIP_MAX_NUM_TIMER_IRQ_SLOTS];
+
+	u32 gic_base_addr;
+	u32 uart_base_addr;
+
+	u32 dpv_base_addr;
+	u32 dpv_irq_pin;
+	u32 dpv_irq_target;
+
+	u32 pixif_base_addr;
+
+	u32 pal_trace_level;
+	u32 pal_trace_destination;
+
+	u32 pal_trace_level1;
+	u32 pal_trace_destination1;
+
+	u32 heap_base;
+	u32 heap_size;
+
+	u32 cache_base_addr[2];
+};
+
+int vpu_imx8q_setup_dec(struct vpu_dev *vpu);
+int vpu_imx8q_setup_enc(struct vpu_dev *vpu);
+int vpu_imx8q_setup(struct vpu_dev *vpu);
+int vpu_imx8q_reset(struct vpu_dev *vpu);
+int vpu_imx8q_set_system_cfg_common(struct vpu_rpc_system_config *config, u32 regs, u32 core_id);
+int vpu_imx8q_boot_core(struct vpu_core *core);
+int vpu_imx8q_get_power_state(struct vpu_core *core);
+int vpu_imx8q_on_firmware_loaded(struct vpu_core *core);
+u32 vpu_imx8q_check_memory_region(dma_addr_t base, dma_addr_t addr, u32 size);
+bool vpu_imx8q_check_codec(enum vpu_core_type type);
+bool vpu_imx8q_check_fmt(enum vpu_core_type type, u32 pixelfmt);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:23 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:23 +0800
Subject: [PATCH v15.1 04/13] media: amphion: add vpu core driver
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <d20efa77469544e2c545a5c44ed392101ee63325.1643165765.git.ming.qian@nxp.com>

The vpu supports encoder and decoder.
it needs vpu core to handle it.
core will run either encoder or decoder firmware.

This driver is for support the vpu core.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_codec.h |  68 ++
 drivers/media/platform/amphion/vpu_core.c  | 871 +++++++++++++++++++++
 drivers/media/platform/amphion/vpu_core.h  |  15 +
 drivers/media/platform/amphion/vpu_dbg.c   | 495 ++++++++++++
 drivers/media/platform/amphion/vpu_rpc.c   | 257 ++++++
 drivers/media/platform/amphion/vpu_rpc.h   | 456 +++++++++++
 6 files changed, 2162 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_codec.h
 create mode 100644 drivers/media/platform/amphion/vpu_core.c
 create mode 100644 drivers/media/platform/amphion/vpu_core.h
 create mode 100644 drivers/media/platform/amphion/vpu_dbg.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.c
 create mode 100644 drivers/media/platform/amphion/vpu_rpc.h

diff --git a/drivers/media/platform/amphion/vpu_codec.h b/drivers/media/platform/amphion/vpu_codec.h
new file mode 100644
index 000000000000..528a93f08ecd
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_codec.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CODEC_H
+#define _AMPHION_VPU_CODEC_H
+
+struct vpu_encode_params {
+	u32 input_format;
+	u32 codec_format;
+	u32 profile;
+	u32 tier;
+	u32 level;
+	struct v4l2_fract frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	struct v4l2_rect crop;
+	u32 out_width;
+	u32 out_height;
+
+	u32 gop_length;
+	u32 bframes;
+
+	u32 rc_enable;
+	u32 rc_mode;
+	u32 bitrate;
+	u32 bitrate_min;
+	u32 bitrate_max;
+
+	u32 i_frame_qp;
+	u32 p_frame_qp;
+	u32 b_frame_qp;
+	u32 qp_min;
+	u32 qp_max;
+	u32 qp_min_i;
+	u32 qp_max_i;
+
+	struct {
+		u32 enable;
+		u32 idc;
+		u32 width;
+		u32 height;
+	} sar;
+
+	struct {
+		u32 primaries;
+		u32 transfer;
+		u32 matrix;
+		u32 full_range;
+	} color;
+};
+
+struct vpu_decode_params {
+	u32 codec_format;
+	u32 output_format;
+	u32 b_dis_reorder;
+	u32 b_non_frame;
+	u32 frame_count;
+	u32 end_flag;
+	struct {
+		u32 base;
+		u32 size;
+	} udata;
+};
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c
new file mode 100644
index 000000000000..07dcc8bb1c94
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_core.c
@@ -0,0 +1,871 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <linux/pm_domain.h>
+#include <linux/firmware.h>
+#include <linux/vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+#include "vpu_rpc.h"
+#include "vpu_cmds.h"
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val)
+{
+	writel(val, core->base + reg);
+}
+
+u32 csr_readl(struct vpu_core *core, u32 reg)
+{
+	return readl(core->base + reg);
+}
+
+static int vpu_core_load_firmware(struct vpu_core *core)
+{
+	const struct firmware *pfw = NULL;
+	int ret = 0;
+
+	if (!core->fw.virt) {
+		dev_err(core->dev, "firmware buffer is not ready\n");
+		return -EINVAL;
+	}
+
+	ret = request_firmware(&pfw, core->res->fwname, core->dev);
+	dev_dbg(core->dev, "request_firmware %s : %d\n", core->res->fwname, ret);
+	if (ret) {
+		dev_err(core->dev, "request firmware %s failed, ret = %d\n",
+			core->res->fwname, ret);
+		return ret;
+	}
+
+	if (core->fw.length < pfw->size) {
+		dev_err(core->dev, "firmware buffer size want %zu, but %d\n",
+			pfw->size, core->fw.length);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	memset_io(core->fw.virt, 0, core->fw.length);
+	memcpy(core->fw.virt, pfw->data, pfw->size);
+	core->fw.bytesused = pfw->size;
+	ret = vpu_iface_on_firmware_loaded(core);
+exit:
+	release_firmware(pfw);
+	pfw = NULL;
+
+	return ret;
+}
+
+static int vpu_core_boot_done(struct vpu_core *core)
+{
+	u32 fw_version;
+
+	fw_version = vpu_iface_get_version(core);
+	dev_info(core->dev, "%s firmware version : %d.%d.%d\n",
+		 vpu_core_type_desc(core->type),
+		 (fw_version >> 16) & 0xff,
+		 (fw_version >> 8) & 0xff,
+		 fw_version & 0xff);
+	core->supported_instance_count = vpu_iface_get_max_instance_count(core);
+	if (core->res->act_size) {
+		u32 count = core->act.length / core->res->act_size;
+
+		core->supported_instance_count = min(core->supported_instance_count, count);
+	}
+	core->fw_version = fw_version;
+	core->state = VPU_CORE_ACTIVE;
+
+	return 0;
+}
+
+static int vpu_core_wait_boot_done(struct vpu_core *core)
+{
+	int ret;
+
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "boot timeout\n");
+		return -EINVAL;
+	}
+	return vpu_core_boot_done(core);
+}
+
+static int vpu_core_boot(struct vpu_core *core, bool load)
+{
+	int ret;
+
+	reinit_completion(&core->cmp);
+	if (load) {
+		ret = vpu_core_load_firmware(core);
+		if (ret)
+			return ret;
+	}
+
+	vpu_iface_boot_core(core);
+	return vpu_core_wait_boot_done(core);
+}
+
+static int vpu_core_shutdown(struct vpu_core *core)
+{
+	return vpu_iface_shutdown_core(core);
+}
+
+static int vpu_core_restore(struct vpu_core *core)
+{
+	int ret;
+
+	ret = vpu_core_sw_reset(core);
+	if (ret)
+		return ret;
+
+	vpu_core_boot_done(core);
+	return vpu_iface_restore_core(core);
+}
+
+static int __vpu_alloc_dma(struct device *dev, struct vpu_buffer *buf)
+{
+	gfp_t gfp = GFP_KERNEL | GFP_DMA32;
+
+	if (!buf->length)
+		return 0;
+
+	buf->virt = dma_alloc_coherent(dev, buf->length, &buf->phys, gfp);
+	if (!buf->virt)
+		return -ENOMEM;
+
+	buf->dev = dev;
+
+	return 0;
+}
+
+void vpu_free_dma(struct vpu_buffer *buf)
+{
+	if (!buf->virt || !buf->dev)
+		return;
+
+	dma_free_coherent(buf->dev, buf->length, buf->virt, buf->phys);
+	buf->virt = NULL;
+	buf->phys = 0;
+	buf->length = 0;
+	buf->bytesused = 0;
+	buf->dev = NULL;
+}
+
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf)
+{
+	return __vpu_alloc_dma(core->dev, buf);
+}
+
+static void vpu_core_check_hang(struct vpu_core *core)
+{
+	if (core->hang_mask)
+		core->state = VPU_CORE_HANG;
+}
+
+static struct vpu_core *vpu_core_find_proper_by_type(struct vpu_dev *vpu, u32 type)
+{
+	struct vpu_core *core = NULL;
+	int request_count = INT_MAX;
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		dev_dbg(c->dev, "instance_mask = 0x%lx, state = %d\n", c->instance_mask, c->state);
+		if (c->type != type)
+			continue;
+		if (c->state == VPU_CORE_DEINIT) {
+			core = c;
+			break;
+		}
+		vpu_core_check_hang(c);
+		if (c->state != VPU_CORE_ACTIVE)
+			continue;
+		if (c->request_count < request_count) {
+			request_count = c->request_count;
+			core = c;
+		}
+		if (!request_count)
+			break;
+	}
+
+	return core;
+}
+
+static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core)
+{
+	struct vpu_core *c;
+
+	list_for_each_entry(c, &vpu->cores, list) {
+		if (c == core)
+			return true;
+	}
+
+	return false;
+}
+
+static void vpu_core_get_vpu(struct vpu_core *core)
+{
+	core->vpu->get_vpu(core->vpu);
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->get_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->get_dec(core->vpu);
+}
+
+static int vpu_core_register(struct device *dev, struct vpu_core *core)
+{
+	struct vpu_dev *vpu = dev_get_drvdata(dev);
+	int ret = 0;
+
+	dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type));
+	if (vpu_core_is_exist(vpu, core))
+		return 0;
+
+	core->workqueue = alloc_workqueue("vpu", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!core->workqueue) {
+		dev_err(core->dev, "fail to alloc workqueue\n");
+		return -ENOMEM;
+	}
+	INIT_WORK(&core->msg_work, vpu_msg_run_work);
+	INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
+	core->msg_buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
+	core->msg_buffer = vzalloc(core->msg_buffer_size);
+	if (!core->msg_buffer) {
+		dev_err(core->dev, "failed allocate buffer for fifo\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	ret = kfifo_init(&core->msg_fifo, core->msg_buffer, core->msg_buffer_size);
+	if (ret) {
+		dev_err(core->dev, "failed init kfifo\n");
+		goto error;
+	}
+
+	list_add_tail(&core->list, &vpu->cores);
+
+	vpu_core_get_vpu(core);
+
+	if (vpu_iface_get_power_state(core))
+		ret = vpu_core_restore(core);
+	if (ret)
+		goto error;
+
+	return 0;
+error:
+	if (core->msg_buffer) {
+		vfree(core->msg_buffer);
+		core->msg_buffer = NULL;
+	}
+	if (core->workqueue) {
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+	return ret;
+}
+
+static void vpu_core_put_vpu(struct vpu_core *core)
+{
+	if (core->type == VPU_CORE_TYPE_ENC)
+		core->vpu->put_enc(core->vpu);
+	if (core->type == VPU_CORE_TYPE_DEC)
+		core->vpu->put_dec(core->vpu);
+	core->vpu->put_vpu(core->vpu);
+}
+
+static int vpu_core_unregister(struct device *dev, struct vpu_core *core)
+{
+	list_del_init(&core->list);
+
+	vpu_core_put_vpu(core);
+	core->vpu = NULL;
+	vfree(core->msg_buffer);
+	core->msg_buffer = NULL;
+
+	if (core->workqueue) {
+		cancel_work_sync(&core->msg_work);
+		cancel_delayed_work_sync(&core->msg_delayed_work);
+		destroy_workqueue(core->workqueue);
+		core->workqueue = NULL;
+	}
+
+	return 0;
+}
+
+static int vpu_core_acquire_instance(struct vpu_core *core)
+{
+	int id;
+
+	id = ffz(core->instance_mask);
+	if (id >= core->supported_instance_count)
+		return -EINVAL;
+
+	set_bit(id, &core->instance_mask);
+
+	return id;
+}
+
+static void vpu_core_release_instance(struct vpu_core *core, int id)
+{
+	if (id < 0 || id >= core->supported_instance_count)
+		return;
+
+	clear_bit(id, &core->instance_mask);
+}
+
+struct vpu_inst *vpu_inst_get(struct vpu_inst *inst)
+{
+	if (!inst)
+		return NULL;
+
+	atomic_inc(&inst->ref_count);
+
+	return inst;
+}
+
+void vpu_inst_put(struct vpu_inst *inst)
+{
+	if (!inst)
+		return;
+	if (atomic_dec_and_test(&inst->ref_count)) {
+		if (inst->release)
+			inst->release(inst);
+	}
+}
+
+struct vpu_core *vpu_request_core(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_core *core = NULL;
+	int ret;
+
+	mutex_lock(&vpu->lock);
+
+	core = vpu_core_find_proper_by_type(vpu, type);
+	if (!core)
+		goto exit;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(core->dev);
+
+	if (core->state == VPU_CORE_DEINIT) {
+		ret = vpu_core_boot(core, true);
+		if (ret) {
+			pm_runtime_put_sync(core->dev);
+			mutex_unlock(&core->lock);
+			core = NULL;
+			goto exit;
+		}
+	}
+
+	core->request_count++;
+
+	mutex_unlock(&core->lock);
+exit:
+	mutex_unlock(&vpu->lock);
+
+	return core;
+}
+
+void vpu_release_core(struct vpu_core *core)
+{
+	if (!core)
+		return;
+
+	mutex_lock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+	if (core->request_count)
+		core->request_count--;
+	mutex_unlock(&core->lock);
+}
+
+int vpu_inst_register(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	struct vpu_core *core;
+	int ret = 0;
+
+	vpu = inst->vpu;
+	core = inst->core;
+	if (!core) {
+		core = vpu_request_core(vpu, inst->type);
+		if (!core) {
+			dev_err(vpu->dev, "there is no vpu core for %s\n",
+				vpu_core_type_desc(inst->type));
+			return -EINVAL;
+		}
+		inst->core = core;
+		inst->dev = get_device(core->dev);
+	}
+
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count)
+		goto exit;
+
+	ret = vpu_core_acquire_instance(core);
+	if (ret < 0)
+		goto exit;
+
+	vpu_trace(inst->dev, "[%d] %p\n", ret, inst);
+	inst->id = ret;
+	list_add_tail(&inst->list, &core->instances);
+	ret = 0;
+	if (core->res->act_size) {
+		inst->act.phys = core->act.phys + core->res->act_size * inst->id;
+		inst->act.virt = core->act.virt + core->res->act_size * inst->id;
+		inst->act.length = core->res->act_size;
+	}
+	vpu_inst_create_dbgfs_file(inst);
+exit:
+	mutex_unlock(&core->lock);
+
+	if (ret)
+		dev_err(core->dev, "register instance fail\n");
+	return ret;
+}
+
+int vpu_inst_unregister(struct vpu_inst *inst)
+{
+	struct vpu_core *core;
+
+	if (!inst->core)
+		return 0;
+
+	core = inst->core;
+	vpu_clear_request(inst);
+	mutex_lock(&core->lock);
+	if (inst->id >= 0 && inst->id < core->supported_instance_count) {
+		vpu_inst_remove_dbgfs_file(inst);
+		list_del_init(&inst->list);
+		vpu_core_release_instance(core, inst->id);
+		inst->id = VPU_INST_NULL_ID;
+	}
+	vpu_core_check_hang(core);
+	if (core->state == VPU_CORE_HANG && !core->instance_mask) {
+		dev_info(core->dev, "reset hang core\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index)
+{
+	struct vpu_inst *inst = NULL;
+	struct vpu_inst *tmp;
+
+	mutex_lock(&core->lock);
+	if (!test_bit(index, &core->instance_mask))
+		goto exit;
+	list_for_each_entry(tmp, &core->instances, list) {
+		if (tmp->id == index) {
+			inst = vpu_inst_get(tmp);
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->lock);
+
+	return inst;
+}
+
+const struct vpu_core_resources *vpu_get_resource(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	struct vpu_core *core = NULL;
+	const struct vpu_core_resources *res = NULL;
+
+	if (!inst || !inst->vpu)
+		return NULL;
+
+	if (inst->core && inst->core->res)
+		return inst->core->res;
+
+	vpu = inst->vpu;
+	mutex_lock(&vpu->lock);
+	list_for_each_entry(core, &vpu->cores, list) {
+		if (core->type == inst->type) {
+			res = core->res;
+			break;
+		}
+	}
+	mutex_unlock(&vpu->lock);
+
+	return res;
+}
+
+static int vpu_core_parse_dt(struct vpu_core *core, struct device_node *np)
+{
+	struct device_node *node;
+	struct resource res;
+	int ret;
+
+	if (of_count_phandle_with_args(np, "memory-region", NULL) < 2) {
+		dev_err(core->dev, "need 2 memory-region for boot and rpc\n");
+		return -ENODEV;
+	}
+
+	node = of_parse_phandle(np, "memory-region", 0);
+	if (!node) {
+		dev_err(core->dev, "boot-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		dev_err(core->dev, "boot-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->fw.phys = res.start;
+	core->fw.length = resource_size(&res);
+
+	node = of_parse_phandle(np, "memory-region", 1);
+	if (!node) {
+		dev_err(core->dev, "rpc-region of_parse_phandle error\n");
+		return -ENODEV;
+	}
+	if (of_address_to_resource(node, 0, &res)) {
+		dev_err(core->dev, "rpc-region of_address_to_resource error\n");
+		return -EINVAL;
+	}
+	core->rpc.phys = res.start;
+	core->rpc.length = resource_size(&res);
+
+	if (core->rpc.length < core->res->rpc_size + core->res->fwlog_size) {
+		dev_err(core->dev, "the rpc-region <%pad, 0x%x> is not enough\n",
+			&core->rpc.phys, core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->fw.virt = ioremap_wc(core->fw.phys, core->fw.length);
+	core->rpc.virt = ioremap_wc(core->rpc.phys, core->rpc.length);
+	memset_io(core->rpc.virt, 0, core->rpc.length);
+
+	ret = vpu_iface_check_memory_region(core, core->rpc.phys, core->rpc.length);
+	if (ret != VPU_CORE_MEMORY_UNCACHED) {
+		dev_err(core->dev, "rpc region<%pad, 0x%x> isn't uncached\n",
+			&core->rpc.phys, core->rpc.length);
+		return -EINVAL;
+	}
+
+	core->log.phys = core->rpc.phys + core->res->rpc_size;
+	core->log.virt = core->rpc.virt + core->res->rpc_size;
+	core->log.length = core->res->fwlog_size;
+	core->act.phys = core->log.phys + core->log.length;
+	core->act.virt = core->log.virt + core->log.length;
+	core->act.length = core->rpc.length - core->res->rpc_size - core->log.length;
+	core->rpc.length = core->res->rpc_size;
+
+	return 0;
+}
+
+static int vpu_core_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core;
+	struct vpu_dev *vpu = dev_get_drvdata(dev->parent);
+	struct vpu_shared_addr *iface;
+	u32 iface_data_size;
+	int ret;
+
+	dev_dbg(dev, "probe\n");
+	if (!vpu)
+		return -EINVAL;
+	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+
+	core->pdev = pdev;
+	core->dev = dev;
+	platform_set_drvdata(pdev, core);
+	core->vpu = vpu;
+	INIT_LIST_HEAD(&core->instances);
+	mutex_init(&core->lock);
+	mutex_init(&core->cmd_lock);
+	init_completion(&core->cmp);
+	init_waitqueue_head(&core->ack_wq);
+	core->state = VPU_CORE_DEINIT;
+
+	core->res = of_device_get_match_data(dev);
+	if (!core->res)
+		return -ENODEV;
+
+	core->type = core->res->type;
+	core->id = of_alias_get_id(dev->of_node, "vpu_core");
+	if (core->id < 0) {
+		dev_err(dev, "can't get vpu core id\n");
+		return core->id;
+	}
+	dev_info(core->dev, "[%d] = %s\n", core->id, vpu_core_type_desc(core->type));
+	ret = vpu_core_parse_dt(core, dev->of_node);
+	if (ret)
+		return ret;
+
+	core->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->base))
+		return PTR_ERR(core->base);
+
+	if (!vpu_iface_check_codec(core)) {
+		dev_err(core->dev, "is not supported\n");
+		return -EINVAL;
+	}
+
+	ret = vpu_mbox_init(core);
+	if (ret)
+		return ret;
+
+	iface = devm_kzalloc(dev, sizeof(*iface), GFP_KERNEL);
+	if (!iface)
+		return -ENOMEM;
+
+	iface_data_size = vpu_iface_get_data_size(core);
+	if (iface_data_size) {
+		iface->priv = devm_kzalloc(dev, iface_data_size, GFP_KERNEL);
+		if (!iface->priv)
+			return -ENOMEM;
+	}
+
+	ret = vpu_iface_init(core, iface, &core->rpc, core->fw.phys);
+	if (ret) {
+		dev_err(core->dev, "init iface fail, ret = %d\n", ret);
+		return ret;
+	}
+
+	vpu_iface_config_system(core, vpu->res->mreg_base, vpu->base);
+	vpu_iface_set_log_buf(core, &core->log);
+
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret) {
+		pm_runtime_put_noidle(dev);
+		pm_runtime_set_suspended(dev);
+		goto err_runtime_disable;
+	}
+
+	ret = vpu_core_register(dev->parent, core);
+	if (ret)
+		goto err_core_register;
+	core->parent = dev->parent;
+
+	pm_runtime_put_sync(dev);
+	vpu_core_create_dbgfs_file(core);
+
+	return 0;
+
+err_core_register:
+	pm_runtime_put_sync(dev);
+err_runtime_disable:
+	pm_runtime_disable(dev);
+
+	return ret;
+}
+
+static int vpu_core_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct vpu_core *core = platform_get_drvdata(pdev);
+	int ret;
+
+	vpu_core_remove_dbgfs_file(core);
+	ret = pm_runtime_get_sync(dev);
+	WARN_ON(ret < 0);
+
+	vpu_core_shutdown(core);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+	vpu_core_unregister(core->parent, core);
+	iounmap(core->fw.virt);
+	iounmap(core->rpc.virt);
+	mutex_destroy(&core->lock);
+	mutex_destroy(&core->cmd_lock);
+
+	return 0;
+}
+
+static int __maybe_unused vpu_core_runtime_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	return vpu_mbox_request(core);
+}
+
+static int __maybe_unused vpu_core_runtime_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+
+	vpu_mbox_free(core);
+	return 0;
+}
+
+static void vpu_core_cancel_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+
+	cancel_work_sync(&core->msg_work);
+	cancel_delayed_work_sync(&core->msg_delayed_work);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		cancel_work_sync(&inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static void vpu_core_resume_work(struct vpu_core *core)
+{
+	struct vpu_inst *inst = NULL;
+	unsigned long delay = msecs_to_jiffies(10);
+
+	queue_work(core->workqueue, &core->msg_work);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list)
+		queue_work(inst->workqueue, &inst->msg_work);
+	mutex_unlock(&core->lock);
+}
+
+static int __maybe_unused vpu_core_resume(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	pm_runtime_get_sync(dev);
+	vpu_core_get_vpu(core);
+	if (core->state != VPU_CORE_SNAPSHOT)
+		goto exit;
+
+	if (!vpu_iface_get_power_state(core)) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_boot(core, false);
+			if (ret) {
+				dev_err(core->dev, "%s boot fail\n", __func__);
+				core->state = VPU_CORE_DEINIT;
+				goto exit;
+			}
+		} else {
+			core->state = VPU_CORE_DEINIT;
+		}
+	} else {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_sw_reset(core);
+			if (ret) {
+				dev_err(core->dev, "%s sw_reset fail\n", __func__);
+				core->state = VPU_CORE_HANG;
+				goto exit;
+			}
+		}
+		core->state = VPU_CORE_ACTIVE;
+	}
+
+exit:
+	pm_runtime_put_sync(dev);
+	mutex_unlock(&core->lock);
+
+	vpu_core_resume_work(core);
+	return ret;
+}
+
+static int __maybe_unused vpu_core_suspend(struct device *dev)
+{
+	struct vpu_core *core = dev_get_drvdata(dev);
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	if (core->state == VPU_CORE_ACTIVE) {
+		if (!list_empty(&core->instances)) {
+			ret = vpu_core_snapshot(core);
+			if (ret) {
+				mutex_unlock(&core->lock);
+				return ret;
+			}
+		}
+
+		core->state = VPU_CORE_SNAPSHOT;
+	}
+	mutex_unlock(&core->lock);
+
+	vpu_core_cancel_work(core);
+
+	mutex_lock(&core->lock);
+	vpu_core_put_vpu(core);
+	mutex_unlock(&core->lock);
+	return ret;
+}
+
+static const struct dev_pm_ops vpu_core_pm_ops = {
+	SET_RUNTIME_PM_OPS(vpu_core_runtime_suspend, vpu_core_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(vpu_core_suspend, vpu_core_resume)
+};
+
+static struct vpu_core_resources imx8q_enc = {
+	.type = VPU_CORE_TYPE_ENC,
+	.fwname = "vpu/vpu_fw_imx8_enc.bin",
+	.stride = 16,
+	.max_width = 1920,
+	.max_height = 1920,
+	.min_width = 64,
+	.min_height = 48,
+	.step_width = 2,
+	.step_height = 2,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+	.act_size = 0xc0000,
+};
+
+static struct vpu_core_resources imx8q_dec = {
+	.type = VPU_CORE_TYPE_DEC,
+	.fwname = "vpu/vpu_fw_imx8_dec.bin",
+	.stride = 256,
+	.max_width = 8188,
+	.max_height = 8188,
+	.min_width = 16,
+	.min_height = 16,
+	.step_width = 1,
+	.step_height = 1,
+	.rpc_size = 0x80000,
+	.fwlog_size = 0x80000,
+};
+
+static const struct of_device_id vpu_core_dt_match[] = {
+	{ .compatible = "nxp,imx8q-vpu-encoder", .data = &imx8q_enc },
+	{ .compatible = "nxp,imx8q-vpu-decoder", .data = &imx8q_dec },
+	{}
+};
+MODULE_DEVICE_TABLE(of, vpu_core_dt_match);
+
+static struct platform_driver amphion_vpu_core_driver = {
+	.probe = vpu_core_probe,
+	.remove = vpu_core_remove,
+	.driver = {
+		.name = "amphion-vpu-core",
+		.of_match_table = vpu_core_dt_match,
+		.pm = &vpu_core_pm_ops,
+	},
+};
+
+int __init vpu_core_driver_init(void)
+{
+	return platform_driver_register(&amphion_vpu_core_driver);
+}
+
+void __exit vpu_core_driver_exit(void)
+{
+	platform_driver_unregister(&amphion_vpu_core_driver);
+}
diff --git a/drivers/media/platform/amphion/vpu_core.h b/drivers/media/platform/amphion/vpu_core.h
new file mode 100644
index 000000000000..00a662997da4
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_core.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CORE_H
+#define _AMPHION_VPU_CORE_H
+
+void csr_writel(struct vpu_core *core, u32 reg, u32 val);
+u32 csr_readl(struct vpu_core *core, u32 reg);
+int vpu_alloc_dma(struct vpu_core *core, struct vpu_buffer *buf);
+void vpu_free_dma(struct vpu_buffer *buf);
+struct vpu_inst *vpu_core_find_instance(struct vpu_core *core, u32 index);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_dbg.c b/drivers/media/platform/amphion/vpu_dbg.c
new file mode 100644
index 000000000000..23a01c0dbf9d
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_dbg.c
@@ -0,0 +1,495 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pm_runtime.h>
+#include <media/v4l2-device.h>
+#include <linux/debugfs.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_v4l2.h"
+
+struct print_buf_desc {
+	u32 start_h_phy;
+	u32 start_h_vir;
+	u32 start_m;
+	u32 bytes;
+	u32 read;
+	u32 write;
+	char buffer[0];
+};
+
+static char *vb2_stat_name[] = {
+	[VB2_BUF_STATE_DEQUEUED] = "dequeued",
+	[VB2_BUF_STATE_IN_REQUEST] = "in_request",
+	[VB2_BUF_STATE_PREPARING] = "preparing",
+	[VB2_BUF_STATE_QUEUED] = "queued",
+	[VB2_BUF_STATE_ACTIVE] = "active",
+	[VB2_BUF_STATE_DONE] = "done",
+	[VB2_BUF_STATE_ERROR] = "error",
+};
+
+static char *vpu_stat_name[] = {
+	[VPU_BUF_STATE_IDLE] = "idle",
+	[VPU_BUF_STATE_INUSE] = "inuse",
+	[VPU_BUF_STATE_DECODED] = "decoded",
+	[VPU_BUF_STATE_READY] = "ready",
+	[VPU_BUF_STATE_SKIP] = "skip",
+	[VPU_BUF_STATE_ERROR] = "error",
+};
+
+static int vpu_dbg_instance(struct seq_file *s, void *data)
+{
+	struct vpu_inst *inst = s->private;
+	char str[128];
+	int num;
+	struct vb2_queue *vq;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(inst->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "state = %d\n", inst->state);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"min_buffer_out = %d, min_buffer_cap = %d\n",
+			inst->min_buffer_out, inst->min_buffer_cap);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"output (%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			vq->num_buffers,
+			inst->out_format.pixfmt,
+			inst->out_format.pixfmt >> 8,
+			inst->out_format.pixfmt >> 16,
+			inst->out_format.pixfmt >> 24,
+			inst->out_format.width,
+			inst->out_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->out_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->out_format.sizeimage[i],
+				inst->out_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+
+	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	num = scnprintf(str, sizeof(str),
+			"capture(%2d, %2d): fmt = %c%c%c%c %d x %d, %d;",
+			vb2_is_streaming(vq),
+			vq->num_buffers,
+			inst->cap_format.pixfmt,
+			inst->cap_format.pixfmt >> 8,
+			inst->cap_format.pixfmt >> 16,
+			inst->cap_format.pixfmt >> 24,
+			inst->cap_format.width,
+			inst->cap_format.height,
+			vq->last_buffer_dequeued);
+	if (seq_write(s, str, num))
+		return 0;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		num = scnprintf(str, sizeof(str), " %d(%d)",
+				inst->cap_format.sizeimage[i],
+				inst->cap_format.bytesperline[i]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	if (seq_write(s, "\n", 1))
+		return 0;
+	num = scnprintf(str, sizeof(str), "crop: (%d, %d) %d x %d\n",
+			inst->crop.left,
+			inst->crop.top,
+			inst->crop.width,
+			inst->crop.height);
+	if (seq_write(s, str, num))
+		return 0;
+
+	vq = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"output [%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_get_buffer_state(vbuf)]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	vq = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	for (i = 0; i < vq->num_buffers; i++) {
+		struct vb2_buffer *vb = vq->bufs[i];
+		struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+		if (vb->state == VB2_BUF_STATE_DEQUEUED)
+			continue;
+		num = scnprintf(str, sizeof(str),
+				"capture[%2d] state = %10s, %8s\n",
+				i, vb2_stat_name[vb->state],
+				vpu_stat_name[vpu_get_buffer_state(vbuf)]);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	num = scnprintf(str, sizeof(str), "sequence = %d\n", inst->sequence);
+	if (seq_write(s, str, num))
+		return 0;
+
+	if (inst->use_stream_buffer) {
+		num = scnprintf(str, sizeof(str), "stream_buffer = %d / %d, <%pad, 0x%x>\n",
+				vpu_helper_get_used_space(inst),
+				inst->stream_buffer.length,
+				&inst->stream_buffer.phys,
+				inst->stream_buffer.length);
+		if (seq_write(s, str, num))
+			return 0;
+	}
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&inst->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "flow :\n");
+	if (seq_write(s, str, num))
+		return 0;
+
+	mutex_lock(&inst->core->cmd_lock);
+	for (i = 0; i < ARRAY_SIZE(inst->flows); i++) {
+		u32 idx = (inst->flow_idx + i) % (ARRAY_SIZE(inst->flows));
+
+		if (!inst->flows[idx])
+			continue;
+		num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n",
+				inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C",
+				inst->flows[idx]);
+		if (seq_write(s, str, num)) {
+			mutex_unlock(&inst->core->cmd_lock);
+			return 0;
+		}
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+
+	i = 0;
+	while (true) {
+		num = call_vop(inst, get_debug_info, str, sizeof(str), i++);
+		if (num <= 0)
+			break;
+		if (seq_write(s, str, num))
+			return 0;
+	}
+
+	return 0;
+}
+
+static int vpu_dbg_core(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct vpu_shared_addr *iface = core->iface;
+	char str[128];
+	int num;
+
+	num = scnprintf(str, sizeof(str), "[%s]\n", vpu_core_type_desc(core->type));
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "boot_region  = <%pad, 0x%x>\n",
+			&core->fw.phys, core->fw.length);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "rpc_region   = <%pad, 0x%x> used = 0x%x\n",
+			&core->rpc.phys, core->rpc.length, core->rpc.bytesused);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "fwlog_region = <%pad, 0x%x>\n",
+			&core->log.phys, core->log.length);
+	if (seq_write(s, str, num))
+		return 0;
+
+	num = scnprintf(str, sizeof(str), "state = %d\n", core->state);
+	if (seq_write(s, str, num))
+		return 0;
+	if (core->state == VPU_CORE_DEINIT)
+		return 0;
+	num = scnprintf(str, sizeof(str), "fw version = %d.%d.%d\n",
+			(core->fw_version >> 16) & 0xff,
+			(core->fw_version >> 8) & 0xff,
+			core->fw_version & 0xff);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "instances = %d/%d (0x%02lx), %d\n",
+			hweight32(core->instance_mask),
+			core->supported_instance_count,
+			core->instance_mask,
+			core->request_count);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str), "kfifo len = 0x%x\n", kfifo_len(&core->msg_fifo));
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"cmd_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->cmd_desc->start,
+			iface->cmd_desc->end,
+			iface->cmd_desc->wptr,
+			iface->cmd_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+	num = scnprintf(str, sizeof(str),
+			"msg_buf:[0x%x, 0x%x], wptr = 0x%x, rptr = 0x%x\n",
+			iface->msg_desc->start,
+			iface->msg_desc->end,
+			iface->msg_desc->wptr,
+			iface->msg_desc->rptr);
+	if (seq_write(s, str, num))
+		return 0;
+
+	return 0;
+}
+
+static int vpu_dbg_fwlog(struct seq_file *s, void *data)
+{
+	struct vpu_core *core = s->private;
+	struct print_buf_desc *print_buf;
+	int length;
+	u32 rptr;
+	u32 wptr;
+	int ret = 0;
+
+	if (!core->log.virt || core->state == VPU_CORE_DEINIT)
+		return 0;
+
+	print_buf = core->log.virt;
+	rptr = print_buf->read;
+	wptr = print_buf->write;
+
+	if (rptr == wptr)
+		return 0;
+	else if (rptr < wptr)
+		length = wptr - rptr;
+	else
+		length = print_buf->bytes + wptr - rptr;
+
+	if (s->count + length >= s->size) {
+		s->count = s->size;
+		return 0;
+	}
+
+	if (rptr + length >= print_buf->bytes) {
+		int num = print_buf->bytes - rptr;
+
+		if (seq_write(s, print_buf->buffer + rptr, num))
+			ret = -1;
+		length -= num;
+		rptr = 0;
+	}
+
+	if (length) {
+		if (seq_write(s, print_buf->buffer + rptr, length))
+			ret = -1;
+		rptr += length;
+	}
+	if (!ret)
+		print_buf->read = rptr;
+
+	return 0;
+}
+
+static int vpu_dbg_inst_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_instance, inode->i_private);
+}
+
+static ssize_t vpu_dbg_inst_write(struct file *file,
+				  const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_inst *inst = s->private;
+
+	vpu_session_debug(inst);
+
+	return size;
+}
+
+static ssize_t vpu_dbg_core_write(struct file *file,
+				  const char __user *user_buf, size_t size, loff_t *ppos)
+{
+	struct seq_file *s = file->private_data;
+	struct vpu_core *core = s->private;
+
+	pm_runtime_get_sync(core->dev);
+	mutex_lock(&core->lock);
+	if (core->state != VPU_CORE_DEINIT && !core->instance_mask) {
+		dev_info(core->dev, "reset\n");
+		if (!vpu_core_sw_reset(core)) {
+			core->state = VPU_CORE_ACTIVE;
+			core->hang_mask = 0;
+		}
+	}
+	mutex_unlock(&core->lock);
+	pm_runtime_put_sync(core->dev);
+
+	return size;
+}
+
+static int vpu_dbg_core_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_core, inode->i_private);
+}
+
+static int vpu_dbg_fwlog_open(struct inode *inode, struct file *filp)
+{
+	return single_open(filp, vpu_dbg_fwlog, inode->i_private);
+}
+
+static const struct file_operations vpu_dbg_inst_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_inst_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_inst_write,
+};
+
+static const struct file_operations vpu_dbg_core_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_core_open,
+	.release = single_release,
+	.read = seq_read,
+	.write = vpu_dbg_core_write,
+};
+
+static const struct file_operations vpu_dbg_fwlog_fops = {
+	.owner = THIS_MODULE,
+	.open = vpu_dbg_fwlog_open,
+	.release = single_release,
+	.read = seq_read,
+};
+
+int vpu_inst_create_dbgfs_file(struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!inst || !inst->core || !inst->core->vpu)
+		return -EINVAL;
+
+	vpu = inst->core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (inst->debugfs)
+		return 0;
+
+	scnprintf(name, sizeof(name), "instance.%d.%d", inst->core->id, inst->id);
+	inst->debugfs = debugfs_create_file((const char *)name,
+					    VERIFY_OCTAL_PERMISSIONS(0644),
+					    vpu->debugfs,
+					    inst,
+					    &vpu_dbg_inst_fops);
+	if (!inst->debugfs) {
+		dev_err(inst->dev, "vpu create debugfs %s fail\n", name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_inst_remove_dbgfs_file(struct vpu_inst *inst)
+{
+	if (!inst)
+		return 0;
+
+	debugfs_remove(inst->debugfs);
+	inst->debugfs = NULL;
+
+	return 0;
+}
+
+int vpu_core_create_dbgfs_file(struct vpu_core *core)
+{
+	struct vpu_dev *vpu;
+	char name[64];
+
+	if (!core || !core->vpu)
+		return -EINVAL;
+
+	vpu = core->vpu;
+	if (!vpu->debugfs)
+		return -EINVAL;
+
+	if (!core->debugfs) {
+		scnprintf(name, sizeof(name), "core.%d", core->id);
+		core->debugfs = debugfs_create_file((const char *)name,
+						    VERIFY_OCTAL_PERMISSIONS(0644),
+						    vpu->debugfs,
+						    core,
+						    &vpu_dbg_core_fops);
+		if (!core->debugfs) {
+			dev_err(core->dev, "vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+	if (!core->debugfs_fwlog) {
+		scnprintf(name, sizeof(name), "fwlog.%d", core->id);
+		core->debugfs_fwlog = debugfs_create_file((const char *)name,
+							  VERIFY_OCTAL_PERMISSIONS(0444),
+							  vpu->debugfs,
+							  core,
+							  &vpu_dbg_fwlog_fops);
+		if (!core->debugfs_fwlog) {
+			dev_err(core->dev, "vpu create debugfs %s fail\n", name);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_core_remove_dbgfs_file(struct vpu_core *core)
+{
+	if (!core)
+		return 0;
+	debugfs_remove(core->debugfs);
+	core->debugfs = NULL;
+	debugfs_remove(core->debugfs_fwlog);
+	core->debugfs_fwlog = NULL;
+
+	return 0;
+}
+
+void vpu_inst_record_flow(struct vpu_inst *inst, u32 flow)
+{
+	if (!inst)
+		return;
+
+	inst->flows[inst->flow_idx] = flow;
+	inst->flow_idx = (inst->flow_idx + 1) % (ARRAY_SIZE(inst->flows));
+}
diff --git a/drivers/media/platform/amphion/vpu_rpc.c b/drivers/media/platform/amphion/vpu_rpc.c
new file mode 100644
index 000000000000..16fb55927e0e
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_rpc.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/firmware/imx/ipc.h>
+#include <linux/firmware/imx/svc/misc.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+#include "vpu_malone.h"
+
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->check_memory_region)
+		return VPU_CORE_MEMORY_INVALID;
+
+	return ops->check_memory_region(core->fw.phys, addr, size);
+}
+
+static u32 vpu_rpc_check_buffer_space(struct vpu_rpc_buffer_desc *desc, bool write)
+{
+	u32 ptr1;
+	u32 ptr2;
+	u32 size;
+
+	size = desc->end - desc->start;
+	if (write) {
+		ptr1 = desc->wptr;
+		ptr2 = desc->rptr;
+	} else {
+		ptr1 = desc->rptr;
+		ptr2 = desc->wptr;
+	}
+
+	if (ptr1 == ptr2) {
+		if (!write)
+			return 0;
+		else
+			return size;
+	}
+
+	return (ptr2 + size - ptr1) % size;
+}
+
+static int vpu_rpc_send_cmd_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *cmd)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 *data;
+	u32 wptr;
+	u32 i;
+
+	desc = shared->cmd_desc;
+	space = vpu_rpc_check_buffer_space(desc, true);
+	if (space < (((cmd->hdr.num + 1) << 2) + 16))
+		return -EINVAL;
+	wptr = desc->wptr;
+	data = (u32 *)(shared->cmd_mem_vir + desc->wptr - desc->start);
+	*data = 0;
+	*data |= ((cmd->hdr.index & 0xff) << 24);
+	*data |= ((cmd->hdr.num & 0xff) << 16);
+	*data |= (cmd->hdr.id & 0x3fff);
+	wptr += 4;
+	data++;
+	if (wptr >= desc->end) {
+		wptr = desc->start;
+		data = shared->cmd_mem_vir;
+	}
+
+	for (i = 0; i < cmd->hdr.num; i++) {
+		*data = cmd->data[i];
+		wptr += 4;
+		data++;
+		if (wptr >= desc->end) {
+			wptr = desc->start;
+			data = shared->cmd_mem_vir;
+		}
+	}
+
+	/*update wptr after data is written*/
+	mb();
+	desc->wptr = wptr;
+
+	return 0;
+}
+
+static bool vpu_rpc_check_msg(struct vpu_shared_addr *shared)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 space = 0;
+	u32 msgword;
+	u32 msgnum;
+
+	desc = shared->msg_desc;
+	space = vpu_rpc_check_buffer_space(desc, 0);
+	space = (space >> 2);
+
+	if (space) {
+		msgword = *(u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+		msgnum = (msgword & 0xff0000) >> 16;
+		if (msgnum <= space)
+			return true;
+	}
+
+	return false;
+}
+
+static int vpu_rpc_receive_msg_buf(struct vpu_shared_addr *shared, struct vpu_rpc_event *msg)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	u32 *data;
+	u32 msgword;
+	u32 rptr;
+	u32 i;
+
+	if (!vpu_rpc_check_msg(shared))
+		return -EINVAL;
+
+	desc = shared->msg_desc;
+	data = (u32 *)(shared->msg_mem_vir + desc->rptr - desc->start);
+	rptr = desc->rptr;
+	msgword = *data;
+	data++;
+	rptr += 4;
+	if (rptr >= desc->end) {
+		rptr = desc->start;
+		data = shared->msg_mem_vir;
+	}
+
+	msg->hdr.index = (msgword >> 24) & 0xff;
+	msg->hdr.num = (msgword >> 16) & 0xff;
+	msg->hdr.id = msgword & 0x3fff;
+
+	if (msg->hdr.num > ARRAY_SIZE(msg->data))
+		return -EINVAL;
+
+	for (i = 0; i < msg->hdr.num; i++) {
+		msg->data[i] = *data;
+		data++;
+		rptr += 4;
+		if (rptr >= desc->end) {
+			rptr = desc->start;
+			data = shared->msg_mem_vir;
+		}
+	}
+
+	/*update rptr after data is read*/
+	mb();
+	desc->rptr = rptr;
+
+	return 0;
+}
+
+struct vpu_iface_ops imx8q_rpc_ops[] = {
+	[VPU_CORE_TYPE_ENC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_windsor_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_windsor_init_rpc,
+		.set_log_buf = vpu_windsor_set_log_buf,
+		.set_system_cfg = vpu_windsor_set_system_cfg,
+		.get_version = vpu_windsor_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.pack_cmd = vpu_windsor_pack_cmd,
+		.convert_msg_id = vpu_windsor_convert_msg_id,
+		.unpack_msg_data = vpu_windsor_unpack_msg_data,
+		.config_memory_resource = vpu_windsor_config_memory_resource,
+		.get_stream_buffer_size = vpu_windsor_get_stream_buffer_size,
+		.config_stream_buffer = vpu_windsor_config_stream_buffer,
+		.get_stream_buffer_desc = vpu_windsor_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_windsor_update_stream_buffer,
+		.set_encode_params = vpu_windsor_set_encode_params,
+		.input_frame = vpu_windsor_input_frame,
+		.get_max_instance_count = vpu_windsor_get_max_instance_count,
+	},
+	[VPU_CORE_TYPE_DEC] = {
+		.check_codec = vpu_imx8q_check_codec,
+		.check_fmt = vpu_imx8q_check_fmt,
+		.boot_core = vpu_imx8q_boot_core,
+		.get_power_state = vpu_imx8q_get_power_state,
+		.on_firmware_loaded = vpu_imx8q_on_firmware_loaded,
+		.get_data_size = vpu_malone_get_data_size,
+		.check_memory_region = vpu_imx8q_check_memory_region,
+		.init_rpc = vpu_malone_init_rpc,
+		.set_log_buf = vpu_malone_set_log_buf,
+		.set_system_cfg = vpu_malone_set_system_cfg,
+		.get_version = vpu_malone_get_version,
+		.send_cmd_buf = vpu_rpc_send_cmd_buf,
+		.receive_msg_buf = vpu_rpc_receive_msg_buf,
+		.get_stream_buffer_size = vpu_malone_get_stream_buffer_size,
+		.config_stream_buffer = vpu_malone_config_stream_buffer,
+		.set_decode_params = vpu_malone_set_decode_params,
+		.pack_cmd = vpu_malone_pack_cmd,
+		.convert_msg_id = vpu_malone_convert_msg_id,
+		.unpack_msg_data = vpu_malone_unpack_msg_data,
+		.get_stream_buffer_desc = vpu_malone_get_stream_buffer_desc,
+		.update_stream_buffer = vpu_malone_update_stream_buffer,
+		.add_scode = vpu_malone_add_scode,
+		.input_frame = vpu_malone_input_frame,
+		.pre_send_cmd = vpu_malone_pre_cmd,
+		.post_send_cmd = vpu_malone_post_cmd,
+		.init_instance = vpu_malone_init_instance,
+		.get_max_instance_count = vpu_malone_get_max_instance_count,
+	},
+};
+
+static struct vpu_iface_ops *vpu_get_iface(struct vpu_dev *vpu, enum vpu_core_type type)
+{
+	struct vpu_iface_ops *rpc_ops = NULL;
+	u32 size = 0;
+
+	switch (vpu->res->plat_type) {
+	case IMX8QXP:
+	case IMX8QM:
+		rpc_ops = imx8q_rpc_ops;
+		size = ARRAY_SIZE(imx8q_rpc_ops);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (type >= size)
+		return NULL;
+
+	return &rpc_ops[type];
+}
+
+struct vpu_iface_ops *vpu_core_get_iface(struct vpu_core *core)
+{
+	return vpu_get_iface(core->vpu, core->type);
+}
+
+struct vpu_iface_ops *vpu_inst_get_iface(struct vpu_inst *inst)
+{
+	if (inst->core)
+		return vpu_core_get_iface(inst->core);
+
+	return vpu_get_iface(inst->vpu, inst->type);
+}
diff --git a/drivers/media/platform/amphion/vpu_rpc.h b/drivers/media/platform/amphion/vpu_rpc.h
new file mode 100644
index 000000000000..c764ff52d026
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_rpc.h
@@ -0,0 +1,456 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_RPC_H
+#define _AMPHION_VPU_RPC_H
+
+#include <media/videobuf2-core.h>
+#include "vpu_codec.h"
+
+struct vpu_rpc_buffer_desc {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+};
+
+struct vpu_shared_addr {
+	void *iface;
+	struct vpu_rpc_buffer_desc *cmd_desc;
+	void *cmd_mem_vir;
+	struct vpu_rpc_buffer_desc *msg_desc;
+	void *msg_mem_vir;
+
+	unsigned long boot_addr;
+	struct vpu_core *core;
+	void *priv;
+};
+
+struct vpu_rpc_event_header {
+	u32 index;
+	u32 id;
+	u32 num;
+};
+
+struct vpu_rpc_event {
+	struct vpu_rpc_event_header hdr;
+	u32 data[128];
+};
+
+struct vpu_iface_ops {
+	bool (*check_codec)(enum vpu_core_type type);
+	bool (*check_fmt)(enum vpu_core_type type, u32 pixelfmt);
+	u32 (*get_data_size)(void);
+	u32 (*check_memory_region)(dma_addr_t base, dma_addr_t addr, u32 size);
+	int (*boot_core)(struct vpu_core *core);
+	int (*shutdown_core)(struct vpu_core *core);
+	int (*restore_core)(struct vpu_core *core);
+	int (*get_power_state)(struct vpu_core *core);
+	int (*on_firmware_loaded)(struct vpu_core *core);
+	void (*init_rpc)(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr);
+	void (*set_log_buf)(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log);
+	void (*set_system_cfg)(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 index);
+	void (*set_stream_cfg)(struct vpu_shared_addr *shared, u32 index);
+	u32 (*get_version)(struct vpu_shared_addr *shared);
+	u32 (*get_max_instance_count)(struct vpu_shared_addr *shared);
+	int (*get_stream_buffer_size)(struct vpu_shared_addr *shared);
+	int (*send_cmd_buf)(struct vpu_shared_addr *shared,
+			    struct vpu_rpc_event *cmd);
+	int (*receive_msg_buf)(struct vpu_shared_addr *shared,
+			       struct vpu_rpc_event *msg);
+	int (*pack_cmd)(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+	int (*convert_msg_id)(u32 msg_id);
+	int (*unpack_msg_data)(struct vpu_rpc_event *pkt, void *data);
+	int (*input_frame)(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb);
+	int (*config_memory_resource)(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      u32 type,
+				      u32 index,
+				      struct vpu_buffer *buf);
+	int (*config_stream_buffer)(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_buffer *buf);
+	int (*update_stream_buffer)(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write);
+	int (*get_stream_buffer_desc)(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc);
+	int (*set_encode_params)(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_encode_params *params,
+				 u32 update);
+	int (*set_decode_params)(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params,
+				 u32 update);
+	int (*add_scode)(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type);
+	int (*pre_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*post_send_cmd)(struct vpu_shared_addr *shared, u32 instance);
+	int (*init_instance)(struct vpu_shared_addr *shared, u32 instance);
+};
+
+enum {
+	VPU_CORE_MEMORY_INVALID = 0,
+	VPU_CORE_MEMORY_CACHED,
+	VPU_CORE_MEMORY_UNCACHED
+};
+
+struct vpu_rpc_region_t {
+	dma_addr_t start;
+	dma_addr_t end;
+	dma_addr_t type;
+};
+
+struct vpu_iface_ops *vpu_core_get_iface(struct vpu_core *core);
+struct vpu_iface_ops *vpu_inst_get_iface(struct vpu_inst *inst);
+u32 vpu_iface_check_memory_region(struct vpu_core *core, dma_addr_t addr, u32 size);
+
+static inline bool vpu_iface_check_codec(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->check_codec)
+		return ops->check_codec(core->type);
+
+	return true;
+}
+
+static inline bool vpu_iface_check_format(struct vpu_inst *inst, u32 pixelfmt)
+{
+	struct vpu_iface_ops *ops = vpu_inst_get_iface(inst);
+
+	if (ops && ops->check_fmt)
+		return ops->check_fmt(inst->type, pixelfmt);
+
+	return true;
+}
+
+static inline int vpu_iface_boot_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->boot_core)
+		return ops->boot_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_get_power_state(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->get_power_state)
+		return ops->get_power_state(core);
+	return 1;
+}
+
+static inline int vpu_iface_shutdown_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->shutdown_core)
+		return ops->shutdown_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_restore_core(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->restore_core)
+		return ops->restore_core(core);
+	return 0;
+}
+
+static inline int vpu_iface_on_firmware_loaded(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (ops && ops->on_firmware_loaded)
+		return ops->on_firmware_loaded(core);
+
+	return 0;
+}
+
+static inline u32 vpu_iface_get_data_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_data_size)
+		return 0;
+
+	return ops->get_data_size();
+}
+
+static inline int vpu_iface_init(struct vpu_core *core,
+				 struct vpu_shared_addr *shared,
+				 struct vpu_buffer *rpc,
+				 dma_addr_t boot_addr)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->init_rpc)
+		return -EINVAL;
+
+	ops->init_rpc(shared, rpc, boot_addr);
+	core->iface = shared;
+	shared->core = core;
+	if (rpc->bytesused > rpc->length)
+		return -ENOSPC;
+	return 0;
+}
+
+static inline int vpu_iface_set_log_buf(struct vpu_core *core,
+					struct vpu_buffer *log)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops)
+		return -EINVAL;
+
+	if (ops->set_log_buf)
+		ops->set_log_buf(core->iface, log);
+
+	return 0;
+}
+
+static inline int vpu_iface_config_system(struct vpu_core *core, u32 regs_base, void __iomem *regs)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops)
+		return -EINVAL;
+	if (ops->set_system_cfg)
+		ops->set_system_cfg(core->iface, regs_base, regs, core->id);
+
+	return 0;
+}
+
+static inline int vpu_iface_get_stream_buffer_size(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_stream_buffer_size)
+		return 0;
+
+	return ops->get_stream_buffer_size(core->iface);
+}
+
+static inline int vpu_iface_config_stream(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || inst->id < 0)
+		return -EINVAL;
+	if (ops->set_stream_cfg)
+		ops->set_stream_cfg(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_send_cmd(struct vpu_core *core, struct vpu_rpc_event *cmd)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->send_cmd_buf)
+		return -EINVAL;
+
+	return ops->send_cmd_buf(core->iface, cmd);
+}
+
+static inline int vpu_iface_receive_msg(struct vpu_core *core, struct vpu_rpc_event *msg)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->receive_msg_buf)
+		return -EINVAL;
+
+	return ops->receive_msg_buf(core->iface, msg);
+}
+
+static inline int vpu_iface_pack_cmd(struct vpu_core *core,
+				     struct vpu_rpc_event *pkt,
+				     u32 index, u32 id, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->pack_cmd)
+		return -EINVAL;
+	return ops->pack_cmd(pkt, index, id, data);
+}
+
+static inline int vpu_iface_convert_msg_id(struct vpu_core *core, u32 msg_id)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->convert_msg_id)
+		return -EINVAL;
+
+	return ops->convert_msg_id(msg_id);
+}
+
+static inline int vpu_iface_unpack_msg_data(struct vpu_core *core,
+					    struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->unpack_msg_data)
+		return -EINVAL;
+
+	return ops->unpack_msg_data(pkt, data);
+}
+
+static inline int vpu_iface_input_frame(struct vpu_inst *inst,
+					struct vb2_buffer *vb)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->input_frame)
+		return -EINVAL;
+
+	return ops->input_frame(inst->core->iface, inst, vb);
+}
+
+static inline int vpu_iface_config_memory_resource(struct vpu_inst *inst,
+						   u32 type,
+						   u32 index,
+						   struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->config_memory_resource || inst->id < 0)
+		return -EINVAL;
+
+	return ops->config_memory_resource(inst->core->iface,
+					inst->id,
+					type, index, buf);
+}
+
+static inline int vpu_iface_config_stream_buffer(struct vpu_inst *inst,
+						 struct vpu_buffer *buf)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->config_stream_buffer || inst->id < 0)
+		return -EINVAL;
+
+	return ops->config_stream_buffer(inst->core->iface, inst->id, buf);
+}
+
+static inline int vpu_iface_update_stream_buffer(struct vpu_inst *inst,
+						 u32 ptr, bool write)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->update_stream_buffer || inst->id < 0)
+		return -EINVAL;
+
+	return ops->update_stream_buffer(inst->core->iface, inst->id, ptr, write);
+}
+
+static inline int vpu_iface_get_stream_buffer_desc(struct vpu_inst *inst,
+						   struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->get_stream_buffer_desc || inst->id < 0)
+		return -EINVAL;
+
+	if (!desc)
+		return 0;
+
+	return ops->get_stream_buffer_desc(inst->core->iface, inst->id, desc);
+}
+
+static inline u32 vpu_iface_get_version(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_version)
+		return 0;
+
+	return ops->get_version(core->iface);
+}
+
+static inline u32 vpu_iface_get_max_instance_count(struct vpu_core *core)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(core);
+
+	if (!ops || !ops->get_max_instance_count)
+		return 0;
+
+	return ops->get_max_instance_count(core->iface);
+}
+
+static inline int vpu_iface_set_encode_params(struct vpu_inst *inst,
+					      struct vpu_encode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->set_encode_params || inst->id < 0)
+		return -EINVAL;
+
+	return ops->set_encode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_set_decode_params(struct vpu_inst *inst,
+					      struct vpu_decode_params *params, u32 update)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->set_decode_params  || inst->id < 0)
+		return -EINVAL;
+
+	return ops->set_decode_params(inst->core->iface, inst->id, params, update);
+}
+
+static inline int vpu_iface_add_scode(struct vpu_inst *inst, u32 scode_type)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (!ops || !ops->add_scode  || inst->id < 0)
+		return -EINVAL;
+
+	return ops->add_scode(inst->core->iface, inst->id,
+				&inst->stream_buffer,
+				inst->out_format.pixfmt,
+				scode_type);
+}
+
+static inline int vpu_iface_pre_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->pre_send_cmd && inst->id >= 0)
+		return ops->pre_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_post_send_cmd(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->post_send_cmd && inst->id >= 0)
+		return ops->post_send_cmd(inst->core->iface, inst->id);
+	return 0;
+}
+
+static inline int vpu_iface_init_instance(struct vpu_inst *inst)
+{
+	struct vpu_iface_ops *ops = vpu_core_get_iface(inst->core);
+
+	if (ops && ops->init_instance && inst->id >= 0)
+		return ops->init_instance(inst->core->iface, inst->id);
+
+	return 0;
+}
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:24 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:24 +0800
Subject: [PATCH v15.1 05/13] media: amphion: implement vpu core communication
 based on mailbox
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <5873ee47a84cdf5f0377ce9f7a65a90a8bcc34c7.1643165765.git.ming.qian@nxp.com>

driver use mailbox to communicate with vpu core.
and there are a command buffer and a message buffer.
driver will write commands to the command buffer,
then trigger a vpu core interrupt
vpu core will write messages to the message buffer,
then trigger a cpu interrupt.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_cmds.c | 436 ++++++++++++++++++++++
 drivers/media/platform/amphion/vpu_cmds.h |  25 ++
 drivers/media/platform/amphion/vpu_mbox.c | 118 ++++++
 drivers/media/platform/amphion/vpu_mbox.h |  16 +
 drivers/media/platform/amphion/vpu_msgs.c | 385 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_msgs.h |  14 +
 6 files changed, 994 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.c
 create mode 100644 drivers/media/platform/amphion/vpu_cmds.h
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.c
 create mode 100644 drivers/media/platform/amphion/vpu_mbox.h
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.c
 create mode 100644 drivers/media/platform/amphion/vpu_msgs.h

diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c
new file mode 100644
index 000000000000..51e404ebda8f
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_cmds.c
@@ -0,0 +1,436 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+
+struct vpu_cmd_request {
+	u32 request;
+	u32 response;
+	u32 handled;
+};
+
+struct vpu_cmd_t {
+	struct list_head list;
+	u32 id;
+	struct vpu_cmd_request *request;
+	struct vpu_rpc_event *pkt;
+	unsigned long key;
+};
+
+static struct vpu_cmd_request vpu_cmd_requests[] = {
+	{
+		.request = VPU_CMD_ID_CONFIGURE_CODEC,
+		.response = VPU_MSG_ID_MEM_REQUEST,
+		.handled = 1,
+	},
+	{
+		.request = VPU_CMD_ID_START,
+		.response = VPU_MSG_ID_START_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_STOP,
+		.response = VPU_MSG_ID_STOP_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_ABORT,
+		.response = VPU_MSG_ID_ABORT_DONE,
+		.handled = 0,
+	},
+	{
+		.request = VPU_CMD_ID_RST_BUF,
+		.response = VPU_MSG_ID_BUF_RST,
+		.handled = 1,
+	},
+};
+
+static int vpu_cmd_send(struct vpu_core *core, struct vpu_rpc_event *pkt)
+{
+	int ret = 0;
+
+	ret = vpu_iface_send_cmd(core, pkt);
+	if (ret)
+		return ret;
+
+	/*write cmd data to cmd buffer before trigger a cmd interrupt*/
+	mb();
+	vpu_mbox_send_type(core, COMMAND);
+
+	return ret;
+}
+
+static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	struct vpu_cmd_t *cmd;
+	int i;
+	int ret;
+
+	cmd = vzalloc(sizeof(*cmd));
+	if (!cmd)
+		return NULL;
+
+	cmd->pkt = vzalloc(sizeof(*cmd->pkt));
+	if (!cmd->pkt) {
+		vfree(cmd);
+		return NULL;
+	}
+
+	cmd->id = id;
+	ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data);
+	if (ret) {
+		dev_err(inst->dev, "iface pack cmd(%d) fail\n", id);
+		vfree(cmd->pkt);
+		vfree(cmd);
+		return NULL;
+	}
+	for (i = 0; i < ARRAY_SIZE(vpu_cmd_requests); i++) {
+		if (vpu_cmd_requests[i].request == id) {
+			cmd->request = &vpu_cmd_requests[i];
+			break;
+		}
+	}
+
+	return cmd;
+}
+
+static void vpu_free_cmd(struct vpu_cmd_t *cmd)
+{
+	if (!cmd)
+		return;
+	if (cmd->pkt)
+		vfree(cmd->pkt);
+	vfree(cmd);
+}
+
+static int vpu_session_process_cmd(struct vpu_inst *inst, struct vpu_cmd_t *cmd)
+{
+	int ret;
+
+	if (!inst || !cmd || !cmd->pkt)
+		return -EINVAL;
+
+	dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id);
+	vpu_iface_pre_send_cmd(inst);
+	ret = vpu_cmd_send(inst->core, cmd->pkt);
+	if (!ret) {
+		vpu_iface_post_send_cmd(inst);
+		vpu_inst_record_flow(inst, cmd->id);
+	} else {
+		dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id);
+	}
+
+	return ret;
+}
+
+static void vpu_process_cmd_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	if (!inst || inst->pending)
+		return;
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		if (vpu_session_process_cmd(inst, cmd))
+			dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id);
+		if (cmd->request) {
+			inst->pending = (void *)cmd;
+			break;
+		}
+		vpu_free_cmd(cmd);
+	}
+}
+
+static int vpu_request_cmd(struct vpu_inst *inst, u32 id, void *data,
+			   unsigned long *key, int *sync)
+{
+	struct vpu_core *core;
+	struct vpu_cmd_t *cmd;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	cmd = vpu_alloc_cmd(inst, id, data);
+	if (!cmd)
+		return -ENOMEM;
+
+	mutex_lock(&core->cmd_lock);
+	cmd->key = core->cmd_seq++;
+	if (key)
+		*key = cmd->key;
+	if (sync)
+		*sync = cmd->request ? true : false;
+	list_add_tail(&cmd->list, &inst->cmd_q);
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+static void vpu_clear_pending(struct vpu_inst *inst)
+{
+	if (!inst || !inst->pending)
+		return;
+
+	vpu_free_cmd(inst->pending);
+	wake_up_all(&inst->core->ack_wq);
+	inst->pending = NULL;
+}
+
+static bool vpu_check_response(struct vpu_cmd_t *cmd, u32 response, u32 handled)
+{
+	struct vpu_cmd_request *request;
+
+	if (!cmd || !cmd->request)
+		return false;
+
+	request = cmd->request;
+	if (request->response != response)
+		return false;
+	if (request->handled != handled)
+		return false;
+
+	return true;
+}
+
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->cmd_lock);
+	if (vpu_check_response(inst->pending, response, handled))
+		vpu_clear_pending(inst);
+
+	vpu_process_cmd_request(inst);
+	mutex_unlock(&core->cmd_lock);
+
+	return 0;
+}
+
+void vpu_clear_request(struct vpu_inst *inst)
+{
+	struct vpu_cmd_t *cmd;
+	struct vpu_cmd_t *tmp;
+
+	mutex_lock(&inst->core->cmd_lock);
+	if (inst->pending)
+		vpu_clear_pending(inst);
+
+	list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) {
+		list_del_init(&cmd->list);
+		vpu_free_cmd(cmd);
+	}
+	mutex_unlock(&inst->core->cmd_lock);
+}
+
+static bool check_is_responsed(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core = inst->core;
+	struct vpu_cmd_t *cmd;
+	bool flag = true;
+
+	mutex_lock(&core->cmd_lock);
+	cmd = inst->pending;
+	if (cmd && key == cmd->key) {
+		flag = false;
+		goto exit;
+	}
+	list_for_each_entry(cmd, &inst->cmd_q, list) {
+		if (key == cmd->key) {
+			flag = false;
+			break;
+		}
+	}
+exit:
+	mutex_unlock(&core->cmd_lock);
+
+	return flag;
+}
+
+static int sync_session_response(struct vpu_inst *inst, unsigned long key)
+{
+	struct vpu_core *core;
+
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	call_vop(inst, wait_prepare);
+	wait_event_timeout(core->ack_wq, check_is_responsed(inst, key), VPU_TIMEOUT);
+	call_vop(inst, wait_finish);
+
+	if (!check_is_responsed(inst, key)) {
+		dev_err(inst->dev, "[%d] sync session timeout\n", inst->id);
+		set_bit(inst->id, &core->hang_mask);
+		mutex_lock(&inst->core->cmd_lock);
+		vpu_clear_pending(inst);
+		mutex_unlock(&inst->core->cmd_lock);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_session_send_cmd(struct vpu_inst *inst, u32 id, void *data)
+{
+	unsigned long key;
+	int sync = false;
+	int ret = -EINVAL;
+
+	if (inst->id < 0)
+		return -EINVAL;
+
+	ret = vpu_request_cmd(inst, id, data, &key, &sync);
+	if (!ret && sync)
+		ret = sync_session_response(inst, key);
+
+	if (ret)
+		dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id);
+
+	return ret;
+}
+
+int vpu_session_configure_codec(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_CONFIGURE_CODEC, NULL);
+}
+
+int vpu_session_start(struct vpu_inst *inst)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_START, NULL);
+}
+
+int vpu_session_stop(struct vpu_inst *inst)
+{
+	int ret;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_STOP, NULL);
+	/* workaround for a firmware bug,
+	 * if the next command is too close after stop cmd,
+	 * the firmware may enter wfi wrongly.
+	 */
+	usleep_range(3000, 5000);
+	return ret;
+}
+
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FRAME_ENCODE, &timestamp);
+}
+
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_ALLOC, fs);
+}
+
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_FS_RELEASE, fs);
+}
+
+int vpu_session_abort(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_ABORT, NULL);
+}
+
+int vpu_session_rst_buf(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_RST_BUF, NULL);
+}
+
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_TIMESTAMP, info);
+}
+
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg)
+{
+	if (inst->type & VPU_CORE_TYPE_DEC)
+		vpu_iface_set_decode_params(inst, arg, 1);
+	else
+		vpu_iface_set_encode_params(inst, arg, 1);
+
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_UPDATE_PARAMETER, arg);
+}
+
+int vpu_session_debug(struct vpu_inst *inst)
+{
+	return vpu_session_send_cmd(inst, VPU_CMD_ID_DEBUG, NULL);
+}
+
+int vpu_core_snapshot(struct vpu_core *core)
+{
+	struct vpu_inst *inst;
+	int ret;
+
+	if (!core || list_empty(&core->instances))
+		return 0;
+
+	inst = list_first_entry(&core->instances, struct vpu_inst, list);
+
+	reinit_completion(&core->cmp);
+	ret = vpu_session_send_cmd(inst, VPU_CMD_ID_SNAPSHOT, NULL);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "snapshot timeout\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_core_sw_reset(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	vpu_iface_pack_cmd(core, &pkt, 0, VPU_CMD_ID_FIRM_RESET, NULL);
+
+	reinit_completion(&core->cmp);
+	mutex_lock(&core->cmd_lock);
+	ret = vpu_cmd_send(core, &pkt);
+	mutex_unlock(&core->cmd_lock);
+	if (ret)
+		return ret;
+	ret = wait_for_completion_timeout(&core->cmp, VPU_TIMEOUT);
+	if (!ret) {
+		dev_err(core->dev, "sw reset timeout\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_cmds.h b/drivers/media/platform/amphion/vpu_cmds.h
new file mode 100644
index 000000000000..bc538d277bc9
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_cmds.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_CMDS_H
+#define _AMPHION_VPU_CMDS_H
+
+int vpu_session_configure_codec(struct vpu_inst *inst);
+int vpu_session_start(struct vpu_inst *inst);
+int vpu_session_stop(struct vpu_inst *inst);
+int vpu_session_abort(struct vpu_inst *inst);
+int vpu_session_rst_buf(struct vpu_inst *inst);
+int vpu_session_encode_frame(struct vpu_inst *inst, s64 timestamp);
+int vpu_session_alloc_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_release_fs(struct vpu_inst *inst, struct vpu_fs_info *fs);
+int vpu_session_fill_timestamp(struct vpu_inst *inst, struct vpu_ts_info *info);
+int vpu_session_update_parameters(struct vpu_inst *inst, void *arg);
+int vpu_core_snapshot(struct vpu_core *core);
+int vpu_core_sw_reset(struct vpu_core *core);
+int vpu_response_cmd(struct vpu_inst *inst, u32 response, u32 handled);
+void vpu_clear_request(struct vpu_inst *inst);
+int vpu_session_debug(struct vpu_inst *inst);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c
new file mode 100644
index 000000000000..bf759eb2fd46
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_mbox.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_mbox.h"
+#include "vpu_msgs.h"
+
+static void vpu_mbox_rx_callback(struct mbox_client *cl, void *msg)
+{
+	struct vpu_mbox *rx = container_of(cl, struct vpu_mbox, cl);
+	struct vpu_core *core = container_of(rx, struct vpu_core, rx);
+
+	vpu_isr(core, *(u32 *)msg);
+}
+
+static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox)
+{
+	struct mbox_chan *ch;
+	struct mbox_client *cl;
+
+	if (!dev || !mbox)
+		return -EINVAL;
+	if (mbox->ch)
+		return 0;
+
+	cl = &mbox->cl;
+	cl->dev = dev;
+	if (mbox->block) {
+		cl->tx_block = true;
+		cl->tx_tout = 1000;
+	} else {
+		cl->tx_block = false;
+	}
+	cl->knows_txdone = false;
+	cl->rx_callback = vpu_mbox_rx_callback;
+
+	ch = mbox_request_channel_byname(cl, mbox->name);
+	if (IS_ERR(ch)) {
+		dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n",
+			mbox->name, PTR_ERR(ch));
+		return PTR_ERR(ch);
+	}
+
+	mbox->ch = ch;
+	return 0;
+}
+
+int vpu_mbox_init(struct vpu_core *core)
+{
+	scnprintf(core->tx_type.name, sizeof(core->tx_type.name) - 1, "tx0");
+	core->tx_type.block = true;
+
+	scnprintf(core->tx_data.name, sizeof(core->tx_data.name) - 1, "tx1");
+	core->tx_data.block = false;
+
+	scnprintf(core->rx.name, sizeof(core->rx.name) - 1, "rx");
+	core->rx.block = true;
+
+	return 0;
+}
+
+int vpu_mbox_request(struct vpu_core *core)
+{
+	int ret;
+
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_type);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->tx_data);
+	if (ret)
+		goto error;
+	ret = vpu_mbox_request_channel(core->dev, &core->rx);
+	if (ret)
+		goto error;
+
+	dev_dbg(core->dev, "%s request mbox\n", vpu_core_type_desc(core->type));
+	return 0;
+error:
+	vpu_mbox_free(core);
+	return ret;
+}
+
+void vpu_mbox_free(struct vpu_core *core)
+{
+	mbox_free_channel(core->tx_type.ch);
+	mbox_free_channel(core->tx_data.ch);
+	mbox_free_channel(core->rx.ch);
+	core->tx_type.ch = NULL;
+	core->tx_data.ch = NULL;
+	core->rx.ch = NULL;
+	dev_dbg(core->dev, "%s free mbox\n", vpu_core_type_desc(core->type));
+}
+
+void vpu_mbox_send_type(struct vpu_core *core, u32 type)
+{
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data)
+{
+	mbox_send_message(core->tx_data.ch, &data);
+	mbox_send_message(core->tx_type.ch, &type);
+}
+
+void vpu_mbox_enable_rx(struct vpu_dev *dev)
+{
+}
diff --git a/drivers/media/platform/amphion/vpu_mbox.h b/drivers/media/platform/amphion/vpu_mbox.h
new file mode 100644
index 000000000000..79cfd874e92b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_mbox.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MBOX_H
+#define _AMPHION_VPU_MBOX_H
+
+int vpu_mbox_init(struct vpu_core *core);
+int vpu_mbox_request(struct vpu_core *core);
+void vpu_mbox_free(struct vpu_core *core);
+void vpu_mbox_send_msg(struct vpu_core *core, u32 type, u32 data);
+void vpu_mbox_send_type(struct vpu_core *core, u32 type);
+void vpu_mbox_enable_rx(struct vpu_dev *dev);
+
+#endif
diff --git a/drivers/media/platform/amphion/vpu_msgs.c b/drivers/media/platform/amphion/vpu_msgs.c
new file mode 100644
index 000000000000..a406ab08e490
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_msgs.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_mbox.h"
+#include "vpu_defs.h"
+#include "vpu_cmds.h"
+#include "vpu_msgs.h"
+#include "vpu_v4l2.h"
+
+#define VPU_PKT_HEADER_LENGTH		3
+
+struct vpu_msg_handler {
+	u32 id;
+	void (*done)(struct vpu_inst *inst, struct vpu_rpc_event *pkt);
+};
+
+static void vpu_session_handle_start_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+}
+
+static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_pkt_mem_req_data req_data;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data);
+	vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n",
+		  inst->id,
+		  req_data.enc_frame_size,
+		  req_data.enc_frame_num,
+		  req_data.ref_frame_size,
+		  req_data.ref_frame_num,
+		  req_data.act_buf_size,
+		  req_data.act_buf_num);
+	call_vop(inst, mem_request,
+		 req_data.enc_frame_size,
+		 req_data.enc_frame_num,
+		 req_data.ref_frame_size,
+		 req_data.ref_frame_num,
+		 req_data.act_buf_size,
+		 req_data.act_buf_num);
+}
+
+static void vpu_session_handle_stop_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	call_vop(inst, stop_done);
+}
+
+static void vpu_session_handle_seq_hdr(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_codec_info info;
+	const struct vpu_core_resources *res;
+
+	memset(&info, 0, sizeof(info));
+	res = vpu_get_resource(inst);
+	info.stride = res ? res->stride : 1;
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, event_notify, VPU_MSG_ID_SEQ_HDR_FOUND, &info);
+}
+
+static void vpu_session_handle_resolution_change(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_RES_CHANGE, NULL);
+}
+
+static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_enc_pic_info info;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n",
+		inst->id, info.frame_id, info.wptr, info.frame_size);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_fs_info fs;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+	call_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs);
+}
+
+static void vpu_session_handle_frame_release(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	if (inst->core->type == VPU_CORE_TYPE_ENC) {
+		struct vpu_frame_info info;
+
+		memset(&info, 0, sizeof(info));
+		vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info.sequence);
+		dev_dbg(inst->dev, "[%d] %d\n", inst->id, info.sequence);
+		info.type = inst->out_format.type;
+		call_vop(inst, buf_done, &info);
+	} else if (inst->core->type == VPU_CORE_TYPE_DEC) {
+		struct vpu_fs_info fs;
+
+		vpu_iface_unpack_msg_data(inst->core, pkt, &fs);
+		call_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs);
+	}
+}
+
+static void vpu_session_handle_input_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	dev_dbg(inst->dev, "[%d]\n", inst->id);
+	call_vop(inst, input_done);
+}
+
+static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	call_vop(inst, get_one_frame, &info);
+}
+
+static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	struct vpu_dec_pic_info info;
+	struct vpu_frame_info frame;
+
+	memset(&frame, 0, sizeof(frame));
+	vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info);
+	if (inst->core->type == VPU_CORE_TYPE_DEC)
+		frame.type = inst->cap_format.type;
+	frame.id = info.id;
+	frame.luma = info.luma;
+	frame.skipped = info.skipped;
+	frame.timestamp = info.timestamp;
+
+	call_vop(inst, buf_done, &frame);
+}
+
+static void vpu_session_handle_eos(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	call_vop(inst, event_notify, VPU_MSG_ID_PIC_EOS, NULL);
+}
+
+static void vpu_session_handle_error(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	dev_err(inst->dev, "unsupported stream\n");
+	call_vop(inst, event_notify, VPU_MSG_ID_UNSUPPORTED, NULL);
+	vpu_v4l2_set_error(inst);
+}
+
+static void vpu_session_handle_firmware_xcpt(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	char *str = (char *)pkt->data;
+
+	dev_err(inst->dev, "%s firmware xcpt: %s\n",
+		vpu_core_type_desc(inst->core->type), str);
+	call_vop(inst, event_notify, VPU_MSG_ID_FIRMWARE_XCPT, NULL);
+	set_bit(inst->id, &inst->core->hang_mask);
+	vpu_v4l2_set_error(inst);
+}
+
+struct vpu_msg_handler handlers[] = {
+	{VPU_MSG_ID_START_DONE, vpu_session_handle_start_done},
+	{VPU_MSG_ID_STOP_DONE, vpu_session_handle_stop_done},
+	{VPU_MSG_ID_MEM_REQUEST, vpu_session_handle_mem_request},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, vpu_session_handle_seq_hdr},
+	{VPU_MSG_ID_RES_CHANGE, vpu_session_handle_resolution_change},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, vpu_session_handle_input_done},
+	{VPU_MSG_ID_FRAME_REQ, vpu_session_handle_frame_request},
+	{VPU_MSG_ID_FRAME_RELEASE, vpu_session_handle_frame_release},
+	{VPU_MSG_ID_ENC_DONE, vpu_session_handle_enc_frame_done},
+	{VPU_MSG_ID_PIC_DECODED, vpu_session_handle_pic_decoded},
+	{VPU_MSG_ID_DEC_DONE, vpu_session_handle_pic_done},
+	{VPU_MSG_ID_PIC_EOS, vpu_session_handle_eos},
+	{VPU_MSG_ID_UNSUPPORTED, vpu_session_handle_error},
+	{VPU_MSG_ID_FIRMWARE_XCPT, vpu_session_handle_firmware_xcpt},
+};
+
+static int vpu_session_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *msg)
+{
+	int ret;
+	u32 msg_id;
+	struct vpu_msg_handler *handler = NULL;
+	unsigned int i;
+
+	ret = vpu_iface_convert_msg_id(inst->core, msg->hdr.id);
+	if (ret < 0)
+		return -EINVAL;
+
+	msg_id = ret;
+	dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id);
+
+	for (i = 0; i < ARRAY_SIZE(handlers); i++) {
+		if (handlers[i].id == msg_id) {
+			handler = &handlers[i];
+			break;
+		}
+	}
+
+	if (handler && handler->done)
+		handler->done(inst, msg);
+
+	vpu_response_cmd(inst, msg_id, 1);
+
+	return 0;
+}
+
+static bool vpu_inst_receive_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes = sizeof(struct vpu_rpc_event_header);
+	u32 ret;
+
+	memset(pkt, 0, sizeof(*pkt));
+	if (kfifo_len(&inst->msg_fifo) < bytes)
+		return false;
+
+	ret = kfifo_out(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		return false;
+
+	if (pkt->hdr.num > 0) {
+		bytes = pkt->hdr.num * sizeof(u32);
+		ret = kfifo_out(&inst->msg_fifo, pkt->data, bytes);
+		if (ret != bytes)
+			return false;
+	}
+
+	return true;
+}
+
+void vpu_inst_run_work(struct work_struct *work)
+{
+	struct vpu_inst *inst = container_of(work, struct vpu_inst, msg_work);
+	struct vpu_rpc_event pkt;
+
+	while (vpu_inst_receive_msg(inst, &pkt))
+		vpu_session_handle_msg(inst, &pkt);
+}
+
+static void vpu_inst_handle_msg(struct vpu_inst *inst, struct vpu_rpc_event *pkt)
+{
+	u32 bytes;
+	u32 id = pkt->hdr.id;
+	int ret;
+
+	if (!inst->workqueue)
+		return;
+
+	bytes = sizeof(pkt->hdr) + pkt->hdr.num * sizeof(u32);
+	ret = kfifo_in(&inst->msg_fifo, pkt, bytes);
+	if (ret != bytes)
+		dev_err(inst->dev, "[%d:%d]overflow: %d\n", inst->core->id, inst->id, id);
+	queue_work(inst->workqueue, &inst->msg_work);
+}
+
+static int vpu_handle_msg(struct vpu_core *core)
+{
+	struct vpu_rpc_event pkt;
+	struct vpu_inst *inst;
+	int ret;
+
+	memset(&pkt, 0, sizeof(pkt));
+	while (!vpu_iface_receive_msg(core, &pkt)) {
+		dev_dbg(core->dev, "event index = %d, id = %d, num = %d\n",
+			pkt.hdr.index, pkt.hdr.id, pkt.hdr.num);
+
+		ret = vpu_iface_convert_msg_id(core, pkt.hdr.id);
+		if (ret < 0)
+			continue;
+
+		inst = vpu_core_find_instance(core, pkt.hdr.index);
+		if (inst) {
+			vpu_response_cmd(inst, ret, 0);
+			mutex_lock(&core->cmd_lock);
+			vpu_inst_record_flow(inst, ret);
+			mutex_unlock(&core->cmd_lock);
+
+			vpu_inst_handle_msg(inst, &pkt);
+			vpu_inst_put(inst);
+		}
+		memset(&pkt, 0, sizeof(pkt));
+	}
+
+	return 0;
+}
+
+static int vpu_isr_thread(struct vpu_core *core, u32 irq_code)
+{
+	dev_dbg(core->dev, "irq code = 0x%x\n", irq_code);
+	switch (irq_code) {
+	case VPU_IRQ_CODE_SYNC:
+		vpu_mbox_send_msg(core, PRC_BUF_OFFSET, core->rpc.phys - core->fw.phys);
+		vpu_mbox_send_msg(core, BOOT_ADDRESS, core->fw.phys);
+		vpu_mbox_send_msg(core, INIT_DONE, 2);
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		break;
+	default:
+		vpu_handle_msg(core);
+		break;
+	}
+
+	return 0;
+}
+
+static void vpu_core_run_msg_work(struct vpu_core *core)
+{
+	const unsigned int SIZE = sizeof(u32);
+
+	while (kfifo_len(&core->msg_fifo) >= SIZE) {
+		u32 data;
+
+		if (kfifo_out(&core->msg_fifo, &data, SIZE) == SIZE)
+			vpu_isr_thread(core, data);
+	}
+}
+
+void vpu_msg_run_work(struct work_struct *work)
+{
+	struct vpu_core *core = container_of(work, struct vpu_core, msg_work);
+	unsigned long delay = msecs_to_jiffies(10);
+
+	vpu_core_run_msg_work(core);
+	queue_delayed_work(core->workqueue, &core->msg_delayed_work, delay);
+}
+
+void vpu_msg_delayed_work(struct work_struct *work)
+{
+	struct vpu_core *core;
+	struct delayed_work *dwork;
+	u32 bytes = sizeof(bytes);
+	u32 i;
+
+	if (!work)
+		return;
+
+	dwork = to_delayed_work(work);
+	core = container_of(dwork, struct vpu_core, msg_delayed_work);
+	if (kfifo_len(&core->msg_fifo) >= bytes)
+		vpu_core_run_msg_work(core);
+
+	bytes = sizeof(struct vpu_rpc_event_header);
+	for (i = 0; i < core->supported_instance_count; i++) {
+		struct vpu_inst *inst = vpu_core_find_instance(core, i);
+
+		if (!inst)
+			continue;
+
+		if (inst->workqueue && kfifo_len(&inst->msg_fifo) >= bytes)
+			queue_work(inst->workqueue, &inst->msg_work);
+
+		vpu_inst_put(inst);
+	}
+}
+
+int vpu_isr(struct vpu_core *core, u32 irq)
+{
+	switch (irq) {
+	case VPU_IRQ_CODE_SYNC:
+		break;
+	case VPU_IRQ_CODE_BOOT_DONE:
+		complete(&core->cmp);
+		break;
+	case VPU_IRQ_CODE_SNAPSHOT_DONE:
+		complete(&core->cmp);
+		break;
+	default:
+		break;
+	}
+
+	if (kfifo_in(&core->msg_fifo, &irq, sizeof(irq)) != sizeof(irq))
+		dev_err(core->dev, "[%d]overflow: %d\n", core->id, irq);
+	queue_work(core->workqueue, &core->msg_work);
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_msgs.h b/drivers/media/platform/amphion/vpu_msgs.h
new file mode 100644
index 000000000000..c466b4f62aad
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_msgs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MSGS_H
+#define _AMPHION_VPU_MSGS_H
+
+int vpu_isr(struct vpu_core *core, u32 irq);
+void vpu_inst_run_work(struct work_struct *work);
+void vpu_msg_run_work(struct work_struct *work);
+void vpu_msg_delayed_work(struct work_struct *work);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:25 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:25 +0800
Subject: [PATCH v15.1 06/13] media: amphion: add vpu v4l2 m2m support
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <1b3df5788edc51cbedf0627965b10b3f7ad1a60a.1643165765.git.ming.qian@nxp.com>

vpu_v4l2.c implements the v4l2 m2m driver methods.
vpu_helpers.c implements the common helper functions
vpu_color.c converts the v4l2 colorspace with
the VUI parameters that specified by ITU-T | ISO/IEC

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_color.c   | 183 +++++
 drivers/media/platform/amphion/vpu_helpers.c | 413 +++++++++++
 drivers/media/platform/amphion/vpu_helpers.h |  74 ++
 drivers/media/platform/amphion/vpu_v4l2.c    | 720 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_v4l2.h    |  55 ++
 5 files changed, 1445 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_color.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.c
 create mode 100644 drivers/media/platform/amphion/vpu_helpers.h
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.c
 create mode 100644 drivers/media/platform/amphion/vpu_v4l2.h

diff --git a/drivers/media/platform/amphion/vpu_color.c b/drivers/media/platform/amphion/vpu_color.c
new file mode 100644
index 000000000000..80b9a53fd1c1
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_color.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+#include "vpu.h"
+#include "vpu_helpers.h"
+
+static const u8 colorprimaries[] = {
+	0,
+	V4L2_COLORSPACE_REC709,         /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	V4L2_COLORSPACE_470_SYSTEM_M,   /*Rec. ITU-R BT.470-6 System M*/
+	V4L2_COLORSPACE_470_SYSTEM_BG,  /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_COLORSPACE_SMPTE170M,      /*SMPTE170M*/
+	V4L2_COLORSPACE_SMPTE240M,      /*SMPTE240M*/
+	0,                              /*Generic film*/
+	V4L2_COLORSPACE_BT2020,         /*Rec. ITU-R BT.2020-2*/
+	0,                              /*SMPTE ST 428-1*/
+};
+
+static const u8 colortransfers[] = {
+	0,
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                              /*Rec. ITU-R BT.470-6 System M*/
+	0,                              /*Rec. ITU-R BT.470-6 System B, G*/
+	V4L2_XFER_FUNC_709,             /*SMPTE170M*/
+	V4L2_XFER_FUNC_SMPTE240M,       /*SMPTE240M*/
+	V4L2_XFER_FUNC_NONE,            /*Linear transfer characteristics*/
+	0,
+	0,
+	0,                              /*IEC 61966-2-4*/
+	0,                              /*Rec. ITU-R BT.1361-0 extended colour gamut*/
+	V4L2_XFER_FUNC_SRGB,            /*IEC 61966-2-1 sRGB or sYCC*/
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (10 bit system)*/
+	V4L2_XFER_FUNC_709,             /*Rec. ITU-R BT.2020-2 (12 bit system)*/
+	V4L2_XFER_FUNC_SMPTE2084,       /*SMPTE ST 2084*/
+	0,                              /*SMPTE ST 428-1*/
+	0                               /*Rec. ITU-R BT.2100-0 hybrid log-gamma (HLG)*/
+};
+
+static const u8 colormatrixcoefs[] = {
+	0,
+	V4L2_YCBCR_ENC_709,              /*Rec. ITU-R BT.709-6*/
+	0,
+	0,
+	0,                               /*Title 47 Code of Federal Regulations*/
+	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 625*/
+	V4L2_YCBCR_ENC_601,              /*Rec. ITU-R BT.601-7 525*/
+	V4L2_YCBCR_ENC_SMPTE240M,        /*SMPTE240M*/
+	0,
+	V4L2_YCBCR_ENC_BT2020,           /*Rec. ITU-R BT.2020-2*/
+	V4L2_YCBCR_ENC_BT2020_CONST_LUM  /*Rec. ITU-R BT.2020-2 constant*/
+};
+
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries)
+{
+	return vpu_helper_find_in_array_u8(colorprimaries, ARRAY_SIZE(colorprimaries), primaries);
+}
+
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries)
+{
+	return primaries < ARRAY_SIZE(colorprimaries) ? colorprimaries[primaries] : 0;
+}
+
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers)
+{
+	return vpu_helper_find_in_array_u8(colortransfers, ARRAY_SIZE(colortransfers), transfers);
+}
+
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers)
+{
+	return transfers < ARRAY_SIZE(colortransfers) ? colortransfers[transfers] : 0;
+}
+
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix)
+{
+	return vpu_helper_find_in_array_u8(colormatrixcoefs, ARRAY_SIZE(colormatrixcoefs), matrix);
+}
+
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix)
+{
+	return matrix < ARRAY_SIZE(colormatrixcoefs) ? colormatrixcoefs[matrix] : 0;
+}
+
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range)
+{
+	return (full_range == V4L2_QUANTIZATION_FULL_RANGE);
+}
+
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range)
+{
+	if (full_range)
+		return V4L2_QUANTIZATION_FULL_RANGE;
+
+	return V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+int vpu_color_check_primaries(u32 primaries)
+{
+	return vpu_color_cvrt_primaries_v2i(primaries) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_transfers(u32 transfers)
+{
+	return vpu_color_cvrt_transfers_v2i(transfers) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_matrix(u32 matrix)
+{
+	return vpu_color_cvrt_matrix_v2i(matrix) ? 0 : -EINVAL;
+}
+
+int vpu_color_check_full_range(u32 full_range)
+{
+	int ret = -EINVAL;
+
+	switch (full_range) {
+	case V4L2_QUANTIZATION_FULL_RANGE:
+	case V4L2_QUANTIZATION_LIM_RANGE:
+		ret = 0;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range)
+{
+	u32 transfers;
+	u32 matrix;
+	u32 full_range;
+
+	switch (primaries) {
+	case V4L2_COLORSPACE_REC709:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_709;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+	case V4L2_COLORSPACE_SMPTE170M:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_601;
+		break;
+	case V4L2_COLORSPACE_SMPTE240M:
+		transfers = V4L2_XFER_FUNC_SMPTE240M;
+		matrix = V4L2_YCBCR_ENC_SMPTE240M;
+		break;
+	case V4L2_COLORSPACE_BT2020:
+		transfers = V4L2_XFER_FUNC_709;
+		matrix = V4L2_YCBCR_ENC_BT2020;
+		break;
+	default:
+		transfers = V4L2_XFER_FUNC_DEFAULT;
+		matrix = V4L2_YCBCR_ENC_DEFAULT;
+		break;
+	}
+	full_range = V4L2_QUANTIZATION_LIM_RANGE;
+
+	if (ptransfers)
+		*ptransfers = transfers;
+	if (pmatrix)
+		*pmatrix = matrix;
+	if (pfull_range)
+		*pfull_range = full_range;
+
+	return 0;
+}
diff --git a/drivers/media/platform/amphion/vpu_helpers.c b/drivers/media/platform/amphion/vpu_helpers.c
new file mode 100644
index 000000000000..768abf89e606
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_helpers.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_rpc.h"
+#include "vpu_helpers.h"
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x)
+{
+	int i;
+
+	for (i = 0; i < size; i++) {
+		if (array[i] == x)
+			return i;
+	}
+
+	return 0;
+}
+
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type)
+{
+	const struct vpu_format *pfmt;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
+			continue;
+		if (pfmt->type == type)
+			return true;
+	}
+
+	return false;
+}
+
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt)
+{
+	const struct vpu_format *pfmt;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	if (!vpu_iface_check_format(inst, pixelfmt))
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (pfmt->pixfmt == pixelfmt && (!type || type == pfmt->type))
+			return pfmt;
+	}
+
+	return NULL;
+}
+
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index)
+{
+	const struct vpu_format *pfmt;
+	int i = 0;
+
+	if (!inst || !inst->formats)
+		return NULL;
+
+	for (pfmt = inst->formats; pfmt->pixfmt; pfmt++) {
+		if (!vpu_iface_check_format(inst, pfmt->pixfmt))
+			continue;
+
+		if (pfmt->type == type) {
+			if (index == i)
+				return pfmt;
+			i++;
+		}
+	}
+
+	return NULL;
+}
+
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst)
+		return width;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return width;
+	if (res->max_width)
+		width = clamp(width, res->min_width, res->max_width);
+	if (res->step_width)
+		width = ALIGN(width, res->step_width);
+
+	return width;
+}
+
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height)
+{
+	const struct vpu_core_resources *res;
+
+	if (!inst)
+		return height;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return height;
+	if (res->max_height)
+		height = clamp(height, res->min_height, res->max_height);
+	if (res->step_height)
+		height = ALIGN(height, res->step_height);
+
+	return height;
+}
+
+static u32 get_nv12_plane_size(u32 width, u32 height, int plane_no,
+			       u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	height = ALIGN(height, 2);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = bytesperline * height >> 1;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_tiled_8l128_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+				      u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 ws = 3;
+	u32 hs = 7;
+	u32 bitdepth = 8;
+	u32 bytesperline;
+	u32 size = 0;
+
+	if (interlaced)
+		hs++;
+	if (fmt == V4L2_PIX_FMT_NV12M_10BE_8L128)
+		bitdepth = 10;
+	bytesperline = DIV_ROUND_UP(width * bitdepth, BITS_PER_BYTE);
+	bytesperline = ALIGN(bytesperline, 1 << ws);
+	bytesperline = ALIGN(bytesperline, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	height = ALIGN(height, 1 << hs);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	else if (plane_no == 1)
+		size = (bytesperline * ALIGN(height, 1 << (hs + 1))) >> 1;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+static u32 get_default_plane_size(u32 width, u32 height, int plane_no,
+				  u32 stride, u32 interlaced, u32 *pbl)
+{
+	u32 bytesperline;
+	u32 size = 0;
+
+	bytesperline = ALIGN(width, stride);
+	if (pbl)
+		bytesperline = max(bytesperline, *pbl);
+	if (plane_no == 0)
+		size = bytesperline * height;
+	if (pbl)
+		*pbl = bytesperline;
+
+	return size;
+}
+
+u32 vpu_helper_get_plane_size(u32 fmt, u32 w, u32 h, int plane_no,
+			      u32 stride, u32 interlaced, u32 *pbl)
+{
+	switch (fmt) {
+	case V4L2_PIX_FMT_NV12M:
+		return get_nv12_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	case V4L2_PIX_FMT_NV12M_8L128:
+	case V4L2_PIX_FMT_NV12M_10BE_8L128:
+		return get_tiled_8l128_plane_size(fmt, w, h, plane_no, stride, interlaced, pbl);
+	default:
+		return get_default_plane_size(w, h, plane_no, stride, interlaced, pbl);
+	}
+}
+
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+				       u32 *rptr, u32 size, void *dst)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !rptr || !dst)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *rptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memcpy(dst, virt + (offset - start), size);
+	} else {
+		memcpy(dst, virt + (offset - start), end - offset);
+		memcpy(dst + end - offset, virt, size + offset - end);
+	}
+
+	*rptr = vpu_helper_step_walk(stream_buffer, offset, size);
+	return size;
+}
+
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				     u32 *wptr, u32 size, void *src)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr || !src)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memcpy(virt + (offset - start), src, size);
+	} else {
+		memcpy(virt + (offset - start), src, end - offset);
+		memcpy(virt, src + end - offset, size + offset - end);
+	}
+
+	*wptr = vpu_helper_step_walk(stream_buffer, offset, size);
+
+	return size;
+}
+
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				    u32 *wptr, u8 val, u32 size)
+{
+	u32 offset;
+	u32 start;
+	u32 end;
+	void *virt;
+
+	if (!stream_buffer || !wptr)
+		return -EINVAL;
+
+	if (!size)
+		return 0;
+
+	offset = *wptr;
+	start = stream_buffer->phys;
+	end = start + stream_buffer->length;
+	virt = stream_buffer->virt;
+	if (offset < start || offset > end)
+		return -EINVAL;
+
+	if (offset + size <= end) {
+		memset(virt + (offset - start), val, size);
+	} else {
+		memset(virt + (offset - start), val, end - offset);
+		memset(virt, val, size + offset - end);
+	}
+
+	offset += size;
+	if (offset >= end)
+		offset -= stream_buffer->length;
+
+	*wptr = offset;
+
+	return size;
+}
+
+u32 vpu_helper_get_free_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.rptr > desc.wptr)
+		return desc.rptr - desc.wptr;
+	else if (desc.rptr < desc.wptr)
+		return (desc.end - desc.start + desc.rptr - desc.wptr);
+	else
+		return desc.end - desc.start;
+}
+
+u32 vpu_helper_get_used_space(struct vpu_inst *inst)
+{
+	struct vpu_rpc_buffer_desc desc;
+
+	if (vpu_iface_get_stream_buffer_desc(inst, &desc))
+		return 0;
+
+	if (desc.wptr > desc.rptr)
+		return desc.wptr - desc.rptr;
+	else if (desc.wptr < desc.rptr)
+		return (desc.end - desc.start + desc.wptr - desc.rptr);
+	else
+		return 0;
+}
+
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		ctrl->val = inst->min_buffer_cap;
+		break;
+	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+		ctrl->val = inst->min_buffer_out;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			      u32 pixelformat, u32 offset, u32 bytesused)
+{
+	u32 start_code;
+	int start_code_size;
+	u32 val = 0;
+	int i;
+	int ret = -EINVAL;
+
+	if (!stream_buffer || !stream_buffer->virt)
+		return -EINVAL;
+
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		start_code_size = 4;
+		start_code = 0x00000001;
+		break;
+	default:
+		return 0;
+	}
+
+	for (i = 0; i < bytesused; i++) {
+		val = (val << 8) | vpu_helper_read_byte(stream_buffer, offset + i);
+		if (i < start_code_size - 1)
+			continue;
+		if (val == start_code) {
+			ret = i + 1 - start_code_size;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].src == src)
+			return pairs[i].dst;
+	}
+
+	return -EINVAL;
+}
+
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst)
+{
+	u32 i;
+
+	if (!pairs || !cnt)
+		return -EINVAL;
+
+	for (i = 0; i < cnt; i++) {
+		if (pairs[i].dst == dst)
+			return pairs[i].src;
+	}
+
+	return -EINVAL;
+}
diff --git a/drivers/media/platform/amphion/vpu_helpers.h b/drivers/media/platform/amphion/vpu_helpers.h
new file mode 100644
index 000000000000..3676cc83e85b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_helpers.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_HELPERS_H
+#define _AMPHION_VPU_HELPERS_H
+
+struct vpu_pair {
+	u32 src;
+	u32 dst;
+};
+
+#define MAKE_TIMESTAMP(s, ns)		(((s32)(s) * NSEC_PER_SEC) + (ns))
+#define VPU_INVALID_TIMESTAMP		MAKE_TIMESTAMP(-1, 0)
+
+int vpu_helper_find_in_array_u8(const u8 *array, u32 size, u32 x);
+bool vpu_helper_check_type(struct vpu_inst *inst, u32 type);
+const struct vpu_format *vpu_helper_find_format(struct vpu_inst *inst, u32 type, u32 pixelfmt);
+const struct vpu_format *vpu_helper_enum_format(struct vpu_inst *inst, u32 type, int index);
+u32 vpu_helper_valid_frame_width(struct vpu_inst *inst, u32 width);
+u32 vpu_helper_valid_frame_height(struct vpu_inst *inst, u32 height);
+u32 vpu_helper_get_plane_size(u32 fmt, u32 width, u32 height, int plane_no,
+			      u32 stride, u32 interlaced, u32 *pbl);
+u32 vpu_helper_copy_from_stream_buffer(struct vpu_buffer *stream_buffer,
+				       u32 *rptr, u32 size, void *dst);
+u32 vpu_helper_copy_to_stream_buffer(struct vpu_buffer *stream_buffer,
+				     u32 *wptr, u32 size, void *src);
+u32 vpu_helper_memset_stream_buffer(struct vpu_buffer *stream_buffer,
+				    u32 *wptr, u8 val, u32 size);
+u32 vpu_helper_get_free_space(struct vpu_inst *inst);
+u32 vpu_helper_get_used_space(struct vpu_inst *inst);
+int vpu_helper_g_volatile_ctrl(struct v4l2_ctrl *ctrl);
+void vpu_helper_get_kmp_next(const u8 *pattern, int *next, int size);
+int vpu_helper_kmp_search(u8 *s, int s_len, const u8 *p, int p_len, int *next);
+int vpu_helper_kmp_search_in_stream_buffer(struct vpu_buffer *stream_buffer,
+					   u32 offset, int bytesused,
+					   const u8 *p, int p_len, int *next);
+int vpu_helper_find_startcode(struct vpu_buffer *stream_buffer,
+			      u32 pixelformat, u32 offset, u32 bytesused);
+
+static inline u32 vpu_helper_step_walk(struct vpu_buffer *stream_buffer, u32 pos, u32 step)
+{
+	pos += step;
+	if (pos > stream_buffer->phys + stream_buffer->length)
+		pos -= stream_buffer->length;
+
+	return pos;
+}
+
+static inline u8 vpu_helper_read_byte(struct vpu_buffer *stream_buffer, u32 pos)
+{
+	u8 *pdata = (u8 *)stream_buffer->virt;
+
+	return pdata[pos % stream_buffer->length];
+}
+
+int vpu_color_check_primaries(u32 primaries);
+int vpu_color_check_transfers(u32 transfers);
+int vpu_color_check_matrix(u32 matrix);
+int vpu_color_check_full_range(u32 full_range);
+u32 vpu_color_cvrt_primaries_v2i(u32 primaries);
+u32 vpu_color_cvrt_primaries_i2v(u32 primaries);
+u32 vpu_color_cvrt_transfers_v2i(u32 transfers);
+u32 vpu_color_cvrt_transfers_i2v(u32 transfers);
+u32 vpu_color_cvrt_matrix_v2i(u32 matrix);
+u32 vpu_color_cvrt_matrix_i2v(u32 matrix);
+u32 vpu_color_cvrt_full_range_v2i(u32 full_range);
+u32 vpu_color_cvrt_full_range_i2v(u32 full_range);
+int vpu_color_get_default(u32 primaries, u32 *ptransfers, u32 *pmatrix, u32 *pfull_range);
+
+int vpu_find_dst_by_src(struct vpu_pair *pairs, u32 cnt, u32 src);
+int vpu_find_src_by_dst(struct vpu_pair *pairs, u32 cnt, u32 dst);
+#endif
diff --git a/drivers/media/platform/amphion/vpu_v4l2.c b/drivers/media/platform/amphion/vpu_v4l2.c
new file mode 100644
index 000000000000..9d3176c0f5eb
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_v4l2.c
@@ -0,0 +1,720 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_core.h"
+#include "vpu_v4l2.h"
+#include "vpu_msgs.h"
+#include "vpu_helpers.h"
+
+void vpu_inst_lock(struct vpu_inst *inst)
+{
+	mutex_lock(&inst->lock);
+}
+
+void vpu_inst_unlock(struct vpu_inst *inst)
+{
+	mutex_unlock(&inst->lock);
+}
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_dma_contig_plane_dma_addr(vb, plane_no) +
+			vb->planes[plane_no].data_offset;
+}
+
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no)
+{
+	if (plane_no >= vb->num_planes)
+		return 0;
+	return vb2_plane_size(vb, plane_no) - vb->planes[plane_no].data_offset;
+}
+
+void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state)
+{
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	vpu_buf->state = state;
+}
+
+unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf)
+{
+	struct vpu_vb2_buffer *vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	return vpu_buf->state;
+}
+
+void vpu_v4l2_set_error(struct vpu_inst *inst)
+{
+	struct vb2_queue *src_q;
+	struct vb2_queue *dst_q;
+
+	if (!inst)
+		return;
+
+	vpu_inst_lock(inst);
+	dev_err(inst->dev, "some error occurs in codec\n");
+	if (inst->fh.m2m_ctx) {
+		src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+		dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+		if (src_q)
+			src_q->error = 1;
+		if (dst_q)
+			dst_q->error = 1;
+	}
+	vpu_inst_unlock(inst);
+}
+
+int vpu_notify_eos(struct vpu_inst *inst)
+{
+	static const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_EOS
+	};
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	v4l2_event_queue_fh(&inst->fh, &ev);
+
+	return 0;
+}
+
+int vpu_notify_source_change(struct vpu_inst *inst)
+{
+	static const struct v4l2_event ev = {
+		.id = 0,
+		.type = V4L2_EVENT_SOURCE_CHANGE,
+		.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION
+	};
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	v4l2_event_queue_fh(&inst->fh, &ev);
+	return 0;
+}
+
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return -EINVAL;
+
+	if (q->last_buffer_dequeued)
+		return 0;
+	vpu_trace(inst->dev, "last buffer dequeued\n");
+	q->last_buffer_dequeued = true;
+	wake_up(&q->done_wq);
+	vpu_notify_eos(inst);
+	return 0;
+}
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	u32 type = f->type;
+	u32 stride = 1;
+	u32 bytesperline;
+	u32 sizeimage;
+	const struct vpu_format *fmt;
+	const struct vpu_core_resources *res;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, type, pixmp->pixelformat);
+	if (!fmt) {
+		fmt = vpu_helper_enum_format(inst, type, 0);
+		if (!fmt)
+			return NULL;
+		pixmp->pixelformat = fmt->pixfmt;
+	}
+
+	res = vpu_get_resource(inst);
+	if (res)
+		stride = res->stride;
+	if (pixmp->width)
+		pixmp->width = vpu_helper_valid_frame_width(inst, pixmp->width);
+	if (pixmp->height)
+		pixmp->height = vpu_helper_valid_frame_height(inst, pixmp->height);
+	pixmp->flags = fmt->flags;
+	pixmp->num_planes = fmt->num_planes;
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		bytesperline = max_t(s32, pixmp->plane_fmt[i].bytesperline, 0);
+		sizeimage = vpu_helper_get_plane_size(pixmp->pixelformat,
+						      pixmp->width,
+						      pixmp->height,
+						      i,
+						      stride,
+						      pixmp->field > V4L2_FIELD_NONE ? 1 : 0,
+						      &bytesperline);
+		sizeimage = max_t(s32, pixmp->plane_fmt[i].sizeimage, sizeimage);
+		pixmp->plane_fmt[i].bytesperline = bytesperline;
+		pixmp->plane_fmt[i].sizeimage = sizeimage;
+	}
+
+	return fmt;
+}
+
+static bool vpu_check_ready(struct vpu_inst *inst, u32 type)
+{
+	if (!inst)
+		return false;
+	if (inst->state == VPU_CODEC_STATE_DEINIT || inst->id < 0)
+		return false;
+	if (!inst->ops->check_ready)
+		return true;
+	return call_vop(inst, check_ready, type);
+}
+
+int vpu_process_output_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->out_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+		vbuf = &buf->vb;
+		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
+			break;
+		vbuf = NULL;
+	}
+
+	if (!vbuf)
+		return -EINVAL;
+
+	dev_dbg(inst->dev, "[%d]frame id = %d / %d\n",
+		inst->id, vbuf->sequence, inst->sequence);
+	return call_vop(inst, process_output, &vbuf->vb2_buf);
+}
+
+int vpu_process_capture_buffer(struct vpu_inst *inst)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vpu_check_ready(inst, inst->cap_format.type))
+		return -EINVAL;
+
+	v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+		vbuf = &buf->vb;
+		if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_IDLE)
+			break;
+		vbuf = NULL;
+	}
+	if (!vbuf)
+		return -EINVAL;
+
+	return call_vop(inst, process_capture, &vbuf->vb2_buf);
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->sequence == sequence)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx)
+{
+	struct v4l2_m2m_buffer *buf = NULL;
+	struct vb2_v4l2_buffer *vbuf = NULL;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return NULL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		v4l2_m2m_for_each_src_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	} else {
+		v4l2_m2m_for_each_dst_buf(inst->fh.m2m_ctx, buf) {
+			vbuf = &buf->vb;
+			if (vbuf->vb2_buf.index == idx)
+				break;
+			vbuf = NULL;
+		}
+	}
+
+	return vbuf;
+}
+
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type)
+{
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	else
+		q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+
+	return q->num_buffers;
+}
+
+static void vpu_m2m_device_run(void *priv)
+{
+}
+
+static void vpu_m2m_job_abort(void *priv)
+{
+	struct vpu_inst *inst = priv;
+	struct v4l2_m2m_ctx *m2m_ctx = inst->fh.m2m_ctx;
+
+	v4l2_m2m_job_finish(m2m_ctx->m2m_dev, m2m_ctx);
+}
+
+static const struct v4l2_m2m_ops vpu_m2m_ops = {
+	.device_run = vpu_m2m_device_run,
+	.job_abort = vpu_m2m_job_abort
+};
+
+static int vpu_vb2_queue_setup(struct vb2_queue *vq,
+			       unsigned int *buf_count,
+			       unsigned int *plane_count,
+			       unsigned int psize[],
+			       struct device *allocators[])
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vq);
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, vq->type);
+
+	if (*plane_count) {
+		if (*plane_count != cur_fmt->num_planes)
+			return -EINVAL;
+		for (i = 0; i < cur_fmt->num_planes; i++) {
+			if (psize[i] < cur_fmt->sizeimage[i])
+				return -EINVAL;
+		}
+		return 0;
+	}
+
+	*plane_count = cur_fmt->num_planes;
+	for (i = 0; i < cur_fmt->num_planes; i++)
+		psize[i] = cur_fmt->sizeimage[i];
+
+	return 0;
+}
+
+static int vpu_vb2_buf_init(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	return 0;
+}
+
+static int vpu_vb2_buf_out_validate(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+
+	vbuf->field = V4L2_FIELD_NONE;
+
+	return 0;
+}
+
+static int vpu_vb2_buf_prepare(struct vb2_buffer *vb)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_format *cur_fmt;
+	u32 i;
+
+	cur_fmt = vpu_get_format(inst, vb->type);
+	for (i = 0; i < cur_fmt->num_planes; i++) {
+		if (vpu_get_vb_length(vb, i) < cur_fmt->sizeimage[i]) {
+			dev_dbg(inst->dev, "[%d] %s buf[%d] is invalid\n",
+				inst->id, vpu_type_name(vb->type), vb->index);
+			vpu_set_buffer_state(vbuf, VPU_BUF_STATE_ERROR);
+		}
+	}
+
+	return 0;
+}
+
+static void vpu_vb2_buf_finish(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+	struct vb2_queue *q = vb->vb2_queue;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_LAST)
+		vpu_notify_eos(inst);
+
+	if (list_empty(&q->done_list))
+		call_vop(inst, on_queue_empty, q->type);
+}
+
+void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state)
+{
+	struct vb2_v4l2_buffer *buf;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		while ((buf = v4l2_m2m_src_buf_remove(inst->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	} else {
+		while ((buf = v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
+			v4l2_m2m_buf_done(buf, state);
+	}
+}
+
+static int vpu_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+	struct vpu_format *fmt = vpu_get_format(inst, q->type);
+	int ret;
+
+	vpu_inst_unlock(inst);
+	ret = vpu_inst_register(inst);
+	vpu_inst_lock(inst);
+	if (ret) {
+		vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_QUEUED);
+		return ret;
+	}
+
+	vpu_trace(inst->dev, "[%d] %s %c%c%c%c %dx%d %u(%u) %u(%u) %u(%u) %d\n",
+		  inst->id, vpu_type_name(q->type),
+		  fmt->pixfmt,
+		  fmt->pixfmt >> 8,
+		  fmt->pixfmt >> 16,
+		  fmt->pixfmt >> 24,
+		  fmt->width, fmt->height,
+		  fmt->sizeimage[0], fmt->bytesperline[0],
+		  fmt->sizeimage[1], fmt->bytesperline[1],
+		  fmt->sizeimage[2], fmt->bytesperline[2],
+		  q->num_buffers);
+	call_vop(inst, start, q->type);
+	vb2_clear_last_buffer_dequeued(q);
+
+	return 0;
+}
+
+static void vpu_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct vpu_inst *inst = vb2_get_drv_priv(q);
+
+	vpu_trace(inst->dev, "[%d] %s\n", inst->id, vpu_type_name(q->type));
+
+	call_vop(inst, stop, q->type);
+	vpu_vb2_buffers_return(inst, q->type, VB2_BUF_STATE_ERROR);
+	if (V4L2_TYPE_IS_OUTPUT(q->type))
+		inst->sequence = 0;
+}
+
+static void vpu_vb2_buf_queue(struct vb2_buffer *vb)
+{
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	struct vpu_inst *inst = vb2_get_drv_priv(vb->vb2_queue);
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+	if (V4L2_TYPE_IS_OUTPUT(vb->type)) {
+		vbuf->sequence = inst->sequence++;
+		if ((s64)vb->timestamp < 0)
+			vb->timestamp = VPU_INVALID_TIMESTAMP;
+	}
+
+	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
+	vpu_process_output_buffer(inst);
+	vpu_process_capture_buffer(inst);
+}
+
+static const struct vb2_ops vpu_vb2_ops = {
+	.queue_setup        = vpu_vb2_queue_setup,
+	.buf_init           = vpu_vb2_buf_init,
+	.buf_out_validate   = vpu_vb2_buf_out_validate,
+	.buf_prepare        = vpu_vb2_buf_prepare,
+	.buf_finish         = vpu_vb2_buf_finish,
+	.start_streaming    = vpu_vb2_start_streaming,
+	.stop_streaming     = vpu_vb2_stop_streaming,
+	.buf_queue          = vpu_vb2_buf_queue,
+	.wait_prepare       = vb2_ops_wait_prepare,
+	.wait_finish        = vb2_ops_wait_finish,
+};
+
+static int vpu_m2m_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
+{
+	struct vpu_inst *inst = priv;
+	int ret;
+
+	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	inst->out_format.type = src_vq->type;
+	src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	src_vq->ops = &vpu_vb2_ops;
+	src_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_DEC && inst->use_stream_buffer)
+		src_vq->mem_ops = &vb2_vmalloc_memops;
+	src_vq->drv_priv = inst;
+	src_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	src_vq->min_buffers_needed = 1;
+	src_vq->dev = inst->vpu->dev;
+	src_vq->lock = &inst->lock;
+	ret = vb2_queue_init(src_vq);
+	if (ret)
+		return ret;
+
+	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	inst->cap_format.type = dst_vq->type;
+	dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
+	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	dst_vq->ops = &vpu_vb2_ops;
+	dst_vq->mem_ops = &vb2_dma_contig_memops;
+	if (inst->type == VPU_CORE_TYPE_ENC && inst->use_stream_buffer)
+		dst_vq->mem_ops = &vb2_vmalloc_memops;
+	dst_vq->drv_priv = inst;
+	dst_vq->buf_struct_size = sizeof(struct vpu_vb2_buffer);
+	dst_vq->min_buffers_needed = 1;
+	dst_vq->dev = inst->vpu->dev;
+	dst_vq->lock = &inst->lock;
+	ret = vb2_queue_init(dst_vq);
+	if (ret) {
+		vb2_queue_release(src_vq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int vpu_v4l2_release(struct vpu_inst *inst)
+{
+	vpu_trace(inst->vpu->dev, "%p\n", inst);
+
+	vpu_release_core(inst->core);
+	put_device(inst->dev);
+
+	if (inst->workqueue) {
+		cancel_work_sync(&inst->msg_work);
+		destroy_workqueue(inst->workqueue);
+		inst->workqueue = NULL;
+	}
+
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	mutex_destroy(&inst->lock);
+	v4l2_fh_del(&inst->fh);
+	v4l2_fh_exit(&inst->fh);
+
+	call_vop(inst, cleanup);
+
+	return 0;
+}
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct vpu_func *func;
+	int ret = 0;
+
+	if (!file || !inst || !inst->ops)
+		return -EINVAL;
+
+	if (inst->type == VPU_CORE_TYPE_ENC)
+		func = &vpu->encoder;
+	else
+		func = &vpu->decoder;
+
+	atomic_set(&inst->ref_count, 0);
+	vpu_inst_get(inst);
+	inst->vpu = vpu;
+	inst->core = vpu_request_core(vpu, inst->type);
+	if (inst->core)
+		inst->dev = get_device(inst->core->dev);
+	mutex_init(&inst->lock);
+	INIT_LIST_HEAD(&inst->cmd_q);
+	inst->id = VPU_INST_NULL_ID;
+	inst->release = vpu_v4l2_release;
+	inst->pid = current->pid;
+	inst->tgid = current->tgid;
+	inst->min_buffer_cap = 2;
+	inst->min_buffer_out = 2;
+	v4l2_fh_init(&inst->fh, func->vfd);
+	v4l2_fh_add(&inst->fh);
+
+	ret = call_vop(inst, ctrl_init);
+	if (ret)
+		goto error;
+
+	inst->fh.m2m_ctx = v4l2_m2m_ctx_init(func->m2m_dev, inst, vpu_m2m_queue_init);
+	if (IS_ERR(inst->fh.m2m_ctx)) {
+		dev_err(vpu->dev, "v4l2_m2m_ctx_init fail\n");
+		ret = PTR_ERR(func->m2m_dev);
+		goto error;
+	}
+
+	inst->fh.ctrl_handler = &inst->ctrl_handler;
+	file->private_data = &inst->fh;
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	inst->workqueue = alloc_workqueue("vpu_inst", WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (inst->workqueue) {
+		INIT_WORK(&inst->msg_work, vpu_inst_run_work);
+		ret = kfifo_init(&inst->msg_fifo,
+				 inst->msg_buffer,
+				 rounddown_pow_of_two(sizeof(inst->msg_buffer)));
+		if (ret) {
+			destroy_workqueue(inst->workqueue);
+			inst->workqueue = NULL;
+		}
+	}
+	vpu_trace(vpu->dev, "tgid = %d, pid = %d, type = %s, inst = %p\n",
+		  inst->tgid, inst->pid, vpu_core_type_desc(inst->type), inst);
+
+	return 0;
+error:
+	vpu_inst_put(inst);
+	return ret;
+}
+
+int vpu_v4l2_close(struct file *file)
+{
+	struct vpu_dev *vpu = video_drvdata(file);
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_trace(vpu->dev, "tgid = %d, pid = %d, inst = %p\n", inst->tgid, inst->pid, inst);
+
+	vpu_inst_lock(inst);
+	if (inst->fh.m2m_ctx) {
+		v4l2_m2m_ctx_release(inst->fh.m2m_ctx);
+		inst->fh.m2m_ctx = NULL;
+	}
+	vpu_inst_unlock(inst);
+
+	call_vop(inst, release);
+	vpu_inst_unregister(inst);
+	vpu_inst_put(inst);
+
+	return 0;
+}
+
+int vpu_add_func(struct vpu_dev *vpu, struct vpu_func *func)
+{
+	struct video_device *vfd;
+	int ret;
+
+	if (!vpu || !func)
+		return -EINVAL;
+
+	if (func->vfd)
+		return 0;
+
+	func->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
+	if (IS_ERR(func->m2m_dev)) {
+		dev_err(vpu->dev, "v4l2_m2m_init fail\n");
+		func->vfd = NULL;
+		return PTR_ERR(func->m2m_dev);
+	}
+
+	vfd = video_device_alloc();
+	if (!vfd) {
+		v4l2_m2m_release(func->m2m_dev);
+		dev_err(vpu->dev, "alloc vpu decoder video device fail\n");
+		return -ENOMEM;
+	}
+	vfd->release = video_device_release;
+	vfd->vfl_dir = VFL_DIR_M2M;
+	vfd->v4l2_dev = &vpu->v4l2_dev;
+	vfd->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+	if (func->type == VPU_CORE_TYPE_ENC) {
+		strscpy(vfd->name, "amphion-vpu-encoder", sizeof(vfd->name));
+		vfd->fops = venc_get_fops();
+		vfd->ioctl_ops = venc_get_ioctl_ops();
+	} else {
+		strscpy(vfd->name, "amphion-vpu-decoder", sizeof(vfd->name));
+		vfd->fops = vdec_get_fops();
+		vfd->ioctl_ops = vdec_get_ioctl_ops();
+	}
+
+	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		video_device_release(vfd);
+		v4l2_m2m_release(func->m2m_dev);
+		return ret;
+	}
+	video_set_drvdata(vfd, vpu);
+	func->vfd = vfd;
+
+	ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);
+	if (ret) {
+		v4l2_m2m_release(func->m2m_dev);
+		func->m2m_dev = NULL;
+		video_unregister_device(func->vfd);
+		func->vfd = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void vpu_remove_func(struct vpu_func *func)
+{
+	if (!func)
+		return;
+
+	if (func->m2m_dev) {
+		v4l2_m2m_unregister_media_controller(func->m2m_dev);
+		v4l2_m2m_release(func->m2m_dev);
+		func->m2m_dev = NULL;
+	}
+	if (func->vfd) {
+		video_unregister_device(func->vfd);
+		func->vfd = NULL;
+	}
+}
diff --git a/drivers/media/platform/amphion/vpu_v4l2.h b/drivers/media/platform/amphion/vpu_v4l2.h
new file mode 100644
index 000000000000..90fa7ea67495
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_v4l2.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_V4L2_H
+#define _AMPHION_VPU_V4L2_H
+
+#include <linux/videodev2.h>
+
+void vpu_inst_lock(struct vpu_inst *inst);
+void vpu_inst_unlock(struct vpu_inst *inst);
+void vpu_set_buffer_state(struct vb2_v4l2_buffer *vbuf, unsigned int state);
+unsigned int vpu_get_buffer_state(struct vb2_v4l2_buffer *vbuf);
+
+int vpu_v4l2_open(struct file *file, struct vpu_inst *inst);
+int vpu_v4l2_close(struct file *file);
+
+const struct vpu_format *vpu_try_fmt_common(struct vpu_inst *inst, struct v4l2_format *f);
+int vpu_process_output_buffer(struct vpu_inst *inst);
+int vpu_process_capture_buffer(struct vpu_inst *inst);
+struct vb2_v4l2_buffer *vpu_find_buf_by_sequence(struct vpu_inst *inst, u32 type, u32 sequence);
+struct vb2_v4l2_buffer *vpu_find_buf_by_idx(struct vpu_inst *inst, u32 type, u32 idx);
+void vpu_v4l2_set_error(struct vpu_inst *inst);
+int vpu_notify_eos(struct vpu_inst *inst);
+int vpu_notify_source_change(struct vpu_inst *inst);
+int vpu_set_last_buffer_dequeued(struct vpu_inst *inst);
+void vpu_vb2_buffers_return(struct vpu_inst *inst, unsigned int type, enum vb2_buffer_state state);
+int vpu_get_num_buffers(struct vpu_inst *inst, u32 type);
+
+dma_addr_t vpu_get_vb_phy_addr(struct vb2_buffer *vb, u32 plane_no);
+unsigned int vpu_get_vb_length(struct vb2_buffer *vb, u32 plane_no);
+static inline struct vpu_format *vpu_get_format(struct vpu_inst *inst, u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return &inst->out_format;
+	else
+		return &inst->cap_format;
+}
+
+static inline char *vpu_type_name(u32 type)
+{
+	return V4L2_TYPE_IS_OUTPUT(type) ? "output" : "capture";
+}
+
+static inline int vpu_vb_is_codecconfig(struct vb2_v4l2_buffer *vbuf)
+{
+#ifdef V4L2_BUF_FLAG_CODECCONFIG
+	return (vbuf->flags & V4L2_BUF_FLAG_CODECCONFIG) ? 1 : 0;
+#else
+	return 0;
+#endif
+}
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:26 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:26 +0800
Subject: [PATCH v15.1 07/13] media: amphion: add v4l2 m2m vpu encoder stateful
 driver
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <b53eac2b43b211e1cb12841a078e18dcc5c695e6.1643165765.git.ming.qian@nxp.com>

This consists of video encoder implementation plus encoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/venc.c | 1365 +++++++++++++++++++++++++
 1 file changed, 1365 insertions(+)
 create mode 100644 drivers/media/platform/amphion/venc.c

diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c
new file mode 100644
index 000000000000..3b96d6f91e6e
--- /dev/null
+++ b/drivers/media/platform/amphion/venc.c
@@ -0,0 +1,1365 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <linux/ktime.h>
+#include <linux/rational.h>
+#include <linux/vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+
+#define VENC_OUTPUT_ENABLE	BIT(0)
+#define VENC_CAPTURE_ENABLE	BIT(1)
+#define VENC_ENABLE_MASK	(VENC_OUTPUT_ENABLE | VENC_CAPTURE_ENABLE)
+#define VENC_MAX_BUF_CNT	8
+
+struct venc_t {
+	struct vpu_encode_params params;
+	u32 request_key_frame;
+	u32 input_ready;
+	u32 cpb_size;
+	bool bitrate_change;
+
+	struct vpu_buffer enc[VENC_MAX_BUF_CNT];
+	struct vpu_buffer ref[VENC_MAX_BUF_CNT];
+	struct vpu_buffer act[VENC_MAX_BUF_CNT];
+	struct list_head frames;
+	u32 frame_count;
+	u32 encode_count;
+	u32 ready_count;
+	u32 enable;
+	u32 stopped;
+
+	u32 skipped_count;
+	u32 skipped_bytes;
+
+	wait_queue_head_t wq;
+};
+
+struct venc_frame_t {
+	struct list_head list;
+	struct vpu_enc_pic_info info;
+	u32 bytesused;
+	s64 timestamp;
+};
+
+static const struct vpu_format venc_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{0, 0, 0, 0},
+};
+
+static int venc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "amphion vpu encoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int venc_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+	fmt = vpu_helper_enum_format(inst, f->type, f->index);
+	if (!fmt)
+		return -EINVAL;
+
+	f->pixelformat = fmt->pixfmt;
+	f->flags = fmt->flags;
+
+	return 0;
+}
+
+static int venc_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+
+	if (!fsize || fsize->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fsize->pixel_format))
+		return -EINVAL;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.max_width = res->max_width;
+	fsize->stepwise.max_height = res->max_height;
+	fsize->stepwise.min_width = res->min_width;
+	fsize->stepwise.min_height = res->min_height;
+	fsize->stepwise.step_width = res->step_width;
+	fsize->stepwise.step_height = res->step_height;
+
+	return 0;
+}
+
+static int venc_enum_frameintervals(struct file *file, void *fh, struct v4l2_frmivalenum *fival)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+
+	if (!fival || fival->index)
+		return -EINVAL;
+
+	if (!vpu_helper_find_format(inst, 0, fival->pixel_format))
+		return -EINVAL;
+
+	if (!fival->width || !fival->height)
+		return -EINVAL;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+	if (fival->width < res->min_width || fival->width > res->max_width ||
+	    fival->height < res->min_height || fival->height > res->max_height)
+		return -EINVAL;
+
+	fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = USHRT_MAX;
+	fival->stepwise.max.numerator = USHRT_MAX;
+	fival->stepwise.max.denominator = 1;
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = 1;
+
+	return 0;
+}
+
+static int venc_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = venc->params.color.primaries;
+	f->fmt.pix_mp.xfer_func = venc->params.color.transfer;
+	f->fmt.pix_mp.ycbcr_enc = venc->params.color.matrix;
+	f->fmt.pix_mp.quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	vpu_try_fmt_common(inst, f);
+
+	return 0;
+}
+
+static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct venc_t *venc = inst->priv;
+	struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	cur_fmt->pixfmt = fmt->pixfmt;
+	cur_fmt->num_planes = fmt->num_planes;
+	cur_fmt->flags = fmt->flags;
+	cur_fmt->width = pix_mp->width;
+	cur_fmt->height = pix_mp->height;
+	for (i = 0; i < fmt->num_planes; i++) {
+		cur_fmt->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage;
+		cur_fmt->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline;
+	}
+
+	if (pix_mp->field != V4L2_FIELD_ANY)
+		cur_fmt->field = pix_mp->field;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		venc->params.input_format = cur_fmt->pixfmt;
+		venc->params.src_stride = cur_fmt->bytesperline[0];
+		venc->params.src_width = cur_fmt->width;
+		venc->params.src_height = cur_fmt->height;
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = cur_fmt->width;
+		venc->params.crop.height = cur_fmt->height;
+	} else {
+		venc->params.codec_format = cur_fmt->pixfmt;
+		venc->params.out_width = cur_fmt->width;
+		venc->params.out_height = cur_fmt->height;
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+		if (!vpu_color_check_primaries(pix_mp->colorspace)) {
+			venc->params.color.primaries = pix_mp->colorspace;
+			vpu_color_get_default(venc->params.color.primaries,
+					      &venc->params.color.transfer,
+					      &venc->params.color.matrix,
+					      &venc->params.color.full_range);
+		}
+		if (!vpu_color_check_transfers(pix_mp->xfer_func))
+			venc->params.color.transfer = pix_mp->xfer_func;
+		if (!vpu_color_check_matrix(pix_mp->ycbcr_enc))
+			venc->params.color.matrix = pix_mp->ycbcr_enc;
+		if (!vpu_color_check_full_range(pix_mp->quantization))
+			venc->params.color.full_range = pix_mp->quantization;
+	}
+
+	pix_mp->colorspace = venc->params.color.primaries;
+	pix_mp->xfer_func = venc->params.color.transfer;
+	pix_mp->ycbcr_enc = venc->params.color.matrix;
+	pix_mp->quantization = venc->params.color.full_range;
+
+	return 0;
+}
+
+static int venc_g_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	parm->parm.capture.readbuffers = 0;
+	timeperframe->numerator = venc->params.frame_rate.numerator;
+	timeperframe->denominator = venc->params.frame_rate.denominator;
+
+	return 0;
+}
+
+static int venc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *parm)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+	struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe;
+	unsigned long n, d;
+
+	if (!parm)
+		return -EINVAL;
+
+	if (!vpu_helper_check_type(inst, parm->type))
+		return -EINVAL;
+
+	if (!timeperframe->numerator)
+		timeperframe->numerator = venc->params.frame_rate.numerator;
+	if (!timeperframe->denominator)
+		timeperframe->denominator = venc->params.frame_rate.denominator;
+
+	venc->params.frame_rate.numerator = timeperframe->numerator;
+	venc->params.frame_rate.denominator = timeperframe->denominator;
+
+	rational_best_approximation(venc->params.frame_rate.numerator,
+				    venc->params.frame_rate.denominator,
+				    venc->params.frame_rate.numerator,
+				    venc->params.frame_rate.denominator,
+				    &n, &d);
+	venc->params.frame_rate.numerator = n;
+	venc->params.frame_rate.denominator = d;
+
+	parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	memset(parm->parm.capture.reserved, 0, sizeof(parm->parm.capture.reserved));
+
+	return 0;
+}
+
+static int venc_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc = inst->priv;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP_DEFAULT:
+	case V4L2_SEL_TGT_CROP_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->out_format.width;
+		s->r.height = inst->out_format.height;
+		break;
+	case V4L2_SEL_TGT_CROP:
+		s->r = venc->params.crop;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int venc_valid_crop(struct venc_t *venc, const struct vpu_core_resources *res)
+{
+	struct v4l2_rect *rect = NULL;
+	u32 min_width;
+	u32 min_height;
+	u32 src_width;
+	u32 src_height;
+
+	rect = &venc->params.crop;
+	min_width = res->min_width;
+	min_height = res->min_height;
+	src_width = venc->params.src_width;
+	src_height = venc->params.src_height;
+
+	if (rect->width == 0 || rect->height == 0)
+		return -EINVAL;
+	if (rect->left > src_width - min_width || rect->top > src_height - min_height)
+		return -EINVAL;
+
+	rect->width = min(rect->width, src_width - rect->left);
+	rect->width = max_t(u32, rect->width, min_width);
+
+	rect->height = min(rect->height, src_height - rect->top);
+	rect->height = max_t(u32, rect->height, min_height);
+
+	return 0;
+}
+
+static int venc_s_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+	const struct vpu_core_resources *res;
+	struct venc_t *venc = inst->priv;
+
+	res = vpu_get_resource(inst);
+	if (!res)
+		return -EINVAL;
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		return -EINVAL;
+	if (s->target != V4L2_SEL_TGT_CROP)
+		return -EINVAL;
+
+	venc->params.crop.left = ALIGN(s->r.left, res->step_width);
+	venc->params.crop.top = ALIGN(s->r.top, res->step_height);
+	venc->params.crop.width = ALIGN(s->r.width, res->step_width);
+	venc->params.crop.height = ALIGN(s->r.height, res->step_height);
+	if (venc_valid_crop(venc, res)) {
+		venc->params.crop.left = 0;
+		venc->params.crop.top = 0;
+		venc->params.crop.width = venc->params.src_width;
+		venc->params.crop.height = venc->params.src_height;
+	}
+
+	inst->crop = venc->params.crop;
+
+	return 0;
+}
+
+static int venc_drain(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state != VPU_CODEC_STATE_DRAIN)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
+		return 0;
+
+	if (!venc->input_ready)
+		return 0;
+
+	venc->input_ready = false;
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	ret = vpu_session_stop(inst);
+	if (ret)
+		return ret;
+	inst->state = VPU_CODEC_STATE_STOP;
+	wake_up_all(&venc->wq);
+
+	return 0;
+}
+
+static int venc_request_eos(struct vpu_inst *inst)
+{
+	inst->state = VPU_CODEC_STATE_DRAIN;
+	venc_drain(inst);
+
+	return 0;
+}
+
+static int venc_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	if (cmd->cmd == V4L2_ENC_CMD_STOP) {
+		if (inst->state == VPU_CODEC_STATE_DEINIT)
+			vpu_set_last_buffer_dequeued(inst);
+		else
+			venc_request_eos(inst);
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int venc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+}
+
+static const struct v4l2_ioctl_ops venc_ioctl_ops = {
+	.vidioc_querycap               = venc_querycap,
+	.vidioc_enum_fmt_vid_cap       = venc_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = venc_enum_fmt,
+	.vidioc_enum_framesizes        = venc_enum_framesizes,
+	.vidioc_enum_frameintervals    = venc_enum_frameintervals,
+	.vidioc_g_fmt_vid_cap_mplane   = venc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = venc_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = venc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = venc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = venc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = venc_s_fmt,
+	.vidioc_g_parm                 = venc_g_parm,
+	.vidioc_s_parm                 = venc_s_parm,
+	.vidioc_g_selection            = venc_g_selection,
+	.vidioc_s_selection            = venc_s_selection,
+	.vidioc_try_encoder_cmd        = v4l2_m2m_ioctl_try_encoder_cmd,
+	.vidioc_encoder_cmd            = venc_encoder_cmd,
+	.vidioc_subscribe_event        = venc_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static int venc_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct vpu_inst *inst = ctrl_to_inst(ctrl);
+	struct venc_t *venc = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	switch (ctrl->id) {
+	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
+		venc->params.profile = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
+		venc->params.level = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE:
+		venc->params.rc_enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+		venc->params.rc_mode = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE:
+		if (ctrl->val != venc->params.bitrate)
+			venc->bitrate_change = true;
+		venc->params.bitrate = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+		venc->params.bitrate_max = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+		venc->params.gop_length = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+		venc->params.bframes = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP:
+		venc->params.i_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP:
+		venc->params.p_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP:
+		venc->params.b_frame_qp = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME:
+		venc->request_key_frame = 1;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE:
+		venc->cpb_size = ctrl->val * 1024;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
+		venc->params.sar.enable = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC:
+		venc->params.sar.idc = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH:
+		venc->params.sar.width = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT:
+		venc->params.sar.height = ctrl->val;
+		break;
+	case V4L2_CID_MPEG_VIDEO_HEADER_MODE:
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops venc_ctrl_ops = {
+	.s_ctrl = venc_op_s_ctrl,
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int venc_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+			       ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+				 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)),
+			       V4L2_MPEG_VIDEO_H264_PROFILE_HIGH);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+			       0x0,
+			       V4L2_MPEG_VIDEO_H264_LEVEL_4_0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE, 0, 1, 1, 1);
+
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+			       ~((1 << V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+				 (1 << V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)),
+			       V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_BITRATE,
+			  BITRATE_MIN,
+			  BITRATE_MAX,
+			  BITRATE_STEP,
+			  BITRATE_DEFAULT);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+			  BITRATE_MIN, BITRATE_MAX,
+			  BITRATE_STEP,
+			  BITRATE_DEFAULT_PEAK);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_GOP_SIZE, 0, (1 << 16) - 1, 1, 30);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_B_FRAMES, 0, 4, 1, 0);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP, 1, 51, 1, 26);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP, 1, 51, 1, 28);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP, 1, 51, 1, 30);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME, 0, 0, 0, 0);
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_CPB_SIZE, 64, 10240, 1, 1024);
+
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE, 0, 1, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_IDC,
+			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED,
+			       0x0,
+			       V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_1x1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH,
+			  0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std(&inst->ctrl_handler, &venc_ctrl_ops,
+			  V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_HEIGHT,
+			  0, USHRT_MAX, 1, 1);
+	v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &venc_ctrl_ops,
+			       V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+			       ~(1 << V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+			       V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME);
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static bool venc_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vpu_helper_get_free_space(inst) < venc->cpb_size)
+			return false;
+		return venc->input_ready;
+	}
+
+	if (list_empty(&venc->frames))
+		return false;
+	return true;
+}
+
+static u32 venc_get_enable_mask(u32 type)
+{
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return VENC_OUTPUT_ENABLE;
+	else
+		return VENC_CAPTURE_ENABLE;
+}
+
+static void venc_set_enable(struct venc_t *venc, u32 type, int enable)
+{
+	u32 mask = venc_get_enable_mask(type);
+
+	if (enable)
+		venc->enable |= mask;
+	else
+		venc->enable &= ~mask;
+}
+
+static u32 venc_get_enable(struct venc_t *venc, u32 type)
+{
+	return venc->enable & venc_get_enable_mask(type);
+}
+
+static void venc_input_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->input_ready = true;
+	vpu_process_output_buffer(inst);
+	if (inst->state == VPU_CODEC_STATE_DRAIN)
+		venc_drain(inst);
+	vpu_inst_unlock(inst);
+}
+
+/*
+ * It's hardware limitation, that there may be several bytes
+ * redundant data at the beginning of frame.
+ * For android platform, the redundant data may cause cts test fail
+ * So driver will strip them
+ */
+static int venc_precheck_encoded_frame(struct vpu_inst *inst, struct venc_frame_t *frame)
+{
+	struct venc_t *venc;
+	int skipped;
+
+	if (!inst || !frame || !frame->bytesused)
+		return -EINVAL;
+
+	venc = inst->priv;
+	skipped = vpu_helper_find_startcode(&inst->stream_buffer,
+					    inst->cap_format.pixfmt,
+					    frame->info.wptr - inst->stream_buffer.phys,
+					    frame->bytesused);
+	if (skipped > 0) {
+		frame->bytesused -= skipped;
+		frame->info.wptr = vpu_helper_step_walk(&inst->stream_buffer,
+							frame->info.wptr, skipped);
+		venc->skipped_bytes += skipped;
+		venc->skipped_count++;
+	}
+
+	return 0;
+}
+
+static int venc_get_one_encoded_frame(struct vpu_inst *inst,
+				      struct venc_frame_t *frame,
+				      struct vb2_v4l2_buffer *vbuf)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (!vbuf)
+		return -EAGAIN;
+
+	if (!venc_get_enable(inst->priv, vbuf->vb2_buf.type)) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return 0;
+	}
+	if (frame->bytesused > vbuf->vb2_buf.planes[0].length) {
+		v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR);
+		return -ENOMEM;
+	}
+
+	venc_precheck_encoded_frame(inst, frame);
+
+	if (frame->bytesused) {
+		u32 rptr = frame->info.wptr;
+		void *dst = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
+
+		vpu_helper_copy_from_stream_buffer(&inst->stream_buffer,
+						   &rptr, frame->bytesused, dst);
+		vpu_iface_update_stream_buffer(inst, rptr, 0);
+	}
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, frame->bytesused);
+	vbuf->sequence = frame->info.frame_id;
+	vbuf->vb2_buf.timestamp = frame->info.timestamp;
+	vbuf->field = inst->cap_format.field;
+	vbuf->flags |= frame->info.pic_type;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->info.timestamp);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	venc->ready_count++;
+
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		dev_dbg(inst->dev, "[%d][%d]key frame\n", inst->id, frame->info.frame_id);
+
+	return 0;
+}
+
+static int venc_get_encoded_frames(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	if (!inst || !inst->priv || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	venc = inst->priv;
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		if (venc_get_one_encoded_frame(inst, frame,
+					       v4l2_m2m_dst_buf_remove(inst->fh.m2m_ctx)))
+			break;
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+
+	return 0;
+}
+
+static int venc_frame_encoded(struct vpu_inst *inst, void *arg)
+{
+	struct vpu_enc_pic_info *info = arg;
+	struct venc_frame_t *frame;
+	struct venc_t *venc;
+	int ret = 0;
+
+	if (!inst || !info)
+		return -EINVAL;
+	venc = inst->priv;
+	frame = vzalloc(sizeof(*frame));
+	if (!frame)
+		return -ENOMEM;
+
+	memcpy(&frame->info, info, sizeof(frame->info));
+	frame->bytesused = info->frame_size;
+
+	vpu_inst_lock(inst);
+	list_add_tail(&frame->list, &venc->frames);
+	venc->encode_count++;
+	venc_get_encoded_frames(inst);
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static void venc_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!inst || !frame || !inst->fh.m2m_ctx)
+		return;
+
+	vpu_inst_lock(inst);
+	if (!venc_get_enable(inst->priv, frame->type))
+		goto exit;
+	vbuf = vpu_find_buf_by_sequence(inst, frame->type, frame->sequence);
+	if (!vbuf) {
+		dev_err(inst->dev, "[%d] can't find buf: type %d, sequence %d\n",
+			inst->id, frame->type, frame->sequence);
+		goto exit;
+	}
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	if (V4L2_TYPE_IS_OUTPUT(frame->type))
+		v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	else
+		v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void venc_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (venc->stopped && list_empty(&venc->frames))
+		vpu_set_last_buffer_dequeued(inst);
+}
+
+static void venc_stop_done(struct vpu_inst *inst)
+{
+	struct venc_t *venc = inst->priv;
+
+	vpu_inst_lock(inst);
+	venc->stopped = true;
+	venc_set_last_buffer_dequeued(inst);
+	vpu_inst_unlock(inst);
+
+	wake_up_all(&venc->wq);
+}
+
+static void venc_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+}
+
+static void venc_release(struct vpu_inst *inst)
+{
+}
+
+static void venc_cleanup(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+
+	if (!inst)
+		return;
+
+	venc = inst->priv;
+	if (venc)
+		vfree(venc);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static int venc_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	venc_set_enable(venc, type, 1);
+	if ((venc->enable & VENC_ENABLE_MASK) != VENC_ENABLE_MASK)
+		return 0;
+
+	vpu_iface_init_instance(inst);
+	stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+	if (stream_buffer_size > 0) {
+		inst->stream_buffer.length = max_t(u32, stream_buffer_size, venc->cpb_size * 3);
+		ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+		if (ret)
+			goto error;
+
+		inst->use_stream_buffer = true;
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	}
+
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 0);
+	if (ret)
+		goto error;
+	ret = vpu_session_configure_codec(inst);
+	if (ret)
+		goto error;
+
+	inst->state = VPU_CODEC_STATE_CONFIGURED;
+	/*vpu_iface_config_memory_resource*/
+
+	/*config enc expert mode parameter*/
+	ret = vpu_iface_set_encode_params(inst, &venc->params, 1);
+	if (ret)
+		goto error;
+
+	ret = vpu_session_start(inst);
+	if (ret)
+		goto error;
+	inst->state = VPU_CODEC_STATE_STARTED;
+
+	venc->bitrate_change = false;
+	venc->input_ready = true;
+	venc->frame_count = 0;
+	venc->encode_count = 0;
+	venc->ready_count = 0;
+	venc->stopped = false;
+	vpu_process_output_buffer(inst);
+	if (venc->frame_count == 0)
+		dev_err(inst->dev, "[%d] there is no input when starting\n", inst->id);
+
+	return 0;
+error:
+	venc_set_enable(venc, type, 0);
+	inst->state = VPU_CODEC_STATE_DEINIT;
+
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static void venc_cleanup_mem_resource(struct vpu_inst *inst)
+{
+	struct venc_t *venc;
+	u32 i;
+
+	venc = inst->priv;
+
+	for (i = 0; i < ARRAY_SIZE(venc->enc); i++)
+		vpu_free_dma(&venc->enc[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->ref); i++)
+		vpu_free_dma(&venc->ref[i]);
+	for (i = 0; i < ARRAY_SIZE(venc->act); i++)
+		vpu_free_dma(&venc->act[i]);
+}
+
+static void venc_request_mem_resource(struct vpu_inst *inst,
+				      u32 enc_frame_size,
+				      u32 enc_frame_num,
+				      u32 ref_frame_size,
+				      u32 ref_frame_num,
+				      u32 act_frame_size,
+				      u32 act_frame_num)
+{
+	struct venc_t *venc;
+	u32 i;
+	int ret;
+
+	venc = inst->priv;
+	if (enc_frame_num > ARRAY_SIZE(venc->enc)) {
+		dev_err(inst->dev, "[%d] enc num(%d) is out of range\n", inst->id, enc_frame_num);
+		return;
+	}
+	if (ref_frame_num > ARRAY_SIZE(venc->ref)) {
+		dev_err(inst->dev, "[%d] ref num(%d) is out of range\n", inst->id, ref_frame_num);
+		return;
+	}
+	if (act_frame_num > ARRAY_SIZE(venc->act)) {
+		dev_err(inst->dev, "[%d] act num(%d) is out of range\n", inst->id, act_frame_num);
+		return;
+	}
+
+	for (i = 0; i < enc_frame_num; i++) {
+		venc->enc[i].length = enc_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->enc[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	for (i = 0; i < ref_frame_num; i++) {
+		venc->ref[i].length = ref_frame_size;
+		ret = vpu_alloc_dma(inst->core, &venc->ref[i]);
+		if (ret) {
+			venc_cleanup_mem_resource(inst);
+			return;
+		}
+	}
+	if (act_frame_num != 1 || act_frame_size > inst->act.length) {
+		venc_cleanup_mem_resource(inst);
+		return;
+	}
+	venc->act[0].length = act_frame_size;
+	venc->act[0].phys = inst->act.phys;
+	venc->act[0].virt = inst->act.virt;
+
+	for (i = 0; i < enc_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ENC, i, &venc->enc[i]);
+	for (i = 0; i < ref_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_REF, i, &venc->ref[i]);
+	for (i = 0; i < act_frame_num; i++)
+		vpu_iface_config_memory_resource(inst, MEM_RES_ACT, i, &venc->act[i]);
+}
+
+static void venc_cleanup_frames(struct venc_t *venc)
+{
+	struct venc_frame_t *frame;
+	struct venc_frame_t *tmp;
+
+	list_for_each_entry_safe(frame, tmp, &venc->frames, list) {
+		list_del_init(&frame->list);
+		vfree(frame);
+	}
+}
+
+static int venc_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	venc_set_enable(venc, type, 0);
+	if (venc->enable & VENC_ENABLE_MASK)
+		return 0;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (inst->state != VPU_CODEC_STATE_STOP)
+		venc_request_eos(inst);
+
+	call_vop(inst, wait_prepare);
+	if (!wait_event_timeout(venc->wq, venc->stopped, VPU_TIMEOUT)) {
+		set_bit(inst->id, &inst->core->hang_mask);
+		vpu_session_debug(inst);
+	}
+	call_vop(inst, wait_finish);
+
+	inst->state = VPU_CODEC_STATE_DEINIT;
+	venc_cleanup_frames(inst->priv);
+	vpu_free_dma(&inst->stream_buffer);
+	venc_cleanup_mem_resource(inst);
+
+	return 0;
+}
+
+static int venc_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 flags;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		inst->state = VPU_CODEC_STATE_ACTIVE;
+
+	flags = vbuf->flags;
+	if (venc->request_key_frame) {
+		vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME;
+		venc->request_key_frame = 0;
+	}
+	if (venc->bitrate_change) {
+		vpu_session_update_parameters(inst, &venc->params);
+		venc->bitrate_change = false;
+	}
+	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
+	vpu_iface_input_frame(inst, vb);
+	vbuf->flags = flags;
+	venc->input_ready = false;
+	venc->frame_count++;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
+
+	return 0;
+}
+
+static int venc_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct venc_t *venc;
+	struct venc_frame_t *frame = NULL;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	venc = inst->priv;
+	if (list_empty(&venc->frames))
+		return -EINVAL;
+
+	frame = list_first_entry(&venc->frames, struct venc_frame_t, list);
+	vbuf = to_vb2_v4l2_buffer(vb);
+	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	ret = venc_get_one_encoded_frame(inst, frame, vbuf);
+	if (ret)
+		return ret;
+
+	list_del_init(&frame->list);
+	vfree(frame);
+	return 0;
+}
+
+static void venc_on_queue_empty(struct vpu_inst *inst, u32 type)
+{
+	struct venc_t *venc = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	if (venc->stopped)
+		venc_set_last_buffer_dequeued(inst);
+}
+
+static int venc_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct venc_t *venc = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size, "profile = %d\n", venc->params.profile);
+		break;
+	case 1:
+		num = scnprintf(str, size, "level = %d\n", venc->params.level);
+		break;
+	case 2:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				venc->params.frame_rate.numerator,
+				venc->params.frame_rate.denominator);
+		break;
+	case 3:
+		num = scnprintf(str, size, "%d x %d -> %d x %d\n",
+				venc->params.src_width,
+				venc->params.src_height,
+				venc->params.out_width,
+				venc->params.out_height);
+		break;
+	case 4:
+		num = scnprintf(str, size, "(%d, %d)  %d x %d\n",
+				venc->params.crop.left,
+				venc->params.crop.top,
+				venc->params.crop.width,
+				venc->params.crop.height);
+		break;
+	case 5:
+		num = scnprintf(str, size,
+				"enable = 0x%x, input = %d, encode = %d, ready = %d, stopped = %d\n",
+				venc->enable,
+				venc->frame_count, venc->encode_count,
+				venc->ready_count,
+				venc->stopped);
+		break;
+	case 6:
+		num = scnprintf(str, size, "gop = %d\n", venc->params.gop_length);
+		break;
+	case 7:
+		num = scnprintf(str, size, "bframes = %d\n", venc->params.bframes);
+		break;
+	case 8:
+		num = scnprintf(str, size, "rc: %s, mode = %d, bitrate = %d(%d), qp = %d\n",
+				venc->params.rc_enable ? "enable" : "disable",
+				venc->params.rc_mode,
+				venc->params.bitrate,
+				venc->params.bitrate_max,
+				venc->params.i_frame_qp);
+		break;
+	case 9:
+		num = scnprintf(str, size, "sar: enable = %d, idc = %d, %d x %d\n",
+				venc->params.sar.enable,
+				venc->params.sar.idc,
+				venc->params.sar.width,
+				venc->params.sar.height);
+
+		break;
+	case 10:
+		num = scnprintf(str, size,
+				"colorspace: primaries = %d, transfer = %d, matrix = %d, full_range = %d\n",
+				venc->params.color.primaries,
+				venc->params.color.transfer,
+				venc->params.color.matrix,
+				venc->params.color.full_range);
+		break;
+	case 11:
+		num = scnprintf(str, size, "skipped: count = %d, bytes = %d\n",
+				venc->skipped_count, venc->skipped_bytes);
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops venc_inst_ops = {
+	.ctrl_init = venc_ctrl_init,
+	.check_ready = venc_check_ready,
+	.input_done = venc_input_done,
+	.get_one_frame = venc_frame_encoded,
+	.buf_done = venc_buf_done,
+	.stop_done = venc_stop_done,
+	.event_notify = venc_event_notify,
+	.release = venc_release,
+	.cleanup = venc_cleanup,
+	.start = venc_start_session,
+	.mem_request = venc_request_mem_resource,
+	.stop = venc_stop_session,
+	.process_output = venc_process_output,
+	.process_capture = venc_process_capture,
+	.on_queue_empty = venc_on_queue_empty,
+	.get_debug_info = venc_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void venc_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct venc_t *venc;
+	struct v4l2_format f;
+	struct v4l2_streamparm parm;
+
+	venc = inst->priv;
+	venc->params.qp_min = 1;
+	venc->params.qp_max = 51;
+	venc->params.qp_min_i = 1;
+	venc->params.qp_max_i = 51;
+	venc->params.bitrate_min = BITRATE_MIN;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	venc_s_fmt(file, &inst->fh, &f);
+
+	memset(&parm, 0, sizeof(parm));
+	parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	parm.parm.capture.timeperframe.numerator = 1;
+	parm.parm.capture.timeperframe.denominator = 30;
+	venc_s_parm(file, &inst->fh, &parm);
+}
+
+static int venc_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct venc_t *venc;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	venc = vzalloc(sizeof(*venc));
+	if (!venc) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &venc_inst_ops;
+	inst->formats = venc_formats;
+	inst->type = VPU_CORE_TYPE_ENC;
+	inst->priv = venc;
+	INIT_LIST_HEAD(&venc->frames);
+	init_waitqueue_head(&venc->wq);
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret)
+		return ret;
+
+	venc_init(file);
+
+	return 0;
+}
+
+static const struct v4l2_file_operations venc_fops = {
+	.owner = THIS_MODULE,
+	.open = venc_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = v4l2_m2m_fop_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+const struct v4l2_ioctl_ops *venc_get_ioctl_ops(void)
+{
+	return &venc_ioctl_ops;
+}
+
+const struct v4l2_file_operations *venc_get_fops(void)
+{
+	return &venc_fops;
+}
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:27 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:27 +0800
Subject: [PATCH v15.1 08/13] media: amphion: add v4l2 m2m vpu decoder stateful
 driver
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <3fede03e82d0be898f92414c57fba290a8102994.1643165765.git.ming.qian@nxp.com>

This consists of video decoder implementation plus decoder controls.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vdec.c | 1695 +++++++++++++++++++++++++
 1 file changed, 1695 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vdec.c

diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c
new file mode 100644
index 000000000000..50b3a02d0c34
--- /dev/null
+++ b/drivers/media/platform/amphion/vdec.c
@@ -0,0 +1,1695 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <media/videobuf2-vmalloc.h>
+#include "vpu.h"
+#include "vpu_defs.h"
+#include "vpu_core.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_rpc.h"
+
+#define VDEC_FRAME_DEPTH		256
+#define VDEC_MIN_BUFFER_CAP		8
+
+struct vdec_fs_info {
+	char name[8];
+	u32 type;
+	u32 max_count;
+	u32 req_count;
+	u32 count;
+	u32 index;
+	u32 size;
+	struct vpu_buffer buffer[32];
+	u32 tag;
+};
+
+struct vdec_t {
+	u32 seq_hdr_found;
+	struct vpu_buffer udata;
+	struct vpu_decode_params params;
+	struct vpu_dec_codec_info codec_info;
+	enum vpu_codec_state state;
+
+	struct vpu_vb2_buffer *slots[VB2_MAX_FRAME];
+	u32 req_frame_count;
+	struct vdec_fs_info mbi;
+	struct vdec_fs_info dcp;
+	u32 seq_tag;
+
+	bool reset_codec;
+	bool fixed_fmt;
+	u32 decoded_frame_count;
+	u32 display_frame_count;
+	u32 sequence;
+	u32 eos_received;
+	bool is_source_changed;
+	u32 source_change;
+	u32 drain;
+	u32 ts_pre_count;
+	u32 frame_depth;
+	s64 ts_start;
+	s64 ts_input;
+	s64 timestamp;
+};
+
+static const struct vpu_format vdec_formats[] = {
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128,
+		.num_planes = 2,
+		.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE,
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H264_MVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_HEVC,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG2,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_MPEG4,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_XVID,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_VP8,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{
+		.pixfmt = V4L2_PIX_FMT_H263,
+		.num_planes = 1,
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.flags = V4L2_FMT_FLAG_DYN_RESOLUTION
+	},
+	{0, 0, 0, 0},
+};
+
+static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
+	.g_volatile_ctrl = vpu_helper_g_volatile_ctrl,
+};
+
+static int vdec_ctrl_init(struct vpu_inst *inst)
+{
+	struct v4l2_ctrl *ctrl;
+	int ret;
+
+	ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 20);
+	if (ret)
+		return ret;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
+				 V4L2_CID_MIN_BUFFERS_FOR_OUTPUT, 1, 32, 1, 2);
+	if (ctrl)
+		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+	ret = v4l2_ctrl_handler_setup(&inst->ctrl_handler);
+	if (ret) {
+		dev_err(inst->dev, "[%d] setup ctrls fail, ret = %d\n", inst->id, ret);
+		v4l2_ctrl_handler_free(&inst->ctrl_handler);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void vdec_set_last_buffer_dequeued(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (vdec->eos_received) {
+		if (!vpu_set_last_buffer_dequeued(inst))
+			vdec->eos_received--;
+	}
+}
+
+static void vdec_handle_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_queue *q;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return;
+
+	if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return;
+	if (!vdec->source_change)
+		return;
+
+	q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (!list_empty(&q->done_list))
+		return;
+
+	vdec->source_change--;
+	vpu_notify_source_change(inst);
+}
+
+static int vdec_update_state(struct vpu_inst *inst, enum vpu_codec_state state, u32 force)
+{
+	struct vdec_t *vdec = inst->priv;
+	enum vpu_codec_state pre_state = inst->state;
+
+	if (state == VPU_CODEC_STATE_SEEK) {
+		if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec->state = inst->state;
+		else
+			vdec->state = VPU_CODEC_STATE_ACTIVE;
+	}
+	if (inst->state != VPU_CODEC_STATE_SEEK || force)
+		inst->state = state;
+	else if (state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE;
+
+	if (inst->state != pre_state)
+		vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state);
+
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		vdec_handle_resolution_change(inst);
+
+	return 0;
+}
+
+static int vdec_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+	strscpy(cap->driver, "amphion-vpu", sizeof(cap->driver));
+	strscpy(cap->card, "amphion vpu decoder", sizeof(cap->card));
+	strscpy(cap->bus_info, "platform: amphion-vpu", sizeof(cap->bus_info));
+
+	return 0;
+}
+
+static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int ret = -EINVAL;
+
+	vpu_inst_lock(inst);
+	if (!V4L2_TYPE_IS_OUTPUT(f->type) && vdec->fixed_fmt) {
+		if (f->index == 0) {
+			f->pixelformat = inst->cap_format.pixfmt;
+			f->flags = inst->cap_format.flags;
+			ret = 0;
+		}
+	} else {
+		fmt = vpu_helper_enum_format(inst, f->type, f->index);
+		memset(f->reserved, 0, sizeof(f->reserved));
+		if (!fmt)
+			goto exit;
+
+		f->pixelformat = fmt->pixfmt;
+		f->flags = fmt->flags;
+		ret = 0;
+	}
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vpu_format *cur_fmt;
+	int i;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+
+	pixmp->pixelformat = cur_fmt->pixfmt;
+	pixmp->num_planes = cur_fmt->num_planes;
+	pixmp->width = cur_fmt->width;
+	pixmp->height = cur_fmt->height;
+	pixmp->field = cur_fmt->field;
+	pixmp->flags = cur_fmt->flags;
+	for (i = 0; i < pixmp->num_planes; i++) {
+		pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+		pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+	return 0;
+}
+
+static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_try_fmt_common(inst, f);
+
+	vpu_inst_lock(inst);
+	if (vdec->fixed_fmt) {
+		f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+		f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+		f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+		f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+	} else {
+		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+		f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+		f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+		f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_s_fmt_common(struct vpu_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	const struct vpu_format *fmt;
+	struct vpu_format *cur_fmt;
+	struct vb2_queue *q;
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	q = v4l2_m2m_get_vq(inst->fh.m2m_ctx, f->type);
+	if (!q)
+		return -EINVAL;
+	if (vb2_is_busy(q))
+		return -EBUSY;
+
+	fmt = vpu_try_fmt_common(inst, f);
+	if (!fmt)
+		return -EINVAL;
+
+	cur_fmt = vpu_get_format(inst, f->type);
+	if (V4L2_TYPE_IS_OUTPUT(f->type) && inst->state != VPU_CODEC_STATE_DEINIT) {
+		if (cur_fmt->pixfmt != fmt->pixfmt) {
+			vdec->reset_codec = true;
+			vdec->fixed_fmt = false;
+		}
+	}
+	cur_fmt->pixfmt = fmt->pixfmt;
+	if (V4L2_TYPE_IS_OUTPUT(f->type) || !vdec->fixed_fmt) {
+		cur_fmt->num_planes = fmt->num_planes;
+		cur_fmt->flags = fmt->flags;
+		cur_fmt->width = pixmp->width;
+		cur_fmt->height = pixmp->height;
+		for (i = 0; i < fmt->num_planes; i++) {
+			cur_fmt->sizeimage[i] = pixmp->plane_fmt[i].sizeimage;
+			cur_fmt->bytesperline[i] = pixmp->plane_fmt[i].bytesperline;
+		}
+		if (pixmp->field != V4L2_FIELD_ANY)
+			cur_fmt->field = pixmp->field;
+	} else {
+		pixmp->num_planes = cur_fmt->num_planes;
+		pixmp->width = cur_fmt->width;
+		pixmp->height = cur_fmt->height;
+		for (i = 0; i < pixmp->num_planes; i++) {
+			pixmp->plane_fmt[i].bytesperline = cur_fmt->bytesperline[i];
+			pixmp->plane_fmt[i].sizeimage = cur_fmt->sizeimage[i];
+		}
+		pixmp->field = cur_fmt->field;
+	}
+
+	if (!vdec->fixed_fmt) {
+		if (V4L2_TYPE_IS_OUTPUT(f->type)) {
+			vdec->params.codec_format = cur_fmt->pixfmt;
+			vdec->codec_info.color_primaries = f->fmt.pix_mp.colorspace;
+			vdec->codec_info.transfer_chars = f->fmt.pix_mp.xfer_func;
+			vdec->codec_info.matrix_coeffs = f->fmt.pix_mp.ycbcr_enc;
+			vdec->codec_info.full_range = f->fmt.pix_mp.quantization;
+		} else {
+			vdec->params.output_format = cur_fmt->pixfmt;
+			inst->crop.left = 0;
+			inst->crop.top = 0;
+			inst->crop.width = cur_fmt->width;
+			inst->crop.height = cur_fmt->height;
+		}
+	}
+
+	vpu_trace(inst->dev, "[%d] %c%c%c%c %dx%d\n", inst->id,
+		  f->fmt.pix_mp.pixelformat,
+		  f->fmt.pix_mp.pixelformat >> 8,
+		  f->fmt.pix_mp.pixelformat >> 16,
+		  f->fmt.pix_mp.pixelformat >> 24,
+		  f->fmt.pix_mp.width,
+		  f->fmt.pix_mp.height);
+
+	return 0;
+}
+
+static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	vpu_inst_lock(inst);
+	ret = vdec_s_fmt_common(inst, f);
+	if (ret)
+		goto exit;
+
+	if (V4L2_TYPE_IS_OUTPUT(f->type) && !vdec->fixed_fmt) {
+		struct v4l2_format fc;
+
+		memset(&fc, 0, sizeof(fc));
+		fc.type = inst->cap_format.type;
+		fc.fmt.pix_mp.pixelformat = inst->cap_format.pixfmt;
+		fc.fmt.pix_mp.width = pixmp->width;
+		fc.fmt.pix_mp.height = pixmp->height;
+		vdec_s_fmt_common(inst, &fc);
+	}
+
+	f->fmt.pix_mp.colorspace = vdec->codec_info.color_primaries;
+	f->fmt.pix_mp.xfer_func = vdec->codec_info.transfer_chars;
+	f->fmt.pix_mp.ycbcr_enc = vdec->codec_info.matrix_coeffs;
+	f->fmt.pix_mp.quantization = vdec->codec_info.full_range;
+
+exit:
+	vpu_inst_unlock(inst);
+	return ret;
+}
+
+static int vdec_g_selection(struct file *file, void *fh, struct v4l2_selection *s)
+{
+	struct vpu_inst *inst = to_inst(file);
+
+	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_COMPOSE:
+	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+	case V4L2_SEL_TGT_COMPOSE_PADDED:
+		s->r = inst->crop;
+		break;
+	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		s->r.left = 0;
+		s->r.top = 0;
+		s->r.width = inst->cap_format.width;
+		s->r.height = inst->cap_format.height;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vdec_drain(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+
+	if (!vdec->drain)
+		return 0;
+
+	if (v4l2_m2m_num_src_bufs_ready(inst->fh.m2m_ctx))
+		return 0;
+
+	if (!vdec->params.frame_count) {
+		vpu_set_last_buffer_dequeued(inst);
+		return 0;
+	}
+
+	vpu_iface_add_scode(inst, SCODE_PADDING_EOS);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+	vdec->drain = 0;
+	vpu_trace(inst->dev, "[%d] frame_count = %d\n", inst->id, vdec->params.frame_count);
+
+	return 0;
+}
+
+static int vdec_cmd_start(struct vpu_inst *inst)
+{
+	switch (inst->state) {
+	case VPU_CODEC_STATE_STARTED:
+	case VPU_CODEC_STATE_DRAIN:
+	case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE:
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+		break;
+	default:
+		break;
+	}
+	vpu_process_capture_buffer(inst);
+	return 0;
+}
+
+static int vdec_cmd_stop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT) {
+		vpu_set_last_buffer_dequeued(inst);
+	} else {
+		vdec->drain = 1;
+		vdec_drain(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd)
+{
+	struct vpu_inst *inst = to_inst(file);
+	int ret;
+
+	ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd);
+	if (ret)
+		return ret;
+
+	vpu_inst_lock(inst);
+	switch (cmd->cmd) {
+	case V4L2_DEC_CMD_START:
+		vdec_cmd_start(inst);
+		break;
+	case V4L2_DEC_CMD_STOP:
+		vdec_cmd_stop(inst);
+		break;
+	default:
+		break;
+	}
+	vpu_inst_unlock(inst);
+
+	return 0;
+}
+
+static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		return v4l2_event_subscribe(fh, sub, 0, NULL);
+	case V4L2_EVENT_SOURCE_CHANGE:
+		return v4l2_src_change_event_subscribe(fh, sub);
+	case V4L2_EVENT_CTRL:
+		return v4l2_ctrl_subscribe_event(fh, sub);
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct v4l2_ioctl_ops vdec_ioctl_ops = {
+	.vidioc_querycap               = vdec_querycap,
+	.vidioc_enum_fmt_vid_cap       = vdec_enum_fmt,
+	.vidioc_enum_fmt_vid_out       = vdec_enum_fmt,
+	.vidioc_g_fmt_vid_cap_mplane   = vdec_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane   = vdec_g_fmt,
+	.vidioc_try_fmt_vid_cap_mplane = vdec_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane = vdec_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane   = vdec_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane   = vdec_s_fmt,
+	.vidioc_g_selection            = vdec_g_selection,
+	.vidioc_try_decoder_cmd        = v4l2_m2m_ioctl_try_decoder_cmd,
+	.vidioc_decoder_cmd            = vdec_decoder_cmd,
+	.vidioc_subscribe_event        = vdec_subscribe_event,
+	.vidioc_unsubscribe_event      = v4l2_event_unsubscribe,
+	.vidioc_reqbufs                = v4l2_m2m_ioctl_reqbufs,
+	.vidioc_create_bufs	       = v4l2_m2m_ioctl_create_bufs,
+	.vidioc_prepare_buf	       = v4l2_m2m_ioctl_prepare_buf,
+	.vidioc_querybuf               = v4l2_m2m_ioctl_querybuf,
+	.vidioc_qbuf                   = v4l2_m2m_ioctl_qbuf,
+	.vidioc_expbuf                 = v4l2_m2m_ioctl_expbuf,
+	.vidioc_dqbuf                  = v4l2_m2m_ioctl_dqbuf,
+	.vidioc_streamon               = v4l2_m2m_ioctl_streamon,
+	.vidioc_streamoff              = v4l2_m2m_ioctl_streamoff,
+};
+
+static bool vdec_check_ready(struct vpu_inst *inst, unsigned int type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->ts_pre_count >= vdec->frame_depth)
+			return false;
+		return true;
+	}
+
+	if (vdec->req_frame_count)
+		return true;
+
+	return false;
+}
+
+static int vdec_frame_decoded(struct vpu_inst *inst, void *arg)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_dec_pic_info *info = arg;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int ret = 0;
+
+	if (!info || info->id >= ARRAY_SIZE(vdec->slots))
+		return -EINVAL;
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[info->id];
+	if (!vpu_buf) {
+		dev_err(inst->dev, "[%d] decoded invalid frame[%d]\n", inst->id, info->id);
+		ret = -EINVAL;
+		goto exit;
+	}
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED)
+		dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED);
+	vdec->decoded_frame_count++;
+	if (vdec->ts_pre_count >= info->consumed_count)
+		vdec->ts_pre_count -= info->consumed_count;
+	else
+		vdec->ts_pre_count = 0;
+exit:
+	vpu_inst_unlock(inst);
+
+	return ret;
+}
+
+static struct vpu_vb2_buffer *vdec_find_buffer(struct vpu_inst *inst, u32 luma)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+		if (luma == vdec->slots[i]->luma)
+			return vdec->slots[i];
+	}
+
+	return NULL;
+}
+
+static void vdec_buf_done(struct vpu_inst *inst, struct vpu_frame_info *frame)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	u32 sequence;
+
+	if (!frame)
+		return;
+
+	vpu_inst_lock(inst);
+	sequence = vdec->sequence++;
+	vpu_buf = vdec_find_buffer(inst, frame->luma);
+	vpu_inst_unlock(inst);
+	if (!vpu_buf) {
+		dev_err(inst->dev, "[%d] can't find buffer, id = %d, addr = 0x%x\n",
+			inst->id, frame->id, frame->luma);
+		return;
+	}
+	if (frame->skipped) {
+		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
+		return;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vbuf->vb2_buf.index != frame->id)
+		dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n",
+			inst->id, vbuf->vb2_buf.index, frame->id);
+
+	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED)
+		dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 0, inst->cap_format.sizeimage[0]);
+	vb2_set_plane_payload(&vbuf->vb2_buf, 1, inst->cap_format.sizeimage[1]);
+	vbuf->vb2_buf.timestamp = frame->timestamp;
+	vbuf->field = inst->cap_format.field;
+	vbuf->sequence = sequence;
+	dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, frame->timestamp);
+
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+	vpu_inst_lock(inst);
+	vdec->timestamp = frame->timestamp;
+	vdec->display_frame_count++;
+	vpu_inst_unlock(inst);
+	dev_dbg(inst->dev, "[%d] decoded : %d, display : %d, sequence : %d\n",
+		inst->id, vdec->decoded_frame_count, vdec->display_frame_count, vdec->sequence);
+}
+
+static void vdec_stop_done(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 0);
+	vdec->seq_hdr_found = 0;
+	vdec->req_frame_count = 0;
+	vdec->reset_codec = false;
+	vdec->fixed_fmt = false;
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+	vdec->sequence = 0;
+	vdec->eos_received = 0;
+	vdec->is_source_changed = false;
+	vdec->source_change = 0;
+	vpu_inst_unlock(inst);
+}
+
+static bool vdec_check_source_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return false;
+	if (!vb2_is_streaming(v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx)))
+		return true;
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	if (inst->cap_format.pixfmt != vdec->codec_info.pixfmt)
+		return true;
+	if (inst->cap_format.width != vdec->codec_info.decoded_width)
+		return true;
+	if (inst->cap_format.height != vdec->codec_info.decoded_height)
+		return true;
+	if (vpu_get_num_buffers(inst, inst->cap_format.type) < inst->min_buffer_cap)
+		return true;
+	if (inst->crop.left != vdec->codec_info.offset_x)
+		return true;
+	if (inst->crop.top != vdec->codec_info.offset_y)
+		return true;
+	if (inst->crop.width != vdec->codec_info.width)
+		return true;
+	if (inst->crop.height != vdec->codec_info.height)
+		return true;
+	if (fmt && inst->cap_format.num_planes != fmt->num_planes)
+		return true;
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		if (inst->cap_format.bytesperline[i] != vdec->codec_info.bytesperline[i])
+			return true;
+		if (inst->cap_format.sizeimage[i] != vdec->codec_info.sizeimage[i])
+			return true;
+	}
+
+	return false;
+}
+
+static void vdec_init_fmt(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	const struct vpu_format *fmt;
+	int i;
+
+	fmt = vpu_helper_find_format(inst, inst->cap_format.type, vdec->codec_info.pixfmt);
+	inst->out_format.width = vdec->codec_info.width;
+	inst->out_format.height = vdec->codec_info.height;
+	inst->cap_format.width = vdec->codec_info.decoded_width;
+	inst->cap_format.height = vdec->codec_info.decoded_height;
+	inst->cap_format.pixfmt = vdec->codec_info.pixfmt;
+	if (fmt) {
+		inst->cap_format.num_planes = fmt->num_planes;
+		inst->cap_format.flags = fmt->flags;
+	}
+	for (i = 0; i < inst->cap_format.num_planes; i++) {
+		inst->cap_format.bytesperline[i] = vdec->codec_info.bytesperline[i];
+		inst->cap_format.sizeimage[i] = vdec->codec_info.sizeimage[i];
+	}
+	if (vdec->codec_info.progressive)
+		inst->cap_format.field = V4L2_FIELD_NONE;
+	else
+		inst->cap_format.field = V4L2_FIELD_SEQ_BT;
+	if (vdec->codec_info.color_primaries == V4L2_COLORSPACE_DEFAULT)
+		vdec->codec_info.color_primaries = V4L2_COLORSPACE_REC709;
+	if (vdec->codec_info.transfer_chars == V4L2_XFER_FUNC_DEFAULT)
+		vdec->codec_info.transfer_chars = V4L2_XFER_FUNC_709;
+	if (vdec->codec_info.matrix_coeffs == V4L2_YCBCR_ENC_DEFAULT)
+		vdec->codec_info.matrix_coeffs = V4L2_YCBCR_ENC_709;
+	if (vdec->codec_info.full_range == V4L2_QUANTIZATION_DEFAULT)
+		vdec->codec_info.full_range = V4L2_QUANTIZATION_LIM_RANGE;
+}
+
+static void vdec_init_crop(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	inst->crop.left = vdec->codec_info.offset_x;
+	inst->crop.top = vdec->codec_info.offset_y;
+	inst->crop.width = vdec->codec_info.width;
+	inst->crop.height = vdec->codec_info.height;
+}
+
+static void vdec_init_mbi(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->mbi.size = vdec->codec_info.mbi_size;
+	vdec->mbi.max_count = ARRAY_SIZE(vdec->mbi.buffer);
+	scnprintf(vdec->mbi.name, sizeof(vdec->mbi.name), "mbi");
+	vdec->mbi.type = MEM_RES_MBI;
+	vdec->mbi.tag = vdec->seq_tag;
+}
+
+static void vdec_init_dcp(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec->dcp.size = vdec->codec_info.dcp_size;
+	vdec->dcp.max_count = ARRAY_SIZE(vdec->dcp.buffer);
+	scnprintf(vdec->dcp.name, sizeof(vdec->dcp.name), "dcp");
+	vdec->dcp.type = MEM_RES_DCP;
+	vdec->dcp.tag = vdec->seq_tag;
+}
+
+static void vdec_request_one_fs(struct vdec_fs_info *fs)
+{
+	fs->req_count++;
+	if (fs->req_count > fs->max_count)
+		fs->req_count = fs->max_count;
+}
+
+static int vdec_alloc_fs_buffer(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_buffer *buffer;
+
+	if (!inst || !fs || !fs->size)
+		return -EINVAL;
+
+	if (fs->count >= fs->req_count)
+		return -EINVAL;
+
+	buffer = &fs->buffer[fs->count];
+	if (buffer->virt && buffer->length >= fs->size)
+		return 0;
+
+	vpu_free_dma(buffer);
+	buffer->length = fs->size;
+	return vpu_alloc_dma(inst->core, buffer);
+}
+
+static void vdec_alloc_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	int ret;
+
+	while (fs->count < fs->req_count) {
+		ret = vdec_alloc_fs_buffer(inst, fs);
+		if (ret)
+			break;
+		fs->count++;
+	}
+}
+
+static void vdec_clear_fs(struct vdec_fs_info *fs)
+{
+	u32 i;
+
+	if (!fs)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(fs->buffer); i++)
+		vpu_free_dma(&fs->buffer[i]);
+	memset(fs, 0, sizeof(*fs));
+}
+
+static int vdec_response_fs(struct vpu_inst *inst, struct vdec_fs_info *fs)
+{
+	struct vpu_fs_info info;
+	int ret;
+
+	if (fs->index >= fs->count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.id = fs->index;
+	info.type = fs->type;
+	info.tag = fs->tag;
+	info.luma_addr = fs->buffer[fs->index].phys;
+	info.luma_size = fs->buffer[fs->index].length;
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	fs->index++;
+	return 0;
+}
+
+static int vdec_response_frame_abnormal(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_fs_info info;
+
+	if (!vdec->req_frame_count)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag + 0xf0;
+	vpu_session_alloc_fs(inst, &info);
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static int vdec_response_frame(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vpu_fs_info info;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_ACTIVE)
+		return -EINVAL;
+
+	if (!vdec->req_frame_count)
+		return -EINVAL;
+
+	if (!vbuf)
+		return -EINVAL;
+
+	if (vdec->slots[vbuf->vb2_buf.index]) {
+		dev_err(inst->dev, "[%d] repeat alloc fs %d\n",
+			inst->id, vbuf->vb2_buf.index);
+		return -EINVAL;
+	}
+
+	dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n",
+		inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag);
+	vpu_buf = to_vpu_vb2_buffer(vbuf);
+
+	memset(&info, 0, sizeof(info));
+	info.id = vbuf->vb2_buf.index;
+	info.type = MEM_RES_FRAME;
+	info.tag = vdec->seq_tag;
+	info.luma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 0);
+	info.luma_size = inst->cap_format.sizeimage[0];
+	info.chroma_addr = vpu_get_vb_phy_addr(&vbuf->vb2_buf, 1);
+	info.chromau_size = inst->cap_format.sizeimage[1];
+	info.bytesperline = inst->cap_format.bytesperline[0];
+	ret = vpu_session_alloc_fs(inst, &info);
+	if (ret)
+		return ret;
+
+	vpu_buf->tag = info.tag;
+	vpu_buf->luma = info.luma_addr;
+	vpu_buf->chroma_u = info.chromau_size;
+	vpu_buf->chroma_v = 0;
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_INUSE);
+	vdec->slots[info.id] = vpu_buf;
+	vdec->req_frame_count--;
+
+	return 0;
+}
+
+static void vdec_response_fs_request(struct vpu_inst *inst, bool force)
+{
+	struct vdec_t *vdec = inst->priv;
+	int i;
+	int ret;
+
+	if (force) {
+		for (i = vdec->req_frame_count; i > 0; i--)
+			vdec_response_frame_abnormal(inst);
+		return;
+	}
+
+	for (i = vdec->req_frame_count; i > 0; i--) {
+		ret = vpu_process_capture_buffer(inst);
+		if (ret)
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+
+	for (i = vdec->mbi.index; i < vdec->mbi.count; i++) {
+		if (vdec_response_fs(inst, &vdec->mbi))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+	for (i = vdec->dcp.index; i < vdec->dcp.count; i++) {
+		if (vdec_response_fs(inst, &vdec->dcp))
+			break;
+		if (vdec->eos_received)
+			break;
+	}
+}
+
+static void vdec_response_fs_release(struct vpu_inst *inst, u32 id, u32 tag)
+{
+	struct vpu_fs_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.id = id;
+	info.tag = tag;
+	vpu_session_release_fs(inst, &info);
+}
+
+static void vdec_recycle_buffer(struct vpu_inst *inst, struct vb2_v4l2_buffer *vbuf)
+{
+	if (!inst || !vbuf || !inst->fh.m2m_ctx)
+		return;
+
+	if (vbuf->vb2_buf.state != VB2_BUF_STATE_ACTIVE)
+		return;
+	if (vpu_find_buf_by_idx(inst, vbuf->vb2_buf.type, vbuf->vb2_buf.index))
+		return;
+	v4l2_m2m_buf_queue(inst->fh.m2m_ctx, vbuf);
+}
+
+static void vdec_clear_slots(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(vdec->slots); i++) {
+		if (!vdec->slots[i])
+			continue;
+
+		vpu_buf = vdec->slots[i];
+		vbuf = &vpu_buf->m2m_buf.vb;
+
+		vdec_recycle_buffer(inst, vbuf);
+		vdec->slots[i]->state = VPU_BUF_STATE_IDLE;
+		vdec->slots[i] = NULL;
+	}
+}
+
+static void vdec_event_seq_hdr(struct vpu_inst *inst, struct vpu_dec_codec_info *hdr)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_inst_lock(inst);
+	memcpy(&vdec->codec_info, hdr, sizeof(vdec->codec_info));
+
+	vpu_trace(inst->dev, "[%d] %d x %d, crop : (%d, %d) %d x %d, %d, %d\n",
+		  inst->id,
+		  vdec->codec_info.decoded_width,
+		  vdec->codec_info.decoded_height,
+		  vdec->codec_info.offset_x,
+		  vdec->codec_info.offset_y,
+		  vdec->codec_info.width,
+		  vdec->codec_info.height,
+		  hdr->num_ref_frms,
+		  hdr->num_dpb_frms);
+	inst->min_buffer_cap = hdr->num_ref_frms + hdr->num_dpb_frms;
+	vdec->is_source_changed = vdec_check_source_change(inst);
+	vdec_init_fmt(inst);
+	vdec_init_crop(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (!vdec->seq_hdr_found) {
+		vdec->seq_tag = vdec->codec_info.tag;
+		if (vdec->is_source_changed) {
+			vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+			vpu_notify_source_change(inst);
+			vdec->is_source_changed = false;
+		}
+	}
+	if (vdec->seq_tag != vdec->codec_info.tag) {
+		vdec_response_fs_request(inst, true);
+		vpu_trace(inst->dev, "[%d] seq tag change: %d -> %d\n",
+			  inst->id, vdec->seq_tag, vdec->codec_info.tag);
+	}
+	vdec->seq_hdr_found++;
+	vdec->fixed_fmt = true;
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_resolution_change(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	vpu_inst_lock(inst);
+	vdec->seq_tag = vdec->codec_info.tag;
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	vdec_clear_slots(inst);
+	vdec_init_mbi(inst);
+	vdec_init_dcp(inst);
+	if (vdec->is_source_changed) {
+		vdec_update_state(inst, VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE, 0);
+		vdec->source_change++;
+		vdec_handle_resolution_change(inst);
+		vdec->is_source_changed = false;
+	}
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_req_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (!fs)
+		return;
+
+	vpu_inst_lock(inst);
+
+	switch (fs->type) {
+	case MEM_RES_FRAME:
+		vdec->req_frame_count++;
+		break;
+	case MEM_RES_MBI:
+		vdec_request_one_fs(&vdec->mbi);
+		break;
+	case MEM_RES_DCP:
+		vdec_request_one_fs(&vdec->dcp);
+		break;
+	default:
+		break;
+	}
+
+	vdec_alloc_fs(inst, &vdec->mbi);
+	vdec_alloc_fs(inst, &vdec->dcp);
+
+	vdec_response_fs_request(inst, false);
+
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_evnet_rel_fs(struct vpu_inst *inst, struct vpu_fs_info *fs)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_vb2_buffer *vpu_buf;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!fs || fs->id >= ARRAY_SIZE(vdec->slots))
+		return;
+	if (fs->type != MEM_RES_FRAME)
+		return;
+
+	if (fs->id >= vpu_get_num_buffers(inst, inst->cap_format.type)) {
+		dev_err(inst->dev, "[%d] invalid fs(%d) to release\n", inst->id, fs->id);
+		return;
+	}
+
+	vpu_inst_lock(inst);
+	vpu_buf = vdec->slots[fs->id];
+	vdec->slots[fs->id] = NULL;
+
+	if (!vpu_buf) {
+		dev_dbg(inst->dev, "[%d] fs[%d] has bee released\n", inst->id, fs->id);
+		goto exit;
+	}
+
+	vbuf = &vpu_buf->m2m_buf.vb;
+	if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_DECODED) {
+		dev_dbg(inst->dev, "[%d] frame skip\n", inst->id);
+		vdec->sequence++;
+	}
+
+	vdec_response_fs_release(inst, fs->id, vpu_buf->tag);
+	if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_READY)
+		vdec_recycle_buffer(inst, vbuf);
+
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	vpu_process_capture_buffer(inst);
+
+exit:
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_eos(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
+		  inst->id,
+		  vdec->params.frame_count,
+		  vdec->decoded_frame_count,
+		  vdec->display_frame_count,
+		  vdec->sequence);
+	vpu_inst_lock(inst);
+	vdec->eos_received++;
+	vdec->fixed_fmt = false;
+	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+	vdec_update_state(inst, VPU_CODEC_STATE_DRAIN, 0);
+	vdec_set_last_buffer_dequeued(inst);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_event_notify(struct vpu_inst *inst, u32 event, void *data)
+{
+	switch (event) {
+	case VPU_MSG_ID_SEQ_HDR_FOUND:
+		vdec_event_seq_hdr(inst, data);
+		break;
+	case VPU_MSG_ID_RES_CHANGE:
+		vdec_event_resolution_change(inst);
+		break;
+	case VPU_MSG_ID_FRAME_REQ:
+		vdec_event_req_fs(inst, data);
+		break;
+	case VPU_MSG_ID_FRAME_RELEASE:
+		vdec_evnet_rel_fs(inst, data);
+		break;
+	case VPU_MSG_ID_PIC_EOS:
+		vdec_event_eos(inst);
+		break;
+	default:
+		break;
+	}
+}
+
+static int vdec_process_output(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_rpc_buffer_desc desc;
+	s64 timestamp;
+	u32 free_space;
+	int ret;
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	dev_dbg(inst->dev, "[%d] dec output [%d] %d : %ld\n",
+		inst->id, vbuf->sequence, vb->index, vb2_get_plane_payload(vb, 0));
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return -EINVAL;
+	if (vdec->reset_codec)
+		return -EINVAL;
+
+	if (inst->state == VPU_CODEC_STATE_STARTED)
+		vdec_update_state(inst, VPU_CODEC_STATE_ACTIVE, 0);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (ret)
+		return ret;
+
+	free_space = vpu_helper_get_free_space(inst);
+	if (free_space < vb2_get_plane_payload(vb, 0) + 0x40000)
+		return -ENOMEM;
+
+	timestamp = vb->timestamp;
+	if (timestamp >= 0 && vdec->ts_start < 0)
+		vdec->ts_start = timestamp;
+	if (vdec->ts_input < timestamp)
+		vdec->ts_input = timestamp;
+
+	ret = vpu_iface_input_frame(inst, vb);
+	if (ret < 0)
+		return -ENOMEM;
+
+	dev_dbg(inst->dev, "[%d][INPUT  TS]%32lld\n", inst->id, vb->timestamp);
+	vdec->ts_pre_count++;
+	vdec->params.frame_count++;
+
+	v4l2_m2m_src_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	vpu_set_buffer_state(vbuf, VPU_BUF_STATE_IDLE);
+	v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE);
+
+	if (vdec->drain)
+		vdec_drain(inst);
+
+	return 0;
+}
+
+static int vdec_process_capture(struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	int ret;
+
+	if (!inst || !inst->fh.m2m_ctx)
+		return -EINVAL;
+	if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+		return -EINVAL;
+	if (vdec->reset_codec)
+		return -EINVAL;
+
+	ret = vdec_response_frame(inst, vbuf);
+	if (ret)
+		return ret;
+	v4l2_m2m_dst_buf_remove_by_buf(inst->fh.m2m_ctx, vbuf);
+	return 0;
+}
+
+static void vdec_on_queue_empty(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (V4L2_TYPE_IS_OUTPUT(type))
+		return;
+
+	vdec_handle_resolution_change(inst);
+	if (vdec->eos_received)
+		vdec_set_last_buffer_dequeued(inst);
+}
+
+static void vdec_abort(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	struct vpu_rpc_buffer_desc desc;
+	int ret;
+
+	vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state);
+	vpu_iface_add_scode(inst, SCODE_PADDING_ABORT);
+	vdec->params.end_flag = 1;
+	vpu_iface_set_decode_params(inst, &vdec->params, 1);
+
+	vpu_session_abort(inst);
+
+	ret = vpu_iface_get_stream_buffer_desc(inst, &desc);
+	if (!ret)
+		vpu_iface_update_stream_buffer(inst, desc.rptr, 1);
+
+	vpu_session_rst_buf(inst);
+	vpu_trace(inst->dev, "[%d] input : %d, decoded : %d, display : %d, sequence : %d\n",
+		  inst->id,
+		  vdec->params.frame_count,
+		  vdec->decoded_frame_count,
+		  vdec->display_frame_count,
+		  vdec->sequence);
+	vdec->params.end_flag = 0;
+	vdec->drain = 0;
+	vdec->ts_pre_count = 0;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+	vdec->params.frame_count = 0;
+	vdec->decoded_frame_count = 0;
+	vdec->display_frame_count = 0;
+	vdec->sequence = 0;
+}
+
+static void vdec_stop(struct vpu_inst *inst, bool free)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	vdec_clear_slots(inst);
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		vpu_session_stop(inst);
+	vdec_clear_fs(&vdec->mbi);
+	vdec_clear_fs(&vdec->dcp);
+	if (free) {
+		vpu_free_dma(&vdec->udata);
+		vpu_free_dma(&inst->stream_buffer);
+	}
+	vdec_update_state(inst, VPU_CODEC_STATE_DEINIT, 1);
+	vdec->reset_codec = false;
+}
+
+static void vdec_release(struct vpu_inst *inst)
+{
+	if (inst->id != VPU_INST_NULL_ID)
+		vpu_trace(inst->dev, "[%d]\n", inst->id);
+	vpu_inst_lock(inst);
+	vdec_stop(inst, true);
+	vpu_inst_unlock(inst);
+}
+
+static void vdec_cleanup(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec;
+
+	if (!inst)
+		return;
+
+	vdec = inst->priv;
+	if (vdec)
+		vfree(vdec);
+	inst->priv = NULL;
+	vfree(inst);
+}
+
+static void vdec_init_params(struct vdec_t *vdec)
+{
+	vdec->params.frame_count = 0;
+	vdec->params.end_flag = 0;
+}
+
+static int vdec_start(struct vpu_inst *inst)
+{
+	struct vdec_t *vdec = inst->priv;
+	int stream_buffer_size;
+	int ret;
+
+	if (inst->state != VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	vpu_trace(inst->dev, "[%d]\n", inst->id);
+	if (!vdec->udata.virt) {
+		vdec->udata.length = 0x1000;
+		ret = vpu_alloc_dma(inst->core, &vdec->udata);
+		if (ret) {
+			dev_err(inst->dev, "[%d] alloc udata fail\n", inst->id);
+			goto error;
+		}
+	}
+
+	if (!inst->stream_buffer.virt) {
+		stream_buffer_size = vpu_iface_get_stream_buffer_size(inst->core);
+		if (stream_buffer_size > 0) {
+			inst->stream_buffer.length = stream_buffer_size;
+			ret = vpu_alloc_dma(inst->core, &inst->stream_buffer);
+			if (ret) {
+				dev_err(inst->dev, "[%d] alloc stream buffer fail\n", inst->id);
+				goto error;
+			}
+			inst->use_stream_buffer = true;
+		}
+	}
+
+	if (inst->use_stream_buffer)
+		vpu_iface_config_stream_buffer(inst, &inst->stream_buffer);
+	vpu_iface_init_instance(inst);
+	vdec->params.udata.base = vdec->udata.phys;
+	vdec->params.udata.size = vdec->udata.length;
+	ret = vpu_iface_set_decode_params(inst, &vdec->params, 0);
+	if (ret) {
+		dev_err(inst->dev, "[%d] set decode params fail\n", inst->id);
+		goto error;
+	}
+
+	vdec_init_params(vdec);
+	ret = vpu_session_start(inst);
+	if (ret) {
+		dev_err(inst->dev, "[%d] start fail\n", inst->id);
+		goto error;
+	}
+
+	vdec_update_state(inst, VPU_CODEC_STATE_STARTED, 0);
+
+	return 0;
+error:
+	vpu_free_dma(&vdec->udata);
+	vpu_free_dma(&inst->stream_buffer);
+	return ret;
+}
+
+static int vdec_start_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+	int ret = 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (vdec->reset_codec)
+			vdec_stop(inst, false);
+		if (inst->state == VPU_CODEC_STATE_DEINIT) {
+			ret = vdec_start(inst);
+			if (ret)
+				return ret;
+		}
+	}
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		if (inst->state == VPU_CODEC_STATE_SEEK)
+			vdec_update_state(inst, vdec->state, 1);
+		vdec->eos_received = 0;
+		vpu_process_output_buffer(inst);
+	} else {
+		vdec_cmd_start(inst);
+	}
+	if (inst->state == VPU_CODEC_STATE_ACTIVE)
+		vdec_response_fs_request(inst, false);
+
+	return ret;
+}
+
+static int vdec_stop_session(struct vpu_inst *inst, u32 type)
+{
+	struct vdec_t *vdec = inst->priv;
+
+	if (inst->state == VPU_CODEC_STATE_DEINIT)
+		return 0;
+
+	if (V4L2_TYPE_IS_OUTPUT(type)) {
+		vdec_update_state(inst, VPU_CODEC_STATE_SEEK, 0);
+		vdec->drain = 0;
+	} else {
+		if (inst->state != VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE)
+			vdec_abort(inst);
+
+		vdec->eos_received = 0;
+		vdec_clear_slots(inst);
+	}
+
+	return 0;
+}
+
+static int vdec_get_debug_info(struct vpu_inst *inst, char *str, u32 size, u32 i)
+{
+	struct vdec_t *vdec = inst->priv;
+	int num = -1;
+
+	switch (i) {
+	case 0:
+		num = scnprintf(str, size,
+				"req_frame_count = %d\ninterlaced = %d\n",
+				vdec->req_frame_count,
+				vdec->codec_info.progressive ? 0 : 1);
+		break;
+	case 1:
+		num = scnprintf(str, size,
+				"mbi: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->mbi.size,
+				vdec->mbi.req_count,
+				vdec->mbi.count,
+				vdec->mbi.index);
+		break;
+	case 2:
+		num = scnprintf(str, size,
+				"dcp: size = 0x%x request = %d, alloc = %d, response = %d\n",
+				vdec->dcp.size,
+				vdec->dcp.req_count,
+				vdec->dcp.count,
+				vdec->dcp.index);
+		break;
+	case 3:
+		num = scnprintf(str, size, "input_frame_count = %d\n", vdec->params.frame_count);
+		break;
+	case 4:
+		num = scnprintf(str, size, "decoded_frame_count = %d\n", vdec->decoded_frame_count);
+		break;
+	case 5:
+		num = scnprintf(str, size, "display_frame_count = %d\n", vdec->display_frame_count);
+		break;
+	case 6:
+		num = scnprintf(str, size, "sequence = %d\n", vdec->sequence);
+		break;
+	case 7:
+		num = scnprintf(str, size, "drain = %d, eos = %d, source_change = %d\n",
+				vdec->drain, vdec->eos_received, vdec->source_change);
+		break;
+	case 8:
+		num = scnprintf(str, size, "ts_pre_count = %d, frame_depth = %d\n",
+				vdec->ts_pre_count, vdec->frame_depth);
+		break;
+	case 9:
+		num = scnprintf(str, size, "fps = %d/%d\n",
+				vdec->codec_info.frame_rate.numerator,
+				vdec->codec_info.frame_rate.denominator);
+		break;
+	case 10:
+	{
+		s64 timestamp = vdec->timestamp;
+		s64 ts_start = vdec->ts_start;
+		s64 ts_input = vdec->ts_input;
+
+		num = scnprintf(str, size, "timestamp = %9lld.%09lld(%9lld.%09lld, %9lld.%09lld)\n",
+				timestamp / NSEC_PER_SEC,
+				timestamp % NSEC_PER_SEC,
+				ts_start / NSEC_PER_SEC,
+				ts_start % NSEC_PER_SEC,
+				ts_input / NSEC_PER_SEC,
+				ts_input % NSEC_PER_SEC);
+	}
+		break;
+	default:
+		break;
+	}
+
+	return num;
+}
+
+static struct vpu_inst_ops vdec_inst_ops = {
+	.ctrl_init = vdec_ctrl_init,
+	.check_ready = vdec_check_ready,
+	.buf_done = vdec_buf_done,
+	.get_one_frame = vdec_frame_decoded,
+	.stop_done = vdec_stop_done,
+	.event_notify = vdec_event_notify,
+	.release = vdec_release,
+	.cleanup = vdec_cleanup,
+	.start = vdec_start_session,
+	.stop = vdec_stop_session,
+	.process_output = vdec_process_output,
+	.process_capture = vdec_process_capture,
+	.on_queue_empty = vdec_on_queue_empty,
+	.get_debug_info = vdec_get_debug_info,
+	.wait_prepare = vpu_inst_unlock,
+	.wait_finish = vpu_inst_lock,
+};
+
+static void vdec_init(struct file *file)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vdec_t *vdec;
+	struct v4l2_format f;
+
+	vdec = inst->priv;
+	vdec->frame_depth = VDEC_FRAME_DEPTH;
+	vdec->timestamp = VPU_INVALID_TIMESTAMP;
+	vdec->ts_start = VPU_INVALID_TIMESTAMP;
+	vdec->ts_input = VPU_INVALID_TIMESTAMP;
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+
+	memset(&f, 0, sizeof(f));
+	f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+	f.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M_8L128;
+	f.fmt.pix_mp.width = 1280;
+	f.fmt.pix_mp.height = 720;
+	f.fmt.pix_mp.field = V4L2_FIELD_NONE;
+	vdec_s_fmt(file, &inst->fh, &f);
+}
+
+static int vdec_open(struct file *file)
+{
+	struct vpu_inst *inst;
+	struct vdec_t *vdec;
+	int ret;
+
+	inst = vzalloc(sizeof(*inst));
+	if (!inst)
+		return -ENOMEM;
+
+	vdec = vzalloc(sizeof(*vdec));
+	if (!vdec) {
+		vfree(inst);
+		return -ENOMEM;
+	}
+
+	inst->ops = &vdec_inst_ops;
+	inst->formats = vdec_formats;
+	inst->type = VPU_CORE_TYPE_DEC;
+	inst->priv = vdec;
+
+	ret = vpu_v4l2_open(file, inst);
+	if (ret)
+		return ret;
+
+	vdec->fixed_fmt = false;
+	inst->min_buffer_cap = VDEC_MIN_BUFFER_CAP;
+	vdec_init(file);
+
+	return 0;
+}
+
+static __poll_t vdec_poll(struct file *file, poll_table *wait)
+{
+	struct vpu_inst *inst = to_inst(file);
+	struct vb2_queue *src_q, *dst_q;
+	__poll_t ret;
+
+	ret = v4l2_m2m_fop_poll(file, wait);
+	src_q = v4l2_m2m_get_src_vq(inst->fh.m2m_ctx);
+	dst_q = v4l2_m2m_get_dst_vq(inst->fh.m2m_ctx);
+	if (vb2_is_streaming(src_q) && !vb2_is_streaming(dst_q))
+		ret &= (~EPOLLERR);
+	if (!src_q->error && !dst_q->error &&
+	    (vb2_is_streaming(src_q) && list_empty(&src_q->queued_list)) &&
+	    (vb2_is_streaming(dst_q) && list_empty(&dst_q->queued_list)))
+		ret &= (~EPOLLERR);
+
+	return ret;
+}
+
+static const struct v4l2_file_operations vdec_fops = {
+	.owner = THIS_MODULE,
+	.open = vdec_open,
+	.release = vpu_v4l2_close,
+	.unlocked_ioctl = video_ioctl2,
+	.poll = vdec_poll,
+	.mmap = v4l2_m2m_fop_mmap,
+};
+
+const struct v4l2_ioctl_ops *vdec_get_ioctl_ops(void)
+{
+	return &vdec_ioctl_ops;
+}
+
+const struct v4l2_file_operations *vdec_get_fops(void)
+{
+	return &vdec_fops;
+}
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:28 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:28 +0800
Subject: [PATCH v15.1 09/13] media: amphion: implement windsor encoder rpc
 interface
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <f1118c33cfc1d410b681dbd6360e0cb72f201a80.1643165765.git.ming.qian@nxp.com>

This part implements the windsor encoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Reported-by: kernel test robot <lkp at intel.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_windsor.c | 1169 ++++++++++++++++++
 drivers/media/platform/amphion/vpu_windsor.h |   37 +
 2 files changed, 1206 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.c
 create mode 100644 drivers/media/platform/amphion/vpu_windsor.h

diff --git a/drivers/media/platform/amphion/vpu_windsor.c b/drivers/media/platform/amphion/vpu_windsor.c
new file mode 100644
index 000000000000..e8852dd8535b
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_windsor.c
@@ -0,0 +1,1169 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_cmds.h"
+#include "vpu_v4l2.h"
+#include "vpu_imx8q.h"
+#include "vpu_windsor.h"
+
+#define CMD_SIZE				2560
+#define MSG_SIZE				25600
+#define WINDSOR_USER_DATA_WORDS			16
+#define WINDSOR_MAX_SRC_FRAMES			0x6
+#define WINDSOR_MAX_REF_FRAMES			0x3
+#define WINDSOR_BITRATE_UNIT			1024
+#define WINDSOR_H264_EXTENDED_SAR		255
+
+enum {
+	GTB_ENC_CMD_NOOP        = 0x0,
+	GTB_ENC_CMD_STREAM_START,
+	GTB_ENC_CMD_FRAME_ENCODE,
+	GTB_ENC_CMD_FRAME_SKIP,
+	GTB_ENC_CMD_STREAM_STOP,
+	GTB_ENC_CMD_PARAMETER_UPD,
+	GTB_ENC_CMD_TERMINATE,
+	GTB_ENC_CMD_SNAPSHOT,
+	GTB_ENC_CMD_ROLL_SNAPSHOT,
+	GTB_ENC_CMD_LOCK_SCHEDULER,
+	GTB_ENC_CMD_UNLOCK_SCHEDULER,
+	GTB_ENC_CMD_CONFIGURE_CODEC,
+	GTB_ENC_CMD_DEAD_MARK,
+	GTB_ENC_CMD_FIRM_RESET,
+	GTB_ENC_CMD_FW_STATUS,
+	GTB_ENC_CMD_RESERVED
+};
+
+enum {
+	VID_API_EVENT_UNDEFINED = 0x0,
+	VID_API_ENC_EVENT_RESET_DONE = 0x1,
+	VID_API_ENC_EVENT_START_DONE,
+	VID_API_ENC_EVENT_STOP_DONE,
+	VID_API_ENC_EVENT_TERMINATE_DONE,
+	VID_API_ENC_EVENT_FRAME_INPUT_DONE,
+	VID_API_ENC_EVENT_FRAME_DONE,
+	VID_API_ENC_EVENT_FRAME_RELEASE,
+	VID_API_ENC_EVENT_PARA_UPD_DONE,
+	VID_API_ENC_EVENT_MEM_REQUEST,
+	VID_API_ENC_EVENT_FIRMWARE_XCPT,
+	VID_API_ENC_EVENT_RESERVED
+};
+
+enum {
+	MEDIAIP_ENC_PIC_TYPE_B_FRAME = 0,
+	MEDIAIP_ENC_PIC_TYPE_P_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_I_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_IDR_FRAME,
+	MEDIAIP_ENC_PIC_TYPE_BI_FRAME
+};
+
+struct windsor_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_rpc_buffer_desc cmd_buffer_desc;
+	struct vpu_rpc_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 mvd_fw_offset;
+	u32 max_streams;
+	u32 ctrl_iface[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_config;
+	u32 api_version;
+	struct vpu_rpc_buffer_desc log_buffer_desc;
+};
+
+struct windsor_ctrl_iface {
+	u32 enc_yuv_buffer_desc;
+	u32 enc_stream_buffer_desc;
+	u32 enc_expert_mode_param;
+	u32 enc_param;
+	u32 enc_mem_pool;
+	u32 enc_encoding_status;
+	u32 enc_dsa_status;
+};
+
+struct vpu_enc_yuv_desc {
+	u32 frame_id;
+	u32 luma_base;
+	u32 chroma_base;
+	u32 param_idx;
+	u32 key_frame;
+};
+
+struct vpu_enc_calib_params {
+	u32 use_ame;
+
+	u32 cme_mvx_max;
+	u32 cme_mvy_max;
+	u32 ame_prefresh_y0;
+	u32 ame_prefresh_y1;
+	u32 fme_min_sad;
+	u32 cme_min_sad;
+
+	u32 fme_pred_int_weight;
+	u32 fme_pred_hp_weight;
+	u32 fme_pred_qp_weight;
+	u32 fme_cost_weight;
+	u32 fme_act_thold;
+	u32 fme_sad_thold;
+	u32 fme_zero_sad_thold;
+
+	u32 fme_lrg_mvx_lmt;
+	u32 fme_lrg_mvy_lmt;
+	u32 fme_force_mode;
+	u32 fme_force4mvcost;
+	u32 fme_force2mvcost;
+
+	u32 h264_inter_thrd;
+
+	u32 i16x16_mode_cost;
+	u32 i4x4_mode_lambda;
+	u32 i8x8_mode_lambda;
+
+	u32 inter_mod_mult;
+	u32 inter_sel_mult;
+	u32 inter_bid_cost;
+	u32 inter_bwd_cost;
+	u32 inter_4mv_cost;
+	s32 one_mv_i16_cost;
+	s32 one_mv_i4x4_cost;
+	s32 one_mv_i8x8_cost;
+	s32 two_mv_i16_cost;
+	s32 two_mv_i4x4_cost;
+	s32 two_mv_i8x8_cost;
+	s32 four_mv_i16_cost;
+	s32 four_mv_i4x4_cost;
+	s32 four_mv_i8x8_cost;
+
+	u32 intra_pred_enab;
+	u32 intra_chr_pred;
+	u32 intra16_pred;
+	u32 intra4x4_pred;
+	u32 intra8x8_pred;
+
+	u32 cb_base;
+	u32 cb_size;
+	u32 cb_head_room;
+
+	u32 mem_page_width;
+	u32 mem_page_height;
+	u32 mem_total_size;
+	u32 mem_chunk_phys_addr;
+	u32 mem_chunk_virt_addr;
+	u32 mem_chunk_size;
+	u32 mem_y_stride;
+	u32 mem_uv_stride;
+
+	u32 split_wr_enab;
+	u32 split_wr_req_size;
+	u32 split_rd_enab;
+	u32 split_rd_req_size;
+};
+
+struct vpu_enc_config_params {
+	u32 param_change;
+	u32 start_frame;
+	u32 end_frame;
+	u32 userdata_enable;
+	u32 userdata_id[4];
+	u32 userdata_message[WINDSOR_USER_DATA_WORDS];
+	u32 userdata_length;
+	u32 h264_profile_idc;
+	u32 h264_level_idc;
+	u32 h264_au_delimiter;
+	u32 h264_seq_end_code;
+	u32 h264_recovery_points;
+	u32 h264_vui_parameters;
+	u32 h264_aspect_ratio_present;
+	u32 h264_aspect_ratio_sar_width;
+	u32 h264_aspect_ratio_sar_height;
+	u32 h264_overscan_present;
+	u32 h264_video_type_present;
+	u32 h264_video_format;
+	u32 h264_video_full_range;
+	u32 h264_video_colour_descriptor;
+	u32 h264_video_colour_primaries;
+	u32 h264_video_transfer_char;
+	u32 h264_video_matrix_coeff;
+	u32 h264_chroma_loc_info_present;
+	u32 h264_chroma_loc_type_top;
+	u32 h264_chroma_loc_type_bot;
+	u32 h264_timing_info_present;
+	u32 h264_buffering_period_present;
+	u32 h264_low_delay_hrd_flag;
+	u32 aspect_ratio;
+	u32 test_mode;                  // Automated firmware test mode
+	u32 dsa_test_mode;              // Automated test mode for the DSA.
+	u32 fme_test_mode;              // Automated test mode for the fme
+	u32 cbr_row_mode;               //0: FW mode; 1: HW mode
+	u32 windsor_mode;               //0: normal mode; 1: intra only mode; 2: intra+0MV mode
+	u32 encode_mode;                // H264, VC1, MPEG2, DIVX
+	u32 frame_width;                // display width
+	u32 frame_height;               // display height
+	u32 enc_frame_width;            // encoding width, should be 16-pix align
+	u32 enc_frame_height;           // encoding height, should be 16-pix aligned
+	u32 frame_rate_num;
+	u32 frame_rate_den;
+	u32 vi_field_source;
+	u32 vi_frame_width;
+	u32 vi_frame_height;
+	u32 crop_frame_width;
+	u32 crop_frame_height;
+	u32 crop_x_start_posn;
+	u32 crop_y_start_posn;
+	u32 mode422;
+	u32 mode_yuy2;
+	u32 dsa_luma_en;
+	u32 dsa_chroma_en;
+	u32 dsa_ext_hfilt_en;
+	u32 dsa_di_en;
+	u32 dsa_di_top_ref;
+	u32 dsa_vertf_disable;
+	u32 dsa_disable_pwb;
+	u32 dsa_hor_phase;
+	u32 dsa_ver_phase;
+	u32 dsa_iac_enable;
+	u32 iac_sc_threshold;
+	u32 iac_vm_threshold;
+	u32 iac_skip_mode;
+	u32 iac_grp_width;
+	u32 iac_grp_height;
+	u32 rate_control_mode;
+	u32 rate_control_resolution;
+	u32 buffer_size;
+	u32 buffer_level_init;
+	u32 buffer_I_bit_budget;
+	u32 top_field_first;
+	u32 intra_lum_qoffset;
+	u32 intra_chr_qoffset;
+	u32 inter_lum_qoffset;
+	u32 inter_chr_qoffset;
+	u32 use_def_scaling_mtx;
+	u32 inter_8x8_enab;
+	u32 inter_4x4_enab;
+	u32 fme_enable_qpel;
+	u32 fme_enable_hpel;
+	u32 fme_nozeromv;
+	u32 fme_predmv_en;
+	u32 fme_pred_2mv4mv;
+	u32 fme_smallsadthresh;
+	u32 ame_en_lmvc;
+	u32 ame_x_mult;
+	u32 cme_enable_4mv;
+	u32 cme_enable_1mv;
+	u32 hme_enable_16x8mv;
+	u32 hme_enable_8x16mv;
+	u32 cme_mv_weight;
+	u32 cme_mv_cost;
+	u32 ame_mult_mv;
+	u32 ame_shift_mv;
+	u32 hme_forceto1mv_en;
+	u32 hme_2mv_cost;
+	u32 hme_pred_mode;
+	u32 hme_sc_rnge;
+	u32 hme_sw_rnge;
+	u32 output_format;
+	u32 timestamp_enab;
+	u32 initial_pts_enab;
+	u32 initial_pts;
+};
+
+struct vpu_enc_static_params {
+	u32 param_change;
+	u32 gop_length;
+	u32 rate_control_bitrate;
+	u32 rate_control_bitrate_min;
+	u32 rate_control_bitrate_max;
+	u32 rate_control_content_models;
+	u32 rate_control_iframe_maxsize;
+	u32 rate_control_qp_init;
+	u32 rate_control_islice_qp;
+	u32 rate_control_pslice_qp;
+	u32 rate_control_bslice_qp;
+	u32 adaptive_quantization;
+	u32 aq_variance;
+	u32 cost_optimization;
+	u32 fdlp_mode;
+	u32 enable_isegbframes;
+	u32 enable_adaptive_keyratio;
+	u32 keyratio_imin;
+	u32 keyratio_imax;
+	u32 keyratio_pmin;
+	u32 keyratio_pmax;
+	u32 keyratio_bmin;
+	u32 keyratio_bmax;
+	s32 keyratio_istep;
+	s32 keyratio_pstep;
+	s32 keyratio_bstep;
+	u32 enable_paff;
+	u32 enable_b_frame_ref;
+	u32 enable_adaptive_gop;
+	u32 enable_closed_gop;
+	u32 open_gop_refresh_freq;
+	u32 enable_adaptive_sc;
+	u32 enable_fade_detection;
+	s32 fade_detection_threshold;
+	u32 enable_repeat_b;
+	u32 enable_low_delay_b;
+};
+
+struct vpu_enc_dynamic_params {
+	u32 param_change;
+	u32 rows_per_slice;
+	u32 mbaff_enable;
+	u32 dbf_enable;
+	u32 field_source;
+	u32 gop_b_length;
+	u32 mb_group_size;
+	u32 cbr_rows_per_group;
+	u32 skip_enable;
+	u32 pts_bits_0_to_31;
+	u32 pts_bit_32;
+	u32 rm_expsv_cff;
+	u32 const_ipred;
+	s32 chr_qp_offset;
+	u32 intra_mb_qp_offset;
+	u32 h264_cabac_init_method;
+	u32 h264_cabac_init_idc;
+	u32 h264_cabac_enable;
+	s32 alpha_c0_offset_div2;
+	s32 beta_offset_div2;
+	u32 intra_prefresh_y0;
+	u32 intra_prefresh_y1;
+	u32 dbg_dump_rec_src;
+};
+
+struct vpu_enc_expert_mode_param {
+	struct vpu_enc_calib_params calib_param;
+	struct vpu_enc_config_params config_param;
+	struct vpu_enc_static_params static_param;
+	struct vpu_enc_dynamic_params dynamic_param;
+};
+
+enum MEDIAIP_ENC_FMT {
+	MEDIAIP_ENC_FMT_H264 = 0,
+	MEDIAIP_ENC_FMT_VC1,
+	MEDIAIP_ENC_FMT_MPEG2,
+	MEDIAIP_ENC_FMT_MPEG4SP,
+	MEDIAIP_ENC_FMT_H263,
+	MEDIAIP_ENC_FMT_MPEG1,
+	MEDIAIP_ENC_FMT_SHORT_HEADER,
+	MEDIAIP_ENC_FMT_NULL
+};
+
+enum MEDIAIP_ENC_PROFILE {
+	MEDIAIP_ENC_PROF_MPEG2_SP = 0,
+	MEDIAIP_ENC_PROF_MPEG2_MP,
+	MEDIAIP_ENC_PROF_MPEG2_HP,
+	MEDIAIP_ENC_PROF_H264_BP,
+	MEDIAIP_ENC_PROF_H264_MP,
+	MEDIAIP_ENC_PROF_H264_HP,
+	MEDIAIP_ENC_PROF_MPEG4_SP,
+	MEDIAIP_ENC_PROF_MPEG4_ASP,
+	MEDIAIP_ENC_PROF_VC1_SP,
+	MEDIAIP_ENC_PROF_VC1_MP,
+	MEDIAIP_ENC_PROF_VC1_AP
+};
+
+enum MEDIAIP_ENC_BITRATE_MODE {
+	MEDIAIP_ENC_BITRATE_MODE_VBR          = 0x00000001,
+	MEDIAIP_ENC_BITRATE_MODE_CBR          = 0x00000002,
+	MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP  = 0x00000004
+};
+
+struct vpu_enc_memory_resource {
+	u32 phys;
+	u32 virt;
+	u32 size;
+};
+
+struct vpu_enc_param {
+	enum MEDIAIP_ENC_FMT codec_mode;
+	enum MEDIAIP_ENC_PROFILE profile;
+	u32 level;
+
+	struct vpu_enc_memory_resource enc_mem_desc;
+
+	u32 frame_rate;
+	u32 src_stride;
+	u32 src_width;
+	u32 src_height;
+	u32 src_offset_x;
+	u32 src_offset_y;
+	u32 src_crop_width;
+	u32 src_crop_height;
+	u32 out_width;
+	u32 out_height;
+	u32 iframe_interval;
+	u32 bframes;
+	u32 low_latency_mode;
+
+	enum MEDIAIP_ENC_BITRATE_MODE  bitrate_mode;
+	u32 target_bitrate;
+	u32 max_bitrate;
+	u32 min_bitrate;
+	u32 init_slice_qp;
+};
+
+struct vpu_enc_mem_pool {
+	struct vpu_enc_memory_resource enc_frames[WINDSOR_MAX_SRC_FRAMES];
+	struct vpu_enc_memory_resource ref_frames[WINDSOR_MAX_REF_FRAMES];
+	struct vpu_enc_memory_resource act_frame;
+};
+
+struct vpu_enc_encoding_status {
+	u32   frame_id;
+	u32   error_flag;   //Error type
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[12];
+
+};
+
+struct vpu_enc_dsa_status {
+	u32   frame_id;
+	u32   dsa_cyle;
+	u32   mb_y;
+	u32   mb_x;
+	u32   reserved[4];
+};
+
+struct vpu_enc_ctrl {
+	struct vpu_enc_yuv_desc *yuv_desc;
+	struct vpu_rpc_buffer_desc *stream_desc;
+	struct vpu_enc_expert_mode_param *expert;
+	struct vpu_enc_param *param;
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_encoding_status *status;
+	struct vpu_enc_dsa_status *dsa;
+};
+
+struct vpu_enc_host_ctrls {
+	struct vpu_enc_ctrl ctrls[VID_API_NUM_STREAMS];
+};
+
+struct windsor_pic_info {
+	u32 frame_id;
+	u32 pic_encod_done;
+	u32 pic_type;
+	u32 skipped_frame;
+	u32 error_flag;
+	u32 psnr;
+	u32 flush_done;
+	u32 mb_y;
+	u32 mb_x;
+	u32 frame_size;
+	u32 frame_enc_ttl_cycles;
+	u32 frame_enc_ttl_frm_cycles;
+	u32 frame_enc_ttl_slc_cycles;
+	u32 frame_enc_ttl_enc_cycles;
+	u32 frame_enc_ttl_hme_cycles;
+	u32 frame_enc_ttl_dsa_cycles;
+	u32 frame_enc_fw_cycles;
+	u32 frame_crc;
+	u32 num_interrupts_1;
+	u32 num_interrupts_2;
+	u32 poc;
+	u32 ref_info;
+	u32 pic_num;
+	u32 pic_activity;
+	u32 scene_change;
+	u32 mb_stats;
+	u32 enc_cache_count0;
+	u32 enc_cache_count1;
+	u32 mtl_wr_strb_cnt;
+	u32 mtl_rd_strb_cnt;
+	u32 str_buff_wptr;
+	u32 diagnosticEvents;
+	u32 proc_iacc_tot_rd_cnt;
+	u32 proc_dacc_tot_rd_cnt;
+	u32 proc_dacc_tot_wr_cnt;
+	u32 proc_dacc_reg_rd_cnt;
+	u32 proc_dacc_reg_wr_cnt;
+	u32 proc_dacc_rng_rd_cnt;
+	u32 proc_dacc_rng_wr_cnt;
+	s32 tv_s;
+	u32 tv_ns;
+};
+
+u32 vpu_windsor_get_data_size(void)
+{
+	return sizeof(struct vpu_enc_host_ctrls);
+}
+
+static struct vpu_enc_yuv_desc *get_yuv_desc(struct vpu_shared_addr *shared,
+					     u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].yuv_desc;
+}
+
+static struct vpu_enc_mem_pool *get_mem_pool(struct vpu_shared_addr *shared,
+					     u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].pool;
+}
+
+static struct vpu_rpc_buffer_desc *get_stream_buf_desc(struct vpu_shared_addr *shared,
+						       u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].stream_desc;
+}
+
+static struct vpu_enc_expert_mode_param *get_expert_param(struct vpu_shared_addr *shared,
+							  u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].expert;
+}
+
+static struct vpu_enc_param *get_enc_param(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct vpu_enc_host_ctrls *hcs = shared->priv;
+
+	return hcs->ctrls[instance].param;
+}
+
+static u32 get_ptr(u32 ptr)
+{
+	return (ptr | 0x80000000);
+}
+
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			  struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	struct windsor_iface *iface;
+	struct windsor_ctrl_iface *ctrl;
+	struct vpu_enc_host_ctrls *hcs;
+	unsigned int i;
+
+	if (rpc->phys < boot_addr)
+		return;
+
+	base_phy_addr = rpc->phys - boot_addr;
+	iface = rpc->virt;
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+	hcs = shared->priv;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct windsor_iface);
+	phy_addr = base_phy_addr + offset;
+	shared->cmd_desc = &iface->cmd_buffer_desc;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.start =
+	iface->cmd_buffer_desc.rptr =
+	iface->cmd_buffer_desc.wptr = phy_addr;
+	iface->cmd_buffer_desc.end = iface->cmd_buffer_desc.start + CMD_SIZE;
+
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+	shared->msg_desc = &iface->msg_buffer_desc;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.start =
+	iface->msg_buffer_desc.wptr =
+	iface->msg_buffer_desc.rptr = phy_addr;
+	iface->msg_buffer_desc.end = iface->msg_buffer_desc.start + MSG_SIZE;
+
+	offset += MSG_SIZE;
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		iface->ctrl_iface[i] = base_phy_addr + offset;
+		offset += sizeof(struct windsor_ctrl_iface);
+	}
+	for (i = 0; i < ARRAY_SIZE(iface->ctrl_iface); i++) {
+		ctrl = rpc->virt + (iface->ctrl_iface[i] - base_phy_addr);
+
+		ctrl->enc_yuv_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].yuv_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_yuv_desc);
+
+		ctrl->enc_stream_buffer_desc = base_phy_addr + offset;
+		hcs->ctrls[i].stream_desc = rpc->virt + offset;
+		offset += sizeof(struct vpu_rpc_buffer_desc);
+
+		ctrl->enc_expert_mode_param = base_phy_addr + offset;
+		hcs->ctrls[i].expert = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_expert_mode_param);
+
+		ctrl->enc_param = base_phy_addr + offset;
+		hcs->ctrls[i].param = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_param);
+
+		ctrl->enc_mem_pool = base_phy_addr + offset;
+		hcs->ctrls[i].pool = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_mem_pool);
+
+		ctrl->enc_encoding_status = base_phy_addr + offset;
+		hcs->ctrls[i].status = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_encoding_status);
+
+		ctrl->enc_dsa_status = base_phy_addr + offset;
+		hcs->ctrls[i].dsa = rpc->virt + offset;
+		offset += sizeof(struct vpu_enc_dsa_status);
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	iface->log_buffer_desc.start =
+	iface->log_buffer_desc.wptr =
+	iface->log_buffer_desc.rptr = log->phys - shared->boot_addr;
+	iface->log_buffer_desc.end = iface->log_buffer_desc.start + log->length;
+}
+
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct windsor_iface *iface = shared->iface;
+	struct vpu_rpc_system_config *config = &iface->system_config;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+}
+
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0x300000;
+}
+
+static struct vpu_pair windsor_cmds[] = {
+	{VPU_CMD_ID_CONFIGURE_CODEC, GTB_ENC_CMD_CONFIGURE_CODEC},
+	{VPU_CMD_ID_START, GTB_ENC_CMD_STREAM_START},
+	{VPU_CMD_ID_STOP, GTB_ENC_CMD_STREAM_STOP},
+	{VPU_CMD_ID_FRAME_ENCODE, GTB_ENC_CMD_FRAME_ENCODE},
+	{VPU_CMD_ID_SNAPSHOT, GTB_ENC_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, GTB_ENC_CMD_FIRM_RESET},
+	{VPU_CMD_ID_UPDATE_PARAMETER, GTB_ENC_CMD_PARAMETER_UPD},
+	{VPU_CMD_ID_DEBUG, GTB_ENC_CMD_FW_STATUS}
+};
+
+static struct vpu_pair windsor_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_ENC_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_ENC_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_ENC_EVENT_STOP_DONE},
+	{VPU_MSG_ID_FRAME_INPUT_DONE, VID_API_ENC_EVENT_FRAME_INPUT_DONE},
+	{VPU_MSG_ID_ENC_DONE, VID_API_ENC_EVENT_FRAME_DONE},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_ENC_EVENT_FRAME_RELEASE},
+	{VPU_MSG_ID_MEM_REQUEST, VID_API_ENC_EVENT_MEM_REQUEST},
+	{VPU_MSG_ID_PARAM_UPD_DONE, VID_API_ENC_EVENT_PARA_UPD_DONE},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_ENC_EVENT_FIRMWARE_XCPT},
+};
+
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+	s64 timestamp;
+
+	ret = vpu_find_dst_by_src(windsor_cmds, ARRAY_SIZE(windsor_cmds), id);
+	if (ret < 0)
+		return ret;
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+	if (id == VPU_CMD_ID_FRAME_ENCODE) {
+		pkt->hdr.num = 2;
+		timestamp = *(s64 *)data;
+		if (timestamp < 0) {
+			pkt->data[0] = (u32)-1;
+			pkt->data[1] = 0;
+		} else {
+			pkt->data[0] = timestamp / NSEC_PER_SEC;
+			pkt->data[1] = timestamp % NSEC_PER_SEC;
+		}
+	}
+
+	return 0;
+}
+
+int vpu_windsor_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(windsor_msgs, ARRAY_SIZE(windsor_msgs), id);
+}
+
+static void vpu_windsor_unpack_pic_info(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_enc_pic_info *info = data;
+	struct windsor_pic_info *windsor = (struct windsor_pic_info *)pkt->data;
+
+	info->frame_id = windsor->frame_id;
+	switch (windsor->pic_type) {
+	case MEDIAIP_ENC_PIC_TYPE_I_FRAME:
+	case MEDIAIP_ENC_PIC_TYPE_IDR_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_KEYFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_P_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_PFRAME;
+		break;
+	case MEDIAIP_ENC_PIC_TYPE_B_FRAME:
+		info->pic_type = V4L2_BUF_FLAG_BFRAME;
+		break;
+	default:
+		break;
+	}
+	info->skipped_frame = windsor->skipped_frame;
+	info->error_flag = windsor->error_flag;
+	info->psnr = windsor->psnr;
+	info->frame_size = windsor->frame_size;
+	info->wptr = get_ptr(windsor->str_buff_wptr);
+	info->crc = windsor->frame_crc;
+	info->timestamp = MAKE_TIMESTAMP(windsor->tv_s, windsor->tv_ns);
+}
+
+static void vpu_windsor_unpack_mem_req(struct vpu_rpc_event *pkt, void *data)
+{
+	struct vpu_pkt_mem_req_data *req_data = data;
+
+	req_data->enc_frame_size = pkt->data[0];
+	req_data->enc_frame_num = pkt->data[1];
+	req_data->ref_frame_size = pkt->data[2];
+	req_data->ref_frame_num = pkt->data[3];
+	req_data->act_buf_size = pkt->data[4];
+	req_data->act_buf_num = 1;
+}
+
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_ENC_EVENT_FRAME_DONE:
+		vpu_windsor_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_MEM_REQUEST:
+		vpu_windsor_unpack_mem_req(pkt, data);
+		break;
+	case VID_API_ENC_EVENT_FRAME_RELEASE:
+		*(u32 *)data = pkt->data[0];
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_fill_yuv_frame(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vb2_buffer *vb)
+{
+	struct vpu_enc_yuv_desc *desc;
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (instance >= VID_API_NUM_STREAMS)
+		return -EINVAL;
+
+	desc = get_yuv_desc(shared, instance);
+
+	vbuf = to_vb2_v4l2_buffer(vb);
+	desc->frame_id = vbuf->sequence;
+	if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME)
+		desc->key_frame = 1;
+	else
+		desc->key_frame = 0;
+	desc->luma_base = vpu_get_vb_phy_addr(vb, 0);
+	desc->chroma_base = vpu_get_vb_phy_addr(vb, 1);
+
+	return 0;
+}
+
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			    struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	vpu_windsor_fill_yuv_frame(shared, inst->id, vb);
+	return vpu_session_encode_frame(inst, vb->timestamp);
+}
+
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+				       u32 instance,
+				       u32 type,
+				       u32 index,
+				       struct vpu_buffer *buf)
+{
+	struct vpu_enc_mem_pool *pool;
+	struct vpu_enc_memory_resource *res;
+
+	if (instance >= VID_API_NUM_STREAMS)
+		return -EINVAL;
+
+	pool = get_mem_pool(shared, instance);
+
+	switch (type) {
+	case MEM_RES_ENC:
+		res = &pool->enc_frames[index];
+		break;
+	case MEM_RES_REF:
+		res = &pool->ref_frames[index];
+		break;
+	case MEM_RES_ACT:
+		res = &pool->act_frame;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	res->phys = buf->phys;
+	res->virt = buf->phys - shared->boot_addr;
+	res->size = buf->length;
+
+	return 0;
+}
+
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance,
+				     struct vpu_buffer *buf)
+{
+	struct vpu_rpc_buffer_desc *desc;
+	struct vpu_enc_expert_mode_param *expert;
+
+	desc = get_stream_buf_desc(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	desc->start = buf->phys;
+	desc->wptr = buf->phys;
+	desc->rptr = buf->phys;
+	desc->end = buf->phys + buf->length;
+
+	expert->calib_param.mem_chunk_phys_addr = 0;
+	expert->calib_param.mem_chunk_virt_addr = 0;
+	expert->calib_param.mem_chunk_size = 0;
+	expert->calib_param.cb_base = buf->phys;
+	expert->calib_param.cb_size = buf->length;
+
+	return 0;
+}
+
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, u32 ptr, bool write)
+{
+	struct vpu_rpc_buffer_desc *desc;
+
+	desc = get_stream_buf_desc(shared, instance);
+
+	/*update wptr/rptr after data is written or read*/
+	mb();
+	if (write)
+		desc->wptr = ptr;
+	else
+		desc->rptr = ptr;
+
+	return 0;
+}
+
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				       u32 instance, struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_rpc_buffer_desc *rpc_desc;
+
+	rpc_desc = get_stream_buf_desc(shared, instance);
+	if (desc) {
+		desc->wptr = get_ptr(rpc_desc->wptr);
+		desc->rptr = get_ptr(rpc_desc->rptr);
+		desc->start = get_ptr(rpc_desc->start);
+		desc->end = get_ptr(rpc_desc->end);
+	}
+
+	return 0;
+}
+
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	return iface->fw_version;
+}
+
+static int vpu_windsor_set_frame_rate(struct vpu_enc_expert_mode_param *expert,
+				      struct vpu_encode_params *params)
+{
+	expert->config_param.frame_rate_num = params->frame_rate.numerator;
+	expert->config_param.frame_rate_den = params->frame_rate.denominator;
+
+	return 0;
+}
+
+static int vpu_windsor_set_format(struct vpu_enc_param *param, u32 pixelformat)
+{
+	switch (pixelformat) {
+	case V4L2_PIX_FMT_H264:
+		param->codec_mode = MEDIAIP_ENC_FMT_H264;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_profile(struct vpu_enc_param *param, u32 profile)
+{
+	switch (profile) {
+	case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+		param->profile = MEDIAIP_ENC_PROF_H264_BP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+		param->profile = MEDIAIP_ENC_PROF_H264_MP;
+		break;
+	case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+		param->profile = MEDIAIP_ENC_PROF_H264_HP;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const u32 h264_level[] = {
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_0] = 10,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1B]  = 14,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_1] = 11,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_2] = 12,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_1_3] = 13,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_0] = 20,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_1] = 21,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_2_2] = 22,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_0] = 30,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_1] = 31,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_3_2] = 32,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_0] = 40,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_1] = 41,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_4_2] = 42,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_0] = 50,
+	[V4L2_MPEG_VIDEO_H264_LEVEL_5_1] = 51
+};
+
+static int vpu_windsor_set_level(struct vpu_enc_param *param, u32 level)
+{
+	if (level >= ARRAY_SIZE(h264_level))
+		return -EINVAL;
+
+	param->level = h264_level[level];
+
+	return 0;
+}
+
+static int vpu_windsor_set_size(struct vpu_enc_param *windsor,
+				struct vpu_encode_params *params)
+{
+	windsor->src_stride = params->src_stride;
+	windsor->src_width = params->src_width;
+	windsor->src_height = params->src_height;
+	windsor->src_offset_x = params->crop.left;
+	windsor->src_offset_y = params->crop.top;
+	windsor->src_crop_width = params->crop.width;
+	windsor->src_crop_height = params->crop.height;
+	windsor->out_width = params->out_width;
+	windsor->out_height = params->out_height;
+
+	return 0;
+}
+
+static int vpu_windsor_set_gop(struct vpu_enc_param *param, u32 gop)
+{
+	param->iframe_interval = gop;
+
+	return 0;
+}
+
+static int vpu_windsor_set_bframes(struct vpu_enc_param *param, u32 bframes)
+{
+	if (bframes) {
+		param->low_latency_mode = 0;
+		param->bframes = bframes;
+	} else {
+		param->low_latency_mode = 1;
+		param->bframes = 0;
+	}
+
+	return 0;
+}
+
+static int vpu_windsor_set_bitrate_mode(struct vpu_enc_param *param, u32 rc_enable, u32 mode)
+{
+	if (!rc_enable)
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CONSTANT_QP;
+	else if (mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_VBR;
+	else
+		param->bitrate_mode = MEDIAIP_ENC_BITRATE_MODE_CBR;
+
+	return 0;
+}
+
+static u32 vpu_windsor_bitrate(u32 bitrate)
+{
+	return DIV_ROUND_CLOSEST(bitrate, WINDSOR_BITRATE_UNIT);
+}
+
+static int vpu_windsor_set_bitrate(struct vpu_enc_param *windsor,
+				   struct vpu_encode_params *params)
+{
+	windsor->target_bitrate = vpu_windsor_bitrate(params->bitrate);
+	windsor->min_bitrate = vpu_windsor_bitrate(params->bitrate_min);
+	windsor->max_bitrate = vpu_windsor_bitrate(params->bitrate_max);
+
+	return 0;
+}
+
+static int vpu_windsor_set_qp(struct vpu_enc_expert_mode_param *expert,
+			      struct vpu_encode_params *params)
+{
+	expert->static_param.rate_control_islice_qp = params->i_frame_qp;
+	expert->static_param.rate_control_pslice_qp = params->p_frame_qp;
+	expert->static_param.rate_control_bslice_qp = params->b_frame_qp;
+
+	return 0;
+}
+
+static int vpu_windsor_set_sar(struct vpu_enc_expert_mode_param *expert,
+			       struct vpu_encode_params *params)
+{
+	expert->config_param.h264_aspect_ratio_present = params->sar.enable;
+	if (params->sar.idc == V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED)
+		expert->config_param.aspect_ratio = WINDSOR_H264_EXTENDED_SAR;
+	else
+		expert->config_param.aspect_ratio = params->sar.idc;
+	expert->config_param.h264_aspect_ratio_sar_width = params->sar.width;
+	expert->config_param.h264_aspect_ratio_sar_height = params->sar.height;
+
+	return 0;
+}
+
+static int vpu_windsor_set_color(struct vpu_enc_expert_mode_param *expert,
+				 struct vpu_encode_params *params)
+{
+	expert->config_param.h264_video_type_present = 1;
+	expert->config_param.h264_video_format = 5;
+	expert->config_param.h264_video_colour_descriptor = 1;
+	expert->config_param.h264_video_colour_primaries =
+		vpu_color_cvrt_primaries_v2i(params->color.primaries);
+	expert->config_param.h264_video_transfer_char =
+		vpu_color_cvrt_transfers_v2i(params->color.transfer);
+	expert->config_param.h264_video_matrix_coeff =
+		vpu_color_cvrt_matrix_v2i(params->color.matrix);
+	expert->config_param.h264_video_full_range =
+		vpu_color_cvrt_full_range_v2i(params->color.full_range);
+	return 0;
+}
+
+static int vpu_windsor_update_bitrate(struct vpu_shared_addr *shared,
+				      u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	struct vpu_enc_expert_mode_param *expert;
+
+	windsor = get_enc_param(shared, instance);
+	expert = get_expert_param(shared, instance);
+
+	if (windsor->bitrate_mode != MEDIAIP_ENC_BITRATE_MODE_CBR)
+		return 0;
+	if (!params->rc_enable)
+		return 0;
+	if (vpu_windsor_bitrate(params->bitrate) == windsor->target_bitrate)
+		return 0;
+
+	vpu_windsor_set_bitrate(windsor, params);
+	expert->static_param.rate_control_bitrate = windsor->target_bitrate;
+	expert->static_param.rate_control_bitrate_min = windsor->min_bitrate;
+	expert->static_param.rate_control_bitrate_max = windsor->max_bitrate;
+
+	return 0;
+}
+
+static int vpu_windsor_set_params(struct vpu_shared_addr *shared,
+				  u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_param *windsor;
+	int ret;
+
+	windsor = get_enc_param(shared, instance);
+
+	if (params->input_format != V4L2_PIX_FMT_NV12 &&
+	    params->input_format != V4L2_PIX_FMT_NV12M)
+		return -EINVAL;
+
+	ret = vpu_windsor_set_format(windsor, params->codec_format);
+	if (ret)
+		return ret;
+	vpu_windsor_set_profile(windsor, params->profile);
+	vpu_windsor_set_level(windsor, params->level);
+	vpu_windsor_set_size(windsor, params);
+	vpu_windsor_set_gop(windsor, params->gop_length);
+	vpu_windsor_set_bframes(windsor, params->bframes);
+	vpu_windsor_set_bitrate_mode(windsor, params->rc_enable, params->rc_mode);
+	vpu_windsor_set_bitrate(windsor, params);
+	windsor->init_slice_qp = params->i_frame_qp;
+
+	if (!params->frame_rate.numerator)
+		return -EINVAL;
+	windsor->frame_rate = params->frame_rate.denominator / params->frame_rate.numerator;
+
+	return 0;
+}
+
+static int vpu_windsor_update_params(struct vpu_shared_addr *shared,
+				     u32 instance, struct vpu_encode_params *params)
+{
+	struct vpu_enc_expert_mode_param *expert;
+
+	expert = get_expert_param(shared, instance);
+
+	vpu_windsor_set_frame_rate(expert, params);
+	vpu_windsor_set_qp(expert, params);
+	vpu_windsor_set_sar(expert, params);
+	vpu_windsor_set_color(expert, params);
+	vpu_windsor_update_bitrate(shared, instance, params);
+	/*expert->config_param.iac_sc_threshold = 0;*/
+
+	return 0;
+}
+
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+				  u32 instance, struct vpu_encode_params *params, u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_windsor_set_params(shared, instance, params);
+	else
+		return vpu_windsor_update_params(shared, instance, params);
+}
+
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct windsor_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/amphion/vpu_windsor.h b/drivers/media/platform/amphion/vpu_windsor.h
new file mode 100644
index 000000000000..3fbb6556dbca
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_windsor.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_WINDSOR_H
+#define _AMPHION_VPU_WINDSOR_H
+
+u32 vpu_windsor_get_data_size(void);
+void vpu_windsor_init_rpc(struct vpu_shared_addr *shared,
+			  struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_windsor_set_log_buf(struct vpu_shared_addr *shared, struct vpu_buffer *log);
+void vpu_windsor_set_system_cfg(struct vpu_shared_addr *shared,
+				u32 regs_base, void __iomem *regs, u32 core_id);
+int vpu_windsor_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_windsor_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_windsor_convert_msg_id(u32 msg_id);
+int vpu_windsor_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_windsor_config_memory_resource(struct vpu_shared_addr *shared,
+				       u32 instance, u32 type, u32 index,
+				       struct vpu_buffer *buf);
+int vpu_windsor_config_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, struct vpu_buffer *buf);
+int vpu_windsor_update_stream_buffer(struct vpu_shared_addr *shared,
+				     u32 instance, u32 ptr, bool write);
+int vpu_windsor_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				       u32 instance, struct vpu_rpc_buffer_desc *desc);
+u32 vpu_windsor_get_version(struct vpu_shared_addr *shared);
+int vpu_windsor_set_encode_params(struct vpu_shared_addr *shared,
+				  u32 instance,
+				  struct vpu_encode_params *params,
+				  u32 update);
+int vpu_windsor_input_frame(struct vpu_shared_addr *shared,
+			    struct vpu_inst *inst, struct vb2_buffer *vb);
+u32 vpu_windsor_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:29 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:29 +0800
Subject: [PATCH v15.1 10/13] media: amphion: implement malone decoder rpc
 interface
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <e4689bd0bddbfa2bdc44322b672e5735500a0436.1643165765.git.ming.qian@nxp.com>

This part implements the malone decoder rpc interface.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
Tested-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 drivers/media/platform/amphion/vpu_malone.c | 1625 +++++++++++++++++++
 drivers/media/platform/amphion/vpu_malone.h |   44 +
 2 files changed, 1669 insertions(+)
 create mode 100644 drivers/media/platform/amphion/vpu_malone.c
 create mode 100644 drivers/media/platform/amphion/vpu_malone.h

diff --git a/drivers/media/platform/amphion/vpu_malone.c b/drivers/media/platform/amphion/vpu_malone.c
new file mode 100644
index 000000000000..76085b69af6d
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_malone.c
@@ -0,0 +1,1625 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#include <linux/init.h>
+#include <linux/interconnect.h>
+#include <linux/ioctl.h>
+#include <linux/list.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/rational.h>
+#include <media/videobuf2-v4l2.h>
+#include <media/videobuf2-dma-contig.h>
+#include <linux/videodev2.h>
+#include "vpu.h"
+#include "vpu_rpc.h"
+#include "vpu_defs.h"
+#include "vpu_helpers.h"
+#include "vpu_v4l2.h"
+#include "vpu_cmds.h"
+#include "vpu_imx8q.h"
+#include "vpu_malone.h"
+
+#define CMD_SIZE			25600
+#define MSG_SIZE			25600
+#define CODEC_SIZE			0x1000
+#define JPEG_SIZE			0x1000
+#define SEQ_SIZE			0x1000
+#define GOP_SIZE			0x1000
+#define PIC_SIZE			0x1000
+#define QMETER_SIZE			0x1000
+#define DBGLOG_SIZE			0x10000
+#define DEBUG_SIZE			0x80000
+#define ENG_SIZE			0x1000
+#define MALONE_SKIPPED_FRAME_ID		0x555
+
+#define MALONE_ALIGN_MBI		0x800
+#define MALONE_DCP_CHUNK_BIT		16
+#define MALONE_DCP_SIZE_MAX		0x3000000
+#define MALONE_DCP_SIZE_MIN		0x100000
+#define MALONE_DCP_FIXED_MB_ALLOC	250
+
+#define CONFIG_SET(val, cfg, pos, mask)		\
+		(*(cfg) |= (((val) << (pos)) & (mask)))
+//x means source data , y means destination data
+#define STREAM_CONFIG_FORMAT_SET(x, y)		CONFIG_SET(x, y, 0, 0x0000000F)
+#define STREAM_CONFIG_STRBUFIDX_SET(x, y)	CONFIG_SET(x, y, 8, 0x00000300)
+#define STREAM_CONFIG_NOSEQ_SET(x, y)		CONFIG_SET(x, y, 10, 0x00000400)
+#define STREAM_CONFIG_DEBLOCK_SET(x, y)		CONFIG_SET(x, y, 11, 0x00000800)
+#define STREAM_CONFIG_DERING_SET(x, y)		CONFIG_SET(x, y, 12, 0x00001000)
+#define STREAM_CONFIG_IBWAIT_SET(x, y)		CONFIG_SET(x, y, 13, 0x00002000)
+#define STREAM_CONFIG_FBC_SET(x, y)		CONFIG_SET(x, y, 14, 0x00004000)
+#define STREAM_CONFIG_PLAY_MODE_SET(x, y)	CONFIG_SET(x, y, 16, 0x00030000)
+#define STREAM_CONFIG_ENABLE_DCP_SET(x, y)	CONFIG_SET(x, y, 20, 0x00100000)
+#define STREAM_CONFIG_NUM_STR_BUF_SET(x, y)	CONFIG_SET(x, y, 21, 0x00600000)
+#define STREAM_CONFIG_MALONE_USAGE_SET(x, y)	CONFIG_SET(x, y, 23, 0x01800000)
+#define STREAM_CONFIG_MULTI_VID_SET(x, y)	CONFIG_SET(x, y, 25, 0x02000000)
+#define STREAM_CONFIG_OBFUSC_EN_SET(x, y)	CONFIG_SET(x, y, 26, 0x04000000)
+#define STREAM_CONFIG_RC4_EN_SET(x, y)		CONFIG_SET(x, y, 27, 0x08000000)
+#define STREAM_CONFIG_MCX_SET(x, y)		CONFIG_SET(x, y, 28, 0x10000000)
+#define STREAM_CONFIG_PES_SET(x, y)		CONFIG_SET(x, y, 29, 0x20000000)
+#define STREAM_CONFIG_NUM_DBE_SET(x, y)		CONFIG_SET(x, y, 30, 0x40000000)
+#define STREAM_CONFIG_FS_CTRL_MODE_SET(x, y)	CONFIG_SET(x, y, 31, 0x80000000)
+
+enum vpu_malone_stream_input_mode {
+	INVALID_MODE = 0,
+	FRAME_LVL,
+	NON_FRAME_LVL
+};
+
+enum vpu_malone_format {
+	MALONE_FMT_NULL = 0x0,
+	MALONE_FMT_AVC  = 0x1,
+	MALONE_FMT_MP2  = 0x2,
+	MALONE_FMT_VC1  = 0x3,
+	MALONE_FMT_AVS  = 0x4,
+	MALONE_FMT_ASP  = 0x5,
+	MALONE_FMT_JPG  = 0x6,
+	MALONE_FMT_RV   = 0x7,
+	MALONE_FMT_VP6  = 0x8,
+	MALONE_FMT_SPK  = 0x9,
+	MALONE_FMT_VP8  = 0xA,
+	MALONE_FMT_HEVC = 0xB,
+	MALONE_FMT_LAST = MALONE_FMT_HEVC
+};
+
+enum {
+	VID_API_CMD_NULL              = 0x00,
+	VID_API_CMD_PARSE_NEXT_SEQ    = 0x01,
+	VID_API_CMD_PARSE_NEXT_I      = 0x02,
+	VID_API_CMD_PARSE_NEXT_IP     = 0x03,
+	VID_API_CMD_PARSE_NEXT_ANY    = 0x04,
+	VID_API_CMD_DEC_PIC           = 0x05,
+	VID_API_CMD_UPDATE_ES_WR_PTR  = 0x06,
+	VID_API_CMD_UPDATE_ES_RD_PTR  = 0x07,
+	VID_API_CMD_UPDATE_UDATA      = 0x08,
+	VID_API_CMD_GET_FSINFO        = 0x09,
+	VID_API_CMD_SKIP_PIC          = 0x0a,
+	VID_API_CMD_DEC_CHUNK         = 0x0b,
+	VID_API_CMD_START             = 0x10,
+	VID_API_CMD_STOP              = 0x11,
+	VID_API_CMD_ABORT             = 0x12,
+	VID_API_CMD_RST_BUF           = 0x13,
+	VID_API_CMD_FS_RELEASE        = 0x15,
+	VID_API_CMD_MEM_REGION_ATTACH = 0x16,
+	VID_API_CMD_MEM_REGION_DETACH = 0x17,
+	VID_API_CMD_MVC_VIEW_SELECT   = 0x18,
+	VID_API_CMD_FS_ALLOC          = 0x19,
+	VID_API_CMD_DBG_GET_STATUS    = 0x1C,
+	VID_API_CMD_DBG_START_LOG     = 0x1D,
+	VID_API_CMD_DBG_STOP_LOG      = 0x1E,
+	VID_API_CMD_DBG_DUMP_LOG      = 0x1F,
+	VID_API_CMD_YUV_READY         = 0x20,
+	VID_API_CMD_TS                = 0x21,
+
+	VID_API_CMD_FIRM_RESET        = 0x40,
+
+	VID_API_CMD_SNAPSHOT          = 0xAA,
+	VID_API_CMD_ROLL_SNAPSHOT     = 0xAB,
+	VID_API_CMD_LOCK_SCHEDULER    = 0xAC,
+	VID_API_CMD_UNLOCK_SCHEDULER  = 0xAD,
+	VID_API_CMD_CQ_FIFO_DUMP      = 0xAE,
+	VID_API_CMD_DBG_FIFO_DUMP     = 0xAF,
+	VID_API_CMD_SVC_ILP           = 0xBB,
+	VID_API_CMD_FW_STATUS         = 0xF0,
+	VID_API_CMD_INVALID           = 0xFF
+};
+
+enum {
+	VID_API_EVENT_NULL			= 0x00,
+	VID_API_EVENT_RESET_DONE		= 0x01,
+	VID_API_EVENT_SEQ_HDR_FOUND		= 0x02,
+	VID_API_EVENT_PIC_HDR_FOUND		= 0x03,
+	VID_API_EVENT_PIC_DECODED		= 0x04,
+	VID_API_EVENT_FIFO_LOW			= 0x05,
+	VID_API_EVENT_FIFO_HIGH			= 0x06,
+	VID_API_EVENT_FIFO_EMPTY		= 0x07,
+	VID_API_EVENT_FIFO_FULL			= 0x08,
+	VID_API_EVENT_BS_ERROR			= 0x09,
+	VID_API_EVENT_UDATA_FIFO_UPTD		= 0x0A,
+	VID_API_EVENT_RES_CHANGE		= 0x0B,
+	VID_API_EVENT_FIFO_OVF			= 0x0C,
+	VID_API_EVENT_CHUNK_DECODED		= 0x0D,
+	VID_API_EVENT_REQ_FRAME_BUFF		= 0x10,
+	VID_API_EVENT_FRAME_BUFF_RDY		= 0x11,
+	VID_API_EVENT_REL_FRAME_BUFF		= 0x12,
+	VID_API_EVENT_STR_BUF_RST		= 0x13,
+	VID_API_EVENT_RET_PING			= 0x14,
+	VID_API_EVENT_QMETER			= 0x15,
+	VID_API_EVENT_STR_FMT_CHANGE		= 0x16,
+	VID_API_EVENT_FIRMWARE_XCPT		= 0x17,
+	VID_API_EVENT_START_DONE		= 0x18,
+	VID_API_EVENT_STOPPED			= 0x19,
+	VID_API_EVENT_ABORT_DONE		= 0x1A,
+	VID_API_EVENT_FINISHED			= 0x1B,
+	VID_API_EVENT_DBG_STAT_UPDATE		= 0x1C,
+	VID_API_EVENT_DBG_LOG_STARTED		= 0x1D,
+	VID_API_EVENT_DBG_LOG_STOPPED		= 0x1E,
+	VID_API_EVENT_DBG_LOG_UPDATED		= 0x1F,
+	VID_API_EVENT_DBG_MSG_DEC		= 0x20,
+	VID_API_EVENT_DEC_SC_ERR		= 0x21,
+	VID_API_EVENT_CQ_FIFO_DUMP		= 0x22,
+	VID_API_EVENT_DBG_FIFO_DUMP		= 0x23,
+	VID_API_EVENT_DEC_CHECK_RES		= 0x24,
+	VID_API_EVENT_DEC_CFG_INFO		= 0x25,
+	VID_API_EVENT_UNSUPPORTED_STREAM	= 0x26,
+	VID_API_EVENT_STR_SUSPENDED		= 0x30,
+	VID_API_EVENT_SNAPSHOT_DONE		= 0x40,
+	VID_API_EVENT_FW_STATUS                 = 0xF0,
+	VID_API_EVENT_INVALID			= 0xFF
+};
+
+struct vpu_malone_buffer_desc {
+	struct vpu_rpc_buffer_desc buffer;
+	u32 low;
+	u32 high;
+};
+
+struct vpu_malone_str_buffer {
+	u32 wptr;
+	u32 rptr;
+	u32 start;
+	u32 end;
+	u32 lwm;
+};
+
+struct vpu_malone_picth_info {
+	u32 frame_pitch;
+};
+
+struct vpu_malone_table_desc {
+	u32 array_base;
+	u32 size;
+};
+
+struct vpu_malone_dbglog_desc {
+	u32 addr;
+	u32 size;
+	u32 level;
+	u32 reserved;
+};
+
+struct vpu_malone_frame_buffer {
+	u32 addr;
+	u32 size;
+};
+
+struct vpu_malone_udata {
+	u32 base;
+	u32 total_size;
+	u32 slot_size;
+};
+
+struct vpu_malone_buffer_info {
+	u32 stream_input_mode;
+	u32 stream_pic_input_count;
+	u32 stream_pic_parsed_count;
+	u32 stream_buffer_threshold;
+	u32 stream_pic_end_flag;
+};
+
+struct vpu_malone_encrypt_info {
+	u32 rec4key[8];
+	u32 obfusc;
+};
+
+struct malone_iface {
+	u32 exec_base_addr;
+	u32 exec_area_size;
+	struct vpu_malone_buffer_desc cmd_buffer_desc;
+	struct vpu_malone_buffer_desc msg_buffer_desc;
+	u32 cmd_int_enable[VID_API_NUM_STREAMS];
+	struct vpu_malone_picth_info stream_pitch_info[VID_API_NUM_STREAMS];
+	u32 stream_config[VID_API_NUM_STREAMS];
+	struct vpu_malone_table_desc codec_param_tab_desc;
+	struct vpu_malone_table_desc jpeg_param_tab_desc;
+	u32 stream_buffer_desc[VID_API_NUM_STREAMS][VID_API_MAX_BUF_PER_STR];
+	struct vpu_malone_table_desc seq_info_tab_desc;
+	struct vpu_malone_table_desc pic_info_tab_desc;
+	struct vpu_malone_table_desc gop_info_tab_desc;
+	struct vpu_malone_table_desc qmeter_info_tab_desc;
+	u32 stream_error[VID_API_NUM_STREAMS];
+	u32 fw_version;
+	u32 fw_offset;
+	u32 max_streams;
+	struct vpu_malone_dbglog_desc dbglog_desc;
+	struct vpu_rpc_buffer_desc api_cmd_buffer_desc[VID_API_NUM_STREAMS];
+	struct vpu_malone_udata udata_buffer[VID_API_NUM_STREAMS];
+	struct vpu_malone_buffer_desc debug_buffer_desc;
+	struct vpu_malone_buffer_desc eng_access_buff_desc[VID_API_NUM_STREAMS];
+	u32 encrypt_info[VID_API_NUM_STREAMS];
+	struct vpu_rpc_system_config system_cfg;
+	u32 api_version;
+	struct vpu_malone_buffer_info stream_buff_info[VID_API_NUM_STREAMS];
+};
+
+struct malone_jpg_params {
+	u32 rotation_angle;
+	u32 horiz_scale_factor;
+	u32 vert_scale_factor;
+	u32 rotation_mode;
+	u32 rgb_mode;
+	u32 chunk_mode; /* 0 ~ 1 */
+	u32 last_chunk; /* 0 ~ 1 */
+	u32 chunk_rows; /* 0 ~ 255 */
+	u32 num_bytes;
+	u32 jpg_crop_x;
+	u32 jpg_crop_y;
+	u32 jpg_crop_width;
+	u32 jpg_crop_height;
+	u32 jpg_mjpeg_mode;
+	u32 jpg_mjpeg_interlaced;
+};
+
+struct malone_codec_params {
+	u32 disp_imm;
+	u32 fourcc;
+	u32 codec_version;
+	u32 frame_rate;
+	u32 dbglog_enable;
+	u32 bsdma_lwm;
+	u32 bbd_coring;
+	u32 bbd_s_thr_row;
+	u32 bbd_p_thr_row;
+	u32 bbd_s_thr_logo_row;
+	u32 bbd_p_thr_logo_row;
+	u32 bbd_s_thr_col;
+	u32 bbd_p_thr_col;
+	u32 bbd_chr_thr_row;
+	u32 bbd_chr_thr_col;
+	u32 bbd_uv_mid_level;
+	u32 bbd_excl_win_mb_left;
+	u32 bbd_excl_win_mb_right;
+};
+
+struct malone_padding_scode {
+	u32 scode_type;
+	u32 pixelformat;
+	u32 data[2];
+};
+
+struct malone_fmt_mapping {
+	u32 pixelformat;
+	enum vpu_malone_format malone_format;
+};
+
+struct malone_scode_t {
+	struct vpu_inst *inst;
+	struct vb2_buffer *vb;
+	u32 wptr;
+	u32 need_data;
+};
+
+struct malone_scode_handler {
+	u32 pixelformat;
+	int (*insert_scode_seq)(struct malone_scode_t *scode);
+	int (*insert_scode_pic)(struct malone_scode_t *scode);
+};
+
+struct vpu_dec_ctrl {
+	struct malone_codec_params *codec_param;
+	struct malone_jpg_params *jpg;
+	void *seq_mem;
+	void *pic_mem;
+	void *gop_mem;
+	void *qmeter_mem;
+	void *dbglog_mem;
+	struct vpu_malone_str_buffer *str_buf[VID_API_NUM_STREAMS];
+	u32 buf_addr[VID_API_NUM_STREAMS];
+};
+
+u32 vpu_malone_get_data_size(void)
+{
+	return sizeof(struct vpu_dec_ctrl);
+}
+
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr)
+{
+	struct malone_iface *iface;
+	struct vpu_dec_ctrl *hc;
+	unsigned long base_phy_addr;
+	unsigned long phy_addr;
+	unsigned long offset;
+	unsigned int i;
+
+	if (rpc->phys < boot_addr)
+		return;
+
+	iface = rpc->virt;
+	base_phy_addr = rpc->phys - boot_addr;
+	hc = shared->priv;
+
+	shared->iface = iface;
+	shared->boot_addr = boot_addr;
+
+	iface->exec_base_addr = base_phy_addr;
+	iface->exec_area_size = rpc->length;
+
+	offset = sizeof(struct malone_iface);
+	phy_addr = base_phy_addr + offset;
+
+	shared->cmd_desc = &iface->cmd_buffer_desc.buffer;
+	shared->cmd_mem_vir = rpc->virt + offset;
+	iface->cmd_buffer_desc.buffer.start =
+	iface->cmd_buffer_desc.buffer.rptr =
+	iface->cmd_buffer_desc.buffer.wptr = phy_addr;
+	iface->cmd_buffer_desc.buffer.end = iface->cmd_buffer_desc.buffer.start + CMD_SIZE;
+	offset += CMD_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	shared->msg_desc = &iface->msg_buffer_desc.buffer;
+	shared->msg_mem_vir = rpc->virt + offset;
+	iface->msg_buffer_desc.buffer.start =
+	iface->msg_buffer_desc.buffer.wptr =
+	iface->msg_buffer_desc.buffer.rptr = phy_addr;
+	iface->msg_buffer_desc.buffer.end = iface->msg_buffer_desc.buffer.start + MSG_SIZE;
+	offset += MSG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->codec_param_tab_desc.array_base = phy_addr;
+	hc->codec_param = rpc->virt + offset;
+	offset += CODEC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->jpeg_param_tab_desc.array_base = phy_addr;
+	hc->jpg = rpc->virt + offset;
+	offset += JPEG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->seq_info_tab_desc.array_base = phy_addr;
+	hc->seq_mem = rpc->virt + offset;
+	offset += SEQ_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->pic_info_tab_desc.array_base = phy_addr;
+	hc->pic_mem = rpc->virt + offset;
+	offset += PIC_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->gop_info_tab_desc.array_base = phy_addr;
+	hc->gop_mem = rpc->virt + offset;
+	offset += GOP_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->qmeter_info_tab_desc.array_base = phy_addr;
+	hc->qmeter_mem = rpc->virt + offset;
+	offset += QMETER_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	iface->dbglog_desc.addr = phy_addr;
+	iface->dbglog_desc.size = DBGLOG_SIZE;
+	hc->dbglog_mem = rpc->virt + offset;
+	offset += DBGLOG_SIZE;
+	phy_addr = base_phy_addr + offset;
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->eng_access_buff_desc[i].buffer.start =
+		iface->eng_access_buff_desc[i].buffer.wptr =
+		iface->eng_access_buff_desc[i].buffer.rptr = phy_addr;
+		iface->eng_access_buff_desc[i].buffer.end =
+			iface->eng_access_buff_desc[i].buffer.start + ENG_SIZE;
+		offset += ENG_SIZE;
+		phy_addr = base_phy_addr + offset;
+	}
+
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		iface->encrypt_info[i] = phy_addr;
+		offset += sizeof(struct vpu_malone_encrypt_info);
+		phy_addr = base_phy_addr + offset;
+	}
+
+	rpc->bytesused = offset;
+}
+
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log)
+{
+	struct malone_iface *iface = shared->iface;
+
+	iface->debug_buffer_desc.buffer.start =
+	iface->debug_buffer_desc.buffer.wptr =
+	iface->debug_buffer_desc.buffer.rptr = log->phys - shared->boot_addr;
+	iface->debug_buffer_desc.buffer.end = iface->debug_buffer_desc.buffer.start + log->length;
+}
+
+static u32 get_str_buffer_offset(u32 instance)
+{
+	return DEC_MFD_XREG_SLV_BASE + MFD_MCX + MFD_MCX_OFF * instance;
+}
+
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 core_id)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_system_config *config = &iface->system_cfg;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	int i;
+
+	vpu_imx8q_set_system_cfg_common(config, regs_base, core_id);
+	for (i = 0; i < VID_API_NUM_STREAMS; i++) {
+		u32 offset = get_str_buffer_offset(i);
+
+		hc->buf_addr[i] = regs_base + offset;
+		hc->str_buf[i] = regs + offset;
+	}
+}
+
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->fw_version;
+}
+
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared)
+{
+	return 0xc00000;
+}
+
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_buffer *buf)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	str_buf->start = buf->phys;
+	str_buf->rptr = buf->phys;
+	str_buf->wptr = buf->phys;
+	str_buf->end = buf->phys + buf->length;
+	str_buf->lwm = 0x1;
+
+	iface->stream_buffer_desc[instance][0] = hc->buf_addr[instance];
+
+	return 0;
+}
+
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	if (desc) {
+		desc->wptr = str_buf->wptr;
+		desc->rptr = str_buf->rptr;
+		desc->start = str_buf->start;
+		desc->end = str_buf->end;
+	}
+
+	return 0;
+}
+
+static void vpu_malone_update_wptr(struct vpu_malone_str_buffer *str_buf, u32 wptr)
+{
+	/*update wptr after data is written*/
+	mb();
+	str_buf->wptr = wptr;
+}
+
+static void vpu_malone_update_rptr(struct vpu_malone_str_buffer *str_buf, u32 rptr)
+{
+	/*update rptr after data is read*/
+	mb();
+	str_buf->rptr = rptr;
+}
+
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+
+	if (write)
+		vpu_malone_update_wptr(str_buf, ptr);
+	else
+		vpu_malone_update_rptr(str_buf, ptr);
+
+	return 0;
+}
+
+static struct malone_fmt_mapping fmt_mappings[] = {
+	{V4L2_PIX_FMT_H264,        MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_H264_MVC,    MALONE_FMT_AVC},
+	{V4L2_PIX_FMT_HEVC,        MALONE_FMT_HEVC},
+	{V4L2_PIX_FMT_VC1_ANNEX_G, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_VC1_ANNEX_L, MALONE_FMT_VC1},
+	{V4L2_PIX_FMT_MPEG2,       MALONE_FMT_MP2},
+	{V4L2_PIX_FMT_MPEG4,       MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_XVID,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_H263,        MALONE_FMT_ASP},
+	{V4L2_PIX_FMT_JPEG,        MALONE_FMT_JPG},
+	{V4L2_PIX_FMT_VP8,         MALONE_FMT_VP8},
+};
+
+static enum vpu_malone_format vpu_malone_format_remap(u32 pixelformat)
+{
+	u32 i;
+
+	for (i = 0; i < ARRAY_SIZE(fmt_mappings); i++) {
+		if (pixelformat == fmt_mappings[i].pixelformat)
+			return fmt_mappings[i].malone_format;
+	}
+
+	return MALONE_FMT_NULL;
+}
+
+static void vpu_malone_set_stream_cfg(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      enum vpu_malone_format malone_format)
+{
+	struct malone_iface *iface = shared->iface;
+	u32 *curr_str_cfg = &iface->stream_config[instance];
+
+	*curr_str_cfg = 0;
+	STREAM_CONFIG_FORMAT_SET(malone_format, curr_str_cfg);
+	STREAM_CONFIG_STRBUFIDX_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NOSEQ_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DEBLOCK_SET(0, curr_str_cfg);
+	STREAM_CONFIG_DERING_SET(0, curr_str_cfg);
+	STREAM_CONFIG_PLAY_MODE_SET(0x3, curr_str_cfg);
+	STREAM_CONFIG_FS_CTRL_MODE_SET(0x1, curr_str_cfg);
+	STREAM_CONFIG_ENABLE_DCP_SET(1, curr_str_cfg);
+	STREAM_CONFIG_NUM_STR_BUF_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MALONE_USAGE_SET(1, curr_str_cfg);
+	STREAM_CONFIG_MULTI_VID_SET(0, curr_str_cfg);
+	STREAM_CONFIG_OBFUSC_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_RC4_EN_SET(0, curr_str_cfg);
+	STREAM_CONFIG_MCX_SET(1, curr_str_cfg);
+	STREAM_CONFIG_PES_SET(0, curr_str_cfg);
+	STREAM_CONFIG_NUM_DBE_SET(1, curr_str_cfg);
+}
+
+static int vpu_malone_set_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_dec_ctrl *hc = shared->priv;
+	enum vpu_malone_format malone_format;
+
+	malone_format = vpu_malone_format_remap(params->codec_format);
+	iface->udata_buffer[instance].base = params->udata.base;
+	iface->udata_buffer[instance].slot_size = params->udata.size;
+
+	vpu_malone_set_stream_cfg(shared, instance, malone_format);
+
+	if (malone_format == MALONE_FMT_JPG) {
+		//1:JPGD_MJPEG_MODE_A; 2:JPGD_MJPEG_MODE_B
+		hc->jpg[instance].jpg_mjpeg_mode = 1;
+		//0: JPGD_MJPEG_PROGRESSIVE
+		hc->jpg[instance].jpg_mjpeg_interlaced = 0;
+	}
+
+	hc->codec_param[instance].disp_imm = params->b_dis_reorder ? 1 : 0;
+	hc->codec_param[instance].dbglog_enable = 0;
+	iface->dbglog_desc.level = 0;
+
+	if (params->b_non_frame)
+		iface->stream_buff_info[instance].stream_input_mode = NON_FRAME_LVL;
+	else
+		iface->stream_buff_info[instance].stream_input_mode = FRAME_LVL;
+	iface->stream_buff_info[instance].stream_buffer_threshold = 0;
+	iface->stream_buff_info[instance].stream_pic_input_count = 0;
+
+	return 0;
+}
+
+static bool vpu_malone_is_non_frame_mode(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+
+	if (iface->stream_buff_info[instance].stream_input_mode == NON_FRAME_LVL)
+		return true;
+
+	return false;
+}
+
+static int vpu_malone_update_params(struct vpu_shared_addr *shared,
+				    u32 instance,
+				    struct vpu_decode_params *params)
+{
+	struct malone_iface *iface = shared->iface;
+
+	if (params->end_flag)
+		iface->stream_buff_info[instance].stream_pic_end_flag = params->end_flag;
+	params->end_flag = 0;
+
+	return 0;
+}
+
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params,
+				 u32 update)
+{
+	if (!params)
+		return -EINVAL;
+
+	if (!update)
+		return vpu_malone_set_params(shared, instance, params);
+	else
+		return vpu_malone_update_params(shared, instance, params);
+}
+
+static struct vpu_pair malone_cmds[] = {
+	{VPU_CMD_ID_START, VID_API_CMD_START},
+	{VPU_CMD_ID_STOP, VID_API_CMD_STOP},
+	{VPU_CMD_ID_ABORT, VID_API_CMD_ABORT},
+	{VPU_CMD_ID_RST_BUF, VID_API_CMD_RST_BUF},
+	{VPU_CMD_ID_SNAPSHOT, VID_API_CMD_SNAPSHOT},
+	{VPU_CMD_ID_FIRM_RESET, VID_API_CMD_FIRM_RESET},
+	{VPU_CMD_ID_FS_ALLOC, VID_API_CMD_FS_ALLOC},
+	{VPU_CMD_ID_FS_RELEASE, VID_API_CMD_FS_RELEASE},
+	{VPU_CMD_ID_TIMESTAMP, VID_API_CMD_TS},
+	{VPU_CMD_ID_DEBUG, VID_API_CMD_FW_STATUS},
+};
+
+static struct vpu_pair malone_msgs[] = {
+	{VPU_MSG_ID_RESET_DONE, VID_API_EVENT_RESET_DONE},
+	{VPU_MSG_ID_START_DONE, VID_API_EVENT_START_DONE},
+	{VPU_MSG_ID_STOP_DONE, VID_API_EVENT_STOPPED},
+	{VPU_MSG_ID_ABORT_DONE, VID_API_EVENT_ABORT_DONE},
+	{VPU_MSG_ID_BUF_RST, VID_API_EVENT_STR_BUF_RST},
+	{VPU_MSG_ID_PIC_EOS, VID_API_EVENT_FINISHED},
+	{VPU_MSG_ID_SEQ_HDR_FOUND, VID_API_EVENT_SEQ_HDR_FOUND},
+	{VPU_MSG_ID_RES_CHANGE, VID_API_EVENT_RES_CHANGE},
+	{VPU_MSG_ID_PIC_HDR_FOUND, VID_API_EVENT_PIC_HDR_FOUND},
+	{VPU_MSG_ID_PIC_DECODED, VID_API_EVENT_PIC_DECODED},
+	{VPU_MSG_ID_DEC_DONE, VID_API_EVENT_FRAME_BUFF_RDY},
+	{VPU_MSG_ID_FRAME_REQ, VID_API_EVENT_REQ_FRAME_BUFF},
+	{VPU_MSG_ID_FRAME_RELEASE, VID_API_EVENT_REL_FRAME_BUFF},
+	{VPU_MSG_ID_FIFO_LOW, VID_API_EVENT_FIFO_LOW},
+	{VPU_MSG_ID_BS_ERROR, VID_API_EVENT_BS_ERROR},
+	{VPU_MSG_ID_UNSUPPORTED, VID_API_EVENT_UNSUPPORTED_STREAM},
+	{VPU_MSG_ID_FIRMWARE_XCPT, VID_API_EVENT_FIRMWARE_XCPT},
+};
+
+static void vpu_malone_pack_fs_alloc(struct vpu_rpc_event *pkt,
+				     struct vpu_fs_info *fs)
+{
+	const u32 fs_type[] = {
+		[MEM_RES_FRAME] = 0,
+		[MEM_RES_MBI] = 1,
+		[MEM_RES_DCP] = 2,
+	};
+
+	pkt->hdr.num = 7;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+	pkt->data[1] = fs->luma_addr;
+	if (fs->type == MEM_RES_FRAME) {
+		/*
+		 * if luma_addr equal to chroma_addr,
+		 * means luma(plane[0]) and chromau(plane[1]) used the
+		 * same fd -- usage of NXP codec2. Need to manually
+		 * offset chroma addr.
+		 */
+		if (fs->luma_addr == fs->chroma_addr)
+			fs->chroma_addr = fs->luma_addr + fs->luma_size;
+		pkt->data[2] = fs->luma_addr + fs->luma_size / 2;
+		pkt->data[3] = fs->chroma_addr;
+		pkt->data[4] = fs->chroma_addr + fs->chromau_size / 2;
+		pkt->data[5] = fs->bytesperline;
+	} else {
+		pkt->data[2] = fs->luma_size;
+		pkt->data[3] = 0;
+		pkt->data[4] = 0;
+		pkt->data[5] = 0;
+	}
+	pkt->data[6] = fs_type[fs->type];
+}
+
+static void vpu_malone_pack_fs_release(struct vpu_rpc_event *pkt,
+				       struct vpu_fs_info *fs)
+{
+	pkt->hdr.num = 1;
+	pkt->data[0] = fs->id | (fs->tag << 24);
+}
+
+static void vpu_malone_pack_timestamp(struct vpu_rpc_event *pkt,
+				      struct vpu_ts_info *info)
+{
+	pkt->hdr.num = 3;
+	if (info->timestamp < 0) {
+		pkt->data[0] = (u32)-1;
+		pkt->data[1] = 0;
+	} else {
+		pkt->data[0] = info->timestamp / NSEC_PER_SEC;
+		pkt->data[1] = info->timestamp % NSEC_PER_SEC;
+	}
+	pkt->data[2] = info->size;
+}
+
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data)
+{
+	int ret;
+
+	ret = vpu_find_dst_by_src(malone_cmds, ARRAY_SIZE(malone_cmds), id);
+	if (ret < 0)
+		return ret;
+
+	pkt->hdr.id = ret;
+	pkt->hdr.num = 0;
+	pkt->hdr.index = index;
+
+	switch (id) {
+	case VPU_CMD_ID_FS_ALLOC:
+		vpu_malone_pack_fs_alloc(pkt, data);
+		break;
+	case VPU_CMD_ID_FS_RELEASE:
+		vpu_malone_pack_fs_release(pkt, data);
+		break;
+	case VPU_CMD_ID_TIMESTAMP:
+		vpu_malone_pack_timestamp(pkt, data);
+		break;
+	}
+
+	pkt->hdr.index = index;
+	return 0;
+}
+
+int vpu_malone_convert_msg_id(u32 id)
+{
+	return vpu_find_src_by_dst(malone_msgs, ARRAY_SIZE(malone_msgs), id);
+}
+
+static void vpu_malone_fill_planes(struct vpu_dec_codec_info *info)
+{
+	u32 interlaced = info->progressive ? 0 : 1;
+
+	info->bytesperline[0] = 0;
+	info->sizeimage[0] = vpu_helper_get_plane_size(info->pixfmt,
+						       info->decoded_width,
+						       info->decoded_height,
+						       0,
+						       info->stride,
+						       interlaced,
+						       &info->bytesperline[0]);
+	info->bytesperline[1] = 0;
+	info->sizeimage[1] = vpu_helper_get_plane_size(info->pixfmt,
+						       info->decoded_width,
+						       info->decoded_height,
+						       1,
+						       info->stride,
+						       interlaced,
+						       &info->bytesperline[1]);
+}
+
+static void vpu_malone_init_seq_hdr(struct vpu_dec_codec_info *info)
+{
+	u32 chunks = info->num_dfe_area >> MALONE_DCP_CHUNK_BIT;
+
+	vpu_malone_fill_planes(info);
+
+	info->mbi_size = (info->sizeimage[0] + info->sizeimage[1]) >> 2;
+	info->mbi_size = ALIGN(info->mbi_size, MALONE_ALIGN_MBI);
+
+	info->dcp_size = MALONE_DCP_SIZE_MAX;
+	if (chunks) {
+		u32 mb_num;
+		u32 mb_w;
+		u32 mb_h;
+
+		mb_w = DIV_ROUND_UP(info->decoded_width, 16);
+		mb_h = DIV_ROUND_UP(info->decoded_height, 16);
+		mb_num = mb_w * mb_h;
+		info->dcp_size = mb_num * MALONE_DCP_FIXED_MB_ALLOC * chunks;
+		info->dcp_size = clamp_t(u32, info->dcp_size,
+					 MALONE_DCP_SIZE_MIN, MALONE_DCP_SIZE_MAX);
+	}
+}
+
+static void vpu_malone_unpack_seq_hdr(struct vpu_rpc_event *pkt,
+				      struct vpu_dec_codec_info *info)
+{
+	info->num_ref_frms = pkt->data[0];
+	info->num_dpb_frms = pkt->data[1];
+	info->num_dfe_area = pkt->data[2];
+	info->progressive = pkt->data[3];
+	info->width = pkt->data[5];
+	info->height = pkt->data[4];
+	info->decoded_width = pkt->data[12];
+	info->decoded_height = pkt->data[11];
+	info->frame_rate.numerator = 1000;
+	info->frame_rate.denominator = pkt->data[8];
+	info->dsp_asp_ratio = pkt->data[9];
+	info->level_idc = pkt->data[10];
+	info->bit_depth_luma = pkt->data[13];
+	info->bit_depth_chroma = pkt->data[14];
+	info->chroma_fmt = pkt->data[15];
+	info->color_primaries = vpu_color_cvrt_primaries_i2v(pkt->data[16]);
+	info->transfer_chars = vpu_color_cvrt_transfers_i2v(pkt->data[17]);
+	info->matrix_coeffs = vpu_color_cvrt_matrix_i2v(pkt->data[18]);
+	info->full_range = vpu_color_cvrt_full_range_i2v(pkt->data[19]);
+	info->vui_present = pkt->data[20];
+	info->mvc_num_views = pkt->data[21];
+	info->offset_x = pkt->data[23];
+	info->offset_y = pkt->data[25];
+	info->tag = pkt->data[27];
+	if (info->bit_depth_luma > 8)
+		info->pixfmt = V4L2_PIX_FMT_NV12M_10BE_8L128;
+	else
+		info->pixfmt = V4L2_PIX_FMT_NV12M_8L128;
+	if (info->frame_rate.numerator && info->frame_rate.denominator) {
+		unsigned long n, d;
+
+		rational_best_approximation(info->frame_rate.numerator,
+					    info->frame_rate.denominator,
+					    info->frame_rate.numerator,
+					    info->frame_rate.denominator,
+					    &n, &d);
+		info->frame_rate.numerator = n;
+		info->frame_rate.denominator = d;
+	}
+	vpu_malone_init_seq_hdr(info);
+}
+
+static void vpu_malone_unpack_pic_info(struct vpu_rpc_event *pkt,
+				       struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[7];
+	info->luma = pkt->data[0];
+	info->start = pkt->data[10];
+	info->end = pkt->data[12];
+	info->pic_size = pkt->data[11];
+	info->stride = pkt->data[5];
+	info->consumed_count = pkt->data[13];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+}
+
+static void vpu_malone_unpack_req_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->type = pkt->data[1];
+}
+
+static void vpu_malone_unpack_rel_frame(struct vpu_rpc_event *pkt,
+					struct vpu_fs_info *info)
+{
+	info->id = pkt->data[0];
+	info->type = pkt->data[1];
+	info->not_displayed = pkt->data[2];
+}
+
+static void vpu_malone_unpack_buff_rdy(struct vpu_rpc_event *pkt,
+				       struct vpu_dec_pic_info *info)
+{
+	info->id = pkt->data[0];
+	info->luma = pkt->data[1];
+	info->stride = pkt->data[3];
+	if (info->id == MALONE_SKIPPED_FRAME_ID)
+		info->skipped = 1;
+	else
+		info->skipped = 0;
+	info->timestamp = MAKE_TIMESTAMP(pkt->data[9], pkt->data[10]);
+}
+
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data)
+{
+	if (!pkt || !data)
+		return -EINVAL;
+
+	switch (pkt->hdr.id) {
+	case VID_API_EVENT_SEQ_HDR_FOUND:
+		vpu_malone_unpack_seq_hdr(pkt, data);
+		break;
+	case VID_API_EVENT_PIC_DECODED:
+		vpu_malone_unpack_pic_info(pkt, data);
+		break;
+	case VID_API_EVENT_REQ_FRAME_BUFF:
+		vpu_malone_unpack_req_frame(pkt, data);
+		break;
+	case VID_API_EVENT_REL_FRAME_BUFF:
+		vpu_malone_unpack_rel_frame(pkt, data);
+		break;
+	case VID_API_EVENT_FRAME_BUFF_RDY:
+		vpu_malone_unpack_buff_rdy(pkt, data);
+		break;
+	}
+
+	return 0;
+}
+
+static const struct malone_padding_scode padding_scodes[] = {
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG2,       {0xCC010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0xefff0000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264,        {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H264_MVC,    {0x0B010000, 0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_HEVC,        {0x4A010000, 0x20}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_G, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VC1_ANNEX_L, {0x0a010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG2,       {0xb7010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_MPEG4,       {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_XVID,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_H263,        {0xb1010000, 0x0}},
+	{SCODE_PADDING_ABORT,    V4L2_PIX_FMT_VP8,         {0x34010000, 0x0}},
+	{SCODE_PADDING_EOS,      V4L2_PIX_FMT_JPEG,        {0x0, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264,        {0x15010000, 0x0}},
+	{SCODE_PADDING_BUFFLUSH, V4L2_PIX_FMT_H264_MVC,    {0x15010000, 0x0}},
+};
+
+static const struct malone_padding_scode padding_scode_dft = {0x0, 0x0};
+
+static const struct malone_padding_scode *get_padding_scode(u32 type, u32 fmt)
+{
+	const struct malone_padding_scode *s;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(padding_scodes); i++) {
+		s = &padding_scodes[i];
+
+		if (s->scode_type == type && s->pixelformat == fmt)
+			return s;
+	}
+
+	if (type != SCODE_PADDING_BUFFLUSH)
+		return &padding_scode_dft;
+
+	return NULL;
+}
+
+static int vpu_malone_add_padding_scode(struct vpu_buffer *stream_buffer,
+					struct vpu_malone_str_buffer *str_buf,
+					u32 pixelformat, u32 scode_type)
+{
+	u32 wptr;
+	u32 size;
+	u32 total_size = 0;
+	const struct malone_padding_scode *ps;
+	const u32 padding_size = 4096;
+	int ret;
+
+	ps = get_padding_scode(scode_type, pixelformat);
+	if (!ps)
+		return -EINVAL;
+
+	wptr = str_buf->wptr;
+	size = ALIGN(wptr, 4) - wptr;
+	if (size)
+		vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	size = sizeof(ps->data);
+	ret = vpu_helper_copy_to_stream_buffer(stream_buffer, &wptr, size, (void *)ps->data);
+	if (ret < size)
+		return -EINVAL;
+	total_size += size;
+
+	size = padding_size - sizeof(ps->data);
+	vpu_helper_memset_stream_buffer(stream_buffer, &wptr, 0, size);
+	total_size += size;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+	return total_size;
+}
+
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[instance];
+	int ret = -EINVAL;
+
+	switch (scode_type) {
+	case SCODE_PADDING_EOS:
+	case SCODE_PADDING_ABORT:
+	case SCODE_PADDING_BUFFLUSH:
+		ret = vpu_malone_add_padding_scode(stream_buffer, str_buf, pixelformat, scode_type);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+#define MALONE_PAYLOAD_HEADER_SIZE		16
+#define MALONE_CODEC_VERSION_ID			0x1
+#define MALONE_CODEC_ID_VC1_SIMPLE		0x10
+#define MALONE_CODEC_ID_VC1_MAIN		0x11
+#define MALONE_CODEC_ID_ARV8			0x28
+#define MALONE_CODEC_ID_ARV9			0x29
+#define MALONE_CODEC_ID_VP6			0x36
+#define MALONE_CODEC_ID_VP8			0x36
+#define MALONE_CODEC_ID_DIVX3			0x38
+#define MALONE_CODEC_ID_SPK			0x39
+
+#define MALONE_VP8_IVF_SEQ_HEADER_LEN		32
+#define MALONE_VP8_IVF_FRAME_HEADER_LEN		8
+
+#define MALONE_VC1_RCV_CODEC_V1_VERSION		0x85
+#define MALONE_VC1_RCV_CODEC_V2_VERSION		0xC5
+#define MALONE_VC1_RCV_NUM_FRAMES		0xFF
+#define MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE	4
+#define MALONE_VC1_RCV_SEQ_HEADER_LEN		20
+#define MALONE_VC1_RCV_PIC_HEADER_LEN		4
+#define MALONE_VC1_NAL_HEADER_LEN		4
+#define MALONE_VC1_CONTAIN_NAL(data)		(((data) & 0x00FFFFFF) == 0x00010000)
+
+static void set_payload_hdr(u8 *dst, u32 scd_type, u32 codec_id,
+			    u32 buffer_size, u32 width, u32 height)
+{
+	unsigned int payload_size;
+	/* payload_size = buffer_size + itself_size(16) - start_code(4) */
+	payload_size = buffer_size + 12;
+
+	dst[0] = 0x00;
+	dst[1] = 0x00;
+	dst[2] = 0x01;
+	dst[3] = scd_type;
+
+	/* length */
+	dst[4] = ((payload_size >> 16) & 0xff);
+	dst[5] = ((payload_size >> 8) & 0xff);
+	dst[6] = 0x4e;
+	dst[7] = ((payload_size >> 0) & 0xff);
+
+	/* Codec ID and Version */
+	dst[8] = codec_id;
+	dst[9] = MALONE_CODEC_VERSION_ID;
+
+	/* width */
+	dst[10] = ((width >> 8) & 0xff);
+	dst[11] = ((width >> 0) & 0xff);
+	dst[12] = 0x58;
+
+	/* height */
+	dst[13] = ((height >> 8) & 0xff);
+	dst[14] = ((height >> 0) & 0xff);
+	dst[15] = 0x50;
+}
+
+static void set_vp8_ivf_seqhdr(u8 *dst, u32 width, u32 height)
+{
+	/* 0-3byte signature "DKIF" */
+	dst[0] = 0x44;
+	dst[1] = 0x4b;
+	dst[2] = 0x49;
+	dst[3] = 0x46;
+	/* 4-5byte version: should be 0*/
+	dst[4] = 0x00;
+	dst[5] = 0x00;
+	/* 6-7 length of Header */
+	dst[6] = MALONE_VP8_IVF_SEQ_HEADER_LEN;
+	dst[7] = MALONE_VP8_IVF_SEQ_HEADER_LEN >> 8;
+	/* 8-11 VP8 fourcc */
+	dst[8] = 0x56;
+	dst[9] = 0x50;
+	dst[10] = 0x38;
+	dst[11] = 0x30;
+	/* 12-13 width in pixels */
+	dst[12] = width;
+	dst[13] = width >> 8;
+	/* 14-15 height in pixels */
+	dst[14] = height;
+	dst[15] = height >> 8;
+	/* 16-19 frame rate */
+	dst[16] = 0xe8;
+	dst[17] = 0x03;
+	dst[18] = 0x00;
+	dst[19] = 0x00;
+	/* 20-23 time scale */
+	dst[20] = 0x01;
+	dst[21] = 0x00;
+	dst[22] = 0x00;
+	dst[23] = 0x00;
+	/* 24-27 number frames */
+	dst[24] = 0xdf;
+	dst[25] = 0xf9;
+	dst[26] = 0x09;
+	dst[27] = 0x00;
+	/* 28-31 reserved */
+}
+
+static void set_vp8_ivf_pichdr(u8 *dst, u32 frame_size)
+{
+	/*
+	 * firmware just parse 64-bit timestamp(8 bytes).
+	 * As not transfer timestamp to firmware, use default value(ZERO).
+	 * No need to do anything here
+	 */
+}
+
+static void set_vc1_rcv_seqhdr(u8 *dst, u8 *src, u32 width, u32 height)
+{
+	u32 frames = MALONE_VC1_RCV_NUM_FRAMES;
+	u32 ext_data_size = MALONE_VC1_RCV_SEQ_EXT_DATA_SIZE;
+
+	/* 0-2 Number of frames, used default value 0xFF */
+	dst[0] = frames;
+	dst[1] = frames >> 8;
+	dst[2] = frames >> 16;
+
+	/* 3 RCV version, used V1 */
+	dst[3] = MALONE_VC1_RCV_CODEC_V1_VERSION;
+
+	/* 4-7 extension data size */
+	dst[4] = ext_data_size;
+	dst[5] = ext_data_size >> 8;
+	dst[6] = ext_data_size >> 16;
+	dst[7] = ext_data_size >> 24;
+	/* 8-11 extension data */
+	dst[8] = src[0];
+	dst[9] = src[1];
+	dst[10] = src[2];
+	dst[11] = src[3];
+
+	/* height */
+	dst[12] = height;
+	dst[13] = (height >> 8) & 0xff;
+	dst[14] = (height >> 16) & 0xff;
+	dst[15] = (height >> 24) & 0xff;
+	/* width */
+	dst[16] = width;
+	dst[17] = (width >> 8) & 0xff;
+	dst[18] = (width >> 16) & 0xff;
+	dst[19] = (width >> 24) & 0xff;
+}
+
+static void set_vc1_rcv_pichdr(u8 *dst, u32 buffer_size)
+{
+	dst[0] = buffer_size;
+	dst[1] = buffer_size >> 8;
+	dst[2] = buffer_size >> 16;
+	dst[3] = buffer_size >> 24;
+}
+
+static void create_vc1_nal_pichdr(u8 *dst)
+{
+	/* need insert nal header: special ID */
+	dst[0] = 0x0;
+	dst[1] = 0x0;
+	dst[2] = 0x01;
+	dst[3] = 0x0D;
+}
+
+static int vpu_malone_insert_scode_seq(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+	int ret;
+
+	set_payload_hdr(hdr,
+			SCODE_SEQUENCE,
+			codec_id,
+			ext_size,
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(hdr),
+					       hdr);
+	return ret;
+}
+
+static int vpu_malone_insert_scode_pic(struct malone_scode_t *scode, u32 codec_id, u32 ext_size)
+{
+	u8 hdr[MALONE_PAYLOAD_HEADER_SIZE];
+
+	set_payload_hdr(hdr,
+			SCODE_PICTURE,
+			codec_id,
+			ext_size + vb2_get_plane_payload(scode->vb, 0),
+			scode->inst->out_format.width,
+			scode->inst->out_format.height);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(hdr),
+						hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_g_pic(struct malone_scode_t *scode)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	u8 nal_hdr[MALONE_VC1_NAL_HEADER_LEN];
+	u32 *data = NULL;
+
+	vbuf = to_vb2_v4l2_buffer(scode->vb);
+	data = vb2_plane_vaddr(scode->vb, 0);
+
+	if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
+		return 0;
+	if (MALONE_VC1_CONTAIN_NAL(*data))
+		return 0;
+
+	create_vc1_nal_pichdr(nal_hdr);
+	return vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+						&scode->wptr,
+						sizeof(nal_hdr),
+						nal_hdr);
+}
+
+static int vpu_malone_insert_scode_vc1_l_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_seqhdr[MALONE_VC1_RCV_SEQ_HEADER_LEN];
+
+	scode->need_data = 0;
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_seqhdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_seqhdr(rcv_seqhdr,
+			   vb2_plane_vaddr(scode->vb, 0),
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(rcv_seqhdr),
+					       rcv_seqhdr);
+
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vc1_l_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 rcv_pichdr[MALONE_VC1_RCV_PIC_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VC1_SIMPLE,
+					  sizeof(rcv_pichdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vc1_rcv_pichdr(rcv_pichdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(rcv_pichdr),
+					       rcv_pichdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_seq(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_SEQ_HEADER_LEN];
+
+	ret = vpu_malone_insert_scode_seq(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_seqhdr(ivf_hdr,
+			   scode->inst->out_format.width,
+			   scode->inst->out_format.height);
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(ivf_hdr),
+					       ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static int vpu_malone_insert_scode_vp8_pic(struct malone_scode_t *scode)
+{
+	int ret;
+	int size = 0;
+	u8 ivf_hdr[MALONE_VP8_IVF_FRAME_HEADER_LEN] = {0};
+
+	ret = vpu_malone_insert_scode_pic(scode, MALONE_CODEC_ID_VP8, sizeof(ivf_hdr));
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	set_vp8_ivf_pichdr(ivf_hdr, vb2_get_plane_payload(scode->vb, 0));
+	ret = vpu_helper_copy_to_stream_buffer(&scode->inst->stream_buffer,
+					       &scode->wptr,
+					       sizeof(ivf_hdr),
+					       ivf_hdr);
+	if (ret < 0)
+		return ret;
+	size += ret;
+
+	return size;
+}
+
+static const struct malone_scode_handler scode_handlers[] = {
+	{
+		/* fix me, need to swap return operation after gstreamer swap */
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_L,
+		.insert_scode_seq = vpu_malone_insert_scode_vc1_l_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_l_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VC1_ANNEX_G,
+		.insert_scode_pic = vpu_malone_insert_scode_vc1_g_pic,
+	},
+	{
+		.pixelformat = V4L2_PIX_FMT_VP8,
+		.insert_scode_seq = vpu_malone_insert_scode_vp8_seq,
+		.insert_scode_pic = vpu_malone_insert_scode_vp8_pic,
+	},
+};
+
+static const struct malone_scode_handler *get_scode_handler(u32 pixelformat)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(scode_handlers); i++) {
+		if (scode_handlers[i].pixelformat == pixelformat)
+			return &scode_handlers[i];
+	}
+
+	return NULL;
+}
+
+static int vpu_malone_insert_scode(struct malone_scode_t *scode, u32 type)
+{
+	const struct malone_scode_handler *handler;
+	int ret = 0;
+
+	if (!scode || !scode->inst || !scode->vb)
+		return 0;
+
+	scode->need_data = 1;
+	handler = get_scode_handler(scode->inst->out_format.pixfmt);
+	if (!handler)
+		return 0;
+
+	switch (type) {
+	case SCODE_SEQUENCE:
+		if (handler->insert_scode_seq)
+			ret = handler->insert_scode_seq(scode);
+		break;
+	case SCODE_PICTURE:
+		if (handler->insert_scode_pic)
+			ret = handler->insert_scode_pic(scode);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int vpu_malone_input_frame_data(struct vpu_malone_str_buffer *str_buf,
+				       struct vpu_inst *inst, struct vb2_buffer *vb,
+				       u32 disp_imm)
+{
+	struct malone_scode_t scode;
+	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+	u32 wptr = str_buf->wptr;
+	int size = 0;
+	int ret = 0;
+
+	/*add scode: SCODE_SEQUENCE, SCODE_PICTURE, SCODE_SLICE*/
+	scode.inst = inst;
+	scode.vb = vb;
+	scode.wptr = wptr;
+	scode.need_data = 1;
+	if (vbuf->sequence == 0 || vpu_vb_is_codecconfig(vbuf))
+		ret = vpu_malone_insert_scode(&scode, SCODE_SEQUENCE);
+
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+	if (!scode.need_data) {
+		vpu_malone_update_wptr(str_buf, wptr);
+		return size;
+	}
+
+	ret = vpu_malone_insert_scode(&scode, SCODE_PICTURE);
+	if (ret < 0)
+		return -ENOMEM;
+	size += ret;
+	wptr = scode.wptr;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+					       &wptr,
+					       vb2_get_plane_payload(vb, 0),
+					       vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+	size += ret;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	if (disp_imm && !vpu_vb_is_codecconfig(vbuf)) {
+		ret = vpu_malone_add_scode(inst->core->iface,
+					   inst->id,
+					   &inst->stream_buffer,
+					   inst->out_format.pixfmt,
+					   SCODE_PADDING_BUFFLUSH);
+		if (ret < 0)
+			return ret;
+		size += ret;
+	}
+
+	return size;
+}
+
+static int vpu_malone_input_stream_data(struct vpu_malone_str_buffer *str_buf,
+					struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	u32 wptr = str_buf->wptr;
+	int ret = 0;
+
+	ret = vpu_helper_copy_to_stream_buffer(&inst->stream_buffer,
+					       &wptr,
+					       vb2_get_plane_payload(vb, 0),
+					       vb2_plane_vaddr(vb, 0));
+	if (ret < vb2_get_plane_payload(vb, 0))
+		return -ENOMEM;
+
+	vpu_malone_update_wptr(str_buf, wptr);
+
+	return ret;
+}
+
+static int vpu_malone_input_ts(struct vpu_inst *inst, s64  timestamp, u32 size)
+{
+	struct vpu_ts_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.timestamp = timestamp;
+	info.size = size;
+
+	return vpu_session_fill_timestamp(inst, &info);
+}
+
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb)
+{
+	struct vpu_dec_ctrl *hc = shared->priv;
+	struct vb2_v4l2_buffer *vbuf;
+	struct vpu_malone_str_buffer *str_buf = hc->str_buf[inst->id];
+	u32 disp_imm = hc->codec_param[inst->id].disp_imm;
+	u32 size;
+	int ret;
+
+	if (vpu_malone_is_non_frame_mode(shared, inst->id))
+		ret = vpu_malone_input_stream_data(str_buf, inst, vb);
+	else
+		ret = vpu_malone_input_frame_data(str_buf, inst, vb, disp_imm);
+	if (ret < 0)
+		return ret;
+	size = ret;
+
+	/*
+	 * if buffer only contain codec data, and the timestamp is invalid,
+	 * don't put the invalid timestamp to resync
+	 * merge the data to next frame
+	 */
+	vbuf = to_vb2_v4l2_buffer(vb);
+	if (vpu_vb_is_codecconfig(vbuf) && (s64)vb->timestamp < 0) {
+		inst->extra_size += size;
+		return 0;
+	}
+	if (inst->extra_size) {
+		size += inst->extra_size;
+		inst->extra_size = 0;
+	}
+
+	ret = vpu_malone_input_ts(inst, vb->timestamp, size);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static bool vpu_malone_check_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+	u32 size = desc->end - desc->start;
+	u32 rptr = desc->rptr;
+	u32 wptr = desc->wptr;
+	u32 used = (wptr + size - rptr) % size;
+
+	if (!size || used < size / 2)
+		return true;
+
+	return false;
+}
+
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance)
+{
+	u32 cnt = 0;
+
+	while (!vpu_malone_check_ready(shared, instance)) {
+		if (cnt > 30)
+			return false;
+		mdelay(1);
+		cnt++;
+	}
+	return true;
+}
+
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	if (!vpu_malone_is_ready(shared, instance))
+		return -EINVAL;
+
+	return 0;
+}
+
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+
+	desc->wptr++;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance)
+{
+	struct malone_iface *iface = shared->iface;
+	struct vpu_rpc_buffer_desc *desc = &iface->api_cmd_buffer_desc[instance];
+
+	desc->wptr = desc->rptr;
+	if (desc->wptr == desc->end)
+		desc->wptr = desc->start;
+
+	return 0;
+}
+
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared)
+{
+	struct malone_iface *iface = shared->iface;
+
+	return iface->max_streams;
+}
diff --git a/drivers/media/platform/amphion/vpu_malone.h b/drivers/media/platform/amphion/vpu_malone.h
new file mode 100644
index 000000000000..e5a5cbe9843e
--- /dev/null
+++ b/drivers/media/platform/amphion/vpu_malone.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2020-2021 NXP
+ */
+
+#ifndef _AMPHION_VPU_MALONE_H
+#define _AMPHION_VPU_MALONE_H
+
+u32 vpu_malone_get_data_size(void);
+void vpu_malone_init_rpc(struct vpu_shared_addr *shared,
+			 struct vpu_buffer *rpc, dma_addr_t boot_addr);
+void vpu_malone_set_log_buf(struct vpu_shared_addr *shared,
+			    struct vpu_buffer *log);
+void vpu_malone_set_system_cfg(struct vpu_shared_addr *shared,
+			       u32 regs_base, void __iomem *regs, u32 core_id);
+u32 vpu_malone_get_version(struct vpu_shared_addr *shared);
+int vpu_malone_get_stream_buffer_size(struct vpu_shared_addr *shared);
+int vpu_malone_config_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, struct vpu_buffer *buf);
+int vpu_malone_get_stream_buffer_desc(struct vpu_shared_addr *shared,
+				      u32 instance,
+				      struct vpu_rpc_buffer_desc *desc);
+int vpu_malone_update_stream_buffer(struct vpu_shared_addr *shared,
+				    u32 instance, u32 ptr, bool write);
+int vpu_malone_set_decode_params(struct vpu_shared_addr *shared,
+				 u32 instance,
+				 struct vpu_decode_params *params, u32 update);
+int vpu_malone_pack_cmd(struct vpu_rpc_event *pkt, u32 index, u32 id, void *data);
+int vpu_malone_convert_msg_id(u32 msg_id);
+int vpu_malone_unpack_msg_data(struct vpu_rpc_event *pkt, void *data);
+int vpu_malone_add_scode(struct vpu_shared_addr *shared,
+			 u32 instance,
+			 struct vpu_buffer *stream_buffer,
+			 u32 pixelformat,
+			 u32 scode_type);
+int vpu_malone_input_frame(struct vpu_shared_addr *shared,
+			   struct vpu_inst *inst, struct vb2_buffer *vb);
+bool vpu_malone_is_ready(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_pre_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_post_cmd(struct vpu_shared_addr *shared, u32 instance);
+int vpu_malone_init_instance(struct vpu_shared_addr *shared, u32 instance);
+u32 vpu_malone_get_max_instance_count(struct vpu_shared_addr *shared);
+
+#endif
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:30 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:30 +0800
Subject: [PATCH v15.1 11/13] ARM64: dts: freescale: imx8q: add imx vpu codec
 entries
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <7f8db91ae941309e38684a17ae1d3c088e72b209.1643165765.git.ming.qian@nxp.com>

Add the Video Processing Unit node for IMX8Q SoC.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 .../arm64/boot/dts/freescale/imx8-ss-vpu.dtsi | 72 +++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 17 +++++
 arch/arm64/boot/dts/freescale/imx8qxp.dtsi    | 24 +++++++
 3 files changed, 113 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi

diff --git a/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
new file mode 100644
index 000000000000..f2dde6d14ca3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2021 NXP
+ *	Dong Aisheng <aisheng.dong at nxp.com>
+ */
+
+vpu: vpu at 2c000000 {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	ranges = <0x2c000000 0x0 0x2c000000 0x2000000>;
+	reg = <0 0x2c000000 0 0x1000000>;
+	power-domains = <&pd IMX_SC_R_VPU>;
+	status = "disabled";
+
+	mu_m0: mailbox at 2d000000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d000000 0x20000>;
+		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_0>;
+		status = "okay";
+	};
+
+	mu1_m0: mailbox at 2d020000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d020000 0x20000>;
+		interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_1>;
+		status = "okay";
+	};
+
+	mu2_m0: mailbox at 2d040000 {
+		compatible = "fsl,imx6sx-mu";
+		reg = <0x2d040000 0x20000>;
+		interrupts = <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+		#mbox-cells = <2>;
+		power-domains = <&pd IMX_SC_R_VPU_MU_2>;
+		status = "disabled";
+	};
+
+	vpu_core0: vpu_core at 2d080000 {
+		reg = <0x2d080000 0x10000>;
+		compatible = "nxp,imx8q-vpu-decoder";
+		power-domains = <&pd IMX_SC_R_VPU_DEC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu_m0 0 0>,
+			<&mu_m0 0 1>,
+			<&mu_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core1: vpu_core at 2d090000 {
+		reg = <0x2d090000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_0>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu1_m0 0 0>,
+			<&mu1_m0 0 1>,
+			<&mu1_m0 1 0>;
+		status = "disabled";
+	};
+	vpu_core2: vpu_core at 2d0a0000 {
+		reg = <0x2d0a0000 0x10000>;
+		compatible = "nxp,imx8q-vpu-encoder";
+		power-domains = <&pd IMX_SC_R_VPU_ENC_1>;
+		mbox-names = "tx0", "tx1", "rx";
+		mboxes = <&mu2_m0 0 0>,
+			<&mu2_m0 0 1>,
+			<&mu2_m0 1 0>;
+		status = "disabled";
+	};
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
index 863232a47004..05495b60beb8 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -196,6 +196,23 @@ &usdhc2 {
 	status = "okay";
 };
 
+&vpu {
+	compatible = "nxp,imx8qxp-vpu";
+	status = "okay";
+};
+
+&vpu_core0 {
+	reg = <0x2d040000 0x10000>;
+	memory-region = <&decoder_boot>, <&decoder_rpc>;
+	status = "okay";
+};
+
+&vpu_core1 {
+	reg = <0x2d050000 0x10000>;
+	memory-region = <&encoder_boot>, <&encoder_rpc>;
+	status = "okay";
+};
+
 &iomuxc {
 	pinctrl_fec1: fec1grp {
 		fsl,pins = <
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
index dbec7c106e0b..a041b85d612b 100644
--- a/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qxp.dtsi
@@ -46,6 +46,9 @@ aliases {
 		serial1 = &lpuart1;
 		serial2 = &lpuart2;
 		serial3 = &lpuart3;
+		vpu_core0 = &vpu_core0;
+		vpu_core1 = &vpu_core1;
+		vpu_core2 = &vpu_core2;
 	};
 
 	cpus {
@@ -162,10 +165,30 @@ reserved-memory {
 		#size-cells = <2>;
 		ranges;
 
+		decoder_boot: decoder-boot at 84000000 {
+			reg = <0 0x84000000 0 0x2000000>;
+			no-map;
+		};
+
+		encoder_boot: encoder-boot at 86000000 {
+			reg = <0 0x86000000 0 0x200000>;
+			no-map;
+		};
+
+		decoder_rpc: decoder-rpc at 0x92000000 {
+			reg = <0 0x92000000 0 0x100000>;
+			no-map;
+		};
+
 		dsp_reserved: dsp at 92400000 {
 			reg = <0 0x92400000 0 0x2000000>;
 			no-map;
 		};
+
+		encoder_rpc: encoder-rpc at 0x94400000 {
+			reg = <0 0x94400000 0 0x700000>;
+			no-map;
+		};
 	};
 
 	pmu {
@@ -287,6 +310,7 @@ map0 {
 
 	/* sorted in register address */
 	#include "imx8-ss-img.dtsi"
+	#include "imx8-ss-vpu.dtsi"
 	#include "imx8-ss-adma.dtsi"
 	#include "imx8-ss-conn.dtsi"
 	#include "imx8-ss-ddr.dtsi"
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:32 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:32 +0800
Subject: [PATCH v15.1 13/13] MAINTAINERS: add AMPHION VPU CODEC V4L2 driver
 entry
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <e42f0160e4affea33127fa6b175a4b522899f219.1643165765.git.ming.qian@nxp.com>

Add AMPHION VPU CODEC v4l2 driver entry

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..c89dfc45c1c7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1030,6 +1030,15 @@ S:	Maintained
 F:	Documentation/hid/amd-sfh*
 F:	drivers/hid/amd-sfh-hid/
 
+AMPHION VPU CODEC V4L2 DRIVER
+M:	Ming Qian <ming.qian at nxp.com>
+M:	Shijie Qin <shijie.qin at nxp.com>
+M:	Zhou Peng <eagle.zhou at nxp.com>
+L:	linux-media at vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/media/amphion,vpu.yaml
+F:	drivers/media/platform/amphion/
+
 AMS AS73211 DRIVER
 M:	Christian Eggers <ceggers at arri.de>
 L:	linux-iio at vger.kernel.org
-- 
2.33.0



From ming.qian at nxp.com  Tue Jan 25 19:09:31 2022
From: ming.qian at nxp.com (Ming Qian)
Date: Wed, 26 Jan 2022 11:09:31 +0800
Subject: [PATCH v15.1 12/13] firmware: imx: scu-pd: imx8q: add vpu mu resources
In-Reply-To: <cover.1643165764.git.ming.qian@nxp.com>
References: <cover.1643165764.git.ming.qian@nxp.com>
Message-ID: <d9444b239c69714808e27d4c9df3bc9a741caed4.1643165765.git.ming.qian@nxp.com>

the vpu core depends on the mu resources.
if they're missed, the vpu can't work.

Signed-off-by: Ming Qian <ming.qian at nxp.com>
Signed-off-by: Shijie Qin <shijie.qin at nxp.com>
Signed-off-by: Zhou Peng <eagle.zhou at nxp.com>
---
 drivers/firmware/imx/scu-pd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/firmware/imx/scu-pd.c b/drivers/firmware/imx/scu-pd.c
index ff6569c4a53b..af3d057e6421 100644
--- a/drivers/firmware/imx/scu-pd.c
+++ b/drivers/firmware/imx/scu-pd.c
@@ -155,6 +155,10 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
 	{ "vpu-pid", IMX_SC_R_VPU_PID0, 8, true, 0 },
 	{ "vpu-dec0", IMX_SC_R_VPU_DEC_0, 1, false, 0 },
 	{ "vpu-enc0", IMX_SC_R_VPU_ENC_0, 1, false, 0 },
+	{ "vpu-enc1", IMX_SC_R_VPU_ENC_1, 1, false, 0 },
+	{ "vpu-mu0", IMX_SC_R_VPU_MU_0, 1, false, 0 },
+	{ "vpu-mu1", IMX_SC_R_VPU_MU_1, 1, false, 0 },
+	{ "vpu-mu2", IMX_SC_R_VPU_MU_2, 1, false, 0 },
 
 	/* GPU SS */
 	{ "gpu0-pid", IMX_SC_R_GPU_0_PID0, 4, true, 0 },
-- 
2.33.0



From robh at kernel.org  Tue Jan 25 19:29:18 2022
From: robh at kernel.org (Rob Herring)
Date: Tue, 25 Jan 2022 21:29:18 -0600
Subject: [PATCH 2/2] dt-bindings: nvmem: cells: add MAC address cell
In-Reply-To: <20220125180114.12286-3-zajec5@gmail.com>
References: <20220125180114.12286-1-zajec5@gmail.com>
 <20220125180114.12286-3-zajec5@gmail.com>
Message-ID: <1643167758.854851.3724357.nullmailer@robh.at.kernel.org>

On Tue, 25 Jan 2022 19:01:14 +0100, Rafa?? Mi??ecki wrote:
> From: Rafa?? Mi??ecki <rafal at milecki.pl>
> 
> This adds support for describing details of NVMEM cell containing MAC
> address. Those are often device specific and could be nicely stored in
> DT.
> 
> Initial documentation includes support for describing:
> 1. Cell data format (e.g. Broadcom's NVRAM uses ASCII to store MAC)
> 2. Reversed bytes flash (required for i.MX6/i.MX7 OCOTP support)
> 3. Source for multiple addresses (very common in home routers)
> 
> Signed-off-by: Rafa?? Mi??ecki <rafal at milecki.pl>
> ---
>  .../bindings/nvmem/cells/mac-address.yaml     | 94 +++++++++++++++++++
>  1 file changed, 94 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
schemas/nvmem/cells/cell.yaml: ignoring, error parsing file
make[1]: *** Deleting file 'Documentation/devicetree/bindings/nvmem/cells/mac-address.example.dt.yaml'
schemas/nvmem/cells/cell.yaml: ignoring, error parsing file
Traceback (most recent call last):
  File "/usr/local/bin/dt-validate", line 170, in <module>
    sg.check_trees(filename, testtree)
  File "/usr/local/bin/dt-validate", line 119, in check_trees
    self.check_subtree(dt, subtree, False, "/", "/", filename)
  File "/usr/local/bin/dt-validate", line 110, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  File "/usr/local/bin/dt-validate", line 110, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  File "/usr/local/bin/dt-validate", line 110, in check_subtree
    self.check_subtree(tree, value, disabled, name, fullname + name, filename)
  [Previous line repeated 1 more time]
  File "/usr/local/bin/dt-validate", line 105, in check_subtree
    self.check_node(tree, subtree, disabled, nodename, fullname, filename)
  File "/usr/local/bin/dt-validate", line 49, in check_node
    errors = sorted(dtschema.DTValidator(schema).iter_errors(node), key=lambda e: e.linecol)
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 771, in iter_errors
    for error in super().iter_errors(instance, _schema):
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 229, in iter_errors
    for error in errors:
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/_validators.py", line 362, in allOf
    yield from validator.descend(instance, subschema, schema_path=index)
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 245, in descend
    for error in self.evolve(schema=schema).iter_errors(instance):
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 771, in iter_errors
    for error in super().iter_errors(instance, _schema):
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 229, in iter_errors
    for error in errors:
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/_validators.py", line 298, in ref
    yield from validator.descend(instance, resolved)
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 245, in descend
    for error in self.evolve(schema=schema).iter_errors(instance):
  File "/usr/local/lib/python3.8/dist-packages/dtschema/lib.py", line 771, in iter_errors
    for error in super().iter_errors(instance, _schema):
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 219, in iter_errors
    scope = id_of(_schema)
  File "/usr/local/lib/python3.8/dist-packages/jsonschema/validators.py", line 96, in _id_of
    return schema.get("$id", "")
AttributeError: 'NoneType' object has no attribute 'get'
make[1]: *** [scripts/Makefile.lib:378: Documentation/devicetree/bindings/nvmem/cells/mac-address.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1398: dt_binding_check] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1584227

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From baolin.wang7 at gmail.com  Tue Jan 25 19:30:55 2022
From: baolin.wang7 at gmail.com (Baolin Wang)
Date: Wed, 26 Jan 2022 11:30:55 +0800
Subject: [PATCH][next] hwspinlock: stm32: Use struct_size() helper in
 devm_kzalloc()
In-Reply-To: <20220125021353.GA29777@embeddedor>
References: <20220125021353.GA29777@embeddedor>
Message-ID: <CADBw62opvW1kdZbjxc0SBidjn0teYLsrfxTqfKoua6x9O84Neg@mail.gmail.com>

On Tue, Jan 25, 2022 at 10:07 AM Gustavo A. R. Silva
<gustavoars at kernel.org> wrote:
>
> Make use of the struct_size() helper instead of an open-coded version,
> in order to avoid any potential type mistakes or integer overflows that,
> in the worst scenario, could lead to heap overflows.
>
> Also, address the following sparse warnings:
> drivers/hwspinlock/stm32_hwspinlock.c:84:32: warning: using sizeof on a flexible structure
>
> Link: https://github.com/KSPP/linux/issues/174
> Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>

LGTM.
Reviewed-by: Baolin Wang <baolin.wang7 at gmail.com>

> ---
>  drivers/hwspinlock/stm32_hwspinlock.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
> index 5bd11a7fab65..716ad4401249 100644
> --- a/drivers/hwspinlock/stm32_hwspinlock.c
> +++ b/drivers/hwspinlock/stm32_hwspinlock.c
> @@ -73,15 +73,14 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
>         struct device *dev = &pdev->dev;
>         struct stm32_hwspinlock *hw;
>         void __iomem *io_base;
> -       size_t array_size;
>         int i, ret;
>
>         io_base = devm_platform_ioremap_resource(pdev, 0);
>         if (IS_ERR(io_base))
>                 return PTR_ERR(io_base);
>
> -       array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
> -       hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
> +       hw = devm_kzalloc(dev, struct_size(hw, bank.lock, STM32_MUTEX_NUM_LOCKS),
> +                         GFP_KERNEL);
>         if (!hw)
>                 return -ENOMEM;
>
> --
> 2.27.0
>


-- 
Baolin Wang


From qizhong.cheng at mediatek.com  Tue Jan 25 19:37:58 2022
From: qizhong.cheng at mediatek.com (qizhong.cheng)
Date: Wed, 26 Jan 2022 11:37:58 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <e8e42eba6e7cf49bc2260f20844a7849@kernel.org>
References: <20220125165748.GA1458116@bhelgaas>
 <e8e42eba6e7cf49bc2260f20844a7849@kernel.org>
Message-ID: <d78b45e461b204d375830217d0d27ffdd97cedd3.camel@mediatek.com>

On Tue, 2022-01-25 at 17:21 +0000, Marc Zyngier wrote:
> On 2022-01-25 16:57, Bjorn Helgaas wrote:
> > All patches change *something*.  Can you update the subject line so
> > it
> > says something specific about the change?
> > 
> > Maybe something like "Clear MSI status before dispatching handler"?
> > 
> > On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> > > As an edge-triggered interrupts, its interrupt status should be 
> > > cleared
> > > before dispatch to the handler of device.
> > 
> > I'm not an IRQ expert, but the reasoning that "we should clear the
> > MSI
> > interrupt status before dispatching the handler because MSI is an
> > edge-triggered interrupt" doesn't seem completely convincing
> > because
> > your code will now look like this:
> > 
> >   /* Clear the INTx */
> >   writel(1 << bit, port->base + PCIE_INT_STATUS);
> >   generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
> >   ...
> > 
> >   /* Clear MSI interrupt status */
> >   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
> >   generic_handle_domain_irq(port->inner_domain, bit);
> > 
> > You clear interrupt status before dispatching the handler for
> > *both*
> > level-triggered INTx interrupts and edge-triggered MSI interrupts.
> > 
> > So it doesn't seem that simply being edge-triggered is the critical
> > factor here.
> 
> This is the usual problem with these half-baked implementations.
> The signalling to the primary interrupt controller is level, as
> they take a multitude of input and (crucially) latch the MSI
> edges. Effectively, this is an edge-to-level converter, with
> all the problems that this creates.
> 
> By clearing the status *after* the handling, you lose edges that
> have been received and coalesced after the read of the status
> register. By clearing it *before*, you are acknowledging the
> interrupts early, and allowing them to be coalesced independently
> of the ones that have been received earlier.
> 
> This is however mostly an educated guess. Someone with access
> to the TRM should verify this.
> 

Yes, as Maz said, we save the edge-interrupt status so that it becomes
a level-interrupt. This is similar to an edge-to-level converter, so we
need to clear it *before*. We found this problem through a lot of
experiments and tested this patch.

Thanks Helgaas and Maz for your comment.

--
Jazz ain't dead, dreams haven't parted with you.

From kuba at kernel.org  Tue Jan 25 19:40:38 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 19:40:38 -0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <20220123141245.1060-1-jszhang@kernel.org>
References: <20220123141245.1060-1-jszhang@kernel.org>
Message-ID: <20220125194038.4bfa2007@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Sun, 23 Jan 2022 22:12:45 +0800 Jisheng Zhang wrote:
> I met can't receive rx pkt issue with below steps:
> 0.plug in ethernet cable then boot normal and get ip from dhcp server
> 1.quickly hotplug out then hotplug in the ethernet cable
> 2.trigger the dhcp client to renew lease
> 
> tcpdump shows that the request tx pkt is sent out successfully,
> but the mac can't receive the rx pkt.
> 
> The issue can easily be reproduced on platforms with PHY_POLL external
> phy. If we don't allow the phy to stop the RXC during LPI, the issue
> is gone. I think it's unsafe to stop the RXC during LPI because the mac
> needs RXC clock to support RX logic.
> 
> And the 2nd param clk_stop_enable of phy_init_eee() is a bool, so use
> false instead of 0.

FWIW this is marked Changes Requested in pw, TBH I'm not sure what 
the conclusion is but if the patch is good please try to fold the
information requested in the discussion into the commit msg and repost.


From bjorn.andersson at linaro.org  Tue Jan 25 20:13:00 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Tue, 25 Jan 2022 22:13:00 -0600
Subject: [PATCH 3/3] ARM: dts: qcom: basic HP TouchPad support
In-Reply-To: <9f19df2a0017b71547445ac34df221e827c45bd0.1643075547.git.benwolsieffer@gmail.com>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
 <9f19df2a0017b71547445ac34df221e827c45bd0.1643075547.git.benwolsieffer@gmail.com>
Message-ID: <YfDKTGQDh3tDMECz@builder.lan>

On Mon 24 Jan 20:07 CST 2022, Ben Wolsieffer wrote:

> Modify the Dragonboard device tree to support the most basic hardware on
> the HP TouchPad. The headphone UART port and eMMC are supported.
> 

We typically don't have one commit for the cloning and then one to
update the content, in particular since your diffstat became rather
weird.

That said, got some comments below, things that I wouldn't have spotted
if you sent this as just a new file.

> Signed-off-by: Ben Wolsieffer <benwolsieffer at gmail.com>
> ---

@Linus, please take a look at the regulator question below.

>  arch/arm/boot/dts/qcom-apq8060-tenderloin.dts | 549 ++----------------
>  1 file changed, 45 insertions(+), 504 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
> index 996e73aa0b0b..e294f3920b9f 100644
> --- a/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
> +++ b/arch/arm/boot/dts/qcom-apq8060-tenderloin.dts
> @@ -14,6 +14,8 @@ aliases {
>  	};
>  
>  	chosen {
> +		/* Bootloader passes console=tty1, which overrides stdout-path */
> +		bootargs = "console=ttyMSM0,115200 earlycon";
>  		stdout-path = "serial0:115200n8";
>  	};
[..]
>  
>  	soc {
>  		pinctrl at 800000 {
> -			/* eMMMC pins, all 8 data lines connected */

It would be nice if you could throw a separate patch on the list that
fixes this spelling mistake in the original as well.

> -			dragon_sdcc1_pins: sdcc1 {
> +			/* eMMC pins, all 8 data lines connected */
> +			emmc_pins: sdcc1 {
>  				mux {
>  					pins = "gpio159", "gpio160", "gpio161",
>  					     "gpio162", "gpio163", "gpio164",
>  					     "gpio165", "gpio166", "gpio167",
>  					     "gpio168";
> -					     function = "sdc1";
> +					function = "sdc1";
>  				};
>  				clk {
>  					pins = "gpio167"; /* SDC1 CLK */
[..]
> @@ -171,205 +77,33 @@ pinconf {
>  				};
>  			};
>  
> -			dragon_gsbi12_i2c_pins: gsbi12_i2c {
> -				mux {
> -					pins = "gpio115", "gpio116";
> -					function = "gsbi12";
> -				};
> -				pinconf {
> -					pins = "gpio115", "gpio116";
> -					drive-strength = <16>;
> -					/* These have external pull-up 4.7kOhm to 1.8V */
> -					bias-disable;
> -				};
> -			};
> -
> -			/* Primary serial port uart 0 pins */
> -			dragon_gsbi12_serial_pins: gsbi12_serial {
> +			/* Headphone UART pins */
> +			headphone_uart_pins: gsbi12_serial {
>  				mux {
>  					pins = "gpio117", "gpio118";
>  					function = "gsbi12";
>  				};
> -				tx {
> -					pins = "gpio117";
> -					drive-strength = <8>;
> -					bias-disable;
> -				};
>  				rx {
> -					pins = "gpio118";
> +					pins = "gpio117";
>  					drive-strength = <2>;
>  					bias-pull-up;
>  				};
> -			};

I find it hard to conclude what the resulting snippet is from this
chunk, did rx swap place from gpio118 to gpio117?

[..]
> @@ -814,14 +378,16 @@ l20 {
>  					bias-pull-down;
>  				};
>  				l21 {
> -					// 1.1 V according to schematic
>  					regulator-min-microvolt = <1200000>;
>  					regulator-max-microvolt = <1200000>;
>  					bias-pull-down;
> -					regulator-always-on;
> +					/*
> +					 * RPM driver can't handle always-on regulators that are
> +					 * supplied by regulators initialized after them.
> +					 */

That looks like an oversight that should be corrected, perhaps it needs
similar attention that was given to the smd-rpm driver recently?

But this makes me wonder, how can this work on the other board? Linus?

> +					// regulator-always-on;
>  				};
>  				l22 {
> -					// 1.2 V according to schematic
>  					regulator-min-microvolt = <1150000>;
>  					regulator-max-microvolt = <1150000>;
>  					bias-pull-down;
> @@ -845,7 +411,7 @@ l25 {
>  				};
>  
>  				s0 {
> -					// regulator-min-microvolt = <500000>;
> +					// regulator-min-microvolt = <800000>;
>  					// regulator-max-microvolt = <1325000>;

This looks like the full range the regulator could do, do you see a
reason for documenting that here? Unless there's a good reason I think
you should leave the commented min/max out.

>  					regulator-min-microvolt = <1100000>;
>  					regulator-max-microvolt = <1100000>;

Regards,
Bjorn


From bjorn.andersson at linaro.org  Tue Jan 25 20:13:27 2022
From: bjorn.andersson at linaro.org (Bjorn Andersson)
Date: Tue, 25 Jan 2022 22:13:27 -0600
Subject: [PATCH 2/3] dt-bindings: arm: qcom: document HP TouchPad
In-Reply-To: <aa59002aeae45a95097300213fc34490aa8db250.1643075547.git.benwolsieffer@gmail.com>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
 <aa59002aeae45a95097300213fc34490aa8db250.1643075547.git.benwolsieffer@gmail.com>
Message-ID: <YfDKZxciezuDXL54@builder.lan>

On Mon 24 Jan 20:07 CST 2022, Ben Wolsieffer wrote:

> Add binding documentation for the HP TouchPad.
> 

Reviewed-by: Bjorn Andersson <bjorn.andersson at linaro.org>

Regards,
Bjorn

> Signed-off-by: Ben Wolsieffer <benwolsieffer at gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/qcom.yaml | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
> index 370aab274cd1..f7418a8a49fc 100644
> --- a/Documentation/devicetree/bindings/arm/qcom.yaml
> +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
> @@ -119,6 +119,7 @@ properties:
>        - items:
>            - enum:
>                - qcom,apq8060-dragonboard
> +              - qcom,apq8060-tenderloin
>                - qcom,msm8660-surf
>            - const: qcom,msm8660
>  
> -- 
> 2.34.1
> 


From kuba at kernel.org  Tue Jan 25 20:17:56 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Tue, 25 Jan 2022 20:17:56 -0800
Subject: [PATCH net v2 2/2] net: stmmac: skip only stmmac_ptp_register
 when resume from suspend
In-Reply-To: <20220125032324.4055-3-mohammad.athari.ismail@intel.com>
References: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
 <20220125032324.4055-3-mohammad.athari.ismail@intel.com>
Message-ID: <20220125201756.1606e1c4@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>

On Tue, 25 Jan 2022 11:23:24 +0800 Mohammad Athari Bin Ismail wrote:
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index d7e261768f73..b8e5e19e6f7b 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -880,11 +880,12 @@ EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter);
>  /**
>   * stmmac_init_ptp - init PTP
>   * @priv: driver private structure
> + * @ptp_register: register PTP if set
>   * Description: this is to verify if the HW supports the PTPv1 or PTPv2.
>   * This is done by looking at the HW cap. register.
>   * This function also registers the ptp driver.
>   */
> -static int stmmac_init_ptp(struct stmmac_priv *priv)
> +static int stmmac_init_ptp(struct stmmac_priv *priv, bool ptp_register)
>  {
>  	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
>  	int ret;
> @@ -914,7 +915,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
>  	priv->hwts_tx_en = 0;
>  	priv->hwts_rx_en = 0;
>  
> -	stmmac_ptp_register(priv);
> +	if (ptp_register)
> +		stmmac_ptp_register(priv);

stmmac_init_ptp() only has one caller, and the registration step is last.
Wouldn't it be better to move the stmmac_ptp_register() call out to
stmmac_hw_setup()? That way we don't need to pass extra arguments to init.

>  	return 0;
>  }
> @@ -3241,7 +3243,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
>  /**
>   * stmmac_hw_setup - setup mac in a usable state.
>   *  @dev : pointer to the device structure.
> - *  @init_ptp: initialize PTP if set
> + *  @ptp_register: register PTP if set
>   *  Description:
>   *  this is the main function to setup the HW in a usable state because the
>   *  dma engine is reset, the core registers are configured (e.g. AXI,
> @@ -3251,7 +3253,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
>   *  0 on success and an appropriate (-)ve integer as defined in errno.h
>   *  file on failure.
>   */
> -static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
> +static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
>  {
>  	struct stmmac_priv *priv = netdev_priv(dev);
>  	u32 rx_cnt = priv->plat->rx_queues_to_use;
> @@ -3308,13 +3310,11 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>  
>  	stmmac_mmc_setup(priv);
>  
> -	if (init_ptp) {
> -		ret = stmmac_init_ptp(priv);
> -		if (ret == -EOPNOTSUPP)
> -			netdev_warn(priv->dev, "PTP not supported by HW\n");
> -		else if (ret)
> -			netdev_warn(priv->dev, "PTP init failed\n");
> -	}
> +	ret = stmmac_init_ptp(priv, ptp_register);
> +	if (ret == -EOPNOTSUPP)
> +		netdev_warn(priv->dev, "PTP not supported by HW\n");
> +	else if (ret)
> +		netdev_warn(priv->dev, "PTP init failed\n");


From jason-jh.lin at mediatek.com  Tue Jan 25 20:18:09 2022
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 26 Jan 2022 12:18:09 +0800
Subject: [PATCH v14 08/12] soc: mediatek: add mtk-mmsys support for
 mt8195 vdosys0
In-Reply-To: <72aa6c751db15e4aac813247c309fae622180056.camel@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-9-jason-jh.lin@mediatek.com>
 <72aa6c751db15e4aac813247c309fae622180056.camel@mediatek.com>
Message-ID: <54aa0b9c88cf421eb382def79f3e06ef93d33c02.camel@mediatek.com>

Hi CK,

Thanks for the reviews.

On Tue, 2022-01-25 at 11:44 +0800, CK Hu wrote:
> Hi, Jason:
> 
> On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> > Add mt8195 vdosys0 clock driver name and routing table to
> > the driver data of mtk-mmsys.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > Acked-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > ---
> > The vdosys1 impelmentation patch [1] will be dependened on this
> > patch.
> > [1] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
> > - 
> > 
https://patchwork.kernel.org/project/linux-mediatek/patch/20211208024426.15595-6-nancy.lin at mediatek.com/
> > ---
> >  drivers/soc/mediatek/mt8195-mmsys.h    | 220
> > +++++++++++++++++++++++++
> >  drivers/soc/mediatek/mtk-mmsys.c       |  11 ++
> >  include/linux/soc/mediatek/mtk-mmsys.h |   9 +
> >  3 files changed, 240 insertions(+)
> >  create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h
> > 
> > diff --git a/drivers/soc/mediatek/mt8195-mmsys.h
> > b/drivers/soc/mediatek/mt8195-mmsys.h
> > new file mode 100644
> > index 000000000000..e04cabdfa2dc
> > --- /dev/null
> > +++ b/drivers/soc/mediatek/mt8195-mmsys.h
> > @@ -0,0 +1,220 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +
> > +#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
> > +#define __SOC_MEDIATEK_MT8195_MMSYS_H
> > +
> > +#define MT8195_VDO0_OVL_MOUT_EN					
> > 0xf14
> > +/*
> > + * MT8195_VDO0_OVL_MOUT[2:0]: DISP_OVL0
> > + *   BIT(0) : DISP_RDMA0
> > + *   BIT(1) : DISP_WDMA0
> > + *   BIT(2): DISP_OVL1
> 
> I think these information is not necessary because we could get these
> information from mmsys_mt8195_routing_table[].
> 
> Regards,
> CK
> 
These comments was suggest by Fei at:

https://patchwork.kernel.org/project/linux-mediatek/patch/20210921155218.10387-10-jason-jh.lin at mediatek.com/#24546317

I've discussed with him that removing these information is fine.
So' I'll remove it at the next version.

> > + */
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			
> > BIT(0)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			
> > BIT(1)
> > +#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
> > +/*
> > + * MT8195_VDO0_OVL_MOUT[6:4]: DISP_OVL1
> > + *   BIT(0) : DISP_RDMA1
> > + *   BIT(1) : DISP_WDMA1
> > + *   BIT(2): DISP_OVL0
> > + */
> > 
> 
> [snip]
> 
> > +
> > +static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[]
> > =
> > {
> > +	{
> > +		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> > +		MT8195_VDO0_OVL_MOUT_EN,
> > MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
> > +		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
> > +	}, {
> > +		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
> > +		MT8195_VDO0_OVL_MOUT_EN,
> > MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
> > +		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT,

> Why this mask MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT is 0?

> > +		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
> > +	}, {
> > +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> > +		MT8195_VDO0_SEL_IN,

> Why this mask MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE is 0?

> > +		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0,
> > +		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT,

> Why this mask MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0 is 0?

> Regards,
> CK

I'll fix the 0 mask problem with the define of GENMASK(h, l) for each
mux settings.

Regards,
Jason-JH.Lin

> > +		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_IN,
> > MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0,
> > +		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
> > +		MT8195_VDO0_SEL_OUT,
> > MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN,
> > +		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
> > +	}, {
> > +		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_DSI0,
> > +		MT8195_SOUT_DISP_DITHER0_TO_DSI0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
> > +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0,
> > +		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
> > +	}, {
> > +		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
> > +		MT8195_VDO0_SEL_OUT,
> > MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE,
> > +		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
> > +	}, {
> > +		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
> > +		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_DP_INTF0,
> > +		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
> > +	}
> > +};
> > +
> 
> 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>



From Justin.He at arm.com  Tue Jan 25 20:20:31 2022
From: Justin.He at arm.com (Justin He)
Date: Wed, 26 Jan 2022 04:20:31 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <YdgZJ/mBG+BCxmEv@arm.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
Message-ID: <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>

Hi Catalin

> -----Original Message-----
> From: Catalin Marinas <catalin.marinas at arm.com>
> Sent: Friday, January 7, 2022 6:43 PM
> To: Jianyong Wu <Jianyong.Wu at arm.com>
> Cc: will at kernel.org; Anshuman Khandual <Anshuman.Khandual at arm.com>;
> akpm at linux-foundation.org; david at redhat.com; quic_qiancai at quicinc.com;
> ardb at kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; Justin He
> <Justin.He at arm.com>; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> > Hi Catalin,
> >
> > I roughly find the root cause.
> >  alloc_init_pud will be called at the very beginning of kernel boot in
> create_mapping_noalloc where no memory allocator is initialized. But
> lockdep check may need allocate memory. So, kernel take exception when
> acquire lock.(I have not found the exact code that cause this issue)
> that's say we may not be able to use a lock so early.
> >
> > I come up with 2 methods to address it.
> > 1) skip dead lock check at the very beginning of kernel boot in lockdep
> code.
> > 2) provided 2 two versions of __create_pgd_mapping, one with lock in
> > it and the other without. There may be no possible of race for memory
> > mapping at the very beginning time of kernel boot, thus we can use the
> > no lock version of __create_pgd_mapping safely.
> > In my test, this issue is gone if there is no lock held in
> > create_mapping_noalloc. I think create_mapping_noalloc is called early
> > enough to avoid the race conditions of memory mapping, however, I have
> > not proved it.
> 
> I think method 2 would work better but rather than implementing new
> nolock functions I'd add a NO_LOCK flag and check it in
> alloc_init_pud() before mutex_lock/unlock. Also add a comment when
> passing the NO_LOCK flag on why it's needed and why there wouldn't be
> any races at that stage (early boot etc.)
> 
The problematic code path is:
__primary_switched
	early_fdt_map->fixmap_remap_fdt
		create_mapping_noalloc->alloc_init_pud
			mutex_lock (with Jianyong's patch)

The problem seems to be that we will clear BSS segment twice if kaslr
is enabled. Hence, some of the static variables in lockdep init process were
messed up. That is to said, with kaslr enabled we might initialize lockdep
twice if we add mutex_lock/unlock in alloc_init_pud().

In other ways, if we invoke mutex_lock/unlock in such a early booting stage.
It might be unsafe because lockdep inserts lock_acquire/release as the complex
hooks.

In summary, would it better if Jianyong splits these early boot and late boot
case? e.g. introduce a nolock version for create_mapping_noalloc().

What do you think of it?

--
Cheers,
Justin (Jia He)




From ricarkol at google.com  Tue Jan 25 20:30:32 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Tue, 25 Jan 2022 20:30:32 -0800
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function
 for an ID register
In-Reply-To: <20220106042708.2869332-2-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-2-reijiw@google.com>
Message-ID: <YfDOaMrj3/M8g+7z@google.com>

Hey Reiji,

On Wed, Jan 05, 2022 at 08:26:43PM -0800, Reiji Watanabe wrote:
> Introduce arm64_check_features(), which does a basic validity checking
> of an ID register value against the register's limit value, which is
> generally the host's sanitized value.
> 
> This function will be used by the following patches to check if an ID
> register value that userspace tries to set for a guest can be supported
> on the host.
> 
> The validation is done using arm64_ftr_bits_kvm, which is created from
> arm64_ftr_regs, with some entries overwritten by entries from
> arm64_ftr_bits_kvm_override.
> 
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/cpufeature.h |   1 +
>  arch/arm64/kernel/cpufeature.c      | 228 ++++++++++++++++++++++++++++
>  2 files changed, 229 insertions(+)
> 
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef6be92b1921..eda7ddbed8cf 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -631,6 +631,7 @@ void check_local_cpu_capabilities(void);
>  
>  u64 read_sanitised_ftr_reg(u32 id);
>  u64 __read_sysreg_by_encoding(u32 sys_id);
> +int arm64_check_features(u32 sys_reg, u64 val, u64 limit);
>  
>  static inline bool cpu_supports_mixed_endian_el0(void)
>  {
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index 6f3e677d88f1..48dff8b101d9 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -3140,3 +3140,231 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
>  		return sprintf(buf, "Vulnerable\n");
>  	}
>  }
> +
> +#ifdef CONFIG_KVM
> +/*
> + * arm64_ftr_bits_kvm[] is used for KVM to check if features that are
> + * indicated in an ID register value for the guest are available on the host.
> + * arm64_ftr_bits_kvm[] is created based on arm64_ftr_regs[].  But, for
> + * registers for which arm64_ftr_bits_kvm_override[] has a corresponding
> + * entry, replace arm64_ftr_bits entries in arm64_ftr_bits_kvm[] with the
> + * ones in arm64_ftr_bits_kvm_override[].
> + */
> +static struct __ftr_reg_bits_entry *arm64_ftr_bits_kvm;
> +static size_t arm64_ftr_bits_kvm_nentries;

I don't think this is really needed, as arm64_ftr_bits_kvm_override has
to have the same size as arm64_ftr_bits_kvm. You could use
ARRAY_SIZE(arm64_ftr_regs) like in get_arm64_ftr_reg_nowarn().

> +static DEFINE_MUTEX(arm64_ftr_bits_kvm_lock);
> +
> +/*
> + * Number of arm64_ftr_bits entries for each register.
> + * (Number of 4 bits fields in 64 bit register + 1 entry for ARM64_FTR_END)
> + */
> +#define	MAX_FTR_BITS_LEN	17
> +
> +/* Use FTR_LOWER_SAFE for AA64DFR0_EL1.PMUVER and AA64DFR0_EL1.DEBUGVER. */
> +static struct arm64_ftr_bits ftr_id_aa64dfr0_kvm[MAX_FTR_BITS_LEN] = {
> +	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
> +	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
> +	ARM64_FTR_END,
> +};
> +
> +#define	ARM64_FTR_REG_BITS(id, table)	{	\
> +	.sys_id = id,				\
> +	.ftr_bits = &((table)[0]),		\
> +}
> +
> +struct __ftr_reg_bits_entry {
> +	u32	sys_id;
> +	struct arm64_ftr_bits	*ftr_bits;
> +};
> +
> +/*
> + * All entries in arm64_ftr_bits_kvm_override[] are used to override
> + * the corresponding entries in arm64_ftr_bits_kvm[].
> + */
> +static struct __ftr_reg_bits_entry arm64_ftr_bits_kvm_override[] = {
> +	ARM64_FTR_REG_BITS(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0_kvm),
> +};
> +
> +/*
> + * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
> + * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
> + * ARM64_FTR_END (.width == 0).
> + */
> +static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,
> +					struct arm64_ftr_bits *new_ftrp)
> +{
> +	struct arm64_ftr_bits *o_ftrp, *n_ftrp;
> +
> +	for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
> +		for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
> +			if (o_ftrp->shift == n_ftrp->shift) {
> +				*o_ftrp = *n_ftrp;
> +				break;
> +			}
> +		}
> +	}
> +}
> +
> +/*
> + * Copy arm64_ftr_bits entries from @src_ftrp to @dst_ftrp.  The last entries
> + * of @dst_ftrp and @src_ftrp must be ARM64_FTR_END (.width == 0).
> + */
> +static void copy_arm64_ftr_bits(struct arm64_ftr_bits *dst_ftrp,
> +				const struct arm64_ftr_bits *src_ftrp)
> +{
> +	int i = 0;
> +
> +	for (; src_ftrp[i].width; i++) {
> +		if (WARN_ON_ONCE(i >= (MAX_FTR_BITS_LEN - 1)))
> +			break;
> +
> +		dst_ftrp[i] = src_ftrp[i];
> +	}
> +
> +	dst_ftrp[i].width = 0;
> +}
> +
> +/*
> + * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
> + * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
> + * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
> + */
> +static int init_arm64_ftr_bits_kvm(void)
> +{
> +	struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
> +	static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
> +	int i, j, nent, ret;
> +
> +	mutex_lock(&arm64_ftr_bits_kvm_lock);

This is initialized lazily, whenever KVM calls arm64_check_features(). I
guess that's why it needs the lock (and possibly a barrier as you
mentoin in your reply). Would it be possible to simplify things by
initializing arm64_ftr_bits_kvm somewhere at boot time (in
init_cpu_features maybe?)?

> +	if (arm64_ftr_bits_kvm) {
> +		/* Already initialized */
> +		ret = 0;
> +		goto unlock_exit;
> +	}
> +
> +	nent = ARRAY_SIZE(arm64_ftr_regs);
> +	reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
> +				 GFP_KERNEL);
> +	if (!reg_bits_array) {
> +		ret = ENOMEM;
> +		goto unlock_exit;
> +	}
> +
> +	/* Copy entries from arm64_ftr_regs to reg_bits_array */
> +	for (i = 0; i < nent; i++) {
> +		bits = &reg_bits_array[i];
> +		bits->sys_id = arm64_ftr_regs[i].sys_id;
> +		bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
> +	};
> +
> +	/*
> +	 * Override the entries in reg_bits_array with the ones in
> +	 * arm64_ftr_bits_kvm_override.
> +	 */
> +	for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
> +		o_bits = &arm64_ftr_bits_kvm_override[i];
> +		for (j = 0; j < nent; j++) {
> +			bits = &reg_bits_array[j];
> +			if (bits->sys_id != o_bits->sys_id)
> +				continue;
> +
> +			memset(ftr_temp, 0, sizeof(ftr_temp));
> +
> +			/*
> +			 * Temporary save all entries in o_bits->ftr_bits
> +			 * to ftr_temp.
> +			 */
> +			copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
> +
> +			/*
> +			 * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
> +			 */
> +			copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
> +
> +			/*
> +			 * Override entries in o_bits->ftr_bits with the
> +			 * saved ones, and update bits->ftr_bits with
> +			 * o_bits->ftr_bits.
> +			 */
> +			arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
> +			bits->ftr_bits = o_bits->ftr_bits;
> +			break;
> +		}
> +	}
> +
> +	arm64_ftr_bits_kvm_nentries = nent;
> +	arm64_ftr_bits_kvm = reg_bits_array;
> +	ret = 0;
> +
> +unlock_exit:
> +	mutex_unlock(&arm64_ftr_bits_kvm_lock);
> +	return ret;
> +}
> +
> +static int search_cmp_ftr_reg_bits(const void *id, const void *regp)
> +{
> +	return ((int)(unsigned long)id -
> +		(int)((const struct __ftr_reg_bits_entry *)regp)->sys_id);
> +}
> +
> +static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
> +{
> +	const struct __ftr_reg_bits_entry *ret;
> +	int err;
> +
> +	if (!arm64_ftr_bits_kvm) {
> +		/* arm64_ftr_bits_kvm is not initialized yet. */
> +		err = init_arm64_ftr_bits_kvm();
> +		if (err)
> +			return NULL;
> +	}
> +
> +	ret = bsearch((const void *)(unsigned long)sys_id,
> +		      arm64_ftr_bits_kvm,
> +		      arm64_ftr_bits_kvm_nentries,
> +		      sizeof(arm64_ftr_bits_kvm[0]),
> +		      search_cmp_ftr_reg_bits);
> +	if (ret)
> +		return ret->ftr_bits;
> +
> +	return NULL;
> +}
> +
> +/*
> + * Check if features (or levels of features) that are indicated in the ID
> + * register value @val are also indicated in @limit.
> + * This function is for KVM to check if features that are indicated in @val,
> + * which will be used as the ID register value for its guest, are supported
> + * on the host.
> + * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
> + * scheme, the function checks if values of the fields in @val are the same
> + * as the ones in @limit.
> + */
> +int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
> +{
> +	const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);

Given that this is to be used only by KVM (and it's inside CONFIG_KVM),
it might be better to have "kvm" somewhere in its name.

> +	u64 exposed_mask = 0;
> +
> +	if (!ftrp)
> +		return -ENOENT;
> +
> +	for (; ftrp->width; ftrp++) {
> +		s64 ftr_val = arm64_ftr_value(ftrp, val);
> +		s64 ftr_lim = arm64_ftr_value(ftrp, limit);
> +
> +		exposed_mask |= arm64_ftr_mask(ftrp);
> +
> +		if (ftr_val == ftr_lim)
> +			continue;
> +
> +		if (ftr_val != arm64_ftr_safe_value(ftrp, ftr_val, ftr_lim))
> +			return -E2BIG;
> +	}
> +
> +	/* Make sure that no unrecognized fields are set in @val. */
> +	if (val & ~exposed_mask)
> +		return -E2BIG;
> +
> +	return 0;
> +}
> +#endif /* CONFIG_KVM */
> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 


From jason-jh.lin at mediatek.com  Tue Jan 25 20:43:18 2022
From: jason-jh.lin at mediatek.com (Jason-JH Lin)
Date: Wed, 26 Jan 2022 12:43:18 +0800
Subject: [PATCH v14 09/12] soc: mediatek: add mtk-mutex support for
 mt8195 vdosys0
In-Reply-To: <6e23ceaac55d64b7c74c5ce6d7114936354c2011.camel@mediatek.com>
References: <20220107101425.6917-1-jason-jh.lin@mediatek.com>
 <20220107101425.6917-10-jason-jh.lin@mediatek.com>
 <6e23ceaac55d64b7c74c5ce6d7114936354c2011.camel@mediatek.com>
Message-ID: <23915f6d4890d6c7115a01202b84b7aa63d51e36.camel@mediatek.com>

Hi CK,

Thanks for the reviews.

On Mon, 2022-01-24 at 17:13 +0800, CK Hu wrote:
> Hi, Jason:
> 
> On Fri, 2022-01-07 at 18:14 +0800, jason-jh.lin wrote:
> > Add mtk-mutex support for mt8195 vdosys0.
> > 
> > Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> > Acked-by: AngeloGioacchino Del Regno <
> > angelogioacchino.delregno at collabora.com>
> > ---
> > This patch is base on [1]
> > [1] Add mmsys and mutex support for MDP
> > - 
> > 
https://patchwork.kernel.org/project/linux-mediatek/cover/20220104091712.25670-1-moudy.ho at mediatek.com/
> > ---
> >  drivers/soc/mediatek/mtk-mutex.c | 95
> > +++++++++++++++++++++++++++++++-
> >  1 file changed, 92 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-mutex.c
> > b/drivers/soc/mediatek/mtk-mutex.c
> > index 615c42260a50..89daab7e6863 100644
> > --- a/drivers/soc/mediatek/mtk-mutex.c
> > +++ b/drivers/soc/mediatek/mtk-mutex.c
> > @@ -21,6 +21,9 @@
> >  #define MT8183_MUTEX0_MOD0			0x30
> >  #define MT8183_MUTEX0_SOF0			0x2c

[snip]

> >  
> > +static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
> > +	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> > +	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 |
> > MT8195_MUTEX_EOF_DSI0,
> > +	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 |
> > MT8195_MUTEX_EOF_DSI1,
> > +	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 |
> > MT8195_MUTEX_EOF_DPI0,
> > +	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 |
> > MT8195_MUTEX_EOF_DPI1,
> > +	[MUTEX_SOF_DP_INTF0] =
> > +		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
> 
> Why add EOF? Add comment for this.
> 
> Regards,
> CK
> 
OK, I' ll add this comment:

/*
 * To support refresh mode(video mode), DISP_REG_MUTEX_SOF should
 * select the EOF source and configure the EOF plus timing from the 
 * module that provides the timing signal.
 * So that MUTEX can not only send a STREAM_DONE event to GCE
 * but also detect the error at end of frame(EAEOF) when EOF signal
 * arrives.
 */

Regards,
Jason-JH.Lin

> > +	[MUTEX_SOF_DP_INTF1] =
> > +		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
> > +};
> > +
> >  static const struct mtk_mutex_data mt2701_mutex_driver_data = {
> >  	.mutex_mod = mt2701_mutex_mod,
> >  	.mutex_sof = mt2712_mutex_sof,
> > @@ -355,6 +431,13 @@ static const struct mtk_mutex_data
> > mt8192_mutex_driver_data = {
> >  	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
> >  };
> >  
> > +static const struct mtk_mutex_data mt8195_mutex_driver_data = {
> > +	.mutex_mod = mt8195_mutex_mod,
> > +	.mutex_sof = mt8195_mutex_sof,
> > +	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
> > +	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
> > +};
> > +
> >  struct mtk_mutex *mtk_mutex_get(struct device *dev)
> >  {
> >  	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
> > @@ -442,6 +525,9 @@ void mtk_mutex_add_comp(struct mtk_mutex
> > *mutex,
> >  	case DDP_COMPONENT_DPI1:
> >  		sof_id = MUTEX_SOF_DPI1;
> >  		break;
> > +	case DDP_COMPONENT_DP_INTF0:
> > +		sof_id = MUTEX_SOF_DP_INTF0;
> > +		break;
> >  	default:
> >  		if (mtx->data->mutex_mod[id] < 32) {
> >  			offset = DISP_REG_MUTEX_MOD(mtx->data-
> > > mutex_mod_reg,
> > 
> > @@ -481,6 +567,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex
> > *mutex,
> >  	case DDP_COMPONENT_DSI3:
> >  	case DDP_COMPONENT_DPI0:
> >  	case DDP_COMPONENT_DPI1:
> > +	case DDP_COMPONENT_DP_INTF0:
> >  		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
> >  			       mtx->regs +
> >  			       DISP_REG_MUTEX_SOF(mtx->data-
> > > mutex_sof_reg,
> > 
> > @@ -678,6 +765,8 @@ static const struct of_device_id
> > mutex_driver_dt_match[] = {
> >  	  .data = &mt8183_mutex_driver_data},
> >  	{ .compatible = "mediatek,mt8192-disp-mutex",
> >  	  .data = &mt8192_mutex_driver_data},
> > +	{ .compatible = "mediatek,mt8195-disp-mutex",
> > +	  .data = &mt8195_mutex_driver_data},
> >  	{},
> >  };
> >  MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
> 
> 
-- 
Jason-JH Lin <jason-jh.lin at mediatek.com>



From christianshewitt at gmail.com  Tue Jan 25 20:49:51 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:51 +0000
Subject: [PATCH 0/3] arm64: dts: meson: add ATF BL32 reserved-memory regions
Message-ID: <20220126044954.19069-1-christianshewitt@gmail.com>

This series supersedes [0] which fixed a long-running kernel panic issue
seen with Beelink G12B devices booted from Amlogic vendor firmware. The
same issue exists with a wider set of devices from GXBB to SM1, although
it is not often seen due to my kernel fork including 'catch-all' patches
for some time (the meson-gx patch was suggested by Matheusz in 2019) and
many distros actively supporting Amlogic hardware consuming some or all
of my regular patchset.

I've also included a cleanup to the SEI510/SEI610 board files. If that's
not desirable feel free to ignore that patch. I also dropped the fixes
tagging as I'm not sure what original commits could be targetted. If you
think fixes are good please provide some guidance and I'll be happy to
send a revised series.

[0] https://patchwork.kernel.org/project/linux-amlogic/list/?series=607446

Christian Hewitt (3):
  arm64: dts: meson-gx: add ATF BL32 reserved-memory region
  arm64: dts: meson-g12: add ATF BL32 reserved-memory region
  arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610

 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
 arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi         | 6 ++++++
 arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
 4 files changed, 12 insertions(+), 16 deletions(-)

-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:52 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:52 +0000
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory region
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-2-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
present in many devices that boot from Amlogic vendor u-boot.

Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 6b457b2c30a4..aa14ea017a61 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -49,6 +49,12 @@
 			no-map;
 		};
 
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:53 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:53 +0000
Subject: [PATCH 2/3] arm64: dts: meson-g12: add ATF BL32 reserved-memory region
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-3-christianshewitt@gmail.com>

Add an additional reserved memory region for the BL32 trusted firmware
present in many devices that boot from Amlogic vendor u-boot.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 6d99c23261fb..45947c1031c4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -107,6 +107,12 @@
 			no-map;
 		};
 
+		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
+		secmon_reserved_bl32: secmon at 5300000 {
+			reg = <0x0 0x05300000 0x0 0x2000000>;
+			no-map;
+		};
+
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-- 
2.17.1



From christianshewitt at gmail.com  Tue Jan 25 20:49:54 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 04:49:54 +0000
Subject: [PATCH 3/3] arm64: dts: meson-g12: drop BL32 region from SEI510/SEI610
In-Reply-To: <20220126044954.19069-1-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
Message-ID: <20220126044954.19069-4-christianshewitt@gmail.com>

The BL32/TEE reserved-memory region is now inherited from the common
family dtsi (meson-g12-common) so we can drop it from board files.

Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
 arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
 2 files changed, 16 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index d8838dde0f0f..4fb31c2ba31c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -157,14 +157,6 @@
 		regulator-always-on;
 	};
 
-	reserved-memory {
-		/* TEE Reserved Memory */
-		bl32_reserved: bl32 at 5000000 {
-			reg = <0x0 0x05300000 0x0 0x2000000>;
-			no-map;
-		};
-	};
-
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
index 427475846fc7..a5d79f2f7c19 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
@@ -203,14 +203,6 @@
 		regulator-always-on;
 	};
 
-	reserved-memory {
-		/* TEE Reserved Memory */
-		bl32_reserved: bl32 at 5000000 {
-			reg = <0x0 0x05300000 0x0 0x2000000>;
-			no-map;
-		};
-	};
-
 	sdio_pwrseq: sdio-pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
-- 
2.17.1



From miles.chen at mediatek.com  Tue Jan 25 21:11:55 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 13:11:55 +0800
Subject: [PATCH] pinctrl: fix a discarded-qualifiers build error
In-Reply-To: <693a71e17b364afd987f2d2178b7e5cb@AcuMS.aculab.com>
References: <693a71e17b364afd987f2d2178b7e5cb@AcuMS.aculab.com>
Message-ID: <20220126051155.25808-1-miles.chen@mediatek.com>

Hi, 

> You should change the type of 'grp' not add a cast.
> The compiler can warn about casts removing 'const' as well.
> 
> 	David

Thanks for the comment,
I just found that this issue has been fixed [1]


Miles

[1] https://lore.kernel.org/lkml/DM6PR11MB3660804C821D7CA7329B6CAFC45F9 at DM6PR11MB3660.namprd11.prod.outlook.com/



From ricarkol at google.com  Tue Jan 25 21:22:17 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Tue, 25 Jan 2022 21:22:17 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <20220106042708.2869332-3-reijiw@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
Message-ID: <YfDaiUbSkpi9/5YY@google.com>

On Wed, Jan 05, 2022 at 08:26:44PM -0800, Reiji Watanabe wrote:
> Introduce id_regs[] in kvm_arch as a storage of guest's ID registers,
> and save ID registers' sanitized value in the array at KVM_CREATE_VM.
> Use the saved ones when ID registers are read by the guest or
> userspace (via KVM_GET_ONE_REG).
> 
> Signed-off-by: Reiji Watanabe <reijiw at google.com>
> ---
>  arch/arm64/include/asm/kvm_host.h | 16 ++++++++
>  arch/arm64/kvm/arm.c              |  1 +
>  arch/arm64/kvm/sys_regs.c         | 62 ++++++++++++++++++++++---------
>  3 files changed, 62 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 2a5f7f38006f..c789a0137f58 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -102,6 +102,17 @@ struct kvm_s2_mmu {
>  struct kvm_arch_memory_slot {
>  };
>  
> +/*
> + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> + * where 0<=crm<8, 0<=op2<8.

Is this observation based on this table?

Table D12-2 System instruction encodings for non-Debug System register accesses

in that case, it seems that the ID registers list might grow after
crm=7, and as CRm has 4 bits, why not 16*8=128?

> + */
> +#define KVM_ARM_ID_REG_MAX_NUM	64
> +#define IDREG_IDX(id)		((sys_reg_CRm(id) << 3) | sys_reg_Op2(id))
> +#define is_id_reg(id)	\
> +	(sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&	\
> +	 sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&	\
> +	 sys_reg_CRm(id) < 8)
> +
>  struct kvm_arch {
>  	struct kvm_s2_mmu mmu;
>  
> @@ -137,6 +148,9 @@ struct kvm_arch {
>  
>  	/* Memory Tagging Extension enabled for the guest */
>  	bool mte_enabled;
> +
> +	/* ID registers for the guest. */
> +	u64 id_regs[KVM_ARM_ID_REG_MAX_NUM];
>  };
>  
>  struct kvm_vcpu_fault_info {
> @@ -734,6 +748,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
>  long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
>  				struct kvm_arm_copy_mte_tags *copy_tags);
>  
> +void set_default_id_regs(struct kvm *kvm);
> +
>  /* Guest/host FPSIMD coordination helpers */
>  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
>  void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> index e4727dc771bf..5f497a0af254 100644
> --- a/arch/arm64/kvm/arm.c
> +++ b/arch/arm64/kvm/arm.c
> @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
>  	kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
>  
>  	set_default_spectre(kvm);
> +	set_default_id_regs(kvm);
>  
>  	return ret;
>  out_free_stage2_pgd:
> diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> index e3ec1a44f94d..80dc62f98ef0 100644
> --- a/arch/arm64/kvm/sys_regs.c
> +++ b/arch/arm64/kvm/sys_regs.c
> @@ -33,6 +33,8 @@
>  
>  #include "trace.h"
>  
> +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
> +
>  /*
>   * All of this file is extremely similar to the ARM coproc.c, but the
>   * types are different. My gut feeling is that it should be pretty
> @@ -273,7 +275,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
>  			  struct sys_reg_params *p,
>  			  const struct sys_reg_desc *r)
>  {
> -	u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> +	u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
>  	u32 sr = reg_to_encoding(r);
>  
>  	if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> @@ -1059,17 +1061,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
>  	return true;
>  }
>  
> -/* Read a sanitised cpufeature ID register by sys_reg_desc */
> -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> -		struct sys_reg_desc const *r, bool raz)
> +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
>  {
> -	u32 id = reg_to_encoding(r);
> -	u64 val;
> -
> -	if (raz)
> -		return 0;
> -
> -	val = read_sanitised_ftr_reg(id);
> +	u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
>  
>  	switch (id) {
>  	case SYS_ID_AA64PFR0_EL1:
> @@ -1119,6 +1113,14 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
>  	return val;
>  }
>  
> +static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> +		       struct sys_reg_desc const *r, bool raz)
> +{
> +	u32 id = reg_to_encoding(r);
> +
> +	return raz ? 0 : __read_id_reg(vcpu, id);
> +}
> +
>  static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
>  				  const struct sys_reg_desc *r)
>  {
> @@ -1223,9 +1225,8 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
>  /*
>   * cpufeature ID register user accessors
>   *
> - * For now, these registers are immutable for userspace, so no values
> - * are stored, and for set_id_reg() we don't allow the effective value
> - * to be changed.
> + * For now, these registers are immutable for userspace, so for set_id_reg()
> + * we don't allow the effective value to be changed.
>   */
>  static int __get_id_reg(const struct kvm_vcpu *vcpu,
>  			const struct sys_reg_desc *rd, void __user *uaddr,
> @@ -1237,7 +1238,7 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
>  	return reg_to_user(uaddr, &val, id);
>  }
>  
> -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> +static int __set_id_reg(struct kvm_vcpu *vcpu,
>  			const struct sys_reg_desc *rd, void __user *uaddr,
>  			bool raz)
>  {
> @@ -1837,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
>  	if (p->is_write) {
>  		return ignore_write(vcpu, p);
>  	} else {
> -		u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
> -		u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> +		u64 dfr = __read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> +		u64 pfr = __read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
>  		u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
>  
>  		p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
> @@ -2850,3 +2851,30 @@ void kvm_sys_reg_table_init(void)
>  	/* Clear all higher bits. */
>  	cache_levels &= (1 << (i*3))-1;
>  }
> +
> +/*
> + * Set the guest's ID registers that are defined in sys_reg_descs[]
> + * with ID_SANITISED() to the host's sanitized value.
> + */
> +void set_default_id_regs(struct kvm *kvm)
> +{
> +	int i;
> +	u32 id;
> +	const struct sys_reg_desc *rd;
> +	u64 val;
> +
> +	for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> +		rd = &sys_reg_descs[i];
> +		if (rd->access != access_id_reg)
> +			/* Not ID register, or hidden/reserved ID register */
> +			continue;
> +
> +		id = reg_to_encoding(rd);
> +		if (WARN_ON_ONCE(!is_id_reg(id)))
> +			/* Shouldn't happen */
> +			continue;
> +
> +		val = read_sanitised_ftr_reg(id);

I'm a bit confused. Shouldn't the default+sanitized values already use
arm64_ftr_bits_kvm (instead of arm64_ftr_regs)?

> +		kvm->arch.id_regs[IDREG_IDX(id)] = val;
> +	}
> +}
> -- 
> 2.34.1.448.ga2b2bfdf31-goog
> 


From adeep at lexina.in  Tue Jan 25 21:35:00 2022
From: adeep at lexina.in (Vyacheslav)
Date: Wed, 26 Jan 2022 08:35:00 +0300
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-2-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
Message-ID: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>

Hi!

26.01.2022 07:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>   arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index 6b457b2c30a4..aa14ea017a61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -49,6 +49,12 @@
>   			no-map;
>   		};
>   
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
How do I check if we need a similar patch for axg boards?


>   		linux,cma {
>   			compatible = "shared-dma-pool";
>   			reusable;
> 



From reijiw at google.com  Tue Jan 25 22:04:26 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Tue, 25 Jan 2022 22:04:26 -0800
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function
 for an ID register
In-Reply-To: <CA+EHjTx+b0ZVw30riW4OUVP4BCPeJZe+gr5_ycHkPbwU=y7sqA@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-2-reijiw@google.com>
 <CA+EHjTx+b0ZVw30riW4OUVP4BCPeJZe+gr5_ycHkPbwU=y7sqA@mail.gmail.com>
Message-ID: <CAAeT=Fy8AXaM1SGs1wRssTZ9QW9bH-d1d_sCdSrC7EitZLPKBw@mail.gmail.com>

Hi Fuad,

> > +/*
> > + * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
> > + * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
> > + * ARM64_FTR_END (.width == 0).
> > + */
> > +static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,
>
> s/overrite/override

Thank you for catching this. I will fix it.


> > +                                       struct arm64_ftr_bits *new_ftrp)
>
> Should this be const struct arm64_ftr_bits *new_ftrp, which would also
> make it consistent with copy_arm64_ftr_bits()?

Yes, I will make new_ftrp const.

>
> > +{
> > +       struct arm64_ftr_bits *o_ftrp, *n_ftrp;
> > +
> > +       for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
> > +               for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
> > +                       if (o_ftrp->shift == n_ftrp->shift) {
> > +                               *o_ftrp = *n_ftrp;
> > +                               break;
> > +                       }
> > +               }
> > +       }
> > +}
> > +
>
> ...
>
> > +/*
> > + * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
> > + * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
> > + * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
> > + */
> > +static int init_arm64_ftr_bits_kvm(void)
> > +{
> > +       struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
> > +       static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
> > +       int i, j, nent, ret;
> > +
> > +       mutex_lock(&arm64_ftr_bits_kvm_lock);
> > +       if (arm64_ftr_bits_kvm) {
> > +               /* Already initialized */
> > +               ret = 0;
> > +               goto unlock_exit;
> > +       }
> > +
> > +       nent = ARRAY_SIZE(arm64_ftr_regs);
> > +       reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
> > +                                GFP_KERNEL);
> > +       if (!reg_bits_array) {
> > +               ret = ENOMEM;
>
> Should this be -ENOMEM?

Yes, I will fix it.


> > +               goto unlock_exit;
> > +       }
> > +
> > +       /* Copy entries from arm64_ftr_regs to reg_bits_array */
> > +       for (i = 0; i < nent; i++) {
> > +               bits = &reg_bits_array[i];
> > +               bits->sys_id = arm64_ftr_regs[i].sys_id;
> > +               bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
> > +       };
> > +
> > +       /*
> > +        * Override the entries in reg_bits_array with the ones in
> > +        * arm64_ftr_bits_kvm_override.
> > +        */
> > +       for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
> > +               o_bits = &arm64_ftr_bits_kvm_override[i];
> > +               for (j = 0; j < nent; j++) {
> > +                       bits = &reg_bits_array[j];
> > +                       if (bits->sys_id != o_bits->sys_id)
> > +                               continue;
> > +
> > +                       memset(ftr_temp, 0, sizeof(ftr_temp));
> > +
> > +                       /*
> > +                        * Temporary save all entries in o_bits->ftr_bits
> > +                        * to ftr_temp.
> > +                        */
> > +                       copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
> > +
> > +                       /*
> > +                        * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
> > +                        */
> > +                       copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
> > +
> > +                       /*
> > +                        * Override entries in o_bits->ftr_bits with the
> > +                        * saved ones, and update bits->ftr_bits with
> > +                        * o_bits->ftr_bits.
> > +                        */
> > +                       arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
> > +                       bits->ftr_bits = o_bits->ftr_bits;
> > +                       break;
> > +               }
> > +       }
>
> Could you please explain using ftr_temp[] and changing the value in
> arm64_ftr_bits_kvm_override, rather than just
> arm64_ftr_reg_bits_overrite(bits->ftr_bits, o_bits->ftr_bits)?

I would like to maintain the order of the entries in the original
ftr_bits so that (future) functions that work for the original ones
also work for the KVM's.
The copy and override is an easy way to do that.  The same thing can
be done without ftr_temp[], but it would look a bit tricky.

If we assume the order shouldn't matter or entries in ftr_bits
are always in descending order, just changing the value in
arm64_ftr_bits_kvm_override would be a much simpler way though.


>
>
> > +static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
> > +{
> > +       const struct __ftr_reg_bits_entry *ret;
> > +       int err;
> > +
> > +       if (!arm64_ftr_bits_kvm) {
> > +               /* arm64_ftr_bits_kvm is not initialized yet. */
> > +               err = init_arm64_ftr_bits_kvm();
>
> Rather than doing this check, can we just initialize it earlier, maybe
> (indirectly) via kvm_arch_init_vm() or around the same time?

Thank you for the comment.
I will consider when it should be initialized.
( perhaps even earlier than kvm_arch_init_vm())

>
>
> > +               if (err)
> > +                       return NULL;
> > +       }
> > +
> > +       ret = bsearch((const void *)(unsigned long)sys_id,
> > +                     arm64_ftr_bits_kvm,
> > +                     arm64_ftr_bits_kvm_nentries,
> > +                     sizeof(arm64_ftr_bits_kvm[0]),
> > +                     search_cmp_ftr_reg_bits);
> > +       if (ret)
> > +               return ret->ftr_bits;
> > +
> > +       return NULL;
> > +}
> > +
> > +/*
> > + * Check if features (or levels of features) that are indicated in the ID
> > + * register value @val are also indicated in @limit.
> > + * This function is for KVM to check if features that are indicated in @val,
> > + * which will be used as the ID register value for its guest, are supported
> > + * on the host.
> > + * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
> > + * scheme, the function checks if values of the fields in @val are the same
> > + * as the ones in @limit.
> > + */
> > +int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
> > +{
> > +       const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);
> > +       u64 exposed_mask = 0;
> > +
> > +       if (!ftrp)
> > +               return -ENOENT;
> > +
> > +       for (; ftrp->width; ftrp++) {
> > +               s64 ftr_val = arm64_ftr_value(ftrp, val);
> > +               s64 ftr_lim = arm64_ftr_value(ftrp, limit);
> > +
> > +               exposed_mask |= arm64_ftr_mask(ftrp);
> > +
> > +               if (ftr_val == ftr_lim)
> > +                       continue;
>
> At first I thought that this check isn't necessary, it should be
> covered by the check below (arm64_ftr_safe_value. However, I think
> that it's needed for the FTR_HIGHER_OR_ZERO_SAFE case. If my
> understanding is correct, it might be worth adding a comment, or even
> encapsulating this logic in a arm64_is_safe_value() function for
> clarity.

In my understanding, arm64_ftr_safe_value() provides a safe value
when two values are different, and I think there is nothing special
about the usage of this function (This is actually how the function
is used by update_cpu_ftr_reg()).
Without the check, it won't work for FTR_EXACT, but there might be
more in the future.

Perhaps it might be more straightforward to add the equality check
into arm64_ftr_safe_value() ?

>
> > +
> > +               if (ftr_val != arm64_ftr_safe_value(ftrp, ftr_val, ftr_lim))
> > +                       return -E2BIG;
> > +       }
> > +
> > +       /* Make sure that no unrecognized fields are set in @val. */
> > +       if (val & ~exposed_mask)
> > +               return -E2BIG;
> > +
> > +       return 0;
> > +}

Thanks,
Reiji


From miles.chen at mediatek.com  Tue Jan 25 22:04:49 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:04:49 +0800
Subject: [PATCH 13/31] clk: mediatek: pll: Implement unregister API
In-Reply-To: <20220122091731.283592-10-wenst@chromium.org>
References: <20220122091731.283592-10-wenst@chromium.org>
Message-ID: <20220126060449.24874-1-miles.chen@mediatek.com>

> +static void mtk_clk_unregister_pll(struct clk *clk)
> +{
> +	struct clk_hw *hw = __clk_get_hw(clk);
> +	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
> +
> +	clk_unregister(clk);
> +	kfree(pll);
> +}
> +

mtk_clk_unregister_pll() looks different. 
Do we need to check hw before passing it to to_mtk_clk_pll(hw), like
mtk_clk_unregister_mux()?

>  void mtk_clk_register_plls(struct device_node *node,
>  		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
>  {
> @@ -388,4 +397,44 @@ void mtk_clk_register_plls(struct device_node *node,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
>  
> +static __iomem void *mtk_clk_pll_get_base(struct clk *clk,
> +					  const struct mtk_pll_data *data)
> +{
> +	struct clk_hw *hw = __clk_get_hw(clk);
> +	struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
> +
> +	return pll->base_addr - data->reg;
> +}
> +
> +void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
> +			     struct clk_onecell_data *clk_data)
> +{
> +	__iomem void *base = NULL;
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num_plls; i > 0; i--) {
> +		const struct mtk_pll_data *pll = &plls[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[pll->id]))
> +			continue;
> +
> +		/*
> +		 * This is quite ugly but unfortunately the clks don't have
> +		 * any device tied to them, so there's no place to store the
> +		 * pointer to the I/O region base address. We have to fetch
> +		 * it from one of the registered clks.
> +		 */
> +		base = mtk_clk_pll_get_base(clk_data->clks[pll->id], pll);
> +
> +		mtk_clk_unregister_pll(clk_data->clks[pll->id]);
> +		clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
> +	}
> +
> +	iounmap(base);
> +}
> +EXPORT_SYMBOL_GPL(mtk_clk_unregister_plls);
> +
>  MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
> index d01b0c38311d..a889b1e472e7 100644
> --- a/drivers/clk/mediatek/clk-pll.h
> +++ b/drivers/clk/mediatek/clk-pll.h
> @@ -51,5 +51,7 @@ struct mtk_pll_data {
>  void mtk_clk_register_plls(struct device_node *node,
>  			   const struct mtk_pll_data *plls, int num_plls,
>  			   struct clk_onecell_data *clk_data);
> +void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
> +			     struct clk_onecell_data *clk_data);
>  
>  #endif /* __DRV_CLK_MTK_PLL_H */
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:16 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:16 +0800
Subject: [PATCH 0/2] Power: meson-s4: add s4 power domain driver
Message-ID: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>

This patchset adds Power controller driver support for Meson-S4 SoC
Likes Meson-A1, the power domains register only can access in secure world

Shunzhou Jiang (2):
  dt-bindings: power: add Amlogic s4 power domains bindings
  soc: s4: Add support for power domains controller

 .../power/amlogic,meson-sec-pwrc.yaml         |  3 ++-
 drivers/soc/amlogic/meson-secure-pwrc.c       | 21 +++++++++++++++++++
 include/dt-bindings/power/meson-s4-power.h    | 19 +++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/power/meson-s4-power.h

-- 
2.34.1



From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:17 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:17 +0800
Subject: [PATCH 1/2] dt-bindings: power: add Amlogic s4 power domains bindings
In-Reply-To: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
References: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
Message-ID: <20220126061018.705338-2-shunzhou.jiang@amlogic.com>

Add the bindings for the Amlogic Secure power domains, controlling the
secure power domains.

The bindings targets the Amlogic s4, in which the power domains registers
are in secure world.

Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
---
 .../power/amlogic,meson-sec-pwrc.yaml         |  3 ++-
 include/dt-bindings/power/meson-s4-power.h    | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
 create mode 100644 include/dt-bindings/power/meson-s4-power.h

diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
index 5dae04d2936c..7657721a4e96 100644
--- a/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
+++ b/Documentation/devicetree/bindings/power/amlogic,meson-sec-pwrc.yaml
@@ -12,13 +12,14 @@ maintainers:
   - Jianxin Pan <jianxin.pan at amlogic.com>
 
 description: |+
-  Secure Power Domains used in Meson A1/C1 SoCs, and should be the child node
+  Secure Power Domains used in Meson A1/C1/S4 SoCs, and should be the child node
   of secure-monitor.
 
 properties:
   compatible:
     enum:
       - amlogic,meson-a1-pwrc
+      - amlogic,meson-s4-pwrc
 
   "#power-domain-cells":
     const: 1
diff --git a/include/dt-bindings/power/meson-s4-power.h b/include/dt-bindings/power/meson-s4-power.h
new file mode 100644
index 000000000000..462dd2cb938b
--- /dev/null
+++ b/include/dt-bindings/power/meson-s4-power.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2021 Amlogic, Inc.
+ * Author: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_S4_POWER_H
+#define _DT_BINDINGS_MESON_S4_POWER_H
+
+#define PWRC_S4_DOS_HEVC_ID	0
+#define PWRC_S4_DOS_VDEC_ID	1
+#define PWRC_S4_VPU_HDMI_ID	2
+#define PWRC_S4_USB_COMB_ID	3
+#define PWRC_S4_GE2D_ID		4
+#define PWRC_S4_ETH_ID		5
+#define PWRC_S4_DEMOD_ID	6
+#define PWRC_S4_AUDIO_ID	7
+
+#endif
-- 
2.34.1



From shunzhou.jiang at amlogic.com  Tue Jan 25 22:10:18 2022
From: shunzhou.jiang at amlogic.com (Shunzhou Jiang)
Date: Wed, 26 Jan 2022 14:10:18 +0800
Subject: [PATCH 2/2] soc: s4: Add support for power domains controller
In-Reply-To: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
References: <20220126061018.705338-1-shunzhou.jiang@amlogic.com>
Message-ID: <20220126061018.705338-3-shunzhou.jiang@amlogic.com>

Add support s4 Power controller. In s4, power control
registers are in secure domain, and should be accessed by smc.

Signed-off-by: Shunzhou Jiang <shunzhou.jiang at amlogic.com>
---
 drivers/soc/amlogic/meson-secure-pwrc.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/soc/amlogic/meson-secure-pwrc.c b/drivers/soc/amlogic/meson-secure-pwrc.c
index 59bd195fa9c9..8fee01aabab6 100644
--- a/drivers/soc/amlogic/meson-secure-pwrc.c
+++ b/drivers/soc/amlogic/meson-secure-pwrc.c
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <dt-bindings/power/meson-a1-power.h>
+#include <dt-bindings/power/meson-s4-power.h>
 #include <linux/arm-smccc.h>
 #include <linux/firmware/meson/meson_sm.h>
 #include <linux/module.h>
@@ -119,6 +120,17 @@ static struct meson_secure_pwrc_domain_desc a1_pwrc_domains[] = {
 	SEC_PD(RSA,	0),
 };
 
+static struct meson_secure_pwrc_domain_desc s4_pwrc_domains[] = {
+	SEC_PD(S4_DOS_HEVC,	0),
+	SEC_PD(S4_DOS_VDEC,	0),
+	SEC_PD(S4_VPU_HDMI,	GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_USB_COMB,	GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_GE2D,		0),
+	SEC_PD(S4_ETH,		GENPD_FLAG_ALWAYS_ON),
+	SEC_PD(S4_DEMOD,	0),
+	SEC_PD(S4_AUDIO,	0),
+};
+
 static int meson_secure_pwrc_probe(struct platform_device *pdev)
 {
 	int i;
@@ -187,11 +199,20 @@ static struct meson_secure_pwrc_domain_data meson_secure_a1_pwrc_data = {
 	.count = ARRAY_SIZE(a1_pwrc_domains),
 };
 
+static struct meson_secure_pwrc_domain_data meson_secure_s4_pwrc_data = {
+	.domains = s4_pwrc_domains,
+	.count = ARRAY_SIZE(s4_pwrc_domains),
+};
+
 static const struct of_device_id meson_secure_pwrc_match_table[] = {
 	{
 		.compatible = "amlogic,meson-a1-pwrc",
 		.data = &meson_secure_a1_pwrc_data,
 	},
+	{
+		.compatible = "amlogic,meson-s4-pwrc",
+		.data = &meson_secure_s4_pwrc_data,
+	},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, meson_secure_pwrc_match_table);
-- 
2.34.1



From miles.chen at mediatek.com  Tue Jan 25 22:06:20 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:06:20 +0800
Subject: [PATCH 12/31] clk: mediatek: pll: Split definitions into separate
 header file
In-Reply-To: <20220122091731.283592-13-wenst@chromium.org>
References: <20220122091731.283592-13-wenst@chromium.org>
Message-ID: <20220126060620.25823-1-miles.chen@mediatek.com>

> When the PLL type clk was implemented in the MediaTek clk driver
> library, the data structure definitions and function declaration
> were put in the common header file.
> 
> Since it is its own type of clk, and not all platform clk drivers
> utilize it, having the definitions in the common header results
> in wasted cycles during compilation.
> 
> Split out the related definitions and declarations into its own
> header file, and include that only in the platform clk drivers that
> need it.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mt2701.c            |  5 +-
>  drivers/clk/mediatek/clk-mt2712.c            |  3 +-
>  drivers/clk/mediatek/clk-mt6765.c            |  3 +-
>  drivers/clk/mediatek/clk-mt6779.c            |  3 +-
>  drivers/clk/mediatek/clk-mt6797.c            |  3 +-
>  drivers/clk/mediatek/clk-mt7622.c            |  5 +-
>  drivers/clk/mediatek/clk-mt7629.c            |  5 +-
>  drivers/clk/mediatek/clk-mt7986-apmixed.c    |  4 +-
>  drivers/clk/mediatek/clk-mt8135.c            |  3 +-
>  drivers/clk/mediatek/clk-mt8167.c            |  3 +-
>  drivers/clk/mediatek/clk-mt8173.c            |  5 +-
>  drivers/clk/mediatek/clk-mt8183.c            |  3 +-
>  drivers/clk/mediatek/clk-mt8192.c            |  3 +-
>  drivers/clk/mediatek/clk-mt8195-apmixedsys.c |  1 +
>  drivers/clk/mediatek/clk-mt8195-apusys_pll.c |  1 +
>  drivers/clk/mediatek/clk-mt8516.c            |  3 +-
>  drivers/clk/mediatek/clk-mtk.h               | 39 --------------
>  drivers/clk/mediatek/clk-pll.c               |  1 +
>  drivers/clk/mediatek/clk-pll.h               | 55 ++++++++++++++++++++
>  19 files changed, 91 insertions(+), 57 deletions(-)
>  create mode 100644 drivers/clk/mediatek/clk-pll.h
> 
> diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c
> index 695be0f77427..1eb3e4563c3f 100644
> --- a/drivers/clk/mediatek/clk-mt2701.c
> +++ b/drivers/clk/mediatek/clk-mt2701.c
> @@ -10,9 +10,10 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> -#include "clk-mtk.h"
> -#include "clk-gate.h"
>  #include "clk-cpumux.h"
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt2701-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt2712.c b/drivers/clk/mediatek/clk-mt2712.c
> index a3bd9a107209..ff72b9ab945b 100644
> --- a/drivers/clk/mediatek/clk-mt2712.c
> +++ b/drivers/clk/mediatek/clk-mt2712.c
> @@ -13,8 +13,9 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-pll.h"
> +#include "clk-mtk.h"
>  
>  #include <dt-bindings/clock/mt2712-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c
> index d77ea5aff292..24829ca3bd1f 100644
> --- a/drivers/clk/mediatek/clk-mt6765.c
> +++ b/drivers/clk/mediatek/clk-mt6765.c
> @@ -12,9 +12,10 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
>  #include "clk-mux.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt6765-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c
> index 9825385c9f94..7b61664da18f 100644
> --- a/drivers/clk/mediatek/clk-mt6779.c
> +++ b/drivers/clk/mediatek/clk-mt6779.c
> @@ -10,9 +10,10 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> +#include "clk-gate.h"
>  #include "clk-mtk.h"
>  #include "clk-mux.h"
> -#include "clk-gate.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt6779-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c
> index 428eb24ffec5..02259e81625a 100644
> --- a/drivers/clk/mediatek/clk-mt6797.c
> +++ b/drivers/clk/mediatek/clk-mt6797.c
> @@ -9,8 +9,9 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt6797-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt7622.c b/drivers/clk/mediatek/clk-mt7622.c
> index ef5947e15c75..0e1fb30a1e98 100644
> --- a/drivers/clk/mediatek/clk-mt7622.c
> +++ b/drivers/clk/mediatek/clk-mt7622.c
> @@ -11,9 +11,10 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> -#include "clk-mtk.h"
> -#include "clk-gate.h"
>  #include "clk-cpumux.h"
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt7622-clk.h>
>  #include <linux/clk.h> /* for consumer */
> diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
> index a0ee079670c7..c0e023bf31eb 100644
> --- a/drivers/clk/mediatek/clk-mt7629.c
> +++ b/drivers/clk/mediatek/clk-mt7629.c
> @@ -12,9 +12,10 @@
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  
> -#include "clk-mtk.h"
> -#include "clk-gate.h"
>  #include "clk-cpumux.h"
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt7629-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c
> index 98ec3887585f..21d4c82e782a 100644
> --- a/drivers/clk/mediatek/clk-mt7986-apmixed.c
> +++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c
> @@ -10,9 +10,11 @@
>  #include <linux/of_address.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
> -#include "clk-mtk.h"
> +
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
>  #include "clk-mux.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt7986-clk.h>
>  #include <linux/clk.h>
> diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c
> index 9b4b645aea99..09ad272d51f1 100644
> --- a/drivers/clk/mediatek/clk-mt8135.c
> +++ b/drivers/clk/mediatek/clk-mt8135.c
> @@ -11,8 +11,9 @@
>  #include <linux/mfd/syscon.h>
>  #include <dt-bindings/clock/mt8135-clk.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  static DEFINE_SPINLOCK(mt8135_clk_lock);
>  
> diff --git a/drivers/clk/mediatek/clk-mt8167.c b/drivers/clk/mediatek/clk-mt8167.c
> index e5ea10e31799..812b33a57530 100644
> --- a/drivers/clk/mediatek/clk-mt8167.c
> +++ b/drivers/clk/mediatek/clk-mt8167.c
> @@ -12,8 +12,9 @@
>  #include <linux/slab.h>
>  #include <linux/mfd/syscon.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8167-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c
> index 8f898ac476c0..46b7655feeaa 100644
> --- a/drivers/clk/mediatek/clk-mt8173.c
> +++ b/drivers/clk/mediatek/clk-mt8173.c
> @@ -8,9 +8,10 @@
>  #include <linux/of.h>
>  #include <linux/of_address.h>
>  
> -#include "clk-mtk.h"
> -#include "clk-gate.h"
>  #include "clk-cpumux.h"
> +#include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8173-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c
> index 5046852eb0fd..68496554dd3d 100644
> --- a/drivers/clk/mediatek/clk-mt8183.c
> +++ b/drivers/clk/mediatek/clk-mt8183.c
> @@ -11,9 +11,10 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  
> +#include "clk-gate.h"
>  #include "clk-mtk.h"
>  #include "clk-mux.h"
> -#include "clk-gate.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8183-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt8192.c b/drivers/clk/mediatek/clk-mt8192.c
> index cbc7c6dbe0f4..5f998aab3bfd 100644
> --- a/drivers/clk/mediatek/clk-mt8192.c
> +++ b/drivers/clk/mediatek/clk-mt8192.c
> @@ -12,9 +12,10 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  
> +#include "clk-gate.h"
>  #include "clk-mtk.h"
>  #include "clk-mux.h"
> -#include "clk-gate.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8192-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> index 6156ceeed71e..5b1b7dc447eb 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> @@ -5,6 +5,7 @@
>  
>  #include "clk-gate.h"
>  #include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8195-clk.h>
>  #include <linux/of_device.h>
> diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> index f1c84186346e..db449ff877d7 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> @@ -4,6 +4,7 @@
>  // Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
>  
>  #include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8195-clk.h>
>  #include <linux/clk-provider.h>
> diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c
> index 9d4261ecc760..a37143f920ce 100644
> --- a/drivers/clk/mediatek/clk-mt8516.c
> +++ b/drivers/clk/mediatek/clk-mt8516.c
> @@ -11,8 +11,9 @@
>  #include <linux/slab.h>
>  #include <linux/mfd/syscon.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-gate.h"
> +#include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #include <dt-bindings/clock/mt8516-clk.h>
>  
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index bdec7dc5e07a..168220f85489 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -179,45 +179,6 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
>  struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
>  void mtk_free_clk_data(struct clk_onecell_data *clk_data);
>  
> -#define HAVE_RST_BAR	BIT(0)
> -#define PLL_AO		BIT(1)
> -
> -struct mtk_pll_div_table {
> -	u32 div;
> -	unsigned long freq;
> -};
> -
> -struct mtk_pll_data {
> -	int id;
> -	const char *name;
> -	u32 reg;
> -	u32 pwr_reg;
> -	u32 en_mask;
> -	u32 pd_reg;
> -	u32 tuner_reg;
> -	u32 tuner_en_reg;
> -	u8 tuner_en_bit;
> -	int pd_shift;
> -	unsigned int flags;
> -	const struct clk_ops *ops;
> -	u32 rst_bar_mask;
> -	unsigned long fmin;
> -	unsigned long fmax;
> -	int pcwbits;
> -	int pcwibits;
> -	u32 pcw_reg;
> -	int pcw_shift;
> -	u32 pcw_chg_reg;
> -	const struct mtk_pll_div_table *div_table;
> -	const char *parent_name;
> -	u32 en_reg;
> -	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
> -};
> -
> -void mtk_clk_register_plls(struct device_node *node,
> -		const struct mtk_pll_data *plls, int num_plls,
> -		struct clk_onecell_data *clk_data);
> -
>  struct clk *mtk_clk_register_ref2usb_tx(const char *name,
>  			const char *parent_name, void __iomem *reg);
>  
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index f04f724e12e5..64f59554bc9b 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -13,6 +13,7 @@
>  #include <linux/delay.h>
>  
>  #include "clk-mtk.h"
> +#include "clk-pll.h"
>  
>  #define REG_CON0		0
>  #define REG_CON1		4
> diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
> new file mode 100644
> index 000000000000..d01b0c38311d
> --- /dev/null
> +++ b/drivers/clk/mediatek/clk-pll.h
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2014 MediaTek Inc.
> + * Author: James Liao <jamesjj.liao at mediatek.com>
> + */
> +
> +#ifndef __DRV_CLK_MTK_PLL_H
> +#define __DRV_CLK_MTK_PLL_H
> +
> +#include <linux/types.h>
> +
> +struct clk_ops;
> +struct clk_onecell_data;
> +struct device_node;
> +
> +struct mtk_pll_div_table {
> +	u32 div;
> +	unsigned long freq;
> +};
> +
> +#define HAVE_RST_BAR	BIT(0)
> +#define PLL_AO		BIT(1)
> +
> +struct mtk_pll_data {
> +	int id;
> +	const char *name;
> +	u32 reg;
> +	u32 pwr_reg;
> +	u32 en_mask;
> +	u32 pd_reg;
> +	u32 tuner_reg;
> +	u32 tuner_en_reg;
> +	u8 tuner_en_bit;
> +	int pd_shift;
> +	unsigned int flags;
> +	const struct clk_ops *ops;
> +	u32 rst_bar_mask;
> +	unsigned long fmin;
> +	unsigned long fmax;
> +	int pcwbits;
> +	int pcwibits;
> +	u32 pcw_reg;
> +	int pcw_shift;
> +	u32 pcw_chg_reg;
> +	const struct mtk_pll_div_table *div_table;
> +	const char *parent_name;
> +	u32 en_reg;
> +	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
> +};
> +
> +void mtk_clk_register_plls(struct device_node *node,
> +			   const struct mtk_pll_data *plls, int num_plls,
> +			   struct clk_onecell_data *clk_data);
> +
> +#endif /* __DRV_CLK_MTK_PLL_H */
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From wenst at chromium.org  Tue Jan 25 22:18:06 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 26 Jan 2022 14:18:06 +0800
Subject: [PATCH 13/31] clk: mediatek: pll: Implement unregister API
In-Reply-To: <20220126060449.24874-1-miles.chen@mediatek.com>
References: <20220122091731.283592-10-wenst@chromium.org>
 <20220126060449.24874-1-miles.chen@mediatek.com>
Message-ID: <CAGXv+5GKmOrT=yOkadsKVz38vvAj1-1sBN8i86zMLv3yusZeQw@mail.gmail.com>

On Wed, Jan 26, 2022 at 2:04 PM Miles Chen <miles.chen at mediatek.com> wrote:
>
> > +static void mtk_clk_unregister_pll(struct clk *clk)
> > +{
> > +     struct clk_hw *hw = __clk_get_hw(clk);
> > +     struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
> > +
> > +     clk_unregister(clk);
> > +     kfree(pll);
> > +}
> > +
>
> mtk_clk_unregister_pll() looks different.
> Do we need to check hw before passing it to to_mtk_clk_pll(hw), like
> mtk_clk_unregister_mux()?

Good catch.

In theory we should, since __get_clk_hw() would return NULL if clk is NULL.
However the code already does that check before it calls
mtk_clk_unregister_pll(), so the code is safe. We should make everything
consistent though.

I might have written the code on separate days and thus introduced some
discrepancies. I'll fix it in v2.


ChenYu

> >  void mtk_clk_register_plls(struct device_node *node,
> >               const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
> >  {
> > @@ -388,4 +397,44 @@ void mtk_clk_register_plls(struct device_node *node,
> >  }
> >  EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
> >
> > +static __iomem void *mtk_clk_pll_get_base(struct clk *clk,
> > +                                       const struct mtk_pll_data *data)
> > +{
> > +     struct clk_hw *hw = __clk_get_hw(clk);
> > +     struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
> > +
> > +     return pll->base_addr - data->reg;
> > +}
> > +
> > +void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
> > +                          struct clk_onecell_data *clk_data)
> > +{
> > +     __iomem void *base = NULL;
> > +     int i;
> > +
> > +     if (!clk_data)
> > +             return;
> > +
> > +     for (i = num_plls; i > 0; i--) {
> > +             const struct mtk_pll_data *pll = &plls[i - 1];
> > +
> > +             if (IS_ERR_OR_NULL(clk_data->clks[pll->id]))
> > +                     continue;
> > +
> > +             /*
> > +              * This is quite ugly but unfortunately the clks don't have
> > +              * any device tied to them, so there's no place to store the
> > +              * pointer to the I/O region base address. We have to fetch
> > +              * it from one of the registered clks.
> > +              */
> > +             base = mtk_clk_pll_get_base(clk_data->clks[pll->id], pll);
> > +
> > +             mtk_clk_unregister_pll(clk_data->clks[pll->id]);
> > +             clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
> > +     }
> > +
> > +     iounmap(base);
> > +}
> > +EXPORT_SYMBOL_GPL(mtk_clk_unregister_plls);
> > +
> >  MODULE_LICENSE("GPL");
> > diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
> > index d01b0c38311d..a889b1e472e7 100644
> > --- a/drivers/clk/mediatek/clk-pll.h
> > +++ b/drivers/clk/mediatek/clk-pll.h
> > @@ -51,5 +51,7 @@ struct mtk_pll_data {
> >  void mtk_clk_register_plls(struct device_node *node,
> >                          const struct mtk_pll_data *plls, int num_plls,
> >                          struct clk_onecell_data *clk_data);
> > +void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
> > +                          struct clk_onecell_data *clk_data);
> >
> >  #endif /* __DRV_CLK_MTK_PLL_H */
> > --
> > 2.35.0.rc0.227.g00780c9af4-goog
>
>


From wenst at chromium.org  Tue Jan 25 22:32:14 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Wed, 26 Jan 2022 14:32:14 +0800
Subject: [PATCH 11/31] clk: mediatek: mux: Clean up included headers
In-Reply-To: <20220125173836.14548-1-miles.chen@mediatek.com>
References: <20220122091731.283592-12-wenst@chromium.org>
 <20220125173836.14548-1-miles.chen@mediatek.com>
Message-ID: <CAGXv+5GmtbUZdy+0d5igvJrSZSb16ed8=m1YVZCLC0OV1aeXBA@mail.gmail.com>

On Wed, Jan 26, 2022 at 1:38 AM Miles Chen <miles.chen at mediatek.com> wrote:
>
> > Some included headers aren't actually used anywhere, while other headers
> > with the declaration of functions and structures aren't directly
> > included.
> >
> > Get rid of the unused ones, and add the ones that should be included
> > directly.
> >
> > On the header side, replace headers that are included purely for data
> > structure definitions with forward declarations. This decreases the
> > amount of preprocessing and compilation effort required for each
> > inclusion.
>
> Is this inspired by [1]?
> [1] https://lore.kernel.org/lkml/YdIfz+LMewetSaEB at gmail.com/

Yes and no.

When clk-mtk.h was removed from the included headers, many headers had
to be added. Also, clk-mux.h did not include any headers, so if it were
to be used by itself, it probably would not compile.

Using forward declarations for the data structures instead of including the
header files inspired in part by that series though.

ChenYu


From miles.chen at mediatek.com  Tue Jan 25 22:36:43 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:36:43 +0800
Subject: [PATCH 14/31] clk: mediatek: pll: Clean up included headers
In-Reply-To: <20220122091731.283592-15-wenst@chromium.org>
References: <20220122091731.283592-15-wenst@chromium.org>
Message-ID: <20220126063643.11544-1-miles.chen@mediatek.com>

> Some included headers aren't actually used anywhere, while other headers
> with the declaration of functions and structures aren't directly
> included.
> 
> Get rid of the unused ones, and add the ones that should be included
> directly.
> 
> Also, expand the MHZ macro with spelled-out "1000 * 1000" to be able
> to not include clk-mtk.h. The existing ternary operator is rewritten
> in a shortened form to accommodate the expanded macro.

I think MHZ is more human readable than 1000*1000, 
like SZ_4K in linux/sizes.h.

MHZ is also use by other clk-mtxxxx.c (by including clk-mtk.h)
, so maybe we should keep clk-mtk.h?

Miles
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/clk/mediatek/clk-pll.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index 081e0df8203e..9698d1c97cd6 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -4,15 +4,15 @@
>   * Author: James Liao <jamesjj.liao at mediatek.com>
>   */
>  
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> +#include <linux/clk-provider.h>
> +#include <linux/container_of.h>
> +#include <linux/delay.h>
> +#include <linux/err.h>
>  #include <linux/io.h>
>  #include <linux/module.h>
> +#include <linux/of_address.h>
>  #include <linux/slab.h>
> -#include <linux/clkdev.h>
> -#include <linux/delay.h>
>  
> -#include "clk-mtk.h"
>  #include "clk-pll.h"
>  
>  #define REG_CON0		0
> @@ -162,7 +162,7 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
>  static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv,
>  		u32 freq, u32 fin)
>  {
> -	unsigned long fmin = pll->data->fmin ? pll->data->fmin : (1000 * MHZ);
> +	unsigned long fmin = pll->data->fmin ?: (1000 * 1000 * 1000);
>  	const struct mtk_pll_div_table *div_table = pll->data->div_table;
>  	u64 _pcw;
>  	int ibits;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From alexander.stein at ew.tq-group.com  Tue Jan 25 22:42:24 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 07:42:24 +0100
Subject: (EXT) [PATCH V4 01/11] arm64: dts: imx8mq-tqma8mq: Remove
 redundant vpu reference
In-Reply-To: <20220125171129.472775-2-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-2-aford173@gmail.com>
Message-ID: <5426078.mvXUDI8C0e@steina-w>

Am Dienstag, 25. Januar 2022, 18:11:18 CET schrieb Adam Ford:
> The vpu is enabled by default, so there is no need to manually
> enable it.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>

Reviewed-by: Alexander Stein <alexander.stein at ew.tq-group.com>

> diff --git a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi index
> 8aedcddfeab8..38ffcd145b33 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq-tqma8mq.dtsi
> @@ -272,10 +272,6 @@ &usdhc1 {
>  	status = "okay";
>  };
> 
> -&vpu {
> -	status = "okay";
> -};
> -
>  /* Attention: wdog reset forcing POR needs baseboard support */
>  &wdog1 {
>  	status = "okay";






From alexander.stein at ew.tq-group.com  Tue Jan 25 22:45:15 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 07:45:15 +0100
Subject: (EXT) [PATCH V4 09/11] dt-bindings: media: nxp,
 imx8mq-vpu: Add support for G1 on imx8mm
In-Reply-To: <20220125171129.472775-10-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-10-aford173@gmail.com>
Message-ID: <8346301.DvuYhMxLoT@steina-w>

Am Dienstag, 25. Januar 2022, 18:11:26 CET schrieb Adam Ford:
> The i.MX8M mini appears to have a similar G1 decoder but the
> post-processing isn't present, so different compatible flag is required.
> Since all the other parameters are the same with imx8mq, just add
> the new compatible flag to nxp,imx8mq-vpu.yaml.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Ezequiel Garcia <ezequiel at vanguardiasur.com.ar>
> 
> diff --git a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml index
> 9c28d562112b..7dc13a4b1805 100644
> --- a/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> +++ b/Documentation/devicetree/bindings/media/nxp,imx8mq-vpu.yaml
> @@ -5,7 +5,7 @@
>  $id: "http://devicetree.org/schemas/media/nxp,imx8mq-vpu.yaml#"
>  $schema: "http://devicetree.org/meta-schemas/core.yaml#"
> 
> -title: Hantro G1/G2 VPU codecs implemented on i.MX8MQ SoCs
> +title: Hantro G1/G2 VPU codecs implemented on i.MX8M SoCs
> 
>  maintainers:
>    - Philipp Zabel <p.zabel at pengutronix.de>
> @@ -20,6 +20,7 @@ properties:
>          deprecated: true
>        - const: nxp,imx8mq-vpu-g1
>        - const: nxp,imx8mq-vpu-g2
> +      - const: nxp,imx8mm-vpu-g1
> 
>    reg:
>      maxItems: 1

Is there no rule that items are sorted alphabetically?

Regards,
Alexander






From reijiw at google.com  Tue Jan 25 22:46:42 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Tue, 25 Jan 2022 22:46:42 -0800
Subject: [RFC PATCH v4 03/26] KVM: arm64: Introduce struct id_reg_info
In-Reply-To: <CA+EHjTx65scqNVvHci6fge7C5qQ=fiqqHKGwOvOKySQwsCy8Jg@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-4-reijiw@google.com>
 <CA+EHjTx65scqNVvHci6fge7C5qQ=fiqqHKGwOvOKySQwsCy8Jg@mail.gmail.com>
Message-ID: <CAAeT=Fzi2JSuVGijM0x7_w8osRWMFUupz3r10NduO6r5hN+HKw@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 8:29 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:28 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > This patch lays the groundwork to make ID registers writable.
> >
> > Introduce struct id_reg_info for an ID register to manage the
> > register specific control of its value for the guest, and provide set
> > of functions commonly used for ID registers to make them writable.
> >
> > The id_reg_info is used to do register specific initialization,
> > validation of the ID register and etc.  Not all ID registers must
> > have the id_reg_info. ID registers that don't have the id_reg_info
> > are handled in a common way that is applied to all ID registers.
> >
> > At present, changing an ID register from userspace is allowed only
> > if the ID register has the id_reg_info, but that will be changed
> > by the following patches.
> >
> > No ID register has the structure yet and the following patches
> > will add the id_reg_info for some ID registers.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 243 ++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 230 insertions(+), 13 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 80dc62f98ef0..971018288bee 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -265,6 +265,101 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
> >                 return read_zero(vcpu, p);
> >  }
> >
> > +struct id_reg_info {
> > +       u32     sys_reg;        /* Register ID */
>
> Nit: Why not have the comment above, as for the other fields of this struct?

Yes, I will fix that.
(I placed the comment there just because the comment was short
 enough to place it on the right side)

>
> > +
> > +       /*
> > +        * Limit value of the register for a vcpu. The value is the sanitized
> > +        * system value with bits cleared for unsupported features for the
> > +        * guest.
> > +        */
>
> I think that rather than saying "with bits cleared for unsupported
> features", it might be better to rephrase along the lines of "with
> bits indicating" or "set/cleared to indicate", so that it applies to
> signed fields as well.

Thank you for the suggestion ! I will fix the comment.

>
> > +       u64     vcpu_limit_val;
> > +
> > +       /* Fields that we don't to validate by arm64_check_features. */
>
> Nit: Remove "to".

I will fix it.

>
> > +       u64     ignore_mask;
> > +
> > +       /* Initialization function of the id_reg_info */
> > +       void (*init)(struct id_reg_info *id_reg);
> > +       /*
> > +        * This is an optional ID register specific validation function.
> > +        * When userspace tries to set the ID register, arm64_check_features()
> > +        * will check if the requested value indicates any features that cannot
> > +        * be supported by KVM on the host.  But, some ID register fields need
> > +        * a special checking, and this function can be used for such fields.
> > +        * e.g. When SVE is configured for a vCPU by KVM_ARM_VCPU_INIT,
> > +        * ID_AA64PFR0_EL1.SVE shouldn't be set to 0 for the vCPU.
> > +        * The validation function for ID_AA64PFR0_EL1 could be used to check
> > +        * the field is consistent with SVE configuration.
> > +        */
> > +       int (*validate)(struct kvm_vcpu *vcpu, const struct id_reg_info *id_reg,
> > +                       u64 val);
> > +
> > +       /*
> > +        * Return a bitmask of the vCPU's ID register fields that are not
> > +        * synced with saved (per VM) ID register value, which usually
> > +        * indicates opt-in CPU features that is not configured for the vCPU.
>
> Nit: s/is/are

I will fix it.

>
>
> > +        * ID registers are saved per VM, but some opt-in CPU features can
> > +        * be configured per vCPU.  The saved (per VM) values for such
> > +        * features are for vCPUs with the features (and zero for
> > +        * vCPUs without the features).
> > +        * Return value of this function is used to handle such fields
> > +        * for per vCPU ID register read/write request with saved per VM
> > +        * ID register.  See the __write_id_reg's comment for more detail.
> > +        */
> > +       u64 (*vcpu_mask)(const struct kvm_vcpu *vcpu,
> > +                        const struct id_reg_info *id_reg);
> > +};
> > +
> > +static void id_reg_info_init(struct id_reg_info *id_reg)
> > +{
> > +       id_reg->vcpu_limit_val = read_sanitised_ftr_reg(id_reg->sys_reg);
> > +       if (id_reg->init)
>
> If there is an id_reg then the init function is necessary, isn't it?
> Otherwise it doesn't seem to add more than the default handling. If
> that's right, should we instead ensure that init is always set?

The init function is optional (maybe I should comment that).

>
> > +               id_reg->init(id_reg);
> > +}
> > +
> > +/*
> > + * An ID register that needs special handling to control the value for the
> > + * guest must have its own id_reg_info in id_reg_info_table.
> > + * (i.e. the reset value is different from the host's sanitized value,
> > + * the value is affected by opt-in features, some fields need specific
> > + * validation, etc.)
> > + */
> > +#define        GET_ID_REG_INFO(id)     (id_reg_info_table[IDREG_IDX(id)])
> > +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
> > +
> > +static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> > +{
> > +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> > +       u64 limit, tmp_val;
> > +       int err;
> > +
> > +       if (id_reg) {
> > +               limit = id_reg->vcpu_limit_val;
> > +               /*
> > +                * Replace the fields that are indicated in ignore_mask with
> > +                * the value in the limit to not have arm64_check_features()
> > +                * check the field in @val.
> > +                */
> > +               tmp_val = val & ~id_reg->ignore_mask;
> > +               tmp_val |= (limit & id_reg->ignore_mask);
> > +       } else {
> > +               limit = read_sanitised_ftr_reg(id);
> > +               tmp_val = val;
> > +       }
> > +
> > +       /* Check if the value indicates any feature that is not in the limit. */
> > +       err = arm64_check_features(id, tmp_val, limit);
> > +       if (err)
> > +               return err;
> > +
> > +       if (id_reg && id_reg->validate)
> > +               /* Run the ID register specific validity check. */
> > +               err = id_reg->validate(vcpu, id_reg, val);
> > +
> > +       return err;
> > +}
> > +
> >  /*
> >   * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
> >   * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
> > @@ -1061,9 +1156,81 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
> >         return true;
> >  }
> >
> > +static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
> > +{
> > +       return kvm->arch.id_regs[IDREG_IDX(id)];
> > +}
> > +
> > +static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> > +                            u64 preserve_mask)
> > +{
> > +       u64 old, new;
> > +
> > +       mutex_lock(&kvm->lock);
> > +
> > +       old = kvm->arch.id_regs[IDREG_IDX(id)];
> > +
> > +       /* Preserve the value at the bit position set in preserve_mask */
> > +       new = old & preserve_mask;
> > +       new |= (val & ~preserve_mask);
> > +
> > +       /* Don't allow to modify ID register value after KVM_RUN on any vCPUs */
> > +       if (kvm_vm_has_started(kvm) && new != old)
> > +               return -EBUSY;
>
> This path doesn't release the lock. I see that it gets fixed in a
> future patch, but it might be good to fix it here...

Thank you for catching it ! Yes, I will fix this.

>
> > +
> > +       WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
> > +       mutex_unlock(&kvm->lock);
> > +
> > +       return 0;
> > +}
> > +
> > +static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
> > +{
> > +       return modify_kvm_id_reg(kvm, id, val, 0);
> > +}
> > +
> > +
> > +/*
> > + * KVM basically forces all vCPUs of the guest to have a uniform value for
> > + * each ID register (, which means KVM_SET_ONE_REG for a vCPU affects all
> > + * the vCPUs of the guest), and the id_regs[] of kvm_arch holds values
> > + * of ID registers for the guest.  However, there is an exception for
> > + * ID register fields corresponding to CPU features that can be
> > + * configured per vCPU by KVM_ARM_VCPU_INIT, or etc (e.g. PMUv3, SVE, etc).
> > + * For such fields, all vCPUs that have the feature will have a non-zero
> > + * uniform value (, which can be updated by userspace), but the vCPUs that
>
> Nit: uneven nesting of parentheses and commas :)

I will fix it.


> > + * don't have the feature will have zero for the fields.
> > + * Values that @id_regs holds are for vCPUs that have such features.  So,
> > + * to get the ID register value for a vCPU that doesn't have those features,
> > + * the corresponding fields in id_regs[] needs to be cleared.
> > + * A bitmask of the fields are provided by id_reg_info's vcpu_mask(), and
> > + * __write_id_reg() and __read_id_reg() take care of those fields using
> > + * the bitmask.
> > + */
> > +static int __write_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> > +{
> > +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> > +       u64 mask = 0;
> > +
> > +       if (id_reg && id_reg->vcpu_mask)
> > +               mask = id_reg->vcpu_mask(vcpu, id_reg);
> > +
> > +       /*
> > +        * Update the ID register for the guest with @val, except for fields
> > +        * that are set in the mask, which indicates fields for opt-in
> > +        * features that are not configured for the vCPU.
> > +        */
> > +       return modify_kvm_id_reg(vcpu->kvm, id, val, mask);
> > +}
> > +
> >  static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> >  {
> > -       u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
> > +       const struct id_reg_info *id_reg = GET_ID_REG_INFO(id);
> > +       u64 val = read_kvm_id_reg(vcpu->kvm, id);
> > +
> > +       if (id_reg && id_reg->vcpu_mask)
> > +               /* Clear fields for opt-in features that are not configured. */
> > +               val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
> >         switch (id) {
> >         case SYS_ID_AA64PFR0_EL1:
> > @@ -1222,12 +1389,7 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> >         return 0;
> >  }
> >
> > -/*
> > - * cpufeature ID register user accessors
> > - *
> > - * For now, these registers are immutable for userspace, so for set_id_reg()
> > - * we don't allow the effective value to be changed.
> > - */
> > +/* cpufeature ID register user accessors */
> >  static int __get_id_reg(const struct kvm_vcpu *vcpu,
> >                         const struct sys_reg_desc *rd, void __user *uaddr,
> >                         bool raz)
> > @@ -1238,11 +1400,31 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
> >         return reg_to_user(uaddr, &val, id);
> >  }
> >
> > +/*
> > + * Check if the given id indicates AArch32 ID register encoding.
> > + */
> > +static bool is_aarch32_id_reg(u32 id)
> > +{
> > +       u32 crm, op2;
> > +
> > +       if (!is_id_reg(id))
> > +               return false;
> > +
> > +       crm = sys_reg_CRm(id);
> > +       op2 = sys_reg_Op2(id);
> > +       if (crm == 1 || crm == 2 || (crm == 3 && (op2 != 3 && op2 != 7)))
>
> Consistent with the Arm ARM "Table D12-2 System instruction encodings
> for non-Debug System register accesses"
>
> > +               /* AArch32 ID register */
> > +               return true;
> > +
> > +       return false;
> > +}
> > +
> >  static int __set_id_reg(struct kvm_vcpu *vcpu,
> >                         const struct sys_reg_desc *rd, void __user *uaddr,
> >                         bool raz)
> >  {
> >         const u64 id = sys_reg_to_index(rd);
> > +       u32 encoding = reg_to_encoding(rd);
> >         int err;
> >         u64 val;
> >
> > @@ -1250,11 +1432,28 @@ static int __set_id_reg(struct kvm_vcpu *vcpu,
> >         if (err)
> >                 return err;
> >
> > -       /* This is what we mean by invariant: you can't change it. */
> > -       if (val != read_id_reg(vcpu, rd, raz))
> > +       if (val == read_id_reg(vcpu, rd, raz))
> > +               /* The value is same as the current value. Nothing to do. */
> > +               return 0;
> > +
> > +       /*
> > +        * Don't allow to modify the register's value if the register is raz,
> > +        * or the reg doesn't have the id_reg_info.
> > +        */
> > +       if (raz || !GET_ID_REG_INFO(encoding))
> >                 return -EINVAL;
> >
> > -       return 0;
> > +       /*
> > +        * Skip the validation of AArch32 ID registers if the system doesn't
> > +        * 32bit EL0 (their value are UNKNOWN).
> > +        */
> > +       if (system_supports_32bit_el0() || !is_aarch32_id_reg(encoding)) {
> > +               err = validate_id_reg(vcpu, encoding, val);
> > +               if (err)
> > +                       return err;
> > +       }
> > +
> > +       return __write_id_reg(vcpu, encoding, val);
> >  }
> >
> >  static int get_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
> > @@ -2816,6 +3015,20 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> >         return write_demux_regids(uindices);
> >  }
> >
> > +static void id_reg_info_init_all(void)
> > +{
> > +       int i;
> > +       struct id_reg_info *id_reg;
> > +
> > +       for (i = 0; i < ARRAY_SIZE(id_reg_info_table); i++) {
> > +               id_reg = (struct id_reg_info *)id_reg_info_table[i];
> > +               if (!id_reg)
> > +                       continue;
> > +
> > +               id_reg_info_init(id_reg);
> > +       }
> > +}
> > +
> >  void kvm_sys_reg_table_init(void)
> >  {
> >         unsigned int i;
> > @@ -2850,6 +3063,8 @@ void kvm_sys_reg_table_init(void)
> >                         break;
> >         /* Clear all higher bits. */
> >         cache_levels &= (1 << (i*3))-1;
> > +
> > +       id_reg_info_init_all();
> >  }
> >
> >  /*
> > @@ -2862,11 +3077,12 @@ void set_default_id_regs(struct kvm *kvm)
> >         u32 id;
> >         const struct sys_reg_desc *rd;
> >         u64 val;
> > +       struct id_reg_info *idr;
> >
> >         for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> >                 rd = &sys_reg_descs[i];
> >                 if (rd->access != access_id_reg)
> > -                       /* Not ID register, or hidden/reserved ID register */
> > +                       /* Not ID register or hidden/reserved ID register */
> >                         continue;
> >
> >                 id = reg_to_encoding(rd);
> > @@ -2874,7 +3090,8 @@ void set_default_id_regs(struct kvm *kvm)
> >                         /* Shouldn't happen */
> >                         continue;
> >
> > -               val = read_sanitised_ftr_reg(id);
> > -               kvm->arch.id_regs[IDREG_IDX(id)] = val;
> > +               idr = GET_ID_REG_INFO(id);
> > +               val = idr ? idr->vcpu_limit_val : read_sanitised_ftr_reg(id);
> > +               (void)write_kvm_id_reg(kvm, id, val);
>
> Rather than ignoring the return value of write_kvm_id_reg(), wouldn't
> it be better if set_default_id_regs were to propagate it back to
> kvm_arch_init_vm in case there's a problem?

Since write_kvm_id_reg() should never return an error for this
case, returning an error to kvm_arch_init_vm() adds a practically
unnecessary error handling, which I would like to avoid.
So, how about putting WARN_ON_ONCE on its return value ?

Thanks,
Reiji


From alim.akhtar at samsung.com  Tue Jan 25 22:50:51 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 26 Jan 2022 12:20:51 +0530
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <4cfcde38-50cb-646a-0d17-c2cb2977a2e4@canonical.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
 <4cfcde38-50cb-646a-0d17-c2cb2977a2e4@canonical.com>
Message-ID: <063501d81281$10e5b3c0$32b11b40$@samsung.com>

Hi Krzysztof

>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Tuesday, January 25, 2022 10:56 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com;
>sboyd at kernel.org
>Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
>
>On 25/01/2022 18:12, Krzysztof Kozlowski wrote:
>> On 24/01/2022 15:16, Alim Akhtar wrote:
>>> Adds basic support for the Tesla Full Self-Driving (FSD) SoC. This
>>> SoC contains three clusters of four Cortex-A72 CPUs, as well as
>>> several IPs.
>>>
>>> Patches 1 to 9 provide support for the clock controller (which is
>>> designed similarly to Exynos SoCs).
>>>
>>> The remaining changes provide pinmux support, initial device tree support.
>>>
>>> - Changes since v4
>>> * fixed 'make dtbs_check' warnings on patch 14/16
>>>
>>> - Changes since v3
>>> * Addressed Stefen's review comments on patch 14/16
>>> * Fixed kernel test robot warning on patch 04/16
>>> * rebsaed this series on Krzysztof's pinmux new binding schema work
>>> [1]
>>>
>>> - Changes since v2
>>> * Addressed Krzysztof's and Stephen's review comments
>>> * Added Reviewed-by and Acked-by tags
>>> * Rebased on next-20220120
>>>
>>> - Changes since v1
>>> * fixed make dt_binding_check error as pointed by Rob
>>> * Addressed Krzysztof's and Rob's review comments
>>> * Added Reviewed-by and Acked-by tags
>>> * Dropped SPI, MCT and ADC from this series (to be posted in small
>>> sets)
>>>
>>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and
>>> ExynosAutov9 wake-ups") [1]
>>> https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/l
>>> og/?h=for-next
>>>
>>>
>>
>> Thanks, applied DTS/soc and pinctrl patches.
>>
>> I expect Sylwester will pick up the clock ones. Otherwise please let
>> me know to pick it up as well.
>
>I forgot that clock macros are used in DTS. This does not compile and I cannot
>take drivers into DTS branch.
>
>Alim,
>DTS changes dropped. Please resend with the same trick we did for
>Exynos850 board - hard-coded clock IDs as defines. See:
>
>https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/diff/arch/arm6
>4/boot/dts/exynos/exynos850.dtsi?h=samsung-dt64-5.17-
>2&id=e3493220fd3e474abcdcefbe14fb60485097ce06
>
Ok, I will resend patch 14 and 15 (DTS changes) only as suggested above.

>
>Best regards,
>Krzysztof



From alim.akhtar at samsung.com  Tue Jan 25 22:52:44 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 26 Jan 2022 12:22:44 +0530
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
Message-ID: <063601d81281$5492d620$fdb88260$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Tuesday, January 25, 2022 10:42 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com;
>sboyd at kernel.org
>Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
>
>On 24/01/2022 15:16, Alim Akhtar wrote:
>> Adds basic support for the Tesla Full Self-Driving (FSD) SoC. This SoC
>> contains three clusters of four Cortex-A72 CPUs, as well as several
>> IPs.
>>
>> Patches 1 to 9 provide support for the clock controller (which is
>> designed similarly to Exynos SoCs).
>>
>> The remaining changes provide pinmux support, initial device tree support.
>>
>> - Changes since v4
>> * fixed 'make dtbs_check' warnings on patch 14/16
>>
>> - Changes since v3
>> * Addressed Stefen's review comments on patch 14/16
>> * Fixed kernel test robot warning on patch 04/16
>> * rebsaed this series on Krzysztof's pinmux new binding schema work
>> [1]
>>
>> - Changes since v2
>> * Addressed Krzysztof's and Stephen's review comments
>> * Added Reviewed-by and Acked-by tags
>> * Rebased on next-20220120
>>
>> - Changes since v1
>> * fixed make dt_binding_check error as pointed by Rob
>> * Addressed Krzysztof's and Rob's review comments
>> * Added Reviewed-by and Acked-by tags
>> * Dropped SPI, MCT and ADC from this series (to be posted in small
>> sets)
>>
>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and
>> ExynosAutov9 wake-ups") [1]
>> https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/lo
>> g/?h=for-next
>>
>>
>
>Thanks, applied DTS/soc and pinctrl patches.
>
Thanks Krzysztof

>I expect Sylwester will pick up the clock ones. Otherwise please let me know
>to pick it up as well.
>
Hi Sylwester, hope you will be taking clock changes, or let Krzysztof know otherwise.
Thanks

>
>Best regards,
>Krzysztof



From miles.chen at mediatek.com  Tue Jan 25 22:55:32 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:55:32 +0800
Subject: [PATCH 15/31] clk: mediatek: Implement
 mtk_clk_unregister_fixed_clks() API
In-Reply-To: <20220122091731.283592-16-wenst@chromium.org>
References: <20220122091731.283592-16-wenst@chromium.org>
Message-ID: <20220126065532.22463-1-miles.chen@mediatek.com>

> mtk_clk_register_fixed_clks(), as the name suggests, is used to register
> a given list of fixed rate clks. However it is lacking a counterpart
> unregister API.
> 
> Implement said unregister API so that the various clock platform drivers
> can utilize it to do proper unregistration, cleanup and removal.
> 
> In the header file, the register function's declaration is also
> reformatted to fit code style guidelines.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 20 ++++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  6 ++++--
>  2 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 0c5db3c71fdd..7c0d5706eed7 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -80,6 +80,26 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
>  
> +void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> +				   struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_fixed_clk *rc = &clks[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> +			continue;
> +
> +		clk_unregister_fixed_rate(clk_data->clks[rc->id]);
> +		clk_data->clks[rc->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(mtk_clk_unregister_fixed_clks);
> +
>  void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
>  		int num, struct clk_onecell_data *clk_data)
>  {
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 168220f85489..cc7f920eabb4 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -34,8 +34,10 @@ struct mtk_fixed_clk {
>  		.rate = _rate,				\
>  	}
>  
> -void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
> -		int num, struct clk_onecell_data *clk_data);
> +void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> +				 struct clk_onecell_data *clk_data);
> +void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> +				   struct clk_onecell_data *clk_data);
>  
>  struct mtk_fixed_factor {
>  	int id;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Tue Jan 25 22:56:54 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:56:54 +0800
Subject: [PATCH 16/31] clk: mediatek: Implement
 mtk_clk_unregister_factors() API
In-Reply-To: <20220122091731.283592-17-wenst@chromium.org>
References: <20220122091731.283592-17-wenst@chromium.org>
Message-ID: <20220126065654.23309-1-miles.chen@mediatek.com>

> mtk_clk_register_factors(), as the name suggests, is used to register
> a given list of fixed factor clks. However it is lacking a counterpart
> unregister API.
> 
> Implement said unregister API so that the various clock platform drivers
> can utilize it to do proper unregistration, cleanup and removal.
> 
> In the header file, the register function's declaration is also
> reformatted to fit code style guidelines.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>
Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 20 ++++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  6 ++++--
>  2 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 7c0d5706eed7..b267b2f04b84 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -126,6 +126,26 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
>  
> +void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
> +				struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_fixed_factor *ff = &clks[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> +			continue;
> +
> +		clk_unregister_fixed_factor(clk_data->clks[ff->id]);
> +		clk_data->clks[ff->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(mtk_clk_unregister_factors);
> +
>  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  		void __iomem *base, spinlock_t *lock)
>  {
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index cc7f920eabb4..4db1a97c1250 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -55,8 +55,10 @@ struct mtk_fixed_factor {
>  		.div = _div,				\
>  	}
>  
> -void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> -		int num, struct clk_onecell_data *clk_data);
> +void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
> +			      struct clk_onecell_data *clk_data);
> +void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
> +				struct clk_onecell_data *clk_data);
>  
>  struct mtk_composite {
>  	int id;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From alim.akhtar at gmail.com  Tue Jan 25 22:58:58 2022
From: alim.akhtar at gmail.com (Alim Akhtar)
Date: Wed, 26 Jan 2022 12:28:58 +0530
Subject: [PATCH 01/12] arm64: dts: exynos: add USB DWC3 supplies to
 Espresso board
In-Reply-To: <20220123111644.25540-2-krzysztof.kozlowski@canonical.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
 <20220123111644.25540-2-krzysztof.kozlowski@canonical.com>
Message-ID: <CAGOxZ51zavNVpvUv0C17Cit+pdkERC70m5Ez3ELGpFh8tGDozQ@mail.gmail.com>

Hi Krzysztof

On Mon, Jan 24, 2022 at 1:34 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> Add required voltage regulators for USB DWC3 block on Exynos7 Espresso
> board.  Due to lack of schematics of Espresso board, the choice of
> regulators is approximate.  What bindings call VDD10, for Exynos7 should
> be actually called VDD09 (0.9 V).  Use regulators with a matching
> voltage range based on vendor sources for Meizu Pro 5 M576 handset (also
> with Exynos7420).
>

I checked Espresso board schematic, it is 0.9V for the USB and supplied by LDO4

> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  arch/arm64/boot/dts/exynos/exynos7-espresso.dts | 5 +++++
>  arch/arm64/boot/dts/exynos/exynos7.dtsi         | 2 +-
>  2 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> index 125c03f351d9..4c45e689d34a 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos7-espresso.dts
> @@ -412,6 +412,11 @@ &ufs {
>         status = "okay";
>  };
>
> +&usbdrd {
> +       vdd10-supply = <&ldo4_reg>;
> +       vdd33-supply = <&ldo6_reg>;
> +};
> +
>  &usbdrd_phy {
>         vbus-supply = <&usb30_vbus_reg>;
>         vbus-boost-supply = <&usb3drd_boost_5v>;
> diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> index c3efbc8add38..01b4210d8b62 100644
> --- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
> +++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
> @@ -672,7 +672,7 @@ usbdrd_phy: phy at 15500000 {
>                         #phy-cells = <1>;
>                 };
>
> -               usbdrd3 {
> +               usbdrd: usb {
>                         compatible = "samsung,exynos7-dwusb3";
>                         clocks = <&clock_fsys0 ACLK_USBDRD300>,
>                                <&clock_fsys0 SCLK_USBDRD300_SUSPENDCLK>,
> --
> 2.32.0
>


-- 
Regards,
Alim


From miles.chen at mediatek.com  Tue Jan 25 22:58:57 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 14:58:57 +0800
Subject: [PATCH 17/31] clk: mediatek: Implement
 mtk_clk_unregister_divider_clks() API
In-Reply-To: <20220122091731.283592-18-wenst@chromium.org>
References: <20220122091731.283592-18-wenst@chromium.org>
Message-ID: <20220126065857.24513-1-miles.chen@mediatek.com>

> mtk_clk_register_divider_clks(), as the name suggests, is used to register
> a given list of divider clks. However it is lacking a counterpart
> unregister API.
> 
> Implement said unregister API so that the various clock platform drivers
> can utilize it to do proper unregistration, cleanup and removal.
> 
> In the header file, the register function's declaration is also
> reformatted to fit code style guidelines.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mtk.c | 19 +++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  8 +++++---
>  2 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index b267b2f04b84..3a6dfe445e63 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -286,6 +286,25 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
>  	}
>  }
>  
> +void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
> +				 struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_clk_divider *mcd = &mcds[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
> +			continue;
> +
> +		clk_unregister_divider(clk_data->clks[mcd->id]);
> +		clk_data->clks[mcd->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +
>  int mtk_clk_simple_probe(struct platform_device *pdev)
>  {
>  	const struct mtk_clk_desc *mcd;
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 4db1a97c1250..e3ae22fb0334 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -176,9 +176,11 @@ struct mtk_clk_divider {
>  		.div_width = _width,				\
>  }
>  
> -void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
> -			int num, void __iomem *base, spinlock_t *lock,
> -				struct clk_onecell_data *clk_data);
> +void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
> +			       void __iomem *base, spinlock_t *lock,
> +			       struct clk_onecell_data *clk_data);
> +void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
> +				 struct clk_onecell_data *clk_data);
>  
>  struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num);
>  void mtk_free_clk_data(struct clk_onecell_data *clk_data);
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From quic_jinlmao at quicinc.com  Tue Jan 25 23:07:38 2022
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Wed, 26 Jan 2022 15:07:38 +0800
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <20220121171552.GA1811357@p14s>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
 <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
 <20220121171552.GA1811357@p14s>
Message-ID: <24c09945-bcda-81e4-f53c-af871f696094@quicinc.com>

Hi Mathieu,

Good afternoon.

On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
> Hey Jinlong,
>
> On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
>> Hi Mathieu,
>>
>> Good Day.
>>
>> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
>>> [...]
>>>
>>>>>>> +
>>>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>>>> +{
>>>>>>> +    static int traceid = TPDM_TRACE_ID_START;
>>>>>>> +
>>>>>>> +    drvdata->traceid = traceid++;
>>>>>>> +}
>>>>>> I have been specific on how to properly do this in the last revision.  Given the
>>>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>>>
>>>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>>>> process it before the holidays.
>>>>>>
>>>>>> Thanks,
>>>>>> Mathieu
>>>>> Hi Mathieu,
>>>>>
>>>>> Sorry, not addressed your previous comments here.
>>>>>
>>>>> For the trace id, each coresight component has 7 bits to store the trace
>>>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>>>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>>>> Architecture specification v3.0
>>>>
>>> Correct
>>>
>>>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>>>> our internal device. About 80 ids are already used.
>>>>>
>>>>> Some components have fixed trace id in HW. If we use functions below to
>>>>> count the trace id, there will be conflict to other components.
>>>>>
>>>>> Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
>>>>> components ? And handle trace ids in its' own driver ?
>>>>>
>>>> This will limit systems to 15 cores - some have more!
>>>>
>>> Correct
>>>
>>>>> static inline int coresight_get_system_trace_id(int id)
>>>>> {
>>>>>            /* Start system IDs above the highest per CPU trace ID. */
>>>>>            return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>>>> }
>>> Looking at my own suggestion again this won't work since it returns the same traceID
>>> when called multiple times.
>>>
>>> For this patchset and _without_ taking into account internal devices that have
>>> their traceID set in HW:
>>>
>>> 1. Define a bitmask that is 7 bit wide.
>> Should it be a 128 bit wide bitmask? (0--127)?
> Yes, you are correct.
>
>>> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
>>> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
>>> first available bit after cpumask_last(cpu_possible_mask) + 1.
>> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
>> Return the first zero bit position as the trace id and set the bit.
> I need to clarify something with Mike on this - I will get back to you on
> Monday.
Do you have more comments on this ?
>
>>> 4. Define a new function called coresight_put_system_trace_id(int id) that
>>> clears the bit in the mask corresponding to @id.
>>>
>>> For now that should work.
>>>
>>>>> static inline int coresight_get_trace_id(int cpu)
>>>>> {
>>>>>        /*
>>>>>         * A trace ID of value 0 is invalid, so let's start at some
>>>>>         * random value that fits in 7 bits and go from there.  Since
>>>>>         * the common convention is to have data trace IDs be I(N) + 1,
>>>>>         * set instruction trace IDs as a function of the CPU number.
>>>>>         */
>>>>>        return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>>>> }
>>>>>
>>>> This fixed relationship between cpu and trace ID is used in the perf
>>>> tooling to populate the elements in the perf.data file to correctly
>>>> allow association between CPU and trace data, and thus allow correct
>>>> trace decode.
>>> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
>>> perf header - theoretically we should be able to change the allocation scheme
>>> without impacting the decoding process.
>>>
>>>> It should be possible to create another more dynamic mapping scheme -
>>>> but this must include a way to support the perf requirements too.
>>>>
>>> TraceIDs have been a lurking problem for as long as the subsystem has existed.
>>> For now what I have suggested above should be sufficient to provide an
>>> in-between solution that doesn't hold back this patchset.
>>>
>>> That being said, we need to start thinking about the best way to do this.  I
>>> will put a patchset together in the new year that aims in that direction.
>>>
>>>> Regards
>>>>
>>>> Mike
>>>>
>>>>> Thanks
>>>>>
>>>>> Jinlong Mao
>>>>>
>>>>>>> +
>>>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>>> +{
>>>>>>> +    struct device *dev = &adev->dev;
>>>>>>> +    struct coresight_platform_data *pdata;
>>>>>>> +    struct tpdm_drvdata *drvdata;
>>>>>>> +    struct coresight_desc desc = { 0 };
>>>>>>> +
>>>>>>> +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>>>> +    if (!desc.name)
>>>>>>> +            return -ENOMEM;
>>>>>>> +    pdata = coresight_get_platform_data(dev);
>>>>>>> +    if (IS_ERR(pdata))
>>>>>>> +            return PTR_ERR(pdata);
>>>>>>> +    adev->dev.platform_data = pdata;
>>>>>>> +
>>>>>>> +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>>>> +    if (!drvdata)
>>>>>>> +            return -ENOMEM;
>>>>>>> +    drvdata->dev = &adev->dev;
>>>>>>> +    dev_set_drvdata(dev, drvdata);
>>>>>>> +
>>>>>>> +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>>>> +    if (!drvdata->base)
>>>>>>> +            return -ENOMEM;
>>>>>>> +
>>>>>>> +    mutex_init(&drvdata->lock);
>>>>>>> +
>>>>>>> +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>>>> +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>>>> +    desc.ops = &tpdm_cs_ops;
>>>>>>> +    desc.pdata = adev->dev.platform_data;
>>>>>>> +    desc.dev = &adev->dev;
>>>>>>> +    drvdata->csdev = coresight_register(&desc);
>>>>>>> +    if (IS_ERR(drvdata->csdev))
>>>>>>> +            return PTR_ERR(drvdata->csdev);
>>>>>>> +
>>>>>>> +    tpdm_init_default_data(drvdata);
>>>>>>> +    pm_runtime_put(&adev->dev);
>>>>>>> +
>>>>>>> +    return 0;
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>>>> +{
>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>>>> +
>>>>>>> +    coresight_unregister(drvdata->csdev);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static struct amba_id tpdm_ids[] = {
>>>>>>> +    {
>>>>>>> +            .id = 0x000f0e00,
>>>>>>> +            .mask = 0x000fff00,
>>>>>>> +    },
>>>>>>> +    { 0, 0},
>>>>>>> +};
>>>>>>> +
>>>>>>> +static struct amba_driver tpdm_driver = {
>>>>>>> +    .drv = {
>>>>>>> +            .name   = "coresight-tpdm",
>>>>>>> +            .owner  = THIS_MODULE,
>>>>>>> +            .suppress_bind_attrs = true,
>>>>>>> +    },
>>>>>>> +    .probe          = tpdm_probe,
>>>>>>> +    .id_table       = tpdm_ids,
>>>>>>> +};
>>>>>>> +
>>>>>>> +module_amba_driver(tpdm_driver);
>>>>>>> +
>>>>>>> +MODULE_LICENSE("GPL v2");
>>>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..980ae90ff1c8
>>>>>>> --- /dev/null
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> @@ -0,0 +1,31 @@
>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>> +/*
>>>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>>> + */
>>>>>>> +
>>>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>> +
>>>>>>> +/* Default value of the traceid */
>>>>>>> +#define TPDM_TRACE_ID_START 128
>>>>>>> +
>>>>>>> +/**
>>>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>>>> + * @base:       memory mapped base address for this component.
>>>>>>> + * @dev:        The device entity associated to this component.
>>>>>>> + * @csdev:      component vitals needed by the framework.
>>>>>>> + * @lock:       lock for the enable value.
>>>>>>> + * @enable:     enable status of the component.
>>>>>>> + * @traceid:    value of the current ID for this component.
>>>>>>> + */
>>>>>>> +
>>>>>>> +struct tpdm_drvdata {
>>>>>>> +    void __iomem            *base;
>>>>>>> +    struct device           *dev;
>>>>>>> +    struct coresight_device *csdev;
>>>>>>> +    struct mutex            lock;
>>>>>>> +    bool                    enable;
>>>>>>> +    int                     traceid;
>>>>>>> +};
>>>>>>> +
>>>>>>> +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>>>> --- a/include/linux/coresight.h
>>>>>>> +++ b/include/linux/coresight.h
>>>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>>>>        CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>>>>        CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>>>>        CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>>>> +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>>>>     };
>>>>>>>
>>>>>>>     enum coresight_dev_subtype_helper {
>>>>>>> --
>>>>>>> 2.17.1
>>>>>>>
>>>>
>>>> -- 
>>>> Mike Leach
>>>> Principal Engineer, ARM Ltd.
>>>> Manchester Design Centre. UK


From zajec5 at gmail.com  Tue Jan 25 23:07:45 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 26 Jan 2022 08:07:45 +0100
Subject: [PATCH REBASED 2/2] dt-bindings: nvmem: cells: add MAC address cell
In-Reply-To: <20220126070745.32305-1-zajec5@gmail.com>
References: <20220125180114.12286-1-zajec5@gmail.com>
 <20220126070745.32305-1-zajec5@gmail.com>
Message-ID: <20220126070745.32305-2-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This adds support for describing details of NVMEM cell containing MAC
address. Those are often device specific and could be nicely stored in
DT.

Initial documentation includes support for describing:
1. Cell data format (e.g. Broadcom's NVRAM uses ASCII to store MAC)
2. Reversed bytes flash (required for i.MX6/i.MX7 OCOTP support)
3. Source for multiple addresses (very common in home routers)

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/nvmem/cells/mac-address.yaml     | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml b/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml
new file mode 100644
index 000000000000..f8d19e87cdf0
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/cells/mac-address.yaml
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/cells/mac-address.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM cell containing a MAC address
+
+maintainers:
+  - Rafa? Mi?ecki <rafal at milecki.pl>
+
+properties:
+  compatible:
+    const: mac-address
+
+  format:
+    description: |
+      Some NVMEM cells contain MAC in a non-binary format.
+
+      ASCII should be specified if MAC is string formatted like:
+      - "01:23:45:67:89:AB" (30 31 3a 32 33 3a 34 35 3a 36 37 3a 38 39 3a 41 42)
+      - "01-23-45-67-89-AB"
+      - "0123456789AB"
+    enum:
+      - ascii
+
+  reversed-bytes:
+    type: boolean
+    description: |
+      MAC is stored in reversed bytes order. Example:
+      Stored value: AB 89 67 45 23 01
+      Actual MAC: 01 23 45 67 89 AB
+
+  base-address:
+    type: boolean
+    description: |
+      Marks NVMEM cell as provider of multiple addresses that are relative to
+      the one actually stored physically. Respective addresses can be requested
+      by specifying cell index of NVMEM cell.
+
+allOf:
+  - $ref: cell.yaml#
+  - if:
+      required:
+        - base-address
+    then:
+      properties:
+        "#nvmem-cell-cells":
+          const: 1
+      required:
+        - "#nvmem-cell-cells"
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    partitions {
+        compatible = "fixed-partitions";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        partition at f00000 {
+            compatible = "nvmem-cells";
+            label = "calibration";
+            reg = <0xf00000 0x100000>;
+            ranges = <0 0xf00000 0x100000>;
+            #address-cells = <1>;
+            #size-cells = <1>;
+
+            mac at 100 {
+                compatible = "mac-address";
+                reg = <0x100 0x6>;
+            };
+
+            mac at 200 {
+                compatible = "mac-address";
+                reg = <0x200 0x6>;
+                reversed-bytes;
+            };
+
+            mac at 300 {
+                compatible = "mac-address";
+                reg = <0x300 0x11>;
+                format = "ascii";
+            };
+
+            mac at 400 {
+                compatible = "mac-address";
+                reg = <0x400 0x6>;
+                base-address;
+                #nvmem-cell-cells = <1>;
+            };
+        };
+    };
-- 
2.31.1



From zajec5 at gmail.com  Tue Jan 25 23:07:44 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 26 Jan 2022 08:07:44 +0100
Subject: [PATCH REBASED 1/2] dt-bindings: nvmem: extract NVMEM cell to
 separated file
In-Reply-To: <20220125180114.12286-1-zajec5@gmail.com>
References: <20220125180114.12286-1-zajec5@gmail.com>
Message-ID: <20220126070745.32305-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This will allow adding binding for more specific cells and reusing
(sharing) common code.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../devicetree/bindings/nvmem/cells/cell.yaml | 34 +++++++++++++++++++
 .../devicetree/bindings/nvmem/nvmem.yaml      | 22 +-----------
 2 files changed, 35 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/cells/cell.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/cells/cell.yaml b/Documentation/devicetree/bindings/nvmem/cells/cell.yaml
new file mode 100644
index 000000000000..adfc2e639f43
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/cells/cell.yaml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/cells/cell.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM cell
+
+maintainers:
+  - Srinivas Kandagatla <srinivas.kandagatla at linaro.org>
+
+description: NVMEM cell is a data entry of NVMEM device.
+
+properties:
+  reg:
+    maxItems: 1
+    description:
+      Offset and size in bytes within the storage device.
+
+  bits:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    items:
+      - minimum: 0
+        maximum: 7
+        description:
+          Offset in bit within the address range specified by reg.
+      - minimum: 1
+        description:
+          Size in bit within the address range specified by reg.
+
+required:
+  - reg
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
index 43ed7e32e5ac..b79b51e98ee8 100644
--- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml
+++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml
@@ -41,27 +41,7 @@ properties:
 
 patternProperties:
   "@[0-9a-f]+(,[0-7])?$":
-    type: object
-
-    properties:
-      reg:
-        maxItems: 1
-        description:
-          Offset and size in bytes within the storage device.
-
-      bits:
-        $ref: /schemas/types.yaml#/definitions/uint32-array
-        items:
-          - minimum: 0
-            maximum: 7
-            description:
-              Offset in bit within the address range specified by reg.
-          - minimum: 1
-            description:
-              Size in bit within the address range specified by reg.
-
-    required:
-      - reg
+    $ref: cells/cell.yaml#
 
 additionalProperties: true
 
-- 
2.31.1



From miles.chen at mediatek.com  Tue Jan 25 23:06:09 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 15:06:09 +0800
Subject: [PATCH 18/31] clk: mediatek: Implement
 mtk_clk_unregister_composites() API
In-Reply-To: <20220122091731.283592-19-wenst@chromium.org>
References: <20220122091731.283592-19-wenst@chromium.org>
Message-ID: <20220126070609.28749-1-miles.chen@mediatek.com>

> mtk_clk_register_composites(), as the name suggests, is used to register
> a given list of composite clks. However it is lacking a counterpart
> unregister API.
> 
> Implement said unregister API so that the various clock platform drivers
> can utilize it to do proper unregistration, cleanup and removal.
> 
> In the header file, the register function's declaration is also
> reformatted to fit code style guidelines.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 41 ++++++++++++++++++++++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  2 ++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 3a6dfe445e63..2150ed8678e0 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -233,6 +233,27 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  	return ERR_PTR(ret);
>  }
>  
> +static void mtk_clk_unregister_composite(struct clk *clk)
> +{
> +	struct clk_hw *hw = __clk_get_hw(clk);
> +	struct clk_composite *composite = to_clk_composite(hw);
> +	struct clk_mux *mux = NULL;
> +	struct clk_gate *gate = NULL;
> +	struct clk_divider *div = NULL;

Like mtk_clk_unregister_pll(clk), let's check !hw for consistency
of clk unregister functions.

thanks,
Miles
> +
> +	if (composite->mux_hw)
> +		mux = to_clk_mux(composite->mux_hw);
> +	if (composite->gate_hw)
> +		gate = to_clk_gate(composite->gate_hw);
> +	if (composite->rate_hw)
> +		div = to_clk_divider(composite->rate_hw);
> +
> +	clk_unregister_composite(clk);
> +	kfree(div);
> +	kfree(gate);
> +	kfree(mux);
> +}
> +
>  void mtk_clk_register_composites(const struct mtk_composite *mcs,
>  		int num, void __iomem *base, spinlock_t *lock,
>  		struct clk_onecell_data *clk_data)
> @@ -259,6 +280,26 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
>  
> +void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
> +				   struct clk_onecell_data *clk_data)
> +{
> +	int i;
> +
> +	if (!clk_data)
> +		return;
> +
> +	for (i = num; i > 0; i--) {
> +		const struct mtk_composite *mc = &mcs[i - 1];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mc->id]))
> +			continue;
> +
> +		mtk_clk_unregister_composite(clk_data->clks[mc->id]);
> +		clk_data->clks[mc->id] = ERR_PTR(-ENOENT);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(mtk_clk_unregister_composites);
> +
>  void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
>  			int num, void __iomem *base, spinlock_t *lock,
>  				struct clk_onecell_data *clk_data)
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index e3ae22fb0334..3c3a934f53cd 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -153,6 +153,8 @@ struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  void mtk_clk_register_composites(const struct mtk_composite *mcs,
>  		int num, void __iomem *base, spinlock_t *lock,
>  		struct clk_onecell_data *clk_data);
> +void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
> +				   struct clk_onecell_data *clk_data);
>  
>  struct mtk_clk_divider {
>  	int id;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From christianshewitt at gmail.com  Tue Jan 25 23:12:42 2022
From: christianshewitt at gmail.com (Christian Hewitt)
Date: Wed, 26 Jan 2022 11:12:42 +0400
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
 <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
Message-ID: <343C247D-4F10-4E88-B971-5A1F41A2C892@gmail.com>


> On 26 Jan 2022, at 9:35 am, Vyacheslav <adeep at lexina.in> wrote:
> 
> Hi!
> 
> 26.01.2022 07:49, Christian Hewitt wrote:
>> Add an additional reserved memory region for the BL32 trusted firmware
>> present in many devices that boot from Amlogic vendor u-boot.
>> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
>> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
>> ---
>>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>>  1 file changed, 6 insertions(+)
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> index 6b457b2c30a4..aa14ea017a61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> @@ -49,6 +49,12 @@
>>  			no-map;
>>  		};
>>  +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
>> +		secmon_reserved_bl32: secmon at 5300000 {
>> +			reg = <0x0 0x05300000 0x0 0x2000000>;
>> +			no-map;
>> +		};
>> +
> How do I check if we need a similar patch for axg boards?

Are they booting using Amlogic (vendor) u-boot sources that
include bl32.img in the FIP signing recipe?

If booting from upstream u-boot, like JetHome boards, it?s
nothing to worry about.

Christian



From miles.chen at mediatek.com  Tue Jan 25 23:13:49 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 15:13:49 +0800
Subject: [PATCH 19/31] clk: mediatek: Add mtk_clk_simple_remove()
In-Reply-To: <20220122091731.283592-20-wenst@chromium.org>
References: <20220122091731.283592-20-wenst@chromium.org>
Message-ID: <20220126071349.1118-1-miles.chen@mediatek.com>

> In commit c58cd0e40ffa ("clk: mediatek: Add mtk_clk_simple_probe() to
> simplify clock providers"), a generic probe function was added to
> simplify clk drivers that only needed to support clk gates. However due
> to the lack of unregister APIs, a corresponding remove function was not
> added.
> 
> Now that the unregister APIs have been implemented, add aforementioned
> remove function to make it complete.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 15 +++++++++++++++
>  drivers/clk/mediatek/clk-mtk.h |  1 +
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index 2150ed8678e0..cd76e1d80242 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -369,6 +369,8 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
>  	if (r)
>  		goto free_data;
>  
> +	platform_set_drvdata(pdev, clk_data);
> +
>  	return r;
>  
>  free_data:
> @@ -376,4 +378,17 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +int mtk_clk_simple_remove(struct platform_device *pdev)
> +{
> +	const struct mtk_clk_desc *mcd = of_device_get_match_data(&pdev->dev);
> +	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
> +	mtk_free_clk_data(clk_data);
> +
> +	return 0;
> +}
> +
>  MODULE_LICENSE("GPL");
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 3c3a934f53cd..4fa658f5d934 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -202,5 +202,6 @@ struct mtk_clk_desc {
>  };
>  
>  int mtk_clk_simple_probe(struct platform_device *pdev);
> +int mtk_clk_simple_remove(struct platform_device *pdev);
>  
>  #endif /* __DRV_CLK_MTK_H */
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:24 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:24 +0800
Subject: [PATCH v15 04/12] dt-bindings: display: mediatek: dsc: add yaml for
 mt8195 SoC binding
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-5-jason-jh.lin@mediatek.com>

1. Add mediatek,dsc.yaml to describe DSC module in details.
2. Add mt8195 SoC binding to mediatek,dsc.yaml.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,dsc.yaml        | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
new file mode 100644
index 000000000000..1ec083eff824
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dsc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: mediatek display DSC controller
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  The DSC standard is a specification of the algorithms used for
+  compressing and decompressing image display streams, including
+  the specification of the syntax and semantics of the compressed
+  video bit stream. DSC is designed for real-time systems with
+  real-time compression, transmission, decompression and Display.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8195-disp-dsc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: DSC Wrapper Clock
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments
+      defined in this property, such as phandle of gce, subsys id,
+      register offset and size.
+      Each subsys id is mapping to a base address of display function blocks
+      register which is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dsc0: disp_dsc_wrap at 1c009000 {
+        compatible = "mediatek,mt8195-disp-dsc";
+        reg = <0 0x1c009000 0 0x1000>;
+        interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+        clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c00XXXX 0x9000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:28 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:28 +0800
Subject: [PATCH v15 08/12] soc: mediatek: add mtk-mmsys support for mt8195
 vdosys0
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-9-jason-jh.lin@mediatek.com>

Add mt8195 vdosys0 clock driver name and routing table to
the driver data of mtk-mmsys.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
This patch is base on [1]
[1] soc: mediatek: mmsys: add mt8192 mmsys support
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=524857

The vdosys1 impelmentation patch [2]
[2] soc: mediatek: add mtk-mmsys support for mt8195 vdosys1
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210906071539.12953-7-nancy.lin at mediatek.com/
---
 drivers/soc/mediatek/mt8195-mmsys.h    | 130 +++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c       |  11 +++
 include/linux/soc/mediatek/mtk-mmsys.h |   9 ++
 3 files changed, 150 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

diff --git a/drivers/soc/mediatek/mt8195-mmsys.h b/drivers/soc/mediatek/mt8195-mmsys.h
new file mode 100644
index 000000000000..24a3afe23bc8
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-mmsys.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8195_MMSYS_H
+#define __SOC_MEDIATEK_MT8195_MMSYS_H
+
+#define MT8195_VDO0_OVL_MOUT_EN					0xf14
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(0)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_WDMA0			BIT(1)
+#define MT8195_MOUT_DISP_OVL0_TO_DISP_OVL1			BIT(2)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1			BIT(4)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_WDMA1			BIT(5)
+#define MT8195_MOUT_DISP_OVL1_TO_DISP_OVL0			BIT(6)
+
+#define MT8195_VDO0_SEL_IN					0xf34
+#define MT8195_SEL_IN_VPP_MERGE_FROM_MASK			GENMASK(1, 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT		(0 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_DISP_DITHER1		(1 << 0)
+#define MT8195_SEL_IN_VPP_MERGE_FROM_VDO1_VIRTUAL0		(2 << 0)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_MASK			GENMASK(4, 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0		(0 << 4)
+#define MT8195_SEL_IN_DSC_WRAP0_IN_FROM_VPP_MERGE		(1 << 4)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_MASK			GENMASK(5, 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_DISP_DITHER1		(0 << 5)
+#define MT8195_SEL_IN_DSC_WRAP1_IN_FROM_VPP_MERGE		(1 << 5)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_MASK			GENMASK(8, 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_VPP_MERGE		(0 << 8)
+#define MT8195_SEL_IN_SINA_VIRTUAL0_FROM_DSC_WRAP1_OUT		(1 << 8)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_MASK			GENMASK(9, 9)
+#define MT8195_SEL_IN_SINB_VIRTUAL0_FROM_DSC_WRAP0_OUT		(0 << 9)
+#define MT8195_SEL_IN_DP_INTF0_FROM_MASK			GENMASK(13, 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_DSC_WRAP1_OUT		(0 << 0)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE			(1 << 12)
+#define MT8195_SEL_IN_DP_INTF0_FROM_VDO1_VIRTUAL0		(2 << 12)
+#define MT8195_SEL_IN_DSI0_FROM_MASK				GENMASK(16, 16)
+#define MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT			(0 << 16)
+#define MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0			(1 << 16)
+#define MT8195_SEL_IN_DSI1_FROM_MASK				GENMASK(17, 17)
+#define MT8195_SEL_IN_DSI1_FROM_DSC_WRAP1_OUT			(0 << 17)
+#define MT8195_SEL_IN_DSI1_FROM_VPP_MERGE			(1 << 17)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_MASK			GENMASK(20, 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_DISP_OVL1			(0 << 20)
+#define MT8195_SEL_IN_DISP_WDMA1_FROM_VPP_MERGE			(1 << 20)
+#define MT8195_SEL_IN_DSC_WRAP1_FROM_MASK			GENMASK(21, 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DSC_WRAP1_IN		(0 << 21)
+#define MT8195_SEL_IN_DSC_WRAP1_OUT_FROM_DISP_DITHER1		(1 << 21)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_MASK			GENMASK(22, 22)
+#define MT8195_SEL_IN_DISP_WDMA0_FROM_DISP_OVL0			(0 << 22)
+
+#define MT8195_VDO0_SEL_OUT					0xf38
+#define MT8195_SOUT_DISP_DITHER0_TO_MASK			BIT(0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN		(0 << 0)
+#define MT8195_SOUT_DISP_DITHER0_TO_DSI0			(1 << 0)
+#define MT8195_SOUT_DISP_DITHER1_TO_MASK			GENMASK(2, 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_IN		(0 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_VPP_MERGE			(1 << 1)
+#define MT8195_SOUT_DISP_DITHER1_TO_DSC_WRAP1_OUT		(2 << 1)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_MASK			GENMASK(4, 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_VPP_MERGE			(0 << 4)
+#define MT8195_SOUT_VDO1_VIRTUAL0_TO_DP_INTF0			(1 << 4)
+#define MT8195_SOUT_VPP_MERGE_TO_MASK				GENMASK(10, 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSI1				(0 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DP_INTF0			(1 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_SINA_VIRTUAL0			(2 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DISP_WDMA1			(3 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP0_IN			(4 << 8)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN_MASK		GENMASK(11, 11)
+#define MT8195_SOUT_VPP_MERGE_TO_DSC_WRAP1_IN			(0 << 11)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_MASK			GENMASK(13, 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0			(0 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_SINB_VIRTUAL0		(1 << 12)
+#define MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE			(2 << 12)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_MASK			GENMASK(17, 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DSI1			(0 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_DP_INTF0			(1 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_SINA_VIRTUAL0		(2 << 16)
+#define MT8195_SOUT_DSC_WRAP1_OUT_TO_VPP_MERGE			(3 << 16)
+
+static const struct mtk_mmsys_routes mmsys_mt8195_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		MT8195_MOUT_DISP_OVL0_TO_DISP_RDMA0
+	}, {
+		DDP_COMPONENT_OVL1, DDP_COMPONENT_RDMA1,
+		MT8195_VDO0_OVL_MOUT_EN, MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1,
+		MT8195_MOUT_DISP_OVL1_TO_DISP_RDMA1
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_VPP_MERGE_FROM_MASK,
+		MT8195_SEL_IN_VPP_MERGE_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DP_INTF0_FROM_MASK,
+		MT8195_SEL_IN_DP_INTF0_FROM_VPP_MERGE
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSC_WRAP0_IN_FROM_MASK,
+		MT8195_SEL_IN_DSC_WRAP0_IN_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_MASK,
+		MT8195_SEL_IN_DSI0_FROM_DSC_WRAP0_OUT
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_IN, MT8195_SEL_IN_DSI0_FROM_MASK,
+		MT8195_SEL_IN_DSI0_FROM_DISP_DITHER0
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSC0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_MASK,
+		MT8195_SOUT_DISP_DITHER0_TO_DSC_WRAP0_IN
+	}, {
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DISP_DITHER0_TO_MASK,
+		MT8195_SOUT_DISP_DITHER0_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_DSI0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_MASK,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_DSI0
+	}, {
+		DDP_COMPONENT_DSC0, DDP_COMPONENT_MERGE0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_DSC_WRAP0_OUT_TO_MASK,
+		MT8195_SOUT_DSC_WRAP0_OUT_TO_VPP_MERGE
+	}, {
+		DDP_COMPONENT_MERGE0, DDP_COMPONENT_DP_INTF0,
+		MT8195_VDO0_SEL_OUT, MT8195_SOUT_VPP_MERGE_TO_MASK,
+		MT8195_SOUT_VPP_MERGE_TO_DP_INTF0
+	}
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 5f79c7e039ad..5865d268c5b4 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -18,6 +18,7 @@
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
 #include "mt8192-mmsys.h"
+#include "mt8195-mmsys.h"
 #include "mt8365-mmsys.h"
 
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
@@ -66,6 +67,12 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.clk_driver = "clk-mt8195-vdo0",
+	.routes = mmsys_mt8195_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
+};
+
 static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
 	.clk_driver = "clk-mt8365-mm",
 	.routes = mt8365_mmsys_routing_table,
@@ -391,6 +398,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8192-mmsys",
 		.data = &mt8192_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-vdosys0",
+		.data = &mt8195_vdosys0_driver_data,
+	},
 	{
 		.compatible = "mediatek,mt8365-mmsys",
 		.data = &mt8365_mmsys_driver_data,
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
index 45e77d1cd6c1..c0ba22ad7229 100644
--- a/include/linux/soc/mediatek/mtk-mmsys.h
+++ b/include/linux/soc/mediatek/mtk-mmsys.h
@@ -23,13 +23,22 @@ enum mtk_ddp_comp_id {
 	DDP_COMPONENT_COLOR0,
 	DDP_COMPONENT_COLOR1,
 	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DP_INTF0,
 	DDP_COMPONENT_DPI0,
 	DDP_COMPONENT_DPI1,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_DSC1,
 	DDP_COMPONENT_DSI0,
 	DDP_COMPONENT_DSI1,
 	DDP_COMPONENT_DSI2,
 	DDP_COMPONENT_DSI3,
 	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_MERGE1,
+	DDP_COMPONENT_MERGE2,
+	DDP_COMPONENT_MERGE3,
+	DDP_COMPONENT_MERGE4,
+	DDP_COMPONENT_MERGE5,
 	DDP_COMPONENT_OD0,
 	DDP_COMPONENT_OD1,
 	DDP_COMPONENT_OVL0,
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:32 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:32 +0800
Subject: [PATCH v15 12/12] drm/mediatek: add mediatek-drm of vdosys0 support
 for mt8195
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-13-jason-jh.lin@mediatek.com>

Add driver data of mt8195 vdosys0 to mediatek-drm and the sub driver.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
rebase on series [1]

[1] drm/mediatek: add support for mediatek SOC MT8192
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489
---
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c |  6 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.c   | 28 ++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
index d41a3970b944..77c952bdc88c 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
+++ b/drivers/gpu/drm/mediatek/mtk_disp_rdma.c
@@ -357,6 +357,10 @@ static const struct mtk_disp_rdma_data mt8192_rdma_driver_data = {
 	.fifo_size = 5 * SZ_1K,
 };
 
+static const struct mtk_disp_rdma_data mt8195_rdma_driver_data = {
+	.fifo_size = 1920,
+};
+
 static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	{ .compatible = "mediatek,mt2701-disp-rdma",
 	  .data = &mt2701_rdma_driver_data},
@@ -366,6 +370,8 @@ static const struct of_device_id mtk_disp_rdma_driver_dt_match[] = {
 	  .data = &mt8183_rdma_driver_data},
 	{ .compatible = "mediatek,mt8192-disp-rdma",
 	  .data = &mt8192_rdma_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = &mt8195_rdma_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_disp_rdma_driver_dt_match);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 2f33fe8ad46b..274a5bb10851 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -177,6 +177,19 @@ static const enum mtk_ddp_comp_id mt8192_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8195_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSC0,
+	DDP_COMPONENT_MERGE0,
+	DDP_COMPONENT_DP_INTF0,
+};
+
 static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
 	.main_path = mt2701_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt2701_mtk_ddp_main),
@@ -228,6 +241,11 @@ static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8192_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
+	.main_path = mt8195_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
+};
+
 static int mtk_drm_kms_init(struct drm_device *drm)
 {
 	struct mtk_drm_private *private = drm->dev_private;
@@ -447,12 +465,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_DITHER },
 	{ .compatible = "mediatek,mt8183-disp-dither",
 	  .data = (void *)MTK_DISP_DITHER },
+	{ .compatible = "mediatek,mt8195-disp-dsc",
+	  .data = (void *)MTK_DISP_DSC },
 	{ .compatible = "mediatek,mt8167-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8173-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
 	{ .compatible = "mediatek,mt8183-disp-gamma",
 	  .data = (void *)MTK_DISP_GAMMA, },
+	{ .compatible = "mediatek,mt8195-disp-merge",
+	  .data = (void *)MTK_DISP_MERGE },
 	{ .compatible = "mediatek,mt2701-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt2712-disp-mutex",
@@ -465,6 +487,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
 	  .data = (void *)MTK_DISP_OD },
 	{ .compatible = "mediatek,mt2701-disp-ovl",
@@ -499,6 +523,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8192-disp-rdma",
 	  .data = (void *)MTK_DISP_RDMA },
+	{ .compatible = "mediatek,mt8195-disp-rdma",
+	  .data = (void *)MTK_DISP_RDMA },
 	{ .compatible = "mediatek,mt8173-disp-ufoe",
 	  .data = (void *)MTK_DISP_UFOE },
 	{ .compatible = "mediatek,mt8173-disp-wdma",
@@ -535,6 +561,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8183_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8192-mmsys",
 	  .data = &mt8192_mmsys_driver_data},
+	{.compatible = "mediatek,mt8195-vdosys0",
+	  .data = &mt8195_vdosys0_driver_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_drm_of_ids);
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:21 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:21 +0800
Subject: [PATCH v15 01/12] dt-bindings: arm: mediatek: mmsys: add power and
 gce properties
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-2-jason-jh.lin@mediatek.com>

Power:
1. Add description for power-domains property.

GCE:
1. Add description for mboxes property.
2. Add description for mediatek,gce-client-reg property.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../bindings/arm/mediatek/mediatek,mmsys.yaml | 30 ++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 763c62323a74..474bcf9c250d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -40,6 +40,30 @@ properties:
   reg:
     maxItems: 1
 
+  power-domains:
+    description:
+      A phandle and PM domain specifier as defined by bindings
+      of the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  mboxes:
+    description:
+      Using mailbox to communicate with GCE, it should have this
+      property and list of phandle, mailbox specifiers. See
+      Documentation/devicetree/bindings/mailbox/mtk-gce.txt for details.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+  mediatek,gce-client-reg:
+    description:
+      The register of client driver can be configured by gce with 4 arguments
+      defined in this property, such as phandle of gce, subsys id,
+      register offset and size.
+      Each subsys id is mapping to a base address of display function blocks
+      register which is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
   "#clock-cells":
     const: 1
 
@@ -57,7 +81,11 @@ examples:
   - |
     mmsys: syscon at 14000000 {
         compatible = "mediatek,mt8173-mmsys", "syscon";
-        reg = <0x14000000 0x1000>;
+        reg = <0 0x14000000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         #clock-cells = <1>;
         #reset-cells = <1>;
+        mboxes = <&gce 0 CMDQ_THR_PRIO_HIGHEST>,
+                 <&gce 1 CMDQ_THR_PRIO_HIGHEST>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>;
     };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:30 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:30 +0800
Subject: [PATCH v15 10/12] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-11-jason-jh.lin@mediatek.com>

DSC is designed for real-time systems with real-time compression,
transmission, decompression and display.
The DSC standard is a specification of the algorithms used for
compressing and decompressing image display streams, including
the specification of the syntax and semantics of the compressed
video bit stream.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
rebase on series [1]

[1] drm/mediatek: add support for mediatek SOC MT8192
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489
---
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c | 47 +++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |  1 +
 2 files changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index b4b682bc1991..90b289b5f9a4 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -40,6 +40,12 @@
 #define DITHER_LSB_ERR_SHIFT_G(x)		(((x) & 0x7) << 12)
 #define DITHER_ADD_LSHIFT_G(x)			(((x) & 0x7) << 4)
 
+#define DISP_REG_DSC_CON			0x0000
+#define DSC_EN					BIT(0)
+#define DSC_DUAL_INOUT				BIT(2)
+#define DSC_BYPASS				BIT(4)
+#define DSC_UFOE_SEL				BIT(16)
+
 #define DISP_REG_OD_EN				0x0000
 #define DISP_REG_OD_CFG				0x0020
 #define OD_RELAYMODE				BIT(0)
@@ -181,6 +187,36 @@ static void mtk_dither_set(struct device *dev, unsigned int bpc,
 			      DISP_DITHERING, cmdq_pkt);
 }
 
+static void mtk_dsc_config(struct device *dev, unsigned int w,
+			   unsigned int h, unsigned int vrefresh,
+			   unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* dsc bypass mode */
+	mtk_ddp_write_mask(cmdq_pkt, DSC_BYPASS, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_BYPASS);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_UFOE_SEL, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_UFOE_SEL);
+	mtk_ddp_write_mask(cmdq_pkt, DSC_DUAL_INOUT, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_DSC_CON, DSC_DUAL_INOUT);
+}
+
+static void mtk_dsc_start(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	/* write with mask to reserve the value set in mtk_dsc_config */
+	mtk_ddp_write_mask(NULL, DSC_EN, &priv->cmdq_reg, priv->regs, DISP_REG_DSC_CON, DSC_EN);
+}
+
+static void mtk_dsc_stop(struct device *dev)
+{
+	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, priv->regs + DISP_REG_DSC_CON);
+}
+
 static void mtk_od_config(struct device *dev, unsigned int w,
 			  unsigned int h, unsigned int vrefresh,
 			  unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
@@ -270,6 +306,14 @@ static const struct mtk_ddp_comp_funcs ddp_dpi = {
 	.stop = mtk_dpi_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_dsc = {
+	.clk_enable = mtk_ddp_clk_enable,
+	.clk_disable = mtk_ddp_clk_disable,
+	.config = mtk_dsc_config,
+	.start = mtk_dsc_start,
+	.stop = mtk_dsc_stop,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_dsi = {
 	.start = mtk_dsi_ddp_start,
 	.stop = mtk_dsi_ddp_stop,
@@ -339,6 +383,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_CCORR] = "ccorr",
 	[MTK_DISP_COLOR] = "color",
 	[MTK_DISP_DITHER] = "dither",
+	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
@@ -369,6 +414,8 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DITHER]		= { MTK_DISP_DITHER,	0, &ddp_dither },
 	[DDP_COMPONENT_DPI0]		= { MTK_DPI,		0, &ddp_dpi },
 	[DDP_COMPONENT_DPI1]		= { MTK_DPI,		1, &ddp_dpi },
+	[DDP_COMPONENT_DSC0]		= { MTK_DISP_DSC,	0, &ddp_dsc },
+	[DDP_COMPONENT_DSC1]		= { MTK_DISP_DSC,	1, &ddp_dsc },
 	[DDP_COMPONENT_DSI0]		= { MTK_DSI,		0, &ddp_dsi },
 	[DDP_COMPONENT_DSI1]		= { MTK_DSI,		1, &ddp_dsi },
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,		2, &ddp_dsi },
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 4c6a98662305..5e6ff12f16ad 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -23,6 +23,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_CCORR,
 	MTK_DISP_COLOR,
 	MTK_DISP_DITHER,
+	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:29 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:29 +0800
Subject: [PATCH v15 09/12] soc: mediatek: add mtk-mutex support for mt8195
 vdosys0
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-10-jason-jh.lin@mediatek.com>

Add mtk-mutex support for mt8195 vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
This patch is base on [1]

[1] Add mmsys and mutex support for MDP
- https://patchwork.kernel.org/project/linux-mediatek/cover/20220104091712.25670-1-moudy.ho at mediatek.com/
---
 drivers/soc/mediatek/mtk-mutex.c | 103 ++++++++++++++++++++++++++++++-
 1 file changed, 100 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 615c42260a50..5bfea86aa8cf 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -21,6 +21,9 @@
 #define MT8183_MUTEX0_MOD0			0x30
 #define MT8183_MUTEX0_SOF0			0x2c
 
+#define MT8195_DISP_MUTEX0_MOD0			0x30
+#define MT8195_DISP_MUTEX0_SOF			0x2c
+
 #define DISP_REG_MUTEX_EN(n)			(0x20 + 0x20 * (n))
 #define DISP_REG_MUTEX(n)			(0x24 + 0x20 * (n))
 #define DISP_REG_MUTEX_RST(n)			(0x28 + 0x20 * (n))
@@ -83,6 +86,36 @@
 #define MT8173_MUTEX_MOD_DISP_PWM1		24
 #define MT8173_MUTEX_MOD_DISP_OD		25
 
+#define MT8195_MUTEX_MOD_DISP_OVL0		0
+#define MT8195_MUTEX_MOD_DISP_WDMA0		1
+#define MT8195_MUTEX_MOD_DISP_RDMA0		2
+#define MT8195_MUTEX_MOD_DISP_COLOR0		3
+#define MT8195_MUTEX_MOD_DISP_CCORR0		4
+#define MT8195_MUTEX_MOD_DISP_AAL0		5
+#define MT8195_MUTEX_MOD_DISP_GAMMA0		6
+#define MT8195_MUTEX_MOD_DISP_DITHER0		7
+#define MT8195_MUTEX_MOD_DISP_DSI0		8
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0	9
+#define MT8195_MUTEX_MOD_DISP_OVL1		10
+#define MT8195_MUTEX_MOD_DISP_WDMA1		11
+#define MT8195_MUTEX_MOD_DISP_RDMA1		12
+#define MT8195_MUTEX_MOD_DISP_COLOR1		13
+#define MT8195_MUTEX_MOD_DISP_CCORR1		14
+#define MT8195_MUTEX_MOD_DISP_AAL1		15
+#define MT8195_MUTEX_MOD_DISP_GAMMA1		16
+#define MT8195_MUTEX_MOD_DISP_DITHER1		17
+#define MT8195_MUTEX_MOD_DISP_DSI1		18
+#define MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE1	19
+#define MT8195_MUTEX_MOD_DISP_VPP_MERGE		20
+#define MT8195_MUTEX_MOD_DISP_DP_INTF0		21
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY0	22
+#define MT8195_MUTEX_MOD_DISP_VPP1_DL_RELAY1	23
+#define MT8195_MUTEX_MOD_DISP_VDO1_DL_RELAY2	24
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY3	25
+#define MT8195_MUTEX_MOD_DISP_VDO0_DL_RELAY4	26
+#define MT8195_MUTEX_MOD_DISP_PWM0		27
+#define MT8195_MUTEX_MOD_DISP_PWM1		28
+
 #define MT2712_MUTEX_MOD_DISP_PWM2		10
 #define MT2712_MUTEX_MOD_DISP_OVL0		11
 #define MT2712_MUTEX_MOD_DISP_OVL1		12
@@ -119,9 +152,21 @@
 #define MT8167_MUTEX_SOF_DPI1			3
 #define MT8183_MUTEX_SOF_DSI0			1
 #define MT8183_MUTEX_SOF_DPI0			2
+#define MT8195_MUTEX_SOF_DSI0			1
+#define MT8195_MUTEX_SOF_DSI1			2
+#define MT8195_MUTEX_SOF_DP_INTF0		3
+#define MT8195_MUTEX_SOF_DP_INTF1		4
+#define MT8195_MUTEX_SOF_DPI0			6 /* for HDMI_TX */
+#define MT8195_MUTEX_SOF_DPI1			5 /* for digital video out */
 
 #define MT8183_MUTEX_EOF_DSI0			(MT8183_MUTEX_SOF_DSI0 << 6)
 #define MT8183_MUTEX_EOF_DPI0			(MT8183_MUTEX_SOF_DPI0 << 6)
+#define MT8195_MUTEX_EOF_DSI0			(MT8195_MUTEX_SOF_DSI0 << 7)
+#define MT8195_MUTEX_EOF_DSI1			(MT8195_MUTEX_SOF_DSI1 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF0		(MT8195_MUTEX_SOF_DP_INTF0 << 7)
+#define MT8195_MUTEX_EOF_DP_INTF1		(MT8195_MUTEX_SOF_DP_INTF1 << 7)
+#define MT8195_MUTEX_EOF_DPI0			(MT8195_MUTEX_SOF_DPI0 << 7)
+#define MT8195_MUTEX_EOF_DPI1			(MT8195_MUTEX_SOF_DPI1 << 7)
 
 #define MT8183_MUTEX_MDP_START			5
 #define MT8183_MUTEX_MDP_MOD_MASK		0x07FFFFFF
@@ -148,6 +193,9 @@ enum mtk_mutex_sof_id {
 	MUTEX_SOF_DPI1,
 	MUTEX_SOF_DSI2,
 	MUTEX_SOF_DSI3,
+	MUTEX_SOF_DP_INTF0,
+	MUTEX_SOF_DP_INTF1,
+	DDP_MUTEX_SOF_MAX,
 };
 
 struct mtk_mutex_data {
@@ -274,7 +322,23 @@ static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_RDMA4] = MT8192_MUTEX_MOD_DISP_RDMA4,
 };
 
-static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8195_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_OVL0] = MT8195_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_WDMA0] = MT8195_MUTEX_MOD_DISP_WDMA0,
+	[DDP_COMPONENT_RDMA0] = MT8195_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_COLOR0] = MT8195_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_CCORR] = MT8195_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_AAL0] = MT8195_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_GAMMA] = MT8195_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_DITHER] = MT8195_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_MERGE0] = MT8195_MUTEX_MOD_DISP_VPP_MERGE,
+	[DDP_COMPONENT_DSC0] = MT8195_MUTEX_MOD_DISP_DSC_WRAP0_CORE0,
+	[DDP_COMPONENT_DSI0] = MT8195_MUTEX_MOD_DISP_DSI0,
+	[DDP_COMPONENT_PWM0] = MT8195_MUTEX_MOD_DISP_PWM0,
+	[DDP_COMPONENT_DP_INTF0] = MT8195_MUTEX_MOD_DISP_DP_INTF0,
+};
+
+static const unsigned int mt2712_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DSI1] = MUTEX_SOF_DSI1,
@@ -284,7 +348,7 @@ static const unsigned int mt2712_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DSI3] = MUTEX_SOF_DSI3,
 };
 
-static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8167_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8167_MUTEX_SOF_DPI0,
@@ -292,7 +356,7 @@ static const unsigned int mt8167_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 };
 
 /* Add EOF setting so overlay hardware can receive frame done irq */
-static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+static const unsigned int mt8183_mutex_sof[DDP_MUTEX_SOF_MAX] = {
 	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
 	[MUTEX_SOF_DSI0] = MUTEX_SOF_DSI0 | MT8183_MUTEX_EOF_DSI0,
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
@@ -306,6 +370,26 @@ static const unsigned int mt8183_mutex_mdp_offset[MDP_PIPE_MAX] = {
 	[MDP_PIPE_WPEI2] = MT8183_MUTEX_MDP_START + 3
 };
 
+/*
+ * To support refresh mode(video mode), DISP_REG_MUTEX_SOF should
+ * select the EOF source and configure the EOF plus timing from the
+ * module that provides the timing signal.
+ * So that MUTEX can not only send a STREAM_DONE event to GCE
+ * but also detect the error at end of frame(EAEOF) when EOF signal
+ * arrives.
+ */
+static const unsigned int mt8195_mutex_sof[DDP_MUTEX_SOF_MAX] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8195_MUTEX_SOF_DSI0 | MT8195_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DSI1] = MT8195_MUTEX_SOF_DSI1 | MT8195_MUTEX_EOF_DSI1,
+	[MUTEX_SOF_DPI0] = MT8195_MUTEX_SOF_DPI0 | MT8195_MUTEX_EOF_DPI0,
+	[MUTEX_SOF_DPI1] = MT8195_MUTEX_SOF_DPI1 | MT8195_MUTEX_EOF_DPI1,
+	[MUTEX_SOF_DP_INTF0] =
+		MT8195_MUTEX_SOF_DP_INTF0 | MT8195_MUTEX_EOF_DP_INTF0,
+	[MUTEX_SOF_DP_INTF1] =
+		MT8195_MUTEX_SOF_DP_INTF1 | MT8195_MUTEX_EOF_DP_INTF1,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -355,6 +439,13 @@ static const struct mtk_mutex_data mt8192_mutex_driver_data = {
 	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
 };
 
+static const struct mtk_mutex_data mt8195_mutex_driver_data = {
+	.mutex_mod = mt8195_mutex_mod,
+	.mutex_sof = mt8195_mutex_sof,
+	.mutex_mod_reg = MT8195_DISP_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8195_DISP_MUTEX0_SOF,
+};
+
 struct mtk_mutex *mtk_mutex_get(struct device *dev)
 {
 	struct mtk_mutex_ctx *mtx = dev_get_drvdata(dev);
@@ -442,6 +533,9 @@ void mtk_mutex_add_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DPI1:
 		sof_id = MUTEX_SOF_DPI1;
 		break;
+	case DDP_COMPONENT_DP_INTF0:
+		sof_id = MUTEX_SOF_DP_INTF0;
+		break;
 	default:
 		if (mtx->data->mutex_mod[id] < 32) {
 			offset = DISP_REG_MUTEX_MOD(mtx->data->mutex_mod_reg,
@@ -481,6 +575,7 @@ void mtk_mutex_remove_comp(struct mtk_mutex *mutex,
 	case DDP_COMPONENT_DSI3:
 	case DDP_COMPONENT_DPI0:
 	case DDP_COMPONENT_DPI1:
+	case DDP_COMPONENT_DP_INTF0:
 		writel_relaxed(MUTEX_SOF_SINGLE_MODE,
 			       mtx->regs +
 			       DISP_REG_MUTEX_SOF(mtx->data->mutex_sof_reg,
@@ -678,6 +773,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8183_mutex_driver_data},
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = &mt8192_mutex_driver_data},
+	{ .compatible = "mediatek,mt8195-disp-mutex",
+	  .data = &mt8195_mutex_driver_data},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mutex_driver_dt_match);
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:25 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:25 +0800
Subject: [PATCH v15 05/12] dt-bindings: display: mediatek: merge: add
 additional prop for mt8195
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-6-jason-jh.lin@mediatek.com>

add MERGE additional properties description for mt8195:
1. async clock
2. fifo setting enable
3. reset controller

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,merge.yaml      | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index 7aa6974d509d..fae106cf1753 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -36,8 +36,28 @@ properties:
       Documentation/devicetree/bindings/power/power-domain.yaml for details.
 
   clocks:
+    maxItems: 2
     items:
       - description: MERGE Clock
+      - description: MERGE Async Clock
+          Controlling the synchronous process between MERGE and other display
+          function blocks cross clock domain.
+
+  clock-names:
+    maxItems: 2
+    items:
+      - const: merge
+      - const: merge_async
+
+  mediatek,merge-fifo-en:
+    description:
+      The setting of merge fifo is mainly provided for the display latency
+      buffer to ensure that the back-end panel display data will not be
+      underrun, a little more data is needed in the fifo.
+      According to the merge fifo settings, when the water level is detected
+      to be insufficient, it will trigger RDMA sending ultra and preulra
+      command to SMI to speed up the data rate.
+    type: boolean
 
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
@@ -47,6 +67,11 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     maxItems: 1
 
+  resets:
+    description: reset controller
+      See Documentation/devicetree/bindings/reset/reset.txt for details.
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -64,3 +89,16 @@ examples:
         power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
         clocks = <&mmsys CLK_MM_DISP_MERGE>;
     };
+
+    merge5: disp_vpp_merge5 at 1c110000 {
+        compatible = "mediatek,mt8195-disp-merge";
+        reg = <0 0x1c110000 0 0x1000>;
+        interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&vdosys1 CLK_VDO1_VPP_MERGE4>,
+                 <&vdosys1 CLK_VDO1_MERGE4_DL_ASYNC>;
+        clock-names = "merge","merge_async";
+        power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
+        mediatek,gce-client-reg = <&gce1 SUBSYS_1c11XXXX 0x0000 0x1000>;
+        mediatek,merge-fifo-en = <1>;
+        resets = <&vdosys1 MT8195_VDOSYS1_SW0_RST_B_MERGE4_DL_ASYNC>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:20 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:20 +0800
Subject: [PATCH v15 00/12] Add Mediatek Soc DRM (vdosys0) support for mt8195
Message-ID: <20220126071932.32615-1-jason-jh.lin@mediatek.com>

Change in v15:
- remove mt8195-mmsys.h comment for mux settings
- define the mask macro to replace using value as mask
  to fix zero mask problem
- add EOF setting comment for MUTEX sof register

Change in v14:
- rebase on mediatek-drm-next-5.17
- rebase on "Add mmsys and mutex support for MDP" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=602528
- rebase on "media: mediatek: support mdp3 on mt8183 platform" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=602834

Change in v13:
- remove dts patch
- rebase on kernel-5.16-rc1
- rebase on mediatek-drm-next

Change in v12:
- add clock-names property to merge yaml
- using BIT(nr) macro to define the settings of mmsys routing table
- fix clk_get and clk_prepare_enable error handling issue

Change in v11:
- rebase on kernel-5.15-rc1
- change mbox label to gce0 for dts node of vdosys0
- change ovl compatibale to mt8192 to set smi_id_en=true in driver data
- move common module from display folder to common folder,
  such as AAL, COCLOR, CCORR and MUTEX

Change in v10:
- rebase on "drm/mediatek: add support for mediatek SOC MT8192" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489
- rebase on "soc: mediatek: mmsys: add mt8192 mmsys support" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=524857
- fix some typo and "mediatek" start with capital in every dt-bindings
- move mutex yaml from dfisplay folder to soc folder
- separate merge additional propoerties to an individual dt-bindings patch

Change in v9:
- separate power and gce properties of mmsys into another dt-binding patch
- rebase on "Separate aal module" series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=516463
- keep mtk_ddp_clk_enable/disable in the same place
- change mtk_dsc_start config register to mtk_drm_ddp_write_mask
- remove the 0 setting of merge fifo config function
- add CCORR driver data for mt8195

Change in v8:
- add DP_INTF0 mux into mmsys routing table
- add DP_INTF0 mutex mod and enum into add/remove comp function
- remove bypass DSC enum in mtk_ddp_comp_init

Change in v7:
- add dt=binding of mmsys and disp path into this series
- separate th modidfication of alphabetic order, remove unused define and
  rename the define of register offset to individual patch
- add comment for MERGE ultra and preultra setting

Change in v6:
- adjust alphabetic order for mediatek-drm
- move the patch that add mt8195 support for mediatek-drm as
  the lastest patch
- add MERGE define for const varriable 

Change in v5:
- add power-domain property into vdosys0 and vdosys1 dts node.
- add MT8195 prifix and remove unused VDO1 define in mt8195-mmsys.h

Change in v4:
- extract dt-binding patches to another patch series
  https://patchwork.kernel.org/project/linux-mediatek/list/?series=519597
- squash DSC module into mtk_drm_ddp_comp.c
- add coment and simplify MERGE config function

Change in v3:
- change mmsys and display dt-bindings document from txt to yaml
- add MERGE additional description in display dt-bindings document
- fix mboxes-cells number of vdosys0 node in dts
- drop mutex eof convert define
- remove pm_runtime apis in DSC and MERGE
- change DSC and MERGE enum to alphabetic order

Change in v2:
- add DSC yaml file
- add mt8195 drm driver porting parts in to one patch
- remove useless define, variable, structure member and function
- simplify DSC and MERGE file and switch threre order

jason-jh.lin (12):
  dt-bindings: arm: mediatek: mmsys: add power and gce properties
  dt-bindings: arm: mediatek: mmsys: add mt8195 SoC binding
  dt-bindings: display: mediatek: disp: split each block to individual
    yaml
  dt-bindings: display: mediatek: dsc: add yaml for mt8195 SoC binding
  dt-bindings: display: mediatek: merge: add additional prop for mt8195
  dt-bindings: display: mediatek: add mt8195 SoC binding for vdosys0
  dt-bindings: arm: mediatek: move out common module from display folder
  soc: mediatek: add mtk-mmsys support for mt8195 vdosys0
  soc: mediatek: add mtk-mutex support for mt8195 vdosys0
  drm/mediatek: add DSC support for mediatek-drm
  drm/mediatek: add MERGE support for mediatek-drm
  drm/mediatek: add mediatek-drm of vdosys0 support for mt8195

 .../bindings/arm/mediatek/mediatek,mmsys.yaml |  32 ++-
 .../display/mediatek/mediatek,disp.txt        | 219 ----------------
 .../display/mediatek/mediatek,dither.yaml     |  76 ++++++
 .../display/mediatek/mediatek,dsc.yaml        |  71 +++++
 .../display/mediatek/mediatek,gamma.yaml      |  77 ++++++
 .../display/mediatek/mediatek,merge.yaml      | 106 ++++++++
 .../display/mediatek/mediatek,od.yaml         |  53 ++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  88 +++++++
 .../display/mediatek/mediatek,ovl.yaml        | 103 ++++++++
 .../display/mediatek/mediatek,postmask.yaml   |  69 +++++
 .../display/mediatek/mediatek,rdma.yaml       | 117 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  58 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  61 +++++
 .../bindings/soc/mediatek/mediatek,aal.yaml   |  72 +++++
 .../bindings/soc/mediatek/mediatek,ccorr.yaml |  46 +++-
 .../bindings/soc/mediatek/mediatek,color.yaml |  81 ++++++
 .../bindings/soc/mediatek/mediatek,mutex.yaml |  77 ++++++
 .../bindings/soc/mediatek/mediatek,wdma.yaml  |  47 +++-
 drivers/gpu/drm/mediatek/Makefile             |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h       |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c     | 246 ++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c      |   6 +
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c   |  63 +++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h   |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c        |  32 ++-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h        |   1 +
 drivers/soc/mediatek/mt8195-mmsys.h           | 130 +++++++++
 drivers/soc/mediatek/mtk-mmsys.c              |  11 +
 drivers/soc/mediatek/mtk-mutex.c              | 103 +++++++-
 include/linux/soc/mediatek/mtk-mmsys.h        |   9 +
 30 files changed, 1832 insertions(+), 233 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dsc.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c
 create mode 100644 drivers/soc/mediatek/mt8195-mmsys.h

-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:26 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:26 +0800
Subject: [PATCH v15 06/12] dt-bindings: display: mediatek: add mt8195 SoC
 binding for vdosys0
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-7-jason-jh.lin@mediatek.com>

Add mt8195 SoC binding to AAL, CCORR, COLOR, DITHER, GAMMA, MERGE,
MUTEX, OVL and RDMA yaml schema for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../devicetree/bindings/display/mediatek/mediatek,aal.yaml   | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,ccorr.yaml | 5 +++++
 .../devicetree/bindings/display/mediatek/mediatek,color.yaml | 1 +
 .../bindings/display/mediatek/mediatek,dither.yaml           | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,gamma.yaml | 1 +
 .../devicetree/bindings/display/mediatek/mediatek,merge.yaml | 2 ++
 .../devicetree/bindings/display/mediatek/mediatek,mutex.yaml | 5 +++--
 .../devicetree/bindings/display/mediatek/mediatek,ovl.yaml   | 5 +++++
 .../devicetree/bindings/display/mediatek/mediatek,rdma.yaml  | 2 ++
 9 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
index 044331f5aacb..225f9dd726d2 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -28,6 +28,7 @@ properties:
               - mediatek,mt2712-disp-aal
               - mediatek,mt8183-disp-aal
               - mediatek,mt8192-disp-aal
+              - mediatek,mt8195-disp-aal
           - enum:
               - mediatek,mt8173-disp-aal
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
index ea45b40edee7..6894b6999412 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -25,6 +25,11 @@ properties:
           - const: mediatek,mt8183-disp-ccorr
       - items:
           - const: mediatek,mt8192-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8192-disp-ccorr
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
index 13628f346718..bc83155b3b4c 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -38,6 +38,7 @@ properties:
           - enum:
               - mediatek,mt8183-disp-color
               - mediatek,mt8192-disp-color
+              - mediatek,mt8195-disp-color
           - enum:
               - mediatek,mt8173-disp-color
   reg:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
index 2c05e3019c75..9d89297f5f1d 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -27,6 +27,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8192-disp-dither
+              - mediatek,mt8195-disp-dither
           - enum:
               - mediatek,mt8183-disp-dither
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
index 89ccb8dbadd7..247baad147b3 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -28,6 +28,7 @@ properties:
       - items:
           - enum:
               - mediatek,mt8192-disp-gamma
+              - mediatek,mt8195-disp-gamma
           - enum:
               - mediatek,mt8183-disp-gamma
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
index fae106cf1753..60b21ef5549b 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -23,6 +23,8 @@ properties:
     oneOf:
       - items:
           - const: mediatek,mt8173-disp-merge
+      - items:
+          - const: mediatek,mt8195-disp-merge
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
index 90f11e12a55e..6eca525eced0 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display mutex
+title: Mediatek mutex
 
 maintainers:
   - Chun-Kuang Hu <chunkuang.hu at kernel.org>
@@ -36,7 +36,8 @@ properties:
           - const: mediatek,mt8183-disp-mutex
       - items:
           - const: mediatek,mt8192-disp-mutex
-
+      - items:
+          - const: mediatek,mt8195-disp-mutex
   reg:
     maxItems: 1
 
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
index 8e4a62cb9c81..e71f79bc2dee 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -35,6 +35,11 @@ properties:
               - mediatek,mt2712-disp-ovl
           - enum:
               - mediatek,mt2701-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ovl
+          - enum:
+              - mediatek,mt8183-disp-ovl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
index a3c5f4c9fbcd..8ef821641672 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -29,6 +29,8 @@ properties:
           - const: mediatek,mt8173-disp-rdma
       - items:
           - const: mediatek,mt8183-disp-rdma
+      - items:
+          - const: mediatek,mt8195-disp-rdma
       - items:
           - enum:
               - mediatek,mt7623-disp-rdma
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:31 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:31 +0800
Subject: [PATCH v15 11/12] drm/mediatek: add MERGE support for mediatek-drm
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-12-jason-jh.lin@mediatek.com>

Add MERGE engine file:
MERGE module is used to merge two slice-per-line inputs
into one side-by-side output.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
rebase on series [1]

[1] drm/mediatek: add support for mediatek SOC MT8192
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=529489
---
 drivers/gpu/drm/mediatek/Makefile           |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_merge.c   | 246 ++++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  16 ++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h |   1 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.c      |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.h      |   1 +
 7 files changed, 276 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_merge.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..a38e88e82d12 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -4,6 +4,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_ccorr.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
+		  mtk_disp_merge.o \
 		  mtk_disp_ovl.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 86c3068894b1..a33b13fe2b6e 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -55,6 +55,14 @@ void mtk_gamma_set_common(void __iomem *regs, struct drm_crtc_state *state);
 void mtk_gamma_start(struct device *dev);
 void mtk_gamma_stop(struct device *dev);
 
+int mtk_merge_clk_enable(struct device *dev);
+void mtk_merge_clk_disable(struct device *dev);
+void mtk_merge_config(struct device *dev, unsigned int width,
+		      unsigned int height, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_merge_start(struct device *dev);
+void mtk_merge_stop(struct device *dev);
+
 void mtk_ovl_bgclr_in_on(struct device *dev);
 void mtk_ovl_bgclr_in_off(struct device *dev);
 void mtk_ovl_bypass_shadow(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_merge.c b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
new file mode 100644
index 000000000000..45face638153
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_merge.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_drm_ddp_comp.h"
+#include "mtk_drm_drv.h"
+#include "mtk_disp_drv.h"
+
+#define DISP_REG_MERGE_CTRL		0x000
+#define MERGE_EN				1
+#define DISP_REG_MERGE_CFG_0		0x010
+#define DISP_REG_MERGE_CFG_4		0x020
+#define DISP_REG_MERGE_CFG_10		0x038
+/* no swap */
+#define SWAP_MODE				0
+#define FLD_SWAP_MODE				GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_12		0x040
+#define CFG_10_10_1PI_2PO_BUF_MODE		6
+#define CFG_10_10_2PI_2PO_BUF_MODE		8
+#define FLD_CFG_MERGE_MODE			GENMASK(4, 0)
+#define DISP_REG_MERGE_CFG_24		0x070
+#define DISP_REG_MERGE_CFG_25		0x074
+#define DISP_REG_MERGE_CFG_36		0x0a0
+#define ULTRA_EN				BIT(0)
+#define PREULTRA_EN				BIT(4)
+#define DISP_REG_MERGE_CFG_37		0x0a4
+/* 0: Off, 1: SRAM0, 2: SRAM1, 3: SRAM0 + SRAM1 */
+#define BUFFER_MODE				3
+#define FLD_BUFFER_MODE				GENMASK(1, 0)
+/*
+ * For the ultra and preultra settings, 6us ~ 9us is experience value
+ * and the maximum frequency of mmsys clock is 594MHz.
+ */
+#define DISP_REG_MERGE_CFG_40		0x0b0
+/* 6 us, 594M pixel/sec */
+#define ULTRA_TH_LOW				(6 * 594)
+/* 8 us, 594M pixel/sec */
+#define ULTRA_TH_HIGH				(8 * 594)
+#define FLD_ULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_ULTRA_TH_HIGH			GENMASK(31, 16)
+#define DISP_REG_MERGE_CFG_41		0x0b4
+/* 8 us, 594M pixel/sec */
+#define PREULTRA_TH_LOW				(8 * 594)
+/* 9 us, 594M pixel/sec */
+#define PREULTRA_TH_HIGH			(9 * 594)
+#define FLD_PREULTRA_TH_LOW			GENMASK(15, 0)
+#define FLD_PREULTRA_TH_HIGH			GENMASK(31, 16)
+
+struct mtk_disp_merge {
+	void __iomem			*regs;
+	struct clk			*clk;
+	struct clk			*async_clk;
+	struct cmdq_client_reg		cmdq_reg;
+	bool				fifo_en;
+};
+
+void mtk_merge_start(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(MERGE_EN, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+void mtk_merge_stop(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	writel(0x0, priv->regs + DISP_REG_MERGE_CTRL);
+}
+
+static void mtk_merge_fifo_setting(struct mtk_disp_merge *priv,
+				   struct cmdq_pkt *cmdq_pkt)
+{
+	mtk_ddp_write(cmdq_pkt, ULTRA_EN | PREULTRA_EN,
+		      &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_36);
+
+	mtk_ddp_write_mask(cmdq_pkt, BUFFER_MODE,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_37,
+			   FLD_BUFFER_MODE);
+
+	mtk_ddp_write_mask(cmdq_pkt, ULTRA_TH_LOW | ULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_40,
+			   FLD_ULTRA_TH_LOW | FLD_ULTRA_TH_HIGH);
+
+	mtk_ddp_write_mask(cmdq_pkt, PREULTRA_TH_LOW | PREULTRA_TH_HIGH << 16,
+			   &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CFG_41,
+			   FLD_PREULTRA_TH_LOW | FLD_PREULTRA_TH_HIGH);
+}
+
+void mtk_merge_config(struct device *dev, unsigned int w,
+		      unsigned int h, unsigned int vrefresh,
+		      unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+	unsigned int mode = CFG_10_10_1PI_2PO_BUF_MODE;
+
+	if (!h || !w) {
+		dev_err(dev, "%s: input width(%d) or height(%d) is invalid\n", __func__, w, h);
+		return;
+	}
+
+	if (priv->fifo_en) {
+		mtk_merge_fifo_setting(priv, cmdq_pkt);
+		mode = CFG_10_10_2PI_2PO_BUF_MODE;
+	}
+
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_0);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_4);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_24);
+	mtk_ddp_write(cmdq_pkt, h << 16 | w, &priv->cmdq_reg, priv->regs,
+		      DISP_REG_MERGE_CFG_25);
+	mtk_ddp_write_mask(cmdq_pkt, SWAP_MODE, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_10, FLD_SWAP_MODE);
+	mtk_ddp_write_mask(cmdq_pkt, mode, &priv->cmdq_reg, priv->regs,
+			   DISP_REG_MERGE_CFG_12, FLD_CFG_MERGE_MODE);
+}
+
+int mtk_merge_clk_enable(struct device *dev)
+{
+	int ret = 0;
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(dev, "merge clk prepare enable failed\n");
+		return ret;
+	}
+
+	ret = clk_prepare_enable(priv->async_clk);
+	if (ret) {
+		/* should clean up the state of priv->clk */
+		clk_disable_unprepare(priv->clk);
+
+		dev_err(dev, "async clk prepare enable failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+void mtk_merge_clk_disable(struct device *dev)
+{
+	struct mtk_disp_merge *priv = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(priv->async_clk);
+	clk_disable_unprepare(priv->clk);
+}
+
+static int mtk_disp_merge_bind(struct device *dev, struct device *master,
+			       void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_merge_unbind(struct device *dev, struct device *master,
+				  void *data)
+{
+}
+
+static const struct component_ops mtk_disp_merge_component_ops = {
+	.bind	= mtk_disp_merge_bind,
+	.unbind = mtk_disp_merge_unbind,
+};
+
+static int mtk_disp_merge_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct mtk_disp_merge *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap merge\n");
+		return PTR_ERR(priv->regs);
+	}
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get merge clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	priv->async_clk = devm_clk_get_optional(dev, "merge_async");
+	if (IS_ERR(priv->async_clk)) {
+		dev_err(dev, "failed to get merge async clock\n");
+		return PTR_ERR(priv->async_clk);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->fifo_en = of_property_read_bool(dev->of_node,
+					      "mediatek,merge-fifo-en");
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_merge_component_ops);
+	if (ret != 0)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_merge_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_merge_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_merge_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8195-disp-merge", },
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, mtk_disp_merge_driver_dt_match);
+
+struct platform_driver mtk_disp_merge_driver = {
+	.probe = mtk_disp_merge_probe,
+	.remove = mtk_disp_merge_remove,
+	.driver = {
+		.name = "mediatek-disp-merge",
+		.owner = THIS_MODULE,
+		.of_match_table = mtk_disp_merge_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index 90b289b5f9a4..26d197da41c0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -328,6 +328,14 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
 	.stop = mtk_gamma_stop,
 };
 
+static const struct mtk_ddp_comp_funcs ddp_merge = {
+	.clk_enable = mtk_merge_clk_enable,
+	.clk_disable = mtk_merge_clk_disable,
+	.start = mtk_merge_start,
+	.stop = mtk_merge_stop,
+	.config = mtk_merge_config,
+};
+
 static const struct mtk_ddp_comp_funcs ddp_od = {
 	.clk_enable = mtk_ddp_clk_enable,
 	.clk_disable = mtk_ddp_clk_disable,
@@ -385,6 +393,7 @@ static const char * const mtk_ddp_comp_stem[MTK_DDP_COMP_TYPE_MAX] = {
 	[MTK_DISP_DITHER] = "dither",
 	[MTK_DISP_DSC] = "dsc",
 	[MTK_DISP_GAMMA] = "gamma",
+	[MTK_DISP_MERGE] = "merge",
 	[MTK_DISP_MUTEX] = "mutex",
 	[MTK_DISP_OD] = "od",
 	[MTK_DISP_OVL] = "ovl",
@@ -421,6 +430,12 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_DSI2]		= { MTK_DSI,		2, &ddp_dsi },
 	[DDP_COMPONENT_DSI3]		= { MTK_DSI,		3, &ddp_dsi },
 	[DDP_COMPONENT_GAMMA]		= { MTK_DISP_GAMMA,	0, &ddp_gamma },
+	[DDP_COMPONENT_MERGE0]		= { MTK_DISP_MERGE,	0, &ddp_merge },
+	[DDP_COMPONENT_MERGE1]		= { MTK_DISP_MERGE,	1, &ddp_merge },
+	[DDP_COMPONENT_MERGE2]		= { MTK_DISP_MERGE,	2, &ddp_merge },
+	[DDP_COMPONENT_MERGE3]		= { MTK_DISP_MERGE,	3, &ddp_merge },
+	[DDP_COMPONENT_MERGE4]		= { MTK_DISP_MERGE,	4, &ddp_merge },
+	[DDP_COMPONENT_MERGE5]		= { MTK_DISP_MERGE,	5, &ddp_merge },
 	[DDP_COMPONENT_OD0]		= { MTK_DISP_OD,	0, &ddp_od },
 	[DDP_COMPONENT_OD1]		= { MTK_DISP_OD,	1, &ddp_od },
 	[DDP_COMPONENT_OVL0]		= { MTK_DISP_OVL,	0, &ddp_ovl },
@@ -555,6 +570,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_CCORR ||
 	    type == MTK_DISP_COLOR ||
 	    type == MTK_DISP_GAMMA ||
+	    type == MTK_DISP_MERGE ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
 	    type == MTK_DISP_PWM ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
index 5e6ff12f16ad..221e2e3a3c8d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h
@@ -25,6 +25,7 @@ enum mtk_ddp_comp_type {
 	MTK_DISP_DITHER,
 	MTK_DISP_DSC,
 	MTK_DISP_GAMMA,
+	MTK_DISP_MERGE,
 	MTK_DISP_MUTEX,
 	MTK_DISP_OD,
 	MTK_DISP_OVL,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 56ff8c57ef8f..2f33fe8ad46b 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -599,7 +599,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		private->comp_node[comp_id] = of_node_get(node);
 
 		/*
-		 * Currently only the AAL, CCORR, COLOR, GAMMA, OVL, RDMA, DSI, and DPI
+		 * Currently only the AAL, CCORR, COLOR, GAMMA, MERGE, OVL, RDMA, DSI, and DPI
 		 * blocks have separate component platform drivers and initialize their own
 		 * DDP component structure. The others are initialized here.
 		 */
@@ -607,6 +607,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_CCORR ||
 		    comp_type == MTK_DISP_COLOR ||
 		    comp_type == MTK_DISP_GAMMA ||
+		    comp_type == MTK_DISP_MERGE ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
 		    comp_type == MTK_DISP_RDMA ||
@@ -708,6 +709,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_ccorr_driver,
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
+	&mtk_disp_merge_driver,
 	&mtk_disp_ovl_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 3e7d1e6fbe01..a58cebd01d35 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -50,6 +50,7 @@ extern struct platform_driver mtk_disp_aal_driver;
 extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
+extern struct platform_driver mtk_disp_merge_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:23 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:23 +0800
Subject: [PATCH v15 03/12] dt-bindings: display: mediatek: disp: split each
 block to individual yaml
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-4-jason-jh.lin@mediatek.com>

1. Remove mediatek,dislpay.txt
2. Split each display function block to individual yaml file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,aal.yaml        |  76 ++++++
 .../display/mediatek/mediatek,ccorr.yaml      |  71 ++++++
 .../display/mediatek/mediatek,color.yaml      |  85 +++++++
 .../display/mediatek/mediatek,disp.txt        | 219 ------------------
 .../display/mediatek/mediatek,dither.yaml     |  75 ++++++
 .../display/mediatek/mediatek,gamma.yaml      |  76 ++++++
 .../display/mediatek/mediatek,merge.yaml      |  66 ++++++
 .../display/mediatek/mediatek,mutex.yaml      |  82 +++++++
 .../display/mediatek/mediatek,od.yaml         |  53 +++++
 .../display/mediatek/mediatek,ovl-2l.yaml     |  88 +++++++
 .../display/mediatek/mediatek,ovl.yaml        |  98 ++++++++
 .../display/mediatek/mediatek,postmask.yaml   |  69 ++++++
 .../display/mediatek/mediatek,rdma.yaml       | 115 +++++++++
 .../display/mediatek/mediatek,split.yaml      |  58 +++++
 .../display/mediatek/mediatek,ufoe.yaml       |  61 +++++
 .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
 16 files changed, 1159 insertions(+), 219 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
 create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
new file mode 100644
index 000000000000..044331f5aacb
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display adaptive ambient light processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display adaptive ambient light processor, namely AAL,
+  is responsible for backlight power saving and sunlight visibility improving.
+  AAL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-aal
+      - items:
+          - enum:
+              - mediatek,mt2712-disp-aal
+              - mediatek,mt8183-disp-aal
+              - mediatek,mt8192-disp-aal
+          - enum:
+              - mediatek,mt8173-disp-aal
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: AAL Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    aal at 14015000 {
+        compatible = "mediatek,mt8173-disp-aal";
+        reg = <0 0x14015000 0 0x1000>;
+        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_AAL>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
new file mode 100644
index 000000000000..ea45b40edee7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display color correction, namely CCORR, reproduces correct color
+  on panels with different color gamut.
+  CCORR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - const: mediatek,mt8192-disp-ccorr
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
new file mode 100644
index 000000000000..13628f346718
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display color processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display color processor, namely COLOR, provides hue, luma and
+  saturation adjustments to get better picture quality and to have one panel
+  resemble the other in their output characteristics.
+  COLOR device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-color
+      - items:
+          - const: mediatek,mt8167-disp-color
+      - items:
+          - const: mediatek,mt8173-disp-color
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-color
+              - mediatek,mt2712-disp-color
+          - enum:
+              - mediatek,mt2701-disp-color
+      - items:
+          - enum:
+              - mediatek,mt8183-disp-color
+              - mediatek,mt8192-disp-color
+          - enum:
+              - mediatek,mt8173-disp-color
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: COLOR Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    color0: color at 14013000 {
+        compatible = "mediatek,mt8173-disp-color";
+        reg = <0 0x14013000 0 0x1000>;
+        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
deleted file mode 100644
index 78044c340e20..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
+++ /dev/null
@@ -1,219 +0,0 @@
-Mediatek display subsystem
-==========================
-
-The Mediatek display subsystem consists of various DISP function blocks in the
-MMSYS register space. The connections between them can be configured by output
-and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
-of frame signal are distributed to the other function blocks by a DISP_MUTEX
-function block.
-
-All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
-For a description of the MMSYS_CONFIG binding, see
-Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml.
-
-DISP function blocks
-====================
-
-A display stream starts at a source function block that reads pixel data from
-memory and ends with a sink function block that drives pixels on a display
-interface, or writes pixels back to memory. All DISP function blocks have
-their own register space, interrupt, and clock gate. The blocks that can
-access memory additionally have to list the IOMMU and local arbiter they are
-connected to.
-
-For a description of the display interface sink function blocks, see
-Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
-Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
-
-Required properties (all function blocks):
-- compatible: "mediatek,<chip>-disp-<function>", one of
-	"mediatek,<chip>-disp-ovl"   		- overlay (4 layers, blending, csc)
-	"mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
-	"mediatek,<chip>-disp-rdma"  		- read DMA / line buffer
-	"mediatek,<chip>-disp-wdma"  		- write DMA
-	"mediatek,<chip>-disp-ccorr"            - color correction
-	"mediatek,<chip>-disp-color" 		- color processor
-	"mediatek,<chip>-disp-dither"           - dither
-	"mediatek,<chip>-disp-aal"   		- adaptive ambient light controller
-	"mediatek,<chip>-disp-gamma" 		- gamma correction
-	"mediatek,<chip>-disp-merge" 		- merge streams from two RDMA sources
-	"mediatek,<chip>-disp-postmask" 	- control round corner for display frame
-	"mediatek,<chip>-disp-split" 		- split stream to two encoders
-	"mediatek,<chip>-disp-ufoe"  		- data compression engine
-	"mediatek,<chip>-dsi"        		- DSI controller, see mediatek,dsi.txt
-	"mediatek,<chip>-dpi"        		- DPI controller, see mediatek,dpi.txt
-	"mediatek,<chip>-disp-mutex" 		- display mutex
-	"mediatek,<chip>-disp-od"    		- overdrive
-  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
-- reg: Physical base address and length of the function block register space
-- interrupts: The interrupt signal from the function block (required, except for
-  merge and split function blocks).
-- clocks: device clocks
-  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
-  For most function blocks this is just a single clock input. Only the DSI and
-  DPI controller nodes have multiple clock inputs. These are documented in
-  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
-  An exception is that the mt8183 mutex is always free running with no clocks property.
-
-Required properties (DMA function blocks):
-- compatible: Should be one of
-	"mediatek,<chip>-disp-ovl"
-	"mediatek,<chip>-disp-rdma"
-	"mediatek,<chip>-disp-wdma"
-  the supported chips are mt2701, mt8167 and mt8173.
-- larb: Should contain a phandle pointing to the local arbiter device as defined
-  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
-- iommus: Should point to the respective IOMMU block with master port as
-  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
-  for details.
-
-Optional properties (RDMA function blocks):
-- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
-  property to the corresponding rdma
-  the value is the Max value which defined in hardware data sheet.
-  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
-  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
-  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
-
-Examples:
-
-mmsys: clock-controller at 14000000 {
-	compatible = "mediatek,mt8173-mmsys", "syscon";
-	reg = <0 0x14000000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	#clock-cells = <1>;
-};
-
-ovl0: ovl at 1400c000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400c000 0 0x1000>;
-	interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL0>;
-	iommus = <&iommu M4U_PORT_DISP_OVL0>;
-	mediatek,larb = <&larb0>;
-};
-
-ovl1: ovl at 1400d000 {
-	compatible = "mediatek,mt8173-disp-ovl";
-	reg = <0 0x1400d000 0 0x1000>;
-	interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OVL1>;
-	iommus = <&iommu M4U_PORT_DISP_OVL1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma0: rdma at 1400e000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400e000 0 0x1000>;
-	interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA0>;
-	mediatek,larb = <&larb0>;
-	mediatek,rdma-fifosize = <8192>;
-};
-
-rdma1: rdma at 1400f000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x1400f000 0 0x1000>;
-	interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-rdma2: rdma at 14010000 {
-	compatible = "mediatek,mt8173-disp-rdma";
-	reg = <0 0x14010000 0 0x1000>;
-	interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_RDMA2>;
-	iommus = <&iommu M4U_PORT_DISP_RDMA2>;
-	mediatek,larb = <&larb4>;
-};
-
-wdma0: wdma at 14011000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14011000 0 0x1000>;
-	interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-	mediatek,larb = <&larb0>;
-};
-
-wdma1: wdma at 14012000 {
-	compatible = "mediatek,mt8173-disp-wdma";
-	reg = <0 0x14012000 0 0x1000>;
-	interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_WDMA1>;
-	iommus = <&iommu M4U_PORT_DISP_WDMA1>;
-	mediatek,larb = <&larb4>;
-};
-
-color0: color at 14013000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14013000 0 0x1000>;
-	interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR0>;
-};
-
-color1: color at 14014000 {
-	compatible = "mediatek,mt8173-disp-color";
-	reg = <0 0x14014000 0 0x1000>;
-	interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_COLOR1>;
-};
-
-aal at 14015000 {
-	compatible = "mediatek,mt8173-disp-aal";
-	reg = <0 0x14015000 0 0x1000>;
-	interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_AAL>;
-};
-
-gamma at 14016000 {
-	compatible = "mediatek,mt8173-disp-gamma";
-	reg = <0 0x14016000 0 0x1000>;
-	interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_GAMMA>;
-};
-
-ufoe at 1401a000 {
-	compatible = "mediatek,mt8173-disp-ufoe";
-	reg = <0 0x1401a000 0 0x1000>;
-	interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_UFOE>;
-};
-
-dsi0: dsi at 1401b000 {
-	/* See mediatek,dsi.txt for details */
-};
-
-dpi0: dpi at 1401d000 {
-	/* See mediatek,dpi.txt for details */
-};
-
-mutex: mutex at 14020000 {
-	compatible = "mediatek,mt8173-disp-mutex";
-	reg = <0 0x14020000 0 0x1000>;
-	interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_MUTEX_32K>;
-};
-
-od at 14023000 {
-	compatible = "mediatek,mt8173-disp-od";
-	reg = <0 0x14023000 0 0x1000>;
-	power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-	clocks = <&mmsys CLK_MM_DISP_OD>;
-};
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
new file mode 100644
index 000000000000..2c05e3019c75
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display dither processor
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display dither processor, namely DITHER, works by approximating
+  unavailable colors with available colors and by mixing and matching available
+  colors to mimic unavailable ones.
+  DITHER device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-dither
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-dither
+          - enum:
+              - mediatek,mt8183-disp-dither
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: DITHER Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    dither0: dither at 14012000 {
+        compatible = "mediatek,mt8183-disp-dither";
+        reg = <0 0x14012000 0 0x1000>;
+        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
new file mode 100644
index 000000000000..89ccb8dbadd7
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display gamma correction
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display gamma correction, namely GAMMA, provides a nonlinear
+  operation used to adjust luminance in??display system.
+  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-gamma
+      - items:
+          - const: mediatek,mt8183-disp-gamma
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-gamma
+          - enum:
+              - mediatek,mt8183-disp-gamma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: GAMMA Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    gamma at 14016000 {
+        compatible = "mediatek,mt8173-disp-gamma";
+        reg = <0 0x14016000 0 0x1000>;
+        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
new file mode 100644
index 000000000000..7aa6974d509d
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display merge
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display merge, namely MERGE, is used to merge two slice-per-line
+  inputs into one side-by-side output.
+  MERGE device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-merge
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MERGE Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    merge at 14017000 {
+        compatible = "mediatek,mt8173-disp-merge";
+        reg = <0 0x14017000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_MERGE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
new file mode 100644
index 000000000000..90f11e12a55e
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display mutex
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek mutex, namely MUTEX, is used to send the triggers signals called
+  Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
+  data path or MDP data path.
+  In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
+  the shadow register.
+  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-mutex
+      - items:
+          - const: mediatek,mt2712-disp-mutex
+      - items:
+          - const: mediatek,mt8167-disp-mutex
+      - items:
+          - const: mediatek,mt8173-disp-mutex
+      - items:
+          - const: mediatek,mt8183-disp-mutex
+      - items:
+          - const: mediatek,mt8192-disp-mutex
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: MUTEX Clock
+
+  mediatek,gce-events:
+    description:
+      The event id which is mapping to the specific hardware event signal
+      to gce. The event id is defined in the gce header
+      include/dt-bindings/gce/<chip>-gce.h of each chips.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    mutex: mutex at 14020000 {
+        compatible = "mediatek,mt8173-disp-mutex";
+        reg = <0 0x14020000 0 0x1000>;
+        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_MUTEX_32K>;
+        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
+                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
new file mode 100644
index 000000000000..7519db315217
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
@@ -0,0 +1,53 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overdirve
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overdrive, namely OD, increases the transition values
+  of pixels between consecutive frames to make LCD rotate faster.
+  OD device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2712-disp-od
+      - items:
+          - const: mediatek,mt8173-disp-od
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: OD Clock
+
+required:
+  - compatible
+  - reg
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    od at 14023000 {
+        compatible = "mediatek,mt8173-disp-od";
+        reg = <0 0x14023000 0 0x1000>;
+        clocks = <&mmsys CLK_MM_DISP_OD>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
new file mode 100644
index 000000000000..611a2dbdefa4
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay 2 layer
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overlay 2 layer, namely OVL-2L, provides 2 more layer
+  for OVL.
+  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-disp-ovl-2l
+      - items:
+          - const: mediatek,mt8192-disp-ovl-2l
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL-2L Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl_2l0: ovl at 14009000 {
+        compatible = "mediatek,mt8183-disp-ovl-2l";
+        reg = <0 0x14009000 0 0x1000>;
+        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
+        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
new file mode 100644
index 000000000000..8e4a62cb9c81
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display overlay
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display overlay, namely OVL, can do alpha blending from
+  the memory.
+  OVL device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-ovl
+      - items:
+          - const: mediatek,mt8173-disp-ovl
+      - items:
+          - const: mediatek,mt8183-disp-ovl
+      - items:
+          - const: mediatek,mt8192-disp-ovl
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-ovl
+              - mediatek,mt2712-disp-ovl
+          - enum:
+              - mediatek,mt2701-disp-ovl
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: OVL Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommu
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ovl0: ovl at 1400c000 {
+        compatible = "mediatek,mt8173-disp-ovl";
+        reg = <0 0x1400c000 0 0x1000>;
+        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_OVL0>;
+        iommus = <&iommu M4U_PORT_DISP_OVL0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
new file mode 100644
index 000000000000..6ac1da2e8871
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,postmask.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display postmask
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display postmask, namely POSTMASK, provides round corner pattern
+  generation.
+  POSTMASK device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8192-disp-postmask
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: POSTMASK Clock
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    postmask0: postmask at 1400d000 {
+        compatible = "mediatek,mt8192-disp-postmask";
+        reg = <0 0x1400d000 0 0x1000>;
+        interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>;
+        power-domains = <&scpsys MT8192_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_POSTMASK0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
new file mode 100644
index 000000000000..a3c5f4c9fbcd
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
@@ -0,0 +1,115 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Read Direct Memory Access
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek Read Direct Memory Access(RDMA) component used to read the
+  data into DMA. It provides real time data to the back-end panel
+  driver, such as DSI, DPI and DP_INTF.
+  It contains one line buffer to store the sufficient pixel data.
+  RDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt2701-disp-rdma
+      - items:
+          - const: mediatek,mt8173-disp-rdma
+      - items:
+          - const: mediatek,mt8183-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt7623-disp-rdma
+              - mediatek,mt2712-disp-rdma
+          - enum:
+              - mediatek,mt2701-disp-rdma
+      - items:
+          - enum:
+              - mediatek,mt8192-disp-rdma
+          - enum:
+              - mediatek,mt8183-disp-rdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: RDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,rdma-fifo-size:
+    description:
+      rdma fifo size may be different even in same SOC, add this property to the
+      corresponding rdma.
+      The value below is the Max value which defined in hardware data sheet
+      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
+      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
+      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [8192, 5120, 2048]
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    rdma0: rdma at 1400e000 {
+        compatible = "mediatek,mt8173-disp-rdma";
+        reg = <0 0x1400e000 0 0x1000>;
+        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,rdma-fifosize = <8192>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
new file mode 100644
index 000000000000..4f08e89c1067
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display split
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display split, namely SPLIT, is used to split stream to two
+  encoders.
+  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-split
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: SPLIT Clock
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    split0: split at 14018000 {
+        compatible = "mediatek,mt8173-disp-split";
+        reg = <0 0x14018000 0 0x1000>;
+        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
new file mode 100644
index 000000000000..6e8748529e73
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek display UFOe
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek display UFOe stands for Unified Frame Optimization engine.
+  UFOe can cut the data rate for DSI port which may lead to reduce power
+  consumption.
+  UFOe device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-ufoe
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: UFOe Clock
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+
+    ufoe at 1401a000 {
+        compatible = "mediatek,mt8173-disp-ufoe";
+        reg = <0 0x1401a000 0 0x1000>;
+        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_UFOE>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
new file mode 100644
index 000000000000..aaf5649b6413
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Write Direct Memory Access
+
+maintainers:
+  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+description: |
+  Mediatek Write Direct Memory Access(WDMA) component used to write
+  the data into DMA.
+  WDMA device node must be siblings to the central MMSYS_CONFIG node.
+  For a description of the MMSYS_CONFIG binding, see
+  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+  for details.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: mediatek,mt8173-disp-wdma
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: WDMA Clock
+
+  iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
+
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+  mediatek,gce-client-reg:
+    description: The register of client driver can be configured by gce with
+      4 arguments defined in this property, such as phandle of gce, subsys id,
+      register offset and size. Each GCE subsys id is mapping to a client
+      defined in the header include/dt-bindings/gce/<chip>-gce.h.
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
+additionalProperties: false
+
+examples:
+  - |
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:27 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:27 +0800
Subject: [PATCH v15 07/12] dt-bindings: arm: mediatek: move out common module
 from display folder
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-8-jason-jh.lin@mediatek.com>

AAL, COLOR, CCORR, MUTEX, WDMA could be used by other modules,
such as MDP, so move their binding document into the common folder.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
---
 .../display/mediatek/mediatek,ccorr.yaml      | 76 ----------------
 .../display/mediatek/mediatek,wdma.yaml       | 86 -------------------
 .../mediatek/mediatek,aal.yaml                | 13 +--
 .../bindings/soc/mediatek/mediatek,ccorr.yaml | 46 ++++++++--
 .../mediatek/mediatek,color.yaml              | 15 ++--
 .../mediatek/mediatek,mutex.yaml              | 12 +--
 .../bindings/soc/mediatek/mediatek,wdma.yaml  | 47 +++++++++-
 7 files changed, 96 insertions(+), 199 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
 delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,aal.yaml (78%)
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,color.yaml (78%)
 rename Documentation/devicetree/bindings/{display => soc}/mediatek/mediatek,mutex.yaml (80%)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
deleted file mode 100644
index 6894b6999412..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Mediatek display color correction
-
-maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
-
-description: |
-  Mediatek display color correction, namely CCORR, reproduces correct color
-  on panels with different color gamut.
-  CCORR device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
-
-properties:
-  compatible:
-    oneOf:
-      - items:
-          - const: mediatek,mt8183-disp-ccorr
-      - items:
-          - const: mediatek,mt8192-disp-ccorr
-      - items:
-          - enum:
-              - mediatek,mt8195-disp-ccorr
-          - enum:
-              - mediatek,mt8192-disp-ccorr
-
-  reg:
-    maxItems: 1
-
-  interrupts:
-    maxItems: 1
-
-  power-domains:
-    description: A phandle and PM domain specifier as defined by bindings of
-      the power controller specified by phandle. See
-      Documentation/devicetree/bindings/power/power-domain.yaml for details.
-
-  clocks:
-    items:
-      - description: CCORR Clock
-
-  mediatek,gce-client-reg:
-    description: The register of client driver can be configured by gce with
-      4 arguments defined in this property, such as phandle of gce, subsys id,
-      register offset and size. Each GCE subsys id is mapping to a client
-      defined in the header include/dt-bindings/gce/<chip>-gce.h.
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    maxItems: 1
-
-required:
-  - compatible
-  - reg
-  - interrupts
-  - power-domains
-  - clocks
-
-additionalProperties: false
-
-examples:
-  - |
-
-    ccorr0: ccorr at 1400f000 {
-        compatible = "mediatek,mt8183-disp-ccorr";
-        reg = <0 0x1400f000 0 0x1000>;
-        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
-        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
-        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
-        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
-    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
deleted file mode 100644
index aaf5649b6413..000000000000
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
+++ /dev/null
@@ -1,86 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Mediatek Write Direct Memory Access
-
-maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
-
-description: |
-  Mediatek Write Direct Memory Access(WDMA) component used to write
-  the data into DMA.
-  WDMA device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
-
-properties:
-  compatible:
-    oneOf:
-      - items:
-          - const: mediatek,mt8173-disp-wdma
-
-  reg:
-    maxItems: 1
-
-  interrupts:
-    maxItems: 1
-
-  power-domains:
-    description: A phandle and PM domain specifier as defined by bindings of
-      the power controller specified by phandle. See
-      Documentation/devicetree/bindings/power/power-domain.yaml for details.
-
-  clocks:
-    items:
-      - description: WDMA Clock
-
-  iommus:
-    description:
-      This property should point to the respective IOMMU block with master port as argument,
-      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
-
-  mediatek,larb:
-    description:
-      This property should contain a phandle pointing to the local arbiter devices defined in
-      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
-      It must sort according to the local arbiter index, like larb0, larb1, larb2...
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    minItems: 1
-    maxItems: 32
-
-  mediatek,gce-client-reg:
-    description: The register of client driver can be configured by gce with
-      4 arguments defined in this property, such as phandle of gce, subsys id,
-      register offset and size. Each GCE subsys id is mapping to a client
-      defined in the header include/dt-bindings/gce/<chip>-gce.h.
-    $ref: /schemas/types.yaml#/definitions/phandle-array
-    maxItems: 1
-
-required:
-  - compatible
-  - reg
-  - interrupts
-  - power-domains
-  - clocks
-  - iommus
-
-additionalProperties: false
-
-examples:
-  - |
-
-    wdma0: wdma at 14011000 {
-        compatible = "mediatek,mt8173-disp-wdma";
-        reg = <0 0x14011000 0 0x1000>;
-        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
-        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
-        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
-        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
-        mediatek,larb = <&larb0>;
-        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
-    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
similarity index 78%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
index 225f9dd726d2..f9f57e073b37 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,aal.yaml
@@ -1,22 +1,17 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,aal.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display adaptive ambient light processor
+title: Mediatek adaptive ambient light processor
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek display adaptive ambient light processor, namely AAL,
+  Mediatek adaptive ambient light processor, namely AAL,
   is responsible for backlight power saving and sunlight visibility improving.
-  AAL device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
index cf23f4f5bd69..c4db0b42cf86 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yaml
@@ -10,17 +10,40 @@ maintainers:
   - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek color correction with 3X3 matrix.
+  Mediatek color correction, namely CCORR, reproduces correct color
+  on panels with 3X3 matrix of different color gamut.
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt8183-mdp3-ccorr
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-mdp3-ccorr
+      - items:
+          - const: mediatek,mt8183-disp-ccorr
+      - items:
+          - const: mediatek,mt8192-disp-ccorr
+      - items:
+          - enum:
+              - mediatek,mt8195-disp-ccorr
+          - enum:
+              - mediatek,mt8192-disp-ccorr
 
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
+  power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
+
+  clocks:
+    items:
+      - description: CCORR Clock
+    minItems: 1
+
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
       4 arguments defined in this property, such as phandle of gce, subsys id,
@@ -29,8 +52,10 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     maxItems: 1
 
-  clocks:
-    minItems: 1
+required:
+  - compatible
+  - reg
+  - clocks
 
 additionalProperties: false
 
@@ -45,3 +70,12 @@ examples:
       mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0xc000 0x1000>;
       clocks = <&mmsys CLK_MM_MDP_CCORR>;
     };
+
+    ccorr0: ccorr at 1400f000 {
+        compatible = "mediatek,mt8183-disp-ccorr";
+        reg = <0 0x1400f000 0 0x1000>;
+        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
+        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
+    };
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
similarity index 78%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
index bc83155b3b4c..8f8b048a8407 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,color.yaml
@@ -1,23 +1,18 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,color.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Mediatek display color processor
+title: Mediatek color processor
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
-  Mediatek display color processor, namely COLOR, provides hue, luma and
-  saturation adjustments to get better picture quality and to have one panel
+  Mediatek color processor, namely COLOR, provides hue, luma and saturation
+  adjustments to get better picture quality and to have one panel
   resemble the other in their output characteristics.
-  COLOR device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
similarity index 80%
rename from Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
rename to Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
index 6eca525eced0..6e1d1ea377c4 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,mutex.yaml
@@ -1,25 +1,19 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
+$id: http://devicetree.org/schemas/arm/mediatek/mediatek,mutex.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Mediatek mutex
 
 maintainers:
-  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
-  - Philipp Zabel <p.zabel at pengutronix.de>
+  - Matthias Brugger <matthias.bgg at gmail.com>
 
 description: |
   Mediatek mutex, namely MUTEX, is used to send the triggers signals called
-  Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
-  data path or MDP data path.
+  Start Of Frame(SOF) / End Of Frame(EOF) to each sub-modules on the data path.
   In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
   the shadow register.
-  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
-  For a description of the MMSYS_CONFIG binding, see
-  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
-  for details.
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
index 4057b5232e45..7e5d1a6a79a9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
@@ -15,13 +15,18 @@ description: |
 
 properties:
   compatible:
-    items:
-      - enum:
-          - mediatek,mt8183-mdp3-wdma
+    oneOf:
+      - items:
+          - const: mediatek,mt8183-mdp3-wdma
+      - items:
+          - const: mediatek,mt8173-disp-wdma
 
   reg:
     maxItems: 1
 
+  interrupts:
+    maxItems: 1
+
   mediatek,gce-client-reg:
     description: The register of client driver can be configured by gce with
       4 arguments defined in this property, such as phandle of gce, subsys id,
@@ -31,14 +36,39 @@ properties:
     maxItems: 1
 
   power-domains:
+    description: A phandle and PM domain specifier as defined by bindings of
+      the power controller specified by phandle. See
+      Documentation/devicetree/bindings/power/power-domain.yaml for details.
     maxItems: 1
 
   clocks:
+    items:
+      - description: WDMA Clock
     minItems: 1
 
   iommus:
+    description:
+      This property should point to the respective IOMMU block with master port as argument,
+      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
     maxItems: 1
 
+  mediatek,larb:
+    description:
+      This property should contain a phandle pointing to the local arbiter devices defined in
+      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
+      It must sort according to the local arbiter index, like larb0, larb1, larb2...
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    maxItems: 32
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - power-domains
+  - clocks
+  - iommus
+
 additionalProperties: false
 
 examples:
@@ -56,3 +86,14 @@ examples:
       clocks = <&mmsys CLK_MM_MDP_WDMA0>;
       iommus = <&iommu>;
     };
+
+    wdma0: wdma at 14011000 {
+        compatible = "mediatek,mt8173-disp-wdma";
+        reg = <0 0x14011000 0 0x1000>;
+        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
+        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
+        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
+        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
+        mediatek,larb = <&larb0>;
+        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
+    };
-- 
2.18.0



From jason-jh.lin at mediatek.com  Tue Jan 25 23:19:22 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 15:19:22 +0800
Subject: [PATCH v15 02/12] dt-bindings: arm: mediatek: mmsys: add mt8195 SoC
 binding
In-Reply-To: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
Message-ID: <20220126071932.32615-3-jason-jh.lin@mediatek.com>

There are 2 mmsys, namely vdosys0 and vdosys1 in mt8195.
Each of them is bound to a display pipeline, so add their
definition in mtk-mmsys documentation with 2 compatibles.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml        | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
index 474bcf9c250d..a978cdd32575 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
@@ -31,6 +31,8 @@ properties:
               - mediatek,mt8183-mmsys
               - mediatek,mt8192-mmsys
               - mediatek,mt8365-mmsys
+              - mediatek,mt8195-vdosys0
+              - mediatek,mt8195-vdosys1
           - const: syscon
       - items:
           - const: mediatek,mt7623-mmsys
-- 
2.18.0



From mohammad.athari.ismail at intel.com  Tue Jan 25 23:23:22 2022
From: mohammad.athari.ismail at intel.com (Ismail, Mohammad Athari)
Date: Wed, 26 Jan 2022 07:23:22 +0000
Subject: [PATCH net v2 2/2] net: stmmac: skip only stmmac_ptp_register
 when resume from suspend
In-Reply-To: <20220125201756.1606e1c4@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <20220125032324.4055-1-mohammad.athari.ismail@intel.com>
 <20220125032324.4055-3-mohammad.athari.ismail@intel.com>
 <20220125201756.1606e1c4@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <CO1PR11MB4771A6297E5E91D063DBDCA6D5209@CO1PR11MB4771.namprd11.prod.outlook.com>



> -----Original Message-----
> From: Jakub Kicinski <kuba at kernel.org>
> Sent: Wednesday, January 26, 2022 12:18 PM
> To: Ismail, Mohammad Athari <mohammad.athari.ismail at intel.com>
> Cc: Giuseppe Cavallaro <peppe.cavallaro at st.com>; Alexandre Torgue
> <alexandre.torgue at st.com>; Jose Abreu <joabreu at synopsys.com>; David
> S . Miller <davem at davemloft.net>; Maxime Coquelin
> <mcoquelin.stm32 at gmail.com>; Ong, Boon Leong
> <boon.leong.ong at intel.com>; Voon, Weifeng <weifeng.voon at intel.com>;
> Wong, Vee Khee <vee.khee.wong at intel.com>; Huacai Chen
> <chenhuacai at kernel.org>; Alexandre Torgue
> <alexandre.torgue at foss.st.com>; netdev at vger.kernel.org; linux-stm32 at st-
> md-mailman.stormreply.com; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; stable at vger.kernel.org
> Subject: Re: [PATCH net v2 2/2] net: stmmac: skip only stmmac_ptp_register
> when resume from suspend
> 
> On Tue, 25 Jan 2022 11:23:24 +0800 Mohammad Athari Bin Ismail wrote:
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index d7e261768f73..b8e5e19e6f7b 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -880,11 +880,12 @@
> EXPORT_SYMBOL_GPL(stmmac_init_tstamp_counter);
> >  /**
> >   * stmmac_init_ptp - init PTP
> >   * @priv: driver private structure
> > + * @ptp_register: register PTP if set
> >   * Description: this is to verify if the HW supports the PTPv1 or PTPv2.
> >   * This is done by looking at the HW cap. register.
> >   * This function also registers the ptp driver.
> >   */
> > -static int stmmac_init_ptp(struct stmmac_priv *priv)
> > +static int stmmac_init_ptp(struct stmmac_priv *priv, bool
> > +ptp_register)
> >  {
> >  	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
> >  	int ret;
> > @@ -914,7 +915,8 @@ static int stmmac_init_ptp(struct stmmac_priv
> *priv)
> >  	priv->hwts_tx_en = 0;
> >  	priv->hwts_rx_en = 0;
> >
> > -	stmmac_ptp_register(priv);
> > +	if (ptp_register)
> > +		stmmac_ptp_register(priv);
> 
> stmmac_init_ptp() only has one caller, and the registration step is last.
> Wouldn't it be better to move the stmmac_ptp_register() call out to
> stmmac_hw_setup()? That way we don't need to pass extra arguments to
> init.

Yes agree with you suggestion. Will fix it in v3. Thanks.

-Athari-

> 
> >  	return 0;
> >  }
> > @@ -3241,7 +3243,7 @@ static int stmmac_fpe_start_wq(struct
> > stmmac_priv *priv)
> >  /**
> >   * stmmac_hw_setup - setup mac in a usable state.
> >   *  @dev : pointer to the device structure.
> > - *  @init_ptp: initialize PTP if set
> > + *  @ptp_register: register PTP if set
> >   *  Description:
> >   *  this is the main function to setup the HW in a usable state because the
> >   *  dma engine is reset, the core registers are configured (e.g. AXI,
> > @@ -3251,7 +3253,7 @@ static int stmmac_fpe_start_wq(struct
> stmmac_priv *priv)
> >   *  0 on success and an appropriate (-)ve integer as defined in errno.h
> >   *  file on failure.
> >   */
> > -static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
> > +static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
> >  {
> >  	struct stmmac_priv *priv = netdev_priv(dev);
> >  	u32 rx_cnt = priv->plat->rx_queues_to_use; @@ -3308,13 +3310,11
> @@
> > static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
> >
> >  	stmmac_mmc_setup(priv);
> >
> > -	if (init_ptp) {
> > -		ret = stmmac_init_ptp(priv);
> > -		if (ret == -EOPNOTSUPP)
> > -			netdev_warn(priv->dev, "PTP not supported by
> HW\n");
> > -		else if (ret)
> > -			netdev_warn(priv->dev, "PTP init failed\n");
> > -	}
> > +	ret = stmmac_init_ptp(priv, ptp_register);
> > +	if (ret == -EOPNOTSUPP)
> > +		netdev_warn(priv->dev, "PTP not supported by HW\n");
> > +	else if (ret)
> > +		netdev_warn(priv->dev, "PTP init failed\n");


From miles.chen at mediatek.com  Tue Jan 25 23:29:23 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 15:29:23 +0800
Subject: [PATCH 21/31] clk: mediatek: cpumux: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-22-wenst@chromium.org>
References: <20220122091731.283592-22-wenst@chromium.org>
Message-ID: <20220126072923.10391-1-miles.chen@mediatek.com>

> The cpumux clk type registration function does not stop or return errors
> if any clk failed to be registered, nor does it implement an error
> handling path. This may result in a partially working device if any
> step failed.
> 
> Make the register function return proper error codes, and bail out if
> errors occur. Proper cleanup, i.e. unregister any clks that were
> successfully registered, is done in the new error path.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-cpumux.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
> index 658aee789f44..499c60432280 100644
> --- a/drivers/clk/mediatek/clk-cpumux.c
> +++ b/drivers/clk/mediatek/clk-cpumux.c
> @@ -123,13 +123,26 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
>  		clk = mtk_clk_register_cpumux(mux, regmap);
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
>  		clk_data->clks[mux->id] = clk;
>  	}
>  
>  	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_composite *mux = &clks[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
> +
> +		mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
> +		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
> +	}
> +
> +	return PTR_ERR(clk);
>  }
>  
>  void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Tue Jan 25 23:26:47 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 15:26:47 +0800
Subject: [PATCH 20/31] clk: mediatek: mtk: Clean up included headers
In-Reply-To: <20220122091731.283592-21-wenst@chromium.org>
References: <20220122091731.283592-21-wenst@chromium.org>
Message-ID: <20220126072647.8794-1-miles.chen@mediatek.com>

> Some included headers aren't actually used anywhere, while other headers
> with the declaration of functions and structures aren't directly
> included.
> 
> Get rid of the unused ones, and add the ones that should be included
> directly.
> 
> On the header side, replace headers that are included purely for data
> structure definitions with forward declarations. This decreases the
> amount of preprocessing and compilation effort required for each
> inclusion.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mtk.c | 13 ++++++-------
>  drivers/clk/mediatek/clk-mtk.h | 12 ++++++------
>  2 files changed, 12 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index cd76e1d80242..d2c50186cceb 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -4,17 +4,16 @@
>   * Author: James Liao <jamesjj.liao at mediatek.com>
>   */
>  
> -#include <linux/of.h>
> -#include <linux/of_address.h>
> +#include <linux/bitops.h>
> +#include <linux/clk-provider.h>
>  #include <linux/err.h>
>  #include <linux/io.h>
> -#include <linux/slab.h>
> -#include <linux/delay.h>
> -#include <linux/clkdev.h>
> -#include <linux/module.h>
>  #include <linux/mfd/syscon.h>
> -#include <linux/device.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
>  
>  #include "clk-mtk.h"
>  #include "clk-gate.h"
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 4fa658f5d934..7f902581a115 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -7,19 +7,19 @@
>  #ifndef __DRV_CLK_MTK_H
>  #define __DRV_CLK_MTK_H
>  
> -#include <linux/regmap.h>
> -#include <linux/bitops.h>
>  #include <linux/clk-provider.h>
> -#include <linux/platform_device.h>
> -
> -struct clk;
> -struct clk_onecell_data;
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/spinlock.h>
> +#include <linux/types.h>
>  
>  #define MAX_MUX_GATE_BIT	31
>  #define INVALID_MUX_GATE_BIT	(MAX_MUX_GATE_BIT + 1)
>  
>  #define MHZ (1000 * 1000)
>  
> +struct platform_device;
> +
>  struct mtk_fixed_clk {
>  	int id;
>  	const char *name;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From cki-project at redhat.com  Tue Jan 25 23:39:50 2022
From: cki-project at redhat.com (CKI Project)
Date: Wed, 26 Jan 2022 07:39:50 -0000
Subject: =?utf-8?q?=F0=9F=92=A5?= PANICKED: Test report for kernel 5.17.0-rc1
 (arm-next, e783362e)
Message-ID: <cki.G5JSKGQZR2EWI8OX9FV0@redhat.com>



Check out this report and any autotriaged failures in our web dashboard:
    https://datawarehouse.cki-project.org/kcidb/checkouts/30202

Hello,

We ran automated tests on a recent commit from this kernel tree:

       Kernel repo: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git
            Commit: e783362eb54c - Linux 5.17-rc1

The results of these automated tests are provided below.

    Overall result: FAILED (see details below)
             Merge: OK
           Compile: OK
             Tests: PANICKED
    Targeted tests: NO

All kernel binaries, config files, and logs are available for download here:

  https://arr-cki-prod-datawarehouse-public.s3.amazonaws.com/index.html?prefix=datawarehouse-public/2022/01/25/455767689

One or more kernel tests failed:

    aarch64:
     ? selinux-policy: serge-testsuite
     ? stress: stress-ng - os
     ? xfstests - xfs
     ? selinux-policy: serge-testsuite
     ? LTP - syscalls
     ? LTP - fs
     ? LTP - syscalls
     ? LTP - fs

We hope that these logs can help you find the problem quickly. For the full
detail on our testing procedures, please scroll to the bottom of this message.

Please reply to this email if you have any questions about the tests that we
ran or if you have any suggestions on how to make future tests more effective.

        ,-.   ,-.
       ( C ) ( K )  Continuous
        `-',-.`-'   Kernel
          ( I )     Integration
           `-'
______________________________________________________________________________

Compile testing
---------------

We compiled the kernel for 1 architecture:

    aarch64:
      make options: make -j24 INSTALL_MOD_STRIP=1 targz-pkg



Hardware testing
----------------
We booted each kernel and ran the following tests:

  aarch64:
    Host 1:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? IPMI driver test
       ? IPMItool loop stress test
       ? selinux-policy: serge-testsuite
       ? Storage blktests - blk
       ? Storage block - filesystem fio test
       ? Storage block - queue scheduler test
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? stress: stress-ng - interrupt
       ? stress: stress-ng - cpu
       ? stress: stress-ng - cpu-cache
       ? stress: stress-ng - memory
       ? ? Podman system test - as root
       ? ? Podman system test - as user
       ? ? xfstests - btrfs
       ? ? Storage blktests - nvme-tcp
       ? ? Storage block - storage fio numa
       ? ? lvm cache test
       ? ? stress: stress-ng - os

    Host 2:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ? ??? SELinux Custom Module Setup
       ??? Boot test
       ??? Reboot test
       ? ??? Storage blktests - srp

    Host 3:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? Networking bridge: sanity - mlx5
       ? Ethernet drivers sanity - mlx5

    Host 4:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? Networking bridge: sanity - mlx5
       ? Ethernet drivers sanity - mlx5

    Host 5:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test

    Host 6:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? ? Storage blktests - nvmeof-mp

    Host 7:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? xfstests - ext4
       ? xfstests - xfs
       ? IPMI driver test
       ? IPMItool loop stress test
       ? selinux-policy: serge-testsuite
       ? Storage blktests - blk
       ? Storage block - filesystem fio test
       ? Storage block - queue scheduler test
       ? storage: software RAID testing
       ? Storage: swraid mdadm raid_module test
       ? stress: stress-ng - interrupt
       ? stress: stress-ng - cpu
       ? stress: stress-ng - cpu-cache
       ? stress: stress-ng - memory
       ? ? Podman system test - as root
       ? ? Podman system test - as user
       ? ? xfstests - btrfs
       ? ? Storage blktests - nvme-tcp
       ? ? Storage block - storage fio numa
       ? ? lvm cache test
       ? ? stress: stress-ng - os

    Host 8:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ? ? SELinux Custom Module Setup
       ? Boot test
       ??? Reboot test
       ? ??? Storage blktests - srp

    Host 9:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP - cve
       ? LTP - sched
       ? LTP - syscalls
       ? LTP - can
       ? LTP - commands
       ? LTP - containers
       ? LTP - dio
       ? LTP - fs
       ??? LTP - fsx
       ??? LTP - math
       ??? LTP - hugetlb
       ??? LTP - mm
       ??? LTP - nptl
       ??? LTP - pty
       ??? LTP - ipc
       ??? LTP - tracing
       ??? LTP: openposix test suite
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? NFS Connectathon
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: dm/common
       ??? lvm snapper test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? i2c: i2cdetect sanity
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? Networking: igmp conformance test
       ? ??? audit: audit testsuite test

    Host 10:
       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? ACPI table test
       ? ACPI enabled test
       ? LTP - cve
       ? LTP - sched
       ? LTP - syscalls
       ? LTP - can
       ? LTP - commands
       ? LTP - containers
       ? LTP - dio
       ? LTP - fs
       ??? LTP - fsx
       ??? LTP - math
       ??? LTP - hugetlb
       ??? LTP - mm
       ??? LTP - nptl
       ??? LTP - pty
       ??? LTP - ipc
       ??? LTP - tracing
       ??? LTP: openposix test suite
       ??? CIFS Connectathon
       ??? POSIX pjd-fstest suites
       ??? NFS Connectathon
       ??? Loopdev Sanity
       ??? jvm - jcstress tests
       ??? Memory: fork_mem
       ??? Memory function: memfd_create
       ??? AMTU (Abstract Machine Test Utility)
       ??? Networking bridge: sanity
       ??? Ethernet drivers sanity
       ??? Networking socket: fuzz
       ??? Networking route: pmtu
       ??? Networking route_func - local
       ??? Networking route_func - forward
       ??? Networking TCP: keepalive test
       ??? Networking UDP: socket
       ??? Networking cki netfilter test
       ??? Networking tunnel: geneve basic test
       ??? Networking tunnel: gre basic
       ??? L2TP basic test
       ??? Networking tunnel: vxlan basic
       ??? Networking ipsec: basic netns - transport
       ??? Networking ipsec: basic netns - tunnel
       ??? Libkcapi AF_ALG test
       ??? pciutils: update pci ids test
       ??? ALSA PCM loopback test
       ??? ALSA Control (mixer) Userspace Element test
       ??? storage: dm/common
       ??? lvm snapper test
       ??? storage: SCSI VPD
       ??? trace: ftrace/tracer
       ? ??? i2c: i2cdetect sanity
       ? ??? Firmware test suite
       ? ??? Memory function: kaslr
       ? ??? Networking: igmp conformance test
       ? ??? audit: audit testsuite test

    Host 11:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? ??? Storage blktests - srp

    Host 12:

       ? Internal infrastructure issues prevented one or more tests (marked
       with ???) from running on this architecture.
       This is not the fault of the kernel that was tested.

       ? ? SELinux Custom Module Setup
       ? Boot test
       ? Reboot test
       ? ??? Storage blktests - srp

  Test sources: https://gitlab.com/cki-project/kernel-tests
    ? Pull requests are welcome for new tests or improvements to existing tests!

Aborted tests
-------------
Tests that didn't complete running successfully are marked with ???.
If this was caused by an infrastructure issue, we try to mark that
explicitly in the report.

Waived tests
------------
If the test run included waived tests, they are marked with ?. Such tests are
executed but their results are not taken into account. Tests are waived when
their results are not reliable enough, e.g. when they're just introduced or are
being fixed.

Testing timeout
---------------
We aim to provide a report within reasonable timeframe. Tests that haven't
finished running yet are marked with ?.
Targeted tests
--------------
Test runs for patches always include a set of base tests, plus some
tests chosen based on the file paths modified by the patch. The latter
are called "targeted tests". If no targeted tests are run, that means
no patch-specific tests are available. Please, consider contributing a
targeted test for related patches to increase test coverage. See
https://docs.engineering.redhat.com/x/_wEZB for more details.



From miles.chen at mediatek.com  Tue Jan 25 23:42:42 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 15:42:42 +0800
Subject: [PATCH 22/31] clk: mediatek: gate: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-23-wenst@chromium.org>
References: <20220122091731.283592-23-wenst@chromium.org>
Message-ID: <20220126074242.18291-1-miles.chen@mediatek.com>

> The gate clk type registration function does not stop or return errors
> if any clk failed to be registered, nor does it implement an error
> handling path. This may result in a partially working device if any
> step failed.
> 
> Make the register function return proper error codes, and bail out if
> errors occur. Proper cleanup, i.e. unregister any clks that were
> successfully registered, is done in the new error path.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-gate.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
> index e8881ae1489a..631ff170b7b9 100644
> --- a/drivers/clk/mediatek/clk-gate.c
> +++ b/drivers/clk/mediatek/clk-gate.c
> @@ -237,13 +237,26 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
>  		clk_data->clks[gate->id] = clk;
>  	}
>  
>  	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_gate *gate = &clks[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[gate->id]))
> +			continue;
> +
> +		mtk_clk_unregister_gate(clk_data->clks[gate->id]);
> +		clk_data->clks[gate->id] = ERR_PTR(-ENOENT);
> +	}
> +
> +	return PTR_ERR(clk);
>  }
>  
>  int mtk_clk_register_gates(struct device_node *node,
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From shawnguo at kernel.org  Tue Jan 25 23:44:32 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 15:44:32 +0800
Subject: (EXT) Re: (EXT) Re: [PATCH] arm64: dts: imx8mm-venice-gw73xx-0x:
 add dt overlays for serial modes
In-Reply-To: <6686721.lOV4Wx5bFT@steina-w>
References: <20211214213630.14819-1-tharvey@gateworks.com>
 <2226437.ElGaqSPkdT@steina-w>
 <CAJ+vNU2PxF=9VwMv4f8N5W5Gs2Ynxdn9jHTSkWH7zd3Fo5hBiw@mail.gmail.com>
 <6686721.lOV4Wx5bFT@steina-w>
Message-ID: <20220126074432.GF4686@dragon>

On Wed, Jan 12, 2022 at 07:58:00AM +0100, Alexander Stein wrote:
> Am Dienstag, 11. Januar 2022, 18:53:29 CET schrieb Tim Harvey:
> > On Mon, Jan 10, 2022 at 11:20 PM Alexander Stein
> > 
> > <alexander.stein at ew.tq-group.com> wrote:
> > > Am Dienstag, 11. Januar 2022, 01:00:21 CET schrieb Tim Harvey:
> > > > [SNIP]
> > > > 
> > > > > diff --git a/arch/arm64/boot/dts/freescale/Makefile
> > > > > b/arch/arm64/boot/dts/freescale/Makefile index
> > > > > a14a6173b765..5ec8d59347b6
> > > > > 100644
> > > > > --- a/arch/arm64/boot/dts/freescale/Makefile
> > > > > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > > > > @@ -44,6 +44,9 @@ dtb-$(CONFIG_ARCH_MXC) +=
> > > > > imx8mm-var-som-symphony.dtb
> > > > > 
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
> > > > > 
> > > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs422.dtbo
> > > > > +dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x-rs485.dtbo
> > > > > 
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
> > > > >  dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
> > > > 
> > > > [SNIP]
> > > > I'm mostly interested to see if my approach to dt fragments here and
> > > > the naming of the files makes sense to others.
> > > > 
> > > > This patch causes the kernel to build dtbo files for:
> > > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs232-rts.dtbo
> > > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs422.dtbo
> > > > arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dtbo
> > > > 
> > > > The intention is that these files are used by boot firmware (U-Boot)
> > > > to adjust the dtb before passing it to the kernel.
> > > 
> > > Hi Tim,
> > > 
> > > do these dtbo actually work? I'm wondering because I was trying to
> > > useoverlays myself and noticed that the had to be compiled with -@ for
> > > u-boot to be able
> > > to apply them. Apparently there are 2 possibilities:
> > Alexander,
> > 
> > Yes, they work, but I do manually set DTC_FLAGS=-@ when building
> > kernel dtbs to make them work.
> 
> I see, I expected something like this. That's why I responded to you.
> 
> > > * Set "DTC_FLAGS_[dtb] := -@" yourself
> > > See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> > > commit/?id=e426d63e752bdbe7d5ba2d872319dde9ab844a07
> > > 
> > > * Use dedicated overlay target
> > > See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
> > > commit/?id=15d16d6dadf6947ac7f9a686c615995c5a426ce2
> > > 
> > > You use neither of them. IIRC just naming the target file .dtbo will not
> > > apply symbols (-Q) during dtc call. Can you verify using 'V=1'
> > > Also I'm wondering which way is the best to go.
> > 
> > I wasn't aware there was a way to do this via Makefiles. It seems that
> > perhaps Rob's approach with 'kbuild: Add generic rule to apply
> > fdtoverlay' is a way to avoid having to add them all manually in the
> > first approach? I must admit I'm not sure how to use that.
> 
> I tried using this myself for my custom board. I feel it is a bit cumbersome 
> to get it right.
> See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/
> arch/arm64/boot/dts/xilinx/Makefile for an example.
> 
> Essentially you define your .dtb as before and add another target (e.g. sm-
> k26-revA-sck-kv-g-revA-dtbs) where you add your .dtbo _after_ the original 
> .dtb. This target needs to be added to 'dtb-y' as before.
> 
> I suspect this way is needed to check the .dtbo against the base .dtb if it 
> actually matches.

Yeah, I like this check.  Tim, could you update your patch to follow
this pattern?

Shawn


From roger.lu at mediatek.com  Tue Jan 25 23:49:09 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Wed, 26 Jan 2022 15:49:09 +0800
Subject: [PATCH v21 8/8] soc: mediatek: SVS: add mt8192 SVS GPU driver
In-Reply-To: <2c0e89c6-6e9c-9d12-703f-d71e22023e7a@collabora.com>
References: <20220107095200.4389-1-roger.lu@mediatek.com>
 <20220107095200.4389-9-roger.lu@mediatek.com>
 <2c0e89c6-6e9c-9d12-703f-d71e22023e7a@collabora.com>
Message-ID: <bcc104a362f637d92e69045dc57dd02c17c45975.camel@mediatek.com>

Hi AngeloGioacchino,

Sorry for the late reply.

On Fri, 2022-01-07 at 15:33 +0100, AngeloGioacchino Del Regno wrote:
> Il 07/01/22 10:52, Roger Lu ha scritto:
> > mt8192 SVS GPU uses 2-line (high/low bank) HW architecture to provide
> > bank voltages. High bank helps update higher frequency's voltage
> > and low bank helps update lower frequency's voltage.
> > 
> > Signed-off-by: Roger Lu <roger.lu at mediatek.com>
> > ---
> >   drivers/soc/mediatek/mtk-svs.c | 469 ++++++++++++++++++++++++++++++++-
> >   1 file changed, 464 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
> > index 93cdaecadd6d..bec6524ab33a 100644
> > --- a/drivers/soc/mediatek/mtk-svs.c
> > +++ b/drivers/soc/mediatek/mtk-svs.c
> 
> ..snip..
> 
> > @@ -639,9 +706,11 @@ static int svs_status_debug_show(struct seq_file *m,
> > void *v)
> >   
> >   	ret = svs_get_zone_temperature(svsb->tzone_name, &tzone_temp);
> >   	if (ret)
> > -		seq_printf(m, "%s: temperature ignore\n", svsb->name);
> > +		seq_printf(m, "%s: temperature ignore, turn_pt = %u\n",
> > +			   svsb->name, svsb->turn_pt);
> >   	else
> > -		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
> > +		seq_printf(m, "%s: temperature = %d, turn_pt = %u\n",
> > +			   svsb->name, tzone_temp, svsb->turn_pt);
> >   
> >   	for (i = 0; i < svsb->opp_count; i++) {
> >   		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
> > @@ -784,6 +853,181 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1,
> > u32 fx)
> >   	return DIV_ROUND_UP(vx, 100);
> >   }
> >   
> > +static void svs_get_bank_volts_v3(struct svs_platform *svsp)
> > +{
> > +	struct svs_bank *svsb = svsp->pbank;
> > +	u32 i, j, *vop, vop74, vop30, mask7_0 = GENMASK(7, 0);
> > +	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;
> 
> mask7_0, bits8, reg_bytes are constants, and it's not right to declare
> constants
> as variables like you're doing here.
> 
> Please replace all usages of `mask7_0` with either a definition or with the
> call
> to the GENMASK macro;
> also, replace all usages of `bits8` with a definition, or just 8;
> finally, either make `reg_bytes` a `const u8` or a definition.
> 
> 
> In my opinion, a #define would be preferred, since the exact same comments on
> the exact same values also apply to function svs_set_bank_freq_pct_v3().
> 
> After that fix, you'll get my R-b.
> 
> I feel like v22 will be golden :)

No problem. I'll use GENMASK macro and replace bits8/reg_bytes with 
definition. Thanks for the tutorial a lot. :)

> 
> Regards,
> - Angelo
> 
> > +	u32 middle_index = (svsb->opp_count / 2);
> > +	u32 opp_start = 0, opp_stop = 0, turn_pt = svsb->turn_pt;
> > +
> > +	if (svsb->phase == SVSB_PHASE_MON &&
> > +	    svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
> > +		return;
> > +
> > +	vop74 = svs_readl_relaxed(svsp, VOP74);
> > +	vop30 = svs_readl_relaxed(svsp, VOP30);
> > +
> > +	/* Target is to set svsb->volt[] by algorithm */
> > +	if (turn_pt < middle_index) {
> > +		if (svsb->type == SVSB_HIGH) {
> > +			/* volt[0] ~ volt[turn_pt - 1] */
> > +			for (i = 0; i < turn_pt; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				vop = (shift_byte < reg_bytes) ? &vop30 :
> > +								 &vop74;
> > +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> > +				shift_byte++;
> > +			}
> > +		} else if (svsb->type == SVSB_LOW) {
> > +			/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
> > +			j = svsb->opp_count - 7;
> > +			svsb->volt[turn_pt] = vop30 & mask7_0;
> > +			shift_byte++;
> > +			for (i = j; i < svsb->opp_count; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				vop = (shift_byte < reg_bytes) ? &vop30 :
> > +								 &vop74;
> > +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> > +				shift_byte++;
> > +			}
> > +
> > +			/* volt[turn_pt + 1] ~ volt[j - 1] by interpolate */
> > +			for (i = turn_pt + 1; i < j; i++)
> > +				svsb->volt[i] =
> > +					interpolate(svsb->freq_pct[turn_pt],
> > +						    svsb->freq_pct[j],
> > +						    svsb->volt[turn_pt],
> > +						    svsb->volt[j],
> > +						    svsb->freq_pct[i]);
> > +		}
> > +	} else {
> > +		if (svsb->type == SVSB_HIGH) {
> > +			/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
> > +			j = turn_pt - 7;
> > +			svsb->volt[0] = vop30 & mask7_0;
> > +			shift_byte++;
> > +			for (i = j; i < turn_pt; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				vop = (shift_byte < reg_bytes) ? &vop30 :
> > +								 &vop74;
> > +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> > +				shift_byte++;
> > +			}
> > +
> > +			/* volt[1] ~ volt[j - 1] by interpolate */
> > +			for (i = 1; i < j; i++)
> > +				svsb->volt[i] =
> > +					interpolate(svsb->freq_pct[0],
> > +						    svsb->freq_pct[j],
> > +						    svsb->volt[0],
> > +						    svsb->volt[j],
> > +						    svsb->freq_pct[i]);
> > +		} else if (svsb->type == SVSB_LOW) {
> > +			/* volt[turn_pt] ~ volt[opp_count - 1] */
> > +			for (i = turn_pt; i < svsb->opp_count; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				vop = (shift_byte < reg_bytes) ? &vop30 :
> > +								 &vop74;
> > +				svsb->volt[i] = (*vop >> b_sft) & mask7_0;
> > +				shift_byte++;
> > +			}
> > +		}
> > +	}
> > +
> > +	if (svsb->type == SVSB_HIGH) {
> > +		opp_start = 0;
> > +		opp_stop = svsb->turn_pt;
> > +	} else if (svsb->type == SVSB_LOW) {
> > +		opp_start = svsb->turn_pt;
> > +		opp_stop = svsb->opp_count;
> > +	}
> > +
> > +	for (i = opp_start; i < opp_stop; i++)
> > +		if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT)
> > +			svsb->volt[i] -= svsb->dvt_fixed;
> > +}
> > +
> > +static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
> > +{
> > +	struct svs_bank *svsb = svsp->pbank;
> > +	u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0;
> > +	u32 b_sft, bits8 = 8, shift_byte = 0, reg_bytes = 4;
> > +	u32 middle_index = (svsb->opp_count / 2);
> > +	u32 turn_pt = middle_index;
> > +
> > +	for (i = 0; i < svsb->opp_count; i++) {
> > +		if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) {
> > +			svsb->turn_pt = i;
> > +			break;
> > +		}
> > +	}
> > +
> > +	turn_pt = svsb->turn_pt;
> > +
> > +	/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
> > +	if (turn_pt < middle_index) {
> > +		if (svsb->type == SVSB_HIGH) {
> > +			/* Edge case for preventing freq_pct30 from being 0 */
> > +			if (turn_pt == 0)
> > +				freq_pct30 = svsb->freq_pct[0];
> > +
> > +			/* freq_pct[0] ~ freq_pct[turn_pt - 1] */
> > +			for (i = 0; i < turn_pt; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				freq_pct = (shift_byte < reg_bytes) ?
> > +					   &freq_pct30 : &freq_pct74;
> > +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> > +				shift_byte++;
> > +			}
> > +		} else if (svsb->type == SVSB_LOW) {
> > +			/*
> > +			 * freq_pct[turn_pt] +
> > +			 * freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
> > +			 */
> > +			freq_pct30 = svsb->freq_pct[turn_pt];
> > +			shift_byte++;
> > +			j = svsb->opp_count - 7;
> > +			for (i = j; i < svsb->opp_count; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				freq_pct = (shift_byte < reg_bytes) ?
> > +					   &freq_pct30 : &freq_pct74;
> > +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> > +				shift_byte++;
> > +			}
> > +		}
> > +	} else {
> > +		if (svsb->type == SVSB_HIGH) {
> > +			/*
> > +			 * freq_pct[0] +
> > +			 * freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
> > +			 */
> > +			freq_pct30 = svsb->freq_pct[0];
> > +			shift_byte++;
> > +			j = turn_pt - 7;
> > +			for (i = j; i < turn_pt; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				freq_pct = (shift_byte < reg_bytes) ?
> > +					   &freq_pct30 : &freq_pct74;
> > +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> > +				shift_byte++;
> > +			}
> > +		} else if (svsb->type == SVSB_LOW) {
> > +			/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
> > +			for (i = turn_pt; i < svsb->opp_count; i++) {
> > +				b_sft = bits8 * (shift_byte % reg_bytes);
> > +				freq_pct = (shift_byte < reg_bytes) ?
> > +					   &freq_pct30 : &freq_pct74;
> > +				*freq_pct |= (svsb->freq_pct[i] << b_sft);
> > +				shift_byte++;
> > +			}
> > +		}
> > +	}
> > +
> > +	svs_writel_relaxed(svsp, freq_pct74, FREQPCT74);
> > +	svs_writel_relaxed(svsp, freq_pct30, FREQPCT30);
> > +}
> > +
> >   static void svs_get_bank_volts_v2(struct svs_platform *svsp)
> >   {
> >   	struct svs_bank *svsb = svsp->pbank;
> 
> 
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> 
https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-mediatek__;!!CTRNKA9wMg0ARbw!2hHinI997WLSwDhGwMLxsnPzZMt8US0HmcDwqKvo2yvyiHuJ7AR4BSd7C_Z2haFK$
>  



From krzysztof.kozlowski at canonical.com  Wed Jan 26 00:10:13 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 09:10:13 +0100
Subject: [PATCH 01/12] arm64: dts: exynos: add USB DWC3 supplies to
 Espresso board
In-Reply-To: <CAGOxZ51zavNVpvUv0C17Cit+pdkERC70m5Ez3ELGpFh8tGDozQ@mail.gmail.com>
References: <20220123111644.25540-1-krzysztof.kozlowski@canonical.com>
 <20220123111644.25540-2-krzysztof.kozlowski@canonical.com>
 <CAGOxZ51zavNVpvUv0C17Cit+pdkERC70m5Ez3ELGpFh8tGDozQ@mail.gmail.com>
Message-ID: <cabc3a91-807c-856b-5b74-03788781e2a0@canonical.com>

On 26/01/2022 07:58, Alim Akhtar wrote:
> Hi Krzysztof
> 
> On Mon, Jan 24, 2022 at 1:34 PM Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> Add required voltage regulators for USB DWC3 block on Exynos7 Espresso
>> board.  Due to lack of schematics of Espresso board, the choice of
>> regulators is approximate.  What bindings call VDD10, for Exynos7 should
>> be actually called VDD09 (0.9 V).  Use regulators with a matching
>> voltage range based on vendor sources for Meizu Pro 5 M576 handset (also
>> with Exynos7420).
>>
> 
> I checked Espresso board schematic, it is 0.9V for the USB and supplied by LDO4
> 

Thanks for checking!


Best regards,
Krzysztof


From yangyicong at hisilicon.com  Wed Jan 26 00:09:46 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Wed, 26 Jan 2022 16:09:46 +0800
Subject: [PATCH v2 1/2] sched: Add per_cpu cluster domain info and
 cpus_share_resources API
In-Reply-To: <20220126080947.4529-1-yangyicong@hisilicon.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
Message-ID: <20220126080947.4529-2-yangyicong@hisilicon.com>

From: Barry Song <song.bao.hua at hisilicon.com>

Add per-cpu cluster domain info and cpus_share_resources() API.
This is the preparation for the optimization of select_idle_cpu()
on platforms with cluster scheduler level.

Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 include/linux/sched/sd_flags.h |  7 +++++++
 include/linux/sched/topology.h |  8 +++++++-
 kernel/sched/core.c            | 12 ++++++++++++
 kernel/sched/sched.h           |  2 ++
 kernel/sched/topology.c        | 15 +++++++++++++++
 5 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/include/linux/sched/sd_flags.h b/include/linux/sched/sd_flags.h
index 57bde66d95f7..42ed454e8b18 100644
--- a/include/linux/sched/sd_flags.h
+++ b/include/linux/sched/sd_flags.h
@@ -109,6 +109,13 @@ SD_FLAG(SD_ASYM_CPUCAPACITY_FULL, SDF_SHARED_PARENT | SDF_NEEDS_GROUPS)
  */
 SD_FLAG(SD_SHARE_CPUCAPACITY, SDF_SHARED_CHILD | SDF_NEEDS_GROUPS)
 
+/*
+ * Domain members share CPU cluster (LLC tags or L2 cache)
+ *
+ * NEEDS_GROUPS: Clusters are shared between groups.
+ */
+SD_FLAG(SD_CLUSTER, SDF_NEEDS_GROUPS)
+
 /*
  * Domain members share CPU package resources (i.e. caches)
  *
diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h
index 8054641c0a7b..2f84fdf00481 100644
--- a/include/linux/sched/topology.h
+++ b/include/linux/sched/topology.h
@@ -45,7 +45,7 @@ static inline int cpu_smt_flags(void)
 #ifdef CONFIG_SCHED_CLUSTER
 static inline int cpu_cluster_flags(void)
 {
-	return SD_SHARE_PKG_RESOURCES;
+	return SD_CLUSTER | SD_SHARE_PKG_RESOURCES;
 }
 #endif
 
@@ -177,6 +177,7 @@ cpumask_var_t *alloc_sched_domains(unsigned int ndoms);
 void free_sched_domains(cpumask_var_t doms[], unsigned int ndoms);
 
 bool cpus_share_cache(int this_cpu, int that_cpu);
+bool cpus_share_resources(int this_cpu, int that_cpu);
 
 typedef const struct cpumask *(*sched_domain_mask_f)(int cpu);
 typedef int (*sched_domain_flags_f)(void);
@@ -230,6 +231,11 @@ static inline bool cpus_share_cache(int this_cpu, int that_cpu)
 	return true;
 }
 
+static inline bool cpus_share_resources(int this_cpu, int that_cpu)
+{
+	return true;
+}
+
 #endif	/* !CONFIG_SMP */
 
 #if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 848eaa0efe0e..7b203a6d96b2 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3746,6 +3746,18 @@ bool cpus_share_cache(int this_cpu, int that_cpu)
 	return per_cpu(sd_llc_id, this_cpu) == per_cpu(sd_llc_id, that_cpu);
 }
 
+/*
+ * Whether CPUs are share cache resources, which means LLC on non-cluster
+ * machines and LLC tag or L2 on machines with clusters.
+ */
+bool cpus_share_resources(int this_cpu, int that_cpu)
+{
+	if (this_cpu == that_cpu)
+		return true;
+
+	return per_cpu(sd_share_id, this_cpu) == per_cpu(sd_share_id, that_cpu);
+}
+
 static inline bool ttwu_queue_cond(int cpu, int wake_flags)
 {
 	/*
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index de53be905739..d04b342cc28d 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1765,7 +1765,9 @@ static inline struct sched_domain *lowest_flag_domain(int cpu, int flag)
 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_llc);
 DECLARE_PER_CPU(int, sd_llc_size);
 DECLARE_PER_CPU(int, sd_llc_id);
+DECLARE_PER_CPU(int, sd_share_id);
 DECLARE_PER_CPU(struct sched_domain_shared __rcu *, sd_llc_shared);
+DECLARE_PER_CPU(struct sched_domain __rcu *, sd_cluster);
 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_numa);
 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing);
 DECLARE_PER_CPU(struct sched_domain __rcu *, sd_asym_cpucapacity);
diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c
index d201a7052a29..408fede6e732 100644
--- a/kernel/sched/topology.c
+++ b/kernel/sched/topology.c
@@ -644,6 +644,8 @@ static void destroy_sched_domains(struct sched_domain *sd)
 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_llc);
 DEFINE_PER_CPU(int, sd_llc_size);
 DEFINE_PER_CPU(int, sd_llc_id);
+DEFINE_PER_CPU(int, sd_share_id);
+DEFINE_PER_CPU(struct sched_domain __rcu *, sd_cluster);
 DEFINE_PER_CPU(struct sched_domain_shared __rcu *, sd_llc_shared);
 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_numa);
 DEFINE_PER_CPU(struct sched_domain __rcu *, sd_asym_packing);
@@ -669,6 +671,18 @@ static void update_top_cache_domain(int cpu)
 	per_cpu(sd_llc_id, cpu) = id;
 	rcu_assign_pointer(per_cpu(sd_llc_shared, cpu), sds);
 
+	sd = lowest_flag_domain(cpu, SD_CLUSTER);
+	if (sd)
+		id = cpumask_first(sched_domain_span(sd));
+	rcu_assign_pointer(per_cpu(sd_cluster, cpu), sd);
+
+	/*
+	 * This assignment should be placed after the sd_llc_id as
+	 * we want this id equals to cluster id on cluster machines
+	 * but equals to LLC id on non-Cluster machines.
+	 */
+	per_cpu(sd_share_id, cpu) = id;
+
 	sd = lowest_flag_domain(cpu, SD_NUMA);
 	rcu_assign_pointer(per_cpu(sd_numa, cpu), sd);
 
@@ -1514,6 +1528,7 @@ static unsigned long __read_mostly *sched_numa_onlined_nodes;
  */
 #define TOPOLOGY_SD_FLAGS		\
 	(SD_SHARE_CPUCAPACITY	|	\
+	 SD_CLUSTER		|	\
 	 SD_SHARE_PKG_RESOURCES |	\
 	 SD_NUMA		|	\
 	 SD_ASYM_PACKING)
-- 
2.24.0



From yangyicong at hisilicon.com  Wed Jan 26 00:09:45 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Wed, 26 Jan 2022 16:09:45 +0800
Subject: [PATCH v2 0/2] sched/fair: Wake task within the cluster when possible
Message-ID: <20220126080947.4529-1-yangyicong@hisilicon.com>

This is the follow-up work to support cluster scheduler. Previously
we have added cluster level in the scheduler for both ARM64[1] and
X86[2] to support load balance between clusters to bring more memory
bandwidth and decrease cache contention. This patchset, on the other
hand, takes care of wake-up path by giving CPUs within the same cluster
a try before scanning the whole LLC to benefit those tasks communicating
with each other.

[1] 778c558f49a2 ("sched: Add cluster scheduler level in core and related Kconfig for ARM64")
[2] 66558b730f25 ("sched: Add cluster scheduler level for x86")

Change since v1:
- regain the performance data based on v5.17-rc1
- rename cpus_share_cluster to cpus_share_resources per Vincent and Gautham, thanks!

Barry Song (2):
  sched: Add per_cpu cluster domain info and cpus_share_resources API
  sched/fair: Scan cluster before scanning LLC in wake-up path

 include/linux/sched/sd_flags.h |  7 ++++++
 include/linux/sched/topology.h |  8 +++++-
 kernel/sched/core.c            | 12 +++++++++
 kernel/sched/fair.c            | 46 +++++++++++++++++++++++++++++++---
 kernel/sched/sched.h           |  2 ++
 kernel/sched/topology.c        | 15 +++++++++++
 6 files changed, 85 insertions(+), 5 deletions(-)

-- 
2.24.0



From yangyicong at hisilicon.com  Wed Jan 26 00:09:47 2022
From: yangyicong at hisilicon.com (Yicong Yang)
Date: Wed, 26 Jan 2022 16:09:47 +0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <20220126080947.4529-1-yangyicong@hisilicon.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
Message-ID: <20220126080947.4529-3-yangyicong@hisilicon.com>

From: Barry Song <song.bao.hua at hisilicon.com>

For platforms having clusters like Kunpeng920, CPUs within the same
cluster have lower latency when synchronizing and accessing shared
resources like cache. Thus, this patch tries to find an idle cpu
within the cluster of the target CPU before scanning the whole LLC
to gain lower latency.

Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
patch doesn't consider SMT for this moment.

Testing has been done on Kunpeng920 by pinning tasks to one numa
and two numa. On Kunpeng920, Each numa has 8 clusters and each
cluster has 4 CPUs.

With this patch, We noticed enhancement on tbench within one
numa or cross two numa.

On numa 0:
                            5.17-rc1                patched
Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)

On numa 0-1:
                            5.17-rc1                patched
Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*

This will also help to improve the MySQL. With MySQL server
running on numa 0 and client running on numa 1, both QPS and
latency is imporved on read-write case:
                        5.17-rc1        patched
QPS-16threads        143333.2633    145077.4033(+1.22%)
QPS-24threads        195085.9367    202719.6133(+3.91%)
QPS-32threads        241165.6867      249020.74(+3.26%)
QPS-64threads        244586.8433    253387.7567(+3.60%)
avg-lat-16threads           2.23           2.19(+1.19%)
avg-lat-24threads           2.46           2.36(+3.79%)
avg-lat-36threads           2.66           2.57(+3.26%)
avg-lat-64threads           5.23           5.05(+3.44%)

Tested-by: Yicong Yang <yangyicong at hisilicon.com>
Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
---
 kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 42 insertions(+), 4 deletions(-)

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 5146163bfabb..2f84a933aedd 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
 
 #endif /* CONFIG_SCHED_SMT */
 
+#ifdef CONFIG_SCHED_CLUSTER
+/*
+ * Scan the cluster domain for idle CPUs and clear cluster cpumask after scanning
+ */
+static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
+{
+	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
+	struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster, target));
+	int cpu, idle_cpu;
+
+	/* TODO: Support SMT case while a machine with both cluster and SMT born */
+	if (!sched_smt_active() && sd) {
+		for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
+			idle_cpu = __select_idle_cpu(cpu, p);
+			if ((unsigned int)idle_cpu < nr_cpumask_bits)
+				return idle_cpu;
+		}
+
+		/* Don't ping-pong tasks in and out cluster frequently */
+		if (cpus_share_resources(target, prev_cpu))
+			return target;
+
+		cpumask_andnot(cpus, cpus, sched_domain_span(sd));
+	}
+
+	return -1;
+}
+#else
+static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
+{
+	return -1;
+}
+#endif
+
 /*
  * Scan the LLC domain for idle CPUs; this is dynamically regulated by
  * comparing the average scan cost (tracked in sd->avg_scan_cost) against the
  * average idle time for this rq (as found in rq->avg_idle).
  */
-static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool has_idle_core, int target)
+static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
 {
 	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
 	int i, cpu, idle_cpu = -1, nr = INT_MAX;
@@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, bool
 
 	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
 
+	idle_cpu = scan_cluster(p, prev_cpu, target);
+	if ((unsigned int)idle_cpu < nr_cpumask_bits)
+		return idle_cpu;
+
 	if (sched_feat(SIS_PROP) && !has_idle_core) {
 		u64 avg_cost, avg_idle, span_avg;
 		unsigned long now = jiffies;
@@ -6416,7 +6454,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
 	/*
 	 * If the previous CPU is cache affine and idle, don't be stupid:
 	 */
-	if (prev != target && cpus_share_cache(prev, target) &&
+	if (prev != target && cpus_share_resources(prev, target) &&
 	    (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
 	    asym_fits_capacity(task_util, prev))
 		return prev;
@@ -6442,7 +6480,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
 	p->recent_used_cpu = prev;
 	if (recent_used_cpu != prev &&
 	    recent_used_cpu != target &&
-	    cpus_share_cache(recent_used_cpu, target) &&
+	    cpus_share_resources(recent_used_cpu, target) &&
 	    (available_idle_cpu(recent_used_cpu) || sched_idle_cpu(recent_used_cpu)) &&
 	    cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
 	    asym_fits_capacity(task_util, recent_used_cpu)) {
@@ -6483,7 +6521,7 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target)
 		}
 	}
 
-	i = select_idle_cpu(p, sd, has_idle_core, target);
+	i = select_idle_cpu(p, sd, has_idle_core, prev, target);
 	if ((unsigned)i < nr_cpumask_bits)
 		return i;
 
-- 
2.24.0



From miles.chen at mediatek.com  Wed Jan 26 00:09:45 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:09:45 +0800
Subject: [PATCH 24/31] clk: mediatek: mux: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-25-wenst@chromium.org>
References: <20220122091731.283592-25-wenst@chromium.org>
Message-ID: <20220126080946.1836-1-miles.chen@mediatek.com>

> The mux clk type registration function does not stop or return errors
> if any clk failed to be registered, nor does it implement an error
> handling path. This may result in a partially working device if any
> step failed.
> 
> Make the register function return proper error codes, and bail out if
> errors occur. Proper cleanup, i.e. unregister any clks that were
> successfully registered, is done in the new error path.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mux.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> index 70aa42144632..f51e67650f03 100644
> --- a/drivers/clk/mediatek/clk-mux.c
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -215,13 +215,26 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
>  		clk_data->clks[mux->id] = clk;
>  	}
>  
>  	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_mux *mux = &muxes[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
> +
> +		mtk_clk_unregister_mux(clk_data->clks[mux->id]);
> +		clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
> +	}
> +
> +	return PTR_ERR(clk);
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_muxes);
>  
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From miles.chen at mediatek.com  Wed Jan 26 00:08:36 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:08:36 +0800
Subject: [PATCH 23/31] clk: mediatek: mux: Reverse check for existing clk
 to reduce nesting level
In-Reply-To: <20220122091731.283592-24-wenst@chromium.org>
References: <20220122091731.283592-24-wenst@chromium.org>
Message-ID: <20220126080836.1148-1-miles.chen@mediatek.com>

> The clk registration code here currently does:
> 
>     if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
>             ... do clk registration ...
>     }
> 
> This extra level of nesting wastes screen real estate.
> 
> Reduce the nesting level by reversing the conditional shown above.
> Other than that, functionality is not changed.
>
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-mux.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> Diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
> Index 01af6a52711a..70aa42144632 100644
> --- a/drivers/clk/mediatek/clk-mux.c
> +++ b/drivers/clk/mediatek/clk-mux.c
> @@ -208,16 +208,17 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
>  	for (i = 0; i < num; i++) {
>  		const struct mtk_mux *mux = &muxes[i];
>  
> -		if (IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
> -			clk = mtk_clk_register_mux(mux, regmap, lock);
> +		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id]))
> +			continue;
>  
> -			if (IS_ERR(clk)) {
> -				pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
> -				continue;
> -			}
> +		clk = mtk_clk_register_mux(mux, regmap, lock);
>  
> -			clk_data->clks[mux->id] = clk;
> +		if (IS_ERR(clk)) {
> +			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
> +			continue;
>  		}
> +
> +		clk_data->clks[mux->id] = clk;
>  	}
>  
>  	return 0;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Wed Jan 26 00:13:38 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:13:38 +0800
Subject: [PATCH 25/31] clk: mediatek: pll: Implement error handling in
 register API
In-Reply-To: <20220122091731.283592-26-wenst@chromium.org>
References: <20220122091731.283592-26-wenst@chromium.org>
Message-ID: <20220126081338.4114-1-miles.chen@mediatek.com>

> The pll clk type registration function does not stop or return errors
> if any clk failed to be registered, nor does it implement an error
> handling path. This may result in a partially working device if any
> step failed.
> 
> Make the register function return proper error codes, and bail out if
> errors occur. Proper cleanup, i.e. unregister any clks that were
> successfully registered, and unmap the I/O space, is done in the new
> error path.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>
> ---
>  drivers/clk/mediatek/clk-pll.c | 23 +++++++++++++++++++----
>  drivers/clk/mediatek/clk-pll.h |  6 +++---
>  2 files changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
> index 9698d1c97cd6..1dd15f560659 100644
> --- a/drivers/clk/mediatek/clk-pll.c
> +++ b/drivers/clk/mediatek/clk-pll.c
> @@ -369,8 +369,9 @@ static void mtk_clk_unregister_pll(struct clk *clk)
>  	kfree(pll);
>  }
>  
> -void mtk_clk_register_plls(struct device_node *node,
> -		const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
> +int mtk_clk_register_plls(struct device_node *node,
> +			  const struct mtk_pll_data *plls, int num_plls,
> +			  struct clk_onecell_data *clk_data)
>  {
>  	void __iomem *base;
>  	int i;
> @@ -379,7 +380,7 @@ void mtk_clk_register_plls(struct device_node *node,
>  	base = of_iomap(node, 0);
>  	if (!base) {
>  		pr_err("%s(): ioremap failed\n", __func__);
> -		return;
> +		return -EINVAL;
>  	}
>  
>  	for (i = 0; i < num_plls; i++) {
> @@ -389,11 +390,25 @@ void mtk_clk_register_plls(struct device_node *node,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", pll->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
>  		clk_data->clks[pll->id] = clk;
>  	}
> +
> +	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_pll_data *pll = &plls[i];
> +
> +		mtk_clk_unregister_pll(clk_data->clks[pll->id]);
> +		clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
> +	};
> +
> +	iounmap(base);
> +
> +	return PTR_ERR(clk);
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
>  
> diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h
> index a889b1e472e7..bf06e44caef9 100644
> --- a/drivers/clk/mediatek/clk-pll.h
> +++ b/drivers/clk/mediatek/clk-pll.h
> @@ -48,9 +48,9 @@ struct mtk_pll_data {
>  	u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
>  };
>  
> -void mtk_clk_register_plls(struct device_node *node,
> -			   const struct mtk_pll_data *plls, int num_plls,
> -			   struct clk_onecell_data *clk_data);
> +int mtk_clk_register_plls(struct device_node *node,
> +			  const struct mtk_pll_data *plls, int num_plls,
> +			  struct clk_onecell_data *clk_data);
>  void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
>  			     struct clk_onecell_data *clk_data);
>  
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog




From miles.chen at mediatek.com  Wed Jan 26 00:16:54 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:16:54 +0800
Subject: [PATCH 26/31] clk: mediatek: mtk: Implement error handling in
 register APIs
In-Reply-To: <20220122091731.283592-27-wenst@chromium.org>
References: <20220122091731.283592-27-wenst@chromium.org>
Message-ID: <20220126081654.5988-1-miles.chen@mediatek.com>

> The remaining clk registration functions do not stop or return errors
> if any clk failed to be registered, nor do they implement error
> handling paths. This may result in a partially working device if any
> step fails.
> 
> Make the register functions return proper error codes, and bail out if
> errors occur. Proper cleanup, i.e. unregister any clks that were
> successfully registered, is done in the new error path.
> 
> This also makes the |struct clk_data *| argument mandatory, as it is
> used to track the list of clks registered.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mtk.c | 118 ++++++++++++++++++++++++++-------
>  drivers/clk/mediatek/clk-mtk.h |  20 +++---
>  2 files changed, 103 insertions(+), 35 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index d2c50186cceb..e1977c8e130a 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -53,16 +53,19 @@ void mtk_free_clk_data(struct clk_onecell_data *clk_data)
>  	kfree(clk_data);
>  }
>  
> -void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
> -		int num, struct clk_onecell_data *clk_data)
> +int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> +				struct clk_onecell_data *clk_data)
>  {
>  	int i;
>  	struct clk *clk;
>  
> +	if (!clk_data)
> +		return -ENOMEM;
> +
>  	for (i = 0; i < num; i++) {
>  		const struct mtk_fixed_clk *rc = &clks[i];
>  
> -		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> +		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id]))
>  			continue;
>  
>  		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
> @@ -70,12 +73,26 @@ void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", rc->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
> -		if (clk_data)
> -			clk_data->clks[rc->id] = clk;
> +		clk_data->clks[rc->id] = clk;
>  	}
> +
> +	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_fixed_clk *rc = &clks[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[rc->id]))
> +			continue;
> +
> +		clk_unregister_fixed_rate(clk_data->clks[rc->id]);
> +		clk_data->clks[rc->id] = ERR_PTR(-ENOENT);
> +	}
> +
> +	return PTR_ERR(clk);
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_fixed_clks);
>  
> @@ -99,16 +116,19 @@ void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_unregister_fixed_clks);
>  
> -void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
> -		int num, struct clk_onecell_data *clk_data)
> +int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
> +			     struct clk_onecell_data *clk_data)
>  {
>  	int i;
>  	struct clk *clk;
>  
> +	if (!clk_data)
> +		return -ENOMEM;
> +
>  	for (i = 0; i < num; i++) {
>  		const struct mtk_fixed_factor *ff = &clks[i];
>  
> -		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> +		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id]))
>  			continue;
>  
>  		clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
> @@ -116,12 +136,26 @@ void mtk_clk_register_factors(const struct mtk_fixed_factor *clks,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", ff->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
> -		if (clk_data)
> -			clk_data->clks[ff->id] = clk;
> +		clk_data->clks[ff->id] = clk;
> +	}
> +
> +	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_fixed_factor *ff = &clks[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[ff->id]))
> +			continue;
> +
> +		clk_unregister_fixed_factor(clk_data->clks[ff->id]);
> +		clk_data->clks[ff->id] = ERR_PTR(-ENOENT);
>  	}
> +
> +	return PTR_ERR(clk);
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_factors);
>  
> @@ -253,13 +287,16 @@ static void mtk_clk_unregister_composite(struct clk *clk)
>  	kfree(mux);
>  }
>  
> -void mtk_clk_register_composites(const struct mtk_composite *mcs,
> -		int num, void __iomem *base, spinlock_t *lock,
> -		struct clk_onecell_data *clk_data)
> +int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
> +				void __iomem *base, spinlock_t *lock,
> +				struct clk_onecell_data *clk_data)
>  {
>  	struct clk *clk;
>  	int i;
>  
> +	if (!clk_data)
> +		return -ENOMEM;
> +
>  	for (i = 0; i < num; i++) {
>  		const struct mtk_composite *mc = &mcs[i];
>  
> @@ -270,12 +307,26 @@ void mtk_clk_register_composites(const struct mtk_composite *mcs,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", mc->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
> -		if (clk_data)
> -			clk_data->clks[mc->id] = clk;
> +		clk_data->clks[mc->id] = clk;
> +	}
> +
> +	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_composite *mc = &mcs[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mcs->id]))
> +			continue;
> +
> +		mtk_clk_unregister_composite(clk_data->clks[mc->id]);
> +		clk_data->clks[mc->id] = ERR_PTR(-ENOENT);
>  	}
> +
> +	return PTR_ERR(clk);
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_register_composites);
>  
> @@ -299,17 +350,20 @@ void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
>  }
>  EXPORT_SYMBOL_GPL(mtk_clk_unregister_composites);
>  
> -void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
> -			int num, void __iomem *base, spinlock_t *lock,
> -				struct clk_onecell_data *clk_data)
> +int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
> +			      void __iomem *base, spinlock_t *lock,
> +			      struct clk_onecell_data *clk_data)
>  {
>  	struct clk *clk;
>  	int i;
>  
> +	if (!clk_data)
> +		return -ENOMEM;
> +
>  	for (i = 0; i <  num; i++) {
>  		const struct mtk_clk_divider *mcd = &mcds[i];
>  
> -		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
> +		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
>  			continue;
>  
>  		clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
> @@ -318,12 +372,26 @@ void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds,
>  
>  		if (IS_ERR(clk)) {
>  			pr_err("Failed to register clk %s: %pe\n", mcd->name, clk);
> -			continue;
> +			goto err;
>  		}
>  
> -		if (clk_data)
> -			clk_data->clks[mcd->id] = clk;
> +		clk_data->clks[mcd->id] = clk;
> +	}
> +
> +	return 0;
> +
> +err:
> +	while (--i >= 0) {
> +		const struct mtk_clk_divider *mcd = &mcds[i];
> +
> +		if (IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
> +			continue;
> +
> +		mtk_clk_unregister_composite(clk_data->clks[mcd->id]);
> +		clk_data->clks[mcd->id] = ERR_PTR(-ENOENT);
>  	}
> +
> +	return PTR_ERR(clk);
>  }
>  
>  void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
> diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
> index 7f902581a115..bf6565aa7319 100644
> --- a/drivers/clk/mediatek/clk-mtk.h
> +++ b/drivers/clk/mediatek/clk-mtk.h
> @@ -34,8 +34,8 @@ struct mtk_fixed_clk {
>  		.rate = _rate,				\
>  	}
>  
> -void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> -				 struct clk_onecell_data *clk_data);
> +int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> +				struct clk_onecell_data *clk_data);
>  void mtk_clk_unregister_fixed_clks(const struct mtk_fixed_clk *clks, int num,
>  				   struct clk_onecell_data *clk_data);
>  
> @@ -55,8 +55,8 @@ struct mtk_fixed_factor {
>  		.div = _div,				\
>  	}
>  
> -void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
> -			      struct clk_onecell_data *clk_data);
> +int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
> +			     struct clk_onecell_data *clk_data);
>  void mtk_clk_unregister_factors(const struct mtk_fixed_factor *clks, int num,
>  				struct clk_onecell_data *clk_data);
>  
> @@ -150,9 +150,9 @@ struct mtk_composite {
>  struct clk *mtk_clk_register_composite(const struct mtk_composite *mc,
>  		void __iomem *base, spinlock_t *lock);
>  
> -void mtk_clk_register_composites(const struct mtk_composite *mcs,
> -		int num, void __iomem *base, spinlock_t *lock,
> -		struct clk_onecell_data *clk_data);
> +int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
> +				void __iomem *base, spinlock_t *lock,
> +				struct clk_onecell_data *clk_data);
>  void mtk_clk_unregister_composites(const struct mtk_composite *mcs, int num,
>  				   struct clk_onecell_data *clk_data);
>  
> @@ -178,9 +178,9 @@ struct mtk_clk_divider {
>  		.div_width = _width,				\
>  }
>  
> -void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
> -			       void __iomem *base, spinlock_t *lock,
> -			       struct clk_onecell_data *clk_data);
> +int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
> +			      void __iomem *base, spinlock_t *lock,
> +			      struct clk_onecell_data *clk_data);
>  void mtk_clk_unregister_dividers(const struct mtk_clk_divider *mcds, int num,
>  				 struct clk_onecell_data *clk_data);
>  
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 



From miles.chen at mediatek.com  Wed Jan 26 00:19:09 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:19:09 +0800
Subject: [PATCH 27/31] clk: mediatek: Unregister clks in
 mtk_clk_simple_probe() error path
In-Reply-To: <20220122091731.283592-28-wenst@chromium.org>
References: <20220122091731.283592-28-wenst@chromium.org>
Message-ID: <20220126081909.7300-1-miles.chen@mediatek.com>

> Until now the mediatek clk driver library did not have any way to
> unregister clks, and so all drivers did not do proper cleanup in
> their error paths.
> 
> Now that the library does have APIs to unregister clks, use them
> in the error path of mtk_clk_simple_probe() to do proper cleanup.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mtk.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
> index e1977c8e130a..6d0b8842971b 100644
> --- a/drivers/clk/mediatek/clk-mtk.c
> +++ b/drivers/clk/mediatek/clk-mtk.c
> @@ -434,12 +434,14 @@ int mtk_clk_simple_probe(struct platform_device *pdev)
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  	if (r)
> -		goto free_data;
> +		goto unregister_clks;
>  
>  	platform_set_drvdata(pdev, clk_data);
>  
>  	return r;
>  
> +unregister_clks:
> +	mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data);
>  free_data:
>  	mtk_free_clk_data(clk_data);
>  	return r;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From peng.fan at nxp.com  Wed Jan 26 00:23:44 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 26 Jan 2022 08:23:44 +0000
Subject: [PATCH] firmware: imx: add get resource owner api
In-Reply-To: <20220111032147.342012-1-peng.fan@oss.nxp.com>
References: <20220111032147.342012-1-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB9417B5E817D6A3FB162030BE88209@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH] firmware: imx: add get resource owner api

Ping.. we need this API for remoteproc partition case.

Thanks,
Peng.

> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add resource owner management API, this API could be used to check
> whether M4 is under control of Linux.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/imx/rm.c           | 45
> +++++++++++++++++++++++++++++
>  include/linux/firmware/imx/svc/rm.h |  5 ++++
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/firmware/imx/rm.c b/drivers/firmware/imx/rm.c index
> a12db6ff323b..3c3605f98123 100644
> --- a/drivers/firmware/imx/rm.c
> +++ b/drivers/firmware/imx/rm.c
> @@ -43,3 +43,48 @@ bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc
> *ipc, u16 resource)
>  	return hdr->func;
>  }
>  EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
> +
> +/*
> + * This function get @resource partition number
> + *
> + * @param[in]     ipc         IPC handle
> + * @param[in]     resource    resource the control is associated with
> + * @param[out]    pt          pointer to return the partition number
> + *
> + * @return Returns 0 for success and < 0 for errors.
> + */
> +struct imx_sc_msg_rm_get_resource_owner {
> +	struct imx_sc_rpc_msg hdr;
> +	union {
> +		struct {
> +			u16 resource;
> +		} req;
> +		struct {
> +			u8 val;
> +		} resp;
> +	} data;
> +} __packed __aligned(4);
> +
> +int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource,
> +u8 *pt) {
> +	struct imx_sc_msg_rm_get_resource_owner msg;
> +	struct imx_sc_rpc_msg *hdr = &msg.hdr;
> +	int ret;
> +
> +	hdr->ver = IMX_SC_RPC_VERSION;
> +	hdr->svc = IMX_SC_RPC_SVC_RM;
> +	hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER;
> +	hdr->size = 2;
> +
> +	msg.data.req.resource = resource;
> +
> +	ret = imx_scu_call_rpc(ipc, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	if (pt)
> +		*pt = msg.data.resp.val;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(imx_sc_rm_get_resource_owner);
> diff --git a/include/linux/firmware/imx/svc/rm.h
> b/include/linux/firmware/imx/svc/rm.h
> index 456b6a59d29b..ff481b23ea36 100644
> --- a/include/linux/firmware/imx/svc/rm.h
> +++ b/include/linux/firmware/imx/svc/rm.h
> @@ -59,11 +59,16 @@ enum imx_sc_rm_func {
> 
>  #if IS_ENABLED(CONFIG_IMX_SCU)
>  bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
> +int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource,
> +u8 *pt);
>  #else
>  static inline bool
>  imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)  {
>  	return true;
>  }
> +static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc,
> +u16 resource, u8 *pt) {
> +	return -ENOTSUPP;
> +}
>  #endif
>  #endif
> --
> 2.25.1



From miles.chen at mediatek.com  Wed Jan 26 00:23:50 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:23:50 +0800
Subject: [PATCH 28/31] clk: mediatek: mt8195: Hook up
 mtk_clk_simple_remove()
In-Reply-To: <20220122091731.283592-29-wenst@chromium.org>
References: <20220122091731.283592-29-wenst@chromium.org>
Message-ID: <20220126082350.10393-1-miles.chen@mediatek.com>

> Various small clock controllers only have clock gates, and utilize
> mtk_clk_simple_probe() as their driver probe function.
> 
> Now that we have a matching remove function, hook it up for the relevant
> drivers. This was done with the following command:
> 
> sed -i -e '/mtk_clk_simple_probe/a \
>         .remove = mtk_clk_simple_remove,' drivers/clk/mediatek/clk-mt8195-*.c
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Thanks for doing this exmaple, we can apply 
mtk_clk_simple_probe/mtk_clk_simple_remove to other clk-mtxxxx in the future.

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mt8195-cam.c          | 1 +
>  drivers/clk/mediatek/clk-mt8195-ccu.c          | 1 +
>  drivers/clk/mediatek/clk-mt8195-img.c          | 1 +
>  drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c | 1 +
>  drivers/clk/mediatek/clk-mt8195-infra_ao.c     | 1 +
>  drivers/clk/mediatek/clk-mt8195-ipe.c          | 1 +
>  drivers/clk/mediatek/clk-mt8195-mfg.c          | 1 +
>  drivers/clk/mediatek/clk-mt8195-peri_ao.c      | 1 +
>  drivers/clk/mediatek/clk-mt8195-scp_adsp.c     | 1 +
>  drivers/clk/mediatek/clk-mt8195-vdec.c         | 1 +
>  drivers/clk/mediatek/clk-mt8195-venc.c         | 1 +
>  drivers/clk/mediatek/clk-mt8195-vpp0.c         | 1 +
>  drivers/clk/mediatek/clk-mt8195-vpp1.c         | 1 +
>  drivers/clk/mediatek/clk-mt8195-wpe.c          | 1 +
>  14 files changed, 14 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8195-cam.c b/drivers/clk/mediatek/clk-mt8195-cam.c
> index 3d261fc3848e..e4d00fe6e757 100644
> --- a/drivers/clk/mediatek/clk-mt8195-cam.c
> +++ b/drivers/clk/mediatek/clk-mt8195-cam.c
> @@ -134,6 +134,7 @@ static const struct of_device_id of_match_clk_mt8195_cam[] = {
>  
>  static struct platform_driver clk_mt8195_cam_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-cam",
>  		.of_match_table = of_match_clk_mt8195_cam,
> diff --git a/drivers/clk/mediatek/clk-mt8195-ccu.c b/drivers/clk/mediatek/clk-mt8195-ccu.c
> index f846f1d73605..4e326b6301ba 100644
> --- a/drivers/clk/mediatek/clk-mt8195-ccu.c
> +++ b/drivers/clk/mediatek/clk-mt8195-ccu.c
> @@ -42,6 +42,7 @@ static const struct of_device_id of_match_clk_mt8195_ccu[] = {
>  
>  static struct platform_driver clk_mt8195_ccu_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-ccu",
>  		.of_match_table = of_match_clk_mt8195_ccu,
> diff --git a/drivers/clk/mediatek/clk-mt8195-img.c b/drivers/clk/mediatek/clk-mt8195-img.c
> index 22b52a8f15fe..12f5c436d075 100644
> --- a/drivers/clk/mediatek/clk-mt8195-img.c
> +++ b/drivers/clk/mediatek/clk-mt8195-img.c
> @@ -88,6 +88,7 @@ static const struct of_device_id of_match_clk_mt8195_img[] = {
>  
>  static struct platform_driver clk_mt8195_img_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-img",
>  		.of_match_table = of_match_clk_mt8195_img,
> diff --git a/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
> index 4ab312eb26a5..fbc809d05072 100644
> --- a/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
> +++ b/drivers/clk/mediatek/clk-mt8195-imp_iic_wrap.c
> @@ -58,6 +58,7 @@ static const struct of_device_id of_match_clk_mt8195_imp_iic_wrap[] = {
>  
>  static struct platform_driver clk_mt8195_imp_iic_wrap_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-imp_iic_wrap",
>  		.of_match_table = of_match_clk_mt8195_imp_iic_wrap,
> diff --git a/drivers/clk/mediatek/clk-mt8195-infra_ao.c b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
> index 5f9b69967459..8ebe3b9415c4 100644
> --- a/drivers/clk/mediatek/clk-mt8195-infra_ao.c
> +++ b/drivers/clk/mediatek/clk-mt8195-infra_ao.c
> @@ -198,6 +198,7 @@ static const struct of_device_id of_match_clk_mt8195_infra_ao[] = {
>  
>  static struct platform_driver clk_mt8195_infra_ao_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-infra_ao",
>  		.of_match_table = of_match_clk_mt8195_infra_ao,
> diff --git a/drivers/clk/mediatek/clk-mt8195-ipe.c b/drivers/clk/mediatek/clk-mt8195-ipe.c
> index fc1d42b6ac84..b0d745cf7752 100644
> --- a/drivers/clk/mediatek/clk-mt8195-ipe.c
> +++ b/drivers/clk/mediatek/clk-mt8195-ipe.c
> @@ -43,6 +43,7 @@ static const struct of_device_id of_match_clk_mt8195_ipe[] = {
>  
>  static struct platform_driver clk_mt8195_ipe_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-ipe",
>  		.of_match_table = of_match_clk_mt8195_ipe,
> diff --git a/drivers/clk/mediatek/clk-mt8195-mfg.c b/drivers/clk/mediatek/clk-mt8195-mfg.c
> index aca6d9c0837c..9411c556a5a9 100644
> --- a/drivers/clk/mediatek/clk-mt8195-mfg.c
> +++ b/drivers/clk/mediatek/clk-mt8195-mfg.c
> @@ -39,6 +39,7 @@ static const struct of_device_id of_match_clk_mt8195_mfg[] = {
>  
>  static struct platform_driver clk_mt8195_mfg_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-mfg",
>  		.of_match_table = of_match_clk_mt8195_mfg,
> diff --git a/drivers/clk/mediatek/clk-mt8195-peri_ao.c b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
> index 907a92b22de8..2f6b3bb657db 100644
> --- a/drivers/clk/mediatek/clk-mt8195-peri_ao.c
> +++ b/drivers/clk/mediatek/clk-mt8195-peri_ao.c
> @@ -54,6 +54,7 @@ static const struct of_device_id of_match_clk_mt8195_peri_ao[] = {
>  
>  static struct platform_driver clk_mt8195_peri_ao_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-peri_ao",
>  		.of_match_table = of_match_clk_mt8195_peri_ao,
> diff --git a/drivers/clk/mediatek/clk-mt8195-scp_adsp.c b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
> index 26b4846c5894..e16c383f631b 100644
> --- a/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
> +++ b/drivers/clk/mediatek/clk-mt8195-scp_adsp.c
> @@ -39,6 +39,7 @@ static const struct of_device_id of_match_clk_mt8195_scp_adsp[] = {
>  
>  static struct platform_driver clk_mt8195_scp_adsp_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-scp_adsp",
>  		.of_match_table = of_match_clk_mt8195_scp_adsp,
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdec.c b/drivers/clk/mediatek/clk-mt8195-vdec.c
> index a1df04f42a90..a1446b666385 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vdec.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vdec.c
> @@ -96,6 +96,7 @@ static const struct of_device_id of_match_clk_mt8195_vdec[] = {
>  
>  static struct platform_driver clk_mt8195_vdec_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-vdec",
>  		.of_match_table = of_match_clk_mt8195_vdec,
> diff --git a/drivers/clk/mediatek/clk-mt8195-venc.c b/drivers/clk/mediatek/clk-mt8195-venc.c
> index 7339851a0856..622f57804f96 100644
> --- a/drivers/clk/mediatek/clk-mt8195-venc.c
> +++ b/drivers/clk/mediatek/clk-mt8195-venc.c
> @@ -61,6 +61,7 @@ static const struct of_device_id of_match_clk_mt8195_venc[] = {
>  
>  static struct platform_driver clk_mt8195_venc_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-venc",
>  		.of_match_table = of_match_clk_mt8195_venc,
> diff --git a/drivers/clk/mediatek/clk-mt8195-vpp0.c b/drivers/clk/mediatek/clk-mt8195-vpp0.c
> index c3241466a8d0..bf2939c3a023 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vpp0.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vpp0.c
> @@ -102,6 +102,7 @@ static const struct of_device_id of_match_clk_mt8195_vpp0[] = {
>  
>  static struct platform_driver clk_mt8195_vpp0_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-vpp0",
>  		.of_match_table = of_match_clk_mt8195_vpp0,
> diff --git a/drivers/clk/mediatek/clk-mt8195-vpp1.c b/drivers/clk/mediatek/clk-mt8195-vpp1.c
> index ce0b9a40a179..ffd52c762890 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vpp1.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vpp1.c
> @@ -100,6 +100,7 @@ static const struct of_device_id of_match_clk_mt8195_vpp1[] = {
>  
>  static struct platform_driver clk_mt8195_vpp1_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-vpp1",
>  		.of_match_table = of_match_clk_mt8195_vpp1,
> diff --git a/drivers/clk/mediatek/clk-mt8195-wpe.c b/drivers/clk/mediatek/clk-mt8195-wpe.c
> index 274d60838d8e..b483fab10e18 100644
> --- a/drivers/clk/mediatek/clk-mt8195-wpe.c
> +++ b/drivers/clk/mediatek/clk-mt8195-wpe.c
> @@ -135,6 +135,7 @@ static const struct of_device_id of_match_clk_mt8195_wpe[] = {
>  
>  static struct platform_driver clk_mt8195_wpe_drv = {
>  	.probe = mtk_clk_simple_probe,
> +	.remove = mtk_clk_simple_remove,
>  	.driver = {
>  		.name = "clk-mt8195-wpe",
>  		.of_match_table = of_match_clk_mt8195_wpe,
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From peng.fan at nxp.com  Wed Jan 26 00:24:47 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 26 Jan 2022 08:24:47 +0000
Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
In-Reply-To: <DU0PR04MB94177F777E854B92C665303488519@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20211214120737.1611955-1-peng.fan@oss.nxp.com>
 <DU0PR04MB94177F777E854B92C665303488519@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <DU0PR04MB9417BA24DB13CD6C98BE47CF88209@DU0PR04MB9417.eurprd04.prod.outlook.com>

Daniel,

> Subject: RE: [PATCH 0/5] clocksource/drivers/imx: several updates

Do you have time to give a look?

Thanks,
Peng.

> 
> > Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
> >
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > This patchset includes several update of i.MX sysctr and tpm driver.
> 
> Ping..
> 
> Thanks,
> Peng.
> 
> >
> > Peng Fan (5):
> >   clocksource/drivers/imx-sysctr: drop IRQF_IRQPOLL
> >   clocksource/drivers/imx-tpm: drop IRQF_IRQPOLL
> >   clocksource/drivers/imx-tpm: mark two variable with __ro_after_init
> >   clocksource/drivers/imx-tpm: add CLOCK_EVT_FEAT_DYNIRQ
> >   clocksource/drivers/imx-tpm: update name of clkevt
> >
> >  drivers/clocksource/timer-imx-sysctr.c |  2 +-
> >  drivers/clocksource/timer-imx-tpm.c    | 10 +++++-----
> >  2 files changed, 6 insertions(+), 6 deletions(-)
> >
> > --
> > 2.25.1



From krzysztof.kozlowski at canonical.com  Wed Jan 26 00:25:15 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 09:25:15 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <20220125194609.32314-1-nick.hawkins@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
Message-ID: <500da964-fe29-bbdf-761e-8ea33213318b@canonical.com>

On 25/01/2022 20:46, nick.hawkins at hpe.com wrote:
> From: Nick Hawkins <nick.hawkins at hpe.com>
> 
> Signed-off-by: Nick Hawkins <nick.hawkins at hpe.com>
> ---
>  .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
>  MAINTAINERS                                   |   8 +
>  arch/arm/Kconfig                              |   2 +
>  arch/arm/boot/dts/gxp.dts                     | 700 ++++++++++++++++++
>  arch/arm/configs/gxp_defconfig                | 243 ++++++
>  arch/arm/mach-hpe/Kconfig                     |  20 +
>  arch/arm/mach-hpe/Makefile                    |   1 +
>  arch/arm/mach-hpe/gxp.c                       |  63 ++
>  8 files changed, 1039 insertions(+)
>  create mode 100644 arch/arm/boot/dts/gxp.dts
>  create mode 100644 arch/arm/configs/gxp_defconfig
>  create mode 100644 arch/arm/mach-hpe/Kconfig
>  create mode 100644 arch/arm/mach-hpe/Makefile
>  create mode 100644 arch/arm/mach-hpe/gxp.c
> 
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> index 294093d45a23..e8b0ec874aed 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
> @@ -515,6 +515,8 @@ patternProperties:
>      description: Jiangsu HopeRun Software Co., Ltd.
>    "^hp,.*":
>      description: Hewlett Packard

I guess this should be renamed/clarified to "Hewlett Packard
Incorporated", since these are two different companies.

Anyway, bindings go as separate patch, first in the series.

> +  "^hpe,.*":
> +    description: Hewlett Packard Enterprise
>    "^hsg,.*":


Best regards,
Krzysztof


From peng.fan at nxp.com  Wed Jan 26 00:28:54 2022
From: peng.fan at nxp.com (Peng Fan)
Date: Wed, 26 Jan 2022 08:28:54 +0000
Subject: [PATCH 0/7] mailbox: imx: misc fix and SECO MU support
In-Reply-To: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
Message-ID: <DU0PR04MB941793A918C5E08C9A48BCAC88209@DU0PR04MB9417.eurprd04.prod.outlook.com>

> Subject: [PATCH 0/7] mailbox: imx: misc fix and SECO MU support

Ping..

Thanks,
Peng.

> 
> From: Peng Fan <peng.fan at nxp.com>
> 
> This patchset includes a few fixes for low power and i.MX8 SECO MU support
> 
> Franck LENORMAND (1):
>   mailbox: imx: add i.MX8 SECO MU support
> 
> Peng Fan (2):
>   dt-bindings: mailbox: imx-mu: add i.MX8 SECO MU support
>   mailbox: imx: introduce rxdb callback
> 
> Ranjani Vaidyanathan (2):
>   mailbox: imx: Add support for identifying SCU wakeup source from sysfs
>   mailbox: imx: enlarge timeout while reading/writing messages to SCFW
> 
> Robin Gong (2):
>   mailbox: imx: fix wakeup failure from freeze mode
>   mailbox: imx: fix crash in resume on i.mx8ulp
> 
>  .../devicetree/bindings/mailbox/fsl,mu.yaml   |   1 +
>  drivers/mailbox/imx-mailbox.c                 | 249
> +++++++++++++++++-
>  2 files changed, 243 insertions(+), 7 deletions(-)
> 
> --
> 2.25.1



From fabien.dessenne at foss.st.com  Wed Jan 26 00:29:22 2022
From: fabien.dessenne at foss.st.com (Fabien DESSENNE)
Date: Wed, 26 Jan 2022 09:29:22 +0100
Subject: [Linux-stm32] [PATCH][next] hwspinlock: stm32: Use struct_size()
 helper in devm_kzalloc()
In-Reply-To: <20220125021353.GA29777@embeddedor>
References: <20220125021353.GA29777@embeddedor>
Message-ID: <ad53072e-e497-3321-eaa4-bbe8b2da2af4@foss.st.com>

Hi Gustavo,

Thank you for the patch.
I am fine with it with a nit picking comment regarding the non-mandatory 
80 characters line break [1].

BR

Fabien

[1] https://lkml.org/lkml/2020/5/29/1038


On 25/01/2022 03:13, Gustavo A. R. Silva wrote:
> Make use of the struct_size() helper instead of an open-coded version,
> in order to avoid any potential type mistakes or integer overflows that,
> in the worst scenario, could lead to heap overflows.
> 
> Also, address the following sparse warnings:
> drivers/hwspinlock/stm32_hwspinlock.c:84:32: warning: using sizeof on a
> flexible structure
> 
> Link: https://github.com/KSPP/linux/issues/174
> Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
> ---
>   drivers/hwspinlock/stm32_hwspinlock.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/hwspinlock/stm32_hwspinlock.c
> b/drivers/hwspinlock/stm32_hwspinlock.c
> index 5bd11a7fab65..716ad4401249 100644
> --- a/drivers/hwspinlock/stm32_hwspinlock.c
> +++ b/drivers/hwspinlock/stm32_hwspinlock.c
> @@ -73,15 +73,14 @@ static int stm32_hwspinlock_probe(struct
> platform_device *pdev)
>   	struct device *dev = &pdev->dev;
>   	struct stm32_hwspinlock *hw;
>   	void __iomem *io_base;
> -	size_t array_size;
>   	int i, ret;
>   
>   	io_base = devm_platform_ioremap_resource(pdev, 0);
>   	if (IS_ERR(io_base))
>   		return PTR_ERR(io_base);
>   
> -	array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
> -	hw = devm_kzalloc(dev, sizeof(*hw) + array_size, GFP_KERNEL);
> +	hw = devm_kzalloc(dev, struct_size(hw, bank.lock,
> STM32_MUTEX_NUM_LOCKS),
> +			  GFP_KERNEL);

No need from line break here.


>   	if (!hw)
>   		return -ENOMEM;
>   
> 


From shawnguo at kernel.org  Wed Jan 26 00:33:52 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 16:33:52 +0800
Subject: [PATCH v3 8/8] arm64: dts: ls1028a-qds: add overlays for various
 serdes protocols
In-Reply-To: <20211214093240.23320-9-leoyang.li@nxp.com>
References: <20211214093240.23320-1-leoyang.li@nxp.com>
 <20211214093240.23320-9-leoyang.li@nxp.com>
Message-ID: <20220126083348.GG4686@dragon>

Hi Leo,

On Tue, Dec 14, 2021 at 03:32:40AM -0600, Li Yang wrote:
> From: Alex Marginean <alexandru.marginean at nxp.com>
> 
> Add overlays for various serdes protocols on LS1028A QDS board using
> different PHY cards.  These should be applied at boot, based on serdes
> configuration.  If no overlay is applied, only the RGMII interface on
> the QDS is available in Linux.
> 
> Building device tree fragments requires passing the "-@" argument to
> dtc, which increases the base dtb size and might cause some platforms to
> fail to store the new binary. To avoid that, it would be nice to only
> pass "-@" for the platforms where fragments will be used, aka
> LS1028A-QDS. One approach suggested by Rob Herring is used here:
> 
> https://lore.kernel.org/patchwork/patch/821645/
> 
> Also moved the enet* override nodes in dts file to be in alphabetic order.
> 
> Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> Signed-off-by: Ioana Ciornei <ioana.ciornei at nxp.com>
> Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |  16 +++
>  .../dts/freescale/fsl-ls1028a-qds-13bb.dts    | 113 ++++++++++++++++++
>  .../dts/freescale/fsl-ls1028a-qds-65bb.dts    | 108 +++++++++++++++++
>  .../dts/freescale/fsl-ls1028a-qds-7777.dts    |  82 +++++++++++++
>  .../dts/freescale/fsl-ls1028a-qds-85bb.dts    | 107 +++++++++++++++++
>  .../dts/freescale/fsl-ls1028a-qds-899b.dts    |  75 ++++++++++++
>  .../dts/freescale/fsl-ls1028a-qds-9999.dts    |  79 ++++++++++++
>  .../boot/dts/freescale/fsl-ls1028a-qds.dts    |  19 ++-
>  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi |   2 +-
>  9 files changed, 595 insertions(+), 6 deletions(-)
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
>  create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index a14a6173b765..f518eb1e1142 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -1,4 +1,14 @@
>  # SPDX-License-Identifier: GPL-2.0
> +
> +# required for overlay support
> +DTC_FLAGS_fsl-ls1028a-qds := -@
> +DTC_FLAGS_fsl-ls1028a-qds-13bb := -@
> +DTC_FLAGS_fsl-ls1028a-qds-65bb := -@
> +DTC_FLAGS_fsl-ls1028a-qds-7777 := -@
> +DTC_FLAGS_fsl-ls1028a-qds-85bb := -@
> +DTC_FLAGS_fsl-ls1028a-qds-899b := -@
> +DTC_FLAGS_fsl-ls1028a-qds-9999 := -@
> +
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb
> @@ -11,6 +21,12 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
> +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
>  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> new file mode 100644
> index 000000000000..f748a2c12a70
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 13bb
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board with lane B rework.
> + * Requires a SCH-30841 card with lane A of connector rewired to PHY lane C.
> + * Set-up is a SCH-30842 card in slot 1 and SCH-30841 in slot 2.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;

I cannot find this mdio_slot1 node (and mdio_slot2 below) in any upstream
device tree.  We are not going to maintain a bunch of overlays which are
only meant to apply on the out-of-tree DTs.

So please either submit those missing device nodes in the base DT, or I
will have to revert the patch.

Shawn

> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			slot1_sgmii: ethernet-phy at 2 {
> +				/* AQR112 */
> +				reg = <0x2>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&enetc_port0>;
> +
> +		__overlay__ {
> +			phy-handle = <&slot1_sgmii>;
> +			phy-mode = "usxgmii";
> +			managed = "in-band-status";
> +			status = "okay";
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mdio_slot2>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* 4 ports on AQR412 */
> +			slot2_qxgmii0: ethernet-phy at 0 {
> +				reg = <0x0>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot2_qxgmii1: ethernet-phy at 1 {
> +				reg = <0x1>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot2_qxgmii2: ethernet-phy at 2 {
> +				reg = <0x2>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot2_qxgmii3: ethernet-phy at 3 {
> +				reg = <0x3>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +		};
> +	};
> +
> +	fragment at 3 {
> +		target = <&mscc_felix_ports>;
> +
> +		__overlay__ {
> +			port at 0 {
> +				status = "okay";
> +				phy-handle = <&slot2_qxgmii0>;
> +				phy-mode = "usxgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot2_qxgmii1>;
> +				phy-mode = "usxgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot2_qxgmii2>;
> +				phy-mode = "usxgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 3 {
> +				status = "okay";
> +				phy-handle = <&slot2_qxgmii3>;
> +				phy-mode = "usxgmii";
> +				managed = "in-band-status";
> +			};
> +		};
> +	};
> +
> +	fragment at 4 {
> +		target = <&mscc_felix>;
> +
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> new file mode 100644
> index 000000000000..8ffb707a1576
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> @@ -0,0 +1,108 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 69xx
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board with lane B rework.
> + * Requires a SCH-30842 card in slot 1 and a SCH-28021 card in slot 2.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			slot1_sgmii: ethernet-phy at 2 {
> +				/* AQR112 */
> +				reg = <0x2>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&enetc_port0>;
> +
> +		__overlay__ {
> +			phy-handle = <&slot1_sgmii>;
> +			phy-mode = "2500base-x";
> +			managed = "in-band-status";
> +			status = "okay";
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mdio_slot2>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* 4 ports on VSC8514 */
> +			slot2_qsgmii0: ethernet-phy at 8 {
> +				reg = <0x8>;
> +			};
> +
> +			slot2_qsgmii1: ethernet-phy at 9 {
> +				reg = <0x9>;
> +			};
> +
> +			slot2_qsgmii2: ethernet-phy at a {
> +				reg = <0xa>;
> +			};
> +
> +			slot2_qsgmii3: ethernet-phy at b {
> +				reg = <0xb>;
> +			};
> +		};
> +	};
> +
> +	fragment at 3 {
> +		target = <&mscc_felix_ports>;
> +
> +		__overlay__ {
> +			port at 0 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii0>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii1>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii2>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 3 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii3>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +		};
> +	};
> +
> +	fragment at 4 {
> +		target = <&mscc_felix>;
> +
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> new file mode 100644
> index 000000000000..eb6a1e674f10
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> @@ -0,0 +1,82 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 7777
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board without lane B rework.
> + * Requires a SCH-30841 card without lane A/C rewire and with a FW with muxing
> + * disabled, plugged in slot 1.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* 4 ports on AQR412 */
> +			slot1_sxgmii0: ethernet-phy at 0 {
> +				reg = <0x0>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot1_sxgmii1: ethernet-phy at 1 {
> +				reg = <0x1>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot1_sxgmii2: ethernet-phy at 2 {
> +				reg = <0x2>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +
> +			slot1_sxgmii3: ethernet-phy at 3 {
> +				reg = <0x3>;
> +				compatible = "ethernet-phy-ieee802.3-c45";
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&mscc_felix_ports>;
> +
> +		__overlay__ {
> +			port at 0 {
> +				status = "okay";
> +				phy-handle = <&slot1_sxgmii0>;
> +				phy-mode = "2500base-x";
> +			};
> +
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot1_sxgmii1>;
> +				phy-mode = "2500base-x";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot1_sxgmii2>;
> +				phy-mode = "2500base-x";
> +			};
> +
> +			port at 3 {
> +				status = "okay";
> +				phy-handle = <&slot1_sxgmii3>;
> +				phy-mode = "2500base-x";
> +			};
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mscc_felix>;
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> new file mode 100644
> index 000000000000..8e90c3088ba1
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> @@ -0,0 +1,107 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 85bb
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board with lane B rework.
> + * Requires a SCH-24801 card in slot 1 and a SCH-28021 card in slot 2.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			slot1_sgmii: ethernet-phy at 1c {
> +				/* 1st port on VSC8234 */
> +				reg = <0x1c>;
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&enetc_port0>;
> +
> +		__overlay__ {
> +			phy-handle = <&slot1_sgmii>;
> +			phy-mode = "sgmii";
> +			managed = "in-band-status";
> +			status = "okay";
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mdio_slot2>;
> +
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* 4 ports on VSC8514 */
> +			slot2_qsgmii0: ethernet-phy at 8 {
> +				reg = <0x8>;
> +			};
> +
> +			slot2_qsgmii1: ethernet-phy at 9 {
> +				reg = <0x9>;
> +			};
> +
> +			slot2_qsgmii2: ethernet-phy at a {
> +				reg = <0xa>;
> +			};
> +
> +			slot2_qsgmii3: ethernet-phy at b {
> +				reg = <0xb>;
> +			};
> +		};
> +	};
> +
> +	fragment at 3 {
> +		target = <&mscc_felix_ports>;
> +
> +		__overlay__ {
> +			port at 0 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii0>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii1>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii2>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 3 {
> +				status = "okay";
> +				phy-handle = <&slot2_qsgmii3>;
> +				phy-mode = "qsgmii";
> +				managed = "in-band-status";
> +			};
> +		};
> +	};
> +
> +	fragment at 4 {
> +		target = <&mscc_felix>;
> +
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> new file mode 100644
> index 000000000000..5d0a094e6c44
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 85xx
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board without lane B rework.
> + * Requires a SCH-24801 card in slot 1.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* VSC8234 */
> +			slot1_sgmii0: ethernet-phy at 1c {
> +				reg = <0x1c>;
> +			};
> +
> +			slot1_sgmii1: ethernet-phy at 1d {
> +				reg = <0x1d>;
> +			};
> +
> +			slot1_sgmii2: ethernet-phy at 1e {
> +				reg = <0x1e>;
> +			};
> +
> +			slot1_sgmii3: ethernet-phy at 1f {
> +				reg = <0x1f>;
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&enetc_port0>;
> +		__overlay__ {
> +			phy-handle = <&slot1_sgmii0>;
> +			phy-mode = "sgmii";
> +			managed = "in-band-status";
> +			status = "okay";
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mscc_felix_ports>;
> +		__overlay__ {
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii1>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii2>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +		};
> +	};
> +
> +	fragment at 3 {
> +		target = <&mscc_felix>;
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> new file mode 100644
> index 000000000000..1ef743c48e84
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> @@ -0,0 +1,79 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Device Tree fragment for LS1028A QDS board, serdes 85xx
> + *
> + * Copyright 2019-2021 NXP
> + *
> + * Requires a LS1028A QDS board without lane B rework.
> + * Requires a SCH-24801 card in slot 1.
> + */
> +
> +/dts-v1/;
> +/plugin/;
> +
> +/ {
> +	fragment at 0 {
> +		target = <&mdio_slot1>;
> +		__overlay__ {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			/* VSC8234 */
> +			slot1_sgmii0: ethernet-phy at 1c {
> +				reg = <0x1c>;
> +			};
> +
> +			slot1_sgmii1: ethernet-phy at 1d {
> +				reg = <0x1d>;
> +			};
> +
> +			slot1_sgmii2: ethernet-phy at 1e {
> +				reg = <0x1e>;
> +			};
> +
> +			slot1_sgmii3: ethernet-phy at 1f {
> +				reg = <0x1f>;
> +			};
> +		};
> +	};
> +
> +	fragment at 1 {
> +		target = <&mscc_felix_ports>;
> +		__overlay__ {
> +			port at 0 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii0>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 1 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii1>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 2 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii2>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +
> +			port at 3 {
> +				status = "okay";
> +				phy-handle = <&slot1_sgmii3>;
> +				phy-mode = "sgmii";
> +				managed = "in-band-status";
> +			};
> +		};
> +	};
> +
> +	fragment at 2 {
> +		target = <&mscc_felix>;
> +		__overlay__ {
> +			status = "okay";
> +		};
> +	};
> +};
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> index 782853a449cc..177bc1405f0f 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> @@ -211,6 +211,16 @@ &duart1 {
>  	status = "okay";
>  };
>  
> +&enetc_port1 {
> +	phy-handle = <&qds_phy1>;
> +	phy-mode = "rgmii-id";
> +	status = "okay";
> +};
> +
> +&enetc_port2 {
> +	status = "okay";
> +};
> +
>  &esdhc {
>  	status = "okay";
>  };
> @@ -326,17 +336,16 @@ rtc at 51 {
>  	};
>  };
>  
> -&enetc_port1 {
> -	phy-handle = <&qds_phy1>;
> -	phy-mode = "rgmii-id";
> +&lpuart0 {
>  	status = "okay";
>  };
>  
> -&lpuart0 {
> +&lpuart1 {
>  	status = "okay";
>  };
>  
> -&lpuart1 {
> +&mscc_felix_port4 {
> +	ethernet = <&enetc_port2>;
>  	status = "okay";
>  };
>  
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> index 5a7b26a1bad2..5bb8c26e0825 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> @@ -1115,7 +1115,7 @@ mscc_felix: ethernet-switch at 0,5 {
>  				interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
>  				status = "disabled";
>  
> -				ports {
> +				mscc_felix_ports: ports {
>  					#address-cells = <1>;
>  					#size-cells = <0>;
>  
> -- 
> 2.25.1
> 


From ardb at kernel.org  Wed Jan 26 00:36:56 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 09:36:56 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
Message-ID: <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>

On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
>
> Hi Catalin
>
> > -----Original Message-----
> > From: Catalin Marinas <catalin.marinas at arm.com>
> > Sent: Friday, January 7, 2022 6:43 PM
> > To: Jianyong Wu <Jianyong.Wu at arm.com>
> > Cc: will at kernel.org; Anshuman Khandual <Anshuman.Khandual at arm.com>;
> > akpm at linux-foundation.org; david at redhat.com; quic_qiancai at quicinc.com;
> > ardb at kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> > kernel at lists.infradead.org; gshan at redhat.com; Justin He
> > <Justin.He at arm.com>; nd <nd at arm.com>
> > Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> > pud mapping
> >
> > On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> > > Hi Catalin,
> > >
> > > I roughly find the root cause.
> > >  alloc_init_pud will be called at the very beginning of kernel boot in
> > create_mapping_noalloc where no memory allocator is initialized. But
> > lockdep check may need allocate memory. So, kernel take exception when
> > acquire lock.(I have not found the exact code that cause this issue)
> > that's say we may not be able to use a lock so early.
> > >
> > > I come up with 2 methods to address it.
> > > 1) skip dead lock check at the very beginning of kernel boot in lockdep
> > code.
> > > 2) provided 2 two versions of __create_pgd_mapping, one with lock in
> > > it and the other without. There may be no possible of race for memory
> > > mapping at the very beginning time of kernel boot, thus we can use the
> > > no lock version of __create_pgd_mapping safely.
> > > In my test, this issue is gone if there is no lock held in
> > > create_mapping_noalloc. I think create_mapping_noalloc is called early
> > > enough to avoid the race conditions of memory mapping, however, I have
> > > not proved it.
> >
> > I think method 2 would work better but rather than implementing new
> > nolock functions I'd add a NO_LOCK flag and check it in
> > alloc_init_pud() before mutex_lock/unlock. Also add a comment when
> > passing the NO_LOCK flag on why it's needed and why there wouldn't be
> > any races at that stage (early boot etc.)
> >
> The problematic code path is:
> __primary_switched
>         early_fdt_map->fixmap_remap_fdt
>                 create_mapping_noalloc->alloc_init_pud
>                         mutex_lock (with Jianyong's patch)
>
> The problem seems to be that we will clear BSS segment twice if kaslr
> is enabled. Hence, some of the static variables in lockdep init process were
> messed up. That is to said, with kaslr enabled we might initialize lockdep
> twice if we add mutex_lock/unlock in alloc_init_pud().
>

Thanks for tracking that down.

Note that clearing the BSS twice is not the root problem here. The
root problem is that we set global state while the kernel runs at the
default link time address, and then refer to it again after the entire
kernel has been shifted in the kernel VA space. Such global state
could consist of mutable pointers to statically allocated data (which
would be reset to their default values after the relocation code runs
again), or global pointer variables in BSS. In either case, relying on
such a global variable after the second relocation performed by KASLR
would be risky, and so we should avoid manipulating global state at
all if it might involve pointer to statically allocated data
structures.

> In other ways, if we invoke mutex_lock/unlock in such a early booting stage.
> It might be unsafe because lockdep inserts lock_acquire/release as the complex
> hooks.
>
> In summary, would it better if Jianyong splits these early boot and late boot
> case? e.g. introduce a nolock version for create_mapping_noalloc().
>
> What do you think of it?
>

The pre-KASLR case definitely doesn't need a lock. But given that
create_mapping_noalloc() is only used to map the FDT, which happens
very early one way or the other, wouldn't it be better to move the
lock/unlock into other callers of __create_pgd_mapping()? (and make
sure no other users of the fixmap slots exist)


From krzysztof.kozlowski at canonical.com  Wed Jan 26 00:41:18 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 09:41:18 +0100
Subject: [PATCH] Adding architectural support for HPE's GXP BMC. This is
 the first of a series of patches to support HPE's BMC with Linux Kernel.
In-Reply-To: <CA8148A1-578E-4621-9714-45AB391C353A@hpe.com>
References: <nick.hawkins@hpe.com>
 <20220125194609.32314-1-nick.hawkins@hpe.com>
 <CAK8P3a0ccoH_sNE9eWxQnWHEWNBPFL6k4k6mku=cHs_fRfnL-w@mail.gmail.com>
 <CA8148A1-578E-4621-9714-45AB391C353A@hpe.com>
Message-ID: <2f4dd91a-e4ad-2559-f65e-914561de4047@canonical.com>

On 26/01/2022 02:49, Verdun, Jean-Marie wrote:
> Hello Arnd,
> 
> I work with Nick on upstreaming the initial code for our GXP asic. Many thanks for your feedbacks.
> 
> We will update accordingly. I must admit that I am a little bit lost regarding the process we shall follow to introduce a new SoC. We took the path to send first the DT side and then the drivers through a set of patch per driver. Andrew, seems to guide us into a direction where we shall have a very small DT initially and we will expand it in a step by step manner when we will get drivers approved, this might lead us into a process which might be very sequential. What is the best recommendation to follow ? Either way is ok on our side, I am just looking at the easiest solution for the code Maintainers.

The current DTS patch won't pass checkpatch because you have around 30
undocumented compatibles. The process does not have to be sequential -
quite contrary - rather parallel with several submission happening the
same time. The point is that we need to see the bindings and check
whether your DTS complies with them. Actually the check should be done
by you with dtbs_check, but let's say we also look at it.

Your patch with full-blown DTS and drivers is also good approach, except
there are no drivers sent. For example:
https://lore.kernel.org/?q=hpe%2Cgxp-i2c
https://lore.kernel.org/?q=hpe%2Cgxp-wdt
If you want to avoid building DTS sequentially, no problem, just send
the bindings and DTS.

Andrew's approach is much more flexible because it allows you to discuss
the bindings while not postponing the core part of DTS.


> 
> Most of this code is intended to be used with OpenBMC and u-boot. We didn't have yet upstream anything into the bootloader, and wanted to follow a step by step approach by initially publishing into the kernel (that explain why some init also are still hardcoded in the case the bootloader doesn't provide the data, that is still work in progress, but we can have end user testing the infrastructure). We have a very small user space environment to validate that the kernel boot properly by using u-root, before getting OpenBMC fully loaded. Last but not least, as this is a BMC code, which is new to our end users, it would be just great to have default fall back if the u-boot environment is not properly setup (roughly we could code the MAC address into the umac driver, or the DT to address such cases). We plan to update uboot in the next couple of days by the way. 
> 
> We do not use dtsi at all for the moment, as we are generating a dtb out of the dts file and load it into our SPI image. Probably not the best approach, but this is the way it is implemented currently. The dtb is compiled outside the kernel tree for the moment using dtc compiler. We will add that step into the dts boot Makefile, it make sense. Does the dtsi is mandatory for every SoC ? I can build one if needed. But as this SoC is a BMC, the current dts is an example of what shall be configured. Many other datas related to the hardware target platform are defined into OpenBMC layers while we build for various ProLiant servers. We wanted our kernel code being readily testable that is why we have that generic dts. (GPIOS mapping is machine dependent)

The commit misses description, so I actually don't know how the
architecture looks like. For most of SoC, there is a DTSI because the
SoC is being put on different boards/products. It allows clear
separation between SoC (which could be reused) and board. If you have
only a DTS, then:
1. Where is the SoC here? How it can be re-used by different board?
2. Is it only one DTS per entire sub-architecture? No more boards? Only
one product? No even revisions or improved versions?

Best regards,
Krzysztof


From miles.chen at mediatek.com  Wed Jan 26 00:40:33 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:40:33 +0800
Subject: [PATCH 30/31] clk: mediatek: mt8195: Implement remove functions
In-Reply-To: <20220122091731.283592-31-wenst@chromium.org>
References: <20220122091731.283592-31-wenst@chromium.org>
Message-ID: <20220126084033.20234-1-miles.chen@mediatek.com>

> Until now the mediatek clk driver library did not have any way to
> unregister clks, and so none of the drivers implemented remove
> functions.
> 
> Now that the library does have APIs to unregister clks, use them
> to implement remove functions for the mt8195 clk drivers.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 16 ++++++++++++++++
>  drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 13 +++++++++++++
>  drivers/clk/mediatek/clk-mt8195-topckgen.c   | 20 ++++++++++++++++++++
>  drivers/clk/mediatek/clk-mt8195-vdo0.c       | 16 ++++++++++++++++
>  drivers/clk/mediatek/clk-mt8195-vdo1.c       | 16 ++++++++++++++++
>  5 files changed, 81 insertions(+)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> index af8d80f25f30..29cac3cf5f53 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> @@ -132,6 +132,8 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
>  	if (r)
>  		goto unregister_gates;
>  
> +	platform_set_drvdata(pdev, clk_data);
> +
>  	return r;
>  
>  unregister_gates:
> @@ -143,8 +145,22 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +static int clk_mt8195_apmixed_remove(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_gates(apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
> +	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
> +	mtk_free_clk_data(clk_data);
> +
> +	return 0;
> +}
> +
>  static struct platform_driver clk_mt8195_apmixed_drv = {
>  	.probe = clk_mt8195_apmixed_probe,
> +	.remove = clk_mt8195_apmixed_remove,
>  	.driver = {
>  		.name = "clk-mt8195-apmixed",
>  		.of_match_table = of_match_clk_mt8195_apmixed,
> diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> index 1fff6f3d2dc7..8cd88dfc3283 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> @@ -85,6 +85,18 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +static int clk_mt8195_apusys_pll_remove(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
> +	mtk_free_clk_data(clk_data);
> +
> +	return 0;
> +}
> +
>  static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
>  	{ .compatible = "mediatek,mt8195-apusys_pll", },
>  	{}
> @@ -92,6 +104,7 @@ static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
>  
>  static struct platform_driver clk_mt8195_apusys_pll_drv = {
>  	.probe = clk_mt8195_apusys_pll_probe,
> +	.remove = clk_mt8195_apusys_pll_remove,
>  	.driver = {
>  		.name = "clk-mt8195-apusys_pll",
>  		.of_match_table = of_match_clk_mt8195_apusys_pll,
> diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> index 3631f49a5e5a..b602fcd7f1d1 100644
> --- a/drivers/clk/mediatek/clk-mt8195-topckgen.c
> +++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> @@ -1271,6 +1271,8 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
>  	if (r)
>  		goto unregister_gates;
>  
> +	platform_set_drvdata(pdev, top_clk_data);
> +
>  	return r;
>  
>  unregister_gates:
> @@ -1290,8 +1292,26 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +static int clk_mt8195_topck_remove(struct platform_device *pdev)
> +{
> +	struct clk_onecell_data *top_clk_data = platform_get_drvdata(pdev);
> +	struct device_node *node = pdev->dev.of_node;
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
> +	mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
> +	mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
> +	mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
> +	mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
> +	mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
> +	mtk_free_clk_data(top_clk_data);
> +
> +	return 0;
> +}
> +
>  static struct platform_driver clk_mt8195_topck_drv = {
>  	.probe = clk_mt8195_topck_probe,
> +	.remove = clk_mt8195_topck_remove,
>  	.driver = {
>  		.name = "clk-mt8195-topck",
>  		.of_match_table = of_match_clk_mt8195_topck,
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> index af34eb564b1d..3bc7ed19d550 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> @@ -107,6 +107,8 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
>  	if (r)
>  		goto unregister_gates;
>  
> +	platform_set_drvdata(pdev, clk_data);
> +
>  	return r;
>  
>  unregister_gates:
> @@ -116,8 +118,22 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +static int clk_mt8195_vdo0_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->parent->of_node;
> +	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_gates(vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
> +	mtk_free_clk_data(clk_data);
> +
> +	return 0;
> +}
> +
>  static struct platform_driver clk_mt8195_vdo0_drv = {
>  	.probe = clk_mt8195_vdo0_probe,
> +	.remove = clk_mt8195_vdo0_remove,
>  	.driver = {
>  		.name = "clk-mt8195-vdo0",
>  	},
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
> index 6b502bbc730c..90c738a85ff1 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
> @@ -124,6 +124,8 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
>  	if (r)
>  		goto unregister_gates;
>  
> +	platform_set_drvdata(pdev, clk_data);
> +
>  	return r;
>  
>  unregister_gates:
> @@ -133,8 +135,22 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
>  	return r;
>  }
>  
> +static int clk_mt8195_vdo1_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct device_node *node = dev->parent->of_node;
> +	struct clk_onecell_data *clk_data = platform_get_drvdata(pdev);
> +
> +	of_clk_del_provider(node);
> +	mtk_clk_unregister_gates(vdo1_clks, ARRAY_SIZE(vdo1_clks), clk_data);
> +	mtk_free_clk_data(clk_data);
> +
> +	return 0;
> +}
> +
>  static struct platform_driver clk_mt8195_vdo1_drv = {
>  	.probe = clk_mt8195_vdo1_probe,
> +	.remove = clk_mt8195_vdo1_remove,
>  	.driver = {
>  		.name = "clk-mt8195-vdo1",
>  	},
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From miles.chen at mediatek.com  Wed Jan 26 00:37:41 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:37:41 +0800
Subject: [PATCH 29/31] clk: mediatek: mt8195: Implement error handling in
 probe functions
In-Reply-To: <20220122091731.283592-30-wenst@chromium.org>
References: <20220122091731.283592-30-wenst@chromium.org>
Message-ID: <20220126083741.18563-1-miles.chen@mediatek.com>

> Until now the mediatek clk driver library did not have any way to
> unregister clks, and so all drivers did not do proper cleanup in
> their error paths.
> 
> Now that the library does have APIs to unregister clks, use them
> in the error path of the probe functions for the mt8195 clk drivers
> to do proper cleanup.
> 
> Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

> ---
>  drivers/clk/mediatek/clk-mt8195-apmixedsys.c | 13 ++++--
>  drivers/clk/mediatek/clk-mt8195-apusys_pll.c | 11 ++++-
>  drivers/clk/mediatek/clk-mt8195-topckgen.c   | 49 +++++++++++++++-----
>  drivers/clk/mediatek/clk-mt8195-vdo0.c       |  4 +-
>  drivers/clk/mediatek/clk-mt8195-vdo1.c       |  4 +-
>  5 files changed, 63 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> index 5b1b7dc447eb..af8d80f25f30 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c
> @@ -120,17 +120,24 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
>  	if (!clk_data)
>  		return -ENOMEM;
>  
> -	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
> -	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
> +	r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
>  	if (r)
>  		goto free_apmixed_data;
>  
> +	r = mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
> +	if (r)
> +		goto unregister_plls;
> +
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  	if (r)
> -		goto free_apmixed_data;
> +		goto unregister_gates;
>  
>  	return r;
>  
> +unregister_gates:
> +	mtk_clk_register_gates(node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
> +unregister_plls:
> +	mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
>  free_apmixed_data:
>  	mtk_free_clk_data(clk_data);
>  	return r;
> diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> index db449ff877d7..1fff6f3d2dc7 100644
> --- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> +++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c
> @@ -66,13 +66,20 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
>  	if (!clk_data)
>  		return -ENOMEM;
>  
> -	mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
> -	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
>  	if (r)
>  		goto free_apusys_pll_data;
>  
> +	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
> +	if (r)
> +		goto unregister_plls;
> +
> +	platform_set_drvdata(pdev, clk_data);
> +
>  	return r;
>  
> +unregister_plls:
> +	mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
>  free_apusys_pll_data:
>  	mtk_free_clk_data(clk_data);
>  	return r;
> diff --git a/drivers/clk/mediatek/clk-mt8195-topckgen.c b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> index 3e2aba9c40bb..3631f49a5e5a 100644
> --- a/drivers/clk/mediatek/clk-mt8195-topckgen.c
> +++ b/drivers/clk/mediatek/clk-mt8195-topckgen.c
> @@ -1239,25 +1239,52 @@ static int clk_mt8195_topck_probe(struct platform_device *pdev)
>  		goto free_top_data;
>  	}
>  
> -	mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> -				    top_clk_data);
> -	mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
> -	mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
> -			       &mt8195_clk_lock, top_clk_data);
> -	mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
> -				    &mt8195_clk_lock, top_clk_data);
> -	mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
> -				    &mt8195_clk_lock, top_clk_data);
> -	r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
> +	r = mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
> +					top_clk_data);
>  	if (r)
>  		goto free_top_data;
>  
> +	r = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
> +	if (r)
> +		goto unregister_fixed_clks;
> +
> +	r = mtk_clk_register_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), node,
> +				   &mt8195_clk_lock, top_clk_data);
> +	if (r)
> +		goto unregister_factors;
> +
> +	r = mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
> +					&mt8195_clk_lock, top_clk_data);
> +	if (r)
> +		goto unregister_muxes;
> +
> +	r = mtk_clk_register_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
> +					&mt8195_clk_lock, top_clk_data);
> +	if (r)
> +		goto unregister_composite_muxes;
> +
> +	r = mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks), top_clk_data);
> +	if (r)
> +		goto unregister_composite_divs;
> +
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
>  	if (r)
> -		goto free_top_data;
> +		goto unregister_gates;
>  
>  	return r;
>  
> +unregister_gates:
> +	mtk_clk_unregister_gates(top_clks, ARRAY_SIZE(top_clks), top_clk_data);
> +unregister_composite_divs:
> +	mtk_clk_unregister_composites(top_adj_divs, ARRAY_SIZE(top_adj_divs), top_clk_data);
> +unregister_composite_muxes:
> +	mtk_clk_unregister_composites(top_muxes, ARRAY_SIZE(top_muxes), top_clk_data);
> +unregister_muxes:
> +	mtk_clk_unregister_muxes(top_mtk_muxes, ARRAY_SIZE(top_mtk_muxes), top_clk_data);
> +unregister_factors:
> +	mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
> +unregister_fixed_clks:
> +	mtk_clk_unregister_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks), top_clk_data);
>  free_top_data:
>  	mtk_free_clk_data(top_clk_data);
>  	return r;
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdo0.c b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> index f7ff7618c714..af34eb564b1d 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vdo0.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vdo0.c
> @@ -105,10 +105,12 @@ static int clk_mt8195_vdo0_probe(struct platform_device *pdev)
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  	if (r)
> -		goto free_vdo0_data;
> +		goto unregister_gates;
>  
>  	return r;
>  
> +unregister_gates:
> +	mtk_clk_unregister_gates(vdo0_clks, ARRAY_SIZE(vdo0_clks), clk_data);
>  free_vdo0_data:
>  	mtk_free_clk_data(clk_data);
>  	return r;
> diff --git a/drivers/clk/mediatek/clk-mt8195-vdo1.c b/drivers/clk/mediatek/clk-mt8195-vdo1.c
> index 03df8eae8838..6b502bbc730c 100644
> --- a/drivers/clk/mediatek/clk-mt8195-vdo1.c
> +++ b/drivers/clk/mediatek/clk-mt8195-vdo1.c
> @@ -122,10 +122,12 @@ static int clk_mt8195_vdo1_probe(struct platform_device *pdev)
>  
>  	r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
>  	if (r)
> -		goto free_vdo1_data;
> +		goto unregister_gates;
>  
>  	return r;
>  
> +unregister_gates:
> +	mtk_clk_unregister_gates(vdo1_clks, ARRAY_SIZE(vdo1_clks), clk_data);
>  free_vdo1_data:
>  	mtk_free_clk_data(clk_data);
>  	return r;
> -- 
> 2.35.0.rc0.227.g00780c9af4-goog
> 
> 


From peng.fan at oss.nxp.com  Wed Jan 26 00:51:20 2022
From: peng.fan at oss.nxp.com (Peng Fan (OSS))
Date: Wed, 26 Jan 2022 16:51:20 +0800
Subject: [PATCH V2] remoteproc: support self recovery after rproc crash
Message-ID: <20220126085120.3397450-1-peng.fan@oss.nxp.com>

From: Peng Fan <peng.fan at nxp.com>

Current logic only support main processor to stop/start the remote
processor after rproc crash. However to SoC, such as i.MX8QM/QXP, the
remote processor could do self recovery after crash and trigger watchdog
reboot. It does not need main processor to load image, stop/start M4
core.

This patch add a new flag to indicate whether the SoC has self recovery
capability. And introduce two functions: rproc_self_recovery,
rproc_assisted_recovery for the two cases. Assisted recovery is as
before, let main processor to help recovery, while self recovery is
recover itself withou help. To self recovery, we only do detach and
attach.

Signed-off-by: Peng Fan <peng.fan at nxp.com>
---

V2:
 Nothing change in V2.
 Only move this patch out from
 https://patchwork.kernel.org/project/linux-remoteproc/list/?series=604364

 drivers/remoteproc/remoteproc_core.c | 66 ++++++++++++++++++++--------
 include/linux/remoteproc.h           |  2 +
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c
index 69f51acf235e..4bd5544dab8f 100644
--- a/drivers/remoteproc/remoteproc_core.c
+++ b/drivers/remoteproc/remoteproc_core.c
@@ -1887,6 +1887,49 @@ static int __rproc_detach(struct rproc *rproc)
 	return 0;
 }
 
+static int rproc_self_recovery(struct rproc *rproc)
+{
+	int ret;
+
+	mutex_unlock(&rproc->lock);
+	ret = rproc_detach(rproc);
+	mutex_lock(&rproc->lock);
+	if (ret)
+		return ret;
+
+	if (atomic_inc_return(&rproc->power) > 1)
+		return 0;
+	return rproc_attach(rproc);
+}
+
+static int rproc_assisted_recovery(struct rproc *rproc)
+{
+	const struct firmware *firmware_p;
+	struct device *dev = &rproc->dev;
+	int ret;
+
+	ret = rproc_stop(rproc, true);
+	if (ret)
+		return ret;
+
+	/* generate coredump */
+	rproc->ops->coredump(rproc);
+
+	/* load firmware */
+	ret = request_firmware(&firmware_p, rproc->firmware, dev);
+	if (ret < 0) {
+		dev_err(dev, "request_firmware failed: %d\n", ret);
+		return ret;
+	}
+
+	/* boot the remote processor up again */
+	ret = rproc_start(rproc, firmware_p);
+
+	release_firmware(firmware_p);
+
+	return ret;
+}
+
 /**
  * rproc_trigger_recovery() - recover a remoteproc
  * @rproc: the remote processor
@@ -1901,7 +1944,6 @@ static int __rproc_detach(struct rproc *rproc)
  */
 int rproc_trigger_recovery(struct rproc *rproc)
 {
-	const struct firmware *firmware_p;
 	struct device *dev = &rproc->dev;
 	int ret;
 
@@ -1915,24 +1957,10 @@ int rproc_trigger_recovery(struct rproc *rproc)
 
 	dev_err(dev, "recovering %s\n", rproc->name);
 
-	ret = rproc_stop(rproc, true);
-	if (ret)
-		goto unlock_mutex;
-
-	/* generate coredump */
-	rproc->ops->coredump(rproc);
-
-	/* load firmware */
-	ret = request_firmware(&firmware_p, rproc->firmware, dev);
-	if (ret < 0) {
-		dev_err(dev, "request_firmware failed: %d\n", ret);
-		goto unlock_mutex;
-	}
-
-	/* boot the remote processor up again */
-	ret = rproc_start(rproc, firmware_p);
-
-	release_firmware(firmware_p);
+	if (rproc->self_recovery)
+		ret = rproc_self_recovery(rproc);
+	else
+		ret = rproc_assisted_recovery(rproc);
 
 unlock_mutex:
 	mutex_unlock(&rproc->lock);
diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h
index e0600e1e5c17..b32ef46f8aa4 100644
--- a/include/linux/remoteproc.h
+++ b/include/linux/remoteproc.h
@@ -529,6 +529,7 @@ struct rproc_dump_segment {
  * @elf_machine: firmware ELF machine
  * @cdev: character device of the rproc
  * @cdev_put_on_release: flag to indicate if remoteproc should be shutdown on @char_dev release
+ * @self_recovery: flag to indicate if remoteproc support self recovery
  */
 struct rproc {
 	struct list_head node;
@@ -568,6 +569,7 @@ struct rproc {
 	u16 elf_machine;
 	struct cdev cdev;
 	bool cdev_put_on_release;
+	bool self_recovery;
 };
 
 /**
-- 
2.25.1



From leoyang.li at nxp.com  Wed Jan 26 00:55:52 2022
From: leoyang.li at nxp.com (Leo Li)
Date: Wed, 26 Jan 2022 08:55:52 +0000
Subject: [PATCH v3 8/8] arm64: dts: ls1028a-qds: add overlays for various
 serdes protocols
In-Reply-To: <20220126083348.GG4686@dragon>
References: <20211214093240.23320-1-leoyang.li@nxp.com>
 <20211214093240.23320-9-leoyang.li@nxp.com> <20220126083348.GG4686@dragon>
Message-ID: <AS8PR04MB8946E671ABAF95E88E26D9038F209@AS8PR04MB8946.eurprd04.prod.outlook.com>



> -----Original Message-----
> From: Shawn Guo <shawnguo at kernel.org>
> Sent: Wednesday, January 26, 2022 4:34 PM
> To: Leo Li <leoyang.li at nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org; linux-kernel at vger.kernel.org;
> Alexandru Marginean <alexandru.marginean at nxp.com>; Ioana Ciornei
> <ioana.ciornei at nxp.com>; Aisheng Dong <aisheng.dong at nxp.com>; Jason
> Liu <jason.hui.liu at nxp.com>; Vladimir Oltean <vladimir.oltean at nxp.com>
> Subject: Re: [PATCH v3 8/8] arm64: dts: ls1028a-qds: add overlays for various
> serdes protocols
> 
> Hi Leo,
> 
> On Tue, Dec 14, 2021 at 03:32:40AM -0600, Li Yang wrote:
> > From: Alex Marginean <alexandru.marginean at nxp.com>
> >
> > Add overlays for various serdes protocols on LS1028A QDS board using
> > different PHY cards.  These should be applied at boot, based on serdes
> > configuration.  If no overlay is applied, only the RGMII interface on
> > the QDS is available in Linux.
> >
> > Building device tree fragments requires passing the "-@" argument to
> > dtc, which increases the base dtb size and might cause some platforms
> > to fail to store the new binary. To avoid that, it would be nice to
> > only pass "-@" for the platforms where fragments will be used, aka
> > LS1028A-QDS. One approach suggested by Rob Herring is used here:
> >
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flore
> > .kernel.org%2Fpatchwork%2Fpatch%2F821645%2F&amp;data=04%7C01%7
> Cleoyang
> > .li%40nxp.com%7C05d70cc78d8e432dfb8908d9e0a69c47%7C686ea1d3bc2b
> 4c6fa92
> >
> cd99c5c301635%7C0%7C0%7C637787828474973256%7CUnknown%7CTWFpb
> GZsb3d8eyJ
> >
> WIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%
> 7C3000
> >
> &amp;sdata=FF7G4XlUbxPoZ%2FPu2ERMSe2I5tg%2F8R1nm0wx8W7dxc4%3
> D&amp;rese
> > rved=0
> >
> > Also moved the enet* override nodes in dts file to be in alphabetic order.
> >
> > Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> > Signed-off-by: Ioana Ciornei <ioana.ciornei at nxp.com>
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
> > Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> > Signed-off-by: Li Yang <leoyang.li at nxp.com>
> > ---
> >  arch/arm64/boot/dts/freescale/Makefile        |  16 +++
> >  .../dts/freescale/fsl-ls1028a-qds-13bb.dts    | 113 ++++++++++++++++++
> >  .../dts/freescale/fsl-ls1028a-qds-65bb.dts    | 108 +++++++++++++++++
> >  .../dts/freescale/fsl-ls1028a-qds-7777.dts    |  82 +++++++++++++
> >  .../dts/freescale/fsl-ls1028a-qds-85bb.dts    | 107 +++++++++++++++++
> >  .../dts/freescale/fsl-ls1028a-qds-899b.dts    |  75 ++++++++++++
> >  .../dts/freescale/fsl-ls1028a-qds-9999.dts    |  79 ++++++++++++
> >  .../boot/dts/freescale/fsl-ls1028a-qds.dts    |  19 ++-
> >  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi |   2 +-
> >  9 files changed, 595 insertions(+), 6 deletions(-)  create mode
> > 100644 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> >  create mode 100644
> > arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> >  create mode 100644
> > arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> >  create mode 100644
> > arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> >  create mode 100644
> > arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> >  create mode 100644
> > arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> >
> > diff --git a/arch/arm64/boot/dts/freescale/Makefile
> > b/arch/arm64/boot/dts/freescale/Makefile
> > index a14a6173b765..f518eb1e1142 100644
> > --- a/arch/arm64/boot/dts/freescale/Makefile
> > +++ b/arch/arm64/boot/dts/freescale/Makefile
> > @@ -1,4 +1,14 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > +
> > +# required for overlay support
> > +DTC_FLAGS_fsl-ls1028a-qds := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-13bb := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-65bb := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-7777 := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-85bb := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-899b := -@
> > +DTC_FLAGS_fsl-ls1028a-qds-9999 := -@
> > +
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb @@ -11,6
> > +21,12 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) +=
> > fsl-ls1028a-kontron-sl28-var2.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) +=
> > fsl-ls1028a-kontron-sl28-var3-ads2.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
> > +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
> >  dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb diff --git
> > a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> > new file mode 100644
> > index 000000000000..f748a2c12a70
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
> > @@ -0,0 +1,113 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 13bb
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board with lane B rework.
> > + * Requires a SCH-30841 card with lane A of connector rewired to PHY lane
> C.
> > + * Set-up is a SCH-30842 card in slot 1 and SCH-30841 in slot 2.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> 
> I cannot find this mdio_slot1 node (and mdio_slot2 below) in any upstream
> device tree.  We are not going to maintain a bunch of overlays which are only
> meant to apply on the out-of-tree DTs.

Sorry the patch adding mdio_slot nodes has been missed from the tree maintenance.

> 
> So please either submit those missing device nodes in the base DT, or I will
> have to revert the patch.

Will submit the patch right away.

> 
> Shawn
> 
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			slot1_sgmii: ethernet-phy at 2 {
> > +				/* AQR112 */
> > +				reg = <0x2>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&enetc_port0>;
> > +
> > +		__overlay__ {
> > +			phy-handle = <&slot1_sgmii>;
> > +			phy-mode = "usxgmii";
> > +			managed = "in-band-status";
> > +			status = "okay";
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mdio_slot2>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* 4 ports on AQR412 */
> > +			slot2_qxgmii0: ethernet-phy at 0 {
> > +				reg = <0x0>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot2_qxgmii1: ethernet-phy at 1 {
> > +				reg = <0x1>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot2_qxgmii2: ethernet-phy at 2 {
> > +				reg = <0x2>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot2_qxgmii3: ethernet-phy at 3 {
> > +				reg = <0x3>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 3 {
> > +		target = <&mscc_felix_ports>;
> > +
> > +		__overlay__ {
> > +			port at 0 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qxgmii0>;
> > +				phy-mode = "usxgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qxgmii1>;
> > +				phy-mode = "usxgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qxgmii2>;
> > +				phy-mode = "usxgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 3 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qxgmii3>;
> > +				phy-mode = "usxgmii";
> > +				managed = "in-band-status";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 4 {
> > +		target = <&mscc_felix>;
> > +
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> > new file mode 100644
> > index 000000000000..8ffb707a1576
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
> > @@ -0,0 +1,108 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 69xx
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board with lane B rework.
> > + * Requires a SCH-30842 card in slot 1 and a SCH-28021 card in slot 2.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			slot1_sgmii: ethernet-phy at 2 {
> > +				/* AQR112 */
> > +				reg = <0x2>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&enetc_port0>;
> > +
> > +		__overlay__ {
> > +			phy-handle = <&slot1_sgmii>;
> > +			phy-mode = "2500base-x";
> > +			managed = "in-band-status";
> > +			status = "okay";
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mdio_slot2>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* 4 ports on VSC8514 */
> > +			slot2_qsgmii0: ethernet-phy at 8 {
> > +				reg = <0x8>;
> > +			};
> > +
> > +			slot2_qsgmii1: ethernet-phy at 9 {
> > +				reg = <0x9>;
> > +			};
> > +
> > +			slot2_qsgmii2: ethernet-phy at a {
> > +				reg = <0xa>;
> > +			};
> > +
> > +			slot2_qsgmii3: ethernet-phy at b {
> > +				reg = <0xb>;
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 3 {
> > +		target = <&mscc_felix_ports>;
> > +
> > +		__overlay__ {
> > +			port at 0 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii0>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii1>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii2>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 3 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii3>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 4 {
> > +		target = <&mscc_felix>;
> > +
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> > new file mode 100644
> > index 000000000000..eb6a1e674f10
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
> > @@ -0,0 +1,82 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 7777
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board without lane B rework.
> > + * Requires a SCH-30841 card without lane A/C rewire and with a FW
> > +with muxing
> > + * disabled, plugged in slot 1.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* 4 ports on AQR412 */
> > +			slot1_sxgmii0: ethernet-phy at 0 {
> > +				reg = <0x0>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot1_sxgmii1: ethernet-phy at 1 {
> > +				reg = <0x1>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot1_sxgmii2: ethernet-phy at 2 {
> > +				reg = <0x2>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +
> > +			slot1_sxgmii3: ethernet-phy at 3 {
> > +				reg = <0x3>;
> > +				compatible = "ethernet-phy-ieee802.3-c45";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&mscc_felix_ports>;
> > +
> > +		__overlay__ {
> > +			port at 0 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sxgmii0>;
> > +				phy-mode = "2500base-x";
> > +			};
> > +
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sxgmii1>;
> > +				phy-mode = "2500base-x";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sxgmii2>;
> > +				phy-mode = "2500base-x";
> > +			};
> > +
> > +			port at 3 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sxgmii3>;
> > +				phy-mode = "2500base-x";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mscc_felix>;
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> > new file mode 100644
> > index 000000000000..8e90c3088ba1
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
> > @@ -0,0 +1,107 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 85bb
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board with lane B rework.
> > + * Requires a SCH-24801 card in slot 1 and a SCH-28021 card in slot 2.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			slot1_sgmii: ethernet-phy at 1c {
> > +				/* 1st port on VSC8234 */
> > +				reg = <0x1c>;
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&enetc_port0>;
> > +
> > +		__overlay__ {
> > +			phy-handle = <&slot1_sgmii>;
> > +			phy-mode = "sgmii";
> > +			managed = "in-band-status";
> > +			status = "okay";
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mdio_slot2>;
> > +
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* 4 ports on VSC8514 */
> > +			slot2_qsgmii0: ethernet-phy at 8 {
> > +				reg = <0x8>;
> > +			};
> > +
> > +			slot2_qsgmii1: ethernet-phy at 9 {
> > +				reg = <0x9>;
> > +			};
> > +
> > +			slot2_qsgmii2: ethernet-phy at a {
> > +				reg = <0xa>;
> > +			};
> > +
> > +			slot2_qsgmii3: ethernet-phy at b {
> > +				reg = <0xb>;
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 3 {
> > +		target = <&mscc_felix_ports>;
> > +
> > +		__overlay__ {
> > +			port at 0 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii0>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii1>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii2>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 3 {
> > +				status = "okay";
> > +				phy-handle = <&slot2_qsgmii3>;
> > +				phy-mode = "qsgmii";
> > +				managed = "in-band-status";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 4 {
> > +		target = <&mscc_felix>;
> > +
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> > new file mode 100644
> > index 000000000000..5d0a094e6c44
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
> > @@ -0,0 +1,75 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 85xx
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board without lane B rework.
> > + * Requires a SCH-24801 card in slot 1.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* VSC8234 */
> > +			slot1_sgmii0: ethernet-phy at 1c {
> > +				reg = <0x1c>;
> > +			};
> > +
> > +			slot1_sgmii1: ethernet-phy at 1d {
> > +				reg = <0x1d>;
> > +			};
> > +
> > +			slot1_sgmii2: ethernet-phy at 1e {
> > +				reg = <0x1e>;
> > +			};
> > +
> > +			slot1_sgmii3: ethernet-phy at 1f {
> > +				reg = <0x1f>;
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&enetc_port0>;
> > +		__overlay__ {
> > +			phy-handle = <&slot1_sgmii0>;
> > +			phy-mode = "sgmii";
> > +			managed = "in-band-status";
> > +			status = "okay";
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mscc_felix_ports>;
> > +		__overlay__ {
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii1>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii2>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 3 {
> > +		target = <&mscc_felix>;
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> > new file mode 100644
> > index 000000000000..1ef743c48e84
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
> > @@ -0,0 +1,79 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +/*
> > + * Device Tree fragment for LS1028A QDS board, serdes 85xx
> > + *
> > + * Copyright 2019-2021 NXP
> > + *
> > + * Requires a LS1028A QDS board without lane B rework.
> > + * Requires a SCH-24801 card in slot 1.
> > + */
> > +
> > +/dts-v1/;
> > +/plugin/;
> > +
> > +/ {
> > +	fragment at 0 {
> > +		target = <&mdio_slot1>;
> > +		__overlay__ {
> > +			#address-cells = <1>;
> > +			#size-cells = <0>;
> > +
> > +			/* VSC8234 */
> > +			slot1_sgmii0: ethernet-phy at 1c {
> > +				reg = <0x1c>;
> > +			};
> > +
> > +			slot1_sgmii1: ethernet-phy at 1d {
> > +				reg = <0x1d>;
> > +			};
> > +
> > +			slot1_sgmii2: ethernet-phy at 1e {
> > +				reg = <0x1e>;
> > +			};
> > +
> > +			slot1_sgmii3: ethernet-phy at 1f {
> > +				reg = <0x1f>;
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 1 {
> > +		target = <&mscc_felix_ports>;
> > +		__overlay__ {
> > +			port at 0 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii0>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 1 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii1>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 2 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii2>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +
> > +			port at 3 {
> > +				status = "okay";
> > +				phy-handle = <&slot1_sgmii3>;
> > +				phy-mode = "sgmii";
> > +				managed = "in-band-status";
> > +			};
> > +		};
> > +	};
> > +
> > +	fragment at 2 {
> > +		target = <&mscc_felix>;
> > +		__overlay__ {
> > +			status = "okay";
> > +		};
> > +	};
> > +};
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> > index 782853a449cc..177bc1405f0f 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> > @@ -211,6 +211,16 @@ &duart1 {
> >  	status = "okay";
> >  };
> >
> > +&enetc_port1 {
> > +	phy-handle = <&qds_phy1>;
> > +	phy-mode = "rgmii-id";
> > +	status = "okay";
> > +};
> > +
> > +&enetc_port2 {
> > +	status = "okay";
> > +};
> > +
> >  &esdhc {
> >  	status = "okay";
> >  };
> > @@ -326,17 +336,16 @@ rtc at 51 {
> >  	};
> >  };
> >
> > -&enetc_port1 {
> > -	phy-handle = <&qds_phy1>;
> > -	phy-mode = "rgmii-id";
> > +&lpuart0 {
> >  	status = "okay";
> >  };
> >
> > -&lpuart0 {
> > +&lpuart1 {
> >  	status = "okay";
> >  };
> >
> > -&lpuart1 {
> > +&mscc_felix_port4 {
> > +	ethernet = <&enetc_port2>;
> >  	status = "okay";
> >  };
> >
> > diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > index 5a7b26a1bad2..5bb8c26e0825 100644
> > --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> > @@ -1115,7 +1115,7 @@ mscc_felix: ethernet-switch at 0,5 {
> >  				interrupts = <GIC_SPI 95
> IRQ_TYPE_LEVEL_HIGH>;
> >  				status = "disabled";
> >
> > -				ports {
> > +				mscc_felix_ports: ports {
> >  					#address-cells = <1>;
> >  					#size-cells = <0>;
> >
> > --
> > 2.25.1
> >


From daniel.lezcano at linaro.org  Wed Jan 26 00:59:26 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Jan 2022 09:59:26 +0100
Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
In-Reply-To: <DU0PR04MB9417BA24DB13CD6C98BE47CF88209@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20211214120737.1611955-1-peng.fan@oss.nxp.com>
 <DU0PR04MB94177F777E854B92C665303488519@DU0PR04MB9417.eurprd04.prod.outlook.com>
 <DU0PR04MB9417BA24DB13CD6C98BE47CF88209@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <c7584787-838f-97b8-5e2a-c7f271d8a406@linaro.org>


On 26/01/2022 09:24, Peng Fan wrote:
> Daniel,
> 
>> Subject: RE: [PATCH 0/5] clocksource/drivers/imx: several updates
> 
> Do you have time to give a look?

Yeah, sorry for the delay

They sounds good, I'll pick them up

Thanks

  -- Daniel


>>> Subject: [PATCH 0/5] clocksource/drivers/imx: several updates
>>>
>>> From: Peng Fan <peng.fan at nxp.com>
>>>
>>> This patchset includes several update of i.MX sysctr and tpm driver.
>>
>> Ping..
>>
>> Thanks,
>> Peng.
>>
>>>
>>> Peng Fan (5):
>>>   clocksource/drivers/imx-sysctr: drop IRQF_IRQPOLL
>>>   clocksource/drivers/imx-tpm: drop IRQF_IRQPOLL
>>>   clocksource/drivers/imx-tpm: mark two variable with __ro_after_init
>>>   clocksource/drivers/imx-tpm: add CLOCK_EVT_FEAT_DYNIRQ
>>>   clocksource/drivers/imx-tpm: update name of clkevt
>>>
>>>  drivers/clocksource/timer-imx-sysctr.c |  2 +-
>>>  drivers/clocksource/timer-imx-tpm.c    | 10 +++++-----
>>>  2 files changed, 6 insertions(+), 6 deletions(-)
>>>
>>> --
>>> 2.25.1
> 


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From miles.chen at mediatek.com  Wed Jan 26 00:59:47 2022
From: miles.chen at mediatek.com (Miles Chen)
Date: Wed, 26 Jan 2022 16:59:47 +0800
Subject: [PATCH 31/31] clk: mediatek: Warn if clk IDs are duplicated
In-Reply-To: <20220122091731.283592-32-wenst@chromium.org>
References: <20220122091731.283592-32-wenst@chromium.org>
Message-ID: <20220126085947.31507-1-miles.chen@mediatek.com>

>The Mediatek clk driver library handles duplicate clock IDs in two
>different ways: either ignoring the duplicate entry, or overwriting
>the old clk. Either way may cause unexpected behavior, and the latter
>also causes an orphan clk that cannot be cleaned up.
>
>Align the behavior so that later duplicate entries are ignored, and
>a warning printed. The warning will also aid in making the issue
>noticeable.
>
>Signed-off-by: Chen-Yu Tsai <wenst at chromium.org>
>---
> drivers/clk/mediatek/clk-cpumux.c |  6 ++++++
> drivers/clk/mediatek/clk-gate.c   |  5 ++++-
> drivers/clk/mediatek/clk-mtk.c    | 18 ++++++++++++++----
> drivers/clk/mediatek/clk-mux.c    |  5 ++++-
> drivers/clk/mediatek/clk-pll.c    |  6 ++++++
> 5 files changed, 34 insertions(+), 6 deletions(-)
>
>diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c
>index 499c60432280..c11b3fae622e 100644
>--- a/drivers/clk/mediatek/clk-cpumux.c
>+++ b/drivers/clk/mediatek/clk-cpumux.c
>@@ -120,6 +120,12 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_composite *mux = &clks[i];
> 
>+		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
>+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
>+				node, mux->id);
>+			continue;

%pOF is an useful information when this happens.

Reviewed-by: Miles Chen <miles.chen at mediatek.com>

>+		}
>+
> 		clk = mtk_clk_register_cpumux(mux, regmap);
> 		if (IS_ERR(clk)) {
> 			pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
>diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c
>index 631ff170b7b9..da52023f8455 100644
>--- a/drivers/clk/mediatek/clk-gate.c
>+++ b/drivers/clk/mediatek/clk-gate.c
>@@ -224,8 +224,11 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_gate *gate = &clks[i];
> 
>-		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[gate->id])) {
>+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
>+				node, gate->id);
> 			continue;
>+		}
> 
> 		clk = mtk_clk_register_gate(gate->name, gate->parent_name,
> 					    regmap,
>diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
>index 6d0b8842971b..b2a3568922b2 100644
>--- a/drivers/clk/mediatek/clk-mtk.c
>+++ b/drivers/clk/mediatek/clk-mtk.c
>@@ -65,8 +65,10 @@ int mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, int num,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_fixed_clk *rc = &clks[i];
> 
>-		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[rc->id])) {
>+			pr_warn("Trying to register duplicate clock ID: %d\n", rc->id);
> 			continue;
>+		}
> 
> 		clk = clk_register_fixed_rate(NULL, rc->name, rc->parent, 0,
> 					      rc->rate);
>@@ -128,8 +130,10 @@ int mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_fixed_factor *ff = &clks[i];
> 
>-		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[ff->id])) {
>+			pr_warn("Trying to register duplicate clock ID: %d\n", ff->id);
> 			continue;
>+		}
> 
> 		clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name,
> 				CLK_SET_RATE_PARENT, ff->mult, ff->div);
>@@ -300,8 +304,11 @@ int mtk_clk_register_composites(const struct mtk_composite *mcs, int num,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_composite *mc = &mcs[i];
> 
>-		if (clk_data && !IS_ERR_OR_NULL(clk_data->clks[mc->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[mc->id])) {
>+			pr_warn("Trying to register duplicate clock ID: %d\n",
>+				mc->id);
> 			continue;
>+		}
> 
> 		clk = mtk_clk_register_composite(mc, base, lock);
> 
>@@ -363,8 +370,11 @@ int mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, int num,
> 	for (i = 0; i <  num; i++) {
> 		const struct mtk_clk_divider *mcd = &mcds[i];
> 
>-		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[mcd->id])) {
>+			pr_warn("Trying to register duplicate clock ID: %d\n",
>+				mcd->id);
> 			continue;
>+		}
> 
> 		clk = clk_register_divider(NULL, mcd->name, mcd->parent_name,
> 			mcd->flags, base +  mcd->div_reg, mcd->div_shift,
>diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c
>index f51e67650f03..21ad5a4afd65 100644
>--- a/drivers/clk/mediatek/clk-mux.c
>+++ b/drivers/clk/mediatek/clk-mux.c
>@@ -208,8 +208,11 @@ int mtk_clk_register_muxes(const struct mtk_mux *muxes,
> 	for (i = 0; i < num; i++) {
> 		const struct mtk_mux *mux = &muxes[i];
> 
>-		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id]))
>+		if (!IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
>+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
>+				node, mux->id);
> 			continue;
>+		}
> 
> 		clk = mtk_clk_register_mux(mux, regmap, lock);
> 
>diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c
>index 1dd15f560659..e5e9c188be99 100644
>--- a/drivers/clk/mediatek/clk-pll.c
>+++ b/drivers/clk/mediatek/clk-pll.c
>@@ -386,6 +386,12 @@ int mtk_clk_register_plls(struct device_node *node,
> 	for (i = 0; i < num_plls; i++) {
> 		const struct mtk_pll_data *pll = &plls[i];
> 
>+		if (!IS_ERR_OR_NULL(clk_data->clks[pll->id])) {
>+			pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
>+				node, pll->id);
>+			continue;
>+		}
>+
> 		clk = mtk_clk_register_pll(pll, base);
> 
> 		if (IS_ERR(clk)) {
>-- 
>2.35.0.rc0.227.g00780c9af4-goog
>
>


From jason-jh.lin at mediatek.com  Wed Jan 26 01:01:09 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 17:01:09 +0800
Subject: [PATCH] arm64: dts: mt8195: add gce node
Message-ID: <20220126090109.32143-1-jason-jh.lin@mediatek.com>

Add gce node and gce alias on mt8195 dts file.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch is based on [1]

[1] arm64: dts: Add mediatek SoC mt8195 and evaluation board
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index a363e82f6988..d778ca598d18 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -6,6 +6,7 @@
 
 /dts-v1/;
 #include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/gce/mt8195-gce.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/phy/phy.h>
@@ -18,6 +19,11 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	aliases {
+		gce0 = &gce0;
+		gce1 = &gce1;
+	};
+
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -367,6 +373,22 @@
 			assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
 		};
 
+		gce0: mdp_mailbox at 10320000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10320000 0 0x4000>;
+			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
+		};
+
+		gce1: disp_mailbox at 10330000 {
+			compatible = "mediatek,mt8195-gce";
+			reg = <0 0x10330000 0 0x4000>;
+			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
+			#mbox-cells = <2>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
+		};
+
 		scp_adsp: clock-controller at 10720000 {
 			compatible = "mediatek,mt8195-scp_adsp";
 			reg = <0 0x10720000 0 0x1000>;
-- 
2.18.0



From shawnguo at kernel.org  Wed Jan 26 01:07:40 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 17:07:40 +0800
Subject: [PATCH] arm64: dts: imx8m{m,n}_venice*: add gpio-line-names
In-Reply-To: <20211215001812.9006-1-tharvey@gateworks.com>
References: <20211215001812.9006-1-tharvey@gateworks.com>
Message-ID: <20220126090739.GH4686@dragon>

On Tue, Dec 14, 2021 at 04:18:12PM -0800, Tim Harvey wrote:
> Add gpio-line-names for the various GPIO's used on Gateworks Venice
> boards. Note that these GPIO's are typically 'configured' in Boot
> Firmware via gpio-hog therefore we only configure line names to keep the
> boot firmware configuration from changing on kernel init.
> 
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>

It doesn't apply to my imx/dt64 branch.  Could you rebase?

Shawn


From maz at kernel.org  Wed Jan 26 01:07:48 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 09:07:48 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220125192851.3907611-1-broonie@kernel.org>
References: <20220125192851.3907611-1-broonie@kernel.org>
Message-ID: <87h79q7tln.wl-maz@kernel.org>

On Tue, 25 Jan 2022 19:28:51 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 5 +++++
>  tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>  3 files changed, 14 insertions(+), 2 deletions(-)
>

[...]

> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..647c18733e1b 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>  			nr_vcpus, nr_vcpus_created);
>  
>  	/* Distributor setup */
> -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);

So you now only test whether it is possible to create a virtual GICv3,
but don't actually create it. How does this work?

	M.

-- 
Without deviation from the norm, progress is not possible.


From liang.yang at amlogic.com  Wed Jan 26 01:08:42 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 26 Jan 2022 17:08:42 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
Message-ID: <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>

Hi Neil,

On 2022/1/25 22:54, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> On 21/01/2022 08:45, Liang Yang wrote:
>> This driver will add a MMC clock controller driver support.
>> The original idea about adding a clock controller is during the
>> discussion in the NAND driver mainline effort[1].
>>
>> This driver is tested in the S400 board (AXG platform) with NAND driver.
> 
> Thanks a lot for providing a fixed and updated version of this serie.
> 
> After some chat with Jerome and Kevin, it seems the way the eMMC clock reuse
> for NAND was designed nearly 4 years doesn't look accurate anymore.
> 
> Having a separate clk driver designed to replace the eMMC node when NAND is
> used on the board seems over engineered.
> 
> Actually having the clock code you add in this serie _but_ directly in
> the NAND looks far better, and more coherent since having Linux runtime
> detection of eMMC vs NAND will never happen and even this serie required
> some DT modification from the bootloader.
> 
> I'll let Jerome or Kevin add more details if they want, but I think you should resurrect
> the work you pushed in [1] & [2] but:
> - passing the eMMC clk registers as a third "reg" cell
Does it just need to define a 'reg' resource in NFC node and not 
'syscon' here?
> - passing the same "clocks" phandle as the eMMC node
> - adding the eMMC clock code in the NAND driver directly
> 
> I'm open to discussions if you consider the current approach is still superior.

I don't have persuasive ideas, but really it shares the common clock 
implementation for both NFC and EMMC. and we don't need to paste the 
same code in NFC and EMMC.

> 
> Thanks,
> Neil
> 
> [1] https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
> 
>>
>> Changes since v9 [10]
>>   - use clk_parent_data instead of parent_names
>>
>> Changes since v8 [9]
>>   - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>   - use struct_size to caculate onecell_data
>>   - add clk-phase-delay.h
>>   - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>
>> Changes since v7 [8]
>>   - move meson_clk_get_phase_delay_data() from header to driver
>>   - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>   - remove onecell date and ID for internal MUX clk
>>   - use helper for functions for ONE_BASED in sclk-div
>>   - add ONE_BASED support for duty cycle
>>
>> Changes since v6 [7]:
>>   - add one based support for sclk divier
>>   - alloc sclk in probe for multiple instance
>>   - fix coding styles
>>
>> Changes since v5 [6]:
>>   - remove divider ops with .init and use sclk_div instead
>>   - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>   - drop the useless type cast
>>
>> Changes since v4 [5]:
>>   - use struct parm in phase delay driver
>>   - remove 0 delay releted part in phase delay driver
>>   - don't rebuild the parent name once again
>>   - add divider ops with .init
>>
>> Changes since v3 [4]:
>>   - separate clk-phase-delay driver
>>   - replace clk_get_rate() with clk_hw_get_rate()
>>   - collect Rob's R-Y
>>   - drop 'meson-' prefix from compatible string
>>
>>   Changes since v2 [3]:
>>   - squash dt-binding clock-id patch
>>   - update license
>>   - fix alignment
>>   - construct a clk register helper() function
>>
>> Changes since v1 [2]:
>>   - implement phase clock
>>   - update compatible name
>>   - adjust file name
>>   - divider probe() into small functions, and re-use them
>>
>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>> Liang Yang (4):
>>    clk: meson: add one based divider support for sclk
>>    clk: meson: add emmc sub clock phase delay driver
>>    clk: meson: add DT documentation for emmc clock controller
>>    clk: meson: add sub MMC clock controller driver
>>
>>   .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>   drivers/clk/meson/Kconfig                     |  18 ++
>>   drivers/clk/meson/Makefile                    |   2 +
>>   drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>   drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>   drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>   drivers/clk/meson/sclk-div.c                  |  59 ++--
>>   drivers/clk/meson/sclk-div.h                  |   3 +
>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>   9 files changed, 529 insertions(+), 22 deletions(-)
>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>   create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>   create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>   create mode 100644 drivers/clk/meson/mmc-clkc.c
>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>
> 
> .


From shawnguo at kernel.org  Wed Jan 26 01:10:41 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 17:10:41 +0800
Subject: [PATCH V5 6/9] arm64: dts: imx8mn: add GPC node
In-Reply-To: <20211215004626.2241839-7-aford173@gmail.com>
References: <20211215004626.2241839-1-aford173@gmail.com>
 <20211215004626.2241839-7-aford173@gmail.com>
Message-ID: <20220126091038.GI4686@dragon>

On Tue, Dec 14, 2021 at 06:46:23PM -0600, Adam Ford wrote:
> Add the DT node for the GPC, including all the PGC power domains,
> some of them are not fully functional yet, as they require interaction
> with the blk-ctrls to properly power up/down the peripherals.
> 
> Signed-off-by: Adam Ford <aford173 at gmail.com>
> Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

Applied #6 ~ #9, thanks!


From s.nawrocki at samsung.com  Wed Jan 26 01:12:21 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:12:21 +0100
Subject: [PATCH v5 02/16] dt-bindings: clock: Add bindings definitions
 for FSD CMU blocks
In-Reply-To: <20220124141644.71052-3-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142901epcas5p3776232af7911abfbf08d82358350f57c@epcas5p3.samsung.com>
 <20220124141644.71052-3-alim.akhtar@samsung.com>
Message-ID: <0724f0f6-d72a-0e63-2791-d038b701b8f2@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Clock controller driver of FSD platform is designed to have separate
> instances for each particular CMU. So clock IDs in this bindings header
> also start from 1 for each CMU block.
> 
> Cc: linux-fsd at tesla.com
> Reported-by: kernel test robot <lkp at intel.com>
> [robot: reported missing #endif]
> Acked-by: Stephen Boyd <sboyd at kernel.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From m.tretter at pengutronix.de  Wed Jan 26 01:12:50 2022
From: m.tretter at pengutronix.de (Michael Tretter)
Date: Wed, 26 Jan 2022 10:12:50 +0100
Subject: [PATCH 3/4] iio: adc: xilinx-ams: Fixed wrong sequencer register
 settings
In-Reply-To: <4c5fb3899a8aafa34106a668bcb2807b6f073036.camel@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-4-robert.hancock@calian.com>
 <20220125082108.GE25856@pengutronix.de>
 <4c5fb3899a8aafa34106a668bcb2807b6f073036.camel@calian.com>
Message-ID: <20220126091250.GC2550@pengutronix.de>

On Tue, 25 Jan 2022 16:15:05 +0000, Robert Hancock wrote:
> On Tue, 2022-01-25 at 09:21 +0100, Michael Tretter wrote:
> > On Wed, 19 Jan 2022 19:02:45 -0600, Robert Hancock wrote:
> > > Register settings used for the sequencer configuration register
> > > were incorrect, causing some inputs to not be read properly.
> > > 
> > > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > > ---
> > >  drivers/iio/adc/xilinx-ams.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > > index b93864362dac..199027c93cdc 100644
> > > --- a/drivers/iio/adc/xilinx-ams.c
> > > +++ b/drivers/iio/adc/xilinx-ams.c
> > > @@ -91,8 +91,8 @@
> > >  
> > >  #define AMS_CONF1_SEQ_MASK		GENMASK(15, 12)
> > >  #define AMS_CONF1_SEQ_DEFAULT		FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > 0)
> > > -#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 1)
> > > -#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > 2)
> > > +#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
> > > +#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > 3)
> > 
> > The TRM states that Continuous Loop Mode is 2, but Single Pass Sequence Mode
> > is 1, not 3. Is there a reason, why you need to set both bits?
> 
> Single pass sequence mode (1) just runs the same sequence only once. To read
> these values it needs to switch to single channel mode (3).
> 
> The register bits are defined in Table 3-8 of 
> https://www.xilinx.com/support/documentation/user_guides/ug580-ultrascale-sysmon.pdf
>  .

Thanks for the clarification.

Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

> 
> > 
> > Michael
> > 
> > >  
> > >  #define AMS_REG_SEQ0_MASK		GENMASK(15, 0)
> > >  #define AMS_REG_SEQ2_MASK		GENMASK(21, 16)
> > > -- 
> > > 2.31.1
> > > 
> > > 
> > > _______________________________________________
> > > linux-arm-kernel mailing list
> > > linux-arm-kernel at lists.infradead.org
> > > https://urldefense.com/v3/__http://lists.infradead.org/mailman/listinfo/linux-arm-kernel__;!!IOGos0k!yGFEjSC1BL20lwurby914len0HCLXyzarwxKJP9Jx30qv_qrERSkRJUiVo_2MdusMVA$ 
> > > 
> -- 
> Robert Hancock
> Senior Hardware Designer, Calian Advanced Technologies
> www.calian.com


From s.nawrocki at samsung.com  Wed Jan 26 01:13:10 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:13:10 +0100
Subject: [PATCH v5 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <20220124141644.71052-4-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142905epcas5p33a863799819fb904932d2e88c682940a@epcas5p3.samsung.com>
 <20220124141644.71052-4-alim.akhtar@samsung.com>
Message-ID: <a611a070-4932-1691-1f20-7cfa8bb96cc1@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Add dt-schema documentation for Tesla FSD SoC clock controller.
> 
> Cc: linux-fsd at tesla.com
> Acked-by: Stephen Boyd <sboyd at kernel.org>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>


From s.nawrocki at samsung.com  Wed Jan 26 01:14:58 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:14:58 +0100
Subject: [PATCH v5 04/16] clk: samsung: fsd: Add initial clock support
In-Reply-To: <20220124141644.71052-5-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142911epcas5p2e68f16158121a34e42e1763354ba8a4f@epcas5p2.samsung.com>
 <20220124141644.71052-5-alim.akhtar@samsung.com>
Message-ID: <6457f0c3-4f2a-a784-aadf-b3cbe563db74@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Add initial clock support for FSD (Full Self-Driving) SoC
> which is required to bring-up platforms based on this SoC.
> 
> Also, fix the build error reported by the kernel test robot [1]. 
 
> Cc: linux-fsd at tesla.com
> Reported-by: kernel test robot <lkp at intel.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From s.nawrocki at samsung.com  Wed Jan 26 01:15:31 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:15:31 +0100
Subject: [PATCH v5 05/16] clk: samsung: fsd: Add cmu_peric block clock
 information
In-Reply-To: <20220124141644.71052-6-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142915epcas5p2c112efe9f08ffa2a53122f4e2b8042e1@epcas5p2.samsung.com>
 <20220124141644.71052-6-alim.akhtar@samsung.com>
Message-ID: <c5e523c9-b9e6-c90d-0e94-8410948e43a1@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Add CMU_PERIC block clock information needed for various IPs
> functions found in this block.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Niyas Ahmed S T <niyas.ahmed at samsung.com>
> Signed-off-by: Chandrasekar R <rcsekar at samsung.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Sriranjani P <sriranjani.p at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From s.nawrocki at samsung.com  Wed Jan 26 01:15:57 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:15:57 +0100
Subject: [PATCH v5 06/16] clk: samsung: fsd: Add cmu_fsys0 clock
 information
In-Reply-To: <20220124141644.71052-7-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142919epcas5p3232941c11ef3c5ac8de2ca89b21131e2@epcas5p3.samsung.com>
 <20220124141644.71052-7-alim.akhtar@samsung.com>
Message-ID: <e2893572-66d2-a7e5-e9e3-7feec8738881@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> CMU_FSYS0 block has IPs like UFS, EQOS, PCIe etc, lets add
> the related clock information for the same.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Shradha Todi <shradha.t at samsung.com>
> Signed-off-by: Jayati Sahu <jayati.sahu at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From s.nawrocki at samsung.com  Wed Jan 26 01:17:13 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:17:13 +0100
Subject: [PATCH v5 07/16] clk: samsung: fsd: Add cmu_fsys1 clock
 information
In-Reply-To: <20220124141644.71052-8-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142923epcas5p17cffd89f734eda4c7e9515ac4ec79fb5@epcas5p1.samsung.com>
 <20220124141644.71052-8-alim.akhtar@samsung.com>
Message-ID: <9208c599-ee3b-a6b6-6d71-3ed48fe9a4b8@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Adds cmu_fsys1 block clock information which are needed
> for PCIe IPs in block FSYS1.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Ajay Kumar <ajaykumar.rs at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>


From s.nawrocki at samsung.com  Wed Jan 26 01:17:40 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:17:40 +0100
Subject: [PATCH v5 08/16] clk: samsung: fsd: Add cmu_imem block clock
 information
In-Reply-To: <20220124141644.71052-9-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142928epcas5p4cb956c77eac815ff4347e8e3b09bfb54@epcas5p4.samsung.com>
 <20220124141644.71052-9-alim.akhtar@samsung.com>
Message-ID: <00f99dbb-c425-c838-f1ec-ff2e98f42eef@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Adds cmu_imem clock related code, imem block contains IPs
> like WDT, DMA, TMU etc, these clocks are required for such
> IP function.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Arjun K V <arjun.kv at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Tauseef Nomani <tauseef.n at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From s.nawrocki at samsung.com  Wed Jan 26 01:18:03 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:18:03 +0100
Subject: [PATCH v5 09/16] clk: samsung: fsd: Add cmu_mfc block clock
 information
In-Reply-To: <20220124141644.71052-10-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142933epcas5p4e69babee0d9ea6f94fef365d79329e20@epcas5p4.samsung.com>
 <20220124141644.71052-10-alim.akhtar@samsung.com>
Message-ID: <844bcb9b-daed-7cf6-d6f5-ff5ad2726284@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Adds cmu_mfc clock related code, these clocks are
> required for MFC IP.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Smitha T Murthy <smitha.t at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>



From s.nawrocki at samsung.com  Wed Jan 26 01:18:36 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:18:36 +0100
Subject: [PATCH v5 10/16] clk: samsung: fsd: Add cam_csi block clock
 information
In-Reply-To: <20220124141644.71052-11-alim.akhtar@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142937epcas5p3bdce50bbaa02bbd762cf000401e03ade@epcas5p3.samsung.com>
 <20220124141644.71052-11-alim.akhtar@samsung.com>
Message-ID: <6844bdae-9823-cfc3-4acb-d547c559ae15@samsung.com>

On 24.01.2022 15:16, Alim Akhtar wrote:
> Adds clocks for BLK_CAM_CSI block, this is needed for CSI to work.
> 
> Cc: linux-fsd at tesla.com
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Sathyakam M <sathya at samsung.com>
> Signed-off-by: Pankaj Dubey <pankaj.dubey at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>

Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>


From jbrunet at baylibre.com  Wed Jan 26 01:14:55 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Wed, 26 Jan 2022 10:14:55 +0100
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
 <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
Message-ID: <1jy23226sa.fsf@starbuckisacylon.baylibre.com>


On Wed 26 Jan 2022 at 17:08, Liang Yang <liang.yang at amlogic.com> wrote:

> Hi Neil,
>
> On 2022/1/25 22:54, Neil Armstrong wrote:
>> [ EXTERNAL EMAIL ]
>> Hi Liang,
>> On 21/01/2022 08:45, Liang Yang wrote:
>>> This driver will add a MMC clock controller driver support.
>>> The original idea about adding a clock controller is during the
>>> discussion in the NAND driver mainline effort[1].
>>>
>>> This driver is tested in the S400 board (AXG platform) with NAND driver.
>> Thanks a lot for providing a fixed and updated version of this serie.
>> After some chat with Jerome and Kevin, it seems the way the eMMC clock
>> reuse
>> for NAND was designed nearly 4 years doesn't look accurate anymore.
>> Having a separate clk driver designed to replace the eMMC node when NAND
>> is
>> used on the board seems over engineered.
>> Actually having the clock code you add in this serie _but_ directly in
>> the NAND looks far better, and more coherent since having Linux runtime
>> detection of eMMC vs NAND will never happen and even this serie required
>> some DT modification from the bootloader.
>> I'll let Jerome or Kevin add more details if they want, but I think you
>> should resurrect
>> the work you pushed in [1] & [2] but:
>> - passing the eMMC clk registers as a third "reg" cell
> Does it just need to define a 'reg' resource in NFC node and not 'syscon'
> here?

Yes

>> - passing the same "clocks" phandle as the eMMC node
>> - adding the eMMC clock code in the NAND driver directly
>> I'm open to discussions if you consider the current approach is still
>> superior.
>
> I don't have persuasive ideas, but really it shares the common clock
> implementation for both NFC and EMMC. and we don't need to paste the 
> same code in NFC and EMMC.

You don't need to copy everything. If I understood correctly, all the
Rx/Tx should not be needed. Yes, there is some duplication as it stands but
it allows to avoid coupling the MMC and NAND driver. We can still think
about optimizing things later on. Let's get something simply working
first.

>
>> Thanks,
>> Neil
>> [1]
>> https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
>> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
>> 
>>>
>>> Changes since v9 [10]
>>>   - use clk_parent_data instead of parent_names
>>>
>>> Changes since v8 [9]
>>>   - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>>   - use struct_size to caculate onecell_data
>>>   - add clk-phase-delay.h
>>>   - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>>
>>> Changes since v7 [8]
>>>   - move meson_clk_get_phase_delay_data() from header to driver
>>>   - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>>   - remove onecell date and ID for internal MUX clk
>>>   - use helper for functions for ONE_BASED in sclk-div
>>>   - add ONE_BASED support for duty cycle
>>>
>>> Changes since v6 [7]:
>>>   - add one based support for sclk divier
>>>   - alloc sclk in probe for multiple instance
>>>   - fix coding styles
>>>
>>> Changes since v5 [6]:
>>>   - remove divider ops with .init and use sclk_div instead
>>>   - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>>   - drop the useless type cast
>>>
>>> Changes since v4 [5]:
>>>   - use struct parm in phase delay driver
>>>   - remove 0 delay releted part in phase delay driver
>>>   - don't rebuild the parent name once again
>>>   - add divider ops with .init
>>>
>>> Changes since v3 [4]:
>>>   - separate clk-phase-delay driver
>>>   - replace clk_get_rate() with clk_hw_get_rate()
>>>   - collect Rob's R-Y
>>>   - drop 'meson-' prefix from compatible string
>>>
>>>   Changes since v2 [3]:
>>>   - squash dt-binding clock-id patch
>>>   - update license
>>>   - fix alignment
>>>   - construct a clk register helper() function
>>>
>>> Changes since v1 [2]:
>>>   - implement phase clock
>>>   - update compatible name
>>>   - adjust file name
>>>   - divider probe() into small functions, and re-use them
>>>
>>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>>> Liang Yang (4):
>>>    clk: meson: add one based divider support for sclk
>>>    clk: meson: add emmc sub clock phase delay driver
>>>    clk: meson: add DT documentation for emmc clock controller
>>>    clk: meson: add sub MMC clock controller driver
>>>
>>>   .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>>   drivers/clk/meson/Kconfig                     |  18 ++
>>>   drivers/clk/meson/Makefile                    |   2 +
>>>   drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>>   drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>>   drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>>   drivers/clk/meson/sclk-div.c                  |  59 ++--
>>>   drivers/clk/meson/sclk-div.h                  |   3 +
>>>   include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>>   9 files changed, 529 insertions(+), 22 deletions(-)
>>>   create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>   create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>>   create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>>   create mode 100644 drivers/clk/meson/mmc-clkc.c
>>>   create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>
>> .



From krzysztof.kozlowski at canonical.com  Wed Jan 26 01:19:36 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 10:19:36 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <063501d81281$10e5b3c0$32b11b40$@samsung.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
 <4cfcde38-50cb-646a-0d17-c2cb2977a2e4@canonical.com>
 <063501d81281$10e5b3c0$32b11b40$@samsung.com>
Message-ID: <4c029f92-ece7-78c1-e64b-cbe438b45a5f@canonical.com>

On 26/01/2022 07:50, Alim Akhtar wrote:
> Hi Krzysztof
> 
>> -----Original Message-----
>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>> Sent: Tuesday, January 25, 2022 10:56 PM
>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>> Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>> olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>> catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>> linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com;
>> sboyd at kernel.org
>> Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
>>
>> On 25/01/2022 18:12, Krzysztof Kozlowski wrote:
>>> On 24/01/2022 15:16, Alim Akhtar wrote:
>>>> Adds basic support for the Tesla Full Self-Driving (FSD) SoC. This
>>>> SoC contains three clusters of four Cortex-A72 CPUs, as well as
>>>> several IPs.
>>>>
>>>> Patches 1 to 9 provide support for the clock controller (which is
>>>> designed similarly to Exynos SoCs).
>>>>
>>>> The remaining changes provide pinmux support, initial device tree support.
>>>>
>>>> - Changes since v4
>>>> * fixed 'make dtbs_check' warnings on patch 14/16
>>>>
>>>> - Changes since v3
>>>> * Addressed Stefen's review comments on patch 14/16
>>>> * Fixed kernel test robot warning on patch 04/16
>>>> * rebsaed this series on Krzysztof's pinmux new binding schema work
>>>> [1]
>>>>
>>>> - Changes since v2
>>>> * Addressed Krzysztof's and Stephen's review comments
>>>> * Added Reviewed-by and Acked-by tags
>>>> * Rebased on next-20220120
>>>>
>>>> - Changes since v1
>>>> * fixed make dt_binding_check error as pointed by Rob
>>>> * Addressed Krzysztof's and Rob's review comments
>>>> * Added Reviewed-by and Acked-by tags
>>>> * Dropped SPI, MCT and ADC from this series (to be posted in small
>>>> sets)
>>>>
>>>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>>>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850 and
>>>> ExynosAutov9 wake-ups") [1]
>>>> https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git/l
>>>> og/?h=for-next
>>>>
>>>>
>>>
>>> Thanks, applied DTS/soc and pinctrl patches.
>>>
>>> I expect Sylwester will pick up the clock ones. Otherwise please let
>>> me know to pick it up as well.
>>
>> I forgot that clock macros are used in DTS. This does not compile and I cannot
>> take drivers into DTS branch.
>>
>> Alim,
>> DTS changes dropped. Please resend with the same trick we did for
>> Exynos850 board - hard-coded clock IDs as defines. See:
>>
>> https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/diff/arch/arm6
>> 4/boot/dts/exynos/exynos850.dtsi?h=samsung-dt64-5.17-
>> 2&id=e3493220fd3e474abcdcefbe14fb60485097ce06
>>
> Ok, I will resend patch 14 and 15 (DTS changes) only as suggested above.

I see Sylwester acked clock patches, so I will take them. No need to
resend, I'll organize the patches so they will compile.


Best regards,
Krzysztof


From liuchao173 at huawei.com  Wed Jan 26 01:18:53 2022
From: liuchao173 at huawei.com (Chao Liu)
Date: Wed, 26 Jan 2022 09:18:53 +0000
Subject: [PATCH] add cpu frequency to cpuinfo in arm64
Message-ID: <20220126091853.280826-1-liuchao173@huawei.com>

There is cpu frequency in /proc/cpuinfo in x86 but not in arm64

Signed-off-by: Chao Liu <liuchao173 at huawei.com>
---
 arch/arm64/kernel/cpuinfo.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..a5af899bebc9 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
+#include <linux/cpufreq.h>
 
 /*
  * In case the boot CPU is hotpluggable, we record its initial state and
@@ -144,6 +145,7 @@ static int c_show(struct seq_file *m, void *v)
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
 		u32 midr = cpuinfo->reg_midr;
+		unsigned int freq = cpufreq_quick_get(i);
 
 		/*
 		 * glibc reads /proc/cpuinfo to determine the number of
@@ -159,6 +161,11 @@ static int c_show(struct seq_file *m, void *v)
 			   loops_per_jiffy / (500000UL/HZ),
 			   loops_per_jiffy / (5000UL/HZ) % 100);
 
+
+		if (cpu_freq)
+			seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
+				   freq / 1000, (freq % 1000));
+
 		/*
 		 * Dump out the common processor features in a single line.
 		 * Userspace should read the hwcaps with getauxval(AT_HWCAP)
-- 
2.23.0



From s.nawrocki at samsung.com  Wed Jan 26 01:21:33 2022
From: s.nawrocki at samsung.com (Sylwester Nawrocki)
Date: Wed, 26 Jan 2022 10:21:33 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <063601d81281$5492d620$fdb88260$@samsung.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
 <063601d81281$5492d620$fdb88260$@samsung.com>
Message-ID: <bccd3ad0-7862-ef3b-246c-71463baaca52@samsung.com>

Hi,

On 26.01.2022 07:52, Alim Akhtar wrote:
>>
>> Thanks, applied DTS/soc and pinctrl patches.
>>
> Thanks Krzysztof
> 
>> I expect Sylwester will pick up the clock ones. Otherwise please let me know
>> to pick it up as well.
>>
> Hi Sylwester, hope you will be taking clock changes, or let Krzysztof know otherwise.
> Thanks

Krzysztof, can you also take the clk patches through your tree?
If you prefer to avoid it I will create a topic branch with the
clk headers and DT bindings documentation.


-- 
Regards,
Sylwester


From tarumizu.kohei at fujitsu.com  Wed Jan 26 01:24:35 2022
From: tarumizu.kohei at fujitsu.com (tarumizu.kohei at fujitsu.com)
Date: Wed, 26 Jan 2022 09:24:35 +0000
Subject: [PATCH 0/8] Add hardware prefetch control driver for arm64 and x86
In-Reply-To: <931f6d2a-9001-e736-e7e2-7f86f87539cc@intel.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
 <931f6d2a-9001-e736-e7e2-7f86f87539cc@intel.com>
Message-ID: <OSBPR01MB203754574F2AC6281EFA1FDE80209@OSBPR01MB2037.jpnprd01.prod.outlook.com>

> Doesn't this break the one-value-per-file sysfs rules?

Sorry, I forgot the sysfs rules.

The current interface specification was decided referring to the
specification of /sys/class/rnbd-client/ctl/map_device. However,
I thought that the current specification of preftch_control was
inappropriate because it relevant to "Mixing types, expressing
multiple lines of data" in Documentation/filesystems/sysfs.rst.

The next version patch divides the attribute file by option, as
described below.

* Current version interface

```
/sys/devices/system/cpu/cpu0/cache/index0/
	prefetch_control (attribute file)
```

* Next version interface look like this

```
/sys/devices/system/cpu/cpu0/cache/index0/prefetch_control/
	hardware_prefetcher_enable (attribute file)
	ip_prefetcher_enable (attribute file)
```

From liuchao173 at huawei.com  Wed Jan 26 01:23:49 2022
From: liuchao173 at huawei.com (Chao Liu)
Date: Wed, 26 Jan 2022 09:23:49 +0000
Subject: [PATCH v2] add cpu frequency to cpuinfo in arm64
Message-ID: <20220126092349.285642-1-liuchao173@huawei.com>

There is cpu frequency in /proc/cpuinfo in x86 but not in arm64

Signed-off-by: Chao Liu <liuchao173 at huawei.com>
---
Change in v2:
- fix spelling errors and remove remove redundant blank line

 arch/arm64/kernel/cpuinfo.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..39a36e6e8079 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -24,6 +24,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
+#include <linux/cpufreq.h>
 
 /*
  * In case the boot CPU is hotpluggable, we record its initial state and
@@ -144,6 +145,7 @@ static int c_show(struct seq_file *m, void *v)
 	for_each_online_cpu(i) {
 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
 		u32 midr = cpuinfo->reg_midr;
+		unsigned int freq = cpufreq_quick_get(i);
 
 		/*
 		 * glibc reads /proc/cpuinfo to determine the number of
@@ -159,6 +161,10 @@ static int c_show(struct seq_file *m, void *v)
 			   loops_per_jiffy / (500000UL/HZ),
 			   loops_per_jiffy / (5000UL/HZ) % 100);
 
+		if (freq)
+			seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
+				   freq / 1000, (freq % 1000));
+
 		/*
 		 * Dump out the common processor features in a single line.
 		 * Userspace should read the hwcaps with getauxval(AT_HWCAP)
-- 
2.23.0



From leoyang.li at nxp.com  Wed Jan 26 01:26:50 2022
From: leoyang.li at nxp.com (Li Yang)
Date: Wed, 26 Jan 2022 03:26:50 -0600
Subject: [PATCH] arm64: dts: ls1028a-qds: define mdio slots for networking
 options
Message-ID: <20220126092650.19962-1-leoyang.li@nxp.com>

The ls1028a QDS board support different pluggable PHY cards.  Define the
nodes for these slots to be updated at boot time with overlay according
to board setup.

Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
Signed-off-by: Li Yang <leoyang.li at nxp.com>
---
 .../boot/dts/freescale/fsl-ls1028a-qds.dts    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 177bc1405f0f..19d3952dbffe 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -107,6 +107,30 @@ qds_phy1: ethernet-phy at 5 {
 				reg = <5>;
 			};
 		};
+
+		mdio_slot1: mdio at 4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		mdio_slot2: mdio at 5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		mdio_slot3: mdio at 6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		mdio_slot4: mdio at 7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
 	};
 };
 
-- 
2.25.1



From krzysztof.kozlowski at canonical.com  Wed Jan 26 01:32:10 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 10:32:10 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <bccd3ad0-7862-ef3b-246c-71463baaca52@samsung.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
 <063601d81281$5492d620$fdb88260$@samsung.com>
 <bccd3ad0-7862-ef3b-246c-71463baaca52@samsung.com>
Message-ID: <31da451b-a36c-74fb-5667-d4193284c6cd@canonical.com>

On 26/01/2022 10:21, Sylwester Nawrocki wrote:
> Hi,
> 
> On 26.01.2022 07:52, Alim Akhtar wrote:
>>>
>>> Thanks, applied DTS/soc and pinctrl patches.
>>>
>> Thanks Krzysztof
>>
>>> I expect Sylwester will pick up the clock ones. Otherwise please let me know
>>> to pick it up as well.
>>>
>> Hi Sylwester, hope you will be taking clock changes, or let Krzysztof know otherwise.
>> Thanks
> 
> Krzysztof, can you also take the clk patches through your tree?
> If you prefer to avoid it I will create a topic branch with the
> clk headers and DT bindings documentation.

No problem, I'll consume everything I encounter :)


Best regards,
Krzysztof


From shawnguo at kernel.org  Wed Jan 26 01:35:58 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 17:35:58 +0800
Subject: [PATCH] arm64: dts: imx8mn-venice-gw7902: disable gpu
In-Reply-To: <20211216161227.31960-1-tharvey@gateworks.com>
References: <20211216161227.31960-1-tharvey@gateworks.com>
Message-ID: <20220126093558.GL4686@dragon>

On Thu, Dec 16, 2021 at 08:12:27AM -0800, Tim Harvey wrote:
> Since commit 99aa29932271 ("arm64: dts: imx8mn: Enable GPU")
> imx8mn-venice-gw7902 will hang during kernel init because it uses
> a MIMX8MN5CVTI which does not have a GPU.

I do not quite follow on this.  i.MX8MN integrates a GPU, and
MIMX8MN5CVTI is built on i.MX8MN, correct?  If so, how comes
MIMX8MN5CVTI doesn't have a GPU?

> 
> Disable pgc_gpumix to work around this. We also disable the GPU devices
> that depend on the gpumix power domain and pgc_gpu to avoid them staying
> in a probe deferred state forever.

Is this an indication that GPU should be disabled in imx8mn.dtsi and
enabled board by board?

Shawn

> 
> Cc: Adam Ford <aford173 at gmail.com>
> Cc: Lucas Stach <l.stach at pengutronix.de>
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> ---
>  .../boot/dts/freescale/imx8mn-venice-gw7902.dts      | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> index 236f425e1570..2d58005d20e4 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> @@ -220,6 +220,10 @@
>  	};
>  };
>  
> +&disp_blk_ctrl {
> +	status = "disabled";
> +};
> +
>  /* off-board header */
>  &ecspi2 {
>  	pinctrl-names = "default";
> @@ -251,6 +255,10 @@
>  	};
>  };
>  
> +&gpu {
> +	status = "disabled";
> +};
> +
>  &i2c1 {
>  	clock-frequency = <100000>;
>  	pinctrl-names = "default";
> @@ -546,6 +554,10 @@
>  	status = "okay";
>  };
>  
> +&pgc_gpumix {
> +	status = "disabled";
> +};
> +
>  /* off-board header */
>  &sai3 {
>  	pinctrl-names = "default";
> -- 
> 2.17.1
> 


From daniel.lezcano at linaro.org  Wed Jan 26 01:36:32 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Jan 2022 10:36:32 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <20220125171809.1273269-6-daniel.lezcano@linaro.org>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
Message-ID: <f91ac11e-82bf-2803-bb22-1a4500f07468@linaro.org>


Hi Heiko,

do you have comments on this patch?


On 25/01/2022 18:18, Daniel Lezcano wrote:
> The DTPM framework does support now the hierarchy description.
> 
> The platform specific code can call the hierarchy creation function
> with an array of struct dtpm_node pointing to their parent.
> 
> This patch provides a description of the big / Little CPUs and the
> GPU and tie them together under a virtual 'package' name. Only rk3399 is
> described now.
> 
> The description could be extended in the future with the memory
> controller with devfreq.
> 
> The description is always a module and it describes the soft
> dependencies. The userspace has to load the softdeps module in the
> right order.
> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> ---
>  drivers/soc/rockchip/Kconfig  |  8 +++++
>  drivers/soc/rockchip/Makefile |  1 +
>  drivers/soc/rockchip/dtpm.c   | 59 +++++++++++++++++++++++++++++++++++
>  3 files changed, 68 insertions(+)
>  create mode 100644 drivers/soc/rockchip/dtpm.c
> 
> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
> index 25eb2c1e31bb..6dc017f02431 100644
> --- a/drivers/soc/rockchip/Kconfig
> +++ b/drivers/soc/rockchip/Kconfig
> @@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS
>  
>            If unsure, say N.
>  
> +config ROCKCHIP_DTPM
> +	tristate "Rockchip DTPM hierarchy"
> +	depends on DTPM && DRM_PANFROST && m
> +	help
> +	 Describe the hierarchy for the Dynamic Thermal Power
> +	 Management tree on this platform. That will create all the
> +	 power capping capable devices.
> +
>  endif
> diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
> index 875032f7344e..05f31a4e743c 100644
> --- a/drivers/soc/rockchip/Makefile
> +++ b/drivers/soc/rockchip/Makefile
> @@ -5,3 +5,4 @@
>  obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
>  obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
>  obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
> +obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
> diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
> new file mode 100644
> index 000000000000..0b73a9cba954
> --- /dev/null
> +++ b/drivers/soc/rockchip/dtpm.c
> @@ -0,0 +1,59 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2021 Linaro Limited
> + *
> + * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
> + *
> + * DTPM hierarchy description
> + */
> +#include <linux/dtpm.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +static struct dtpm_node __initdata rk3399_hierarchy[] = {
> +	[0]{ .name = "rk3399",
> +	     .type = DTPM_NODE_VIRTUAL },
> +	[1]{ .name = "package",
> +	     .type = DTPM_NODE_VIRTUAL,
> +	     .parent = &rk3399_hierarchy[0] },
> +	[2]{ .name = "/cpus/cpu at 0",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[3]{ .name = "/cpus/cpu at 1",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[4]{ .name = "/cpus/cpu at 2",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[5]{ .name = "/cpus/cpu at 3",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[6]{ .name = "/cpus/cpu at 100",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[7]{ .name = "/cpus/cpu at 101",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[8]{ .name = "/gpu at ff9a0000",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[9]{ },
> +};
> +
> +static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
> +        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
> +        {},
> +};
> +
> +static int __init rockchip_dtpm_init(void)
> +{
> +	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
> +}
> +module_init(rockchip_dtpm_init);
> +
> +MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
> +MODULE_DESCRIPTION("Rockchip DTPM driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dtpm");
> +MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano at kernel.org");
> 


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From geert at linux-m68k.org  Wed Jan 26 01:40:37 2022
From: geert at linux-m68k.org (Geert Uytterhoeven)
Date: Wed, 26 Jan 2022 10:40:37 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <20220125171809.1273269-6-daniel.lezcano@linaro.org>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
Message-ID: <CAMuHMdXZEYNjFh2T4beWdfn8av_qXaPbg4yFk=9whESnLBaFAQ@mail.gmail.com>

Hi Daniel,

On Tue, Jan 25, 2022 at 6:18 PM Daniel Lezcano
<daniel.lezcano at linaro.org> wrote:
> The DTPM framework does support now the hierarchy description.
>
> The platform specific code can call the hierarchy creation function
> with an array of struct dtpm_node pointing to their parent.
>
> This patch provides a description of the big / Little CPUs and the
> GPU and tie them together under a virtual 'package' name. Only rk3399 is
> described now.
>
> The description could be extended in the future with the memory
> controller with devfreq.
>
> The description is always a module and it describes the soft
> dependencies. The userspace has to load the softdeps module in the
> right order.
>
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>

Thanks for your patch!

> ---

Can you please insert a changelog here, especially if you don't CC all
parties on the cover letter?
Yes, I can get it from lore, but it's easier for the audience if it's included
here.

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds


From liang.yang at amlogic.com  Wed Jan 26 01:42:17 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Wed, 26 Jan 2022 17:42:17 +0800
Subject: [PATCH v10 0/4] clk: meson: add a sub EMMC clock controller
 support
In-Reply-To: <1jy23226sa.fsf@starbuckisacylon.baylibre.com>
References: <20220121074508.42168-1-liang.yang@amlogic.com>
 <f5a429f2-ffbc-ea03-810a-45a0f90959a2@baylibre.com>
 <6eb4f247-367b-d460-6314-fc94ccd00b89@amlogic.com>
 <1jy23226sa.fsf@starbuckisacylon.baylibre.com>
Message-ID: <27bf78f7-23b9-d759-28eb-0594006a30c6@amlogic.com>

Hi Jerome,

On 2022/1/26 17:14, Jerome Brunet wrote:
> [ EXTERNAL EMAIL ]
> 
> 
> On Wed 26 Jan 2022 at 17:08, Liang Yang <liang.yang at amlogic.com> wrote:
> 
>> Hi Neil,
>>
>> On 2022/1/25 22:54, Neil Armstrong wrote:
>>> [ EXTERNAL EMAIL ]
>>> Hi Liang,
>>> On 21/01/2022 08:45, Liang Yang wrote:
>>>> This driver will add a MMC clock controller driver support.
>>>> The original idea about adding a clock controller is during the
>>>> discussion in the NAND driver mainline effort[1].
>>>>
>>>> This driver is tested in the S400 board (AXG platform) with NAND driver.
>>> Thanks a lot for providing a fixed and updated version of this serie.
>>> After some chat with Jerome and Kevin, it seems the way the eMMC clock
>>> reuse
>>> for NAND was designed nearly 4 years doesn't look accurate anymore.
>>> Having a separate clk driver designed to replace the eMMC node when NAND
>>> is
>>> used on the board seems over engineered.
>>> Actually having the clock code you add in this serie _but_ directly in
>>> the NAND looks far better, and more coherent since having Linux runtime
>>> detection of eMMC vs NAND will never happen and even this serie required
>>> some DT modification from the bootloader.
>>> I'll let Jerome or Kevin add more details if they want, but I think you
>>> should resurrect
>>> the work you pushed in [1] & [2] but:
>>> - passing the eMMC clk registers as a third "reg" cell
>> Does it just need to define a 'reg' resource in NFC node and not 'syscon'
>> here?
> 
> Yes
> 
>>> - passing the same "clocks" phandle as the eMMC node
>>> - adding the eMMC clock code in the NAND driver directly
>>> I'm open to discussions if you consider the current approach is still
>>> superior.
>>
>> I don't have persuasive ideas, but really it shares the common clock
>> implementation for both NFC and EMMC. and we don't need to paste the
>> same code in NFC and EMMC.
> 
> You don't need to copy everything. If I understood correctly, all the
> Rx/Tx should not be needed. Yes, there is some duplication as it stands but
> it allows to avoid coupling the MMC and NAND driver. We can still think
> about optimizing things later on. Let's get something simply working
> first.
ok. i will do it. thank you.
> 
>>
>>> Thanks,
>>> Neil
>>> [1]
>>> https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
>>> [2] https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
>>>
>>>>
>>>> Changes since v9 [10]
>>>>    - use clk_parent_data instead of parent_names
>>>>
>>>> Changes since v8 [9]
>>>>    - use MESON_SCLK_ONE_BASED instead of CLK_DIVIDER_ONE_BASED
>>>>    - use struct_size to caculate onecell_data
>>>>    - add clk-phase-delay.h
>>>>    - define CLK_DELAY_STEP_PS_GX and CLK_DELAY_STEP_PS_AXG
>>>>
>>>> Changes since v7 [8]
>>>>    - move meson_clk_get_phase_delay_data() from header to driver
>>>>    - CONFIG sclk-div with COMMON_CLK_AMLOGIC instead of COMMON_CLK_AMLOGIC_AUDIO
>>>>    - remove onecell date and ID for internal MUX clk
>>>>    - use helper for functions for ONE_BASED in sclk-div
>>>>    - add ONE_BASED support for duty cycle
>>>>
>>>> Changes since v6 [7]:
>>>>    - add one based support for sclk divier
>>>>    - alloc sclk in probe for multiple instance
>>>>    - fix coding styles
>>>>
>>>> Changes since v5 [6]:
>>>>    - remove divider ops with .init and use sclk_div instead
>>>>    - drop CLK_DIVIDER_ROUND_CLOSEST in mux and div
>>>>    - drop the useless type cast
>>>>
>>>> Changes since v4 [5]:
>>>>    - use struct parm in phase delay driver
>>>>    - remove 0 delay releted part in phase delay driver
>>>>    - don't rebuild the parent name once again
>>>>    - add divider ops with .init
>>>>
>>>> Changes since v3 [4]:
>>>>    - separate clk-phase-delay driver
>>>>    - replace clk_get_rate() with clk_hw_get_rate()
>>>>    - collect Rob's R-Y
>>>>    - drop 'meson-' prefix from compatible string
>>>>
>>>>    Changes since v2 [3]:
>>>>    - squash dt-binding clock-id patch
>>>>    - update license
>>>>    - fix alignment
>>>>    - construct a clk register helper() function
>>>>
>>>> Changes since v1 [2]:
>>>>    - implement phase clock
>>>>    - update compatible name
>>>>    - adjust file name
>>>>    - divider probe() into small functions, and re-use them
>>>>
>>>> [1] https://lkml.kernel.org/r/20180628090034.0637a062 at xps13
>>>> [2] https://lkml.kernel.org/r/20180703145716.31860-1-yixun.lan at amlogic.com
>>>> [3] https://lkml.kernel.org/r/20180710163658.6175-1-yixun.lan at amlogic.com
>>>> [4] https://lkml.kernel.org/r/20180712211244.11428-1-yixun.lan at amlogic.com
>>>> [5] https://lkml.kernel.org/r/20180809070724.11935-4-yixun.lan at amlogic.com
>>>> [6] https://lkml.kernel.org/r/1539839245-13793-1-git-send-email-jianxin.pan at amlogic.com
>>>> [7] https://lkml.kernel.org/r/1541089855-19356-1-git-send-email-jianxin.pan at amlogic.com
>>>> [8] https://lkml.kernel.org/r/1544457877-51301-1-git-send-email-jianxin.pan at amlogic.com
>>>> [9] https://lkml.kernel.org/r/1545063850-21504-1-git-send-email-jianxin.pan at amlogic.com
>>>> [10] https://lore.kernel.org/all/20220113115745.45826-1-liang.yang at amlogic.com/
>>>> Liang Yang (4):
>>>>     clk: meson: add one based divider support for sclk
>>>>     clk: meson: add emmc sub clock phase delay driver
>>>>     clk: meson: add DT documentation for emmc clock controller
>>>>     clk: meson: add sub MMC clock controller driver
>>>>
>>>>    .../bindings/clock/amlogic,mmc-clkc.yaml      |  64 ++++
>>>>    drivers/clk/meson/Kconfig                     |  18 ++
>>>>    drivers/clk/meson/Makefile                    |   2 +
>>>>    drivers/clk/meson/clk-phase-delay.c           |  69 ++++
>>>>    drivers/clk/meson/clk-phase-delay.h           |  20 ++
>>>>    drivers/clk/meson/mmc-clkc.c                  | 302 ++++++++++++++++++
>>>>    drivers/clk/meson/sclk-div.c                  |  59 ++--
>>>>    drivers/clk/meson/sclk-div.h                  |   3 +
>>>>    include/dt-bindings/clock/amlogic,mmc-clkc.h  |  14 +
>>>>    9 files changed, 529 insertions(+), 22 deletions(-)
>>>>    create mode 100644 Documentation/devicetree/bindings/clock/amlogic,mmc-clkc.yaml
>>>>    create mode 100644 drivers/clk/meson/clk-phase-delay.c
>>>>    create mode 100644 drivers/clk/meson/clk-phase-delay.h
>>>>    create mode 100644 drivers/clk/meson/mmc-clkc.c
>>>>    create mode 100644 include/dt-bindings/clock/amlogic,mmc-clkc.h
>>>>
>>> .
> 
> .


From jason-jh.lin at mediatek.com  Wed Jan 26 01:33:40 2022
From: jason-jh.lin at mediatek.com (jason-jh.lin)
Date: Wed, 26 Jan 2022 17:33:40 +0800
Subject: [PATCH] arm64: dts: mt8195: add display node for vdosys0
Message-ID: <20220126093340.18792-1-jason-jh.lin@mediatek.com>

Add display node for vdosys0.

Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
---
This patch depends on series [1]
[1] Add Mediatek Soc DRM (vdosys0) support for mt8195
- https://patchwork.kernel.org/project/linux-mediatek/list/?series=608548

This patch is based on [2][3][4]
[2] arm64: dts: Add mediatek SoC mt8195 and evaluation board
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen at mediatek.com/
[3] arm64: dts: mt8195: add IOMMU and smi nodes
- https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
[4] arm64: dts: mt8195: add gce node
- https://patchwork.kernel.org/project/linux-mediatek/patch/20220126090109.32143-1-jason-jh.lin at mediatek.com/
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 123 +++++++++++++++++++++++
 1 file changed, 123 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index d778ca598d18..cc3a9e898c77 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -1067,5 +1067,128 @@
 			reg = <0 0x1b000000 0 0x1000>;
 			#clock-cells = <1>;
 		};
+
+		ovl0: disp_ovl at 1c000000 {
+			compatible = "mediatek,mt8195-disp-ovl",
+				     "mediatek,mt8192-disp-ovl";
+			reg = <0 0x1c000000 0 0x1000>;
+			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x0000 0x1000>;
+		};
+
+		rdma0: disp_rdma at 1c002000 {
+			compatible = "mediatek,mt8195-disp-rdma";
+			reg = <0 0x1c002000 0 0x1000>;
+			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
+			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x2000 0x1000>;
+		};
+
+		color0: disp_color at 1c003000 {
+			compatible = "mediatek,mt8195-disp-color",
+				     "mediatek,mt8173-disp-color";
+			reg = <0 0x1c003000 0 0x1000>;
+			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x3000 0x1000>;
+		};
+
+		ccorr0: disp_ccorr at 1c004000 {
+			compatible = "mediatek,mt8195-disp-ccorr",
+				     "mediatek,mt8192-disp-ccorr";
+			reg = <0 0x1c004000 0 0x1000>;
+			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x4000 0x1000>;
+		};
+
+		aal0: disp_aal at 1c005000 {
+			compatible = "mediatek,mt8195-disp-aal",
+				     "mediatek,mt8173-disp-aal";
+			reg = <0 0x1c005000 0 0x1000>;
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x5000 0x1000>;
+		};
+
+		gamma0: disp_gamma at 1c006000 {
+			compatible = "mediatek,mt8195-disp-gamma",
+				     "mediatek,mt8173-disp-gamma";
+			reg = <0 0x1c006000 0 0x1000>;
+			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x6000 0x1000>;
+		};
+
+		dither0: disp_dither at 1c007000 {
+			compatible = "mediatek,mt8195-disp-dither",
+				     "mediatek,mt8183-disp-dither";
+			reg = <0 0x1c007000 0 0x1000>;
+			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x7000 0x1000>;
+		};
+
+		dsc0: disp_dsc_wrap at 1c009000 {
+			compatible = "mediatek,mt8195-disp-dsc";
+			reg = <0 0x1c009000 0 0x1000>;
+			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c00XXXX 0x9000 0x1000>;
+		};
+
+		merge0: disp_vpp_merge0 at 1c014000 {
+			compatible = "mediatek,mt8195-disp-merge";
+			reg = <0 0x1c014000 0 0x1000>;
+			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
+			mediatek,gce-client-reg =
+				 <&gce0 SUBSYS_1c01XXXX 0x4000 0x1000>;
+		};
+
+		mutex: disp_mutex0 at 1c016000 {
+			compatible = "mediatek,mt8195-disp-mutex";
+			reg = <0 0x1c016000 0 0x1000>;
+			reg-names = "vdo0_mutex";
+			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
+			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
+			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			clock-names = "vdo0_mutex";
+			mediatek,gce-events =
+				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
+		};
+
+		vdosys0: syscon at 1c01a000 {
+			compatible = "mediatek,mt8195-vdosys0", "syscon";
+			reg = <0 0x1c01a000 0 0x1000>;
+			mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
+			#clock-cells = <1>;
+		};
+
+		vdosys1: syscon at 1c100000 {
+			compatible = "mediatek,mt8195-vdosys1", "syscon";
+			reg = <0 0x1c100000 0 0x1000>;
+			#clock-cells = <1>;
+		};
 	};
 };
-- 
2.18.0



From mohammad.athari.ismail at intel.com  Wed Jan 26 01:47:21 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Wed, 26 Jan 2022 17:47:21 +0800
Subject: [PATCH net 0/2] Fix PTP issue in stmmac
Message-ID: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>

This patch series to fix PTP issue in stmmac related to:
1/ PTP clock source configuration during initialization.
2/ PTP initialization during resume from suspend.

Mohammad Athari Bin Ismail (2):
  net: stmmac: configure PTP clock source prior to PTP initialization
  net: stmmac: skip only stmmac_ptp_register when resume from suspend

 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 23 ++++++++++---------
 .../net/ethernet/stmicro/stmmac/stmmac_ptp.c  |  3 ---
 2 files changed, 12 insertions(+), 14 deletions(-)

-- 
2.17.1



From mohammad.athari.ismail at intel.com  Wed Jan 26 01:47:22 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Wed, 26 Jan 2022 17:47:22 +0800
Subject: [PATCH net 1/2] net: stmmac: configure PTP clock source prior to PTP
 initialization
In-Reply-To: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
References: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220126094723.11849-2-mohammad.athari.ismail@intel.com>

For Intel platform, it is required to configure PTP clock source prior PTP
initialization in MAC. So, need to move ptp_clk_freq_config execution from
stmmac_ptp_register() to stmmac_init_ptp().

Fixes: 76da35dc99af ("stmmac: intel: Add PSE and PCH PTP clock source selection")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 +++
 drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 3 ---
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..d7e261768f73 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -889,6 +889,9 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	bool xmac = priv->plat->has_gmac4 || priv->plat->has_xgmac;
 	int ret;
 
+	if (priv->plat->ptp_clk_freq_config)
+		priv->plat->ptp_clk_freq_config(priv);
+
 	ret = stmmac_init_tstamp_counter(priv, STMMAC_HWTS_ACTIVE);
 	if (ret)
 		return ret;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 0d24ebd37873..1c9f02f9c317 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -297,9 +297,6 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
 {
 	int i;
 
-	if (priv->plat->ptp_clk_freq_config)
-		priv->plat->ptp_clk_freq_config(priv);
-
 	for (i = 0; i < priv->dma_cap.pps_out_num; i++) {
 		if (i >= STMMAC_PPS_MAX)
 			break;
-- 
2.17.1



From mohammad.athari.ismail at intel.com  Wed Jan 26 01:47:23 2022
From: mohammad.athari.ismail at intel.com (Mohammad Athari Bin Ismail)
Date: Wed, 26 Jan 2022 17:47:23 +0800
Subject: [PATCH net v3 2/2] net: stmmac: skip only stmmac_ptp_register when
 resume from suspend
In-Reply-To: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
References: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
Message-ID: <20220126094723.11849-3-mohammad.athari.ismail@intel.com>

When resume from suspend, besides skipping PTP registration, it also
skipping PTP HW initialization. This could cause PTP clock not able to
operate properly when resume from suspend.

To fix this, only stmmac_ptp_register() is skipped when resume from
suspend.

Fixes: fe1319291150 ("stmmac: Don't init ptp again when resume from suspend/hibernation")
Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: Mohammad Athari Bin Ismail <mohammad.athari.ismail at intel.com>
---
v3 changelog:
- Move the stmmac_ptp_register() call out to stmmac_hw_setup().
Commented by Jakub Kicinski <kuba at kernel.org>.

v2 changelog:
- Fix build warning related to "function parameter or member not described".
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 +++++++++----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d7e261768f73..dfda1cbf81ae 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -914,8 +914,6 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 	priv->hwts_tx_en = 0;
 	priv->hwts_rx_en = 0;
 
-	stmmac_ptp_register(priv);
-
 	return 0;
 }
 
@@ -3241,7 +3239,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
 /**
  * stmmac_hw_setup - setup mac in a usable state.
  *  @dev : pointer to the device structure.
- *  @init_ptp: initialize PTP if set
+ *  @ptp_register: register PTP if set
  *  Description:
  *  this is the main function to setup the HW in a usable state because the
  *  dma engine is reset, the core registers are configured (e.g. AXI,
@@ -3251,7 +3249,7 @@ static int stmmac_fpe_start_wq(struct stmmac_priv *priv)
  *  0 on success and an appropriate (-)ve integer as defined in errno.h
  *  file on failure.
  */
-static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
+static int stmmac_hw_setup(struct net_device *dev, bool ptp_register)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	u32 rx_cnt = priv->plat->rx_queues_to_use;
@@ -3308,13 +3306,13 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
 
 	stmmac_mmc_setup(priv);
 
-	if (init_ptp) {
-		ret = stmmac_init_ptp(priv);
-		if (ret == -EOPNOTSUPP)
-			netdev_warn(priv->dev, "PTP not supported by HW\n");
-		else if (ret)
-			netdev_warn(priv->dev, "PTP init failed\n");
-	}
+	ret = stmmac_init_ptp(priv);
+	if (ret == -EOPNOTSUPP)
+		netdev_warn(priv->dev, "PTP not supported by HW\n");
+	else if (ret)
+		netdev_warn(priv->dev, "PTP init failed\n");
+	else if (ptp_register)
+		stmmac_ptp_register(priv);
 
 	priv->eee_tw_timer = STMMAC_DEFAULT_TWT_LS;
 
-- 
2.17.1



From linux at armlinux.org.uk  Wed Jan 26 01:55:05 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 09:55:05 +0000
Subject: [PATCH net-next 4/7] net: stmmac/xpcs: convert to pcs_validate()
In-Reply-To: <20220125105303.2025dfae@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
References: <YfAnkuhiMoeFcVnb@shell.armlinux.org.uk>
 <E1nCOs4-005LSp-HF@rmk-PC.armlinux.org.uk>
 <20220125105303.2025dfae@kicinski-fedora-PC1C0HJN.hsd1.ca.comcast.net>
Message-ID: <YfEaeaES8w7PmB0n@shell.armlinux.org.uk>

On Tue, Jan 25, 2022 at 10:53:03AM -0800, Jakub Kicinski wrote:
> On Tue, 25 Jan 2022 16:40:40 +0000 Russell King (Oracle) wrote:
> > stmmac explicitly calls the xpcs driver to validate the ethtool
> > linkmodes. This is no longer necessary as phylink now supports
> > validation through a PCS method. Convert both drivers to use this
> > new mechanism.
> > 
> > Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> Sign-offs got scrambled.

Grumble. Never used to happen when I used MicroEMACS, but seems to be a
regular occurence when using vim - because it's pretty much impossible
to see wrapped lines in vim, especially when they have the perfect
amount of white space at the end of the previous line.

> Transient warning from here to patch 6:
> 
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:943:22: warning: unused variable 'priv' [-Wunused-variable]
>         struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
>                             ^

Thanks, v2 will be on its way with both of the above fixed.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From daniel.lezcano at linaro.org  Wed Jan 26 01:58:00 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Jan 2022 10:58:00 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <CAMuHMdXZEYNjFh2T4beWdfn8av_qXaPbg4yFk=9whESnLBaFAQ@mail.gmail.com>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
 <CAMuHMdXZEYNjFh2T4beWdfn8av_qXaPbg4yFk=9whESnLBaFAQ@mail.gmail.com>
Message-ID: <31c6898b-e6f0-5118-119a-13e01e9fa507@linaro.org>

On 26/01/2022 10:40, Geert Uytterhoeven wrote:
> Hi Daniel,
> 
> On Tue, Jan 25, 2022 at 6:18 PM Daniel Lezcano
> <daniel.lezcano at linaro.org> wrote:
>> The DTPM framework does support now the hierarchy description.
>>
>> The platform specific code can call the hierarchy creation function
>> with an array of struct dtpm_node pointing to their parent.
>>
>> This patch provides a description of the big / Little CPUs and the
>> GPU and tie them together under a virtual 'package' name. Only rk3399 is
>> described now.
>>
>> The description could be extended in the future with the memory
>> controller with devfreq.
>>
>> The description is always a module and it describes the soft
>> dependencies. The userspace has to load the softdeps module in the
>> right order.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> 
> Thanks for your patch!
> 
>> ---
> 
> Can you please insert a changelog here, especially if you don't CC all
> parties on the cover letter?

Ah yes, will do in the future

> Yes, I can get it from lore, but it's easier for the audience if it's included
> here.

Changelog:
   V7:
   - No changes

   V6:
   - Made rk3399 always as a module and added module softdeps

   V5:
   - Module creation





-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From l.stach at pengutronix.de  Wed Jan 26 01:58:56 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Wed, 26 Jan 2022 10:58:56 +0100
Subject: [PATCH] arm64: dts: imx8mn-venice-gw7902: disable gpu
In-Reply-To: <20220126093558.GL4686@dragon>
References: <20211216161227.31960-1-tharvey@gateworks.com>
 <20220126093558.GL4686@dragon>
Message-ID: <d5a15039255d13cf4321bf1c18f49a9cdb666607.camel@pengutronix.de>

Am Mittwoch, dem 26.01.2022 um 17:35 +0800 schrieb Shawn Guo:
> On Thu, Dec 16, 2021 at 08:12:27AM -0800, Tim Harvey wrote:
> > Since commit 99aa29932271 ("arm64: dts: imx8mn: Enable GPU")
> > imx8mn-venice-gw7902 will hang during kernel init because it uses
> > a MIMX8MN5CVTI which does not have a GPU.
> 
> I do not quite follow on this.  i.MX8MN integrates a GPU, and
> MIMX8MN5CVTI is built on i.MX8MN, correct?  If so, how comes
> MIMX8MN5CVTI doesn't have a GPU?
> 
It's a fused-down variant of the i.MX8MN that has the GPU disabled by
fuses.

> > 
> > Disable pgc_gpumix to work around this. We also disable the GPU devices
> > that depend on the gpumix power domain and pgc_gpu to avoid them staying
> > in a probe deferred state forever.
> 
> Is this an indication that GPU should be disabled in imx8mn.dtsi and
> enabled board by board?
> 
There's a trade-off here: most boards will probably use the full
variants that include the GPU, so probably less boards will need to
disable the GPU, as done here, than boards that need to enable it when
the base DT disables the GPU.

Same story as with the i.MX6 where there are some SKUs that disable the
VPU by fuses: we enable it in the base DT and if you happen to build a
very low-cost board that uses the fused-down version you need to
disable it in the board DT.

Regards,
Lucas

> Shawn
> 
> > 
> > Cc: Adam Ford <aford173 at gmail.com>
> > Cc: Lucas Stach <l.stach at pengutronix.de>
> > Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> > ---
> >  .../boot/dts/freescale/imx8mn-venice-gw7902.dts      | 12 ++++++++++++
> >  1 file changed, 12 insertions(+)
> > 
> > diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> > index 236f425e1570..2d58005d20e4 100644
> > --- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> > +++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
> > @@ -220,6 +220,10 @@
> >  	};
> >  };
> >  
> > +&disp_blk_ctrl {
> > +	status = "disabled";
> > +};
> > +
> >  /* off-board header */
> >  &ecspi2 {
> >  	pinctrl-names = "default";
> > @@ -251,6 +255,10 @@
> >  	};
> >  };
> >  
> > +&gpu {
> > +	status = "disabled";
> > +};
> > +
> >  &i2c1 {
> >  	clock-frequency = <100000>;
> >  	pinctrl-names = "default";
> > @@ -546,6 +554,10 @@
> >  	status = "okay";
> >  };
> >  
> > +&pgc_gpumix {
> > +	status = "disabled";
> > +};
> > +
> >  /* off-board header */
> >  &sai3 {
> >  	pinctrl-names = "default";
> > -- 
> > 2.17.1
> > 




From krzysztof.kozlowski at canonical.com  Wed Jan 26 02:05:49 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 11:05:49 +0100
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD)
 SoC (clock parts)
In-Reply-To: <20220124141644.71052-1-alim.akhtar@samsung.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
Message-ID: <164319151879.214823.14786470465879458997.b4-ty@canonical.com>

On Mon, 24 Jan 2022 19:46:28 +0530, Alim Akhtar wrote:
> Adds basic support for the Tesla Full Self-Driving (FSD)
> SoC. This SoC contains three clusters of four Cortex-A72 CPUs,
> as well as several IPs.
> 
> Patches 1 to 9 provide support for the clock controller
> (which is designed similarly to Exynos SoCs).
> 
> [...]

Applied also clock parts, thanks!

[01/16] dt-bindings: add vendor prefix for Tesla
        commit: a5a93e9b9ab9b4f367a773b32bbe1687006d75b7
[02/16] dt-bindings: clock: Add bindings definitions for FSD CMU blocks
        commit: d6dc675377261472adda696da456b4ebcc5bb9d9
[03/16] dt-bindings: clock: Document FSD CMU bindings
        commit: ed68db7b7f2fd01e930fa3e6fbb75954dc25e41c
[04/16] clk: samsung: fsd: Add initial clock support
        commit: 4f346005aaed641042ca18171c4383a6a85f6a8b
[05/16] clk: samsung: fsd: Add cmu_peric block clock information
        commit: e3f3dc3810d3765128d28b241f4afb761d81678a
[06/16] clk: samsung: fsd: Add cmu_fsys0 clock information
        commit: a15e367b02543f96ae845baf7be4526080437305
[07/16] clk: samsung: fsd: Add cmu_fsys1 clock information
        commit: bfbce52e4649b9a2c7296a6296ffbdfc3b07de2e
[08/16] clk: samsung: fsd: Add cmu_imem block clock information
        commit: ca0fdfd131c7d33984d8feeda23a99e883ffb0cb
[09/16] clk: samsung: fsd: Add cmu_mfc block clock information
        commit: 75c50afaa0d9a3e8f96940451bed6d0ccc6a0a03
[10/16] clk: samsung: fsd: Add cam_csi block clock information
        commit: b826c3e4de1a44ad8e5536d86d5ef062a54ed2b2
[13/16] dt-bindings: arm: add Tesla FSD ARM SoC
        commit: d25c5eb511df3439cd91517bcbce4b274f8972b9
[14/16] arm64: dts: fsd: Add initial device tree support
        commit: 18b1db6a162c29695920fdf212ccb8d7d5c07e9a
[15/16] arm64: dts: fsd: Add initial pinctrl support
        commit: 684dac402f212d8ededbe7d97bc42a5e49533f40
[16/16] arm64: defconfig: Enable Tesla FSD SoC
        commit: 0d525a653b03a25190650f783026c8e655268b48

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Wed Jan 26 02:07:01 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 11:07:01 +0100
Subject: [PATCH v5 03/16] dt-bindings: clock: Document FSD CMU bindings
In-Reply-To: <a611a070-4932-1691-1f20-7cfa8bb96cc1@samsung.com>
References: <20220124141644.71052-1-alim.akhtar@samsung.com>
 <CGME20220124142905epcas5p33a863799819fb904932d2e88c682940a@epcas5p3.samsung.com>
 <20220124141644.71052-4-alim.akhtar@samsung.com>
 <a611a070-4932-1691-1f20-7cfa8bb96cc1@samsung.com>
Message-ID: <c1ad0ec0-74c2-08fa-ecb8-ea652cd96849@canonical.com>

On 26/01/2022 10:13, Sylwester Nawrocki wrote:
> On 24.01.2022 15:16, Alim Akhtar wrote:
>> Add dt-schema documentation for Tesla FSD SoC clock controller.
>>
>> Cc: linux-fsd at tesla.com
>> Acked-by: Stephen Boyd <sboyd at kernel.org>
>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> 
> Acked-by: Sylwester Nawrocki <s.nawrocki at samsung.com>

Thanks, applied with all other clock driver changes.

Sylwester,
They are on separate branch, so I could send you pull if needed for
conflict resolution. Just let me know.

Best regards,
Krzysztof


From sudeep.holla at arm.com  Wed Jan 26 02:08:31 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Jan 2022 10:08:31 +0000
Subject: [PATCH v2] add cpu frequency to cpuinfo in arm64
In-Reply-To: <20220126092349.285642-1-liuchao173@huawei.com>
References: <20220126092349.285642-1-liuchao173@huawei.com>
Message-ID: <20220126100831.vrjid6c6k5qafd6a@bogus>

On Wed, Jan 26, 2022 at 09:23:49AM +0000, Chao Liu wrote:
> There is cpu frequency in /proc/cpuinfo in x86 but not in arm64
>

This has been repeatedly rejected in the past for valid reasons. I
could find this link[1] quickly, but I am sure you can find a handful of
such attempts in the past.

-- 
Regards,
Sudeep

[1] https://patchwork.kernel.org/project/linux-arm-kernel/patch/1386924222-23169-1-git-send-email-vkale at apm.com/


From Jianyong.Wu at arm.com  Wed Jan 26 02:09:40 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Wed, 26 Jan 2022 10:09:40 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
Message-ID: <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi Ard,

> -----Original Message-----
> From: Ard Biesheuvel <ardb at kernel.org>
> Sent: Wednesday, January 26, 2022 4:37 PM
> To: Justin He <Justin.He at arm.com>
> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
> david at redhat.com; quic_qiancai at quicinc.com; linux-
> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> gshan at redhat.com; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
> >
> > Hi Catalin
> >
> > > -----Original Message-----
> > > From: Catalin Marinas <catalin.marinas at arm.com>
> > > Sent: Friday, January 7, 2022 6:43 PM
> > > To: Jianyong Wu <Jianyong.Wu at arm.com>
> > > Cc: will at kernel.org; Anshuman Khandual
> <Anshuman.Khandual at arm.com>;
> > > akpm at linux-foundation.org; david at redhat.com;
> > > quic_qiancai at quicinc.com; ardb at kernel.org;
> > > linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
> > > gshan at redhat.com; Justin He <Justin.He at arm.com>; nd <nd at arm.com>
> > > Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
> > > create pud mapping
> > >
> > > On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> > > > Hi Catalin,
> > > >
> > > > I roughly find the root cause.
> > > >  alloc_init_pud will be called at the very beginning of kernel
> > > > boot in
> > > create_mapping_noalloc where no memory allocator is initialized. But
> > > lockdep check may need allocate memory. So, kernel take exception
> > > when acquire lock.(I have not found the exact code that cause this
> > > issue) that's say we may not be able to use a lock so early.
> > > >
> > > > I come up with 2 methods to address it.
> > > > 1) skip dead lock check at the very beginning of kernel boot in
> > > > lockdep
> > > code.
> > > > 2) provided 2 two versions of __create_pgd_mapping, one with lock
> > > > in it and the other without. There may be no possible of race for
> > > > memory mapping at the very beginning time of kernel boot, thus we
> > > > can use the no lock version of __create_pgd_mapping safely.
> > > > In my test, this issue is gone if there is no lock held in
> > > > create_mapping_noalloc. I think create_mapping_noalloc is called
> > > > early enough to avoid the race conditions of memory mapping,
> > > > however, I have not proved it.
> > >
> > > I think method 2 would work better but rather than implementing new
> > > nolock functions I'd add a NO_LOCK flag and check it in
> > > alloc_init_pud() before mutex_lock/unlock. Also add a comment when
> > > passing the NO_LOCK flag on why it's needed and why there wouldn't
> > > be any races at that stage (early boot etc.)
> > >
> > The problematic code path is:
> > __primary_switched
> >         early_fdt_map->fixmap_remap_fdt
> >                 create_mapping_noalloc->alloc_init_pud
> >                         mutex_lock (with Jianyong's patch)
> >
> > The problem seems to be that we will clear BSS segment twice if kaslr
> > is enabled. Hence, some of the static variables in lockdep init
> > process were messed up. That is to said, with kaslr enabled we might
> > initialize lockdep twice if we add mutex_lock/unlock in alloc_init_pud().
> >
> 
> Thanks for tracking that down.
> 
> Note that clearing the BSS twice is not the root problem here. The root
> problem is that we set global state while the kernel runs at the default link
> time address, and then refer to it again after the entire kernel has been
> shifted in the kernel VA space. Such global state could consist of mutable
> pointers to statically allocated data (which would be reset to their default
> values after the relocation code runs again), or global pointer variables in BSS.
> In either case, relying on such a global variable after the second relocation
> performed by KASLR would be risky, and so we should avoid manipulating
> global state at all if it might involve pointer to statically allocated data
> structures.
> 
> > In other ways, if we invoke mutex_lock/unlock in such a early booting stage.
> > It might be unsafe because lockdep inserts lock_acquire/release as the
> > complex hooks.
> >
> > In summary, would it better if Jianyong splits these early boot and
> > late boot case? e.g. introduce a nolock version for
> create_mapping_noalloc().
> >
> > What do you think of it?
> >
> 
> The pre-KASLR case definitely doesn't need a lock. But given that
> create_mapping_noalloc() is only used to map the FDT, which happens very
> early one way or the other, wouldn't it be better to move the lock/unlock
> into other callers of __create_pgd_mapping()? (and make sure no other
> users of the fixmap slots exist)

There are server callers of __create_pgd_mapping. I think some of them need no fixmap lock as they are called so early. I figure out all of them here:
create_mapping_noalloc:   no lock
create_pgd_mapping:   no lock
__map_memblock:    no lock
map_kernel_segment:  no lock
map_entry_trampoline: no lock
update_mapping_prot:    need lock
arch_add_memory:  need lock

WDYT?

Thanks
Jianyong

From ardb at kernel.org  Wed Jan 26 02:12:27 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 11:12:27 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>

On Wed, 26 Jan 2022 at 11:09, Jianyong Wu <Jianyong.Wu at arm.com> wrote:
>
> Hi Ard,
>
> > -----Original Message-----
> > From: Ard Biesheuvel <ardb at kernel.org>
> > Sent: Wednesday, January 26, 2022 4:37 PM
> > To: Justin He <Justin.He at arm.com>
> > Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
> > <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
> > <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
> > david at redhat.com; quic_qiancai at quicinc.com; linux-
> > kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > gshan at redhat.com; nd <nd at arm.com>
> > Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> > pud mapping
> >
> > On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
> > >
> > > Hi Catalin
> > >
> > > > -----Original Message-----
> > > > From: Catalin Marinas <catalin.marinas at arm.com>
> > > > Sent: Friday, January 7, 2022 6:43 PM
> > > > To: Jianyong Wu <Jianyong.Wu at arm.com>
> > > > Cc: will at kernel.org; Anshuman Khandual
> > <Anshuman.Khandual at arm.com>;
> > > > akpm at linux-foundation.org; david at redhat.com;
> > > > quic_qiancai at quicinc.com; ardb at kernel.org;
> > > > linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
> > > > gshan at redhat.com; Justin He <Justin.He at arm.com>; nd <nd at arm.com>
> > > > Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
> > > > create pud mapping
> > > >
> > > > On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> > > > > Hi Catalin,
> > > > >
> > > > > I roughly find the root cause.
> > > > >  alloc_init_pud will be called at the very beginning of kernel
> > > > > boot in
> > > > create_mapping_noalloc where no memory allocator is initialized. But
> > > > lockdep check may need allocate memory. So, kernel take exception
> > > > when acquire lock.(I have not found the exact code that cause this
> > > > issue) that's say we may not be able to use a lock so early.
> > > > >
> > > > > I come up with 2 methods to address it.
> > > > > 1) skip dead lock check at the very beginning of kernel boot in
> > > > > lockdep
> > > > code.
> > > > > 2) provided 2 two versions of __create_pgd_mapping, one with lock
> > > > > in it and the other without. There may be no possible of race for
> > > > > memory mapping at the very beginning time of kernel boot, thus we
> > > > > can use the no lock version of __create_pgd_mapping safely.
> > > > > In my test, this issue is gone if there is no lock held in
> > > > > create_mapping_noalloc. I think create_mapping_noalloc is called
> > > > > early enough to avoid the race conditions of memory mapping,
> > > > > however, I have not proved it.
> > > >
> > > > I think method 2 would work better but rather than implementing new
> > > > nolock functions I'd add a NO_LOCK flag and check it in
> > > > alloc_init_pud() before mutex_lock/unlock. Also add a comment when
> > > > passing the NO_LOCK flag on why it's needed and why there wouldn't
> > > > be any races at that stage (early boot etc.)
> > > >
> > > The problematic code path is:
> > > __primary_switched
> > >         early_fdt_map->fixmap_remap_fdt
> > >                 create_mapping_noalloc->alloc_init_pud
> > >                         mutex_lock (with Jianyong's patch)
> > >
> > > The problem seems to be that we will clear BSS segment twice if kaslr
> > > is enabled. Hence, some of the static variables in lockdep init
> > > process were messed up. That is to said, with kaslr enabled we might
> > > initialize lockdep twice if we add mutex_lock/unlock in alloc_init_pud().
> > >
> >
> > Thanks for tracking that down.
> >
> > Note that clearing the BSS twice is not the root problem here. The root
> > problem is that we set global state while the kernel runs at the default link
> > time address, and then refer to it again after the entire kernel has been
> > shifted in the kernel VA space. Such global state could consist of mutable
> > pointers to statically allocated data (which would be reset to their default
> > values after the relocation code runs again), or global pointer variables in BSS.
> > In either case, relying on such a global variable after the second relocation
> > performed by KASLR would be risky, and so we should avoid manipulating
> > global state at all if it might involve pointer to statically allocated data
> > structures.
> >
> > > In other ways, if we invoke mutex_lock/unlock in such a early booting stage.
> > > It might be unsafe because lockdep inserts lock_acquire/release as the
> > > complex hooks.
> > >
> > > In summary, would it better if Jianyong splits these early boot and
> > > late boot case? e.g. introduce a nolock version for
> > create_mapping_noalloc().
> > >
> > > What do you think of it?
> > >
> >
> > The pre-KASLR case definitely doesn't need a lock. But given that
> > create_mapping_noalloc() is only used to map the FDT, which happens very
> > early one way or the other, wouldn't it be better to move the lock/unlock
> > into other callers of __create_pgd_mapping()? (and make sure no other
> > users of the fixmap slots exist)
>
> There are server callers of __create_pgd_mapping. I think some of them need no fixmap lock as they are called so early. I figure out all of them here:
> create_mapping_noalloc:   no lock
> create_pgd_mapping:   no lock
> __map_memblock:    no lock
> map_kernel_segment:  no lock
> map_entry_trampoline: no lock
> update_mapping_prot:    need lock
> arch_add_memory:  need lock
>
> WDYT?
>

That seems reasonable, but it needs to be documented clearly in the code.


From david at redhat.com  Wed Jan 26 02:17:42 2022
From: david at redhat.com (David Hildenbrand)
Date: Wed, 26 Jan 2022 11:17:42 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
Message-ID: <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>

On 26.01.22 11:12, Ard Biesheuvel wrote:
> On Wed, 26 Jan 2022 at 11:09, Jianyong Wu <Jianyong.Wu at arm.com> wrote:
>>
>> Hi Ard,
>>
>>> -----Original Message-----
>>> From: Ard Biesheuvel <ardb at kernel.org>
>>> Sent: Wednesday, January 26, 2022 4:37 PM
>>> To: Justin He <Justin.He at arm.com>
>>> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
>>> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
>>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
>>> david at redhat.com; quic_qiancai at quicinc.com; linux-
>>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>> gshan at redhat.com; nd <nd at arm.com>
>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
>>> pud mapping
>>>
>>> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
>>>>
>>>> Hi Catalin
>>>>
>>>>> -----Original Message-----
>>>>> From: Catalin Marinas <catalin.marinas at arm.com>
>>>>> Sent: Friday, January 7, 2022 6:43 PM
>>>>> To: Jianyong Wu <Jianyong.Wu at arm.com>
>>>>> Cc: will at kernel.org; Anshuman Khandual
>>> <Anshuman.Khandual at arm.com>;
>>>>> akpm at linux-foundation.org; david at redhat.com;
>>>>> quic_qiancai at quicinc.com; ardb at kernel.org;
>>>>> linux-kernel at vger.kernel.org; linux-arm- kernel at lists.infradead.org;
>>>>> gshan at redhat.com; Justin He <Justin.He at arm.com>; nd <nd at arm.com>
>>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
>>>>> create pud mapping
>>>>>
>>>>> On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
>>>>>> Hi Catalin,
>>>>>>
>>>>>> I roughly find the root cause.
>>>>>>  alloc_init_pud will be called at the very beginning of kernel
>>>>>> boot in
>>>>> create_mapping_noalloc where no memory allocator is initialized. But
>>>>> lockdep check may need allocate memory. So, kernel take exception
>>>>> when acquire lock.(I have not found the exact code that cause this
>>>>> issue) that's say we may not be able to use a lock so early.
>>>>>>
>>>>>> I come up with 2 methods to address it.
>>>>>> 1) skip dead lock check at the very beginning of kernel boot in
>>>>>> lockdep
>>>>> code.
>>>>>> 2) provided 2 two versions of __create_pgd_mapping, one with lock
>>>>>> in it and the other without. There may be no possible of race for
>>>>>> memory mapping at the very beginning time of kernel boot, thus we
>>>>>> can use the no lock version of __create_pgd_mapping safely.
>>>>>> In my test, this issue is gone if there is no lock held in
>>>>>> create_mapping_noalloc. I think create_mapping_noalloc is called
>>>>>> early enough to avoid the race conditions of memory mapping,
>>>>>> however, I have not proved it.
>>>>>
>>>>> I think method 2 would work better but rather than implementing new
>>>>> nolock functions I'd add a NO_LOCK flag and check it in
>>>>> alloc_init_pud() before mutex_lock/unlock. Also add a comment when
>>>>> passing the NO_LOCK flag on why it's needed and why there wouldn't
>>>>> be any races at that stage (early boot etc.)
>>>>>
>>>> The problematic code path is:
>>>> __primary_switched
>>>>         early_fdt_map->fixmap_remap_fdt
>>>>                 create_mapping_noalloc->alloc_init_pud
>>>>                         mutex_lock (with Jianyong's patch)
>>>>
>>>> The problem seems to be that we will clear BSS segment twice if kaslr
>>>> is enabled. Hence, some of the static variables in lockdep init
>>>> process were messed up. That is to said, with kaslr enabled we might
>>>> initialize lockdep twice if we add mutex_lock/unlock in alloc_init_pud().
>>>>
>>>
>>> Thanks for tracking that down.
>>>
>>> Note that clearing the BSS twice is not the root problem here. The root
>>> problem is that we set global state while the kernel runs at the default link
>>> time address, and then refer to it again after the entire kernel has been
>>> shifted in the kernel VA space. Such global state could consist of mutable
>>> pointers to statically allocated data (which would be reset to their default
>>> values after the relocation code runs again), or global pointer variables in BSS.
>>> In either case, relying on such a global variable after the second relocation
>>> performed by KASLR would be risky, and so we should avoid manipulating
>>> global state at all if it might involve pointer to statically allocated data
>>> structures.
>>>
>>>> In other ways, if we invoke mutex_lock/unlock in such a early booting stage.
>>>> It might be unsafe because lockdep inserts lock_acquire/release as the
>>>> complex hooks.
>>>>
>>>> In summary, would it better if Jianyong splits these early boot and
>>>> late boot case? e.g. introduce a nolock version for
>>> create_mapping_noalloc().
>>>>
>>>> What do you think of it?
>>>>
>>>
>>> The pre-KASLR case definitely doesn't need a lock. But given that
>>> create_mapping_noalloc() is only used to map the FDT, which happens very
>>> early one way or the other, wouldn't it be better to move the lock/unlock
>>> into other callers of __create_pgd_mapping()? (and make sure no other
>>> users of the fixmap slots exist)
>>
>> There are server callers of __create_pgd_mapping. I think some of them need no fixmap lock as they are called so early. I figure out all of them here:
>> create_mapping_noalloc:   no lock
>> create_pgd_mapping:   no lock
>> __map_memblock:    no lock
>> map_kernel_segment:  no lock
>> map_entry_trampoline: no lock
>> update_mapping_prot:    need lock
>> arch_add_memory:  need lock
>>
>> WDYT?
>>
> 
> That seems reasonable, but it needs to be documented clearly in the code.
> 

Just a random thought, could we rely on system_state to do the locking
conditionally?

-- 
Thanks,

David / dhildenb



From nobuta.keiya at fujitsu.com  Wed Jan 26 02:20:16 2022
From: nobuta.keiya at fujitsu.com (nobuta.keiya at fujitsu.com)
Date: Wed, 26 Jan 2022 10:20:16 +0000
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <825b8b72-c746-ba24-7142-3fff481e82d6@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
 <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
 <825b8b72-c746-ba24-7142-3fff481e82d6@linux.microsoft.com>
Message-ID: <TY2PR01MB5257BE671A481D81F1A40E0185209@TY2PR01MB5257.jpnprd01.prod.outlook.com>

> I have not seen any activity on that in a long time. IIRC, Julien quit RedHat.
> I don't know if anyone else has taken over this work in RedHat.
> 
> Sorry, I don't have any more information.
> 
> Madhavan

Thanks for your information.

By the way, I'm considering test code for arch_stack_walk_reliable().
Specifically, I apply Suraj's patch to enable livepatch, and added a function
that sleeps between SYM_CODE_START and SYM_CODE_END, then livepatch
checks if the task has an unreliable stack.
For now my internal test code working correctly, but my Kconfig excludes
STACK_VALIDATION dependency.

It seems that objtool will not be enabled yet, so I would like to test it easier.
If you are already testing with this patch, could you tell me how to do it?


Thanks,
Keiya

> 
> On 1/24/22 23:21, nobuta.keiya at fujitsu.com wrote:
> > Hi Madhavan,
> >
> >> Select HAVE_RELIABLE_STACKTRACE in arm64/Kconfig to allow
> >> arch_stack_walk_reliable() to be used.
> >>
> >> Note that this is conditional upon STACK_VALIDATION which will be
> >> added when frame pointer validation is implemented (say via objtool).
> >
> > I know that Julien Thierry published objtool support for arm64 [1],
> > but I'm not sure if it has been updated. Could you tell me other threads if you know?
> >
> > [1]
> > https://lore.kernel.org/linux-arm-kernel/20210303170932.1838634-1-jthi
> > erry at redhat.com/
> >
> >
> > Thanks,
> > Keiya
> >
> >>
> >> Signed-off-by: Madhavan T. Venkataraman
> >> <madvenka at linux.microsoft.com>
> >> ---
> >>  arch/arm64/Kconfig | 1 +
> >>  1 file changed, 1 insertion(+)
> >>
> >> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index
> >> f6e333b59314..bc7b3514b563 100644
> >> --- a/arch/arm64/Kconfig
> >> +++ b/arch/arm64/Kconfig
> >> @@ -223,6 +223,7 @@ config ARM64
> >>  	select THREAD_INFO_IN_TASK
> >>  	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
> >>  	select TRACE_IRQFLAGS_SUPPORT
> >> +	select HAVE_RELIABLE_STACKTRACE if FRAME_POINTER &&
> >> +STACK_VALIDATION
> >>  	help
> >>  	  ARM 64-bit (AArch64) Linux support.
> >>
> >> --
> >> 2.25.1
> >
> >
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From linux at armlinux.org.uk  Wed Jan 26 02:24:40 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:24:40 +0000
Subject: [PATCH net-next v2 0/7] net: stmmac/xpcs: modernise PCS support
Message-ID: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>

Hi,

This series updates xpcs and stmmac for the recent changes to phylink
to better support split PCS and to get rid of private MAC validation
functions.

This series is slightly more involved than other conversions as stmmac
has already had optional proper split PCS support.

The first six patches of this series were originally posted on 16th
December for CFT, and Wong Vee Khee reported his Intel Elkhart Lake
setup was fine the first six these. However, no tested-by was given.

The patches:

1) Provide a function to query the xpcs for the interface modes that
   are supported.

2) Populates the MAC capabilities and switches stmmac_validate() to use
   phylink_get_linkmodes(). We do not use phylink_generic_validate() yet
   as (a) we do not always have the supported interfaces populated, and
   (b) the existing code does not restrict based on interface. There
   should be no functional effect from this patch.

3) Populates phylink's supported interfaces from the xpcs when the xpcs
   is configured by firmware and also the firmware configured interface
   mode. Note: this will restrict stmmac to only supporting these
   interfaces modes - stmmac maintainers need to verify that this
   behaviour is acceptable.

4) stmmac_validate() tail-calls xpcs_validate(), but we don't need it to
   now that PCS have their own validation method. Convert stmmac and
   xpcs to use this method instead.

5) xpcs sets the poll field of phylink_pcs to true, meaning xpcs
   requires its status to be polled. There is no need to also set the
   phylink_config.pcs_poll. Remove this.

6) Switch to phylink_generic_validate(). This is probably the most
   contravertial change in this patch set as this will cause the MAC to
   restrict link modes based on the interface mode. From an inspection
   of the xpcs driver, this should be safe, as XPCS only further
   restricts the link modes to a subset of these (whether that is
   correct or not is not an issue I am addressing here.) For
   implementations that do not use xpcs, this is a more open question
   and needs feedback from stmmac maintainers.

7) Convert to use mac_select_pcs() rather than phylink_set_pcs() to set
   the PCS - the intention is to eventually remove phylink_set_pcs()
   once there are no more users of this.

v2: fix signoff and temporary warning in patch 4

 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 147 +++++++---------------
 drivers/net/pcs/pcs-xpcs.c                        |  41 +++---
 include/linux/pcs/pcs-xpcs.h                      |   3 +-
 3 files changed, 73 insertions(+), 118 deletions(-)

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From moudy.ho at mediatek.com  Wed Jan 26 02:24:42 2022
From: moudy.ho at mediatek.com (moudy.ho)
Date: Wed, 26 Jan 2022 18:24:42 +0800
Subject: [PATCH v11 1/3] dt-binding: mt8183: add Mediatek MDP3 dt-bindings
In-Reply-To: <815a363d-749e-d7a5-3786-c11dfd4d22d4@collabora.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-2-moudy.ho@mediatek.com>
 <YesiwTSxa9HJ1lxG@robh.at.kernel.org>
 <815a363d-749e-d7a5-3786-c11dfd4d22d4@collabora.com>
Message-ID: <56801c5e596727a4f97e82e23450f9689808e040.camel@mediatek.com>

On Mon, 2022-01-24 at 12:40 +0100, AngeloGioacchino Del Regno wrote:
> Il 21/01/22 22:16, Rob Herring ha scritto:
> > On Wed, Jan 05, 2022 at 05:37:56PM +0800, Moudy Ho wrote:
> 
> Hello Rob,
> 
> since I'm not the best at reviewing dt-bindings, I always try to
> leave that to
> 
> other reviewers; in which case, thank you for your awesome review
> activity on
> 
> all of these (and helping me a lot on some of my attempts to write
> yaml..!!)
> 
> 
> In this case, though, since I do have knowledge about the platform,
> it's probably
> worth for me to try to address some of your questions, on at least
> this one.
> 
> 
> > > This patch adds DT binding document for Media Data Path 3 (MDP3)
> > > a unit in multimedia system used for scaling and color format
> > > convert.
> > > 
> > > Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
> > > ---
> > >   .../bindings/media/mediatek,mdp3-rdma.yaml    | 193
> > > ++++++++++++++++++
> > >   .../bindings/media/mediatek,mdp3-rsz.yaml     |  55 +++++
> > >   .../bindings/media/mediatek,mdp3-wrot.yaml    |  57 ++++++
> > >   .../bindings/soc/mediatek/mediatek,ccorr.yaml |  47 +++++
> > >   .../bindings/soc/mediatek/mediatek,wdma.yaml  |  58 ++++++
> > >   5 files changed, 410 insertions(+)
> > >   create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> > >   create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> > >   create mode 100644
> > > Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml
> > >   create mode 100644
> > > Documentation/devicetree/bindings/soc/mediatek/mediatek,ccorr.yam
> > > l
> > >   create mode 100644
> > > Documentation/devicetree/bindings/soc/mediatek/mediatek,wdma.yaml
> > > 
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml 
> > > b/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml
> > > new file mode 100644
> > > index 000000000000..002503383934
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > > rdma.yaml
> > > @@ -0,0 +1,193 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > https://urldefense.com/v3/__http://devicetree.org/schemas/media/mediatek,mdp3-rdma.yaml*__;Iw!!CTRNKA9wMg0ARbw!zgc4tZBqeOyinIM3DFy7YlTTFM9LtRFRUOLmIB6Go6xpTeaPQaFg_ekOtt5fpkQb$
> > >  
> > > +$schema: 
> > > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!zgc4tZBqeOyinIM3DFy7YlTTFM9LtRFRUOLmIB6Go6xpTeaPQaFg_ekOtk8-fzFI$
> > >  
> > > +
> > > +title: Mediatek Read Direct Memory Access
> > > +
> > > +maintainers:
> > > +  - Matthias Brugger <matthias.bgg at gmail.com>
> > > +
> > > +description: |
> > > +  Mediatek Read Direct Memory Access(RDMA) component used to do
> > > read DMA.
> > > +  It contains one line buffer to store the sufficient pixel
> > > data, and
> > > +  must be siblings to the central MMSYS_CONFIG node.
> > > +  For a description of the MMSYS_CONFIG binding, see
> > > +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.
> > > yaml
> > > +  for details.
> > > +  The 1st RDMA is also used to be a controller node in Media
> > > Data Path 3(MDP3)
> > > +  that containing MMSYS, MUTEX, GCE and SCP settings.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    oneOf:
> > > +      - items:
> > > +          # MDP3 controller node
> > > +          - const: mediatek,mt8183-mdp3
> > 
> > How is this more specific than this:
> > 
> > > +          - const: mediatek,mt8183-mdp3-rdma0
> 
> Probably, oneOf is not the right choice here... "mediatek,mt8183-
> mdp3" is needed
> to probe the "main" mdp3 core pdev, while RDMA0 is a necessary
> component (as in
> this driver uses the component framework, and rdma0 is required for
> functionality,
> as far as I understand).
> 
> This shouldn't be a choice, meaning that defining mdp3-rdma0 without
> mdp3 is
> completely useless, as there wouldn't be anything else initializing
> that component,
> nor sub-components of that.
> 
Hi Rob and Angelo,
Sorry for the incomplete description here, I originally planned to add
a compatible name here in the future when the chip has multiple RDMAs.
Since 8183 currently has only one RDMA, the above design expression is
incorrect and should be rewritten as follows:

[8183]
properties:
  compatible:
    items:
      # MDP3 controller node
      - const: mediatek,mt8183-mdp3
      - const: mediatek,mt8195-mdp3-rdma0

[8195]
properties:
  compatible:
    oneOf:
      - items:
          # MDP3 controller node
          - const: mediatek,mt8183-mdp3
          - const: mediatek,mt8195-mdp3-rdma0
      - items:
          # normal RDMA conponent
          - const: mediatek,mt8195-mdp3-rdma1
      - items:
          # normal RDMA conponent
          - const: mediatek,mt8195-mdp3-rdma2
      - items:
          # normal RDMA conponent
          - const: mediatek,mt8195-mdp3-rdma3

> > > +      - items:
> > > +          # normal RDMA conponent
> > > +          - const: mediatek,mt8183-mdp3-rdma0
> > > +
> > > +  mediatek,scp:
> > > +    description: The node of system control processor (SCP),
> > > using
> > > +      the remoteproc & rpmsg framework.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    maxItems: 1
> > > +
> > > +  mediatek,mdp3-comps:
> > > +    description: MTK sub-system of direct-link or DIP
> > 
> > This needs a better description. What is DIP? What is direct-link?
> 
> I agree, this needs a better description.
> 
I tried to modify the description as follows, could you help to see if
there is anything confusing:

  mediatek,mdp3-comps:
    description:
      MDP subsystem which has direct-link from Image Signal
Processor(ISP).
      When using the camera, the DMA of ISP PASS (DIP) module will
directly trigger MDP3 without other control (such as V4L2 M2M) to
create corresponding HW path.
      The MDP3 controller must set up a series of registers at the
beginning of path creation which covering MMSYS, IMGSYS, and MDP3's
components, so that data flow can pass through MDP3.
      The entire path is briefly described as follows:
      DIP   : ISP ->
      MDP3  :       IMGI -> DL -> CCORR(optional) -> RSZ -> PATH_OUT ->
WDMA/WROT
> > 
> > > +    $ref: /schemas/types.yaml#/definitions/string-array
> > > +    items:
> > > +      - enum:
> > > +          # MDP direct-link input path selection, create a
> > > +          # component for path connectedness of HW pipe control
> > > +          - mediatek,mt8183-mdp3-dl1
> > > +      - enum:
> > > +          - mediatek,mt8183-mdp3-dl2
> > > +      - enum:
> > > +          # MDP direct-link output path selection, create a
> > > +          # component for path connectedness of HW pipe control
> > > +          - mediatek,mt8183-mdp3-path1
> > > +      - enum:
> > > +          - mediatek,mt8183-mdp3-path2
> > > +      - enum:
> > > +          # Input DMA of ISP PASS2 (DIP) module for raw image
> > > input
> > > +          - mediatek,mt8183-mdp3-imgi
> > > +      - enum:
> > > +          # Output DMA of ISP PASS2 (DIP) module for YUV image
> > > output
> > > +          - mediatek,mt8183-mdp3-exto
> > 
> > There's only 1 possible value for mediatek,mdp3-comps, so why does
> > it
> > need to be in DT?
> > 
> 
> The wanted logic here (I believe) is that, depending on firmware
> capabilities
> and/or platform/board capabilities, you may miss some subcomponents
> like IMGI
> and/or EXTO.
> As for DL1/2 and PATH1/2... DL1+PATH1 is surely critically necessary
> for the
> functionality of the MDP3 RDMA... I don't know whether it's possible
> that we
> get any fw/platform/device that's not using DL2/PATH2 at all.
> 
> Moudy, can you please explain?
> 
Hi Angelo,
  Thanks for your help and your assumptions are correct.
  In further chips(such as 8195), IMGI will be replaced by WPE, and
PATH_OUT will be removed, and DL will be expanded to 6 (implicit number
of direct-link from ISP paths).
  For this variable hardware design, not sure how to flexibly describe
in dt-bindings to meet futher requirements.
  It should be that I got wrong with the definition of "enum", should
it be rewritten as follows in 8183?
      items:
        - enum:
          # MDP direct-link input path selection, create a
          # component for path connectedness of HW pipe control
          - mediatek,mt8183-mdp3-dl1
          - mediatek,mt8183-mdp3-dl2
          # MDP direct-link output path selection, create a
          # component for path connectedness of HW pipe control
          - mediatek,mt8183-mdp3-path1
          - mediatek,mt8183-mdp3-path2
          # Input DMA of ISP PASS2 (DIP) module for raw image input
          - mediatek,mt8183-mdp3-imgi
          # Output DMA of ISP PASS2 (DIP) module for YUV image output
          - mediatek,mt8183-mdp3-exto
      items: (8195)
          snip....
      items: (8192)
          snip...
> > > +
> > > +  reg:
> > > +    items:
> > > +      - description: basic RDMA HW address
> > > +      - description: MDP direct-link 1st and 2nd input
> > > +      - description: MDP direct-link 1st output
> > > +      - description: MDP direct-link 2nd output
> > > +      - description: ISP input and output
> > > +
> > > +  mediatek,gce-client-reg:
> > > +    description: The register of client driver can be configured
> > > by gce with
> > > +      4 arguments defined in this property, such as phandle of
> > > gce, subsys id,
> > > +      register offset and size. Each GCE subsys id is mapping to
> > > a client
> > > +      defined in the header include/dt-bindings/gce/<chip>-
> > > gce.h.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > +    items:
> > > +      - description: GCE client for RDMA
> > > +      - description: GCR client for MDP direct-link 1st and 2nd
> > > input
> > > +      - description: GCR client for MDP direct-link 1st output
> > > +      - description: GCR client for MDP direct-link 2nd output
> > > +      - description: GCR client for ISP input and output
> > > +
> > > +  power-domains:
> > > +    maxItems: 1
> > > +
> > > +  clocks:
> > > +    items:
> > > +      - description: RDMA clock
> > > +      - description: RSZ clock
> > > +      - description: direck-link TX clock in MDP side
> > > +      - description: direck-link RX clock in MDP side
> > > +      - description: direck-link TX clock in ISP side
> > > +      - description: direck-link RX clock in ISP side
> > > +
> > > +  iommus:
> > > +    maxItems: 1
> > > +
> > > +  mediatek,mmsys:
> > > +    description: The node of mux(multiplexer) controller for HW
> > > connections.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +
> > > +  mediatek,mm-mutex:
> > 
> > Is this some sort of h/w lock? We have a standard binding for that.
> > 
> 
> There's a story behind that one: this was part of mtk (display) DRM
> drivers, then
> it was moved to soc/mediatek/mtk-mutex.c as it started being shared.
> 
> I wonder if the mm-mutex can be rewritten and moved to hwspinlock...
> this driver
> is growing and now, with the introduction of MDP3, we're seeing some
> more.
> 
> Though, it's definitely worth mentioning that the usage of MediaTek's
> mm-mutex is
> varying a bit between the drm case and the mdp3 case as, here, we
> have a "command
> queue" mechanism that is used for commands ordering in HW.
> This is a very complex architecture that has very specific
> requirements.
> For how I see it, migrating that to hwspinlock would require an
> almost complete
> reimplementation of soc/mediatek/*, which would take a considerable
> amount of
> time and efforts.
> I'm mostly sure that I can help with that, but for how things are
> looking right
> 
> now, between refactoring, getting code solid, going through sane
> reviews and a
> final merge, I'd say that this will take 8-12 months from now.
> 
> For this reason, I would propose to perform a slow and steady
> migration of the
> MediaTek mmsys, scpsys, mutex over time, but only after getting in
> the support
> for the new SoCs and functionality for the older ones, provided in
> this series
> and some others that were already sent by MTK, half (or more) of
> which have
> already been merged.

  Sorry for the misunderstanding caused by the name, the original mtk-
mutex design did have the ability to lock registers, but that has since
been removed but the name continues.
  It's not one of those h/w locks like spinlock, semaphore, or mutex
but is just designed to send signals to trigger h/w components to get
or send data.

> > > +    description: The node of sof(start of frame) signal
> > > controller.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +    maxItems: 1
> > > +
> > > +  mediatek,mailbox-gce:
> > > +    description: The node of global command engine (GCE), used
> > > to read/write
> > > +      registers with critical time limitation.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle
> > > +
> > > +  mboxes:
> > > +    items:
> > > +      - description: used for 1st data pipe from RDMA
> > > +      - description: used for 2nd data pipe from RDMA
> > > +      - description: used for 3rd data pipe from Direct-Link
> > > +      - description: used for 4th data pipe from Direct-Link
> > > +
> > > +  gce-subsys:
> > > +    description: sub-system id corresponding to the global
> > > command engine (GCE)
> > > +      register address.
> > > +    $ref: /schemas/types.yaml#/definitions/phandle-array
> > > +
> > > +if:
> > > +  properties:
> > > +    compatible:
> > > +      contains:
> > > +        const: mediatek,mt8183-mdp3
> > > +
> > > +then:
> > > +  required:
> > > +    - mediatek,scp
> > > +    - mediatek,mmsys
> > > +    - mediatek,mm-mutex
> > > +    - mediatek,mailbox-gce
> > > +    - mboxes
> > > +    - gce-subsys
> > > +
> > > +required:
> > > +  - compatible
> > > +  - reg
> > > +  - clocks
> > > +  - mediatek,gce-client-reg
> > > +
> > > +additionalProperties: false
> > > +
> > > +examples:
> > > +  - |
> > > +    #include <dt-bindings/clock/mt8183-clk.h>
> > > +    #include <dt-bindings/gce/mt8183-gce.h>
> > > +    #include <dt-bindings/power/mt8183-power.h>
> > > +    #include <dt-bindings/memory/mt8183-larb-port.h>
> > > +
> > > +    mdp3_rdma0: mdp3_rdma0 at 14001000 {
> > > +      compatible = "mediatek,mt8183-mdp3",
> > > +                   "mediatek,mt8183-mdp3-rdma0";
> > > +      mediatek,scp = <&scp>;
> > > +      mediatek,mdp3-comps = "mediatek,mt8183-mdp3-dl1",
> > > +                            "mediatek,mt8183-mdp3-dl2",
> > > +                            "mediatek,mt8183-mdp3-path1",
> > > +                            "mediatek,mt8183-mdp3-path2",
> > > +                            "mediatek,mt8183-mdp3-imgi",
> > > +                            "mediatek,mt8183-mdp3-exto";
> > > +      reg = <0x14001000 0x1000>,
> > > +            <0x14000000 0x1000>,
> > > +            <0x14005000 0x1000>,
> > > +            <0x14006000 0x1000>,
> > > +            <0x15020000 0x1000>;
> > > +      mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000
> > > 0x1000>,
> > > +                                <&gce SUBSYS_1400XXXX 0 0x1000>,
> > > +                                <&gce SUBSYS_1400XXXX 0x5000
> > > 0x1000>,
> > > +                                <&gce SUBSYS_1400XXXX 0x6000
> > > 0x1000>,
> > > +                                <&gce SUBSYS_1502XXXX 0 0x1000>;
> > > +      power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> > > +      clocks = <&mmsys CLK_MM_MDP_RDMA0>,
> > > +               <&mmsys CLK_MM_MDP_RSZ1>,
> > > +               <&mmsys CLK_MM_MDP_DL_TXCK>,
> > > +               <&mmsys CLK_MM_MDP_DL_RX>,
> > > +               <&mmsys CLK_MM_IPU_DL_TXCK>,
> > > +               <&mmsys CLK_MM_IPU_DL_RX>;
> > > +      iommus = <&iommu>;
> > > +      mediatek,mmsys = <&mmsys>;
> > > +      mediatek,mm-mutex = <&mutex>;
> > > +      mediatek,mailbox-gce = <&gce>;
> > > +      mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
> > > +               <&gce 21 CMDQ_THR_PRIO_LOWEST>,
> > > +               <&gce 22 CMDQ_THR_PRIO_LOWEST>,
> > > +               <&gce 23 CMDQ_THR_PRIO_LOWEST>;
> > > +      gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
> > > +                   <&gce 0x14010000 SUBSYS_1401XXXX>,
> > > +                   <&gce 0x14020000 SUBSYS_1402XXXX>,
> > > +                   <&gce 0x15020000 SUBSYS_1502XXXX>;
> > > +    };
> > > diff --git
> > > a/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> > > b/Documentation/devicetree/bindings/media/mediatek,mdp3-rsz.yaml
> > > new file mode 100644
> > > index 000000000000..cd4cf1531535
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/media/mediatek,mdp3-
> > > rsz.yaml
> > > @@ -0,0 +1,55 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id: 
> > > https://urldefense.com/v3/__http://devicetree.org/schemas/media/mediatek,mdp3-rsz.yaml*__;Iw!!CTRNKA9wMg0ARbw!zgc4tZBqeOyinIM3DFy7YlTTFM9LtRFRUOLmIB6Go6xpTeaPQaFg_ekOtoNRPuZQ$
> > >  
> > > +$schema: 
> > > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!zgc4tZBqeOyinIM3DFy7YlTTFM9LtRFRUOLmIB6Go6xpTeaPQaFg_ekOtk8-fzFI$
> > >  
> > > +
> > > +title: Mediatek Resizer
> > > +
> > > +maintainers:
> > > +  - Matthias Brugger <matthias.bgg at gmail.com>
> > > +
> > > +description: |
> > > +  One of Media Data Path 3 (MDP3) components used to do frame
> > > resizing.
> > > +
> > > +properties:
> > > +  compatible:
> > > +    items:
> > > +      - enum:
> > > +          - mediatek,mt8183-mdp3-rsz0
> > > +          - mediatek,mt8183-mdp3-rsz1
> > 
> > Again, what's the difference between 0 and 1?
> > 
> > I've probably asked that before, but without a sufficient reasoning
> > here in the schema I'm just going to keep asking the same question.
> 
> This can probably be, instead, something like
> 
> compatible = "mediatek,mt8183-mdp3-rsz";
> reg = < .... >;
> mediatek,instance-id = <0>;
> gce reg, clocks, blah...
> 
> or
> 
> compatible = "mediatek,mt8183-mdp3-rsz";
> reg = < ...rsz0... >, < ...rsz1... >;
> reg-names = "rsz0", "rsz1";
> gce reg, clocks, blah...
> 
> 
> ...In any case, if MediaTek chose to separate these like that, I
> guess that
> there will be differences in newer SoCs that would make that kind of
> binding
> much necessary.
> 
> Please Moudy, can you explain why you didn't write that like the
> examples
> that I provided there?

Before version 10 it was written the same way as the first form Angelo
mentioned - with h/w indexed properties, but Rob thinks it's bad idea.
At that time I asked Rob if it could be rewritten into its current V11
form, but I updated before I got a suggestion.
Apologize for the inconvenience casued by my careless handling.

In the 8183 MDP3, only RSZ is configured with 2 sets. The 1st set
upstream can have quality adjustment components (like AAL or CCORR or
both) connected, but the 2nd set does not.
Although those two RSZ components have the same hardware function but
register address. The MDP paths with different functions will be
created due to the different upstream and downstream connections.
In addition to the various upstream/downstream connection methods
caused by chip design, the above conditions are also dynamically
determined according to the current usage scenario(with or without PQ,
rotation...etc).
Also, considering that multiple paths are used at the same time, MDP3
will need to know which components are currently available for
dispatch.
At present, I can't find a better description form, let me know if you
have any thoughts with this.

> > 
> > Rob
> > 

Thanks,
Moudy
> 



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:25:55 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:25:55 +0000
Subject: [PATCH net-next v2 1/7] net: xpcs: add support for retrieving
 supported interface modes
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfUx-005Rcu-4K@rmk-PC.armlinux.org.uk>

Add a function to the xpcs driver to retrieve the supported PHY
interface modes, which can be used by drivers to fill in phylink's
supported_interfaces mask.

We validate the interface bit index to ensure that it fits within the
bitmap as xpcs lists PHY_INTERFACE_MODE_MAX in an entry.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/pcs/pcs-xpcs.c   | 14 ++++++++++++++
 include/linux/pcs/pcs-xpcs.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index cd6742e6ba8b..f45821524fab 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -662,6 +662,20 @@ void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 }
 EXPORT_SYMBOL_GPL(xpcs_validate);
 
+void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
+{
+	int i, j;
+
+	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
+		const struct xpcs_compat *compat = &xpcs->id->compat[i];
+
+		for (j = 0; j < compat->num_interfaces; j++)
+			if (compat->interface[j] < PHY_INTERFACE_MODE_MAX)
+				__set_bit(compat->interface[j], interfaces);
+	}
+}
+EXPORT_SYMBOL_GPL(xpcs_get_interfaces);
+
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable)
 {
 	int ret;
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index add077a81b21..3126a4924d92 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -33,6 +33,7 @@ int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 		   unsigned int mode);
 void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
 		   struct phylink_link_state *state);
+void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
 struct dw_xpcs *xpcs_create(struct mdio_device *mdiodev,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:00 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:00 +0000
Subject: [PATCH net-next v2 2/7] net: stmmac: convert to
 phylink_get_linkmodes()
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfV2-005Rd0-8V@rmk-PC.armlinux.org.uk>

Add the MAC speed, duplex and pause capabilities to the phylink_config
structure, and switch stmmac_validate() to use phylink_get_linkmodes()
to generate the mask of supported ethtool link modes.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 125 ++++++------------
 1 file changed, 42 insertions(+), 83 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 6708ca2aa4f7..e85ca75d394d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -942,95 +942,22 @@ static void stmmac_validate(struct phylink_config *config,
 {
 	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
-	int tx_cnt = priv->plat->tx_queues_to_use;
-	int max_speed = priv->plat->max_speed;
-
-	phylink_set(mac_supported, 10baseT_Half);
-	phylink_set(mac_supported, 10baseT_Full);
-	phylink_set(mac_supported, 100baseT_Half);
-	phylink_set(mac_supported, 100baseT_Full);
-	phylink_set(mac_supported, 1000baseT_Half);
-	phylink_set(mac_supported, 1000baseT_Full);
-	phylink_set(mac_supported, 1000baseKX_Full);
 
+	/* This is very similar to phylink_generic_validate() except that
+	 * we always use PHY_INTERFACE_MODE_INTERNAL to get all capabilities.
+	 * This is because we don't always have config->supported_interfaces
+	 * populated (only when we have the XPCS.)
+	 *
+	 * When we do have an XPCS, we could pass state->interface, as XPCS
+	 * limits to a subset of the ethtool link modes allowed here.
+	 */
 	phylink_set(mac_supported, Autoneg);
-	phylink_set(mac_supported, Pause);
-	phylink_set(mac_supported, Asym_Pause);
 	phylink_set_port_modes(mac_supported);
-
-	/* Cut down 1G if asked to */
-	if ((max_speed > 0) && (max_speed < 1000)) {
-		phylink_set(mask, 1000baseT_Full);
-		phylink_set(mask, 1000baseX_Full);
-	} else if (priv->plat->has_gmac4) {
-		if (!max_speed || max_speed >= 2500) {
-			phylink_set(mac_supported, 2500baseT_Full);
-			phylink_set(mac_supported, 2500baseX_Full);
-		}
-	} else if (priv->plat->has_xgmac) {
-		if (!max_speed || (max_speed >= 2500)) {
-			phylink_set(mac_supported, 2500baseT_Full);
-			phylink_set(mac_supported, 2500baseX_Full);
-		}
-		if (!max_speed || (max_speed >= 5000)) {
-			phylink_set(mac_supported, 5000baseT_Full);
-		}
-		if (!max_speed || (max_speed >= 10000)) {
-			phylink_set(mac_supported, 10000baseSR_Full);
-			phylink_set(mac_supported, 10000baseLR_Full);
-			phylink_set(mac_supported, 10000baseER_Full);
-			phylink_set(mac_supported, 10000baseLRM_Full);
-			phylink_set(mac_supported, 10000baseT_Full);
-			phylink_set(mac_supported, 10000baseKX4_Full);
-			phylink_set(mac_supported, 10000baseKR_Full);
-		}
-		if (!max_speed || (max_speed >= 25000)) {
-			phylink_set(mac_supported, 25000baseCR_Full);
-			phylink_set(mac_supported, 25000baseKR_Full);
-			phylink_set(mac_supported, 25000baseSR_Full);
-		}
-		if (!max_speed || (max_speed >= 40000)) {
-			phylink_set(mac_supported, 40000baseKR4_Full);
-			phylink_set(mac_supported, 40000baseCR4_Full);
-			phylink_set(mac_supported, 40000baseSR4_Full);
-			phylink_set(mac_supported, 40000baseLR4_Full);
-		}
-		if (!max_speed || (max_speed >= 50000)) {
-			phylink_set(mac_supported, 50000baseCR2_Full);
-			phylink_set(mac_supported, 50000baseKR2_Full);
-			phylink_set(mac_supported, 50000baseSR2_Full);
-			phylink_set(mac_supported, 50000baseKR_Full);
-			phylink_set(mac_supported, 50000baseSR_Full);
-			phylink_set(mac_supported, 50000baseCR_Full);
-			phylink_set(mac_supported, 50000baseLR_ER_FR_Full);
-			phylink_set(mac_supported, 50000baseDR_Full);
-		}
-		if (!max_speed || (max_speed >= 100000)) {
-			phylink_set(mac_supported, 100000baseKR4_Full);
-			phylink_set(mac_supported, 100000baseSR4_Full);
-			phylink_set(mac_supported, 100000baseCR4_Full);
-			phylink_set(mac_supported, 100000baseLR4_ER4_Full);
-			phylink_set(mac_supported, 100000baseKR2_Full);
-			phylink_set(mac_supported, 100000baseSR2_Full);
-			phylink_set(mac_supported, 100000baseCR2_Full);
-			phylink_set(mac_supported, 100000baseLR2_ER2_FR2_Full);
-			phylink_set(mac_supported, 100000baseDR2_Full);
-		}
-	}
-
-	/* Half-Duplex can only work with single queue */
-	if (tx_cnt > 1) {
-		phylink_set(mask, 10baseT_Half);
-		phylink_set(mask, 100baseT_Half);
-		phylink_set(mask, 1000baseT_Half);
-	}
+	phylink_get_linkmodes(mac_supported, PHY_INTERFACE_MODE_INTERNAL,
+			      config->mac_capabilities);
 
 	linkmode_and(supported, supported, mac_supported);
-	linkmode_andnot(supported, supported, mask);
-
 	linkmode_and(state->advertising, state->advertising, mac_supported);
-	linkmode_andnot(state->advertising, state->advertising, mask);
 
 	/* If PCS is supported, check which modes it supports. */
 	if (priv->hw->xpcs)
@@ -1253,6 +1180,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 {
 	struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
 	struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
+	int max_speed = priv->plat->max_speed;
 	int mode = priv->plat->phy_interface;
 	struct phylink *phylink;
 
@@ -1266,6 +1194,37 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (!fwnode)
 		fwnode = dev_fwnode(priv->device);
 
+	priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+		MAC_10 | MAC_100;
+
+	if (!max_speed || max_speed >= 1000)
+		priv->phylink_config.mac_capabilities |= MAC_1000;
+
+	if (priv->plat->has_gmac4) {
+		if (!max_speed || max_speed >= 2500)
+			priv->phylink_config.mac_capabilities |= MAC_2500FD;
+	} else if (priv->plat->has_xgmac) {
+		if (!max_speed || max_speed >= 2500)
+			priv->phylink_config.mac_capabilities |= MAC_2500FD;
+		if (!max_speed || max_speed >= 5000)
+			priv->phylink_config.mac_capabilities |= MAC_5000FD;
+		if (!max_speed || max_speed >= 10000)
+			priv->phylink_config.mac_capabilities |= MAC_10000FD;
+		if (!max_speed || max_speed >= 25000)
+			priv->phylink_config.mac_capabilities |= MAC_25000FD;
+		if (!max_speed || max_speed >= 40000)
+			priv->phylink_config.mac_capabilities |= MAC_40000FD;
+		if (!max_speed || max_speed >= 50000)
+			priv->phylink_config.mac_capabilities |= MAC_50000FD;
+		if (!max_speed || max_speed >= 100000)
+			priv->phylink_config.mac_capabilities |= MAC_100000FD;
+	}
+
+	/* Half-Duplex can only work with single queue */
+	if (priv->plat->tx_queues_to_use > 1)
+		priv->phylink_config.mac_capabilities &=
+			~(MAC_10HD | MAC_100HD | MAC_1000HD);
+
 	phylink = phylink_create(&priv->phylink_config, fwnode,
 				 mode, &stmmac_phylink_mac_ops);
 	if (IS_ERR(phylink))
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:05 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:05 +0000
Subject: [PATCH net-next v2 3/7] net: stmmac: fill in supported_interfaces
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfV7-005Rd9-CJ@rmk-PC.armlinux.org.uk>

Fill in phylink's supported_interfaces bitmap with the PHY interface
modes which can be used to talk to the PHY.

We indicate that the PHY interface mode passed in platform data is
always supported, as this is the initial mode passed into phylink.
When there is no PCS specified, we assume that this is the only mode
that is supported - indeed, the driver appears not to support dynamic
switching of interface types at present.

When a xpcs is present, it defines the PHY interface modes that the
stmmac driver can support. Request the supported interfaces from the
xpcs driver, and pass them to phylink.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e85ca75d394d..bd20920daf7b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1194,6 +1194,14 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (!fwnode)
 		fwnode = dev_fwnode(priv->device);
 
+	/* Set the platform/firmware specified interface mode */
+	__set_bit(mode, priv->phylink_config.supported_interfaces);
+
+	/* If we have an xpcs, it defines which PHY interfaces are supported. */
+	if (priv->hw->xpcs)
+		xpcs_get_interfaces(priv->hw->xpcs,
+				    priv->phylink_config.supported_interfaces);
+
 	priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
 		MAC_10 | MAC_100;
 
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:10 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:10 +0000
Subject: [PATCH net-next v2 4/7] net: stmmac/xpcs: convert to pcs_validate()
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfVC-005RdF-FZ@rmk-PC.armlinux.org.uk>

stmmac explicitly calls the xpcs driver to validate the ethtool
linkmodes. This is no longer necessary as phylink now supports
validation through a PCS method. Convert both drivers to use this
new mechanism.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL
Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c |  5 ----
 drivers/net/pcs/pcs-xpcs.c                    | 27 ++++++++-----------
 include/linux/pcs/pcs-xpcs.h                  |  2 --
 3 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index bd20920daf7b..029f21b9d452 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -940,7 +940,6 @@ static void stmmac_validate(struct phylink_config *config,
 			    unsigned long *supported,
 			    struct phylink_link_state *state)
 {
-	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
 
 	/* This is very similar to phylink_generic_validate() except that
@@ -958,10 +957,6 @@ static void stmmac_validate(struct phylink_config *config,
 
 	linkmode_and(supported, supported, mac_supported);
 	linkmode_and(state->advertising, state->advertising, mac_supported);
-
-	/* If PCS is supported, check which modes it supports. */
-	if (priv->hw->xpcs)
-		xpcs_validate(priv->hw->xpcs, supported, state);
 }
 
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index f45821524fab..61418d4dc0cd 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -632,35 +632,29 @@ static void xpcs_resolve_pma(struct dw_xpcs *xpcs,
 	}
 }
 
-void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
-		   struct phylink_link_state *state)
+static int xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+			 const struct phylink_link_state *state)
 {
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported);
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported) = { 0, };
 	const struct xpcs_compat *compat;
+	struct dw_xpcs *xpcs;
 	int i;
 
-	/* phylink expects us to report all supported modes with
-	 * PHY_INTERFACE_MODE_NA, just don't limit the supported and
-	 * advertising masks and exit.
-	 */
-	if (state->interface == PHY_INTERFACE_MODE_NA)
-		return;
-
-	linkmode_zero(xpcs_supported);
-
+	xpcs = phylink_pcs_to_xpcs(pcs);
 	compat = xpcs_find_compat(xpcs->id, state->interface);
 
-	/* Populate the supported link modes for this
-	 * PHY interface type
+	/* Populate the supported link modes for this PHY interface type.
+	 * FIXME: what about the port modes and autoneg bit? This masks
+	 * all those away.
 	 */
 	if (compat)
 		for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
 			set_bit(compat->supported[i], xpcs_supported);
 
 	linkmode_and(supported, supported, xpcs_supported);
-	linkmode_and(state->advertising, state->advertising, xpcs_supported);
+
+	return 0;
 }
-EXPORT_SYMBOL_GPL(xpcs_validate);
 
 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces)
 {
@@ -1120,6 +1114,7 @@ static const struct xpcs_id xpcs_id_list[] = {
 };
 
 static const struct phylink_pcs_ops xpcs_phylink_ops = {
+	.pcs_validate = xpcs_validate,
 	.pcs_config = xpcs_config,
 	.pcs_get_state = xpcs_get_state,
 	.pcs_link_up = xpcs_link_up,
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index 3126a4924d92..266eb26fb029 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -31,8 +31,6 @@ void xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
 		  phy_interface_t interface, int speed, int duplex);
 int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface,
 		   unsigned int mode);
-void xpcs_validate(struct dw_xpcs *xpcs, unsigned long *supported,
-		   struct phylink_link_state *state);
 void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces);
 int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns,
 		    int enable);
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:15 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:15 +0000
Subject: [PATCH net-next v2 5/7] net: stmmac: remove phylink_config.pcs_poll
 usage
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfVH-005RdO-Ik@rmk-PC.armlinux.org.uk>

Phylink will use PCS polling whenever the PCS's poll member is set, so
setting phylink_config.pcs_poll as well is redundant.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 029f21b9d452..1b6bba656709 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -1181,7 +1181,6 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 
 	priv->phylink_config.dev = &priv->dev->dev;
 	priv->phylink_config.type = PHYLINK_NETDEV;
-	priv->phylink_config.pcs_poll = true;
 	if (priv->plat->mdio_bus_data)
 		priv->phylink_config.ovr_an_inband =
 			mdio_bus_data->xpcs_an_inband;
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:20 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:20 +0000
Subject: [PATCH net-next v2 6/7] net: stmmac: convert to
 phylink_generic_validate()
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfVM-005RdX-MF@rmk-PC.armlinux.org.uk>

Convert stmmac to use phylink_generic_validate() now that we have the
MAC capabilities and supported interfaces filled in, and we have the
PCS validation handled via the PCS operations.

Tested-by: Wong Vee Khee <vee.khee.wong at linux.intel.com> # Intel EHL            Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 .../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +------------------
 1 file changed, 1 insertion(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1b6bba656709..0fd96a98f489 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -936,29 +936,6 @@ static void stmmac_mac_flow_ctrl(struct stmmac_priv *priv, u32 duplex)
 			priv->pause, tx_cnt);
 }
 
-static void stmmac_validate(struct phylink_config *config,
-			    unsigned long *supported,
-			    struct phylink_link_state *state)
-{
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
-
-	/* This is very similar to phylink_generic_validate() except that
-	 * we always use PHY_INTERFACE_MODE_INTERNAL to get all capabilities.
-	 * This is because we don't always have config->supported_interfaces
-	 * populated (only when we have the XPCS.)
-	 *
-	 * When we do have an XPCS, we could pass state->interface, as XPCS
-	 * limits to a subset of the ethtool link modes allowed here.
-	 */
-	phylink_set(mac_supported, Autoneg);
-	phylink_set_port_modes(mac_supported);
-	phylink_get_linkmodes(mac_supported, PHY_INTERFACE_MODE_INTERNAL,
-			      config->mac_capabilities);
-
-	linkmode_and(supported, supported, mac_supported);
-	linkmode_and(state->advertising, state->advertising, mac_supported);
-}
-
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
 			      const struct phylink_link_state *state)
 {
@@ -1095,7 +1072,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 }
 
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
-	.validate = stmmac_validate,
+	.validate = phylink_generic_validate,
 	.mac_config = stmmac_mac_config,
 	.mac_link_down = stmmac_mac_link_down,
 	.mac_link_up = stmmac_mac_link_up,
-- 
2.30.2



From rmk+kernel at armlinux.org.uk  Wed Jan 26 02:26:25 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 10:26:25 +0000
Subject: [PATCH net-next v2 7/7] net: stmmac: use .mac_select_pcs() interface
In-Reply-To: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
References: <YfEhaK7VtJ4oru03@shell.armlinux.org.uk>
Message-ID: <E1nCfVR-005Rdd-Pq@rmk-PC.armlinux.org.uk>

Convert stmmac to use the mac_select_pcs() interface rather than using
phylink_set_pcs(). The intention here is to unify the approach for PCS
and eventually to remove phylink_set_pcs().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 0fd96a98f489..e4381e13dae5 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -936,6 +936,17 @@ static void stmmac_mac_flow_ctrl(struct stmmac_priv *priv, u32 duplex)
 			priv->pause, tx_cnt);
 }
 
+static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config,
+						 phy_interface_t interface)
+{
+	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
+
+	if (!priv->hw->xpcs)
+		return NULL;
+
+	return &priv->hw->xpcs->pcs;
+}
+
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
 			      const struct phylink_link_state *state)
 {
@@ -1073,6 +1084,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
 
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
 	.validate = phylink_generic_validate,
+	.mac_select_pcs = stmmac_mac_select_pcs,
 	.mac_config = stmmac_mac_config,
 	.mac_link_down = stmmac_mac_link_down,
 	.mac_link_up = stmmac_mac_link_up,
@@ -1209,9 +1221,6 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
 	if (IS_ERR(phylink))
 		return PTR_ERR(phylink);
 
-	if (priv->hw->xpcs)
-		phylink_set_pcs(phylink, &priv->hw->xpcs->pcs);
-
 	priv->phylink = phylink;
 	return 0;
 }
-- 
2.30.2



From sudeep.holla at arm.com  Wed Jan 26 02:26:34 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Jan 2022 10:26:34 +0000
Subject: [PATCH] arm64: dts: juno: Remove GICv2m dma-range
In-Reply-To: <856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com>
References: <856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com>
Message-ID: <164319269169.2046287.10837792007397050176.b4-ty@arm.com>

On Mon, 24 Jan 2022 17:57:01 +0000, Robin Murphy wrote:
> Although it is painstakingly honest to describe all 3 PCI windows in
> "dma-ranges", it misses the the subtle distinction that the window for
> the GICv2m range is normally programmed for Device memory attributes
> rather than Normal Cacheable like the DRAM windows. Since MMU-401 only
> offers stage 2 translation, this means that when the PCI SMMU is
> enabled, accesses through that IPA range unexpectedly lose coherency if
> mapped as cacheable at the SMMU, due to the attribute combining rules.
> Since an extra 256KB is neither here nor there when we still have 10GB
> worth of usable address space, rather than attempting to describe and
> cope with this detail let's just remove the offending range. If the SMMU
> is not used then it makes no difference anyway.
> 
> [...]

Applied to sudeep.holla/linux (for-next/juno), thanks!


[1/1] arm64: dts: juno: Remove GICv2m dma-range
      https://git.kernel.org/sudeep.holla/c/31eeb6b09f

--

Regards,
Sudeep



From Jianyong.Wu at arm.com  Wed Jan 26 02:28:17 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Wed, 26 Jan 2022 10:28:17 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
Message-ID: <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi David,

> -----Original Message-----
> From: David Hildenbrand <david at redhat.com>
> Sent: Wednesday, January 26, 2022 6:18 PM
> To: Ard Biesheuvel <ardb at kernel.org>; Jianyong Wu
> <Jianyong.Wu at arm.com>
> Cc: Justin He <Justin.He at arm.com>; Catalin Marinas
> <Catalin.Marinas at arm.com>; will at kernel.org; Anshuman Khandual
> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
> quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On 26.01.22 11:12, Ard Biesheuvel wrote:
> > On Wed, 26 Jan 2022 at 11:09, Jianyong Wu <Jianyong.Wu at arm.com>
> wrote:
> >>
> >> Hi Ard,
> >>
> >>> -----Original Message-----
> >>> From: Ard Biesheuvel <ardb at kernel.org>
> >>> Sent: Wednesday, January 26, 2022 4:37 PM
> >>> To: Justin He <Justin.He at arm.com>
> >>> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
> >>> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
> >>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
> >>> david at redhat.com; quic_qiancai at quicinc.com; linux-
> >>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> >>> gshan at redhat.com; nd <nd at arm.com>
> >>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
> >>> create pud mapping
> >>>
> >>> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
> >>>>
> >>>> Hi Catalin
> >>>>
> >>>>> -----Original Message-----
> >>>>> From: Catalin Marinas <catalin.marinas at arm.com>
> >>>>> Sent: Friday, January 7, 2022 6:43 PM
> >>>>> To: Jianyong Wu <Jianyong.Wu at arm.com>
> >>>>> Cc: will at kernel.org; Anshuman Khandual
> >>> <Anshuman.Khandual at arm.com>;
> >>>>> akpm at linux-foundation.org; david at redhat.com;
> >>>>> quic_qiancai at quicinc.com; ardb at kernel.org;
> >>>>> linux-kernel at vger.kernel.org; linux-arm-
> >>>>> kernel at lists.infradead.org; gshan at redhat.com; Justin He
> >>>>> <Justin.He at arm.com>; nd <nd at arm.com>
> >>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
> >>>>> create pud mapping
> >>>>>
> >>>>> On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> >>>>>> Hi Catalin,
> >>>>>>
> >>>>>> I roughly find the root cause.
> >>>>>>  alloc_init_pud will be called at the very beginning of kernel
> >>>>>> boot in
> >>>>> create_mapping_noalloc where no memory allocator is initialized.
> >>>>> But lockdep check may need allocate memory. So, kernel take
> >>>>> exception when acquire lock.(I have not found the exact code that
> >>>>> cause this
> >>>>> issue) that's say we may not be able to use a lock so early.
> >>>>>>
> >>>>>> I come up with 2 methods to address it.
> >>>>>> 1) skip dead lock check at the very beginning of kernel boot in
> >>>>>> lockdep
> >>>>> code.
> >>>>>> 2) provided 2 two versions of __create_pgd_mapping, one with lock
> >>>>>> in it and the other without. There may be no possible of race for
> >>>>>> memory mapping at the very beginning time of kernel boot, thus we
> >>>>>> can use the no lock version of __create_pgd_mapping safely.
> >>>>>> In my test, this issue is gone if there is no lock held in
> >>>>>> create_mapping_noalloc. I think create_mapping_noalloc is called
> >>>>>> early enough to avoid the race conditions of memory mapping,
> >>>>>> however, I have not proved it.
> >>>>>
> >>>>> I think method 2 would work better but rather than implementing
> >>>>> new nolock functions I'd add a NO_LOCK flag and check it in
> >>>>> alloc_init_pud() before mutex_lock/unlock. Also add a comment
> when
> >>>>> passing the NO_LOCK flag on why it's needed and why there wouldn't
> >>>>> be any races at that stage (early boot etc.)
> >>>>>
> >>>> The problematic code path is:
> >>>> __primary_switched
> >>>>         early_fdt_map->fixmap_remap_fdt
> >>>>                 create_mapping_noalloc->alloc_init_pud
> >>>>                         mutex_lock (with Jianyong's patch)
> >>>>
> >>>> The problem seems to be that we will clear BSS segment twice if
> >>>> kaslr is enabled. Hence, some of the static variables in lockdep
> >>>> init process were messed up. That is to said, with kaslr enabled we
> >>>> might initialize lockdep twice if we add mutex_lock/unlock in
> alloc_init_pud().
> >>>>
> >>>
> >>> Thanks for tracking that down.
> >>>
> >>> Note that clearing the BSS twice is not the root problem here. The
> >>> root problem is that we set global state while the kernel runs at
> >>> the default link time address, and then refer to it again after the
> >>> entire kernel has been shifted in the kernel VA space. Such global
> >>> state could consist of mutable pointers to statically allocated data
> >>> (which would be reset to their default values after the relocation code
> runs again), or global pointer variables in BSS.
> >>> In either case, relying on such a global variable after the second
> >>> relocation performed by KASLR would be risky, and so we should avoid
> >>> manipulating global state at all if it might involve pointer to
> >>> statically allocated data structures.
> >>>
> >>>> In other ways, if we invoke mutex_lock/unlock in such a early booting
> stage.
> >>>> It might be unsafe because lockdep inserts lock_acquire/release as
> >>>> the complex hooks.
> >>>>
> >>>> In summary, would it better if Jianyong splits these early boot and
> >>>> late boot case? e.g. introduce a nolock version for
> >>> create_mapping_noalloc().
> >>>>
> >>>> What do you think of it?
> >>>>
> >>>
> >>> The pre-KASLR case definitely doesn't need a lock. But given that
> >>> create_mapping_noalloc() is only used to map the FDT, which happens
> >>> very early one way or the other, wouldn't it be better to move the
> >>> lock/unlock into other callers of __create_pgd_mapping()? (and make
> >>> sure no other users of the fixmap slots exist)
> >>
> >> There are server callers of __create_pgd_mapping. I think some of them
> need no fixmap lock as they are called so early. I figure out all of them here:
> >> create_mapping_noalloc:   no lock
> >> create_pgd_mapping:   no lock
> >> __map_memblock:    no lock
> >> map_kernel_segment:  no lock
> >> map_entry_trampoline: no lock
> >> update_mapping_prot:    need lock
> >> arch_add_memory:  need lock
> >>
> >> WDYT?
> >>
> >
> > That seems reasonable, but it needs to be documented clearly in the code.
> >
> 
> Just a random thought, could we rely on system_state to do the locking
> conditionally?

I can't see the point. At the early stages of kernel boot, we definitely need no lock. Also, I think we should keep it simple.

Thanks
Jianyong

> 
> --
> Thanks,
> 
> David / dhildenb


From david at redhat.com  Wed Jan 26 02:30:52 2022
From: david at redhat.com (David Hildenbrand)
Date: Wed, 26 Jan 2022 11:30:52 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>

On 26.01.22 11:28, Jianyong Wu wrote:
> Hi David,
> 
>> -----Original Message-----
>> From: David Hildenbrand <david at redhat.com>
>> Sent: Wednesday, January 26, 2022 6:18 PM
>> To: Ard Biesheuvel <ardb at kernel.org>; Jianyong Wu
>> <Jianyong.Wu at arm.com>
>> Cc: Justin He <Justin.He at arm.com>; Catalin Marinas
>> <Catalin.Marinas at arm.com>; will at kernel.org; Anshuman Khandual
>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
>> quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org; linux-arm-
>> kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
>> pud mapping
>>
>> On 26.01.22 11:12, Ard Biesheuvel wrote:
>>> On Wed, 26 Jan 2022 at 11:09, Jianyong Wu <Jianyong.Wu at arm.com>
>> wrote:
>>>>
>>>> Hi Ard,
>>>>
>>>>> -----Original Message-----
>>>>> From: Ard Biesheuvel <ardb at kernel.org>
>>>>> Sent: Wednesday, January 26, 2022 4:37 PM
>>>>> To: Justin He <Justin.He at arm.com>
>>>>> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
>>>>> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
>>>>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
>>>>> david at redhat.com; quic_qiancai at quicinc.com; linux-
>>>>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>> gshan at redhat.com; nd <nd at arm.com>
>>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
>>>>> create pud mapping
>>>>>
>>>>> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
>>>>>>
>>>>>> Hi Catalin
>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Catalin Marinas <catalin.marinas at arm.com>
>>>>>>> Sent: Friday, January 7, 2022 6:43 PM
>>>>>>> To: Jianyong Wu <Jianyong.Wu at arm.com>
>>>>>>> Cc: will at kernel.org; Anshuman Khandual
>>>>> <Anshuman.Khandual at arm.com>;
>>>>>>> akpm at linux-foundation.org; david at redhat.com;
>>>>>>> quic_qiancai at quicinc.com; ardb at kernel.org;
>>>>>>> linux-kernel at vger.kernel.org; linux-arm-
>>>>>>> kernel at lists.infradead.org; gshan at redhat.com; Justin He
>>>>>>> <Justin.He at arm.com>; nd <nd at arm.com>
>>>>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
>>>>>>> create pud mapping
>>>>>>>
>>>>>>> On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
>>>>>>>> Hi Catalin,
>>>>>>>>
>>>>>>>> I roughly find the root cause.
>>>>>>>>  alloc_init_pud will be called at the very beginning of kernel
>>>>>>>> boot in
>>>>>>> create_mapping_noalloc where no memory allocator is initialized.
>>>>>>> But lockdep check may need allocate memory. So, kernel take
>>>>>>> exception when acquire lock.(I have not found the exact code that
>>>>>>> cause this
>>>>>>> issue) that's say we may not be able to use a lock so early.
>>>>>>>>
>>>>>>>> I come up with 2 methods to address it.
>>>>>>>> 1) skip dead lock check at the very beginning of kernel boot in
>>>>>>>> lockdep
>>>>>>> code.
>>>>>>>> 2) provided 2 two versions of __create_pgd_mapping, one with lock
>>>>>>>> in it and the other without. There may be no possible of race for
>>>>>>>> memory mapping at the very beginning time of kernel boot, thus we
>>>>>>>> can use the no lock version of __create_pgd_mapping safely.
>>>>>>>> In my test, this issue is gone if there is no lock held in
>>>>>>>> create_mapping_noalloc. I think create_mapping_noalloc is called
>>>>>>>> early enough to avoid the race conditions of memory mapping,
>>>>>>>> however, I have not proved it.
>>>>>>>
>>>>>>> I think method 2 would work better but rather than implementing
>>>>>>> new nolock functions I'd add a NO_LOCK flag and check it in
>>>>>>> alloc_init_pud() before mutex_lock/unlock. Also add a comment
>> when
>>>>>>> passing the NO_LOCK flag on why it's needed and why there wouldn't
>>>>>>> be any races at that stage (early boot etc.)
>>>>>>>
>>>>>> The problematic code path is:
>>>>>> __primary_switched
>>>>>>         early_fdt_map->fixmap_remap_fdt
>>>>>>                 create_mapping_noalloc->alloc_init_pud
>>>>>>                         mutex_lock (with Jianyong's patch)
>>>>>>
>>>>>> The problem seems to be that we will clear BSS segment twice if
>>>>>> kaslr is enabled. Hence, some of the static variables in lockdep
>>>>>> init process were messed up. That is to said, with kaslr enabled we
>>>>>> might initialize lockdep twice if we add mutex_lock/unlock in
>> alloc_init_pud().
>>>>>>
>>>>>
>>>>> Thanks for tracking that down.
>>>>>
>>>>> Note that clearing the BSS twice is not the root problem here. The
>>>>> root problem is that we set global state while the kernel runs at
>>>>> the default link time address, and then refer to it again after the
>>>>> entire kernel has been shifted in the kernel VA space. Such global
>>>>> state could consist of mutable pointers to statically allocated data
>>>>> (which would be reset to their default values after the relocation code
>> runs again), or global pointer variables in BSS.
>>>>> In either case, relying on such a global variable after the second
>>>>> relocation performed by KASLR would be risky, and so we should avoid
>>>>> manipulating global state at all if it might involve pointer to
>>>>> statically allocated data structures.
>>>>>
>>>>>> In other ways, if we invoke mutex_lock/unlock in such a early booting
>> stage.
>>>>>> It might be unsafe because lockdep inserts lock_acquire/release as
>>>>>> the complex hooks.
>>>>>>
>>>>>> In summary, would it better if Jianyong splits these early boot and
>>>>>> late boot case? e.g. introduce a nolock version for
>>>>> create_mapping_noalloc().
>>>>>>
>>>>>> What do you think of it?
>>>>>>
>>>>>
>>>>> The pre-KASLR case definitely doesn't need a lock. But given that
>>>>> create_mapping_noalloc() is only used to map the FDT, which happens
>>>>> very early one way or the other, wouldn't it be better to move the
>>>>> lock/unlock into other callers of __create_pgd_mapping()? (and make
>>>>> sure no other users of the fixmap slots exist)
>>>>
>>>> There are server callers of __create_pgd_mapping. I think some of them
>> need no fixmap lock as they are called so early. I figure out all of them here:
>>>> create_mapping_noalloc:   no lock
>>>> create_pgd_mapping:   no lock
>>>> __map_memblock:    no lock
>>>> map_kernel_segment:  no lock
>>>> map_entry_trampoline: no lock
>>>> update_mapping_prot:    need lock
>>>> arch_add_memory:  need lock
>>>>
>>>> WDYT?
>>>>
>>>
>>> That seems reasonable, but it needs to be documented clearly in the code.
>>>
>>
>> Just a random thought, could we rely on system_state to do the locking
>> conditionally?
> 
> I can't see the point. At the early stages of kernel boot, we definitely need no lock. Also, I think we should keep it simple.
> 

Is e.g.,

if (system_state < SYSTEM_RUNNING)
	/* lock */

if (system_state < SYSTEM_RUNNING)
	/* unlock */

more complicated than checking individual users and eventually getting
it wrong?

> Thanks
> Jianyong


-- 
Thanks,

David / dhildenb



From david at redhat.com  Wed Jan 26 02:31:46 2022
From: david at redhat.com (David Hildenbrand)
Date: Wed, 26 Jan 2022 11:31:46 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
Message-ID: <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>

On 26.01.22 11:30, David Hildenbrand wrote:
> On 26.01.22 11:28, Jianyong Wu wrote:
>> Hi David,
>>
>>> -----Original Message-----
>>> From: David Hildenbrand <david at redhat.com>
>>> Sent: Wednesday, January 26, 2022 6:18 PM
>>> To: Ard Biesheuvel <ardb at kernel.org>; Jianyong Wu
>>> <Jianyong.Wu at arm.com>
>>> Cc: Justin He <Justin.He at arm.com>; Catalin Marinas
>>> <Catalin.Marinas at arm.com>; will at kernel.org; Anshuman Khandual
>>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
>>> quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org; linux-arm-
>>> kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
>>> pud mapping
>>>
>>> On 26.01.22 11:12, Ard Biesheuvel wrote:
>>>> On Wed, 26 Jan 2022 at 11:09, Jianyong Wu <Jianyong.Wu at arm.com>
>>> wrote:
>>>>>
>>>>> Hi Ard,
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Ard Biesheuvel <ardb at kernel.org>
>>>>>> Sent: Wednesday, January 26, 2022 4:37 PM
>>>>>> To: Justin He <Justin.He at arm.com>
>>>>>> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
>>>>>> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
>>>>>> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
>>>>>> david at redhat.com; quic_qiancai at quicinc.com; linux-
>>>>>> kernel at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
>>>>>> gshan at redhat.com; nd <nd at arm.com>
>>>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
>>>>>> create pud mapping
>>>>>>
>>>>>> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
>>>>>>>
>>>>>>> Hi Catalin
>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: Catalin Marinas <catalin.marinas at arm.com>
>>>>>>>> Sent: Friday, January 7, 2022 6:43 PM
>>>>>>>> To: Jianyong Wu <Jianyong.Wu at arm.com>
>>>>>>>> Cc: will at kernel.org; Anshuman Khandual
>>>>>> <Anshuman.Khandual at arm.com>;
>>>>>>>> akpm at linux-foundation.org; david at redhat.com;
>>>>>>>> quic_qiancai at quicinc.com; ardb at kernel.org;
>>>>>>>> linux-kernel at vger.kernel.org; linux-arm-
>>>>>>>> kernel at lists.infradead.org; gshan at redhat.com; Justin He
>>>>>>>> <Justin.He at arm.com>; nd <nd at arm.com>
>>>>>>>> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
>>>>>>>> create pud mapping
>>>>>>>>
>>>>>>>> On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
>>>>>>>>> Hi Catalin,
>>>>>>>>>
>>>>>>>>> I roughly find the root cause.
>>>>>>>>>  alloc_init_pud will be called at the very beginning of kernel
>>>>>>>>> boot in
>>>>>>>> create_mapping_noalloc where no memory allocator is initialized.
>>>>>>>> But lockdep check may need allocate memory. So, kernel take
>>>>>>>> exception when acquire lock.(I have not found the exact code that
>>>>>>>> cause this
>>>>>>>> issue) that's say we may not be able to use a lock so early.
>>>>>>>>>
>>>>>>>>> I come up with 2 methods to address it.
>>>>>>>>> 1) skip dead lock check at the very beginning of kernel boot in
>>>>>>>>> lockdep
>>>>>>>> code.
>>>>>>>>> 2) provided 2 two versions of __create_pgd_mapping, one with lock
>>>>>>>>> in it and the other without. There may be no possible of race for
>>>>>>>>> memory mapping at the very beginning time of kernel boot, thus we
>>>>>>>>> can use the no lock version of __create_pgd_mapping safely.
>>>>>>>>> In my test, this issue is gone if there is no lock held in
>>>>>>>>> create_mapping_noalloc. I think create_mapping_noalloc is called
>>>>>>>>> early enough to avoid the race conditions of memory mapping,
>>>>>>>>> however, I have not proved it.
>>>>>>>>
>>>>>>>> I think method 2 would work better but rather than implementing
>>>>>>>> new nolock functions I'd add a NO_LOCK flag and check it in
>>>>>>>> alloc_init_pud() before mutex_lock/unlock. Also add a comment
>>> when
>>>>>>>> passing the NO_LOCK flag on why it's needed and why there wouldn't
>>>>>>>> be any races at that stage (early boot etc.)
>>>>>>>>
>>>>>>> The problematic code path is:
>>>>>>> __primary_switched
>>>>>>>         early_fdt_map->fixmap_remap_fdt
>>>>>>>                 create_mapping_noalloc->alloc_init_pud
>>>>>>>                         mutex_lock (with Jianyong's patch)
>>>>>>>
>>>>>>> The problem seems to be that we will clear BSS segment twice if
>>>>>>> kaslr is enabled. Hence, some of the static variables in lockdep
>>>>>>> init process were messed up. That is to said, with kaslr enabled we
>>>>>>> might initialize lockdep twice if we add mutex_lock/unlock in
>>> alloc_init_pud().
>>>>>>>
>>>>>>
>>>>>> Thanks for tracking that down.
>>>>>>
>>>>>> Note that clearing the BSS twice is not the root problem here. The
>>>>>> root problem is that we set global state while the kernel runs at
>>>>>> the default link time address, and then refer to it again after the
>>>>>> entire kernel has been shifted in the kernel VA space. Such global
>>>>>> state could consist of mutable pointers to statically allocated data
>>>>>> (which would be reset to their default values after the relocation code
>>> runs again), or global pointer variables in BSS.
>>>>>> In either case, relying on such a global variable after the second
>>>>>> relocation performed by KASLR would be risky, and so we should avoid
>>>>>> manipulating global state at all if it might involve pointer to
>>>>>> statically allocated data structures.
>>>>>>
>>>>>>> In other ways, if we invoke mutex_lock/unlock in such a early booting
>>> stage.
>>>>>>> It might be unsafe because lockdep inserts lock_acquire/release as
>>>>>>> the complex hooks.
>>>>>>>
>>>>>>> In summary, would it better if Jianyong splits these early boot and
>>>>>>> late boot case? e.g. introduce a nolock version for
>>>>>> create_mapping_noalloc().
>>>>>>>
>>>>>>> What do you think of it?
>>>>>>>
>>>>>>
>>>>>> The pre-KASLR case definitely doesn't need a lock. But given that
>>>>>> create_mapping_noalloc() is only used to map the FDT, which happens
>>>>>> very early one way or the other, wouldn't it be better to move the
>>>>>> lock/unlock into other callers of __create_pgd_mapping()? (and make
>>>>>> sure no other users of the fixmap slots exist)
>>>>>
>>>>> There are server callers of __create_pgd_mapping. I think some of them
>>> need no fixmap lock as they are called so early. I figure out all of them here:
>>>>> create_mapping_noalloc:   no lock
>>>>> create_pgd_mapping:   no lock
>>>>> __map_memblock:    no lock
>>>>> map_kernel_segment:  no lock
>>>>> map_entry_trampoline: no lock
>>>>> update_mapping_prot:    need lock
>>>>> arch_add_memory:  need lock
>>>>>
>>>>> WDYT?
>>>>>
>>>>
>>>> That seems reasonable, but it needs to be documented clearly in the code.
>>>>
>>>
>>> Just a random thought, could we rely on system_state to do the locking
>>> conditionally?
>>
>> I can't see the point. At the early stages of kernel boot, we definitely need no lock. Also, I think we should keep it simple.
>>
> 
> Is e.g.,
> 
> if (system_state < SYSTEM_RUNNING)
> 	/* lock */
> 
> if (system_state < SYSTEM_RUNNING)
> 	/* unlock */

of course, inverting the conditions ;)


-- 
Thanks,

David / dhildenb



From sudeep.holla at arm.com  Wed Jan 26 02:36:14 2022
From: sudeep.holla at arm.com (Sudeep Holla)
Date: Wed, 26 Jan 2022 10:36:14 +0000
Subject: [PATCH 5/8] arm64: Create cache sysfs directory without ACPI
 PPTT for hardware prefetch control
In-Reply-To: <20220125071414.811344-6-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
 <20220125071414.811344-6-tarumizu.kohei@fujitsu.com>
Message-ID: <20220126103614.pcrcuc2kzklkq3xa@bogus>

On Tue, Jan 25, 2022 at 04:14:11PM +0900, Kohei Tarumizu wrote:
> This patch will create a cache sysfs directory without ACPI PPTT if
> the CONFIG_HWPF_CONTROL is true.
> 
> Hardware prefetch control driver need cache sysfs directory and cache
> level/type information. In ARM processor, these information can be
> obtained from the register even without PPTT. Therefore, we set the
> cpu_map_populated to true to create cache sysfs directory if the
> machine doesn't have PPTT.

I am assuming this is ACPI enabled system.

This looks bit hacky in my opinion. Before I explore better way of adding it,
I would like to check if you have explored ways to add PPTT reading these
registers from UEFI/EDK2 as PPTT has other topology information which you will
need anyways. That would simplify handling of these cacheinfo sysfs in the
kernel. Let me know what are your thoughts ?

-- 
Regards,
Sudeep


From linux at armlinux.org.uk  Wed Jan 26 03:00:33 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 11:00:33 +0000
Subject: [PATCH net v2 4/6] ethernet: i825xx: don't write directly to
 netdev->dev_addr
In-Reply-To: <20220126003801.1736586-5-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
 <20220126003801.1736586-5-kuba@kernel.org>
Message-ID: <YfEp0bFb7MKwhmg+@shell.armlinux.org.uk>

On Tue, Jan 25, 2022 at 04:37:59PM -0800, Jakub Kicinski wrote:
> netdev->dev_addr is const now.
> 
> Compile tested rpc_defconfig w/ GCC 8.5.
> 
> Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Wed Jan 26 03:01:15 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 11:01:15 +0000
Subject: [PATCH net v2 5/6] ethernet: 8390/etherh: don't write directly
 to netdev->dev_addr
In-Reply-To: <20220126003801.1736586-6-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
 <20220126003801.1736586-6-kuba@kernel.org>
Message-ID: <YfEp+9mh64QE0BYf@shell.armlinux.org.uk>

On Tue, Jan 25, 2022 at 04:38:00PM -0800, Jakub Kicinski wrote:
> netdev->dev_addr is const now.
> 
> Compile tested rpc_defconfig w/ GCC 8.5.
> 
> Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From linux at armlinux.org.uk  Wed Jan 26 03:01:43 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 11:01:43 +0000
Subject: [PATCH net v2 6/6] ethernet: seeq/ether3: don't write directly
 to netdev->dev_addr
In-Reply-To: <20220126003801.1736586-7-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
 <20220126003801.1736586-7-kuba@kernel.org>
Message-ID: <YfEqF+IbPRhthS9p@shell.armlinux.org.uk>

On Tue, Jan 25, 2022 at 04:38:01PM -0800, Jakub Kicinski wrote:
> netdev->dev_addr is const now.
> 
> Compile tested rpc_defconfig w/ GCC 8.5.
> 
> Fixes: adeef3e32146 ("net: constify netdev->dev_addr")
> Signed-off-by: Jakub Kicinski <kuba at kernel.org>

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>

Thanks!

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From hverkuil-cisco at xs4all.nl  Wed Jan 26 03:03:07 2022
From: hverkuil-cisco at xs4all.nl (Hans Verkuil)
Date: Wed, 26 Jan 2022 12:03:07 +0100
Subject: [BUG] pinctrl: reg-fixed-voltage usb0-vbus: error -EINVAL: can't
 get GPIO
In-Reply-To: <2f82dbe8-50d6-d905-9065-d3869948aa06@xs4all.nl>
References: <Yea3rBmY+MO4AhhV@Red>
 <2f82dbe8-50d6-d905-9065-d3869948aa06@xs4all.nl>
Message-ID: <ef2317a5-d9a7-a663-2477-b435b777d4e0@xs4all.nl>

On 18/01/2022 15:13, Hans Verkuil wrote:
> On 1/18/22 13:50, Corentin Labbe wrote:
>> Hello
>>
>> As reported on old googlegroup sunxi mainling list, on linux-next-20220118, USB storage fail to bring up on orangepiPC.
>> We can see some error logs in dmesg:
>> reg-fixed-voltage usb0-vbus: error -EINVAL: can't get GPIO
>> reg-fixed-voltage: probe of usb0-vbus failed with error -22
>>
>> This is bisected to: 8df89a7cbc63c7598c00611ad17b67e8d5b4fad3 pinctrl-sunxi: don't call pinctrl_gpio_direction()
>>
>> Reverting this commit lead to a working USB storage being setuped.

Hopefully this is resolved by this patch:

https://patchwork.linuxtv.org/project/linux-media/patch/0f536cd8-01db-5d16-2cec-ec6d19409a49 at xs4all.nl/

Please test!

Regards,

	Hans

> 
> Hmm, I'll bet it's EPROBE_DEFER related.
> 
> The original call (pre that commit) of pinctrl_gpio_direction_output() checks
> if the pin controller could find the pin (pinctrl_get_device_gpio_range()).
> 
> That doesn't happen in the new code.
> 
> The sunxi appears to have two pincontrollers in the device tree (&pio and &r_pio),
> that might be part of the reason this is an issue here.
> 
> Linus, should there be a check somewhere for a missing pincontroller in
> gpiod_get_index()? I suspect that before my commit it was the gpiod_configure_flags
> call in that function that returned -EPROBE_DEFER, but I'm not completely certain.
> 
> If someone can give me a hint about what should be done, then I can make a patch.
> 
> The alternative is to revert this sunxi patch, but perhaps this is a deeper
> problem with these pincontroller drivers that set the direction directly
> instead of going through pinctrl_gpio_direction_output().
> 
> Corentin, it would help me if you can figure out where the EPROBE_DEFER is
> returned (pre-commit) in drivers/pinctrl/core.c. Probably pinctrl_get_device_gpio_range().
> 
> And I'd love to have the WARN_ON(1) output from just before the 'return -EPROBE_DEFER'.
> 
> Regards,
> 
> 	Hans
> 
>>
>> Regards



From linmq006 at gmail.com  Wed Jan 26 03:04:47 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Wed, 26 Jan 2022 11:04:47 +0000
Subject: [PATCH] spi: meson-spicc: add IRQ check in meson_spicc_probe
Message-ID: <20220126110447.24549-1-linmq006@gmail.com>

This check misses checking for  platform_get_irq()'s call and may passes
the negative error codes to devm_request_irq(), which takes unsigned IRQ #,
causing it to fail with -EINVAL, overriding an original error code.
Stop calling devm_request_irq() with invalid IRQ #s.

Fixes: 454fa271bc4e ("spi: Add Meson SPICC driver")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/spi/spi-meson-spicc.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index c208efeadd18..0bc7daa7afc8 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -693,6 +693,11 @@ static int meson_spicc_probe(struct platform_device *pdev)
 	writel_relaxed(0, spicc->base + SPICC_INTREG);
 
 	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = irq;
+		goto out_master;
+	}
+
 	ret = devm_request_irq(&pdev->dev, irq, meson_spicc_irq,
 			       0, NULL, spicc);
 	if (ret) {
-- 
2.17.1



From houtao1 at huawei.com  Wed Jan 26 03:10:58 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Wed, 26 Jan 2022 19:10:58 +0800
Subject: [PATCH bpf-next] bpf, arm64: enable kfunc call
In-Reply-To: <b54b3297-086c-1b64-1c25-01f70c6412af@iogearbox.net>
References: <20220119144942.305568-1-houtao1@huawei.com>
 <b54b3297-086c-1b64-1c25-01f70c6412af@iogearbox.net>
Message-ID: <67471472-d37f-2c56-2e9c-0030a02e1bd9@huawei.com>

Hi,

On 1/25/2022 12:21 AM, Daniel Borkmann wrote:
> On 1/19/22 3:49 PM, Hou Tao wrote:
>> Since commit b2eed9b58811 ("arm64/kernel: kaslr: reduce module
>> randomization range to 2 GB"), for arm64 whether KASLR is enabled
>> or not, the module is placed within 2GB of the kernel region, so
>> s32 in bpf_kfunc_desc is sufficient to represente the offset of
>> module function relative to __bpf_call_base. The only thing needed
>> is to override bpf_jit_supports_kfunc_call().
>>
>> Signed-off-by: Hou Tao <houtao1 at huawei.com>
>
> Lgtm, could we also add a BPF selftest to assert that this assumption
> won't break in future when bpf_jit_supports_kfunc_call() returns true?
>
> E.g. extending lib/test_bpf.ko could be an option, wdyt?
Make sense.? Will figure out how to done that.

Regards,
Tao
>
>> ---
>> ? arch/arm64/net/bpf_jit_comp.c | 5 +++++
>> ? 1 file changed, 5 insertions(+)
>>
>> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
>> index e96d4d87291f..74f9a9b6a053 100644
>> --- a/arch/arm64/net/bpf_jit_comp.c
>> +++ b/arch/arm64/net/bpf_jit_comp.c
>> @@ -1143,6 +1143,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog
>> *prog)
>> ????? return prog;
>> ? }
>> ? +bool bpf_jit_supports_kfunc_call(void)
>> +{
>> +??? return true;
>> +}
>> +
>> ? u64 bpf_jit_alloc_exec_limit(void)
>> ? {
>> ????? return VMALLOC_END - VMALLOC_START;
>>
>
> .



From john at metanate.com  Wed Jan 26 03:17:19 2022
From: john at metanate.com (John Keeping)
Date: Wed, 26 Jan 2022 11:17:19 +0000
Subject: [PATCH] ARM: dts: rockchip: fix MMC compatibles for rk3288
In-Reply-To: <7e935740-66a3-da07-a196-0584dab310b9@gmail.com>
References: <20220125115007.3138311-1-john@metanate.com>
 <7e935740-66a3-da07-a196-0584dab310b9@gmail.com>
Message-ID: <YfEtv+UIT7Y+d2lx@donbot>

Hi Johan,

On Tue, Jan 25, 2022 at 01:14:21PM +0100, Johan Jonker wrote:
> MMC aliases should go in the dts board files.
> Sort on reg address, based on availability and without number gab.
> (For rk3288 a lot of boards to change. That's why it wasn't done
> yet...Could someone pick that up?)

Since there aren't any mmc aliases for rk3288 at the moment, I'll drop
this and send a patch adding them for the one board I have access to.

At some point the nonstandard mshc aliases should be removed, but it
may be best to keep them around for a while given that 5.17 will be the
first kernel that doesn't use these as a weird mechanism for per-port
settings.

> On 1/25/22 12:50, John Keeping wrote:
> > Prior to commit 4bac670aa5cb ("mmc: dw_mmc: rockchip: use common_caps")
> > the mshcN aliases were used in an unusual way by the dw_mmc driver and
> > affected behaviour.  Now that this has been fixed, rename the mmc
> > aliases to use the standard form.
> > 
> > Signed-off-by: John Keeping <john at metanate.com>
> > ---
> >  arch/arm/boot/dts/rk3288.dtsi | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> > index aaaa61875701..50fa0a4652b5 100644
> > --- a/arch/arm/boot/dts/rk3288.dtsi
> > +++ b/arch/arm/boot/dts/rk3288.dtsi
> > @@ -25,10 +25,10 @@ aliases {
> >  		i2c3 = &i2c3;
> >  		i2c4 = &i2c4;
> >  		i2c5 = &i2c5;
> > -		mshc0 = &emmc;
> > -		mshc1 = &sdmmc;
> > -		mshc2 = &sdio0;
> > -		mshc3 = &sdio1;
> > +		mmc0 = &emmc;
> > +		mmc1 = &sdmmc;
> > +		mmc2 = &sdio0;
> > +		mmc3 = &sdio1;
> >  		serial0 = &uart0;
> >  		serial1 = &uart1;
> >  		serial2 = &uart2;


From apatel at ventanamicro.com  Wed Jan 26 03:44:44 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:44 +0530
Subject: [PATCH v10 0/8] RISC-V CPU Idle Support
Message-ID: <20220126114452.692512-1-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

This series adds RISC-V CPU Idle support using SBI HSM suspend function.
The RISC-V SBI CPU idle driver added by this series is highly inspired
from the ARM PSCI CPU idle driver.

At high-level, this series includes the following changes:
1) Preparatory arch/riscv patches (Patches 1 to 3)
2) Defines for RISC-V SBI HSM suspend (Patch 4)
3) Preparatory patch to share code between RISC-V SBI CPU idle driver
   and ARM PSCI CPU idle driver (Patch 5)
4) RISC-V SBI CPU idle driver and related DT bindings (Patches 6 to 7)

These patches can be found in riscv_sbi_hsm_suspend_v10 branch of
https://github.com/avpatel/linux.git

Special thanks Sandeep Tripathy for providing early feeback on SBI HSM
support in all above projects (RISC-V SBI specification, OpenSBI, and
Linux RISC-V).

Changes since v9:
 - Rebased on Linux-5.17-rc1

Changes since v8:
 - Rebased on Linux-5.15-rc5
 - Fixed DT schema check errors in PATCH7

Changes since v7:
 - Rebased on Linux-5.15-rc3
 - Renamed cpuidle-sbi.c to cpuidle-riscv-sbi.c in PATCH6

Changes since v6:
 - Fixed error reported by "make DT_CHECKER_FLAGS=-m dt_binding_check"

Changes since v5:
 - Rebased on Linux-5.13-rc5
 - Removed unnecessary exports from PATCH5
 - Removed stray ";" from PATCH5
 - Moved sbi_cpuidle_pd_power_off() under "#ifdef CONFIG_DT_IDLE_GENPD"
   in PATCH6

Changes since v4:
 - Rebased on Linux-5.13-rc2
 - Renamed all dt_idle_genpd functions to have "dt_idle_" prefix
 - Added MAINTAINERS file entry for dt_idle_genpd

Changes since v3:
 - Rebased on Linux-5.13-rc2
 - Fixed __cpu_resume_enter() which was broken due to XIP kernel support
 - Removed "struct dt_idle_genpd_ops" abstraction which simplifies code
   sharing between ARM PSCI and RISC-V SBI drivers in PATCH5

Changes since v2:
 - Rebased on Linux-5.12-rc3
 - Updated PATCH7 to add common DT bindings for both ARM and RISC-V
   idle states
 - Added "additionalProperties = false" for both idle-states node and
   child nodes in PATCH7

Changes since v1:
 - Fixex minor typo in PATCH1
 - Use just "idle-states" as DT node name for CPU idle states
 - Added documentation for "cpu-idle-states" DT property in
   devicetree/bindings/riscv/cpus.yaml
 - Added documentation for "riscv,sbi-suspend-param" DT property in
   devicetree/bindings/riscv/idle-states.yaml

Anup Patel (8):
  RISC-V: Enable CPU_IDLE drivers
  RISC-V: Rename relocate() and make it global
  RISC-V: Add arch functions for non-retentive suspend entry/exit
  RISC-V: Add SBI HSM suspend related defines
  cpuidle: Factor-out power domain related code from PSCI domain driver
  cpuidle: Add RISC-V SBI CPU idle driver
  dt-bindings: Add common bindings for ARM and RISC-V idle states
  RISC-V: Enable RISC-V SBI CPU Idle driver for QEMU virt machine

 .../bindings/arm/msm/qcom,idle-state.txt      |   2 +-
 .../devicetree/bindings/arm/psci.yaml         |   2 +-
 .../bindings/{arm => cpu}/idle-states.yaml    | 228 ++++++-
 .../devicetree/bindings/riscv/cpus.yaml       |   6 +
 MAINTAINERS                                   |  14 +
 arch/riscv/Kconfig                            |   7 +
 arch/riscv/Kconfig.socs                       |   3 +
 arch/riscv/configs/defconfig                  |   2 +
 arch/riscv/configs/rv32_defconfig             |   2 +
 arch/riscv/include/asm/asm.h                  |  27 +
 arch/riscv/include/asm/cpuidle.h              |  24 +
 arch/riscv/include/asm/sbi.h                  |  27 +-
 arch/riscv/include/asm/suspend.h              |  36 +
 arch/riscv/kernel/Makefile                    |   2 +
 arch/riscv/kernel/asm-offsets.c               |   3 +
 arch/riscv/kernel/cpu_ops_sbi.c               |   2 +-
 arch/riscv/kernel/head.S                      |  28 +-
 arch/riscv/kernel/process.c                   |   3 +-
 arch/riscv/kernel/suspend.c                   |  87 +++
 arch/riscv/kernel/suspend_entry.S             | 124 ++++
 arch/riscv/kvm/vcpu_sbi_hsm.c                 |   4 +-
 drivers/cpuidle/Kconfig                       |   9 +
 drivers/cpuidle/Kconfig.arm                   |   1 +
 drivers/cpuidle/Kconfig.riscv                 |  15 +
 drivers/cpuidle/Makefile                      |   5 +
 drivers/cpuidle/cpuidle-psci-domain.c         | 138 +---
 drivers/cpuidle/cpuidle-psci.h                |  15 +-
 drivers/cpuidle/cpuidle-riscv-sbi.c           | 627 ++++++++++++++++++
 drivers/cpuidle/dt_idle_genpd.c               | 178 +++++
 drivers/cpuidle/dt_idle_genpd.h               |  50 ++
 30 files changed, 1484 insertions(+), 187 deletions(-)
 rename Documentation/devicetree/bindings/{arm => cpu}/idle-states.yaml (74%)
 create mode 100644 arch/riscv/include/asm/cpuidle.h
 create mode 100644 arch/riscv/include/asm/suspend.h
 create mode 100644 arch/riscv/kernel/suspend.c
 create mode 100644 arch/riscv/kernel/suspend_entry.S
 create mode 100644 drivers/cpuidle/Kconfig.riscv
 create mode 100644 drivers/cpuidle/cpuidle-riscv-sbi.c
 create mode 100644 drivers/cpuidle/dt_idle_genpd.c
 create mode 100644 drivers/cpuidle/dt_idle_genpd.h

-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:45 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:45 +0530
Subject: [PATCH v10 1/8] RISC-V: Enable CPU_IDLE drivers
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-2-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

We force select CPU_PM and provide asm/cpuidle.h so that we can
use CPU IDLE drivers for Linux RISC-V kernel.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at vetanamicro.com>
---
 arch/riscv/Kconfig                |  7 +++++++
 arch/riscv/configs/defconfig      |  1 +
 arch/riscv/configs/rv32_defconfig |  1 +
 arch/riscv/include/asm/cpuidle.h  | 24 ++++++++++++++++++++++++
 arch/riscv/kernel/process.c       |  3 ++-
 5 files changed, 35 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/include/asm/cpuidle.h

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5adcbd9b5e88..76976d12b463 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -46,6 +46,7 @@ config RISCV
 	select CLONE_BACKWARDS
 	select CLINT_TIMER if !MMU
 	select COMMON_CLK
+	select CPU_PM if CPU_IDLE
 	select EDAC_SUPPORT
 	select GENERIC_ARCH_TOPOLOGY if SMP
 	select GENERIC_ATOMIC64 if !64BIT
@@ -547,4 +548,10 @@ source "kernel/power/Kconfig"
 
 endmenu
 
+menu "CPU Power Management"
+
+source "drivers/cpuidle/Kconfig"
+
+endmenu
+
 source "arch/riscv/kvm/Kconfig"
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index f120fcc43d0a..a5e0482a4969 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -20,6 +20,7 @@ CONFIG_SOC_SIFIVE=y
 CONFIG_SOC_VIRT=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_CPU_IDLE=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
 CONFIG_JUMP_LABEL=y
diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig
index 8b56a7f1eb06..d1b87db54d68 100644
--- a/arch/riscv/configs/rv32_defconfig
+++ b/arch/riscv/configs/rv32_defconfig
@@ -20,6 +20,7 @@ CONFIG_SOC_VIRT=y
 CONFIG_ARCH_RV32I=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_CPU_IDLE=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
 CONFIG_JUMP_LABEL=y
diff --git a/arch/riscv/include/asm/cpuidle.h b/arch/riscv/include/asm/cpuidle.h
new file mode 100644
index 000000000000..71fdc607d4bc
--- /dev/null
+++ b/arch/riscv/include/asm/cpuidle.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2021 Allwinner Ltd
+ * Copyright (C) 2021 Western Digital Corporation or its affiliates.
+ */
+
+#ifndef _ASM_RISCV_CPUIDLE_H
+#define _ASM_RISCV_CPUIDLE_H
+
+#include <asm/barrier.h>
+#include <asm/processor.h>
+
+static inline void cpu_do_idle(void)
+{
+	/*
+	 * Add mb() here to ensure that all
+	 * IO/MEM accesses are completed prior
+	 * to entering WFI.
+	 */
+	mb();
+	wait_for_interrupt();
+}
+
+#endif
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 03ac3aa611f5..504b496787aa 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -23,6 +23,7 @@
 #include <asm/string.h>
 #include <asm/switch_to.h>
 #include <asm/thread_info.h>
+#include <asm/cpuidle.h>
 
 register unsigned long gp_in_global __asm__("gp");
 
@@ -37,7 +38,7 @@ extern asmlinkage void ret_from_kernel_thread(void);
 
 void arch_cpu_idle(void)
 {
-	wait_for_interrupt();
+	cpu_do_idle();
 	raw_local_irq_enable();
 }
 
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:46 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:46 +0530
Subject: [PATCH v10 2/8] RISC-V: Rename relocate() and make it global
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-3-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

The low-level relocate() function enables mmu and relocates
execution to link-time addresses. We rename relocate() function
to relocate_enable_mmu() function which is more informative.

Also, the relocate_enable_mmu() function will be used in the
resume path when a CPU wakes-up from a non-retentive suspend
so we make it global symbol.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/riscv/kernel/head.S | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 2363b43312fc..5f4c6b6c4974 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -90,7 +90,8 @@ pe_head_start:
 
 .align 2
 #ifdef CONFIG_MMU
-relocate:
+	.global relocate_enable_mmu
+relocate_enable_mmu:
 	/* Relocate return address */
 	la a1, kernel_map
 	XIP_FIXUP_OFFSET a1
@@ -185,7 +186,7 @@ secondary_start_sbi:
 	/* Enable virtual memory and relocate to virtual address */
 	la a0, swapper_pg_dir
 	XIP_FIXUP_OFFSET a0
-	call relocate
+	call relocate_enable_mmu
 #endif
 	call setup_trap_vector
 	tail smp_callin
@@ -329,7 +330,7 @@ clear_bss_done:
 #ifdef CONFIG_MMU
 	la a0, early_pg_dir
 	XIP_FIXUP_OFFSET a0
-	call relocate
+	call relocate_enable_mmu
 #endif /* CONFIG_MMU */
 
 	call setup_trap_vector
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:47 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:47 +0530
Subject: [PATCH v10 3/8] RISC-V: Add arch functions for non-retentive suspend
 entry/exit
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-4-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

The hart registers and CSRs are not preserved in non-retentative
suspend state so we provide arch specific helper functions which
will save/restore hart context upon entry/exit to non-retentive
suspend state. These helper functions can be used by cpuidle
drivers for non-retentive suspend entry/exit.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/riscv/include/asm/asm.h      |  27 +++++++
 arch/riscv/include/asm/suspend.h  |  36 +++++++++
 arch/riscv/kernel/Makefile        |   2 +
 arch/riscv/kernel/asm-offsets.c   |   3 +
 arch/riscv/kernel/head.S          |  21 -----
 arch/riscv/kernel/suspend.c       |  87 +++++++++++++++++++++
 arch/riscv/kernel/suspend_entry.S | 124 ++++++++++++++++++++++++++++++
 7 files changed, 279 insertions(+), 21 deletions(-)
 create mode 100644 arch/riscv/include/asm/suspend.h
 create mode 100644 arch/riscv/kernel/suspend.c
 create mode 100644 arch/riscv/kernel/suspend_entry.S

diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 618d7c5af1a2..48b4baa4d706 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -67,4 +67,31 @@
 #error "Unexpected __SIZEOF_SHORT__"
 #endif
 
+#ifdef __ASSEMBLY__
+
+/* Common assembly source macros */
+
+#ifdef CONFIG_XIP_KERNEL
+.macro XIP_FIXUP_OFFSET reg
+	REG_L t0, _xip_fixup
+	add \reg, \reg, t0
+.endm
+.macro XIP_FIXUP_FLASH_OFFSET reg
+	la t1, __data_loc
+	li t0, XIP_OFFSET_MASK
+	and t1, t1, t0
+	li t1, XIP_OFFSET
+	sub t0, t0, t1
+	sub \reg, \reg, t0
+.endm
+_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
+#else
+.macro XIP_FIXUP_OFFSET reg
+.endm
+.macro XIP_FIXUP_FLASH_OFFSET reg
+.endm
+#endif /* CONFIG_XIP_KERNEL */
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* _ASM_RISCV_ASM_H */
diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h
new file mode 100644
index 000000000000..8be391c2aecb
--- /dev/null
+++ b/arch/riscv/include/asm/suspend.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ */
+
+#ifndef _ASM_RISCV_SUSPEND_H
+#define _ASM_RISCV_SUSPEND_H
+
+#include <asm/ptrace.h>
+
+struct suspend_context {
+	/* Saved and restored by low-level functions */
+	struct pt_regs regs;
+	/* Saved and restored by high-level functions */
+	unsigned long scratch;
+	unsigned long tvec;
+	unsigned long ie;
+#ifdef CONFIG_MMU
+	unsigned long satp;
+#endif
+};
+
+/* Low-level CPU suspend entry function */
+int __cpu_suspend_enter(struct suspend_context *context);
+
+/* High-level CPU suspend which will save context and call finish() */
+int cpu_suspend(unsigned long arg,
+		int (*finish)(unsigned long arg,
+			      unsigned long entry,
+			      unsigned long context));
+
+/* Low-level CPU resume entry function */
+int __cpu_resume_enter(unsigned long hartid, unsigned long context);
+
+#endif
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 612556faa527..13fa5733f5e7 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -48,6 +48,8 @@ obj-$(CONFIG_RISCV_BOOT_SPINWAIT) += cpu_ops_spinwait.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_MODULE_SECTIONS)	+= module-sections.o
 
+obj-$(CONFIG_CPU_PM)		+= suspend_entry.o suspend.o
+
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= mcount-dyn.o
 
diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
index df0519a64eaf..df9444397908 100644
--- a/arch/riscv/kernel/asm-offsets.c
+++ b/arch/riscv/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
 #include <asm/thread_info.h>
 #include <asm/ptrace.h>
 #include <asm/cpu_ops_sbi.h>
+#include <asm/suspend.h>
 
 void asm_offsets(void);
 
@@ -113,6 +114,8 @@ void asm_offsets(void)
 	OFFSET(PT_BADADDR, pt_regs, badaddr);
 	OFFSET(PT_CAUSE, pt_regs, cause);
 
+	OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
+
 	OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero);
 	OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra);
 	OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp);
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 5f4c6b6c4974..893b8bb69391 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -16,27 +16,6 @@
 #include <asm/image.h>
 #include "efi-header.S"
 
-#ifdef CONFIG_XIP_KERNEL
-.macro XIP_FIXUP_OFFSET reg
-	REG_L t0, _xip_fixup
-	add \reg, \reg, t0
-.endm
-.macro XIP_FIXUP_FLASH_OFFSET reg
-	la t1, __data_loc
-	li t0, XIP_OFFSET_MASK
-	and t1, t1, t0
-	li t1, XIP_OFFSET
-	sub t0, t0, t1
-	sub \reg, \reg, t0
-.endm
-_xip_fixup: .dword CONFIG_PHYS_RAM_BASE - CONFIG_XIP_PHYS_ADDR - XIP_OFFSET
-#else
-.macro XIP_FIXUP_OFFSET reg
-.endm
-.macro XIP_FIXUP_FLASH_OFFSET reg
-.endm
-#endif /* CONFIG_XIP_KERNEL */
-
 __HEAD
 ENTRY(_start)
 	/*
diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c
new file mode 100644
index 000000000000..9ba24fb8cc93
--- /dev/null
+++ b/arch/riscv/kernel/suspend.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/ftrace.h>
+#include <asm/csr.h>
+#include <asm/suspend.h>
+
+static void suspend_save_csrs(struct suspend_context *context)
+{
+	context->scratch = csr_read(CSR_SCRATCH);
+	context->tvec = csr_read(CSR_TVEC);
+	context->ie = csr_read(CSR_IE);
+
+	/*
+	 * No need to save/restore IP CSR (i.e. MIP or SIP) because:
+	 *
+	 * 1. For no-MMU (M-mode) kernel, the bits in MIP are set by
+	 *    external devices (such as interrupt controller, timer, etc).
+	 * 2. For MMU (S-mode) kernel, the bits in SIP are set by
+	 *    M-mode firmware and external devices (such as interrupt
+	 *    controller, etc).
+	 */
+
+#ifdef CONFIG_MMU
+	context->satp = csr_read(CSR_SATP);
+#endif
+}
+
+static void suspend_restore_csrs(struct suspend_context *context)
+{
+	csr_write(CSR_SCRATCH, context->scratch);
+	csr_write(CSR_TVEC, context->tvec);
+	csr_write(CSR_IE, context->ie);
+
+#ifdef CONFIG_MMU
+	csr_write(CSR_SATP, context->satp);
+#endif
+}
+
+int cpu_suspend(unsigned long arg,
+		int (*finish)(unsigned long arg,
+			      unsigned long entry,
+			      unsigned long context))
+{
+	int rc = 0;
+	struct suspend_context context = { 0 };
+
+	/* Finisher should be non-NULL */
+	if (!finish)
+		return -EINVAL;
+
+	/* Save additional CSRs*/
+	suspend_save_csrs(&context);
+
+	/*
+	 * Function graph tracer state gets incosistent when the kernel
+	 * calls functions that never return (aka finishers) hence disable
+	 * graph tracing during their execution.
+	 */
+	pause_graph_tracing();
+
+	/* Save context on stack */
+	if (__cpu_suspend_enter(&context)) {
+		/* Call the finisher */
+		rc = finish(arg, __pa_symbol(__cpu_resume_enter),
+			    (ulong)&context);
+
+		/*
+		 * Should never reach here, unless the suspend finisher
+		 * fails. Successful cpu_suspend() should return from
+		 * __cpu_resume_entry()
+		 */
+		if (!rc)
+			rc = -EOPNOTSUPP;
+	}
+
+	/* Enable function graph tracer */
+	unpause_graph_tracing();
+
+	/* Restore additional CSRs */
+	suspend_restore_csrs(&context);
+
+	return rc;
+}
diff --git a/arch/riscv/kernel/suspend_entry.S b/arch/riscv/kernel/suspend_entry.S
new file mode 100644
index 000000000000..4b07b809a2b8
--- /dev/null
+++ b/arch/riscv/kernel/suspend_entry.S
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/csr.h>
+
+	.text
+	.altmacro
+	.option norelax
+
+ENTRY(__cpu_suspend_enter)
+	/* Save registers (except A0 and T0-T6) */
+	REG_S	ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
+	REG_S	sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
+	REG_S	gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
+	REG_S	tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
+	REG_S	s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
+	REG_S	s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
+	REG_S	a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
+	REG_S	a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
+	REG_S	a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
+	REG_S	a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
+	REG_S	a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
+	REG_S	a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
+	REG_S	a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
+	REG_S	s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
+	REG_S	s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
+	REG_S	s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
+	REG_S	s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
+	REG_S	s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
+	REG_S	s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
+	REG_S	s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
+	REG_S	s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
+	REG_S	s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
+	REG_S	s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
+
+	/* Save CSRs */
+	csrr	t0, CSR_EPC
+	REG_S	t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
+	csrr	t0, CSR_STATUS
+	REG_S	t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
+	csrr	t0, CSR_TVAL
+	REG_S	t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
+	csrr	t0, CSR_CAUSE
+	REG_S	t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
+
+	/* Return non-zero value */
+	li	a0, 1
+
+	/* Return to C code */
+	ret
+END(__cpu_suspend_enter)
+
+ENTRY(__cpu_resume_enter)
+	/* Load the global pointer */
+	.option push
+	.option norelax
+		la gp, __global_pointer$
+	.option pop
+
+#ifdef CONFIG_MMU
+	/* Save A0 and A1 */
+	add	t0, a0, zero
+	add	t1, a1, zero
+
+	/* Enable MMU */
+	la	a0, swapper_pg_dir
+	XIP_FIXUP_OFFSET a0
+	call	relocate_enable_mmu
+
+	/* Restore A0 and A1 */
+	add	a0, t0, zero
+	add	a1, t1, zero
+#endif
+
+	/* Make A0 point to suspend context */
+	add	a0, a1, zero
+
+	/* Restore CSRs */
+	REG_L	t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0)
+	csrw	CSR_EPC, t0
+	REG_L	t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0)
+	csrw	CSR_STATUS, t0
+	REG_L	t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0)
+	csrw	CSR_TVAL, t0
+	REG_L	t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0)
+	csrw	CSR_CAUSE, t0
+
+	/* Restore registers (except A0 and T0-T6) */
+	REG_L	ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0)
+	REG_L	sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0)
+	REG_L	gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0)
+	REG_L	tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0)
+	REG_L	s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0)
+	REG_L	s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0)
+	REG_L	a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0)
+	REG_L	a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0)
+	REG_L	a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0)
+	REG_L	a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0)
+	REG_L	a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0)
+	REG_L	a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0)
+	REG_L	a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0)
+	REG_L	s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0)
+	REG_L	s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0)
+	REG_L	s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0)
+	REG_L	s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0)
+	REG_L	s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0)
+	REG_L	s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0)
+	REG_L	s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0)
+	REG_L	s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0)
+	REG_L	s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0)
+	REG_L	s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0)
+
+	/* Return zero value */
+	add	a0, zero, zero
+
+	/* Return to C code */
+	ret
+END(__cpu_resume_enter)
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:48 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:48 +0530
Subject: [PATCH v10 4/8] RISC-V: Add SBI HSM suspend related defines
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-5-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

We add defines related to SBI HSM suspend call and also
update HSM states naming as-per latest SBI specification.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/riscv/include/asm/sbi.h    | 27 ++++++++++++++++++++++-----
 arch/riscv/kernel/cpu_ops_sbi.c |  2 +-
 arch/riscv/kvm/vcpu_sbi_hsm.c   |  4 ++--
 3 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index d1c37479d828..06133b4f8e20 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -71,15 +71,32 @@ enum sbi_ext_hsm_fid {
 	SBI_EXT_HSM_HART_START = 0,
 	SBI_EXT_HSM_HART_STOP,
 	SBI_EXT_HSM_HART_STATUS,
+	SBI_EXT_HSM_HART_SUSPEND,
 };
 
-enum sbi_hsm_hart_status {
-	SBI_HSM_HART_STATUS_STARTED = 0,
-	SBI_HSM_HART_STATUS_STOPPED,
-	SBI_HSM_HART_STATUS_START_PENDING,
-	SBI_HSM_HART_STATUS_STOP_PENDING,
+enum sbi_hsm_hart_state {
+	SBI_HSM_STATE_STARTED = 0,
+	SBI_HSM_STATE_STOPPED,
+	SBI_HSM_STATE_START_PENDING,
+	SBI_HSM_STATE_STOP_PENDING,
+	SBI_HSM_STATE_SUSPENDED,
+	SBI_HSM_STATE_SUSPEND_PENDING,
+	SBI_HSM_STATE_RESUME_PENDING,
 };
 
+#define SBI_HSM_SUSP_BASE_MASK			0x7fffffff
+#define SBI_HSM_SUSP_NON_RET_BIT		0x80000000
+#define SBI_HSM_SUSP_PLAT_BASE			0x10000000
+
+#define SBI_HSM_SUSPEND_RET_DEFAULT		0x00000000
+#define SBI_HSM_SUSPEND_RET_PLATFORM		SBI_HSM_SUSP_PLAT_BASE
+#define SBI_HSM_SUSPEND_RET_LAST		SBI_HSM_SUSP_BASE_MASK
+#define SBI_HSM_SUSPEND_NON_RET_DEFAULT		SBI_HSM_SUSP_NON_RET_BIT
+#define SBI_HSM_SUSPEND_NON_RET_PLATFORM	(SBI_HSM_SUSP_NON_RET_BIT | \
+						 SBI_HSM_SUSP_PLAT_BASE)
+#define SBI_HSM_SUSPEND_NON_RET_LAST		(SBI_HSM_SUSP_NON_RET_BIT | \
+						 SBI_HSM_SUSP_BASE_MASK)
+
 enum sbi_ext_srst_fid {
 	SBI_EXT_SRST_RESET = 0,
 };
diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
index dae29cbfe550..2e16f6732cdf 100644
--- a/arch/riscv/kernel/cpu_ops_sbi.c
+++ b/arch/riscv/kernel/cpu_ops_sbi.c
@@ -111,7 +111,7 @@ static int sbi_cpu_is_stopped(unsigned int cpuid)
 
 	rc = sbi_hsm_hart_get_status(hartid);
 
-	if (rc == SBI_HSM_HART_STATUS_STOPPED)
+	if (rc == SBI_HSM_STATE_STOPPED)
 		return 0;
 	return rc;
 }
diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c
index 2e383687fa48..1ac4b2e8e4ec 100644
--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -60,9 +60,9 @@ static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu)
 	if (!target_vcpu)
 		return -EINVAL;
 	if (!target_vcpu->arch.power_off)
-		return SBI_HSM_HART_STATUS_STARTED;
+		return SBI_HSM_STATE_STARTED;
 	else
-		return SBI_HSM_HART_STATUS_STOPPED;
+		return SBI_HSM_STATE_STOPPED;
 }
 
 static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:49 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:49 +0530
Subject: [PATCH v10 5/8] cpuidle: Factor-out power domain related code from
 PSCI domain driver
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-6-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

The generic power domain related code in PSCI domain driver is largely
independent of PSCI and can be shared with RISC-V SBI domain driver
hence we factor-out this code into dt_idle_genpd.c and dt_idle_genpd.h.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>
---
 MAINTAINERS                           |   7 +
 drivers/cpuidle/Kconfig               |   4 +
 drivers/cpuidle/Kconfig.arm           |   1 +
 drivers/cpuidle/Makefile              |   1 +
 drivers/cpuidle/cpuidle-psci-domain.c | 138 +-------------------
 drivers/cpuidle/cpuidle-psci.h        |  15 ++-
 drivers/cpuidle/dt_idle_genpd.c       | 178 ++++++++++++++++++++++++++
 drivers/cpuidle/dt_idle_genpd.h       |  50 ++++++++
 8 files changed, 259 insertions(+), 135 deletions(-)
 create mode 100644 drivers/cpuidle/dt_idle_genpd.c
 create mode 100644 drivers/cpuidle/dt_idle_genpd.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..0c67ebe7f07e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5051,6 +5051,13 @@ S:	Supported
 F:	drivers/cpuidle/cpuidle-psci.h
 F:	drivers/cpuidle/cpuidle-psci-domain.c
 
+CPUIDLE DRIVER - DT IDLE PM DOMAIN
+M:	Ulf Hansson <ulf.hansson at linaro.org>
+L:	linux-pm at vger.kernel.org
+S:	Supported
+F:	drivers/cpuidle/dt_idle_genpd.c
+F:	drivers/cpuidle/dt_idle_genpd.h
+
 CRAMFS FILESYSTEM
 M:	Nicolas Pitre <nico at fluxnic.net>
 S:	Maintained
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index c0aeedd66f02..f1afe7ab6b54 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -47,6 +47,10 @@ config CPU_IDLE_GOV_HALTPOLL
 config DT_IDLE_STATES
 	bool
 
+config DT_IDLE_GENPD
+	depends on PM_GENERIC_DOMAINS_OF
+	bool
+
 menu "ARM CPU Idle Drivers"
 depends on ARM || ARM64
 source "drivers/cpuidle/Kconfig.arm"
diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm
index 15d6c46c0a47..be7f512109f7 100644
--- a/drivers/cpuidle/Kconfig.arm
+++ b/drivers/cpuidle/Kconfig.arm
@@ -27,6 +27,7 @@ config ARM_PSCI_CPUIDLE_DOMAIN
 	bool "PSCI CPU idle Domain"
 	depends on ARM_PSCI_CPUIDLE
 	depends on PM_GENERIC_DOMAINS_OF
+	select DT_IDLE_GENPD
 	default y
 	help
 	  Select this to enable the PSCI based CPUidle driver to use PM domains,
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 26bbc5e74123..11a26cef279f 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -6,6 +6,7 @@
 obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
 obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
 obj-$(CONFIG_DT_IDLE_STATES)		  += dt_idle_states.o
+obj-$(CONFIG_DT_IDLE_GENPD)		  += dt_idle_genpd.o
 obj-$(CONFIG_ARCH_HAS_CPU_RELAX)	  += poll_state.o
 obj-$(CONFIG_HALTPOLL_CPUIDLE)		  += cpuidle-haltpoll.o
 
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
index ff2c3f8e4668..755bbdfc5b82 100644
--- a/drivers/cpuidle/cpuidle-psci-domain.c
+++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -47,73 +47,14 @@ static int psci_pd_power_off(struct generic_pm_domain *pd)
 	return 0;
 }
 
-static int psci_pd_parse_state_nodes(struct genpd_power_state *states,
-				     int state_count)
-{
-	int i, ret;
-	u32 psci_state, *psci_state_buf;
-
-	for (i = 0; i < state_count; i++) {
-		ret = psci_dt_parse_state_node(to_of_node(states[i].fwnode),
-					&psci_state);
-		if (ret)
-			goto free_state;
-
-		psci_state_buf = kmalloc(sizeof(u32), GFP_KERNEL);
-		if (!psci_state_buf) {
-			ret = -ENOMEM;
-			goto free_state;
-		}
-		*psci_state_buf = psci_state;
-		states[i].data = psci_state_buf;
-	}
-
-	return 0;
-
-free_state:
-	i--;
-	for (; i >= 0; i--)
-		kfree(states[i].data);
-	return ret;
-}
-
-static int psci_pd_parse_states(struct device_node *np,
-			struct genpd_power_state **states, int *state_count)
-{
-	int ret;
-
-	/* Parse the domain idle states. */
-	ret = of_genpd_parse_idle_states(np, states, state_count);
-	if (ret)
-		return ret;
-
-	/* Fill out the PSCI specifics for each found state. */
-	ret = psci_pd_parse_state_nodes(*states, *state_count);
-	if (ret)
-		kfree(*states);
-
-	return ret;
-}
-
-static void psci_pd_free_states(struct genpd_power_state *states,
-				unsigned int state_count)
-{
-	int i;
-
-	for (i = 0; i < state_count; i++)
-		kfree(states[i].data);
-	kfree(states);
-}
-
 static int psci_pd_init(struct device_node *np, bool use_osi)
 {
 	struct generic_pm_domain *pd;
 	struct psci_pd_provider *pd_provider;
 	struct dev_power_governor *pd_gov;
-	struct genpd_power_state *states = NULL;
 	int ret = -ENOMEM, state_count = 0;
 
-	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	pd = dt_idle_pd_alloc(np, psci_dt_parse_state_node);
 	if (!pd)
 		goto out;
 
@@ -121,22 +62,6 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 	if (!pd_provider)
 		goto free_pd;
 
-	pd->name = kasprintf(GFP_KERNEL, "%pOF", np);
-	if (!pd->name)
-		goto free_pd_prov;
-
-	/*
-	 * Parse the domain idle states and let genpd manage the state selection
-	 * for those being compatible with "domain-idle-state".
-	 */
-	ret = psci_pd_parse_states(np, &states, &state_count);
-	if (ret)
-		goto free_name;
-
-	pd->free_states = psci_pd_free_states;
-	pd->name = kbasename(pd->name);
-	pd->states = states;
-	pd->state_count = state_count;
 	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
 
 	/* Allow power off when OSI has been successfully enabled. */
@@ -149,10 +74,8 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 	pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL;
 
 	ret = pm_genpd_init(pd, pd_gov, false);
-	if (ret) {
-		psci_pd_free_states(states, state_count);
-		goto free_name;
-	}
+	if (ret)
+		goto free_pd_prov;
 
 	ret = of_genpd_add_provider_simple(np, pd);
 	if (ret)
@@ -166,12 +89,10 @@ static int psci_pd_init(struct device_node *np, bool use_osi)
 
 remove_pd:
 	pm_genpd_remove(pd);
-free_name:
-	kfree(pd->name);
 free_pd_prov:
 	kfree(pd_provider);
 free_pd:
-	kfree(pd);
+	dt_idle_pd_free(pd);
 out:
 	pr_err("failed to init PM domain ret=%d %pOF\n", ret, np);
 	return ret;
@@ -195,30 +116,6 @@ static void psci_pd_remove(void)
 	}
 }
 
-static int psci_pd_init_topology(struct device_node *np)
-{
-	struct device_node *node;
-	struct of_phandle_args child, parent;
-	int ret;
-
-	for_each_child_of_node(np, node) {
-		if (of_parse_phandle_with_args(node, "power-domains",
-					"#power-domain-cells", 0, &parent))
-			continue;
-
-		child.np = node;
-		child.args_count = 0;
-		ret = of_genpd_add_subdomain(&parent, &child);
-		of_node_put(parent.np);
-		if (ret) {
-			of_node_put(node);
-			return ret;
-		}
-	}
-
-	return 0;
-}
-
 static bool psci_pd_try_set_osi_mode(void)
 {
 	int ret;
@@ -282,7 +179,7 @@ static int psci_cpuidle_domain_probe(struct platform_device *pdev)
 		goto no_pd;
 
 	/* Link genpd masters/subdomains to model the CPU topology. */
-	ret = psci_pd_init_topology(np);
+	ret = dt_idle_pd_init_topology(np);
 	if (ret)
 		goto remove_pd;
 
@@ -314,28 +211,3 @@ static int __init psci_idle_init_domains(void)
 	return platform_driver_register(&psci_cpuidle_domain_driver);
 }
 subsys_initcall(psci_idle_init_domains);
-
-struct device *psci_dt_attach_cpu(int cpu)
-{
-	struct device *dev;
-
-	dev = dev_pm_domain_attach_by_name(get_cpu_device(cpu), "psci");
-	if (IS_ERR_OR_NULL(dev))
-		return dev;
-
-	pm_runtime_irq_safe(dev);
-	if (cpu_online(cpu))
-		pm_runtime_get_sync(dev);
-
-	dev_pm_syscore_device(dev, true);
-
-	return dev;
-}
-
-void psci_dt_detach_cpu(struct device *dev)
-{
-	if (IS_ERR_OR_NULL(dev))
-		return;
-
-	dev_pm_domain_detach(dev, false);
-}
diff --git a/drivers/cpuidle/cpuidle-psci.h b/drivers/cpuidle/cpuidle-psci.h
index d8e925e84c27..4e132640ed64 100644
--- a/drivers/cpuidle/cpuidle-psci.h
+++ b/drivers/cpuidle/cpuidle-psci.h
@@ -10,8 +10,19 @@ void psci_set_domain_state(u32 state);
 int psci_dt_parse_state_node(struct device_node *np, u32 *state);
 
 #ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN
-struct device *psci_dt_attach_cpu(int cpu);
-void psci_dt_detach_cpu(struct device *dev);
+
+#include "dt_idle_genpd.h"
+
+static inline struct device *psci_dt_attach_cpu(int cpu)
+{
+	return dt_idle_attach_cpu(cpu, "psci");
+}
+
+static inline void psci_dt_detach_cpu(struct device *dev)
+{
+	dt_idle_detach_cpu(dev);
+}
+
 #else
 static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; }
 static inline void psci_dt_detach_cpu(struct device *dev) { }
diff --git a/drivers/cpuidle/dt_idle_genpd.c b/drivers/cpuidle/dt_idle_genpd.c
new file mode 100644
index 000000000000..b37165514d4e
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_genpd.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PM domains for CPUs via genpd.
+ *
+ * Copyright (C) 2019 Linaro Ltd.
+ * Author: Ulf Hansson <ulf.hansson at linaro.org>
+ *
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "dt-idle-genpd: " fmt
+
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "dt_idle_genpd.h"
+
+static int pd_parse_state_nodes(
+			int (*parse_state)(struct device_node *, u32 *),
+			struct genpd_power_state *states, int state_count)
+{
+	int i, ret;
+	u32 state, *state_buf;
+
+	for (i = 0; i < state_count; i++) {
+		ret = parse_state(to_of_node(states[i].fwnode), &state);
+		if (ret)
+			goto free_state;
+
+		state_buf = kmalloc(sizeof(u32), GFP_KERNEL);
+		if (!state_buf) {
+			ret = -ENOMEM;
+			goto free_state;
+		}
+		*state_buf = state;
+		states[i].data = state_buf;
+	}
+
+	return 0;
+
+free_state:
+	i--;
+	for (; i >= 0; i--)
+		kfree(states[i].data);
+	return ret;
+}
+
+static int pd_parse_states(struct device_node *np,
+			   int (*parse_state)(struct device_node *, u32 *),
+			   struct genpd_power_state **states,
+			   int *state_count)
+{
+	int ret;
+
+	/* Parse the domain idle states. */
+	ret = of_genpd_parse_idle_states(np, states, state_count);
+	if (ret)
+		return ret;
+
+	/* Fill out the dt specifics for each found state. */
+	ret = pd_parse_state_nodes(parse_state, *states, *state_count);
+	if (ret)
+		kfree(*states);
+
+	return ret;
+}
+
+static void pd_free_states(struct genpd_power_state *states,
+			    unsigned int state_count)
+{
+	int i;
+
+	for (i = 0; i < state_count; i++)
+		kfree(states[i].data);
+	kfree(states);
+}
+
+void dt_idle_pd_free(struct generic_pm_domain *pd)
+{
+	pd_free_states(pd->states, pd->state_count);
+	kfree(pd->name);
+	kfree(pd);
+}
+
+struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
+			int (*parse_state)(struct device_node *, u32 *))
+{
+	struct generic_pm_domain *pd;
+	struct genpd_power_state *states = NULL;
+	int ret, state_count = 0;
+
+	pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+	if (!pd)
+		goto out;
+
+	pd->name = kasprintf(GFP_KERNEL, "%pOF", np);
+	if (!pd->name)
+		goto free_pd;
+
+	/*
+	 * Parse the domain idle states and let genpd manage the state selection
+	 * for those being compatible with "domain-idle-state".
+	 */
+	ret = pd_parse_states(np, parse_state, &states, &state_count);
+	if (ret)
+		goto free_name;
+
+	pd->free_states = pd_free_states;
+	pd->name = kbasename(pd->name);
+	pd->states = states;
+	pd->state_count = state_count;
+
+	pr_debug("alloc PM domain %s\n", pd->name);
+	return pd;
+
+free_name:
+	kfree(pd->name);
+free_pd:
+	kfree(pd);
+out:
+	pr_err("failed to alloc PM domain %pOF\n", np);
+	return NULL;
+}
+
+int dt_idle_pd_init_topology(struct device_node *np)
+{
+	struct device_node *node;
+	struct of_phandle_args child, parent;
+	int ret;
+
+	for_each_child_of_node(np, node) {
+		if (of_parse_phandle_with_args(node, "power-domains",
+					"#power-domain-cells", 0, &parent))
+			continue;
+
+		child.np = node;
+		child.args_count = 0;
+		ret = of_genpd_add_subdomain(&parent, &child);
+		of_node_put(parent.np);
+		if (ret) {
+			of_node_put(node);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+struct device *dt_idle_attach_cpu(int cpu, const char *name)
+{
+	struct device *dev;
+
+	dev = dev_pm_domain_attach_by_name(get_cpu_device(cpu), name);
+	if (IS_ERR_OR_NULL(dev))
+		return dev;
+
+	pm_runtime_irq_safe(dev);
+	if (cpu_online(cpu))
+		pm_runtime_get_sync(dev);
+
+	dev_pm_syscore_device(dev, true);
+
+	return dev;
+}
+
+void dt_idle_detach_cpu(struct device *dev)
+{
+	if (IS_ERR_OR_NULL(dev))
+		return;
+
+	dev_pm_domain_detach(dev, false);
+}
diff --git a/drivers/cpuidle/dt_idle_genpd.h b/drivers/cpuidle/dt_idle_genpd.h
new file mode 100644
index 000000000000..a95483d08a02
--- /dev/null
+++ b/drivers/cpuidle/dt_idle_genpd.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __DT_IDLE_GENPD
+#define __DT_IDLE_GENPD
+
+struct device_node;
+struct generic_pm_domain;
+
+#ifdef CONFIG_DT_IDLE_GENPD
+
+void dt_idle_pd_free(struct generic_pm_domain *pd);
+
+struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np,
+			int (*parse_state)(struct device_node *, u32 *));
+
+int dt_idle_pd_init_topology(struct device_node *np);
+
+struct device *dt_idle_attach_cpu(int cpu, const char *name);
+
+void dt_idle_detach_cpu(struct device *dev);
+
+#else
+
+static inline void dt_idle_pd_free(struct generic_pm_domain *pd)
+{
+}
+
+static inline struct generic_pm_domain *dt_idle_pd_alloc(
+			struct device_node *np,
+			int (*parse_state)(struct device_node *, u32 *))
+{
+	return NULL;
+}
+
+static inline int dt_idle_pd_init_topology(struct device_node *np)
+{
+	return 0;
+}
+
+static inline struct device *dt_idle_attach_cpu(int cpu, const char *name)
+{
+	return NULL;
+}
+
+static inline void dt_idle_detach_cpu(struct device *dev)
+{
+}
+
+#endif
+
+#endif
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:50 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:50 +0530
Subject: [PATCH v10 6/8] cpuidle: Add RISC-V SBI CPU idle driver
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-7-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

The RISC-V SBI HSM extension provides HSM suspend call which can
be used by Linux RISC-V to enter platform specific low-power state.

This patch adds a CPU idle driver based on RISC-V SBI calls which
will populate idle states from device tree and use SBI calls to
entry these idle states.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Reviewed-by: Anup Patel <apatel at ventanamicro.com>
---
 MAINTAINERS                         |   7 +
 drivers/cpuidle/Kconfig             |   5 +
 drivers/cpuidle/Kconfig.riscv       |  15 +
 drivers/cpuidle/Makefile            |   4 +
 drivers/cpuidle/cpuidle-riscv-sbi.c | 627 ++++++++++++++++++++++++++++
 5 files changed, 658 insertions(+)
 create mode 100644 drivers/cpuidle/Kconfig.riscv
 create mode 100644 drivers/cpuidle/cpuidle-riscv-sbi.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0c67ebe7f07e..15c63a717458 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5058,6 +5058,13 @@ S:	Supported
 F:	drivers/cpuidle/dt_idle_genpd.c
 F:	drivers/cpuidle/dt_idle_genpd.h
 
+CPUIDLE DRIVER - RISC-V SBI
+M:	Anup Patel <anup at brainfault.org>
+L:	linux-pm at vger.kernel.org
+L:	linux-riscv at lists.infradead.org
+S:	Maintained
+F:	drivers/cpuidle/cpuidle-riscv-sbi.c
+
 CRAMFS FILESYSTEM
 M:	Nicolas Pitre <nico at fluxnic.net>
 S:	Maintained
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index f1afe7ab6b54..ff71dd662880 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -66,6 +66,11 @@ depends on PPC
 source "drivers/cpuidle/Kconfig.powerpc"
 endmenu
 
+menu "RISC-V CPU Idle Drivers"
+depends on RISCV
+source "drivers/cpuidle/Kconfig.riscv"
+endmenu
+
 config HALTPOLL_CPUIDLE
 	tristate "Halt poll cpuidle driver"
 	depends on X86 && KVM_GUEST
diff --git a/drivers/cpuidle/Kconfig.riscv b/drivers/cpuidle/Kconfig.riscv
new file mode 100644
index 000000000000..78518c26af74
--- /dev/null
+++ b/drivers/cpuidle/Kconfig.riscv
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# RISC-V CPU Idle drivers
+#
+
+config RISCV_SBI_CPUIDLE
+	bool "RISC-V SBI CPU idle Driver"
+	depends on RISCV_SBI
+	select DT_IDLE_STATES
+	select CPU_IDLE_MULTIPLE_DRIVERS
+	select DT_IDLE_GENPD if PM_GENERIC_DOMAINS_OF
+	help
+	  Select this option to enable RISC-V SBI firmware based CPU idle
+	  driver for RISC-V systems. This drivers also supports hierarchical
+	  DT based layout of the idle state.
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
index 11a26cef279f..d103342b7cfc 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
@@ -35,3 +35,7 @@ obj-$(CONFIG_MIPS_CPS_CPUIDLE)		+= cpuidle-cps.o
 # POWERPC drivers
 obj-$(CONFIG_PSERIES_CPUIDLE)		+= cpuidle-pseries.o
 obj-$(CONFIG_POWERNV_CPUIDLE)		+= cpuidle-powernv.o
+
+###############################################################################
+# RISC-V drivers
+obj-$(CONFIG_RISCV_SBI_CPUIDLE)		+= cpuidle-riscv-sbi.o
diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c
new file mode 100644
index 000000000000..b459eda2cd37
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-riscv-sbi.c
@@ -0,0 +1,627 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * RISC-V SBI CPU idle driver.
+ *
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
+ * Copyright (c) 2022 Ventana Micro Systems Inc.
+ */
+
+#define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpu_cooling.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <asm/cpuidle.h>
+#include <asm/sbi.h>
+#include <asm/suspend.h>
+
+#include "dt_idle_states.h"
+#include "dt_idle_genpd.h"
+
+struct sbi_cpuidle_data {
+	u32 *states;
+	struct device *dev;
+};
+
+struct sbi_domain_state {
+	bool available;
+	u32 state;
+};
+
+static DEFINE_PER_CPU_READ_MOSTLY(struct sbi_cpuidle_data, sbi_cpuidle_data);
+static DEFINE_PER_CPU(struct sbi_domain_state, domain_state);
+static bool sbi_cpuidle_use_osi;
+static bool sbi_cpuidle_use_cpuhp;
+static bool sbi_cpuidle_pd_allow_domain_state;
+
+static inline void sbi_set_domain_state(u32 state)
+{
+	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
+
+	data->available = true;
+	data->state = state;
+}
+
+static inline u32 sbi_get_domain_state(void)
+{
+	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
+
+	return data->state;
+}
+
+static inline void sbi_clear_domain_state(void)
+{
+	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
+
+	data->available = false;
+}
+
+static inline bool sbi_is_domain_state_available(void)
+{
+	struct sbi_domain_state *data = this_cpu_ptr(&domain_state);
+
+	return data->available;
+}
+
+static int sbi_suspend_finisher(unsigned long suspend_type,
+				unsigned long resume_addr,
+				unsigned long opaque)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_SUSPEND,
+			suspend_type, resume_addr, opaque, 0, 0, 0);
+
+	return (ret.error) ? sbi_err_map_linux_errno(ret.error) : 0;
+}
+
+static int sbi_suspend(u32 state)
+{
+	if (state & SBI_HSM_SUSP_NON_RET_BIT)
+		return cpu_suspend(state, sbi_suspend_finisher);
+	else
+		return sbi_suspend_finisher(state, 0, 0);
+}
+
+static int sbi_cpuidle_enter_state(struct cpuidle_device *dev,
+				   struct cpuidle_driver *drv, int idx)
+{
+	u32 *states = __this_cpu_read(sbi_cpuidle_data.states);
+
+	return CPU_PM_CPU_IDLE_ENTER_PARAM(sbi_suspend, idx, states[idx]);
+}
+
+static int __sbi_enter_domain_idle_state(struct cpuidle_device *dev,
+					  struct cpuidle_driver *drv, int idx,
+					  bool s2idle)
+{
+	struct sbi_cpuidle_data *data = this_cpu_ptr(&sbi_cpuidle_data);
+	u32 *states = data->states;
+	struct device *pd_dev = data->dev;
+	u32 state;
+	int ret;
+
+	ret = cpu_pm_enter();
+	if (ret)
+		return -1;
+
+	/* Do runtime PM to manage a hierarchical CPU toplogy. */
+	rcu_irq_enter_irqson();
+	if (s2idle)
+		dev_pm_genpd_suspend(pd_dev);
+	else
+		pm_runtime_put_sync_suspend(pd_dev);
+	rcu_irq_exit_irqson();
+
+	if (sbi_is_domain_state_available())
+		state = sbi_get_domain_state();
+	else
+		state = states[idx];
+
+	ret = sbi_suspend(state) ? -1 : idx;
+
+	rcu_irq_enter_irqson();
+	if (s2idle)
+		dev_pm_genpd_resume(pd_dev);
+	else
+		pm_runtime_get_sync(pd_dev);
+	rcu_irq_exit_irqson();
+
+	cpu_pm_exit();
+
+	/* Clear the domain state to start fresh when back from idle. */
+	sbi_clear_domain_state();
+	return ret;
+}
+
+static int sbi_enter_domain_idle_state(struct cpuidle_device *dev,
+				       struct cpuidle_driver *drv, int idx)
+{
+	return __sbi_enter_domain_idle_state(dev, drv, idx, false);
+}
+
+static int sbi_enter_s2idle_domain_idle_state(struct cpuidle_device *dev,
+					      struct cpuidle_driver *drv,
+					      int idx)
+{
+	return __sbi_enter_domain_idle_state(dev, drv, idx, true);
+}
+
+static int sbi_cpuidle_cpuhp_up(unsigned int cpu)
+{
+	struct device *pd_dev = __this_cpu_read(sbi_cpuidle_data.dev);
+
+	if (pd_dev)
+		pm_runtime_get_sync(pd_dev);
+
+	return 0;
+}
+
+static int sbi_cpuidle_cpuhp_down(unsigned int cpu)
+{
+	struct device *pd_dev = __this_cpu_read(sbi_cpuidle_data.dev);
+
+	if (pd_dev) {
+		pm_runtime_put_sync(pd_dev);
+		/* Clear domain state to start fresh at next online. */
+		sbi_clear_domain_state();
+	}
+
+	return 0;
+}
+
+static void sbi_idle_init_cpuhp(void)
+{
+	int err;
+
+	if (!sbi_cpuidle_use_cpuhp)
+		return;
+
+	err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
+					"cpuidle/sbi:online",
+					sbi_cpuidle_cpuhp_up,
+					sbi_cpuidle_cpuhp_down);
+	if (err)
+		pr_warn("Failed %d while setup cpuhp state\n", err);
+}
+
+static const struct of_device_id sbi_cpuidle_state_match[] = {
+	{ .compatible = "riscv,idle-state",
+	  .data = sbi_cpuidle_enter_state },
+	{ },
+};
+
+static bool sbi_suspend_state_is_valid(u32 state)
+{
+	if (state > SBI_HSM_SUSPEND_RET_DEFAULT &&
+	    state < SBI_HSM_SUSPEND_RET_PLATFORM)
+		return false;
+	if (state > SBI_HSM_SUSPEND_NON_RET_DEFAULT &&
+	    state < SBI_HSM_SUSPEND_NON_RET_PLATFORM)
+		return false;
+	return true;
+}
+
+static int sbi_dt_parse_state_node(struct device_node *np, u32 *state)
+{
+	int err = of_property_read_u32(np, "riscv,sbi-suspend-param", state);
+
+	if (err) {
+		pr_warn("%pOF missing riscv,sbi-suspend-param property\n", np);
+		return err;
+	}
+
+	if (!sbi_suspend_state_is_valid(*state)) {
+		pr_warn("Invalid SBI suspend state %#x\n", *state);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int sbi_dt_cpu_init_topology(struct cpuidle_driver *drv,
+				     struct sbi_cpuidle_data *data,
+				     unsigned int state_count, int cpu)
+{
+	/* Currently limit the hierarchical topology to be used in OSI mode. */
+	if (!sbi_cpuidle_use_osi)
+		return 0;
+
+	data->dev = dt_idle_attach_cpu(cpu, "sbi");
+	if (IS_ERR_OR_NULL(data->dev))
+		return PTR_ERR_OR_ZERO(data->dev);
+
+	/*
+	 * Using the deepest state for the CPU to trigger a potential selection
+	 * of a shared state for the domain, assumes the domain states are all
+	 * deeper states.
+	 */
+	drv->states[state_count - 1].enter = sbi_enter_domain_idle_state;
+	drv->states[state_count - 1].enter_s2idle =
+					sbi_enter_s2idle_domain_idle_state;
+	sbi_cpuidle_use_cpuhp = true;
+
+	return 0;
+}
+
+static int sbi_cpuidle_dt_init_states(struct device *dev,
+					struct cpuidle_driver *drv,
+					unsigned int cpu,
+					unsigned int state_count)
+{
+	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
+	struct device_node *state_node;
+	struct device_node *cpu_node;
+	u32 *states;
+	int i, ret;
+
+	cpu_node = of_cpu_device_node_get(cpu);
+	if (!cpu_node)
+		return -ENODEV;
+
+	states = devm_kcalloc(dev, state_count, sizeof(*states), GFP_KERNEL);
+	if (!states) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Parse SBI specific details from state DT nodes */
+	for (i = 1; i < state_count; i++) {
+		state_node = of_get_cpu_state_node(cpu_node, i - 1);
+		if (!state_node)
+			break;
+
+		ret = sbi_dt_parse_state_node(state_node, &states[i]);
+		of_node_put(state_node);
+
+		if (ret)
+			return ret;
+
+		pr_debug("sbi-state %#x index %d\n", states[i], i);
+	}
+	if (i != state_count) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	/* Initialize optional data, used for the hierarchical topology. */
+	ret = sbi_dt_cpu_init_topology(drv, data, state_count, cpu);
+	if (ret < 0)
+		return ret;
+
+	/* Store states in the per-cpu struct. */
+	data->states = states;
+
+fail:
+	of_node_put(cpu_node);
+
+	return ret;
+}
+
+static void sbi_cpuidle_deinit_cpu(int cpu)
+{
+	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
+
+	dt_idle_detach_cpu(data->dev);
+	sbi_cpuidle_use_cpuhp = false;
+}
+
+static int sbi_cpuidle_init_cpu(struct device *dev, int cpu)
+{
+	struct cpuidle_driver *drv;
+	unsigned int state_count = 0;
+	int ret = 0;
+
+	drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
+	if (!drv)
+		return -ENOMEM;
+
+	drv->name = "sbi_cpuidle";
+	drv->owner = THIS_MODULE;
+	drv->cpumask = (struct cpumask *)cpumask_of(cpu);
+
+	/* RISC-V architectural WFI to be represented as state index 0. */
+	drv->states[0].enter = sbi_cpuidle_enter_state;
+	drv->states[0].exit_latency = 1;
+	drv->states[0].target_residency = 1;
+	drv->states[0].power_usage = UINT_MAX;
+	strcpy(drv->states[0].name, "WFI");
+	strcpy(drv->states[0].desc, "RISC-V WFI");
+
+	/*
+	 * If no DT idle states are detected (ret == 0) let the driver
+	 * initialization fail accordingly since there is no reason to
+	 * initialize the idle driver if only wfi is supported, the
+	 * default archictectural back-end already executes wfi
+	 * on idle entry.
+	 */
+	ret = dt_init_idle_driver(drv, sbi_cpuidle_state_match, 1);
+	if (ret <= 0) {
+		pr_debug("HART%ld: failed to parse DT idle states\n",
+			 cpuid_to_hartid_map(cpu));
+		return ret ? : -ENODEV;
+	}
+	state_count = ret + 1; /* Include WFI state as well */
+
+	/* Initialize idle states from DT. */
+	ret = sbi_cpuidle_dt_init_states(dev, drv, cpu, state_count);
+	if (ret) {
+		pr_err("HART%ld: failed to init idle states\n",
+		       cpuid_to_hartid_map(cpu));
+		return ret;
+	}
+
+	ret = cpuidle_register(drv, NULL);
+	if (ret)
+		goto deinit;
+
+	cpuidle_cooling_register(drv);
+
+	return 0;
+deinit:
+	sbi_cpuidle_deinit_cpu(cpu);
+	return ret;
+}
+
+static void sbi_cpuidle_domain_sync_state(struct device *dev)
+{
+	/*
+	 * All devices have now been attached/probed to the PM domain
+	 * topology, hence it's fine to allow domain states to be picked.
+	 */
+	sbi_cpuidle_pd_allow_domain_state = true;
+}
+
+#ifdef CONFIG_DT_IDLE_GENPD
+
+static int sbi_cpuidle_pd_power_off(struct generic_pm_domain *pd)
+{
+	struct genpd_power_state *state = &pd->states[pd->state_idx];
+	u32 *pd_state;
+
+	if (!state->data)
+		return 0;
+
+	if (!sbi_cpuidle_pd_allow_domain_state)
+		return -EBUSY;
+
+	/* OSI mode is enabled, set the corresponding domain state. */
+	pd_state = state->data;
+	sbi_set_domain_state(*pd_state);
+
+	return 0;
+}
+
+struct sbi_pd_provider {
+	struct list_head link;
+	struct device_node *node;
+};
+
+static LIST_HEAD(sbi_pd_providers);
+
+static int sbi_pd_init(struct device_node *np)
+{
+	struct generic_pm_domain *pd;
+	struct sbi_pd_provider *pd_provider;
+	struct dev_power_governor *pd_gov;
+	int ret = -ENOMEM, state_count = 0;
+
+	pd = dt_idle_pd_alloc(np, sbi_dt_parse_state_node);
+	if (!pd)
+		goto out;
+
+	pd_provider = kzalloc(sizeof(*pd_provider), GFP_KERNEL);
+	if (!pd_provider)
+		goto free_pd;
+
+	pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
+
+	/* Allow power off when OSI is available. */
+	if (sbi_cpuidle_use_osi)
+		pd->power_off = sbi_cpuidle_pd_power_off;
+	else
+		pd->flags |= GENPD_FLAG_ALWAYS_ON;
+
+	/* Use governor for CPU PM domains if it has some states to manage. */
+	pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL;
+
+	ret = pm_genpd_init(pd, pd_gov, false);
+	if (ret)
+		goto free_pd_prov;
+
+	ret = of_genpd_add_provider_simple(np, pd);
+	if (ret)
+		goto remove_pd;
+
+	pd_provider->node = of_node_get(np);
+	list_add(&pd_provider->link, &sbi_pd_providers);
+
+	pr_debug("init PM domain %s\n", pd->name);
+	return 0;
+
+remove_pd:
+	pm_genpd_remove(pd);
+free_pd_prov:
+	kfree(pd_provider);
+free_pd:
+	dt_idle_pd_free(pd);
+out:
+	pr_err("failed to init PM domain ret=%d %pOF\n", ret, np);
+	return ret;
+}
+
+static void sbi_pd_remove(void)
+{
+	struct sbi_pd_provider *pd_provider, *it;
+	struct generic_pm_domain *genpd;
+
+	list_for_each_entry_safe(pd_provider, it, &sbi_pd_providers, link) {
+		of_genpd_del_provider(pd_provider->node);
+
+		genpd = of_genpd_remove_last(pd_provider->node);
+		if (!IS_ERR(genpd))
+			kfree(genpd);
+
+		of_node_put(pd_provider->node);
+		list_del(&pd_provider->link);
+		kfree(pd_provider);
+	}
+}
+
+static int sbi_genpd_probe(struct device_node *np)
+{
+	struct device_node *node;
+	int ret = 0, pd_count = 0;
+
+	if (!np)
+		return -ENODEV;
+
+	/*
+	 * Parse child nodes for the "#power-domain-cells" property and
+	 * initialize a genpd/genpd-of-provider pair when it's found.
+	 */
+	for_each_child_of_node(np, node) {
+		if (!of_find_property(node, "#power-domain-cells", NULL))
+			continue;
+
+		ret = sbi_pd_init(node);
+		if (ret)
+			goto put_node;
+
+		pd_count++;
+	}
+
+	/* Bail out if not using the hierarchical CPU topology. */
+	if (!pd_count)
+		goto no_pd;
+
+	/* Link genpd masters/subdomains to model the CPU topology. */
+	ret = dt_idle_pd_init_topology(np);
+	if (ret)
+		goto remove_pd;
+
+	return 0;
+
+put_node:
+	of_node_put(node);
+remove_pd:
+	sbi_pd_remove();
+	pr_err("failed to create CPU PM domains ret=%d\n", ret);
+no_pd:
+	return ret;
+}
+
+#else
+
+static inline int sbi_genpd_probe(struct device_node *np)
+{
+	return 0;
+}
+
+#endif
+
+static int sbi_cpuidle_probe(struct platform_device *pdev)
+{
+	int cpu, ret;
+	struct cpuidle_driver *drv;
+	struct cpuidle_device *dev;
+	struct device_node *np, *pds_node;
+
+	/* Detect OSI support based on CPU DT nodes */
+	sbi_cpuidle_use_osi = true;
+	for_each_possible_cpu(cpu) {
+		np = of_cpu_device_node_get(cpu);
+		if (np &&
+		    of_find_property(np, "power-domains", NULL) &&
+		    of_find_property(np, "power-domain-names", NULL)) {
+			continue;
+		} else {
+			sbi_cpuidle_use_osi = false;
+			break;
+		}
+	}
+
+	/* Populate generic power domains from DT nodes */
+	pds_node = of_find_node_by_path("/cpus/power-domains");
+	if (pds_node) {
+		ret = sbi_genpd_probe(pds_node);
+		of_node_put(pds_node);
+		if (ret)
+			return ret;
+	}
+
+	/* Initialize CPU idle driver for each CPU */
+	for_each_possible_cpu(cpu) {
+		ret = sbi_cpuidle_init_cpu(&pdev->dev, cpu);
+		if (ret) {
+			pr_debug("HART%ld: idle driver init failed\n",
+				 cpuid_to_hartid_map(cpu));
+			goto out_fail;
+		}
+	}
+
+	/* Setup CPU hotplut notifiers */
+	sbi_idle_init_cpuhp();
+
+	pr_info("idle driver registered for all CPUs\n");
+
+	return 0;
+
+out_fail:
+	while (--cpu >= 0) {
+		dev = per_cpu(cpuidle_devices, cpu);
+		drv = cpuidle_get_cpu_driver(dev);
+		cpuidle_unregister(drv);
+		sbi_cpuidle_deinit_cpu(cpu);
+	}
+
+	return ret;
+}
+
+static struct platform_driver sbi_cpuidle_driver = {
+	.probe = sbi_cpuidle_probe,
+	.driver = {
+		.name = "sbi-cpuidle",
+		.sync_state = sbi_cpuidle_domain_sync_state,
+	},
+};
+
+static int __init sbi_cpuidle_init(void)
+{
+	int ret;
+	struct platform_device *pdev;
+
+	/*
+	 * The SBI HSM suspend function is only available when:
+	 * 1) SBI version is 0.3 or higher
+	 * 2) SBI HSM extension is available
+	 */
+	if ((sbi_spec_version < sbi_mk_version(0, 3)) ||
+	    sbi_probe_extension(SBI_EXT_HSM) <= 0) {
+		pr_info("HSM suspend not available\n");
+		return 0;
+	}
+
+	ret = platform_driver_register(&sbi_cpuidle_driver);
+	if (ret)
+		return ret;
+
+	pdev = platform_device_register_simple("sbi-cpuidle",
+						-1, NULL, 0);
+	if (IS_ERR(pdev)) {
+		platform_driver_unregister(&sbi_cpuidle_driver);
+		return PTR_ERR(pdev);
+	}
+
+	return 0;
+}
+device_initcall(sbi_cpuidle_init);
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:51 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:51 +0530
Subject: [PATCH v10 7/8] dt-bindings: Add common bindings for ARM and RISC-V
 idle states
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-8-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

The RISC-V CPU idle states will be described in under the
/cpus/idle-states DT node in the same way as ARM CPU idle
states.

This patch adds common bindings documentation for both ARM
and RISC-V idle states.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/arm/msm/qcom,idle-state.txt      |   2 +-
 .../devicetree/bindings/arm/psci.yaml         |   2 +-
 .../bindings/{arm => cpu}/idle-states.yaml    | 228 ++++++++++++++++--
 .../devicetree/bindings/riscv/cpus.yaml       |   6 +
 4 files changed, 219 insertions(+), 19 deletions(-)
 rename Documentation/devicetree/bindings/{arm => cpu}/idle-states.yaml (74%)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,idle-state.txt b/Documentation/devicetree/bindings/arm/msm/qcom,idle-state.txt
index 6ce0b212ec6d..606b4b1b709d 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,idle-state.txt
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,idle-state.txt
@@ -81,4 +81,4 @@ Example:
 		};
 	};
 
-[1]. Documentation/devicetree/bindings/arm/idle-states.yaml
+[1]. Documentation/devicetree/bindings/cpu/idle-states.yaml
diff --git a/Documentation/devicetree/bindings/arm/psci.yaml b/Documentation/devicetree/bindings/arm/psci.yaml
index 8b77cf83a095..dd83ef278af0 100644
--- a/Documentation/devicetree/bindings/arm/psci.yaml
+++ b/Documentation/devicetree/bindings/arm/psci.yaml
@@ -101,7 +101,7 @@ properties:
       bindings in [1]) must specify this property.
 
       [1] Kernel documentation - ARM idle states bindings
-        Documentation/devicetree/bindings/arm/idle-states.yaml
+        Documentation/devicetree/bindings/cpu/idle-states.yaml
 
 patternProperties:
   "^power-domain-":
diff --git a/Documentation/devicetree/bindings/arm/idle-states.yaml b/Documentation/devicetree/bindings/cpu/idle-states.yaml
similarity index 74%
rename from Documentation/devicetree/bindings/arm/idle-states.yaml
rename to Documentation/devicetree/bindings/cpu/idle-states.yaml
index 52bce5dbb11f..95506ffb816c 100644
--- a/Documentation/devicetree/bindings/arm/idle-states.yaml
+++ b/Documentation/devicetree/bindings/cpu/idle-states.yaml
@@ -1,25 +1,30 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/arm/idle-states.yaml#
+$id: http://devicetree.org/schemas/cpu/idle-states.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: ARM idle states binding description
+title: Idle states binding description
 
 maintainers:
   - Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
+  - Anup Patel <anup at brainfault.org>
 
 description: |+
   ==========================================
   1 - Introduction
   ==========================================
 
-  ARM systems contain HW capable of managing power consumption dynamically,
-  where cores can be put in different low-power states (ranging from simple wfi
-  to power gating) according to OS PM policies. The CPU states representing the
-  range of dynamic idle states that a processor can enter at run-time, can be
-  specified through device tree bindings representing the parameters required to
-  enter/exit specific idle states on a given processor.
+  ARM and RISC-V systems contain HW capable of managing power consumption
+  dynamically, where cores can be put in different low-power states (ranging
+  from simple wfi to power gating) according to OS PM policies. The CPU states
+  representing the range of dynamic idle states that a processor can enter at
+  run-time, can be specified through device tree bindings representing the
+  parameters required to enter/exit specific idle states on a given processor.
+
+  ==========================================
+  2 - ARM idle states
+  ==========================================
 
   According to the Server Base System Architecture document (SBSA, [3]), the
   power states an ARM CPU can be put into are identified by the following list:
@@ -43,8 +48,23 @@ description: |+
   The device tree binding definition for ARM idle states is the subject of this
   document.
 
+  ==========================================
+  3 - RISC-V idle states
+  ==========================================
+
+  On RISC-V systems, the HARTs (or CPUs) [6] can be put in platform specific
+  suspend (or idle) states (ranging from simple WFI, power gating, etc). The
+  RISC-V SBI v0.3 (or higher) [7] hart state management extension provides a
+  standard mechanism for OS to request HART state transitions.
+
+  The platform specific suspend (or idle) states of a hart can be either
+  retentive or non-rententive in nature. A retentive suspend state will
+  preserve HART registers and CSR values for all privilege modes whereas
+  a non-retentive suspend state will not preserve HART registers and CSR
+  values.
+
   ===========================================
-  2 - idle-states definitions
+  4 - idle-states definitions
   ===========================================
 
   Idle states are characterized for a specific system through a set of
@@ -211,10 +231,10 @@ description: |+
   properties specification that is the subject of the following sections.
 
   ===========================================
-  3 - idle-states node
+  5 - idle-states node
   ===========================================
 
-  ARM processor idle states are defined within the idle-states node, which is
+  The processor idle states are defined within the idle-states node, which is
   a direct child of the cpus node [1] and provides a container where the
   processor idle states, defined as device tree nodes, are listed.
 
@@ -223,7 +243,7 @@ description: |+
   just supports idle_standby, an idle-states node is not required.
 
   ===========================================
-  4 - References
+  6 - References
   ===========================================
 
   [1] ARM Linux Kernel documentation - CPUs bindings
@@ -238,9 +258,15 @@ description: |+
   [4] ARM Architecture Reference Manuals
       http://infocenter.arm.com/help/index.jsp
 
-  [6] ARM Linux Kernel documentation - Booting AArch64 Linux
+  [5] ARM Linux Kernel documentation - Booting AArch64 Linux
       Documentation/arm64/booting.rst
 
+  [6] RISC-V Linux Kernel documentation - CPUs bindings
+      Documentation/devicetree/bindings/riscv/cpus.yaml
+
+  [7] RISC-V Supervisor Binary Interface (SBI)
+      http://github.com/riscv/riscv-sbi-doc/riscv-sbi.adoc
+
 properties:
   $nodename:
     const: idle-states
@@ -253,7 +279,7 @@ properties:
       On ARM 32-bit systems this property is optional
 
       This assumes that the "enable-method" property is set to "psci" in the cpu
-      node[6] that is responsible for setting up CPU idle management in the OS
+      node[5] that is responsible for setting up CPU idle management in the OS
       implementation.
     const: psci
 
@@ -265,8 +291,8 @@ patternProperties:
       as follows.
 
       The idle state entered by executing the wfi instruction (idle_standby
-      SBSA,[3][4]) is considered standard on all ARM platforms and therefore
-      must not be listed.
+      SBSA,[3][4]) is considered standard on all ARM and RISC-V platforms and
+      therefore must not be listed.
 
       In addition to the properties listed above, a state node may require
       additional properties specific to the entry-method defined in the
@@ -275,7 +301,27 @@ patternProperties:
 
     properties:
       compatible:
-        const: arm,idle-state
+        enum:
+          - arm,idle-state
+          - riscv,idle-state
+
+      arm,psci-suspend-param:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          power_state parameter to pass to the ARM PSCI suspend call.
+
+          Device tree nodes that require usage of PSCI CPU_SUSPEND function
+          (i.e. idle states node with entry-method property is set to "psci")
+          must specify this property.
+
+      riscv,sbi-suspend-param:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          suspend_type parameter to pass to the RISC-V SBI HSM suspend call.
+
+          This property is required in idle state nodes of device tree meant
+          for RISC-V systems. For more details on the suspend_type parameter
+          refer the SBI specifiation v0.3 (or higher) [7].
 
       local-timer-stop:
         description:
@@ -317,6 +363,8 @@ patternProperties:
         description:
           A string used as a descriptive name for the idle state.
 
+    additionalProperties: false
+
     required:
       - compatible
       - entry-latency-us
@@ -658,4 +706,150 @@ examples:
         };
     };
 
+  - |
+    // Example 3 (RISC-V 64-bit, 4-cpu systems, two clusters):
+
+    cpus {
+        #size-cells = <0>;
+        #address-cells = <1>;
+
+        cpu at 0 {
+            device_type = "cpu";
+            compatible = "riscv";
+            reg = <0x0>;
+            riscv,isa = "rv64imafdc";
+            mmu-type = "riscv,sv48";
+            cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
+                            &CLUSTER_RET_0 &CLUSTER_NONRET_0>;
+
+            cpu_intc0: interrupt-controller {
+                #interrupt-cells = <1>;
+                compatible = "riscv,cpu-intc";
+                interrupt-controller;
+            };
+        };
+
+        cpu at 1 {
+            device_type = "cpu";
+            compatible = "riscv";
+            reg = <0x1>;
+            riscv,isa = "rv64imafdc";
+            mmu-type = "riscv,sv48";
+            cpu-idle-states = <&CPU_RET_0_0 &CPU_NONRET_0_0
+                            &CLUSTER_RET_0 &CLUSTER_NONRET_0>;
+
+            cpu_intc1: interrupt-controller {
+                #interrupt-cells = <1>;
+                compatible = "riscv,cpu-intc";
+                interrupt-controller;
+            };
+        };
+
+        cpu at 10 {
+            device_type = "cpu";
+            compatible = "riscv";
+            reg = <0x10>;
+            riscv,isa = "rv64imafdc";
+            mmu-type = "riscv,sv48";
+            cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
+                            &CLUSTER_RET_1 &CLUSTER_NONRET_1>;
+
+            cpu_intc10: interrupt-controller {
+                #interrupt-cells = <1>;
+                compatible = "riscv,cpu-intc";
+                interrupt-controller;
+            };
+        };
+
+        cpu at 11 {
+            device_type = "cpu";
+            compatible = "riscv";
+            reg = <0x11>;
+            riscv,isa = "rv64imafdc";
+            mmu-type = "riscv,sv48";
+            cpu-idle-states = <&CPU_RET_1_0 &CPU_NONRET_1_0
+                            &CLUSTER_RET_1 &CLUSTER_NONRET_1>;
+
+            cpu_intc11: interrupt-controller {
+                #interrupt-cells = <1>;
+                compatible = "riscv,cpu-intc";
+                interrupt-controller;
+            };
+        };
+
+        idle-states {
+            CPU_RET_0_0: cpu-retentive-0-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x10000000>;
+                entry-latency-us = <20>;
+                exit-latency-us = <40>;
+                min-residency-us = <80>;
+            };
+
+            CPU_NONRET_0_0: cpu-nonretentive-0-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x90000000>;
+                entry-latency-us = <250>;
+                exit-latency-us = <500>;
+                min-residency-us = <950>;
+            };
+
+            CLUSTER_RET_0: cluster-retentive-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x11000000>;
+                local-timer-stop;
+                entry-latency-us = <50>;
+                exit-latency-us = <100>;
+                min-residency-us = <250>;
+                wakeup-latency-us = <130>;
+            };
+
+            CLUSTER_NONRET_0: cluster-nonretentive-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x91000000>;
+                local-timer-stop;
+                entry-latency-us = <600>;
+                exit-latency-us = <1100>;
+                min-residency-us = <2700>;
+                wakeup-latency-us = <1500>;
+            };
+
+            CPU_RET_1_0: cpu-retentive-1-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x10000010>;
+                entry-latency-us = <20>;
+                exit-latency-us = <40>;
+                min-residency-us = <80>;
+            };
+
+            CPU_NONRET_1_0: cpu-nonretentive-1-0 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x90000010>;
+                entry-latency-us = <250>;
+                exit-latency-us = <500>;
+                min-residency-us = <950>;
+            };
+
+            CLUSTER_RET_1: cluster-retentive-1 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x11000010>;
+                local-timer-stop;
+                entry-latency-us = <50>;
+                exit-latency-us = <100>;
+                min-residency-us = <250>;
+                wakeup-latency-us = <130>;
+            };
+
+            CLUSTER_NONRET_1: cluster-nonretentive-1 {
+                compatible = "riscv,idle-state";
+                riscv,sbi-suspend-param = <0x91000010>;
+                local-timer-stop;
+                entry-latency-us = <600>;
+                exit-latency-us = <1100>;
+                min-residency-us = <2700>;
+                wakeup-latency-us = <1500>;
+            };
+        };
+    };
+
 ...
diff --git a/Documentation/devicetree/bindings/riscv/cpus.yaml b/Documentation/devicetree/bindings/riscv/cpus.yaml
index aa5fb64d57eb..f62f646bc695 100644
--- a/Documentation/devicetree/bindings/riscv/cpus.yaml
+++ b/Documentation/devicetree/bindings/riscv/cpus.yaml
@@ -99,6 +99,12 @@ properties:
       - compatible
       - interrupt-controller
 
+  cpu-idle-states:
+    $ref: '/schemas/types.yaml#/definitions/phandle-array'
+    description: |
+      List of phandles to idle state nodes supported
+      by this hart (see ./idle-states.yaml).
+
 required:
   - riscv,isa
   - interrupt-controller
-- 
2.25.1



From apatel at ventanamicro.com  Wed Jan 26 03:44:52 2022
From: apatel at ventanamicro.com (Anup Patel)
Date: Wed, 26 Jan 2022 17:14:52 +0530
Subject: [PATCH v10 8/8] RISC-V: Enable RISC-V SBI CPU Idle driver for QEMU
 virt machine
In-Reply-To: <20220126114452.692512-1-apatel@ventanamicro.com>
References: <20220126114452.692512-1-apatel@ventanamicro.com>
Message-ID: <20220126114452.692512-9-apatel@ventanamicro.com>

From: Anup Patel <anup.patel at wdc.com>

We enable RISC-V SBI CPU Idle driver for QEMU virt machine to test
SBI HSM Supend on QEMU.

Signed-off-by: Anup Patel <anup.patel at wdc.com>
Signed-off-by: Anup Patel <apatel at ventanamicro.com>
---
 arch/riscv/Kconfig.socs           | 3 +++
 arch/riscv/configs/defconfig      | 1 +
 arch/riscv/configs/rv32_defconfig | 1 +
 3 files changed, 5 insertions(+)

diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index 6ec44a22278a..f4097a815201 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -36,6 +36,9 @@ config SOC_VIRT
 	select GOLDFISH
 	select RTC_DRV_GOLDFISH if RTC_CLASS
 	select SIFIVE_PLIC
+	select PM_GENERIC_DOMAINS if PM
+	select PM_GENERIC_DOMAINS_OF if PM && OF
+	select RISCV_SBI_CPUIDLE if CPU_IDLE
 	help
 	  This enables support for QEMU Virt Machine.
 
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index a5e0482a4969..b8c882b70b02 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -20,6 +20,7 @@ CONFIG_SOC_SIFIVE=y
 CONFIG_SOC_VIRT=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_PM=y
 CONFIG_CPU_IDLE=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig
index d1b87db54d68..6f9a7c89bff9 100644
--- a/arch/riscv/configs/rv32_defconfig
+++ b/arch/riscv/configs/rv32_defconfig
@@ -20,6 +20,7 @@ CONFIG_SOC_VIRT=y
 CONFIG_ARCH_RV32I=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
+CONFIG_PM=y
 CONFIG_CPU_IDLE=y
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM=m
-- 
2.25.1



From shawnguo at kernel.org  Wed Jan 26 03:56:47 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 19:56:47 +0800
Subject: [PATCH] arm64: dts: imx8mn-venice-gw7902: disable gpu
In-Reply-To: <d5a15039255d13cf4321bf1c18f49a9cdb666607.camel@pengutronix.de>
References: <20211216161227.31960-1-tharvey@gateworks.com>
 <20220126093558.GL4686@dragon>
 <d5a15039255d13cf4321bf1c18f49a9cdb666607.camel@pengutronix.de>
Message-ID: <20220126115646.GM4686@dragon>

On Wed, Jan 26, 2022 at 10:58:56AM +0100, Lucas Stach wrote:
> Am Mittwoch, dem 26.01.2022 um 17:35 +0800 schrieb Shawn Guo:
> > On Thu, Dec 16, 2021 at 08:12:27AM -0800, Tim Harvey wrote:
> > > Since commit 99aa29932271 ("arm64: dts: imx8mn: Enable GPU")
> > > imx8mn-venice-gw7902 will hang during kernel init because it uses
> > > a MIMX8MN5CVTI which does not have a GPU.
> > 
> > I do not quite follow on this.  i.MX8MN integrates a GPU, and
> > MIMX8MN5CVTI is built on i.MX8MN, correct?  If so, how comes
> > MIMX8MN5CVTI doesn't have a GPU?
> > 
> It's a fused-down variant of the i.MX8MN that has the GPU disabled by
> fuses.
> 
> > > 
> > > Disable pgc_gpumix to work around this. We also disable the GPU devices
> > > that depend on the gpumix power domain and pgc_gpu to avoid them staying
> > > in a probe deferred state forever.
> > 
> > Is this an indication that GPU should be disabled in imx8mn.dtsi and
> > enabled board by board?
> > 
> There's a trade-off here: most boards will probably use the full
> variants that include the GPU, so probably less boards will need to
> disable the GPU, as done here, than boards that need to enable it when
> the base DT disables the GPU.
> 
> Same story as with the i.MX6 where there are some SKUs that disable the
> VPU by fuses: we enable it in the base DT and if you happen to build a
> very low-cost board that uses the fused-down version you need to
> disable it in the board DT.

Thanks, Lucas!

Patch applied!

Shawn


From daniel.lezcano at linaro.org  Wed Jan 26 03:57:05 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Jan 2022 12:57:05 +0100
Subject: (subset) [PATCH 1/3] ARM: dts: exynos: drop old thermal
 properties from Exynos4210
In-Reply-To: <164313029072.79782.14492454091056440886.b4-ty@canonical.com>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
 <164313029072.79782.14492454091056440886.b4-ty@canonical.com>
Message-ID: <c4a6d5a4-647a-f80c-e487-a5434e744bae@linaro.org>

On 25/01/2022 18:04, Krzysztof Kozlowski wrote:
> On Sat, 22 Jan 2022 14:25:52 +0100, Krzysztof Kozlowski wrote:
>> The samsung,tmu_gain and samsung,tmu_reference_voltage properties of
>> Exynos Thermal Management Unit driver are not used since April 2018.
>> They were removed with commit fccfe0993b5d ("thermal: exynos: remove
>> parsing of samsung,tmu_gain property") and commit 61020d189dbc
>> ("thermal: exynos: remove parsing of samsung, tmu_reference_voltage
>> property"), so drop them also from Exynos4210 DTS.
>>
>> [...]
> 
> Applied, thanks!
> 
> [1/3] ARM: dts: exynos: drop old thermal properties from Exynos4210
>       commit: e20bd06fc421fba4099be51d3f56b9b1741b499b
> 

I guess up to me to pick 2 and 3


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From robin.murphy at arm.com  Wed Jan 26 04:05:22 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 26 Jan 2022 12:05:22 +0000
Subject: [PATCH v2] add cpu frequency to cpuinfo in arm64
In-Reply-To: <20220126092349.285642-1-liuchao173@huawei.com>
References: <20220126092349.285642-1-liuchao173@huawei.com>
Message-ID: <bf7fdba2-7850-9d38-157d-7a1e726512a5@arm.com>

On 2022-01-26 09:23, Chao Liu wrote:
> There is cpu frequency in /proc/cpuinfo in x86 but not in arm64

arm64 cpuinfo also doesn't show the APIC ID or microcode version. 
Different architectures are different.

Besides, x86 cpuinfo only shows MHz if the CPU has X86_FEATURE_TSC, so 
for compatibility we should only do this on AArch64 CPUs which have 
X86_FEATURE_TSC.

Robin.

> Signed-off-by: Chao Liu <liuchao173 at huawei.com>
> ---
> Change in v2:
> - fix spelling errors and remove remove redundant blank line
> 
>   arch/arm64/kernel/cpuinfo.c | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 591c18a889a5..39a36e6e8079 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -24,6 +24,7 @@
>   #include <linux/sched.h>
>   #include <linux/smp.h>
>   #include <linux/delay.h>
> +#include <linux/cpufreq.h>
>   
>   /*
>    * In case the boot CPU is hotpluggable, we record its initial state and
> @@ -144,6 +145,7 @@ static int c_show(struct seq_file *m, void *v)
>   	for_each_online_cpu(i) {
>   		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
>   		u32 midr = cpuinfo->reg_midr;
> +		unsigned int freq = cpufreq_quick_get(i);
>   
>   		/*
>   		 * glibc reads /proc/cpuinfo to determine the number of
> @@ -159,6 +161,10 @@ static int c_show(struct seq_file *m, void *v)
>   			   loops_per_jiffy / (500000UL/HZ),
>   			   loops_per_jiffy / (5000UL/HZ) % 100);
>   
> +		if (freq)
> +			seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
> +				   freq / 1000, (freq % 1000));
> +
>   		/*
>   		 * Dump out the common processor features in a single line.
>   		 * Userspace should read the hwcaps with getauxval(AT_HWCAP)


From shawnguo at kernel.org  Wed Jan 26 04:09:17 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:09:17 +0800
Subject: [PATCH] arm64: dts: imx8qm: Drop CPU 'arm,armv8' compatible
In-Reply-To: <20211217173908.3201517-1-robh@kernel.org>
References: <20211217173908.3201517-1-robh@kernel.org>
Message-ID: <20220126120914.GN4686@dragon>

On Fri, Dec 17, 2021 at 11:39:08AM -0600, Rob Herring wrote:
> The CPU 'arm,armv8' compatible is only for s/w models, so remove it from
> i.MX8QM CPU nodes.
> 
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Sascha Hauer <s.hauer at pengutronix.de>
> Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Rob Herring <robh at kernel.org>

Applied, thanks!


From shawnguo at kernel.org  Wed Jan 26 04:19:01 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:19:01 +0800
Subject: [PATCH] ARM: dts: imx: Add missing LVDS decoder on M53Menlo
In-Reply-To: <20211218152516.256482-1-marex@denx.de>
References: <20211218152516.256482-1-marex@denx.de>
Message-ID: <20220126121900.GO4686@dragon>

On Sat, Dec 18, 2021 at 04:25:16PM +0100, Marek Vasut wrote:
> The M53Menlo display unit uses an LVDS-to-DPI bridge, TI DS90CF364A.
> Describe this bridge in DT, otherwise the DT incorrectly describes
> DPI panel attached directly to LVDS source.
> 
> Fixes: 716be61d1869 ("ARM: dts: imx53: Add Menlosystems M53 board")
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> ---
>  arch/arm/boot/dts/imx53-m53menlo.dts | 27 +++++++++++++++++++++++++--
>  1 file changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
> index 4f88e96d81dd..a1eb36229ef8 100644
> --- a/arch/arm/boot/dts/imx53-m53menlo.dts
> +++ b/arch/arm/boot/dts/imx53-m53menlo.dts
> @@ -53,6 +53,29 @@ eth {
>  		};
>  	};
>  
> +	lvds-decoder {
> +		compatible = "ti,ds90cf364a", "lvds-decoder";

Is this "ti,ds90cf364a" documented anywhere?

> +
> +		ports {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +
> +			port at 0 {
> +				reg = <0>;

Please have a newline between property and child node.

Shawn

> +				lvds_decoder_in: endpoint {
> +					remote-endpoint = <&lvds0_out>;
> +				};
> +			};
> +
> +			port at 1 {
> +				reg = <1>;
> +				lvds_decoder_out: endpoint {
> +					remote-endpoint = <&panel_in>;
> +				};
> +			};
> +		};
> +	};
> +
>  	panel {
>  		compatible = "edt,etm0700g0dh6";
>  		pinctrl-0 = <&pinctrl_display_gpio>;
> @@ -61,7 +84,7 @@ panel {
>  
>  		port {
>  			panel_in: endpoint {
> -				remote-endpoint = <&lvds0_out>;
> +				remote-endpoint = <&lvds_decoder_out>;
>  			};
>  		};
>  	};
> @@ -450,7 +473,7 @@ port at 2 {
>  			reg = <2>;
>  
>  			lvds0_out: endpoint {
> -				remote-endpoint = <&panel_in>;
> +				remote-endpoint = <&lvds_decoder_in>;
>  			};
>  		};
>  	};
> -- 
> 2.33.0
> 


From krzysztof.kozlowski at canonical.com  Wed Jan 26 04:20:02 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Wed, 26 Jan 2022 13:20:02 +0100
Subject: (subset) [PATCH 1/3] ARM: dts: exynos: drop old thermal
 properties from Exynos4210
In-Reply-To: <c4a6d5a4-647a-f80c-e487-a5434e744bae@linaro.org>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
 <164313029072.79782.14492454091056440886.b4-ty@canonical.com>
 <c4a6d5a4-647a-f80c-e487-a5434e744bae@linaro.org>
Message-ID: <CA+Eumj6rUZ=e6oOZyRMEEoXn2uh0FpuUQbJaT3rsX3rhXT67pQ@mail.gmail.com>

On Wed, 26 Jan 2022 at 12:57, Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
>
> On 25/01/2022 18:04, Krzysztof Kozlowski wrote:
> > On Sat, 22 Jan 2022 14:25:52 +0100, Krzysztof Kozlowski wrote:
> >> The samsung,tmu_gain and samsung,tmu_reference_voltage properties of
> >> Exynos Thermal Management Unit driver are not used since April 2018.
> >> They were removed with commit fccfe0993b5d ("thermal: exynos: remove
> >> parsing of samsung,tmu_gain property") and commit 61020d189dbc
> >> ("thermal: exynos: remove parsing of samsung, tmu_reference_voltage
> >> property"), so drop them also from Exynos4210 DTS.
> >>
> >> [...]
> >
> > Applied, thanks!
> >
> > [1/3] ARM: dts: exynos: drop old thermal properties from Exynos4210
> >       commit: e20bd06fc421fba4099be51d3f56b9b1741b499b
> >
>
> I guess up to me to pick 2 and 3

Yes, please.

Best regards,
Krzysztof


From gregkh at linuxfoundation.org  Wed Jan 26 04:20:47 2022
From: gregkh at linuxfoundation.org (Greg Kroah-Hartman)
Date: Wed, 26 Jan 2022 13:20:47 +0100
Subject: [PATCH] usb: gadget: atmel: Revert regression in USB Gadget
 (atmel_usba_udc)
In-Reply-To: <3bb113cd-fbf6-6898-6ae3-2f8cb8c64992@leemhuis.info>
References: <20211211183650.12183-1-marcelo.jimenez@gmail.com>
 <3bb113cd-fbf6-6898-6ae3-2f8cb8c64992@leemhuis.info>
Message-ID: <YfE8nyH1lW/I8NTV@kroah.com>

On Sun, Dec 12, 2021 at 10:48:14AM +0100, Thorsten Leemhuis wrote:
> [TLDR: adding this regression to regzbot; most of this mail is compiled
> from a few templates paragraphs some of you might have seen already.]
> 
> Hi, this is your Linux kernel regression tracker speaking.
> 
> Top-posting for once, to make this easy accessible to everyone.
> 
> Thanks for the report. BTW, if anyone like me wonders what the included
> patch is about: it afaics is the revert of the patch causing the
> problem. Anyway:
> 
> To be sure this issue doesn't fall through the cracks unnoticed, I'm
> adding it to regzbot, my Linux kernel regression tracking bot:
> 
> #regzbot ^introduced 70a7f8be8598
> #regzbot title usb: gadget: atmel: ethernet over USB Gadget not
> recognized anymore after disconnect and reconnect
> #regzbot ignore-activity

How do I say "this isn't a regression, it's a broken board
configuration" and get regzbot to stop tracking this?

thanks,

greg k-h


From houtao1 at huawei.com  Tue Jan 25 02:57:05 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Tue, 25 Jan 2022 18:57:05 +0800
Subject: [PATCH bpf-next v2 0/2] bpf, arm64: fix bpf line info
Message-ID: <20220125105707.292449-1-houtao1@huawei.com>

Hi,

The patchset addresses two issues in bpf line info for arm64:

(1) insn_to_jit_off only considers the body itself and ignores
     prologue before the body. Fixed in patch #1.

(2) insn_to_jit_off passed to bpf_prog_fill_jited_linfo() is
     calculated in instruction granularity instead of bytes
     granularity. Fixed in patch #2.

Comments are always welcome.

Regards,
Tao

Change Log:
v2:
 * split into two independent patches (from Daniel)
 * use AARCH64_INSN_SIZE instead of defining INSN_SIZE

v1: https://lore.kernel.org/bpf/20220104014236.1512639-1-houtao1 at huawei.com

Hou Tao (2):
  bpf, arm64: call build_prologue() first in first JIT pass
  bpf, arm64: calculate offset as byte-offset for bpf line info

 arch/arm64/net/bpf_jit_comp.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

-- 
2.27.0



From houtao1 at huawei.com  Tue Jan 25 02:57:06 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Tue, 25 Jan 2022 18:57:06 +0800
Subject: [PATCH bpf-next v2 1/2] bpf,
 arm64: call build_prologue() first in first JIT pass
In-Reply-To: <20220125105707.292449-1-houtao1@huawei.com>
References: <20220125105707.292449-1-houtao1@huawei.com>
Message-ID: <20220125105707.292449-2-houtao1@huawei.com>

BPF line info needs ctx->offset to be the instruction offset
in the whole jited image instead of the body itself, so also
call build_prologue() first in first JIT pass.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e96d4d87291f..6a83f3070985 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1049,15 +1049,18 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 		goto out_off;
 	}
 
-	/* 1. Initial fake pass to compute ctx->idx. */
-
-	/* Fake pass to fill in ctx->offset. */
-	if (build_body(&ctx, extra_pass)) {
+	/*
+	 * 1. Initial fake pass to compute ctx->idx and ctx->offset.
+	 *
+	 * BPF line info needs ctx->offset[i] to be the offset of
+	 * instruction[i] in jited image, so build prologue first.
+	 */
+	if (build_prologue(&ctx, was_classic)) {
 		prog = orig_prog;
 		goto out_off;
 	}
 
-	if (build_prologue(&ctx, was_classic)) {
+	if (build_body(&ctx, extra_pass)) {
 		prog = orig_prog;
 		goto out_off;
 	}
-- 
2.27.0



From houtao1 at huawei.com  Tue Jan 25 02:57:07 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Tue, 25 Jan 2022 18:57:07 +0800
Subject: [PATCH bpf-next v2 2/2] bpf,
 arm64: calculate offset as byte-offset for bpf line info
In-Reply-To: <20220125105707.292449-1-houtao1@huawei.com>
References: <20220125105707.292449-1-houtao1@huawei.com>
Message-ID: <20220125105707.292449-3-houtao1@huawei.com>

insn_to_jit_off passed to bpf_prog_fill_jited_linfo() is calculated
in instruction granularity instead of bytes granularity, but bpf
line info requires byte offset, so fixing it by calculating offset
as byte-offset.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 6a83f3070985..7b94e0c5e134 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -152,10 +152,12 @@ static inline int bpf2a64_offset(int bpf_insn, int off,
 	bpf_insn++;
 	/*
 	 * Whereas arm64 branch instructions encode the offset
-	 * from the branch itself, so we must subtract 1 from the
+	 * from the branch itself, so we must subtract 4 from the
 	 * instruction offset.
 	 */
-	return ctx->offset[bpf_insn + off] - (ctx->offset[bpf_insn] - 1);
+	return (ctx->offset[bpf_insn + off] -
+		(ctx->offset[bpf_insn] - AARCH64_INSN_SIZE)) /
+		AARCH64_INSN_SIZE;
 }
 
 static void jit_fill_hole(void *area, unsigned int size)
@@ -946,13 +948,14 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
 		const struct bpf_insn *insn = &prog->insnsi[i];
 		int ret;
 
+		/* BPF line info needs byte-offset instead of insn-offset */
 		if (ctx->image == NULL)
-			ctx->offset[i] = ctx->idx;
+			ctx->offset[i] = ctx->idx * AARCH64_INSN_SIZE;
 		ret = build_insn(insn, ctx, extra_pass);
 		if (ret > 0) {
 			i++;
 			if (ctx->image == NULL)
-				ctx->offset[i] = ctx->idx;
+				ctx->offset[i] = ctx->idx * AARCH64_INSN_SIZE;
 			continue;
 		}
 		if (ret)
@@ -964,7 +967,7 @@ static int build_body(struct jit_ctx *ctx, bool extra_pass)
 	 * instruction (end of program)
 	 */
 	if (ctx->image == NULL)
-		ctx->offset[i] = ctx->idx;
+		ctx->offset[i] = ctx->idx * AARCH64_INSN_SIZE;
 
 	return 0;
 }
-- 
2.27.0



From daniel.lezcano at linaro.org  Wed Jan 26 04:26:42 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Wed, 26 Jan 2022 13:26:42 +0100
Subject: (subset) [PATCH 1/3] ARM: dts: exynos: drop old thermal
 properties from Exynos4210
In-Reply-To: <CA+Eumj6rUZ=e6oOZyRMEEoXn2uh0FpuUQbJaT3rsX3rhXT67pQ@mail.gmail.com>
References: <20220122132554.65192-1-krzysztof.kozlowski@canonical.com>
 <164313029072.79782.14492454091056440886.b4-ty@canonical.com>
 <c4a6d5a4-647a-f80c-e487-a5434e744bae@linaro.org>
 <CA+Eumj6rUZ=e6oOZyRMEEoXn2uh0FpuUQbJaT3rsX3rhXT67pQ@mail.gmail.com>
Message-ID: <8fba22fc-3fc1-a55e-9926-7f008ac24925@linaro.org>

On 26/01/2022 13:20, Krzysztof Kozlowski wrote:
> On Wed, 26 Jan 2022 at 12:57, Daniel Lezcano <daniel.lezcano at linaro.org> wrote:
>>
>> On 25/01/2022 18:04, Krzysztof Kozlowski wrote:
>>> On Sat, 22 Jan 2022 14:25:52 +0100, Krzysztof Kozlowski wrote:
>>>> The samsung,tmu_gain and samsung,tmu_reference_voltage properties of
>>>> Exynos Thermal Management Unit driver are not used since April 2018.
>>>> They were removed with commit fccfe0993b5d ("thermal: exynos: remove
>>>> parsing of samsung,tmu_gain property") and commit 61020d189dbc
>>>> ("thermal: exynos: remove parsing of samsung, tmu_reference_voltage
>>>> property"), so drop them also from Exynos4210 DTS.
>>>>
>>>> [...]
>>>
>>> Applied, thanks!
>>>
>>> [1/3] ARM: dts: exynos: drop old thermal properties from Exynos4210
>>>       commit: e20bd06fc421fba4099be51d3f56b9b1741b499b
>>>
>>
>> I guess up to me to pick 2 and 3
> 
> Yes, please.

Ok, I'll wait for Rob's ack

Thanks

  -- Daniel


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From joey.gouly at arm.com  Wed Jan 26 04:27:26 2022
From: joey.gouly at arm.com (Joey Gouly)
Date: Wed, 26 Jan 2022 12:27:26 +0000
Subject: [PATCH v1 5/7] kselftest/arm64: mte: user_mem: check different
 offsets and sizes
In-Reply-To: <YfAmSPPjRCpxg6zB@sirena.org.uk>
References: <20220125150920.23955-1-joey.gouly@arm.com>
 <20220125150920.23955-6-joey.gouly@arm.com>
 <YfAmSPPjRCpxg6zB@sirena.org.uk>
Message-ID: <20220126122726.GA26274@e124191.cambridge.arm.com>

On Tue, Jan 25, 2022 at 04:33:12PM +0000, Mark Brown wrote:
> On Tue, Jan 25, 2022 at 03:09:18PM +0000, Joey Gouly wrote:
> 
> > +	int fileoff, ptroff, size;
> > +	int sizes[] = {1, 2, 3, 8, 16, 32, 4096};
> 
> Assuming the goal is to go up to PAGE_SIZE might it be worth extending
> this to cover the case where the kernel has been built for 64K pages?

Good idea, I will do that for v2 (and 16K).


From shawnguo at kernel.org  Wed Jan 26 04:27:49 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:27:49 +0800
Subject: [RESEND v4 02/10] arm64: dts: freescale: Add the top level dtsi
 support for imx8dxl
In-Reply-To: <1639680494-23183-3-git-send-email-abel.vesa@nxp.com>
References: <1639680494-23183-1-git-send-email-abel.vesa@nxp.com>
 <1639680494-23183-3-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220126122748.GP4686@dragon>

On Thu, Dec 16, 2021 at 08:48:06PM +0200, Abel Vesa wrote:
> From: Jacky Bai <ping.bai at nxp.com>
> 
> The i.MX8DXL is a device targeting the automotive and industrial
> market segments. The flexibility of the architecture allows for
> use in a wide variety of general embedded applications. The chip
> is designed to achieve both high performance and low power consumption.
> The chip relies on the power efficient dual (2x) Cortex-A35 cluster.
> 
> Add the reserved memory node property for dsp reserved memory,
> the wakeup-irq property for SCU node, the imx ion, the rpmsg and the

Not sure what "ion" is.

> cm4 rproc support.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/imx8dxl.dtsi | 245 +++++++++++++++++++++
>  1 file changed, 245 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8dxl.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8dxl.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
> new file mode 100644
> index 000000000000..f16f88882c39
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8dxl.dtsi
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2019-2021 NXP
> + */
> +
> +#include <dt-bindings/clock/imx8-clock.h>
> +#include <dt-bindings/firmware/imx/rsrc.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/pinctrl/pads-imx8dxl.h>
> +#include <dt-bindings/thermal/thermal.h>
> +
> +/ {
> +	interrupt-parent = <&gic>;
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +
> +	aliases {
> +		ethernet0 = &fec1;
> +		ethernet1 = &eqos;
> +		gpio0 = &lsio_gpio0;
> +		gpio1 = &lsio_gpio1;
> +		gpio2 = &lsio_gpio2;
> +		gpio3 = &lsio_gpio3;
> +		gpio4 = &lsio_gpio4;
> +		gpio5 = &lsio_gpio5;
> +		gpio6 = &lsio_gpio6;
> +		gpio7 = &lsio_gpio7;
> +		i2c2 = &i2c2;
> +		i2c3 = &i2c3;
> +		mmc0 = &usdhc1;
> +		mmc1 = &usdhc2;
> +		mu1 = &lsio_mu1;
> +		serial0 = &lpuart0;
> +		serial1 = &lpuart1;
> +		serial2 = &lpuart2;
> +		serial3 = &lpuart3;
> +	};
> +
> +	cpus: cpus {
> +		#address-cells = <2>;
> +		#size-cells = <0>;
> +
> +		/* We have 1 clusters with 2 Cortex-A35 cores */

s/clusters/cluster

> +		A35_0: cpu at 0 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x0>;
> +			enable-method = "psci";
> +			next-level-cache = <&A35_L2>;
> +			clocks = <&clk IMX_SC_R_A35 IMX_SC_PM_CLK_CPU>;
> +			#cooling-cells = <2>;
> +			operating-points-v2 = <&a35_opp_table>;
> +		};
> +
> +		A35_1: cpu at 1 {
> +			device_type = "cpu";
> +			compatible = "arm,cortex-a35";
> +			reg = <0x0 0x1>;
> +			enable-method = "psci";
> +			next-level-cache = <&A35_L2>;
> +			clocks = <&clk IMX_SC_R_A35 IMX_SC_PM_CLK_CPU>;
> +			#cooling-cells = <2>;
> +			operating-points-v2 = <&a35_opp_table>;
> +		};
> +
> +		A35_L2: l2-cache0 {
> +			compatible = "cache";
> +		};
> +	};
> +
> +	a35_opp_table: opp-table {
> +		compatible = "operating-points-v2";
> +		opp-shared;
> +
> +		opp-900000000 {
> +			opp-hz = /bits/ 64 <900000000>;
> +			opp-microvolt = <1000000>;
> +			clock-latency-ns = <150000>;
> +		};
> +
> +		opp-1200000000 {
> +			opp-hz = /bits/ 64 <1200000000>;
> +			opp-microvolt = <1100000>;
> +			clock-latency-ns = <150000>;
> +			opp-suspend;
> +		};
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		dsp_reserved: dsp at 92400000 {
> +			reg = <0 0x92400000 0 0x2000000>;
> +			no-map;
> +		};
> +	};
> +
> +	gic: interrupt-controller at 51a00000 {
> +		compatible = "arm,gic-v3";
> +		reg = <0x0 0x51a00000 0 0x10000>, /* GIC Dist */
> +		      <0x0 0x51b00000 0 0xc0000>; /* GICR (RD_base + SGI_base) */
> +		#interrupt-cells = <3>;
> +		interrupt-controller;
> +		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	pmu {
> +		compatible = "arm,armv8-pmuv3";
> +		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
> +	};
> +
> +	psci {
> +		compatible = "arm,psci-1.0";
> +		method = "smc";
> +	};
> +
> +	scu {
> +		compatible = "fsl,imx-scu";
> +		mbox-names = "tx0",
> +			     "rx0",
> +			     "gip3";
> +		mboxes = <&lsio_mu1 0 0
> +			  &lsio_mu1 1 0
> +			  &lsio_mu1 3 3>;
> +
> +		pd: imx8dxl-pd {
> +			compatible = "fsl,imx8dxl-scu-pd", "fsl,scu-pd";
> +			#power-domain-cells = <1>;
> +		};
> +
> +		clk: clock-controller {
> +			compatible = "fsl,imx8dxl-clk", "fsl,scu-clk";
> +			#clock-cells = <2>;
> +			clocks = <&xtal32k &xtal24m>;
> +			clock-names = "xtal_32KHz", "xtal_24Mhz";
> +		};
> +
> +		iomuxc: pinctrl {
> +			compatible = "fsl,imx8dxl-iomuxc";
> +		};
> +
> +		ocotp: imx8qx-ocotp {
> +			compatible = "fsl,imx8dxl-scu-ocotp", "fsl,imx8qxp-scu-ocotp";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +
> +			fec_mac0: mac at 2c4 {
> +				reg = <0x2c4 6>;
> +			};
> +
> +			fec_mac1: mac at 2c6 {
> +				reg = <0x2c6 6>;
> +			};
> +		};
> +
> +		watchdog {
> +			compatible = "fsl,imx-sc-wdt";
> +			timeout-sec = <60>;
> +		};
> +
> +		tsens: thermal-sensor {
> +			compatible = "fsl,imx-sc-thermal";
> +			#thermal-sensor-cells = <1>;
> +		};
> +	};
> +
> +	timer {
> +		compatible = "arm,armv8-timer";
> +		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */
> +			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */
> +			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */
> +			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */
> +	};
> +
> +	thermal_zones: thermal-zones {
> +		cpu-thermal0 {
> +			polling-delay-passive = <250>;
> +			polling-delay = <2000>;
> +			thermal-sensors = <&tsens IMX_SC_R_SYSTEM>;
> +
> +			trips {
> +				cpu_alert0: trip0 {
> +					temperature = <107000>;
> +					hysteresis = <2000>;
> +					type = "passive";
> +				};

Have a newline between nodes.

> +				cpu_crit0: trip1 {
> +					temperature = <127000>;
> +					hysteresis = <2000>;
> +					type = "critical";
> +				};
> +			};
> +			cooling-maps {
> +				map0 {
> +					trip = <&cpu_alert0>;
> +					cooling-device =
> +					<&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +				};
> +			};
> +		};
> +	};
> +
> +	clk_dummy: clock-dummy {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <0>;
> +		clock-output-names = "clk_dummy";
> +	};

Why do we need this?

Shawn

> +
> +	xtal32k: clock-xtal32k {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <32768>;
> +		clock-output-names = "xtal_32KHz";
> +	};
> +
> +	xtal24m: clock-xtal24m {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <24000000>;
> +		clock-output-names = "xtal_24MHz";
> +	};
> +
> +	sc_pwrkey: sc-powerkey {
> +		compatible = "fsl,imx8-pwrkey";
> +		linux,keycode = <KEY_POWER>;
> +		wakeup-source;
> +	};
> +
> +	/* sorted in register address */
> +	#include "imx8-ss-adma.dtsi"
> +	#include "imx8-ss-conn.dtsi"
> +	#include "imx8-ss-ddr.dtsi"
> +	#include "imx8-ss-lsio.dtsi"
> +};
> +
> +#include "imx8dxl-ss-adma.dtsi"
> +#include "imx8dxl-ss-conn.dtsi"
> +#include "imx8dxl-ss-lsio.dtsi"
> +#include "imx8dxl-ss-ddr.dtsi"
> -- 
> 2.31.1
> 


From maz at kernel.org  Wed Jan 26 04:29:00 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 12:29:00 +0000
Subject: [PATCH v2] add cpu frequency to cpuinfo in arm64
In-Reply-To: <bf7fdba2-7850-9d38-157d-7a1e726512a5@arm.com>
References: <20220126092349.285642-1-liuchao173@huawei.com>
 <bf7fdba2-7850-9d38-157d-7a1e726512a5@arm.com>
Message-ID: <c73a9fb20b42f2086a0fb9c068ecc272@kernel.org>

On 2022-01-26 12:05, Robin Murphy wrote:
> On 2022-01-26 09:23, Chao Liu wrote:
>> There is cpu frequency in /proc/cpuinfo in x86 but not in arm64
> 
> arm64 cpuinfo also doesn't show the APIC ID or microcode version.
> Different architectures are different.
> 
> Besides, x86 cpuinfo only shows MHz if the CPU has X86_FEATURE_TSC, so
> for compatibility we should only do this on AArch64 CPUs which have
> X86_FEATURE_TSC.

/me prepares a patch to be sent in just over 2 months...

         M.
-- 
Jazz is not dead. It just smells funny...


From shawnguo at kernel.org  Wed Jan 26 04:36:34 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:36:34 +0800
Subject: [RESEND v4 04/10] arm64: dts: freescale: Add adma subsystem dtsi
 for imx8dxl
In-Reply-To: <1639680494-23183-5-git-send-email-abel.vesa@nxp.com>
References: <1639680494-23183-1-git-send-email-abel.vesa@nxp.com>
 <1639680494-23183-5-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220126123633.GQ4686@dragon>

On Thu, Dec 16, 2021 at 08:48:08PM +0200, Abel Vesa wrote:
> Override the I2Cs, LPUARTs, audio_ipg_clk and dma_ipg_clk with
> the i.MX8DXL specific properties.
> 
> Signed-off-by: Clark Wang <xiaoning.wang at nxp.com>
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>  .../boot/dts/freescale/imx8dxl-ss-adma.dtsi   | 53 +++++++++++++++++++
>  1 file changed, 53 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> new file mode 100644
> index 000000000000..eccc31ee8f1b
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-adma.dtsi
> @@ -0,0 +1,53 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2019-2021 NXP
> + */
> +
> +&audio_ipg_clk {
> +	clock-frequency = <160000000>;
> +};
> +
> +&dma_ipg_clk {
> +	clock-frequency = <160000000>;
> +};
> +
> +&i2c0 {
> +	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> +	interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&i2c1 {
> +	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> +	interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&i2c2 {
> +	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> +	interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&i2c3 {
> +	compatible = "fsl,imx8dxl-lpi2c", "fsl,imx7ulp-lpi2c";
> +	interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&lpuart0 {
> +	compatible = "fsl,imx8dxl-lpuart", "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&lpuart1 {
> +	compatible = "fsl,imx8dxl-lpuart", "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&lpuart2 {
> +	compatible = "fsl,imx8dxl-lpuart", "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&lpuart3 {
> +	compatible = "fsl,imx8dxl-lpuart", "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
> +	interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +

Drop the newline.

Shawn


From marex at denx.de  Wed Jan 26 04:39:00 2022
From: marex at denx.de (Marek Vasut)
Date: Wed, 26 Jan 2022 13:39:00 +0100
Subject: [PATCH] ARM: dts: imx: Add missing LVDS decoder on M53Menlo
In-Reply-To: <20220126121900.GO4686@dragon>
References: <20211218152516.256482-1-marex@denx.de>
 <20220126121900.GO4686@dragon>
Message-ID: <24f1010a-a722-c931-57e1-ee26e74296d4@denx.de>

On 1/26/22 13:19, Shawn Guo wrote:
> On Sat, Dec 18, 2021 at 04:25:16PM +0100, Marek Vasut wrote:
>> The M53Menlo display unit uses an LVDS-to-DPI bridge, TI DS90CF364A.
>> Describe this bridge in DT, otherwise the DT incorrectly describes
>> DPI panel attached directly to LVDS source.
>>
>> Fixes: 716be61d1869 ("ARM: dts: imx53: Add Menlosystems M53 board")
>> Signed-off-by: Marek Vasut <marex at denx.de>
>> Cc: Shawn Guo <shawnguo at kernel.org>
>> Cc: Fabio Estevam <festevam at gmail.com>
>> Cc: NXP Linux Team <linux-imx at nxp.com>
>> ---
>>   arch/arm/boot/dts/imx53-m53menlo.dts | 27 +++++++++++++++++++++++++--
>>   1 file changed, 25 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
>> index 4f88e96d81dd..a1eb36229ef8 100644
>> --- a/arch/arm/boot/dts/imx53-m53menlo.dts
>> +++ b/arch/arm/boot/dts/imx53-m53menlo.dts
>> @@ -53,6 +53,29 @@ eth {
>>   		};
>>   	};
>>   
>> +	lvds-decoder {
>> +		compatible = "ti,ds90cf364a", "lvds-decoder";
> 
> Is this "ti,ds90cf364a" documented anywhere?

Here is a RB'd patch, currently waiting for someone from dri-devel to 
pick it:

https://patchwork.freedesktop.org/series/98203/

>> +
>> +		ports {
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +
>> +			port at 0 {
>> +				reg = <0>;
> 
> Please have a newline between property and child node.

Maybe you can fix this up when applying ?

Thanks


From shawnguo at kernel.org  Wed Jan 26 04:47:33 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:47:33 +0800
Subject: [RESEND v4 05/10] arm64: dts: freescale: Add the imx8dxl
 connectivity subsys dtsi
In-Reply-To: <1639680494-23183-6-git-send-email-abel.vesa@nxp.com>
References: <1639680494-23183-1-git-send-email-abel.vesa@nxp.com>
 <1639680494-23183-6-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220126124732.GR4686@dragon>

On Thu, Dec 16, 2021 at 08:48:09PM +0200, Abel Vesa wrote:
> From: Jacky Bai <ping.bai at nxp.com>
> 
> On i.MX8DXL, the Connectivity subsystem includes below peripherals:
> 1x ENET with AVB support, 1x ENET with TSN support, 2x USB OTG,
> 1x eMMC, 2x SD, 1x NAND.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>  .../boot/dts/freescale/imx8dxl-ss-conn.dtsi   | 137 ++++++++++++++++++
>  1 file changed, 137 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
> new file mode 100644
> index 000000000000..b0059296a03f
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8dxl-ss-conn.dtsi
> @@ -0,0 +1,137 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2019-2021 NXP
> + */

Shouldn't we include imx8-ss-conn.dtsi here?  Otherwise, the
/delete-node/ and &conn_subsys reference below looks baseless.

> +
> +/delete-node/ &enet1_lpcg;
> +/delete-node/ &fec2;
> +
> +&conn_subsys {
> +	conn_enet0_root_clk: clock-conn-enet0-root {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <250000000>;
> +		clock-output-names = "conn_enet0_root_clk";
> +	};
> +
> +	eqos: ethernet at 5b050000 {
> +		compatible = "nxp,imx8dxl-dwmac-eqos", "snps,dwmac-5.10a";
> +		reg = <0x5b050000 0x10000>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
> +			     <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
> +		interrupt-names = "eth_wake_irq", "macirq";
> +		clocks = <&eqos_lpcg IMX_LPCG_CLK_2>,
> +			 <&eqos_lpcg IMX_LPCG_CLK_4>,
> +			 <&eqos_lpcg IMX_LPCG_CLK_0>,
> +			 <&eqos_lpcg IMX_LPCG_CLK_3>,
> +			 <&eqos_lpcg IMX_LPCG_CLK_1>;
> +		clock-names = "stmmaceth", "pclk", "ptp_ref", "tx", "mem";
> +		assigned-clocks = <&clk IMX_SC_R_ENET_1 IMX_SC_PM_CLK_PER>;
> +		assigned-clock-rates = <125000000>;
> +		power-domains = <&pd IMX_SC_R_ENET_1>;
> +		clk_csr = <0>;

Is this property documented anywhere?

> +		status = "disabled";
> +	};
> +
> +	usbotg2: usb at 5b0e0000 {
> +		compatible = "fsl,imx8dxl-usb", "fsl,imx7ulp-usb";
> +		reg = <0x5b0e0000 0x200>;
> +		interrupt-parent = <&gic>;
> +		interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
> +		fsl,usbphy = <&usbphy2>;
> +		fsl,usbmisc = <&usbmisc2 0>;
> +		/*
> +		 * usbotg1 and usbotg2 share one clcok

s/clcok/clock

> +		 * scfw disable clock access and keep it always on
> +		 * in case other core (M4) use one of these.
> +		 */
> +		clocks = <&clk_dummy>;
> +		ahb-burst-config = <0x0>;
> +		tx-burst-size-dword = <0x10>;
> +		rx-burst-size-dword = <0x10>;
> +		#stream-id-cells = <1>;
> +		power-domains = <&pd IMX_SC_R_USB_1>;
> +		status = "disabled";
> +	};
> +
> +	usbmisc2: usbmisc at 5b0e0200 {
> +		#index-cells = <1>;
> +		compatible = "fsl,imx8dxl-usbmisc", "fsl,imx7ulp-usbmisc";
> +		reg = <0x5b0e0200 0x200>;
> +	};
> +
> +	usbphy2: usbphy at 0x5b110000 {
> +		compatible = "fsl,imx8dxl-usbphy", "fsl,imx7ulp-usbphy";
> +		reg = <0x5b110000 0x1000>;
> +		clocks = <&usb2_2_lpcg IMX_LPCG_CLK_7>;
> +		status = "disabled";
> +	};
> +
> +	eqos_lpcg: clock-controller at 5b240000 {
> +		compatible = "fsl,imx8qxp-lpcg";
> +		reg = <0x5b240000 0x10000>;
> +		#clock-cells = <1>;
> +		clocks = <&conn_enet0_root_clk>,
> +			 <&conn_axi_clk>,
> +			 <&conn_axi_clk>,
> +			 <&clk IMX_SC_R_ENET_1 IMX_SC_PM_CLK_PER>,
> +			 <&conn_ipg_clk>;
> +		clock-indices = <IMX_LPCG_CLK_0>,
> +				<IMX_LPCG_CLK_2>,
> +				<IMX_LPCG_CLK_4>,
> +				<IMX_LPCG_CLK_5>,
> +				<IMX_LPCG_CLK_6>;
> +		clock-output-names = "eqos_ptp",
> +				     "eqos_mem_clk",
> +				     "eqos_aclk",
> +				     "eqos_clk",
> +				     "eqos_csr_clk";
> +		power-domains = <&pd IMX_SC_R_ENET_1>;
> +	};
> +
> +	usb2_2_lpcg: clock-controller at 5b280000 {
> +		compatible = "fsl,imx8qxp-lpcg";
> +		reg = <0x5b280000 0x10000>;
> +		#clock-cells = <1>;
> +

Unneeded newline.

Shawn

> +		clock-indices = <IMX_LPCG_CLK_7>;
> +		clocks = <&conn_ipg_clk>;
> +		clock-output-names = "usboh3_2_phy_ipg_clk";
> +	};
> +
> +};
> +
> +&enet0_lpcg {
> +	clocks = <&conn_enet0_root_clk>,
> +		 <&conn_enet0_root_clk>,
> +		 <&conn_axi_clk>,
> +		 <&clk IMX_SC_R_ENET_0 IMX_SC_C_TXCLK>,
> +		 <&conn_ipg_clk>,
> +		 <&conn_ipg_clk>;
> +};
> +
> +&fec1 {
> +	compatible = "fsl,imx8dxl-fec", "fsl,imx8qm-fec";
> +	interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>,
> +		     <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>;
> +	assigned-clocks = <&clk IMX_SC_R_ENET_0 IMX_SC_C_CLKDIV>;
> +	assigned-clock-rates = <125000000>;
> +};
> +
> +&usdhc1 {
> +	compatible = "fsl,imx8dxl-usdhc", "fsl,imx8qxp-usdhc";
> +	interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&usdhc2 {
> +	compatible = "fsl,imx8dxl-usdhc", "fsl,imx8qxp-usdhc";
> +	interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
> +};
> +
> +&usdhc3 {
> +	compatible = "fsl,imx8dxl-usdhc", "fsl,imx8qxp-usdhc";
> +	interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
> +};
> -- 
> 2.31.1
> 


From alexander.stein at ew.tq-group.com  Wed Jan 26 04:49:46 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 13:49:46 +0100
Subject: (EXT) RE: [PATCH v3 3/4] usb: dwc3: imx8mp: Add support for
 setting SOC specific flags
In-Reply-To: <VI1PR04MB4333E8AA7C261C0B3084D8A489599@VI1PR04MB4333.eurprd04.prod.outlook.com>
References: <20220118131626.926394-1-alexander.stein@ew.tq-group.com>
 <20220118131626.926394-4-alexander.stein@ew.tq-group.com>
 <VI1PR04MB4333E8AA7C261C0B3084D8A489599@VI1PR04MB4333.eurprd04.prod.outlook.com>
Message-ID: <10829327.T7Z3S40VBb@steina-w>

Am Mittwoch, 19. Januar 2022, 15:14:05 CET schrieb Jun Li:
> > -----Original Message-----
> > From: Alexander Stein <alexander.stein at ew.tq-group.com>
> > Sent: Tuesday, January 18, 2022 9:16 PM
> > To: Greg Kroah-Hartman <gregkh at linuxfoundation.org>; Rob Herring
> > <robh+dt at kernel.org>; Shawn Guo <shawnguo at kernel.org>; Sascha Hauer
> > <s.hauer at pengutronix.de>; Fabio Estevam <festevam at gmail.com>
> > Cc: Alexander Stein <alexander.stein at ew.tq-group.com>; dl-linux-imx
> > <linux-imx at nxp.com>; linux-usb at vger.kernel.org;
> > devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Jun Li
> > <jun.li at nxp.com>
> > Subject: [PATCH v3 3/4] usb: dwc3: imx8mp: Add support for setting SOC
> > specific flags
> > 
> > The i.MX8MP glue layer has support for the following flags:
> > * over-current polarity
> > * PWR pad polarity
> > * controlling PPC flag in HCCPARAMS register
> > * permanent port attach for usb2 & usb3 port
> > 
> > Allow setting these flags by supporting specific flags in the glue node.
> > In order to get this to work an additional IORESOURCE_MEM and clock is
> > necessary. For backward compatibility this is purely optional.
> > 
> > Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> > ---
> > 
> >  drivers/usb/dwc3/dwc3-imx8mp.c | 81 ++++++++++++++++++++++++++++++++++
> >  1 file changed, 81 insertions(+)
> > 
> > diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c
> > b/drivers/usb/dwc3/dwc3-imx8mp.c index 1c8fe657b3a9..3df4313b3740 100644
> > --- a/drivers/usb/dwc3/dwc3-imx8mp.c
> > +++ b/drivers/usb/dwc3/dwc3-imx8mp.c
> > @@ -36,17 +36,66 @@
> > 
> >  #define USB_WAKEUP_EN_MASK		GENMASK(5, 0)
> > 
> > +/* USB glue registers */
> > +#define USB_CTRL0		0x00
> > +#define USB_CTRL1		0x04
> > +
> > +#define USB_CTRL0_PORTPWR_EN	BIT(12) /* 1 - PPC enabled (default) */
> > +#define USB_CTRL0_USB3_FIXED	BIT(22) /* 1 - USB3 permanent attached */
> > +#define USB_CTRL0_USB2_FIXED	BIT(23) /* 1 - USB2 permanent attached */
> > +
> > +#define USB_CTRL1_OC_POLARITY	BIT(16) /* 0 - HIGH / 1 - LOW */
> > +#define USB_CTRL1_PWR_POLARITY	BIT(17) /* 0 - HIGH / 1 - LOW */
> > +
> > 
> >  struct dwc3_imx8mp {
> >  
> >  	struct device			*dev;
> >  	struct platform_device		*dwc3;
> >  	void __iomem			*hsio_blk_base;
> > 
> > +	void __iomem			*glue_base;
> > 
> >  	struct clk			*hsio_clk;
> >  	struct clk			*suspend_clk;
> > 
> > +	struct clk			*phy_clk;
> > 
> >  	int				irq;
> >  	bool				pm_suspended;
> >  	bool				wakeup_pending;
> >  
> >  };
> > 
> > +static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx) {
> > +	struct device *dev = dwc3_imx->dev;
> > +	u32 value;
> > +
> > +	if ((!dwc3_imx->glue_base) || (!dwc3_imx->phy_clk))
> > +		return;
> > +
> > +	value = readl(dwc3_imx->glue_base + USB_CTRL0);
> > +
> > +	if (device_property_read_bool(dev, "fsl,permanently-attached"))
> > +		value |= (USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
> > +	else
> > +		value &= ~(USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
> > +
> > +	if (device_property_read_bool(dev,
> > "fsl,disable-port-power-control"))
> > +		value &= ~(USB_CTRL0_PORTPWR_EN);
> > +	else
> > +		value |= USB_CTRL0_PORTPWR_EN;
> > +
> > +	writel(value, dwc3_imx->glue_base + USB_CTRL0);
> > +
> > +	value = readl(dwc3_imx->glue_base + USB_CTRL1);
> > +	if (device_property_read_bool(dev, "fsl,over-current-active-low"))
> > +		value |= USB_CTRL1_OC_POLARITY;
> > +	else
> > +		value &= ~USB_CTRL1_OC_POLARITY;
> > +
> > +	if (device_property_read_bool(dev, "fsl,power-active-low"))
> > +		value |= USB_CTRL1_PWR_POLARITY;
> > +	else
> > +		value &= ~USB_CTRL1_PWR_POLARITY;
> > +
> > +	writel(value, dwc3_imx->glue_base + USB_CTRL1); }
> > +
> > 
> >  static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)  {
> >  
> >  	struct dwc3	*dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
> > 
> > @@ -100,6 +149,7 @@ static int dwc3_imx8mp_probe(struct platform_device
> > *pdev)
> > 
> >  	struct device		*dev = &pdev->dev;
> >  	struct device_node	*dwc3_np, *node = dev->of_node;
> >  	struct dwc3_imx8mp	*dwc3_imx;
> > 
> > +	struct resource		*res;
> > 
> >  	int			err, irq;
> >  	
> >  	if (!node) {
> > 
> > @@ -119,6 +169,15 @@ static int dwc3_imx8mp_probe(struct platform_device
> > *pdev)
> > 
> >  	if (IS_ERR(dwc3_imx->hsio_blk_base))
> >  	
> >  		return PTR_ERR(dwc3_imx->hsio_blk_base);
> > 
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
> > +	if (!res) {
> > +		dev_warn(dev, "Base address for glue layer missing. 
Continuing
> > without, some features are missing though.");
> > +	} else {
> > +		dwc3_imx->glue_base = devm_ioremap_resource(dev, res);
> > +		if (IS_ERR(dwc3_imx->glue_base))
> > +			return PTR_ERR(dwc3_imx->glue_base);
> > +	}
> > +
> > 
> >  	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
> >  	if (IS_ERR(dwc3_imx->hsio_clk)) {
> >  	
> >  		err = PTR_ERR(dwc3_imx->hsio_clk);
> > 
> > @@ -145,6 +204,24 @@ static int dwc3_imx8mp_probe(struct platform_device
> > *pdev)
> > 
> >  		goto disable_hsio_clk;
> >  	
> >  	}
> > 
> > +	dwc3_imx->phy_clk = devm_clk_get(dev, "phy");
> > +	if (PTR_ERR(dwc3_imx->phy_clk) == -ENOENT) {
> > +		dev_warn(dev, "PHY clock missing. Continuing without, 
some features
> > are missing though.");

Hi,

> What feature needs phy clock turned on here, why phy driver turns on
> this clock is not enough for you?

I have to admit that the clock name 'phy' might be misleading. In this case 
the actual clock is IMX8MP_CLK_USB_PHY_ROOT. Apparently this clock (or a 
dependent) is necessary to access the USB3_GLUE block in imx8mp. This block 
contains the USB3_CTRL0/USB3_CTRL1, we want to access in this case, as well as 
the PHY registers, hence the name I guess.
While it is true that phy-fsl-imx8mq-usb enables this clock as well, there is 
no guarantee this lock is enabled when we want to access the GLUE registers.
Depending on the probe order it is actually possible the clock is disabled 
while dwc3-imx8mp being probed, resulting in a system lockup.
This happens especially if there is only one USB host enabled and the drivers 
are built as modules.

Meanwhile I noticed [1] landed last week. So I gave it a try. With that in 
place there is no need to use IMX8MP_CLK_USB_PHY_ROOT in this driver anymore.
As it turns out IMX8MP_CLK_USB_ROOT is the required clock (used by imx8mp-blk-
ctrl for USB power domain).
With that, I'll send a new version based on Lucas' patchset.

Thanks for the feedback
Alexander

[1] https://patchwork.kernel.org/project/linux-arm-kernel/cover/
20220119134027.2931945-1-l.stach at pengutronix.de/





From broonie at kernel.org  Wed Jan 26 04:52:22 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 12:52:22 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <87h79q7tln.wl-maz@kernel.org>
References: <20220125192851.3907611-1-broonie@kernel.org>
 <87h79q7tln.wl-maz@kernel.org>
Message-ID: <YfFEBlsUH+dMxmku@sirena.org.uk>

On Wed, Jan 26, 2022 at 09:07:48AM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> >  	/* Distributor setup */
> > -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> > +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);

> So you now only test whether it is possible to create a virtual GICv3,
> but don't actually create it. How does this work?

Oh, that's rather obscure in the API - so the file descriptor returned
if the test flag is specified can't actually be used?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/ab5a3211/attachment-0001.sig>

From shawnguo at kernel.org  Wed Jan 26 04:53:55 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:53:55 +0800
Subject: [RESEND v4 08/10] arm64: dts: imx8dxl: Add i.MX8DXL evk board
 support
In-Reply-To: <1639680494-23183-9-git-send-email-abel.vesa@nxp.com>
References: <1639680494-23183-1-git-send-email-abel.vesa@nxp.com>
 <1639680494-23183-9-git-send-email-abel.vesa@nxp.com>
Message-ID: <20220126125355.GS4686@dragon>

On Thu, Dec 16, 2021 at 08:48:12PM +0200, Abel Vesa wrote:
> From: Jacky Bai <ping.bai at nxp.com>
> 
> Add i.MX8DXL EVK board support.
> 
> Signed-off-by: Jacky Bai <ping.bai at nxp.com>
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
> ---
>  arch/arm64/boot/dts/freescale/Makefile        |   1 +
>  arch/arm64/boot/dts/freescale/imx8dxl-evk.dts | 266 ++++++++++++++++++
>  2 files changed, 267 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
> index 5018b8b1e5f2..f117d3e811ba 100644
> --- a/arch/arm64/boot/dts/freescale/Makefile
> +++ b/arch/arm64/boot/dts/freescale/Makefile
> @@ -72,6 +72,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-thor96.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-rmb3.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-zest.dtb
> +dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb

Keep the list sorted.

>  dtb-$(CONFIG_ARCH_MXC) += imx8qm-mek.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
>  dtb-$(CONFIG_ARCH_MXC) += imx8qxp-colibri-eval-v3.dtb
> diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
> new file mode 100644
> index 000000000000..68dfe722af6d
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
> @@ -0,0 +1,266 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright 2019-2021 NXP
> + */
> +
> +/dts-v1/;
> +
> +#include "imx8dxl.dtsi"
> +
> +/ {
> +	model = "Freescale i.MX8DXL EVK";
> +	compatible = "fsl,imx8dxl-evk", "fsl,imx8dxl";
> +
> +	chosen {
> +		stdout-path = &lpuart0;
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x00000000 0x80000000 0 0x40000000>;
> +	};
> +
> +	reserved-memory {
> +		#address-cells = <2>;
> +		#size-cells = <2>;
> +		ranges;
> +
> +		/*
> +		 * 0x8800_0000 ~ 0x8FFF_FFFF is reserved for M4
> +		 * Shouldn't be used at A core and Linux side.
> +		 *
> +		 */
> +		m4_reserved: m4 at 88000000 {
> +			no-map;
> +			reg = <0 0x88000000 0 0x8000000>;
> +		};
> +
> +		/* global autoconfigured region for contiguous allocations */
> +		linux,cma {
> +			compatible = "shared-dma-pool";
> +			reusable;
> +			size = <0 0x14000000>;
> +			alloc-ranges = <0 0x98000000 0 0x14000000>;
> +			linux,cma-default;
> +		};
> +	};
> +
> +	reg_usdhc2_vmmc: usdhc2-vmmc {
> +		compatible = "regulator-fixed";
> +		regulator-name = "SD1_SPWR";
> +		regulator-min-microvolt = <3000000>;
> +		regulator-max-microvolt = <3000000>;
> +		gpio = <&lsio_gpio4 30 GPIO_ACTIVE_HIGH>;
> +		enable-active-high;
> +		off-on-delay-us = <3480>;
> +	};
> +};
> +
> +&lpuart0 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart0>;
> +	status = "okay";
> +};
> +
> +&lpuart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart1>;
> +	status = "okay";
> +};
> +
> +&lsio_gpio4 {
> +	status = "okay";
> +};
> +
> +&lsio_gpio5 {
> +	status = "okay";
> +};
> +
> +&thermal_zones {
> +	pmic-thermal0 {
> +		polling-delay-passive = <250>;
> +		polling-delay = <2000>;
> +		thermal-sensors = <&tsens IMX_SC_R_PMIC_0>;

Have a newline between property and child node.

> +		trips {
> +			pmic_alert0: trip0 {
> +				temperature = <110000>;
> +				hysteresis = <2000>;
> +				type = "passive";
> +			};

Have a newline between nodes.

> +			pmic_crit0: trip1 {
> +				temperature = <125000>;
> +				hysteresis = <2000>;
> +				type = "critical";
> +			};
> +		};
> +		cooling-maps {
> +			map0 {
> +				trip = <&pmic_alert0>;
> +				cooling-device =
> +					<&A35_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
> +					<&A35_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
> +			};
> +		};
> +	};
> +};
> +
> +&usdhc1 {
> +		pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +		pinctrl-0 = <&pinctrl_usdhc1>;
> +		pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
> +		pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
> +		bus-width = <8>;
> +		no-sd;
> +		no-sdio;
> +		non-removable;
> +		status = "okay";

One level of indent is good enough.

> +};
> +
> +&usdhc2 {
> +		pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +		pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
> +		pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
> +		pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
> +		bus-width = <4>;
> +		vmmc-supply = <&reg_usdhc2_vmmc>;
> +		cd-gpios = <&lsio_gpio5 1 GPIO_ACTIVE_LOW>;
> +		wp-gpios = <&lsio_gpio5 0 GPIO_ACTIVE_HIGH>;
> +		max-frequency = <100000000>;
> +		status = "okay";
> +};
> +
> +&iomuxc {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_hog>;
> +
> +	pinctrl_hog: hoggrp {
> +		fsl,pins = <
> +			IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD	0x000514a0
> +			IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK_PAD	0x000014a0
> +			IMX8DXL_SPI3_CS0_ADMA_ACM_MCLK_OUT1		0x0600004c
> +			IMX8DXL_SNVS_TAMPER_OUT1_LSIO_GPIO2_IO05_IN	0x0600004c
> +		>;
> +	};
> +
> +	pinctrl_i2c2: i2c2grp {
> +		fsl,pins = <
> +			IMX8DXL_SPI1_SCK_ADMA_I2C2_SDA		0x06000021
> +			IMX8DXL_SPI1_SDO_ADMA_I2C2_SCL		0x06000021
> +		>;
> +	};
> +
> +	pinctrl_i2c3: i2c3grp {
> +		fsl,pins = <
> +			IMX8DXL_SPI1_CS0_ADMA_I2C3_SDA		0x06000021
> +			IMX8DXL_SPI1_SDI_ADMA_I2C3_SCL		0x06000021
> +		>;
> +	};
> +
> +	pinctrl_lpuart0: lpuart0grp {
> +		fsl,pins = <
> +			IMX8DXL_UART0_RX_ADMA_UART0_RX		0x06000020
> +			IMX8DXL_UART0_TX_ADMA_UART0_TX		0x06000020
> +		>;
> +	};
> +
> +	pinctrl_lpuart1: lpuart1grp {
> +		fsl,pins = <
> +			IMX8DXL_UART1_TX_ADMA_UART1_TX          0x06000020
> +			IMX8DXL_UART1_RX_ADMA_UART1_RX          0x06000020
> +			IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B    0x06000020
> +			IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B    0x06000020
> +		>;
> +	};
> +
> +	pinctrl_usdhc1: usdhc1grp {
> +		fsl,pins = <
> +			IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK	0x06000041
> +			IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD	0x00000021
> +			IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0	0x00000021
> +			IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1	0x00000021
> +			IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2	0x00000021
> +			IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3	0x00000021
> +			IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4	0x00000021
> +			IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5	0x00000021
> +			IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6	0x00000021
> +			IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7	0x00000021
> +			IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE	0x00000041
> +		>;
> +	};
> +
> +	pinctrl_usdhc1_100mhz: usdhc1grp100mhz {

For sake of consistency, we probably should still end the node name with 'grp'.

Shawn

> +		fsl,pins = <
> +			IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK	0x06000041
> +			IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD	0x00000021
> +			IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0	0x00000021
> +			IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1	0x00000021
> +			IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2	0x00000021
> +			IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3	0x00000021
> +			IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4	0x00000021
> +			IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5	0x00000021
> +			IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6	0x00000021
> +			IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7	0x00000021
> +			IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE	0x00000041
> +		>;
> +	};
> +
> +	pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
> +		fsl,pins = <
> +			IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK	0x06000041
> +			IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD	0x00000021
> +			IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0	0x00000021
> +			IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1	0x00000021
> +			IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2	0x00000021
> +			IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3	0x00000021
> +			IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4	0x00000021
> +			IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5	0x00000021
> +			IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6	0x00000021
> +			IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7	0x00000021
> +			IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE	0x00000041
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_gpio: usdhc2gpiogrp {
> +		fsl,pins = <
> +			IMX8DXL_ENET0_RGMII_TX_CTL_LSIO_GPIO4_IO30	0x00000040 /* RESET_B */
> +			IMX8DXL_ENET0_RGMII_TXD1_LSIO_GPIO5_IO00	0x00000021 /* WP */
> +			IMX8DXL_ENET0_RGMII_TXD2_LSIO_GPIO5_IO01	0x00000021 /* CD */
> +		>;
> +	};
> +
> +	pinctrl_usdhc2: usdhc2grp {
> +		fsl,pins = <
> +			IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK		0x06000041
> +			IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3	0x00000021
> +			IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC1_VSELECT	0x00000021
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
> +		fsl,pins = <
> +			IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK		0x06000041
> +			IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3	0x00000021
> +			IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC1_VSELECT	0x00000021
> +		>;
> +	};
> +
> +	pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
> +		fsl,pins = <
> +			IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK		0x06000041
> +			IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2	0x00000021
> +			IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3	0x00000021
> +			IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC1_VSELECT	0x00000021
> +		>;
> +	};
> +};
> -- 
> 2.31.1
> 


From regressions at leemhuis.info  Wed Jan 26 04:54:08 2022
From: regressions at leemhuis.info (Thorsten Leemhuis)
Date: Wed, 26 Jan 2022 13:54:08 +0100
Subject: [PATCH] usb: gadget: atmel: Revert regression in USB Gadget
 (atmel_usba_udc)
In-Reply-To: <YfE8nyH1lW/I8NTV@kroah.com>
References: <20211211183650.12183-1-marcelo.jimenez@gmail.com>
 <3bb113cd-fbf6-6898-6ae3-2f8cb8c64992@leemhuis.info>
 <YfE8nyH1lW/I8NTV@kroah.com>
Message-ID: <1aed666b-e812-91be-f412-af073b1a320b@leemhuis.info>

On 26.01.22 13:20, Greg Kroah-Hartman wrote:
> On Sun, Dec 12, 2021 at 10:48:14AM +0100, Thorsten Leemhuis wrote:
>> [TLDR: adding this regression to regzbot; most of this mail is compiled
>> from a few templates paragraphs some of you might have seen already.]
>>
>> Hi, this is your Linux kernel regression tracker speaking.
>>
>> Top-posting for once, to make this easy accessible to everyone.
>>
>> Thanks for the report. BTW, if anyone like me wonders what the included
>> patch is about: it afaics is the revert of the patch causing the
>> problem. Anyway:
>>
>> To be sure this issue doesn't fall through the cracks unnoticed, I'm
>> adding it to regzbot, my Linux kernel regression tracking bot:
>>
>> #regzbot ^introduced 70a7f8be8598
>> #regzbot title usb: gadget: atmel: ethernet over USB Gadget not
>> recognized anymore after disconnect and reconnect
>> #regzbot ignore-activity
> 
> How do I say "this isn't a regression, it's a broken board
> configuration" and get regzbot to stop tracking this?

Like this:

#regzbot invalid: not a regression, it's a broken board configuration

And it's hereby done. :-D

TWIMC, this documents explains all regzbot commands:
https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md

Ciao, Thorsten



From shawnguo at kernel.org  Wed Jan 26 04:56:51 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 20:56:51 +0800
Subject: [PATCH 1/1] arm64: dts: tqma8mqml: add PCIe support
In-Reply-To: <20211217102207.722897-1-alexander.stein@ew.tq-group.com>
References: <20211217102207.722897-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220126125648.GT4686@dragon>

On Fri, Dec 17, 2021 at 11:22:07AM +0100, Alexander Stein wrote:
> Add PCIe support to TQMa8MxML series.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

It doesn't apply to my imx/dt64 branch.  Could you rebase?

Shawn

> ---
> This goes on top of the series recently applied to pci/dwc [1]:
> [PATCH v7 0/8] Add the imx8m pcie phy driver and imx8mm pcie support
> [1] https://patchwork.kernel.org/project/linux-pci/list/?series=589031&state=*
> 
>  .../dts/freescale/imx8mm-tqma8mqml-mba8mx.dts | 19 +++++++++++++++++++
>  .../boot/dts/freescale/imx8mm-tqma8mqml.dtsi  |  5 +++++
>  arch/arm64/boot/dts/freescale/mba8mx.dtsi     |  6 ++++++
>  3 files changed, 30 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
> index 7844878788f4..286d2df01cfa 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
> @@ -5,6 +5,7 @@
>  
>  /dts-v1/;
>  
> +#include <dt-bindings/phy/phy-imx8-pcie.h>
>  #include "imx8mm-tqma8mqml.dtsi"
>  #include "mba8mx.dtsi"
>  
> @@ -58,6 +59,24 @@ expander2: gpio at 27 {
>  	};
>  };
>  
> +&pcie_phy {
> +	clocks = <&pcie0_refclk>;
> +	status = "okay";
> +};
> +
> +&pcie0 {
> +	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
> +	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
> +		<&pcie0_refclk>;
> +	clock-names = "pcie", "pcie_aux", "pcie_bus";
> +	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
> +				<&clk IMX8MM_CLK_PCIE1_CTRL>;
> +	assigned-clock-rates = <10000000>, <250000000>;
> +	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
> +				<&clk IMX8MM_SYS_PLL2_250M>;
> +	status = "okay";
> +};
> +
>  &sai3 {
>  	assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
>  	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
> index 284e62acc0b4..16ee9b5179e6 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
> @@ -227,6 +227,11 @@ eeprom0: eeprom at 57 {
>  	};
>  };
>  
> +&pcie_phy {
> +	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
> +	fsl,clkreq-unsupported;
> +};
> +
>  &usdhc3 {
>  	pinctrl-names = "default", "state_100mhz", "state_200mhz";
>  	pinctrl-0 = <&pinctrl_usdhc3>;
> diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
> index e694dacb16af..42e12c190e9e 100644
> --- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
> +++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
> @@ -87,6 +87,12 @@ panel_in_lvds0: endpoint {
>  		};
>  	};
>  
> +	pcie0_refclk: pcie0-refclk {
> +		compatible = "fixed-clock";
> +		#clock-cells = <0>;
> +		clock-frequency = <100000000>;
> +	};
> +
>  	reg_12v: regulator-12v {
>  		compatible = "regulator-fixed";
>  		regulator-name = "MBA8MX_12V";
> -- 
> 2.25.1
> 


From shawnguo at kernel.org  Wed Jan 26 05:02:56 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 21:02:56 +0800
Subject: [PATCH] ARM: dts: imx: Add missing LVDS decoder on M53Menlo
In-Reply-To: <24f1010a-a722-c931-57e1-ee26e74296d4@denx.de>
References: <20211218152516.256482-1-marex@denx.de>
 <20220126121900.GO4686@dragon>
 <24f1010a-a722-c931-57e1-ee26e74296d4@denx.de>
Message-ID: <20220126130255.GU4686@dragon>

On Wed, Jan 26, 2022 at 01:39:00PM +0100, Marek Vasut wrote:
> On 1/26/22 13:19, Shawn Guo wrote:
> > On Sat, Dec 18, 2021 at 04:25:16PM +0100, Marek Vasut wrote:
> > > The M53Menlo display unit uses an LVDS-to-DPI bridge, TI DS90CF364A.
> > > Describe this bridge in DT, otherwise the DT incorrectly describes
> > > DPI panel attached directly to LVDS source.
> > > 
> > > Fixes: 716be61d1869 ("ARM: dts: imx53: Add Menlosystems M53 board")
> > > Signed-off-by: Marek Vasut <marex at denx.de>
> > > Cc: Shawn Guo <shawnguo at kernel.org>
> > > Cc: Fabio Estevam <festevam at gmail.com>
> > > Cc: NXP Linux Team <linux-imx at nxp.com>
> > > ---
> > >   arch/arm/boot/dts/imx53-m53menlo.dts | 27 +++++++++++++++++++++++++--
> > >   1 file changed, 25 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
> > > index 4f88e96d81dd..a1eb36229ef8 100644
> > > --- a/arch/arm/boot/dts/imx53-m53menlo.dts
> > > +++ b/arch/arm/boot/dts/imx53-m53menlo.dts
> > > @@ -53,6 +53,29 @@ eth {
> > >   		};
> > >   	};
> > > +	lvds-decoder {
> > > +		compatible = "ti,ds90cf364a", "lvds-decoder";
> > 
> > Is this "ti,ds90cf364a" documented anywhere?
> 
> Here is a RB'd patch, currently waiting for someone from dri-devel to pick
> it:
> 
> https://patchwork.freedesktop.org/series/98203/

I will have to wait till it lands.

Shawn

> 
> > > +
> > > +		ports {
> > > +			#address-cells = <1>;
> > > +			#size-cells = <0>;
> > > +
> > > +			port at 0 {
> > > +				reg = <0>;
> > 
> > Please have a newline between property and child node.
> 
> Maybe you can fix this up when applying ?
> 
> Thanks


From jszhang at kernel.org  Wed Jan 26 04:55:22 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Wed, 26 Jan 2022 20:55:22 +0800
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <Ye2SznI2rNKAUDIq@lunn.ch>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
 <Ye2SznI2rNKAUDIq@lunn.ch>
Message-ID: <YfFEulZJKzuRQfeG@xhacker>

On Sun, Jan 23, 2022 at 06:39:26PM +0100, Andrew Lunn wrote:
> > I think this is a common issue because the MAC needs phy's RXC for RX
> > logic. But it's better to let other stmmac users verify. The issue
> > can easily be reproduced on platforms with PHY_POLL external phy.
> 
> What is the relevance of PHY polling here? Are you saying if the PHY
> is using interrupts you do not see this issue?

I tried these two days, if the PHY is using interrupts, I can't
reproduce the issue. It looks a bit more complex. Any suggestions?

Thanks in advance


From maz at kernel.org  Wed Jan 26 05:05:01 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 13:05:01 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <YfFEBlsUH+dMxmku@sirena.org.uk>
References: <20220125192851.3907611-1-broonie@kernel.org>
 <87h79q7tln.wl-maz@kernel.org> <YfFEBlsUH+dMxmku@sirena.org.uk>
Message-ID: <87czke7ima.wl-maz@kernel.org>

On Wed, 26 Jan 2022 12:52:22 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> On Wed, Jan 26, 2022 at 09:07:48AM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > >  	/* Distributor setup */
> > > -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> > > +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
> 
> > So you now only test whether it is possible to create a virtual GICv3,
> > but don't actually create it. How does this work?
> 
> Oh, that's rather obscure in the API - so the file descriptor returned
> if the test flag is specified can't actually be used?

No file descriptor is returned at all from the kernel, so you should
always get -1 as populated by kvm_create_device().

See virt/kvm/kvm_main.c::kvm_ioctl_create_device().

	M.

-- 
Without deviation from the norm, progress is not possible.


From shawnguo at kernel.org  Wed Jan 26 05:06:33 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 21:06:33 +0800
Subject: [PATCH v2 2/2] arm64: dts: imx: add Protonic PRT8MM board
In-Reply-To: <20211217213617.3793534-2-l.stach@pengutronix.de>
References: <20211217213617.3793534-1-l.stach@pengutronix.de>
 <20211217213617.3793534-2-l.stach@pengutronix.de>
Message-ID: <20220126130632.GV4686@dragon>

On Fri, Dec 17, 2021 at 10:36:17PM +0100, Lucas Stach wrote:
> From: David Jander <david at protonic.nl>
> 
> The Protonic PRT8MM is a low-cost agricultural Virtual Terminal. This
> commit adds most of the board functionality sans the display output,
> as the i.MX8MM display support isn't ready yet.
> 
> Signed-off-by: David Jander <david at protonic.nl>
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> ---
>  .../boot/dts/freescale/imx8mm-prt8mm.dts      | 304 ++++++++++++++++++
>  1 file changed, 304 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts b/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts
> new file mode 100644
> index 000000000000..13330ad67760
> --- /dev/null
> +++ b/arch/arm64/boot/dts/freescale/imx8mm-prt8mm.dts
> @@ -0,0 +1,304 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright 2020 Protonic Holland
> + * Copyright 2019 NXP
> + */
> +
> +/dts-v1/;
> +
> +#include <dt-bindings/usb/pd.h>
> +#include "imx8mm.dtsi"
> +
> +/ {
> +	model = "Protonic PRT8MM";
> +	compatible = "prt,prt8mm", "fsl,imx8mm";
> +
> +	chosen {
> +		stdout-path = &uart4;
> +	};
> +
> +	memory at 40000000 {
> +		device_type = "memory";
> +		reg = <0x0 0x40000000 0 0x40000000>;
> +	};
> +
> +	leds {
> +		compatible = "gpio-leds";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_gpio_leds>;
> +
> +		debug-led0 {
> +			label = "DEBUG_LED0";
> +			gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "heartbeat";
> +		};
> +
> +		debug-led1 {
> +			label = "DEBUG_LED1";
> +			gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
> +			linux,default-trigger = "cpu";
> +		};
> +	};
> +
> +	sound-ssm2518 {
> +		compatible = "simple-audio-card";
> +		simple-audio-card,name = "ssm2518-audio";
> +		simple-audio-card,format = "i2s";
> +		simple-audio-card,frame-master = <&cpudai>;
> +		simple-audio-card,bitclock-master = <&cpudai>;
> +
> +		cpudai: simple-audio-card,cpu {
> +			sound-dai = <&sai3>;
> +		};
> +
> +		simple-audio-card,codec {
> +			sound-dai = <&ssm2518>;
> +			clocks = <&clk IMX8MM_CLK_SAI3_ROOT>;
> +		};
> +	};
> +};
> +
> +&i2c1 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c1>;
> +	status = "okay";
> +
> +	ssm2518: audio-codec at 34 {
> +		compatible = "adi,ssm2518";
> +		reg = <0x34>;
> +		#sound-dai-cells = <0>;
> +	};
> +};
> +
> +&i2c2 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c2>;
> +	status = "okay";
> +
> +	regulator at 60 {
> +		compatible = "fcs,fan53555";
> +		reg = <0x60>;
> +		regulator-name = "0V9_CORE";
> +		regulator-min-microvolt = <900000>;
> +		regulator-max-microvolt = <980000>;
> +		regulator-boot-on;
> +		regulator-always-on;
> +	};
> +};
> +
> +&i2c3 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c3>;
> +	status = "okay";
> +
> +	rtc at 51 {
> +		compatible = "nxp,pcf85363";
> +		reg = <0x51>;
> +	};
> +
> +	temp-sense at 70 {
> +		compatible = "ti,tmp103";
> +		reg = <0x70>;
> +	};
> +
> +	touchscreeen at 5d {

slave-address order is broken.  I fixed it up and applied both.

Shawn

> +		compatible = "goodix,gt911";
> +		reg = <0x5d>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_touchscreen>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <8 IRQ_TYPE_NONE>;
> +		irq-gpios = <&gpio1 8 GPIO_ACTIVE_HIGH>;
> +		reset-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
> +	};
> +};
> +
> +&sai3 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_sai3>;
> +	assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
> +	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
> +	assigned-clock-rates = <12288000>;
> +	fsl,sai-mclk-direction-output;
> +	fsl,sai-asynchronous;
> +	status = "okay";
> +};
> +
> +&snvs_pwrkey {
> +	status = "okay";
> +};
> +
> +&uart4 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_uart4>;
> +	status = "okay";
> +};
> +
> +&usbotg1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_usbotg1>;
> +	dr_mode = "host";
> +	disable-over-current;
> +	power-active-high;
> +	status = "okay";
> +};
> +
> +&usdhc2 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_usdhc2>;
> +	assigned-clocks = <&clk IMX8MM_CLK_USDHC2>;
> +	assigned-clock-rates = <100000000>;
> +	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
> +	bus-width = <4>;
> +	status = "okay";
> +};
> +
> +&usdhc3 {
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz";
> +	pinctrl-0 = <&pinctrl_usdhc3>;
> +	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
> +	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
> +	assigned-clocks = <&clk IMX8MM_CLK_USDHC3_ROOT>;
> +	assigned-clock-rates = <400000000>;
> +	bus-width = <8>;
> +	non-removable;
> +	no-sdio;
> +	no-sd;
> +	status = "okay";
> +};
> +
> +&wdog1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_wdog>;
> +	fsl,ext-reset-output;
> +	status = "okay";
> +};
> +
> +&iomuxc {
> +	pinctrl_gpio_leds: ledsgrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_NAND_ALE_GPIO3_IO0			0x00
> +			MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1		0x00
> +		>;
> +	};
> +
> +	pinctrl_i2c1: i2c1grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400000c3
> +			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400000c3
> +		>;
> +	};
> +
> +	pinctrl_i2c2: i2c2grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL			0x400000c3
> +			MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA			0x400000c3
> +		>;
> +	};
> +
> +	pinctrl_i2c3: i2c3grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL			0x400000c3
> +			MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400000c3
> +		>;
> +	};
> +
> +	pinctrl_sai3: sai3grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC		0xd6
> +			MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK		0xd6
> +			MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK		0xd6
> +			MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0		0xd6
> +		>;
> +	};
> +
> +	pinctrl_touchscreen: tsgrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x80
> +			MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x80
> +		>;
> +	};
> +
> +	pinctrl_uart4: uart4grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX		0x040
> +			MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX		0x040
> +		>;
> +	};
> +
> +	pinctrl_usbotg1: usbotg1grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_GPIO1_IO12_USB1_OTG_PWR		0x000
> +			MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC		0x000
> +		>;
> +	};
> +
> +	pinctrl_usdhc2: usdhc2grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x190
> +			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d0
> +			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0
> +			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0
> +			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0
> +			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0
> +			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x0d4
> +		>;
> +	};
> +
> +	pinctrl_usdhc3: usdhc3grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x190
> +			MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d0
> +			MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d0
> +			MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d0
> +			MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d0
> +			MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d0
> +			MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d0
> +			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d0
> +			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d0
> +			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d0
> +			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x190
> +		>;
> +	};
> +
> +	pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x194
> +			MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d4
> +			MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d4
> +			MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d4
> +			MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d4
> +			MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d4
> +			MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d4
> +			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d4
> +			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d4
> +			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d4
> +			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x194
> +		>;
> +	};
> +
> +	pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x196
> +			MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d6
> +			MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d6
> +			MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d6
> +			MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d6
> +			MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d6
> +			MX8MM_IOMUXC_NAND_RE_B_USDHC3_DATA4		0x1d6
> +			MX8MM_IOMUXC_NAND_CE2_B_USDHC3_DATA5		0x1d6
> +			MX8MM_IOMUXC_NAND_CE3_B_USDHC3_DATA6		0x1d6
> +			MX8MM_IOMUXC_NAND_CLE_USDHC3_DATA7		0x1d6
> +			MX8MM_IOMUXC_NAND_CE1_B_USDHC3_STROBE		0x196
> +		>;
> +	};
> +
> +	pinctrl_wdog: wdoggrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6
> +		>;
> +	};
> +};
> -- 
> 2.30.2
> 


From shawnguo at kernel.org  Wed Jan 26 05:10:34 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 21:10:34 +0800
Subject: [PATCH v2] arm64: dts: imx8mq: disable DDRC node by default
In-Reply-To: <20211218181808.235310-1-dev@lynxeye.de>
References: <20211218181808.235310-1-dev@lynxeye.de>
Message-ID: <20220126131033.GW4686@dragon>

On Sat, Dec 18, 2021 at 07:18:08PM +0100, Lucas Stach wrote:
> Without a OPP table or a downstream TF-A running on the system the DDRC will
> fail to probe, as it has no means to scale the DRAM frequency in that case.
> This however will block the bus scaling driver to come up and this in turn
> prevents other devices that hook into the interconnect from probing.
> 
> If the DDRC is disabled, the interconnect driver will simply ignore it. As
> most systems don't want to scale the DRAM frequency, disable the node by
> default and only enable it on the systems that actually uses this
> capability and provides a valid OPP table in the DT.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>
> Reviewed-by: Fabio Estevam <festevam at gmail.com>
> Acked-by: Martin Kepplinger <martin.kepplinger at puri.sm>
> Reviewed-by: Guido G?nther <agx at sigxcpu.org>

Applied, thanks!


From shawnguo at kernel.org  Wed Jan 26 05:13:34 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 21:13:34 +0800
Subject: [PATCH v2 1/2] arm64: dts: mnt-reform2: add internal display
 support
In-Reply-To: <20211218182021.235561-1-dev@lynxeye.de>
References: <20211218182021.235561-1-dev@lynxeye.de>
Message-ID: <20220126131333.GX4686@dragon>

On Sat, Dec 18, 2021 at 07:20:20PM +0100, Lucas Stach wrote:
> This adds support for the internal display of the Reform2 Laptop, which
> is connected to the i.MX8MQ via a MIPI-DSI->eDP bridge chip. Clocking
> is derived from a system PLL, which provides quite good rate matching
> for the single supported display mode and keeps the video PLL free for
> usage with the external display, which isn't supported yet.
> 
> Signed-off-by: Lucas Stach <dev at lynxeye.de>

Applied both, thanks!


From shawnguo at kernel.org  Wed Jan 26 05:17:17 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Wed, 26 Jan 2022 21:17:17 +0800
Subject: [PATCH] ARM: dts: imx6qdl-udoo: Properly describe the SD card
 detect
In-Reply-To: <20211219224215.1043447-1-festevam@gmail.com>
References: <20211219224215.1043447-1-festevam@gmail.com>
Message-ID: <20220126131716.GY4686@dragon>

On Sun, Dec 19, 2021 at 07:42:15PM -0300, Fabio Estevam wrote:
> GPIO7_IO00 is used as SD card detect.
> 
> Properly describe this in the devicetree.
> 
> Fixes: 40cdaa542cf0 ("ARM: dts: imx6q-udoo: Add initial board support")
> Signed-off-by: Fabio Estevam <festevam at gmail.com>

Applied, thanks!


From zajec5 at gmail.com  Wed Jan 26 05:21:16 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 26 Jan 2022 14:21:16 +0100
Subject: [PATCH] dt-bindings: watchdog: brcm,
 bcm7038: add more compatible strings
Message-ID: <20220126132116.11070-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This hardware block is used on almost all BCM63xx family chipsets and
BCM4908 which reuses a lot of BCM63xx parts. Add relevant compatible
strings and also include a generic one.

The only SoC with a different block I found is BCM6838 (thus not included
in this change).

It may be worth noting that BCM6338, BCM6345, BCM6348 and BCM63268 don't
include "SoftRst" register but that can be handled by drivers based on
precise compatible string.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
 .../bindings/watchdog/brcm,bcm7038-wdt.yaml   | 21 +++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
index a926809352b8..b663f360f571 100644
--- a/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
@@ -16,9 +16,22 @@ maintainers:
 
 properties:
   compatible:
-    enum:
-      - brcm,bcm6345-wdt
-      - brcm,bcm7038-wdt
+    items:
+      - enum:
+          - brcm,bcm4908-wdt
+          - brcm,bcm60333-wdt
+          - brcm,bcm63138-wdt
+          - brcm,bcm63148-wdt
+          - brcm,bcm63268-wdt
+          - brcm,bcm63381-wdt
+          - brcm,bcm6848-wdt
+          - brcm,bcm6858-wdt
+          - brcm,bcm68360-wdt
+          - brcm,bcm6338-wdt
+          - brcm,bcm6345-wdt
+          - brcm,bcm6348-wdt
+          - brcm,bcm7038-wdt
+      - const: brcm,bcm63xx-wdt
 
   reg:
     maxItems: 1
@@ -37,7 +50,7 @@ required:
 examples:
   - |
     watchdog at f040a7e8 {
-      compatible = "brcm,bcm7038-wdt";
+      compatible = "brcm,bcm7038-wdt", "brcm,bcm63xx-wdt";
       reg = <0xf040a7e8 0x16>;
       clocks = <&upg_fixed>;
     };
-- 
2.31.1



From broonie at kernel.org  Wed Jan 26 05:21:17 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 13:21:17 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <87czke7ima.wl-maz@kernel.org>
References: <20220125192851.3907611-1-broonie@kernel.org>
 <87h79q7tln.wl-maz@kernel.org> <YfFEBlsUH+dMxmku@sirena.org.uk>
 <87czke7ima.wl-maz@kernel.org>
Message-ID: <YfFKzWxNd5l26Ebk@sirena.org.uk>

On Wed, Jan 26, 2022 at 01:05:01PM +0000, Marc Zyngier wrote:
> Mark Brown <broonie at kernel.org> wrote:

> > > So you now only test whether it is possible to create a virtual GICv3,
> > > but don't actually create it. How does this work?

> > Oh, that's rather obscure in the API - so the file descriptor returned
> > if the test flag is specified can't actually be used?

> No file descriptor is returned at all from the kernel, so you should
> always get -1 as populated by kvm_create_device().

> See virt/kvm/kvm_main.c::kvm_ioctl_create_device().

Ugh, right - the descriptor is returned separately to the return code
but is then mapped onto the return code by the library since the library
just aborts on error in the non-test case and in the test case the kernel
returns an inverted boolean which gets passed straight through.  Like I
say the API seems a bit confusing here.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/8f3f7fff/attachment.sig>

From andrew at lunn.ch  Wed Jan 26 05:21:39 2022
From: andrew at lunn.ch (Andrew Lunn)
Date: Wed, 26 Jan 2022 14:21:39 +0100
Subject: [PATCH] arm64: dts: ls1028a-qds: define mdio slots for
 networking options
In-Reply-To: <20220126092650.19962-1-leoyang.li@nxp.com>
References: <20220126092650.19962-1-leoyang.li@nxp.com>
Message-ID: <YfFK426N+0Y/UTEI@lunn.ch>

On Wed, Jan 26, 2022 at 03:26:50AM -0600, Li Yang wrote:
> The ls1028a QDS board support different pluggable PHY cards.  Define the
> nodes for these slots to be updated at boot time with overlay according
> to board setup.
> 
> Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>

Reviewed-by: Andrew Lunn <andrew at lunn.ch>

    Andrew


From alexander.stein at ew.tq-group.com  Wed Jan 26 05:23:38 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 14:23:38 +0100
Subject: [PATCH v2 1/1] arm64: dts: tqma8mqml: add PCIe support
Message-ID: <20220126132339.60683-1-alexander.stein@ew.tq-group.com>

Add PCIe support to TQMa8MxML series.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
This goes on top of the series recently applied to pci/dwc [1]:
[PATCH v7 0/8] Add the imx8m pcie phy driver and imx8mm pcie support

Changes in v2:
* rebased to Shawn's current imx/dt64 (as of 2022/01/26)

[1] https://patchwork.kernel.org/project/linux-pci/list/?series=589031&state=*

 .../dts/freescale/imx8mm-tqma8mqml-mba8mx.dts | 19 +++++++++++++++++++
 .../boot/dts/freescale/imx8mm-tqma8mqml.dtsi  |  5 +++++
 arch/arm64/boot/dts/freescale/mba8mx.dtsi     |  6 ++++++
 3 files changed, 30 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
index 7844878788f4..286d2df01cfa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml-mba8mx.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/phy/phy-imx8-pcie.h>
 #include "imx8mm-tqma8mqml.dtsi"
 #include "mba8mx.dtsi"
 
@@ -58,6 +59,24 @@ expander2: gpio at 27 {
 	};
 };
 
+&pcie_phy {
+	clocks = <&pcie0_refclk>;
+	status = "okay";
+};
+
+&pcie0 {
+	reset-gpio = <&expander0 14 GPIO_ACTIVE_LOW>;
+	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+		<&pcie0_refclk>;
+	clock-names = "pcie", "pcie_aux", "pcie_bus";
+	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+				<&clk IMX8MM_CLK_PCIE1_CTRL>;
+	assigned-clock-rates = <10000000>, <250000000>;
+	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+				<&clk IMX8MM_SYS_PLL2_250M>;
+	status = "okay";
+};
+
 &sai3 {
 	assigned-clocks = <&clk IMX8MM_CLK_SAI3>;
 	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index 284e62acc0b4..16ee9b5179e6 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -227,6 +227,11 @@ eeprom0: eeprom at 57 {
 	};
 };
 
+&pcie_phy {
+	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_INPUT>;
+	fsl,clkreq-unsupported;
+};
+
 &usdhc3 {
 	pinctrl-names = "default", "state_100mhz", "state_200mhz";
 	pinctrl-0 = <&pinctrl_usdhc3>;
diff --git a/arch/arm64/boot/dts/freescale/mba8mx.dtsi b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
index f27e3c8de916..3ea34b3a55f8 100644
--- a/arch/arm64/boot/dts/freescale/mba8mx.dtsi
+++ b/arch/arm64/boot/dts/freescale/mba8mx.dtsi
@@ -66,6 +66,12 @@ led2: led2 {
 		};
 	};
 
+	pcie0_refclk: pcie0-refclk {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <100000000>;
+	};
+
 	reg_hub_vbus: regulator-hub-vbus {
 		compatible = "regulator-fixed";
 		regulator-name = "MBA8MX_HUB_VBUS";
-- 
2.25.1



From linux at armlinux.org.uk  Wed Jan 26 05:27:34 2022
From: linux at armlinux.org.uk (Russell King (Oracle))
Date: Wed, 26 Jan 2022 13:27:34 +0000
Subject: [PATCH] net: stmmac: don't stop RXC during LPI
In-Reply-To: <YfFEulZJKzuRQfeG@xhacker>
References: <20220123141245.1060-1-jszhang@kernel.org>
 <Ye15va7tFWMgKPEE@lunn.ch> <Ye19bHxcQ5Plx0v9@xhacker>
 <Ye2SznI2rNKAUDIq@lunn.ch> <YfFEulZJKzuRQfeG@xhacker>
Message-ID: <YfFMRoLixWR/8spY@shell.armlinux.org.uk>

On Wed, Jan 26, 2022 at 08:55:22PM +0800, Jisheng Zhang wrote:
> On Sun, Jan 23, 2022 at 06:39:26PM +0100, Andrew Lunn wrote:
> > > I think this is a common issue because the MAC needs phy's RXC for RX
> > > logic. But it's better to let other stmmac users verify. The issue
> > > can easily be reproduced on platforms with PHY_POLL external phy.
> > 
> > What is the relevance of PHY polling here? Are you saying if the PHY
> > is using interrupts you do not see this issue?
> 
> I tried these two days, if the PHY is using interrupts, I can't
> reproduce the issue. It looks a bit more complex. Any suggestions?

I suppose it could be that there is a delay between the PHY reporting
the link loss, raising an interrupt, which is then processed to disable
the receive side, and the PHY going into LPI. The problem with polling
is, well, it's polling, and at a one second rate - which probably is too
long between the PHY noticing the loss of link and going into LPI.

What this also probably means is that if interrupt latency is high
enough, the same problem will occur.

So maybe the EEE support to be a little more clever - so we only enable
clock stop after the MAC driver has disabled the receive side.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!


From maz at kernel.org  Wed Jan 26 05:32:28 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 13:32:28 +0000
Subject: [PATCH] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <YfFKzWxNd5l26Ebk@sirena.org.uk>
References: <20220125192851.3907611-1-broonie@kernel.org>
 <87h79q7tln.wl-maz@kernel.org> <YfFEBlsUH+dMxmku@sirena.org.uk>
 <87czke7ima.wl-maz@kernel.org> <YfFKzWxNd5l26Ebk@sirena.org.uk>
Message-ID: <87bkzy7hcj.wl-maz@kernel.org>

aOn Wed, 26 Jan 2022 13:21:17 +0000,
Mark Brown <broonie at kernel.org> wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> On Wed, Jan 26, 2022 at 01:05:01PM +0000, Marc Zyngier wrote:
> > Mark Brown <broonie at kernel.org> wrote:
> 
> > > > So you now only test whether it is possible to create a virtual GICv3,
> > > > but don't actually create it. How does this work?
> 
> > > Oh, that's rather obscure in the API - so the file descriptor returned
> > > if the test flag is specified can't actually be used?
> 
> > No file descriptor is returned at all from the kernel, so you should
> > always get -1 as populated by kvm_create_device().
> 
> > See virt/kvm/kvm_main.c::kvm_ioctl_create_device().
> 
> Ugh, right - the descriptor is returned separately to the return code
> but is then mapped onto the return code by the library since the library
> just aborts on error in the non-test case and in the test case the kernel
> returns an inverted boolean which gets passed straight through.  Like I
> say the API seems a bit confusing here.

That's a very... "kind" way of putting it.

	M.

-- 
Without deviation from the norm, progress is not possible.


From marex at denx.de  Wed Jan 26 05:35:46 2022
From: marex at denx.de (Marek Vasut)
Date: Wed, 26 Jan 2022 14:35:46 +0100
Subject: [PATCH] ARM: dts: imx: Add missing LVDS decoder on M53Menlo
In-Reply-To: <20220126130255.GU4686@dragon>
References: <20211218152516.256482-1-marex@denx.de>
 <20220126121900.GO4686@dragon> <24f1010a-a722-c931-57e1-ee26e74296d4@denx.de>
 <20220126130255.GU4686@dragon>
Message-ID: <f14f7241-7456-bcd5-b741-cd89905f1bbd@denx.de>

On 1/26/22 14:02, Shawn Guo wrote:
> On Wed, Jan 26, 2022 at 01:39:00PM +0100, Marek Vasut wrote:
>> On 1/26/22 13:19, Shawn Guo wrote:
>>> On Sat, Dec 18, 2021 at 04:25:16PM +0100, Marek Vasut wrote:
>>>> The M53Menlo display unit uses an LVDS-to-DPI bridge, TI DS90CF364A.
>>>> Describe this bridge in DT, otherwise the DT incorrectly describes
>>>> DPI panel attached directly to LVDS source.
>>>>
>>>> Fixes: 716be61d1869 ("ARM: dts: imx53: Add Menlosystems M53 board")
>>>> Signed-off-by: Marek Vasut <marex at denx.de>
>>>> Cc: Shawn Guo <shawnguo at kernel.org>
>>>> Cc: Fabio Estevam <festevam at gmail.com>
>>>> Cc: NXP Linux Team <linux-imx at nxp.com>
>>>> ---
>>>>    arch/arm/boot/dts/imx53-m53menlo.dts | 27 +++++++++++++++++++++++++--
>>>>    1 file changed, 25 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/imx53-m53menlo.dts b/arch/arm/boot/dts/imx53-m53menlo.dts
>>>> index 4f88e96d81dd..a1eb36229ef8 100644
>>>> --- a/arch/arm/boot/dts/imx53-m53menlo.dts
>>>> +++ b/arch/arm/boot/dts/imx53-m53menlo.dts
>>>> @@ -53,6 +53,29 @@ eth {
>>>>    		};
>>>>    	};
>>>> +	lvds-decoder {
>>>> +		compatible = "ti,ds90cf364a", "lvds-decoder";
>>>
>>> Is this "ti,ds90cf364a" documented anywhere?
>>
>> Here is a RB'd patch, currently waiting for someone from dri-devel to pick
>> it:
>>
>> https://patchwork.freedesktop.org/series/98203/
> 
> I will have to wait till it lands.

Of course.


From marcelo.jimenez at gmail.com  Wed Jan 26 05:43:17 2022
From: marcelo.jimenez at gmail.com (Marcelo Roberto Jimenez)
Date: Wed, 26 Jan 2022 10:43:17 -0300
Subject: [PATCH] usb: gadget: atmel: Revert regression in USB Gadget
 (atmel_usba_udc)
In-Reply-To: <CACjc_5o9eO5YTVt4jE7v1E9nirCwFMc1=Ub-jXSFCg1_8A2M-A@mail.gmail.com>
References: <20211211183650.12183-1-marcelo.jimenez@gmail.com>
 <3bb113cd-fbf6-6898-6ae3-2f8cb8c64992@leemhuis.info>
 <YfE8nyH1lW/I8NTV@kroah.com>
 <CACjc_5o9eO5YTVt4jE7v1E9nirCwFMc1=Ub-jXSFCg1_8A2M-A@mail.gmail.com>
Message-ID: <CACjc_5pmqLAo5X-Yj6Om9vvktR-0FN5SYgDxn=GvCn-yxcee+w@mail.gmail.com>

Hi Greg,

On Wed, Jan 26, 2022 at 9:20 AM Greg Kroah-Hartman
<gregkh at linuxfoundation.org> wrote:
> On Sun, Dec 12, 2021 at 10:48:14AM +0100, Thorsten Leemhuis wrote:
> > [TLDR: adding this regression to regzbot; most of this mail is compiled
> > from a few templates paragraphs some of you might have seen already.]
> >
> > Hi, this is your Linux kernel regression tracker speaking.
> >
> > Top-posting for once, to make this easy accessible to everyone.
> >
> > Thanks for the report. BTW, if anyone like me wonders what the included
> > patch is about: it afaics is the revert of the patch causing the
> > problem. Anyway:
> >
> > To be sure this issue doesn't fall through the cracks unnoticed, I'm
> > adding it to regzbot, my Linux kernel regression tracking bot:
> >
> > #regzbot ^introduced 70a7f8be8598
> > #regzbot title usb: gadget: atmel: ethernet over USB Gadget not
> > recognized anymore after disconnect and reconnect
> > #regzbot ignore-activity
>
> How do I say "this isn't a regression, it's a broken board
> configuration" and get regzbot to stop tracking this?

I sent the logs to Cristian on Jan, 14, but I don't know if they were
helpful. The problem is pretty much reproducible here. I understand
that from the previously quoted specification sentence, the hardware
must perform VBUS sensing, and this is something I can confirm the
hardware is not capable of. But if Cristian cannot reproduce it in a
different SOC configured without a VBUS sensing pin, I can only hope
Microchip/Atmel will look into the issue. On my side, it seems like I
will have to maintain a patched kernel for this hardware.

So, let's move on.

> thanks,
>
> greg k-h

Best regards,
Marcelo.


From alexander.stein at ew.tq-group.com  Wed Jan 26 05:51:58 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 14:51:58 +0100
Subject: (EXT) [PATCH 9/9] arm64: dts: imx8mp: add GPU nodes
In-Reply-To: <20220119134027.2931945-10-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-10-l.stach@pengutronix.de>
Message-ID: <4527167.VLH7GnMWUR@steina-w>

Am Mittwoch, 19. Januar 2022, 14:40:27 CET schrieb Lucas Stach:
> Add the DT nodes for both the 3D and 2D GPU cores found on the i.MX8MP.
> 
> etnaviv-gpu 38000000.gpu: model: GC7000, revision: 6204
> etnaviv-gpu 38008000.gpu: model: GC520, revision: 5341
> [drm] Initialized etnaviv 1.3.0 20151214 for etnaviv on minor 0

Unfortunately it does not work when CONFIG_DRM_ETNAVIV=m
etnaviv-gpu 38000000.gpu: model: GC0, revision: 0
etnaviv-gpu 38000000.gpu: Unknown GPU model
etnaviv-gpu 38008000.gpu: model: GC0, revision: 0
etnaviv-gpu 38008000.gpu: Unknown GPU model

When I use CONFIG_DRM_ETNAVIV=y, I get the same log message as you. It's not 
related to this patch, but I have no clue if the cause is in blk-ctrl or pgc.

I think (don't know for sure yet) my random errors on USB side are gone when 
USB drivers (PHY as well) are built-in. But I might be wrong here.

Best regards,
Alexander





From broonie at kernel.org  Wed Jan 26 05:53:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 13:53:19 +0000
Subject: [PATCH v2] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
Message-ID: <20220126135319.1918802-1-broonie@kernel.org>

The arch_timer and vgic_irq kselftests assume that they can create a
vgic-v3, using the library function vgic_v3_setup() which aborts with a
test failure if it is not possible to do so. Since vgic-v3 can only be
instantiated on systems where the host has GICv3 this leads to false
positives on older systems where that is not the case.

Fix this by changing vgic_v3_setup() to return an error if the vgic can't
be instantiated and have the callers skip if this happens. We could also
exit flagging a skip in vgic_v3_setup() but this would prevent future test
cases conditionally deciding which GIC to use or generally doing more
complex output.

Signed-off-by: Mark Brown <broonie at kernel.org>
---

v2:
 - The test for being able to create the GIC doesn't actually
   instantiate it, add a call doing so in that case.

 tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
 tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
 tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 5 ++++-
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index 9ad38bd360a4..791d38404652 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
 {
 	struct kvm_vm *vm;
 	unsigned int i;
+	int ret;
 	int nr_vcpus = test_args.nr_vcpus;
 
 	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
@@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
 
 	ucall_init(vm, NULL);
 	test_init_timer_irq(vm);
-	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	if (ret < 0) {
+		pr_info("Failed to create vgic-v3, skipping\n");
+		exit(KSFT_SKIP);
+	}
 
 	/* Make all the test's cmdline args visible to the guest */
 	sync_global_to_guest(vm, test_args);
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
index e6c7d7f8fbd1..b127a261fd29 100644
--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
@@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
 
 	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
 			GICD_BASE_GPA, GICR_BASE_GPA);
+	if (gic_fd < 0) {
+		pr_info("Failed to create vgic-v3, skipping\n");
+		exit(KSFT_SKIP);
+	}
 
 	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
 		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
index b3a0fca0d780..4ea65e119bdd 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
@@ -51,7 +51,10 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
 			"Number of vCPUs requested (%u) doesn't match with the ones created for the VM (%u)\n",
 			nr_vcpus, nr_vcpus_created);
 
-	/* Distributor setup */
+	/* Distributor setup - test if it's possible then actually do it */
+	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
+	if (gic_fd != 0)
+		return -1;
 	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
 
 	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
-- 
2.30.2



From wanngchenng at gmail.com  Wed Jan 26 06:00:09 2022
From: wanngchenng at gmail.com (Wang Cheng)
Date: Wed, 26 Jan 2022 22:00:09 +0800
Subject: [BUG] drivers/perf: hisi: kernel fails to boot since commit
 ac4511c9364c "drivers/perf: hisi: Add identifier sysfs file"
In-Reply-To: <2508ac09-0722-1d86-9eed-883ccded199c@hisilicon.com>
References: <20220125143541.uvgmumsd2mezdmnc@ppc.localdomain>
 <2508ac09-0722-1d86-9eed-883ccded199c@hisilicon.com>
Message-ID: <20220126140009.ln7zdwta2h5hpulw@ppc.localdomain>

Hi Shaokun,

On 22/01/26 10:24AM, Shaokun Zhang wrote:
>
> As John said that some guys has reported the similiar issue on this
> chip.

Thanks for your time, John. I think the problem in this report is same
with mine.

>
> I'm checking with the BIOS guy and which version they fix the issue.
> I will give the right BIOS and can you help to try it?

Of course, I'd like to have a try.
Here is my BIOS info:
$ cat /sys/class/dmi/id/bios_vendor
ZdTech
$ cat /sys/class/dmi/id/bios_version
KL.4.008.200605
$ cat /sys/class/dmi/id/bios_date
06/05/2020

Thanks,
--
Cheng


From alexander.stein at ew.tq-group.com  Wed Jan 26 06:02:51 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:02:51 +0100
Subject: (EXT) [PATCH 7/9] arm64: dts: imx8mp: add HSIO power-domains
In-Reply-To: <20220119134027.2931945-8-l.stach@pengutronix.de>
References: <20220119134027.2931945-1-l.stach@pengutronix.de>
 <20220119134027.2931945-8-l.stach@pengutronix.de>
Message-ID: <4713370.usQuhbGJ8B@steina-w>

Hi Lucas,

Am Mittwoch, 19. Januar 2022, 14:40:25 CET schrieb Lucas Stach:
> This adds the GPC and HSIO blk-ctrl nodes providing power control for
> the high-speed (USB and PCIe) IOs.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

$ make dtbs_check DT_SCHEMA_FILES=Documentation/devicetree/bindings/usb/
fsl,imx8mp-dwc3.yaml gives the warnings:
> usb at 32f10100: 'power-domains' does not match any of the regexes: 
'^usb@[0-9a-f]+$', 'pinctrl-[0-9]+'
>         From schema: linux/Documentation/devicetree/bindings/usb/fsl,imx8mp-
dwc3.yaml
> usb at 32f10108: 'power-domains' does not match any of the regexes: 
'^usb@[0-9a-f]+$', 'pinctrl-[0-9]+'
>         From schema: linux/Documentation/devicetree/bindings/usb/fsl,imx8mp-
dwc3.yaml

Alexander

> ---
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi | 63 ++++++++++++++++++++---
>  1 file changed, 57 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index
> 04d259de5667..b76af96b9b5c 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
> @@ -4,6 +4,7 @@
>   */
> 
>  #include <dt-bindings/clock/imx8mp-clock.h>
> +#include <dt-bindings/power/imx8mp-power.h>
>  #include <dt-bindings/gpio/gpio.h>
>  #include <dt-bindings/input/input.h>
>  #include <dt-bindings/interrupt-controller/arm-gic.h>
> @@ -443,6 +444,44 @@ src: reset-controller at 30390000 {
>  				interrupts = <GIC_SPI 89 
IRQ_TYPE_LEVEL_HIGH>;
>  				#reset-cells = <1>;
>  			};
> +
> +			gpc: gpc at 303a0000 {
> +				compatible = "fsl,imx8mp-gpc";
> +				reg = <0x303a0000 0x10000>;
> +				interrupt-parent = <&gic>;
> +				interrupt-controller;
> +				#interrupt-cells = <3>;
> +
> +				pgc {
> +					#address-cells = <1>;
> +					#size-cells = <0>;
> +
> +					pgc_pcie_phy: power-
domain at 1 {
> +						#power-
domain-cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_PCIE_PHY>;
> +					};
> +
> +					pgc_usb1_phy: power-
domain at 2 {
> +						#power-
domain-cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_USB1_PHY>;
> +					};
> +
> +					pgc_usb2_phy: power-
domain at 3 {
> +						#power-
domain-cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_USB2_PHY>;
> +					};
> +
> +					pgc_hsiomix: power-
domains at 17 {
> +						#power-
domain-cells = <0>;
> +						reg = 
<IMX8MP_POWER_DOMAIN_HSIOMIX>;
> +						clocks = 
<&clk IMX8MP_CLK_HSIO_AXI>,
> +							 
<&clk IMX8MP_CLK_HSIO_ROOT>;
> +						assigned-
clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
> +						assigned-
clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
> +						assigned-
clock-rates = <500000000>;
> +					};
> +				};
> +			};
>  		};
> 
>  		aips2: bus at 30400000 {
> @@ -875,6 +914,20 @@ ddr-pmu at 3d800000 {
>  			interrupts = <GIC_SPI 98 
IRQ_TYPE_LEVEL_HIGH>;
>  		};
> 
> +		hsio_blk_ctrl: blk-ctrl at 32f10000 {
> +			compatible = "fsl,imx8mp-hsio-blk-ctrl", 
"syscon";
> +			reg = <0x32f10000 0x24>;
> +			clocks = <&clk IMX8MP_CLK_USB_ROOT>,
> +				 <&clk IMX8MP_CLK_PCIE_ROOT>;
> +			clock-names = "usb", "pcie";
> +			power-domains = <&pgc_hsiomix>, 
<&pgc_hsiomix>,
> +					<&pgc_usb1_phy>, 
<&pgc_usb2_phy>,
> +					<&pgc_hsiomix>, 
<&pgc_pcie_phy>;
> +			power-domain-names = "bus", "usb", "usb-
phy1",
> +					     "usb-phy2", 
"pcie", "pcie-phy";
> +			#power-domain-cells = <1>;
> +		};
> +
>  		usb3_phy0: usb-phy at 381f0040 {
>  			compatible = "fsl,imx8mp-usb-phy";
>  			reg = <0x381f0040 0x40>;
> @@ -882,6 +935,7 @@ usb3_phy0: usb-phy at 381f0040 {
>  			clock-names = "phy";
>  			assigned-clocks = <&clk 
IMX8MP_CLK_USB_PHY_REF>;
>  			assigned-clock-parents = <&clk 
IMX8MP_CLK_24M>;
> +			power-domains = <&hsio_blk_ctrl 
IMX8MP_HSIOBLK_PD_USB_PHY1>;
>  			#phy-cells = <0>;
>  			status = "disabled";
>  		};
> @@ -893,6 +947,7 @@ usb3_0: usb at 32f10100 {
>  				 <&clk IMX8MP_CLK_USB_ROOT>;
>  			clock-names = "hsio", "suspend";
>  			interrupts = <GIC_SPI 148 
IRQ_TYPE_LEVEL_HIGH>;
> +			power-domains = <&hsio_blk_ctrl 
IMX8MP_HSIOBLK_PD_USB>;
>  			#address-cells = <1>;
>  			#size-cells = <1>;
>  			dma-ranges = <0x40000000 0x40000000 
0xc0000000>;
> @@ -906,9 +961,6 @@ usb_dwc3_0: usb at 38100000 {
>  					 <&clk 
IMX8MP_CLK_USB_CORE_REF>,
>  					 <&clk 
IMX8MP_CLK_USB_ROOT>;
>  				clock-names = "bus_early", "ref", 
"suspend";
> -				assigned-clocks = <&clk 
IMX8MP_CLK_HSIO_AXI>;
> -				assigned-clock-parents = <&clk 
IMX8MP_SYS_PLL2_500M>;
> -				assigned-clock-rates = 
<500000000>;
>  				interrupts = <GIC_SPI 40 
IRQ_TYPE_LEVEL_HIGH>;
>  				phys = <&usb3_phy0>, <&usb3_phy0>;
>  				phy-names = "usb2-phy", "usb3-
phy";
> @@ -924,6 +976,7 @@ usb3_phy1: usb-phy at 382f0040 {
>  			clock-names = "phy";
>  			assigned-clocks = <&clk 
IMX8MP_CLK_USB_PHY_REF>;
>  			assigned-clock-parents = <&clk 
IMX8MP_CLK_24M>;
> +			power-domains = <&hsio_blk_ctrl 
IMX8MP_HSIOBLK_PD_USB_PHY2>;
>  			#phy-cells = <0>;
>  		};
> 
> @@ -934,6 +987,7 @@ usb3_1: usb at 32f10108 {
>  				 <&clk IMX8MP_CLK_USB_ROOT>;
>  			clock-names = "hsio", "suspend";
>  			interrupts = <GIC_SPI 149 
IRQ_TYPE_LEVEL_HIGH>;
> +			power-domains = <&hsio_blk_ctrl 
IMX8MP_HSIOBLK_PD_USB>;
>  			#address-cells = <1>;
>  			#size-cells = <1>;
>  			dma-ranges = <0x40000000 0x40000000 
0xc0000000>;
> @@ -947,9 +1001,6 @@ usb_dwc3_1: usb at 38200000 {
>  					 <&clk 
IMX8MP_CLK_USB_CORE_REF>,
>  					 <&clk 
IMX8MP_CLK_USB_ROOT>;
>  				clock-names = "bus_early", "ref", 
"suspend";
> -				assigned-clocks = <&clk 
IMX8MP_CLK_HSIO_AXI>;
> -				assigned-clock-parents = <&clk 
IMX8MP_SYS_PLL2_500M>;
> -				assigned-clock-rates = 
<500000000>;
>  				interrupts = <GIC_SPI 41 
IRQ_TYPE_LEVEL_HIGH>;
>  				phys = <&usb3_phy1>, <&usb3_phy1>;
>  				phy-names = "usb2-phy", "usb3-
phy";






From alexander.stein at ew.tq-group.com  Wed Jan 26 06:13:36 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:13:36 +0100
Subject: [PATCH v4 0/4] i.MX8MP: more USB3 glue layer feature support
Message-ID: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>

Hi all,

Thanks for the feedback on v3 [1].

This patchset aims to support flags for e.g. over-current active low or port
permanantly attached which are provided in the USB3 glue layer.

In v4 the patchset depends on Lucas' i.MX8MP power-domains patchset [2].
Because of that the 'phy' clock usage can be dropped, as now power domains
take care of the clocks. Due to powering up/down the glue layer settings
will have to be reapplied during resume.

Changes in v4:
* Depends on Lucas' i.MX8MP power-domains patchset
* removed 'phy' clock usage from dwc3-imx8mp.c
* Reapply glue layer settings upon resume

Changes in v3:
* Rename existing member for clarity
* Moved feature implementation from phy-fsl-imx8mq-usb.c to dwc3-imx8mp.c

[1] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20220118131626.926394-1-alexander.stein at ew.tq-group.com/
[2] https://patchwork.kernel.org/project/linux-arm-kernel/cover/20220119134027.2931945-1-l.stach at pengutronix.de/

Alexander Stein (4):
  usb: dwc3: imx8mp: rename iomem base pointer
  dt-bindings: usb: dwc3-imx8mp: Add imx8mp specific flags
  usb: dwc3: imx8mp: Add support for setting SOC specific flags
  arm64: dts: imx8mp: Add memory for USB3 glue layer to usb3 nodes

 .../bindings/usb/fsl,imx8mp-dwc3.yaml         | 31 +++++++-
 arch/arm64/boot/dts/freescale/imx8mp.dtsi     |  6 +-
 drivers/usb/dwc3/dwc3-imx8mp.c                | 76 +++++++++++++++++--
 3 files changed, 100 insertions(+), 13 deletions(-)

-- 
2.25.1



From alexander.stein at ew.tq-group.com  Wed Jan 26 06:13:37 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:13:37 +0100
Subject: [PATCH v4 1/4] usb: dwc3: imx8mp: rename iomem base pointer
In-Reply-To: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
References: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220126141340.234125-2-alexander.stein@ew.tq-group.com>

Until now the iomem used is not USB glue as the name suggests, but
HSIO BLK_CTL. Rename the struct member accordingly. This is a preparing
patch for when USB glue is actually used.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index d328d20abfbc..1c8fe657b3a9 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -39,7 +39,7 @@
 struct dwc3_imx8mp {
 	struct device			*dev;
 	struct platform_device		*dwc3;
-	void __iomem			*glue_base;
+	void __iomem			*hsio_blk_base;
 	struct clk			*hsio_clk;
 	struct clk			*suspend_clk;
 	int				irq;
@@ -55,7 +55,7 @@ static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 	if (!dwc3)
 		return;
 
-	val = readl(dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 
 	if ((dwc3->current_dr_role == DWC3_GCTL_PRTCAP_HOST) && dwc3->xhci)
 		val |= USB_WAKEUP_EN | USB_WAKEUP_SS_CONN |
@@ -64,16 +64,16 @@ static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 		val |= USB_WAKEUP_EN | USB_WAKEUP_VBUS_EN |
 		       USB_WAKEUP_VBUS_SRC_SESS_VAL;
 
-	writel(val, dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 }
 
 static void dwc3_imx8mp_wakeup_disable(struct dwc3_imx8mp *dwc3_imx)
 {
 	u32 val;
 
-	val = readl(dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	val = readl(dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 	val &= ~(USB_WAKEUP_EN | USB_WAKEUP_EN_MASK);
-	writel(val, dwc3_imx->glue_base + USB_WAKEUP_CTRL);
+	writel(val, dwc3_imx->hsio_blk_base + USB_WAKEUP_CTRL);
 }
 
 static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx)
@@ -115,9 +115,9 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 
 	dwc3_imx->dev = dev;
 
-	dwc3_imx->glue_base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(dwc3_imx->glue_base))
-		return PTR_ERR(dwc3_imx->glue_base);
+	dwc3_imx->hsio_blk_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(dwc3_imx->hsio_blk_base))
+		return PTR_ERR(dwc3_imx->hsio_blk_base);
 
 	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
 	if (IS_ERR(dwc3_imx->hsio_clk)) {
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Wed Jan 26 06:13:38 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:13:38 +0100
Subject: [PATCH v4 2/4] dt-bindings: usb: dwc3-imx8mp: Add imx8mp specific
 flags
In-Reply-To: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
References: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220126141340.234125-3-alexander.stein@ew.tq-group.com>

This adds bindings for features in the USB glue block. They allow
setting polarity of PWR and OC as well as disabling port power control.
Also permanently attached can be annotated as well.
Additional IO address and clock are needed.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 .../bindings/usb/fsl,imx8mp-dwc3.yaml         | 31 ++++++++++++++++---
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
index 974032b1fda0..01ab0f922ae8 100644
--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
@@ -15,9 +15,9 @@ properties:
     const: fsl,imx8mp-dwc3
 
   reg:
-    maxItems: 1
-    description: Address and length of the register set for the wrapper of
-      dwc3 core on the SOC.
+    items:
+      - description: Address and length of the register set for HSIO Block Control
+      - description: Address and length of the register set for the wrapper of dwc3 core on the SOC.
 
   "#address-cells":
     enum: [ 1, 2 ]
@@ -49,6 +49,28 @@ properties:
       - const: hsio
       - const: suspend
 
+  fsl,permanently-attached:
+    type: boolean
+    description:
+      Indicates if the device atached to a downstream port is
+      permanently attached.
+
+  fsl,disable-port-power-control:
+    type: boolean
+    description:
+      Indicates whether the host controller implementation includes port
+      power control. Defines Bit 3 in capability register (HCCPARAMS).
+
+  fsl,over-current-active-low:
+    type: boolean
+    description:
+      Over current signal polarity is active low.
+
+  fsl,power-active-low:
+    type: boolean
+    description:
+      Power pad (PWR) polarity is active low.
+
 # Required child node:
 
 patternProperties:
@@ -74,7 +96,8 @@ examples:
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     usb3_0: usb at 32f10100 {
       compatible = "fsl,imx8mp-dwc3";
-      reg = <0x32f10100 0x8>;
+      reg = <0x32f10100 0x8>,
+            <0x381f0000 0x20>;
       clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
                <&clk IMX8MP_CLK_USB_ROOT>;
       clock-names = "hsio", "suspend";
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Wed Jan 26 06:13:39 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:13:39 +0100
Subject: [PATCH v4 3/4] usb: dwc3: imx8mp: Add support for setting SOC
 specific flags
In-Reply-To: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
References: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220126141340.234125-4-alexander.stein@ew.tq-group.com>

The i.MX8MP glue layer has support for the following flags:
* over-current polarity
* PWR pad polarity
* controlling PPC flag in HCCPARAMS register
* permanent port attach for usb2 & usb3 port

Allow setting these flags by supporting specific flags in the glue node.
In order to get this to work an additional IORESOURCE_MEM and clock is
necessary. For backward compatibility this is purely optional.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 drivers/usb/dwc3/dwc3-imx8mp.c | 62 ++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c
index 1c8fe657b3a9..5a96b66bf237 100644
--- a/drivers/usb/dwc3/dwc3-imx8mp.c
+++ b/drivers/usb/dwc3/dwc3-imx8mp.c
@@ -36,10 +36,22 @@
 
 #define USB_WAKEUP_EN_MASK		GENMASK(5, 0)
 
+/* USB glue registers */
+#define USB_CTRL0		0x00
+#define USB_CTRL1		0x04
+
+#define USB_CTRL0_PORTPWR_EN	BIT(12) /* 1 - PPC enabled (default) */
+#define USB_CTRL0_USB3_FIXED	BIT(22) /* 1 - USB3 permanent attached */
+#define USB_CTRL0_USB2_FIXED	BIT(23) /* 1 - USB2 permanent attached */
+
+#define USB_CTRL1_OC_POLARITY	BIT(16) /* 0 - HIGH / 1 - LOW */
+#define USB_CTRL1_PWR_POLARITY	BIT(17) /* 0 - HIGH / 1 - LOW */
+
 struct dwc3_imx8mp {
 	struct device			*dev;
 	struct platform_device		*dwc3;
 	void __iomem			*hsio_blk_base;
+	void __iomem			*glue_base;
 	struct clk			*hsio_clk;
 	struct clk			*suspend_clk;
 	int				irq;
@@ -47,6 +59,42 @@ struct dwc3_imx8mp {
 	bool				wakeup_pending;
 };
 
+static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx)
+{
+	struct device *dev = dwc3_imx->dev;
+	u32 value;
+
+	if (!dwc3_imx->glue_base)
+		return;
+
+	value = readl(dwc3_imx->glue_base + USB_CTRL0);
+
+	if (device_property_read_bool(dev, "fsl,permanently-attached"))
+		value |= (USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
+	else
+		value &= ~(USB_CTRL0_USB2_FIXED | USB_CTRL0_USB3_FIXED);
+
+	if (device_property_read_bool(dev, "fsl,disable-port-power-control"))
+		value &= ~(USB_CTRL0_PORTPWR_EN);
+	else
+		value |= USB_CTRL0_PORTPWR_EN;
+
+	writel(value, dwc3_imx->glue_base + USB_CTRL0);
+
+	value = readl(dwc3_imx->glue_base + USB_CTRL1);
+	if (device_property_read_bool(dev, "fsl,over-current-active-low"))
+		value |= USB_CTRL1_OC_POLARITY;
+	else
+		value &= ~USB_CTRL1_OC_POLARITY;
+
+	if (device_property_read_bool(dev, "fsl,power-active-low"))
+		value |= USB_CTRL1_PWR_POLARITY;
+	else
+		value &= ~USB_CTRL1_PWR_POLARITY;
+
+	writel(value, dwc3_imx->glue_base + USB_CTRL1);
+}
+
 static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx)
 {
 	struct dwc3	*dwc3 = platform_get_drvdata(dwc3_imx->dwc3);
@@ -100,6 +148,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	struct device		*dev = &pdev->dev;
 	struct device_node	*dwc3_np, *node = dev->of_node;
 	struct dwc3_imx8mp	*dwc3_imx;
+	struct resource		*res;
 	int			err, irq;
 
 	if (!node) {
@@ -119,6 +168,15 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	if (IS_ERR(dwc3_imx->hsio_blk_base))
 		return PTR_ERR(dwc3_imx->hsio_blk_base);
 
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!res) {
+		dev_warn(dev, "Base address for glue layer missing. Continuing without, some features are missing though.");
+	} else {
+		dwc3_imx->glue_base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(dwc3_imx->glue_base))
+			return PTR_ERR(dwc3_imx->glue_base);
+	}
+
 	dwc3_imx->hsio_clk = devm_clk_get(dev, "hsio");
 	if (IS_ERR(dwc3_imx->hsio_clk)) {
 		err = PTR_ERR(dwc3_imx->hsio_clk);
@@ -152,6 +210,8 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev)
 	}
 	dwc3_imx->irq = irq;
 
+	imx8mp_configure_glue(dwc3_imx);
+
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 	err = pm_runtime_get_sync(dev);
@@ -252,6 +312,8 @@ static int __maybe_unused dwc3_imx8mp_resume(struct dwc3_imx8mp *dwc3_imx,
 	dwc3_imx8mp_wakeup_disable(dwc3_imx);
 	dwc3_imx->pm_suspended = false;
 
+	imx8mp_configure_glue(dwc3_imx);
+
 	if (dwc3_imx->wakeup_pending) {
 		dwc3_imx->wakeup_pending = false;
 		if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_DEVICE) {
-- 
2.25.1



From alexander.stein at ew.tq-group.com  Wed Jan 26 06:13:40 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Wed, 26 Jan 2022 15:13:40 +0100
Subject: [PATCH v4 4/4] arm64: dts: imx8mp: Add memory for USB3 glue layer to
 usb3 nodes
In-Reply-To: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
References: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220126141340.234125-5-alexander.stein@ew.tq-group.com>

The USB3 glue layer has 2 areas in the register set, see RM Rev.1
section 11.2.5.2.1 GLUE_usb3 memory map:
* USB3 control/status
* PHY control/status

Provide the memory area to the usb3 nodes for accessing the features
in the USB3 control area.

Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index e61ac5f136ad..d4aadb434d36 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1030,7 +1030,8 @@ usb3_phy0: usb-phy at 381f0040 {
 
 		usb3_0: usb at 32f10100 {
 			compatible = "fsl,imx8mp-dwc3";
-			reg = <0x32f10100 0x8>;
+			reg = <0x32f10100 0x8>,
+			      <0x381f0000 0x20>;
 			clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
 				 <&clk IMX8MP_CLK_USB_ROOT>;
 			clock-names = "hsio", "suspend";
@@ -1070,7 +1071,8 @@ usb3_phy1: usb-phy at 382f0040 {
 
 		usb3_1: usb at 32f10108 {
 			compatible = "fsl,imx8mp-dwc3";
-			reg = <0x32f10108 0x8>;
+			reg = <0x32f10108 0x8>,
+			      <0x382f0000 0x20>;
 			clocks = <&clk IMX8MP_CLK_HSIO_ROOT>,
 				 <&clk IMX8MP_CLK_USB_ROOT>;
 			clock-names = "hsio", "suspend";
-- 
2.25.1



From drjones at redhat.com  Wed Jan 26 06:17:41 2022
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 26 Jan 2022 15:17:41 +0100
Subject: [PATCH v2] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220126135319.1918802-1-broonie@kernel.org>
References: <20220126135319.1918802-1-broonie@kernel.org>
Message-ID: <20220126141741.zxxltis5zdtjzz33@gator>

On Wed, Jan 26, 2022 at 01:53:19PM +0000, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> 
> v2:
>  - The test for being able to create the GIC doesn't actually
>    instantiate it, add a call doing so in that case.
> 
>  tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
>  tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 5 ++++-
>  3 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 9ad38bd360a4..791d38404652 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
>  {
>  	struct kvm_vm *vm;
>  	unsigned int i;
> +	int ret;
>  	int nr_vcpus = test_args.nr_vcpus;
>  
>  	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
> @@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
>  
>  	ucall_init(vm, NULL);
>  	test_init_timer_irq(vm);
> -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (ret < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");

Please use 'print_skip', which appends ", skipping test" to keep the skip
messages consistent. Also, print_skip can't be disabled with -DQUIET like
pr_info.

> +		exit(KSFT_SKIP);
> +	}
>  
>  	/* Make all the test's cmdline args visible to the guest */
>  	sync_global_to_guest(vm, test_args);
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> index e6c7d7f8fbd1..b127a261fd29 100644
> --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> @@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
>  
>  	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
>  			GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (gic_fd < 0) {
> +		pr_info("Failed to create vgic-v3, skipping\n");

print_skip

> +		exit(KSFT_SKIP);
> +	}
>  
>  	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
>  		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..4ea65e119bdd 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -51,7 +51,10 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>  			"Number of vCPUs requested (%u) doesn't match with the ones created for the VM (%u)\n",
>  			nr_vcpus, nr_vcpus_created);
>  
> -	/* Distributor setup */
> +	/* Distributor setup - test if it's possible then actually do it */
> +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
> +	if (gic_fd != 0)
> +		return -1;
>  	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);

kvm selftests generally asserts on failure with the nonunderscore
prefixed KVM ioctl wrapper functions, which is why you appear to
be forced to do this nasty dance. However, kvm selftests usually
always also offers an underscore prefixed version of the KVM ioctl
wrapper function too for cases like these. So we can just do

  if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false, &gic_fd) != 0)
          return -1;


Thanks,
drew

>  
>  	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
> -- 
> 2.30.2
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
> 



From peter.hilber at opensynergy.com  Wed Jan 26 06:28:52 2022
From: peter.hilber at opensynergy.com (Peter Hilber)
Date: Wed, 26 Jan 2022 15:28:52 +0100
Subject: [PATCH 1/6] firmware: arm_scmi: Add atomic mode support to virtio
 transport
In-Reply-To: <20220124100341.41191-2-cristian.marussi@arm.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
 <20220124100341.41191-2-cristian.marussi@arm.com>
Message-ID: <425e9a2b-a03f-a038-2598-33f28cd5f4e9@opensynergy.com>

On 24.01.22 11:03, Cristian Marussi wrote:
> Add support for .mark_txdone and .poll_done transport operations to SCMI
> VirtIO transport as pre-requisites to enable atomic operations.
> 
> Add a Kernel configuration option to enable SCMI VirtIO transport polling
> and atomic mode for selected SCMI transactions while leaving it default
> disabled.
> 

Hi Cristian,

please see one remark below.

Best regards,

Peter

> Cc: "Michael S. Tsirkin" <mst at redhat.com>
> Cc: Igor Skalkin <igor.skalkin at opensynergy.com>
> Cc: Peter Hilber <peter.hilber at opensynergy.com>
> Cc: virtualization at lists.linux-foundation.org
> Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> ---
> - check for deferred_wq existence before queueing work to avoid
>   race at driver removal time
> - changed mark_txdone decision-logic about message release
> - fixed race while checking for msg polled from another thread
> - using dedicated poll_status instead of poll_idx upper bits
> - pick initial poll_idx earlier insde send_message to avoid missing
>   early replies
> - removed F_NOTIFY mention in comment
> - clearing xfer->priv on the IRQ tx path once message has been fetched
> - added some store barriers
> - updated some comments
> ---
>  drivers/firmware/arm_scmi/Kconfig  |  15 ++
>  drivers/firmware/arm_scmi/driver.c |   9 +-
>  drivers/firmware/arm_scmi/virtio.c | 315 ++++++++++++++++++++++++++---
>  3 files changed, 310 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig
> index d429326433d1..7794bd41eaa0 100644
> --- a/drivers/firmware/arm_scmi/Kconfig
> +++ b/drivers/firmware/arm_scmi/Kconfig
> @@ -118,6 +118,21 @@ config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE
>  	  the ones implemented by kvmtool) and let the core Kernel VirtIO layer
>  	  take care of the needed conversions, say N.
>  
> +config ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE
> +	bool "Enable atomic mode for SCMI VirtIO transport"
> +	depends on ARM_SCMI_TRANSPORT_VIRTIO
> +	help
> +	  Enable support of atomic operation for SCMI VirtIO based transport.
> +
> +	  If you want the SCMI VirtIO based transport to operate in atomic
> +	  mode, avoiding any kind of sleeping behaviour for selected
> +	  transactions on the TX path, answer Y.
> +
> +	  Enabling atomic mode operations allows any SCMI driver using this
> +	  transport to optionally ask for atomic SCMI transactions and operate
> +	  in atomic context too, at the price of using a number of busy-waiting
> +	  primitives all over instead. If unsure say N.
> +
>  endif #ARM_SCMI_PROTOCOL
>  
>  config ARM_SCMI_POWER_DOMAIN
> diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
> index c2e7897ff56e..dc972a54e93e 100644
> --- a/drivers/firmware/arm_scmi/driver.c
> +++ b/drivers/firmware/arm_scmi/driver.c
> @@ -648,7 +648,8 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo,
>  
>  	unpack_scmi_header(msg_hdr, &xfer->hdr);
>  	if (priv)
> -		xfer->priv = priv;
> +		/* Ensure order between xfer->priv store and following ops */
> +		smp_store_mb(xfer->priv, priv);
>  	info->desc->ops->fetch_notification(cinfo, info->desc->max_msg_size,
>  					    xfer);
>  	scmi_notify(cinfo->handle, xfer->hdr.protocol_id,
> @@ -680,8 +681,12 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo,
>  		xfer->rx.len = info->desc->max_msg_size;
>  
>  	if (priv)
> -		xfer->priv = priv;
> +		/* Ensure order between xfer->priv store and following ops */
> +		smp_store_mb(xfer->priv, priv);
>  	info->desc->ops->fetch_response(cinfo, xfer);
> +	if (priv)
> +		/* Ensure order between xfer->priv clear and later accesses */
> +		smp_store_mb(xfer->priv, NULL);
>  
>  	trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
>  			   xfer->hdr.protocol_id, xfer->hdr.seq,
> diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c
> index fd0f6f91fc0b..39c293f0ffd3 100644
> --- a/drivers/firmware/arm_scmi/virtio.c
> +++ b/drivers/firmware/arm_scmi/virtio.c
> @@ -3,8 +3,8 @@
>   * Virtio Transport driver for Arm System Control and Management Interface
>   * (SCMI).
>   *
> - * Copyright (C) 2020-2021 OpenSynergy.
> - * Copyright (C) 2021 ARM Ltd.
> + * Copyright (C) 2020-2022 OpenSynergy.
> + * Copyright (C) 2021-2022 ARM Ltd.
>   */
>  
>  /**
> @@ -38,6 +38,9 @@
>   * @vqueue: Associated virtqueue
>   * @cinfo: SCMI Tx or Rx channel
>   * @free_list: List of unused scmi_vio_msg, maintained for Tx channels only
> + * @deferred_tx_work: Worker for TX deferred replies processing
> + * @deferred_tx_wq: Workqueue for TX deferred replies
> + * @pending_cmds_list: List of pre-fetched commands queueud for later processing
>   * @is_rx: Whether channel is an Rx channel
>   * @ready: Whether transport user is ready to hear about channel
>   * @max_msg: Maximum number of pending messages for this channel.
> @@ -49,6 +52,9 @@ struct scmi_vio_channel {
>  	struct virtqueue *vqueue;
>  	struct scmi_chan_info *cinfo;
>  	struct list_head free_list;
> +	struct list_head pending_cmds_list;
> +	struct work_struct deferred_tx_work;
> +	struct workqueue_struct *deferred_tx_wq;
>  	bool is_rx;
>  	bool ready;
>  	unsigned int max_msg;
> @@ -58,6 +64,12 @@ struct scmi_vio_channel {
>  	spinlock_t ready_lock;
>  };
>  
> +enum poll_states {
> +	VIO_MSG_NOT_POLLED,
> +	VIO_MSG_POLLING,
> +	VIO_MSG_POLL_DONE,
> +};
> +
>  /**
>   * struct scmi_vio_msg - Transport PDU information
>   *
> @@ -65,12 +77,22 @@ struct scmi_vio_channel {
>   * @input: SDU used for (delayed) responses and notifications
>   * @list: List which scmi_vio_msg may be part of
>   * @rx_len: Input SDU size in bytes, once input has been received
> + * @poll_idx: Last used index registered for polling purposes if this message
> + *	      transaction reply was configured for polling.
> + *	      Note that since virtqueue used index is an unsigned 16-bit we can
> + *	      use some out-of-scale values to signify particular conditions.
> + * @poll_status: Polling state for this message.
> + * @poll_lock: Protect access to @poll_idx and @poll_status.
>   */
>  struct scmi_vio_msg {
>  	struct scmi_msg_payld *request;
>  	struct scmi_msg_payld *input;
>  	struct list_head list;
>  	unsigned int rx_len;
> +	unsigned int poll_idx;
> +	enum poll_states poll_status;
> +	/* lock to protect access to poll_idx. */
> +	spinlock_t poll_lock;
>  };
>  
>  /* Only one SCMI VirtIO device can possibly exist */
> @@ -81,40 +103,43 @@ static bool scmi_vio_have_vq_rx(struct virtio_device *vdev)
>  	return virtio_has_feature(vdev, VIRTIO_SCMI_F_P2A_CHANNELS);
>  }
>  
> +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
>  static int scmi_vio_feed_vq_rx(struct scmi_vio_channel *vioch,
>  			       struct scmi_vio_msg *msg,
>  			       struct device *dev)
>  {
>  	struct scatterlist sg_in;
>  	int rc;
> -	unsigned long flags;
>  
>  	sg_init_one(&sg_in, msg->input, VIRTIO_SCMI_MAX_PDU_SIZE);
>  
> -	spin_lock_irqsave(&vioch->lock, flags);
> -
>  	rc = virtqueue_add_inbuf(vioch->vqueue, &sg_in, 1, msg, GFP_ATOMIC);
>  	if (rc)
>  		dev_err(dev, "failed to add to RX virtqueue (%d)\n", rc);
>  	else
>  		virtqueue_kick(vioch->vqueue);
>  
> -	spin_unlock_irqrestore(&vioch->lock, flags);
> -
>  	return rc;
>  }
>  
> +/* Expect to be called with vioch->lock acquired by the caller and IRQs off */
> +static inline void scmi_vio_feed_vq_tx(struct scmi_vio_channel *vioch,
> +				       struct scmi_vio_msg *msg)
> +{
> +	spin_lock(&msg->poll_lock);
> +	msg->poll_status = VIO_MSG_NOT_POLLED;
> +	spin_unlock(&msg->poll_lock);
> +
> +	list_add(&msg->list, &vioch->free_list);
> +}
> +
>  static void scmi_finalize_message(struct scmi_vio_channel *vioch,
>  				  struct scmi_vio_msg *msg)
>  {
> -	if (vioch->is_rx) {
> +	if (vioch->is_rx)
>  		scmi_vio_feed_vq_rx(vioch, msg, vioch->cinfo->dev);
> -	} else {
> -		/* Here IRQs are assumed to be already disabled by the caller */
> -		spin_lock(&vioch->lock);
> -		list_add(&msg->list, &vioch->free_list);
> -		spin_unlock(&vioch->lock);
> -	}
> +	else
> +		scmi_vio_feed_vq_tx(vioch, msg);
>  }
>  
>  static void scmi_vio_complete_cb(struct virtqueue *vqueue)
> @@ -144,6 +169,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  			virtqueue_disable_cb(vqueue);
>  			cb_enabled = false;
>  		}
> +
>  		msg = virtqueue_get_buf(vqueue, &length);
>  		if (!msg) {
>  			if (virtqueue_enable_cb(vqueue))
> @@ -157,7 +183,9 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  			scmi_rx_callback(vioch->cinfo,
>  					 msg_read_header(msg->input), msg);
>  
> +			spin_lock(&vioch->lock);
>  			scmi_finalize_message(vioch, msg);
> +			spin_unlock(&vioch->lock);
>  		}
>  
>  		/*
> @@ -176,6 +204,34 @@ static void scmi_vio_complete_cb(struct virtqueue *vqueue)
>  	spin_unlock_irqrestore(&vioch->ready_lock, ready_flags);
>  }
>  
> +static void scmi_vio_deferred_tx_worker(struct work_struct *work)
> +{
> +	unsigned long flags;
> +	struct scmi_vio_channel *vioch;
> +	struct scmi_vio_msg *msg, *tmp;
> +
> +	vioch = container_of(work, struct scmi_vio_channel, deferred_tx_work);
> +
> +	/* Process pre-fetched messages */
> +	spin_lock_irqsave(&vioch->lock, flags);
> +
> +	/* Scan the list of possibly pre-fetched messages during polling. */
> +	list_for_each_entry_safe(msg, tmp, &vioch->pending_cmds_list, list) {
> +		list_del(&msg->list);
> +
> +		scmi_rx_callback(vioch->cinfo,
> +				 msg_read_header(msg->input), msg);
> +
> +		/* Free the processed message once done */
> +		scmi_vio_feed_vq_tx(vioch, msg);
> +	}
> +
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	/* Process possibly still pending messages */
> +	scmi_vio_complete_cb(vioch->vqueue);
> +}
> +
>  static const char *const scmi_vio_vqueue_names[] = { "tx", "rx" };
>  
>  static vq_callback_t *scmi_vio_complete_callbacks[] = {
> @@ -244,6 +300,19 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  
>  	vioch = &((struct scmi_vio_channel *)scmi_vdev->priv)[index];
>  
> +	/* Setup a deferred worker for polling. */
> +	if (tx && !vioch->deferred_tx_wq) {
> +		vioch->deferred_tx_wq =
> +			alloc_workqueue(dev_name(&scmi_vdev->dev),
> +					WQ_UNBOUND | WQ_FREEZABLE | WQ_SYSFS,
> +					0);
> +		if (!vioch->deferred_tx_wq)
> +			return -ENOMEM;
> +
> +		INIT_WORK(&vioch->deferred_tx_work,
> +			  scmi_vio_deferred_tx_worker);
> +	}
> +
>  	for (i = 0; i < vioch->max_msg; i++) {
>  		struct scmi_vio_msg *msg;
>  
> @@ -257,6 +326,7 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  						    GFP_KERNEL);
>  			if (!msg->request)
>  				return -ENOMEM;
> +			spin_lock_init(&msg->poll_lock);
>  		}
>  
>  		msg->input = devm_kzalloc(cinfo->dev, VIRTIO_SCMI_MAX_PDU_SIZE,
> @@ -264,13 +334,12 @@ static int virtio_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
>  		if (!msg->input)
>  			return -ENOMEM;
>  
> -		if (tx) {
> -			spin_lock_irqsave(&vioch->lock, flags);
> -			list_add_tail(&msg->list, &vioch->free_list);
> -			spin_unlock_irqrestore(&vioch->lock, flags);
> -		} else {
> +		spin_lock_irqsave(&vioch->lock, flags);
> +		if (tx)
> +			scmi_vio_feed_vq_tx(vioch, msg);
> +		else
>  			scmi_vio_feed_vq_rx(vioch, msg, cinfo->dev);
> -		}
> +		spin_unlock_irqrestore(&vioch->lock, flags);
>  	}
>  
>  	spin_lock_irqsave(&vioch->lock, flags);
> @@ -291,11 +360,22 @@ static int virtio_chan_free(int id, void *p, void *data)
>  	unsigned long flags;
>  	struct scmi_chan_info *cinfo = p;
>  	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +	void *deferred_wq = NULL;
>  
>  	spin_lock_irqsave(&vioch->ready_lock, flags);
>  	vioch->ready = false;
>  	spin_unlock_irqrestore(&vioch->ready_lock, flags);
>  
> +	spin_lock_irqsave(&vioch->lock, flags);
> +	if (!vioch->is_rx && vioch->deferred_tx_wq) {
> +		deferred_wq = vioch->deferred_tx_wq;
> +		vioch->deferred_tx_wq = NULL;
> +	}
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	if (deferred_wq)
> +		destroy_workqueue(deferred_wq);
> +
>  	scmi_free_channel(cinfo, data, id);
>  
>  	spin_lock_irqsave(&vioch->lock, flags);
> @@ -324,16 +404,33 @@ static int virtio_send_message(struct scmi_chan_info *cinfo,
>  	}
>  
>  	msg = list_first_entry(&vioch->free_list, typeof(*msg), list);
> -	list_del(&msg->list);
> +	/* Re-init element so we can discern anytime if it is still in-flight */
> +	list_del_init(&msg->list);
>  
>  	msg_tx_prepare(msg->request, xfer);
>  
>  	sg_init_one(&sg_out, msg->request, msg_command_size(xfer));
>  	sg_init_one(&sg_in, msg->input, msg_response_size(xfer));
>  
> +	/*
> +	 * If polling was requested for this transaction:
> +	 *  - retrieve last used index (will be used as polling reference)
> +	 *  - bind the polled message to the xfer via .priv
> +	 */
> +	if (xfer->hdr.poll_completion) {
> +		spin_lock(&msg->poll_lock);
> +		msg->poll_status = VIO_MSG_POLLING;
> +		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
> +		spin_unlock(&msg->poll_lock);
> +		/* Ensure initialized msg is visibly bound to xfer */
> +		smp_store_mb(xfer->priv, msg);
> +	}
> +
>  	rc = virtqueue_add_sgs(vioch->vqueue, sgs, 1, 1, msg, GFP_ATOMIC);
>  	if (rc) {
> -		list_add(&msg->list, &vioch->free_list);
> +		/* Ensure order between xfer->priv clear and vq feeding */
> +		smp_store_mb(xfer->priv, NULL);
> +		scmi_vio_feed_vq_tx(vioch, msg);
>  		dev_err(vioch->cinfo->dev,
>  			"failed to add to TX virtqueue (%d)\n", rc);
>  	} else {
> @@ -350,10 +447,8 @@ static void virtio_fetch_response(struct scmi_chan_info *cinfo,
>  {
>  	struct scmi_vio_msg *msg = xfer->priv;
>  
> -	if (msg) {
> +	if (msg)
>  		msg_fetch_response(msg->input, msg->rx_len, xfer);
> -		xfer->priv = NULL;
> -	}
>  }
>  
>  static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
> @@ -361,12 +456,174 @@ static void virtio_fetch_notification(struct scmi_chan_info *cinfo,
>  {
>  	struct scmi_vio_msg *msg = xfer->priv;
>  
> -	if (msg) {
> +	if (msg)
>  		msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer);
> -		xfer->priv = NULL;
> +}
> +
> +/**
> + * virtio_mark_txdone  - Mark transmission done
> + *
> + * Free only completed polling transfer messages.
> + *
> + * Note that in the SCMI VirtIO transport we never explicitly release timed-out
> + * messages by forcibly re-adding them to the free-list inside the TX code path;
> + * we instead let IRQ/RX callbacks eventually clean up such messages once,
> + * finally, a late reply is received and discarded (if ever).
> + *
> + * This approach was deemed preferable since those pending timed-out buffers are
> + * still effectively owned by the SCMI platform VirtIO device even after timeout
> + * expiration: forcibly freeing and reusing them before they had been returned
> + * explicitly by the SCMI platform could lead to subtle bugs due to message
> + * corruption.
> + * An SCMI platform VirtIO device which never returns message buffers is
> + * anyway broken and it will quickly lead to exhaustion of available messages.
> + *
> + * For this same reason, here, we take care to free only the polled messages
> + * that had been somehow replied, since they won't be freed elsewhere;
> + * late replies to timed-out polled messages would be anyway freed by RX
> + * callbacks instead.
> + *
> + * @cinfo: SCMI channel info
> + * @ret: Transmission return code
> + * @xfer: Transfer descriptor
> + */
> +static void virtio_mark_txdone(struct scmi_chan_info *cinfo, int ret,
> +			       struct scmi_xfer *xfer)
> +{
> +	unsigned long flags;
> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +	struct scmi_vio_msg *msg = xfer->priv;
> +
> +	/* Must be a polled xfer and not already freed on the IRQ path */
> +	if (!xfer->hdr.poll_completion || !msg)
> +		return;
> +
> +	/* Ensure msg is unbound from xfer anyway at this point */
> +	smp_store_mb(xfer->priv, NULL);
> +
> +	/* Do not free timedout polled messages */
> +	if (ret != -ETIMEDOUT) {
> +		spin_lock_irqsave(&vioch->lock, flags);
> +		scmi_vio_feed_vq_tx(vioch, msg);
> +		spin_unlock_irqrestore(&vioch->lock, flags);
>  	}
>  }
>  
> +/**
> + * virtio_poll_done  - Provide polling support for VirtIO transport
> + *
> + * @cinfo: SCMI channel info
> + * @xfer: Reference to the transfer being poll for.
> + *
> + * VirtIO core provides a polling mechanism based only on last used indexes:
> + * this means that it is possible to poll the virtqueues waiting for something
> + * new to arrive from the host side but the only way to check if the freshly
> + * arrived buffer was what we were waiting for is to compare the newly arrived
> + * message descriptors with the one we are polling on.
> + *
> + * As a consequence it can happen to dequeue something different from the buffer
> + * we were poll-waiting for: if that is the case such early fetched buffers are
> + * then added to a the @pending_cmds_list list for later processing by a
> + * dedicated deferred worker.
> + *
> + * So, basically, once something new is spotted we proceed to de-queue all the
> + * freshly received used buffers until we found the one we were polling on, or,
> + * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
> + * in the vqueue at the end of the polling loop (possible due to inherent races
> + * in virtqueues handling mechanisms), we similarly kick the deferred worker
> + * and let it process those, to avoid indefinitely looping in the .poll_done
> + * helper.
> + *
> + * Note that, since we do NOT have per-message suppress notification mechanism,
> + * the message we are polling for could be delivered via usual IRQs callbacks
> + * on another core which happened to have IRQs enabled: in such case it will be
> + * handled as such by scmi_rx_callback() and the polling loop in the
> + * SCMI Core TX path will be transparently terminated anyway.
> + *
> + * Return: True once polling has successfully completed.
> + */
> +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> +			     struct scmi_xfer *xfer)
> +{
> +	bool pending, ret = false;
> +	unsigned int length, any_prefetched = 0;
> +	unsigned long flags;
> +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> +
> +	if (!msg)
> +		return true;
> +
> +	spin_lock_irqsave(&vioch->lock, flags);

If now acquiring vioch->lock here, I see no need to virtqueue_poll() any more.
After checking msg->poll_status, we could just directly try virtqueue_get_buf().

On the other hand, always taking the vioch->lock in a busy loop might better be
avoided (I assumed before that taking it was omitted on purpose), since it
might hamper tx channel progress in other cores (but I'm not sure about the
actual impact).

Also, I don't yet understand why the vioch->lock would need to be taken here.

> +	spin_lock(&msg->poll_lock);
> +	/* Processed already by other polling loop on another CPU ? */
> +	if (msg->poll_status == VIO_MSG_POLL_DONE) {
> +		spin_unlock(&msg->poll_lock);
> +		spin_unlock_irqrestore(&vioch->lock, flags);
> +		return true;
> +	}
> +
> +	/* Has cmdq index moved at all ? */
> +	pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> +	spin_unlock(&msg->poll_lock);
> +	if (!pending) {
> +		spin_unlock_irqrestore(&vioch->lock, flags);
> +		return false;
> +	}
> +
> +	virtqueue_disable_cb(vioch->vqueue);
> +
> +	/*
> +	 * If something arrived we cannot be sure, without dequeueing, if it
> +	 * was the reply to the xfer we are polling for, or, to other, even
> +	 * possibly non-polling, pending xfers: process all new messages
> +	 * till the polled-for message is found OR the vqueue is empty.
> +	 */
> +	while ((next_msg = virtqueue_get_buf(vioch->vqueue, &length))) {
> +		next_msg->rx_len = length;
> +		/* Is the message we were polling for ? */
> +		if (next_msg == msg) {
> +			ret = true;
> +			break;
> +		}
> +
> +		spin_lock(&next_msg->poll_lock);
> +		if (next_msg->poll_status == VIO_MSG_NOT_POLLED) {
> +			any_prefetched++;
> +			list_add_tail(&next_msg->list,
> +				      &vioch->pending_cmds_list);
> +		} else {
> +			/* We picked another currently polled msg */
> +			next_msg->poll_status = VIO_MSG_POLL_DONE;
> +		}
> +		spin_unlock(&next_msg->poll_lock);
> +	}
> +
> +	/*
> +	 * When the polling loop has successfully terminated if something
> +	 * else was queued in the meantime, it will be served by a deferred
> +	 * worker OR by the normal IRQ/callback OR by other poll loops.
> +	 *
> +	 * If we are still looking for the polled reply, the polling index has
> +	 * to be updated to the current vqueue last used index.
> +	 */
> +	if (ret) {
> +		pending = !virtqueue_enable_cb(vioch->vqueue);
> +	} else {
> +		spin_lock(&msg->poll_lock);
> +		msg->poll_idx = virtqueue_enable_cb_prepare(vioch->vqueue);
> +		pending = virtqueue_poll(vioch->vqueue, msg->poll_idx);
> +		spin_unlock(&msg->poll_lock);
> +	}
> +
> +	if (vioch->deferred_tx_wq && (any_prefetched || pending))
> +		queue_work(vioch->deferred_tx_wq, &vioch->deferred_tx_work);
> +
> +	spin_unlock_irqrestore(&vioch->lock, flags);
> +
> +	return ret;
> +}
> +
>  static const struct scmi_transport_ops scmi_virtio_ops = {
>  	.link_supplier = virtio_link_supplier,
>  	.chan_available = virtio_chan_available,
> @@ -376,6 +633,8 @@ static const struct scmi_transport_ops scmi_virtio_ops = {
>  	.send_message = virtio_send_message,
>  	.fetch_response = virtio_fetch_response,
>  	.fetch_notification = virtio_fetch_notification,
> +	.mark_txdone = virtio_mark_txdone,
> +	.poll_done = virtio_poll_done,
>  };
>  
>  static int scmi_vio_probe(struct virtio_device *vdev)
> @@ -418,6 +677,7 @@ static int scmi_vio_probe(struct virtio_device *vdev)
>  		spin_lock_init(&channels[i].lock);
>  		spin_lock_init(&channels[i].ready_lock);
>  		INIT_LIST_HEAD(&channels[i].free_list);
> +		INIT_LIST_HEAD(&channels[i].pending_cmds_list);
>  		channels[i].vqueue = vqs[i];
>  
>  		sz = virtqueue_get_vring_size(channels[i].vqueue);
> @@ -506,4 +766,5 @@ const struct scmi_desc scmi_virtio_desc = {
>  	.max_rx_timeout_ms = 60000, /* for non-realtime virtio devices */
>  	.max_msg = 0, /* overridden by virtio_get_max_msg() */
>  	.max_msg_size = VIRTIO_SCMI_MAX_MSG_SIZE,
> +	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE),
>  };




From broonie at kernel.org  Wed Jan 26 06:29:14 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 14:29:14 +0000
Subject: [PATCH v2] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220126141741.zxxltis5zdtjzz33@gator>
References: <20220126135319.1918802-1-broonie@kernel.org>
 <20220126141741.zxxltis5zdtjzz33@gator>
Message-ID: <YfFauhK4FuM1/I8S@sirena.org.uk>

On Wed, Jan 26, 2022 at 03:17:41PM +0100, Andrew Jones wrote:
> On Wed, Jan 26, 2022 at 01:53:19PM +0000, Mark Brown wrote:

> > -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> > +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> > +	if (ret < 0) {
> > +		pr_info("Failed to create vgic-v3, skipping\n");

> Please use 'print_skip', which appends ", skipping test" to keep the skip
> messages consistent. Also, print_skip can't be disabled with -DQUIET like
> pr_info.

I see.  It might be nice to convert these tests to use the ksft_
stuff...

> > -	/* Distributor setup */
> > +	/* Distributor setup - test if it's possible then actually do it */
> > +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
> > +	if (gic_fd != 0)
> > +		return -1;
> >  	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);

> kvm selftests generally asserts on failure with the nonunderscore
> prefixed KVM ioctl wrapper functions, which is why you appear to
> be forced to do this nasty dance. However, kvm selftests usually
> always also offers an underscore prefixed version of the KVM ioctl
> wrapper function too for cases like these. So we can just do

>   if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false, &gic_fd) != 0)
>           return -1;

And the _ version is OK to use in the vgic code?  The _ makes it look
like it's internal only.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/2048aa63/attachment.sig>

From drjones at redhat.com  Wed Jan 26 06:50:33 2022
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 26 Jan 2022 15:50:33 +0100
Subject: [PATCH v2] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <YfFauhK4FuM1/I8S@sirena.org.uk>
References: <20220126135319.1918802-1-broonie@kernel.org>
 <20220126141741.zxxltis5zdtjzz33@gator>
 <YfFauhK4FuM1/I8S@sirena.org.uk>
Message-ID: <20220126145033.nwsf2g7dim7yeoz2@gator>

On Wed, Jan 26, 2022 at 02:29:14PM +0000, Mark Brown wrote:
> On Wed, Jan 26, 2022 at 03:17:41PM +0100, Andrew Jones wrote:
> > On Wed, Jan 26, 2022 at 01:53:19PM +0000, Mark Brown wrote:
> 
> > > -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> > > +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> > > +	if (ret < 0) {
> > > +		pr_info("Failed to create vgic-v3, skipping\n");
> 
> > Please use 'print_skip', which appends ", skipping test" to keep the skip
> > messages consistent. Also, print_skip can't be disabled with -DQUIET like
> > pr_info.
> 
> I see.  It might be nice to convert these tests to use the ksft_
> stuff...

Indeed. I'll add that to my TODO.

> 
> > > -	/* Distributor setup */
> > > +	/* Distributor setup - test if it's possible then actually do it */
> > > +	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, true);
> > > +	if (gic_fd != 0)
> > > +		return -1;
> > >  	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> 
> > kvm selftests generally asserts on failure with the nonunderscore
> > prefixed KVM ioctl wrapper functions, which is why you appear to
> > be forced to do this nasty dance. However, kvm selftests usually
> > always also offers an underscore prefixed version of the KVM ioctl
> > wrapper function too for cases like these. So we can just do
> 
> >   if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false, &gic_fd) != 0)
> >           return -1;
> 
> And the _ version is OK to use in the vgic code?  The _ makes it look
> like it's internal only.

It's extra OK. Anything in lib/* or lib/*/* is internal to the lib.
However, it's even OK for a unit test to use the _ prefixed functions.
The _ isn't so much about being internal as it is about being a raw
version of the ioctl wrapper, which returns error codes, vs. the
asserting version of the wrapper which only returns results on success.

Thanks,
drew



From broonie at kernel.org  Wed Jan 26 06:52:42 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 14:52:42 +0000
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
Message-ID: <20220126145242.3473836-1-broonie@kernel.org>

The arch_timer and vgic_irq kselftests assume that they can create a
vgic-v3, using the library function vgic_v3_setup() which aborts with a
test failure if it is not possible to do so. Since vgic-v3 can only be
instantiated on systems where the host has GICv3 this leads to false
positives on older systems where that is not the case.

Fix this by changing vgic_v3_setup() to return an error if the vgic can't
be instantiated and have the callers skip if this happens. We could also
exit flagging a skip in vgic_v3_setup() but this would prevent future test
cases conditionally deciding which GIC to use or generally doing more
complex output.

Signed-off-by: Mark Brown <broonie at kernel.org>
---

v3:
 - Use custom print_skip() helper.
 - Use internal version of _kvm_create_device.
v2:
 - The test for being able to create the GIC doesn't actually
   instantiate it, add a call doing so in that case.

 tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
 tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
 tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
index 9ad38bd360a4..b08d30bf71c5 100644
--- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
+++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
@@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
 {
 	struct kvm_vm *vm;
 	unsigned int i;
+	int ret;
 	int nr_vcpus = test_args.nr_vcpus;
 
 	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
@@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
 
 	ucall_init(vm, NULL);
 	test_init_timer_irq(vm);
-	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
+	if (ret < 0) {
+		print_skip("Failed to create vgic-v3");
+		exit(KSFT_SKIP);
+	}
 
 	/* Make all the test's cmdline args visible to the guest */
 	sync_global_to_guest(vm, test_args);
diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
index e6c7d7f8fbd1..7eca97799917 100644
--- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
+++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
@@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
 
 	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
 			GICD_BASE_GPA, GICR_BASE_GPA);
+	if (gic_fd < 0) {
+		print_skip("Failed to create vgic-v3, skipping");
+		exit(KSFT_SKIP);
+	}
 
 	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
 		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
index b3a0fca0d780..f5cd0c536d85 100644
--- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
+++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
@@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
 			nr_vcpus, nr_vcpus_created);
 
 	/* Distributor setup */
-	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
+	if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3,
+			       false, &gic_fd) != 0)
+		return -1;
 
 	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
 			0, &nr_irqs, true);
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:23 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:23 +0100
Subject: [PATCH 01/27] drm/encoder: Add of_graph port to struct drm_encoder
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-2-s.hauer@pengutronix.de>

Add a device node to drm_encoder which corresponds with the port node
in the DT description of the encoder. This allows drivers to find the
of_graph link between a crtc and an encoder.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 include/drm/drm_encoder.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/drm/drm_encoder.h b/include/drm/drm_encoder.h
index 6e91a0280f31..3acd054b1eb3 100644
--- a/include/drm/drm_encoder.h
+++ b/include/drm/drm_encoder.h
@@ -99,6 +99,8 @@ struct drm_encoder {
 	struct drm_device *dev;
 	struct list_head head;
 
+	struct device_node *port;
+
 	struct drm_mode_object base;
 	char *name;
 	/**
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:28 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:28 +0100
Subject: [PATCH 06/27] drm/rockchip: dw_hdmi: Add support for hclk
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-7-s.hauer@pengutronix.de>

The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 3d7c3f6fdf22..b9928e622adf 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -76,6 +76,7 @@ struct rockchip_hdmi {
 	const struct rockchip_hdmi_chip_data *chip_data;
 	struct clk *ref_clk;
 	struct clk *grf_clk;
+	struct clk *hclk_clk;
 	struct dw_hdmi *hdmi;
 	struct regulator *avdd_0v9;
 	struct regulator *avdd_1v8;
@@ -226,6 +227,16 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 		return PTR_ERR(hdmi->grf_clk);
 	}
 
+	hdmi->hclk_clk = devm_clk_get(hdmi->dev, "hclk");
+	if (PTR_ERR(hdmi->hclk_clk) == -ENOENT) {
+		hdmi->hclk_clk = NULL;
+	} else if (PTR_ERR(hdmi->hclk_clk) == -EPROBE_DEFER) {
+		return -EPROBE_DEFER;
+	} else if (IS_ERR(hdmi->hclk_clk)) {
+		DRM_DEV_ERROR(hdmi->dev, "failed to get hclk_clk clock\n");
+		return PTR_ERR(hdmi->hclk_clk);
+	}
+
 	hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9");
 	if (IS_ERR(hdmi->avdd_0v9))
 		return PTR_ERR(hdmi->avdd_0v9);
@@ -593,6 +604,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		goto err_clk;
 	}
 
+	ret = clk_prepare_enable(hdmi->hclk_clk);
+	if (ret) {
+		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI hclk clock: %d\n",
+			      ret);
+		goto err_clk;
+	}
+
 	if (hdmi->chip_data == &rk3568_chip_data) {
 		regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
 			     HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:26 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:26 +0100
Subject: [PATCH 04/27] drm/rockchip: dw_hdmi: add rk3568 support
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-5-s.hauer@pengutronix.de>

Add a new dw_hdmi_plat_data struct and new compatible for rk3568.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 31 +++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index e352e0404f77..262eef614cb1 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -50,6 +50,10 @@
 #define RK3399_GRF_SOC_CON20		0x6250
 #define RK3399_HDMI_LCDC_SEL		BIT(6)
 
+#define RK3568_GRF_VO_CON1		0x0364
+#define RK3568_HDMI_SDAIN_MSK		BIT(15)
+#define RK3568_HDMI_SCLIN_MSK		BIT(14)
+
 #define HIWORD_UPDATE(val, mask)	(val | (mask) << 16)
 
 /**
@@ -470,6 +474,19 @@ static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
 	.use_drm_infoframe = true,
 };
 
+static struct rockchip_hdmi_chip_data rk3568_chip_data = {
+	.lcdsel_grf_reg = -1,
+};
+
+static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
+	.mode_valid = dw_hdmi_rockchip_mode_valid,
+	.mpll_cfg   = rockchip_mpll_cfg,
+	.cur_ctr    = rockchip_cur_ctr,
+	.phy_config = rockchip_phy_config,
+	.phy_data = &rk3568_chip_data,
+	.use_drm_infoframe = true,
+};
+
 static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
 	{ .compatible = "rockchip,rk3228-dw-hdmi",
 	  .data = &rk3228_hdmi_drv_data
@@ -483,6 +500,9 @@ static const struct of_device_id dw_hdmi_rockchip_dt_ids[] = {
 	{ .compatible = "rockchip,rk3399-dw-hdmi",
 	  .data = &rk3399_hdmi_drv_data
 	},
+	{ .compatible = "rockchip,rk3568-dw-hdmi",
+	  .data = &rk3568_hdmi_drv_data
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, dw_hdmi_rockchip_dt_ids);
@@ -517,6 +537,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	encoder = &hdmi->encoder;
 
 	encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
+
+	encoder->port = of_graph_get_port_by_id(dev->of_node, 0);
+
 	/*
 	 * If we failed to find the CRTC(s) which this encoder is
 	 * supposed to be connected to, it's because the CRTC has
@@ -547,6 +570,14 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	if (hdmi->chip_data == &rk3568_chip_data) {
+		regmap_write(hdmi->regmap, RK3568_GRF_VO_CON1,
+			     HIWORD_UPDATE(RK3568_HDMI_SDAIN_MSK |
+					   RK3568_HDMI_SCLIN_MSK,
+					   RK3568_HDMI_SDAIN_MSK |
+					   RK3568_HDMI_SCLIN_MSK));
+	}
+
 	drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
 	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:24 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:24 +0100
Subject: [PATCH 02/27] drm/rockchip: dw_hdmi: Do not leave clock enabled in
 error case
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-3-s.hauer@pengutronix.de>

The driver returns an error when devm_phy_optional_get() fails leaving
the previously enabled clock turned on. Change order and enable the
clock only after the phy has been acquired.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 830bdd5e9b7c..8677c8271678 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -529,13 +529,6 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	ret = clk_prepare_enable(hdmi->vpll_clk);
-	if (ret) {
-		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
-			      ret);
-		return ret;
-	}
-
 	hdmi->phy = devm_phy_optional_get(dev, "hdmi");
 	if (IS_ERR(hdmi->phy)) {
 		ret = PTR_ERR(hdmi->phy);
@@ -544,6 +537,13 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	ret = clk_prepare_enable(hdmi->vpll_clk);
+	if (ret) {
+		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
+			      ret);
+		return ret;
+	}
+
 	drm_encoder_helper_add(encoder, &dw_hdmi_rockchip_encoder_helper_funcs);
 	drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
 
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:22 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:22 +0100
Subject: [PATCH v4 00/27] drm/rockchip: RK356x VOP2 support
Message-ID: <20220126145549.617165-1-s.hauer@pengutronix.de>

This is v4 of adding RK356x VOP2 support. Due to popular demand I added
a changelog to each patch, at least starting with changes to v3, I
didn't care to add the older changes as well. I hopefully integrated all
feedback I received to v3. Additionally I added some patches to the HDMI
driver to support resolutions up to 4k at 60Hz. The patches are mostly
taken from the downstream kernel. Some have been send to public lists,
but were never applied upstream for reasons I do not know. The patches
are a bit more intrusive than needed for my case, but are present in the
downstream kernel for a long time, so I decided just to take them
instead of stripping them down to my needs. With these patches I
successfully used the driver with 4k at 30Hz. 4k at 60Hz doesn't work for me,
I hope this is due to my low quality cable.

Sascha

Changes since v3:
- added changelog to each patch
- Add 4k support to hdmi driver
- rebase on v5.17-rc1

Changes since v2:
- Add pin names to HDMI supply pin description
- Add hclk support to HDMI driver
- Dual license rockchip-vop2 binding, update binding
- Add HDMI connector to board dts files
- drop unnecessary gamma_lut registers from vop2
- Update dclk_vop[012] clock handling, no longer hacks needed
- Complete regmap conversion

Changes since v1:
- drop all unnecessary waiting for frames within atomic modeset and plane update
- Cluster subwin support removed
- gamma support removed
- unnecessary irq_lock removed
- interrupt handling simplified
- simplified zpos handling
- drop is_alpha_support(), use fb->format->has_alpha instead
- use devm_regulator_get() rather than devm_regulator_get_optional() for hdmi regulators
- Use fixed number of planes per video port
- Drop homegrown regmap code from vop2 driver (not complete yet)
- Add separate include file for vop2 driver to not pollute the vop include

Andy Yan (1):
  drm: rockchip: Add VOP2 driver

Benjamin Gaignard (1):
  dt-bindings: display: rockchip: dw-hdmi: Add compatible for rk3568
    HDMI

Douglas Anderson (2):
  drm/rockchip: dw_hdmi: Use auto-generated tables
  drm/rockchip: dw_hdmi: Set cur_ctr to 0 always

Michael Riesch (1):
  arm64: dts: rockchip: enable vop2 and hdmi tx on quartz64a

Nickey Yang (1):
  drm/rockchip: dw_hdmi: add default 594Mhz clk for 4K at 60hz

Sascha Hauer (21):
  drm/encoder: Add of_graph port to struct drm_encoder
  drm/rockchip: dw_hdmi: Do not leave clock enabled in error case
  drm/rockchip: dw_hdmi: rename vpll clock to reference clock
  drm/rockchip: dw_hdmi: add rk3568 support
  drm/rockchip: dw_hdmi: add regulator support
  drm/rockchip: dw_hdmi: Add support for hclk
  drm/rockchip: dw_hdmi: drop mode_valid hook
  clk: rockchip: rk3568: Add more PLL rates
  dt-bindings: display: rockchip: dw-hdmi: Make unwedge pinctrl optional
  dt-bindings: display: rockchip: dw-hdmi: use "ref" as clock name
  dt-bindings: display: rockchip: dw-hdmi: Add regulator support
  dt-bindings: display: rockchip: dw-hdmi: Add additional clock
  dt-bindings: display: rockchip: Add binding for VOP2
  arm64: dts: rockchip: rk3399: reorder hmdi clocks
  arm64: dts: rockchip: rk3399: rename HDMI ref clock to 'ref'
  arm64: dts: rockchip: rk356x: Add VOP2 nodes
  arm64: dts: rockchip: rk356x: Add HDMI nodes
  arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi
  clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop*
  clk: rk3568: Add CLK_SET_RATE_PARENT to the HDMI reference clock
  drm/rockchip: Make VOP driver optional

 .../display/rockchip/rockchip,dw-hdmi.yaml    |   29 +-
 .../display/rockchip/rockchip-vop2.yaml       |  146 +
 arch/arm64/boot/dts/rockchip/rk3399.dtsi      |    6 +-
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   48 +
 arch/arm64/boot/dts/rockchip/rk3566.dtsi      |    4 +
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     |   48 +
 arch/arm64/boot/dts/rockchip/rk3568.dtsi      |    4 +
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   86 +
 drivers/clk/rockchip/clk-rk3568.c             |   14 +-
 drivers/gpu/drm/rockchip/Kconfig              |   14 +
 drivers/gpu/drm/rockchip/Makefile             |    4 +-
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |  293 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |    3 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |    7 +-
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c    |    2 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h   |   15 +
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 2665 +++++++++++++++++
 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  480 +++
 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  |  285 ++
 include/drm/drm_encoder.h                     |    2 +
 include/dt-bindings/soc/rockchip,vop2.h       |   14 +
 21 files changed, 4039 insertions(+), 130 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
 create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
 create mode 100644 include/dt-bindings/soc/rockchip,vop2.h

-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:25 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:25 +0100
Subject: [PATCH 03/27] drm/rockchip: dw_hdmi: rename vpll clock to reference
 clock
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-4-s.hauer@pengutronix.de>

"vpll" is a misnomer. A clock input to a device should be named after
the usage in the device, not after the clock that drives it. On the
rk3568 the same clock is driven by the HPLL.
To fix that, this patch renames the vpll clock to ref clock. The clock
name "vpll" is left for compatibility to old device trees.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 29 ++++++++++++---------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 8677c8271678..e352e0404f77 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -69,7 +69,7 @@ struct rockchip_hdmi {
 	struct regmap *regmap;
 	struct drm_encoder encoder;
 	const struct rockchip_hdmi_chip_data *chip_data;
-	struct clk *vpll_clk;
+	struct clk *ref_clk;
 	struct clk *grf_clk;
 	struct dw_hdmi *hdmi;
 	struct phy *phy;
@@ -196,14 +196,17 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 		return PTR_ERR(hdmi->regmap);
 	}
 
-	hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
-	if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
-		hdmi->vpll_clk = NULL;
-	} else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+	hdmi->ref_clk = devm_clk_get(hdmi->dev, "ref");
+	if (PTR_ERR(hdmi->ref_clk) == -ENOENT)
+		hdmi->ref_clk = devm_clk_get(hdmi->dev, "vpll");
+
+	if (PTR_ERR(hdmi->ref_clk) == -ENOENT) {
+		hdmi->ref_clk = NULL;
+	} else if (PTR_ERR(hdmi->ref_clk) == -EPROBE_DEFER) {
 		return -EPROBE_DEFER;
-	} else if (IS_ERR(hdmi->vpll_clk)) {
-		DRM_DEV_ERROR(hdmi->dev, "failed to get vpll clock\n");
-		return PTR_ERR(hdmi->vpll_clk);
+	} else if (IS_ERR(hdmi->ref_clk)) {
+		DRM_DEV_ERROR(hdmi->dev, "failed to get reference clock\n");
+		return PTR_ERR(hdmi->ref_clk);
 	}
 
 	hdmi->grf_clk = devm_clk_get(hdmi->dev, "grf");
@@ -257,7 +260,7 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
 {
 	struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
 
-	clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
+	clk_set_rate(hdmi->ref_clk, adj_mode->clock * 1000);
 }
 
 static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)
@@ -537,9 +540,9 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
-	ret = clk_prepare_enable(hdmi->vpll_clk);
+	ret = clk_prepare_enable(hdmi->ref_clk);
 	if (ret) {
-		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI vpll: %d\n",
+		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n",
 			      ret);
 		return ret;
 	}
@@ -558,7 +561,7 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	if (IS_ERR(hdmi->hdmi)) {
 		ret = PTR_ERR(hdmi->hdmi);
 		drm_encoder_cleanup(encoder);
-		clk_disable_unprepare(hdmi->vpll_clk);
+		clk_disable_unprepare(hdmi->ref_clk);
 	}
 
 	return ret;
@@ -570,7 +573,7 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
 	struct rockchip_hdmi *hdmi = dev_get_drvdata(dev);
 
 	dw_hdmi_unbind(hdmi->hdmi);
-	clk_disable_unprepare(hdmi->vpll_clk);
+	clk_disable_unprepare(hdmi->ref_clk);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:27 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:27 +0100
Subject: [PATCH 05/27] drm/rockchip: dw_hdmi: add regulator support
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-6-s.hauer@pengutronix.de>

The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs needed
for the HDMI port. add support for these to the driver for boards which
have them supplied by switchable regulators.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 41 +++++++++++++++++++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 262eef614cb1..3d7c3f6fdf22 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -9,6 +9,7 @@
 #include <linux/platform_device.h>
 #include <linux/phy/phy.h>
 #include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
 
 #include <drm/bridge/dw_hdmi.h>
 #include <drm/drm_edid.h>
@@ -76,6 +77,8 @@ struct rockchip_hdmi {
 	struct clk *ref_clk;
 	struct clk *grf_clk;
 	struct dw_hdmi *hdmi;
+	struct regulator *avdd_0v9;
+	struct regulator *avdd_1v8;
 	struct phy *phy;
 };
 
@@ -223,6 +226,14 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 		return PTR_ERR(hdmi->grf_clk);
 	}
 
+	hdmi->avdd_0v9 = devm_regulator_get(hdmi->dev, "avdd-0v9");
+	if (IS_ERR(hdmi->avdd_0v9))
+		return PTR_ERR(hdmi->avdd_0v9);
+
+	hdmi->avdd_1v8 = devm_regulator_get(hdmi->dev, "avdd-1v8");
+	if (IS_ERR(hdmi->avdd_1v8))
+		return PTR_ERR(hdmi->avdd_1v8);
+
 	return 0;
 }
 
@@ -563,11 +574,23 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 		return ret;
 	}
 
+	ret = regulator_enable(hdmi->avdd_0v9);
+	if (ret) {
+		DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd0v9: %d\n", ret);
+		goto err_avdd_0v9;
+	}
+
+	ret = regulator_enable(hdmi->avdd_1v8);
+	if (ret) {
+		DRM_DEV_ERROR(hdmi->dev, "failed to enable avdd1v8: %d\n", ret);
+		goto err_avdd_1v8;
+	}
+
 	ret = clk_prepare_enable(hdmi->ref_clk);
 	if (ret) {
 		DRM_DEV_ERROR(hdmi->dev, "Failed to enable HDMI reference clock: %d\n",
 			      ret);
-		return ret;
+		goto err_clk;
 	}
 
 	if (hdmi->chip_data == &rk3568_chip_data) {
@@ -591,10 +614,19 @@ static int dw_hdmi_rockchip_bind(struct device *dev, struct device *master,
 	 */
 	if (IS_ERR(hdmi->hdmi)) {
 		ret = PTR_ERR(hdmi->hdmi);
-		drm_encoder_cleanup(encoder);
-		clk_disable_unprepare(hdmi->ref_clk);
+		goto err_bind;
 	}
 
+	return 0;
+
+err_bind:
+	clk_disable_unprepare(hdmi->ref_clk);
+	drm_encoder_cleanup(encoder);
+err_clk:
+	regulator_disable(hdmi->avdd_1v8);
+err_avdd_1v8:
+	regulator_disable(hdmi->avdd_0v9);
+err_avdd_0v9:
 	return ret;
 }
 
@@ -605,6 +637,9 @@ static void dw_hdmi_rockchip_unbind(struct device *dev, struct device *master,
 
 	dw_hdmi_unbind(hdmi->hdmi);
 	clk_disable_unprepare(hdmi->ref_clk);
+
+	regulator_disable(hdmi->avdd_1v8);
+	regulator_disable(hdmi->avdd_0v9);
 }
 
 static const struct component_ops dw_hdmi_rockchip_ops = {
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:30 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:30 +0100
Subject: [PATCH 08/27] drm/rockchip: dw_hdmi: drop mode_valid hook
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-9-s.hauer@pengutronix.de>

The driver checks if the pixel clock of the given mode matches an entry
in the mpll config table. The frequencies in the mpll table are meant as
a frequency range up to which the entry works, not as a frequency that
must match the pixel clock. The downstream Kernel also does not have
this check, so drop it to allow for more display resolutions.

Changes since v3:
- new patch

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 25 ---------------------
 1 file changed, 25 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 160107b333ef..c44eb4d2e2d5 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -256,26 +256,6 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
 	return 0;
 }
 
-static enum drm_mode_status
-dw_hdmi_rockchip_mode_valid(struct dw_hdmi *hdmi, void *data,
-			    const struct drm_display_info *info,
-			    const struct drm_display_mode *mode)
-{
-	const struct dw_hdmi_mpll_config *mpll_cfg = rockchip_mpll_cfg;
-	int pclk = mode->clock * 1000;
-	bool valid = false;
-	int i;
-
-	for (i = 0; mpll_cfg[i].mpixelclock != (~0UL); i++) {
-		if (pclk == mpll_cfg[i].mpixelclock) {
-			valid = true;
-			break;
-		}
-	}
-
-	return (valid) ? MODE_OK : MODE_BAD;
-}
-
 static void dw_hdmi_rockchip_encoder_disable(struct drm_encoder *encoder)
 {
 }
@@ -441,7 +421,6 @@ static struct rockchip_hdmi_chip_data rk3228_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3228_hdmi_drv_data = {
-	.mode_valid = dw_hdmi_rockchip_mode_valid,
 	.mpll_cfg = rockchip_mpll_cfg,
 	.cur_ctr = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
@@ -458,7 +437,6 @@ static struct rockchip_hdmi_chip_data rk3288_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3288_hdmi_drv_data = {
-	.mode_valid = dw_hdmi_rockchip_mode_valid,
 	.mpll_cfg   = rockchip_mpll_cfg,
 	.cur_ctr    = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
@@ -478,7 +456,6 @@ static struct rockchip_hdmi_chip_data rk3328_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3328_hdmi_drv_data = {
-	.mode_valid = dw_hdmi_rockchip_mode_valid,
 	.mpll_cfg = rockchip_mpll_cfg,
 	.cur_ctr = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
@@ -496,7 +473,6 @@ static struct rockchip_hdmi_chip_data rk3399_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3399_hdmi_drv_data = {
-	.mode_valid = dw_hdmi_rockchip_mode_valid,
 	.mpll_cfg   = rockchip_mpll_cfg,
 	.cur_ctr    = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
@@ -509,7 +485,6 @@ static struct rockchip_hdmi_chip_data rk3568_chip_data = {
 };
 
 static const struct dw_hdmi_plat_data rk3568_hdmi_drv_data = {
-	.mode_valid = dw_hdmi_rockchip_mode_valid,
 	.mpll_cfg   = rockchip_mpll_cfg,
 	.cur_ctr    = rockchip_cur_ctr,
 	.phy_config = rockchip_phy_config,
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:31 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:31 +0100
Subject: [PATCH 09/27] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-10-s.hauer@pengutronix.de>

From: Douglas Anderson <dianders at chromium.org>

Jitter was improved by lowering the MPLL bandwidth to account for high
frequency noise in the rk3288 PLL.  In each case MPLL bandwidth was
lowered only enough to get us a comfortable margin.  We believe that
lowering the bandwidth like this is safe given sufficient testing.

Changes since v3:
- new patch

Signed-off-by: Douglas Anderson <dianders at chromium.org>
Signed-off-by: Yakir Yang <ykk at rock-chips.com>
(am from https://patchwork.kernel.org/patch/9223301/)
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++--------------
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index c44eb4d2e2d5..77f82a4fd027 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -176,20 +176,8 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
 static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
 	/*      pixelclk    bpp8    bpp10   bpp12 */
 	{
-		40000000,  { 0x0018, 0x0018, 0x0018 },
-	}, {
-		65000000,  { 0x0028, 0x0028, 0x0028 },
-	}, {
-		66000000,  { 0x0038, 0x0038, 0x0038 },
-	}, {
-		74250000,  { 0x0028, 0x0038, 0x0038 },
-	}, {
-		83500000,  { 0x0028, 0x0038, 0x0038 },
-	}, {
-		146250000, { 0x0038, 0x0038, 0x0038 },
-	}, {
-		148500000, { 0x0000, 0x0038, 0x0038 },
-	}, {
+		600000000, { 0x0000, 0x0000, 0x0000 },
+	},  {
 		~0UL,      { 0x0000, 0x0000, 0x0000},
 	}
 };
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:39 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:39 +0100
Subject: [PATCH 17/27] dt-bindings: display: rockchip: Add binding for VOP2
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-18-s.hauer@pengutronix.de>

The VOP2 is found on newer Rockchip SoCs like the rk3568 or the rk3566.
The binding differs slightly from the existing VOP binding, so add a new
binding file for it.

Changes since v3:
- drop redundant _vop suffix from clock names

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../display/rockchip/rockchip-vop2.yaml       | 146 ++++++++++++++++++
 1 file changed, 146 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
new file mode 100644
index 000000000000..572cfb307c20
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -0,0 +1,146 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/rockchip/rockchip-vop2.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip SoC display controller (VOP2)
+
+description:
+  VOP2 (Video Output Processor v2) is the display controller for the Rockchip
+  series of SoCs which transfers the image data from a video memory
+  buffer to an external LCD interface.
+
+maintainers:
+  - Sandy Huang <hjc at rock-chips.com>
+  - Heiko Stuebner <heiko at sntech.de>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3566-vop
+      - rockchip,rk3568-vop
+
+  reg:
+    minItems: 1
+    items:
+      - description:
+          Must contain one entry corresponding to the base address and length
+          of the register space.
+      - description:
+          Can optionally contain a second entry corresponding to
+          the CRTC gamma LUT address.
+
+  interrupts:
+    maxItems: 1
+    description:
+      The VOP interrupt is shared by several interrupt sources, such as
+      frame start (VSYNC), line flag and other status interrupts.
+
+  clocks:
+    items:
+      - description: Clock for ddr buffer transfer.
+      - description: Clock for the ahb bus to R/W the phy regs.
+      - description: Pixel clock for video port 0.
+      - description: Pixel clock for video port 1.
+      - description: Pixel clock for video port 2.
+
+  clock-names:
+    items:
+      - const: aclk
+      - const: hclk
+      - const: dclk_vp0
+      - const: dclk_vp1
+      - const: dclk_vp2
+
+  rockchip,grf:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to GRF regs used for misc control
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    properties:
+      port at 0:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output endpoint of VP0
+
+      port at 1:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output endpoint of VP1
+
+      port at 2:
+        $ref: /schemas/graph.yaml#/properties/port
+        description:
+          Output endpoint of VP2
+
+  assigned-clocks: true
+
+  assigned-clock-rates: true
+
+  assigned-clock-parents: true
+
+  iommus:
+    maxItems: 1
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - ports
+
+additionalProperties: false
+
+examples:
+  - |
+        #include <dt-bindings/clock/rk3568-cru.h>
+        #include <dt-bindings/interrupt-controller/arm-gic.h>
+        #include <dt-bindings/power/rk3568-power.h>
+        bus {
+            #address-cells = <2>;
+            #size-cells = <2>;
+            vop: vop at fe040000 {
+                compatible = "rockchip,rk3568-vop";
+                reg = <0x0 0xfe040000 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>;
+                interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                clocks = <&cru ACLK_VOP>,
+                         <&cru HCLK_VOP>,
+                         <&cru DCLK_VOP0>,
+                         <&cru DCLK_VOP1>,
+                         <&cru DCLK_VOP2>;
+                clock-names = "aclk_vop",
+                              "hclk_vop",
+                              "dclk_vp0",
+                              "dclk_vp1",
+                              "dclk_vp2";
+                power-domains = <&power RK3568_PD_VO>;
+                iommus = <&vop_mmu>;
+                vop_out: ports {
+                    #address-cells = <1>;
+                    #size-cells = <0>;
+                    vp0: port at 0 {
+                        reg = <0>;
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                    };
+                    vp1: port at 1 {
+                        reg = <1>;
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                    };
+                    vp2: port at 2 {
+                        reg = <2>;
+                        #address-cells = <1>;
+                        #size-cells = <0>;
+                    };
+                };
+            };
+        };
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:33 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:33 +0100
Subject: [PATCH 11/27] clk: rockchip: rk3568: Add more PLL rates
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-12-s.hauer@pengutronix.de>

This adds a few more PLL settings needed for some standard resolutions:

297MHz    3840x2160-30.00
241.5MHz  2560x1440-59.95
135MHz    1280x1024-75.02
119MHz    1680x1050-59.88
108MHz    1280x1024-60.02
 78.75MHz 1024x768-75.03

Changes since v3:
- new patch

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/clk/rockchip/clk-rk3568.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
index 69a9e8069a48..9d889fc46811 100644
--- a/drivers/clk/rockchip/clk-rk3568.c
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -71,11 +71,17 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
 	RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
 	RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
 	RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+	RK3036_PLL_RATE(297000000, 2, 99, 4, 1, 1, 0),
+	RK3036_PLL_RATE(241500000, 2, 161, 4, 2, 1, 0),
 	RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
 	RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
 	RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
+	RK3036_PLL_RATE(135000000, 2, 45, 4, 1, 1, 0),
+	RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0),
+	RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0),
 	RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
 	RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+	RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0),
 	RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
 	{ /* sentinel */ },
 };
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:47 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:47 +0100
Subject: [PATCH 25/27] clk: rk3568: Add CLK_SET_RATE_PARENT to the HDMI
 reference clock
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-26-s.hauer@pengutronix.de>

On the rk3568 we have this (simplified) situation:

 .--------.     .-----.    .---------.
-| hpll   |--.--| /n  |----|dclk_vop0|-
 `--------?  |  `-----?    `---------?
             |  .-----.    .---------.
             `--| /m  |----|dclk_vop1|-
             |  `-----?    `---------?
             |             .---------.
             `-------------|hdmi_ref |-
                           `---------?

For the HDMI to work the HDMI reference clock needs to be the same as the
pixel clock which means the dividers have be set to one. The last patch removed
the CLK_SET_RATE_PARENT flag from the pixel clocks which means the hpll is not
changed on pixel clock changes. In order to allow the HDMI controller to
set a suitable PLL rate we now add the CLK_SET_RATE_PARENT flag to the
HDMI reference clock. With this the flow becomes:

1) HDMI controller driver sets the rate to its pixel clock which means
   hpll is set to the pixel clock
2) VOP2 driver sets dclk_vop[012] to the pixel clock. As this can't change
   the hpll clock anymore this means only the divider is adjusted to the
   desired value of dividing by one.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/clk/rockchip/clk-rk3568.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
index 7687c62d1fa8..63dfbeeeb06d 100644
--- a/drivers/clk/rockchip/clk-rk3568.c
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -1568,7 +1568,7 @@ static struct rockchip_clk_branch rk3568_clk_pmu_branches[] __initdata = {
 			RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS),
 	GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0,
 			RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS),
-	MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0,
+	MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, CLK_SET_RATE_PARENT,
 			RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS),
 };
 
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:36 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:36 +0100
Subject: [PATCH 14/27] dt-bindings: display: rockchip: dw-hdmi: use "ref" as
 clock name
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-15-s.hauer@pengutronix.de>

"vpll" is a misnomer. A clock input to a device should be named after
the usage in the device, not after the clock that drives it. On the
rk3568 the same clock is driven by the HPLL.
This patch adds "ref" as a new alternative clock name for "vpll"

Changes since v3:
- Keep old clock name for compatibility reasons

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml      | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 6e09dd2ee05a..638119924ad8 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -37,7 +37,8 @@ properties:
       # order when present.
       - description: The HDMI CEC controller main clock
       - description: Power for GRF IO
-      - description: External clock for some HDMI PHY
+      - description: External clock for some HDMI PHY (old clock name, deprecated)
+      - description: External clock for some HDMI PHY (new name)
 
   clock-names:
     minItems: 2
@@ -48,10 +49,14 @@ properties:
           - cec
           - grf
           - vpll
+          - ref
       - enum:
           - grf
           - vpll
-      - const: vpll
+          - ref
+      - enum:
+          - vpll
+          - ref
 
   ddc-i2c-bus:
     $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:29 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:29 +0100
Subject: [PATCH 07/27] drm/rockchip: dw_hdmi: Use auto-generated tables
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-8-s.hauer@pengutronix.de>

From: Douglas Anderson <dianders at chromium.org>

The previous tables for mpll_cfg and curr_ctrl were created using the
20-pages of example settings provided by the PHY vendor.  Those
example settings weren't particularly dense, so there were places
where we were guessing what the settings would be for 10-bit and
12-bit (not that we use those anyway).  It was also always a lot of
extra work every time we wanted to add a new clock rate since we had
to cross-reference several tables.

In <http://crosreview.com/285855> I've gone through the work to figure
out how to generate this table automatically.  Let's now use the
automatically generated table and then we'll never need to look at it
again.

We only support 8-bit mode right now and only support a small number
of clock rates and and I've verified that the only 8-bit rate that was
affected was 148.5.  That mode appears to have been wrong in the old
table.

Changes since v3:
- new patch

Signed-off-by: Douglas Anderson <dianders at chromium.org>
Signed-off-by: Yakir Yang <ykk at rock-chips.com>
Reviewed-by: St?phane Marchesin <marcheu at chromium.org>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 130 +++++++++++---------
 1 file changed, 69 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index b9928e622adf..160107b333ef 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -87,80 +87,88 @@ struct rockchip_hdmi {
 
 static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
 	{
-		27000000, {
-			{ 0x00b3, 0x0000},
-			{ 0x2153, 0x0000},
-			{ 0x40f3, 0x0000}
+		30666000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40f3, 0x0000 },
 		},
-	}, {
-		36000000, {
-			{ 0x00b3, 0x0000},
-			{ 0x2153, 0x0000},
-			{ 0x40f3, 0x0000}
+	},  {
+		36800000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2153, 0x0000 },
+			{ 0x40a2, 0x0001 },
 		},
-	}, {
-		40000000, {
-			{ 0x00b3, 0x0000},
-			{ 0x2153, 0x0000},
-			{ 0x40f3, 0x0000}
+	},  {
+		46000000, {
+			{ 0x00b3, 0x0000 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
 		},
-	}, {
-		54000000, {
-			{ 0x0072, 0x0001},
-			{ 0x2142, 0x0001},
-			{ 0x40a2, 0x0001},
+	},  {
+		61333000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x40a2, 0x0001 },
 		},
-	}, {
-		65000000, {
-			{ 0x0072, 0x0001},
-			{ 0x2142, 0x0001},
-			{ 0x40a2, 0x0001},
+	},  {
+		73600000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2142, 0x0001 },
+			{ 0x4061, 0x0002 },
 		},
-	}, {
-		66000000, {
-			{ 0x013e, 0x0003},
-			{ 0x217e, 0x0002},
-			{ 0x4061, 0x0002}
+	},  {
+		92000000, {
+			{ 0x0072, 0x0001 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
 		},
-	}, {
-		74250000, {
-			{ 0x0072, 0x0001},
-			{ 0x2145, 0x0002},
-			{ 0x4061, 0x0002}
+	},  {
+		122666000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4061, 0x0002 },
 		},
-	}, {
-		83500000, {
-			{ 0x0072, 0x0001},
+	},  {
+		147200000, {
+			{ 0x0051, 0x0002 },
+			{ 0x2145, 0x0002 },
+			{ 0x4064, 0x0003 },
 		},
-	}, {
-		108000000, {
-			{ 0x0051, 0x0002},
-			{ 0x2145, 0x0002},
-			{ 0x4061, 0x0002}
+	},  {
+		184000000, {
+			{ 0x0051, 0x0002 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
 		},
-	}, {
-		106500000, {
-			{ 0x0051, 0x0002},
-			{ 0x2145, 0x0002},
-			{ 0x4061, 0x0002}
+	},  {
+		226666000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x4064, 0x0003 },
 		},
-	}, {
-		146250000, {
-			{ 0x0051, 0x0002},
-			{ 0x2145, 0x0002},
-			{ 0x4061, 0x0002}
+	},  {
+		272000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x214c, 0x0003 },
+			{ 0x5a64, 0x0003 },
 		},
-	}, {
-		148500000, {
-			{ 0x0051, 0x0003},
-			{ 0x214c, 0x0003},
-			{ 0x4064, 0x0003}
+	},  {
+		340000000, {
+			{ 0x0040, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
 		},
-	}, {
+	},  {
+		600000000, {
+			{ 0x1a40, 0x0003 },
+			{ 0x3b4c, 0x0003 },
+			{ 0x5a64, 0x0003 },
+		},
+	},  {
 		~0UL, {
-			{ 0x00a0, 0x000a },
-			{ 0x2001, 0x000f },
-			{ 0x4002, 0x000f },
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
+			{ 0x0000, 0x0000 },
 		},
 	}
 };
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:35 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:35 +0100
Subject: [PATCH 13/27] dt-bindings: display: rockchip: dw-hdmi: Make unwedge
 pinctrl optional
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-14-s.hauer@pengutronix.de>

None of the upstream device tree files has a "unwedge" pinctrl
specified. Make it optional.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 45cae4f57a1c..6e09dd2ee05a 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -73,6 +73,7 @@ properties:
       The unwedge pinctrl entry shall drive the DDC SDA line low. This is
       intended to work around a hardware errata that can cause the DDC I2C
       bus to be wedged.
+    minItems: 1
     items:
       - const: default
       - const: unwedge
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:34 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:34 +0100
Subject: [PATCH 12/27] dt-bindings: display: rockchip: dw-hdmi: Add compatible
 for rk3568 HDMI
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-13-s.hauer@pengutronix.de>

From: Benjamin Gaignard <benjamin.gaignard at collabora.com>

Define a new compatible for rk3568 HDMI.
This version of HDMI hardware block needs two new clocks hclk_vio and hclk
to provide phy reference clocks.

Signed-off-by: Benjamin Gaignard <benjamin.gaignard at collabora.com>
Reviewed-by: Rob Herring <robh at kernel.org>
Link: https://lore.kernel.org/r/20210707120323.401785-2-benjamin.gaignard at collabora.com
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index da3b889ad8fc..45cae4f57a1c 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -23,6 +23,7 @@ properties:
       - rockchip,rk3288-dw-hdmi
       - rockchip,rk3328-dw-hdmi
       - rockchip,rk3399-dw-hdmi
+      - rockchip,rk3568-dw-hdmi
 
   reg-io-width:
     const: 4
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:37 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:37 +0100
Subject: [PATCH 15/27] dt-bindings: display: rockchip: dw-hdmi: Add regulator
 support
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-16-s.hauer@pengutronix.de>

The RK3568 has HDMI_TX_AVDD0V9 and HDMI_TX_AVDD_1V8 supply inputs
needed for the HDMI port. Add the binding for these supplies.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml   | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index 638119924ad8..d7cb2b2be60e 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -28,6 +28,17 @@ properties:
   reg-io-width:
     const: 4
 
+  avdd-0v9-supply:
+    description:
+      A 0.9V supply that powers up the SoC internal circuitry. The actual pin name
+      varies between the different SoCs and is usually HDMI_TX_AVDD_0V9 or sometimes
+      HDMI_AVDD_1V0.
+
+  avdd-1v8-supply:
+    description:
+      A 1.8V supply that powers up the SoC internal circuitry. The pin name on the
+      SoC usually is HDMI_TX_AVDD_1V8.
+
   clocks:
     minItems: 2
     items:
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:43 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:43 +0100
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-22-s.hauer@pengutronix.de>

Add support for the HDMI port found on RK3568.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 4008bd666d01..e38fb223e9b8 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -10,7 +10,6 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/power/rk3568-power.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
-#include <dt-bindings/soc/rockchip,vop2.h>
 #include <dt-bindings/thermal/thermal.h>
 
 / {
@@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
 		status = "disabled";
 	};
 
+	hdmi: hdmi at fe0a0000 {
+		compatible = "rockchip,rk3568-dw-hdmi";
+		reg = <0x0 0xfe0a0000 0x0 0x20000>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru PCLK_HDMI_HOST>,
+			 <&cru CLK_HDMI_SFR>,
+			 <&cru CLK_HDMI_CEC>,
+			 <&pmucru CLK_HDMI_REF>,
+			 <&cru HCLK_VOP>;
+		clock-names = "iahb", "isfr", "cec", "ref", "hclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
+		power-domains = <&power RK3568_PD_VO>;
+		reg-io-width = <4>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
+		status = "disabled";
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port at 0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			hdmi_out: port at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+
 	qos_gpu: qos at fe128000 {
 		compatible = "rockchip,rk3568-qos", "syscon";
 		reg = <0x0 0xfe128000 0x0 0x20>;
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:48 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:48 +0100
Subject: [PATCH 26/27] drm/rockchip: Make VOP driver optional
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-27-s.hauer@pengutronix.de>

With upcoming VOP2 support VOP won't be the only choice anymore, so make
the VOP driver optional.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/Kconfig            | 8 ++++++++
 drivers/gpu/drm/rockchip/Makefile           | 3 ++-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 2 +-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 9f1ecefc3933..b9b156308460 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -21,8 +21,16 @@ config DRM_ROCKCHIP
 
 if DRM_ROCKCHIP
 
+config ROCKCHIP_VOP
+	bool "Rockchip VOP driver"
+	default y
+	help
+	  This selects support for the VOP driver. You should enable it
+	  on all older SoCs up to RK3399.
+
 config ROCKCHIP_ANALOGIX_DP
 	bool "Rockchip specific extensions for Analogix DP driver"
+	depends on ROCKCHIP_VOP
 	help
 	  This selects support for Rockchip SoC specific extensions
 	  for the Analogix Core DP driver. If you want to enable DP
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
index 1a56f696558c..dfc5512fdb9f 100644
--- a/drivers/gpu/drm/rockchip/Makefile
+++ b/drivers/gpu/drm/rockchip/Makefile
@@ -4,8 +4,9 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
-		rockchip_drm_gem.o rockchip_drm_vop.o rockchip_vop_reg.o
+		rockchip_drm_gem.o
 
+rockchipdrm-$(CONFIG_ROCKCHIP_VOP) += rockchip_drm_vop.o rockchip_vop_reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
 rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
 rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index bec207de4544..82c8faf1fb6b 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -458,7 +458,7 @@ static int __init rockchip_drm_init(void)
 	int ret;
 
 	num_rockchip_sub_drivers = 0;
-	ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_DRM_ROCKCHIP);
+	ADD_ROCKCHIP_SUB_DRIVER(vop_platform_driver, CONFIG_ROCKCHIP_VOP);
 	ADD_ROCKCHIP_SUB_DRIVER(rockchip_lvds_driver,
 				CONFIG_ROCKCHIP_LVDS);
 	ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver,
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:45 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:45 +0100
Subject: [PATCH 23/27] arm64: dts: rockchip: enable vop2 and hdmi tx on
 quartz64a
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-24-s.hauer@pengutronix.de>

From: Michael Riesch <michael.riesch at wolfvision.net>

Enable the RK356x Video Output Processor (VOP) 2 on the Pine64
Quartz64 Model A.

Changes since v3:
- Fix HDMI connector type

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 166399b7f13f..64de5b15f572 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -4,6 +4,7 @@
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rk3566.dtsi"
 
 / {
@@ -35,6 +36,17 @@ fan: gpio_fan {
 		#cooling-cells = <2>;
 	};
 
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -205,6 +217,18 @@ &gmac1m0_clkinout
 	status = "okay";
 };
 
+&hdmi {
+	avdd-0v9-supply = <&vdda_0v9>;
+	avdd-1v8-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -551,3 +575,27 @@ bluetooth {
 &uart2 {
 	status = "okay";
 };
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint at 0 {
+		reg = <0>;
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint at RK3568_VOP2_EP_HDMI {
+		reg = <RK3568_VOP2_EP_HDMI>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:32 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:32 +0100
Subject: [PATCH 10/27] drm/rockchip: dw_hdmi: add default 594Mhz clk for
 4K@60hz
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-11-s.hauer@pengutronix.de>

From: Nickey Yang <nickey.yang at rock-chips.com>

add 594Mhz configuration parameters in rockchip_phy_config

Changes since v3:
- new patch

Change-Id: Iaa335cdd90059817fd9892877e574f8b84f2b5dc
Signed-off-by: Nickey Yang <nickey.yang at rock-chips.com>
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index 77f82a4fd027..c038674271b2 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -187,6 +187,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
 	{ 74250000,  0x8009, 0x0004, 0x0272},
 	{ 148500000, 0x802b, 0x0004, 0x028d},
 	{ 297000000, 0x8039, 0x0005, 0x028d},
+	{ 594000000, 0x8039, 0x0000, 0x019d},
 	{ ~0UL,	     0x0000, 0x0000, 0x0000}
 };
 
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:42 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:42 +0100
Subject: [PATCH 20/27] arm64: dts: rockchip: rk356x: Add VOP2 nodes
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-21-s.hauer@pengutronix.de>

The VOP2 is the display output controller on the RK3568. Add the node
for it to the dtsi file along with the required display-subsystem node
and the iommu node.

changes since v3:
- Bring back gamma_lut regs
- Drop redundant _vop suffix from clock names

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk3566.dtsi |  4 ++
 arch/arm64/boot/dts/rockchip/rk3568.dtsi |  4 ++
 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 51 ++++++++++++++++++++++++
 include/dt-bindings/soc/rockchip,vop2.h  | 14 +++++++
 4 files changed, 73 insertions(+)
 create mode 100644 include/dt-bindings/soc/rockchip,vop2.h

diff --git a/arch/arm64/boot/dts/rockchip/rk3566.dtsi b/arch/arm64/boot/dts/rockchip/rk3566.dtsi
index 3839eef5e4f7..595fa2562cb8 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3566.dtsi
@@ -18,3 +18,7 @@ power-domain at RK3568_PD_PIPE {
 		#power-domain-cells = <0>;
 	};
 };
+
+&vop {
+	compatible = "rockchip,rk3566-vop";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
index 2fd313a295f8..1e55efb6fcfd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -95,3 +95,7 @@ power-domain at RK3568_PD_PIPE {
 		#power-domain-cells = <0>;
 	};
 };
+
+&vop {
+	compatible = "rockchip,rk3568-vop";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a23975..4008bd666d01 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -10,6 +10,7 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/power/rk3568-power.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include <dt-bindings/thermal/thermal.h>
 
 / {
@@ -129,6 +130,11 @@ opp-1800000000 {
 		};
 	};
 
+	display_subsystem: display-subsystem {
+		compatible = "rockchip,display-subsystem";
+		ports = <&vop_out>;
+	};
+
 	firmware {
 		scmi: scmi {
 			compatible = "arm,scmi-smc";
@@ -451,6 +457,51 @@ gmac1_mtl_tx_setup: tx-queues-config {
 		};
 	};
 
+	vop: vop at fe040000 {
+		reg = <0x0 0xfe040000 0x0 0x3000>, <0x0 0xfe044000 0x0 0x1000>;
+		reg-names = "regs", "gamma_lut";
+		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>, <&cru DCLK_VOP0>, <&cru DCLK_VOP1>, <&cru DCLK_VOP2>;
+		clock-names = "aclk", "hclk", "dclk_vp0", "dclk_vp1", "dclk_vp2";
+		iommus = <&vop_mmu>;
+		power-domains = <&power RK3568_PD_VO>;
+		rockchip,grf = <&grf>;
+		status = "disabled";
+
+		vop_out: ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			vp0: port at 0 {
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			vp1: port at 1 {
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+
+			vp2: port at 2 {
+				reg = <2>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+			};
+		};
+	};
+
+	vop_mmu: iommu at fe043e00 {
+		compatible = "rockchip,rk3568-iommu";
+		reg = <0x0 0xfe043e00 0x0 0x100>, <0x0 0xfe043f00 0x0 0x100>;
+		interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
+		clock-names = "aclk", "iface";
+		#iommu-cells = <0>;
+		status = "disabled";
+	};
+
 	qos_gpu: qos at fe128000 {
 		compatible = "rockchip,rk3568-qos", "syscon";
 		reg = <0x0 0xfe128000 0x0 0x20>;
diff --git a/include/dt-bindings/soc/rockchip,vop2.h b/include/dt-bindings/soc/rockchip,vop2.h
new file mode 100644
index 000000000000..0a87bc90564a
--- /dev/null
+++ b/include/dt-bindings/soc/rockchip,vop2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */
+
+#ifndef __DT_BINDINGS_ROCKCHIP_VOP2_H
+#define __DT_BINDINGS_ROCKCHIP_VOP2_H
+
+#define RK3568_VOP2_EP_RGB	0
+#define RK3568_VOP2_EP_HDMI	1
+#define RK3568_VOP2_EP_EDP	2
+#define RK3568_VOP2_EP_MIPI0	3
+#define RK3568_VOP2_EP_LVDS0	4
+#define RK3568_VOP2_EP_MIPI1	5
+#define RK3568_VOP2_EP_LVDS1	6
+
+#endif /* __DT_BINDINGS_ROCKCHIP_VOP2_H */
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:38 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:38 +0100
Subject: [PATCH 16/27] dt-bindings: display: rockchip: dw-hdmi: Add additional
 clock
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-17-s.hauer@pengutronix.de>

The rk3568 HDMI has an additional clock that needs to be enabled for the
HDMI controller to work. The purpose of that clock is not clear. It is
named "hclk" in the downstream driver, so use the same name.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../bindings/display/rockchip/rockchip,dw-hdmi.yaml        | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
index d7cb2b2be60e..7dd753630b46 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,dw-hdmi.yaml
@@ -44,12 +44,13 @@ properties:
     items:
       - {}
       - {}
-      # The next three clocks are all optional, but shall be specified in this
+      # The next four clocks are all optional, but shall be specified in this
       # order when present.
       - description: The HDMI CEC controller main clock
       - description: Power for GRF IO
       - description: External clock for some HDMI PHY (old clock name, deprecated)
       - description: External clock for some HDMI PHY (new name)
+      - description: hclk
 
   clock-names:
     minItems: 2
@@ -61,13 +62,17 @@ properties:
           - grf
           - vpll
           - ref
+          - hclk
       - enum:
           - grf
           - vpll
           - ref
+          - hclk
       - enum:
           - vpll
           - ref
+          - hclk
+      - const: hclk
 
   ddc-i2c-bus:
     $ref: /schemas/types.yaml#/definitions/phandle
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:44 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:44 +0100
Subject: [PATCH 22/27] arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-23-s.hauer@pengutronix.de>

This enabled the VOP2 display controller along with hdmi and the
required port routes which is enough to get a picture out of the
hdmi port of the board.

Changes since v3:
- Fix HDMI connector type

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 184e2aa2416a..9a669240e49a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -7,6 +7,7 @@
 /dts-v1/;
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/soc/rockchip,vop2.h>
 #include "rk3568.dtsi"
 
 / {
@@ -33,6 +34,17 @@ dc_12v: dc-12v {
 		regulator-max-microvolt = <12000000>;
 	};
 
+	hdmi-con {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con_in: endpoint {
+				remote-endpoint = <&hdmi_out_con>;
+			};
+		};
+	};
+
 	vcc3v3_sys: vcc3v3-sys {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_sys";
@@ -106,6 +118,12 @@ &gmac1m1_rgmii_clk
 	status = "okay";
 };
 
+&hdmi {
+	avdd-0v9-supply = <&vdda0v9_image>;
+	avdd-1v8-supply = <&vcca1v8_image>;
+	status = "okay";
+};
+
 &i2c0 {
 	status = "okay";
 
@@ -390,3 +408,33 @@ &sdmmc0 {
 &uart2 {
 	status = "okay";
 };
+
+&vop {
+	assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>;
+	assigned-clock-parents = <&pmucru PLL_HPLL>, <&cru PLL_VPLL>;
+	status = "okay";
+};
+
+&vop_mmu {
+	status = "okay";
+};
+
+&hdmi_in {
+	hdmi_in_vp0: endpoint at 0 {
+		reg = <0>;
+		remote-endpoint = <&vp0_out_hdmi>;
+	};
+};
+
+&hdmi_out {
+	hdmi_out_con: endpoint {
+		remote-endpoint = <&hdmi_con_in>;
+	};
+};
+
+&vp0 {
+	vp0_out_hdmi: endpoint at RK3568_VOP2_EP_HDMI {
+		reg = <RK3568_VOP2_EP_HDMI>;
+		remote-endpoint = <&hdmi_in_vp0>;
+	};
+};
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:46 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:46 +0100
Subject: [PATCH 24/27] clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop*
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-25-s.hauer@pengutronix.de>

The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or
cpll. gpll and cpll also drive many other clocks, so changing the
dclk_vop[012] clocks could change these other clocks as well. Drop
CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can
only adjust the pixel clocks with the divider between the PLL and the
dclk_vop[012] which means the user may have to adjust the PLL clock to a
suitable rate using the assigned-clock-rate device tree property.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 drivers/clk/rockchip/clk-rk3568.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
index 9d889fc46811..7687c62d1fa8 100644
--- a/drivers/clk/rockchip/clk-rk3568.c
+++ b/drivers/clk/rockchip/clk-rk3568.c
@@ -1044,13 +1044,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
 			RK3568_CLKGATE_CON(20), 8, GFLAGS),
 	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
 			RK3568_CLKGATE_CON(20), 9, GFLAGS),
-	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 10, GFLAGS),
-	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
+	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 11, GFLAGS),
-	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
+	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
 			RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
 			RK3568_CLKGATE_CON(20), 12, GFLAGS),
 	GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:41 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:41 +0100
Subject: [PATCH 19/27] arm64: dts: rockchip: rk3399: rename HDMI ref clock to
 'ref'
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-20-s.hauer@pengutronix.de>

The reference clock for the HDMI controller has been renamed to 'ref',
the previous 'vpll' name is only left for compatibility in the driver.
Rename the clock to the new name.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index 080457a68e3c..d0add619b0d2 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1884,7 +1884,7 @@ hdmi: hdmi at ff940000 {
 			 <&cru SCLK_HDMI_CEC>,
 			 <&cru PCLK_VIO_GRF>,
 			 <&cru PLL_VPLL>;
-		clock-names = "iahb", "isfr", "cec", "grf", "vpll";
+		clock-names = "iahb", "isfr", "cec", "grf", "ref";
 		power-domains = <&power RK3399_PD_HDCP>;
 		reg-io-width = <4>;
 		rockchip,grf = <&grf>;
-- 
2.30.2



From s.hauer at pengutronix.de  Wed Jan 26 06:55:40 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Wed, 26 Jan 2022 15:55:40 +0100
Subject: [PATCH 18/27] arm64: dts: rockchip: rk3399: reorder hmdi clocks
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <20220126145549.617165-19-s.hauer@pengutronix.de>

The binding specifies the clock order to "cec", "grf", "vpll". Reorder
the clocks accordingly.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index d3cdf6f42a30..080457a68e3c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1881,10 +1881,10 @@ hdmi: hdmi at ff940000 {
 		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&cru PCLK_HDMI_CTRL>,
 			 <&cru SCLK_HDMI_SFR>,
-			 <&cru PLL_VPLL>,
+			 <&cru SCLK_HDMI_CEC>,
 			 <&cru PCLK_VIO_GRF>,
-			 <&cru SCLK_HDMI_CEC>;
-		clock-names = "iahb", "isfr", "vpll", "grf", "cec";
+			 <&cru PLL_VPLL>;
+		clock-names = "iahb", "isfr", "cec", "grf", "vpll";
 		power-domains = <&power RK3399_PD_HDCP>;
 		reg-io-width = <4>;
 		rockchip,grf = <&grf>;
-- 
2.30.2



From andre.przywara at arm.com  Wed Jan 26 07:02:50 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 15:02:50 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <20220125150057.3936090-2-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
Message-ID: <20220126150250.2dd88556@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:43 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> The ZCR_ELx.LEN field covers bits[3:0] of ZCR_ELx, and bits[8:4] are
> RAZ/WI, likely so that in future these can be used to extend LEN without
> complicating the probing of the maximum available vector length.
> 
> Currently ZCR_EL3_LEN_MASK is defined as 0x1ff, covering both the LEN
> field and the RAZ/WI bits.
> 
> To match the architecture as documented, reduce this down to 0xf, only
> covering the bits currently allocated to the LEN field. We can extend
> this in future if the LEN field is widened.
> 
> As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
> used as a value rather than as a bit mask.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Andre Przywara <andre.przywara at arm.com>
> Cc: Mark Brown <broonie at kernel.org>

Looks good to me:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch64/boot.S            | 2 +-
>  arch/aarch64/include/asm/cpu.h | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 72c6b79..ee9ddaa 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -123,7 +123,7 @@ ASM_FUNC(_start)
>  	msr	cptr_el3, x0
>  	isb
>  
> -	mov	x0, #ZCR_EL3_LEN_MASK		// SVE: Enable full vector len
> +	mov	x0, #ZCR_EL3_LEN_MAX		// SVE: Enable full vector len
>  	msr	ZCR_EL3, x0			// for EL2.
>  
>  1:
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 63eb1c3..e3269b8 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -30,7 +30,7 @@
>  #define CPTR_EL3_EZ		(1 << 8)
>  
>  #define ZCR_EL3			s3_6_c1_c2_0
> -#define ZCR_EL3_LEN_MASK	0x1ff
> +#define ZCR_EL3_LEN_MAX		0xf
>  
>  #define SCTLR_EL1_CP15BEN	(1 << 5)
>  #define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)



From andre.przywara at arm.com  Wed Jan 26 07:03:12 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 15:03:12 +0000
Subject: [bootwrapper PATCH v3 04/15] Add bit-field macros
In-Reply-To: <20220125150057.3936090-5-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-5-mark.rutland@arm.com>
Message-ID: <20220126150312.56b6f536@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:46 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> Arm architectural documentation typically defines bit-fields as
> `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> helpful if we could define fields in the same way.
> 
> Add helpers so that we can do so, along with helper to extract/insert
> bit-field values.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

I extracted the code and checked the examples, see below.

> ---
>  include/bits.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 66 insertions(+)
>  create mode 100644 include/bits.h
> 
> diff --git a/include/bits.h b/include/bits.h
> new file mode 100644
> index 0000000..5f0ad8f
> --- /dev/null
> +++ b/include/bits.h
> @@ -0,0 +1,66 @@
> +/*
> + * include/bits.h - helpers for bit-field definitions.
> + *
> + * Copyright (C) 2021 ARM Limited. All rights reserved.
> + *
> + * Use of this source code is governed by a BSD-style license that can be
> + * found in the LICENSE.txt file.
> + */
> +#ifndef __BITS_H
> +#define __BITS_H
> +
> +#ifdef __ASSEMBLY__
> +#define UL(x)	x
> +#define ULL(x)	x
> +#else
> +#define UL(x)	x##UL
> +#define ULL(x)	x##ULL
> +#endif
> +
> +/*
> + * Define a contiguous mask of bits with `msb` as the most significant bit and
> + * `lsb` as the least significant bit. The `msb` value must be greater than or
> + * equal to `lsb`.
> + *
> + * For example:
> + * - BITS(63, 63) is 0x8000000000000000
> + * - BITS(63, 0)  is 0xFFFFFFFFFFFFFFFF
> + * - BITS(0, 0)   is 0x0000000000000001
> + * - BITS(49, 17) is 0x0001FFFFFFFE0000

This should be 0x0003fffffffe0000, in real life and with the below
implementation. So just a comment fix.

The rest of the examples checked out, so with that fixed:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre


> + */
> +#define BITS(msb, lsb) \
> +	((~ULL(0) >> (63 - msb)) & (~ULL(0) << lsb))
> +
> +/*
> + * Define a mask of a single set bit `b`.
> + *
> + * For example:
> + * - BIT(63) is 0x8000000000000000
> + * - BIT(0)  is 0x0000000000000001
> + * - BIT(32) is 0x0000000100000000
> + */
> +#define BIT(b)	BITS(b, b)
> +
> +/*
> + * Find the least significant set bit in the contiguous set of bits in `mask`.
> + *
> + * For example:
> + * - BITS_LSB(0x0000000000000001) is 0
> + * - BITS_LSB(0x000000000000ff00) is 8
> + * - BITS_LSB(0x8000000000000000) is 63
> + */
> +#define BITS_LSB(mask)	(__builtin_ffsll(mask) - 1)
> +
> +/*
> + * Extract a bit-field out of `val` described by the contiguous set of bits in
> + * `mask`.
> + *
> + * For example:
> + * - BITS_EXTRACT(0xABCD, BITS(15, 12)) is 0xA
> + * - BITS_EXTRACT(0xABCD, BITS(11, 8))  is 0xB
> + * - BITS_EXTRACT(0xABCD, BIT(7))       is 0x1
> + */
> +#define BITS_EXTRACT(val, mask) \
> +	(((val) & (mask)) >> BITS_LSB(mask))
> +
> +#endif



From andre.przywara at arm.com  Wed Jan 26 07:03:38 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 15:03:38 +0000
Subject: [bootwrapper PATCH v3 02/15] aarch64: correct SCTLR_EL1_KERNEL
 for AA32 kernels
In-Reply-To: <20220125150057.3936090-3-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-3-mark.rutland@arm.com>
Message-ID: <20220126150338.5af163e5@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:44 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> Bits [31:0] of the AArch64 SCTLR_EL1 register are architecturally mapped
> to bits [31:0] of the AArch32 SCTLR register. This means that any
> individual bit always has the same value across the two registers.
> 
> Across the two registers, the same bit may have distinct meanings,
> distinct RESx behaviour, and distinct reset behaviour. For example,
> SCTLR_EL1[28] is nTLSMD, which we wich to initialize to 0b1, whereas
> SCTLR[28] is TRE, which we wish to initialize to 0b0.
> 
> To avoid setting bits which we did not intend to, and in preparation for
> configuring more AArch64 RES1 bits, this patch decouples the
> SCTLR_EL1_KERNEL value used for AArch32 kernels from the SCTLR_EL1_RES1
> definitions such that is does not inherit AArch64 SCTLR_EL1 bits which
> would be problematic in the AArch32 SCTLR. For now we open-code a copy
> of the bits defined in arch/aarch64/include/asm/cpu.h.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> Cc: Andre Przywara <andre.przywara at arm.com>
> ---
>  arch/aarch64/include/asm/cpu.h | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index e3269b8..49d3f86 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -36,8 +36,15 @@
>  #define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
>  
>  #ifdef KERNEL_32
> -/* 32-bit kernel decompressor uses CP15 barriers */
> -#define SCTLR_EL1_KERNEL	(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
> +/*
> + * When booting a 32-bit kernel, EL1 uses AArch32 and registers which are
> + * architecturally mapped must be configured with the AArch32 layout.
> + *
> + * We copy the AArch32 definition of SCTLR_KERNEL here.
> + *
> + * TODO: restructure the headers to share a single definition.
> + */
> +#define SCTLR_EL1_KERNEL	(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)

Is the verbatim copying of the value, including the redundancy, intended?
Maybe that meant 3 << 3, as bits[4:3] are documented as "Reserved,
RAO/SBOP" in the ARMv7 ARM?
It's fine with me either way, since it copies the aarch32 value, just
wanted to check:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

>  #define SPSR_KERNEL		(SPSR_A | SPSR_I | SPSR_F | SPSR_HYP)
>  #else
>  #define SCTLR_EL1_KERNEL	SCTLR_EL1_RES1



From maxime at cerno.tech  Wed Jan 26 07:03:38 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Wed, 26 Jan 2022 16:03:38 +0100
Subject: [RFC PATCH v2 4/7] media: bcm2835-unicam: Add support for for
 CCP2/CSI2 camera interface
In-Reply-To: <0212af6d-a5de-05bb-161b-4271692dee59@ideasonboard.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-5-jeanmichel.hautbois@ideasonboard.com>
 <YeySvkxEfpzTj+pC@pendragon.ideasonboard.com>
 <0212af6d-a5de-05bb-161b-4271692dee59@ideasonboard.com>
Message-ID: <20220126150338.j6bep2v5wmi3xnnq@houat>

Hi,

On Wed, Jan 26, 2022 at 03:21:40PM +0100, Jean-Michel Hautbois wrote:
> On 23/01/2022 00:26, Laurent Pinchart wrote:
> > > +struct unicam_device {
> > > +	struct kref kref;
> > > +
> > > +	/* V4l2 specific parameters */
> > > +	struct v4l2_async_subdev asd;
> > > +
> > > +	/* peripheral base address */
> > > +	void __iomem *base;
> > > +	/* clock gating base address */
> > > +	void __iomem *clk_gate_base;
> > > +	/* lp clock handle */
> > > +	struct clk *clock;
> > > +	/* vpu clock handle */
> > > +	struct clk *vpu_clock;
> > > +	/* vpu clock request */
> > > +	struct clk_request *vpu_req;
> > 
> > Not used (and that may be a problem).
> 
> In the original linux-rpi tree, there is this portion of code in
> unicam_start_streaming:
> 
> dev->vpu_req = clk_request_start(dev->vpu_clock, MIN_VPU_CLOCK_RATE);
> if (!dev->vpu_req) {
> 	unicam_err(dev, "failed to set up VPU clock\n");
> 	goto error_pipeline;
> }
> 
> ret = clk_prepare_enable(dev->vpu_clock);
> if (ret) {
> 	unicam_err(dev, "Failed to enable VPU clock: %d\n", ret);
> 	goto error_pipeline;
> }
> 
> And this is used as this because it depends on the non-merged series "clk:
> [PATCH v2 0/3] clk: Implement a clock request API" [1]
> 
> [1]: https://lore.kernel.org/all/20210914093515.260031-1-maxime at cerno.tech/
> 
> That's why I modified the code and called:
> clk_set_min_rate(dev->vpu_clock, UNICAM_MIN_VPU_CLOCK_RATE);

I assume this would depend on the framerate and resolution though?

> Dave, is it ok or do we need absolutely the clock request API ?

The main issue is that clk_set_min_rate will never scale the clock back
if you (or the HVS) don't have those constraints anymore. So you
eventually make the clock run at the maximum you'll ever need all the
time (which would be around 500MHz in our case).

The clock request API was an attempt at making the clock scale back to
its minimum when we no longer needed it. The current discussion points
towards changing the behavior of clk_set_min_rate:

https://lore.kernel.org/linux-clk/20220125141549.747889-1-maxime at cerno.tech/

So it looks like we won't need the clk_request API after all.

Maxime
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/6cd8798b/attachment.sig>

From andre.przywara at arm.com  Wed Jan 26 07:03:49 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 15:03:49 +0000
Subject: [bootwrapper PATCH v3 03/15] Document entry requirements
In-Reply-To: <20220125150057.3936090-4-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-4-mark.rutland@arm.com>
Message-ID: <20220126150349.68186b6b@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:45 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> Currently the boot-wrapper only supports some combinations of exception
> levels, with other combinations not being supported.
> 
> While we generally expect the boot-wrapper to be entered at the highest
> implemented exception level, the AArch32 boot-wrapper has a comment
> implying it supports being entered with something else owning EL3. As
> this would require such EL3 firmware to always be in sync with the
> boot-wrapper's requirements, which change over time, we don't actually
> support such a configuration.
> 
> Some CPU state (such as CNTFRQ/CNTFRQ_EL0) needs to be initialized at
> the highest implemented exception level, but today the boot-wrapper only
> does so when entered at EL3 / Secure-PL1. Thus, today the only
> completely supported configurations are EL3 / Secure-PL1, and entering
> in other configurations is not entirely supported.
> 
> The aarch64 `jump_kernel` function always writes to SCTLR_EL2, which is
> UNDEFINED at EL1. Hence, the aarch64 boot-wrapper does not support being
> entered at EL1.
> 
> The aarch32 code assumes that any non-hyp mode is Secure PL1, and
> attempt to switch to monitor mode. If entered on a system without the
> security extensions, where the highest privileged mode is Non-secure
> PL1, this will not work. Hence the aarch32 boot-wrapper does not support
> being entered at Non-secure PL1.
> 
> Actually supporting all of these configurations requires restructuring
> much of the boot-wrapper. For now, document the supported configurations
> in each architecture's boot.S, and remove the misleading comment from
> arch/aarch32/boot.S. Subsequent patches will improve the support and add
> support for additional configurations.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

I like that idea of documenting what we can sanely support, instead of
trying to support everyone and their dog, when this won't work in
practice anyway or cannot be well tested.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks!
Andre

> ---
>  arch/aarch32/boot.S | 14 ++++++++++++++
>  arch/aarch32/psci.S |  5 -----
>  arch/aarch64/boot.S | 13 +++++++++++++
>  3 files changed, 27 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/aarch32/boot.S b/arch/aarch32/boot.S
> index 4add338..00c432d 100644
> --- a/arch/aarch32/boot.S
> +++ b/arch/aarch32/boot.S
> @@ -16,6 +16,20 @@
>  	.arch_extension virt
>  
>  	.section .init
> +
> +	/*
> +	 * The boot-wrapper must be entered from the reset vector at the
> +	 * highest implemented exception level. The boot-wrapper only supports
> +	 * being entered in the following modes:
> +	 *
> +	 * - PL1 / EL3 (Secure) Supervisor mode
> +	 *   Entering in this mode is strongly recommended.
> +	 *   PL2 must be implemented.
> +	 *
> +	 * - PL2 / EL2 (Non-secure) Hypervisor mode
> +	 *   Entering in this mode is partially supported.
> +	 *   PSCI is not supported when entered in this mode.
> +	 */
>  ASM_FUNC(_start)
>  	/* Stack initialisation */
>  	cpuid	r0, r1
> diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
> index dc7aeb7..e0d2972 100644
> --- a/arch/aarch32/psci.S
> +++ b/arch/aarch32/psci.S
> @@ -44,11 +44,6 @@ ASM_FUNC(start_el3)
>  	/* pass through */
>  
>  ASM_FUNC(start_no_el3)
> -	/*
> -	 * For no-el3, we assume that firmware launched the boot-wrapper in
> -	 * non-secure EL2 or EL1. We assume it has its own PSCI implementation
> -	 * sitting at EL3, and that this path is only taken by primary CPU.
> -	 */
>  	cpuid	r0, r1
>  	blx	find_logical_id
>  	b	psci_first_spin
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index ee9ddaa..d682ba5 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -12,6 +12,19 @@
>  
>  	.section .init
>  
> +	/*
> +	 * The boot-wrapper must be entered from the reset vector at the
> +	 * highest implemented exception level. The boot-wrapper only supports
> +	 * being entered at the following exception levels:
> +	 *
> +	 * - EL3 (Secure)
> +	 *   Entering at EL3 is strongly recommended.
> +	 *   EL2 must be implemented.
> +	 *
> +	 * - EL2 (Non-secure)
> +	 *   Entering at EL2 is partially supported.
> +	 *   PSCI is not supported when entered in this exception level.
> +	 */
>  ASM_FUNC(_start)
>  	cpuid	x0, x1
>  	bl	find_logical_id



From frank-w at public-files.de  Wed Jan 26 07:04:36 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 26 Jan 2022 16:04:36 +0100
Subject: Aw: [PATCH 01/27] drm/encoder: Add of_graph port to struct drm_encoder
In-Reply-To: <20220126145549.617165-2-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-2-s.hauer@pengutronix.de>
Message-ID: <trinity-e0e26df4-dbdf-4a86-be55-c8cd09fdf261-1643209476020@3c-app-gmx-bap59>

Hi

> Gesendet: Mittwoch, 26. Januar 2022 um 15:55 Uhr
> Von: "Sascha Hauer" <s.hauer at pengutronix.de>
> Betreff: [PATCH 01/27] drm/encoder: Add of_graph port to struct drm_encoder

Please use "git format-patch -vX ..." when creating your patches to make sure the version is set in every patch and not only the coverletter. That makes it easier to find Patch from specific version and shows version also in Patchwork where the coverletter is hidden

regards Frank


From Sergiy_Kibrik at epam.com  Wed Jan 26 07:09:30 2022
From: Sergiy_Kibrik at epam.com (Sergiy Kibrik)
Date: Wed, 26 Jan 2022 15:09:30 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu device
In-Reply-To: <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
 <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
 <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
Message-ID: <PAXPR03MB81144A63E18CAF10E785E2A7F0209@PAXPR03MB8114.eurprd03.prod.outlook.com>

Hi Robin,

> 
> This could break Linux guests, since depending on the deferred probe
> timeout setting it could lead to drivers never probing because the "IOMMU"
> never becomes available.
> 

I've noticed no deferred probe timeouts when booting with this patch. Could you please explain more on how this would break guests?
Thank you!

 -- Sergiy

From broonie at kernel.org  Wed Jan 26 07:10:40 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:40 +0000
Subject: [PATCH v9 00/40] arm64/sme: Initial support for the Scalable Matrix
 Extension
Message-ID: <20220126151120.3811248-1-broonie@kernel.org>

This series provides initial support for the ARMv9 Scalable Matrix
Extension (SME).  SME takes the approach used for vectors in SVE and
extends this to provide architectural support for matrix operations.  A
more detailed overview can be found in [1].

For the kernel SME can be thought of as a series of features which are
intended to be used together by applications but operate mostly
orthogonally:

 - The ZA matrix register.
 - Streaming mode, in which ZA can be accessed and a subset of SVE
   features are available.
 - A second vector length, used for streaming mode SVE and ZA and
   controlled using a similar interface to that for SVE.
 - TPIDR2, a new userspace controllable system register intended for use
   by the C library for storing context related to the ZA ABI.

A substantial part of the series is dedicated to refactoring the
existing SVE support so that we don't need to duplicate code for
handling vector lengths and the SVE registers, this involves creating an
array of vector types and making the users take the vector type as a
parameter.  I'm not 100% happy with this but wasn't able to come up with
anything better, duplicating code definitely felt like a bad idea so
this felt like the least bad thing.  If this approach makes sense to
people it might make sense to split this off into a separate series
and/or merge it while the rest is pending review to try to make things a
little more digestable, the series is very large so it'd probably make
things easier to digest if some of the preparatory refactoring could be
merged before the rest is ready.

One feature of the architecture of particular note is that switching
to and from streaming mode may change the size of and invalidate the
contents of the SVE registers, and when in streaming mode the FFR is not
accessible.  This complicates aspects of the ABI like signal handling
and ptrace.

This initial implementation is mainly intended to get the ABI in place,
there are several areas which will be worked on going forwards - some of
these will be blockers, others could be handled in followup serieses:

 - SME is currently not supported for KVM guests, this will be done as a
   followup series.  A host system can use SME and run KVM guests but
   SME is not available in the guests.
 - The KVM host support is done in a very simplistic way, were anyone to
   attempt to use it in production there would be performance impacts on
   hosts with SME support. As part of this we also add enumeration of
   fine grained traps.
 - There is not currently ptrace or signal support TPIDR2, this will be
   done as a followup series.
 - No support is currently provided for scheduler control of SME or SME
   applications, given the size of the SME register state the context
   switch overhead may be noticable so this may be needed especially for
   real time applications.  Similar concerns already exist for larger
   SVE vector lengths but are amplified for SME, particularly as the
   vector length increases.
 - There has been no work on optimising the performance of anything the
   kernel does.

It is not expected that any systems will be encountered that support SME
but not SVE, SME is an ARMv9 feature and SVE is mandatory for ARMv9.
The code attempts to handle any such systems that are encountered but
this hasn't been tested extensively.

v9:
 - Remove defensive programming around IS_ENABLED() and FGT in KVM code.
 - Fix naming of TPIDR2 FGT register bit.
 - Add patches making handling of floating point register bits more
   consistent (also sent as separate series).
 - Drop now unused enumeration of fine grained traps.
v8:
 - Rebase onto v5.17-rc1.
 - Support interoperation with KVM, SME is disabled for KVM guests with
   minimal handling for cleaning up SME state when entering and leaving
   the guest.
 - Document and implement that signal handlers are invoked with ZA and
   streaming mode disabled.
 - Use the RDSVL instruction introduced in EAC2 of the architecture to
   obtain the streaming mode vector length during enumeration, ZA state
   loading/saving and in test programs.
 - Store a pointer to SVCR in fpsimd_last_state and use it in fpsimd_save()
   for interoperation with KVM.
 - Add a test case sme_trap_no_sm checking that we generate a SIGILL
   when using an instruction that requires streaming mode without
   enabling it.
 - Add basic ZA context form validation to testcases helper library.
 - Move signal tests over to validating streaming VL from ZA information.
 - Pulled in patch removing ARRAY_SIZE() so that kselftest builds
   cleanly and to avoid trivial conflicts.
v7:
 - Rebase onto v5.16-rc3.
 - Reduce indentation when supporting custom triggers for signal tests
   as suggested by Catalin.
 - Change to specifying a width for all CPU features rather than adding
   single bit specific infrastructure.
 - Don't require zeroing of non-shared SVE state during syscalls.
v6:
 - Rebase onto v5.16-rc1.
 - Return to disabling TIF_SVE on kernel entry even if we have SME
   state, this avoids the need for KVM to handle the case where TIF_SVE
   is set on guest entry.
 - Add syscall-abi.h to SME updates to syscall-abi, mistakenly omitted
   from commit.
v5:
 - Rebase onto currently merged SVE and kselftest patches.
 - Add support for the FA64 option, introduced in the recently published
   EAC1 update to the specification.
 - Pull in test program for the syscall ABI previously sent separately
   with some revisions and add coverage for the SME ABI.
 - Fix checking for options with 1 bit fields in ID_AA64SMFR0_EL1.
 - Minor fixes and clarifications to the ABI documentation.
v4:
 - Rebase onto merged patches.
 - Remove an uneeded NULL check in vec_proc_do_default_vl().
 - Include patch to factor out utility routines in kselftests written in
   assembler.
 - Specify -ffreestanding when building TPIDR2 test.
v3:
 - Skip FFR rather than predicate registers in sve_flush_live().
 - Don't assume a bool is all zeros in sve_flush_live() as per AAPCS.
 - Don't redundantly specify a zero index when clearing FFR.
v2:
 - Fix several issues with !SME and !SVE configurations.
 - Preserve TPIDR2 when creating a new thread/process unless
   CLONE_SETTLS is set.
 - Report traps due to using features in an invalid mode as SIGILL.
 - Spell out streaming mode behaviour in SVE ABI documentation more
   directly.
 - Document TPIDR2 in the ABI document.
 - Use SMSTART and SMSTOP rather than read/modify/write sequences.
 - Rework logic for exiting streaming mode on syscall.
 - Don't needlessly initialise SVCR on access trap.
 - Always restore SME VL for userspace if SME traps are disabled.
 - Only yield to encourage preemption every 128 iterations in za-test,
   otherwise do a getpid(), and validate SVCR after syscall.
 - Leave streaming mode disabled except when reading the vector length
   in za-test, and disable ZA after detecting a mismatch.
 - Add SME support to vlset.
 - Clarifications and typo fixes in comments.
 - Move sme_alloc() forward declaration back a patch.

[1] https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/scalable-matrix-extension-armv9-a-architecture

Mark Brown (40):
  arm64: Define CPACR_EL1_FPEN similarly to other floating point
    controls
  arm64: Always use individual bits in CPACR floating point enables
  arm64: cpufeature: Always specify and use a field width for
    capabilities
  kselftest/arm64: Remove local ARRAY_SIZE() definitions
  arm64/sme: Provide ABI documentation for SME
  arm64/sme: System register and exception syndrome definitions
  arm64/sme: Manually encode SME instructions
  arm64/sme: Early CPU setup for SME
  arm64/sme: Basic enumeration support
  arm64/sme: Identify supported SME vector lengths at boot
  arm64/sme: Implement sysctl to set the default vector length
  arm64/sme: Implement vector length configuration prctl()s
  arm64/sme: Implement support for TPIDR2
  arm64/sme: Implement SVCR context switching
  arm64/sme: Implement streaming SVE context switching
  arm64/sme: Implement ZA context switching
  arm64/sme: Implement traps and syscall handling for SME
  arm64/sme: Disable ZA and streaming mode when handling signals
  arm64/sme: Implement streaming SVE signal handling
  arm64/sme: Implement ZA signal handling
  arm64/sme: Implement ptrace support for streaming mode SVE registers
  arm64/sme: Add ptrace support for ZA
  arm64/sme: Disable streaming mode and ZA when flushing CPU state
  arm64/sme: Save and restore streaming mode over EFI runtime calls
  KVM: arm64: Hide SME system registers from guests
  KVM: arm64: Trap SME usage in guest
  KVM: arm64: Handle SME host state when running guests
  arm64/sme: Provide Kconfig for SME
  kselftest/arm64: sme: Add streaming SME support to vlset
  kselftest/arm64: Add tests for TPIDR2
  kselftest/arm64: Extend vector configuration API tests to cover SME
  kselftest/arm64: sme: Provide streaming mode SVE stress test
  kselftest/arm64: signal: Allow tests to be incompatible with features
  kselftest/arm64: signal: Handle ZA signal context in core code
  kselftest/arm64: Add stress test for SME ZA context switching
  kselftest/arm64: signal: Add SME signal handling tests
  kselftest/arm64: Add streaming SVE to SVE ptrace tests
  kselftest/arm64: Add coverage for the ZA ptrace interface
  kselftest/arm64: Add SME support to syscall ABI test
  squqsh traps

 Documentation/arm64/elf_hwcaps.rst            |  33 +
 Documentation/arm64/index.rst                 |   1 +
 Documentation/arm64/sme.rst                   | 432 +++++++++++++
 Documentation/arm64/sve.rst                   |  70 ++-
 arch/arm64/Kconfig                            |  11 +
 arch/arm64/include/asm/cpu.h                  |   4 +
 arch/arm64/include/asm/cpufeature.h           |  25 +
 arch/arm64/include/asm/el2_setup.h            |  64 +-
 arch/arm64/include/asm/esr.h                  |  13 +-
 arch/arm64/include/asm/exception.h            |   1 +
 arch/arm64/include/asm/fpsimd.h               | 110 +++-
 arch/arm64/include/asm/fpsimdmacros.h         |  86 +++
 arch/arm64/include/asm/hwcap.h                |   8 +
 arch/arm64/include/asm/kvm_arm.h              |   5 +-
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/processor.h            |  18 +-
 arch/arm64/include/asm/sysreg.h               |  67 +-
 arch/arm64/include/asm/thread_info.h          |   2 +
 arch/arm64/include/uapi/asm/hwcap.h           |   8 +
 arch/arm64/include/uapi/asm/ptrace.h          |  69 ++-
 arch/arm64/include/uapi/asm/sigcontext.h      |  55 +-
 arch/arm64/kernel/cpufeature.c                | 273 ++++++--
 arch/arm64/kernel/cpuinfo.c                   |  13 +
 arch/arm64/kernel/entry-common.c              |  11 +
 arch/arm64/kernel/entry-fpsimd.S              |  36 ++
 arch/arm64/kernel/fpsimd.c                    | 585 ++++++++++++++++--
 arch/arm64/kernel/process.c                   |  28 +-
 arch/arm64/kernel/ptrace.c                    | 356 +++++++++--
 arch/arm64/kernel/signal.c                    | 194 +++++-
 arch/arm64/kernel/syscall.c                   |  34 +-
 arch/arm64/kernel/traps.c                     |   1 +
 arch/arm64/kvm/fpsimd.c                       |  43 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |   4 +-
 arch/arm64/kvm/hyp/nvhe/switch.c              |  30 +
 arch/arm64/kvm/hyp/vhe/switch.c               |  15 +-
 arch/arm64/kvm/sys_regs.c                     |   9 +-
 arch/arm64/tools/cpucaps                      |   2 +
 include/uapi/linux/elf.h                      |   2 +
 include/uapi/linux/prctl.h                    |   9 +
 kernel/sys.c                                  |  12 +
 tools/testing/selftests/arm64/abi/.gitignore  |   1 +
 tools/testing/selftests/arm64/abi/Makefile    |   9 +-
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 ++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 205 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 +
 tools/testing/selftests/arm64/abi/tpidr2.c    | 298 +++++++++
 tools/testing/selftests/arm64/fp/.gitignore   |   4 +
 tools/testing/selftests/arm64/fp/Makefile     |  12 +-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   |  14 +
 tools/testing/selftests/arm64/fp/rdvl.S       |   8 +
 tools/testing/selftests/arm64/fp/rdvl.h       |   1 +
 tools/testing/selftests/arm64/fp/ssve-stress  |  59 ++
 tools/testing/selftests/arm64/fp/sve-ptrace.c |  13 +-
 tools/testing/selftests/arm64/fp/sve-test.S   |  30 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c |  10 +
 tools/testing/selftests/arm64/fp/vlset.c      |  10 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c  | 354 +++++++++++
 tools/testing/selftests/arm64/fp/za-stress    |  59 ++
 tools/testing/selftests/arm64/fp/za-test.S    | 426 +++++++++++++
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   5 +
 .../arm64/signal/test_signals_utils.c         |  40 +-
 .../arm64/signal/test_signals_utils.h         |   2 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 ++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 ++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++
 .../arm64/signal/testcases/testcases.c        |  36 ++
 .../arm64/signal/testcases/testcases.h        |   3 +-
 71 files changed, 4585 insertions(+), 251 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:41 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:41 +0000
Subject: [PATCH v9 01/40] arm64: Define CPACR_EL1_FPEN similarly to other
 floating point controls
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-2-broonie@kernel.org>

The base floating point, SVE and SME all have enable controls for EL0 and
EL1 in CPACR_EL1 which have a similar layout and function. Currently the
basic floating point enable FPEN is defined differently to the SVE control,
specified as a single define in kvm_arm.h rather than in sysreg.h. Move the
define to sysreg.h and provide separate EL0 and EL1 control bits so code
managing the different floating point enables can look consistent.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h | 1 -
 arch/arm64/include/asm/sysreg.h  | 4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..eec790842fe2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -355,7 +355,6 @@
 	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
 
-#define CPACR_EL1_FPEN		(3 << 20)
 #define CPACR_EL1_TTA		(1 << 28)
 #define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..1da4c43d597d 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1097,6 +1097,10 @@
 #define ZCR_ELx_LEN_SIZE	9
 #define ZCR_ELx_LEN_MASK	0x1ff
 
+#define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
+#define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
+#define CPACR_EL1_FPEN		(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN)
+
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 #define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:42 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:42 +0000
Subject: [PATCH v9 02/40] arm64: Always use individual bits in CPACR floating
 point enables
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-3-broonie@kernel.org>

CPACR_EL1 has several bitfields for controlling traps for floating point
features to EL1, each of which has a separate bits for EL0 and EL1. Marc
Zyngier noted that we are not consistent in our use of defines to
manipulate these, sometimes using a define covering the whole field and
sometimes using defines for the individual bits. Make this consistent by
expanding the whole field defines where they are used (currently only in
the KVM code) and deleting them so that no further uses can be
introduced.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h        | 3 ++-
 arch/arm64/include/asm/sysreg.h         | 2 --
 arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 6 +++---
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index eec790842fe2..1767ded83888 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -356,6 +356,7 @@
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
 
 #define CPACR_EL1_TTA		(1 << 28)
-#define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
+#define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |\
+				 CPACR_EL1_ZEN_EL1EN)
 
 #endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 1da4c43d597d..e66dd9ebc337 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1099,11 +1099,9 @@
 
 #define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
 #define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_FPEN		(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN)
 
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
 
 /* TCR EL1 Bit Definitions */
 #define SYS_TCR_EL1_TCMA1	(BIT(58))
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..4689b0fe7f4d 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -174,9 +174,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
 	/* Valid trap.  Switch the context: */
 	if (has_vhe()) {
-		reg = CPACR_EL1_FPEN;
+		reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
 		if (sve_guest)
-			reg |= CPACR_EL1_ZEN;
+			reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
 
 		sysreg_clear_set(cpacr_el1, 0, reg);
 	} else {
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 11d053fdd604..619353b06e38 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,7 +38,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
-	val &= ~CPACR_EL1_ZEN;
+	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
 
 	/*
 	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -53,9 +53,9 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	if (update_fp_enabled(vcpu)) {
 		if (vcpu_has_sve(vcpu))
-			val |= CPACR_EL1_ZEN;
+			val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
 	} else {
-		val &= ~CPACR_EL1_FPEN;
+		val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
 		__activate_traps_fpsimd32(vcpu);
 	}
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:43 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:43 +0000
Subject: [PATCH v9 03/40] arm64: cpufeature: Always specify and use a field
 width for capabilities
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-4-broonie@kernel.org>

Since all the fields in the main ID registers are 4 bits wide we have up
until now not bothered specifying the width in the code. Since we now
wish to use this mechanism to enumerate features from the floating point
feature registers which do not follow this pattern add a width to the
table.  This means updating all the existing table entries but makes it
less likely that we run into issues in future due to implicitly assuming
a 4 bit width.

Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/cpufeature.h |   1 +
 arch/arm64/kernel/cpufeature.c      | 167 +++++++++++++++++-----------
 2 files changed, 102 insertions(+), 66 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..2728abd9cae4 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
 		struct {	/* Feature register checking */
 			u32 sys_reg;
 			u8 field_pos;
+			u8 field_width;
 			u8 min_field_value;
 			u8 hwcap_type;
 			bool sign;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..d9f09e40aaf6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1307,7 +1307,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
 {
-	int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
+	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+						    entry->field_width,
+						    entry->sign);
 
 	return val >= entry->min_field_value;
 }
@@ -1952,6 +1954,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR0_EL1,
 		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -1963,6 +1966,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_pan,
@@ -1976,6 +1980,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 3,
 	},
@@ -1988,6 +1993,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 2,
 	},
@@ -2012,6 +2018,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 #ifdef CONFIG_KVM
@@ -2023,6 +2030,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL1_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 	{
@@ -2043,6 +2051,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		 */
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_CSV3_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = unmap_kernel_at_el0,
 		.cpu_enable = kpti_install_ng_mappings,
@@ -2062,6 +2071,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2072,6 +2082,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 	},
 #endif
@@ -2083,6 +2094,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_SVE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_SVE,
 		.matches = has_cpuid_feature,
 		.cpu_enable = sve_kernel_enable,
@@ -2097,6 +2109,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
 		.cpu_enable = cpu_clear_disr,
 	},
@@ -2115,6 +2128,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_AMU_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_AMU,
 		.cpu_enable = cpu_amu_enable,
 	},
@@ -2139,6 +2153,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_FWB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 		.cpu_enable = cpu_has_fwb,
@@ -2150,6 +2165,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_TTL_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 	},
@@ -2160,6 +2176,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_TLB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64ISAR0_TLB_RANGE,
 	},
@@ -2178,6 +2195,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 		.matches = has_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
@@ -2190,6 +2208,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_CRC32_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2199,6 +2218,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_SSBS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
 	},
@@ -2211,6 +2231,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_CNP_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_cnp,
 	},
@@ -2222,6 +2243,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_SB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2233,6 +2255,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_APA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2243,6 +2266,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_API_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_API_IMP_DEF,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2258,6 +2282,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED,
 		.matches = has_cpuid_feature,
 	},
@@ -2268,6 +2293,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPI_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPI_IMP_DEF,
 		.matches = has_cpuid_feature,
 	},
@@ -2288,6 +2314,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = can_use_gic_priorities,
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_GIC_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2299,6 +2326,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
+		.field_width = 4,
 		.field_pos = ID_AA64MMFR2_E0PD_SHIFT,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
@@ -2313,6 +2341,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2330,6 +2359,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpu_enable = bti_enable,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_BT_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_BT_BTI,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2342,6 +2372,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE,
 		.sign = FTR_UNSIGNED,
 		.cpu_enable = cpu_enable_mte,
@@ -2353,6 +2384,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE_ASYMM,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2364,16 +2396,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+		.field_width = 4,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
 	{},
 };
 
-#define HWCAP_CPUID_MATCH(reg, field, s, min_value)				\
+#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value)			\
 		.matches = has_cpuid_feature,					\
 		.sys_reg = reg,							\
 		.field_pos = field,						\
+		.field_width = width,						\
 		.sign = s,							\
 		.min_field_value = min_value,
 
@@ -2383,10 +2417,10 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.hwcap_type = cap_type,						\
 		.hwcap = cap,							\
 
-#define HWCAP_CAP(reg, field, s, min_value, cap_type, cap)			\
+#define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap)		\
 	{									\
 		__HWCAP_CAP(#cap, cap_type, cap)				\
-		HWCAP_CPUID_MATCH(reg, field, s, min_value)			\
+		HWCAP_CPUID_MATCH(reg, field, width, s, min_value) 		\
 	}
 
 #define HWCAP_MULTI_CAP(list, cap_type, cap)					\
@@ -2406,11 +2440,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
+				  4, FTR_UNSIGNED,
+				  ID_AA64ISAR1_APA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
 	},
 	{},
 };
@@ -2418,77 +2453,77 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
 	},
 	{},
 };
 #endif
 
 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
-	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
 #endif
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
 #endif
 #ifdef CONFIG_ARM64_MTE
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
 #endif /* CONFIG_ARM64_MTE */
-	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
-	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
-	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
+	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
+	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
 	{},
 };
 
@@ -2517,15 +2552,15 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope)
 static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
 #ifdef CONFIG_COMPAT
 	HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON),
-	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
+	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
 	/* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
 #endif
 	{},
 };
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:44 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:44 +0000
Subject: [PATCH v9 04/40] kselftest/arm64: Remove local ARRAY_SIZE()
 definitions
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-5-broonie@kernel.org>

An ARRAY_SIZE() has been added to kselftest.h so remove the local versions
in some of the arm64 selftests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/syscall-abi.c | 1 -
 tools/testing/selftests/arm64/fp/sve-ptrace.c   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index d8eeeafb50dc..1e13b7523918 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,7 +18,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
 extern void do_syscall(int sve_vl);
diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index af798b9d232c..90ba1d6a6781 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -21,8 +21,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
 #ifndef NT_ARM_SVE
 #define NT_ARM_SVE 0x405
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:45 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:45 +0000
Subject: [PATCH v9 05/40] arm64/sme: Provide ABI documentation for SME
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-6-broonie@kernel.org>

Provide ABI documentation for SME similar to that for SVE. Due to the very
large overlap around streaming SVE mode in both implementation and
interfaces documentation for streaming mode SVE is added to the SVE
document rather than the SME one.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/index.rst |   1 +
 Documentation/arm64/sme.rst   | 432 ++++++++++++++++++++++++++++++++++
 Documentation/arm64/sve.rst   |  70 +++++-
 3 files changed, 493 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst

diff --git a/Documentation/arm64/index.rst b/Documentation/arm64/index.rst
index 4f840bac083e..ae21f8118830 100644
--- a/Documentation/arm64/index.rst
+++ b/Documentation/arm64/index.rst
@@ -21,6 +21,7 @@ ARM64 Architecture
     perf
     pointer-authentication
     silicon-errata
+    sme
     sve
     tagged-address-abi
     tagged-pointers
diff --git a/Documentation/arm64/sme.rst b/Documentation/arm64/sme.rst
new file mode 100644
index 000000000000..15df3157c592
--- /dev/null
+++ b/Documentation/arm64/sme.rst
@@ -0,0 +1,432 @@
+===================================================
+Scalable Matrix Extension support for AArch64 Linux
+===================================================
+
+This document outlines briefly the interface provided to userspace by Linux in
+order to support use of the ARM Scalable Matrix Extension (SME).
+
+This is an outline of the most important features and issues only and not
+intended to be exhaustive.  It should be read in conjunction with the SVE
+documentation in sve.rst which provides details on the Streaming SVE mode
+included in SME.
+
+This document does not aim to describe the SME architecture or programmer's
+model.  To aid understanding, a minimal description of relevant programmer's
+model features for SME is included in Appendix A.
+
+
+1.  General
+-----------
+
+* PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA
+  register state and TPIDR2_EL0 are tracked per thread.
+
+* The presence of SME is reported to userspace via HWCAP2_SME in the aux vector
+  AT_HWCAP2 entry.  Presence of this flag implies the presence of the SME
+  instructions and registers, and the Linux-specific system interfaces
+  described in this document.  SME is reported in /proc/cpuinfo as "sme".
+
+* Support for the execution of SME instructions in userspace can also be
+  detected by reading the CPU ID register ID_AA64PFR1_EL1 using an MRS
+  instruction, and checking that the value of the SME field is nonzero. [3]
+
+  It does not guarantee the presence of the system interfaces described in the
+  following sections: software that needs to verify that those interfaces are
+  present must check for HWCAP2_SME instead.
+
+* There are a number of optional SME features, presence of these is reported
+  through AT_HWCAP2 through:
+
+	HWCAP2_SME_I16I64
+	HWCAP2_SME_F64F64
+	HWCAP2_SME_I8I32
+	HWCAP2_SME_F16F32
+	HWCAP2_SME_B16F32
+	HWCAP2_SME_F32F32
+	HWCAP2_SME_FA64
+
+  This list may be extended over time as the SME architecture evolves.
+
+  These extensions are also reported via the CPU ID register ID_AA64SMFR0_EL1,
+  which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
+  cpu-feature-registers.txt for details.
+
+* Debuggers should restrict themselves to interacting with the target via the
+  NT_ARM_SVE, NT_ARM_SSVE and NT_ARM_ZA regsets.  The recommended way
+  of detecting support for these regsets is to connect to a target process
+  first and then attempt a
+
+	ptrace(PTRACE_GETREGSET, pid, NT_ARM_<regset>, &iov).
+
+* Whenever ZA register values are exchanged in memory between userspace and
+  the kernel, the register value is encoded in memory as a series of horizontal
+  vectors from 0 to VL/8-1 stored in the same endianness invariant format as is
+  used for SVE vectors.
+
+* On thread creation TPIDR2_EL0 is preserved unless CLONE_SETTLS is specified,
+  in which case it is set to 0.
+
+2.  Vector lengths
+------------------
+
+SME defines a second vector length similar to the SVE vector length which is
+controls the size of the streaming mode SVE vectors and the ZA matrix array.
+The ZA matrix is square with each side having as many bytes as a SVE vector.
+
+
+3.  Sharing of streaming and non-streaming mode SVE state
+---------------------------------------------------------
+
+It is implementation defined which if any parts of the SVE state are shared
+between streaming and non-streaming modes.  When switching between modes
+via software interfaces such as ptrace if no register content is provided as
+part of switching no state will be assumed to be shared and everything will
+be zeroed.
+
+
+4.  System call behaviour
+-------------------------
+
+* On syscall PSTATE.ZA is preserved, if PSTATE.ZA==1 then the contents of the
+  ZA matrix are preserved.
+
+* On syscall PSTATE.SM will be cleared and the SVE registers will be handled
+  as normal.
+
+* Neither the SVE registers nor ZA are used to pass arguments to or receive
+  results from any syscall.
+
+* On creation fork() or clone() the newly created process will have PSTATE.SM
+  and PSTATE.ZA cleared.
+
+* All other SME state of a thread, including the currently configured vector
+  length, the state of the PR_SME_VL_INHERIT flag, and the deferred vector
+  length (if any), is preserved across all syscalls, subject to the specific
+  exceptions for execve() described in section 6.
+
+
+5.  Signal handling
+-------------------
+
+* Signal handlers are invoked with streaming mode and ZA disabled.
+
+* A new signal frame record za_context encodes the ZA register contents on
+  signal delivery. [1]
+
+* The signal frame record for ZA always contains basic metadata, in particular
+  the thread's vector length (in za_context.vl).
+
+* The ZA matrix may or may not be included in the record, depending on
+  the value of PSTATE.ZA.  The registers are present if and only if:
+  za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+  in which case PSTATE.ZA == 1.
+
+* If matrix data is present, the remainder of the record has a vl-dependent
+  size and layout.  Macros ZA_SIG_* are defined [1] to facilitate access to
+  them.
+
+* The matrix is stored as a series of horizontal vectors in the same format as
+  is used for SVE vectors.
+
+* If the ZA context is too big to fit in sigcontext.__reserved[], then extra
+  space is allocated on the stack, an extra_context record is written in
+  __reserved[] referencing this space.  za_context is then written in the
+  extra space.  Refer to [1] for further details about this mechanism.
+
+
+5.  Signal return
+-----------------
+
+When returning from a signal handler:
+
+* If there is no za_context record in the signal frame, or if the record is
+  present but contains no register data as desribed in the previous section,
+  then ZA is disabled.
+
+* If za_context is present in the signal frame and contains matrix data then
+  PSTATE.ZA is set to 1 and ZA is populated with the specified data.
+
+* The vector length cannot be changed via signal return.  If za_context.vl in
+  the signal frame does not match the current vector length, the signal return
+  attempt is treated as illegal, resulting in a forced SIGSEGV.
+
+
+6.  prctl extensions
+--------------------
+
+Some new prctl() calls are added to allow programs to manage the SME vector
+length:
+
+prctl(PR_SME_SET_VL, unsigned long arg)
+
+    Sets the vector length of the calling thread and related flags, where
+    arg == vl | flags.  Other threads of the calling process are unaffected.
+
+    vl is the desired vector length, where sve_vl_valid(vl) must be true.
+
+    flags:
+
+	PR_SME_VL_INHERIT
+
+	    Inherit the current vector length across execve().  Otherwise, the
+	    vector length is reset to the system default at execve().  (See
+	    Section 9.)
+
+	PR_SME_SET_VL_ONEXEC
+
+	    Defer the requested vector length change until the next execve()
+	    performed by this thread.
+
+	    The effect is equivalent to implicit exceution of the following
+	    call immediately after the next execve() (if any) by the thread:
+
+		prctl(PR_SME_SET_VL, arg & ~PR_SME_SET_VL_ONEXEC)
+
+	    This allows launching of a new program with a different vector
+	    length, while avoiding runtime side effects in the caller.
+
+	    Without PR_SME_SET_VL_ONEXEC, the requested change takes effect
+	    immediately.
+
+
+    Return value: a nonnegative on success, or a negative value on error:
+	EINVAL: SME not supported, invalid vector length requested, or
+	    invalid flags.
+
+
+    On success:
+
+    * Either the calling thread's vector length or the deferred vector length
+      to be applied at the next execve() by the thread (dependent on whether
+      PR_SME_SET_VL_ONEXEC is present in arg), is set to the largest value
+      supported by the system that is less than or equal to vl.  If vl ==
+      SVE_VL_MAX, the value set will be the largest value supported by the
+      system.
+
+    * Any previously outstanding deferred vector length change in the calling
+      thread is cancelled.
+
+    * The returned value describes the resulting configuration, encoded as for
+      PR_SME_GET_VL.  The vector length reported in this value is the new
+      current vector length for this thread if PR_SME_SET_VL_ONEXEC was not
+      present in arg; otherwise, the reported vector length is the deferred
+      vector length that will be applied at the next execve() by the calling
+      thread.
+
+    * Changing the vector length causes all of ZA, P0..P15, FFR and all bits of
+      Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
+      unspecified, including both streaming and non-streaming SVE state.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+    * Changing the vector length causes PSTATE.ZA and PSTATE.SM to be cleared.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+
+prctl(PR_SME_GET_VL)
+
+    Gets the vector length of the calling thread.
+
+    The following flag may be OR-ed into the result:
+
+	PR_SME_VL_INHERIT
+
+	    Vector length will be inherited across execve().
+
+    There is no way to determine whether there is an outstanding deferred
+    vector length change (which would only normally be the case between a
+    fork() or vfork() and the corresponding execve() in typical use).
+
+    To extract the vector length from the result, bitwise and it with
+    PR_SME_VL_LEN_MASK.
+
+    Return value: a nonnegative value on success, or a negative value on error:
+	EINVAL: SME not supported.
+
+
+7.  ptrace extensions
+---------------------
+
+* A new regset NT_ARM_SSVE is defined for access to streaming mode SVE
+  state via PTRACE_GETREGSET and  PTRACE_SETREGSET, this is documented in
+  sve.rst.
+
+* A new regset NT_ARM_ZA is defined for ZA state for access to ZA state via
+  PTRACE_GETREGSET and PTRACE_SETREGSET.
+
+  Refer to [2] for definitions.
+
+The regset data starts with struct user_za_header, containing:
+
+    size
+
+	Size of the complete regset, in bytes.
+	This depends on vl and possibly on other things in the future.
+
+	If a call to PTRACE_GETREGSET requests less data than the value of
+	size, the caller can allocate a larger buffer and retry in order to
+	read the complete regset.
+
+    max_size
+
+	Maximum size in bytes that the regset can grow to for the target
+	thread.  The regset won't grow bigger than this even if the target
+	thread changes its vector length etc.
+
+    vl
+
+	Target thread's current streaming vector length, in bytes.
+
+    max_vl
+
+	Maximum possible streaming vector length for the target thread.
+
+    flags
+
+	Zero or more of the following flags, which have the same
+	meaning and behaviour as the corresponding PR_SET_VL_* flags:
+
+	    SME_PT_VL_INHERIT
+
+	    SME_PT_VL_ONEXEC (SETREGSET only).
+
+* The effects of changing the vector length and/or flags are equivalent to
+  those documented for PR_SME_SET_VL.
+
+  The caller must make a further GETREGSET call if it needs to know what VL is
+  actually set by SETREGSET, unless is it known in advance that the requested
+  VL is supported.
+
+* The size and layout of the payload depends on the header fields.  The
+  SME_PT_ZA_*() macros are provided to facilitate access to the data.
+
+* In either case, for SETREGSET it is permissible to omit the payload, in which
+  case the vector length and flags are changed and PSTATE.ZA is set to 0
+  (along with any consequences of those changes).  If a payload is provided
+  then PSTATE.ZA will be set to 1.
+
+* For SETREGSET, if the requested VL is not supported, the effect will be the
+  same as if the payload were omitted, except that an EIO error is reported.
+  No attempt is made to translate the payload data to the correct layout
+  for the vector length actually set.  It is up to the caller to translate the
+  payload layout for the actual VL and retry.
+
+* The effect of writing a partial, incomplete payload is unspecified.
+
+
+8.  ELF coredump extensions
+---------------------------
+
+* NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
+
+* A NT_ARM_ZA note will be added to each coredump for each thread of the
+  dumped process.  The contents will be equivalent to the data that would have
+  been read if a PTRACE_GETREGSET of NT_ARM_ZA were executed for each thread
+  when the coredump was generated.
+
+
+9.  System runtime configuration
+--------------------------------
+
+* To mitigate the ABI impact of expansion of the signal frame, a policy
+  mechanism is provided for administrators, distro maintainers and developers
+  to set the default vector length for userspace processes:
+
+/proc/sys/abi/sme_default_vector_length
+
+    Writing the text representation of an integer to this file sets the system
+    default vector length to the specified value, unless the value is greater
+    than the maximum vector length supported by the system in which case the
+    default vector length is set to that maximum.
+
+    The result can be determined by reopening the file and reading its
+    contents.
+
+    At boot, the default vector length is initially set to 32 or the maximum
+    supported vector length, whichever is smaller and supported.  This
+    determines the initial vector length of the init process (PID 1).
+
+    Reading this file returns the current system default vector length.
+
+* At every execve() call, the new vector length of the new process is set to
+  the system default vector length, unless
+
+    * PR_SME_VL_INHERIT (or equivalently SME_PT_VL_INHERIT) is set for the
+      calling thread, or
+
+    * a deferred vector length change is pending, established via the
+      PR_SME_SET_VL_ONEXEC flag (or SME_PT_VL_ONEXEC).
+
+* Modifying the system default vector length does not affect the vector length
+  of any existing process or thread that does not make an execve() call.
+
+
+Appendix A.  SME programmer's model (informative)
+=================================================
+
+This section provides a minimal description of the additions made by SVE to the
+ARMv8-A programmer's model that are relevant to this document.
+
+Note: This section is for information only and not intended to be complete or
+to replace any architectural specification.
+
+A.1.  Registers
+---------------
+
+In A64 state, SME adds the following:
+
+* A new mode, streaming mode, in which a subset of the normal FPSIMD and SVE
+  features are available.  When supported EL0 software may enter and leave
+  streaming mode at any time.
+
+  For best system performance it is strongly encouraged for software to enable
+  streaming mode only when it is actively being used.
+
+* A new vector length controlling the size of ZA and the Z registers when in
+  streaming mode, separately to the vector length used for SVE when not in
+  streaming mode.  There is no requirement that either the currently selected
+  vector length or the set of vector lengths supported for the two modes in
+  a given system have any relationship.  The streaming mode vector length
+  is referred to as SVL.
+
+* A new ZA matrix register.  This is a square matrix of SVLxSVL bits.  Most
+  operations on ZA require that streaming mode be enabled but ZA can be
+  enabled without streaming mode in order to load, save and retain data.
+
+  For best system performance it is strongly encouraged for software to enable
+  ZA only when it is actively being used.
+
+* Two new 1 bit fields in PSTATE which may be controlled via the SMSTART and
+  SMSTOP instructions or by access to the SVCR system register:
+
+  * PSTATE.ZA, if this is 1 then the ZA matrix is accessible and has valid
+    data while if it is 0 then ZA can not be accessed.  When PSTATE.ZA is
+    changed from 0 to 1 all bits in ZA are cleared.
+
+  * PSTATE.SM, if this is 1 then the PE is in streaming mode.  When the value
+    of PSTATE.SM is changed then it is implementation defined if the subset
+    of the floating point register bits valid in both modes may be retained.
+    Any other bits will be cleared.
+
+
+References
+==========
+
+[1] arch/arm64/include/uapi/asm/sigcontext.h
+    AArch64 Linux signal ABI definitions
+
+[2] arch/arm64/include/uapi/asm/ptrace.h
+    AArch64 Linux ptrace ABI definitions
+
+[3] Documentation/arm64/cpu-feature-registers.rst
+
+[4] ARM IHI0055C
+    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
+    http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+    Procedure Call Standard for the ARM 64-bit Architecture (AArch64)
diff --git a/Documentation/arm64/sve.rst b/Documentation/arm64/sve.rst
index 9d9a4de5bc34..93c2c2990584 100644
--- a/Documentation/arm64/sve.rst
+++ b/Documentation/arm64/sve.rst
@@ -7,7 +7,9 @@ Author: Dave Martin <Dave.Martin at arm.com>
 Date:   4 August 2017
 
 This document outlines briefly the interface provided to userspace by Linux in
-order to support use of the ARM Scalable Vector Extension (SVE).
+order to support use of the ARM Scalable Vector Extension (SVE), including
+interactions with Streaming SVE mode added by the Scalable Matrix Extension
+(SME).
 
 This is an outline of the most important features and issues only and not
 intended to be exhaustive.
@@ -23,6 +25,10 @@ model features for SVE is included in Appendix A.
 * SVE registers Z0..Z31, P0..P15 and FFR and the current vector length VL, are
   tracked per-thread.
 
+* In streaming mode FFR is not accessible unless HWCAP2_SME_FA64 is present
+  in the system, when it is not supported and these interfaces are used to
+  access streaming mode FFR is read and written as zero.
+
 * The presence of SVE is reported to userspace via HWCAP_SVE in the aux vector
   AT_HWCAP entry.  Presence of this flag implies the presence of the SVE
   instructions and registers, and the Linux-specific system interfaces
@@ -53,10 +59,19 @@ model features for SVE is included in Appendix A.
   which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
   cpu-feature-registers.txt for details.
 
+* On hardware that supports the SME extensions, HWCAP2_SME will also be
+  reported in the AT_HWCAP2 aux vector entry.  Among other things SME adds
+  streaming mode which provides a subset of the SVE feature set using a
+  separate SME vector length and the same Z/V registers.  See sme.rst
+  for more details.
+
 * Debuggers should restrict themselves to interacting with the target via the
   NT_ARM_SVE regset.  The recommended way of detecting support for this regset
   is to connect to a target process first and then attempt a
-  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).
+  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).  Note that when SME is
+  present and streaming SVE mode is in use the FPSIMD subset of registers
+  will be read via NT_ARM_SVE and NT_ARM_SVE writes will exit streaming mode
+  in the target.
 
 * Whenever SVE scalable register values (Zn, Pn, FFR) are exchanged in memory
   between userspace and the kernel, the register value is encoded in memory in
@@ -126,6 +141,11 @@ the SVE instruction set architecture.
   are only present in fpsimd_context.  For convenience, the content of V0..V31
   is duplicated between sve_context and fpsimd_context.
 
+* The record contains a flag field which includes a flag SVE_SIG_FLAG_SM which
+  if set indicates that the thread is in streaming mode and the vector length
+  and register data (if present) describe the streaming SVE data and vector
+  length.
+
 * The signal frame record for SVE always contains basic metadata, in particular
   the thread's vector length (in sve_context.vl).
 
@@ -170,6 +190,11 @@ When returning from a signal handler:
   the signal frame does not match the current vector length, the signal return
   attempt is treated as illegal, resulting in a forced SIGSEGV.
 
+* It is permitted to enter or leave streaming mode by setting or clearing
+  the SVE_SIG_FLAG_SM flag but applications should take care to ensure that
+  when doing so sve_context.vl and any register data are appropriate for the
+  vector length in the new mode.
+
 
 6.  prctl extensions
 --------------------
@@ -265,8 +290,14 @@ prctl(PR_SVE_GET_VL)
 7.  ptrace extensions
 ---------------------
 
-* A new regset NT_ARM_SVE is defined for use with PTRACE_GETREGSET and
-  PTRACE_SETREGSET.
+* New regsets NT_ARM_SVE and NT_ARM_SSVE are defined for use with
+  PTRACE_GETREGSET and PTRACE_SETREGSET. NT_ARM_SSVE describes the
+  streaming mode SVE registers and NT_ARM_SVE describes the
+  non-streaming mode SVE registers.
+
+  In this description a register set is referred to as being "live" when
+  the target is in the appropriate streaming or non-streaming mode and is
+  using data beyond the subset shared with the FPSIMD Vn registers.
 
   Refer to [2] for definitions.
 
@@ -297,7 +328,7 @@ The regset data starts with struct user_sve_header, containing:
 
     flags
 
-	either
+	at most one of
 
 	    SVE_PT_REGS_FPSIMD
 
@@ -331,6 +362,10 @@ The regset data starts with struct user_sve_header, containing:
 
 	    SVE_PT_VL_ONEXEC (SETREGSET only).
 
+	If neither FPSIMD nor SVE flags are provided then no register
+	payload is available, this is only possible when SME is implemented.
+
+
 * The effects of changing the vector length and/or flags are equivalent to
   those documented for PR_SVE_SET_VL.
 
@@ -346,6 +381,13 @@ The regset data starts with struct user_sve_header, containing:
   case only the vector length and flags are changed (along with any
   consequences of those changes).
 
+* In systems supporting SME when in streaming mode a GETREGSET for
+  NT_REG_SVE will return only the user_sve_header with no register data,
+  similarly a GETREGSET for NT_REG_SSVE will not return any register data
+  when not in streaming mode.
+
+* A GETREGSET for NT_ARM_SSVE will never return SVE_PT_REGS_FPSIMD.
+
 * For SETREGSET, if an SVE_PT_REGS_SVE payload is present and the
   requested VL is not supported, the effect will be the same as if the
   payload were omitted, except that an EIO error is reported.  No
@@ -355,17 +397,25 @@ The regset data starts with struct user_sve_header, containing:
   unspecified.  It is up to the caller to translate the payload layout
   for the actual VL and retry.
 
+* Where SME is implemented it is not possible to GETREGSET the register
+  state for normal SVE when in streaming mode, nor the streaming mode
+  register state when in normal mode, regardless of the implementation defined
+  behaviour of the hardware for sharing data between the two modes.
+
+* Any SETREGSET of NT_ARM_SVE will exit streaming mode if the target was in
+  streaming mode and any SETREGSET of NT_ARM_SSVE will enter streaming mode
+  if the target was not in streaming mode.
+
 * The effect of writing a partial, incomplete payload is unspecified.
 
 
 8.  ELF coredump extensions
 ---------------------------
 
-* A NT_ARM_SVE note will be added to each coredump for each thread of the
-  dumped process.  The contents will be equivalent to the data that would have
-  been read if a PTRACE_GETREGSET of NT_ARM_SVE were executed for each thread
-  when the coredump was generated.
-
+* NT_ARM_SVE and NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
 
 9.  System runtime configuration
 --------------------------------
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:46 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:46 +0000
Subject: [PATCH v9 06/40] arm64/sme: System register and exception syndrome
 definitions
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-7-broonie@kernel.org>

The arm64 Scalable Matrix Extension (SME) adds some new system registers,
fields in existing system registers and exception syndromes. This patch
adds definitions for these for use in future patches implementing support
for this extension.

Since SME will be the first user of FEAT_HCX in the kernel also include
the definitions for enumerating it and the HCRX system register it adds.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h     | 12 +++++-
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/include/asm/sysreg.h  | 63 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/traps.c        |  1 +
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d52a0b269ee8..43872e0cfd1e 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -37,7 +37,8 @@
 #define ESR_ELx_EC_ERET		(0x1a)	/* EL2 only */
 /* Unallocated EC: 0x1B */
 #define ESR_ELx_EC_FPAC		(0x1C)	/* EL1 and above */
-/* Unallocated EC: 0x1D - 0x1E */
+#define ESR_ELx_EC_SME		(0x1D)
+/* Unallocated EC: 0x1E */
 #define ESR_ELx_EC_IMP_DEF	(0x1f)	/* EL3 only */
 #define ESR_ELx_EC_IABT_LOW	(0x20)
 #define ESR_ELx_EC_IABT_CUR	(0x21)
@@ -327,6 +328,15 @@
 #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ	(ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\
 					 ESR_ELx_CP15_32_ISS_DIR_READ)
 
+/*
+ * ISS values for SME traps
+ */
+
+#define ESR_ELx_SME_ISS_SME_DISABLED	0
+#define ESR_ELx_SME_ISS_ILL		1
+#define ESR_ELx_SME_ISS_SM_DISABLED	2
+#define ESR_ELx_SME_ISS_ZA_DISABLED	3
+
 #ifndef __ASSEMBLY__
 #include <asm/types.h>
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 1767ded83888..13ae232ec4a1 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -279,6 +279,7 @@
 #define CPTR_EL2_TCPAC	(1U << 31)
 #define CPTR_EL2_TAM	(1 << 30)
 #define CPTR_EL2_TTA	(1 << 20)
+#define CPTR_EL2_TSM	(1 << 12)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
 #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index e66dd9ebc337..6056c9aaab28 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -173,6 +173,7 @@
 #define SYS_ID_AA64PFR0_EL1		sys_reg(3, 0, 0, 4, 0)
 #define SYS_ID_AA64PFR1_EL1		sys_reg(3, 0, 0, 4, 1)
 #define SYS_ID_AA64ZFR0_EL1		sys_reg(3, 0, 0, 4, 4)
+#define SYS_ID_AA64SMFR0_EL1		sys_reg(3, 0, 0, 4, 5)
 
 #define SYS_ID_AA64DFR0_EL1		sys_reg(3, 0, 0, 5, 0)
 #define SYS_ID_AA64DFR1_EL1		sys_reg(3, 0, 0, 5, 1)
@@ -196,6 +197,8 @@
 
 #define SYS_ZCR_EL1			sys_reg(3, 0, 1, 2, 0)
 #define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
+#define SYS_SMPRI_EL1			sys_reg(3, 0, 1, 2, 4)
+#define SYS_SMCR_EL1			sys_reg(3, 0, 1, 2, 6)
 
 #define SYS_TTBR0_EL1			sys_reg(3, 0, 2, 0, 0)
 #define SYS_TTBR1_EL1			sys_reg(3, 0, 2, 0, 1)
@@ -388,6 +391,8 @@
 #define TRBIDR_ALIGN_MASK		GENMASK(3, 0)
 #define TRBIDR_ALIGN_SHIFT		0
 
+#define SMPRI_EL1_PRIORITY_MASK		0xf
+
 #define SYS_PMINTENSET_EL1		sys_reg(3, 0, 9, 14, 1)
 #define SYS_PMINTENCLR_EL1		sys_reg(3, 0, 9, 14, 2)
 
@@ -443,8 +448,13 @@
 #define SYS_CCSIDR_EL1			sys_reg(3, 1, 0, 0, 0)
 #define SYS_CLIDR_EL1			sys_reg(3, 1, 0, 0, 1)
 #define SYS_GMID_EL1			sys_reg(3, 1, 0, 0, 4)
+#define SYS_SMIDR_EL1			sys_reg(3, 1, 0, 0, 6)
 #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
 
+#define SYS_SMIDR_EL1_IMPLEMENTER_SHIFT	24
+#define SYS_SMIDR_EL1_SMPS_SHIFT	15
+#define SYS_SMIDR_EL1_AFFINITY_SHIFT	0
+
 #define SYS_CSSELR_EL1			sys_reg(3, 2, 0, 0, 0)
 
 #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
@@ -453,6 +463,10 @@
 #define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
 #define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
 
+#define SYS_SVCR_EL0			sys_reg(3, 3, 4, 2, 2)
+#define SYS_SVCR_EL0_ZA_MASK		2
+#define SYS_SVCR_EL0_SM_MASK		1
+
 #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
 #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
 #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
@@ -469,6 +483,7 @@
 
 #define SYS_TPIDR_EL0			sys_reg(3, 3, 13, 0, 2)
 #define SYS_TPIDRRO_EL0			sys_reg(3, 3, 13, 0, 3)
+#define SYS_TPIDR2_EL0			sys_reg(3, 3, 13, 0, 5)
 
 #define SYS_SCXTNUM_EL0			sys_reg(3, 3, 13, 0, 7)
 
@@ -538,6 +553,9 @@
 #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
 #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
+#define SYS_HCRX_EL2			sys_reg(3, 4, 1, 2, 2)
+#define SYS_SMPRIMAP_EL2		sys_reg(3, 4, 1, 2, 5)
+#define SYS_SMCR_EL2			sys_reg(3, 4, 1, 2, 6)
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
 #define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
 #define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
@@ -597,6 +615,7 @@
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
 #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+#define SYS_SMCR_EL12			sys_reg(3, 5, 1, 2, 6)
 #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
 #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
 #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
@@ -620,6 +639,7 @@
 #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
 
 /* Common SCTLR_ELx flags. */
+#define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
 
@@ -815,6 +835,7 @@
 #define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
 
 /* id_aa64pfr1 */
+#define ID_AA64PFR1_SME_SHIFT		24
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
 #define ID_AA64PFR1_RASFRAC_SHIFT	12
 #define ID_AA64PFR1_MTE_SHIFT		8
@@ -825,6 +846,7 @@
 #define ID_AA64PFR1_SSBS_PSTATE_ONLY	1
 #define ID_AA64PFR1_SSBS_PSTATE_INSNS	2
 #define ID_AA64PFR1_BT_BTI		0x1
+#define ID_AA64PFR1_SME			1
 
 #define ID_AA64PFR1_MTE_NI		0x0
 #define ID_AA64PFR1_MTE_EL0		0x1
@@ -853,6 +875,23 @@
 #define ID_AA64ZFR0_AES_PMULL		0x2
 #define ID_AA64ZFR0_SVEVER_SVE2		0x1
 
+/* id_aa64smfr0 */
+#define ID_AA64SMFR0_FA64_SHIFT		63
+#define ID_AA64SMFR0_I16I64_SHIFT	52
+#define ID_AA64SMFR0_F64F64_SHIFT	48
+#define ID_AA64SMFR0_I8I32_SHIFT	36
+#define ID_AA64SMFR0_F16F32_SHIFT	35
+#define ID_AA64SMFR0_B16F32_SHIFT	34
+#define ID_AA64SMFR0_F32F32_SHIFT	32
+
+#define ID_AA64SMFR0_FA64		0x1
+#define ID_AA64SMFR0_I16I64		0x4
+#define ID_AA64SMFR0_F64F64		0x1
+#define ID_AA64SMFR0_I8I32		0x4
+#define ID_AA64SMFR0_F16F32		0x1
+#define ID_AA64SMFR0_B16F32		0x1
+#define ID_AA64SMFR0_F32F32		0x1
+
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_ECV_SHIFT		60
 #define ID_AA64MMFR0_FGT_SHIFT		56
@@ -904,6 +943,7 @@
 #endif
 
 /* id_aa64mmfr1 */
+#define ID_AA64MMFR1_HCX_SHIFT		40
 #define ID_AA64MMFR1_AFP_SHIFT		44
 #define ID_AA64MMFR1_ETS_SHIFT		36
 #define ID_AA64MMFR1_TWED_SHIFT		32
@@ -1097,9 +1137,24 @@
 #define ZCR_ELx_LEN_SIZE	9
 #define ZCR_ELx_LEN_MASK	0x1ff
 
+#define SMCR_ELx_FA64_SHIFT	31
+#define SMCR_ELx_FA64_MASK	(1 << SMCR_ELx_FA64_SHIFT)
+
+/*
+ * The SMCR_ELx_LEN_* definitions intentionally include bits [8:4] which
+ * are reserved by the SME architecture for future expansion of the LEN
+ * field, with compatible semantics.
+ */
+#define SMCR_ELx_LEN_SHIFT	0
+#define SMCR_ELx_LEN_SIZE	9
+#define SMCR_ELx_LEN_MASK	0x1ff
+
 #define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
 #define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
 
+#define CPACR_EL1_SMEN_EL1EN	(BIT(24)) /* enable EL1 access */
+#define CPACR_EL1_SMEN_EL0EN	(BIT(25)) /* enable EL0 access, if EL1EN set */
+
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 
@@ -1152,6 +1207,8 @@
 #define TRFCR_ELx_ExTRE			BIT(1)
 #define TRFCR_ELx_E0TRE			BIT(0)
 
+/* HCRX_EL2 definitions */
+#define HCRX_EL2_SMPME_MASK		(1 << 5)
 
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
@@ -1215,6 +1272,12 @@
 #define ICH_VTR_TDS_SHIFT	19
 #define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
 
+/* HFG[WR]TR_EL2 bit definitions */
+#define HFGxTR_EL2_nTPIDR2_EL0_SHIFT	55
+#define HFGxTR_EL2_nTPIDR2_EL0_MASK	BIT_MASK(HFGxTR_EL2_nTPIDR2_EL0_SHIFT)
+#define HFGxTR_EL2_nSMPRI_EL1_SHIFT	54
+#define HFGxTR_EL2_nSMPRI_EL1_MASK	BIT_MASK(HFGxTR_EL2_nSMPRI_EL1_SHIFT)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Create a mask for the feature bits of the specified feature. */
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 70fc42470f13..88effb25c399 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -822,6 +822,7 @@ static const char *esr_class_str[] = {
 	[ESR_ELx_EC_SVE]		= "SVE",
 	[ESR_ELx_EC_ERET]		= "ERET/ERETAA/ERETAB",
 	[ESR_ELx_EC_FPAC]		= "FPAC",
+	[ESR_ELx_EC_SME]		= "SME",
 	[ESR_ELx_EC_IMP_DEF]		= "EL3 IMP DEF",
 	[ESR_ELx_EC_IABT_LOW]		= "IABT (lower EL)",
 	[ESR_ELx_EC_IABT_CUR]		= "IABT (current EL)",
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:47 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:47 +0000
Subject: [PATCH v9 07/40] arm64/sme: Manually encode SME instructions
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-8-broonie@kernel.org>

As with SVE rather than impose ambitious toolchain requirements for SME
we manually encode the few instructions which we require in order to
perform the work the kernel needs to do. The instructions used to save
and restore context are provided as assembler macros while those for
entering and leaving streaming mode are done in asm volatile blocks
since they are expected to be used from C.

We could do the SMSTART and SMSTOP operations with read/modify/write
cycles on SVCR but using the aliases provided for individual field
accesses should be slightly faster. These instructions are aliases for
MSR but since our minimum toolchain requirements are old enough to mean
that we can't use the sX_X_cX_cX_X form and they always use xzr rather
than taking a value like write_sysreg_s() wants we just use .inst.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       | 25 +++++++++++++
 arch/arm64/include/asm/fpsimdmacros.h | 53 +++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index cb24385e3632..c90f7f99a768 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -249,6 +249,31 @@ static inline void sve_setup(void) { }
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static inline void sme_smstart_sm(void)
+{
+	asm volatile(".inst 0xd503437f");
+}
+
+static inline void sme_smstop_sm(void)
+{
+	asm volatile(".inst 0xd503427f");
+}
+
+static inline void sme_smstop(void)
+{
+	asm volatile(".inst 0xd503467f");
+}
+
+#else
+
+static inline void sme_smstart_sm(void) { }
+static inline void sme_smstop_sm(void) { }
+static inline void sme_smstop(void) { }
+
+#endif /* ! CONFIG_ARM64_SME */
+
 /* For use by EFI runtime services calls only */
 extern void __efi_fpsimd_begin(void);
 extern void __efi_fpsimd_end(void);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 2509d7dde55a..11c426ddd62c 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -93,6 +93,12 @@
 	.endif
 .endm
 
+.macro _sme_check_wv v
+	.if (\v) < 12 || (\v) > 15
+		.error "Bad vector select register \v."
+	.endif
+.endm
+
 /* SVE instruction encodings for non-SVE-capable assemblers */
 /* (pre binutils 2.28, all kernel capable clang versions support SVE) */
 
@@ -174,6 +180,53 @@
 		| (\np)
 .endm
 
+/* SME instruction encodings for non-SME-capable assemblers */
+
+/* RDSVL X\nx, #\imm */
+.macro _sme_rdsvl nx, imm
+	_check_general_reg \nx
+	_check_num (\imm), -0x20, 0x1f
+	.inst	0x04bf5800			\
+		| (\nx)				\
+		| (((\imm) & 0x3f) << 5)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_str_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_ldr_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * Zero the entire ZA array
+ *	ZERO ZA
+ */
+.macro zero_za
+	.inst 0xc00800ff
+.endm
+
 .macro __for from:req, to:req
 	.if (\from) == (\to)
 		_for__body %\from
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:49 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:49 +0000
Subject: [PATCH v9 09/40] arm64/sme: Basic enumeration support
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-10-broonie@kernel.org>

This patch introduces basic cpufeature support for discovering the presence
of the Scalable Matrix Extension.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/elf_hwcaps.rst  | 33 +++++++++++++++++
 arch/arm64/include/asm/cpu.h        |  1 +
 arch/arm64/include/asm/cpufeature.h | 12 ++++++
 arch/arm64/include/asm/fpsimd.h     |  2 +
 arch/arm64/include/asm/hwcap.h      |  8 ++++
 arch/arm64/include/uapi/asm/hwcap.h |  8 ++++
 arch/arm64/kernel/cpufeature.c      | 57 +++++++++++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c         |  9 +++++
 arch/arm64/kernel/fpsimd.c          | 30 +++++++++++++++
 arch/arm64/tools/cpucaps            |  2 +
 10 files changed, 162 insertions(+)

diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index b72ff17d600a..5626cf208000 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -259,6 +259,39 @@ HWCAP2_RPRES
 
     Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
 
+HWCAP2_SME
+
+    Functionality implied by ID_AA64PFR1_EL1.SME == 0b0001, as described
+    by Documentation/arm64/sme.rst.
+
+HWCAP2_SME_I16I64
+
+    Functionality implied by ID_AA64SMFR0_EL1.I16I64 == 0b1111.
+
+HWCAP2_SME_F64F64
+
+    Functionality implied by ID_AA64SMFR0_EL1.F64F64 == 0b1.
+
+HWCAP2_SME_I8I32
+
+    Functionality implied by ID_AA64SMFR0_EL1.I8I32 == 0b1111.
+
+HWCAP2_SME_F16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F16F32 == 0b1.
+
+HWCAP2_SME_B16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.B16F32 == 0b1.
+
+HWCAP2_SME_F32F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F32F32 == 0b1.
+
+HWCAP2_SME_FA64
+
+    Functionality implied by ID_AA64SMFR0_EL1.FA64 == 0b1.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index a58e366f0b07..d08062bcb9c1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -58,6 +58,7 @@ struct cpuinfo_arm64 {
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr1;
 	u64		reg_id_aa64zfr0;
+	u64		reg_id_aa64smfr0;
 
 	struct cpuinfo_32bit	aarch32;
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 2728abd9cae4..f93b1442143f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -728,6 +728,18 @@ static __always_inline bool system_supports_sve(void)
 		cpus_have_const_cap(ARM64_SVE);
 }
 
+static __always_inline bool system_supports_sme(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME);
+}
+
+static __always_inline bool system_supports_fa64(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME_FA64);
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index c90f7f99a768..6b7eb6f2cecd 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -74,6 +74,8 @@ extern void sve_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f68fbb207473..76d9999527c5 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -108,6 +108,14 @@
 #define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
 #define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
 #define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_SME		__khwcap2_feature(SME)
+#define KERNEL_HWCAP_SME_I16I64		__khwcap2_feature(SME_I16I64)
+#define KERNEL_HWCAP_SME_F64F64		__khwcap2_feature(SME_F64F64)
+#define KERNEL_HWCAP_SME_I8I32		__khwcap2_feature(SME_I8I32)
+#define KERNEL_HWCAP_SME_F16F32		__khwcap2_feature(SME_F16F32)
+#define KERNEL_HWCAP_SME_B16F32		__khwcap2_feature(SME_B16F32)
+#define KERNEL_HWCAP_SME_F32F32		__khwcap2_feature(SME_F32F32)
+#define KERNEL_HWCAP_SME_FA64		__khwcap2_feature(SME_FA64)
 
 /*
  * This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index f03731847d9d..60de5626f8fb 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -78,5 +78,13 @@
 #define HWCAP2_ECV		(1 << 19)
 #define HWCAP2_AFP		(1 << 20)
 #define HWCAP2_RPRES		(1 << 21)
+#define HWCAP2_SME		(1 << 22)
+#define HWCAP2_SME_I16I64	(1 << 23)
+#define HWCAP2_SME_F64F64	(1 << 24)
+#define HWCAP2_SME_I8I32	(1 << 25)
+#define HWCAP2_SME_F16F32	(1 << 26)
+#define HWCAP2_SME_B16F32	(1 << 27)
+#define HWCAP2_SME_F32F32	(1 << 28)
+#define HWCAP2_SME_FA64		(1 << 29)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d9f09e40aaf6..3cd7fe53cffa 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -251,6 +251,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SME_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE),
@@ -283,6 +284,24 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_FA64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I16I64_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F64F64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I8I32_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_B16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F32F32_SHIFT, 1, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0),
@@ -634,6 +653,7 @@ static const struct __ftr_reg_entry {
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
 			       &id_aa64pfr1_override),
 	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
+	ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -947,6 +967,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
 	init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
 	init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
+	init_cpu_ftr_reg(SYS_ID_AA64SMFR0_EL1, info->reg_id_aa64smfr0);
 
 	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
 		init_32bit_cpu_features(&info->aarch32);
@@ -2400,6 +2421,32 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+#ifdef CONFIG_ARM64_SME
+	{
+		.desc = "Scalable Matrix Extension",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME,
+		.sys_reg = SYS_ID_AA64PFR1_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64PFR1_SME_SHIFT,
+		.field_width = 4,
+		.min_field_value = ID_AA64PFR1_SME,
+		.matches = has_cpuid_feature,
+		.cpu_enable = sme_kernel_enable,
+	},
+	{
+		.desc = "FA64",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME_FA64,
+		.sys_reg = SYS_ID_AA64SMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64SMFR0_FA64_SHIFT,
+		.field_width = 1,
+		.min_field_value = ID_AA64SMFR0_FA64,
+		.matches = has_cpuid_feature,
+		.cpu_enable = fa64_kernel_enable,
+	},
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
@@ -2524,6 +2571,16 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
 	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+#ifdef CONFIG_ARM64_SME
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SME_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SME, CAP_HWCAP, KERNEL_HWCAP_SME),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_FA64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_FA64, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I16I64_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I16I64, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F64F64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F64F64, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I8I32_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I8I32, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F16F32, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_B16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_B16F32, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F32F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F32F32, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..33ec182e872e 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -97,6 +97,14 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_ECV]		= "ecv",
 	[KERNEL_HWCAP_AFP]		= "afp",
 	[KERNEL_HWCAP_RPRES]		= "rpres",
+	[KERNEL_HWCAP_SME]		= "sme",
+	[KERNEL_HWCAP_SME_I16I64]	= "smei16i64",
+	[KERNEL_HWCAP_SME_F64F64]	= "smef64f64",
+	[KERNEL_HWCAP_SME_I8I32]	= "smei8i32",
+	[KERNEL_HWCAP_SME_F16F32]	= "smef16f32",
+	[KERNEL_HWCAP_SME_B16F32]	= "smeb16f32",
+	[KERNEL_HWCAP_SME_F32F32]	= "smef32f32",
+	[KERNEL_HWCAP_SME_FA64]		= "smefa64",
 };
 
 #ifdef CONFIG_COMPAT
@@ -400,6 +408,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 	info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
+	info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
 
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		info->reg_gmid = read_cpuid(GMID_EL1);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 5280e098cfb5..576490be3c2b 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -987,6 +987,32 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Set priority for all PEs to architecturally defined minimum */
+	write_sysreg_s(read_sysreg_s(SYS_SMPRI_EL1) & ~SMPRI_EL1_PRIORITY_MASK,
+		       SYS_SMPRI_EL1);
+
+	/* Allow SME in kernel */
+	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
+	isb();
+}
+
+/*
+ * This must be called after sme_kernel_enable(), we rely on the
+ * feature table being sorted to ensure this.
+ */
+void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Allow use of FA64 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
+		       SYS_SMCR_EL1);
+}
+
+#endif /* CONFIG_ARM64_SVE */
+
 /*
  * Trapped SVE access
  *
@@ -1532,6 +1558,10 @@ static int __init fpsimd_init(void)
 	if (!cpu_have_named_feature(ASIMD))
 		pr_notice("Advanced SIMD is not implemented\n");
 
+
+	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
+		pr_notice("SME is implemented but not SVE\n");
+
 	return sve_sysctl_init();
 }
 core_initcall(fpsimd_init);
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..58dfc8547c64 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -41,6 +41,8 @@ KVM_PROTECTED_MODE
 MISMATCHED_CACHE_TYPE
 MTE
 MTE_ASYMM
+SME
+SME_FA64
 SPECTRE_V2
 SPECTRE_V3A
 SPECTRE_V4
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:48 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:48 +0000
Subject: [PATCH v9 08/40] arm64/sme: Early CPU setup for SME
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-9-broonie@kernel.org>

SME requires similar setup to that for SVE: disable traps to EL2 and
make sure that the maximum vector length is available to EL1, for SME we
have two traps - one for SME itself and one for TPIDR2.

In addition since we currently make no active use of priority control
for SCMUs we map all SME priorities lower ELs may configure to 0, the
architecture specified minimum priority, to ensure that nothing we
manage is able to configure itself to consume excessive resources.  This
will need to be revisited should there be a need to manage SME
priorities at runtime.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 64 ++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 3198acb2aad8..31f1a69c9dd2 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -143,6 +143,50 @@
 .Lskip_sve_\@:
 .endm
 
+/* SME register access and priority mapping */
+.macro __init_el2_nvhe_sme
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	bic	x0, x0, #CPTR_EL2_TSM		// Also disable SME traps
+	msr	cptr_el2, x0			// Disable copro. traps to EL2
+	isb
+
+	mrs	x1, sctlr_el2
+	orr	x1, x1, #SCTLR_ELx_ENTP2	// Disable TPIDR2 traps
+	msr	sctlr_el2, x1
+	isb
+
+	mov	x1, #0				// SMCR controls
+
+	mrs_s	x2, SYS_ID_AA64SMFR0_EL1
+	ubfx	x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
+	cbz	x2, .Lskip_sme_fa64_\@
+
+	orr	x1, x1, SMCR_ELx_FA64_MASK
+.Lskip_sme_fa64_\@:
+
+	orr	x1, x1, #SMCR_ELx_LEN_MASK	// Enable full SME vector
+	msr_s	SYS_SMCR_EL2, x1		// length for EL1.
+
+	mrs_s	x1, SYS_SMIDR_EL1		// Priority mapping supported?
+	ubfx    x1, x1, #SYS_SMIDR_EL1_SMPS_SHIFT, #1
+	cbz     x1, .Lskip_sme_\@
+
+	msr_s	SYS_SMPRIMAP_EL2, xzr		// Make all priorities equal
+
+	mrs	x1, id_aa64mmfr1_el1		// HCRX_EL2 present?
+	ubfx	x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	mrs_s	x1, SYS_HCRX_EL2
+	orr	x1, x1, #HCRX_EL2_SMPME_MASK	// Enable priority mapping
+	msr_s	SYS_HCRX_EL2, x1
+
+.Lskip_sme_\@:
+.endm
+
 /* Disable any fine grained traps */
 .macro __init_el2_fgt
 	mrs	x1, id_aa64mmfr0_el1
@@ -153,15 +197,26 @@
 	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
 	cmp	x1, #3
-	b.lt	.Lset_fgt_\@
+	b.lt	.Lset_debug_fgt_\@
 	/* Disable PMSNEVFR_EL1 read and write traps */
 	orr	x0, x0, #(1 << 62)
 
-.Lset_fgt_\@:
+.Lset_debug_fgt_\@:
 	msr_s	SYS_HDFGRTR_EL2, x0
 	msr_s	SYS_HDFGWTR_EL2, x0
-	msr_s	SYS_HFGRTR_EL2, xzr
-	msr_s	SYS_HFGWTR_EL2, xzr
+
+	mov	x0, xzr
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lset_fgt_\@
+
+	/* Disable nVHE traps of TPIDR2 and SMPRI */
+	orr	x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
+	orr	x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
+
+.Lset_fgt_\@:
+	msr_s	SYS_HFGRTR_EL2, x0
+	msr_s	SYS_HFGWTR_EL2, x0
 	msr_s	SYS_HFGITR_EL2, xzr
 
 	mrs	x1, id_aa64pfr0_el1		// AMU traps UNDEF without AMU
@@ -196,6 +251,7 @@
 	__init_el2_nvhe_idregs
 	__init_el2_nvhe_cptr
 	__init_el2_nvhe_sve
+	__init_el2_nvhe_sme
 	__init_el2_fgt
 	__init_el2_nvhe_prepare_eret
 .endm
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:50 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:50 +0000
Subject: [PATCH v9 10/40] arm64/sme: Identify supported SME vector lengths at
 boot
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-11-broonie@kernel.org>

The vector lengths used for SME are controlled through a similar set of
registers to those for SVE and enumerated using a similar algorithm with
some slight differences due to the fact that unlike SVE there are no
restrictions on which combinations of vector lengths can be supported
nor any mandatory vector lengths which must be implemented.  Add a new
vector type and implement support for enumerating it.

One slightly awkward feature is that we need to read the current vector
length using a different instruction (or enter streaming mode which
would have the same issue and be higher cost).  Rather than add an ops
structure we add special cases directly in the otherwise generic
vec_probe_vqs() function, this is a bit inelegant but it's the only
place where this is an issue.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpu.h        |   3 +
 arch/arm64/include/asm/cpufeature.h |   7 ++
 arch/arm64/include/asm/fpsimd.h     |  26 ++++++
 arch/arm64/include/asm/processor.h  |   1 +
 arch/arm64/kernel/cpufeature.c      |  49 +++++++++++
 arch/arm64/kernel/cpuinfo.c         |   4 +
 arch/arm64/kernel/entry-fpsimd.S    |   9 ++
 arch/arm64/kernel/fpsimd.c          | 123 +++++++++++++++++++++++++++-
 8 files changed, 220 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index d08062bcb9c1..550e1fc4ae6c 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -64,6 +64,9 @@ struct cpuinfo_arm64 {
 
 	/* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */
 	u64		reg_zcr;
+
+	/* pseudo-SMCR for recording maximum ZCR_EL1 LEN value: */
+	u64		reg_smcr;
 };
 
 DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index f93b1442143f..9d36035acce3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -620,6 +620,13 @@ static inline bool id_aa64pfr0_sve(u64 pfr0)
 	return val > 0;
 }
 
+static inline bool id_aa64pfr1_sme(u64 pfr1)
+{
+	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_SME_SHIFT);
+
+	return val > 0;
+}
+
 static inline bool id_aa64pfr1_mte(u64 pfr1)
 {
 	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_MTE_SHIFT);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 6b7eb6f2cecd..8cb99b6fe565 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -78,6 +78,7 @@ extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
+extern u64 read_smcr_features(void);
 
 /*
  * Helpers to translate bit indices in sve_vq_map to VQ values (and
@@ -172,6 +173,12 @@ static inline void write_vl(enum vec_type type, u64 val)
 		tmp = read_sysreg_s(SYS_ZCR_EL1) & ~ZCR_ELx_LEN_MASK;
 		write_sysreg_s(tmp | val, SYS_ZCR_EL1);
 		break;
+#endif
+#ifdef CONFIG_ARM64_SME
+	case ARM64_VEC_SME:
+		tmp = read_sysreg_s(SYS_SMCR_EL1) & ~SMCR_ELx_LEN_MASK;
+		write_sysreg_s(tmp | val, SYS_SMCR_EL1);
+		break;
 #endif
 	default:
 		WARN_ON_ONCE(1);
@@ -268,12 +275,31 @@ static inline void sme_smstop(void)
 	asm volatile(".inst 0xd503467f");
 }
 
+extern void __init sme_setup(void);
+
+static inline int sme_max_vl(void)
+{
+	return vec_max_vl(ARM64_VEC_SME);
+}
+
+static inline int sme_max_virtualisable_vl(void)
+{
+	return vec_max_virtualisable_vl(ARM64_VEC_SME);
+}
+
+extern unsigned int sme_get_vl(void);
+
 #else
 
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_setup(void) { }
+static inline unsigned int sme_get_vl(void) { return 0; }
+static inline int sme_max_vl(void) { return 0; }
+static inline int sme_max_virtualisable_vl(void) { return 0; }
+
 #endif /* ! CONFIG_ARM64_SME */
 
 /* For use by EFI runtime services calls only */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..df68f0fb0ded 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -117,6 +117,7 @@ struct debug_info {
 
 enum vec_type {
 	ARM64_VEC_SVE = 0,
+	ARM64_VEC_SME,
 	ARM64_VEC_MAX,
 };
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 3cd7fe53cffa..1995ff72a8c6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -570,6 +570,12 @@ static const struct arm64_ftr_bits ftr_zcr[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_smcr[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
+		SMCR_ELx_LEN_SHIFT, SMCR_ELx_LEN_SIZE, 0),	/* LEN */
+	ARM64_FTR_END,
+};
+
 /*
  * Common ftr bits for a 32bit register with all hidden, strict
  * attributes, with 4bit feature fields and a default safe value of
@@ -673,6 +679,7 @@ static const struct __ftr_reg_entry {
 
 	/* Op1 = 0, CRn = 1, CRm = 2 */
 	ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
+	ARM64_FTR_REG(SYS_SMCR_EL1, ftr_smcr),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
 	ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -977,6 +984,14 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 		vec_init_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		init_cpu_ftr_reg(SYS_SMCR_EL1, info->reg_smcr);
+		if (IS_ENABLED(CONFIG_ARM64_SME)) {
+			sme_kernel_enable(NULL);
+			vec_init_vq_map(ARM64_VEC_SME);
+		}
+	}
+
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
 
@@ -1203,6 +1218,9 @@ void update_cpu_features(int cpu,
 	taint |= check_update_ftr_reg(SYS_ID_AA64ZFR0_EL1, cpu,
 				      info->reg_id_aa64zfr0, boot->reg_id_aa64zfr0);
 
+	taint |= check_update_ftr_reg(SYS_ID_AA64SMFR0_EL1, cpu,
+				      info->reg_id_aa64smfr0, boot->reg_id_aa64smfr0);
+
 	if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
 		taint |= check_update_ftr_reg(SYS_ZCR_EL1, cpu,
 					info->reg_zcr, boot->reg_zcr);
@@ -1213,6 +1231,16 @@ void update_cpu_features(int cpu,
 			vec_update_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		taint |= check_update_ftr_reg(SYS_SMCR_EL1, cpu,
+					info->reg_smcr, boot->reg_smcr);
+
+		/* Probe vector lengths, unless we already gave up on SME */
+		if (id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1)) &&
+		    !system_capabilities_finalized())
+			vec_update_vq_map(ARM64_VEC_SME);
+	}
+
 	/*
 	 * The kernel uses the LDGM/STGM instructions and the number of tags
 	 * they read/write depends on the GMID_EL1.BS field. Check that the
@@ -2878,6 +2906,23 @@ static void verify_sve_features(void)
 	/* Add checks on other ZCR bits here if necessary */
 }
 
+static void verify_sme_features(void)
+{
+	u64 safe_smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	u64 smcr = read_smcr_features();
+
+	unsigned int safe_len = safe_smcr & SMCR_ELx_LEN_MASK;
+	unsigned int len = smcr & SMCR_ELx_LEN_MASK;
+
+	if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SME)) {
+		pr_crit("CPU%d: SME: vector length support mismatch\n",
+			smp_processor_id());
+		cpu_die_early();
+	}
+
+	/* Add checks on other SMCR bits here if necessary */
+}
+
 static void verify_hyp_capabilities(void)
 {
 	u64 safe_mmfr1, mmfr0, mmfr1;
@@ -2930,6 +2975,9 @@ static void verify_local_cpu_capabilities(void)
 	if (system_supports_sve())
 		verify_sve_features();
 
+	if (system_supports_sme())
+		verify_sme_features();
+
 	if (is_hyp_mode_available())
 		verify_hyp_capabilities();
 }
@@ -3047,6 +3095,7 @@ void __init setup_cpu_features(void)
 		pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
 
 	sve_setup();
+	sme_setup();
 	minsigstksz_setup();
 
 	/* Advertise that we have computed the system capabilities */
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 33ec182e872e..72dc155719b0 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -420,6 +420,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	    id_aa64pfr0_sve(info->reg_id_aa64pfr0))
 		info->reg_zcr = read_zcr_features();
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1))
+		info->reg_smcr = read_smcr_features();
+
 	cpuinfo_detect_icache_policy(info);
 }
 
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index dc242e269f9a..deee5f01462e 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -86,3 +86,12 @@ SYM_FUNC_START(sve_flush_live)
 SYM_FUNC_END(sve_flush_live)
 
 #endif /* CONFIG_ARM64_SVE */
+
+#ifdef CONFIG_ARM64_SME
+
+SYM_FUNC_START(sme_get_vl)
+	_sme_rdsvl	0, 1
+	ret
+SYM_FUNC_END(sme_get_vl)
+
+#endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 576490be3c2b..3fb2167f8af7 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -136,6 +136,12 @@ __ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
 		.max_virtualisable_vl	= SVE_VL_MIN,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[ARM64_VEC_SME] = {
+		.type			= ARM64_VEC_SME,
+		.name			= "SME",
+	},
+#endif
 };
 
 static unsigned int vec_vl_inherit_flag(enum vec_type type)
@@ -186,6 +192,20 @@ extern void __percpu *efi_sve_state;
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int get_sme_default_vl(void)
+{
+	return get_default_vl(ARM64_VEC_SME);
+}
+
+static void set_sme_default_vl(int val)
+{
+	set_default_vl(ARM64_VEC_SME, val);
+}
+
+#endif
+
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
 EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
 
@@ -403,6 +423,8 @@ static unsigned int find_supported_vector_length(enum vec_type type,
 
 	if (vl > max_vl)
 		vl = max_vl;
+	if (vl < info->min_vl)
+		vl = info->min_vl;
 
 	bit = find_next_bit(info->vq_map, SVE_VQ_MAX,
 			    __vq_to_bit(sve_vq_from_vl(vl)));
@@ -764,7 +786,23 @@ static void vec_probe_vqs(struct vl_info *info,
 
 	for (vq = SVE_VQ_MAX; vq >= SVE_VQ_MIN; --vq) {
 		write_vl(info->type, vq - 1); /* self-syncing */
-		vl = sve_get_vl();
+
+		switch (info->type) {
+		case ARM64_VEC_SVE:
+			vl = sve_get_vl();
+			break;
+		case ARM64_VEC_SME:
+			vl = sme_get_vl();
+			break;
+		default:
+			vl = 0;
+			break;
+		}
+
+		/* Minimum VL identified? */
+		if (sve_vq_from_vl(vl) > vq)
+			break;
+
 		vq = sve_vq_from_vl(vl); /* skip intervening lengths */
 		set_bit(__vq_to_bit(vq), map);
 	}
@@ -1011,7 +1049,88 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 		       SYS_SMCR_EL1);
 }
 
-#endif /* CONFIG_ARM64_SVE */
+/*
+ * Read the pseudo-SMCR used by cpufeatures to identify the supported
+ * vector length.
+ *
+ * Use only if SME is present.
+ * This function clobbers the SME vector length.
+ */
+u64 read_smcr_features(void)
+{
+	u64 smcr;
+	unsigned int vq_max;
+
+	sme_kernel_enable(NULL);
+	sme_smstart_sm();
+
+	/*
+	 * Set the maximum possible VL.
+	 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
+		       SYS_SMCR_EL1);
+
+	smcr = read_sysreg_s(SYS_SMCR_EL1);
+	smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */
+	vq_max = sve_vq_from_vl(sve_get_vl());
+	smcr |= vq_max - 1; /* set LEN field to maximum effective value */
+
+	sme_smstop_sm();
+
+	return smcr;
+}
+
+void __init sme_setup(void)
+{
+	struct vl_info *info = &vl_info[ARM64_VEC_SME];
+	u64 smcr;
+	int min_bit;
+
+	if (!system_supports_sme())
+		return;
+
+	/*
+	 * SME doesn't require any particular vector length be
+	 * supported but it does require at least one.  We should have
+	 * disabled the feature entirely while bringing up CPUs but
+	 * let's double check here.
+	 */
+	WARN_ON(bitmap_empty(info->vq_map, SVE_VQ_MAX));
+
+	min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);
+	info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));
+
+	smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	info->max_vl = sve_vl_from_vq((smcr & SMCR_ELx_LEN_MASK) + 1);
+
+	/*
+	 * Sanity-check that the max VL we determined through CPU features
+	 * corresponds properly to sme_vq_map.  If not, do our best:
+	 */
+	if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SME,
+								 info->max_vl)))
+		info->max_vl = find_supported_vector_length(ARM64_VEC_SME,
+							    info->max_vl);
+
+	WARN_ON(info->min_vl > info->max_vl);
+
+	/*
+	 * For the default VL, pick the maximum supported value <= 32
+	 * (256 bits) if there is one since this is guaranteed not to
+	 * grow the signal frame when in streaming mode, otherwise the
+	 * minimum available VL will be used.
+	 */
+	set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));
+
+	pr_info("SME: minimum available vector length %u bytes per vector\n",
+		info->min_vl);
+	pr_info("SME: maximum available vector length %u bytes per vector\n",
+		info->max_vl);
+	pr_info("SME: default vector length %u bytes per vector\n",
+		get_sme_default_vl());
+}
+
+#endif /* CONFIG_ARM64_SME */
 
 /*
  * Trapped SVE access
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:51 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:51 +0000
Subject: [PATCH v9 11/40] arm64/sme: Implement sysctl to set the default
 vector length
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-12-broonie@kernel.org>

As for SVE provide a sysctl which allows the default SME vector length to
be configured.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 3fb2167f8af7..841b9609342f 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -483,6 +483,30 @@ static int __init sve_sysctl_init(void)
 static int __init sve_sysctl_init(void) { return 0; }
 #endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
 
+#if defined(CONFIG_ARM64_SME) && defined(CONFIG_SYSCTL)
+static struct ctl_table sme_default_vl_table[] = {
+	{
+		.procname	= "sme_default_vector_length",
+		.mode		= 0644,
+		.proc_handler	= vec_proc_do_default_vl,
+		.extra1		= &vl_info[ARM64_VEC_SME],
+	},
+	{ }
+};
+
+static int __init sme_sysctl_init(void)
+{
+	if (system_supports_sme())
+		if (!register_sysctl("abi", sme_default_vl_table))
+			return -EINVAL;
+
+	return 0;
+}
+
+#else /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+static int __init sme_sysctl_init(void) { return 0; }
+#endif /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+
 #define ZREG(sve_state, vq, n) ((char *)(sve_state) +		\
 	(SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
 
@@ -1681,6 +1705,9 @@ static int __init fpsimd_init(void)
 	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
 		pr_notice("SME is implemented but not SVE\n");
 
-	return sve_sysctl_init();
+	sve_sysctl_init();
+	sme_sysctl_init();
+
+	return 0;
 }
 core_initcall(fpsimd_init);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:52 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:52 +0000
Subject: [PATCH v9 12/40] arm64/sme: Implement vector length configuration
 prctl()s
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-13-broonie@kernel.org>

As for SVE provide a prctl() interface which allows processes to
configure their SME vector length.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  4 ++++
 arch/arm64/include/asm/processor.h   |  4 +++-
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 32 ++++++++++++++++++++++++++++
 include/uapi/linux/prctl.h           |  9 ++++++++
 kernel/sys.c                         | 12 +++++++++++
 6 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 8cb99b6fe565..babf944e7c0c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
 }
 
 extern unsigned int sme_get_vl(void);
+extern int sme_set_current_vl(unsigned long arg);
+extern int sme_get_current_vl(void);
 
 #else
 
@@ -299,6 +301,8 @@ static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
 static inline int sme_max_virtualisable_vl(void) { return 0; }
+static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
+static inline int sme_get_current_vl(void) { return -EINVAL; }
 
 #endif /* ! CONFIG_ARM64_SME */
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index df68f0fb0ded..f2c2ebd440e2 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -354,9 +354,11 @@ extern void __init minsigstksz_setup(void);
  */
 #include <asm/fpsimd.h>
 
-/* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */
+/* Userspace interface for PR_S[MV]E_{SET,GET}_VL prctl()s: */
 #define SVE_SET_VL(arg)	sve_set_current_vl(arg)
 #define SVE_GET_VL()	sve_get_current_vl()
+#define SME_SET_VL(arg)	sme_set_current_vl(arg)
+#define SME_GET_VL()	sme_get_current_vl()
 
 /* PR_PAC_RESET_KEYS prctl */
 #define PAC_RESET_KEYS(tsk, arg)	ptrauth_prctl_reset_keys(tsk, arg)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index e1317b7c4525..4e6b58dcd6f9 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 841b9609342f..1edb3996f9cf 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
 	switch (type) {
 	case ARM64_VEC_SVE:
 		return TIF_SVE_VL_INHERIT;
+	case ARM64_VEC_SME:
+		return TIF_SME_VL_INHERIT;
 	default:
 		WARN_ON_ONCE(1);
 		return 0;
@@ -801,6 +803,36 @@ int sve_get_current_vl(void)
 	return vec_prctl_status(ARM64_VEC_SVE, 0);
 }
 
+#ifdef CONFIG_ARM64_SME
+/* PR_SME_SET_VL */
+int sme_set_current_vl(unsigned long arg)
+{
+	unsigned long vl, flags;
+	int ret;
+
+	vl = arg & PR_SME_VL_LEN_MASK;
+	flags = arg & ~vl;
+
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
+	if (ret)
+		return ret;
+
+	return vec_prctl_status(ARM64_VEC_SME, flags);
+}
+
+/* PR_SME_GET_VL */
+int sme_get_current_vl(void)
+{
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	return vec_prctl_status(ARM64_VEC_SME, 0);
+}
+#endif /* CONFIG_ARM64_SME */
+
 static void vec_probe_vqs(struct vl_info *info,
 			  DECLARE_BITMAP(map, SVE_VQ_MAX))
 {
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index e998764f0262..a5e06dcbba13 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -272,6 +272,15 @@ struct prctl_mm_map {
 # define PR_SCHED_CORE_SCOPE_THREAD_GROUP	1
 # define PR_SCHED_CORE_SCOPE_PROCESS_GROUP	2
 
+/* arm64 Scalable Matrix Extension controls */
+/* Flag values must be in sync with SVE versions */
+#define PR_SME_SET_VL			63	/* set task vector length */
+# define PR_SME_SET_VL_ONEXEC		(1 << 18) /* defer effect until exec */
+#define PR_SME_GET_VL			64	/* get task vector length */
+/* Bits common to PR_SME_SET_VL and PR_SME_GET_VL */
+# define PR_SME_VL_LEN_MASK		0xffff
+# define PR_SME_VL_INHERIT		(1 << 17) /* inherit across exec */
+
 #define PR_SET_VMA		0x53564d41
 # define PR_SET_VMA_ANON_NAME		0
 
diff --git a/kernel/sys.c b/kernel/sys.c
index ecc4cf019242..5cd4fffc7cd0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -116,6 +116,12 @@
 #ifndef SVE_GET_VL
 # define SVE_GET_VL()		(-EINVAL)
 #endif
+#ifndef SME_SET_VL
+# define SME_SET_VL(a)		(-EINVAL)
+#endif
+#ifndef SME_GET_VL
+# define SME_GET_VL()		(-EINVAL)
+#endif
 #ifndef PAC_RESET_KEYS
 # define PAC_RESET_KEYS(a, b)	(-EINVAL)
 #endif
@@ -2523,6 +2529,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_SVE_GET_VL:
 		error = SVE_GET_VL();
 		break;
+	case PR_SME_SET_VL:
+		error = SME_SET_VL(arg2);
+		break;
+	case PR_SME_GET_VL:
+		error = SME_GET_VL();
+		break;
 	case PR_GET_SPECULATION_CTRL:
 		if (arg3 || arg4 || arg5)
 			return -EINVAL;
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:53 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:53 +0000
Subject: [PATCH v9 13/40] arm64/sme: Implement support for TPIDR2
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-14-broonie@kernel.org>

The Scalable Matrix Extension introduces support for a new thread specific
data register TPIDR2 intended for use by libc. The kernel must save the
value of TPIDR2 on context switch and should ensure that all new threads
start off with a default value of 0. Add a field to the thread_struct to
store TPIDR2 and context switch it with the other thread specific data.

In case there are future extensions which also use TPIDR2 we introduce
system_supports_tpidr2() and use that rather than system_supports_sme()
for TPIDR2 handling.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  5 +++++
 arch/arm64/include/asm/processor.h  |  1 +
 arch/arm64/kernel/fpsimd.c          |  4 ++++
 arch/arm64/kernel/process.c         | 14 ++++++++++++--
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9d36035acce3..12252352d2ee 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -747,6 +747,11 @@ static __always_inline bool system_supports_fa64(void)
 		cpus_have_const_cap(ARM64_SME_FA64);
 }
 
+static __always_inline bool system_supports_tpidr2(void)
+{
+	return system_supports_sme();
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index f2c2ebd440e2..008a1767ebff 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			tpidr2_el0;
 };
 
 static inline unsigned int thread_get_vl(struct thread_struct *thread,
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 1edb3996f9cf..40ef89120774 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1092,6 +1092,10 @@ void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 	/* Allow SME in kernel */
 	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
 	isb();
+
+	/* Allow EL0 to access TPIDR2 */
+	write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
+	isb();
 }
 
 /*
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..e69a3dcdb0d9 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -250,6 +250,8 @@ void show_regs(struct pt_regs *regs)
 static void tls_thread_flush(void)
 {
 	write_sysreg(0, tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(0, SYS_TPIDR2_EL0);
 
 	if (is_compat_task()) {
 		current->thread.uw.tp_value = 0;
@@ -343,6 +345,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 		 * out-of-sync with the saved value.
 		 */
 		*task_user_tls(p) = read_sysreg(tpidr_el0);
+		if (system_supports_tpidr2())
+			p->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 
 		if (stack_start) {
 			if (is_compat_thread(task_thread_info(p)))
@@ -353,10 +357,12 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 		/*
 		 * If a TLS pointer was passed to clone, use it for the new
-		 * thread.
+		 * thread.  We also reset TPIDR2 if it's in use.
 		 */
-		if (clone_flags & CLONE_SETTLS)
+		if (clone_flags & CLONE_SETTLS) {
 			p->thread.uw.tp_value = tls;
+			p->thread.tpidr2_el0 = 0;
+		}
 	} else {
 		/*
 		 * A kthread has no context to ERET to, so ensure any buggy
@@ -387,6 +393,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 void tls_preserve_current_state(void)
 {
 	*task_user_tls(current) = read_sysreg(tpidr_el0);
+	if (system_supports_tpidr2() && !is_compat_task())
+		current->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 }
 
 static void tls_thread_switch(struct task_struct *next)
@@ -399,6 +407,8 @@ static void tls_thread_switch(struct task_struct *next)
 		write_sysreg(0, tpidrro_el0);
 
 	write_sysreg(*task_user_tls(next), tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(next->thread.tpidr2_el0, SYS_TPIDR2_EL0);
 }
 
 /*
-- 
2.30.2



From drjones at redhat.com  Wed Jan 26 07:12:27 2022
From: drjones at redhat.com (Andrew Jones)
Date: Wed, 26 Jan 2022 16:12:27 +0100
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220126145242.3473836-1-broonie@kernel.org>
References: <20220126145242.3473836-1-broonie@kernel.org>
Message-ID: <20220126151227.jlhb5o32jwal24m6@gator>

On Wed, Jan 26, 2022 at 02:52:42PM +0000, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> 
> v3:
>  - Use custom print_skip() helper.
>  - Use internal version of _kvm_create_device.
> v2:
>  - The test for being able to create the GIC doesn't actually
>    instantiate it, add a call doing so in that case.
> 
>  tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
>  tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>  3 files changed, 13 insertions(+), 2 deletions(-)
>

 
Reviewed-by: Andrew Jones <drjones at redhat.com>



From broonie at kernel.org  Wed Jan 26 07:10:54 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:54 +0000
Subject: [PATCH v9 14/40] arm64/sme: Implement SVCR context switching
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-15-broonie@kernel.org>

In SME the use of both streaming SVE mode and ZA are tracked through
PSTATE.SM and PSTATE.ZA, visible through the system register SVCR.  In
order to context switch the floating point state for SME we need to
context switch the contents of this register as part of context
switching the floating point state.

Since changing the vector length exits streaming SVE mode and disables
ZA we also make sure we update SVCR appropriately when setting vector
length, and similarly ensure that new threads have streaming SVE mode
and ZA disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  3 ++-
 arch/arm64/include/asm/processor.h   |  1 +
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 18 +++++++++++++++++-
 arch/arm64/kernel/process.c          |  2 ++
 arch/arm64/kvm/fpsimd.c              |  4 ++++
 6 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index babf944e7c0c..d1bae65d3dba 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -46,7 +46,8 @@ extern void fpsimd_restore_current_state(void);
 extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
-				     void *sve_state, unsigned int sve_vl);
+				     void *sve_state, unsigned int sve_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 008a1767ebff..7e08a4d48c24 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			svcr;
 	u64			tpidr2_el0;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 4e6b58dcd6f9..848739c15de8 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME			27	/* SME in use */
 #define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 40ef89120774..a1918b71d335 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	u64 *svcr;
 	unsigned int sve_vl;
 };
 
@@ -359,6 +360,9 @@ static void task_fpsimd_load(void)
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
 		sve_load_state(sve_pffr(&current->thread),
@@ -384,6 +388,12 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    test_thread_flag(TIF_SME)) {
+		u64 *svcr = last->svcr;
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+	}
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
 	    test_thread_flag(TIF_SVE)) {
 		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
@@ -735,6 +745,10 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
 		sve_to_fpsimd(task);
 
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
+				       SYS_SVCR_EL0_ZA_MASK);
+
 	if (task == current)
 		put_cpu_fpsimd_context();
 
@@ -1398,6 +1412,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
 	if (system_supports_sve()) {
@@ -1412,7 +1427,7 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl)
+			      unsigned int sve_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1421,6 +1436,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	WARN_ON(!in_softirq() && !irqs_disabled());
 
 	last->st = st;
+	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
 }
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index e69a3dcdb0d9..f2d32a29641c 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -310,6 +310,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.svcr = 0;
+
 	/* clear any pending asynchronous tag fault raised by the parent */
 	clear_tsk_thread_flag(dst, TIF_MTE_ASYNC_FAULT);
 
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 2f48fd362a8c..04698c4bcd30 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -103,6 +103,10 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
+		/*
+		 * Currently we do not support SME guests so SVCR is
+		 * always 0 and we just need a variable to point to.
+		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:55 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:55 +0000
Subject: [PATCH v9 15/40] arm64/sme: Implement streaming SVE context switching
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-16-broonie@kernel.org>

When in streaming mode we need to save and restore the streaming mode
SVE register state rather than the regular SVE register state. This uses
the streaming mode vector length and omits FFR but is otherwise identical,
if TIF_SVE is enabled when we are in streaming mode then streaming mode
takes precedence.

This does not handle use of streaming SVE state with KVM, ptrace or
signals. This will be updated in further patches.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  22 +++++-
 arch/arm64/include/asm/fpsimdmacros.h |  11 +++
 arch/arm64/include/asm/processor.h    |  10 +++
 arch/arm64/kernel/entry-fpsimd.S      |   5 ++
 arch/arm64/kernel/fpsimd.c            | 109 +++++++++++++++++++++-----
 arch/arm64/kvm/fpsimd.c               |   3 +-
 6 files changed, 137 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index d1bae65d3dba..650ec642159c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,11 +47,21 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     u64 *svcr);
+				     unsigned int sme_vl, u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
 
+static inline bool thread_sm_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_SM_MASK);
+}
+
+static inline bool thread_za_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_ZA_MASK);
+}
+
 /* Maximum VL that SVE/SME VL-agnostic software can transparently support */
 #define VL_ARCH_MAX 0x100
 
@@ -63,7 +73,14 @@ static inline size_t sve_ffr_offset(int vl)
 
 static inline void *sve_pffr(struct thread_struct *thread)
 {
-	return (char *)thread->sve_state + sve_ffr_offset(thread_get_sve_vl(thread));
+	unsigned int vl;
+
+	if (system_supports_sme() && thread_sm_enabled(thread))
+		vl = thread_get_sme_vl(thread);
+	else
+		vl = thread_get_sve_vl(thread);
+
+	return (char *)thread->sve_state + sve_ffr_offset(vl);
 }
 
 extern void sve_save_state(void *state, u32 *pfpsr, int save_ffr);
@@ -72,6 +89,7 @@ extern void sve_load_state(void const *state, u32 const *pfpsr,
 extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
+extern void sme_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 11c426ddd62c..a50fa1eab730 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -261,6 +261,17 @@
 921:
 .endm
 
+/* Update SMCR_EL1.LEN with the new VQ */
+.macro sme_load_vq xvqminus1, xtmp, xtmp2
+		mrs_s		\xtmp, SYS_SMCR_EL1
+		bic		\xtmp2, \xtmp, SMCR_ELx_LEN_MASK
+		orr		\xtmp2, \xtmp2, \xvqminus1
+		cmp		\xtmp2, \xtmp
+		b.eq		921f
+		msr_s		SYS_SMCR_EL1, \xtmp2	//self-synchronising
+921:
+.endm
+
 /* Preserve the first 128-bits of Znz and zero the rest. */
 .macro _sve_flush_z nz
 	_sve_check_zreg \nz
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 7e08a4d48c24..6e2af9de153c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -183,6 +183,11 @@ static inline unsigned int thread_get_sve_vl(struct thread_struct *thread)
 	return thread_get_vl(thread, ARM64_VEC_SVE);
 }
 
+static inline unsigned int thread_get_sme_vl(struct thread_struct *thread)
+{
+	return thread_get_vl(thread, ARM64_VEC_SME);
+}
+
 unsigned int task_get_vl(const struct task_struct *task, enum vec_type type);
 void task_set_vl(struct task_struct *task, enum vec_type type,
 		 unsigned long vl);
@@ -196,6 +201,11 @@ static inline unsigned int task_get_sve_vl(const struct task_struct *task)
 	return task_get_vl(task, ARM64_VEC_SVE);
 }
 
+static inline unsigned int task_get_sme_vl(const struct task_struct *task)
+{
+	return task_get_vl(task, ARM64_VEC_SME);
+}
+
 static inline void task_set_sve_vl(struct task_struct *task, unsigned long vl)
 {
 	task_set_vl(task, ARM64_VEC_SVE, vl);
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index deee5f01462e..6f88c0f86d50 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -94,4 +94,9 @@ SYM_FUNC_START(sme_get_vl)
 	ret
 SYM_FUNC_END(sme_get_vl)
 
+SYM_FUNC_START(sme_set_vq)
+	sme_load_vq x0, x1, x2
+	ret
+SYM_FUNC_END(sme_set_vq)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a1918b71d335..12fef62cf07a 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -123,6 +123,7 @@ struct fpsimd_last_state_struct {
 	void *sve_state;
 	u64 *svcr;
 	unsigned int sve_vl;
+	unsigned int sme_vl;
 };
 
 static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
@@ -301,17 +302,28 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
 	task->thread.vl_onexec[type] = vl;
 }
 
+/*
+ * TIF_SME controls whether a task can use SME without trapping while
+ * in userspace, when TIF_SME is set then we must have storage
+ * alocated in sve_state and za_state to store the contents of both ZA
+ * and the SVE registers for both streaming and non-streaming modes.
+ *
+ * If both SVCR.ZA and SVCR.SM are disabled then at any point we
+ * may disable TIF_SME and reenable traps.
+ */
+
+
 /*
  * TIF_SVE controls whether a task can use SVE without trapping while
- * in userspace, and also the way a task's FPSIMD/SVE state is stored
- * in thread_struct.
+ * in userspace, and also (together with TIF_SME) the way a task's
+ * FPSIMD/SVE state is stored in thread_struct.
  *
  * The kernel uses this flag to track whether a user task is actively
  * using SVE, and therefore whether full SVE register state needs to
  * be tracked.  If not, the cheaper FPSIMD context handling code can
  * be used instead of the more costly SVE equivalents.
  *
- *  * TIF_SVE set:
+ *  * TIF_SVE or SVCR.SM set:
  *
  *    The task can execute SVE instructions while in userspace without
  *    trapping to the kernel.
@@ -319,7 +331,8 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  *    When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
  *    corresponding Zn), P0-P15 and FFR are encoded in in
  *    task->thread.sve_state, formatted appropriately for vector
- *    length task->thread.sve_vl.
+ *    length task->thread.sve_vl or, if SVCR.SM is set,
+ *    task->thread.sme_vl.
  *
  *    task->thread.sve_state must point to a valid buffer at least
  *    sve_state_size(task) bytes in size.
@@ -357,19 +370,40 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  */
 static void task_fpsimd_load(void)
 {
+	bool restore_sve_regs = false;
+	bool restore_ffr;
+
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
-		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
-
+	/* Check if we should restore SVE first */
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
+		restore_sve_regs = true;
+		restore_ffr = true;
+	}
+
+	/* Restore SME, override SVE register configuration if needed */
+	if (system_supports_sme()) {
+		unsigned long sme_vl = task_get_sme_vl(current);
+
+		if (test_thread_flag(TIF_SME))
+			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
+
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
+		if (thread_sm_enabled(&current->thread)) {
+			restore_sve_regs = true;
+			restore_ffr = system_supports_fa64();
+		}
+	}
+
+	if (restore_sve_regs)
 		sve_load_state(sve_pffr(&current->thread),
-			       &current->thread.uw.fpsimd_state.fpsr, true);
-	} else {
+			       &current->thread.uw.fpsimd_state.fpsr,
+			       restore_ffr);
+	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
-	}
 }
 
 /*
@@ -381,6 +415,9 @@ static void fpsimd_save(void)
 	struct fpsimd_last_state_struct const *last =
 		this_cpu_ptr(&fpsimd_last_state);
 	/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
+	bool save_sve_regs = false;
+	bool save_ffr;
+	unsigned int vl;
 
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
@@ -388,15 +425,33 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) &&
-	    test_thread_flag(TIF_SME)) {
+	if (test_thread_flag(TIF_SVE)) {
+		save_sve_regs = true;
+		save_ffr = true;
+		vl = last->sve_vl;
+	}
+
+	if (system_supports_sme()) {
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (thread_za_enabled(&current->thread)) {
+			/* ZA state managment is not implemented yet */
+			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
+			return;
+		}
+
+		/* If we are in streaming mode override regular SVE. */
+		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
+			save_sve_regs = true;
+			save_ffr = system_supports_fa64();
+			vl = last->sme_vl;
+		}
 	}
 
-	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
-	    test_thread_flag(TIF_SVE)) {
-		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
+	if (IS_ENABLED(CONFIG_ARM64_SVE) && save_sve_regs) {
+		/* Get the configured VL from RDVL, will account for SM */
+		if (WARN_ON(sve_get_vl() != vl)) {
 			/*
 			 * Can't save the user regs, so current would
 			 * re-enter user with corrupt state.
@@ -407,8 +462,8 @@ static void fpsimd_save(void)
 		}
 
 		sve_save_state((char *)last->sve_state +
-					sve_ffr_offset(last->sve_vl),
-			       &last->st->fpsr, true);
+					sve_ffr_offset(vl),
+			       &last->st->fpsr, save_ffr);
 	} else {
 		fpsimd_save_state(last->st);
 	}
@@ -613,7 +668,14 @@ static void sve_to_fpsimd(struct task_struct *task)
  */
 static size_t sve_state_size(struct task_struct const *task)
 {
-	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(task_get_sve_vl(task)));
+	unsigned int vl = 0;
+
+	if (system_supports_sve())
+		vl = task_get_sve_vl(task);
+	if (system_supports_sme())
+		vl = max(vl, task_get_sme_vl(task));
+
+	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl));
 }
 
 /*
@@ -742,7 +804,8 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	}
 
 	fpsimd_flush_task_state(task);
-	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
+	if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
+	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
 	if (system_supports_sme() && type == ARM64_VEC_SME)
@@ -1369,6 +1432,9 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
+	if (system_supports_sme())
+		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1412,6 +1478,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
@@ -1427,7 +1494,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, u64 *svcr)
+			      unsigned int sve_vl, unsigned int sme_vl,
+			      u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1439,6 +1507,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
+	last->sme_vl = sme_vl;
 }
 
 /*
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 04698c4bcd30..902c598b7ed2 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -109,7 +109,8 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
-					 vcpu->arch.sve_max_vl);
+					 vcpu->arch.sve_max_vl,
+					 0);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:56 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:56 +0000
Subject: [PATCH v9 16/40] arm64/sme: Implement ZA context switching
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-17-broonie@kernel.org>

Allocate space for storing ZA on first access to SME and use that to save
and restore ZA state when context switching. We do this by using the vector
form of the LDR and STR ZA instructions, these do not require streaming
mode and have implementation recommendations that they avoid contention
issues in shared SMCU implementations.

Since ZA is architecturally guaranteed to be zeroed when enabled we do not
need to explicitly zero ZA, either we will be restoring from a saved copy
or trapping on first use of SME so we know that ZA must be disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  5 ++++-
 arch/arm64/include/asm/fpsimdmacros.h | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/kvm_host.h     |  3 +++
 arch/arm64/include/asm/processor.h    |  1 +
 arch/arm64/kernel/entry-fpsimd.S      | 22 ++++++++++++++++++++++
 arch/arm64/kernel/fpsimd.c            | 20 +++++++++++++-------
 arch/arm64/kvm/fpsimd.c               |  2 +-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 650ec642159c..af404e5b8d82 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,7 +47,8 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     unsigned int sme_vl, u64 *svcr);
+				     void *za_state, unsigned int sme_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
@@ -90,6 +91,8 @@ extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
 extern void sme_set_vq(unsigned long vq_minus_1);
+extern void za_save_state(void *state);
+extern void za_load_state(void const *state);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index a50fa1eab730..35d67e393519 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -318,3 +318,25 @@
 		ldr		w\nxtmp, [\xpfpsr, #4]
 		msr		fpcr, x\nxtmp
 .endm
+
+.macro sme_save_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_str_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
+
+.macro sme_load_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_ldr_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..7dc85d5a6552 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -280,8 +280,11 @@ struct vcpu_reset_state {
 
 struct kvm_vcpu_arch {
 	struct kvm_cpu_context ctxt;
+
+	/* Guest floating point state */
 	void *sve_state;
 	unsigned int sve_max_vl;
+	u64 svcr;
 
 	/* Stage 2 paging state used by the hardware on next switch */
 	struct kvm_s2_mmu *hw_mmu;
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6e2af9de153c..5a5c5edd76df 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -153,6 +153,7 @@ struct thread_struct {
 
 	unsigned int		fpsimd_cpu;
 	void			*sve_state;	/* SVE registers, if any */
+	void			*za_state;	/* ZA register, if any */
 	unsigned int		vl[ARM64_VEC_MAX];	/* vector length */
 	unsigned int		vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */
 	unsigned long		fault_address;	/* fault info */
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index 6f88c0f86d50..229436f33df5 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -99,4 +99,26 @@ SYM_FUNC_START(sme_set_vq)
 	ret
 SYM_FUNC_END(sme_set_vq)
 
+/*
+ * Save the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_save_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_save_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_save_state)
+
+/*
+ * Load the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_load_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_load_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_load_state)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 12fef62cf07a..c9e8186e69c0 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	void *za_state;
 	u64 *svcr;
 	unsigned int sve_vl;
 	unsigned int sme_vl;
@@ -387,11 +388,15 @@ static void task_fpsimd_load(void)
 	if (system_supports_sme()) {
 		unsigned long sme_vl = task_get_sme_vl(current);
 
+		/* Ensure VL is set up for restoring data */
 		if (test_thread_flag(TIF_SME))
 			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
 
 		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
 
+		if (thread_za_enabled(&current->thread))
+			za_load_state(current->thread.za_state);
+
 		if (thread_sm_enabled(&current->thread)) {
 			restore_sve_regs = true;
 			restore_ffr = system_supports_fa64();
@@ -435,11 +440,10 @@ static void fpsimd_save(void)
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
 
-		if (thread_za_enabled(&current->thread)) {
-			/* ZA state managment is not implemented yet */
-			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
-			return;
-		}
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (*svcr & SYS_SVCR_EL0_ZA_MASK)
+			za_save_state(last->za_state);
 
 		/* If we are in streaming mode override regular SVE. */
 		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
@@ -1477,6 +1481,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	WARN_ON(!system_supports_fpsimd());
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
+	last->za_state = current->thread.za_state;
 	last->sve_vl = task_get_sve_vl(current);
 	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
@@ -1494,8 +1499,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, unsigned int sme_vl,
-			      u64 *svcr)
+			      unsigned int sve_vl, void *za_state,
+			      unsigned int sme_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1506,6 +1511,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->st = st;
 	last->svcr = svcr;
 	last->sve_state = sve_state;
+	last->za_state = za_state;
 	last->sve_vl = sve_vl;
 	last->sme_vl = sme_vl;
 }
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 902c598b7ed2..338733ac63f8 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -110,7 +110,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl,
-					 0);
+					 NULL, 0, &vcpu->arch.svcr);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:57 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:57 +0000
Subject: [PATCH v9 17/40] arm64/sme: Implement traps and syscall handling for
 SME
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-18-broonie@kernel.org>

By default all SME operations in userspace will trap.  When this happens
we allocate storage space for the SME register state, set up the SVE
registers and disable traps.  We do not need to initialize ZA since the
architecture guarantees that it will be zeroed when enabled and when we
trap ZA is disabled.

On syscall we exit streaming mode if we were previously in it and ensure
that all but the lower 128 bits of the registers are zeroed while
preserving the state of ZA. This follows the aarch64 PCS for SME, ZA
state is preserved over a function call and streaming mode is exited.
Since the traps for SME do not distinguish between streaming mode SVE
and ZA usage if ZA is in use rather than reenabling traps we instead
zero the parts of the SVE registers not shared with FPSIMD and leave SME
enabled, this simplifies handling SME traps. If ZA is not in use then we
reenable SME traps and fall through to normal handling of SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h       |   1 +
 arch/arm64/include/asm/exception.h |   1 +
 arch/arm64/include/asm/fpsimd.h    |  27 +++++
 arch/arm64/kernel/entry-common.c   |  11 ++
 arch/arm64/kernel/fpsimd.c         | 180 ++++++++++++++++++++++++++---
 arch/arm64/kernel/process.c        |  12 +-
 arch/arm64/kernel/syscall.c        |  34 +++++-
 7 files changed, 242 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 43872e0cfd1e..0467837fd66b 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -76,6 +76,7 @@
 #define ESR_ELx_IL_SHIFT	(25)
 #define ESR_ELx_IL		(UL(1) << ESR_ELx_IL_SHIFT)
 #define ESR_ELx_ISS_MASK	(ESR_ELx_IL - 1)
+#define ESR_ELx_ISS(esr)	((esr) & ESR_ELx_ISS_MASK)
 
 /* ISS field definitions shared by different classes */
 #define ESR_ELx_WNR_SHIFT	(6)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 339477dca551..2add7f33b7c2 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -64,6 +64,7 @@ void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr,
 			struct pt_regs *regs);
 void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs);
 void do_sve_acc(unsigned int esr, struct pt_regs *regs);
+void do_sme_acc(unsigned int esr, struct pt_regs *regs);
 void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs);
 void do_sysinstr(unsigned int esr, struct pt_regs *regs);
 void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index af404e5b8d82..3ca152aaf7c9 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -282,6 +282,16 @@ static inline void sve_setup(void) { }
 
 #ifdef CONFIG_ARM64_SME
 
+static inline void sme_user_disable(void)
+{
+	sysreg_clear_set(cpacr_el1, CPACR_EL1_SMEN_EL0EN, 0);
+}
+
+static inline void sme_user_enable(void)
+{
+	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_SMEN_EL0EN);
+}
+
 static inline void sme_smstart_sm(void)
 {
 	asm volatile(".inst 0xd503437f");
@@ -309,16 +319,33 @@ static inline int sme_max_virtualisable_vl(void)
 	return vec_max_virtualisable_vl(ARM64_VEC_SME);
 }
 
+extern void sme_alloc(struct task_struct *task);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
 
+/*
+ * Return how many bytes of memory are required to store the full SME
+ * specific state (currently just ZA) for task, given task's currently
+ * configured vector length.
+ */
+static inline size_t za_state_size(struct task_struct const *task)
+{
+	unsigned int vl = task_get_sme_vl(task);
+
+	return ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));
+}
+
 #else
 
+static inline void sme_user_disable(void) { BUILD_BUG(); }
+static inline void sme_user_enable(void) { BUILD_BUG(); }
+
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_alloc(struct task_struct *task) { }
 static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..b2ad525d6c87 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -524,6 +524,14 @@ static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
 	exit_to_user_mode(regs);
 }
 
+static void noinstr el0_sme_acc(struct pt_regs *regs, unsigned long esr)
+{
+	enter_from_user_mode(regs);
+	local_daif_restore(DAIF_PROCCTX);
+	do_sme_acc(esr, regs);
+	exit_to_user_mode(regs);
+}
+
 static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
 {
 	enter_from_user_mode(regs);
@@ -632,6 +640,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 	case ESR_ELx_EC_SVE:
 		el0_sve_acc(regs, esr);
 		break;
+	case ESR_ELx_EC_SME:
+		el0_sme_acc(regs, esr);
+		break;
 	case ESR_ELx_EC_FP_EXC64:
 		el0_fpsimd_exc(regs, esr);
 		break;
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c9e8186e69c0..33f80512753d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -209,6 +209,12 @@ static void set_sme_default_vl(int val)
 	set_default_vl(ARM64_VEC_SME, val);
 }
 
+static void sme_free(struct task_struct *);
+
+#else
+
+static inline void sme_free(struct task_struct *t) { }
+
 #endif
 
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
@@ -409,6 +415,21 @@ static void task_fpsimd_load(void)
 			       restore_ffr);
 	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
+
+	/*
+	 * If we didn't set up any SVE registers but we do have SME
+	 * enabled for userspace then ensure the SVE registers are
+	 * flushed since userspace can switch to streaming mode and
+	 * view the register state without trapping.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME) &&
+	    !restore_sve_regs) {
+		int sve_vq_minus_one;
+
+		sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(sve_vq_minus_one);
+		sve_flush_live(true, sve_vq_minus_one);
+	}
 }
 
 /*
@@ -812,18 +833,22 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
-	if (system_supports_sme() && type == ARM64_VEC_SME)
+	if (system_supports_sme() && type == ARM64_VEC_SME) {
 		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
 				       SYS_SVCR_EL0_ZA_MASK);
+		clear_thread_flag(TIF_SME);
+	}
 
 	if (task == current)
 		put_cpu_fpsimd_context();
 
 	/*
-	 * Force reallocation of task SVE state to the correct size
-	 * on next use:
+	 * Force reallocation of task SVE and SME state to the correct
+	 * size on next use:
 	 */
 	sve_free(task);
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		sme_free(task);
 
 	task_set_vl(task, type, vl);
 
@@ -1158,12 +1183,43 @@ void __init sve_setup(void)
 void fpsimd_release_task(struct task_struct *dead_task)
 {
 	__sve_free(dead_task);
+	sme_free(dead_task);
 }
 
 #endif /* CONFIG_ARM64_SVE */
 
 #ifdef CONFIG_ARM64_SME
 
+/* This will move to uapi/asm/sigcontext.h when signals are implemented */
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+/*
+ * Ensure that task->thread.za_state is allocated and sufficiently large.
+ *
+ * This function should be used only in preparation for replacing
+ * task->thread.za_state with new data.  The memory is always zeroed
+ * here to prevent stale data from showing through: this is done in
+ * the interest of testability and predictability, the architecture
+ * guarantees that when ZA is enabled it will be zeroed.
+ */
+void sme_alloc(struct task_struct *task)
+{
+	if (task->thread.za_state) {
+		memset(task->thread.za_state, 0, za_state_size(task));
+		return;
+	}
+
+	/* This could potentially be up to 64K. */
+	task->thread.za_state =
+		kzalloc(za_state_size(task), GFP_KERNEL);
+}
+
+static void sme_free(struct task_struct *task)
+{
+	kfree(task->thread.za_state);
+	task->thread.za_state = NULL;
+}
+
 void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 {
 	/* Set priority for all PEs to architecturally defined minimum */
@@ -1273,6 +1329,29 @@ void __init sme_setup(void)
 
 #endif /* CONFIG_ARM64_SME */
 
+static void sve_init_regs(void)
+{
+	/*
+	 * Convert the FPSIMD state to SVE, zeroing all the state that
+	 * is not shared with FPSIMD. If (as is likely) the current
+	 * state is live in the registers then do this there and
+	 * update our metadata for the current task including
+	 * disabling the trap, otherwise update our in-memory copy.
+	 * We are guaranteed to not be in streaming mode, we can only
+	 * take a SVE trap when not in streaming mode and we can't be
+	 * in streaming mode when taking a SME trap.
+	 */
+	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+		unsigned long vq_minus_one =
+			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(vq_minus_one);
+		sve_flush_live(true, vq_minus_one);
+		fpsimd_bind_task_to_cpu();
+	} else {
+		fpsimd_to_sve(current);
+	}
+}
+
 /*
  * Trapped SVE access
  *
@@ -1304,22 +1383,77 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 		WARN_ON(1); /* SVE access shouldn't have trapped */
 
 	/*
-	 * Convert the FPSIMD state to SVE, zeroing all the state that
-	 * is not shared with FPSIMD. If (as is likely) the current
-	 * state is live in the registers then do this there and
-	 * update our metadata for the current task including
-	 * disabling the trap, otherwise update our in-memory copy.
+	 * Even if the task can have used streaming mode we can only
+	 * generate SVE access traps in normal SVE mode and
+	 * transitioning out of streaming mode may discard any
+	 * streaming mode state.  Always clear the high bits to avoid
+	 * any potential errors tracking what is properly initialised.
 	 */
+	sve_init_regs();
+
+	put_cpu_fpsimd_context();
+}
+
+/*
+ * Trapped SME access
+ *
+ * Storage is allocated for the full SVE and SME state, the current
+ * FPSIMD register contents are migrated to SVE if SVE is not already
+ * active, and the access trap is disabled.
+ *
+ * TIF_SME should be clear on entry: otherwise, fpsimd_restore_current_state()
+ * would have disabled the SME access trap for userspace during
+ * ret_to_user, making an SVE access trap impossible in that case.
+ */
+void do_sme_acc(unsigned int esr, struct pt_regs *regs)
+{
+	/* Even if we chose not to use SME, the hardware could still trap: */
+	if (unlikely(!system_supports_sme()) || WARN_ON(is_compat_task())) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	/*
+	 * If this not a trap due to SME being disabled then something
+	 * is being used in the wrong mode, report as SIGILL.
+	 */
+	if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	sve_alloc(current);
+	sme_alloc(current);
+	if (!current->thread.sve_state || !current->thread.za_state) {
+		force_sig(SIGKILL);
+		return;
+	}
+
+	get_cpu_fpsimd_context();
+
+	/* With TIF_SME userspace shouldn't generate any traps */
+	if (test_and_set_thread_flag(TIF_SME))
+		WARN_ON(1);
+
 	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
 		unsigned long vq_minus_one =
-			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
-		sve_set_vq(vq_minus_one);
-		sve_flush_live(true, vq_minus_one);
+			sve_vq_from_vl(task_get_sme_vl(current)) - 1;
+		sme_set_vq(vq_minus_one);
+
 		fpsimd_bind_task_to_cpu();
-	} else {
-		fpsimd_to_sve(current);
 	}
 
+	/*
+	 * If SVE was not already active initialise the SVE registers,
+	 * any non-shared state between the streaming and regular SVE
+	 * registers is architecturally guaranteed to be zeroed when
+	 * we enter streaming mode.  We do not need to initialize ZA
+	 * since ZA must be disabled at this point and enabling ZA is
+	 * architecturally defined to zero ZA.
+	 */
+	if (system_supports_sve() && !test_thread_flag(TIF_SVE))
+		sve_init_regs();
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1436,8 +1570,11 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
-	if (system_supports_sme())
+	if (system_supports_sme()) {
+		clear_thread_flag(TIF_SME);
+		sme_free(current);
 		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+	}
 
 	put_cpu_fpsimd_context();
 }
@@ -1487,15 +1624,24 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
+	/*
+	 * Toggle SVE and SME trapping for userspace if needed, these
+	 * are serialsied by ret_to_user().
+	 */
+	if (system_supports_sme()) {
+		if (test_thread_flag(TIF_SME))
+			sme_user_enable();
+		else
+			sme_user_disable();
+	}
+
 	if (system_supports_sve()) {
-		/* Toggle SVE trapping for userspace if needed */
 		if (test_thread_flag(TIF_SVE))
 			sve_user_enable();
 		else
 			sve_user_disable();
-
-		/* Serialised by exception return to user */
 	}
+
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f2d32a29641c..f7fcc625ea0e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -299,17 +299,19 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
 
 	/*
-	 * Detach src's sve_state (if any) from dst so that it does not
-	 * get erroneously used or freed prematurely.  dst's sve_state
-	 * will be allocated on demand later on if dst uses SVE.
-	 * For consistency, also clear TIF_SVE here: this could be done
+	 * Detach src's sve/za_state (if any) from dst so that it does not
+	 * get erroneously used or freed prematurely.  dst's copies
+	 * will be allocated on demand later on if dst uses SVE/SME.
+	 * For consistency, also clear TIF_SVE/SME here: this could be done
 	 * later in copy_process(), but to avoid tripping up future
-	 * maintainers it is best not to leave TIF_SVE and sve_state in
+	 * maintainers it is best not to leave TIF flags and buffers in
 	 * an inconsistent state, even temporarily.
 	 */
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.za_state = NULL;
+	clear_tsk_thread_flag(dst, TIF_SME);
 	dst->thread.svcr = 0;
 
 	/* clear any pending asynchronous tag fault raised by the parent */
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index c938603b3ba0..958b2d926354 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -158,11 +158,41 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 	syscall_trace_exit(regs);
 }
 
-static inline void sve_user_discard(void)
+/*
+ * As per the ABI exit SME streaming mode and clear the SVE state not
+ * shared with FPSIMD on syscall entry.
+ */
+static inline void fp_user_discard(void)
 {
+	/*
+	 * If SME is active then exit streaming mode.  If ZA is active
+	 * then flush the SVE registers but leave userspace access to
+	 * both SVE and SME enabled, otherwise disable SME for the
+	 * task and fall through to disabling SVE too.  This means
+	 * that after a syscall we never have any SME register state
+	 * to track, if this changes the KVM code will need updating.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME)) {
+		u64 svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (svcr & SYS_SVCR_EL0_SM_MASK)
+			sme_smstop_sm();
+
+		if (!(svcr & SYS_SVCR_EL0_ZA_MASK)) {
+			clear_thread_flag(TIF_SME);
+			sme_user_disable();
+		}
+	}
+
+
 	if (!system_supports_sve())
 		return;
 
+	/*
+	 * If SME is not active then disable SVE, the registers will
+	 * be cleared when userspace next attempts to access them and
+	 * we do not need to track the SVE register state until then.
+	 */
 	clear_thread_flag(TIF_SVE);
 
 	/*
@@ -177,7 +207,7 @@ static inline void sve_user_discard(void)
 
 void do_el0_svc(struct pt_regs *regs)
 {
-	sve_user_discard();
+	fp_user_discard();
 	el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:58 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:58 +0000
Subject: [PATCH v9 18/40] arm64/sme: Disable ZA and streaming mode when
 handling signals
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-19-broonie@kernel.org>

The ABI requires that streaming mode and ZA are disabled when invoking
signal handlers, do this in setup_return() when we prepare the task state
for the signal handler.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/signal.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index d8aaf4b6f432..cda04fd73333 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -758,6 +758,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 	/* TCO (Tag Check Override) always cleared for signal handlers */
 	regs->pstate &= ~PSR_TCO_BIT;
 
+	/* Signal handlers are invoked with ZA and streaming mode disabled */
+	if (system_supports_sme()) {
+		current->thread.svcr &= ~(SYS_SVCR_EL0_ZA_MASK |
+					  SYS_SVCR_EL0_SM_MASK);
+		sme_smstop();
+	}
+
 	if (ka->sa.sa_flags & SA_RESTORER)
 		sigtramp = ka->sa.sa_restorer;
 	else
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:10:59 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:10:59 +0000
Subject: [PATCH v9 19/40] arm64/sme: Implement streaming SVE signal handling
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-20-broonie@kernel.org>

When in streaming mode we have the same set of SVE registers as we do in
regular SVE mode with the exception of FFR and the use of the SME vector
length. Provide signal handling for these registers by taking one of the
reserved words in the SVE signal context as a flags field and defining a
flag with a flag which is set for streaming mode. When the flag is set the
vector length is set to the streaming mode vector length and we save and
restore streaming mode data. We support entering or leaving streaming mode
based on the value of the flag but do not support changing the vector
length, this is not currently supported SVE signal handling.

We could instead allocate a separate record in the signal frame for the
streaming mode SVE context but this inflates the size of the maximal signal
frame required and adds complication when validating signal frames from
userspace, especially given the current structure of the code.

Any implementation of support for streaming mode vectors in signals will
have some potential for causing issues for applications that attempt to
handle SVE vectors in signals, use streaming mode but do not understand
streaming mode in their signal handling code, it is hard to identify a
case that is clearly better than any other - they all have cases where
they could cause unexpected register corruption or faults.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h | 16 ++++++--
 arch/arm64/kernel/signal.c               | 48 ++++++++++++++++++------
 2 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 0c796c795dbe..3a3366d4fbc2 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -134,9 +134,12 @@ struct extra_context {
 struct sve_context {
 	struct _aarch64_ctx head;
 	__u16 vl;
-	__u16 __reserved[3];
+	__u16 flags;
+	__u16 __reserved[2];
 };
 
+#define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -186,9 +189,16 @@ struct sve_context {
  * sve_context.vl must equal the thread's current vector length when
  * doing a sigreturn.
  *
+ * On systems with support for SME the SVE register state may reflect either
+ * streaming or non-streaming mode.  In streaming mode the streaming mode
+ * vector length will be used and the flag SVE_SIG_FLAG_SM will be set in
+ * the flags field. It is permitted to enter or leave streaming mode in
+ * a signal return, applications should take care to ensure that any difference
+ * in vector length between the two modes is handled, including any resixing
+ * and movement of context blocks.
  *
- * Note: for all these macros, the "vq" argument denotes the SVE
- * vector length in quadwords (i.e., units of 128 bits).
+ * Note: for all these macros, the "vq" argument denotes the vector length
+ * in quadwords (i.e., units of 128 bits).
  *
  * The correct way to obtain vq is to use sve_vq_from_vl(vl).  The
  * result is valid if and only if sve_vl_valid(vl) is true.  This is
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index cda04fd73333..5e6ec6ed8a1c 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -227,11 +227,17 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 {
 	int err = 0;
 	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	u16 flags = 0;
 	unsigned int vl = task_get_sve_vl(current);
 	unsigned int vq = 0;
 
-	if (test_thread_flag(TIF_SVE))
+	if (thread_sm_enabled(&current->thread)) {
+		vl = task_get_sme_vl(current);
 		vq = sve_vq_from_vl(vl);
+		flags |= SVE_SIG_FLAG_SM;
+	} else if (test_thread_flag(TIF_SVE)) {
+		vq = sve_vq_from_vl(vl);
+	}
 
 	memset(reserved, 0, sizeof(reserved));
 
@@ -239,6 +245,7 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
 			 &ctx->head.size, err);
 	__put_user_error(vl, &ctx->vl, err);
+	__put_user_error(flags, &ctx->flags, err);
 	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
 	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
 
@@ -259,18 +266,28 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
 	int err;
-	unsigned int vq;
+	unsigned int vl, vq;
 	struct user_fpsimd_state fpsimd;
 	struct sve_context sve;
 
 	if (__copy_from_user(&sve, user->sve, sizeof(sve)))
 		return -EFAULT;
 
-	if (sve.vl != task_get_sve_vl(current))
+	if (sve.flags & SVE_SIG_FLAG_SM) {
+		if (!system_supports_sme())
+			return -EINVAL;
+
+		vl = task_get_sme_vl(current);
+	} else {
+		vl = task_get_sve_vl(current);
+	}
+
+	if (sve.vl != vl)
 		return -EINVAL;
 
 	if (sve.head.size <= sizeof(*user->sve)) {
 		clear_thread_flag(TIF_SVE);
+		current->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
 		goto fpsimd_only;
 	}
 
@@ -302,7 +319,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (err)
 		return -EFAULT;
 
-	set_thread_flag(TIF_SVE);
+	if (sve.flags & SVE_SIG_FLAG_SM)
+		current->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+	else
+		set_thread_flag(TIF_SVE);
 
 fpsimd_only:
 	/* copy the FP and status/control registers */
@@ -394,7 +414,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			break;
 
 		case SVE_MAGIC:
-			if (!system_supports_sve())
+			if (!system_supports_sve() && !system_supports_sme())
 				goto invalid;
 
 			if (user->sve)
@@ -593,11 +613,16 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 	if (system_supports_sve()) {
 		unsigned int vq = 0;
 
-		if (add_all || test_thread_flag(TIF_SVE)) {
-			int vl = sve_max_vl();
+		if (add_all || test_thread_flag(TIF_SVE) ||
+		    thread_sm_enabled(&current->thread)) {
+			int vl = max(sve_max_vl(), sme_max_vl());
 
-			if (!add_all)
-				vl = task_get_sve_vl(current);
+			if (!add_all) {
+				if (thread_sm_enabled(&current->thread))
+					vl = task_get_sme_vl(current);
+				else
+					vl = task_get_sve_vl(current);
+			}
 
 			vq = sve_vq_from_vl(vl);
 		}
@@ -648,8 +673,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
 	}
 
-	/* Scalable Vector Extension state, if present */
-	if (system_supports_sve() && err == 0 && user->sve_offset) {
+	/* Scalable Vector Extension state (including streaming), if present */
+	if ((system_supports_sve() || system_supports_sme()) &&
+	    err == 0 && user->sve_offset) {
 		struct sve_context __user *sve_ctx =
 			apply_user_offset(user, user->sve_offset);
 		err |= preserve_sve_context(sve_ctx);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:00 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:00 +0000
Subject: [PATCH v9 20/40] arm64/sme: Implement ZA signal handling
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-21-broonie@kernel.org>

Implement support for ZA in signal handling in a very similar way to how
we implement support for SVE registers, using a signal context structure
with optional register state after it. Where present this register state
stores the ZA matrix as a series of horizontal vectors numbered from 0 to
VL/8 in the endinanness independent format used for vectors.

As with SVE we do not allow changes in the vector length during signal
return but we do allow ZA to be enabled or disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h |  41 +++++++
 arch/arm64/kernel/fpsimd.c               |   3 -
 arch/arm64/kernel/signal.c               | 139 +++++++++++++++++++++++
 3 files changed, 180 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 3a3366d4fbc2..d45bdf2c8b26 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -140,6 +140,14 @@ struct sve_context {
 
 #define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
 
+#define ZA_MAGIC	0x54366345
+
+struct za_context {
+	struct _aarch64_ctx head;
+	__u16 vl;
+	__u16 __reserved[3];
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -259,4 +267,37 @@ struct sve_context {
 #define SVE_SIG_CONTEXT_SIZE(vq) \
 		(SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 
+/*
+ * If the ZA register is enabled for the thread at signal delivery then,
+ * za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * and the register data may be accessed using the ZA_SIG_*() macros.
+ *
+ * If za_context.head.size < ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * then ZA was not enabled and no register data was included in which case
+ * ZA register was not enabled for the thread and no register data
+ * the ZA_SIG_*() macros should not be used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the za_context block if it wants to
+ * enable the ZA register when it was previously non-live or vice-versa.
+ * This may require the caller to allocate fresh memory and/or move other
+ * context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * za_context.vl must equal the thread's current SME vector length when
+ * doing a sigreturn.
+ */
+
+#define ZA_SIG_REGS_OFFSET					\
+	((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \
+				  (SVE_SIG_ZREG_SIZE(vq) * n))
+
+#define ZA_SIG_CONTEXT_SIZE(vq) \
+		(ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
+
 #endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 33f80512753d..2242c14a5a05 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1190,9 +1190,6 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #ifdef CONFIG_ARM64_SME
 
-/* This will move to uapi/asm/sigcontext.h when signals are implemented */
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
-
 /*
  * Ensure that task->thread.za_state is allocated and sufficiently large.
  *
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 5e6ec6ed8a1c..8efa78765cad 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -57,6 +57,7 @@ struct rt_sigframe_user_layout {
 	unsigned long fpsimd_offset;
 	unsigned long esr_offset;
 	unsigned long sve_offset;
+	unsigned long za_offset;
 	unsigned long extra_offset;
 	unsigned long end_offset;
 };
@@ -219,6 +220,7 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 struct user_ctxs {
 	struct fpsimd_context __user *fpsimd;
 	struct sve_context __user *sve;
+	struct za_context __user *za;
 };
 
 #ifdef CONFIG_ARM64_SVE
@@ -347,6 +349,101 @@ extern int restore_sve_fpsimd_context(struct user_ctxs *user);
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int preserve_za_context(struct za_context __user *ctx)
+{
+	int err = 0;
+	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	unsigned int vl = task_get_sme_vl(current);
+	unsigned int vq;
+
+	if (thread_za_enabled(&current->thread))
+		vq = sve_vq_from_vl(vl);
+	else
+		vq = 0;
+
+	memset(reserved, 0, sizeof(reserved));
+
+	__put_user_error(ZA_MAGIC, &ctx->head.magic, err);
+	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
+			 &ctx->head.size, err);
+	__put_user_error(vl, &ctx->vl, err);
+	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
+	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
+
+	if (vq) {
+		/*
+		 * This assumes that the ZA state has already been saved to
+		 * the task struct by calling the function
+		 * fpsimd_signal_preserve_current_state().
+		 */
+		err |= __copy_to_user((char __user *)ctx + ZA_SIG_REGS_OFFSET,
+				      current->thread.za_state,
+				      ZA_SIG_REGS_SIZE(vq));
+	}
+
+	return err ? -EFAULT : 0;
+}
+
+static int restore_za_context(struct user_ctxs __user *user)
+{
+	int err;
+	unsigned int vq;
+	struct za_context za;
+
+	if (__copy_from_user(&za, user->za, sizeof(za)))
+		return -EFAULT;
+
+	if (za.vl != task_get_sme_vl(current))
+		return -EINVAL;
+
+	if (za.head.size <= sizeof(*user->za)) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		return 0;
+	}
+
+	vq = sve_vq_from_vl(za.vl);
+
+	if (za.head.size < ZA_SIG_CONTEXT_SIZE(vq))
+		return -EINVAL;
+
+	/*
+	 * Careful: we are about __copy_from_user() directly into
+	 * thread.za_state with preemption enabled, so protection is
+	 * needed to prevent a racing context switch from writing stale
+	 * registers back over the new data.
+	 */
+
+	fpsimd_flush_task_state(current);
+	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
+
+	sme_alloc(current);
+	if (!current->thread.za_state) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		clear_thread_flag(TIF_SME);
+		return -ENOMEM;
+	}
+
+	err = __copy_from_user(current->thread.za_state,
+			       (char __user const *)user->za +
+					ZA_SIG_REGS_OFFSET,
+			       ZA_SIG_REGS_SIZE(vq));
+	if (err)
+		return -EFAULT;
+
+	set_thread_flag(TIF_SME);
+	current->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+	return 0;
+}
+#else /* ! CONFIG_ARM64_SME */
+
+/* Turn any non-optimised out attempts to use these into a link error: */
+extern int preserve_za_context(void __user *ctx);
+extern int restore_za_context(struct user_ctxs *user);
+
+#endif /* ! CONFIG_ARM64_SME */
 
 static int parse_user_sigframe(struct user_ctxs *user,
 			       struct rt_sigframe __user *sf)
@@ -361,6 +458,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 
 	user->fpsimd = NULL;
 	user->sve = NULL;
+	user->za = NULL;
 
 	if (!IS_ALIGNED((unsigned long)base, 16))
 		goto invalid;
@@ -426,6 +524,19 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			user->sve = (struct sve_context __user *)head;
 			break;
 
+		case ZA_MAGIC:
+			if (!system_supports_sme())
+				goto invalid;
+
+			if (user->za)
+				goto invalid;
+
+			if (size < sizeof(*user->za))
+				goto invalid;
+
+			user->za = (struct za_context __user *)head;
+			break;
+
 		case EXTRA_MAGIC:
 			if (have_extra_context)
 				goto invalid;
@@ -549,6 +660,9 @@ static int restore_sigframe(struct pt_regs *regs,
 		}
 	}
 
+	if (err == 0 && system_supports_sme() && user.za)
+		err = restore_za_context(&user);
+
 	return err;
 }
 
@@ -633,6 +747,24 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 			return err;
 	}
 
+	if (system_supports_sme()) {
+		unsigned int vl;
+		unsigned int vq = 0;
+
+		if (add_all)
+			vl = sme_max_vl();
+		else
+			vl = task_get_sme_vl(current);
+
+		if (thread_za_enabled(&current->thread))
+			vq = sve_vq_from_vl(vl);
+
+		err = sigframe_alloc(user, &user->za_offset,
+				     ZA_SIG_CONTEXT_SIZE(vq));
+		if (err)
+			return err;
+	}
+
 	return sigframe_alloc_end(user);
 }
 
@@ -681,6 +813,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		err |= preserve_sve_context(sve_ctx);
 	}
 
+	/* ZA state if present */
+	if (system_supports_sme() && err == 0 && user->za_offset) {
+		struct za_context __user *za_ctx =
+			apply_user_offset(user, user->za_offset);
+		err |= preserve_za_context(za_ctx);
+	}
+
 	if (err == 0 && user->extra_offset) {
 		char __user *sfp = (char __user *)user->sigframe;
 		char __user *userp =
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:01 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:01 +0000
Subject: [PATCH v9 21/40] arm64/sme: Implement ptrace support for streaming
 mode SVE registers
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-22-broonie@kernel.org>

The streaming mode SVE registers are represented using the same data
structures as for SVE but since the vector lengths supported and in use
may not be the same as SVE we represent them with a new type NT_ARM_SSVE.
Unfortunately we only have a single 16 bit reserved field available in
the header so there is no space to fit the current and maximum vector
length for both standard and streaming SVE mode without redefining the
structure in a way the creates a complicatd and fragile ABI. Since FFR
is not present in streaming mode it is read and written as zero.

Setting NT_ARM_SSVE registers will put the task into streaming mode,
similarly setting NT_ARM_SVE registers will exit it. Reads that do not
correspond to the current mode of the task will return the header with
no register data. For compatibility reasons on write setting no flag for
the register type will be interpreted as setting SVE registers, though
users can provide no register data as an alternative mechanism for doing
so.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  13 +-
 arch/arm64/kernel/fpsimd.c           |  21 ++-
 arch/arm64/kernel/ptrace.c           | 212 +++++++++++++++++++++------
 include/uapi/linux/elf.h             |   1 +
 4 files changed, 190 insertions(+), 57 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 758ae984ff97..522b925a78c1 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -109,7 +109,7 @@ struct user_hwdebug_state {
 	}		dbg_regs[16];
 };
 
-/* SVE/FP/SIMD state (NT_ARM_SVE) */
+/* SVE/FP/SIMD state (NT_ARM_SVE & NT_ARM_SSVE) */
 
 struct user_sve_header {
 	__u32 size; /* total meaningful regset content in bytes */
@@ -220,6 +220,7 @@ struct user_sve_header {
 	(SVE_PT_SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - \
 		SVE_PT_SVE_PREGS_OFFSET(vq))
 
+/* For streaming mode SVE (SSVE) FFR must be read and written as zero */
 #define SVE_PT_SVE_FFR_OFFSET(vq) \
 	(SVE_PT_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
 
@@ -240,10 +241,12 @@ struct user_sve_header {
 			- SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1))	\
 		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
-#define SVE_PT_SIZE(vq, flags)						\
-	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		\
-		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	\
-		: SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
+#define SVE_PT_SIZE(vq, flags)						  \
+	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		  \
+		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	  \
+		: ((((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD ?  \
+		    SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags) \
+		  : SVE_PT_REGS_OFFSET)))
 
 /* pointer authentication masks (NT_ARM_PAC_MASK) */
 
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2242c14a5a05..8b111b7f2006 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -645,14 +645,19 @@ static void __fpsimd_to_sve(void *sst, struct user_fpsimd_state const *fst,
  */
 static void fpsimd_to_sve(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void *sst = task->thread.sve_state;
 	struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
 
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	__fpsimd_to_sve(sst, fst, vq);
 }
 
@@ -669,7 +674,7 @@ static void fpsimd_to_sve(struct task_struct *task)
  */
 static void sve_to_fpsimd(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void const *sst = task->thread.sve_state;
 	struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
 	unsigned int i;
@@ -678,7 +683,12 @@ static void sve_to_fpsimd(struct task_struct *task)
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	for (i = 0; i < SVE_NUM_ZREGS; ++i) {
 		p = (__uint128_t const *)ZREG(sst, vq, i);
 		fst->vregs[i] = arm64_le128_to_cpu(*p);
@@ -819,8 +829,7 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	/*
 	 * To ensure the FPSIMD bits of the SVE vector registers are preserved,
 	 * write any live register state back to task_struct, and convert to a
-	 * regular FPSIMD thread.  Since the vector length can only be changed
-	 * with a syscall we can't be in streaming mode while reconfiguring.
+	 * regular FPSIMD thread.
 	 */
 	if (task == current) {
 		get_cpu_fpsimd_context();
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 39dbdfdc38d3..0b8324fa1abc 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -714,21 +714,51 @@ static int system_call_set(struct task_struct *target,
 #ifdef CONFIG_ARM64_SVE
 
 static void sve_init_header_from_task(struct user_sve_header *header,
-				      struct task_struct *target)
+				      struct task_struct *target,
+				      enum vec_type type)
 {
 	unsigned int vq;
+	bool active;
+	bool fpsimd_only;
+	enum vec_type task_type;
 
 	memset(header, 0, sizeof(*header));
 
-	header->flags = test_tsk_thread_flag(target, TIF_SVE) ?
-		SVE_PT_REGS_SVE : SVE_PT_REGS_FPSIMD;
-	if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
-		header->flags |= SVE_PT_VL_INHERIT;
+	/* Check if the requested registers are active for the task */
+	if (thread_sm_enabled(&target->thread))
+		task_type = ARM64_VEC_SME;
+	else
+		task_type = ARM64_VEC_SVE;
+	active = (task_type == type);
+
+	switch (type) {
+	case ARM64_VEC_SVE:
+		if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE);
+		break;
+	case ARM64_VEC_SME:
+		if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = false;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return;
+	}
 
-	header->vl = task_get_sve_vl(target);
+	if (active) {
+		if (fpsimd_only) {
+			header->flags |= SVE_PT_REGS_FPSIMD;
+		} else {
+			header->flags |= SVE_PT_REGS_SVE;
+		}
+	}
+
+	header->vl = task_get_vl(target, type);
 	vq = sve_vq_from_vl(header->vl);
 
-	header->max_vl = sve_max_vl();
+	header->max_vl = vec_max_vl(type);
 	header->size = SVE_PT_SIZE(vq, header->flags);
 	header->max_size = SVE_PT_SIZE(sve_vq_from_vl(header->max_vl),
 				      SVE_PT_REGS_SVE);
@@ -739,19 +769,17 @@ static unsigned int sve_size_from_header(struct user_sve_header const *header)
 	return ALIGN(header->size, SVE_VQ_BYTES);
 }
 
-static int sve_get(struct task_struct *target,
-		   const struct user_regset *regset,
-		   struct membuf to)
+static int sve_get_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  struct membuf to,
+			  enum vec_type type)
 {
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
-	sve_init_header_from_task(&header, target);
+	sve_init_header_from_task(&header, target, type);
 	vq = sve_vq_from_vl(header.vl);
 
 	membuf_write(&to, &header, sizeof(header));
@@ -759,49 +787,61 @@ static int sve_get(struct task_struct *target,
 	if (target == current)
 		fpsimd_preserve_current_state();
 
-	/* Registers: FPSIMD-only case */
-
 	BUILD_BUG_ON(SVE_PT_FPSIMD_OFFSET != sizeof(header));
-	if ((header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
+	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
+
+	switch ((header.flags & SVE_PT_REGS_MASK)) {
+	case SVE_PT_REGS_FPSIMD:
 		return __fpr_get(target, regset, to);
 
-	/* Otherwise: full SVE case */
+	case SVE_PT_REGS_SVE:
+		start = SVE_PT_SVE_OFFSET;
+		end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
+		membuf_write(&to, target->thread.sve_state, end - start);
 
-	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
-	start = SVE_PT_SVE_OFFSET;
-	end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
-	membuf_write(&to, target->thread.sve_state, end - start);
+		start = end;
+		end = SVE_PT_SVE_FPSR_OFFSET(vq);
+		membuf_zero(&to, end - start);
 
-	start = end;
-	end = SVE_PT_SVE_FPSR_OFFSET(vq);
-	membuf_zero(&to, end - start);
+		/*
+		 * Copy fpsr, and fpcr which must follow contiguously in
+		 * struct fpsimd_state:
+		 */
+		start = end;
+		end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
+		membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr,
+			     end - start);
 
-	/*
-	 * Copy fpsr, and fpcr which must follow contiguously in
-	 * struct fpsimd_state:
-	 */
-	start = end;
-	end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
-	membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr, end - start);
+		start = end;
+		end = sve_size_from_header(&header);
+		return membuf_zero(&to, end - start);
 
-	start = end;
-	end = sve_size_from_header(&header);
-	return membuf_zero(&to, end - start);
+	default:
+		return 0;
+	}
 }
 
-static int sve_set(struct task_struct *target,
+static int sve_get(struct task_struct *target,
 		   const struct user_regset *regset,
-		   unsigned int pos, unsigned int count,
-		   const void *kbuf, const void __user *ubuf)
+		   struct membuf to)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SVE);
+}
+
+static int sve_set_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  unsigned int pos, unsigned int count,
+			  const void *kbuf, const void __user *ubuf,
+			  enum vec_type type)
 {
 	int ret;
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
 	if (count < sizeof(header))
 		return -EINVAL;
@@ -814,13 +854,37 @@ static int sve_set(struct task_struct *target,
 	 * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
 	 * vec_set_vector_length(), which will also validate them for us:
 	 */
-	ret = vec_set_vector_length(target, ARM64_VEC_SVE, header.vl,
+	ret = vec_set_vector_length(target, type, header.vl,
 		((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
 	if (ret)
 		goto out;
 
 	/* Actual VL set may be less than the user asked for: */
-	vq = sve_vq_from_vl(task_get_sve_vl(target));
+	vq = sve_vq_from_vl(task_get_vl(target, type));
+
+	/* Enter/exit streaming mode */
+	if (system_supports_sme()) {
+		u64 old_svcr = target->thread.svcr;
+
+		switch (type) {
+		case ARM64_VEC_SVE:
+			target->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
+			break;
+		case ARM64_VEC_SME:
+			target->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+			break;
+		default:
+			WARN_ON_ONCE(1);
+			return -EINVAL;
+		}
+
+		/*
+		 * If we switched then invalidate any existing SVE
+		 * state and ensure there's storage.
+		 */
+		if (target->thread.svcr != old_svcr)
+			sve_alloc(target);
+	}
 
 	/* Registers: FPSIMD-only case */
 
@@ -832,7 +896,10 @@ static int sve_set(struct task_struct *target,
 		goto out;
 	}
 
-	/* Otherwise: full SVE case */
+	/*
+	 * Otherwise: no registers or full SVE case.  For backwards
+	 * compatibility reasons we treat empty flags as SVE registers.
+	 */
 
 	/*
 	 * If setting a different VL from the requested VL and there is
@@ -853,8 +920,9 @@ static int sve_set(struct task_struct *target,
 
 	/*
 	 * Ensure target->thread.sve_state is up to date with target's
-	 * FPSIMD regs, so that a short copyin leaves trailing registers
-	 * unmodified.
+	 * FPSIMD regs, so that a short copyin leaves trailing
+	 * registers unmodified.  Always enable SVE even if going into
+	 * streaming mode.
 	 */
 	fpsimd_sync_to_sve(target);
 	set_tsk_thread_flag(target, TIF_SVE);
@@ -890,8 +958,46 @@ static int sve_set(struct task_struct *target,
 	return ret;
 }
 
+static int sve_set(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SVE);
+}
+
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int ssve_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   struct membuf to)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SME);
+}
+
+static int ssve_set(struct task_struct *target,
+		    const struct user_regset *regset,
+		    unsigned int pos, unsigned int count,
+		    const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SME);
+}
+
+#endif /* CONFIG_ARM64_SME */
+
 #ifdef CONFIG_ARM64_PTR_AUTH
 static int pac_mask_get(struct task_struct *target,
 			const struct user_regset *regset,
@@ -1109,6 +1215,9 @@ enum aarch64_regset {
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SVE,
 #endif
+#ifdef CONFIG_ARM64_SVE
+	REGSET_SSVE,
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
 	REGSET_PAC_ENABLED_KEYS,
@@ -1189,6 +1298,17 @@ static const struct user_regset aarch64_regsets[] = {
 		.set = sve_set,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[REGSET_SSVE] = { /* Streaming mode SVE */
+		.core_note_type = NT_ARM_SSVE,
+		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
+				  SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = ssve_get,
+		.set = ssve_set,
+	},
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
 		.core_note_type = NT_ARM_PAC_MASK,
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61bf4774b8f2..61502388683f 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -427,6 +427,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_PACG_KEYS	0x408	/* ARM pointer authentication generic key */
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
+#define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:02 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:02 +0000
Subject: [PATCH v9 22/40] arm64/sme: Add ptrace support for ZA
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-23-broonie@kernel.org>

The ZA array can be read and written with the NT_ARM_ZA.  Similarly to
our interface for the SVE vector registers the regset consists of a
header with information on the current vector length followed by an
optional register data payload, represented as for signals as a series
of horizontal vectors from 0 to VL/8 in the endianness independent
format used for vectors.

On get if ZA is enabled then register data will be provided, otherwise
it will be omitted.  On set if register data is provided then ZA is
enabled and initialized using the provided data, otherwise it is
disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  56 +++++++++++
 arch/arm64/kernel/ptrace.c           | 144 +++++++++++++++++++++++++++
 include/uapi/linux/elf.h             |   1 +
 3 files changed, 201 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 522b925a78c1..7fa2f7036aa7 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -268,6 +268,62 @@ struct user_pac_generic_keys {
 	__uint128_t	apgakey;
 };
 
+/* ZA state (NT_ARM_ZA) */
+
+struct user_za_header {
+	__u32 size; /* total meaningful regset content in bytes */
+	__u32 max_size; /* maxmium possible size for this thread */
+	__u16 vl; /* current vector length */
+	__u16 max_vl; /* maximum possible vector length */
+	__u16 flags;
+	__u16 __reserved;
+};
+
+/*
+ * Common ZA_PT_* flags:
+ * These must be kept in sync with prctl interface in <linux/prctl.h>
+ */
+#define ZA_PT_VL_INHERIT		((1 << 17) /* PR_SME_VL_INHERIT */ >> 16)
+#define ZA_PT_VL_ONEXEC			((1 << 18) /* PR_SME_SET_VL_ONEXEC */ >> 16)
+
+
+/*
+ * The remainder of the ZA state follows struct user_za_header.  The
+ * total size of the ZA state (including header) depends on the
+ * metadata in the header:  ZA_PT_SIZE(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_za_header to the register data */
+#define ZA_PT_ZA_OFFSET						\
+	((sizeof(struct user_za_header) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+/*
+ * The payload starts at offset ZA_PT_ZA_OFFSET, and is of size
+ * ZA_PT_ZA_SIZE(vq, flags).
+ *
+ * The ZA array is stored as a sequence of horizontal vectors ZAV of SVL/8
+ * bytes each, starting from vector 0.
+ *
+ * Additional data might be appended in the future.
+ *
+ * The ZA matrix is represented in memory in an endianness-invariant layout
+ * which differs from the layout used for the FPSIMD V-registers on big-endian
+ * systems: see sigcontext.h for more explanation.
+ */
+
+#define ZA_PT_ZAV_OFFSET(vq, n) \
+	(ZA_PT_ZA_OFFSET + ((vq * __SVE_VQ_BYTES) * n))
+
+#define ZA_PT_ZA_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_PT_SIZE(vq)						\
+	(ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq))
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 0b8324fa1abc..d6f27d3bf6e7 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -996,6 +996,141 @@ static int ssve_set(struct task_struct *target,
 			      ARM64_VEC_SME);
 }
 
+static int za_get(struct task_struct *target,
+		  const struct user_regset *regset,
+		  struct membuf to)
+{
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	memset(&header, 0, sizeof(header));
+
+	if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+		header.flags |= ZA_PT_VL_INHERIT;
+
+	header.vl = task_get_sme_vl(target);
+	vq = sve_vq_from_vl(header.vl);
+	header.max_vl = sme_max_vl();
+	header.max_size = ZA_PT_SIZE(vq);
+
+	/* If ZA is not active there is only the header */
+	if (thread_za_enabled(&target->thread))
+		header.size = ZA_PT_SIZE(vq);
+	else
+		header.size = ZA_PT_ZA_OFFSET;
+
+	membuf_write(&to, &header, sizeof(header));
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	end = ZA_PT_ZA_OFFSET;
+;
+	if (target == current)
+		fpsimd_preserve_current_state();
+
+	/* Any register data to include? */
+	if (thread_za_enabled(&target->thread)) {
+		start = end;
+		end = ZA_PT_SIZE(vq);
+		membuf_write(&to, target->thread.za_state, end - start);
+	}
+
+	/* Zero any trailing padding */
+	start = end;
+	end = ALIGN(header.size, SVE_VQ_BYTES);
+	return membuf_zero(&to, end - start);
+}
+
+static int za_set(struct task_struct *target,
+		  const struct user_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	if (count < sizeof(header))
+		return -EINVAL;
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &header,
+				 0, sizeof(header));
+	if (ret)
+		goto out;
+
+	/*
+	 * All current ZA_PT_* flags are consumed by
+	 * vec_set_vector_length(), which will also validate them for
+	 * us:
+	 */
+	ret = vec_set_vector_length(target, ARM64_VEC_SME, header.vl,
+		((unsigned long)header.flags) << 16);
+	if (ret)
+		goto out;
+
+	/* Actual VL set may be less than the user asked for: */
+	vq = sve_vq_from_vl(task_get_sme_vl(target));
+
+	/* Ensure there is some SVE storage for streaming mode */
+	if (!target->thread.sve_state) {
+		sve_alloc(target);
+		if (!target->thread.sve_state) {
+			clear_thread_flag(TIF_SME);
+			ret = -ENOMEM;
+			goto out;
+		}
+	}
+
+	/* Allocate/reinit ZA storage */
+	sme_alloc(target);
+	if (!target->thread.za_state) {
+		ret = -ENOMEM;
+		clear_tsk_thread_flag(target, TIF_SME);
+		goto out;
+	}
+
+	/* If there is no data then disable ZA */
+	if (!count) {
+		target->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		goto out;
+	}
+
+	/*
+	 * If setting a different VL from the requested VL and there is
+	 * register data, the data layout will be wrong: don't even
+	 * try to set the registers in this case.
+	 */
+	if (vq != sve_vq_from_vl(header.vl)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	start = ZA_PT_ZA_OFFSET;
+	end = ZA_PT_SIZE(vq);
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 target->thread.za_state,
+				 start, end);
+	if (ret)
+		goto out;
+
+	/* Mark ZA as active and let userspace use it */
+	set_tsk_thread_flag(target, TIF_SME);
+	target->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+out:
+	fpsimd_flush_task_state(target);
+	return ret;
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 #ifdef CONFIG_ARM64_PTR_AUTH
@@ -1217,6 +1352,7 @@ enum aarch64_regset {
 #endif
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SSVE,
+	REGSET_ZA,
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
@@ -1308,6 +1444,14 @@ static const struct user_regset aarch64_regsets[] = {
 		.regset_get = ssve_get,
 		.set = ssve_set,
 	},
+	[REGSET_ZA] = { /* SME ZA */
+		.core_note_type = NT_ARM_ZA,
+		.n = DIV_ROUND_UP(ZA_PT_ZA_SIZE(SVE_VQ_MAX), SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = za_get,
+		.set = za_set,
+	},
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61502388683f..7ef574f3256a 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -428,6 +428,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
 #define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
+#define NT_ARM_ZA	0x40c		/* ARM SME ZA registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:04 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:04 +0000
Subject: [PATCH v9 24/40] arm64/sme: Save and restore streaming mode over EFI
 runtime calls
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-25-broonie@kernel.org>

When saving and restoring the floating point state over an EFI runtime
call ensure that we handle streaming mode, only handling FFR if we are not
in streaming mode and ensuring that we are in normal mode over the call
into runtime services.

We currently assume that ZA will not be modified by runtime services, the
specification is not yet finalised so this may need updating if that
changes.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index e00d3a9e919c..a7077a5d1ed2 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1059,21 +1059,25 @@ int vec_verify_vq_map(enum vec_type type)
 
 static void __init sve_efi_setup(void)
 {
-	struct vl_info *info = &vl_info[ARM64_VEC_SVE];
+	int max_vl = 0;
+	int i;
 
 	if (!IS_ENABLED(CONFIG_EFI))
 		return;
 
+	for (i = 0; i < ARRAY_SIZE(vl_info); i++)
+		max_vl = max(vl_info[i].max_vl, max_vl);
+
 	/*
 	 * alloc_percpu() warns and prints a backtrace if this goes wrong.
 	 * This is evidence of a crippled system and we are returning void,
 	 * so no attempt is made to handle this situation here.
 	 */
-	if (!sve_vl_valid(info->max_vl))
+	if (!sve_vl_valid(max_vl))
 		goto fail;
 
 	efi_sve_state = __alloc_percpu(
-		SVE_SIG_REGS_SIZE(sve_vq_from_vl(info->max_vl)), SVE_VQ_BYTES);
+		SVE_SIG_REGS_SIZE(sve_vq_from_vl(max_vl)), SVE_VQ_BYTES);
 	if (!efi_sve_state)
 		goto fail;
 
@@ -1848,6 +1852,7 @@ EXPORT_SYMBOL(kernel_neon_end);
 static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state);
 static DEFINE_PER_CPU(bool, efi_fpsimd_state_used);
 static DEFINE_PER_CPU(bool, efi_sve_state_used);
+static DEFINE_PER_CPU(bool, efi_sm_state);
 
 /*
  * EFI runtime services support functions
@@ -1882,12 +1887,28 @@ void __efi_fpsimd_begin(void)
 		 */
 		if (system_supports_sve() && likely(efi_sve_state)) {
 			char *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+			u64 svcr;
 
 			__this_cpu_write(efi_sve_state_used, true);
 
+			/* If we are in streaming mode don't touch FFR */
+			if (system_supports_sme()) {
+				svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+				ffr = svcr & SYS_SVCR_EL0_SM_MASK;
+
+				__this_cpu_write(efi_sm_state, ffr);
+			}
+
 			sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
+
+			if (system_supports_sme())
+				sysreg_clear_set_s(SYS_SVCR_EL0,
+						   SYS_SVCR_EL0_SM_MASK, 0);
+
 		} else {
 			fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state));
 		}
@@ -1910,11 +1931,25 @@ void __efi_fpsimd_end(void)
 		if (system_supports_sve() &&
 		    likely(__this_cpu_read(efi_sve_state_used))) {
 			char const *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+
+			/*
+			 * Restore streaming mode; EFI calls are
+			 * normal function calls so should not return in
+			 * streaming mode.
+			 */
+			if (system_supports_sme()) {
+				if (__this_cpu_read(efi_sm_state)) {
+					sysreg_clear_set_s(SYS_SVCR_EL0,
+							   0,
+							   SYS_SVCR_EL0_SM_MASK);
+					ffr = false;
+				}
+			}
 
-			sve_set_vq(sve_vq_from_vl(sve_get_vl()) - 1);
 			sve_load_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
 
 			__this_cpu_write(efi_sve_state_used, false);
 		} else {
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:03 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:03 +0000
Subject: [PATCH v9 23/40] arm64/sme: Disable streaming mode and ZA when
 flushing CPU state
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-24-broonie@kernel.org>

Both streaming mode and ZA may increase power consumption when they are
enabled and streaming mode makes many FPSIMD and SVE instructions undefined
which will cause problems for any kernel mode floating point so disable
both when we flush the CPU state. This covers both kernel_neon_begin() and
idle and after flushing the state a reload is always required anyway.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8b111b7f2006..e00d3a9e919c 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1762,6 +1762,15 @@ static void fpsimd_flush_cpu_state(void)
 {
 	WARN_ON(!system_supports_fpsimd());
 	__this_cpu_write(fpsimd_last_state.st, NULL);
+
+	/*
+	 * Leaving streaming mode enabled will cause issues for any kernel
+	 * NEON and leaving streaming mode or ZA enabled may increase power
+	 * consumption.
+	 */
+	if (system_supports_sme())
+		sme_smstop();
+
 	set_thread_flag(TIF_FOREIGN_FPSTATE);
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:05 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:05 +0000
Subject: [PATCH v9 25/40] KVM: arm64: Hide SME system registers from guests
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-26-broonie@kernel.org>

For the time being we do not support use of SME by KVM guests, support for
this will be enabled in future. In order to prevent any side effects or
side channels via the new system registers, including the EL0 read/write
register TPIDR2, explicitly undefine all the system registers added by
SME and mask out the SME bitfield in SYS_ID_AA64PFR1.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba316ff..43516eda9143 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1089,6 +1089,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 	case SYS_ID_AA64PFR1_EL1:
 		if (!kvm_has_mte(vcpu->kvm))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
+
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_SME);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1508,7 +1510,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
 	ID_SANITISED(ID_AA64ZFR0_EL1),
-	ID_UNALLOCATED(4,5),
+	ID_HIDDEN(ID_AA64SMFR0_EL1),
 	ID_UNALLOCATED(4,6),
 	ID_UNALLOCATED(4,7),
 
@@ -1551,6 +1553,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
 	{ SYS_DESC(SYS_TRFCR_EL1), undef_access },
+	{ SYS_DESC(SYS_SMPRI_EL1), undef_access },
+	{ SYS_DESC(SYS_SMCR_EL1), undef_access },
 	{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
 	{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
 	{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
@@ -1633,8 +1637,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr },
 	{ SYS_DESC(SYS_CLIDR_EL1), access_clidr },
+	{ SYS_DESC(SYS_SMIDR_EL1), undef_access },
 	{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
 	{ SYS_DESC(SYS_CTR_EL0), access_ctr },
+	{ SYS_DESC(SYS_SVCR_EL0), undef_access },
 
 	{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
 	  .reset = reset_pmcr, .reg = PMCR_EL0 },
@@ -1674,6 +1680,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
 	{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
+	{ SYS_DESC(SYS_TPIDR2_EL0), undef_access },
 
 	{ SYS_DESC(SYS_SCXTNUM_EL0), undef_access },
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:06 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:06 +0000
Subject: [PATCH v9 26/40] KVM: arm64: Trap SME usage in guest
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-27-broonie@kernel.org>

SME defines two new traps which need to be enabled for guests to ensure
that they can't use SME, one for the main SME operations which mirrors the
traps for SVE and another for access to TPIDR2 in SCTLR_EL2.

For VHE manage SMEN along with ZEN in activate_traps() and the FP state
management callbacks, along with SCTLR_EL2.EnTPIDR2.  There is no
existing dynamic management of SCTLR_EL2.

For nVHE manage TSM in activate_traps() along with the fine grained
traps for TPIDR2 and SMPRI.  There is no existing dynamic management of
fine grained traps.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 30 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c  | 11 ++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 6410d21d8695..184bf6bd79b9 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -47,10 +47,25 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 		__activate_traps_fpsimd32(vcpu);
 	}
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		val |= CPTR_EL2_TSM;
 
 	write_sysreg(val, cptr_el2);
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
+	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
 
@@ -94,9 +109,24 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
+	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+		u64 val;
+
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	cptr = CPTR_EL2_DEFAULT;
 	if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED))
 		cptr |= CPTR_EL2_TZ;
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		cptr &= ~CPTR_EL2_TSM;
 
 	write_sysreg(cptr, cptr_el2);
 	write_sysreg(__kvm_hyp_host_vector, vbar_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 619353b06e38..21217485514d 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,7 +38,8 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
-	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
+	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN |
+		 CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN);
 
 	/*
 	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -59,6 +60,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		__activate_traps_fpsimd32(vcpu);
 	}
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(val, cpacr_el1);
 
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
@@ -80,6 +85,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 	 */
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
 	write_sysreg(vectors, vbar_el1);
 }
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:07 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:07 +0000
Subject: [PATCH v9 27/40] KVM: arm64: Handle SME host state when running guests
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-28-broonie@kernel.org>

While we don't currently support SME in guests we do currently support it
for the host system so we need to take care of SME's impact, including
the floating point register state, when running guests. Simiarly to SVE
we need to manage the traps in CPACR_RL1, what is new is the handling of
streaming mode and ZA.

Normally we defer any handling of the floating point register state until
the guest first uses it however if the system is in streaming mode FPSIMD
and SVE operations may generate SME traps which we would need to distinguish
from actual attempts by the guest to use SME. Rather than do this for the
time being if we are in streaming mode when entering the guest we force
the floating point state to be saved immediately and exit streaming mode,
meaning that the guest won't generate SME traps for supported operations.

We could handle ZA in the access trap similarly to the FPSIMD/SVE state
without the disruption caused by streaming mode but for simplicity
handle it the same way as streaming mode for now.

This will be revisited when we support SME for guests (hopefully before SME
hardware becomes available), for now it will only incur additional cost on
systems with SME and even there only if streaming mode or ZA are enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/fpsimd.c           | 38 +++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7dc85d5a6552..404b7358ba96 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -438,6 +438,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
 #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
+#define KVM_ARM64_HOST_SME_ENABLED	(1 << 15) /* SME enabled for EL0 */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 338733ac63f8..cecaddb644ce 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -82,6 +82,26 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
 		vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
+
+	/*
+	 * We don't currently support SME guests but if we leave
+	 * things in streaming mode then when the guest starts running
+	 * FPSIMD or SVE code it may generate SME traps so as a
+	 * special case if we are in streaming mode we force the host
+	 * state to be saved now and exit streaming mode so that we
+	 * don't have to handle any SME traps for valid guest
+	 * operations. Do this for ZA as well for now for simplicity.
+	 */
+	if (system_supports_sme()) {
+		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
+			vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED;
+
+		if (read_sysreg_s(SYS_SVCR_EL0) &
+		    (SYS_SVCR_EL0_SM_MASK | SYS_SVCR_EL0_ZA_MASK)) {
+			vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
+			fpsimd_save_and_flush_cpu_state();
+		}
+	}
 }
 
 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
@@ -129,6 +149,24 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 
 	local_irq_save(flags);
 
+	/*
+	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
+	 * CPACR_EL1_DEFAULT and we need to reenable SME.
+	 */
+	if (has_vhe()) {
+		if (system_supports_sme()) {
+			/* Also restore EL0 state seen on entry */
+			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
+				sysreg_clear_set(CPACR_EL1, 0,
+						 CPACR_EL1_SMEN_EL0EN |
+						 CPACR_EL1_SMEN_EL1EN);
+			else
+				sysreg_clear_set(CPACR_EL1,
+						 CPACR_EL1_SMEN_EL0EN,
+						 CPACR_EL1_SMEN_EL1EN);
+		}
+	}
+
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
 		if (vcpu_has_sve(vcpu)) {
 			__vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:08 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:08 +0000
Subject: [PATCH v9 28/40] arm64/sme: Provide Kconfig for SME
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-29-broonie@kernel.org>

Now that basline support for the Scalable Matrix Extension (SME) is present
introduce the Kconfig option allowing it to be built. While the feature
registers don't impose a strong requirement for a system with SME to
support SVE at runtime the support for streaming mode SVE is mostly
shared with normal SVE so depend on SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..f60f3b04ddf5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1839,6 +1839,17 @@ config ARM64_SVE
 	  booting the kernel.  If unsure and you are not observing these
 	  symptoms, you should assume that it is safe to say Y.
 
+config ARM64_SME
+	bool "ARM Scalable Matrix Extension support"
+	default y
+	depends on ARM64_SVE
+	help
+	  The Scalable Matrix Extension (SME) is an extension to the AArch64
+	  execution state which utilises a substantial subset of the SVE
+	  instruction set, together with the addition of new architectural
+	  register state capable of holding two dimensional matrix tiles to
+	  enable various matrix operations.
+
 config ARM64_MODULE_PLTS
 	bool "Use PLTs to allow module memory to spill over into vmalloc area"
 	depends on MODULES
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:09 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:09 +0000
Subject: [PATCH v9 29/40] kselftest/arm64: sme: Add streaming SME support to
 vlset
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-30-broonie@kernel.org>

The Scalable Matrix Extenions (SME) introduces additional register state
with configurable vector lengths, similar to SVE but configured separately.
Extend vlset to support configuring this state with a --sme or -s command
line option.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/vlset.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/fp/vlset.c b/tools/testing/selftests/arm64/fp/vlset.c
index 308d27a68226..76912a581a95 100644
--- a/tools/testing/selftests/arm64/fp/vlset.c
+++ b/tools/testing/selftests/arm64/fp/vlset.c
@@ -22,12 +22,15 @@ static int inherit = 0;
 static int no_inherit = 0;
 static int force = 0;
 static unsigned long vl;
+static int set_ctl = PR_SVE_SET_VL;
+static int get_ctl = PR_SVE_GET_VL;
 
 static const struct option options[] = {
 	{ "force",	no_argument, NULL, 'f' },
 	{ "inherit",	no_argument, NULL, 'i' },
 	{ "max",	no_argument, NULL, 'M' },
 	{ "no-inherit",	no_argument, &no_inherit, 1 },
+	{ "sme",	no_argument, NULL, 's' },
 	{ "help",	no_argument, NULL, '?' },
 	{}
 };
@@ -50,6 +53,9 @@ static int parse_options(int argc, char **argv)
 		case 'M':	vl = SVE_VL_MAX; break;
 		case 'f':	force = 1; break;
 		case 'i':	inherit = 1; break;
+		case 's':	set_ctl = PR_SME_SET_VL;
+				get_ctl = PR_SME_GET_VL;
+				break;
 		case 0:		break;
 		default:	goto error;
 		}
@@ -125,14 +131,14 @@ int main(int argc, char **argv)
 	if (inherit)
 		flags |= PR_SVE_VL_INHERIT;
 
-	t = prctl(PR_SVE_SET_VL, vl | flags);
+	t = prctl(set_ctl, vl | flags);
 	if (t < 0) {
 		fprintf(stderr, "%s: PR_SVE_SET_VL: %s\n",
 			program_name, strerror(errno));
 		goto error;
 	}
 
-	t = prctl(PR_SVE_GET_VL);
+	t = prctl(get_ctl);
 	if (t == -1) {
 		fprintf(stderr, "%s: PR_SVE_GET_VL: %s\n",
 			program_name, strerror(errno));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:10 +0000
Subject: [PATCH v9 30/40] kselftest/arm64: Add tests for TPIDR2
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-31-broonie@kernel.org>

The Scalable Matrix Extension adds a new system register TPIDR2 intended to
be used by libc for its own thread specific use, add some kselftests which
exercise the ABI for it.

Since this test should with some adjustment work for TPIDR and any other
similar registers added in future add tests for it in a separate
directory rather than placing it with the other floating point tests,
nothing existing looked suitable so I created a new test directory
called "abi".

Since this feature is intended to be used by libc the test is built as
freestanding code using nolibc so we don't end up with the test program
and libc both trying to manage the register simultaneously and
distrupting each other. As a result of being written using nolibc rather
than using hwcaps to identify if SME is available in the system we check
for the default SME vector length configuration in proc, adding hwcap
support to nolibc seems like disproportionate effort and didn't feel
entirely idiomatic for what nolibc is trying to do.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/.gitignore |   1 +
 tools/testing/selftests/arm64/abi/Makefile   |   9 +-
 tools/testing/selftests/arm64/abi/tpidr2.c   | 298 +++++++++++++++++++
 3 files changed, 307 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c

diff --git a/tools/testing/selftests/arm64/abi/.gitignore b/tools/testing/selftests/arm64/abi/.gitignore
index b79cf5814c23..b9e54417250d 100644
--- a/tools/testing/selftests/arm64/abi/.gitignore
+++ b/tools/testing/selftests/arm64/abi/.gitignore
@@ -1 +1,2 @@
 syscall-abi
+tpidr2
diff --git a/tools/testing/selftests/arm64/abi/Makefile b/tools/testing/selftests/arm64/abi/Makefile
index 96eba974ac8d..c8d7f2495eb2 100644
--- a/tools/testing/selftests/arm64/abi/Makefile
+++ b/tools/testing/selftests/arm64/abi/Makefile
@@ -1,8 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (C) 2021 ARM Limited
 
-TEST_GEN_PROGS := syscall-abi
+TEST_GEN_PROGS := syscall-abi tpidr2
 
 include ../../lib.mk
 
 $(OUTPUT)/syscall-abi: syscall-abi.c syscall-abi-asm.S
+
+# Build with nolibc since TPIDR2 is intended to be actively managed by
+# libc and we're trying to test the functionality that it depends on here.
+$(OUTPUT)/tpidr2: tpidr2.c
+	$(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+		-static -include ../../../../include/nolibc/nolibc.h \
+		-ffreestanding -Wall $^ -o $@ -lgcc
diff --git a/tools/testing/selftests/arm64/abi/tpidr2.c b/tools/testing/selftests/arm64/abi/tpidr2.c
new file mode 100644
index 000000000000..351a098b503a
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/tpidr2.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#define SYS_TPIDR2 "S3_3_C13_C0_5"
+
+#define EXPECTED_TESTS 5
+
+static void putstr(const char *str)
+{
+	write(1, str, strlen(str));
+}
+
+static void putnum(unsigned int num)
+{
+	char c;
+
+	if (num / 10)
+		putnum(num / 10);
+
+	c = '0' + (num % 10);
+	write(1, &c, 1);
+}
+
+static int tests_run;
+static int tests_passed;
+static int tests_failed;
+static int tests_skipped;
+
+static void set_tpidr2(uint64_t val)
+{
+	asm volatile (
+		"msr	" SYS_TPIDR2 ", %0\n"
+		:
+		: "r"(val)
+		: "cc");
+}
+
+static uint64_t get_tpidr2(void)
+{
+	uint64_t val;
+
+	asm volatile (
+		"mrs	%0, " SYS_TPIDR2 "\n"
+		: "=r"(val)
+		:
+		: "cc");
+
+	return val;
+}
+
+static void print_summary(void)
+{
+	if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS)
+		putstr("# UNEXPECTED TEST COUNT: ");
+
+	putstr("# Totals: pass:");
+	putnum(tests_passed);
+	putstr(" fail:");
+	putnum(tests_failed);
+	putstr(" xfail:0 xpass:0 skip:");
+	putnum(tests_skipped);
+	putstr(" error:0\n");
+}
+
+/* Processes should start with TPIDR2 == 0 */
+static int default_value(void)
+{
+	return get_tpidr2() == 0;
+}
+
+/* If we set TPIDR2 we should read that value */
+static int write_read(void)
+{
+	set_tpidr2(getpid());
+
+	return getpid() == get_tpidr2();
+}
+
+/* If we set a value we should read the same value after scheduling out */
+static int write_sleep_read(void)
+{
+	set_tpidr2(getpid());
+
+	msleep(100);
+
+	return getpid() == get_tpidr2();
+}
+
+/*
+ * If we fork the value in the parent should be unchanged and the
+ * child should start with the same value and be able to set its own
+ * value.
+ */
+static int write_fork_read(void)
+{
+	pid_t newpid, waiting, oldpid;
+	int status;
+
+	set_tpidr2(getpid());
+
+	oldpid = getpid();
+	newpid = fork();
+	if (newpid == 0) {
+		/* In child */
+		if (get_tpidr2() != oldpid) {
+			putstr("# TPIDR2 changed in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		set_tpidr2(getpid());
+		if (get_tpidr2() == getpid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+	if (newpid < 0) {
+		putstr("# fork() failed: -");
+		putnum(-newpid);
+		putstr("\n");
+		return 0;
+	}
+
+	for (;;) {
+		waiting = waitpid(newpid, &status, 0);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# waitpid() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != newpid) {
+			putstr("# waitpid() returned wrong PID\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (getpid() != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+/*
+ * sys_clone() has a lot of per architecture variation so just define
+ * it here rather than adding it to nolibc, plus the raw API is a
+ * little more convenient for this test.
+ */
+static int sys_clone(unsigned long clone_flags, unsigned long newsp,
+		     int *parent_tidptr, unsigned long tls,
+		     int *child_tidptr)
+{
+	return my_syscall5(__NR_clone, clone_flags, newsp, parent_tidptr, tls,
+			   child_tidptr);
+}
+
+/*
+ * If we clone with CLONE_SETTLS then the value in the parent should
+ * be unchanged and the child should start with zero and be able to
+ * set its own value.
+ */
+static int write_clone_read(void)
+{
+	int parent_tid, child_tid;
+	pid_t parent, waiting;
+	int ret, status;
+
+	parent = getpid();
+	set_tpidr2(parent);
+
+	ret = sys_clone(CLONE_SETTLS, 0, &parent_tid, 0, &child_tid);
+	if (ret == -1) {
+		putstr("# clone() failed\n");
+		putnum(errno);
+		putstr("\n");
+		return 0;
+	}
+
+	if (ret == 0) {
+		/* In child */
+		if (get_tpidr2() != 0) {
+			putstr("# TPIDR2 non-zero in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		if (gettid() == 0)
+			putstr("# Child TID==0\n");
+		set_tpidr2(gettid());
+		if (get_tpidr2() == gettid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+
+	for (;;) {
+		waiting = wait4(ret, &status, __WCLONE, NULL);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# wait4() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != ret) {
+			putstr("# wait4() returned wrong PID ");
+			putnum(waiting);
+			putstr("\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (parent != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+#define run_test(name)			     \
+	if (name()) {			     \
+		tests_passed++;		     \
+	} else {			     \
+		tests_failed++;		     \
+		putstr("not ");		     \
+	}				     \
+	putstr("ok ");			     \
+	putnum(++tests_run);		     \
+	putstr(" " #name "\n");
+
+int main(int argc, char **argv)
+{
+	int ret, i;
+
+	putstr("TAP version 13\n");
+	putstr("1..");
+	putnum(EXPECTED_TESTS);
+	putstr("\n");
+
+	putstr("# PID: ");
+	putnum(getpid());
+	putstr("\n");
+
+	/*
+	 * This test is run with nolibc which doesn't support hwcap and
+	 * it's probably disproportionate to implement so instead check
+	 * for the default vector length configuration in /proc.
+	 */
+	ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
+	if (ret >= 0) {
+		run_test(default_value);
+		run_test(write_read);
+		run_test(write_sleep_read);
+		run_test(write_fork_read);
+		run_test(write_clone_read);
+
+	} else {
+		putstr("# SME support not present\n");
+
+		for (i = 0; i < EXPECTED_TESTS; i++) {
+			putstr("ok ");
+			putnum(i);
+			putstr(" skipped, TPIDR2 not supported\n");
+		}
+
+		tests_skipped += EXPECTED_TESTS;
+	}
+
+	print_summary();
+
+	return 0;
+}
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:12 +0000
Subject: [PATCH v9 32/40] kselftest/arm64: sme: Provide streaming mode SVE
 stress test
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-33-broonie@kernel.org>

One of the features of SME is the addition of streaming mode, in which we
have access to a set of streaming mode SVE registers at the SME vector
length. Since these are accessed using the SVE instructions let's reuse
the existing SVE stress test for testing with a compile time option for
controlling the few small differences needed:

 - Enter streaming mode immediately on starting the program.
 - In streaming mode FFR is removed so skip reading and writing FFR.

In order to avoid requiring a cutting edge toolchain with SME support
use the op/CR form for specifying SVCR.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |  1 +
 tools/testing/selftests/arm64/fp/Makefile    |  3 +
 tools/testing/selftests/arm64/fp/ssve-stress | 59 ++++++++++++++++++++
 tools/testing/selftests/arm64/fp/sve-test.S  | 30 ++++++++++
 4 files changed, 93 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 6e9a610c5e5d..5729a5b1adfc 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -5,5 +5,6 @@ rdvl-sve
 sve-probe-vls
 sve-ptrace
 sve-test
+ssve-test
 vec-syscfg
 vlset
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index a224fff8082b..e6643c9b0474 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -5,6 +5,7 @@ TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
+	ssve-test ssve-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -19,6 +20,8 @@ sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
 sve-test: sve-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+ssve-test: sve-test.S asm-utils.o
+	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 
diff --git a/tools/testing/selftests/arm64/fp/ssve-stress b/tools/testing/selftests/arm64/fp/ssve-stress
new file mode 100644
index 000000000000..e2bd2cc184ad
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/ssve-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./ssve-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S
index f5b1b48ffff2..31764e8370db 100644
--- a/tools/testing/selftests/arm64/fp/sve-test.S
+++ b/tools/testing/selftests/arm64/fp/sve-test.S
@@ -156,6 +156,7 @@ endfunction
 // We fill the upper lanes of FFR with zeros.
 // Beware: corrupts P0.
 function setup_ffr
+#ifndef SSVE
 	mov	x4, x30
 
 	and	w0, w0, #0x3
@@ -178,6 +179,9 @@ function setup_ffr
 	wrffr	p0.b
 
 	ret	x4
+#else
+	ret
+#endif
 endfunction
 
 // Trivial memory compare: compare x2 bytes starting at address x0 with
@@ -260,6 +264,7 @@ endfunction
 // Beware -- corrupts P0.
 // Clobbers x0-x5.
 function check_ffr
+#ifndef SSVE
 	mov	x3, x30
 
 	ldr	x4, =scratch
@@ -280,6 +285,9 @@ function check_ffr
 	mov	x2, x5
 	mov	x30, x3
 	b	memcmp
+#else
+	ret
+#endif
 endfunction
 
 // Any SVE register modified here can cause corruption in the main
@@ -295,13 +303,26 @@ function irritator_handler
 	movi	v0.8b, #1
 	movi	v9.16b, #2
 	movi	v31.8b, #3
+#ifndef SSVE
 	// And P0
 	rdffr	p0.b
 	// And FFR
 	wrffr	p15.b
+#endif
+
+	ret
+endfunction
+
+#ifdef SSVE
+function enable_sm
+	// Set SVCR.SM to 1, equivalent to SMSTART SM but doesn't need a
+	// SME capable toolchain.
+	mov	x0, #1
+	msr	S3_3_C4_C2_2, x0
 
 	ret
 endfunction
+#endif
 
 function terminate_handler
 	mov	w21, w0
@@ -359,6 +380,11 @@ endfunction
 .globl _start
 function _start
 _start:
+#ifdef SSVE
+	puts	"Streaming mode "
+	bl	enable_sm
+#endif
+
 	// Sanity-check and report the vector length
 
 	rdvl	x19, #8
@@ -407,6 +433,10 @@ _start:
 	orr	w2, w2, #SA_NODEFER
 	bl	setsignal
 
+#ifdef SSVE
+	bl	enable_sm	// syscalls will have exited streaming mode
+#endif
+
 	mov	x22, #0		// generation number, increments per iteration
 .Ltest_loop:
 	rdvl	x0, #8
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:11 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:11 +0000
Subject: [PATCH v9 31/40] kselftest/arm64: Extend vector configuration API
 tests to cover SME
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-32-broonie@kernel.org>

Provide RDVL helpers for SME and extend the main vector configuration tests
to cover SME.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore   |  1 +
 tools/testing/selftests/arm64/fp/Makefile     |  3 ++-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   | 14 ++++++++++++++
 tools/testing/selftests/arm64/fp/rdvl.S       |  8 ++++++++
 tools/testing/selftests/arm64/fp/rdvl.h       |  1 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 10 ++++++++++
 6 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index c50d86331ed2..6e9a610c5e5d 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -1,5 +1,6 @@
 fp-pidbench
 fpsimd-test
+rdvl-sme
 rdvl-sve
 sve-probe-vls
 sve-ptrace
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 95f0b877a060..a224fff8082b 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -3,7 +3,7 @@
 CFLAGS += -I../../../../../usr/include/
 TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
-	rdvl-sve \
+	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	vlset
 
@@ -13,6 +13,7 @@ fp-pidbench: fp-pidbench.S asm-utils.o
 	$(CC) -nostdlib $^ -o $@
 fpsimd-test: fpsimd-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+rdvl-sme: rdvl-sme.o rdvl.o
 rdvl-sve: rdvl-sve.o rdvl.o
 sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
diff --git a/tools/testing/selftests/arm64/fp/rdvl-sme.c b/tools/testing/selftests/arm64/fp/rdvl-sme.c
new file mode 100644
index 000000000000..49b0b2e08bac
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl-sme.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <stdio.h>
+
+#include "rdvl.h"
+
+int main(void)
+{
+	int vl = rdvl_sme();
+
+	printf("%d\n", vl);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/arm64/fp/rdvl.S b/tools/testing/selftests/arm64/fp/rdvl.S
index c916c1c9defd..1a2ebf07a20c 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.S
+++ b/tools/testing/selftests/arm64/fp/rdvl.S
@@ -8,3 +8,11 @@ rdvl_sve:
 	hint	34			// BTI C
 	rdvl	x0, #1
 	ret
+
+.globl rdvl_sme
+rdvl_sme:
+	hint	34			// BTI C
+
+	.inst	0x4bf5820		// RDSVL x0, #1
+
+	ret
diff --git a/tools/testing/selftests/arm64/fp/rdvl.h b/tools/testing/selftests/arm64/fp/rdvl.h
index 7c9d953fc9e7..5d323679fbc9 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.h
+++ b/tools/testing/selftests/arm64/fp/rdvl.h
@@ -3,6 +3,7 @@
 #ifndef RDVL_H
 #define RDVL_H
 
+int rdvl_sme(void);
 int rdvl_sve(void);
 
 #endif
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index c90658811a83..9bcfcdc34ee9 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -51,6 +51,16 @@ static struct vec_data vec_data[] = {
 		.prctl_set = PR_SVE_SET_VL,
 		.default_vl_file = "/proc/sys/abi/sve_default_vector_length",
 	},
+	{
+		.name = "SME",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.rdvl = rdvl_sme,
+		.rdvl_binary = "./rdvl-sme",
+		.prctl_get = PR_SME_GET_VL,
+		.prctl_set = PR_SME_SET_VL,
+		.default_vl_file = "/proc/sys/abi/sme_default_vector_length",
+	},
 };
 
 static int stdio_read_integer(FILE *f, const char *what, int *val)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:13 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:13 +0000
Subject: [PATCH v9 33/40] kselftest/arm64: signal: Allow tests to be
 incompatible with features
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-34-broonie@kernel.org>

Some features may invalidate some tests, for example by supporting an
operation which would trap otherwise. Allow tests to list features that
they are incompatible with so we can cover the case where a signal will
be generated without disruption on systems where that won't happen.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/signal/test_signals.h     |  1 +
 .../arm64/signal/test_signals_utils.c         | 34 ++++++++++++++-----
 .../arm64/signal/test_signals_utils.h         |  2 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index ebe8694dbef0..f909b70d9e98 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -53,6 +53,7 @@ struct tdescr {
 	char			*name;
 	char			*descr;
 	unsigned long		feats_required;
+	unsigned long		feats_incompatible;
 	/* bitmask of effectively supported feats: populated at run-time */
 	unsigned long		feats_supported;
 	bool			initialized;
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 2f8c23af3b5e..5743897984b0 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -36,6 +36,8 @@ static inline char *feats_to_string(unsigned long feats)
 {
 	size_t flen = MAX_FEATS_SZ - 1;
 
+	feats_string[0] = '\0';
+
 	for (int i = 0; i < FMAX_END; i++) {
 		if (feats & (1UL << i)) {
 			size_t tlen = strlen(feats_names[i]);
@@ -256,7 +258,7 @@ int test_init(struct tdescr *td)
 		td->minsigstksz = MINSIGSTKSZ;
 	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
 
-	if (td->feats_required) {
+	if (td->feats_required || td->feats_incompatible) {
 		td->feats_supported = 0;
 		/*
 		 * Checking for CPU required features using both the
@@ -267,15 +269,29 @@ int test_init(struct tdescr *td)
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
 		if (feats_ok(td)) {
-			fprintf(stderr,
-				"Required Features: [%s] supported\n",
-				feats_to_string(td->feats_required &
-						td->feats_supported));
+			if (td->feats_required & td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] supported\n",
+					feats_to_string(td->feats_required &
+							td->feats_supported));
+			if (!(td->feats_incompatible & td->feats_supported))
+				fprintf(stderr,
+					"Incompatible Features: [%s] absent\n",
+					feats_to_string(td->feats_incompatible));
 		} else {
-			fprintf(stderr,
-				"Required Features: [%s] NOT supported\n",
-				feats_to_string(td->feats_required &
-						~td->feats_supported));
+			if ((td->feats_required & td->feats_supported) !=
+			    td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] NOT supported\n",
+					feats_to_string(td->feats_required &
+							~td->feats_supported));
+			if (td->feats_incompatible & td->feats_supported)
+				fprintf(stderr,
+					"Incompatible Features: [%s] supported\n",
+					feats_to_string(td->feats_incompatible &
+							~td->feats_supported));
+
+
 			td->result = KSFT_SKIP;
 			return 0;
 		}
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 6772b5c8d274..f3aa99ba67bb 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -18,6 +18,8 @@ void test_result(struct tdescr *td);
 
 static inline bool feats_ok(struct tdescr *td)
 {
+	if (td->feats_incompatible & td->feats_supported)
+		return false;
 	return (td->feats_required & td->feats_supported) == td->feats_required;
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:14 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:14 +0000
Subject: [PATCH v9 34/40] kselftest/arm64: signal: Handle ZA signal context in
 core code
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-35-broonie@kernel.org>

As part of the generic code for signal handling test cases we parse all
signal frames to make sure they have at least the basic form we expect
and that there are no unexpected frames present in the signal context.
Add coverage of the ZA signal frame to this code.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../arm64/signal/testcases/testcases.c        | 36 +++++++++++++++++++
 .../arm64/signal/testcases/testcases.h        |  3 +-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
index 8c2a57fc2f9c..84c36bee4d82 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
@@ -75,6 +75,31 @@ bool validate_sve_context(struct sve_context *sve, char **err)
 	return true;
 }
 
+bool validate_za_context(struct za_context *za, char **err)
+{
+	/* Size will be rounded up to a multiple of 16 bytes */
+	size_t regs_size
+		= ((ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za->vl)) + 15) / 16) * 16;
+
+	if (!za || !err)
+		return false;
+
+	/* Either a bare za_context or a za_context followed by regs data */
+	if ((za->head.size != sizeof(struct za_context)) &&
+	    (za->head.size != regs_size)) {
+		*err = "bad size for ZA context";
+		return false;
+	}
+
+	if (!sve_vl_valid(za->vl)) {
+		*err = "SME VL in ZA context invalid";
+
+		return false;
+	}
+
+	return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
 	bool terminated = false;
@@ -82,6 +107,7 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 	int flags = 0;
 	struct extra_context *extra = NULL;
 	struct sve_context *sve = NULL;
+	struct za_context *za = NULL;
 	struct _aarch64_ctx *head =
 		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
 
@@ -120,6 +146,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 			sve = (struct sve_context *)head;
 			flags |= SVE_CTX;
 			break;
+		case ZA_MAGIC:
+			if (flags & ZA_CTX)
+				*err = "Multiple ZA_MAGIC";
+			/* Size is validated in validate_za_context() */
+			za = (struct za_context *)head;
+			flags |= ZA_CTX;
+			break;
 		case EXTRA_MAGIC:
 			if (flags & EXTRA_CTX)
 				*err = "Multiple EXTRA_MAGIC";
@@ -165,6 +198,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 		if (flags & SVE_CTX)
 			if (!validate_sve_context(sve, err))
 				return false;
+		if (flags & ZA_CTX)
+			if (!validate_za_context(za, err))
+				return false;
 
 		head = GET_RESV_NEXT_HEAD(head);
 	}
diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
index ad884c135314..49f1d5de7b5b 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.h
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
@@ -16,7 +16,8 @@
 
 #define FPSIMD_CTX	(1 << 0)
 #define SVE_CTX		(1 << 1)
-#define EXTRA_CTX	(1 << 2)
+#define ZA_CTX		(1 << 2)
+#define EXTRA_CTX	(1 << 3)
 
 #define KSFT_BAD_MAGIC	0xdeadbeef
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:15 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:15 +0000
Subject: [PATCH v9 35/40] kselftest/arm64: Add stress test for SME ZA context
 switching
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-36-broonie@kernel.org>

Add a stress test for context switching of the ZA register state based on
the similar tests Dave Martin wrote for FPSIMD and SVE registers. The test
loops indefinitely writing a data pattern to ZA then reading it back and
verifying that it's what was expected.

Unlike the other tests we manually assemble the SME instructions since at
present no released toolchain has SME support integrated.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore |   1 +
 tools/testing/selftests/arm64/fp/Makefile   |   3 +
 tools/testing/selftests/arm64/fp/za-stress  |  59 +++
 tools/testing/selftests/arm64/fp/za-test.S  | 426 ++++++++++++++++++++
 4 files changed, 489 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 5729a5b1adfc..ead3197e720b 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,3 +8,4 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index e6643c9b0474..38d2d0d5a0eb 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -6,6 +6,7 @@ TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	ssve-test ssve-stress \
+	za-test za-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -24,5 +25,7 @@ ssve-test: sve-test.S asm-utils.o
 	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
+za-test: za-test.o asm-utils.o
+	$(CC) -nostdlib $^ -o $@
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-stress b/tools/testing/selftests/arm64/fp/za-stress
new file mode 100644
index 000000000000..5ac386b55b95
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./za-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/za-test.S b/tools/testing/selftests/arm64/fp/za-test.S
new file mode 100644
index 000000000000..99e1bb3b6b18
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-test.S
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2021 ARM Limited.
+// Original author: Mark Brown <broonie at kernel.org>
+//
+// Scalable Matrix Extension ZA context switch test
+// Repeatedly writes unique test patterns into each ZA tile
+// and reads them back to verify integrity.
+//
+// for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
+// (leave it running for as long as you want...)
+// kill $pids
+
+#include <asm/unistd.h>
+#include "assembler.h"
+#include "asm-offsets.h"
+
+.arch_extension sve
+
+#define MAXVL     2048
+#define MAXVL_B   (MAXVL / 8)
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * RDSVL X\nx, #\imm
+ */
+.macro rdsvl nx, imm
+	.inst	0x4bf5800			\
+		| (\imm << 5)			\
+		| (\nx)
+.endm
+
+.macro smstop
+	msr	S0_3_C4_C6_3, xzr
+.endm
+
+.macro smstart_za
+	msr	S0_3_C4_C5_3, xzr
+.endm
+
+// Declare some storage space to shadow ZA register contents and a
+// scratch buffer for a vector.
+.pushsection .text
+.data
+.align 4
+zaref:
+	.space	MAXVL_B * MAXVL_B
+scratch:
+	.space	MAXVL_B
+.popsection
+
+// Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
+// Clobbers x0-x3
+function memcpy
+	cmp	x2, #0
+	b.eq	1f
+0:	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	0b
+1:	ret
+endfunction
+
+// Generate a test pattern for storage in ZA
+// x0: pid
+// x1: row in ZA
+// x2: generation
+
+// These values are used to constuct a 32-bit pattern that is repeated in the
+// scratch buffer as many times as will fit:
+// bits 31:28	generation number (increments once per test_loop)
+// bits 27:16	pid
+// bits 15: 8	row number
+// bits  7: 0	32-bit lane index
+
+function pattern
+	mov	w3, wzr
+	bfi	w3, w0, #16, #12	// PID
+	bfi	w3, w1, #8, #8		// Row
+	bfi	w3, w2, #28, #4		// Generation
+
+	ldr	x0, =scratch
+	mov	w1, #MAXVL_B / 4
+
+0:	str	w3, [x0], #4
+	add	w3, w3, #1		// Lane
+	subs	w1, w1, #1
+	b.ne	0b
+
+	ret
+endfunction
+
+// Get the address of shadow data for ZA horizontal vector xn
+.macro _adrza xd, xn, nrtmp
+	ldr	\xd, =zaref
+	rdsvl	\nrtmp, 1
+	madd	\xd, x\nrtmp, \xn, \xd
+.endm
+
+// Set up test pattern in a ZA horizontal vector
+// x0: pid
+// x1: row number
+// x2: generation
+function setup_za
+	mov	x4, x30
+	mov	x12, x1			// Use x12 for vector select
+
+	bl	pattern			// Get pattern in scratch buffer
+	_adrza	x0, x12, 2		// Shadow buffer pointer to x0 and x5
+	mov	x5, x0
+	ldr	x1, =scratch
+	bl	memcpy			// length set up in x2 by _adrza
+
+	_ldr_za 12, 5			// load vector w12 from pointer x5
+
+	ret	x4
+endfunction
+
+// Trivial memory compare: compare x2 bytes starting at address x0 with
+// bytes starting at address x1.
+// Returns only if all bytes match; otherwise, the program is aborted.
+// Clobbers x0-x5.
+function memcmp
+	cbz	x2, 2f
+
+	stp	x0, x1, [sp, #-0x20]!
+	str	x2, [sp, #0x10]
+
+	mov	x5, #0
+0:	ldrb	w3, [x0, x5]
+	ldrb	w4, [x1, x5]
+	add	x5, x5, #1
+	cmp	w3, w4
+	b.ne	1f
+	subs	x2, x2, #1
+	b.ne	0b
+
+1:	ldr	x2, [sp, #0x10]
+	ldp	x0, x1, [sp], #0x20
+	b.ne	barf
+
+2:	ret
+endfunction
+
+// Verify that a ZA vector matches its shadow in memory, else abort
+// x0: row number
+// Clobbers x0-x7 and x12.
+function check_za
+	mov	x3, x30
+
+	mov	x12, x0
+	_adrza	x5, x0, 6		// pointer to expected value in x5
+	mov	x4, x0
+	ldr	x7, =scratch		// x7 is scratch
+
+	mov	x0, x7			// Poison scratch
+	mov	x1, x6
+	bl	memfill_ae
+
+	_str_za 12, 7			// save vector w12 to pointer x7
+
+	mov	x0, x5
+	mov	x1, x7
+	mov	x2, x6
+	mov	x30, x3
+	b	memcmp
+endfunction
+
+// Any SME register modified here can cause corruption in the main
+// thread -- but *only* the locations modified here.
+function irritator_handler
+	// Increment the irritation signal count (x23):
+	ldr	x0, [x2, #ucontext_regs + 8 * 23]
+	add	x0, x0, #1
+	str	x0, [x2, #ucontext_regs + 8 * 23]
+
+	// Corrupt some random ZA data
+#if 0
+	adr	x0, .text + (irritator_handler - .text) / 16 * 16
+	movi	v0.8b, #1
+	movi	v9.16b, #2
+	movi	v31.8b, #3
+#endif
+
+	ret
+endfunction
+
+function terminate_handler
+	mov	w21, w0
+	mov	x20, x2
+
+	puts	"Terminated by signal "
+	mov	w0, w21
+	bl	putdec
+	puts	", no error, iterations="
+	ldr	x0, [x20, #ucontext_regs + 8 * 22]
+	bl	putdec
+	puts	", signals="
+	ldr	x0, [x20, #ucontext_regs + 8 * 23]
+	bl	putdecn
+
+	mov	x0, #0
+	mov	x8, #__NR_exit
+	svc	#0
+endfunction
+
+// w0: signal number
+// x1: sa_action
+// w2: sa_flags
+// Clobbers x0-x6,x8
+function setsignal
+	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
+
+	mov	w4, w0
+	mov	x5, x1
+	mov	w6, w2
+
+	add	x0, sp, #16
+	mov	x1, #sa_sz
+	bl	memclr
+
+	mov	w0, w4
+	add	x1, sp, #16
+	str	w6, [x1, #sa_flags]
+	str	x5, [x1, #sa_handler]
+	mov	x2, #0
+	mov	x3, #sa_mask_sz
+	mov	x8, #__NR_rt_sigaction
+	svc	#0
+
+	cbz	w0, 1f
+
+	puts	"sigaction failure\n"
+	b	.Labort
+
+1:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
+	ret
+endfunction
+
+// Main program entry point
+.globl _start
+function _start
+_start:
+	puts	"Streaming mode "
+	smstart_za
+
+	// Sanity-check and report the vector length
+
+	rdsvl	19, 8
+	cmp	x19, #128
+	b.lo	1f
+	cmp	x19, #2048
+	b.hi	1f
+	tst	x19, #(8 - 1)
+	b.eq	2f
+
+1:	puts	"bad vector length: "
+	mov	x0, x19
+	bl	putdecn
+	b	.Labort
+
+2:	puts	"vector length:\t"
+	mov	x0, x19
+	bl	putdec
+	puts	" bits\n"
+
+	// Obtain our PID, to ensure test pattern uniqueness between processes
+	mov	x8, #__NR_getpid
+	svc	#0
+	mov	x20, x0
+
+	puts	"PID:\t"
+	mov	x0, x20
+	bl	putdecn
+
+	mov	x23, #0		// Irritation signal count
+
+	mov	w0, #SIGINT
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGTERM
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGUSR1
+	adr	x1, irritator_handler
+	mov	w2, #SA_SIGINFO
+	orr	w2, w2, #SA_NODEFER
+	bl	setsignal
+
+	mov	x22, #0		// generation number, increments per iteration
+.Ltest_loop:
+	rdsvl	0, 8
+	cmp	x0, x19
+	b.ne	vl_barf
+
+	rdsvl	21, 1		// Set up ZA & shadow with test pattern
+0:	mov	x0, x20
+	sub	x1, x21, #1
+	mov	x2, x22
+	bl	setup_za
+	subs	x21, x21, #1
+	b.ne	0b
+
+	and	x8, x22, #127		// Every 128 interations...
+	cbz	x8, 0f
+	mov	x8, #__NR_getpid	// (otherwise minimal syscall)
+	b	1f
+0:
+	mov	x8, #__NR_sched_yield	// ...encourage preemption
+1:
+	svc	#0
+
+	mrs	x0, S3_3_C4_C2_2	// SVCR should have ZA=1,SM=0
+	and	x1, x0, #3
+	cmp	x1, #2
+	b.ne	svcr_barf
+
+	rdsvl	21, 1			// Verify that the data made it through
+	rdsvl	24, 1			// Verify that the data made it through
+0:	sub	x0, x24, x21
+	bl	check_za
+	subs	x21, x21, #1
+	bne	0b
+
+	add	x22, x22, #1	// Everything still working
+	b	.Ltest_loop
+
+.Labort:
+	mov	x0, #0
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+endfunction
+
+function barf
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// end hack
+	smstop
+	mov	x10, x0	// expected data
+	mov	x11, x1	// actual data
+	mov	x12, x2	// data size
+
+	puts	"Mismatch: PID="
+	mov	x0, x20
+	bl	putdec
+	puts	", iteration="
+	mov	x0, x22
+	bl	putdec
+	puts	", row="
+	mov	x0, x21
+	bl	putdecn
+	puts	"\tExpected ["
+	mov	x0, x10
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n\tGot      ["
+	mov	x0, x11
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n"
+
+	mov	x8, #__NR_getpid
+	svc	#0
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// ^ end of hack
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+//	mov	x8, #__NR_exit
+//	mov	x1, #1
+//	svc	#0
+endfunction
+
+function vl_barf
+	mov	x10, x0
+
+	puts	"Bad active VL: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
+
+function svcr_barf
+	mov	x10, x0
+
+	puts	"Bad SVCR: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:16 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:16 +0000
Subject: [PATCH v9 36/40] kselftest/arm64: signal: Add SME signal handling
 tests
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-37-broonie@kernel.org>

Add test cases for the SME signal handing ABI patterned off the SVE tests.
Due to the small size of the tests and the differences in ABI (especially
around needing to account for both streaming SVE and ZA) there is some code
duplication here.

We currently cover:
 - Reporting of the vector length.
 - Lack of support for changing vector length.
 - Presence and size of register state for streaming SVE and ZA.

As with the SVE tests we do not yet have any validation of register
contents.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   4 +
 .../arm64/signal/test_signals_utils.c         |   6 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++++++++++++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++++++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++++++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 +++++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 +++++++++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++++++++++++++++
 9 files changed, 420 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index c1742755abb9..4de8eb26d4de 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mangle_*
 fake_sigreturn_*
+sme_*
+ssve_*
 sve_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index f909b70d9e98..c70fdec7d7c4 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -34,11 +34,15 @@
 enum {
 	FSSBS_BIT,
 	FSVE_BIT,
+	FSME_BIT,
+	FSME_FA64_BIT,
 	FMAX_END
 };
 
 #define FEAT_SSBS		(1UL << FSSBS_BIT)
 #define FEAT_SVE		(1UL << FSVE_BIT)
+#define FEAT_SME		(1UL << FSME_BIT)
+#define FEAT_SME_FA64		(1UL << FSME_FA64_BIT)
 
 /*
  * A descriptor used to describe and configure a test case.
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 5743897984b0..b588d10afd5b 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -27,6 +27,8 @@ static int sig_copyctx = SIGTRAP;
 static char const *const feats_names[FMAX_END] = {
 	" SSBS ",
 	" SVE ",
+	" SME ",
+	" FA64 ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -268,6 +270,10 @@ int test_init(struct tdescr *td)
 			td->feats_supported |= FEAT_SSBS;
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+			td->feats_supported |= FEAT_SME;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+			td->feats_supported |= FEAT_SME_FA64;
 		if (feats_ok(td)) {
 			if (td->feats_required & td->feats_supported)
 				fprintf(stderr,
diff --git a/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
new file mode 100644
index 000000000000..7ed762b7202f
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Attempt to change the streaming SVE vector length in a signal
+ * handler, this is not supported and is expected to segfault.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least two VLs */
+	if (nvls < 2) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static int fake_sigreturn_ssve_change_vl(struct tdescr *td,
+					 siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	/* Get a signal context with a SME ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	if (head->size != sizeof(struct sve_context)) {
+		fprintf(stderr, "Register data present, aborting\n");
+		return 1;
+	}
+
+	sve = (struct sve_context *)head;
+
+	/* No changes are supported; init left us at minimum VL so go to max */
+	fprintf(stderr, "Attempting to change VL from %d to %d\n",
+		sve->vl, vls[0]);
+	sve->vl = vls[0];
+
+	fake_sigreturn(&sf, sizeof(sf), 0);
+
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "FAKE_SIGRETURN_SSVE_CHANGE",
+	.descr = "Attempt to change Streaming SVE VL",
+	.feats_required = FEAT_SME,
+	.sig_ok = SIGSEGV,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = fake_sigreturn_ssve_change_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
new file mode 100644
index 000000000000..f9d76ae32bba
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using a streaming mode instruction without enabling it
+ * generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_no_sm_trigger(struct tdescr *td)
+{
+	/* SMSTART ZA ; ADDHA ZA0.S, P0/M, P0/M, Z0.S */
+	asm volatile(".inst 0xd503457f ; .inst 0xc0900000");
+
+	return 0;
+}
+
+int sme_trap_no_sm_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME trap without SM",
+	.descr = "Check that we get a SIGILL if we use streaming mode without enabling it",
+	.timeout = 3,
+	.feats_required = FEAT_SME,   /* We need a SMSTART ZA */
+	.sanity_disabled = true,
+	.trigger = sme_trap_no_sm_trigger,
+	.run = sme_trap_no_sm_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
new file mode 100644
index 000000000000..e469ae5348e3
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using an instruction not supported in streaming mode
+ * traps when in streaming mode.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_non_streaming_trigger(struct tdescr *td)
+{
+	/*
+	 * The framework will handle SIGILL so we need to exit SM to
+	 * stop any other code triggering a further SIGILL down the
+	 * line from using a streaming-illegal instruction.
+	 */
+	asm volatile(".inst 0xd503437f; /* SMSTART ZA */ \
+		      cnt v0.16b, v0.16b; \
+                      .inst 0xd503447f  /* SMSTOP ZA */");
+
+	return 0;
+}
+
+int sme_trap_non_streaming_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME SM trap unsupported instruction",
+	.descr = "Check that we get a SIGILL if we use an unsupported instruction in streaming mode",
+	.feats_required = FEAT_SME,
+	.feats_incompatible = FEAT_SME_FA64,
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_non_streaming_trigger,
+	.run = sme_trap_non_streaming_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
new file mode 100644
index 000000000000..3a7747af4715
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that accessing ZA without enabling it generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_za_trigger(struct tdescr *td)
+{
+	/* ZERO ZA */
+	asm volatile(".inst 0xc00800ff");
+
+	return 0;
+}
+
+int sme_trap_za_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME ZA trap",
+	.descr = "Check that we get a SIGILL if we access ZA without enabling",
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_za_trigger,
+	.run = sme_trap_za_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_vl.c b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
new file mode 100644
index 000000000000..13ff3b35cbaf
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Check that the SME vector length reported in signal contexts is the
+ * expected one.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+unsigned int vl;
+
+static bool get_sme_vl(struct tdescr *td)
+{
+	int ret = prctl(PR_SME_GET_VL);
+	if (ret == -1)
+		return false;
+
+	vl = ret;
+
+	return true;
+}
+
+static int sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct za_context *za;
+
+	/* Get a signal context which should have a ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, ZA_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No ZA context\n");
+		return 1;
+	}
+	za = (struct za_context *)head;
+
+	if (za->vl != vl) {
+		fprintf(stderr, "ZA sigframe VL %u, expected %u\n",
+			za->vl, vl);
+		return 1;
+	} else {
+		fprintf(stderr, "got expected VL %u\n", vl);
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "SME VL",
+	.descr = "Check that we get the right SME VL reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = get_sme_vl,
+	.run = sme_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
new file mode 100644
index 000000000000..44a08d43cd50
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that the streaming SVE register context in signal frames is
+ * set up as expected.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least one VL */
+	if (nvls < 1) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static void setup_ssve_regs(void)
+{
+	/* SMSTART SM */
+	asm volatile(".inst 0x7f4303d5");
+
+	/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
+	asm volatile(".inst 0x04bf5030" : : : "x16" );
+}
+
+static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
+			 unsigned int vl)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *ssve;
+
+	fprintf(stderr, "Testing VL %d\n", vl);
+
+	if (prctl(PR_SME_SET_VL, vl) == -1) {
+		fprintf(stderr, "Failed to set VL\n");
+		return 1;
+	}
+
+	/* 
+	 * Get a signal context which should have a SVE frame and registers
+	 * in it.
+	 */
+	setup_ssve_regs();
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	ssve = (struct sve_context *)head;
+	if (ssve->vl != vl) {
+		fprintf(stderr, "Got VL %d, expected %d\n", ssve->vl, vl);
+		return 1;
+	}
+
+	/* The actual size validation is done in get_current_context() */
+	fprintf(stderr, "Got expected size %u and VL %d\n",
+		head->size, ssve->vl);
+
+	return 0;
+}
+
+static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	int i;
+
+	for (i = 0; i < nvls; i++) {
+		/*
+		 * TODO: the signal test helpers can't currently cope
+		 * with signal frames bigger than struct sigcontext,
+		 * skip VLs that will trigger that.
+		 */
+		if (vls[i] > 64)
+			continue;
+
+		if (do_one_sme_vl(td, si, uc, vls[i]))
+			return 1;
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "Streaming SVE registers",
+	.descr = "Check that we get the right Streaming SVE registers reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = sme_regs,
+};
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:17 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:17 +0000
Subject: [PATCH v9 37/40] kselftest/arm64: Add streaming SVE to SVE ptrace
 tests
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-38-broonie@kernel.org>

In order to allow ptrace of streaming mode SVE registers we have added a
new regset for streaming mode which in isolation offers the same ABI as
regular SVE with a different vector type. Add this to the array of regsets
we handle, together with additional tests for the interoperation of the
two regsets.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index 90ba1d6a6781..fb74b11bab71 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -26,6 +26,10 @@
 #define NT_ARM_SVE 0x405
 #endif
 
+#ifndef NT_ARM_SSVE
+#define NT_ARM_SSVE 0x40b
+#endif
+
 struct vec_type {
 	const char *name;
 	unsigned long hwcap_type;
@@ -42,6 +46,13 @@ static const struct vec_type vec_types[] = {
 		.regset = NT_ARM_SVE,
 		.prctl_set = PR_SVE_SET_VL,
 	},
+	{
+		.name = "Streaming SVE",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.regset = NT_ARM_SSVE,
+		.prctl_set = PR_SME_SET_VL,
+	},
 };
 
 #define VL_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:18 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:18 +0000
Subject: [PATCH v9 38/40] kselftest/arm64: Add coverage for the ZA ptrace
 interface
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-39-broonie@kernel.org>

Add some basic coverage for the ZA ptrace interface, including walking
through all the vector lengths supported in the system. As with SVE we do
not currently validate the data all the way through to the running process.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |   1 +
 tools/testing/selftests/arm64/fp/Makefile    |   3 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c | 354 +++++++++++++++++++
 3 files changed, 357 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index ead3197e720b..d98d3d48b504 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,4 +8,5 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-ptrace
 za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 38d2d0d5a0eb..807a8faf8d57 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 CFLAGS += -I../../../../../usr/include/
-TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
+TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg za-ptrace
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
@@ -27,5 +27,6 @@ vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 za-test: za-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+za-ptrace: za-ptrace.o
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-ptrace.c b/tools/testing/selftests/arm64/fp/za-ptrace.c
new file mode 100644
index 000000000000..692c82624855
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-ptrace.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+#include "../../kselftest.h"
+
+/* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
+#ifndef NT_ARM_ZA
+#define NT_ARM_ZA 0x40c
+#endif
+
+#define EXPECTED_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
+
+static void fill_buf(char *buf, size_t size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		buf[i] = random();
+}
+
+static int do_child(void)
+{
+	if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
+		ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno));
+
+	if (raise(SIGSTOP))
+		ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno));
+
+	return EXIT_SUCCESS;
+}
+
+static struct user_za_header *get_za(pid_t pid, void **buf, size_t *size)
+{
+	struct user_za_header *za;
+	void *p;
+	size_t sz = sizeof(*za);
+	struct iovec iov;
+
+	while (1) {
+		if (*size < sz) {
+			p = realloc(*buf, sz);
+			if (!p) {
+				errno = ENOMEM;
+				goto error;
+			}
+
+			*buf = p;
+			*size = sz;
+		}
+
+		iov.iov_base = *buf;
+		iov.iov_len = sz;
+		if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZA, &iov))
+			goto error;
+
+		za = *buf;
+		if (za->size <= sz)
+			break;
+
+		sz = za->size;
+	}
+
+	return za;
+
+error:
+	return NULL;
+}
+
+static int set_za(pid_t pid, const struct user_za_header *za)
+{
+	struct iovec iov;
+
+	iov.iov_base = (void *)za;
+	iov.iov_len = za->size;
+	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZA, &iov);
+}
+
+/* Validate attempting to set the specfied VL via ptrace */
+static void ptrace_set_get_vl(pid_t child, unsigned int vl, bool *supported)
+{
+	struct user_za_header za;
+	struct user_za_header *new_za = NULL;
+	size_t new_za_size = 0;
+	int ret, prctl_vl;
+
+	*supported = false;
+
+	/* Check if the VL is supported in this process */
+	prctl_vl = prctl(PR_SME_SET_VL, vl);
+	if (prctl_vl == -1)
+		ksft_exit_fail_msg("prctl(PR_SME_SET_VL) failed: %s (%d)\n",
+				   strerror(errno), errno);
+
+	/* If the VL is not supported then a supported VL will be returned */
+	*supported = (prctl_vl == vl);
+
+	/* Set the VL by doing a set with no register payload */
+	memset(&za, 0, sizeof(za));
+	za.size = sizeof(za);
+	za.vl = vl;
+	ret = set_za(child, &za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u\n", vl);
+		return;
+	}
+
+	/*
+	 * Read back the new register state and verify that we have the
+	 * same VL that we got from prctl() on ourselves.
+	 */
+	if (!get_za(child, (void **)&new_za, &new_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u\n", vl);
+		return;
+	}
+
+	ksft_test_result(new_za->vl = prctl_vl, "Set VL %u\n", vl);
+
+	free(new_za);
+}
+
+/* Validate attempting to set no ZA data and read it back */
+static void ptrace_set_no_data(pid_t child, unsigned int vl)
+{
+	void *read_buf = NULL;
+	struct user_za_header write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	int ret;
+
+	/* Set up some data and write it out */
+	memset(&write_za, 0, sizeof(write_za));
+	write_za.size = ZA_PT_ZA_OFFSET;
+	write_za.vl = vl;
+
+	ret = set_za(child, &write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u no data\n", vl);
+		return;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u no data\n", vl);
+		return;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za.size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za.size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(read_za->size == write_za.size,
+			 "Disabled ZA for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+}
+
+/* Validate attempting to set data and read it back */
+static void ptrace_set_get_data(pid_t child, unsigned int vl)
+{
+	void *write_buf;
+	void *read_buf = NULL;
+	struct user_za_header *write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	unsigned int vq = sve_vq_from_vl(vl);
+	int ret;
+	size_t data_size;
+
+	data_size = ZA_PT_SIZE(vq);
+	write_buf = malloc(data_size);
+	if (!write_buf) {
+		ksft_test_result_fail("Error allocating %d byte buffer for VL %u\n",
+				      data_size, vl);
+		return;
+	}
+	write_za = write_buf;
+
+	/* Set up some data and write it out */
+	memset(write_za, 0, data_size);
+	write_za->size = data_size;
+	write_za->vl = vl;
+
+	fill_buf(write_buf + ZA_PT_ZA_OFFSET, ZA_PT_ZA_SIZE(vq));
+
+	ret = set_za(child, write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u data\n", vl);
+		goto out;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u data\n", vl);
+		goto out;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za->size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za->size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(memcmp(write_buf + ZA_PT_ZA_OFFSET,
+				read_buf + ZA_PT_ZA_OFFSET,
+				ZA_PT_ZA_SIZE(vq)) == 0,
+			 "Data match for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+out:
+	free(write_buf);
+}
+
+static int do_parent(pid_t child)
+{
+	int ret = EXIT_FAILURE;
+	pid_t pid;
+	int status;
+	siginfo_t si;
+	unsigned int vq, vl;
+	bool vl_supported;
+
+	/* Attach to the child */
+	while (1) {
+		int sig;
+
+		pid = wait(&status);
+		if (pid == -1) {
+			perror("wait");
+			goto error;
+		}
+
+		/*
+		 * This should never happen but it's hard to flag in
+		 * the framework.
+		 */
+		if (pid != child)
+			continue;
+
+		if (WIFEXITED(status) || WIFSIGNALED(status))
+			ksft_exit_fail_msg("Child died unexpectedly\n");
+
+		if (!WIFSTOPPED(status))
+			goto error;
+
+		sig = WSTOPSIG(status);
+
+		if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			if (errno == EINVAL) {
+				sig = 0; /* bust group-stop */
+				goto cont;
+			}
+
+			ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+
+		if (sig == SIGSTOP && si.si_code == SI_TKILL &&
+		    si.si_pid == pid)
+			break;
+
+	cont:
+		if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			ksft_test_result_fail("PTRACE_CONT: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+	}
+
+	/* Step through every possible VQ */
+	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
+		vl = sve_vl_from_vq(vq);
+
+		/* First, try to set this vector length */
+		ptrace_set_get_vl(child, vl, &vl_supported);
+
+		/* If the VL is supported validate data set/get */
+		if (vl_supported) {
+			ptrace_set_no_data(child, vl);
+			ptrace_set_get_data(child, vl);
+		} else {
+			ksft_test_result_skip("Disabled ZA for VL %u\n", vl);
+			ksft_test_result_skip("Get and set data for VL %u\n",
+					      vl);
+		}
+	}
+
+	ret = EXIT_SUCCESS;
+
+error:
+	kill(child, SIGKILL);
+
+disappeared:
+	return ret;
+}
+
+int main(void)
+{
+	int ret = EXIT_SUCCESS;
+	pid_t child;
+
+	srandom(getpid());
+
+	ksft_print_header();
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME)) {
+		ksft_set_plan(1);
+		ksft_exit_skip("SME not available\n");
+	}
+
+	ksft_set_plan(EXPECTED_TESTS);
+
+	child = fork();
+	if (!child)
+		return do_child();
+
+	if (do_parent(child))
+		ret = EXIT_FAILURE;
+
+	ksft_print_cnts();
+
+	return ret;
+}
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:19 +0000
Subject: [PATCH v9 39/40] kselftest/arm64: Add SME support to syscall ABI test
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-40-broonie@kernel.org>

For every possible combination of SVE and SME vector length verify that for
each possible value of SVCR after a syscall we leave streaming mode and ZA
is preserved. We don't need to take account of any streaming/non streaming
SVE vector length changes in the assembler code since the store instructions
will handle the vector length for us. We log if the system supports FA64 and
only try to set FFR in streaming mode if it does.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 204 ++++++++++++++++--
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 ++
 3 files changed, 265 insertions(+), 23 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
index 983467cfcee0..bc70e04224bf 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
+++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
@@ -9,15 +9,42 @@
 // invoked is configured in x8 of the input GPR data.
 //
 // x0:	SVE VL, 0 for FP only
+// x1:	SME VL
 //
 //	GPRs:	gpr_in, gpr_out
 //	FPRs:	fpr_in, fpr_out
 //	Zn:	z_in, z_out
 //	Pn:	p_in, p_out
 //	FFR:	ffr_in, ffr_out
+//	ZA:	za_in, za_out
+//	SVCR:	svcr_in, svcr_out
+
+#include "syscall-abi.h"
 
 .arch_extension sve
 
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
 .globl do_syscall
 do_syscall:
 	// Store callee saved registers x19-x29 (80 bytes) plus x0 and x1
@@ -30,6 +57,24 @@ do_syscall:
 	stp	x25, x26, [sp, #80]
 	stp	x27, x28, [sp, #96]
 
+	// Set SVCR if we're doing SME
+	cbz	x1, 1f
+	adrp	x2, svcr_in
+	ldr	x2, [x2, :lo12:svcr_in]
+	msr	S3_3_C4_C2_2, x2
+1:
+
+	// Load ZA if it's enabled - uses x12 as scratch due to SME LDR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_in
+2:	_ldr_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Load GPRs x8-x28, and save our SP/FP for later comparison
 	ldr	x2, =gpr_in
 	add	x2, x2, #64
@@ -68,7 +113,7 @@ do_syscall:
 	ldp	q30, q31, [x2, #16 * 30]
 1:
 
-	// Load the SVE registers if we're doing SVE
+	// Load the SVE registers if we're doing SVE/SME
 	cbz	x0, 1f
 
 	ldr	x2, =z_in
@@ -105,9 +150,13 @@ do_syscall:
 	ldr	z30, [x2, #30, MUL VL]
 	ldr	z31, [x2, #31, MUL VL]
 
+	// Only set a non-zero FFR, test patterns must be zero since the
+	// syscall should clear it - this lets us handle FA64.
 	ldr	x2, =ffr_in
+	cbz	x2, 2f
 	ldr	p0, [x2, #0]
 	wrffr	p0.b
+2:
 
 	ldr	x2, =p_in
 	ldr	p0, [x2, #0, MUL VL]
@@ -169,6 +218,24 @@ do_syscall:
 	stp	q28, q29, [x2, #16 * 28]
 	stp	q30, q31, [x2, #16 * 30]
 
+	// Save SVCR if we're doing SME
+	cbz	x1, 1f
+	mrs	x2, S3_3_C4_C2_2
+	adrp	x3, svcr_out
+	str	x2, [x3, :lo12:svcr_out]
+1:
+
+	// Save ZA if it's enabled - uses x12 as scratch due to SME STR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_out
+2:	_str_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Save the SVE state if we have some
 	cbz	x0, 1f
 
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index 1e13b7523918..b632bfe9e022 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,9 +18,13 @@
 
 #include "../../kselftest.h"
 
+#include "syscall-abi.h"
+
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
-extern void do_syscall(int sve_vl);
+static int default_sme_vl;
+
+extern void do_syscall(int sve_vl, int sme_vl);
 
 static void fill_random(void *buf, size_t size)
 {
@@ -48,14 +52,15 @@ static struct syscall_cfg {
 uint64_t gpr_in[NUM_GPR];
 uint64_t gpr_out[NUM_GPR];
 
-static void setup_gpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(gpr_in, sizeof(gpr_in));
 	gpr_in[8] = cfg->syscall_nr;
 	memset(gpr_out, 0, sizeof(gpr_out));
 }
 
-static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -79,13 +84,15 @@ static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
 uint64_t fpr_in[NUM_FPR * 2];
 uint64_t fpr_out[NUM_FPR * 2];
 
-static void setup_fpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(fpr_in, sizeof(fpr_in));
 	memset(fpr_out, 0, sizeof(fpr_out));
 }
 
-static int check_fpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -109,13 +116,15 @@ static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_z(struct syscall_cfg *cfg, int sve_vl)
+static void setup_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(z_in, sizeof(z_in));
 	fill_random(z_out, sizeof(z_out));
 }
 
-static int check_z(struct syscall_cfg *cfg, int sve_vl)
+static int check_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vl;
 	int errors = 0;
@@ -126,13 +135,17 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 
 	/*
 	 * After a syscall the low 128 bits of the Z registers should
-	 * be preserved and the rest be zeroed or preserved.
+	 * be preserved and the rest be zeroed or preserved, except if
+	 * we were in streaming mode in which case the low 128 bits may
+	 * also be cleared by the transition out of streaming mode.
 	 */
 	for (i = 0; i < SVE_NUM_ZREGS; i++) {
 		void *in = &z_in[reg_size * i];
 		void *out = &z_out[reg_size * i];
 
-		if (memcmp(in, out, SVE_VQ_BYTES) != 0) {
+		if ((memcmp(in, out, SVE_VQ_BYTES) != 0) &&
+		    !((svcr & SVCR_SM_MASK) &&
+		      memcmp(z_zero, out, SVE_VQ_BYTES) == 0)) {
 			ksft_print_msg("%s SVE VL %d Z%d low 128 bits changed\n",
 				       cfg->name, sve_vl, i);
 			errors++;
@@ -145,13 +158,15 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_p(struct syscall_cfg *cfg, int sve_vl)
+static void setup_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(p_in, sizeof(p_in));
 	fill_random(p_out, sizeof(p_out));
 }
 
-static int check_p(struct syscall_cfg *cfg, int sve_vl)
+static int check_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2; /* 1 bit per VL byte */
 
@@ -175,8 +190,19 @@ static int check_p(struct syscall_cfg *cfg, int sve_vl)
 uint8_t ffr_in[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t ffr_out[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
+	/*
+	 * If we are in streaming mode and do not have FA64 then FFR
+	 * is unavailable.
+	 */
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)) {
+		memset(&ffr_in, 0, sizeof(ffr_in));
+		return;
+	}
+
 	/*
 	 * It is only valid to set a contiguous set of bits starting
 	 * at 0.  For now since we're expecting this to be cleared by
@@ -186,7 +212,8 @@ static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
 	fill_random(ffr_out, sizeof(ffr_out));
 }
 
-static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
+static int check_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2;  /* 1 bit per VL byte */
 	int errors = 0;
@@ -195,6 +222,10 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	if (!sve_vl)
 		return 0;
 
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64))
+		return 0;
+
 	/* After a syscall the P registers should be preserved or zeroed */
 	for (i = 0; i < reg_size; i++)
 		if (ffr_out[i] && (ffr_in[i] != ffr_out[i]))
@@ -206,8 +237,65 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	return errors;
 }
 
-typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl);
-typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl);
+uint64_t svcr_in, svcr_out;
+
+static void setup_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	svcr_in = svcr;
+}
+
+static int check_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
+{
+	int errors = 0;
+
+	if (svcr_out & SVCR_SM_MASK) {
+		ksft_print_msg("%s Still in SM, SVCR %llx\n",
+			       cfg->name, svcr_out);
+		errors++;
+	}
+
+	if ((svcr_in & SVCR_ZA_MASK) != (svcr_out & SVCR_ZA_MASK)) {
+		ksft_print_msg("%s PSTATE.ZA changed, SVCR %llx != %llx\n",
+			       cfg->name, svcr_in, svcr_out);
+		errors++;
+	}
+
+	return errors;
+}
+
+uint8_t za_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+uint8_t za_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+
+static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
+{
+	fill_random(za_in, sizeof(za_in));
+	memset(za_out, 0, sizeof(za_out));
+}
+
+static int check_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	size_t reg_size = sme_vl * sme_vl;
+	int errors = 0;
+
+	if (!(svcr & SVCR_ZA_MASK))
+		return 0;
+
+	if (memcmp(za_in, za_out, reg_size) != 0) {
+		ksft_print_msg("SME VL %d ZA does not match\n", sme_vl);
+		errors++;
+	}
+
+	return errors;
+}
+
+typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			 uint64_t svcr);
+typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			uint64_t svcr);
 
 /*
  * Each set of registers has a setup function which is called before
@@ -225,20 +313,23 @@ static struct {
 	{ setup_z, check_z },
 	{ setup_p, check_p },
 	{ setup_ffr, check_ffr },
+	{ setup_svcr, check_svcr },
+	{ setup_za, check_za },
 };
 
-static bool do_test(struct syscall_cfg *cfg, int sve_vl)
+static bool do_test(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	int errors = 0;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		regset[i].setup(cfg, sve_vl);
+		regset[i].setup(cfg, sve_vl, sme_vl, svcr);
 
-	do_syscall(sve_vl);
+	do_syscall(sve_vl, sme_vl);
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		errors += regset[i].check(cfg, sve_vl);
+		errors += regset[i].check(cfg, sve_vl, sme_vl, svcr);
 
 	return errors == 0;
 }
@@ -246,9 +337,10 @@ static bool do_test(struct syscall_cfg *cfg, int sve_vl)
 static void test_one_syscall(struct syscall_cfg *cfg)
 {
 	int sve_vq, sve_vl;
+	int sme_vq, sme_vl;
 
 	/* FPSIMD only case */
-	ksft_test_result(do_test(cfg, 0),
+	ksft_test_result(do_test(cfg, 0, default_sme_vl, 0),
 			 "%s FPSIMD\n", cfg->name);
 
 	if (!(getauxval(AT_HWCAP) & HWCAP_SVE))
@@ -265,8 +357,36 @@ static void test_one_syscall(struct syscall_cfg *cfg)
 		if (sve_vq != sve_vq_from_vl(sve_vl))
 			sve_vq = sve_vq_from_vl(sve_vl);
 
-		ksft_test_result(do_test(cfg, sve_vl),
+		ksft_test_result(do_test(cfg, sve_vl, default_sme_vl, 0),
 				 "%s SVE VL %d\n", cfg->name, sve_vl);
+
+		if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+			continue;
+
+		for (sme_vq = SVE_VQ_MAX; sme_vq > 0; --sme_vq) {
+			sme_vl = prctl(PR_SME_SET_VL, sme_vq * 16);
+			if (sme_vl == -1)
+				ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+						   strerror(errno), errno);
+
+			sme_vl &= PR_SME_VL_LEN_MASK;
+
+			if (sme_vq != sve_vq_from_vl(sme_vl))
+				sme_vq = sve_vq_from_vl(sme_vl);
+
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK | SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM+ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK),
+					 "%s SVE VL %d/SME VL %d ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+		}
 	}
 }
 
@@ -299,14 +419,54 @@ int sve_count_vls(void)
 	return vl_count;
 }
 
+int sme_count_vls(void)
+{
+	unsigned int vq;
+	int vl_count = 0;
+	int vl;
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+		return 0;
+
+	/* Ensure we configure a SME VL, used to flag if SVCR is set */
+	default_sme_vl = 16;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SME_SET_VL, vq * 16);
+		if (vl == -1)
+			ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+					   strerror(errno), errno);
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		if (vq != sve_vq_from_vl(vl))
+			vq = sve_vq_from_vl(vl);
+
+		vl_count++;
+	}
+
+	return vl_count;
+}
+
 int main(void)
 {
 	int i;
+	int tests = 1;  /* FPSIMD */
 
 	srandom(getpid());
 
 	ksft_print_header();
-	ksft_set_plan(ARRAY_SIZE(syscalls) * (sve_count_vls() + 1));
+	tests += sve_count_vls();
+	tests += (sve_count_vls() * sme_count_vls()) * 3;
+	ksft_set_plan(ARRAY_SIZE(syscalls) * tests);
+
+	if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+		ksft_print_msg("SME with FA64\n");
+	else if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+		ksft_print_msg("SME without FA64\n");
 
 	for (i = 0; i < ARRAY_SIZE(syscalls); i++)
 		test_one_syscall(&syscalls[i]);
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.h b/tools/testing/selftests/arm64/abi/syscall-abi.h
new file mode 100644
index 000000000000..bda5a87ad381
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+
+#ifndef SYSCALL_ABI_H
+#define SYSCALL_ABI_H
+
+#define SVCR_ZA_MASK		2
+#define SVCR_SM_MASK		1
+
+#define SVCR_ZA_SHIFT		1
+#define SVCR_SM_SHIFT		0
+
+#endif
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:11:20 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:11:20 +0000
Subject: [PATCH v9 40/40] squqsh traps
In-Reply-To: <20220126151120.3811248-1-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
Message-ID: <20220126151120.3811248-41-broonie@kernel.org>

---
 arch/arm64/kvm/fpsimd.c          | 22 ++++++++++------------
 arch/arm64/kvm/hyp/nvhe/switch.c | 20 ++++++++++----------
 arch/arm64/kvm/hyp/vhe/switch.c  |  4 ++--
 3 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index cecaddb644ce..1c585553d74f 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -153,18 +153,16 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
 	 * CPACR_EL1_DEFAULT and we need to reenable SME.
 	 */
-	if (has_vhe()) {
-		if (system_supports_sme()) {
-			/* Also restore EL0 state seen on entry */
-			if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
-				sysreg_clear_set(CPACR_EL1, 0,
-						 CPACR_EL1_SMEN_EL0EN |
-						 CPACR_EL1_SMEN_EL1EN);
-			else
-				sysreg_clear_set(CPACR_EL1,
-						 CPACR_EL1_SMEN_EL0EN,
-						 CPACR_EL1_SMEN_EL1EN);
-		}
+	if (has_vhe() && system_supports_sme()) {
+		/* Also restore EL0 state seen on entry */
+		if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
+			sysreg_clear_set(CPACR_EL1, 0,
+					 CPACR_EL1_SMEN_EL0EN |
+					 CPACR_EL1_SMEN_EL1EN);
+		else
+			sysreg_clear_set(CPACR_EL1,
+					 CPACR_EL1_SMEN_EL0EN,
+					 CPACR_EL1_SMEN_EL1EN);
 	}
 
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 184bf6bd79b9..caace61ea459 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -47,21 +47,20 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 		__activate_traps_fpsimd32(vcpu);
 	}
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+	if (cpus_have_final_cap(ARM64_SME))
 		val |= CPTR_EL2_TSM;
 
 	write_sysreg(val, cptr_el2);
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
-	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+	if (cpus_have_final_cap(ARM64_SME)) {
 		val = read_sysreg_s(SYS_HFGRTR_EL2);
-		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
 			 HFGxTR_EL2_nSMPRI_EL1_MASK);
 		write_sysreg_s(val, SYS_HFGRTR_EL2);
 
 		val = read_sysreg_s(SYS_HFGWTR_EL2);
-		val &= ~(HFGxTR_EL2_nTPIDR_EL0_MASK |
+		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
 			 HFGxTR_EL2_nSMPRI_EL1_MASK);
 		write_sysreg_s(val, SYS_HFGWTR_EL2);
 	}
@@ -109,23 +108,24 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME) &&
-	    cpus_have_final_cap(ARM64_HAS_FGT)) {
+	if (cpus_have_final_cap(ARM64_SME)) {
 		u64 val;
 
 		val = read_sysreg_s(SYS_HFGRTR_EL2);
-		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			HFGxTR_EL2_nSMPRI_EL1_MASK;
 		write_sysreg_s(val, SYS_HFGRTR_EL2);
 
 		val = read_sysreg_s(SYS_HFGWTR_EL2);
-		val |= HFGxTR_EL2_nTPIDR_EL0_MASK | HFGxTR_EL2_nSMPRI_EL1_MASK;
+		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			HFGxTR_EL2_nSMPRI_EL1_MASK;
 		write_sysreg_s(val, SYS_HFGWTR_EL2);
 	}
 
 	cptr = CPTR_EL2_DEFAULT;
 	if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED))
 		cptr |= CPTR_EL2_TZ;
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+	if (cpus_have_final_cap(ARM64_SME))
 		cptr &= ~CPTR_EL2_TSM;
 
 	write_sysreg(cptr, cptr_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 21217485514d..a4d2fb5c9710 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -60,7 +60,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		__activate_traps_fpsimd32(vcpu);
 	}
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+	if (cpus_have_final_cap(ARM64_SME))
 		write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
 			     sctlr_el2);
 
@@ -85,7 +85,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 	 */
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && cpus_have_final_cap(ARM64_SME))
+	if (cpus_have_final_cap(ARM64_SME))
 		write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
 			     sctlr_el2);
 
-- 
2.30.2



From john.p.donnelly at oracle.com  Wed Jan 26 07:16:38 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Wed, 26 Jan 2022 09:16:38 -0600
Subject: [PATCH v20 1/5] arm64: Use insert_resource() to simplify code
In-Reply-To: <20220124084708.683-2-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
 <20220124084708.683-2-thunder.leizhen@huawei.com>
Message-ID: <171196ee-8c61-2ebd-b74d-87c0a15ae4ea@oracle.com>

On 1/24/22 2:47 AM, Zhen Lei wrote:
> insert_resource() traverses the subtree layer by layer from the root node
> until a proper location is found. Compared with request_resource(), the
> parent node does not need to be determined in advance.
> 
> In addition, move the insertion of node 'crashk_res' into function
> reserve_crashkernel() to make the associated code close together.
> 
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>


Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   arch/arm64/kernel/setup.c | 17 +++--------------
>   arch/arm64/mm/init.c      |  1 +
>   2 files changed, 4 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
> index f70573928f1bff0..a81efcc359e4e78 100644
> --- a/arch/arm64/kernel/setup.c
> +++ b/arch/arm64/kernel/setup.c
> @@ -225,6 +225,8 @@ static void __init request_standard_resources(void)
>   	kernel_code.end     = __pa_symbol(__init_begin - 1);
>   	kernel_data.start   = __pa_symbol(_sdata);
>   	kernel_data.end     = __pa_symbol(_end - 1);
> +	insert_resource(&iomem_resource, &kernel_code);
> +	insert_resource(&iomem_resource, &kernel_data);
>   
>   	num_standard_resources = memblock.memory.cnt;
>   	res_size = num_standard_resources * sizeof(*standard_resources);
> @@ -246,20 +248,7 @@ static void __init request_standard_resources(void)
>   			res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
>   		}
>   
> -		request_resource(&iomem_resource, res);
> -
> -		if (kernel_code.start >= res->start &&
> -		    kernel_code.end <= res->end)
> -			request_resource(res, &kernel_code);
> -		if (kernel_data.start >= res->start &&
> -		    kernel_data.end <= res->end)
> -			request_resource(res, &kernel_data);
> -#ifdef CONFIG_KEXEC_CORE
> -		/* Userspace will find "Crash kernel" region in /proc/iomem. */
> -		if (crashk_res.end && crashk_res.start >= res->start &&
> -		    crashk_res.end <= res->end)
> -			request_resource(res, &crashk_res);
> -#endif
> +		insert_resource(&iomem_resource, res);
>   	}
>   }
>   
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index db63cc885771a52..90f276d46b93bc6 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -109,6 +109,7 @@ static void __init reserve_crashkernel(void)
>   	kmemleak_ignore_phys(crash_base);
>   	crashk_res.start = crash_base;
>   	crashk_res.end = crash_base + crash_size - 1;
> +	insert_resource(&iomem_resource, &crashk_res);
>   }
>   #else
>   static void __init reserve_crashkernel(void)



From john.p.donnelly at oracle.com  Wed Jan 26 07:17:37 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Wed, 26 Jan 2022 09:17:37 -0600
Subject: [PATCH v20 2/5] arm64: kdump: introduce some macros for crash
 kernel reservation
In-Reply-To: <20220124084708.683-3-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
 <20220124084708.683-3-thunder.leizhen@huawei.com>
Message-ID: <35d28434-25d7-5aca-e810-2b4639dd5810@oracle.com>

On 1/24/22 2:47 AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> Introduce macro CRASH_ALIGN for alignment, macro CRASH_ADDR_LOW_MAX
> for upper bound of low crash memory, macro CRASH_ADDR_HIGH_MAX for
> upper bound of high crash memory, use macros instead.
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> Tested-by: John Donnelly <John.p.donnelly at oracle.com>
> Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>


Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   arch/arm64/mm/init.c | 11 ++++++++---
>   1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 90f276d46b93bc6..6c653a2c7cff052 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -65,6 +65,12 @@ EXPORT_SYMBOL(memstart_addr);
>   phys_addr_t arm64_dma_phys_limit __ro_after_init;
>   
>   #ifdef CONFIG_KEXEC_CORE
> +/* Current arm64 boot protocol requires 2MB alignment */
> +#define CRASH_ALIGN		SZ_2M
> +
> +#define CRASH_ADDR_LOW_MAX	arm64_dma_phys_limit
> +#define CRASH_ADDR_HIGH_MAX	MEMBLOCK_ALLOC_ACCESSIBLE
> +
>   /*
>    * reserve_crashkernel() - reserves memory for crash kernel
>    *
> @@ -75,7 +81,7 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>   static void __init reserve_crashkernel(void)
>   {
>   	unsigned long long crash_base, crash_size;
> -	unsigned long long crash_max = arm64_dma_phys_limit;
> +	unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
>   	int ret;
>   
>   	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> @@ -90,8 +96,7 @@ static void __init reserve_crashkernel(void)
>   	if (crash_base)
>   		crash_max = crash_base + crash_size;
>   
> -	/* Current arm64 boot protocol requires 2MB alignment */
> -	crash_base = memblock_phys_alloc_range(crash_size, SZ_2M,
> +	crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
>   					       crash_base, crash_max);
>   	if (!crash_base) {
>   		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",



From john.p.donnelly at oracle.com  Wed Jan 26 07:18:18 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Wed, 26 Jan 2022 09:18:18 -0600
Subject: [PATCH v20 3/5] arm64: kdump: reimplement crashkernel=X
In-Reply-To: <20220124084708.683-4-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
 <20220124084708.683-4-thunder.leizhen@huawei.com>
Message-ID: <48e9f8e8-be1e-fa62-1cbd-61be4a73658e@oracle.com>

On 1/24/22 2:47 AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> There are following issues in arm64 kdump:
> 1. We use crashkernel=X to reserve crashkernel below 4G, which
> will fail when there is no enough low memory.
> 2. If reserving crashkernel above 4G, in this case, crash dump
> kernel will boot failure because there is no low memory available
> for allocation.
> 
> To solve these issues, change the behavior of crashkernel=X and
> introduce crashkernel=X,[high,low]. crashkernel=X tries low allocation
> in DMA zone, and fall back to high allocation if it fails.
> We can also use "crashkernel=X,high" to select a region above DMA zone,
> which also tries to allocate at least 256M in DMA zone automatically.
> "crashkernel=Y,low" can be used to allocate specified size low memory.
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>


Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   arch/arm64/kernel/machine_kexec.c      |  9 +++-
>   arch/arm64/kernel/machine_kexec_file.c | 12 ++++-
>   arch/arm64/mm/init.c                   | 68 ++++++++++++++++++++++++--
>   3 files changed, 81 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
> index e16b248699d5c3c..19c2d487cb08feb 100644
> --- a/arch/arm64/kernel/machine_kexec.c
> +++ b/arch/arm64/kernel/machine_kexec.c
> @@ -329,8 +329,13 @@ bool crash_is_nosave(unsigned long pfn)
>   
>   	/* in reserved memory? */
>   	addr = __pfn_to_phys(pfn);
> -	if ((addr < crashk_res.start) || (crashk_res.end < addr))
> -		return false;
> +	if ((addr < crashk_res.start) || (crashk_res.end < addr)) {
> +		if (!crashk_low_res.end)
> +			return false;
> +
> +		if ((addr < crashk_low_res.start) || (crashk_low_res.end < addr))
> +			return false;
> +	}
>   
>   	if (!kexec_crash_image)
>   		return true;
> diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
> index 59c648d51848886..889951291cc0f9c 100644
> --- a/arch/arm64/kernel/machine_kexec_file.c
> +++ b/arch/arm64/kernel/machine_kexec_file.c
> @@ -65,10 +65,18 @@ static int prepare_elf_headers(void **addr, unsigned long *sz)
>   
>   	/* Exclude crashkernel region */
>   	ret = crash_exclude_mem_range(cmem, crashk_res.start, crashk_res.end);
> +	if (ret)
> +		goto out;
> +
> +	if (crashk_low_res.end) {
> +		ret = crash_exclude_mem_range(cmem, crashk_low_res.start, crashk_low_res.end);
> +		if (ret)
> +			goto out;
> +	}
>   
> -	if (!ret)
> -		ret =  crash_prepare_elf64_headers(cmem, true, addr, sz);
> +	ret = crash_prepare_elf64_headers(cmem, true, addr, sz);
>   
> +out:
>   	kfree(cmem);
>   	return ret;
>   }
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 6c653a2c7cff052..a5d43feac0d7d96 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -71,6 +71,30 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>   #define CRASH_ADDR_LOW_MAX	arm64_dma_phys_limit
>   #define CRASH_ADDR_HIGH_MAX	MEMBLOCK_ALLOC_ACCESSIBLE
>   
> +static int __init reserve_crashkernel_low(unsigned long long low_size)
> +{
> +	unsigned long long low_base;
> +
> +	/* passed with crashkernel=0,low ? */
> +	if (!low_size)
> +		return 0;
> +
> +	low_base = memblock_phys_alloc_range(low_size, CRASH_ALIGN, 0, CRASH_ADDR_LOW_MAX);
> +	if (!low_base) {
> +		pr_err("cannot allocate crashkernel low memory (size:0x%llx).\n", low_size);
> +		return -ENOMEM;
> +	}
> +
> +	pr_info("crashkernel low memory reserved: 0x%llx - 0x%llx (%lld MB)\n",
> +		low_base, low_base + low_size, low_size >> 20);
> +
> +	crashk_low_res.start = low_base;
> +	crashk_low_res.end   = low_base + low_size - 1;
> +	insert_resource(&iomem_resource, &crashk_low_res);
> +
> +	return 0;
> +}
> +
>   /*
>    * reserve_crashkernel() - reserves memory for crash kernel
>    *
> @@ -81,29 +105,62 @@ phys_addr_t arm64_dma_phys_limit __ro_after_init;
>   static void __init reserve_crashkernel(void)
>   {
>   	unsigned long long crash_base, crash_size;
> +	unsigned long long crash_low_size = SZ_256M;
>   	unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
>   	int ret;
> +	bool fixed_base;
> +	char *cmdline = boot_command_line;
>   
> -	ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
> +	/* crashkernel=X[@offset] */
> +	ret = parse_crashkernel(cmdline, memblock_phys_mem_size(),
>   				&crash_size, &crash_base);
> -	/* no crashkernel= or invalid value specified */
> -	if (ret || !crash_size)
> -		return;
> +	if (ret || !crash_size) {
> +		unsigned long long low_size;
>   
> +		/* crashkernel=X,high */
> +		ret = parse_crashkernel_high(cmdline, 0, &crash_size, &crash_base);
> +		if (ret || !crash_size)
> +			return;
> +
> +		/* crashkernel=X,low */
> +		ret = parse_crashkernel_low(cmdline, 0, &low_size, &crash_base);
> +		if (!ret)
> +			crash_low_size = low_size;
> +
> +		crash_max = CRASH_ADDR_HIGH_MAX;
> +	}
> +
> +	fixed_base = !!crash_base;
>   	crash_size = PAGE_ALIGN(crash_size);
>   
>   	/* User specifies base address explicitly. */
>   	if (crash_base)
>   		crash_max = crash_base + crash_size;
>   
> +retry:
>   	crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
>   					       crash_base, crash_max);
>   	if (!crash_base) {
> +		/*
> +		 * Attempt to fully allocate low memory failed, fall back
> +		 * to high memory, the minimum required low memory will be
> +		 * reserved later.
> +		 */
> +		if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) {
> +			crash_max = CRASH_ADDR_HIGH_MAX;
> +			goto retry;
> +		}
> +
>   		pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
>   			crash_size);
>   		return;
>   	}
>   
> +	if (crash_base >= SZ_4G && reserve_crashkernel_low(crash_low_size)) {
> +		memblock_phys_free(crash_base, crash_size);
> +		return;
> +	}
> +
>   	pr_info("crashkernel reserved: 0x%016llx - 0x%016llx (%lld MB)\n",
>   		crash_base, crash_base + crash_size, crash_size >> 20);
>   
> @@ -112,6 +169,9 @@ static void __init reserve_crashkernel(void)
>   	 * map. Inform kmemleak so that it won't try to access it.
>   	 */
>   	kmemleak_ignore_phys(crash_base);
> +	if (crashk_low_res.end)
> +		kmemleak_ignore_phys(crashk_low_res.start);
> +
>   	crashk_res.start = crash_base;
>   	crashk_res.end = crash_base + crash_size - 1;
>   	insert_resource(&iomem_resource, &crashk_res);



From john.p.donnelly at oracle.com  Wed Jan 26 07:19:04 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Wed, 26 Jan 2022 09:19:04 -0600
Subject: [PATCH v20 4/5] of: fdt: Add memory for devices by DT property
 "linux,usable-memory-range"
In-Reply-To: <20220124084708.683-5-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
 <20220124084708.683-5-thunder.leizhen@huawei.com>
Message-ID: <87fee388-fe72-4c87-577d-aae07a4a6da0@oracle.com>

On 1/24/22 2:47 AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> When reserving crashkernel in high memory, some low memory is reserved
> for crash dump kernel devices and never mapped by the first kernel.
> This memory range is advertised to crash dump kernel via DT property
> under /chosen,
>          linux,usable-memory-range = <BASE1 SIZE1 [BASE2 SIZE2]>
> 
> We reused the DT property linux,usable-memory-range and made the low
> memory region as the second range "BASE2 SIZE2", which keeps compatibility
> with existing user-space and older kdump kernels.
> 
> Crash dump kernel reads this property at boot time and call memblock_add()
> to add the low memory region after memblock_cap_memory_range() has been
> called.
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Co-developed-by: Zhen Lei <thunder.leizhen at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> Tested-by: Dave Kleikamp <dave.kleikamp at oracle.com>

Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   drivers/of/fdt.c | 33 +++++++++++++++++++++++----------
>   1 file changed, 23 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index ad85ff6474ff139..df4b9d2418a13d4 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -973,16 +973,24 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node)
>   
>   static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND;
>   
> +/*
> + * The main usage of linux,usable-memory-range is for crash dump kernel.
> + * Originally, the number of usable-memory regions is one. Now there may
> + * be two regions, low region and high region.
> + * To make compatibility with existing user-space and older kdump, the low
> + * region is always the last range of linux,usable-memory-range if exist.
> + */
> +#define MAX_USABLE_RANGES		2
> +
>   /**
>    * early_init_dt_check_for_usable_mem_range - Decode usable memory range
>    * location from flat tree
>    */
>   void __init early_init_dt_check_for_usable_mem_range(void)
>   {
> -	const __be32 *prop;
> -	int len;
> -	phys_addr_t cap_mem_addr;
> -	phys_addr_t cap_mem_size;
> +	struct memblock_region rgn[MAX_USABLE_RANGES] = {0};
> +	const __be32 *prop, *endp;
> +	int len, i;
>   	unsigned long node = chosen_node_offset;
>   
>   	if ((long)node < 0)
> @@ -991,16 +999,21 @@ void __init early_init_dt_check_for_usable_mem_range(void)
>   	pr_debug("Looking for usable-memory-range property... ");
>   
>   	prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len);
> -	if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells)))
> +	if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells)))
>   		return;
>   
> -	cap_mem_addr = dt_mem_next_cell(dt_root_addr_cells, &prop);
> -	cap_mem_size = dt_mem_next_cell(dt_root_size_cells, &prop);
> +	endp = prop + (len / sizeof(__be32));
> +	for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) {
> +		rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop);
> +		rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop);
>   
> -	pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr,
> -		 &cap_mem_size);
> +		pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n",
> +			 i, &rgn[i].base, &rgn[i].size);
> +	}
>   
> -	memblock_cap_memory_range(cap_mem_addr, cap_mem_size);
> +	memblock_cap_memory_range(rgn[0].base, rgn[0].size);
> +	for (i = 1; i < MAX_USABLE_RANGES && rgn[i].size; i++)
> +		memblock_add(rgn[i].base, rgn[i].size);
>   }
>   
>   #ifdef CONFIG_SERIAL_EARLYCON



From jszhang at kernel.org  Wed Jan 26 07:12:15 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Wed, 26 Jan 2022 23:12:15 +0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and
 unprepare "stmmaceth" clk
In-Reply-To: <38c41c04-abde-4d55-ed7c-515b6bba9c54@sholland.org>
References: <20220123132805.758-1-jszhang@kernel.org>
 <38c41c04-abde-4d55-ed7c-515b6bba9c54@sholland.org>
Message-ID: <YfFkz1d9onk+ITGg@xhacker>

On Sun, Jan 23, 2022 at 01:43:37PM -0600, Samuel Holland wrote:
> On 1/23/22 7:28 AM, Jisheng Zhang wrote:
> > Fix warnings on Allwinner D1 platform:
> > 
> > [    1.604695] ------------[ cut here ]------------
> > [    1.609328] bus-emac already disabled
> > [    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
> > [    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
> > [    1.627653] Hardware name: Allwinner D1 NeZha (DT)
> > [    1.632443] Workqueue: events_unbound deferred_probe_work_func
> > [    1.638286] epc : clk_core_disable+0xcc/0xec
> > [    1.642561]  ra : clk_core_disable+0xcc/0xec
> > [    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
> > [    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
> > [    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
> > [    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
> > [    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
> > [    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
> > [    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
> > [    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > [    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > [    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
> > [    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
> > [    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
> > [    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
> > [    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
> > [    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > [    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
> > [    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > [    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > [    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > [    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > [    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > [    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > [    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > [    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > [    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > [    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > [    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > [    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > [    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > [    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > [    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > [    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > [    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > [    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
> > [    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > [    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > [    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
> > [    1.873675] ------------[ cut here ]------------
> > [    1.878366] bus-emac already unprepared
> > [    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
> > [    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
> > [    1.898674] Hardware name: Allwinner D1 NeZha (DT)
> > [    1.903464] Workqueue: events_unbound deferred_probe_work_func
> > [    1.909305] epc : clk_core_unprepare+0xe4/0x168
> > [    1.913840]  ra : clk_core_unprepare+0xe4/0x168
> > [    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
> > [    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
> > [    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
> > [    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
> > [    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
> > [    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
> > [    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
> > [    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > [    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > [    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
> > [    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
> > [    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
> > [    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
> > [    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
> > [    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
> > [    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > [    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > [    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > [    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > [    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > [    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > [    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > [    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > [    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > [    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > [    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > [    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > [    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > [    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > [    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > [    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > [    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > [    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
> > [    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > [    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > [    2.135455] ---[ end trace 8d5c6046255f84a1 ]---
> > 
> > the dwmmac-sun8i driver will get the "stmmaceth" clk as tx_clk during
> > driver initialization. If stmmac_dvr_probe() fails due to various
> > reasons, sun8i_dwmac_exit() will disable and unprepare the "stmmaceth"
> > clk, then stmmac_remove_config_dt() will disable and unprepare the
> > clk again.
> 
> This should still be balanced, because both stmmac_probe_config_dt and
> sun8i_dwmac_init prepare/enable the clock, so the dwmac-sun8i glue layer calls
> stmmac_dvr_probe with the clock having an enable count of 2. It looks like the
> underlying issue is that commit 5ec55823438e ("net: stmmac: add clocks
> management for gmac driver") introduces unbalanced runtime PM.

I added some printk then retested, the problem is triggered as below:

stmmac_probe_config_dt() enable the clk
sun8i_dwmac_init() enble the clk again
stmmac_dvr_probe() succeed, but it calls pm_runtime_put(), so rpm will
disable the clk
sun8i_dwmac_reset() fails due to various reason
sun8i_dwmac_exit() disable the clk, this is fine
stmmac_remove_config_dt() disable the clk again, so ccf complains.

The key here is: whether we should let stmmac_dvr_probe() calls
pm_runtime_put() or let stmmac users to determine whether we could
let rpm go?
If we keep current behavior: stmmac users need to take care
the code after stmmac_dvr_probe, including error handling code path,
if we touch access registers, we need to call pm_runtime_get_sync()
firstly.

Since the commit 5ec55823438e has been in for a long time, I'll submit
a patch to follow this way.

Thanks
>  - stmmac_dvr_probe calls pm_runtime_get_noresume and pm_runtime_set_active,
> since it assumes the clocks are already enabled. This is fine.
>  - If stmmac_dvr_probe fails, it calls stmmac_bus_clks_config(priv, false),
> which drops the enable count down to 1. This is a bug, not just in this case,
> but also because it will unbalance the clocks if runtime PM is disabled.
>  - If stmmac_dvr_probe fails, it never calls pm_runtime_disable if the failure
> occurs after the call to pm_runtime_enable. This is also a bug.
> 
> It looks like at some point stmmac_dvr_remove was expected to leave all of the
> clocks disabled, but it must leave them enabled as of commit 8f269102baf7 ("net:
> stmmac: disable clocks in stmmac_remove_config_dt()"), since
> stmmac_remove_config_dt is called after stmmac_dvr_remove in stmmac_pltfr_remove.
>  - If stmmac_dvr_probe succeeds, it calls pm_runtime_put. This allows runtime PM
> to suspend the device, dropping the clock enable count to 1. This is fine.
>  - But then stmmac_dvr_remove calls pm_runtime_put as well. It needs to do the
> opposite. It must ensure the device is runtime resumed, so the clock enable
> count matches what it was before stmmac_dvr_probe was called (in this case: 2).
> 
> > Currently, there's no other usage of tx_clk except preparing and
> > enabling, we can fix the above warnings by simply removing the tx_clk
> > and all its usage, we rely on the common stmmac_probe_config_dt()
> > routine to prepare and enable the stmmaceth clk.
> 
> This is a good change to make, as indeed this code is now unnecessary, and
> removing it will allow runtime PM to actually disable the clock. But I am not
> sure how this resolves the warnings you are seeing, as the sun8i_dwmac_init/exit
> calls should have been balanced already.
> 
> Can you check if the PHY regulator is also getting unbalanced? Unbalanced calls
> to sun8i_dwmac_exit would also underflow the regulator use count, which should
> trigger its own warning.
> 
> Regards,
> Samuel
> 
> > Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
> > ---
> >  .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 20 +------------------
> >  1 file changed, 1 insertion(+), 19 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> > index 617d0e4c6495..d97469825e53 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> > @@ -57,7 +57,6 @@ struct emac_variant {
> >  };
> >  
> >  /* struct sunxi_priv_data - hold all sunxi private data
> > - * @tx_clk:	reference to MAC TX clock
> >   * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
> >   * @regulator:	reference to the optional regulator
> >   * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
> > @@ -68,7 +67,6 @@ struct emac_variant {
> >   * @mux_handle:	Internal pointer used by mdio-mux lib
> >   */
> >  struct sunxi_priv_data {
> > -	struct clk *tx_clk;
> >  	struct clk *ephy_clk;
> >  	struct regulator *regulator;
> >  	struct reset_control *rst_ephy;
> > @@ -579,22 +577,14 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
> >  		}
> >  	}
> >  
> > -	ret = clk_prepare_enable(gmac->tx_clk);
> > -	if (ret) {
> > -		dev_err(&pdev->dev, "Could not enable AHB clock\n");
> > -		goto err_disable_regulator;
> > -	}
> > -
> >  	if (gmac->use_internal_phy) {
> >  		ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
> >  		if (ret)
> > -			goto err_disable_clk;
> > +			goto err_disable_regulator;
> >  	}
> >  
> >  	return 0;
> >  
> > -err_disable_clk:
> > -	clk_disable_unprepare(gmac->tx_clk);
> >  err_disable_regulator:
> >  	if (gmac->regulator)
> >  		regulator_disable(gmac->regulator);
> > @@ -1043,8 +1033,6 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
> >  	if (gmac->variant->soc_has_internal_phy)
> >  		sun8i_dwmac_unpower_internal_phy(gmac);
> >  
> > -	clk_disable_unprepare(gmac->tx_clk);
> > -
> >  	if (gmac->regulator)
> >  		regulator_disable(gmac->regulator);
> >  }
> > @@ -1167,12 +1155,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
> >  		return -EINVAL;
> >  	}
> >  
> > -	gmac->tx_clk = devm_clk_get(dev, "stmmaceth");
> > -	if (IS_ERR(gmac->tx_clk)) {
> > -		dev_err(dev, "Could not get TX clock\n");
> > -		return PTR_ERR(gmac->tx_clk);
> > -	}
> > -
> >  	/* Optional regulator for PHY */
> >  	gmac->regulator = devm_regulator_get_optional(dev, "phy");
> >  	if (IS_ERR(gmac->regulator)) {
> > 
> 


From john.p.donnelly at oracle.com  Wed Jan 26 07:19:51 2022
From: john.p.donnelly at oracle.com (john.p.donnelly at oracle.com)
Date: Wed, 26 Jan 2022 09:19:51 -0600
Subject: [PATCH v20 5/5] kdump: update Documentation about crashkernel
In-Reply-To: <20220124084708.683-6-thunder.leizhen@huawei.com>
References: <20220124084708.683-1-thunder.leizhen@huawei.com>
 <20220124084708.683-6-thunder.leizhen@huawei.com>
Message-ID: <8e57b05f-8f50-e160-6d24-e1fdac2a9c59@oracle.com>

On 1/24/22 2:47 AM, Zhen Lei wrote:
> From: Chen Zhou <chenzhou10 at huawei.com>
> 
> For arm64, the behavior of crashkernel=X has been changed, which
> tries low allocation in DMA zone and fall back to high allocation
> if it fails.
> 
> We can also use "crashkernel=X,high" to select a high region above
> DMA zone, which also tries to allocate at least 256M low memory in
> DMA zone automatically and "crashkernel=Y,low" can be used to allocate
> specified size low memory.
> 
> So update the Documentation.
> 
> Signed-off-by: Chen Zhou <chenzhou10 at huawei.com>
> Signed-off-by: Zhen Lei <thunder.leizhen at huawei.com>

Acked-by: John Donnelly  <john.p.donnelly at oracle.com>

> ---
>   Documentation/admin-guide/kdump/kdump.rst       | 11 +++++++++--
>   Documentation/admin-guide/kernel-parameters.txt | 11 +++++++++--
>   2 files changed, 18 insertions(+), 4 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
> index cb30ca3df27c9b2..d4c287044be0c70 100644
> --- a/Documentation/admin-guide/kdump/kdump.rst
> +++ b/Documentation/admin-guide/kdump/kdump.rst
> @@ -361,8 +361,15 @@ Boot into System Kernel
>      kernel will automatically locate the crash kernel image within the
>      first 512MB of RAM if X is not given.
>   
> -   On arm64, use "crashkernel=Y[@X]".  Note that the start address of
> -   the kernel, X if explicitly specified, must be aligned to 2MiB (0x200000).
> +   On arm64, use "crashkernel=X" to try low allocation in DMA zone and
> +   fall back to high allocation if it fails.
> +   We can also use "crashkernel=X,high" to select a high region above
> +   DMA zone, which also tries to allocate at least 256M low memory in
> +   DMA zone automatically.
> +   "crashkernel=Y,low" can be used to allocate specified size low memory.
> +   Use "crashkernel=Y at X" if you really have to reserve memory from
> +   specified start address X. Note that the start address of the kernel,
> +   X if explicitly specified, must be aligned to 2MiB (0x200000).
>   
>   Load the Dump-capture Kernel
>   ============================
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index f5a27f067db9ed9..65780c2ca830be0 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -792,6 +792,9 @@
>   			[KNL, X86-64] Select a region under 4G first, and
>   			fall back to reserve region above 4G when '@offset'
>   			hasn't been specified.
> +			[KNL, ARM64] Try low allocation in DMA zone and fall back
> +			to high allocation if it fails when '@offset' hasn't been
> +			specified.
>   			See Documentation/admin-guide/kdump/kdump.rst for further details.
>   
>   	crashkernel=range1:size1[,range2:size2,...][@offset]
> @@ -808,6 +811,8 @@
>   			Otherwise memory region will be allocated below 4G, if
>   			available.
>   			It will be ignored if crashkernel=X is specified.
> +			[KNL, ARM64] range in high memory.
> +			Allow kernel to allocate physical memory region from top.
>   	crashkernel=size[KMG],low
>   			[KNL, X86-64] range under 4G. When crashkernel=X,high
>   			is passed, kernel could allocate physical memory region
> @@ -816,13 +821,15 @@
>   			requires at least 64M+32K low memory, also enough extra
>   			low memory is needed to make sure DMA buffers for 32-bit
>   			devices won't run out. Kernel would try to allocate at
> -			at least 256M below 4G automatically.
> +			least 256M below 4G automatically.
>   			This one let user to specify own low range under 4G
>   			for second kernel instead.
>   			0: to disable low allocation.
>   			It will be ignored when crashkernel=X,high is not used
>   			or memory reserved is below 4G.
> -
> +			[KNL, ARM64] range in low memory.
> +			This one let user to specify a low range in DMA zone for
> +			crash dump kernel.
>   	cryptomgr.notests
>   			[KNL] Disable crypto self-tests
>   



From broonie at kernel.org  Wed Jan 26 07:24:08 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:24:08 +0000
Subject: [PATCH v9 40/40] squqsh traps
In-Reply-To: <20220126151120.3811248-41-broonie@kernel.org>
References: <20220126151120.3811248-1-broonie@kernel.org>
 <20220126151120.3811248-41-broonie@kernel.org>
Message-ID: <YfFnmC5vekv06d3K@sirena.org.uk>

On Wed, Jan 26, 2022 at 03:11:20PM +0000, Mark Brown wrote:
> ---
>  arch/arm64/kvm/fpsimd.c          | 22 ++++++++++------------
>  arch/arm64/kvm/hyp/nvhe/switch.c | 20 ++++++++++----------
>  arch/arm64/kvm/hyp/vhe/switch.c  |  4 ++--
>  3 files changed, 22 insertions(+), 24 deletions(-)

Ugh, sorry - looks like I didn't finish my rebase.  Will resend.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/c71dc7e2/attachment.sig>

From broonie at kernel.org  Wed Jan 26 07:27:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:10 +0000
Subject: [PATCH v10 00/39] arm64/sme: Initial support for the Scalable Matrix
 Extension
Message-ID: <20220126152749.233712-1-broonie@kernel.org>

This series provides initial support for the ARMv9 Scalable Matrix
Extension (SME).  SME takes the approach used for vectors in SVE and
extends this to provide architectural support for matrix operations.  A
more detailed overview can be found in [1].

For the kernel SME can be thought of as a series of features which are
intended to be used together by applications but operate mostly
orthogonally:

 - The ZA matrix register.
 - Streaming mode, in which ZA can be accessed and a subset of SVE
   features are available.
 - A second vector length, used for streaming mode SVE and ZA and
   controlled using a similar interface to that for SVE.
 - TPIDR2, a new userspace controllable system register intended for use
   by the C library for storing context related to the ZA ABI.

A substantial part of the series is dedicated to refactoring the
existing SVE support so that we don't need to duplicate code for
handling vector lengths and the SVE registers, this involves creating an
array of vector types and making the users take the vector type as a
parameter.  I'm not 100% happy with this but wasn't able to come up with
anything better, duplicating code definitely felt like a bad idea so
this felt like the least bad thing.  If this approach makes sense to
people it might make sense to split this off into a separate series
and/or merge it while the rest is pending review to try to make things a
little more digestable, the series is very large so it'd probably make
things easier to digest if some of the preparatory refactoring could be
merged before the rest is ready.

One feature of the architecture of particular note is that switching
to and from streaming mode may change the size of and invalidate the
contents of the SVE registers, and when in streaming mode the FFR is not
accessible.  This complicates aspects of the ABI like signal handling
and ptrace.

This initial implementation is mainly intended to get the ABI in place,
there are several areas which will be worked on going forwards - some of
these will be blockers, others could be handled in followup serieses:

 - SME is currently not supported for KVM guests, this will be done as a
   followup series.  A host system can use SME and run KVM guests but
   SME is not available in the guests.
 - The KVM host support is done in a very simplistic way, were anyone to
   attempt to use it in production there would be performance impacts on
   hosts with SME support. As part of this we also add enumeration of
   fine grained traps.
 - There is not currently ptrace or signal support TPIDR2, this will be
   done as a followup series.
 - No support is currently provided for scheduler control of SME or SME
   applications, given the size of the SME register state the context
   switch overhead may be noticable so this may be needed especially for
   real time applications.  Similar concerns already exist for larger
   SVE vector lengths but are amplified for SME, particularly as the
   vector length increases.
 - There has been no work on optimising the performance of anything the
   kernel does.

It is not expected that any systems will be encountered that support SME
but not SVE, SME is an ARMv9 feature and SVE is mandatory for ARMv9.
The code attempts to handle any such systems that are encountered but
this hasn't been tested extensively.

v10:
 - Actually do the rebase of fixups from the previous version into
   relevant patches.
v9:
 - Remove defensive programming around IS_ENABLED() and FGT in KVM code.
 - Fix naming of TPIDR2 FGT register bit.
 - Add patches making handling of floating point register bits more
   consistent (also sent as separate series).
 - Drop now unused enumeration of fine grained traps.
v8:
 - Rebase onto v5.17-rc1.
 - Support interoperation with KVM, SME is disabled for KVM guests with
   minimal handling for cleaning up SME state when entering and leaving
   the guest.
 - Document and implement that signal handlers are invoked with ZA and
   streaming mode disabled.
 - Use the RDSVL instruction introduced in EAC2 of the architecture to
   obtain the streaming mode vector length during enumeration, ZA state
   loading/saving and in test programs.
 - Store a pointer to SVCR in fpsimd_last_state and use it in fpsimd_save()
   for interoperation with KVM.
 - Add a test case sme_trap_no_sm checking that we generate a SIGILL
   when using an instruction that requires streaming mode without
   enabling it.
 - Add basic ZA context form validation to testcases helper library.
 - Move signal tests over to validating streaming VL from ZA information.
 - Pulled in patch removing ARRAY_SIZE() so that kselftest builds
   cleanly and to avoid trivial conflicts.
v7:
 - Rebase onto v5.16-rc3.
 - Reduce indentation when supporting custom triggers for signal tests
   as suggested by Catalin.
 - Change to specifying a width for all CPU features rather than adding
   single bit specific infrastructure.
 - Don't require zeroing of non-shared SVE state during syscalls.
v6:
 - Rebase onto v5.16-rc1.
 - Return to disabling TIF_SVE on kernel entry even if we have SME
   state, this avoids the need for KVM to handle the case where TIF_SVE
   is set on guest entry.
 - Add syscall-abi.h to SME updates to syscall-abi, mistakenly omitted
   from commit.
v5:
 - Rebase onto currently merged SVE and kselftest patches.
 - Add support for the FA64 option, introduced in the recently published
   EAC1 update to the specification.
 - Pull in test program for the syscall ABI previously sent separately
   with some revisions and add coverage for the SME ABI.
 - Fix checking for options with 1 bit fields in ID_AA64SMFR0_EL1.
 - Minor fixes and clarifications to the ABI documentation.
v4:
 - Rebase onto merged patches.
 - Remove an uneeded NULL check in vec_proc_do_default_vl().
 - Include patch to factor out utility routines in kselftests written in
   assembler.
 - Specify -ffreestanding when building TPIDR2 test.
v3:
 - Skip FFR rather than predicate registers in sve_flush_live().
 - Don't assume a bool is all zeros in sve_flush_live() as per AAPCS.
 - Don't redundantly specify a zero index when clearing FFR.
v2:
 - Fix several issues with !SME and !SVE configurations.
 - Preserve TPIDR2 when creating a new thread/process unless
   CLONE_SETTLS is set.
 - Report traps due to using features in an invalid mode as SIGILL.
 - Spell out streaming mode behaviour in SVE ABI documentation more
   directly.
 - Document TPIDR2 in the ABI document.
 - Use SMSTART and SMSTOP rather than read/modify/write sequences.
 - Rework logic for exiting streaming mode on syscall.
 - Don't needlessly initialise SVCR on access trap.
 - Always restore SME VL for userspace if SME traps are disabled.
 - Only yield to encourage preemption every 128 iterations in za-test,
   otherwise do a getpid(), and validate SVCR after syscall.
 - Leave streaming mode disabled except when reading the vector length
   in za-test, and disable ZA after detecting a mismatch.
 - Add SME support to vlset.
 - Clarifications and typo fixes in comments.
 - Move sme_alloc() forward declaration back a patch.

[1] https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/scalable-matrix-extension-armv9-a-architecture

Mark Brown (39):
  arm64: Define CPACR_EL1_FPEN similarly to other floating point
    controls
  arm64: Always use individual bits in CPACR floating point enables
  arm64: cpufeature: Always specify and use a field width for
    capabilities
  kselftest/arm64: Remove local ARRAY_SIZE() definitions
  arm64/sme: Provide ABI documentation for SME
  arm64/sme: System register and exception syndrome definitions
  arm64/sme: Manually encode SME instructions
  arm64/sme: Early CPU setup for SME
  arm64/sme: Basic enumeration support
  arm64/sme: Identify supported SME vector lengths at boot
  arm64/sme: Implement sysctl to set the default vector length
  arm64/sme: Implement vector length configuration prctl()s
  arm64/sme: Implement support for TPIDR2
  arm64/sme: Implement SVCR context switching
  arm64/sme: Implement streaming SVE context switching
  arm64/sme: Implement ZA context switching
  arm64/sme: Implement traps and syscall handling for SME
  arm64/sme: Disable ZA and streaming mode when handling signals
  arm64/sme: Implement streaming SVE signal handling
  arm64/sme: Implement ZA signal handling
  arm64/sme: Implement ptrace support for streaming mode SVE registers
  arm64/sme: Add ptrace support for ZA
  arm64/sme: Disable streaming mode and ZA when flushing CPU state
  arm64/sme: Save and restore streaming mode over EFI runtime calls
  KVM: arm64: Hide SME system registers from guests
  KVM: arm64: Trap SME usage in guest
  KVM: arm64: Handle SME host state when running guests
  arm64/sme: Provide Kconfig for SME
  kselftest/arm64: sme: Add streaming SME support to vlset
  kselftest/arm64: Add tests for TPIDR2
  kselftest/arm64: Extend vector configuration API tests to cover SME
  kselftest/arm64: sme: Provide streaming mode SVE stress test
  kselftest/arm64: signal: Allow tests to be incompatible with features
  kselftest/arm64: signal: Handle ZA signal context in core code
  kselftest/arm64: Add stress test for SME ZA context switching
  kselftest/arm64: signal: Add SME signal handling tests
  kselftest/arm64: Add streaming SVE to SVE ptrace tests
  kselftest/arm64: Add coverage for the ZA ptrace interface
  kselftest/arm64: Add SME support to syscall ABI test

 Documentation/arm64/elf_hwcaps.rst            |  33 +
 Documentation/arm64/index.rst                 |   1 +
 Documentation/arm64/sme.rst                   | 432 +++++++++++++
 Documentation/arm64/sve.rst                   |  70 ++-
 arch/arm64/Kconfig                            |  11 +
 arch/arm64/include/asm/cpu.h                  |   4 +
 arch/arm64/include/asm/cpufeature.h           |  25 +
 arch/arm64/include/asm/el2_setup.h            |  64 +-
 arch/arm64/include/asm/esr.h                  |  13 +-
 arch/arm64/include/asm/exception.h            |   1 +
 arch/arm64/include/asm/fpsimd.h               | 110 +++-
 arch/arm64/include/asm/fpsimdmacros.h         |  86 +++
 arch/arm64/include/asm/hwcap.h                |   8 +
 arch/arm64/include/asm/kvm_arm.h              |   5 +-
 arch/arm64/include/asm/kvm_host.h             |   4 +
 arch/arm64/include/asm/processor.h            |  18 +-
 arch/arm64/include/asm/sysreg.h               |  67 +-
 arch/arm64/include/asm/thread_info.h          |   2 +
 arch/arm64/include/uapi/asm/hwcap.h           |   8 +
 arch/arm64/include/uapi/asm/ptrace.h          |  69 ++-
 arch/arm64/include/uapi/asm/sigcontext.h      |  55 +-
 arch/arm64/kernel/cpufeature.c                | 273 ++++++--
 arch/arm64/kernel/cpuinfo.c                   |  13 +
 arch/arm64/kernel/entry-common.c              |  11 +
 arch/arm64/kernel/entry-fpsimd.S              |  36 ++
 arch/arm64/kernel/fpsimd.c                    | 585 ++++++++++++++++--
 arch/arm64/kernel/process.c                   |  28 +-
 arch/arm64/kernel/ptrace.c                    | 356 +++++++++--
 arch/arm64/kernel/signal.c                    | 194 +++++-
 arch/arm64/kernel/syscall.c                   |  34 +-
 arch/arm64/kernel/traps.c                     |   1 +
 arch/arm64/kvm/fpsimd.c                       |  43 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |   4 +-
 arch/arm64/kvm/hyp/nvhe/switch.c              |  30 +
 arch/arm64/kvm/hyp/vhe/switch.c               |  15 +-
 arch/arm64/kvm/sys_regs.c                     |   9 +-
 arch/arm64/tools/cpucaps                      |   2 +
 include/uapi/linux/elf.h                      |   2 +
 include/uapi/linux/prctl.h                    |   9 +
 kernel/sys.c                                  |  12 +
 tools/testing/selftests/arm64/abi/.gitignore  |   1 +
 tools/testing/selftests/arm64/abi/Makefile    |   9 +-
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 ++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 205 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 +
 tools/testing/selftests/arm64/abi/tpidr2.c    | 298 +++++++++
 tools/testing/selftests/arm64/fp/.gitignore   |   4 +
 tools/testing/selftests/arm64/fp/Makefile     |  12 +-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   |  14 +
 tools/testing/selftests/arm64/fp/rdvl.S       |   8 +
 tools/testing/selftests/arm64/fp/rdvl.h       |   1 +
 tools/testing/selftests/arm64/fp/ssve-stress  |  59 ++
 tools/testing/selftests/arm64/fp/sve-ptrace.c |  13 +-
 tools/testing/selftests/arm64/fp/sve-test.S   |  30 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c |  10 +
 tools/testing/selftests/arm64/fp/vlset.c      |  10 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c  | 354 +++++++++++
 tools/testing/selftests/arm64/fp/za-stress    |  59 ++
 tools/testing/selftests/arm64/fp/za-test.S    | 426 +++++++++++++
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   5 +
 .../arm64/signal/test_signals_utils.c         |  40 +-
 .../arm64/signal/test_signals_utils.h         |   2 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 ++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 ++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++
 .../arm64/signal/testcases/testcases.c        |  36 ++
 .../arm64/signal/testcases/testcases.h        |   3 +-
 71 files changed, 4585 insertions(+), 251 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:11 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:11 +0000
Subject: [PATCH v10 01/39] arm64: Define CPACR_EL1_FPEN similarly to other
 floating point controls
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-2-broonie@kernel.org>

The base floating point, SVE and SME all have enable controls for EL0 and
EL1 in CPACR_EL1 which have a similar layout and function. Currently the
basic floating point enable FPEN is defined differently to the SVE control,
specified as a single define in kvm_arm.h rather than in sysreg.h. Move the
define to sysreg.h and provide separate EL0 and EL1 control bits so code
managing the different floating point enables can look consistent.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h | 1 -
 arch/arm64/include/asm/sysreg.h  | 4 ++++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..eec790842fe2 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -355,7 +355,6 @@
 	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
 
-#define CPACR_EL1_FPEN		(3 << 20)
 #define CPACR_EL1_TTA		(1 << 28)
 #define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..1da4c43d597d 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1097,6 +1097,10 @@
 #define ZCR_ELx_LEN_SIZE	9
 #define ZCR_ELx_LEN_MASK	0x1ff
 
+#define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
+#define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
+#define CPACR_EL1_FPEN		(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN)
+
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 #define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:12 +0000
Subject: [PATCH v10 02/39] arm64: Always use individual bits in CPACR floating
 point enables
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-3-broonie@kernel.org>

CPACR_EL1 has several bitfields for controlling traps for floating point
features to EL1, each of which has a separate bits for EL0 and EL1. Marc
Zyngier noted that we are not consistent in our use of defines to
manipulate these, sometimes using a define covering the whole field and
sometimes using defines for the individual bits. Make this consistent by
expanding the whole field defines where they are used (currently only in
the KVM code) and deleting them so that no further uses can be
introduced.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h        | 3 ++-
 arch/arm64/include/asm/sysreg.h         | 2 --
 arch/arm64/kvm/hyp/include/hyp/switch.h | 4 ++--
 arch/arm64/kvm/hyp/vhe/switch.c         | 6 +++---
 4 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index eec790842fe2..1767ded83888 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -356,6 +356,7 @@
 	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
 
 #define CPACR_EL1_TTA		(1 << 28)
-#define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
+#define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN |\
+				 CPACR_EL1_ZEN_EL1EN)
 
 #endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 1da4c43d597d..e66dd9ebc337 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1099,11 +1099,9 @@
 
 #define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
 #define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_FPEN		(CPACR_EL1_FPEN_EL1EN | CPACR_EL1_FPEN_EL0EN)
 
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
-#define CPACR_EL1_ZEN		(CPACR_EL1_ZEN_EL1EN | CPACR_EL1_ZEN_EL0EN)
 
 /* TCR EL1 Bit Definitions */
 #define SYS_TCR_EL1_TCMA1	(BIT(58))
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..4689b0fe7f4d 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -174,9 +174,9 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 
 	/* Valid trap.  Switch the context: */
 	if (has_vhe()) {
-		reg = CPACR_EL1_FPEN;
+		reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
 		if (sve_guest)
-			reg |= CPACR_EL1_ZEN;
+			reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
 
 		sysreg_clear_set(cpacr_el1, 0, reg);
 	} else {
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 11d053fdd604..619353b06e38 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,7 +38,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
-	val &= ~CPACR_EL1_ZEN;
+	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
 
 	/*
 	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -53,9 +53,9 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	if (update_fp_enabled(vcpu)) {
 		if (vcpu_has_sve(vcpu))
-			val |= CPACR_EL1_ZEN;
+			val |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
 	} else {
-		val &= ~CPACR_EL1_FPEN;
+		val &= ~(CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN);
 		__activate_traps_fpsimd32(vcpu);
 	}
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:13 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:13 +0000
Subject: [PATCH v10 03/39] arm64: cpufeature: Always specify and use a field
 width for capabilities
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-4-broonie@kernel.org>

Since all the fields in the main ID registers are 4 bits wide we have up
until now not bothered specifying the width in the code. Since we now
wish to use this mechanism to enumerate features from the floating point
feature registers which do not follow this pattern add a width to the
table.  This means updating all the existing table entries but makes it
less likely that we run into issues in future due to implicitly assuming
a 4 bit width.

Signed-off-by: Mark Brown <broonie at kernel.org>
Cc: Suzuki K Poulose <suzuki.poulose at arm.com>
---
 arch/arm64/include/asm/cpufeature.h |   1 +
 arch/arm64/kernel/cpufeature.c      | 167 +++++++++++++++++-----------
 2 files changed, 102 insertions(+), 66 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..2728abd9cae4 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -356,6 +356,7 @@ struct arm64_cpu_capabilities {
 		struct {	/* Feature register checking */
 			u32 sys_reg;
 			u8 field_pos;
+			u8 field_width;
 			u8 min_field_value;
 			u8 hwcap_type;
 			bool sign;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..d9f09e40aaf6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1307,7 +1307,9 @@ u64 __read_sysreg_by_encoding(u32 sys_id)
 static bool
 feature_matches(u64 reg, const struct arm64_cpu_capabilities *entry)
 {
-	int val = cpuid_feature_extract_field(reg, entry->field_pos, entry->sign);
+	int val = cpuid_feature_extract_field_width(reg, entry->field_pos,
+						    entry->field_width,
+						    entry->sign);
 
 	return val >= entry->min_field_value;
 }
@@ -1952,6 +1954,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR0_EL1,
 		.field_pos = ID_AA64MMFR0_ECV_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -1963,6 +1966,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_pan,
@@ -1976,6 +1980,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.field_pos = ID_AA64MMFR1_PAN_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 3,
 	},
@@ -1988,6 +1993,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_ATOMICS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 2,
 	},
@@ -2012,6 +2018,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL0_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 #ifdef CONFIG_KVM
@@ -2023,6 +2030,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_EL1_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_ELx_32BIT_64BIT,
 	},
 	{
@@ -2043,6 +2051,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		 */
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_CSV3_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = unmap_kernel_at_el0,
 		.cpu_enable = kpti_install_ng_mappings,
@@ -2062,6 +2071,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2072,6 +2082,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_DPB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 	},
 #endif
@@ -2083,6 +2094,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_SVE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_SVE,
 		.matches = has_cpuid_feature,
 		.cpu_enable = sve_kernel_enable,
@@ -2097,6 +2109,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_RAS_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_RAS_V1,
 		.cpu_enable = cpu_clear_disr,
 	},
@@ -2115,6 +2128,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64PFR0_AMU_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR0_AMU,
 		.cpu_enable = cpu_amu_enable,
 	},
@@ -2139,6 +2153,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_FWB_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 		.cpu_enable = cpu_has_fwb,
@@ -2150,6 +2165,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_TTL_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.matches = has_cpuid_feature,
 	},
@@ -2160,6 +2176,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_TLB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64ISAR0_TLB_RANGE,
 	},
@@ -2178,6 +2195,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR1_HADBS_SHIFT,
+		.field_width = 4,
 		.min_field_value = 2,
 		.matches = has_hw_dbm,
 		.cpu_enable = cpu_enable_hw_dbm,
@@ -2190,6 +2208,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_CRC32_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 	},
 	{
@@ -2199,6 +2218,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_SSBS_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
 	},
@@ -2211,6 +2231,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64MMFR2_CNP_SHIFT,
+		.field_width = 4,
 		.min_field_value = 1,
 		.cpu_enable = cpu_enable_cnp,
 	},
@@ -2222,6 +2243,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.field_pos = ID_AA64ISAR1_SB_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2233,6 +2255,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_APA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_APA_ARCHITECTED,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2243,6 +2266,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_API_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_API_IMP_DEF,
 		.matches = has_address_auth_cpucap,
 	},
@@ -2258,6 +2282,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPA_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPA_ARCHITECTED,
 		.matches = has_cpuid_feature,
 	},
@@ -2268,6 +2293,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_GPI_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64ISAR1_GPI_IMP_DEF,
 		.matches = has_cpuid_feature,
 	},
@@ -2288,6 +2314,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = can_use_gic_priorities,
 		.sys_reg = SYS_ID_AA64PFR0_EL1,
 		.field_pos = ID_AA64PFR0_GIC_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2299,6 +2326,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.sys_reg = SYS_ID_AA64MMFR2_EL1,
 		.sign = FTR_UNSIGNED,
+		.field_width = 4,
 		.field_pos = ID_AA64MMFR2_E0PD_SHIFT,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
@@ -2313,6 +2341,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64ISAR0_EL1,
 		.field_pos = ID_AA64ISAR0_RNDR_SHIFT,
+		.field_width = 4,
 		.sign = FTR_UNSIGNED,
 		.min_field_value = 1,
 	},
@@ -2330,6 +2359,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.cpu_enable = bti_enable,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_BT_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_BT_BTI,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2342,6 +2372,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE,
 		.sign = FTR_UNSIGNED,
 		.cpu_enable = cpu_enable_mte,
@@ -2353,6 +2384,7 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.sys_reg = SYS_ID_AA64PFR1_EL1,
 		.field_pos = ID_AA64PFR1_MTE_SHIFT,
+		.field_width = 4,
 		.min_field_value = ID_AA64PFR1_MTE_ASYMM,
 		.sign = FTR_UNSIGNED,
 	},
@@ -2364,16 +2396,18 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
 		.field_pos = ID_AA64ISAR1_LRCPC_SHIFT,
+		.field_width = 4,
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
 	{},
 };
 
-#define HWCAP_CPUID_MATCH(reg, field, s, min_value)				\
+#define HWCAP_CPUID_MATCH(reg, field, width, s, min_value)			\
 		.matches = has_cpuid_feature,					\
 		.sys_reg = reg,							\
 		.field_pos = field,						\
+		.field_width = width,						\
 		.sign = s,							\
 		.min_field_value = min_value,
 
@@ -2383,10 +2417,10 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.hwcap_type = cap_type,						\
 		.hwcap = cap,							\
 
-#define HWCAP_CAP(reg, field, s, min_value, cap_type, cap)			\
+#define HWCAP_CAP(reg, field, width, s, min_value, cap_type, cap)		\
 	{									\
 		__HWCAP_CAP(#cap, cap_type, cap)				\
-		HWCAP_CPUID_MATCH(reg, field, s, min_value)			\
+		HWCAP_CPUID_MATCH(reg, field, width, s, min_value) 		\
 	}
 
 #define HWCAP_MULTI_CAP(list, cap_type, cap)					\
@@ -2406,11 +2440,12 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_APA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
+				  4, FTR_UNSIGNED,
+				  ID_AA64ISAR1_APA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
 	},
 	{},
 };
@@ -2418,77 +2453,77 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPA_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
 	},
 	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
-				  FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
+				  4, FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
 	},
 	{},
 };
 #endif
 
 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
-	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
-	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
-	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_PMULL),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AES),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA1),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA2_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_SHA512),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_CRC32),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_ATOMICS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ATOMICS),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RDM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDRDM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SHA3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SHA3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM3_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM3),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_SM4_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SM4),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_DP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDDP),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_FHM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDFHM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FLAGM),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_TS_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_FLAGM2),
+	HWCAP_CAP(SYS_ID_AA64ISAR0_EL1, ID_AA64ISAR0_RNDR_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RNG),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_FP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_FP_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FPHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 0, CAP_HWCAP, KERNEL_HWCAP_ASIMD),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_ASIMD_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ASIMDHP),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_DIT_SHIFT, 4, FTR_SIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DIT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DCPOP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DPB_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_DCPODP),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_JSCVT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FCMA),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_LRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, 4, FTR_UNSIGNED, 2, CAP_HWCAP, KERNEL_HWCAP_ILRCPC),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FRINTTS_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_FRINT),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_SB_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_SB),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_BF16_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_BF16),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_DGH_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_DGH),
+	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_I8MM_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_I8MM),
+	HWCAP_CAP(SYS_ID_AA64MMFR2_EL1, ID_AA64MMFR2_AT_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
-	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
-	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+	HWCAP_CAP(SYS_ID_AA64PFR0_EL1, ID_AA64PFR0_SVE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR0_SVE, CAP_HWCAP, KERNEL_HWCAP_SVE),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SVEVER_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SVEVER_SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_AES_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_AES_PMULL, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BITPERM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BITPERM, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_BF16_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_BF16, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SHA3_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SHA3, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_SM4_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_SM4, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_I8MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_I8MM, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F32MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F32MM, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+	HWCAP_CAP(SYS_ID_AA64ZFR0_EL1, ID_AA64ZFR0_F64MM_SHIFT, 4, FTR_UNSIGNED, ID_AA64ZFR0_F64MM, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
 #endif
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_BT_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_BT_BTI, CAP_HWCAP, KERNEL_HWCAP_BTI),
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_addr_matches, CAP_HWCAP, KERNEL_HWCAP_PACA),
 	HWCAP_MULTI_CAP(ptr_auth_hwcap_gen_matches, CAP_HWCAP, KERNEL_HWCAP_PACG),
 #endif
 #ifdef CONFIG_ARM64_MTE
-	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
 #endif /* CONFIG_ARM64_MTE */
-	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
-	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
-	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
+	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
+	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
 	{},
 };
 
@@ -2517,15 +2552,15 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope)
 static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = {
 #ifdef CONFIG_COMPAT
 	HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON),
-	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
+	HWCAP_CAP(SYS_MVFR1_EL1, MVFR1_SIMDFMAC_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4),
 	/* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
-	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
-	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFP),
+	HWCAP_CAP(SYS_MVFR0_EL1, MVFR0_FPDP_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv3),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 2, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_PMULL),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_AES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_AES),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA1_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA1),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_SHA2_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_SHA2),
+	HWCAP_CAP(SYS_ID_ISAR5_EL1, ID_ISAR5_CRC32_SHIFT, 4, FTR_UNSIGNED, 1, CAP_COMPAT_HWCAP2, COMPAT_HWCAP2_CRC32),
 #endif
 	{},
 };
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:14 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:14 +0000
Subject: [PATCH v10 04/39] kselftest/arm64: Remove local ARRAY_SIZE()
 definitions
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-5-broonie@kernel.org>

An ARRAY_SIZE() has been added to kselftest.h so remove the local versions
in some of the arm64 selftests.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/syscall-abi.c | 1 -
 tools/testing/selftests/arm64/fp/sve-ptrace.c   | 2 --
 2 files changed, 3 deletions(-)

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index d8eeeafb50dc..1e13b7523918 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,7 +18,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
 extern void do_syscall(int sve_vl);
diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index af798b9d232c..90ba1d6a6781 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -21,8 +21,6 @@
 
 #include "../../kselftest.h"
 
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
 /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
 #ifndef NT_ARM_SVE
 #define NT_ARM_SVE 0x405
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:15 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:15 +0000
Subject: [PATCH v10 05/39] arm64/sme: Provide ABI documentation for SME
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-6-broonie@kernel.org>

Provide ABI documentation for SME similar to that for SVE. Due to the very
large overlap around streaming SVE mode in both implementation and
interfaces documentation for streaming mode SVE is added to the SVE
document rather than the SME one.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/index.rst |   1 +
 Documentation/arm64/sme.rst   | 432 ++++++++++++++++++++++++++++++++++
 Documentation/arm64/sve.rst   |  70 +++++-
 3 files changed, 493 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/arm64/sme.rst

diff --git a/Documentation/arm64/index.rst b/Documentation/arm64/index.rst
index 4f840bac083e..ae21f8118830 100644
--- a/Documentation/arm64/index.rst
+++ b/Documentation/arm64/index.rst
@@ -21,6 +21,7 @@ ARM64 Architecture
     perf
     pointer-authentication
     silicon-errata
+    sme
     sve
     tagged-address-abi
     tagged-pointers
diff --git a/Documentation/arm64/sme.rst b/Documentation/arm64/sme.rst
new file mode 100644
index 000000000000..15df3157c592
--- /dev/null
+++ b/Documentation/arm64/sme.rst
@@ -0,0 +1,432 @@
+===================================================
+Scalable Matrix Extension support for AArch64 Linux
+===================================================
+
+This document outlines briefly the interface provided to userspace by Linux in
+order to support use of the ARM Scalable Matrix Extension (SME).
+
+This is an outline of the most important features and issues only and not
+intended to be exhaustive.  It should be read in conjunction with the SVE
+documentation in sve.rst which provides details on the Streaming SVE mode
+included in SME.
+
+This document does not aim to describe the SME architecture or programmer's
+model.  To aid understanding, a minimal description of relevant programmer's
+model features for SME is included in Appendix A.
+
+
+1.  General
+-----------
+
+* PSTATE.SM, PSTATE.ZA, the streaming mode vector length, the ZA
+  register state and TPIDR2_EL0 are tracked per thread.
+
+* The presence of SME is reported to userspace via HWCAP2_SME in the aux vector
+  AT_HWCAP2 entry.  Presence of this flag implies the presence of the SME
+  instructions and registers, and the Linux-specific system interfaces
+  described in this document.  SME is reported in /proc/cpuinfo as "sme".
+
+* Support for the execution of SME instructions in userspace can also be
+  detected by reading the CPU ID register ID_AA64PFR1_EL1 using an MRS
+  instruction, and checking that the value of the SME field is nonzero. [3]
+
+  It does not guarantee the presence of the system interfaces described in the
+  following sections: software that needs to verify that those interfaces are
+  present must check for HWCAP2_SME instead.
+
+* There are a number of optional SME features, presence of these is reported
+  through AT_HWCAP2 through:
+
+	HWCAP2_SME_I16I64
+	HWCAP2_SME_F64F64
+	HWCAP2_SME_I8I32
+	HWCAP2_SME_F16F32
+	HWCAP2_SME_B16F32
+	HWCAP2_SME_F32F32
+	HWCAP2_SME_FA64
+
+  This list may be extended over time as the SME architecture evolves.
+
+  These extensions are also reported via the CPU ID register ID_AA64SMFR0_EL1,
+  which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
+  cpu-feature-registers.txt for details.
+
+* Debuggers should restrict themselves to interacting with the target via the
+  NT_ARM_SVE, NT_ARM_SSVE and NT_ARM_ZA regsets.  The recommended way
+  of detecting support for these regsets is to connect to a target process
+  first and then attempt a
+
+	ptrace(PTRACE_GETREGSET, pid, NT_ARM_<regset>, &iov).
+
+* Whenever ZA register values are exchanged in memory between userspace and
+  the kernel, the register value is encoded in memory as a series of horizontal
+  vectors from 0 to VL/8-1 stored in the same endianness invariant format as is
+  used for SVE vectors.
+
+* On thread creation TPIDR2_EL0 is preserved unless CLONE_SETTLS is specified,
+  in which case it is set to 0.
+
+2.  Vector lengths
+------------------
+
+SME defines a second vector length similar to the SVE vector length which is
+controls the size of the streaming mode SVE vectors and the ZA matrix array.
+The ZA matrix is square with each side having as many bytes as a SVE vector.
+
+
+3.  Sharing of streaming and non-streaming mode SVE state
+---------------------------------------------------------
+
+It is implementation defined which if any parts of the SVE state are shared
+between streaming and non-streaming modes.  When switching between modes
+via software interfaces such as ptrace if no register content is provided as
+part of switching no state will be assumed to be shared and everything will
+be zeroed.
+
+
+4.  System call behaviour
+-------------------------
+
+* On syscall PSTATE.ZA is preserved, if PSTATE.ZA==1 then the contents of the
+  ZA matrix are preserved.
+
+* On syscall PSTATE.SM will be cleared and the SVE registers will be handled
+  as normal.
+
+* Neither the SVE registers nor ZA are used to pass arguments to or receive
+  results from any syscall.
+
+* On creation fork() or clone() the newly created process will have PSTATE.SM
+  and PSTATE.ZA cleared.
+
+* All other SME state of a thread, including the currently configured vector
+  length, the state of the PR_SME_VL_INHERIT flag, and the deferred vector
+  length (if any), is preserved across all syscalls, subject to the specific
+  exceptions for execve() described in section 6.
+
+
+5.  Signal handling
+-------------------
+
+* Signal handlers are invoked with streaming mode and ZA disabled.
+
+* A new signal frame record za_context encodes the ZA register contents on
+  signal delivery. [1]
+
+* The signal frame record for ZA always contains basic metadata, in particular
+  the thread's vector length (in za_context.vl).
+
+* The ZA matrix may or may not be included in the record, depending on
+  the value of PSTATE.ZA.  The registers are present if and only if:
+  za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+  in which case PSTATE.ZA == 1.
+
+* If matrix data is present, the remainder of the record has a vl-dependent
+  size and layout.  Macros ZA_SIG_* are defined [1] to facilitate access to
+  them.
+
+* The matrix is stored as a series of horizontal vectors in the same format as
+  is used for SVE vectors.
+
+* If the ZA context is too big to fit in sigcontext.__reserved[], then extra
+  space is allocated on the stack, an extra_context record is written in
+  __reserved[] referencing this space.  za_context is then written in the
+  extra space.  Refer to [1] for further details about this mechanism.
+
+
+5.  Signal return
+-----------------
+
+When returning from a signal handler:
+
+* If there is no za_context record in the signal frame, or if the record is
+  present but contains no register data as desribed in the previous section,
+  then ZA is disabled.
+
+* If za_context is present in the signal frame and contains matrix data then
+  PSTATE.ZA is set to 1 and ZA is populated with the specified data.
+
+* The vector length cannot be changed via signal return.  If za_context.vl in
+  the signal frame does not match the current vector length, the signal return
+  attempt is treated as illegal, resulting in a forced SIGSEGV.
+
+
+6.  prctl extensions
+--------------------
+
+Some new prctl() calls are added to allow programs to manage the SME vector
+length:
+
+prctl(PR_SME_SET_VL, unsigned long arg)
+
+    Sets the vector length of the calling thread and related flags, where
+    arg == vl | flags.  Other threads of the calling process are unaffected.
+
+    vl is the desired vector length, where sve_vl_valid(vl) must be true.
+
+    flags:
+
+	PR_SME_VL_INHERIT
+
+	    Inherit the current vector length across execve().  Otherwise, the
+	    vector length is reset to the system default at execve().  (See
+	    Section 9.)
+
+	PR_SME_SET_VL_ONEXEC
+
+	    Defer the requested vector length change until the next execve()
+	    performed by this thread.
+
+	    The effect is equivalent to implicit exceution of the following
+	    call immediately after the next execve() (if any) by the thread:
+
+		prctl(PR_SME_SET_VL, arg & ~PR_SME_SET_VL_ONEXEC)
+
+	    This allows launching of a new program with a different vector
+	    length, while avoiding runtime side effects in the caller.
+
+	    Without PR_SME_SET_VL_ONEXEC, the requested change takes effect
+	    immediately.
+
+
+    Return value: a nonnegative on success, or a negative value on error:
+	EINVAL: SME not supported, invalid vector length requested, or
+	    invalid flags.
+
+
+    On success:
+
+    * Either the calling thread's vector length or the deferred vector length
+      to be applied at the next execve() by the thread (dependent on whether
+      PR_SME_SET_VL_ONEXEC is present in arg), is set to the largest value
+      supported by the system that is less than or equal to vl.  If vl ==
+      SVE_VL_MAX, the value set will be the largest value supported by the
+      system.
+
+    * Any previously outstanding deferred vector length change in the calling
+      thread is cancelled.
+
+    * The returned value describes the resulting configuration, encoded as for
+      PR_SME_GET_VL.  The vector length reported in this value is the new
+      current vector length for this thread if PR_SME_SET_VL_ONEXEC was not
+      present in arg; otherwise, the reported vector length is the deferred
+      vector length that will be applied at the next execve() by the calling
+      thread.
+
+    * Changing the vector length causes all of ZA, P0..P15, FFR and all bits of
+      Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
+      unspecified, including both streaming and non-streaming SVE state.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+    * Changing the vector length causes PSTATE.ZA and PSTATE.SM to be cleared.
+      Calling PR_SME_SET_VL with vl equal to the thread's current vector
+      length, or calling PR_SME_SET_VL with the PR_SVE_SET_VL_ONEXEC flag,
+      does not constitute a change to the vector length for this purpose.
+
+
+prctl(PR_SME_GET_VL)
+
+    Gets the vector length of the calling thread.
+
+    The following flag may be OR-ed into the result:
+
+	PR_SME_VL_INHERIT
+
+	    Vector length will be inherited across execve().
+
+    There is no way to determine whether there is an outstanding deferred
+    vector length change (which would only normally be the case between a
+    fork() or vfork() and the corresponding execve() in typical use).
+
+    To extract the vector length from the result, bitwise and it with
+    PR_SME_VL_LEN_MASK.
+
+    Return value: a nonnegative value on success, or a negative value on error:
+	EINVAL: SME not supported.
+
+
+7.  ptrace extensions
+---------------------
+
+* A new regset NT_ARM_SSVE is defined for access to streaming mode SVE
+  state via PTRACE_GETREGSET and  PTRACE_SETREGSET, this is documented in
+  sve.rst.
+
+* A new regset NT_ARM_ZA is defined for ZA state for access to ZA state via
+  PTRACE_GETREGSET and PTRACE_SETREGSET.
+
+  Refer to [2] for definitions.
+
+The regset data starts with struct user_za_header, containing:
+
+    size
+
+	Size of the complete regset, in bytes.
+	This depends on vl and possibly on other things in the future.
+
+	If a call to PTRACE_GETREGSET requests less data than the value of
+	size, the caller can allocate a larger buffer and retry in order to
+	read the complete regset.
+
+    max_size
+
+	Maximum size in bytes that the regset can grow to for the target
+	thread.  The regset won't grow bigger than this even if the target
+	thread changes its vector length etc.
+
+    vl
+
+	Target thread's current streaming vector length, in bytes.
+
+    max_vl
+
+	Maximum possible streaming vector length for the target thread.
+
+    flags
+
+	Zero or more of the following flags, which have the same
+	meaning and behaviour as the corresponding PR_SET_VL_* flags:
+
+	    SME_PT_VL_INHERIT
+
+	    SME_PT_VL_ONEXEC (SETREGSET only).
+
+* The effects of changing the vector length and/or flags are equivalent to
+  those documented for PR_SME_SET_VL.
+
+  The caller must make a further GETREGSET call if it needs to know what VL is
+  actually set by SETREGSET, unless is it known in advance that the requested
+  VL is supported.
+
+* The size and layout of the payload depends on the header fields.  The
+  SME_PT_ZA_*() macros are provided to facilitate access to the data.
+
+* In either case, for SETREGSET it is permissible to omit the payload, in which
+  case the vector length and flags are changed and PSTATE.ZA is set to 0
+  (along with any consequences of those changes).  If a payload is provided
+  then PSTATE.ZA will be set to 1.
+
+* For SETREGSET, if the requested VL is not supported, the effect will be the
+  same as if the payload were omitted, except that an EIO error is reported.
+  No attempt is made to translate the payload data to the correct layout
+  for the vector length actually set.  It is up to the caller to translate the
+  payload layout for the actual VL and retry.
+
+* The effect of writing a partial, incomplete payload is unspecified.
+
+
+8.  ELF coredump extensions
+---------------------------
+
+* NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
+
+* A NT_ARM_ZA note will be added to each coredump for each thread of the
+  dumped process.  The contents will be equivalent to the data that would have
+  been read if a PTRACE_GETREGSET of NT_ARM_ZA were executed for each thread
+  when the coredump was generated.
+
+
+9.  System runtime configuration
+--------------------------------
+
+* To mitigate the ABI impact of expansion of the signal frame, a policy
+  mechanism is provided for administrators, distro maintainers and developers
+  to set the default vector length for userspace processes:
+
+/proc/sys/abi/sme_default_vector_length
+
+    Writing the text representation of an integer to this file sets the system
+    default vector length to the specified value, unless the value is greater
+    than the maximum vector length supported by the system in which case the
+    default vector length is set to that maximum.
+
+    The result can be determined by reopening the file and reading its
+    contents.
+
+    At boot, the default vector length is initially set to 32 or the maximum
+    supported vector length, whichever is smaller and supported.  This
+    determines the initial vector length of the init process (PID 1).
+
+    Reading this file returns the current system default vector length.
+
+* At every execve() call, the new vector length of the new process is set to
+  the system default vector length, unless
+
+    * PR_SME_VL_INHERIT (or equivalently SME_PT_VL_INHERIT) is set for the
+      calling thread, or
+
+    * a deferred vector length change is pending, established via the
+      PR_SME_SET_VL_ONEXEC flag (or SME_PT_VL_ONEXEC).
+
+* Modifying the system default vector length does not affect the vector length
+  of any existing process or thread that does not make an execve() call.
+
+
+Appendix A.  SME programmer's model (informative)
+=================================================
+
+This section provides a minimal description of the additions made by SVE to the
+ARMv8-A programmer's model that are relevant to this document.
+
+Note: This section is for information only and not intended to be complete or
+to replace any architectural specification.
+
+A.1.  Registers
+---------------
+
+In A64 state, SME adds the following:
+
+* A new mode, streaming mode, in which a subset of the normal FPSIMD and SVE
+  features are available.  When supported EL0 software may enter and leave
+  streaming mode at any time.
+
+  For best system performance it is strongly encouraged for software to enable
+  streaming mode only when it is actively being used.
+
+* A new vector length controlling the size of ZA and the Z registers when in
+  streaming mode, separately to the vector length used for SVE when not in
+  streaming mode.  There is no requirement that either the currently selected
+  vector length or the set of vector lengths supported for the two modes in
+  a given system have any relationship.  The streaming mode vector length
+  is referred to as SVL.
+
+* A new ZA matrix register.  This is a square matrix of SVLxSVL bits.  Most
+  operations on ZA require that streaming mode be enabled but ZA can be
+  enabled without streaming mode in order to load, save and retain data.
+
+  For best system performance it is strongly encouraged for software to enable
+  ZA only when it is actively being used.
+
+* Two new 1 bit fields in PSTATE which may be controlled via the SMSTART and
+  SMSTOP instructions or by access to the SVCR system register:
+
+  * PSTATE.ZA, if this is 1 then the ZA matrix is accessible and has valid
+    data while if it is 0 then ZA can not be accessed.  When PSTATE.ZA is
+    changed from 0 to 1 all bits in ZA are cleared.
+
+  * PSTATE.SM, if this is 1 then the PE is in streaming mode.  When the value
+    of PSTATE.SM is changed then it is implementation defined if the subset
+    of the floating point register bits valid in both modes may be retained.
+    Any other bits will be cleared.
+
+
+References
+==========
+
+[1] arch/arm64/include/uapi/asm/sigcontext.h
+    AArch64 Linux signal ABI definitions
+
+[2] arch/arm64/include/uapi/asm/ptrace.h
+    AArch64 Linux ptrace ABI definitions
+
+[3] Documentation/arm64/cpu-feature-registers.rst
+
+[4] ARM IHI0055C
+    http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
+    http://infocenter.arm.com/help/topic/com.arm.doc.subset.swdev.abi/index.html
+    Procedure Call Standard for the ARM 64-bit Architecture (AArch64)
diff --git a/Documentation/arm64/sve.rst b/Documentation/arm64/sve.rst
index 9d9a4de5bc34..93c2c2990584 100644
--- a/Documentation/arm64/sve.rst
+++ b/Documentation/arm64/sve.rst
@@ -7,7 +7,9 @@ Author: Dave Martin <Dave.Martin at arm.com>
 Date:   4 August 2017
 
 This document outlines briefly the interface provided to userspace by Linux in
-order to support use of the ARM Scalable Vector Extension (SVE).
+order to support use of the ARM Scalable Vector Extension (SVE), including
+interactions with Streaming SVE mode added by the Scalable Matrix Extension
+(SME).
 
 This is an outline of the most important features and issues only and not
 intended to be exhaustive.
@@ -23,6 +25,10 @@ model features for SVE is included in Appendix A.
 * SVE registers Z0..Z31, P0..P15 and FFR and the current vector length VL, are
   tracked per-thread.
 
+* In streaming mode FFR is not accessible unless HWCAP2_SME_FA64 is present
+  in the system, when it is not supported and these interfaces are used to
+  access streaming mode FFR is read and written as zero.
+
 * The presence of SVE is reported to userspace via HWCAP_SVE in the aux vector
   AT_HWCAP entry.  Presence of this flag implies the presence of the SVE
   instructions and registers, and the Linux-specific system interfaces
@@ -53,10 +59,19 @@ model features for SVE is included in Appendix A.
   which userspace can read using an MRS instruction.  See elf_hwcaps.txt and
   cpu-feature-registers.txt for details.
 
+* On hardware that supports the SME extensions, HWCAP2_SME will also be
+  reported in the AT_HWCAP2 aux vector entry.  Among other things SME adds
+  streaming mode which provides a subset of the SVE feature set using a
+  separate SME vector length and the same Z/V registers.  See sme.rst
+  for more details.
+
 * Debuggers should restrict themselves to interacting with the target via the
   NT_ARM_SVE regset.  The recommended way of detecting support for this regset
   is to connect to a target process first and then attempt a
-  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).
+  ptrace(PTRACE_GETREGSET, pid, NT_ARM_SVE, &iov).  Note that when SME is
+  present and streaming SVE mode is in use the FPSIMD subset of registers
+  will be read via NT_ARM_SVE and NT_ARM_SVE writes will exit streaming mode
+  in the target.
 
 * Whenever SVE scalable register values (Zn, Pn, FFR) are exchanged in memory
   between userspace and the kernel, the register value is encoded in memory in
@@ -126,6 +141,11 @@ the SVE instruction set architecture.
   are only present in fpsimd_context.  For convenience, the content of V0..V31
   is duplicated between sve_context and fpsimd_context.
 
+* The record contains a flag field which includes a flag SVE_SIG_FLAG_SM which
+  if set indicates that the thread is in streaming mode and the vector length
+  and register data (if present) describe the streaming SVE data and vector
+  length.
+
 * The signal frame record for SVE always contains basic metadata, in particular
   the thread's vector length (in sve_context.vl).
 
@@ -170,6 +190,11 @@ When returning from a signal handler:
   the signal frame does not match the current vector length, the signal return
   attempt is treated as illegal, resulting in a forced SIGSEGV.
 
+* It is permitted to enter or leave streaming mode by setting or clearing
+  the SVE_SIG_FLAG_SM flag but applications should take care to ensure that
+  when doing so sve_context.vl and any register data are appropriate for the
+  vector length in the new mode.
+
 
 6.  prctl extensions
 --------------------
@@ -265,8 +290,14 @@ prctl(PR_SVE_GET_VL)
 7.  ptrace extensions
 ---------------------
 
-* A new regset NT_ARM_SVE is defined for use with PTRACE_GETREGSET and
-  PTRACE_SETREGSET.
+* New regsets NT_ARM_SVE and NT_ARM_SSVE are defined for use with
+  PTRACE_GETREGSET and PTRACE_SETREGSET. NT_ARM_SSVE describes the
+  streaming mode SVE registers and NT_ARM_SVE describes the
+  non-streaming mode SVE registers.
+
+  In this description a register set is referred to as being "live" when
+  the target is in the appropriate streaming or non-streaming mode and is
+  using data beyond the subset shared with the FPSIMD Vn registers.
 
   Refer to [2] for definitions.
 
@@ -297,7 +328,7 @@ The regset data starts with struct user_sve_header, containing:
 
     flags
 
-	either
+	at most one of
 
 	    SVE_PT_REGS_FPSIMD
 
@@ -331,6 +362,10 @@ The regset data starts with struct user_sve_header, containing:
 
 	    SVE_PT_VL_ONEXEC (SETREGSET only).
 
+	If neither FPSIMD nor SVE flags are provided then no register
+	payload is available, this is only possible when SME is implemented.
+
+
 * The effects of changing the vector length and/or flags are equivalent to
   those documented for PR_SVE_SET_VL.
 
@@ -346,6 +381,13 @@ The regset data starts with struct user_sve_header, containing:
   case only the vector length and flags are changed (along with any
   consequences of those changes).
 
+* In systems supporting SME when in streaming mode a GETREGSET for
+  NT_REG_SVE will return only the user_sve_header with no register data,
+  similarly a GETREGSET for NT_REG_SSVE will not return any register data
+  when not in streaming mode.
+
+* A GETREGSET for NT_ARM_SSVE will never return SVE_PT_REGS_FPSIMD.
+
 * For SETREGSET, if an SVE_PT_REGS_SVE payload is present and the
   requested VL is not supported, the effect will be the same as if the
   payload were omitted, except that an EIO error is reported.  No
@@ -355,17 +397,25 @@ The regset data starts with struct user_sve_header, containing:
   unspecified.  It is up to the caller to translate the payload layout
   for the actual VL and retry.
 
+* Where SME is implemented it is not possible to GETREGSET the register
+  state for normal SVE when in streaming mode, nor the streaming mode
+  register state when in normal mode, regardless of the implementation defined
+  behaviour of the hardware for sharing data between the two modes.
+
+* Any SETREGSET of NT_ARM_SVE will exit streaming mode if the target was in
+  streaming mode and any SETREGSET of NT_ARM_SSVE will enter streaming mode
+  if the target was not in streaming mode.
+
 * The effect of writing a partial, incomplete payload is unspecified.
 
 
 8.  ELF coredump extensions
 ---------------------------
 
-* A NT_ARM_SVE note will be added to each coredump for each thread of the
-  dumped process.  The contents will be equivalent to the data that would have
-  been read if a PTRACE_GETREGSET of NT_ARM_SVE were executed for each thread
-  when the coredump was generated.
-
+* NT_ARM_SVE and NT_ARM_SSVE notes will be added to each coredump for
+  each thread of the dumped process.  The contents will be equivalent to the
+  data that would have been read if a PTRACE_GETREGSET of the corresponding
+  type were executed for each thread when the coredump was generated.
 
 9.  System runtime configuration
 --------------------------------
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:16 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:16 +0000
Subject: [PATCH v10 06/39] arm64/sme: System register and exception syndrome
 definitions
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-7-broonie@kernel.org>

The arm64 Scalable Matrix Extension (SME) adds some new system registers,
fields in existing system registers and exception syndromes. This patch
adds definitions for these for use in future patches implementing support
for this extension.

Since SME will be the first user of FEAT_HCX in the kernel also include
the definitions for enumerating it and the HCRX system register it adds.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h     | 12 +++++-
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/include/asm/sysreg.h  | 63 ++++++++++++++++++++++++++++++++
 arch/arm64/kernel/traps.c        |  1 +
 4 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d52a0b269ee8..43872e0cfd1e 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -37,7 +37,8 @@
 #define ESR_ELx_EC_ERET		(0x1a)	/* EL2 only */
 /* Unallocated EC: 0x1B */
 #define ESR_ELx_EC_FPAC		(0x1C)	/* EL1 and above */
-/* Unallocated EC: 0x1D - 0x1E */
+#define ESR_ELx_EC_SME		(0x1D)
+/* Unallocated EC: 0x1E */
 #define ESR_ELx_EC_IMP_DEF	(0x1f)	/* EL3 only */
 #define ESR_ELx_EC_IABT_LOW	(0x20)
 #define ESR_ELx_EC_IABT_CUR	(0x21)
@@ -327,6 +328,15 @@
 #define ESR_ELx_CP15_32_ISS_SYS_CNTFRQ	(ESR_ELx_CP15_32_ISS_SYS_VAL(0, 0, 14, 0) |\
 					 ESR_ELx_CP15_32_ISS_DIR_READ)
 
+/*
+ * ISS values for SME traps
+ */
+
+#define ESR_ELx_SME_ISS_SME_DISABLED	0
+#define ESR_ELx_SME_ISS_ILL		1
+#define ESR_ELx_SME_ISS_SM_DISABLED	2
+#define ESR_ELx_SME_ISS_ZA_DISABLED	3
+
 #ifndef __ASSEMBLY__
 #include <asm/types.h>
 
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 1767ded83888..13ae232ec4a1 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -279,6 +279,7 @@
 #define CPTR_EL2_TCPAC	(1U << 31)
 #define CPTR_EL2_TAM	(1 << 30)
 #define CPTR_EL2_TTA	(1 << 20)
+#define CPTR_EL2_TSM	(1 << 12)
 #define CPTR_EL2_TFP	(1 << CPTR_EL2_TFP_SHIFT)
 #define CPTR_EL2_TZ	(1 << 8)
 #define CPTR_NVHE_EL2_RES1	0x000032ff /* known RES1 bits in CPTR_EL2 (nVHE) */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index e66dd9ebc337..6056c9aaab28 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -173,6 +173,7 @@
 #define SYS_ID_AA64PFR0_EL1		sys_reg(3, 0, 0, 4, 0)
 #define SYS_ID_AA64PFR1_EL1		sys_reg(3, 0, 0, 4, 1)
 #define SYS_ID_AA64ZFR0_EL1		sys_reg(3, 0, 0, 4, 4)
+#define SYS_ID_AA64SMFR0_EL1		sys_reg(3, 0, 0, 4, 5)
 
 #define SYS_ID_AA64DFR0_EL1		sys_reg(3, 0, 0, 5, 0)
 #define SYS_ID_AA64DFR1_EL1		sys_reg(3, 0, 0, 5, 1)
@@ -196,6 +197,8 @@
 
 #define SYS_ZCR_EL1			sys_reg(3, 0, 1, 2, 0)
 #define SYS_TRFCR_EL1			sys_reg(3, 0, 1, 2, 1)
+#define SYS_SMPRI_EL1			sys_reg(3, 0, 1, 2, 4)
+#define SYS_SMCR_EL1			sys_reg(3, 0, 1, 2, 6)
 
 #define SYS_TTBR0_EL1			sys_reg(3, 0, 2, 0, 0)
 #define SYS_TTBR1_EL1			sys_reg(3, 0, 2, 0, 1)
@@ -388,6 +391,8 @@
 #define TRBIDR_ALIGN_MASK		GENMASK(3, 0)
 #define TRBIDR_ALIGN_SHIFT		0
 
+#define SMPRI_EL1_PRIORITY_MASK		0xf
+
 #define SYS_PMINTENSET_EL1		sys_reg(3, 0, 9, 14, 1)
 #define SYS_PMINTENCLR_EL1		sys_reg(3, 0, 9, 14, 2)
 
@@ -443,8 +448,13 @@
 #define SYS_CCSIDR_EL1			sys_reg(3, 1, 0, 0, 0)
 #define SYS_CLIDR_EL1			sys_reg(3, 1, 0, 0, 1)
 #define SYS_GMID_EL1			sys_reg(3, 1, 0, 0, 4)
+#define SYS_SMIDR_EL1			sys_reg(3, 1, 0, 0, 6)
 #define SYS_AIDR_EL1			sys_reg(3, 1, 0, 0, 7)
 
+#define SYS_SMIDR_EL1_IMPLEMENTER_SHIFT	24
+#define SYS_SMIDR_EL1_SMPS_SHIFT	15
+#define SYS_SMIDR_EL1_AFFINITY_SHIFT	0
+
 #define SYS_CSSELR_EL1			sys_reg(3, 2, 0, 0, 0)
 
 #define SYS_CTR_EL0			sys_reg(3, 3, 0, 0, 1)
@@ -453,6 +463,10 @@
 #define SYS_RNDR_EL0			sys_reg(3, 3, 2, 4, 0)
 #define SYS_RNDRRS_EL0			sys_reg(3, 3, 2, 4, 1)
 
+#define SYS_SVCR_EL0			sys_reg(3, 3, 4, 2, 2)
+#define SYS_SVCR_EL0_ZA_MASK		2
+#define SYS_SVCR_EL0_SM_MASK		1
+
 #define SYS_PMCR_EL0			sys_reg(3, 3, 9, 12, 0)
 #define SYS_PMCNTENSET_EL0		sys_reg(3, 3, 9, 12, 1)
 #define SYS_PMCNTENCLR_EL0		sys_reg(3, 3, 9, 12, 2)
@@ -469,6 +483,7 @@
 
 #define SYS_TPIDR_EL0			sys_reg(3, 3, 13, 0, 2)
 #define SYS_TPIDRRO_EL0			sys_reg(3, 3, 13, 0, 3)
+#define SYS_TPIDR2_EL0			sys_reg(3, 3, 13, 0, 5)
 
 #define SYS_SCXTNUM_EL0			sys_reg(3, 3, 13, 0, 7)
 
@@ -538,6 +553,9 @@
 #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
 #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
+#define SYS_HCRX_EL2			sys_reg(3, 4, 1, 2, 2)
+#define SYS_SMPRIMAP_EL2		sys_reg(3, 4, 1, 2, 5)
+#define SYS_SMCR_EL2			sys_reg(3, 4, 1, 2, 6)
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
 #define SYS_HDFGRTR_EL2			sys_reg(3, 4, 3, 1, 4)
 #define SYS_HDFGWTR_EL2			sys_reg(3, 4, 3, 1, 5)
@@ -597,6 +615,7 @@
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
 #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+#define SYS_SMCR_EL12			sys_reg(3, 5, 1, 2, 6)
 #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
 #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
 #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
@@ -620,6 +639,7 @@
 #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
 
 /* Common SCTLR_ELx flags. */
+#define SCTLR_ELx_ENTP2	(BIT(60))
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
 
@@ -815,6 +835,7 @@
 #define ID_AA64PFR0_ELx_32BIT_64BIT	0x2
 
 /* id_aa64pfr1 */
+#define ID_AA64PFR1_SME_SHIFT		24
 #define ID_AA64PFR1_MPAMFRAC_SHIFT	16
 #define ID_AA64PFR1_RASFRAC_SHIFT	12
 #define ID_AA64PFR1_MTE_SHIFT		8
@@ -825,6 +846,7 @@
 #define ID_AA64PFR1_SSBS_PSTATE_ONLY	1
 #define ID_AA64PFR1_SSBS_PSTATE_INSNS	2
 #define ID_AA64PFR1_BT_BTI		0x1
+#define ID_AA64PFR1_SME			1
 
 #define ID_AA64PFR1_MTE_NI		0x0
 #define ID_AA64PFR1_MTE_EL0		0x1
@@ -853,6 +875,23 @@
 #define ID_AA64ZFR0_AES_PMULL		0x2
 #define ID_AA64ZFR0_SVEVER_SVE2		0x1
 
+/* id_aa64smfr0 */
+#define ID_AA64SMFR0_FA64_SHIFT		63
+#define ID_AA64SMFR0_I16I64_SHIFT	52
+#define ID_AA64SMFR0_F64F64_SHIFT	48
+#define ID_AA64SMFR0_I8I32_SHIFT	36
+#define ID_AA64SMFR0_F16F32_SHIFT	35
+#define ID_AA64SMFR0_B16F32_SHIFT	34
+#define ID_AA64SMFR0_F32F32_SHIFT	32
+
+#define ID_AA64SMFR0_FA64		0x1
+#define ID_AA64SMFR0_I16I64		0x4
+#define ID_AA64SMFR0_F64F64		0x1
+#define ID_AA64SMFR0_I8I32		0x4
+#define ID_AA64SMFR0_F16F32		0x1
+#define ID_AA64SMFR0_B16F32		0x1
+#define ID_AA64SMFR0_F32F32		0x1
+
 /* id_aa64mmfr0 */
 #define ID_AA64MMFR0_ECV_SHIFT		60
 #define ID_AA64MMFR0_FGT_SHIFT		56
@@ -904,6 +943,7 @@
 #endif
 
 /* id_aa64mmfr1 */
+#define ID_AA64MMFR1_HCX_SHIFT		40
 #define ID_AA64MMFR1_AFP_SHIFT		44
 #define ID_AA64MMFR1_ETS_SHIFT		36
 #define ID_AA64MMFR1_TWED_SHIFT		32
@@ -1097,9 +1137,24 @@
 #define ZCR_ELx_LEN_SIZE	9
 #define ZCR_ELx_LEN_MASK	0x1ff
 
+#define SMCR_ELx_FA64_SHIFT	31
+#define SMCR_ELx_FA64_MASK	(1 << SMCR_ELx_FA64_SHIFT)
+
+/*
+ * The SMCR_ELx_LEN_* definitions intentionally include bits [8:4] which
+ * are reserved by the SME architecture for future expansion of the LEN
+ * field, with compatible semantics.
+ */
+#define SMCR_ELx_LEN_SHIFT	0
+#define SMCR_ELx_LEN_SIZE	9
+#define SMCR_ELx_LEN_MASK	0x1ff
+
 #define CPACR_EL1_FPEN_EL1EN	(BIT(20)) /* enable EL1 access */
 #define CPACR_EL1_FPEN_EL0EN	(BIT(21)) /* enable EL0 access, if EL1EN set */
 
+#define CPACR_EL1_SMEN_EL1EN	(BIT(24)) /* enable EL1 access */
+#define CPACR_EL1_SMEN_EL0EN	(BIT(25)) /* enable EL0 access, if EL1EN set */
+
 #define CPACR_EL1_ZEN_EL1EN	(BIT(16)) /* enable EL1 access */
 #define CPACR_EL1_ZEN_EL0EN	(BIT(17)) /* enable EL0 access, if EL1EN set */
 
@@ -1152,6 +1207,8 @@
 #define TRFCR_ELx_ExTRE			BIT(1)
 #define TRFCR_ELx_E0TRE			BIT(0)
 
+/* HCRX_EL2 definitions */
+#define HCRX_EL2_SMPME_MASK		(1 << 5)
 
 /* GIC Hypervisor interface registers */
 /* ICH_MISR_EL2 bit definitions */
@@ -1215,6 +1272,12 @@
 #define ICH_VTR_TDS_SHIFT	19
 #define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)
 
+/* HFG[WR]TR_EL2 bit definitions */
+#define HFGxTR_EL2_nTPIDR2_EL0_SHIFT	55
+#define HFGxTR_EL2_nTPIDR2_EL0_MASK	BIT_MASK(HFGxTR_EL2_nTPIDR2_EL0_SHIFT)
+#define HFGxTR_EL2_nSMPRI_EL1_SHIFT	54
+#define HFGxTR_EL2_nSMPRI_EL1_MASK	BIT_MASK(HFGxTR_EL2_nSMPRI_EL1_SHIFT)
+
 #define ARM64_FEATURE_FIELD_BITS	4
 
 /* Create a mask for the feature bits of the specified feature. */
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 70fc42470f13..88effb25c399 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -822,6 +822,7 @@ static const char *esr_class_str[] = {
 	[ESR_ELx_EC_SVE]		= "SVE",
 	[ESR_ELx_EC_ERET]		= "ERET/ERETAA/ERETAB",
 	[ESR_ELx_EC_FPAC]		= "FPAC",
+	[ESR_ELx_EC_SME]		= "SME",
 	[ESR_ELx_EC_IMP_DEF]		= "EL3 IMP DEF",
 	[ESR_ELx_EC_IABT_LOW]		= "IABT (lower EL)",
 	[ESR_ELx_EC_IABT_CUR]		= "IABT (current EL)",
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:17 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:17 +0000
Subject: [PATCH v10 07/39] arm64/sme: Manually encode SME instructions
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-8-broonie@kernel.org>

As with SVE rather than impose ambitious toolchain requirements for SME
we manually encode the few instructions which we require in order to
perform the work the kernel needs to do. The instructions used to save
and restore context are provided as assembler macros while those for
entering and leaving streaming mode are done in asm volatile blocks
since they are expected to be used from C.

We could do the SMSTART and SMSTOP operations with read/modify/write
cycles on SVCR but using the aliases provided for individual field
accesses should be slightly faster. These instructions are aliases for
MSR but since our minimum toolchain requirements are old enough to mean
that we can't use the sX_X_cX_cX_X form and they always use xzr rather
than taking a value like write_sysreg_s() wants we just use .inst.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       | 25 +++++++++++++
 arch/arm64/include/asm/fpsimdmacros.h | 53 +++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index cb24385e3632..c90f7f99a768 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -249,6 +249,31 @@ static inline void sve_setup(void) { }
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static inline void sme_smstart_sm(void)
+{
+	asm volatile(".inst 0xd503437f");
+}
+
+static inline void sme_smstop_sm(void)
+{
+	asm volatile(".inst 0xd503427f");
+}
+
+static inline void sme_smstop(void)
+{
+	asm volatile(".inst 0xd503467f");
+}
+
+#else
+
+static inline void sme_smstart_sm(void) { }
+static inline void sme_smstop_sm(void) { }
+static inline void sme_smstop(void) { }
+
+#endif /* ! CONFIG_ARM64_SME */
+
 /* For use by EFI runtime services calls only */
 extern void __efi_fpsimd_begin(void);
 extern void __efi_fpsimd_end(void);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 2509d7dde55a..11c426ddd62c 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -93,6 +93,12 @@
 	.endif
 .endm
 
+.macro _sme_check_wv v
+	.if (\v) < 12 || (\v) > 15
+		.error "Bad vector select register \v."
+	.endif
+.endm
+
 /* SVE instruction encodings for non-SVE-capable assemblers */
 /* (pre binutils 2.28, all kernel capable clang versions support SVE) */
 
@@ -174,6 +180,53 @@
 		| (\np)
 .endm
 
+/* SME instruction encodings for non-SME-capable assemblers */
+
+/* RDSVL X\nx, #\imm */
+.macro _sme_rdsvl nx, imm
+	_check_general_reg \nx
+	_check_num (\imm), -0x20, 0x1f
+	.inst	0x04bf5800			\
+		| (\nx)				\
+		| (((\imm) & 0x3f) << 5)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_str_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _sme_ldr_zav nw, nxbase, offset=0
+	_sme_check_wv \nw
+	_check_general_reg \nxbase
+	_check_num (\offset), -0x100, 0xff
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * Zero the entire ZA array
+ *	ZERO ZA
+ */
+.macro zero_za
+	.inst 0xc00800ff
+.endm
+
 .macro __for from:req, to:req
 	.if (\from) == (\to)
 		_for__body %\from
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:18 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:18 +0000
Subject: [PATCH v10 08/39] arm64/sme: Early CPU setup for SME
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-9-broonie@kernel.org>

SME requires similar setup to that for SVE: disable traps to EL2 and
make sure that the maximum vector length is available to EL1, for SME we
have two traps - one for SME itself and one for TPIDR2.

In addition since we currently make no active use of priority control
for SCMUs we map all SME priorities lower ELs may configure to 0, the
architecture specified minimum priority, to ensure that nothing we
manage is able to configure itself to consume excessive resources.  This
will need to be revisited should there be a need to manage SME
priorities at runtime.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/el2_setup.h | 64 ++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 3198acb2aad8..31f1a69c9dd2 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -143,6 +143,50 @@
 .Lskip_sve_\@:
 .endm
 
+/* SME register access and priority mapping */
+.macro __init_el2_nvhe_sme
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	bic	x0, x0, #CPTR_EL2_TSM		// Also disable SME traps
+	msr	cptr_el2, x0			// Disable copro. traps to EL2
+	isb
+
+	mrs	x1, sctlr_el2
+	orr	x1, x1, #SCTLR_ELx_ENTP2	// Disable TPIDR2 traps
+	msr	sctlr_el2, x1
+	isb
+
+	mov	x1, #0				// SMCR controls
+
+	mrs_s	x2, SYS_ID_AA64SMFR0_EL1
+	ubfx	x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
+	cbz	x2, .Lskip_sme_fa64_\@
+
+	orr	x1, x1, SMCR_ELx_FA64_MASK
+.Lskip_sme_fa64_\@:
+
+	orr	x1, x1, #SMCR_ELx_LEN_MASK	// Enable full SME vector
+	msr_s	SYS_SMCR_EL2, x1		// length for EL1.
+
+	mrs_s	x1, SYS_SMIDR_EL1		// Priority mapping supported?
+	ubfx    x1, x1, #SYS_SMIDR_EL1_SMPS_SHIFT, #1
+	cbz     x1, .Lskip_sme_\@
+
+	msr_s	SYS_SMPRIMAP_EL2, xzr		// Make all priorities equal
+
+	mrs	x1, id_aa64mmfr1_el1		// HCRX_EL2 present?
+	ubfx	x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
+	cbz	x1, .Lskip_sme_\@
+
+	mrs_s	x1, SYS_HCRX_EL2
+	orr	x1, x1, #HCRX_EL2_SMPME_MASK	// Enable priority mapping
+	msr_s	SYS_HCRX_EL2, x1
+
+.Lskip_sme_\@:
+.endm
+
 /* Disable any fine grained traps */
 .macro __init_el2_fgt
 	mrs	x1, id_aa64mmfr0_el1
@@ -153,15 +197,26 @@
 	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4
 	cmp	x1, #3
-	b.lt	.Lset_fgt_\@
+	b.lt	.Lset_debug_fgt_\@
 	/* Disable PMSNEVFR_EL1 read and write traps */
 	orr	x0, x0, #(1 << 62)
 
-.Lset_fgt_\@:
+.Lset_debug_fgt_\@:
 	msr_s	SYS_HDFGRTR_EL2, x0
 	msr_s	SYS_HDFGWTR_EL2, x0
-	msr_s	SYS_HFGRTR_EL2, xzr
-	msr_s	SYS_HFGWTR_EL2, xzr
+
+	mov	x0, xzr
+	mrs	x1, id_aa64pfr1_el1
+	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
+	cbz	x1, .Lset_fgt_\@
+
+	/* Disable nVHE traps of TPIDR2 and SMPRI */
+	orr	x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK
+	orr	x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK
+
+.Lset_fgt_\@:
+	msr_s	SYS_HFGRTR_EL2, x0
+	msr_s	SYS_HFGWTR_EL2, x0
 	msr_s	SYS_HFGITR_EL2, xzr
 
 	mrs	x1, id_aa64pfr0_el1		// AMU traps UNDEF without AMU
@@ -196,6 +251,7 @@
 	__init_el2_nvhe_idregs
 	__init_el2_nvhe_cptr
 	__init_el2_nvhe_sve
+	__init_el2_nvhe_sme
 	__init_el2_fgt
 	__init_el2_nvhe_prepare_eret
 .endm
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:19 +0000
Subject: [PATCH v10 09/39] arm64/sme: Basic enumeration support
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-10-broonie@kernel.org>

This patch introduces basic cpufeature support for discovering the presence
of the Scalable Matrix Extension.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/elf_hwcaps.rst  | 33 +++++++++++++++++
 arch/arm64/include/asm/cpu.h        |  1 +
 arch/arm64/include/asm/cpufeature.h | 12 ++++++
 arch/arm64/include/asm/fpsimd.h     |  2 +
 arch/arm64/include/asm/hwcap.h      |  8 ++++
 arch/arm64/include/uapi/asm/hwcap.h |  8 ++++
 arch/arm64/kernel/cpufeature.c      | 57 +++++++++++++++++++++++++++++
 arch/arm64/kernel/cpuinfo.c         |  9 +++++
 arch/arm64/kernel/fpsimd.c          | 30 +++++++++++++++
 arch/arm64/tools/cpucaps            |  2 +
 10 files changed, 162 insertions(+)

diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index b72ff17d600a..5626cf208000 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -259,6 +259,39 @@ HWCAP2_RPRES
 
     Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
 
+HWCAP2_SME
+
+    Functionality implied by ID_AA64PFR1_EL1.SME == 0b0001, as described
+    by Documentation/arm64/sme.rst.
+
+HWCAP2_SME_I16I64
+
+    Functionality implied by ID_AA64SMFR0_EL1.I16I64 == 0b1111.
+
+HWCAP2_SME_F64F64
+
+    Functionality implied by ID_AA64SMFR0_EL1.F64F64 == 0b1.
+
+HWCAP2_SME_I8I32
+
+    Functionality implied by ID_AA64SMFR0_EL1.I8I32 == 0b1111.
+
+HWCAP2_SME_F16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F16F32 == 0b1.
+
+HWCAP2_SME_B16F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.B16F32 == 0b1.
+
+HWCAP2_SME_F32F32
+
+    Functionality implied by ID_AA64SMFR0_EL1.F32F32 == 0b1.
+
+HWCAP2_SME_FA64
+
+    Functionality implied by ID_AA64SMFR0_EL1.FA64 == 0b1.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index a58e366f0b07..d08062bcb9c1 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -58,6 +58,7 @@ struct cpuinfo_arm64 {
 	u64		reg_id_aa64pfr0;
 	u64		reg_id_aa64pfr1;
 	u64		reg_id_aa64zfr0;
+	u64		reg_id_aa64smfr0;
 
 	struct cpuinfo_32bit	aarch32;
 
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 2728abd9cae4..f93b1442143f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -728,6 +728,18 @@ static __always_inline bool system_supports_sve(void)
 		cpus_have_const_cap(ARM64_SVE);
 }
 
+static __always_inline bool system_supports_sme(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME);
+}
+
+static __always_inline bool system_supports_fa64(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_SME) &&
+		cpus_have_const_cap(ARM64_SME_FA64);
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index c90f7f99a768..6b7eb6f2cecd 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -74,6 +74,8 @@ extern void sve_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
+extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f68fbb207473..76d9999527c5 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -108,6 +108,14 @@
 #define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
 #define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
 #define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_SME		__khwcap2_feature(SME)
+#define KERNEL_HWCAP_SME_I16I64		__khwcap2_feature(SME_I16I64)
+#define KERNEL_HWCAP_SME_F64F64		__khwcap2_feature(SME_F64F64)
+#define KERNEL_HWCAP_SME_I8I32		__khwcap2_feature(SME_I8I32)
+#define KERNEL_HWCAP_SME_F16F32		__khwcap2_feature(SME_F16F32)
+#define KERNEL_HWCAP_SME_B16F32		__khwcap2_feature(SME_B16F32)
+#define KERNEL_HWCAP_SME_F32F32		__khwcap2_feature(SME_F32F32)
+#define KERNEL_HWCAP_SME_FA64		__khwcap2_feature(SME_FA64)
 
 /*
  * This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index f03731847d9d..60de5626f8fb 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -78,5 +78,13 @@
 #define HWCAP2_ECV		(1 << 19)
 #define HWCAP2_AFP		(1 << 20)
 #define HWCAP2_RPRES		(1 << 21)
+#define HWCAP2_SME		(1 << 22)
+#define HWCAP2_SME_I16I64	(1 << 23)
+#define HWCAP2_SME_F64F64	(1 << 24)
+#define HWCAP2_SME_I8I32	(1 << 25)
+#define HWCAP2_SME_F16F32	(1 << 26)
+#define HWCAP2_SME_B16F32	(1 << 27)
+#define HWCAP2_SME_F32F32	(1 << 28)
+#define HWCAP2_SME_FA64		(1 << 29)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index d9f09e40aaf6..3cd7fe53cffa 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -251,6 +251,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SME_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_MPAMFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_RASFRAC_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_MTE),
@@ -283,6 +284,24 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_id_aa64smfr0[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_FA64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I16I64_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F64F64_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_I8I32_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_B16F32_SHIFT, 1, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_SME),
+		       FTR_STRICT, FTR_EXACT, ID_AA64SMFR0_F32F32_SHIFT, 1, 0),
+	ARM64_FTR_END,
+};
+
 static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0),
@@ -634,6 +653,7 @@ static const struct __ftr_reg_entry {
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
 			       &id_aa64pfr1_override),
 	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
+	ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
 
 	/* Op1 = 0, CRn = 0, CRm = 5 */
 	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -947,6 +967,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 	init_cpu_ftr_reg(SYS_ID_AA64PFR0_EL1, info->reg_id_aa64pfr0);
 	init_cpu_ftr_reg(SYS_ID_AA64PFR1_EL1, info->reg_id_aa64pfr1);
 	init_cpu_ftr_reg(SYS_ID_AA64ZFR0_EL1, info->reg_id_aa64zfr0);
+	init_cpu_ftr_reg(SYS_ID_AA64SMFR0_EL1, info->reg_id_aa64smfr0);
 
 	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
 		init_32bit_cpu_features(&info->aarch32);
@@ -2400,6 +2421,32 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.min_field_value = 1,
 	},
+#ifdef CONFIG_ARM64_SME
+	{
+		.desc = "Scalable Matrix Extension",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME,
+		.sys_reg = SYS_ID_AA64PFR1_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64PFR1_SME_SHIFT,
+		.field_width = 4,
+		.min_field_value = ID_AA64PFR1_SME,
+		.matches = has_cpuid_feature,
+		.cpu_enable = sme_kernel_enable,
+	},
+	{
+		.desc = "FA64",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_SME_FA64,
+		.sys_reg = SYS_ID_AA64SMFR0_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64SMFR0_FA64_SHIFT,
+		.field_width = 1,
+		.min_field_value = ID_AA64SMFR0_FA64,
+		.matches = has_cpuid_feature,
+		.cpu_enable = fa64_kernel_enable,
+	},
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
@@ -2524,6 +2571,16 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
 	HWCAP_CAP(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_RPRES_SHIFT, 4, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_RPRES),
+#ifdef CONFIG_ARM64_SME
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SME_SHIFT, 4, FTR_UNSIGNED, ID_AA64PFR1_SME, CAP_HWCAP, KERNEL_HWCAP_SME),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_FA64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_FA64, CAP_HWCAP, KERNEL_HWCAP_SME_FA64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I16I64_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I16I64, CAP_HWCAP, KERNEL_HWCAP_SME_I16I64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F64F64_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F64F64, CAP_HWCAP, KERNEL_HWCAP_SME_F64F64),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_I8I32_SHIFT, 4, FTR_UNSIGNED, ID_AA64SMFR0_I8I32, CAP_HWCAP, KERNEL_HWCAP_SME_I8I32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F16F32, CAP_HWCAP, KERNEL_HWCAP_SME_F16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_B16F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_B16F32, CAP_HWCAP, KERNEL_HWCAP_SME_B16F32),
+	HWCAP_CAP(SYS_ID_AA64SMFR0_EL1, ID_AA64SMFR0_F32F32_SHIFT, 1, FTR_UNSIGNED, ID_AA64SMFR0_F32F32, CAP_HWCAP, KERNEL_HWCAP_SME_F32F32),
+#endif /* CONFIG_ARM64_SME */
 	{},
 };
 
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..33ec182e872e 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -97,6 +97,14 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_ECV]		= "ecv",
 	[KERNEL_HWCAP_AFP]		= "afp",
 	[KERNEL_HWCAP_RPRES]		= "rpres",
+	[KERNEL_HWCAP_SME]		= "sme",
+	[KERNEL_HWCAP_SME_I16I64]	= "smei16i64",
+	[KERNEL_HWCAP_SME_F64F64]	= "smef64f64",
+	[KERNEL_HWCAP_SME_I8I32]	= "smei8i32",
+	[KERNEL_HWCAP_SME_F16F32]	= "smef16f32",
+	[KERNEL_HWCAP_SME_B16F32]	= "smeb16f32",
+	[KERNEL_HWCAP_SME_F32F32]	= "smef32f32",
+	[KERNEL_HWCAP_SME_FA64]		= "smefa64",
 };
 
 #ifdef CONFIG_COMPAT
@@ -400,6 +408,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	info->reg_id_aa64pfr0 = read_cpuid(ID_AA64PFR0_EL1);
 	info->reg_id_aa64pfr1 = read_cpuid(ID_AA64PFR1_EL1);
 	info->reg_id_aa64zfr0 = read_cpuid(ID_AA64ZFR0_EL1);
+	info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1);
 
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		info->reg_gmid = read_cpuid(GMID_EL1);
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 5280e098cfb5..576490be3c2b 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -987,6 +987,32 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Set priority for all PEs to architecturally defined minimum */
+	write_sysreg_s(read_sysreg_s(SYS_SMPRI_EL1) & ~SMPRI_EL1_PRIORITY_MASK,
+		       SYS_SMPRI_EL1);
+
+	/* Allow SME in kernel */
+	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
+	isb();
+}
+
+/*
+ * This must be called after sme_kernel_enable(), we rely on the
+ * feature table being sorted to ensure this.
+ */
+void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
+{
+	/* Allow use of FA64 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_FA64_MASK,
+		       SYS_SMCR_EL1);
+}
+
+#endif /* CONFIG_ARM64_SVE */
+
 /*
  * Trapped SVE access
  *
@@ -1532,6 +1558,10 @@ static int __init fpsimd_init(void)
 	if (!cpu_have_named_feature(ASIMD))
 		pr_notice("Advanced SIMD is not implemented\n");
 
+
+	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
+		pr_notice("SME is implemented but not SVE\n");
+
 	return sve_sysctl_init();
 }
 core_initcall(fpsimd_init);
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..58dfc8547c64 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -41,6 +41,8 @@ KVM_PROTECTED_MODE
 MISMATCHED_CACHE_TYPE
 MTE
 MTE_ASYMM
+SME
+SME_FA64
 SPECTRE_V2
 SPECTRE_V3A
 SPECTRE_V4
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:20 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:20 +0000
Subject: [PATCH v10 10/39] arm64/sme: Identify supported SME vector lengths at
 boot
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-11-broonie@kernel.org>

The vector lengths used for SME are controlled through a similar set of
registers to those for SVE and enumerated using a similar algorithm with
some slight differences due to the fact that unlike SVE there are no
restrictions on which combinations of vector lengths can be supported
nor any mandatory vector lengths which must be implemented.  Add a new
vector type and implement support for enumerating it.

One slightly awkward feature is that we need to read the current vector
length using a different instruction (or enter streaming mode which
would have the same issue and be higher cost).  Rather than add an ops
structure we add special cases directly in the otherwise generic
vec_probe_vqs() function, this is a bit inelegant but it's the only
place where this is an issue.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpu.h        |   3 +
 arch/arm64/include/asm/cpufeature.h |   7 ++
 arch/arm64/include/asm/fpsimd.h     |  26 ++++++
 arch/arm64/include/asm/processor.h  |   1 +
 arch/arm64/kernel/cpufeature.c      |  49 +++++++++++
 arch/arm64/kernel/cpuinfo.c         |   4 +
 arch/arm64/kernel/entry-fpsimd.S    |   9 ++
 arch/arm64/kernel/fpsimd.c          | 123 +++++++++++++++++++++++++++-
 8 files changed, 220 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h
index d08062bcb9c1..550e1fc4ae6c 100644
--- a/arch/arm64/include/asm/cpu.h
+++ b/arch/arm64/include/asm/cpu.h
@@ -64,6 +64,9 @@ struct cpuinfo_arm64 {
 
 	/* pseudo-ZCR for recording maximum ZCR_EL1 LEN value: */
 	u64		reg_zcr;
+
+	/* pseudo-SMCR for recording maximum ZCR_EL1 LEN value: */
+	u64		reg_smcr;
 };
 
 DECLARE_PER_CPU(struct cpuinfo_arm64, cpu_data);
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index f93b1442143f..9d36035acce3 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -620,6 +620,13 @@ static inline bool id_aa64pfr0_sve(u64 pfr0)
 	return val > 0;
 }
 
+static inline bool id_aa64pfr1_sme(u64 pfr1)
+{
+	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_SME_SHIFT);
+
+	return val > 0;
+}
+
 static inline bool id_aa64pfr1_mte(u64 pfr1)
 {
 	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_MTE_SHIFT);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 6b7eb6f2cecd..8cb99b6fe565 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -78,6 +78,7 @@ extern void sme_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 extern void fa64_kernel_enable(const struct arm64_cpu_capabilities *__unused);
 
 extern u64 read_zcr_features(void);
+extern u64 read_smcr_features(void);
 
 /*
  * Helpers to translate bit indices in sve_vq_map to VQ values (and
@@ -172,6 +173,12 @@ static inline void write_vl(enum vec_type type, u64 val)
 		tmp = read_sysreg_s(SYS_ZCR_EL1) & ~ZCR_ELx_LEN_MASK;
 		write_sysreg_s(tmp | val, SYS_ZCR_EL1);
 		break;
+#endif
+#ifdef CONFIG_ARM64_SME
+	case ARM64_VEC_SME:
+		tmp = read_sysreg_s(SYS_SMCR_EL1) & ~SMCR_ELx_LEN_MASK;
+		write_sysreg_s(tmp | val, SYS_SMCR_EL1);
+		break;
 #endif
 	default:
 		WARN_ON_ONCE(1);
@@ -268,12 +275,31 @@ static inline void sme_smstop(void)
 	asm volatile(".inst 0xd503467f");
 }
 
+extern void __init sme_setup(void);
+
+static inline int sme_max_vl(void)
+{
+	return vec_max_vl(ARM64_VEC_SME);
+}
+
+static inline int sme_max_virtualisable_vl(void)
+{
+	return vec_max_virtualisable_vl(ARM64_VEC_SME);
+}
+
+extern unsigned int sme_get_vl(void);
+
 #else
 
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_setup(void) { }
+static inline unsigned int sme_get_vl(void) { return 0; }
+static inline int sme_max_vl(void) { return 0; }
+static inline int sme_max_virtualisable_vl(void) { return 0; }
+
 #endif /* ! CONFIG_ARM64_SME */
 
 /* For use by EFI runtime services calls only */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..df68f0fb0ded 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -117,6 +117,7 @@ struct debug_info {
 
 enum vec_type {
 	ARM64_VEC_SVE = 0,
+	ARM64_VEC_SME,
 	ARM64_VEC_MAX,
 };
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 3cd7fe53cffa..1995ff72a8c6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -570,6 +570,12 @@ static const struct arm64_ftr_bits ftr_zcr[] = {
 	ARM64_FTR_END,
 };
 
+static const struct arm64_ftr_bits ftr_smcr[] = {
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE,
+		SMCR_ELx_LEN_SHIFT, SMCR_ELx_LEN_SIZE, 0),	/* LEN */
+	ARM64_FTR_END,
+};
+
 /*
  * Common ftr bits for a 32bit register with all hidden, strict
  * attributes, with 4bit feature fields and a default safe value of
@@ -673,6 +679,7 @@ static const struct __ftr_reg_entry {
 
 	/* Op1 = 0, CRn = 1, CRm = 2 */
 	ARM64_FTR_REG(SYS_ZCR_EL1, ftr_zcr),
+	ARM64_FTR_REG(SYS_SMCR_EL1, ftr_smcr),
 
 	/* Op1 = 1, CRn = 0, CRm = 0 */
 	ARM64_FTR_REG(SYS_GMID_EL1, ftr_gmid),
@@ -977,6 +984,14 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
 		vec_init_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		init_cpu_ftr_reg(SYS_SMCR_EL1, info->reg_smcr);
+		if (IS_ENABLED(CONFIG_ARM64_SME)) {
+			sme_kernel_enable(NULL);
+			vec_init_vq_map(ARM64_VEC_SME);
+		}
+	}
+
 	if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
 		init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
 
@@ -1203,6 +1218,9 @@ void update_cpu_features(int cpu,
 	taint |= check_update_ftr_reg(SYS_ID_AA64ZFR0_EL1, cpu,
 				      info->reg_id_aa64zfr0, boot->reg_id_aa64zfr0);
 
+	taint |= check_update_ftr_reg(SYS_ID_AA64SMFR0_EL1, cpu,
+				      info->reg_id_aa64smfr0, boot->reg_id_aa64smfr0);
+
 	if (id_aa64pfr0_sve(info->reg_id_aa64pfr0)) {
 		taint |= check_update_ftr_reg(SYS_ZCR_EL1, cpu,
 					info->reg_zcr, boot->reg_zcr);
@@ -1213,6 +1231,16 @@ void update_cpu_features(int cpu,
 			vec_update_vq_map(ARM64_VEC_SVE);
 	}
 
+	if (id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		taint |= check_update_ftr_reg(SYS_SMCR_EL1, cpu,
+					info->reg_smcr, boot->reg_smcr);
+
+		/* Probe vector lengths, unless we already gave up on SME */
+		if (id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1)) &&
+		    !system_capabilities_finalized())
+			vec_update_vq_map(ARM64_VEC_SME);
+	}
+
 	/*
 	 * The kernel uses the LDGM/STGM instructions and the number of tags
 	 * they read/write depends on the GMID_EL1.BS field. Check that the
@@ -2878,6 +2906,23 @@ static void verify_sve_features(void)
 	/* Add checks on other ZCR bits here if necessary */
 }
 
+static void verify_sme_features(void)
+{
+	u64 safe_smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	u64 smcr = read_smcr_features();
+
+	unsigned int safe_len = safe_smcr & SMCR_ELx_LEN_MASK;
+	unsigned int len = smcr & SMCR_ELx_LEN_MASK;
+
+	if (len < safe_len || vec_verify_vq_map(ARM64_VEC_SME)) {
+		pr_crit("CPU%d: SME: vector length support mismatch\n",
+			smp_processor_id());
+		cpu_die_early();
+	}
+
+	/* Add checks on other SMCR bits here if necessary */
+}
+
 static void verify_hyp_capabilities(void)
 {
 	u64 safe_mmfr1, mmfr0, mmfr1;
@@ -2930,6 +2975,9 @@ static void verify_local_cpu_capabilities(void)
 	if (system_supports_sve())
 		verify_sve_features();
 
+	if (system_supports_sme())
+		verify_sme_features();
+
 	if (is_hyp_mode_available())
 		verify_hyp_capabilities();
 }
@@ -3047,6 +3095,7 @@ void __init setup_cpu_features(void)
 		pr_info("emulated: Privileged Access Never (PAN) using TTBR0_EL1 switching\n");
 
 	sve_setup();
+	sme_setup();
 	minsigstksz_setup();
 
 	/* Advertise that we have computed the system capabilities */
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 33ec182e872e..72dc155719b0 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -420,6 +420,10 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
 	    id_aa64pfr0_sve(info->reg_id_aa64pfr0))
 		info->reg_zcr = read_zcr_features();
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1))
+		info->reg_smcr = read_smcr_features();
+
 	cpuinfo_detect_icache_policy(info);
 }
 
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index dc242e269f9a..deee5f01462e 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -86,3 +86,12 @@ SYM_FUNC_START(sve_flush_live)
 SYM_FUNC_END(sve_flush_live)
 
 #endif /* CONFIG_ARM64_SVE */
+
+#ifdef CONFIG_ARM64_SME
+
+SYM_FUNC_START(sme_get_vl)
+	_sme_rdsvl	0, 1
+	ret
+SYM_FUNC_END(sme_get_vl)
+
+#endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 576490be3c2b..3fb2167f8af7 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -136,6 +136,12 @@ __ro_after_init struct vl_info vl_info[ARM64_VEC_MAX] = {
 		.max_virtualisable_vl	= SVE_VL_MIN,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[ARM64_VEC_SME] = {
+		.type			= ARM64_VEC_SME,
+		.name			= "SME",
+	},
+#endif
 };
 
 static unsigned int vec_vl_inherit_flag(enum vec_type type)
@@ -186,6 +192,20 @@ extern void __percpu *efi_sve_state;
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int get_sme_default_vl(void)
+{
+	return get_default_vl(ARM64_VEC_SME);
+}
+
+static void set_sme_default_vl(int val)
+{
+	set_default_vl(ARM64_VEC_SME, val);
+}
+
+#endif
+
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
 EXPORT_PER_CPU_SYMBOL(fpsimd_context_busy);
 
@@ -403,6 +423,8 @@ static unsigned int find_supported_vector_length(enum vec_type type,
 
 	if (vl > max_vl)
 		vl = max_vl;
+	if (vl < info->min_vl)
+		vl = info->min_vl;
 
 	bit = find_next_bit(info->vq_map, SVE_VQ_MAX,
 			    __vq_to_bit(sve_vq_from_vl(vl)));
@@ -764,7 +786,23 @@ static void vec_probe_vqs(struct vl_info *info,
 
 	for (vq = SVE_VQ_MAX; vq >= SVE_VQ_MIN; --vq) {
 		write_vl(info->type, vq - 1); /* self-syncing */
-		vl = sve_get_vl();
+
+		switch (info->type) {
+		case ARM64_VEC_SVE:
+			vl = sve_get_vl();
+			break;
+		case ARM64_VEC_SME:
+			vl = sme_get_vl();
+			break;
+		default:
+			vl = 0;
+			break;
+		}
+
+		/* Minimum VL identified? */
+		if (sve_vq_from_vl(vl) > vq)
+			break;
+
 		vq = sve_vq_from_vl(vl); /* skip intervening lengths */
 		set_bit(__vq_to_bit(vq), map);
 	}
@@ -1011,7 +1049,88 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 		       SYS_SMCR_EL1);
 }
 
-#endif /* CONFIG_ARM64_SVE */
+/*
+ * Read the pseudo-SMCR used by cpufeatures to identify the supported
+ * vector length.
+ *
+ * Use only if SME is present.
+ * This function clobbers the SME vector length.
+ */
+u64 read_smcr_features(void)
+{
+	u64 smcr;
+	unsigned int vq_max;
+
+	sme_kernel_enable(NULL);
+	sme_smstart_sm();
+
+	/*
+	 * Set the maximum possible VL.
+	 */
+	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
+		       SYS_SMCR_EL1);
+
+	smcr = read_sysreg_s(SYS_SMCR_EL1);
+	smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */
+	vq_max = sve_vq_from_vl(sve_get_vl());
+	smcr |= vq_max - 1; /* set LEN field to maximum effective value */
+
+	sme_smstop_sm();
+
+	return smcr;
+}
+
+void __init sme_setup(void)
+{
+	struct vl_info *info = &vl_info[ARM64_VEC_SME];
+	u64 smcr;
+	int min_bit;
+
+	if (!system_supports_sme())
+		return;
+
+	/*
+	 * SME doesn't require any particular vector length be
+	 * supported but it does require at least one.  We should have
+	 * disabled the feature entirely while bringing up CPUs but
+	 * let's double check here.
+	 */
+	WARN_ON(bitmap_empty(info->vq_map, SVE_VQ_MAX));
+
+	min_bit = find_last_bit(info->vq_map, SVE_VQ_MAX);
+	info->min_vl = sve_vl_from_vq(__bit_to_vq(min_bit));
+
+	smcr = read_sanitised_ftr_reg(SYS_SMCR_EL1);
+	info->max_vl = sve_vl_from_vq((smcr & SMCR_ELx_LEN_MASK) + 1);
+
+	/*
+	 * Sanity-check that the max VL we determined through CPU features
+	 * corresponds properly to sme_vq_map.  If not, do our best:
+	 */
+	if (WARN_ON(info->max_vl != find_supported_vector_length(ARM64_VEC_SME,
+								 info->max_vl)))
+		info->max_vl = find_supported_vector_length(ARM64_VEC_SME,
+							    info->max_vl);
+
+	WARN_ON(info->min_vl > info->max_vl);
+
+	/*
+	 * For the default VL, pick the maximum supported value <= 32
+	 * (256 bits) if there is one since this is guaranteed not to
+	 * grow the signal frame when in streaming mode, otherwise the
+	 * minimum available VL will be used.
+	 */
+	set_sme_default_vl(find_supported_vector_length(ARM64_VEC_SME, 32));
+
+	pr_info("SME: minimum available vector length %u bytes per vector\n",
+		info->min_vl);
+	pr_info("SME: maximum available vector length %u bytes per vector\n",
+		info->max_vl);
+	pr_info("SME: default vector length %u bytes per vector\n",
+		get_sme_default_vl());
+}
+
+#endif /* CONFIG_ARM64_SME */
 
 /*
  * Trapped SVE access
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:21 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:21 +0000
Subject: [PATCH v10 11/39] arm64/sme: Implement sysctl to set the default
 vector length
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-12-broonie@kernel.org>

As for SVE provide a sysctl which allows the default SME vector length to
be configured.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 3fb2167f8af7..841b9609342f 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -483,6 +483,30 @@ static int __init sve_sysctl_init(void)
 static int __init sve_sysctl_init(void) { return 0; }
 #endif /* ! (CONFIG_ARM64_SVE && CONFIG_SYSCTL) */
 
+#if defined(CONFIG_ARM64_SME) && defined(CONFIG_SYSCTL)
+static struct ctl_table sme_default_vl_table[] = {
+	{
+		.procname	= "sme_default_vector_length",
+		.mode		= 0644,
+		.proc_handler	= vec_proc_do_default_vl,
+		.extra1		= &vl_info[ARM64_VEC_SME],
+	},
+	{ }
+};
+
+static int __init sme_sysctl_init(void)
+{
+	if (system_supports_sme())
+		if (!register_sysctl("abi", sme_default_vl_table))
+			return -EINVAL;
+
+	return 0;
+}
+
+#else /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+static int __init sme_sysctl_init(void) { return 0; }
+#endif /* ! (CONFIG_ARM64_SME && CONFIG_SYSCTL) */
+
 #define ZREG(sve_state, vq, n) ((char *)(sve_state) +		\
 	(SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET))
 
@@ -1681,6 +1705,9 @@ static int __init fpsimd_init(void)
 	if (cpu_have_named_feature(SME) && !cpu_have_named_feature(SVE))
 		pr_notice("SME is implemented but not SVE\n");
 
-	return sve_sysctl_init();
+	sve_sysctl_init();
+	sme_sysctl_init();
+
+	return 0;
 }
 core_initcall(fpsimd_init);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:22 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:22 +0000
Subject: [PATCH v10 12/39] arm64/sme: Implement vector length configuration
 prctl()s
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-13-broonie@kernel.org>

As for SVE provide a prctl() interface which allows processes to
configure their SME vector length.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  4 ++++
 arch/arm64/include/asm/processor.h   |  4 +++-
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 32 ++++++++++++++++++++++++++++
 include/uapi/linux/prctl.h           |  9 ++++++++
 kernel/sys.c                         | 12 +++++++++++
 6 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 8cb99b6fe565..babf944e7c0c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -288,6 +288,8 @@ static inline int sme_max_virtualisable_vl(void)
 }
 
 extern unsigned int sme_get_vl(void);
+extern int sme_set_current_vl(unsigned long arg);
+extern int sme_get_current_vl(void);
 
 #else
 
@@ -299,6 +301,8 @@ static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
 static inline int sme_max_virtualisable_vl(void) { return 0; }
+static inline int sme_set_current_vl(unsigned long arg) { return -EINVAL; }
+static inline int sme_get_current_vl(void) { return -EINVAL; }
 
 #endif /* ! CONFIG_ARM64_SME */
 
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index df68f0fb0ded..f2c2ebd440e2 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -354,9 +354,11 @@ extern void __init minsigstksz_setup(void);
  */
 #include <asm/fpsimd.h>
 
-/* Userspace interface for PR_SVE_{SET,GET}_VL prctl()s: */
+/* Userspace interface for PR_S[MV]E_{SET,GET}_VL prctl()s: */
 #define SVE_SET_VL(arg)	sve_set_current_vl(arg)
 #define SVE_GET_VL()	sve_get_current_vl()
+#define SME_SET_VL(arg)	sme_set_current_vl(arg)
+#define SME_GET_VL()	sme_get_current_vl()
 
 /* PR_PAC_RESET_KEYS prctl */
 #define PAC_RESET_KEYS(tsk, arg)	ptrauth_prctl_reset_keys(tsk, arg)
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index e1317b7c4525..4e6b58dcd6f9 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1 << TIF_NEED_RESCHED)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 841b9609342f..1edb3996f9cf 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -149,6 +149,8 @@ static unsigned int vec_vl_inherit_flag(enum vec_type type)
 	switch (type) {
 	case ARM64_VEC_SVE:
 		return TIF_SVE_VL_INHERIT;
+	case ARM64_VEC_SME:
+		return TIF_SME_VL_INHERIT;
 	default:
 		WARN_ON_ONCE(1);
 		return 0;
@@ -801,6 +803,36 @@ int sve_get_current_vl(void)
 	return vec_prctl_status(ARM64_VEC_SVE, 0);
 }
 
+#ifdef CONFIG_ARM64_SME
+/* PR_SME_SET_VL */
+int sme_set_current_vl(unsigned long arg)
+{
+	unsigned long vl, flags;
+	int ret;
+
+	vl = arg & PR_SME_VL_LEN_MASK;
+	flags = arg & ~vl;
+
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	ret = vec_set_vector_length(current, ARM64_VEC_SME, vl, flags);
+	if (ret)
+		return ret;
+
+	return vec_prctl_status(ARM64_VEC_SME, flags);
+}
+
+/* PR_SME_GET_VL */
+int sme_get_current_vl(void)
+{
+	if (!system_supports_sme() || is_compat_task())
+		return -EINVAL;
+
+	return vec_prctl_status(ARM64_VEC_SME, 0);
+}
+#endif /* CONFIG_ARM64_SME */
+
 static void vec_probe_vqs(struct vl_info *info,
 			  DECLARE_BITMAP(map, SVE_VQ_MAX))
 {
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index e998764f0262..a5e06dcbba13 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -272,6 +272,15 @@ struct prctl_mm_map {
 # define PR_SCHED_CORE_SCOPE_THREAD_GROUP	1
 # define PR_SCHED_CORE_SCOPE_PROCESS_GROUP	2
 
+/* arm64 Scalable Matrix Extension controls */
+/* Flag values must be in sync with SVE versions */
+#define PR_SME_SET_VL			63	/* set task vector length */
+# define PR_SME_SET_VL_ONEXEC		(1 << 18) /* defer effect until exec */
+#define PR_SME_GET_VL			64	/* get task vector length */
+/* Bits common to PR_SME_SET_VL and PR_SME_GET_VL */
+# define PR_SME_VL_LEN_MASK		0xffff
+# define PR_SME_VL_INHERIT		(1 << 17) /* inherit across exec */
+
 #define PR_SET_VMA		0x53564d41
 # define PR_SET_VMA_ANON_NAME		0
 
diff --git a/kernel/sys.c b/kernel/sys.c
index ecc4cf019242..5cd4fffc7cd0 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -116,6 +116,12 @@
 #ifndef SVE_GET_VL
 # define SVE_GET_VL()		(-EINVAL)
 #endif
+#ifndef SME_SET_VL
+# define SME_SET_VL(a)		(-EINVAL)
+#endif
+#ifndef SME_GET_VL
+# define SME_GET_VL()		(-EINVAL)
+#endif
 #ifndef PAC_RESET_KEYS
 # define PAC_RESET_KEYS(a, b)	(-EINVAL)
 #endif
@@ -2523,6 +2529,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 	case PR_SVE_GET_VL:
 		error = SVE_GET_VL();
 		break;
+	case PR_SME_SET_VL:
+		error = SME_SET_VL(arg2);
+		break;
+	case PR_SME_GET_VL:
+		error = SME_GET_VL();
+		break;
 	case PR_GET_SPECULATION_CTRL:
 		if (arg3 || arg4 || arg5)
 			return -EINVAL;
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:23 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:23 +0000
Subject: [PATCH v10 13/39] arm64/sme: Implement support for TPIDR2
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-14-broonie@kernel.org>

The Scalable Matrix Extension introduces support for a new thread specific
data register TPIDR2 intended for use by libc. The kernel must save the
value of TPIDR2 on context switch and should ensure that all new threads
start off with a default value of 0. Add a field to the thread_struct to
store TPIDR2 and context switch it with the other thread specific data.

In case there are future extensions which also use TPIDR2 we introduce
system_supports_tpidr2() and use that rather than system_supports_sme()
for TPIDR2 handling.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/cpufeature.h |  5 +++++
 arch/arm64/include/asm/processor.h  |  1 +
 arch/arm64/kernel/fpsimd.c          |  4 ++++
 arch/arm64/kernel/process.c         | 14 ++++++++++++--
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 9d36035acce3..12252352d2ee 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -747,6 +747,11 @@ static __always_inline bool system_supports_fa64(void)
 		cpus_have_const_cap(ARM64_SME_FA64);
 }
 
+static __always_inline bool system_supports_tpidr2(void)
+{
+	return system_supports_sme();
+}
+
 static __always_inline bool system_supports_cnp(void)
 {
 	return IS_ENABLED(CONFIG_ARM64_CNP) &&
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index f2c2ebd440e2..008a1767ebff 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			tpidr2_el0;
 };
 
 static inline unsigned int thread_get_vl(struct thread_struct *thread,
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 1edb3996f9cf..40ef89120774 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1092,6 +1092,10 @@ void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 	/* Allow SME in kernel */
 	write_sysreg(read_sysreg(CPACR_EL1) | CPACR_EL1_SMEN_EL1EN, CPACR_EL1);
 	isb();
+
+	/* Allow EL0 to access TPIDR2 */
+	write_sysreg(read_sysreg(SCTLR_EL1) | SCTLR_ELx_ENTP2, SCTLR_EL1);
+	isb();
 }
 
 /*
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..e69a3dcdb0d9 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -250,6 +250,8 @@ void show_regs(struct pt_regs *regs)
 static void tls_thread_flush(void)
 {
 	write_sysreg(0, tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(0, SYS_TPIDR2_EL0);
 
 	if (is_compat_task()) {
 		current->thread.uw.tp_value = 0;
@@ -343,6 +345,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 		 * out-of-sync with the saved value.
 		 */
 		*task_user_tls(p) = read_sysreg(tpidr_el0);
+		if (system_supports_tpidr2())
+			p->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 
 		if (stack_start) {
 			if (is_compat_thread(task_thread_info(p)))
@@ -353,10 +357,12 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 
 		/*
 		 * If a TLS pointer was passed to clone, use it for the new
-		 * thread.
+		 * thread.  We also reset TPIDR2 if it's in use.
 		 */
-		if (clone_flags & CLONE_SETTLS)
+		if (clone_flags & CLONE_SETTLS) {
 			p->thread.uw.tp_value = tls;
+			p->thread.tpidr2_el0 = 0;
+		}
 	} else {
 		/*
 		 * A kthread has no context to ERET to, so ensure any buggy
@@ -387,6 +393,8 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
 void tls_preserve_current_state(void)
 {
 	*task_user_tls(current) = read_sysreg(tpidr_el0);
+	if (system_supports_tpidr2() && !is_compat_task())
+		current->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0);
 }
 
 static void tls_thread_switch(struct task_struct *next)
@@ -399,6 +407,8 @@ static void tls_thread_switch(struct task_struct *next)
 		write_sysreg(0, tpidrro_el0);
 
 	write_sysreg(*task_user_tls(next), tpidr_el0);
+	if (system_supports_tpidr2())
+		write_sysreg_s(next->thread.tpidr2_el0, SYS_TPIDR2_EL0);
 }
 
 /*
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:24 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:24 +0000
Subject: [PATCH v10 14/39] arm64/sme: Implement SVCR context switching
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-15-broonie@kernel.org>

In SME the use of both streaming SVE mode and ZA are tracked through
PSTATE.SM and PSTATE.ZA, visible through the system register SVCR.  In
order to context switch the floating point state for SME we need to
context switch the contents of this register as part of context
switching the floating point state.

Since changing the vector length exits streaming SVE mode and disables
ZA we also make sure we update SVCR appropriately when setting vector
length, and similarly ensure that new threads have streaming SVE mode
and ZA disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h      |  3 ++-
 arch/arm64/include/asm/processor.h   |  1 +
 arch/arm64/include/asm/thread_info.h |  1 +
 arch/arm64/kernel/fpsimd.c           | 18 +++++++++++++++++-
 arch/arm64/kernel/process.c          |  2 ++
 arch/arm64/kvm/fpsimd.c              |  4 ++++
 6 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index babf944e7c0c..d1bae65d3dba 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -46,7 +46,8 @@ extern void fpsimd_restore_current_state(void);
 extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
-				     void *sve_state, unsigned int sve_vl);
+				     void *sve_state, unsigned int sve_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 008a1767ebff..7e08a4d48c24 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -168,6 +168,7 @@ struct thread_struct {
 	u64			mte_ctrl;
 #endif
 	u64			sctlr_user;
+	u64			svcr;
 	u64			tpidr2_el0;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 4e6b58dcd6f9..848739c15de8 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -82,6 +82,7 @@ int arch_dup_task_struct(struct task_struct *dst,
 #define TIF_SVE_VL_INHERIT	24	/* Inherit SVE vl_onexec across exec */
 #define TIF_SSBD		25	/* Wants SSB mitigation */
 #define TIF_TAGGED_ADDR		26	/* Allow tagged user addresses */
+#define TIF_SME			27	/* SME in use */
 #define TIF_SME_VL_INHERIT	28	/* Inherit SME vl_onexec across exec */
 
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 40ef89120774..a1918b71d335 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	u64 *svcr;
 	unsigned int sve_vl;
 };
 
@@ -359,6 +360,9 @@ static void task_fpsimd_load(void)
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
 		sve_load_state(sve_pffr(&current->thread),
@@ -384,6 +388,12 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    test_thread_flag(TIF_SME)) {
+		u64 *svcr = last->svcr;
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+	}
+
 	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
 	    test_thread_flag(TIF_SVE)) {
 		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
@@ -735,6 +745,10 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
 		sve_to_fpsimd(task);
 
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
+				       SYS_SVCR_EL0_ZA_MASK);
+
 	if (task == current)
 		put_cpu_fpsimd_context();
 
@@ -1398,6 +1412,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
 	if (system_supports_sve()) {
@@ -1412,7 +1427,7 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl)
+			      unsigned int sve_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1421,6 +1436,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	WARN_ON(!in_softirq() && !irqs_disabled());
 
 	last->st = st;
+	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
 }
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index e69a3dcdb0d9..f2d32a29641c 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -310,6 +310,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.svcr = 0;
+
 	/* clear any pending asynchronous tag fault raised by the parent */
 	clear_tsk_thread_flag(dst, TIF_MTE_ASYNC_FAULT);
 
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 2f48fd362a8c..04698c4bcd30 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -103,6 +103,10 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 	WARN_ON_ONCE(!irqs_disabled());
 
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
+		/*
+		 * Currently we do not support SME guests so SVCR is
+		 * always 0 and we just need a variable to point to.
+		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:25 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:25 +0000
Subject: [PATCH v10 15/39] arm64/sme: Implement streaming SVE context switching
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-16-broonie@kernel.org>

When in streaming mode we need to save and restore the streaming mode
SVE register state rather than the regular SVE register state. This uses
the streaming mode vector length and omits FFR but is otherwise identical,
if TIF_SVE is enabled when we are in streaming mode then streaming mode
takes precedence.

This does not handle use of streaming SVE state with KVM, ptrace or
signals. This will be updated in further patches.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  22 +++++-
 arch/arm64/include/asm/fpsimdmacros.h |  11 +++
 arch/arm64/include/asm/processor.h    |  10 +++
 arch/arm64/kernel/entry-fpsimd.S      |   5 ++
 arch/arm64/kernel/fpsimd.c            | 109 +++++++++++++++++++++-----
 arch/arm64/kvm/fpsimd.c               |   3 +-
 6 files changed, 137 insertions(+), 23 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index d1bae65d3dba..650ec642159c 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,11 +47,21 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     u64 *svcr);
+				     unsigned int sme_vl, u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
 
+static inline bool thread_sm_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_SM_MASK);
+}
+
+static inline bool thread_za_enabled(struct thread_struct *thread)
+{
+	return system_supports_sme() && (thread->svcr & SYS_SVCR_EL0_ZA_MASK);
+}
+
 /* Maximum VL that SVE/SME VL-agnostic software can transparently support */
 #define VL_ARCH_MAX 0x100
 
@@ -63,7 +73,14 @@ static inline size_t sve_ffr_offset(int vl)
 
 static inline void *sve_pffr(struct thread_struct *thread)
 {
-	return (char *)thread->sve_state + sve_ffr_offset(thread_get_sve_vl(thread));
+	unsigned int vl;
+
+	if (system_supports_sme() && thread_sm_enabled(thread))
+		vl = thread_get_sme_vl(thread);
+	else
+		vl = thread_get_sve_vl(thread);
+
+	return (char *)thread->sve_state + sve_ffr_offset(vl);
 }
 
 extern void sve_save_state(void *state, u32 *pfpsr, int save_ffr);
@@ -72,6 +89,7 @@ extern void sve_load_state(void const *state, u32 const *pfpsr,
 extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
+extern void sme_set_vq(unsigned long vq_minus_1);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index 11c426ddd62c..a50fa1eab730 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -261,6 +261,17 @@
 921:
 .endm
 
+/* Update SMCR_EL1.LEN with the new VQ */
+.macro sme_load_vq xvqminus1, xtmp, xtmp2
+		mrs_s		\xtmp, SYS_SMCR_EL1
+		bic		\xtmp2, \xtmp, SMCR_ELx_LEN_MASK
+		orr		\xtmp2, \xtmp2, \xvqminus1
+		cmp		\xtmp2, \xtmp
+		b.eq		921f
+		msr_s		SYS_SMCR_EL1, \xtmp2	//self-synchronising
+921:
+.endm
+
 /* Preserve the first 128-bits of Znz and zero the rest. */
 .macro _sve_flush_z nz
 	_sve_check_zreg \nz
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 7e08a4d48c24..6e2af9de153c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -183,6 +183,11 @@ static inline unsigned int thread_get_sve_vl(struct thread_struct *thread)
 	return thread_get_vl(thread, ARM64_VEC_SVE);
 }
 
+static inline unsigned int thread_get_sme_vl(struct thread_struct *thread)
+{
+	return thread_get_vl(thread, ARM64_VEC_SME);
+}
+
 unsigned int task_get_vl(const struct task_struct *task, enum vec_type type);
 void task_set_vl(struct task_struct *task, enum vec_type type,
 		 unsigned long vl);
@@ -196,6 +201,11 @@ static inline unsigned int task_get_sve_vl(const struct task_struct *task)
 	return task_get_vl(task, ARM64_VEC_SVE);
 }
 
+static inline unsigned int task_get_sme_vl(const struct task_struct *task)
+{
+	return task_get_vl(task, ARM64_VEC_SME);
+}
+
 static inline void task_set_sve_vl(struct task_struct *task, unsigned long vl)
 {
 	task_set_vl(task, ARM64_VEC_SVE, vl);
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index deee5f01462e..6f88c0f86d50 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -94,4 +94,9 @@ SYM_FUNC_START(sme_get_vl)
 	ret
 SYM_FUNC_END(sme_get_vl)
 
+SYM_FUNC_START(sme_set_vq)
+	sme_load_vq x0, x1, x2
+	ret
+SYM_FUNC_END(sme_set_vq)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index a1918b71d335..12fef62cf07a 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -123,6 +123,7 @@ struct fpsimd_last_state_struct {
 	void *sve_state;
 	u64 *svcr;
 	unsigned int sve_vl;
+	unsigned int sme_vl;
 };
 
 static DEFINE_PER_CPU(struct fpsimd_last_state_struct, fpsimd_last_state);
@@ -301,17 +302,28 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
 	task->thread.vl_onexec[type] = vl;
 }
 
+/*
+ * TIF_SME controls whether a task can use SME without trapping while
+ * in userspace, when TIF_SME is set then we must have storage
+ * alocated in sve_state and za_state to store the contents of both ZA
+ * and the SVE registers for both streaming and non-streaming modes.
+ *
+ * If both SVCR.ZA and SVCR.SM are disabled then at any point we
+ * may disable TIF_SME and reenable traps.
+ */
+
+
 /*
  * TIF_SVE controls whether a task can use SVE without trapping while
- * in userspace, and also the way a task's FPSIMD/SVE state is stored
- * in thread_struct.
+ * in userspace, and also (together with TIF_SME) the way a task's
+ * FPSIMD/SVE state is stored in thread_struct.
  *
  * The kernel uses this flag to track whether a user task is actively
  * using SVE, and therefore whether full SVE register state needs to
  * be tracked.  If not, the cheaper FPSIMD context handling code can
  * be used instead of the more costly SVE equivalents.
  *
- *  * TIF_SVE set:
+ *  * TIF_SVE or SVCR.SM set:
  *
  *    The task can execute SVE instructions while in userspace without
  *    trapping to the kernel.
@@ -319,7 +331,8 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  *    When stored, Z0-Z31 (incorporating Vn in bits[127:0] or the
  *    corresponding Zn), P0-P15 and FFR are encoded in in
  *    task->thread.sve_state, formatted appropriately for vector
- *    length task->thread.sve_vl.
+ *    length task->thread.sve_vl or, if SVCR.SM is set,
+ *    task->thread.sme_vl.
  *
  *    task->thread.sve_state must point to a valid buffer at least
  *    sve_state_size(task) bytes in size.
@@ -357,19 +370,40 @@ void task_set_vl_onexec(struct task_struct *task, enum vec_type type,
  */
 static void task_fpsimd_load(void)
 {
+	bool restore_sve_regs = false;
+	bool restore_ffr;
+
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) && test_thread_flag(TIF_SME))
-		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
-
+	/* Check if we should restore SVE first */
 	if (IS_ENABLED(CONFIG_ARM64_SVE) && test_thread_flag(TIF_SVE)) {
 		sve_set_vq(sve_vq_from_vl(task_get_sve_vl(current)) - 1);
+		restore_sve_regs = true;
+		restore_ffr = true;
+	}
+
+	/* Restore SME, override SVE register configuration if needed */
+	if (system_supports_sme()) {
+		unsigned long sme_vl = task_get_sme_vl(current);
+
+		if (test_thread_flag(TIF_SME))
+			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
+
+		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
+
+		if (thread_sm_enabled(&current->thread)) {
+			restore_sve_regs = true;
+			restore_ffr = system_supports_fa64();
+		}
+	}
+
+	if (restore_sve_regs)
 		sve_load_state(sve_pffr(&current->thread),
-			       &current->thread.uw.fpsimd_state.fpsr, true);
-	} else {
+			       &current->thread.uw.fpsimd_state.fpsr,
+			       restore_ffr);
+	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
-	}
 }
 
 /*
@@ -381,6 +415,9 @@ static void fpsimd_save(void)
 	struct fpsimd_last_state_struct const *last =
 		this_cpu_ptr(&fpsimd_last_state);
 	/* set by fpsimd_bind_task_to_cpu() or fpsimd_bind_state_to_cpu() */
+	bool save_sve_regs = false;
+	bool save_ffr;
+	unsigned int vl;
 
 	WARN_ON(!system_supports_fpsimd());
 	WARN_ON(!have_cpu_fpsimd_context());
@@ -388,15 +425,33 @@ static void fpsimd_save(void)
 	if (test_thread_flag(TIF_FOREIGN_FPSTATE))
 		return;
 
-	if (IS_ENABLED(CONFIG_ARM64_SME) &&
-	    test_thread_flag(TIF_SME)) {
+	if (test_thread_flag(TIF_SVE)) {
+		save_sve_regs = true;
+		save_ffr = true;
+		vl = last->sve_vl;
+	}
+
+	if (system_supports_sme()) {
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (thread_za_enabled(&current->thread)) {
+			/* ZA state managment is not implemented yet */
+			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
+			return;
+		}
+
+		/* If we are in streaming mode override regular SVE. */
+		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
+			save_sve_regs = true;
+			save_ffr = system_supports_fa64();
+			vl = last->sme_vl;
+		}
 	}
 
-	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
-	    test_thread_flag(TIF_SVE)) {
-		if (WARN_ON(sve_get_vl() != last->sve_vl)) {
+	if (IS_ENABLED(CONFIG_ARM64_SVE) && save_sve_regs) {
+		/* Get the configured VL from RDVL, will account for SM */
+		if (WARN_ON(sve_get_vl() != vl)) {
 			/*
 			 * Can't save the user regs, so current would
 			 * re-enter user with corrupt state.
@@ -407,8 +462,8 @@ static void fpsimd_save(void)
 		}
 
 		sve_save_state((char *)last->sve_state +
-					sve_ffr_offset(last->sve_vl),
-			       &last->st->fpsr, true);
+					sve_ffr_offset(vl),
+			       &last->st->fpsr, save_ffr);
 	} else {
 		fpsimd_save_state(last->st);
 	}
@@ -613,7 +668,14 @@ static void sve_to_fpsimd(struct task_struct *task)
  */
 static size_t sve_state_size(struct task_struct const *task)
 {
-	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(task_get_sve_vl(task)));
+	unsigned int vl = 0;
+
+	if (system_supports_sve())
+		vl = task_get_sve_vl(task);
+	if (system_supports_sme())
+		vl = max(vl, task_get_sme_vl(task));
+
+	return SVE_SIG_REGS_SIZE(sve_vq_from_vl(vl));
 }
 
 /*
@@ -742,7 +804,8 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	}
 
 	fpsimd_flush_task_state(task);
-	if (test_and_clear_tsk_thread_flag(task, TIF_SVE))
+	if (test_and_clear_tsk_thread_flag(task, TIF_SVE) ||
+	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
 	if (system_supports_sme() && type == ARM64_VEC_SME)
@@ -1369,6 +1432,9 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
+	if (system_supports_sme())
+		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1412,6 +1478,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
 	last->sve_vl = task_get_sve_vl(current);
+	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
@@ -1427,7 +1494,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, u64 *svcr)
+			      unsigned int sve_vl, unsigned int sme_vl,
+			      u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1439,6 +1507,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->svcr = svcr;
 	last->sve_state = sve_state;
 	last->sve_vl = sve_vl;
+	last->sme_vl = sme_vl;
 }
 
 /*
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 04698c4bcd30..902c598b7ed2 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -109,7 +109,8 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		 */
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
-					 vcpu->arch.sve_max_vl);
+					 vcpu->arch.sve_max_vl,
+					 0);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:26 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:26 +0000
Subject: [PATCH v10 16/39] arm64/sme: Implement ZA context switching
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-17-broonie@kernel.org>

Allocate space for storing ZA on first access to SME and use that to save
and restore ZA state when context switching. We do this by using the vector
form of the LDR and STR ZA instructions, these do not require streaming
mode and have implementation recommendations that they avoid contention
issues in shared SMCU implementations.

Since ZA is architecturally guaranteed to be zeroed when enabled we do not
need to explicitly zero ZA, either we will be restoring from a saved copy
or trapping on first use of SME so we know that ZA must be disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/fpsimd.h       |  5 ++++-
 arch/arm64/include/asm/fpsimdmacros.h | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/kvm_host.h     |  3 +++
 arch/arm64/include/asm/processor.h    |  1 +
 arch/arm64/kernel/entry-fpsimd.S      | 22 ++++++++++++++++++++++
 arch/arm64/kernel/fpsimd.c            | 20 +++++++++++++-------
 arch/arm64/kvm/fpsimd.c               |  2 +-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 650ec642159c..af404e5b8d82 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -47,7 +47,8 @@ extern void fpsimd_update_current_state(struct user_fpsimd_state const *state);
 
 extern void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *state,
 				     void *sve_state, unsigned int sve_vl,
-				     unsigned int sme_vl, u64 *svcr);
+				     void *za_state, unsigned int sme_vl,
+				     u64 *svcr);
 
 extern void fpsimd_flush_task_state(struct task_struct *target);
 extern void fpsimd_save_and_flush_cpu_state(void);
@@ -90,6 +91,8 @@ extern void sve_flush_live(bool flush_ffr, unsigned long vq_minus_1);
 extern unsigned int sve_get_vl(void);
 extern void sve_set_vq(unsigned long vq_minus_1);
 extern void sme_set_vq(unsigned long vq_minus_1);
+extern void za_save_state(void *state);
+extern void za_load_state(void const *state);
 
 struct arm64_cpu_capabilities;
 extern void sve_kernel_enable(const struct arm64_cpu_capabilities *__unused);
diff --git a/arch/arm64/include/asm/fpsimdmacros.h b/arch/arm64/include/asm/fpsimdmacros.h
index a50fa1eab730..35d67e393519 100644
--- a/arch/arm64/include/asm/fpsimdmacros.h
+++ b/arch/arm64/include/asm/fpsimdmacros.h
@@ -318,3 +318,25 @@
 		ldr		w\nxtmp, [\xpfpsr, #4]
 		msr		fpcr, x\nxtmp
 .endm
+
+.macro sme_save_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_str_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
+
+.macro sme_load_za nxbase, xvl, nw
+	mov	w\nw, #0
+
+423:
+	_sme_ldr_zav \nw, \nxbase
+	add	x\nxbase, x\nxbase, \xvl
+	add	x\nw, x\nw, #1
+	cmp	\xvl, x\nw
+	bne	423b
+.endm
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..7dc85d5a6552 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -280,8 +280,11 @@ struct vcpu_reset_state {
 
 struct kvm_vcpu_arch {
 	struct kvm_cpu_context ctxt;
+
+	/* Guest floating point state */
 	void *sve_state;
 	unsigned int sve_max_vl;
+	u64 svcr;
 
 	/* Stage 2 paging state used by the hardware on next switch */
 	struct kvm_s2_mmu *hw_mmu;
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6e2af9de153c..5a5c5edd76df 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -153,6 +153,7 @@ struct thread_struct {
 
 	unsigned int		fpsimd_cpu;
 	void			*sve_state;	/* SVE registers, if any */
+	void			*za_state;	/* ZA register, if any */
 	unsigned int		vl[ARM64_VEC_MAX];	/* vector length */
 	unsigned int		vl_onexec[ARM64_VEC_MAX]; /* vl after next exec */
 	unsigned long		fault_address;	/* fault info */
diff --git a/arch/arm64/kernel/entry-fpsimd.S b/arch/arm64/kernel/entry-fpsimd.S
index 6f88c0f86d50..229436f33df5 100644
--- a/arch/arm64/kernel/entry-fpsimd.S
+++ b/arch/arm64/kernel/entry-fpsimd.S
@@ -99,4 +99,26 @@ SYM_FUNC_START(sme_set_vq)
 	ret
 SYM_FUNC_END(sme_set_vq)
 
+/*
+ * Save the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_save_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_save_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_save_state)
+
+/*
+ * Load the SME state
+ *
+ * x0 - pointer to buffer for state
+ */
+SYM_FUNC_START(za_load_state)
+	_sme_rdsvl	1, 1		// x1 = VL/8
+	sme_load_za 0, x1, 12
+	ret
+SYM_FUNC_END(za_load_state)
+
 #endif /* CONFIG_ARM64_SME */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 12fef62cf07a..c9e8186e69c0 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -121,6 +121,7 @@
 struct fpsimd_last_state_struct {
 	struct user_fpsimd_state *st;
 	void *sve_state;
+	void *za_state;
 	u64 *svcr;
 	unsigned int sve_vl;
 	unsigned int sme_vl;
@@ -387,11 +388,15 @@ static void task_fpsimd_load(void)
 	if (system_supports_sme()) {
 		unsigned long sme_vl = task_get_sme_vl(current);
 
+		/* Ensure VL is set up for restoring data */
 		if (test_thread_flag(TIF_SME))
 			sme_set_vq(sve_vq_from_vl(sme_vl) - 1);
 
 		write_sysreg_s(current->thread.svcr, SYS_SVCR_EL0);
 
+		if (thread_za_enabled(&current->thread))
+			za_load_state(current->thread.za_state);
+
 		if (thread_sm_enabled(&current->thread)) {
 			restore_sve_regs = true;
 			restore_ffr = system_supports_fa64();
@@ -435,11 +440,10 @@ static void fpsimd_save(void)
 		u64 *svcr = last->svcr;
 		*svcr = read_sysreg_s(SYS_SVCR_EL0);
 
-		if (thread_za_enabled(&current->thread)) {
-			/* ZA state managment is not implemented yet */
-			force_signal_inject(SIGKILL, SI_KERNEL, 0, 0);
-			return;
-		}
+		*svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (*svcr & SYS_SVCR_EL0_ZA_MASK)
+			za_save_state(last->za_state);
 
 		/* If we are in streaming mode override regular SVE. */
 		if (*svcr & SYS_SVCR_EL0_SM_MASK) {
@@ -1477,6 +1481,7 @@ static void fpsimd_bind_task_to_cpu(void)
 	WARN_ON(!system_supports_fpsimd());
 	last->st = &current->thread.uw.fpsimd_state;
 	last->sve_state = current->thread.sve_state;
+	last->za_state = current->thread.za_state;
 	last->sve_vl = task_get_sve_vl(current);
 	last->sme_vl = task_get_sme_vl(current);
 	last->svcr = &current->thread.svcr;
@@ -1494,8 +1499,8 @@ static void fpsimd_bind_task_to_cpu(void)
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
-			      unsigned int sve_vl, unsigned int sme_vl,
-			      u64 *svcr)
+			      unsigned int sve_vl, void *za_state,
+			      unsigned int sme_vl, u64 *svcr)
 {
 	struct fpsimd_last_state_struct *last =
 		this_cpu_ptr(&fpsimd_last_state);
@@ -1506,6 +1511,7 @@ void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
 	last->st = st;
 	last->svcr = svcr;
 	last->sve_state = sve_state;
+	last->za_state = za_state;
 	last->sve_vl = sve_vl;
 	last->sme_vl = sme_vl;
 }
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 902c598b7ed2..338733ac63f8 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -110,7 +110,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
 		fpsimd_bind_state_to_cpu(&vcpu->arch.ctxt.fp_regs,
 					 vcpu->arch.sve_state,
 					 vcpu->arch.sve_max_vl,
-					 0);
+					 NULL, 0, &vcpu->arch.svcr);
 
 		clear_thread_flag(TIF_FOREIGN_FPSTATE);
 		update_thread_flag(TIF_SVE, vcpu_has_sve(vcpu));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:27 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:27 +0000
Subject: [PATCH v10 17/39] arm64/sme: Implement traps and syscall handling for
 SME
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-18-broonie@kernel.org>

By default all SME operations in userspace will trap.  When this happens
we allocate storage space for the SME register state, set up the SVE
registers and disable traps.  We do not need to initialize ZA since the
architecture guarantees that it will be zeroed when enabled and when we
trap ZA is disabled.

On syscall we exit streaming mode if we were previously in it and ensure
that all but the lower 128 bits of the registers are zeroed while
preserving the state of ZA. This follows the aarch64 PCS for SME, ZA
state is preserved over a function call and streaming mode is exited.
Since the traps for SME do not distinguish between streaming mode SVE
and ZA usage if ZA is in use rather than reenabling traps we instead
zero the parts of the SVE registers not shared with FPSIMD and leave SME
enabled, this simplifies handling SME traps. If ZA is not in use then we
reenable SME traps and fall through to normal handling of SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/esr.h       |   1 +
 arch/arm64/include/asm/exception.h |   1 +
 arch/arm64/include/asm/fpsimd.h    |  27 +++++
 arch/arm64/kernel/entry-common.c   |  11 ++
 arch/arm64/kernel/fpsimd.c         | 180 ++++++++++++++++++++++++++---
 arch/arm64/kernel/process.c        |  12 +-
 arch/arm64/kernel/syscall.c        |  34 +++++-
 7 files changed, 242 insertions(+), 24 deletions(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 43872e0cfd1e..0467837fd66b 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -76,6 +76,7 @@
 #define ESR_ELx_IL_SHIFT	(25)
 #define ESR_ELx_IL		(UL(1) << ESR_ELx_IL_SHIFT)
 #define ESR_ELx_ISS_MASK	(ESR_ELx_IL - 1)
+#define ESR_ELx_ISS(esr)	((esr) & ESR_ELx_ISS_MASK)
 
 /* ISS field definitions shared by different classes */
 #define ESR_ELx_WNR_SHIFT	(6)
diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
index 339477dca551..2add7f33b7c2 100644
--- a/arch/arm64/include/asm/exception.h
+++ b/arch/arm64/include/asm/exception.h
@@ -64,6 +64,7 @@ void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr,
 			struct pt_regs *regs);
 void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs);
 void do_sve_acc(unsigned int esr, struct pt_regs *regs);
+void do_sme_acc(unsigned int esr, struct pt_regs *regs);
 void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs);
 void do_sysinstr(unsigned int esr, struct pt_regs *regs);
 void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index af404e5b8d82..3ca152aaf7c9 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -282,6 +282,16 @@ static inline void sve_setup(void) { }
 
 #ifdef CONFIG_ARM64_SME
 
+static inline void sme_user_disable(void)
+{
+	sysreg_clear_set(cpacr_el1, CPACR_EL1_SMEN_EL0EN, 0);
+}
+
+static inline void sme_user_enable(void)
+{
+	sysreg_clear_set(cpacr_el1, 0, CPACR_EL1_SMEN_EL0EN);
+}
+
 static inline void sme_smstart_sm(void)
 {
 	asm volatile(".inst 0xd503437f");
@@ -309,16 +319,33 @@ static inline int sme_max_virtualisable_vl(void)
 	return vec_max_virtualisable_vl(ARM64_VEC_SME);
 }
 
+extern void sme_alloc(struct task_struct *task);
 extern unsigned int sme_get_vl(void);
 extern int sme_set_current_vl(unsigned long arg);
 extern int sme_get_current_vl(void);
 
+/*
+ * Return how many bytes of memory are required to store the full SME
+ * specific state (currently just ZA) for task, given task's currently
+ * configured vector length.
+ */
+static inline size_t za_state_size(struct task_struct const *task)
+{
+	unsigned int vl = task_get_sme_vl(task);
+
+	return ZA_SIG_REGS_SIZE(sve_vq_from_vl(vl));
+}
+
 #else
 
+static inline void sme_user_disable(void) { BUILD_BUG(); }
+static inline void sme_user_enable(void) { BUILD_BUG(); }
+
 static inline void sme_smstart_sm(void) { }
 static inline void sme_smstop_sm(void) { }
 static inline void sme_smstop(void) { }
 
+static inline void sme_alloc(struct task_struct *task) { }
 static inline void sme_setup(void) { }
 static inline unsigned int sme_get_vl(void) { return 0; }
 static inline int sme_max_vl(void) { return 0; }
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index ef7fcefb96bd..b2ad525d6c87 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -524,6 +524,14 @@ static void noinstr el0_sve_acc(struct pt_regs *regs, unsigned long esr)
 	exit_to_user_mode(regs);
 }
 
+static void noinstr el0_sme_acc(struct pt_regs *regs, unsigned long esr)
+{
+	enter_from_user_mode(regs);
+	local_daif_restore(DAIF_PROCCTX);
+	do_sme_acc(esr, regs);
+	exit_to_user_mode(regs);
+}
+
 static void noinstr el0_fpsimd_exc(struct pt_regs *regs, unsigned long esr)
 {
 	enter_from_user_mode(regs);
@@ -632,6 +640,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs)
 	case ESR_ELx_EC_SVE:
 		el0_sve_acc(regs, esr);
 		break;
+	case ESR_ELx_EC_SME:
+		el0_sme_acc(regs, esr);
+		break;
 	case ESR_ELx_EC_FP_EXC64:
 		el0_fpsimd_exc(regs, esr);
 		break;
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index c9e8186e69c0..33f80512753d 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -209,6 +209,12 @@ static void set_sme_default_vl(int val)
 	set_default_vl(ARM64_VEC_SME, val);
 }
 
+static void sme_free(struct task_struct *);
+
+#else
+
+static inline void sme_free(struct task_struct *t) { }
+
 #endif
 
 DEFINE_PER_CPU(bool, fpsimd_context_busy);
@@ -409,6 +415,21 @@ static void task_fpsimd_load(void)
 			       restore_ffr);
 	else
 		fpsimd_load_state(&current->thread.uw.fpsimd_state);
+
+	/*
+	 * If we didn't set up any SVE registers but we do have SME
+	 * enabled for userspace then ensure the SVE registers are
+	 * flushed since userspace can switch to streaming mode and
+	 * view the register state without trapping.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME) &&
+	    !restore_sve_regs) {
+		int sve_vq_minus_one;
+
+		sve_vq_minus_one = sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(sve_vq_minus_one);
+		sve_flush_live(true, sve_vq_minus_one);
+	}
 }
 
 /*
@@ -812,18 +833,22 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	    thread_sm_enabled(&task->thread))
 		sve_to_fpsimd(task);
 
-	if (system_supports_sme() && type == ARM64_VEC_SME)
+	if (system_supports_sme() && type == ARM64_VEC_SME) {
 		task->thread.svcr &= ~(SYS_SVCR_EL0_SM_MASK |
 				       SYS_SVCR_EL0_ZA_MASK);
+		clear_thread_flag(TIF_SME);
+	}
 
 	if (task == current)
 		put_cpu_fpsimd_context();
 
 	/*
-	 * Force reallocation of task SVE state to the correct size
-	 * on next use:
+	 * Force reallocation of task SVE and SME state to the correct
+	 * size on next use:
 	 */
 	sve_free(task);
+	if (system_supports_sme() && type == ARM64_VEC_SME)
+		sme_free(task);
 
 	task_set_vl(task, type, vl);
 
@@ -1158,12 +1183,43 @@ void __init sve_setup(void)
 void fpsimd_release_task(struct task_struct *dead_task)
 {
 	__sve_free(dead_task);
+	sme_free(dead_task);
 }
 
 #endif /* CONFIG_ARM64_SVE */
 
 #ifdef CONFIG_ARM64_SME
 
+/* This will move to uapi/asm/sigcontext.h when signals are implemented */
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+/*
+ * Ensure that task->thread.za_state is allocated and sufficiently large.
+ *
+ * This function should be used only in preparation for replacing
+ * task->thread.za_state with new data.  The memory is always zeroed
+ * here to prevent stale data from showing through: this is done in
+ * the interest of testability and predictability, the architecture
+ * guarantees that when ZA is enabled it will be zeroed.
+ */
+void sme_alloc(struct task_struct *task)
+{
+	if (task->thread.za_state) {
+		memset(task->thread.za_state, 0, za_state_size(task));
+		return;
+	}
+
+	/* This could potentially be up to 64K. */
+	task->thread.za_state =
+		kzalloc(za_state_size(task), GFP_KERNEL);
+}
+
+static void sme_free(struct task_struct *task)
+{
+	kfree(task->thread.za_state);
+	task->thread.za_state = NULL;
+}
+
 void sme_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
 {
 	/* Set priority for all PEs to architecturally defined minimum */
@@ -1273,6 +1329,29 @@ void __init sme_setup(void)
 
 #endif /* CONFIG_ARM64_SME */
 
+static void sve_init_regs(void)
+{
+	/*
+	 * Convert the FPSIMD state to SVE, zeroing all the state that
+	 * is not shared with FPSIMD. If (as is likely) the current
+	 * state is live in the registers then do this there and
+	 * update our metadata for the current task including
+	 * disabling the trap, otherwise update our in-memory copy.
+	 * We are guaranteed to not be in streaming mode, we can only
+	 * take a SVE trap when not in streaming mode and we can't be
+	 * in streaming mode when taking a SME trap.
+	 */
+	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
+		unsigned long vq_minus_one =
+			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
+		sve_set_vq(vq_minus_one);
+		sve_flush_live(true, vq_minus_one);
+		fpsimd_bind_task_to_cpu();
+	} else {
+		fpsimd_to_sve(current);
+	}
+}
+
 /*
  * Trapped SVE access
  *
@@ -1304,22 +1383,77 @@ void do_sve_acc(unsigned int esr, struct pt_regs *regs)
 		WARN_ON(1); /* SVE access shouldn't have trapped */
 
 	/*
-	 * Convert the FPSIMD state to SVE, zeroing all the state that
-	 * is not shared with FPSIMD. If (as is likely) the current
-	 * state is live in the registers then do this there and
-	 * update our metadata for the current task including
-	 * disabling the trap, otherwise update our in-memory copy.
+	 * Even if the task can have used streaming mode we can only
+	 * generate SVE access traps in normal SVE mode and
+	 * transitioning out of streaming mode may discard any
+	 * streaming mode state.  Always clear the high bits to avoid
+	 * any potential errors tracking what is properly initialised.
 	 */
+	sve_init_regs();
+
+	put_cpu_fpsimd_context();
+}
+
+/*
+ * Trapped SME access
+ *
+ * Storage is allocated for the full SVE and SME state, the current
+ * FPSIMD register contents are migrated to SVE if SVE is not already
+ * active, and the access trap is disabled.
+ *
+ * TIF_SME should be clear on entry: otherwise, fpsimd_restore_current_state()
+ * would have disabled the SME access trap for userspace during
+ * ret_to_user, making an SVE access trap impossible in that case.
+ */
+void do_sme_acc(unsigned int esr, struct pt_regs *regs)
+{
+	/* Even if we chose not to use SME, the hardware could still trap: */
+	if (unlikely(!system_supports_sme()) || WARN_ON(is_compat_task())) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	/*
+	 * If this not a trap due to SME being disabled then something
+	 * is being used in the wrong mode, report as SIGILL.
+	 */
+	if (ESR_ELx_ISS(esr) != ESR_ELx_SME_ISS_SME_DISABLED) {
+		force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0);
+		return;
+	}
+
+	sve_alloc(current);
+	sme_alloc(current);
+	if (!current->thread.sve_state || !current->thread.za_state) {
+		force_sig(SIGKILL);
+		return;
+	}
+
+	get_cpu_fpsimd_context();
+
+	/* With TIF_SME userspace shouldn't generate any traps */
+	if (test_and_set_thread_flag(TIF_SME))
+		WARN_ON(1);
+
 	if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {
 		unsigned long vq_minus_one =
-			sve_vq_from_vl(task_get_sve_vl(current)) - 1;
-		sve_set_vq(vq_minus_one);
-		sve_flush_live(true, vq_minus_one);
+			sve_vq_from_vl(task_get_sme_vl(current)) - 1;
+		sme_set_vq(vq_minus_one);
+
 		fpsimd_bind_task_to_cpu();
-	} else {
-		fpsimd_to_sve(current);
 	}
 
+	/*
+	 * If SVE was not already active initialise the SVE registers,
+	 * any non-shared state between the streaming and regular SVE
+	 * registers is architecturally guaranteed to be zeroed when
+	 * we enter streaming mode.  We do not need to initialize ZA
+	 * since ZA must be disabled at this point and enabling ZA is
+	 * architecturally defined to zero ZA.
+	 */
+	if (system_supports_sve() && !test_thread_flag(TIF_SVE))
+		sve_init_regs();
+
 	put_cpu_fpsimd_context();
 }
 
@@ -1436,8 +1570,11 @@ void fpsimd_flush_thread(void)
 		fpsimd_flush_thread_vl(ARM64_VEC_SVE);
 	}
 
-	if (system_supports_sme())
+	if (system_supports_sme()) {
+		clear_thread_flag(TIF_SME);
+		sme_free(current);
 		fpsimd_flush_thread_vl(ARM64_VEC_SME);
+	}
 
 	put_cpu_fpsimd_context();
 }
@@ -1487,15 +1624,24 @@ static void fpsimd_bind_task_to_cpu(void)
 	last->svcr = &current->thread.svcr;
 	current->thread.fpsimd_cpu = smp_processor_id();
 
+	/*
+	 * Toggle SVE and SME trapping for userspace if needed, these
+	 * are serialsied by ret_to_user().
+	 */
+	if (system_supports_sme()) {
+		if (test_thread_flag(TIF_SME))
+			sme_user_enable();
+		else
+			sme_user_disable();
+	}
+
 	if (system_supports_sve()) {
-		/* Toggle SVE trapping for userspace if needed */
 		if (test_thread_flag(TIF_SVE))
 			sve_user_enable();
 		else
 			sve_user_disable();
-
-		/* Serialised by exception return to user */
 	}
+
 }
 
 void fpsimd_bind_state_to_cpu(struct user_fpsimd_state *st, void *sve_state,
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index f2d32a29641c..f7fcc625ea0e 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -299,17 +299,19 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 	BUILD_BUG_ON(!IS_ENABLED(CONFIG_THREAD_INFO_IN_TASK));
 
 	/*
-	 * Detach src's sve_state (if any) from dst so that it does not
-	 * get erroneously used or freed prematurely.  dst's sve_state
-	 * will be allocated on demand later on if dst uses SVE.
-	 * For consistency, also clear TIF_SVE here: this could be done
+	 * Detach src's sve/za_state (if any) from dst so that it does not
+	 * get erroneously used or freed prematurely.  dst's copies
+	 * will be allocated on demand later on if dst uses SVE/SME.
+	 * For consistency, also clear TIF_SVE/SME here: this could be done
 	 * later in copy_process(), but to avoid tripping up future
-	 * maintainers it is best not to leave TIF_SVE and sve_state in
+	 * maintainers it is best not to leave TIF flags and buffers in
 	 * an inconsistent state, even temporarily.
 	 */
 	dst->thread.sve_state = NULL;
 	clear_tsk_thread_flag(dst, TIF_SVE);
 
+	dst->thread.za_state = NULL;
+	clear_tsk_thread_flag(dst, TIF_SME);
 	dst->thread.svcr = 0;
 
 	/* clear any pending asynchronous tag fault raised by the parent */
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index c938603b3ba0..958b2d926354 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -158,11 +158,41 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
 	syscall_trace_exit(regs);
 }
 
-static inline void sve_user_discard(void)
+/*
+ * As per the ABI exit SME streaming mode and clear the SVE state not
+ * shared with FPSIMD on syscall entry.
+ */
+static inline void fp_user_discard(void)
 {
+	/*
+	 * If SME is active then exit streaming mode.  If ZA is active
+	 * then flush the SVE registers but leave userspace access to
+	 * both SVE and SME enabled, otherwise disable SME for the
+	 * task and fall through to disabling SVE too.  This means
+	 * that after a syscall we never have any SME register state
+	 * to track, if this changes the KVM code will need updating.
+	 */
+	if (system_supports_sme() && test_thread_flag(TIF_SME)) {
+		u64 svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+		if (svcr & SYS_SVCR_EL0_SM_MASK)
+			sme_smstop_sm();
+
+		if (!(svcr & SYS_SVCR_EL0_ZA_MASK)) {
+			clear_thread_flag(TIF_SME);
+			sme_user_disable();
+		}
+	}
+
+
 	if (!system_supports_sve())
 		return;
 
+	/*
+	 * If SME is not active then disable SVE, the registers will
+	 * be cleared when userspace next attempts to access them and
+	 * we do not need to track the SVE register state until then.
+	 */
 	clear_thread_flag(TIF_SVE);
 
 	/*
@@ -177,7 +207,7 @@ static inline void sve_user_discard(void)
 
 void do_el0_svc(struct pt_regs *regs)
 {
-	sve_user_discard();
+	fp_user_discard();
 	el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table);
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:28 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:28 +0000
Subject: [PATCH v10 18/39] arm64/sme: Disable ZA and streaming mode when
 handling signals
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-19-broonie@kernel.org>

The ABI requires that streaming mode and ZA are disabled when invoking
signal handlers, do this in setup_return() when we prepare the task state
for the signal handler.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/signal.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index d8aaf4b6f432..cda04fd73333 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -758,6 +758,13 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 	/* TCO (Tag Check Override) always cleared for signal handlers */
 	regs->pstate &= ~PSR_TCO_BIT;
 
+	/* Signal handlers are invoked with ZA and streaming mode disabled */
+	if (system_supports_sme()) {
+		current->thread.svcr &= ~(SYS_SVCR_EL0_ZA_MASK |
+					  SYS_SVCR_EL0_SM_MASK);
+		sme_smstop();
+	}
+
 	if (ka->sa.sa_flags & SA_RESTORER)
 		sigtramp = ka->sa.sa_restorer;
 	else
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:29 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:29 +0000
Subject: [PATCH v10 19/39] arm64/sme: Implement streaming SVE signal handling
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-20-broonie@kernel.org>

When in streaming mode we have the same set of SVE registers as we do in
regular SVE mode with the exception of FFR and the use of the SME vector
length. Provide signal handling for these registers by taking one of the
reserved words in the SVE signal context as a flags field and defining a
flag with a flag which is set for streaming mode. When the flag is set the
vector length is set to the streaming mode vector length and we save and
restore streaming mode data. We support entering or leaving streaming mode
based on the value of the flag but do not support changing the vector
length, this is not currently supported SVE signal handling.

We could instead allocate a separate record in the signal frame for the
streaming mode SVE context but this inflates the size of the maximal signal
frame required and adds complication when validating signal frames from
userspace, especially given the current structure of the code.

Any implementation of support for streaming mode vectors in signals will
have some potential for causing issues for applications that attempt to
handle SVE vectors in signals, use streaming mode but do not understand
streaming mode in their signal handling code, it is hard to identify a
case that is clearly better than any other - they all have cases where
they could cause unexpected register corruption or faults.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h | 16 ++++++--
 arch/arm64/kernel/signal.c               | 48 ++++++++++++++++++------
 2 files changed, 50 insertions(+), 14 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 0c796c795dbe..3a3366d4fbc2 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -134,9 +134,12 @@ struct extra_context {
 struct sve_context {
 	struct _aarch64_ctx head;
 	__u16 vl;
-	__u16 __reserved[3];
+	__u16 flags;
+	__u16 __reserved[2];
 };
 
+#define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -186,9 +189,16 @@ struct sve_context {
  * sve_context.vl must equal the thread's current vector length when
  * doing a sigreturn.
  *
+ * On systems with support for SME the SVE register state may reflect either
+ * streaming or non-streaming mode.  In streaming mode the streaming mode
+ * vector length will be used and the flag SVE_SIG_FLAG_SM will be set in
+ * the flags field. It is permitted to enter or leave streaming mode in
+ * a signal return, applications should take care to ensure that any difference
+ * in vector length between the two modes is handled, including any resixing
+ * and movement of context blocks.
  *
- * Note: for all these macros, the "vq" argument denotes the SVE
- * vector length in quadwords (i.e., units of 128 bits).
+ * Note: for all these macros, the "vq" argument denotes the vector length
+ * in quadwords (i.e., units of 128 bits).
  *
  * The correct way to obtain vq is to use sve_vq_from_vl(vl).  The
  * result is valid if and only if sve_vl_valid(vl) is true.  This is
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index cda04fd73333..5e6ec6ed8a1c 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -227,11 +227,17 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 {
 	int err = 0;
 	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	u16 flags = 0;
 	unsigned int vl = task_get_sve_vl(current);
 	unsigned int vq = 0;
 
-	if (test_thread_flag(TIF_SVE))
+	if (thread_sm_enabled(&current->thread)) {
+		vl = task_get_sme_vl(current);
 		vq = sve_vq_from_vl(vl);
+		flags |= SVE_SIG_FLAG_SM;
+	} else if (test_thread_flag(TIF_SVE)) {
+		vq = sve_vq_from_vl(vl);
+	}
 
 	memset(reserved, 0, sizeof(reserved));
 
@@ -239,6 +245,7 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
 			 &ctx->head.size, err);
 	__put_user_error(vl, &ctx->vl, err);
+	__put_user_error(flags, &ctx->flags, err);
 	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
 	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
 
@@ -259,18 +266,28 @@ static int preserve_sve_context(struct sve_context __user *ctx)
 static int restore_sve_fpsimd_context(struct user_ctxs *user)
 {
 	int err;
-	unsigned int vq;
+	unsigned int vl, vq;
 	struct user_fpsimd_state fpsimd;
 	struct sve_context sve;
 
 	if (__copy_from_user(&sve, user->sve, sizeof(sve)))
 		return -EFAULT;
 
-	if (sve.vl != task_get_sve_vl(current))
+	if (sve.flags & SVE_SIG_FLAG_SM) {
+		if (!system_supports_sme())
+			return -EINVAL;
+
+		vl = task_get_sme_vl(current);
+	} else {
+		vl = task_get_sve_vl(current);
+	}
+
+	if (sve.vl != vl)
 		return -EINVAL;
 
 	if (sve.head.size <= sizeof(*user->sve)) {
 		clear_thread_flag(TIF_SVE);
+		current->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
 		goto fpsimd_only;
 	}
 
@@ -302,7 +319,10 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user)
 	if (err)
 		return -EFAULT;
 
-	set_thread_flag(TIF_SVE);
+	if (sve.flags & SVE_SIG_FLAG_SM)
+		current->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+	else
+		set_thread_flag(TIF_SVE);
 
 fpsimd_only:
 	/* copy the FP and status/control registers */
@@ -394,7 +414,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			break;
 
 		case SVE_MAGIC:
-			if (!system_supports_sve())
+			if (!system_supports_sve() && !system_supports_sme())
 				goto invalid;
 
 			if (user->sve)
@@ -593,11 +613,16 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 	if (system_supports_sve()) {
 		unsigned int vq = 0;
 
-		if (add_all || test_thread_flag(TIF_SVE)) {
-			int vl = sve_max_vl();
+		if (add_all || test_thread_flag(TIF_SVE) ||
+		    thread_sm_enabled(&current->thread)) {
+			int vl = max(sve_max_vl(), sme_max_vl());
 
-			if (!add_all)
-				vl = task_get_sve_vl(current);
+			if (!add_all) {
+				if (thread_sm_enabled(&current->thread))
+					vl = task_get_sme_vl(current);
+				else
+					vl = task_get_sve_vl(current);
+			}
 
 			vq = sve_vq_from_vl(vl);
 		}
@@ -648,8 +673,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);
 	}
 
-	/* Scalable Vector Extension state, if present */
-	if (system_supports_sve() && err == 0 && user->sve_offset) {
+	/* Scalable Vector Extension state (including streaming), if present */
+	if ((system_supports_sve() || system_supports_sme()) &&
+	    err == 0 && user->sve_offset) {
 		struct sve_context __user *sve_ctx =
 			apply_user_offset(user, user->sve_offset);
 		err |= preserve_sve_context(sve_ctx);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:30 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:30 +0000
Subject: [PATCH v10 20/39] arm64/sme: Implement ZA signal handling
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-21-broonie@kernel.org>

Implement support for ZA in signal handling in a very similar way to how
we implement support for SVE registers, using a signal context structure
with optional register state after it. Where present this register state
stores the ZA matrix as a series of horizontal vectors numbered from 0 to
VL/8 in the endinanness independent format used for vectors.

As with SVE we do not allow changes in the vector length during signal
return but we do allow ZA to be enabled or disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/sigcontext.h |  41 +++++++
 arch/arm64/kernel/fpsimd.c               |   3 -
 arch/arm64/kernel/signal.c               | 139 +++++++++++++++++++++++
 3 files changed, 180 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/sigcontext.h b/arch/arm64/include/uapi/asm/sigcontext.h
index 3a3366d4fbc2..d45bdf2c8b26 100644
--- a/arch/arm64/include/uapi/asm/sigcontext.h
+++ b/arch/arm64/include/uapi/asm/sigcontext.h
@@ -140,6 +140,14 @@ struct sve_context {
 
 #define SVE_SIG_FLAG_SM	0x1	/* Context describes streaming mode */
 
+#define ZA_MAGIC	0x54366345
+
+struct za_context {
+	struct _aarch64_ctx head;
+	__u16 vl;
+	__u16 __reserved[3];
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #include <asm/sve_context.h>
@@ -259,4 +267,37 @@ struct sve_context {
 #define SVE_SIG_CONTEXT_SIZE(vq) \
 		(SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
 
+/*
+ * If the ZA register is enabled for the thread at signal delivery then,
+ * za_context.head.size >= ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * and the register data may be accessed using the ZA_SIG_*() macros.
+ *
+ * If za_context.head.size < ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za_context.vl))
+ * then ZA was not enabled and no register data was included in which case
+ * ZA register was not enabled for the thread and no register data
+ * the ZA_SIG_*() macros should not be used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the za_context block if it wants to
+ * enable the ZA register when it was previously non-live or vice-versa.
+ * This may require the caller to allocate fresh memory and/or move other
+ * context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * za_context.vl must equal the thread's current SME vector length when
+ * doing a sigreturn.
+ */
+
+#define ZA_SIG_REGS_OFFSET					\
+	((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \
+				  (SVE_SIG_ZREG_SIZE(vq) * n))
+
+#define ZA_SIG_CONTEXT_SIZE(vq) \
+		(ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
+
 #endif /* _UAPI__ASM_SIGCONTEXT_H */
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 33f80512753d..2242c14a5a05 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1190,9 +1190,6 @@ void fpsimd_release_task(struct task_struct *dead_task)
 
 #ifdef CONFIG_ARM64_SME
 
-/* This will move to uapi/asm/sigcontext.h when signals are implemented */
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
-
 /*
  * Ensure that task->thread.za_state is allocated and sufficiently large.
  *
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 5e6ec6ed8a1c..8efa78765cad 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -57,6 +57,7 @@ struct rt_sigframe_user_layout {
 	unsigned long fpsimd_offset;
 	unsigned long esr_offset;
 	unsigned long sve_offset;
+	unsigned long za_offset;
 	unsigned long extra_offset;
 	unsigned long end_offset;
 };
@@ -219,6 +220,7 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 struct user_ctxs {
 	struct fpsimd_context __user *fpsimd;
 	struct sve_context __user *sve;
+	struct za_context __user *za;
 };
 
 #ifdef CONFIG_ARM64_SVE
@@ -347,6 +349,101 @@ extern int restore_sve_fpsimd_context(struct user_ctxs *user);
 
 #endif /* ! CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int preserve_za_context(struct za_context __user *ctx)
+{
+	int err = 0;
+	u16 reserved[ARRAY_SIZE(ctx->__reserved)];
+	unsigned int vl = task_get_sme_vl(current);
+	unsigned int vq;
+
+	if (thread_za_enabled(&current->thread))
+		vq = sve_vq_from_vl(vl);
+	else
+		vq = 0;
+
+	memset(reserved, 0, sizeof(reserved));
+
+	__put_user_error(ZA_MAGIC, &ctx->head.magic, err);
+	__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),
+			 &ctx->head.size, err);
+	__put_user_error(vl, &ctx->vl, err);
+	BUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));
+	err |= __copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));
+
+	if (vq) {
+		/*
+		 * This assumes that the ZA state has already been saved to
+		 * the task struct by calling the function
+		 * fpsimd_signal_preserve_current_state().
+		 */
+		err |= __copy_to_user((char __user *)ctx + ZA_SIG_REGS_OFFSET,
+				      current->thread.za_state,
+				      ZA_SIG_REGS_SIZE(vq));
+	}
+
+	return err ? -EFAULT : 0;
+}
+
+static int restore_za_context(struct user_ctxs __user *user)
+{
+	int err;
+	unsigned int vq;
+	struct za_context za;
+
+	if (__copy_from_user(&za, user->za, sizeof(za)))
+		return -EFAULT;
+
+	if (za.vl != task_get_sme_vl(current))
+		return -EINVAL;
+
+	if (za.head.size <= sizeof(*user->za)) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		return 0;
+	}
+
+	vq = sve_vq_from_vl(za.vl);
+
+	if (za.head.size < ZA_SIG_CONTEXT_SIZE(vq))
+		return -EINVAL;
+
+	/*
+	 * Careful: we are about __copy_from_user() directly into
+	 * thread.za_state with preemption enabled, so protection is
+	 * needed to prevent a racing context switch from writing stale
+	 * registers back over the new data.
+	 */
+
+	fpsimd_flush_task_state(current);
+	/* From now, fpsimd_thread_switch() won't touch thread.sve_state */
+
+	sme_alloc(current);
+	if (!current->thread.za_state) {
+		current->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		clear_thread_flag(TIF_SME);
+		return -ENOMEM;
+	}
+
+	err = __copy_from_user(current->thread.za_state,
+			       (char __user const *)user->za +
+					ZA_SIG_REGS_OFFSET,
+			       ZA_SIG_REGS_SIZE(vq));
+	if (err)
+		return -EFAULT;
+
+	set_thread_flag(TIF_SME);
+	current->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+	return 0;
+}
+#else /* ! CONFIG_ARM64_SME */
+
+/* Turn any non-optimised out attempts to use these into a link error: */
+extern int preserve_za_context(void __user *ctx);
+extern int restore_za_context(struct user_ctxs *user);
+
+#endif /* ! CONFIG_ARM64_SME */
 
 static int parse_user_sigframe(struct user_ctxs *user,
 			       struct rt_sigframe __user *sf)
@@ -361,6 +458,7 @@ static int parse_user_sigframe(struct user_ctxs *user,
 
 	user->fpsimd = NULL;
 	user->sve = NULL;
+	user->za = NULL;
 
 	if (!IS_ALIGNED((unsigned long)base, 16))
 		goto invalid;
@@ -426,6 +524,19 @@ static int parse_user_sigframe(struct user_ctxs *user,
 			user->sve = (struct sve_context __user *)head;
 			break;
 
+		case ZA_MAGIC:
+			if (!system_supports_sme())
+				goto invalid;
+
+			if (user->za)
+				goto invalid;
+
+			if (size < sizeof(*user->za))
+				goto invalid;
+
+			user->za = (struct za_context __user *)head;
+			break;
+
 		case EXTRA_MAGIC:
 			if (have_extra_context)
 				goto invalid;
@@ -549,6 +660,9 @@ static int restore_sigframe(struct pt_regs *regs,
 		}
 	}
 
+	if (err == 0 && system_supports_sme() && user.za)
+		err = restore_za_context(&user);
+
 	return err;
 }
 
@@ -633,6 +747,24 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user,
 			return err;
 	}
 
+	if (system_supports_sme()) {
+		unsigned int vl;
+		unsigned int vq = 0;
+
+		if (add_all)
+			vl = sme_max_vl();
+		else
+			vl = task_get_sme_vl(current);
+
+		if (thread_za_enabled(&current->thread))
+			vq = sve_vq_from_vl(vl);
+
+		err = sigframe_alloc(user, &user->za_offset,
+				     ZA_SIG_CONTEXT_SIZE(vq));
+		if (err)
+			return err;
+	}
+
 	return sigframe_alloc_end(user);
 }
 
@@ -681,6 +813,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,
 		err |= preserve_sve_context(sve_ctx);
 	}
 
+	/* ZA state if present */
+	if (system_supports_sme() && err == 0 && user->za_offset) {
+		struct za_context __user *za_ctx =
+			apply_user_offset(user, user->za_offset);
+		err |= preserve_za_context(za_ctx);
+	}
+
 	if (err == 0 && user->extra_offset) {
 		char __user *sfp = (char __user *)user->sigframe;
 		char __user *userp =
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:32 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:32 +0000
Subject: [PATCH v10 22/39] arm64/sme: Add ptrace support for ZA
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-23-broonie@kernel.org>

The ZA array can be read and written with the NT_ARM_ZA.  Similarly to
our interface for the SVE vector registers the regset consists of a
header with information on the current vector length followed by an
optional register data payload, represented as for signals as a series
of horizontal vectors from 0 to VL/8 in the endianness independent
format used for vectors.

On get if ZA is enabled then register data will be provided, otherwise
it will be omitted.  On set if register data is provided then ZA is
enabled and initialized using the provided data, otherwise it is
disabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  56 +++++++++++
 arch/arm64/kernel/ptrace.c           | 144 +++++++++++++++++++++++++++
 include/uapi/linux/elf.h             |   1 +
 3 files changed, 201 insertions(+)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 522b925a78c1..7fa2f7036aa7 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -268,6 +268,62 @@ struct user_pac_generic_keys {
 	__uint128_t	apgakey;
 };
 
+/* ZA state (NT_ARM_ZA) */
+
+struct user_za_header {
+	__u32 size; /* total meaningful regset content in bytes */
+	__u32 max_size; /* maxmium possible size for this thread */
+	__u16 vl; /* current vector length */
+	__u16 max_vl; /* maximum possible vector length */
+	__u16 flags;
+	__u16 __reserved;
+};
+
+/*
+ * Common ZA_PT_* flags:
+ * These must be kept in sync with prctl interface in <linux/prctl.h>
+ */
+#define ZA_PT_VL_INHERIT		((1 << 17) /* PR_SME_VL_INHERIT */ >> 16)
+#define ZA_PT_VL_ONEXEC			((1 << 18) /* PR_SME_SET_VL_ONEXEC */ >> 16)
+
+
+/*
+ * The remainder of the ZA state follows struct user_za_header.  The
+ * total size of the ZA state (including header) depends on the
+ * metadata in the header:  ZA_PT_SIZE(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_za_header to the register data */
+#define ZA_PT_ZA_OFFSET						\
+	((sizeof(struct user_za_header) + (__SVE_VQ_BYTES - 1))	\
+		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
+
+/*
+ * The payload starts at offset ZA_PT_ZA_OFFSET, and is of size
+ * ZA_PT_ZA_SIZE(vq, flags).
+ *
+ * The ZA array is stored as a sequence of horizontal vectors ZAV of SVL/8
+ * bytes each, starting from vector 0.
+ *
+ * Additional data might be appended in the future.
+ *
+ * The ZA matrix is represented in memory in an endianness-invariant layout
+ * which differs from the layout used for the FPSIMD V-registers on big-endian
+ * systems: see sigcontext.h for more explanation.
+ */
+
+#define ZA_PT_ZAV_OFFSET(vq, n) \
+	(ZA_PT_ZA_OFFSET + ((vq * __SVE_VQ_BYTES) * n))
+
+#define ZA_PT_ZA_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+
+#define ZA_PT_SIZE(vq)						\
+	(ZA_PT_ZA_OFFSET + ZA_PT_ZA_SIZE(vq))
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _UAPI__ASM_PTRACE_H */
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 0b8324fa1abc..d6f27d3bf6e7 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -996,6 +996,141 @@ static int ssve_set(struct task_struct *target,
 			      ARM64_VEC_SME);
 }
 
+static int za_get(struct task_struct *target,
+		  const struct user_regset *regset,
+		  struct membuf to)
+{
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	memset(&header, 0, sizeof(header));
+
+	if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+		header.flags |= ZA_PT_VL_INHERIT;
+
+	header.vl = task_get_sme_vl(target);
+	vq = sve_vq_from_vl(header.vl);
+	header.max_vl = sme_max_vl();
+	header.max_size = ZA_PT_SIZE(vq);
+
+	/* If ZA is not active there is only the header */
+	if (thread_za_enabled(&target->thread))
+		header.size = ZA_PT_SIZE(vq);
+	else
+		header.size = ZA_PT_ZA_OFFSET;
+
+	membuf_write(&to, &header, sizeof(header));
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	end = ZA_PT_ZA_OFFSET;
+;
+	if (target == current)
+		fpsimd_preserve_current_state();
+
+	/* Any register data to include? */
+	if (thread_za_enabled(&target->thread)) {
+		start = end;
+		end = ZA_PT_SIZE(vq);
+		membuf_write(&to, target->thread.za_state, end - start);
+	}
+
+	/* Zero any trailing padding */
+	start = end;
+	end = ALIGN(header.size, SVE_VQ_BYTES);
+	return membuf_zero(&to, end - start);
+}
+
+static int za_set(struct task_struct *target,
+		  const struct user_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct user_za_header header;
+	unsigned int vq;
+	unsigned long start, end;
+
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	/* Header */
+	if (count < sizeof(header))
+		return -EINVAL;
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &header,
+				 0, sizeof(header));
+	if (ret)
+		goto out;
+
+	/*
+	 * All current ZA_PT_* flags are consumed by
+	 * vec_set_vector_length(), which will also validate them for
+	 * us:
+	 */
+	ret = vec_set_vector_length(target, ARM64_VEC_SME, header.vl,
+		((unsigned long)header.flags) << 16);
+	if (ret)
+		goto out;
+
+	/* Actual VL set may be less than the user asked for: */
+	vq = sve_vq_from_vl(task_get_sme_vl(target));
+
+	/* Ensure there is some SVE storage for streaming mode */
+	if (!target->thread.sve_state) {
+		sve_alloc(target);
+		if (!target->thread.sve_state) {
+			clear_thread_flag(TIF_SME);
+			ret = -ENOMEM;
+			goto out;
+		}
+	}
+
+	/* Allocate/reinit ZA storage */
+	sme_alloc(target);
+	if (!target->thread.za_state) {
+		ret = -ENOMEM;
+		clear_tsk_thread_flag(target, TIF_SME);
+		goto out;
+	}
+
+	/* If there is no data then disable ZA */
+	if (!count) {
+		target->thread.svcr &= ~SYS_SVCR_EL0_ZA_MASK;
+		goto out;
+	}
+
+	/*
+	 * If setting a different VL from the requested VL and there is
+	 * register data, the data layout will be wrong: don't even
+	 * try to set the registers in this case.
+	 */
+	if (vq != sve_vq_from_vl(header.vl)) {
+		ret = -EIO;
+		goto out;
+	}
+
+	BUILD_BUG_ON(ZA_PT_ZA_OFFSET != sizeof(header));
+	start = ZA_PT_ZA_OFFSET;
+	end = ZA_PT_SIZE(vq);
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 target->thread.za_state,
+				 start, end);
+	if (ret)
+		goto out;
+
+	/* Mark ZA as active and let userspace use it */
+	set_tsk_thread_flag(target, TIF_SME);
+	target->thread.svcr |= SYS_SVCR_EL0_ZA_MASK;
+
+out:
+	fpsimd_flush_task_state(target);
+	return ret;
+}
+
 #endif /* CONFIG_ARM64_SME */
 
 #ifdef CONFIG_ARM64_PTR_AUTH
@@ -1217,6 +1352,7 @@ enum aarch64_regset {
 #endif
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SSVE,
+	REGSET_ZA,
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
@@ -1308,6 +1444,14 @@ static const struct user_regset aarch64_regsets[] = {
 		.regset_get = ssve_get,
 		.set = ssve_set,
 	},
+	[REGSET_ZA] = { /* SME ZA */
+		.core_note_type = NT_ARM_ZA,
+		.n = DIV_ROUND_UP(ZA_PT_ZA_SIZE(SVE_VQ_MAX), SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = za_get,
+		.set = za_set,
+	},
 #endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61502388683f..7ef574f3256a 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -428,6 +428,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
 #define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
+#define NT_ARM_ZA	0x40c		/* ARM SME ZA registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:31 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:31 +0000
Subject: [PATCH v10 21/39] arm64/sme: Implement ptrace support for streaming
 mode SVE registers
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-22-broonie@kernel.org>

The streaming mode SVE registers are represented using the same data
structures as for SVE but since the vector lengths supported and in use
may not be the same as SVE we represent them with a new type NT_ARM_SSVE.
Unfortunately we only have a single 16 bit reserved field available in
the header so there is no space to fit the current and maximum vector
length for both standard and streaming SVE mode without redefining the
structure in a way the creates a complicatd and fragile ABI. Since FFR
is not present in streaming mode it is read and written as zero.

Setting NT_ARM_SSVE registers will put the task into streaming mode,
similarly setting NT_ARM_SVE registers will exit it. Reads that do not
correspond to the current mode of the task will return the header with
no register data. For compatibility reasons on write setting no flag for
the register type will be interpreted as setting SVE registers, though
users can provide no register data as an alternative mechanism for doing
so.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/uapi/asm/ptrace.h |  13 +-
 arch/arm64/kernel/fpsimd.c           |  21 ++-
 arch/arm64/kernel/ptrace.c           | 212 +++++++++++++++++++++------
 include/uapi/linux/elf.h             |   1 +
 4 files changed, 190 insertions(+), 57 deletions(-)

diff --git a/arch/arm64/include/uapi/asm/ptrace.h b/arch/arm64/include/uapi/asm/ptrace.h
index 758ae984ff97..522b925a78c1 100644
--- a/arch/arm64/include/uapi/asm/ptrace.h
+++ b/arch/arm64/include/uapi/asm/ptrace.h
@@ -109,7 +109,7 @@ struct user_hwdebug_state {
 	}		dbg_regs[16];
 };
 
-/* SVE/FP/SIMD state (NT_ARM_SVE) */
+/* SVE/FP/SIMD state (NT_ARM_SVE & NT_ARM_SSVE) */
 
 struct user_sve_header {
 	__u32 size; /* total meaningful regset content in bytes */
@@ -220,6 +220,7 @@ struct user_sve_header {
 	(SVE_PT_SVE_PREG_OFFSET(vq, __SVE_NUM_PREGS) - \
 		SVE_PT_SVE_PREGS_OFFSET(vq))
 
+/* For streaming mode SVE (SSVE) FFR must be read and written as zero */
 #define SVE_PT_SVE_FFR_OFFSET(vq) \
 	(SVE_PT_REGS_OFFSET + __SVE_FFR_OFFSET(vq))
 
@@ -240,10 +241,12 @@ struct user_sve_header {
 			- SVE_PT_SVE_OFFSET + (__SVE_VQ_BYTES - 1))	\
 		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
-#define SVE_PT_SIZE(vq, flags)						\
-	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		\
-		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	\
-		: SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
+#define SVE_PT_SIZE(vq, flags)						  \
+	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		  \
+		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	  \
+		: ((((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD ?  \
+		    SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags) \
+		  : SVE_PT_REGS_OFFSET)))
 
 /* pointer authentication masks (NT_ARM_PAC_MASK) */
 
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 2242c14a5a05..8b111b7f2006 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -645,14 +645,19 @@ static void __fpsimd_to_sve(void *sst, struct user_fpsimd_state const *fst,
  */
 static void fpsimd_to_sve(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void *sst = task->thread.sve_state;
 	struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state;
 
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	__fpsimd_to_sve(sst, fst, vq);
 }
 
@@ -669,7 +674,7 @@ static void fpsimd_to_sve(struct task_struct *task)
  */
 static void sve_to_fpsimd(struct task_struct *task)
 {
-	unsigned int vq;
+	unsigned int vq, vl;
 	void const *sst = task->thread.sve_state;
 	struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state;
 	unsigned int i;
@@ -678,7 +683,12 @@ static void sve_to_fpsimd(struct task_struct *task)
 	if (!system_supports_sve())
 		return;
 
-	vq = sve_vq_from_vl(task_get_sve_vl(task));
+	if (thread_sm_enabled(&task->thread))
+		vl = task_get_sme_vl(task);
+	else
+		vl = task_get_sve_vl(task);
+
+	vq = sve_vq_from_vl(vl);
 	for (i = 0; i < SVE_NUM_ZREGS; ++i) {
 		p = (__uint128_t const *)ZREG(sst, vq, i);
 		fst->vregs[i] = arm64_le128_to_cpu(*p);
@@ -819,8 +829,7 @@ int vec_set_vector_length(struct task_struct *task, enum vec_type type,
 	/*
 	 * To ensure the FPSIMD bits of the SVE vector registers are preserved,
 	 * write any live register state back to task_struct, and convert to a
-	 * regular FPSIMD thread.  Since the vector length can only be changed
-	 * with a syscall we can't be in streaming mode while reconfiguring.
+	 * regular FPSIMD thread.
 	 */
 	if (task == current) {
 		get_cpu_fpsimd_context();
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 39dbdfdc38d3..0b8324fa1abc 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -714,21 +714,51 @@ static int system_call_set(struct task_struct *target,
 #ifdef CONFIG_ARM64_SVE
 
 static void sve_init_header_from_task(struct user_sve_header *header,
-				      struct task_struct *target)
+				      struct task_struct *target,
+				      enum vec_type type)
 {
 	unsigned int vq;
+	bool active;
+	bool fpsimd_only;
+	enum vec_type task_type;
 
 	memset(header, 0, sizeof(*header));
 
-	header->flags = test_tsk_thread_flag(target, TIF_SVE) ?
-		SVE_PT_REGS_SVE : SVE_PT_REGS_FPSIMD;
-	if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
-		header->flags |= SVE_PT_VL_INHERIT;
+	/* Check if the requested registers are active for the task */
+	if (thread_sm_enabled(&target->thread))
+		task_type = ARM64_VEC_SME;
+	else
+		task_type = ARM64_VEC_SVE;
+	active = (task_type == type);
+
+	switch (type) {
+	case ARM64_VEC_SVE:
+		if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE);
+		break;
+	case ARM64_VEC_SME:
+		if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
+			header->flags |= SVE_PT_VL_INHERIT;
+		fpsimd_only = false;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return;
+	}
 
-	header->vl = task_get_sve_vl(target);
+	if (active) {
+		if (fpsimd_only) {
+			header->flags |= SVE_PT_REGS_FPSIMD;
+		} else {
+			header->flags |= SVE_PT_REGS_SVE;
+		}
+	}
+
+	header->vl = task_get_vl(target, type);
 	vq = sve_vq_from_vl(header->vl);
 
-	header->max_vl = sve_max_vl();
+	header->max_vl = vec_max_vl(type);
 	header->size = SVE_PT_SIZE(vq, header->flags);
 	header->max_size = SVE_PT_SIZE(sve_vq_from_vl(header->max_vl),
 				      SVE_PT_REGS_SVE);
@@ -739,19 +769,17 @@ static unsigned int sve_size_from_header(struct user_sve_header const *header)
 	return ALIGN(header->size, SVE_VQ_BYTES);
 }
 
-static int sve_get(struct task_struct *target,
-		   const struct user_regset *regset,
-		   struct membuf to)
+static int sve_get_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  struct membuf to,
+			  enum vec_type type)
 {
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
-	sve_init_header_from_task(&header, target);
+	sve_init_header_from_task(&header, target, type);
 	vq = sve_vq_from_vl(header.vl);
 
 	membuf_write(&to, &header, sizeof(header));
@@ -759,49 +787,61 @@ static int sve_get(struct task_struct *target,
 	if (target == current)
 		fpsimd_preserve_current_state();
 
-	/* Registers: FPSIMD-only case */
-
 	BUILD_BUG_ON(SVE_PT_FPSIMD_OFFSET != sizeof(header));
-	if ((header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD)
+	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
+
+	switch ((header.flags & SVE_PT_REGS_MASK)) {
+	case SVE_PT_REGS_FPSIMD:
 		return __fpr_get(target, regset, to);
 
-	/* Otherwise: full SVE case */
+	case SVE_PT_REGS_SVE:
+		start = SVE_PT_SVE_OFFSET;
+		end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
+		membuf_write(&to, target->thread.sve_state, end - start);
 
-	BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header));
-	start = SVE_PT_SVE_OFFSET;
-	end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq);
-	membuf_write(&to, target->thread.sve_state, end - start);
+		start = end;
+		end = SVE_PT_SVE_FPSR_OFFSET(vq);
+		membuf_zero(&to, end - start);
 
-	start = end;
-	end = SVE_PT_SVE_FPSR_OFFSET(vq);
-	membuf_zero(&to, end - start);
+		/*
+		 * Copy fpsr, and fpcr which must follow contiguously in
+		 * struct fpsimd_state:
+		 */
+		start = end;
+		end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
+		membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr,
+			     end - start);
 
-	/*
-	 * Copy fpsr, and fpcr which must follow contiguously in
-	 * struct fpsimd_state:
-	 */
-	start = end;
-	end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE;
-	membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr, end - start);
+		start = end;
+		end = sve_size_from_header(&header);
+		return membuf_zero(&to, end - start);
 
-	start = end;
-	end = sve_size_from_header(&header);
-	return membuf_zero(&to, end - start);
+	default:
+		return 0;
+	}
 }
 
-static int sve_set(struct task_struct *target,
+static int sve_get(struct task_struct *target,
 		   const struct user_regset *regset,
-		   unsigned int pos, unsigned int count,
-		   const void *kbuf, const void __user *ubuf)
+		   struct membuf to)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SVE);
+}
+
+static int sve_set_common(struct task_struct *target,
+			  const struct user_regset *regset,
+			  unsigned int pos, unsigned int count,
+			  const void *kbuf, const void __user *ubuf,
+			  enum vec_type type)
 {
 	int ret;
 	struct user_sve_header header;
 	unsigned int vq;
 	unsigned long start, end;
 
-	if (!system_supports_sve())
-		return -EINVAL;
-
 	/* Header */
 	if (count < sizeof(header))
 		return -EINVAL;
@@ -814,13 +854,37 @@ static int sve_set(struct task_struct *target,
 	 * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
 	 * vec_set_vector_length(), which will also validate them for us:
 	 */
-	ret = vec_set_vector_length(target, ARM64_VEC_SVE, header.vl,
+	ret = vec_set_vector_length(target, type, header.vl,
 		((unsigned long)header.flags & ~SVE_PT_REGS_MASK) << 16);
 	if (ret)
 		goto out;
 
 	/* Actual VL set may be less than the user asked for: */
-	vq = sve_vq_from_vl(task_get_sve_vl(target));
+	vq = sve_vq_from_vl(task_get_vl(target, type));
+
+	/* Enter/exit streaming mode */
+	if (system_supports_sme()) {
+		u64 old_svcr = target->thread.svcr;
+
+		switch (type) {
+		case ARM64_VEC_SVE:
+			target->thread.svcr &= ~SYS_SVCR_EL0_SM_MASK;
+			break;
+		case ARM64_VEC_SME:
+			target->thread.svcr |= SYS_SVCR_EL0_SM_MASK;
+			break;
+		default:
+			WARN_ON_ONCE(1);
+			return -EINVAL;
+		}
+
+		/*
+		 * If we switched then invalidate any existing SVE
+		 * state and ensure there's storage.
+		 */
+		if (target->thread.svcr != old_svcr)
+			sve_alloc(target);
+	}
 
 	/* Registers: FPSIMD-only case */
 
@@ -832,7 +896,10 @@ static int sve_set(struct task_struct *target,
 		goto out;
 	}
 
-	/* Otherwise: full SVE case */
+	/*
+	 * Otherwise: no registers or full SVE case.  For backwards
+	 * compatibility reasons we treat empty flags as SVE registers.
+	 */
 
 	/*
 	 * If setting a different VL from the requested VL and there is
@@ -853,8 +920,9 @@ static int sve_set(struct task_struct *target,
 
 	/*
 	 * Ensure target->thread.sve_state is up to date with target's
-	 * FPSIMD regs, so that a short copyin leaves trailing registers
-	 * unmodified.
+	 * FPSIMD regs, so that a short copyin leaves trailing
+	 * registers unmodified.  Always enable SVE even if going into
+	 * streaming mode.
 	 */
 	fpsimd_sync_to_sve(target);
 	set_tsk_thread_flag(target, TIF_SVE);
@@ -890,8 +958,46 @@ static int sve_set(struct task_struct *target,
 	return ret;
 }
 
+static int sve_set(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sve())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SVE);
+}
+
 #endif /* CONFIG_ARM64_SVE */
 
+#ifdef CONFIG_ARM64_SME
+
+static int ssve_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   struct membuf to)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_get_common(target, regset, to, ARM64_VEC_SME);
+}
+
+static int ssve_set(struct task_struct *target,
+		    const struct user_regset *regset,
+		    unsigned int pos, unsigned int count,
+		    const void *kbuf, const void __user *ubuf)
+{
+	if (!system_supports_sme())
+		return -EINVAL;
+
+	return sve_set_common(target, regset, pos, count, kbuf, ubuf,
+			      ARM64_VEC_SME);
+}
+
+#endif /* CONFIG_ARM64_SME */
+
 #ifdef CONFIG_ARM64_PTR_AUTH
 static int pac_mask_get(struct task_struct *target,
 			const struct user_regset *regset,
@@ -1109,6 +1215,9 @@ enum aarch64_regset {
 #ifdef CONFIG_ARM64_SVE
 	REGSET_SVE,
 #endif
+#ifdef CONFIG_ARM64_SVE
+	REGSET_SSVE,
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	REGSET_PAC_MASK,
 	REGSET_PAC_ENABLED_KEYS,
@@ -1189,6 +1298,17 @@ static const struct user_regset aarch64_regsets[] = {
 		.set = sve_set,
 	},
 #endif
+#ifdef CONFIG_ARM64_SME
+	[REGSET_SSVE] = { /* Streaming mode SVE */
+		.core_note_type = NT_ARM_SSVE,
+		.n = DIV_ROUND_UP(SVE_PT_SIZE(SVE_VQ_MAX, SVE_PT_REGS_SVE),
+				  SVE_VQ_BYTES),
+		.size = SVE_VQ_BYTES,
+		.align = SVE_VQ_BYTES,
+		.regset_get = ssve_get,
+		.set = ssve_set,
+	},
+#endif
 #ifdef CONFIG_ARM64_PTR_AUTH
 	[REGSET_PAC_MASK] = {
 		.core_note_type = NT_ARM_PAC_MASK,
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 61bf4774b8f2..61502388683f 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -427,6 +427,7 @@ typedef struct elf64_shdr {
 #define NT_ARM_PACG_KEYS	0x408	/* ARM pointer authentication generic key */
 #define NT_ARM_TAGGED_ADDR_CTRL	0x409	/* arm64 tagged address control (prctl()) */
 #define NT_ARM_PAC_ENABLED_KEYS	0x40a	/* arm64 ptr auth enabled keys (prctl()) */
+#define NT_ARM_SSVE	0x40b		/* ARM Streaming SVE registers */
 #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
 #define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
 #define NT_MIPS_DSP	0x800		/* MIPS DSP ASE registers */
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:33 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:33 +0000
Subject: [PATCH v10 23/39] arm64/sme: Disable streaming mode and ZA when
 flushing CPU state
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-24-broonie@kernel.org>

Both streaming mode and ZA may increase power consumption when they are
enabled and streaming mode makes many FPSIMD and SVE instructions undefined
which will cause problems for any kernel mode floating point so disable
both when we flush the CPU state. This covers both kernel_neon_begin() and
idle and after flushing the state a reload is always required anyway.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 8b111b7f2006..e00d3a9e919c 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1762,6 +1762,15 @@ static void fpsimd_flush_cpu_state(void)
 {
 	WARN_ON(!system_supports_fpsimd());
 	__this_cpu_write(fpsimd_last_state.st, NULL);
+
+	/*
+	 * Leaving streaming mode enabled will cause issues for any kernel
+	 * NEON and leaving streaming mode or ZA enabled may increase power
+	 * consumption.
+	 */
+	if (system_supports_sme())
+		sme_smstop();
+
 	set_thread_flag(TIF_FOREIGN_FPSTATE);
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:34 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:34 +0000
Subject: [PATCH v10 24/39] arm64/sme: Save and restore streaming mode over EFI
 runtime calls
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-25-broonie@kernel.org>

When saving and restoring the floating point state over an EFI runtime
call ensure that we handle streaming mode, only handling FFR if we are not
in streaming mode and ensuring that we are in normal mode over the call
into runtime services.

We currently assume that ZA will not be modified by runtime services, the
specification is not yet finalised so this may need updating if that
changes.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++++++++++++++++-----
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index e00d3a9e919c..a7077a5d1ed2 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1059,21 +1059,25 @@ int vec_verify_vq_map(enum vec_type type)
 
 static void __init sve_efi_setup(void)
 {
-	struct vl_info *info = &vl_info[ARM64_VEC_SVE];
+	int max_vl = 0;
+	int i;
 
 	if (!IS_ENABLED(CONFIG_EFI))
 		return;
 
+	for (i = 0; i < ARRAY_SIZE(vl_info); i++)
+		max_vl = max(vl_info[i].max_vl, max_vl);
+
 	/*
 	 * alloc_percpu() warns and prints a backtrace if this goes wrong.
 	 * This is evidence of a crippled system and we are returning void,
 	 * so no attempt is made to handle this situation here.
 	 */
-	if (!sve_vl_valid(info->max_vl))
+	if (!sve_vl_valid(max_vl))
 		goto fail;
 
 	efi_sve_state = __alloc_percpu(
-		SVE_SIG_REGS_SIZE(sve_vq_from_vl(info->max_vl)), SVE_VQ_BYTES);
+		SVE_SIG_REGS_SIZE(sve_vq_from_vl(max_vl)), SVE_VQ_BYTES);
 	if (!efi_sve_state)
 		goto fail;
 
@@ -1848,6 +1852,7 @@ EXPORT_SYMBOL(kernel_neon_end);
 static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state);
 static DEFINE_PER_CPU(bool, efi_fpsimd_state_used);
 static DEFINE_PER_CPU(bool, efi_sve_state_used);
+static DEFINE_PER_CPU(bool, efi_sm_state);
 
 /*
  * EFI runtime services support functions
@@ -1882,12 +1887,28 @@ void __efi_fpsimd_begin(void)
 		 */
 		if (system_supports_sve() && likely(efi_sve_state)) {
 			char *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+			u64 svcr;
 
 			__this_cpu_write(efi_sve_state_used, true);
 
+			/* If we are in streaming mode don't touch FFR */
+			if (system_supports_sme()) {
+				svcr = read_sysreg_s(SYS_SVCR_EL0);
+
+				ffr = svcr & SYS_SVCR_EL0_SM_MASK;
+
+				__this_cpu_write(efi_sm_state, ffr);
+			}
+
 			sve_save_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
+
+			if (system_supports_sme())
+				sysreg_clear_set_s(SYS_SVCR_EL0,
+						   SYS_SVCR_EL0_SM_MASK, 0);
+
 		} else {
 			fpsimd_save_state(this_cpu_ptr(&efi_fpsimd_state));
 		}
@@ -1910,11 +1931,25 @@ void __efi_fpsimd_end(void)
 		if (system_supports_sve() &&
 		    likely(__this_cpu_read(efi_sve_state_used))) {
 			char const *sve_state = this_cpu_ptr(efi_sve_state);
+			bool ffr = true;
+
+			/*
+			 * Restore streaming mode; EFI calls are
+			 * normal function calls so should not return in
+			 * streaming mode.
+			 */
+			if (system_supports_sme()) {
+				if (__this_cpu_read(efi_sm_state)) {
+					sysreg_clear_set_s(SYS_SVCR_EL0,
+							   0,
+							   SYS_SVCR_EL0_SM_MASK);
+					ffr = false;
+				}
+			}
 
-			sve_set_vq(sve_vq_from_vl(sve_get_vl()) - 1);
 			sve_load_state(sve_state + sve_ffr_offset(sve_max_vl()),
 				       &this_cpu_ptr(&efi_fpsimd_state)->fpsr,
-				       true);
+				       ffr);
 
 			__this_cpu_write(efi_sve_state_used, false);
 		} else {
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:35 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:35 +0000
Subject: [PATCH v10 25/39] KVM: arm64: Hide SME system registers from guests
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-26-broonie@kernel.org>

For the time being we do not support use of SME by KVM guests, support for
this will be enabled in future. In order to prevent any side effects or
side channels via the new system registers, including the EL0 read/write
register TPIDR2, explicitly undefine all the system registers added by
SME and mask out the SME bitfield in SYS_ID_AA64PFR1.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba316ff..43516eda9143 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1089,6 +1089,8 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 	case SYS_ID_AA64PFR1_EL1:
 		if (!kvm_has_mte(vcpu->kvm))
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
+
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_SME);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1508,7 +1510,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
 	ID_SANITISED(ID_AA64ZFR0_EL1),
-	ID_UNALLOCATED(4,5),
+	ID_HIDDEN(ID_AA64SMFR0_EL1),
 	ID_UNALLOCATED(4,6),
 	ID_UNALLOCATED(4,7),
 
@@ -1551,6 +1553,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility },
 	{ SYS_DESC(SYS_TRFCR_EL1), undef_access },
+	{ SYS_DESC(SYS_SMPRI_EL1), undef_access },
+	{ SYS_DESC(SYS_SMCR_EL1), undef_access },
 	{ SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 },
 	{ SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 },
 	{ SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 },
@@ -1633,8 +1637,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_CCSIDR_EL1), access_ccsidr },
 	{ SYS_DESC(SYS_CLIDR_EL1), access_clidr },
+	{ SYS_DESC(SYS_SMIDR_EL1), undef_access },
 	{ SYS_DESC(SYS_CSSELR_EL1), access_csselr, reset_unknown, CSSELR_EL1 },
 	{ SYS_DESC(SYS_CTR_EL0), access_ctr },
+	{ SYS_DESC(SYS_SVCR_EL0), undef_access },
 
 	{ PMU_SYS_REG(SYS_PMCR_EL0), .access = access_pmcr,
 	  .reset = reset_pmcr, .reg = PMCR_EL0 },
@@ -1674,6 +1680,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
 	{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
+	{ SYS_DESC(SYS_TPIDR2_EL0), undef_access },
 
 	{ SYS_DESC(SYS_SCXTNUM_EL0), undef_access },
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:36 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:36 +0000
Subject: [PATCH v10 26/39] KVM: arm64: Trap SME usage in guest
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-27-broonie@kernel.org>

SME defines two new traps which need to be enabled for guests to ensure
that they can't use SME, one for the main SME operations which mirrors the
traps for SVE and another for access to TPIDR2 in SCTLR_EL2.

For VHE manage SMEN along with ZEN in activate_traps() and the FP state
management callbacks, along with SCTLR_EL2.EnTPIDR2.  There is no
existing dynamic management of SCTLR_EL2.

For nVHE manage TSM in activate_traps() along with the fine grained
traps for TPIDR2 and SMPRI.  There is no existing dynamic management of
fine grained traps.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kvm/hyp/nvhe/switch.c | 30 ++++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c  | 11 ++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 6410d21d8695..caace61ea459 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -47,10 +47,24 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
 		__activate_traps_fpsimd32(vcpu);
 	}
+	if (cpus_have_final_cap(ARM64_SME))
+		val |= CPTR_EL2_TSM;
 
 	write_sysreg(val, cptr_el2);
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
 
+	if (cpus_have_final_cap(ARM64_SME)) {
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val &= ~(HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			 HFGxTR_EL2_nSMPRI_EL1_MASK);
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {
 		struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
 
@@ -94,9 +108,25 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 
 	write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
 
+	if (cpus_have_final_cap(ARM64_SME)) {
+		u64 val;
+
+		val = read_sysreg_s(SYS_HFGRTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGRTR_EL2);
+
+		val = read_sysreg_s(SYS_HFGWTR_EL2);
+		val |= HFGxTR_EL2_nTPIDR2_EL0_MASK |
+			HFGxTR_EL2_nSMPRI_EL1_MASK;
+		write_sysreg_s(val, SYS_HFGWTR_EL2);
+	}
+
 	cptr = CPTR_EL2_DEFAULT;
 	if (vcpu_has_sve(vcpu) && (vcpu->arch.flags & KVM_ARM64_FP_ENABLED))
 		cptr |= CPTR_EL2_TZ;
+	if (cpus_have_final_cap(ARM64_SME))
+		cptr &= ~CPTR_EL2_TSM;
 
 	write_sysreg(cptr, cptr_el2);
 	write_sysreg(__kvm_hyp_host_vector, vbar_el2);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 619353b06e38..a4d2fb5c9710 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -38,7 +38,8 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
-	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN);
+	val &= ~(CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN |
+		 CPACR_EL1_SMEN_EL0EN | CPACR_EL1_SMEN_EL1EN);
 
 	/*
 	 * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
@@ -59,6 +60,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		__activate_traps_fpsimd32(vcpu);
 	}
 
+	if (cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) & ~SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(val, cpacr_el1);
 
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
@@ -80,6 +85,10 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
 	 */
 	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
 
+	if (cpus_have_final_cap(ARM64_SME))
+		write_sysreg(read_sysreg(sctlr_el2) | SCTLR_ELx_ENTP2,
+			     sctlr_el2);
+
 	write_sysreg(CPACR_EL1_DEFAULT, cpacr_el1);
 	write_sysreg(vectors, vbar_el1);
 }
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:37 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:37 +0000
Subject: [PATCH v10 27/39] KVM: arm64: Handle SME host state when running
 guests
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-28-broonie@kernel.org>

While we don't currently support SME in guests we do currently support it
for the host system so we need to take care of SME's impact, including
the floating point register state, when running guests. Simiarly to SVE
we need to manage the traps in CPACR_RL1, what is new is the handling of
streaming mode and ZA.

Normally we defer any handling of the floating point register state until
the guest first uses it however if the system is in streaming mode FPSIMD
and SVE operations may generate SME traps which we would need to distinguish
from actual attempts by the guest to use SME. Rather than do this for the
time being if we are in streaming mode when entering the guest we force
the floating point state to be saved immediately and exit streaming mode,
meaning that the guest won't generate SME traps for supported operations.

We could handle ZA in the access trap similarly to the FPSIMD/SVE state
without the disruption caused by streaming mode but for simplicity
handle it the same way as streaming mode for now.

This will be revisited when we support SME for guests (hopefully before SME
hardware becomes available), for now it will only incur additional cost on
systems with SME and even there only if streaming mode or ZA are enabled.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  1 +
 arch/arm64/kvm/fpsimd.c           | 36 +++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7dc85d5a6552..404b7358ba96 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -438,6 +438,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
 #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
+#define KVM_ARM64_HOST_SME_ENABLED	(1 << 15) /* SME enabled for EL0 */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
index 338733ac63f8..1c585553d74f 100644
--- a/arch/arm64/kvm/fpsimd.c
+++ b/arch/arm64/kvm/fpsimd.c
@@ -82,6 +82,26 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
 
 	if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
 		vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
+
+	/*
+	 * We don't currently support SME guests but if we leave
+	 * things in streaming mode then when the guest starts running
+	 * FPSIMD or SVE code it may generate SME traps so as a
+	 * special case if we are in streaming mode we force the host
+	 * state to be saved now and exit streaming mode so that we
+	 * don't have to handle any SME traps for valid guest
+	 * operations. Do this for ZA as well for now for simplicity.
+	 */
+	if (system_supports_sme()) {
+		if (read_sysreg(cpacr_el1) & CPACR_EL1_SMEN_EL0EN)
+			vcpu->arch.flags |= KVM_ARM64_HOST_SME_ENABLED;
+
+		if (read_sysreg_s(SYS_SVCR_EL0) &
+		    (SYS_SVCR_EL0_SM_MASK | SYS_SVCR_EL0_ZA_MASK)) {
+			vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
+			fpsimd_save_and_flush_cpu_state();
+		}
+	}
 }
 
 void kvm_arch_vcpu_ctxflush_fp(struct kvm_vcpu *vcpu)
@@ -129,6 +149,22 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
 
 	local_irq_save(flags);
 
+	/*
+	 * If we have VHE then the Hyp code will reset CPACR_EL1 to
+	 * CPACR_EL1_DEFAULT and we need to reenable SME.
+	 */
+	if (has_vhe() && system_supports_sme()) {
+		/* Also restore EL0 state seen on entry */
+		if (vcpu->arch.flags & KVM_ARM64_HOST_SME_ENABLED)
+			sysreg_clear_set(CPACR_EL1, 0,
+					 CPACR_EL1_SMEN_EL0EN |
+					 CPACR_EL1_SMEN_EL1EN);
+		else
+			sysreg_clear_set(CPACR_EL1,
+					 CPACR_EL1_SMEN_EL0EN,
+					 CPACR_EL1_SMEN_EL1EN);
+	}
+
 	if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
 		if (vcpu_has_sve(vcpu)) {
 			__vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:38 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:38 +0000
Subject: [PATCH v10 28/39] arm64/sme: Provide Kconfig for SME
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-29-broonie@kernel.org>

Now that basline support for the Scalable Matrix Extension (SME) is present
introduce the Kconfig option allowing it to be built. While the feature
registers don't impose a strong requirement for a system with SME to
support SVE at runtime the support for streaming mode SVE is mostly
shared with normal SVE so depend on SVE.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/Kconfig | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..f60f3b04ddf5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1839,6 +1839,17 @@ config ARM64_SVE
 	  booting the kernel.  If unsure and you are not observing these
 	  symptoms, you should assume that it is safe to say Y.
 
+config ARM64_SME
+	bool "ARM Scalable Matrix Extension support"
+	default y
+	depends on ARM64_SVE
+	help
+	  The Scalable Matrix Extension (SME) is an extension to the AArch64
+	  execution state which utilises a substantial subset of the SVE
+	  instruction set, together with the addition of new architectural
+	  register state capable of holding two dimensional matrix tiles to
+	  enable various matrix operations.
+
 config ARM64_MODULE_PLTS
 	bool "Use PLTs to allow module memory to spill over into vmalloc area"
 	depends on MODULES
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:39 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:39 +0000
Subject: [PATCH v10 29/39] kselftest/arm64: sme: Add streaming SME support to
 vlset
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-30-broonie@kernel.org>

The Scalable Matrix Extenions (SME) introduces additional register state
with configurable vector lengths, similar to SVE but configured separately.
Extend vlset to support configuring this state with a --sme or -s command
line option.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/vlset.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/arm64/fp/vlset.c b/tools/testing/selftests/arm64/fp/vlset.c
index 308d27a68226..76912a581a95 100644
--- a/tools/testing/selftests/arm64/fp/vlset.c
+++ b/tools/testing/selftests/arm64/fp/vlset.c
@@ -22,12 +22,15 @@ static int inherit = 0;
 static int no_inherit = 0;
 static int force = 0;
 static unsigned long vl;
+static int set_ctl = PR_SVE_SET_VL;
+static int get_ctl = PR_SVE_GET_VL;
 
 static const struct option options[] = {
 	{ "force",	no_argument, NULL, 'f' },
 	{ "inherit",	no_argument, NULL, 'i' },
 	{ "max",	no_argument, NULL, 'M' },
 	{ "no-inherit",	no_argument, &no_inherit, 1 },
+	{ "sme",	no_argument, NULL, 's' },
 	{ "help",	no_argument, NULL, '?' },
 	{}
 };
@@ -50,6 +53,9 @@ static int parse_options(int argc, char **argv)
 		case 'M':	vl = SVE_VL_MAX; break;
 		case 'f':	force = 1; break;
 		case 'i':	inherit = 1; break;
+		case 's':	set_ctl = PR_SME_SET_VL;
+				get_ctl = PR_SME_GET_VL;
+				break;
 		case 0:		break;
 		default:	goto error;
 		}
@@ -125,14 +131,14 @@ int main(int argc, char **argv)
 	if (inherit)
 		flags |= PR_SVE_VL_INHERIT;
 
-	t = prctl(PR_SVE_SET_VL, vl | flags);
+	t = prctl(set_ctl, vl | flags);
 	if (t < 0) {
 		fprintf(stderr, "%s: PR_SVE_SET_VL: %s\n",
 			program_name, strerror(errno));
 		goto error;
 	}
 
-	t = prctl(PR_SVE_GET_VL);
+	t = prctl(get_ctl);
 	if (t == -1) {
 		fprintf(stderr, "%s: PR_SVE_GET_VL: %s\n",
 			program_name, strerror(errno));
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:40 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:40 +0000
Subject: [PATCH v10 30/39] kselftest/arm64: Add tests for TPIDR2
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-31-broonie@kernel.org>

The Scalable Matrix Extension adds a new system register TPIDR2 intended to
be used by libc for its own thread specific use, add some kselftests which
exercise the ABI for it.

Since this test should with some adjustment work for TPIDR and any other
similar registers added in future add tests for it in a separate
directory rather than placing it with the other floating point tests,
nothing existing looked suitable so I created a new test directory
called "abi".

Since this feature is intended to be used by libc the test is built as
freestanding code using nolibc so we don't end up with the test program
and libc both trying to manage the register simultaneously and
distrupting each other. As a result of being written using nolibc rather
than using hwcaps to identify if SME is available in the system we check
for the default SME vector length configuration in proc, adding hwcap
support to nolibc seems like disproportionate effort and didn't feel
entirely idiomatic for what nolibc is trying to do.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/abi/.gitignore |   1 +
 tools/testing/selftests/arm64/abi/Makefile   |   9 +-
 tools/testing/selftests/arm64/abi/tpidr2.c   | 298 +++++++++++++++++++
 3 files changed, 307 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/abi/tpidr2.c

diff --git a/tools/testing/selftests/arm64/abi/.gitignore b/tools/testing/selftests/arm64/abi/.gitignore
index b79cf5814c23..b9e54417250d 100644
--- a/tools/testing/selftests/arm64/abi/.gitignore
+++ b/tools/testing/selftests/arm64/abi/.gitignore
@@ -1 +1,2 @@
 syscall-abi
+tpidr2
diff --git a/tools/testing/selftests/arm64/abi/Makefile b/tools/testing/selftests/arm64/abi/Makefile
index 96eba974ac8d..c8d7f2495eb2 100644
--- a/tools/testing/selftests/arm64/abi/Makefile
+++ b/tools/testing/selftests/arm64/abi/Makefile
@@ -1,8 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (C) 2021 ARM Limited
 
-TEST_GEN_PROGS := syscall-abi
+TEST_GEN_PROGS := syscall-abi tpidr2
 
 include ../../lib.mk
 
 $(OUTPUT)/syscall-abi: syscall-abi.c syscall-abi-asm.S
+
+# Build with nolibc since TPIDR2 is intended to be actively managed by
+# libc and we're trying to test the functionality that it depends on here.
+$(OUTPUT)/tpidr2: tpidr2.c
+	$(CC) -fno-asynchronous-unwind-tables -fno-ident -s -Os -nostdlib \
+		-static -include ../../../../include/nolibc/nolibc.h \
+		-ffreestanding -Wall $^ -o $@ -lgcc
diff --git a/tools/testing/selftests/arm64/abi/tpidr2.c b/tools/testing/selftests/arm64/abi/tpidr2.c
new file mode 100644
index 000000000000..351a098b503a
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/tpidr2.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+
+#define SYS_TPIDR2 "S3_3_C13_C0_5"
+
+#define EXPECTED_TESTS 5
+
+static void putstr(const char *str)
+{
+	write(1, str, strlen(str));
+}
+
+static void putnum(unsigned int num)
+{
+	char c;
+
+	if (num / 10)
+		putnum(num / 10);
+
+	c = '0' + (num % 10);
+	write(1, &c, 1);
+}
+
+static int tests_run;
+static int tests_passed;
+static int tests_failed;
+static int tests_skipped;
+
+static void set_tpidr2(uint64_t val)
+{
+	asm volatile (
+		"msr	" SYS_TPIDR2 ", %0\n"
+		:
+		: "r"(val)
+		: "cc");
+}
+
+static uint64_t get_tpidr2(void)
+{
+	uint64_t val;
+
+	asm volatile (
+		"mrs	%0, " SYS_TPIDR2 "\n"
+		: "=r"(val)
+		:
+		: "cc");
+
+	return val;
+}
+
+static void print_summary(void)
+{
+	if (tests_passed + tests_failed + tests_skipped != EXPECTED_TESTS)
+		putstr("# UNEXPECTED TEST COUNT: ");
+
+	putstr("# Totals: pass:");
+	putnum(tests_passed);
+	putstr(" fail:");
+	putnum(tests_failed);
+	putstr(" xfail:0 xpass:0 skip:");
+	putnum(tests_skipped);
+	putstr(" error:0\n");
+}
+
+/* Processes should start with TPIDR2 == 0 */
+static int default_value(void)
+{
+	return get_tpidr2() == 0;
+}
+
+/* If we set TPIDR2 we should read that value */
+static int write_read(void)
+{
+	set_tpidr2(getpid());
+
+	return getpid() == get_tpidr2();
+}
+
+/* If we set a value we should read the same value after scheduling out */
+static int write_sleep_read(void)
+{
+	set_tpidr2(getpid());
+
+	msleep(100);
+
+	return getpid() == get_tpidr2();
+}
+
+/*
+ * If we fork the value in the parent should be unchanged and the
+ * child should start with the same value and be able to set its own
+ * value.
+ */
+static int write_fork_read(void)
+{
+	pid_t newpid, waiting, oldpid;
+	int status;
+
+	set_tpidr2(getpid());
+
+	oldpid = getpid();
+	newpid = fork();
+	if (newpid == 0) {
+		/* In child */
+		if (get_tpidr2() != oldpid) {
+			putstr("# TPIDR2 changed in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		set_tpidr2(getpid());
+		if (get_tpidr2() == getpid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+	if (newpid < 0) {
+		putstr("# fork() failed: -");
+		putnum(-newpid);
+		putstr("\n");
+		return 0;
+	}
+
+	for (;;) {
+		waiting = waitpid(newpid, &status, 0);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# waitpid() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != newpid) {
+			putstr("# waitpid() returned wrong PID\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (getpid() != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+/*
+ * sys_clone() has a lot of per architecture variation so just define
+ * it here rather than adding it to nolibc, plus the raw API is a
+ * little more convenient for this test.
+ */
+static int sys_clone(unsigned long clone_flags, unsigned long newsp,
+		     int *parent_tidptr, unsigned long tls,
+		     int *child_tidptr)
+{
+	return my_syscall5(__NR_clone, clone_flags, newsp, parent_tidptr, tls,
+			   child_tidptr);
+}
+
+/*
+ * If we clone with CLONE_SETTLS then the value in the parent should
+ * be unchanged and the child should start with zero and be able to
+ * set its own value.
+ */
+static int write_clone_read(void)
+{
+	int parent_tid, child_tid;
+	pid_t parent, waiting;
+	int ret, status;
+
+	parent = getpid();
+	set_tpidr2(parent);
+
+	ret = sys_clone(CLONE_SETTLS, 0, &parent_tid, 0, &child_tid);
+	if (ret == -1) {
+		putstr("# clone() failed\n");
+		putnum(errno);
+		putstr("\n");
+		return 0;
+	}
+
+	if (ret == 0) {
+		/* In child */
+		if (get_tpidr2() != 0) {
+			putstr("# TPIDR2 non-zero in child: ");
+			putnum(get_tpidr2());
+			putstr("\n");
+			exit(0);
+		}
+
+		if (gettid() == 0)
+			putstr("# Child TID==0\n");
+		set_tpidr2(gettid());
+		if (get_tpidr2() == gettid()) {
+			exit(1);
+		} else {
+			putstr("# Failed to set TPIDR2 in child\n");
+			exit(0);
+		}
+	}
+
+	for (;;) {
+		waiting = wait4(ret, &status, __WCLONE, NULL);
+
+		if (waiting < 0) {
+			if (errno == EINTR)
+				continue;
+			putstr("# wait4() failed: ");
+			putnum(errno);
+			putstr("\n");
+			return 0;
+		}
+		if (waiting != ret) {
+			putstr("# wait4() returned wrong PID ");
+			putnum(waiting);
+			putstr("\n");
+			return 0;
+		}
+
+		if (!WIFEXITED(status)) {
+			putstr("# child did not exit\n");
+			return 0;
+		}
+
+		if (parent != get_tpidr2()) {
+			putstr("# TPIDR2 corrupted in parent\n");
+			return 0;
+		}
+
+		return WEXITSTATUS(status);
+	}
+}
+
+#define run_test(name)			     \
+	if (name()) {			     \
+		tests_passed++;		     \
+	} else {			     \
+		tests_failed++;		     \
+		putstr("not ");		     \
+	}				     \
+	putstr("ok ");			     \
+	putnum(++tests_run);		     \
+	putstr(" " #name "\n");
+
+int main(int argc, char **argv)
+{
+	int ret, i;
+
+	putstr("TAP version 13\n");
+	putstr("1..");
+	putnum(EXPECTED_TESTS);
+	putstr("\n");
+
+	putstr("# PID: ");
+	putnum(getpid());
+	putstr("\n");
+
+	/*
+	 * This test is run with nolibc which doesn't support hwcap and
+	 * it's probably disproportionate to implement so instead check
+	 * for the default vector length configuration in /proc.
+	 */
+	ret = open("/proc/sys/abi/sme_default_vector_length", O_RDONLY, 0);
+	if (ret >= 0) {
+		run_test(default_value);
+		run_test(write_read);
+		run_test(write_sleep_read);
+		run_test(write_fork_read);
+		run_test(write_clone_read);
+
+	} else {
+		putstr("# SME support not present\n");
+
+		for (i = 0; i < EXPECTED_TESTS; i++) {
+			putstr("ok ");
+			putnum(i);
+			putstr(" skipped, TPIDR2 not supported\n");
+		}
+
+		tests_skipped += EXPECTED_TESTS;
+	}
+
+	print_summary();
+
+	return 0;
+}
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:41 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:41 +0000
Subject: [PATCH v10 31/39] kselftest/arm64: Extend vector configuration API
 tests to cover SME
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-32-broonie@kernel.org>

Provide RDVL helpers for SME and extend the main vector configuration tests
to cover SME.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore   |  1 +
 tools/testing/selftests/arm64/fp/Makefile     |  3 ++-
 tools/testing/selftests/arm64/fp/rdvl-sme.c   | 14 ++++++++++++++
 tools/testing/selftests/arm64/fp/rdvl.S       |  8 ++++++++
 tools/testing/selftests/arm64/fp/rdvl.h       |  1 +
 tools/testing/selftests/arm64/fp/vec-syscfg.c | 10 ++++++++++
 6 files changed, 36 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/rdvl-sme.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index c50d86331ed2..6e9a610c5e5d 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -1,5 +1,6 @@
 fp-pidbench
 fpsimd-test
+rdvl-sme
 rdvl-sve
 sve-probe-vls
 sve-ptrace
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 95f0b877a060..a224fff8082b 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -3,7 +3,7 @@
 CFLAGS += -I../../../../../usr/include/
 TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
-	rdvl-sve \
+	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	vlset
 
@@ -13,6 +13,7 @@ fp-pidbench: fp-pidbench.S asm-utils.o
 	$(CC) -nostdlib $^ -o $@
 fpsimd-test: fpsimd-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+rdvl-sme: rdvl-sme.o rdvl.o
 rdvl-sve: rdvl-sve.o rdvl.o
 sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
diff --git a/tools/testing/selftests/arm64/fp/rdvl-sme.c b/tools/testing/selftests/arm64/fp/rdvl-sme.c
new file mode 100644
index 000000000000..49b0b2e08bac
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/rdvl-sme.c
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <stdio.h>
+
+#include "rdvl.h"
+
+int main(void)
+{
+	int vl = rdvl_sme();
+
+	printf("%d\n", vl);
+
+	return 0;
+}
diff --git a/tools/testing/selftests/arm64/fp/rdvl.S b/tools/testing/selftests/arm64/fp/rdvl.S
index c916c1c9defd..1a2ebf07a20c 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.S
+++ b/tools/testing/selftests/arm64/fp/rdvl.S
@@ -8,3 +8,11 @@ rdvl_sve:
 	hint	34			// BTI C
 	rdvl	x0, #1
 	ret
+
+.globl rdvl_sme
+rdvl_sme:
+	hint	34			// BTI C
+
+	.inst	0x4bf5820		// RDSVL x0, #1
+
+	ret
diff --git a/tools/testing/selftests/arm64/fp/rdvl.h b/tools/testing/selftests/arm64/fp/rdvl.h
index 7c9d953fc9e7..5d323679fbc9 100644
--- a/tools/testing/selftests/arm64/fp/rdvl.h
+++ b/tools/testing/selftests/arm64/fp/rdvl.h
@@ -3,6 +3,7 @@
 #ifndef RDVL_H
 #define RDVL_H
 
+int rdvl_sme(void);
 int rdvl_sve(void);
 
 #endif
diff --git a/tools/testing/selftests/arm64/fp/vec-syscfg.c b/tools/testing/selftests/arm64/fp/vec-syscfg.c
index c90658811a83..9bcfcdc34ee9 100644
--- a/tools/testing/selftests/arm64/fp/vec-syscfg.c
+++ b/tools/testing/selftests/arm64/fp/vec-syscfg.c
@@ -51,6 +51,16 @@ static struct vec_data vec_data[] = {
 		.prctl_set = PR_SVE_SET_VL,
 		.default_vl_file = "/proc/sys/abi/sve_default_vector_length",
 	},
+	{
+		.name = "SME",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.rdvl = rdvl_sme,
+		.rdvl_binary = "./rdvl-sme",
+		.prctl_get = PR_SME_GET_VL,
+		.prctl_set = PR_SME_SET_VL,
+		.default_vl_file = "/proc/sys/abi/sme_default_vector_length",
+	},
 };
 
 static int stdio_read_integer(FILE *f, const char *what, int *val)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:42 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:42 +0000
Subject: [PATCH v10 32/39] kselftest/arm64: sme: Provide streaming mode SVE
 stress test
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-33-broonie@kernel.org>

One of the features of SME is the addition of streaming mode, in which we
have access to a set of streaming mode SVE registers at the SME vector
length. Since these are accessed using the SVE instructions let's reuse
the existing SVE stress test for testing with a compile time option for
controlling the few small differences needed:

 - Enter streaming mode immediately on starting the program.
 - In streaming mode FFR is removed so skip reading and writing FFR.

In order to avoid requiring a cutting edge toolchain with SME support
use the op/CR form for specifying SVCR.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |  1 +
 tools/testing/selftests/arm64/fp/Makefile    |  3 +
 tools/testing/selftests/arm64/fp/ssve-stress | 59 ++++++++++++++++++++
 tools/testing/selftests/arm64/fp/sve-test.S  | 30 ++++++++++
 4 files changed, 93 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/ssve-stress

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 6e9a610c5e5d..5729a5b1adfc 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -5,5 +5,6 @@ rdvl-sve
 sve-probe-vls
 sve-ptrace
 sve-test
+ssve-test
 vec-syscfg
 vlset
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index a224fff8082b..e6643c9b0474 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -5,6 +5,7 @@ TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
+	ssve-test ssve-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -19,6 +20,8 @@ sve-ptrace: sve-ptrace.o
 sve-probe-vls: sve-probe-vls.o rdvl.o
 sve-test: sve-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+ssve-test: sve-test.S asm-utils.o
+	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 
diff --git a/tools/testing/selftests/arm64/fp/ssve-stress b/tools/testing/selftests/arm64/fp/ssve-stress
new file mode 100644
index 000000000000..e2bd2cc184ad
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/ssve-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./ssve-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/sve-test.S b/tools/testing/selftests/arm64/fp/sve-test.S
index f5b1b48ffff2..31764e8370db 100644
--- a/tools/testing/selftests/arm64/fp/sve-test.S
+++ b/tools/testing/selftests/arm64/fp/sve-test.S
@@ -156,6 +156,7 @@ endfunction
 // We fill the upper lanes of FFR with zeros.
 // Beware: corrupts P0.
 function setup_ffr
+#ifndef SSVE
 	mov	x4, x30
 
 	and	w0, w0, #0x3
@@ -178,6 +179,9 @@ function setup_ffr
 	wrffr	p0.b
 
 	ret	x4
+#else
+	ret
+#endif
 endfunction
 
 // Trivial memory compare: compare x2 bytes starting at address x0 with
@@ -260,6 +264,7 @@ endfunction
 // Beware -- corrupts P0.
 // Clobbers x0-x5.
 function check_ffr
+#ifndef SSVE
 	mov	x3, x30
 
 	ldr	x4, =scratch
@@ -280,6 +285,9 @@ function check_ffr
 	mov	x2, x5
 	mov	x30, x3
 	b	memcmp
+#else
+	ret
+#endif
 endfunction
 
 // Any SVE register modified here can cause corruption in the main
@@ -295,13 +303,26 @@ function irritator_handler
 	movi	v0.8b, #1
 	movi	v9.16b, #2
 	movi	v31.8b, #3
+#ifndef SSVE
 	// And P0
 	rdffr	p0.b
 	// And FFR
 	wrffr	p15.b
+#endif
+
+	ret
+endfunction
+
+#ifdef SSVE
+function enable_sm
+	// Set SVCR.SM to 1, equivalent to SMSTART SM but doesn't need a
+	// SME capable toolchain.
+	mov	x0, #1
+	msr	S3_3_C4_C2_2, x0
 
 	ret
 endfunction
+#endif
 
 function terminate_handler
 	mov	w21, w0
@@ -359,6 +380,11 @@ endfunction
 .globl _start
 function _start
 _start:
+#ifdef SSVE
+	puts	"Streaming mode "
+	bl	enable_sm
+#endif
+
 	// Sanity-check and report the vector length
 
 	rdvl	x19, #8
@@ -407,6 +433,10 @@ _start:
 	orr	w2, w2, #SA_NODEFER
 	bl	setsignal
 
+#ifdef SSVE
+	bl	enable_sm	// syscalls will have exited streaming mode
+#endif
+
 	mov	x22, #0		// generation number, increments per iteration
 .Ltest_loop:
 	rdvl	x0, #8
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:44 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:44 +0000
Subject: [PATCH v10 34/39] kselftest/arm64: signal: Handle ZA signal context
 in core code
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-35-broonie@kernel.org>

As part of the generic code for signal handling test cases we parse all
signal frames to make sure they have at least the basic form we expect
and that there are no unexpected frames present in the signal context.
Add coverage of the ZA signal frame to this code.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../arm64/signal/testcases/testcases.c        | 36 +++++++++++++++++++
 .../arm64/signal/testcases/testcases.h        |  3 +-
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.c b/tools/testing/selftests/arm64/signal/testcases/testcases.c
index 8c2a57fc2f9c..84c36bee4d82 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.c
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.c
@@ -75,6 +75,31 @@ bool validate_sve_context(struct sve_context *sve, char **err)
 	return true;
 }
 
+bool validate_za_context(struct za_context *za, char **err)
+{
+	/* Size will be rounded up to a multiple of 16 bytes */
+	size_t regs_size
+		= ((ZA_SIG_CONTEXT_SIZE(sve_vq_from_vl(za->vl)) + 15) / 16) * 16;
+
+	if (!za || !err)
+		return false;
+
+	/* Either a bare za_context or a za_context followed by regs data */
+	if ((za->head.size != sizeof(struct za_context)) &&
+	    (za->head.size != regs_size)) {
+		*err = "bad size for ZA context";
+		return false;
+	}
+
+	if (!sve_vl_valid(za->vl)) {
+		*err = "SME VL in ZA context invalid";
+
+		return false;
+	}
+
+	return true;
+}
+
 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 {
 	bool terminated = false;
@@ -82,6 +107,7 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 	int flags = 0;
 	struct extra_context *extra = NULL;
 	struct sve_context *sve = NULL;
+	struct za_context *za = NULL;
 	struct _aarch64_ctx *head =
 		(struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
 
@@ -120,6 +146,13 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 			sve = (struct sve_context *)head;
 			flags |= SVE_CTX;
 			break;
+		case ZA_MAGIC:
+			if (flags & ZA_CTX)
+				*err = "Multiple ZA_MAGIC";
+			/* Size is validated in validate_za_context() */
+			za = (struct za_context *)head;
+			flags |= ZA_CTX;
+			break;
 		case EXTRA_MAGIC:
 			if (flags & EXTRA_CTX)
 				*err = "Multiple EXTRA_MAGIC";
@@ -165,6 +198,9 @@ bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err)
 		if (flags & SVE_CTX)
 			if (!validate_sve_context(sve, err))
 				return false;
+		if (flags & ZA_CTX)
+			if (!validate_za_context(za, err))
+				return false;
 
 		head = GET_RESV_NEXT_HEAD(head);
 	}
diff --git a/tools/testing/selftests/arm64/signal/testcases/testcases.h b/tools/testing/selftests/arm64/signal/testcases/testcases.h
index ad884c135314..49f1d5de7b5b 100644
--- a/tools/testing/selftests/arm64/signal/testcases/testcases.h
+++ b/tools/testing/selftests/arm64/signal/testcases/testcases.h
@@ -16,7 +16,8 @@
 
 #define FPSIMD_CTX	(1 << 0)
 #define SVE_CTX		(1 << 1)
-#define EXTRA_CTX	(1 << 2)
+#define ZA_CTX		(1 << 2)
+#define EXTRA_CTX	(1 << 3)
 
 #define KSFT_BAD_MAGIC	0xdeadbeef
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:43 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:43 +0000
Subject: [PATCH v10 33/39] kselftest/arm64: signal: Allow tests to be
 incompatible with features
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-34-broonie@kernel.org>

Some features may invalidate some tests, for example by supporting an
operation which would trap otherwise. Allow tests to list features that
they are incompatible with so we can cover the case where a signal will
be generated without disruption on systems where that won't happen.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/signal/test_signals.h     |  1 +
 .../arm64/signal/test_signals_utils.c         | 34 ++++++++++++++-----
 .../arm64/signal/test_signals_utils.h         |  2 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index ebe8694dbef0..f909b70d9e98 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -53,6 +53,7 @@ struct tdescr {
 	char			*name;
 	char			*descr;
 	unsigned long		feats_required;
+	unsigned long		feats_incompatible;
 	/* bitmask of effectively supported feats: populated at run-time */
 	unsigned long		feats_supported;
 	bool			initialized;
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 2f8c23af3b5e..5743897984b0 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -36,6 +36,8 @@ static inline char *feats_to_string(unsigned long feats)
 {
 	size_t flen = MAX_FEATS_SZ - 1;
 
+	feats_string[0] = '\0';
+
 	for (int i = 0; i < FMAX_END; i++) {
 		if (feats & (1UL << i)) {
 			size_t tlen = strlen(feats_names[i]);
@@ -256,7 +258,7 @@ int test_init(struct tdescr *td)
 		td->minsigstksz = MINSIGSTKSZ;
 	fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
 
-	if (td->feats_required) {
+	if (td->feats_required || td->feats_incompatible) {
 		td->feats_supported = 0;
 		/*
 		 * Checking for CPU required features using both the
@@ -267,15 +269,29 @@ int test_init(struct tdescr *td)
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
 		if (feats_ok(td)) {
-			fprintf(stderr,
-				"Required Features: [%s] supported\n",
-				feats_to_string(td->feats_required &
-						td->feats_supported));
+			if (td->feats_required & td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] supported\n",
+					feats_to_string(td->feats_required &
+							td->feats_supported));
+			if (!(td->feats_incompatible & td->feats_supported))
+				fprintf(stderr,
+					"Incompatible Features: [%s] absent\n",
+					feats_to_string(td->feats_incompatible));
 		} else {
-			fprintf(stderr,
-				"Required Features: [%s] NOT supported\n",
-				feats_to_string(td->feats_required &
-						~td->feats_supported));
+			if ((td->feats_required & td->feats_supported) !=
+			    td->feats_supported)
+				fprintf(stderr,
+					"Required Features: [%s] NOT supported\n",
+					feats_to_string(td->feats_required &
+							~td->feats_supported));
+			if (td->feats_incompatible & td->feats_supported)
+				fprintf(stderr,
+					"Incompatible Features: [%s] supported\n",
+					feats_to_string(td->feats_incompatible &
+							~td->feats_supported));
+
+
 			td->result = KSFT_SKIP;
 			return 0;
 		}
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.h b/tools/testing/selftests/arm64/signal/test_signals_utils.h
index 6772b5c8d274..f3aa99ba67bb 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.h
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.h
@@ -18,6 +18,8 @@ void test_result(struct tdescr *td);
 
 static inline bool feats_ok(struct tdescr *td)
 {
+	if (td->feats_incompatible & td->feats_supported)
+		return false;
 	return (td->feats_required & td->feats_supported) == td->feats_required;
 }
 
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:45 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:45 +0000
Subject: [PATCH v10 35/39] kselftest/arm64: Add stress test for SME ZA context
 switching
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-36-broonie@kernel.org>

Add a stress test for context switching of the ZA register state based on
the similar tests Dave Martin wrote for FPSIMD and SVE registers. The test
loops indefinitely writing a data pattern to ZA then reading it back and
verifying that it's what was expected.

Unlike the other tests we manually assemble the SME instructions since at
present no released toolchain has SME support integrated.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore |   1 +
 tools/testing/selftests/arm64/fp/Makefile   |   3 +
 tools/testing/selftests/arm64/fp/za-stress  |  59 +++
 tools/testing/selftests/arm64/fp/za-test.S  | 426 ++++++++++++++++++++
 4 files changed, 489 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/fp/za-stress
 create mode 100644 tools/testing/selftests/arm64/fp/za-test.S

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index 5729a5b1adfc..ead3197e720b 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,3 +8,4 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index e6643c9b0474..38d2d0d5a0eb 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -6,6 +6,7 @@ TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
 	ssve-test ssve-stress \
+	za-test za-stress \
 	vlset
 
 all: $(TEST_GEN_PROGS) $(TEST_PROGS_EXTENDED)
@@ -24,5 +25,7 @@ ssve-test: sve-test.S asm-utils.o
 	$(CC) -DSSVE -nostdlib $^ -o $@
 vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
+za-test: za-test.o asm-utils.o
+	$(CC) -nostdlib $^ -o $@
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-stress b/tools/testing/selftests/arm64/fp/za-stress
new file mode 100644
index 000000000000..5ac386b55b95
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-stress
@@ -0,0 +1,59 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0-only
+# Copyright (C) 2015-2019 ARM Limited.
+# Original author: Dave Martin <Dave.Martin at arm.com>
+
+set -ue
+
+NR_CPUS=`nproc`
+
+pids=
+logs=
+
+cleanup () {
+	trap - INT TERM CHLD
+	set +e
+
+	if [ -n "$pids" ]; then
+		kill $pids
+		wait $pids
+		pids=
+	fi
+
+	if [ -n "$logs" ]; then
+		cat $logs
+		rm $logs
+		logs=
+	fi
+}
+
+interrupt () {
+	cleanup
+	exit 0
+}
+
+child_died () {
+	cleanup
+	exit 1
+}
+
+trap interrupt INT TERM EXIT
+
+for x in `seq 0 $((NR_CPUS * 4))`; do
+	log=`mktemp`
+	logs=$logs\ $log
+	./za-test >$log &
+	pids=$pids\ $!
+done
+
+# Wait for all child processes to be created:
+sleep 10
+
+while :; do
+	kill -USR1 $pids
+done &
+pids=$pids\ $!
+
+wait
+
+exit 1
diff --git a/tools/testing/selftests/arm64/fp/za-test.S b/tools/testing/selftests/arm64/fp/za-test.S
new file mode 100644
index 000000000000..99e1bb3b6b18
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-test.S
@@ -0,0 +1,426 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2021 ARM Limited.
+// Original author: Mark Brown <broonie at kernel.org>
+//
+// Scalable Matrix Extension ZA context switch test
+// Repeatedly writes unique test patterns into each ZA tile
+// and reads them back to verify integrity.
+//
+// for x in `seq 1 NR_CPUS`; do sve-test & pids=$pids\ $! ; done
+// (leave it running for as long as you want...)
+// kill $pids
+
+#include <asm/unistd.h>
+#include "assembler.h"
+#include "asm-offsets.h"
+
+.arch_extension sve
+
+#define MAXVL     2048
+#define MAXVL_B   (MAXVL / 8)
+
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * RDSVL X\nx, #\imm
+ */
+.macro rdsvl nx, imm
+	.inst	0x4bf5800			\
+		| (\imm << 5)			\
+		| (\nx)
+.endm
+
+.macro smstop
+	msr	S0_3_C4_C6_3, xzr
+.endm
+
+.macro smstart_za
+	msr	S0_3_C4_C5_3, xzr
+.endm
+
+// Declare some storage space to shadow ZA register contents and a
+// scratch buffer for a vector.
+.pushsection .text
+.data
+.align 4
+zaref:
+	.space	MAXVL_B * MAXVL_B
+scratch:
+	.space	MAXVL_B
+.popsection
+
+// Trivial memory copy: copy x2 bytes, starting at address x1, to address x0.
+// Clobbers x0-x3
+function memcpy
+	cmp	x2, #0
+	b.eq	1f
+0:	ldrb	w3, [x1], #1
+	strb	w3, [x0], #1
+	subs	x2, x2, #1
+	b.ne	0b
+1:	ret
+endfunction
+
+// Generate a test pattern for storage in ZA
+// x0: pid
+// x1: row in ZA
+// x2: generation
+
+// These values are used to constuct a 32-bit pattern that is repeated in the
+// scratch buffer as many times as will fit:
+// bits 31:28	generation number (increments once per test_loop)
+// bits 27:16	pid
+// bits 15: 8	row number
+// bits  7: 0	32-bit lane index
+
+function pattern
+	mov	w3, wzr
+	bfi	w3, w0, #16, #12	// PID
+	bfi	w3, w1, #8, #8		// Row
+	bfi	w3, w2, #28, #4		// Generation
+
+	ldr	x0, =scratch
+	mov	w1, #MAXVL_B / 4
+
+0:	str	w3, [x0], #4
+	add	w3, w3, #1		// Lane
+	subs	w1, w1, #1
+	b.ne	0b
+
+	ret
+endfunction
+
+// Get the address of shadow data for ZA horizontal vector xn
+.macro _adrza xd, xn, nrtmp
+	ldr	\xd, =zaref
+	rdsvl	\nrtmp, 1
+	madd	\xd, x\nrtmp, \xn, \xd
+.endm
+
+// Set up test pattern in a ZA horizontal vector
+// x0: pid
+// x1: row number
+// x2: generation
+function setup_za
+	mov	x4, x30
+	mov	x12, x1			// Use x12 for vector select
+
+	bl	pattern			// Get pattern in scratch buffer
+	_adrza	x0, x12, 2		// Shadow buffer pointer to x0 and x5
+	mov	x5, x0
+	ldr	x1, =scratch
+	bl	memcpy			// length set up in x2 by _adrza
+
+	_ldr_za 12, 5			// load vector w12 from pointer x5
+
+	ret	x4
+endfunction
+
+// Trivial memory compare: compare x2 bytes starting at address x0 with
+// bytes starting at address x1.
+// Returns only if all bytes match; otherwise, the program is aborted.
+// Clobbers x0-x5.
+function memcmp
+	cbz	x2, 2f
+
+	stp	x0, x1, [sp, #-0x20]!
+	str	x2, [sp, #0x10]
+
+	mov	x5, #0
+0:	ldrb	w3, [x0, x5]
+	ldrb	w4, [x1, x5]
+	add	x5, x5, #1
+	cmp	w3, w4
+	b.ne	1f
+	subs	x2, x2, #1
+	b.ne	0b
+
+1:	ldr	x2, [sp, #0x10]
+	ldp	x0, x1, [sp], #0x20
+	b.ne	barf
+
+2:	ret
+endfunction
+
+// Verify that a ZA vector matches its shadow in memory, else abort
+// x0: row number
+// Clobbers x0-x7 and x12.
+function check_za
+	mov	x3, x30
+
+	mov	x12, x0
+	_adrza	x5, x0, 6		// pointer to expected value in x5
+	mov	x4, x0
+	ldr	x7, =scratch		// x7 is scratch
+
+	mov	x0, x7			// Poison scratch
+	mov	x1, x6
+	bl	memfill_ae
+
+	_str_za 12, 7			// save vector w12 to pointer x7
+
+	mov	x0, x5
+	mov	x1, x7
+	mov	x2, x6
+	mov	x30, x3
+	b	memcmp
+endfunction
+
+// Any SME register modified here can cause corruption in the main
+// thread -- but *only* the locations modified here.
+function irritator_handler
+	// Increment the irritation signal count (x23):
+	ldr	x0, [x2, #ucontext_regs + 8 * 23]
+	add	x0, x0, #1
+	str	x0, [x2, #ucontext_regs + 8 * 23]
+
+	// Corrupt some random ZA data
+#if 0
+	adr	x0, .text + (irritator_handler - .text) / 16 * 16
+	movi	v0.8b, #1
+	movi	v9.16b, #2
+	movi	v31.8b, #3
+#endif
+
+	ret
+endfunction
+
+function terminate_handler
+	mov	w21, w0
+	mov	x20, x2
+
+	puts	"Terminated by signal "
+	mov	w0, w21
+	bl	putdec
+	puts	", no error, iterations="
+	ldr	x0, [x20, #ucontext_regs + 8 * 22]
+	bl	putdec
+	puts	", signals="
+	ldr	x0, [x20, #ucontext_regs + 8 * 23]
+	bl	putdecn
+
+	mov	x0, #0
+	mov	x8, #__NR_exit
+	svc	#0
+endfunction
+
+// w0: signal number
+// x1: sa_action
+// w2: sa_flags
+// Clobbers x0-x6,x8
+function setsignal
+	str	x30, [sp, #-((sa_sz + 15) / 16 * 16 + 16)]!
+
+	mov	w4, w0
+	mov	x5, x1
+	mov	w6, w2
+
+	add	x0, sp, #16
+	mov	x1, #sa_sz
+	bl	memclr
+
+	mov	w0, w4
+	add	x1, sp, #16
+	str	w6, [x1, #sa_flags]
+	str	x5, [x1, #sa_handler]
+	mov	x2, #0
+	mov	x3, #sa_mask_sz
+	mov	x8, #__NR_rt_sigaction
+	svc	#0
+
+	cbz	w0, 1f
+
+	puts	"sigaction failure\n"
+	b	.Labort
+
+1:	ldr	x30, [sp], #((sa_sz + 15) / 16 * 16 + 16)
+	ret
+endfunction
+
+// Main program entry point
+.globl _start
+function _start
+_start:
+	puts	"Streaming mode "
+	smstart_za
+
+	// Sanity-check and report the vector length
+
+	rdsvl	19, 8
+	cmp	x19, #128
+	b.lo	1f
+	cmp	x19, #2048
+	b.hi	1f
+	tst	x19, #(8 - 1)
+	b.eq	2f
+
+1:	puts	"bad vector length: "
+	mov	x0, x19
+	bl	putdecn
+	b	.Labort
+
+2:	puts	"vector length:\t"
+	mov	x0, x19
+	bl	putdec
+	puts	" bits\n"
+
+	// Obtain our PID, to ensure test pattern uniqueness between processes
+	mov	x8, #__NR_getpid
+	svc	#0
+	mov	x20, x0
+
+	puts	"PID:\t"
+	mov	x0, x20
+	bl	putdecn
+
+	mov	x23, #0		// Irritation signal count
+
+	mov	w0, #SIGINT
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGTERM
+	adr	x1, terminate_handler
+	mov	w2, #SA_SIGINFO
+	bl	setsignal
+
+	mov	w0, #SIGUSR1
+	adr	x1, irritator_handler
+	mov	w2, #SA_SIGINFO
+	orr	w2, w2, #SA_NODEFER
+	bl	setsignal
+
+	mov	x22, #0		// generation number, increments per iteration
+.Ltest_loop:
+	rdsvl	0, 8
+	cmp	x0, x19
+	b.ne	vl_barf
+
+	rdsvl	21, 1		// Set up ZA & shadow with test pattern
+0:	mov	x0, x20
+	sub	x1, x21, #1
+	mov	x2, x22
+	bl	setup_za
+	subs	x21, x21, #1
+	b.ne	0b
+
+	and	x8, x22, #127		// Every 128 interations...
+	cbz	x8, 0f
+	mov	x8, #__NR_getpid	// (otherwise minimal syscall)
+	b	1f
+0:
+	mov	x8, #__NR_sched_yield	// ...encourage preemption
+1:
+	svc	#0
+
+	mrs	x0, S3_3_C4_C2_2	// SVCR should have ZA=1,SM=0
+	and	x1, x0, #3
+	cmp	x1, #2
+	b.ne	svcr_barf
+
+	rdsvl	21, 1			// Verify that the data made it through
+	rdsvl	24, 1			// Verify that the data made it through
+0:	sub	x0, x24, x21
+	bl	check_za
+	subs	x21, x21, #1
+	bne	0b
+
+	add	x22, x22, #1	// Everything still working
+	b	.Ltest_loop
+
+.Labort:
+	mov	x0, #0
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+endfunction
+
+function barf
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// end hack
+	smstop
+	mov	x10, x0	// expected data
+	mov	x11, x1	// actual data
+	mov	x12, x2	// data size
+
+	puts	"Mismatch: PID="
+	mov	x0, x20
+	bl	putdec
+	puts	", iteration="
+	mov	x0, x22
+	bl	putdec
+	puts	", row="
+	mov	x0, x21
+	bl	putdecn
+	puts	"\tExpected ["
+	mov	x0, x10
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n\tGot      ["
+	mov	x0, x11
+	mov	x1, x12
+	bl	dumphex
+	puts	"]\n"
+
+	mov	x8, #__NR_getpid
+	svc	#0
+// fpsimd.c acitivty log dump hack
+//	ldr	w0, =0xdeadc0de
+//	mov	w8, #__NR_exit
+//	svc	#0
+// ^ end of hack
+	mov	x1, #SIGABRT
+	mov	x8, #__NR_kill
+	svc	#0
+//	mov	x8, #__NR_exit
+//	mov	x1, #1
+//	svc	#0
+endfunction
+
+function vl_barf
+	mov	x10, x0
+
+	puts	"Bad active VL: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
+
+function svcr_barf
+	mov	x10, x0
+
+	puts	"Bad SVCR: "
+	mov	x0, x10
+	bl	putdecn
+
+	mov	x8, #__NR_exit
+	mov	x1, #1
+	svc	#0
+endfunction
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:46 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:46 +0000
Subject: [PATCH v10 36/39] kselftest/arm64: signal: Add SME signal handling
 tests
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-37-broonie@kernel.org>

Add test cases for the SME signal handing ABI patterned off the SVE tests.
Due to the small size of the tests and the differences in ABI (especially
around needing to account for both streaming SVE and ZA) there is some code
duplication here.

We currently cover:
 - Reporting of the vector length.
 - Lack of support for changing vector length.
 - Presence and size of register state for streaming SVE and ZA.

As with the SVE tests we do not yet have any validation of register
contents.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../testing/selftests/arm64/signal/.gitignore |   2 +
 .../selftests/arm64/signal/test_signals.h     |   4 +
 .../arm64/signal/test_signals_utils.c         |   6 +
 .../testcases/fake_sigreturn_sme_change_vl.c  |  92 +++++++++++++
 .../arm64/signal/testcases/sme_trap_no_sm.c   |  38 ++++++
 .../signal/testcases/sme_trap_non_streaming.c |  45 ++++++
 .../arm64/signal/testcases/sme_trap_za.c      |  36 +++++
 .../selftests/arm64/signal/testcases/sme_vl.c |  68 +++++++++
 .../arm64/signal/testcases/ssve_regs.c        | 129 ++++++++++++++++++
 9 files changed, 420 insertions(+)
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/sme_vl.c
 create mode 100644 tools/testing/selftests/arm64/signal/testcases/ssve_regs.c

diff --git a/tools/testing/selftests/arm64/signal/.gitignore b/tools/testing/selftests/arm64/signal/.gitignore
index c1742755abb9..4de8eb26d4de 100644
--- a/tools/testing/selftests/arm64/signal/.gitignore
+++ b/tools/testing/selftests/arm64/signal/.gitignore
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mangle_*
 fake_sigreturn_*
+sme_*
+ssve_*
 sve_*
 !*.[ch]
diff --git a/tools/testing/selftests/arm64/signal/test_signals.h b/tools/testing/selftests/arm64/signal/test_signals.h
index f909b70d9e98..c70fdec7d7c4 100644
--- a/tools/testing/selftests/arm64/signal/test_signals.h
+++ b/tools/testing/selftests/arm64/signal/test_signals.h
@@ -34,11 +34,15 @@
 enum {
 	FSSBS_BIT,
 	FSVE_BIT,
+	FSME_BIT,
+	FSME_FA64_BIT,
 	FMAX_END
 };
 
 #define FEAT_SSBS		(1UL << FSSBS_BIT)
 #define FEAT_SVE		(1UL << FSVE_BIT)
+#define FEAT_SME		(1UL << FSME_BIT)
+#define FEAT_SME_FA64		(1UL << FSME_FA64_BIT)
 
 /*
  * A descriptor used to describe and configure a test case.
diff --git a/tools/testing/selftests/arm64/signal/test_signals_utils.c b/tools/testing/selftests/arm64/signal/test_signals_utils.c
index 5743897984b0..b588d10afd5b 100644
--- a/tools/testing/selftests/arm64/signal/test_signals_utils.c
+++ b/tools/testing/selftests/arm64/signal/test_signals_utils.c
@@ -27,6 +27,8 @@ static int sig_copyctx = SIGTRAP;
 static char const *const feats_names[FMAX_END] = {
 	" SSBS ",
 	" SVE ",
+	" SME ",
+	" FA64 ",
 };
 
 #define MAX_FEATS_SZ	128
@@ -268,6 +270,10 @@ int test_init(struct tdescr *td)
 			td->feats_supported |= FEAT_SSBS;
 		if (getauxval(AT_HWCAP) & HWCAP_SVE)
 			td->feats_supported |= FEAT_SVE;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+			td->feats_supported |= FEAT_SME;
+		if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+			td->feats_supported |= FEAT_SME_FA64;
 		if (feats_ok(td)) {
 			if (td->feats_required & td->feats_supported)
 				fprintf(stderr,
diff --git a/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
new file mode 100644
index 000000000000..7ed762b7202f
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Attempt to change the streaming SVE vector length in a signal
+ * handler, this is not supported and is expected to segfault.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least two VLs */
+	if (nvls < 2) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static int fake_sigreturn_ssve_change_vl(struct tdescr *td,
+					 siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *sve;
+
+	/* Get a signal context with a SME ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	if (head->size != sizeof(struct sve_context)) {
+		fprintf(stderr, "Register data present, aborting\n");
+		return 1;
+	}
+
+	sve = (struct sve_context *)head;
+
+	/* No changes are supported; init left us at minimum VL so go to max */
+	fprintf(stderr, "Attempting to change VL from %d to %d\n",
+		sve->vl, vls[0]);
+	sve->vl = vls[0];
+
+	fake_sigreturn(&sf, sizeof(sf), 0);
+
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "FAKE_SIGRETURN_SSVE_CHANGE",
+	.descr = "Attempt to change Streaming SVE VL",
+	.feats_required = FEAT_SME,
+	.sig_ok = SIGSEGV,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = fake_sigreturn_ssve_change_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
new file mode 100644
index 000000000000..f9d76ae32bba
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_no_sm.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using a streaming mode instruction without enabling it
+ * generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_no_sm_trigger(struct tdescr *td)
+{
+	/* SMSTART ZA ; ADDHA ZA0.S, P0/M, P0/M, Z0.S */
+	asm volatile(".inst 0xd503457f ; .inst 0xc0900000");
+
+	return 0;
+}
+
+int sme_trap_no_sm_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME trap without SM",
+	.descr = "Check that we get a SIGILL if we use streaming mode without enabling it",
+	.timeout = 3,
+	.feats_required = FEAT_SME,   /* We need a SMSTART ZA */
+	.sanity_disabled = true,
+	.trigger = sme_trap_no_sm_trigger,
+	.run = sme_trap_no_sm_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
new file mode 100644
index 000000000000..e469ae5348e3
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_non_streaming.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that using an instruction not supported in streaming mode
+ * traps when in streaming mode.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_non_streaming_trigger(struct tdescr *td)
+{
+	/*
+	 * The framework will handle SIGILL so we need to exit SM to
+	 * stop any other code triggering a further SIGILL down the
+	 * line from using a streaming-illegal instruction.
+	 */
+	asm volatile(".inst 0xd503437f; /* SMSTART ZA */ \
+		      cnt v0.16b, v0.16b; \
+                      .inst 0xd503447f  /* SMSTOP ZA */");
+
+	return 0;
+}
+
+int sme_trap_non_streaming_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME SM trap unsupported instruction",
+	.descr = "Check that we get a SIGILL if we use an unsupported instruction in streaming mode",
+	.feats_required = FEAT_SME,
+	.feats_incompatible = FEAT_SME_FA64,
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_non_streaming_trigger,
+	.run = sme_trap_non_streaming_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
new file mode 100644
index 000000000000..3a7747af4715
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_trap_za.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that accessing ZA without enabling it generates a SIGILL.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+int sme_trap_za_trigger(struct tdescr *td)
+{
+	/* ZERO ZA */
+	asm volatile(".inst 0xc00800ff");
+
+	return 0;
+}
+
+int sme_trap_za_run(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	return 1;
+}
+
+struct tdescr tde = {
+	.name = "SME ZA trap",
+	.descr = "Check that we get a SIGILL if we access ZA without enabling",
+	.timeout = 3,
+	.sanity_disabled = true,
+	.trigger = sme_trap_za_trigger,
+	.run = sme_trap_za_run,
+	.sig_ok = SIGILL,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/sme_vl.c b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
new file mode 100644
index 000000000000..13ff3b35cbaf
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/sme_vl.c
@@ -0,0 +1,68 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Check that the SME vector length reported in signal contexts is the
+ * expected one.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+unsigned int vl;
+
+static bool get_sme_vl(struct tdescr *td)
+{
+	int ret = prctl(PR_SME_GET_VL);
+	if (ret == -1)
+		return false;
+
+	vl = ret;
+
+	return true;
+}
+
+static int sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct za_context *za;
+
+	/* Get a signal context which should have a ZA frame in it */
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, ZA_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No ZA context\n");
+		return 1;
+	}
+	za = (struct za_context *)head;
+
+	if (za->vl != vl) {
+		fprintf(stderr, "ZA sigframe VL %u, expected %u\n",
+			za->vl, vl);
+		return 1;
+	} else {
+		fprintf(stderr, "got expected VL %u\n", vl);
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "SME VL",
+	.descr = "Check that we get the right SME VL reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = get_sme_vl,
+	.run = sme_vl,
+};
diff --git a/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
new file mode 100644
index 000000000000..44a08d43cd50
--- /dev/null
+++ b/tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
@@ -0,0 +1,129 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021 ARM Limited
+ *
+ * Verify that the streaming SVE register context in signal frames is
+ * set up as expected.
+ */
+
+#include <signal.h>
+#include <ucontext.h>
+#include <sys/prctl.h>
+
+#include "test_signals_utils.h"
+#include "testcases.h"
+
+struct fake_sigframe sf;
+static unsigned int vls[SVE_VQ_MAX];
+unsigned int nvls = 0;
+
+static bool sme_get_vls(struct tdescr *td)
+{
+	int vq, vl;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SVE_SET_VL, vq * 16);
+		if (vl == -1)
+			return false;
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		/* Skip missing VLs */
+		vq = sve_vq_from_vl(vl);
+
+		vls[nvls++] = vl;
+	}
+
+	/* We need at least one VL */
+	if (nvls < 1) {
+		fprintf(stderr, "Only %d VL supported\n", nvls);
+		return false;
+	}
+
+	return true;
+}
+
+static void setup_ssve_regs(void)
+{
+	/* SMSTART SM */
+	asm volatile(".inst 0x7f4303d5");
+
+	/* RDVL x16, #1 so we should have SVE regs; real data is TODO */
+	asm volatile(".inst 0x04bf5030" : : : "x16" );
+}
+
+static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
+			 unsigned int vl)
+{
+	size_t resv_sz, offset;
+	struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf);
+	struct sve_context *ssve;
+
+	fprintf(stderr, "Testing VL %d\n", vl);
+
+	if (prctl(PR_SME_SET_VL, vl) == -1) {
+		fprintf(stderr, "Failed to set VL\n");
+		return 1;
+	}
+
+	/* 
+	 * Get a signal context which should have a SVE frame and registers
+	 * in it.
+	 */
+	setup_ssve_regs();
+	if (!get_current_context(td, &sf.uc))
+		return 1;
+
+	resv_sz = GET_SF_RESV_SIZE(sf);
+	head = get_header(head, SVE_MAGIC, resv_sz, &offset);
+	if (!head) {
+		fprintf(stderr, "No SVE context\n");
+		return 1;
+	}
+
+	ssve = (struct sve_context *)head;
+	if (ssve->vl != vl) {
+		fprintf(stderr, "Got VL %d, expected %d\n", ssve->vl, vl);
+		return 1;
+	}
+
+	/* The actual size validation is done in get_current_context() */
+	fprintf(stderr, "Got expected size %u and VL %d\n",
+		head->size, ssve->vl);
+
+	return 0;
+}
+
+static int sme_regs(struct tdescr *td, siginfo_t *si, ucontext_t *uc)
+{
+	int i;
+
+	for (i = 0; i < nvls; i++) {
+		/*
+		 * TODO: the signal test helpers can't currently cope
+		 * with signal frames bigger than struct sigcontext,
+		 * skip VLs that will trigger that.
+		 */
+		if (vls[i] > 64)
+			continue;
+
+		if (do_one_sme_vl(td, si, uc, vls[i]))
+			return 1;
+	}
+
+	td->pass = 1;
+
+	return 0;
+}
+
+struct tdescr tde = {
+	.name = "Streaming SVE registers",
+	.descr = "Check that we get the right Streaming SVE registers reported",
+	.feats_required = FEAT_SME,
+	.timeout = 3,
+	.init = sme_get_vls,
+	.run = sme_regs,
+};
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:47 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:47 +0000
Subject: [PATCH v10 37/39] kselftest/arm64: Add streaming SVE to SVE ptrace
 tests
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-38-broonie@kernel.org>

In order to allow ptrace of streaming mode SVE registers we have added a
new regset for streaming mode which in isolation offers the same ABI as
regular SVE with a different vector type. Add this to the array of regsets
we handle, together with additional tests for the interoperation of the
two regsets.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/tools/testing/selftests/arm64/fp/sve-ptrace.c b/tools/testing/selftests/arm64/fp/sve-ptrace.c
index 90ba1d6a6781..fb74b11bab71 100644
--- a/tools/testing/selftests/arm64/fp/sve-ptrace.c
+++ b/tools/testing/selftests/arm64/fp/sve-ptrace.c
@@ -26,6 +26,10 @@
 #define NT_ARM_SVE 0x405
 #endif
 
+#ifndef NT_ARM_SSVE
+#define NT_ARM_SSVE 0x40b
+#endif
+
 struct vec_type {
 	const char *name;
 	unsigned long hwcap_type;
@@ -42,6 +46,13 @@ static const struct vec_type vec_types[] = {
 		.regset = NT_ARM_SVE,
 		.prctl_set = PR_SVE_SET_VL,
 	},
+	{
+		.name = "Streaming SVE",
+		.hwcap_type = AT_HWCAP2,
+		.hwcap = HWCAP2_SME,
+		.regset = NT_ARM_SSVE,
+		.prctl_set = PR_SME_SET_VL,
+	},
 };
 
 #define VL_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:48 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:48 +0000
Subject: [PATCH v10 38/39] kselftest/arm64: Add coverage for the ZA ptrace
 interface
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-39-broonie@kernel.org>

Add some basic coverage for the ZA ptrace interface, including walking
through all the vector lengths supported in the system. As with SVE we do
not currently validate the data all the way through to the running process.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 tools/testing/selftests/arm64/fp/.gitignore  |   1 +
 tools/testing/selftests/arm64/fp/Makefile    |   3 +-
 tools/testing/selftests/arm64/fp/za-ptrace.c | 354 +++++++++++++++++++
 3 files changed, 357 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/arm64/fp/za-ptrace.c

diff --git a/tools/testing/selftests/arm64/fp/.gitignore b/tools/testing/selftests/arm64/fp/.gitignore
index ead3197e720b..d98d3d48b504 100644
--- a/tools/testing/selftests/arm64/fp/.gitignore
+++ b/tools/testing/selftests/arm64/fp/.gitignore
@@ -8,4 +8,5 @@ sve-test
 ssve-test
 vec-syscfg
 vlset
+za-ptrace
 za-test
diff --git a/tools/testing/selftests/arm64/fp/Makefile b/tools/testing/selftests/arm64/fp/Makefile
index 38d2d0d5a0eb..807a8faf8d57 100644
--- a/tools/testing/selftests/arm64/fp/Makefile
+++ b/tools/testing/selftests/arm64/fp/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 CFLAGS += -I../../../../../usr/include/
-TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg
+TEST_GEN_PROGS := sve-ptrace sve-probe-vls vec-syscfg za-ptrace
 TEST_PROGS_EXTENDED := fp-pidbench fpsimd-test fpsimd-stress \
 	rdvl-sme rdvl-sve \
 	sve-test sve-stress \
@@ -27,5 +27,6 @@ vec-syscfg: vec-syscfg.o rdvl.o
 vlset: vlset.o
 za-test: za-test.o asm-utils.o
 	$(CC) -nostdlib $^ -o $@
+za-ptrace: za-ptrace.o
 
 include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/fp/za-ptrace.c b/tools/testing/selftests/arm64/fp/za-ptrace.c
new file mode 100644
index 000000000000..692c82624855
--- /dev/null
+++ b/tools/testing/selftests/arm64/fp/za-ptrace.c
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+#include <errno.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/auxv.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+#include "../../kselftest.h"
+
+/* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
+#ifndef NT_ARM_ZA
+#define NT_ARM_ZA 0x40c
+#endif
+
+#define EXPECTED_TESTS (((SVE_VQ_MAX - SVE_VQ_MIN) + 1) * 3)
+
+static void fill_buf(char *buf, size_t size)
+{
+	int i;
+
+	for (i = 0; i < size; i++)
+		buf[i] = random();
+}
+
+static int do_child(void)
+{
+	if (ptrace(PTRACE_TRACEME, -1, NULL, NULL))
+		ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno));
+
+	if (raise(SIGSTOP))
+		ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno));
+
+	return EXIT_SUCCESS;
+}
+
+static struct user_za_header *get_za(pid_t pid, void **buf, size_t *size)
+{
+	struct user_za_header *za;
+	void *p;
+	size_t sz = sizeof(*za);
+	struct iovec iov;
+
+	while (1) {
+		if (*size < sz) {
+			p = realloc(*buf, sz);
+			if (!p) {
+				errno = ENOMEM;
+				goto error;
+			}
+
+			*buf = p;
+			*size = sz;
+		}
+
+		iov.iov_base = *buf;
+		iov.iov_len = sz;
+		if (ptrace(PTRACE_GETREGSET, pid, NT_ARM_ZA, &iov))
+			goto error;
+
+		za = *buf;
+		if (za->size <= sz)
+			break;
+
+		sz = za->size;
+	}
+
+	return za;
+
+error:
+	return NULL;
+}
+
+static int set_za(pid_t pid, const struct user_za_header *za)
+{
+	struct iovec iov;
+
+	iov.iov_base = (void *)za;
+	iov.iov_len = za->size;
+	return ptrace(PTRACE_SETREGSET, pid, NT_ARM_ZA, &iov);
+}
+
+/* Validate attempting to set the specfied VL via ptrace */
+static void ptrace_set_get_vl(pid_t child, unsigned int vl, bool *supported)
+{
+	struct user_za_header za;
+	struct user_za_header *new_za = NULL;
+	size_t new_za_size = 0;
+	int ret, prctl_vl;
+
+	*supported = false;
+
+	/* Check if the VL is supported in this process */
+	prctl_vl = prctl(PR_SME_SET_VL, vl);
+	if (prctl_vl == -1)
+		ksft_exit_fail_msg("prctl(PR_SME_SET_VL) failed: %s (%d)\n",
+				   strerror(errno), errno);
+
+	/* If the VL is not supported then a supported VL will be returned */
+	*supported = (prctl_vl == vl);
+
+	/* Set the VL by doing a set with no register payload */
+	memset(&za, 0, sizeof(za));
+	za.size = sizeof(za);
+	za.vl = vl;
+	ret = set_za(child, &za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u\n", vl);
+		return;
+	}
+
+	/*
+	 * Read back the new register state and verify that we have the
+	 * same VL that we got from prctl() on ourselves.
+	 */
+	if (!get_za(child, (void **)&new_za, &new_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u\n", vl);
+		return;
+	}
+
+	ksft_test_result(new_za->vl = prctl_vl, "Set VL %u\n", vl);
+
+	free(new_za);
+}
+
+/* Validate attempting to set no ZA data and read it back */
+static void ptrace_set_no_data(pid_t child, unsigned int vl)
+{
+	void *read_buf = NULL;
+	struct user_za_header write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	int ret;
+
+	/* Set up some data and write it out */
+	memset(&write_za, 0, sizeof(write_za));
+	write_za.size = ZA_PT_ZA_OFFSET;
+	write_za.vl = vl;
+
+	ret = set_za(child, &write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u no data\n", vl);
+		return;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u no data\n", vl);
+		return;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za.size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za.size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(read_za->size == write_za.size,
+			 "Disabled ZA for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+}
+
+/* Validate attempting to set data and read it back */
+static void ptrace_set_get_data(pid_t child, unsigned int vl)
+{
+	void *write_buf;
+	void *read_buf = NULL;
+	struct user_za_header *write_za;
+	struct user_za_header *read_za;
+	size_t read_za_size = 0;
+	unsigned int vq = sve_vq_from_vl(vl);
+	int ret;
+	size_t data_size;
+
+	data_size = ZA_PT_SIZE(vq);
+	write_buf = malloc(data_size);
+	if (!write_buf) {
+		ksft_test_result_fail("Error allocating %d byte buffer for VL %u\n",
+				      data_size, vl);
+		return;
+	}
+	write_za = write_buf;
+
+	/* Set up some data and write it out */
+	memset(write_za, 0, data_size);
+	write_za->size = data_size;
+	write_za->vl = vl;
+
+	fill_buf(write_buf + ZA_PT_ZA_OFFSET, ZA_PT_ZA_SIZE(vq));
+
+	ret = set_za(child, write_za);
+	if (ret != 0) {
+		ksft_test_result_fail("Failed to set VL %u data\n", vl);
+		goto out;
+	}
+
+	/* Read the data back */
+	if (!get_za(child, (void **)&read_buf, &read_za_size)) {
+		ksft_test_result_fail("Failed to read VL %u data\n", vl);
+		goto out;
+	}
+	read_za = read_buf;
+
+	/* We might read more data if there's extensions we don't know */
+	if (read_za->size < write_za->size) {
+		ksft_test_result_fail("VL %u wrote %d bytes, only read %d\n",
+				      vl, write_za->size, read_za->size);
+		goto out_read;
+	}
+
+	ksft_test_result(memcmp(write_buf + ZA_PT_ZA_OFFSET,
+				read_buf + ZA_PT_ZA_OFFSET,
+				ZA_PT_ZA_SIZE(vq)) == 0,
+			 "Data match for VL %u\n", vl);
+
+out_read:
+	free(read_buf);
+out:
+	free(write_buf);
+}
+
+static int do_parent(pid_t child)
+{
+	int ret = EXIT_FAILURE;
+	pid_t pid;
+	int status;
+	siginfo_t si;
+	unsigned int vq, vl;
+	bool vl_supported;
+
+	/* Attach to the child */
+	while (1) {
+		int sig;
+
+		pid = wait(&status);
+		if (pid == -1) {
+			perror("wait");
+			goto error;
+		}
+
+		/*
+		 * This should never happen but it's hard to flag in
+		 * the framework.
+		 */
+		if (pid != child)
+			continue;
+
+		if (WIFEXITED(status) || WIFSIGNALED(status))
+			ksft_exit_fail_msg("Child died unexpectedly\n");
+
+		if (!WIFSTOPPED(status))
+			goto error;
+
+		sig = WSTOPSIG(status);
+
+		if (ptrace(PTRACE_GETSIGINFO, pid, NULL, &si)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			if (errno == EINVAL) {
+				sig = 0; /* bust group-stop */
+				goto cont;
+			}
+
+			ksft_test_result_fail("PTRACE_GETSIGINFO: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+
+		if (sig == SIGSTOP && si.si_code == SI_TKILL &&
+		    si.si_pid == pid)
+			break;
+
+	cont:
+		if (ptrace(PTRACE_CONT, pid, NULL, sig)) {
+			if (errno == ESRCH)
+				goto disappeared;
+
+			ksft_test_result_fail("PTRACE_CONT: %s\n",
+					      strerror(errno));
+			goto error;
+		}
+	}
+
+	/* Step through every possible VQ */
+	for (vq = SVE_VQ_MIN; vq <= SVE_VQ_MAX; vq++) {
+		vl = sve_vl_from_vq(vq);
+
+		/* First, try to set this vector length */
+		ptrace_set_get_vl(child, vl, &vl_supported);
+
+		/* If the VL is supported validate data set/get */
+		if (vl_supported) {
+			ptrace_set_no_data(child, vl);
+			ptrace_set_get_data(child, vl);
+		} else {
+			ksft_test_result_skip("Disabled ZA for VL %u\n", vl);
+			ksft_test_result_skip("Get and set data for VL %u\n",
+					      vl);
+		}
+	}
+
+	ret = EXIT_SUCCESS;
+
+error:
+	kill(child, SIGKILL);
+
+disappeared:
+	return ret;
+}
+
+int main(void)
+{
+	int ret = EXIT_SUCCESS;
+	pid_t child;
+
+	srandom(getpid());
+
+	ksft_print_header();
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME)) {
+		ksft_set_plan(1);
+		ksft_exit_skip("SME not available\n");
+	}
+
+	ksft_set_plan(EXPECTED_TESTS);
+
+	child = fork();
+	if (!child)
+		return do_child();
+
+	if (do_parent(child))
+		ret = EXIT_FAILURE;
+
+	ksft_print_cnts();
+
+	return ret;
+}
-- 
2.30.2



From broonie at kernel.org  Wed Jan 26 07:27:49 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:27:49 +0000
Subject: [PATCH v10 39/39] kselftest/arm64: Add SME support to syscall ABI test
In-Reply-To: <20220126152749.233712-1-broonie@kernel.org>
References: <20220126152749.233712-1-broonie@kernel.org>
Message-ID: <20220126152749.233712-40-broonie@kernel.org>

For every possible combination of SVE and SME vector length verify that for
each possible value of SVCR after a syscall we leave streaming mode and ZA
is preserved. We don't need to take account of any streaming/non streaming
SVE vector length changes in the assembler code since the store instructions
will handle the vector length for us. We log if the system supports FA64 and
only try to set FFR in streaming mode if it does.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/abi/syscall-abi-asm.S     |  69 +++++-
 .../testing/selftests/arm64/abi/syscall-abi.c | 204 ++++++++++++++++--
 .../testing/selftests/arm64/abi/syscall-abi.h |  15 ++
 3 files changed, 265 insertions(+), 23 deletions(-)
 create mode 100644 tools/testing/selftests/arm64/abi/syscall-abi.h

diff --git a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
index 983467cfcee0..bc70e04224bf 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
+++ b/tools/testing/selftests/arm64/abi/syscall-abi-asm.S
@@ -9,15 +9,42 @@
 // invoked is configured in x8 of the input GPR data.
 //
 // x0:	SVE VL, 0 for FP only
+// x1:	SME VL
 //
 //	GPRs:	gpr_in, gpr_out
 //	FPRs:	fpr_in, fpr_out
 //	Zn:	z_in, z_out
 //	Pn:	p_in, p_out
 //	FFR:	ffr_in, ffr_out
+//	ZA:	za_in, za_out
+//	SVCR:	svcr_in, svcr_out
+
+#include "syscall-abi.h"
 
 .arch_extension sve
 
+/*
+ * LDR (vector to ZA array):
+ *	LDR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _ldr_za nw, nxbase, offset=0
+	.inst	0xe1000000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
+/*
+ * STR (vector from ZA array):
+ *	STR ZA[\nw, #\offset], [X\nxbase, #\offset, MUL VL]
+ */
+.macro _str_za nw, nxbase, offset=0
+	.inst	0xe1200000			\
+		| (((\nw) & 3) << 13)		\
+		| ((\nxbase) << 5)		\
+		| ((\offset) & 7)
+.endm
+
 .globl do_syscall
 do_syscall:
 	// Store callee saved registers x19-x29 (80 bytes) plus x0 and x1
@@ -30,6 +57,24 @@ do_syscall:
 	stp	x25, x26, [sp, #80]
 	stp	x27, x28, [sp, #96]
 
+	// Set SVCR if we're doing SME
+	cbz	x1, 1f
+	adrp	x2, svcr_in
+	ldr	x2, [x2, :lo12:svcr_in]
+	msr	S3_3_C4_C2_2, x2
+1:
+
+	// Load ZA if it's enabled - uses x12 as scratch due to SME LDR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_in
+2:	_ldr_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Load GPRs x8-x28, and save our SP/FP for later comparison
 	ldr	x2, =gpr_in
 	add	x2, x2, #64
@@ -68,7 +113,7 @@ do_syscall:
 	ldp	q30, q31, [x2, #16 * 30]
 1:
 
-	// Load the SVE registers if we're doing SVE
+	// Load the SVE registers if we're doing SVE/SME
 	cbz	x0, 1f
 
 	ldr	x2, =z_in
@@ -105,9 +150,13 @@ do_syscall:
 	ldr	z30, [x2, #30, MUL VL]
 	ldr	z31, [x2, #31, MUL VL]
 
+	// Only set a non-zero FFR, test patterns must be zero since the
+	// syscall should clear it - this lets us handle FA64.
 	ldr	x2, =ffr_in
+	cbz	x2, 2f
 	ldr	p0, [x2, #0]
 	wrffr	p0.b
+2:
 
 	ldr	x2, =p_in
 	ldr	p0, [x2, #0, MUL VL]
@@ -169,6 +218,24 @@ do_syscall:
 	stp	q28, q29, [x2, #16 * 28]
 	stp	q30, q31, [x2, #16 * 30]
 
+	// Save SVCR if we're doing SME
+	cbz	x1, 1f
+	mrs	x2, S3_3_C4_C2_2
+	adrp	x3, svcr_out
+	str	x2, [x3, :lo12:svcr_out]
+1:
+
+	// Save ZA if it's enabled - uses x12 as scratch due to SME STR
+	tbz	x2, #SVCR_ZA_SHIFT, 1f
+	mov	w12, #0
+	ldr	x2, =za_out
+2:	_str_za 12, 2
+	add	x2, x2, x1
+	add	x12, x12, #1
+	cmp	x1, x12
+	bne	2b
+1:
+
 	// Save the SVE state if we have some
 	cbz	x0, 1f
 
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.c b/tools/testing/selftests/arm64/abi/syscall-abi.c
index 1e13b7523918..b632bfe9e022 100644
--- a/tools/testing/selftests/arm64/abi/syscall-abi.c
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.c
@@ -18,9 +18,13 @@
 
 #include "../../kselftest.h"
 
+#include "syscall-abi.h"
+
 #define NUM_VL ((SVE_VQ_MAX - SVE_VQ_MIN) + 1)
 
-extern void do_syscall(int sve_vl);
+static int default_sme_vl;
+
+extern void do_syscall(int sve_vl, int sme_vl);
 
 static void fill_random(void *buf, size_t size)
 {
@@ -48,14 +52,15 @@ static struct syscall_cfg {
 uint64_t gpr_in[NUM_GPR];
 uint64_t gpr_out[NUM_GPR];
 
-static void setup_gpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(gpr_in, sizeof(gpr_in));
 	gpr_in[8] = cfg->syscall_nr;
 	memset(gpr_out, 0, sizeof(gpr_out));
 }
 
-static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_gpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl, uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -79,13 +84,15 @@ static int check_gpr(struct syscall_cfg *cfg, int sve_vl)
 uint64_t fpr_in[NUM_FPR * 2];
 uint64_t fpr_out[NUM_FPR * 2];
 
-static void setup_fpr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
 	fill_random(fpr_in, sizeof(fpr_in));
 	memset(fpr_out, 0, sizeof(fpr_out));
 }
 
-static int check_fpr(struct syscall_cfg *cfg, int sve_vl)
+static int check_fpr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	int errors = 0;
 	int i;
@@ -109,13 +116,15 @@ static uint8_t z_zero[__SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 uint8_t z_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_z(struct syscall_cfg *cfg, int sve_vl)
+static void setup_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(z_in, sizeof(z_in));
 	fill_random(z_out, sizeof(z_out));
 }
 
-static int check_z(struct syscall_cfg *cfg, int sve_vl)
+static int check_z(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vl;
 	int errors = 0;
@@ -126,13 +135,17 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 
 	/*
 	 * After a syscall the low 128 bits of the Z registers should
-	 * be preserved and the rest be zeroed or preserved.
+	 * be preserved and the rest be zeroed or preserved, except if
+	 * we were in streaming mode in which case the low 128 bits may
+	 * also be cleared by the transition out of streaming mode.
 	 */
 	for (i = 0; i < SVE_NUM_ZREGS; i++) {
 		void *in = &z_in[reg_size * i];
 		void *out = &z_out[reg_size * i];
 
-		if (memcmp(in, out, SVE_VQ_BYTES) != 0) {
+		if ((memcmp(in, out, SVE_VQ_BYTES) != 0) &&
+		    !((svcr & SVCR_SM_MASK) &&
+		      memcmp(z_zero, out, SVE_VQ_BYTES) == 0)) {
 			ksft_print_msg("%s SVE VL %d Z%d low 128 bits changed\n",
 				       cfg->name, sve_vl, i);
 			errors++;
@@ -145,13 +158,15 @@ static int check_z(struct syscall_cfg *cfg, int sve_vl)
 uint8_t p_in[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t p_out[SVE_NUM_PREGS * __SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_p(struct syscall_cfg *cfg, int sve_vl)
+static void setup_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	fill_random(p_in, sizeof(p_in));
 	fill_random(p_out, sizeof(p_out));
 }
 
-static int check_p(struct syscall_cfg *cfg, int sve_vl)
+static int check_p(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		   uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2; /* 1 bit per VL byte */
 
@@ -175,8 +190,19 @@ static int check_p(struct syscall_cfg *cfg, int sve_vl)
 uint8_t ffr_in[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 uint8_t ffr_out[__SVE_PREG_SIZE(SVE_VQ_MAX)];
 
-static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
+static void setup_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
 {
+	/*
+	 * If we are in streaming mode and do not have FA64 then FFR
+	 * is unavailable.
+	 */
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)) {
+		memset(&ffr_in, 0, sizeof(ffr_in));
+		return;
+	}
+
 	/*
 	 * It is only valid to set a contiguous set of bits starting
 	 * at 0.  For now since we're expecting this to be cleared by
@@ -186,7 +212,8 @@ static void setup_ffr(struct syscall_cfg *cfg, int sve_vl)
 	fill_random(ffr_out, sizeof(ffr_out));
 }
 
-static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
+static int check_ffr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
 {
 	size_t reg_size = sve_vq_from_vl(sve_vl) * 2;  /* 1 bit per VL byte */
 	int errors = 0;
@@ -195,6 +222,10 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	if (!sve_vl)
 		return 0;
 
+	if ((svcr & SVCR_SM_MASK) &&
+	    !(getauxval(AT_HWCAP2) & HWCAP2_SME_FA64))
+		return 0;
+
 	/* After a syscall the P registers should be preserved or zeroed */
 	for (i = 0; i < reg_size; i++)
 		if (ffr_out[i] && (ffr_in[i] != ffr_out[i]))
@@ -206,8 +237,65 @@ static int check_ffr(struct syscall_cfg *cfg, int sve_vl)
 	return errors;
 }
 
-typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl);
-typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl);
+uint64_t svcr_in, svcr_out;
+
+static void setup_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	svcr_in = svcr;
+}
+
+static int check_svcr(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		      uint64_t svcr)
+{
+	int errors = 0;
+
+	if (svcr_out & SVCR_SM_MASK) {
+		ksft_print_msg("%s Still in SM, SVCR %llx\n",
+			       cfg->name, svcr_out);
+		errors++;
+	}
+
+	if ((svcr_in & SVCR_ZA_MASK) != (svcr_out & SVCR_ZA_MASK)) {
+		ksft_print_msg("%s PSTATE.ZA changed, SVCR %llx != %llx\n",
+			       cfg->name, svcr_in, svcr_out);
+		errors++;
+	}
+
+	return errors;
+}
+
+uint8_t za_in[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+uint8_t za_out[SVE_NUM_PREGS * __SVE_ZREG_SIZE(SVE_VQ_MAX)];
+
+static void setup_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		     uint64_t svcr)
+{
+	fill_random(za_in, sizeof(za_in));
+	memset(za_out, 0, sizeof(za_out));
+}
+
+static int check_za(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
+{
+	size_t reg_size = sme_vl * sme_vl;
+	int errors = 0;
+
+	if (!(svcr & SVCR_ZA_MASK))
+		return 0;
+
+	if (memcmp(za_in, za_out, reg_size) != 0) {
+		ksft_print_msg("SME VL %d ZA does not match\n", sme_vl);
+		errors++;
+	}
+
+	return errors;
+}
+
+typedef void (*setup_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			 uint64_t svcr);
+typedef int (*check_fn)(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+			uint64_t svcr);
 
 /*
  * Each set of registers has a setup function which is called before
@@ -225,20 +313,23 @@ static struct {
 	{ setup_z, check_z },
 	{ setup_p, check_p },
 	{ setup_ffr, check_ffr },
+	{ setup_svcr, check_svcr },
+	{ setup_za, check_za },
 };
 
-static bool do_test(struct syscall_cfg *cfg, int sve_vl)
+static bool do_test(struct syscall_cfg *cfg, int sve_vl, int sme_vl,
+		    uint64_t svcr)
 {
 	int errors = 0;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		regset[i].setup(cfg, sve_vl);
+		regset[i].setup(cfg, sve_vl, sme_vl, svcr);
 
-	do_syscall(sve_vl);
+	do_syscall(sve_vl, sme_vl);
 
 	for (i = 0; i < ARRAY_SIZE(regset); i++)
-		errors += regset[i].check(cfg, sve_vl);
+		errors += regset[i].check(cfg, sve_vl, sme_vl, svcr);
 
 	return errors == 0;
 }
@@ -246,9 +337,10 @@ static bool do_test(struct syscall_cfg *cfg, int sve_vl)
 static void test_one_syscall(struct syscall_cfg *cfg)
 {
 	int sve_vq, sve_vl;
+	int sme_vq, sme_vl;
 
 	/* FPSIMD only case */
-	ksft_test_result(do_test(cfg, 0),
+	ksft_test_result(do_test(cfg, 0, default_sme_vl, 0),
 			 "%s FPSIMD\n", cfg->name);
 
 	if (!(getauxval(AT_HWCAP) & HWCAP_SVE))
@@ -265,8 +357,36 @@ static void test_one_syscall(struct syscall_cfg *cfg)
 		if (sve_vq != sve_vq_from_vl(sve_vl))
 			sve_vq = sve_vq_from_vl(sve_vl);
 
-		ksft_test_result(do_test(cfg, sve_vl),
+		ksft_test_result(do_test(cfg, sve_vl, default_sme_vl, 0),
 				 "%s SVE VL %d\n", cfg->name, sve_vl);
+
+		if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+			continue;
+
+		for (sme_vq = SVE_VQ_MAX; sme_vq > 0; --sme_vq) {
+			sme_vl = prctl(PR_SME_SET_VL, sme_vq * 16);
+			if (sme_vl == -1)
+				ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+						   strerror(errno), errno);
+
+			sme_vl &= PR_SME_VL_LEN_MASK;
+
+			if (sme_vq != sve_vq_from_vl(sme_vl))
+				sme_vq = sve_vq_from_vl(sme_vl);
+
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK | SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM+ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_SM_MASK),
+					 "%s SVE VL %d/SME VL %d SM\n",
+					 cfg->name, sve_vl, sme_vl);
+			ksft_test_result(do_test(cfg, sve_vl, sme_vl,
+						 SVCR_ZA_MASK),
+					 "%s SVE VL %d/SME VL %d ZA\n",
+					 cfg->name, sve_vl, sme_vl);
+		}
 	}
 }
 
@@ -299,14 +419,54 @@ int sve_count_vls(void)
 	return vl_count;
 }
 
+int sme_count_vls(void)
+{
+	unsigned int vq;
+	int vl_count = 0;
+	int vl;
+
+	if (!(getauxval(AT_HWCAP2) & HWCAP2_SME))
+		return 0;
+
+	/* Ensure we configure a SME VL, used to flag if SVCR is set */
+	default_sme_vl = 16;
+
+	/*
+	 * Enumerate up to SVE_VQ_MAX vector lengths
+	 */
+	for (vq = SVE_VQ_MAX; vq > 0; --vq) {
+		vl = prctl(PR_SME_SET_VL, vq * 16);
+		if (vl == -1)
+			ksft_exit_fail_msg("PR_SME_SET_VL failed: %s (%d)\n",
+					   strerror(errno), errno);
+
+		vl &= PR_SME_VL_LEN_MASK;
+
+		if (vq != sve_vq_from_vl(vl))
+			vq = sve_vq_from_vl(vl);
+
+		vl_count++;
+	}
+
+	return vl_count;
+}
+
 int main(void)
 {
 	int i;
+	int tests = 1;  /* FPSIMD */
 
 	srandom(getpid());
 
 	ksft_print_header();
-	ksft_set_plan(ARRAY_SIZE(syscalls) * (sve_count_vls() + 1));
+	tests += sve_count_vls();
+	tests += (sve_count_vls() * sme_count_vls()) * 3;
+	ksft_set_plan(ARRAY_SIZE(syscalls) * tests);
+
+	if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
+		ksft_print_msg("SME with FA64\n");
+	else if (getauxval(AT_HWCAP2) & HWCAP2_SME)
+		ksft_print_msg("SME without FA64\n");
 
 	for (i = 0; i < ARRAY_SIZE(syscalls); i++)
 		test_one_syscall(&syscalls[i]);
diff --git a/tools/testing/selftests/arm64/abi/syscall-abi.h b/tools/testing/selftests/arm64/abi/syscall-abi.h
new file mode 100644
index 000000000000..bda5a87ad381
--- /dev/null
+++ b/tools/testing/selftests/arm64/abi/syscall-abi.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2021 ARM Limited.
+ */
+
+#ifndef SYSCALL_ABI_H
+#define SYSCALL_ABI_H
+
+#define SVCR_ZA_MASK		2
+#define SVCR_SM_MASK		1
+
+#define SVCR_ZA_SHIFT		1
+#define SVCR_SM_SHIFT		0
+
+#endif
-- 
2.30.2



From mathieu.poirier at linaro.org  Wed Jan 26 07:34:37 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Wed, 26 Jan 2022 08:34:37 -0700
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <24c09945-bcda-81e4-f53c-af871f696094@quicinc.com>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
 <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
 <20220121171552.GA1811357@p14s>
 <24c09945-bcda-81e4-f53c-af871f696094@quicinc.com>
Message-ID: <20220126153437.GA2144852@p14s>

On Wed, Jan 26, 2022 at 03:07:38PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
> 
> Good afternoon.
> 
> On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
> > Hey Jinlong,
> > 
> > On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> > > Hi Mathieu,
> > > 
> > > Good Day.
> > > 
> > > On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > > > [...]
> > > > 
> > > > > > > > +
> > > > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > > > +{
> > > > > > > > +    static int traceid = TPDM_TRACE_ID_START;
> > > > > > > > +
> > > > > > > > +    drvdata->traceid = traceid++;
> > > > > > > > +}
> > > > > > > I have been specific on how to properly do this in the last revision.  Given the
> > > > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > > > > 
> > > > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > > > process it before the holidays.
> > > > > > > 
> > > > > > > Thanks,
> > > > > > > Mathieu
> > > > > > Hi Mathieu,
> > > > > > 
> > > > > > Sorry, not addressed your previous comments here.
> > > > > > 
> > > > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > > > Architecture specification v3.0
> > > > > 
> > > > Correct
> > > > 
> > > > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > > > our internal device. About 80 ids are already used.
> > > > > > 
> > > > > > Some components have fixed trace id in HW. If we use functions below to
> > > > > > count the trace id, there will be conflict to other components.
> > > > > > 
> > > > > > Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
> > > > > > components ? And handle trace ids in its' own driver ?
> > > > > > 
> > > > > This will limit systems to 15 cores - some have more!
> > > > > 
> > > > Correct
> > > > 
> > > > > > static inline int coresight_get_system_trace_id(int id)
> > > > > > {
> > > > > >            /* Start system IDs above the highest per CPU trace ID. */
> > > > > >            return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > > > }
> > > > Looking at my own suggestion again this won't work since it returns the same traceID
> > > > when called multiple times.
> > > > 
> > > > For this patchset and _without_ taking into account internal devices that have
> > > > their traceID set in HW:
> > > > 
> > > > 1. Define a bitmask that is 7 bit wide.
> > > Should it be a 128 bit wide bitmask? (0--127)?
> > Yes, you are correct.
> > 
> > > > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > > > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > > > first available bit after cpumask_last(cpu_possible_mask) + 1.
> > > Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> > > Return the first zero bit position as the trace id and set the bit.
> > I need to clarify something with Mike on this - I will get back to you on
> > Monday.
> Do you have more comments on this ?

I just received clarifications on this - there is no need to continue enacting
the current scheme and as such reserving bits following the above formula will
not be needed either.  Simply assigning free traceIDs based on request will
work just fine.  

That of course is taking into account that 0x0, 0x1 and 0x70 - 0x7f are
reserved.  0x1 is currently used for STM and should eventually be fixed to
simply request a traceID the same way any other component do.  You can fix it as
part of this set but it is not mandatory.

Let me know if there are things I haven't been clear on.

Thanks,
Mathieu

> > 
> > > > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > > > clears the bit in the mask corresponding to @id.
> > > > 
> > > > For now that should work.
> > > > 
> > > > > > static inline int coresight_get_trace_id(int cpu)
> > > > > > {
> > > > > >        /*
> > > > > >         * A trace ID of value 0 is invalid, so let's start at some
> > > > > >         * random value that fits in 7 bits and go from there.  Since
> > > > > >         * the common convention is to have data trace IDs be I(N) + 1,
> > > > > >         * set instruction trace IDs as a function of the CPU number.
> > > > > >         */
> > > > > >        return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > > > }
> > > > > > 
> > > > > This fixed relationship between cpu and trace ID is used in the perf
> > > > > tooling to populate the elements in the perf.data file to correctly
> > > > > allow association between CPU and trace data, and thus allow correct
> > > > > trace decode.
> > > > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > > > perf header - theoretically we should be able to change the allocation scheme
> > > > without impacting the decoding process.
> > > > 
> > > > > It should be possible to create another more dynamic mapping scheme -
> > > > > but this must include a way to support the perf requirements too.
> > > > > 
> > > > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > > > For now what I have suggested above should be sufficient to provide an
> > > > in-between solution that doesn't hold back this patchset.
> > > > 
> > > > That being said, we need to start thinking about the best way to do this.  I
> > > > will put a patchset together in the new year that aims in that direction.
> > > > 
> > > > > Regards
> > > > > 
> > > > > Mike
> > > > > 
> > > > > > Thanks
> > > > > > 
> > > > > > Jinlong Mao
> > > > > > 
> > > > > > > > +
> > > > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > > > +{
> > > > > > > > +    struct device *dev = &adev->dev;
> > > > > > > > +    struct coresight_platform_data *pdata;
> > > > > > > > +    struct tpdm_drvdata *drvdata;
> > > > > > > > +    struct coresight_desc desc = { 0 };
> > > > > > > > +
> > > > > > > > +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > > > +    if (!desc.name)
> > > > > > > > +            return -ENOMEM;
> > > > > > > > +    pdata = coresight_get_platform_data(dev);
> > > > > > > > +    if (IS_ERR(pdata))
> > > > > > > > +            return PTR_ERR(pdata);
> > > > > > > > +    adev->dev.platform_data = pdata;
> > > > > > > > +
> > > > > > > > +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > > > +    if (!drvdata)
> > > > > > > > +            return -ENOMEM;
> > > > > > > > +    drvdata->dev = &adev->dev;
> > > > > > > > +    dev_set_drvdata(dev, drvdata);
> > > > > > > > +
> > > > > > > > +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > > > +    if (!drvdata->base)
> > > > > > > > +            return -ENOMEM;
> > > > > > > > +
> > > > > > > > +    mutex_init(&drvdata->lock);
> > > > > > > > +
> > > > > > > > +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > > > +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > > > +    desc.ops = &tpdm_cs_ops;
> > > > > > > > +    desc.pdata = adev->dev.platform_data;
> > > > > > > > +    desc.dev = &adev->dev;
> > > > > > > > +    drvdata->csdev = coresight_register(&desc);
> > > > > > > > +    if (IS_ERR(drvdata->csdev))
> > > > > > > > +            return PTR_ERR(drvdata->csdev);
> > > > > > > > +
> > > > > > > > +    tpdm_init_default_data(drvdata);
> > > > > > > > +    pm_runtime_put(&adev->dev);
> > > > > > > > +
> > > > > > > > +    return 0;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > > > +{
> > > > > > > > +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > > > +
> > > > > > > > +    coresight_unregister(drvdata->csdev);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > > > +    {
> > > > > > > > +            .id = 0x000f0e00,
> > > > > > > > +            .mask = 0x000fff00,
> > > > > > > > +    },
> > > > > > > > +    { 0, 0},
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > > > +    .drv = {
> > > > > > > > +            .name   = "coresight-tpdm",
> > > > > > > > +            .owner  = THIS_MODULE,
> > > > > > > > +            .suppress_bind_attrs = true,
> > > > > > > > +    },
> > > > > > > > +    .probe          = tpdm_probe,
> > > > > > > > +    .id_table       = tpdm_ids,
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +module_amba_driver(tpdm_driver);
> > > > > > > > +
> > > > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > > > new file mode 100644
> > > > > > > > index 000000000000..980ae90ff1c8
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > > > @@ -0,0 +1,31 @@
> > > > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > > > +/*
> > > > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > > > +
> > > > > > > > +/* Default value of the traceid */
> > > > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > > > +
> > > > > > > > +/**
> > > > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > > > + * @base:       memory mapped base address for this component.
> > > > > > > > + * @dev:        The device entity associated to this component.
> > > > > > > > + * @csdev:      component vitals needed by the framework.
> > > > > > > > + * @lock:       lock for the enable value.
> > > > > > > > + * @enable:     enable status of the component.
> > > > > > > > + * @traceid:    value of the current ID for this component.
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > +struct tpdm_drvdata {
> > > > > > > > +    void __iomem            *base;
> > > > > > > > +    struct device           *dev;
> > > > > > > > +    struct coresight_device *csdev;
> > > > > > > > +    struct mutex            lock;
> > > > > > > > +    bool                    enable;
> > > > > > > > +    int                     traceid;
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > > > --- a/include/linux/coresight.h
> > > > > > > > +++ b/include/linux/coresight.h
> > > > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > > > >        CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > > > >        CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > > > >        CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > > > +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > > > >     };
> > > > > > > > 
> > > > > > > >     enum coresight_dev_subtype_helper {
> > > > > > > > --
> > > > > > > > 2.17.1
> > > > > > > > 
> > > > > 
> > > > > -- 
> > > > > Mike Leach
> > > > > Principal Engineer, ARM Ltd.
> > > > > Manchester Design Centre. UK


From mkorpershoek at baylibre.com  Wed Jan 26 07:35:16 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Wed, 26 Jan 2022 16:35:16 +0100
Subject: [PATCH v19 0/3] Add matrix keypad driver support for Mediatek SoCs
Message-ID: <20220126153519.3637496-1-mkorpershoek@baylibre.com>

Dear all,

This is a follow-up on an abandoned series, see [1]

Since Dmitry seemed generally happy with the driver, I applied his rename
recommendations.
I also did a couple of binding fixes which were needed to pass "make dt_binding_check".

Thus, I have made the following:

* All Reviewed-By: tags were kept
* Applied Marco's reviewed by on the bindings (since he approved v10)
* Fengping is still the maintainer since he is the original author of this driver
* The binding license is not changed even if checkpatch recommended it:
  > WARNING: DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)

Please tell me if you would rather have me do things differently.

[1] https://lore.kernel.org/all/20200909072159.14888-1-fengping.yu at mediatek.com/

v18 -> v19:
- bindings: fix maintainer -> maintainers keyword
- bindings: add matrix-keymap.yaml ref and remove included properties
- bindings: fix compatible strings (reported by make dt_binding_check)
- bindings: reorder properties to match the required ones
- bindings: remove un-necessary descriptions
- bindings: fix multiline description for mediatek,debounce-us
- bindings: fix example to pass make dt_binding_check
- bindings: fixed licence to GPL-2.0 only (checkpatch)
- bindings: rename to mediatek,mt6779-keypad.yaml to match driver
- rename driver to mt6779-keypad.c
- prefix function names with mt6779_keypad_
- prefix globals with mt6779_keypad_
- rename CONFIG_KEYBOARD_MTK_KPD to CONFIG_KEYBOARD_MT6779
- rename module name to mt6779-keypad
- update copyright year to 2022

fengping.yu (3):
  dt-bindings: input: Add bindings for Mediatek matrix keypad
  Input: mt6779-keypad - Add MediaTek keypad driver
  arm64: defconfig: Add CONFIG_KEYBOARD_MT6779=m

 .../input/mediatek,mt6779-keypad.yaml         |  80 +++++++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/input/keyboard/Kconfig                |  12 +
 drivers/input/keyboard/Makefile               |   1 +
 drivers/input/keyboard/mt6779-keypad.c        | 218 ++++++++++++++++++
 5 files changed, 312 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
 create mode 100644 drivers/input/keyboard/mt6779-keypad.c


base-commit: 87a0b2fafc09766d8c55461a18345a1cfb10a7fe
-- 
2.32.0



From mkorpershoek at baylibre.com  Wed Jan 26 07:35:18 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Wed, 26 Jan 2022 16:35:18 +0100
Subject: [PATCH v19 2/3] Input: mt6779-keypad - Add MediaTek keypad driver
In-Reply-To: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
References: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
Message-ID: <20220126153519.3637496-3-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

This patch adds matrix keypad support for Mediatek SoCs.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/Kconfig         |  12 ++
 drivers/input/keyboard/Makefile        |   1 +
 drivers/input/keyboard/mt6779-keypad.c | 218 +++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/input/keyboard/mt6779-keypad.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0c607da9ee10..03a9530f620e 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -779,6 +779,18 @@ config KEYBOARD_BCM
 	  To compile this driver as a module, choose M here: the
 	  module will be called bcm-keypad.
 
+config KEYBOARD_MT6779
+	tristate "MediaTek Keypad Support"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	select REGMAP_MMIO
+	select INPUT_MATRIXKMAP
+	help
+	  Say Y here if you want to use the keypad on MediaTek SoCs.
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mt6779-keypad.
+
 config KEYBOARD_MTK_PMIC
 	tristate "MediaTek PMIC keys support"
 	depends on MFD_MT6397
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index e3c8648f834e..721936e90290 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
+obj-$(CONFIG_KEYBOARD_MT6779)		+= mt6779-keypad.o
 obj-$(CONFIG_KEYBOARD_MTK_PMIC) 	+= mtk-pmic-keys.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
diff --git a/drivers/input/keyboard/mt6779-keypad.c b/drivers/input/keyboard/mt6779-keypad.c
new file mode 100644
index 000000000000..1564ed529e09
--- /dev/null
+++ b/drivers/input/keyboard/mt6779-keypad.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author Fengping Yu <fengping.yu at mediatek.com>
+ */
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MTK_KPD_NAME		"mt6779-keypad"
+#define MTK_KPD_MEM		0x0004
+#define MTK_KPD_DEBOUNCE	0x0018
+#define MTK_KPD_DEBOUNCE_MASK	GENMASK(13, 0)
+#define MTK_KPD_DEBOUNCE_MAX_US	256000
+#define MTK_KPD_NUM_MEMS	5
+#define MTK_KPD_NUM_BITS	136	/* 4*32+8 MEM5 only use 8 BITS */
+
+struct mt6779_keypad {
+	struct regmap *regmap;
+	struct input_dev *input_dev;
+	struct clk *clk;
+	void __iomem *base;
+	u32 n_rows;
+	u32 n_cols;
+	DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS);
+};
+
+static const struct regmap_config mt6779_keypad_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = sizeof(u32),
+	.max_register = 36,
+};
+
+static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
+{
+	struct mt6779_keypad *keypad = dev_id;
+	unsigned short *keycode = keypad->input_dev->keycode;
+	DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
+	DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
+	int bit_nr;
+	int pressed;
+	unsigned short code;
+	int row, col;
+	int row_shift = get_count_order(keypad->n_cols);
+
+	regmap_bulk_read(keypad->regmap, MTK_KPD_MEM,
+			 new_state, MTK_KPD_NUM_MEMS);
+
+	bitmap_xor(change, new_state, keypad->keymap_state, MTK_KPD_NUM_BITS);
+
+	for_each_set_bit(bit_nr, change, MTK_KPD_NUM_BITS) {
+	/* For 32bits register, only bits [15:0] use to indicate key status */
+		if (bit_nr % 32 >= 16)
+			continue;
+
+		/* 1: not pressed, 0: pressed */
+		pressed = !test_bit(bit_nr, new_state);
+		dev_dbg(&keypad->input_dev->dev, "%s",
+			pressed ? "pressed" : "released");
+
+		row = bit_nr / 32;
+		col = bit_nr % 32;
+
+		code = keycode[MATRIX_SCAN_CODE(row, col, row_shift)];
+
+		input_report_key(keypad->input_dev, code, pressed);
+		input_sync(keypad->input_dev);
+
+		dev_dbg(&keypad->input_dev->dev,
+			"report Linux keycode = %d\n", code);
+	}
+
+	bitmap_copy(keypad->keymap_state, new_state, MTK_KPD_NUM_BITS);
+
+	return IRQ_HANDLED;
+}
+
+static void mt6779_keypad_clk_disable(void *data)
+{
+	clk_disable_unprepare(data);
+}
+
+static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
+{
+	struct mt6779_keypad *keypad;
+	unsigned int irq;
+	u32 debounce;
+	bool wakeup;
+	int error;
+
+	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+	if (!keypad)
+		return -ENOMEM;
+
+	keypad->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(keypad->base))
+		return PTR_ERR(keypad->base);
+
+	keypad->regmap = devm_regmap_init_mmio(&pdev->dev,
+					       keypad->base,
+					       &mt6779_keypad_regmap_cfg);
+	if (IS_ERR(keypad->regmap)) {
+		dev_err(&pdev->dev,
+			"regmap init failed:%pe\n", keypad->regmap);
+		return PTR_ERR(keypad->regmap);
+	}
+
+	bitmap_fill(keypad->keymap_state, MTK_KPD_NUM_BITS);
+
+	keypad->input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!keypad->input_dev) {
+		dev_err(&pdev->dev, "Failed to allocate input dev\n");
+		return -ENOMEM;
+	}
+
+	keypad->input_dev->name = MTK_KPD_NAME;
+	keypad->input_dev->id.bustype = BUS_HOST;
+
+	error = matrix_keypad_parse_properties(&pdev->dev, &keypad->n_rows,
+					       &keypad->n_cols);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to parse keypad params\n");
+		return error;
+	}
+
+	if (device_property_read_u32(&pdev->dev, "mediatek,debounce-us",
+				     &debounce))
+		debounce = 16000;
+
+	if (debounce > MTK_KPD_DEBOUNCE_MAX_US) {
+		dev_err(&pdev->dev, "Debounce time exceeds the maximum allowed time %dus\n",
+			MTK_KPD_DEBOUNCE_MAX_US);
+		return -EINVAL;
+	}
+
+	wakeup = device_property_read_bool(&pdev->dev, "wakeup-source");
+
+	dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n",
+		keypad->n_rows, keypad->n_cols, debounce);
+
+	error = matrix_keypad_build_keymap(NULL, NULL,
+					   keypad->n_rows,
+					   keypad->n_cols,
+					   NULL,
+					   keypad->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to build keymap\n");
+		return error;
+	}
+
+	regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
+		     debounce * 32 / 1000 & MTK_KPD_DEBOUNCE_MASK);
+
+	keypad->clk = devm_clk_get(&pdev->dev, "kpd");
+	if (IS_ERR(keypad->clk))
+		return PTR_ERR(keypad->clk);
+
+	error = clk_prepare_enable(keypad->clk);
+	if (error) {
+		dev_err(&pdev->dev, "cannot prepare/enable keypad clock\n");
+		return error;
+	}
+
+	error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable, keypad->clk);
+	if (error)
+		return error;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	error = devm_request_threaded_irq(&pdev->dev, irq,
+					  NULL, mt6779_keypad_irq_handler,
+					  IRQF_ONESHOT,
+					  MTK_KPD_NAME, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to request IRQ#%d:%d\n",
+			irq, error);
+		return error;
+	}
+
+	error = input_register_device(keypad->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to register device\n");
+		return error;
+	}
+
+	error =  device_init_wakeup(&pdev->dev, wakeup);
+	if (error)
+		dev_warn(&pdev->dev, "device_init_wakeup fail\n");
+
+	return 0;
+}
+
+static const struct of_device_id mt6779_keypad_of_match[] = {
+	{ .compatible = "mediatek,mt6779-keypad" },
+	{ .compatible = "mediatek,mt6873-keypad" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver mt6779_keypad_pdrv = {
+	.probe = mt6779_keypad_pdrv_probe,
+	.driver = {
+		   .name = MTK_KPD_NAME,
+		   .of_match_table = mt6779_keypad_of_match,
+	},
+};
+module_platform_driver(mt6779_keypad_pdrv);
+
+MODULE_AUTHOR("Mediatek Corporation");
+MODULE_DESCRIPTION("MTK Keypad (KPD) Driver");
+MODULE_LICENSE("GPL");
-- 
2.32.0



From mkorpershoek at baylibre.com  Wed Jan 26 07:35:17 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Wed, 26 Jan 2022 16:35:17 +0100
Subject: [PATCH v19 1/3] dt-bindings: input: Add bindings for Mediatek matrix
 keypad
In-Reply-To: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
References: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
Message-ID: <20220126153519.3637496-2-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

This patch add devicetree bindings for Mediatek matrix keypad driver.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 .../input/mediatek,mt6779-keypad.yaml         | 80 +++++++++++++++++++
 1 file changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml

diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
new file mode 100644
index 000000000000..2c76029224a0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
@@ -0,0 +1,80 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/mediatek,mt6779-keypad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek's Keypad Controller device tree bindings
+
+maintainers:
+  - Fengping Yu <fengping.yu at mediatek.com>
+
+allOf:
+  - $ref: "/schemas/input/matrix-keymap.yaml#"
+
+description: |
+  Mediatek's Keypad controller is used to interface a SoC with a matrix-type
+  keypad device. The keypad controller supports multiple row and column lines.
+  A key can be placed at each intersection of a unique row and a unique column.
+  The keypad controller can sense a key-press and key-release and report the
+  event using a interrupt to the cpu.
+
+properties:
+  compatible:
+    oneOf:
+      - const: mediatek,mt6779-keypad
+      - items:
+          - enum:
+            - mediatek,mt6873-keypad
+          - const: mediatek,mt6779-keypad
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    description: Names of the clocks listed in clocks property in the same order
+    items:
+       - const: kpd
+
+  wakeup-source:
+    description: use any event on keypad as wakeup event
+    type: boolean
+
+  mediatek,debounce-us:
+    description: |
+      Debounce interval in microseconds, if not specified, the default
+      value is 16000
+    maximum: 256000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/input/input.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        kp at 10010000 {
+          compatible = "mediatek,mt6779-keypad";
+          reg = <0 0x10010000 0 0x1000>;
+          interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_FALLING>;
+          clocks = <&clk26m>;
+          clock-names = "kpd";
+        };
+    };
-- 
2.32.0



From mkorpershoek at baylibre.com  Wed Jan 26 07:35:19 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Wed, 26 Jan 2022 16:35:19 +0100
Subject: [PATCH v19 3/3] arm64: defconfig: Add CONFIG_KEYBOARD_MT6779=m
In-Reply-To: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
References: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
Message-ID: <20220126153519.3637496-4-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

Add Mediatek matrix keypad support in defconfig.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f2e2b9bdd702..099a9e68711c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -390,6 +390,7 @@ CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_SNVS_PWRKEY=m
 CONFIG_KEYBOARD_IMX_SC_KEY=m
 CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_KEYBOARD_MT6779=m
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_GOODIX=m
-- 
2.32.0



From broonie at kernel.org  Wed Jan 26 07:36:50 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:36:50 +0000
Subject: [PATCH] spi: uniphier: Fix a bug that doesn't point to private
 data correctly
In-Reply-To: <1640148492-32178-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1640148492-32178-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <164321141026.490397.11451995975683431974.b4-ty@kernel.org>

On Wed, 22 Dec 2021 13:48:12 +0900, Kunihiko Hayashi wrote:
> In uniphier_spi_remove(), there is a wrong code to get private data from
> the platform device, so the driver can't be removed properly.
> 
> The driver should get spi_master from the platform device and retrieve
> the private data from it.
> 
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/1] spi: uniphier: Fix a bug that doesn't point to private data correctly
      commit: 23e3404de1aecc62c14ac96d4b63403c3e0f52d5

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From broonie at kernel.org  Wed Jan 26 07:36:52 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 15:36:52 +0000
Subject: [PATCH] spi: meson-spicc: add IRQ check in meson_spicc_probe
In-Reply-To: <20220126110447.24549-1-linmq006@gmail.com>
References: <20220126110447.24549-1-linmq006@gmail.com>
Message-ID: <164321141213.490397.12590014811818910927.b4-ty@kernel.org>

On Wed, 26 Jan 2022 11:04:47 +0000, Miaoqian Lin wrote:
> This check misses checking for  platform_get_irq()'s call and may passes
> the negative error codes to devm_request_irq(), which takes unsigned IRQ #,
> causing it to fail with -EINVAL, overriding an original error code.
> Stop calling devm_request_irq() with invalid IRQ #s.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/1] spi: meson-spicc: add IRQ check in meson_spicc_probe
      commit: e937440f7fc444a3e3f1fb75ea65292d6f433a44

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From dianders at chromium.org  Wed Jan 26 07:42:48 2022
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 26 Jan 2022 07:42:48 -0800
Subject: [PATCH 09/27] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always
In-Reply-To: <20220126145549.617165-10-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-10-s.hauer@pengutronix.de>
Message-ID: <CAD=FV=VCWW4c3iqfzezU5=KKVFNP+EhPGTBZ7uZdQ=bSCJHQVA@mail.gmail.com>

Hi,

On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
>
> From: Douglas Anderson <dianders at chromium.org>
>
> Jitter was improved by lowering the MPLL bandwidth to account for high
> frequency noise in the rk3288 PLL.  In each case MPLL bandwidth was
> lowered only enough to get us a comfortable margin.  We believe that
> lowering the bandwidth like this is safe given sufficient testing.
>
> Changes since v3:
> - new patch
>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> (am from https://patchwork.kernel.org/patch/9223301/)

Probably remove the "am from" line? It's not standard in upstream and
that link doesn't seem to go anywhere anymore...


> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++--------------
>  1 file changed, 2 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> index c44eb4d2e2d5..77f82a4fd027 100644
> --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> @@ -176,20 +176,8 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
>  static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
>         /*      pixelclk    bpp8    bpp10   bpp12 */
>         {
> -               40000000,  { 0x0018, 0x0018, 0x0018 },
> -       }, {
> -               65000000,  { 0x0028, 0x0028, 0x0028 },
> -       }, {
> -               66000000,  { 0x0038, 0x0038, 0x0038 },
> -       }, {
> -               74250000,  { 0x0028, 0x0038, 0x0038 },
> -       }, {
> -               83500000,  { 0x0028, 0x0038, 0x0038 },
> -       }, {
> -               146250000, { 0x0038, 0x0038, 0x0038 },
> -       }, {
> -               148500000, { 0x0000, 0x0038, 0x0038 },
> -       }, {
> +               600000000, { 0x0000, 0x0000, 0x0000 },
> +       },  {

This is what we did for rk3288. I can't personally vouch for the
effects on other SoCs.

-Doug


From patchwork-bot+netdevbpf at kernel.org  Wed Jan 26 07:50:11 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 26 Jan 2022 15:50:11 +0000
Subject: [PATCH net v2 0/6] ethernet: fix some esoteric drivers after
 netdev->dev_addr constification
In-Reply-To: <20220126003801.1736586-1-kuba@kernel.org>
References: <20220126003801.1736586-1-kuba@kernel.org>
Message-ID: <164321221144.12592.6135964602167128218.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Tue, 25 Jan 2022 16:37:55 -0800 you wrote:
> Looking at recent fixes for drivers which don't get included with
> allmodconfig builds I thought it's worth grepping for more instances of:
> 
>   dev->dev_addr\[.*\] =
> 
> This set contains the fixes.
> 
> [...]

Here is the summary with links:
  - [net,v2,1/6] ethernet: 3com/typhoon: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/007c95120d1b
  - [net,v2,2/6] ethernet: tundra: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/14ba66a60fbf
  - [net,v2,3/6] ethernet: broadcom/sb1250-mac: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/7f6ec2b2f01b
  - [net,v2,4/6] ethernet: i825xx: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/98ef22bbae78
  - [net,v2,5/6] ethernet: 8390/etherh: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/5518c5246ba6
  - [net,v2,6/6] ethernet: seeq/ether3: don't write directly to netdev->dev_addr
    https://git.kernel.org/netdev/net/c/8eb86fc2f490

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Wed Jan 26 07:50:12 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Wed, 26 Jan 2022 15:50:12 +0000
Subject: [PATCH net-next 0/2] net: axienet: modernise pcs implementation
In-Reply-To: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
References: <YfAgeKiKvxcQ0w57@shell.armlinux.org.uk>
Message-ID: <164321221213.12592.9190321368977882213.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net-next.git (master)
by David S. Miller <davem at davemloft.net>:

On Tue, 25 Jan 2022 16:08:24 +0000 you wrote:
> Hi,
> 
> These two patches modernise the Xilinx axienet PCS implementation to
> use the phylink split PCS support.
> 
> The first patch adds split PCS support and makes use of the newly
> introduced mac_select_pcs() function, which is the preferred way to
> conditionally attach a PCS.
> 
> [...]

Here is the summary with links:
  - [net-next,1/2] net: axienet: convert to phylink_pcs
    https://git.kernel.org/netdev/net-next/c/7a86be6a5135
  - [net-next,2/2] net: axienet: replace mdiobus_write() with mdiodev_write()
    https://git.kernel.org/netdev/net-next/c/03854d8a7723

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From robin.murphy at arm.com  Wed Jan 26 07:54:25 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 26 Jan 2022 15:54:25 +0000
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu device
In-Reply-To: <PAXPR03MB81144A63E18CAF10E785E2A7F0209@PAXPR03MB8114.eurprd03.prod.outlook.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
 <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
 <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
 <PAXPR03MB81144A63E18CAF10E785E2A7F0209@PAXPR03MB8114.eurprd03.prod.outlook.com>
Message-ID: <447f89ca-86c0-dc35-e7ac-e6639a573670@arm.com>

On 2022-01-26 15:09, Sergiy Kibrik wrote:
> Hi Robin,
> 
>>
>> This could break Linux guests, since depending on the deferred probe
>> timeout setting it could lead to drivers never probing because the "IOMMU"
>> never becomes available.
>>
> 
> I've noticed no deferred probe timeouts when booting with this patch. Could you please explain more on how this would break guests?

Right now I think it would actually require command-line intervention, 
e.g. "fw_devlink=on" or "deferred_probe_timeout=3600" (with modules 
enabled for the latter to take full effect), but I'm wary of the 
potential for future config options to control those behaviours by default.

Robin.

> Thank you!
> 
>   -- Sergiy


From dianders at chromium.org  Wed Jan 26 07:54:53 2022
From: dianders at chromium.org (Doug Anderson)
Date: Wed, 26 Jan 2022 07:54:53 -0800
Subject: [PATCH 07/27] drm/rockchip: dw_hdmi: Use auto-generated tables
In-Reply-To: <20220126145549.617165-8-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-8-s.hauer@pengutronix.de>
Message-ID: <CAD=FV=U7W_oWjS_gCurAkNdkcuHQGn-XH=-VwP2MSG9zO92ySg@mail.gmail.com>

Hi,

On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
>
> From: Douglas Anderson <dianders at chromium.org>
>
> The previous tables for mpll_cfg and curr_ctrl were created using the
> 20-pages of example settings provided by the PHY vendor.  Those
> example settings weren't particularly dense, so there were places
> where we were guessing what the settings would be for 10-bit and
> 12-bit (not that we use those anyway).  It was also always a lot of
> extra work every time we wanted to add a new clock rate since we had
> to cross-reference several tables.
>
> In <http://crosreview.com/285855> I've gone through the work to figure

The `crosreview.com` syntax doesn't seem to work anymore. Could maybe
update to https://crrev.com/c/285855 ?

> out how to generate this table automatically.  Let's now use the
> automatically generated table and then we'll never need to look at it
> again.
>
> We only support 8-bit mode right now and only support a small number
> of clock rates and and I've verified that the only 8-bit rate that was
> affected was 148.5.  That mode appears to have been wrong in the old
> table.
>
> Changes since v3:
> - new patch
>
> Signed-off-by: Douglas Anderson <dianders at chromium.org>
> Signed-off-by: Yakir Yang <ykk at rock-chips.com>

Should probably change the "at" to "@" ?

> Reviewed-by: St?phane Marchesin <marcheu at chromium.org>

In general shouldn't carry downstream reviews when posting upstream
unless you're certain that the person intended it...


It's been a long time, but in general I think I was fairly confident
in the numbers that my script pumped out, at least given the caveat of
no pixel repetition and 8-bit only. That being said, I didn't have any
inside knowledge of the hardware and just figured out formulas that
seemed to match the table that I had. YMMV.

I'll also say that when I did a rebase of veyron (rk3288-based
Chromebook) to 4.19 about 2.5 years ago, I ended up squashing several
of these patches into 1. That can be found at
<https://crrev.com/c/1661056>. That also has details about why some of
these patches never made it upstream. The main reason, at least in the
case of rk3288, was the PLL sharing problem that nobody ever solved.
rk3288 didn't have quite enough PLLs and thus, if you were using both
VOPs, one of the VOPs was going to be severely limited in what pixel
clocks it could make. There was no framework deciding which VOP should
be limited and how the system should react to this...


In any case, I'm pretty far disconnected from all this stuff now, but
I wish you the best of luck in trying to get it all solved!

-Doug


From alisaidi at amazon.com  Wed Jan 26 07:58:20 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Wed, 26 Jan 2022 15:58:20 +0000
Subject: [PATCH 1/2] perf arm-spe: Add arm_spe_record to synthesized
In-Reply-To: <5ca990a5-eedd-0edb-26d3-b5e16c36ac34@arm.com>
References: <5ca990a5-eedd-0edb-26d3-b5e16c36ac34@arm.com>
Message-ID: <20220126155820.21929-1-alisaidi@amazon.com>

Hi German,
>Hi Ali,
>
>On 25/01/2022 19:20, Ali Saidi wrote:
>> Providing the arm_spe_record as raw data to the synthesized SPE samples
>> allows perf scripts to read and separately process the data in ways
>> existing perf tools don't support and mirrors functionality available
>> for PEBS.
>> Signed-off-by: Ali Saidi <alisaidi at amazon.com>
>> ---
>>  tools/perf/util/arm-spe.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
>> index d2b64e3f588b..a7499cde6fc0 100644
>> --- a/tools/perf/util/arm-spe.c
>> +++ b/tools/perf/util/arm-spe.c
>> @@ -336,6 +336,8 @@ static int arm_spe__synth_mem_sample(struct arm_spe_queue *speq,
>>  	sample.phys_addr = record->phys_addr;
>>  	sample.data_src = data_src;
>>  	sample.weight = record->latency;
>> +	sample.raw_size = sizeof(*record);
>> +	sample.raw_data = record;
>
>Have you tried this with perf-inject? I think it would need the PERF_SAMPLE_RAW bit in the sample_type,

Yes I've tried the following and it worked as expected with the original
perf.data or the perf.data.jitted after perf-inject. 

perf record -e arm_spe_0/jitter=1/ -k 1 java ...
perf  inject -f --jit -i perf.data -o perf.data.jitted
perf script -i perf.data -s t1.py --itrace=i1i

>
>Although I quickly looked over the perf inject code and it looks like it's expecting some type of padding:
>
>  // synthetic-events.c
>  if (type & PERF_SAMPLE_RAW) {
>    result += sizeof(u32);
>    result += sample->raw_size;
>  }
>
>I'm seeing some comments in utils/event.h related to this on the intel events.

Yes i noticed this too,but looking at how the raw data is added to the same
other places like intel-pt.c:1703 the perf_synth__raw*() functions are used to
strip away the 4 bytes bytes before the data is added to the sample. The other
places i can find the padding used is in builtin-script.c but given we have the
--dump-raw-trace option it's not clear to me that it's needed to wrap the
arm_spe_event in another struct with padding like perf_synth_intel_ptwrite?

Thanks,
Ali



From maz at kernel.org  Wed Jan 26 08:01:47 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 16:01:47 +0000
Subject: [PATCH v5 12/69] KVM: arm64: nv: Handle HCR_EL2.NV system
 register traps
In-Reply-To: <YebiAjUTzVECLOun@shell.armlinux.org.uk>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-13-maz@kernel.org>
 <YebiAjUTzVECLOun@shell.armlinux.org.uk>
Message-ID: <87a6fi7afo.wl-maz@kernel.org>

On Tue, 18 Jan 2022 15:51:30 +0000,
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> 
> On Mon, Nov 29, 2021 at 08:00:53PM +0000, Marc Zyngier wrote:
> > From: Jintack Lim <jintack.lim at linaro.org>
> > 
> > ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
> > this bit is set, accessing EL2 registers in EL1 traps to EL2. In
> > addition, executing the following instructions in EL1 will trap to EL2:
> > tlbi, at, eret, and msr/mrs instructions to access SP_EL1. Most of the
> > instructions that trap to EL2 with the NV bit were undef at EL1 prior to
> > ARM v8.3. The only instruction that was not undef is eret.
> > 
> > This patch sets up a handler for EL2 registers and SP_EL1 register
> > accesses at EL1. The host hypervisor keeps those register values in
> > memory, and will emulate their behavior.
> > 
> > This patch doesn't set the NV bit yet. It will be set in a later patch
> > once nested virtualization support is completed.
> > 
> > Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> > [maz: added SCTLR_EL2 RES0/RES1 handling]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> ...
> > @@ -1825,9 +1882,51 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> >  	{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
> >  	  .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
> >  
> > +	{ SYS_DESC(SYS_VPIDR_EL2), access_rw, reset_val, VPIDR_EL2, 0 },
> > +	{ SYS_DESC(SYS_VMPIDR_EL2), access_rw, reset_val, VMPIDR_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_SCTLR_EL2), access_sctlr_el2, reset_val, SCTLR_EL2, SCTLR_EL2_RES1 },
> > +	{ SYS_DESC(SYS_ACTLR_EL2), access_rw, reset_val, ACTLR_EL2, 0 },
> > +	{ SYS_DESC(SYS_HCR_EL2), access_rw, reset_val, HCR_EL2, 0 },
> > +	{ SYS_DESC(SYS_MDCR_EL2), access_rw, reset_val, MDCR_EL2, 0 },
> > +	{ SYS_DESC(SYS_CPTR_EL2), access_rw, reset_val, CPTR_EL2, CPTR_EL2_DEFAULT },
> > +	{ SYS_DESC(SYS_HSTR_EL2), access_rw, reset_val, HSTR_EL2, 0 },
> > +	{ SYS_DESC(SYS_HACR_EL2), access_rw, reset_val, HACR_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_TTBR0_EL2), access_rw, reset_val, TTBR0_EL2, 0 },
> > +	{ SYS_DESC(SYS_TTBR1_EL2), access_rw, reset_val, TTBR1_EL2, 0 },
> > +	{ SYS_DESC(SYS_TCR_EL2), access_rw, reset_val, TCR_EL2, TCR_EL2_RES1 },
> > +	{ SYS_DESC(SYS_VTTBR_EL2), access_rw, reset_val, VTTBR_EL2, 0 },
> > +	{ SYS_DESC(SYS_VTCR_EL2), access_rw, reset_val, VTCR_EL2, 0 },
> > +
> >  	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
> > +	{ SYS_DESC(SYS_SPSR_EL2), access_rw, reset_val, SPSR_EL2, 0 },
> > +	{ SYS_DESC(SYS_ELR_EL2), access_rw, reset_val, ELR_EL2, 0 },
> > +	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
> > +
> >  	{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },
> > +	{ SYS_DESC(SYS_AFSR0_EL2), access_rw, reset_val, AFSR0_EL2, 0 },
> > +	{ SYS_DESC(SYS_AFSR1_EL2), access_rw, reset_val, AFSR1_EL2, 0 },
> > +	{ SYS_DESC(SYS_ESR_EL2), access_rw, reset_val, ESR_EL2, 0 },
> >  	{ SYS_DESC(SYS_FPEXC32_EL2), NULL, reset_val, FPEXC32_EL2, 0x700 },
> > +
> > +	{ SYS_DESC(SYS_FAR_EL2), access_rw, reset_val, FAR_EL2, 0 },
> > +	{ SYS_DESC(SYS_HPFAR_EL2), access_rw, reset_val, HPFAR_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_MAIR_EL2), access_rw, reset_val, MAIR_EL2, 0 },
> > +	{ SYS_DESC(SYS_AMAIR_EL2), access_rw, reset_val, AMAIR_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_VBAR_EL2), access_rw, reset_val, VBAR_EL2, 0 },
> > +	{ SYS_DESC(SYS_RVBAR_EL2), access_rw, reset_val, RVBAR_EL2, 0 },
> > +	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
> > +
> > +	{ SYS_DESC(SYS_CONTEXTIDR_EL2), access_rw, reset_val, CONTEXTIDR_EL2, 0 },
> > +	{ SYS_DESC(SYS_TPIDR_EL2), access_rw, reset_val, TPIDR_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_CNTVOFF_EL2), access_rw, reset_val, CNTVOFF_EL2, 0 },
> > +	{ SYS_DESC(SYS_CNTHCTL_EL2), access_rw, reset_val, CNTHCTL_EL2, 0 },
> > +
> > +	{ SYS_DESC(SYS_SP_EL2), NULL, reset_unknown, SP_EL2 },
> 
> Doesn't this have an effect on the ability to migrate guests between
> identical hardware but running kernels with vs without this patch?
> From what I remember, QEMU fails a migration if the migration target
> has less system registers than the migration source.
> 
> If so, this should at the very least be spelt out in the commit
> message - it's a user experience breaking change. Maybe also preventing
> the exposure of these when NV is disabled would be a good idea?

Yes, that's a known issue. I have taken steps to avoid exposing these
registers (the get-reg-list test now passes on a !NV system, while it
didn't before).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From pgwipeout at gmail.com  Wed Jan 26 08:04:26 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 11:04:26 -0500
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <20220126145549.617165-22-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-22-s.hauer@pengutronix.de>
Message-ID: <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>

On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
>
> Add support for the HDMI port found on RK3568.
>
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
>  1 file changed, 36 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 4008bd666d01..e38fb223e9b8 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -10,7 +10,6 @@
>  #include <dt-bindings/pinctrl/rockchip.h>
>  #include <dt-bindings/power/rk3568-power.h>
>  #include <dt-bindings/soc/rockchip,boot-mode.h>
> -#include <dt-bindings/soc/rockchip,vop2.h>
>  #include <dt-bindings/thermal/thermal.h>
>
>  / {
> @@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
>                 status = "disabled";
>         };
>
> +       hdmi: hdmi at fe0a0000 {
> +               compatible = "rockchip,rk3568-dw-hdmi";
> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&cru PCLK_HDMI_HOST>,
> +                        <&cru CLK_HDMI_SFR>,
> +                        <&cru CLK_HDMI_CEC>,
> +                        <&pmucru CLK_HDMI_REF>,
> +                        <&cru HCLK_VOP>;
> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
> +               pinctrl-names = "default";
> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;

I looked into CEC support here, and it seems that it does work with one change.
Please add the two following lines to your patch:
assigned-clocks = <&cru CLK_HDMI_CEC>;
assigned-clock-rates = <32768>;

The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
function.

> +               power-domains = <&power RK3568_PD_VO>;
> +               reg-io-width = <4>;
> +               rockchip,grf = <&grf>;
> +               #sound-dai-cells = <0>;
> +               status = "disabled";
> +
> +               ports {
> +                       #address-cells = <1>;
> +                       #size-cells = <0>;
> +
> +                       hdmi_in: port at 0 {
> +                               reg = <0>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                       };
> +
> +                       hdmi_out: port at 1 {
> +                               reg = <1>;
> +                               #address-cells = <1>;
> +                               #size-cells = <0>;
> +                       };
> +               };
> +       };
> +
>         qos_gpu: qos at fe128000 {
>                 compatible = "rockchip,rk3568-qos", "syscon";
>                 reg = <0x0 0xfe128000 0x0 0x20>;
> --
> 2.30.2
>


From maz at kernel.org  Wed Jan 26 08:08:02 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 16:08:02 +0000
Subject: [PATCH v5 12/69] KVM: arm64: nv: Handle HCR_EL2.NV system
 register traps
In-Reply-To: <YeVTnZcW82G36cda@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-13-maz@kernel.org>
 <YeVTnZcW82G36cda@monolith.localdoman>
Message-ID: <878rv27a59.wl-maz@kernel.org>

On Mon, 17 Jan 2022 11:31:41 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> Nitpick, but HCR_EL2.NV also traps accesses to *_EL02 and *_EL12 registers,
> according to ARM DDI 0487G.a, page D5-2770. The subject could be changed to
> "Handle HCR_EL2.NV *_EL2 system register traps" to better match the
> content, but doesn't make much a difference overall.
> 
> On Mon, Nov 29, 2021 at 08:00:53PM +0000, Marc Zyngier wrote:
> > From: Jintack Lim <jintack.lim at linaro.org>
> > 
> > ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
> > this bit is set, accessing EL2 registers in EL1 traps to EL2. In
> > addition, executing the following instructions in EL1 will trap to EL2:
> > tlbi, at, eret, and msr/mrs instructions to access SP_EL1. Most of the
> > instructions that trap to EL2 with the NV bit were undef at EL1 prior to
> > ARM v8.3. The only instruction that was not undef is eret.
> > 
> > This patch sets up a handler for EL2 registers and SP_EL1 register
> > accesses at EL1. The host hypervisor keeps those register values in
> > memory, and will emulate their behavior.
> > 
> > This patch doesn't set the NV bit yet. It will be set in a later patch
> > once nested virtualization support is completed.
> > 
> > Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> > [maz: added SCTLR_EL2 RES0/RES1 handling]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/sysreg.h |  41 +++++++++++-
> >  arch/arm64/kvm/sys_regs.c       | 109 ++++++++++++++++++++++++++++++--
> >  2 files changed, 144 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 615dd6278f8b..c77fe5401826 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -531,10 +531,26 @@
> >  
> >  #define SYS_PMCCFILTR_EL0		sys_reg(3, 3, 14, 15, 7)
> >  
> > +#define SYS_VPIDR_EL2			sys_reg(3, 4, 0, 0, 0)
> > +#define SYS_VMPIDR_EL2			sys_reg(3, 4, 0, 0, 5)
> > +
> >  #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
> > +#define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
> > +#define SYS_HCR_EL2			sys_reg(3, 4, 1, 1, 0)
> > +#define SYS_MDCR_EL2			sys_reg(3, 4, 1, 1, 1)
> > +#define SYS_CPTR_EL2			sys_reg(3, 4, 1, 1, 2)
> > +#define SYS_HSTR_EL2			sys_reg(3, 4, 1, 1, 3)
> >  #define SYS_HFGRTR_EL2			sys_reg(3, 4, 1, 1, 4)
> >  #define SYS_HFGWTR_EL2			sys_reg(3, 4, 1, 1, 5)
> >  #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
> > +#define SYS_HACR_EL2			sys_reg(3, 4, 1, 1, 7)
> > +
> > +#define SYS_TTBR0_EL2			sys_reg(3, 4, 2, 0, 0)
> > +#define SYS_TTBR1_EL2			sys_reg(3, 4, 2, 0, 1)
> > +#define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
> > +#define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
> > +#define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
> > +
> >  #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
> >  #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
> >  #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
> > @@ -543,14 +559,26 @@
> >  #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
> >  #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
> >  #define SYS_ELR_EL2			sys_reg(3, 4, 4, 0, 1)
> > +#define SYS_SP_EL1			sys_reg(3, 4, 4, 1, 0)
> >  #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
> > +#define SYS_AFSR0_EL2			sys_reg(3, 4, 5, 1, 0)
> > +#define SYS_AFSR1_EL2			sys_reg(3, 4, 5, 1, 1)
> >  #define SYS_ESR_EL2			sys_reg(3, 4, 5, 2, 0)
> >  #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
> >  #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
> >  #define SYS_TFSR_EL2			sys_reg(3, 4, 5, 6, 0)
> >  #define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
> >  
> > -#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
> > +#define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
> > +#define SYS_HPFAR_EL2			sys_reg(3, 4, 6, 0, 4)
> > +
> > +#define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
> > +#define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
> > +
> > +#define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
> > +#define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
> > +#define SYS_RMR_EL2			sys_reg(3, 4, 12, 0, 2)
> > +#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1, 1)
> >  #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
> >  #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
> >  #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
> > @@ -592,15 +620,24 @@
> >  #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
> >  #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
> >  
> > +#define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
> > +#define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
> > +
> > +#define SYS_CNTVOFF_EL2			sys_reg(3, 4, 14, 0, 3)
> > +#define SYS_CNTHCTL_EL2			sys_reg(3, 4, 14, 1, 0)
> > +
> >  /* VHE encodings for architectural EL0/1 system registers */
> >  #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
> >  #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
> >  #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
> > +
> >  #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
> >  #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
> >  #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
> > +
> >  #define SYS_SPSR_EL12			sys_reg(3, 5, 4, 0, 0)
> >  #define SYS_ELR_EL12			sys_reg(3, 5, 4, 0, 1)
> > +
> >  #define SYS_AFSR0_EL12			sys_reg(3, 5, 5, 1, 0)
> >  #define SYS_AFSR1_EL12			sys_reg(3, 5, 5, 1, 1)
> >  #define SYS_ESR_EL12			sys_reg(3, 5, 5, 2, 0)
> > @@ -618,6 +655,8 @@
> >  #define SYS_CNTV_CTL_EL02		sys_reg(3, 5, 14, 3, 1)
> >  #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
> >  
> > +#define SYS_SP_EL2			sys_reg(3, 6,  4, 1, 0)
> 
> Checked the encoding for the newly added registers, they match.
> 
> > +
> >  /* Common SCTLR_ELx flags. */
> >  #define SCTLR_ELx_DSSBS	(BIT(44))
> >  #define SCTLR_ELx_ATA	(BIT(43))
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index e3ec1a44f94d..a23701f29858 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -105,6 +105,46 @@ static u32 get_ccsidr(u32 csselr)
> >  	return ccsidr;
> >  }
> >  
> > +static bool access_rw(struct kvm_vcpu *vcpu,
> > +		      struct sys_reg_params *p,
> > +		      const struct sys_reg_desc *r)
> > +{
> > +	if (p->is_write)
> > +		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
> > +	else
> > +		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
> > +
> > +	return true;
> > +}
> > +
> > +static bool access_sctlr_el2(struct kvm_vcpu *vcpu,
> > +			     struct sys_reg_params *p,
> > +			     const struct sys_reg_desc *r)
> > +{
> > +	if (p->is_write) {
> > +		u64 val = p->regval;
> > +
> > +		if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)) {
> > +			val &= ~(GENMASK_ULL(63,45) | GENMASK_ULL(34, 32) |
> > +				 BIT_ULL(17) | BIT_ULL(9));
> > +			val |=  SCTLR_EL1_RES1;
> > +		} else {
> > +			val &= ~(GENMASK_ULL(63,45) | BIT_ULL(42) |
> > +				 GENMASK_ULL(39, 38) | GENMASK_ULL(35, 32) |
> > +				 BIT_ULL(26) | BIT_ULL(24) | BIT_ULL(20) |
> > +				 BIT_ULL(17) | GENMASK_ULL(15, 14) |
> > +				 GENMASK(10, 7));
> > +			val |=  SCTLR_EL2_RES1;
> > +		}
> 
> Some bits in SCTLR_EL2 are functional bits when {E2H, TGE} = {1, 1}, otherwise
> they are RES0. This is how ARM DDI 0487G.a describes the behaviour of bits which
> are RES0 only in some contexts (page Glossary-8529, emphasis added by me):
> 
> "For a bit in a read/write register, when the bit is described as RES0:
> 
> - An indirect write to the register sets the bit to 0.
> 
> - ** A read of the bit must return the value last successfully written to the bit,
>   by either a direct or an indirect write, regardless of the use of the register
>   when the bit was written **
> 
> If the bit has not been successfully written since reset, then the read of the bit returns the reset
> value if there is one, or otherwise returns an UNKNOWN value.
> 
> - A direct write to the bit must update a storage location associated with the bit.
> 
> - While the use of the register is such that the bit is described as RES0, the
>   value of the bit must have no effect on the operation of the PE, other than
>   determining the value read back from that bit, unless this Manual
>   explicitly defines additional properties for the bit."
> 
> Let's take bit 24, E0E, as an example. When E2H,TGE != {1,1} (which means the
> bit is now RES0), KVM clears the bit on a write, when according to the above
> definition, it should save the value.

That's an interesting observation. It means we should munge these bits
at save/restore time (specially in the nVHE case where we have to
translate SCTLR_EL2 to the SCTLR_EL1 format), rather than at access
time.

This would also solve the discrepancy we have between the ARMv8.3
trapping and the ARMv8.4 memory write (we can sanitise the former, but
not the latter).

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From jszhang at kernel.org  Wed Jan 26 08:00:31 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Thu, 27 Jan 2022 00:00:31 +0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and
 unprepare "stmmaceth" clk
In-Reply-To: <YfFkz1d9onk+ITGg@xhacker>
References: <20220123132805.758-1-jszhang@kernel.org>
 <38c41c04-abde-4d55-ed7c-515b6bba9c54@sholland.org>
 <YfFkz1d9onk+ITGg@xhacker>
Message-ID: <YfFwH9gHdN3fnx22@xhacker>

On Wed, Jan 26, 2022 at 11:12:28PM +0800, Jisheng Zhang wrote:
> On Sun, Jan 23, 2022 at 01:43:37PM -0600, Samuel Holland wrote:
> > On 1/23/22 7:28 AM, Jisheng Zhang wrote:
> > > Fix warnings on Allwinner D1 platform:
> > > 
> > > [    1.604695] ------------[ cut here ]------------
> > > [    1.609328] bus-emac already disabled
> > > [    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
> > > [    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
> > > [    1.627653] Hardware name: Allwinner D1 NeZha (DT)
> > > [    1.632443] Workqueue: events_unbound deferred_probe_work_func
> > > [    1.638286] epc : clk_core_disable+0xcc/0xec
> > > [    1.642561]  ra : clk_core_disable+0xcc/0xec
> > > [    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
> > > [    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
> > > [    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
> > > [    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
> > > [    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
> > > [    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
> > > [    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
> > > [    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > > [    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > > [    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
> > > [    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
> > > [    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
> > > [    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
> > > [    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
> > > [    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > [    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
> > > [    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > > [    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > [    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > > [    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > > [    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > > [    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > > [    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > > [    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > > [    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > > [    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > > [    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > > [    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > > [    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > > [    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > > [    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > [    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > [    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > > [    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
> > > [    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > > [    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > > [    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
> > > [    1.873675] ------------[ cut here ]------------
> > > [    1.878366] bus-emac already unprepared
> > > [    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
> > > [    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
> > > [    1.898674] Hardware name: Allwinner D1 NeZha (DT)
> > > [    1.903464] Workqueue: events_unbound deferred_probe_work_func
> > > [    1.909305] epc : clk_core_unprepare+0xe4/0x168
> > > [    1.913840]  ra : clk_core_unprepare+0xe4/0x168
> > > [    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
> > > [    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
> > > [    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
> > > [    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
> > > [    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
> > > [    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
> > > [    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
> > > [    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > > [    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > > [    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
> > > [    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
> > > [    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
> > > [    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
> > > [    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
> > > [    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
> > > [    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > > [    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > [    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > > [    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > > [    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > > [    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > > [    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > > [    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > > [    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > > [    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > > [    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > > [    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > > [    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > > [    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > > [    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > [    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > [    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > > [    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
> > > [    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > > [    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > > [    2.135455] ---[ end trace 8d5c6046255f84a1 ]---
> > > 
> > > the dwmmac-sun8i driver will get the "stmmaceth" clk as tx_clk during
> > > driver initialization. If stmmac_dvr_probe() fails due to various
> > > reasons, sun8i_dwmac_exit() will disable and unprepare the "stmmaceth"
> > > clk, then stmmac_remove_config_dt() will disable and unprepare the
> > > clk again.
> > 
> > This should still be balanced, because both stmmac_probe_config_dt and
> > sun8i_dwmac_init prepare/enable the clock, so the dwmac-sun8i glue layer calls
> > stmmac_dvr_probe with the clock having an enable count of 2. It looks like the
> > underlying issue is that commit 5ec55823438e ("net: stmmac: add clocks
> > management for gmac driver") introduces unbalanced runtime PM.
> 
> I added some printk then retested, the problem is triggered as below:
> 
> stmmac_probe_config_dt() enable the clk
> sun8i_dwmac_init() enble the clk again
> stmmac_dvr_probe() succeed, but it calls pm_runtime_put(), so rpm will
> disable the clk
> sun8i_dwmac_reset() fails due to various reason
> sun8i_dwmac_exit() disable the clk, this is fine
> stmmac_remove_config_dt() disable the clk again, so ccf complains.
> 
> The key here is: whether we should let stmmac_dvr_probe() calls
> pm_runtime_put() or let stmmac users to determine whether we could
> let rpm go?
> If we keep current behavior: stmmac users need to take care
> the code after stmmac_dvr_probe, including error handling code path,
> if we touch access registers, we need to call pm_runtime_get_sync()
> firstly.
> 
> Since the commit 5ec55823438e has been in for a long time, I'll submit
> a patch to follow this way.
> 

After reading the code and commit history, I found some users suffering
from the runtimepm issues, for example, dwmac-rk.c, so I changed my
idea. I think it's better to let stmmac users to call pm_runtime_put():

First of all, only the users know whether it's safe to finally
keep the mac runtime suspended after probe.

Secondly, if the users need to do platform specific operations after
stmmac_dvr_probe(), especially needs to access some registers, we have
to resume the mac firstly. The error handling code path also needs to
take care of it. It looks a bit strange resume immediately resume the
mac after suspending it.

Any suggestion is welcome.

PS: Since this would partially revert commit 5ec55823438e, I add Joakim
into the email thread.

Thanks


From broonie at kernel.org  Wed Jan 26 08:33:53 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 16:33:53 +0000
Subject: [PATCH v1 6/7] kselftest/arm64: mte: add test type enum
In-Reply-To: <20220125150920.23955-7-joey.gouly@arm.com>
References: <20220125150920.23955-1-joey.gouly@arm.com>
 <20220125150920.23955-7-joey.gouly@arm.com>
Message-ID: <YfF38X0Emg9N6iIy@sirena.org.uk>

On Tue, Jan 25, 2022 at 03:09:19PM +0000, Joey Gouly wrote:

> This enum will be used to parameterise the test to perform other syscalls
> than 'read'.

> -	evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz),

> +	for (t = 0; t < LAST_TEST; t++) {
> +		evaluate_test(check_usermem_access_fault(USE_MMAP, MTE_SYNC_ERR, MAP_PRIVATE, page_sz, t),

I appreciate that the lines were already over 80 columns here but
between the extra parameter and the extra indentation we're getting some
very long lines here.  Some line breaks wouldn't go amiss?

Alternatively I wonder if it wouldn't be better to restructure this so
that the list of tests is stored in a data structure, or indeed it looks
like as well as the enum for syscalls we could also be generating the
various combinations of shared/private, sync/async and tag offsets.
That seems more maintainable overall.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/b201ec58/attachment-0001.sig>

From andre.przywara at arm.com  Wed Jan 26 08:35:44 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 16:35:44 +0000
Subject: [bootwrapper PATCH v3 06/15] aarch32: add coprocessor accessors
In-Reply-To: <20220125150057.3936090-7-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-7-mark.rutland@arm.com>
Message-ID: <20220126163544.3b84f3cc@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:48 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> We open code the use of mrc/mcr for specific registers, which is
> somewhat tedious. Add macros to do this generically, along with a helper
> to extract a specific register field. Existing C usage is converted to
> the new helpers, and register definitions moved to a common location.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

The bits look alright:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch32/include/asm/cpu.h    | 45 ++++++++++++++++++++-----------
>  arch/aarch32/include/asm/gic-v3.h |  6 +++--
>  2 files changed, 34 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index 105cae5..d691c7b 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -9,9 +9,13 @@
>  #ifndef __ASM_AARCH32_CPU_H
>  #define __ASM_AARCH32_CPU_H
>  
> +#include <bits.h>
> +
>  #define MPIDR_ID_BITS		0x00ffffff
>  #define MPIDR_INVALID		(-1)
>  
> +#define ID_PFR1_GIC		BITS(31, 28)
> +
>  /* Only RES1 bits and CP15 barriers for the kernel */
>  #define HSCTLR_KERNEL		(3 << 28 | 3 << 22 | 1 << 18 | 1 << 16 | 1 << 11 | 3 << 4)
>  #define SCTLR_KERNEL		(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
> @@ -40,32 +44,43 @@
>  #define sevl()		asm volatile ("sev" : : : "memory")
>  #endif
>  
> -static inline unsigned long read_mpidr(void)
> -{
> -	unsigned long mpidr;
> +#define MPIDR		"p15, 0, %0, c0, c0, 5"
> +#define ID_PFR1		"p15, 0, %0, c0, c1, 1"
> +#define ICIALLU		"p15, 0, %0, c7, c5, 0"
>  
> -	asm volatile ("mrc	p15, 0, %0, c0, c0, 5\n" : "=r" (mpidr));
> -	return mpidr & MPIDR_ID_BITS;
> -}
> +#define ICC_SRE		"p15, 6, %0, c12, c12, 5"
> +#define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
>  
> -static inline uint32_t read_id_pfr1(void)
> -{
> -	uint32_t val;
> +#define mrc(reg)						\
> +({								\
> +	unsigned long __mrc_val;				\
> +	asm volatile("mrc " reg : "=r" (__mrc_val));		\
> +	__mrc_val;						\
> +})
>  
> -	asm volatile ("mrc	p15, 0, %0, c0, c1, 1\n" : "=r" (val));
> -	return val;
> +#define mcr(reg, val)						\
> +do {								\
> +	unsigned long __mcr_val = val;				\
> +	asm volatile("mcr " reg : : "r" (__mcr_val));		\
> +} while (0)
> +
> +
> +#define mrc_field(reg, field) \
> +	BITS_EXTRACT(mrc(reg), (reg##_##field))
> +
> +static inline unsigned long read_mpidr(void)
> +{
> +	return mrc(MPIDR) & MPIDR_ID_BITS;
>  }
>  
>  static inline void iciallu(void)
>  {
> -	uint32_t val = 0;
> -
> -	asm volatile ("mcr	p15, 0, %0, c7, c5, 0" : : "r" (val));
> +	mcr(ICIALLU, 0);
>  }
>  
>  static inline int has_gicv3_sysreg(void)
>  {
> -	return !!((read_id_pfr1() >> 28) & 0xf);
> +	return !!mrc_field(ID_PFR1, GIC);
>  }
>  
>  #endif /* __ASSEMBLY__ */
> diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
> index 65f38de..b28136a 100644
> --- a/arch/aarch32/include/asm/gic-v3.h
> +++ b/arch/aarch32/include/asm/gic-v3.h
> @@ -9,14 +9,16 @@
>  #ifndef __ASM_AARCH32_GICV3_H
>  #define __ASM_AARCH32_GICV3_H
>  
> +#include <asm/cpu.h>
> +
>  static inline void gic_write_icc_sre(uint32_t val)
>  {
> -	asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
> +	mcr(ICC_SRE, val);
>  }
>  
>  static inline void gic_write_icc_ctlr(uint32_t val)
>  {
> -	asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
> +	mcr(ICC_CTLR, val);
>  }
>  
>  #endif



From andre.przywara at arm.com  Wed Jan 26 08:35:53 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 16:35:53 +0000
Subject: [bootwrapper PATCH v3 08/15] aarch64: initialize SCTLR_ELx for
 the boot-wrapper
In-Reply-To: <20220125150057.3936090-9-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-9-mark.rutland@arm.com>
Message-ID: <20220126163553.1c6ba46e@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:50 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi,

> The SCTLR_ELx registers contain fields which are UNKNOWN or
> IMPLEMENTATION DEFINED out of reset. This includes SCTLR_ELx.EE, which
> defines the endianness of memory accesses (e.g. reads from literal
> pools). Due to this, portions of boot-wrapper code are not guaranteed
> to work correctly.
> 
> Rework the startup code to explicitly initialize SCTLR_ELx for the
> exception level the boot-wrapper was entered at. When entered at EL2
> it's necessary to first initialise HCR_EL2.E2H as this affects the RESx
> behaviour of bits in SCTLR_EL2, and also aliases SCTLR_EL1 to SCTLR_EL2,
> which would break the initialization performed in jump_kernel.
> 
> As we plan to eventually support the highest implemented EL being any of
> EL3/EL2/EL1, code is added to handle all of these exception levels, even
> though we do not currently support starting at EL1.
> 
> We'll initialize other registers in subsequent patches.

While I still would like to have seen bit 7 cleared and bit 5 set in
SCTLR_EL1, that is admittedly debatable, and any EL1 user should set that
for their EL0 themselves. The rest is fine, so:

> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  arch/aarch64/boot.S            | 74 +++++++++++++++++++++++++++-------
>  arch/aarch64/include/asm/cpu.h | 30 +++++++++++++-
>  2 files changed, 88 insertions(+), 16 deletions(-)
> 
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index d682ba5..204c199 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -26,26 +26,26 @@
>  	 *   PSCI is not supported when entered in this exception level.
>  	 */
>  ASM_FUNC(_start)
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	cmp	x0, #MPIDR_INVALID
> -	beq	err_invalid_id
> -	bl	setup_stack
> -
> -	/*
> -	 * EL3 initialisation
> -	 */
>  	mrs	x0, CurrentEL
>  	cmp	x0, #CURRENTEL_EL3
> -	b.eq	1f
> +	b.eq	reset_at_el3
> +	cmp	x0, #CURRENTEL_EL2
> +	b.eq	reset_at_el2
> +	cmp	x0, #CURRENTEL_EL1
> +	b.eq	reset_at_el1
>  
> -	mov	w0, #1
> -	ldr	x1, =flag_no_el3
> -	str	w0, [x1]
> +	/* Booting at EL0 is not supported */
> +	b	.
>  
> -	b	start_no_el3
> +	/*
> +	 * EL3 initialisation
> +	 */
> +reset_at_el3:
> +	mov_64	x0, SCTLR_EL3_RESET
> +	msr	sctlr_el3, x0
> +	isb
>  
> -1:	mov	x0, #0x30			// RES1
> +	mov	x0, #0x30			// RES1
>  	orr	x0, x0, #(1 << 0)		// Non-secure EL1
>  	orr	x0, x0, #(1 << 8)		// HVC enable
>  
> @@ -143,10 +143,54 @@ ASM_FUNC(_start)
>  	ldr	x0, =COUNTER_FREQ
>  	msr	cntfrq_el0, x0
>  
> +	cpuid	x0, x1
> +	bl	find_logical_id
> +	cmp	x0, #MPIDR_INVALID
> +	b.eq	err_invalid_id
> +	bl	setup_stack
> +
>  	bl	gic_secure_init
>  
>  	b	start_el3
>  
> +	/*
> +	 * EL2 initialization
> +	 */
> +reset_at_el2:
> +	// Ensure E2H is not in use
> +	mov_64	x0, HCR_EL2_RESET
> +	msr	hcr_el2, x0
> +	isb
> +
> +	mov_64	x0, SCTLR_EL2_RESET
> +	msr	sctlr_el2, x0
> +	isb
> +
> +	b	reset_no_el3
> +
> +	/*
> +	 * EL1 initialization
> +	 */
> +reset_at_el1:
> +	mov_64	x0, SCTLR_EL1_RESET
> +	msr	sctlr_el1, x0
> +	isb
> +
> +	b	reset_no_el3
> +
> +reset_no_el3:
> +	cpuid	x0, x1
> +	bl	find_logical_id
> +	cmp	x0, #MPIDR_INVALID
> +	b.eq	err_invalid_id
> +	bl	setup_stack
> +
> +	mov	w0, #1
> +	ldr	x1, =flag_no_el3
> +	str	w0, [x1]
> +
> +	b	start_no_el3
> +
>  err_invalid_id:
>  	b	.
>  
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 341a545..0a4085b 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -14,6 +14,35 @@
>  #define MPIDR_ID_BITS		0xff00ffffff
>  
>  #define CURRENTEL_EL3		(3 << 2)
> +#define CURRENTEL_EL2		(2 << 2)
> +#define CURRENTEL_EL1		(1 << 2)
> +
> +/*
> + * RES1 bit definitions definitions as of ARM DDI 0487G.b
> + *
> + * These includes bits which are RES1 in some configurations.
> + */
> +#define SCTLR_EL3_RES1							\
> +	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(18) | BIT(16) |	\
> +	 BIT(11) | BIT(5) | BIT(4))
> +
> +#define SCTLR_EL2_RES1							\
> +	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(18) |	\
> +	 BIT(16) | BIT(11) | BIT(5) | BIT(4))
> +
> +#define SCTLR_EL1_RES1							\
> +	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(11) |	\
> +	 BIT(8) | BIT(7) | BIT(4))
> +
> +#define HCR_EL2_RES1		(BIT(1))
> +
> +/*
> + * Initial register values required for the boot-wrapper to run out-of-reset.
> + */
> +#define SCTLR_EL3_RESET		SCTLR_EL3_RES1
> +#define SCTLR_EL2_RESET		SCTLR_EL2_RES1
> +#define SCTLR_EL1_RESET		SCTLR_EL1_RES1
> +#define HCR_EL2_RESET		HCR_EL2_RES1
>  
>  #define ID_AA64PFR0_EL1_GIC	BITS(27, 24)
>  
> @@ -43,7 +72,6 @@
>  #define ZCR_EL3_LEN_MAX		0xf
>  
>  #define SCTLR_EL1_CP15BEN	(1 << 5)
> -#define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
>  
>  #ifdef KERNEL_32
>  /*



From andre.przywara at arm.com  Wed Jan 26 08:36:02 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 16:36:02 +0000
Subject: [bootwrapper PATCH v3 11/15] aarch64: move the bulk of EL3
 initialization to C
In-Reply-To: <20220125150057.3936090-12-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-12-mark.rutland@arm.com>
Message-ID: <20220126163602.70842a29@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:53 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

> The majority of state that we initialize at EL3 is necessary for code at
> lower ELs to function, but isnt' necessary for the boot-wrapper itself.
> Given that, it would be better to write this in C where it can be
> written mode clearly, and where it will be possible to add logging/debug
> logic.
> 
> This patch migrates the AArch64 EL3 initialization to C.
> 
> There should be no functional change as a result of this patch.
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

With the changes it looks good now, also checked for the BRBE addition.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  Makefile.am                    |   2 +-
>  arch/aarch64/boot.S            | 100 +--------------------------------
>  arch/aarch64/include/asm/cpu.h |  35 +++++++++++-
>  arch/aarch64/init.c            |  72 ++++++++++++++++++++++++
>  4 files changed, 109 insertions(+), 100 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index 5a0ebd2..a5e8e8b 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -155,7 +155,7 @@ $(COMMON_SRC):
>  %.o: %.S Makefile | $(ARCH_SRC)
>  	$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
>  
> -%.o: %.c Makefile | $(COMMON_SRC)
> +%.o: %.c Makefile | $(ARCH_SRC) $(COMMON_SRC)
>  	$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
>  
>  model.lds: $(LD_SCRIPT) Makefile
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 7872daf..c0ec518 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -45,104 +45,6 @@ reset_at_el3:
>  	msr	sctlr_el3, x0
>  	isb
>  
> -	mov	x0, #0x30			// RES1
> -	orr	x0, x0, #(1 << 0)		// Non-secure EL1
> -	orr	x0, x0, #(1 << 8)		// HVC enable
> -
> -	/* Enable pointer authentication if present */
> -	mrs	x1, id_aa64isar1_el1
> -	/* We check for APA+API and GPA+GPI */
> -	ldr	x2, =((0xff << 24) | (0xff << 4))
> -	and	x1, x1, x2
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 16)		// AP key enable
> -	orr	x0, x0, #(1 << 17)		// AP insn enable
> -1:
> -	/* Enable TME if present */
> -	mrs	x1, id_aa64isar0_el1
> -	ubfx	x1, x1, #24, #4
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 34)		// TME enable
> -1:
> -	/* Enable FGT if present */
> -	mrs	x1, id_aa64mmfr0_el1
> -	ubfx	x1, x1, #56, #4
> -	cbz	x1, 1f
> -
> -	orr	x0, x0, #(1 << 27)		// FGT enable
> -1:
> -	/* Enable ECV2 if present (allows CNTPOFF_EL2) */
> -	mrs	x1, id_aa64mmfr0_el1
> -	ubfx	x1, x1, #60, #4
> -	cmp	x1, #2
> -	b.lt	1f
> -
> -	orr	x0, x0, #(1 << 28)		// ECV enable
> -1:
> -	/* Enable MTE if present */
> -	mrs	x10, id_aa64pfr1_el1
> -	ubfx	x10, x10, #8, #4
> -	cmp	x10, #2
> -	b.lt	1f
> -
> -	orr	x0, x0, #(1 << 26)		// ATA enable
> -1:
> -#ifndef KERNEL_32
> -	orr	x0, x0, #(1 << 10)		// 64-bit EL2
> -#endif
> -	msr	scr_el3, x0
> -
> -	msr	cptr_el3, xzr			// Disable copro. traps to EL3
> -
> -	mov	x0, xzr
> -	mrs	x1, id_aa64dfr0_el1
> -	ubfx	x1, x1, #32, #4
> -	cbz	x1, 1f
> -
> -	// Enable SPE for the non-secure world.
> -	orr	x0, x0, #(0x3 << 12)
> -
> -	// Do not trap PMSNEVFR_EL1 if present
> -	cmp	x1, #3
> -	b.lt	1f
> -	orr	x0, x0, #(1 << 36)
> -
> -1:	mrs	x1, id_aa64dfr0_el1
> -	ubfx	x1, x1, #44, #4
> -	cbz	x1, 1f
> -
> -	// Enable TRBE for the non-secure world.
> -	ldr	x1, =(0x3 << 24)
> -	orr	x0, x0, x1
> -
> -1:	mrs     x1, id_aa64dfr0_el1
> -	ubfx    x1, x1, #52, #4
> -	cbz     x1, 1f
> -
> -	// Enable BRBE for the non-secure world.
> -	ldr     x1, =(0x3 << 32)
> -	orr     x0, x0, x1
> -
> -1:	msr	mdcr_el3, x0			// Disable traps to EL3
> -
> -	mrs	x0, id_aa64pfr0_el1
> -	ubfx	x0, x0, #32, #4			// SVE present?
> -	cbz	x0, 1f				// Skip SVE init if not
> -
> -	mrs	x0, cptr_el3
> -	orr	x0, x0, #CPTR_EL3_EZ		// enable SVE
> -	msr	cptr_el3, x0
> -	isb
> -
> -	mov	x0, #ZCR_EL3_LEN_MAX		// SVE: Enable full vector len
> -	msr	ZCR_EL3, x0			// for EL2.
> -
> -1:
> -	ldr	x0, =COUNTER_FREQ
> -	msr	cntfrq_el0, x0
> -
>  	cpuid	x0, x1
>  	bl	find_logical_id
>  	cmp	x0, #MPIDR_INVALID
> @@ -151,6 +53,8 @@ reset_at_el3:
>  
>  	bl	cpu_init_bootwrapper
>  
> +	bl	cpu_init_el3
> +
>  	bl	gic_secure_init
>  
>  	b	start_el3
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index 0a4085b..1be2d54 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -34,7 +34,40 @@
>  	(BIT(29) | BIT(28) | BIT(23) | BIT(22) | BIT(20) | BIT(11) |	\
>  	 BIT(8) | BIT(7) | BIT(4))
>  
> -#define HCR_EL2_RES1		(BIT(1))
> +#define MDCR_EL3_NSPB_NS_NOTRAP			(UL(3) << 12)
> +#define MDCR_EL3_NSTB_NS_NOTRAP			(UL(3) << 24)
> +#define MDCR_EL3_SBRBE_NOTRAP_NOPROHIBIT	(UL(3) << 32)
> +#define MDCR_EL3_ENPMSN				BIT(36)
> +
> +#define SCR_EL3_RES1			BITS(5, 4)
> +#define SCR_EL3_NS			BIT(0)
> +#define SCR_EL3_HCE			BIT(8)
> +#define SCR_EL3_RW			BIT(10)
> +#define SCR_EL3_APK			BIT(16)
> +#define SCR_EL3_API			BIT(17)
> +#define SCR_EL3_ATA			BIT(26)
> +#define SCR_EL3_FGTEN			BIT(27)
> +#define SCR_EL3_ECVEN			BIT(28)
> +#define SCR_EL3_TME			BIT(34)
> +
> +#define HCR_EL2_RES1			BIT(1)
> +
> +#define ID_AA64DFR0_EL1_PMSVER		BITS(35, 32)
> +#define ID_AA64DFR0_EL1_TRACEBUFFER	BITS(47, 44)
> +#define ID_AA64DFR0_EL1_BRBE		BITS(55, 52)
> +
> +#define ID_AA64ISAR0_EL1_TME		BITS(27, 24)
> +
> +#define ID_AA64ISAR1_EL1_APA		BITS(7, 4)
> +#define ID_AA64ISAR1_EL1_API		BITS(11, 8)
> +#define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
> +#define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
> +
> +#define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
> +#define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
> +
> +#define ID_AA64PFR1_EL1_MTE		BITS(11, 8)
> +#define ID_AA64PFR0_EL1_SVE		BITS(35, 32)
>  
>  /*
>   * Initial register values required for the boot-wrapper to run out-of-reset.
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> index 82816e7..74190be 100644
> --- a/arch/aarch64/init.c
> +++ b/arch/aarch64/init.c
> @@ -8,6 +8,7 @@
>   */
>  #include <cpu.h>
>  #include <platform.h>
> +#include <stdbool.h>
>  
>  void announce_arch(void)
>  {
> @@ -17,3 +18,74 @@ void announce_arch(void)
>  	print_char('0' + el);
>  	print_string("\r\n");
>  }
> +
> +static inline bool kernel_is_32bit(void)
> +{
> +#ifdef KERNEL_32
> +	return true;
> +#else
> +	return false;
> +#endif
> +}
> +
> +static inline bool cpu_has_pauth(void)
> +{
> +	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
> +				       ID_AA64ISAR1_EL1_API |
> +				       ID_AA64ISAR1_EL1_GPA |
> +				       ID_AA64ISAR1_EL1_GPI;
> +
> +	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
> +}
> +
> +void cpu_init_el3(void)
> +{
> +	unsigned long scr = SCR_EL3_RES1 | SCR_EL3_NS | SCR_EL3_HCE;
> +	unsigned long mdcr = 0;
> +	unsigned long cptr = 0;
> +
> +	if (cpu_has_pauth())
> +		scr |= SCR_EL3_APK | SCR_EL3_API;
> +
> +	if (mrs_field(ID_AA64ISAR0_EL1, TME))
> +		scr |= SCR_EL3_TME;
> +
> +	if (mrs_field(ID_AA64MMFR0_EL1, FGT))
> +		scr |= SCR_EL3_FGTEN;
> +
> +	if (mrs_field(ID_AA64MMFR0_EL1, ECV) >= 2)
> +		scr |= SCR_EL3_ECVEN;
> +
> +	if (mrs_field(ID_AA64PFR1_EL1, MTE) >= 2)
> +		scr |= SCR_EL3_ATA;
> +
> +	if (!kernel_is_32bit())
> +		scr |= SCR_EL3_RW;
> +
> +	msr(SCR_EL3, scr);
> +
> +	msr(CPTR_EL3, cptr);
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, PMSVER))
> +		mdcr |= MDCR_EL3_NSPB_NS_NOTRAP;
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, PMSVER) >= 3)
> +		mdcr |= MDCR_EL3_ENPMSN;
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, TRACEBUFFER))
> +		mdcr |= MDCR_EL3_NSTB_NS_NOTRAP;
> +
> +	if (mrs_field(ID_AA64DFR0_EL1, BRBE))
> +		mdcr |= MDCR_EL3_SBRBE_NOTRAP_NOPROHIBIT;
> +
> +	msr(MDCR_EL3, mdcr);
> +
> +	if (mrs_field(ID_AA64PFR0_EL1, SVE)) {
> +		cptr |= CPTR_EL3_EZ;
> +		msr(CPTR_EL3, cptr);
> +		isb();
> +		msr(ZCR_EL3, ZCR_EL3_LEN_MAX);
> +	}
> +
> +	msr(CNTFRQ_EL0, COUNTER_FREQ);
> +}



From andre.przywara at arm.com  Wed Jan 26 08:36:30 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 16:36:30 +0000
Subject: [bootwrapper PATCH v3 14/15] Rework bootmethod initialization
In-Reply-To: <20220125150057.3936090-15-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-15-mark.rutland@arm.com>
Message-ID: <20220126163630.721aba71@donnerap.cambridge.arm.com>

On Tue, 25 Jan 2022 15:00:56 +0000
Mark Rutland <mark.rutland at arm.com> wrote:

Hi Mark,

> We currently initialize the bootmethod late, in assembly code. This
> requires us to maintain the el3/no_el3 distintion late into the boot
> process, and means we cannot produce any helpful diagnostic when booted
> at an unexpected exception level.
> 
> Rework things so that we initialize the bootmethod early, with a warning
> when things are wrong. The el3/no_el3 distinction is now irrelevant to
> the bootmethod code, and can be removed in subsequent patches.
> 
> When a boot-wrapper configured for PSCI is entered at EL2, a warning is
> looged to the serial console as:
> 
> | Boot-wrapper v0.2
> | Entered at EL2
> | Memory layout:
> | [0000000080000000..0000000080001f90] => boot-wrapper
> | [000000008000fff8..0000000080010000] => mbox
> | [0000000080200000..00000000822af200] => kernel
> | [0000000088000000..0000000088002857] => dtb
> |
> | WARNING: PSCI could not be initialized. Boot may fail
> 
> Signed-off-by: Mark Rutland <mark.rutland at arm.com>

Thanks for the changes, looks good now:

Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Cheers,
Andre

> ---
>  Makefile.am                    |  1 +
>  arch/aarch32/include/asm/cpu.h |  1 +
>  arch/aarch32/init.c            | 16 ++++++++++++++++
>  arch/aarch32/psci.S            |  8 +-------
>  arch/aarch32/utils.S           |  9 ---------
>  arch/aarch64/init.c            | 15 +++++++++++++++
>  arch/aarch64/psci.S            | 21 ++-------------------
>  arch/aarch64/spin.S            |  3 +++
>  arch/aarch64/utils.S           |  9 ---------
>  common/init.c                  |  7 ++++++-
>  common/psci.c                  | 20 +++++++++++++++++---
>  include/boot.h                 |  7 +++++++
>  12 files changed, 69 insertions(+), 48 deletions(-)
> 
> diff --git a/Makefile.am b/Makefile.am
> index a5e8e8b..40bc5d6 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -48,6 +48,7 @@ ARCH_SRC	:= arch/aarch64/
>  endif
>  
>  if PSCI
> +DEFINES		+= -DPSCI
>  ARCH_OBJ	+= psci.o
>  COMMON_OBJ	+= psci.o
>  PSCI_NODE	:= psci {				\
> diff --git a/arch/aarch32/include/asm/cpu.h b/arch/aarch32/include/asm/cpu.h
> index c1bce9a..3426075 100644
> --- a/arch/aarch32/include/asm/cpu.h
> +++ b/arch/aarch32/include/asm/cpu.h
> @@ -63,6 +63,7 @@ static inline unsigned long read_cpsr(void)
>  #define SCR		"p15, 0, %0, c1, c1, 0"
>  #define NSACR		"p15, 0, %0, c1, c1, 2"
>  #define ICIALLU		"p15, 0, %0, c7, c5, 0"
> +#define MVBAR		"p15, 0, %0, c12, c0, 1"
>  
>  #define ICC_SRE		"p15, 6, %0, c12, c12, 5"
>  #define ICC_CTLR	"p15, 6, %0, c12, c12, 4"
> diff --git a/arch/aarch32/init.c b/arch/aarch32/init.c
> index 7143c66..e25f0c7 100644
> --- a/arch/aarch32/init.c
> +++ b/arch/aarch32/init.c
> @@ -8,6 +8,7 @@
>   */
>  #include <cpu.h>
>  #include <platform.h>
> +#include <stdbool.h>
>  
>  static const char *mode_string(void)
>  {
> @@ -39,3 +40,18 @@ void cpu_init_secure_pl1(void)
>  
>  	mcr(CNTFRQ, COUNTER_FREQ);
>  }
> +
> +#ifdef PSCI
> +extern char psci_vectors[];
> +
> +bool cpu_init_psci_arch(void)
> +{
> +	if (read_cpsr_mode() != PSR_MON)
> +		return false;
> +
> +	mcr(MVBAR, (unsigned long)psci_vectors);
> +	isb();
> +
> +	return true;
> +}
> +#endif
> diff --git a/arch/aarch32/psci.S b/arch/aarch32/psci.S
> index e0d2972..cdc36b0 100644
> --- a/arch/aarch32/psci.S
> +++ b/arch/aarch32/psci.S
> @@ -15,7 +15,7 @@
>  
>  	.section .vectors
>  	.align 6
> -smc_vectors:
> +ASM_DATA(psci_vectors)
>  	b	err_exception			@ Reset
>  	b	err_exception			@ Undef
>  	b	handle_smc			@ SMC
> @@ -39,11 +39,5 @@ handle_smc:
>  	movs	pc, lr
>  
>  ASM_FUNC(start_el3)
> -	ldr	r0, =smc_vectors
> -	blx	setup_vector
> -	/* pass through */
> -
>  ASM_FUNC(start_no_el3)
> -	cpuid	r0, r1
> -	blx	find_logical_id
>  	b	psci_first_spin
> diff --git a/arch/aarch32/utils.S b/arch/aarch32/utils.S
> index 5809f48..58279aa 100644
> --- a/arch/aarch32/utils.S
> +++ b/arch/aarch32/utils.S
> @@ -35,12 +35,3 @@ ASM_FUNC(find_logical_id)
>  	bx	lr
>  3:	mov	r0, #MPIDR_INVALID
>  	bx	lr
> -
> -/*
> - * Setup EL3 vectors.
> - * r0: vector address
> - */
> -ASM_FUNC(setup_vector)
> -	mcr	p15, 0, r0, c12, c0, 1	@ MVBAR
> -	isb
> -	bx	lr
> diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
> index 74190be..6677f2b 100644
> --- a/arch/aarch64/init.c
> +++ b/arch/aarch64/init.c
> @@ -89,3 +89,18 @@ void cpu_init_el3(void)
>  
>  	msr(CNTFRQ_EL0, COUNTER_FREQ);
>  }
> +
> +#ifdef PSCI
> +extern char psci_vectors[];
> +
> +bool cpu_init_psci_arch(void)
> +{
> +	if (mrs(CurrentEL) != CURRENTEL_EL3)
> +		return false;
> +
> +	msr(VBAR_EL3, (unsigned long)psci_vectors);
> +	isb();
> +
> +	return true;
> +}
> +#endif
> diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> index 8bd224b..d6ca2eb 100644
> --- a/arch/aarch64/psci.S
> +++ b/arch/aarch64/psci.S
> @@ -19,7 +19,7 @@
>  	.section .vectors, "w"
>  
>  	.align 11
> -vector:
> +ASM_DATA(psci_vectors)
>  	// current EL, SP_EL0
>  	ventry	err_exception	// synchronous
>  	ventry	err_exception	// IRQ
> @@ -80,22 +80,5 @@ smc_exit:
>  	eret
>  
>  ASM_FUNC(start_el3)
> -	ldr	x0, =vector
> -	bl	setup_vector
> -
> -	/* only boot the primary cpu (entry 0 in the table) */
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	b	psci_first_spin
> -
> -/*
> - * This PSCI implementation requires EL3. Without EL3 we'll only boot the
> - * primary cpu, all others will be trapped in an infinite loop.
> - */
>  ASM_FUNC(start_no_el3)
> -	cpuid	x0, x1
> -	bl	find_logical_id
> -	cbz	x0, psci_first_spin
> -spin_dead:
> -	wfe
> -	b	spin_dead
> +	b	psci_first_spin
> diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
> index 1ea1c0b..764c532 100644
> --- a/arch/aarch64/spin.S
> +++ b/arch/aarch64/spin.S
> @@ -12,6 +12,9 @@
>  
>  	.text
>  
> +ASM_FUNC(cpu_init_bootmethod)
> +	ret
> +
>  ASM_FUNC(start_el3)
>  ASM_FUNC(start_no_el3)
>  	cpuid	x0, x1
> diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
> index 85c7f8a..32393cc 100644
> --- a/arch/aarch64/utils.S
> +++ b/arch/aarch64/utils.S
> @@ -32,12 +32,3 @@ ASM_FUNC(find_logical_id)
>  	ret
>  3:	mov	x0, #MPIDR_INVALID
>  	ret
> -
> -/*
> - * Setup EL3 vectors
> - * x0: vector address
> - */
> -ASM_FUNC(setup_vector)
> -	msr	VBAR_EL3, x0
> -	isb
> -	ret
> diff --git a/common/init.c b/common/init.c
> index fc74b9e..3c05ac3 100644
> --- a/common/init.c
> +++ b/common/init.c
> @@ -6,6 +6,7 @@
>   * Use of this source code is governed by a BSD-style license that can be
>   * found in the LICENSE.txt file.
>   */
> +#include <boot.h>
>  #include <cpu.h>
>  #include <platform.h>
>  
> @@ -44,7 +45,9 @@ void announce_arch(void);
>  
>  void cpu_init_bootwrapper(void)
>  {
> -	if (this_cpu_logical_id() == 0) {
> +	unsigned int cpu = this_cpu_logical_id();
> +
> +	if (cpu == 0) {
>  		init_uart();
>  		announce_bootwrapper();
>  		announce_arch();
> @@ -52,4 +55,6 @@ void cpu_init_bootwrapper(void)
>  		print_string("\r\n");
>  		init_platform();
>  	}
> +
> +	cpu_init_bootmethod(cpu);
>  }
> diff --git a/common/psci.c b/common/psci.c
> index a0e8700..5ae4255 100644
> --- a/common/psci.c
> +++ b/common/psci.c
> @@ -12,6 +12,7 @@
>  #include <bakery_lock.h>
>  #include <boot.h>
>  #include <cpu.h>
> +#include <platform.h>
>  #include <psci.h>
>  
>  #ifndef CPU_IDS
> @@ -78,12 +79,25 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
>  	}
>  }
>  
> -void __noreturn psci_first_spin(unsigned int cpu)
> +void __noreturn psci_first_spin(void)
>  {
> -	if (cpu == MPIDR_INVALID)
> -		while (1);
> +	unsigned int cpu = this_cpu_logical_id();
>  
>  	first_spin(cpu, branch_table + cpu, PSCI_ADDR_INVALID);
>  
>  	unreachable();
>  }
> +
> +void cpu_init_bootmethod(unsigned int cpu)
> +{
> +	if (cpu_init_psci_arch())
> +		return;
> +
> +	if (cpu == 0) {
> +		print_string("WARNING: PSCI could not be initialized. Boot may fail\r\n\r\n");
> +		return;
> +	}
> +
> +	while (1)
> +		wfe();
> +}
> diff --git a/include/boot.h b/include/boot.h
> index d75e013..459d1d5 100644
> --- a/include/boot.h
> +++ b/include/boot.h
> @@ -10,10 +10,17 @@
>  #define __BOOT_H
>  
>  #include <compiler.h>
> +#include <stdbool.h>
>  
>  void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
>  
>  void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
>  			   unsigned long invalid_addr);
>  
> +void cpu_init_bootmethod(unsigned int cpu);
> +
> +#ifdef PSCI
> +bool cpu_init_psci_arch(void);
> +#endif
> +
>  #endif



From alim.akhtar at samsung.com  Wed Jan 26 08:47:02 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Wed, 26 Jan 2022 22:17:02 +0530
Subject: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
In-Reply-To: <4c029f92-ece7-78c1-e64b-cbe438b45a5f@canonical.com>
References: <CGME20220124142850epcas5p2f82243b87386b3d49a9302c87e015d6b@epcas5p2.samsung.com>
 <20220124141644.71052-1-alim.akhtar@samsung.com>
 <d9682f16-13b7-b6dc-5afd-b2d319143de5@canonical.com>
 <4cfcde38-50cb-646a-0d17-c2cb2977a2e4@canonical.com>
 <063501d81281$10e5b3c0$32b11b40$@samsung.com>
 <4c029f92-ece7-78c1-e64b-cbe438b45a5f@canonical.com>
Message-ID: <067001d812d4$5a26ab40$0e7401c0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Wednesday, January 26, 2022 2:50 PM
>To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>Cc: soc at kernel.org; linux-clk at vger.kernel.org; devicetree at vger.kernel.org;
>olof at lixom.net; arnd at arndb.de; linus.walleij at linaro.org;
>catalin.marinas at arm.com; robh+dt at kernel.org; s.nawrocki at samsung.com;
>linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com;
>sboyd at kernel.org
>Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving (FSD) SoC
>
>On 26/01/2022 07:50, Alim Akhtar wrote:
>> Hi Krzysztof
>>
>>> -----Original Message-----
>>> From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>>> Sent: Tuesday, January 25, 2022 10:56 PM
>>> To: Alim Akhtar <alim.akhtar at samsung.com>; linux-arm-
>>> kernel at lists.infradead.org; linux-kernel at vger.kernel.org
>>> Cc: soc at kernel.org; linux-clk at vger.kernel.org;
>>> devicetree at vger.kernel.org; olof at lixom.net; arnd at arndb.de;
>>> linus.walleij at linaro.org; catalin.marinas at arm.com;
>>> robh+dt at kernel.org; s.nawrocki at samsung.com;
>>> linux-samsung-soc at vger.kernel.org; pankaj.dubey at samsung.com;
>>> sboyd at kernel.org
>>> Subject: Re: [PATCH v5 00/16] Add support for Tesla Full Self-Driving
>>> (FSD) SoC
>>>
>>> On 25/01/2022 18:12, Krzysztof Kozlowski wrote:
>>>> On 24/01/2022 15:16, Alim Akhtar wrote:
>>>>> Adds basic support for the Tesla Full Self-Driving (FSD) SoC. This
>>>>> SoC contains three clusters of four Cortex-A72 CPUs, as well as
>>>>> several IPs.
>>>>>
>>>>> Patches 1 to 9 provide support for the clock controller (which is
>>>>> designed similarly to Exynos SoCs).
>>>>>
>>>>> The remaining changes provide pinmux support, initial device tree
>support.
>>>>>
>>>>> - Changes since v4
>>>>> * fixed 'make dtbs_check' warnings on patch 14/16
>>>>>
>>>>> - Changes since v3
>>>>> * Addressed Stefen's review comments on patch 14/16
>>>>> * Fixed kernel test robot warning on patch 04/16
>>>>> * rebsaed this series on Krzysztof's pinmux new binding schema work
>>>>> [1]
>>>>>
>>>>> - Changes since v2
>>>>> * Addressed Krzysztof's and Stephen's review comments
>>>>> * Added Reviewed-by and Acked-by tags
>>>>> * Rebased on next-20220120
>>>>>
>>>>> - Changes since v1
>>>>> * fixed make dt_binding_check error as pointed by Rob
>>>>> * Addressed Krzysztof's and Rob's review comments
>>>>> * Added Reviewed-by and Acked-by tags
>>>>> * Dropped SPI, MCT and ADC from this series (to be posted in small
>>>>> sets)
>>>>>
>>>>> NOTE: These patches are based on Krzysztof's pinmux for-next branch
>>>>> commit 832ae134ccc1 ("pinctrl: samsung: add support for Exynos850
>>>>> and
>>>>> ExynosAutov9 wake-ups") [1]
>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung.git
>>>>> /l
>>>>> og/?h=for-next
>>>>>
>>>>>
>>>>
>>>> Thanks, applied DTS/soc and pinctrl patches.
>>>>
>>>> I expect Sylwester will pick up the clock ones. Otherwise please let
>>>> me know to pick it up as well.
>>>
>>> I forgot that clock macros are used in DTS. This does not compile and
>>> I cannot take drivers into DTS branch.
>>>
>>> Alim,
>>> DTS changes dropped. Please resend with the same trick we did for
>>> Exynos850 board - hard-coded clock IDs as defines. See:
>>>
>>> https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git/diff/a
>>> rch/arm6
>>> 4/boot/dts/exynos/exynos850.dtsi?h=samsung-dt64-5.17-
>>> 2&id=e3493220fd3e474abcdcefbe14fb60485097ce06
>>>
>> Ok, I will resend patch 14 and 15 (DTS changes) only as suggested above.
>
>I see Sylwester acked clock patches, so I will take them. No need to resend, I'll
>organize the patches so they will compile.
>
Awesome, thanks Krzysztof and Sylwester

>
>Best regards,
>Krzysztof



From robh at kernel.org  Wed Jan 26 08:47:59 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 10:47:59 -0600
Subject: [RFC V1 10/11] perf: Expand perf_branch_entry.type
In-Reply-To: <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YfF7P9flt8D2+Kfr@robh.at.kernel.org>

On Mon, Jan 24, 2022 at 10:00:52AM +0530, Anshuman Khandual wrote:
> Current perf_branch_entry.type is a 4 bits field just enough to accommodate
> 16 generic branch types. This is insufficient to accommodate platforms like
> arm64 which has much more branch types. Lets just expands this field into a
> 6 bits one, which can now hold 64 generic branch types. This also adds more
> generic branch types and updates the BRBE driver as required.
> 
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: Will Deacon <will at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu_brbe.c           |  7 ++++++-

This patch should come before the BRBE support so that it can be applied
sooner rather than later. If another field is added to the end before 
expanding this field, then you will be stuck with assembling bits from 2 
fields.

>  include/uapi/linux/perf_event.h       | 10 ++++++++--
>  tools/include/uapi/linux/perf_event.h | 10 ++++++++--
>  tools/perf/util/branch.c              |  8 +++++++-
>  4 files changed, 29 insertions(+), 6 deletions(-)


From james.morse at arm.com  Wed Jan 26 08:49:29 2022
From: james.morse at arm.com (James Morse)
Date: Wed, 26 Jan 2022 16:49:29 +0000
Subject: [PATCH 4/4] KVM: arm64: Workaround Cortex-A510's single-step and
 PAC trap errata
In-Reply-To: <87k0en7jcw.wl-maz@kernel.org>
References: <20220125153803.549084-1-james.morse@arm.com>
 <20220125153803.549084-5-james.morse@arm.com> <87mtjj7o7y.wl-maz@kernel.org>
 <711e16a1-c853-10e8-43d5-31890f0d4c7c@arm.com> <87k0en7jcw.wl-maz@kernel.org>
Message-ID: <a28f54a5-47d2-651a-0a2f-4274ab9d5855@arm.com>

Hi Marc,

On 25/01/2022 18:36, Marc Zyngier wrote:
> On Tue, 25 Jan 2022 18:19:45 +0000,
> James Morse <james.morse at arm.com> wrote:
>> On 25/01/2022 16:51, Marc Zyngier wrote:
>>> On Tue, 25 Jan 2022 15:38:03 +0000,
>>> James Morse <james.morse at arm.com> wrote:
>>>>
>>>> Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
>>>> single-stepping authenticated ERET instructions. A single step is
>>>> expected, but a pointer authentication trap is taken instead. The
>>>> erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
>>>> EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
>>>>
>>>> Because the conditions require an ERET into active-not-pending state,
>>>> this is only a problem for the EL2 when EL2 is stepping EL1. In this case
>>>> the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
>>>> restored.

>>>> diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
>>>> index 331dd10821df..93bf140cc972 100644
>>>> --- a/arch/arm64/kvm/hyp/include/hyp/switch.h
>>>> +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
>>>> @@ -440,6 +442,22 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
>>>>  			write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
>>>>  	}
>>>>  
>>>> +	/*
>>>> +	 * Check for the conditions of Cortex-A510's #2077057. When these occur
>>>> +	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
>>>> +	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
>>>> +	 * Did we just take a PAC exception when a step exception was expected?
>>>> +	 */
>>>> +	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057) &&
>>>
>>> nit: we can drop this IS_ENABLED()...
>>
>> Hmmm, I thought dead code elimination was a good thing!
>> Without the cpu_errata.c match, (which is also guarded by #ifdef),
>> the cap will never be true, even if an affected CPU showed up. This
>> way the compiler knows it can remove all this.

> I don't dispute that. However, experience shows that the more of these
> we sprinkle around, the quicker this code bitrots as we don't build
> for all the possible configurations. In general, we hardly have any
> dependency on configuration symbols, and rely on static keys got
> things not be terribly sucky.

I'll remove it - but I'm not convinced:

If this were in an #ifdef block, I agree that would prevent the compiler from even seeing
this code, and it would certainly bitrot if that Kconfig isn't selected, and would not be
build-tested properly in all the bizarre cases that only CI systems try.

But the IS_ENABLED() stuff lets the compiler can see inside that block, and means the
compiler can check the types etc, before eventually removing it as the condition becomes
"if(false)".

For example:
|	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_2077057))
|		synchronize_vcpu_pstate(42);

This fails to compile regardless of the value of the Kconfig symbol:
| In file included from arch/arm64/kvm/hyp/vhe/switch.c:7:
| ./arch/arm64/kvm/hyp/include/hyp/switch.h: In function ?synchronize_vcpu_pstate?:
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:415:27: warning: passing argument 1 of
| ?synchronize_vcpu_pstate? makes pointer from integer without a cast [-Wint-conversion]
|   415 |   synchronize_vcpu_pstate(42);
|
| ./arch/arm64/kvm/hyp/include/hyp/switch.h:405:61: note: expected ?struct kvm_vcpu *? but
| argument is of type ?int?
|  405 | static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu, u64 *exit_code)

etc.

| cat .config | grep 2077057
| # CONFIG_ARM64_ERRATUM_2077057 is not set


I guess you're worried about link errors.

[..]

>>> Other than that, I'm happy to take the series as a whole ASAP, if only
>>> for the two pretty embarrassing bug fixes. If you can respin it
>>> shortly and address the comments above, I'd like it into -rc2.
>>
>> Will do. Shout if you strongly care about the IS_ENABLED().
> 
> I'd really like it gone. Otherwise, I'll never compile that code.


Thanks,

James


From bigeasy at linutronix.de  Wed Jan 26 08:56:03 2022
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Wed, 26 Jan 2022 17:56:03 +0100
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <87czq573et.mognet@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
 <87czq573et.mognet@arm.com>
Message-ID: <YfF9I5PcZJA5532B@linutronix.de>

On 2021-08-22 19:14:18 [+0100], Valentin Schneider wrote:
> Thanks for carrying it through, I'll keep that change for the next version.

Just a quick question. This series ended with 3 patches in my queue. It
got decimated further due to Frederic series which ended up in
v5.17-rc1. I still have
| 2021-08-11 21:13 +0100 Valentin Schneider    ? sched: Introduce migratable()
| 2021-08-11 21:13 +0100 Valentin Schneider    ? arm64: mm: Make arch_faults_on_old_pte() check for migratability

what do we do about these two? I could repost these two if there are no
objections?
 
Sebastian


From robh at kernel.org  Wed Jan 26 08:59:44 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 10:59:44 -0600
Subject: [RFC V1 03/11] arm64/perf: Update struct arm_pmu for BRBE
In-Reply-To: <1642998653-21377-4-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-4-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YfF+APV2vew5AloE@robh.at.kernel.org>

On Mon, Jan 24, 2022 at 10:00:45AM +0530, Anshuman Khandual wrote:
> This updates struct arm_pmu to include all required helpers that will drive

>From submitting-patches.rst:

Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
to do frotz", as if you are giving orders to the codebase to change
its behaviour.

> BRBE functionality for a given PMU implementation. These are the following.

Don't describe what the change is, one can read the diff for that. 
Answer why it is needed.

One thing to answer in the commit msg is why we need the hooks here.  
Have we concluded that adding BRBE hooks to struct arm_pmu for what is 
an armv8 specific feature is the right approach? I don't recall 
reaching that conclusion.

> 
> - brbe_filter	: Convert perf event filters into BRBE HW filters
> - brbe_probe	: Probe BRBE HW and capture its attributes
> - brbe_enable	: Enable BRBE HW with a given config
> - brbe_disable	: Disable BRBE HW
> - brbe_read	: Read BRBE buffer for captured branch records
> - brbe_reset	: Reset BRBE buffer
> - brbe_supported: Whether BRBE is supported or not

The function names seem pretty self-explanatory, but the text is needed, 
shouldn't it be in the struct declaration.

I'm not really a fan of patches adding dead code. That's not any less to 
review. Restructuring with 'no functional change' OTOH is helpful in 
reviewing.

> A BRBE driver implementation needs to provide these functionalities.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kernel/perf_event.c | 36 ++++++++++++++++++++++++++++++++++
>  include/linux/perf/arm_pmu.h   |  7 +++++++
>  2 files changed, 43 insertions(+)
> 
> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> index cab678ed6618..f6a47036b0b4 100644
> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -1015,6 +1015,35 @@ static int armv8pmu_filter_match(struct perf_event *event)
>  	return evtype != ARMV8_PMUV3_PERFCTR_CHAIN;
>  }
>  
> +static void armv8pmu_brbe_filter(struct pmu_hw_events *hw_event, struct perf_event *event)
> +{
> +}
> +
> +static void armv8pmu_brbe_enable(struct pmu_hw_events *hw_event)
> +{
> +}
> +
> +static void armv8pmu_brbe_disable(struct pmu_hw_events *hw_event)
> +{
> +}
> +
> +static void armv8pmu_brbe_read(struct pmu_hw_events *hw_event, struct perf_event *event)
> +{
> +}
> +
> +static void armv8pmu_brbe_probe(struct pmu_hw_events *hw_event)
> +{
> +}
> +
> +static void armv8pmu_brbe_reset(struct pmu_hw_events *hw_event)
> +{
> +}
> +
> +static bool armv8pmu_brbe_supported(struct perf_event *event)
> +{
> +	return false;
> +}
> +
>  static void armv8pmu_reset(void *info)
>  {
>  	struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
> @@ -1247,6 +1276,13 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
>  
>  	cpu_pmu->pmu.event_idx		= armv8pmu_user_event_idx;
>  
> +	cpu_pmu->brbe_filter		= armv8pmu_brbe_filter;
> +	cpu_pmu->brbe_enable		= armv8pmu_brbe_enable;
> +	cpu_pmu->brbe_disable		= armv8pmu_brbe_disable;
> +	cpu_pmu->brbe_read		= armv8pmu_brbe_read;
> +	cpu_pmu->brbe_probe		= armv8pmu_brbe_probe;
> +	cpu_pmu->brbe_reset		= armv8pmu_brbe_reset;
> +	cpu_pmu->brbe_supported		= armv8pmu_brbe_supported;
>  	cpu_pmu->name			= name;
>  	cpu_pmu->map_event		= map_event;
>  	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
> index 2512e2f9cd4e..c0dd0d6c5883 100644
> --- a/include/linux/perf/arm_pmu.h
> +++ b/include/linux/perf/arm_pmu.h
> @@ -98,6 +98,13 @@ struct arm_pmu {
>  	void		(*reset)(void *);
>  	int		(*map_event)(struct perf_event *event);
>  	int		(*filter_match)(struct perf_event *event);
> +	void		(*brbe_filter)(struct pmu_hw_events *hw_events, struct perf_event *event);
> +	void		(*brbe_probe)(struct pmu_hw_events *hw_events);
> +	void		(*brbe_enable)(struct pmu_hw_events *hw_events);
> +	void		(*brbe_disable)(struct pmu_hw_events *hw_events);
> +	void		(*brbe_read)(struct pmu_hw_events *hw_events, struct perf_event *event);
> +	void		(*brbe_reset)(struct pmu_hw_events *hw_events);
> +	bool		(*brbe_supported)(struct perf_event *event);
>  	int		num_events;
>  	bool		secure_access; /* 32-bit ARM only */
>  #define ARMV8_PMUV3_MAX_COMMON_EVENTS		0x40
> -- 
> 2.25.1
> 
> 


From jszhang at kernel.org  Wed Jan 26 08:52:15 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Thu, 27 Jan 2022 00:52:15 +0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: use return val of
 readl_poll_timeout()
Message-ID: <20220126165215.1921-1-jszhang@kernel.org>

When readl_poll_timeout() timeout, we'd better directly use its return
value.

Before this patch:
[    2.145528] dwmac-sun8i: probe of 4500000.ethernet failed with error -14

After this patch:
[    2.138520] dwmac-sun8i: probe of 4500000.ethernet failed with error -110

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 617d0e4c6495..09644ab0d87a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -756,7 +756,7 @@ static int sun8i_dwmac_reset(struct stmmac_priv *priv)
 
 	if (err) {
 		dev_err(priv->device, "EMAC reset timeout\n");
-		return -EFAULT;
+		return err;
 	}
 	return 0;
 }
-- 
2.34.1



From robh at kernel.org  Wed Jan 26 09:07:24 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 11:07:24 -0600
Subject: [RFC V1 06/11] arm64/perf: Drive BRBE from perf event states
In-Reply-To: <1642998653-21377-7-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-7-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YfF/zBS3kL/+eC1k@robh.at.kernel.org>

On Mon, Jan 24, 2022 at 10:00:48AM +0530, Anshuman Khandual wrote:
> Branch stack sampling rides along the normal perf event and all the branch
> records get captured during the PMU interrupt. This just changes perf event
> handling on the arm64 platform to accommodate required BRBE operations that
> will enable branch stack sampling support.
> 
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  arch/arm64/kernel/perf_event.c |  6 +++++
>  drivers/perf/arm_pmu.c         | 40 ++++++++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> index f6a47036b0b4..11c82c8f2eec 100644
> --- a/arch/arm64/kernel/perf_event.c
> +++ b/arch/arm64/kernel/perf_event.c
> @@ -864,6 +864,12 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
>  		if (!armpmu_event_set_period(event))
>  			continue;
>  
> +		if (has_branch_stack(event)) {
> +			cpu_pmu->brbe_read(cpuc, event);

Is has_branch_stack() guaranteed to be false on arm32? If not, this will 
be a NULL function ptr. 

To add to my other comments, this patch is where I would add 
brbe_read(), etc. to arm_pmu.

Rob


From frank-w at public-files.de  Wed Jan 26 09:10:33 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Wed, 26 Jan 2022 18:10:33 +0100
Subject: Aw: [PATCH 27/27] drm: rockchip: Add VOP2 driver
In-Reply-To: <20220126145549.617165-28-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-28-s.hauer@pengutronix.de>
Message-ID: <trinity-29a2d337-830f-4ff2-861d-bbe695726bbf-1643217033760@3c-app-gmx-bap59>

Hi Sascha

tested full series on Bananapi r2 Pro V0 prototype (rk3568)

4K at 60Hz
1080p at 60Hz

both look good

Tested-By: Frank Wunderlich <frank-w at public-files.de>

regards Frank


From madvenka at linux.microsoft.com  Wed Jan 26 09:14:10 2022
From: madvenka at linux.microsoft.com (Madhavan T. Venkataraman)
Date: Wed, 26 Jan 2022 11:14:10 -0600
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <TY2PR01MB5257BE671A481D81F1A40E0185209@TY2PR01MB5257.jpnprd01.prod.outlook.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
 <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
 <825b8b72-c746-ba24-7142-3fff481e82d6@linux.microsoft.com>
 <TY2PR01MB5257BE671A481D81F1A40E0185209@TY2PR01MB5257.jpnprd01.prod.outlook.com>
Message-ID: <1a0e19db-a7f8-4c8e-0163-398fcd364d54@linux.microsoft.com>



On 1/26/22 04:20, nobuta.keiya at fujitsu.com wrote:
>> I have not seen any activity on that in a long time. IIRC, Julien quit RedHat.
>> I don't know if anyone else has taken over this work in RedHat.
>>
>> Sorry, I don't have any more information.
>>
>> Madhavan
> 
> Thanks for your information.
> 
> By the way, I'm considering test code for arch_stack_walk_reliable().
> Specifically, I apply Suraj's patch to enable livepatch, and added a function
> that sleeps between SYM_CODE_START and SYM_CODE_END, then livepatch
> checks if the task has an unreliable stack.
> For now my internal test code working correctly, but my Kconfig excludes
> STACK_VALIDATION dependency.
> 
> It seems that objtool will not be enabled yet, so I would like to test it easier.
> If you are already testing with this patch, could you tell me how to do it?
> 
> 

For now, I have an instrumented kernel that directly invokes arch_stack_walk_reliable()
from various places in the kernel (interrupt handlers, exception handlers, ftrace entry,
kprobe handler, etc). I also have a test driver to induce conditions like null pointer
dereference. I use this to test different cases where arch_stack_walk_reliable() should
return an error.

As for livepatch testing, I have enhanced objtool and the kernel so the frame pointer can
be validated dynamically rather than statically. I have tested various different livepatch
selftests successfully. I have also written my own livepatch tests to add to the selftests.
I am currently working on preparing an RFC patch series for review. Basically, this series
implements STACK_VALIDATION in a different way.

I plan to publish my work soon (hopefully Feb 2022). I was going to do in December. However,
my workload in Microsoft did not permit me to do that. I am also planning to set up a github
repo so people can try out my changes, if they are interested.

So, stay tuned.

Madhavan


From jernej.skrabec at gmail.com  Wed Jan 26 09:14:25 2022
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Wed, 26 Jan 2022 18:14:25 +0100
Subject: [PATCH] net: stmmac: dwmac-sun8i: use return val of
 readl_poll_timeout()
In-Reply-To: <20220126165215.1921-1-jszhang@kernel.org>
References: <20220126165215.1921-1-jszhang@kernel.org>
Message-ID: <5533854.DvuYhMxLoT@kista>

Hi!

Dne sreda, 26. januar 2022 ob 17:52:15 CET je Jisheng Zhang napisal(a):
> When readl_poll_timeout() timeout, we'd better directly use its return
> value.
> 
> Before this patch:
> [    2.145528] dwmac-sun8i: probe of 4500000.ethernet failed with error -14
> 
> After this patch:
> [    2.138520] dwmac-sun8i: probe of 4500000.ethernet failed with error -110
> 
> Signed-off-by: Jisheng Zhang <jszhang at kernel.org>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Best regards,
Jernej

> ---
>  drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/
ethernet/stmicro/stmmac/dwmac-sun8i.c
> index 617d0e4c6495..09644ab0d87a 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
> @@ -756,7 +756,7 @@ static int sun8i_dwmac_reset(struct stmmac_priv *priv)
>  
>  	if (err) {
>  		dev_err(priv->device, "EMAC reset timeout\n");
> -		return -EFAULT;
> +		return err;
>  	}
>  	return 0;
>  }
> -- 
> 2.34.1
> 
> 




From broonie at kernel.org  Wed Jan 26 09:16:17 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 17:16:17 +0000
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
 <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
Message-ID: <YfGB4RnMjl9W6iso@sirena.org.uk>

On Tue, Jan 25, 2022 at 05:21:27AM +0000, nobuta.keiya at fujitsu.com wrote:

> I know that Julien Thierry published objtool support for arm64 [1], but I'm not
> sure if it has been updated. Could you tell me other threads if you know?

I've not heard of anyone else picking that up.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/70627a87/attachment.sig>

From robh at kernel.org  Wed Jan 26 09:18:59 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 11:18:59 -0600
Subject: [RFC V1 05/11] arm64/perf: Detect support for BRBE
In-Reply-To: <1642998653-21377-6-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-6-git-send-email-anshuman.khandual@arm.com>
Message-ID: <YfGCgwlk6wHS/OYe@robh.at.kernel.org>

On Mon, Jan 24, 2022 at 10:00:47AM +0530, Anshuman Khandual wrote:
> CPU specific BRBE entries, cycle count, format support gets detected during
> PMU init. This information gets saved in per-cpu struct pmu_hw_events which
> later helps in operating BRBE during a perf event context.

Another NOP commit. The subject says 'arm64' and that we detect BRBE 
support. This patch neither touches arm64 code nor detects anything.

> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu_platform.c | 34 +++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
> index 513de1f54e2d..800e4a6e8bc3 100644
> --- a/drivers/perf/arm_pmu_platform.c
> +++ b/drivers/perf/arm_pmu_platform.c
> @@ -172,6 +172,36 @@ static int armpmu_request_irqs(struct arm_pmu *armpmu)
>  	return err;
>  }
>  
> +static void arm_brbe_probe_cpu(void *info)
> +{
> +	struct pmu_hw_events *hw_events;
> +	struct arm_pmu *armpmu = info;
> +
> +	/*
> +	 * Return from here, if BRBE driver has not been
> +	 * implemented for this PMU. This helps prevent
> +	 * kernel crash later when brbe_probe() will be
> +	 * called on the PMU.
> +	 */
> +	if (!armpmu->brbe_probe)
> +		return;
> +
> +	hw_events = per_cpu_ptr(armpmu->hw_events, smp_processor_id());
> +	armpmu->brbe_probe(hw_events);
> +}
> +
> +static int armpmu_request_brbe(struct arm_pmu *armpmu)
> +{
> +	int cpu, err = 0;
> +
> +	for_each_cpu(cpu, &armpmu->supported_cpus) {
> +		err = smp_call_function_single(cpu, arm_brbe_probe_cpu, armpmu, 1);
> +		if (err)
> +			return err;
> +	}
> +	return err;
> +}
> +
>  static void armpmu_free_irqs(struct arm_pmu *armpmu)
>  {
>  	int cpu;
> @@ -229,6 +259,10 @@ int arm_pmu_device_probe(struct platform_device *pdev,
>  	if (ret)
>  		goto out_free_irqs;
>  
> +	ret = armpmu_request_brbe(pmu);
> +	if (ret)
> +		goto out_free_irqs;
> +
>  	ret = armpmu_register(pmu);
>  	if (ret) {
>  		dev_err(dev, "failed to register PMU devices!\n");
> -- 
> 2.25.1
> 
> 


From james.clark at arm.com  Wed Jan 26 09:27:19 2022
From: james.clark at arm.com (James Clark)
Date: Wed, 26 Jan 2022 17:27:19 +0000
Subject: [RFC V1 11/11] perf: Capture branch privilege information
In-Reply-To: <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-12-git-send-email-anshuman.khandual@arm.com>
Message-ID: <b85da904-50cb-b7e3-1429-6f5ef244567b@arm.com>



On 24/01/2022 04:30, Anshuman Khandual wrote:
> Platforms like arm64 could capture privilege level information for all the
> branch records. Hence this adds a new element in the struct branch_entry to
> record the privilege level information, which could be requested through a
> new event.attr.branch_sample_type flag PERF_SAMPLE_BRANCH_PRIV_SAVE. While
> here, update the BRBE driver as required.
> 
> Cc: Will Deacon <will at kernel.org>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Peter Zijlstra <peterz at infradead.org>
> Cc: Ingo Molnar <mingo at redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> Cc: Jiri Olsa <jolsa at redhat.com>
> Cc: Namhyung Kim <namhyung at kernel.org>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-perf-users at vger.kernel.org
> Cc: linux-kernel at vger.kernel.org
> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> ---
>  drivers/perf/arm_pmu_brbe.c              | 28 ++++++++++++++++++++++++
>  include/linux/perf_event.h               |  5 +++++
>  include/uapi/linux/perf_event.h          | 13 ++++++++++-
>  tools/include/uapi/linux/perf_event.h    | 13 ++++++++++-
>  tools/perf/Documentation/perf-record.txt |  1 +
>  tools/perf/util/parse-branch-options.c   |  1 +
>  6 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
> index 7cd1208c6c58..d4cbea74c148 100644
> --- a/drivers/perf/arm_pmu_brbe.c
> +++ b/drivers/perf/arm_pmu_brbe.c
> @@ -270,6 +270,25 @@ static int brbe_fetch_perf_type(u64 brbinf)
>  	}
>  }
>  
> +static int brbe_fetch_perf_priv(u64 brbinf)
> +{
> +	int brbe_el = brbe_fetch_el(brbinf);
> +
> +	switch (brbe_el) {
> +	case BRBINF_EL_EL0:
> +		return PERF_BR_USER;
> +	case BRBINF_EL_EL1:
> +		return PERF_BR_KERNEL;
> +	case BRBINF_EL_EL2:
> +		if (is_kernel_in_hyp_mode())
> +			return PERF_BR_KERNEL;
> +		return PERF_BR_HV;
> +	default:
> +		pr_warn("unknown branch privilege captured\n");
> +		return -1;
> +	}
> +}
> +
>  static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *event,
>  			       u64 brbinf, int idx)
>  {
> @@ -302,6 +321,15 @@ static void capture_brbe_flags(struct pmu_hw_events *cpuc, struct perf_event *ev
>  			cpuc->brbe_entries[idx].in_tx = brbinf & BRBINF_TX;
>  		}
>  	}
> +
> +	if (branch_sample_priv(event)) {
> +		/*
> +		 * All these information (i.e branch privilege level) are not
> +		 * available for source only branch records.
> +		 */
> +		if (type != BRBINF_VALID_SOURCE)
> +			cpuc->brbe_entries[idx].priv = brbe_fetch_perf_priv(brbinf);
> +	}
>  }
>  
>  /*
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 916ce5102b33..8021b6a30d86 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -1688,4 +1688,9 @@ static inline bool branch_sample_hw_index(const struct perf_event *event)
>  {
>  	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_HW_INDEX;
>  }
> +
> +static inline bool branch_sample_priv(const struct perf_event *event)
> +{
> +	return event->attr.branch_sample_type & PERF_SAMPLE_BRANCH_PRIV_SAVE;
> +}
>  #endif /* _LINUX_PERF_EVENT_H */
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 361fdc6b87a0..4d77710f7a4e 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +
>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER	= 0,
> +	PERF_BR_KERNEL	= 1,
> +	PERF_BR_HV	= 2,
> +};
> +

Can we have 0 as "UNKNOWN". It's going to be difficult to parse files when privilege information
isn't saved and get accurate results without that. For example if it's not set then presumably
the field would be 0 (PERF_BR_USER), but that doesn't mean the samples are user in that case.

I know you might be able to go backwards and look at what arguments were passed to the kernel but
it's not guaranteed that the kernel honored the request anyway. There are also other platforms
to think about etc.

If you look at the branch type definitions above they start at 0 (PERF_BR_UNKNOWN) which I think
works out quite nicely in the userspace code.

>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
> index 9a82b8aaed93..a2208400b0b9 100644
> --- a/tools/include/uapi/linux/perf_event.h
> +++ b/tools/include/uapi/linux/perf_event.h
> @@ -204,6 +204,8 @@ enum perf_branch_sample_type_shift {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT	= 17, /* save low level index of raw branch records */
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT	= 18, /* save privillege mode */
> +
>  	PERF_SAMPLE_BRANCH_MAX_SHIFT		/* non-ABI */
>  };
>  
> @@ -233,6 +235,8 @@ enum perf_branch_sample_type {
>  
>  	PERF_SAMPLE_BRANCH_HW_INDEX	= 1U << PERF_SAMPLE_BRANCH_HW_INDEX_SHIFT,
>  
> +	PERF_SAMPLE_BRANCH_PRIV_SAVE	= 1U << PERF_SAMPLE_BRANCH_PRIV_SAVE_SHIFT,
> +
>  	PERF_SAMPLE_BRANCH_MAX		= 1U << PERF_SAMPLE_BRANCH_MAX_SHIFT,
>  };
>  
> @@ -265,6 +269,12 @@ enum {
>  	PERF_BR_MAX,
>  };
>  
> +enum {
> +	PERF_BR_USER    = 0,
> +	PERF_BR_KERNEL  = 1,
> +	PERF_BR_HV      = 2,
> +};
> +
>  #define PERF_SAMPLE_BRANCH_PLM_ALL \
>  	(PERF_SAMPLE_BRANCH_USER|\
>  	 PERF_SAMPLE_BRANCH_KERNEL|\
> @@ -1377,7 +1387,8 @@ struct perf_branch_entry {
>  		abort:1,    /* transaction abort */
>  		cycles:16,  /* cycle count to last branch */
>  		type:6,     /* branch type */
> -		reserved:38;
> +		priv:2,     /* privilege level */
> +		reserved:36;
>  };
>  
>  union perf_sample_weight {
> diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
> index 9ccc75935bc5..3e33686977a1 100644
> --- a/tools/perf/Documentation/perf-record.txt
> +++ b/tools/perf/Documentation/perf-record.txt
> @@ -387,6 +387,7 @@ following filters are defined:
>  	- abort_tx: only when the target is a hardware transaction abort
>  	- cond: conditional branches
>  	- save_type: save branch type during sampling in case binary is not available later
> +	- priv: save privilege state during sampling in case binary is not available later
>  
>  +
>  The option requires at least one branch type among any, any_call, any_ret, ind_call, cond.
> diff --git a/tools/perf/util/parse-branch-options.c b/tools/perf/util/parse-branch-options.c
> index bb4aa88c50a8..00588b9db474 100644
> --- a/tools/perf/util/parse-branch-options.c
> +++ b/tools/perf/util/parse-branch-options.c
> @@ -32,6 +32,7 @@ static const struct branch_mode branch_modes[] = {
>  	BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
>  	BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE),
>  	BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK),
> +	BRANCH_OPT("priv", PERF_SAMPLE_BRANCH_PRIV_SAVE),
>  	BRANCH_END
>  };
>  
> 


From ardb at kernel.org  Wed Jan 26 09:30:00 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:00 +0100
Subject: [RFC PATCH 01/12] asm-generic/pgalloc: allow arch to override PMD
 alloc/free routines
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-2-ardb@kernel.org>

Extend the existing CPP macro based hooks that allow architectures to
specialize the code that allocates and frees pages to be used as page
tables.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 include/asm-generic/pgalloc.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 977bea16cf1b..65f31f615d99 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -34,6 +34,7 @@ static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
 }
 #endif
 
+#ifndef __HAVE_ARCH_PTE_FREE_KERNEL
 /**
  * pte_free_kernel - free PTE-level kernel page table page
  * @mm: the mm_struct of the current context
@@ -43,6 +44,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 {
 	free_page((unsigned long)pte);
 }
+#endif
 
 /**
  * __pte_alloc_one - allocate a page for PTE-level user page table
@@ -91,6 +93,7 @@ static inline pgtable_t pte_alloc_one(struct mm_struct *mm)
  * done with a reference count in struct page.
  */
 
+#ifndef __HAVE_ARCH_PTE_FREE
 /**
  * pte_free - free PTE-level user page table page
  * @mm: the mm_struct of the current context
@@ -101,11 +104,11 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte_page)
 	pgtable_pte_page_dtor(pte_page);
 	__free_page(pte_page);
 }
+#endif
 
 
 #if CONFIG_PGTABLE_LEVELS > 2
 
-#ifndef __HAVE_ARCH_PMD_ALLOC_ONE
 /**
  * pmd_alloc_one - allocate a page for PMD-level page table
  * @mm: the mm_struct of the current context
@@ -116,7 +119,7 @@ static inline void pte_free(struct mm_struct *mm, struct page *pte_page)
  *
  * Return: pointer to the allocated memory or %NULL on error
  */
-static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+static inline pmd_t *__pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 {
 	struct page *page;
 	gfp_t gfp = GFP_PGTABLE_USER;
@@ -132,6 +135,12 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
 	}
 	return (pmd_t *)page_address(page);
 }
+
+#ifndef __HAVE_ARCH_PMD_ALLOC_ONE
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	return __pmd_alloc_one(mm, addr);
+}
 #endif
 
 #ifndef __HAVE_ARCH_PMD_FREE
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:29:59 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:29:59 +0100
Subject: [RFC PATCH 00/12] arm64: implement read-only page tables
Message-ID: <20220126173011.3476262-1-ardb@kernel.org>

This RFC series implements support for mapping all user and kernel page
tables read-only in the linear map, and using a special fixmap slot to
make any modifications.

The purpose is to prevent page tables from being manipulated
inadvertently, which is becoming more and more important on arm64, as
many new hardening features such as BTI and MTE are controlled via
attributes in the page tables.

This series is only half of the work that is underway to implement this
in terms of hypervisor services rather than fixmap pokes, as this will
allow the hypervisor to remove all write permissions from pages used as
page tables. This work is being done in the context of the pKVM project,
which defines a clear boundary between the hypervisor executing at EL2,
and the [untrusted] host running at EL1. In this context, managing the
host's page tables at HYP level should increase the robustness of the
entire system substantially.

This series is posted separately for discussion, as it introduces the
changes that are necessary to route all page table updates via a small
set of helpers, allowing us to choose between unprotected, fixmap or HYP
protection straight-forwardly.

The pKVM specific changes will be posted as a followup series.

Cc: Will Deacon <will at kernel.org>
Cc: Marc Zyngier <maz at kernel.org>
Cc: Fuad Tabba <tabba at google.com>
Cc: Quentin Perret <qperret at google.com>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: James Morse <james.morse at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>

Ard Biesheuvel (12):
  asm-generic/pgalloc: allow arch to override PMD alloc/free routines
  arm64: mm: add helpers to remap page tables read-only/read-write
  arm64: mm: use a fixmap slot for user page table modifications
  arm64: mm: remap PGD pages r/o in the linear region after allocation
  arm64: mm: remap PUD pages r/o in linear region
  arm64: mm: remap PMD pages r/o in linear region
  arm64: mm: remap PTE level user page tables r/o in the linear region
  arm64: mm: remap kernel PTE level page tables r/o in the linear region
  arm64: mm: remap kernel page tables read-only at end of init
  mm: add default definition of p4d_index()
  arm64: efi: use set_pte_at() not set_pte() in order to pass mm pointer
  arm64: hugetlb: use set_pte_at() not set_pte() to provide mm pointer

 arch/arm64/Kconfig               |  11 ++
 arch/arm64/include/asm/fixmap.h  |   1 +
 arch/arm64/include/asm/pgalloc.h |  49 ++++++++-
 arch/arm64/include/asm/pgtable.h |  82 +++++++++++---
 arch/arm64/include/asm/tlb.h     |   6 +
 arch/arm64/kernel/efi.c          |   2 +-
 arch/arm64/mm/Makefile           |   2 +
 arch/arm64/mm/fault.c            |   8 +-
 arch/arm64/mm/hugetlbpage.c      |   4 +-
 arch/arm64/mm/mmu.c              | 115 +++++++++++++++++++-
 arch/arm64/mm/pageattr.c         |  14 +++
 arch/arm64/mm/pgd.c              |  25 +++--
 arch/arm64/mm/ro_page_tables.c   | 100 +++++++++++++++++
 include/asm-generic/pgalloc.h    |  13 ++-
 include/linux/pgtable.h          |   8 ++
 15 files changed, 405 insertions(+), 35 deletions(-)
 create mode 100644 arch/arm64/mm/ro_page_tables.c


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:01 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:01 +0100
Subject: [RFC PATCH 02/12] arm64: mm: add helpers to remap page tables
 read-only/read-write
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-3-ardb@kernel.org>

Add a couple of helpers to remap a single page read-only or read-write
via its linear address. This will be used for mappings of page table
pages in the linear region.

Note that set_memory_ro/set_memory_rw operate on addresses in the
vmalloc space only, so they cannot be used here.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgtable.h |  3 +++
 arch/arm64/mm/pageattr.c         | 14 ++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c4ba047a82d2..8d3806c68687 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -34,6 +34,9 @@
 #include <linux/mm_types.h>
 #include <linux/sched.h>
 
+int set_pgtable_ro(void *addr);
+int set_pgtable_rw(void *addr);
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
 
diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c
index a3bacd79507a..61f4aca08b95 100644
--- a/arch/arm64/mm/pageattr.c
+++ b/arch/arm64/mm/pageattr.c
@@ -153,6 +153,20 @@ int set_memory_valid(unsigned long addr, int numpages, int enable)
 					__pgprot(PTE_VALID));
 }
 
+int set_pgtable_ro(void *addr)
+{
+	return __change_memory_common((u64)addr, PAGE_SIZE,
+				      __pgprot(PTE_RDONLY),
+				      __pgprot(PTE_WRITE));
+}
+
+int set_pgtable_rw(void *addr)
+{
+	return __change_memory_common((u64)addr, PAGE_SIZE,
+				      __pgprot(PTE_WRITE),
+				      __pgprot(PTE_RDONLY));
+}
+
 int set_direct_map_invalid_noflush(struct page *page)
 {
 	struct page_change_data data = {
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:02 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:02 +0100
Subject: [RFC PATCH 03/12] arm64: mm: use a fixmap slot for user page table
 modifications
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-4-ardb@kernel.org>

To prepare for user and kernel page tables being remapped read-only in
the linear region, define a new fixmap slot and use it to apply all page
table descriptor updates that target page tables other than swapper.

Fortunately for us, the fixmap descriptors themselves are always
manipulated via their kernel mapping in .bss, so there is no special
exception required to avoid circular logic here.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/Kconfig               |  11 +++
 arch/arm64/include/asm/fixmap.h  |   1 +
 arch/arm64/include/asm/pgalloc.h |  28 +++++-
 arch/arm64/include/asm/pgtable.h |  79 +++++++++++++---
 arch/arm64/mm/Makefile           |   2 +
 arch/arm64/mm/fault.c            |   8 +-
 arch/arm64/mm/ro_page_tables.c   | 100 ++++++++++++++++++++
 7 files changed, 209 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..a3e98286b074 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1311,6 +1311,17 @@ config RODATA_FULL_DEFAULT_ENABLED
 	  This requires the linear region to be mapped down to pages,
 	  which may adversely affect performance in some cases.
 
+config ARM64_RO_PAGE_TABLES
+	bool "Remap page tables read-only in the kernel VA space"
+	select RODATA_FULL_DEFAULT_ENABLED
+	help
+	  Remap linear mappings of page table pages read-only as long as they
+	  are being used as such, and use a fixmap API to manipulate all page
+	  table descriptors, instead of manipulating them directly via their
+	  writable mappings in the direct map. This is intended as a debug
+	  and/or hardening feature, as it removes the ability for stray writes
+	  to be exploited to bypass permission restrictions.
+
 config ARM64_SW_TTBR0_PAN
 	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
 	help
diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
index 4335800201c9..71dfbe0452bb 100644
--- a/arch/arm64/include/asm/fixmap.h
+++ b/arch/arm64/include/asm/fixmap.h
@@ -50,6 +50,7 @@ enum fixed_addresses {
 
 	FIX_EARLYCON_MEM_BASE,
 	FIX_TEXT_POKE0,
+	FIX_TEXT_POKE_PTE,
 
 #ifdef CONFIG_ACPI_APEI_GHES
 	/* Used for GHES mapping from assorted contexts */
diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 237224484d0f..d54ac9f8d6c7 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -30,7 +30,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
 	pudval_t pudval = PUD_TYPE_TABLE;
 
 	pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
-	__pud_populate(pudp, __pa(pmdp), pudval);
+	if (page_tables_are_ro())
+		xchg_ro_pte(mm, (pte_t *)pudp,
+			    __pte(__phys_to_pud_val(__pa(pmdp) | pudval)));
+	else
+		__pud_populate(pudp, __pa(pmdp), pudval);
 }
 #else
 static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
@@ -51,7 +55,11 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
 	p4dval_t p4dval = P4D_TYPE_TABLE;
 
 	p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
-	__p4d_populate(p4dp, __pa(pudp), p4dval);
+	if (page_tables_are_ro())
+		xchg_ro_pte(mm, (pte_t *)p4dp,
+			    __pte(__phys_to_p4d_val(__pa(pudp) | p4dval)));
+	else
+		__p4d_populate(p4dp, __pa(pudp), p4dval);
 }
 #else
 static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
@@ -76,15 +84,27 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
 static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
 {
+	pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN;
+
 	VM_BUG_ON(mm && mm != &init_mm);
-	__pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
+	if (page_tables_are_ro())
+		xchg_ro_pte(mm, (pte_t *)pmdp,
+			    __pte(__phys_to_pmd_val(__pa(ptep) | pmdval)));
+	else
+		__pmd_populate(pmdp, __pa(ptep), pmdval);
 }
 
 static inline void
 pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
 {
+	pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_PXN;
+
 	VM_BUG_ON(mm == &init_mm);
-	__pmd_populate(pmdp, page_to_phys(ptep), PMD_TYPE_TABLE | PMD_TABLE_PXN);
+	if (page_tables_are_ro())
+		xchg_ro_pte(mm, (pte_t *)pmdp,
+			    __pte(__phys_to_pmd_val(page_to_phys(ptep) | pmdval)));
+	else
+		__pmd_populate(pmdp, page_to_phys(ptep), pmdval);
 }
 
 #endif
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 8d3806c68687..a8daea6b4ac9 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -30,6 +30,7 @@
 
 #include <asm/cmpxchg.h>
 #include <asm/fixmap.h>
+#include <linux/jump_label.h>
 #include <linux/mmdebug.h>
 #include <linux/mm_types.h>
 #include <linux/sched.h>
@@ -37,6 +38,17 @@
 int set_pgtable_ro(void *addr);
 int set_pgtable_rw(void *addr);
 
+DECLARE_STATIC_KEY_FALSE(ro_page_tables);
+
+static inline bool page_tables_are_ro(void)
+{
+	return IS_ENABLED(CONFIG_ARM64_RO_PAGE_TABLES) &&
+	       static_branch_unlikely(&ro_page_tables);
+}
+
+pte_t xchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t pte);
+pte_t cmpxchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t old, pte_t new);
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
 
@@ -89,7 +101,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
 	__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
 
 #define pte_none(pte)		(!pte_val(pte))
-#define pte_clear(mm,addr,ptep)	set_pte(ptep, __pte(0))
+#define pte_clear(mm,addr,ptep)	set_pte_at(mm, addr, ptep, __pte(0))
 #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
 
 /*
@@ -257,7 +269,10 @@ static inline pte_t pte_mkdevmap(pte_t pte)
 
 static inline void set_pte(pte_t *ptep, pte_t pte)
 {
-	WRITE_ONCE(*ptep, pte);
+	if (page_tables_are_ro())
+		xchg_ro_pte(&init_mm, ptep, pte);
+	else
+		WRITE_ONCE(*ptep, pte);
 
 	/*
 	 * Only if the new pte is valid and kernel, otherwise TLB maintenance
@@ -343,7 +358,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
 
 	__check_racy_pte_update(mm, ptep, pte);
 
-	set_pte(ptep, pte);
+	if (page_tables_are_ro())
+		xchg_ro_pte(mm, ptep, pte);
+	else
+		set_pte(ptep, pte);
 }
 
 /*
@@ -579,7 +597,10 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 	}
 #endif /* __PAGETABLE_PMD_FOLDED */
 
-	WRITE_ONCE(*pmdp, pmd);
+	if (page_tables_are_ro())
+		xchg_ro_pte(&init_mm, (pte_t *)pmdp, pmd_pte(pmd));
+	else
+		WRITE_ONCE(*pmdp, pmd);
 
 	if (pmd_valid(pmd)) {
 		dsb(ishst);
@@ -589,7 +610,10 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 
 static inline void pmd_clear(pmd_t *pmdp)
 {
-	set_pmd(pmdp, __pmd(0));
+	if (page_tables_are_ro())
+		xchg_ro_pte(NULL, (pte_t *)pmdp, __pte(0));
+	else
+		set_pmd(pmdp, __pmd(0));
 }
 
 static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
@@ -640,7 +664,10 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 	}
 #endif /* __PAGETABLE_PUD_FOLDED */
 
-	WRITE_ONCE(*pudp, pud);
+	if (page_tables_are_ro())
+		xchg_ro_pte(&init_mm, (pte_t *)pudp, pud_pte(pud));
+	else
+		WRITE_ONCE(*pudp, pud);
 
 	if (pud_valid(pud)) {
 		dsb(ishst);
@@ -650,7 +677,10 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 
 static inline void pud_clear(pud_t *pudp)
 {
-	set_pud(pudp, __pud(0));
+	if (page_tables_are_ro())
+		xchg_ro_pte(NULL, (pte_t *)pudp, __pte(0));
+	else
+		set_pud(pudp, __pud(0));
 }
 
 static inline phys_addr_t pud_page_paddr(pud_t pud)
@@ -704,14 +734,20 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
 		return;
 	}
 
-	WRITE_ONCE(*p4dp, p4d);
+	if (page_tables_are_ro())
+		xchg_ro_pte(&init_mm, (pte_t *)p4dp, p4d_pte(p4d));
+	else
+		WRITE_ONCE(*p4dp, p4d);
 	dsb(ishst);
 	isb();
 }
 
 static inline void p4d_clear(p4d_t *p4dp)
 {
-	set_p4d(p4dp, __p4d(0));
+	if (page_tables_are_ro())
+		xchg_ro_pte(NULL, (pte_t *)p4dp, __pte(0));
+	else
+		set_p4d(p4dp, __p4d(0));
 }
 
 static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
@@ -806,7 +842,7 @@ static inline int pgd_devmap(pgd_t pgd)
  * Atomic pte/pmd modifications.
  */
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-static inline int __ptep_test_and_clear_young(pte_t *ptep)
+static inline int __ptep_test_and_clear_young(struct mm_struct *mm, pte_t *ptep)
 {
 	pte_t old_pte, pte;
 
@@ -814,8 +850,13 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
 	do {
 		old_pte = pte;
 		pte = pte_mkold(pte);
-		pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
-					       pte_val(old_pte), pte_val(pte));
+
+		if (page_tables_are_ro())
+			pte = cmpxchg_ro_pte(mm, ptep, old_pte, pte);
+		else
+			pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
+						       pte_val(old_pte),
+						       pte_val(pte));
 	} while (pte_val(pte) != pte_val(old_pte));
 
 	return pte_young(pte);
@@ -825,7 +866,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
 					    unsigned long address,
 					    pte_t *ptep)
 {
-	return __ptep_test_and_clear_young(ptep);
+	return __ptep_test_and_clear_young(vma->vm_mm, ptep);
 }
 
 #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
@@ -863,6 +904,8 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 				       unsigned long address, pte_t *ptep)
 {
+	if (page_tables_are_ro())
+		return xchg_ro_pte(mm, ptep, __pte(0));
 	return __pte(xchg_relaxed(&pte_val(*ptep), 0));
 }
 
@@ -888,8 +931,12 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
 	do {
 		old_pte = pte;
 		pte = pte_wrprotect(pte);
-		pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
-					       pte_val(old_pte), pte_val(pte));
+		if (page_tables_are_ro())
+			pte = cmpxchg_ro_pte(mm, ptep, old_pte, pte);
+		else
+			pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
+						       pte_val(old_pte),
+						       pte_val(pte));
 	} while (pte_val(pte) != pte_val(old_pte));
 }
 
@@ -905,6 +952,8 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
 static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
 		unsigned long address, pmd_t *pmdp, pmd_t pmd)
 {
+	if (page_tables_are_ro())
+		return pte_pmd(xchg_ro_pte(vma->vm_mm, (pte_t *)pmdp, pmd_pte(pmd)));
 	return __pmd(xchg_relaxed(&pmd_val(*pmdp), pmd_val(pmd)));
 }
 #endif
diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
index ff1e800ba7a1..7750cafd969a 100644
--- a/arch/arm64/mm/Makefile
+++ b/arch/arm64/mm/Makefile
@@ -14,3 +14,5 @@ KASAN_SANITIZE_physaddr.o	+= n
 
 obj-$(CONFIG_KASAN)		+= kasan_init.o
 KASAN_SANITIZE_kasan_init.o	:= n
+
+obj-$(CONFIG_ARM64_RO_PAGE_TABLES) += ro_page_tables.o
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 77341b160aca..5a5055c3e1c2 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -220,7 +220,13 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
 		pteval ^= PTE_RDONLY;
 		pteval |= pte_val(entry);
 		pteval ^= PTE_RDONLY;
-		pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
+		if (page_tables_are_ro())
+			pteval = pte_val(cmpxchg_ro_pte(vma->vm_mm, ptep,
+							__pte(old_pteval),
+							__pte(pteval)));
+		else
+			pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval,
+						 pteval);
 	} while (pteval != old_pteval);
 
 	/* Invalidate a stale read-only entry */
diff --git a/arch/arm64/mm/ro_page_tables.c b/arch/arm64/mm/ro_page_tables.c
new file mode 100644
index 000000000000..f497adfd774d
--- /dev/null
+++ b/arch/arm64/mm/ro_page_tables.c
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 - Google Inc
+ * Author: Ard Biesheuvel <ardb at google.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/memory.h>
+#include <linux/mm.h>
+#include <linux/sizes.h>
+
+#include <asm/fixmap.h>
+#include <asm/kernel-pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/sections.h>
+
+static DEFINE_RAW_SPINLOCK(patch_pte_lock);
+
+DEFINE_STATIC_KEY_FALSE(ro_page_tables);
+
+static bool __initdata ro_page_tables_enabled = true;
+
+static int __init parse_ro_page_tables(char *arg)
+{
+	return strtobool(arg, &ro_page_tables_enabled);
+}
+early_param("ro_page_tables", parse_ro_page_tables);
+
+static bool in_kernel_text_or_rodata(phys_addr_t pa)
+{
+	/*
+	 * This is a minimal check to ensure that the r/o page table patching
+	 * API is not being abused to make changes to the kernel text. This
+	 * should ideally cover module and BPF text/rodata as well, but that
+	 * is less straight-forward and hence more costly.
+	 */
+	return pa >= __pa_symbol(_stext) && pa < __pa_symbol(__init_begin);
+}
+
+pte_t xchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t pte)
+{
+	unsigned long flags;
+	u64 pte_pa;
+	pte_t ret;
+	pte_t *p;
+
+	/* can we use __pa() on ptep? */
+	if (!virt_addr_valid(ptep)) {
+		/* only linear aliases are remapped r/o anyway */
+		pte_val(ret) = xchg_relaxed(&pte_val(*ptep), pte_val(pte));
+		return ret;
+	}
+
+	pte_pa = __pa(ptep);
+	BUG_ON(in_kernel_text_or_rodata(pte_pa));
+
+	raw_spin_lock_irqsave(&patch_pte_lock, flags);
+	p = (pte_t *)set_fixmap_offset(FIX_TEXT_POKE_PTE, pte_pa);
+	pte_val(ret) = xchg_relaxed(&pte_val(*p), pte_val(pte));
+	clear_fixmap(FIX_TEXT_POKE_PTE);
+	raw_spin_unlock_irqrestore(&patch_pte_lock, flags);
+	return ret;
+}
+
+pte_t cmpxchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t old, pte_t new)
+{
+	unsigned long flags;
+	u64 pte_pa;
+	pte_t ret;
+	pte_t *p;
+
+	BUG_ON(!virt_addr_valid(ptep));
+
+	pte_pa = __pa(ptep);
+	BUG_ON(in_kernel_text_or_rodata(pte_pa));
+
+	raw_spin_lock_irqsave(&patch_pte_lock, flags);
+	p = (pte_t *)set_fixmap_offset(FIX_TEXT_POKE_PTE, pte_pa);
+	pte_val(ret) = cmpxchg_relaxed(&pte_val(*p), pte_val(old), pte_val(new));
+	clear_fixmap(FIX_TEXT_POKE_PTE);
+	raw_spin_unlock_irqrestore(&patch_pte_lock, flags);
+	return ret;
+}
+
+static int __init ro_page_tables_init(void)
+{
+	if (ro_page_tables_enabled) {
+		if (!rodata_full) {
+			pr_err("Failed to enable R/O page table protection, rodata=full is not enabled\n");
+		} else {
+			pr_err("Enabling R/O page table protection\n");
+			static_branch_enable(&ro_page_tables);
+		}
+	}
+	return 0;
+}
+early_initcall(ro_page_tables_init);
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:04 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:04 +0100
Subject: [RFC PATCH 05/12] arm64: mm: remap PUD pages r/o in linear region
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-6-ardb@kernel.org>

Implement the arch specific PUD alloc/free helpers by wrapping the
generic code, and remapping the page read-only on allocation and
read-write on free.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h |  5 +++++
 arch/arm64/include/asm/tlb.h     |  2 ++
 arch/arm64/mm/mmu.c              | 20 ++++++++++++++++++++
 3 files changed, 27 insertions(+)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index d54ac9f8d6c7..737e9f32b199 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -14,6 +14,8 @@
 #include <asm/tlbflush.h>
 
 #define __HAVE_ARCH_PGD_FREE
+#define __HAVE_ARCH_PUD_ALLOC_ONE
+#define __HAVE_ARCH_PUD_FREE
 #include <asm-generic/pgalloc.h>
 
 #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
@@ -45,6 +47,9 @@ static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 
 #if CONFIG_PGTABLE_LEVELS > 3
 
+pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr);
+void pud_free(struct mm_struct *mm, pud_t *pud);
+
 static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
 {
 	set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index c995d1f4594f..6557626752fc 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -94,6 +94,8 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pudp,
 				  unsigned long addr)
 {
+	if (page_tables_are_ro())
+		set_pgtable_rw(pudp);
 	tlb_remove_table(tlb, virt_to_page(pudp));
 }
 #endif
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index a52c3162beae..03d77c4c3570 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1645,3 +1645,23 @@ static int __init prevent_bootmem_remove_init(void)
 }
 early_initcall(prevent_bootmem_remove_init);
 #endif
+
+#ifndef __PAGETABLE_PUD_FOLDED
+pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	pud_t *pud = __pud_alloc_one(mm, addr);
+
+	if (!pud)
+		return NULL;
+	if (page_tables_are_ro())
+		set_pgtable_ro(pud);
+	return pud;
+}
+
+void pud_free(struct mm_struct *mm, pud_t *pud)
+{
+	if (page_tables_are_ro())
+		set_pgtable_rw(pud);
+	free_page((u64)pud);
+}
+#endif
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:03 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:03 +0100
Subject: [RFC PATCH 04/12] arm64: mm: remap PGD pages r/o in the linear region
 after allocation
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-5-ardb@kernel.org>

As the first step in restricting write access to all page tables via the
linear mapping, remap the page at the root PGD level of a user space
page table hierarchy read-only after allocation, so that it can only be
manipulated using the dedicated fixmap based API.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/mmu.c |  7 ++++--
 arch/arm64/mm/pgd.c | 25 ++++++++++++++------
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index acfae9b41cc8..a52c3162beae 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -394,8 +394,11 @@ static phys_addr_t __pgd_pgtable_alloc(int shift)
 	void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL);
 	BUG_ON(!ptr);
 
-	/* Ensure the zeroed page is visible to the page table walker */
-	dsb(ishst);
+	if (page_tables_are_ro())
+		set_pgtable_ro(ptr);
+	else
+		/* Ensure the zeroed page is visible to the page table walker */
+		dsb(ishst);
 	return __pa(ptr);
 }
 
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 4a64089e5771..637d6eceeada 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -9,8 +9,10 @@
 #include <linux/mm.h>
 #include <linux/gfp.h>
 #include <linux/highmem.h>
+#include <linux/set_memory.h>
 #include <linux/slab.h>
 
+#include <asm/mmu_context.h>
 #include <asm/pgalloc.h>
 #include <asm/page.h>
 #include <asm/tlbflush.h>
@@ -20,24 +22,33 @@ static struct kmem_cache *pgd_cache __ro_after_init;
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	gfp_t gfp = GFP_PGTABLE_USER;
+	pgd_t *pgd;
 
-	if (PGD_SIZE == PAGE_SIZE)
-		return (pgd_t *)__get_free_page(gfp);
-	else
+	if (PGD_SIZE < PAGE_SIZE && !page_tables_are_ro())
 		return kmem_cache_alloc(pgd_cache, gfp);
+
+	pgd = (pgd_t *)__get_free_page(gfp);
+	if (!pgd)
+		return NULL;
+	if (page_tables_are_ro())
+		set_pgtable_ro(pgd);
+	return pgd;
 }
 
 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-	if (PGD_SIZE == PAGE_SIZE)
-		free_page((unsigned long)pgd);
-	else
+	if (PGD_SIZE < PAGE_SIZE && !page_tables_are_ro()) {
 		kmem_cache_free(pgd_cache, pgd);
+	} else {
+		if (page_tables_are_ro())
+			set_pgtable_rw(pgd);
+		free_page((unsigned long)pgd);
+	}
 }
 
 void __init pgtable_cache_init(void)
 {
-	if (PGD_SIZE == PAGE_SIZE)
+	if (PGD_SIZE == PAGE_SIZE || page_tables_are_ro())
 		return;
 
 #ifdef CONFIG_ARM64_PA_BITS_52
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:05 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:05 +0100
Subject: [RFC PATCH 06/12] arm64: mm: remap PMD pages r/o in linear region
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-7-ardb@kernel.org>

PMD modifications all go through the fixmap update routine, so there is
no longer a need to keep it mapped read/write in the linear region.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h |  5 +++++
 arch/arm64/include/asm/tlb.h     |  2 ++
 arch/arm64/mm/mmu.c              | 21 ++++++++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 737e9f32b199..63f9ae9e96fe 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -16,12 +16,17 @@
 #define __HAVE_ARCH_PGD_FREE
 #define __HAVE_ARCH_PUD_ALLOC_ONE
 #define __HAVE_ARCH_PUD_FREE
+#define __HAVE_ARCH_PMD_ALLOC_ONE
+#define __HAVE_ARCH_PMD_FREE
 #include <asm-generic/pgalloc.h>
 
 #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
 
 #if CONFIG_PGTABLE_LEVELS > 2
 
+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr);
+void pmd_free(struct mm_struct *mm, pmd_t *pmd);
+
 static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
 {
 	set_pud(pudp, __pud(__phys_to_pud_val(pmdp) | prot));
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 6557626752fc..0f54fbb59bba 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -85,6 +85,8 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp,
 {
 	struct page *page = virt_to_page(pmdp);
 
+	if (page_tables_are_ro())
+		set_pgtable_rw(pmdp);
 	pgtable_pmd_page_dtor(page);
 	tlb_remove_table(tlb, page);
 }
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 03d77c4c3570..e55d91a5f1ed 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1665,3 +1665,24 @@ void pud_free(struct mm_struct *mm, pud_t *pud)
 	free_page((u64)pud);
 }
 #endif
+
+#ifndef __PAGETABLE_PMD_FOLDED
+pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
+{
+	pmd_t *pmd = __pmd_alloc_one(mm, addr);
+
+	if (!pmd)
+		return NULL;
+	if (page_tables_are_ro())
+		set_pgtable_ro(pmd);
+	return pmd;
+}
+
+void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+	if (page_tables_are_ro())
+		set_pgtable_rw(pmd);
+	pgtable_pmd_page_dtor(virt_to_page(pmd));
+	free_page((u64)pmd);
+}
+#endif
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:06 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:06 +0100
Subject: [RFC PATCH 07/12] arm64: mm: remap PTE level user page tables r/o in
 the linear region
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-8-ardb@kernel.org>

Now that all PTE manipulations for user space tables go via the fixmap,
we can remap these tables read-only in the linear region so they cannot
be corrupted inadvertently.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h |  5 +++++
 arch/arm64/include/asm/tlb.h     |  2 ++
 arch/arm64/mm/mmu.c              | 23 ++++++++++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 63f9ae9e96fe..18a5bb0c9ee4 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -18,10 +18,15 @@
 #define __HAVE_ARCH_PUD_FREE
 #define __HAVE_ARCH_PMD_ALLOC_ONE
 #define __HAVE_ARCH_PMD_FREE
+#define __HAVE_ARCH_PTE_ALLOC_ONE
+#define __HAVE_ARCH_PTE_FREE
 #include <asm-generic/pgalloc.h>
 
 #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
 
+pgtable_t pte_alloc_one(struct mm_struct *mm);
+void pte_free(struct mm_struct *mm, struct page *pte_page);
+
 #if CONFIG_PGTABLE_LEVELS > 2
 
 pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr);
diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index 0f54fbb59bba..e69a44160cce 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -75,6 +75,8 @@ static inline void tlb_flush(struct mmu_gather *tlb)
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 				  unsigned long addr)
 {
+	if (page_tables_are_ro())
+		set_pgtable_rw(page_address(pte));
 	pgtable_pte_page_dtor(pte);
 	tlb_remove_table(tlb, pte);
 }
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index e55d91a5f1ed..949846654797 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1686,3 +1686,26 @@ void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 	free_page((u64)pmd);
 }
 #endif
+
+pgtable_t pte_alloc_one(struct mm_struct *mm)
+{
+	pgtable_t pgt = __pte_alloc_one(mm, GFP_PGTABLE_USER);
+
+	VM_BUG_ON(mm == &init_mm);
+
+	if (!pgt)
+		return NULL;
+	if (page_tables_are_ro())
+		set_pgtable_ro(page_address(pgt));
+	return pgt;
+}
+
+void pte_free(struct mm_struct *mm, struct page *pte_page)
+{
+	VM_BUG_ON(mm == &init_mm);
+
+	if (page_tables_are_ro())
+		set_pgtable_rw(page_address(pte_page));
+	pgtable_pte_page_dtor(pte_page);
+	__free_page(pte_page);
+}
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:07 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:07 +0100
Subject: [RFC PATCH 08/12] arm64: mm: remap kernel PTE level page tables r/o
 in the linear region
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-9-ardb@kernel.org>

Now that all kernel page table manipulations are routed through the
fixmap API if r/o page tables are enabled, we can remove write access
from the linear mapping of those pages.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/include/asm/pgalloc.h |  6 +++++
 arch/arm64/mm/mmu.c              | 24 +++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 18a5bb0c9ee4..073482634e74 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -20,6 +20,9 @@
 #define __HAVE_ARCH_PMD_FREE
 #define __HAVE_ARCH_PTE_ALLOC_ONE
 #define __HAVE_ARCH_PTE_FREE
+#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL
+#define __HAVE_ARCH_PTE_FREE_KERNEL
+
 #include <asm-generic/pgalloc.h>
 
 #define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
@@ -27,6 +30,9 @@
 pgtable_t pte_alloc_one(struct mm_struct *mm);
 void pte_free(struct mm_struct *mm, struct page *pte_page);
 
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm);
+void pte_free_kernel(struct mm_struct *mm, pte_t *pte);
+
 #if CONFIG_PGTABLE_LEVELS > 2
 
 pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr);
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 949846654797..971501535757 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1402,7 +1402,7 @@ int pmd_free_pte_page(pmd_t *pmdp, unsigned long addr)
 	table = pte_offset_kernel(pmdp, addr);
 	pmd_clear(pmdp);
 	__flush_tlb_kernel_pgtable(addr);
-	pte_free_kernel(NULL, table);
+	pte_free_kernel(&init_mm, table);
 	return 1;
 }
 
@@ -1709,3 +1709,25 @@ void pte_free(struct mm_struct *mm, struct page *pte_page)
 	pgtable_pte_page_dtor(pte_page);
 	__free_page(pte_page);
 }
+
+pte_t *pte_alloc_one_kernel(struct mm_struct *mm)
+{
+	pte_t *pte = __pte_alloc_one_kernel(mm);
+
+	VM_BUG_ON(mm != &init_mm);
+
+	if (!pte)
+		return NULL;
+	if (page_tables_are_ro())
+		set_pgtable_ro(pte);
+	return pte;
+}
+
+void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+	VM_BUG_ON(mm != &init_mm);
+
+	if (page_tables_are_ro())
+		set_pgtable_rw(pte);
+	free_page((u64)pte);
+}
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:08 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:08 +0100
Subject: [RFC PATCH 09/12] arm64: mm: remap kernel page tables read-only at
 end of init
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-10-ardb@kernel.org>

Now that all the handling is in place to deal with read-only page tables
at runtime, do a pass over the kernel page tables at boot to remap all
the page table pages read-only that were allocated early.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/mmu.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 971501535757..b1212f6d48f2 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -559,8 +559,23 @@ static void __init map_mem(pgd_t *pgdp)
 	memblock_clear_nomap(kernel_start, kernel_end - kernel_start);
 }
 
+static void mark_pgtables_ro(const pmd_t *pmdp, int level, int num_entries)
+{
+	while (num_entries--) {
+		if (pmd_valid(*pmdp) && pmd_table(*pmdp)) {
+			pmd_t *next = __va(__pmd_to_phys(*pmdp));
+
+			if (level < 2)
+				mark_pgtables_ro(next, level + 1, PTRS_PER_PMD);
+			set_pgtable_ro(next);
+		}
+		pmdp++;
+	}
+}
+
 void mark_rodata_ro(void)
 {
+	int pgd_level = 4 - CONFIG_PGTABLE_LEVELS;
 	unsigned long section_size;
 
 	/*
@@ -571,6 +586,11 @@ void mark_rodata_ro(void)
 	update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
 			    section_size, PAGE_KERNEL_RO);
 
+#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+	mark_pgtables_ro((pmd_t *)&tramp_pg_dir, pgd_level, PTRS_PER_PGD);
+#endif
+	mark_pgtables_ro((pmd_t *)&swapper_pg_dir, pgd_level, PTRS_PER_PGD);
+
 	debug_checkwx();
 }
 
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:09 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:09 +0100
Subject: [RFC PATCH 10/12] mm: add default definition of p4d_index()
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-11-ardb@kernel.org>

Implement a default version of p4d_index() similar to how pud/pmd_index
are defined.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 include/linux/pgtable.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index bc8713a76e03..e8aacf6ea207 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -79,6 +79,14 @@ static inline unsigned long pud_index(unsigned long address)
 #define pud_index pud_index
 #endif
 
+#ifndef p4d_index
+static inline unsigned long p4d_index(unsigned long address)
+{
+	return (address >> P4D_SHIFT) & (PTRS_PER_P4D - 1);
+}
+#define p4d_index p4d_index
+#endif
+
 #ifndef pgd_index
 /* Must be a compile-time constant, so implement it as a macro */
 #define pgd_index(a)  (((a) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:10 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:10 +0100
Subject: [RFC PATCH 11/12] arm64: efi: use set_pte_at() not set_pte() in order
 to pass mm pointer
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-12-ardb@kernel.org>

The set_pte() helper does not carry the struct mm pointer, which makes
it difficult for the implementation to reason about the context in which
the set_pte() call is taking place. So switch to set_pte_at() instead.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/kernel/efi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index e1be6c429810..e3e50adfae18 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -92,7 +92,7 @@ static int __init set_permissions(pte_t *ptep, unsigned long addr, void *data)
 		pte = set_pte_bit(pte, __pgprot(PTE_RDONLY));
 	if (md->attribute & EFI_MEMORY_XP)
 		pte = set_pte_bit(pte, __pgprot(PTE_PXN));
-	set_pte(ptep, pte);
+	set_pte_at(&efi_mm, addr, ptep, pte);
 	return 0;
 }
 
-- 
2.30.2



From ardb at kernel.org  Wed Jan 26 09:30:11 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Wed, 26 Jan 2022 18:30:11 +0100
Subject: [RFC PATCH 12/12] arm64: hugetlb: use set_pte_at() not set_pte() to
 provide mm pointer
In-Reply-To: <20220126173011.3476262-1-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
Message-ID: <20220126173011.3476262-13-ardb@kernel.org>

Switch to set_pte_at() so we can provide the mm pointer to the code that
performs the page table update.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/mm/hugetlbpage.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c
index ffb9c229610a..099b28b00f4c 100644
--- a/arch/arm64/mm/hugetlbpage.c
+++ b/arch/arm64/mm/hugetlbpage.c
@@ -252,8 +252,8 @@ void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr,
 
 	ncontig = num_contig_ptes(sz, &pgsize);
 
-	for (i = 0; i < ncontig; i++, ptep++)
-		set_pte(ptep, pte);
+	for (i = 0; i < ncontig; i++, ptep++, addr += pgsize)
+		set_pte_at(mm, addr, ptep, pte);
 }
 
 pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma,
-- 
2.30.2



From jszhang at kernel.org  Wed Jan 26 09:31:05 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Thu, 27 Jan 2022 01:31:05 +0800
Subject: [PATCH] net: stmmac: dwmac-sun8i: fix double disable and
 unprepare "stmmaceth" clk
In-Reply-To: <YfFwH9gHdN3fnx22@xhacker>
References: <20220123132805.758-1-jszhang@kernel.org>
 <38c41c04-abde-4d55-ed7c-515b6bba9c54@sholland.org>
 <YfFkz1d9onk+ITGg@xhacker> <YfFwH9gHdN3fnx22@xhacker>
Message-ID: <YfGFWT5o3QW8pzsD@xhacker>

On Thu, Jan 27, 2022 at 12:00:42AM +0800, Jisheng Zhang wrote:
> On Wed, Jan 26, 2022 at 11:12:28PM +0800, Jisheng Zhang wrote:
> > On Sun, Jan 23, 2022 at 01:43:37PM -0600, Samuel Holland wrote:
> > > On 1/23/22 7:28 AM, Jisheng Zhang wrote:
> > > > Fix warnings on Allwinner D1 platform:
> > > > 
> > > > [    1.604695] ------------[ cut here ]------------
> > > > [    1.609328] bus-emac already disabled
> > > > [    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
> > > > [    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
> > > > [    1.627653] Hardware name: Allwinner D1 NeZha (DT)
> > > > [    1.632443] Workqueue: events_unbound deferred_probe_work_func
> > > > [    1.638286] epc : clk_core_disable+0xcc/0xec
> > > > [    1.642561]  ra : clk_core_disable+0xcc/0xec
> > > > [    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
> > > > [    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
> > > > [    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
> > > > [    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
> > > > [    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
> > > > [    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
> > > > [    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
> > > > [    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > > > [    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > > > [    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
> > > > [    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
> > > > [    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
> > > > [    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
> > > > [    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
> > > > [    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > > [    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
> > > > [    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > > > [    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > > [    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > > > [    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > > > [    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > > > [    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > > > [    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > > > [    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > > > [    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > > > [    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > > > [    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > > > [    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > > > [    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > > > [    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > > > [    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > > [    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > > [    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > > > [    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
> > > > [    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > > > [    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > > > [    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
> > > > [    1.873675] ------------[ cut here ]------------
> > > > [    1.878366] bus-emac already unprepared
> > > > [    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
> > > > [    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
> > > > [    1.898674] Hardware name: Allwinner D1 NeZha (DT)
> > > > [    1.903464] Workqueue: events_unbound deferred_probe_work_func
> > > > [    1.909305] epc : clk_core_unprepare+0xe4/0x168
> > > > [    1.913840]  ra : clk_core_unprepare+0xe4/0x168
> > > > [    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
> > > > [    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
> > > > [    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
> > > > [    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
> > > > [    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
> > > > [    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
> > > > [    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
> > > > [    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
> > > > [    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
> > > > [    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
> > > > [    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
> > > > [    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
> > > > [    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
> > > > [    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
> > > > [    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
> > > > [    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
> > > > [    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
> > > > [    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
> > > > [    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
> > > > [    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
> > > > [    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
> > > > [    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
> > > > [    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
> > > > [    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
> > > > [    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
> > > > [    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
> > > > [    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
> > > > [    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
> > > > [    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
> > > > [    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > > [    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
> > > > [    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
> > > > [    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
> > > > [    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
> > > > [    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
> > > > [    2.135455] ---[ end trace 8d5c6046255f84a1 ]---
> > > > 
> > > > the dwmmac-sun8i driver will get the "stmmaceth" clk as tx_clk during
> > > > driver initialization. If stmmac_dvr_probe() fails due to various
> > > > reasons, sun8i_dwmac_exit() will disable and unprepare the "stmmaceth"
> > > > clk, then stmmac_remove_config_dt() will disable and unprepare the
> > > > clk again.
> > > 
> > > This should still be balanced, because both stmmac_probe_config_dt and
> > > sun8i_dwmac_init prepare/enable the clock, so the dwmac-sun8i glue layer calls
> > > stmmac_dvr_probe with the clock having an enable count of 2. It looks like the
> > > underlying issue is that commit 5ec55823438e ("net: stmmac: add clocks
> > > management for gmac driver") introduces unbalanced runtime PM.
> > 
> > I added some printk then retested, the problem is triggered as below:
> > 
> > stmmac_probe_config_dt() enable the clk
> > sun8i_dwmac_init() enble the clk again
> > stmmac_dvr_probe() succeed, but it calls pm_runtime_put(), so rpm will
> > disable the clk
> > sun8i_dwmac_reset() fails due to various reason
> > sun8i_dwmac_exit() disable the clk, this is fine
> > stmmac_remove_config_dt() disable the clk again, so ccf complains.
> > 
> > The key here is: whether we should let stmmac_dvr_probe() calls
> > pm_runtime_put() or let stmmac users to determine whether we could
> > let rpm go?
> > If we keep current behavior: stmmac users need to take care
> > the code after stmmac_dvr_probe, including error handling code path,
> > if we touch access registers, we need to call pm_runtime_get_sync()
> > firstly.
> > 
> > Since the commit 5ec55823438e has been in for a long time, I'll submit
> > a patch to follow this way.
> > 
> 
> After reading the code and commit history, I found some users suffering
> from the runtimepm issues, for example, dwmac-rk.c, so I changed my
> idea. I think it's better to let stmmac users to call pm_runtime_put():
> 
> First of all, only the users know whether it's safe to finally
> keep the mac runtime suspended after probe.
> 
> Secondly, if the users need to do platform specific operations after
> stmmac_dvr_probe(), especially needs to access some registers, we have
> to resume the mac firstly. The error handling code path also needs to
> take care of it. It looks a bit strange resume immediately resume the
> mac after suspending it.
> 
> Any suggestion is welcome.
> 
> PS: Since this would partially revert commit 5ec55823438e, I add Joakim
> into the email thread.
> 
If we keep current behavior as is, and let stmmac users to take care
necessary runtime resume before specific handling, we need similar
patch as dwmac-sun8i below for all stmmac users, especially the error
handling path:


diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 09644ab0d87a..ef2acea3d036 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -16,6 +16,7 @@
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 #include <linux/stmmac.h>
@@ -1254,6 +1255,7 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 	ndev = dev_get_drvdata(&pdev->dev);
 	priv = netdev_priv(ndev);
 
+	pm_runtime_get_sync(&pdev->dev);
 	/* The mux must be registered after parent MDIO
 	 * so after stmmac_dvr_probe()
 	 */
@@ -1272,12 +1274,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 			goto dwmac_remove;
 	}
 
+	pm_runtime_put(&pdev->dev);
+
 	return 0;
 
 dwmac_mux:
 	reset_control_put(gmac->rst_ephy);
 	clk_put(gmac->ephy_clk);
 dwmac_remove:
+	pm_runtime_put_noidle(&pdev->dev);
 	stmmac_dvr_remove(&pdev->dev);
 dwmac_exit:
 	sun8i_dwmac_exit(pdev, gmac);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 8ded4be08b00..2f9bd1eacb81 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7133,6 +7133,10 @@ int stmmac_dvr_remove(struct device *dev)
 
 	netdev_info(priv->dev, "%s: removing driver", __func__);
 
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_put_noidle(dev);
+
 	stmmac_stop_all_dma(priv);
 	stmmac_mac_set(priv, priv->ioaddr, false);
 	netif_carrier_off(ndev);
@@ -7151,8 +7155,6 @@ int stmmac_dvr_remove(struct device *dev)
 	if (priv->plat->stmmac_rst)
 		reset_control_assert(priv->plat->stmmac_rst);
 	reset_control_assert(priv->plat->stmmac_ahb_rst);
-	pm_runtime_put(dev);
-	pm_runtime_disable(dev);
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI)
 		stmmac_mdio_unregister(ndev);


From broonie at kernel.org  Wed Jan 26 09:44:21 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 17:44:21 +0000
Subject: [PATCH] kselftest/arm64: Remove local definitions of MTE prctls
Message-ID: <20220126174421.1712795-1-broonie@kernel.org>

The GCR EL1 test unconditionally includes local definitions of the prctls
it tests. Since not only will the kselftest build infrastructure ensure
that the in tree uapi headers are available but the toolchain being used to
build kselftest may ensure that system uapi headers with MTE support are
available this causes the compiler to warn about duplicate definitions.
Remove these duplicate definitions.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 .../selftests/arm64/mte/check_gcr_el1_cswitch.c       | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c b/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
index a876db1f096a..325bca0de0f6 100644
--- a/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
+++ b/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
@@ -19,17 +19,6 @@
 #include "kselftest.h"
 #include "mte_common_util.h"
 
-#define PR_SET_TAGGED_ADDR_CTRL 55
-#define PR_GET_TAGGED_ADDR_CTRL 56
-# define PR_TAGGED_ADDR_ENABLE  (1UL << 0)
-# define PR_MTE_TCF_SHIFT	1
-# define PR_MTE_TCF_NONE	(0UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_SYNC	(1UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_ASYNC	(2UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TCF_MASK	(3UL << PR_MTE_TCF_SHIFT)
-# define PR_MTE_TAG_SHIFT	3
-# define PR_MTE_TAG_MASK	(0xffffUL << PR_MTE_TAG_SHIFT)
-
 #include "mte_def.h"
 
 #define NUM_ITERATIONS		1024
-- 
2.30.2



From robin.murphy at arm.com  Wed Jan 26 09:56:00 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 26 Jan 2022 17:56:00 +0000
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-22-s.hauer@pengutronix.de>
 <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>
Message-ID: <a1438d39-b670-1ca5-d3f7-4e3f54702e53@arm.com>

On 2022-01-26 16:04, Peter Geis wrote:
> On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
>>
>> Add support for the HDMI port found on RK3568.
>>
>> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
>> ---
>>   arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
>>   1 file changed, 36 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> index 4008bd666d01..e38fb223e9b8 100644
>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>> @@ -10,7 +10,6 @@
>>   #include <dt-bindings/pinctrl/rockchip.h>
>>   #include <dt-bindings/power/rk3568-power.h>
>>   #include <dt-bindings/soc/rockchip,boot-mode.h>
>> -#include <dt-bindings/soc/rockchip,vop2.h>
>>   #include <dt-bindings/thermal/thermal.h>
>>
>>   / {
>> @@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
>>                  status = "disabled";
>>          };
>>
>> +       hdmi: hdmi at fe0a0000 {
>> +               compatible = "rockchip,rk3568-dw-hdmi";
>> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
>> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
>> +               clocks = <&cru PCLK_HDMI_HOST>,
>> +                        <&cru CLK_HDMI_SFR>,
>> +                        <&cru CLK_HDMI_CEC>,
>> +                        <&pmucru CLK_HDMI_REF>,
>> +                        <&cru HCLK_VOP>;
>> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
>> +               pinctrl-names = "default";
>> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
> 
> I looked into CEC support here, and it seems that it does work with one change.
> Please add the two following lines to your patch:
> assigned-clocks = <&cru CLK_HDMI_CEC>;
> assigned-clock-rates = <32768>;
> 
> The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
> feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
> function.

Wouldn't it make far more sense to just stick a suitable clk_set_rate() 
call in the driver? AFAICS it's already explicitly aware of the CEC clock.

Robin.

>> +               power-domains = <&power RK3568_PD_VO>;
>> +               reg-io-width = <4>;
>> +               rockchip,grf = <&grf>;
>> +               #sound-dai-cells = <0>;
>> +               status = "disabled";
>> +
>> +               ports {
>> +                       #address-cells = <1>;
>> +                       #size-cells = <0>;
>> +
>> +                       hdmi_in: port at 0 {
>> +                               reg = <0>;
>> +                               #address-cells = <1>;
>> +                               #size-cells = <0>;
>> +                       };
>> +
>> +                       hdmi_out: port at 1 {
>> +                               reg = <1>;
>> +                               #address-cells = <1>;
>> +                               #size-cells = <0>;
>> +                       };
>> +               };
>> +       };
>> +
>>          qos_gpu: qos at fe128000 {
>>                  compatible = "rockchip,rk3568-qos", "syscon";
>>                  reg = <0x0 0xfe128000 0x0 0x20>;
>> --
>> 2.30.2
>>
> 
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From romain.perier at gmail.com  Wed Jan 26 09:55:56 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:55:56 +0100
Subject: [PATCH v4 0/8] ARM: mstar: cpupll
Message-ID: <20220126175604.17919-1-romain.perier@gmail.com>

This series adds a basic driver for the PLL that generates
the cpu clock on MStar/SigmaStar ARMv7 SoCs.

Unfortunately there isn't much documentation for this thing
so there are few magic values and guesses.

This needs to come after the MPLL DT changes.

Changes since v3:
- Added Reviewed-by on Daniel's patches
- Removed "[PATCH v3 8/9] ARM: mstar: Add OPP table for mercury5"

Changes since v2:
- Re-ordered Kconfig by name
- Re-ordered includes alphabetically and removed useless ones
- Used timeout for cpu_relax
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_frequencyforreg()
- Returned DIV_ROUND_DOWN_ULL() directly in
  msc313_cpupll_regforfrequecy()
- Reduced the number of lines for msc313_cpupll_of_match
- Removed CLK_IS_CRITICAL

Changes since v1:
- Re-worked the series and ensure that 'make dt_binding_check' passes.
  The required commit is merged now, so it is okay.
- Fixed coding style issues in the driver and makes check_patch.pl happy
- Added one more commit for extending the opp_table for infinity2m.

Daniel Palmer (7):
  dt-bindings: clk: mstar msc313 cpupll binding description
  clk: mstar: msc313 cpupll clk driver
  ARM: mstar: Add cpupll to base dtsi
  ARM: mstar: Link cpupll to cpu
  ARM: mstar: Link cpupll to second core
  ARM: mstar: Add OPP table for infinity
  ARM: mstar: Add OPP table for infinity3

Romain Perier (1):
  ARM: mstar: Extend opp_table for infinity2m

 .../bindings/clock/mstar,msc313-cpupll.yaml   |  45 ++++
 arch/arm/boot/dts/mstar-infinity.dtsi         |  34 +++
 arch/arm/boot/dts/mstar-infinity2m.dtsi       |  17 ++
 arch/arm/boot/dts/mstar-infinity3.dtsi        |  58 +++++
 arch/arm/boot/dts/mstar-v7.dtsi               |   9 +
 drivers/clk/mstar/Kconfig                     |   8 +
 drivers/clk/mstar/Makefile                    |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c         | 221 ++++++++++++++++++
 8 files changed, 393 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:55:59 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:55:59 +0100
Subject: [PATCH v4 3/8] ARM: mstar: Add cpupll to base dtsi
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-4-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

All MStar/SigmaStar ARMv7 SoCs have the CPU PLL at the same
place so add it to the base dtsi.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 89ebfe4f29da..2249faaa3aa7 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -155,6 +155,13 @@ mpll: mpll at 206000 {
 				clocks = <&xtal>;
 			};
 
+			cpupll: cpupll at 206400 {
+				compatible = "mstar,msc313-cpupll";
+				reg = <0x206400 0x200>;
+				#clock-cells = <0>;
+				clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+			};
+
 			gpio: gpio at 207800 {
 				#gpio-cells = <2>;
 				reg = <0x207800 0x200>;
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:55:57 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:55:57 +0100
Subject: [PATCH v4 1/8] dt-bindings: clk: mstar msc313 cpupll binding
 description
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-2-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a binding description for the MStar/SigmaStar CPU PLL block.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/clock/mstar,msc313-cpupll.yaml   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml

diff --git a/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
new file mode 100644
index 000000000000..a9ad7ab5230c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/mstar,msc313-cpupll.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/mstar,msc313-cpupll.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MStar/Sigmastar MSC313 CPU PLL
+
+maintainers:
+  - Daniel Palmer <daniel at thingy.jp>
+
+description: |
+  The MStar/SigmaStar MSC313 and later ARMv7 chips have a scalable
+  PLL that can be used as the clock source for the CPU(s).
+
+properties:
+  compatible:
+    const: mstar,msc313-cpupll
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mstar-msc313-mpll.h>
+    cpupll: cpupll at 206400 {
+        compatible = "mstar,msc313-cpupll";
+        reg = <0x206400 0x200>;
+        #clock-cells = <1>;
+        clocks = <&mpll MSTAR_MSC313_MPLL_DIV2>;
+    };
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:56:00 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:56:00 +0100
Subject: [PATCH v4 4/8] ARM: mstar: Link cpupll to cpu
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-5-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The CPU clock is sourced from the CPU PLL.
Link cpupll to the cpu so that frequency scaling can happen.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-v7.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-v7.dtsi b/arch/arm/boot/dts/mstar-v7.dtsi
index 2249faaa3aa7..c26ba9b7b6dd 100644
--- a/arch/arm/boot/dts/mstar-v7.dtsi
+++ b/arch/arm/boot/dts/mstar-v7.dtsi
@@ -21,6 +21,8 @@ cpu0: cpu at 0 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a7";
 			reg = <0x0>;
+			clocks = <&cpupll>;
+			clock-names = "cpuclk";
 		};
 	};
 
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:55:58 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:55:58 +0100
Subject: [PATCH v4 2/8] clk: mstar: msc313 cpupll clk driver
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-3-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add a driver for the CPU pll/ARM pll/MIPS pll that is present
in MStar SoCs.

Currently there is no documentation for this block so it's possible
this driver isn't entirely correct.

Only tested on the version of this IP in the MStar/SigmaStar
ARMv7 SoCs.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
---
 drivers/clk/mstar/Kconfig             |   8 +
 drivers/clk/mstar/Makefile            |   2 +-
 drivers/clk/mstar/clk-msc313-cpupll.c | 221 ++++++++++++++++++++++++++
 3 files changed, 230 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/mstar/clk-msc313-cpupll.c

diff --git a/drivers/clk/mstar/Kconfig b/drivers/clk/mstar/Kconfig
index de37e1bce2d2..146eeb637318 100644
--- a/drivers/clk/mstar/Kconfig
+++ b/drivers/clk/mstar/Kconfig
@@ -1,4 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config MSTAR_MSC313_CPUPLL
+	bool "MStar CPUPLL driver"
+	depends on ARCH_MSTARV7 || COMPILE_TEST
+	default ARCH_MSTARV7
+	help
+	  Support for the CPU PLL present on MStar/Sigmastar SoCs.
+
 config MSTAR_MSC313_MPLL
 	bool "MStar MPLL driver"
 	depends on ARCH_MSTARV7 || COMPILE_TEST
@@ -7,3 +14,4 @@ config MSTAR_MSC313_MPLL
 	help
 	  Support for the MPLL PLL and dividers block present on
 	  MStar/Sigmastar SoCs.
+
diff --git a/drivers/clk/mstar/Makefile b/drivers/clk/mstar/Makefile
index f8dcd25ede1d..21296a04e65a 100644
--- a/drivers/clk/mstar/Makefile
+++ b/drivers/clk/mstar/Makefile
@@ -2,5 +2,5 @@
 #
 # Makefile for mstar specific clk
 #
-
+obj-$(CONFIG_MSTAR_MSC313_CPUPLL) += clk-msc313-cpupll.o
 obj-$(CONFIG_MSTAR_MSC313_MPLL) += clk-msc313-mpll.o
diff --git a/drivers/clk/mstar/clk-msc313-cpupll.c b/drivers/clk/mstar/clk-msc313-cpupll.c
new file mode 100644
index 000000000000..c57b509e8c20
--- /dev/null
+++ b/drivers/clk/mstar/clk-msc313-cpupll.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Daniel Palmer <daniel at thingy.jp>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+
+/*
+ * This IP is not documented outside of the messy vendor driver.
+ * Below is what we think the registers look like based on looking at
+ * the vendor code and poking at the hardware:
+ *
+ * 0x140 -- LPF low. Seems to store one half of the clock transition
+ * 0x144 /
+ * 0x148 -- LPF high. Seems to store one half of the clock transition
+ * 0x14c /
+ * 0x150 -- vendor code says "toggle lpf enable"
+ * 0x154 -- mu?
+ * 0x15c -- lpf_update_count?
+ * 0x160 -- vendor code says "switch to LPF". Clock source config? Register bank?
+ * 0x164 -- vendor code says "from low to high" which seems to mean transition from LPF low to
+ * LPF high.
+ * 0x174 -- Seems to be the PLL lock status bit
+ * 0x180 -- Seems to be the current frequency, this might need to be populated by software?
+ * 0x184 /  The vendor driver uses these to set the initial value of LPF low
+ *
+ * Frequency seems to be calculated like this:
+ * (parent clock (432mhz) / register_magic_value) * 16 * 524288
+ * Only the lower 24 bits of the resulting value will be used. In addition, the
+ * PLL doesn't seem to be able to lock on frequencies lower than 220 MHz, as
+ * divisor 0xfb586f (220 MHz) works but 0xfb7fff locks up.
+ *
+ * Vendor values:
+ * frequency - register value
+ *
+ * 400000000  - 0x0067AE14
+ * 600000000  - 0x00451EB8,
+ * 800000000  - 0x0033D70A,
+ * 1000000000 - 0x002978d4,
+ */
+
+#define REG_LPF_LOW_L		0x140
+#define REG_LPF_LOW_H		0x144
+#define REG_LPF_HIGH_BOTTOM	0x148
+#define REG_LPF_HIGH_TOP	0x14c
+#define REG_LPF_TOGGLE		0x150
+#define REG_LPF_MYSTERYTWO	0x154
+#define REG_LPF_UPDATE_COUNT	0x15c
+#define REG_LPF_MYSTERYONE	0x160
+#define REG_LPF_TRANSITIONCTRL	0x164
+#define REG_LPF_LOCK		0x174
+#define REG_CURRENT		0x180
+
+#define LPF_LOCK_TIMEOUT	100000000
+
+#define MULTIPLIER_1		16
+#define MULTIPLIER_2		524288
+#define MULTIPLIER		(MULTIPLIER_1 * MULTIPLIER_2)
+
+struct msc313_cpupll {
+	void __iomem *base;
+	struct clk_hw clk_hw;
+};
+
+#define to_cpupll(_hw) container_of(_hw, struct msc313_cpupll, clk_hw)
+
+static u32 msc313_cpupll_reg_read32(struct msc313_cpupll *cpupll, unsigned int reg)
+{
+	u32 value;
+
+	value = ioread16(cpupll->base + reg + 4) << 16;
+	value |= ioread16(cpupll->base + reg);
+
+	return value;
+}
+
+static void msc313_cpupll_reg_write32(struct msc313_cpupll *cpupll, unsigned int reg, u32 value)
+{
+	u16 l = value & 0xffff, h = (value >> 16) & 0xffff;
+
+	iowrite16(l, cpupll->base + reg);
+	iowrite16(h, cpupll->base + reg + 4);
+}
+
+static void msc313_cpupll_setfreq(struct msc313_cpupll *cpupll, u32 regvalue)
+{
+	ktime_t timeout;
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_HIGH_BOTTOM, regvalue);
+
+	iowrite16(0x1, cpupll->base + REG_LPF_MYSTERYONE);
+	iowrite16(0x6, cpupll->base + REG_LPF_MYSTERYTWO);
+	iowrite16(0x8, cpupll->base + REG_LPF_UPDATE_COUNT);
+	iowrite16(BIT(12), cpupll->base + REG_LPF_TRANSITIONCTRL);
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+	iowrite16(1, cpupll->base + REG_LPF_TOGGLE);
+
+	timeout = ktime_add_ns(ktime_get(), LPF_LOCK_TIMEOUT);
+	while (!(ioread16(cpupll->base + REG_LPF_LOCK))) {
+		if (ktime_after(ktime_get(), timeout)) {
+			pr_err("timeout waiting for LPF_LOCK\n");
+			return;
+		}
+		cpu_relax();
+	}
+
+	iowrite16(0, cpupll->base + REG_LPF_TOGGLE);
+
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L, regvalue);
+}
+
+static unsigned long msc313_cpupll_frequencyforreg(u32 reg, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || reg == 0)
+		return 0;
+	return DIV_ROUND_DOWN_ULL(prescaled, reg);
+}
+
+static u32 msc313_cpupll_regforfrequecy(unsigned long rate, unsigned long parent_rate)
+{
+	unsigned long long prescaled = ((unsigned long long)parent_rate) * MULTIPLIER;
+
+	if (prescaled == 0 || rate == 0)
+		return 0;
+	return DIV_ROUND_UP_ULL(prescaled, rate);
+}
+
+static unsigned long msc313_cpupll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+
+	return msc313_cpupll_frequencyforreg(msc313_cpupll_reg_read32(cpupll, REG_LPF_LOW_L),
+					     parent_rate);
+}
+
+static long msc313_cpupll_round_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	u32 reg = msc313_cpupll_regforfrequecy(rate, *parent_rate);
+	long rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	/*
+	 * This is my poor attempt at making sure the resulting
+	 * rate doesn't overshoot the requested rate.
+	 */
+	for (; rounded >= rate && reg > 0; reg--)
+		rounded = msc313_cpupll_frequencyforreg(reg, *parent_rate);
+
+	return rounded;
+}
+
+static int msc313_cpupll_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
+{
+	struct msc313_cpupll *cpupll = to_cpupll(hw);
+	u32 reg = msc313_cpupll_regforfrequecy(rate, parent_rate);
+
+	msc313_cpupll_setfreq(cpupll, reg);
+
+	return 0;
+}
+
+static const struct clk_ops msc313_cpupll_ops = {
+	.recalc_rate	= msc313_cpupll_recalc_rate,
+	.round_rate	= msc313_cpupll_round_rate,
+	.set_rate	= msc313_cpupll_set_rate,
+};
+
+static const struct of_device_id msc313_cpupll_of_match[] = {
+	{ .compatible = "mstar,msc313-cpupll" },
+	{}
+};
+
+static const struct clk_parent_data cpupll_parent = {
+	.index	= 0,
+};
+
+static int msc313_cpupll_probe(struct platform_device *pdev)
+{
+	struct clk_init_data clk_init = {};
+	struct device *dev = &pdev->dev;
+	struct msc313_cpupll *cpupll;
+	int ret;
+
+	cpupll = devm_kzalloc(&pdev->dev, sizeof(*cpupll), GFP_KERNEL);
+	if (!cpupll)
+		return -ENOMEM;
+
+	cpupll->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(cpupll->base))
+		return PTR_ERR(cpupll->base);
+
+	/* LPF might not contain the current frequency so fix that up */
+	msc313_cpupll_reg_write32(cpupll, REG_LPF_LOW_L,
+				  msc313_cpupll_reg_read32(cpupll, REG_CURRENT));
+
+	clk_init.name = dev_name(dev);
+	clk_init.ops = &msc313_cpupll_ops;
+	clk_init.parent_data = &cpupll_parent;
+	clk_init.num_parents = 1;
+	cpupll->clk_hw.init = &clk_init;
+
+	ret = devm_clk_hw_register(dev, &cpupll->clk_hw);
+	if (ret)
+		return ret;
+
+	return of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_simple_get, &cpupll->clk_hw);
+}
+
+static struct platform_driver msc313_cpupll_driver = {
+	.driver = {
+		.name = "mstar-msc313-cpupll",
+		.of_match_table = msc313_cpupll_of_match,
+	},
+	.probe = msc313_cpupll_probe,
+};
+builtin_platform_driver(msc313_cpupll_driver);
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:56:01 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:56:01 +0100
Subject: [PATCH v4 5/8] ARM: mstar: Link cpupll to second core
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-6-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The second core also sources it's clock from the CPU PLL.

Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index 6d4d1d224e96..dc339cd29778 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -11,6 +11,8 @@ cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
 		reg = <0x1>;
+		clocks = <&cpupll>;
+		clock-names = "cpuclk";
 	};
 };
 
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:56:02 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:56:02 +0100
Subject: [PATCH v4 6/8] ARM: mstar: Add OPP table for infinity
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-7-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

Add an OPP table for the inifinity chips so
that cpu frequency scaling can happen.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity.dtsi | 34 +++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity.dtsi b/arch/arm/boot/dts/mstar-infinity.dtsi
index 0bee517797f4..441a917b88ba 100644
--- a/arch/arm/boot/dts/mstar-infinity.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity.dtsi
@@ -8,6 +8,40 @@
 
 #include <dt-bindings/gpio/msc313-gpio.h>
 
+/ {
+	cpu0_opp_table: opp_table0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-240000000 {
+			opp-hz = /bits/ 64 <240000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+		opp-600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+	};
+};
+
+&cpu0 {
+	operating-points-v2 = <&cpu0_opp_table>;
+};
+
 &imi {
 	reg = <0xa0000000 0x16000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:56:03 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:56:03 +0100
Subject: [PATCH v4 7/8] ARM: mstar: Add OPP table for infinity3
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-8-romain.perier@gmail.com>

From: Daniel Palmer <daniel at 0x0f.com>

The infinity3 has a slightly higher max frequency
compared to the infinity so extend the OPP table.

Co-authored-by: Willy Tarreau <w at 1wt.eu>
Signed-off-by: Daniel Palmer <daniel at 0x0f.com>
Reviewed-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity3.dtsi | 58 ++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity3.dtsi b/arch/arm/boot/dts/mstar-infinity3.dtsi
index 9857e2a9934d..a56cf29e5d82 100644
--- a/arch/arm/boot/dts/mstar-infinity3.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity3.dtsi
@@ -6,6 +6,64 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+	opp-1008000000 {
+		opp-hz = /bits/ 64 <1008000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+	};
+
+	// overclock frequencies below, shown to work fine up to 1.3 GHz
+	opp-108000000 {
+		opp-hz = /bits/ 64 <1080000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1188000000 {
+		opp-hz = /bits/ 64 <1188000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1296000000 {
+		opp-hz = /bits/ 64 <1296000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1350000000 {
+		opp-hz = /bits/ 64 <1350000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1404000000 {
+		opp-hz = /bits/ 64 <1404000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1458000000 {
+		opp-hz = /bits/ 64 <1458000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+
+	opp-1512000000 {
+		opp-hz = /bits/ 64 <1512000000>;
+		opp-microvolt = <1000000>;
+		clock-latency-ns = <300000>;
+		turbo-mode;
+	};
+};
+
 &imi {
 	reg = <0xa0000000 0x20000>;
 };
-- 
2.34.1



From romain.perier at gmail.com  Wed Jan 26 09:56:04 2022
From: romain.perier at gmail.com (Romain Perier)
Date: Wed, 26 Jan 2022 18:56:04 +0100
Subject: [PATCH v4 8/8] ARM: mstar: Extend opp_table for infinity2m
In-Reply-To: <20220126175604.17919-1-romain.perier@gmail.com>
References: <20220126175604.17919-1-romain.perier@gmail.com>
Message-ID: <20220126175604.17919-9-romain.perier@gmail.com>

infinity2m are running up to 1.2Ghz, this extends opp_table with the
corresponding frequencies and enable operating-points table for cpu1

Signed-off-by: Romain Perier <romain.perier at gmail.com>
---
 arch/arm/boot/dts/mstar-infinity2m.dtsi | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm/boot/dts/mstar-infinity2m.dtsi b/arch/arm/boot/dts/mstar-infinity2m.dtsi
index dc339cd29778..1b485efd7156 100644
--- a/arch/arm/boot/dts/mstar-infinity2m.dtsi
+++ b/arch/arm/boot/dts/mstar-infinity2m.dtsi
@@ -6,10 +6,25 @@
 
 #include "mstar-infinity.dtsi"
 
+&cpu0_opp_table {
+		opp-1000000000 {
+			opp-hz = /bits/ 64 <1000000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+
+		opp-1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-microvolt = <1000000>;
+			clock-latency-ns = <300000>;
+		};
+};
+
 &cpus {
 	cpu1: cpu at 1 {
 		device_type = "cpu";
 		compatible = "arm,cortex-a7";
+		operating-points-v2 = <&cpu0_opp_table>;
 		reg = <0x1>;
 		clocks = <&cpupll>;
 		clock-names = "cpuclk";
-- 
2.34.1



From valentin.schneider at arm.com  Wed Jan 26 10:10:51 2022
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Wed, 26 Jan 2022 18:10:51 +0000
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <YfF9I5PcZJA5532B@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de> <87czq573et.mognet@arm.com>
 <YfF9I5PcZJA5532B@linutronix.de>
Message-ID: <87r18u2wr8.mognet@arm.com>

On 26/01/22 17:56, Sebastian Andrzej Siewior wrote:
> On 2021-08-22 19:14:18 [+0100], Valentin Schneider wrote:
>> Thanks for carrying it through, I'll keep that change for the next version.
>
> Just a quick question. This series ended with 3 patches in my queue. It
> got decimated further due to Frederic series which ended up in
> v5.17-rc1. I still have
> | 2021-08-11 21:13 +0100 Valentin Schneider    ? sched: Introduce migratable()
> | 2021-08-11 21:13 +0100 Valentin Schneider    ? arm64: mm: Make arch_faults_on_old_pte() check for migratability
>
> what do we do about these two? I could repost these two if there are no
> objections?
>

Heh, had forgotten about those - I'm happy to repost with the
s/migratable/is_migratable/. I also need to go back to those splats I got
on my emag and fix the PMU/GPIO warnings...

> Sebastian


From laurent.pinchart at ideasonboard.com  Wed Jan 26 10:42:44 2022
From: laurent.pinchart at ideasonboard.com (Laurent Pinchart)
Date: Wed, 26 Jan 2022 20:42:44 +0200
Subject: [RFC PATCH v2 5/7] ARM: dts: bcm2711: Add unicam CSI nodes
In-Reply-To: <CAPY8ntDR5AsxGE5fh_KHMonoZait9evxQkpidu10F7EY9CPxZA@mail.gmail.com>
References: <20220121081810.155500-1-jeanmichel.hautbois@ideasonboard.com>
 <20220121081810.155500-6-jeanmichel.hautbois@ideasonboard.com>
 <Yes3c1v+V1hMlWfW@pendragon.ideasonboard.com>
 <CAPY8ntDR5AsxGE5fh_KHMonoZait9evxQkpidu10F7EY9CPxZA@mail.gmail.com>
Message-ID: <YfGWJCReevd752++@pendragon.ideasonboard.com>

Hi Dave,

On Mon, Jan 24, 2022 at 12:31:34PM +0000, Dave Stevenson wrote:
> On Fri, 21 Jan 2022 at 22:45, Laurent Pinchart wrote:
> > On Fri, Jan 21, 2022 at 09:18:08AM +0100, Jean-Michel Hautbois wrote:
> > > Add both MIPI CSI-2 nodes in the core bcm2711 tree. Use the 3-cells
> > > interrupt declaration, corresponding clocks and default as disabled.
> > >
> > > Signed-off-by: Jean-Michel Hautbois <jeanmichel.hautbois at ideasonboard.com>
> > > ---
> > >  arch/arm/boot/dts/bcm2711.dtsi | 31 +++++++++++++++++++++++++++++++
> > >  1 file changed, 31 insertions(+)
> > >
> > > diff --git a/arch/arm/boot/dts/bcm2711.dtsi b/arch/arm/boot/dts/bcm2711.dtsi
> > > index dff18fc9a906..077141df7024 100644
> > > --- a/arch/arm/boot/dts/bcm2711.dtsi
> > > +++ b/arch/arm/boot/dts/bcm2711.dtsi
> > > @@ -3,6 +3,7 @@
> > >
> > >  #include <dt-bindings/interrupt-controller/arm-gic.h>
> > >  #include <dt-bindings/soc/bcm2835-pm.h>
> > > +#include <dt-bindings/power/raspberrypi-power.h>
> > >
> > >  / {
> > >       compatible = "brcm,bcm2711";
> > > @@ -293,6 +294,36 @@ hvs: hvs at 7e400000 {
> > >                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
> > >               };
> > >
> > > +             csi0: csi1 at 7e800000 {
> >
> > The node name should be csi at 7e800000, not csi1 at 7e800000. Now, this will
> > probably cause issues with the firmware that looks for csi1 (and csi0 ?)
> > to hand over control of the Unicam CSI-2 receiver to the kernel. I
> > wonder if this is something that could be handled by a firmware update,
> > to also recognize nodes named "csi" ?
> 
> It already looks for any node starting "csi". If you check the
> downstream DT [1], then the nodes are "csi0: csi at 7e800000" and "csi1:
> csi at 7e801000".

Oops, indeed. I think I was misled by
https://github.com/raspberrypi/linux/blob/rpi-5.10.y/Documentation/devicetree/bindings/media/bcm2835-unicam.txt
that mentions "csi0" and "csi1".

It's all good then. Jean-Michel, can you update the DT bindings in the
next iteration of the series to correct the DT node naming ?

> There is no actual action required to hand the peripheral over to the
> kernel, it just prevents the firmware from using it and causing
> problems (it masks out the interrupt, and that's checked as part of
> the firmware initialising the peripheral).
> 
> If using imx219 or one of the other sensors supported by the firmware,
> "vcgencmd get_camera" should report that the sensor isn't detected,
> and "sudo vcdbg log msg" should have a line similar to
> "020174.613: camsubs: Ignoring camera 0 as unicam device not available"
> 
>   Dave
> 
> [1] https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm270x.dtsi#L88
> 
> > > +                     compatible = "brcm,bcm2835-unicam";
> > > +                     reg = <0x7e800000 0x800>,
> > > +                           <0x7e802000 0x4>;
> > > +                     interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
> > > +                     clocks = <&clocks BCM2835_CLOCK_CAM0>,
> > > +                              <&firmware_clocks 4>;
> > > +                     clock-names = "lp", "vpu";
> > > +                     power-domains = <&power RPI_POWER_DOMAIN_UNICAM0>;
> > > +                     #address-cells = <1>;
> > > +                     #size-cells = <0>;
> > > +                     #clock-cells = <1>;
> >
> > Why do you need #address-cells, #size-cells and #clock-cells ? They're
> > not mentioned in the binding.
> >
> > > +                     status="disabled";
> >
> > Missing spaces around the =.
> >
> > Same comment for the next node.
> >
> > > +             };
> > > +
> > > +             csi1: csi1 at 7e801000 {
> > > +                     compatible = "brcm,bcm2835-unicam";
> > > +                     reg = <0x7e801000 0x800>,
> > > +                           <0x7e802004 0x4>;
> > > +                     interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
> > > +                     clocks = <&clocks BCM2835_CLOCK_CAM1>,
> > > +                              <&firmware_clocks 4>;
> > > +                     clock-names = "lp", "vpu";
> > > +                     power-domains = <&power RPI_POWER_DOMAIN_UNICAM1>;
> > > +                     #address-cells = <1>;
> > > +                     #size-cells = <0>;
> > > +                     #clock-cells = <1>;
> > > +                     status="disabled";
> > > +             };
> > > +
> > >               pixelvalve3: pixelvalve at 7ec12000 {
> > >                       compatible = "brcm,bcm2711-pixelvalve3";
> > >                       reg = <0x7ec12000 0x100>;

-- 
Regards,

Laurent Pinchart


From pgwipeout at gmail.com  Wed Jan 26 10:44:11 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 13:44:11 -0500
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <a1438d39-b670-1ca5-d3f7-4e3f54702e53@arm.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-22-s.hauer@pengutronix.de>
 <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>
 <a1438d39-b670-1ca5-d3f7-4e3f54702e53@arm.com>
Message-ID: <CAMdYzYrcsj5Vas+ysoK6iD3uEAdmhcmLVi-5LY7hfHEtjeB6Cg@mail.gmail.com>

On Wed, Jan 26, 2022 at 12:56 PM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2022-01-26 16:04, Peter Geis wrote:
> > On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >>
> >> Add support for the HDMI port found on RK3568.
> >>
> >> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> >> ---
> >>   arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
> >>   1 file changed, 36 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> index 4008bd666d01..e38fb223e9b8 100644
> >> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >> @@ -10,7 +10,6 @@
> >>   #include <dt-bindings/pinctrl/rockchip.h>
> >>   #include <dt-bindings/power/rk3568-power.h>
> >>   #include <dt-bindings/soc/rockchip,boot-mode.h>
> >> -#include <dt-bindings/soc/rockchip,vop2.h>
> >>   #include <dt-bindings/thermal/thermal.h>
> >>
> >>   / {
> >> @@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
> >>                  status = "disabled";
> >>          };
> >>
> >> +       hdmi: hdmi at fe0a0000 {
> >> +               compatible = "rockchip,rk3568-dw-hdmi";
> >> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
> >> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> >> +               clocks = <&cru PCLK_HDMI_HOST>,
> >> +                        <&cru CLK_HDMI_SFR>,
> >> +                        <&cru CLK_HDMI_CEC>,
> >> +                        <&pmucru CLK_HDMI_REF>,
> >> +                        <&cru HCLK_VOP>;
> >> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
> >> +               pinctrl-names = "default";
> >> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
> >
> > I looked into CEC support here, and it seems that it does work with one change.
> > Please add the two following lines to your patch:
> > assigned-clocks = <&cru CLK_HDMI_CEC>;
> > assigned-clock-rates = <32768>;
> >
> > The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
> > feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
> > function.
>
> Wouldn't it make far more sense to just stick a suitable clk_set_rate()
> call in the driver? AFAICS it's already explicitly aware of the CEC clock.

This is handled purely in the
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c driver, so I'm hesitant to
touch it there as it would affect all users, not just Rockchip.

Could someone familiar with the dw-hdmi IP weigh in on the minimum and
maximum clock rate the CEC block can handle?

>
> Robin.
>
> >> +               power-domains = <&power RK3568_PD_VO>;
> >> +               reg-io-width = <4>;
> >> +               rockchip,grf = <&grf>;
> >> +               #sound-dai-cells = <0>;
> >> +               status = "disabled";
> >> +
> >> +               ports {
> >> +                       #address-cells = <1>;
> >> +                       #size-cells = <0>;
> >> +
> >> +                       hdmi_in: port at 0 {
> >> +                               reg = <0>;
> >> +                               #address-cells = <1>;
> >> +                               #size-cells = <0>;
> >> +                       };
> >> +
> >> +                       hdmi_out: port at 1 {
> >> +                               reg = <1>;
> >> +                               #address-cells = <1>;
> >> +                               #size-cells = <0>;
> >> +                       };
> >> +               };
> >> +       };
> >> +
> >>          qos_gpu: qos at fe128000 {
> >>                  compatible = "rockchip,rk3568-qos", "syscon";
> >>                  reg = <0x0 0xfe128000 0x0 0x20>;
> >> --
> >> 2.30.2
> >>
> >
> > _______________________________________________
> > Linux-rockchip mailing list
> > Linux-rockchip at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-rockchip


From sstabellini at kernel.org  Wed Jan 26 10:56:39 2022
From: sstabellini at kernel.org (Stefano Stabellini)
Date: Wed, 26 Jan 2022 10:56:39 -0800 (PST)
Subject: [PATCH v3 1/2] dt-bindings: arm: xen: document Xen iommu
 device
In-Reply-To: <447f89ca-86c0-dc35-e7ac-e6639a573670@arm.com>
References: <20220117123251.140867-1-Sergiy_Kibrik@epam.com>
 <20220117123251.140867-2-Sergiy_Kibrik@epam.com>
 <e88b882f-4b5d-a801-fc68-66b7f790e11c@arm.com>
 <PAXPR03MB81144A63E18CAF10E785E2A7F0209@PAXPR03MB8114.eurprd03.prod.outlook.com>
 <447f89ca-86c0-dc35-e7ac-e6639a573670@arm.com>
Message-ID: <alpine.DEB.2.22.394.2201261050300.27308@ubuntu-linux-20-04-desktop>

On Wed, 26 Jan 2022, Robin Murphy wrote:
> On 2022-01-26 15:09, Sergiy Kibrik wrote:
> > Hi Robin,
> > 
> > > 
> > > This could break Linux guests, since depending on the deferred probe
> > > timeout setting it could lead to drivers never probing because the "IOMMU"
> > > never becomes available.
> > > 
> > 
> > I've noticed no deferred probe timeouts when booting with this patch. Could
> > you please explain more on how this would break guests?
> 
> Right now I think it would actually require command-line intervention, e.g.
> "fw_devlink=on" or "deferred_probe_timeout=3600" (with modules enabled for the
> latter to take full effect), but I'm wary of the potential for future config
> options to control those behaviours by default.

If deferred_probe_timeout=3600 was specified, we would just need an
IOMMU driver in Linux for the "xen,iommu-el2-v1" node to solve the
problem, right? I guess I am trying to say that it wouldn't be a device
tree interface problem but rather a Linux implementation discussion.


From catalin.marinas at arm.com  Wed Jan 26 10:57:21 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Wed, 26 Jan 2022 18:57:21 +0000
Subject: [PATCH v2] arm64: extable: fix load_unaligned_zeropad() reg
 indices
In-Reply-To: <20220125182217.2605202-1-eugenis@google.com>
References: <20220125182217.2605202-1-eugenis@google.com>
Message-ID: <164322343553.819367.16239308759447224919.b4-ty@arm.com>

On Tue, 25 Jan 2022 10:22:17 -0800, Evgenii Stepanov wrote:
> In ex_handler_load_unaligned_zeropad() we erroneously extract the data and
> addr register indices from ex->type rather than ex->data. As ex->type will
> contain EX_TYPE_LOAD_UNALIGNED_ZEROPAD (i.e. 4):
>  * We'll always treat X0 as the address register, since EX_DATA_REG_ADDR is
>    extracted from bits [9:5]. Thus, we may attempt to dereference an
>    arbitrary address as X0 may hold an arbitrary value.
>  * We'll always treat X4 as the data register, since EX_DATA_REG_DATA is
>    extracted from bits [4:0]. Thus we will corrupt X4 and cause arbitrary
>    behaviour within load_unaligned_zeropad() and its caller.
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/1] arm64: extable: fix load_unaligned_zeropad() reg indices
      https://git.kernel.org/arm64/c/afa1bf69aac3

-- 
Catalin



From german.gomez at arm.com  Wed Jan 26 11:07:51 2022
From: german.gomez at arm.com (German Gomez)
Date: Wed, 26 Jan 2022 19:07:51 +0000
Subject: [PATCH 1/2] perf arm-spe: Add arm_spe_record to synthesized
In-Reply-To: <20220126155820.21929-1-alisaidi@amazon.com>
References: <5ca990a5-eedd-0edb-26d3-b5e16c36ac34@arm.com>
 <20220126155820.21929-1-alisaidi@amazon.com>
Message-ID: <c4a96839-1b4b-ac4d-38aa-26c1f4c8645a@arm.com>


On 26/01/2022 15:58, Ali Saidi wrote:
> Hi German,
>> Hi Ali,
>>
>> On 25/01/2022 19:20, Ali Saidi wrote:
>>> [...]
>>>
>>> +	sample.raw_size = sizeof(*record);
>>> +	sample.raw_data = record;
>> Have you tried this with perf-inject? I think it would need the PERF_SAMPLE_RAW bit in the sample_type,
> Yes I've tried the following and it worked as expected with the original
> perf.data or the perf.data.jitted after perf-inject. 
>
> perf record -e arm_spe_0/jitter=1/ -k 1 java ...
> perf  inject -f --jit -i perf.data -o perf.data.jitted

This is not injecting the synthesized samples. I think it is still????
processing from the aux trace. Try adding "--itrace=i1i --strip" to the
inject command to remove the AUXTRACE events. Judging by the raw
samples, the data is missing:

11 20005239445831 0x3510 [0x94]: PERF_RECORD_SAMPLE(IP, 0x1): 47670/47670: 0xffffab6e02d1b320 period: 1 addr: 0

. ... raw event: size 64 bytes
.? 0000:? 09 00 00 00 01 00 40 00 f3 10 9b 3b 00 00 00 00? ...... at ....;....
.? 0010:? 98 c5 e3 02 6e ab ff ff 36 ba 00 00 36 ba 00 00? ....n...6...6...
.? 0020:? 35 da 30 d5 31 12 00 00 0b 00 00 00 00 00 00 00? 5.0.1...........
.? 0030:? 01 00 00 00 00 00 00 00 82 01 00 88 00 00 00 00? ................

vs when adding PERF_SAMPLE_RAW to attr.sample_type:??????

. ... raw event: size 148 bytes
.? 0000:? 09 00 00 00 01 00 94 00 f3 10 9b 3b 00 00 00 00? ...........;....
.? 0010:? 98 c5 e3 02 6e ab ff ff 36 ba 00 00 36 ba 00 00? ....n...6...6...
[...]
.? 0080:? 00 00 00 00 2a 00 00 00 00 00 00 00 82 01 00 88? ....*...........
.? 0090:? 00 00 00 00

> perf script -i perf.data -s t1.py --itrace=i1i
>
>> Although I quickly looked over the perf inject code and it looks like it's expecting some type of padding:
>>
>> [...]
>>
>> I'm seeing some comments in utils/event.h related to this on the intel events.
> Yes i noticed this too,but looking at how the raw data is added to the same
> other places like intel-pt.c:1703 the perf_synth__raw*() functions are used to
> strip away the 4 bytes bytes before the data is added to the sample. The other
> places i can find the padding used is in builtin-script.c but given we have the
> --dump-raw-trace option it's not clear to me that it's needed to wrap the
> arm_spe_event in another struct with padding like perf_synth_intel_ptwrite?

I think the intel use case makes sense because the layout of the data
is fixed and documented. If we modify the struct arm_spe_record later it
may not be obvious how to match it to the raw data of an older perf.data
file. And we're generating bigger files with redundant information.

Thanks,
German

>
> Thanks,
> Ali
>


From skhan at linuxfoundation.org  Wed Jan 26 11:22:41 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Wed, 26 Jan 2022 12:22:41 -0700
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220126145242.3473836-1-broonie@kernel.org>
References: <20220126145242.3473836-1-broonie@kernel.org>
Message-ID: <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>

On 1/26/22 7:52 AM, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> 
> v3:
>   - Use custom print_skip() helper.
>   - Use internal version of _kvm_create_device.
> v2:
>   - The test for being able to create the GIC doesn't actually
>     instantiate it, add a call doing so in that case.
> 
>   tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>   tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
>   tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>   3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 9ad38bd360a4..b08d30bf71c5 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
>   {
>   	struct kvm_vm *vm;
>   	unsigned int i;
> +	int ret;
>   	int nr_vcpus = test_args.nr_vcpus;
>   
>   	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
> @@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
>   
>   	ucall_init(vm, NULL);
>   	test_init_timer_irq(vm);
> -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (ret < 0) {
> +		print_skip("Failed to create vgic-v3");

Printing the negative error code returned by vgic_v3_setup will be useful.

> +		exit(KSFT_SKIP);
> +	}
>   
>   	/* Make all the test's cmdline args visible to the guest */
>   	sync_global_to_guest(vm, test_args);
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> index e6c7d7f8fbd1..7eca97799917 100644
> --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> @@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
>   
>   	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
>   			GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (gic_fd < 0) {
> +		print_skip("Failed to create vgic-v3, skipping");

Same here.

> +		exit(KSFT_SKIP);
> +	}
>   
>   	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
>   		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..f5cd0c536d85 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>   			nr_vcpus, nr_vcpus_created);
>   
>   	/* Distributor setup */
> -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> +	if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3,
> +			       false, &gic_fd) != 0)
> +		return -1;
>   
>   	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
>   			0, &nr_irqs, true);
> 

With these fixed:

Reviewed-by: Shuah Khan <skhan at linuxfoundation.org>

thanks,
-- Shuah


From robin.murphy at arm.com  Wed Jan 26 11:24:56 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Wed, 26 Jan 2022 19:24:56 +0000
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <CAMdYzYrcsj5Vas+ysoK6iD3uEAdmhcmLVi-5LY7hfHEtjeB6Cg@mail.gmail.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-22-s.hauer@pengutronix.de>
 <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>
 <a1438d39-b670-1ca5-d3f7-4e3f54702e53@arm.com>
 <CAMdYzYrcsj5Vas+ysoK6iD3uEAdmhcmLVi-5LY7hfHEtjeB6Cg@mail.gmail.com>
Message-ID: <45132d1f-626d-5fe3-3118-21c0b3f4c8f1@arm.com>

On 2022-01-26 18:44, Peter Geis wrote:
> On Wed, Jan 26, 2022 at 12:56 PM Robin Murphy <robin.murphy at arm.com> wrote:
>>
>> On 2022-01-26 16:04, Peter Geis wrote:
>>> On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
>>>>
>>>> Add support for the HDMI port found on RK3568.
>>>>
>>>> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
>>>> ---
>>>>    arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
>>>>    1 file changed, 36 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> index 4008bd666d01..e38fb223e9b8 100644
>>>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
>>>> @@ -10,7 +10,6 @@
>>>>    #include <dt-bindings/pinctrl/rockchip.h>
>>>>    #include <dt-bindings/power/rk3568-power.h>
>>>>    #include <dt-bindings/soc/rockchip,boot-mode.h>
>>>> -#include <dt-bindings/soc/rockchip,vop2.h>
>>>>    #include <dt-bindings/thermal/thermal.h>
>>>>
>>>>    / {
>>>> @@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
>>>>                   status = "disabled";
>>>>           };
>>>>
>>>> +       hdmi: hdmi at fe0a0000 {
>>>> +               compatible = "rockchip,rk3568-dw-hdmi";
>>>> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
>>>> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
>>>> +               clocks = <&cru PCLK_HDMI_HOST>,
>>>> +                        <&cru CLK_HDMI_SFR>,
>>>> +                        <&cru CLK_HDMI_CEC>,
>>>> +                        <&pmucru CLK_HDMI_REF>,
>>>> +                        <&cru HCLK_VOP>;
>>>> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
>>>> +               pinctrl-names = "default";
>>>> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
>>>
>>> I looked into CEC support here, and it seems that it does work with one change.
>>> Please add the two following lines to your patch:
>>> assigned-clocks = <&cru CLK_HDMI_CEC>;
>>> assigned-clock-rates = <32768>;
>>>
>>> The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
>>> feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
>>> function.
>>
>> Wouldn't it make far more sense to just stick a suitable clk_set_rate()
>> call in the driver? AFAICS it's already explicitly aware of the CEC clock.
> 
> This is handled purely in the
> drivers/gpu/drm/bridge/synopsys/dw-hdmi.c driver, so I'm hesitant to
> touch it there as it would affect all users, not just Rockchip.

I'd have a strong hunch that it's a standard thing for the DesignWare IP 
and not affected by platform integration. I don't have the magical 
Synopsys databook, but between the trusty old i.MX6 manual and most of 
the other in-tree DTs getting their dw-hdmi "cec" clock from 
suspiciously-obviously-named sources, I'd be somewhat surprised if it 
was ever anything other than 32KHz.

Robin.

> Could someone familiar with the dw-hdmi IP weigh in on the minimum and
> maximum clock rate the CEC block can handle?
> 
>>
>> Robin.
>>
>>>> +               power-domains = <&power RK3568_PD_VO>;
>>>> +               reg-io-width = <4>;
>>>> +               rockchip,grf = <&grf>;
>>>> +               #sound-dai-cells = <0>;
>>>> +               status = "disabled";
>>>> +
>>>> +               ports {
>>>> +                       #address-cells = <1>;
>>>> +                       #size-cells = <0>;
>>>> +
>>>> +                       hdmi_in: port at 0 {
>>>> +                               reg = <0>;
>>>> +                               #address-cells = <1>;
>>>> +                               #size-cells = <0>;
>>>> +                       };
>>>> +
>>>> +                       hdmi_out: port at 1 {
>>>> +                               reg = <1>;
>>>> +                               #address-cells = <1>;
>>>> +                               #size-cells = <0>;
>>>> +                       };
>>>> +               };
>>>> +       };
>>>> +
>>>>           qos_gpu: qos at fe128000 {
>>>>                   compatible = "rockchip,rk3568-qos", "syscon";
>>>>                   reg = <0x0 0xfe128000 0x0 0x20>;
>>>> --
>>>> 2.30.2
>>>>
>>>
>>> _______________________________________________
>>> Linux-rockchip mailing list
>>> Linux-rockchip at lists.infradead.org
>>> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From broonie at kernel.org  Wed Jan 26 11:52:51 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 19:52:51 +0000
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>
References: <20220126145242.3473836-1-broonie@kernel.org>
 <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>
Message-ID: <YfGmk1I8l+ROoE/k@sirena.org.uk>

On Wed, Jan 26, 2022 at 12:22:41PM -0700, Shuah Khan wrote:
> On 1/26/22 7:52 AM, Mark Brown wrote:

> > +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> > +	if (ret < 0) {
> > +		print_skip("Failed to create vgic-v3");

> Printing the negative error code returned by vgic_v3_setup will be useful.

If the function fails for any reason other than the system not
supporting vgic-v3 it will abort rather than return.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/e6821f2e/attachment.sig>

From pgwipeout at gmail.com  Wed Jan 26 12:00:01 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 15:00:01 -0500
Subject: [PATCH 21/27] arm64: dts: rockchip: rk356x: Add HDMI nodes
In-Reply-To: <45132d1f-626d-5fe3-3118-21c0b3f4c8f1@arm.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-22-s.hauer@pengutronix.de>
 <CAMdYzYrLw9+VW08cuj4_o4GDFhgBB8dZ-oVJ0TUnKFGLNetdyQ@mail.gmail.com>
 <a1438d39-b670-1ca5-d3f7-4e3f54702e53@arm.com>
 <CAMdYzYrcsj5Vas+ysoK6iD3uEAdmhcmLVi-5LY7hfHEtjeB6Cg@mail.gmail.com>
 <45132d1f-626d-5fe3-3118-21c0b3f4c8f1@arm.com>
Message-ID: <CAMdYzYpyrACnNtRYUNSSkEA_AUdWJ22BvWKU3YVHumLmcB1fpA@mail.gmail.com>

On Wed, Jan 26, 2022 at 2:25 PM Robin Murphy <robin.murphy at arm.com> wrote:
>
> On 2022-01-26 18:44, Peter Geis wrote:
> > On Wed, Jan 26, 2022 at 12:56 PM Robin Murphy <robin.murphy at arm.com> wrote:
> >>
> >> On 2022-01-26 16:04, Peter Geis wrote:
> >>> On Wed, Jan 26, 2022 at 9:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >>>>
> >>>> Add support for the HDMI port found on RK3568.
> >>>>
> >>>> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> >>>> ---
> >>>>    arch/arm64/boot/dts/rockchip/rk356x.dtsi | 37 +++++++++++++++++++++++-
> >>>>    1 file changed, 36 insertions(+), 1 deletion(-)
> >>>>
> >>>> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >>>> index 4008bd666d01..e38fb223e9b8 100644
> >>>> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >>>> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> >>>> @@ -10,7 +10,6 @@
> >>>>    #include <dt-bindings/pinctrl/rockchip.h>
> >>>>    #include <dt-bindings/power/rk3568-power.h>
> >>>>    #include <dt-bindings/soc/rockchip,boot-mode.h>
> >>>> -#include <dt-bindings/soc/rockchip,vop2.h>
> >>>>    #include <dt-bindings/thermal/thermal.h>
> >>>>
> >>>>    / {
> >>>> @@ -502,6 +501,42 @@ vop_mmu: iommu at fe043e00 {
> >>>>                   status = "disabled";
> >>>>           };
> >>>>
> >>>> +       hdmi: hdmi at fe0a0000 {
> >>>> +               compatible = "rockchip,rk3568-dw-hdmi";
> >>>> +               reg = <0x0 0xfe0a0000 0x0 0x20000>;
> >>>> +               interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
> >>>> +               clocks = <&cru PCLK_HDMI_HOST>,
> >>>> +                        <&cru CLK_HDMI_SFR>,
> >>>> +                        <&cru CLK_HDMI_CEC>,
> >>>> +                        <&pmucru CLK_HDMI_REF>,
> >>>> +                        <&cru HCLK_VOP>;
> >>>> +               clock-names = "iahb", "isfr", "cec", "ref", "hclk";
> >>>> +               pinctrl-names = "default";
> >>>> +               pinctrl-0 = <&hdmitx_scl &hdmitx_sda &hdmitxm0_cec>;
> >>>
> >>> I looked into CEC support here, and it seems that it does work with one change.
> >>> Please add the two following lines to your patch:
> >>> assigned-clocks = <&cru CLK_HDMI_CEC>;
> >>> assigned-clock-rates = <32768>;
> >>>
> >>> The issue is the clk_rtc32k_frac clock that feeds clk_rtc_32k which
> >>> feeds clk_hdmi_cec is 24mhz at boot, which is too high for CEC to
> >>> function.
> >>
> >> Wouldn't it make far more sense to just stick a suitable clk_set_rate()
> >> call in the driver? AFAICS it's already explicitly aware of the CEC clock.
> >
> > This is handled purely in the
> > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c driver, so I'm hesitant to
> > touch it there as it would affect all users, not just Rockchip.
>
> I'd have a strong hunch that it's a standard thing for the DesignWare IP
> and not affected by platform integration. I don't have the magical
> Synopsys databook, but between the trusty old i.MX6 manual and most of
> the other in-tree DTs getting their dw-hdmi "cec" clock from
> suspiciously-obviously-named sources, I'd be somewhat surprised if it
> was ever anything other than 32KHz.

My main concern was similar to the other HDMI clock issues, mainly
setting the clock can propagate up and affect other users of the
upstream clock.
I'll spin up a quick patch for this method.

Thanks,
Peter

>
> Robin.
>
> > Could someone familiar with the dw-hdmi IP weigh in on the minimum and
> > maximum clock rate the CEC block can handle?
> >
> >>
> >> Robin.
> >>
> >>>> +               power-domains = <&power RK3568_PD_VO>;
> >>>> +               reg-io-width = <4>;
> >>>> +               rockchip,grf = <&grf>;
> >>>> +               #sound-dai-cells = <0>;
> >>>> +               status = "disabled";
> >>>> +
> >>>> +               ports {
> >>>> +                       #address-cells = <1>;
> >>>> +                       #size-cells = <0>;
> >>>> +
> >>>> +                       hdmi_in: port at 0 {
> >>>> +                               reg = <0>;
> >>>> +                               #address-cells = <1>;
> >>>> +                               #size-cells = <0>;
> >>>> +                       };
> >>>> +
> >>>> +                       hdmi_out: port at 1 {
> >>>> +                               reg = <1>;
> >>>> +                               #address-cells = <1>;
> >>>> +                               #size-cells = <0>;
> >>>> +                       };
> >>>> +               };
> >>>> +       };
> >>>> +
> >>>>           qos_gpu: qos at fe128000 {
> >>>>                   compatible = "rockchip,rk3568-qos", "syscon";
> >>>>                   reg = <0x0 0xfe128000 0x0 0x20>;
> >>>> --
> >>>> 2.30.2
> >>>>
> >>>
> >>> _______________________________________________
> >>> Linux-rockchip mailing list
> >>> Linux-rockchip at lists.infradead.org
> >>> http://lists.infradead.org/mailman/listinfo/linux-rockchip


From skhan at linuxfoundation.org  Wed Jan 26 12:03:44 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Wed, 26 Jan 2022 13:03:44 -0700
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <YfGmk1I8l+ROoE/k@sirena.org.uk>
References: <20220126145242.3473836-1-broonie@kernel.org>
 <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>
 <YfGmk1I8l+ROoE/k@sirena.org.uk>
Message-ID: <48c44d74-6668-7823-ada6-0285a8b32a35@linuxfoundation.org>

On 1/26/22 12:52 PM, Mark Brown wrote:
> On Wed, Jan 26, 2022 at 12:22:41PM -0700, Shuah Khan wrote:
>> On 1/26/22 7:52 AM, Mark Brown wrote:
> 
>>> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
>>> +	if (ret < 0) {
>>> +		print_skip("Failed to create vgic-v3");
> 
>> Printing the negative error code returned by vgic_v3_setup will be useful.
> 
> If the function fails for any reason other than the system not
> supporting vgic-v3 it will abort rather than return.
> 

Hmm. vgic_v3_setup() return gic_fd looks like and the interface says
Return: GIC file-descriptor or negative error code upon failure

I don't follow the abort part.

thanks,
-- Shuah


From carlos.bilbao at amd.com  Wed Jan 26 12:07:50 2022
From: carlos.bilbao at amd.com (Carlos Bilbao)
Date: Wed, 26 Jan 2022 14:07:50 -0600
Subject: [PATCH] include: linux: Reorganize timekeeping and ktime headers
Message-ID: <20220126200749.12090-1-carlos.bilbao@amd.com>

The timekeeping subsystem could use some reorganization. Reorganize and
separate the headers by making ktime.h take care of the ktime_get()
family of functions, and reserve timekeeping.h for the actual timekeeping.

This also helps to avoid implicit function errors and strengthens the
header dependencies, since timekeeping.h was using ktime_to_ns(), a static
function defined in a header it does no include, ktime.h.

This patch also includes the header timekeeping.h wherever it is necessary
for a successful compilation after the header code reorganization for all
archs.

Signed-off-by: Carlos Bilbao <carlos.bilbao at amd.com>
Acked-by: Geert Uytterhoeven <geert at linux-m68k.org>
---
 arch/arm64/kvm/hypercalls.c    |   1 +
 arch/ia64/kernel/time.c        |   1 +
 arch/m68k/atari/time.c         |   1 +
 arch/m68k/hp300/time.c         |   2 +
 arch/m68k/mac/via.c            |   1 +
 arch/m68k/mvme16x/config.c     |   1 +
 arch/m68k/sun3/sun3ints.c      |   1 +
 arch/powerpc/kernel/time.c     |   1 +
 arch/x86/kernel/rtc.c          |   1 +
 arch/x86/kernel/tsc.c          |   1 +
 drivers/rtc/class.c            |   1 +
 include/linux/ktime.h          | 196 +++++++++++++++++++++++++++++++-
 include/linux/pps_kernel.h     |   1 +
 include/linux/sched_clock.h    |   2 +
 include/linux/stmmac.h         |   1 +
 include/linux/timekeeping.h    | 197 +--------------------------------
 init/main.c                    |   1 +
 kernel/time/ntp.c              |   1 +
 kernel/time/posix-timers.c     |   1 +
 kernel/time/tick-legacy.c      |   1 +
 kernel/time/time.c             |   1 +
 kernel/time/timekeeping.c      |   1 +
 sound/pci/hda/hda_controller.c |   1 +
 23 files changed, 218 insertions(+), 198 deletions(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index 30da78f72b3b..41499c1d7379 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -3,6 +3,7 @@
 
 #include <linux/arm-smccc.h>
 #include <linux/kvm_host.h>
+#include <linux/timekeeping.h>
 
 #include <asm/kvm_emulate.h>
 
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index fa9c0ab8c6fc..85e79ff3c98e 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/timex.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 7e44d0e9d0f8..b09d3ff40b36 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -19,6 +19,7 @@
 #include <linux/clocksource.h>
 #include <linux/delay.h>
 #include <linux/export.h>
+#include <linux/timekeeping.h>
 
 #include <asm/atariints.h>
 #include <asm/machdep.h>
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index 1d1b7b3b5dd4..56c575096bcb 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -14,6 +14,8 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
+
 #include <asm/machdep.h>
 #include <asm/irq.h>
 #include <asm/io.h>
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index 3d11d6219cdd..6dd8f85288e4 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/timekeeping.h>
 
 #include <asm/macintosh.h>
 #include <asm/macints.h>
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index b4422c2dfbbf..ebe1dc3ebb4c 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -28,6 +28,7 @@
 #include <linux/rtc.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
+#include <linux/timekeeping.h>
 
 #include <asm/bootinfo.h>
 #include <asm/bootinfo-vme.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 36cc280a4505..209dccc2aed6 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/timekeeping.h>
 #include <asm/intersil.h>
 #include <asm/oplib.h>
 #include <asm/sun3ints.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index cae8f03a44fe..b577a5a06621 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -54,6 +54,7 @@
 #include <linux/of_clk.h>
 #include <linux/suspend.h>
 #include <linux/processor.h>
+#include <linux/timekeeping.h>
 #include <asm/trace.h>
 
 #include <asm/interrupt.h>
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 586f718b8e95..98ea05cc6aeb 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -9,6 +9,7 @@
 #include <linux/export.h>
 #include <linux/pnp.h>
 #include <linux/of.h>
+#include <linux/timekeeping.h>
 
 #include <asm/vsyscall.h>
 #include <asm/x86_init.h>
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index a698196377be..add4388283c5 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
 #include <linux/timex.h>
 #include <linux/static_key.h>
 #include <linux/static_call.h>
+#include <linux/timekeeping.h>
 
 #include <asm/hpet.h>
 #include <asm/timer.h>
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 4b460c61f1d8..7e2bce8cf0b1 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,6 +16,7 @@
 #include <linux/kdev_t.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 #include <linux/workqueue.h>
 
 #include "rtc-core.h"
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index 73f20deb497d..07971008b795 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -229,6 +229,198 @@ static inline ktime_t ms_to_ktime(u64 ms)
 	return ms * NSEC_PER_MSEC;
 }
 
-# include <linux/timekeeping.h>
+/*
+ * ktime_get() family: read the current time in a multitude of ways,
+ *
+ * The default time reference is CLOCK_MONOTONIC, starting at
+ * boot time but not counting the time spent in suspend.
+ * For other references, use the functions with "real", "clocktai",
+ * "boottime" and "raw" suffixes.
+ *
+ * To get the time in a different format, use the ones wit
+ * "ns", "ts64" and "seconds" suffix.
+ *
+ * See Documentation/core-api/timekeeping.rst for more details.
+ */
 
-#endif
+
+/*
+ * timespec64 based interfaces
+ */
+extern void ktime_get_raw_ts64(struct timespec64 *ts);
+extern void ktime_get_ts64(struct timespec64 *ts);
+extern void ktime_get_real_ts64(struct timespec64 *tv);
+extern void ktime_get_coarse_ts64(struct timespec64 *ts);
+extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
+
+void getboottime64(struct timespec64 *ts);
+
+/*
+ * time64_t base interfaces
+ */
+extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
+extern time64_t ktime_get_real_seconds(void);
+
+/*
+ * ktime_t based interfaces
+ */
+
+enum tk_offsets {
+	TK_OFFS_REAL,
+	TK_OFFS_BOOT,
+	TK_OFFS_TAI,
+	TK_OFFS_MAX,
+};
+
+extern ktime_t ktime_get(void);
+extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
+extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
+extern ktime_t ktime_get_raw(void);
+extern u32 ktime_get_resolution_ns(void);
+
+/**
+ * ktime_get_real - get the real (wall-) time in ktime_t format
+ */
+static inline ktime_t ktime_get_real(void)
+{
+	return ktime_get_with_offset(TK_OFFS_REAL);
+}
+
+static inline ktime_t ktime_get_coarse_real(void)
+{
+	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
+}
+
+/**
+ * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
+ *
+ * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
+ * time spent in suspend.
+ */
+static inline ktime_t ktime_get_boottime(void)
+{
+	return ktime_get_with_offset(TK_OFFS_BOOT);
+}
+
+static inline ktime_t ktime_get_coarse_boottime(void)
+{
+	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
+}
+
+/**
+ * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
+ */
+static inline ktime_t ktime_get_clocktai(void)
+{
+	return ktime_get_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse_clocktai(void)
+{
+	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
+}
+
+static inline ktime_t ktime_get_coarse(void)
+{
+	struct timespec64 ts;
+
+	ktime_get_coarse_ts64(&ts);
+	return timespec64_to_ktime(ts);
+}
+
+static inline u64 ktime_get_coarse_ns(void)
+{
+	return ktime_to_ns(ktime_get_coarse());
+}
+
+static inline u64 ktime_get_coarse_real_ns(void)
+{
+	return ktime_to_ns(ktime_get_coarse_real());
+}
+
+static inline u64 ktime_get_coarse_boottime_ns(void)
+{
+	return ktime_to_ns(ktime_get_coarse_boottime());
+}
+
+static inline u64 ktime_get_coarse_clocktai_ns(void)
+{
+	return ktime_to_ns(ktime_get_coarse_clocktai());
+}
+
+/**
+ * ktime_mono_to_real - Convert monotonic time to clock realtime
+ */
+static inline ktime_t ktime_mono_to_real(ktime_t mono)
+{
+	return ktime_mono_to_any(mono, TK_OFFS_REAL);
+}
+
+static inline u64 ktime_get_ns(void)
+{
+	return ktime_to_ns(ktime_get());
+}
+
+static inline u64 ktime_get_real_ns(void)
+{
+	return ktime_to_ns(ktime_get_real());
+}
+
+static inline u64 ktime_get_boottime_ns(void)
+{
+	return ktime_to_ns(ktime_get_boottime());
+}
+
+static inline u64 ktime_get_clocktai_ns(void)
+{
+	return ktime_to_ns(ktime_get_clocktai());
+}
+
+static inline u64 ktime_get_raw_ns(void)
+{
+	return ktime_to_ns(ktime_get_raw());
+}
+
+extern u64 ktime_get_mono_fast_ns(void);
+extern u64 ktime_get_raw_fast_ns(void);
+extern u64 ktime_get_boot_fast_ns(void);
+extern u64 ktime_get_real_fast_ns(void);
+
+/*
+ * timespec64/time64_t interfaces utilizing the ktime based ones
+ * for API completeness, these could be implemented more efficiently
+ * if needed.
+ */
+static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
+{
+	*ts = ktime_to_timespec64(ktime_get_boottime());
+}
+
+static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
+{
+	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
+}
+
+static inline time64_t ktime_get_boottime_seconds(void)
+{
+	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
+}
+
+static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
+{
+	*ts = ktime_to_timespec64(ktime_get_clocktai());
+}
+
+static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
+{
+	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
+}
+
+static inline time64_t ktime_get_clocktai_seconds(void)
+{
+	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
+}
+
+#endif /* _LINUX_KTIME_H */
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h
index 78c8ac4951b5..24970c202ac6 100644
--- a/include/linux/pps_kernel.h
+++ b/include/linux/pps_kernel.h
@@ -12,6 +12,7 @@
 #include <linux/cdev.h>
 #include <linux/device.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 
 /*
  * Global defines
diff --git a/include/linux/sched_clock.h b/include/linux/sched_clock.h
index 835ee87ed792..f0fa287710da 100644
--- a/include/linux/sched_clock.h
+++ b/include/linux/sched_clock.h
@@ -5,6 +5,8 @@
 #ifndef LINUX_SCHED_CLOCK
 #define LINUX_SCHED_CLOCK
 
+#include <linux/timekeeping.h>
+
 #ifdef CONFIG_GENERIC_SCHED_CLOCK
 /**
  * struct clock_read_data - data required to read from sched_clock()
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index a6f03b36fc4f..bf235ff101d5 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -14,6 +14,7 @@
 
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/timekeeping.h>
 
 #define MTL_MAX_RX_QUEUES	8
 #define MTL_MAX_TX_QUEUES	8
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index 78a98bdff76d..b1c54f5ff91e 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -19,201 +19,6 @@ extern void legacy_timer_tick(unsigned long ticks);
 extern int do_settimeofday64(const struct timespec64 *ts);
 extern int do_sys_settimeofday64(const struct timespec64 *tv,
 				 const struct timezone *tz);
-
-/*
- * ktime_get() family: read the current time in a multitude of ways,
- *
- * The default time reference is CLOCK_MONOTONIC, starting at
- * boot time but not counting the time spent in suspend.
- * For other references, use the functions with "real", "clocktai",
- * "boottime" and "raw" suffixes.
- *
- * To get the time in a different format, use the ones wit
- * "ns", "ts64" and "seconds" suffix.
- *
- * See Documentation/core-api/timekeeping.rst for more details.
- */
-
-
-/*
- * timespec64 based interfaces
- */
-extern void ktime_get_raw_ts64(struct timespec64 *ts);
-extern void ktime_get_ts64(struct timespec64 *ts);
-extern void ktime_get_real_ts64(struct timespec64 *tv);
-extern void ktime_get_coarse_ts64(struct timespec64 *ts);
-extern void ktime_get_coarse_real_ts64(struct timespec64 *ts);
-
-void getboottime64(struct timespec64 *ts);
-
-/*
- * time64_t base interfaces
- */
-extern time64_t ktime_get_seconds(void);
-extern time64_t __ktime_get_real_seconds(void);
-extern time64_t ktime_get_real_seconds(void);
-
-/*
- * ktime_t based interfaces
- */
-
-enum tk_offsets {
-	TK_OFFS_REAL,
-	TK_OFFS_BOOT,
-	TK_OFFS_TAI,
-	TK_OFFS_MAX,
-};
-
-extern ktime_t ktime_get(void);
-extern ktime_t ktime_get_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs);
-extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs);
-extern ktime_t ktime_get_raw(void);
-extern u32 ktime_get_resolution_ns(void);
-
-/**
- * ktime_get_real - get the real (wall-) time in ktime_t format
- */
-static inline ktime_t ktime_get_real(void)
-{
-	return ktime_get_with_offset(TK_OFFS_REAL);
-}
-
-static inline ktime_t ktime_get_coarse_real(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_REAL);
-}
-
-/**
- * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
- *
- * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
- * time spent in suspend.
- */
-static inline ktime_t ktime_get_boottime(void)
-{
-	return ktime_get_with_offset(TK_OFFS_BOOT);
-}
-
-static inline ktime_t ktime_get_coarse_boottime(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_BOOT);
-}
-
-/**
- * ktime_get_clocktai - Returns the TAI time of day in ktime_t format
- */
-static inline ktime_t ktime_get_clocktai(void)
-{
-	return ktime_get_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse_clocktai(void)
-{
-	return ktime_get_coarse_with_offset(TK_OFFS_TAI);
-}
-
-static inline ktime_t ktime_get_coarse(void)
-{
-	struct timespec64 ts;
-
-	ktime_get_coarse_ts64(&ts);
-	return timespec64_to_ktime(ts);
-}
-
-static inline u64 ktime_get_coarse_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse());
-}
-
-static inline u64 ktime_get_coarse_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_real());
-}
-
-static inline u64 ktime_get_coarse_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_boottime());
-}
-
-static inline u64 ktime_get_coarse_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_coarse_clocktai());
-}
-
-/**
- * ktime_mono_to_real - Convert monotonic time to clock realtime
- */
-static inline ktime_t ktime_mono_to_real(ktime_t mono)
-{
-	return ktime_mono_to_any(mono, TK_OFFS_REAL);
-}
-
-static inline u64 ktime_get_ns(void)
-{
-	return ktime_to_ns(ktime_get());
-}
-
-static inline u64 ktime_get_real_ns(void)
-{
-	return ktime_to_ns(ktime_get_real());
-}
-
-static inline u64 ktime_get_boottime_ns(void)
-{
-	return ktime_to_ns(ktime_get_boottime());
-}
-
-static inline u64 ktime_get_clocktai_ns(void)
-{
-	return ktime_to_ns(ktime_get_clocktai());
-}
-
-static inline u64 ktime_get_raw_ns(void)
-{
-	return ktime_to_ns(ktime_get_raw());
-}
-
-extern u64 ktime_get_mono_fast_ns(void);
-extern u64 ktime_get_raw_fast_ns(void);
-extern u64 ktime_get_boot_fast_ns(void);
-extern u64 ktime_get_real_fast_ns(void);
-
-/*
- * timespec64/time64_t interfaces utilizing the ktime based ones
- * for API completeness, these could be implemented more efficiently
- * if needed.
- */
-static inline void ktime_get_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_boottime());
-}
-
-static inline void ktime_get_coarse_boottime_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_boottime());
-}
-
-static inline time64_t ktime_get_boottime_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_boottime(), NSEC_PER_SEC);
-}
-
-static inline void ktime_get_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_clocktai());
-}
-
-static inline void ktime_get_coarse_clocktai_ts64(struct timespec64 *ts)
-{
-	*ts = ktime_to_timespec64(ktime_get_coarse_clocktai());
-}
-
-static inline time64_t ktime_get_clocktai_seconds(void)
-{
-	return ktime_divns(ktime_get_coarse_clocktai(), NSEC_PER_SEC);
-}
-
 /*
  * RTC specific
  */
@@ -308,4 +113,4 @@ void read_persistent_wall_and_boot_offset(struct timespec64 *wall_clock,
 extern int update_persistent_clock64(struct timespec64 now);
 #endif
 
-#endif
+#endif /* _LINUX_TIMEKEEPING_H */
diff --git a/init/main.c b/init/main.c
index bb984ed79de0..6a6f85e9404f 100644
--- a/init/main.c
+++ b/init/main.c
@@ -99,6 +99,7 @@
 #include <linux/kcsan.h>
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
+#include <linux/timekeeping.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 406dccb79c2b..804f06801737 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -18,6 +18,7 @@
 #include <linux/module.h>
 #include <linux/rtc.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "ntp_internal.h"
 #include "timekeeping_internal.h"
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 1cd10b102c51..410a9336748e 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -13,6 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/time.h>
+#include <linux/timekeeping.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
 
diff --git a/kernel/time/tick-legacy.c b/kernel/time/tick-legacy.c
index af225b32f5b3..9a534f716462 100644
--- a/kernel/time/tick-legacy.c
+++ b/kernel/time/tick-legacy.c
@@ -7,6 +7,7 @@
 #include <linux/irq.h>
 #include <linux/profile.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 29923b20e0e4..7292ed074742 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -29,6 +29,7 @@
 #include <linux/timex.h>
 #include <linux/capability.h>
 #include <linux/timekeeper_internal.h>
+#include <linux/timekeeping.h>
 #include <linux/errno.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index b348749a9fc6..d234cb8a97fe 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -22,6 +22,7 @@
 #include <linux/pvclock_gtod.h>
 #include <linux/compiler.h>
 #include <linux/audit.h>
+#include <linux/timekeeping.h>
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 930ae4002a81..8014f02e4443 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
+#include <linux/timekeeping.h>
 
 #ifdef CONFIG_X86
 /* for art-tsc conversion */
-- 
2.27.0



From maz at kernel.org  Wed Jan 26 12:11:23 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 20:11:23 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <YebKfXhj08h9PoXb@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
 <YebKfXhj08h9PoXb@monolith.localdoman>
Message-ID: <877dam6yvo.wl-maz@kernel.org>

On Tue, 18 Jan 2022 14:11:09 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> > From: Jintack Lim <jintack.lim at linaro.org>
> > 
> > Support injecting exceptions and performing exception returns to and
> > from virtual EL2.  This must be done entirely in software except when
> > taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
> > == {1,1}  (a VHE guest hypervisor).
> 
> Might be useful to explain why emulation shouldn't (or can't) be done in
> software in that particular case.
> 
> It looks to me like kvm_inject_nested() and kvm_emulate_nested_eret()
> handles the above case, so why does does it say that emulation must not be
> done entirely in software?

Not quite. What can be done in HW is the transition between EL0 and
vEL2 when the guest is VHE (where EL2 looks just like EL1). Everything
else has to be mediated one way or the other.

> 
> > 
> > Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > [maz: switch to common exception injection framework]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  .mailmap                             |   1 +
> >  arch/arm64/include/asm/kvm_arm.h     |  17 +++
> >  arch/arm64/include/asm/kvm_emulate.h |  10 ++
> >  arch/arm64/include/asm/kvm_host.h    |   1 +
> >  arch/arm64/kvm/Makefile              |   2 +-
> >  arch/arm64/kvm/emulate-nested.c      | 176 +++++++++++++++++++++++++++
> >  arch/arm64/kvm/hyp/exception.c       |  49 ++++++--
> >  arch/arm64/kvm/inject_fault.c        |  68 +++++++++--
> >  arch/arm64/kvm/trace_arm.h           |  59 +++++++++
> >  9 files changed, 362 insertions(+), 21 deletions(-)
> >  create mode 100644 arch/arm64/kvm/emulate-nested.c
> > 
> > diff --git a/.mailmap b/.mailmap
> > index 14314e3c5d5e..491238a888cb 100644
> > --- a/.mailmap
> > +++ b/.mailmap
> > @@ -167,6 +167,7 @@ Jeff Layton <jlayton at kernel.org> <jlayton at redhat.com>
> >  Jens Axboe <axboe at suse.de>
> >  Jens Osterkamp <Jens.Osterkamp at de.ibm.com>
> >  Jernej Skrabec <jernej.skrabec at gmail.com> <jernej.skrabec at siol.net>
> > +<jintack at cs.columbia.edu> <jintack.lim at linaro.org>
> >  Jiri Slaby <jirislaby at kernel.org> <jirislaby at gmail.com>
> >  Jiri Slaby <jirislaby at kernel.org> <jslaby at novell.com>
> >  Jiri Slaby <jirislaby at kernel.org> <jslaby at suse.com>
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index a39fcf318c77..589a6b92d741 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -359,4 +359,21 @@
> >  #define CPACR_EL1_TTA		(1 << 28)
> >  #define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
> >  
> > +#define kvm_mode_names				\
> > +	{ PSR_MODE_EL0t,	"EL0t" },	\
> > +	{ PSR_MODE_EL1t,	"EL1t" },	\
> > +	{ PSR_MODE_EL1h,	"EL1h" },	\
> > +	{ PSR_MODE_EL2t,	"EL2t" },	\
> > +	{ PSR_MODE_EL2h,	"EL2h" },	\
> > +	{ PSR_MODE_EL3t,	"EL3t" },	\
> > +	{ PSR_MODE_EL3h,	"EL3h" },	\
> > +	{ PSR_AA32_MODE_USR,	"32-bit USR" },	\
> > +	{ PSR_AA32_MODE_FIQ,	"32-bit FIQ" },	\
> > +	{ PSR_AA32_MODE_IRQ,	"32-bit IRQ" },	\
> > +	{ PSR_AA32_MODE_SVC,	"32-bit SVC" },	\
> > +	{ PSR_AA32_MODE_ABT,	"32-bit ABT" },	\
> > +	{ PSR_AA32_MODE_HYP,	"32-bit HYP" },	\
> > +	{ PSR_AA32_MODE_UND,	"32-bit UND" },	\
> > +	{ PSR_AA32_MODE_SYS,	"32-bit SYS" }
> > +
> >  #endif /* __ARM64_KVM_ARM_H__ */
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index f4b079945d0f..46c849ba281e 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -33,6 +33,12 @@ enum exception_type {
> >  	except_type_serror	= 0x180,
> >  };
> >  
> > +#define kvm_exception_type_names		\
> > +	{ except_type_sync,	"SYNC"   },	\
> > +	{ except_type_irq,	"IRQ"    },	\
> > +	{ except_type_fiq,	"FIQ"    },	\
> > +	{ except_type_serror,	"SERROR" }
> > +
> >  bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
> >  void kvm_skip_instr32(struct kvm_vcpu *vcpu);
> >  
> > @@ -41,6 +47,10 @@ void kvm_inject_vabt(struct kvm_vcpu *vcpu);
> >  void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr);
> >  void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
> >  
> > +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
> > +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
> > +int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
> > +
> >  static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
> >  {
> >  	return !(vcpu->arch.hcr_el2 & HCR_RW);
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 4f642a2e9c34..7b6fe18ee450 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -477,6 +477,7 @@ struct kvm_vcpu_arch {
> >  #define KVM_ARM64_EXCEPT_AA64_ELx_SERR	(3 << 9)
> >  #define KVM_ARM64_EXCEPT_AA64_EL1	(0 << 11)
> >  #define KVM_ARM64_EXCEPT_AA64_EL2	(1 << 11)
> > +#define KVM_ARM64_EXCEPT_AA64_EL_MASK	(1 << 11)
> >  
> >  /*
> >   * Overlaps with KVM_ARM64_EXCEPT_MASK on purpose so that it can't be
> > diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
> > index 989bb5dad2c8..1f602526e9a2 100644
> > --- a/arch/arm64/kvm/Makefile
> > +++ b/arch/arm64/kvm/Makefile
> > @@ -16,7 +16,7 @@ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
> >  	 inject_fault.o va_layout.o handle_exit.o \
> >  	 guest.o debug.o reset.o sys_regs.o \
> >  	 vgic-sys-reg-v3.o fpsimd.o pmu.o \
> > -	 arch_timer.o trng.o\
> > +	 arch_timer.o trng.o emulate-nested.o \
> >  	 vgic/vgic.o vgic/vgic-init.o \
> >  	 vgic/vgic-irqfd.o vgic/vgic-v2.o \
> >  	 vgic/vgic-v3.o vgic/vgic-v4.o \
> > diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> > new file mode 100644
> > index 000000000000..339e8272b01e
> > --- /dev/null
> > +++ b/arch/arm64/kvm/emulate-nested.c
> > @@ -0,0 +1,176 @@
> > +/*
> > + * Copyright (C) 2016 - Linaro and Columbia University
> > + * Author: Jintack Lim <jintack.lim at linaro.org>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * 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.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> 
> Wouldn't an SPDX license identifier be better here?

Yup, done.

> 
> > + */
> > +
> > +#include <linux/kvm.h>
> > +#include <linux/kvm_host.h>
> > +
> > +#include <asm/kvm_emulate.h>
> > +#include <asm/kvm_nested.h>
> > +
> > +#include "hyp/include/hyp/adjust_pc.h"
> > +
> > +#include "trace.h"
> > +
> > +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> > +{
> > +	u64 spsr, elr, mode;
> > +	bool direct_eret;
> > +
> > +	/*
> > +	 * Going through the whole put/load motions is a waste of time
> > +	 * if this is a VHE guest hypervisor returning to its own
> > +	 * userspace, or the hypervisor performing a local exception
> > +	 * return. No need to save/restore registers, no need to
> > +	 * switch S2 MMU. Just do the canonical ERET.
> > +	 */
> > +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> > +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> > +
> > +	direct_eret  = (mode == PSR_MODE_EL0t &&
> > +			vcpu_el2_e2h_is_set(vcpu) &&
> > +			vcpu_el2_tge_is_set(vcpu));
> > +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> > +
> > +	if (direct_eret) {
> > +		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
> > +		*vcpu_cpsr(vcpu) = spsr;
> > +		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
> > +		return;
> > +	}
> > +
> > +	preempt_disable();
> > +	kvm_arch_vcpu_put(vcpu);
> > +
> > +	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
> > +
> > +	trace_kvm_nested_eret(vcpu, elr, spsr);
> > +
> > +	/*
> > +	 * Note that the current exception level is always the virtual EL2,
> > +	 * since we set HCR_EL2.NV bit only when entering the virtual EL2.
> > +	 */
> > +	*vcpu_pc(vcpu) = elr;
> > +	*vcpu_cpsr(vcpu) = spsr;
> > +
> > +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> > +	preempt_enable();
> > +}
> > +
> > +static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2,
> > +				     enum exception_type type)
> > +{
> > +	trace_kvm_inject_nested_exception(vcpu, esr_el2, type);
> > +
> > +	switch (type) {
> > +	case except_type_sync:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_SYNC;
> > +		break;
> > +	case except_type_irq:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_IRQ;
> > +		break;
> > +	default:
> > +		WARN_ONCE(1, "Unsupported EL2 exception injection %d\n", type);
> > +	}
> > +
> > +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL2		|
> > +			     KVM_ARM64_PENDING_EXCEPTION);
> > +
> > +	vcpu_write_sys_reg(vcpu, esr_el2, ESR_EL2);
> > +}
> > +
> > +/*
> > + * Emulate taking an exception to EL2.
> > + * See ARM ARM J8.1.2 AArch64.TakeException()
> > + */
> > +static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
> > +			     enum exception_type type)
> > +{
> > +	u64 pstate, mode;
> > +	bool direct_inject;
> > +
> > +	if (!nested_virt_in_use(vcpu)) {
> > +		kvm_err("Unexpected call to %s for the non-nesting configuration\n",
> > +				__func__);
> > +		return -EINVAL;
> > +	}
> > +
> > +	/*
> > +	 * As for ERET, we can avoid doing too much on the injection path by
> > +	 * checking that we either took the exception from a VHE host
> > +	 * userspace or from vEL2. In these cases, there is no change in
> > +	 * translation regime (or anything else), so let's do as little as
> > +	 * possible.
> > +	 */
> > +	pstate = *vcpu_cpsr(vcpu);
> > +	mode = pstate & (PSR_MODE_MASK | PSR_MODE32_BIT);
> > +
> > +	direct_inject  = (mode == PSR_MODE_EL0t &&
> > +			  vcpu_el2_e2h_is_set(vcpu) &&
> > +			  vcpu_el2_tge_is_set(vcpu));
> > +	direct_inject |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> > +
> > +	if (direct_inject) {
> > +		kvm_inject_el2_exception(vcpu, esr_el2, type);
> > +		return 1;
> > +	}
> > +
> > +	preempt_disable();
> > +	kvm_arch_vcpu_put(vcpu);
> > +
> > +	kvm_inject_el2_exception(vcpu, esr_el2, type);
> > +
> > +	/*
> > +	 * A hard requirement is that a switch between EL1 and EL2
> > +	 * contexts has to happen between a put/load, so that we can
> > +	 * pick the correct timer and interrupt configuration, among
> > +	 * other things.
> > +	 *
> > +	 * Make sure the exception actually took place before we load
> > +	 * the new context.
> > +	 */
> > +	__kvm_adjust_pc(vcpu);
> > +
> > +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> > +	preempt_enable();
> > +
> > +	return 1;
> > +}
> > +
> > +int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
> > +{
> > +	return kvm_inject_nested(vcpu, esr_el2, except_type_sync);
> > +}
> > +
> > +int kvm_inject_nested_irq(struct kvm_vcpu *vcpu)
> 
> I assume this is actually injecting an IRQ to the guest's virtual EL2, not
> a nested interrupt, right?

Neither, really. This is injecting an IRQ *exception* into the guest.
The actual interrupt delivery is done via the vgic. If nested
interrupts (in the interrupt preemption sense) have to happen, the
vgic will take care of it.

> 
> > +{
> > +	/*
> > +	 * Do not inject an irq if the:
> > +	 *  - Current exception level is EL2, and
> > +	 *  - virtual HCR_EL2.TGE == 0
> > +	 *  - virtual HCR_EL2.IMO == 0
> > +	 *
> > +	 * See Table D1-17 "Physical interrupt target and masking when EL3 is
> > +	 * not implemented and EL2 is implemented" in ARM DDI 0487C.a.
> 
> That's now Table D1-13 in ARM DDI 0487G.a, the latest Arm ARM as of now, in
> case you want to update the comment. The table name isn't unchanged, so
> that can be used to find it in newer versions, so I don't think the update
> is strictly necessary.
> 
> I assume the comment refers to the first line of the table, as that's the
> only case when an interrupt is unconditionally not taken when asserted.
> But according to the table, the interrupt is not taken when the *target* EL
> is EL1 and the CPU is executing at EL2. Which makes me very confused. Isn't
> this function supposed to inject an interrupt to virtual EL2? If this
> function also injects interrupts to virtual EL1, why doesn't it also check
> that the target EL is EL1 before returning?

This is already checked by the caller: see kvm_vgic_flush_hwstate()
which has the following sequence:

	if (vgic_state_is_nested(vcpu)) {
		if (kvm_vgic_vcpu_pending_irq(vcpu))
			kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);

which ends up triggering the exception injection.

> 
> > +	 */
> > +
> > +	if (vcpu_mode_el2(vcpu) && !vcpu_el2_tge_is_set(vcpu) &&
> > +	    !(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_IMO))
> > +		return 1;
> > +
> > +	/* esr_el2 value doesn't matter for exits due to irqs. */
> > +	return kvm_inject_nested(vcpu, 0, except_type_irq);
> > +}
> > diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
> > index 0418399e0a20..4ef5e86efd8b 100644
> > --- a/arch/arm64/kvm/hyp/exception.c
> > +++ b/arch/arm64/kvm/hyp/exception.c
> > @@ -13,6 +13,7 @@
> >  #include <hyp/adjust_pc.h>
> >  #include <linux/kvm_host.h>
> >  #include <asm/kvm_emulate.h>
> > +#include <asm/kvm_nested.h>
> >  
> >  #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__)
> >  #error Hypervisor code only!
> > @@ -22,7 +23,9 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
> >  {
> >  	u64 val;
> >  
> > -	if (__vcpu_read_sys_reg_from_cpu(reg, &val))
> > +	if (unlikely(nested_virt_in_use(vcpu)))
> > +		return vcpu_read_sys_reg(vcpu, reg);
> > +	else if (__vcpu_read_sys_reg_from_cpu(reg, &val))
> >  		return val;
> 
> I find the above unintuitive. The original code duplicated the
> functionality from sys_regs.c::vcpu_read_sys_reg() in order to be able to
> run the code at EL2 in the protected KVM case. So why are we now adding
> back the dependency to the EL1 code? Yes, the call to vcpu_read_sys_reg()
> is never compiled because of how nested_virt_in_use() is defined, but still
> looks unconsistent with the purpose of the function (and this file).
> 
> After careful digging, I realized why this change is needed:
> kvm_inject_nested() calls __kvm_adjust_pc() after a vcpu_put(), so the
> function needs to check vcpu->arch.sysregs_loaded_on_cpu, which now can be
> false. Why not copy the body of vcpu_read_sys_reg(), which is what
> __vcpu_read_sys_reg is supposed to do? With a comment explaining why
> sysregs_loaded_on_cpu can be false, I think the code would be a lot more
> understandable.
> 
> Or is it that you want all VCPU register accesses to be done with
> vcpu_read_sys_reg() when the VCPU has the EL2 feature?

Both. The whole NV support is based on this "put/load" sequences when
we alternate between EL{0,1} and EL2, and tracking whether you're
loaded or not is really difficult. I agree that this is pretty ugly,
but I also don't want to spread the crap everywhere (and I have
trouble keeping both the NV and pKVM models in my head at the same
time!).

> 
> >  
> >  	return __vcpu_sys_reg(vcpu, reg);
> > @@ -30,14 +33,24 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
> >  
> >  static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
> >  {
> > -	if (__vcpu_write_sys_reg_to_cpu(val, reg))
> > -		return;
> > -
> > -	 __vcpu_sys_reg(vcpu, reg) = val;
> > +	if (unlikely(nested_virt_in_use(vcpu)))
> > +		vcpu_write_sys_reg(vcpu, val, reg);
> > +	else if (!__vcpu_write_sys_reg_to_cpu(val, reg))
> > +		__vcpu_sys_reg(vcpu, reg) = val;
> >  }
> >  
> > -static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
> > +static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
> > +			      u64 val)
> >  {
> > +	if (unlikely(nested_virt_in_use(vcpu))) {
> > +		if (target_mode == PSR_MODE_EL1h)
> > +			vcpu_write_sys_reg(vcpu, val, SPSR_EL1);
> > +		else
> > +			vcpu_write_sys_reg(vcpu, val, SPSR_EL2);
> > +
> > +		return;
> > +	}
> > +
> >  	write_sysreg_el1(val, SYS_SPSR);
> >  }
> >  
> > @@ -97,6 +110,11 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
> >  		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
> >  		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
> >  		break;
> > +	case PSR_MODE_EL2h:
> > +		vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
> > +		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
> > +		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
> > +		break;
> >  	default:
> >  		/* Don't do that */
> >  		BUG();
> > @@ -149,7 +167,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
> >  	new |= target_mode;
> >  
> >  	*vcpu_cpsr(vcpu) = new;
> > -	__vcpu_write_spsr(vcpu, old);
> > +	__vcpu_write_spsr(vcpu, target_mode, old);
> >  }
> >  
> >  /*
> > @@ -320,11 +338,22 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
> >  		      KVM_ARM64_EXCEPT_AA64_EL1):
> >  			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync);
> >  			break;
> > +
> > +		case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
> > +		      KVM_ARM64_EXCEPT_AA64_EL2):
> > +			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_sync);
> > +			break;
> > +
> > +		case (KVM_ARM64_EXCEPT_AA64_ELx_IRQ |
> > +		      KVM_ARM64_EXCEPT_AA64_EL2):
> > +			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_irq);
> > +			break;
> > +
> >  		default:
> >  			/*
> > -			 * Only EL1_SYNC makes sense so far, EL2_{SYNC,IRQ}
> > -			 * will be implemented at some point. Everything
> > -			 * else gets silently ignored.
> > +			 * Only EL1_SYNC and EL2_{SYNC,IRQ} makes
> > +			 * sense so far. Everything else gets silently
> > +			 * ignored.
> >  			 */
> >  			break;
> >  		}
> > diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
> > index b47df73e98d7..5dcf3f8b08b8 100644
> > --- a/arch/arm64/kvm/inject_fault.c
> > +++ b/arch/arm64/kvm/inject_fault.c
> > @@ -12,19 +12,58 @@
> >  
> >  #include <linux/kvm_host.h>
> >  #include <asm/kvm_emulate.h>
> > +#include <asm/kvm_nested.h>
> >  #include <asm/esr.h>
> >  
> > +static void pend_sync_exception(struct kvm_vcpu *vcpu)
> > +{
> > +	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
> > +			     KVM_ARM64_PENDING_EXCEPTION);
> > +
> > +	/* If not nesting, EL1 is the only possible exception target */
> > +	if (likely(!nested_virt_in_use(vcpu))) {
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> > +		return;
> > +	}
> > +
> > +	/*
> > +	 * With NV, we need to pick between EL1 and EL2. Note that we
> > +	 * never deal with a nesting exception here, hence never
> 
> I don't understand what "a nesting exception" refers to. In
> emulate_nested.c, the comment for kvm_inject_nested() says that it
> emulates taking an exception to EL2, so I assume a *nested*
> exception is an exception injected to guest virtual EL2. But what is
> a *nesting* exception? Am I misunderstanding something?

Same thing. It is just that the code and the comments have been
written by 3 different people, none of whom being native English
speakers, and this is bound to be inconsistent.

Just get over it. ;-)

> 
> > +	 * changing context, and the exception itself can be delayed
> > +	 * until the next entry.
> > +	 */
> > +	switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
> > +	case PSR_MODE_EL2h:
> > +	case PSR_MODE_EL2t:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> > +		break;
> > +	case PSR_MODE_EL1h:
> > +	case PSR_MODE_EL1t:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> > +		break;
> > +	case PSR_MODE_EL0t:
> > +		if (vcpu_el2_tge_is_set(vcpu) & HCR_TGE)
> 
> Doesn't vcpu_el2_tge_is_set() already return true if HCR_TGE is set?

Weee!!! Nice catch! Good thing we almost never inject any of those (we
mostly run wel;l behaved SW), as we'd target the wrong exception
level...

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From broonie at kernel.org  Wed Jan 26 12:13:18 2022
From: broonie at kernel.org (Mark Brown)
Date: Wed, 26 Jan 2022 20:13:18 +0000
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <48c44d74-6668-7823-ada6-0285a8b32a35@linuxfoundation.org>
References: <20220126145242.3473836-1-broonie@kernel.org>
 <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>
 <YfGmk1I8l+ROoE/k@sirena.org.uk>
 <48c44d74-6668-7823-ada6-0285a8b32a35@linuxfoundation.org>
Message-ID: <YfGrXr1/NGREULnB@sirena.org.uk>

On Wed, Jan 26, 2022 at 01:03:44PM -0700, Shuah Khan wrote:
> On 1/26/22 12:52 PM, Mark Brown wrote:

> > If the function fails for any reason other than the system not
> > supporting vgic-v3 it will abort rather than return.

> Hmm. vgic_v3_setup() return gic_fd looks like and the interface says
> Return: GIC file-descriptor or negative error code upon failure

Yes, but in reality the only return other than a valid file descriptor
is just -1 rather than a useful error code.

> I don't follow the abort part.

All the TEST_ASSERTS() in the code (including those in the functions
called) are calls to test_assert() in assert.c which if the test
asserted isn't true will print some diagnostics and call exit(), the
general idiom is to give up immediately on error.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220126/56ad478e/attachment-0001.sig>

From maz at kernel.org  Wed Jan 26 12:32:39 2022
From: maz at kernel.org (Marc Zyngier)
Date: Wed, 26 Jan 2022 20:32:39 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <YebklBdMSwOplyrJ@shell.armlinux.org.uk>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
 <YebklBdMSwOplyrJ@shell.armlinux.org.uk>
Message-ID: <875yq66xw8.wl-maz@kernel.org>

On Tue, 18 Jan 2022 16:02:28 +0000,
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> 
> On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> > From: Jintack Lim <jintack.lim at linaro.org>
> > 
> > Support injecting exceptions and performing exception returns to and
> > from virtual EL2.  This must be done entirely in software except when
> > taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
> > == {1,1}  (a VHE guest hypervisor).
> > 
> > Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > [maz: switch to common exception injection framework]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> ...
> > +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> > +{
> > +	u64 spsr, elr, mode;
> > +	bool direct_eret;
> > +
> > +	/*
> > +	 * Going through the whole put/load motions is a waste of time
> > +	 * if this is a VHE guest hypervisor returning to its own
> > +	 * userspace, or the hypervisor performing a local exception
> > +	 * return. No need to save/restore registers, no need to
> > +	 * switch S2 MMU. Just do the canonical ERET.
> > +	 */
> > +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> > +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> > +
> > +	direct_eret  = (mode == PSR_MODE_EL0t &&
> > +			vcpu_el2_e2h_is_set(vcpu) &&
> > +			vcpu_el2_tge_is_set(vcpu));
> > +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> 
> There are excessive parens on the RHS of the above two.

I guess this is my personal taste, and this is the kind of cosmetic
things that help me reason about the code. Some people use syntax
highlighting, I use bracketing. I don't think this really matters in
the grand scheme of things.

[...]

> > +/*
> > + * Emulate taking an exception to EL2.
> > + * See ARM ARM J8.1.2 AArch64.TakeException()
> > + */
> > +static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
> > +			     enum exception_type type)
> > +{
> > +	u64 pstate, mode;
> > +	bool direct_inject;
> > +
> > +	if (!nested_virt_in_use(vcpu)) {
> > +		kvm_err("Unexpected call to %s for the non-nesting configuration\n",
> > +				__func__);
> 
> Too much indentation. I'm guessing this "unexpected" condition isn't
> something that can be caused by a rogue guest? If it can, doesn't this
> need to be rate limited?

If we end-up here, this is very much a hypervisor logic bug.

[...]

> > +
> > +	/* If not nesting, EL1 is the only possible exception target */
> > +	if (likely(!nested_virt_in_use(vcpu))) {
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> > +		return;
> > +	}
> > +
> > +	/*
> > +	 * With NV, we need to pick between EL1 and EL2. Note that we
> > +	 * never deal with a nesting exception here, hence never
> > +	 * changing context, and the exception itself can be delayed
> > +	 * until the next entry.
> > +	 */
> > +	switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
> > +	case PSR_MODE_EL2h:
> > +	case PSR_MODE_EL2t:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> > +		break;
> > +	case PSR_MODE_EL1h:
> > +	case PSR_MODE_EL1t:
> > +		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> > +		break;
> > +	case PSR_MODE_EL0t:
> > +		if (vcpu_el2_tge_is_set(vcpu) & HCR_TGE)
> > +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
> > +		else
> > +			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
> > +		break;
> > +	default:
> > +		BUG();
> 
> Is taking out the host really appropriate here? Is this something a
> rogue guest could trigger?

This switch is supposed to cover all the NS exception levels, in
either stack configuration. If we suddenly find ourselves with a
non-architectural state, we have horribly messed up. And no, a guest
shouldn't be able to affect this. If it can, that's even more of a
reason to take everything down ASAP.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From skhan at linuxfoundation.org  Wed Jan 26 12:50:36 2022
From: skhan at linuxfoundation.org (Shuah Khan)
Date: Wed, 26 Jan 2022 13:50:36 -0700
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <YfGrXr1/NGREULnB@sirena.org.uk>
References: <20220126145242.3473836-1-broonie@kernel.org>
 <4424dd30-f74b-006f-b540-dbaf02e45e28@linuxfoundation.org>
 <YfGmk1I8l+ROoE/k@sirena.org.uk>
 <48c44d74-6668-7823-ada6-0285a8b32a35@linuxfoundation.org>
 <YfGrXr1/NGREULnB@sirena.org.uk>
Message-ID: <2e9162ef-6107-e56c-e713-1f1ac7f83003@linuxfoundation.org>

On 1/26/22 1:13 PM, Mark Brown wrote:
> On Wed, Jan 26, 2022 at 01:03:44PM -0700, Shuah Khan wrote:
>> On 1/26/22 12:52 PM, Mark Brown wrote:
> 
>>> If the function fails for any reason other than the system not
>>> supporting vgic-v3 it will abort rather than return.
> 
>> Hmm. vgic_v3_setup() return gic_fd looks like and the interface says
>> Return: GIC file-descriptor or negative error code upon failure
> 
> Yes, but in reality the only return other than a valid file descriptor
> is just -1 rather than a useful error code.
> 

The interface document gives the impression that it will return
error - Oh well. In which case, no point in printing that. Agree.

>> I don't follow the abort part.
> 
> All the TEST_ASSERTS() in the code (including those in the functions
> called) are calls to test_assert() in assert.c which if the test
> asserted isn't true will print some diagnostics and call exit(), the
> general idiom is to give up immediately on error.
> 

Ah right. Makes sense.

thanks,
-- Shuah


From helgaas at kernel.org  Wed Jan 26 12:51:05 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Wed, 26 Jan 2022 14:51:05 -0600
Subject: [PATCH] Revert "PCI: j721e: Drop redundant struct device *"
In-Reply-To: <20220124122132.435743-1-christian.gmeiner@gmail.com>
Message-ID: <20220126205105.GA47875@bhelgaas>

On Mon, Jan 24, 2022 at 01:21:22PM +0100, Christian Gmeiner wrote:
> This reverts commit 19e863828acf6d8ac8475ba1fd93c0fe17fdc4ef.
> 
> Fixes the following oops:
>  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010

My fault, sorry for breaking this.  Thanks a lot for the report!

19e863828acf ("PCI: j721e: Drop redundant struct device *") failed to
consider the uses of pcie->cdns_pcie->dev before pcie->cdns_pcie is
initialized.  I'll figure out what to do about it.

>  Internal error: Oops: 96000004 [#1] PREEMPT SMP
>  Modules linked in:
>  CPU: 1 PID: 7 Comm: kworker/u4:0 Not tainted 5.17.0-rc1-00086-ge38b27816fea-dirty #71
>  Hardware name: CPE0108 (DT)
>  Workqueue: events_unbound deferred_probe_work_func
>  pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
>  pc : j721e_pcie_probe+0x184/0x600
>  lr : j721e_pcie_probe+0x170/0x600
>  sp : ffff80000957bae0
>  x29: ffff80000957bae0 x28: ffff800009357000 x27: ffff00000000c078
>  x26: ffff00003fe047a8 x25: 0000000000000000 x24: ffff0000000f5280
>  x23: ffff800008c98f78 x22: ffff800008f90ff0 x21: ffff000000231410
>  x20: ffff000002ef2780 x19: 0000000000000021 x18: 0000000000000001
>  x17: 0000000000000000 x16: 0000000000058c00 x15: ffffffffffffffff
>  x14: ffffffffffffffff x13: 0000000000000010 x12: 0101010101010101
>  x11: 0000000000000040 x10: ffff8000093e06c8 x9 : ffff8000093e06c0
>  x8 : ffff000000400270 x7 : 0000000000000000 x6 : ffff000000231590
>  x5 : ffff80000957b9e0 x4 : 0000000000000000 x3 : ffff0000002314f4
>  x2 : 0000000000000000 x1 : ffff0000000f5280 x0 : 0000000000000000
>  Call trace:
>   j721e_pcie_probe+0x184/0x600
>   platform_probe+0x68/0xe0
>   really_probe+0x144/0x320
>   __driver_probe_device+0xc4/0xe0
>   driver_probe_device+0x7c/0x110
>   __device_attach_driver+0x90/0xe0
>   bus_for_each_drv+0x78/0xd0
>   __device_attach+0xf0/0x150
>   device_initial_probe+0x14/0x20
>   bus_probe_device+0x9c/0xb0
>   deferred_probe_work_func+0x88/0xc0
>   process_one_work+0x1bc/0x340
>   worker_thread+0x1f8/0x420
>   kthread+0x110/0x120
>   ret_from_fork+0x10/0x20
>  Code: f9400280 a90573fb d0005396 913fc2d6 (f9400800)
> 
> Fixes: 19e863828acf ("PCI: j721e: Drop redundant struct device *")
> Signed-off-by: Christian Gmeiner <christian.gmeiner at gmail.com>
> ---
>  drivers/pci/controller/cadence/pci-j721e.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
> index 489586a4cdc7..cd43d1898482 100644
> --- a/drivers/pci/controller/cadence/pci-j721e.c
> +++ b/drivers/pci/controller/cadence/pci-j721e.c
> @@ -51,10 +51,11 @@ enum link_status {
>  #define MAX_LANES			2
>  
>  struct j721e_pcie {
> -	struct cdns_pcie	*cdns_pcie;
> +	struct device		*dev;
>  	struct clk		*refclk;
>  	u32			mode;
>  	u32			num_lanes;
> +	struct cdns_pcie	*cdns_pcie;
>  	void __iomem		*user_cfg_base;
>  	void __iomem		*intd_cfg_base;
>  	u32			linkdown_irq_regfield;
> @@ -98,7 +99,7 @@ static inline void j721e_pcie_intd_writel(struct j721e_pcie *pcie, u32 offset,
>  static irqreturn_t j721e_pcie_link_irq_handler(int irq, void *priv)
>  {
>  	struct j721e_pcie *pcie = priv;
> -	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device *dev = pcie->dev;
>  	u32 reg;
>  
>  	reg = j721e_pcie_intd_readl(pcie, STATUS_REG_SYS_2);
> @@ -164,7 +165,7 @@ static const struct cdns_pcie_ops j721e_pcie_ops = {
>  static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
>  			       unsigned int offset)
>  {
> -	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device *dev = pcie->dev;
>  	u32 mask = J721E_MODE_RC;
>  	u32 mode = pcie->mode;
>  	u32 val = 0;
> @@ -183,7 +184,7 @@ static int j721e_pcie_set_mode(struct j721e_pcie *pcie, struct regmap *syscon,
>  static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
>  				     struct regmap *syscon, unsigned int offset)
>  {
> -	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device *dev = pcie->dev;
>  	struct device_node *np = dev->of_node;
>  	int link_speed;
>  	u32 val = 0;
> @@ -204,7 +205,7 @@ static int j721e_pcie_set_link_speed(struct j721e_pcie *pcie,
>  static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
>  				     struct regmap *syscon, unsigned int offset)
>  {
> -	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device *dev = pcie->dev;
>  	u32 lanes = pcie->num_lanes;
>  	u32 val = 0;
>  	int ret;
> @@ -219,7 +220,7 @@ static int j721e_pcie_set_lane_count(struct j721e_pcie *pcie,
>  
>  static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
>  {
> -	struct device *dev = pcie->cdns_pcie->dev;
> +	struct device *dev = pcie->dev;
>  	struct device_node *node = dev->of_node;
>  	struct of_phandle_args args;
>  	unsigned int offset = 0;
> @@ -376,6 +377,7 @@ static int j721e_pcie_probe(struct platform_device *pdev)
>  	if (!pcie)
>  		return -ENOMEM;
>  
> +	pcie->dev = dev;
>  	pcie->mode = mode;
>  	pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
>  
> -- 
> 2.34.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From clabbe at baylibre.com  Wed Jan 26 13:04:33 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:33 +0000
Subject: [PATCH 0/8] crypto: allwinner: various improvments
Message-ID: <20220126210441.3661782-1-clabbe@baylibre.com>

Hello

The main topic was to remove memory allocation from requests function.
Doing this on sun8i-ss, lead to some extra fixes to be found.

Regards

Corentin Labbe (8):
  crypto: sun8i-ce: do not allocate memory when handling requests
  crypto: sun4i-ss: do not allocate backup IV on requests
  crypto: sun8i-ss: handle zero sized sg
  crypto: sun8i-ss: do not allocate memory when handling hash requests
  crypto: sun8i-ss: do not zeroize all pad
  crypto: sun8i-ss: remove redundant test
  crypto: sun8i-ss: test error before assigning
  crypto: sun8i-ss: handle requests if last block is not modulo 64

 .../allwinner/sun4i-ss/sun4i-ss-cipher.c      | 22 ++---
 drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h  |  1 +
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c      | 28 ++-----
 .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 20 ++++-
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h  |  8 +-
 .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 10 +++
 .../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 84 ++++++++++---------
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h  |  6 ++
 8 files changed, 100 insertions(+), 79 deletions(-)

-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:34 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:34 +0000
Subject: [PATCH 1/8] crypto: sun8i-ce: do not allocate memory when handling
 requests
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-2-clabbe@baylibre.com>

Instead of allocate memory on each requests, it is easier to
pre-allocate buffer for IV.
This made error path easier.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 .../allwinner/sun8i-ce/sun8i-ce-cipher.c      | 28 ++++++-------------
 .../crypto/allwinner/sun8i-ce/sun8i-ce-core.c | 20 ++++++++++---
 drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h  |  8 +++---
 3 files changed, 29 insertions(+), 27 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
index 8f0031e45a03..f4221025d651 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c
@@ -151,23 +151,13 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
 	ivsize = crypto_skcipher_ivsize(tfm);
 	if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
 		rctx->ivlen = ivsize;
-		rctx->bounce_iv = kzalloc(ivsize, GFP_KERNEL | GFP_DMA);
-		if (!rctx->bounce_iv) {
-			err = -ENOMEM;
-			goto theend_key;
-		}
 		if (rctx->op_dir & CE_DECRYPTION) {
-			rctx->backup_iv = kzalloc(ivsize, GFP_KERNEL);
-			if (!rctx->backup_iv) {
-				err = -ENOMEM;
-				goto theend_key;
-			}
 			offset = areq->cryptlen - ivsize;
-			scatterwalk_map_and_copy(rctx->backup_iv, areq->src,
+			scatterwalk_map_and_copy(chan->backup_iv, areq->src,
 						 offset, ivsize, 0);
 		}
-		memcpy(rctx->bounce_iv, areq->iv, ivsize);
-		rctx->addr_iv = dma_map_single(ce->dev, rctx->bounce_iv, rctx->ivlen,
+		memcpy(chan->bounce_iv, areq->iv, ivsize);
+		rctx->addr_iv = dma_map_single(ce->dev, chan->bounce_iv, rctx->ivlen,
 					       DMA_TO_DEVICE);
 		if (dma_mapping_error(ce->dev, rctx->addr_iv)) {
 			dev_err(ce->dev, "Cannot DMA MAP IV\n");
@@ -256,13 +246,13 @@ static int sun8i_ce_cipher_prepare(struct crypto_engine *engine, void *async_req
 			dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE);
 		offset = areq->cryptlen - ivsize;
 		if (rctx->op_dir & CE_DECRYPTION) {
-			memcpy(areq->iv, rctx->backup_iv, ivsize);
-			kfree_sensitive(rctx->backup_iv);
+			memcpy(areq->iv, chan->backup_iv, ivsize);
+			memzero_explicit(chan->backup_iv, ivsize);
 		} else {
 			scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
 						 ivsize, 0);
 		}
-		kfree(rctx->bounce_iv);
+		memzero_explicit(chan->bounce_iv, ivsize);
 	}
 
 theend_key:
@@ -319,13 +309,13 @@ static int sun8i_ce_cipher_unprepare(struct crypto_engine *engine, void *async_r
 			dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE);
 		offset = areq->cryptlen - ivsize;
 		if (rctx->op_dir & CE_DECRYPTION) {
-			memcpy(areq->iv, rctx->backup_iv, ivsize);
-			kfree_sensitive(rctx->backup_iv);
+			memcpy(areq->iv, chan->backup_iv, ivsize);
+			memzero_explicit(chan->backup_iv, ivsize);
 		} else {
 			scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
 						 ivsize, 0);
 		}
-		kfree(rctx->bounce_iv);
+		memzero_explicit(chan->bounce_iv, ivsize);
 	}
 
 	dma_unmap_single(ce->dev, rctx->addr_key, op->keylen, DMA_TO_DEVICE);
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
index ea2c655e4ff1..b57aed120d33 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-core.c
@@ -305,7 +305,7 @@ static struct sun8i_ce_alg_template ce_algs[] = {
 			.cra_priority = 400,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_ASYNC |
 				CRYPTO_ALG_NEED_FALLBACK,
 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
 			.cra_module = THIS_MODULE,
@@ -332,7 +332,7 @@ static struct sun8i_ce_alg_template ce_algs[] = {
 			.cra_priority = 400,
 			.cra_blocksize = AES_BLOCK_SIZE,
 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_ASYNC |
 				CRYPTO_ALG_NEED_FALLBACK,
 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
 			.cra_module = THIS_MODULE,
@@ -358,7 +358,7 @@ static struct sun8i_ce_alg_template ce_algs[] = {
 			.cra_priority = 400,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_ASYNC |
 				CRYPTO_ALG_NEED_FALLBACK,
 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
 			.cra_module = THIS_MODULE,
@@ -385,7 +385,7 @@ static struct sun8i_ce_alg_template ce_algs[] = {
 			.cra_priority = 400,
 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
 			.cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
-				CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
+				CRYPTO_ALG_ASYNC |
 				CRYPTO_ALG_NEED_FALLBACK,
 			.cra_ctxsize = sizeof(struct sun8i_cipher_tfm_ctx),
 			.cra_module = THIS_MODULE,
@@ -728,6 +728,18 @@ static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev *ce)
 			err = -ENOMEM;
 			goto error_engine;
 		}
+		ce->chanlist[i].bounce_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE,
+							 GFP_KERNEL | GFP_DMA);
+		if (!ce->chanlist[i].bounce_iv) {
+			err = -ENOMEM;
+			goto error_engine;
+		}
+		ce->chanlist[i].backup_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE,
+							 GFP_KERNEL);
+		if (!ce->chanlist[i].backup_iv) {
+			err = -ENOMEM;
+			goto error_engine;
+		}
 	}
 	return 0;
 error_engine:
diff --git a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
index 719f9a730857..229b696d5a2c 100644
--- a/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
+++ b/drivers/crypto/allwinner/sun8i-ce/sun8i-ce.h
@@ -213,6 +213,8 @@ struct ce_task {
  * @status:	set to 1 by interrupt if task is done
  * @t_phy:	Physical address of task
  * @tl:		pointer to the current ce_task for this flow
+ * @backup_iv:		buffer which contain the next IV to store
+ * @bounce_iv:		buffer which contain the IV
  * @stat_req:	number of request done by this flow
  */
 struct sun8i_ce_flow {
@@ -222,6 +224,8 @@ struct sun8i_ce_flow {
 	dma_addr_t t_phy;
 	int timeout;
 	struct ce_task *tl;
+	void *backup_iv;
+	void *bounce_iv;
 #ifdef CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG
 	unsigned long stat_req;
 #endif
@@ -268,8 +272,6 @@ struct sun8i_ce_dev {
  * struct sun8i_cipher_req_ctx - context for a skcipher request
  * @op_dir:		direction (encrypt vs decrypt) for this request
  * @flow:		the flow to use for this request
- * @backup_iv:		buffer which contain the next IV to store
- * @bounce_iv:		buffer which contain the IV
  * @ivlen:		size of bounce_iv
  * @nr_sgs:		The number of source SG (as given by dma_map_sg())
  * @nr_sgd:		The number of destination SG (as given by dma_map_sg())
@@ -280,8 +282,6 @@ struct sun8i_ce_dev {
 struct sun8i_cipher_req_ctx {
 	u32 op_dir;
 	int flow;
-	void *backup_iv;
-	void *bounce_iv;
 	unsigned int ivlen;
 	int nr_sgs;
 	int nr_sgd;
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:35 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:35 +0000
Subject: [PATCH 2/8] crypto: sun4i-ss: do not allocate backup IV on requests
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-3-clabbe@baylibre.com>

Instead of allocate memory on each requests, it is easier to
pre-allocate buffer for backup IV.
This made error path easier.
Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 .../allwinner/sun4i-ss/sun4i-ss-cipher.c      | 22 +++++++------------
 drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h  |  1 +
 2 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
index 8dc2a475c601..a8c784acce13 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss-cipher.c
@@ -20,7 +20,6 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 	unsigned int ivsize = crypto_skcipher_ivsize(tfm);
 	struct sun4i_cipher_req_ctx *ctx = skcipher_request_ctx(areq);
 	u32 mode = ctx->mode;
-	void *backup_iv = NULL;
 	/* when activating SS, the default FIFO space is SS_RX_DEFAULT(32) */
 	u32 rx_cnt = SS_RX_DEFAULT;
 	u32 tx_cnt = 0;
@@ -47,10 +46,8 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 	}
 
 	if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
-		backup_iv = kzalloc(ivsize, GFP_KERNEL);
-		if (!backup_iv)
-			return -ENOMEM;
-		scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
+		scatterwalk_map_and_copy(ctx->backup_iv, areq->src,
+					 areq->cryptlen - ivsize, ivsize, 0);
 	}
 
 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
@@ -133,8 +130,8 @@ static int noinline_for_stack sun4i_ss_opti_poll(struct skcipher_request *areq)
 
 	if (areq->iv) {
 		if (mode & SS_DECRYPTION) {
-			memcpy(areq->iv, backup_iv, ivsize);
-			kfree_sensitive(backup_iv);
+			memcpy(areq->iv, ctx->backup_iv, ivsize);
+			memzero_explicit(ctx->backup_iv, ivsize);
 		} else {
 			scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
 						 ivsize, 0);
@@ -198,7 +195,6 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 	unsigned int ileft = areq->cryptlen;
 	unsigned int oleft = areq->cryptlen;
 	unsigned int todo;
-	void *backup_iv = NULL;
 	struct sg_mapping_iter mi, mo;
 	unsigned long pi = 0, po = 0; /* progress for in and out */
 	bool miter_err;
@@ -242,10 +238,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 		return sun4i_ss_cipher_poll_fallback(areq);
 
 	if (areq->iv && ivsize > 0 && mode & SS_DECRYPTION) {
-		backup_iv = kzalloc(ivsize, GFP_KERNEL);
-		if (!backup_iv)
-			return -ENOMEM;
-		scatterwalk_map_and_copy(backup_iv, areq->src, areq->cryptlen - ivsize, ivsize, 0);
+		scatterwalk_map_and_copy(ctx->backup_iv, areq->src,
+					 areq->cryptlen - ivsize, ivsize, 0);
 	}
 
 	if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG)) {
@@ -382,8 +376,8 @@ static int sun4i_ss_cipher_poll(struct skcipher_request *areq)
 	}
 	if (areq->iv) {
 		if (mode & SS_DECRYPTION) {
-			memcpy(areq->iv, backup_iv, ivsize);
-			kfree_sensitive(backup_iv);
+			memcpy(areq->iv, ctx->backup_iv, ivsize);
+			memzero_explicit(ctx->backup_iv, ivsize);
 		} else {
 			scatterwalk_map_and_copy(areq->iv, areq->dst, areq->cryptlen - ivsize,
 						 ivsize, 0);
diff --git a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
index 0fee6f4e2d90..ba59c7a48825 100644
--- a/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
+++ b/drivers/crypto/allwinner/sun4i-ss/sun4i-ss.h
@@ -183,6 +183,7 @@ struct sun4i_tfm_ctx {
 
 struct sun4i_cipher_req_ctx {
 	u32 mode;
+	u8 backup_iv[AES_BLOCK_SIZE];
 	struct skcipher_request fallback_req;   // keep at the end
 };
 
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:36 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:36 +0000
Subject: [PATCH 3/8] crypto: sun8i-ss: handle zero sized sg
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-4-clabbe@baylibre.com>

sun8i-ss does not handle well the possible zero sized sg.

Fixes: d9b45418a917 ("crypto: sun8i-ss - support hash algorithms")
Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index 3c073eb3db03..2557bb3fe7aa 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -379,13 +379,21 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 	}
 
 	len = areq->nbytes;
-	for_each_sg(areq->src, sg, nr_sgs, i) {
+	sg = areq->src;
+	i = 0;
+	while (len > 0 && sg) {
+		if (sg_dma_len(sg) == 0) {
+			sg = sg_next(sg);
+			continue;
+		}
 		rctx->t_src[i].addr = sg_dma_address(sg);
 		todo = min(len, sg_dma_len(sg));
 		rctx->t_src[i].len = todo / 4;
 		len -= todo;
 		rctx->t_dst[i].addr = addr_res;
 		rctx->t_dst[i].len = digestsize / 4;
+		sg = sg_next(sg);
+		i++;
 	}
 	if (len > 0) {
 		dev_err(ss->dev, "remaining len %d\n", len);
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:37 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:37 +0000
Subject: [PATCH 4/8] crypto: sun8i-ss: do not allocate memory when handling
 hash requests
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-5-clabbe@baylibre.com>

Instead of allocate memory on each requests, it is easier to
pre-allocate buffers.
This made error path easier.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 10 ++++++++++
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 15 +++------------
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h      |  4 ++++
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 319fe3279a71..084261d7899c 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -474,6 +474,16 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
 	for (i = 0; i < MAXFLOW; i++) {
 		init_completion(&ss->flows[i].complete);
 
+		/* the padding could be up to two block. */
+		ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
+						GFP_KERNEL | GFP_DMA);
+		if (!ss->flows[i].pad)
+			goto error_engine;
+		ss->flows[i].result = devm_kmalloc(ss->dev, SHA256_DIGEST_SIZE,
+						   GFP_KERNEL | GFP_DMA);
+		if (!ss->flows[i].result)
+			goto error_engine;
+
 		ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true);
 		if (!ss->flows[i].engine) {
 			dev_err(ss->dev, "Cannot allocate engine\n");
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index 2557bb3fe7aa..f7a9578e87f7 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -341,18 +341,11 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 	if (digestsize == SHA224_DIGEST_SIZE)
 		digestsize = SHA256_DIGEST_SIZE;
 
-	/* the padding could be up to two block. */
-	pad = kzalloc(algt->alg.hash.halg.base.cra_blocksize * 2, GFP_KERNEL | GFP_DMA);
-	if (!pad)
-		return -ENOMEM;
+	result = ss->flows[rctx->flow].result;
+	pad = ss->flows[rctx->flow].pad;
+	memset(pad, 0, algt->alg.hash.halg.base.cra_blocksize * 2);
 	bf = (__le32 *)pad;
 
-	result = kzalloc(digestsize, GFP_KERNEL | GFP_DMA);
-	if (!result) {
-		kfree(pad);
-		return -ENOMEM;
-	}
-
 	for (i = 0; i < MAX_SG; i++) {
 		rctx->t_dst[i].addr = 0;
 		rctx->t_dst[i].len = 0;
@@ -448,8 +441,6 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 
 	memcpy(areq->result, result, algt->alg.hash.halg.digestsize);
 theend:
-	kfree(pad);
-	kfree(result);
 	crypto_finalize_hash_request(engine, breq, err);
 	return 0;
 }
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
index 28188685b910..f9f089ede934 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
@@ -121,11 +121,15 @@ struct sginfo {
  * @complete:	completion for the current task on this flow
  * @status:	set to 1 by interrupt if task is done
  * @stat_req:	number of request done by this flow
+ * @pad:	padding buffer for hash operations
+ * @result:	buffer for storing the result of hash operations
  */
 struct sun8i_ss_flow {
 	struct crypto_engine *engine;
 	struct completion complete;
 	int status;
+	void *pad;
+	void *result;
 #ifdef CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG
 	unsigned long stat_req;
 #endif
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:38 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:38 +0000
Subject: [PATCH 5/8] crypto: sun8i-ss: do not zeroize all pad
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-6-clabbe@baylibre.com>

Instead of memset all pad buffer, it is faster to only put 0 where
needed.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index f7a9578e87f7..ef3020bc9547 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -328,7 +328,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 	unsigned int len;
 	u64 fill, min_fill, byte_count;
 	void *pad, *result;
-	int j, i, todo;
+	int j, i, k, todo;
 	__be64 *bebits;
 	__le64 *lebits;
 	dma_addr_t addr_res, addr_pad;
@@ -343,7 +343,6 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 
 	result = ss->flows[rctx->flow].result;
 	pad = ss->flows[rctx->flow].pad;
-	memset(pad, 0, algt->alg.hash.halg.base.cra_blocksize * 2);
 	bf = (__le32 *)pad;
 
 	for (i = 0; i < MAX_SG; i++) {
@@ -404,7 +403,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 	if (fill < min_fill)
 		fill += 64;
 
+	k = j;
 	j += (fill - min_fill) / sizeof(u32);
+	for (; k < j; k++)
+		bf[k] = 0;
 
 	switch (algt->ss_algo_id) {
 	case SS_ID_HASH_MD5:
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:39 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:39 +0000
Subject: [PATCH 6/8] crypto: sun8i-ss: remove redundant test
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-7-clabbe@baylibre.com>

Some fallback tests were redundant with what sun8i_ss_hash_need_fallback() already do.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index ef3020bc9547..7ebd11d3ff7d 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -287,21 +287,11 @@ int sun8i_ss_hash_digest(struct ahash_request *areq)
 	struct sun8i_ss_alg_template *algt;
 	struct sun8i_ss_dev *ss;
 	struct crypto_engine *engine;
-	struct scatterlist *sg;
-	int nr_sgs, e, i;
+	int e;
 
 	if (sun8i_ss_hash_need_fallback(areq))
 		return sun8i_ss_hash_digest_fb(areq);
 
-	nr_sgs = sg_nents(areq->src);
-	if (nr_sgs > MAX_SG - 1)
-		return sun8i_ss_hash_digest_fb(areq);
-
-	for_each_sg(areq->src, sg, nr_sgs, i) {
-		if (sg->length % 4 || !IS_ALIGNED(sg->offset, sizeof(u32)))
-			return sun8i_ss_hash_digest_fb(areq);
-	}
-
 	algt = container_of(alg, struct sun8i_ss_alg_template, alg.hash);
 	ss = algt->ss;
 
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:40 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:40 +0000
Subject: [PATCH 7/8] crypto: sun8i-ss: test error before assigning
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-8-clabbe@baylibre.com>

The first thing we should do after dma_map_single() is to test the
result.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index 7ebd11d3ff7d..1aae36d541d8 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -414,15 +414,15 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 	}
 
 	addr_pad = dma_map_single(ss->dev, pad, j * 4, DMA_TO_DEVICE);
-	rctx->t_src[i].addr = addr_pad;
-	rctx->t_src[i].len = j;
-	rctx->t_dst[i].addr = addr_res;
-	rctx->t_dst[i].len = digestsize / 4;
 	if (dma_mapping_error(ss->dev, addr_pad)) {
 		dev_err(ss->dev, "DMA error on padding SG\n");
 		err = -EINVAL;
 		goto theend;
 	}
+	rctx->t_src[i].addr = addr_pad;
+	rctx->t_src[i].len = j;
+	rctx->t_dst[i].addr = addr_res;
+	rctx->t_dst[i].len = digestsize / 4;
 
 	err = sun8i_ss_run_hash_task(ss, rctx, crypto_tfm_alg_name(areq->base.tfm));
 
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:04:41 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:04:41 +0000
Subject: [PATCH 8/8] crypto: sun8i-ss: handle requests if last block is not
 modulo 64
In-Reply-To: <20220126210441.3661782-1-clabbe@baylibre.com>
References: <20220126210441.3661782-1-clabbe@baylibre.com>
Message-ID: <20220126210441.3661782-9-clabbe@baylibre.com>

The current sun8i-ss handle only requests with all SG length being
modulo 64.
But the last SG could be always handled by copying it on the pad buffer.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 .../crypto/allwinner/sun8i-ss/sun8i-ss-core.c |  2 +-
 .../crypto/allwinner/sun8i-ss/sun8i-ss-hash.c | 35 ++++++++++++++-----
 drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h  |  2 ++
 3 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
index 084261d7899c..c8c079f3b466 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c
@@ -475,7 +475,7 @@ static int allocate_flows(struct sun8i_ss_dev *ss)
 		init_completion(&ss->flows[i].complete);
 
 		/* the padding could be up to two block. */
-		ss->flows[i].pad = devm_kmalloc(ss->dev, SHA256_BLOCK_SIZE * 2,
+		ss->flows[i].pad = devm_kmalloc(ss->dev, MAX_PAD_SIZE,
 						GFP_KERNEL | GFP_DMA);
 		if (!ss->flows[i].pad)
 			goto error_engine;
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
index 1aae36d541d8..dd5e4f0fd5ab 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -13,6 +13,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
 #include <crypto/internal/hash.h>
+#include <crypto/scatterwalk.h>
 #include <crypto/sha1.h>
 #include <crypto/sha2.h>
 #include <crypto/md5.h>
@@ -261,6 +262,9 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
 
 	if (areq->nbytes == 0)
 		return true;
+	if (areq->nbytes >= MAX_PAD_SIZE - 64)
+		return true;
+
 	/* we need to reserve one SG for the padding one */
 	if (sg_nents(areq->src) > MAX_SG - 1)
 		return true;
@@ -269,10 +273,13 @@ static bool sun8i_ss_hash_need_fallback(struct ahash_request *areq)
 		/* SS can operate hash only on full block size
 		 * since SS support only MD5,sha1,sha224 and sha256, blocksize
 		 * is always 64
-		 * TODO: handle request if last SG is not len%64
-		 * but this will need to copy data on a new SG of size=64
 		 */
-		if (sg->length % 64 || !IS_ALIGNED(sg->offset, sizeof(u32)))
+		/* Only the last block could be bounced to the pad buffer */
+		if (sg->length % 64 && sg_next(sg))
+			return true;
+		if (!IS_ALIGNED(sg->offset, sizeof(u32)))
+			return true;
+		if (sg->length % 4)
 			return true;
 		sg = sg_next(sg);
 	}
@@ -360,6 +367,7 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 		goto theend;
 	}
 
+	j = 0;
 	len = areq->nbytes;
 	sg = areq->src;
 	i = 0;
@@ -368,12 +376,19 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 			sg = sg_next(sg);
 			continue;
 		}
-		rctx->t_src[i].addr = sg_dma_address(sg);
 		todo = min(len, sg_dma_len(sg));
-		rctx->t_src[i].len = todo / 4;
-		len -= todo;
-		rctx->t_dst[i].addr = addr_res;
-		rctx->t_dst[i].len = digestsize / 4;
+		/* only the last SG could be with a size not modulo64 */
+		if (todo % 64 == 0) {
+			rctx->t_src[i].addr = sg_dma_address(sg);
+			rctx->t_src[i].len = todo / 4;
+			rctx->t_dst[i].addr = addr_res;
+			rctx->t_dst[i].len = digestsize / 4;
+			len -= todo;
+		} else {
+			scatterwalk_map_and_copy(bf, sg, 0, todo, 0);
+			j += todo / 4;
+			len -= todo;
+		}
 		sg = sg_next(sg);
 		i++;
 	}
@@ -383,8 +398,10 @@ int sun8i_ss_hash_run(struct crypto_engine *engine, void *breq)
 		goto theend;
 	}
 
+	if (j > 0)
+		i--;
+
 	byte_count = areq->nbytes;
-	j = 0;
 	bf[j++] = cpu_to_le32(0x80);
 
 	fill = 64 - (byte_count % 64);
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
index f9f089ede934..8c9649bab88c 100644
--- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
+++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss.h
@@ -82,6 +82,8 @@
 #define PRNG_DATA_SIZE (160 / 8)
 #define PRNG_SEED_SIZE DIV_ROUND_UP(175, 8)
 
+#define MAX_PAD_SIZE 4096
+
 /*
  * struct ss_clock - Describe clocks used by sun8i-ss
  * @name:       Name of clock needed by this variant
-- 
2.34.1



From clabbe at baylibre.com  Wed Jan 26 13:11:28 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Wed, 26 Jan 2022 21:11:28 +0000
Subject: [PATCH] dt-bindings: net: convert net/cortina, gemini-ethernet to yaml
Message-ID: <20220126211128.3663486-1-clabbe@baylibre.com>

Converts net/cortina,gemini-ethernet.txt to yaml
This permits to detect some missing properties like interrupts

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 .../bindings/net/cortina,gemini-ethernet.txt  |  92 ------------
 .../bindings/net/cortina,gemini-ethernet.yaml | 138 ++++++++++++++++++
 2 files changed, 138 insertions(+), 92 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
 create mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml

diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
deleted file mode 100644
index 6c559981d110..000000000000
--- a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-Cortina Systems Gemini Ethernet Controller
-==========================================
-
-This ethernet controller is found in the Gemini SoC family:
-StorLink SL3512 and SL3516, also known as Cortina Systems
-CS3512 and CS3516.
-
-Required properties:
-- compatible: must be "cortina,gemini-ethernet"
-- reg: must contain the global registers and the V-bit and A-bit
-  memory areas, in total three register sets.
-- syscon: a phandle to the system controller
-- #address-cells: must be specified, must be <1>
-- #size-cells: must be specified, must be <1>
-- ranges: should be state like this giving a 1:1 address translation
-  for the subnodes
-
-The subnodes represents the two ethernet ports in this device.
-They are not independent of each other since they share resources
-in the parent node, and are thus children.
-
-Required subnodes:
-- port0: contains the resources for ethernet port 0
-- port1: contains the resources for ethernet port 1
-
-Required subnode properties:
-- compatible: must be "cortina,gemini-ethernet-port"
-- reg: must contain two register areas: the DMA/TOE memory and
-  the GMAC memory area of the port
-- interrupts: should contain the interrupt line of the port.
-  this is nominally a level interrupt active high.
-- resets: this must provide an SoC-integrated reset line for
-  the port.
-- clocks: this should contain a handle to the PCLK clock for
-  clocking the silicon in this port
-- clock-names: must be "PCLK"
-
-Optional subnode properties:
-- phy-mode: see ethernet.txt
-- phy-handle: see ethernet.txt
-
-Example:
-
-mdio-bus {
-	(...)
-	phy0: ethernet-phy at 1 {
-		reg = <1>;
-		device_type = "ethernet-phy";
-	};
-	phy1: ethernet-phy at 3 {
-		reg = <3>;
-		device_type = "ethernet-phy";
-	};
-};
-
-
-ethernet at 60000000 {
-	compatible = "cortina,gemini-ethernet";
-	reg = <0x60000000 0x4000>, /* Global registers, queue */
-	      <0x60004000 0x2000>, /* V-bit */
-	      <0x60006000 0x2000>; /* A-bit */
-	syscon = <&syscon>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges;
-
-	gmac0: ethernet-port at 0 {
-		compatible = "cortina,gemini-ethernet-port";
-		reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */
-		      <0x6000a000 0x2000>; /* Port 0 GMAC */
-		interrupt-parent = <&intcon>;
-		interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
-		resets = <&syscon GEMINI_RESET_GMAC0>;
-		clocks = <&syscon GEMINI_CLK_GATE_GMAC0>;
-		clock-names = "PCLK";
-		phy-mode = "rgmii";
-		phy-handle = <&phy0>;
-	};
-
-	gmac1: ethernet-port at 1 {
-		compatible = "cortina,gemini-ethernet-port";
-		reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */
-		      <0x6000e000 0x2000>; /* Port 1 GMAC */
-		interrupt-parent = <&intcon>;
-		interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
-		resets = <&syscon GEMINI_RESET_GMAC1>;
-		clocks = <&syscon GEMINI_CLK_GATE_GMAC1>;
-		clock-names = "PCLK";
-		phy-mode = "rgmii";
-		phy-handle = <&phy1>;
-	};
-};
diff --git a/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml
new file mode 100644
index 000000000000..294977fd32f7
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/cortina,gemini-ethernet.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cortina Systems Gemini Ethernet Controller
+
+maintainers:
+  - Linus Walleij <linus.walleij at linaro.org>
+
+description: |
+  This ethernet controller is found in the Gemini SoC family:
+  StorLink SL3512 and SL3516, also known as Cortina Systems
+  CS3512 and CS3516.
+
+properties:
+  compatible:
+    const: cortina,gemini-ethernet
+
+  reg:
+    minItems: 3
+    description: must contain the global registers and the V-bit and A-bit
+      memory areas, in total three register sets.
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+#The subnodes represents the two ethernet ports in this device.
+#They are not independent of each other since they share resources
+#in the parent node, and are thus children.
+patternProperties:
+  "^ethernet-port@[0-9]+$":
+    type: object
+    description: contains the resources for ethernet port
+    allOf:
+      - $ref: ethernet-controller.yaml#
+    properties:
+      compatible:
+        const: cortina,gemini-ethernet-port
+
+      reg:
+        minItems: 2
+        items:
+          - description: DMA/TOE memory
+          - description: GMAC memory area of the port
+
+      interrupts:
+        maxItems: 1
+        description: should contain the interrupt line of the port.
+                     this is nominally a level interrupt active high.
+
+      resets:
+        maxItems: 1
+        description: this must provide an SoC-integrated reset line for the port.
+
+      clocks:
+        maxItems: 1
+        description: this should contain a handle to the PCLK clock for
+                     clocking the silicon in this port
+
+      clock-names:
+        const: PCLK
+
+    required:
+      - reg
+      - compatible
+      - interrupts
+      - resets
+      - clocks
+      - clock-names
+
+required:
+  - compatible
+  - reg
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/cortina,gemini-clock.h>
+    #include <dt-bindings/reset/cortina,gemini-reset.h>
+    mdio0: mdio {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      phy0: ethernet-phy at 1 {
+        reg = <1>;
+        device_type = "ethernet-phy";
+      };
+      phy1: ethernet-phy at 3 {
+        reg = <3>;
+        device_type = "ethernet-phy";
+      };
+    };
+
+
+    ethernet at 60000000 {
+        compatible = "cortina,gemini-ethernet";
+        reg = <0x60000000 0x4000>, /* Global registers, queue */
+              <0x60004000 0x2000>, /* V-bit */
+              <0x60006000 0x2000>; /* A-bit */
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        gmac0: ethernet-port at 0 {
+    		compatible = "cortina,gemini-ethernet-port";
+    		reg = <0x60008000 0x2000>, /* Port 0 DMA/TOE */
+    		      <0x6000a000 0x2000>; /* Port 0 GMAC */
+    		interrupt-parent = <&intcon>;
+    		interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
+    		resets = <&syscon GEMINI_RESET_GMAC0>;
+    		clocks = <&syscon GEMINI_CLK_GATE_GMAC0>;
+    		clock-names = "PCLK";
+    		phy-mode = "rgmii";
+    		phy-handle = <&phy0>;
+    	};
+
+    	gmac1: ethernet-port at 1 {
+    		compatible = "cortina,gemini-ethernet-port";
+    		reg = <0x6000c000 0x2000>, /* Port 1 DMA/TOE */
+    		      <0x6000e000 0x2000>; /* Port 1 GMAC */
+    		interrupt-parent = <&intcon>;
+    		interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
+    		resets = <&syscon GEMINI_RESET_GMAC1>;
+    		clocks = <&syscon GEMINI_CLK_GATE_GMAC1>;
+    		clock-names = "PCLK";
+    		phy-mode = "rgmii";
+    		phy-handle = <&phy1>;
+    	};
+    };
-- 
2.34.1



From lkp at intel.com  Wed Jan 26 13:25:19 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 27 Jan 2022 05:25:19 +0800
Subject: [PATCH] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <20220126200749.12090-1-carlos.bilbao@amd.com>
References: <20220126200749.12090-1-carlos.bilbao@amd.com>
Message-ID: <202201270546.CQtmCsGw-lkp@intel.com>

Hi Carlos,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on geert-m68k/for-next]
[also build test WARNING on tip/timers/core tip/x86/core linus/master v5.17-rc1 next-20220125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Carlos-Bilbao/include-linux-Reorganize-timekeeping-and-ktime-headers/20220127-041038
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git for-next
config: m68k-allmodconfig (https://download.01.org/0day-ci/archive/20220127/202201270546.CQtmCsGw-lkp at intel.com/config)
compiler: m68k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/3c432f5cbb3c550c1cef6747c4281b65a7d9d708
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Carlos-Bilbao/include-linux-Reorganize-timekeeping-and-ktime-headers/20220127-041038
        git checkout 3c432f5cbb3c550c1cef6747c4281b65a7d9d708
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=m68k SHELL=/bin/bash arch/m68k/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> arch/m68k/kernel/time.c:67:6: warning: no previous prototype for 'read_persistent_clock64' [-Wmissing-prototypes]
      67 | void read_persistent_clock64(struct timespec64 *ts)
         |      ^~~~~~~~~~~~~~~~~~~~~~~
   arch/m68k/kernel/time.c:145:13: warning: no previous prototype for 'time_init' [-Wmissing-prototypes]
     145 | void __init time_init(void)
         |             ^~~~~~~~~


vim +/read_persistent_clock64 +67 arch/m68k/kernel/time.c

fa7f9e7fade8457 Greg Ungerer  2012-01-23  64  
065f109f2506d6b Arnd Bergmann 2018-04-23  65  #ifdef CONFIG_M68KCLASSIC
065f109f2506d6b Arnd Bergmann 2018-04-23  66  #if !IS_BUILTIN(CONFIG_RTC_DRV_GENERIC)
065f109f2506d6b Arnd Bergmann 2018-04-23 @67  void read_persistent_clock64(struct timespec64 *ts)
fa7f9e7fade8457 Greg Ungerer  2012-01-23  68  {
fa7f9e7fade8457 Greg Ungerer  2012-01-23  69  	struct rtc_time time;
b65769fc013edb7 Finn Thain    2018-04-23  70  
fa7f9e7fade8457 Greg Ungerer  2012-01-23  71  	ts->tv_sec = 0;
fa7f9e7fade8457 Greg Ungerer  2012-01-23  72  	ts->tv_nsec = 0;
fa7f9e7fade8457 Greg Ungerer  2012-01-23  73  
b65769fc013edb7 Finn Thain    2018-04-23  74  	if (!mach_hwclk)
b65769fc013edb7 Finn Thain    2018-04-23  75  		return;
b65769fc013edb7 Finn Thain    2018-04-23  76  
fa7f9e7fade8457 Greg Ungerer  2012-01-23  77  	mach_hwclk(0, &time);
fa7f9e7fade8457 Greg Ungerer  2012-01-23  78  
065f109f2506d6b Arnd Bergmann 2018-04-23  79  	ts->tv_sec = mktime64(time.tm_year + 1900, time.tm_mon + 1, time.tm_mday,
fa7f9e7fade8457 Greg Ungerer  2012-01-23  80  			      time.tm_hour, time.tm_min, time.tm_sec);
fa7f9e7fade8457 Greg Ungerer  2012-01-23  81  }
065f109f2506d6b Arnd Bergmann 2018-04-23  82  #endif
fa7f9e7fade8457 Greg Ungerer  2012-01-23  83  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From robh at kernel.org  Wed Jan 26 14:10:52 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 16:10:52 -0600
Subject: [PATCH v19 1/3] dt-bindings: input: Add bindings for Mediatek
 matrix keypad
In-Reply-To: <20220126153519.3637496-2-mkorpershoek@baylibre.com>
References: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
 <20220126153519.3637496-2-mkorpershoek@baylibre.com>
Message-ID: <1643235052.864878.1535097.nullmailer@robh.at.kernel.org>

On Wed, 26 Jan 2022 16:35:17 +0100, Mattijs Korpershoek wrote:
> From: "fengping.yu" <fengping.yu at mediatek.com>
> 
> This patch add devicetree bindings for Mediatek matrix keypad driver.
> 
> Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
> ---
>  .../input/mediatek,mt6779-keypad.yaml         | 80 +++++++++++++++++++
>  1 file changed, 80 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:
./Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml:28:13: [warning] wrong indentation: expected 14 but found 12 (indentation)
./Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml:43:8: [warning] wrong indentation: expected 6 but found 7 (indentation)

dtschema/dtc warnings/errors:

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1584526

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Wed Jan 26 14:10:52 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 16:10:52 -0600
Subject: [PATCH] dt-bindings: watchdog: brcm,
 bcm7038: add more compatible strings
In-Reply-To: <20220126132116.11070-1-zajec5@gmail.com>
References: <20220126132116.11070-1-zajec5@gmail.com>
Message-ID: <1643235052.838468.1535092.nullmailer@robh.at.kernel.org>

On Wed, 26 Jan 2022 14:21:16 +0100, Rafa?? Mi??ecki wrote:
> From: Rafa?? Mi??ecki <rafal at milecki.pl>
> 
> This hardware block is used on almost all BCM63xx family chipsets and
> BCM4908 which reuses a lot of BCM63xx parts. Add relevant compatible
> strings and also include a generic one.
> 
> The only SoC with a different block I found is BCM6838 (thus not included
> in this change).
> 
> It may be worth noting that BCM6338, BCM6345, BCM6348 and BCM63268 don't
> include "SoftRst" register but that can be handled by drivers based on
> precise compatible string.
> 
> Signed-off-by: Rafa?? Mi??ecki <rafal at milecki.pl>
> ---
>  .../bindings/watchdog/brcm,bcm7038-wdt.yaml   | 21 +++++++++++++++----
>  1 file changed, 17 insertions(+), 4 deletions(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/brcm,twd.example.dt.yaml: timer-mfd at ff800400: watchdog at 28:compatible: ['brcm,bcm7038-wdt'] is too short
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/brcm,twd.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/brcm,twd.example.dt.yaml: watchdog at 28: compatible: ['brcm,bcm7038-wdt'] is too short
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1584464

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Wed Jan 26 14:10:52 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 16:10:52 -0600
Subject: [PATCH 17/27] dt-bindings: display: rockchip: Add binding for VOP2
In-Reply-To: <20220126145549.617165-18-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-18-s.hauer@pengutronix.de>
Message-ID: <1643235052.852354.1535095.nullmailer@robh.at.kernel.org>

On Wed, 26 Jan 2022 15:55:39 +0100, Sascha Hauer wrote:
> The VOP2 is found on newer Rockchip SoCs like the rk3568 or the rk3566.
> The binding differs slightly from the existing VOP binding, so add a new
> binding file for it.
> 
> Changes since v3:
> - drop redundant _vop suffix from clock names
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  .../display/rockchip/rockchip-vop2.yaml       | 146 ++++++++++++++++++
>  1 file changed, 146 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.example.dt.yaml: vop at fe040000: clock-names:0: 'aclk' was expected
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.example.dt.yaml: vop at fe040000: clock-names:1: 'hclk' was expected
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1584511

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Wed Jan 26 14:10:52 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 16:10:52 -0600
Subject: [PATCH v4 2/4] dt-bindings: usb: dwc3-imx8mp: Add imx8mp specific
 flags
In-Reply-To: <20220126141340.234125-3-alexander.stein@ew.tq-group.com>
References: <20220126141340.234125-1-alexander.stein@ew.tq-group.com>
 <20220126141340.234125-3-alexander.stein@ew.tq-group.com>
Message-ID: <1643235052.902207.1535103.nullmailer@robh.at.kernel.org>

On Wed, 26 Jan 2022 15:13:38 +0100, Alexander Stein wrote:
> This adds bindings for features in the USB glue block. They allow
> setting polarity of PWR and OC as well as disabling port power control.
> Also permanently attached can be annotated as well.
> Additional IO address and clock are needed.
> 
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>
> ---
>  .../bindings/usb/fsl,imx8mp-dwc3.yaml         | 31 ++++++++++++++++---
>  1 file changed, 27 insertions(+), 4 deletions(-)
> 

Running 'make dtbs_check' with the schema in this patch gives the
following warnings. Consider if they are expected or the schema is
incorrect. These may not be new warnings.

Note that it is not yet a requirement to have 0 warnings for dtbs_check.
This will change in the future.

Full log is available here: https://patchwork.ozlabs.org/patch/1584490


usb at 32f10100: reg: [[854655232, 8]] is too short
	arch/arm64/boot/dts/freescale/imx8mp-evk.dt.yaml
	arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dt.yaml

usb at 32f10108: reg: [[854655240, 8]] is too short
	arch/arm64/boot/dts/freescale/imx8mp-evk.dt.yaml
	arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dt.yaml



From zajec5 at gmail.com  Wed Jan 26 14:20:34 2022
From: zajec5 at gmail.com (=?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?=)
Date: Wed, 26 Jan 2022 23:20:34 +0100
Subject: [PATCH V2] dt-bindings: watchdog: brcm,
 bcm7038: add more compatible strings
In-Reply-To: <20220126132116.11070-1-zajec5@gmail.com>
References: <20220126132116.11070-1-zajec5@gmail.com>
Message-ID: <20220126222034.16889-1-zajec5@gmail.com>

From: Rafa? Mi?ecki <rafal at milecki.pl>

This hardware block is used on almost all BCM63xx family chipsets and
BCM4908 which reuses a lot of BCM63xx parts. Add relevant compatible
strings and also include a generic one.

The only SoC with a different block I found is BCM6838 (thus not included
in this change).

It may be worth noting that BCM6338, BCM6345, BCM6348 and BCM63268 don't
include "SoftRst" register but that can be handled by drivers based on
precise compatible string.

Signed-off-by: Rafa? Mi?ecki <rafal at milecki.pl>
---
V2: Sort enum entries & update brcm,twd.yaml
---
 .../devicetree/bindings/mfd/brcm,twd.yaml     |  2 +-
 .../bindings/watchdog/brcm,bcm7038-wdt.yaml   | 21 +++++++++++++++----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/brcm,twd.yaml b/Documentation/devicetree/bindings/mfd/brcm,twd.yaml
index 634526f790b8..3f5db1990aba 100644
--- a/Documentation/devicetree/bindings/mfd/brcm,twd.yaml
+++ b/Documentation/devicetree/bindings/mfd/brcm,twd.yaml
@@ -55,7 +55,7 @@ examples:
         #size-cells = <1>;
 
         watchdog at 28 {
-            compatible = "brcm,bcm7038-wdt";
+            compatible = "brcm,bcm4908-wdt", "brcm,bcm63xx-wdt";
             reg = <0x28 0x8>;
         };
     };
diff --git a/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
index a926809352b8..4d848442913c 100644
--- a/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
+++ b/Documentation/devicetree/bindings/watchdog/brcm,bcm7038-wdt.yaml
@@ -16,9 +16,22 @@ maintainers:
 
 properties:
   compatible:
-    enum:
-      - brcm,bcm6345-wdt
-      - brcm,bcm7038-wdt
+    items:
+      - enum:
+          - brcm,bcm4908-wdt
+          - brcm,bcm6338-wdt
+          - brcm,bcm6345-wdt
+          - brcm,bcm6348-wdt
+          - brcm,bcm6848-wdt
+          - brcm,bcm6858-wdt
+          - brcm,bcm7038-wdt
+          - brcm,bcm60333-wdt
+          - brcm,bcm63138-wdt
+          - brcm,bcm63148-wdt
+          - brcm,bcm63268-wdt
+          - brcm,bcm63381-wdt
+          - brcm,bcm68360-wdt
+      - const: brcm,bcm63xx-wdt
 
   reg:
     maxItems: 1
@@ -37,7 +50,7 @@ required:
 examples:
   - |
     watchdog at f040a7e8 {
-      compatible = "brcm,bcm7038-wdt";
+      compatible = "brcm,bcm7038-wdt", "brcm,bcm63xx-wdt";
       reg = <0xf040a7e8 0x16>;
       clocks = <&upg_fixed>;
     };
-- 
2.31.1



From robh+dt at kernel.org  Wed Jan 26 14:44:01 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 16:44:01 -0600
Subject: [PATCH v19 1/3] dt-bindings: input: Add bindings for Mediatek
 matrix keypad
In-Reply-To: <20220126153519.3637496-2-mkorpershoek@baylibre.com>
References: <20220126153519.3637496-1-mkorpershoek@baylibre.com>
 <20220126153519.3637496-2-mkorpershoek@baylibre.com>
Message-ID: <CAL_JsqJfHhucrfj5rXeNqFJLSj=7Oy7AcPCscd+_pRNhz46btQ@mail.gmail.com>

On Wed, Jan 26, 2022 at 9:35 AM Mattijs Korpershoek
<mkorpershoek at baylibre.com> wrote:
>
> From: "fengping.yu" <fengping.yu at mediatek.com>
>
> This patch add devicetree bindings for Mediatek matrix keypad driver.
>
> Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
> Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
> Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
> ---
>  .../input/mediatek,mt6779-keypad.yaml         | 80 +++++++++++++++++++
>  1 file changed, 80 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
>
> diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
> new file mode 100644
> index 000000000000..2c76029224a0
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
> @@ -0,0 +1,80 @@
> +# SPDX-License-Identifier: GPL-2.0

dual license new bindings

> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/input/mediatek,mt6779-keypad.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek's Keypad Controller device tree bindings
> +
> +maintainers:
> +  - Fengping Yu <fengping.yu at mediatek.com>
> +
> +allOf:
> +  - $ref: "/schemas/input/matrix-keymap.yaml#"
> +
> +description: |
> +  Mediatek's Keypad controller is used to interface a SoC with a matrix-type
> +  keypad device. The keypad controller supports multiple row and column lines.
> +  A key can be placed at each intersection of a unique row and a unique column.
> +  The keypad controller can sense a key-press and key-release and report the
> +  event using a interrupt to the cpu.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - const: mediatek,mt6779-keypad
> +      - items:
> +          - enum:
> +            - mediatek,mt6873-keypad
> +          - const: mediatek,mt6779-keypad
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +
> +  clock-names:
> +    description: Names of the clocks listed in clocks property in the same order

Drop generic descriptions.

> +    items:
> +       - const: kpd
> +
> +  wakeup-source:
> +    description: use any event on keypad as wakeup event
> +    type: boolean
> +
> +  mediatek,debounce-us:

We already a somewhat common property: debounce-delay-ms

> +    description: |
> +      Debounce interval in microseconds, if not specified, the default
> +      value is 16000
> +    maximum: 256000

default: 16000


> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/input/input.h>
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +
> +    soc {
> +        #address-cells = <2>;
> +        #size-cells = <2>;
> +
> +        kp at 10010000 {

Use a standard node name: keyboard at ... or keys at ...

> +          compatible = "mediatek,mt6779-keypad";
> +          reg = <0 0x10010000 0 0x1000>;
> +          interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_FALLING>;
> +          clocks = <&clk26m>;
> +          clock-names = "kpd";
> +        };
> +    };
> --
> 2.32.0
>


From lkp at intel.com  Wed Jan 26 14:47:21 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 27 Jan 2022 06:47:21 +0800
Subject: [PATCH] include: linux: Reorganize timekeeping and ktime headers
In-Reply-To: <20220126200749.12090-1-carlos.bilbao@amd.com>
References: <20220126200749.12090-1-carlos.bilbao@amd.com>
Message-ID: <202201270622.w96GBqWO-lkp@intel.com>

Hi Carlos,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on geert-m68k/for-next]
[also build test WARNING on tip/timers/core tip/x86/core linus/master v5.17-rc1 next-20220125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Carlos-Bilbao/include-linux-Reorganize-timekeeping-and-ktime-headers/20220127-041038
base:   https://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k.git for-next
config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20220127/202201270622.w96GBqWO-lkp at intel.com/config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/3c432f5cbb3c550c1cef6747c4281b65a7d9d708
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Carlos-Bilbao/include-linux-Reorganize-timekeeping-and-ktime-headers/20220127-041038
        git checkout 3c432f5cbb3c550c1cef6747c4281b65a7d9d708
        # save the config file to linux build tree
        mkdir build_dir
        make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> arch/um/kernel/time.c:763:6: warning: no previous prototype for 'read_persistent_clock64' [-Wmissing-prototypes]
     763 | void read_persistent_clock64(struct timespec64 *ts)
         |      ^~~~~~~~~~~~~~~~~~~~~~~
   arch/um/kernel/time.c:778:13: warning: no previous prototype for 'time_init' [-Wmissing-prototypes]
     778 | void __init time_init(void)
         |             ^~~~~~~~~


vim +/read_persistent_clock64 +763 arch/um/kernel/time.c

aceb343464a136e arch/um/kernel/time_kern.c Jeff Dike       2006-07-10  762  
288fb3d5683f508 arch/um/kernel/time.c      Arnd Bergmann   2017-11-02 @763  void read_persistent_clock64(struct timespec64 *ts)
9f31f5774961a73 arch/um/kernel/time.c      John Stultz     2010-07-13  764  {
065038706f77a56 arch/um/kernel/time.c      Johannes Berg   2019-05-27  765  	long long nsecs;
065038706f77a56 arch/um/kernel/time.c      Johannes Berg   2019-05-27  766  
7f3414226b58b0d arch/um/kernel/time.c      Johannes Berg   2021-01-15  767  	time_travel_set_start();
7f3414226b58b0d arch/um/kernel/time.c      Johannes Berg   2021-01-15  768  
2701c1bd91dda81 arch/um/kernel/time.c      Johannes Berg   2020-12-02  769  	if (time_travel_mode != TT_MODE_OFF)
065038706f77a56 arch/um/kernel/time.c      Johannes Berg   2019-05-27  770  		nsecs = time_travel_start + time_travel_time;
065038706f77a56 arch/um/kernel/time.c      Johannes Berg   2019-05-27  771  	else
065038706f77a56 arch/um/kernel/time.c      Johannes Berg   2019-05-27  772  		nsecs = os_persistent_clock_emulation();
b29230769e3482b arch/um/kernel/time.c      Thomas Gleixner 2010-08-03  773  
288fb3d5683f508 arch/um/kernel/time.c      Arnd Bergmann   2017-11-02  774  	set_normalized_timespec64(ts, nsecs / NSEC_PER_SEC,
9f31f5774961a73 arch/um/kernel/time.c      John Stultz     2010-07-13  775  				  nsecs % NSEC_PER_SEC);
9f31f5774961a73 arch/um/kernel/time.c      John Stultz     2010-07-13  776  }
9f31f5774961a73 arch/um/kernel/time.c      John Stultz     2010-07-13  777  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From john.stultz at linaro.org  Wed Jan 26 14:51:52 2022
From: john.stultz at linaro.org (John Stultz)
Date: Wed, 26 Jan 2022 14:51:52 -0800
Subject: [PATCH] lib/crypto: blake2s: avoid indirect calls to compression
 function for Clang CFI
In-Reply-To: <20220119135450.564115-1-Jason@zx2c4.com>
References: <CAHmME9qVMomgb53rABKsucCoEhwsk+=KzDdEcGKtecOXuahTZw@mail.gmail.com>
 <20220119135450.564115-1-Jason@zx2c4.com>
Message-ID: <CANcMJZABKTdwU8455pLfBjMjgsDO7BNjNWTvwx0sP+3TcJw_XA@mail.gmail.com>

On Fri, Jan 21, 2022 at 11:17 AM Jason A. Donenfeld <Jason at zx2c4.com> wrote:
>
> blake2s_compress_generic is weakly aliased to blake2s_generic. The
> current harness for function selection uses a function pointer, which is
> ordinarily inlined and resolved at compile time. But when Clang's CFI is
> enabled, CFI still triggers when making an indirect call via a weak
> symbol. This seems like a bug in Clang's CFI, as though it's bucketing
> weak symbols and strong symbols differently. It also only seems to
> trigger when "full LTO" mode is used, rather than "thin LTO".
>
> [    0.000000][    T0] Kernel panic - not syncing: CFI failure (target: blake2s_compress_generic+0x0/0x1444)
> [    0.000000][    T0] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.16.0-mainline-06981-g076c855b846e #1
> [    0.000000][    T0] Hardware name: MT6873 (DT)
> [    0.000000][    T0] Call trace:
> [    0.000000][    T0]  dump_backtrace+0xfc/0x1dc
> [    0.000000][    T0]  dump_stack_lvl+0xa8/0x11c
> [    0.000000][    T0]  panic+0x194/0x464
> [    0.000000][    T0]  __cfi_check_fail+0x54/0x58
> [    0.000000][    T0]  __cfi_slowpath_diag+0x354/0x4b0
> [    0.000000][    T0]  blake2s_update+0x14c/0x178
> [    0.000000][    T0]  _extract_entropy+0xf4/0x29c
> [    0.000000][    T0]  crng_initialize_primary+0x24/0x94
> [    0.000000][    T0]  rand_initialize+0x2c/0x6c
> [    0.000000][    T0]  start_kernel+0x2f8/0x65c
> [    0.000000][    T0]  __primary_switched+0xc4/0x7be4
> [    0.000000][    T0] Rebooting in 5 seconds..

YongQin also reported hitting this issue(also, only in the LTO=full
case) on the db845c dev board. Sami pointed me to this patch and I
just wanted to confirm it gets things booting again.

Reported-by: YongQin Liu <yongqin.liu at linaro.org>
Tested-by: John Stultz <john.stultz at linaro.org>

Thanks so much for the quick analysis and fix!
-john


From ebiggers at kernel.org  Wed Jan 26 14:54:27 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 14:54:27 -0800
Subject: [PATCH v2] lib/crypto: blake2s: avoid indirect calls to
 compression function for Clang CFI
In-Reply-To: <CAHmME9oQuKLo2D_OGMy-8PS-u=a-ERvP+1L7RvpjJ2_xBaM5eQ@mail.gmail.com>
References: <20220119135450.564115-1-Jason@zx2c4.com>
 <20220124192849.14755-1-Jason@zx2c4.com>
 <Ye+bam3aSIjz8n9E@sol.localdomain>
 <CAHmME9oQuKLo2D_OGMy-8PS-u=a-ERvP+1L7RvpjJ2_xBaM5eQ@mail.gmail.com>
Message-ID: <YfHRIw9aFwCYaXh7@sol.localdomain>

On Tue, Jan 25, 2022 at 01:23:34PM +0100, Jason A. Donenfeld wrote:
> On 1/25/22, Eric Biggers <ebiggers at kernel.org> wrote:
> > On Mon, Jan 24, 2022 at 08:28:49PM +0100, Jason A. Donenfeld wrote:
> >> blake2s_compress_generic is weakly aliased by blake2s_generic. The
> >
> > Don't you mean "weakly aliased by blake2s_compress"?
> 
> Grrrr. Thanks.
> 
> >> Changes v1->v2:
> >> - Wrapped columns at 80 for Eric.
> >
> > It is the recommended coding style, so not just for me :-)
> 
> I was under the impression this increased to 100 mid-2020 or so, and
> checkpatch.pl now makes noise at that width instead.

>From Documentation/process/coding-style.rst:

"The preferred limit on the length of a single line is 80 columns.

 Statements longer than 80 columns should be broken into sensible chunks,
 unless exceeding 80 columns significantly increases readability and does
 not hide information."

It's not as strict as it used to be, but checkpatch seems to be overly-lenient.
I always run it with --max-line-length=80.

- Eric


From robh at kernel.org  Wed Jan 26 15:11:46 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 17:11:46 -0600
Subject: [PATCH] dt-bindings: arm, cci-400: Add interrupt controller to example
Message-ID: <20220126231146.1632819-1-robh@kernel.org>

In order to parse the 'interrupts' an interrupt provider node is needed.
That is because the example is a full example (starting with root node)
and on those we don't guess and generate a fake provider.

Signed-off-by: Rob Herring <robh at kernel.org>
---
 Documentation/devicetree/bindings/arm/arm,cci-400.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/arm,cci-400.yaml b/Documentation/devicetree/bindings/arm/arm,cci-400.yaml
index f8530a50863a..1706134b75a3 100644
--- a/Documentation/devicetree/bindings/arm/arm,cci-400.yaml
+++ b/Documentation/devicetree/bindings/arm/arm,cci-400.yaml
@@ -119,6 +119,11 @@ examples:
           arm,hbi = <0x249>;
           interrupt-parent = <&gic>;
 
+          gic: interrupt-controller {
+              interrupt-controller;
+              #interrupt-cells = <3>;
+          };
+
           /*
            * This CCI node corresponds to a CCI component whose control
            * registers sits at address 0x000000002c090000.
-- 
2.32.0



From robh at kernel.org  Wed Jan 26 15:14:27 2022
From: robh at kernel.org (Rob Herring)
Date: Wed, 26 Jan 2022 17:14:27 -0600
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
Message-ID: <20220126231427.1638089-1-robh@kernel.org>

'sound-dai' is a common property, but has duplicate type definitions.
Create a new common definition to define the type and then update all
the other occurrences to just define how many entries there are just
like other phandle+arg properties.

The constraints on the number of entries is based on the examples and
could be wrong.

Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
Signed-off-by: Rob Herring <robh at kernel.org>
---
Please ack, this depends on commit abf0fee97313 ("dt-bindings: Improve
phandle-array schemas") in my tree.
---
 .../bindings/sound/amlogic,gx-sound-card.yaml |  4 ++--
 .../bindings/sound/google,sc7180-trogdor.yaml |  6 ++++--
 .../bindings/sound/imx-audio-card.yaml        |  7 +++++--
 .../bindings/sound/qcom,sm8250.yaml           | 10 +++++++---
 .../bindings/sound/samsung,aries-wm8994.yaml  |  5 +----
 .../bindings/sound/samsung,midas-audio.yaml   |  2 --
 .../bindings/sound/samsung,odroid.yaml        |  9 +++------
 .../devicetree/bindings/sound/sound-dai.yaml  | 20 +++++++++++++++++++
 8 files changed, 42 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml

diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
index 2e35aeaa8781..8b5be4b92f35 100644
--- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
+++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
@@ -57,7 +57,7 @@ patternProperties:
           rate
 
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
         description: phandle of the CPU DAI
 
     patternProperties:
@@ -71,7 +71,7 @@ patternProperties:
 
         properties:
           sound-dai:
-            $ref: /schemas/types.yaml#/definitions/phandle-array
+            maxItems: 1
             description: phandle of the codec DAI
 
         required:
diff --git a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
index 837e3faa63a9..233caa0ade87 100644
--- a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
+++ b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
@@ -62,13 +62,15 @@ patternProperties:
         description: Holds subnode which indicates cpu dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            maxItems: 1
 
       codec:
         description: Holds subnode which indicates codec dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            maxItems: 1
 
     required:
       - link-name
diff --git a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
index d1816dd061cf..bb3a435722c7 100644
--- a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
+++ b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
@@ -59,13 +59,16 @@ patternProperties:
         description: Holds subnode which indicates cpu dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            maxItems: 1
 
       codec:
         description: Holds subnode which indicates codec dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            minItems: 1
+            maxItems: 2
 
       fsl,mclk-equal-bclk:
         description: Indicates mclk can be equal to bclk, especially for sai interface
diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
index 4bfda04b4608..4ecd4080bb96 100644
--- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
@@ -69,19 +69,23 @@ patternProperties:
         description: Holds subnode which indicates cpu dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            maxItems: 1
 
       platform:
         description: Holds subnode which indicates platform dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            maxItems: 1
 
       codec:
         description: Holds subnode which indicates codec dai.
         type: object
         properties:
-          sound-dai: true
+          sound-dai:
+            minItems: 1
+            maxItems: 4
 
     required:
       - link-name
diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
index eb487ed3ca3b..4ffa275b3c49 100644
--- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
+++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
@@ -27,9 +27,6 @@ properties:
       sound-dai:
         minItems: 2
         maxItems: 2
-        items:
-          maxItems: 1
-        $ref: /schemas/types.yaml#/definitions/phandle-array
         description: |
           phandles to the I2S controller and bluetooth codec,
           in that order
@@ -38,7 +35,7 @@ properties:
     type: object
     properties:
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
+        maxItems: 1
         description: phandle to the WM8994 CODEC
 
   samsung,audio-routing:
diff --git a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
index 095775c598fa..ec50bcb4af5f 100644
--- a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
+++ b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
@@ -21,7 +21,6 @@ properties:
     type: object
     properties:
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
         maxItems: 1
         description: phandle to the I2S controller
     required:
@@ -31,7 +30,6 @@ properties:
     type: object
     properties:
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
         maxItems: 1
         description: phandle to the WM1811 CODEC
     required:
diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
index e8122bc87362..db2513f3e168 100644
--- a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
+++ b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
@@ -37,18 +37,15 @@ properties:
     type: object
     properties:
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
         description: phandles to the I2S controllers
 
   codec:
     type: object
     properties:
       sound-dai:
-        $ref: /schemas/types.yaml#/definitions/phandle-array
-        description: |
-          List of phandles to the CODEC nodes,
-          first entry must be corresponding to the MAX98090 CODEC and
-          the second entry must be the phandle of the HDMI IP block node.
+        items:
+          - description: phandle of the MAX98090 CODEC
+          - description: phandle of the HDMI IP block node
 
   samsung,audio-routing:
     $ref: /schemas/types.yaml#/definitions/non-unique-string-array
diff --git a/Documentation/devicetree/bindings/sound/sound-dai.yaml b/Documentation/devicetree/bindings/sound/sound-dai.yaml
new file mode 100644
index 000000000000..61c6f7abc4e7
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/sound-dai.yaml
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/sound-dai.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Digital Audio Interface consumer Device Tree Bindings
+
+maintainers:
+  - Rob Herring <robh at kernel.org>
+
+select: true
+
+properties:
+  sound-dai:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: A phandle plus args to digital audio interface provider(s)
+
+additionalProperties: true
+...
-- 
2.32.0



From theleks at ko-hh.de  Wed Jan 26 15:43:25 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 00:43:25 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
Message-ID: <20220126234325.GA7363@odroid-VirtualBox>

The interrupt pin of the external ethernet phy is used, instead of the
enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
the gpio_ao bank.
Using open drain prevents reboot issues.

This causes phy interrupt problems at system startup.
[   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
[   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
[   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
[   76.649635] Call trace:
[   76.649638]  dump_backtrace+0x0/0x1c8
[   76.649658]  show_stack+0x14/0x60
[   76.649667]  dump_stack_lvl+0x64/0x7c
[   76.649676]  dump_stack+0x14/0x2c
[   76.649683]  __report_bad_irq+0x38/0xe8
[   76.649695]  note_interrupt+0x220/0x3a0
[   76.649704]  handle_irq_event_percpu+0x58/0x88
[   76.649713]  handle_irq_event+0x44/0xd8
[   76.649721]  handle_fasteoi_irq+0xa8/0x130
[   76.649730]  generic_handle_domain_irq+0x38/0x58
[   76.649738]  gic_handle_irq+0x9c/0xb8
[   76.649747]  call_on_irq_stack+0x28/0x38
[   76.649755]  do_interrupt_handler+0x7c/0x80
[   76.649763]  el1_interrupt+0x34/0x80
[   76.649772]  el1h_64_irq_handler+0x14/0x20
[   76.649781]  el1h_64_irq+0x74/0x78
[   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
[   76.649796]  irq_thread_fn+0x5c/0x98
[   76.649804]  irq_thread+0x13c/0x260
[   76.649812]  kthread+0x144/0x178
[   76.649822]  ret_from_fork+0x10/0x20
[   76.649830] handlers:
[   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
[   76.661256] Disabling IRQ #36

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 0bd1e98a0eef..ddb1b345397f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From andre.przywara at arm.com  Wed Jan 26 15:57:26 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Wed, 26 Jan 2022 23:57:26 +0000
Subject: [PATCH] ARM: dts: suniv: Add MMC and clock macros.
In-Reply-To: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
References: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
Message-ID: <20220126235726.03abdab4@slackpad.fritz.box>

On Mon, 24 Jan 2022 20:13:52 -0500
Jesse Taube <mr.bossman075 at gmail.com> wrote:

Hi Jesse,

I understand that get_maintainers.pl suggested this CC: list,  but you
should add sunxi people and linux-arm kernel ML. Doing that now.

> Include clock and reset macros and replace magic numbers.
> Add MMC node.

This patch itself does not do much, does it? You would at least need to
enable that in the board dts.
And this should be multiple patches:
1) replace numbers with macros (part of this patch)
2) Add the MMC compatible string combo to the the bindings doc
3) Add the *two* MMC nodes and at least the pinctrl node for MMC0 to the
SoC .dtsi (partly in this patch)
4) Enable the MMC and the card detect pin in the Nano board .dts

I checked that the macros names match the numbers they replace, so
you can add my R-b: on that patch 1 (if you follow my suggestion).
The MMC node also seems to look sane.

> 
> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>

It is not evident why Mesih's S-o-b: is in here? The patch seems to be
authored and sent by you? Either you make him the author if that is his
patch originally, or you put him just as Cc: or in Suggested-by:, maybe.

Cheers,
Andre

> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> ---
>  arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 +++++++++++++++++++++++-----
>  1 file changed, 34 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> index 6100d3b75f61..32872bb29917 100644
> --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
> +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> @@ -4,6 +4,9 @@
>   * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
>   */
>  
> +#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
> +#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
> +
>  / {
>  	#address-cells = <1>;
>  	#size-cells = <1>;
> @@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
>  			compatible = "allwinner,suniv-f1c100s-pinctrl";
>  			reg = <0x01c20800 0x400>;
>  			interrupts = <38>, <39>, <40>;
> -			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
> +			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
>  			clock-names = "apb", "hosc", "losc";
>  			gpio-controller;
>  			interrupt-controller;
> @@ -93,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
>  				pins = "PE0", "PE1";
>  				function = "uart0";
>  			};
> +
> +			mmc0_pins: mmc0-pins {
> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
> +				function = "mmc0";
> +			};
>  		};
>  
>  		timer at 1c20c00 {
> @@ -108,14 +116,33 @@ wdt: watchdog at 1c20ca0 {
>  			reg = <0x01c20ca0 0x20>;
>  		};
>  
> +		mmc0: mmc at 1c0f000 {
> +			compatible = "allwinner,suniv-f1c100s-mmc",
> +				     "allwinner,sun7i-a20-mmc";
> +			reg = <0x01c0f000 0x1000>;
> +			clocks = <&ccu CLK_BUS_MMC0>,
> +				 <&ccu CLK_MMC0>,
> +				 <&ccu CLK_MMC0_OUTPUT>,
> +				 <&ccu CLK_MMC0_SAMPLE>;
> +			clock-names = "ahb", "mmc", "output", "sample";
> +			resets = <&ccu RST_BUS_MMC0>;
> +			reset-names = "ahb";
> +			interrupts = <23>;
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&mmc0_pins>;
> +			status = "disabled";
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +		};
> +
>  		uart0: serial at 1c25000 {
>  			compatible = "snps,dw-apb-uart";
>  			reg = <0x01c25000 0x400>;
>  			interrupts = <1>;
>  			reg-shift = <2>;
>  			reg-io-width = <4>;
> -			clocks = <&ccu 38>;
> -			resets = <&ccu 24>;
> +			clocks = <&ccu CLK_BUS_UART0>;
> +			resets = <&ccu RST_BUS_UART0>;
>  			status = "disabled";
>  		};
>  
> @@ -125,8 +152,8 @@ uart1: serial at 1c25400 {
>  			interrupts = <2>;
>  			reg-shift = <2>;
>  			reg-io-width = <4>;
> -			clocks = <&ccu 39>;
> -			resets = <&ccu 25>;
> +			clocks = <&ccu CLK_BUS_UART1>;
> +			resets = <&ccu RST_BUS_UART1>;
>  			status = "disabled";
>  		};
>  
> @@ -136,8 +163,8 @@ uart2: serial at 1c25800 {
>  			interrupts = <3>;
>  			reg-shift = <2>;
>  			reg-io-width = <4>;
> -			clocks = <&ccu 40>;
> -			resets = <&ccu 26>;
> +			clocks = <&ccu CLK_BUS_UART2>;
> +			resets = <&ccu RST_BUS_UART2>;
>  			status = "disabled";
>  		};
>  	};



From mr.bossman075 at gmail.com  Wed Jan 26 16:12:05 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Wed, 26 Jan 2022 19:12:05 -0500
Subject: [PATCH] ARM: dts: suniv: Add MMC and clock macros.
In-Reply-To: <20220126235726.03abdab4@slackpad.fritz.box>
References: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
 <20220126235726.03abdab4@slackpad.fritz.box>
Message-ID: <d69233d8-4e3d-56db-d4d3-1b39fe84ee30@gmail.com>



On 1/26/22 18:57, Andre Przywara wrote:
> On Mon, 24 Jan 2022 20:13:52 -0500
> Jesse Taube <mr.bossman075 at gmail.com> wrote:
> 
> Hi Jesse,
> 
> I understand that get_maintainers.pl suggested this CC: list,  but you
> should add sunxi people and linux-arm kernel ML. Doing that now.
Uh yeah that makes sense in hind sight.
>> Include clock and reset macros and replace magic numbers.
>> Add MMC node.
> 
> This patch itself does not do much, does it? You would at least need to
> enable that in the board dts.
True it doesn't do much just so that its in both u-boot and linux.
> And this should be multiple patches:
> 1) replace numbers with macros (part of this patch)
> 2) Add the MMC compatible string combo to the the bindings doc
> 3) Add the *two* MMC nodes and at least the pinctrl node for MMC0 to the
> SoC .dtsi (partly in this patch)
> 4) Enable the MMC and the card detect pin in the Nano board .dts
> 
> I checked that the macros names match the numbers they replace, so
> you can add my R-b: on that patch 1 (if you follow my suggestion).
> The MMC node also seems to look sane.
That seems okay.
>>
>> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
> 
> It is not evident why Mesih's S-o-b: is in here? The patch seems to be
> authored and sent by you? Either you make him the author if that is his
> patch originally, or you put him just as Cc: or in Suggested-by:, maybe.
I did write the patch after I wrote it I was looking at his github and 
he had almost the same patch.
> Cheers,
> Andre
> 
>> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
>> ---
>>   arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 +++++++++++++++++++++++-----
>>   1 file changed, 34 insertions(+), 7 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
>> index 6100d3b75f61..32872bb29917 100644
>> --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
>> +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
>> @@ -4,6 +4,9 @@
>>    * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
>>    */
>>   
>> +#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
>> +#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
>> +
>>   / {
>>   	#address-cells = <1>;
>>   	#size-cells = <1>;
>> @@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
>>   			compatible = "allwinner,suniv-f1c100s-pinctrl";
>>   			reg = <0x01c20800 0x400>;
>>   			interrupts = <38>, <39>, <40>;
>> -			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
>> +			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
>>   			clock-names = "apb", "hosc", "losc";
>>   			gpio-controller;
>>   			interrupt-controller;
>> @@ -93,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
>>   				pins = "PE0", "PE1";
>>   				function = "uart0";
>>   			};
>> +
>> +			mmc0_pins: mmc0-pins {
>> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
>> +				function = "mmc0";
>> +			};
>>   		};
>>   
>>   		timer at 1c20c00 {
>> @@ -108,14 +116,33 @@ wdt: watchdog at 1c20ca0 {
>>   			reg = <0x01c20ca0 0x20>;
>>   		};
>>   
>> +		mmc0: mmc at 1c0f000 {
>> +			compatible = "allwinner,suniv-f1c100s-mmc",
>> +				     "allwinner,sun7i-a20-mmc";
>> +			reg = <0x01c0f000 0x1000>;
>> +			clocks = <&ccu CLK_BUS_MMC0>,
>> +				 <&ccu CLK_MMC0>,
>> +				 <&ccu CLK_MMC0_OUTPUT>,
>> +				 <&ccu CLK_MMC0_SAMPLE>;
>> +			clock-names = "ahb", "mmc", "output", "sample";
>> +			resets = <&ccu RST_BUS_MMC0>;
>> +			reset-names = "ahb";
>> +			interrupts = <23>;
>> +			pinctrl-names = "default";
>> +			pinctrl-0 = <&mmc0_pins>;
>> +			status = "disabled";
>> +			#address-cells = <1>;
>> +			#size-cells = <0>;
>> +		};
>> +
>>   		uart0: serial at 1c25000 {
>>   			compatible = "snps,dw-apb-uart";
>>   			reg = <0x01c25000 0x400>;
>>   			interrupts = <1>;
>>   			reg-shift = <2>;
>>   			reg-io-width = <4>;
>> -			clocks = <&ccu 38>;
>> -			resets = <&ccu 24>;
>> +			clocks = <&ccu CLK_BUS_UART0>;
>> +			resets = <&ccu RST_BUS_UART0>;
>>   			status = "disabled";
>>   		};
>>   
>> @@ -125,8 +152,8 @@ uart1: serial at 1c25400 {
>>   			interrupts = <2>;
>>   			reg-shift = <2>;
>>   			reg-io-width = <4>;
>> -			clocks = <&ccu 39>;
>> -			resets = <&ccu 25>;
>> +			clocks = <&ccu CLK_BUS_UART1>;
>> +			resets = <&ccu RST_BUS_UART1>;
>>   			status = "disabled";
>>   		};
>>   
>> @@ -136,8 +163,8 @@ uart2: serial at 1c25800 {
>>   			interrupts = <3>;
>>   			reg-shift = <2>;
>>   			reg-io-width = <4>;
>> -			clocks = <&ccu 40>;
>> -			resets = <&ccu 26>;
>> +			clocks = <&ccu CLK_BUS_UART2>;
>> +			resets = <&ccu RST_BUS_UART2>;
>>   			status = "disabled";
>>   		};
>>   	};
> 


From linus.walleij at linaro.org  Wed Jan 26 16:36:43 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:43 +0100
Subject: [PATCH 00/13] IXP4xx spring cleaning
Message-ID: <20220127003656.330161-1-linus.walleij@linaro.org>

This cleans out the remaining board files from IXP4xx and
makes it an exclusive device tree subarchitecture without any
special weirdness in arch/arm/mach-ixp4xx.

The biggest noticeable change is the removal of the old PCI
driver and along with that the removal of the special DMA
coherency code and defines and the DMA bouncing.

I tried to convert the IXP4xx to multiplatform on top of
this but it didn't work because IXP4xx wants to be big
endian and multiplatform config creates a problem like
this:

../arch/arm/kernel/head.S: Assembler messages:
../arch/arm/kernel/head.S:94: Error: selected processor does not support `setend be' in ARM mode

I think this is because MULTI_V5 turns on CPUs that cannot
do big endian, and IXP4xx turn on big endian. (It crashes if
I try to boot in little endian mode, sorry. It really wants
to run big endian.)

But before fixing multiplatform we can fix all of this!

The networking patches are dependencies so I am requesting
ACKs from the network maintainers on these.

Linus Walleij (12):
  ARM: ixp4xx: Delete the Goramo MLR boardfile
  ARM: ixp4xx: Delete old PCI driver
  ARM: ixp4xx: Drop stale Kconfig entry
  ARM: ixp4xx: Drop UDC info setting function
  soc: ixp4xx: Add features from regmap helper
  soc: ixp4xx-npe: Access syscon regs using regmap
  net: ixp4xx_eth: Drop platform data support
  net: ixp4xx_hss: Check features using syscon
  ARM: ixp4xx: Remove feature bit accessors
  ARM: ixp4xx: Drop custom DMA coherency and bouncing
  ARM: ixp4xx: Drop all common code
  ARM: ixp4xx: Convert to SPARSE_IRQ and P2V

Zoltan HERPAI (1):
  ARM: ixp4xx: Delete Gateway 7001 boardfiles

 arch/arm/Kconfig                              |  11 +-
 arch/arm/mach-ixp4xx/Kconfig                  |  57 --
 arch/arm/mach-ixp4xx/Makefile                 |  19 +-
 arch/arm/mach-ixp4xx/common-pci.c             | 451 ---------------
 arch/arm/mach-ixp4xx/common.c                 | 448 --------------
 arch/arm/mach-ixp4xx/gateway7001-pci.c        |  61 --
 arch/arm/mach-ixp4xx/gateway7001-setup.c      | 113 ----
 arch/arm/mach-ixp4xx/goramo_mlr.c             | 532 -----------------
 arch/arm/mach-ixp4xx/include/mach/hardware.h  |  32 -
 arch/arm/mach-ixp4xx/include/mach/io.h        | 545 ------------------
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    | 303 ----------
 arch/arm/mach-ixp4xx/include/mach/platform.h  | 102 ----
 arch/arm/mach-ixp4xx/include/mach/udc.h       |   8 -
 .../arm/mach-ixp4xx/include/mach/uncompress.h |   4 +-
 arch/arm/mach-ixp4xx/irqs.h                   |  64 --
 drivers/crypto/ixp4xx_crypto.c                |   1 -
 drivers/net/ethernet/xscale/Kconfig           |   4 +-
 drivers/net/ethernet/xscale/ixp4xx_eth.c      |  69 +--
 drivers/net/ethernet/xscale/ptp_ixp46x.c      |   1 -
 drivers/net/wan/Kconfig                       |   3 +-
 drivers/net/wan/ixp4xx_hss.c                  |  39 +-
 drivers/soc/ixp4xx/Kconfig                    |   1 +
 drivers/soc/ixp4xx/ixp4xx-npe.c               |  34 +-
 include/linux/platform_data/eth_ixp4xx.h      |  21 -
 include/linux/platform_data/wan_ixp4xx_hss.h  |  17 -
 include/linux/soc/ixp4xx/cpu.h                |  26 +-
 include/linux/soc/ixp4xx/npe.h                |   2 +
 kernel/dma/mapping.c                          |   2 -
 28 files changed, 99 insertions(+), 2871 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/common-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/common.c
 delete mode 100644 arch/arm/mach-ixp4xx/gateway7001-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/gateway7001-setup.c
 delete mode 100644 arch/arm/mach-ixp4xx/goramo_mlr.c
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/hardware.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/io.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/platform.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/udc.h
 delete mode 100644 arch/arm/mach-ixp4xx/irqs.h
 delete mode 100644 include/linux/platform_data/eth_ixp4xx.h
 delete mode 100644 include/linux/platform_data/wan_ixp4xx_hss.h

-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:44 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:44 +0100
Subject: [PATCH 01/13] ARM: ixp4xx: Delete Gateway 7001 boardfiles
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-2-linus.walleij@linaro.org>

From: Zoltan HERPAI <wigyori at uid0.hu>

This board is replaced with the corresponding device tree.

Cc: Imre Kaloz <kaloz at openwrt.org>
Signed-off-by: Zoltan HERPAI <wigyori at uid0.hu>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-ixp4xx/Kconfig             |   8 --
 arch/arm/mach-ixp4xx/Makefile            |   3 -
 arch/arm/mach-ixp4xx/gateway7001-pci.c   |  61 ------------
 arch/arm/mach-ixp4xx/gateway7001-setup.c | 113 -----------------------
 4 files changed, 185 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/gateway7001-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/gateway7001-setup.c

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 4c787b4be62b..e6b23c3ce50c 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,14 +17,6 @@ config MACH_IXP4XX_OF
 	help
 	  Say 'Y' here to support Device Tree-based IXP4xx platforms.
 
-config MACH_GATEWAY7001
-	bool "Gateway 7001"
-	depends on IXP4XX_PCI_LEGACY
-	help
-	  Say 'Y' here if you want your kernel to support Gateway's
-	  7001 Access Point. For more information on this platform,
-	  see http://openwrt.org
-
 config MACH_GORAMO_MLR
 	bool "GORAMO Multi Link Router"
 	depends on IXP4XX_PCI_LEGACY
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index b241094c9649..0a92f8c40e1c 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -9,11 +9,8 @@ obj-pci-n	:=
 # Device tree platform
 obj-pci-$(CONFIG_MACH_IXP4XX_OF)	+= ixp4xx-of.o
 
-obj-pci-$(CONFIG_MACH_GATEWAY7001)	+= gateway7001-pci.o
-
 obj-y	+= common.o
 
-obj-$(CONFIG_MACH_GATEWAY7001)	+= gateway7001-setup.o
 obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o
 
 obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
deleted file mode 100644
index 3c3ee9dad6d8..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-pci.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arch/mach-ixp4xx/gateway7001-pci.c
- *
- * PCI setup routines for Gateway 7001
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz at openwrt.org>
- *
- * based on coyote-pci.c:
- *	Copyright (C) 2002 Jungo Software Technologies.
- *	Copyright (C) 2003 MontaVista Softwrae, Inc.
- *
- * Maintainer: Imre Kaloz <kaloz at openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-
-#include <asm/mach/pci.h>
-
-#include "irqs.h"
-
-void __init gateway7001_pci_preinit(void)
-{
-	irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
-	irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
-
-	ixp4xx_pci_preinit();
-}
-
-static int __init gateway7001_map_irq(const struct pci_dev *dev, u8 slot,
-	u8 pin)
-{
-	if (slot == 1)
-		return IRQ_IXP4XX_GPIO11;
-	else if (slot == 2)
-		return IRQ_IXP4XX_GPIO10;
-	else return -1;
-}
-
-struct hw_pci gateway7001_pci __initdata = {
-	.nr_controllers = 1,
-	.ops		= &ixp4xx_ops,
-	.preinit =        gateway7001_pci_preinit,
-	.setup =          ixp4xx_setup,
-	.map_irq =        gateway7001_map_irq,
-};
-
-int __init gateway7001_pci_init(void)
-{
-	if (machine_is_gateway7001())
-		pci_common_init(&gateway7001_pci);
-	return 0;
-}
-
-subsys_initcall(gateway7001_pci_init);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
deleted file mode 100644
index 678e7dfff0e5..000000000000
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ /dev/null
@@ -1,113 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/arm/mach-ixp4xx/gateway7001-setup.c
- *
- * Board setup for the Gateway 7001 board
- *
- * Copyright (C) 2007 Imre Kaloz <kaloz at openwrt.org>
- *
- * based on coyote-setup.c:
- *      Copyright (C) 2003-2005 MontaVista Software, Inc.
- *
- * Author: Imre Kaloz <Kaloz at openwrt.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-
-#include "irqs.h"
-
-static struct flash_platform_data gateway7001_flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-};
-
-static struct resource gateway7001_flash_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gateway7001_flash = {
-	.name		= "IXP4XX-Flash",
-	.id		= 0,
-	.dev		= {
-		.platform_data = &gateway7001_flash_data,
-	},
-	.num_resources	= 1,
-	.resource	= &gateway7001_flash_resource,
-};
-
-static struct resource gateway7001_uart_resource = {
-	.start	= IXP4XX_UART2_BASE_PHYS,
-	.end	= IXP4XX_UART2_BASE_PHYS + 0x0fff,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct plat_serial8250_port gateway7001_uart_data[] = {
-	{
-		.mapbase	= IXP4XX_UART2_BASE_PHYS,
-		.membase	= (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
-		.irq		= IRQ_IXP4XX_UART2,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= IXP4XX_UART_XTAL,
-	},
-	{ },
-};
-
-static struct platform_device gateway7001_uart = {
-	.name		= "serial8250",
-	.id		= PLAT8250_DEV_PLATFORM,
-	.dev			= {
-		.platform_data	= gateway7001_uart_data,
-	},
-	.num_resources	= 1,
-	.resource	= &gateway7001_uart_resource,
-};
-
-static struct platform_device *gateway7001_devices[] __initdata = {
-	&gateway7001_flash,
-	&gateway7001_uart
-};
-
-static void __init gateway7001_init(void)
-{
-	ixp4xx_sys_init();
-
-	gateway7001_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
-	gateway7001_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1;
-
-	*IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE;
-	*IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0;
-
-	platform_add_devices(gateway7001_devices, ARRAY_SIZE(gateway7001_devices));
-}
-
-#ifdef CONFIG_MACH_GATEWAY7001
-MACHINE_START(GATEWAY7001, "Gateway 7001 AP")
-	/* Maintainer: Imre Kaloz <kaloz at openwrt.org> */
-	.map_io		= ixp4xx_map_io,
-	.init_early	= ixp4xx_init_early,
-	.init_irq	= ixp4xx_init_irq,
-	.init_time	= ixp4xx_timer_init,
-	.atag_offset	= 0x100,
-	.init_machine	= gateway7001_init,
-#if defined(CONFIG_PCI)
-	.dma_zone_size	= SZ_64M,
-#endif
-	.restart	= ixp4xx_restart,
-MACHINE_END
-#endif
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:45 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:45 +0100
Subject: [PATCH 02/13] ARM: ixp4xx: Delete the Goramo MLR boardfile
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-3-linus.walleij@linaro.org>

This board is replaced with the corresponding device tree.

Also delete dangling platform data file only used by this
boardfile and nothing else.

Cc: Krzysztof Ha?asa <khalasa at piap.pl>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
ChangeLog v1->v2:
- New patch now that we have all we need in the device tree
  we can drop the boardfile.
---
 arch/arm/mach-ixp4xx/Kconfig                 |   7 -
 arch/arm/mach-ixp4xx/Makefile                |   2 -
 arch/arm/mach-ixp4xx/goramo_mlr.c            | 532 -------------------
 include/linux/platform_data/wan_ixp4xx_hss.h |  17 -
 4 files changed, 558 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/goramo_mlr.c
 delete mode 100644 include/linux/platform_data/wan_ixp4xx_hss.h

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index e6b23c3ce50c..0fac12cb31a6 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,13 +17,6 @@ config MACH_IXP4XX_OF
 	help
 	  Say 'Y' here to support Device Tree-based IXP4xx platforms.
 
-config MACH_GORAMO_MLR
-	bool "GORAMO Multi Link Router"
-	depends on IXP4XX_PCI_LEGACY
-	help
-	  Say 'Y' here if you want your kernel to support GORAMO
-	  MultiLink router.
-
 config ARCH_PRPMC1100
 	bool "PrPMC1100"
 	help
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 0a92f8c40e1c..83719704a626 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -11,6 +11,4 @@ obj-pci-$(CONFIG_MACH_IXP4XX_OF)	+= ixp4xx-of.o
 
 obj-y	+= common.o
 
-obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o
-
 obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
deleted file mode 100644
index 07b50dfcc489..000000000000
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ /dev/null
@@ -1,532 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Goramo MultiLink router platform code
- * Copyright (C) 2006-2009 Krzysztof Halasa <khc at pm.waw.pl>
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/hdlc.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/platform_data/wan_ixp4xx_hss.h>
-#include <linux/serial_8250.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-#include <asm/mach/pci.h>
-#include <asm/system_info.h>
-
-#include "irqs.h"
-
-#define SLOT_ETHA		0x0B	/* IDSEL = AD21 */
-#define SLOT_ETHB		0x0C	/* IDSEL = AD20 */
-#define SLOT_MPCI		0x0D	/* IDSEL = AD19 */
-#define SLOT_NEC		0x0E	/* IDSEL = AD18 */
-
-/* GPIO lines */
-#define GPIO_SCL		0
-#define GPIO_SDA		1
-#define GPIO_STR		2
-#define GPIO_IRQ_NEC		3
-#define GPIO_IRQ_ETHA		4
-#define GPIO_IRQ_ETHB		5
-#define GPIO_HSS0_DCD_N		6
-#define GPIO_HSS1_DCD_N		7
-#define GPIO_UART0_DCD		8
-#define GPIO_UART1_DCD		9
-#define GPIO_HSS0_CTS_N		10
-#define GPIO_HSS1_CTS_N		11
-#define GPIO_IRQ_MPCI		12
-#define GPIO_HSS1_RTS_N		13
-#define GPIO_HSS0_RTS_N		14
-/* GPIO15 is not connected */
-
-/* Control outputs from 74HC4094 */
-#define CONTROL_HSS0_CLK_INT	0
-#define CONTROL_HSS1_CLK_INT	1
-#define CONTROL_HSS0_DTR_N	2
-#define CONTROL_HSS1_DTR_N	3
-#define CONTROL_EXT		4
-#define CONTROL_AUTO_RESET	5
-#define CONTROL_PCI_RESET_N	6
-#define CONTROL_EEPROM_WC_N	7
-
-/* offsets from start of flash ROM = 0x50000000 */
-#define CFG_ETH0_ADDRESS	0x40 /* 6 bytes */
-#define CFG_ETH1_ADDRESS	0x46 /* 6 bytes */
-#define CFG_REV			0x4C /* u32 */
-#define CFG_SDRAM_SIZE		0x50 /* u32 */
-#define CFG_SDRAM_CONF		0x54 /* u32 */
-#define CFG_SDRAM_MODE		0x58 /* u32 */
-#define CFG_SDRAM_REFRESH	0x5C /* u32 */
-
-#define CFG_HW_BITS		0x60 /* u32 */
-#define  CFG_HW_USB_PORTS	0x00000007 /* 0 = no NEC chip, 1-5 = ports # */
-#define  CFG_HW_HAS_PCI_SLOT	0x00000008
-#define  CFG_HW_HAS_ETH0	0x00000010
-#define  CFG_HW_HAS_ETH1	0x00000020
-#define  CFG_HW_HAS_HSS0	0x00000040
-#define  CFG_HW_HAS_HSS1	0x00000080
-#define  CFG_HW_HAS_UART0	0x00000100
-#define  CFG_HW_HAS_UART1	0x00000200
-#define  CFG_HW_HAS_EEPROM	0x00000400
-
-#define FLASH_CMD_READ_ARRAY	0xFF
-#define FLASH_CMD_READ_ID	0x90
-#define FLASH_SER_OFF		0x102 /* 0x81 in 16-bit mode */
-
-static u32 hw_bits = 0xFFFFFFFD;    /* assume all hardware present */;
-static u8 control_value;
-
-/*
- * FIXME: this is reimplementing I2C bit-bangining. Move this
- * over to using driver/i2c/busses/i2c-gpio.c like all other boards
- * and register proper I2C device(s) on the bus for this. (See
- * other IXP4xx boards for examples.)
- */
-static void set_scl(u8 value)
-{
-	gpio_set_value(GPIO_SCL, !!value);
-	udelay(3);
-}
-
-static void set_sda(u8 value)
-{
-	gpio_set_value(GPIO_SDA, !!value);
-	udelay(3);
-}
-
-static void set_str(u8 value)
-{
-	gpio_set_value(GPIO_STR, !!value);
-	udelay(3);
-}
-
-static inline void set_control(int line, int value)
-{
-	if (value)
-		control_value |=  (1 << line);
-	else
-		control_value &= ~(1 << line);
-}
-
-
-static void output_control(void)
-{
-	int i;
-
-	gpio_direction_output(GPIO_SCL, 1);
-	gpio_direction_output(GPIO_SDA, 1);
-
-	for (i = 0; i < 8; i++) {
-		set_scl(0);
-		set_sda(control_value & (0x80 >> i)); /* MSB first */
-		set_scl(1);	/* active edge */
-	}
-
-	set_str(1);
-	set_str(0);
-
-	set_scl(0);
-	set_sda(1);		/* Be ready for START */
-	set_scl(1);
-}
-
-
-static void (*set_carrier_cb_tab[2])(void *pdev, int carrier);
-
-static int hss_set_clock(int port, unsigned int clock_type)
-{
-	int ctrl_int = port ? CONTROL_HSS1_CLK_INT : CONTROL_HSS0_CLK_INT;
-
-	switch (clock_type) {
-	case CLOCK_DEFAULT:
-	case CLOCK_EXT:
-		set_control(ctrl_int, 0);
-		output_control();
-		return CLOCK_EXT;
-
-	case CLOCK_INT:
-		set_control(ctrl_int, 1);
-		output_control();
-		return CLOCK_INT;
-
-	default:
-		return -EINVAL;
-	}
-}
-
-static irqreturn_t hss_dcd_irq(int irq, void *pdev)
-{
-	int port = (irq == IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N));
-	int i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
-	set_carrier_cb_tab[port](pdev, !i);
-	return IRQ_HANDLED;
-}
-
-
-static int hss_open(int port, void *pdev,
-		    void (*set_carrier_cb)(void *pdev, int carrier))
-{
-	int i, irq;
-
-	if (!port)
-		irq = IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N);
-	else
-		irq = IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N);
-
-	i = gpio_get_value(port ? GPIO_HSS1_DCD_N : GPIO_HSS0_DCD_N);
-	set_carrier_cb(pdev, !i);
-
-	set_carrier_cb_tab[!!port] = set_carrier_cb;
-
-	if ((i = request_irq(irq, hss_dcd_irq, 0, "IXP4xx HSS", pdev)) != 0) {
-		printk(KERN_ERR "ixp4xx_hss: failed to request IRQ%i (%i)\n",
-		       irq, i);
-		return i;
-	}
-
-	set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 0);
-	output_control();
-	gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 0);
-	return 0;
-}
-
-static void hss_close(int port, void *pdev)
-{
-	free_irq(port ? IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N) :
-		 IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), pdev);
-	set_carrier_cb_tab[!!port] = NULL; /* catch bugs */
-
-	set_control(port ? CONTROL_HSS1_DTR_N : CONTROL_HSS0_DTR_N, 1);
-	output_control();
-	gpio_set_value(port ? GPIO_HSS1_RTS_N : GPIO_HSS0_RTS_N, 1);
-}
-
-
-/* Flash memory */
-static struct flash_platform_data flash_data = {
-	.map_name	= "cfi_probe",
-	.width		= 2,
-};
-
-static struct resource flash_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device device_flash = {
-	.name		= "IXP4XX-Flash",
-	.id		= 0,
-	.dev		= { .platform_data = &flash_data },
-	.num_resources	= 1,
-	.resource	= &flash_resource,
-};
-
-/* IXP425 2 UART ports */
-static struct resource uart_resources[] = {
-	{
-		.start		= IXP4XX_UART1_BASE_PHYS,
-		.end		= IXP4XX_UART1_BASE_PHYS + 0x0fff,
-		.flags		= IORESOURCE_MEM,
-	},
-	{
-		.start		= IXP4XX_UART2_BASE_PHYS,
-		.end		= IXP4XX_UART2_BASE_PHYS + 0x0fff,
-		.flags		= IORESOURCE_MEM,
-	}
-};
-
-static struct plat_serial8250_port uart_data[] = {
-	{
-		.mapbase	= IXP4XX_UART1_BASE_PHYS,
-		.membase	= (char __iomem *)IXP4XX_UART1_BASE_VIRT +
-			REG_OFFSET,
-		.irq		= IRQ_IXP4XX_UART1,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= IXP4XX_UART_XTAL,
-	},
-	{
-		.mapbase	= IXP4XX_UART2_BASE_PHYS,
-		.membase	= (char __iomem *)IXP4XX_UART2_BASE_VIRT +
-			REG_OFFSET,
-		.irq		= IRQ_IXP4XX_UART2,
-		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= IXP4XX_UART_XTAL,
-	},
-	{ },
-};
-
-static struct platform_device device_uarts = {
-	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM,
-	.dev.platform_data	= uart_data,
-	.num_resources		= 2,
-	.resource		= uart_resources,
-};
-
-
-/* Built-in 10/100 Ethernet MAC interfaces */
-static struct resource eth_npeb_resources[] = {
-	{
-		.start		= IXP4XX_EthB_BASE_PHYS,
-		.end		= IXP4XX_EthB_BASE_PHYS + 0x0fff,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct resource eth_npec_resources[] = {
-	{
-		.start		= IXP4XX_EthC_BASE_PHYS,
-		.end		= IXP4XX_EthC_BASE_PHYS + 0x0fff,
-		.flags		= IORESOURCE_MEM,
-	},
-};
-
-static struct eth_plat_info eth_plat[] = {
-	{
-		.phy		= 0,
-		.rxq		= 3,
-		.txreadyq	= 32,
-	}, {
-		.phy		= 1,
-		.rxq		= 4,
-		.txreadyq	= 33,
-	}
-};
-
-static struct platform_device device_eth_tab[] = {
-	{
-		.name			= "ixp4xx_eth",
-		.id			= IXP4XX_ETH_NPEB,
-		.dev.platform_data	= eth_plat,
-		.num_resources		= ARRAY_SIZE(eth_npeb_resources),
-		.resource		= eth_npeb_resources,
-	}, {
-		.name			= "ixp4xx_eth",
-		.id			= IXP4XX_ETH_NPEC,
-		.dev.platform_data	= eth_plat + 1,
-		.num_resources		= ARRAY_SIZE(eth_npec_resources),
-		.resource		= eth_npec_resources,
-	}
-};
-
-
-/* IXP425 2 synchronous serial ports */
-static struct hss_plat_info hss_plat[] = {
-	{
-		.set_clock	= hss_set_clock,
-		.open		= hss_open,
-		.close		= hss_close,
-		.txreadyq	= 34,
-	}, {
-		.set_clock	= hss_set_clock,
-		.open		= hss_open,
-		.close		= hss_close,
-		.txreadyq	= 35,
-	}
-};
-
-static struct platform_device device_hss_tab[] = {
-	{
-		.name			= "ixp4xx_hss",
-		.id			= 0,
-		.dev.platform_data	= hss_plat,
-	}, {
-		.name			= "ixp4xx_hss",
-		.id			= 1,
-		.dev.platform_data	= hss_plat + 1,
-	}
-};
-
-
-static struct platform_device *device_tab[7] __initdata = {
-	&device_flash,		/* index 0 */
-};
-
-static inline u8 __init flash_readb(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
-	return __raw_readb(flash + addr);
-#else
-	return __raw_readb(flash + (addr ^ 3));
-#endif
-}
-
-static inline u16 __init flash_readw(u8 __iomem *flash, u32 addr)
-{
-#ifdef __ARMEB__
-	return __raw_readw(flash + addr);
-#else
-	return __raw_readw(flash + (addr ^ 2));
-#endif
-}
-
-static void __init gmlr_init(void)
-{
-	u8 __iomem *flash;
-	int i, devices = 1; /* flash */
-
-	ixp4xx_sys_init();
-
-	if ((flash = ioremap(IXP4XX_EXP_BUS_BASE_PHYS, 0x80)) == NULL)
-		printk(KERN_ERR "goramo-mlr: unable to access system"
-		       " configuration data\n");
-	else {
-		system_rev = __raw_readl(flash + CFG_REV);
-		hw_bits = __raw_readl(flash + CFG_HW_BITS);
-
-		for (i = 0; i < ETH_ALEN; i++) {
-			eth_plat[0].hwaddr[i] =
-				flash_readb(flash, CFG_ETH0_ADDRESS + i);
-			eth_plat[1].hwaddr[i] =
-				flash_readb(flash, CFG_ETH1_ADDRESS + i);
-		}
-
-		__raw_writew(FLASH_CMD_READ_ID, flash);
-		system_serial_high = flash_readw(flash, FLASH_SER_OFF);
-		system_serial_high <<= 16;
-		system_serial_high |= flash_readw(flash, FLASH_SER_OFF + 2);
-		system_serial_low = flash_readw(flash, FLASH_SER_OFF + 4);
-		system_serial_low <<= 16;
-		system_serial_low |= flash_readw(flash, FLASH_SER_OFF + 6);
-		__raw_writew(FLASH_CMD_READ_ARRAY, flash);
-
-		iounmap(flash);
-	}
-
-	switch (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1)) {
-	case CFG_HW_HAS_UART0:
-		memset(&uart_data[1], 0, sizeof(uart_data[1]));
-		device_uarts.num_resources = 1;
-		break;
-
-	case CFG_HW_HAS_UART1:
-		device_uarts.dev.platform_data = &uart_data[1];
-		device_uarts.resource = &uart_resources[1];
-		device_uarts.num_resources = 1;
-		break;
-	}
-	if (hw_bits & (CFG_HW_HAS_UART0 | CFG_HW_HAS_UART1))
-		device_tab[devices++] = &device_uarts; /* max index 1 */
-
-	if (hw_bits & CFG_HW_HAS_ETH0)
-		device_tab[devices++] = &device_eth_tab[0]; /* max index 2 */
-	if (hw_bits & CFG_HW_HAS_ETH1)
-		device_tab[devices++] = &device_eth_tab[1]; /* max index 3 */
-
-	if (hw_bits & CFG_HW_HAS_HSS0)
-		device_tab[devices++] = &device_hss_tab[0]; /* max index 4 */
-	if (hw_bits & CFG_HW_HAS_HSS1)
-		device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
-
-	hss_plat[0].timer_freq = ixp4xx_timer_freq;
-	hss_plat[1].timer_freq = ixp4xx_timer_freq;
-
-	gpio_request(GPIO_SCL, "SCL/clock");
-	gpio_request(GPIO_SDA, "SDA/data");
-	gpio_request(GPIO_STR, "strobe");
-	gpio_request(GPIO_HSS0_RTS_N, "HSS0 RTS");
-	gpio_request(GPIO_HSS1_RTS_N, "HSS1 RTS");
-	gpio_request(GPIO_HSS0_DCD_N, "HSS0 DCD");
-	gpio_request(GPIO_HSS1_DCD_N, "HSS1 DCD");
-
-	gpio_direction_output(GPIO_SCL, 1);
-	gpio_direction_output(GPIO_SDA, 1);
-	gpio_direction_output(GPIO_STR, 0);
-	gpio_direction_output(GPIO_HSS0_RTS_N, 1);
-	gpio_direction_output(GPIO_HSS1_RTS_N, 1);
-	gpio_direction_input(GPIO_HSS0_DCD_N);
-	gpio_direction_input(GPIO_HSS1_DCD_N);
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
-
-	set_control(CONTROL_HSS0_DTR_N, 1);
-	set_control(CONTROL_HSS1_DTR_N, 1);
-	set_control(CONTROL_EEPROM_WC_N, 1);
-	set_control(CONTROL_PCI_RESET_N, 1);
-	output_control();
-
-	msleep(1);	      /* Wait for PCI devices to initialize */
-
-	flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
-	flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
-
-	platform_add_devices(device_tab, devices);
-}
-
-
-#ifdef CONFIG_PCI
-static void __init gmlr_pci_preinit(void)
-{
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
-	irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
-	ixp4xx_pci_preinit();
-}
-
-static void __init gmlr_pci_postinit(void)
-{
-	if ((hw_bits & CFG_HW_USB_PORTS) >= 2 &&
-	    (hw_bits & CFG_HW_USB_PORTS) < 5) {
-		/* need to adjust number of USB ports on NEC chip */
-		u32 value, addr = BIT(32 - SLOT_NEC) | 0xE0;
-		if (!ixp4xx_pci_read(addr, NP_CMD_CONFIGREAD, &value)) {
-			value &= ~7;
-			value |= (hw_bits & CFG_HW_USB_PORTS);
-			ixp4xx_pci_write(addr, NP_CMD_CONFIGWRITE, value);
-		}
-	}
-}
-
-static int __init gmlr_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	switch(slot) {
-	case SLOT_ETHA:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA);
-	case SLOT_ETHB:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB);
-	case SLOT_NEC:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC);
-	default:	return IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI);
-	}
-}
-
-static struct hw_pci gmlr_hw_pci __initdata = {
-	.nr_controllers = 1,
-	.ops		= &ixp4xx_ops,
-	.preinit	= gmlr_pci_preinit,
-	.postinit	= gmlr_pci_postinit,
-	.setup		= ixp4xx_setup,
-	.map_irq	= gmlr_map_irq,
-};
-
-static int __init gmlr_pci_init(void)
-{
-	if (machine_is_goramo_mlr() &&
-	    (hw_bits & (CFG_HW_USB_PORTS | CFG_HW_HAS_PCI_SLOT)))
-		pci_common_init(&gmlr_hw_pci);
-	return 0;
-}
-
-subsys_initcall(gmlr_pci_init);
-#endif /* CONFIG_PCI */
-
-
-MACHINE_START(GORAMO_MLR, "MultiLink")
-	/* Maintainer: Krzysztof Halasa */
-	.map_io		= ixp4xx_map_io,
-	.init_early	= ixp4xx_init_early,
-	.init_irq	= ixp4xx_init_irq,
-	.init_time	= ixp4xx_timer_init,
-	.atag_offset	= 0x100,
-	.init_machine	= gmlr_init,
-#if defined(CONFIG_PCI)
-	.dma_zone_size	= SZ_64M,
-#endif
-	.restart	= ixp4xx_restart,
-MACHINE_END
diff --git a/include/linux/platform_data/wan_ixp4xx_hss.h b/include/linux/platform_data/wan_ixp4xx_hss.h
deleted file mode 100644
index d525a0feb9e1..000000000000
--- a/include/linux/platform_data/wan_ixp4xx_hss.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __PLATFORM_DATA_WAN_IXP4XX_HSS_H
-#define __PLATFORM_DATA_WAN_IXP4XX_HSS_H
-
-#include <linux/types.h>
-
-/* Information about built-in HSS (synchronous serial) interfaces */
-struct hss_plat_info {
-	int (*set_clock)(int port, unsigned int clock_type);
-	int (*open)(int port, void *pdev,
-		    void (*set_carrier_cb)(void *pdev, int carrier));
-	void (*close)(int port, void *pdev);
-	u8 txreadyq;
-	u32 timer_freq;
-};
-
-#endif
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:47 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:47 +0100
Subject: [PATCH 04/13] ARM: ixp4xx: Drop stale Kconfig entry
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-5-linus.walleij@linaro.org>

The Kconfig entry for the Motorola PrPMC1100 was added to the
kernel in the very first git import for v2.6.12-rc2 in 2005.
But it was never used for anything since it was not accompanied
by any boardfile.

It is easy to support with a device tree if someone needs it,
delete this stray Kconfig.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-ixp4xx/Kconfig | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 495cbfd2358d..f41ba3f42fc8 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,13 +17,6 @@ config MACH_IXP4XX_OF
 	help
 	  Say 'Y' here to support Device Tree-based IXP4xx platforms.
 
-config ARCH_PRPMC1100
-	bool "PrPMC1100"
-	help
-	  Say 'Y' here if you want your kernel to support the Motorola
-	  PrPCM1100 Processor Mezanine Module. For more information on
-	  this platform, see <file:Documentation/arm/ixp4xx.rst>.
-
 endmenu
 
 endif
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:48 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:48 +0100
Subject: [PATCH 05/13] ARM: ixp4xx: Drop UDC info setting function
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-6-linus.walleij@linaro.org>

The IXP4xx has a callback to "set UDC info" for the USB but
nothing in the kernel is using it. Delete it.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-ixp4xx/common.c           | 11 -----------
 arch/arm/mach-ixp4xx/include/mach/udc.h |  8 --------
 2 files changed, 19 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/udc.h

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 1116bd2df687..5192cf621f5b 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -31,7 +31,6 @@
 #include <linux/irqchip/irq-ixp4xx.h>
 #include <linux/platform_data/timer-ixp4xx.h>
 #include <linux/dma-map-ops.h>
-#include <mach/udc.h>
 #include <mach/hardware.h>
 #include <linux/uaccess.h>
 #include <asm/page.h>
@@ -113,13 +112,6 @@ void __init ixp4xx_timer_init(void)
 				  IXP4XX_TIMER_FREQ);
 }
 
-static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
-
-void __init ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info)
-{
-	memcpy(&ixp4xx_udc_info, info, sizeof *info);
-}
-
 static struct resource ixp4xx_udc_resources[] = {
 	[0] = {
 		.start  = 0xc800b000,
@@ -160,9 +152,6 @@ static struct platform_device ixp4xx_udc_device = {
 	.id             = -1,
 	.num_resources  = 2,
 	.resource       = ixp4xx_udc_resources,
-	.dev            = {
-		.platform_data = &ixp4xx_udc_info,
-	},
 };
 
 static struct resource ixp4xx_npe_resources[] = {
diff --git a/arch/arm/mach-ixp4xx/include/mach/udc.h b/arch/arm/mach-ixp4xx/include/mach/udc.h
deleted file mode 100644
index 7bd8b96c8843..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/udc.h
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/udc.h
- *
- */
-#include <linux/platform_data/pxa2xx_udc.h>
-
-extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
-
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:46 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:46 +0100
Subject: [PATCH 03/13] ARM: ixp4xx: Delete old PCI driver
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-4-linus.walleij@linaro.org>

We are just using the new PCI driver in the proper PCI host
drivers folder: drivers/pci/controller/pci-ixp4xx.c.

The new driver does not support indirect PCI but it has
turned out noone is using this. If the feature is desired
we have ways to implement it, suggested by John Linville.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig                             |   2 -
 arch/arm/mach-ixp4xx/Kconfig                 |  35 --
 arch/arm/mach-ixp4xx/Makefile                |  14 +-
 arch/arm/mach-ixp4xx/common-pci.c            | 451 ---------------
 arch/arm/mach-ixp4xx/common.c                |  28 -
 arch/arm/mach-ixp4xx/include/mach/hardware.h |   6 -
 arch/arm/mach-ixp4xx/include/mach/io.h       | 545 -------------------
 arch/arm/mach-ixp4xx/include/mach/platform.h |   4 -
 8 files changed, 1 insertion(+), 1084 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/common-pci.c
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/io.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fabe39169b12..3a95203236d2 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -391,8 +391,6 @@ config ARCH_IXP4XX
 	select HAVE_PCI
 	select IXP4XX_IRQ
 	select IXP4XX_TIMER
-	# With the new PCI driver this is not needed
-	select NEED_MACH_IO_H if IXP4XX_PCI_LEGACY
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	help
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 0fac12cb31a6..495cbfd2358d 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -24,41 +24,6 @@ config ARCH_PRPMC1100
 	  PrPCM1100 Processor Mezanine Module. For more information on
 	  this platform, see <file:Documentation/arm/ixp4xx.rst>.
 
-comment "IXP4xx Options"
-
-config IXP4XX_PCI_LEGACY
-	bool "IXP4xx legacy PCI driver support"
-	depends on PCI
-	help
-	  Selects legacy PCI driver.
-	  Not recommended for new development.
-
-config IXP4XX_INDIRECT_PCI
-	bool "Use indirect PCI memory access"
-	depends on IXP4XX_PCI_LEGACY
-	help
-          IXP4xx provides two methods of accessing PCI memory space:
-
-          1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
-             To access PCI via this space, we simply ioremap() the BAR
-             into the kernel and we can use the standard read[bwl]/write[bwl]
-             macros. This is the preferred method due to speed but it
-             limits the system to just 64MB of PCI memory. This can be
-             problematic if using video cards and other memory-heavy devices.
-
-	  2) If > 64MB of memory space is required, the IXP4xx can be
-	     configured to use indirect registers to access the whole PCI
-	     memory space. This currently allows for up to 1 GB (0x10000000
-	     to 0x4FFFFFFF) of memory on the bus. The disadvantage of this
-	     is that every PCI access requires three local register accesses
-	     plus a spinlock, but in some cases the performance hit is
-	     acceptable. In addition, you cannot mmap() PCI devices in this
-	     case due to the indirect nature of the PCI window.
-
-	  By default, the direct method is used. Choose this option if you
-	  need to use the indirect method instead. If you don't know
-	  what you need, leave this option unselected.
-
 endmenu
 
 endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 83719704a626..4ebe35227bf6 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -1,14 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-obj-pci-y	:=
-obj-pci-n	:=
-
-# Device tree platform
-obj-pci-$(CONFIG_MACH_IXP4XX_OF)	+= ixp4xx-of.o
-
-obj-y	+= common.o
-
-obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o
+obj-y	+= ixp4xx-of.o common.o
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
deleted file mode 100644
index 893c19c254e3..000000000000
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ /dev/null
@@ -1,451 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ixp4xx/common-pci.c 
- *
- * IXP4XX PCI routines for all platforms
- *
- * Maintainer: Deepak Saxena <dsaxena at plexity.net>
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 Greg Ungerer <gerg at snapgear.com>
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <asm/dma-mapping.h>
-
-#include <asm/cputype.h>
-#include <asm/irq.h>
-#include <linux/sizes.h>
-#include <asm/mach/pci.h>
-#include <mach/hardware.h>
-
-
-/*
- * IXP4xx PCI read function is dependent on whether we are 
- * running A0 or B0 (AppleGate) silicon.
- */
-int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-
-/*
- * Base address for PCI register region
- */
-unsigned long ixp4xx_pci_reg_base = 0;
-
-/*
- * PCI cfg an I/O routines are done by programming a 
- * command/byte enable register, and then read/writing
- * the data from a data register. We need to ensure
- * these transactions are atomic or we will end up
- * with corrupt data on the bus or in a driver.
- */
-static DEFINE_RAW_SPINLOCK(ixp4xx_pci_lock);
-
-/*
- * Read from PCI config space
- */
-static void crp_read(u32 ad_cbe, u32 *data)
-{
-	unsigned long flags;
-	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-	*PCI_CRP_AD_CBE = ad_cbe;
-	*data = *PCI_CRP_RDATA;
-	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-/*
- * Write to PCI config space
- */
-static void crp_write(u32 ad_cbe, u32 data)
-{ 
-	unsigned long flags;
-	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-	*PCI_CRP_AD_CBE = CRP_AD_CBE_WRITE | ad_cbe;
-	*PCI_CRP_WDATA = data;
-	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-}
-
-static inline int check_master_abort(void)
-{
-	/* check Master Abort bit after access */
-	unsigned long isr = *PCI_ISR;
-
-	if (isr & PCI_ISR_PFE) {
-		/* make sure the Master Abort bit is reset */    
-		*PCI_ISR = PCI_ISR_PFE;
-		pr_debug("%s failed\n", __func__);
-		return 1;
-	}
-
-	return 0;
-}
-
-int ixp4xx_pci_read_errata(u32 addr, u32 cmd, u32* data)
-{
-	unsigned long flags;
-	int retval = 0;
-	int i;
-
-	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
-	*PCI_NP_AD = addr;
-
-	/* 
-	 * PCI workaround  - only works if NP PCI space reads have 
-	 * no side effects!!! Read 8 times. last one will be good.
-	 */
-	for (i = 0; i < 8; i++) {
-		*PCI_NP_CBE = cmd;
-		*data = *PCI_NP_RDATA;
-		*data = *PCI_NP_RDATA;
-	}
-
-	if(check_master_abort())
-		retval = 1;
-
-	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-	return retval;
-}
-
-int ixp4xx_pci_read_no_errata(u32 addr, u32 cmd, u32* data)
-{
-	unsigned long flags;
-	int retval = 0;
-
-	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
-	*PCI_NP_AD = addr;
-
-	/* set up and execute the read */    
-	*PCI_NP_CBE = cmd;
-
-	/* the result of the read is now in NP_RDATA */
-	*data = *PCI_NP_RDATA; 
-
-	if(check_master_abort())
-		retval = 1;
-
-	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-	return retval;
-}
-
-int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data)
-{    
-	unsigned long flags;
-	int retval = 0;
-
-	raw_spin_lock_irqsave(&ixp4xx_pci_lock, flags);
-
-	*PCI_NP_AD = addr;
-
-	/* set up the write */
-	*PCI_NP_CBE = cmd;
-
-	/* execute the write by writing to NP_WDATA */
-	*PCI_NP_WDATA = data;
-
-	if(check_master_abort())
-		retval = 1;
-
-	raw_spin_unlock_irqrestore(&ixp4xx_pci_lock, flags);
-	return retval;
-}
-
-static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where)
-{
-	u32 addr;
-	if (!bus_num) {
-		/* type 0 */
-		addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) | 
-		    (where & ~3);	
-	} else {
-		/* type 1 */
-		addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) | 
-			((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1;
-	}
-	return addr;
-}
-
-/*
- * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
- * 0 and 3 are not valid indexes...
- */
-static u32 bytemask[] = {
-	/*0*/	0,
-	/*1*/	0xff,
-	/*2*/	0xffff,
-	/*3*/	0,
-	/*4*/	0xffffffff,
-};
-
-static u32 local_byte_lane_enable_bits(u32 n, int size)
-{
-	if (size == 1)
-		return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL;
-	if (size == 2)
-		return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL;
-	if (size == 4)
-		return 0;
-	return 0xffffffff;
-}
-
-static int local_read_config(int where, int size, u32 *value)
-{ 
-	u32 n, data;
-	pr_debug("local_read_config from %d size %d\n", where, size);
-	n = where % 4;
-	crp_read(where & ~3, &data);
-	*value = (data >> (8*n)) & bytemask[size];
-	pr_debug("local_read_config read %#x\n", *value);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int local_write_config(int where, int size, u32 value)
-{
-	u32 n, byte_enables, data;
-	pr_debug("local_write_config %#x to %d size %d\n", value, where, size);
-	n = where % 4;
-	byte_enables = local_byte_lane_enable_bits(n, size);
-	if (byte_enables == 0xffffffff)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	data = value << (8*n);
-	crp_write((where & ~3) | byte_enables, data);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static u32 byte_lane_enable_bits(u32 n, int size)
-{
-	if (size == 1)
-		return (0xf & ~BIT(n)) << 4;
-	if (size == 2)
-		return (0xf & ~(BIT(n) | BIT(n+1))) << 4;
-	if (size == 4)
-		return 0;
-	return 0xffffffff;
-}
-
-static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
-{
-	u32 n, byte_enables, addr, data;
-	u8 bus_num = bus->number;
-
-	pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
-		bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
-	*value = 0xffffffff;
-	n = where % 4;
-	byte_enables = byte_lane_enable_bits(n, size);
-	if (byte_enables == 0xffffffff)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	addr = ixp4xx_config_addr(bus_num, devfn, where);
-	if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_CONFIGREAD, &data))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	*value = (data >> (8*n)) & bytemask[size];
-	pr_debug("read_config_byte read %#x\n", *value);
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static int ixp4xx_pci_write_config(struct pci_bus *bus,  unsigned int devfn, int where, int size, u32 value)
-{
-	u32 n, byte_enables, addr, data;
-	u8 bus_num = bus->number;
-
-	pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
-		size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-
-	n = where % 4;
-	byte_enables = byte_lane_enable_bits(n, size);
-	if (byte_enables == 0xffffffff)
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-
-	addr = ixp4xx_config_addr(bus_num, devfn, where);
-	data = value << (8*n);
-	if (ixp4xx_pci_write(addr, byte_enables | NP_CMD_CONFIGWRITE, data))
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops ixp4xx_ops = {
-	.read =  ixp4xx_pci_read_config,
-	.write = ixp4xx_pci_write_config,
-};
-
-/*
- * PCI abort handler
- */
-static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-	u32 isr, status;
-
-	isr = *PCI_ISR;
-	local_read_config(PCI_STATUS, 2, &status);
-	pr_debug("PCI: abort_handler addr = %#lx, isr = %#x, "
-		"status = %#x\n", addr, isr, status);
-
-	/* make sure the Master Abort bit is reset */    
-	*PCI_ISR = PCI_ISR_PFE;
-	status |= PCI_STATUS_REC_MASTER_ABORT;
-	local_write_config(PCI_STATUS, 2, status);
-
-	/*
-	 * If it was an imprecise abort, then we need to correct the
-	 * return address to be _after_ the instruction.
-	 */
-	if (fsr & (1 << 10))
-		regs->ARM_pc += 4;
-
-	return 0;
-}
-
-void __init ixp4xx_pci_preinit(void)
-{
-	unsigned long cpuid = read_cpuid_id();
-
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-	pcibios_min_mem = 0x10000000; /* 1 GB of indirect PCI MMIO space */
-#else
-	pcibios_min_mem = 0x48000000; /* 64 MB of PCI MMIO space */
-#endif
-	/*
-	 * Determine which PCI read method to use.
-	 * Rev 0 IXP425 requires workaround.
-	 */
-	if (!(cpuid & 0xf) && cpu_is_ixp42x()) {
-		printk("PCI: IXP42x A0 silicon detected - "
-			"PCI Non-Prefetch Workaround Enabled\n");
-		ixp4xx_pci_read = ixp4xx_pci_read_errata;
-	} else
-		ixp4xx_pci_read = ixp4xx_pci_read_no_errata;
-
-
-	/* hook in our fault handler for PCI errors */
-	hook_fault_code(16+6, abort_handler, SIGBUS, 0,
-			"imprecise external abort");
-
-	pr_debug("setup PCI-AHB(inbound) and AHB-PCI(outbound) address mappings\n");
-
-	/*
-	 * We use identity AHB->PCI address translation
-	 * in the 0x48000000 to 0x4bffffff address space
-	 */
-	*PCI_PCIMEMBASE = 0x48494A4B;
-
-	/*
-	 * We also use identity PCI->AHB address translation
-	 * in 4 16MB BARs that begin at the physical memory start
-	 */
-	*PCI_AHBMEMBASE = (PHYS_OFFSET & 0xFF000000) +
-		((PHYS_OFFSET & 0xFF000000) >> 8) +
-		((PHYS_OFFSET & 0xFF000000) >> 16) +
-		((PHYS_OFFSET & 0xFF000000) >> 24) +
-		0x00010203;
-
-	if (*PCI_CSR & PCI_CSR_HOST) {
-		printk("PCI: IXP4xx is host\n");
-
-		pr_debug("setup BARs in controller\n");
-
-		/*
-		 * We configure the PCI inbound memory windows to be
-		 * 1:1 mapped to SDRAM
-		 */
-		local_write_config(PCI_BASE_ADDRESS_0, 4, PHYS_OFFSET);
-		local_write_config(PCI_BASE_ADDRESS_1, 4, PHYS_OFFSET + SZ_16M);
-		local_write_config(PCI_BASE_ADDRESS_2, 4, PHYS_OFFSET + SZ_32M);
-		local_write_config(PCI_BASE_ADDRESS_3, 4,
-					PHYS_OFFSET + SZ_32M + SZ_16M);
-
-		/*
-		 * Enable CSR window at 64 MiB to allow PCI masters
-		 * to continue prefetching past 64 MiB boundary.
-		 */
-		local_write_config(PCI_BASE_ADDRESS_4, 4, PHYS_OFFSET + SZ_64M);
-
-		/*
-		 * Enable the IO window to be way up high, at 0xfffffc00
-		 */
-		local_write_config(PCI_BASE_ADDRESS_5, 4, 0xfffffc01);
-		local_write_config(0x40, 4, 0x000080FF); /* No TRDY time limit */
-	} else {
-		printk("PCI: IXP4xx is target - No bus scan performed\n");
-	}
-
-	printk("PCI: IXP4xx Using %s access for memory space\n",
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-			"direct"
-#else
-			"indirect"
-#endif
-		);
-
-	pr_debug("clear error bits in ISR\n");
-	*PCI_ISR = PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE;
-
-	/*
-	 * Set Initialize Complete in PCI Control Register: allow IXP4XX to
-	 * respond to PCI configuration cycles. Specify that the AHB bus is
-	 * operating in big endian mode. Set up byte lane swapping between 
-	 * little-endian PCI and the big-endian AHB bus 
-	 */
-#ifdef __ARMEB__
-	*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
-#else
-	*PCI_CSR = PCI_CSR_IC | PCI_CSR_ABE;
-#endif
-
-	pr_debug("DONE\n");
-}
-
-int ixp4xx_setup(int nr, struct pci_sys_data *sys)
-{
-	struct resource *res;
-
-	if (nr >= 1)
-		return 0;
-
-	res = kcalloc(2, sizeof(*res), GFP_KERNEL);
-	if (res == NULL) {
-		/* 
-		 * If we're out of memory this early, something is wrong,
-		 * so we might as well catch it here.
-		 */
-		panic("PCI: unable to allocate resources?\n");
-	}
-
-	local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-
-	res[0].name = "PCI I/O Space";
-	res[0].start = 0x00000000;
-	res[0].end = 0x0000ffff;
-	res[0].flags = IORESOURCE_IO;
-
-	res[1].name = "PCI Memory Space";
-	res[1].start = PCIBIOS_MIN_MEM;
-	res[1].end = PCIBIOS_MAX_MEM;
-	res[1].flags = IORESOURCE_MEM;
-
-	request_resource(&ioport_resource, &res[0]);
-	request_resource(&iomem_resource, &res[1]);
-
-	pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset);
-	pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset);
-
-	return 1;
-}
-
-EXPORT_SYMBOL(ixp4xx_pci_read);
-EXPORT_SYMBOL(ixp4xx_pci_write);
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index cdc720f54daa..1116bd2df687 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -411,38 +411,10 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
 }
 EXPORT_SYMBOL(dma_set_coherent_mask);
 
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-static void __iomem *ixp4xx_ioremap_caller(phys_addr_t addr, size_t size,
-					   unsigned int mtype, void *caller)
-{
-	if (!is_pci_memory(addr))
-		return __arm_ioremap_caller(addr, size, mtype, caller);
-
-	return (void __iomem *)addr;
-}
-
-static void ixp4xx_iounmap(volatile void __iomem *addr)
-{
-	if (!is_pci_memory((__force u32)addr))
-		__iounmap(addr);
-}
-#endif
-
 void __init ixp4xx_init_early(void)
 {
 	platform_notify = ixp4xx_platform_notify;
 #ifdef CONFIG_PCI
 	platform_notify_remove = ixp4xx_platform_notify_remove;
 #endif
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-	arch_ioremap_caller = ixp4xx_ioremap_caller;
-	arch_iounmap = ixp4xx_iounmap;
-#endif
 }
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
index b2b7301ce503..41f28fb8e63f 100644
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ b/arch/arm/mach-ixp4xx/include/mach/hardware.h
@@ -13,12 +13,6 @@
 #ifndef __ASM_ARCH_HARDWARE_H__
 #define __ASM_ARCH_HARDWARE_H__
 
-#ifdef CONFIG_IXP4XX_INDIRECT_PCI
-#define PCIBIOS_MAX_MEM		0x4FFFFFFF
-#else
-#define PCIBIOS_MAX_MEM		0x4BFFFFFF
-#endif
-
 /* Register locations and bits */
 #include "ixp4xx-regs.h"
 
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
deleted file mode 100644
index 014cf6dcaf8b..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ /dev/null
@@ -1,545 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/io.h
- *
- * Author: Deepak Saxena <dsaxena at plexity.net>
- *
- * Copyright (C) 2002-2005  MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#include <linux/bitops.h>
-
-#include <mach/hardware.h>
-
-extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
-extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
-
-
-/*
- * IXP4xx provides two methods of accessing PCI memory space:
- *
- * 1) A direct mapped window from 0x48000000 to 0x4BFFFFFF (64MB).
- *    To access PCI via this space, we simply ioremap() the BAR
- *    into the kernel and we can use the standard read[bwl]/write[bwl]
- *    macros. This is the preffered method due to speed but it
- *    limits the system to just 64MB of PCI memory. This can be
- *    problematic if using video cards and other memory-heavy targets.
- *
- * 2) If > 64MB of memory space is required, the IXP4xx can use indirect
- *    registers to access the whole 4 GB of PCI memory space (as we do below
- *    for I/O transactions). This allows currently for up to 1 GB (0x10000000
- *    to 0x4FFFFFFF) of memory on the bus. The disadvantage of this is that
- *    every PCI access requires three local register accesses plus a spinlock,
- *    but in some cases the performance hit is acceptable. In addition, you
- *    cannot mmap() PCI devices in this case.
- */
-#ifdef	CONFIG_IXP4XX_INDIRECT_PCI
-
-/*
- * In the case of using indirect PCI, we simply return the actual PCI
- * address and our read/write implementation use that to drive the 
- * access registers. If something outside of PCI is ioremap'd, we
- * fallback to the default.
- */
-
-extern unsigned long pcibios_min_mem;
-static inline int is_pci_memory(u32 addr)
-{
-	return (addr >= pcibios_min_mem) && (addr <= 0x4FFFFFFF);
-}
-
-#define writeb(v, p)			__indirect_writeb(v, p)
-#define writew(v, p)			__indirect_writew(v, p)
-#define writel(v, p)			__indirect_writel(v, p)
-
-#define writeb_relaxed(v, p)		__indirect_writeb(v, p)
-#define writew_relaxed(v, p)		__indirect_writew(v, p)
-#define writel_relaxed(v, p)		__indirect_writel(v, p)
-
-#define writesb(p, v, l)		__indirect_writesb(p, v, l)
-#define writesw(p, v, l)		__indirect_writesw(p, v, l)
-#define writesl(p, v, l)		__indirect_writesl(p, v, l)
-
-#define readb(p)			__indirect_readb(p)
-#define readw(p)			__indirect_readw(p)
-#define readl(p)			__indirect_readl(p)
-
-#define readb_relaxed(p)		__indirect_readb(p)
-#define readw_relaxed(p)		__indirect_readw(p)
-#define readl_relaxed(p)		__indirect_readl(p)
-
-#define readsb(p, v, l)			__indirect_readsb(p, v, l)
-#define readsw(p, v, l)			__indirect_readsw(p, v, l)
-#define readsl(p, v, l)			__indirect_readsl(p, v, l)
-
-static inline void __indirect_writeb(u8 value, volatile void __iomem *p)
-{
-	u32 addr = (u32)p;
-	u32 n, byte_enables, data;
-
-	if (!is_pci_memory(addr)) {
-		__raw_writeb(value, p);
-		return;
-	}
-
-	n = addr % 4;
-	byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
-	data = value << (8*n);
-	ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesb(volatile void __iomem *bus_addr,
-				      const void *p, int count)
-{
-	const u8 *vaddr = p;
-
-	while (count--)
-		writeb(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writew(u16 value, volatile void __iomem *p)
-{
-	u32 addr = (u32)p;
-	u32 n, byte_enables, data;
-
-	if (!is_pci_memory(addr)) {
-		__raw_writew(value, p);
-		return;
-	}
-
-	n = addr % 4;
-	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
-	data = value << (8*n);
-	ixp4xx_pci_write(addr, byte_enables | NP_CMD_MEMWRITE, data);
-}
-
-static inline void __indirect_writesw(volatile void __iomem *bus_addr,
-				      const void *p, int count)
-{
-	const u16 *vaddr = p;
-
-	while (count--)
-		writew(*vaddr++, bus_addr);
-}
-
-static inline void __indirect_writel(u32 value, volatile void __iomem *p)
-{
-	u32 addr = (__force u32)p;
-
-	if (!is_pci_memory(addr)) {
-		__raw_writel(value, p);
-		return;
-	}
-
-	ixp4xx_pci_write(addr, NP_CMD_MEMWRITE, value);
-}
-
-static inline void __indirect_writesl(volatile void __iomem *bus_addr,
-				      const void *p, int count)
-{
-	const u32 *vaddr = p;
-	while (count--)
-		writel(*vaddr++, bus_addr);
-}
-
-static inline u8 __indirect_readb(const volatile void __iomem *p)
-{
-	u32 addr = (u32)p;
-	u32 n, byte_enables, data;
-
-	if (!is_pci_memory(addr))
-		return __raw_readb(p);
-
-	n = addr % 4;
-	byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
-	if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
-		return 0xff;
-
-	return data >> (8*n);
-}
-
-static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
-				     void *p, u32 count)
-{
-	u8 *vaddr = p;
-
-	while (count--)
-		*vaddr++ = readb(bus_addr);
-}
-
-static inline u16 __indirect_readw(const volatile void __iomem *p)
-{
-	u32 addr = (u32)p;
-	u32 n, byte_enables, data;
-
-	if (!is_pci_memory(addr))
-		return __raw_readw(p);
-
-	n = addr % 4;
-	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
-	if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_MEMREAD, &data))
-		return 0xffff;
-
-	return data>>(8*n);
-}
-
-static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
-				     void *p, u32 count)
-{
-	u16 *vaddr = p;
-
-	while (count--)
-		*vaddr++ = readw(bus_addr);
-}
-
-static inline u32 __indirect_readl(const volatile void __iomem *p)
-{
-	u32 addr = (__force u32)p;
-	u32 data;
-
-	if (!is_pci_memory(addr))
-		return __raw_readl(p);
-
-	if (ixp4xx_pci_read(addr, NP_CMD_MEMREAD, &data))
-		return 0xffffffff;
-
-	return data;
-}
-
-static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
-				     void *p, u32 count)
-{
-	u32 *vaddr = p;
-
-	while (count--)
-		*vaddr++ = readl(bus_addr);
-}
-
-
-/*
- * We can use the built-in functions b/c they end up calling writeb/readb
- */
-#define memset_io(c,v,l)		_memset_io((c),(v),(l))
-#define memcpy_fromio(a,c,l)		_memcpy_fromio((a),(c),(l))
-#define memcpy_toio(c,a,l)		_memcpy_toio((c),(a),(l))
-
-#endif /* CONFIG_IXP4XX_INDIRECT_PCI */
-
-#ifndef CONFIG_PCI
-
-#define	__io(v)		__typesafe_io(v)
-
-#else
-
-/*
- * IXP4xx does not have a transparent cpu -> PCI I/O translation
- * window.  Instead, it has a set of registers that must be tweaked
- * with the proper byte lanes, command types, and address for the
- * transaction.  This means that we need to override the default
- * I/O functions.
- */
-
-#define outb outb
-static inline void outb(u8 value, u32 addr)
-{
-	u32 n, byte_enables, data;
-	n = addr % 4;
-	byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
-	data = value << (8*n);
-	ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsb outsb
-static inline void outsb(u32 io_addr, const void *p, u32 count)
-{
-	const u8 *vaddr = p;
-
-	while (count--)
-		outb(*vaddr++, io_addr);
-}
-
-#define outw outw
-static inline void outw(u16 value, u32 addr)
-{
-	u32 n, byte_enables, data;
-	n = addr % 4;
-	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
-	data = value << (8*n);
-	ixp4xx_pci_write(addr, byte_enables | NP_CMD_IOWRITE, data);
-}
-
-#define outsw outsw
-static inline void outsw(u32 io_addr, const void *p, u32 count)
-{
-	const u16 *vaddr = p;
-	while (count--)
-		outw(cpu_to_le16(*vaddr++), io_addr);
-}
-
-#define outl outl
-static inline void outl(u32 value, u32 addr)
-{
-	ixp4xx_pci_write(addr, NP_CMD_IOWRITE, value);
-}
-
-#define outsl outsl
-static inline void outsl(u32 io_addr, const void *p, u32 count)
-{
-	const u32 *vaddr = p;
-	while (count--)
-		outl(cpu_to_le32(*vaddr++), io_addr);
-}
-
-#define inb inb
-static inline u8 inb(u32 addr)
-{
-	u32 n, byte_enables, data;
-	n = addr % 4;
-	byte_enables = (0xf & ~BIT(n)) << IXP4XX_PCI_NP_CBE_BESL;
-	if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
-		return 0xff;
-
-	return data >> (8*n);
-}
-
-#define insb insb
-static inline void insb(u32 io_addr, void *p, u32 count)
-{
-	u8 *vaddr = p;
-	while (count--)
-		*vaddr++ = inb(io_addr);
-}
-
-#define inw inw
-static inline u16 inw(u32 addr)
-{
-	u32 n, byte_enables, data;
-	n = addr % 4;
-	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
-	if (ixp4xx_pci_read(addr, byte_enables | NP_CMD_IOREAD, &data))
-		return 0xffff;
-
-	return data>>(8*n);
-}
-
-#define insw insw
-static inline void insw(u32 io_addr, void *p, u32 count)
-{
-	u16 *vaddr = p;
-	while (count--)
-		*vaddr++ = le16_to_cpu(inw(io_addr));
-}
-
-#define inl inl
-static inline u32 inl(u32 addr)
-{
-	u32 data;
-	if (ixp4xx_pci_read(addr, NP_CMD_IOREAD, &data))
-		return 0xffffffff;
-
-	return data;
-}
-
-#define insl insl
-static inline void insl(u32 io_addr, void *p, u32 count)
-{
-	u32 *vaddr = p;
-	while (count--)
-		*vaddr++ = le32_to_cpu(inl(io_addr));
-}
-
-#define PIO_OFFSET      0x10000UL
-#define PIO_MASK        0x0ffffUL
-
-#define	__is_io_address(p)	(((unsigned long)p >= PIO_OFFSET) && \
-					((unsigned long)p <= (PIO_MASK + PIO_OFFSET)))
-
-#define	ioread8(p)			ioread8(p)
-static inline u8 ioread8(const void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		return (unsigned int)inb(port & PIO_MASK);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		return (unsigned int)__raw_readb(addr);
-#else
-		return (unsigned int)__indirect_readb(addr);
-#endif
-}
-
-#define	ioread8_rep(p, v, c)		ioread8_rep(p, v, c)
-static inline void ioread8_rep(const void __iomem *addr, void *vaddr, u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		insb(port & PIO_MASK, vaddr, count);
-	else
-#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_readsb(addr, vaddr, count);
-#else
-		__indirect_readsb(addr, vaddr, count);
-#endif
-}
-
-#define	ioread16(p)			ioread16(p)
-static inline u16 ioread16(const void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		return	(unsigned int)inw(port & PIO_MASK);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		return le16_to_cpu((__force __le16)__raw_readw(addr));
-#else
-		return (unsigned int)__indirect_readw(addr);
-#endif
-}
-
-#define	ioread16_rep(p, v, c)		ioread16_rep(p, v, c)
-static inline void ioread16_rep(const void __iomem *addr, void *vaddr,
-				u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		insw(port & PIO_MASK, vaddr, count);
-	else
-#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_readsw(addr, vaddr, count);
-#else
-		__indirect_readsw(addr, vaddr, count);
-#endif
-}
-
-#define	ioread32(p)			ioread32(p)
-static inline u32 ioread32(const void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		return	(unsigned int)inl(port & PIO_MASK);
-	else {
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		return le32_to_cpu((__force __le32)__raw_readl(addr));
-#else
-		return (unsigned int)__indirect_readl(addr);
-#endif
-	}
-}
-
-#define	ioread32_rep(p, v, c)		ioread32_rep(p, v, c)
-static inline void ioread32_rep(const void __iomem *addr, void *vaddr,
-				u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		insl(port & PIO_MASK, vaddr, count);
-	else
-#ifndef	CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_readsl(addr, vaddr, count);
-#else
-		__indirect_readsl(addr, vaddr, count);
-#endif
-}
-
-#define	iowrite8(v, p)			iowrite8(v, p)
-static inline void iowrite8(u8 value, void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outb(value, port & PIO_MASK);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writeb(value, addr);
-#else
-		__indirect_writeb(value, addr);
-#endif
-}
-
-#define	iowrite8_rep(p, v, c)		iowrite8_rep(p, v, c)
-static inline void iowrite8_rep(void __iomem *addr, const void *vaddr,
-				u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outsb(port & PIO_MASK, vaddr, count);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writesb(addr, vaddr, count);
-#else
-		__indirect_writesb(addr, vaddr, count);
-#endif
-}
-
-#define	iowrite16(v, p)			iowrite16(v, p)
-static inline void iowrite16(u16 value, void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outw(value, port & PIO_MASK);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writew(cpu_to_le16(value), addr);
-#else
-		__indirect_writew(value, addr);
-#endif
-}
-
-#define	iowrite16_rep(p, v, c)		iowrite16_rep(p, v, c)
-static inline void iowrite16_rep(void __iomem *addr, const void *vaddr,
-				 u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outsw(port & PIO_MASK, vaddr, count);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writesw(addr, vaddr, count);
-#else
-		__indirect_writesw(addr, vaddr, count);
-#endif
-}
-
-#define	iowrite32(v, p)			iowrite32(v, p)
-static inline void iowrite32(u32 value, void __iomem *addr)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outl(value, port & PIO_MASK);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writel((u32 __force)cpu_to_le32(value), addr);
-#else
-		__indirect_writel(value, addr);
-#endif
-}
-
-#define	iowrite32_rep(p, v, c)		iowrite32_rep(p, v, c)
-static inline void iowrite32_rep(void __iomem *addr, const void *vaddr,
-				 u32 count)
-{
-	unsigned long port = (unsigned long __force)addr;
-	if (__is_io_address(port))
-		outsl(port & PIO_MASK, vaddr, count);
-	else
-#ifndef CONFIG_IXP4XX_INDIRECT_PCI
-		__raw_writesl(addr, vaddr, count);
-#else
-		__indirect_writesl(addr, vaddr, count);
-#endif
-}
-
-#define ioport_map(port, nr) ioport_map(port, nr)
-static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
-{
-	return ((void __iomem*)((port) + PIO_OFFSET));
-}
-#define	ioport_unmap(addr) ioport_unmap(addr)
-static inline void ioport_unmap(void __iomem *addr)
-{
-}
-#endif /* CONFIG_PCI */
-
-#endif /* __ASM_ARM_ARCH_IO_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
index d8b4df96db08..f9ec07f00be0 100644
--- a/arch/arm/mach-ixp4xx/include/mach/platform.h
+++ b/arch/arm/mach-ixp4xx/include/mach/platform.h
@@ -93,10 +93,6 @@ extern void ixp4xx_init_irq(void);
 extern void ixp4xx_sys_init(void);
 extern void ixp4xx_timer_init(void);
 extern void ixp4xx_restart(enum reboot_mode, const char *);
-extern void ixp4xx_pci_preinit(void);
-struct pci_sys_data;
-extern int ixp4xx_setup(int nr, struct pci_sys_data *sys);
-extern struct pci_ops ixp4xx_ops;
 
 #endif // __ASSEMBLY__
 
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:49 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:49 +0100
Subject: [PATCH 06/13] soc: ixp4xx: Add features from regmap helper
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-7-linus.walleij@linaro.org>

If we want to read the CFG2 register on the expansion bus and
apply the inversion and check for some hardcoded versions this
helper comes in handy.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 include/linux/soc/ixp4xx/cpu.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/linux/soc/ixp4xx/cpu.h b/include/linux/soc/ixp4xx/cpu.h
index 88bd8de0e803..48c2e241ac83 100644
--- a/include/linux/soc/ixp4xx/cpu.h
+++ b/include/linux/soc/ixp4xx/cpu.h
@@ -9,6 +9,7 @@
 #define __SOC_IXP4XX_CPU_H__
 
 #include <linux/io.h>
+#include <linux/regmap.h>
 #ifdef CONFIG_ARM
 #include <asm/cputype.h>
 #endif
@@ -23,6 +24,9 @@
 #define IXP46X_PROCESSOR_ID_VALUE	0x69054200 /* including IXP455 */
 #define IXP46X_PROCESSOR_ID_MASK	0xfffffff0
 
+/* Feature register in the expansion bus controller */
+#define IXP4XX_EXP_CNFG2		0x2c
+
 /* "fuse" bits of IXP_EXP_CFG2 */
 /* All IXP4xx CPUs */
 #define IXP4XX_FEATURE_RCOMP		(1 << 0)
@@ -89,6 +93,22 @@
 
 u32 ixp4xx_read_feature_bits(void);
 void ixp4xx_write_feature_bits(u32 value);
+static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
+{
+	u32 val;
+
+	regmap_read(rmap, IXP4XX_EXP_CNFG2, &val);
+	/* For some reason this register is inverted */
+	val = ~val;
+	if (cpu_is_ixp42x_rev_a0())
+		return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
+					       IXP4XX_FEATURE_AES);
+	if (cpu_is_ixp42x())
+		return val & IXP42X_FEATURE_MASK;
+	if (cpu_is_ixp43x())
+		return val & IXP43X_FEATURE_MASK;
+	return val & IXP46X_FEATURE_MASK;
+}
 #else
 #define cpu_is_ixp42x_rev_a0()		0
 #define cpu_is_ixp42x()			0
@@ -101,6 +121,10 @@ static inline u32 ixp4xx_read_feature_bits(void)
 static inline void ixp4xx_write_feature_bits(u32 value)
 {
 }
+static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
+{
+	return 0;
+}
 #endif
 
 #endif  /* _ASM_ARCH_CPU_H */
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:51 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:51 +0100
Subject: [PATCH 08/13] net: ixp4xx_eth: Drop platform data support
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-9-linus.walleij@linaro.org>

All IXP4xx platforms are converted to device tree, the platform
data path is no longer used. Drop the code and custom include,
confine the driver in its own file.

Depend on OF and remove ifdefs around this, as we are all probing
from OF now.

Cc: David S. Miller <davem at davemloft.net>
Cc: Jakub Kicinski <kuba at kernel.org>
Cc: netdev at vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Network maintainers: I'm looking for an ACK to take this
change through ARM SoC along with other changes removing
these accessor functions.
---
 drivers/net/ethernet/xscale/Kconfig      |  4 +-
 drivers/net/ethernet/xscale/ixp4xx_eth.c | 69 +++++++-----------------
 include/linux/platform_data/eth_ixp4xx.h | 21 --------
 3 files changed, 20 insertions(+), 74 deletions(-)
 delete mode 100644 include/linux/platform_data/eth_ixp4xx.h

diff --git a/drivers/net/ethernet/xscale/Kconfig b/drivers/net/ethernet/xscale/Kconfig
index 0e878fa6e322..b33f64c54b0e 100644
--- a/drivers/net/ethernet/xscale/Kconfig
+++ b/drivers/net/ethernet/xscale/Kconfig
@@ -20,9 +20,9 @@ if NET_VENDOR_XSCALE
 
 config IXP4XX_ETH
 	tristate "Intel IXP4xx Ethernet support"
-	depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
+	depends on ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR && OF
 	select PHYLIB
-	select OF_MDIO if OF
+	select OF_MDIO
 	select NET_PTP_CLASSIFY
 	help
 	  Say Y here if you want to use built-in Ethernet ports
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index df77a22d1b81..577a24b3ad70 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -30,7 +30,6 @@
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/phy.h>
-#include <linux/platform_data/eth_ixp4xx.h>
 #include <linux/platform_device.h>
 #include <linux/ptp_classify.h>
 #include <linux/slab.h>
@@ -38,6 +37,11 @@
 #include <linux/soc/ixp4xx/npe.h>
 #include <linux/soc/ixp4xx/qmgr.h>
 #include <linux/soc/ixp4xx/cpu.h>
+#include <linux/types.h>
+
+#define IXP4XX_ETH_NPEA		0x00
+#define IXP4XX_ETH_NPEB		0x10
+#define IXP4XX_ETH_NPEC		0x20
 
 #include "ixp46x_ts.h"
 
@@ -147,6 +151,16 @@ typedef void buffer_t;
 #define free_buffer_irq kfree
 #endif
 
+/* Information about built-in Ethernet MAC interfaces */
+struct eth_plat_info {
+	u8 phy;		/* MII PHY ID, 0 - 31 */
+	u8 rxq;		/* configurable, currently 0 - 31 only */
+	u8 txreadyq;
+	u8 hwaddr[6];
+	u8 npe;		/* NPE instance used by this interface */
+	bool has_mdio;	/* If this instance has an MDIO bus */
+};
+
 struct eth_regs {
 	u32 tx_control[2], __res1[2];		/* 000 */
 	u32 rx_control[2], __res2[2];		/* 010 */
@@ -1366,7 +1380,6 @@ static const struct net_device_ops ixp4xx_netdev_ops = {
 	.ndo_validate_addr = eth_validate_addr,
 };
 
-#ifdef CONFIG_OF
 static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
 {
 	struct device_node *np = dev->of_node;
@@ -1417,12 +1430,6 @@ static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
 
 	return plat;
 }
-#else
-static struct eth_plat_info *ixp4xx_of_get_platdata(struct device *dev)
-{
-	return NULL;
-}
-#endif
 
 static int ixp4xx_eth_probe(struct platform_device *pdev)
 {
@@ -1434,49 +1441,9 @@ static int ixp4xx_eth_probe(struct platform_device *pdev)
 	struct port *port;
 	int err;
 
-	if (np) {
-		plat = ixp4xx_of_get_platdata(dev);
-		if (!plat)
-			return -ENODEV;
-	} else {
-		plat = dev_get_platdata(dev);
-		if (!plat)
-			return -ENODEV;
-		plat->npe = pdev->id;
-		switch (plat->npe) {
-		case IXP4XX_ETH_NPEA:
-			/* If the MDIO bus is not up yet, defer probe */
-			break;
-		case IXP4XX_ETH_NPEB:
-			/* On all except IXP43x, NPE-B is used for the MDIO bus.
-			 * If there is no NPE-B in the feature set, bail out,
-			 * else we have the MDIO bus here.
-			 */
-			if (!cpu_is_ixp43x()) {
-				if (!(ixp4xx_read_feature_bits() &
-				      IXP4XX_FEATURE_NPEB_ETH0))
-					return -ENODEV;
-				/* Else register the MDIO bus on NPE-B */
-				plat->has_mdio = true;
-			}
-			break;
-		case IXP4XX_ETH_NPEC:
-			/* IXP43x lacks NPE-B and uses NPE-C for the MDIO bus
-			 * access, if there is no NPE-C, no bus, nothing works,
-			 * so bail out.
-			 */
-			if (cpu_is_ixp43x()) {
-				if (!(ixp4xx_read_feature_bits() &
-				      IXP4XX_FEATURE_NPEC_ETH))
-					return -ENODEV;
-				/* Else register the MDIO bus on NPE-B */
-				plat->has_mdio = true;
-			}
-			break;
-		default:
-			return -ENODEV;
-		}
-	}
+	plat = ixp4xx_of_get_platdata(dev);
+	if (!plat)
+		return -ENODEV;
 
 	if (!(ndev = devm_alloc_etherdev(dev, sizeof(struct port))))
 		return -ENOMEM;
diff --git a/include/linux/platform_data/eth_ixp4xx.h b/include/linux/platform_data/eth_ixp4xx.h
deleted file mode 100644
index 114b0940729f..000000000000
--- a/include/linux/platform_data/eth_ixp4xx.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __PLATFORM_DATA_ETH_IXP4XX
-#define __PLATFORM_DATA_ETH_IXP4XX
-
-#include <linux/types.h>
-
-#define IXP4XX_ETH_NPEA		0x00
-#define IXP4XX_ETH_NPEB		0x10
-#define IXP4XX_ETH_NPEC		0x20
-
-/* Information about built-in Ethernet MAC interfaces */
-struct eth_plat_info {
-	u8 phy;		/* MII PHY ID, 0 - 31 */
-	u8 rxq;		/* configurable, currently 0 - 31 only */
-	u8 txreadyq;
-	u8 hwaddr[6];
-	u8 npe;		/* NPE instance used by this interface */
-	bool has_mdio;	/* If this instance has an MDIO bus */
-};
-
-#endif
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:52 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:52 +0100
Subject: [PATCH 09/13] net: ixp4xx_hss: Check features using syscon
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-10-linus.walleij@linaro.org>

If we access the syscon (expansion bus config registers) using the
syscon regmap instead of relying on direct accessor functions,
we do not need to call this static code in the machine
(arch/arm/mach-ixp4xx/common.c) which makes things less dependent
on custom machine-dependent code.

Look up the syscon regmap and handle the error: this will make
deferred probe work with relation to the syscon.

Select the syscon in Kconfig and depend on OF so we know that
all we need will be available.

Cc: David S. Miller <davem at davemloft.net>
Cc: Jakub Kicinski <kuba at kernel.org>
Cc: netdev at vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Network maintainers: I'm looking for an ACK to take this
change through ARM SoC along with other changes removing
these accessor functions.
---
 drivers/net/wan/Kconfig      |  3 ++-
 drivers/net/wan/ixp4xx_hss.c | 39 ++++++++++++++++++++----------------
 2 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 592a8389fc5a..140780ac1745 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -293,7 +293,8 @@ config SLIC_DS26522
 config IXP4XX_HSS
 	tristate "Intel IXP4xx HSS (synchronous serial port) support"
 	depends on HDLC && IXP4XX_NPE && IXP4XX_QMGR
-	depends on ARCH_IXP4XX
+	depends on ARCH_IXP4XX && OF
+	select MFD_SYSCON
 	help
 	  Say Y here if you want to use built-in HSS ports
 	  on IXP4xx processor.
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 0b7d9f2f2b8b..863c3e34e136 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -16,8 +16,10 @@
 #include <linux/hdlc.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
 #include <linux/platform_device.h>
 #include <linux/poll.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/gpio/consumer.h>
 #include <linux/of.h>
@@ -1389,9 +1391,28 @@ static int ixp4xx_hss_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct net_device *ndev;
 	struct device_node *np;
+	struct regmap *rmap;
 	struct port *port;
 	hdlc_device *hdlc;
 	int err;
+	u32 val;
+
+	/*
+	 * Go into the syscon and check if we have the HSS and HDLC
+	 * features available, else this will not work.
+	 */
+	rmap = syscon_regmap_lookup_by_compatible("syscon");
+	if (IS_ERR(rmap))
+		return dev_err_probe(dev, PTR_ERR(rmap),
+				     "failed to look up syscon\n");
+
+	val = cpu_ixp4xx_features(rmap);
+
+	if ((val & (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
+	    (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) {
+		dev_err(dev, "HDLC and HSS feature unavailable in platform\n");
+		return -ENODEV;
+	}
 
 	np = dev->of_node;
 
@@ -1516,25 +1537,9 @@ static struct platform_driver ixp4xx_hss_driver = {
 	.probe		= ixp4xx_hss_probe,
 	.remove		= ixp4xx_hss_remove,
 };
-
-static int __init hss_init_module(void)
-{
-	if ((ixp4xx_read_feature_bits() &
-	     (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS)) !=
-	    (IXP4XX_FEATURE_HDLC | IXP4XX_FEATURE_HSS))
-		return -ENODEV;
-
-	return platform_driver_register(&ixp4xx_hss_driver);
-}
-
-static void __exit hss_cleanup_module(void)
-{
-	platform_driver_unregister(&ixp4xx_hss_driver);
-}
+module_platform_driver(ixp4xx_hss_driver);
 
 MODULE_AUTHOR("Krzysztof Halasa");
 MODULE_DESCRIPTION("Intel IXP4xx HSS driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:ixp4xx_hss");
-module_init(hss_init_module);
-module_exit(hss_cleanup_module);
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:50 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:50 +0100
Subject: [PATCH 07/13] soc: ixp4xx-npe: Access syscon regs using regmap
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-8-linus.walleij@linaro.org>

If we access the syscon (expansion bus config registers) using the
syscon regmap instead of relying on direct accessor functions,
we do not need to call this static code in the machine
(arch/arm/mach-ixp4xx/common.c) which makes things less dependent
on custom machine-dependent code.

Look up the syscon regmap and handle the error: this will make
deferred probe work with relation to the syscon.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 drivers/soc/ixp4xx/Kconfig      |  1 +
 drivers/soc/ixp4xx/ixp4xx-npe.c | 34 ++++++++++++++++++++++++---------
 include/linux/soc/ixp4xx/npe.h  |  2 ++
 3 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/drivers/soc/ixp4xx/Kconfig b/drivers/soc/ixp4xx/Kconfig
index e3eb19b85fa4..c55f0c9ae513 100644
--- a/drivers/soc/ixp4xx/Kconfig
+++ b/drivers/soc/ixp4xx/Kconfig
@@ -12,6 +12,7 @@ config IXP4XX_QMGR
 config IXP4XX_NPE
 	tristate "IXP4xx Network Processor Engine support"
 	select FW_LOADER
+	select MFD_SYSCON
 	help
 	  This driver supports IXP4xx built-in network coprocessors
 	  and is automatically selected by Ethernet and HSS drivers.
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index f490c4ca51f5..4fbbd6aca7e1 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -16,6 +16,7 @@
 #include <linux/firmware.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -284,6 +285,7 @@ static int __must_check npe_logical_reg_write32(struct npe *npe, u32 addr,
 
 static int npe_reset(struct npe *npe)
 {
+	u32 reset_bit = (IXP4XX_FEATURE_RESET_NPEA << npe->id);
 	u32 val, ctl, exec_count, ctx_reg2;
 	int i;
 
@@ -380,16 +382,19 @@ static int npe_reset(struct npe *npe)
 	__raw_writel(0, &npe->regs->action_points[3]);
 	__raw_writel(0, &npe->regs->watch_count);
 
-	val = ixp4xx_read_feature_bits();
+	/*
+	 * We need to work on cached values here because the register
+	 * will read inverted but needs to be written non-inverted.
+	 */
+	val = cpu_ixp4xx_features(npe->rmap);
 	/* reset the NPE */
-	ixp4xx_write_feature_bits(val &
-				  ~(IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val & ~reset_bit);
 	/* deassert reset */
-	ixp4xx_write_feature_bits(val |
-				  (IXP4XX_FEATURE_RESET_NPEA << npe->id));
+	regmap_write(npe->rmap, IXP4XX_EXP_CNFG2, val | reset_bit);
+
 	for (i = 0; i < MAX_RETRIES; i++) {
-		if (ixp4xx_read_feature_bits() &
-		    (IXP4XX_FEATURE_RESET_NPEA << npe->id))
+		val = cpu_ixp4xx_features(npe->rmap);
+		if (val & reset_bit)
 			break;	/* NPE is back alive */
 		udelay(1);
 	}
@@ -683,6 +688,15 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
 	struct resource *res;
+	struct regmap *rmap;
+	u32 val;
+	int ret;
+
+	/* This system has only one syscon, so fetch it */
+	rmap = syscon_regmap_lookup_by_compatible("syscon");
+	if (IS_ERR(rmap))
+		return dev_err_probe(dev, PTR_ERR(rmap),
+				     "failed to look up syscon\n");
 
 	for (i = 0; i < NPE_COUNT; i++) {
 		struct npe *npe = &npe_tab[i];
@@ -691,8 +705,9 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
 		if (!res)
 			return -ENODEV;
 
-		if (!(ixp4xx_read_feature_bits() &
-		      (IXP4XX_FEATURE_RESET_NPEA << i))) {
+		val = cpu_ixp4xx_features(rmap);
+
+		if (!(val & (IXP4XX_FEATURE_RESET_NPEA << i))) {
 			dev_info(dev, "NPE%d at %pR not available\n",
 				 i, res);
 			continue; /* NPE already disabled or not present */
@@ -700,6 +715,7 @@ static int ixp4xx_npe_probe(struct platform_device *pdev)
 		npe->regs = devm_ioremap_resource(dev, res);
 		if (IS_ERR(npe->regs))
 			return PTR_ERR(npe->regs);
+		npe->rmap = rmap;
 
 		if (npe_reset(npe)) {
 			dev_info(dev, "NPE%d at %pR does not reset\n",
diff --git a/include/linux/soc/ixp4xx/npe.h b/include/linux/soc/ixp4xx/npe.h
index 2a91f465d456..9efeac777da1 100644
--- a/include/linux/soc/ixp4xx/npe.h
+++ b/include/linux/soc/ixp4xx/npe.h
@@ -3,6 +3,7 @@
 #define __IXP4XX_NPE_H
 
 #include <linux/kernel.h>
+#include <linux/regmap.h>
 
 extern const char *npe_names[];
 
@@ -17,6 +18,7 @@ struct npe_regs {
 
 struct npe {
 	struct npe_regs __iomem *regs;
+	struct regmap *rmap;
 	int id;
 	int valid;
 };
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:53 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:53 +0100
Subject: [PATCH 10/13] ARM: ixp4xx: Remove feature bit accessors
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-11-linus.walleij@linaro.org>

We switched users of the accessors over to using syscon to inspect
the bits, or removed the need for checking them. Delete these
accessors.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-ixp4xx/common.c  | 21 ---------------------
 include/linux/soc/ixp4xx/cpu.h | 10 ----------
 2 files changed, 31 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 5192cf621f5b..4e51514ace6d 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -43,27 +43,6 @@
 
 #include "irqs.h"
 
-u32 ixp4xx_read_feature_bits(void)
-{
-	u32 val = ~__raw_readl(IXP4XX_EXP_CFG2);
-
-	if (cpu_is_ixp42x_rev_a0())
-		return IXP42X_FEATURE_MASK & ~(IXP4XX_FEATURE_RCOMP |
-					       IXP4XX_FEATURE_AES);
-	if (cpu_is_ixp42x())
-		return val & IXP42X_FEATURE_MASK;
-	if (cpu_is_ixp43x())
-		return val & IXP43X_FEATURE_MASK;
-	return val & IXP46X_FEATURE_MASK;
-}
-EXPORT_SYMBOL(ixp4xx_read_feature_bits);
-
-void ixp4xx_write_feature_bits(u32 value)
-{
-	__raw_writel(~value, IXP4XX_EXP_CFG2);
-}
-EXPORT_SYMBOL(ixp4xx_write_feature_bits);
-
 #define IXP4XX_TIMER_FREQ 66666000
 
 /*************************************************************************
diff --git a/include/linux/soc/ixp4xx/cpu.h b/include/linux/soc/ixp4xx/cpu.h
index 48c2e241ac83..f526ac33afea 100644
--- a/include/linux/soc/ixp4xx/cpu.h
+++ b/include/linux/soc/ixp4xx/cpu.h
@@ -90,9 +90,6 @@
 			 IXP43X_PROCESSOR_ID_VALUE)
 #define cpu_is_ixp46x()	((read_cpuid_id() & IXP46X_PROCESSOR_ID_MASK) == \
 			 IXP46X_PROCESSOR_ID_VALUE)
-
-u32 ixp4xx_read_feature_bits(void);
-void ixp4xx_write_feature_bits(u32 value);
 static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
 {
 	u32 val;
@@ -114,13 +111,6 @@ static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
 #define cpu_is_ixp42x()			0
 #define cpu_is_ixp43x()			0
 #define cpu_is_ixp46x()			0
-static inline u32 ixp4xx_read_feature_bits(void)
-{
-	return 0;
-}
-static inline void ixp4xx_write_feature_bits(u32 value)
-{
-}
 static inline u32 cpu_ixp4xx_features(struct regmap *rmap)
 {
 	return 0;
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:54 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:54 +0100
Subject: [PATCH 11/13] ARM: ixp4xx: Drop custom DMA coherency and bouncing
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-12-linus.walleij@linaro.org>

The new PCI driver does not need any of this stuff, so just
drop it.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig              |  5 ---
 arch/arm/mach-ixp4xx/common.c | 57 -----------------------------------
 kernel/dma/mapping.c          |  2 --
 3 files changed, 64 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3a95203236d2..ec0dbaf73a81 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -217,9 +217,6 @@ config ARCH_MAY_HAVE_PC_FDC
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
 
-config ARCH_HAS_DMA_SET_COHERENT_MASK
-	bool
-
 config GENERIC_ISA_DMA
 	bool
 
@@ -381,10 +378,8 @@ config ARCH_IOP32X
 config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	depends on MMU
-	select ARCH_HAS_DMA_SET_COHERENT_MASK
 	select ARCH_SUPPORTS_BIG_ENDIAN
 	select CPU_XSCALE
-	select DMABOUNCE if PCI
 	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_IXP4XX
 	select GPIOLIB
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 4e51514ace6d..310e1602fbfc 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -30,7 +30,6 @@
 #include <linux/soc/ixp4xx/cpu.h>
 #include <linux/irqchip/irq-ixp4xx.h>
 #include <linux/platform_data/timer-ixp4xx.h>
-#include <linux/dma-map-ops.h>
 #include <mach/hardware.h>
 #include <linux/uaccess.h>
 #include <asm/page.h>
@@ -330,59 +329,3 @@ void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
 		*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
 	}
 }
-
-#ifdef CONFIG_PCI
-static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
-{
-	return (dma_addr + size) > SZ_64M;
-}
-
-static int ixp4xx_platform_notify_remove(struct device *dev)
-{
-	if (dev_is_pci(dev))
-		dmabounce_unregister_dev(dev);
-
-	return 0;
-}
-#endif
-
-/*
- * Setup DMA mask to 64MB on PCI devices and 4 GB on all other things.
- */
-static int ixp4xx_platform_notify(struct device *dev)
-{
-	dev->dma_mask = &dev->coherent_dma_mask;
-
-#ifdef CONFIG_PCI
-	if (dev_is_pci(dev)) {
-		dev->coherent_dma_mask = DMA_BIT_MASK(28); /* 64 MB */
-		dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce);
-		return 0;
-	}
-#endif
-
-	dev->coherent_dma_mask = DMA_BIT_MASK(32);
-	return 0;
-}
-
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
-	if (dev_is_pci(dev))
-		mask &= DMA_BIT_MASK(28); /* 64 MB */
-
-	if ((mask & DMA_BIT_MASK(28)) == DMA_BIT_MASK(28)) {
-		dev->coherent_dma_mask = mask;
-		return 0;
-	}
-
-	return -EIO;		/* device wanted sub-64MB mask */
-}
-EXPORT_SYMBOL(dma_set_coherent_mask);
-
-void __init ixp4xx_init_early(void)
-{
-	platform_notify = ixp4xx_platform_notify;
-#ifdef CONFIG_PCI
-	platform_notify_remove = ixp4xx_platform_notify_remove;
-#endif
-}
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index 9478eccd1c8e..559461a826ba 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -745,7 +745,6 @@ int dma_set_mask(struct device *dev, u64 mask)
 }
 EXPORT_SYMBOL(dma_set_mask);
 
-#ifndef CONFIG_ARCH_HAS_DMA_SET_COHERENT_MASK
 int dma_set_coherent_mask(struct device *dev, u64 mask)
 {
 	/*
@@ -761,7 +760,6 @@ int dma_set_coherent_mask(struct device *dev, u64 mask)
 	return 0;
 }
 EXPORT_SYMBOL(dma_set_coherent_mask);
-#endif
 
 size_t dma_max_mapping_size(struct device *dev)
 {
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:56 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:56 +0100
Subject: [PATCH 13/13] ARM: ixp4xx: Convert to SPARSE_IRQ and P2V
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-14-linus.walleij@linaro.org>

Turn on sparse IRQs and patch-physical-to-virtual for IXP4xx
as this is required for multiplatform. Drop the PHYS_OFFSET as
we are now using P2V.

Tested and works like a charm on my systems.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/Kconfig | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ec0dbaf73a81..02df28b3ee7e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -263,7 +263,7 @@ config PHYS_OFFSET
 	hex "Physical address of main memory" if MMU
 	depends on !ARM_PATCH_PHYS_VIRT
 	default DRAM_BASE if !MMU
-	default 0x00000000 if ARCH_FOOTBRIDGE || ARCH_IXP4XX
+	default 0x00000000 if ARCH_FOOTBRIDGE
 	default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
 	default 0x30000000 if ARCH_S3C24XX
 	default 0xa0000000 if ARCH_IOP32X || ARCH_PXA
@@ -379,6 +379,7 @@ config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	depends on MMU
 	select ARCH_SUPPORTS_BIG_ENDIAN
+	select ARM_PATCH_PHYS_VIRT
 	select CPU_XSCALE
 	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIO_IXP4XX
@@ -386,6 +387,7 @@ config ARCH_IXP4XX
 	select HAVE_PCI
 	select IXP4XX_IRQ
 	select IXP4XX_TIMER
+	select SPARSE_IRQ
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	help
-- 
2.34.1



From linus.walleij at linaro.org  Wed Jan 26 16:36:55 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Thu, 27 Jan 2022 01:36:55 +0100
Subject: [PATCH 12/13] ARM: ixp4xx: Drop all common code
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <20220127003656.330161-13-linus.walleij@linaro.org>

After moving away from all the code we depend on in common we can
get a clean device tree boot and delete the common code in
arch/arm/mach-ixp4xx/common.c altogether.

Two physical register addresses remain in use, just copy these
verbatim into uncompress.h.

Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
 arch/arm/mach-ixp4xx/Makefile                 |   2 +-
 arch/arm/mach-ixp4xx/common.c                 | 331 ------------------
 arch/arm/mach-ixp4xx/include/mach/hardware.h  |  26 --
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    | 303 ----------------
 arch/arm/mach-ixp4xx/include/mach/platform.h  |  98 ------
 .../arm/mach-ixp4xx/include/mach/uncompress.h |   4 +-
 arch/arm/mach-ixp4xx/irqs.h                   |  64 ----
 drivers/crypto/ixp4xx_crypto.c                |   1 -
 drivers/net/ethernet/xscale/ptp_ixp46x.c      |   1 -
 9 files changed, 4 insertions(+), 826 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/common.c
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/hardware.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/platform.h
 delete mode 100644 arch/arm/mach-ixp4xx/irqs.h

diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 4ebe35227bf6..3d1c9d854c7f 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -1,2 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-y	+= ixp4xx-of.o common.o
+obj-y	+= ixp4xx-of.o
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
deleted file mode 100644
index 310e1602fbfc..000000000000
--- a/arch/arm/mach-ixp4xx/common.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/common.c
- *
- * Generic code shared across all IXP4XX platforms
- *
- * Maintainer: Deepak Saxena <dsaxena at plexity.net>
- *
- * Copyright 2002 (c) Intel Corporation
- * Copyright 2003-2004 (c) MontaVista, Software, Inc. 
- * 
- * This file is licensed under  the terms of the GNU General Public 
- * License version 2. This program is licensed "as is" without any 
- * warranty of any kind, whether express or implied.
- */
-
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/platform_device.h>
-#include <linux/serial_core.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/io.h>
-#include <linux/export.h>
-#include <linux/cpu.h>
-#include <linux/pci.h>
-#include <linux/sched_clock.h>
-#include <linux/soc/ixp4xx/cpu.h>
-#include <linux/irqchip/irq-ixp4xx.h>
-#include <linux/platform_data/timer-ixp4xx.h>
-#include <mach/hardware.h>
-#include <linux/uaccess.h>
-#include <asm/page.h>
-#include <asm/exception.h>
-#include <asm/irq.h>
-#include <asm/system_misc.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#include "irqs.h"
-
-#define IXP4XX_TIMER_FREQ 66666000
-
-/*************************************************************************
- * IXP4xx chipset I/O mapping
- *************************************************************************/
-static struct map_desc ixp4xx_io_desc[] __initdata = {
-	{	/* UART, Interrupt ctrl, GPIO, timers, NPEs, MACs, USB .... */
-		.virtual	= (unsigned long)IXP4XX_PERIPHERAL_BASE_VIRT,
-		.pfn		= __phys_to_pfn(IXP4XX_PERIPHERAL_BASE_PHYS),
-		.length		= IXP4XX_PERIPHERAL_REGION_SIZE,
-		.type		= MT_DEVICE
-	}, {	/* Expansion Bus Config Registers */
-		.virtual	= (unsigned long)IXP4XX_EXP_CFG_BASE_VIRT,
-		.pfn		= __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
-		.length		= IXP4XX_EXP_CFG_REGION_SIZE,
-		.type		= MT_DEVICE
-	}, {	/* PCI Registers */
-		.virtual	= (unsigned long)IXP4XX_PCI_CFG_BASE_VIRT,
-		.pfn		= __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
-		.length		= IXP4XX_PCI_CFG_REGION_SIZE,
-		.type		= MT_DEVICE
-	},
-};
-
-void __init ixp4xx_map_io(void)
-{
-  	iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
-}
-
-void __init ixp4xx_init_irq(void)
-{
-	/*
-	 * ixp4xx does not implement the XScale PWRMODE register
-	 * so it must not call cpu_do_idle().
-	 */
-	cpu_idle_poll_ctrl(true);
-
-	ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
-			(cpu_is_ixp46x() || cpu_is_ixp43x()));
-}
-
-void __init ixp4xx_timer_init(void)
-{
-	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
-				  IRQ_IXP4XX_TIMER1,
-				  IXP4XX_TIMER_FREQ);
-}
-
-static struct resource ixp4xx_udc_resources[] = {
-	[0] = {
-		.start  = 0xc800b000,
-		.end    = 0xc800bfff,
-		.flags  = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start  = IRQ_IXP4XX_USB,
-		.end    = IRQ_IXP4XX_USB,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource ixp4xx_gpio_resource[] = {
-	{
-		.start = IXP4XX_GPIO_BASE_PHYS,
-		.end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device ixp4xx_gpio_device = {
-	.name           = "ixp4xx-gpio",
-	.id             = -1,
-	.dev = {
-		.coherent_dma_mask      = DMA_BIT_MASK(32),
-	},
-	.resource = ixp4xx_gpio_resource,
-	.num_resources  = ARRAY_SIZE(ixp4xx_gpio_resource),
-};
-
-/*
- * USB device controller. The IXP4xx uses the same controller as PXA25X,
- * so we just use the same device.
- */
-static struct platform_device ixp4xx_udc_device = {
-	.name           = "pxa25x-udc",
-	.id             = -1,
-	.num_resources  = 2,
-	.resource       = ixp4xx_udc_resources,
-};
-
-static struct resource ixp4xx_npe_resources[] = {
-	{
-		.start = IXP4XX_NPEA_BASE_PHYS,
-		.end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IXP4XX_NPEB_BASE_PHYS,
-		.end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IXP4XX_NPEC_BASE_PHYS,
-		.end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
-		.flags = IORESOURCE_MEM,
-	},
-
-};
-
-static struct platform_device ixp4xx_npe_device = {
-	.name           = "ixp4xx-npe",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(ixp4xx_npe_resources),
-	.resource       = ixp4xx_npe_resources,
-};
-
-static struct resource ixp4xx_qmgr_resources[] = {
-	{
-		.start = IXP4XX_QMGR_BASE_PHYS,
-		.end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
-		.flags = IORESOURCE_MEM,
-	},
-	{
-		.start = IRQ_IXP4XX_QM1,
-		.end = IRQ_IXP4XX_QM1,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = IRQ_IXP4XX_QM2,
-		.end = IRQ_IXP4XX_QM2,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device ixp4xx_qmgr_device = {
-	.name           = "ixp4xx-qmgr",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(ixp4xx_qmgr_resources),
-	.resource       = ixp4xx_qmgr_resources,
-};
-
-static struct platform_device *ixp4xx_devices[] __initdata = {
-	&ixp4xx_npe_device,
-	&ixp4xx_qmgr_device,
-	&ixp4xx_gpio_device,
-	&ixp4xx_udc_device,
-};
-
-static struct resource ixp46x_i2c_resources[] = {
-	[0] = {
-		.start 	= 0xc8011000,
-		.end	= 0xc801101c,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start 	= IRQ_IXP4XX_I2C,
-		.end	= IRQ_IXP4XX_I2C,
-		.flags	= IORESOURCE_IRQ
-	}
-};
-
-/* A single 32-bit register on IXP46x */
-#define IXP4XX_HWRANDOM_BASE_PHYS	0x70002100
-
-static struct resource ixp46x_hwrandom_resource[] = {
-	{
-		.start = IXP4XX_HWRANDOM_BASE_PHYS,
-		.end = IXP4XX_HWRANDOM_BASE_PHYS + 0x3,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device ixp46x_hwrandom_device = {
-	.name           = "ixp4xx-hwrandom",
-	.id             = -1,
-	.dev = {
-		.coherent_dma_mask      = DMA_BIT_MASK(32),
-	},
-	.resource = ixp46x_hwrandom_resource,
-	.num_resources  = ARRAY_SIZE(ixp46x_hwrandom_resource),
-};
-
-/*
- * I2C controller. The IXP46x uses the same block as the IOP3xx, so
- * we just use the same device name.
- */
-static struct platform_device ixp46x_i2c_controller = {
-	.name		= "IOP3xx-I2C",
-	.id		= 0,
-	.num_resources	= 2,
-	.resource	= ixp46x_i2c_resources
-};
-
-static struct resource ixp46x_ptp_resources[] = {
-	DEFINE_RES_MEM(IXP4XX_TIMESYNC_BASE_PHYS, SZ_4K),
-	DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO8, "master"),
-	DEFINE_RES_IRQ_NAMED(IRQ_IXP4XX_GPIO7, "slave"),
-};
-
-static struct platform_device ixp46x_ptp = {
-	.name		= "ptp-ixp46x",
-	.id		= -1,
-	.resource	= ixp46x_ptp_resources,
-	.num_resources	= ARRAY_SIZE(ixp46x_ptp_resources),
-};
-
-static struct platform_device *ixp46x_devices[] __initdata = {
-	&ixp46x_hwrandom_device,
-	&ixp46x_i2c_controller,
-	&ixp46x_ptp,
-};
-
-unsigned long ixp4xx_exp_bus_size;
-EXPORT_SYMBOL(ixp4xx_exp_bus_size);
-
-static struct platform_device_info ixp_dev_info __initdata = {
-	.name		= "ixp4xx_crypto",
-	.id		= 0,
-	.dma_mask	= DMA_BIT_MASK(32),
-};
-
-static int __init ixp_crypto_register(void)
-{
-	struct platform_device *pdev;
-
-	if (!(~(*IXP4XX_EXP_CFG2) & (IXP4XX_FEATURE_HASH |
-				IXP4XX_FEATURE_AES | IXP4XX_FEATURE_DES))) {
-		printk(KERN_ERR "ixp_crypto: No HW crypto available\n");
-		return -ENODEV;
-	}
-
-	pdev = platform_device_register_full(&ixp_dev_info);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	return 0;
-}
-
-void __init ixp4xx_sys_init(void)
-{
-	ixp4xx_exp_bus_size = SZ_16M;
-
-	platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
-
-	if (IS_ENABLED(CONFIG_CRYPTO_DEV_IXP4XX))
-		ixp_crypto_register();
-
-	if (cpu_is_ixp46x()) {
-		int region;
-
-		platform_add_devices(ixp46x_devices,
-				ARRAY_SIZE(ixp46x_devices));
-
-		for (region = 0; region < 7; region++) {
-			if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) {
-				ixp4xx_exp_bus_size = SZ_32M;
-				break;
-			}
-		}
-	}
-
-	printk("IXP4xx: Using %luMiB expansion bus window size\n",
-			ixp4xx_exp_bus_size >> 20);
-}
-
-unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
-EXPORT_SYMBOL(ixp4xx_timer_freq);
-
-void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
-{
-	if (mode == REBOOT_SOFT) {
-		/* Jump into ROM at address 0 */
-		soft_restart(0);
-	} else {
-		/* Use on-chip reset capability */
-
-		/* set the "key" register to enable access to
-		 * "timer" and "enable" registers
-		 */
-		*IXP4XX_OSWK = IXP4XX_WDT_KEY;
-
-		/* write 0 to the timer register for an immediate reset */
-		*IXP4XX_OSWT = 0;
-
-		*IXP4XX_OSWE = IXP4XX_WDT_RESET_ENABLE | IXP4XX_WDT_COUNT_ENABLE;
-	}
-}
diff --git a/arch/arm/mach-ixp4xx/include/mach/hardware.h b/arch/arm/mach-ixp4xx/include/mach/hardware.h
deleted file mode 100644
index 41f28fb8e63f..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/hardware.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/hardware.h 
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-/*
- * Hardware definitions for IXP4xx based systems
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#define __ASM_ARCH_HARDWARE_H__
-
-/* Register locations and bits */
-#include "ixp4xx-regs.h"
-
-#ifndef __ASSEMBLER__
-#include <linux/soc/ixp4xx/cpu.h>
-#endif
-
-/* Platform helper functions and definitions */
-#include "platform.h"
-
-#endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
deleted file mode 100644
index 74e63d4531aa..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
- *
- * Register definitions for IXP4xx chipset. This file contains 
- * register location and bit definitions only. Platform specific 
- * definitions and helper function declarations are in platform.h 
- * and machine-name.h.
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- */
-
-#ifndef _ASM_ARM_IXP4XX_H_
-#define _ASM_ARM_IXP4XX_H_
-
-/*
- * IXP4xx Linux Memory Map:
- *
- * Phy		Size		Virt		Description
- * =========================================================================
- *
- * 0x00000000	0x10000000(max)	PAGE_OFFSET	System RAM
- *
- * 0x48000000	0x04000000	ioremap'd	PCI Memory Space
- *
- * 0x50000000	0x10000000	ioremap'd	EXP BUS
- *
- * 0xC8000000	0x00013000	0xFEF00000	On-Chip Peripherals
- *
- * 0xC0000000	0x00001000	0xFEF13000	PCI CFG
- *
- * 0xC4000000	0x00001000	0xFEF14000	EXP CFG
- *
- * 0x60000000	0x00004000	0xFEF15000	QMgr
- */
-
-/*
- * Queue Manager
- */
-#define IXP4XX_QMGR_BASE_PHYS		0x60000000
-
-/*
- * Peripheral space, including debug UART. Must be section-aligned so that
- * it can be used with the low-level debug code.
- */
-#define IXP4XX_PERIPHERAL_BASE_PHYS	0xC8000000
-#define IXP4XX_PERIPHERAL_BASE_VIRT	IOMEM(0xFEC00000)
-#define IXP4XX_PERIPHERAL_REGION_SIZE	0x00013000
-
-/*
- * PCI Config registers
- */
-#define IXP4XX_PCI_CFG_BASE_PHYS	0xC0000000
-#define IXP4XX_PCI_CFG_BASE_VIRT	IOMEM(0xFEC13000)
-#define IXP4XX_PCI_CFG_REGION_SIZE	0x00001000
-
-/*
- * Expansion BUS Configuration registers
- */
-#define IXP4XX_EXP_CFG_BASE_PHYS	0xC4000000
-#define IXP4XX_EXP_CFG_BASE_VIRT	0xFEC14000
-#define IXP4XX_EXP_CFG_REGION_SIZE	0x00001000
-
-#define IXP4XX_EXP_CS0_OFFSET	0x00
-#define IXP4XX_EXP_CS1_OFFSET   0x04
-#define IXP4XX_EXP_CS2_OFFSET   0x08
-#define IXP4XX_EXP_CS3_OFFSET   0x0C
-#define IXP4XX_EXP_CS4_OFFSET   0x10
-#define IXP4XX_EXP_CS5_OFFSET   0x14
-#define IXP4XX_EXP_CS6_OFFSET   0x18
-#define IXP4XX_EXP_CS7_OFFSET   0x1C
-#define IXP4XX_EXP_CFG0_OFFSET	0x20
-#define IXP4XX_EXP_CFG1_OFFSET	0x24
-#define IXP4XX_EXP_CFG2_OFFSET	0x28
-#define IXP4XX_EXP_CFG3_OFFSET	0x2C
-
-/*
- * Expansion Bus Controller registers.
- */
-#define IXP4XX_EXP_REG(x) ((volatile u32 __iomem *)(IXP4XX_EXP_CFG_BASE_VIRT+(x)))
-
-#define IXP4XX_EXP_CS0      IXP4XX_EXP_REG(IXP4XX_EXP_CS0_OFFSET)
-#define IXP4XX_EXP_CS1      IXP4XX_EXP_REG(IXP4XX_EXP_CS1_OFFSET)
-#define IXP4XX_EXP_CS2      IXP4XX_EXP_REG(IXP4XX_EXP_CS2_OFFSET) 
-#define IXP4XX_EXP_CS3      IXP4XX_EXP_REG(IXP4XX_EXP_CS3_OFFSET)
-#define IXP4XX_EXP_CS4      IXP4XX_EXP_REG(IXP4XX_EXP_CS4_OFFSET)
-#define IXP4XX_EXP_CS5      IXP4XX_EXP_REG(IXP4XX_EXP_CS5_OFFSET)
-#define IXP4XX_EXP_CS6      IXP4XX_EXP_REG(IXP4XX_EXP_CS6_OFFSET)     
-#define IXP4XX_EXP_CS7      IXP4XX_EXP_REG(IXP4XX_EXP_CS7_OFFSET)
-
-#define IXP4XX_EXP_CFG0     IXP4XX_EXP_REG(IXP4XX_EXP_CFG0_OFFSET) 
-#define IXP4XX_EXP_CFG1     IXP4XX_EXP_REG(IXP4XX_EXP_CFG1_OFFSET) 
-#define IXP4XX_EXP_CFG2     IXP4XX_EXP_REG(IXP4XX_EXP_CFG2_OFFSET) 
-#define IXP4XX_EXP_CFG3     IXP4XX_EXP_REG(IXP4XX_EXP_CFG3_OFFSET)
-
-
-/*
- * Peripheral Space Register Region Base Addresses
- */
-#define IXP4XX_UART1_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x0000)
-#define IXP4XX_UART2_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x1000)
-#define IXP4XX_PMU_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x2000)
-#define IXP4XX_INTC_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x3000)
-#define IXP4XX_GPIO_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x4000)
-#define IXP4XX_TIMER_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x5000)
-#define IXP4XX_NPEA_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000)
-#define IXP4XX_NPEB_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000)
-#define IXP4XX_NPEC_BASE_PHYS   	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000)
-#define IXP4XX_EthB_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x9000)
-#define IXP4XX_EthC_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xA000)
-#define IXP4XX_USB_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xC000)
-#define IXP4XX_EthB1_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xD000)
-#define IXP4XX_EthB2_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xE000)
-#define IXP4XX_EthB3_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_PHYS	(IXP4XX_PERIPHERAL_BASE_PHYS + 0x10000)
-#define IXP4XX_I2C_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x11000)
-#define IXP4XX_SSP_BASE_PHYS		(IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000)
-
-
-/* The UART is explicitly put in the beginning of fixmap */
-#define IXP4XX_UART1_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000)
-#define IXP4XX_UART2_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000)
-#define IXP4XX_PMU_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000)
-#define IXP4XX_INTC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
-#define IXP4XX_GPIO_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
-#define IXP4XX_TIMER_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_EthB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
-#define IXP4XX_EthC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
-#define IXP4XX_USB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
-/* ixp46X only */
-#define IXP4XX_EthA_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xC000)
-#define IXP4XX_EthB1_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xD000)
-#define IXP4XX_EthB2_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xE000)
-#define IXP4XX_EthB3_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xF000)
-#define IXP4XX_TIMESYNC_BASE_VIRT	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x10000)
-#define IXP4XX_I2C_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
-#define IXP4XX_SSP_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
-
-/*
- * Constants to make it easy to access Timer Control/Status registers
- */
-#define IXP4XX_OSTS_OFFSET	0x00  /* Continious TimeStamp */
-#define IXP4XX_OST1_OFFSET	0x04  /* Timer 1 Timestamp */
-#define IXP4XX_OSRT1_OFFSET	0x08  /* Timer 1 Reload */
-#define IXP4XX_OST2_OFFSET	0x0C  /* Timer 2 Timestamp */
-#define IXP4XX_OSRT2_OFFSET	0x10  /* Timer 2 Reload */
-#define IXP4XX_OSWT_OFFSET	0x14  /* Watchdog Timer */
-#define IXP4XX_OSWE_OFFSET	0x18  /* Watchdog Enable */
-#define IXP4XX_OSWK_OFFSET	0x1C  /* Watchdog Key */
-#define IXP4XX_OSST_OFFSET	0x20  /* Timer Status */
-
-/*
- * Operating System Timer Register Definitions.
- */
-
-#define IXP4XX_TIMER_REG(x) ((volatile u32 *)(IXP4XX_TIMER_BASE_VIRT+(x)))
-
-#define IXP4XX_OSTS	IXP4XX_TIMER_REG(IXP4XX_OSTS_OFFSET)
-#define IXP4XX_OST1	IXP4XX_TIMER_REG(IXP4XX_OST1_OFFSET)
-#define IXP4XX_OSRT1	IXP4XX_TIMER_REG(IXP4XX_OSRT1_OFFSET)
-#define IXP4XX_OST2	IXP4XX_TIMER_REG(IXP4XX_OST2_OFFSET)
-#define IXP4XX_OSRT2	IXP4XX_TIMER_REG(IXP4XX_OSRT2_OFFSET)
-#define IXP4XX_OSWT	IXP4XX_TIMER_REG(IXP4XX_OSWT_OFFSET)
-#define IXP4XX_OSWE	IXP4XX_TIMER_REG(IXP4XX_OSWE_OFFSET)
-#define IXP4XX_OSWK	IXP4XX_TIMER_REG(IXP4XX_OSWK_OFFSET)
-#define IXP4XX_OSST	IXP4XX_TIMER_REG(IXP4XX_OSST_OFFSET)
-
-/*
- * Timer register values and bit definitions 
- */
-#define IXP4XX_OST_ENABLE		0x00000001
-#define IXP4XX_OST_ONE_SHOT		0x00000002
-/* Low order bits of reload value ignored */
-#define IXP4XX_OST_RELOAD_MASK		0x00000003
-#define IXP4XX_OST_DISABLED		0x00000000
-#define IXP4XX_OSST_TIMER_1_PEND	0x00000001
-#define IXP4XX_OSST_TIMER_2_PEND	0x00000002
-#define IXP4XX_OSST_TIMER_TS_PEND	0x00000004
-#define IXP4XX_OSST_TIMER_WDOG_PEND	0x00000008
-#define IXP4XX_OSST_TIMER_WARM_RESET	0x00000010
-
-#define	IXP4XX_WDT_KEY			0x0000482E
-
-#define	IXP4XX_WDT_RESET_ENABLE		0x00000001
-#define	IXP4XX_WDT_IRQ_ENABLE		0x00000002
-#define	IXP4XX_WDT_COUNT_ENABLE		0x00000004
-
-
-/*
- * Constants to make it easy to access PCI Control/Status registers
- */
-#define PCI_NP_AD_OFFSET            0x00
-#define PCI_NP_CBE_OFFSET           0x04
-#define PCI_NP_WDATA_OFFSET         0x08
-#define PCI_NP_RDATA_OFFSET         0x0c
-#define PCI_CRP_AD_CBE_OFFSET       0x10
-#define PCI_CRP_WDATA_OFFSET        0x14
-#define PCI_CRP_RDATA_OFFSET        0x18
-#define PCI_CSR_OFFSET              0x1c
-#define PCI_ISR_OFFSET              0x20
-#define PCI_INTEN_OFFSET            0x24
-#define PCI_DMACTRL_OFFSET          0x28
-#define PCI_AHBMEMBASE_OFFSET       0x2c
-#define PCI_AHBIOBASE_OFFSET        0x30
-#define PCI_PCIMEMBASE_OFFSET       0x34
-#define PCI_AHBDOORBELL_OFFSET      0x38
-#define PCI_PCIDOORBELL_OFFSET      0x3C
-#define PCI_ATPDMA0_AHBADDR_OFFSET  0x40
-#define PCI_ATPDMA0_PCIADDR_OFFSET  0x44
-#define PCI_ATPDMA0_LENADDR_OFFSET  0x48
-#define PCI_ATPDMA1_AHBADDR_OFFSET  0x4C
-#define PCI_ATPDMA1_PCIADDR_OFFSET  0x50
-#define PCI_ATPDMA1_LENADDR_OFFSET	0x54
-
-/*
- * PCI Control/Status Registers
- */
-#define _IXP4XX_PCI_CSR(x) ((volatile u32 *)(IXP4XX_PCI_CFG_BASE_VIRT+(x)))
-
-#define PCI_NP_AD               _IXP4XX_PCI_CSR(PCI_NP_AD_OFFSET)
-#define PCI_NP_CBE              _IXP4XX_PCI_CSR(PCI_NP_CBE_OFFSET)
-#define PCI_NP_WDATA            _IXP4XX_PCI_CSR(PCI_NP_WDATA_OFFSET)
-#define PCI_NP_RDATA            _IXP4XX_PCI_CSR(PCI_NP_RDATA_OFFSET)
-#define PCI_CRP_AD_CBE          _IXP4XX_PCI_CSR(PCI_CRP_AD_CBE_OFFSET)
-#define PCI_CRP_WDATA           _IXP4XX_PCI_CSR(PCI_CRP_WDATA_OFFSET)
-#define PCI_CRP_RDATA           _IXP4XX_PCI_CSR(PCI_CRP_RDATA_OFFSET)
-#define PCI_CSR                 _IXP4XX_PCI_CSR(PCI_CSR_OFFSET) 
-#define PCI_ISR                 _IXP4XX_PCI_CSR(PCI_ISR_OFFSET)
-#define PCI_INTEN               _IXP4XX_PCI_CSR(PCI_INTEN_OFFSET)
-#define PCI_DMACTRL             _IXP4XX_PCI_CSR(PCI_DMACTRL_OFFSET)
-#define PCI_AHBMEMBASE          _IXP4XX_PCI_CSR(PCI_AHBMEMBASE_OFFSET)
-#define PCI_AHBIOBASE           _IXP4XX_PCI_CSR(PCI_AHBIOBASE_OFFSET)
-#define PCI_PCIMEMBASE          _IXP4XX_PCI_CSR(PCI_PCIMEMBASE_OFFSET)
-#define PCI_AHBDOORBELL         _IXP4XX_PCI_CSR(PCI_AHBDOORBELL_OFFSET)
-#define PCI_PCIDOORBELL         _IXP4XX_PCI_CSR(PCI_PCIDOORBELL_OFFSET)
-#define PCI_ATPDMA0_AHBADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA0_AHBADDR_OFFSET)
-#define PCI_ATPDMA0_PCIADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA0_PCIADDR_OFFSET)
-#define PCI_ATPDMA0_LENADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA0_LENADDR_OFFSET)
-#define PCI_ATPDMA1_AHBADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA1_AHBADDR_OFFSET)
-#define PCI_ATPDMA1_PCIADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA1_PCIADDR_OFFSET)
-#define PCI_ATPDMA1_LENADDR     _IXP4XX_PCI_CSR(PCI_ATPDMA1_LENADDR_OFFSET)
-
-/*
- * PCI register values and bit definitions 
- */
-
-/* CSR bit definitions */
-#define PCI_CSR_HOST    	0x00000001
-#define PCI_CSR_ARBEN   	0x00000002
-#define PCI_CSR_ADS     	0x00000004
-#define PCI_CSR_PDS     	0x00000008
-#define PCI_CSR_ABE     	0x00000010
-#define PCI_CSR_DBT     	0x00000020
-#define PCI_CSR_ASE     	0x00000100
-#define PCI_CSR_IC      	0x00008000
-
-/* ISR (Interrupt status) Register bit definitions */
-#define PCI_ISR_PSE     	0x00000001
-#define PCI_ISR_PFE     	0x00000002
-#define PCI_ISR_PPE     	0x00000004
-#define PCI_ISR_AHBE    	0x00000008
-#define PCI_ISR_APDC    	0x00000010
-#define PCI_ISR_PADC    	0x00000020
-#define PCI_ISR_ADB     	0x00000040
-#define PCI_ISR_PDB     	0x00000080
-
-/* INTEN (Interrupt Enable) Register bit definitions */
-#define PCI_INTEN_PSE   	0x00000001
-#define PCI_INTEN_PFE   	0x00000002
-#define PCI_INTEN_PPE   	0x00000004
-#define PCI_INTEN_AHBE  	0x00000008
-#define PCI_INTEN_APDC  	0x00000010
-#define PCI_INTEN_PADC  	0x00000020
-#define PCI_INTEN_ADB   	0x00000040
-#define PCI_INTEN_PDB   	0x00000080
-
-/*
- * Shift value for byte enable on NP cmd/byte enable register
- */
-#define IXP4XX_PCI_NP_CBE_BESL		4
-
-/*
- * PCI commands supported by NP access unit
- */
-#define NP_CMD_IOREAD			0x2
-#define NP_CMD_IOWRITE			0x3
-#define NP_CMD_CONFIGREAD		0xa
-#define NP_CMD_CONFIGWRITE		0xb
-#define NP_CMD_MEMREAD			0x6
-#define	NP_CMD_MEMWRITE			0x7
-
-/*
- * Constants for CRP access into local config space
- */
-#define CRP_AD_CBE_BESL         20
-#define CRP_AD_CBE_WRITE	0x00010000
-
-#define DCMD_LENGTH	0x01fff		/* length mask (max = 8K - 1) */
-
-#endif
diff --git a/arch/arm/mach-ixp4xx/include/mach/platform.h b/arch/arm/mach-ixp4xx/include/mach/platform.h
deleted file mode 100644
index f9ec07f00be0..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/platform.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-ixp4xx/include/mach/platform.h
- *
- * Constants and functions that are useful to IXP4xx platform-specific code
- * and device drivers.
- *
- * Copyright (C) 2004 MontaVista Software, Inc.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <mach/hardware.h>"
-#endif
-
-#ifndef __ASSEMBLY__
-
-#include <linux/reboot.h>
-#include <linux/platform_data/eth_ixp4xx.h>
-
-#include <asm/types.h>
-
-#ifndef	__ARMEB__
-#define	REG_OFFSET	0
-#else
-#define	REG_OFFSET	3
-#endif
-
-/*
- * Expansion bus memory regions
- */
-#define IXP4XX_EXP_BUS_BASE_PHYS	(0x50000000)
-
-/*
- * The expansion bus on the IXP4xx can be configured for either 16 or
- * 32MB windows and the CS offset for each region changes based on the
- * current configuration. This means that we cannot simply hardcode
- * each offset. ixp4xx_sys_init() looks at the expansion bus configuration
- * as setup by the bootloader to determine our window size.
- */
-extern unsigned long ixp4xx_exp_bus_size;
-
-#define	IXP4XX_EXP_BUS_BASE(region)\
-		(IXP4XX_EXP_BUS_BASE_PHYS + ((region) * ixp4xx_exp_bus_size))
-
-#define IXP4XX_EXP_BUS_END(region)\
-		(IXP4XX_EXP_BUS_BASE(region) + ixp4xx_exp_bus_size - 1)
-
-/* Those macros can be used to adjust timing and configure
- * other features for each region.
- */
-
-#define IXP4XX_EXP_BUS_RECOVERY_T(x)	(((x) & 0x0f) << 16)
-#define IXP4XX_EXP_BUS_HOLD_T(x)	(((x) & 0x03) << 20)
-#define IXP4XX_EXP_BUS_STROBE_T(x)	(((x) & 0x0f) << 22)
-#define IXP4XX_EXP_BUS_SETUP_T(x)	(((x) & 0x03) << 26)
-#define IXP4XX_EXP_BUS_ADDR_T(x)	(((x) & 0x03) << 28)
-#define IXP4XX_EXP_BUS_SIZE(x)		(((x) & 0x0f) << 10)
-#define IXP4XX_EXP_BUS_CYCLES(x)	(((x) & 0x03) << 14)
-
-#define IXP4XX_EXP_BUS_CS_EN		(1L << 31)
-#define IXP4XX_EXP_BUS_BYTE_RD16	(1L << 6)
-#define IXP4XX_EXP_BUS_HRDY_POL		(1L << 5)
-#define IXP4XX_EXP_BUS_MUX_EN		(1L << 4)
-#define IXP4XX_EXP_BUS_SPLT_EN		(1L << 3)
-#define IXP4XX_EXP_BUS_WR_EN		(1L << 1)
-#define IXP4XX_EXP_BUS_BYTE_EN		(1L << 0)
-
-#define IXP4XX_EXP_BUS_CYCLES_INTEL	0x00
-#define IXP4XX_EXP_BUS_CYCLES_MOTOROLA	0x01
-#define IXP4XX_EXP_BUS_CYCLES_HPI	0x02
-
-#define IXP4XX_FLASH_WRITABLE	(0x2)
-#define IXP4XX_FLASH_DEFAULT	(0xbcd23c40)
-#define IXP4XX_FLASH_WRITE	(0xbcd23c42)
-
-/*
- * Clock Speed Definitions.
- */
-#define IXP4XX_PERIPHERAL_BUS_CLOCK 	(66) /* 66MHzi APB BUS   */ 
-#define IXP4XX_UART_XTAL        	14745600
-
-/*
- * Frequency of clock used for primary clocksource
- */
-extern unsigned long ixp4xx_timer_freq;
-
-/*
- * Functions used by platform-level setup code
- */
-extern void ixp4xx_map_io(void);
-extern void ixp4xx_init_early(void);
-extern void ixp4xx_init_irq(void);
-extern void ixp4xx_sys_init(void);
-extern void ixp4xx_timer_init(void);
-extern void ixp4xx_restart(enum reboot_mode, const char *);
-
-#endif // __ASSEMBLY__
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/uncompress.h b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
index 9e08b270cfc7..09e7663e6a55 100644
--- a/arch/arm/mach-ixp4xx/include/mach/uncompress.h
+++ b/arch/arm/mach-ixp4xx/include/mach/uncompress.h
@@ -9,10 +9,12 @@
 #ifndef _ARCH_UNCOMPRESS_H_
 #define _ARCH_UNCOMPRESS_H_
 
-#include "ixp4xx-regs.h"
 #include <asm/mach-types.h>
 #include <linux/serial_reg.h>
 
+#define IXP4XX_UART1_BASE_PHYS 0xc8000000
+#define IXP4XX_UART2_BASE_PHYS 0xc8001000
+
 #define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
 
 volatile u32* uart_base;
diff --git a/arch/arm/mach-ixp4xx/irqs.h b/arch/arm/mach-ixp4xx/irqs.h
deleted file mode 100644
index a3e8d6408c56..000000000000
--- a/arch/arm/mach-ixp4xx/irqs.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ixp4xx/include/mach/irqs.h 
- *
- * IRQ definitions for IXP4XX based systems
- *
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003 MontaVista Software, Inc.
- */
-
-#ifndef _ARCH_IXP4XX_IRQS_H_
-#define _ARCH_IXP4XX_IRQS_H_
-
-#define IRQ_IXP4XX_BASE		16
-
-#define IRQ_IXP4XX_NPEA		(IRQ_IXP4XX_BASE + 0)
-#define IRQ_IXP4XX_NPEB		(IRQ_IXP4XX_BASE + 1)
-#define IRQ_IXP4XX_NPEC		(IRQ_IXP4XX_BASE + 2)
-#define IRQ_IXP4XX_QM1		(IRQ_IXP4XX_BASE + 3)
-#define IRQ_IXP4XX_QM2		(IRQ_IXP4XX_BASE + 4)
-#define IRQ_IXP4XX_TIMER1	(IRQ_IXP4XX_BASE + 5)
-#define IRQ_IXP4XX_GPIO0	(IRQ_IXP4XX_BASE + 6)
-#define IRQ_IXP4XX_GPIO1	(IRQ_IXP4XX_BASE + 7)
-#define IRQ_IXP4XX_PCI_INT	(IRQ_IXP4XX_BASE + 8)
-#define IRQ_IXP4XX_PCI_DMA1	(IRQ_IXP4XX_BASE + 9)
-#define IRQ_IXP4XX_PCI_DMA2	(IRQ_IXP4XX_BASE + 10)
-#define IRQ_IXP4XX_TIMER2	(IRQ_IXP4XX_BASE + 11)
-#define IRQ_IXP4XX_USB		(IRQ_IXP4XX_BASE + 12)
-#define IRQ_IXP4XX_UART2	(IRQ_IXP4XX_BASE + 13)
-#define IRQ_IXP4XX_TIMESTAMP	(IRQ_IXP4XX_BASE + 14)
-#define IRQ_IXP4XX_UART1	(IRQ_IXP4XX_BASE + 15)
-#define IRQ_IXP4XX_WDOG		(IRQ_IXP4XX_BASE + 16)
-#define IRQ_IXP4XX_AHB_PMU	(IRQ_IXP4XX_BASE + 17)
-#define IRQ_IXP4XX_XSCALE_PMU	(IRQ_IXP4XX_BASE + 18)
-#define IRQ_IXP4XX_GPIO2	(IRQ_IXP4XX_BASE + 19)
-#define IRQ_IXP4XX_GPIO3	(IRQ_IXP4XX_BASE + 20)
-#define IRQ_IXP4XX_GPIO4	(IRQ_IXP4XX_BASE + 21)
-#define IRQ_IXP4XX_GPIO5	(IRQ_IXP4XX_BASE + 22)
-#define IRQ_IXP4XX_GPIO6	(IRQ_IXP4XX_BASE + 23)
-#define IRQ_IXP4XX_GPIO7	(IRQ_IXP4XX_BASE + 24)
-#define IRQ_IXP4XX_GPIO8	(IRQ_IXP4XX_BASE + 25)
-#define IRQ_IXP4XX_GPIO9	(IRQ_IXP4XX_BASE + 26)
-#define IRQ_IXP4XX_GPIO10	(IRQ_IXP4XX_BASE + 27)
-#define IRQ_IXP4XX_GPIO11	(IRQ_IXP4XX_BASE + 28)
-#define IRQ_IXP4XX_GPIO12	(IRQ_IXP4XX_BASE + 29)
-#define IRQ_IXP4XX_SW_INT1	(IRQ_IXP4XX_BASE + 30)
-#define IRQ_IXP4XX_SW_INT2	(IRQ_IXP4XX_BASE + 31)
-#define IRQ_IXP4XX_USB_HOST	(IRQ_IXP4XX_BASE + 32)
-#define IRQ_IXP4XX_I2C		(IRQ_IXP4XX_BASE + 33)
-#define IRQ_IXP4XX_SSP		(IRQ_IXP4XX_BASE + 34)
-#define IRQ_IXP4XX_TSYNC	(IRQ_IXP4XX_BASE + 35)
-#define IRQ_IXP4XX_EAU_DONE	(IRQ_IXP4XX_BASE + 36)
-#define IRQ_IXP4XX_SHA_DONE	(IRQ_IXP4XX_BASE + 37)
-#define IRQ_IXP4XX_SWCP_PE	(IRQ_IXP4XX_BASE + 58)
-#define IRQ_IXP4XX_QM_PE	(IRQ_IXP4XX_BASE + 60)
-#define IRQ_IXP4XX_MCU_ECC	(IRQ_IXP4XX_BASE + 61)
-#define IRQ_IXP4XX_EXP_PE	(IRQ_IXP4XX_BASE + 62)
-
-#define _IXP4XX_GPIO_IRQ(n)	(IRQ_IXP4XX_GPIO ## n)
-#define IXP4XX_GPIO_IRQ(n)	_IXP4XX_GPIO_IRQ(n)
-
-#define	XSCALE_PMU_IRQ		(IRQ_IXP4XX_XSCALE_PMU)
-
-#endif
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 98730aab287c..d39a386b31ac 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -33,7 +33,6 @@
 
 /* Intermittent includes, delete this after v5.14-rc1 */
 #include <linux/soc/ixp4xx/cpu.h>
-#include <mach/ixp4xx-regs.h>
 
 #define MAX_KEYLEN 32
 
diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c
index 39234852e01b..1f382777aa5a 100644
--- a/drivers/net/ethernet/xscale/ptp_ixp46x.c
+++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c
@@ -16,7 +16,6 @@
 #include <linux/ptp_clock_kernel.h>
 #include <linux/platform_device.h>
 #include <linux/soc/ixp4xx/cpu.h>
-#include <mach/ixp4xx-regs.h>
 
 #include "ixp46x_ts.h"
 
-- 
2.34.1



From andre.przywara at arm.com  Wed Jan 26 16:53:04 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Thu, 27 Jan 2022 00:53:04 +0000
Subject: [PATCH] ARM: dts: suniv: Add MMC and clock macros.
In-Reply-To: <d69233d8-4e3d-56db-d4d3-1b39fe84ee30@gmail.com>
References: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
 <20220126235726.03abdab4@slackpad.fritz.box>
 <d69233d8-4e3d-56db-d4d3-1b39fe84ee30@gmail.com>
Message-ID: <20220127005304.06215ae8@slackpad.fritz.box>

On Wed, 26 Jan 2022 19:12:05 -0500
Jesse Taube <mr.bossman075 at gmail.com> wrote:

> On 1/26/22 18:57, Andre Przywara wrote:
> > On Mon, 24 Jan 2022 20:13:52 -0500
> > Jesse Taube <mr.bossman075 at gmail.com> wrote:
> > 
> > Hi Jesse,
> > 
> > I understand that get_maintainers.pl suggested this CC: list,  but you
> > should add sunxi people and linux-arm kernel ML. Doing that now.  
> Uh yeah that makes sense in hind sight.
> >> Include clock and reset macros and replace magic numbers.
> >> Add MMC node.  
> > 
> > This patch itself does not do much, does it? You would at least need to
> > enable that in the board dts.  
> True it doesn't do much just so that its in both u-boot and linux.
> > And this should be multiple patches:
> > 1) replace numbers with macros (part of this patch)
> > 2) Add the MMC compatible string combo to the the bindings doc
> > 3) Add the *two* MMC nodes and at least the pinctrl node for MMC0 to the
> > SoC .dtsi (partly in this patch)
> > 4) Enable the MMC and the card detect pin in the Nano board .dts
> > 
> > I checked that the macros names match the numbers they replace, so
> > you can add my R-b: on that patch 1 (if you follow my suggestion).
> > The MMC node also seems to look sane.  
> That seems okay.
> >>
> >> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>  
> > 
> > It is not evident why Mesih's S-o-b: is in here? The patch seems to be
> > authored and sent by you? Either you make him the author if that is his
> > patch originally, or you put him just as Cc: or in Suggested-by:, maybe.  
> I did write the patch after I wrote it I was looking at his github and 
> he had almost the same patch.

Yeah, not really surprising, there are only so many ways to write a DT.
I guess he never sent it, and since you wrote it, it's yours, so just
add him in Cc:, since he was involved in the F1C100s upstreaming.

Cheers,
Andre

> > Cheers,
> > Andre
> >   
> >> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> >> ---
> >>   arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 +++++++++++++++++++++++-----
> >>   1 file changed, 34 insertions(+), 7 deletions(-)
> >>
> >> diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >> index 6100d3b75f61..32872bb29917 100644
> >> --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >> +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >> @@ -4,6 +4,9 @@
> >>    * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
> >>    */
> >>   
> >> +#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
> >> +#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
> >> +
> >>   / {
> >>   	#address-cells = <1>;
> >>   	#size-cells = <1>;
> >> @@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
> >>   			compatible = "allwinner,suniv-f1c100s-pinctrl";
> >>   			reg = <0x01c20800 0x400>;
> >>   			interrupts = <38>, <39>, <40>;
> >> -			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
> >> +			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
> >>   			clock-names = "apb", "hosc", "losc";
> >>   			gpio-controller;
> >>   			interrupt-controller;
> >> @@ -93,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
> >>   				pins = "PE0", "PE1";
> >>   				function = "uart0";
> >>   			};
> >> +
> >> +			mmc0_pins: mmc0-pins {
> >> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
> >> +				function = "mmc0";
> >> +			};
> >>   		};
> >>   
> >>   		timer at 1c20c00 {
> >> @@ -108,14 +116,33 @@ wdt: watchdog at 1c20ca0 {
> >>   			reg = <0x01c20ca0 0x20>;
> >>   		};
> >>   
> >> +		mmc0: mmc at 1c0f000 {
> >> +			compatible = "allwinner,suniv-f1c100s-mmc",
> >> +				     "allwinner,sun7i-a20-mmc";
> >> +			reg = <0x01c0f000 0x1000>;
> >> +			clocks = <&ccu CLK_BUS_MMC0>,
> >> +				 <&ccu CLK_MMC0>,
> >> +				 <&ccu CLK_MMC0_OUTPUT>,
> >> +				 <&ccu CLK_MMC0_SAMPLE>;
> >> +			clock-names = "ahb", "mmc", "output", "sample";
> >> +			resets = <&ccu RST_BUS_MMC0>;
> >> +			reset-names = "ahb";
> >> +			interrupts = <23>;
> >> +			pinctrl-names = "default";
> >> +			pinctrl-0 = <&mmc0_pins>;
> >> +			status = "disabled";
> >> +			#address-cells = <1>;
> >> +			#size-cells = <0>;
> >> +		};
> >> +
> >>   		uart0: serial at 1c25000 {
> >>   			compatible = "snps,dw-apb-uart";
> >>   			reg = <0x01c25000 0x400>;
> >>   			interrupts = <1>;
> >>   			reg-shift = <2>;
> >>   			reg-io-width = <4>;
> >> -			clocks = <&ccu 38>;
> >> -			resets = <&ccu 24>;
> >> +			clocks = <&ccu CLK_BUS_UART0>;
> >> +			resets = <&ccu RST_BUS_UART0>;
> >>   			status = "disabled";
> >>   		};
> >>   
> >> @@ -125,8 +152,8 @@ uart1: serial at 1c25400 {
> >>   			interrupts = <2>;
> >>   			reg-shift = <2>;
> >>   			reg-io-width = <4>;
> >> -			clocks = <&ccu 39>;
> >> -			resets = <&ccu 25>;
> >> +			clocks = <&ccu CLK_BUS_UART1>;
> >> +			resets = <&ccu RST_BUS_UART1>;
> >>   			status = "disabled";
> >>   		};
> >>   
> >> @@ -136,8 +163,8 @@ uart2: serial at 1c25800 {
> >>   			interrupts = <3>;
> >>   			reg-shift = <2>;
> >>   			reg-io-width = <4>;
> >> -			clocks = <&ccu 40>;
> >> -			resets = <&ccu 26>;
> >> +			clocks = <&ccu CLK_BUS_UART2>;
> >> +			resets = <&ccu RST_BUS_UART2>;
> >>   			status = "disabled";
> >>   		};
> >>   	};  
> >   



From biao.huang at mediatek.com  Wed Jan 26 16:47:22 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 08:47:22 +0800
Subject: [PATCH net-next v1 1/9] net: ethernet: mtk-star-emac: store
 bit_clk_div in compat structure
In-Reply-To: <CAMRc=Mc+DqcQFGqxoYXYG-VCuaKkJusoVGSHb0G-MtYsiVCxVw@mail.gmail.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-2-biao.huang@mediatek.com>
 <CAMRc=Mc+DqcQFGqxoYXYG-VCuaKkJusoVGSHb0G-MtYsiVCxVw@mail.gmail.com>
Message-ID: <9793dc8c5c30db9342eb54c1b9c0a10b339d2860.camel@mediatek.com>

Dear Bartosz,
	Thanks for your comments!

On Tue, 2022-01-25 at 10:50 +0100, Bartosz Golaszewski wrote:
> On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com>
> wrote:
> > 
> > From: Fabien Parent <fparent at baylibre.com>
> > 
> > Not all the SoC are using the same clock divider. Move the divider
> > into
> > a compat structure specific to the SoCs.
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > Signed-off-by: Fabien Parent <fparent at baylibre.com>
> > ---
> >  drivers/net/ethernet/mediatek/mtk_star_emac.c | 23
> > +++++++++++++++----
> >  1 file changed, 19 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > index 1d5dd2015453..26f5020f2e9c 100644
> > --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > @@ -17,6 +17,7 @@
> >  #include <linux/module.h>
> >  #include <linux/netdevice.h>
> >  #include <linux/of.h>
> > +#include <linux/of_device.h>
> >  #include <linux/of_mdio.h>
> >  #include <linux/of_net.h>
> >  #include <linux/platform_device.h>
> > @@ -232,6 +233,10 @@ struct mtk_star_ring {
> >         unsigned int tail;
> >  };
> > 
> > +struct mtk_star_compat {
> > +       unsigned char bit_clk_div;
> > +};
> > +
> >  struct mtk_star_priv {
> >         struct net_device *ndev;
> > 
> > @@ -257,6 +262,8 @@ struct mtk_star_priv {
> >         int duplex;
> >         int pause;
> > 
> > +       const struct mtk_star_compat *compat_data;
> > +
> >         /* Protects against concurrent descriptor access. */
> >         spinlock_t lock;
> > 
> > @@ -899,7 +906,7 @@ static void mtk_star_init_config(struct
> > mtk_star_priv *priv)
> >         regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
> >         regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
> >                            MTK_STAR_MSK_MAC_CLK_CONF,
> > -                          MTK_STAR_BIT_CLK_DIV_10);
> > +                          priv->compat_data->bit_clk_div);
> >  }
> > 
> >  static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> > @@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct
> > platform_device *pdev)
> > 
> >         priv = netdev_priv(ndev);
> >         priv->ndev = ndev;
> > +       priv->compat_data = of_device_get_match_data(&pdev->dev);
> >         SET_NETDEV_DEV(ndev, dev);
> >         platform_set_drvdata(pdev, ndev);
> > 
> > @@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct
> > platform_device *pdev)
> >         return devm_register_netdev(dev, ndev);
> >  }
> > 
> > +static struct mtk_star_compat mtk_star_mt8516_compat = {
> 
> static const ... ?
Yes, will fix it in next send.
> 
> > +       .bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
> > +};
> > +
> >  static const struct of_device_id mtk_star_of_match[] = {
> > -       { .compatible = "mediatek,mt8516-eth", },
> > -       { .compatible = "mediatek,mt8518-eth", },
> > -       { .compatible = "mediatek,mt8175-eth", },
> > +       { .compatible = "mediatek,mt8516-eth",
> > +         .data = &mtk_star_mt8516_compat },
> > +       { .compatible = "mediatek,mt8518-eth",
> > +         .data = &mtk_star_mt8516_compat },
> > +       { .compatible = "mediatek,mt8175-eth",
> > +         .data = &mtk_star_mt8516_compat },
> >         { }
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> > --
> > 2.25.1
> > 

From biao.huang at mediatek.com  Wed Jan 26 16:51:50 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 08:51:50 +0800
Subject: [PATCH net-next v1 3/9] net: ethernet: mtk-star-emac: add
 support for MT8365 SoC
In-Reply-To: <CAMRc=MefKOmdKbm5KT=zQLORwm7oYe1oUy_XW3heqAqFqbE5NQ@mail.gmail.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-4-biao.huang@mediatek.com>
 <CAMRc=MefKOmdKbm5KT=zQLORwm7oYe1oUy_XW3heqAqFqbE5NQ@mail.gmail.com>
Message-ID: <cabca14fc2cabc85c4a9bd9946d88066c5d8e2f2.camel@mediatek.com>

Dear Bartosz,
	Thanks for your comments!

On Tue, 2022-01-25 at 11:21 +0100, Bartosz Golaszewski wrote:
> On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com>
> wrote:
> > 
> > Add Ethernet driver support for MT8365 SoC.
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
> > Signed-off-by: Fabien Parent <fparent at baylibre.com>
> > ---
> >  drivers/net/ethernet/mediatek/mtk_star_emac.c | 75
> > ++++++++++++++++---
> >  1 file changed, 64 insertions(+), 11 deletions(-)
> > 
> > diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > index 7c2af775d601..403439782db9 100644
> > --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > @@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] =
> > { "core", "reg", "trans" };
> >  #define MTK_STAR_REG_MAC_CLK_CONF              0x00ac
> >  #define MTK_STAR_MSK_MAC_CLK_CONF              GENMASK(7, 0)
> >  #define MTK_STAR_BIT_CLK_DIV_10                        0x0a
> > +#define MTK_STAR_BIT_CLK_DIV_50                        0x32
> > 
> >  /* Counter registers. */
> >  #define MTK_STAR_REG_C_RXOKPKT                 0x0100
> > @@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[]
> > = { "core", "reg", "trans" };
> >  #define MTK_STAR_REG_C_RX_TWIST                        0x0218
> > 
> >  /* Ethernet CFG Control */
> > -#define MTK_PERICFG_REG_NIC_CFG_CON            0x03c4
> > -#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII    GENMASK(3, 0)
> > -#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII       BIT(0)
> > +#define MTK_PERICFG_REG_NIC_CFG0_CON           0x03c4
> > +#define MTK_PERICFG_REG_NIC_CFG1_CON           0x03c8
> > +#define MTK_PERICFG_REG_NIC_CFG_CON_V2         0x0c10
> > +#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF   GENMASK(3, 0)
> > +#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII       1
> > 
> >  /* Represents the actual structure of descriptors used by the MAC.
> > We can
> >   * reuse the same structure for both TX and RX - the layout is the
> > same, only
> > @@ -234,6 +237,7 @@ struct mtk_star_ring {
> >  };
> > 
> >  struct mtk_star_compat {
> > +       int (*set_interface_mode)(struct net_device *ndev);
> >         unsigned char bit_clk_div;
> >  };
> > 
> > @@ -909,13 +913,6 @@ static void mtk_star_init_config(struct
> > mtk_star_priv *priv)
> >                            priv->compat_data->bit_clk_div);
> >  }
> > 
> > -static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
> > -{
> > -       regmap_update_bits(priv->pericfg,
> > MTK_PERICFG_REG_NIC_CFG_CON,
> > -                          MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
> > -                          MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
> > -}
> > -
> >  static int mtk_star_enable(struct net_device *ndev)
> >  {
> >         struct mtk_star_priv *priv = netdev_priv(ndev);
> > @@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct
> > platform_device *pdev)
> >                 return -ENODEV;
> >         }
> > 
> > -       mtk_star_set_mode_rmii(priv);
> > +       if (priv->compat_data->set_interface_mode) {
> > +               ret = priv->compat_data->set_interface_mode(ndev);
> > +               if (ret) {
> > +                       dev_err(dev, "Failed to set phy interface,
> > err = %d\n", ret);
> > +                       return -EINVAL;
> > +               }
> > +       }
> 
> Shouldn't you still call mtk_star_set_mode_rmii(priv) if there's no
> callback?
mtk_star_set_mode_rmii is replaced by priv->compat_data-
>set_interface_mode,
all the interface settings are moved to set_interface_mode,
and we'll implement it for every IC.

so, mtk_star_set_mode_rmii is no longer used.
> 
> > 
> >         ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
> >         if (ret) {
> > @@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct
> > platform_device *pdev)
> >         return devm_register_netdev(dev, ndev);
> >  }
> > 
> > +static int mt8516_set_interface_mode(struct net_device *ndev)
> > +{
> > +       struct mtk_star_priv *priv = netdev_priv(ndev);
> > +       struct device *dev = mtk_star_get_dev(priv);
> > +       unsigned int intf_val = 0;
> 
> No need to initialize.
OK, will fix it in next send.
> 
> > +
> > +       switch (priv->phy_intf) {
> > +       case PHY_INTERFACE_MODE_RMII:
> > +               intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> > +               break;
> > +       default:
> > +               dev_err(dev, "This interface not supported\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       regmap_update_bits(priv->pericfg,
> > MTK_PERICFG_REG_NIC_CFG0_CON,
> > +                          MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> > +                          intf_val);
> > +       return 0;
> 
> You can directly return regmap_update_bits().
OK, will fix it in next send.
> 
> > +}
> > +
> > +static int mt8365_set_interface_mode(struct net_device *ndev)
> > +{
> > +       struct mtk_star_priv *priv = netdev_priv(ndev);
> > +       struct device *dev = mtk_star_get_dev(priv);
> > +       unsigned int intf_val = 0;
> > +
> > +       switch (priv->phy_intf) {
> > +       case PHY_INTERFACE_MODE_RMII:
> > +               intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
> > +               break;
> > +       default:
> > +               dev_err(dev, "This interface not supported\n");
> > +               return -EINVAL;
> > +       }
> > +
> > +       regmap_update_bits(priv->pericfg,
> > MTK_PERICFG_REG_NIC_CFG_CON_V2,
> > +                          MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
> > +                          intf_val);
> > +       return 0;
> > +}
> 
> Same as above.
OK, will fix it in next send.
> 
> > +
> >  static struct mtk_star_compat mtk_star_mt8516_compat = {
> > +       .set_interface_mode = mt8516_set_interface_mode,
> >         .bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
> >  };
> > 
> > +static struct mtk_star_compat mtk_star_mt8365_compat = {
> > +       .set_interface_mode = mt8365_set_interface_mode,
> > +       .bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
> > +};
> > +
> >  static const struct of_device_id mtk_star_of_match[] = {
> >         { .compatible = "mediatek,mt8516-eth",
> >           .data = &mtk_star_mt8516_compat },
> > @@ -1575,6 +1626,8 @@ static const struct of_device_id
> > mtk_star_of_match[] = {
> >           .data = &mtk_star_mt8516_compat },
> >         { .compatible = "mediatek,mt8175-eth",
> >           .data = &mtk_star_mt8516_compat },
> > +       { .compatible = "mediatek,mt8365-eth",
> > +         .data = &mtk_star_mt8365_compat },
> >         { }
> >  };
> >  MODULE_DEVICE_TABLE(of, mtk_star_of_match);
> > --
> > 2.25.1
> > 
> 
> Bart

From pgwipeout at gmail.com  Wed Jan 26 17:00:20 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 20:00:20 -0500
Subject: [PATCH 0/3] Quartz64-A fixes and enablement from 5.17-rc1
Message-ID: <20220127010023.3169415-1-pgwipeout@gmail.com>

Good Evening,

This is the first of several patch series for further expanding
Quartz64-A support.

This series has the following patches:
Fix the ddr regulator voltage.
Add pmu_io_domains to permit sdio and high speed emmc support.
Add sdmmc1 node for wifi support.

Please review and apply.

Very Respectfully,
Peter Geis


Peter Geis (3):
  arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
  arm64: dts: rockchip: add Quartz64-A pmu_io_domains
  arm64: dts: rockchip: add Quartz64-A sdmmc1 node

 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 60 ++++++++++++++++++-
 1 file changed, 58 insertions(+), 2 deletions(-)

-- 
2.25.1



From pgwipeout at gmail.com  Wed Jan 26 17:00:21 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 20:00:21 -0500
Subject: [PATCH 1/3] arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
In-Reply-To: <20220127010023.3169415-1-pgwipeout@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
Message-ID: <20220127010023.3169415-2-pgwipeout@gmail.com>

The Quartz64 Model A uses a voltage divider to ensure ddr voltage is
within specification from the default regulator configuration.
Adjusting this voltage is detrimental, and currently causes the ddr
voltage to be about 0.8v.

Remove the min and max voltage setpoints for the ddr regulator.

Fixes: b33a22a1e7c4 ("arm64: dts: rockchip: add basic dts for Pine64
Quartz64-A")

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 166399b7f13f..d9eb92d59099 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -285,8 +285,6 @@ regulator-state-mem {
 			vcc_ddr: DCDC_REG3 {
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <1100000>;
-				regulator-max-microvolt = <1100000>;
 				regulator-initial-mode = <0x2>;
 				regulator-name = "vcc_ddr";
 				regulator-state-mem {
-- 
2.25.1



From pgwipeout at gmail.com  Wed Jan 26 17:00:22 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 20:00:22 -0500
Subject: [PATCH 2/3] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
In-Reply-To: <20220127010023.3169415-1-pgwipeout@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
Message-ID: <20220127010023.3169415-3-pgwipeout@gmail.com>

Several io power domains on the Quartz64-A operate at 1.8v.
Add the pmu_io_domains definition to enable support for this.
This permits the enablement of the following features:
sdio - wifi support
sdhci - mmc-hs200-1_8v

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index d9eb92d59099..33c2c18caaa9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -482,6 +482,19 @@ vcc_sd_h: vcc-sd-h {
 	};
 };
 
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc1v8_dvp>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	mmc-hs200-1_8v;
-- 
2.25.1



From pgwipeout at gmail.com  Wed Jan 26 17:00:23 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Wed, 26 Jan 2022 20:00:23 -0500
Subject: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <20220127010023.3169415-1-pgwipeout@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
Message-ID: <20220127010023.3169415-4-pgwipeout@gmail.com>

The sdmmc1 node on Quartz64-A supports the optional wifi module from
Pine64.
Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
the Quartz64-A.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 45 +++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 33c2c18caaa9..1d73ac6557c5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -91,6 +91,18 @@ simple-audio-card,codec {
 		};
 	};
 
+	sdio_pwrseq: sdio-pwrseq {
+		status = "okay";
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk817 1>;
+		clock-names = "ext_clock";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+		reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
+		post-power-on-delay-ms = <100>;
+		power-off-delay-us = <5000000>;
+	};
+
 	vcc12v_dcin: vcc12v_dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -147,6 +159,17 @@ vcc_sys: vcc_sys {
 		regulator-max-microvolt = <4400000>;
 		vin-supply = <&vbus>;
 	};
+
+	/* sourced from vcc_sys, sdio module operates internally at 3.3v */
+	vcc_wl: vcc_wl {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_wl";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
 };
 
 &cpu0 {
@@ -475,6 +498,12 @@ pmic_int_l: pmic-int-l {
 		};
 	};
 
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	vcc_sd {
 		vcc_sd_h: vcc-sd-h {
 			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -516,6 +545,22 @@ &sdmmc0 {
 	status = "okay";
 };
 
+&sdmmc1 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	disable-wp;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_wl>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
 &spdif {
 	status = "okay";
 };
-- 
2.25.1



From nobuta.keiya at fujitsu.com  Wed Jan 26 17:13:37 2022
From: nobuta.keiya at fujitsu.com (nobuta.keiya at fujitsu.com)
Date: Thu, 27 Jan 2022 01:13:37 +0000
Subject: [PATCH v13 11/11] arm64: Select HAVE_RELIABLE_STACKTRACE
In-Reply-To: <1a0e19db-a7f8-4c8e-0163-398fcd364d54@linux.microsoft.com>
References: <95691cae4f4504f33d0fc9075541b1e7deefe96f>
 <20220117145608.6781-1-madvenka@linux.microsoft.com>
 <20220117145608.6781-12-madvenka@linux.microsoft.com>
 <TY2PR01MB5257518B8EB381E16D52B244855F9@TY2PR01MB5257.jpnprd01.prod.outlook.com>
 <825b8b72-c746-ba24-7142-3fff481e82d6@linux.microsoft.com>
 <TY2PR01MB5257BE671A481D81F1A40E0185209@TY2PR01MB5257.jpnprd01.prod.outlook.com>
 <1a0e19db-a7f8-4c8e-0163-398fcd364d54@linux.microsoft.com>
Message-ID: <TY2PR01MB5257F92BDD5E55914A63DD2C85219@TY2PR01MB5257.jpnprd01.prod.outlook.com>

> >> I have not seen any activity on that in a long time. IIRC, Julien quit RedHat.
> >> I don't know if anyone else has taken over this work in RedHat.
> >>
> >> Sorry, I don't have any more information.
> >>
> >> Madhavan
> >
> > Thanks for your information.
> >
> > By the way, I'm considering test code for arch_stack_walk_reliable().
> > Specifically, I apply Suraj's patch to enable livepatch, and added a function
> > that sleeps between SYM_CODE_START and SYM_CODE_END, then livepatch
> > checks if the task has an unreliable stack.
> > For now my internal test code working correctly, but my Kconfig excludes
> > STACK_VALIDATION dependency.
> >
> > It seems that objtool will not be enabled yet, so I would like to test it easier.
> > If you are already testing with this patch, could you tell me how to do it?
> >
> >
> 
> For now, I have an instrumented kernel that directly invokes arch_stack_walk_reliable()
> from various places in the kernel (interrupt handlers, exception handlers, ftrace entry,
> kprobe handler, etc). I also have a test driver to induce conditions like null pointer
> dereference. I use this to test different cases where arch_stack_walk_reliable() should
> return an error.

That's good to know, thanks.

> 
> As for livepatch testing, I have enhanced objtool and the kernel so the frame pointer can
> be validated dynamically rather than statically. I have tested various different livepatch
> selftests successfully. I have also written my own livepatch tests to add to the selftests.
> I am currently working on preparing an RFC patch series for review. Basically, this series
> implements STACK_VALIDATION in a different way.
> 
> I plan to publish my work soon (hopefully Feb 2022). I was going to do in December. However,
> my workload in Microsoft did not permit me to do that. I am also planning to set up a github
> repo so people can try out my changes, if they are interested.
> 
> So, stay tuned.
> 
> Madhavan

I'm very interested, so I would to be happy if you could tell me when the github repo is set up.


Thanks again,

Keiya


From biao.huang at mediatek.com  Wed Jan 26 17:13:55 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:13:55 +0800
Subject: [PATCH net-next v1 2/9] net: ethernet: mtk-star-emac: modify
 IRQ trigger flags
In-Reply-To: <CAMRc=McZTped08HwbM+pr-xtsDyddTLjpsCc_f7ucoDM2DNXaw@mail.gmail.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-3-biao.huang@mediatek.com>
 <CAMRc=McZTped08HwbM+pr-xtsDyddTLjpsCc_f7ucoDM2DNXaw@mail.gmail.com>
Message-ID: <5ebfab5e96d957d671a055a342dc56e47c7c4d8a.camel@mediatek.com>

Dear Bartosz,
	Thanks for your comments!

On Tue, 2022-01-25 at 11:22 +0100, Bartosz Golaszewski wrote:
> On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com>
> wrote:
> > 
> > If the flags in request_irq() is IRQF_TRIGGER_NONE, the trigger
> > method
> > is determined by "interrupt" property in dts.
> > So, modify the flag from IRQF_TRIGGER_FALLING to IRQF_TRIGGER_NONE.
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
> > ---
> >  drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > index 26f5020f2e9c..7c2af775d601 100644
> > --- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > +++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
> > @@ -959,7 +959,7 @@ static int mtk_star_enable(struct net_device
> > *ndev)
> > 
> >         /* Request the interrupt */
> >         ret = request_irq(ndev->irq, mtk_star_handle_irq,
> > -                         IRQF_TRIGGER_FALLING, ndev->name, ndev);
> > +                         IRQF_TRIGGER_NONE, ndev->name, ndev);
> >         if (ret)
> >                 goto err_free_skbs;
> > 
> > --
> > 2.25.1
> > 
> 
> Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>
I'll add reviewd-by in next send.

From tim.c.chen at linux.intel.com  Wed Jan 26 17:14:29 2022
From: tim.c.chen at linux.intel.com (Tim Chen)
Date: Wed, 26 Jan 2022 17:14:29 -0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <20220126080947.4529-3-yangyicong@hisilicon.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
Message-ID: <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>

On Wed, 2022-01-26 at 16:09 +0800, Yicong Yang wrote:
> From: Barry Song <song.bao.hua at hisilicon.com>
> 
> For platforms having clusters like Kunpeng920, CPUs within the same
> cluster have lower latency when synchronizing and accessing shared
> resources like cache. Thus, this patch tries to find an idle cpu
> within the cluster of the target CPU before scanning the whole LLC
> to gain lower latency.
> 
> Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> patch doesn't consider SMT for this moment.
> 
> Testing has been done on Kunpeng920 by pinning tasks to one numa
> and two numa. On Kunpeng920, Each numa has 8 clusters and each
> cluster has 4 CPUs.
> 
> With this patch, We noticed enhancement on tbench within one
> numa or cross two numa.
> 
> On numa 0:
>                             5.17-rc1                patched
> Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> 
> On numa 0-1:
>                             5.17-rc1                patched
> Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> 
> This will also help to improve the MySQL. With MySQL server
> running on numa 0 and client running on numa 1, both QPS and
> latency is imporved on read-write case:
>                         5.17-rc1        patched
> QPS-16threads        143333.2633    145077.4033(+1.22%)
> QPS-24threads        195085.9367    202719.6133(+3.91%)
> QPS-32threads        241165.6867      249020.74(+3.26%)
> QPS-64threads        244586.8433    253387.7567(+3.60%)
> avg-lat-16threads           2.23           2.19(+1.19%)
> avg-lat-24threads           2.46           2.36(+3.79%)
> avg-lat-36threads           2.66           2.57(+3.26%)
> avg-lat-64threads           5.23           5.05(+3.44%)
> 
> Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++
> ----
>  1 file changed, 42 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 5146163bfabb..2f84a933aedd 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct
> task_struct *p, struct sched_domain *sd
>  
>  #endif /* CONFIG_SCHED_SMT */
>  
> +#ifdef CONFIG_SCHED_CLUSTER
> +/*
> + * Scan the cluster domain for idle CPUs and clear cluster cpumask
> after scanning
> + */
> +static inline int scan_cluster(struct task_struct *p, int prev_cpu,
> int target)
> +{
> +	struct cpumask *cpus =
> this_cpu_cpumask_var_ptr(select_idle_mask);
> +	struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster,
> target));
> +	int cpu, idle_cpu;
> +
> +	/* TODO: Support SMT case while a machine with both cluster and
> SMT born */

This is probably a clearer comment

	/* TODO: Support SMT system with cluster topology */

> +	if (!sched_smt_active() && sd) {
> +		for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> +			idle_cpu = __select_idle_cpu(cpu, p);
>   */
> -static int select_idle_cpu(struct task_struct *p, struct
> sched_domain *sd, bool has_idle_core, int target)
> +static int select_idle_cpu(struct task_struct *p, struct
> sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
>  {
>  	struct cpumask *cpus =
> this_cpu_cpumask_var_ptr(select_idle_mask);
>  	int i, cpu, idle_cpu = -1, nr = INT_MAX;
> @@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct task_struct
> *p, struct sched_domain *sd, bool
>  
>  	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
>  
> +	idle_cpu = scan_cluster(p, prev_cpu, target);

Shouldn't "cpus" from 

cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);

be passed to scan_cluster, to make sure that the cpu returned is 
in the affinity mask of the task? I don't see p->cpus_ptr
being checked in scan_cluster to make sure the cpu found is in the
affinity mask.

Tim


> +	if ((unsigned int)idle_cpu < nr_cpumask_bits)
> +		return idle_cpu;
> +
>  	if (sched_feat(SIS_PROP) && !has_idle_core) {
>  		u64 avg_cost, avg_idle, span_avg;
>  		unsigned long now = jiffies;
> @@ -6416,7 +6454,7 @@ static int select_idle_sibling(struct
> task_struct *p, int prev, int target)
>  	/*
>  	 * If the previous CPU is cache affine and idle, don't be
> stupid:
>  	 */
> -	if (prev != target && cpus_share_cache(prev, target) &&
> +	if (prev != target && cpus_share_resources(prev, target) &&
>  	    (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
>  	    asym_fits_capacity(task_util, prev))
>  		return prev;
> @@ -6442,7 +6480,7 @@ static int select_idle_sibling(struct
> task_struct *p, int prev, int target)
>  	p->recent_used_cpu = prev;
>  	if (recent_used_cpu != prev &&
>  	    recent_used_cpu != target &&
> -	    cpus_share_cache(recent_used_cpu, target) &&
> +	    cpus_share_resources(recent_used_cpu, target) &&
>  	    (available_idle_cpu(recent_used_cpu) ||
> sched_idle_cpu(recent_used_cpu)) &&
>  	    cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
>  	    asym_fits_capacity(task_util, recent_used_cpu)) {
> @@ -6483,7 +6521,7 @@ static int select_idle_sibling(struct
> task_struct *p, int prev, int target)
>  		}
>  	}
>  
> -	i = select_idle_cpu(p, sd, has_idle_core, target);
> +	i = select_idle_cpu(p, sd, has_idle_core, prev, target);
>  	if ((unsigned)i < nr_cpumask_bits)
>  		return i;
>  



From biao.huang at mediatek.com  Wed Jan 26 17:13:13 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:13:13 +0800
Subject: [PATCH net-next v1 4/9] dt-bindings: net: mtk-star-emac: add
 support for MT8365
In-Reply-To: <CAMRc=MdVKdXcK0gdBSpaaSm5fx1o5Sy_0-JJBPK0=Xp7UmQnqQ@mail.gmail.com>
References: <20220120070226.1492-1-biao.huang@mediatek.com>
 <20220120070226.1492-5-biao.huang@mediatek.com>
 <CAMRc=MdVKdXcK0gdBSpaaSm5fx1o5Sy_0-JJBPK0=Xp7UmQnqQ@mail.gmail.com>
Message-ID: <07089392136a4a0790dd1fe73443db7e47700077.camel@mediatek.com>

Dear Bartosz,
	Thanks for your comments~

On Tue, 2022-01-25 at 11:23 +0100, Bartosz Golaszewski wrote:
> On Thu, Jan 20, 2022 at 8:02 AM Biao Huang <biao.huang at mediatek.com>
> wrote:
> > 
> > Add binding document for Ethernet on MT8365.
> > 
> > Signed-off-by: Biao Huang <biao.huang at mediatek.com>
> > ---
> >  Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1
> > +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/mediatek,star-
> > emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-
> > emac.yaml
> > index e6a5ff208253..87a8b25b03a6 100644
> > --- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
> > +++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
> > @@ -23,6 +23,7 @@ properties:
> >        - mediatek,mt8516-eth
> >        - mediatek,mt8518-eth
> >        - mediatek,mt8175-eth
> > +      - mediatek,mt8365-eth
> > 
> >    reg:
> >      maxItems: 1
> > --
> > 2.25.1
> > 
> 
> Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>
I'll add revieed-by in next send.

From Justin.He at arm.com  Wed Jan 26 17:31:34 2022
From: Justin.He at arm.com (Justin He)
Date: Thu, 27 Jan 2022 01:31:34 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
Message-ID: <VI1PR08MB3742D95CC6B9EC2B07E2A020F7219@VI1PR08MB3742.eurprd08.prod.outlook.com>

Hi Ard

> -----Original Message-----
> From: Ard Biesheuvel <ardb at kernel.org>
> Sent: Wednesday, January 26, 2022 4:37 PM
> To: Justin He <Justin.He at arm.com>
> Cc: Catalin Marinas <Catalin.Marinas at arm.com>; Jianyong Wu
> <Jianyong.Wu at arm.com>; will at kernel.org; Anshuman Khandual
> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org; david at redhat.com;
> quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Wed, 26 Jan 2022 at 05:21, Justin He <Justin.He at arm.com> wrote:
> >
> > Hi Catalin
> >
> > > -----Original Message-----
> > > From: Catalin Marinas <catalin.marinas at arm.com>
> > > Sent: Friday, January 7, 2022 6:43 PM
> > > To: Jianyong Wu <Jianyong.Wu at arm.com>
> > > Cc: will at kernel.org; Anshuman Khandual <Anshuman.Khandual at arm.com>;
> > > akpm at linux-foundation.org; david at redhat.com; quic_qiancai at quicinc.com;
> > > ardb at kernel.org; linux-kernel at vger.kernel.org; linux-arm-
> > > kernel at lists.infradead.org; gshan at redhat.com; Justin He
> > > <Justin.He at arm.com>; nd <nd at arm.com>
> > > Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when
> create
> > > pud mapping
> > >
> > > On Fri, Jan 07, 2022 at 09:10:57AM +0000, Jianyong Wu wrote:
> > > > Hi Catalin,
> > > >
> > > > I roughly find the root cause.
> > > >  alloc_init_pud will be called at the very beginning of kernel boot
> in
> > > create_mapping_noalloc where no memory allocator is initialized. But
> > > lockdep check may need allocate memory. So, kernel take exception when
> > > acquire lock.(I have not found the exact code that cause this issue)
> > > that's say we may not be able to use a lock so early.
> > > >
> > > > I come up with 2 methods to address it.
> > > > 1) skip dead lock check at the very beginning of kernel boot in
> lockdep
> > > code.
> > > > 2) provided 2 two versions of __create_pgd_mapping, one with lock in
> > > > it and the other without. There may be no possible of race for
> memory
> > > > mapping at the very beginning time of kernel boot, thus we can use
> the
> > > > no lock version of __create_pgd_mapping safely.
> > > > In my test, this issue is gone if there is no lock held in
> > > > create_mapping_noalloc. I think create_mapping_noalloc is called
> early
> > > > enough to avoid the race conditions of memory mapping, however, I
> have
> > > > not proved it.
> > >
> > > I think method 2 would work better but rather than implementing new
> > > nolock functions I'd add a NO_LOCK flag and check it in
> > > alloc_init_pud() before mutex_lock/unlock. Also add a comment when
> > > passing the NO_LOCK flag on why it's needed and why there wouldn't be
> > > any races at that stage (early boot etc.)
> > >
> > The problematic code path is:
> > __primary_switched
> >         early_fdt_map->fixmap_remap_fdt
> >                 create_mapping_noalloc->alloc_init_pud
> >                         mutex_lock (with Jianyong's patch)
> >
> > The problem seems to be that we will clear BSS segment twice if kaslr
> > is enabled. Hence, some of the static variables in lockdep init process
> were
> > messed up. That is to said, with kaslr enabled we might initialize
> lockdep
> > twice if we add mutex_lock/unlock in alloc_init_pud().
> >
> 
> Thanks for tracking that down.
> 
> Note that clearing the BSS twice is not the root problem here. The
> root problem is that we set global state while the kernel runs at the
> default link time address, and then refer to it again after the entire
> kernel has been shifted in the kernel VA space. Such global state
> could consist of mutable pointers to statically allocated data (which
> would be reset to their default values after the relocation code runs
> again), or global pointer variables in BSS. In either case, relying on
> such a global variable after the second relocation performed by KASLR
> would be risky, and so we should avoid manipulating global state at
> all if it might involve pointer to statically allocated data
> structures.
> 
Thanks for the explanation, which makes root cause clearer.
I have a question off this thread:
Should we avoid to invoke early_fdt_map and init_feature_override twice
with kaslr enabled?

In Commit f6f0c4362f07 ("arm64: Extract early FDT mapping from kaslr
early_init() "), it implicitly invokes early_fdt_map first time before
kaslr is enabled and 2nd time after it.

What to you think of below changes (tested in both guest and host boot):

diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 6a98f1a38c29..3758ac057a6a 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -450,12 +450,12 @@ SYM_FUNC_START_LOCAL(__primary_switched)
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
        bl      kasan_early_init
 #endif
-       mov     x0, x21                         // pass FDT address in x0
-       bl      early_fdt_map                   // Try mapping the FDT early
-       bl      init_feature_override           // Parse cpu feature overrides
 #ifdef CONFIG_RANDOMIZE_BASE
        tst     x23, ~(MIN_KIMG_ALIGN - 1)      // already running randomized?
        b.ne    0f
+       mov     x0, x21                         // pass FDT address in x0
+       bl      early_fdt_map                   // Try mapping the FDT early
+       bl      init_feature_override           // Parse cpu feature overrides
        bl      kaslr_early_init                // parse FDT for KASLR options
        cbz     x0, 0f                          // KASLR disabled? just proceed
        orr     x23, x23, x0                    // record KASLR offset


--
Cheers,
Justin (Jia He)



From cgel.zte at gmail.com  Wed Jan 26 17:44:32 2022
From: cgel.zte at gmail.com (cgel.zte at gmail.com)
Date: Thu, 27 Jan 2022 01:44:32 +0000
Subject: [PATCH] vchiq-mmal: Remove redundant 'flush_workqueue()' calls
Message-ID: <20220127014432.1185206-1-chi.minghao@zte.com.cn>

From: "Minghao Chi (CGEL ZTE)" <chi.minghao at zte.com.cn>

'destroy_workqueue()' already drains the queue before destroying it,
so there is no need to flush it explicitly.

Remove the redundant 'flush_workqueue()' calls.

Reported-by: Zeal Robot <zealci at zte.com.cn>
Signed-off-by: Minghao Chi (CGEL ZTE) <chi.minghao at zte.com.cn>
Signed-off-by: CGEL ZTE <cgel.zte at gmail.com>
---
 drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
index 76d3f0399964..60305c63c6f6 100644
--- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
+++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
@@ -1844,7 +1844,6 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
 	mutex_unlock(&instance->vchiq_mutex);
 
 	vchiq_shutdown(instance->vchiq_instance);
-	flush_workqueue(instance->bulk_wq);
 	destroy_workqueue(instance->bulk_wq);
 
 	vfree(instance->bulk_scratch);
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:48 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:48 +0800
Subject: [PATCH net-next v2 0/9] add more features for mtk-star-emac
Message-ID: <20220127015857.9868-1-biao.huang@mediatek.com>

Changes in v2:
1. fix coding style as Bartosz's comments.
2. add reviewed-by as Bartosz's comments.

This series add more features for mtk-star-emac:
1. add reference clock pad selection for RMII;
2. add simple timing adjustment for RMII;
3. add support for MII;
4. add support for new IC MT8365;
5. separate tx/rx interrupt handling.

Biao Huang (8):
  net: ethernet: mtk-star-emac: modify IRQ trigger flags
  net: ethernet: mtk-star-emac: add support for MT8365 SoC
  dt-bindings: net: mtk-star-emac: add support for MT8365
  net: ethernet: mtk-star-emac: add clock pad selection for RMII
  net: ethernet: mtk-star-emac: add timing adjustment support
  dt-bindings: net: mtk-star-emac: add description for new  properties
  net: ethernet: mtk-star-emac: add support for MII interface
  net: ethernet: mtk-star-emac: separate tx/rx handling with two NAPIs

Fabien Parent (1):
  net: ethernet: mtk-star-emac: store bit_clk_div in compat structure

 .../bindings/net/mediatek,star-emac.yaml      |  17 +
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 477 ++++++++++++------
 2 files changed, 341 insertions(+), 153 deletions(-)

-- 
2.25.1




From biao.huang at mediatek.com  Wed Jan 26 17:58:49 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:49 +0800
Subject: [PATCH net-next v2 1/9] net: ethernet: mtk-star-emac: store
 bit_clk_div in compat structure
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-2-biao.huang@mediatek.com>

From: Fabien Parent <fparent at baylibre.com>

Not all the SoC are using the same clock divider. Move the divider into
a compat structure specific to the SoCs.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Fabien Parent <fparent at baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 23 +++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 1d5dd2015453..7fd8ec0fc636 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -17,6 +17,7 @@
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/platform_device.h>
@@ -232,6 +233,10 @@ struct mtk_star_ring {
 	unsigned int tail;
 };
 
+struct mtk_star_compat {
+	unsigned char bit_clk_div;
+};
+
 struct mtk_star_priv {
 	struct net_device *ndev;
 
@@ -257,6 +262,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 
+	const struct mtk_star_compat *compat_data;
+
 	/* Protects against concurrent descriptor access. */
 	spinlock_t lock;
 
@@ -899,7 +906,7 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_SYS_CONF, val);
 	regmap_update_bits(priv->regs, MTK_STAR_REG_MAC_CLK_CONF,
 			   MTK_STAR_MSK_MAC_CLK_CONF,
-			   MTK_STAR_BIT_CLK_DIV_10);
+			   priv->compat_data->bit_clk_div);
 }
 
 static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
@@ -1461,6 +1468,7 @@ static int mtk_star_probe(struct platform_device *pdev)
 
 	priv = netdev_priv(ndev);
 	priv->ndev = ndev;
+	priv->compat_data = of_device_get_match_data(&pdev->dev);
 	SET_NETDEV_DEV(ndev, dev);
 	platform_set_drvdata(pdev, ndev);
 
@@ -1556,10 +1564,17 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static const struct mtk_star_compat mtk_star_mt8516_compat = {
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
-	{ .compatible = "mediatek,mt8516-eth", },
-	{ .compatible = "mediatek,mt8518-eth", },
-	{ .compatible = "mediatek,mt8175-eth", },
+	{ .compatible = "mediatek,mt8516-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8518-eth",
+	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8175-eth",
+	  .data = &mtk_star_mt8516_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:54 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:54 +0800
Subject: [PATCH net-next v2 6/9] net: ethernet: mtk-star-emac: add timing
 adjustment support
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-7-biao.huang@mediatek.com>

Add simple clock inversion for timing adjustment in driver.
Add property "mediatek,txc-inverse" or "mediatek,rxc-inverse" to
device node when necessary.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 34 +++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index d69f75661e75..d5e974e0db6d 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -131,6 +131,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_INT_MASK			0x0054
 #define MTK_STAR_BIT_INT_MASK_FNRC		BIT(6)
 
+/* Delay-Macro Register */
+#define MTK_STAR_REG_TEST0			0x0058
+#define MTK_STAR_BIT_INV_RX_CLK			BIT(30)
+#define MTK_STAR_BIT_INV_TX_CLK			BIT(31)
+
 /* Misc. Config Register */
 #define MTK_STAR_REG_TEST1			0x005c
 #define MTK_STAR_BIT_TEST1_RST_HASH_MBIST	BIT(31)
@@ -268,6 +273,8 @@ struct mtk_star_priv {
 	int duplex;
 	int pause;
 	bool rmii_rxc;
+	bool rx_inv;
+	bool tx_inv;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1450,6 +1457,25 @@ static void mtk_star_clk_disable_unprepare(void *data)
 	clk_bulk_disable_unprepare(MTK_STAR_NCLKS, priv->clks);
 }
 
+static int mtk_star_set_timing(struct mtk_star_priv *priv)
+{
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int delay_val = 0;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
+		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	regmap_write(priv->regs, MTK_STAR_REG_TEST0, delay_val);
+
+	return 0;
+}
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1532,6 +1558,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	}
 
 	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+	priv->rx_inv = of_property_read_bool(of_node, "mediatek,rxc-inverse");
+	priv->tx_inv = of_property_read_bool(of_node, "mediatek,txc-inverse");
 
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
@@ -1541,6 +1569,12 @@ static int mtk_star_probe(struct platform_device *pdev)
 		}
 	}
 
+	ret = mtk_star_set_timing(priv);
+	if (ret) {
+		dev_err(dev, "Failed to set timing, err = %d\n", ret);
+		return -EINVAL;
+	}
+
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(dev, "unsupported DMA mask\n");
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:50 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:50 +0800
Subject: [PATCH net-next v2 2/9] net: ethernet: mtk-star-emac: modify IRQ
 trigger flags
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-3-biao.huang@mediatek.com>

If the flags in request_irq() is IRQF_TRIGGER_NONE, the trigger method
is determined by "interrupt" property in dts.
So, modify the flag from IRQF_TRIGGER_FALLING to IRQF_TRIGGER_NONE.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 7fd8ec0fc636..a8fbbbcd185b 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -959,7 +959,7 @@ static int mtk_star_enable(struct net_device *ndev)
 
 	/* Request the interrupt */
 	ret = request_irq(ndev->irq, mtk_star_handle_irq,
-			  IRQF_TRIGGER_FALLING, ndev->name, ndev);
+			  IRQF_TRIGGER_NONE, ndev->name, ndev);
 	if (ret)
 		goto err_free_skbs;
 
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:53 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:53 +0800
Subject: [PATCH net-next v2 5/9] net: ethernet: mtk-star-emac: add clock pad
 selection for RMII
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-6-biao.huang@mediatek.com>

This patch add a new dts property named "mediatek,rmii-rxc" parsing
in driver, which will configure MAC to select which pin the RMII reference
clock is connected to, TXC or RXC.

TXC pad is the default reference clock pin. If user wants to use RXC pad
instead, add "mediatek,rmii-rxc" to corresponding device node.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index a3884beaa3fe..d69f75661e75 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -189,6 +189,8 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -265,6 +267,7 @@ struct mtk_star_priv {
 	int speed;
 	int duplex;
 	int pause;
+	bool rmii_rxc;
 
 	const struct mtk_star_compat *compat_data;
 
@@ -1528,6 +1531,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	priv->rmii_rxc = of_property_read_bool(of_node, "mediatek,rmii-rxc");
+
 	if (priv->compat_data->set_interface_mode) {
 		ret = priv->compat_data->set_interface_mode(ndev);
 		if (ret) {
@@ -1571,17 +1576,25 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 	struct device *dev = mtk_star_get_dev(priv);
-	unsigned int intf_val;
+	unsigned int intf_val, ret, rmii_rxc;
 
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
 		return -EINVAL;
 	}
 
+	ret = regmap_update_bits(priv->pericfg,
+				 MTK_PERICFG_REG_NIC_CFG1_CON,
+				 MTK_PERICFG_BIT_NIC_CFG_CON_CLK,
+				 rmii_rxc);
+	if (ret)
+		return ret;
+
 	return regmap_update_bits(priv->pericfg,
 				  MTK_PERICFG_REG_NIC_CFG0_CON,
 				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
@@ -1597,6 +1610,7 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	switch (priv->phy_intf) {
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
 		break;
 	default:
 		dev_err(dev, "This interface not supported\n");
@@ -1605,7 +1619,8 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 
 	return regmap_update_bits(priv->pericfg,
 				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
-				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF |
+				  MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2,
 				  intf_val);
 }
 
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:56 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:56 +0800
Subject: [PATCH net-next v2 8/9] net: ethernet: mtk-star-emac: add support for
 MII interface
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-9-biao.huang@mediatek.com>

Add support for MII interface.
If user wants to use MII, assign "MII" to "phy-mode" property in dts.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index d5e974e0db6d..167a019fd8f5 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -193,6 +193,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
 #define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
 #define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_MII		0
 #define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK		BIT(0)
 #define MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2	BIT(8)
@@ -1463,6 +1464,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 	unsigned int delay_val = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
 	case PHY_INTERFACE_MODE_RMII:
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_RX_CLK, priv->rx_inv);
 		delay_val |= FIELD_PREP(MTK_STAR_BIT_INV_TX_CLK, priv->tx_inv);
@@ -1545,7 +1547,8 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ret = of_get_phy_mode(of_node, &priv->phy_intf);
 	if (ret) {
 		return ret;
-	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII) {
+	} else if (priv->phy_intf != PHY_INTERFACE_MODE_RMII &&
+		   priv->phy_intf != PHY_INTERFACE_MODE_MII) {
 		dev_err(dev, "unsupported phy mode: %s\n",
 			phy_modes(priv->phy_intf));
 		return -EINVAL;
@@ -1610,9 +1613,12 @@ static int mt8516_set_interface_mode(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 	struct device *dev = mtk_star_get_dev(priv);
-	unsigned int intf_val, ret, rmii_rxc;
+	unsigned int intf_val, ret, rmii_rxc = 0;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		rmii_rxc = priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK;
@@ -1642,6 +1648,9 @@ static int mt8365_set_interface_mode(struct net_device *ndev)
 	unsigned int intf_val;
 
 	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_MII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_MII;
+		break;
 	case PHY_INTERFACE_MODE_RMII:
 		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
 		intf_val |= priv->rmii_rxc ? 0 : MTK_PERICFG_BIT_NIC_CFG_CON_CLK_V2;
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:55 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:55 +0800
Subject: [PATCH net-next v2 7/9] dt-bindings: net: mtk-star-emac: add
 description for new properties
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-8-biao.huang@mediatek.com>

Add description for new properties which will be parsed in driver.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
---
 .../bindings/net/mediatek,star-emac.yaml         | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index 87a8b25b03a6..41b1b1dd562c 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -48,6 +48,22 @@ properties:
       Phandle to the device containing the PERICFG register range. This is used
       to control the MII mode.
 
+  mediatek,rmii-rxc:
+    type: boolean
+    description:
+      If present, indicates that the RMII reference clock, which is from external
+      PHYs, is connected to RXC pin. Otherwise, is connected to TXC pin.
+
+  mediatek,rxc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on RXC pad will be inversed.
+
+  mediatek,txc-inverse:
+    type: boolean
+    description:
+      If present, indicates that clock on TXC pad will be inversed.
+
   mdio:
     type: object
     description:
-- 
2.25.1



From yangyicong at huawei.com  Wed Jan 26 18:02:37 2022
From: yangyicong at huawei.com (Yicong Yang)
Date: Thu, 27 Jan 2022 10:02:37 +0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>
Message-ID: <b793e565-670d-cc66-6947-7d927ebcb8b3@huawei.com>

On 2022/1/27 9:14, Tim Chen wrote:
> On Wed, 2022-01-26 at 16:09 +0800, Yicong Yang wrote:
>> From: Barry Song <song.bao.hua at hisilicon.com>
>>
>> For platforms having clusters like Kunpeng920, CPUs within the same
>> cluster have lower latency when synchronizing and accessing shared
>> resources like cache. Thus, this patch tries to find an idle cpu
>> within the cluster of the target CPU before scanning the whole LLC
>> to gain lower latency.
>>
>> Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
>> patch doesn't consider SMT for this moment.
>>
>> Testing has been done on Kunpeng920 by pinning tasks to one numa
>> and two numa. On Kunpeng920, Each numa has 8 clusters and each
>> cluster has 4 CPUs.
>>
>> With this patch, We noticed enhancement on tbench within one
>> numa or cross two numa.
>>
>> On numa 0:
>>                             5.17-rc1                patched
>> Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
>> Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
>> Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
>> Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
>> Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
>> Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
>> Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
>> Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
>>
>> On numa 0-1:
>>                             5.17-rc1                patched
>> Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
>> Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
>> Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
>> Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
>> Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
>> Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
>> Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
>> Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
>> Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
>> Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
>>
>> This will also help to improve the MySQL. With MySQL server
>> running on numa 0 and client running on numa 1, both QPS and
>> latency is imporved on read-write case:
>>                         5.17-rc1        patched
>> QPS-16threads        143333.2633    145077.4033(+1.22%)
>> QPS-24threads        195085.9367    202719.6133(+3.91%)
>> QPS-32threads        241165.6867      249020.74(+3.26%)
>> QPS-64threads        244586.8433    253387.7567(+3.60%)
>> avg-lat-16threads           2.23           2.19(+1.19%)
>> avg-lat-24threads           2.46           2.36(+3.79%)
>> avg-lat-36threads           2.66           2.57(+3.26%)
>> avg-lat-64threads           5.23           5.05(+3.44%)
>>
>> Tested-by: Yicong Yang <yangyicong at hisilicon.com>
>> Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>> ---
>>  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++
>> ----
>>  1 file changed, 42 insertions(+), 4 deletions(-)
>>
>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>> index 5146163bfabb..2f84a933aedd 100644
>> --- a/kernel/sched/fair.c
>> +++ b/kernel/sched/fair.c
>> @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct
>> task_struct *p, struct sched_domain *sd
>>  
>>  #endif /* CONFIG_SCHED_SMT */
>>  
>> +#ifdef CONFIG_SCHED_CLUSTER
>> +/*
>> + * Scan the cluster domain for idle CPUs and clear cluster cpumask
>> after scanning
>> + */
>> +static inline int scan_cluster(struct task_struct *p, int prev_cpu,
>> int target)
>> +{
>> +	struct cpumask *cpus =
>> this_cpu_cpumask_var_ptr(select_idle_mask);
>> +	struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster,
>> target));
>> +	int cpu, idle_cpu;
>> +
>> +	/* TODO: Support SMT case while a machine with both cluster and
>> SMT born */
> 
> This is probably a clearer comment
> 
> 	/* TODO: Support SMT system with cluster topology */
> 
>> +	if (!sched_smt_active() && sd) {
>> +		for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
>> +			idle_cpu = __select_idle_cpu(cpu, p);
>>   */
>> -static int select_idle_cpu(struct task_struct *p, struct
>> sched_domain *sd, bool has_idle_core, int target)
>> +static int select_idle_cpu(struct task_struct *p, struct
>> sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
>>  {
>>  	struct cpumask *cpus =
>> this_cpu_cpumask_var_ptr(select_idle_mask);
>>  	int i, cpu, idle_cpu = -1, nr = INT_MAX;
>> @@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct task_struct
>> *p, struct sched_domain *sd, bool
>>  
>>  	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
>>  
>> +	idle_cpu = scan_cluster(p, prev_cpu, target);
> 
> Shouldn't "cpus" from 
> 
> cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> 
> be passed to scan_cluster, to make sure that the cpu returned is 
> in the affinity mask of the task? I don't see p->cpus_ptr
> being checked in scan_cluster to make sure the cpu found is in the
> affinity mask.
> 

The cpus scanned in scan_cluster() is the intersection of
select_idle_mask and sched_domain_span(cluster_sd), and
we limited the select_idle_mask in the tasks' affinity mask
before we enter scan_cluster() here.

Thanks.

> Tim
> 
> 
>> +	if ((unsigned int)idle_cpu < nr_cpumask_bits)
>> +		return idle_cpu;
>> +
>>  	if (sched_feat(SIS_PROP) && !has_idle_core) {
>>  		u64 avg_cost, avg_idle, span_avg;
>>  		unsigned long now = jiffies;
>> @@ -6416,7 +6454,7 @@ static int select_idle_sibling(struct
>> task_struct *p, int prev, int target)
>>  	/*
>>  	 * If the previous CPU is cache affine and idle, don't be
>> stupid:
>>  	 */
>> -	if (prev != target && cpus_share_cache(prev, target) &&
>> +	if (prev != target && cpus_share_resources(prev, target) &&
>>  	    (available_idle_cpu(prev) || sched_idle_cpu(prev)) &&
>>  	    asym_fits_capacity(task_util, prev))
>>  		return prev;
>> @@ -6442,7 +6480,7 @@ static int select_idle_sibling(struct
>> task_struct *p, int prev, int target)
>>  	p->recent_used_cpu = prev;
>>  	if (recent_used_cpu != prev &&
>>  	    recent_used_cpu != target &&
>> -	    cpus_share_cache(recent_used_cpu, target) &&
>> +	    cpus_share_resources(recent_used_cpu, target) &&
>>  	    (available_idle_cpu(recent_used_cpu) ||
>> sched_idle_cpu(recent_used_cpu)) &&
>>  	    cpumask_test_cpu(p->recent_used_cpu, p->cpus_ptr) &&
>>  	    asym_fits_capacity(task_util, recent_used_cpu)) {
>> @@ -6483,7 +6521,7 @@ static int select_idle_sibling(struct
>> task_struct *p, int prev, int target)
>>  		}
>>  	}
>>  
>> -	i = select_idle_cpu(p, sd, has_idle_core, target);
>> +	i = select_idle_cpu(p, sd, has_idle_core, prev, target);
>>  	if ((unsigned)i < nr_cpumask_bits)
>>  		return i;
>>  
> 
> .
> 


From biao.huang at mediatek.com  Wed Jan 26 17:58:52 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:52 +0800
Subject: [PATCH net-next v2 4/9] dt-bindings: net: mtk-star-emac: add support
 for MT8365
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-5-biao.huang@mediatek.com>

Add binding document for Ethernet on MT8365.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Reviewed-by: Bartosz Golaszewski <brgl at bgdev.pl>
---
 Documentation/devicetree/bindings/net/mediatek,star-emac.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
index e6a5ff208253..87a8b25b03a6 100644
--- a/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,star-emac.yaml
@@ -23,6 +23,7 @@ properties:
       - mediatek,mt8516-eth
       - mediatek,mt8518-eth
       - mediatek,mt8175-eth
+      - mediatek,mt8365-eth
 
   reg:
     maxItems: 1
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:51 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:51 +0800
Subject: [PATCH net-next v2 3/9] net: ethernet: mtk-star-emac: add support for
 MT8365 SoC
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-4-biao.huang@mediatek.com>

Add Ethernet driver support for MT8365 SoC.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
Signed-off-by: Fabien Parent <fparent at baylibre.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 75 ++++++++++++++++---
 1 file changed, 64 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index a8fbbbcd185b..a3884beaa3fe 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -151,6 +151,7 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_MAC_CLK_CONF		0x00ac
 #define MTK_STAR_MSK_MAC_CLK_CONF		GENMASK(7, 0)
 #define MTK_STAR_BIT_CLK_DIV_10			0x0a
+#define MTK_STAR_BIT_CLK_DIV_50			0x32
 
 /* Counter registers. */
 #define MTK_STAR_REG_C_RXOKPKT			0x0100
@@ -183,9 +184,11 @@ static const char *const mtk_star_clk_names[] = { "core", "reg", "trans" };
 #define MTK_STAR_REG_C_RX_TWIST			0x0218
 
 /* Ethernet CFG Control */
-#define MTK_PERICFG_REG_NIC_CFG_CON		0x03c4
-#define MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII	GENMASK(3, 0)
-#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	BIT(0)
+#define MTK_PERICFG_REG_NIC_CFG0_CON		0x03c4
+#define MTK_PERICFG_REG_NIC_CFG1_CON		0x03c8
+#define MTK_PERICFG_REG_NIC_CFG_CON_V2		0x0c10
+#define MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF	GENMASK(3, 0)
+#define MTK_PERICFG_BIT_NIC_CFG_CON_RMII	1
 
 /* Represents the actual structure of descriptors used by the MAC. We can
  * reuse the same structure for both TX and RX - the layout is the same, only
@@ -234,6 +237,7 @@ struct mtk_star_ring {
 };
 
 struct mtk_star_compat {
+	int (*set_interface_mode)(struct net_device *ndev);
 	unsigned char bit_clk_div;
 };
 
@@ -909,13 +913,6 @@ static void mtk_star_init_config(struct mtk_star_priv *priv)
 			   priv->compat_data->bit_clk_div);
 }
 
-static void mtk_star_set_mode_rmii(struct mtk_star_priv *priv)
-{
-	regmap_update_bits(priv->pericfg, MTK_PERICFG_REG_NIC_CFG_CON,
-			   MTK_PERICFG_MSK_NIC_CFG_CON_CFG_MII,
-			   MTK_PERICFG_BIT_NIC_CFG_CON_RMII);
-}
-
 static int mtk_star_enable(struct net_device *ndev)
 {
 	struct mtk_star_priv *priv = netdev_priv(ndev);
@@ -1531,7 +1528,13 @@ static int mtk_star_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	mtk_star_set_mode_rmii(priv);
+	if (priv->compat_data->set_interface_mode) {
+		ret = priv->compat_data->set_interface_mode(ndev);
+		if (ret) {
+			dev_err(dev, "Failed to set phy interface, err = %d\n", ret);
+			return -EINVAL;
+		}
+	}
 
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
@@ -1564,10 +1567,58 @@ static int mtk_star_probe(struct platform_device *pdev)
 	return devm_register_netdev(dev, ndev);
 }
 
+static int mt8516_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(priv->pericfg,
+				  MTK_PERICFG_REG_NIC_CFG0_CON,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  intf_val);
+}
+
+static int mt8365_set_interface_mode(struct net_device *ndev)
+{
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	struct device *dev = mtk_star_get_dev(priv);
+	unsigned int intf_val;
+
+	switch (priv->phy_intf) {
+	case PHY_INTERFACE_MODE_RMII:
+		intf_val = MTK_PERICFG_BIT_NIC_CFG_CON_RMII;
+		break;
+	default:
+		dev_err(dev, "This interface not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(priv->pericfg,
+				  MTK_PERICFG_REG_NIC_CFG_CON_V2,
+				  MTK_PERICFG_REG_NIC_CFG_CON_CFG_INTF,
+				  intf_val);
+}
+
 static const struct mtk_star_compat mtk_star_mt8516_compat = {
+	.set_interface_mode = mt8516_set_interface_mode,
 	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_10,
 };
 
+static const struct mtk_star_compat mtk_star_mt8365_compat = {
+	.set_interface_mode = mt8365_set_interface_mode,
+	.bit_clk_div = MTK_STAR_BIT_CLK_DIV_50,
+};
+
 static const struct of_device_id mtk_star_of_match[] = {
 	{ .compatible = "mediatek,mt8516-eth",
 	  .data = &mtk_star_mt8516_compat },
@@ -1575,6 +1626,8 @@ static const struct of_device_id mtk_star_of_match[] = {
 	  .data = &mtk_star_mt8516_compat },
 	{ .compatible = "mediatek,mt8175-eth",
 	  .data = &mtk_star_mt8516_compat },
+	{ .compatible = "mediatek,mt8365-eth",
+	  .data = &mtk_star_mt8365_compat },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, mtk_star_of_match);
-- 
2.25.1



From biao.huang at mediatek.com  Wed Jan 26 17:58:57 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Thu, 27 Jan 2022 09:58:57 +0800
Subject: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate tx/rx
 handling with two NAPIs
In-Reply-To: <20220127015857.9868-1-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
Message-ID: <20220127015857.9868-10-biao.huang@mediatek.com>

Current driver may lost tx interrupts under bidirectional test with iperf3,
which leads to some unexpected issues.

This patch let rx/tx interrupt enable/disable separately, and rx/tx are
handled in different NAPIs.

Signed-off-by: Biao Huang <biao.huang at mediatek.com>
Signed-off-by: Yinghua Pan <ot_yinghua.pan at mediatek.com>
---
 drivers/net/ethernet/mediatek/mtk_star_emac.c | 317 ++++++++++--------
 1 file changed, 181 insertions(+), 136 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 167a019fd8f5..e5bcf851511a 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -229,7 +229,7 @@ struct mtk_star_ring_desc_data {
 	struct sk_buff *skb;
 };
 
-#define MTK_STAR_RING_NUM_DESCS			128
+#define MTK_STAR_RING_NUM_DESCS			512
 #define MTK_STAR_NUM_TX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_RX_DESCS			MTK_STAR_RING_NUM_DESCS
 #define MTK_STAR_NUM_DESCS_TOTAL		(MTK_STAR_RING_NUM_DESCS * 2)
@@ -264,7 +264,8 @@ struct mtk_star_priv {
 	struct mtk_star_ring rx_ring;
 
 	struct mii_bus *mii;
-	struct napi_struct napi;
+	struct napi_struct tx_napi;
+	struct napi_struct rx_napi;
 
 	struct device_node *phy_node;
 	phy_interface_t phy_intf;
@@ -380,19 +381,16 @@ mtk_star_ring_push_head_tx(struct mtk_star_ring *ring,
 	mtk_star_ring_push_head(ring, desc_data, flags);
 }
 
-static unsigned int mtk_star_ring_num_used_descs(struct mtk_star_ring *ring)
+static unsigned int mtk_star_tx_ring_avail(struct mtk_star_ring *ring)
 {
-	return abs(ring->head - ring->tail);
-}
+	u32 avail;
 
-static bool mtk_star_ring_full(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) == MTK_STAR_RING_NUM_DESCS;
-}
+	if (ring->tail > ring->head)
+		avail = ring->tail - ring->head - 1;
+	else
+		avail = MTK_STAR_RING_NUM_DESCS - ring->head + ring->tail - 1;
 
-static bool mtk_star_ring_descs_available(struct mtk_star_ring *ring)
-{
-	return mtk_star_ring_num_used_descs(ring) > 0;
+	return avail;
 }
 
 static dma_addr_t mtk_star_dma_map_rx(struct mtk_star_priv *priv,
@@ -415,7 +413,7 @@ static void mtk_star_dma_unmap_rx(struct mtk_star_priv *priv,
 }
 
 static dma_addr_t mtk_star_dma_map_tx(struct mtk_star_priv *priv,
-				      struct sk_buff *skb)
+					     struct sk_buff *skb)
 {
 	struct device *dev = mtk_star_get_dev(priv);
 
@@ -437,6 +435,36 @@ static void mtk_star_nic_disable_pd(struct mtk_star_priv *priv)
 			  MTK_STAR_BIT_MAC_CFG_NIC_PD);
 }
 
+static void mtk_star_enable_dma_irq(struct mtk_star_priv *priv,
+				    bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value &= ~MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value &= ~MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
+static void mtk_star_disable_dma_irq(struct mtk_star_priv *priv,
+				     bool rx, bool tx)
+{
+	u32 value;
+
+	regmap_read(priv->regs, MTK_STAR_REG_INT_MASK, &value);
+
+	if (tx)
+		value |= MTK_STAR_BIT_INT_STS_TNTC;
+	if (rx)
+		value |= MTK_STAR_BIT_INT_STS_FNRC;
+
+	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, value);
+}
+
 /* Unmask the three interrupts we care about, mask all others. */
 static void mtk_star_intr_enable(struct mtk_star_priv *priv)
 {
@@ -452,20 +480,11 @@ static void mtk_star_intr_disable(struct mtk_star_priv *priv)
 	regmap_write(priv->regs, MTK_STAR_REG_INT_MASK, ~0);
 }
 
-static unsigned int mtk_star_intr_read(struct mtk_star_priv *priv)
-{
-	unsigned int val;
-
-	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
-
-	return val;
-}
-
 static unsigned int mtk_star_intr_ack_all(struct mtk_star_priv *priv)
 {
 	unsigned int val;
 
-	val = mtk_star_intr_read(priv);
+	regmap_read(priv->regs, MTK_STAR_REG_INT_STS, &val);
 	regmap_write(priv->regs, MTK_STAR_REG_INT_STS, val);
 
 	return val;
@@ -737,25 +756,46 @@ static void mtk_star_free_tx_skbs(struct mtk_star_priv *priv)
 	mtk_star_ring_free_skbs(priv, ring, mtk_star_dma_unmap_tx);
 }
 
-/* All processing for TX and RX happens in the napi poll callback.
- *
- * FIXME: The interrupt handling should be more fine-grained with each
- * interrupt enabled/disabled independently when needed. Unfortunatly this
- * turned out to impact the driver's stability and until we have something
- * working properly, we're disabling all interrupts during TX & RX processing
- * or when resetting the counter registers.
+/* mtk_star_handle_irq - Interrupt Handler.
+ * @irq: interrupt number.
+ * @data: pointer to a network interface device structure.
+ * Description : this is the driver interrupt service routine.
+ * it mainly handles:
+ *  1. tx complete interrupt for frame transmission.
+ *  2. rx complete interrupt for frame reception.
+ *  3. MAC Management Counter interrupt to avoid counter overflow.
  */
 static irqreturn_t mtk_star_handle_irq(int irq, void *data)
 {
-	struct mtk_star_priv *priv;
-	struct net_device *ndev;
+	struct net_device *ndev = data;
+	struct mtk_star_priv *priv = netdev_priv(ndev);
+	unsigned int intr_status = mtk_star_intr_ack_all(priv);
+	unsigned long flags = 0;
+
+	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
+		if (napi_schedule_prep(&priv->rx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Rx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, true, false);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->rx_napi);
+		}
+	}
 
-	ndev = data;
-	priv = netdev_priv(ndev);
+	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
+		if (napi_schedule_prep(&priv->tx_napi)) {
+			spin_lock_irqsave(&priv->lock, flags);
+			/* mask Tx Complete interrupt */
+			mtk_star_disable_dma_irq(priv, false, true);
+			spin_unlock_irqrestore(&priv->lock, flags);
+			__napi_schedule_irqoff(&priv->tx_napi);
+		}
+	}
 
-	if (netif_running(ndev)) {
-		mtk_star_intr_disable(priv);
-		napi_schedule(&priv->napi);
+	/* interrupt is triggered once any counters reach 0x8000000 */
+	if (intr_status & MTK_STAR_REG_INT_STS_MIB_CNT_TH) {
+		mtk_star_update_stats(priv);
+		mtk_star_reset_counters(priv);
 	}
 
 	return IRQ_HANDLED;
@@ -971,7 +1011,8 @@ static int mtk_star_enable(struct net_device *ndev)
 	if (ret)
 		goto err_free_skbs;
 
-	napi_enable(&priv->napi);
+	napi_enable(&priv->tx_napi);
+	napi_enable(&priv->rx_napi);
 
 	mtk_star_intr_ack_all(priv);
 	mtk_star_intr_enable(priv);
@@ -1004,7 +1045,8 @@ static void mtk_star_disable(struct net_device *ndev)
 	struct mtk_star_priv *priv = netdev_priv(ndev);
 
 	netif_stop_queue(ndev);
-	napi_disable(&priv->napi);
+	napi_disable(&priv->tx_napi);
+	napi_disable(&priv->rx_napi);
 	mtk_star_intr_disable(priv);
 	mtk_star_dma_disable(priv);
 	mtk_star_intr_ack_all(priv);
@@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 	struct mtk_star_ring *ring = &priv->tx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
 	struct mtk_star_ring_desc_data desc_data;
+	int nfrags = skb_shinfo(skb)->nr_frags;
+
+	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
+		if (!netif_queue_stopped(ndev)) {
+			netif_stop_queue(ndev);
+			/* This is a hard error, log it. */
+			netdev_err(priv->ndev, "%s: Tx Ring full when queue awake\n",
+				   __func__);
+		}
+		return NETDEV_TX_BUSY;
+	}
 
 	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
 	if (dma_mapping_error(dev, desc_data.dma_addr))
@@ -1050,18 +1103,10 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
 
 	desc_data.skb = skb;
 	desc_data.len = skb->len;
-
-	spin_lock_bh(&priv->lock);
-
 	mtk_star_ring_push_head_tx(ring, &desc_data);
 
 	netdev_sent_queue(ndev, skb->len);
 
-	if (mtk_star_ring_full(ring))
-		netif_stop_queue(ndev);
-
-	spin_unlock_bh(&priv->lock);
-
 	mtk_star_dma_resume_tx(priv);
 
 	return NETDEV_TX_OK;
@@ -1092,23 +1137,31 @@ static int mtk_star_tx_complete_one(struct mtk_star_priv *priv)
 	return ret;
 }
 
-static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
+static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
 {
-	struct mtk_star_ring *ring = &priv->tx_ring;
-	struct net_device *ndev = priv->ndev;
-	int ret, pkts_compl, bytes_compl;
+	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
+	struct mtk_star_priv *priv;
+	struct mtk_star_ring *ring;
+	struct net_device *ndev;
+	unsigned long flags = 0;
+	unsigned int entry;
 	bool wake = false;
 
-	spin_lock(&priv->lock);
+	priv = container_of(napi, struct mtk_star_priv, tx_napi);
+	ndev = priv->ndev;
 
-	for (pkts_compl = 0, bytes_compl = 0;;
+	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));
+	ring = &priv->tx_ring;
+	entry = ring->tail;
+	for (pkts_compl = 0, bytes_compl = 0;
+	     (entry != ring->head) && (count < budget);
 	     pkts_compl++, bytes_compl += ret, wake = true) {
-		if (!mtk_star_ring_descs_available(ring))
-			break;
 
 		ret = mtk_star_tx_complete_one(priv);
 		if (ret < 0)
 			break;
+		count++;
+		entry = ring->tail;
 	}
 
 	netdev_completed_queue(ndev, pkts_compl, bytes_compl);
@@ -1116,7 +1169,16 @@ static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
 	if (wake && netif_queue_stopped(ndev))
 		netif_wake_queue(ndev);
 
-	spin_unlock(&priv->lock);
+	__netif_tx_unlock_bh(netdev_get_tx_queue(priv->ndev, 0));
+
+	count = min(count, budget);
+	if (count < budget && napi_complete_done(napi, count)) {
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, false, true);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+
+	return count;
 }
 
 static void mtk_star_netdev_get_stats64(struct net_device *ndev,
@@ -1196,7 +1258,7 @@ static const struct ethtool_ops mtk_star_ethtool_ops = {
 	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
 };
 
-static int mtk_star_receive_packet(struct mtk_star_priv *priv)
+static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
 {
 	struct mtk_star_ring *ring = &priv->rx_ring;
 	struct device *dev = mtk_star_get_dev(priv);
@@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
 	struct net_device *ndev = priv->ndev;
 	struct sk_buff *curr_skb, *new_skb;
 	dma_addr_t new_dma_addr;
-	int ret;
+	int ret, count = 0;
 
-	spin_lock(&priv->lock);
-	ret = mtk_star_ring_pop_tail(ring, &desc_data);
-	spin_unlock(&priv->lock);
-	if (ret)
-		return -1;
+	while (count < budget) {
+		ret = mtk_star_ring_pop_tail(ring, &desc_data);
+		if (ret)
+			return -1;
 
-	curr_skb = desc_data.skb;
+		curr_skb = desc_data.skb;
 
-	if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
-	    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
-		/* Error packet -> drop and reuse skb. */
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		if ((desc_data.flags & MTK_STAR_DESC_BIT_RX_CRCE) ||
+		    (desc_data.flags & MTK_STAR_DESC_BIT_RX_OSIZE)) {
+			/* Error packet -> drop and reuse skb. */
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	/* Prepare new skb before receiving the current one. Reuse the current
-	 * skb if we fail at any point.
-	 */
-	new_skb = mtk_star_alloc_skb(ndev);
-	if (!new_skb) {
-		ndev->stats.rx_dropped++;
-		new_skb = curr_skb;
-		goto push_new_skb;
-	}
+		/* Prepare new skb before receiving the current one.
+		 * Reuse the current skb if we fail at any point.
+		 */
+		new_skb = mtk_star_alloc_skb(ndev);
+		if (!new_skb) {
+			ndev->stats.rx_dropped++;
+			new_skb = curr_skb;
+			goto push_new_skb;
+		}
 
-	new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
-	if (dma_mapping_error(dev, new_dma_addr)) {
-		ndev->stats.rx_dropped++;
-		dev_kfree_skb(new_skb);
-		new_skb = curr_skb;
-		netdev_err(ndev, "DMA mapping error of RX descriptor\n");
-		goto push_new_skb;
-	}
+		new_dma_addr = mtk_star_dma_map_rx(priv, new_skb);
+		if (dma_mapping_error(dev, new_dma_addr)) {
+			ndev->stats.rx_dropped++;
+			dev_kfree_skb(new_skb);
+			new_skb = curr_skb;
+			netdev_err(ndev, "DMA mapping error of RX descriptor\n");
+			goto push_new_skb;
+		}
 
-	/* We can't fail anymore at this point: it's safe to unmap the skb. */
-	mtk_star_dma_unmap_rx(priv, &desc_data);
+		/* We can't fail anymore at this point:
+		 * it's safe to unmap the skb.
+		 */
+		mtk_star_dma_unmap_rx(priv, &desc_data);
 
-	skb_put(desc_data.skb, desc_data.len);
-	desc_data.skb->ip_summed = CHECKSUM_NONE;
-	desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
-	desc_data.skb->dev = ndev;
-	netif_receive_skb(desc_data.skb);
+		skb_put(desc_data.skb, desc_data.len);
+		desc_data.skb->ip_summed = CHECKSUM_NONE;
+		desc_data.skb->protocol = eth_type_trans(desc_data.skb, ndev);
+		desc_data.skb->dev = ndev;
+		netif_receive_skb(desc_data.skb);
 
-	/* update dma_addr for new skb */
-	desc_data.dma_addr = new_dma_addr;
+		/* update dma_addr for new skb */
+		desc_data.dma_addr = new_dma_addr;
 
 push_new_skb:
-	desc_data.len = skb_tailroom(new_skb);
-	desc_data.skb = new_skb;
-
-	spin_lock(&priv->lock);
-	mtk_star_ring_push_head_rx(ring, &desc_data);
-	spin_unlock(&priv->lock);
-
-	return 0;
-}
 
-static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
-{
-	int received, ret;
+		count++;
 
-	for (received = 0, ret = 0; received < budget && ret == 0; received++)
-		ret = mtk_star_receive_packet(priv);
+		desc_data.len = skb_tailroom(new_skb);
+		desc_data.skb = new_skb;
+		mtk_star_ring_push_head_rx(ring, &desc_data);
+	}
 
 	mtk_star_dma_resume_rx(priv);
 
-	return received;
+	return count;
 }
 
-static int mtk_star_poll(struct napi_struct *napi, int budget)
+static int mtk_star_rx_poll(struct napi_struct *napi, int budget)
 {
 	struct mtk_star_priv *priv;
-	unsigned int status;
-	int received = 0;
+	unsigned long flags = 0;
+	int work_done = 0;
 
-	priv = container_of(napi, struct mtk_star_priv, napi);
+	priv = container_of(napi, struct mtk_star_priv, rx_napi);
 
-	status = mtk_star_intr_read(priv);
-	mtk_star_intr_ack_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_TNTC)
-		/* Clean-up all TX descriptors. */
-		mtk_star_tx_complete_all(priv);
-
-	if (status & MTK_STAR_BIT_INT_STS_FNRC)
-		/* Receive up to $budget packets. */
-		received = mtk_star_process_rx(priv, budget);
-
-	if (unlikely(status & MTK_STAR_REG_INT_STS_MIB_CNT_TH)) {
-		mtk_star_update_stats(priv);
-		mtk_star_reset_counters(priv);
+	work_done = mtk_star_rx(priv, budget);
+	if (work_done < budget) {
+		napi_complete_done(napi, work_done);
+		spin_lock_irqsave(&priv->lock, flags);
+		mtk_star_enable_dma_irq(priv, true, false);
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
-	if (received < budget)
-		napi_complete_done(napi, received);
-
-	mtk_star_intr_enable(priv);
-
-	return received;
+	return work_done;
 }
 
 static void mtk_star_mdio_rwok_clear(struct mtk_star_priv *priv)
@@ -1478,6 +1519,7 @@ static int mtk_star_set_timing(struct mtk_star_priv *priv)
 
 	return 0;
 }
+
 static int mtk_star_probe(struct platform_device *pdev)
 {
 	struct device_node *of_node;
@@ -1604,7 +1646,10 @@ static int mtk_star_probe(struct platform_device *pdev)
 	ndev->netdev_ops = &mtk_star_netdev_ops;
 	ndev->ethtool_ops = &mtk_star_ethtool_ops;
 
-	netif_napi_add(ndev, &priv->napi, mtk_star_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_napi_add(ndev, &priv->rx_napi,
+		       mtk_star_rx_poll, MTK_STAR_NAPI_WEIGHT);
+	netif_tx_napi_add(ndev, &priv->tx_napi,
+			  mtk_star_tx_poll, MTK_STAR_NAPI_WEIGHT);
 
 	return devm_register_netdev(dev, ndev);
 }
-- 
2.25.1



From tim.c.chen at linux.intel.com  Wed Jan 26 18:30:23 2022
From: tim.c.chen at linux.intel.com (Tim Chen)
Date: Wed, 26 Jan 2022 18:30:23 -0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <b793e565-670d-cc66-6947-7d927ebcb8b3@huawei.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>
 <b793e565-670d-cc66-6947-7d927ebcb8b3@huawei.com>
Message-ID: <95f82bf3524289bfbcaeee6e83b6dac48ed07f25.camel@linux.intel.com>

On Thu, 2022-01-27 at 10:02 +0800, Yicong Yang wrote:
> On 2022/1/27 9:14, Tim Chen wrote:
> > On Wed, 2022-01-26 at 16:09 +0800, Yicong Yang wrote:
> > > From: Barry Song <song.bao.hua at hisilicon.com>
> > > 
> > > For platforms having clusters like Kunpeng920, CPUs within the
> > > same
> > > cluster have lower latency when synchronizing and accessing
> > > shared
> > > resources like cache. Thus, this patch tries to find an idle cpu
> > > within the cluster of the target CPU before scanning the whole
> > > LLC
> > > to gain lower latency.
> > > 
> > > Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> > > patch doesn't consider SMT for this moment.
> > > 
> > > Testing has been done on Kunpeng920 by pinning tasks to one numa
> > > and two numa. On Kunpeng920, Each numa has 8 clusters and each
> > > cluster has 4 CPUs.
> > > 
> > > With this patch, We noticed enhancement on tbench within one
> > > numa or cross two numa.
> > > 
> > > On numa 0:
> > >                             5.17-rc1                patched
> > > Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> > > Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> > > Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> > > Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> > > Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> > > Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> > > Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> > > Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> > > 
> > > On numa 0-1:
> > >                             5.17-rc1                patched
> > > Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> > > Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> > > Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> > > Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> > > Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> > > Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> > > Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> > > Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> > > Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> > > Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> > > 
> > > This will also help to improve the MySQL. With MySQL server
> > > running on numa 0 and client running on numa 1, both QPS and
> > > latency is imporved on read-write case:
> > >                         5.17-rc1        patched
> > > QPS-16threads        143333.2633    145077.4033(+1.22%)
> > > QPS-24threads        195085.9367    202719.6133(+3.91%)
> > > QPS-32threads        241165.6867      249020.74(+3.26%)
> > > QPS-64threads        244586.8433    253387.7567(+3.60%)
> > > avg-lat-16threads           2.23           2.19(+1.19%)
> > > avg-lat-24threads           2.46           2.36(+3.79%)
> > > avg-lat-36threads           2.66           2.57(+3.26%)
> > > avg-lat-64threads           5.23           5.05(+3.44%)
> > > 
> > > Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> > > Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> > > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> > > ---
> > >  kernel/sched/fair.c | 46
> > > +++++++++++++++++++++++++++++++++++++++++
> > > ----
> > >  1 file changed, 42 insertions(+), 4 deletions(-)
> > > 
> > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > > index 5146163bfabb..2f84a933aedd 100644
> > > --- a/kernel/sched/fair.c
> > > +++ b/kernel/sched/fair.c
> > > @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct
> > > task_struct *p, struct sched_domain *sd
> > >  
> > >  #endif /* CONFIG_SCHED_SMT */
> > >  
> > > +#ifdef CONFIG_SCHED_CLUSTER
> > > +/*
> > > + * Scan the cluster domain for idle CPUs and clear cluster
> > > cpumask
> > > after scanning
> > > + */
> > > +static inline int scan_cluster(struct task_struct *p, int
> > > prev_cpu,
> > > int target)
> > > +{
> > > +	struct cpumask *cpus =
> > > this_cpu_cpumask_var_ptr(select_idle_mask);
> > > +	struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster,
> > > target));
> > > +	int cpu, idle_cpu;
> > > +
> > > +	/* TODO: Support SMT case while a machine with both cluster and
> > > SMT born */
> > 
> > This is probably a clearer comment
> > 
> > 	/* TODO: Support SMT system with cluster topology */
> > 
> > > +	if (!sched_smt_active() && sd) {
> > > +		for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> > > +			idle_cpu = __select_idle_cpu(cpu, p);
> > >   */
> > > -static int select_idle_cpu(struct task_struct *p, struct
> > > sched_domain *sd, bool has_idle_core, int target)
> > > +static int select_idle_cpu(struct task_struct *p, struct
> > > sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
> > >  {
> > >  	struct cpumask *cpus =
> > > this_cpu_cpumask_var_ptr(select_idle_mask);
> > >  	int i, cpu, idle_cpu = -1, nr = INT_MAX;
> > > @@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct
> > > task_struct
> > > *p, struct sched_domain *sd, bool
> > >  
> > >  	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> > >  
> > > +	idle_cpu = scan_cluster(p, prev_cpu, target);
> > 
> > Shouldn't "cpus" from 
> > 
> > cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> > 
> > be passed to scan_cluster, to make sure that the cpu returned is 
> > in the affinity mask of the task? I don't see p->cpus_ptr
> > being checked in scan_cluster to make sure the cpu found is in the
> > affinity mask.
> > 
> 
> The cpus scanned in scan_cluster() is the intersection of
> select_idle_mask and sched_domain_span(cluster_sd), and
> we limited the select_idle_mask in the tasks' affinity mask
> before we enter scan_cluster() here.

Ah, I missed the fact that cpus point to the select_idle_mask.

Thanks.

Tim




From benwolsieffer at gmail.com  Wed Jan 26 18:33:19 2022
From: benwolsieffer at gmail.com (Ben Wolsieffer)
Date: Wed, 26 Jan 2022 21:33:19 -0500
Subject: [PATCH 3/3] ARM: dts: qcom: basic HP TouchPad support
In-Reply-To: <YfDKTGQDh3tDMECz@builder.lan>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
 <9f19df2a0017b71547445ac34df221e827c45bd0.1643075547.git.benwolsieffer@gmail.com>
 <YfDKTGQDh3tDMECz@builder.lan>
Message-ID: <YfIEb+BSNI3maH79@Dell-Inspiron-15>

On Tue, Jan 25, 2022 at 10:13:00PM -0600, Bjorn Andersson wrote:
> On Mon 24 Jan 20:07 CST 2022, Ben Wolsieffer wrote:
> 
> > Modify the Dragonboard device tree to support the most basic hardware on
> > the HP TouchPad. The headphone UART port and eMMC are supported.
> > 
> 
> We typically don't have one commit for the cloning and then one to
> update the content, in particular since your diffstat became rather
> weird.
> 
> That said, got some comments below, things that I wouldn't have spotted
> if you sent this as just a new file.

Ok, I'll squash those for v2.

> > -			dragon_sdcc1_pins: sdcc1 {
> > +			/* eMMC pins, all 8 data lines connected */
> > +			emmc_pins: sdcc1 {
> >  				mux {
> >  					pins = "gpio159", "gpio160", "gpio161",
> >  					     "gpio162", "gpio163", "gpio164",
> >  					     "gpio165", "gpio166", "gpio167",
> >  					     "gpio168";
> > -					     function = "sdc1";
> > +					function = "sdc1";
> >  				};
> >  				clk {
> >  					pins = "gpio167"; /* SDC1 CLK */
> [..]
> > @@ -171,205 +77,33 @@ pinconf {
> >  				};
> >  			};
> >  
> > -			dragon_gsbi12_i2c_pins: gsbi12_i2c {
> > -				mux {
> > -					pins = "gpio115", "gpio116";
> > -					function = "gsbi12";
> > -				};
> > -				pinconf {
> > -					pins = "gpio115", "gpio116";
> > -					drive-strength = <16>;
> > -					/* These have external pull-up 4.7kOhm to 1.8V */
> > -					bias-disable;
> > -				};
> > -			};
> > -
> > -			/* Primary serial port uart 0 pins */
> > -			dragon_gsbi12_serial_pins: gsbi12_serial {
> > +			/* Headphone UART pins */
> > +			headphone_uart_pins: gsbi12_serial {
> >  				mux {
> >  					pins = "gpio117", "gpio118";
> >  					function = "gsbi12";
> >  				};
> > -				tx {
> > -					pins = "gpio117";
> > -					drive-strength = <8>;
> > -					bias-disable;
> > -				};
> >  				rx {
> > -					pins = "gpio118";
> > +					pins = "gpio117";
> >  					drive-strength = <2>;
> >  					bias-pull-up;
> >  				};
> > -			};
> 
> I find it hard to conclude what the resulting snippet is from this
> chunk, did rx swap place from gpio118 to gpio117?

Yes, I made that swap based on comments in the downstream kernel, but,
now that I think about it, there's a good chance those comments are
wrong. The downstream kernel configures both pins as 8 mA drive with no
bias, so no one would ever notice that they were swapped. I think I'll
swap them back in v2. In practice I think the pin configuration makes
little difference, but should I keep the config from the Dragonboard or
match the downstream kernel?

> [..]
> > @@ -814,14 +378,16 @@ l20 {
> >  					bias-pull-down;
> >  				};
> >  				l21 {
> > -					// 1.1 V according to schematic
> >  					regulator-min-microvolt = <1200000>;
> >  					regulator-max-microvolt = <1200000>;
> >  					bias-pull-down;
> > -					regulator-always-on;
> > +					/*
> > +					 * RPM driver can't handle always-on regulators that are
> > +					 * supplied by regulators initialized after them.
> > +					 */
> 
> That looks like an oversight that should be corrected, perhaps it needs
> similar attention that was given to the smd-rpm driver recently?
> 
> But this makes me wonder, how can this work on the other board? Linus?

It probably doesn't work as intended, but doesn't cause a major
problem either. I only noticed the failure while looking through dmesg.
As soon as the RPM driver probe gets to an always on regulator with a not
yet initialized supply, devm_regulator_register() returns -EAGAIN, it
breaks out of the loop, and the rest of the regulators don't get
initialized. The initialization is retried several times during boot
(because of -EAGAIN), but always fails at the same spot. This doesn't
actually seem to cause any visible problem, other than errors in dmesg.

I tried making the driver continue to initialize the rest of the
regulators even if one fails with -EAGAIN, but still return -EAGAIN from
probe(). My thought was that this would cause probe to be retried later,
and initialization would succeed now that the supply regulators were
available, but instead it seems to hang before any console output.

I don't know if the regulator supplies are correct either, because the
downstream kernel doesn't specify them. I also know next to nothing about
the RPM, so I would definitely appreciate a review from someone familiar
with it.

> > +					// regulator-always-on;
> >  				};
> >  				l22 {
> > -					// 1.2 V according to schematic
> >  					regulator-min-microvolt = <1150000>;
> >  					regulator-max-microvolt = <1150000>;
> >  					bias-pull-down;
> > @@ -845,7 +411,7 @@ l25 {
> >  				};
> >  
> >  				s0 {
> > -					// regulator-min-microvolt = <500000>;
> > +					// regulator-min-microvolt = <800000>;
> >  					// regulator-max-microvolt = <1325000>;
> 
> This looks like the full range the regulator could do, do you see a
> reason for documenting that here? Unless there's a good reason I think
> you should leave the commented min/max out.

That was just copied from the Dragonboard DTS, with updated values from
the downstream kernel. I assume some kind of voltage/frequency scaling
driver is needed to actually support a range of voltages here, so I
guess the comments could serve as a reference if that was ever
implemented.



From tim.c.chen at linux.intel.com  Wed Jan 26 18:36:47 2022
From: tim.c.chen at linux.intel.com (Tim Chen)
Date: Wed, 26 Jan 2022 18:36:47 -0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <95f82bf3524289bfbcaeee6e83b6dac48ed07f25.camel@linux.intel.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>
 <b793e565-670d-cc66-6947-7d927ebcb8b3@huawei.com>
 <95f82bf3524289bfbcaeee6e83b6dac48ed07f25.camel@linux.intel.com>
Message-ID: <62bbdd77f70f7b46a044685668e33fb031812c38.camel@linux.intel.com>

On Wed, 2022-01-26 at 18:30 -0800, Tim Chen wrote:
> On Thu, 2022-01-27 at 10:02 +0800, Yicong Yang wrote:
> > On 2022/1/27 9:14, Tim Chen wrote:
> > > On Wed, 2022-01-26 at 16:09 +0800, Yicong Yang wrote:
> > > > From: Barry Song <song.bao.hua at hisilicon.com>
> > > > 
> > > > For platforms having clusters like Kunpeng920, CPUs within the
> > > > same
> > > > cluster have lower latency when synchronizing and accessing
> > > > shared
> > > > resources like cache. Thus, this patch tries to find an idle
> > > > cpu
> > > > within the cluster of the target CPU before scanning the whole
> > > > LLC
> > > > to gain lower latency.
> > > > 
> > > > Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so
> > > > this
> > > > patch doesn't consider SMT for this moment.
> > > > 
> > > > Testing has been done on Kunpeng920 by pinning tasks to one
> > > > numa
> > > > and two numa. On Kunpeng920, Each numa has 8 clusters and each
> > > > cluster has 4 CPUs.
> > > > 
> > > > With this patch, We noticed enhancement on tbench within one
> > > > numa or cross two numa.
> > > > 
> > > > On numa 0:
> > > >                             5.17-rc1                patched
> > > > Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> > > > Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> > > > Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> > > > Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> > > > Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> > > > Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> > > > Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> > > > Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> > > > 
> > > > On numa 0-1:
> > > >                             5.17-rc1                patched
> > > > Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> > > > Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> > > > Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> > > > Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> > > > Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> > > > Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> > > > Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> > > > Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> > > > Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> > > > Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> > > > 
> > > > This will also help to improve the MySQL. With MySQL server
> > > > running on numa 0 and client running on numa 1, both QPS and
> > > > latency is imporved on read-write case:
> > > >                         5.17-rc1        patched
> > > > QPS-16threads        143333.2633    145077.4033(+1.22%)
> > > > QPS-24threads        195085.9367    202719.6133(+3.91%)
> > > > QPS-32threads        241165.6867      249020.74(+3.26%)
> > > > QPS-64threads        244586.8433    253387.7567(+3.60%)
> > > > avg-lat-16threads           2.23           2.19(+1.19%)
> > > > avg-lat-24threads           2.46           2.36(+3.79%)
> > > > avg-lat-36threads           2.66           2.57(+3.26%)
> > > > avg-lat-64threads           5.23           5.05(+3.44%)
> > > > 
> > > > Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> > > > Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> > > > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> > > > ---
> > > >  kernel/sched/fair.c | 46
> > > > +++++++++++++++++++++++++++++++++++++++++
> > > > ----
> > > >  1 file changed, 42 insertions(+), 4 deletions(-)
> > > > 
> > > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > > > index 5146163bfabb..2f84a933aedd 100644
> > > > --- a/kernel/sched/fair.c
> > > > +++ b/kernel/sched/fair.c
> > > > @@ -6262,12 +6262,46 @@ static inline int
> > > > select_idle_smt(struct
> > > > task_struct *p, struct sched_domain *sd
> > > >  
> > > >  #endif /* CONFIG_SCHED_SMT */
> > > >  
> > > > +#ifdef CONFIG_SCHED_CLUSTER
> > > > +/*
> > > > + * Scan the cluster domain for idle CPUs and clear cluster
> > > > cpumask
> > > > after scanning
> > > > + */
> > > > +static inline int scan_cluster(struct task_struct *p, int
> > > > prev_cpu,
> > > > int target)
> > > > +{
> > > > +	struct cpumask *cpus =
> > > > this_cpu_cpumask_var_ptr(select_idle_mask);
> > > > +	struct sched_domain *sd =
> > > > rcu_dereference(per_cpu(sd_cluster,
> > > > target));
> > > > +	int cpu, idle_cpu;
> > > > +
> > > > +	/* TODO: Support SMT case while a machine with both
> > > > cluster and
> > > > SMT born */
> > > 
> > > This is probably a clearer comment
> > > 
> > > 	/* TODO: Support SMT system with cluster topology */
> > > 
> > > > +	if (!sched_smt_active() && sd) {
> > > > +		for_each_cpu_and(cpu, cpus,
> > > > sched_domain_span(sd)) {
> > > > +			idle_cpu = __select_idle_cpu(cpu, p);
> > > >   */
> > > > -static int select_idle_cpu(struct task_struct *p, struct
> > > > sched_domain *sd, bool has_idle_core, int target)
> > > > +static int select_idle_cpu(struct task_struct *p, struct
> > > > sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
> > > >  {
> > > >  	struct cpumask *cpus =
> > > > this_cpu_cpumask_var_ptr(select_idle_mask);
> > > >  	int i, cpu, idle_cpu = -1, nr = INT_MAX;
> > > > @@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct
> > > > task_struct
> > > > *p, struct sched_domain *sd, bool
> > > >  
> > > >  	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> > > >  
> > > > +	idle_cpu = scan_cluster(p, prev_cpu, target);
> > > 
> > > Shouldn't "cpus" from 
> > > 
> > > cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
> > > 
> > > be passed to scan_cluster, to make sure that the cpu returned is 
> > > in the affinity mask of the task? I don't see p->cpus_ptr
> > > being checked in scan_cluster to make sure the cpu found is in
> > > the
> > > affinity mask.
> > > 
> > 
> > The cpus scanned in scan_cluster() is the intersection of
> > select_idle_mask and sched_domain_span(cluster_sd), and
> > we limited the select_idle_mask in the tasks' affinity mask
> > before we enter scan_cluster() here.
> 
> Ah, I missed the fact that cpus point to the select_idle_mask.
> 

I think it will be easier to read the code if you pass "cpus" directly
to scan cluster, rather than making this implicit, and having this
assignment 

*cpus = this_cpu_cpumask_var_ptr(select_idle_mask);

again in scan_cluster.

Tim




From patchwork-bot+netdevbpf at kernel.org  Wed Jan 26 18:50:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 27 Jan 2022 02:50:10 +0000
Subject: [PATCH v2] net: ethernet: cortina: permit to set mac address in DT
In-Reply-To: <20220125210811.54350-1-clabbe@baylibre.com>
References: <20220125210811.54350-1-clabbe@baylibre.com>
Message-ID: <164325181066.16805.3054747911337839049.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (master)
by Jakub Kicinski <kuba at kernel.org>:

On Tue, 25 Jan 2022 21:08:11 +0000 you wrote:
> Add ability of setting mac address in DT for cortina ethernet driver.
> 
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> ---
> Changes since v1:
> - fixed reverse christmas tree of the mac variable
> 
> [...]

Here is the summary with links:
  - [v2] net: ethernet: cortina: permit to set mac address in DT
    https://git.kernel.org/netdev/net-next/c/15f75fd31932

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From yunfei.dong at mediatek.com  Wed Jan 26 18:55:36 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:36 +0800
Subject: [PATCH v1, 0/8] support mt8195 decoder
Message-ID: <20220127025544.10854-1-yunfei.dong@mediatek.com>

Firstly, add mt8195 soc lat hardware and compatible, then add documents.
For vp8 only support MM21 mode, H264/vp9 support MT21C, need to separate
them. Next, initialize vp9 stateless decoder parameters. Lastly, enable
H264 inner racing mode to reduce hardware latency.

Patch 1~4 add mt8195 soc lat hardware and compatible, then add documents.
Patch 5 using different format for different codecs.
Patch 6 prevent kernel crash when scp reboot.
Patch 7 init vp9 stateless decoder parameters.
Patch 8 enable H264 inner racing mode to reduce hardware latency.
---
This patch depends on "support mt8186 decoder"[1]

[1]  https://patchwork.kernel.org/project/linux-mediatek/cover/20220122075606.19373-1-yunfei.dong at mediatek.com
---
Tinghan Shen (1):
  media: mtk-vcodec: prevent kernel crash when scp ipi timeout

Yunfei Dong (7):
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for lat soc
  media: mtk-vcodec: Add to support lat soc hardware
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8195
  media: mtk-vcodec: Adds compatible for mt8195
  media: mtk-vcodec: Different codec using different capture format
  media: uapi: Init VP9 stateless decode params
  media: mtk-vcodec: Add to support H264 inner racing mode

 .../media/mediatek,vcodec-subdev-decoder.yaml | 50 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 41 +++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  8 +++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 12 +++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 50 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 11 ++++
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 23 +++++++--
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  5 ++
 drivers/media/v4l2-core/v4l2-ctrls-core.c     |  8 +++
 10 files changed, 202 insertions(+), 8 deletions(-)

-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:39 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:39 +0800
Subject: [PATCH v1,
 3/8] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8195
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-4-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8195.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../bindings/media/mediatek,vcodec-subdev-decoder.yaml           | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index a3c892338ac0..a2f2db29daed 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -50,6 +50,7 @@ properties:
     enum:
       - mediatek,mt8192-vcodec-dec
       - mediatek,mt8186-vcodec-dec
+      - mediatek,mt8195-vcodec-dec
 
   reg:
     maxItems: 1
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:38 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:38 +0800
Subject: [PATCH v1, 2/8] media: mtk-vcodec: Add to support lat soc hardware
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-3-yunfei.dong@mediatek.com>

Add lat soc compatible and to support lat soc power/clk helper.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c      | 12 +++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h      |  2 ++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c      | 16 ++++++++++++++++
 .../media/platform/mtk-vcodec/mtk_vcodec_drv.h   |  1 +
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 7b5da3e4cac2..7374d5a5c156 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -28,6 +28,10 @@ static const struct of_device_id mtk_vdec_hw_match[] = {
 		.compatible = "mediatek,mtk-vcodec-core",
 		.data = (void *)MTK_VDEC_CORE,
 	},
+	{
+		.compatible = "mediatek,mtk-vcodec-lat-soc",
+		.data = (void *)MTK_VDEC_LAT_SOC,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match);
@@ -166,9 +170,11 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 	subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS];
 	set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
 
-	ret = mtk_vdec_hw_init_irq(subdev_dev);
-	if (ret)
-		goto err;
+	if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) {
+		ret = mtk_vdec_hw_init_irq(subdev_dev);
+		if (ret)
+			goto err;
+	}
 
 	subdev_dev->reg_base[VDEC_HW_MISC] =
 		devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index a63e4b1b81c3..b8938c6c3e72 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -17,6 +17,8 @@
 #define VDEC_IRQ_CLR 0x10
 #define VDEC_IRQ_CFG_REG 0xa4
 
+#define IS_SUPPORT_VDEC_HW_IRQ(hw_idx) (hw_idx != MTK_VDEC_LAT_SOC)
+
 /**
  * enum mtk_vdec_hw_reg_idx - subdev hardware register base index
  * @VDEC_HW_SYS : vdec soc register index
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 1581a1277473..76e1442fc6f9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -203,6 +203,14 @@ static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
 		mtk_vcodec_dec_pw_on(pm);
 		mtk_vcodec_dec_clock_on(pm);
 	}
+
+	if (hw_idx == MTK_VDEC_LAT0) {
+		pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC);
+		if (pm) {
+			mtk_vcodec_dec_pw_on(pm);
+			mtk_vcodec_dec_clock_on(pm);
+		}
+	}
 }
 
 static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
@@ -215,6 +223,14 @@ static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
 		mtk_vcodec_dec_clock_off(pm);
 		mtk_vcodec_dec_pw_off(pm);
 	}
+
+	if (hw_idx == MTK_VDEC_LAT0) {
+		pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC);
+		if (pm) {
+			mtk_vcodec_dec_clock_off(pm);
+			mtk_vcodec_dec_pw_off(pm);
+		}
+	}
 }
 
 void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cd2939b47790..363b999dd709 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,7 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_CORE,
 	MTK_VDEC_LAT0,
 	MTK_VDEC_LAT1,
+	MTK_VDEC_LAT_SOC,
 	MTK_VDEC_HW_MAX,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:40 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:40 +0800
Subject: [PATCH v1, 4/8] media: mtk-vcodec: Adds compatible for mt8195
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-5-yunfei.dong@mediatek.com>

Adds compatible for mt8195 platform.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 2d21d0010c9c..938bf14e4e8c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -468,6 +468,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
 		.compatible = "mediatek,mt8186-vcodec-dec",
 		.data = &mtk_vdec_single_core_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8195-vcodec-dec",
+		.data = &mtk_lat_sig_core_pdata,
+	},
 	{},
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:41 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:41 +0800
Subject: [PATCH v1,
 5/8] media: mtk-vcodec: Different codec using different capture format
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-6-yunfei.dong@mediatek.com>

Vp8 need to use MM21, but vp9 and h264 need to use HyFbc mode
for mt8195. Vp8/vp9/h264 use the same MM21 format for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 6ad17e69e32d..f2ced0147534 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -35,6 +35,44 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	return NULL;
 }
 
+static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
+{
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
+	const struct mtk_video_fmt *fmt;
+	struct mtk_q_data *q_data;
+	int num_frame_count = 0, i;
+	bool ret = true;
+
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
+		if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
+			continue;
+
+		num_frame_count++;
+	}
+
+	if (num_frame_count == 1)
+		return true;
+
+	fmt = &dec_pdata->vdec_formats[format_index];
+	q_data = &ctx->q_data[MTK_Q_DATA_SRC];
+	switch (q_data->fmt->fourcc) {
+	case V4L2_PIX_FMT_VP8_FRAME:
+		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+			ret = true;
+		break;
+	case V4L2_PIX_FMT_H264_SLICE:
+	case V4L2_PIX_FMT_VP9_FRAME:
+		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+			ret = false;
+		break;
+	default:
+		ret = true;
+		break;
+	};
+
+	return ret;
+}
+
 static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
 					      enum v4l2_buf_type type)
 {
@@ -578,6 +616,9 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
 			continue;
 
+		if (!output_queue && !mtk_vdec_get_cap_fmt(ctx, i))
+			continue;
+
 		if (j == f->index)
 			break;
 		++j;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:42 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:42 +0800
Subject: [PATCH v1,
 6/8] media: mtk-vcodec: prevent kernel crash when scp ipi timeout
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-7-yunfei.dong@mediatek.com>

From: Tinghan Shen <tinghan.shen at mediatek.com>

When SCP timeout during playing video, kernel crashes with following
message. It's caused by accessing NULL pointer in vpu_dec_ipi_handler.
This patch doesn't solve the root cause of NULL pointer, but merely
prevent kernel crashed when encounter the NULL pointer.

After applied this patch, kernel keeps alive, only the video player turns
to green screen.

[67242.065474] pc : vpu_dec_ipi_handler+0xa0/0xb20 [mtk_vcodec_dec]
[67242.065485] [MTK_V4L2] level=0 fops_vcodec_open(),334:
18000000.vcodec_dec decoder [135]
[67242.065523] lr : scp_ipi_handler+0x11c/0x244 [mtk_scp]
[67242.065540] sp : ffffffbb4207fb10
[67242.065557] x29: ffffffbb4207fb30 x28: ffffffd00a1d5000
[67242.065592] x27: 1ffffffa0143aa24 x26: 0000000000000000
[67242.065625] x25: dfffffd000000000 x24: ffffffd0168bfdb0
[67242.065659] x23: 1ffffff76840ff74 x22: ffffffbb41fa8a88
[67242.065692] x21: ffffffbb4207fb9c x20: ffffffbb4207fba0
[67242.065725] x19: ffffffbb4207fb98 x18: 0000000000000000
[67242.065758] x17: 0000000000000000 x16: ffffffd042022094
[67242.065791] x15: 1ffffff77ed4b71a x14: 1ffffff77ed4b719
[67242.065824] x13: 0000000000000000 x12: 0000000000000000
[67242.065857] x11: 0000000000000000 x10: dfffffd000000001
[67242.065890] x9 : 0000000000000000 x8 : 0000000000000002
[67242.065923] x7 : 0000000000000000 x6 : 000000000000003f
[67242.065956] x5 : 0000000000000040 x4 : ffffffffffffffe0
[67242.065989] x3 : ffffffd043b841b8 x2 : 0000000000000000
[67242.066021] x1 : 0000000000000010 x0 : 0000000000000010
[67242.066055] Call trace:
[67242.066092]  vpu_dec_ipi_handler+0xa0/0xb20 [mtk_vcodec_dec
12220d230d83a7426fc38c56b3e7bc6066955bae]
[67242.066119]  scp_ipi_handler+0x11c/0x244 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066145]  mt8192_scp_irq_handler+0x70/0x128 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066172]  scp_irq_handler+0xa0/0x114 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066200]  irq_thread_fn+0x84/0xf8
[67242.066220]  irq_thread+0x170/0x1ec
[67242.066242]  kthread+0x2f8/0x3b8
[67242.066264]  ret_from_fork+0x10/0x30
[67242.066292] Code: 38f96908 35003628 91004340 d343fc08 (38f96908)

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 35f4d5583084..1041dd663e76 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -91,6 +91,11 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
 					(unsigned long)msg->ap_inst_addr;
 
+	if (!vpu) {
+		mtk_v4l2_err("ap_inst_addr is NULL");
+		return;
+	}
+
 	mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id);
 
 	vpu->failure = msg->status;
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:44 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:44 +0800
Subject: [PATCH v1,
 8/8] media: mtk-vcodec: Add to support H264 inner racing mode
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-9-yunfei.dong@mediatek.com>

In order to reduce decoder latency, enable H264 inner racing mode.

Send lat trans buffer information to core when trigger lat to work,
need not to wait until lat decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  4 +++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 34 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 10 ++++++
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 23 ++++++++++---
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 938bf14e4e8c..099dc28b7445 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -390,6 +390,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	atomic_set(&dev->dec_active_cnt, 0);
+	memset(dev->vdec_racing_info, 0 , sizeof(dev->vdec_racing_info));
+	mutex_init(&dev->dec_racing_info_mutex);
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 76e1442fc6f9..065d14a3d11f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -173,6 +173,34 @@ static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_i
 	}
 }
 
+static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx)
+{
+	void __iomem *vdec_racing_addr;
+	int j;
+
+	mutex_lock(&ctx->dev->dec_racing_info_mutex);
+	if (atomic_inc_return(&ctx->dev->dec_active_cnt) == 1) {
+		vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100;
+		for (j = 0; j < 132; j++)
+			writel(ctx->dev->vdec_racing_info[j], vdec_racing_addr + j * 4);
+	}
+	mutex_unlock(&ctx->dev->dec_racing_info_mutex);
+}
+
+static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx)
+{
+	void __iomem *vdec_racing_addr;
+	int j;
+
+	mutex_lock(&ctx->dev->dec_racing_info_mutex);
+	if (atomic_dec_and_test(&ctx->dev->dec_active_cnt)) {
+		vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100;
+		for (j = 0; j < 132; j++)
+			ctx->dev->vdec_racing_info[j] = readl(vdec_racing_addr + j * 4);
+	}
+	mutex_unlock(&ctx->dev->dec_racing_info_mutex);
+}
+
 static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
 						   int hw_idx)
 {
@@ -243,11 +271,17 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
 	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
 
 	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+
+	if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
+		mtk_vcodec_load_racing_info(ctx);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
 
 void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
 {
+	if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
+		mtk_vcodec_record_racing_info(ctx);
+
 	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
 
 	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 363b999dd709..4d6ace869b5a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -28,6 +28,7 @@
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
 #define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
+#define IS_VDEC_INNER_RACING(capability) (capability & MTK_VCODEC_INNER_RACING)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -360,6 +361,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
 	MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
+	MTK_VCODEC_INNER_RACING = 0x20000,
 };
 
 /**
@@ -480,6 +482,10 @@ struct mtk_vcodec_enc_pdata {
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
+ *
+ * @dec_active_cnt: used to mark whether need to record register value
+ * @vdec_racing_info: record register value
+ * @dec_racing_info_mutex: mutex lock used for inner racing mode
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -525,6 +531,10 @@ struct mtk_vcodec_dev {
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
+
+	atomic_t dec_active_cnt;
+	u32 vdec_racing_info[132];
+	struct mutex dec_racing_info_mutex;
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
index 5541edbafed2..988d1d12d5c8 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -617,6 +617,17 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		goto err_free_fb_out;
 	}
 
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+
+	if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
+		memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		       sizeof(share_info->h264_slice_params));
+		vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	}
+
 	/* wait decoder done interrupt */
 	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
 					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
@@ -630,14 +641,16 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
 		inst->vsi->wdma_end_addr_offset;
-	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
-	share_info->nal_info = inst->vsi->dec.nal_info;
 	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
 				       share_info->trans_end);
 
-	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
-	       sizeof(share_info->h264_slice_params));
-	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
+		memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		       sizeof(share_info->h264_slice_params));
+		vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	}
+	mtk_vcodec_debug(inst, "lat crc: 0x%x 0x%x 0x%x", inst->vsi->dec.crc[0],
+			 inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]);
 	inst->slice_dec_num++;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Wed Jan 26 18:55:37 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:37 +0800
Subject: [PATCH v1,
 1/8] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for lat
 soc
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-2-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for compatible "mediatek,mtk-vcodec-lat-soc".

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/mediatek,vcodec-subdev-decoder.yaml | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index 6415c9f29130..a3c892338ac0 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -189,6 +189,55 @@ patternProperties:
 
     additionalProperties: false
 
+  '^vcodec-lat-soc@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-lat-soc
+
+      reg:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
 required:
   - compatible
   - reg
-- 
2.25.1



From yangyicong at huawei.com  Wed Jan 26 19:05:52 2022
From: yangyicong at huawei.com (Yicong Yang)
Date: Thu, 27 Jan 2022 11:05:52 +0800
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <62bbdd77f70f7b46a044685668e33fb031812c38.camel@linux.intel.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <f2617aa806df6d64718a7cb5b41bafe593bccda3.camel@linux.intel.com>
 <b793e565-670d-cc66-6947-7d927ebcb8b3@huawei.com>
 <95f82bf3524289bfbcaeee6e83b6dac48ed07f25.camel@linux.intel.com>
 <62bbdd77f70f7b46a044685668e33fb031812c38.camel@linux.intel.com>
Message-ID: <4d4099d8-e890-9e56-c395-5f521d98081a@huawei.com>

On 2022/1/27 10:36, Tim Chen wrote:
> On Wed, 2022-01-26 at 18:30 -0800, Tim Chen wrote:
>> On Thu, 2022-01-27 at 10:02 +0800, Yicong Yang wrote:
>>> On 2022/1/27 9:14, Tim Chen wrote:
>>>> On Wed, 2022-01-26 at 16:09 +0800, Yicong Yang wrote:
>>>>> From: Barry Song <song.bao.hua at hisilicon.com>
>>>>>
>>>>> For platforms having clusters like Kunpeng920, CPUs within the
>>>>> same
>>>>> cluster have lower latency when synchronizing and accessing
>>>>> shared
>>>>> resources like cache. Thus, this patch tries to find an idle
>>>>> cpu
>>>>> within the cluster of the target CPU before scanning the whole
>>>>> LLC
>>>>> to gain lower latency.
>>>>>
>>>>> Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so
>>>>> this
>>>>> patch doesn't consider SMT for this moment.
>>>>>
>>>>> Testing has been done on Kunpeng920 by pinning tasks to one
>>>>> numa
>>>>> and two numa. On Kunpeng920, Each numa has 8 clusters and each
>>>>> cluster has 4 CPUs.
>>>>>
>>>>> With this patch, We noticed enhancement on tbench within one
>>>>> numa or cross two numa.
>>>>>
>>>>> On numa 0:
>>>>>                             5.17-rc1                patched
>>>>> Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
>>>>> Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
>>>>> Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
>>>>> Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
>>>>> Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
>>>>> Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
>>>>> Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
>>>>> Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
>>>>>
>>>>> On numa 0-1:
>>>>>                             5.17-rc1                patched
>>>>> Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
>>>>> Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
>>>>> Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
>>>>> Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
>>>>> Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
>>>>> Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
>>>>> Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
>>>>> Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
>>>>> Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
>>>>> Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
>>>>>
>>>>> This will also help to improve the MySQL. With MySQL server
>>>>> running on numa 0 and client running on numa 1, both QPS and
>>>>> latency is imporved on read-write case:
>>>>>                         5.17-rc1        patched
>>>>> QPS-16threads        143333.2633    145077.4033(+1.22%)
>>>>> QPS-24threads        195085.9367    202719.6133(+3.91%)
>>>>> QPS-32threads        241165.6867      249020.74(+3.26%)
>>>>> QPS-64threads        244586.8433    253387.7567(+3.60%)
>>>>> avg-lat-16threads           2.23           2.19(+1.19%)
>>>>> avg-lat-24threads           2.46           2.36(+3.79%)
>>>>> avg-lat-36threads           2.66           2.57(+3.26%)
>>>>> avg-lat-64threads           5.23           5.05(+3.44%)
>>>>>
>>>>> Tested-by: Yicong Yang <yangyicong at hisilicon.com>
>>>>> Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
>>>>> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
>>>>> ---
>>>>>  kernel/sched/fair.c | 46
>>>>> +++++++++++++++++++++++++++++++++++++++++
>>>>> ----
>>>>>  1 file changed, 42 insertions(+), 4 deletions(-)
>>>>>
>>>>> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
>>>>> index 5146163bfabb..2f84a933aedd 100644
>>>>> --- a/kernel/sched/fair.c
>>>>> +++ b/kernel/sched/fair.c
>>>>> @@ -6262,12 +6262,46 @@ static inline int
>>>>> select_idle_smt(struct
>>>>> task_struct *p, struct sched_domain *sd
>>>>>  
>>>>>  #endif /* CONFIG_SCHED_SMT */
>>>>>  
>>>>> +#ifdef CONFIG_SCHED_CLUSTER
>>>>> +/*
>>>>> + * Scan the cluster domain for idle CPUs and clear cluster
>>>>> cpumask
>>>>> after scanning
>>>>> + */
>>>>> +static inline int scan_cluster(struct task_struct *p, int
>>>>> prev_cpu,
>>>>> int target)
>>>>> +{
>>>>> +	struct cpumask *cpus =
>>>>> this_cpu_cpumask_var_ptr(select_idle_mask);
>>>>> +	struct sched_domain *sd =
>>>>> rcu_dereference(per_cpu(sd_cluster,
>>>>> target));
>>>>> +	int cpu, idle_cpu;
>>>>> +
>>>>> +	/* TODO: Support SMT case while a machine with both
>>>>> cluster and
>>>>> SMT born */
>>>>
>>>> This is probably a clearer comment
>>>>
>>>> 	/* TODO: Support SMT system with cluster topology */
>>>>
>>>>> +	if (!sched_smt_active() && sd) {
>>>>> +		for_each_cpu_and(cpu, cpus,
>>>>> sched_domain_span(sd)) {
>>>>> +			idle_cpu = __select_idle_cpu(cpu, p);
>>>>>   */
>>>>> -static int select_idle_cpu(struct task_struct *p, struct
>>>>> sched_domain *sd, bool has_idle_core, int target)
>>>>> +static int select_idle_cpu(struct task_struct *p, struct
>>>>> sched_domain *sd, bool has_idle_core, int prev_cpu, int target)
>>>>>  {
>>>>>  	struct cpumask *cpus =
>>>>> this_cpu_cpumask_var_ptr(select_idle_mask);
>>>>>  	int i, cpu, idle_cpu = -1, nr = INT_MAX;
>>>>> @@ -6282,6 +6316,10 @@ static int select_idle_cpu(struct
>>>>> task_struct
>>>>> *p, struct sched_domain *sd, bool
>>>>>  
>>>>>  	cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
>>>>>  
>>>>> +	idle_cpu = scan_cluster(p, prev_cpu, target);
>>>>
>>>> Shouldn't "cpus" from 
>>>>
>>>> cpumask_and(cpus, sched_domain_span(sd), p->cpus_ptr);
>>>>
>>>> be passed to scan_cluster, to make sure that the cpu returned is 
>>>> in the affinity mask of the task? I don't see p->cpus_ptr
>>>> being checked in scan_cluster to make sure the cpu found is in
>>>> the
>>>> affinity mask.
>>>>
>>>
>>> The cpus scanned in scan_cluster() is the intersection of
>>> select_idle_mask and sched_domain_span(cluster_sd), and
>>> we limited the select_idle_mask in the tasks' affinity mask
>>> before we enter scan_cluster() here.
>>
>> Ah, I missed the fact that cpus point to the select_idle_mask.
>>
> 
> I think it will be easier to read the code if you pass "cpus" directly
> to scan cluster, rather than making this implicit, and having this
> assignment 
> 
> *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
> 
> again in scan_cluster.

sure. It does look more readable and I think we can change to that. :)

Thanks.


From yunfei.dong at mediatek.com  Wed Jan 26 18:55:43 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Thu, 27 Jan 2022 10:55:43 +0800
Subject: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
In-Reply-To: <20220127025544.10854-1-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
Message-ID: <20220127025544.10854-8-yunfei.dong@mediatek.com>

Init some of VP9 frame decode params to default value.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 54abe5245dcc..b25c77b8a445 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -112,6 +112,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
 	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
+	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	void *p = ptr.p + idx * ctrl->elem_size;
 
@@ -152,6 +153,13 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		p_vp8_frame = p;
 		p_vp8_frame->num_dct_parts = 1;
 		break;
+	case V4L2_CTRL_TYPE_VP9_FRAME:
+		p_vp9_frame = p;
+		p_vp9_frame->profile = 0;
+		p_vp9_frame->bit_depth = 8;
+		p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
+			V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
+		break;
 	case V4L2_CTRL_TYPE_FWHT_PARAMS:
 		p_fwht_params = p;
 		p_fwht_params->version = V4L2_FWHT_VERSION;
-- 
2.25.1



From chaotian.jing at mediatek.com  Wed Jan 26 19:31:12 2022
From: chaotian.jing at mediatek.com (Chaotian Jing)
Date: Thu, 27 Jan 2022 11:31:12 +0800
Subject: [PATCH v5 3/3] mmc: mediatek: add support for SDIO eint IRQ
In-Reply-To: <20220121071942.11601-4-axe.yang@mediatek.com>
References: <20220121071942.11601-1-axe.yang@mediatek.com>
 <20220121071942.11601-4-axe.yang@mediatek.com>
Message-ID: <c03acbc0a259d7b7f4a313b764e4dc9a69e898fe.camel@mediatek.com>

On Fri, 2022-01-21 at 15:19 +0800, Axe Yang wrote:
> Add support for eint IRQ when MSDC is used as an SDIO host. This
> feature requires SDIO device support async IRQ function. With this
> feature, SDIO host can be awakened by SDIO card in suspend state,
> without additional pin.
> 
> MSDC driver will time-share the SDIO DAT1 pin. During suspend, MSDC
> turn off clock and switch SDIO DAT1 pin to GPIO mode. And during
> resume, switch GPIO function back to DAT1 mode then turn on clock.
> 
> Some device tree property should be added or modified in MSDC node
> to support SDIO eint IRQ. Pinctrls named state_dat1 and state_eint
> are mandatory. And cap-sdio-async-irq flag is necessary since this
> feature depends on asynchronous interrupt:
>         &mmcX {
>                 ...
>                 pinctrl-names = "default", "state_uhs", "state_eint",
>                                 "state_dat1";
>                 ...
>                 pinctrl-2 = <&mmc2_pins_eint>;
>                 pinctrl-3 = <&mmc2_pins_dat1>;
>                 ...
>                 cap-sdio-async-irq;
>                 ...
>         };
> 
> Co-developed-by: Yong Mao <yong.mao at mediatek.com>
> Signed-off-by: Yong Mao <yong.mao at mediatek.com>
> Signed-off-by: Axe Yang <axe.yang at mediatek.com>
Acked-by: Chaotian Jing <chaotian.jing at mediatek.com>
> ---
>  drivers/mmc/host/mtk-sd.c | 123 +++++++++++++++++++++++++++++++++++-
> --
>  1 file changed, 115 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
> index 65037e1d7723..f8e38228d810 100644
> --- a/drivers/mmc/host/mtk-sd.c
> +++ b/drivers/mmc/host/mtk-sd.c
> @@ -1,6 +1,6 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /*
> - * Copyright (c) 2014-2015 MediaTek Inc.
> + * Copyright (c) 2014-2015, 2022 MediaTek Inc.
>   * Author: Chaotian.Jing <chaotian.jing at mediatek.com>
>   */
>  
> @@ -9,6 +9,7 @@
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/gpio/consumer.h>
>  #include <linux/iopoll.h>
>  #include <linux/ioport.h>
>  #include <linux/irq.h>
> @@ -440,8 +441,12 @@ struct msdc_host {
>  	struct pinctrl *pinctrl;
>  	struct pinctrl_state *pins_default;
>  	struct pinctrl_state *pins_uhs;
> +	struct pinctrl_state *pins_eint;
> +	struct pinctrl_state *pins_dat1;
>  	struct delayed_work req_timeout;
>  	int irq;		/* host interrupt */
> +	int eint_irq;		/* device interrupt */
> +	int sdio_irq_cnt;	/* irq enable cnt */
>  	struct reset_control *reset;
>  
>  	struct clk *src_clk;	/* msdc source clock */
> @@ -465,6 +470,7 @@ struct msdc_host {
>  	bool hs400_tuning;	/* hs400 mode online tuning */
>  	bool internal_cd;	/* Use internal card-detect logic */
>  	bool cqhci;		/* support eMMC hw cmdq */
> +	bool sdio_eint_ready;	/* Ready to support SDIO eint
> interrupt */
>  	struct msdc_save_para save_para; /* used when gate HCLK */
>  	struct msdc_tune_para def_tune_para; /* default tune setting */
>  	struct msdc_tune_para saved_tune_para; /* tune result of
> CMD21/CMD19 */
> @@ -1527,10 +1533,12 @@ static void msdc_enable_sdio_irq(struct
> mmc_host *mmc, int enb)
>  	__msdc_enable_sdio_irq(host, enb);
>  	spin_unlock_irqrestore(&host->lock, flags);
>  
> -	if (enb)
> -		pm_runtime_get_noresume(host->dev);
> -	else
> -		pm_runtime_put_noidle(host->dev);
> +	if (mmc->card && !mmc->card->cccr.enable_async_irq) {
> +		if (enb)
> +			pm_runtime_get_noresume(host->dev);
> +		else
> +			pm_runtime_put_noidle(host->dev);
> +	}
>  }
>  
>  static irqreturn_t msdc_cmdq_irq(struct msdc_host *host, u32 intsts)
> @@ -2461,6 +2469,48 @@ static const struct mmc_host_ops mt_msdc_ops =
> {
>  	.hw_reset = msdc_hw_reset,
>  };
>  
> +static irqreturn_t msdc_sdio_eint_irq(int irq, void *dev_id)
> +{
> +	struct msdc_host *host = dev_id;
> +	struct mmc_host *mmc = mmc_from_priv(host);
> +
> +	spin_lock(&host->lock);
> +	if (likely(host->sdio_irq_cnt > 0)) {
> +		disable_irq_nosync(host->eint_irq);
> +		disable_irq_wake(host->eint_irq);
> +		host->sdio_irq_cnt--;
> +	}
> +	spin_unlock(&host->lock);
> +
> +	sdio_signal_irq(mmc);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int msdc_request_dat1_eint_irq(struct msdc_host *host)
> +{
> +	struct gpio_desc *desc;
> +	int irq, ret;
> +
> +	desc = devm_gpiod_get(host->dev, "eint", GPIOD_IN);
> +	if (IS_ERR(desc))
> +		return PTR_ERR(desc);
> +
> +	irq = gpiod_to_irq(desc);
> +	if (irq < 0)
> +		return irq;
> +
> +	ret = devm_request_threaded_irq(host->dev, irq, NULL,
> msdc_sdio_eint_irq,
> +					IRQF_TRIGGER_LOW | IRQF_ONESHOT
> | IRQF_NO_AUTOEN,
> +					"sdio-eint", host);
> +	if (ret)
> +		return ret;
> +
> +	host->eint_irq = irq;
> +
> +	return 0;
> +}
> +
>  static const struct cqhci_host_ops msdc_cmdq_ops = {
>  	.enable         = msdc_cqe_enable,
>  	.disable        = msdc_cqe_disable,
> @@ -2631,6 +2681,23 @@ static int msdc_drv_probe(struct
> platform_device *pdev)
>  		goto host_free;
>  	}
>  
> +	if (!(mmc->caps2 & MMC_CAP2_NO_SDIO) && (mmc->caps2 &
> MMC_CAP2_SDIO_ASYNC_IRQ)) {
> +		/* Support for SDIO eint irq */
> +		host->pins_eint = pinctrl_lookup_state(host->pinctrl,
> "state_eint");
> +		if (IS_ERR(host->pins_eint)) {
> +			dev_dbg(&pdev->dev, "Cannot find pinctrl
> eint!\n");
> +		} else {
> +			host->pins_dat1 = pinctrl_lookup_state(host-
> >pinctrl, "state_dat1");
> +			if (IS_ERR(host->pins_dat1)) {
> +				ret = dev_err_probe(&pdev->dev,
> PTR_ERR(host->pins_dat1),
> +						    "Cannot find
> pinctrl dat1!\n");
> +				goto host_free;
> +			}
> +
> +			host->sdio_eint_ready = true;
> +		}
> +	}
> +
>  	msdc_of_property_parse(pdev, host);
>  
>  	host->dev = &pdev->dev;
> @@ -2722,6 +2789,16 @@ static int msdc_drv_probe(struct
> platform_device *pdev)
>  	if (ret)
>  		goto release;
>  
> +	if (host->sdio_eint_ready) {
> +		ret = msdc_request_dat1_eint_irq(host);
> +		if (ret) {
> +			dev_err(host->dev, "Failed to register data1
> eint irq!\n");
> +			goto release;
> +		}
> +
> +		pinctrl_select_state(host->pinctrl, host->pins_dat1);
> +	}
> +
>  	pm_runtime_set_active(host->dev);
>  	pm_runtime_set_autosuspend_delay(host->dev,
> MTK_MMC_AUTOSUSPEND_DELAY);
>  	pm_runtime_use_autosuspend(host->dev);
> @@ -2843,8 +2920,22 @@ static int __maybe_unused
> msdc_runtime_suspend(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);
> +	unsigned long flags;
>  
>  	msdc_save_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		disable_irq(host->irq);
> +		pinctrl_select_state(host->pinctrl, host->pins_eint);
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt == 0) {
> +			enable_irq(host->eint_irq);
> +			enable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt++;
> +		}
> +		sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
> +		spin_unlock_irqrestore(&host->lock, flags);
> +	}
>  	msdc_gate_clock(host);
>  	return 0;
>  }
> @@ -2853,6 +2944,7 @@ static int __maybe_unused
> msdc_runtime_resume(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	struct msdc_host *host = mmc_priv(mmc);
> +	unsigned long flags;
>  	int ret;
>  
>  	ret = msdc_ungate_clock(host);
> @@ -2860,10 +2952,25 @@ static int __maybe_unused
> msdc_runtime_resume(struct device *dev)
>  		return ret;
>  
>  	msdc_restore_reg(host);
> +
> +	if (host->sdio_eint_ready) {
> +		spin_lock_irqsave(&host->lock, flags);
> +		if (host->sdio_irq_cnt > 0) {
> +			disable_irq_nosync(host->eint_irq);
> +			disable_irq_wake(host->eint_irq);
> +			host->sdio_irq_cnt--;
> +			sdr_set_bits(host->base + SDC_CFG,
> SDC_CFG_SDIOIDE);
> +		} else {
> +			sdr_clr_bits(host->base + MSDC_INTEN,
> MSDC_INTEN_SDIOIRQ);
> +		}
> +		spin_unlock_irqrestore(&host->lock, flags);
> +		pinctrl_select_state(host->pinctrl, host->pins_uhs);
> +		enable_irq(host->irq);
> +	}
>  	return 0;
>  }
>  
> -static int __maybe_unused msdc_suspend(struct device *dev)
> +static int __maybe_unused msdc_suspend_noirq(struct device *dev)
>  {
>  	struct mmc_host *mmc = dev_get_drvdata(dev);
>  	int ret;
> @@ -2877,13 +2984,13 @@ static int __maybe_unused msdc_suspend(struct
> device *dev)
>  	return pm_runtime_force_suspend(dev);
>  }
>  
> -static int __maybe_unused msdc_resume(struct device *dev)
> +static int __maybe_unused msdc_resume_noirq(struct device *dev)
>  {
>  	return pm_runtime_force_resume(dev);
>  }
>  
>  static const struct dev_pm_ops msdc_dev_pm_ops = {
> -	SET_SYSTEM_SLEEP_PM_OPS(msdc_suspend, msdc_resume)
> +	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(msdc_suspend_noirq,
> msdc_resume_noirq)
>  	SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume,
> NULL)
>  };
>  

From roger.lu at mediatek.com  Wed Jan 26 19:39:52 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:52 +0800
Subject: [PATCH v22 3/7] soc: mediatek: SVS: introduce MTK SVS engine
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-4-roger.lu@mediatek.com>

The Smart Voltage Scaling(SVS) engine is a piece of hardware
which calculates suitable SVS bank voltages to OPP voltage table.
Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
when receiving OPP_EVENT_ADJUST_VOLTAGE.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/Kconfig   |   10 +
 drivers/soc/mediatek/Makefile  |    1 +
 drivers/soc/mediatek/mtk-svs.c | 1422 ++++++++++++++++++++++++++++++++
 3 files changed, 1433 insertions(+)
 create mode 100644 drivers/soc/mediatek/mtk-svs.c

diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index fdd8bc08569e..3c3eedea35f7 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -73,4 +73,14 @@ config MTK_MMSYS
 	  Say yes here to add support for the MediaTek Multimedia
 	  Subsystem (MMSYS).
 
+config MTK_SVS
+	tristate "MediaTek Smart Voltage Scaling(SVS)"
+	depends on MTK_EFUSE && NVMEM
+	help
+	  The Smart Voltage Scaling(SVS) engine is a piece of hardware
+	  which has several controllers(banks) for calculating suitable
+	  voltage to different power domains(CPU/GPU/CCI) according to
+	  chip process corner, temperatures and other factors. Then DVFS
+	  driver could apply SVS bank voltage to PMIC/Buck.
+
 endmenu
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index 90270f8114ed..0e9e703c931a 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
 obj-$(CONFIG_MTK_SCPSYS_PM_DOMAINS) += mtk-pm-domains.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mmsys.o
 obj-$(CONFIG_MTK_MMSYS) += mtk-mutex.o
+obj-$(CONFIG_MTK_SVS) += mtk-svs.o
diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
new file mode 100644
index 000000000000..2d7ea3d607c4
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -0,0 +1,1422 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_qos.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* svs bank 1-line software id */
+#define SVSB_CPU_LITTLE			BIT(0)
+#define SVSB_CPU_BIG			BIT(1)
+#define SVSB_CCI			BIT(2)
+#define SVSB_GPU			BIT(3)
+
+/* svs bank mode support */
+#define SVSB_MODE_ALL_DISABLE		0
+#define SVSB_MODE_INIT01		BIT(1)
+#define SVSB_MODE_INIT02		BIT(2)
+
+/* svs bank volt flags */
+#define SVSB_INIT01_PD_REQ		BIT(0)
+#define SVSB_INIT01_VOLT_IGNORE		BIT(1)
+#define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
+
+/* svs bank register common configuration */
+#define SVSB_DET_MAX			0xffff
+#define SVSB_DET_WINDOW			0xa28
+#define SVSB_DTHI			0x1
+#define SVSB_DTLO			0xfe
+#define SVSB_EN_INIT01			0x1
+#define SVSB_EN_INIT02			0x5
+#define SVSB_EN_OFF			0x0
+#define SVSB_INTEN_INIT0x		0x00005f01
+#define SVSB_INTSTS_CLEAN		0x00ffffff
+#define SVSB_INTSTS_COMPLETE		0x1
+#define SVSB_RUNCONFIG_DEFAULT		0x80000000
+
+/* svs bank related setting */
+#define MAX_OPP_ENTRIES			16
+#define SVSB_DC_SIGNED_BIT		BIT(15)
+#define SVSB_DET_CLK_EN			BIT(31)
+
+static DEFINE_SPINLOCK(svs_lock);
+
+/**
+ * enum svsb_phase - svs bank phase enumeration
+ * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
+ * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
+ * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
+ * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
+ *
+ * Each svs bank has its own independent phase and we enable each svs bank by
+ * running their phase orderly. However, when svs bank encounters unexpected
+ * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
+ *
+ * svs bank general phase-enabled order:
+ * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02
+ */
+enum svsb_phase {
+	SVSB_PHASE_ERROR = 0,
+	SVSB_PHASE_INIT01,
+	SVSB_PHASE_INIT02,
+	SVSB_PHASE_MAX,
+};
+
+enum svs_reg_index {
+	DESCHAR = 0,
+	TEMPCHAR,
+	DETCHAR,
+	AGECHAR,
+	DCCONFIG,
+	AGECONFIG,
+	FREQPCT30,
+	FREQPCT74,
+	LIMITVALS,
+	VBOOT,
+	DETWINDOW,
+	CONFIG,
+	TSCALCS,
+	RUNCONFIG,
+	SVSEN,
+	INIT2VALS,
+	DCVALUES,
+	AGEVALUES,
+	VOP30,
+	VOP74,
+	TEMP,
+	INTSTS,
+	INTSTSRAW,
+	INTEN,
+	CHKINT,
+	CHKSHIFT,
+	STATUS,
+	VDESIGN30,
+	VDESIGN74,
+	DVT30,
+	DVT74,
+	AGECOUNT,
+	SMSTATE0,
+	SMSTATE1,
+	CTL0,
+	DESDETSEC,
+	TEMPAGESEC,
+	CTRLSPARE0,
+	CTRLSPARE1,
+	CTRLSPARE2,
+	CTRLSPARE3,
+	CORESEL,
+	THERMINTST,
+	INTST,
+	THSTAGE0ST,
+	THSTAGE1ST,
+	THSTAGE2ST,
+	THAHBST0,
+	THAHBST1,
+	SPARE0,
+	SPARE1,
+	SPARE2,
+	SPARE3,
+	THSLPEVEB,
+	SVS_REG_MAX,
+};
+
+static const u32 svs_regs_v2[] = {
+	[DESCHAR]		= 0xc00,
+	[TEMPCHAR]		= 0xc04,
+	[DETCHAR]		= 0xc08,
+	[AGECHAR]		= 0xc0c,
+	[DCCONFIG]		= 0xc10,
+	[AGECONFIG]		= 0xc14,
+	[FREQPCT30]		= 0xc18,
+	[FREQPCT74]		= 0xc1c,
+	[LIMITVALS]		= 0xc20,
+	[VBOOT]			= 0xc24,
+	[DETWINDOW]		= 0xc28,
+	[CONFIG]		= 0xc2c,
+	[TSCALCS]		= 0xc30,
+	[RUNCONFIG]		= 0xc34,
+	[SVSEN]			= 0xc38,
+	[INIT2VALS]		= 0xc3c,
+	[DCVALUES]		= 0xc40,
+	[AGEVALUES]		= 0xc44,
+	[VOP30]			= 0xc48,
+	[VOP74]			= 0xc4c,
+	[TEMP]			= 0xc50,
+	[INTSTS]		= 0xc54,
+	[INTSTSRAW]		= 0xc58,
+	[INTEN]			= 0xc5c,
+	[CHKINT]		= 0xc60,
+	[CHKSHIFT]		= 0xc64,
+	[STATUS]		= 0xc68,
+	[VDESIGN30]		= 0xc6c,
+	[VDESIGN74]		= 0xc70,
+	[DVT30]			= 0xc74,
+	[DVT74]			= 0xc78,
+	[AGECOUNT]		= 0xc7c,
+	[SMSTATE0]		= 0xc80,
+	[SMSTATE1]		= 0xc84,
+	[CTL0]			= 0xc88,
+	[DESDETSEC]		= 0xce0,
+	[TEMPAGESEC]		= 0xce4,
+	[CTRLSPARE0]		= 0xcf0,
+	[CTRLSPARE1]		= 0xcf4,
+	[CTRLSPARE2]		= 0xcf8,
+	[CTRLSPARE3]		= 0xcfc,
+	[CORESEL]		= 0xf00,
+	[THERMINTST]		= 0xf04,
+	[INTST]			= 0xf08,
+	[THSTAGE0ST]		= 0xf0c,
+	[THSTAGE1ST]		= 0xf10,
+	[THSTAGE2ST]		= 0xf14,
+	[THAHBST0]		= 0xf18,
+	[THAHBST1]		= 0xf1c,
+	[SPARE0]		= 0xf20,
+	[SPARE1]		= 0xf24,
+	[SPARE2]		= 0xf28,
+	[SPARE3]		= 0xf2c,
+	[THSLPEVEB]		= 0xf30,
+};
+
+/**
+ * struct svs_platform - svs platform control
+ * @name: svs platform name
+ * @base: svs platform register base
+ * @dev: svs platform device
+ * @main_clk: main clock for svs bank
+ * @pbank: svs bank pointer needing to be protected by spin_lock section
+ * @banks: svs banks that svs platform supports
+ * @efuse_parsing: svs platform efuse parsing function pointer
+ * @probe: svs platform probe function pointer
+ * @irqflags: svs platform irq settings flags
+ * @efuse_max: total number of svs efuse
+ * @regs: svs platform registers map
+ * @bank_max: total number of svs banks
+ * @efuse: svs efuse data received from NVMEM framework
+ */
+struct svs_platform {
+	char *name;
+	void __iomem *base;
+	struct device *dev;
+	struct clk *main_clk;
+	struct svs_bank *pbank;
+	struct svs_bank *banks;
+	bool (*efuse_parsing)(struct svs_platform *svsp);
+	int (*probe)(struct svs_platform *svsp);
+	unsigned long irqflags;
+	size_t efuse_max;
+	const u32 *regs;
+	u32 bank_max;
+	u32 *efuse;
+};
+
+struct svs_platform_data {
+	char *name;
+	struct svs_bank *banks;
+	bool (*efuse_parsing)(struct svs_platform *svsp);
+	int (*probe)(struct svs_platform *svsp);
+	unsigned long irqflags;
+	const u32 *regs;
+	u32 bank_max;
+};
+
+/**
+ * struct svs_bank - svs bank representation
+ * @dev: bank device
+ * @opp_dev: device for opp table/buck control
+ * @pd_dev: power domain device for SoC mtcmos control
+ * @init_completion: the timeout completion for bank init
+ * @buck: regulator used by opp_dev
+ * @lock: mutex lock to protect voltage update process
+ * @set_freq_pct: function pointer to set bank frequency percent table
+ * @get_volts: function pointer to get bank voltages
+ * @name: bank name
+ * @buck_name: regulator name
+ * @phase: bank current phase
+ * @volt_od: bank voltage overdrive
+ * @pm_runtime_enabled_count: bank pm runtime enabled count
+ * @mode_support: bank mode support.
+ * @freq_base: reference frequency for bank init
+ * @vboot: voltage request for bank init01 only
+ * @opp_dfreq: default opp frequency table
+ * @opp_dvolt: default opp voltage table
+ * @freq_pct: frequency percent table for bank init
+ * @volt: bank voltage table
+ * @volt_step: bank voltage step
+ * @volt_base: bank voltage base
+ * @volt_flags: bank voltage flags
+ * @vmax: bank voltage maximum
+ * @vmin: bank voltage minimum
+ * @age_config: bank age configuration
+ * @age_voffset_in: bank age voltage offset
+ * @dc_config: bank dc configuration
+ * @dc_voffset_in: bank dc voltage offset
+ * @dvt_fixed: bank dvt fixed value
+ * @vco: bank VCO value
+ * @chk_shift: bank chicken shift
+ * @core_sel: bank selection
+ * @opp_count: bank opp count
+ * @int_st: bank interrupt identification
+ * @sw_id: bank software identification
+ * @cpu_id: cpu core id for SVS CPU bank use only
+ * @ctl0: TS-x selection
+ * @bdes: svs efuse data
+ * @mdes: svs efuse data
+ * @mtdes: svs efuse data
+ * @dcbdet: svs efuse data
+ * @dcmdet: svs efuse data
+ *
+ * Svs bank will generate suitalbe voltages by below general math equation
+ * and provide these voltages to opp voltage table.
+ *
+ * opp_volt[i] = (volt[i] * volt_step) + volt_base;
+ */
+struct svs_bank {
+	struct device *dev;
+	struct device *opp_dev;
+	struct device *pd_dev;
+	struct completion init_completion;
+	struct regulator *buck;
+	struct mutex lock;	/* lock to protect voltage update process */
+	void (*set_freq_pct)(struct svs_platform *svsp);
+	void (*get_volts)(struct svs_platform *svsp);
+	char *name;
+	char *buck_name;
+	enum svsb_phase phase;
+	s32 volt_od;
+	u32 pm_runtime_enabled_count;
+	u32 mode_support;
+	u32 freq_base;
+	u32 vboot;
+	u32 opp_dfreq[MAX_OPP_ENTRIES];
+	u32 opp_dvolt[MAX_OPP_ENTRIES];
+	u32 freq_pct[MAX_OPP_ENTRIES];
+	u32 volt[MAX_OPP_ENTRIES];
+	u32 volt_step;
+	u32 volt_base;
+	u32 volt_flags;
+	u32 vmax;
+	u32 vmin;
+	u32 age_config;
+	u32 age_voffset_in;
+	u32 dc_config;
+	u32 dc_voffset_in;
+	u32 dvt_fixed;
+	u32 vco;
+	u32 chk_shift;
+	u32 core_sel;
+	u32 opp_count;
+	u32 int_st;
+	u32 sw_id;
+	u32 cpu_id;
+	u32 ctl0;
+	u32 bdes;
+	u32 mdes;
+	u32 mtdes;
+	u32 dcbdet;
+	u32 dcmdet;
+};
+
+static u32 percent(u32 numerator, u32 denominator)
+{
+	/* If not divide 1000, "numerator * 100" will have data overflow. */
+	numerator /= 1000;
+	denominator /= 1000;
+
+	return DIV_ROUND_UP(numerator * 100, denominator);
+}
+
+static u32 svs_readl_relaxed(struct svs_platform *svsp, enum svs_reg_index rg_i)
+{
+	return readl_relaxed(svsp->base + svsp->regs[rg_i]);
+}
+
+static void svs_writel_relaxed(struct svs_platform *svsp, u32 val,
+			       enum svs_reg_index rg_i)
+{
+	writel_relaxed(val, svsp->base + svsp->regs[rg_i]);
+}
+
+static void svs_switch_bank(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svs_writel_relaxed(svsp, svsb->core_sel, CORESEL);
+}
+
+static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
+				     u32 svsb_volt_base)
+{
+	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
+}
+
+static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
+{
+	int ret = -EPERM;
+	u32 i, svsb_volt, opp_volt;
+
+	mutex_lock(&svsb->lock);
+
+	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
+	for (i = 0; i < svsb->opp_count; i++) {
+		switch (svsb->phase) {
+		case SVSB_PHASE_ERROR:
+			opp_volt = svsb->opp_dvolt[i];
+			break;
+		case SVSB_PHASE_INIT01:
+			/* do nothing */
+			goto unlock_mutex;
+		case SVSB_PHASE_INIT02:
+			svsb_volt = max(svsb->volt[i], svsb->vmin);
+			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
+							     svsb->volt_step,
+							     svsb->volt_base);
+			break;
+		default:
+			dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase);
+			ret = -EINVAL;
+			goto unlock_mutex;
+		}
+
+		opp_volt = min(opp_volt, svsb->opp_dvolt[i]);
+		ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
+						svsb->opp_dfreq[i],
+						opp_volt, opp_volt,
+						svsb->opp_dvolt[i]);
+		if (ret) {
+			dev_err(svsb->dev, "set %uuV fail: %d\n",
+				opp_volt, ret);
+			goto unlock_mutex;
+		}
+	}
+
+unlock_mutex:
+	mutex_unlock(&svsb->lock);
+
+	return ret;
+}
+
+static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
+{
+	u32 vx;
+
+	if (v0 == v1 || f0 == f1)
+		return v0;
+
+	/* *100 to have decimal fraction factor */
+	vx = (v0 * 100) - ((((v0 - v1) * 100) / (f0 - f1)) * (f0 - fx));
+
+	return DIV_ROUND_UP(vx, 100);
+}
+
+static void svs_get_bank_volts_v2(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 temp, i;
+
+	temp = svs_readl_relaxed(svsp, VOP74);
+	svsb->volt[14] = (temp >> 24) & GENMASK(7, 0);
+	svsb->volt[12] = (temp >> 16) & GENMASK(7, 0);
+	svsb->volt[10] = (temp >> 8)  & GENMASK(7, 0);
+	svsb->volt[8] = (temp & GENMASK(7, 0));
+
+	temp = svs_readl_relaxed(svsp, VOP30);
+	svsb->volt[6] = (temp >> 24) & GENMASK(7, 0);
+	svsb->volt[4] = (temp >> 16) & GENMASK(7, 0);
+	svsb->volt[2] = (temp >> 8)  & GENMASK(7, 0);
+	svsb->volt[0] = (temp & GENMASK(7, 0));
+
+	for (i = 0; i <= 12; i += 2)
+		svsb->volt[i + 1] = interpolate(svsb->freq_pct[i],
+						svsb->freq_pct[i + 2],
+						svsb->volt[i],
+						svsb->volt[i + 2],
+						svsb->freq_pct[i + 1]);
+
+	svsb->volt[15] = interpolate(svsb->freq_pct[12],
+				     svsb->freq_pct[14],
+				     svsb->volt[12],
+				     svsb->volt[14],
+				     svsb->freq_pct[15]);
+
+	for (i = 0; i < svsb->opp_count; i++)
+		svsb->volt[i] += svsb->volt_od;
+}
+
+static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svs_writel_relaxed(svsp,
+			   (svsb->freq_pct[14] << 24) |
+			   (svsb->freq_pct[12] << 16) |
+			   (svsb->freq_pct[10] << 8) |
+			   svsb->freq_pct[8],
+			   FREQPCT74);
+
+	svs_writel_relaxed(svsp,
+			   (svsb->freq_pct[6] << 24) |
+			   (svsb->freq_pct[4] << 16) |
+			   (svsb->freq_pct[2] << 8) |
+			   svsb->freq_pct[0],
+			   FREQPCT30);
+}
+
+static void svs_set_bank_phase(struct svs_platform *svsp,
+			       enum svsb_phase target_phase)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 des_char, temp_char, det_char, limit_vals, init2vals;
+
+	svs_switch_bank(svsp);
+
+	des_char = (svsb->bdes << 8) | svsb->mdes;
+	svs_writel_relaxed(svsp, des_char, DESCHAR);
+
+	temp_char = (svsb->vco << 16) | (svsb->mtdes << 8) | svsb->dvt_fixed;
+	svs_writel_relaxed(svsp, temp_char, TEMPCHAR);
+
+	det_char = (svsb->dcbdet << 8) | svsb->dcmdet;
+	svs_writel_relaxed(svsp, det_char, DETCHAR);
+
+	svs_writel_relaxed(svsp, svsb->dc_config, DCCONFIG);
+	svs_writel_relaxed(svsp, svsb->age_config, AGECONFIG);
+	svs_writel_relaxed(svsp, SVSB_RUNCONFIG_DEFAULT, RUNCONFIG);
+
+	svsb->set_freq_pct(svsp);
+
+	limit_vals = (svsb->vmax << 24) | (svsb->vmin << 16) |
+		     (SVSB_DTHI << 8) | SVSB_DTLO;
+	svs_writel_relaxed(svsp, limit_vals, LIMITVALS);
+
+	svs_writel_relaxed(svsp, SVSB_DET_WINDOW, DETWINDOW);
+	svs_writel_relaxed(svsp, SVSB_DET_MAX, CONFIG);
+	svs_writel_relaxed(svsp, svsb->chk_shift, CHKSHIFT);
+	svs_writel_relaxed(svsp, svsb->ctl0, CTL0);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+
+	switch (target_phase) {
+	case SVSB_PHASE_INIT01:
+		svs_writel_relaxed(svsp, svsb->vboot, VBOOT);
+		svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN);
+		svs_writel_relaxed(svsp, SVSB_EN_INIT01, SVSEN);
+		break;
+	case SVSB_PHASE_INIT02:
+		svs_writel_relaxed(svsp, SVSB_INTEN_INIT0x, INTEN);
+		init2vals = (svsb->age_voffset_in << 16) | svsb->dc_voffset_in;
+		svs_writel_relaxed(svsp, init2vals, INIT2VALS);
+		svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN);
+		break;
+	default:
+		dev_err(svsb->dev, "requested unknown target phase: %u\n",
+			target_phase);
+		break;
+	}
+}
+
+static inline void svs_error_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_err(svsb->dev, "%s: CORESEL = 0x%08x\n",
+		__func__, svs_readl_relaxed(svsp, CORESEL));
+	dev_err(svsb->dev, "SVSEN = 0x%08x, INTSTS = 0x%08x\n",
+		svs_readl_relaxed(svsp, SVSEN),
+		svs_readl_relaxed(svsp, INTSTS));
+	dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n",
+		svs_readl_relaxed(svsp, SMSTATE0),
+		svs_readl_relaxed(svsp, SMSTATE1));
+
+	svsb->phase = SVSB_PHASE_ERROR;
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+}
+
+static inline void svs_init01_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_info(svsb->dev, "%s: VDN74~30:0x%08x~0x%08x, DC:0x%08x\n",
+		 __func__, svs_readl_relaxed(svsp, VDESIGN74),
+		 svs_readl_relaxed(svsp, VDESIGN30),
+		 svs_readl_relaxed(svsp, DCVALUES));
+
+	svsb->phase = SVSB_PHASE_INIT01;
+	svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
+				GENMASK(15, 0)) + 1;
+	if (svsb->volt_flags & SVSB_INIT01_VOLT_IGNORE ||
+	    (svsb->dc_voffset_in & SVSB_DC_SIGNED_BIT &&
+	     svsb->volt_flags & SVSB_INIT01_VOLT_INC_ONLY))
+		svsb->dc_voffset_in = 0;
+
+	svsb->age_voffset_in = svs_readl_relaxed(svsp, AGEVALUES) &
+			       GENMASK(15, 0);
+
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
+	svsb->core_sel &= ~SVSB_DET_CLK_EN;
+}
+
+static inline void svs_init02_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	dev_info(svsb->dev, "%s: VOP74~30:0x%08x~0x%08x, DC:0x%08x\n",
+		 __func__, svs_readl_relaxed(svsp, VOP74),
+		 svs_readl_relaxed(svsp, VOP30),
+		 svs_readl_relaxed(svsp, DCVALUES));
+
+	svsb->phase = SVSB_PHASE_INIT02;
+	svsb->get_volts(svsp);
+
+	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
+}
+
+static irqreturn_t svs_isr(int irq, void *data)
+{
+	struct svs_platform *svsp = data;
+	struct svs_bank *svsb = NULL;
+	unsigned long flags;
+	u32 idx, int_sts, svs_en;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		WARN(!svsb, "%s: svsb(%s) is null", __func__, svsb->name);
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+
+		/* Find out which svs bank fires interrupt */
+		if (svsb->int_st & svs_readl_relaxed(svsp, INTST)) {
+			spin_unlock_irqrestore(&svs_lock, flags);
+			continue;
+		}
+
+		svs_switch_bank(svsp);
+		int_sts = svs_readl_relaxed(svsp, INTSTS);
+		svs_en = svs_readl_relaxed(svsp, SVSEN);
+
+		if (int_sts == SVSB_INTSTS_COMPLETE &&
+		    svs_en == SVSB_EN_INIT01)
+			svs_init01_isr_handler(svsp);
+		else if (int_sts == SVSB_INTSTS_COMPLETE &&
+			 svs_en == SVSB_EN_INIT02)
+			svs_init02_isr_handler(svsp);
+		else
+			svs_error_isr_handler(svsp);
+
+		spin_unlock_irqrestore(&svs_lock, flags);
+		break;
+	}
+
+	svs_adjust_pm_opp_volts(svsb);
+
+	if (svsb->phase == SVSB_PHASE_INIT01 ||
+	    svsb->phase == SVSB_PHASE_INIT02)
+		complete(&svsb->init_completion);
+
+	return IRQ_HANDLED;
+}
+
+static int svs_init01(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct pm_qos_request *cpu_qos_request;
+	unsigned long flags, time_left;
+	bool search_done;
+	int ret = 0, r;
+	u32 opp_freq, opp_vboot, buck_volt, idx, i;
+
+	cpu_qos_request = kzalloc(sizeof(*cpu_qos_request), GFP_KERNEL);
+	if (!cpu_qos_request)
+		return -ENOMEM;
+
+	/* Let CPUs leave idle-off state for initializing svs_init01. */
+	cpu_latency_qos_add_request(cpu_qos_request, 0);
+
+	 /* Svs bank init01 preparation - power enable */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		ret = regulator_enable(svsb->buck);
+		if (ret) {
+			dev_err(svsb->dev, "%s enable fail: %d\n",
+				svsb->buck_name, ret);
+			goto init01_remove_cpu_qos_request;
+		}
+
+		/* Some buck doesn't support mode change. Show fail msg only */
+		ret = regulator_set_mode(svsb->buck, REGULATOR_MODE_FAST);
+		if (ret)
+			dev_notice(svsb->dev, "set fast mode fail: %d\n", ret);
+
+		if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
+			if (!pm_runtime_enabled(svsb->pd_dev)) {
+				pm_runtime_enable(svsb->pd_dev);
+				svsb->pm_runtime_enabled_count++;
+			}
+
+			ret = pm_runtime_get_sync(svsb->pd_dev);
+			if (ret < 0) {
+				dev_err(svsb->dev, "mtcmos on fail: %d\n", ret);
+				goto init01_remove_cpu_qos_request;
+			}
+		}
+	}
+
+	/*
+	 * Svs bank init01 preparation - vboot voltage adjustment
+	 * Sometimes two svs banks use the same buck. Therefore,
+	 * we have to set each svs bank to target voltage(vboot) first.
+	 */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		/*
+		 * Find the fastest freq that can be run at vboot and
+		 * fix to that freq until svs_init01 is done.
+		 */
+		search_done = false;
+		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
+						      svsb->volt_step,
+						      svsb->volt_base);
+
+		for (i = 0; i < svsb->opp_count; i++) {
+			opp_freq = svsb->opp_dfreq[i];
+			if (!search_done && svsb->opp_dvolt[i] <= opp_vboot) {
+				ret = dev_pm_opp_adjust_voltage(svsb->opp_dev,
+								opp_freq,
+								opp_vboot,
+								opp_vboot,
+								opp_vboot);
+				if (ret) {
+					dev_err(svsb->dev,
+						"set opp %uuV vboot fail: %d\n",
+						opp_vboot, ret);
+					goto init01_finish;
+				}
+
+				search_done = true;
+			} else {
+				ret = dev_pm_opp_disable(svsb->opp_dev,
+							 svsb->opp_dfreq[i]);
+				if (ret) {
+					dev_err(svsb->dev,
+						"opp %uHz disable fail: %d\n",
+						svsb->opp_dfreq[i], ret);
+					goto init01_finish;
+				}
+			}
+		}
+	}
+
+	/* Svs bank init01 begins */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		opp_vboot = svs_bank_volt_to_opp_volt(svsb->vboot,
+						      svsb->volt_step,
+						      svsb->volt_base);
+
+		buck_volt = regulator_get_voltage(svsb->buck);
+		if (buck_volt != opp_vboot) {
+			dev_err(svsb->dev,
+				"buck voltage: %uuV, expected vboot: %uuV\n",
+				buck_volt, opp_vboot);
+			ret = -EPERM;
+			goto init01_finish;
+		}
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_INIT01);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		time_left = wait_for_completion_timeout(&svsb->init_completion,
+							msecs_to_jiffies(5000));
+		if (!time_left) {
+			dev_err(svsb->dev, "init01 completion timeout\n");
+			ret = -EBUSY;
+			goto init01_finish;
+		}
+	}
+
+init01_finish:
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT01))
+			continue;
+
+		for (i = 0; i < svsb->opp_count; i++) {
+			r = dev_pm_opp_enable(svsb->opp_dev,
+					      svsb->opp_dfreq[i]);
+			if (r)
+				dev_err(svsb->dev, "opp %uHz enable fail: %d\n",
+					svsb->opp_dfreq[i], r);
+		}
+
+		if (svsb->volt_flags & SVSB_INIT01_PD_REQ) {
+			r = pm_runtime_put_sync(svsb->pd_dev);
+			if (r)
+				dev_err(svsb->dev, "mtcmos off fail: %d\n", r);
+
+			if (svsb->pm_runtime_enabled_count > 0) {
+				pm_runtime_disable(svsb->pd_dev);
+				svsb->pm_runtime_enabled_count--;
+			}
+		}
+
+		r = regulator_set_mode(svsb->buck, REGULATOR_MODE_NORMAL);
+		if (r)
+			dev_notice(svsb->dev, "set normal mode fail: %d\n", r);
+
+		r = regulator_disable(svsb->buck);
+		if (r)
+			dev_err(svsb->dev, "%s disable fail: %d\n",
+				svsb->buck_name, r);
+	}
+
+init01_remove_cpu_qos_request:
+	cpu_latency_qos_remove_request(cpu_qos_request);
+	kfree(cpu_qos_request);
+
+	return ret;
+}
+
+static int svs_init02(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	unsigned long flags, time_left;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT02))
+			continue;
+
+		reinit_completion(&svsb->init_completion);
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_INIT02);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		time_left = wait_for_completion_timeout(&svsb->init_completion,
+							msecs_to_jiffies(5000));
+		if (!time_left) {
+			dev_err(svsb->dev, "init02 completion timeout\n");
+			return -EBUSY;
+		}
+	}
+
+	return 0;
+}
+
+static int svs_start(struct svs_platform *svsp)
+{
+	int ret;
+
+	ret = svs_init01(svsp);
+	if (ret)
+		return ret;
+
+	ret = svs_init02(svsp);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int svs_suspend(struct device *dev)
+{
+	struct svs_platform *svsp = dev_get_drvdata(dev);
+	struct svs_bank *svsb;
+	unsigned long flags;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		/* This might wait for svs_isr() process */
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_switch_bank(svsp);
+		svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+		svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		svsb->phase = SVSB_PHASE_ERROR;
+		svs_adjust_pm_opp_volts(svsb);
+	}
+
+	clk_disable_unprepare(svsp->main_clk);
+
+	return 0;
+}
+
+static int svs_resume(struct device *dev)
+{
+	struct svs_platform *svsp = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_prepare_enable(svsp->main_clk);
+	if (ret) {
+		dev_err(svsp->dev, "cannot enable main_clk, disable svs\n");
+		return ret;
+	}
+
+	ret = svs_init02(svsp);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int svs_bank_resource_setup(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct dev_pm_opp *opp;
+	unsigned long freq;
+	int count, ret;
+	u32 idx, i;
+
+	dev_set_drvdata(svsp->dev, svsp);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			svsb->name = "SVSB_CPU_LITTLE";
+			break;
+		case SVSB_CPU_BIG:
+			svsb->name = "SVSB_CPU_BIG";
+			break;
+		case SVSB_CCI:
+			svsb->name = "SVSB_CCI";
+			break;
+		case SVSB_GPU:
+			svsb->name = "SVSB_GPU";
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return -EINVAL;
+		}
+
+		svsb->dev = devm_kzalloc(svsp->dev, sizeof(*svsb->dev),
+					 GFP_KERNEL);
+		if (!svsb->dev)
+			return -ENOMEM;
+
+		ret = dev_set_name(svsb->dev, "%s", svsb->name);
+		if (ret)
+			return ret;
+
+		dev_set_drvdata(svsb->dev, svsp);
+
+		ret = dev_pm_opp_of_add_table(svsb->opp_dev);
+		if (ret) {
+			dev_err(svsb->dev, "add opp table fail: %d\n", ret);
+			return ret;
+		}
+
+		mutex_init(&svsb->lock);
+		init_completion(&svsb->init_completion);
+
+		if (svsb->mode_support & SVSB_MODE_INIT01) {
+			svsb->buck = devm_regulator_get_optional(svsb->opp_dev,
+								 svsb->buck_name);
+			if (IS_ERR(svsb->buck)) {
+				dev_err(svsb->dev, "cannot get \"%s-supply\"\n",
+					svsb->buck_name);
+				return PTR_ERR(svsb->buck);
+			}
+		}
+
+		count = dev_pm_opp_get_opp_count(svsb->opp_dev);
+		if (svsb->opp_count != count) {
+			dev_err(svsb->dev,
+				"opp_count not \"%u\" but get \"%d\"?\n",
+				svsb->opp_count, count);
+			return count;
+		}
+
+		for (i = 0, freq = U32_MAX; i < svsb->opp_count; i++, freq--) {
+			opp = dev_pm_opp_find_freq_floor(svsb->opp_dev, &freq);
+			if (IS_ERR(opp)) {
+				dev_err(svsb->dev, "cannot find freq = %ld\n",
+					PTR_ERR(opp));
+				return PTR_ERR(opp);
+			}
+
+			svsb->opp_dfreq[i] = freq;
+			svsb->opp_dvolt[i] = dev_pm_opp_get_voltage(opp);
+			svsb->freq_pct[i] = percent(svsb->opp_dfreq[i],
+						    svsb->freq_base);
+			dev_pm_opp_put(opp);
+		}
+	}
+
+	return 0;
+}
+
+static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	u32 idx, i, ft_pgm;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse[i])
+			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+				 i, svsp->efuse[i]);
+
+	if (!svsp->efuse[2]) {
+		dev_notice(svsp->dev, "svs_efuse[2] = 0x0?\n");
+		return false;
+	}
+
+	/* Svs efuse parsing */
+	ft_pgm = (svsp->efuse[0] >> 4) & GENMASK(3, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (ft_pgm <= 1)
+			svsb->volt_flags |= SVSB_INIT01_VOLT_IGNORE;
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			svsb->bdes = svsp->efuse[16] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[16] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[16] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[16] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 10;
+			else
+				svsb->volt_od += 2;
+			break;
+		case SVSB_CPU_BIG:
+			svsb->bdes = svsp->efuse[18] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[18] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[18] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[18] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = svsp->efuse[17] & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 15;
+			else
+				svsb->volt_od += 12;
+			break;
+		case SVSB_CCI:
+			svsb->bdes = svsp->efuse[4] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[4] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[4] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[4] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = (svsp->efuse[5] >> 16) & GENMASK(7, 0);
+
+			if (ft_pgm <= 3)
+				svsb->volt_od += 10;
+			else
+				svsb->volt_od += 2;
+			break;
+		case SVSB_GPU:
+			svsb->bdes = svsp->efuse[6] & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[6] >> 8) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[6] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[6] >> 24) & GENMASK(7, 0);
+			svsb->mtdes  = svsp->efuse[5] & GENMASK(7, 0);
+
+			if (ft_pgm >= 2) {
+				svsb->freq_base = 800000000; /* 800MHz */
+				svsb->dvt_fixed = 2;
+			}
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static bool svs_is_efuse_data_correct(struct svs_platform *svsp)
+{
+	struct nvmem_cell *cell;
+
+	/* Get svs efuse by nvmem */
+	cell = nvmem_cell_get(svsp->dev, "svs-calibration-data");
+	if (IS_ERR(cell)) {
+		dev_err(svsp->dev, "no \"svs-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		return false;
+	}
+
+	svsp->efuse = nvmem_cell_read(cell, &svsp->efuse_max);
+	if (IS_ERR(svsp->efuse)) {
+		dev_err(svsp->dev, "cannot read svs efuse: %ld\n",
+			PTR_ERR(svsp->efuse));
+		return false;
+	}
+
+	svsp->efuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	return svsp->efuse_parsing(svsp);
+}
+
+static struct device *svs_get_subsys_device(struct svs_platform *svsp,
+					    const char *node_name)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+
+	np = of_find_node_by_name(NULL, node_name);
+	if (!np) {
+		dev_err(svsp->dev, "cannot find %s node\n", node_name);
+		return ERR_PTR(-ENODEV);
+	}
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev) {
+		of_node_put(np);
+		dev_err(svsp->dev, "cannot find pdev by %s\n", node_name);
+		return ERR_PTR(-ENXIO);
+	}
+
+	of_node_put(np);
+
+	return &pdev->dev;
+}
+
+static struct device *svs_add_device_link(struct svs_platform *svsp,
+					  const char *node_name)
+{
+	struct device *dev;
+	struct device_link *sup_link;
+
+	if (!node_name) {
+		dev_err(svsp->dev, "node name cannot be null\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	dev = svs_get_subsys_device(svsp, node_name);
+	if (IS_ERR(dev))
+		return dev;
+
+	sup_link = device_link_add(svsp->dev, dev,
+				   DL_FLAG_AUTOREMOVE_CONSUMER);
+	if (!sup_link) {
+		dev_err(svsp->dev, "sup_link is NULL\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	if (sup_link->supplier->links.status != DL_DEV_DRIVER_BOUND)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	return dev;
+}
+
+static int svs_mt8183_platform_probe(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+		case SVSB_CPU_BIG:
+			svsb->opp_dev = get_cpu_device(svsb->cpu_id);
+			break;
+		case SVSB_CCI:
+			svsb->opp_dev = svs_add_device_link(svsp, "cci");
+			break;
+		case SVSB_GPU:
+			svsb->opp_dev = svs_add_device_link(svsp, "mali");
+			svsb->pd_dev = svs_add_device_link(svsp, "mali_gpu_core2");
+			if (IS_ERR(svsb->pd_dev))
+				return PTR_ERR(svsb->pd_dev);
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			return -EINVAL;
+		}
+
+		if (IS_ERR(svsb->opp_dev))
+			return PTR_ERR(svsb->opp_dev);
+	}
+
+	return 0;
+}
+
+static struct svs_bank svs_mt8183_banks[] = {
+	{
+		.sw_id			= SVSB_CPU_LITTLE,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.cpu_id			= 0,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1989000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x64,
+		.vmin			= 0x18,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0000,
+		.int_st			= BIT(0),
+		.ctl0			= 0x00010001,
+	},
+	{
+		.sw_id			= SVSB_CPU_BIG,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.cpu_id			= 4,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1989000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x58,
+		.vmin			= 0x10,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0001,
+		.int_st			= BIT(1),
+		.ctl0			= 0x00000001,
+	},
+	{
+		.sw_id			= SVSB_CCI,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.buck_name		= "proc",
+		.volt_flags		= SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 1196000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x64,
+		.vmin			= 0x18,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x7,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0002,
+		.int_st			= BIT(2),
+		.ctl0			= 0x00100003,
+	},
+	{
+		.sw_id			= SVSB_GPU,
+		.set_freq_pct		= svs_set_bank_freq_pct_v2,
+		.get_volts		= svs_get_bank_volts_v2,
+		.buck_name		= "mali",
+		.volt_flags		= SVSB_INIT01_PD_REQ |
+					  SVSB_INIT01_VOLT_INC_ONLY,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 900000000,
+		.vboot			= 0x30,
+		.volt_step		= 6250,
+		.volt_base		= 500000,
+		.vmax			= 0x40,
+		.vmin			= 0x14,
+		.age_config		= 0x555555,
+		.dc_config		= 0x555555,
+		.dvt_fixed		= 0x3,
+		.vco			= 0x10,
+		.chk_shift		= 0x77,
+		.core_sel		= 0x8fff0003,
+		.int_st			= BIT(3),
+		.ctl0			= 0x00050001,
+	},
+};
+
+static const struct svs_platform_data svs_mt8183_platform_data = {
+	.name = "mt8183-svs",
+	.banks = svs_mt8183_banks,
+	.efuse_parsing = svs_mt8183_efuse_parsing,
+	.probe = svs_mt8183_platform_probe,
+	.irqflags = IRQF_TRIGGER_LOW,
+	.regs = svs_regs_v2,
+	.bank_max = ARRAY_SIZE(svs_mt8183_banks),
+};
+
+static const struct of_device_id svs_of_match[] = {
+	{
+		.compatible = "mediatek,mt8183-svs",
+		.data = &svs_mt8183_platform_data,
+	}, {
+		/* Sentinel */
+	},
+};
+
+static struct svs_platform *svs_platform_probe(struct platform_device *pdev)
+{
+	struct svs_platform *svsp;
+	const struct svs_platform_data *svsp_data;
+	int ret;
+
+	svsp_data = of_device_get_match_data(&pdev->dev);
+	if (!svsp_data) {
+		dev_err(&pdev->dev, "no svs platform data?\n");
+		return ERR_PTR(-EPERM);
+	}
+
+	svsp = devm_kzalloc(&pdev->dev, sizeof(*svsp), GFP_KERNEL);
+	if (!svsp)
+		return ERR_PTR(-ENOMEM);
+
+	svsp->dev = &pdev->dev;
+	svsp->name = svsp_data->name;
+	svsp->banks = svsp_data->banks;
+	svsp->efuse_parsing = svsp_data->efuse_parsing;
+	svsp->probe = svsp_data->probe;
+	svsp->irqflags = svsp_data->irqflags;
+	svsp->regs = svsp_data->regs;
+	svsp->bank_max = svsp_data->bank_max;
+
+	ret = svsp->probe(svsp);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return svsp;
+}
+
+static int svs_probe(struct platform_device *pdev)
+{
+	struct svs_platform *svsp;
+	unsigned int svsp_irq;
+	int ret;
+
+	svsp = svs_platform_probe(pdev);
+	if (IS_ERR(svsp)) {
+		dev_err_probe(&pdev->dev, PTR_ERR(svsp),
+			      "svs platform probe fail\n");
+		return PTR_ERR(svsp);
+	}
+
+	if (!svs_is_efuse_data_correct(svsp)) {
+		dev_notice(svsp->dev, "efuse data isn't correct\n");
+		return -EPERM;
+	}
+
+	ret = svs_bank_resource_setup(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs bank resource setup fail: %d\n", ret);
+		return ret;
+	}
+
+	svsp_irq = irq_of_parse_and_map(svsp->dev->of_node, 0);
+	ret = devm_request_threaded_irq(svsp->dev, svsp_irq, NULL, svs_isr,
+					svsp->irqflags | IRQF_ONESHOT,
+					svsp->name, svsp);
+	if (ret) {
+		dev_err(svsp->dev, "register irq(%d) failed: %d\n",
+			svsp_irq, ret);
+		return ret;
+	}
+
+	svsp->main_clk = devm_clk_get(svsp->dev, "main");
+	if (IS_ERR(svsp->main_clk)) {
+		dev_err(svsp->dev, "failed to get clock: %ld\n",
+			PTR_ERR(svsp->main_clk));
+		return PTR_ERR(svsp->main_clk);
+	}
+
+	ret = clk_prepare_enable(svsp->main_clk);
+	if (ret) {
+		dev_err(svsp->dev, "cannot enable main clk: %d\n", ret);
+		return ret;
+	}
+
+	svsp->base = of_iomap(svsp->dev->of_node, 0);
+	if (IS_ERR_OR_NULL(svsp->base)) {
+		dev_err(svsp->dev, "cannot find svs register base\n");
+		ret = -EINVAL;
+		goto svs_probe_clk_disable;
+	}
+
+	ret = svs_start(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs start fail: %d\n", ret);
+		goto svs_probe_iounmap;
+	}
+
+	return 0;
+
+svs_probe_iounmap:
+	iounmap(svsp->base);
+
+svs_probe_clk_disable:
+	clk_disable_unprepare(svsp->main_clk);
+
+	return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(svs_pm_ops, svs_suspend, svs_resume);
+
+static struct platform_driver svs_driver = {
+	.probe	= svs_probe,
+	.driver	= {
+		.name		= "mtk-svs",
+		.pm		= &svs_pm_ops,
+		.of_match_table	= of_match_ptr(svs_of_match),
+	},
+};
+
+module_platform_driver(svs_driver);
+
+MODULE_AUTHOR("Roger Lu <roger.lu at mediatek.com>");
+MODULE_DESCRIPTION("MediaTek SVS driver");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:55 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:55 +0800
Subject: [PATCH v22 6/7] dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-7-roger.lu@mediatek.com>

Add mt8192 svs compatible/resets in dt-bindings.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../devicetree/bindings/soc/mediatek/mtk-svs.yaml         | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
index dfd275f4973c..eecfec13ee8b 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -22,6 +22,7 @@ properties:
   compatible:
     enum:
       - mediatek,mt8183-svs
+      - mediatek,mt8192-svs
 
   reg:
     maxItems: 1
@@ -50,6 +51,13 @@ properties:
       - const: svs-calibration-data
       - const: t-calibration-data
 
+  resets:
+    maxItems: 1
+
+  reset-names:
+    items:
+      - const: svs_rst
+
 required:
   - compatible
   - reg
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:50 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:50 +0800
Subject: [PATCH v22 1/7] dt-bindings: soc: mediatek: add mtk svs dt-bindings
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-2-roger.lu@mediatek.com>

Document the binding for enabling mtk svs on MediaTek SoC.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 .../bindings/soc/mediatek/mtk-svs.yaml        | 83 +++++++++++++++++++
 1 file changed, 83 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml

diff --git a/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
new file mode 100644
index 000000000000..dfd275f4973c
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/soc/mediatek/mtk-svs.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek Smart Voltage Scaling (SVS) Device Tree Bindings
+
+maintainers:
+  - Roger Lu <roger.lu at mediatek.com>
+  - Matthias Brugger <matthias.bgg at gmail.com>
+  - Kevin Hilman <khilman at kernel.org>
+
+description: |+
+  The SVS engine is a piece of hardware which has several
+  controllers(banks) for calculating suitable voltage to
+  different power domains(CPU/GPU/CCI) according to
+  chip process corner, temperatures and other factors. Then DVFS
+  driver could apply SVS bank voltage to PMIC/Buck.
+
+properties:
+  compatible:
+    enum:
+      - mediatek,mt8183-svs
+
+  reg:
+    maxItems: 1
+    description: Address range of the MTK SVS controller.
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+    description: Main clock for MTK SVS controller to work.
+
+  clock-names:
+    const: main
+
+  nvmem-cells:
+    minItems: 1
+    description:
+      Phandle to the calibration data provided by a nvmem device.
+    items:
+      - description: SVS efuse for SVS controller
+      - description: Thermal efuse for SVS controller
+
+  nvmem-cell-names:
+    items:
+      - const: svs-calibration-data
+      - const: t-calibration-data
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - nvmem-cells
+  - nvmem-cell-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mt8183-clk.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        svs at 1100b000 {
+            compatible = "mediatek,mt8183-svs";
+            reg = <0 0x1100b000 0 0x1000>;
+            interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+            clocks = <&infracfg CLK_INFRA_THERM>;
+            clock-names = "main";
+            nvmem-cells = <&svs_calibration>, <&thermal_calibration>;
+            nvmem-cell-names = "svs-calibration-data", "t-calibration-data";
+        };
+    };
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:51 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:51 +0800
Subject: [PATCH v22 2/7] arm64: dts: mt8183: add svs device information
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-3-roger.lu@mediatek.com>

Add compatible/reg/irq/clock/efuse setting in svs node.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/mt8183.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 00f2ddd245e1..e1a3b63f4250 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -807,6 +807,18 @@
 			status = "disabled";
 		};
 
+		svs: svs at 1100b000 {
+			compatible = "mediatek,mt8183-svs";
+			reg = <0 0x1100b000 0 0x1000>;
+			interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_LOW>;
+			clocks = <&infracfg CLK_INFRA_THERM>;
+			clock-names = "main";
+			nvmem-cells = <&svs_calibration>,
+				      <&thermal_calibration>;
+			nvmem-cell-names = "svs-calibration-data",
+					   "t-calibration-data";
+		};
+
 		thermal: thermal at 1100b000 {
 			#thermal-sensor-cells = <1>;
 			compatible = "mediatek,mt8183-thermal";
@@ -1325,6 +1337,10 @@
 			mipi_tx_calibration: calib at 190 {
 				reg = <0x190 0xc>;
 			};
+
+			svs_calibration: calib at 580 {
+				reg = <0x580 0x64>;
+			};
 		};
 
 		u3phy: t-phy at 11f40000 {
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:49 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:49 +0800
Subject: [PATCH v22 0/7] soc: mediatek: SVS: introduce MTK SVS engine
Message-ID: <20220127033956.24585-1-roger.lu@mediatek.com>

The Smart Voltage Scaling(SVS) engine is a piece of hardware
which calculates suitable SVS bank voltages to OPP voltage table.
Then, DVFS driver could apply those SVS bank voltages to PMIC/Buck
when receiving OPP_EVENT_ADJUST_VOLTAGE.

1. SVS driver uses OPP adjust event in [1] to update OPP table voltage part.
2. SVS driver gets thermal/GPU device by node [2][3] and CPU device by get_cpu_device().
After retrieving subsys device, SVS driver calls device_link_add() to make sure probe/suspend callback priority.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git/commit/?h=opp/linux-next&id=25cb20a212a1f989385dfe23230817e69c62bee5
[2] https://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git/commit/?h=opp/linux-next&id=b325ce39785b1408040d90365a6ab1aa36e94f87
[3] https://git.kernel.org/pub/scm/linux/kernel/git/matthias.bgg/linux.git/commit/?h=v5.16-next/dts64&id=a8168cebf1bca1b5269e8a7eb2626fb76814d6e2

change since v21:
- Rebase to kernel 5.17-rc1.
- Remove unnecessary "maxItems" from nvmem-cells in mtk-svs.yaml.
- Move svs_platform_data definition to the beginning of the file for increased readability.
- For better performance purpose, we add "thermal_zone_device" memeber in svs bank structure and cache it at driver probe time.
- Remove svs_get_zone_temperature() and call thermal_zone_get_temp() directly when we needs to read temperature.
- Drop mt8192 svs node patch and we'll submit another complete mt8192.dtsi patch including mt8192 svs node.
- Replace mask7_0 with GENMASK macro and bits8/reg_bytes with corresponding definition.
- Separate definition with "register common configuration" and "related setting" for better categorization.
- Remove redundant codes including "svsb->suspended concept" and refine comments.
- Move devm_regulator_get_optional() to svs_bank_resource_setup() for better understanding.

Roger Lu (7):
  [v22,1/7] dt-bindings: soc: mediatek: add mtk svs dt-bindings
  [v22,2/7] arm64: dts: mt8183: add svs device information
  [v22,3/7] soc: mediatek: SVS: introduce MTK SVS engine
  [v22,4/7] soc: mediatek: SVS: add monitor mode
  [v22,5/7] soc: mediatek: SVS: add debug commands
  [v22,6/7] dt-bindings: soc: mediatek: add mt8192 svs dt-bindings
  [v22,7/7] soc: mediatek: SVS: add mt8192 SVS GPU driver

 .../bindings/soc/mediatek/mtk-svs.yaml        |   91 +
 arch/arm64/boot/dts/mediatek/mt8183.dtsi      |   16 +
 drivers/soc/mediatek/Kconfig                  |   10 +
 drivers/soc/mediatek/Makefile                 |    1 +
 drivers/soc/mediatek/mtk-svs.c                | 2439 +++++++++++++++++
 5 files changed, 2557 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/soc/mediatek/mtk-svs.yaml
 create mode 100644 drivers/soc/mediatek/mtk-svs.c




From roger.lu at mediatek.com  Wed Jan 26 19:39:54 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:54 +0800
Subject: [PATCH v22 5/7] soc: mediatek: SVS: add debug commands
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-6-roger.lu@mediatek.com>

The purpose of SVS is to help find the suitable voltages
for DVFS. Therefore, if SVS bank voltages are concerned
to be wrong, we can adjust SVS bank voltages by this patch.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 321 ++++++++++++++++++++++++++++++++-
 1 file changed, 318 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index be53470d439c..d3977de56335 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -6,6 +6,7 @@
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/device.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
@@ -23,6 +24,7 @@
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/thermal.h>
@@ -69,6 +71,39 @@
 
 static DEFINE_SPINLOCK(svs_lock);
 
+#define debug_fops_ro(name)						\
+	static int svs_##name##_debug_open(struct inode *inode,		\
+					   struct file *filp)		\
+	{								\
+		return single_open(filp, svs_##name##_debug_show,	\
+				   inode->i_private);			\
+	}								\
+	static const struct file_operations svs_##name##_debug_fops = {	\
+		.owner = THIS_MODULE,					\
+		.open = svs_##name##_debug_open,			\
+		.read = seq_read,					\
+		.llseek = seq_lseek,					\
+		.release = single_release,				\
+	}
+
+#define debug_fops_rw(name)						\
+	static int svs_##name##_debug_open(struct inode *inode,		\
+					   struct file *filp)		\
+	{								\
+		return single_open(filp, svs_##name##_debug_show,	\
+				   inode->i_private);			\
+	}								\
+	static const struct file_operations svs_##name##_debug_fops = {	\
+		.owner = THIS_MODULE,					\
+		.open = svs_##name##_debug_open,			\
+		.read = seq_read,					\
+		.write = svs_##name##_debug_write,			\
+		.llseek = seq_lseek,					\
+		.release = single_release,				\
+	}
+
+#define svs_dentry_data(name)	{__stringify(name), &svs_##name##_debug_fops}
+
 /**
  * enum svsb_phase - svs bank phase enumeration
  * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
@@ -269,6 +304,8 @@ struct svs_platform_data {
  * @tzone_name: thermal zone name
  * @phase: bank current phase
  * @volt_od: bank voltage overdrive
+ * @voffset: bank voltage offset for debug purpose
+ * @reg_data: bank register data in different phase for debug purpose
  * @pm_runtime_enabled_count: bank pm runtime enabled count
  * @mode_support: bank mode support.
  * @freq_base: reference frequency for bank init
@@ -328,6 +365,8 @@ struct svs_bank {
 	char *tzone_name;
 	enum svsb_phase phase;
 	s32 volt_od;
+	s32 voffset;
+	u32 reg_data[SVSB_PHASE_MAX][SVS_REG_MAX];
 	u32 pm_runtime_enabled_count;
 	u32 mode_support;
 	u32 freq_base;
@@ -434,14 +473,15 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 			/* do nothing */
 			goto unlock_mutex;
 		case SVSB_PHASE_INIT02:
-			svsb_volt = max(svsb->volt[i], svsb->vmin);
+			svsb_volt = max(svsb->volt[i] + svsb->voffset,
+					svsb->vmin);
 			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
 							     svsb->volt_step,
 							     svsb->volt_base);
 			break;
 		case SVSB_PHASE_MON:
-			svsb_volt = max(svsb->volt[i] + temp_voffset,
-					svsb->vmin);
+			svsb_volt = max(svsb->volt[i] + temp_voffset +
+					svsb->voffset, svsb->vmin);
 			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
 							     svsb->volt_step,
 							     svsb->volt_base);
@@ -470,6 +510,257 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 	return ret;
 }
 
+static int svs_dump_debug_show(struct seq_file *m, void *p)
+{
+	struct svs_platform *svsp = (struct svs_platform *)m->private;
+	struct svs_bank *svsb;
+	unsigned long svs_reg_addr;
+	u32 idx, i, j, bank_id;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse && svsp->efuse[i])
+			seq_printf(m, "M_HW_RES%d = 0x%08x\n",
+				   i, svsp->efuse[i]);
+
+	for (i = 0; i < svsp->tefuse_max; i++)
+		if (svsp->tefuse)
+			seq_printf(m, "THERMAL_EFUSE%d = 0x%08x\n",
+				   i, svsp->tefuse[i]);
+
+	for (bank_id = 0, idx = 0; idx < svsp->bank_max; idx++, bank_id++) {
+		svsb = &svsp->banks[idx];
+
+		for (i = SVSB_PHASE_INIT01; i <= SVSB_PHASE_MON; i++) {
+			seq_printf(m, "Bank_number = %u\n", bank_id);
+
+			if (i == SVSB_PHASE_INIT01 || i == SVSB_PHASE_INIT02)
+				seq_printf(m, "mode = init%d\n", i);
+			else if (i == SVSB_PHASE_MON)
+				seq_puts(m, "mode = mon\n");
+			else
+				seq_puts(m, "mode = error\n");
+
+			for (j = DESCHAR; j < SVS_REG_MAX; j++) {
+				svs_reg_addr = (unsigned long)(svsp->base +
+							       svsp->regs[j]);
+				seq_printf(m, "0x%08lx = 0x%08x\n",
+					   svs_reg_addr, svsb->reg_data[i][j]);
+			}
+		}
+	}
+
+	return 0;
+}
+
+debug_fops_ro(dump);
+
+static int svs_enable_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+
+	switch (svsb->phase) {
+	case SVSB_PHASE_ERROR:
+		seq_puts(m, "disabled\n");
+		break;
+	case SVSB_PHASE_INIT01:
+		seq_puts(m, "init1\n");
+		break;
+	case SVSB_PHASE_INIT02:
+		seq_puts(m, "init2\n");
+		break;
+	case SVSB_PHASE_MON:
+		seq_puts(m, "mon mode\n");
+		break;
+	default:
+		seq_puts(m, "unknown\n");
+		break;
+	}
+
+	return 0;
+}
+
+static ssize_t svs_enable_debug_write(struct file *filp,
+				      const char __user *buffer,
+				      size_t count, loff_t *pos)
+{
+	struct svs_bank *svsb = file_inode(filp)->i_private;
+	struct svs_platform *svsp = dev_get_drvdata(svsb->dev);
+	unsigned long flags;
+	int enabled, ret;
+	char *buf = NULL;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+
+	buf = (char *)memdup_user_nul(buffer, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	ret = kstrtoint(buf, 10, &enabled);
+	if (ret)
+		return ret;
+
+	if (!enabled) {
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svsb->mode_support = SVSB_MODE_ALL_DISABLE;
+		svs_switch_bank(svsp);
+		svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
+		svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
+		spin_unlock_irqrestore(&svs_lock, flags);
+
+		svsb->phase = SVSB_PHASE_ERROR;
+		svs_adjust_pm_opp_volts(svsb);
+	}
+
+	kfree(buf);
+
+	return count;
+}
+
+debug_fops_rw(enable);
+
+static int svs_status_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+	struct dev_pm_opp *opp;
+	int tzone_temp = 0, ret;
+	u32 i;
+
+	ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
+	if (ret)
+		seq_printf(m, "%s: temperature ignore\n", svsb->name);
+	else
+		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
+						 svsb->opp_dfreq[i], true);
+		if (IS_ERR(opp)) {
+			seq_printf(m, "%s: cannot find freq = %u (%ld)\n",
+				   svsb->name, svsb->opp_dfreq[i],
+				   PTR_ERR(opp));
+			return PTR_ERR(opp);
+		}
+
+		seq_printf(m, "opp_freq[%02u]: %u, opp_volt[%02u]: %lu, ",
+			   i, svsb->opp_dfreq[i], i,
+			   dev_pm_opp_get_voltage(opp));
+		seq_printf(m, "svsb_volt[%02u]: 0x%x, freq_pct[%02u]: %u\n",
+			   i, svsb->volt[i], i, svsb->freq_pct[i]);
+		dev_pm_opp_put(opp);
+	}
+
+	return 0;
+}
+
+debug_fops_ro(status);
+
+static int svs_voffset_debug_show(struct seq_file *m, void *v)
+{
+	struct svs_bank *svsb = (struct svs_bank *)m->private;
+
+	seq_printf(m, "%d\n", svsb->voffset);
+
+	return 0;
+}
+
+static ssize_t svs_voffset_debug_write(struct file *filp,
+				       const char __user *buffer,
+				       size_t count, loff_t *pos)
+{
+	struct svs_bank *svsb = file_inode(filp)->i_private;
+	char *buf = NULL;
+	s32 voffset;
+
+	if (count >= PAGE_SIZE)
+		return -EINVAL;
+
+	buf = (char *)memdup_user_nul(buffer, count);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	if (!kstrtoint(buf, 10, &voffset)) {
+		svsb->voffset = voffset;
+		svs_adjust_pm_opp_volts(svsb);
+	}
+
+	kfree(buf);
+
+	return count;
+}
+
+debug_fops_rw(voffset);
+
+static int svs_create_debug_cmds(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct dentry *svs_dir, *svsb_dir, *file_entry;
+	const char *d = "/sys/kernel/debug/svs";
+	u32 i, idx;
+
+	struct svs_dentry {
+		const char *name;
+		const struct file_operations *fops;
+	};
+
+	struct svs_dentry svs_entries[] = {
+		svs_dentry_data(dump),
+	};
+
+	struct svs_dentry svsb_entries[] = {
+		svs_dentry_data(enable),
+		svs_dentry_data(status),
+		svs_dentry_data(voffset),
+	};
+
+	svs_dir = debugfs_create_dir("svs", NULL);
+	if (IS_ERR(svs_dir)) {
+		dev_err(svsp->dev, "cannot create %s: %ld\n",
+			d, PTR_ERR(svs_dir));
+		return PTR_ERR(svs_dir);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(svs_entries); i++) {
+		file_entry = debugfs_create_file(svs_entries[i].name, 0664,
+						 svs_dir, svsp,
+						 svs_entries[i].fops);
+		if (IS_ERR(file_entry)) {
+			dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
+				d, svs_entries[i].name, PTR_ERR(file_entry));
+			return PTR_ERR(file_entry);
+		}
+	}
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->mode_support == SVSB_MODE_ALL_DISABLE)
+			continue;
+
+		svsb_dir = debugfs_create_dir(svsb->name, svs_dir);
+		if (IS_ERR(svsb_dir)) {
+			dev_err(svsp->dev, "cannot create %s/%s: %ld\n",
+				d, svsb->name, PTR_ERR(svsb_dir));
+			return PTR_ERR(svsb_dir);
+		}
+
+		for (i = 0; i < ARRAY_SIZE(svsb_entries); i++) {
+			file_entry = debugfs_create_file(svsb_entries[i].name,
+							 0664, svsb_dir, svsb,
+							 svsb_entries[i].fops);
+			if (IS_ERR(file_entry)) {
+				dev_err(svsp->dev, "no %s/%s/%s?: %ld\n",
+					d, svsb->name, svsb_entries[i].name,
+					PTR_ERR(file_entry));
+				return PTR_ERR(file_entry);
+			}
+		}
+	}
+
+	return 0;
+}
+
 static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
 {
 	u32 vx;
@@ -594,6 +885,16 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 	}
 }
 
+static inline void svs_save_bank_register_data(struct svs_platform *svsp,
+					       enum svsb_phase phase)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	enum svs_reg_index rg_i;
+
+	for (rg_i = DESCHAR; rg_i < SVS_REG_MAX; rg_i++)
+		svsb->reg_data[phase][rg_i] = svs_readl_relaxed(svsp, rg_i);
+}
+
 static inline void svs_error_isr_handler(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
@@ -608,6 +909,8 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
 		svs_readl_relaxed(svsp, SMSTATE1));
 	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_ERROR);
+
 	svsb->phase = SVSB_PHASE_ERROR;
 	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
 	svs_writel_relaxed(svsp, SVSB_INTSTS_CLEAN, INTSTS);
@@ -622,6 +925,8 @@ static inline void svs_init01_isr_handler(struct svs_platform *svsp)
 		 svs_readl_relaxed(svsp, VDESIGN30),
 		 svs_readl_relaxed(svsp, DCVALUES));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT01);
+
 	svsb->phase = SVSB_PHASE_INIT01;
 	svsb->dc_voffset_in = ~(svs_readl_relaxed(svsp, DCVALUES) &
 				GENMASK(15, 0)) + 1;
@@ -647,6 +952,8 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp)
 		 svs_readl_relaxed(svsp, VOP30),
 		 svs_readl_relaxed(svsp, DCVALUES));
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_INIT02);
+
 	svsb->phase = SVSB_PHASE_INIT02;
 	svsb->get_volts(svsp);
 
@@ -658,6 +965,8 @@ static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
 
+	svs_save_bank_register_data(svsp, SVSB_PHASE_MON);
+
 	svsb->phase = SVSB_PHASE_MON;
 	svsb->get_volts(svsp);
 
@@ -1634,6 +1943,12 @@ static int svs_probe(struct platform_device *pdev)
 		goto svs_probe_iounmap;
 	}
 
+	ret = svs_create_debug_cmds(svsp);
+	if (ret) {
+		dev_err(svsp->dev, "svs create debug cmds fail: %d\n", ret);
+		goto svs_probe_iounmap;
+	}
+
 	return 0;
 
 svs_probe_iounmap:
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:53 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:53 +0800
Subject: [PATCH v22 4/7] soc: mediatek: SVS: add monitor mode
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-5-roger.lu@mediatek.com>

SVS monitor mode is based on different thermal temperature
to provide suitable SVS bank voltages.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 253 ++++++++++++++++++++++++++++++++-
 1 file changed, 247 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index 2d7ea3d607c4..be53470d439c 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -25,6 +25,7 @@
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/thermal.h>
 
 /* svs bank 1-line software id */
 #define SVSB_CPU_LITTLE			BIT(0)
@@ -36,6 +37,7 @@
 #define SVSB_MODE_ALL_DISABLE		0
 #define SVSB_MODE_INIT01		BIT(1)
 #define SVSB_MODE_INIT02		BIT(2)
+#define SVSB_MODE_MON			BIT(3)
 
 /* svs bank volt flags */
 #define SVSB_INIT01_PD_REQ		BIT(0)
@@ -49,16 +51,21 @@
 #define SVSB_DTLO			0xfe
 #define SVSB_EN_INIT01			0x1
 #define SVSB_EN_INIT02			0x5
+#define SVSB_EN_MON			0x2
 #define SVSB_EN_OFF			0x0
 #define SVSB_INTEN_INIT0x		0x00005f01
+#define SVSB_INTEN_MONVOPEN		0x00ff0000
 #define SVSB_INTSTS_CLEAN		0x00ffffff
 #define SVSB_INTSTS_COMPLETE		0x1
+#define SVSB_INTSTS_MONVOP		0x00ff0000
 #define SVSB_RUNCONFIG_DEFAULT		0x80000000
 
 /* svs bank related setting */
 #define MAX_OPP_ENTRIES			16
 #define SVSB_DC_SIGNED_BIT		BIT(15)
 #define SVSB_DET_CLK_EN			BIT(31)
+#define SVSB_TEMP_LOWER_BOUND		0xb2
+#define SVSB_TEMP_UPPER_BOUND		0x64
 
 static DEFINE_SPINLOCK(svs_lock);
 
@@ -67,6 +74,7 @@ static DEFINE_SPINLOCK(svs_lock);
  * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
  * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
  * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
+ * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
  * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
  *
  * Each svs bank has its own independent phase and we enable each svs bank by
@@ -74,12 +82,13 @@ static DEFINE_SPINLOCK(svs_lock);
  * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
  *
  * svs bank general phase-enabled order:
- * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02
+ * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
  */
 enum svsb_phase {
 	SVSB_PHASE_ERROR = 0,
 	SVSB_PHASE_INIT01,
 	SVSB_PHASE_INIT02,
+	SVSB_PHASE_MON,
 	SVSB_PHASE_MAX,
 };
 
@@ -210,9 +219,11 @@ static const u32 svs_regs_v2[] = {
  * @probe: svs platform probe function pointer
  * @irqflags: svs platform irq settings flags
  * @efuse_max: total number of svs efuse
+ * @tefuse_max: total number of thermal efuse
  * @regs: svs platform registers map
  * @bank_max: total number of svs banks
  * @efuse: svs efuse data received from NVMEM framework
+ * @tefuse: thermal efuse data received from NVMEM framework
  */
 struct svs_platform {
 	char *name;
@@ -225,9 +236,11 @@ struct svs_platform {
 	int (*probe)(struct svs_platform *svsp);
 	unsigned long irqflags;
 	size_t efuse_max;
+	size_t tefuse_max;
 	const u32 *regs;
 	u32 bank_max;
 	u32 *efuse;
+	u32 *tefuse;
 };
 
 struct svs_platform_data {
@@ -247,11 +260,13 @@ struct svs_platform_data {
  * @pd_dev: power domain device for SoC mtcmos control
  * @init_completion: the timeout completion for bank init
  * @buck: regulator used by opp_dev
+ * @tzd: thermal zone device for getting temperature
  * @lock: mutex lock to protect voltage update process
  * @set_freq_pct: function pointer to set bank frequency percent table
  * @get_volts: function pointer to get bank voltages
  * @name: bank name
  * @buck_name: regulator name
+ * @tzone_name: thermal zone name
  * @phase: bank current phase
  * @volt_od: bank voltage overdrive
  * @pm_runtime_enabled_count: bank pm runtime enabled count
@@ -280,6 +295,13 @@ struct svs_platform_data {
  * @sw_id: bank software identification
  * @cpu_id: cpu core id for SVS CPU bank use only
  * @ctl0: TS-x selection
+ * @temp: bank temperature
+ * @tzone_htemp: thermal zone high temperature threshold
+ * @tzone_htemp_voffset: thermal zone high temperature voltage offset
+ * @tzone_ltemp: thermal zone low temperature threshold
+ * @tzone_ltemp_voffset: thermal zone low temperature voltage offset
+ * @bts: svs efuse data
+ * @mts: svs efuse data
  * @bdes: svs efuse data
  * @mdes: svs efuse data
  * @mtdes: svs efuse data
@@ -297,11 +319,13 @@ struct svs_bank {
 	struct device *pd_dev;
 	struct completion init_completion;
 	struct regulator *buck;
+	struct thermal_zone_device *tzd;
 	struct mutex lock;	/* lock to protect voltage update process */
 	void (*set_freq_pct)(struct svs_platform *svsp);
 	void (*get_volts)(struct svs_platform *svsp);
 	char *name;
 	char *buck_name;
+	char *tzone_name;
 	enum svsb_phase phase;
 	s32 volt_od;
 	u32 pm_runtime_enabled_count;
@@ -330,6 +354,13 @@ struct svs_bank {
 	u32 sw_id;
 	u32 cpu_id;
 	u32 ctl0;
+	u32 temp;
+	u32 tzone_htemp;
+	u32 tzone_htemp_voffset;
+	u32 tzone_ltemp;
+	u32 tzone_ltemp_voffset;
+	u32 bts;
+	u32 mts;
 	u32 bdes;
 	u32 mdes;
 	u32 mtdes;
@@ -372,11 +403,27 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
 
 static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 {
-	int ret = -EPERM;
-	u32 i, svsb_volt, opp_volt;
+	int ret = -EPERM, tzone_temp = 0;
+	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
 
 	mutex_lock(&svsb->lock);
 
+	/* Get thermal effect */
+	if (svsb->phase == SVSB_PHASE_MON) {
+		ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
+		if (ret || (svsb->temp > SVSB_TEMP_UPPER_BOUND &&
+			    svsb->temp < SVSB_TEMP_LOWER_BOUND)) {
+			dev_err(svsb->dev, "%s: %d (0x%x), run default volts\n",
+				svsb->tzone_name, ret, svsb->temp);
+			svsb->phase = SVSB_PHASE_ERROR;
+		}
+
+		if (tzone_temp >= svsb->tzone_htemp)
+			temp_voffset += svsb->tzone_htemp_voffset;
+		else if (tzone_temp <= svsb->tzone_ltemp)
+			temp_voffset += svsb->tzone_ltemp_voffset;
+	}
+
 	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
 	for (i = 0; i < svsb->opp_count; i++) {
 		switch (svsb->phase) {
@@ -392,6 +439,13 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 							     svsb->volt_step,
 							     svsb->volt_base);
 			break;
+		case SVSB_PHASE_MON:
+			svsb_volt = max(svsb->volt[i] + temp_voffset,
+					svsb->vmin);
+			opp_volt = svs_bank_volt_to_opp_volt(svsb_volt,
+							     svsb->volt_step,
+							     svsb->volt_base);
+			break;
 		default:
 			dev_err(svsb->dev, "unknown phase: %u\n", svsb->phase);
 			ret = -EINVAL;
@@ -486,7 +540,7 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 			       enum svsb_phase target_phase)
 {
 	struct svs_bank *svsb = svsp->pbank;
-	u32 des_char, temp_char, det_char, limit_vals, init2vals;
+	u32 des_char, temp_char, det_char, limit_vals, init2vals, ts_calcs;
 
 	svs_switch_bank(svsp);
 
@@ -527,6 +581,12 @@ static void svs_set_bank_phase(struct svs_platform *svsp,
 		svs_writel_relaxed(svsp, init2vals, INIT2VALS);
 		svs_writel_relaxed(svsp, SVSB_EN_INIT02, SVSEN);
 		break;
+	case SVSB_PHASE_MON:
+		ts_calcs = (svsb->bts << 12) | svsb->mts;
+		svs_writel_relaxed(svsp, ts_calcs, TSCALCS);
+		svs_writel_relaxed(svsp, SVSB_INTEN_MONVOPEN, INTEN);
+		svs_writel_relaxed(svsp, SVSB_EN_MON, SVSEN);
+		break;
 	default:
 		dev_err(svsb->dev, "requested unknown target phase: %u\n",
 			target_phase);
@@ -546,6 +606,7 @@ static inline void svs_error_isr_handler(struct svs_platform *svsp)
 	dev_err(svsb->dev, "SMSTATE0 = 0x%08x, SMSTATE1 = 0x%08x\n",
 		svs_readl_relaxed(svsp, SMSTATE0),
 		svs_readl_relaxed(svsp, SMSTATE1));
+	dev_err(svsb->dev, "TEMP = 0x%08x\n", svs_readl_relaxed(svsp, TEMP));
 
 	svsb->phase = SVSB_PHASE_ERROR;
 	svs_writel_relaxed(svsp, SVSB_EN_OFF, SVSEN);
@@ -593,6 +654,17 @@ static inline void svs_init02_isr_handler(struct svs_platform *svsp)
 	svs_writel_relaxed(svsp, SVSB_INTSTS_COMPLETE, INTSTS);
 }
 
+static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+
+	svsb->phase = SVSB_PHASE_MON;
+	svsb->get_volts(svsp);
+
+	svsb->temp = svs_readl_relaxed(svsp, TEMP) & GENMASK(7, 0);
+	svs_writel_relaxed(svsp, SVSB_INTSTS_MONVOP, INTSTS);
+}
+
 static irqreturn_t svs_isr(int irq, void *data)
 {
 	struct svs_platform *svsp = data;
@@ -623,6 +695,8 @@ static irqreturn_t svs_isr(int irq, void *data)
 		else if (int_sts == SVSB_INTSTS_COMPLETE &&
 			 svs_en == SVSB_EN_INIT02)
 			svs_init02_isr_handler(svsp);
+		else if (int_sts & SVSB_INTSTS_MONVOP)
+			svs_mon_mode_isr_handler(svsp);
 		else
 			svs_error_isr_handler(svsp);
 
@@ -843,6 +917,25 @@ static int svs_init02(struct svs_platform *svsp)
 	return 0;
 }
 
+static void svs_mon_mode(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	unsigned long flags;
+	u32 idx;
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_MON))
+			continue;
+
+		spin_lock_irqsave(&svs_lock, flags);
+		svsp->pbank = svsb;
+		svs_set_bank_phase(svsp, SVSB_PHASE_MON);
+		spin_unlock_irqrestore(&svs_lock, flags);
+	}
+}
+
 static int svs_start(struct svs_platform *svsp)
 {
 	int ret;
@@ -855,6 +948,8 @@ static int svs_start(struct svs_platform *svsp)
 	if (ret)
 		return ret;
 
+	svs_mon_mode(svsp);
+
 	return 0;
 }
 
@@ -900,6 +995,8 @@ static int svs_resume(struct device *dev)
 	if (ret)
 		return ret;
 
+	svs_mon_mode(svsp);
+
 	return 0;
 }
 
@@ -964,6 +1061,15 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 			}
 		}
 
+		if (svsb->mode_support & SVSB_MODE_MON) {
+			svsb->tzd = thermal_zone_get_zone_by_name(svsb->tzone_name);
+			if (IS_ERR(svsb->tzd)) {
+				dev_err(svsb->dev, "cannot get \"%s\" thermal zone\n",
+					svsb->tzone_name);
+				return PTR_ERR(svsb->tzd);
+			}
+		}
+
 		count = dev_pm_opp_get_opp_count(svsb->opp_dev);
 		if (svsb->opp_count != count) {
 			dev_err(svsb->dev,
@@ -994,7 +1100,11 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb;
-	u32 idx, i, ft_pgm;
+	struct nvmem_cell *cell;
+	int format[6], x_roomt[6], o_vtsmcu[5], o_vtsabb, tb_roomt = 0;
+	int adc_ge_t, adc_oe_t, ge, oe, gain, degc_cali, adc_cali_en_t;
+	int o_slope, o_slope_sign, ts_id;
+	u32 idx, i, ft_pgm, mts, temp0, temp1, temp2;
 
 	for (i = 0; i < svsp->efuse_max; i++)
 		if (svsp->efuse[i])
@@ -1070,6 +1180,126 @@ static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 		}
 	}
 
+	/* Get thermal efuse by nvmem */
+	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
+	if (IS_ERR(cell)) {
+		dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max);
+	if (IS_ERR(svsp->tefuse)) {
+		dev_err(svsp->dev, "cannot read thermal efuse: %ld\n",
+			PTR_ERR(svsp->tefuse));
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	svsp->tefuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	/* Thermal efuse parsing */
+	adc_ge_t = (svsp->tefuse[1] >> 22) & GENMASK(9, 0);
+	adc_oe_t = (svsp->tefuse[1] >> 12) & GENMASK(9, 0);
+
+	o_vtsmcu[0] = (svsp->tefuse[0] >> 17) & GENMASK(8, 0);
+	o_vtsmcu[1] = (svsp->tefuse[0] >> 8) & GENMASK(8, 0);
+	o_vtsmcu[2] = svsp->tefuse[1] & GENMASK(8, 0);
+	o_vtsmcu[3] = (svsp->tefuse[2] >> 23) & GENMASK(8, 0);
+	o_vtsmcu[4] = (svsp->tefuse[2] >> 5) & GENMASK(8, 0);
+	o_vtsabb = (svsp->tefuse[2] >> 14) & GENMASK(8, 0);
+
+	degc_cali = (svsp->tefuse[0] >> 1) & GENMASK(5, 0);
+	adc_cali_en_t = svsp->tefuse[0] & BIT(0);
+	o_slope_sign = (svsp->tefuse[0] >> 7) & BIT(0);
+
+	ts_id = (svsp->tefuse[1] >> 9) & BIT(0);
+	o_slope = (svsp->tefuse[0] >> 26) & GENMASK(5, 0);
+
+	if (adc_cali_en_t == 1) {
+		if (!ts_id)
+			o_slope = 0;
+
+		if (adc_ge_t < 265 || adc_ge_t > 758 ||
+		    adc_oe_t < 265 || adc_oe_t > 758 ||
+		    o_vtsmcu[0] < -8 || o_vtsmcu[0] > 484 ||
+		    o_vtsmcu[1] < -8 || o_vtsmcu[1] > 484 ||
+		    o_vtsmcu[2] < -8 || o_vtsmcu[2] > 484 ||
+		    o_vtsmcu[3] < -8 || o_vtsmcu[3] > 484 ||
+		    o_vtsmcu[4] < -8 || o_vtsmcu[4] > 484 ||
+		    o_vtsabb < -8 || o_vtsabb > 484 ||
+		    degc_cali < 1 || degc_cali > 63) {
+			dev_err(svsp->dev, "bad thermal efuse, no mon mode\n");
+			goto remove_mt8183_svsb_mon_mode;
+		}
+	} else {
+		dev_err(svsp->dev, "no thermal efuse, no mon mode\n");
+		goto remove_mt8183_svsb_mon_mode;
+	}
+
+	ge = ((adc_ge_t - 512) * 10000) / 4096;
+	oe = (adc_oe_t - 512);
+	gain = (10000 + ge);
+
+	format[0] = (o_vtsmcu[0] + 3350 - oe);
+	format[1] = (o_vtsmcu[1] + 3350 - oe);
+	format[2] = (o_vtsmcu[2] + 3350 - oe);
+	format[3] = (o_vtsmcu[3] + 3350 - oe);
+	format[4] = (o_vtsmcu[4] + 3350 - oe);
+	format[5] = (o_vtsabb + 3350 - oe);
+
+	for (i = 0; i < 6; i++)
+		x_roomt[i] = (((format[i] * 10000) / 4096) * 10000) / gain;
+
+	temp0 = (10000 * 100000 / gain) * 15 / 18;
+
+	if (!o_slope_sign)
+		mts = (temp0 * 10) / (1534 + o_slope * 10);
+	else
+		mts = (temp0 * 10) / (1534 - o_slope * 10);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mts = mts;
+
+		switch (svsb->sw_id) {
+		case SVSB_CPU_LITTLE:
+			tb_roomt = x_roomt[3];
+			break;
+		case SVSB_CPU_BIG:
+			tb_roomt = x_roomt[4];
+			break;
+		case SVSB_CCI:
+			tb_roomt = x_roomt[3];
+			break;
+		case SVSB_GPU:
+			tb_roomt = x_roomt[1];
+			break;
+		default:
+			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
+			goto remove_mt8183_svsb_mon_mode;
+		}
+
+		temp0 = (degc_cali * 10 / 2);
+		temp1 = ((10000 * 100000 / 4096 / gain) *
+			 oe + tb_roomt * 10) * 15 / 18;
+
+		if (!o_slope_sign)
+			temp2 = temp1 * 100 / (1534 + o_slope * 10);
+		else
+			temp2 = temp1 * 100 / (1534 - o_slope * 10);
+
+		svsb->bts = (temp0 + temp2 - 250) * 4 / 10;
+	}
+
+	return true;
+
+remove_mt8183_svsb_mon_mode:
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mode_support &= ~SVSB_MODE_MON;
+	}
+
 	return true;
 }
 
@@ -1152,9 +1382,14 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
 
 static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 {
+	struct device *dev;
 	struct svs_bank *svsb;
 	u32 idx;
 
+	dev = svs_add_device_link(svsp, "thermal");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
 	for (idx = 0; idx < svsp->bank_max; idx++) {
 		svsb = &svsp->banks[idx];
 
@@ -1261,9 +1496,11 @@ static struct svs_bank svs_mt8183_banks[] = {
 		.set_freq_pct		= svs_set_bank_freq_pct_v2,
 		.get_volts		= svs_get_bank_volts_v2,
 		.buck_name		= "mali",
+		.tzone_name		= "tzts2",
 		.volt_flags		= SVSB_INIT01_PD_REQ |
 					  SVSB_INIT01_VOLT_INC_ONLY,
-		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02,
+		.mode_support		= SVSB_MODE_INIT01 | SVSB_MODE_INIT02 |
+					  SVSB_MODE_MON,
 		.opp_count		= MAX_OPP_ENTRIES,
 		.freq_base		= 900000000,
 		.vboot			= 0x30,
@@ -1279,6 +1516,10 @@ static struct svs_bank svs_mt8183_banks[] = {
 		.core_sel		= 0x8fff0003,
 		.int_st			= BIT(3),
 		.ctl0			= 0x00050001,
+		.tzone_htemp		= 85000,
+		.tzone_htemp_voffset	= 0,
+		.tzone_ltemp		= 25000,
+		.tzone_ltemp_voffset	= 3,
 	},
 };
 
-- 
2.18.0



From roger.lu at mediatek.com  Wed Jan 26 19:39:56 2022
From: roger.lu at mediatek.com (Roger Lu)
Date: Thu, 27 Jan 2022 11:39:56 +0800
Subject: [PATCH v22 7/7] soc: mediatek: SVS: add mt8192 SVS GPU driver
In-Reply-To: <20220127033956.24585-1-roger.lu@mediatek.com>
References: <20220127033956.24585-1-roger.lu@mediatek.com>
Message-ID: <20220127033956.24585-8-roger.lu@mediatek.com>

mt8192 SVS GPU uses 2-line (high/low bank) HW architecture to provide
bank voltages. High bank helps update higher frequency's voltage
and low bank helps update lower frequency's voltage.

Signed-off-by: Roger Lu <roger.lu at mediatek.com>
---
 drivers/soc/mediatek/mtk-svs.c | 471 ++++++++++++++++++++++++++++++++-
 1 file changed, 466 insertions(+), 5 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-svs.c b/drivers/soc/mediatek/mtk-svs.c
index d3977de56335..54af3b4b90a9 100644
--- a/drivers/soc/mediatek/mtk-svs.c
+++ b/drivers/soc/mediatek/mtk-svs.c
@@ -24,6 +24,7 @@
 #include <linux/pm_qos.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -35,6 +36,10 @@
 #define SVSB_CCI			BIT(2)
 #define SVSB_GPU			BIT(3)
 
+/* svs bank 2-line type */
+#define SVSB_LOW			BIT(8)
+#define SVSB_HIGH			BIT(9)
+
 /* svs bank mode support */
 #define SVSB_MODE_ALL_DISABLE		0
 #define SVSB_MODE_INIT01		BIT(1)
@@ -45,6 +50,8 @@
 #define SVSB_INIT01_PD_REQ		BIT(0)
 #define SVSB_INIT01_VOLT_IGNORE		BIT(1)
 #define SVSB_INIT01_VOLT_INC_ONLY	BIT(2)
+#define SVSB_MON_VOLT_IGNORE		BIT(16)
+#define SVSB_REMOVE_DVTFIXED_VOLT	BIT(24)
 
 /* svs bank register common configuration */
 #define SVSB_DET_MAX			0xffff
@@ -63,7 +70,9 @@
 #define SVSB_RUNCONFIG_DEFAULT		0x80000000
 
 /* svs bank related setting */
+#define BITS8				8
 #define MAX_OPP_ENTRIES			16
+#define REG_BYTES			4
 #define SVSB_DC_SIGNED_BIT		BIT(15)
 #define SVSB_DET_CLK_EN			BIT(31)
 #define SVSB_TEMP_LOWER_BOUND		0xb2
@@ -250,6 +259,7 @@ static const u32 svs_regs_v2[] = {
  * @main_clk: main clock for svs bank
  * @pbank: svs bank pointer needing to be protected by spin_lock section
  * @banks: svs banks that svs platform supports
+ * @rst: svs platform reset control
  * @efuse_parsing: svs platform efuse parsing function pointer
  * @probe: svs platform probe function pointer
  * @irqflags: svs platform irq settings flags
@@ -267,6 +277,7 @@ struct svs_platform {
 	struct clk *main_clk;
 	struct svs_bank *pbank;
 	struct svs_bank *banks;
+	struct reset_control *rst;
 	bool (*efuse_parsing)(struct svs_platform *svsp);
 	int (*probe)(struct svs_platform *svsp);
 	unsigned long irqflags;
@@ -309,6 +320,7 @@ struct svs_platform_data {
  * @pm_runtime_enabled_count: bank pm runtime enabled count
  * @mode_support: bank mode support.
  * @freq_base: reference frequency for bank init
+ * @turn_freq_base: refenrece frequency for turn point
  * @vboot: voltage request for bank init01 only
  * @opp_dfreq: default opp frequency table
  * @opp_dvolt: default opp voltage table
@@ -344,6 +356,8 @@ struct svs_platform_data {
  * @mtdes: svs efuse data
  * @dcbdet: svs efuse data
  * @dcmdet: svs efuse data
+ * @turn_pt: 2-line turn point tells which opp_volt calculated by high/low bank
+ * @type: bank type to represent it is 2-line (high/low) bank or 1-line bank
  *
  * Svs bank will generate suitalbe voltages by below general math equation
  * and provide these voltages to opp voltage table.
@@ -370,6 +384,7 @@ struct svs_bank {
 	u32 pm_runtime_enabled_count;
 	u32 mode_support;
 	u32 freq_base;
+	u32 turn_freq_base;
 	u32 vboot;
 	u32 opp_dfreq[MAX_OPP_ENTRIES];
 	u32 opp_dvolt[MAX_OPP_ENTRIES];
@@ -405,6 +420,8 @@ struct svs_bank {
 	u32 mtdes;
 	u32 dcbdet;
 	u32 dcmdet;
+	u32 turn_pt;
+	u32 type;
 };
 
 static u32 percent(u32 numerator, u32 denominator)
@@ -440,13 +457,59 @@ static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
 	return (svsb_volt * svsb_volt_step) + svsb_volt_base;
 }
 
+static u32 svs_opp_volt_to_bank_volt(u32 opp_u_volt, u32 svsb_volt_step,
+				     u32 svsb_volt_base)
+{
+	return (opp_u_volt - svsb_volt_base) / svsb_volt_step;
+}
+
+static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
+{
+	struct dev_pm_opp *opp;
+	u32 i, opp_u_volt;
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
+						 svsb->opp_dfreq[i],
+						 true);
+		if (IS_ERR(opp)) {
+			dev_err(svsb->dev, "cannot find freq = %u (%ld)\n",
+				svsb->opp_dfreq[i], PTR_ERR(opp));
+			return PTR_ERR(opp);
+		}
+
+		opp_u_volt = dev_pm_opp_get_voltage(opp);
+		svsb->volt[i] = svs_opp_volt_to_bank_volt(opp_u_volt,
+							  svsb->volt_step,
+							  svsb->volt_base);
+		dev_pm_opp_put(opp);
+	}
+
+	return 0;
+}
+
 static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 {
 	int ret = -EPERM, tzone_temp = 0;
-	u32 i, svsb_volt, opp_volt, temp_voffset = 0;
+	u32 i, svsb_volt, opp_volt, temp_voffset = 0, opp_start, opp_stop;
 
 	mutex_lock(&svsb->lock);
 
+	/*
+	 * 2-line bank updates its corresponding opp volts.
+	 * 1-line bank updates all opp volts.
+	 */
+	if (svsb->type == SVSB_HIGH) {
+		opp_start = 0;
+		opp_stop = svsb->turn_pt;
+	} else if (svsb->type == SVSB_LOW) {
+		opp_start = svsb->turn_pt;
+		opp_stop = svsb->opp_count;
+	} else {
+		opp_start = 0;
+		opp_stop = svsb->opp_count;
+	}
+
 	/* Get thermal effect */
 	if (svsb->phase == SVSB_PHASE_MON) {
 		ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
@@ -461,10 +524,16 @@ static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
 			temp_voffset += svsb->tzone_htemp_voffset;
 		else if (tzone_temp <= svsb->tzone_ltemp)
 			temp_voffset += svsb->tzone_ltemp_voffset;
+
+		/* 2-line bank update all opp volts when running mon mode */
+		if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+			opp_start = 0;
+			opp_stop = svsb->opp_count;
+		}
 	}
 
 	/* vmin <= svsb_volt (opp_volt) <= default opp voltage */
-	for (i = 0; i < svsb->opp_count; i++) {
+	for (i = opp_start; i < opp_stop; i++) {
 		switch (svsb->phase) {
 		case SVSB_PHASE_ERROR:
 			opp_volt = svsb->opp_dvolt[i];
@@ -629,9 +698,11 @@ static int svs_status_debug_show(struct seq_file *m, void *v)
 
 	ret = thermal_zone_get_temp(svsb->tzd, &tzone_temp);
 	if (ret)
-		seq_printf(m, "%s: temperature ignore\n", svsb->name);
+		seq_printf(m, "%s: temperature ignore, turn_pt = %u\n",
+			   svsb->name, svsb->turn_pt);
 	else
-		seq_printf(m, "%s: temperature = %d\n", svsb->name, tzone_temp);
+		seq_printf(m, "%s: temperature = %d, turn_pt = %u\n",
+			   svsb->name, tzone_temp, svsb->turn_pt);
 
 	for (i = 0; i < svsb->opp_count; i++) {
 		opp = dev_pm_opp_find_freq_exact(svsb->opp_dev,
@@ -774,6 +845,181 @@ static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
 	return DIV_ROUND_UP(vx, 100);
 }
 
+static void svs_get_bank_volts_v3(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 i, j, *vop, vop74, vop30, turn_pt = svsb->turn_pt;
+	u32 b_sft, shift_byte = 0, opp_start = 0, opp_stop = 0;
+	u32 middle_index = (svsb->opp_count / 2);
+
+	if (svsb->phase == SVSB_PHASE_MON &&
+	    svsb->volt_flags & SVSB_MON_VOLT_IGNORE)
+		return;
+
+	vop74 = svs_readl_relaxed(svsp, VOP74);
+	vop30 = svs_readl_relaxed(svsp, VOP30);
+
+	/* Target is to set svsb->volt[] by algorithm */
+	if (turn_pt < middle_index) {
+		if (svsb->type == SVSB_HIGH) {
+			/* volt[0] ~ volt[turn_pt - 1] */
+			for (i = 0; i < turn_pt; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				vop = (shift_byte < REG_BYTES) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/* volt[turn_pt] + volt[j] ~ volt[opp_count - 1] */
+			j = svsb->opp_count - 7;
+			svsb->volt[turn_pt] = vop30 & GENMASK(7, 0);
+			shift_byte++;
+			for (i = j; i < svsb->opp_count; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				vop = (shift_byte < REG_BYTES) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
+				shift_byte++;
+			}
+
+			/* volt[turn_pt + 1] ~ volt[j - 1] by interpolate */
+			for (i = turn_pt + 1; i < j; i++)
+				svsb->volt[i] = interpolate(svsb->freq_pct[turn_pt],
+							    svsb->freq_pct[j],
+							    svsb->volt[turn_pt],
+							    svsb->volt[j],
+							    svsb->freq_pct[i]);
+		}
+	} else {
+		if (svsb->type == SVSB_HIGH) {
+			/* volt[0] + volt[j] ~ volt[turn_pt - 1] */
+			j = turn_pt - 7;
+			svsb->volt[0] = vop30 & GENMASK(7, 0);
+			shift_byte++;
+			for (i = j; i < turn_pt; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				vop = (shift_byte < REG_BYTES) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
+				shift_byte++;
+			}
+
+			/* volt[1] ~ volt[j - 1] by interpolate */
+			for (i = 1; i < j; i++)
+				svsb->volt[i] = interpolate(svsb->freq_pct[0],
+							    svsb->freq_pct[j],
+							    svsb->volt[0],
+							    svsb->volt[j],
+							    svsb->freq_pct[i]);
+		} else if (svsb->type == SVSB_LOW) {
+			/* volt[turn_pt] ~ volt[opp_count - 1] */
+			for (i = turn_pt; i < svsb->opp_count; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				vop = (shift_byte < REG_BYTES) ? &vop30 :
+								 &vop74;
+				svsb->volt[i] = (*vop >> b_sft) & GENMASK(7, 0);
+				shift_byte++;
+			}
+		}
+	}
+
+	if (svsb->type == SVSB_HIGH) {
+		opp_start = 0;
+		opp_stop = svsb->turn_pt;
+	} else if (svsb->type == SVSB_LOW) {
+		opp_start = svsb->turn_pt;
+		opp_stop = svsb->opp_count;
+	}
+
+	for (i = opp_start; i < opp_stop; i++)
+		if (svsb->volt_flags & SVSB_REMOVE_DVTFIXED_VOLT)
+			svsb->volt[i] -= svsb->dvt_fixed;
+}
+
+static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb = svsp->pbank;
+	u32 i, j, *freq_pct, freq_pct74 = 0, freq_pct30 = 0;
+	u32 b_sft, shift_byte = 0, turn_pt;
+	u32 middle_index = (svsb->opp_count / 2);
+
+	for (i = 0; i < svsb->opp_count; i++) {
+		if (svsb->opp_dfreq[i] <= svsb->turn_freq_base) {
+			svsb->turn_pt = i;
+			break;
+		}
+	}
+
+	turn_pt = svsb->turn_pt;
+
+	/* Target is to fill out freq_pct74 / freq_pct30 by algorithm */
+	if (turn_pt < middle_index) {
+		if (svsb->type == SVSB_HIGH) {
+			/*
+			 * If we don't handle this situation,
+			 * SVSB_HIGH's FREQPCT74 / FREQPCT30 would keep "0"
+			 * and this leads SVSB_LOW to work abnormally.
+			 */
+			if (turn_pt == 0)
+				freq_pct30 = svsb->freq_pct[0];
+
+			/* freq_pct[0] ~ freq_pct[turn_pt - 1] */
+			for (i = 0; i < turn_pt; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				freq_pct = (shift_byte < REG_BYTES) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/*
+			 * freq_pct[turn_pt] +
+			 * freq_pct[opp_count - 7] ~ freq_pct[opp_count -1]
+			 */
+			freq_pct30 = svsb->freq_pct[turn_pt];
+			shift_byte++;
+			j = svsb->opp_count - 7;
+			for (i = j; i < svsb->opp_count; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				freq_pct = (shift_byte < REG_BYTES) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		}
+	} else {
+		if (svsb->type == SVSB_HIGH) {
+			/*
+			 * freq_pct[0] +
+			 * freq_pct[turn_pt - 7] ~ freq_pct[turn_pt - 1]
+			 */
+			freq_pct30 = svsb->freq_pct[0];
+			shift_byte++;
+			j = turn_pt - 7;
+			for (i = j; i < turn_pt; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				freq_pct = (shift_byte < REG_BYTES) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		} else if (svsb->type == SVSB_LOW) {
+			/* freq_pct[turn_pt] ~ freq_pct[opp_count - 1] */
+			for (i = turn_pt; i < svsb->opp_count; i++) {
+				b_sft = BITS8 * (shift_byte % REG_BYTES);
+				freq_pct = (shift_byte < REG_BYTES) ?
+					   &freq_pct30 : &freq_pct74;
+				*freq_pct |= (svsb->freq_pct[i] << b_sft);
+				shift_byte++;
+			}
+		}
+	}
+
+	svs_writel_relaxed(svsp, freq_pct74, FREQPCT74);
+	svs_writel_relaxed(svsp, freq_pct30, FREQPCT30);
+}
+
 static void svs_get_bank_volts_v2(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb = svsp->pbank;
@@ -1223,6 +1469,25 @@ static int svs_init02(struct svs_platform *svsp)
 		}
 	}
 
+	/*
+	 * 2-line high/low bank update its corresponding opp voltages only.
+	 * Therefore, we sync voltages from opp for high/low bank voltages
+	 * consistency.
+	 */
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (!(svsb->mode_support & SVSB_MODE_INIT02))
+			continue;
+
+		if (svsb->type == SVSB_HIGH || svsb->type == SVSB_LOW) {
+			if (svs_sync_bank_volts_from_opp(svsb)) {
+				dev_err(svsb->dev, "sync volt fail\n");
+				return -EPERM;
+			}
+		}
+	}
+
 	return 0;
 }
 
@@ -1267,6 +1532,7 @@ static int svs_suspend(struct device *dev)
 	struct svs_platform *svsp = dev_get_drvdata(dev);
 	struct svs_bank *svsb;
 	unsigned long flags;
+	int ret;
 	u32 idx;
 
 	for (idx = 0; idx < svsp->bank_max; idx++) {
@@ -1284,6 +1550,12 @@ static int svs_suspend(struct device *dev)
 		svs_adjust_pm_opp_volts(svsb);
 	}
 
+	ret = reset_control_assert(svsp->rst);
+	if (ret) {
+		dev_err(svsp->dev, "cannot assert reset %d\n", ret);
+		return ret;
+	}
+
 	clk_disable_unprepare(svsp->main_clk);
 
 	return 0;
@@ -1300,6 +1572,12 @@ static int svs_resume(struct device *dev)
 		return ret;
 	}
 
+	ret = reset_control_deassert(svsp->rst);
+	if (ret) {
+		dev_err(svsp->dev, "cannot deassert reset %d\n", ret);
+		return ret;
+	}
+
 	ret = svs_init02(svsp);
 	if (ret)
 		return ret;
@@ -1333,7 +1611,12 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 			svsb->name = "SVSB_CCI";
 			break;
 		case SVSB_GPU:
-			svsb->name = "SVSB_GPU";
+			if (svsb->type == SVSB_HIGH)
+				svsb->name = "SVSB_GPU_HIGH";
+			else if (svsb->type == SVSB_LOW)
+				svsb->name = "SVSB_GPU_LOW";
+			else
+				svsb->name = "SVSB_GPU";
 			break;
 		default:
 			dev_err(svsb->dev, "unknown sw_id: %u\n", svsb->sw_id);
@@ -1406,6 +1689,84 @@ static int svs_bank_resource_setup(struct svs_platform *svsp)
 	return 0;
 }
 
+static bool svs_mt8192_efuse_parsing(struct svs_platform *svsp)
+{
+	struct svs_bank *svsb;
+	struct nvmem_cell *cell;
+	u32 idx, i, vmin, golden_temp;
+
+	for (i = 0; i < svsp->efuse_max; i++)
+		if (svsp->efuse[i])
+			dev_info(svsp->dev, "M_HW_RES%d: 0x%08x\n",
+				 i, svsp->efuse[i]);
+
+	if (!svsp->efuse[9]) {
+		dev_notice(svsp->dev, "svs_efuse[9] = 0x0?\n");
+		return false;
+	}
+
+	/* Svs efuse parsing */
+	vmin = (svsp->efuse[19] >> 4) & GENMASK(1, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (vmin == 0x1)
+			svsb->vmin = 0x1e;
+
+		if (svsb->type == SVSB_LOW) {
+			svsb->mtdes = svsp->efuse[10] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[10] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[10] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[17]) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[17] >> 8) & GENMASK(7, 0);
+		} else if (svsb->type == SVSB_HIGH) {
+			svsb->mtdes = svsp->efuse[9] & GENMASK(7, 0);
+			svsb->bdes = (svsp->efuse[9] >> 16) & GENMASK(7, 0);
+			svsb->mdes = (svsp->efuse[9] >> 24) & GENMASK(7, 0);
+			svsb->dcbdet = (svsp->efuse[17] >> 16) & GENMASK(7, 0);
+			svsb->dcmdet = (svsp->efuse[17] >> 24) & GENMASK(7, 0);
+		}
+
+		svsb->vmax += svsb->dvt_fixed;
+	}
+
+	/* Thermal efuse parsing */
+	cell = nvmem_cell_get(svsp->dev, "t-calibration-data");
+	if (IS_ERR_OR_NULL(cell)) {
+		dev_err(svsp->dev, "no \"t-calibration-data\"? %ld\n",
+			PTR_ERR(cell));
+		return false;
+	}
+
+	svsp->tefuse = nvmem_cell_read(cell, &svsp->tefuse_max);
+	if (IS_ERR(svsp->tefuse)) {
+		dev_err(svsp->dev, "cannot read thermal efuse: %ld\n",
+			PTR_ERR(svsp->tefuse));
+		return false;
+	}
+
+	svsp->tefuse_max /= sizeof(u32);
+	nvmem_cell_put(cell);
+
+	for (i = 0; i < svsp->tefuse_max; i++)
+		if (svsp->tefuse[i] != 0)
+			break;
+
+	if (i == svsp->tefuse_max)
+		golden_temp = 50; /* All thermal efuse data are 0 */
+	else
+		golden_temp = (svsp->tefuse[0] >> 24) & GENMASK(7, 0);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+		svsb->mts = 500;
+		svsb->bts = (((500 * golden_temp + 250460) / 1000) - 25) * 4;
+	}
+
+	return true;
+}
+
 static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp)
 {
 	struct svs_bank *svsb;
@@ -1689,6 +2050,38 @@ static struct device *svs_add_device_link(struct svs_platform *svsp,
 	return dev;
 }
 
+static int svs_mt8192_platform_probe(struct svs_platform *svsp)
+{
+	struct device *dev;
+	struct svs_bank *svsb;
+	u32 idx;
+
+	svsp->rst = devm_reset_control_get_optional(svsp->dev, "svs_rst");
+	if (IS_ERR(svsp->rst)) {
+		dev_err_probe(svsp->dev, PTR_ERR(svsp->rst),
+			      "cannot get svs reset control\n");
+		return PTR_ERR(svsp->rst);
+	}
+
+	dev = svs_add_device_link(svsp, "lvts");
+	if (IS_ERR(dev))
+		return PTR_ERR(dev);
+
+	for (idx = 0; idx < svsp->bank_max; idx++) {
+		svsb = &svsp->banks[idx];
+
+		if (svsb->type == SVSB_HIGH)
+			svsb->opp_dev = svs_add_device_link(svsp, "mali");
+		else if (svsb->type == SVSB_LOW)
+			svsb->opp_dev = svs_get_subsys_device(svsp, "mali");
+
+		if (IS_ERR(svsb->opp_dev))
+			return PTR_ERR(svsb->opp_dev);
+	}
+
+	return 0;
+}
+
 static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 {
 	struct device *dev;
@@ -1728,6 +2121,61 @@ static int svs_mt8183_platform_probe(struct svs_platform *svsp)
 	return 0;
 }
 
+static struct svs_bank svs_mt8192_banks[] = {
+	{
+		.sw_id			= SVSB_GPU,
+		.type			= SVSB_LOW,
+		.set_freq_pct		= svs_set_bank_freq_pct_v3,
+		.get_volts		= svs_get_bank_volts_v3,
+		.volt_flags		= SVSB_REMOVE_DVTFIXED_VOLT,
+		.mode_support		= SVSB_MODE_INIT02,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 688000000,
+		.turn_freq_base		= 688000000,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.vmax			= 0x60,
+		.vmin			= 0x1a,
+		.age_config		= 0x555555,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x1,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.core_sel		= 0x0fff0100,
+		.int_st			= BIT(0),
+		.ctl0			= 0x00540003,
+	},
+	{
+		.sw_id			= SVSB_GPU,
+		.type			= SVSB_HIGH,
+		.set_freq_pct		= svs_set_bank_freq_pct_v3,
+		.get_volts		= svs_get_bank_volts_v3,
+		.tzone_name		= "gpu1",
+		.volt_flags		= SVSB_REMOVE_DVTFIXED_VOLT |
+					  SVSB_MON_VOLT_IGNORE,
+		.mode_support		= SVSB_MODE_INIT02 | SVSB_MODE_MON,
+		.opp_count		= MAX_OPP_ENTRIES,
+		.freq_base		= 902000000,
+		.turn_freq_base		= 688000000,
+		.volt_step		= 6250,
+		.volt_base		= 400000,
+		.vmax			= 0x60,
+		.vmin			= 0x1a,
+		.age_config		= 0x555555,
+		.dc_config		= 0x1,
+		.dvt_fixed		= 0x6,
+		.vco			= 0x18,
+		.chk_shift		= 0x87,
+		.core_sel		= 0x0fff0101,
+		.int_st			= BIT(1),
+		.ctl0			= 0x00540003,
+		.tzone_htemp		= 85000,
+		.tzone_htemp_voffset	= 0,
+		.tzone_ltemp		= 25000,
+		.tzone_ltemp_voffset	= 7,
+	},
+};
+
 static struct svs_bank svs_mt8183_banks[] = {
 	{
 		.sw_id			= SVSB_CPU_LITTLE,
@@ -1832,6 +2280,16 @@ static struct svs_bank svs_mt8183_banks[] = {
 	},
 };
 
+static const struct svs_platform_data svs_mt8192_platform_data = {
+	.name = "mt8192-svs",
+	.banks = svs_mt8192_banks,
+	.efuse_parsing = svs_mt8192_efuse_parsing,
+	.probe = svs_mt8192_platform_probe,
+	.irqflags = IRQF_TRIGGER_HIGH,
+	.regs = svs_regs_v2,
+	.bank_max = ARRAY_SIZE(svs_mt8192_banks),
+};
+
 static const struct svs_platform_data svs_mt8183_platform_data = {
 	.name = "mt8183-svs",
 	.banks = svs_mt8183_banks,
@@ -1844,6 +2302,9 @@ static const struct svs_platform_data svs_mt8183_platform_data = {
 
 static const struct of_device_id svs_of_match[] = {
 	{
+		.compatible = "mediatek,mt8192-svs",
+		.data = &svs_mt8192_platform_data,
+	}, {
 		.compatible = "mediatek,mt8183-svs",
 		.data = &svs_mt8183_platform_data,
 	}, {
-- 
2.18.0



From f.fainelli at gmail.com  Wed Jan 26 19:55:09 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Wed, 26 Jan 2022 19:55:09 -0800
Subject: [PATCH 0/4] Broadcom STB PM PSCI extensions
In-Reply-To: <20220122035421.4086618-1-f.fainelli@gmail.com>
References: <20220122035421.4086618-1-f.fainelli@gmail.com>
Message-ID: <c7b80842-1e30-8a25-933c-da8658a91287@gmail.com>



On 1/21/2022 7:54 PM, Florian Fainelli wrote:
> Hi all,
> 
> This patch series contains the Broadcom STB PSCI extensions which adds
> some additional functions on top of the existing standard PSCI interface
> which is the reason for having the driver implement a custom
> suspend_ops.
> 
> These platforms have traditionally supported a mode that is akin to
> ACPI's S2 with the CPU in WFI and all of the chip being clock gated
> which is entered with "echo standby > /sys/power/state". Additional a
> true suspend to DRAM as defined in ACPI by S3 is implemented with "echo
> mem > /sys/power/state".
> 
> These platforms also may have an external Broadcom PMIC chip which can
> cause the SoC to be powercycled assuming that we communicate that intent
> via a vendor specific PSCI SYSTEM_RESET2.
> 
> Since it is desirable to get any new functionality added to the kernel
> to be loadable as a module as part of shipping said products in a Google
> Kernel Image (GKI) environment, we need to export a couple of symbols from
> drivers/firmware/psci/psci.c.
> 
> Thanks for your feedback.

I will be sending a v2 addressing the kbuild robot failures reported but 
would prefer to get some feedback first so it can be addressed 
simultaneously. Thanks!

> 
> Florian Fainelli (4):
>    firmware: psci: Export a couple of suspend symbols
>    soc: bcm: brcmstb: Make legacy PM code depend on !ARM_PSCI_FW
>    soc: bcm: brcmstb: Added support for PSCI system suspend operations
>    Documentation: ABI: Document Broadcom STB PSCI firmware files
> 
>   .../ABI/testing/sysfs-firmware-brcmstb        |  16 +
>   drivers/firmware/psci/psci.c                  |   9 +-
>   drivers/soc/bcm/brcmstb/Kconfig               |   4 +-
>   drivers/soc/bcm/brcmstb/pm/Makefile           |   3 +
>   drivers/soc/bcm/brcmstb/pm/pm-psci.c          | 315 ++++++++++++++++++
>   include/linux/psci.h                          |   2 +
>   include/linux/soc/brcmstb/brcmstb-smccc.h     |  84 +++++
>   7 files changed, 430 insertions(+), 3 deletions(-)
>   create mode 100644 Documentation/ABI/testing/sysfs-firmware-brcmstb
>   create mode 100644 drivers/soc/bcm/brcmstb/pm/pm-psci.c
>   create mode 100644 include/linux/soc/brcmstb/brcmstb-smccc.h
> 

-- 
Florian


From reijiw at google.com  Wed Jan 26 20:01:35 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed, 26 Jan 2022 20:01:35 -0800
Subject: [RFC PATCH v4 04/26] KVM: arm64: Make ID_AA64PFR0_EL1 writable
In-Reply-To: <CA+EHjTxCWe2pFNhq+9gRUJ0RnjX4OcuV2WazDbProUaJE2ZTBg@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-5-reijiw@google.com>
 <CA+EHjTxCWe2pFNhq+9gRUJ0RnjX4OcuV2WazDbProUaJE2ZTBg@mail.gmail.com>
Message-ID: <CAAeT=FzBC+1P3jNuLvF_tLwy-aQehPyJXJ3dmAsijB8=ky-ZKA@mail.gmail.com>

 Hi Fuad,

On Mon, Jan 24, 2022 at 8:51 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:28 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > This patch adds id_reg_info for ID_AA64PFR0_EL1 to make it writable by
> > userspace.
> >
> > Return an error if userspace tries to set SVE/GIC field of the register
> > to a value that conflicts with SVE/GIC configuration for the guest.
> > SIMD/FP/SVE fields of the requested value are validated according to
> > Arm ARM.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h |   1 +
> >  arch/arm64/include/asm/sysreg.h   |   2 +
> >  arch/arm64/kvm/sys_regs.c         | 177 +++++++++++++++++++-----------
> >  arch/arm64/kvm/vgic/vgic-init.c   |   5 +
> >  4 files changed, 123 insertions(+), 62 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index c789a0137f58..4509f9e7472d 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -749,6 +749,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
> >                                 struct kvm_arm_copy_mte_tags *copy_tags);
> >
> >  void set_default_id_regs(struct kvm *kvm);
> > +int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
> >
> >  /* Guest/host FPSIMD coordination helpers */
> >  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 16b3f1a1d468..e26027817171 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -798,6 +798,7 @@
> >  #define ID_AA64PFR0_ASIMD_SUPPORTED    0x0
> >  #define ID_AA64PFR0_ELx_64BIT_ONLY     0x1
> >  #define ID_AA64PFR0_ELx_32BIT_64BIT    0x2
> > +#define ID_AA64PFR0_GIC3               0x1
> >
> >  /* id_aa64pfr1 */
> >  #define ID_AA64PFR1_MPAMFRAC_SHIFT     16
> > @@ -1197,6 +1198,7 @@
> >  #define ICH_VTR_TDS_MASK       (1 << ICH_VTR_TDS_SHIFT)
> >
> >  #define ARM64_FEATURE_FIELD_BITS       4
> > +#define ARM64_FEATURE_FIELD_MASK       ((1ull << ARM64_FEATURE_FIELD_BITS) - 1)
> >
> >  /* Create a mask for the feature bits of the specified feature. */
> >  #define ARM64_FEATURE_MASK(x)  (GENMASK_ULL(x##_SHIFT + ARM64_FEATURE_FIELD_BITS - 1, x##_SHIFT))
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 971018288bee..1eb5c5fb614f 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -318,6 +318,92 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
> >                 id_reg->init(id_reg);
> >  }
> >
> > +static int validate_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> > +                                   const struct id_reg_info *id_reg, u64 val)
> > +{
> > +       int fp, simd;
> > +       unsigned int gic;
> > +       bool vcpu_has_sve = vcpu_has_sve(vcpu);
> > +       bool pfr0_has_sve = id_aa64pfr0_sve(val);
> > +
> > +       simd = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_ASIMD_SHIFT);
> > +       fp = cpuid_feature_extract_signed_field(val, ID_AA64PFR0_FP_SHIFT);
> > +       if (simd != fp)
>
> Why is this the case? Could you add a comment?

Arm ARM says AdvSIMD field must have the same value as the FP field.
I will add the comment.


> > +               return -EINVAL;
> > +
> > +       /* fp must be supported when sve is supported */
> > +       if (pfr0_has_sve && (fp < 0))
> > +               return -EINVAL;
> > +
> > +       /* Check if there is a conflict with a request via KVM_ARM_VCPU_INIT */
> > +       if (vcpu_has_sve ^ pfr0_has_sve)
> > +               return -EPERM;
> > +
> > +       if ((irqchip_in_kernel(vcpu->kvm) &&
> > +            vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)) {
> > +               gic = cpuid_feature_extract_unsigned_field(val,
> > +                                                       ID_AA64PFR0_GIC_SHIFT);
> > +               if (gic == 0)
> > +                       return -EPERM;
> > +
> > +               if (gic > ID_AA64PFR0_GIC3)
> > +                       return -E2BIG;
> > +       } else {
> > +               u64 mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> > +               int err = arm64_check_features(id_reg->sys_reg, val & mask,
> > +                                              id_reg->vcpu_limit_val & mask);
> > +               if (err)
> > +                       return err;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static void init_id_aa64pfr0_el1_info(struct id_reg_info *id_reg)
> > +{
> > +       u64 limit = id_reg->vcpu_limit_val;
> > +       unsigned int gic;
> > +
> > +       limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
> > +       if (!system_supports_sve())
> > +               limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> > +
> > +       /*
> > +        * The default is to expose CSV2 == 1 and CSV3 == 1 if the HW
> > +        * isn't affected.  Userspace can override this as long as it
> > +        * doesn't promise the impossible.
> > +        */
> > +       limit &= ~(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2) |
> > +                  ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3));
> > +
> > +       if (arm64_get_spectre_v2_state() == SPECTRE_UNAFFECTED)
> > +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), 1);
> > +       if (arm64_get_meltdown_state() == SPECTRE_UNAFFECTED)
> > +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), 1);
> > +
> > +       gic = cpuid_feature_extract_unsigned_field(limit, ID_AA64PFR0_GIC_SHIFT);
> > +       if (gic > 1) {
> > +               /* Limit to GICv3.0/4.0 */
> > +               limit &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> > +               limit |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), ID_AA64PFR0_GIC3);
> > +       }
> > +       id_reg->vcpu_limit_val = limit;
> > +}
> > +
> > +static u64 vcpu_mask_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu,
> > +                                        const struct id_reg_info *idr)
> > +{
> > +       return vcpu_has_sve(vcpu) ? 0 : ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> > +}
> > +
> > +static struct id_reg_info id_aa64pfr0_el1_info = {
> > +       .sys_reg = SYS_ID_AA64PFR0_EL1,
> > +       .ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR0_GIC),
> > +       .init = init_id_aa64pfr0_el1_info,
> > +       .validate = validate_id_aa64pfr0_el1,
> > +       .vcpu_mask = vcpu_mask_id_aa64pfr0_el1,
> > +};
> > +
> >  /*
> >   * An ID register that needs special handling to control the value for the
> >   * guest must have its own id_reg_info in id_reg_info_table.
> > @@ -326,7 +412,9 @@ static void id_reg_info_init(struct id_reg_info *id_reg)
> >   * validation, etc.)
> >   */
> >  #define        GET_ID_REG_INFO(id)     (id_reg_info_table[IDREG_IDX(id)])
> > -static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {};
> > +static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
> > +       [IDREG_IDX(SYS_ID_AA64PFR0_EL1)] = &id_aa64pfr0_el1_info,
> > +};
> >
> >  static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> >  {
> > @@ -1161,12 +1249,12 @@ static u64 read_kvm_id_reg(struct kvm *kvm, u32 id)
> >         return kvm->arch.id_regs[IDREG_IDX(id)];
> >  }
> >
> > -static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> > +static int __modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> >                              u64 preserve_mask)
> >  {
> >         u64 old, new;
> >
> > -       mutex_lock(&kvm->lock);
> > +       lockdep_assert_held(&kvm->lock);
> >
> >         old = kvm->arch.id_regs[IDREG_IDX(id)];
> >
> > @@ -1179,11 +1267,21 @@ static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> >                 return -EBUSY;
> >
> >         WRITE_ONCE(kvm->arch.id_regs[IDREG_IDX(id)], new);
> > -       mutex_unlock(&kvm->lock);
> >
> >         return 0;
> >  }
> >
> > +static int modify_kvm_id_reg(struct kvm *kvm, u32 id, u64 val,
> > +                            u64 preserve_mask)
> > +{
> > +       int ret;
> > +
> > +       mutex_lock(&kvm->lock);
> > +       ret = __modify_kvm_id_reg(kvm, id, val, preserve_mask);
> > +       mutex_unlock(&kvm->lock);
> > +
> > +       return ret;
> > +}
>
> I think you probably wanted these changes to modify_kvm_id_reg() to go
> into the previous patch rather than in this one.

I will move them into the previous patch.
(I delayed this change until the code actually needed it)

>
>
> >  static int write_kvm_id_reg(struct kvm *kvm, u32 id, u64 val)
> >  {
> >         return modify_kvm_id_reg(kvm, id, val, 0);
> > @@ -1233,20 +1331,6 @@ static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> >                 val &= ~(id_reg->vcpu_mask(vcpu, id_reg));
> >
> >         switch (id) {
> > -       case SYS_ID_AA64PFR0_EL1:
> > -               if (!vcpu_has_sve(vcpu))
> > -                       val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_SVE);
> > -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_AMU);
> > -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2);
> > -               val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2);
> > -               val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3);
> > -               val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3);
> > -               if (irqchip_in_kernel(vcpu->kvm) &&
> > -                   vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
> > -                       val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC);
> > -                       val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), 1);
> > -               }
> > -               break;
> >         case SYS_ID_AA64PFR1_EL1:
> >                 if (!kvm_has_mte(vcpu->kvm))
> >                         val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_MTE);
> > @@ -1347,48 +1431,6 @@ static unsigned int sve_visibility(const struct kvm_vcpu *vcpu,
> >         return REG_HIDDEN;
> >  }
> >
> > -static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> > -                              const struct sys_reg_desc *rd,
> > -                              const struct kvm_one_reg *reg, void __user *uaddr)
> > -{
> > -       const u64 id = sys_reg_to_index(rd);
> > -       u8 csv2, csv3;
> > -       int err;
> > -       u64 val;
> > -
> > -       err = reg_from_user(&val, uaddr, id);
> > -       if (err)
> > -               return err;
> > -
> > -       /*
> > -        * Allow AA64PFR0_EL1.CSV2 to be set from userspace as long as
> > -        * it doesn't promise more than what is actually provided (the
> > -        * guest could otherwise be covered in ectoplasmic residue).
> > -        */
> > -       csv2 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV2_SHIFT);
> > -       if (csv2 > 1 ||
> > -           (csv2 && arm64_get_spectre_v2_state() != SPECTRE_UNAFFECTED))
> > -               return -EINVAL;
> > -
> > -       /* Same thing for CSV3 */
> > -       csv3 = cpuid_feature_extract_unsigned_field(val, ID_AA64PFR0_CSV3_SHIFT);
> > -       if (csv3 > 1 ||
> > -           (csv3 && arm64_get_meltdown_state() != SPECTRE_UNAFFECTED))
> > -               return -EINVAL;
> > -
> > -       /* We can only differ with CSV[23], and anything else is an error */
> > -       val ^= read_id_reg(vcpu, rd, false);
> > -       val &= ~((0xFUL << ID_AA64PFR0_CSV2_SHIFT) |
> > -                (0xFUL << ID_AA64PFR0_CSV3_SHIFT));
> > -       if (val)
> > -               return -EINVAL;
> > -
> > -       vcpu->kvm->arch.pfr0_csv2 = csv2;
> > -       vcpu->kvm->arch.pfr0_csv3 = csv3 ;
> > -
> > -       return 0;
> > -}
> > -
> >  /* cpufeature ID register user accessors */
> >  static int __get_id_reg(const struct kvm_vcpu *vcpu,
> >                         const struct sys_reg_desc *rd, void __user *uaddr,
> > @@ -1702,8 +1744,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
> >
> >         /* AArch64 ID registers */
> >         /* CRm=4 */
> > -       { SYS_DESC(SYS_ID_AA64PFR0_EL1), .access = access_id_reg,
> > -         .get_user = get_id_reg, .set_user = set_id_aa64pfr0_el1, },
> > +       ID_SANITISED(ID_AA64PFR0_EL1),
> >         ID_SANITISED(ID_AA64PFR1_EL1),
> >         ID_UNALLOCATED(4,2),
> >         ID_UNALLOCATED(4,3),
> > @@ -3095,3 +3136,15 @@ void set_default_id_regs(struct kvm *kvm)
> >                 (void)write_kvm_id_reg(kvm, id, val);
> >         }
> >  }
> > +
> > +/*
> > + * Update the ID register's field with @fval for the guest.
> > + * The caller is expected to hold the kvm->lock.
> > + */
> > +int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval)
> > +{
> > +       u64 val = ((u64)fval & ARM64_FEATURE_FIELD_MASK) << field_shift;
> > +       u64 preserve_mask = ~(ARM64_FEATURE_FIELD_MASK << field_shift);
> > +
> > +       return __modify_kvm_id_reg(kvm, id, val, preserve_mask);
> > +}
>
> This seems to me like it should also be in the previous patch or a
> separate patch.

This is also the same as the previous comment.
I will move them into the previous patch.

>
> > diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
> > index 0a06d0648970..28d9bf0e178c 100644
> > --- a/arch/arm64/kvm/vgic/vgic-init.c
> > +++ b/arch/arm64/kvm/vgic/vgic-init.c
> > @@ -116,6 +116,11 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
> >         else
> >                 INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
> >
> > +       if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
> > +               /* Set ID_AA64PFR0_EL1.GIC to 1 */
> > +               (void)kvm_set_id_reg_feature(kvm, SYS_ID_AA64PFR0_EL1,
> > +                                    ID_AA64PFR0_GIC3, ID_AA64PFR0_GIC_SHIFT);
> > +
>
> If this fails wouldn't it be better to return the error?

This should never fail because kvm_vgic_create() prevents
userspace from running the first KVM_RUN for any vCPUs
while it calls kvm_set_id_reg_feature().
So, I am thinking of adding WARN_ON_ONCE() for the return value
rather than adding an unnecessary error handling.

Thanks,
Reiji


From ricarkol at google.com  Wed Jan 26 20:16:59 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Wed, 26 Jan 2022 20:16:59 -0800
Subject: [PATCH v3] kselftest: kvm/arm64: Skip tests if we can't create a
 vgic-v3
In-Reply-To: <20220126145242.3473836-1-broonie@kernel.org>
References: <20220126145242.3473836-1-broonie@kernel.org>
Message-ID: <YfIcu2DMi83eua8C@google.com>

On Wed, Jan 26, 2022 at 02:52:42PM +0000, Mark Brown wrote:
> The arch_timer and vgic_irq kselftests assume that they can create a
> vgic-v3, using the library function vgic_v3_setup() which aborts with a
> test failure if it is not possible to do so. Since vgic-v3 can only be
> instantiated on systems where the host has GICv3 this leads to false
> positives on older systems where that is not the case.
> 
> Fix this by changing vgic_v3_setup() to return an error if the vgic can't
> be instantiated and have the callers skip if this happens. We could also
> exit flagging a skip in vgic_v3_setup() but this would prevent future test
> cases conditionally deciding which GIC to use or generally doing more
> complex output.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
> 
> v3:
>  - Use custom print_skip() helper.
>  - Use internal version of _kvm_create_device.
> v2:
>  - The test for being able to create the GIC doesn't actually
>    instantiate it, add a call doing so in that case.
> 
>  tools/testing/selftests/kvm/aarch64/arch_timer.c | 7 ++++++-
>  tools/testing/selftests/kvm/aarch64/vgic_irq.c   | 4 ++++
>  tools/testing/selftests/kvm/lib/aarch64/vgic.c   | 4 +++-
>  3 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/kvm/aarch64/arch_timer.c b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> index 9ad38bd360a4..b08d30bf71c5 100644
> --- a/tools/testing/selftests/kvm/aarch64/arch_timer.c
> +++ b/tools/testing/selftests/kvm/aarch64/arch_timer.c
> @@ -366,6 +366,7 @@ static struct kvm_vm *test_vm_create(void)
>  {
>  	struct kvm_vm *vm;
>  	unsigned int i;
> +	int ret;
>  	int nr_vcpus = test_args.nr_vcpus;
>  
>  	vm = vm_create_default_with_vcpus(nr_vcpus, 0, 0, guest_code, NULL);
> @@ -382,7 +383,11 @@ static struct kvm_vm *test_vm_create(void)
>  
>  	ucall_init(vm, NULL);
>  	test_init_timer_irq(vm);
> -	vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	ret = vgic_v3_setup(vm, nr_vcpus, 64, GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (ret < 0) {
> +		print_skip("Failed to create vgic-v3");
> +		exit(KSFT_SKIP);
> +	}
>  
>  	/* Make all the test's cmdline args visible to the guest */
>  	sync_global_to_guest(vm, test_args);
> diff --git a/tools/testing/selftests/kvm/aarch64/vgic_irq.c b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> index e6c7d7f8fbd1..7eca97799917 100644
> --- a/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> +++ b/tools/testing/selftests/kvm/aarch64/vgic_irq.c
> @@ -761,6 +761,10 @@ static void test_vgic(uint32_t nr_irqs, bool level_sensitive, bool eoi_split)
>  
>  	gic_fd = vgic_v3_setup(vm, 1, nr_irqs,
>  			GICD_BASE_GPA, GICR_BASE_GPA);
> +	if (gic_fd < 0) {
> +		print_skip("Failed to create vgic-v3, skipping");
> +		exit(KSFT_SKIP);
> +	}
>  
>  	vm_install_exception_handler(vm, VECTOR_IRQ_CURRENT,
>  		guest_irq_handlers[args.eoi_split][args.level_sensitive]);
> diff --git a/tools/testing/selftests/kvm/lib/aarch64/vgic.c b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> index b3a0fca0d780..f5cd0c536d85 100644
> --- a/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> +++ b/tools/testing/selftests/kvm/lib/aarch64/vgic.c
> @@ -52,7 +52,9 @@ int vgic_v3_setup(struct kvm_vm *vm, unsigned int nr_vcpus, uint32_t nr_irqs,
>  			nr_vcpus, nr_vcpus_created);
>  
>  	/* Distributor setup */
> -	gic_fd = kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3, false);
> +	if (_kvm_create_device(vm, KVM_DEV_TYPE_ARM_VGIC_V3,
> +			       false, &gic_fd) != 0)
> +		return -1;
>  
>  	kvm_device_access(gic_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
>  			0, &nr_irqs, true);
> -- 
> 2.30.2
> 
> _______________________________________________
> kvmarm mailing list
> kvmarm at lists.cs.columbia.edu
> https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

Tried both gicv2 and v3 and the change works as expected.

Tested-by: Ricardo Koller <ricarkol at google.com>


From lkp at intel.com  Wed Jan 26 20:17:24 2022
From: lkp at intel.com (kernel test robot)
Date: Thu, 27 Jan 2022 12:17:24 +0800
Subject: [PATCH 1/8] crypto: sun8i-ce: do not allocate memory when
 handling requests
In-Reply-To: <20220126210441.3661782-2-clabbe@baylibre.com>
References: <20220126210441.3661782-2-clabbe@baylibre.com>
Message-ID: <202201271243.hLjdr8IB-lkp@intel.com>

Hi Corentin,

I love your patch! Perhaps something to improve:

[auto build test WARNING on sunxi/sunxi/for-next]
[also build test WARNING on herbert-cryptodev-2.6/master herbert-crypto-2.6/master v5.17-rc1 next-20220125]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Corentin-Labbe/crypto-allwinner-various-improvments/20220127-050556
base:   https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux.git sunxi/for-next
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20220127/202201271243.hLjdr8IB-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2a1b7aa016c0f4b5598806205bdfbab1ea2d92c4)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://github.com/0day-ci/linux/commit/d0b880af8c99abcd0f36463b82c92d71024408de
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Corentin-Labbe/crypto-allwinner-various-improvments/20220127-050556
        git checkout d0b880af8c99abcd0f36463b82c92d71024408de
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/crypto/allwinner/sun8i-ce/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

>> drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c:258:1: warning: unused label 'theend_key' [-Wunused-label]
   theend_key:
   ^~~~~~~~~~~
   1 warning generated.


vim +/theend_key +258 drivers/crypto/allwinner/sun8i-ce/sun8i-ce-cipher.c

06f751b613296cc Corentin Labbe 2019-10-23  108  
06f751b613296cc Corentin Labbe 2019-10-23  109  	flow = rctx->flow;
06f751b613296cc Corentin Labbe 2019-10-23  110  
06f751b613296cc Corentin Labbe 2019-10-23  111  	chan = &ce->chanlist[flow];
06f751b613296cc Corentin Labbe 2019-10-23  112  
06f751b613296cc Corentin Labbe 2019-10-23  113  	cet = chan->tl;
06f751b613296cc Corentin Labbe 2019-10-23  114  	memset(cet, 0, sizeof(struct ce_task));
06f751b613296cc Corentin Labbe 2019-10-23  115  
93c7f4d357de68f Corentin Labbe 2019-11-17  116  	cet->t_id = cpu_to_le32(flow);
93c7f4d357de68f Corentin Labbe 2019-11-17  117  	common = ce->variant->alg_cipher[algt->ce_algo_id];
93c7f4d357de68f Corentin Labbe 2019-11-17  118  	common |= rctx->op_dir | CE_COMM_INT;
93c7f4d357de68f Corentin Labbe 2019-11-17  119  	cet->t_common_ctl = cpu_to_le32(common);
06f751b613296cc Corentin Labbe 2019-10-23  120  	/* CTS and recent CE (H6) need length in bytes, in word otherwise */
6b4f76c2cd9e6c3 Corentin Labbe 2020-09-18  121  	if (ce->variant->cipher_t_dlen_in_bytes)
93c7f4d357de68f Corentin Labbe 2019-11-17  122  		cet->t_dlen = cpu_to_le32(areq->cryptlen);
93c7f4d357de68f Corentin Labbe 2019-11-17  123  	else
93c7f4d357de68f Corentin Labbe 2019-11-17  124  		cet->t_dlen = cpu_to_le32(areq->cryptlen / 4);
06f751b613296cc Corentin Labbe 2019-10-23  125  
93c7f4d357de68f Corentin Labbe 2019-11-17  126  	sym = ce->variant->op_mode[algt->ce_blockmode];
06f751b613296cc Corentin Labbe 2019-10-23  127  	len = op->keylen;
06f751b613296cc Corentin Labbe 2019-10-23  128  	switch (len) {
06f751b613296cc Corentin Labbe 2019-10-23  129  	case 128 / 8:
93c7f4d357de68f Corentin Labbe 2019-11-17  130  		sym |= CE_AES_128BITS;
06f751b613296cc Corentin Labbe 2019-10-23  131  		break;
06f751b613296cc Corentin Labbe 2019-10-23  132  	case 192 / 8:
93c7f4d357de68f Corentin Labbe 2019-11-17  133  		sym |= CE_AES_192BITS;
06f751b613296cc Corentin Labbe 2019-10-23  134  		break;
06f751b613296cc Corentin Labbe 2019-10-23  135  	case 256 / 8:
93c7f4d357de68f Corentin Labbe 2019-11-17  136  		sym |= CE_AES_256BITS;
06f751b613296cc Corentin Labbe 2019-10-23  137  		break;
06f751b613296cc Corentin Labbe 2019-10-23  138  	}
06f751b613296cc Corentin Labbe 2019-10-23  139  
93c7f4d357de68f Corentin Labbe 2019-11-17  140  	cet->t_sym_ctl = cpu_to_le32(sym);
06f751b613296cc Corentin Labbe 2019-10-23  141  	cet->t_asym_ctl = 0;
06f751b613296cc Corentin Labbe 2019-10-23  142  
0605fa0f78266cc Corentin Labbe 2020-09-18  143  	rctx->addr_key = dma_map_single(ce->dev, op->key, op->keylen, DMA_TO_DEVICE);
0605fa0f78266cc Corentin Labbe 2020-09-18  144  	if (dma_mapping_error(ce->dev, rctx->addr_key)) {
06f751b613296cc Corentin Labbe 2019-10-23  145  		dev_err(ce->dev, "Cannot DMA MAP KEY\n");
06f751b613296cc Corentin Labbe 2019-10-23  146  		err = -EFAULT;
06f751b613296cc Corentin Labbe 2019-10-23  147  		goto theend;
06f751b613296cc Corentin Labbe 2019-10-23  148  	}
0605fa0f78266cc Corentin Labbe 2020-09-18  149  	cet->t_key = cpu_to_le32(rctx->addr_key);
06f751b613296cc Corentin Labbe 2019-10-23  150  
06f751b613296cc Corentin Labbe 2019-10-23  151  	ivsize = crypto_skcipher_ivsize(tfm);
06f751b613296cc Corentin Labbe 2019-10-23  152  	if (areq->iv && crypto_skcipher_ivsize(tfm) > 0) {
a216f8d540cf132 Corentin Labbe 2020-09-18  153  		rctx->ivlen = ivsize;
06f751b613296cc Corentin Labbe 2019-10-23  154  		if (rctx->op_dir & CE_DECRYPTION) {
06f751b613296cc Corentin Labbe 2019-10-23  155  			offset = areq->cryptlen - ivsize;
d0b880af8c99abc Corentin Labbe 2022-01-26  156  			scatterwalk_map_and_copy(chan->backup_iv, areq->src,
a216f8d540cf132 Corentin Labbe 2020-09-18  157  						 offset, ivsize, 0);
06f751b613296cc Corentin Labbe 2019-10-23  158  		}
d0b880af8c99abc Corentin Labbe 2022-01-26  159  		memcpy(chan->bounce_iv, areq->iv, ivsize);
d0b880af8c99abc Corentin Labbe 2022-01-26  160  		rctx->addr_iv = dma_map_single(ce->dev, chan->bounce_iv, rctx->ivlen,
93c7f4d357de68f Corentin Labbe 2019-11-17  161  					       DMA_TO_DEVICE);
0605fa0f78266cc Corentin Labbe 2020-09-18  162  		if (dma_mapping_error(ce->dev, rctx->addr_iv)) {
06f751b613296cc Corentin Labbe 2019-10-23  163  			dev_err(ce->dev, "Cannot DMA MAP IV\n");
06f751b613296cc Corentin Labbe 2019-10-23  164  			err = -ENOMEM;
06f751b613296cc Corentin Labbe 2019-10-23  165  			goto theend_iv;
06f751b613296cc Corentin Labbe 2019-10-23  166  		}
0605fa0f78266cc Corentin Labbe 2020-09-18  167  		cet->t_iv = cpu_to_le32(rctx->addr_iv);
06f751b613296cc Corentin Labbe 2019-10-23  168  	}
06f751b613296cc Corentin Labbe 2019-10-23  169  
06f751b613296cc Corentin Labbe 2019-10-23  170  	if (areq->src == areq->dst) {
06f751b613296cc Corentin Labbe 2019-10-23  171  		nr_sgs = dma_map_sg(ce->dev, areq->src, sg_nents(areq->src),
06f751b613296cc Corentin Labbe 2019-10-23  172  				    DMA_BIDIRECTIONAL);
06f751b613296cc Corentin Labbe 2019-10-23  173  		if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
06f751b613296cc Corentin Labbe 2019-10-23  174  			dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
06f751b613296cc Corentin Labbe 2019-10-23  175  			err = -EINVAL;
06f751b613296cc Corentin Labbe 2019-10-23  176  			goto theend_iv;
06f751b613296cc Corentin Labbe 2019-10-23  177  		}
06f751b613296cc Corentin Labbe 2019-10-23  178  		nr_sgd = nr_sgs;
06f751b613296cc Corentin Labbe 2019-10-23  179  	} else {
06f751b613296cc Corentin Labbe 2019-10-23  180  		nr_sgs = dma_map_sg(ce->dev, areq->src, sg_nents(areq->src),
06f751b613296cc Corentin Labbe 2019-10-23  181  				    DMA_TO_DEVICE);
06f751b613296cc Corentin Labbe 2019-10-23  182  		if (nr_sgs <= 0 || nr_sgs > MAX_SG) {
06f751b613296cc Corentin Labbe 2019-10-23  183  			dev_err(ce->dev, "Invalid sg number %d\n", nr_sgs);
06f751b613296cc Corentin Labbe 2019-10-23  184  			err = -EINVAL;
06f751b613296cc Corentin Labbe 2019-10-23  185  			goto theend_iv;
06f751b613296cc Corentin Labbe 2019-10-23  186  		}
06f751b613296cc Corentin Labbe 2019-10-23  187  		nr_sgd = dma_map_sg(ce->dev, areq->dst, sg_nents(areq->dst),
06f751b613296cc Corentin Labbe 2019-10-23  188  				    DMA_FROM_DEVICE);
06f751b613296cc Corentin Labbe 2019-10-23  189  		if (nr_sgd <= 0 || nr_sgd > MAX_SG) {
06f751b613296cc Corentin Labbe 2019-10-23  190  			dev_err(ce->dev, "Invalid sg number %d\n", nr_sgd);
06f751b613296cc Corentin Labbe 2019-10-23  191  			err = -EINVAL;
06f751b613296cc Corentin Labbe 2019-10-23  192  			goto theend_sgs;
06f751b613296cc Corentin Labbe 2019-10-23  193  		}
06f751b613296cc Corentin Labbe 2019-10-23  194  	}
06f751b613296cc Corentin Labbe 2019-10-23  195  
06f751b613296cc Corentin Labbe 2019-10-23  196  	len = areq->cryptlen;
06f751b613296cc Corentin Labbe 2019-10-23  197  	for_each_sg(areq->src, sg, nr_sgs, i) {
93c7f4d357de68f Corentin Labbe 2019-11-17  198  		cet->t_src[i].addr = cpu_to_le32(sg_dma_address(sg));
06f751b613296cc Corentin Labbe 2019-10-23  199  		todo = min(len, sg_dma_len(sg));
93c7f4d357de68f Corentin Labbe 2019-11-17  200  		cet->t_src[i].len = cpu_to_le32(todo / 4);
06f751b613296cc Corentin Labbe 2019-10-23  201  		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
06f751b613296cc Corentin Labbe 2019-10-23  202  			areq->cryptlen, i, cet->t_src[i].len, sg->offset, todo);
06f751b613296cc Corentin Labbe 2019-10-23  203  		len -= todo;
06f751b613296cc Corentin Labbe 2019-10-23  204  	}
06f751b613296cc Corentin Labbe 2019-10-23  205  	if (len > 0) {
06f751b613296cc Corentin Labbe 2019-10-23  206  		dev_err(ce->dev, "remaining len %d\n", len);
06f751b613296cc Corentin Labbe 2019-10-23  207  		err = -EINVAL;
06f751b613296cc Corentin Labbe 2019-10-23  208  		goto theend_sgs;
06f751b613296cc Corentin Labbe 2019-10-23  209  	}
06f751b613296cc Corentin Labbe 2019-10-23  210  
06f751b613296cc Corentin Labbe 2019-10-23  211  	len = areq->cryptlen;
06f751b613296cc Corentin Labbe 2019-10-23  212  	for_each_sg(areq->dst, sg, nr_sgd, i) {
93c7f4d357de68f Corentin Labbe 2019-11-17  213  		cet->t_dst[i].addr = cpu_to_le32(sg_dma_address(sg));
06f751b613296cc Corentin Labbe 2019-10-23  214  		todo = min(len, sg_dma_len(sg));
93c7f4d357de68f Corentin Labbe 2019-11-17  215  		cet->t_dst[i].len = cpu_to_le32(todo / 4);
06f751b613296cc Corentin Labbe 2019-10-23  216  		dev_dbg(ce->dev, "%s total=%u SG(%d %u off=%d) todo=%u\n", __func__,
06f751b613296cc Corentin Labbe 2019-10-23  217  			areq->cryptlen, i, cet->t_dst[i].len, sg->offset, todo);
06f751b613296cc Corentin Labbe 2019-10-23  218  		len -= todo;
06f751b613296cc Corentin Labbe 2019-10-23  219  	}
06f751b613296cc Corentin Labbe 2019-10-23  220  	if (len > 0) {
06f751b613296cc Corentin Labbe 2019-10-23  221  		dev_err(ce->dev, "remaining len %d\n", len);
06f751b613296cc Corentin Labbe 2019-10-23  222  		err = -EINVAL;
06f751b613296cc Corentin Labbe 2019-10-23  223  		goto theend_sgs;
06f751b613296cc Corentin Labbe 2019-10-23  224  	}
06f751b613296cc Corentin Labbe 2019-10-23  225  
06f751b613296cc Corentin Labbe 2019-10-23  226  	chan->timeout = areq->cryptlen;
0605fa0f78266cc Corentin Labbe 2020-09-18  227  	rctx->nr_sgs = nr_sgs;
0605fa0f78266cc Corentin Labbe 2020-09-18  228  	rctx->nr_sgd = nr_sgd;
0605fa0f78266cc Corentin Labbe 2020-09-18  229  	return 0;
06f751b613296cc Corentin Labbe 2019-10-23  230  
06f751b613296cc Corentin Labbe 2019-10-23  231  theend_sgs:
06f751b613296cc Corentin Labbe 2019-10-23  232  	if (areq->src == areq->dst) {
884b93c51025026 Xiang Chen     2021-03-16  233  		dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
884b93c51025026 Xiang Chen     2021-03-16  234  			     DMA_BIDIRECTIONAL);
06f751b613296cc Corentin Labbe 2019-10-23  235  	} else {
06f751b613296cc Corentin Labbe 2019-10-23  236  		if (nr_sgs > 0)
884b93c51025026 Xiang Chen     2021-03-16  237  			dma_unmap_sg(ce->dev, areq->src, sg_nents(areq->src),
884b93c51025026 Xiang Chen     2021-03-16  238  				     DMA_TO_DEVICE);
884b93c51025026 Xiang Chen     2021-03-16  239  		dma_unmap_sg(ce->dev, areq->dst, sg_nents(areq->dst),
884b93c51025026 Xiang Chen     2021-03-16  240  			     DMA_FROM_DEVICE);
06f751b613296cc Corentin Labbe 2019-10-23  241  	}
06f751b613296cc Corentin Labbe 2019-10-23  242  
06f751b613296cc Corentin Labbe 2019-10-23  243  theend_iv:
06f751b613296cc Corentin Labbe 2019-10-23  244  	if (areq->iv && ivsize > 0) {
0605fa0f78266cc Corentin Labbe 2020-09-18  245  		if (rctx->addr_iv)
0605fa0f78266cc Corentin Labbe 2020-09-18  246  			dma_unmap_single(ce->dev, rctx->addr_iv, rctx->ivlen, DMA_TO_DEVICE);
06f751b613296cc Corentin Labbe 2019-10-23  247  		offset = areq->cryptlen - ivsize;
06f751b613296cc Corentin Labbe 2019-10-23  248  		if (rctx->op_dir & CE_DECRYPTION) {
d0b880af8c99abc Corentin Labbe 2022-01-26  249  			memcpy(areq->iv, chan->backup_iv, ivsize);
d0b880af8c99abc Corentin Labbe 2022-01-26  250  			memzero_explicit(chan->backup_iv, ivsize);
06f751b613296cc Corentin Labbe 2019-10-23  251  		} else {
06f751b613296cc Corentin Labbe 2019-10-23  252  			scatterwalk_map_and_copy(areq->iv, areq->dst, offset,
06f751b613296cc Corentin Labbe 2019-10-23  253  						 ivsize, 0);
06f751b613296cc Corentin Labbe 2019-10-23  254  		}
d0b880af8c99abc Corentin Labbe 2022-01-26  255  		memzero_explicit(chan->bounce_iv, ivsize);
06f751b613296cc Corentin Labbe 2019-10-23  256  	}
06f751b613296cc Corentin Labbe 2019-10-23  257  
06f751b613296cc Corentin Labbe 2019-10-23 @258  theend_key:
0605fa0f78266cc Corentin Labbe 2020-09-18  259  	dma_unmap_single(ce->dev, rctx->addr_key, op->keylen, DMA_TO_DEVICE);
06f751b613296cc Corentin Labbe 2019-10-23  260  
06f751b613296cc Corentin Labbe 2019-10-23  261  theend:
06f751b613296cc Corentin Labbe 2019-10-23  262  	return err;
06f751b613296cc Corentin Labbe 2019-10-23  263  }
06f751b613296cc Corentin Labbe 2019-10-23  264  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From reijiw at google.com  Wed Jan 26 21:03:34 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed, 26 Jan 2022 21:03:34 -0800
Subject: [RFC PATCH v4 14/26] KVM: arm64: Add consistency checking for
 frac fields of ID registers
In-Reply-To: <CA+EHjTzQK2kswrW3LDf0ybz4estOCdafCvtRZHWwvTv2nH-UVw@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-15-reijiw@google.com>
 <CA+EHjTzQK2kswrW3LDf0ybz4estOCdafCvtRZHWwvTv2nH-UVw@mail.gmail.com>
Message-ID: <CAAeT=FzR+=evcsOA9PMtsE=TDJmBq1LJxR5wo1DMgEZ0B=dU9Q@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 9:01 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Feature fractional field of an ID register cannot be simply validated
> > at KVM_SET_ONE_REG because its validity depends on its (main) feature
> > field value, which could be in a different ID register (and might be
> > set later).
> > Validate fractional fields at the first KVM_RUN instead.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h |   1 +
> >  arch/arm64/kvm/arm.c              |   3 +
> >  arch/arm64/kvm/sys_regs.c         | 116 +++++++++++++++++++++++++++++-
> >  3 files changed, 117 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 4509f9e7472d..7b3f86bd6a6b 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -750,6 +750,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
> >
> >  void set_default_id_regs(struct kvm *kvm);
> >  int kvm_set_id_reg_feature(struct kvm *kvm, u32 id, u8 field_shift, u8 fval);
> > +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu);
> >
> >  /* Guest/host FPSIMD coordination helpers */
> >  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 5f497a0af254..16fc2ce32069 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -596,6 +596,9 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
> >         if (!kvm_arm_vcpu_is_finalized(vcpu))
> >                 return -EPERM;
> >
> > +       if (!kvm_vm_is_protected(kvm) && kvm_id_regs_consistency_check(vcpu))
> > +               return -EPERM;
> > +
> >         vcpu->arch.has_run_once = true;
> >
> >         kvm_arm_vcpu_init_debug(vcpu);
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index ddbeefc3881c..6adb7b04620c 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -756,9 +756,6 @@ static struct id_reg_info id_aa64pfr0_el1_info = {
> >
> >  static struct id_reg_info id_aa64pfr1_el1_info = {
> >         .sys_reg = SYS_ID_AA64PFR1_EL1,
> > -       .ignore_mask = ARM64_FEATURE_MASK(ID_AA64PFR1_RASFRAC) |
> > -                      ARM64_FEATURE_MASK(ID_AA64PFR1_MPAMFRAC) |
> > -                      ARM64_FEATURE_MASK(ID_AA64PFR1_CSV2FRAC),
> >         .init = init_id_aa64pfr1_el1_info,
> >         .validate = validate_id_aa64pfr1_el1,
> >         .vcpu_mask = vcpu_mask_id_aa64pfr1_el1,
> > @@ -3434,10 +3431,109 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices)
> >         return write_demux_regids(uindices);
> >  }
> >
> > +/* ID register's fractional field information with its feature field. */
> > +struct feature_frac {
> > +       u32     id;
> > +       u32     shift;
> > +       u32     frac_id;
> > +       u32     frac_shift;
> > +       u8      frac_ftr_check;
> > +};
>
> frac_ftr_check doesn't seem to be used. Also, it would be easier to
> read if the ordering of the fields match the ordering you initialize
> them below.

Thank you for catching this.
I will remove frac_ftr_check and change the ordering.

>
> > +
> > +static struct feature_frac feature_frac_table[] = {
> > +       {
> > +               .frac_id = SYS_ID_AA64PFR1_EL1,
> > +               .frac_shift = ID_AA64PFR1_RASFRAC_SHIFT,
> > +               .id = SYS_ID_AA64PFR0_EL1,
> > +               .shift = ID_AA64PFR0_RAS_SHIFT,
> > +       },
> > +       {
> > +               .frac_id = SYS_ID_AA64PFR1_EL1,
> > +               .frac_shift = ID_AA64PFR1_MPAMFRAC_SHIFT,
> > +               .id = SYS_ID_AA64PFR0_EL1,
> > +               .shift = ID_AA64PFR0_MPAM_SHIFT,
> > +       },
> > +       {
> > +               .frac_id = SYS_ID_AA64PFR1_EL1,
> > +               .frac_shift = ID_AA64PFR1_CSV2FRAC_SHIFT,
> > +               .id = SYS_ID_AA64PFR0_EL1,
> > +               .shift = ID_AA64PFR0_CSV2_SHIFT,
> > +       },
> > +};
> > +
> > +/*
> > + * Return non-zero if the feature/fractional fields pair are not
> > + * supported. Return zero otherwise.
> > + * This function validates only the fractional feature field,
> > + * and relies on the fact the feature field is validated before
> > + * through arm64_check_features.
> > + */
> > +static int vcpu_id_reg_feature_frac_check(const struct kvm_vcpu *vcpu,
> > +                                         const struct feature_frac *ftr_frac)
> > +{
> > +       const struct id_reg_info *id_reg;
> > +       u32 id;
> > +       u64 val, lim, mask;
> > +
> > +       /* Check if the feature field value is same as the limit */
> > +       id = ftr_frac->id;
> > +       id_reg = GET_ID_REG_INFO(id);
> > +
> > +       mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->shift;
> > +       val = __read_id_reg(vcpu, id) & mask;
> > +       lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
> > +       lim &= mask;
> > +
> > +       if (val != lim)
> > +               /*
> > +                * The feature level is lower than the limit.
> > +                * Any fractional version should be fine.
> > +                */
> > +               return 0;
> > +
> > +       /* Check the fractional feature field */
> > +       id = ftr_frac->frac_id;
> > +       id_reg = GET_ID_REG_INFO(id);
> > +
> > +       mask = (u64)ARM64_FEATURE_FIELD_MASK << ftr_frac->frac_shift;
> > +       val = __read_id_reg(vcpu, id) & mask;
> > +       lim = id_reg ? id_reg->vcpu_limit_val : read_sanitised_ftr_reg(id);
> > +       lim &= mask;
> > +
> > +       if (val == lim)
> > +               /*
> > +                * Both the feature and fractional fields are the same
> > +                * as limit.
> > +                */
> > +               return 0;
> > +
> > +       return arm64_check_features(id, val, lim);
> > +}
> > +
> > +int kvm_id_regs_consistency_check(const struct kvm_vcpu *vcpu)
>
> Nit: considering that this is only checking the fractional fields,
> should the function name reflect that?

Thank you for the suggestion.
I will change the function name to reflect that.
(There were more checks in older version and I forgot to
change the name...)

Thanks,
Reiji


From ebiggers at kernel.org  Wed Jan 26 21:08:38 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 21:08:38 -0800
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <20220125014422.80552-4-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
Message-ID: <YfIo1pL69+GRsSzp@sol.localdomain>

Hi Huck,

This patch generally looks good.  Some comments below:

> +config CRYPTO_HCTR2
> +	tristate "HCTR2 support"
> +	select CRYPTO_XCTR
> +	select CRYPTO_POLYVAL
> +	select CRYPTO_MANAGER
> +	help
> +	  HCTR2 is a length-preserving encryption mode that is efficient on
> +	  processors with instructions to accelerate AES and carryless
> +	  multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
> +	  processors with the ARMv8 crypto extensions.

The Kconfig help text should mention that this is for storage encryption.

> diff --git a/crypto/hctr2.c b/crypto/hctr2.c
> new file mode 100644
> index 000000000000..af43f81b68f3
> --- /dev/null
> +++ b/crypto/hctr2.c
> @@ -0,0 +1,475 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * HCTR2 length-preserving encryption mode
> + *
> + * Copyright 2021 Google LLC
> + */
> +
> +
> +/*
> + * HCTR2 is a length-preserving encryption mode that is efficient on
> + * processors with instructions to accelerate aes and carryless
> + * multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
> + * processors with the ARMv8 crypto extensions.
> + *
> + * Length-preserving encryption with HCTR2
> + *	(https://eprint.iacr.org/2021/1441.pdf)

The mention of the paper should fit into the rest of the text, like "Reference:
..." or "For more details, see the paper ...".

> + *
> + *	HCTR2 has a strict set of requirements for the hash function. For this
> + *	purpose we only allow POLYVAL. To avoid misuse, XCTR is required as
> + *	specified in the HCTR2 paper, though theoretically there is a larger class
> + *	of algorithms that could be used.
> + */

HCTR2 is only defined with POLYVAL and XCTR.  So this paragraph isn't necessary.

You could mention that the block cipher can be replaced with one other than AES,
although that can be considered "obvious".

> +static int hctr2_setkey(struct crypto_skcipher *tfm, const u8 *key,
> +			unsigned int keylen)
> +{
> +	struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +	u8 hbar[BLOCKCIPHER_BLOCK_SIZE];
> +	int err;
> +
> +	crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
> +	crypto_cipher_set_flags(tctx->blockcipher,
> +				crypto_skcipher_get_flags(tfm) &
> +				CRYPTO_TFM_REQ_MASK);
> +	err = crypto_cipher_setkey(tctx->blockcipher, key, keylen);
> +	if (err)
> +		return err;
> +
> +	crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
> +	crypto_skcipher_set_flags(tctx->streamcipher,
> +				  crypto_skcipher_get_flags(tfm) &
> +				  CRYPTO_TFM_REQ_MASK);
> +	err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
> +	if (err)
> +		return err;
> +
> +	memset(tctx->L, 0, sizeof(tctx->L));
> +	memset(hbar, 0, sizeof(hbar));
> +	tctx->L[0] = 0x01;
> +	crypto_cipher_encrypt_one(tctx->blockcipher, tctx->L, tctx->L);
> +	crypto_cipher_encrypt_one(tctx->blockcipher, hbar, hbar);
> +
> +	crypto_shash_clear_flags(tctx->hash, CRYPTO_TFM_REQ_MASK);
> +	crypto_shash_set_flags(tctx->hash, crypto_skcipher_get_flags(tfm) &
> +			       CRYPTO_TFM_REQ_MASK);
> +	err = crypto_shash_setkey(tctx->hash, hbar, BLOCKCIPHER_BLOCK_SIZE);
> +	return err;
> +}

This should call 'memzero_explicit(hbar, sizeof(hbar))' before returning.

> +static int hctr2_hash_tweak(struct skcipher_request *req, u8 *iv)
> +{
> +	u64 tweak_length_part[2];

This should be __le64, not u64.   Also, how about calling this
tweak_length_block or tweaklen_block, given that it's one POLYVAL block?

> +	err = crypto_shash_update(hash_desc, (u8 *)tweak_length_part, sizeof(tweak_length_part));
> +	if (err)
> +		return err;

Limiting lines to 80 columns is still recommended.
'checkpatch --max-line-length=80' will warn about this.

> +	err = crypto_shash_update(hash_desc, iv, TWEAK_SIZE);
> +	return err;
> +}

This can be just 'return crypto_shash_update(...'

> +static int hctr2_hash_message(struct skcipher_request *req,
> +			      struct scatterlist *sgl,
> +			      u8 digest[POLYVAL_DIGEST_SIZE])
> +{
> +	u8 padding[BLOCKCIPHER_BLOCK_SIZE];
> +	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +	struct shash_desc *hash_desc = &rctx->u.hash_desc;
> +	const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
> +	struct sg_mapping_iter miter;
> +	unsigned int remainder = bulk_len % BLOCKCIPHER_BLOCK_SIZE;
> +	int err;
> +
> +	sg_miter_start(&miter, sgl, sg_nents(sgl),
> +		       SG_MITER_FROM_SG | SG_MITER_ATOMIC);
> +	while (sg_miter_next(&miter)) {
> +		err = crypto_shash_update(hash_desc, miter.addr, miter.length);
> +		if (err)
> +			break;
> +	}
> +	sg_miter_stop(&miter);

I don't think it is guaranteed that the length of the crypto request is equal to
the length of the scatterlist; the scatterlist could be longer.

So this would need to stop after processing bulk_len bytes only, like what
adiantum_hash_message() does.

> +static int hctr2_finish(struct skcipher_request *req)
> +{
> +	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +	u8 digest[POLYVAL_DIGEST_SIZE];
> +	int err;
> +
> +	err = hctr2_hash_tweak(req, req->iv);
> +	if (err)
> +		return err;
> +	err = hctr2_hash_message(req, rctx->bulk_part_dst, digest);
> +	if (err)
> +		return err;
> +	crypto_xor(rctx->first_block, digest, BLOCKCIPHER_BLOCK_SIZE);
> +
> +	scatterwalk_map_and_copy(rctx->first_block, req->dst,
> +				 0, BLOCKCIPHER_BLOCK_SIZE, 1);
> +	return 0;
> +}

In general, I think the code could use some more comments that map what is being
done to the pseudocode in the paper.  That would make it easier to understand.

> +	err = -ENAMETOOLONG;
> +	if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
> +				 "hctr2(%s)", blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
> +		goto err_free_inst;
> +	if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
> +		     "hctr2(%s,%s,%s)",
> +		     blockcipher_alg->cra_driver_name,
> +		     streamcipher_alg->base.cra_driver_name,
> +		     hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
> +		goto err_free_inst;
[...]
> +/* hctr2(blockcipher_name [, xctr(blockcipher_name)] [, polyval_name]) */
> +static struct crypto_template hctr2_tmpl = {
> +	.name = "hctr2",
> +	.create = hctr2_create,
> +	.module = THIS_MODULE,
> +};

The optional parameters mentioned in the comment above don't appear to be
implemented.  Also, the syntax described is ambiguous.  I think you meant for
there to be only one set of square brackets?

xctr(blockcipher_name) should be xctr_name, since it would have to be a driver /
implementation name, and those don't necessarily include parentheses like the
algorithm names do.

Did you consider not allowing the single block cipher implementation to be
overridden?  The single block cipher is a minor part compared to xctr.  This
would simplify the "full" syntax slighty, as then it would be
"hctr2(xctr_name, polyval_name)" instead of
"hctr2(blockcipher_name, xctr_name, polyval_name)".

I suppose it does make sense to take the single block cipher parameter, given
that it is used.  But you'll need to make sure to make hctr2_create() enforce
that the same block cipher is used in both parameters.

> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index da3736e51982..87e4df6f8ea9 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -33630,4 +33630,791 @@ static const struct hash_testvec polyval_tv_template[] = {
>  	},
>  };
>  
> +/*
> + * Test vectors generated using https://github.com/google/hctr2
> + */
> +static const struct cipher_testvec aes_hctr2_tv_template[] = {
[snip 787 lines]

I think the selection of test vectors still needs some improvemnt.  As-is, there
are two random test vectors for every permutation of message length in [16, 17,
48, 255] and key length in [16, 24, 32] -- so, 24 test vectors total.  However,
multiple random test vectors with the same lengths are unlikely to be better
than one.  Also, testing each AES key length with every message length is
unlikely to be useful.

Message length is really the main way that things can go wrong in practice.  And
the real-world case of "long aligned message" is not being tested at all.  So I
think the test coverage would be better, with fewer test vectors, if more
message lengths were tested but there were fewer tests for each length.  For
example, one test vector for each message length in [16, 17, 31, 48, 64, 128,
255, 512], assigning different AES key lengths to different ones so that all AES
key lengths get covered.

- Eric


From ebiggers at kernel.org  Wed Jan 26 21:19:27 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 21:19:27 -0800
Subject: [RFC PATCH 2/7] crypto: polyval - Add POLYVAL support
In-Reply-To: <20220125014422.80552-3-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-3-nhuck@google.com>
Message-ID: <YfIrXzoKsX5TjAGY@sol.localdomain>

On Mon, Jan 24, 2022 at 07:44:17PM -0600, Nathan Huckleberry wrote:
> Add support for POLYVAL, an ?-universal hash function similar to GHASH.

I think you mean ?-?U (i.e. ?-?-universal), as appears elsewhere in this
patchset?

> POLYVAL is used as a component to implement HCTR2 mode.
> 
> POLYVAL is implemented as an shash algorithm.  The implementation is
> modified from ghash-generic.c.
> 
> More information on POLYVAL can be found in the HCTR2 paper:
> https://eprint.iacr.org/2021/1441.pdf
> 
> Signed-off-by: Nathan Huckleberry <nhuck at google.com>

This commit message could use a brief mention of why POLYVAL is used instead of
GHASH, and where POLYVAL is originally from.  It is in the paper, but it's worth
emphasizing.

> diff --git a/crypto/polyval-generic.c b/crypto/polyval-generic.c
> new file mode 100644
> index 000000000000..63e908697ea0
> --- /dev/null
> +++ b/crypto/polyval-generic.c
> @@ -0,0 +1,183 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * POLYVAL: hash function for HCTR2.
> + *
> + * Copyright (c) 2007 Nokia Siemens Networks - Mikko Herranen <mh1 at iki.fi>
> + * Copyright (c) 2009 Intel Corp.
> + *   Author: Huang Ying <ying.huang at intel.com>
> + * Copyright 2021 Google LLC
> + */
> +
> +/*
> + * Code based on crypto/ghash-generic.c
> + *
> + * POLYVAL is a keyed hash function similar to GHASH. POLYVAL uses a
> + * different modulus for finite field multiplication which makes hardware
> + * accelerated implementations on little-endian machines faster.
> + *
> + * Like GHASH, POLYVAL is not a cryptographic hash function and should
> + * not be used outside of crypto modes explicitly designed to use POLYVAL.
> + *
> + */

This comment could use some more explanation about the implementation.  The code
is using the implementation trick where the multiplication is actually done
using the GHASH field, but it is not explained.  Also, it should be explained
why this implementation was chosen.  The reason that the GHASH trick is used
instead of doing a POLYVAL native implementation is because in practice, one of
the accelerated implementations will/should be used instead, right?  So this one
didn't matter much -- there just had to be a generic implementation.

There should also be a warning that this implementation isn't constant-time.

- Eric 


From ebiggers at kernel.org  Wed Jan 26 21:28:22 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 21:28:22 -0800
Subject: [RFC PATCH 1/7] crypto: xctr - Add XCTR support
In-Reply-To: <20220125014422.80552-2-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-2-nhuck@google.com>
Message-ID: <YfItdqtnwhaxpz89@sol.localdomain>

On Mon, Jan 24, 2022 at 07:44:16PM -0600, Nathan Huckleberry wrote:
> Add a generic implementation of XCTR mode as a template.  XCTR is a
> blockcipher mode similar to CTR mode.  XCTR uses XORs and little-endian
> addition rather than big-endian arithmetic which makes it slightly
> faster on little-endian CPUs.  It is used as a component to implement
> HCTR2.
>
> 
> More information on XCTR mode can be found in the HCTR2 paper:
> https://eprint.iacr.org/2021/1441.pdf

The other advantage (besides being faster on little-endian CPUs) of XCTR over
CTR is that on practical input sizes, XCTR never needs to deal with integer
overflows, and therefore is less likely to be implemented incorrectly.  It is in
the paper, but it's worth emphasizing.

> +static void crypto_xctr_crypt_final(struct skcipher_walk *walk,
> +				   struct crypto_cipher *tfm, u32 byte_ctr)
> +{
> +	unsigned int bsize = crypto_cipher_blocksize(tfm);
> +	unsigned long alignmask = crypto_cipher_alignmask(tfm);
> +	u8 ctr[MAX_CIPHER_BLOCKSIZE];
> +	u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
> +	u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
> +	u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
> +	u8 *src = walk->src.virt.addr;
> +	u8 *dst = walk->dst.virt.addr;
> +	unsigned int nbytes = walk->nbytes;
> +	u32 ctr32 = byte_ctr / bsize + 1;
> +
> +	u32_to_le_block(ctr, ctr32, bsize);
> +	crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
> +	crypto_cipher_encrypt_one(tfm, keystream, ctrblk);
> +	crypto_xor_cpy(dst, keystream, src, nbytes);
> +}

How about limiting it to a 16-byte block size for now?  That would simplify the
implementation.  You can enforce the block size in crypto_xctr_create().

> +static struct crypto_template crypto_xctr_tmpl[] = {
> +	{
> +		.name = "xctr",
> +		.create = crypto_xctr_create,
> +		.module = THIS_MODULE,
> +	}
> +};

This is defining an array containing 1 crypto_template.  It should just define a
crypto_template struct on its own (not an array).

- Eric


From vkoul at kernel.org  Wed Jan 26 21:28:32 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 27 Jan 2022 10:58:32 +0530
Subject: [PATCH v2] phy: freescale: pcie: cosmetic clean-up
In-Reply-To: <20220113090321.119880-1-marcel@ziswiler.com>
References: <20220113090321.119880-1-marcel@ziswiler.com>
Message-ID: <YfItgKZ4eCeFB5ZX@matsya>

On 13-01-22, 10:03, Marcel Ziswiler wrote:
> From: Marcel Ziswiler <marcel.ziswiler at toradex.com>
> 
> Sort includes alphabethically and add a new line before the dt-bindings
> one as usually done.

Applied, thanks

-- 
~Vinod


From ebiggers at kernel.org  Wed Jan 26 21:36:09 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 21:36:09 -0800
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <YfIrr8MagPw9scLr@gondor.apana.org.au>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <YfIo1pL69+GRsSzp@sol.localdomain>
 <YfIrr8MagPw9scLr@gondor.apana.org.au>
Message-ID: <YfIvSXgnUMoPglCt@sol.localdomain>

On Thu, Jan 27, 2022 at 04:20:47PM +1100, Herbert Xu wrote:
> On Wed, Jan 26, 2022 at 09:08:38PM -0800, Eric Biggers wrote:
> >
> > The optional parameters mentioned in the comment above don't appear to be
> > implemented.  Also, the syntax described is ambiguous.  I think you meant for
> > there to be only one set of square brackets?
> > 
> > xctr(blockcipher_name) should be xctr_name, since it would have to be a driver /
> > implementation name, and those don't necessarily include parentheses like the
> > algorithm names do.
> > 
> > Did you consider not allowing the single block cipher implementation to be
> > overridden?  The single block cipher is a minor part compared to xctr.  This
> > would simplify the "full" syntax slighty, as then it would be
> > "hctr2(xctr_name, polyval_name)" instead of
> > "hctr2(blockcipher_name, xctr_name, polyval_name)".
> > 
> > I suppose it does make sense to take the single block cipher parameter, given
> > that it is used.  But you'll need to make sure to make hctr2_create() enforce
> > that the same block cipher is used in both parameters.
> 
> For the single block cipher parameter, another option is to derive
> it from the xctr_name.  That is, once you have the skcipher for
> xctr_name, you extract its cra_name, assuming that it must be of
> the form xctr(%s) then you just strip away the xctr() and get the
> single block cipher name that way.

That's what I had in mind with "hctr2(xctr_name, polyval_name)".

> 
> The purpose of having the parameter explicitly is so that the
> instantiatied algorithm is automatically torn down when the
> underlying algorithm is replaced with a better version.
> 
> This is in general unnecessary if you're simply using the
> single block cipher to generate setup material.
> 

Well, the single block cipher isn't used just in ->setkey(), but also in
->encrypt() and ->decrypt() (not for the bulk of the data, but for 1 block).
So allowing its implementation to be specified might make sense.

Alternatively the single block cipher could be emulated with xctr which the
template already has, similar to how the cts template only uses cbc, but I think
that would be pretty messy here.

- Eric


From krishnar at ami.com  Wed Jan 26 21:39:08 2022
From: krishnar at ami.com (krishnar4)
Date: Thu, 27 Jan 2022 11:09:08 +0530
Subject: [PATCH linux dev-5.15] hwmon: (pmbus) modify PSU fan_target convert
 value to false
In-Reply-To: <git-send-email-krishnar@ami.com>
References: <git-send-email-krishnar@ami.com>
Message-ID: <20220127053908.16587-1-krishnar@ami.com>

Description: PSU can't use sysfs fan_target to control PSU fan duty.

Signed-off-by: krishnar4 <krishnar at ami.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 776ee2237be2..a56c2e1c4079 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1889,7 +1889,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
 
 	sensor = pmbus_add_sensor(data, "fan", "target", index, page,
 				  0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
-				  false, false, true);
+				  false, false, false);
 
 	if (!sensor)
 		return -ENOMEM;
-- 
2.17.1



From jbx6244 at gmail.com  Wed Jan 26 21:57:00 2022
From: jbx6244 at gmail.com (Johan Jonker)
Date: Thu, 27 Jan 2022 06:57:00 +0100
Subject: [PATCH 2/3] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
In-Reply-To: <20220127010023.3169415-3-pgwipeout@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <20220127010023.3169415-3-pgwipeout@gmail.com>
Message-ID: <e2479729-154a-122f-f2e0-89b62ffe2c8d@gmail.com>

Hi Peter,

On 1/27/22 02:00, Peter Geis wrote:
> Several io power domains on the Quartz64-A operate at 1.8v.
> Add the pmu_io_domains definition to enable support for this.
> This permits the enablement of the following features:
> sdio - wifi support
> sdhci - mmc-hs200-1_8v
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> index d9eb92d59099..33c2c18caaa9 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> @@ -482,6 +482,19 @@ vcc_sd_h: vcc-sd-h {
>  	};
>  };
>  

https://files.pine64.org/doc/quartz64/Quartz64_model-A_schematic_v2.0_20210427.pdf

Could you check with the IO Power Domain Map?

> +&pmu_io_domains {
> +	pmuio1-supply = <&vcc3v3_pmu>;
VCC3V3_PMU

> +	pmuio2-supply = <&vcc3v3_pmu>;
VCC3V3_PMU

> +	vccio1-supply = <&vccio_acodec>;
VCCIO_ACODEC

> +	vccio2-supply = <&vcc_1v8>;
VCC_1V8

> +	vccio3-supply = <&vccio_sd>;
VCCIO_SD

> +	vccio4-supply = <&vcc_1v8>;
==> VCC1V8_PMU

> +	vccio5-supply = <&vcc_3v3>;
==> VCC_1V8

> +	vccio6-supply = <&vcc1v8_dvp>;
VCC1V8_DVP

> +	vccio7-supply = <&vcc_3v3>;
VCC_3V3

> +	status = "okay";
> +};
> +
>  &sdhci {
>  	bus-width = <8>;
>  	mmc-hs200-1_8v;


From krishnar at ami.com  Wed Jan 26 22:04:59 2022
From: krishnar at ami.com (krishnar4)
Date: Thu, 27 Jan 2022 11:34:59 +0530
Subject: [PATCH linux dev-5.15] hwmon: (pmbus) modify PSU fan_target convert
 value to false
In-Reply-To: <git-send-email-krishnar@ami.com>
References: <git-send-email-krishnar@ami.com>
Message-ID: <20220127060459.17310-1-krishnar@ami.com>

Description: PSU can't use sysfs fan_target to control PSU fan duty.

Signed-off-by: krishnar4 <krishnar at ami.com>
---
 drivers/hwmon/pmbus/pmbus_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 776ee2237be2..a56c2e1c4079 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1889,7 +1889,7 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
 
 	sensor = pmbus_add_sensor(data, "fan", "target", index, page,
 				  0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
-				  false, false, true);
+				  false, false, false);
 
 	if (!sensor)
 		return -ENOMEM;
-- 
2.17.1



From john.fastabend at gmail.com  Wed Jan 26 22:06:13 2022
From: john.fastabend at gmail.com (John Fastabend)
Date: Wed, 26 Jan 2022 22:06:13 -0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <20220121135632.136976-3-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
Message-ID: <61f23655411bc_57f032084@john.notmuch>

Hou Tao wrote:
> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
> it only add support for x86-64, so support these atomic operations
> for arm64 as well.
> 
> Basically the implementation procedure is almost mechanical translation
> of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
> under arch/arm64/include/asm. An extra temporary register is needed
> for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
> adding TMP_REG_4 just use BPF_REG_AX instead.
> 
> For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
> both ./test_verifier and "./test_progs -t atomic" are exercised and
> passed correspondingly.
> 
> Signed-off-by: Hou Tao <houtao1 at huawei.com>
> ---
>  

[...]

> +static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
> +{
> +	const u8 code = insn->code;
> +	const u8 dst = bpf2a64[insn->dst_reg];
> +	const u8 src = bpf2a64[insn->src_reg];
> +	const u8 tmp = bpf2a64[TMP_REG_1];
> +	const u8 tmp2 = bpf2a64[TMP_REG_2];
> +	const bool isdw = BPF_SIZE(code) == BPF_DW;
> +	const s16 off = insn->off;
> +	u8 reg;
> +
> +	if (!off) {
> +		reg = dst;
> +	} else {
> +		emit_a64_mov_i(1, tmp, off, ctx);
> +		emit(A64_ADD(1, tmp, tmp, dst), ctx);
> +		reg = tmp;
> +	}
> +
> +	switch (insn->imm) {

Diff'ing X86 implementation which has a BPF_SUB case how is it avoided
here?

> +	/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
> +	case BPF_ADD:
> +		emit(A64_STADD(isdw, reg, src), ctx);
> +		break;
> +	case BPF_AND:
> +		emit(A64_MVN(isdw, tmp2, src), ctx);
> +		emit(A64_STCLR(isdw, reg, tmp2), ctx);
> +		break;
> +	case BPF_OR:
> +		emit(A64_STSET(isdw, reg, src), ctx);
> +		break;
> +	case BPF_XOR:
> +		emit(A64_STEOR(isdw, reg, src), ctx);
> +		break;
> +	/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
> +	case BPF_ADD | BPF_FETCH:
> +		emit(A64_LDADDAL(isdw, src, reg, src), ctx);
> +		break;
> +	case BPF_AND | BPF_FETCH:
> +		emit(A64_MVN(isdw, tmp2, src), ctx);
> +		emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
> +		break;
> +	case BPF_OR | BPF_FETCH:
> +		emit(A64_LDSETAL(isdw, src, reg, src), ctx);
> +		break;
> +	case BPF_XOR | BPF_FETCH:
> +		emit(A64_LDEORAL(isdw, src, reg, src), ctx);
> +		break;
> +	/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
> +	case BPF_XCHG:
> +		emit(A64_SWPAL(isdw, src, reg, src), ctx);
> +		break;
> +	/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
> +	case BPF_CMPXCHG:
> +		emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
> +		break;
> +	default:
> +		pr_err_once("unknown atomic op code %02x\n", insn->imm);
> +		return -EINVAL;

Was about to suggest maybe EFAULT to align with x86, but on second
thought seems arm jit uses EINVAL more universally so best to be
self consistent. Just an observation.

> +	}
> +
> +	return 0;
> +}
> +


From hsinyi at chromium.org  Wed Jan 26 22:17:22 2022
From: hsinyi at chromium.org (Hsin-Yi Wang)
Date: Thu, 27 Jan 2022 14:17:22 +0800
Subject: [PATCH v2 7/7] arm64: dts: Add Mediatek SoC MT8186 dts and
 evaluation board and Makefile
In-Reply-To: <20220105022726.2458-8-allen-kh.cheng@mediatek.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
 <20220105022726.2458-8-allen-kh.cheng@mediatek.com>
Message-ID: <CAJMQK-j0F_yrWNnS418O7e1AdS7VH76XdQMx2boLoe2LVV0nYA@mail.gmail.com>

On Wed, Jan 5, 2022 at 10:27 AM allen-kh.cheng
<allen-kh.cheng at mediatek.com> wrote:
>
> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
>
> Add basic chip support for Mediatek MT8186
>
> Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> ---
>  arch/arm64/boot/dts/mediatek/Makefile       |   1 +
>  arch/arm64/boot/dts/mediatek/mt8186-evb.dts |  24 ++
>  arch/arm64/boot/dts/mediatek/mt8186.dtsi    | 352 ++++++++++++++++++++
>  3 files changed, 377 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi
>
> diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
> index 4f68ebed2e31..2271c3452c64 100644
> --- a/arch/arm64/boot/dts/mediatek/Makefile
> +++ b/arch/arm64/boot/dts/mediatek/Makefile
> @@ -31,5 +31,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
> +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
>  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> new file mode 100644
> index 000000000000..eb23d1f19f87
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + */
> +/dts-v1/;
> +#include "mt8186.dtsi"
> +
> +/ {
> +       model = "MediaTek MT8186 evaluation board";
> +       compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
> +
> +       aliases {
> +               serial0 = &uart0;
> +       };
> +
> +       chosen {
> +               stdout-path = "serial0:921600n8";
> +       };
> +
> +       memory {
> +               device_type = "memory";
> +               reg = <0 0x40000000 0 0x80000000>;
> +       };
> +};
> diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> new file mode 100644
> index 000000000000..fce84c341291
> --- /dev/null
> +++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> @@ -0,0 +1,352 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * Copyright (C) 2022 MediaTek Inc.
> + */
> +/dts-v1/;
> +
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +#include <dt-bindings/phy/phy.h>
> +
> +/ {
> +       compatible = "mediatek,mt8186";
> +       interrupt-parent = <&gic>;
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +
> +       cpus {
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +
> +               cpu0: cpu at 000 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0000>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu1: cpu at 001 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0100>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu2: cpu at 002 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0200>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu3: cpu at 003 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0300>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu4: cpu at 100 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0400>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu5: cpu at 101 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a55", "arm,armv8";
> +                       reg = <0x0500>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2000000000>;
> +                       cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
> +                       next-level-cache = <&l2_0>;
> +               };
> +
> +               cpu6: cpu at 102 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a75", "arm,armv8";
> +                       reg = <0x0600>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2050000000>;
> +                       cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
> +                       next-level-cache = <&l2_1>;
> +               };
> +
> +               cpu7: cpu at 103 {
> +                       device_type = "cpu";
> +                       compatible = "arm,cortex-a75", "arm,armv8";
> +                       reg = <0x0700>;
> +                       enable-method = "psci";
> +                       clock-frequency = <2050000000>;
> +                       cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
> +                       next-level-cache = <&l2_1>;
> +               };
> +
> +               cpu-map {
> +                       cluster0 {
> +                               core0 {
> +                                       cpu = <&cpu0>;
> +                               };
> +
> +                               core1 {
> +                                       cpu = <&cpu1>;
> +                               };
> +
> +                               core2 {
> +                                       cpu = <&cpu2>;
> +                               };
> +
> +                               core3 {
> +                                       cpu = <&cpu3>;
> +                               };
> +
> +                               core4 {
> +                                       cpu = <&cpu4>;
> +                               };
> +
> +                               core5 {
> +                                       cpu = <&cpu5>;
> +                               };
> +
> +                       };
> +                       cluster1 {
> +                               core0 {
> +                                       cpu = <&cpu6>;
> +                               };
> +
> +                               core1 {
> +                                       cpu = <&cpu7>;
> +                               };
> +                       };
> +               };
> +
> +               idle-states {
> +                       entry-method = "psci";
> +
> +                       cpuoff_l: cpu-off-l {
> +                               compatible = "arm,idle-state";
> +                               arm,psci-suspend-param = <0x00010001>;
> +                               local-timer-stop;
> +                               entry-latency-us = <50>;
> +                               exit-latency-us = <100>;
> +                               min-residency-us = <1600>;
> +                       };
> +
> +                       cpuoff_b: cpu-off-b {
> +                               compatible = "arm,idle-state";
> +                               arm,psci-suspend-param = <0x00010001>;
> +                               local-timer-stop;
> +                               entry-latency-us = <50>;
> +                               exit-latency-us = <100>;
> +                               min-residency-us = <1400>;
> +                       };
> +
> +                       clusteroff_l: cluster-off-l {
> +                               compatible = "arm,idle-state";
> +                               arm,psci-suspend-param = <0x01010001>;
> +                               local-timer-stop;
> +                               entry-latency-us = <100>;
> +                               exit-latency-us = <250>;
> +                               min-residency-us = <2100>;
> +                       };
> +
> +                       clusteroff_b: cluster-off-b {
> +                               compatible = "arm,idle-state";
> +                               arm,psci-suspend-param = <0x01010001>;
> +                               local-timer-stop;
> +                               entry-latency-us = <100>;
> +                               exit-latency-us = <250>;
> +                               min-residency-us = <1900>;
> +                       };
> +
> +                       mcusysoff: mcusys-off {
> +                               compatible = "arm,idle-state";
> +                               arm,psci-suspend-param = <0x01010002>;
> +                               local-timer-stop;
> +                               entry-latency-us = <300>;
> +                               exit-latency-us = <1200>;
> +                               min-residency-us = <2600>;
> +                       };
> +               };
> +
> +               l2_0: l2-cache0 {
> +                       compatible = "cache";
> +                       next-level-cache = <&l3_0>;
> +               };
> +
> +               l2_1: l2-cache1 {
> +                       compatible = "cache";
> +                       next-level-cache = <&l3_0>;
> +               };
> +
> +               l3_0: l3-cache {
> +                       compatible = "cache";
> +               };
> +       };
> +
> +       clk26m: oscillator-26m {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <26000000>;
> +       };
> +
> +       clk32k: oscillator-32k {
> +               compatible = "fixed-clock";
> +               #clock-cells = <0>;
> +               clock-frequency = <32000>;
> +       };
> +
> +       psci {
> +               compatible      = "arm,psci-1.0";
> +               method          = "smc";
> +       };
> +

please move below nodes into soc {}


> +       gic: interrupt-controller {
> +               compatible = "arm,gic-v3";
> +               #interrupt-cells = <3>;
> +               #address-cells = <2>;
> +               #size-cells = <2>;
> +               #redistributor-regions = <1>;
> +               interrupt-parent = <&gic>;
> +               interrupt-controller;
> +               reg = <0 0x0c000000 0 0x40000>, // distributor
> +                     <0 0x0c040000 0 0x200000>; // redistributor
> +               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> +       };
> +
> +       watchdog: watchdog at 10007000 {
> +               compatible = "mediatek,mt8186-wdt",
> +                               "mediatek,mt6589-wdt";
> +               reg = <0 0x10007000 0 0x1000>;
> +       };
> +
> +       sys_timer at 10017000 {
> +               compatible = "mediatek,mt8186_timer",
> +                            "mediatek,mt6765-timer";
> +               reg = <0 0x10017000 0 0x1000>;
> +               interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>;
> +       };
> +
> +       timer: timer {
> +               compatible = "arm,armv8-timer";
> +               interrupt-parent = <&gic>;
> +               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> +                               <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> +                               <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> +                               <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> +               clock-frequency = <13000000>;
> +       };
> +
> +       uart0: serial at 11002000 {
> +               compatible = "mediatek,mt8186-uart",
> +                            "mediatek,mt6577-uart";
> +               reg = <0 0x11002000 0 0x1000>;
> +               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>, <&clk26m>;
> +               clock-names = "baud", "bus";
> +       };
> +
> +       uart1: serial at 11003000 {
> +               compatible = "mediatek,mt8186-uart",
> +                            "mediatek,mt6577-uart";
> +               reg = <0 0x11003000 0 0x1000>;
> +               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>, <&clk26m>;
> +               clock-names = "baud", "bus";
> +               status = "disabled";
> +       };
> +
> +       uart2: serial at 11018000 {
> +               compatible = "mediatek,mt8186-uart",
> +                            "mediatek,mt6577-uart";
> +               reg = <0 0x11018000 0 0x1000>;
> +               interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>, <&clk26m>;
> +               clock-names = "baud", "bus";
> +               status = "disabled";
> +       };
> +
> +       mmc0: mmc at 11230000 {
> +               compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
> +               reg = <0 0x11230000 0 0x1000>,
> +                     <0 0x11cd0000 0 0x1000>;
> +               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>,
> +                        <&clk26m>,
> +                        <&clk26m>,
> +                        <&clk26m>;
> +               clock-names = "source", "hclk", "source_cg",
> +                             "ahb_clk";
> +               status = "disabled";
> +       };
> +
> +       mmc1: mmc at 11240000 {
> +               compatible = "mediatek,mt8186-mmc", "mediatek,mt8183-mmc";
> +               reg = <0 0x11240000 0 0x1000>,
> +                     <0 0x11c90000 0 0x1000>;
> +               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> +               clocks = <&clk26m>,
> +                        <&clk26m>,
> +                        <&clk26m>;
> +               clock-names = "source", "hclk", "source_cg";
> +               status = "disabled";
> +       };
> +
> +       u3phy1: usb-phy1 at 11c80000 {
> +               compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
> +               #address-cells = <2>;
> +               #size-cells = <2>;
> +               ranges;
> +               status = "okay";
> +
> +               u2port1: usb2-phy1 at 11c80000 {
> +                       reg = <0 0x11c80000 0 0x700>;
> +                       clocks = <&clk26m>;
> +                       clock-names = "ref";
> +                       #phy-cells = <1>;
> +                       status = "okay";
> +               };
> +
> +               u3port1: usb3-phy1 at 11c80900 {
> +                       reg = <0 0x11c80900 0 0x700>;
> +                       clocks = <&clk26m>;
> +                       clock-names = "ref";
> +                       #phy-cells = <1>;
> +                       status = "okay";
> +               };
> +       };
> +
> +       u3phy0: usb-phy at 11ca0000 {
> +               compatible = "mediatek,mt8186-tphy", "mediatek,generic-tphy-v2";
> +               #address-cells = <2>;
> +               #size-cells = <2>;
> +               ranges;
> +               status = "okay";
> +
> +               u2port0: usb2-phy at 11ca0000 {
> +                       reg = <0 0x11ca0000 0 0x700>;
> +                       clocks = <&clk26m>;
> +                       clock-names = "ref";
> +                       #phy-cells = <1>;
> +                       mediatek,discth = <0x8>;
> +                       status = "okay";
> +               };
> +       };
> +};
> --
> 2.18.0
>


From jbx6244 at gmail.com  Wed Jan 26 22:18:31 2022
From: jbx6244 at gmail.com (Johan Jonker)
Date: Thu, 27 Jan 2022 07:18:31 +0100
Subject: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <20220127010023.3169415-4-pgwipeout@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <20220127010023.3169415-4-pgwipeout@gmail.com>
Message-ID: <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>



On 1/27/22 02:00, Peter Geis wrote:
> The sdmmc1 node on Quartz64-A supports the optional wifi module from
> Pine64.
> Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> the Quartz64-A.
> 
> Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> ---
>  .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 45 +++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> index 33c2c18caaa9..1d73ac6557c5 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> @@ -91,6 +91,18 @@ simple-audio-card,codec {
>  		};
>  	};
>  
> +	sdio_pwrseq: sdio-pwrseq {

> +		status = "okay";

When a node is not previously disabled, then there's no need for "okay".

> +		compatible = "mmc-pwrseq-simple";
> +		clocks = <&rk817 1>;
> +		clock-names = "ext_clock";
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&wifi_enable_h>;
> +		reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
> +		post-power-on-delay-ms = <100>;
> +		power-off-delay-us = <5000000>;
> +	};
> +
>  	vcc12v_dcin: vcc12v_dcin {
>  		compatible = "regulator-fixed";
>  		regulator-name = "vcc12v_dcin";
> @@ -147,6 +159,17 @@ vcc_sys: vcc_sys {
>  		regulator-max-microvolt = <4400000>;
>  		vin-supply = <&vbus>;
>  	};
> +
> +	/* sourced from vcc_sys, sdio module operates internally at 3.3v */
> +	vcc_wl: vcc_wl {
> +		compatible = "regulator-fixed";
> +		regulator-name = "vcc_wl";
> +		regulator-always-on;
> +		regulator-boot-on;
> +		regulator-min-microvolt = <3300000>;
> +		regulator-max-microvolt = <3300000>;
> +		vin-supply = <&vcc_sys>;
> +	};
>  };
>  
>  &cpu0 {
> @@ -475,6 +498,12 @@ pmic_int_l: pmic-int-l {
>  		};
>  	};
>  
> +	sdio-pwrseq {
> +		wifi_enable_h: wifi-enable-h {
> +			rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
> +		};
> +	};
> +
>  	vcc_sd {
>  		vcc_sd_h: vcc-sd-h {
>  			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
> @@ -516,6 +545,22 @@ &sdmmc0 {
>  	status = "okay";
>  };
>  
> +&sdmmc1 {
> +	bus-width = <4>;
> +	cap-sd-highspeed;
> +	cap-sdio-irq;

> +	disable-wp;

>From mmc-controller.yaml:

  disable-wp:
    $ref: /schemas/types.yaml#/definitions/flag
    description:
      When set, no physical write-protect line is present. This
      property should only be specified when the controller has a
      dedicated write-protect detection logic. If a GPIO is always used
      for the write-protect detection logic, it is sufficient to not
      specify the wp-gpios property in the absence of a write-protect
      line. Not used in combination with eMMC or SDIO.

> +	keep-power-in-suspend;
> +	mmc-pwrseq = <&sdio_pwrseq>;
> +	non-removable;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
> +	sd-uhs-sdr104;
> +	vmmc-supply = <&vcc_wl>;
> +	vqmmc-supply = <&vcc_1v8>;
> +	status = "okay";
> +};
> +
>  &spdif {
>  	status = "okay";
>  };


From khalasa at piap.pl  Wed Jan 26 22:18:28 2022
From: khalasa at piap.pl (=?utf-8?Q?Krzysztof_Ha=C5=82asa?=)
Date: Thu, 27 Jan 2022 07:18:28 +0100
Subject: [PATCH 00/13] IXP4xx spring cleaning
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org> (Linus
 Walleij's message of "Thu, 27 Jan 2022 01:36:43 +0100")
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <m3tudpya4r.fsf@t19.piap.pl>

Hi Linus,

Linus Walleij <linus.walleij at linaro.org> writes:

> I think this is because MULTI_V5 turns on CPUs that cannot
> do big endian, and IXP4xx turn on big endian. (It crashes if
> I try to boot in little endian mode, sorry. It really wants
> to run big endian.)

The IXP4xx used to work little-endian, with certain limitations, I guess
it could be easily made to work again.

The limitations were a bit of headache, though. The most problematic was
the network buffers were big-endian and required on-the-fly swapping,
which limited e.g. routing performance (I don't remember the numbers).
Also the crypto operations may have been affected (not sure, perhaps
there was an endianness flag for the crypto coprocessor).

There was a special memory mode where the CPU could swap the buffers in
hardware (it was an MMU page attribute). This special mode wasn't
available on the first CPU revision. I had an experimental, a bit
complicated patch which made use of this feature. This way I was able to
run off-the-shelf little-endian system (like Debian) without the network
performance hit.

IIRC the first CPU revision was used in certain routers (access
servers?) perhaps by US Robotics (3Com?). I had an experimental board
with this early chip as well. Otherwise I think most hardware used the
second revision. The newer chips (IXP43x and 45x/46x) had the feature
from the start, basically I think only the IXP425 rev. A0 (also called
IXC1100 by Intel?) was a problem.
-- 
Krzysztof "Chris" Ha?asa

Sie? Badawcza ?ukasiewicz
Przemys?owy Instytut Automatyki i Pomiar?w PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


From Jianyong.Wu at arm.com  Wed Jan 26 22:24:50 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Thu, 27 Jan 2022 06:24:50 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
 <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
Message-ID: <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi David,

> >>>>>> Thanks for tracking that down.
> >>>>>>
> >>>>>> Note that clearing the BSS twice is not the root problem here.
> >>>>>> The root problem is that we set global state while the kernel
> >>>>>> runs at the default link time address, and then refer to it again
> >>>>>> after the entire kernel has been shifted in the kernel VA space.
> >>>>>> Such global state could consist of mutable pointers to statically
> >>>>>> allocated data (which would be reset to their default values
> >>>>>> after the relocation code
> >>> runs again), or global pointer variables in BSS.
> >>>>>> In either case, relying on such a global variable after the
> >>>>>> second relocation performed by KASLR would be risky, and so we
> >>>>>> should avoid manipulating global state at all if it might involve
> >>>>>> pointer to statically allocated data structures.
> >>>>>>
> >>>>>>> In other ways, if we invoke mutex_lock/unlock in such a early
> >>>>>>> booting
> >>> stage.
> >>>>>>> It might be unsafe because lockdep inserts lock_acquire/release
> >>>>>>> as the complex hooks.
> >>>>>>>
> >>>>>>> In summary, would it better if Jianyong splits these early boot
> >>>>>>> and late boot case? e.g. introduce a nolock version for
> >>>>>> create_mapping_noalloc().
> >>>>>>>
> >>>>>>> What do you think of it?
> >>>>>>>
> >>>>>>
> >>>>>> The pre-KASLR case definitely doesn't need a lock. But given that
> >>>>>> create_mapping_noalloc() is only used to map the FDT, which
> >>>>>> happens very early one way or the other, wouldn't it be better to
> >>>>>> move the lock/unlock into other callers of
> >>>>>> __create_pgd_mapping()? (and make sure no other users of the
> >>>>>> fixmap slots exist)
> >>>>>
> >>>>> There are server callers of __create_pgd_mapping. I think some of
> >>>>> them
> >>> need no fixmap lock as they are called so early. I figure out all of them
> here:
> >>>>> create_mapping_noalloc:   no lock
> >>>>> create_pgd_mapping:   no lock
> >>>>> __map_memblock:    no lock
> >>>>> map_kernel_segment:  no lock
> >>>>> map_entry_trampoline: no lock
> >>>>> update_mapping_prot:    need lock
> >>>>> arch_add_memory:  need lock
> >>>>>
> >>>>> WDYT?
> >>>>>
> >>>>
> >>>> That seems reasonable, but it needs to be documented clearly in the
> code.
> >>>>
> >>>
> >>> Just a random thought, could we rely on system_state to do the
> >>> locking conditionally?
> >>
> >> I can't see the point. At the early stages of kernel boot, we definitely
> need no lock. Also, I think we should keep it simple.
> >>
> >
> > Is e.g.,
> >
> > if (system_state < SYSTEM_RUNNING)
> > 	/* lock */
> >
> > if (system_state < SYSTEM_RUNNING)
> > 	/* unlock */
> 
> of course, inverting the conditions ;)

Yes, system_state can roughly separate these callers of __create_pgd_mapping. When system_state > SYSTEM_BOOTING we can add the lock.
Thus, I have the following change:

static DEFINE_SPINLOCK(swapper_pgdir_lock);
+static DEFINE_MUTEX(fixmap_lock);

 void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
 {
@@ -329,6 +330,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
        }
        BUG_ON(p4d_bad(p4d));

+       if (system_state > SYSTEM_BOOTING)
+               mutex_lock(&fixmap_lock);
        pudp = pud_set_fixmap_offset(p4dp, addr);
        do {
                pud_t old_pud = READ_ONCE(*pudp);
@@ -359,6 +362,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
        } while (pudp++, addr = next, addr != end);

        pud_clear_fixmap();
+       if (system_state > SYSTEM_BOOTING)
+               mutex_unlock(&fixmap_lock);
 }

It seems work and somehow simper. But I don't know if it is reasonable to do this. So, any idea? @Ard Biesheuvel  @Catalin Marinas 

Thanks
Jianyong

> 
> 
> --
> Thanks,
> 
> David / dhildenb


From herbert at gondor.apana.org.au  Wed Jan 26 21:40:16 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 27 Jan 2022 16:40:16 +1100
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <YfIvSXgnUMoPglCt@sol.localdomain>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <YfIo1pL69+GRsSzp@sol.localdomain>
 <YfIrr8MagPw9scLr@gondor.apana.org.au>
 <YfIvSXgnUMoPglCt@sol.localdomain>
Message-ID: <YfIwQFAqSW68VQ62@gondor.apana.org.au>

On Wed, Jan 26, 2022 at 09:36:09PM -0800, Eric Biggers wrote:
>
> Well, the single block cipher isn't used just in ->setkey(), but also in
> ->encrypt() and ->decrypt() (not for the bulk of the data, but for 1 block).
> So allowing its implementation to be specified might make sense.

The question is is it performance-critical? Including it as a
parameter would be worthwhile if it is.  But if its cost is dwarfed
by that of the accompanying operations then it might not be worth
the complexity.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Wed Jan 26 21:44:48 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 27 Jan 2022 16:44:48 +1100
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <YfIwQFAqSW68VQ62@gondor.apana.org.au>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <YfIo1pL69+GRsSzp@sol.localdomain>
 <YfIrr8MagPw9scLr@gondor.apana.org.au>
 <YfIvSXgnUMoPglCt@sol.localdomain>
 <YfIwQFAqSW68VQ62@gondor.apana.org.au>
Message-ID: <YfIxUPc1KsSMTMLq@gondor.apana.org.au>

On Thu, Jan 27, 2022 at 04:40:16PM +1100, Herbert Xu wrote:
>
> The question is is it performance-critical? Including it as a
> parameter would be worthwhile if it is.  But if its cost is dwarfed
> by that of the accompanying operations then it might not be worth
> the complexity.

It looks like this is similar to the situation in XTS where I chose
not to make it a full parameter during the skcipher conversion:

commit f1c131b45410a202eb45cc55980a7a9e4e4b4f40
Author: Herbert Xu <herbert at gondor.apana.org.au>
Date:   Tue Nov 22 20:08:19 2016 +0800

    crypto: xts - Convert to skcipher

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Wed Jan 26 21:20:47 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Thu, 27 Jan 2022 16:20:47 +1100
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <YfIo1pL69+GRsSzp@sol.localdomain>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <YfIo1pL69+GRsSzp@sol.localdomain>
Message-ID: <YfIrr8MagPw9scLr@gondor.apana.org.au>

On Wed, Jan 26, 2022 at 09:08:38PM -0800, Eric Biggers wrote:
>
> The optional parameters mentioned in the comment above don't appear to be
> implemented.  Also, the syntax described is ambiguous.  I think you meant for
> there to be only one set of square brackets?
> 
> xctr(blockcipher_name) should be xctr_name, since it would have to be a driver /
> implementation name, and those don't necessarily include parentheses like the
> algorithm names do.
> 
> Did you consider not allowing the single block cipher implementation to be
> overridden?  The single block cipher is a minor part compared to xctr.  This
> would simplify the "full" syntax slighty, as then it would be
> "hctr2(xctr_name, polyval_name)" instead of
> "hctr2(blockcipher_name, xctr_name, polyval_name)".
> 
> I suppose it does make sense to take the single block cipher parameter, given
> that it is used.  But you'll need to make sure to make hctr2_create() enforce
> that the same block cipher is used in both parameters.

For the single block cipher parameter, another option is to derive
it from the xctr_name.  That is, once you have the skcipher for
xctr_name, you extract its cra_name, assuming that it must be of
the form xctr(%s) then you just strip away the xctr() and get the
single block cipher name that way.

The purpose of having the parameter explicitly is so that the
instantiatied algorithm is automatically torn down when the
underlying algorithm is replaced with a better version.

This is in general unnecessary if you're simply using the
single block cipher to generate setup material.

Cheers,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From ebiggers at kernel.org  Wed Jan 26 22:35:42 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 22:35:42 -0800
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <20220125014422.80552-4-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
Message-ID: <YfI9PrAGYc0v9fGg@sol.localdomain>

On Mon, Jan 24, 2022 at 07:44:18PM -0600, Nathan Huckleberry wrote:
> +static int hctr2_hash_tweak(struct skcipher_request *req, u8 *iv)
> +{

The iv parameter is unnecessary here, since it can be gotten from req->iv.

> +static int hctr2_crypt(struct skcipher_request *req, bool enc)
> +{
> +	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> +	const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +	struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +	u8 digest[POLYVAL_DIGEST_SIZE];
> +	int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
> +	int err;
> +
> +	// Requests must be at least one block
> +	if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
> +		return -EINVAL;
> +
> +	scatterwalk_map_and_copy(rctx->first_block, req->src,
> +				 0, BLOCKCIPHER_BLOCK_SIZE, 0);
> +	rctx->bulk_part_src = scatterwalk_ffwd(rctx->sg_src, req->src, BLOCKCIPHER_BLOCK_SIZE);
> +	rctx->bulk_part_dst = scatterwalk_ffwd(rctx->sg_dst, req->dst, BLOCKCIPHER_BLOCK_SIZE);
> +
> +	err = hctr2_hash_tweak(req, req->iv);
> +	if (err)
> +		return err;
> +	err = hctr2_hash_message(req, rctx->bulk_part_src, digest);
> +	if (err)
> +		return err;
> +	crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
> +
> +	if (enc)
> +		crypto_cipher_encrypt_one(tctx->blockcipher, rctx->first_block, digest);
> +	else
> +		crypto_cipher_decrypt_one(tctx->blockcipher, rctx->first_block, digest);
> +
> +	crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
> +	crypto_xor(digest, tctx->L, BLOCKCIPHER_BLOCK_SIZE);
> +
> +	skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
> +	skcipher_request_set_crypt(&rctx->u.streamcipher_req, rctx->bulk_part_src,
> +				   rctx->bulk_part_dst, bulk_len, digest);
> +	skcipher_request_set_callback(&rctx->u.streamcipher_req,
> +				      req->base.flags,
> +				      hctr2_streamcipher_done, req);
> +	return crypto_skcipher_encrypt(&rctx->u.streamcipher_req) ?:
> +		hctr2_finish(req);
> +}

The IV passed to skcipher_request_set_crypt() above needs to be part of the
request context, not part of the stack frame of this function, in case the xctr
implementation is asynchronous which would cause the stack frame to go out of
scope.  The x86 implementation operates asynchronously when called in a context
where SIMD instructions are unavailable.

Perhaps rctx->first_block can be reused, as it's already in the request context?

Make sure to test your changes with CONFIG_CRYPTO_MANAGER_EXTRA_TESTS enabled,
as that is able to detect this bug (at least when CONFIG_KASAN is also enabled,
which I also highly recommend) since it tests calling the crypto algorithms in a
context where SIMD instructions cannot be used.  Here's the bug report I got:

	BUG: KASAN: stack-out-of-bounds in __crypto_xor+0x29e/0x480 crypto/algapi.c:1005
	Read of size 8 at addr ffffc900006775f8 by task kworker/2:1/41
	CPU: 2 PID: 41 Comm: kworker/2:1 Not tainted 5.17.0-rc1-00071-gb35cef9ae599 #8
	Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ArchLinux 1.15.0-1 04/01/2014
	Workqueue: cryptd cryptd_queue_worker
	Call Trace:
	 <TASK>
	 show_stack+0x3d/0x3f arch/x86/kernel/dumpstack.c:318
	 __dump_stack lib/dump_stack.c:88 [inline]
	 dump_stack_lvl+0x49/0x5e lib/dump_stack.c:106
	 print_address_description.constprop.0+0x24/0x150 mm/kasan/report.c:255
	 __kasan_report.cold+0x7d/0x11a mm/kasan/report.c:442
	 kasan_report+0x3c/0x50 mm/kasan/report.c:459
	 __asan_report_load8_noabort+0x14/0x20 mm/kasan/report_generic.c:309
	 __crypto_xor+0x29e/0x480 crypto/algapi.c:1005
	 crypto_xor_cpy include/crypto/algapi.h:182 [inline]
	 xctr_crypt+0x1f1/0x2f0 arch/x86/crypto/aesni-intel_glue.c:585
	 crypto_skcipher_encrypt+0xe2/0x150 crypto/skcipher.c:630
	 cryptd_skcipher_encrypt+0x1c2/0x320 crypto/cryptd.c:274
	 cryptd_queue_worker+0xe4/0x160 crypto/cryptd.c:181
	 process_one_work+0x822/0x14e0 kernel/workqueue.c:2307
	 worker_thread+0x590/0xf60 kernel/workqueue.c:2454
	 kthread+0x257/0x2f0 kernel/kthread.c:377
	 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:295
	 </TASK>
	Memory state around the buggy address:
	 ffffc90000677480: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00
	 ffffc90000677500: 00 00 00 00 00 00 00 00 00 00 f3 f3 f3 f3 f3 00
	>ffffc90000677580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1
									^
	 ffffc90000677600: f1 f1 f1 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00
	 ffffc90000677680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	==================================================================
	alg: skcipher: hctr2(aes-aesni,xctr-aes-aesni,polyval-pclmulqdqni) encryption test failed (wrong result) on test vector 2, cfg="random: use_digest nosimd src_divs=[100.0%@+3830] iv_offset=45"
	------------[ cut here ]------------
	alg: self-tests for hctr2(aes-aesni,xctr-aes-aesni,polyval-pclmulqdqni) (hctr2(aes)) failed (rc=-22)
	WARNING: CPU: 2 PID: 519 at crypto/testmgr.c:5690 alg_test+0x2d9/0x830 crypto/testmgr.c:5690


> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index a3a24aa07492..fa8f33210358 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -4994,6 +4994,12 @@ static const struct alg_test_desc alg_test_descs[] = {
>  		.suite = {
>  			.hash = __VECS(ghash_tv_template)
>  		}
> +	}, {
> +		.alg = "hctr2(aes)",
> +		.test = alg_test_skcipher,

The .generic_driver field should be filled in here to allow the comparison tests
to run, since the default strategy of forming the generic driver name isn't
valid here; it would result in hctr2(aes-generic), which doesn't work.

- Eric


From hch at infradead.org  Wed Jan 26 22:38:56 2022
From: hch at infradead.org (Christoph Hellwig)
Date: Wed, 26 Jan 2022 22:38:56 -0800
Subject: [PATCH 11/13] ARM: ixp4xx: Drop custom DMA coherency and bouncing
In-Reply-To: <20220127003656.330161-12-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
 <20220127003656.330161-12-linus.walleij@linaro.org>
Message-ID: <YfI+AKDk1xRaN7be@infradead.org>

On Thu, Jan 27, 2022 at 01:36:54AM +0100, Linus Walleij wrote:
> The new PCI driver does not need any of this stuff, so just
> drop it.

Please CC me and the iommu list on changes to kernel/dma/.

But dropping this hooks is awesome, so:

Reviewed-by: Christoph Hellwig <hch at lst.de>


From ebiggers at kernel.org  Wed Jan 26 22:41:31 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Wed, 26 Jan 2022 22:41:31 -0800
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <YfIxUPc1KsSMTMLq@gondor.apana.org.au>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <YfIo1pL69+GRsSzp@sol.localdomain>
 <YfIrr8MagPw9scLr@gondor.apana.org.au>
 <YfIvSXgnUMoPglCt@sol.localdomain>
 <YfIwQFAqSW68VQ62@gondor.apana.org.au>
 <YfIxUPc1KsSMTMLq@gondor.apana.org.au>
Message-ID: <YfI+m9tqj/B4fEzj@sol.localdomain>

On Thu, Jan 27, 2022 at 04:44:48PM +1100, Herbert Xu wrote:
> On Thu, Jan 27, 2022 at 04:40:16PM +1100, Herbert Xu wrote:
> >
> > The question is is it performance-critical? Including it as a
> > parameter would be worthwhile if it is.  But if its cost is dwarfed
> > by that of the accompanying operations then it might not be worth
> > the complexity.
> 
> It looks like this is similar to the situation in XTS where I chose
> not to make it a full parameter during the skcipher conversion:
> 
> commit f1c131b45410a202eb45cc55980a7a9e4e4b4f40
> Author: Herbert Xu <herbert at gondor.apana.org.au>
> Date:   Tue Nov 22 20:08:19 2016 +0800
> 
>     crypto: xts - Convert to skcipher
> 
> Cheers,

Sure, that makes sense.

Note that if the meaning of the first parameter to the template will differ
(blockcipher_name vs. xctr_name), the full syntax probably should be supported
by a separate template called "hctr2_base" rather than by "hctr2", to avoid
having the meaning of the first parameter be context-dependent.  This would be
like gcm and gcm_base.  So we'd have e.g.:

	hctr2(aes)
	hctr2_base(xctr-aes-aesni,polyval-pclmulqdqni)

cra_name would be set to the former, while cra_driver_name would be set to the
latter.

- Eric


From jkchen at linux.alibaba.com  Wed Jan 26 22:42:02 2022
From: jkchen at linux.alibaba.com (Jay Chen)
Date: Thu, 27 Jan 2022 14:42:02 +0800
Subject: [PATCH v4] coresight: tmc: change device registration from misc to
 cdev
Message-ID: <20220127064202.22814-1-jkchen@linux.alibaba.com>

Currently, there are 130 etr and etf on our machine,
but the current coresight tmc driver uses misc_register
to register the device, which leads to the error that
the device number is not enough.

coresight-tmc: probe of xxxxx failed with error -16

This patch changes the device registration method
to cdev's dynamic registration method to solve the
problem of insufficient device numbers.

Signed-off-by: Jay Chen <jkchen at linux.alibaba.com>
---
 .../hwtracing/coresight/coresight-tmc-core.c  | 103 ++++++++++++++----
 drivers/hwtracing/coresight/coresight-tmc.h   |  11 +-
 2 files changed, 91 insertions(+), 23 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index d0276af82494..0977f1ce6338 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -12,7 +12,6 @@
 #include <linux/io.h>
 #include <linux/err.h>
 #include <linux/fs.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/property.h>
 #include <linux/uaccess.h>
@@ -31,6 +30,12 @@ DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
 DEFINE_CORESIGHT_DEVLIST(etr_devs, "tmc_etr");
 
+static DEFINE_IDA(tmc_ida);
+static dev_t tmc_major;
+static struct class *tmc_class;
+
+#define TMC_DEV_MAX	(MINORMASK + 1)
+
 void tmc_wait_for_tmcready(struct tmc_drvdata *drvdata)
 {
 	struct coresight_device *csdev = drvdata->csdev;
@@ -146,8 +151,10 @@ static int tmc_read_unprepare(struct tmc_drvdata *drvdata)
 static int tmc_open(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_prepare(drvdata);
 	if (ret)
@@ -178,8 +185,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 {
 	char *bufp;
 	ssize_t actual;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(file->f_inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
 	if (actual <= 0)
 		return 0;
@@ -199,8 +208,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len,
 static int tmc_release(struct inode *inode, struct file *file)
 {
 	int ret;
-	struct tmc_drvdata *drvdata = container_of(file->private_data,
-						   struct tmc_drvdata, miscdev);
+	struct tmc_cdev *cdev = container_of(inode->i_cdev,
+					     struct tmc_cdev, cdev);
+	struct tmc_drvdata *drvdata = container_of(cdev,
+						   struct tmc_drvdata, cdev);
 
 	ret = tmc_read_unprepare(drvdata);
 	if (ret)
@@ -451,6 +462,7 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
 	u32 devid;
+	dev_t devt;
 	void __iomem *base;
 	struct device *dev = &adev->dev;
 	struct coresight_platform_data *pdata = NULL;
@@ -546,14 +558,32 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
 		goto out;
 	}
 
-	drvdata->miscdev.name = desc.name;
-	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
-	drvdata->miscdev.fops = &tmc_fops;
-	ret = misc_register(&drvdata->miscdev);
+	ret = ida_simple_get(&tmc_ida, 0, TMC_DEV_MAX, GFP_KERNEL);
+	if (ret < 0)
+		goto err_coresight_unregister;
+
+	cdev_init(&drvdata->cdev.cdev, &tmc_fops);
+	drvdata->cdev.cdev.owner = THIS_MODULE;
+	devt = MKDEV(MAJOR(tmc_major), ret);
+	ret = cdev_add(&drvdata->cdev.cdev, devt, 1);
 	if (ret)
-		coresight_unregister(drvdata->csdev);
-	else
+		goto err_free_tmc_ida;
+
+	drvdata->cdev.dev = device_create(tmc_class, NULL, devt, &drvdata->cdev, desc.name);
+	if (IS_ERR(drvdata->cdev.dev)) {
+		ret = PTR_ERR(drvdata->cdev.dev);
+		goto err_delete_cdev;
+	} else
 		pm_runtime_put(&adev->dev);
+
+	return 0;
+
+err_delete_cdev:
+	cdev_del(&drvdata->cdev.cdev);
+err_free_tmc_ida:
+	ida_simple_remove(&tmc_ida, MINOR(devt));
+err_coresight_unregister:
+	coresight_unregister(drvdata->csdev);
 out:
 	return ret;
 }
@@ -583,13 +613,11 @@ static void tmc_shutdown(struct amba_device *adev)
 static void tmc_remove(struct amba_device *adev)
 {
 	struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+	struct device *dev = drvdata->cdev.dev;
 
-	/*
-	 * Since misc_open() holds a refcount on the f_ops, which is
-	 * etb fops in this case, device is there until last file
-	 * handler to this device is closed.
-	 */
-	misc_deregister(&drvdata->miscdev);
+	ida_simple_remove(&tmc_ida, MINOR(dev->devt));
+	device_destroy(tmc_class, dev->devt);
+	cdev_del(&drvdata->cdev.cdev);
 	coresight_unregister(drvdata->csdev);
 }
 
@@ -618,7 +646,42 @@ static struct amba_driver tmc_driver = {
 	.id_table	= tmc_ids,
 };
 
-module_amba_driver(tmc_driver);
+static int __init tmc_init(void)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&tmc_major, 0, TMC_DEV_MAX, "tmc");
+	if (ret < 0) {
+		pr_err("tmc: failed to allocate char dev region\n");
+		return ret;
+	}
+
+	tmc_class = class_create(THIS_MODULE, "tmc");
+	if (IS_ERR(tmc_class)) {
+		pr_err("tmc: failed to create class\n");
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+		return PTR_ERR(tmc_class);
+	}
+
+	ret = amba_driver_register(&tmc_driver);
+	if (ret) {
+		pr_err("tmc: error registering amba driver\n");
+		class_destroy(tmc_class);
+		unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+	}
+
+	return ret;
+}
+
+static void __exit tmc_exit(void)
+{
+	amba_driver_unregister(&tmc_driver);
+	class_destroy(tmc_class);
+	unregister_chrdev_region(tmc_major, TMC_DEV_MAX);
+}
+
+module_init(tmc_init);
+module_exit(tmc_exit);
 
 MODULE_AUTHOR("Pratik Patel <pratikp at codeaurora.org>");
 MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h
index 6bec20a392b3..11441c6b9c26 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.h
+++ b/drivers/hwtracing/coresight/coresight-tmc.h
@@ -7,9 +7,9 @@
 #ifndef _CORESIGHT_TMC_H
 #define _CORESIGHT_TMC_H
 
+#include <linux/cdev.h>
 #include <linux/dma-mapping.h>
 #include <linux/idr.h>
-#include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
 
@@ -163,11 +163,16 @@ struct etr_buf {
 	void				*private;
 };
 
+struct tmc_cdev {
+	struct cdev cdev;
+	struct device *dev;
+};
+
 /**
  * struct tmc_drvdata - specifics associated to an TMC component
  * @base:	memory mapped base address for this component.
  * @csdev:	component vitals needed by the framework.
- * @miscdev:	specifics to handle "/dev/xyz.tmc" entry.
+ * @tmc_cdev:	specifics to handle "/dev/xyz.tmc" entry.
  * @spinlock:	only one at a time pls.
  * @pid:	Process ID of the process being monitored by the session
  *		that is using this component.
@@ -191,7 +196,7 @@ struct etr_buf {
 struct tmc_drvdata {
 	void __iomem		*base;
 	struct coresight_device	*csdev;
-	struct miscdevice	miscdev;
+	struct tmc_cdev		cdev;
 	spinlock_t		spinlock;
 	pid_t			pid;
 	bool			reading;
-- 
2.27.0



From vkoul at kernel.org  Wed Jan 26 22:42:26 2022
From: vkoul at kernel.org (Vinod Koul)
Date: Thu, 27 Jan 2022 12:12:26 +0530
Subject: [PATCH] phy: phy-mtk-tphy: Fix dumplicated argument in
 phy-mtk-tphy
In-Reply-To: <20220107025050.787720-1-wanjiabing@vivo.com>
References: <20220107025050.787720-1-wanjiabing@vivo.com>
Message-ID: <YfI+0uzGZDLig+zC@matsya>

On 07-01-22, 10:50, Wan Jiabing wrote:
> Fix following coccicheck warning:
> ./drivers/phy/mediatek/phy-mtk-tphy.c:994:6-29: duplicated argument
> to && or ||
> 
> The efuse_rx_imp is duplicate. Here should be efuse_tx_imp.

Applied, thanks

-- 
~Vinod


From reijiw at google.com  Wed Jan 26 23:19:17 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Wed, 26 Jan 2022 23:19:17 -0800
Subject: [RFC PATCH v4 20/26] KVM: arm64: Trap disabled features of
 ID_AA64PFR0_EL1
In-Reply-To: <CA+EHjTy4L37G89orJ+cPTTZdFUehxNSMy0Pd36PW41JKVB0ohA@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-21-reijiw@google.com>
 <CA+EHjTy4L37G89orJ+cPTTZdFUehxNSMy0Pd36PW41JKVB0ohA@mail.gmail.com>
Message-ID: <CAAeT=Fx1pM66cQaefkBTAJ7-Y0nzjmABJrp5DiNm4_47hdEyrg@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 9:17 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Add feature_config_ctrl for RAS and AMU, which are indicated in
> > ID_AA64PFR0_EL1, to program configuration registers to trap
> > guest's using those features when they are not exposed to the guest.
> >
> > Introduce trap_ras_regs() to change a behavior of guest's access to
> > the registers, which is currently raz/wi, depending on the feature's
> > availability for the guest (and inject undefined instruction
> > exception when guest's RAS register access are trapped and RAS is
> > not exposed to the guest).  In order to keep the current visibility
> > of the RAS registers from userspace (always visible), a visibility
> > function for RAS registers is not added.
> >
> > No code is added for AMU's access/visibility handler because the
> > current code already injects the exception for Guest's AMU register
> > access unconditionally because AMU is never exposed to the guest.
>
> I think it might be code to trap it anyway, in case AMU guest support
> is added in the future.

Yes, I will fix it.
(I forgot to update the comment above...)


> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 90 +++++++++++++++++++++++++++++++++++----
> >  1 file changed, 82 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 33893a501475..015d67092d5e 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -304,6 +304,63 @@ struct feature_config_ctrl {
> >         void    (*trap_activate)(struct kvm_vcpu *vcpu);
> >  };
> >
> > +enum vcpu_config_reg {
> > +       VCPU_HCR_EL2 = 1,
> > +       VCPU_MDCR_EL2,
> > +       VCPU_CPTR_EL2,
> > +};
> > +
> > +static void feature_trap_activate(struct kvm_vcpu *vcpu,
> > +                                 enum vcpu_config_reg cfg_reg,
> > +                                 u64 cfg_set, u64 cfg_clear)
> > +{
> > +       u64 *reg_ptr, reg_val;
> > +
> > +       switch (cfg_reg) {
> > +       case VCPU_HCR_EL2:
> > +               reg_ptr = &vcpu->arch.hcr_el2;
> > +               break;
> > +       case VCPU_MDCR_EL2:
> > +               reg_ptr = &vcpu->arch.mdcr_el2;
> > +               break;
> > +       case VCPU_CPTR_EL2:
> > +               reg_ptr = &vcpu->arch.cptr_el2;
> > +               break;
> > +       }
> > +
> > +       /* Clear/Set fields that are indicated by cfg_clear/cfg_set. */
> > +       reg_val = (*reg_ptr & ~cfg_clear);
> > +       reg_val |= cfg_set;
> > +       *reg_ptr = reg_val;
> > +}
> > +
> > +static void feature_ras_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TERR | HCR_TEA, HCR_FIEN);
>
> Covers all the flags for ras.
>
> > +}
> > +
> > +static void feature_amu_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_CPTR_EL2, CPTR_EL2_TAM, 0);
>
> Covers the CPTR flags for AMU, but as you mentioned, does not
> explicitly clear HCR_AMVOFFEN.

In my understanding, clearing HCR_EL2.AMVOFFEN is not necessary as
CPTR_EL2.TAM == 1 traps the guest's accessing AMEVCNTR0<n>_EL0 and
AMEVCNTR1<n>_EL0 anyway (HCR_EL2.AMVOFFEN doesn't matter).
(Or is my understanding wrong ??)

Thanks,
Reiji


From krzysztof.kozlowski at canonical.com  Wed Jan 26 23:28:56 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 27 Jan 2022 08:28:56 +0100
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
In-Reply-To: <20220126231427.1638089-1-robh@kernel.org>
References: <20220126231427.1638089-1-robh@kernel.org>
Message-ID: <f0bd9681-c87b-a6bf-09af-05e45b0b9707@canonical.com>

On 27/01/2022 00:14, Rob Herring wrote:
> 'sound-dai' is a common property, but has duplicate type definitions.
> Create a new common definition to define the type and then update all
> the other occurrences to just define how many entries there are just
> like other phandle+arg properties.
> 
> The constraints on the number of entries is based on the examples and
> could be wrong.
> 
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> Please ack, this depends on commit abf0fee97313 ("dt-bindings: Improve
> phandle-array schemas") in my tree.
> ---
>  .../bindings/sound/amlogic,gx-sound-card.yaml |  4 ++--
>  .../bindings/sound/google,sc7180-trogdor.yaml |  6 ++++--
>  .../bindings/sound/imx-audio-card.yaml        |  7 +++++--
>  .../bindings/sound/qcom,sm8250.yaml           | 10 +++++++---
>  .../bindings/sound/samsung,aries-wm8994.yaml  |  5 +----
>  .../bindings/sound/samsung,midas-audio.yaml   |  2 --
>  .../bindings/sound/samsung,odroid.yaml        |  9 +++------
>  .../devicetree/bindings/sound/sound-dai.yaml  | 20 +++++++++++++++++++
>  8 files changed, 42 insertions(+), 21 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml
> 


Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


Best regards,
Krzysztof


From arnd at arndb.de  Wed Jan 26 23:55:12 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 27 Jan 2022 08:55:12 +0100
Subject: [PATCH 00/13] IXP4xx spring cleaning
In-Reply-To: <20220127003656.330161-1-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
Message-ID: <CAK8P3a1xgEUF_LZU4nO3tn-OO=HuhUUqpUEuoGpC5uAmwzVM0w@mail.gmail.com>

On Thu, Jan 27, 2022 at 1:36 AM Linus Walleij <linus.walleij at linaro.org> wrote:
>
> This cleans out the remaining board files from IXP4xx and
> makes it an exclusive device tree subarchitecture without any
> special weirdness in arch/arm/mach-ixp4xx.
>
> The biggest noticeable change is the removal of the old PCI
> driver and along with that the removal of the special DMA
> coherency code and defines and the DMA bouncing.

Very nice!

> I tried to convert the IXP4xx to multiplatform on top of
> this but it didn't work because IXP4xx wants to be big
> endian and multiplatform config creates a problem like
> this:
>
> ../arch/arm/kernel/head.S: Assembler messages:
> ../arch/arm/kernel/head.S:94: Error: selected processor does not support `setend be' in ARM mode
>
> I think this is because MULTI_V5 turns on CPUs that cannot
> do big endian, and IXP4xx turn on big endian.

The issue appears to be some mixup between BE8 and BE32 mode,
as this instruction only available on ARMv6 and higher with their
moder BE8 mode, while ARMv5 used the old-style BE32 mode that
does not have the setend instruction. I don't know how you got
to a configuration with BE8 mode on ARMv5, but I'm sure this can
be solved.

> (It crashes if I try to boot in little endian mode, sorry. It really
> wants to run big endian.)

My best guess is that this is caused by drivers using the "wrong"
register accessors, it should be possible to fix as well, but
would likely need fixes in a lot of files. I don't know what the
right way to do register accesses on BE8 is any more, but
apparently ixp4xx was working both ways in the past. It would
be nice to be able to run Debian armel user space.

      Arnd


From kavyasree.kotagiri at microchip.com  Thu Jan 27 00:04:08 2022
From: kavyasree.kotagiri at microchip.com (Kavyasree Kotagiri)
Date: Thu, 27 Jan 2022 13:34:08 +0530
Subject: [PATCH] crypto: atmel: add support for AES and SHA IPs available on
 lan966x SoC
Message-ID: <20220127080408.15791-1-kavyasree.kotagiri@microchip.com>

This patch adds support for hardware version of AES and SHA IPs
available on lan966x SoC.

Tested-by: Vradha Panchal <vradha.panchal at microchip.com>
Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
---
 drivers/crypto/atmel-aes.c | 2 ++
 drivers/crypto/atmel-sha.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index fe0558403191..358f1092d890 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -2509,6 +2509,8 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
 
 	/* keep only major version number */
 	switch (dd->hw_version & 0xff0) {
+	case 0x700:
+		fallthrough;
 	case 0x500:
 		dd->caps.has_dualbuff = 1;
 		dd->caps.has_cfb64 = 1;
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 1b13f601fd95..6c7bb91c8cce 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -2508,6 +2508,8 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
 
 	/* keep only major version number */
 	switch (dd->hw_version & 0xff0) {
+	case 0x700:
+		fallthrough;
 	case 0x510:
 		dd->caps.has_dma = 1;
 		dd->caps.has_dualbuff = 1;
-- 
2.17.1



From houtao1 at huawei.com  Thu Jan 27 00:10:33 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 16:10:33 +0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <61f23655411bc_57f032084@john.notmuch>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
 <61f23655411bc_57f032084@john.notmuch>
Message-ID: <8b67fa3d-f83c-85a5-5159-70b0f913833a@huawei.com>

Hi,

On 1/27/2022 2:06 PM, John Fastabend wrote:
> Hou Tao wrote:
>> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
>> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
>> it only add support for x86-64, so support these atomic operations
>> for arm64 as well.
>>
>> +static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
>> +{
>> +	const u8 code = insn->code;
>> +	const u8 dst = bpf2a64[insn->dst_reg];
>> +	const u8 src = bpf2a64[insn->src_reg];
>> +	const u8 tmp = bpf2a64[TMP_REG_1];
>> +	const u8 tmp2 = bpf2a64[TMP_REG_2];
>> +	const bool isdw = BPF_SIZE(code) == BPF_DW;
>> +	const s16 off = insn->off;
>> +	u8 reg;
>> +
>> +	if (!off) {
>> +		reg = dst;
>> +	} else {
>> +		emit_a64_mov_i(1, tmp, off, ctx);
>> +		emit(A64_ADD(1, tmp, tmp, dst), ctx);
>> +		reg = tmp;
>> +	}
>> +
>> +	switch (insn->imm) {
> Diff'ing X86 implementation which has a BPF_SUB case how is it avoided
> here?
I think it is just left over from patchset [1], because according to the LLVM
commit [2]
__sync_fetch_and_sub(&addr, value) is implemented by __sync_fetch_and_add(&addr,
-value).
I will post a patch to remove it.

[1]: https://lore.kernel.org/bpf/20210114181751.768687-1-jackmanb at google.com/
[2]: https://reviews.llvm.org/D72184
>> +	/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
>> +	case BPF_ADD:
>> +		emit(A64_STADD(isdw, reg, src), ctx);
>> +		break;
>> +	case BPF_AND:
>> +		emit(A64_MVN(isdw, tmp2, src), ctx);
>> +		emit(A64_STCLR(isdw, reg, tmp2), ctx);
>> +		break;
>> +	case BPF_OR:
>> +		emit(A64_STSET(isdw, reg, src), ctx);
>> +		break;
>> +	case BPF_XOR:
>> +		emit(A64_STEOR(isdw, reg, src), ctx);
>> +		break;
>> +	/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
>> +	case BPF_ADD | BPF_FETCH:
>> +		emit(A64_LDADDAL(isdw, src, reg, src), ctx);
>> +		break;
>> +	case BPF_AND | BPF_FETCH:
>> +		emit(A64_MVN(isdw, tmp2, src), ctx);
>> +		emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
>> +		break;
>> +	case BPF_OR | BPF_FETCH:
>> +		emit(A64_LDSETAL(isdw, src, reg, src), ctx);
>> +		break;
>> +	case BPF_XOR | BPF_FETCH:
>> +		emit(A64_LDEORAL(isdw, src, reg, src), ctx);
>> +		break;
>> +	/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
>> +	case BPF_XCHG:
>> +		emit(A64_SWPAL(isdw, src, reg, src), ctx);
>> +		break;
>> +	/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
>> +	case BPF_CMPXCHG:
>> +		emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
>> +		break;
>> +	default:
>> +		pr_err_once("unknown atomic op code %02x\n", insn->imm);
>> +		return -EINVAL;
> Was about to suggest maybe EFAULT to align with x86, but on second
> thought seems arm jit uses EINVAL more universally so best to be
> self consistent. Just an observation.
OK. So I will still return -EINVAL for invalid atomic operation.
>
>> +	}
>> +
>> +	return 0;
>> +}
>> +
> .



From hverkuil at xs4all.nl  Thu Jan 27 00:46:45 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Thu, 27 Jan 2022 09:46:45 +0100
Subject: [PATCH V4 02/11] dt-bindings: power: imx8mq: add defines for VPU
 blk-ctrl domains
In-Reply-To: <20220125171129.472775-3-aford173@gmail.com>
References: <20220125171129.472775-1-aford173@gmail.com>
 <20220125171129.472775-3-aford173@gmail.com>
Message-ID: <43e29322-fc4d-2c72-86b2-1f41fb05a2f9@xs4all.nl>

Shawn,

Can you take patches 2-4 of this series or shall I? In the latter case I
need your Acked-by for these three patches.

Regards,

	Hans

On 25/01/2022 18:11, Adam Ford wrote:
> From: Lucas Stach <l.stach at pengutronix.de>
> 
> This adds the defines for the power domains provided by the VPU
> blk-ctrl on the i.MX8MQ.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
> Acked-by: Rob Herring <robh at kernel.org>
> 
> diff --git a/include/dt-bindings/power/imx8mq-power.h b/include/dt-bindings/power/imx8mq-power.h
> index 8a513bd9166e..9f7d0f1e7c32 100644
> --- a/include/dt-bindings/power/imx8mq-power.h
> +++ b/include/dt-bindings/power/imx8mq-power.h
> @@ -18,4 +18,7 @@
>  #define IMX8M_POWER_DOMAIN_MIPI_CSI2	9
>  #define IMX8M_POWER_DOMAIN_PCIE2	10
>  
> +#define IMX8MQ_VPUBLK_PD_G1		0
> +#define IMX8MQ_VPUBLK_PD_G2		1
> +
>  #endif



From xiongx18 at fudan.edu.cn  Thu Jan 27 00:41:05 2022
From: xiongx18 at fudan.edu.cn (Xin Xiong)
Date: Thu, 27 Jan 2022 16:41:05 +0800
Subject: [PATCH] mtd: rawnand: atmel: fix refcount issue in
 atmel_nand_controller_init
Message-ID: <20220127084104.3683-1-xiongx18@fudan.edu.cn>

The reference counting issue happens in several error handling paths
on a refcounted object "nc->dmac". In these paths, the function simply
returns the error code, forgetting to balance the reference count of
"nc->dmac", increased earlier by dma_request_channel(), which may
cause refcount leaks.

Fix it by decrementing the refcount of specific object in those error
paths.

Fixes: f88fc122cc34 ("mtd: nand: Cleanup/rework the atmel_nand driver")
Co-developed-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
Signed-off-by: Xiyu Yang <xiyuyang19 at fudan.edu.cn>
Co-developed-by: Xin Tan <tanxin.ctf at gmail.com>
Signed-off-by: Xin Tan <tanxin.ctf at gmail.com>
Signed-off-by: Xin Xiong <xiongx18 at fudan.edu.cn>
---
 drivers/mtd/nand/raw/atmel/nand-controller.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index f3276ee9e4fe..7003877632fb 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -2060,13 +2060,15 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
 	nc->mck = of_clk_get(dev->parent->of_node, 0);
 	if (IS_ERR(nc->mck)) {
 		dev_err(dev, "Failed to retrieve MCK clk\n");
-		return PTR_ERR(nc->mck);
+		ret = PTR_ERR(nc->mck);
+		goto out_release_dma;
 	}
 
 	np = of_parse_phandle(dev->parent->of_node, "atmel,smc", 0);
 	if (!np) {
 		dev_err(dev, "Missing or invalid atmel,smc property\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_release_dma;
 	}
 
 	nc->smc = syscon_node_to_regmap(np);
@@ -2074,10 +2076,20 @@ static int atmel_nand_controller_init(struct atmel_nand_controller *nc,
 	if (IS_ERR(nc->smc)) {
 		ret = PTR_ERR(nc->smc);
 		dev_err(dev, "Could not get SMC regmap (err = %d)\n", ret);
-		return ret;
+		goto out_release_dma;
 	}
 
 	return 0;
+
+out_release_dma:
+	if (nc->caps->has_dma && !atmel_nand_avoid_dma) {
+		if (!IS_ERR_OR_NULL(nc->dmac)) {
+			dma_release_channel(nc->dmac);
+			nc->dmac = NULL;
+		}
+	}
+
+	return ret;
 }
 
 static int
-- 
2.25.1



From chunfeng.yun at mediatek.com  Thu Jan 27 00:59:30 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Thu, 27 Jan 2022 16:59:30 +0800
Subject: [PATCH v3] dt-bindings: nvmem: convert mtk-efuse.txt to YAML schema
Message-ID: <20220127085930.15637-1-chunfeng.yun@mediatek.com>

Convert mtk-efuse.txt to YAML schema mediatek,efuse.yaml

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
v3: add reviewed-by Rob

v2:
  1. remove description of subnodes which is covered by nvmem.yaml suggested by Rob
  2. change the example which is commoner than mt8173's
---
 .../bindings/nvmem/mediatek,efuse.yaml        | 86 +++++++++++++++++++
 .../devicetree/bindings/nvmem/mtk-efuse.txt   | 43 ----------
 2 files changed, 86 insertions(+), 43 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml
 delete mode 100644 Documentation/devicetree/bindings/nvmem/mtk-efuse.txt

diff --git a/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml b/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml
new file mode 100644
index 000000000000..0f592c36431c
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/mediatek,efuse.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek efuse device tree bindings
+
+description: |
+  MediaTek's efuse is used for storing calibration data, it can be accessed
+  on ARM devices usiong I/O mapped memory.
+
+maintainers:
+  - Andrew-CT Chen <andrew-ct.chen at mediatek.com>
+
+allOf:
+  - $ref: "nvmem.yaml#"
+
+properties:
+  $nodename:
+    pattern: "^efuse@[0-9a-f]+$"
+
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - mediatek,mt7622-efuse
+              - mediatek,mt7623-efuse
+              - mediatek,mt8173-efuse
+              - mediatek,mt8192-efuse
+              - mediatek,mt8195-efuse
+              - mediatek,mt8516-efuse
+          - const: mediatek,efuse
+      - const: mediatek,mt8173-efuse
+        deprecated: true
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    efuse at 11c10000 {
+        compatible = "mediatek,mt8195-efuse", "mediatek,efuse";
+        reg = <0x11c10000 0x1000>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        u3_tx_imp_p0: usb3-tx-imp at 184 {
+            reg = <0x184 0x1>;
+            bits = <0 5>;
+        };
+        u3_rx_imp_p0: usb3-rx-imp at 184 {
+            reg = <0x184 0x2>;
+            bits = <5 5>;
+        };
+        u3_intr_p0: usb3-intr at 185 {
+            reg = <0x185 0x1>;
+            bits = <2 6>;
+        };
+        comb_tx_imp_p1: usb3-tx-imp at 186 {
+            reg = <0x186 0x1>;
+            bits = <0 5>;
+        };
+        comb_rx_imp_p1: usb3-rx-imp at 186 {
+            reg = <0x186 0x2>;
+            bits = <5 5>;
+        };
+        comb_intr_p1: usb3-intr at 187 {
+            reg = <0x187 0x1>;
+            bits = <2 6>;
+        };
+        u2_intr_p0: usb2-intr-p0 at 188 {
+            reg = <0x188 0x1>;
+            bits = <0 5>;
+        };
+        u2_intr_p1: usb2-intr-p1 at 188 {
+            reg = <0x188 0x2>;
+            bits = <5 5>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt b/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
deleted file mode 100644
index 39d529599444..000000000000
--- a/Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-= Mediatek MTK-EFUSE device tree bindings =
-
-This binding is intended to represent MTK-EFUSE which is found in most Mediatek SOCs.
-
-Required properties:
-- compatible: should be
-	      "mediatek,mt7622-efuse", "mediatek,efuse": for MT7622
-	      "mediatek,mt7623-efuse", "mediatek,efuse": for MT7623
-	      "mediatek,mt8173-efuse" or "mediatek,efuse": for MT8173
-	      "mediatek,mt8192-efuse", "mediatek,efuse": for MT8192
-	      "mediatek,mt8195-efuse", "mediatek,efuse": for MT8195
-	      "mediatek,mt8516-efuse", "mediatek,efuse": for MT8516
-- reg: Should contain registers location and length
-- bits: contain the bits range by offset and size
-
-= Data cells =
-Are child nodes of MTK-EFUSE, bindings of which as described in
-bindings/nvmem/nvmem.txt
-
-Example:
-
-	efuse: efuse at 10206000 {
-		compatible = "mediatek,mt8173-efuse";
-		reg	   = <0 0x10206000 0 0x1000>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-
-		/* Data cells */
-		thermal_calibration: calib at 528 {
-			reg = <0x528 0xc>;
-		};
-	};
-
-= Data consumers =
-Are device nodes which consume nvmem data cells.
-
-For example:
-
-	thermal {
-		...
-		nvmem-cells = <&thermal_calibration>;
-		nvmem-cell-names = "calibration";
-	};
-- 
2.18.0



From a-govindraju at ti.com  Thu Jan 27 01:02:25 2022
From: a-govindraju at ti.com (Aswath Govindraju)
Date: Thu, 27 Jan 2022 14:32:25 +0530
Subject: [PATCH] arm64: dts: ti: k3-j721e-common-proc-board: Enable PCIe +
 QSGMII multilink configuration
Message-ID: <20220127090226.11481-1-a-govindraju@ti.com>

From: Swapnil Jakhade <sjakhade at cadence.com>

Enable PCIe + QSGMII multilink configuration for serdes 0. This is for
testing Sierra PHY multilink configuration.
Add support for PLL_CMNLC1 to get clock from REFRCV1 for multilink case.

Signed-off-by: Swapnil Jakhade <sjakhade at cadence.com>
Signed-off-by: Aswath Govindraju <a-govindraju at ti.com>
---
 .../boot/dts/ti/k3-j721e-common-proc-board.dts    | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
index 2d7596911b27..157d86dc2824 100644
--- a/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
+++ b/arch/arm64/boot/dts/ti/k3-j721e-common-proc-board.dts
@@ -431,7 +431,7 @@
 };
 
 &serdes_ln_ctrl {
-	idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_PCIE0_LANE1>,
+	idle-states = <J721E_SERDES0_LANE0_PCIE0_LANE0>, <J721E_SERDES0_LANE1_QSGMII_LANE2>,
 		      <J721E_SERDES1_LANE0_PCIE1_LANE0>, <J721E_SERDES1_LANE1_PCIE1_LANE1>,
 		      <J721E_SERDES2_LANE0_PCIE2_LANE0>, <J721E_SERDES2_LANE1_PCIE2_LANE1>,
 		      <J721E_SERDES3_LANE0_USB3_0_SWAP>, <J721E_SERDES3_LANE1_USB3_0>,
@@ -757,8 +757,8 @@
 };
 
 &serdes0 {
-	assigned-clocks = <&serdes0 CDNS_SIERRA_PLL_CMNLC>;
-	assigned-clock-parents = <&wiz0_pll1_refclk>;
+	assigned-clocks = <&serdes0 CDNS_SIERRA_PLL_CMNLC>, <&serdes0 CDNS_SIERRA_PLL_CMNLC1>;
+	assigned-clock-parents = <&wiz0_pll1_refclk>, <&wiz0_pll1_refclk>;
 
 	serdes0_pcie_link: phy at 0 {
 		reg = <0>;
@@ -767,6 +767,15 @@
 		cdns,phy-type = <PHY_TYPE_PCIE>;
 		resets = <&serdes_wiz0 1>;
 	};
+
+	serdes0_qsgmii_link: phy at 1 {
+		reg = <1>;
+		cdns,num-lanes = <1>;
+		#phy-cells = <0>;
+		cdns,phy-type = <PHY_TYPE_QSGMII>;
+		resets = <&serdes_wiz0 2>;
+	};
+
 };
 
 &serdes1 {
-- 
2.17.1



From jbrunet at baylibre.com  Thu Jan 27 01:00:53 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 27 Jan 2022 10:00:53 +0100
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
In-Reply-To: <20220126231427.1638089-1-robh@kernel.org>
References: <20220126231427.1638089-1-robh@kernel.org>
Message-ID: <1jtudp1rc1.fsf@starbuckisacylon.baylibre.com>


On Wed 26 Jan 2022 at 17:14, Rob Herring <robh at kernel.org> wrote:

> 'sound-dai' is a common property, but has duplicate type definitions.
> Create a new common definition to define the type and then update all
> the other occurrences to just define how many entries there are just
> like other phandle+arg properties.
>
> The constraints on the number of entries is based on the examples and
> could be wrong.
>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
> Please ack, this depends on commit abf0fee97313 ("dt-bindings: Improve
> phandle-array schemas") in my tree.
> ---
>  .../bindings/sound/amlogic,gx-sound-card.yaml |  4 ++--
>  .../bindings/sound/google,sc7180-trogdor.yaml |  6 ++++--
>  .../bindings/sound/imx-audio-card.yaml        |  7 +++++--
>  .../bindings/sound/qcom,sm8250.yaml           | 10 +++++++---
>  .../bindings/sound/samsung,aries-wm8994.yaml  |  5 +----
>  .../bindings/sound/samsung,midas-audio.yaml   |  2 --
>  .../bindings/sound/samsung,odroid.yaml        |  9 +++------
>  .../devicetree/bindings/sound/sound-dai.yaml  | 20 +++++++++++++++++++
>  8 files changed, 42 insertions(+), 21 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> index 2e35aeaa8781..8b5be4b92f35 100644
> --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> @@ -57,7 +57,7 @@ patternProperties:
>            rate
>  
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
> +        maxItems: 1
>          description: phandle of the CPU DAI
>  
>      patternProperties:
> @@ -71,7 +71,7 @@ patternProperties:
>  
>          properties:
>            sound-dai:
> -            $ref: /schemas/types.yaml#/definitions/phandle-array
> +            maxItems: 1

No min or max here. Links may have more than one codec.

Ex:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#n158

>              description: phandle of the codec DAI
>  
>          required:
> diff --git a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
> index 837e3faa63a9..233caa0ade87 100644
> --- a/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
> +++ b/Documentation/devicetree/bindings/sound/google,sc7180-trogdor.yaml
> @@ -62,13 +62,15 @@ patternProperties:
>          description: Holds subnode which indicates cpu dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            maxItems: 1
>  
>        codec:
>          description: Holds subnode which indicates codec dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            maxItems: 1
>  
>      required:
>        - link-name
> diff --git a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
> index d1816dd061cf..bb3a435722c7 100644
> --- a/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
> +++ b/Documentation/devicetree/bindings/sound/imx-audio-card.yaml
> @@ -59,13 +59,16 @@ patternProperties:
>          description: Holds subnode which indicates cpu dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            maxItems: 1
>  
>        codec:
>          description: Holds subnode which indicates codec dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            minItems: 1
> +            maxItems: 2
>  
>        fsl,mclk-equal-bclk:
>          description: Indicates mclk can be equal to bclk, especially for sai interface
> diff --git a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
> index 4bfda04b4608..4ecd4080bb96 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,sm8250.yaml
> @@ -69,19 +69,23 @@ patternProperties:
>          description: Holds subnode which indicates cpu dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            maxItems: 1
>  
>        platform:
>          description: Holds subnode which indicates platform dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            maxItems: 1
>  
>        codec:
>          description: Holds subnode which indicates codec dai.
>          type: object
>          properties:
> -          sound-dai: true
> +          sound-dai:
> +            minItems: 1
> +            maxItems: 4
>  
>      required:
>        - link-name
> diff --git a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
> index eb487ed3ca3b..4ffa275b3c49 100644
> --- a/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
> +++ b/Documentation/devicetree/bindings/sound/samsung,aries-wm8994.yaml
> @@ -27,9 +27,6 @@ properties:
>        sound-dai:
>          minItems: 2
>          maxItems: 2
> -        items:
> -          maxItems: 1
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
>          description: |
>            phandles to the I2S controller and bluetooth codec,
>            in that order
> @@ -38,7 +35,7 @@ properties:
>      type: object
>      properties:
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
> +        maxItems: 1
>          description: phandle to the WM8994 CODEC
>  
>    samsung,audio-routing:
> diff --git a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
> index 095775c598fa..ec50bcb4af5f 100644
> --- a/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
> +++ b/Documentation/devicetree/bindings/sound/samsung,midas-audio.yaml
> @@ -21,7 +21,6 @@ properties:
>      type: object
>      properties:
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
>          maxItems: 1
>          description: phandle to the I2S controller
>      required:
> @@ -31,7 +30,6 @@ properties:
>      type: object
>      properties:
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
>          maxItems: 1
>          description: phandle to the WM1811 CODEC
>      required:
> diff --git a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
> index e8122bc87362..db2513f3e168 100644
> --- a/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
> +++ b/Documentation/devicetree/bindings/sound/samsung,odroid.yaml
> @@ -37,18 +37,15 @@ properties:
>      type: object
>      properties:
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
>          description: phandles to the I2S controllers
>  
>    codec:
>      type: object
>      properties:
>        sound-dai:
> -        $ref: /schemas/types.yaml#/definitions/phandle-array
> -        description: |
> -          List of phandles to the CODEC nodes,
> -          first entry must be corresponding to the MAX98090 CODEC and
> -          the second entry must be the phandle of the HDMI IP block node.
> +        items:
> +          - description: phandle of the MAX98090 CODEC
> +          - description: phandle of the HDMI IP block node
>  
>    samsung,audio-routing:
>      $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> diff --git a/Documentation/devicetree/bindings/sound/sound-dai.yaml b/Documentation/devicetree/bindings/sound/sound-dai.yaml
> new file mode 100644
> index 000000000000..61c6f7abc4e7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/sound-dai.yaml
> @@ -0,0 +1,20 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/sound-dai.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Digital Audio Interface consumer Device Tree Bindings
> +
> +maintainers:
> +  - Rob Herring <robh at kernel.org>
> +
> +select: true
> +
> +properties:
> +  sound-dai:
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    description: A phandle plus args to digital audio interface provider(s)
> +
> +additionalProperties: true
> +...



From cristian.marussi at arm.com  Thu Jan 27 01:07:59 2022
From: cristian.marussi at arm.com (Cristian Marussi)
Date: Thu, 27 Jan 2022 09:07:59 +0000
Subject: [PATCH 1/6] firmware: arm_scmi: Add atomic mode support to
 virtio transport
In-Reply-To: <425e9a2b-a03f-a038-2598-33f28cd5f4e9@opensynergy.com>
References: <20220124100341.41191-1-cristian.marussi@arm.com>
 <20220124100341.41191-2-cristian.marussi@arm.com>
 <425e9a2b-a03f-a038-2598-33f28cd5f4e9@opensynergy.com>
Message-ID: <20220127090759.GA5776@e120937-lin>

On Wed, Jan 26, 2022 at 03:28:52PM +0100, Peter Hilber wrote:
> On 24.01.22 11:03, Cristian Marussi wrote:
> > Add support for .mark_txdone and .poll_done transport operations to SCMI
> > VirtIO transport as pre-requisites to enable atomic operations.
> > 
> > Add a Kernel configuration option to enable SCMI VirtIO transport polling
> > and atomic mode for selected SCMI transactions while leaving it default
> > disabled.
> > 
> 
> Hi Cristian,
> 

Hi Peter,

> please see one remark below.
> 
> Best regards,
> 
> Peter
> 
> > Cc: "Michael S. Tsirkin" <mst at redhat.com>
> > Cc: Igor Skalkin <igor.skalkin at opensynergy.com>
> > Cc: Peter Hilber <peter.hilber at opensynergy.com>
> > Cc: virtualization at lists.linux-foundation.org
> > Signed-off-by: Cristian Marussi <cristian.marussi at arm.com>
> > ---

[snip]

> > +/**
> > + * virtio_poll_done  - Provide polling support for VirtIO transport
> > + *
> > + * @cinfo: SCMI channel info
> > + * @xfer: Reference to the transfer being poll for.
> > + *
> > + * VirtIO core provides a polling mechanism based only on last used indexes:
> > + * this means that it is possible to poll the virtqueues waiting for something
> > + * new to arrive from the host side but the only way to check if the freshly
> > + * arrived buffer was what we were waiting for is to compare the newly arrived
> > + * message descriptors with the one we are polling on.
> > + *
> > + * As a consequence it can happen to dequeue something different from the buffer
> > + * we were poll-waiting for: if that is the case such early fetched buffers are
> > + * then added to a the @pending_cmds_list list for later processing by a
> > + * dedicated deferred worker.
> > + *
> > + * So, basically, once something new is spotted we proceed to de-queue all the
> > + * freshly received used buffers until we found the one we were polling on, or,
> > + * we have 'seemingly' emptied the virtqueue; if some buffers are still pending
> > + * in the vqueue at the end of the polling loop (possible due to inherent races
> > + * in virtqueues handling mechanisms), we similarly kick the deferred worker
> > + * and let it process those, to avoid indefinitely looping in the .poll_done
> > + * helper.
> > + *
> > + * Note that, since we do NOT have per-message suppress notification mechanism,
> > + * the message we are polling for could be delivered via usual IRQs callbacks
> > + * on another core which happened to have IRQs enabled: in such case it will be
> > + * handled as such by scmi_rx_callback() and the polling loop in the
> > + * SCMI Core TX path will be transparently terminated anyway.
> > + *
> > + * Return: True once polling has successfully completed.
> > + */
> > +static bool virtio_poll_done(struct scmi_chan_info *cinfo,
> > +			     struct scmi_xfer *xfer)
> > +{
> > +	bool pending, ret = false;
> > +	unsigned int length, any_prefetched = 0;
> > +	unsigned long flags;
> > +	struct scmi_vio_msg *next_msg, *msg = xfer->priv;
> > +	struct scmi_vio_channel *vioch = cinfo->transport_info;
> > +
> > +	if (!msg)
> > +		return true;
> > +
> > +	spin_lock_irqsave(&vioch->lock, flags);
> 
> If now acquiring vioch->lock here, I see no need to virtqueue_poll() any more.
> After checking msg->poll_status, we could just directly try virtqueue_get_buf().
> 
> On the other hand, always taking the vioch->lock in a busy loop might better be
> avoided (I assumed before that taking it was omitted on purpose), since it
> might hamper tx channel progress in other cores (but I'm not sure about the
> actual impact).
> 
> Also, I don't yet understand why the vioch->lock would need to be taken here.

There was a race I could reproduce between the below check against
VIO_MSG_POLL_DONE and the poll_idx later update near the end of the poll loop
where another thread could have set VIO_MSG_POLL_DONE after this thread
had checked it and then this same thread would have cleared it rewriting
the new poll_idx; so at first I needlessly enlanrged the spinlocked section
(even though I knew was subtopimal given virtqueue_poll does not need
serialization) and then forget to properly review this thing.

BUT now that, following your suggestion, I introduced a dedicated
poll_status that race is gone, so I shrinked back the spinlocked section
as before and works fine (even poll_idx itself does not need to be
protected really given it can be accessed only here)

I'll post the fix in -rc2 together with the core change in the
virtio-core I proposed last week to Michael (if not too costly as perfs)

Thanks,
Cristian


From piotr.oniszczuk at gmail.com  Thu Jan 27 01:17:13 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Thu, 27 Jan 2022 10:17:13 +0100
Subject: [PATCH 27/27] drm: rockchip: Add VOP2 driver
In-Reply-To: <20220126145549.617165-28-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-28-s.hauer@pengutronix.de>
Message-ID: <6588D77C-D3CB-4FB0-8B00-5EDD6ABD6923@gmail.com>

Sascha,

FYI 
small report regarding 4k modes support in v4:

-on rk3399 it gives me 4k screen where right vertical 1/3 part of screen is garbage
-on rk3566 my samsung 4k monitor has black screen and cycle of OSD msgs: HDMI2 connected; HDMI2 disconnected; ....

I would suggest split v4 into 2 separated series:

-VOP2 support
-HDMI 4k modes support

BTW: getting well working 4k HDMI modes on rk3399 was real story for me.
There is many different series of patches to address this - but all have some subtle issues for me (i.e. 4k HDMI modes works but i.e. Qt is failing with DRM atomic commits in EGLFS)
I developed well working [1] giving me reliable 4k on rk3399 (including working Qt DRM drawing in EGLFS mode) 
Maybe it will be somehow helpful to get 4k modes solution for rk3566 _and_ rk3399 (on single kernel binary)?

[1] https://github.com/warpme/minimyth2/blob/master/script/kernel/linux-5.16/files/0730-drm-rockchip-add-4k-videomodes-support.patch

br


> Wiadomo?? napisana przez Sascha Hauer <s.hauer at pengutronix.de> w dniu 26.01.2022, o godz. 15:55:
> 
> From: Andy Yan <andy.yan at rock-chips.com>
> 
> The VOP2 unit is found on Rockchip SoCs beginning with rk3566/rk3568.
> It replaces the VOP unit found in the older Rockchip SoCs.
> 
> This driver has been derived from the downstream Rockchip Kernel and
> heavily modified:
> 
> - All nonstandard DRM properties have been removed
> - dropped struct vop2_plane_state and pass around less data between
>  functions
> - Dropped all DRM_FORMAT_* not known on upstream
> - rework register access to get rid of excessively used macros
> - Drop all waiting for framesyncs
> 
> The driver is tested with HDMI and MIPI-DSI display on a RK3568-EVB
> board. Overlay support is tested with the modetest utility. AFBC support
> on the cluster windows is tested with weston-simple-dmabuf-egl on
> weston using the (yet to be upstreamed) panfrost driver support.
> 
> Changes since v3:
> - Sort includes
> - fix typos
> - Drop spinlock
> - Use regmap_set_bits()/regmap_clear_bits()
> - simplify vop2_scale_factor()
> - simplify vop2_afbc_transform_offset()
> 



From wenst at chromium.org  Thu Jan 27 01:23:56 2022
From: wenst at chromium.org (Chen-Yu Tsai)
Date: Thu, 27 Jan 2022 17:23:56 +0800
Subject: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
In-Reply-To: <20220127025544.10854-8-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
 <20220127025544.10854-8-yunfei.dong@mediatek.com>
Message-ID: <CAGXv+5ELuvvG6dwXH5DdHtjOm4j4AAVTk2UxGOitF5v5Vx265A@mail.gmail.com>

Hi,

On Thu, Jan 27, 2022 at 10:56 AM Yunfei Dong <yunfei.dong at mediatek.com> wrote:
>
> Init some of VP9 frame decode params to default value.
>
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

Maybe add

Fixes: b88dbe38dca8 ("media: uapi: Add VP9 stateless decoder controls")

> ---
>  drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
>
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index 54abe5245dcc..b25c77b8a445 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -112,6 +112,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>         struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
>         struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
>         struct v4l2_ctrl_vp8_frame *p_vp8_frame;
> +       struct v4l2_ctrl_vp9_frame *p_vp9_frame;
>         struct v4l2_ctrl_fwht_params *p_fwht_params;
>         void *p = ptr.p + idx * ctrl->elem_size;
>
> @@ -152,6 +153,13 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>                 p_vp8_frame = p;
>                 p_vp8_frame->num_dct_parts = 1;
>                 break;
> +       case V4L2_CTRL_TYPE_VP9_FRAME:
> +               p_vp9_frame = p;
> +               p_vp9_frame->profile = 0;
> +               p_vp9_frame->bit_depth = 8;
> +               p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
> +                       V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
> +               break;
>         case V4L2_CTRL_TYPE_FWHT_PARAMS:
>                 p_fwht_params = p;
>                 p_fwht_params->version = V4L2_FWHT_VERSION;
> --
> 2.25.1
>


From ardb at kernel.org  Thu Jan 27 01:29:31 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 10:29:31 +0100
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <20220125014422.80552-4-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
Message-ID: <CAMj1kXG5vQ6SmRPPYjd4gg4O7gtjQg_NCOtEjY_EZoCPohcf2w@mail.gmail.com>

On Tue, 25 Jan 2022 at 02:47, Nathan Huckleberry <nhuck at google.com> wrote:
>
> Add support for HCTR2 as a template.  HCTR2 is a length-preserving
> encryption mode that is efficient on processors with instructions to
> accelerate AES and carryless multiplication, e.g. x86 processors with
> AES-NI and CLMUL, and ARM processors with the ARMv8 Crypto Extensions.
>
> As a length-preserving encryption mode, HCTR2 is suitable for
> applications such as storage encryption where ciphertext expansion is
> not possible, and thus authenticated encryption cannot be used.
> Currently, such applications usually use XTS, or in some cases Adiantum.
> XTS has the disadvantage that it is a narrow-block mode: a bitflip will
> only change 16 bytes in the resulting ciphertext or plaintext.  This
> reveals more information to an attacker than necessary.
>
> HCTR2 is a wide-block mode, so it provides a stronger security property:
> a bitflip will change the entire message.  HCTR2 is somewhat similar to
> Adiantum, which is also a wide-block mode.  However, HCTR2 is designed
> to take advantage of existing crypto instructions, while Adiantum
> targets devices without such hardware support.  Adiantum is also
> designed with longer messages in mind, while HCTR2 is designed to be
> efficient even on short messages.
>
> HCTR2 requires POLYVAL and XCTR as components.  More information on
> HCTR2 can be found here: Length-preserving encryption with HCTR2:
> https://eprint.iacr.org/2021/1441.pdf
>
> Signed-off-by: Nathan Huckleberry <nhuck at google.com>
> ---
>  crypto/Kconfig   |  11 +
>  crypto/Makefile  |   1 +
>  crypto/hctr2.c   | 475 ++++++++++++++++++++++++++++
>  crypto/tcrypt.c  |   5 +
>  crypto/testmgr.c |   6 +
>  crypto/testmgr.h | 787 +++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 1285 insertions(+)
>  create mode 100644 crypto/hctr2.c
>
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 051060cd5e21..3cdb6c351062 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -524,6 +524,17 @@ config CRYPTO_ADIANTUM
>
>           If unsure, say N.
>
> +config CRYPTO_HCTR2
> +       tristate "HCTR2 support"
> +       select CRYPTO_XCTR
> +       select CRYPTO_POLYVAL
> +       select CRYPTO_MANAGER
> +       help
> +         HCTR2 is a length-preserving encryption mode that is efficient on
> +         processors with instructions to accelerate AES and carryless
> +         multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
> +         processors with the ARMv8 crypto extensions.
> +
>  config CRYPTO_ESSIV
>         tristate "ESSIV support for block encryption"
>         select CRYPTO_AUTHENC
> diff --git a/crypto/Makefile b/crypto/Makefile
> index 561f901a91d4..2dca9dbdede6 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -94,6 +94,7 @@ obj-$(CONFIG_CRYPTO_LRW) += lrw.o
>  obj-$(CONFIG_CRYPTO_XTS) += xts.o
>  obj-$(CONFIG_CRYPTO_CTR) += ctr.o
>  obj-$(CONFIG_CRYPTO_XCTR) += xctr.o
> +obj-$(CONFIG_CRYPTO_HCTR2) += hctr2.o
>  obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
>  obj-$(CONFIG_CRYPTO_ADIANTUM) += adiantum.o
>  obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
> diff --git a/crypto/hctr2.c b/crypto/hctr2.c
> new file mode 100644
> index 000000000000..af43f81b68f3
> --- /dev/null
> +++ b/crypto/hctr2.c
> @@ -0,0 +1,475 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * HCTR2 length-preserving encryption mode
> + *
> + * Copyright 2021 Google LLC

Off by one?

> + */
> +
> +
> +/*
> + * HCTR2 is a length-preserving encryption mode that is efficient on
> + * processors with instructions to accelerate aes and carryless
> + * multiplication, e.g. x86 processors with AES-NI and CLMUL, and ARM
> + * processors with the ARMv8 crypto extensions.
> + *
> + * Length-preserving encryption with HCTR2
> + *     (https://eprint.iacr.org/2021/1441.pdf)
> + *
> + *     HCTR2 has a strict set of requirements for the hash function. For this
> + *     purpose we only allow POLYVAL. To avoid misuse, XCTR is required as
> + *     specified in the HCTR2 paper, though theoretically there is a larger class
> + *     of algorithms that could be used.
> + */
> +
> +#include <crypto/internal/cipher.h>
> +#include <crypto/internal/hash.h>
> +#include <crypto/internal/skcipher.h>
> +#include <crypto/polyval.h>
> +#include <crypto/scatterwalk.h>
> +#include <linux/module.h>
> +
> +#define BLOCKCIPHER_BLOCK_SIZE         16
> +
> +/*
> + * The specification allows variable-length tweaks, but Linux's crypto API
> + * currently only allows algorithms to support a single length.  The "natural"
> + * tweak length for HCTR2 is 16, since that fits into one POLYVAL block for
> + * the best performance.  But longer tweaks are useful for fscrypt, to avoid
> + * needing to derive per-file keys.  So instead we use two blocks, or 32 bytes.
> + */
> +#define TWEAK_SIZE             32
> +
> +struct hctr2_instance_ctx {
> +       struct crypto_cipher_spawn blockcipher_spawn;
> +       struct crypto_skcipher_spawn streamcipher_spawn;
> +       struct crypto_shash_spawn hash_spawn;
> +};
> +
> +struct hctr2_tfm_ctx {
> +       struct crypto_cipher *blockcipher;
> +       struct crypto_skcipher *streamcipher;
> +       struct crypto_shash *hash;
> +       u8 L[BLOCKCIPHER_BLOCK_SIZE];
> +};
> +
> +struct hctr2_request_ctx {
> +       u8 first_block[BLOCKCIPHER_BLOCK_SIZE];
> +       struct scatterlist *bulk_part_dst;
> +       struct scatterlist *bulk_part_src;
> +       struct scatterlist sg_src[2];
> +       struct scatterlist sg_dst[2];
> +       /* Sub-requests, must be last */
> +       union {
> +               struct shash_desc hash_desc;
> +               struct skcipher_request streamcipher_req;
> +       } u;
> +};
> +
> +static int hctr2_setkey(struct crypto_skcipher *tfm, const u8 *key,
> +                       unsigned int keylen)
> +{
> +       struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +       u8 hbar[BLOCKCIPHER_BLOCK_SIZE];
> +       int err;
> +
> +       crypto_cipher_clear_flags(tctx->blockcipher, CRYPTO_TFM_REQ_MASK);
> +       crypto_cipher_set_flags(tctx->blockcipher,
> +                               crypto_skcipher_get_flags(tfm) &
> +                               CRYPTO_TFM_REQ_MASK);
> +       err = crypto_cipher_setkey(tctx->blockcipher, key, keylen);
> +       if (err)
> +               return err;
> +
> +       crypto_skcipher_clear_flags(tctx->streamcipher, CRYPTO_TFM_REQ_MASK);
> +       crypto_skcipher_set_flags(tctx->streamcipher,
> +                                 crypto_skcipher_get_flags(tfm) &
> +                                 CRYPTO_TFM_REQ_MASK);
> +       err = crypto_skcipher_setkey(tctx->streamcipher, key, keylen);
> +       if (err)
> +               return err;
> +
> +       memset(tctx->L, 0, sizeof(tctx->L));
> +       memset(hbar, 0, sizeof(hbar));
> +       tctx->L[0] = 0x01;
> +       crypto_cipher_encrypt_one(tctx->blockcipher, tctx->L, tctx->L);
> +       crypto_cipher_encrypt_one(tctx->blockcipher, hbar, hbar);
> +
> +       crypto_shash_clear_flags(tctx->hash, CRYPTO_TFM_REQ_MASK);
> +       crypto_shash_set_flags(tctx->hash, crypto_skcipher_get_flags(tfm) &
> +                              CRYPTO_TFM_REQ_MASK);
> +       err = crypto_shash_setkey(tctx->hash, hbar, BLOCKCIPHER_BLOCK_SIZE);
> +       return err;
> +}
> +
> +static int hctr2_hash_tweak(struct skcipher_request *req, u8 *iv)
> +{
> +       u64 tweak_length_part[2];
> +       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> +       const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +       struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +       struct shash_desc *hash_desc = &rctx->u.hash_desc;
> +       int err;
> +
> +       memset(tweak_length_part, 0, sizeof(tweak_length_part));
> +       if (req->cryptlen % POLYVAL_BLOCK_SIZE == 0)
> +               tweak_length_part[0] = cpu_to_le64(TWEAK_SIZE * 8 * 2 + 2);
> +       else
> +               tweak_length_part[0] = cpu_to_le64(TWEAK_SIZE * 8 * 2 + 3);
> +
> +       hash_desc->tfm = tctx->hash;
> +       err = crypto_shash_init(hash_desc);
> +       if (err)
> +               return err;
> +
> +       err = crypto_shash_update(hash_desc, (u8 *)tweak_length_part, sizeof(tweak_length_part));
> +       if (err)
> +               return err;
> +       err = crypto_shash_update(hash_desc, iv, TWEAK_SIZE);
> +       return err;
> +}
> +
> +static int hctr2_hash_message(struct skcipher_request *req,
> +                             struct scatterlist *sgl,
> +                             u8 digest[POLYVAL_DIGEST_SIZE])
> +{
> +       u8 padding[BLOCKCIPHER_BLOCK_SIZE];
> +       struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +       struct shash_desc *hash_desc = &rctx->u.hash_desc;
> +       const unsigned int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
> +       struct sg_mapping_iter miter;
> +       unsigned int remainder = bulk_len % BLOCKCIPHER_BLOCK_SIZE;
> +       int err;
> +
> +       sg_miter_start(&miter, sgl, sg_nents(sgl),
> +                      SG_MITER_FROM_SG | SG_MITER_ATOMIC);

Note to maintainers: this adds another use of kmap_atomic(), meaning
that this executes with preemption disabled even on !HIGHMEM
architectures.

Is there a plan to address that? Should we add another SG_MITER flag
that uses kmap_local() instead?

> +       while (sg_miter_next(&miter)) {
> +               err = crypto_shash_update(hash_desc, miter.addr, miter.length);
> +               if (err)
> +                       break;
> +       }
> +       sg_miter_stop(&miter);
> +       if (err)
> +               return err;
> +
> +       if (remainder) {
> +               memset(padding, 0, BLOCKCIPHER_BLOCK_SIZE);
> +               padding[0] = 0x01;
> +               err = crypto_shash_update(hash_desc, padding, BLOCKCIPHER_BLOCK_SIZE - remainder);
> +               if (err)
> +                       return err;
> +       }
> +       return crypto_shash_final(hash_desc, digest);
> +}
> +
> +static int hctr2_finish(struct skcipher_request *req)
> +{
> +       struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +       u8 digest[POLYVAL_DIGEST_SIZE];
> +       int err;
> +
> +       err = hctr2_hash_tweak(req, req->iv);
> +       if (err)
> +               return err;
> +       err = hctr2_hash_message(req, rctx->bulk_part_dst, digest);
> +       if (err)
> +               return err;
> +       crypto_xor(rctx->first_block, digest, BLOCKCIPHER_BLOCK_SIZE);
> +
> +       scatterwalk_map_and_copy(rctx->first_block, req->dst,
> +                                0, BLOCKCIPHER_BLOCK_SIZE, 1);
> +       return 0;
> +}
> +
> +static void hctr2_streamcipher_done(struct crypto_async_request *areq,
> +                                   int err)
> +{
> +       struct skcipher_request *req = areq->data;
> +
> +       if (!err)
> +               err = hctr2_finish(req);
> +
> +       skcipher_request_complete(req, err);
> +}
> +
> +static int hctr2_crypt(struct skcipher_request *req, bool enc)
> +{
> +       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> +       const struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +       struct hctr2_request_ctx *rctx = skcipher_request_ctx(req);
> +       u8 digest[POLYVAL_DIGEST_SIZE];
> +       int bulk_len = req->cryptlen - BLOCKCIPHER_BLOCK_SIZE;
> +       int err;
> +
> +       // Requests must be at least one block
> +       if (req->cryptlen < BLOCKCIPHER_BLOCK_SIZE)
> +               return -EINVAL;
> +
> +       scatterwalk_map_and_copy(rctx->first_block, req->src,
> +                                0, BLOCKCIPHER_BLOCK_SIZE, 0);
> +       rctx->bulk_part_src = scatterwalk_ffwd(rctx->sg_src, req->src, BLOCKCIPHER_BLOCK_SIZE);
> +       rctx->bulk_part_dst = scatterwalk_ffwd(rctx->sg_dst, req->dst, BLOCKCIPHER_BLOCK_SIZE);
> +
> +       err = hctr2_hash_tweak(req, req->iv);
> +       if (err)
> +               return err;
> +       err = hctr2_hash_message(req, rctx->bulk_part_src, digest);
> +       if (err)
> +               return err;
> +       crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
> +
> +       if (enc)
> +               crypto_cipher_encrypt_one(tctx->blockcipher, rctx->first_block, digest);
> +       else
> +               crypto_cipher_decrypt_one(tctx->blockcipher, rctx->first_block, digest);
> +
> +       crypto_xor(digest, rctx->first_block, BLOCKCIPHER_BLOCK_SIZE);
> +       crypto_xor(digest, tctx->L, BLOCKCIPHER_BLOCK_SIZE);
> +
> +       skcipher_request_set_tfm(&rctx->u.streamcipher_req, tctx->streamcipher);
> +       skcipher_request_set_crypt(&rctx->u.streamcipher_req, rctx->bulk_part_src,
> +                                  rctx->bulk_part_dst, bulk_len, digest);
> +       skcipher_request_set_callback(&rctx->u.streamcipher_req,
> +                                     req->base.flags,
> +                                     hctr2_streamcipher_done, req);
> +       return crypto_skcipher_encrypt(&rctx->u.streamcipher_req) ?:
> +               hctr2_finish(req);
> +}
> +
> +static int hctr2_encrypt(struct skcipher_request *req)
> +{
> +       return hctr2_crypt(req, true);
> +}
> +
> +static int hctr2_decrypt(struct skcipher_request *req)
> +{
> +       return hctr2_crypt(req, false);
> +}
> +
> +static int hctr2_init_tfm(struct crypto_skcipher *tfm)
> +{
> +       struct skcipher_instance *inst = skcipher_alg_instance(tfm);
> +       struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
> +       struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +       struct crypto_skcipher *streamcipher;
> +       struct crypto_cipher *blockcipher;
> +       struct crypto_shash *hash;
> +       unsigned int subreq_size;
> +       int err;
> +
> +       streamcipher = crypto_spawn_skcipher(&ictx->streamcipher_spawn);
> +       if (IS_ERR(streamcipher))
> +               return PTR_ERR(streamcipher);
> +
> +       blockcipher = crypto_spawn_cipher(&ictx->blockcipher_spawn);
> +       if (IS_ERR(blockcipher)) {
> +               err = PTR_ERR(blockcipher);
> +               goto err_free_streamcipher;
> +       }
> +
> +       hash = crypto_spawn_shash(&ictx->hash_spawn);
> +       if (IS_ERR(hash)) {
> +               err = PTR_ERR(hash);
> +               goto err_free_blockcipher;
> +       }
> +
> +       tctx->streamcipher = streamcipher;
> +       tctx->blockcipher = blockcipher;
> +       tctx->hash = hash;
> +
> +       BUILD_BUG_ON(offsetofend(struct hctr2_request_ctx, u) !=
> +                                sizeof(struct hctr2_request_ctx));
> +       subreq_size = max(sizeof_field(struct hctr2_request_ctx, u.hash_desc) +
> +                         crypto_shash_descsize(hash), sizeof_field(struct
> +                         hctr2_request_ctx, u.streamcipher_req) +
> +                         crypto_skcipher_reqsize(streamcipher));
> +
> +       crypto_skcipher_set_reqsize(tfm, offsetof(struct hctr2_request_ctx, u) +
> +                                   subreq_size);
> +       return 0;
> +
> +err_free_blockcipher:
> +       crypto_free_cipher(blockcipher);
> +err_free_streamcipher:
> +       crypto_free_skcipher(streamcipher);
> +       return err;
> +}
> +
> +static void hctr2_exit_tfm(struct crypto_skcipher *tfm)
> +{
> +       struct hctr2_tfm_ctx *tctx = crypto_skcipher_ctx(tfm);
> +
> +       crypto_free_cipher(tctx->blockcipher);
> +       crypto_free_skcipher(tctx->streamcipher);
> +       crypto_free_shash(tctx->hash);
> +}
> +
> +static void hctr2_free_instance(struct skcipher_instance *inst)
> +{
> +       struct hctr2_instance_ctx *ictx = skcipher_instance_ctx(inst);
> +
> +       crypto_drop_cipher(&ictx->blockcipher_spawn);
> +       crypto_drop_skcipher(&ictx->streamcipher_spawn);
> +       crypto_drop_shash(&ictx->hash_spawn);
> +       kfree(inst);
> +}
> +
> +/*
> + * Check for a supported set of inner algorithms.
> + * See the comment at the beginning of this file.
> + */
> +static bool hctr2_supported_algorithms(struct skcipher_alg *streamcipher_alg,
> +                                      struct crypto_alg *blockcipher_alg,
> +                                      struct shash_alg *hash_alg)
> +{
> +       if (strncmp(streamcipher_alg->base.cra_name, "xctr(", 4) != 0)
> +               return false;
> +
> +       if (blockcipher_alg->cra_blocksize != BLOCKCIPHER_BLOCK_SIZE)
> +               return false;
> +
> +       if (strcmp(hash_alg->base.cra_name, "polyval") != 0)
> +               return false;
> +
> +       return true;
> +}
> +
> +static int hctr2_create_common(struct crypto_template *tmpl,
> +                              struct rtattr **tb,
> +                              const char *blockcipher_name,
> +                              const char *streamcipher_name,
> +                              const char *polyval_name)
> +{
> +       u32 mask;
> +       struct skcipher_instance *inst;
> +       struct hctr2_instance_ctx *ictx;
> +       struct skcipher_alg *streamcipher_alg;
> +       struct crypto_alg *blockcipher_alg;
> +       struct shash_alg *hash_alg;
> +       int err;
> +
> +       err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER, &mask);
> +       if (err)
> +               return err;
> +
> +       inst = kzalloc(sizeof(*inst) + sizeof(*ictx), GFP_KERNEL);
> +       if (!inst)
> +               return -ENOMEM;
> +       ictx = skcipher_instance_ctx(inst);
> +
> +       /* Stream cipher, xctr(block_cipher) */
> +       err = crypto_grab_skcipher(&ictx->streamcipher_spawn,
> +                                  skcipher_crypto_instance(inst),
> +                                  streamcipher_name, 0, mask);
> +       if (err)
> +               goto err_free_inst;
> +       streamcipher_alg = crypto_spawn_skcipher_alg(&ictx->streamcipher_spawn);
> +
> +       /* Block cipher, e.g. "aes" */
> +       err = crypto_grab_cipher(&ictx->blockcipher_spawn,
> +                                skcipher_crypto_instance(inst),
> +                                blockcipher_name, 0, mask);
> +       if (err)
> +               goto err_free_inst;
> +       blockcipher_alg = crypto_spawn_cipher_alg(&ictx->blockcipher_spawn);
> +
> +       /* Polyval ?-?U hash function */
> +       err = crypto_grab_shash(&ictx->hash_spawn,
> +                               skcipher_crypto_instance(inst),
> +                               polyval_name, 0, mask);
> +       if (err)
> +               goto err_free_inst;
> +       hash_alg = crypto_spawn_shash_alg(&ictx->hash_spawn);
> +
> +       /* Check the set of algorithms */
> +       if (!hctr2_supported_algorithms(streamcipher_alg, blockcipher_alg,
> +                                       hash_alg)) {
> +               pr_warn("Unsupported HCTR2 instantiation: (%s,%s,%s)\n",
> +                       streamcipher_alg->base.cra_name,
> +                       blockcipher_alg->cra_name, hash_alg->base.cra_name);
> +               err = -EINVAL;
> +               goto err_free_inst;
> +       }
> +
> +       /* Instance fields */
> +
> +       err = -ENAMETOOLONG;
> +       if (snprintf(inst->alg.base.cra_name, CRYPTO_MAX_ALG_NAME,
> +                                "hctr2(%s)", blockcipher_alg->cra_name) >= CRYPTO_MAX_ALG_NAME)
> +               goto err_free_inst;
> +       if (snprintf(inst->alg.base.cra_driver_name, CRYPTO_MAX_ALG_NAME,
> +                    "hctr2(%s,%s,%s)",
> +                    blockcipher_alg->cra_driver_name,
> +                    streamcipher_alg->base.cra_driver_name,
> +                    hash_alg->base.cra_driver_name) >= CRYPTO_MAX_ALG_NAME)
> +               goto err_free_inst;
> +
> +       inst->alg.base.cra_blocksize = BLOCKCIPHER_BLOCK_SIZE;
> +       inst->alg.base.cra_ctxsize = sizeof(struct hctr2_tfm_ctx);
> +       inst->alg.base.cra_alignmask = streamcipher_alg->base.cra_alignmask |
> +                                      hash_alg->base.cra_alignmask;
> +       /*
> +        * The hash function is called twice, so it is weighted higher than the
> +        * streamcipher and blockcipher.
> +        */
> +       inst->alg.base.cra_priority = (2 * streamcipher_alg->base.cra_priority +
> +                                      4 * hash_alg->base.cra_priority +
> +                                      blockcipher_alg->cra_priority) / 7;
> +
> +       inst->alg.setkey = hctr2_setkey;
> +       inst->alg.encrypt = hctr2_encrypt;
> +       inst->alg.decrypt = hctr2_decrypt;
> +       inst->alg.init = hctr2_init_tfm;
> +       inst->alg.exit = hctr2_exit_tfm;
> +       inst->alg.min_keysize = crypto_skcipher_alg_min_keysize(streamcipher_alg);
> +       inst->alg.max_keysize = crypto_skcipher_alg_max_keysize(streamcipher_alg);
> +       inst->alg.ivsize = TWEAK_SIZE;
> +
> +       inst->free = hctr2_free_instance;
> +
> +       err = skcipher_register_instance(tmpl, inst);
> +       if (err) {
> +err_free_inst:
> +               hctr2_free_instance(inst);
> +       }
> +       return err;
> +}
> +
> +static int hctr2_create(struct crypto_template *tmpl, struct rtattr **tb)
> +{
> +       const char *blockcipher_name;
> +       char streamcipher_name[CRYPTO_MAX_ALG_NAME];
> +
> +       blockcipher_name = crypto_attr_alg_name(tb[1]);
> +       if (IS_ERR(blockcipher_name))
> +               return PTR_ERR(blockcipher_name);
> +
> +       if (snprintf(streamcipher_name, CRYPTO_MAX_ALG_NAME, "xctr(%s)",
> +                   blockcipher_name) >= CRYPTO_MAX_ALG_NAME)
> +               return -ENAMETOOLONG;
> +       return hctr2_create_common(tmpl, tb, blockcipher_name, streamcipher_name, "polyval");
> +}
> +
> +/* hctr2(blockcipher_name [, xctr(blockcipher_name)] [, polyval_name]) */
> +static struct crypto_template hctr2_tmpl = {
> +       .name = "hctr2",
> +       .create = hctr2_create,
> +       .module = THIS_MODULE,
> +};
> +
> +static int __init hctr2_module_init(void)
> +{
> +       return crypto_register_template(&hctr2_tmpl);
> +}
> +
> +static void __exit hctr2_module_exit(void)
> +{
> +       crypto_unregister_template(&hctr2_tmpl);
> +}
> +
> +subsys_initcall(hctr2_module_init);
> +module_exit(hctr2_module_exit);
> +
> +MODULE_DESCRIPTION("HCTR2 length-preserving encryption mode");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS_CRYPTO("hctr2");
> +MODULE_IMPORT_NS(CRYPTO_INTERNAL);
> diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
> index b358a5141218..5af2e859830a 100644
> --- a/crypto/tcrypt.c
> +++ b/crypto/tcrypt.c
> @@ -2385,6 +2385,11 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
>                                    16, 16, aead_speed_template_19, num_mb);
>                 break;
>
> +       case 226:
> +               test_cipher_speed("hctr2(aes)", ENCRYPT, sec, NULL,
> +                                 0, speed_template_32);
> +               break;
> +
>         case 300:
>                 if (alg) {
>                         test_hash_speed(alg, sec, generic_hash_speed_template);
> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index a3a24aa07492..fa8f33210358 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -4994,6 +4994,12 @@ static const struct alg_test_desc alg_test_descs[] = {
>                 .suite = {
>                         .hash = __VECS(ghash_tv_template)
>                 }
> +       }, {
> +               .alg = "hctr2(aes)",
> +               .test = alg_test_skcipher,
> +               .suite = {
> +                       .cipher = __VECS(aes_hctr2_tv_template)
> +               }
>         }, {
>                 .alg = "hmac(md5)",
>                 .test = alg_test_hash,
> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index da3736e51982..87e4df6f8ea9 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -33630,4 +33630,791 @@ static const struct hash_testvec polyval_tv_template[] = {
>         },
>  };
>
> +/*
> + * Test vectors generated using https://github.com/google/hctr2
> + */
> +static const struct cipher_testvec aes_hctr2_tv_template[] = {
> +       {
> +               .key    = "\xe1\x15\x66\x3c\x8d\xc6\x3a\xff"
> +                         "\xef\x41\xd7\x47\xa2\xcc\x8a\xba",
> +               .iv     = "\xc3\xbe\x2a\xcb\xb5\x39\x86\xf1"
> +                         "\x91\xad\x6c\xf4\xde\x74\x45\x63"
> +                         "\x5c\x7a\xd5\xcc\x8b\x76\xef\x0e"
> +                         "\xcf\x2c\x60\x69\x37\xfd\x07\x96",
> +               .ptext  = "\x65\x75\xae\xd3\xe2\xbc\x43\x5c"
> +                         "\xb3\x1a\xd8\x05\xc3\xd0\x56\x29",
> +               .ctext  = "\x11\x91\xea\x74\x58\xcc\xd5\xa2"
> +                         "\xd0\x55\x9e\x3d\xfe\x7f\xc8\xfe",
> +               .klen   = 16,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\x50\xcc\x28\x5c\xaf\x62\xa2\x4e"
> +                         "\x02\xf0\xc0\x5e\xc1\x29\x80\xca",
> +               .iv     = "\x64\xa5\xd5\xf9\xf4\x68\x26\xea"
> +                         "\xce\xbb\x6c\xdd\xa5\xef\x39\xb5"
> +                         "\x5c\x93\xdf\x1b\x93\x21\xbe\x49"
> +                         "\xff\x9e\x86\x4f\x7c\x4d\x51\x15",
> +               .ptext  = "\x34\xc1\x08\x3e\x9c\x28\x0a\xcf"
> +                         "\x33\xdb\x3f\x0d\x05\x27\xa4\xed",
> +               .ctext  = "\x7c\xae\xbb\x37\x4a\x55\x94\x5b"
> +                         "\xc6\x6f\x8f\x9f\x68\x5f\xc7\x62",
> +               .klen   = 16,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\xda\xce\x30\x85\xe7\x06\xe6\x02"
> +                         "\x8f\x02\xbf\x9a\x82\x6e\x54\xde",
> +               .iv     = "\xf6\x7a\x28\xce\xfb\x6c\xb3\xc5"
> +                         "\x47\x81\x58\x69\x07\xe5\x22\xdb"
> +                         "\x66\x93\xd7\xe9\xbd\x5c\x7f\xf0"
> +                         "\x8a\x0b\x07\x09\xbb\xf1\x48\xc4",
> +               .ptext  = "\x01\xcd\xa4\x47\x8e\x4e\xbc\x7d"
> +                         "\xfd\xd8\xe9\xaa\xc7\x37\x25\x3d"
> +                         "\x56",
> +               .ctext  = "\xf3\xb2\x9e\xde\x96\x5d\xf0\xf6"
> +                         "\xb6\x43\x57\xc5\x53\xe8\xf9\x05"
> +                         "\x87",
> +               .klen   = 16,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\xe1\x22\xee\x5b\x3c\x92\x0e\x52"
> +                         "\xd7\x95\x88\xa3\x79\x6c\xf8\xd9",
> +               .iv     = "\xb8\xd1\xe7\x32\x36\x96\xd6\x44"
> +                         "\x9c\x36\xad\x31\x5c\xaa\xf0\x17"
> +                         "\x33\x2f\x29\x04\x31\xf5\x46\xc1"
> +                         "\x2f\x1b\xfa\xa1\xbd\x86\xc4\xd3",
> +               .ptext  = "\x87\xd7\xb8\x2d\x12\x62\xed\x41"
> +                         "\x30\x7e\xd4\x0c\xfd\xb9\x6d\x8e"
> +                         "\x30",
> +               .ctext  = "\xb6\x6a\x0c\x71\x96\x22\xb9\x40"
> +                         "\xa2\x04\x56\x14\x22\xae\xaa\x94"
> +                         "\x26",
> +               .klen   = 16,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\xf6\x2b\xab\xec\x04\x4a\x47\xa6"
> +                         "\x37\xf0\x50\x3d\x56\xe5\x61\xac",
> +               .iv     = "\xb7\x6d\x55\x7d\xe2\xf0\x10\x93"
> +                         "\x07\x1e\x5a\x9d\xc3\x59\x6f\x98"
> +                         "\x11\xde\xdb\x3a\x03\xf4\x0e\xcc"
> +                         "\x15\xa4\x1c\xdf\x3c\x55\x89\x27",
> +               .ptext  = "\xbe\xc6\x74\x4b\xb9\xa1\x43\x86"
> +                         "\xc2\x4a\x65\x00\xbf\x43\xe4\x84"
> +                         "\x6d\xae\x0a\x3c\xec\x6b\x3d\x43"
> +                         "\xcf\x49\x36\x88\x14\x3d\x3c\xfc"
> +                         "\xfb\xc1\x58\x1f\x39\x81\x88\xeb"
> +                         "\x4e\xa1\xe2\x59\xad\x47\xa3\x61",
> +               .ctext  = "\x80\x25\x8e\x11\xed\x58\x21\x6f"
> +                         "\x34\xe3\xa1\xb8\xc0\x99\x6a\x50"
> +                         "\xe0\x18\x23\x4f\x1b\x00\x68\x39"
> +                         "\x75\x34\x95\xfb\x9e\xb4\x18\x89"
> +                         "\x53\x12\x2c\xe2\xee\x59\x32\xa6"
> +                         "\xc5\x3f\xd1\x37\xbc\x12\x40\xbd",
> +               .klen   = 16,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\x39\x4e\x4d\x5c\xd6\x63\xaf\x4b"
> +                         "\xcf\xc3\x2c\x53\x8e\x3d\x7b\x3d",
> +               .iv     = "\x1d\x4a\x01\xa0\x88\xac\xdf\x2c"
> +                         "\x34\x88\x13\xef\xa4\xe7\xe5\x2e"
> +                         "\x44\xf8\xdc\xff\x74\xd4\x8a\x81"
> +                         "\x26\xfe\x50\x57\xca\x0b\x93\x54",
> +               .ptext  = "\x55\x76\x17\x29\xc6\xd2\xbd\x9c"
> +                         "\xf4\xde\x9b\x8e\x71\xf7\xe4\xfd"
> +                         "\x60\xc0\xca\xbc\x8a\x70\x31\x9b"
> +                         "\x2d\xfd\x92\x51\x31\x4d\x3e\x1b"
> +                         "\xdf\x66\x46\xba\x28\x1f\x08\xc1"
> +                         "\x1b\xd0\x8a\x5c\x8e\xe1\xcf\x79",
> +               .ctext  = "\x34\x1f\x14\x61\x16\xd8\xf0\x73"
> +                         "\x38\xe7\x5f\xc8\x64\x70\x28\x93"
> +                         "\x9b\xb3\x1c\xfe\x62\xbf\x8e\x3c"
> +                         "\xf5\x17\x2d\xfc\x0d\x3b\x61\xf7"
> +                         "\x30\x25\x4d\x5b\x0c\x84\x5f\x86"
> +                         "\x94\xa1\xbe\xa5\x6d\xa9\x10\x78",
> +               .klen   = 16,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\x3e\x08\x5d\x64\x6c\x98\xec\xec"
> +                         "\x70\x0e\x0d\xa1\x41\x20\x99\x82",
> +               .iv     = "\x11\xb7\x77\x91\x0d\x99\xd9\x8d"
> +                         "\x35\x3a\xf7\x14\x6b\x09\x37\xe5"
> +                         "\xad\x51\xf6\xc3\x96\x4b\x64\x56"
> +                         "\xa8\xbd\x81\xcc\xbe\x94\xaf\xe4",
> +               .ptext  = "\xff\x8d\xb9\xc0\xe3\x69\xb3\xb2"
> +                         "\x8b\x11\x26\xb3\x11\xec\xfb\xb9"
> +                         "\x9c\xc1\x71\xd6\xe3\x26\x0e\xe0"
> +                         "\x68\x40\x60\xb9\x3a\x63\x56\x8a"
> +                         "\x9e\xc1\xf0\x10\xb1\x64\x32\x70"
> +                         "\xf8\xcd\xc6\xc4\x49\x4c\xe1\xce"
> +                         "\xf3\xe1\x03\xf8\x35\xae\xe0\x5e"
> +                         "\xef\x5f\xbc\x41\x75\x26\x13\xcc"
> +                         "\x37\x85\xdf\xc0\x5d\xa6\x47\x98"
> +                         "\xf1\x97\x52\x58\x04\xe6\xb5\x01"
> +                         "\xc0\xb8\x17\x6d\x74\xbd\x9a\xdf"
> +                         "\xa4\x37\x94\x86\xb0\x13\x83\x28"
> +                         "\xc9\xa2\x07\x3f\xb5\xb2\x72\x40"
> +                         "\x0e\x60\xdf\x57\x07\xb7\x2c\x66"
> +                         "\x10\x3f\x8d\xdd\x30\x0a\x47\xd5"
> +                         "\xe8\x9d\xfb\xa1\xaf\x53\xd7\x05"
> +                         "\xc7\xd2\xba\xe7\x2c\xa0\xbf\xb8"
> +                         "\xd1\x93\xe7\x41\x82\xa3\x41\x3a"
> +                         "\xaf\x12\xd6\xf8\x34\xda\x92\x46"
> +                         "\xad\xa2\x2f\xf6\x7e\x46\x96\xd8"
> +                         "\x03\xf3\x49\x64\xde\xd8\x06\x8b"
> +                         "\xa0\xbc\x63\x35\x38\xb6\x6b\xda"
> +                         "\x5b\x50\x3f\x13\xa5\x84\x1b\x1b"
> +                         "\x66\x89\x95\xb7\xc2\x16\x3c\xe9"
> +                         "\x24\xb0\x8c\x6f\x49\xef\xf7\x28"
> +                         "\x6a\x24\xfd\xbe\x25\xe2\xb4\x90"
> +                         "\x77\x44\x08\xb8\xda\xd2\xde\x2c"
> +                         "\xa0\x57\x45\x57\x29\x47\x6b\x89"
> +                         "\x4a\xf6\xa7\x2a\xc3\x9e\x7b\xc8"
> +                         "\xfd\x9f\x89\xab\xee\x6d\xa3\xb4"
> +                         "\x23\x90\x7a\xe9\x89\xa0\xc7\xb3"
> +                         "\x17\x41\x87\x91\xfc\x97\x42",
> +               .ctext  = "\xfc\x9b\x96\x66\xc4\x82\x2a\x4a"
> +                         "\xb1\x24\xba\xc7\x78\x5f\x79\xc1"
> +                         "\x57\x2e\x47\x29\x4d\x7b\xd2\x9a"
> +                         "\xbd\xc6\xc1\x26\x7b\x8e\x3f\x5d"
> +                         "\xd4\xb4\x9f\x6a\x02\x24\x4a\xad"
> +                         "\x0c\x00\x1b\xdf\x92\xc5\x8a\xe1"
> +                         "\x77\x79\xcc\xd5\x20\xbf\x83\xf4"
> +                         "\x4b\xad\x11\xbf\xdb\x47\x65\x70"
> +                         "\x43\xf3\x65\xdf\xb7\xdc\xb2\xb9"
> +                         "\xaa\x3f\xb3\xdf\x79\x69\x0d\xa0"
> +                         "\x86\x1c\xba\x48\x0b\x01\xc1\x88"
> +                         "\xdf\x03\xb1\x06\x3c\x1d\x56\xa1"
> +                         "\x8e\x98\xc1\xa6\x95\xa2\x5b\x72"
> +                         "\x76\x59\xd2\x26\x25\xcd\xef\x7c"
> +                         "\xc9\x60\xea\x43\xd1\x12\x8a\x8a"
> +                         "\x63\x12\x78\xcb\x2f\x88\x1e\x88"
> +                         "\x78\x59\xde\xba\x4d\x2c\x78\x61"
> +                         "\x75\x37\x54\xfd\x80\xc7\x5e\x98"
> +                         "\xcf\x14\x62\x8e\xfb\x72\xee\x4d"
> +                         "\x9f\xaf\x8b\x09\xe5\x21\x0a\x91"
> +                         "\x8f\x88\x87\xd5\xb1\x84\xab\x18"
> +                         "\x08\x57\xed\x72\x35\xa6\x0e\xc6"
> +                         "\xff\xcb\xfe\x2c\x48\x39\x14\x44"
> +                         "\xba\x59\x32\x3a\x2d\xc4\x5f\xcb"
> +                         "\xbe\x68\x8e\x7b\xee\x21\xa4\x32"
> +                         "\x11\xa0\x99\xfd\x90\xde\x59\x43"
> +                         "\xeb\xed\xd5\x87\x68\x46\xc6\xde"
> +                         "\x0b\x07\x17\x59\x6a\xab\xca\x15"
> +                         "\x65\x02\x01\xb6\x71\x8c\x3b\xaa"
> +                         "\x18\x3b\x30\xae\x38\x5b\x2c\x74"
> +                         "\xd4\xee\x4a\xfc\xf7\x1b\x09\xd4"
> +                         "\xda\x8b\x1d\x5d\x6f\x21\x6c",
> +               .klen   = 16,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x9f\xd3\xd5\x1a\x0e\xba\x32\x0a"
> +                         "\x1d\xa5\xd1\x14\x16\x58\xcd\xdd",
> +               .iv     = "\x10\x52\x8d\x53\x3f\x54\x11\x01"
> +                         "\x19\x3b\xd8\xa5\xe8\x38\x77\x3e"
> +                         "\xd4\x58\xff\x0a\x13\xd2\x09\xe4"
> +                         "\x77\x38\x28\x46\xf9\x16\xd3\xfc",
> +               .ptext  = "\x5d\x3f\x4a\xa1\x16\x9a\x3c\xdf"
> +                         "\xd8\x21\x51\xdc\xb7\x3c\x12\xda"
> +                         "\xd1\xe1\xba\x38\xf1\xc1\x9c\x84"
> +                         "\xc7\x48\xe1\xd5\xed\x84\x3b\xcd"
> +                         "\xc7\x1b\xe1\x5d\x1b\xa5\x79\x3c"
> +                         "\xe3\x7e\xab\xf7\xac\x71\x49\x1d"
> +                         "\x25\x2b\x8f\x40\xe8\x89\x45\x67"
> +                         "\x39\x33\xd3\x27\xd5\xff\x16\xb5"
> +                         "\x46\x0f\x37\x05\x14\x87\xa7\xc2"
> +                         "\x35\x7f\x66\x98\x48\x5c\x1a\x05"
> +                         "\x6c\x0a\xd8\xe4\x28\x1e\x99\x6e"
> +                         "\x84\x6c\x13\x07\xc8\x23\xcd\x22"
> +                         "\x80\xb8\xc7\x9e\xbe\xcb\xed\x0b"
> +                         "\xfa\x9d\xf5\x4b\x4f\x0c\x6e\x4e"
> +                         "\x1b\xec\x8c\xb1\x9b\x64\xaa\x65"
> +                         "\x5e\x91\x45\xda\x87\x14\x89\x43"
> +                         "\x61\xb8\xc7\x68\xc6\xe0\x53\x0a"
> +                         "\x71\xef\xac\xc2\xb2\x41\xd9\x4e"
> +                         "\x41\xf8\xb3\xee\x2f\x59\xff\x05"
> +                         "\x91\x77\x34\xe1\xb2\x1c\x46\x95"
> +                         "\xf2\xea\x2a\x15\x70\x97\xa3\x7f"
> +                         "\xc3\x68\x23\x73\xd4\x86\xf7\xe0"
> +                         "\xc6\x6a\xbd\x70\x63\x0a\x5e\xe2"
> +                         "\xba\xe6\x7c\x18\x71\xc4\x1d\x07"
> +                         "\x40\xb0\x18\xd7\x52\xc1\x9e\x4e"
> +                         "\x8a\x3a\x75\xc3\xf5\xf1\xf9\x8e"
> +                         "\x00\x0e\x4f\x7f\x17\x16\x38\x73"
> +                         "\xf6\x91\x29\x2a\xcb\xf8\xee\x1a"
> +                         "\xf8\x09\x75\x0a\xaf\xb1\x47\x7c"
> +                         "\xcf\xca\xd3\xbd\x28\x8b\xa6\xe5"
> +                         "\x33\xd1\x63\xea\x89\x1d\xa3\x63"
> +                         "\x9d\x1f\xb2\xc6\x02\x50\x1b",
> +               .ctext  = "\xd3\x8c\xee\xa6\x45\x11\xaf\x8a"
> +                         "\x21\x75\x1f\x84\x1d\x6f\x3f\xbe"
> +                         "\xc6\x07\xdd\x64\x6c\x99\x9b\x8b"
> +                         "\xfa\xef\x41\xf2\xe1\x04\xe2\x0a"
> +                         "\x12\x88\x96\x98\x74\xd4\x6c\x5d"
> +                         "\x6b\xf4\x8b\xfc\x87\x5f\x4b\x70"
> +                         "\x29\x07\x13\x49\xad\x52\x3e\xa7"
> +                         "\x88\x20\x8a\xdd\x5d\xe9\x2d\x86"
> +                         "\x5c\x1e\x33\x82\x07\xe9\x04\xa4"
> +                         "\x72\xbd\xa8\xb3\x67\x2e\xc0\x80"
> +                         "\xea\x9d\x44\x55\x36\xca\xb6\xb4"
> +                         "\x0d\x5e\xaf\x87\x63\x45\x65\xd8"
> +                         "\x90\x58\xc3\xec\x27\x5a\x7f\x25"
> +                         "\x1b\x14\x08\x2b\xed\x14\xe2\x80"
> +                         "\x53\xc2\xed\xbf\x88\xf3\x74\x8d"
> +                         "\x79\x99\x9e\x7f\x18\x2b\x1f\x70"
> +                         "\x09\x46\x88\x41\x1b\xce\xc5\x69"
> +                         "\xd8\xc8\x83\xfa\x32\xd8\xb7\xab"
> +                         "\x87\xae\xda\x36\xc1\x75\xba\xf5"
> +                         "\xd3\x22\xcc\x0a\x20\x62\x37\xfd"
> +                         "\xc1\xe1\x6c\xc6\xac\x4b\x1e\x34"
> +                         "\x4f\xbe\x09\xea\xb1\xd3\x30\xa6"
> +                         "\xf1\xd8\x51\x0f\x83\xf7\x36\x83"
> +                         "\x17\x23\x25\x6c\xb4\x5f\x4f\x76"
> +                         "\xde\x0a\x09\x54\xf3\xd2\xca\x52"
> +                         "\xc2\xec\x6a\x9c\x0a\xa0\x59\x8e"
> +                         "\xbe\x09\x02\x83\xcf\x4e\xe3\x59"
> +                         "\x6d\xff\x45\x49\x1f\xa7\x32\x67"
> +                         "\x1d\xb4\xdf\x60\xb9\x30\xd4\x64"
> +                         "\xfc\x47\xf7\xe7\xfa\x94\x23\x60"
> +                         "\xd5\x47\xe4\x4e\x61\x45\x7e\x48"
> +                         "\xd3\xad\xad\x97\x61\x1c\x32",
> +               .klen   = 16,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\xea\x2f\x51\x6f\x31\xe9\x2f\x7b"
> +                         "\x68\xc8\x1a\xd5\xfa\x9c\xe1\x40"
> +                         "\x95\xe9\x47\xcb\xa1\x9a\xf7\xee",
> +               .iv     = "\xe6\x77\x52\x55\x9c\xa7\xc1\x91"
> +                         "\x02\xa7\x32\x87\x76\x91\x72\x2e"
> +                         "\xf3\xa4\x84\x33\xe8\xa5\xa3\x57"
> +                         "\x42\x5d\xd5\x6c\xaa\xf1\xfd\x53",
> +               .ptext  = "\x22\xd0\xff\xba\xad\x43\xaf\x63"
> +                         "\x0e\xb1\x0c\x60\x0f\x64\x92\x5a",
> +               .ctext  = "\x21\x85\xb9\xb8\xdf\x5e\x8b\x70"
> +                         "\xfe\x79\xc0\x5d\x9d\x89\x30\xdc",
> +               .klen   = 24,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\x44\x18\xc4\xb2\x25\xe5\xa6\x90"
> +                         "\x7a\x12\x8c\x35\x6a\x98\x44\x3c"
> +                         "\x4b\x67\x18\x24\x34\xce\x30\x7e",
> +               .iv     = "\x8e\xf9\x6d\xf5\x52\x06\xb5\x07"
> +                         "\xd1\x13\xfe\x36\x87\xee\x6e\x13"
> +                         "\xea\xde\x54\xaf\x49\xc6\x4f\xce"
> +                         "\xe1\x86\x8e\xcd\x22\x12\xde\x39",
> +               .ptext  = "\x34\x14\x8d\x92\xa6\x83\xd5\x87"
> +                         "\x89\xfd\xf7\xb1\x8f\x93\x0b\x1c",
> +               .ctext  = "\x4f\xdd\xc7\x22\x85\x33\x9d\x34"
> +                         "\xc8\x9b\x88\xfd\x8f\x40\xab\x42",
> +               .klen   = 24,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\x24\xf6\xe1\x62\xe5\xaf\x99\xda"
> +                         "\x84\xec\x41\xb0\xa3\x0b\xd5\xa8"
> +                         "\xa0\x3e\x7b\xa6\xdd\x6c\x8f\xa8",
> +               .iv     = "\x7f\x80\x24\x62\x32\xdd\xab\x66"
> +                         "\xf2\x87\x29\x24\xec\xd2\x4b\x9f"
> +                         "\x0c\x33\x52\xd9\xe0\xcc\x6e\xe4"
> +                         "\x90\x85\x43\x97\xc4\x62\x14\x33",
> +               .ptext  = "\xef\x58\xe7\x7f\xa9\xd9\xb8\xd7"
> +                         "\xa2\x91\x97\x07\x27\x9e\xba\xe8"
> +                         "\xaa",
> +               .ctext  = "\xd7\xc3\x81\x91\xf2\x40\x17\x73"
> +                         "\x3e\x3b\x1c\x2a\x8e\x11\x9c\x17"
> +                         "\xf1",
> +               .klen   = 24,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\xa6\xc2\x58\x49\x28\x50\x8c\x88"
> +                         "\x84\x9c\xb1\x70\x18\x99\x9c\x0d"
> +                         "\x08\x60\x4f\xb1\xcf\x90\x66\x72",
> +               .iv     = "\x80\x14\x7f\x97\x64\x17\x55\xef"
> +                         "\x4b\x1b\xce\x2b\x09\x20\x5a\xed"
> +                         "\x96\xdc\xa6\x6e\xb0\x59\x54\x00"
> +                         "\x1d\x26\x3d\x96\xc2\x3e\x73\x05",
> +               .ptext  = "\x49\x8b\x90\x34\x41\x63\xc6\x9a"
> +                         "\x07\xe0\x9d\x86\x77\x54\x63\x6d"
> +                         "\x6a",
> +               .ctext  = "\xcb\x94\xfa\xc3\xeb\xf8\x37\xfe"
> +                         "\x15\x76\x03\xd9\x67\xe4\x90\x28"
> +                         "\x0c",
> +               .klen   = 24,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\xbf\xaf\xd7\x67\x8c\x47\xcf\x21"
> +                         "\x8a\xa5\xdd\x32\x25\x47\xbe\x4f"
> +                         "\xf1\x3a\x0b\xa6\xaa\x2d\xcf\x09",
> +               .iv     = "\xd9\xe8\xf0\x92\x4e\xfc\x1d\xf2"
> +                         "\x81\x37\x7c\x8f\xf1\x59\x09\x20"
> +                         "\xf4\x46\x51\x86\x4f\x54\x8b\x32"
> +                         "\x58\xd1\x99\x8b\x8c\x03\xeb\x5d",
> +               .ptext  = "\xcd\x64\x90\xf9\x7c\xe5\x0e\x5a"
> +                         "\x75\xe7\x8e\x39\x86\xec\x20\x43"
> +                         "\x8a\x49\x09\x15\x47\xf4\x3c\x89"
> +                         "\x21\xeb\xcf\x4e\xcf\x91\xb5\x40"
> +                         "\xcd\xe5\x4d\x5c\x6f\xf2\xd2\x80"
> +                         "\xfa\xab\xb3\x76\x9f\x7f\x84\x0a",
> +               .ctext  = "\x44\x98\x64\x15\xb7\x0b\x80\xa3"
> +                         "\xb9\xca\x23\xff\x3b\x0b\x68\x74"
> +                         "\xbb\x3e\x20\x19\x9f\x28\x71\x2a"
> +                         "\x48\x3c\x7c\xe2\xef\xb5\x10\xac"
> +                         "\x82\x9f\xcd\x08\x8f\x6b\x16\x6f"
> +                         "\xc3\xbb\x07\xfb\x3c\xb0\x1b\x27",
> +               .klen   = 24,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\xbe\xbb\x77\x46\x06\x9c\xf4\x4d"
> +                         "\x37\x9a\xe6\x3f\x27\xa7\x3b\x6e"
> +                         "\x7a\x36\xb8\xb3\xff\xba\x51\xcc",
> +               .iv     = "\x06\xbc\x8f\x66\x6a\xbe\xed\x5e"
> +                         "\x51\xf2\x72\x11\x3a\x56\x85\x21"
> +                         "\x44\xfe\xec\x47\x2b\x09\xb8\x6f"
> +                         "\x08\x85\x2a\x93\xa3\xc3\xab\x5e",
> +               .ptext  = "\xc7\x74\x42\xf1\xea\xc5\x37\x2d"
> +                         "\xc2\xa0\xf6\xd5\x5a\x9a\xbb\xa0"
> +                         "\xb2\xfd\x54\x8e\x98\xa0\xea\xc7"
> +                         "\x79\x09\x65\x63\xa0\x2e\x82\x4e"
> +                         "\x49\x9c\x39\x67\xd0\x0d\x80\x3e"
> +                         "\x1a\x86\x84\x2b\x20\x23\xdf\xa7",
> +               .ctext  = "\x5f\xa3\x11\xca\x93\xfa\x24\x3a"
> +                         "\x24\xb6\xcf\x1e\x76\xbc\xab\xc4"
> +                         "\xf3\x24\xa0\x27\xac\x90\xec\xe9"
> +                         "\x73\x28\x7d\x35\x67\xfe\x2e\xa8"
> +                         "\x89\x77\xac\xeb\xc3\x68\x36\xf4"
> +                         "\x8f\x80\x2c\xf1\x80\xef\x49\x49",
> +               .klen   = 24,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\x76\xe4\x8f\xf0\x60\x7b\xe4\x0d"
> +                         "\xb9\x06\xfa\x90\x38\x55\x0a\x98"
> +                         "\xaa\x7d\x97\xfe\x8d\x77\x39\x9f",
> +               .iv     = "\xf7\x2c\x39\x70\xa4\x28\x66\x45"
> +                         "\xea\x62\x1b\xdd\xb0\xfa\x6c\x50"
> +                         "\xcf\xf7\x4a\x57\xdf\x1e\xa4\xf0"
> +                         "\x0f\xf6\x8a\x71\x15\xcf\xa0\x29",
> +               .ptext  = "\x9c\x15\x7c\xc0\x70\x49\x65\xac"
> +                         "\x95\x67\x37\x40\x8b\x0e\x9d\xa9"
> +                         "\x66\x0a\x5e\x32\x58\xa1\x40\x8d"
> +                         "\x46\xa2\xbd\x4f\x5a\xb1\x5f\xd5"
> +                         "\x9d\x8e\x55\x18\x7e\x43\x43\xa9"
> +                         "\x55\x1a\x3f\x50\x51\x7a\xc9\x1b"
> +                         "\x2f\xd8\x36\x35\x41\xf3\x3d\x42"
> +                         "\x7e\x3e\xd5\x94\x6b\xa7\xa0\xc6"
> +                         "\x02\x35\xba\x59\x7a\xc3\xda\xca"
> +                         "\xa3\x73\x18\x6a\x57\x2f\xbd\xe8"
> +                         "\xc8\x3a\x6c\x07\x0e\xea\x6c\x17"
> +                         "\x4f\x3a\xcc\xc3\x70\x89\x99\x23"
> +                         "\x78\x38\xd7\x60\x51\x5a\xe5\xec"
> +                         "\x19\x98\x5b\x78\x9f\xb8\xb9\x00"
> +                         "\x7c\xf8\xab\x23\x59\xf0\x71\xcf"
> +                         "\x7f\x06\x11\x55\x85\x94\xe5\x50"
> +                         "\x0d\x01\x93\xcb\xde\x58\x90\x00"
> +                         "\xc5\x34\x7e\xda\x26\xbf\x58\x15"
> +                         "\x80\x33\x34\x56\x86\xaa\xc8\x6e"
> +                         "\x2b\x47\x98\xb6\xc9\x1c\xa4\xb6"
> +                         "\xac\xf1\x76\xfe\x33\x57\x2d\xad"
> +                         "\x42\x15\x34\xba\x71\x96\xfe\x0e"
> +                         "\xba\xee\x68\x36\x3a\xe0\xe7\xc7"
> +                         "\x3e\x6d\x54\xda\x77\x04\x26\x2c"
> +                         "\xc1\x45\x16\xd9\xdd\x89\xd3\xf1"
> +                         "\xcc\xfc\x19\x44\x6c\x99\xb2\x44"
> +                         "\x1f\x89\x34\x21\xb1\x8d\x02\x5c"
> +                         "\x76\x1e\x27\x84\xf9\xd4\xa3\x03"
> +                         "\x1d\x26\xc1\x39\xb6\x67\x6c\xad"
> +                         "\xb5\x69\x6b\x54\x65\xf6\x9c\xcf"
> +                         "\xaf\x00\x12\x87\x21\x2f\x68\xcb"
> +                         "\xd2\x76\xc1\x43\xce\x24\xc2",
> +               .ctext  = "\x40\xff\x83\x8e\xef\x98\xa1\xcb"
> +                         "\x57\x3f\xb6\xf3\x26\x99\x96\xe2"
> +                         "\xd0\x68\x80\x32\x2c\x58\x9a\xd6"
> +                         "\x24\xd0\x21\x17\xc0\x6e\x44\xb6"
> +                         "\xa7\xa0\xdd\xde\xce\x18\x5a\x17"
> +                         "\xf2\xc1\x98\xab\x61\xcd\x70\x0a"
> +                         "\x4d\xef\x9f\xa6\x9d\x8b\x45\x81"
> +                         "\x23\x90\x65\xe0\x45\x2c\x74\xc5"
> +                         "\x7d\xe8\x43\xec\x5a\xfa\x54\x64"
> +                         "\x6f\xfc\x4b\x6c\x83\xec\x1d\xbc"
> +                         "\x39\x19\x2f\xa7\xe6\x46\x5a\x4e"
> +                         "\x17\x6d\x0b\xf2\x7a\x14\x0c\x50"
> +                         "\x8e\x83\x00\xb7\xbb\x65\x77\xfd"
> +                         "\x72\xb3\xea\xe4\xde\x54\xd6\xc0"
> +                         "\x8c\x02\xb2\xdb\xc3\xe6\x46\xd5"
> +                         "\xfb\xb4\x03\x29\xdc\xa4\x64\xe3"
> +                         "\xe8\x20\xb5\x4d\x81\x44\x20\xc8"
> +                         "\x29\x41\xce\x05\x3a\xd6\xe3\x0e"
> +                         "\x0b\xea\xdf\x50\xea\x91\xaa\x9b"
> +                         "\xc4\x9c\x09\x4a\x42\xfa\xef\x38"
> +                         "\x3b\xdf\xfb\x5b\x95\xa2\x9a\xbd"
> +                         "\x10\x55\x61\x4a\xee\x8b\xda\x1f"
> +                         "\x23\x69\xce\x6e\x92\x64\x3e\x32"
> +                         "\x4d\x80\x23\xf1\x43\xd7\x01\x54"
> +                         "\x6f\x18\x4c\x53\x91\xd5\xaa\xeb"
> +                         "\x17\x73\x92\x7f\x10\x7b\x57\x02"
> +                         "\x8e\x6f\xce\x63\x83\x6b\x12\xba"
> +                         "\xbc\x23\xcb\x95\x3a\x1f\x16\xe5"
> +                         "\x21\xf7\x52\x17\x43\x28\x52\xaf"
> +                         "\x2e\x6f\x7f\x36\xe6\x0c\x31\x90"
> +                         "\x57\xf7\x5f\x7c\x06\x3e\x47\x5f"
> +                         "\xb8\xc4\x2a\xeb\xd7\x91\xf1",
> +               .klen   = 24,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x87\x2b\xdd\x36\x2a\x76\x60\xce"
> +                         "\xfb\x54\xa7\x5a\x3f\x40\xcd\x10"
> +                         "\xc8\x88\x0e\xd8\x83\x31\xd5\x5e",
> +               .iv     = "\x3b\x6c\x32\xde\x9c\x02\xb6\xa1"
> +                         "\x13\xfe\x8d\x4a\x8d\xf8\x15\x8d"
> +                         "\x0b\x2c\x14\x1c\x44\xd4\x1f\x7e"
> +                         "\xcc\x33\xf0\x03\xa3\x41\x3e\x6d",
> +               .ptext  = "\x6a\x0c\x6b\x8b\x44\x75\x77\x0b"
> +                         "\x7d\x9f\xca\x35\x27\x36\xbf\xe3"
> +                         "\xc2\x09\x3e\x6e\x42\xd4\x81\xc2"
> +                         "\x4a\xd5\xa3\x00\x5d\x2b\x97\x0a"
> +                         "\xe0\xd9\x8b\x10\x79\x74\xf4\x5f"
> +                         "\xef\xf0\xc7\x3b\xbc\xbe\x69\xe4"
> +                         "\x0f\xb8\xa2\x39\x15\x70\x3a\xa6"
> +                         "\x20\x86\x8b\x3c\x6e\xca\xfc\x36"
> +                         "\xea\x32\x5f\xa6\x17\x2b\xd3\x24"
> +                         "\x65\x69\x9c\x13\x5c\x56\xb6\x14"
> +                         "\x3a\x8f\x21\x40\xde\x23\x6f\x8b"
> +                         "\x2f\xa8\xa4\x81\x91\xb6\xbe\x7c"
> +                         "\x12\x25\x7c\x87\xb8\x74\x6a\xa7"
> +                         "\x8d\xa5\xb9\x8c\xb4\xa9\xd2\x6a"
> +                         "\xb2\xb3\x6e\x8b\x40\x9f\xf2\x38"
> +                         "\xd8\x26\xf1\xfa\x6f\xb9\x29\xfe"
> +                         "\x0f\xc1\x4d\x90\xf8\x49\xe1\x72"
> +                         "\x70\x63\x35\xdc\xfe\xb4\x72\x06"
> +                         "\xae\x7e\xbe\x36\x23\xa2\x4a\x03"
> +                         "\x6c\xa8\xa0\x7a\x5c\x44\x60\xc4"
> +                         "\x2b\x50\xa1\x19\xa4\x35\xfc\x00"
> +                         "\xd1\x0a\x8f\x9c\x54\x5b\xdc\x53"
> +                         "\x68\x7b\x7b\x1e\xd0\x8e\xd0\x93"
> +                         "\x8f\xaf\xf5\xa2\x40\xe1\x15\x33"
> +                         "\x49\x41\xaa\x57\xf3\x13\x1b\xa5"
> +                         "\x8a\xab\x01\x2b\x28\xec\x63\x81"
> +                         "\x34\x77\xf1\x3f\xc2\x47\x09\x31"
> +                         "\xc2\x80\x1c\xa9\x16\x6b\xa5\x0a"
> +                         "\x1c\xbe\x23\x0c\x41\x63\xd6\x92"
> +                         "\x7f\x3a\x74\x71\x86\x5e\x30\xc1"
> +                         "\xc5\xee\x5b\x41\x9a\xed\x43\xab"
> +                         "\x10\x40\xc4\xe6\xf3\xaa\xc2",
> +               .ctext  = "\x45\x61\x53\x5c\x56\x08\xc2\x78"
> +                         "\x01\x23\x8d\x9d\x8e\xeb\xca\xcd"
> +                         "\xf5\x1f\x01\x3f\xba\x9d\xea\x87"
> +                         "\xca\x23\xc5\xa8\xb2\x92\x87\x0d"
> +                         "\x62\x8c\x72\x9c\xe8\xa5\x3f\x75"
> +                         "\xda\xa4\xd5\x92\x6f\xae\x4e\xeb"
> +                         "\xfd\x21\xe6\xa9\x7e\xbf\xed\x85"
> +                         "\xbd\x8c\x88\x18\xa8\x79\xd0\x09"
> +                         "\x5b\x6b\x96\x32\x63\x1a\x6e\x27"
> +                         "\x72\xa3\x7a\xc4\x48\xf3\xed\x04"
> +                         "\x5d\xc7\x01\x23\x7c\x36\x57\x57"
> +                         "\xf4\x45\xf6\xf6\xc7\x9a\xb2\x2f"
> +                         "\x88\x79\xac\xaf\xfd\x52\xa7\x96"
> +                         "\x83\x65\x5d\x6b\xa2\x3b\x2b\x17"
> +                         "\x6c\xa7\xe3\x03\x2e\x6b\xa5\x80"
> +                         "\x32\x0b\x7c\x86\x38\x64\x24\x64"
> +                         "\x51\x61\xca\xa8\xdc\x67\x6a\x17"
> +                         "\x96\xc8\xbd\xd0\x0f\x99\x78\x75"
> +                         "\xbb\x81\xc8\x35\xc1\x5c\x48\x66"
> +                         "\x75\x8a\xed\x44\x57\x10\xc9\xd8"
> +                         "\x85\x91\xaf\x2b\xdd\xc0\xfc\x7f"
> +                         "\x19\x9d\x22\x8f\x94\xe7\xb0\x86"
> +                         "\x34\x17\xd3\xe1\x10\x2a\x30\x3a"
> +                         "\x4d\x5b\xab\x99\xf5\xf8\x21\x78"
> +                         "\x9d\x1b\xba\x1f\xb9\x18\x20\xfa"
> +                         "\x12\x09\x65\xb0\x2c\xf0\x0c\x11"
> +                         "\x4d\x91\xb0\xa0\x24\xb0\xf8\x61"
> +                         "\xe0\x65\xc1\x21\x72\x98\xbc\x29"
> +                         "\x92\x85\x2c\xfc\xa1\x0c\xa0\x04"
> +                         "\x6d\x21\x3d\x40\x62\xda\x55\x71"
> +                         "\xee\xa1\x1e\x5e\xc3\x42\x0b\xa0"
> +                         "\x4b\xe5\xbd\x95\xa9\xdf\x70",
> +               .klen   = 24,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x9e\xeb\xb2\x49\x3c\x1c\xf5\xf4"
> +                         "\x6a\x99\xc2\xc4\xdf\xb1\xf4\xdd"
> +                         "\x75\x20\x57\xea\x2c\x4f\xcd\xb2"
> +                         "\xa5\x3d\x7b\x49\x1e\xab\xfd\x0f",
> +               .iv     = "\xdf\x63\xd4\xab\xd2\x49\xf3\xd8"
> +                         "\x33\x81\x37\x60\x7d\xfa\x73\x08"
> +                         "\xd8\x49\x6d\x80\xe8\x2f\x62\x54"
> +                         "\xeb\x0e\xa9\x39\x5b\x45\x7f\x8a",
> +               .ptext  = "\x67\xc9\xf2\x30\x84\x41\x8e\x43"
> +                         "\xfb\xf3\xb3\x3e\x79\x36\x7f\xe8",
> +               .ctext  = "\x27\x38\x78\x47\x16\xd9\x71\x35"
> +                         "\x2e\x7e\xdd\x7e\x43\x3c\xb8\x40",
> +               .klen   = 32,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\x50\x4a\xc8\x94\x01\x13\xd3\x0c"
> +                         "\xd9\xaa\xf3\x4c\xf8\x3f\x2c\x39"
> +                         "\x9e\xec\xc6\xa8\x97\xf2\x8e\x73"
> +                         "\x94\xb8\x4c\x40\x03\x28\xaf\xc2",
> +               .iv     = "\x9e\xaa\x0b\x7f\x12\x2a\xe3\xdf"
> +                         "\x05\x03\x93\x1b\xda\xc8\xd7\x98"
> +                         "\x8a\xf9\xdf\x63\xb1\xcd\x15\xaa"
> +                         "\x02\x8e\x41\xa0\x75\x1d\x17\x0e",
> +               .ptext  = "\xe2\x8a\x35\xa7\x10\x0d\x65\x6e"
> +                         "\xad\x77\xce\x07\xbb\x67\x83\x03",
> +               .ctext  = "\x81\xc1\x1c\x06\x73\xcb\xc1\xe6"
> +                         "\xed\x1f\x5b\xf0\x7d\x8b\x12\xf8",
> +               .klen   = 32,
> +               .len    = 16,
> +       },
> +       {
> +               .key    = "\x93\xfa\x7e\xe2\x0e\x67\xc4\x39"
> +                         "\xe7\xca\x47\x95\x68\x9d\x5e\x5a"
> +                         "\x7c\x26\x19\xab\xc6\xca\x6a\x4c"
> +                         "\x45\xa6\x96\x42\xae\x6c\xff\xe7",
> +               .iv     = "\xea\x82\x47\x95\x3b\x22\xa1\x3a"
> +                         "\x6a\xca\x24\x4c\x50\x7e\x23\xcd"
> +                         "\x0e\x50\xe5\x41\xb6\x65\x29\xd8"
> +                         "\x30\x23\x00\xd2\x54\xa7\xd6\x56",
> +               .ptext  = "\xdb\x1f\x1f\xec\xad\x83\x6e\x5d"
> +                         "\x19\xa5\xf6\x3b\xb4\x93\x5a\x57"
> +                         "\x6f",
> +               .ctext  = "\xf1\x46\x6e\x9d\xb3\x01\xf0\x6b"
> +                         "\xc2\xac\x57\x88\x48\x6d\x40\x72"
> +                         "\x68",
> +               .klen   = 32,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\xbe\xa5\x63\xe5\x3d\xa6\xdd\x83"
> +                         "\x12\x4e\x52\x3e\xb7\x47\x13\xc0"
> +                         "\x98\x57\x14\x8c\xe9\xbe\x0d\xb4"
> +                         "\xa7\x82\x0e\x99\x82\x94\x0f\x60",
> +               .iv     = "\x36\xdf\x56\x4d\xcf\x6a\xd2\xf4"
> +                         "\x35\x92\x3d\xd2\x31\x24\xf8\xa6"
> +                         "\x27\x27\xe4\x55\xe2\xe0\xc3\xb5"
> +                         "\xe7\x40\x31\xae\x98\xab\xab\x93",
> +               .ptext  = "\xf4\x54\x01\xb5\x11\xe3\xed\x8d"
> +                         "\xa4\xf0\xf7\x3f\xc8\x4b\xac\x7a"
> +                         "\xb9",
> +               .ctext  = "\xa7\xb5\xa4\xaa\x6b\x56\xdb\x79"
> +                         "\x30\xa1\x6e\xfe\xa2\x60\xcb\xb3"
> +                         "\x10",
> +               .klen   = 32,
> +               .len    = 17,
> +       },
> +       {
> +               .key    = "\x03\x65\x03\x6e\x4d\xe6\xe8\x4e"
> +                         "\x8b\xbe\x22\x19\x48\x31\xee\xd9"
> +                         "\xa0\x91\x21\xbe\x62\x89\xde\x78"
> +                         "\xd9\xb0\x36\xa3\x3c\xce\x43\xd5",
> +               .iv     = "\xa9\xc3\x4b\xe7\x0f\xfc\x6d\xbf"
> +                         "\x56\x27\x21\x1c\xfc\xd6\x04\x10"
> +                         "\x5f\x43\xe2\x30\x35\x29\x6c\x10"
> +                         "\x90\xf1\xbf\x61\xed\x0f\x8a\x91",
> +               .ptext  = "\x07\xaa\x02\x26\xb4\x98\x11\x5e"
> +                         "\x33\x41\x21\x51\x51\x63\x2c\x72"
> +                         "\x00\xab\x32\xa7\x1c\xc8\x3c\x9c"
> +                         "\x25\x0e\x8b\x9a\xdf\x85\xed\x2d"
> +                         "\xf4\xf2\xbc\x55\xca\x92\x6d\x22"
> +                         "\xfd\x22\x3b\x42\x4c\x0b\x74\xec",
> +               .ctext  = "\x7b\xb1\x43\x6d\xd8\x72\x6c\xf6"
> +                         "\x67\x6a\x00\xc4\xf1\xf0\xf5\xa4"
> +                         "\xfc\x60\x91\xab\x46\x0b\x15\xfc"
> +                         "\xd7\xc1\x28\x15\xa1\xfc\xf7\x68"
> +                         "\x8e\xcc\x27\x62\x00\x64\x56\x72"
> +                         "\xa6\x17\xd7\x3f\x67\x80\x10\x58",
> +               .klen   = 32,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\x93\x14\x30\x98\x95\xda\xad\xeb"
> +                         "\xb8\x22\xb5\x98\x57\x7c\xfa\x14"
> +                         "\x88\x8a\x70\x76\x09\x7d\x03\xb7"
> +                         "\xf9\x1d\x5d\x30\x1f\x24\xb2\xce",
> +               .iv     = "\x47\xb7\x08\xb9\xc1\xf5\x12\x57"
> +                         "\x68\x4d\x74\x71\xc3\x0b\x05\xc5"
> +                         "\x8d\x00\x48\x9d\x3a\xfc\x85\x05"
> +                         "\x49\x82\x96\x95\x09\x1a\x17\x27",
> +               .ptext  = "\x3f\xf5\x2c\x26\x53\x6c\xdc\x88"
> +                         "\x5e\xf3\x2e\x0d\x22\xe4\xef\x4e"
> +                         "\xad\xaf\xe5\xf7\x5c\xd3\x84\x0e"
> +                         "\xe1\xbb\x19\x0a\xcf\x1e\xb6\xf3"
> +                         "\x53\xf3\x25\xa2\x66\x7a\xd2\x97"
> +                         "\x58\x39\x7a\xd6\x4b\x7f\x31\x76",
> +               .ctext  = "\x75\x16\xb1\x9a\xa9\x9d\x12\x78"
> +                         "\x5a\xd1\x36\xc5\x11\x4c\x1a\xc5"
> +                         "\x9b\x21\x12\x0b\xef\x13\xbc\xd0"
> +                         "\x31\x03\xcc\xd9\xf5\x59\x23\xb6"
> +                         "\x70\xaf\xc2\x84\x57\x5c\xad\xc7"
> +                         "\x89\x6a\xf4\x39\x14\x7e\x0d\x0d",
> +               .klen   = 32,
> +               .len    = 48,
> +       },
> +       {
> +               .key    = "\x36\x45\x11\xa2\x98\x5f\x96\x7c"
> +                         "\xc6\xb4\x94\x31\x0a\x67\x09\x32"
> +                         "\x6c\x6f\x6f\x00\xf0\x17\xcb\xac"
> +                         "\xa5\xa9\x47\x9e\x2e\x85\x2f\xfa",
> +               .iv     = "\x28\x88\xaa\x9b\x59\x3b\x1e\x97"
> +                         "\x82\xe5\x5c\x9e\x6d\x14\x11\x19"
> +                         "\x6e\x38\x8f\xd5\x40\x2b\xca\xf9"
> +                         "\x7b\x4c\xe4\xa3\xd0\xd2\x8a\x13",
> +               .ptext  = "\x95\xd2\xf7\x71\x1b\xca\xa5\x86"
> +                         "\xd9\x48\x01\x93\x2f\x79\x55\x29"
> +                         "\x71\x13\x15\x0e\xe6\x12\xbc\x4d"
> +                         "\x8a\x31\xe3\x40\x2a\xc6\x5e\x0d"
> +                         "\x68\xbb\x4a\x62\x8d\xc7\x45\x77"
> +                         "\xd2\xb8\xc7\x1d\xf1\xd2\x5d\x97"
> +                         "\xcf\xac\x52\xe5\x32\x77\xb6\xda"
> +                         "\x30\x85\xcf\x2b\x98\xe9\xaa\x34"
> +                         "\x62\xb5\x23\x9e\xb7\xa6\xd4\xe0"
> +                         "\xb4\x58\x18\x8c\x4d\xde\x4d\x01"
> +                         "\x83\x89\x24\xca\xfb\x11\xd4\x82"
> +                         "\x30\x7a\x81\x35\xa0\xb4\xd4\xb6"
> +                         "\x84\xea\x47\x91\x8c\x19\x86\x25"
> +                         "\xa6\x06\x8d\x78\xe6\xed\x87\xeb"
> +                         "\xda\xea\x73\x7c\xbf\x66\xb8\x72"
> +                         "\xe3\x0a\xb8\x0c\xcb\x1a\x73\xf1"
> +                         "\xa7\xca\x0a\xde\x57\x2b\xbd\x2b"
> +                         "\xeb\x8b\x24\x38\x22\xd3\x0e\x1f"
> +                         "\x17\xa0\x84\x98\x31\x77\xfd\x34"
> +                         "\x6a\x4e\x3d\x84\x4c\x0e\xfb\xed"
> +                         "\xc8\x2a\x51\xfa\xd8\x73\x21\x8a"
> +                         "\xdb\xb5\xfe\x1f\xee\xc4\xe8\x65"
> +                         "\x54\x84\xdd\x96\x6d\xfd\xd3\x31"
> +                         "\x77\x36\x52\x6b\x80\x4f\x9e\xb4"
> +                         "\xa2\x55\xbf\x66\x41\x49\x4e\x87"
> +                         "\xa7\x0c\xca\xe7\xa5\xc5\xf6\x6f"
> +                         "\x27\x56\xe2\x48\x22\xdd\x5f\x59"
> +                         "\x3c\xf1\x9f\x83\xe5\x2d\xfb\x71"
> +                         "\xad\xd1\xae\x1b\x20\x5c\x47\xb7"
> +                         "\x3b\xd3\x14\xce\x81\x42\xb1\x0a"
> +                         "\xf0\x49\xfa\xc2\xe7\x86\xbf\xcd"
> +                         "\xb0\x95\x9f\x8f\x79\x41\x54",
> +               .ctext  = "\xf6\x57\x51\xc4\x25\x61\x2d\xfa"
> +                         "\xd6\xd9\x3f\x9a\x81\x51\xdd\x8e"
> +                         "\x3d\xe7\xaa\x2d\xb1\xda\xc8\xa6"
> +                         "\x9d\xaa\x3c\xab\x62\xf2\x80\xc3"
> +                         "\x2c\xe7\x58\x72\x1d\x44\xc5\x28"
> +                         "\x7f\xb4\xf9\xbc\x9c\xb2\xab\x8e"
> +                         "\xfa\xd1\x4d\x72\xd9\x79\xf5\xa0"
> +                         "\x24\x3e\x90\x25\x31\x14\x38\x45"
> +                         "\x59\xc8\xf6\xe2\xc6\xf6\xc1\xa7"
> +                         "\xb2\xf8\xa7\xa9\x2b\x6f\x12\x3a"
> +                         "\xb0\x81\xa4\x08\x57\x59\xb1\x56"
> +                         "\x4c\x8f\x18\x55\x33\x5f\xd6\x6a"
> +                         "\xc6\xa0\x4b\xd6\x6b\x64\x3e\x9e"
> +                         "\xfd\x66\x16\xe2\xdb\xeb\x5f\xb3"
> +                         "\x50\x50\x3e\xde\x8d\x72\x76\x01"
> +                         "\xbe\xcc\xc9\x52\x09\x2d\x8d\xe7"
> +                         "\xd6\xc3\x66\xdb\x36\x08\xd1\x77"
> +                         "\xc8\x73\x46\x26\x24\x29\xbf\x68"
> +                         "\x2d\x2a\x99\x43\x56\x55\xe4\x93"
> +                         "\xaf\xae\x4d\xe7\x55\x4a\xc0\x45"
> +                         "\x26\xeb\x3b\x12\x90\x7c\xdc\xd1"
> +                         "\xd5\x6f\x0a\xd0\xa9\xd7\x4b\x89"
> +                         "\x0b\x07\xd8\x86\xad\xa1\xc4\x69"
> +                         "\x1f\x5e\x8b\xc4\x9e\x91\x41\x25"
> +                         "\x56\x98\x69\x78\x3a\x9e\xae\x91"
> +                         "\xd8\xd9\xfa\xfb\xff\x81\x25\x09"
> +                         "\xfc\xed\x2d\x87\xbc\x04\x62\x97"
> +                         "\x35\xe1\x26\xc2\x46\x1c\xcf\xd7"
> +                         "\x14\xed\x02\x09\xa5\xb2\xb6\xaa"
> +                         "\x27\x4e\x61\xb3\x71\x6b\x47\x16"
> +                         "\xb7\xe8\xd4\xaf\x52\xeb\x6a\x6b"
> +                         "\xdb\x4c\x65\x21\x9e\x1c\x36",
> +               .klen   = 32,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x56\x33\x37\x21\xc4\xea\x8b\x88"
> +                         "\x67\x5e\xee\xb8\x0b\x6c\x04\x43"
> +                         "\x17\xc5\x2b\x8a\x37\x17\x8b\x37"
> +                         "\x60\x57\x3f\xa7\x82\xcd\xb9\x09",
> +               .iv     = "\x88\xee\x9b\x35\x21\x2d\x41\xa1"
> +                         "\x16\x0d\x7f\xdf\x57\xc9\xb9\xc3"
> +                         "\xf6\x30\x53\xbf\x89\x46\xe6\x87"
> +                         "\x60\xc8\x5e\x59\xdd\x8a\x7b\xfe",
> +               .ptext  = "\x49\xe2\x0a\x4f\x7a\x60\x75\x9b"
> +                         "\x95\x98\x2c\xe7\x4f\xb4\x58\xb9"
> +                         "\x24\x54\x46\x34\xdf\x58\x31\xe7"
> +                         "\x23\xc6\xa2\x60\x4a\xd2\x59\xb6"
> +                         "\xeb\x3e\xc2\xf8\xe5\x14\x3c\x6d"
> +                         "\x4b\x72\xcb\x5f\xcb\xa7\x47\xb9"
> +                         "\x7a\x49\xfc\xf1\xad\x92\x76\x55"
> +                         "\xac\x59\xdc\x3a\xc6\x8b\x7c\xdb"
> +                         "\x06\xcd\xea\x6a\x34\x51\xb7\xb2"
> +                         "\xe5\x39\x3c\x87\x00\x90\xc2\xbb"
> +                         "\xb2\xa5\x2c\x58\xc2\x9b\xe3\x77"
> +                         "\x95\x82\x50\xcb\x23\xdc\x18\xd8"
> +                         "\x4e\xbb\x13\x5d\x35\x3d\x9a\xda"
> +                         "\xe4\x75\xa1\x75\x17\x59\x8c\x6a"
> +                         "\xb2\x76\x7e\xd4\x45\x31\x0a\x45"
> +                         "\x2e\x60\x83\x3d\xdc\x8d\x43\x20"
> +                         "\x58\x24\xb2\x9d\xd5\x59\x64\x32"
> +                         "\x4e\x6f\xb9\x9c\xde\x77\x4d\x65"
> +                         "\xdf\xc0\x7a\xeb\x40\x80\xe8\xe5"
> +                         "\xc7\xc1\x77\x3b\xae\x2b\x85\xce"
> +                         "\x56\xfa\x43\x41\x96\x23\x8e\xab"
> +                         "\xd3\xc8\x65\xef\x0b\xfe\x42\x4c"
> +                         "\x3a\x8a\x54\x55\xab\xa3\xf9\x62"
> +                         "\x9f\x8e\xbe\x33\x9a\xfe\x6b\x52"
> +                         "\xd4\x4c\x93\x84\x7c\x7e\xb1\x5e"
> +                         "\x32\xaf\x6e\x21\x44\xd2\x6b\x56"
> +                         "\xcd\x2c\x9d\x03\x3b\x50\x1f\x0a"
> +                         "\xc3\x98\xff\x3a\x1d\x36\x7e\x6d"
> +                         "\xcf\xbc\xe7\xe8\xfc\x24\x55\xfd"
> +                         "\x72\x3d\xa7\x3f\x09\xa7\x38\xe6"
> +                         "\x57\x8d\xc4\x74\x7f\xd3\x26\x75"
> +                         "\xda\xfa\x29\x35\xc1\x31\x82",
> +               .ctext  = "\x02\x23\x74\x02\x56\xf4\x7b\xc8"
> +                         "\x55\x61\xa0\x6b\x68\xff\xde\x87"
> +                         "\x9d\x66\x77\x86\x98\x63\xab\xd5"
> +                         "\xd6\xf4\x7e\x3b\xf4\xae\x97\x13"
> +                         "\x79\xc0\x96\x75\x87\x33\x2a\x0e"
> +                         "\xc2\x1a\x13\x90\x5f\x6e\x93\xed"
> +                         "\x54\xfe\xee\x05\x48\xae\x20\x2d"
> +                         "\xa9\x2b\x98\xa3\xc8\xaf\x17\x6b"
> +                         "\x82\x4a\x9a\x7f\xf0\xce\xd9\x26"
> +                         "\x16\x28\xeb\xf4\x4b\xab\x7d\x6e"
> +                         "\x96\x27\xd2\x90\xbb\x8d\x98\xdc"
> +                         "\xb8\x6f\x7a\x98\x67\xef\x1c\xfb"
> +                         "\xd0\x23\x1a\x2f\xc9\x58\x4e\xc6"
> +                         "\x38\x03\x53\x61\x8e\xff\x55\x46"
> +                         "\x47\xe8\x1f\x9d\x66\x95\x9b\x7f"
> +                         "\x26\xac\xf2\x61\xa4\x05\x15\xcb"
> +                         "\x62\xb6\x6b\x7c\x57\x95\x9d\x25"
> +                         "\x9e\x83\xb1\x88\x50\x39\xb5\x34"
> +                         "\x8a\x04\x2b\x76\x1b\xb8\x8c\x57"
> +                         "\x26\x21\x99\x2e\x93\xc8\x9b\xb2"
> +                         "\x31\xe1\xe3\x27\xde\xc8\xf2\xc5"
> +                         "\x01\x7a\x45\x38\x6f\xe7\xa0\x9d"
> +                         "\x8c\x41\x99\xec\x3d\xb6\xaf\x66"
> +                         "\x76\xac\xc8\x78\xb0\xdf\xcf\xce"
> +                         "\xa1\x29\x46\x6f\xe3\x35\x4a\x67"
> +                         "\x59\x27\x14\xcc\x04\xdb\xb3\x03"
> +                         "\xb7\x2d\x8d\xf9\x75\x9e\x59\x42"
> +                         "\xe3\xa4\xf8\xf4\x82\x27\xa3\xa9"
> +                         "\x79\xac\x6b\x8a\xd8\xdb\x29\x73"
> +                         "\x02\xbb\x6f\x85\x00\x92\xea\x59"
> +                         "\x30\x1b\x19\xf3\xab\x6e\x99\x9a"
> +                         "\xf2\x23\x27\xc6\x59\x5a\x9c",
> +               .klen   = 32,
> +               .len    = 255,
> +       },
> +
> +};
> +
>  #endif /* _CRYPTO_TESTMGR_H */
> --
> 2.35.0.rc0.227.g00780c9af4-goog
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From krzysztof.kozlowski at canonical.com  Thu Jan 27 01:33:33 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Thu, 27 Jan 2022 10:33:33 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
Message-ID: <cb11d2e0-dd03-9a48-74f3-0a22f49f16b5@canonical.com>

On 27/12/2021 12:29, Krzysztof Kozlowski wrote:
> Hi,
> 
> Second pull with DTS for ARM64, on top of previous pull.
> 
> Best regards,
> Krzysztof
> 
> 
> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
> 
>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
> 
> are available in the Git repository at:
> 
>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
> 
> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
> 
>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
> 
> ----------------------------------------------------------------
> Samsung DTS ARM64 changes for v5.17, part two
> 
> Add initial Exynos850 support and WinLink E850-96 board using it.
> 
> ----------------------------------------------------------------
> Sam Protsenko (2):
>       arm64: dts: exynos: Add initial Exynos850 SoC support
>       arm64: dts: exynos: Add initial E850-96 board support
> 

I'll send all this as v5.18 material, so this pull-req can be skipped.


Best regards,
Krzysztof


From quic_jinlmao at quicinc.com  Thu Jan 27 01:33:26 2022
From: quic_jinlmao at quicinc.com (Jinlong Mao)
Date: Thu, 27 Jan 2022 17:33:26 +0800
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <20220126153437.GA2144852@p14s>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
 <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
 <20220121171552.GA1811357@p14s>
 <24c09945-bcda-81e4-f53c-af871f696094@quicinc.com>
 <20220126153437.GA2144852@p14s>
Message-ID: <25d9a681-b899-5936-868d-34f645ee40ef@quicinc.com>


On 1/26/2022 11:34 PM, Mathieu Poirier wrote:
> On Wed, Jan 26, 2022 at 03:07:38PM +0800, Jinlong Mao wrote:
>> Hi Mathieu,
>>
>> Good afternoon.
>>
>> On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
>>> Hey Jinlong,
>>>
>>> On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
>>>> Hi Mathieu,
>>>>
>>>> Good Day.
>>>>
>>>> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
>>>>> [...]
>>>>>
>>>>>>>>> +
>>>>>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>>>>>> +{
>>>>>>>>> +    static int traceid = TPDM_TRACE_ID_START;
>>>>>>>>> +
>>>>>>>>> +    drvdata->traceid = traceid++;
>>>>>>>>> +}
>>>>>>>> I have been specific on how to properly do this in the last revision.  Given the
>>>>>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>>>>>
>>>>>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>>>>>> process it before the holidays.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Mathieu
>>>>>>> Hi Mathieu,
>>>>>>>
>>>>>>> Sorry, not addressed your previous comments here.
>>>>>>>
>>>>>>> For the trace id, each coresight component has 7 bits to store the trace
>>>>>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>>>>>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>>>>>> Architecture specification v3.0
>>>>>>
>>>>> Correct
>>>>>
>>>>>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>>>>>> our internal device. About 80 ids are already used.
>>>>>>>
>>>>>>> Some components have fixed trace id in HW. If we use functions below to
>>>>>>> count the trace id, there will be conflict to other components.
>>>>>>>
>>>>>>> Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
>>>>>>> components ? And handle trace ids in its' own driver ?
>>>>>>>
>>>>>> This will limit systems to 15 cores - some have more!
>>>>>>
>>>>> Correct
>>>>>
>>>>>>> static inline int coresight_get_system_trace_id(int id)
>>>>>>> {
>>>>>>>             /* Start system IDs above the highest per CPU trace ID. */
>>>>>>>             return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>>>>>> }
>>>>> Looking at my own suggestion again this won't work since it returns the same traceID
>>>>> when called multiple times.
>>>>>
>>>>> For this patchset and _without_ taking into account internal devices that have
>>>>> their traceID set in HW:
>>>>>
>>>>> 1. Define a bitmask that is 7 bit wide.
>>>> Should it be a 128 bit wide bitmask? (0--127)?
>>> Yes, you are correct.
>>>
>>>>> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
>>>>> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
>>>>> first available bit after cpumask_last(cpu_possible_mask) + 1.
>>>> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
>>>> Return the first zero bit position as the trace id and set the bit.
>>> I need to clarify something with Mike on this - I will get back to you on
>>> Monday.
>> Do you have more comments on this ?
> I just received clarifications on this - there is no need to continue enacting
> the current scheme and as such reserving bits following the above formula will
> not be needed either.  Simply assigning free traceIDs based on request will
> work just fine.
>
> That of course is taking into account that 0x0, 0x1 and 0x70 - 0x7f are
> reserved.  0x1 is currently used for STM and should eventually be fixed to
> simply request a traceID the same way any other component do.  You can fix it as
> part of this set but it is not mandatory.
>
> Let me know if there are things I haven't been clear on.
>
> Thanks,
> Mathieu

Hi Mathieu,


Do you mean ETM sources and other sources can share the same 
"coresight_get_trace_id" function ?


int trace_id = 1;

int coresight_get_trace_id ()
{
 ?? ?trace_id += 1;
 ?? ?if (trace_id > 1 && trace_id < 0x70)
 ?? ???? return trace_id;
 ?? ?else
 ?? ???? return -EINVAL;
}

or do we still need a different function for other sources like use 
"coresight_get_system_trace_id" ?
Return the id from 1 and skip the ids which equeals to 
CORESIGHT_ETM_PMU_SEED + (cpu * 2).

Thanks

Jinlong Mao

>>>>> 4. Define a new function called coresight_put_system_trace_id(int id) that
>>>>> clears the bit in the mask corresponding to @id.
>>>>>
>>>>> For now that should work.
>>>>>
>>>>>>> static inline int coresight_get_trace_id(int cpu)
>>>>>>> {
>>>>>>>         /*
>>>>>>>          * A trace ID of value 0 is invalid, so let's start at some
>>>>>>>          * random value that fits in 7 bits and go from there.  Since
>>>>>>>          * the common convention is to have data trace IDs be I(N) + 1,
>>>>>>>          * set instruction trace IDs as a function of the CPU number.
>>>>>>>          */
>>>>>>>         return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>>>>>> }
>>>>>>>
>>>>>> This fixed relationship between cpu and trace ID is used in the perf
>>>>>> tooling to populate the elements in the perf.data file to correctly
>>>>>> allow association between CPU and trace data, and thus allow correct
>>>>>> trace decode.
>>>>> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
>>>>> perf header - theoretically we should be able to change the allocation scheme
>>>>> without impacting the decoding process.
>>>>>
>>>>>> It should be possible to create another more dynamic mapping scheme -
>>>>>> but this must include a way to support the perf requirements too.
>>>>>>
>>>>> TraceIDs have been a lurking problem for as long as the subsystem has existed.
>>>>> For now what I have suggested above should be sufficient to provide an
>>>>> in-between solution that doesn't hold back this patchset.
>>>>>
>>>>> That being said, we need to start thinking about the best way to do this.  I
>>>>> will put a patchset together in the new year that aims in that direction.
>>>>>
>>>>>> Regards
>>>>>>
>>>>>> Mike
>>>>>>
>>>>>>> Thanks
>>>>>>>
>>>>>>> Jinlong Mao
>>>>>>>
>>>>>>>>> +
>>>>>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>>>>> +{
>>>>>>>>> +    struct device *dev = &adev->dev;
>>>>>>>>> +    struct coresight_platform_data *pdata;
>>>>>>>>> +    struct tpdm_drvdata *drvdata;
>>>>>>>>> +    struct coresight_desc desc = { 0 };
>>>>>>>>> +
>>>>>>>>> +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>>>>>> +    if (!desc.name)
>>>>>>>>> +            return -ENOMEM;
>>>>>>>>> +    pdata = coresight_get_platform_data(dev);
>>>>>>>>> +    if (IS_ERR(pdata))
>>>>>>>>> +            return PTR_ERR(pdata);
>>>>>>>>> +    adev->dev.platform_data = pdata;
>>>>>>>>> +
>>>>>>>>> +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>>>>>> +    if (!drvdata)
>>>>>>>>> +            return -ENOMEM;
>>>>>>>>> +    drvdata->dev = &adev->dev;
>>>>>>>>> +    dev_set_drvdata(dev, drvdata);
>>>>>>>>> +
>>>>>>>>> +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>>>>>> +    if (!drvdata->base)
>>>>>>>>> +            return -ENOMEM;
>>>>>>>>> +
>>>>>>>>> +    mutex_init(&drvdata->lock);
>>>>>>>>> +
>>>>>>>>> +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>>>>>> +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>>>>>> +    desc.ops = &tpdm_cs_ops;
>>>>>>>>> +    desc.pdata = adev->dev.platform_data;
>>>>>>>>> +    desc.dev = &adev->dev;
>>>>>>>>> +    drvdata->csdev = coresight_register(&desc);
>>>>>>>>> +    if (IS_ERR(drvdata->csdev))
>>>>>>>>> +            return PTR_ERR(drvdata->csdev);
>>>>>>>>> +
>>>>>>>>> +    tpdm_init_default_data(drvdata);
>>>>>>>>> +    pm_runtime_put(&adev->dev);
>>>>>>>>> +
>>>>>>>>> +    return 0;
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>>>>>> +{
>>>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>>>>>> +
>>>>>>>>> +    coresight_unregister(drvdata->csdev);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static struct amba_id tpdm_ids[] = {
>>>>>>>>> +    {
>>>>>>>>> +            .id = 0x000f0e00,
>>>>>>>>> +            .mask = 0x000fff00,
>>>>>>>>> +    },
>>>>>>>>> +    { 0, 0},
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +static struct amba_driver tpdm_driver = {
>>>>>>>>> +    .drv = {
>>>>>>>>> +            .name   = "coresight-tpdm",
>>>>>>>>> +            .owner  = THIS_MODULE,
>>>>>>>>> +            .suppress_bind_attrs = true,
>>>>>>>>> +    },
>>>>>>>>> +    .probe          = tpdm_probe,
>>>>>>>>> +    .id_table       = tpdm_ids,
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +module_amba_driver(tpdm_driver);
>>>>>>>>> +
>>>>>>>>> +MODULE_LICENSE("GPL v2");
>>>>>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>>> new file mode 100644
>>>>>>>>> index 000000000000..980ae90ff1c8
>>>>>>>>> --- /dev/null
>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>>> @@ -0,0 +1,31 @@
>>>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>>>> +/*
>>>>>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>>>> +
>>>>>>>>> +/* Default value of the traceid */
>>>>>>>>> +#define TPDM_TRACE_ID_START 128
>>>>>>>>> +
>>>>>>>>> +/**
>>>>>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>>>>>> + * @base:       memory mapped base address for this component.
>>>>>>>>> + * @dev:        The device entity associated to this component.
>>>>>>>>> + * @csdev:      component vitals needed by the framework.
>>>>>>>>> + * @lock:       lock for the enable value.
>>>>>>>>> + * @enable:     enable status of the component.
>>>>>>>>> + * @traceid:    value of the current ID for this component.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +struct tpdm_drvdata {
>>>>>>>>> +    void __iomem            *base;
>>>>>>>>> +    struct device           *dev;
>>>>>>>>> +    struct coresight_device *csdev;
>>>>>>>>> +    struct mutex            lock;
>>>>>>>>> +    bool                    enable;
>>>>>>>>> +    int                     traceid;
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>>>>>> --- a/include/linux/coresight.h
>>>>>>>>> +++ b/include/linux/coresight.h
>>>>>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>>>>>>         CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>>>>>>         CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>>>>>>         CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>>>>>> +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>>>>>>      };
>>>>>>>>>
>>>>>>>>>      enum coresight_dev_subtype_helper {
>>>>>>>>> --
>>>>>>>>> 2.17.1
>>>>>>>>>
>>>>>> -- 
>>>>>> Mike Leach
>>>>>> Principal Engineer, ARM Ltd.
>>>>>> Manchester Design Centre. UK


From ardb at kernel.org  Thu Jan 27 01:42:49 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 10:42:49 +0100
Subject: [RFC PATCH 1/7] crypto: xctr - Add XCTR support
In-Reply-To: <20220125014422.80552-2-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-2-nhuck@google.com>
Message-ID: <CAMj1kXHCXNZEuK7hY5MfiBE2xAHbTN=ZOtm4zKzd4=dfTErgDA@mail.gmail.com>

On Tue, 25 Jan 2022 at 02:46, Nathan Huckleberry <nhuck at google.com> wrote:
>
> Add a generic implementation of XCTR mode as a template.  XCTR is a
> blockcipher mode similar to CTR mode.  XCTR uses XORs and little-endian
> addition rather than big-endian arithmetic which makes it slightly
> faster on little-endian CPUs.  It is used as a component to implement
> HCTR2.
>
> More information on XCTR mode can be found in the HCTR2 paper:
> https://eprint.iacr.org/2021/1441.pdf
>
> Signed-off-by: Nathan Huckleberry <nhuck at google.com>
> ---
>  crypto/Kconfig        |   9 +
>  crypto/Makefile       |   1 +
>  crypto/tcrypt.c       |   1 +
>  crypto/testmgr.c      |   6 +
>  crypto/testmgr.h      | 546 ++++++++++++++++++++++++++++++++++++++++++
>  crypto/xctr.c         | 202 ++++++++++++++++
>  include/crypto/xctr.h |  19 ++
>  7 files changed, 784 insertions(+)
>  create mode 100644 crypto/xctr.c
>  create mode 100644 include/crypto/xctr.h
>
> diff --git a/crypto/Kconfig b/crypto/Kconfig
> index 94bfa32cc6a1..b00de5f22eaf 100644
> --- a/crypto/Kconfig
> +++ b/crypto/Kconfig
> @@ -452,6 +452,15 @@ config CRYPTO_PCBC
>           PCBC: Propagating Cipher Block Chaining mode
>           This block cipher algorithm is required for RxRPC.
>
> +config CRYPTO_XCTR
> +       tristate
> +       select CRYPTO_SKCIPHER
> +       select CRYPTO_MANAGER
> +       help
> +         XCTR: XOR Counter mode. This blockcipher mode is a variant of CTR mode
> +         using XORs and little-endian addition rather than big-endian arithmetic.
> +         XCTR mode is used to implement HCTR2.
> +
>  config CRYPTO_XTS
>         tristate "XTS support"
>         select CRYPTO_SKCIPHER
> diff --git a/crypto/Makefile b/crypto/Makefile
> index d76bff8d0ffd..6b3fe3df1489 100644
> --- a/crypto/Makefile
> +++ b/crypto/Makefile
> @@ -93,6 +93,7 @@ obj-$(CONFIG_CRYPTO_CTS) += cts.o
>  obj-$(CONFIG_CRYPTO_LRW) += lrw.o
>  obj-$(CONFIG_CRYPTO_XTS) += xts.o
>  obj-$(CONFIG_CRYPTO_CTR) += ctr.o
> +obj-$(CONFIG_CRYPTO_XCTR) += xctr.o
>  obj-$(CONFIG_CRYPTO_KEYWRAP) += keywrap.o
>  obj-$(CONFIG_CRYPTO_ADIANTUM) += adiantum.o
>  obj-$(CONFIG_CRYPTO_NHPOLY1305) += nhpoly1305.o
> diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
> index 00149657a4bc..da7848f84d12 100644
> --- a/crypto/tcrypt.c
> +++ b/crypto/tcrypt.c
> @@ -1750,6 +1750,7 @@ static int do_test(const char *alg, u32 type, u32 mask, int m, u32 num_mb)
>                 ret += tcrypt_test("rfc3686(ctr(aes))");
>                 ret += tcrypt_test("ofb(aes)");
>                 ret += tcrypt_test("cfb(aes)");
> +               ret += tcrypt_test("xctr(aes)");
>                 break;
>
>         case 11:
> diff --git a/crypto/testmgr.c b/crypto/testmgr.c
> index 5831d4bbc64f..5acf92354543 100644
> --- a/crypto/testmgr.c
> +++ b/crypto/testmgr.c
> @@ -5454,6 +5454,12 @@ static const struct alg_test_desc alg_test_descs[] = {
>                 .suite = {
>                         .cipher = __VECS(xchacha20_tv_template)
>                 },
> +       }, {
> +               .alg = "xctr(aes)",
> +               .test = alg_test_skcipher,
> +               .suite = {
> +                       .cipher = __VECS(aes_xctr_tv_template)
> +               }
>         }, {
>                 .alg = "xts(aes)",
>                 .generic_driver = "xts(ecb(aes-generic))",
> diff --git a/crypto/testmgr.h b/crypto/testmgr.h
> index a253d66ba1c1..e1ebbb3c4d4c 100644
> --- a/crypto/testmgr.h
> +++ b/crypto/testmgr.h
> @@ -32800,4 +32800,550 @@ static const struct hash_testvec blakes2s_256_tv_template[] = {{
>                           0xd5, 0x06, 0xb5, 0x3a, 0x7c, 0x7a, 0x65, 0x1d, },
>  }};
>
> +/*
> + * Test vectors generated using https://github.com/google/hctr2
> + */
> +static const struct cipher_testvec aes_xctr_tv_template[] = {
> +       {
> +               .key    = "\x06\x20\x5d\xba\x50\xb5\x12\x8e"
> +                         "\xee\x65\x3c\x59\x80\xa1\xfe\xb1",
> +               .iv     = "\x16\x52\x22\x0d\x1c\x76\x94\x9f"
> +                         "\x74\xba\x41\x0c\xc4\xc4\xaf\xb9",
> +               .ptext  = "\x02\x62\x54\x87\x28\x8f\xa1\xd3"
> +                         "\x8f\xd8\xc6\xab\x08\xef\xea\x83"
> +                         "\xa3\xbd\xf4\x85\x47\x66\x74\x11"
> +                         "\xf1\x58\x9f\x9f\xe8\xb9\x95\xc9",
> +               .ctext  = "\x11\xfe\xef\xb4\x9e\xed\x5b\xe5"
> +                         "\x92\x9b\x03\xa7\x6d\x8e\xf9\x7a"
> +                         "\xaa\xfa\x33\x4a\xf7\xd9\xb2\xeb"
> +                         "\x73\xa1\x85\xbc\x45\xbc\x42\x70",
> +               .klen   = 16,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\x19\x0e\xea\x30\x59\x8e\x39\x35"
> +                         "\x93\x63\xcc\x8b\x5f\x98\x4f\x43",
> +               .iv     = "\x4b\x9f\xf4\xd8\xaa\xcf\x99\xdc"
> +                         "\xc5\x07\xe0\xde\xb2\x6d\x85\x12",
> +               .ptext  = "\x23\x2d\x48\x15\x89\x34\x54\xf9"
> +                         "\x2b\x38\xd1\x62\x06\x98\x21\x59"
> +                         "\xd4\x3a\x45\x6f\x12\x27\x08\xa9"
> +                         "\x3e\x0f\x21\x3d\xda\x80\x92\x3f",
> +               .ctext  = "\x01\xa7\xe5\x9e\xf8\x49\xbb\x36"
> +                         "\x49\xb8\x59\x7a\x77\x3f\x5a\x10"
> +                         "\x2e\x8f\xe7\xc9\xc4\xb8\xdb\x86"
> +                         "\xe4\xc0\x6b\x60\x2f\x79\xa0\x91",
> +               .klen   = 16,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\x17\xa6\x01\x3d\x5d\xd6\xef\x2d"
> +                         "\x69\x8f\x4c\x54\x5b\xae\x43\xf0",
> +               .iv     = "\xa9\x1b\x47\x60\x26\x82\xf7\x1c"
> +                         "\x80\xf8\x88\xdd\xfb\x44\xd9\xda",
> +               .ptext  = "\xf7\x67\xcd\xa6\x04\x65\x53\x99"
> +                         "\x90\x5c\xa2\x56\x74\xd7\x9d\xf2"
> +                         "\x0b\x03\x7f\x4e\xa7\x84\x72\x2b"
> +                         "\xf0\xa5\xbf\xe6\x9a\x62\x3a\xfe"
> +                         "\x69\x5c\x93\x79\x23\x86\x64\x85"
> +                         "\xeb\x13\xb1\x5a\xd5\x48\x39\xa0"
> +                         "\x70\xfb\x06\x9a\xd7\x12\x5a\xb9"
> +                         "\xbe\xed\x2c\x81\x64\xf7\xcf\x80"
> +                         "\xee\xe6\x28\x32\x2d\x37\x4c\x32"
> +                         "\xf4\x1f\x23\x21\xe9\xc8\xc9\xbf"
> +                         "\x54\xbc\xcf\xb4\xc2\x65\x39\xdf"
> +                         "\xa5\xfb\x14\x11\xed\x62\x38\xcf"
> +                         "\x9b\x58\x11\xdd\xe9\xbd\x37\x57"
> +                         "\x75\x4c\x9e\xd5\x67\x0a\x48\xc6"
> +                         "\x0d\x05\x4e\xb1\x06\xd7\xec\x2e"
> +                         "\x9e\x59\xde\x4f\xab\x38\xbb\xe5"
> +                         "\x87\x04\x5a\x2c\x2a\xa2\x8f\x3c"
> +                         "\xe7\xe1\x46\xa9\x49\x9f\x24\xad"
> +                         "\x2d\xb0\x55\x40\x64\xd5\xda\x7e"
> +                         "\x1e\x77\xb8\x29\x72\x73\xc3\x84"
> +                         "\xcd\xf3\x94\x90\x58\x76\xc9\x2c"
> +                         "\x2a\xad\x56\xde\x33\x18\xb6\x3b"
> +                         "\x10\xe9\xe9\x8d\xf0\xa9\x7f\x05"
> +                         "\xf7\xb5\x8c\x13\x7e\x11\x3d\x1e"
> +                         "\x02\xbb\x5b\xea\x69\xff\x85\xcf"
> +                         "\x6a\x18\x97\x45\xe3\x96\xba\x4d"
> +                         "\x2d\x7a\x70\x78\x15\x2c\xe9\xdc"
> +                         "\x4e\x09\x92\x57\x04\xd8\x0b\xa6"
> +                         "\x20\x71\x76\x47\x76\x96\x89\xa0"
> +                         "\xd9\x29\xa2\x5a\x06\xdb\x56\x39"
> +                         "\x60\x33\x59\x04\x95\x89\xf6\x18"
> +                         "\x1d\x70\x75\x85\x3a\xb7\x6e",
> +               .ctext  = "\xe1\xe7\x3f\xd3\x6a\xb9\x2f\x64"
> +                         "\x37\xc5\xa4\xe9\xca\x0a\xa1\xd6"
> +                         "\xea\x7d\x39\xe5\xe6\xcc\x80\x54"
> +                         "\x74\x31\x2a\x04\x33\x79\x8c\x8e"
> +                         "\x4d\x47\x84\x28\x27\x9b\x3c\x58"
> +                         "\x54\x58\x20\x4f\x70\x01\x52\x5b"
> +                         "\xac\x95\x61\x49\x5f\xef\xba\xce"
> +                         "\xd7\x74\x56\xe7\xbb\xe0\x3c\xd0"
> +                         "\x7f\xa9\x23\x57\x33\x2a\xf6\xcb"
> +                         "\xbe\x42\x14\x95\xa8\xf9\x7a\x7e"
> +                         "\x12\x53\x3a\xe2\x13\xfe\x2d\x89"
> +                         "\xeb\xac\xd7\xa8\xa5\xf8\x27\xf3"
> +                         "\x74\x9a\x65\x63\xd1\x98\x3a\x7e"
> +                         "\x27\x7b\xc0\x20\x00\x4d\xf4\xe5"
> +                         "\x7b\x69\xa6\xa8\x06\x50\x85\xb6"
> +                         "\x7f\xac\x7f\xda\x1f\xf5\x37\x56"
> +                         "\x9b\x2f\xd3\x86\x6b\x70\xbd\x0e"
> +                         "\x55\x9a\x9d\x4b\x08\xb5\x5b\x7b"
> +                         "\xd4\x7c\xb4\x71\x49\x92\x4a\x1e"
> +                         "\xed\x6d\x11\x09\x47\x72\x32\x6a"
> +                         "\x97\x53\x36\xaf\xf3\x06\x06\x2c"
> +                         "\x69\xf1\x59\x00\x36\x95\x28\x2a"
> +                         "\xb6\xcd\x10\x21\x84\x73\x5c\x96"
> +                         "\x86\x14\x2c\x3d\x02\xdb\x53\x9a"
> +                         "\x61\xde\xea\x99\x84\x7a\x27\xf6"
> +                         "\xf7\xc8\x49\x73\x4b\xb8\xeb\xd3"
> +                         "\x41\x33\xdd\x09\x68\xe2\x64\xb8"
> +                         "\x5f\x75\x74\x97\x91\x54\xda\xc2"
> +                         "\x73\x2c\x1e\x5a\x84\x48\x01\x1a"
> +                         "\x0d\x8b\x0a\xdf\x07\x2e\xee\x77"
> +                         "\x1d\x17\x41\x7a\xc9\x33\x63\xfa"
> +                         "\x9f\xc3\x74\x57\x5f\x03\x4c",
> +               .klen   = 16,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\xd1\x87\xd3\xa1\x97\x6a\x4b\xf9"
> +                         "\x5d\xcb\x6c\x07\x6e\x2d\x48\xad",
> +               .iv     = "\xe9\x8c\x88\x40\xa9\x52\xe0\xbc"
> +                         "\x8a\x47\x3a\x09\x5d\x60\xdd\xb2",
> +               .ptext  = "\x67\x80\x86\x46\x18\xc6\xed\xd2"
> +                         "\x99\x0f\x7a\xc3\xa5\x0b\x80\xcb"
> +                         "\x8d\xe4\x0b\x4c\x1e\x4c\x98\x46"
> +                         "\x87\x8a\x8c\x76\x75\xce\x2c\x27"
> +                         "\x74\x88\xdc\x37\xaa\x77\x53\x14"
> +                         "\xd3\x01\xcf\xb5\xcb\xdd\xb4\x8e"
> +                         "\x6b\x54\x68\x01\xc3\xdf\xbc\xdd"
> +                         "\x1a\x08\x4c\x11\xab\x25\x4b\x69"
> +                         "\x25\x21\x78\xb1\x91\x1b\x75\xfa"
> +                         "\xd0\x10\xf3\x8a\x65\xd3\x8d\x2e"
> +                         "\xf8\xb6\xce\x29\xf9\x1e\x45\x5f"
> +                         "\x4e\x41\x63\x6f\xf9\xca\x59\xd7"
> +                         "\xc8\x9c\x97\xda\xff\xab\x42\x47"
> +                         "\xfb\x2b\xca\xed\xda\x6c\x96\xe4"
> +                         "\x59\x0d\xc6\x4a\x26\xde\xa8\x50"
> +                         "\xc5\xbb\x13\xf8\xd1\xb9\x6b\xf4"
> +                         "\x19\x30\xfb\xc0\x4f\x6b\x96\xc4"
> +                         "\x88\x0b\x57\xb3\x43\xbd\xdd\xe2"
> +                         "\x06\xae\x88\x44\x41\xdf\xa4\x29"
> +                         "\x31\xd3\x38\xeb\xe9\xf8\xa2\xe4"
> +                         "\x6a\x55\x2f\x56\x58\x19\xeb\xf7"
> +                         "\x5f\x4b\x15\x52\xe4\xaa\xdc\x31"
> +                         "\x4a\x32\xc9\x31\x96\x68\x3b\x80"
> +                         "\x20\x4f\xe5\x8f\x87\xc9\x37\x58"
> +                         "\x79\xfd\xc9\xc1\x9a\x83\xe3\x8b"
> +                         "\x6b\x57\x07\xef\x28\x8d\x55\xcb"
> +                         "\x4e\xb6\xa2\xb6\xd3\x4f\x8b\x10"
> +                         "\x70\x10\x02\xf6\x74\x71\x20\x5a"
> +                         "\xe2\x2f\xb6\x46\xc5\x22\xa3\x29"
> +                         "\xf5\xc1\x25\xb0\x4d\xda\xaf\x04"
> +                         "\xca\x83\xe6\x3f\x66\x6e\x3b\xa4"
> +                         "\x09\x40\x22\xd7\x97\x12\x1e",
> +               .ctext  = "\xd4\x6d\xfa\xc8\x6e\x54\x31\x69"
> +                         "\x47\x51\x0f\xb8\xfa\x03\xa2\xe1"
> +                         "\x57\xa8\x4f\x2d\xc5\x4e\x8d\xcd"
> +                         "\x92\x0f\x71\x08\xdd\xa4\x5b\xc7"
> +                         "\x69\x3a\x3d\x93\x29\x1d\x87\x2c"
> +                         "\xfa\x96\xd2\x4d\x72\x61\xb0\x9e"
> +                         "\xa7\xf5\xd5\x09\x3d\x43\x32\x82"
> +                         "\xd2\x9a\x58\xe3\x4c\x84\xc2\xad"
> +                         "\x33\x77\x9c\x5d\x37\xc1\x4f\x95"
> +                         "\x56\x55\xc6\x76\x62\x27\x6a\xc7"
> +                         "\x45\x80\x9e\x7c\x48\xc8\x14\xbb"
> +                         "\x32\xbf\x4a\xbb\x8d\xb4\x2c\x7c"
> +                         "\x01\xfa\xc8\xde\x10\x55\xa0\xae"
> +                         "\x29\xed\xe2\x3d\xd6\x26\xfa\x3c"
> +                         "\x7a\x81\xae\xfd\xc3\x2f\xe5\x3a"
> +                         "\x00\xa3\xf0\x66\x0f\x3a\xd2\xa3"
> +                         "\xaf\x0e\x75\xbb\x79\xad\xcc\xe0"
> +                         "\x98\x10\xfb\xf1\xc0\x0c\xb9\x03"
> +                         "\x07\xee\x46\x6a\xc0\xf6\x17\x8f"
> +                         "\x7f\xc9\xad\x16\x58\x54\xb0\xd5"
> +                         "\x67\x73\x9f\xce\xea\x4b\x60\x57"
> +                         "\x1d\x62\x72\xec\xab\xe3\xd8\x32"
> +                         "\x29\x48\x37\x1b\x5c\xd6\xd0\xb7"
> +                         "\xc3\x39\xef\xf6\x1b\x18\xf6\xd1"
> +                         "\x2d\x76\x7c\x68\x50\x37\xfa\x8f"
> +                         "\x16\x87\x5e\xf8\xb1\x79\x82\x52"
> +                         "\xc7\x3e\x0e\xa3\x61\xb9\x00\xe0"
> +                         "\x2e\x03\x80\x6e\xc0\xbf\x63\x78"
> +                         "\xdf\xab\xc2\x3b\xf0\x4c\xb0\xcb"
> +                         "\x91\x6a\x26\xe6\x3a\x86\xef\x1a"
> +                         "\x4e\x4d\x23\x2d\x59\x3a\x02\x3a"
> +                         "\xf3\xda\xd1\x9d\x68\xf6\xef",
> +               .klen   = 16,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x17\xe6\xb1\x85\x40\x24\xbe\x80"
> +                         "\x99\xc7\xa1\x0c\x0f\x72\x31\xb8"
> +                         "\x10\xb5\x11\x21\x3a\x99\x9e\xc8",
> +               .iv     = "\x6b\x5f\xe1\x6a\xe1\x21\xfc\x62"
> +                         "\xd9\x85\x2e\x0b\xbd\x58\x79\xd1",
> +               .ptext  = "\xea\x3c\xad\x9d\x92\x05\x50\xa4"
> +                         "\x68\x56\x6b\x33\x95\xa8\x24\x6c"
> +                         "\xa0\x9d\x91\x15\x3a\x26\xb7\xeb"
> +                         "\xb4\x5d\xf7\x0c\xec\x91\xbe\x11",
> +               .ctext  = "\x6a\xac\xfc\x24\x64\x98\x28\x33"
> +                         "\xa4\x39\xfd\x72\x46\x56\x7e\xf7"
> +                         "\xd0\x7f\xee\x95\xd8\x68\x44\x67"
> +                         "\x70\x80\xd4\x69\x7a\xf5\x8d\xad",
> +               .klen   = 24,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\x02\x81\x0e\xb1\x97\xe0\x20\x0c"
> +                         "\x46\x8c\x7b\xde\xac\xe6\xe0\xb5"
> +                         "\x2e\xb3\xc0\x40\x0e\xb7\x3d\xd3",
> +               .iv     = "\x37\x15\x1c\x61\xab\x95\x8f\xf3"
> +                         "\x11\x3a\x79\xe2\xf7\x33\x96\xb3",
> +               .ptext  = "\x05\xd9\x7a\xc7\x08\x79\xba\xd8"
> +                         "\x4a\x63\x54\xf7\x4e\x0c\x98\x8a"
> +                         "\x5d\x40\x05\xe4\x7a\x7a\x14\x0c"
> +                         "\xa8\xa7\x53\xf4\x3e\x66\x81\x38",
> +               .ctext  = "\x43\x66\x70\x51\xd9\x7c\x6f\x80"
> +                         "\x82\x8e\x34\xda\x5d\x3c\x47\xd1"
> +                         "\xe0\x67\x76\xb5\x78\x98\x47\x26"
> +                         "\x41\x31\xfa\x97\xc9\x79\xeb\x15",
> +               .klen   = 24,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\x9a\xef\x58\x01\x4c\x1e\xa2\x33"
> +                         "\xce\x1f\x32\xae\xc8\x69\x1f\xf5"
> +                         "\x82\x1b\x74\xf4\x8b\x1b\xce\x30",
> +               .iv     = "\xb1\x72\x52\xa8\xc4\x8f\xb5\xec"
> +                         "\x95\x12\x14\x5f\xd2\x29\x14\x0f",
> +               .ptext  = "\x8a\xbc\x20\xbd\x67\x76\x8d\xd8"
> +                         "\xa6\x70\xf0\x74\x8c\x8d\x9c\x00"
> +                         "\xdd\xaf\xef\x28\x5d\x8d\xfa\x87"
> +                         "\x81\x39\x8c\xb1\x6e\x0a\xcf\x3c"
> +                         "\xe8\x3b\xc0\xff\x6e\xe7\xd1\xc6"
> +                         "\x70\xb8\xdf\x27\x62\x72\x8e\xb7"
> +                         "\x6b\xa7\xb2\x74\xdd\xc6\xb4\xc9"
> +                         "\x4c\xd8\x4f\x2c\x09\x75\x6e\xb7"
> +                         "\x41\xb3\x8f\x96\x09\x0d\x40\x8e"
> +                         "\x0f\x49\xc2\xad\xc4\xf7\x71\x0a"
> +                         "\x76\xfb\x45\x97\x29\x7a\xaa\x98"
> +                         "\x22\x55\x4f\x9c\x26\x01\xc8\xb9"
> +                         "\x41\x42\x51\x9d\x00\x5c\x7f\x02"
> +                         "\x9b\x00\xaa\xbd\x69\x47\x9c\x26"
> +                         "\x5b\xcb\x08\xf3\x46\x33\xf9\xeb"
> +                         "\x79\xdd\xfe\x38\x08\x84\x8c\x81"
> +                         "\xb8\x51\xbd\xcd\x72\x00\xdb\xbd"
> +                         "\xf5\xd6\xb4\x80\xf7\xd3\x49\xac"
> +                         "\x9e\xf9\xea\xd5\xad\xd4\xaa\x8f"
> +                         "\x97\x60\xce\x60\xa7\xdd\xc0\xb2"
> +                         "\x51\x80\x9b\xae\xab\x0d\x62\xab"
> +                         "\x78\x1a\xeb\x8c\x03\x6f\x30\xbf"
> +                         "\xe0\xe1\x20\x65\x74\x65\x54\x43"
> +                         "\x92\x57\xd2\x73\x8a\xeb\x99\x38"
> +                         "\xca\x78\xc8\x11\xd7\x92\x1a\x05"
> +                         "\x55\xb8\xfa\xa0\x82\xb7\xd6\x16"
> +                         "\x84\x4d\x25\xc4\xd5\xe4\x55\xf3"
> +                         "\x6c\xb3\xe4\x6e\x66\x31\x5c\x41"
> +                         "\x98\x46\x28\xd8\x71\x05\xf2\x3b"
> +                         "\xd1\x3e\x0f\x79\x7f\xf3\x30\x3f"
> +                         "\xbe\x36\xf4\x50\xbd\x0c\x89\xd5"
> +                         "\xcb\x53\x9f\xeb\x56\xf4\x3f",
> +               .ctext  = "\xee\x90\xe1\x45\xf5\xab\x04\x23"
> +                         "\x70\x0a\x54\x49\xac\x34\xb8\x69"
> +                         "\x3f\xa8\xce\xef\x6e\x63\xc1\x20"
> +                         "\x7a\x41\x43\x5d\xa2\x29\x71\x1d"
> +                         "\xd2\xbb\xb1\xca\xb4\x3a\x5a\xf3"
> +                         "\x0a\x68\x0b\x9d\x6f\x68\x60\x9e"
> +                         "\x9d\xb9\x23\x68\xbb\xdd\x12\x31"
> +                         "\xc6\xd6\xf9\xb3\x80\xe8\xb5\xab"
> +                         "\x84\x2a\x8e\x7b\xb2\x4f\xee\x31"
> +                         "\x83\xc4\x1c\x80\x89\xe4\xe7\xd2"
> +                         "\x00\x65\x98\xd1\x57\xcc\xf6\x87"
> +                         "\x14\xf1\x23\x22\x78\x61\xc7\xb6"
> +                         "\xf5\x90\x97\xdd\xcd\x90\x98\xd8"
> +                         "\xbb\x02\xfa\x2c\xf0\x89\xfc\x7e"
> +                         "\xe7\xcd\xee\x41\x3f\x73\x4a\x08"
> +                         "\xf8\x8f\xf3\xbf\x3a\xd5\xce\xb7"
> +                         "\x7a\xf4\x49\xcd\x3f\xc7\x1f\x77"
> +                         "\x98\xd0\x9d\x82\x20\x8a\x04\x5d"
> +                         "\x9f\x77\xcb\xf4\x38\x92\x47\xce"
> +                         "\x6d\xc3\x51\xc1\xd9\xf4\x2f\x65"
> +                         "\x67\x01\xf4\x46\x3b\xd2\x90\x5d"
> +                         "\x2a\xcb\xc5\x39\x1c\x72\xa5\xba"
> +                         "\xaf\x80\x9b\x87\x01\x85\xa1\x02"
> +                         "\xdf\x79\x4c\x27\x77\x3e\xfc\xb3"
> +                         "\x96\xbc\x42\xad\xdf\xa4\x16\x1e"
> +                         "\x77\xe7\x39\xcc\x78\x2c\xc1\x00"
> +                         "\xe5\xa6\xb5\x9b\x0c\x12\x19\xc5"
> +                         "\x8b\xbe\xae\x4b\xc3\xa3\x91\x8f"
> +                         "\x5b\x82\x0f\x20\x30\x35\x45\x26"
> +                         "\x29\x84\x2e\xc8\x2d\xce\xae\xac"
> +                         "\xbe\x93\x50\x7a\x6a\x01\x08\x38"
> +                         "\xf5\x49\x4d\x8b\x7e\x96\x70",
> +               .klen   = 24,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x2c\x3c\x6c\x78\xaa\x83\xed\x14"
> +                         "\x4e\xe5\xe2\x3e\x1e\x89\xcb\x2f"
> +                         "\x19\x5a\x70\x50\x09\x81\x43\x75",
> +               .iv     = "\xa5\x57\x8e\x3c\xba\x52\x87\x4f"
> +                         "\xb7\x45\x26\xab\x31\xb9\x58\xfa",
> +               .ptext  = "\x43\x29\x69\x02\xf0\xc0\x64\xf3"
> +                         "\xe1\x85\x75\x25\x11\x5d\x18\xf8"
> +                         "\xdc\x96\x82\x1b\xee\x4d\x01\xd2"
> +                         "\x28\x83\xbb\xfe\xe1\x72\x14\x3c"
> +                         "\xe9\xe5\x9f\x8c\x40\xb5\x0a\xaa"
> +                         "\x9f\xb8\xc5\xf1\x01\x05\x65\x79"
> +                         "\x90\x05\xeb\xac\xa8\x52\x35\xc4"
> +                         "\x2d\x56\x0d\xe1\x37\x09\xb8\xec"
> +                         "\x51\xd8\x79\x13\x5b\x85\x8c\x14"
> +                         "\x77\xe3\x64\xea\x89\xb1\x04\x9d"
> +                         "\x6c\x58\x1b\x51\x54\x1f\xc7\x2f"
> +                         "\xc8\x3d\xa6\x93\x39\xce\x77\x3a"
> +                         "\x93\xc2\xaa\x88\xcc\x09\xfa\xc4"
> +                         "\x5e\x92\x3b\x46\xd2\xd6\xd4\x5d"
> +                         "\x31\x58\xc5\xc6\x30\xb8\x7f\x77"
> +                         "\x0f\x1b\xf8\x9a\x7d\x3f\x56\x90"
> +                         "\x61\x8f\x08\x8f\x61\x64\x8e\xf4"
> +                         "\xaa\x7c\xf8\x4c\x0b\xab\x47\x2a"
> +                         "\x0d\xa7\x24\x36\x59\xfe\x94\xfc"
> +                         "\x38\x38\x32\xdf\x73\x1b\x75\xb1"
> +                         "\x6f\xa2\xd8\x0b\xa1\xd4\x31\x58"
> +                         "\xaa\x24\x11\x22\xc9\xf7\x83\x3c"
> +                         "\x6e\xee\x75\xc0\xdd\x3b\x21\x99"
> +                         "\x9f\xde\x81\x9c\x2a\x70\xc4\xb8"
> +                         "\xc6\x27\x4e\x5d\x9a\x4a\xe1\x75"
> +                         "\x01\x95\x47\x87\x3f\x9a\x69\x20"
> +                         "\xb4\x66\x70\x1a\xe2\xb3\x6c\xfa"
> +                         "\x1f\x6e\xf9\xc3\x8a\x1f\x0b\x0b"
> +                         "\xc5\x92\xba\xd9\xf8\x27\x6b\x97"
> +                         "\x01\xe2\x38\x01\x7f\x06\xde\x54"
> +                         "\xb7\x78\xbc\x7d\x6a\xa1\xf2\x6f"
> +                         "\x62\x42\x30\xbf\xb1\x6d\xc7",
> +               .ctext  = "\x53\xc0\xb3\x13\x8f\xbf\x88\x1a"
> +                         "\x6f\xda\xad\x0b\x33\x8b\x82\x9d"
> +                         "\xca\x17\x32\x65\xaa\x72\x24\x1b"
> +                         "\x95\x33\xcc\x5b\x58\x5d\x08\x58"
> +                         "\xe5\x52\xc0\xb7\xc6\x97\x77\x66"
> +                         "\xbd\xf4\x50\xde\xe1\xf0\x70\x61"
> +                         "\xc2\x05\xce\xe0\x90\x2f\x7f\xb3"
> +                         "\x04\x7a\xee\xbe\xb3\xb7\xaf\xda"
> +                         "\x3c\xb8\x95\xb4\x20\xba\x66\x0b"
> +                         "\x97\xcc\x07\x3f\x22\x07\x0e\xea"
> +                         "\x76\xd8\x32\xf9\x34\x47\xcb\xaa"
> +                         "\xb3\x5a\x06\x68\xac\x94\x10\x39"
> +                         "\xf2\x70\xe1\x7b\x98\x5c\x0c\xcb"
> +                         "\x8f\xd8\x48\xfa\x2e\x15\xa1\xf1"
> +                         "\x2f\x85\x55\x39\xd8\x24\xe6\xc1"
> +                         "\x6f\xd7\x52\x97\x42\x7a\x2e\x14"
> +                         "\x39\x74\x16\xf3\x8b\xbd\x38\xb9"
> +                         "\x54\x20\xc6\x31\x1b\x4c\xb7\x26"
> +                         "\xd4\x71\x63\x97\xaa\xbf\xf5\xb7"
> +                         "\x17\x5e\xee\x14\x67\x38\x14\x11"
> +                         "\xf6\x98\x3c\x70\x4a\x89\xf4\x27"
> +                         "\xb4\x72\x7a\xc0\x5d\x58\x3d\x8b"
> +                         "\xf6\xf7\x80\x7b\xa9\xa7\x4d\xf8"
> +                         "\x1a\xbe\x07\x0c\x06\x97\x25\xc8"
> +                         "\x5a\x18\xae\x21\xa6\xe4\x77\x13"
> +                         "\x5a\xe5\xf5\xe0\xd5\x48\x73\x22"
> +                         "\x68\xde\x70\x05\xc4\xdf\xd5\x7c"
> +                         "\xa0\x2b\x99\x9c\xa8\x21\xd7\x6c"
> +                         "\x55\x97\x09\xd6\xb0\x62\x93\x90"
> +                         "\x14\xb1\xd1\x83\x5a\xb3\x17\xb9"
> +                         "\xc7\xcc\x6b\x51\x23\x44\x4b\xef"
> +                         "\x48\x0f\x0f\xf0\x0e\xa1\x8f",
> +               .klen   = 24,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\xed\xd1\xcf\x81\x1c\xf8\x9d\x56"
> +                         "\xd4\x3b\x86\x4b\x65\x96\xfe\xe8"
> +                         "\x8a\xd4\x3b\xd7\x76\x07\xab\xf4"
> +                         "\xe9\xae\xd1\x4d\x50\x9b\x94\x1c",
> +               .iv     = "\x09\x90\xf3\x7c\x15\x99\x7d\x94"
> +                         "\x88\xf4\x99\x19\xd1\x62\xc4\x65",
> +               .ptext  = "\xa2\x06\x41\x55\x60\x2c\xe3\x76"
> +                         "\xa9\xaf\xf9\xe1\xd7\x0d\x65\x49"
> +                         "\xda\x27\x0d\xf8\xec\xdc\x09\x2b"
> +                         "\x06\x24\xe4\xd5\x15\x29\x6b\x5f",
> +               .ctext  = "\xad\x5c\xd0\xc1\x03\x45\xba\x9d"
> +                         "\xab\x6d\x82\xae\xf7\x8e\x2b\x8b"
> +                         "\xd8\x61\xe6\x96\x5c\x5c\xe2\x70"
> +                         "\xe5\x19\x0a\x04\x60\xca\x45\xfc",
> +               .klen   = 32,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\xf8\x75\xa6\xba\x7b\x00\xf0\x71"
> +                         "\x24\x5d\xdf\x93\x8b\xa3\x7d\x6d"
> +                         "\x8e\x0f\x65\xf4\xe2\xbe\x2b\xaa"
> +                         "\x2a\x0d\x9e\x00\x6a\x94\x80\xa1",
> +               .iv     = "\xb9\xb7\x55\x26\x5f\x96\x16\x68"
> +                         "\x5c\x5f\x58\xbb\x4e\x5a\xe1\x3b",
> +               .ptext  = "\x2f\xd9\x2c\xc2\x98\x1e\x81\x5e"
> +                         "\x89\xc8\xec\x1f\x56\x3e\xd9\xa4"
> +                         "\x92\x48\xec\xfc\x5d\xeb\x7f\xad"
> +                         "\x7a\x47\xe6\xda\x71\x1b\x2e\xfa",
> +               .ctext  = "\x25\x5e\x38\x20\xcf\xbe\x4c\x6c"
> +                         "\xe6\xce\xfc\xe2\xca\x6a\xa1\x62"
> +                         "\x3a\xb7\xdf\x21\x3e\x49\xa6\xb8"
> +                         "\x22\xd2\xc8\x37\xa4\x55\x09\xe6",
> +               .klen   = 32,
> +               .len    = 32,
> +       },
> +       {
> +               .key    = "\x32\x37\x2b\x8f\x7b\xb1\x23\x79"
> +                         "\x05\x52\xde\x05\xf1\x68\x3f\x6c"
> +                         "\xa4\xae\xbc\x21\xc2\xc6\xf0\xbd"
> +                         "\x0f\x20\xb7\xa4\xc5\x05\x7b\x64",
> +               .iv     = "\xff\x26\x4e\x67\x48\xdd\xcf\xfe"
> +                         "\x42\x09\x04\x98\x5f\x1e\xfa\x80",
> +               .ptext  = "\x99\xdc\x3b\x19\x41\xf9\xff\x6e"
> +                         "\x76\xb5\x03\xfa\x61\xed\xf8\x44"
> +                         "\x70\xb9\xf0\x83\x80\x6e\x31\x77"
> +                         "\x77\xe4\xc7\xb4\x77\x02\xab\x91"
> +                         "\x82\xc6\xf8\x7c\x46\x61\x03\x69"
> +                         "\x09\xa0\xf7\x12\xb7\x81\x6c\xa9"
> +                         "\x10\x5c\xbb\x55\xb3\x44\xed\xb5"
> +                         "\xa2\x52\x48\x71\x90\x5d\xda\x40"
> +                         "\x0b\x7f\x4a\x11\x6d\xa7\x3d\x8e"
> +                         "\x1b\xcd\x9d\x4e\x75\x8b\x7d\x87"
> +                         "\xe5\x39\x34\x32\x1e\xe6\x8d\x51"
> +                         "\xd4\x1f\xe3\x1d\x50\xa0\x22\x37"
> +                         "\x7c\xb0\xd9\xfb\xb6\xb2\x16\xf6"
> +                         "\x6d\x26\xa0\x4e\x8c\x6a\xe6\xb6"
> +                         "\xbe\x4c\x7c\xe3\x88\x10\x18\x90"
> +                         "\x11\x50\x19\x90\xe7\x19\x3f\xd0"
> +                         "\x31\x15\x0f\x06\x96\xfe\xa7\x7b"
> +                         "\xc3\x32\x88\x69\xa4\x12\xe3\x64"
> +                         "\x02\x30\x17\x74\x6c\x88\x7c\x9b"
> +                         "\xd6\x6d\x75\xdf\x11\x86\x70\x79"
> +                         "\x48\x7d\x34\x3e\x33\x58\x07\x8b"
> +                         "\xd2\x50\xac\x35\x15\x45\x05\xb4"
> +                         "\x4d\x31\x97\x19\x87\x23\x4b\x87"
> +                         "\x53\xdc\xa9\x19\x78\xf1\xbf\x35"
> +                         "\x30\x04\x14\xd4\xcf\xb2\x8c\x87"
> +                         "\x7d\xdb\x69\xc9\xcd\xfe\x40\x3e"
> +                         "\x8d\x66\x5b\x61\xe5\xf0\x2d\x87"
> +                         "\x93\x3a\x0c\x2b\x04\x98\x05\xc2"
> +                         "\x56\x4d\xc4\x6c\xcd\x7a\x98\x7e"
> +                         "\xe2\x2d\x79\x07\x91\x9f\xdf\x2f"
> +                         "\x72\xc9\x8f\xcb\x0b\x87\x1b\xb7"
> +                         "\x04\x86\xcb\x47\xfa\x5d\x03",
> +               .ctext  = "\x0b\x00\xf7\xf2\xc8\x6a\xba\x9a"
> +                         "\x0a\x97\x18\x7a\x00\xa0\xdb\xf4"
> +                         "\x5e\x8e\x4a\xb7\xe0\x51\xf1\x75"
> +                         "\x17\x8b\xb4\xf1\x56\x11\x05\x9f"
> +                         "\x2f\x2e\xba\x67\x04\xe1\xb4\xa5"
> +                         "\xfc\x7c\x8c\xad\xc6\xb9\xd1\x64"
> +                         "\xca\xbd\x5d\xaf\xdb\x65\x48\x4f"
> +                         "\x1b\xb3\x94\x5c\x0b\xd0\xee\xcd"
> +                         "\xb5\x7f\x43\x8a\xd8\x8b\x66\xde"
> +                         "\xd2\x9c\x13\x65\xa4\x47\xa7\x03"
> +                         "\xc5\xa1\x46\x8f\x2f\x84\xbc\xef"
> +                         "\x48\x9d\x9d\xb5\xbd\x43\xff\xd2"
> +                         "\xd2\x7a\x5a\x13\xbf\xb4\xf6\x05"
> +                         "\x17\xcd\x01\x12\xf0\x35\x27\x96"
> +                         "\xf4\xc1\x65\xf7\x69\xef\x64\x1b"
> +                         "\x6e\x4a\xe8\x77\xce\x83\x01\xb7"
> +                         "\x60\xe6\x45\x2a\xcd\x41\x4a\xb5"
> +                         "\x8e\xcc\x45\x93\xf1\xd6\x64\x5f"
> +                         "\x32\x60\xe4\x29\x4a\x82\x6c\x86"
> +                         "\x16\xe4\xcc\xdb\x5f\xc8\x11\xa6"
> +                         "\xfe\x88\xd6\xc3\xe5\x5c\xbb\x67"
> +                         "\xec\xa5\x7b\xf5\xa8\x4f\x77\x25"
> +                         "\x5d\x0c\x2a\x99\xf9\xb9\xd1\xae"
> +                         "\x3c\x83\x2a\x93\x9b\x66\xec\x68"
> +                         "\x2c\x93\x02\x8a\x8a\x1e\x2f\x50"
> +                         "\x09\x37\x19\x5c\x2a\x3a\xc2\xcb"
> +                         "\xcb\x89\x82\x81\xb7\xbb\xef\x73"
> +                         "\x8b\xc9\xae\x42\x96\xef\x70\xc0"
> +                         "\x89\xc7\x3e\x6a\x26\xc3\xe4\x39"
> +                         "\x53\xa9\xcf\x63\x7d\x05\xf3\xff"
> +                         "\x52\x04\xf6\x7f\x23\x96\xe9\xf7"
> +                         "\xff\xd6\x50\xa3\x0e\x20\x71",
> +               .klen   = 32,
> +               .len    = 255,
> +       },
> +       {
> +               .key    = "\x49\x85\x84\x69\xd4\x5f\xf9\xdb"
> +                         "\xf2\xc4\x1c\x62\x20\x88\xea\x8a"
> +                         "\x5b\x69\xe6\x3b\xe2\x5c\xfe\xce"
> +                         "\xe1\x7a\x27\x7b\x1c\xc9\xb4\x43",
> +               .iv     = "\xae\x98\xdb\xef\x5c\x6b\xe9\x27"
> +                         "\x1a\x2f\x51\x17\x97\x7d\x4f\x10",
> +               .ptext  = "\xbe\xf2\x8f\x8a\x51\x9e\x3d\xff"
> +                         "\xd7\x68\x0f\xd2\xf2\x5b\xe3\xa5"
> +                         "\x59\x3e\xcd\xab\x46\xc6\xe9\x24"
> +                         "\x43\xbc\xb8\x37\x1f\x55\x7f\xb5"
> +                         "\xc0\xa6\x68\xdf\xbf\x21\x1e\xed"
> +                         "\x67\x73\xb7\x06\x47\xff\x67\x07"
> +                         "\x5b\x94\xab\xef\x43\x95\x52\xce"
> +                         "\xe7\x71\xbd\x72\x5b\x3a\x25\x01"
> +                         "\xed\x7d\x02\x2d\x72\xd6\xc4\x3d"
> +                         "\xd2\xf5\xe5\xb3\xf2\xd7\xa1\x8d"
> +                         "\x12\x0d\x3b\x4a\x58\xf4\x1b\xfd"
> +                         "\xcd\x2c\x13\x05\x07\x3d\x30\x8a"
> +                         "\x1f\xc6\xed\xfc\x7c\x3c\xa6\x1c"
> +                         "\x64\x2c\x36\xa8\x5d\xe2\xfa\x12"
> +                         "\xd7\x17\xa9\x39\x43\x63\xbf\x44"
> +                         "\xd0\xcb\x4c\xf0\xab\xe6\x75\xd6"
> +                         "\x60\xd1\x64\x9e\x01\x2b\x97\x52"
> +                         "\x97\x24\x32\xb0\xfa\x22\xf4\x04"
> +                         "\xe6\x98\x6a\xbc\xba\xe8\x65\xad"
> +                         "\x60\x08\xfc\xd7\x40\xf8\x2a\xf2"
> +                         "\x5e\x32\x32\x82\x24\x12\xda\xbc"
> +                         "\x8f\x1c\xd4\x06\x81\x08\x80\x35"
> +                         "\x20\xa5\xa8\x3a\x6e\x3e\x2f\x78"
> +                         "\xe4\x7d\x9e\x81\x43\xb8\xfe\xa7"
> +                         "\x3b\xa9\x9b\x1a\xe7\xce\xd2\x3d"
> +                         "\xc1\x27\x26\x22\x35\x12\xa2\xc6"
> +                         "\x59\x51\x22\x31\x7b\xc8\xca\xa6"
> +                         "\xa9\xf3\x16\x57\x72\x3d\xfa\x24"
> +                         "\x66\x56\x5d\x21\x29\x9e\xf2\xff"
> +                         "\xae\x0c\x71\xcf\xc5\xf0\x98\xe5"
> +                         "\xa1\x05\x96\x94\x3e\x36\xed\x97"
> +                         "\xc7\xee\xcd\xc2\x54\x35\x5c",
> +               .ctext  = "\xde\x7f\x5e\xac\x6f\xec\xed\x2a"
> +                         "\x3a\x3b\xb3\x36\x19\x46\x26\x27"
> +                         "\x09\x7b\x49\x47\x1b\x88\x43\xb7"
> +                         "\x65\x67\xef\x0b\xe4\xde\x0a\x97"
> +                         "\x7f\xab\x32\x7c\xa2\xde\x4e\xba"
> +                         "\x11\x9b\x19\x12\x7d\x03\x01\x15"
> +                         "\xa3\x90\x9f\x52\x9d\x29\x3d\x5c"
> +                         "\xc6\x71\x59\x2c\x44\x8f\xb7\x8c"
> +                         "\x0d\x75\x81\x76\xe2\x11\x96\x41"
> +                         "\xae\x48\x27\x0e\xbc\xaf\x1d\xf5"
> +                         "\x51\x68\x5a\x34\xe5\x6d\xdf\x60"
> +                         "\xc7\x9d\x4e\x1a\xaa\xb5\x1a\x57"
> +                         "\x58\x6a\xa4\x79\x0a\xa9\x50\x8d"
> +                         "\x93\x59\xef\x5b\x23\xdb\xc8\xb3"
> +                         "\x38\x96\x8c\xdf\x7d\x6a\x3d\x53"
> +                         "\x84\x9d\xb0\xf0\x07\x5f\xff\x67"
> +                         "\xff\x5b\x3c\x8b\x1f\xa2\x3b\xcf"
> +                         "\xf5\x86\x7c\xbc\x98\x38\x7a\xe5"
> +                         "\x96\x56\xba\x44\x85\x29\x4f\x3a"
> +                         "\x64\xde\xec\xc6\x53\xf0\x30\xca"
> +                         "\xa4\x90\x4f\x9c\x2e\x0e\xec\x2d"
> +                         "\x8c\x38\x1c\x93\x9a\x5d\x5d\x98"
> +                         "\xf9\x2c\xf7\x27\x71\x3c\x69\xa9"
> +                         "\x0b\xec\xd9\x9c\x6c\x69\x09\x47"
> +                         "\xd9\xc2\x84\x6e\x3e\x2d\x9f\x1f"
> +                         "\xb6\x13\x62\x4c\xf3\x33\x44\x13"
> +                         "\x6c\x43\x0a\xae\x8e\x89\xd6\x27"
> +                         "\xdd\xc3\x5b\x37\x62\x09\x47\x94"
> +                         "\xe3\xea\x7d\x08\x14\x70\xb1\x8e"
> +                         "\x83\x4a\xcb\xc0\xa9\xf2\xa3\x02"
> +                         "\xe9\xa0\x44\xfe\xcf\x5a\x15\x50"
> +                         "\xc4\x5a\x6f\xc8\xd6\xf1\x83",
> +               .klen   = 32,
> +               .len    = 255,
> +       },
> +};
> +
>  #endif /* _CRYPTO_TESTMGR_H */
> diff --git a/crypto/xctr.c b/crypto/xctr.c
> new file mode 100644
> index 000000000000..dfb44c092cc4
> --- /dev/null
> +++ b/crypto/xctr.c
> @@ -0,0 +1,202 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * XCTR: XOR Counter mode - Adapted from ctr.c
> + *
> + * (C) Copyright IBM Corp. 2007 - Joy Latten <latten at us.ibm.com>
> + * Copyright 2021 Google LLC
> + */
> +
> +/*
> + * XCTR mode is a blockcipher mode of operation used to implement HCTR2. XCTR is
> + * closely related to the CTR mode of operation; the main difference is that CTR
> + * generates the keystream using E(CTR + IV) whereas XCTR generates the
> + * keystream using E(CTR ^ IV).
> + *
> + * See the HCTR2 paper for more details:
> + *     Length-preserving encryption with HCTR2
> + *      (https://eprint.iacr.org/2021/1441.pdf)
> + */
> +
> +#include <crypto/algapi.h>
> +#include <crypto/xctr.h>
> +#include <crypto/internal/cipher.h>
> +#include <crypto/internal/skcipher.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +
> +static void crypto_xctr_crypt_final(struct skcipher_walk *walk,
> +                                  struct crypto_cipher *tfm, u32 byte_ctr)
> +{
> +       unsigned int bsize = crypto_cipher_blocksize(tfm);
> +       unsigned long alignmask = crypto_cipher_alignmask(tfm);
> +       u8 ctr[MAX_CIPHER_BLOCKSIZE];
> +       u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
> +       u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
> +       u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
> +       u8 *src = walk->src.virt.addr;
> +       u8 *dst = walk->dst.virt.addr;
> +       unsigned int nbytes = walk->nbytes;
> +       u32 ctr32 = byte_ctr / bsize + 1;
> +
> +       u32_to_le_block(ctr, ctr32, bsize);
> +       crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
> +       crypto_cipher_encrypt_one(tfm, keystream, ctrblk);
> +       crypto_xor_cpy(dst, keystream, src, nbytes);
> +}
> +
> +static int crypto_xctr_crypt_segment(struct skcipher_walk *walk,
> +                                   struct crypto_cipher *tfm, u32 byte_ctr)
> +{
> +       void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
> +                  crypto_cipher_alg(tfm)->cia_encrypt;
> +       unsigned int bsize = crypto_cipher_blocksize(tfm);
> +       u8 ctr[MAX_CIPHER_BLOCKSIZE];
> +       u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
> +       u8 *src = walk->src.virt.addr;
> +       u8 *dst = walk->dst.virt.addr;
> +       unsigned int nbytes = walk->nbytes;
> +       u32 ctr32 = byte_ctr / bsize + 1;
> +
> +       do {
> +               /* create keystream */
> +               u32_to_le_block(ctr, ctr32, bsize);
> +               crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
> +               fn(crypto_cipher_tfm(tfm), dst, ctrblk);
> +               crypto_xor(dst, src, bsize);
> +
> +               ctr32++;
> +
> +               src += bsize;
> +               dst += bsize;
> +       } while ((nbytes -= bsize) >= bsize);
> +
> +       return nbytes;
> +}
> +
> +static int crypto_xctr_crypt_inplace(struct skcipher_walk *walk,
> +                                   struct crypto_cipher *tfm, u32 byte_ctr)
> +{
> +       void (*fn)(struct crypto_tfm *, u8 *, const u8 *) =
> +                  crypto_cipher_alg(tfm)->cia_encrypt;
> +       unsigned int bsize = crypto_cipher_blocksize(tfm);
> +       unsigned long alignmask = crypto_cipher_alignmask(tfm);
> +       unsigned int nbytes = walk->nbytes;
> +       u8 ctr[MAX_CIPHER_BLOCKSIZE];
> +       u8 ctrblk[MAX_CIPHER_BLOCKSIZE];
> +       u8 *src = walk->src.virt.addr;
> +       u8 tmp[MAX_CIPHER_BLOCKSIZE + MAX_CIPHER_ALIGNMASK];
> +       u8 *keystream = PTR_ALIGN(tmp + 0, alignmask + 1);
> +       u32 ctr32 = byte_ctr / bsize + 1;
> +
> +       u32_to_le_block(ctr, ctr32, bsize);
> +       do {
> +               /* create keystream */
> +               u32_to_le_block(ctr, ctr32, bsize);
> +               crypto_xor_cpy(ctrblk, ctr, walk->iv, bsize);
> +               fn(crypto_cipher_tfm(tfm), keystream, ctrblk);
> +               crypto_xor(src, keystream, bsize);
> +
> +               ctr32++;
> +
> +               src += bsize;
> +       } while ((nbytes -= bsize) >= bsize);
> +
> +       return nbytes;
> +}
> +
> +static int crypto_xctr_crypt(struct skcipher_request *req)
> +{
> +       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> +       struct crypto_cipher *cipher = skcipher_cipher_simple(tfm);
> +       const unsigned int bsize = crypto_cipher_blocksize(cipher);
> +       struct skcipher_walk walk;
> +       unsigned int nbytes;
> +       int err;
> +       u32 byte_ctr = 0;
> +
> +       err = skcipher_walk_virt(&walk, req, false);
> +
> +       while (walk.nbytes >= bsize) {
> +               if (walk.src.virt.addr == walk.dst.virt.addr)
> +                       nbytes = crypto_xctr_crypt_inplace(&walk, cipher, byte_ctr);
> +               else
> +                       nbytes = crypto_xctr_crypt_segment(&walk, cipher, byte_ctr);
> +
> +               byte_ctr += walk.nbytes - nbytes;
> +               err = skcipher_walk_done(&walk, nbytes);
> +       }
> +
> +       if (walk.nbytes) {
> +               crypto_xctr_crypt_final(&walk, cipher, byte_ctr);
> +               err = skcipher_walk_done(&walk, 0);
> +       }
> +
> +       return err;
> +}
> +
> +static int crypto_xctr_create(struct crypto_template *tmpl, struct rtattr **tb)
> +{
> +       struct skcipher_instance *inst;
> +       struct crypto_alg *alg;
> +       int err;
> +
> +       inst = skcipher_alloc_instance_simple(tmpl, tb);
> +       if (IS_ERR(inst))
> +               return PTR_ERR(inst);
> +
> +       alg = skcipher_ialg_simple(inst);
> +
> +       /* Block size must be >= 4 bytes. */
> +       err = -EINVAL;
> +       if (alg->cra_blocksize < 4)
> +               goto out_free_inst;
> +
> +       /* XCTR mode is a stream cipher. */
> +       inst->alg.base.cra_blocksize = 1;
> +
> +       /*
> +        * To simplify the implementation, configure the skcipher walk to only
> +        * give a partial block at the very end, never earlier.
> +        */
> +       inst->alg.chunksize = alg->cra_blocksize;
> +
> +       inst->alg.encrypt = crypto_xctr_crypt;
> +       inst->alg.decrypt = crypto_xctr_crypt;
> +
> +       err = skcipher_register_instance(tmpl, inst);
> +       if (err) {
> +out_free_inst:
> +               inst->free(inst);
> +       }
> +
> +       return err;
> +}
> +
> +static struct crypto_template crypto_xctr_tmpl[] = {
> +       {
> +               .name = "xctr",
> +               .create = crypto_xctr_create,
> +               .module = THIS_MODULE,
> +       }
> +};
> +
> +static int __init crypto_xctr_module_init(void)
> +{
> +       return crypto_register_template(crypto_xctr_tmpl);
> +}
> +
> +static void __exit crypto_xctr_module_exit(void)
> +{
> +       crypto_unregister_template(crypto_xctr_tmpl);
> +}
> +
> +subsys_initcall(crypto_xctr_module_init);
> +module_exit(crypto_xctr_module_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("XCTR block cipher mode of operation");
> +MODULE_ALIAS_CRYPTO("xctr");
> +MODULE_IMPORT_NS(CRYPTO_INTERNAL);
> diff --git a/include/crypto/xctr.h b/include/crypto/xctr.h
> new file mode 100644
> index 000000000000..0d025e08ca26
> --- /dev/null
> +++ b/include/crypto/xctr.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * XCTR: XOR Counter mode
> + *
> + * Copyright 2021 Google LLC
> + */
> +
> +#include <asm/unaligned.h>
> +
> +#ifndef _CRYPTO_XCTR_H
> +#define _CRYPTO_XCTR_H
> +
> +static inline void u32_to_le_block(u8 *a, u32 x, unsigned int size)
> +{
> +       memset(a, 0, size);
> +       put_unaligned(cpu_to_le32(x), (u32 *)a);

Please use put_unaligned_le32() here.

And casting 'a' to (u32 *) is invalid C, so just pass 'a' directly.
Otherwise, the compiler might infer that 'a' is guaranteed to be
aligned after all, and use an aligned access instead.


> +}
> +
> +#endif  /* _CRYPTO_XCTR_H */
> --
> 2.35.0.rc0.227.g00780c9af4-goog
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From pgwipeout at gmail.com  Thu Jan 27 01:52:49 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 04:52:49 -0500
Subject: [PATCH 2/3] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
In-Reply-To: <e2479729-154a-122f-f2e0-89b62ffe2c8d@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <20220127010023.3169415-3-pgwipeout@gmail.com>
 <e2479729-154a-122f-f2e0-89b62ffe2c8d@gmail.com>
Message-ID: <CAMdYzYrKjVvXHftaJDyOv6MwjEwmvwgMnzZK4gm0+D=XuA+ijg@mail.gmail.com>

On Thu, Jan 27, 2022 at 12:57 AM Johan Jonker <jbx6244 at gmail.com> wrote:
>
> Hi Peter,

Good Morning,

The Rockchip schematics IO Power Domain Map is rarely *if ever* 100%
accurate, you need to check the actual schematic for ground truth.

>
> On 1/27/22 02:00, Peter Geis wrote:
> > Several io power domains on the Quartz64-A operate at 1.8v.
> > Add the pmu_io_domains definition to enable support for this.
> > This permits the enablement of the following features:
> > sdio - wifi support
> > sdhci - mmc-hs200-1_8v
> >
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >  arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > index d9eb92d59099..33c2c18caaa9 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > @@ -482,6 +482,19 @@ vcc_sd_h: vcc-sd-h {
> >       };
> >  };
> >
>
> https://files.pine64.org/doc/quartz64/Quartz64_model-A_schematic_v2.0_20210427.pdf
>
> Could you check with the IO Power Domain Map?
>
> > +&pmu_io_domains {
> > +     pmuio1-supply = <&vcc3v3_pmu>;
> VCC3V3_PMU
>
> > +     pmuio2-supply = <&vcc3v3_pmu>;
> VCC3V3_PMU
>
> > +     vccio1-supply = <&vccio_acodec>;
> VCCIO_ACODEC
>
> > +     vccio2-supply = <&vcc_1v8>;
> VCC_1V8
>
> > +     vccio3-supply = <&vccio_sd>;
> VCCIO_SD
>
> > +     vccio4-supply = <&vcc_1v8>;
> ==> VCC1V8_PMU

Page 16 of the schematic, VCCIO4 is tied to VCC_1V8 via R1519

>
> > +     vccio5-supply = <&vcc_3v3>;
> ==> VCC_1V8

Page 20 of the schematic, VCCIO5 is tied to VCC_3V3 via R1800

>
> > +     vccio6-supply = <&vcc1v8_dvp>;
> VCC1V8_DVP
>
> > +     vccio7-supply = <&vcc_3v3>;
> VCC_3V3
>
> > +     status = "okay";
> > +};
> > +
> >  &sdhci {
> >       bus-width = <8>;
> >       mmc-hs200-1_8v;

Thanks for double checking,
Peter


From pgwipeout at gmail.com  Thu Jan 27 01:55:13 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 04:55:13 -0500
Subject: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <20220127010023.3169415-4-pgwipeout@gmail.com>
 <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>
Message-ID: <CAMdYzYrKq==Bs0aonrJBC+W2c4nQ8cUn2dn_Se4WDaRCkT6SYg@mail.gmail.com>

On Thu, Jan 27, 2022 at 1:18 AM Johan Jonker <jbx6244 at gmail.com> wrote:
>
>
>
> On 1/27/22 02:00, Peter Geis wrote:
> > The sdmmc1 node on Quartz64-A supports the optional wifi module from
> > Pine64.
> > Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> > the Quartz64-A.
> >
> > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > ---
> >  .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 45 +++++++++++++++++++
> >  1 file changed, 45 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > index 33c2c18caaa9..1d73ac6557c5 100644
> > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > @@ -91,6 +91,18 @@ simple-audio-card,codec {
> >               };
> >       };
> >
> > +     sdio_pwrseq: sdio-pwrseq {
>
> > +             status = "okay";
>
> When a node is not previously disabled, then there's no need for "okay".

Thanks, this is here in case an end user wants to easily hack the
board to use this for other purposes.

>
> > +             compatible = "mmc-pwrseq-simple";
> > +             clocks = <&rk817 1>;
> > +             clock-names = "ext_clock";
> > +             pinctrl-names = "default";
> > +             pinctrl-0 = <&wifi_enable_h>;
> > +             reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
> > +             post-power-on-delay-ms = <100>;
> > +             power-off-delay-us = <5000000>;
> > +     };
> > +
> >       vcc12v_dcin: vcc12v_dcin {
> >               compatible = "regulator-fixed";
> >               regulator-name = "vcc12v_dcin";
> > @@ -147,6 +159,17 @@ vcc_sys: vcc_sys {
> >               regulator-max-microvolt = <4400000>;
> >               vin-supply = <&vbus>;
> >       };
> > +
> > +     /* sourced from vcc_sys, sdio module operates internally at 3.3v */
> > +     vcc_wl: vcc_wl {
> > +             compatible = "regulator-fixed";
> > +             regulator-name = "vcc_wl";
> > +             regulator-always-on;
> > +             regulator-boot-on;
> > +             regulator-min-microvolt = <3300000>;
> > +             regulator-max-microvolt = <3300000>;
> > +             vin-supply = <&vcc_sys>;
> > +     };
> >  };
> >
> >  &cpu0 {
> > @@ -475,6 +498,12 @@ pmic_int_l: pmic-int-l {
> >               };
> >       };
> >
> > +     sdio-pwrseq {
> > +             wifi_enable_h: wifi-enable-h {
> > +                     rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
> > +             };
> > +     };
> > +
> >       vcc_sd {
> >               vcc_sd_h: vcc-sd-h {
> >                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
> > @@ -516,6 +545,22 @@ &sdmmc0 {
> >       status = "okay";
> >  };
> >
> > +&sdmmc1 {
> > +     bus-width = <4>;
> > +     cap-sd-highspeed;
> > +     cap-sdio-irq;
>
> > +     disable-wp;
>
> From mmc-controller.yaml:
>
>   disable-wp:
>     $ref: /schemas/types.yaml#/definitions/flag
>     description:
>       When set, no physical write-protect line is present. This
>       property should only be specified when the controller has a
>       dedicated write-protect detection logic. If a GPIO is always used
>       for the write-protect detection logic, it is sufficient to not
>       specify the wp-gpios property in the absence of a write-protect
>       line. Not used in combination with eMMC or SDIO.

Appreciate it, I will drop this.

>
> > +     keep-power-in-suspend;
> > +     mmc-pwrseq = <&sdio_pwrseq>;
> > +     non-removable;
> > +     pinctrl-names = "default";
> > +     pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
> > +     sd-uhs-sdr104;
> > +     vmmc-supply = <&vcc_wl>;
> > +     vqmmc-supply = <&vcc_1v8>;
> > +     status = "okay";
> > +};
> > +
> >  &spdif {
> >       status = "okay";
> >  };


From arnd at arndb.de  Thu Jan 27 02:00:54 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 27 Jan 2022 11:00:54 +0100
Subject: [PATCH 11/13] ARM: ixp4xx: Drop custom DMA coherency and bouncing
In-Reply-To: <20220127003656.330161-12-linus.walleij@linaro.org>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
 <20220127003656.330161-12-linus.walleij@linaro.org>
Message-ID: <CAK8P3a3eqGSZ68smMRdYKOEyghX+tnpfsVqHGYhtFcWTYqf+Pg@mail.gmail.com>

On Thu, Jan 27, 2022 at 1:36 AM Linus Walleij <linus.walleij at linaro.org> wrote:
> @@ -381,10 +378,8 @@ config ARCH_IOP32X
>  config ARCH_IXP4XX
>         bool "IXP4xx-based"
>         depends on MMU
> -       select ARCH_HAS_DMA_SET_COHERENT_MASK
>         select ARCH_SUPPORTS_BIG_ENDIAN
>         select CPU_XSCALE
> -       select DMABOUNCE if PCI
>         select GENERIC_IRQ_MULTI_HANDLER
>         select GPIO_IXP4XX
>         select GPIOLIB

Very nice! AFAICT CONFIG_DMABOUNCE is now only used for the sa1111-ohci
driver on the SA1100 Assabet's neponset add-on -- the other sa1111
based machines
are either not supported by the kernel, or don't need the quirk, while other
devices on sa11111 don't have DMA (ps2, ssp, pcmcia) or no driver (audio).

Maybe we could change the sa1111-ohci driver to use usb_hcd_setup_local_mem(),
which implements a similar method locally, and then kill off dmabounce for good.

usb_hcd_setup_local_mem() is used on some pxa machines (csb726 with ohci-sm501
and eseries/tosa with ohci-tmio), though they use it to DMA into a
small SRAM (8KB
for tmio, 256KB for sm501) rather than a limited section of DRAM.

         Arnd


From bigeasy at linutronix.de  Thu Jan 27 02:07:25 2022
From: bigeasy at linutronix.de (Sebastian Andrzej Siewior)
Date: Thu, 27 Jan 2022 11:07:25 +0100
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <87r18u2wr8.mognet@arm.com>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de>
 <87czq573et.mognet@arm.com> <YfF9I5PcZJA5532B@linutronix.de>
 <87r18u2wr8.mognet@arm.com>
Message-ID: <YfJu3Z9wKOAjLuad@linutronix.de>

On 2022-01-26 18:10:51 [+0000], Valentin Schneider wrote:
> > | 2021-08-11 21:13 +0100 Valentin Schneider    ? sched: Introduce migratable()
> > | 2021-08-11 21:13 +0100 Valentin Schneider    ? arm64: mm: Make arch_faults_on_old_pte() check for migratability
?
> Heh, had forgotten about those - I'm happy to repost with the
> s/migratable/is_migratable/. I also need to go back to those splats I got
> on my emag and fix the PMU/GPIO warnings...

Now that I look at it gain, you might want to drop #1 and then #2 would
switch to cant_migrate(). This might work?

Sebastian


From narmstrong at baylibre.com  Thu Jan 27 02:15:12 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:15:12 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
In-Reply-To: <20220126234325.GA7363@odroid-VirtualBox>
References: <20220126234325.GA7363@odroid-VirtualBox>
Message-ID: <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>

Hi,

On 27/01/2022 00:43, Lutz Koschorreck wrote:
> The interrupt pin of the external ethernet phy is used, instead of the
> enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> the gpio_ao bank.
> Using open drain prevents reboot issues.
> 
> This causes phy interrupt problems at system startup.
> [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> [   76.649635] Call trace:
> [   76.649638]  dump_backtrace+0x0/0x1c8
> [   76.649658]  show_stack+0x14/0x60
> [   76.649667]  dump_stack_lvl+0x64/0x7c
> [   76.649676]  dump_stack+0x14/0x2c
> [   76.649683]  __report_bad_irq+0x38/0xe8
> [   76.649695]  note_interrupt+0x220/0x3a0
> [   76.649704]  handle_irq_event_percpu+0x58/0x88
> [   76.649713]  handle_irq_event+0x44/0xd8
> [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> [   76.649730]  generic_handle_domain_irq+0x38/0x58
> [   76.649738]  gic_handle_irq+0x9c/0xb8
> [   76.649747]  call_on_irq_stack+0x28/0x38
> [   76.649755]  do_interrupt_handler+0x7c/0x80
> [   76.649763]  el1_interrupt+0x34/0x80
> [   76.649772]  el1h_64_irq_handler+0x14/0x20
> [   76.649781]  el1h_64_irq+0x74/0x78
> [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> [   76.649796]  irq_thread_fn+0x5c/0x98
> [   76.649804]  irq_thread+0x13c/0x260
> [   76.649812]  kthread+0x144/0x178
> [   76.649822]  ret_from_fork+0x10/0x20
> [   76.649830] handlers:
> [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> [   76.661256] Disabling IRQ #36
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> 
> Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 0bd1e98a0eef..ddb1b345397f 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;

Wow, indeed it's not the right GPIO chip... my bad.

>  		enable-active-high;
>  		regulator-always-on;
>  

Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?

Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?

Neil



From heiko at sntech.de  Thu Jan 27 02:15:13 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Thu, 27 Jan 2022 11:15:13 +0100
Subject: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <CAMdYzYrKq==Bs0aonrJBC+W2c4nQ8cUn2dn_Se4WDaRCkT6SYg@mail.gmail.com>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>
 <CAMdYzYrKq==Bs0aonrJBC+W2c4nQ8cUn2dn_Se4WDaRCkT6SYg@mail.gmail.com>
Message-ID: <3859424.JUeRptVaKW@diego>

Am Donnerstag, 27. Januar 2022, 10:55:13 CET schrieb Peter Geis:
> On Thu, Jan 27, 2022 at 1:18 AM Johan Jonker <jbx6244 at gmail.com> wrote:
> >
> >
> >
> > On 1/27/22 02:00, Peter Geis wrote:
> > > The sdmmc1 node on Quartz64-A supports the optional wifi module from
> > > Pine64.
> > > Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> > > the Quartz64-A.
> > >
> > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > > ---
> > >  .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 45 +++++++++++++++++++
> > >  1 file changed, 45 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > index 33c2c18caaa9..1d73ac6557c5 100644
> > > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > @@ -91,6 +91,18 @@ simple-audio-card,codec {
> > >               };
> > >       };
> > >
> > > +     sdio_pwrseq: sdio-pwrseq {
> >
> > > +             status = "okay";
> >
> > When a node is not previously disabled, then there's no need for "okay".
> 
> Thanks, this is here in case an end user wants to easily hack the
> board to use this for other purposes.

but please drop it here as well.

A user "hacking" a devicetree should be able to also just _add_
a status "disabled" :-) .




From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:24:39 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:24:39 +0100
Subject: [PATCH] arm64: dts: mt8195: add gce node
In-Reply-To: <20220126090109.32143-1-jason-jh.lin@mediatek.com>
References: <20220126090109.32143-1-jason-jh.lin@mediatek.com>
Message-ID: <15d12a78-b8e2-f2f6-9bb0-9e501f245b94@collabora.com>

Il 26/01/22 10:01, jason-jh.lin ha scritto:
> Add gce node and gce alias on mt8195 dts file.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch is based on [1]
> 
> [1] arm64: dts: Add mediatek SoC mt8195 and evaluation board
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen at mediatek.com/
> ---
>   arch/arm64/boot/dts/mediatek/mt8195.dtsi | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index a363e82f6988..d778ca598d18 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -6,6 +6,7 @@
>   
>   /dts-v1/;
>   #include <dt-bindings/clock/mt8195-clk.h>
> +#include <dt-bindings/gce/mt8195-gce.h>
>   #include <dt-bindings/interrupt-controller/arm-gic.h>
>   #include <dt-bindings/interrupt-controller/irq.h>
>   #include <dt-bindings/phy/phy.h>
> @@ -18,6 +19,11 @@
>   	#address-cells = <2>;
>   	#size-cells = <2>;
>   
> +	aliases {
> +		gce0 = &gce0;
> +		gce1 = &gce1;
> +	};
> +
>   	cpus {
>   		#address-cells = <1>;
>   		#size-cells = <0>;
> @@ -367,6 +373,22 @@
>   			assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
>   		};
>   
> +		gce0: mdp_mailbox at 10320000 {

Just "mailbox" is fine.
		gce0: mailbox at 10320000 {

> +			compatible = "mediatek,mt8195-gce";
> +			reg = <0 0x10320000 0 0x4000>;
> +			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH 0>;
> +			#mbox-cells = <2>;
> +			clocks = <&infracfg_ao CLK_INFRA_AO_GCE>;
> +		};
> +
> +		gce1: disp_mailbox at 10330000 {

Same here, please.

After that,
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

> +			compatible = "mediatek,mt8195-gce";
> +			reg = <0 0x10330000 0 0x4000>;
> +			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH 0>;
> +			#mbox-cells = <2>;
> +			clocks = <&infracfg_ao CLK_INFRA_AO_GCE2>;
> +		};
> +
>   		scp_adsp: clock-controller at 10720000 {
>   			compatible = "mediatek,mt8195-scp_adsp";
>   			reg = <0 0x10720000 0 0x1000>;
> 


From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:27:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:27:21 +0100
Subject: [PATCH v15 10/12] drm/mediatek: add DSC support for mediatek-drm
In-Reply-To: <20220126071932.32615-11-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
 <20220126071932.32615-11-jason-jh.lin@mediatek.com>
Message-ID: <b5e3d5a9-9997-fce5-9201-bccba1af6c7a@collabora.com>

Il 26/01/22 08:19, jason-jh.lin ha scritto:
> DSC is designed for real-time systems with real-time compression,
> transmission, decompression and display.
> The DSC standard is a specification of the algorithms used for
> compressing and decompressing image display streams, including
> the specification of the syntax and semantics of the compressed
> video bit stream.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Reviewed-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>

Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>


From alexandre.belloni at bootlin.com  Thu Jan 27 02:29:11 2022
From: alexandre.belloni at bootlin.com (Alexandre Belloni)
Date: Thu, 27 Jan 2022 11:29:11 +0100
Subject: [PATCH] crypto: atmel: add support for AES and SHA IPs available
 on lan966x SoC
In-Reply-To: <20220127080408.15791-1-kavyasree.kotagiri@microchip.com>
References: <20220127080408.15791-1-kavyasree.kotagiri@microchip.com>
Message-ID: <YfJz91kchrcX9Xqe@piout.net>

On 27/01/2022 13:34:08+0530, Kavyasree Kotagiri wrote:
> This patch adds support for hardware version of AES and SHA IPs
> available on lan966x SoC.
> 
> Tested-by: Vradha Panchal <vradha.panchal at microchip.com>
> Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
> ---
>  drivers/crypto/atmel-aes.c | 2 ++
>  drivers/crypto/atmel-sha.c | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
> index fe0558403191..358f1092d890 100644
> --- a/drivers/crypto/atmel-aes.c
> +++ b/drivers/crypto/atmel-aes.c
> @@ -2509,6 +2509,8 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
>  
>  	/* keep only major version number */
>  	switch (dd->hw_version & 0xff0) {
> +	case 0x700:
> +		fallthrough;

I don't think fallthrough is needed in that case.
>  	case 0x500:
>  		dd->caps.has_dualbuff = 1;
>  		dd->caps.has_cfb64 = 1;
> diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
> index 1b13f601fd95..6c7bb91c8cce 100644
> --- a/drivers/crypto/atmel-sha.c
> +++ b/drivers/crypto/atmel-sha.c
> @@ -2508,6 +2508,8 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
>  
>  	/* keep only major version number */
>  	switch (dd->hw_version & 0xff0) {
> +	case 0x700:
> +		fallthrough;
>  	case 0x510:
>  		dd->caps.has_dma = 1;
>  		dd->caps.has_dualbuff = 1;
> -- 
> 2.17.1
> 

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:32:49 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:32:49 +0100
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <CAMty3ZAojTyw3H8VprH9aiyTyWjeL8oqPxNNr=J33_5FrcUj9Q@mail.gmail.com>
References: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
 <CAMty3ZAojTyw3H8VprH9aiyTyWjeL8oqPxNNr=J33_5FrcUj9Q@mail.gmail.com>
Message-ID: <4b46b8ce-7300-ef42-eb17-efd87ebdf773@collabora.com>

Il 12/01/22 08:09, Jagan Teki ha scritto:
> On Tue, Jan 4, 2022 at 3:30 PM AngeloGioacchino Del Regno
> <angelogioacchino.delregno at collabora.com> wrote:
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
>> ---
> 
> Eventually I've observed similar issue on other Component based DSI
> controllers, hence
> 
> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
> 

Hello dri-devel,
can you please pick this patch?

All MediaTek platforms are broken in v5.17 without this one.

Thanks,
Angelo


From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:35:33 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:35:33 +0100
Subject: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
In-Reply-To: <20220127025544.10854-8-yunfei.dong@mediatek.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
 <20220127025544.10854-8-yunfei.dong@mediatek.com>
Message-ID: <07468ddd-22a8-c2a5-21fd-8468e0e77d74@collabora.com>

Il 27/01/22 03:55, Yunfei Dong ha scritto:
> Init some of VP9 frame decode params to default value.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>

Hello Yunfei,

This patch is not strictly related to MediaTek SoCs, since it's
modfying v4l2-core.
Can you please send this patch separately?

Thanks,
Angelo

> ---
>   drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
>   1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> index 54abe5245dcc..b25c77b8a445 100644
> --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> @@ -112,6 +112,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>   	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
>   	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
>   	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
> +	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
>   	struct v4l2_ctrl_fwht_params *p_fwht_params;
>   	void *p = ptr.p + idx * ctrl->elem_size;
>   
> @@ -152,6 +153,13 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
>   		p_vp8_frame = p;
>   		p_vp8_frame->num_dct_parts = 1;
>   		break;
> +	case V4L2_CTRL_TYPE_VP9_FRAME:
> +		p_vp9_frame = p;
> +		p_vp9_frame->profile = 0;
> +		p_vp9_frame->bit_depth = 8;
> +		p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
> +			V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
> +		break;
>   	case V4L2_CTRL_TYPE_FWHT_PARAMS:
>   		p_fwht_params = p;
>   		p_fwht_params->version = V4L2_FWHT_VERSION;
> 



From alistair at alistair23.me  Thu Jan 27 02:35:33 2022
From: alistair at alistair23.me (Alistair)
Date: Thu, 27 Jan 2022 20:35:33 +1000
Subject: [PATCH v2] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <1a8ee480-b066-8da9-cd63-079e07b7d88a@roeck-us.net>
References: <20220124120027.106754-1-alistair@alistair23.me>
 <1a8ee480-b066-8da9-cd63-079e07b7d88a@roeck-us.net>
Message-ID: <6b0d3b85-a3a3-4f06-a6c1-88fa0a4113f0@www.fastmail.com>

On Tue, 25 Jan 2022, at 2:21 AM, Guenter Roeck wrote:
> On 1/24/22 04:00, Alistair Francis wrote:
> > The i.MX watchdog cannot be disabled by softwrae once it has been
> 
> s/softwrae/software/
> 
> > enabled. This means that it can't be stopped before suspend.
> > 
> > For systems that enter low power mode this is fine, as the watchdog will
> > be automatically stopped by hardwrae in low power mode. Not all i.MX
> 
> s/hardwrae/hardware/
> 
> > platforms support low power mode in the mainline kernel. For example the
> > i.MX7D does not enter low power mode and so will be rebooted 2 minutes
> > after entering freeze or mem sleep states.
> 
> I don't think "mem" adds any value here. Just make it sleep states.
> 
> > 
> > This patch introduces a device tree property "fsl,ping-during-suspend"
> > that can be used to enable ping on suspend support for these systems.
> > 
> > Signed-off-by: Alistair Francis <alistair at alistair23.me>
> > ---
> 
> Change log goes here.
> 
> >   drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
> >   1 file changed, 20 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
> > index 51bfb796898b..d0c5d47ddede 100644
> > --- a/drivers/watchdog/imx2_wdt.c
> > +++ b/drivers/watchdog/imx2_wdt.c
> > @@ -66,6 +66,7 @@ struct imx2_wdt_device {
> >   struct watchdog_device wdog;   
> >   bool ext_reset;
> >   bool clk_is_on;
> 
> I don't see the purpose of this variable. Unless I am missing something is is set
> but never used.

clk_is_on is used in imx2_wdt_ping(), it disables the access if
the clock isn't running.

> 
> > + bool no_ping;
> >   };
> >   
> >   static bool nowayout = WATCHDOG_NOWAYOUT;
> > @@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
> >   
> >   wdev->ext_reset = of_property_read_bool(dev->of_node,
> >   "fsl,ext-reset-output");
> > + /*
> > + * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
> > + * during suspend.
> > + */
> > + wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
> 
> This is ok as long as there is only a single chip requiring this change.
> If there are more, the 'data' field in struct of_device_id should be used
> instead.

I only know of one now, so this should be fine then.

Alistair

> 
> >   platform_set_drvdata(pdev, wdog);
> >   watchdog_set_drvdata(wdog, wdev);
> >   watchdog_set_nowayout(wdog, nowayout);
> >   watchdog_set_restart_priority(wdog, 128);
> >   watchdog_init_timeout(wdog, timeout, dev);
> > - watchdog_stop_ping_on_suspend(wdog);
> > + if (wdev->no_ping)
> > + watchdog_stop_ping_on_suspend(wdog);
> >   
> >   if (imx2_wdt_is_running(wdev)) {
> >   imx2_wdt_set_timeout(wdog, wdog->timeout);
> > @@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
> >   imx2_wdt_ping(wdog);
> >   }
> >   
> > - clk_disable_unprepare(wdev->clk);
> > + if (wdev->no_ping) {
> > + clk_disable_unprepare(wdev->clk);
> >   
> > - wdev->clk_is_on = false;
> > + wdev->clk_is_on = false;
> > + }
> >   
> >   return 0;
> >   }
> > @@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
> >   struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
> >   int ret;
> >   
> > - ret = clk_prepare_enable(wdev->clk);
> > - if (ret)
> > - return ret;
> > + if (wdev->no_ping) {
> > + ret = clk_prepare_enable(wdev->clk);
> >   
> > - wdev->clk_is_on = true;
> > + if (ret)
> > + return ret;
> > +
> > + wdev->clk_is_on = true;
> > + }
> >   
> >   if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
> >   /*
> > @@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
> >   
> >   static const struct of_device_id imx2_wdt_dt_ids[] = {
> >   { .compatible = "fsl,imx21-wdt", },
> > + { .compatible = "fsl,imx7d-wdt", },
> >   { /* sentinel */ }
> >   };
> >   MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
> 
> 


From horatiu.vultur at microchip.com  Thu Jan 27 02:40:23 2022
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Thu, 27 Jan 2022 11:40:23 +0100
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
In-Reply-To: <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>
References: <20220125161245.418882-1-horatiu.vultur@microchip.com>
 <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>
Message-ID: <20220127104023.5dwcrod7toi4hpb7@soft-dev3-1.localhost>

The 01/25/2022 08:46, Colin Foster wrote:
> 
> Hi Horatiu,

Hi Colin,

> 
> On Tue, Jan 25, 2022 at 05:12:45PM +0100, Horatiu Vultur wrote:
> > Initially the driver accessed the registers using u32 __iomem but then
> > in the blamed commit it changed it to use regmap. The problem is that now
> > the offset of the registers is not calculated anymore at word offset but
> > at byte offset. Therefore make sure to multiply the offset with word size.
> >
> 
> Sorry about this one. I see it must have slipped through the cracks
> because I had made the same change in my tree. The only difference is I
> had copied reg_stride into sgpio_priv instead of making regmap_config
> file-scope. For what its worth, with apologies:

No worries, sorry that I missed your patch initially. And thanks for
reviewing this patch.

> 
> Reviewed-by: Colin Foster <colin.foster at in-advantage.com>



> 
> > Fixes: 2afbbab45c261a ("pinctrl: microchip-sgpio: update to support regmap")
> > Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> > ---
> >  drivers/pinctrl/pinctrl-microchip-sgpio.c | 13 +++++++------
> >  1 file changed, 7 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
> > index 8e081c90bdb2..2999c98bbdee 100644
> > --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
> > +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
> > @@ -98,6 +98,12 @@ static const struct sgpio_properties properties_sparx5 = {
> >       .regoff = { 0x00, 0x06, 0x26, 0x04, 0x05, 0x2a, 0x32, 0x3a, 0x3e, 0x42 },
> >  };
> >
> > +static const struct regmap_config regmap_config = {
> > +             .reg_bits = 32,
> > +             .val_bits = 32,
> > +             .reg_stride = 4,
> > +};
> > +
> >  static const char * const functions[] = { "gpio" };
> >
> >  struct sgpio_bank {
> > @@ -137,7 +143,7 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
> >
> >  static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
> >  {
> > -     return priv->properties->regoff[rno] + off;
> > +     return (priv->properties->regoff[rno] + off) * regmap_config.reg_stride;
> >  }
> >
> >  static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
> > @@ -821,11 +827,6 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
> >       struct clk *clk;
> >       u32 __iomem *regs;
> >       u32 val;
> > -     struct regmap_config regmap_config = {
> > -             .reg_bits = 32,
> > -             .val_bits = 32,
> > -             .reg_stride = 4,
> > -     };
> >
> >       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> >       if (!priv)
> > --
> > 2.33.0
> >

-- 
/Horatiu


From anshuman.khandual at arm.com  Thu Jan 27 02:41:15 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 27 Jan 2022 16:11:15 +0530
Subject: [RFC V1 10/11] perf: Expand perf_branch_entry.type
In-Reply-To: <YfF7P9flt8D2+Kfr@robh.at.kernel.org>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
 <YfF7P9flt8D2+Kfr@robh.at.kernel.org>
Message-ID: <004deaf2-b77b-6b88-7bbb-7508c8feb68f@arm.com>



On 1/26/22 10:17 PM, Rob Herring wrote:
> On Mon, Jan 24, 2022 at 10:00:52AM +0530, Anshuman Khandual wrote:
>> Current perf_branch_entry.type is a 4 bits field just enough to accommodate
>> 16 generic branch types. This is insufficient to accommodate platforms like
>> arm64 which has much more branch types. Lets just expands this field into a
>> 6 bits one, which can now hold 64 generic branch types. This also adds more
>> generic branch types and updates the BRBE driver as required.
>>
>> Cc: Peter Zijlstra <peterz at infradead.org>
>> Cc: Ingo Molnar <mingo at redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
>> Cc: Jiri Olsa <jolsa at redhat.com>
>> Cc: Namhyung Kim <namhyung at kernel.org>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-perf-users at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  drivers/perf/arm_pmu_brbe.c           |  7 ++++++-
> 
> This patch should come before the BRBE support so that it can be applied
> sooner rather than later. If another field is added to the end before 
> expanding this field, then you will be stuck with assembling bits from 2 
> fields.

Should I just split this patch from the series and post it separately
right away, to be included in perf while BRBE support gets reviewed ?

> 
>>  include/uapi/linux/perf_event.h       | 10 ++++++++--
>>  tools/include/uapi/linux/perf_event.h | 10 ++++++++--
>>  tools/perf/util/branch.c              |  8 +++++++-
>>  4 files changed, 29 insertions(+), 6 deletions(-)


From narmstrong at baylibre.com  Thu Jan 27 02:44:25 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:44:25 +0100
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
 <a279c365-0615-1c7f-5596-dec9ad1c8229@lexina.in>
Message-ID: <3924894b-d479-7ec2-ff68-b830137f3b79@baylibre.com>

Hi,

On 26/01/2022 06:35, Vyacheslav wrote:
> Hi!
> 
> 26.01.2022 07:49, Christian Hewitt wrote:
>> Add an additional reserved memory region for the BL32 trusted firmware
>> present in many devices that boot from Amlogic vendor u-boot.
>>
>> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
>> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
>> ---
>> ? arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>> ? 1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> index 6b457b2c30a4..aa14ea017a61 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> @@ -49,6 +49,12 @@
>> ????????????? no-map;
>> ????????? };
>> ? +??????? /* 32 MiB reserved for ARM Trusted Firmware (BL32) */
>> +??????? secmon_reserved_bl32: secmon at 5300000 {
>> +??????????? reg = <0x0 0x05300000 0x0 0x2000000>;
>> +??????????? no-map;
>> +??????? };
>> +
> How do I check if we need a similar patch for axg boards?
> 
> 
>> ????????? linux,cma {
>> ????????????? compatible = "shared-dma-pool";
>> ????????????? reusable;
>>
> 

For AXG board with BL32 booting from vendor u-boot, yes.

Neil


From narmstrong at baylibre.com  Thu Jan 27 02:46:08 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:08 +0100
Subject: [PATCH 1/3] arm64: dts: meson-gx: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-2-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-2-christianshewitt@gmail.com>
Message-ID: <517ef196-e622-7ed5-c3be-55ac3f054b74@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Suggested-by: Mateusz Krzak <kszaquitto at gmail.com>
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> index 6b457b2c30a4..aa14ea017a61 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
> @@ -49,6 +49,12 @@
>  			no-map;
>  		};
>  
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
>  		linux,cma {
>  			compatible = "shared-dma-pool";
>  			reusable;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 02:46:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:19 +0100
Subject: [PATCH 2/3] arm64: dts: meson-g12: add ATF BL32 reserved-memory
 region
In-Reply-To: <20220126044954.19069-3-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-3-christianshewitt@gmail.com>
Message-ID: <af845f03-6bd4-cc78-2b7c-a32257f8773f@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> Add an additional reserved memory region for the BL32 trusted firmware
> present in many devices that boot from Amlogic vendor u-boot.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> index 6d99c23261fb..45947c1031c4 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
> @@ -107,6 +107,12 @@
>  			no-map;
>  		};
>  
> +		/* 32 MiB reserved for ARM Trusted Firmware (BL32) */
> +		secmon_reserved_bl32: secmon at 5300000 {
> +			reg = <0x0 0x05300000 0x0 0x2000000>;
> +			no-map;
> +		};
> +
>  		linux,cma {
>  			compatible = "shared-dma-pool";
>  			reusable;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 02:46:33 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 11:46:33 +0100
Subject: [PATCH 3/3] arm64: dts: meson-g12: drop BL32 region from
 SEI510/SEI610
In-Reply-To: <20220126044954.19069-4-christianshewitt@gmail.com>
References: <20220126044954.19069-1-christianshewitt@gmail.com>
 <20220126044954.19069-4-christianshewitt@gmail.com>
Message-ID: <cea820b0-5ca6-4a34-3d57-92e593785001@baylibre.com>

On 26/01/2022 05:49, Christian Hewitt wrote:
> The BL32/TEE reserved-memory region is now inherited from the common
> family dtsi (meson-g12-common) so we can drop it from board files.
> 
> Signed-off-by: Christian Hewitt <christianshewitt at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts | 8 --------
>  arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts  | 8 --------
>  2 files changed, 16 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> index d8838dde0f0f..4fb31c2ba31c 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
> @@ -157,14 +157,6 @@
>  		regulator-always-on;
>  	};
>  
> -	reserved-memory {
> -		/* TEE Reserved Memory */
> -		bl32_reserved: bl32 at 5000000 {
> -			reg = <0x0 0x05300000 0x0 0x2000000>;
> -			no-map;
> -		};
> -	};
> -
>  	sdio_pwrseq: sdio-pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> index 427475846fc7..a5d79f2f7c19 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
> @@ -203,14 +203,6 @@
>  		regulator-always-on;
>  	};
>  
> -	reserved-memory {
> -		/* TEE Reserved Memory */
> -		bl32_reserved: bl32 at 5000000 {
> -			reg = <0x0 0x05300000 0x0 0x2000000>;
> -			no-map;
> -		};
> -	};
> -
>  	sdio_pwrseq: sdio-pwrseq {
>  		compatible = "mmc-pwrseq-simple";
>  		reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From alistair at alistair23.me  Thu Jan 27 02:47:39 2022
From: alistair at alistair23.me (Alistair Francis)
Date: Thu, 27 Jan 2022 20:47:39 +1000
Subject: [PATCH v3] watchdog: imx2_wdg: Alow ping on suspend
Message-ID: <20220127104739.312592-1-alistair@alistair23.me>

The i.MX watchdog cannot be disabled by software once it has been
enabled. This means that it can't be stopped before suspend.

For systems that enter low power mode this is fine, as the watchdog will
be automatically stopped by hardware in low power mode. Not all i.MX
platforms support low power mode in the mainline kernel. For example the
i.MX7D does not enter low power mode and so will be rebooted 2 minutes
after entering sleep states.

This patch introduces a device tree property "fsl,ping-during-suspend"
that can be used to enable ping on suspend support for these systems.

Signed-off-by: Alistair Francis <alistair at alistair23.me>
---
v3:
 - Fixup typos in commit message
v2:
 - Remove custom property

 drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
index 51bfb796898b..d0c5d47ddede 100644
--- a/drivers/watchdog/imx2_wdt.c
+++ b/drivers/watchdog/imx2_wdt.c
@@ -66,6 +66,7 @@ struct imx2_wdt_device {
 	struct watchdog_device wdog;
 	bool ext_reset;
 	bool clk_is_on;
+	bool no_ping;
 };
 
 static bool nowayout = WATCHDOG_NOWAYOUT;
@@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
 
 	wdev->ext_reset = of_property_read_bool(dev->of_node,
 						"fsl,ext-reset-output");
+	/*
+	 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
+	 * during suspend.
+	 */
+	wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
 	platform_set_drvdata(pdev, wdog);
 	watchdog_set_drvdata(wdog, wdev);
 	watchdog_set_nowayout(wdog, nowayout);
 	watchdog_set_restart_priority(wdog, 128);
 	watchdog_init_timeout(wdog, timeout, dev);
-	watchdog_stop_ping_on_suspend(wdog);
+	if (wdev->no_ping)
+		watchdog_stop_ping_on_suspend(wdog);
 
 	if (imx2_wdt_is_running(wdev)) {
 		imx2_wdt_set_timeout(wdog, wdog->timeout);
@@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
 		imx2_wdt_ping(wdog);
 	}
 
-	clk_disable_unprepare(wdev->clk);
+	if (wdev->no_ping) {
+		clk_disable_unprepare(wdev->clk);
 
-	wdev->clk_is_on = false;
+		wdev->clk_is_on = false;
+	}
 
 	return 0;
 }
@@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
 	int ret;
 
-	ret = clk_prepare_enable(wdev->clk);
-	if (ret)
-		return ret;
+	if (wdev->no_ping) {
+		ret = clk_prepare_enable(wdev->clk);
 
-	wdev->clk_is_on = true;
+		if (ret)
+			return ret;
+
+		wdev->clk_is_on = true;
+	}
 
 	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
 		/*
@@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
 
 static const struct of_device_id imx2_wdt_dt_ids[] = {
 	{ .compatible = "fsl,imx21-wdt", },
+	{ .compatible = "fsl,imx7d-wdt", },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);
-- 
2.31.1



From rmk+kernel at armlinux.org.uk  Thu Jan 27 02:54:52 2022
From: rmk+kernel at armlinux.org.uk (Russell King (Oracle))
Date: Thu, 27 Jan 2022 10:54:52 +0000
Subject: [PATCH net-next] net: sparx5: use .mac_select_pcs() interface
Message-ID: <E1nD2QW-005UHW-QK@rmk-PC.armlinux.org.uk>

Convert sparx5 to use the mac_select_interface rather than using
phylink_set_pcs(). The intention here is to unify the approach for
PCS and eventually remove phylink_set_pcs().

Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
---
 drivers/net/ethernet/microchip/sparx5/sparx5_main.c    |  1 -
 drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 10 ++++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 16266275dd36..35689b5e212c 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -328,7 +328,6 @@ static int sparx5_create_port(struct sparx5 *sparx5,
 		return PTR_ERR(phylink);
 
 	spx5_port->phylink = phylink;
-	phylink_set_pcs(phylink, &spx5_port->phylink_pcs);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
index 8ba33bc1a001..830da0e5ff27 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
@@ -26,6 +26,15 @@ static bool port_conf_has_changed(struct sparx5_port_config *a, struct sparx5_po
 	return false;
 }
 
+static struct phylink_pcs *
+sparx5_phylink_mac_select_pcs(struct phylink_config *config,
+			      phy_interface_t interface)
+{
+	struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
+
+	return &port->phylink_pcs;
+}
+
 static void sparx5_phylink_mac_config(struct phylink_config *config,
 				      unsigned int mode,
 				      const struct phylink_link_state *state)
@@ -130,6 +139,7 @@ const struct phylink_pcs_ops sparx5_phylink_pcs_ops = {
 
 const struct phylink_mac_ops sparx5_phylink_mac_ops = {
 	.validate = phylink_generic_validate,
+	.mac_select_pcs = sparx5_phylink_mac_select_pcs,
 	.mac_config = sparx5_phylink_mac_config,
 	.mac_link_down = sparx5_phylink_mac_link_down,
 	.mac_link_up = sparx5_phylink_mac_link_up,
-- 
2.30.2



From miquel.raynal at bootlin.com  Thu Jan 27 02:56:52 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Thu, 27 Jan 2022 11:56:52 +0100
Subject: [PATCH] mtd/memory: omap: Fix build dependencies
Message-ID: <20220127105652.1063624-1-miquel.raynal@bootlin.com>

The Omap2 raw NAND controller (MTD_NAND_OMAP2) selects the Omap memory
controller (OMAP_GPMC) for the ARCH_K3 platforms and for compile
testing.

The Omap memory controller (OMAP_GPMC) depends on OF_ADDRESS because the
driver uses of_address_to_resource().

This may produce the following warning:
WARNING: unmet direct dependencies detected for OMAP_GPMC
Depends on [n]:
  - MEMORY [=y] && OF_ADDRESS [=n]
Selected by [m]:
  - MTD_NAND_OMAP2 [=m] && MTD [=m] && MTD_RAW_NAND [=m] &&
    (ARCH_OMAP2PLUS || ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST [=y]) &&
    HAS_IOMEM [=y]

As the of_address_to_resource() helper has a dummy implementation
returning an error when OF_ADDRESS is not selected, we do not need to
select OF_ADDRESS from the OMAP_GPMC Kconfig menu for compile testing
purposes. Nor we actually do for K3 platforms, but in order to not break
these platforms we can just select OF_ADDRESS from ARCH_K3 directly.

Fixes: dbcb124acebd ("mtd: rawnand: omap2: Select GPMC device driver for ARCH_K3")
Reported-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
Suggested-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 arch/arm64/Kconfig.platforms | 1 +
 drivers/memory/Kconfig       | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms
index 7d5d58800170..1a0d4b575b95 100644
--- a/arch/arm64/Kconfig.platforms
+++ b/arch/arm64/Kconfig.platforms
@@ -123,6 +123,7 @@ config ARCH_K3
 	select TI_SCI_INTR_IRQCHIP
 	select TI_SCI_INTA_IRQCHIP
 	select TI_K3_SOCINFO
+	select OF_ADDRESS
 	help
 	  This enables support for Texas Instruments' K3 multicore SoC
 	  architecture.
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 30bff6cb1b8d..241f0925cbf1 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -104,7 +104,6 @@ config TI_EMIF
 
 config OMAP_GPMC
 	bool "Texas Instruments OMAP SoC GPMC driver" if COMPILE_TEST
-	depends on OF_ADDRESS
 	select GPIOLIB
 	help
 	  This driver is for the General Purpose Memory Controller (GPMC)
-- 
2.27.0



From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:57:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:57:23 +0100
Subject: [PATCH v11 2/3] dts: arm64: mt8183: add Mediatek MDP3 nodes
In-Reply-To: <356f512b549f90b329775e249fd48eb2954ade02.camel@mediatek.com>
References: <20220105093758.6850-1-moudy.ho@mediatek.com>
 <20220105093758.6850-3-moudy.ho@mediatek.com>
 <d61ec481-8059-a897-504a-0125f88fad61@collabora.com>
 <356f512b549f90b329775e249fd48eb2954ade02.camel@mediatek.com>
Message-ID: <08fc74c5-4f2f-8712-454d-8cf3aed4eb10@collabora.com>

Il 25/01/22 09:20, moudy ho ha scritto:
> On Fri, 2022-01-21 at 12:58 +0100, AngeloGioacchino Del Regno wrote:
>> Il 05/01/22 10:37, Moudy Ho ha scritto:
>>> Add device nodes for Media Data Path 3 (MDP3) modules.
>>>
>>> Signed-off-by: Moudy Ho <moudy.ho at mediatek.com>
>>> ---
>>>    arch/arm64/boot/dts/mediatek/mt8183.dtsi | 108
>>> ++++++++++++++++++++++-
>>>    1 file changed, 107 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>>> b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>>> index ba4584faca5a..b872ef1ff6b3 100644
>>> --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>>> +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
>>> @@ -1325,6 +1325,79 @@
>>>    			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX
>>> 0 0x1000>;
>>>    		};
>>>    
>>> +		mdp3_rdma0: mdp3_rdma0 at 14001000 {
>>> +			compatible = "mediatek,mt8183-mdp3",
>>> +				     "mediatek,mt8183-mdp3-rdma0";
>>> +			mediatek,scp = <&scp>;
>>> +			mediatek,mdp3-comps = "mediatek,mt8183-mdp3-
>>> dl1",
>>> +					      "mediatek,mt8183-mdp3-
>>> dl2",
>>> +					      "mediatek,mt8183-mdp3-
>>> path1",
>>> +					      "mediatek,mt8183-mdp3-
>>> path2",
>>> +					      "mediatek,mt8183-mdp3-
>>> imgi",
>>> +					      "mediatek,mt8183-mdp3-
>>> exto";
>>> +			reg = <0 0x14001000 0 0x1000>,
>>> +			      <0 0x14000000 0 0x1000>,
>>> +			      <0 0x14005000 0 0x1000>,
>>> +			      <0 0x14006000 0 0x1000>,
>>> +			      <0 0x15020000 0 0x1000>;
>>> +			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX
>>> 0x1000 0x1000>,
>>> +						  <&gce SUBSYS_1400XXXX
>>> 0 0x1000>,
>>> +						  <&gce SUBSYS_1400XXXX
>>> 0x5000 0x1000>,
>>> +						  <&gce SUBSYS_1400XXXX
>>> 0x6000 0x1000>,
>>> +						  <&gce SUBSYS_1502XXXX
>>> 0 0x1000>;
>>> +			power-domains = <&spm
>>> MT8183_POWER_DOMAIN_DISP>;
>>> +			clocks = <&mmsys CLK_MM_MDP_RDMA0>,
>>> +				 <&mmsys CLK_MM_MDP_RSZ1>,
>>> +				 <&mmsys CLK_MM_MDP_DL_TXCK>,
>>> +				 <&mmsys CLK_MM_MDP_DL_RX>,
>>> +				 <&mmsys CLK_MM_IPU_DL_TXCK>,
>>> +				 <&mmsys CLK_MM_IPU_DL_RX>;
>>> +			iommus = <&iommu M4U_PORT_MDP_RDMA0>;
>>> +			mediatek,mmsys = <&mmsys>;
>>> +			mediatek,mm-mutex = <&mutex>;
>>> +			mediatek,mailbox-gce = <&gce>;
>>> +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>,
>>> +				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
>>> +				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
>>> +				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;
>>
>> Hello Moudy,
>> the mboxes for gce 21, 22, 23 are missing the third cell. Please fix.
>>
>> Regards,
>> Angelo
> 
> Hi Angelo,
> Thanks for the reminder, but I'm a bit confused, the previous
> version(v10) mentioned that the current upstream mbox has only 2
> cells.
> So I should follow this rule to remove the extra 0 in the first item as
> follows:
>   +			mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>,
>   +				 <&gce 21 CMDQ_THR_PRIO_LOWEST>,
>   +				 <&gce 22 CMDQ_THR_PRIO_LOWEST>,
>   +				 <&gce 23 CMDQ_THR_PRIO_LOWEST>;
> 
> Thanks,
> Moudy Ho

Hello Moudy,
I'm sorry for this confusion and you are totally right in the proposed solution,
which is the exact opposite of what I said.

Thanks for understanding,
Angelo

>>
>>> +			gce-subsys = <&gce 0x14000000 SUBSYS_1400XXXX>,
>>> +				     <&gce 0x14010000 SUBSYS_1401XXXX>,
>>> +				     <&gce 0x14020000 SUBSYS_1402XXXX>,
>>> +				     <&gce 0x15020000 SUBSYS_1502XXXX>;
>>> +		};
>>> +
>>
>>
> 



From angelogioacchino.delregno at collabora.com  Thu Jan 27 02:59:59 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 11:59:59 +0100
Subject: [PATCH v4 03/35] iommu/mediatek: Fix 2 HW sharing pgtable issue
In-Reply-To: <20220125085634.17972-4-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-4-yong.wu@mediatek.com>
Message-ID: <fc505da2-809c-c466-2256-b5293f242128@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> In the commit 4f956c97d26b ("iommu/mediatek: Move domain_finalise into
> attach_device"), I overlooked the sharing pgtable case.
> After that commit, the "data" in the mtk_iommu_domain_finalise always is
> the data of the current IOMMU HW. Fix this for the sharing pgtable case.
> 
> Only affect mt2712 which is the only SoC that share pgtable currently.
> 
> Fixes: 4f956c97d26b ("iommu/mediatek: Move domain_finalise into attach_device")
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From s.hauer at pengutronix.de  Thu Jan 27 03:00:09 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 27 Jan 2022 12:00:09 +0100
Subject: [PATCH 27/27] drm: rockchip: Add VOP2 driver
In-Reply-To: <6588D77C-D3CB-4FB0-8B00-5EDD6ABD6923@gmail.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-28-s.hauer@pengutronix.de>
 <6588D77C-D3CB-4FB0-8B00-5EDD6ABD6923@gmail.com>
Message-ID: <20220127110009.GK23490@pengutronix.de>

On Thu, Jan 27, 2022 at 10:17:13AM +0100, Piotr Oniszczuk wrote:
> Sascha,
> 
> FYI 
> small report regarding 4k modes support in v4:
> 
> -on rk3399 it gives me 4k screen where right vertical 1/3 part of screen is garbage
> -on rk3566 my samsung 4k monitor has black screen and cycle of OSD msgs: HDMI2 connected; HDMI2 disconnected; ....

Same here on my rk3568, also with a samsung monitor. Was it 4k at 60Hz or
4k at 30Hz? If the former, could you give 4k at 30Hz a try? That mode works
well here.

> 
> I would suggest split v4 into 2 separated series:

Yeah, splitting up the series makes sense. At the moment I have it all
in one series to ease others testing it.

Sascha

> 
> -VOP2 support
> -HDMI 4k modes support
> 
> BTW: getting well working 4k HDMI modes on rk3399 was real story for me.
> There is many different series of patches to address this - but all have some subtle issues for me (i.e. 4k HDMI modes works but i.e. Qt is failing with DRM atomic commits in EGLFS)
> I developed well working [1] giving me reliable 4k on rk3399 (including working Qt DRM drawing in EGLFS mode) 
> Maybe it will be somehow helpful to get 4k modes solution for rk3566 _and_ rk3399 (on single kernel binary)?
> 
> [1] https://github.com/warpme/minimyth2/blob/master/script/kernel/linux-5.16/files/0730-drm-rockchip-add-4k-videomodes-support.patch

At least there are patches in it that I have in my series as well and
keep popping up everywhere like "drm/rockchip: dw_hdmi: Use
auto-generated tables" and "drm/rockchip: dw_hdmi: Set cur_ctr to 0
always"

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:02:08 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:02:08 +0100
Subject: [PATCH v4 06/35] iommu/mediatek: Add mutex for m4u_group and
 m4u_dom in data
In-Reply-To: <20220125085634.17972-7-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-7-yong.wu@mediatek.com>
Message-ID: <62d2a231-3d05-5008-fae2-335c4ad853bd@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Add a mutex to protect the data in the structure mtk_iommu_data,
> like ->"m4u_group" ->"m4u_dom". For the internal data, we should
> protect it in ourselves driver. Add a mutex for this.
> This could be a fix for the multi-groups support.
> 
> Fixes: c3045f39244e ("iommu/mediatek: Support for multi domains")
> Signed-off-by: Yunfei Wang <yf.wang at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 13 +++++++++++--
>   drivers/iommu/mtk_iommu.h |  2 ++
>   2 files changed, 13 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index ec2c387abf60..095736bfb7b4 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -464,15 +464,16 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
>   		dom->data = data;
>   	}
>   
> +	mutex_lock(&data->mutex);
>   	if (!data->m4u_dom) { /* Initialize the M4U HW */
>   		ret = pm_runtime_resume_and_get(m4udev);
>   		if (ret < 0)
> -			return ret;
> +			goto data_unlock;

In order to enhance human readability, I would rather propose:

			goto err_unlock;

Apart from this,
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

>   
>   		ret = mtk_iommu_hw_init(data);
>   		if (ret) {
>   			pm_runtime_put(m4udev);
> -			return ret;
> +			goto data_unlock;
>   		}
>   		data->m4u_dom = dom;
>   		writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
> @@ -480,9 +481,14 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
>   
>   		pm_runtime_put(m4udev);
>   	}
> +	mutex_unlock(&data->mutex);
>   
>   	mtk_iommu_config(data, dev, true, domid);
>   	return 0;
> +
> +data_unlock:
> +	mutex_unlock(&data->mutex);
> +	return ret;
>   }
>   
>   static void mtk_iommu_detach_device(struct iommu_domain *domain,
> @@ -592,6 +598,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
>   	if (domid < 0)
>   		return ERR_PTR(domid);
>   
> +	mutex_lock(&data->mutex);
>   	group = data->m4u_group[domid];
>   	if (!group) {
>   		group = iommu_group_alloc();
> @@ -600,6 +607,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev)
>   	} else {
>   		iommu_group_ref_get(group);
>   	}
> +	mutex_unlock(&data->mutex);
>   	return group;
>   }
>   
> @@ -874,6 +882,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
>   	}
>   
>   	platform_set_drvdata(pdev, data);
> +	mutex_init(&data->mutex);
>   
>   	ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
>   				     "mtk-iommu.%pa", &ioaddr);
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> index f81fa8862ed0..f413546ac6e5 100644
> --- a/drivers/iommu/mtk_iommu.h
> +++ b/drivers/iommu/mtk_iommu.h
> @@ -80,6 +80,8 @@ struct mtk_iommu_data {
>   
>   	struct dma_iommu_mapping	*mapping; /* For mtk_iommu_v1.c */
>   
> +	struct mutex			mutex; /* Protect m4u_group/m4u_dom above */
> +
>   	struct list_head		list;
>   	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
>   };
> 




From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:02:55 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:02:55 +0100
Subject: [PATCH v4 07/35] iommu/mediatek: Add mutex for data in the
 mtk_iommu_domain
In-Reply-To: <20220125085634.17972-8-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-8-yong.wu@mediatek.com>
Message-ID: <8576a0c5-aa69-aaed-be48-125ae2004f47@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Same with the previous patch, add a mutex for the "data" in the
> mtk_iommu_domain. Just improve the safety for multi devices
> enter attach_device at the same time. We don't get the real issue
> for this.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From s.hauer at pengutronix.de  Thu Jan 27 03:06:02 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 27 Jan 2022 12:06:02 +0100
Subject: [PATCH 09/27] drm/rockchip: dw_hdmi: Set cur_ctr to 0 always
In-Reply-To: <CAD=FV=VCWW4c3iqfzezU5=KKVFNP+EhPGTBZ7uZdQ=bSCJHQVA@mail.gmail.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-10-s.hauer@pengutronix.de>
 <CAD=FV=VCWW4c3iqfzezU5=KKVFNP+EhPGTBZ7uZdQ=bSCJHQVA@mail.gmail.com>
Message-ID: <20220127110602.GL23490@pengutronix.de>

On Wed, Jan 26, 2022 at 07:42:48AM -0800, Doug Anderson wrote:
> Hi,
> 
> On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >
> > From: Douglas Anderson <dianders at chromium.org>
> >
> > Jitter was improved by lowering the MPLL bandwidth to account for high
> > frequency noise in the rk3288 PLL.  In each case MPLL bandwidth was
> > lowered only enough to get us a comfortable margin.  We believe that
> > lowering the bandwidth like this is safe given sufficient testing.
> >
> > Changes since v3:
> > - new patch
> >
> > Signed-off-by: Douglas Anderson <dianders at chromium.org>
> > Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> > (am from https://patchwork.kernel.org/patch/9223301/)
> 
> Probably remove the "am from" line? It's not standard in upstream and
> that link doesn't seem to go anywhere anymore...
> 
> 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 16 ++--------------
> >  1 file changed, 2 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > index c44eb4d2e2d5..77f82a4fd027 100644
> > --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
> > @@ -176,20 +176,8 @@ static const struct dw_hdmi_mpll_config rockchip_mpll_cfg[] = {
> >  static const struct dw_hdmi_curr_ctrl rockchip_cur_ctr[] = {
> >         /*      pixelclk    bpp8    bpp10   bpp12 */
> >         {
> > -               40000000,  { 0x0018, 0x0018, 0x0018 },
> > -       }, {
> > -               65000000,  { 0x0028, 0x0028, 0x0028 },
> > -       }, {
> > -               66000000,  { 0x0038, 0x0038, 0x0038 },
> > -       }, {
> > -               74250000,  { 0x0028, 0x0038, 0x0038 },
> > -       }, {
> > -               83500000,  { 0x0028, 0x0038, 0x0038 },
> > -       }, {
> > -               146250000, { 0x0038, 0x0038, 0x0038 },
> > -       }, {
> > -               148500000, { 0x0000, 0x0038, 0x0038 },
> > -       }, {
> > +               600000000, { 0x0000, 0x0000, 0x0000 },
> > +       },  {
> 
> This is what we did for rk3288. I can't personally vouch for the
> effects on other SoCs.

Fair enough. Rockchip has this patch in their downstream Kernel, so I am
confident it works on SoCs newer as the rk3288 as well. I don't know how
much they care about the older SoCs, but it seems there is only the
rk3228 that is older than the rk3288 that is supported by this driver.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:08:14 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:08:14 +0100
Subject: [PATCH v4 08/35] iommu/mediatek: Use kmalloc for protect buffer
In-Reply-To: <20220125085634.17972-9-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-9-yong.wu@mediatek.com>
Message-ID: <ca47becf-adc9-f11e-5e59-03f203920344@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> No need zero for the protect buffer that is only accessed by the IOMMU HW
> translation fault happened.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

I would rather keep this a devm_kzalloc instead... the cost is very minimal and
this will be handy when new hardware will be introduced, as it may require a bigger
buffer: in that case, "older" platforms will use only part of it and we may get
garbage data at the end.

Regards,
Angelo


From maz at kernel.org  Thu Jan 27 03:08:17 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 11:08:17 +0000
Subject: [PATCH v5 14/69] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <YelqampUOCIt3YZE@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-15-maz@kernel.org>
 <YelqampUOCIt3YZE@monolith.localdoman>
Message-ID: <874k5p77xa.wl-maz@kernel.org>

On Thu, 20 Jan 2022 13:58:02 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:55PM +0000, Marc Zyngier wrote:
> > +void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
> > +{
> > +	u64 spsr, elr, mode;
> > +	bool direct_eret;
> > +
> > +	/*
> > +	 * Going through the whole put/load motions is a waste of time
> > +	 * if this is a VHE guest hypervisor returning to its own
> > +	 * userspace, or the hypervisor performing a local exception
> > +	 * return. No need to save/restore registers, no need to
> > +	 * switch S2 MMU. Just do the canonical ERET.
> > +	 */
> > +	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
> > +	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
> > +
> > +	direct_eret  = (mode == PSR_MODE_EL0t &&
> > +			vcpu_el2_e2h_is_set(vcpu) &&
> > +			vcpu_el2_tge_is_set(vcpu));
> > +	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
> > +
> > +	if (direct_eret) {
> > +		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
> > +		*vcpu_cpsr(vcpu) = spsr;
> > +		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
> > +		return;
> > +	}
> > +
> > +	preempt_disable();
> > +	kvm_arch_vcpu_put(vcpu);
> > +
> > +	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
> > +
> > +	trace_kvm_nested_eret(vcpu, elr, spsr);
> > +
> > +	/*
> > +	 * Note that the current exception level is always the virtual EL2,
> > +	 * since we set HCR_EL2.NV bit only when entering the virtual EL2.
> > +	 */
> > +	*vcpu_pc(vcpu) = elr;
> > +	*vcpu_cpsr(vcpu) = spsr;
> > +
> > +	kvm_arch_vcpu_load(vcpu, smp_processor_id());
> > +	preempt_enable();
> 
> According to ARM DDI 0487G.a, page D13-3289, ERET'ing to EL1 when
> HCR_EL2.TGE is set is an illegal exception return. I don't see this
> case treated here.

Yes, good call.

I've now added handling for both the return to EL1 with TGE set as
well as return to a 32bit mode. The return to EL3 case will directly
be handled by the HW, and the return from AArch32 to AArch64 cannot
happen by construction.

Thanks for spotting it.

	M.

-- 
Without deviation from the norm, progress is not possible.


From andrew.kilroy at arm.com  Thu Jan 27 03:11:13 2022
From: andrew.kilroy at arm.com (Andrew Kilroy)
Date: Thu, 27 Jan 2022 11:11:13 +0000
Subject: [RFC PATCH 1/1] perf arm64: Implement --topdown with metrics
In-Reply-To: <12e0deef-08db-445f-4958-bcd5c3e10367@linux.intel.com>
References: <4c375d34-bf20-496d-22fc-aed8597126e2@huawei.com>
 <20211214184240.24215-1-andrew.kilroy@arm.com>
 <20211214184240.24215-2-andrew.kilroy@arm.com>
 <CAP-5=fXJeH0ZvcHPa20N5KfLwnYSw29rpK3OrnvE0o3u-vGTLA@mail.gmail.com>
 <b1640897-10d7-c11e-4a7a-d17633916c8e@huawei.com>
 <5a2e29c1-2c7e-1b55-9192-62060309aeca@arm.com>
 <12e0deef-08db-445f-4958-bcd5c3e10367@linux.intel.com>
Message-ID: <1ec258b8-c6dd-aa0f-8583-2d7667314be9@arm.com>

Hi Andi,


On 21/12/2021 14:03, Andi Kleen wrote:
> 
> On 12/20/2021 9:21 AM, Andrew Kilroy wrote:
>>
>> On 15/12/2021 10:52, John Garry wrote:
>>> Hi Andrew,
>>>
>>>>> ? const struct pmu_event *metricgroup__find_metric(const char *metric,
>>>>> ????????????????????????????????????????????????? const struct 
>>>>> pmu_events_map *map);
>>>>> ? int metricgroup__parse_groups_test(struct evlist *evlist,
>>>>> diff --git a/tools/perf/util/topdown.c b/tools/perf/util/topdown.c
>>>>> index 1081b20f9891..57c0c5f2c6bd 100644
>>>>> --- a/tools/perf/util/topdown.c
>>>>> +++ b/tools/perf/util/topdown.c
>>>>> @@ -56,3 +56,9 @@ __weak bool arch_topdown_sample_read(struct evsel 
>>>>> *leader __maybe_unused)
>>>>> ? {
>>>>> ???????? return false;
>>>>> ? }
>>>>> +
>>>>> +__weak bool arch_topdown_use_json_metrics(void)
>>>>> +{
>>>
>>> AFAICS, only x86 supports topdown today and that is because they have 
>>> special kernel topdown events exposed for the kernel CPU PMU driver. 
>>> So other architectures - not only arm - would need rely on 
>>> metricgroups for topdown support. So let's make this generic for all 
>>> archs.
>>>
>>>> I like this extension! I've ranted in the past about weak symbols
>>>> breaking with archives due to lazy loading [1]. In this case
>>>> tools/perf/arch/arm64/util/topdown.c has no other symbols within it
>>>> and so the weak symbol has an extra chance of being linked
>>>> incorrectly. We could add a new command line of --topdown-json to
>>>> avoid this, but there seems little difference in doing this over just
>>>> doing '-M TopDownL1'.
>>>
>>>
>>>> Is it possible to use the json metric approach
>>>> for when the CPU version fails?
>>>
>>> I think that's a good idea.
>>>
>>
>>
>> While looking into using the json metrics approach as a fallback to 
>> the original, I noticed? there are two json metricgroups 'TopdownL1' 
>> and 'TopDownL1' (note the case difference) on x86. Not sure if the 
>> case difference is intentional.
>>
>> On skylake, 'TopdownL1' contains the four json metrics Retiring, 
>> Bad_Speculation, Frontend_Bound, and Backend_Bound.? 'TopDownL1' has 
>> 'SLOTS', 'CoreIPC', 'CoreIPC_SMT', 'Instructions'.? I think its a 
>> similar situation on other x86 chips.
> 
> 
> There's also SMT metrics.
> 
> 
> We don't want to include CoreIPC etc. by default because it would cause 
> multiplexing in common situations.
> 
>>
>> The search for those metrics by metricgroup name is case insensitive, 
>> so it's picking up all 8 metrics when using the lookup string 
>> 'TopDownL1'. ?So the extra 'SLOTS', 'CoreIPC', 'CoreIPC_SMT', 
>> 'Instructions' metrics would be printed as well.
>>
>> Not sure what the significance of the case difference might be.
>>
>> Should we use a different string than 'TopDownL1' as the metric group 
>> name to search for?
> 
> 
> We should probably fix the case (or just make the match case insensitive)
> 
> Can we just keep x86 at using the kernel metrics? On Skylake and earlier 
> it needs different formulas and other options depending whether SMT is 
> on or off, so it's not straight forward to express it as json directly.
> 

I posted a v2 of these patches which keeps x86 only using the kernel 
metrics.

 
https://lore.kernel.org/linux-perf-users/20220111150749.13365-1-andrew.kilroy at arm.com/

Would be good to get your feedback,

Thanks
Andrew



From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:15:18 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:15:18 +0100
Subject: [PATCH v4 27/35] iommu/mediatek: Remove mtk_iommu.h
In-Reply-To: <20220125085634.17972-28-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-28-yong.wu@mediatek.com>
Message-ID: <8e1847d0-7c6f-b022-999b-666cb90e9931@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Currently there is only compare_of/release_of/a suspend structure in the
> header file. I think it is no need to keep a header file only for these.
> Move these into the c file and rm this header file.
> 
> I think there should be a common helper for compare_of and release_of.
> There is many copy in drm, it should be another topic.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c    | 25 ++++++++++++++++++++-
>   drivers/iommu/mtk_iommu.h    | 42 ------------------------------------
>   drivers/iommu/mtk_iommu_v1.c | 21 +++++++++++++++---
>   3 files changed, 42 insertions(+), 46 deletions(-)
>   delete mode 100644 drivers/iommu/mtk_iommu.h
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 80c1e5a75868..f88c7bb235bf 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -14,6 +14,7 @@
>   #include <linux/io.h>
>   #include <linux/iommu.h>
>   #include <linux/iopoll.h>
> +#include <linux/io-pgtable.h>
>   #include <linux/list.h>
>   #include <linux/mfd/syscon.h>
>   #include <linux/module.h>
> @@ -30,7 +31,7 @@
>   #include <asm/barrier.h>
>   #include <soc/mediatek/smi.h>
>   
> -#include "mtk_iommu.h"
> +#include <dt-bindings/memory/mtk-memory-port.h>
>   
>   #define REG_MMU_PT_BASE_ADDR			0x000
>   #define MMU_PT_ADDR_MASK			GENMASK(31, 7)
> @@ -166,6 +167,17 @@ struct mtk_iommu_iova_region {
>   	unsigned long long	size;
>   };
>   
> +struct mtk_iommu_suspend_reg {
> +	u32			misc_ctrl;
> +	u32			dcm_dis;
> +	u32			ctrl_reg;
> +	u32			int_control0;
> +	u32			int_main_control;
> +	u32			ivrp_paddr;
> +	u32			vld_pa_rng;
> +	u32			wr_len_ctrl;
> +};
> +
>   struct mtk_iommu_plat_data {
>   	enum mtk_iommu_plat			m4u_plat;
>   	u32					flags;
> @@ -219,6 +231,17 @@ struct mtk_iommu_domain {
>   	struct mutex			mutex; /* Protect "data" in this structure */
>   };
>   
> +/* TODO: A common helper is expected. */
> +static inline int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static inline void release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +

Since it's just one line, at this point you should also open-code these,

as in you can then remove the two helper functions entirely.
So, please do that.

>   static inline int mtk_iommu_bind(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> deleted file mode 100644
> index d332f9769f83..000000000000
> --- a/drivers/iommu/mtk_iommu.h
> +++ /dev/null
> @@ -1,42 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -/*
> - * Copyright (c) 2015-2016 MediaTek Inc.
> - * Author: Honghui Zhang <honghui.zhang at mediatek.com>
> - */
> -
> -#ifndef _MTK_IOMMU_H_
> -#define _MTK_IOMMU_H_
> -
> -#include <linux/device.h>
> -#include <linux/io.h>
> -#include <linux/io-pgtable.h>
> -#include <linux/iommu.h>
> -#include <linux/spinlock.h>
> -#include <soc/mediatek/smi.h>
> -#include <dt-bindings/memory/mtk-memory-port.h>
> -
> -struct mtk_iommu_suspend_reg {
> -	union {
> -		u32			standard_axi_mode;/* v1 */
> -		u32			misc_ctrl;/* v2 */
> -	};
> -	u32				dcm_dis;
> -	u32				ctrl_reg;
> -	u32				int_control0;
> -	u32				int_main_control;
> -	u32				ivrp_paddr;
> -	u32				vld_pa_rng;
> -	u32				wr_len_ctrl;
> -};
> -
> -static inline int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
> -static inline void release_of(struct device *dev, void *data)
> -{
> -	of_node_put(data);
> -}
> -
> -#endif
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index b762a05328d4..23c3bc175153 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -7,7 +7,6 @@
>    *
>    * Based on driver/iommu/mtk_iommu.c
>    */
> -#include <linux/memblock.h>
>   #include <linux/bug.h>
>   #include <linux/clk.h>
>   #include <linux/component.h>
> @@ -28,10 +27,9 @@
>   #include <linux/spinlock.h>
>   #include <asm/barrier.h>
>   #include <asm/dma-iommu.h>
> -#include <linux/init.h>
> +#include <dt-bindings/memory/mtk-memory-port.h>
>   #include <dt-bindings/memory/mt2701-larb-port.h>
>   #include <soc/mediatek/smi.h>
> -#include "mtk_iommu.h"
>   
>   #define REG_MMU_PT_BASE_ADDR			0x000
>   
> @@ -87,6 +85,13 @@
>    */
>   #define M2701_IOMMU_PGT_SIZE			SZ_4M
>   
> +struct mtk_iommu_suspend_reg {
> +	u32			standard_axi_mode;
> +	u32			dcm_dis;
> +	u32			ctrl_reg;
> +	u32			int_control0;
> +};
> +
>   struct mtk_iommu_data {
>   	void __iomem			*base;
>   	int				irq;
> @@ -110,6 +115,16 @@ struct mtk_iommu_domain {
>   	struct mtk_iommu_data		*data;
>   };
>   
> +static inline int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static inline void release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +

....And the same comment applies here too.

>   static inline int mtk_iommu_bind(struct device *dev)
>   {
>   	struct mtk_iommu_data *data = dev_get_drvdata(dev);
> 





From mkorpershoek at baylibre.com  Thu Jan 27 03:15:23 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Thu, 27 Jan 2022 12:15:23 +0100
Subject: [PATCH v20 0/3] Add matrix keypad driver support for Mediatek SoCs
Message-ID: <20220127111526.3716689-1-mkorpershoek@baylibre.com>

Dear all,

This is a follow-up on an abandoned series, see [1]

Since Dmitry seemed generally happy with the driver, I applied his rename
recommendations.

Thus, I have made the following:

* All Reviewed-By: tags were kept
* Applied Marco's Reviewed-By: on the bindings (since he approved v10)
* Fengping is still the maintainer since he is the original author of this driver

Please tell me if you would rather have me do things differently.

[1] https://lore.kernel.org/all/20200909072159.14888-1-fengping.yu at mediatek.com/

v19 -> v20:
bindings: use dual license
bindings: fixed 2 indentation issues found by yamllint
bindings: drop clock-names description
bindings: use standard keyboard node name for example
bindings: use default: keyword for default values
use debounce-delay-ms property instead of mediatek,debounce-us

fengping.yu (3):
  dt-bindings: input: Add bindings for Mediatek matrix keypad
  Input: mt6779-keypad - Add MediaTek keypad driver
  arm64: defconfig: Add CONFIG_KEYBOARD_MT6779=m

 .../input/mediatek,mt6779-keypad.yaml         |  77 +++++++
 arch/arm64/configs/defconfig                  |   1 +
 drivers/input/keyboard/Kconfig                |  12 +
 drivers/input/keyboard/Makefile               |   1 +
 drivers/input/keyboard/mt6779-keypad.c        | 218 ++++++++++++++++++
 5 files changed, 309 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
 create mode 100644 drivers/input/keyboard/mt6779-keypad.c


base-commit: 87a0b2fafc09766d8c55461a18345a1cfb10a7fe
-- 
2.32.0



From mkorpershoek at baylibre.com  Thu Jan 27 03:15:24 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Thu, 27 Jan 2022 12:15:24 +0100
Subject: [PATCH v20 1/3] dt-bindings: input: Add bindings for Mediatek matrix
 keypad
In-Reply-To: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
Message-ID: <20220127111526.3716689-2-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

This patch add devicetree bindings for Mediatek matrix keypad driver.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 .../input/mediatek,mt6779-keypad.yaml         | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml

diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
new file mode 100644
index 000000000000..b1770640f94b
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/mediatek,mt6779-keypad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek's Keypad Controller device tree bindings
+
+maintainers:
+  - Fengping Yu <fengping.yu at mediatek.com>
+
+allOf:
+  - $ref: "/schemas/input/matrix-keymap.yaml#"
+
+description: |
+  Mediatek's Keypad controller is used to interface a SoC with a matrix-type
+  keypad device. The keypad controller supports multiple row and column lines.
+  A key can be placed at each intersection of a unique row and a unique column.
+  The keypad controller can sense a key-press and key-release and report the
+  event using a interrupt to the cpu.
+
+properties:
+  compatible:
+    oneOf:
+      - const: mediatek,mt6779-keypad
+      - items:
+          - enum:
+              - mediatek,mt6873-keypad
+          - const: mediatek,mt6779-keypad
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: kpd
+
+  wakeup-source:
+    description: use any event on keypad as wakeup event
+    type: boolean
+
+  debounce-delay-ms:
+    maximum: 256
+    default: 16
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/input/input.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        keyboard at 10010000 {
+          compatible = "mediatek,mt6779-keypad";
+          reg = <0 0x10010000 0 0x1000>;
+          interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_FALLING>;
+          clocks = <&clk26m>;
+          clock-names = "kpd";
+        };
+    };
-- 
2.32.0



From mkorpershoek at baylibre.com  Thu Jan 27 03:15:25 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Thu, 27 Jan 2022 12:15:25 +0100
Subject: [PATCH v20 2/3] Input: mt6779-keypad - Add MediaTek keypad driver
In-Reply-To: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
Message-ID: <20220127111526.3716689-3-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

This patch adds matrix keypad support for Mediatek SoCs.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
Reviewed-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Reviewed-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
---
 drivers/input/keyboard/Kconfig         |  12 ++
 drivers/input/keyboard/Makefile        |   1 +
 drivers/input/keyboard/mt6779-keypad.c | 218 +++++++++++++++++++++++++
 3 files changed, 231 insertions(+)
 create mode 100644 drivers/input/keyboard/mt6779-keypad.c

diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0c607da9ee10..03a9530f620e 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -779,6 +779,18 @@ config KEYBOARD_BCM
 	  To compile this driver as a module, choose M here: the
 	  module will be called bcm-keypad.
 
+config KEYBOARD_MT6779
+	tristate "MediaTek Keypad Support"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	select REGMAP_MMIO
+	select INPUT_MATRIXKMAP
+	help
+	  Say Y here if you want to use the keypad on MediaTek SoCs.
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mt6779-keypad.
+
 config KEYBOARD_MTK_PMIC
 	tristate "MediaTek PMIC keys support"
 	depends on MFD_MT6397
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index e3c8648f834e..721936e90290 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
 obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
+obj-$(CONFIG_KEYBOARD_MT6779)		+= mt6779-keypad.o
 obj-$(CONFIG_KEYBOARD_MTK_PMIC) 	+= mtk-pmic-keys.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
diff --git a/drivers/input/keyboard/mt6779-keypad.c b/drivers/input/keyboard/mt6779-keypad.c
new file mode 100644
index 000000000000..369366f18fd2
--- /dev/null
+++ b/drivers/input/keyboard/mt6779-keypad.c
@@ -0,0 +1,218 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author Fengping Yu <fengping.yu at mediatek.com>
+ */
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/input/matrix_keypad.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define MTK_KPD_NAME		"mt6779-keypad"
+#define MTK_KPD_MEM		0x0004
+#define MTK_KPD_DEBOUNCE	0x0018
+#define MTK_KPD_DEBOUNCE_MASK	GENMASK(13, 0)
+#define MTK_KPD_DEBOUNCE_MAX_MS	256
+#define MTK_KPD_NUM_MEMS	5
+#define MTK_KPD_NUM_BITS	136	/* 4*32+8 MEM5 only use 8 BITS */
+
+struct mt6779_keypad {
+	struct regmap *regmap;
+	struct input_dev *input_dev;
+	struct clk *clk;
+	void __iomem *base;
+	u32 n_rows;
+	u32 n_cols;
+	DECLARE_BITMAP(keymap_state, MTK_KPD_NUM_BITS);
+};
+
+static const struct regmap_config mt6779_keypad_regmap_cfg = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = sizeof(u32),
+	.max_register = 36,
+};
+
+static irqreturn_t mt6779_keypad_irq_handler(int irq, void *dev_id)
+{
+	struct mt6779_keypad *keypad = dev_id;
+	unsigned short *keycode = keypad->input_dev->keycode;
+	DECLARE_BITMAP(new_state, MTK_KPD_NUM_BITS);
+	DECLARE_BITMAP(change, MTK_KPD_NUM_BITS);
+	int bit_nr;
+	int pressed;
+	unsigned short code;
+	int row, col;
+	int row_shift = get_count_order(keypad->n_cols);
+
+	regmap_bulk_read(keypad->regmap, MTK_KPD_MEM,
+			 new_state, MTK_KPD_NUM_MEMS);
+
+	bitmap_xor(change, new_state, keypad->keymap_state, MTK_KPD_NUM_BITS);
+
+	for_each_set_bit(bit_nr, change, MTK_KPD_NUM_BITS) {
+	/* For 32bits register, only bits [15:0] use to indicate key status */
+		if (bit_nr % 32 >= 16)
+			continue;
+
+		/* 1: not pressed, 0: pressed */
+		pressed = !test_bit(bit_nr, new_state);
+		dev_dbg(&keypad->input_dev->dev, "%s",
+			pressed ? "pressed" : "released");
+
+		row = bit_nr / 32;
+		col = bit_nr % 32;
+
+		code = keycode[MATRIX_SCAN_CODE(row, col, row_shift)];
+
+		input_report_key(keypad->input_dev, code, pressed);
+		input_sync(keypad->input_dev);
+
+		dev_dbg(&keypad->input_dev->dev,
+			"report Linux keycode = %d\n", code);
+	}
+
+	bitmap_copy(keypad->keymap_state, new_state, MTK_KPD_NUM_BITS);
+
+	return IRQ_HANDLED;
+}
+
+static void mt6779_keypad_clk_disable(void *data)
+{
+	clk_disable_unprepare(data);
+}
+
+static int mt6779_keypad_pdrv_probe(struct platform_device *pdev)
+{
+	struct mt6779_keypad *keypad;
+	unsigned int irq;
+	u32 debounce;
+	bool wakeup;
+	int error;
+
+	keypad = devm_kzalloc(&pdev->dev, sizeof(*keypad), GFP_KERNEL);
+	if (!keypad)
+		return -ENOMEM;
+
+	keypad->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(keypad->base))
+		return PTR_ERR(keypad->base);
+
+	keypad->regmap = devm_regmap_init_mmio(&pdev->dev,
+					       keypad->base,
+					       &mt6779_keypad_regmap_cfg);
+	if (IS_ERR(keypad->regmap)) {
+		dev_err(&pdev->dev,
+			"regmap init failed:%pe\n", keypad->regmap);
+		return PTR_ERR(keypad->regmap);
+	}
+
+	bitmap_fill(keypad->keymap_state, MTK_KPD_NUM_BITS);
+
+	keypad->input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!keypad->input_dev) {
+		dev_err(&pdev->dev, "Failed to allocate input dev\n");
+		return -ENOMEM;
+	}
+
+	keypad->input_dev->name = MTK_KPD_NAME;
+	keypad->input_dev->id.bustype = BUS_HOST;
+
+	error = matrix_keypad_parse_properties(&pdev->dev, &keypad->n_rows,
+					       &keypad->n_cols);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to parse keypad params\n");
+		return error;
+	}
+
+	if (device_property_read_u32(&pdev->dev, "debounce-delay-ms",
+				     &debounce))
+		debounce = 16;
+
+	if (debounce > MTK_KPD_DEBOUNCE_MAX_MS) {
+		dev_err(&pdev->dev, "Debounce time exceeds the maximum allowed time %dms\n",
+			MTK_KPD_DEBOUNCE_MAX_MS);
+		return -EINVAL;
+	}
+
+	wakeup = device_property_read_bool(&pdev->dev, "wakeup-source");
+
+	dev_dbg(&pdev->dev, "n_row=%d n_col=%d debounce=%d\n",
+		keypad->n_rows, keypad->n_cols, debounce);
+
+	error = matrix_keypad_build_keymap(NULL, NULL,
+					   keypad->n_rows,
+					   keypad->n_cols,
+					   NULL,
+					   keypad->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to build keymap\n");
+		return error;
+	}
+
+	regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
+		     (debounce * 32) & MTK_KPD_DEBOUNCE_MASK);
+
+	keypad->clk = devm_clk_get(&pdev->dev, "kpd");
+	if (IS_ERR(keypad->clk))
+		return PTR_ERR(keypad->clk);
+
+	error = clk_prepare_enable(keypad->clk);
+	if (error) {
+		dev_err(&pdev->dev, "cannot prepare/enable keypad clock\n");
+		return error;
+	}
+
+	error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable, keypad->clk);
+	if (error)
+		return error;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	error = devm_request_threaded_irq(&pdev->dev, irq,
+					  NULL, mt6779_keypad_irq_handler,
+					  IRQF_ONESHOT,
+					  MTK_KPD_NAME, keypad);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to request IRQ#%d:%d\n",
+			irq, error);
+		return error;
+	}
+
+	error = input_register_device(keypad->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "Failed to register device\n");
+		return error;
+	}
+
+	error =  device_init_wakeup(&pdev->dev, wakeup);
+	if (error)
+		dev_warn(&pdev->dev, "device_init_wakeup fail\n");
+
+	return 0;
+}
+
+static const struct of_device_id mt6779_keypad_of_match[] = {
+	{ .compatible = "mediatek,mt6779-keypad" },
+	{ .compatible = "mediatek,mt6873-keypad" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver mt6779_keypad_pdrv = {
+	.probe = mt6779_keypad_pdrv_probe,
+	.driver = {
+		   .name = MTK_KPD_NAME,
+		   .of_match_table = mt6779_keypad_of_match,
+	},
+};
+module_platform_driver(mt6779_keypad_pdrv);
+
+MODULE_AUTHOR("Mediatek Corporation");
+MODULE_DESCRIPTION("MTK Keypad (KPD) Driver");
+MODULE_LICENSE("GPL");
-- 
2.32.0



From mkorpershoek at baylibre.com  Thu Jan 27 03:15:26 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Thu, 27 Jan 2022 12:15:26 +0100
Subject: [PATCH v20 3/3] arm64: defconfig: Add CONFIG_KEYBOARD_MT6779=m
In-Reply-To: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
Message-ID: <20220127111526.3716689-4-mkorpershoek@baylibre.com>

From: "fengping.yu" <fengping.yu at mediatek.com>

Add Mediatek matrix keypad support in defconfig.

Signed-off-by: fengping.yu <fengping.yu at mediatek.com>
Signed-off-by: Mattijs Korpershoek <mkorpershoek at baylibre.com>
Reviewed-by: Marco Felsch <m.felsch at pengutronix.de>
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index f2e2b9bdd702..099a9e68711c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -390,6 +390,7 @@ CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_SNVS_PWRKEY=m
 CONFIG_KEYBOARD_IMX_SC_KEY=m
 CONFIG_KEYBOARD_CROS_EC=y
+CONFIG_KEYBOARD_MT6779=m
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MXT=m
 CONFIG_TOUCHSCREEN_GOODIX=m
-- 
2.32.0



From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:17:12 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:17:12 +0100
Subject: [PATCH v4 29/35] iommu/mediatek: Add mtk_iommu_bank_data structure
In-Reply-To: <20220125085634.17972-30-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-30-yong.wu@mediatek.com>
Message-ID: <fd39758a-b5a7-c6d9-3d29-0c6221d0c533@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Prepare for supporting multi-banks for the IOMMU HW, No functional change.
> 
> Add a new structure(mtk_iommu_bank_data) for each a bank. Each a bank have
> the independent HW base/IRQ/tlb-range ops, and each a bank has its special
> iommu-domain(independent pgtable), thus, also move the domain information
> into it.
> 
> In previous SoC, we have only one bank which could be treated as bank0(
> bankid always is 0 for the previous SoC).
> 
> After adding this structure, the tlb operations and irq could use
> bank_data as parameter.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From alain.volmat at foss.st.com  Thu Jan 27 03:18:02 2022
From: alain.volmat at foss.st.com (Alain Volmat)
Date: Thu, 27 Jan 2022 12:18:02 +0100
Subject: [PATCH] media: stm32-dcmi: create video dev once sensor is binded
Message-ID: <20220127111802.976275-1-alain.volmat@foss.st.com>

In case of an error during the initialization of the sensor,
the video device is still available since created at the
probe of the dcmi driver. Moreover the device wouldn't
be released even when removing the module since the release
is performed as part of the notifier unbind callback
(not called if no sensor is properly initialized).

This patch move the video device creation with the v4l2 notifier
complete handler in order to avoid having a video device created when
an error happen during the pipe (dcmi - sensor) initialization.

This also makes the video device creation symmetric with the
release which is already done within the notifier unbind handler.

Signed-off-by: Alain Volmat <alain.volmat at foss.st.com>
---
v1: this patch is the replacement patch of a previous attempt [1]
to move the register within the bound callback.

[1] https://lore.kernel.org/linux-media/31ca9ccc-77d4-4368-1024-db70e8e1e7f2 at xs4all.nl/
 drivers/media/platform/stm32/stm32-dcmi.c | 69 ++++++++++++-----------
 1 file changed, 35 insertions(+), 34 deletions(-)

diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c
index e1b17c05229c..80d0fbeabb4f 100644
--- a/drivers/media/platform/stm32/stm32-dcmi.c
+++ b/drivers/media/platform/stm32/stm32-dcmi.c
@@ -134,6 +134,7 @@ struct stm32_dcmi {
 	struct video_device		*vdev;
 	struct v4l2_async_notifier	notifier;
 	struct v4l2_subdev		*source;
+	struct v4l2_subdev		*remote;
 	struct v4l2_format		fmt;
 	struct v4l2_rect		crop;
 	bool				do_crop;
@@ -579,9 +580,9 @@ static void dcmi_buf_queue(struct vb2_buffer *vb)
 	spin_unlock_irq(&dcmi->irqlock);
 }
 
-static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi)
+static struct media_entity *dcmi_find_source(struct v4l2_subdev *subdev)
 {
-	struct media_entity *entity = &dcmi->vdev->entity;
+	struct media_entity *entity = &subdev->entity;
 	struct media_pad *pad;
 
 	/* Walk searching for entity having no sink */
@@ -1721,6 +1722,7 @@ static int dcmi_framesizes_init(struct stm32_dcmi *dcmi)
 static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier)
 {
 	struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
+	int src_pad;
 	int ret;
 
 	/*
@@ -1728,7 +1730,7 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier)
 	 * we search for the source subdevice
 	 * in order to expose it through V4L2 interface
 	 */
-	dcmi->source = media_entity_to_v4l2_subdev(dcmi_find_source(dcmi));
+	dcmi->source = media_entity_to_v4l2_subdev(dcmi_find_source(dcmi->remote));
 	if (!dcmi->source) {
 		dev_err(dcmi->dev, "Source subdevice not found\n");
 		return -ENODEV;
@@ -1768,6 +1770,34 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier)
 		return ret;
 	}
 
+	ret = video_register_device(dcmi->vdev, VFL_TYPE_VIDEO, -1);
+	if (ret) {
+		dev_err(dcmi->dev, "Failed to register video device\n");
+		return ret;
+	}
+
+	dev_dbg(dcmi->dev, "Device registered as %s\n",
+		video_device_node_name(dcmi->vdev));
+
+	/*
+	 * Link remote sub-device to DCMI, it could be
+	 * a parallel camera sensor or a bridge
+	 */
+	src_pad = media_entity_get_fwnode_pad(&dcmi->remote->entity,
+					      dcmi->remote->fwnode,
+					      MEDIA_PAD_FL_SOURCE);
+
+	ret = media_create_pad_link(&dcmi->remote->entity, src_pad,
+				    &dcmi->vdev->entity, 0,
+				    MEDIA_LNK_FL_IMMUTABLE |
+				    MEDIA_LNK_FL_ENABLED);
+	if (ret)
+		dev_err(dcmi->dev, "Failed to create media pad link with subdev \"%s\"\n",
+			dcmi->remote->name);
+	else
+		dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n",
+			dcmi->remote->name);
+
 	return 0;
 }
 
@@ -1788,31 +1818,11 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier,
 				   struct v4l2_async_subdev *asd)
 {
 	struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier);
-	unsigned int ret;
-	int src_pad;
 
 	dev_dbg(dcmi->dev, "Subdev \"%s\" bound\n", subdev->name);
+	dcmi->remote = subdev;
 
-	/*
-	 * Link this sub-device to DCMI, it could be
-	 * a parallel camera sensor or a bridge
-	 */
-	src_pad = media_entity_get_fwnode_pad(&subdev->entity,
-					      subdev->fwnode,
-					      MEDIA_PAD_FL_SOURCE);
-
-	ret = media_create_pad_link(&subdev->entity, src_pad,
-				    &dcmi->vdev->entity, 0,
-				    MEDIA_LNK_FL_IMMUTABLE |
-				    MEDIA_LNK_FL_ENABLED);
-	if (ret)
-		dev_err(dcmi->dev, "Failed to create media pad link with subdev \"%s\"\n",
-			subdev->name);
-	else
-		dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n",
-			subdev->name);
-
-	return ret;
+	return 0;
 }
 
 static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = {
@@ -2008,15 +2018,6 @@ static int dcmi_probe(struct platform_device *pdev)
 	}
 	dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
 
-	ret = video_register_device(dcmi->vdev, VFL_TYPE_VIDEO, -1);
-	if (ret) {
-		dev_err(dcmi->dev, "Failed to register video device\n");
-		goto err_media_entity_cleanup;
-	}
-
-	dev_dbg(dcmi->dev, "Device registered as %s\n",
-		video_device_node_name(dcmi->vdev));
-
 	/* Buffer queue */
 	q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 	q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF;
-- 
2.25.1



From s.hauer at pengutronix.de  Thu Jan 27 03:20:11 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Thu, 27 Jan 2022 12:20:11 +0100
Subject: [PATCH 07/27] drm/rockchip: dw_hdmi: Use auto-generated tables
In-Reply-To: <CAD=FV=U7W_oWjS_gCurAkNdkcuHQGn-XH=-VwP2MSG9zO92ySg@mail.gmail.com>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-8-s.hauer@pengutronix.de>
 <CAD=FV=U7W_oWjS_gCurAkNdkcuHQGn-XH=-VwP2MSG9zO92ySg@mail.gmail.com>
Message-ID: <20220127112011.GM23490@pengutronix.de>

On Wed, Jan 26, 2022 at 07:54:53AM -0800, Doug Anderson wrote:
> Hi,
> 
> On Wed, Jan 26, 2022 at 6:58 AM Sascha Hauer <s.hauer at pengutronix.de> wrote:
> >
> > From: Douglas Anderson <dianders at chromium.org>
> >
> > The previous tables for mpll_cfg and curr_ctrl were created using the
> > 20-pages of example settings provided by the PHY vendor.  Those
> > example settings weren't particularly dense, so there were places
> > where we were guessing what the settings would be for 10-bit and
> > 12-bit (not that we use those anyway).  It was also always a lot of
> > extra work every time we wanted to add a new clock rate since we had
> > to cross-reference several tables.
> >
> > In <http://crosreview.com/285855> I've gone through the work to figure
> 
> The `crosreview.com` syntax doesn't seem to work anymore. Could maybe
> update to https://crrev.com/c/285855 ?

did that, thanks.

> 
> > out how to generate this table automatically.  Let's now use the
> > automatically generated table and then we'll never need to look at it
> > again.
> >
> > We only support 8-bit mode right now and only support a small number
> > of clock rates and and I've verified that the only 8-bit rate that was
> > affected was 148.5.  That mode appears to have been wrong in the old
> > table.
> >
> > Changes since v3:
> > - new patch
> >
> > Signed-off-by: Douglas Anderson <dianders at chromium.org>
> > Signed-off-by: Yakir Yang <ykk at rock-chips.com>
> 
> Should probably change the "at" to "@" ?

yes.

> 
> > Reviewed-by: St?phane Marchesin <marcheu at chromium.org>
> 
> In general shouldn't carry downstream reviews when posting upstream
> unless you're certain that the person intended it...
> 
> 
> It's been a long time, but in general I think I was fairly confident
> in the numbers that my script pumped out, at least given the caveat of
> no pixel repetition and 8-bit only. That being said, I didn't have any
> inside knowledge of the hardware and just figured out formulas that
> seemed to match the table that I had. YMMV.

Rockchip adopted this patch for their downstream Kernel, so they haven't
been able to come up with better values. Given that you created this
patch for a fairly old SoC and the values are still usable on rk3568 I
think that's the way to go.

> 
> I'll also say that when I did a rebase of veyron (rk3288-based
> Chromebook) to 4.19 about 2.5 years ago, I ended up squashing several
> of these patches into 1. That can be found at
> <https://crrev.com/c/1661056>. That also has details about why some of
> these patches never made it upstream. The main reason, at least in the
> case of rk3288, was the PLL sharing problem that nobody ever solved.
> rk3288 didn't have quite enough PLLs and thus, if you were using both
> VOPs, one of the VOPs was going to be severely limited in what pixel
> clocks it could make. There was no framework deciding which VOP should
> be limited and how the system should react to this...
> 
> 
> In any case, I'm pretty far disconnected from all this stuff now, but
> I wish you the best of luck in trying to get it all solved!

Nah, sorry, I won't get that all solved ;)

I am not that interested in rk3288, my main concern is the rk3568. That
one has two spare PLLs for three heads instead of one PLL for two heads,
so the problem is less pressing.

I'll stick to this version of the patch instead of the combined one
because this patch seems to be correct regardless of the PLL problem.

Thanks for the link though, it gives me some insights why things are the
way they are currently.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:21:21 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:21:21 +0100
Subject: [PATCH v4 32/35] iommu/mediatek: Get the proper bankid for multi
 banks
In-Reply-To: <20220125085634.17972-33-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-33-yong.wu@mediatek.com>
Message-ID: <0dce6a25-6e45-efcc-3235-b8b7be81ea4f@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> We preassign some ports in a special bank via the new defined
> banks_portmsk. Put it in the plat_data means it is not expected to be
> adjusted dynamically.
> 
> If the iommu id in the iommu consumer's dtsi node is inside this
> banks_portmsk, then we switch it to this special iommu bank, and
> initialise the IOMMU bank HW.
> 
> Each a bank has the independent pgtable(4GB iova range). Each a bank
> is a independent iommu domain/group. Currently we don't separate different
> iova ranges inside a bank.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 39 ++++++++++++++++++++++++++++++++++++---
>   1 file changed, 36 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index 22586d1aed72..c6de9304bbc6 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -191,6 +191,7 @@ struct mtk_iommu_plat_data {
>   
>   	u8                  banks_num;
>   	bool                banks_enable[MTK_IOMMU_BANK_MAX];
> +	unsigned int        banks_portmsk[MTK_IOMMU_BANK_MAX];

I would prefer to see u32 here instead... but maybe that's just a
personal preference, it doesn't really matter.

In any case:
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>




From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:24:14 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:24:14 +0100
Subject: [PATCH v4 34/35] iommu/mediatek: Backup/restore regsiters for
 multi banks
In-Reply-To: <20220125085634.17972-35-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-35-yong.wu@mediatek.com>
Message-ID: <471f2317-24eb-9d94-8ba2-1124cdc95ed6@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Each bank has some independent registers. thus backup/restore them for
> each a bank when suspend and resume.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:25:03 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:25:03 +0100
Subject: [PATCH v4 35/35] iommu/mediatek: mt8195: Enable multi banks for
 infra iommu
In-Reply-To: <20220125085634.17972-36-yong.wu@mediatek.com>
References: <20220125085634.17972-1-yong.wu@mediatek.com>
 <20220125085634.17972-36-yong.wu@mediatek.com>
Message-ID: <35ddad90-a13b-0370-a218-87887f47c0da@collabora.com>

Il 25/01/22 09:56, Yong Wu ha scritto:
> Enable the multi-bank functions for infra-iommu. We put PCIE in bank0
> and USB in the last bank(bank4). and we don't use the other banks
> currently, disable them.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>



From angelogioacchino.delregno at collabora.com  Thu Jan 27 03:28:05 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 12:28:05 +0100
Subject: [PATCH 2/2] iommu/mediatek: Add mt8186 iommu support
In-Reply-To: <20220125093244.18230-3-yong.wu@mediatek.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
 <20220125093244.18230-3-yong.wu@mediatek.com>
Message-ID: <b52a1df8-58f4-baa2-cfb6-9c56244caa0f@collabora.com>

Il 25/01/22 10:32, Yong Wu ha scritto:
> Add mt8186 iommu supports.
> 
> Signed-off-by: Anan Sun <anan.sun at mediatek.com>
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
>   drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
> index be36e73e4bcc..a3124f48f9e1 100644
> --- a/drivers/iommu/mtk_iommu.c
> +++ b/drivers/iommu/mtk_iommu.c
> @@ -160,6 +160,7 @@ enum mtk_iommu_plat {
>   	M4U_MT8167,
>   	M4U_MT8173,
>   	M4U_MT8183,
> +	M4U_MT8186,
>   	M4U_MT8192,
>   	M4U_MT8195,
>   };
> @@ -1401,6 +1402,21 @@ static const struct mtk_iommu_plat_data mt8183_data = {
>   	.larbid_remap = {{0}, {4}, {5}, {6}, {7}, {2}, {3}, {1}},
>   };
>   
> +static const struct mtk_iommu_plat_data mt8186_data_mm = {
> +	.m4u_plat       = M4U_MT8186,
> +	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
> +			  WR_THROT_EN | IOVA_34_EN | NOT_STD_AXI_MODE |
> +			  MTK_IOMMU_TYPE_MM,
> +	.larbid_remap   = {{0}, {1, MTK_INVALID_LARBID, 8}, {4}, {7}, {2}, {9, 11, 19, 20},
> +			   {MTK_INVALID_LARBID, 14, 16},
> +			   {MTK_INVALID_LARBID, 13, MTK_INVALID_LARBID, 17}},
> +	.inv_sel_reg    = REG_MMU_INV_SEL_GEN2,
> +	.banks_num      = 1,
> +	.banks_enable   = {true},
> +	.iova_region    = mt8192_multi_dom,
> +	.iova_region_nr = ARRAY_SIZE(mt8192_multi_dom),
> +};
> +
>   static const struct mtk_iommu_plat_data mt8192_data = {
>   	.m4u_plat       = M4U_MT8192,
>   	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS | OUT_ORDER_WR_EN |
> @@ -1470,6 +1486,7 @@ static const struct of_device_id mtk_iommu_of_ids[] = {
>   	{ .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data},
>   	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
>   	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
> +	{ .compatible = "mediatek,mt8186-iommu-mm", .data = &mt8186_data_mm},

Hello!

Is there any particular reason why this compatible is not "mediatek,mt8186-m4u"?

Thanks,
Angelo

>   	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
>   	{ .compatible = "mediatek,mt8195-iommu-infra", .data = &mt8195_data_infra},
>   	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data = &mt8195_data_vdo},
> 



From ardb at kernel.org  Thu Jan 27 03:35:42 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 12:35:42 +0100
Subject: [PATCH 0/3] crypto: arm - simplify bit sliced AES 
Message-ID: <20220127113545.7821-1-ardb@kernel.org>

This contains a couple of improvements/simplifications for the bit
sliced AES driver implemented on ARM and arm64.

Ard Biesheuvel (3):
  crypto: arm/aes-neonbs-ctr - deal with non-multiples of AES block size
  crypto: arm64/aes-neonbs-ctr - fallback to plain NEON for final chunk
  crypto: arm64/aes-neonbs-xts - use plain NEON for non-power-of-2 input
    sizes

 arch/arm/crypto/aes-neonbs-core.S   | 105 ++++----
 arch/arm/crypto/aes-neonbs-glue.c   |  35 ++-
 arch/arm64/crypto/aes-glue.c        |   1 +
 arch/arm64/crypto/aes-neonbs-core.S | 264 +++++---------------
 arch/arm64/crypto/aes-neonbs-glue.c |  97 ++++---
 5 files changed, 189 insertions(+), 313 deletions(-)

-- 
2.30.2



From ardb at kernel.org  Thu Jan 27 03:35:43 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 12:35:43 +0100
Subject: [PATCH 1/3] crypto: arm/aes-neonbs-ctr - deal with non-multiples of
 AES block size
In-Reply-To: <20220127113545.7821-1-ardb@kernel.org>
References: <20220127113545.7821-1-ardb@kernel.org>
Message-ID: <20220127113545.7821-2-ardb@kernel.org>

Instead of falling back to C code to deal with the final bit of input
that is not a round multiple of the block size, handle this in the asm
code, permitting us to use overlapping loads and stores for performance,
and implement the 16-byte wide XOR using a single NEON instruction.

Since NEON loads and stores have a natural width of 16 bytes, we need to
handle inputs of less than 16 bytes in a special way, but this rarely
occurs in practice so it does not impact performance. All other input
sizes can be consumed directly by the NEON asm code, although it should
be noted that the core AES transform can still only process 128 bytes (8
AES blocks) at a time.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm/crypto/aes-neonbs-core.S | 105 ++++++++++++--------
 arch/arm/crypto/aes-neonbs-glue.c |  35 +++----
 2 files changed, 77 insertions(+), 63 deletions(-)

diff --git a/arch/arm/crypto/aes-neonbs-core.S b/arch/arm/crypto/aes-neonbs-core.S
index 7d0cc7f226a5..7b61032f29fa 100644
--- a/arch/arm/crypto/aes-neonbs-core.S
+++ b/arch/arm/crypto/aes-neonbs-core.S
@@ -758,29 +758,24 @@ ENTRY(aesbs_cbc_decrypt)
 ENDPROC(aesbs_cbc_decrypt)
 
 	.macro		next_ctr, q
-	vmov.32		\q\()h[1], r10
+	vmov		\q\()h, r9, r10
 	adds		r10, r10, #1
-	vmov.32		\q\()h[0], r9
 	adcs		r9, r9, #0
-	vmov.32		\q\()l[1], r8
+	vmov		\q\()l, r7, r8
 	adcs		r8, r8, #0
-	vmov.32		\q\()l[0], r7
 	adc		r7, r7, #0
 	vrev32.8	\q, \q
 	.endm
 
 	/*
 	 * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
-	 *		     int rounds, int blocks, u8 ctr[], u8 final[])
+	 *		     int rounds, int bytes, u8 ctr[])
 	 */
 ENTRY(aesbs_ctr_encrypt)
 	mov		ip, sp
 	push		{r4-r10, lr}
 
-	ldm		ip, {r5-r7}		// load args 4-6
-	teq		r7, #0
-	addne		r5, r5, #1		// one extra block if final != 0
-
+	ldm		ip, {r5, r6}		// load args 4-5
 	vld1.8		{q0}, [r6]		// load counter
 	vrev32.8	q1, q0
 	vmov		r9, r10, d3
@@ -792,20 +787,19 @@ ENTRY(aesbs_ctr_encrypt)
 	adc		r7, r7, #0
 
 99:	vmov		q1, q0
+	sub		lr, r5, #1
 	vmov		q2, q0
+	adr		ip, 0f
 	vmov		q3, q0
+	and		lr, lr, #112
 	vmov		q4, q0
+	cmp		r5, #112
 	vmov		q5, q0
+	sub		ip, ip, lr, lsl #1
 	vmov		q6, q0
+	add		ip, ip, lr, lsr #2
 	vmov		q7, q0
-
-	adr		ip, 0f
-	sub		lr, r5, #1
-	and		lr, lr, #7
-	cmp		r5, #8
-	sub		ip, ip, lr, lsl #5
-	sub		ip, ip, lr, lsl #2
-	movlt		pc, ip			// computed goto if blocks < 8
+	movle		pc, ip			// computed goto if bytes < 112
 
 	next_ctr	q1
 	next_ctr	q2
@@ -820,12 +814,14 @@ ENTRY(aesbs_ctr_encrypt)
 	bl		aesbs_encrypt8
 
 	adr		ip, 1f
-	and		lr, r5, #7
-	cmp		r5, #8
-	movgt		r4, #0
-	ldrle		r4, [sp, #40]		// load final in the last round
-	sub		ip, ip, lr, lsl #2
-	movlt		pc, ip			// computed goto if blocks < 8
+	sub		lr, r5, #1
+	cmp		r5, #128
+	bic		lr, lr, #15
+	ands		r4, r5, #15		// preserves C flag
+	teqcs		r5, r5			// set Z flag if not last iteration
+	sub		ip, ip, lr, lsr #2
+	rsb		r4, r4, #16
+	movcc		pc, ip			// computed goto if bytes < 128
 
 	vld1.8		{q8}, [r1]!
 	vld1.8		{q9}, [r1]!
@@ -834,46 +830,70 @@ ENTRY(aesbs_ctr_encrypt)
 	vld1.8		{q12}, [r1]!
 	vld1.8		{q13}, [r1]!
 	vld1.8		{q14}, [r1]!
-	teq		r4, #0			// skip last block if 'final'
-1:	bne		2f
+1:	subne		r1, r1, r4
 	vld1.8		{q15}, [r1]!
 
-2:	adr		ip, 3f
-	cmp		r5, #8
-	sub		ip, ip, lr, lsl #3
-	movlt		pc, ip			// computed goto if blocks < 8
+	add		ip, ip, #2f - 1b
 
 	veor		q0, q0, q8
-	vst1.8		{q0}, [r0]!
 	veor		q1, q1, q9
-	vst1.8		{q1}, [r0]!
 	veor		q4, q4, q10
-	vst1.8		{q4}, [r0]!
 	veor		q6, q6, q11
-	vst1.8		{q6}, [r0]!
 	veor		q3, q3, q12
-	vst1.8		{q3}, [r0]!
 	veor		q7, q7, q13
-	vst1.8		{q7}, [r0]!
 	veor		q2, q2, q14
+	bne		3f
+	veor		q5, q5, q15
+
+	movcc		pc, ip			// computed goto if bytes < 128
+
+	vst1.8		{q0}, [r0]!
+	vst1.8		{q1}, [r0]!
+	vst1.8		{q4}, [r0]!
+	vst1.8		{q6}, [r0]!
+	vst1.8		{q3}, [r0]!
+	vst1.8		{q7}, [r0]!
 	vst1.8		{q2}, [r0]!
-	teq		r4, #0			// skip last block if 'final'
-	W(bne)		5f
-3:	veor		q5, q5, q15
+2:	subne		r0, r0, r4
 	vst1.8		{q5}, [r0]!
 
-4:	next_ctr	q0
+	next_ctr	q0
 
-	subs		r5, r5, #8
+	subs		r5, r5, #128
 	bgt		99b
 
 	vst1.8		{q0}, [r6]
 	pop		{r4-r10, pc}
 
-5:	vst1.8		{q5}, [r4]
-	b		4b
+3:	adr		lr, .Lpermute_table + 16
+	cmp		r5, #16			// Z flag remains cleared
+	sub		lr, lr, r4
+	vld1.8		{q8-q9}, [lr]
+	vtbl.8		d16, {q5}, d16
+	vtbl.8		d17, {q5}, d17
+	veor		q5, q8, q15
+	bcc		4f			// have to reload prev if R5 < 16
+	vtbx.8		d10, {q2}, d18
+	vtbx.8		d11, {q2}, d19
+	mov		pc, ip			// branch back to VST sequence
+
+4:	sub		r0, r0, r4
+	vshr.s8		q9, q9, #7		// create mask for VBIF
+	vld1.8		{q8}, [r0]		// reload
+	vbif		q5, q8, q9
+	vst1.8		{q5}, [r0]
+	pop		{r4-r10, pc}
 ENDPROC(aesbs_ctr_encrypt)
 
+	.align		6
+.Lpermute_table:
+	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+	.byte		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	.byte		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+
 	.macro		next_tweak, out, in, const, tmp
 	vshr.s64	\tmp, \in, #63
 	vand		\tmp, \tmp, \const
@@ -888,6 +908,7 @@ ENDPROC(aesbs_ctr_encrypt)
 	 * aesbs_xts_decrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
 	 *		     int blocks, u8 iv[], int reorder_last_tweak)
 	 */
+	.align		6
 __xts_prepare8:
 	vld1.8		{q14}, [r7]		// load iv
 	vmov.i32	d30, #0x87		// compose tweak mask vector
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c
index 5c6cd3c63cbc..f00f042ef357 100644
--- a/arch/arm/crypto/aes-neonbs-glue.c
+++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -37,7 +37,7 @@ asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
 				  int rounds, int blocks, u8 iv[]);
 
 asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
-				  int rounds, int blocks, u8 ctr[], u8 final[]);
+				  int rounds, int blocks, u8 ctr[]);
 
 asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
 				  int rounds, int blocks, u8 iv[], int);
@@ -243,32 +243,25 @@ static int ctr_encrypt(struct skcipher_request *req)
 	err = skcipher_walk_virt(&walk, req, false);
 
 	while (walk.nbytes > 0) {
-		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
-		u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
+		const u8 *src = walk.src.virt.addr;
+		u8 *dst = walk.dst.virt.addr;
+		int bytes = walk.nbytes;
 
-		if (walk.nbytes < walk.total) {
-			blocks = round_down(blocks,
-					    walk.stride / AES_BLOCK_SIZE);
-			final = NULL;
-		}
+		if (unlikely(bytes < AES_BLOCK_SIZE))
+			src = dst = memcpy(buf + sizeof(buf) - bytes,
+					   src, bytes);
+		else if (walk.nbytes < walk.total)
+			bytes &= ~(8 * AES_BLOCK_SIZE - 1);
 
 		kernel_neon_begin();
-		aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
-				  ctx->rk, ctx->rounds, blocks, walk.iv, final);
+		aesbs_ctr_encrypt(dst, src, ctx->rk, ctx->rounds, bytes, walk.iv);
 		kernel_neon_end();
 
-		if (final) {
-			u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
-			u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
+		if (unlikely(bytes < AES_BLOCK_SIZE))
+			memcpy(walk.dst.virt.addr,
+			       buf + sizeof(buf) - bytes, bytes);
 
-			crypto_xor_cpy(dst, src, final,
-				       walk.total % AES_BLOCK_SIZE);
-
-			err = skcipher_walk_done(&walk, 0);
-			break;
-		}
-		err = skcipher_walk_done(&walk,
-					 walk.nbytes - blocks * AES_BLOCK_SIZE);
+		err = skcipher_walk_done(&walk, walk.nbytes - bytes);
 	}
 
 	return err;
-- 
2.30.2



From ardb at kernel.org  Thu Jan 27 03:35:44 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 12:35:44 +0100
Subject: [PATCH 2/3] crypto: arm64/aes-neonbs-ctr - fallback to plain NEON for
 final chunk
In-Reply-To: <20220127113545.7821-1-ardb@kernel.org>
References: <20220127113545.7821-1-ardb@kernel.org>
Message-ID: <20220127113545.7821-3-ardb@kernel.org>

Instead of processing the entire input with the 8-way bit sliced
algorithm, which is sub-optimal for inputs that are not a multiple of
128 bytes in size, invoke the plain NEON version of CTR for the
remainder of the input after processing the bulk using 128 byte strides.

This allows us to greatly simplify the asm code that implements CTR, and
get rid of all the branches and special code paths. It also gains us a
couple of percent of performance.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/aes-glue.c        |   1 +
 arch/arm64/crypto/aes-neonbs-core.S | 132 ++++----------------
 arch/arm64/crypto/aes-neonbs-glue.c |  64 +++++-----
 3 files changed, 55 insertions(+), 142 deletions(-)

diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
index 30b7cc6a7079..3127794c09d6 100644
--- a/arch/arm64/crypto/aes-glue.c
+++ b/arch/arm64/crypto/aes-glue.c
@@ -983,6 +983,7 @@ module_cpu_feature_match(AES, aes_init);
 module_init(aes_init);
 EXPORT_SYMBOL(neon_aes_ecb_encrypt);
 EXPORT_SYMBOL(neon_aes_cbc_encrypt);
+EXPORT_SYMBOL(neon_aes_ctr_encrypt);
 EXPORT_SYMBOL(neon_aes_xts_encrypt);
 EXPORT_SYMBOL(neon_aes_xts_decrypt);
 #endif
diff --git a/arch/arm64/crypto/aes-neonbs-core.S b/arch/arm64/crypto/aes-neonbs-core.S
index a3405b8c344b..f2761481181d 100644
--- a/arch/arm64/crypto/aes-neonbs-core.S
+++ b/arch/arm64/crypto/aes-neonbs-core.S
@@ -869,133 +869,51 @@ SYM_FUNC_END(aesbs_xts_decrypt)
 
 	/*
 	 * aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
-	 *		     int rounds, int blocks, u8 iv[], u8 final[])
+	 *		     int rounds, int blocks, u8 iv[])
 	 */
 SYM_FUNC_START(aesbs_ctr_encrypt)
-	frame_push	8
+	stp		x29, x30, [sp, #-16]!
+	mov		x29, sp
 
-	mov		x19, x0
-	mov		x20, x1
-	mov		x21, x2
-	mov		x22, x3
-	mov		x23, x4
-	mov		x24, x5
-	mov		x25, x6
-
-	cmp		x25, #0
-	cset		x26, ne
-	add		x23, x23, x26		// do one extra block if final
-
-	ldp		x7, x8, [x24]
-	ld1		{v0.16b}, [x24]
+	ldp		x7, x8, [x5]
+	ld1		{v0.16b}, [x5]
 CPU_LE(	rev		x7, x7		)
 CPU_LE(	rev		x8, x8		)
 	adds		x8, x8, #1
 	adc		x7, x7, xzr
 
-99:	mov		x9, #1
-	lsl		x9, x9, x23
-	subs		w23, w23, #8
-	csel		x23, x23, xzr, pl
-	csel		x9, x9, xzr, le
-
-	tbnz		x9, #1, 0f
-	next_ctr	v1
-	tbnz		x9, #2, 0f
+0:	next_ctr	v1
 	next_ctr	v2
-	tbnz		x9, #3, 0f
 	next_ctr	v3
-	tbnz		x9, #4, 0f
 	next_ctr	v4
-	tbnz		x9, #5, 0f
 	next_ctr	v5
-	tbnz		x9, #6, 0f
 	next_ctr	v6
-	tbnz		x9, #7, 0f
 	next_ctr	v7
 
-0:	mov		bskey, x21
-	mov		rounds, x22
+	mov		bskey, x2
+	mov		rounds, x3
 	bl		aesbs_encrypt8
 
-	lsr		x9, x9, x26		// disregard the extra block
-	tbnz		x9, #0, 0f
-
-	ld1		{v8.16b}, [x20], #16
-	eor		v0.16b, v0.16b, v8.16b
-	st1		{v0.16b}, [x19], #16
-	tbnz		x9, #1, 1f
-
-	ld1		{v9.16b}, [x20], #16
-	eor		v1.16b, v1.16b, v9.16b
-	st1		{v1.16b}, [x19], #16
-	tbnz		x9, #2, 2f
-
-	ld1		{v10.16b}, [x20], #16
-	eor		v4.16b, v4.16b, v10.16b
-	st1		{v4.16b}, [x19], #16
-	tbnz		x9, #3, 3f
+	ld1		{ v8.16b-v11.16b}, [x1], #64
+	ld1		{v12.16b-v15.16b}, [x1], #64
 
-	ld1		{v11.16b}, [x20], #16
-	eor		v6.16b, v6.16b, v11.16b
-	st1		{v6.16b}, [x19], #16
-	tbnz		x9, #4, 4f
+	eor		v8.16b, v0.16b, v8.16b
+	eor		v9.16b, v1.16b, v9.16b
+	eor		v10.16b, v4.16b, v10.16b
+	eor		v11.16b, v6.16b, v11.16b
+	eor		v12.16b, v3.16b, v12.16b
+	eor		v13.16b, v7.16b, v13.16b
+	eor		v14.16b, v2.16b, v14.16b
+	eor		v15.16b, v5.16b, v15.16b
 
-	ld1		{v12.16b}, [x20], #16
-	eor		v3.16b, v3.16b, v12.16b
-	st1		{v3.16b}, [x19], #16
-	tbnz		x9, #5, 5f
+	st1		{ v8.16b-v11.16b}, [x0], #64
+	st1		{v12.16b-v15.16b}, [x0], #64
 
-	ld1		{v13.16b}, [x20], #16
-	eor		v7.16b, v7.16b, v13.16b
-	st1		{v7.16b}, [x19], #16
-	tbnz		x9, #6, 6f
-
-	ld1		{v14.16b}, [x20], #16
-	eor		v2.16b, v2.16b, v14.16b
-	st1		{v2.16b}, [x19], #16
-	tbnz		x9, #7, 7f
+	next_ctr	v0
+	subs		x4, x4, #8
+	b.gt		0b
 
-	ld1		{v15.16b}, [x20], #16
-	eor		v5.16b, v5.16b, v15.16b
-	st1		{v5.16b}, [x19], #16
-
-8:	next_ctr	v0
-	st1		{v0.16b}, [x24]
-	cbz		x23, .Lctr_done
-
-	b		99b
-
-.Lctr_done:
-	frame_pop
+	st1		{v0.16b}, [x5]
+	ldp		x29, x30, [sp], #16
 	ret
-
-	/*
-	 * If we are handling the tail of the input (x6 != NULL), return the
-	 * final keystream block back to the caller.
-	 */
-0:	cbz		x25, 8b
-	st1		{v0.16b}, [x25]
-	b		8b
-1:	cbz		x25, 8b
-	st1		{v1.16b}, [x25]
-	b		8b
-2:	cbz		x25, 8b
-	st1		{v4.16b}, [x25]
-	b		8b
-3:	cbz		x25, 8b
-	st1		{v6.16b}, [x25]
-	b		8b
-4:	cbz		x25, 8b
-	st1		{v3.16b}, [x25]
-	b		8b
-5:	cbz		x25, 8b
-	st1		{v7.16b}, [x25]
-	b		8b
-6:	cbz		x25, 8b
-	st1		{v2.16b}, [x25]
-	b		8b
-7:	cbz		x25, 8b
-	st1		{v5.16b}, [x25]
-	b		8b
 SYM_FUNC_END(aesbs_ctr_encrypt)
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
index 8df6ad8cb09d..3189003e1cbe 100644
--- a/arch/arm64/crypto/aes-neonbs-glue.c
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -34,7 +34,7 @@ asmlinkage void aesbs_cbc_decrypt(u8 out[], u8 const in[], u8 const rk[],
 				  int rounds, int blocks, u8 iv[]);
 
 asmlinkage void aesbs_ctr_encrypt(u8 out[], u8 const in[], u8 const rk[],
-				  int rounds, int blocks, u8 iv[], u8 final[]);
+				  int rounds, int blocks, u8 iv[]);
 
 asmlinkage void aesbs_xts_encrypt(u8 out[], u8 const in[], u8 const rk[],
 				  int rounds, int blocks, u8 iv[]);
@@ -46,6 +46,8 @@ asmlinkage void neon_aes_ecb_encrypt(u8 out[], u8 const in[], u32 const rk[],
 				     int rounds, int blocks);
 asmlinkage void neon_aes_cbc_encrypt(u8 out[], u8 const in[], u32 const rk[],
 				     int rounds, int blocks, u8 iv[]);
+asmlinkage void neon_aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
+				     int rounds, int bytes, u8 ctr[]);
 asmlinkage void neon_aes_xts_encrypt(u8 out[], u8 const in[],
 				     u32 const rk1[], int rounds, int bytes,
 				     u32 const rk2[], u8 iv[], int first);
@@ -58,7 +60,7 @@ struct aesbs_ctx {
 	int	rounds;
 } __aligned(AES_BLOCK_SIZE);
 
-struct aesbs_cbc_ctx {
+struct aesbs_cbc_ctr_ctx {
 	struct aesbs_ctx	key;
 	u32			enc[AES_MAX_KEYLENGTH_U32];
 };
@@ -128,10 +130,10 @@ static int ecb_decrypt(struct skcipher_request *req)
 	return __ecb_crypt(req, aesbs_ecb_decrypt);
 }
 
-static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
+static int aesbs_cbc_ctr_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
 			    unsigned int key_len)
 {
-	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
 	struct crypto_aes_ctx rk;
 	int err;
 
@@ -154,7 +156,7 @@ static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key,
 static int cbc_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
 	struct skcipher_walk walk;
 	int err;
 
@@ -177,7 +179,7 @@ static int cbc_encrypt(struct skcipher_request *req)
 static int cbc_decrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-	struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
 	struct skcipher_walk walk;
 	int err;
 
@@ -205,40 +207,32 @@ static int cbc_decrypt(struct skcipher_request *req)
 static int ctr_encrypt(struct skcipher_request *req)
 {
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
-	struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm);
+	struct aesbs_cbc_ctr_ctx *ctx = crypto_skcipher_ctx(tfm);
 	struct skcipher_walk walk;
-	u8 buf[AES_BLOCK_SIZE];
 	int err;
 
 	err = skcipher_walk_virt(&walk, req, false);
 
 	while (walk.nbytes > 0) {
-		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
-		u8 *final = (walk.total % AES_BLOCK_SIZE) ? buf : NULL;
-
-		if (walk.nbytes < walk.total) {
-			blocks = round_down(blocks,
-					    walk.stride / AES_BLOCK_SIZE);
-			final = NULL;
-		}
+		int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7;
+		int nbytes = walk.nbytes % (8 * AES_BLOCK_SIZE);
+		const u8 *src = walk.src.virt.addr;
+		u8 *dst = walk.dst.virt.addr;
 
 		kernel_neon_begin();
-		aesbs_ctr_encrypt(walk.dst.virt.addr, walk.src.virt.addr,
-				  ctx->rk, ctx->rounds, blocks, walk.iv, final);
-		kernel_neon_end();
-
-		if (final) {
-			u8 *dst = walk.dst.virt.addr + blocks * AES_BLOCK_SIZE;
-			u8 *src = walk.src.virt.addr + blocks * AES_BLOCK_SIZE;
-
-			crypto_xor_cpy(dst, src, final,
-				       walk.total % AES_BLOCK_SIZE);
-
-			err = skcipher_walk_done(&walk, 0);
-			break;
+		if (blocks >= 8) {
+			aesbs_ctr_encrypt(dst, src, ctx->key.rk, ctx->key.rounds,
+					  blocks, walk.iv);
+			dst += blocks * AES_BLOCK_SIZE;
+			src += blocks * AES_BLOCK_SIZE;
 		}
-		err = skcipher_walk_done(&walk,
-					 walk.nbytes - blocks * AES_BLOCK_SIZE);
+		if (nbytes && walk.nbytes == walk.total) {
+			neon_aes_ctr_encrypt(dst, src, ctx->enc, ctx->key.rounds,
+					     nbytes, walk.iv);
+			nbytes = 0;
+		}
+		kernel_neon_end();
+		err = skcipher_walk_done(&walk, nbytes);
 	}
 	return err;
 }
@@ -402,14 +396,14 @@ static struct skcipher_alg aes_algs[] = { {
 	.base.cra_driver_name	= "cbc-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= AES_BLOCK_SIZE,
-	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctx),
+	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctr_ctx),
 	.base.cra_module	= THIS_MODULE,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
 	.max_keysize		= AES_MAX_KEY_SIZE,
 	.walksize		= 8 * AES_BLOCK_SIZE,
 	.ivsize			= AES_BLOCK_SIZE,
-	.setkey			= aesbs_cbc_setkey,
+	.setkey			= aesbs_cbc_ctr_setkey,
 	.encrypt		= cbc_encrypt,
 	.decrypt		= cbc_decrypt,
 }, {
@@ -417,7 +411,7 @@ static struct skcipher_alg aes_algs[] = { {
 	.base.cra_driver_name	= "ctr-aes-neonbs",
 	.base.cra_priority	= 250,
 	.base.cra_blocksize	= 1,
-	.base.cra_ctxsize	= sizeof(struct aesbs_ctx),
+	.base.cra_ctxsize	= sizeof(struct aesbs_cbc_ctr_ctx),
 	.base.cra_module	= THIS_MODULE,
 
 	.min_keysize		= AES_MIN_KEY_SIZE,
@@ -425,7 +419,7 @@ static struct skcipher_alg aes_algs[] = { {
 	.chunksize		= AES_BLOCK_SIZE,
 	.walksize		= 8 * AES_BLOCK_SIZE,
 	.ivsize			= AES_BLOCK_SIZE,
-	.setkey			= aesbs_setkey,
+	.setkey			= aesbs_cbc_ctr_setkey,
 	.encrypt		= ctr_encrypt,
 	.decrypt		= ctr_encrypt,
 }, {
-- 
2.30.2



From hayashi.kunihiko at socionext.com  Thu Jan 27 03:35:42 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 27 Jan 2022 20:35:42 +0900
Subject: [PATCH 1/3] pinctrl: uniphier: Add missing audio pinmux settings for
 PXs2 SoC
In-Reply-To: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643283344-24911-2-git-send-email-hayashi.kunihiko@socionext.com>

Add missing audio I/O pinmux settings for PXs2 SoC.
This adds ain1 4ch pins, ain3 and aout1.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index e52e65a24048..6ef892543cb9 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -719,12 +719,16 @@ static const struct pinctrl_pin_desc uniphier_pxs2_pins[] = {
 			     234, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {161, 162, 173, 174};
-static const int ain1_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain1_pins[] = {161, 162, 173, 174, 127, 128, 129};
+static const int ain1_muxvals[] = {8, 8, 8, 8, 3, 3, 3};
 static const unsigned ain2_pins[] = {98, 99, 100, 101, 102, 103, 104};
 static const int ain2_muxvals[] = {8, 8, 8, 8, 8, 8, 8};
+static const unsigned ain3_pins[] = {132, 133, 134, 131};
+static const int ain3_muxvals[] = {5, 5, 5, 5};
 static const unsigned ainiec1_pins[] = {91};
 static const int ainiec1_muxvals[] = {11};
+static const unsigned aout1_pins[] = {87, 88, 89, 90, 92, 93, 94};
+static const int aout1_muxvals[] = {11, 11, 11, 11, 11, 11, 11};
 static const unsigned aout2_pins[] = {175, 176, 177, 178, 183, 184, 185};
 static const int aout2_muxvals[] = {8, 8, 8, 8, 9, 9, 9};
 static const unsigned aout3_pins[] = {105, 106, 107, 108};
@@ -839,7 +843,9 @@ static const unsigned int gpio_range1_pins[] = {
 static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
+	UNIPHIER_PINCTRL_GROUP(aout1),
 	UNIPHIER_PINCTRL_GROUP(aout2),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -880,7 +886,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 
 static const char * const ain1_groups[] = {"ain1"};
 static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain3_groups[] = {"ain3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
+static const char * const aout1_groups[] = {"aout1"};
 static const char * const aout2_groups[] = {"aout2"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
-- 
2.7.4



From hayashi.kunihiko at socionext.com  Thu Jan 27 03:35:43 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 27 Jan 2022 20:35:43 +0900
Subject: [PATCH 2/3] pinctrl: uniphier: Divide pinmux group to support 1ch and
 2ch I2S
In-Reply-To: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>

Current pinmux group for audio in/out assumes 4ch I2S case but the
UniPhier AIO hardware also supports 1ch and 2ch I2S. So divide current
ain1 group into ain1, ain1_dat2 and ain1_dat4 groups. Divide other
ain and aout in the same way.

Signed-off-by: Ryuta NAKANISHI <nakanishi.ryuta at socionext.com>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c | 26 +++++++---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c | 64 ++++++++++++++++++------
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 55 +++++++++++++++-----
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 52 ++++++++++++++-----
 4 files changed, 153 insertions(+), 44 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
index a4fa8e3af607..65ed20bc1fa2 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
@@ -461,10 +461,18 @@ static const struct pinctrl_pin_desc uniphier_ld11_pins[] = {
 			     166, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {151, 152, 153, 154, 155, 156, 157};
-static const int ain1_muxvals[] = {4, 4, 4, 4, 4, 4, 4};
-static const unsigned aout1_pins[] = {137, 138, 139, 140, 141, 142};
-static const int aout1_muxvals[] = {0, 0, 0, 0, 0, 0};
+static const unsigned ain1_pins[] = {151, 152, 153, 154};
+static const int ain1_muxvals[] = {4, 4, 4, 4};
+static const unsigned ain1_dat2_pins[] = {155};
+static const int ain1_dat2_muxvals[] = {4};
+static const unsigned ain1_dat4_pins[] = {156, 157};
+static const int ain1_dat4_muxvals[] = {4, 4};
+static const unsigned aout1_pins[] = {137, 138, 139, 140};
+static const int aout1_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout1_dat2_pins[] = {141};
+static const int aout1_dat2_muxvals[] = {0};
+static const unsigned aout1_dat4_pins[] = {142, 143};
+static const int aout1_dat4_muxvals[] = {0, 3};
 static const unsigned ainiec1_pins[] = {150};
 static const int ainiec1_muxvals[] = {4};
 static const unsigned ainiec1b_pins[] = {141};
@@ -582,7 +590,11 @@ static const unsigned int gpio_range5_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(ainiec1b),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -626,8 +638,10 @@ static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range5),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const aout1_groups[] = {"aout1"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
 static const char * const ainiec1_groups[] = {"ainiec1", "ainiec1b"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
 static const char * const aoutiec2_groups[] = {"aoutiec2"};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
index 850736998206..a68b21fbd0c7 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
@@ -542,18 +542,38 @@ static const struct pinctrl_pin_desc uniphier_ld20_pins[] = {
 			     175, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {150, 151, 152, 153, 154, 155, 156};
-static const int ain1_muxvals[] = {4, 4, 4, 4, 4, 4, 4};
-static const unsigned ain2_pins[] = {116, 117, 118, 119, 120, 121, 122};
-static const int ain2_muxvals[] = {26, 26, 26, 26, 26, 26, 26};
+static const unsigned ain1_pins[] = {150, 151, 152, 153};
+static const int ain1_muxvals[] = {4, 4, 4, 4};
+static const unsigned ain1_dat2_pins[] = {154};
+static const int ain1_dat2_muxvals[] = {4};
+static const unsigned ain1_dat4_pins[] = {155, 156};
+static const int ain1_dat4_muxvals[] = {4, 4};
+static const unsigned ain2_pins[] = {116, 117, 118, 119};
+static const int ain2_muxvals[] = {26, 26, 26, 26};
+static const unsigned ain2_dat2_pins[] = {120};
+static const int ain2_dat2_muxvals[] = {26};
+static const unsigned ain2_dat4_pins[] = {121, 122};
+static const int ain2_dat4_muxvals[] = {26, 26};
 static const unsigned ain3_pins[] = {116, 117, 118, 119};
 static const int ain3_muxvals[] = {27, 27, 27, 27};
-static const unsigned aout1_pins[] = {137, 138, 139, 140, 141, 142};
-static const int aout1_muxvals[] = {0, 0, 0, 0, 0, 0};
-static const unsigned aout1b_pins[] = {150, 151, 152, 153, 154, 155, 156};
-static const int aout1b_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout2_pins[] = {165, 157, 162, 158, 159, 160, 161};
-static const int aout2_muxvals[] = {2, 2, 2, 1, 1, 1, 1};
+static const unsigned aout1_pins[] = {137, 138, 139, 140};
+static const int aout1_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout1_dat2_pins[] = {141};
+static const int aout1_dat2_muxvals[] = {0};
+static const unsigned aout1_dat4_pins[] = {142, 156};
+static const int aout1_dat4_muxvals[] = {0, 1};
+static const unsigned aout1b_pins[] = {150, 151, 152, 153};
+static const int aout1b_muxvals[] = {1, 1, 1, 1};
+static const unsigned aout1b_dat2_pins[] = {154};
+static const int aout1b_dat2_muxvals[] = {1};
+static const unsigned aout1b_dat4_pins[] = {155, 156};
+static const int aout1b_dat4_muxvals[] = {1, 1};
+static const unsigned aout2_pins[] = {165, 157, 162, 158};
+static const int aout2_muxvals[] = {2, 2, 2, 1};
+static const unsigned aout2_dat2_pins[] = {159};
+static const int aout2_dat2_muxvals[] = {1};
+static const unsigned aout2_dat4_pins[] = {160, 161};
+static const int aout2_dat4_muxvals[] = {1, 1};
 static const unsigned aout3_pins[] = {166, 167, 168, 163};
 static const int aout3_muxvals[] = {2, 2, 2, 1};
 static const unsigned aout4_pins[] = {169, 170, 171, 164};
@@ -682,11 +702,21 @@ static const unsigned int gpio_range2_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1b),
+	UNIPHIER_PINCTRL_GROUP(aout1b_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1b_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aout4),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -734,11 +764,17 @@ static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range2),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain2_dat4"};
 static const char * const ain3_groups[] = {"ain3"};
-static const char * const aout1_groups[] = {"aout1", "aout1b"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4",
+					    "aout1b", "aout1b_dat2",
+					    "aout1b_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aout4_groups[] = {"aout4"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index 6ef892543cb9..efeca8fd7c9f 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -719,18 +719,34 @@ static const struct pinctrl_pin_desc uniphier_pxs2_pins[] = {
 			     234, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {161, 162, 173, 174, 127, 128, 129};
-static const int ain1_muxvals[] = {8, 8, 8, 8, 3, 3, 3};
-static const unsigned ain2_pins[] = {98, 99, 100, 101, 102, 103, 104};
-static const int ain2_muxvals[] = {8, 8, 8, 8, 8, 8, 8};
+static const unsigned ain1_pins[] = {161, 162, 173, 174};
+static const int ain1_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain1_dat2_pins[] = {127};
+static const int ain1_dat2_muxvals[] = {3};
+static const unsigned ain1_dat4_pins[] = {128, 129};
+static const int ain1_dat4_muxvals[] = {3, 3};
+static const unsigned ain2_pins[] = {98, 99, 100, 101};
+static const int ain2_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain2_dat2_pins[] = {102};
+static const int ain2_dat2_muxvals[] = {8};
+static const unsigned ain2_dat4_pins[] = {103, 104};
+static const int ain2_dat4_muxvals[] = {8, 8};
 static const unsigned ain3_pins[] = {132, 133, 134, 131};
 static const int ain3_muxvals[] = {5, 5, 5, 5};
 static const unsigned ainiec1_pins[] = {91};
 static const int ainiec1_muxvals[] = {11};
-static const unsigned aout1_pins[] = {87, 88, 89, 90, 92, 93, 94};
-static const int aout1_muxvals[] = {11, 11, 11, 11, 11, 11, 11};
-static const unsigned aout2_pins[] = {175, 176, 177, 178, 183, 184, 185};
-static const int aout2_muxvals[] = {8, 8, 8, 8, 9, 9, 9};
+static const unsigned aout1_pins[] = {87, 88, 89, 90};
+static const int aout1_muxvals[] = {11, 11, 11, 11};
+static const unsigned aout1_dat2_pins[] = {92};
+static const int aout1_dat2_muxvals[] = {11};
+static const unsigned aout1_dat4_pins[] = {93, 94};
+static const int aout1_dat4_muxvals[] = {11, 11};
+static const unsigned aout2_pins[] = {177, 178, 175, 176};
+static const int aout2_muxvals[] = {8, 8, 8, 8};
+static const unsigned aout2_dat2_pins[] = {183};
+static const int aout2_dat2_muxvals[] = {9};
+static const unsigned aout2_dat4_pins[] = {184, 185};
+static const int aout2_dat4_muxvals[] = {9, 9};
 static const unsigned aout3_pins[] = {105, 106, 107, 108};
 static const int aout3_muxvals[] = {8, 8, 8, 8};
 static const unsigned aoutiec1_pins[] = {95};
@@ -842,11 +858,19 @@ static const unsigned int gpio_range1_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
 	UNIPHIER_PINCTRL_GROUP(aoutiec2),
@@ -884,12 +908,16 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range1),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain2_dat4"};
 static const char * const ain3_groups[] = {"ain3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
-static const char * const aout1_groups[] = {"aout1"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
 static const char * const aoutiec2_groups[] = {"aoutiec2"};
@@ -922,9 +950,12 @@ static const char * const usb3_groups[] = {"usb3"};
 static const struct uniphier_pinmux_function uniphier_pxs2_functions[] = {
 	UNIPHIER_PINMUX_FUNCTION(ain1),
 	UNIPHIER_PINMUX_FUNCTION(ain2),
+	UNIPHIER_PINMUX_FUNCTION(ain3),
 	UNIPHIER_PINMUX_FUNCTION(ainiec1),
+	UNIPHIER_PINMUX_FUNCTION(aout1),
 	UNIPHIER_PINMUX_FUNCTION(aout2),
 	UNIPHIER_PINMUX_FUNCTION(aout3),
+	UNIPHIER_PINMUX_FUNCTION(aout4),
 	UNIPHIER_PINMUX_FUNCTION(aoutiec1),
 	UNIPHIER_PINMUX_FUNCTION(aoutiec2),
 	UNIPHIER_PINMUX_FUNCTION(emmc),
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
index 4810db6c0ee8..eb3c9b55f6e3 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
@@ -767,14 +767,30 @@ static const struct pinctrl_pin_desc uniphier_pxs3_pins[] = {
 			     250, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {186, 187, 188, 189, 237, 238, 239};
-static const int ain1_muxvals[] = {0, 0, 0, 0, 1, 1, 1};
-static const unsigned ain2_pins[] = {243, 244, 245, 246, 247, 248, 249};
-static const int ain2_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout1_pins[] = {226, 227, 228, 229, 230, 231, 232};
-static const int aout1_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout2_pins[] = {192, 193, 194, 195, 196, 197, 198};
-static const int aout2_muxvals[] = {0, 0, 0, 0, 0, 0, 0};
+static const unsigned ain1_pins[] = {186, 187, 188, 189};
+static const int ain1_muxvals[] = {0, 0, 0, 0};
+static const unsigned ain1_dat2_pins[] = {237};
+static const int ain1_dat2_muxvals[] = {1};
+static const unsigned ain1_dat4_pins[] = {238, 239};
+static const int ain1_dat4_muxvals[] = {1, 1};
+static const unsigned ain2_pins[] = {243, 244, 245, 246};
+static const int ain2_muxvals[] = {1, 1, 1, 1};
+static const unsigned ain2_dat2_pins[] = {247};
+static const int ain2_dat2_muxvals[] = {1};
+static const unsigned ain2_dat4_pins[] = {248, 249};
+static const int ain2_dat4_muxvals[] = {1, 1};
+static const unsigned aout1_pins[] = {226, 227, 228, 229};
+static const int aout1_muxvals[] = {1, 1, 1, 1};
+static const unsigned aout1_dat2_pins[] = {230};
+static const int aout1_dat2_muxvals[] = {1};
+static const unsigned aout1_dat4_pins[] = {231, 232};
+static const int aout1_dat4_muxvals[] = {1, 1};
+static const unsigned aout2_pins[] = {192, 193, 194, 195};
+static const int aout2_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout2_dat2_pins[] = {196};
+static const int aout2_dat2_muxvals[] = {0};
+static const unsigned aout2_dat4_pins[] = {197, 198};
+static const int aout2_dat4_muxvals[] = {0, 0};
 static const unsigned aout3_pins[] = {199, 200, 201, 202};
 static const int aout3_muxvals[] = {0, 0, 0, 0};
 static const unsigned ainiec1_pins[] = {240};
@@ -888,9 +904,17 @@ static const unsigned int gpio_range2_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -926,10 +950,14 @@ static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range2),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
-static const char * const aout1_groups[] = {"aout1"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain1_dat4"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
-- 
2.7.4



From hayashi.kunihiko at socionext.com  Thu Jan 27 03:35:41 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 27 Jan 2022 20:35:41 +0900
Subject: [PATCH 0/3] pinctrl: uniphier: Add some more pinmux settings
Message-ID: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>

This series includes changes to audio I/O pinmux settings and addition
to USB device pinmux settings.

- Divide audio I/O pinmux groups so that 1/2/4ch can be specified.
  The audio I/O function is available for LD11, LD20, PXs2 and PXs3 SoCs.
  In addition, add the missing pinmux settings for PXs2.

- Add USB device pinmux settings. The USB device function is available
  for PXs2 and PXs3 SoCs.

Kunihiko Hayashi (3):
  pinctrl: uniphier: Add missing audio pinmux settings for PXs2 SoC
  pinctrl: uniphier: Divide pinmux group to support 1ch and 2ch I2S
  pinctrl: uniphier: Add USB device pinmux settings

 drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c | 26 +++++++---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c | 64 ++++++++++++++++++------
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 63 +++++++++++++++++++----
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 62 +++++++++++++++++------
 4 files changed, 172 insertions(+), 43 deletions(-)

-- 
2.7.4



From hayashi.kunihiko at socionext.com  Thu Jan 27 03:35:44 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Thu, 27 Jan 2022 20:35:44 +0900
Subject: [PATCH 3/3] pinctrl: uniphier: Add USB device pinmux settings
In-Reply-To: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643283344-24911-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643283344-24911-4-git-send-email-hayashi.kunihiko@socionext.com>

Add USB device pinmux settings for PXs2 and PXs3 SoCs. Only pins for
ports 0 and 1 support USB device mode.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 10 ++++++++--
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index efeca8fd7c9f..80ea30f5952d 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -817,8 +817,12 @@ static const unsigned uart3b_pins[] = {181, 182};
 static const int uart3b_muxvals[] = {10, 10};
 static const unsigned usb0_pins[] = {56, 57};
 static const int usb0_muxvals[] = {8, 8};
+static const unsigned usb0_device_pins[] = {213};
+static const int usb0_device_muxvals[] = {9};
 static const unsigned usb1_pins[] = {58, 59};
 static const int usb1_muxvals[] = {8, 8};
+static const unsigned usb1_device_pins[] = {214};
+static const int usb1_device_muxvals[] = {9};
 static const unsigned usb2_pins[] = {60, 61};
 static const int usb2_muxvals[] = {8, 8};
 static const unsigned usb3_pins[] = {62, 63};
@@ -901,7 +905,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(uart3),
 	UNIPHIER_PINCTRL_GROUP(uart3b),
 	UNIPHIER_PINCTRL_GROUP(usb0),
+	UNIPHIER_PINCTRL_GROUP(usb0_device),
 	UNIPHIER_PINCTRL_GROUP(usb1),
+	UNIPHIER_PINCTRL_GROUP(usb1_device),
 	UNIPHIER_PINCTRL_GROUP(usb2),
 	UNIPHIER_PINCTRL_GROUP(usb3),
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range0),
@@ -942,8 +948,8 @@ static const char * const uart0_groups[] = {"uart0", "uart0b",
 static const char * const uart1_groups[] = {"uart1"};
 static const char * const uart2_groups[] = {"uart2"};
 static const char * const uart3_groups[] = {"uart3", "uart3b"};
-static const char * const usb0_groups[] = {"usb0"};
-static const char * const usb1_groups[] = {"usb1"};
+static const char * const usb0_groups[] = {"usb0", "usb0_device"};
+static const char * const usb1_groups[] = {"usb1", "usb1_device"};
 static const char * const usb2_groups[] = {"usb2"};
 static const char * const usb3_groups[] = {"usb3"};
 
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
index eb3c9b55f6e3..ab3bd2d9c6c7 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
@@ -855,8 +855,12 @@ static const unsigned int uart3_pins[] = {98, 99};
 static const int uart3_muxvals[] = {0, 0};
 static const unsigned int usb0_pins[] = {84, 85};
 static const int usb0_muxvals[] = {0, 0};
+static const unsigned int usb0_device_pins[] = {110};
+static const int usb0_device_muxvals[] = {2};
 static const unsigned int usb1_pins[] = {86, 87};
 static const int usb1_muxvals[] = {0, 0};
+static const unsigned int usb1_device_pins[] = {111};
+static const int usb1_device_muxvals[] = {2};
 static const unsigned int usb2_pins[] = {88, 89};
 static const int usb2_muxvals[] = {0, 0};
 static const unsigned int usb3_pins[] = {90, 91};
@@ -942,7 +946,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(uart2),
 	UNIPHIER_PINCTRL_GROUP(uart3),
 	UNIPHIER_PINCTRL_GROUP(usb0),
+	UNIPHIER_PINCTRL_GROUP(usb0_device),
 	UNIPHIER_PINCTRL_GROUP(usb1),
+	UNIPHIER_PINCTRL_GROUP(usb1_device),
 	UNIPHIER_PINCTRL_GROUP(usb2),
 	UNIPHIER_PINCTRL_GROUP(usb3),
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range0),
@@ -982,8 +988,8 @@ static const char * const uart0_groups[] = {"uart0", "uart0_ctsrts",
 static const char * const uart1_groups[] = {"uart1"};
 static const char * const uart2_groups[] = {"uart2"};
 static const char * const uart3_groups[] = {"uart3"};
-static const char * const usb0_groups[] = {"usb0"};
-static const char * const usb1_groups[] = {"usb1"};
+static const char * const usb0_groups[] = {"usb0", "usb0_device"};
+static const char * const usb1_groups[] = {"usb1", "usb1_device"};
 static const char * const usb2_groups[] = {"usb2"};
 static const char * const usb3_groups[] = {"usb3"};
 
-- 
2.7.4



From ardb at kernel.org  Thu Jan 27 03:35:45 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 12:35:45 +0100
Subject: [PATCH 3/3] crypto: arm64/aes-neonbs-xts - use plain NEON for
 non-power-of-2 input sizes
In-Reply-To: <20220127113545.7821-1-ardb@kernel.org>
References: <20220127113545.7821-1-ardb@kernel.org>
Message-ID: <20220127113545.7821-4-ardb@kernel.org>

Even though the kernel's implementations of AES-XTS were updated to
implement ciphertext stealing and can operate on inputs of any size
larger than or equal to the AES block size, this feature is rarely used
in practice.

In fact, in the kernel, AES-XTS is only used to operate on 4096 or 512
byte blocks, which means that not only the ciphertext stealing is
effectively dead code, the logic in the bit sliced NEON implementation
to deal with fewer than 8 blocks at a time is also never used.

Since the bit-sliced NEON driver already depends on the plain NEON
version, which is slower but can operate on smaller data quantities more
straightforwardly, let's fallback to the plain NEON implementation of
XTS for any residual inputs that are not multiples of 128 bytes. This
allows us to remove a lot of complicated logic that rarely gets
exercised in practice.

Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
 arch/arm64/crypto/aes-neonbs-core.S | 132 ++++++--------------
 arch/arm64/crypto/aes-neonbs-glue.c |  33 ++---
 2 files changed, 57 insertions(+), 108 deletions(-)

diff --git a/arch/arm64/crypto/aes-neonbs-core.S b/arch/arm64/crypto/aes-neonbs-core.S
index f2761481181d..d427f4556b6e 100644
--- a/arch/arm64/crypto/aes-neonbs-core.S
+++ b/arch/arm64/crypto/aes-neonbs-core.S
@@ -735,119 +735,67 @@ SYM_FUNC_END(aesbs_cbc_decrypt)
 	 *		     int blocks, u8 iv[])
 	 */
 SYM_FUNC_START_LOCAL(__xts_crypt8)
-	mov		x6, #1
-	lsl		x6, x6, x23
-	subs		w23, w23, #8
-	csel		x23, x23, xzr, pl
-	csel		x6, x6, xzr, mi
+	movi		v18.2s, #0x1
+	movi		v19.2s, #0x87
+	uzp1		v18.4s, v18.4s, v19.4s
+
+	ld1		{v0.16b-v3.16b}, [x1], #64
+	ld1		{v4.16b-v7.16b}, [x1], #64
+
+	next_tweak	v26, v25, v18, v19
+	next_tweak	v27, v26, v18, v19
+	next_tweak	v28, v27, v18, v19
+	next_tweak	v29, v28, v18, v19
+	next_tweak	v30, v29, v18, v19
+	next_tweak	v31, v30, v18, v19
+	next_tweak	v16, v31, v18, v19
+	next_tweak	v17, v16, v18, v19
 
-	ld1		{v0.16b}, [x20], #16
-	next_tweak	v26, v25, v30, v31
 	eor		v0.16b, v0.16b, v25.16b
-	tbnz		x6, #1, 0f
-
-	ld1		{v1.16b}, [x20], #16
-	next_tweak	v27, v26, v30, v31
 	eor		v1.16b, v1.16b, v26.16b
-	tbnz		x6, #2, 0f
-
-	ld1		{v2.16b}, [x20], #16
-	next_tweak	v28, v27, v30, v31
 	eor		v2.16b, v2.16b, v27.16b
-	tbnz		x6, #3, 0f
-
-	ld1		{v3.16b}, [x20], #16
-	next_tweak	v29, v28, v30, v31
 	eor		v3.16b, v3.16b, v28.16b
-	tbnz		x6, #4, 0f
-
-	ld1		{v4.16b}, [x20], #16
-	str		q29, [sp, #.Lframe_local_offset]
 	eor		v4.16b, v4.16b, v29.16b
-	next_tweak	v29, v29, v30, v31
-	tbnz		x6, #5, 0f
-
-	ld1		{v5.16b}, [x20], #16
-	str		q29, [sp, #.Lframe_local_offset + 16]
-	eor		v5.16b, v5.16b, v29.16b
-	next_tweak	v29, v29, v30, v31
-	tbnz		x6, #6, 0f
+	eor		v5.16b, v5.16b, v30.16b
+	eor		v6.16b, v6.16b, v31.16b
+	eor		v7.16b, v7.16b, v16.16b
 
-	ld1		{v6.16b}, [x20], #16
-	str		q29, [sp, #.Lframe_local_offset + 32]
-	eor		v6.16b, v6.16b, v29.16b
-	next_tweak	v29, v29, v30, v31
-	tbnz		x6, #7, 0f
+	stp		q16, q17, [sp, #16]
 
-	ld1		{v7.16b}, [x20], #16
-	str		q29, [sp, #.Lframe_local_offset + 48]
-	eor		v7.16b, v7.16b, v29.16b
-	next_tweak	v29, v29, v30, v31
-
-0:	mov		bskey, x21
-	mov		rounds, x22
+	mov		bskey, x2
+	mov		rounds, x3
 	br		x16
 SYM_FUNC_END(__xts_crypt8)
 
 	.macro		__xts_crypt, do8, o0, o1, o2, o3, o4, o5, o6, o7
-	frame_push	6, 64
-
-	mov		x19, x0
-	mov		x20, x1
-	mov		x21, x2
-	mov		x22, x3
-	mov		x23, x4
-	mov		x24, x5
+	stp		x29, x30, [sp, #-48]!
+	mov		x29, sp
 
-	movi		v30.2s, #0x1
-	movi		v25.2s, #0x87
-	uzp1		v30.4s, v30.4s, v25.4s
-	ld1		{v25.16b}, [x24]
+	ld1		{v25.16b}, [x5]
 
-99:	adr		x16, \do8
+0:	adr		x16, \do8
 	bl		__xts_crypt8
 
-	ldp		q16, q17, [sp, #.Lframe_local_offset]
-	ldp		q18, q19, [sp, #.Lframe_local_offset + 32]
+	eor		v16.16b, \o0\().16b, v25.16b
+	eor		v17.16b, \o1\().16b, v26.16b
+	eor		v18.16b, \o2\().16b, v27.16b
+	eor		v19.16b, \o3\().16b, v28.16b
 
-	eor		\o0\().16b, \o0\().16b, v25.16b
-	eor		\o1\().16b, \o1\().16b, v26.16b
-	eor		\o2\().16b, \o2\().16b, v27.16b
-	eor		\o3\().16b, \o3\().16b, v28.16b
+	ldp		q24, q25, [sp, #16]
 
-	st1		{\o0\().16b}, [x19], #16
-	mov		v25.16b, v26.16b
-	tbnz		x6, #1, 1f
-	st1		{\o1\().16b}, [x19], #16
-	mov		v25.16b, v27.16b
-	tbnz		x6, #2, 1f
-	st1		{\o2\().16b}, [x19], #16
-	mov		v25.16b, v28.16b
-	tbnz		x6, #3, 1f
-	st1		{\o3\().16b}, [x19], #16
-	mov		v25.16b, v29.16b
-	tbnz		x6, #4, 1f
-
-	eor		\o4\().16b, \o4\().16b, v16.16b
-	eor		\o5\().16b, \o5\().16b, v17.16b
-	eor		\o6\().16b, \o6\().16b, v18.16b
-	eor		\o7\().16b, \o7\().16b, v19.16b
-
-	st1		{\o4\().16b}, [x19], #16
-	tbnz		x6, #5, 1f
-	st1		{\o5\().16b}, [x19], #16
-	tbnz		x6, #6, 1f
-	st1		{\o6\().16b}, [x19], #16
-	tbnz		x6, #7, 1f
-	st1		{\o7\().16b}, [x19], #16
+	eor		v20.16b, \o4\().16b, v29.16b
+	eor		v21.16b, \o5\().16b, v30.16b
+	eor		v22.16b, \o6\().16b, v31.16b
+	eor		v23.16b, \o7\().16b, v24.16b
 
-	cbz		x23, 1f
-	st1		{v25.16b}, [x24]
+	st1		{v16.16b-v19.16b}, [x0], #64
+	st1		{v20.16b-v23.16b}, [x0], #64
 
-	b		99b
+	subs		x4, x4, #8
+	b.gt		0b
 
-1:	st1		{v25.16b}, [x24]
-	frame_pop
+	st1		{v25.16b}, [x5]
+	ldp		x29, x30, [sp], #48
 	ret
 	.endm
 
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c
index 3189003e1cbe..bac4cabef607 100644
--- a/arch/arm64/crypto/aes-neonbs-glue.c
+++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -302,23 +302,18 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
 		return err;
 
 	while (walk.nbytes >= AES_BLOCK_SIZE) {
-		unsigned int blocks = walk.nbytes / AES_BLOCK_SIZE;
-
-		if (walk.nbytes < walk.total || walk.nbytes % AES_BLOCK_SIZE)
-			blocks = round_down(blocks,
-					    walk.stride / AES_BLOCK_SIZE);
-
+		int blocks = (walk.nbytes / AES_BLOCK_SIZE) & ~7;
 		out = walk.dst.virt.addr;
 		in = walk.src.virt.addr;
 		nbytes = walk.nbytes;
 
 		kernel_neon_begin();
-		if (likely(blocks > 6)) { /* plain NEON is faster otherwise */
-			if (first)
+		if (blocks >= 8) {
+			if (first == 1)
 				neon_aes_ecb_encrypt(walk.iv, walk.iv,
 						     ctx->twkey,
 						     ctx->key.rounds, 1);
-			first = 0;
+			first = 2;
 
 			fn(out, in, ctx->key.rk, ctx->key.rounds, blocks,
 			   walk.iv);
@@ -327,10 +322,17 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
 			in += blocks * AES_BLOCK_SIZE;
 			nbytes -= blocks * AES_BLOCK_SIZE;
 		}
-
-		if (walk.nbytes == walk.total && nbytes > 0)
-			goto xts_tail;
-
+		if (walk.nbytes == walk.total && nbytes > 0) {
+			if (encrypt)
+				neon_aes_xts_encrypt(out, in, ctx->cts.key_enc,
+						     ctx->key.rounds, nbytes,
+						     ctx->twkey, walk.iv, first);
+			else
+				neon_aes_xts_decrypt(out, in, ctx->cts.key_dec,
+						     ctx->key.rounds, nbytes,
+						     ctx->twkey, walk.iv, first);
+			nbytes = first = 0;
+		}
 		kernel_neon_end();
 		err = skcipher_walk_done(&walk, nbytes);
 	}
@@ -355,13 +357,12 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,
 	nbytes = walk.nbytes;
 
 	kernel_neon_begin();
-xts_tail:
 	if (encrypt)
 		neon_aes_xts_encrypt(out, in, ctx->cts.key_enc, ctx->key.rounds,
-				     nbytes, ctx->twkey, walk.iv, first ?: 2);
+				     nbytes, ctx->twkey, walk.iv, first);
 	else
 		neon_aes_xts_decrypt(out, in, ctx->cts.key_dec, ctx->key.rounds,
-				     nbytes, ctx->twkey, walk.iv, first ?: 2);
+				     nbytes, ctx->twkey, walk.iv, first);
 	kernel_neon_end();
 
 	return skcipher_walk_done(&walk, 0);
-- 
2.30.2



From xinlei.lee at mediatek.com  Thu Jan 27 03:42:50 2022
From: xinlei.lee at mediatek.com (xinlei.lee at mediatek.com)
Date: Thu, 27 Jan 2022 19:42:50 +0800
Subject: [v1, 0/3] Add mt8186 dsi compatoble & Move the getting bridge node
 function
Message-ID: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>

From: xinlei lee <xinlei.lee at mediatek.com>

The modification is based on avoiding screen shift:
https://patchwork.kernel.org/project/linux-mediatek/cover/20220114092110.12137-1-rex-bc.chen at mediatek.com/

xinlei lee (3):
  dt-bindings: display: mediatek: dsi: add documentation for MT8186 SoC
  drm/mediatek: Add mt8186 dsi compatible to mtk_dsi.c
  drm/mediatek: Move the getting bridge node function to mtk_dsi_bind

 .../bindings/display/mediatek/mediatek,dsi.txt     |  2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c                 | 37 ++++++++++++++--------
 2 files changed, 24 insertions(+), 15 deletions(-)

-- 
2.6.4



From xinlei.lee at mediatek.com  Thu Jan 27 03:42:51 2022
From: xinlei.lee at mediatek.com (xinlei.lee at mediatek.com)
Date: Thu, 27 Jan 2022 19:42:51 +0800
Subject: [v1, 1/3] dt-bindings: display: mediatek: dsi: add documentation for
 MT8186 SoC
In-Reply-To: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <1643283773-7081-2-git-send-email-xinlei.lee@mediatek.com>

From: xinlei lee <xinlei.lee at mediatek.com>

Add binding documentation for the MT8186 SoC.

Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
---
 Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
index 36b0145..c82b8b2 100644
--- a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
+++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
@@ -7,7 +7,7 @@ channel output.
 
 Required properties:
 - compatible: "mediatek,<chip>-dsi"
-- the supported chips are mt2701, mt7623, mt8167, mt8173 and mt8183.
+- the supported chips are mt2701, mt7623, mt8167, mt8173, mt8183 and mt8186.
 - reg: Physical base address and length of the controller's registers
 - interrupts: The interrupt signal from the function block.
 - clocks: device clocks
-- 
2.6.4



From xinlei.lee at mediatek.com  Thu Jan 27 03:42:53 2022
From: xinlei.lee at mediatek.com (xinlei.lee at mediatek.com)
Date: Thu, 27 Jan 2022 19:42:53 +0800
Subject: [v1, 3/3] drm/mediatek: Move the getting bridge node function to
 mtk_dsi_bind
In-Reply-To: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <1643283773-7081-4-git-send-email-xinlei.lee@mediatek.com>

From: xinlei lee <xinlei.lee at mediatek.com>

The order of probe function for bridge drivers and dsi drivers is uncertain.
To avoid the dsi probe cannot be executed, we place getting bridge node function in
mtk_dsi_bind.

Signed-off-by:Xinlei Lee <xinlei.lee at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 62af60d..a390f26 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -991,6 +991,21 @@ static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
 	int ret;
 	struct drm_device *drm = data;
 	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+	struct drm_panel *panel;
+
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
+					  &panel, &dsi->next_bridge);
+	if (ret)
+		return ret;
+
+	if (panel) {
+		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
+		if (IS_ERR(dsi->next_bridge)) {
+			ret = PTR_ERR(dsi->next_bridge);
+			dev_err(dev, "failed to add bridge: %d\n", ret);
+			return ret;
+		}
+	}
 
 	ret = mtk_dsi_encoder_init(drm, dsi);
 	if (ret)
@@ -1016,7 +1031,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 {
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
-	struct drm_panel *panel;
 	struct resource *regs;
 	int irq_num;
 	int ret;
@@ -1033,19 +1047,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &panel, &dsi->next_bridge);
-	if (ret)
-		goto err_unregister_host;
-
-	if (panel) {
-		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
-		if (IS_ERR(dsi->next_bridge)) {
-			ret = PTR_ERR(dsi->next_bridge);
-			goto err_unregister_host;
-		}
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
-- 
2.6.4



From xinlei.lee at mediatek.com  Thu Jan 27 03:42:52 2022
From: xinlei.lee at mediatek.com (xinlei.lee at mediatek.com)
Date: Thu, 27 Jan 2022 19:42:52 +0800
Subject: [v1,2/3] drm/mediatek: Add mt8186 dsi compatible to mtk_dsi.c
In-Reply-To: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <1643283773-7081-3-git-send-email-xinlei.lee@mediatek.com>

From: xinlei lee <xinlei.lee at mediatek.com>

Add the compatible of mt8186-dsi because we use different cmdq addresses in mt8186.

Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index e91b3ff..62af60d 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1151,6 +1151,12 @@ static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = {
 	.has_size_ctl = true,
 };
 
+static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
+	.reg_cmdq_off = 0xd00,
+	.has_shadow_ctl = true,
+	.has_size_ctl = true,
+};
+
 static const struct of_device_id mtk_dsi_of_match[] = {
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = &mt2701_dsi_driver_data },
@@ -1158,6 +1164,8 @@ static const struct of_device_id mtk_dsi_of_match[] = {
 	  .data = &mt8173_dsi_driver_data },
 	{ .compatible = "mediatek,mt8183-dsi",
 	  .data = &mt8183_dsi_driver_data },
+	{ .compatible = "mediatek,mt8186-dsi",
+	  .data = &mt8186_dsi_driver_data },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);
-- 
2.6.4



From maz at kernel.org  Thu Jan 27 03:48:05 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 11:48:05 +0000
Subject: [PATCH v5 67/69] KVM: arm64: nv: Enable ARMv8.4-NV support
In-Reply-To: <7fe1ce9e-1b86-ed57-a0e5-117d1b9011b4@os.amperecomputing.com>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-68-maz@kernel.org>
 <7fe1ce9e-1b86-ed57-a0e5-117d1b9011b4@os.amperecomputing.com>
Message-ID: <8735l9762y.wl-maz@kernel.org>

On Tue, 18 Jan 2022 11:50:18 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> 
> 
> On 30-11-2021 01:31 am, Marc Zyngier wrote:
> > As all the VNCR-capable system registers are nicely separated
> > from the rest of the crowd, let's set HCR_EL2.NV2 on and let
> > the ball rolling.
> > 
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >   arch/arm64/include/asm/kvm_arm.h     |  1 +
> >   arch/arm64/include/asm/kvm_emulate.h | 23 +++++++++++++----------
> >   arch/arm64/include/asm/sysreg.h      |  1 +
> >   arch/arm64/kvm/hyp/vhe/switch.c      | 14 +++++++++++++-
> >   4 files changed, 28 insertions(+), 11 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
> > index b603466803d2..18c35446249f 100644
> > --- a/arch/arm64/include/asm/kvm_arm.h
> > +++ b/arch/arm64/include/asm/kvm_arm.h
> > @@ -20,6 +20,7 @@
> >   #define HCR_AMVOFFEN	(UL(1) << 51)
> >   #define HCR_FIEN	(UL(1) << 47)
> >   #define HCR_FWB		(UL(1) << 46)
> > +#define HCR_NV2		(UL(1) << 45)
> >   #define HCR_AT		(UL(1) << 44)
> >   #define HCR_NV1		(UL(1) << 43)
> >   #define HCR_NV		(UL(1) << 42)
> > diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> > index 1664430be698..f282997e4a4c 100644
> > --- a/arch/arm64/include/asm/kvm_emulate.h
> > +++ b/arch/arm64/include/asm/kvm_emulate.h
> > @@ -245,21 +245,24 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
> >     static inline u64 __fixup_spsr_el2_write(struct kvm_cpu_context
> > *ctxt, u64 val)
> >   {
> > -	if (!__vcpu_el2_e2h_is_set(ctxt)) {
> > -		/*
> > -		 * Clear the .M field when writing SPSR to the CPU, so that we
> > -		 * can detect when the CPU clobbered our SPSR copy during a
> > -		 * local exception.
> > -		 */
> > -		val &= ~0xc;
> > -	}
> > +	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
> > +
> > +	if (enhanced_nested_virt_in_use(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
> > +		return val;
> >   -	return val;
> > +	/*
> > +	 * Clear the .M field when writing SPSR to the CPU, so that we
> > +	 * can detect when the CPU clobbered our SPSR copy during a
> > +	 * local exception.
> > +	 */
> > +	return val &= ~0xc;
> >   }
> >     static inline u64 __fixup_spsr_el2_read(const struct
> > kvm_cpu_context *ctxt, u64 val)
> >   {
> > -	if (__vcpu_el2_e2h_is_set(ctxt))
> > +	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
> > +
> > +	if (enhanced_nested_virt_in_use(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
> >   		return val;
> >     	/*
> > diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
> > index 71e6a0410e7c..5de90138d0a4 100644
> > --- a/arch/arm64/include/asm/sysreg.h
> > +++ b/arch/arm64/include/asm/sysreg.h
> > @@ -550,6 +550,7 @@
> >   #define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
> >   #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
> >   #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
> > +#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
> >     #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
> >   #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
> > diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
> > index ef4488db6dc1..5cadda79089a 100644
> > --- a/arch/arm64/kvm/hyp/vhe/switch.c
> > +++ b/arch/arm64/kvm/hyp/vhe/switch.c
> > @@ -45,7 +45,13 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
> >   			 * the EL1 virtual memory control register accesses
> >   			 * as well as the AT S1 operations.
> >   			 */
> > -			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_TTLB | HCR_NV1;
> > +			if (enhanced_nested_virt_in_use(vcpu)) {
> > +				hcr &= ~HCR_TVM;
> 
> I think, we should clear TRVM also?
> 				hcr &= ~(HCR_TVM | HCR_TRVM);

Hmmm. But TRVM is never set the first place, is it? It is only here
that we augment the host HCR_EL2 with various trap configurations
depending on whether the host is NV2 capable or not, whether the
guest is VHE or not, and whether the guest as set of additional flags
of its own.

Given that, I don't think there is a need to clear this bit.

Thanks,
	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Thu Jan 27 03:50:30 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 11:50:30 +0000
Subject: [PATCH v5 38/69] KVM: arm64: nv: Support multiple nested Stage-2
 mmu structures
In-Reply-To: <21b0fca8-6b31-dc63-7637-2f80c4b3a272@os.amperecomputing.com>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-39-maz@kernel.org>
 <21b0fca8-6b31-dc63-7637-2f80c4b3a272@os.amperecomputing.com>
Message-ID: <871r0t75yx.wl-maz@kernel.org>

On Tue, 18 Jan 2022 11:24:04 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> 
> 
> On 30-11-2021 01:31 am, Marc Zyngier wrote:
> > +struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
> > +{
> > +	bool nested_stage2_enabled = hcr & HCR_VM;
> > +	int i;
> > +
> > +	/* Don't consider the CnP bit for the vttbr match */
> > +	vttbr = vttbr & ~VTTBR_CNP_BIT;
> > +
> > +	/*
> > +	 * Two possibilities when looking up a S2 MMU context:
> > +	 *
> > +	 * - either S2 is enabled in the guest, and we need a context that
> > +         *   is S2-enabled and matches the full VTTBR (VMID+BADDR), which
> > +         *   makes it safe from a TLB conflict perspective (a broken guest
> > +         *   won't be able to generate them),
> > +	 *
> > +	 * - or S2 is disabled, and we need a context that is S2-disabled
> > +         *   and matches the VMID only, as all TLBs are tagged by VMID even
> > +         *   if S2 translation is enabled.
> 
> I think you were intended to say "if S2 translation is disabled".

Yes, absolutely. Good catch.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From maz at kernel.org  Thu Jan 27 03:50:40 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 11:50:40 +0000
Subject: [PATCH v5 16/69] KVM: arm64: nv: Handle trapped ERET from virtual
 EL2
In-Reply-To: <Yebsq0wWHO5mWZjx@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-17-maz@kernel.org>
 <Yebsq0wWHO5mWZjx@monolith.localdoman>
Message-ID: <87zgnh5re7.wl-maz@kernel.org>

On Tue, 18 Jan 2022 16:36:59 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:57PM +0000, Marc Zyngier wrote:
> > From: Christoffer Dall <christoffer.dall at arm.com>
> > 
> > When a guest hypervisor running virtual EL2 in EL1 executes an ERET
> > instruction, we will have set HCR_EL2.NV which traps ERET to EL2, so
> > that we can emulate the exception return in software.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/esr.h     |  5 +++++
> >  arch/arm64/include/asm/kvm_arm.h |  2 +-
> >  arch/arm64/kvm/handle_exit.c     | 10 ++++++++++
> >  3 files changed, 16 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> > index d52a0b269ee8..6835e4231119 100644
> > --- a/arch/arm64/include/asm/esr.h
> > +++ b/arch/arm64/include/asm/esr.h
> > @@ -257,6 +257,11 @@
> >  		(((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >>		\
> >  		 ESR_ELx_SYS64_ISS_OP2_SHIFT))
> >  
> > +/* ISS field definitions for ERET/ERETAA/ERETAB trapping */
> > +
> > +#define ESR_ELx_ERET_ISS_ERET_ERETAx	0x2
> > +#define ESR_ELx_ERET_ISS_ERETA_ERATAB	0x1
>                             ^^^^^
> Shouldn't that be ERETAA?

Hmm, this is rather ambiguous indeed. I'm going to repaint it as:

#define ESR_ELx_ERET_ISS_ERET		0x2
#define ESR_ELx_ERET_ISS_ERETA		0x1

which matches the ARM ARM wording as of DDI0487G.b.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From angelogioacchino.delregno at collabora.com  Thu Jan 27 04:06:02 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 13:06:02 +0100
Subject: [PATCH] arm64: dts: mt8195: add display node for vdosys0
In-Reply-To: <20220126093340.18792-1-jason-jh.lin@mediatek.com>
References: <20220126093340.18792-1-jason-jh.lin@mediatek.com>
Message-ID: <3d5e8c74-958f-0d43-0579-ee07dff9ee58@collabora.com>

Il 26/01/22 10:33, jason-jh.lin ha scritto:
> Add display node for vdosys0.
> 
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> ---
> This patch depends on series [1]
> [1] Add Mediatek Soc DRM (vdosys0) support for mt8195
> - https://patchwork.kernel.org/project/linux-mediatek/list/?series=608548
> 
> This patch is based on [2][3][4]
> [2] arm64: dts: Add mediatek SoC mt8195 and evaluation board
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20220112114724.1953-4-tinghan.shen at mediatek.com/
> [3] arm64: dts: mt8195: add IOMMU and smi nodes
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20210615173233.26682-15-tinghan.shen at mediatek.com/
> [4] arm64: dts: mt8195: add gce node
> - https://patchwork.kernel.org/project/linux-mediatek/patch/20220126090109.32143-1-jason-jh.lin at mediatek.com/
> ---
>   arch/arm64/boot/dts/mediatek/mt8195.dtsi | 123 +++++++++++++++++++++++
>   1 file changed, 123 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> index d778ca598d18..cc3a9e898c77 100644
> --- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> +++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
> @@ -1067,5 +1067,128 @@
>   			reg = <0 0x1b000000 0 0x1000>;
>   			#clock-cells = <1>;
>   		};
> +
> +		ovl0: disp_ovl at 1c000000 {

Please be consistent with the other SoC DTs: call this ovl at 1c000000

> +			compatible = "mediatek,mt8195-disp-ovl",
> +				     "mediatek,mt8192-disp-ovl";
> +			reg = <0 0x1c000000 0 0x1000>;
> +			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_OVL0>;
> +			iommus = <&iommu_vdo M4U_PORT_L0_DISP_OVL0_RDMA0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x0000 0x1000>;
> +		};
> +
> +		rdma0: disp_rdma at 1c002000 {

...this is just rdma

> +			compatible = "mediatek,mt8195-disp-rdma";
> +			reg = <0 0x1c002000 0 0x1000>;
> +			interrupts = <GIC_SPI 638 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_RDMA0>;
> +			iommus = <&iommu_vdo M4U_PORT_L0_DISP_RDMA0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x2000 0x1000>;
> +		};
> +
> +		color0: disp_color at 1c003000 {

color at ...

> +			compatible = "mediatek,mt8195-disp-color",
> +				     "mediatek,mt8173-disp-color";
> +			reg = <0 0x1c003000 0 0x1000>;
> +			interrupts = <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_COLOR0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x3000 0x1000>;
> +		};
> +
> +		ccorr0: disp_ccorr at 1c004000 {

ccorr at ...

> +			compatible = "mediatek,mt8195-disp-ccorr",
> +				     "mediatek,mt8192-disp-ccorr";
> +			reg = <0 0x1c004000 0 0x1000>;
> +			interrupts = <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_CCORR0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x4000 0x1000>;
> +		};
> +
> +		aal0: disp_aal at 1c005000 {

aal at ...

> +			compatible = "mediatek,mt8195-disp-aal",
> +				     "mediatek,mt8173-disp-aal";
> +			reg = <0 0x1c005000 0 0x1000>;
> +			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_AAL0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x5000 0x1000>;
> +		};
> +
> +		gamma0: disp_gamma at 1c006000 {

gamma at ...

> +			compatible = "mediatek,mt8195-disp-gamma",
> +				     "mediatek,mt8173-disp-gamma";
> +			reg = <0 0x1c006000 0 0x1000>;
> +			interrupts = <GIC_SPI 642 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_GAMMA0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x6000 0x1000>;
> +		};
> +
> +		dither0: disp_dither at 1c007000 {

dither at ....

> +			compatible = "mediatek,mt8195-disp-dither",
> +				     "mediatek,mt8183-disp-dither";
> +			reg = <0 0x1c007000 0 0x1000>;
> +			interrupts = <GIC_SPI 643 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_DITHER0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x7000 0x1000>;
> +		};
> +
> +		dsc0: disp_dsc_wrap at 1c009000 {

dsc at ...

> +			compatible = "mediatek,mt8195-disp-dsc";
> +			reg = <0 0x1c009000 0 0x1000>;
> +			interrupts = <GIC_SPI 645 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DSC_WRAP0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c00XXXX 0x9000 0x1000>;
> +		};
> +
> +		merge0: disp_vpp_merge0 at 1c014000 {

merge at ...

> +			compatible = "mediatek,mt8195-disp-merge";
> +			reg = <0 0x1c014000 0 0x1000>;
> +			interrupts = <GIC_SPI 656 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_VPP_MERGE0>;
> +			mediatek,gce-client-reg =
> +				 <&gce0 SUBSYS_1c01XXXX 0x4000 0x1000>;
> +		};
> +
> +		mutex: disp_mutex0 at 1c016000 {

mutex at ....

> +			compatible = "mediatek,mt8195-disp-mutex";
> +			reg = <0 0x1c016000 0 0x1000>;
> +			reg-names = "vdo0_mutex";
> +			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
> +			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
> +			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
> +			clock-names = "vdo0_mutex";
> +			mediatek,gce-events =
> +				 <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
> +		};
> +
> +		vdosys0: syscon at 1c01a000 {
> +			compatible = "mediatek,mt8195-vdosys0", "syscon";
> +			reg = <0 0x1c01a000 0 0x1000>;
> +			mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
> +			#clock-cells = <1>;
> +		};
> +
> +		vdosys1: syscon at 1c100000 {
> +			compatible = "mediatek,mt8195-vdosys1", "syscon";
> +			reg = <0 0x1c100000 0 0x1000>;
> +			#clock-cells = <1>;
> +		};
>   	};
>   };
> 

Regards,
Angelo


From khalasa at piap.pl  Thu Jan 27 04:17:44 2022
From: khalasa at piap.pl (=?utf-8?Q?Krzysztof_Ha=C5=82asa?=)
Date: Thu, 27 Jan 2022 13:17:44 +0100
Subject: [PATCH 00/13] IXP4xx spring cleaning
In-Reply-To: <CAK8P3a1xgEUF_LZU4nO3tn-OO=HuhUUqpUEuoGpC5uAmwzVM0w@mail.gmail.com>
 (Arnd Bergmann's message of "Thu, 27 Jan 2022 08:55:12 +0100")
References: <20220127003656.330161-1-linus.walleij@linaro.org>
 <CAK8P3a1xgEUF_LZU4nO3tn-OO=HuhUUqpUEuoGpC5uAmwzVM0w@mail.gmail.com>
Message-ID: <m3pmodxthz.fsf@t19.piap.pl>

Hi Arnd,

Arnd Bergmann <arnd at arndb.de> writes:

> It would
> be nice to be able to run Debian armel user space.

Exactly.

OTOH we need to remember IXP4xx is a single core, ARMv5, no NEON, no hw
FP, max 256 MB RAM (455/46x - 512 MB RAM IIRC), the clocks are from 266
up to 533/667 MHz IIRC, the PCI limitations and so on.
-- 
Krzysztof "Chris" Ha?asa

Sie? Badawcza ?ukasiewicz
Przemys?owy Instytut Automatyki i Pomiar?w PIAP
Al. Jerozolimskie 202, 02-486 Warszawa


From clabbe at baylibre.com  Thu Jan 27 04:19:52 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Thu, 27 Jan 2022 12:19:52 +0000
Subject: [PATCH] ARM: dts: aspeed: remove unhandled fttmr010,pwm-outputs
Message-ID: <20220127121952.3985981-1-clabbe@baylibre.com>

fttmr010,pwm-outputs is not handled by its timer driver, so this
property is useless.
Fixes: 67ac01d03862 ("ARM: dts: aspeed: add device tree for YADRO VEGMAN BMC")

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 arch/arm/boot/dts/aspeed-bmc-vegman.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
index 1a5b25b2ea29..43af63910571 100644
--- a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
+++ b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
@@ -166,7 +166,6 @@ &sdhci1 {
 };
 
 &timer {
-	fttmr010,pwm-outputs = <5>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_timer5_default>;
 	#pwm-cells = <3>;
-- 
2.34.1



From anshuman.khandual at arm.com  Thu Jan 27 04:20:54 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Thu, 27 Jan 2022 17:50:54 +0530
Subject: [RFC V1 06/11] arm64/perf: Drive BRBE from perf event states
In-Reply-To: <YfF/zBS3kL/+eC1k@robh.at.kernel.org>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-7-git-send-email-anshuman.khandual@arm.com>
 <YfF/zBS3kL/+eC1k@robh.at.kernel.org>
Message-ID: <9e56509a-2772-a333-ccc3-ad49a2028616@arm.com>


On 1/26/22 10:37 PM, Rob Herring wrote:
> On Mon, Jan 24, 2022 at 10:00:48AM +0530, Anshuman Khandual wrote:
>> Branch stack sampling rides along the normal perf event and all the branch
>> records get captured during the PMU interrupt. This just changes perf event
>> handling on the arm64 platform to accommodate required BRBE operations that
>> will enable branch stack sampling support.
>>
>> Cc: Peter Zijlstra <peterz at infradead.org>
>> Cc: Ingo Molnar <mingo at redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: linux-perf-users at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Cc: linux-arm-kernel at lists.infradead.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/kernel/perf_event.c |  6 +++++
>>  drivers/perf/arm_pmu.c         | 40 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 46 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index f6a47036b0b4..11c82c8f2eec 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -864,6 +864,12 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
>>  		if (!armpmu_event_set_period(event))
>>  			continue;
>>  
>> +		if (has_branch_stack(event)) {
>> +			cpu_pmu->brbe_read(cpuc, event);
> 
> Is has_branch_stack() guaranteed to be false on arm32? If not, this will 
> be a NULL function ptr.

armpmu_event_init() blocks a perf event from being created with branch
stack sampling request without CONFIG_ARM_BRBE_PMU option being enabled
first, which has dependency on CONFIG_ARM64. So has_branch_stack() is
guaranteed to be false on arm32.

static int armpmu_event_init(struct perf_event *event)
{
	....
        if (has_branch_stack(event)) {
                /*
                 * BRBE support is absent. Select CONFIG_ARM_BRBE_PMU
                 * in the config, before branch stack sampling events
                 * can be requested.
                 */
                if (!IS_ENABLED(CONFIG_ARM_BRBE_PMU)) {
                        pr_warn_once("BRBE is disabled, select CONFIG_ARM_BRBE_PMU\n");
                        return -EOPNOTSUPP;
                }


config ARM_BRBE_PMU
        tristate "Enable support for Branch Record Buffer Extension (BRBE)"
        depends on ARM64 && ARM_PMU
        default y
        help
          Enable perf support for Branch Record Buffer Extension (BRBE) which
          records all branches taken in an execution path. This supports some
          branch types and privilege based filtering. It captured additional
          relevant information such as cycle count, misprediction and branch
          type, branch privilege level etc.

> 
> To add to my other comments, this patch is where I would add 
> brbe_read(), etc. to arm_pmu.

Because all new arm_pmu helpers get added and get used in the perf driver
in the same patch, although the actual helper implementation would still
come by bit later via the driver. This also uses updates to pmu_hw_events
struct as well, then that patch needs to be folded here as well.

There is no problem as such, kind of bit subjective. I just feel inclined
to keep the independent infrastructure changes separate making it easy to
review while also creating a flow.


From james.morse at arm.com  Thu Jan 27 04:20:48 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:20:48 +0000
Subject: [PATCH v2 0/4] KVM: arm64: A510 errata workaround and fixes for
 fixup_guest_exit()
Message-ID: <20220127122052.1584324-1-james.morse@arm.com>

Hello!

Changes since v1:
 * Moved the SPSR_EL2 fixup into a helper called earlier
 * Use final cap
 * Dropped the IS_ENABLED() check

---

Early Cortex-A510 parts have a nasty erratum where two ERETs,
pointer-auth and software step conspire to corrupt SPSR_EL2. A
guest can only trigger this when it is being stepped by EL2, which
gives EL2 the opportunity to work around the erratum. Patch 4 does
this, the SDEN is available from:
https://developer.arm.com/documentation/SDEN2397239/900

Patches 2 and 3 fix two issues with the adjacent code where a stale
esr value could be used to alter the ELR_EL2 when an IRQ synchronises
an SError, and when an HVC synchronises an SError, the HVC may be
handled twice, (not just execute twice).


There are three series that would add the Cortex-A510 part macros. I've picked
Anshuman's patch that does this, on the assumption that makes someone's life
easier. I haven't spotted that patch on the arm64/for-next/fixes branch, so
I've not included the hash in the prerequisite field of the CC-stable.

Let me know if you want this reposted once that value is known.

This series is based on v5.17-rc1 and can be retrieved from:
https://git.gitlab.arm.com/linux-arm/linux-jm.git a510_errata/kvm_bits/v2


Thanks,

James

Anshuman Khandual (1):
  arm64: Add Cortex-A510 CPU part definition

James Morse (3):
  KVM: arm64: Avoid consuming a stale esr value when SError occur
  KVM: arm64: Stop handle_exit() from handling HVC twice when an SError
    occurs
  KVM: arm64: Workaround Cortex-A510's single-step and PAC trap errata

 Documentation/arm64/silicon-errata.rst  |  2 ++
 arch/arm64/Kconfig                      | 16 ++++++++++++++++
 arch/arm64/include/asm/cputype.h        |  2 ++
 arch/arm64/kernel/cpu_errata.c          |  8 ++++++++
 arch/arm64/kvm/handle_exit.c            |  8 ++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 23 +++++++++++++++++++++--
 arch/arm64/tools/cpucaps                |  1 +
 7 files changed, 58 insertions(+), 2 deletions(-)

-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 04:20:49 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:20:49 +0000
Subject: [PATCH v2 1/4] arm64: Add Cortex-A510 CPU part definition
In-Reply-To: <20220127122052.1584324-1-james.morse@arm.com>
References: <20220127122052.1584324-1-james.morse@arm.com>
Message-ID: <20220127122052.1584324-2-james.morse@arm.com>

From: Anshuman Khandual <anshuman.khandual at arm.com>

Add the CPU Partnumbers for the new Arm designs.

Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>
Acked-by: Catalin Marinas <catalin.marinas at arm.com>
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/include/asm/cputype.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 19b8441aa8f2..e8fdc10395b6 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,7 @@
 #define ARM_CPU_PART_CORTEX_A76		0xD0B
 #define ARM_CPU_PART_NEOVERSE_N1	0xD0C
 #define ARM_CPU_PART_CORTEX_A77		0xD0D
+#define ARM_CPU_PART_CORTEX_A510	0xD46
 #define ARM_CPU_PART_CORTEX_A710	0xD47
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 
@@ -115,6 +116,7 @@
 #define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
 #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1)
 #define MIDR_CORTEX_A77	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77)
+#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510)
 #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 04:20:50 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:20:50 +0000
Subject: [PATCH v2 2/4] KVM: arm64: Avoid consuming a stale esr value when
 SError occur
In-Reply-To: <20220127122052.1584324-1-james.morse@arm.com>
References: <20220127122052.1584324-1-james.morse@arm.com>
Message-ID: <20220127122052.1584324-3-james.morse@arm.com>

When any exception other than an IRQ occurs, the CPU updates the ESR_EL2
register with the exception syndrome. An SError may also become pending,
and will be synchronised by KVM. KVM notes the exception type, and whether
an SError was synchronised in exit_code.

When an exception other than an IRQ occurs, fixup_guest_exit() updates
vcpu->arch.fault.esr_el2 from the hardware register. When an SError was
synchronised, the vcpu esr value is used to determine if the exception
was due to an HVC. If so, ELR_EL2 is moved back one instruction. This
is so that KVM can process the SError first, and re-execute the HVC if
the guest survives the SError.

But if an IRQ synchronises an SError, the vcpu's esr value is stale.
If the previous non-IRQ exception was an HVC, KVM will corrupt ELR_EL2,
causing an unrelated guest instruction to be executed twice.

Check ARM_EXCEPTION_CODE() before messing with ELR_EL2, IRQs don't
update this register so don't need to check.

Fixes: defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to HYP")
Cc: stable at vger.kernel.org
Reported-by: Steven Price <steven.price at arm.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..331dd10821df 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -424,7 +424,8 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	if (ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ)
 		vcpu->arch.fault.esr_el2 = read_sysreg_el2(SYS_ESR);
 
-	if (ARM_SERROR_PENDING(*exit_code)) {
+	if (ARM_SERROR_PENDING(*exit_code) &&
+	    ARM_EXCEPTION_CODE(*exit_code) != ARM_EXCEPTION_IRQ) {
 		u8 esr_ec = kvm_vcpu_trap_get_class(vcpu);
 
 		/*
-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 04:20:51 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:20:51 +0000
Subject: [PATCH v2 3/4] KVM: arm64: Stop handle_exit() from handling HVC twice
 when an SError occurs
In-Reply-To: <20220127122052.1584324-1-james.morse@arm.com>
References: <20220127122052.1584324-1-james.morse@arm.com>
Message-ID: <20220127122052.1584324-4-james.morse@arm.com>

Prior to commit defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to
HYP"), when an SError is synchronised due to another exception, KVM
handles the SError first. If the guest survives, the instruction that
triggered the original exception is re-exectued to handle the first
exception. HVC is treated as a special case as the instruction wouldn't
normally be re-exectued, as its not a trap.

Commit defe21f49bc9 didn't preserve the behaviour of the 'return 1'
that skips the rest of handle_exit().

Since commit defe21f49bc9, KVM will try to handle the SError and the
original exception at the same time. When the exception was an HVC,
fixup_guest_exit() has already rolled back ELR_EL2, meaning if the
guest has virtual SError masked, it will execute and handle the HVC
twice.

Restore the original behaviour.

Fixes: defe21f49bc9 ("KVM: arm64: Move PC rollback on SError to HYP")
Cc: stable at vger.kernel.org
Signed-off-by: James Morse <james.morse at arm.com>
---
It may be possible to remove both this patch, and the HVC handling code
in fixup_guest_exit(). This means KVM would always handle the exception
and the SError. This may result in unnecessary work if the guest takes
the virtual SError when it is next restarted, but should be harmless if
SError are always re-injected using HCR_EL2.VSE.
---
 arch/arm64/kvm/handle_exit.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fd2dd26caf91..e3140abd2e2e 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -228,6 +228,14 @@ int handle_exit(struct kvm_vcpu *vcpu, int exception_index)
 {
 	struct kvm_run *run = vcpu->run;
 
+	if (ARM_SERROR_PENDING(exception_index)) {
+		/*
+		 * The SError is handled by handle_exit_early(). If the guest
+		 * survives it will re-execute the original instruction.
+		 */
+		return 1;
+	}
+
 	exception_index = ARM_EXCEPTION_CODE(exception_index);
 
 	switch (exception_index) {
-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 04:20:52 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:20:52 +0000
Subject: [PATCH v2 4/4] KVM: arm64: Workaround Cortex-A510's single-step and
 PAC trap errata
In-Reply-To: <20220127122052.1584324-1-james.morse@arm.com>
References: <20220127122052.1584324-1-james.morse@arm.com>
Message-ID: <20220127122052.1584324-5-james.morse@arm.com>

Cortex-A510's erratum #2077057 causes SPSR_EL2 to be corrupted when
single-stepping authenticated ERET instructions. A single step is
expected, but a pointer authentication trap is taken instead. The
erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
EL1 to cause a return to EL2 with a guest controlled ELR_EL2.

Because the conditions require an ERET into active-not-pending state,
this is only a problem for the EL2 when EL2 is stepping EL1. In this case
the previous SPSR_EL2 value is preserved in struct kvm_vcpu, and can be
restored.

Cc: stable at vger.kernel.org # ${GITHASHHERE}: arm64: Add Cortex-A510 CPU part definition
Cc: stable at vger.kernel.org
Signed-off-by: James Morse <james.morse at arm.com>
---
Changes since v1:
 * Moved the SPSR_EL2 fixup into a helper called earlier
 * Use final cap
 * Dropped the IS_ENABLED() check

 Documentation/arm64/silicon-errata.rst  |  2 ++
 arch/arm64/Kconfig                      | 16 ++++++++++++++++
 arch/arm64/kernel/cpu_errata.c          |  8 ++++++++
 arch/arm64/kvm/hyp/include/hyp/switch.h | 20 +++++++++++++++++++-
 arch/arm64/tools/cpucaps                |  1 +
 5 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..ac1ae34564c9 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -92,6 +92,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #2077057        | ARM64_ERRATUM_2077057       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..02b542ec18c8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -670,6 +670,22 @@ config ARM64_ERRATUM_1508412
 config ARM64_WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 	bool
 
+config ARM64_ERRATUM_2077057
+	bool "Cortex-A510: 2077057: workaround software-step corrupting SPSR_EL2"
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 2077057.
+	  Affected Cortex-A510 may corrupt SPSR_EL2 when the a step exception is
+	  expected, but a Pointer Authentication trap is taken instead. The
+	  erratum causes SPSR_EL1 to be copied to SPSR_EL2, which could allow
+	  EL1 to cause a return to EL2 with a guest controlled ELR_EL2.
+
+	  This can only happen when EL2 is stepping EL1.
+
+	  When these conditions occur, the SPSR_EL2 value is unchanged from the
+	  previous guest entry, and can be restored from the in-memory copy.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_2119858
 	bool "Cortex-A710: 2119858: workaround TRBE overwriting trace data in FILL mode"
 	default y
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..04a014c63251 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -597,6 +597,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2077057
+	{
+		.desc = "ARM erratum 2077057",
+		.capability = ARM64_WORKAROUND_2077057,
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2),
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 331dd10821df..701cfb964905 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -402,6 +402,24 @@ static inline bool kvm_hyp_handle_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	return false;
 }
 
+static inline void synchronize_vcpu_pstate(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	/*
+	 * Check for the conditions of Cortex-A510's #2077057. When these occur
+	 * SPSR_EL2 can't be trusted, but isn't needed either as it is
+	 * unchanged from the value in vcpu_gp_regs(vcpu)->pstate.
+	 * Are we single-stepping the guest, and took a PAC exception from the
+	 * active-not-pending state?
+	 */
+	if (cpus_have_final_cap(ARM64_WORKAROUND_2077057)		&&
+	    vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP			&&
+	    *vcpu_cpsr(vcpu) & DBG_SPSR_SS				&&
+	    ESR_ELx_EC(read_sysreg_el2(SYS_ESR)) == ESR_ELx_EC_PAC)
+		write_sysreg_el2(*vcpu_cpsr(vcpu), SYS_SPSR);
+
+	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
+}
+
 /*
  * Return true when we were able to fixup the guest exit and should return to
  * the guest, false when we should restore the host state and return to the
@@ -413,7 +431,7 @@ static inline bool fixup_guest_exit(struct kvm_vcpu *vcpu, u64 *exit_code)
 	 * Save PSTATE early so that we can evaluate the vcpu mode
 	 * early on.
 	 */
-	vcpu->arch.ctxt.regs.pstate = read_sysreg_el2(SYS_SPSR);
+	synchronize_vcpu_pstate(vcpu, exit_code);
 
 	/*
 	 * Check whether we want to repaint the state one way or
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..2e7cd3fecca6 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_2077057
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.30.2



From yuji2.ishikawa at toshiba.co.jp  Thu Jan 27 04:17:14 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Thu, 27 Jan 2022 21:17:14 +0900
Subject: [PATCH 1/1] net: stmmac: dwmac-visconti: No change to ETHER_CLOCK_SEL
 for unexpected speed request.
In-Reply-To: <20220127121714.22915-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220127121714.22915-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <20220127121714.22915-2-yuji2.ishikawa@toshiba.co.jp>

Variable clk_sel_val is not initialized in the default case of the first switch statement.
In that case, the function should return immediately without any changes to the hardware.

Reported-by: kernel test robot <lkp at intel.com>
Reported-by: Dan Carpenter <dan.carpenter at oracle.com>
Fixes: b38dd98ff8d0 ("net: stmmac: Add Toshiba Visconti SoCs glue driver")
Signed-off-by: Yuji Ishikawa <yuji2.ishikawa at toshiba.co.jp>
Reviewed-by: Nobuhiro Iwamatsu <nobuhiro1.iwamatsu at toshiba.co.jp>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
index dde5b772a..c3f10a92b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c
@@ -49,13 +49,15 @@ struct visconti_eth {
 	void __iomem *reg;
 	u32 phy_intf_sel;
 	struct clk *phy_ref_clk;
+	struct device *dev;
 	spinlock_t lock; /* lock to protect register update */
 };
 
 static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
 {
 	struct visconti_eth *dwmac = priv;
-	unsigned int val, clk_sel_val;
+	struct net_device *netdev = dev_get_drvdata(dwmac->dev);
+	unsigned int val, clk_sel_val = 0;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dwmac->lock, flags);
@@ -85,7 +87,9 @@ static void visconti_eth_fix_mac_speed(void *priv, unsigned int speed)
 		break;
 	default:
 		/* No bit control */
-		break;
+		netdev_err(netdev, "Unsupported speed request (%d)", speed);
+		spin_unlock_irqrestore(&dwmac->lock, flags);
+		return;
 	}
 
 	writel(val, dwmac->reg + MAC_CTRL_REG);
@@ -229,6 +233,7 @@ static int visconti_eth_dwmac_probe(struct platform_device *pdev)
 
 	spin_lock_init(&dwmac->lock);
 	dwmac->reg = stmmac_res.addr;
+	dwmac->dev = &pdev->dev;
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->fix_mac_speed = visconti_eth_fix_mac_speed;
 
-- 
2.17.1




From yuji2.ishikawa at toshiba.co.jp  Thu Jan 27 04:17:13 2022
From: yuji2.ishikawa at toshiba.co.jp (Yuji Ishikawa)
Date: Thu, 27 Jan 2022 21:17:13 +0900
Subject: [PATCH 0/1] net: stmmac: dwmac-visconti: Avoid updating hardware
 register for unexpected speed requst
Message-ID: <20220127121714.22915-1-yuji2.ishikawa@toshiba.co.jp>

Function visconti_eth_fix_mac_speed() should not change a register when an unexpected speed value is passed.

Yuji Ishikawa (1):
  net: stmmac: dwmac-visconti: No change to ETHER_CLOCK_SEL for
    unexpected speed request.

 drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

-- 
2.17.1




From david at redhat.com  Thu Jan 27 04:22:47 2022
From: david at redhat.com (David Hildenbrand)
Date: Thu, 27 Jan 2022 13:22:47 +0100
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
 <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
 <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>
Message-ID: <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com>

> 
> Yes, system_state can roughly separate these callers of __create_pgd_mapping. When system_state > SYSTEM_BOOTING we can add the lock.
> Thus, I have the following change:
> 
> static DEFINE_SPINLOCK(swapper_pgdir_lock);
> +static DEFINE_MUTEX(fixmap_lock);
> 
>  void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
>  {
> @@ -329,6 +330,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
>         }
>         BUG_ON(p4d_bad(p4d));
> 
> +       if (system_state > SYSTEM_BOOTING)

As there is nothing smaller than SYSTEM_BOOTING, you can use
	if (system_state != SYSTEM_BOOTING)

...

> 
> It seems work and somehow simper. But I don't know if it is reasonable to do this. So, any idea? @Ard Biesheuvel  @Catalin Marinas 

It's worth looking at kernel/notifier.c, e.g.,
blocking_notifier_chain_register()

if (unlikely(system_state == SYSTEM_BOOTING))
	return notifier_chain_register(&nh->head, n);

down_write(&nh->rwsem);
ret = notifier_chain_register(&nh->head, n);
up_write(&nh->rwsem);



If we decide to go down that path, we should make sure to add a comment like

/*
 * No need for locking during early boot. And it doesn't work as
 * expected with KASLR enabled where we might clear BSS twice.
 */

-- 
Thanks,

David / dhildenb



From catalin.marinas at arm.com  Thu Jan 27 04:24:14 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 27 Jan 2022 12:24:14 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <20220118110255.GC3294453@arm.com>
References: <20211209111048.GM3294453@arm.com> <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com> <YeWtRk0H30q38eM8@arm.com>
 <20220118110255.GC3294453@arm.com>
Message-ID: <YfKO7r5l7AUvd8r/@arm.com>

(Mark posted another series but I'm replying here to clarify some
aspects)

On Tue, Jan 18, 2022 at 11:02:55AM +0000, Szabolcs Nagy wrote:
> The 01/17/2022 17:54, Catalin Marinas wrote:
> > On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
> > > I think we can look at this from two angles:
> > > 
> > > 1. Ignoring MDWE, should whoever does the original mmap() also honour
> > >    PROT_BTI? We do this for static binaries but, for consistency, should
> > >    we extend it to dynamic executable?
> > > 
> > > 2. A 'simple' fix to allow MDWE together with BTI.
> > 
> > Thinking about it, (1) is not that different from the kernel setting
> > PROT_EXEC on the main executable when the dynamic loader could've done
> > it as well. There is a case for making this more consistent: whoever
> > does the mmap() should use the full attributes.
> 
> Yeah that was my original idea that it should be consistent.
> One caveat is that protection flags are normally specified
> in the program header, but the BTI marking is in
> PT_GNU_PROPERTY which is harder to get to, so glibc does not
> try to get it right for the initial mapping either: it has
> to re-mmap or mprotect. (In principle we could use read
> syscalls to parse the ELF headers and notes before mmap,
> but that's more complicated with additional failure modes.)
> 
> i.e. if (2) is fixed then mprotect can be used for library
> mapping too which is simpler than re-mmap.

I lost track of the userspace fixes here, was glibc changed to attempt a
re-mmap of the dynamic libraries instead of mprotect()?

It looks like (2) is a simpler fix and (1) could still be added for
consistency, it's complementary.

> > Question for the toolchain people: would the compiler ever generate
> > relocations in the main executable that the linker needs to resolve via
> > an mprotect(READ|WRITE) followed by mprotect(READ|EXEC)? If yes, we'd
> > better go for a proper MDWE implementation in the kernel.
> 
> There is some support for text relocations in glibc, but it's not
> expected to be common (e.g. it is a bug if a distro binary has it).

Thanks for the clarification.

-- 
Catalin


From tobetter at gmail.com  Thu Jan 27 04:25:46 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 21:25:46 +0900
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
Message-ID: <YfKPSvnFKOaLr74+@anyang>

GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
'FC8731' on BPI-M5

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
index 212c6aa5a3b8..5751c48620ed 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
@@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <3300000>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index bf29afac645f..d4349b355e4a 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.32.0



From james.morse at arm.com  Thu Jan 27 04:29:14 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 12:29:14 +0000
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57 and
 A72
Message-ID: <20220127122914.1585008-1-james.morse@arm.com>

Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
occurs between a pair of AES instructions in aarch32 mode may corrupt
the ELR. The task will subsequently produce the wrong AES result.

The AES instructions are part of the cryptographic extensions, which are
optional. User-space software will detect the support for these
instructions from the hwcaps. If the platform doesn't support these
instructions a software implementation should be used.

Remove the hwcap bits on affected parts to indicate user-space should
not use the AES instructions.

CC: Ard Biesheuvel <ardb at kernel.org>
CC: Suzuki K Poulose <suzuki.poulose at arm.com>
CC: <stable at vger.kernel.org>
Signed-off-by: James Morse <james.morse at arm.com>
---
SDEN:
A57: https://developer.arm.com/documentation/epm049219/2300 1742098
A72: https://developer.arm.com/documentation/epm012079/11   1655431
---
 Documentation/arm64/silicon-errata.rst |  4 ++++
 arch/arm64/Kconfig                     | 16 ++++++++++++++++
 arch/arm64/include/asm/cpufeature.h    |  1 +
 arch/arm64/kernel/cpu_errata.c         | 17 +++++++++++++++++
 arch/arm64/kernel/cpufeature.c         | 23 +++++++++++++++++++++++
 arch/arm64/tools/cpucaps               |  1 +
 6 files changed, 62 insertions(+)

diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
index 5342e895fb60..0f255ab8c3e2 100644
--- a/Documentation/arm64/silicon-errata.rst
+++ b/Documentation/arm64/silicon-errata.rst
@@ -76,10 +76,14 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A57      | #1319537        | ARM64_ERRATUM_1319367       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A57      | #1742098        | ARM64_ERRATUM_1742098       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A72      | #853709         | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A72      | #1319367        | ARM64_ERRATUM_1319367       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A72      | #1655431        | ARM64_ERRATUM_1742098       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A73      | #858921         | ARM64_ERRATUM_858921        |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A76      | #1188873,1418040| ARM64_ERRATUM_1418040       |
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..0daf4fff0eaf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -488,6 +488,22 @@ config ARM64_ERRATUM_834220
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_1742098
+	bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
+	depends on COMPAT
+	default y
+	help
+	  This option removes the AES hwcap for aarch32 user-space to
+	  workaround erratum 1742098 on Cortex-A57 and Cortex-A72.
+
+	  Affected parts may corrupt the AES state if an interrupt is
+	  taken between a pair of AES instructions. These instructions
+	  are only present if the cryptography extensions are present.
+	  All software should have a fallback implementation for CPUs
+	  that don't implement the cryptography extensions.
+
+	  If unsure, say Y.
+
 config ARM64_ERRATUM_845719
 	bool "Cortex-A53: 845719: a load might read incorrect data"
 	depends on COMPAT
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92b1921..355313d46c14 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -857,6 +857,7 @@ extern struct arm64_ftr_override id_aa64isar1_override;
 
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
+void arm64_remove_aes_compat_hwcap(const struct arm64_cpu_capabilities *cap);
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 9e1c1aef9ebd..b06fb054e055 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -376,6 +376,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
 };
 #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
 
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+static struct midr_range broken_aarch32_aes[] = {
+	MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
+	{},
+};
+#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
+
 const struct arm64_cpu_capabilities arm64_errata[] = {
 #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
 	{
@@ -597,6 +605,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
 		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
 	},
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+	{
+		.desc = "ARM erratum 1742098",
+		.capability = ARM64_WORKAROUND_1742098,
+		CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		.cpu_enable = arm64_remove_aes_compat_hwcap,
+	},
 #endif
 	{
 	}
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..06605e267ab0 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1900,6 +1900,29 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
 }
 #endif /* CONFIG_ARM64_MTE */
 
+#ifdef CONFIG_ARM64_ERRATUM_1742098
+/*
+ * compat_elf_hwcap{,2} are built from the sanitised id registers after the
+ * enable calls have run.  See the order of the setup_system_capabilities()
+ * and setup_elf_hwcaps() calls in setup_cpu_features(). Removing the AES
+ * field prevents the AES hwcap from being advertised.
+ */
+void arm64_remove_aes_compat_hwcap(const struct arm64_cpu_capabilities *cap)
+{
+	struct arm64_ftr_reg *aa32isar5 = get_arm64_ftr_reg(SYS_ID_ISAR5_EL1);
+	u64 aes_mask = GENMASK_ULL(ID_ISAR5_AES_SHIFT + 3, ID_ISAR5_AES_SHIFT);
+
+	/*
+	 * On affected platforms this call is made via stop_machine() on all
+	 * online CPUs. Only clear the register from the boot CPU.
+	 */
+	if (smp_processor_id())
+		return;
+
+	aa32isar5->sys_val &= ~aes_mask;
+}
+#endif /* CONFIG_ARM64_ERRATUM_1742098 */
+
 #ifdef CONFIG_KVM
 static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
 {
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..6a3a5c116668 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -55,6 +55,7 @@ WORKAROUND_1418040
 WORKAROUND_1463225
 WORKAROUND_1508412
 WORKAROUND_1542419
+WORKAROUND_1742098
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
 WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
-- 
2.30.2



From tobetter at gmail.com  Thu Jan 27 04:29:25 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 21:29:25 +0900
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
Message-ID: <YfKQJejh0bfGYvof@anyang>

Typo in audio amplifier node, dioo2133 -> dio2133

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
index aa5898a58b89..120f2551a28b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
@@ -22,7 +22,7 @@ aliases {
 		spi0 = &spicc0;
 	};
 
-	dioo2133: audio-amplifier-0 {
+	dio2133: audio-amplifier-0 {
 		compatible = "simple-audio-amplifier";
 		enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
 		VCC-supply = <&vcc_5v>;
@@ -222,7 +222,7 @@ sound {
 		audio-widgets = "Line", "Lineout";
 		audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>,
 				 <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>,
-				 <&dioo2133>;
+				 <&dio2133>;
 		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
 				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
 				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
-- 
2.32.0



From catalin.marinas at arm.com  Thu Jan 27 04:34:28 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 27 Jan 2022 12:34:28 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com>
References: <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
 <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
 <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com>
Message-ID: <YfKRVJlWrgluqD9e@arm.com>

On Thu, Jan 27, 2022 at 01:22:47PM +0100, David Hildenbrand wrote:
> > Yes, system_state can roughly separate these callers of __create_pgd_mapping. When system_state > SYSTEM_BOOTING we can add the lock.
> > Thus, I have the following change:
> > 
> > static DEFINE_SPINLOCK(swapper_pgdir_lock);
> > +static DEFINE_MUTEX(fixmap_lock);
> > 
> >  void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)
> >  {
> > @@ -329,6 +330,8 @@ static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
> >         }
> >         BUG_ON(p4d_bad(p4d));
> > 
> > +       if (system_state > SYSTEM_BOOTING)
> 
> As there is nothing smaller than SYSTEM_BOOTING, you can use
> 	if (system_state != SYSTEM_BOOTING)
> 
> ...
> 
> > 
> > It seems work and somehow simper. But I don't know if it is reasonable to do this. So, any idea? @Ard Biesheuvel  @Catalin Marinas 
> 
> It's worth looking at kernel/notifier.c, e.g.,
> blocking_notifier_chain_register()
> 
> if (unlikely(system_state == SYSTEM_BOOTING))
> 	return notifier_chain_register(&nh->head, n);
> 
> down_write(&nh->rwsem);
> ret = notifier_chain_register(&nh->head, n);
> up_write(&nh->rwsem);
> 
> If we decide to go down that path, we should make sure to add a comment like
> 
> /*
>  * No need for locking during early boot. And it doesn't work as
>  * expected with KASLR enabled where we might clear BSS twice.
>  */

A similar approach sounds fine to me.

-- 
Catalin


From stefan.wahren at i2se.com  Thu Jan 27 04:35:09 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 27 Jan 2022 13:35:09 +0100
Subject: [PATCH] vchiq-mmal: Remove redundant 'flush_workqueue()' calls
In-Reply-To: <20220127014432.1185206-1-chi.minghao@zte.com.cn>
References: <20220127014432.1185206-1-chi.minghao@zte.com.cn>
Message-ID: <fdbe3eaf-c737-0714-6b54-8a7cdbe38a0c@i2se.com>

Hi,

Am 27.01.22 um 02:44 schrieb cgel.zte at gmail.com:
> From: "Minghao Chi (CGEL ZTE)" <chi.minghao at zte.com.cn>
>
> 'destroy_workqueue()' already drains the queue before destroying it,
> so there is no need to flush it explicitly.
>
> Remove the redundant 'flush_workqueue()' calls.
are you sure that drain_workqueue() is the same as flush_workqueue()?
>
> Reported-by: Zeal Robot <zealci at zte.com.cn>
> Signed-off-by: Minghao Chi (CGEL ZTE) <chi.minghao at zte.com.cn>
> Signed-off-by: CGEL ZTE <cgel.zte at gmail.com>
> ---
>  drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> index 76d3f0399964..60305c63c6f6 100644
> --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c
> @@ -1844,7 +1844,6 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance)
>  	mutex_unlock(&instance->vchiq_mutex);
>  
>  	vchiq_shutdown(instance->vchiq_instance);
> -	flush_workqueue(instance->bulk_wq);
>  	destroy_workqueue(instance->bulk_wq);
>  
>  	vfree(instance->bulk_scratch);


From theleks at ko-hh.de  Thu Jan 27 04:38:14 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 13:38:14 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
References: <20220126234325.GA7363@odroid-VirtualBox>
 <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
Message-ID: <20220127123814.GA152653@odroid-VirtualBox>

On Thu, Jan 27, 2022 at 11:15:12AM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 27/01/2022 00:43, Lutz Koschorreck wrote:
> > The interrupt pin of the external ethernet phy is used, instead of the
> > enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> > the gpio_ao bank.
> > Using open drain prevents reboot issues.
> > 
> > This causes phy interrupt problems at system startup.
> > [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> > [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> > [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> > [   76.649635] Call trace:
> > [   76.649638]  dump_backtrace+0x0/0x1c8
> > [   76.649658]  show_stack+0x14/0x60
> > [   76.649667]  dump_stack_lvl+0x64/0x7c
> > [   76.649676]  dump_stack+0x14/0x2c
> > [   76.649683]  __report_bad_irq+0x38/0xe8
> > [   76.649695]  note_interrupt+0x220/0x3a0
> > [   76.649704]  handle_irq_event_percpu+0x58/0x88
> > [   76.649713]  handle_irq_event+0x44/0xd8
> > [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> > [   76.649730]  generic_handle_domain_irq+0x38/0x58
> > [   76.649738]  gic_handle_irq+0x9c/0xb8
> > [   76.649747]  call_on_irq_stack+0x28/0x38
> > [   76.649755]  do_interrupt_handler+0x7c/0x80
> > [   76.649763]  el1_interrupt+0x34/0x80
> > [   76.649772]  el1h_64_irq_handler+0x14/0x20
> > [   76.649781]  el1h_64_irq+0x74/0x78
> > [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> > [   76.649796]  irq_thread_fn+0x5c/0x98
> > [   76.649804]  irq_thread+0x13c/0x260
> > [   76.649812]  kthread+0x144/0x178
> > [   76.649822]  ret_from_fork+0x10/0x20
> > [   76.649830] handlers:
> > [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> > [   76.661256] Disabling IRQ #36
> > 
> > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > 
> > Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> > ---
> >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > index 0bd1e98a0eef..ddb1b345397f 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
> >  		regulator-max-microvolt = <3300000>;
> >  		vin-supply = <&vcc_5v>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
> 
> Wow, indeed it's not the right GPIO chip... my bad.
> 
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> 
> Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?
There is a 10k pull up on the pin of C4 and HC4. Therefore it is fine to
set to GPIO_OPEN_DRAIN. If this pin is left ACTIVE_HIGH and I call
reboot, the bootloader is does not came up, it is an boot loop. Tobetter
fixed that with a reset device driver, but I think using GPIO_OPEN_DRAIN
is the right solution.
> 
> Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?
Yes of cause. I will generate a new patch set.
> 
> Neil
> 
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic


From ardb at kernel.org  Thu Jan 27 04:39:00 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 13:39:00 +0100
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <20220127122914.1585008-1-james.morse@arm.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
Message-ID: <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>

On Thu, 27 Jan 2022 at 13:29, James Morse <james.morse at arm.com> wrote:
>
> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
> occurs between a pair of AES instructions in aarch32 mode may corrupt
> the ELR. The task will subsequently produce the wrong AES result.
>
> The AES instructions are part of the cryptographic extensions, which are
> optional. User-space software will detect the support for these
> instructions from the hwcaps. If the platform doesn't support these
> instructions a software implementation should be used.
>
> Remove the hwcap bits on affected parts to indicate user-space should
> not use the AES instructions.
>
> CC: Ard Biesheuvel <ardb at kernel.org>
> CC: Suzuki K Poulose <suzuki.poulose at arm.com>
> CC: <stable at vger.kernel.org>
> Signed-off-by: James Morse <james.morse at arm.com>

For this patch,

Acked-by: Ard Biesheuvel <ardb at kernel.org>

but I will note that
- depending on the C library used, OpenSSL may use SIGILL trapping to
decide whether these instructions are implemented or not,
- the 32-bit kernel should ideally adopt the same approach,

Fortunately, the only A72 that is known to be widely deployed with
32-bit kernels and/or user space is the Raspberry Pi 4, which does not
implement the crypto extensions.


> ---
> SDEN:
> A57: https://developer.arm.com/documentation/epm049219/2300 1742098
> A72: https://developer.arm.com/documentation/epm012079/11   1655431
> ---
>  Documentation/arm64/silicon-errata.rst |  4 ++++
>  arch/arm64/Kconfig                     | 16 ++++++++++++++++
>  arch/arm64/include/asm/cpufeature.h    |  1 +
>  arch/arm64/kernel/cpu_errata.c         | 17 +++++++++++++++++
>  arch/arm64/kernel/cpufeature.c         | 23 +++++++++++++++++++++++
>  arch/arm64/tools/cpucaps               |  1 +
>  6 files changed, 62 insertions(+)
>
> diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst
> index 5342e895fb60..0f255ab8c3e2 100644
> --- a/Documentation/arm64/silicon-errata.rst
> +++ b/Documentation/arm64/silicon-errata.rst
> @@ -76,10 +76,14 @@ stable kernels.
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A57      | #1319537        | ARM64_ERRATUM_1319367       |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A57      | #1742098        | ARM64_ERRATUM_1742098       |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A72      | #853709         | N/A                         |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A72      | #1319367        | ARM64_ERRATUM_1319367       |
>  +----------------+-----------------+-----------------+-----------------------------+
> +| ARM            | Cortex-A72      | #1655431        | ARM64_ERRATUM_1742098       |
> ++----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A73      | #858921         | ARM64_ERRATUM_858921        |
>  +----------------+-----------------+-----------------+-----------------------------+
>  | ARM            | Cortex-A76      | #1188873,1418040| ARM64_ERRATUM_1418040       |
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 6978140edfa4..0daf4fff0eaf 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -488,6 +488,22 @@ config ARM64_ERRATUM_834220
>
>           If unsure, say Y.
>
> +config ARM64_ERRATUM_1742098
> +       bool "Cortex-A57/A72: 1742098: ELR recorded incorrectly on interrupt taken between cryptographic instructions in a sequence"
> +       depends on COMPAT
> +       default y
> +       help
> +         This option removes the AES hwcap for aarch32 user-space to
> +         workaround erratum 1742098 on Cortex-A57 and Cortex-A72.
> +
> +         Affected parts may corrupt the AES state if an interrupt is
> +         taken between a pair of AES instructions. These instructions
> +         are only present if the cryptography extensions are present.
> +         All software should have a fallback implementation for CPUs
> +         that don't implement the cryptography extensions.
> +
> +         If unsure, say Y.
> +
>  config ARM64_ERRATUM_845719
>         bool "Cortex-A53: 845719: a load might read incorrect data"
>         depends on COMPAT
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index ef6be92b1921..355313d46c14 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -857,6 +857,7 @@ extern struct arm64_ftr_override id_aa64isar1_override;
>
>  u32 get_kvm_ipa_limit(void);
>  void dump_cpu_features(void);
> +void arm64_remove_aes_compat_hwcap(const struct arm64_cpu_capabilities *cap);
>
>  #endif /* __ASSEMBLY__ */
>
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..b06fb054e055 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -376,6 +376,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
>  };
>  #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
>
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +static struct midr_range broken_aarch32_aes[] = {
> +       MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf),
> +       MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
> +       {},
> +};
> +#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
> +
>  const struct arm64_cpu_capabilities arm64_errata[] = {
>  #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
>         {
> @@ -597,6 +605,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>                 .type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>                 CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>         },
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +       {
> +               .desc = "ARM erratum 1742098",
> +               .capability = ARM64_WORKAROUND_1742098,
> +               CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
> +               .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
> +               .cpu_enable = arm64_remove_aes_compat_hwcap,
> +       },
>  #endif
>         {
>         }
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index a46ab3b1c4d5..06605e267ab0 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1900,6 +1900,29 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
>  }
>  #endif /* CONFIG_ARM64_MTE */
>
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +/*
> + * compat_elf_hwcap{,2} are built from the sanitised id registers after the
> + * enable calls have run.  See the order of the setup_system_capabilities()
> + * and setup_elf_hwcaps() calls in setup_cpu_features(). Removing the AES
> + * field prevents the AES hwcap from being advertised.
> + */
> +void arm64_remove_aes_compat_hwcap(const struct arm64_cpu_capabilities *cap)
> +{
> +       struct arm64_ftr_reg *aa32isar5 = get_arm64_ftr_reg(SYS_ID_ISAR5_EL1);
> +       u64 aes_mask = GENMASK_ULL(ID_ISAR5_AES_SHIFT + 3, ID_ISAR5_AES_SHIFT);
> +
> +       /*
> +        * On affected platforms this call is made via stop_machine() on all
> +        * online CPUs. Only clear the register from the boot CPU.
> +        */
> +       if (smp_processor_id())
> +               return;
> +
> +       aa32isar5->sys_val &= ~aes_mask;
> +}
> +#endif /* CONFIG_ARM64_ERRATUM_1742098 */
> +
>  #ifdef CONFIG_KVM
>  static bool is_kvm_protected_mode(const struct arm64_cpu_capabilities *entry, int __unused)
>  {
> diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
> index 870c39537dd0..6a3a5c116668 100644
> --- a/arch/arm64/tools/cpucaps
> +++ b/arch/arm64/tools/cpucaps
> @@ -55,6 +55,7 @@ WORKAROUND_1418040
>  WORKAROUND_1463225
>  WORKAROUND_1508412
>  WORKAROUND_1542419
> +WORKAROUND_1742098
>  WORKAROUND_TRBE_OVERWRITE_FILL_MODE
>  WORKAROUND_TSB_FLUSH_FAILURE
>  WORKAROUND_TRBE_WRITE_OUT_OF_RANGE
> --
> 2.30.2
>


From maz at kernel.org  Thu Jan 27 04:42:42 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 12:42:42 +0000
Subject: [PATCH v5 08/69] KVM: arm64: nv: Reset VCPU to EL2 registers if
 VCPU nested virt is set
In-Reply-To: <20220107215401.61828-1-chase.conklin@arm.com>
References: <20211129200150.351436-9-maz@kernel.org>
 <20220107215401.61828-1-chase.conklin@arm.com>
Message-ID: <87y2315ozh.wl-maz@kernel.org>

On Fri, 07 Jan 2022 21:54:01 +0000,
Chase Conklin <chase.conklin at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon Nov 29 15:00:49 EST 2021, Marc Zyngier <maz at kernel.org> wrote:
> > From: Christoffer Dall <christoffer.dall at arm.com>
> >
> > Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
> > feature is enabled on the VCPU.
> >
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > [maz: rework register reset not to use empty data structures]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/kvm/reset.c | 10 ++++++++--
> >  1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > index 426bd7fbc3fd..38a7182819fb 100644
> > --- a/arch/arm64/kvm/reset.c
> > +++ b/arch/arm64/kvm/reset.c
> > @@ -27,6 +27,7 @@
> >  #include <asm/kvm_asm.h>
> >  #include <asm/kvm_emulate.h>
> >  #include <asm/kvm_mmu.h>
> > +#include <asm/kvm_nested.h>
> >  #include <asm/virt.h>
> >  
> >  /* Maximum phys_shift supported for any VM on this host */
> > @@ -38,6 +39,9 @@ static u32 kvm_ipa_limit;
> >  #define VCPU_RESET_PSTATE_EL1	(PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
> >  				 PSR_F_BIT | PSR_D_BIT)
> >  
> > +#define VCPU_RESET_PSTATE_EL2	(PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> > +				 PSR_F_BIT | PSR_D_BIT)
> > +
> >  #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
> >  				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
> >  
> > @@ -176,8 +180,8 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> >  	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
> >  		return false;
> >  
> > -	/* MTE is incompatible with AArch32 */
> > -	if (kvm_has_mte(vcpu->kvm) && is32bit)
> > +	/* MTE and NV are incompatible with AArch32 */
> > +	if ((kvm_has_mte(vcpu->kvm) || nested_virt_in_use(vcpu)) && is32bit)
> >  		return false;
> 
> Should something similar be done for SVE? I see from the ID register emulation
> that SVE is hidden from the guest but there isn't anything in
> kvm_vcpu_enable_sve() that checks if NV is in use. That means it's possible to
> have both nested_virt_in_use(vcpu) and vcpu_has_sve(vcpu) be true
> simultaneously. If that happens, the FPSIMD fixup can get confused
> 
> 	/*
> 	 * Don't handle SVE traps for non-SVE vcpus here. This
> 	 * includes NV guests for the time being.
> 	 */
> 	if (!sve_guest && (esr_ec != ESR_ELx_EC_FP_ASIMD ||
> 			   guest_hyp_fpsimd_traps_enabled(vcpu)))
> 		return false;
> 
> and incorrectly restore the wrong context instead of forwarding a
> FPSIMD trap to the guest hypervisor.

Yes, nice catch. I have added this to kvm_reset_vcpu() to prevent the
issue.

	if (nested_virt_in_use(vcpu) &&
	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
		ret = -EINVAL;
		goto out;
	}

I may also rename nested_virt_in_use() to vcpu_has_nv(), which would
fit the rest of the code a bit better.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From Steen.Hegelund at microchip.com  Thu Jan 27 04:42:58 2022
From: Steen.Hegelund at microchip.com (Steen.Hegelund at microchip.com)
Date: Thu, 27 Jan 2022 12:42:58 +0000
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
In-Reply-To: <20220125161245.418882-1-horatiu.vultur@microchip.com>
References: <20220125161245.418882-1-horatiu.vultur@microchip.com>
Message-ID: <7ebaf35c71a15326a7bd9be2676846050ccc8eb4.camel@microchip.com>

Good catch Horatiu.

BR
Steen

Acked-by:?Steen Hegelund <Steen.Hegelund at microchip.com>

On Tue, 2022-01-25 at 17:12 +0100, Horatiu Vultur wrote:
> Initially the driver accessed the registers using u32 __iomem but then
> in the blamed commit it changed it to use regmap. The problem is that now
> the offset of the registers is not calculated anymore at word offset but
> at byte offset. Therefore make sure to multiply the offset with word size.
> 
> Fixes: 2afbbab45c261a ("pinctrl: microchip-sgpio: update to support regmap")
> Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
> ---
...

From maz at kernel.org  Thu Jan 27 04:43:43 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 12:43:43 +0000
Subject: [PATCH v5 08/69] KVM: arm64: nv: Reset VCPU to EL2 registers if
 VCPU nested virt is set
In-Reply-To: <YeWiAgWbDhTreD7y@shell.armlinux.org.uk>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-9-maz@kernel.org>
 <YeWiAgWbDhTreD7y@shell.armlinux.org.uk>
Message-ID: <87wnil5oxs.wl-maz@kernel.org>

On Mon, 17 Jan 2022 17:06:10 +0000,
"Russell King (Oracle)" <linux at armlinux.org.uk> wrote:
> 
> On Mon, Nov 29, 2021 at 08:00:49PM +0000, Marc Zyngier wrote:
> > From: Christoffer Dall <christoffer.dall at arm.com>
> > 
> > Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
> > feature is enabled on the VCPU.
> > 
> > Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
> > [maz: rework register reset not to use empty data structures]
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> 
> However, a couple of comments below.
> 
> > ---
> >  arch/arm64/kvm/reset.c | 10 ++++++++--
> >  1 file changed, 8 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
> > index 426bd7fbc3fd..38a7182819fb 100644
> > --- a/arch/arm64/kvm/reset.c
> > +++ b/arch/arm64/kvm/reset.c
> > @@ -27,6 +27,7 @@
> >  #include <asm/kvm_asm.h>
> >  #include <asm/kvm_emulate.h>
> >  #include <asm/kvm_mmu.h>
> > +#include <asm/kvm_nested.h>
> >  #include <asm/virt.h>
> >  
> >  /* Maximum phys_shift supported for any VM on this host */
> > @@ -38,6 +39,9 @@ static u32 kvm_ipa_limit;
> >  #define VCPU_RESET_PSTATE_EL1	(PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
> >  				 PSR_F_BIT | PSR_D_BIT)
> >  
> > +#define VCPU_RESET_PSTATE_EL2	(PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
> > +				 PSR_F_BIT | PSR_D_BIT)
> > +
> >  #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
> >  				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
> >  
> > @@ -176,8 +180,8 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
> >  	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
> >  		return false;
> >  
> > -	/* MTE is incompatible with AArch32 */
> > -	if (kvm_has_mte(vcpu->kvm) && is32bit)
> > +	/* MTE and NV are incompatible with AArch32 */
> > +	if ((kvm_has_mte(vcpu->kvm) || nested_virt_in_use(vcpu)) && is32bit)
> >  		return false;
> 
> It seems we have a bunch of:
> 
> 	if (something && is32bit)
> 		return false;
> 
> tests here - would it make sense to do:
> 
> 	if (is32bit) {
> 		if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
> 			return false;
> 
> 		/* MTE is incompatible with AArch32 */
> 		if (kvm_has_mte(vcpu->kvm))
> 			return false;
> 
> 		/* NV is incompatible with AArch32 */
> 		if (nested_virt_in_use(vcpu))
> 			return false;
> 	}
> 
> in terms of improved readability?

Agreed. I've now reworked to follow this pattern.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From narmstrong at baylibre.com  Thu Jan 27 04:59:19 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 13:59:19 +0100
Subject: [PATCH] arm64: dts: meson-g12b-odroid-n2: fix typo 'dio2133'
In-Reply-To: <YfKQJejh0bfGYvof@anyang>
References: <YfKQJejh0bfGYvof@anyang>
Message-ID: <51093ba3-b562-d2de-07ef-e4af8dfdffac@baylibre.com>

On 27/01/2022 13:29, Dongjin Kim wrote:
> Typo in audio amplifier node, dioo2133 -> dio2133
>

Fixes: ef599f5f3e10 ("arm64: dts: meson: convert ODROID-N2 to dtsi")
Fixes: 67d141c1f8e6 ("arm64: dts: meson: odroid-n2: add jack audio output support")

> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> index aa5898a58b89..120f2551a28b 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi
> @@ -22,7 +22,7 @@ aliases {
>  		spi0 = &spicc0;
>  	};
>  
> -	dioo2133: audio-amplifier-0 {
> +	dio2133: audio-amplifier-0 {
>  		compatible = "simple-audio-amplifier";
>  		enable-gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_HIGH>;
>  		VCC-supply = <&vcc_5v>;
> @@ -222,7 +222,7 @@ sound {
>  		audio-widgets = "Line", "Lineout";
>  		audio-aux-devs = <&tdmout_b>, <&tdmout_c>, <&tdmin_a>,
>  				 <&tdmin_b>, <&tdmin_c>, <&tdmin_lb>,
> -				 <&dioo2133>;
> +				 <&dio2133>;
>  		audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
>  				"TDMOUT_B IN 1", "FRDDR_B OUT 1",
>  				"TDMOUT_B IN 2", "FRDDR_C OUT 1",
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From narmstrong at baylibre.com  Thu Jan 27 05:00:11 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 14:00:11 +0100
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <YfKPSvnFKOaLr74+@anyang>
References: <YfKPSvnFKOaLr74+@anyang>
Message-ID: <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>

Hi,

On 27/01/2022 13:25, Dongjin Kim wrote:
> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
> 'FC8731' on BPI-M5
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> 
> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> index 212c6aa5a3b8..5751c48620ed 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index bf29afac645f..d4349b355e4a 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 
Thanks for the fixes,
can you send 2 patches fixing each files instead ?

Thanks,
Neil


From maz at kernel.org  Thu Jan 27 05:04:02 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 13:04:02 +0000
Subject: [PATCH v5 36/69] KVM: arm64: nv: Filter out unsupported features
 from ID regs
In-Reply-To: <300f7a61-acd1-21bd-d36d-1532d2cecf44@os.amperecomputing.com>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-37-maz@kernel.org>
 <e850857c-9cab-8e16-0568-acb513514ae8@os.amperecomputing.com>
 <87h7b3wqe9.wl-maz@kernel.org>
 <ef667048-7fbe-55dc-9856-546fd9d3c690@os.amperecomputing.com>
 <87zgouuxvy.wl-maz@kernel.org>
 <300f7a61-acd1-21bd-d36d-1532d2cecf44@os.amperecomputing.com>
Message-ID: <87v8y55nzx.wl-maz@kernel.org>

On Fri, 21 Jan 2022 11:33:30 +0000,
Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> 
> Hi Marc,
> 
> On 21-12-2021 02:40 pm, Marc Zyngier wrote:
> > On Tue, 21 Dec 2021 06:03:49 +0000,
> > Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >> 
> >> 
> >> 
> >> On 20-12-2021 03:26 pm, Marc Zyngier wrote:
> >>> On Mon, 20 Dec 2021 07:26:50 +0000,
> >>> Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com> wrote:
> >>>> 
> >>>> 
> >>>> Hi Marc,
> >>>> 
> >>>> On 30-11-2021 01:31 am, Marc Zyngier wrote:
> >>>>> As there is a number of features that we either can't support,
> >>>>> or don't want to support right away with NV, let's add some
> >>>>> basic filtering so that we don't advertize silly things to the
> >>>>> EL2 guest.
> >>>>> 
> >>>>> Whilst we are at it, avertize ARMv8.4-TTL as well as ARMv8.5-GTG.
> >>>>> 
> >>>>> Signed-off-by: Marc Zyngier <maz at kernel.org>
> >>>>> ---
> >>>>>     arch/arm64/include/asm/kvm_nested.h |   6 ++
> >>>>>     arch/arm64/kvm/nested.c             | 152 ++++++++++++++++++++++++++++
> >>>>>     arch/arm64/kvm/sys_regs.c           |   4 +-
> >>>>>     arch/arm64/kvm/sys_regs.h           |   2 +
> >>>>>     4 files changed, 163 insertions(+), 1 deletion(-)
> >>>>> 
> >>>>> diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> >>>>> index 07c15f51cf86..026ddaad972c 100644
> >>>>> --- a/arch/arm64/include/asm/kvm_nested.h
> >>>>> +++ b/arch/arm64/include/asm/kvm_nested.h
> >>>>> @@ -67,4 +67,10 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
> >>>>>     extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
> >>>>>     extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
> >>>>>     +struct sys_reg_params;
> >>>>> +struct sys_reg_desc;
> >>>>> +
> >>>>> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
> >>>>> +			  const struct sys_reg_desc *r);
> >>>>> +
> >>>>>     #endif /* __ARM64_KVM_NESTED_H */
> >>>>> diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> >>>>> index 42a96c8d2adc..19b674983e13 100644
> >>>>> --- a/arch/arm64/kvm/nested.c
> >>>>> +++ b/arch/arm64/kvm/nested.c
> >>>>> @@ -20,6 +20,10 @@
> >>>>>     #include <linux/kvm_host.h>
> >>>>>       #include <asm/kvm_emulate.h>
> >>>>> +#include <asm/kvm_nested.h>
> >>>>> +#include <asm/sysreg.h>
> >>>>> +
> >>>>> +#include "sys_regs.h"
> >>>>>       /*
> >>>>>      * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
> >>>>> @@ -38,3 +42,151 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
> >>>>>       	return -EINVAL;
> >>>>>     }
> >>>>> +
> >>>>> +/*
> >>>>> + * Our emulated CPU doesn't support all the possible features. For the
> >>>>> + * sake of simplicity (and probably mental sanity), wipe out a number
> >>>>> + * of feature bits we don't intend to support for the time being.
> >>>>> + * This list should get updated as new features get added to the NV
> >>>>> + * support, and new extension to the architecture.
> >>>>> + */
> >>>>> +void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
> >>>>> +			  const struct sys_reg_desc *r)
> >>>>> +{
> >>>>> +	u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
> >>>>> +			 (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
> >>>>> +	u64 val, tmp;
> >>>>> +
> >>>>> +	if (!nested_virt_in_use(v))
> >>>>> +		return;
> >>>>> +
> >>>>> +	val = p->regval;
> >>>>> +
> >>>>> +	switch (id) {
> >>>>> +	case SYS_ID_AA64ISAR0_EL1:
> >>>>> +		/* Support everything but O.S. and Range TLBIs */
> >>>>> +		val &= ~(FEATURE(ID_AA64ISAR0_TLB)	|
> >>>>> +			 GENMASK_ULL(27, 24)		|
> >>>>> +			 GENMASK_ULL(3, 0));
> >>>>> +		break;
> >>>>> +
> >>>>> +	case SYS_ID_AA64ISAR1_EL1:
> >>>>> +		/* Support everything but PtrAuth and Spec Invalidation */
> >>>>> +		val &= ~(GENMASK_ULL(63, 56)		|
> >>>>> +			 FEATURE(ID_AA64ISAR1_SPECRES)	|
> >>>>> +			 FEATURE(ID_AA64ISAR1_GPI)	|
> >>>>> +			 FEATURE(ID_AA64ISAR1_GPA)	|
> >>>>> +			 FEATURE(ID_AA64ISAR1_API)	|
> >>>>> +			 FEATURE(ID_AA64ISAR1_APA));
> >>>>> +		break;
> >>>>> +
> >>>>> +	case SYS_ID_AA64PFR0_EL1:
> >>>>> +		/* No AMU, MPAM, S-EL2, RAS or SVE */
> >>>>> +		val &= ~(GENMASK_ULL(55, 52)		|
> >>>>> +			 FEATURE(ID_AA64PFR0_AMU)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_MPAM)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_SEL2)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_RAS)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_SVE)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_EL3)	|
> >>>>> +			 FEATURE(ID_AA64PFR0_EL2));
> >>>>> +		/* 64bit EL2/EL3 only */
> >>>>> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), 0b0001);
> >>>>> +		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), 0b0001);
> >>>>> +		break;
> >>>>> +
> >>>>> +	case SYS_ID_AA64PFR1_EL1:
> >>>>> +		/* Only support SSBS */
> >>>>> +		val &= FEATURE(ID_AA64PFR1_SSBS);
> >>>>> +		break;
> >>>>> +
> >>>>> +	case SYS_ID_AA64MMFR0_EL1:
> >>>>> +		/* Hide ECV, FGT, ExS, Secure Memory */
> >>>>> +		val &= ~(GENMASK_ULL(63, 43)			|
> >>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN4_2)		|
> >>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN16_2)	|
> >>>>> +			 FEATURE(ID_AA64MMFR0_TGRAN64_2)	|
> >>>>> +			 FEATURE(ID_AA64MMFR0_SNSMEM));
> >>>>> +
> >>>>> +		/* Disallow unsupported S2 page sizes */
> >>>>> +		switch (PAGE_SIZE) {
> >>>>> +		case SZ_64K:
> >>>>> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0001);
> >>>>> +			fallthrough;
> >>>>> +		case SZ_16K:
> >>>>> +			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0001);
> >>>>> +			fallthrough;
> >>>>> +		case SZ_4K:
> >>>>> +			/* Support everything */
> >>>>> +			break;
> >>>>> +		}
> >>>> 
> >>>> It seems to me that Host hypervisor(L0) has to boot with 4KB page size
> >>>> to support all (4, 16 and 64KB) page sizes at L1, any specific reason
> >>>> for this restriction?
> >>> 
> >>> Well, yes.
> >>> 
> >>> If you have a L0 that has booted with (let's say) 64kB page size, how
> >>> do you provide S2 mappings with 4kB granularity so that you can
> >>> implement the permissions that a L1 guest hypervisor can impose on its
> >>> own guest, given that KVM currently mandates S1 and S2 to use the same
> >>> page sizes?
> >>> 
> >>> You can't. That's why we tell the guest hypervisor how much we
> >>> support, and the guest hypervisor can decide to go ahead or not
> >>> depending on what it does.
> >>> 
> >>> If one day we can support S2 mappings that are smaller than the host
> >>> page sizes, then we'll be able to allow to advertise all page sizes.
> >>> But I wouldn't hold my breath for this to happen.
> >> 
> >> Thanks for the detailed explanation!.
> >> Can we put one line comment that explains why this manipulation?
> >> It would be helpful to see a comment like S2 PAGE_SIZE should be
> >> at-least the size of Host PAGE_SIZE?
> > 
> > Can do, but we need to get the terminology straight, because this is
> > very quickly becoming confusing. Something like:
> > 
> > diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
> > index 7c9dd1edf011..d35a947f5679 100644
> > --- a/arch/arm64/kvm/nested.c
> > +++ b/arch/arm64/kvm/nested.c
> > @@ -850,7 +850,12 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
> >   			/* Support everything */
> >   			break;
> >   		}
> > -		/* Advertize supported S2 page sizes */
> > +		/*
> > +		 * Since we can't support a guest S2 page size smaller than
> > +		 * the host's own page size (due to KVM only populating its
> > +		 * own S2 using the kernel's page size), advertise the
> > +		 * limitation using FEAT_GTG.
> > +		 */
> 
> I have tried booting L0 with 4K page-size and L1 with 64K and with
> this config the L2/NestedVM boot hangs. I have tried L2 with
> page-sizes 4K and 64K(though S1 page size of L2 should not matter?).

S1 shouldn't matter, but if that's what you are seeing, there is
obviously an issue trying to satisfy a translation fault in this
configuration, and we get stuck.

Could you please add some tracing and work out whether this is the
case? I bet this is an issue trying to combine the L1 S2 translation
(which will be 64kB aligned) with the faulting IPA address, but I
can't immediately pinpoint the bug.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From theleks at ko-hh.de  Thu Jan 27 05:05:37 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Thu, 27 Jan 2022 14:05:37 +0100
Subject: [PATCH v2] arm64: dts: meson-sm1-odroid: use correct enable-gpio pin
 for tf-io regulator
Message-ID: <20220127130537.GA187347@odroid-VirtualBox>

The interrupt pin of the external ethernet phy is used, instead of the
enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
the gpio_ao bank.

This causes phy interrupt problems at system startup.
[   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
[   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
[   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
[   76.649635] Call trace:
[   76.649638]  dump_backtrace+0x0/0x1c8
[   76.649658]  show_stack+0x14/0x60
[   76.649667]  dump_stack_lvl+0x64/0x7c
[   76.649676]  dump_stack+0x14/0x2c
[   76.649683]  __report_bad_irq+0x38/0xe8
[   76.649695]  note_interrupt+0x220/0x3a0
[   76.649704]  handle_irq_event_percpu+0x58/0x88
[   76.649713]  handle_irq_event+0x44/0xd8
[   76.649721]  handle_fasteoi_irq+0xa8/0x130
[   76.649730]  generic_handle_domain_irq+0x38/0x58
[   76.649738]  gic_handle_irq+0x9c/0xb8
[   76.649747]  call_on_irq_stack+0x28/0x38
[   76.649755]  do_interrupt_handler+0x7c/0x80
[   76.649763]  el1_interrupt+0x34/0x80
[   76.649772]  el1h_64_irq_handler+0x14/0x20
[   76.649781]  el1h_64_irq+0x74/0x78
[   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
[   76.649796]  irq_thread_fn+0x5c/0x98
[   76.649804]  irq_thread+0x13c/0x260
[   76.649812]  kthread+0x144/0x178
[   76.649822]  ret_from_fork+0x10/0x20
[   76.649830] handlers:
[   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
[   76.661256] Disabling IRQ #36

Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>

only gpio bank
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index 0bd1e98a0eef..ed7cd5f53046 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 27 05:09:20 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 14:09:20 +0100
Subject: [PATCH v2] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <20220127130537.GA187347@odroid-VirtualBox>
References: <20220127130537.GA187347@odroid-VirtualBox>
Message-ID: <af32f4e8-5ee2-9d16-3880-f681d1c3de6d@baylibre.com>

On 27/01/2022 14:05, Lutz Koschorreck wrote:
> The interrupt pin of the external ethernet phy is used, instead of the
> enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> the gpio_ao bank.
> 
> This causes phy interrupt problems at system startup.
> [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> [   76.649635] Call trace:
> [   76.649638]  dump_backtrace+0x0/0x1c8
> [   76.649658]  show_stack+0x14/0x60
> [   76.649667]  dump_stack_lvl+0x64/0x7c
> [   76.649676]  dump_stack+0x14/0x2c
> [   76.649683]  __report_bad_irq+0x38/0xe8
> [   76.649695]  note_interrupt+0x220/0x3a0
> [   76.649704]  handle_irq_event_percpu+0x58/0x88
> [   76.649713]  handle_irq_event+0x44/0xd8
> [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> [   76.649730]  generic_handle_domain_irq+0x38/0x58
> [   76.649738]  gic_handle_irq+0x9c/0xb8
> [   76.649747]  call_on_irq_stack+0x28/0x38
> [   76.649755]  do_interrupt_handler+0x7c/0x80
> [   76.649763]  el1_interrupt+0x34/0x80
> [   76.649772]  el1h_64_irq_handler+0x14/0x20
> [   76.649781]  el1h_64_irq+0x74/0x78
> [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> [   76.649796]  irq_thread_fn+0x5c/0x98
> [   76.649804]  irq_thread+0x13c/0x260
> [   76.649812]  kthread+0x144/0x178
> [   76.649822]  ret_from_fork+0x10/0x20
> [   76.649830] handlers:
> [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> [   76.661256] Disabling IRQ #36
> 
> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> 
> Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> 
> only gpio bank

Spurious lines, will remove while applying

> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> index 0bd1e98a0eef..ed7cd5f53046 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
>  		regulator-max-microvolt = <3300000>;
>  		vin-supply = <&vcc_5v>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>


From arnd at arndb.de  Thu Jan 27 05:11:43 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 27 Jan 2022 14:11:43 +0100
Subject: [PATCH 00/13] IXP4xx spring cleaning
In-Reply-To: <m3pmodxthz.fsf@t19.piap.pl>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
 <CAK8P3a1xgEUF_LZU4nO3tn-OO=HuhUUqpUEuoGpC5uAmwzVM0w@mail.gmail.com>
 <m3pmodxthz.fsf@t19.piap.pl>
Message-ID: <CAK8P3a3iMvGSH3xVyom4OoEtHwbnz4KX24ZS10dzM9MXSEPp8A@mail.gmail.com>

On Thu, Jan 27, 2022 at 1:17 PM Krzysztof Ha?asa <khalasa at piap.pl> wrote:
> Arnd Bergmann <arnd at arndb.de> writes:
>
> > It would
> > be nice to be able to run Debian armel user space.
>
> Exactly.
>
> OTOH we need to remember IXP4xx is a single core, ARMv5, no NEON, no hw
> FP, max 256 MB RAM (455/46x - 512 MB RAM IIRC), the clocks are from 266
> up to 533/667 MHz IIRC, the PCI limitations and so on.

I think that is fairly typical for hardware that can run Debian armel
user space,
which nowadays means mostly ARM926 based SoCs like sam9 or f1c100s.

While there used to be popular ARMv5 and ARMv6 implementations that are
a bit faster like Kirkwood or IOP13xx, those have mostly been replaced by
ARMv7 or ARMv8 chips in practice, leaving Debian armel for this bottom
end of the scale.

      Arnd


From a.kartashev at yadro.com  Thu Jan 27 05:17:04 2022
From: a.kartashev at yadro.com (Andrei Kartashev)
Date: Thu, 27 Jan 2022 16:17:04 +0300
Subject: [PATCH] ARM: dts: aspeed: remove unhandled fttmr010,pwm-outputs
In-Reply-To: <20220127121952.3985981-1-clabbe@baylibre.com>
References: <20220127121952.3985981-1-clabbe@baylibre.com>
Message-ID: <b5e8f3defc6715fbc0798a5c490d588e247335bc.camel@yadro.com>

Hello,

Good catch! I miss this on porting DTS from local tree, based on
Intel's one. Since there is no such driver in upstream kernel
(https://github.com/Intel-BMC/linux/blob/dev-5.15-intel/drivers/pwm/pwm-fttmr010.c
), both this and beeper sections could be completely removed.

I will send another patch with cleanup.

Thank you.

On Thu, 2022-01-27 at 12:19 +0000, Corentin Labbe wrote:
> fttmr010,pwm-outputs is not handled by its timer driver, so this
> property is useless.
> Fixes: 67ac01d03862 ("ARM: dts: aspeed: add device tree for YADRO
> VEGMAN BMC")
> 
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
> ---
> ?arch/arm/boot/dts/aspeed-bmc-vegman.dtsi | 1 -
> ?1 file changed, 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
> b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
> index 1a5b25b2ea29..43af63910571 100644
> --- a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
> +++ b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
> @@ -166,7 +166,6 @@ &sdhci1 {
> ?};
> ?
> ?&timer {
> -???????fttmr010,pwm-outputs = <5>;
> ????????pinctrl-names = "default";
> ????????pinctrl-0 = <&pinctrl_timer5_default>;
> ????????#pwm-cells = <3>;

-- 
Best regards,
Andrei Kartashev




From clabbe.montjoie at gmail.com  Thu Jan 27 05:34:41 2022
From: clabbe.montjoie at gmail.com (Corentin Labbe)
Date: Thu, 27 Jan 2022 14:34:41 +0100
Subject: [PATCH] crypto: authenc - Fix sleep in atomic context in
 decrypt_tail
In-Reply-To: <Yee2oKxPSLaYY31N@gondor.apana.org.au>
References: <Yd1SIHUNdLIvKhzz@Red> <YeD4rt1OVnEMBr+A@gondor.apana.org.au>
 <YeD6vt47+pAl0SxG@gondor.apana.org.au> <YeEiWmkyNwfgQgmn@Red>
 <YeZx1aVL0HnT9tCB@Red> <Yee2oKxPSLaYY31N@gondor.apana.org.au>
Message-ID: <YfKfcRCOgCzYNLRG@Red>

Le Wed, Jan 19, 2022 at 05:58:40PM +1100, Herbert Xu a ?crit :
> On Tue, Jan 18, 2022 at 08:52:53AM +0100, Corentin Labbe wrote:
> >
> > With my patch, I got:
> > [   38.515668] BUG: sleeping function called from invalid context at crypto/skcipher.c:482
> > [   38.523708] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 84, name: 1c15000.crypto-
> > [   38.532176] preempt_count: 200, expected: 0
> > [   38.536381] CPU: 6 PID: 84 Comm: 1c15000.crypto- Not tainted 5.16.0-next-20220115-00124-g13473e8fac33-dirty #116
> > [   38.546551] Hardware name: Allwinner A83t board
> > [   38.551100]  unwind_backtrace from show_stack+0x10/0x14
> > [   38.556358]  show_stack from dump_stack_lvl+0x40/0x4c
> > [   38.561428]  dump_stack_lvl from __might_resched+0x118/0x154
> > [   38.567107]  __might_resched from skcipher_walk_virt+0xe8/0xec
> > [   38.572955]  skcipher_walk_virt from crypto_cbc_decrypt+0x2c/0x170
> > [   38.579147]  crypto_cbc_decrypt from crypto_skcipher_decrypt+0x38/0x5c
> > [   38.585680]  crypto_skcipher_decrypt from authenc_verify_ahash_done+0x18/0x34
> > [   38.592825]  authenc_verify_ahash_done from crypto_finalize_request+0x6c/0xe4
> > [   38.599974]  crypto_finalize_request from sun8i_ss_hash_run+0x73c/0xb98
> > [   38.606602]  sun8i_ss_hash_run from crypto_pump_work+0x1a8/0x330
> > [   38.612616]  crypto_pump_work from kthread_worker_fn+0xa8/0x1c4
> > [   38.618550]  kthread_worker_fn from kthread+0xf0/0x110
> > [   38.623701]  kthread from ret_from_fork+0x14/0x2c
> > [   38.628414] Exception stack(0xc2247fb0 to 0xc2247ff8)
> > [   38.633468] 7fa0:                                     00000000 00000000 00000000 00000000
> > [   38.641640] 7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> > [   38.649809] 7fe0:i 00000000 00000000 00000000 00000000 00000013 00000000
> > 
> > This is when testing hmac(sha1) on my crypto driver sun8i-ss and crypto testing authenc(hmac-sha1-sun8i-ss,cbc(aes-generic)).
> > 
> > Do you have any idea to better fix my issue ?
> 
> This backtrace is caused by a bug in authenc:
> 
> ---8<---
> The function crypto_authenc_decrypt_tail discards its flags
> argument and always relies on the flags from the original request
> when starting its sub-request.
> 
> This is clearly wrong as it may cause the SLEEPABLE flag to be
> set when it shouldn't.
> 
> Fixes: 92d95ba91772 ("crypto: authenc - Convert to new AEAD interface")
> Reported-by: Corentin Labbe <clabbe.montjoie at gmail.com>
> Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
> 
> diff --git a/crypto/authenc.c b/crypto/authenc.c
> index 670bf1a01d00..17f674a7cdff 100644
> --- a/crypto/authenc.c
> +++ b/crypto/authenc.c
> @@ -253,7 +253,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req,
>  		dst = scatterwalk_ffwd(areq_ctx->dst, req->dst, req->assoclen);
>  
>  	skcipher_request_set_tfm(skreq, ctx->enc);
> -	skcipher_request_set_callback(skreq, aead_request_flags(req),
> +	skcipher_request_set_callback(skreq, flags,
>  				      req->base.complete, req->base.data);
>  	skcipher_request_set_crypt(skreq, src, dst,
>  				   req->cryptlen - authsize, req->iv);
> -- 

This fixes my issue.

Tested-by: Corentin Labbe <clabbe.montjoie at gmail.com>

Thanks


From vladimir.murzin at arm.com  Thu Jan 27 05:40:16 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 27 Jan 2022 13:40:16 +0000
Subject: [PATCH 0/4] arm64: Support of PAuth QARMA3 architected algorithm
Message-ID: <20220127134020.62787-1-vladimir.murzin@arm.com>

QARMA3 is relaxed version of the QARMA5 algorithm which expected to
reduce the latency of calculation while still delivering a suitable
level of security.

Feature advertised via a new ID fields in ID_AA64ISAR2_EL1 [1], so we
need to teach the kernel to identify this.

[1] https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/ID-AA64ISAR2-EL1--AArch64-Instruction-Set-Attribute-Register-2?lang=en

Thanks!

Vladimir Murzin (4):
  arm64: cpufeature: Account min_field_value when cheking secondaries
    for PAuth
  arm64: cpufeature: Warn if mutually exclusive PAuth algorithms
    detected
  arm64: cpufeature: Mark existing PAuth architected algorithm as QARMA5
  arm64: Add support of PAuth QARMA3 architected algorithm

 arch/arm64/include/asm/asm_pointer_auth.h      |  3 ++
 arch/arm64/include/asm/cpufeature.h            |  1 +
 arch/arm64/include/asm/kvm_hyp.h               |  1 +
 arch/arm64/include/asm/sysreg.h                | 13 ++++++
 arch/arm64/kernel/cpufeature.c                 | 63 ++++++++++++++++++++++----
 arch/arm64/kernel/idreg-override.c             | 16 ++++++-
 arch/arm64/kvm/arm.c                           |  1 +
 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h |  5 ++
 arch/arm64/kvm/hyp/nvhe/sys_regs.c             | 14 ++++++
 arch/arm64/kvm/sys_regs.c                      |  5 ++
 arch/arm64/tools/cpucaps                       |  6 ++-
 11 files changed, 115 insertions(+), 13 deletions(-)

-- 
2.7.4



From vladimir.murzin at arm.com  Thu Jan 27 05:40:17 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 27 Jan 2022 13:40:17 +0000
Subject: [PATCH 1/4] arm64: cpufeature: Account min_field_value when cheking
 secondaries for PAuth
In-Reply-To: <20220127134020.62787-1-vladimir.murzin@arm.com>
References: <20220127134020.62787-1-vladimir.murzin@arm.com>
Message-ID: <20220127134020.62787-2-vladimir.murzin@arm.com>

In case, both boot_val and sec_val have value below min_field_value we
would wrongly report that address authentication is supported. It is
not a big issue because we enable address authentication based on boot
cpu (and check there is correct).

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/arm64/kernel/cpufeature.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b..b0ec125 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1826,7 +1826,7 @@ static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry,
 	/* Now check for the secondary CPUs with SCOPE_LOCAL_CPU scope */
 	sec_val = cpuid_feature_extract_field(__read_sysreg_by_encoding(entry->sys_reg),
 					      entry->field_pos, entry->sign);
-	return sec_val == boot_val;
+	return (sec_val >= entry->min_field_value) && (sec_val == boot_val);
 }
 
 static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
-- 
2.7.4



From vladimir.murzin at arm.com  Thu Jan 27 05:40:18 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 27 Jan 2022 13:40:18 +0000
Subject: [PATCH 2/4] arm64: cpufeature: Warn if mutually exclusive PAuth
 algorithms detected
In-Reply-To: <20220127134020.62787-1-vladimir.murzin@arm.com>
References: <20220127134020.62787-1-vladimir.murzin@arm.com>
Message-ID: <20220127134020.62787-3-vladimir.murzin@arm.com>

ARM ARM states for address authentication algorithms

APA, bits [7:4] If the value of ID_AA64ISAR1_EL1.API is non-zero, this
                field must have the value 0b0000.

API, bits [11:8] If the value of ID_AA64ISAR1_EL1.APA is non-zero,
                 this field must have the value 0b0000.

Similarly for generic code authentication algorithms

GPA, bits [27:24] If the value of ID_AA64ISAR1_EL1.GPI is non-zero,
                  this field must have the value 0b0000.

GPI, bits [31:28] If the value of ID_AA64ISAR1_EL1.GPA is non-zero,
                  this field must have the value 0b0000.

Let's add a warning if that not true.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/arm64/kernel/cpufeature.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index b0ec125..9dad0a3 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1832,15 +1832,23 @@ static bool has_address_auth_cpucap(const struct arm64_cpu_capabilities *entry,
 static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
 				     int scope)
 {
-	return has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope) ||
-	       has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+	bool api = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
+	bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope);
+
+	WARN_ON(apa && api);
+
+	return apa || api;
 }
 
 static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
 			     int __unused)
 {
-	return __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH) ||
-	       __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+	bool gpi = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
+	bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH);
+
+	WARN_ON(gpa && gpi);
+
+	return gpa || gpi;
 }
 #endif /* CONFIG_ARM64_PTR_AUTH */
 
-- 
2.7.4



From vladimir.murzin at arm.com  Thu Jan 27 05:40:19 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 27 Jan 2022 13:40:19 +0000
Subject: [PATCH 3/4] arm64: cpufeature: Mark existing PAuth architected
 algorithm as QARMA5
In-Reply-To: <20220127134020.62787-1-vladimir.murzin@arm.com>
References: <20220127134020.62787-1-vladimir.murzin@arm.com>
Message-ID: <20220127134020.62787-4-vladimir.murzin@arm.com>

In preparation of supporting PAuth QARMA3 architected algorithm mark
existing one as QARMA5, so we can distingwish between two.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/arm64/kernel/cpufeature.c | 12 ++++++------
 arch/arm64/tools/cpucaps       |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 9dad0a3..69fbc53 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1833,7 +1833,7 @@ static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
 				     int scope)
 {
 	bool api = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
-	bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH], scope);
+	bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5], scope);
 
 	WARN_ON(apa && api);
 
@@ -1844,7 +1844,7 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
 			     int __unused)
 {
 	bool gpi = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
-	bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH);
+	bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5);
 
 	WARN_ON(gpa && gpi);
 
@@ -2235,8 +2235,8 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 	},
 #ifdef CONFIG_ARM64_PTR_AUTH
 	{
-		.desc = "Address authentication (architected algorithm)",
-		.capability = ARM64_HAS_ADDRESS_AUTH_ARCH,
+		.desc = "Address authentication (architected QARMA5 algorithm)",
+		.capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5,
 		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
@@ -2260,8 +2260,8 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_address_auth_metacap,
 	},
 	{
-		.desc = "Generic authentication (architected algorithm)",
-		.capability = ARM64_HAS_GENERIC_AUTH_ARCH,
+		.desc = "Generic authentication (architected QARMA5 algorithm)",
+		.capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
 		.sys_reg = SYS_ID_AA64ISAR1_EL1,
 		.sign = FTR_UNSIGNED,
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c395..b1b6c40 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -7,7 +7,7 @@ BTI
 HAS_32BIT_EL0_DO_NOT_USE
 HAS_32BIT_EL1
 HAS_ADDRESS_AUTH
-HAS_ADDRESS_AUTH_ARCH
+HAS_ADDRESS_AUTH_ARCH_QARMA5
 HAS_ADDRESS_AUTH_IMP_DEF
 HAS_AMU_EXTN
 HAS_ARMv8_4_TTL
@@ -21,7 +21,7 @@ HAS_E0PD
 HAS_ECV
 HAS_EPAN
 HAS_GENERIC_AUTH
-HAS_GENERIC_AUTH_ARCH
+HAS_GENERIC_AUTH_ARCH_QARMA5
 HAS_GENERIC_AUTH_IMP_DEF
 HAS_IRQ_PRIO_MASKING
 HAS_LDAPR
-- 
2.7.4



From vladimir.murzin at arm.com  Thu Jan 27 05:40:20 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Thu, 27 Jan 2022 13:40:20 +0000
Subject: [PATCH 4/4] arm64: Add support of PAuth QARMA3 architected algorithm
In-Reply-To: <20220127134020.62787-1-vladimir.murzin@arm.com>
References: <20220127134020.62787-1-vladimir.murzin@arm.com>
Message-ID: <20220127134020.62787-5-vladimir.murzin@arm.com>

QARMA3 is relaxed version of the QARMA5 algorithm which expected to
reduce the latency of calculation while still delivering a suitable
level of security.

Support for QARMA3 can be discovered via ID_AA64ISAR2_EL1

    APA3, bits [15:12] Indicates whether the QARMA3 algorithm is
                       implemented in the PE for address
                       authentication in AArch64 state.

    GPA3, bits [11:8]  Indicates whether the QARMA3 algorithm is
                       implemented in the PE for generic code
                       authentication in AArch64 state.

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/arm64/include/asm/asm_pointer_auth.h      |  3 ++
 arch/arm64/include/asm/cpufeature.h            |  1 +
 arch/arm64/include/asm/kvm_hyp.h               |  1 +
 arch/arm64/include/asm/sysreg.h                | 13 ++++++++
 arch/arm64/kernel/cpufeature.c                 | 45 +++++++++++++++++++++++---
 arch/arm64/kernel/idreg-override.c             | 16 +++++++--
 arch/arm64/kvm/arm.c                           |  1 +
 arch/arm64/kvm/hyp/include/nvhe/fixed_config.h |  5 +++
 arch/arm64/kvm/hyp/nvhe/sys_regs.c             | 14 ++++++++
 arch/arm64/kvm/sys_regs.c                      |  5 +++
 arch/arm64/tools/cpucaps                       |  2 ++
 11 files changed, 100 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h
index f1bba5f..4ad9e7f 100644
--- a/arch/arm64/include/asm/asm_pointer_auth.h
+++ b/arch/arm64/include/asm/asm_pointer_auth.h
@@ -60,6 +60,9 @@ alternative_else_nop_endif
 	.macro __ptrauth_keys_init_cpu tsk, tmp1, tmp2, tmp3
 	mrs	\tmp1, id_aa64isar1_el1
 	ubfx	\tmp1, \tmp1, #ID_AA64ISAR1_APA_SHIFT, #8
+	mrs_s	\tmp2, SYS_ID_AA64ISAR2_EL1
+	ubfx	\tmp2, \tmp2, #ID_AA64ISAR2_APA3_SHIFT, #8
+	orr	\tmp1, \tmp1, \tmp2
 	cbz	\tmp1, .Lno_addr_auth\@
 	mov_q	\tmp1, (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | \
 			SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index ef6be92..fe7137f 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -854,6 +854,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
 extern struct arm64_ftr_override id_aa64mmfr1_override;
 extern struct arm64_ftr_override id_aa64pfr1_override;
 extern struct arm64_ftr_override id_aa64isar1_override;
+extern struct arm64_ftr_override id_aa64isar2_override;
 
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 462882f..aa7fa2a 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -118,6 +118,7 @@ extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64isar0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64isar1_el1_sys_val);
+extern u64 kvm_nvhe_sym(id_aa64isar2_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
 extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0..2269321 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -773,11 +773,14 @@
 #define ID_AA64ISAR1_GPI_IMP_DEF		0x1
 
 /* id_aa64isar2 */
+#define ID_AA64ISAR2_APA3_SHIFT		12
+#define ID_AA64ISAR2_GPA3_SHIFT		8
 #define ID_AA64ISAR2_RPRES_SHIFT	4
 #define ID_AA64ISAR2_WFXT_SHIFT		0
 
 #define ID_AA64ISAR2_RPRES_8BIT		0x0
 #define ID_AA64ISAR2_RPRES_12BIT	0x1
+
 /*
  * Value 0x1 has been removed from the architecture, and is
  * reserved, but has not yet been removed from the ARM ARM
@@ -786,6 +789,16 @@
 #define ID_AA64ISAR2_WFXT_NI		0x0
 #define ID_AA64ISAR2_WFXT_SUPPORTED	0x2
 
+#define ID_AA64ISAR2_APA3_NI			0x0
+#define ID_AA64ISAR2_APA3_ARCHITECTED		0x1
+#define ID_AA64ISAR2_APA3_ARCH_EPAC		0x2
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2		0x3
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC	0x4
+#define ID_AA64ISAR2_APA3_ARCH_EPAC2_FPAC_CMB	0x5
+
+#define ID_AA64ISAR2_GPA3_NI			0x0
+#define ID_AA64ISAR2_GPA3_ARCHITECTED		0x1
+
 /* id_aa64pfr0 */
 #define ID_AA64PFR0_CSV3_SHIFT		60
 #define ID_AA64PFR0_CSV2_SHIFT		56
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 69fbc53..aab6766 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -226,6 +226,10 @@ static const struct arm64_ftr_bits ftr_id_aa64isar1[] = {
 };
 
 static const struct arm64_ftr_bits ftr_id_aa64isar2[] = {
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+		       FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_APA3_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH),
+		       FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_GPA3_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_RPRES_SHIFT, 4, 0),
 	ARM64_FTR_END,
 };
@@ -596,6 +600,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
 struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
 struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
 struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
+struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
 
 static const struct __ftr_reg_entry {
 	u32			sys_id;
@@ -644,6 +649,8 @@ static const struct __ftr_reg_entry {
 	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
 			       &id_aa64isar1_override),
 	ARM64_FTR_REG(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2),
+	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR2_EL1, ftr_id_aa64isar2,
+			       &id_aa64isar2_override),
 
 	/* Op1 = 0, CRn = 0, CRm = 7 */
 	ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
@@ -1834,10 +1841,11 @@ static bool has_address_auth_metacap(const struct arm64_cpu_capabilities *entry,
 {
 	bool api = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_IMP_DEF], scope);
 	bool apa = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA5], scope);
+	bool apa3 = has_address_auth_cpucap(cpu_hwcaps_ptrs[ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3], scope);
 
-	WARN_ON(apa && api);
+	WARN_ON((apa && api) || (apa && apa3) || (api && apa3));
 
-	return apa || api;
+	return apa || apa3 || api;
 }
 
 static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
@@ -1845,10 +1853,11 @@ static bool has_generic_auth(const struct arm64_cpu_capabilities *entry,
 {
 	bool gpi = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_IMP_DEF);
 	bool gpa = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA5);
+	bool gpa3 = __system_matches_cap(ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3);
 
-	WARN_ON(gpa && gpi);
+	WARN_ON((gpa && gpi) || (gpa && gpa3) || (gpi && gpa3));
 
-	return gpa || gpi;
+	return gpa || gpa3 || gpi;
 }
 #endif /* CONFIG_ARM64_PTR_AUTH */
 
@@ -2245,6 +2254,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_address_auth_cpucap,
 	},
 	{
+		.desc = "Address authentication (architected QARMA3 algorithm)",
+		.capability = ARM64_HAS_ADDRESS_AUTH_ARCH_QARMA3,
+		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
+		.sys_reg = SYS_ID_AA64ISAR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64ISAR2_APA3_SHIFT,
+		.min_field_value = ID_AA64ISAR2_APA3_ARCHITECTED,
+		.matches = has_address_auth_cpucap,
+	},
+	{
 		.desc = "Address authentication (IMP DEF algorithm)",
 		.capability = ARM64_HAS_ADDRESS_AUTH_IMP_DEF,
 		.type = ARM64_CPUCAP_BOOT_CPU_FEATURE,
@@ -2270,6 +2289,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 	},
 	{
+		.desc = "Generic authentication (architected QARMA3 algorithm)",
+		.capability = ARM64_HAS_GENERIC_AUTH_ARCH_QARMA3,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.sys_reg = SYS_ID_AA64ISAR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64ISAR2_GPA3_SHIFT,
+		.min_field_value = ID_AA64ISAR2_GPA3_ARCHITECTED,
+		.matches = has_cpuid_feature,
+	},
+	{
 		.desc = "Generic authentication (IMP DEF algorithm)",
 		.capability = ARM64_HAS_GENERIC_AUTH_IMP_DEF,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
@@ -2417,6 +2446,10 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 				  FTR_UNSIGNED, ID_AA64ISAR1_APA_ARCHITECTED)
 	},
 	{
+		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_APA3_SHIFT,
+				  FTR_UNSIGNED, ID_AA64ISAR2_APA3_ARCHITECTED)
+	},
+	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_API_SHIFT,
 				  FTR_UNSIGNED, ID_AA64ISAR1_API_IMP_DEF)
 	},
@@ -2429,6 +2462,10 @@ static const struct arm64_cpu_capabilities ptr_auth_hwcap_gen_matches[] = {
 				  FTR_UNSIGNED, ID_AA64ISAR1_GPA_ARCHITECTED)
 	},
 	{
+		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR2_EL1, ID_AA64ISAR2_GPA3_SHIFT,
+				  FTR_UNSIGNED, ID_AA64ISAR2_GPA3_ARCHITECTED)
+	},
+	{
 		HWCAP_CPUID_MATCH(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_GPI_SHIFT,
 				  FTR_UNSIGNED, ID_AA64ISAR1_GPI_IMP_DEF)
 	},
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index d8e606f..5e3cce9 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -17,7 +17,7 @@
 #define FTR_DESC_NAME_LEN	20
 #define FTR_DESC_FIELD_LEN	10
 #define FTR_ALIAS_NAME_LEN	30
-#define FTR_ALIAS_OPTION_LEN	80
+#define FTR_ALIAS_OPTION_LEN	115
 
 struct ftr_set_desc {
 	char 				name[FTR_DESC_NAME_LEN];
@@ -71,6 +71,16 @@ static const struct ftr_set_desc isar1 __initconst = {
 	},
 };
 
+static const struct ftr_set_desc isar2 __initconst = {
+	.name		= "id_aa64isar2",
+	.override	= &id_aa64isar2_override,
+	.fields		= {
+	        { "gpa3", ID_AA64ISAR2_GPA3_SHIFT },
+	        { "apa3", ID_AA64ISAR2_APA3_SHIFT },
+		{}
+	},
+};
+
 extern struct arm64_ftr_override kaslr_feature_override;
 
 static const struct ftr_set_desc kaslr __initconst = {
@@ -88,6 +98,7 @@ static const struct ftr_set_desc * const regs[] __initconst = {
 	&mmfr1,
 	&pfr1,
 	&isar1,
+	&isar2,
 	&kaslr,
 };
 
@@ -100,7 +111,8 @@ static const struct {
 	{ "arm64.nobti",		"id_aa64pfr1.bt=0" },
 	{ "arm64.nopauth",
 	  "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
-	  "id_aa64isar1.api=0 id_aa64isar1.apa=0"	   },
+	  "id_aa64isar1.api=0 id_aa64isar1.apa=0 "
+	  "id_aa64isar2.gpa3=0 id_aa64isar2.apa3=0"	   },
 	{ "arm64.nomte",		"id_aa64pfr1.mte=0" },
 	{ "nokaslr",			"kaslr.disabled=1" },
 };
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a4a0063..a08bc68 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1855,6 +1855,7 @@ static int kvm_hyp_init_protection(u32 hyp_va_bits)
 	kvm_nvhe_sym(id_aa64pfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
 	kvm_nvhe_sym(id_aa64isar0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1);
 	kvm_nvhe_sym(id_aa64isar1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+	kvm_nvhe_sym(id_aa64isar2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
 	kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
 	kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
 	kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val) = read_sanitised_ftr_reg(SYS_ID_AA64MMFR2_EL1);
diff --git a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
index eea1f6a..5ad6265 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/fixed_config.h
@@ -192,6 +192,11 @@
 	ARM64_FEATURE_MASK(ID_AA64ISAR1_I8MM) \
 	)
 
+#define PVM_ID_AA64ISAR2_ALLOW (\
+	ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3) | \
+	ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) \
+	)
+
 u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
 bool kvm_handle_pvm_sysreg(struct kvm_vcpu *vcpu, u64 *exit_code);
 bool kvm_handle_pvm_restricted(struct kvm_vcpu *vcpu, u64 *exit_code);
diff --git a/arch/arm64/kvm/hyp/nvhe/sys_regs.c b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
index 792cf6e..33f5181 100644
--- a/arch/arm64/kvm/hyp/nvhe/sys_regs.c
+++ b/arch/arm64/kvm/hyp/nvhe/sys_regs.c
@@ -22,6 +22,7 @@ u64 id_aa64pfr0_el1_sys_val;
 u64 id_aa64pfr1_el1_sys_val;
 u64 id_aa64isar0_el1_sys_val;
 u64 id_aa64isar1_el1_sys_val;
+u64 id_aa64isar2_el1_sys_val;
 u64 id_aa64mmfr0_el1_sys_val;
 u64 id_aa64mmfr1_el1_sys_val;
 u64 id_aa64mmfr2_el1_sys_val;
@@ -183,6 +184,17 @@ static u64 get_pvm_id_aa64isar1(const struct kvm_vcpu *vcpu)
 	return id_aa64isar1_el1_sys_val & allow_mask;
 }
 
+static u64 get_pvm_id_aa64isar2(const struct kvm_vcpu *vcpu)
+{
+	u64 allow_mask = PVM_ID_AA64ISAR2_ALLOW;
+
+	if (!vcpu_has_ptrauth(vcpu))
+		allow_mask &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+				ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+
+	return id_aa64isar2_el1_sys_val & allow_mask;
+}
+
 static u64 get_pvm_id_aa64mmfr0(const struct kvm_vcpu *vcpu)
 {
 	u64 set_mask;
@@ -225,6 +237,8 @@ u64 pvm_read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
 		return get_pvm_id_aa64isar0(vcpu);
 	case SYS_ID_AA64ISAR1_EL1:
 		return get_pvm_id_aa64isar1(vcpu);
+	case SYS_ID_AA64ISAR2_EL1:
+		return get_pvm_id_aa64isar2(vcpu);
 	case SYS_ID_AA64MMFR0_EL1:
 		return get_pvm_id_aa64mmfr0(vcpu);
 	case SYS_ID_AA64MMFR1_EL1:
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba..baa6529 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1097,6 +1097,11 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
 				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPA) |
 				 ARM64_FEATURE_MASK(ID_AA64ISAR1_GPI));
 		break;
+	case SYS_ID_AA64ISAR2_EL1:
+		if (!vcpu_has_ptrauth(vcpu))
+			val &= ~(ARM64_FEATURE_MASK(ID_AA64ISAR2_APA3) |
+				 ARM64_FEATURE_MASK(ID_AA64ISAR2_GPA3));
+		break;
 	case SYS_ID_AA64DFR0_EL1:
 		/* Limit debug to ARMv8.0 */
 		val &= ~ARM64_FEATURE_MASK(ID_AA64DFR0_DEBUGVER);
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b1b6c40..f2afe9a 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -7,6 +7,7 @@ BTI
 HAS_32BIT_EL0_DO_NOT_USE
 HAS_32BIT_EL1
 HAS_ADDRESS_AUTH
+HAS_ADDRESS_AUTH_ARCH_QARMA3
 HAS_ADDRESS_AUTH_ARCH_QARMA5
 HAS_ADDRESS_AUTH_IMP_DEF
 HAS_AMU_EXTN
@@ -21,6 +22,7 @@ HAS_E0PD
 HAS_ECV
 HAS_EPAN
 HAS_GENERIC_AUTH
+HAS_GENERIC_AUTH_ARCH_QARMA3
 HAS_GENERIC_AUTH_ARCH_QARMA5
 HAS_GENERIC_AUTH_IMP_DEF
 HAS_IRQ_PRIO_MASKING
-- 
2.7.4



From patchwork-bot+netdevbpf at kernel.org  Thu Jan 27 06:00:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 27 Jan 2022 14:00:10 +0000
Subject: [PATCH] net: stmmac: dwmac-sun8i: use return val of
 readl_poll_timeout()
In-Reply-To: <20220126165215.1921-1-jszhang@kernel.org>
References: <20220126165215.1921-1-jszhang@kernel.org>
Message-ID: <164329201085.13469.12025143259464894463.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Thu, 27 Jan 2022 00:52:15 +0800 you wrote:
> When readl_poll_timeout() timeout, we'd better directly use its return
> value.
> 
> Before this patch:
> [    2.145528] dwmac-sun8i: probe of 4500000.ethernet failed with error -14
> 
> After this patch:
> [    2.138520] dwmac-sun8i: probe of 4500000.ethernet failed with error -110
> 
> [...]

Here is the summary with links:
  - net: stmmac: dwmac-sun8i: use return val of readl_poll_timeout()
    https://git.kernel.org/netdev/net/c/9e0db41e7a0b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Thu Jan 27 06:00:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Thu, 27 Jan 2022 14:00:10 +0000
Subject: [PATCH net 0/2] Fix PTP issue in stmmac
In-Reply-To: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
References: <20220126094723.11849-1-mohammad.athari.ismail@intel.com>
Message-ID: <164329201072.13469.12879802019146922568.git-patchwork-notify@kernel.org>

Hello:

This series was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Wed, 26 Jan 2022 17:47:21 +0800 you wrote:
> This patch series to fix PTP issue in stmmac related to:
> 1/ PTP clock source configuration during initialization.
> 2/ PTP initialization during resume from suspend.
> 
> Mohammad Athari Bin Ismail (2):
>   net: stmmac: configure PTP clock source prior to PTP initialization
>   net: stmmac: skip only stmmac_ptp_register when resume from suspend
> 
> [...]

Here is the summary with links:
  - [net,1/2] net: stmmac: configure PTP clock source prior to PTP initialization
    https://git.kernel.org/netdev/net/c/94c82de43e01
  - [net,v3,2/2] net: stmmac: skip only stmmac_ptp_register when resume from suspend
    https://git.kernel.org/netdev/net/c/0735e639f129

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From robh at kernel.org  Thu Jan 27 06:03:05 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Jan 2022 08:03:05 -0600
Subject: [PATCH] dt-bindings: net: convert net/cortina,
 gemini-ethernet to yaml
In-Reply-To: <20220126211128.3663486-1-clabbe@baylibre.com>
References: <20220126211128.3663486-1-clabbe@baylibre.com>
Message-ID: <1643292185.221187.3149357.nullmailer@robh.at.kernel.org>

On Wed, 26 Jan 2022 21:11:28 +0000, Corentin Labbe wrote:
> Converts net/cortina,gemini-ethernet.txt to yaml
> This permits to detect some missing properties like interrupts
> 
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
> ---
>  .../bindings/net/cortina,gemini-ethernet.txt  |  92 ------------
>  .../bindings/net/cortina,gemini-ethernet.yaml | 138 ++++++++++++++++++
>  2 files changed, 138 insertions(+), 92 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt
>  create mode 100644 Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml: patternProperties:^ethernet-port@[0-9]+$:properties:reg: 'oneOf' conditional failed, one must be fixed:
	[{'description': 'DMA/TOE memory'}, {'description': 'GMAC memory area of the port'}] is too long
	[{'description': 'DMA/TOE memory'}, {'description': 'GMAC memory area of the port'}] is too short
	False schema does not allow 2
	1 was expected
	hint: "minItems" is only needed if less than the "items" list length
	from schema $id: http://devicetree.org/meta-schemas/items.yaml#
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/net/cortina,gemini-ethernet.yaml: ignoring, error in schema: patternProperties: ^ethernet-port@[0-9]+$: properties: reg
Documentation/devicetree/bindings/net/cortina,gemini-ethernet.example.dt.yaml:0:0: /example-0/ethernet at 60000000: failed to match any schema with compatible: ['cortina,gemini-ethernet']
Documentation/devicetree/bindings/net/cortina,gemini-ethernet.example.dt.yaml:0:0: /example-0/ethernet at 60000000/ethernet-port at 0: failed to match any schema with compatible: ['cortina,gemini-ethernet-port']
Documentation/devicetree/bindings/net/cortina,gemini-ethernet.example.dt.yaml:0:0: /example-0/ethernet at 60000000/ethernet-port at 1: failed to match any schema with compatible: ['cortina,gemini-ethernet-port']

doc reference errors (make refcheckdocs):
MAINTAINERS: Documentation/devicetree/bindings/net/cortina,gemini-ethernet.txt

See https://patchwork.ozlabs.org/patch/1584680

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From robh at kernel.org  Thu Jan 27 06:03:05 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Jan 2022 08:03:05 -0600
Subject: [PATCH v3] dt-bindings: nvmem: convert mtk-efuse.txt to YAML
 schema
In-Reply-To: <20220127085930.15637-1-chunfeng.yun@mediatek.com>
References: <20220127085930.15637-1-chunfeng.yun@mediatek.com>
Message-ID: <1643292185.232142.3149360.nullmailer@robh.at.kernel.org>

On Thu, 27 Jan 2022 16:59:30 +0800, Chunfeng Yun wrote:
> Convert mtk-efuse.txt to YAML schema mediatek,efuse.yaml
> 
> Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
> Reviewed-by: Rob Herring <robh at kernel.org>
> ---
> v3: add reviewed-by Rob
> 
> v2:
>   1. remove description of subnodes which is covered by nvmem.yaml suggested by Rob
>   2. change the example which is commoner than mt8173's
> ---
>  .../bindings/nvmem/mediatek,efuse.yaml        | 86 +++++++++++++++++++
>  .../devicetree/bindings/nvmem/mtk-efuse.txt   | 43 ----------
>  2 files changed, 86 insertions(+), 43 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/nvmem/mediatek,efuse.yaml
>  delete mode 100644 Documentation/devicetree/bindings/nvmem/mtk-efuse.txt
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/nvmem/mediatek,efuse.example.dts:25.43-28.15: Warning (unique_unit_address_if_enabled): /example-0/efuse at 11c10000/usb3-tx-imp at 184: duplicate unit-address (also used in node /example-0/efuse at 11c10000/usb3-rx-imp at 184)
Documentation/devicetree/bindings/nvmem/mediatek,efuse.example.dts:37.45-40.15: Warning (unique_unit_address_if_enabled): /example-0/efuse at 11c10000/usb3-tx-imp at 186: duplicate unit-address (also used in node /example-0/efuse at 11c10000/usb3-rx-imp at 186)
Documentation/devicetree/bindings/nvmem/mediatek,efuse.example.dts:49.42-52.15: Warning (unique_unit_address_if_enabled): /example-0/efuse at 11c10000/usb2-intr-p0 at 188: duplicate unit-address (also used in node /example-0/efuse at 11c10000/usb2-intr-p1 at 188)

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1584864

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From abel.vesa at nxp.com  Thu Jan 27 06:10:52 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu, 27 Jan 2022 16:10:52 +0200
Subject: [PATCH 2/2] clk: imx: Remove audio_mclk_root_clk
In-Reply-To: <20220127141052.1900174-1-abel.vesa@nxp.com>
References: <20220127141052.1900174-1-abel.vesa@nxp.com>
Message-ID: <20220127141052.1900174-2-abel.vesa@nxp.com>

The audio_mclk_root_clk was added as a gate with the CCGR121 (0x4790),
but according to the reference manual, there is no such gate. The
CCGR121 belongs to ECSPI2 and it is not shared.

Fixes: 8f6d8094b215b57 ("ARM: imx: add imx7d clk tree support")
Reported-by: David Wolfe <david.wolfe at nxp.com>
Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 drivers/clk/imx/clk-imx7d.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index c4e0f1c07192..3f6fd7ef2a68 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -849,7 +849,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
 	hws[IMX7D_WDOG4_ROOT_CLK] = imx_clk_hw_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
 	hws[IMX7D_KPP_ROOT_CLK] = imx_clk_hw_gate4("kpp_root_clk", "ipg_root_clk", base + 0x4aa0, 0);
 	hws[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_hw_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
-	hws[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_hw_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
 	hws[IMX7D_WRCLK_ROOT_CLK] = imx_clk_hw_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
 	hws[IMX7D_USB_CTRL_CLK] = imx_clk_hw_gate4("usb_ctrl_clk", "ahb_root_clk", base + 0x4680, 0);
 	hws[IMX7D_USB_PHY1_CLK] = imx_clk_hw_gate4("usb_phy1_clk", "pll_usb1_main_clk", base + 0x46a0, 0);
-- 
2.31.1



From abel.vesa at nxp.com  Thu Jan 27 06:10:51 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Thu, 27 Jan 2022 16:10:51 +0200
Subject: [PATCH 1/2] arm: dts: imx7: Use audio_mclk_post_div instead
 audio_mclk_root_clk
Message-ID: <20220127141052.1900174-1-abel.vesa@nxp.com>

The audio_mclk_root_clk was added as a gate with the CCGR121 (0x4790),
but according to the reference manual, there is no such gate. Moreover,
the consumer driver of the mentioned clock might gate it and leave
the ECSPI2 (the true owner of that gate) hanging. So lets use the
audio_mclk_post_div, which is the parent.

Signed-off-by: Abel Vesa <abel.vesa at nxp.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi     | 4 ++--
 arch/arm/boot/dts/imx7-mba7.dtsi        | 2 +-
 arch/arm/boot/dts/imx7d-nitrogen7.dts   | 2 +-
 arch/arm/boot/dts/imx7d-pico-hobbit.dts | 4 ++--
 arch/arm/boot/dts/imx7d-pico-pi.dts     | 4 ++--
 arch/arm/boot/dts/imx7d-sdb.dts         | 4 ++--
 arch/arm/boot/dts/imx7s-warp.dts        | 4 ++--
 7 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 62b771c1d5a9..f1c60b0cb143 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -40,7 +40,7 @@ simple-audio-card,cpu {
 
 		dailink_master: simple-audio-card,codec {
 			sound-dai = <&codec>;
-			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		};
 	};
 };
@@ -293,7 +293,7 @@ codec: sgtl5000 at a {
 		compatible = "fsl,sgtl5000";
 		#sound-dai-cells = <0>;
 		reg = <0x0a>;
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_sai1_mclk>;
 		VDDA-supply = <&reg_module_3v3_avdd>;
diff --git a/arch/arm/boot/dts/imx7-mba7.dtsi b/arch/arm/boot/dts/imx7-mba7.dtsi
index 49086c6b6a0a..3df6dff7734a 100644
--- a/arch/arm/boot/dts/imx7-mba7.dtsi
+++ b/arch/arm/boot/dts/imx7-mba7.dtsi
@@ -302,7 +302,7 @@ &i2c2 {
 	tlv320aic32x4: audio-codec at 18 {
 		compatible = "ti,tlv320aic32x4";
 		reg = <0x18>;
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		clock-names = "mclk";
 		ldoin-supply = <&reg_audio_3v3>;
 		iov-supply = <&reg_audio_3v3>;
diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts
index e0751e6ba3c0..a31de900139d 100644
--- a/arch/arm/boot/dts/imx7d-nitrogen7.dts
+++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts
@@ -288,7 +288,7 @@ &i2c4 {
 	codec: wm8960 at 1a {
 		compatible = "wlf,wm8960";
 		reg = <0x1a>;
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		clock-names = "mclk";
 		wlf,shared-lrclk;
 	};
diff --git a/arch/arm/boot/dts/imx7d-pico-hobbit.dts b/arch/arm/boot/dts/imx7d-pico-hobbit.dts
index 7b2198a9372c..d917dc4f2f22 100644
--- a/arch/arm/boot/dts/imx7d-pico-hobbit.dts
+++ b/arch/arm/boot/dts/imx7d-pico-hobbit.dts
@@ -31,7 +31,7 @@ simple-audio-card,cpu {
 
 		dailink_master: simple-audio-card,codec {
 			sound-dai = <&sgtl5000>;
-			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		};
 	};
 };
@@ -41,7 +41,7 @@ sgtl5000: codec at a {
 		#sound-dai-cells = <0>;
 		reg = <0x0a>;
 		compatible = "fsl,sgtl5000";
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		VDDA-supply = <&reg_2p5v>;
 		VDDIO-supply = <&reg_vref_1v8>;
 	};
diff --git a/arch/arm/boot/dts/imx7d-pico-pi.dts b/arch/arm/boot/dts/imx7d-pico-pi.dts
index 70bea95c06d8..f263e391e24c 100644
--- a/arch/arm/boot/dts/imx7d-pico-pi.dts
+++ b/arch/arm/boot/dts/imx7d-pico-pi.dts
@@ -31,7 +31,7 @@ simple-audio-card,cpu {
 
 		dailink_master: simple-audio-card,codec {
 			sound-dai = <&sgtl5000>;
-			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		};
 	};
 };
@@ -41,7 +41,7 @@ sgtl5000: codec at a {
 		#sound-dai-cells = <0>;
 		reg = <0x0a>;
 		compatible = "fsl,sgtl5000";
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		VDDA-supply = <&reg_2p5v>;
 		VDDIO-supply = <&reg_vref_1v8>;
 	};
diff --git a/arch/arm/boot/dts/imx7d-sdb.dts b/arch/arm/boot/dts/imx7d-sdb.dts
index 7813ef960f6e..f053f5122741 100644
--- a/arch/arm/boot/dts/imx7d-sdb.dts
+++ b/arch/arm/boot/dts/imx7d-sdb.dts
@@ -385,14 +385,14 @@ &i2c4 {
 	codec: wm8960 at 1a {
 		compatible = "wlf,wm8960";
 		reg = <0x1a>;
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		clock-names = "mclk";
 		wlf,shared-lrclk;
 		wlf,hp-cfg = <2 2 3>;
 		wlf,gpio-cfg = <1 3>;
 		assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
 				  <&clks IMX7D_PLL_AUDIO_POST_DIV>,
-				  <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+				  <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
 		assigned-clock-rates = <0>, <884736000>, <12288000>;
 	};
diff --git a/arch/arm/boot/dts/imx7s-warp.dts b/arch/arm/boot/dts/imx7s-warp.dts
index 4f1edef06c92..e8734d218b9d 100644
--- a/arch/arm/boot/dts/imx7s-warp.dts
+++ b/arch/arm/boot/dts/imx7s-warp.dts
@@ -75,7 +75,7 @@ simple-audio-card,cpu {
 
 		dailink_master: simple-audio-card,codec {
 			sound-dai = <&codec>;
-			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+			clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		};
 	};
 };
@@ -232,7 +232,7 @@ codec: sgtl5000 at a {
 		#sound-dai-cells = <0>;
 		reg = <0x0a>;
 		compatible = "fsl,sgtl5000";
-		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
+		clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_sai1_mclk>;
 		VDDA-supply = <&vgen4_reg>;
-- 
2.31.1



From a.kartashev at yadro.com  Thu Jan 27 06:16:04 2022
From: a.kartashev at yadro.com (Andrei Kartashev)
Date: Thu, 27 Jan 2022 17:16:04 +0300
Subject: [PATCH v2] ARM: dts: aspeed: vegman: remove beeper
Message-ID: <20220127141604.1163-1-a.kartashev@yadro.com>

Beeper definition is a leftover from internal fork and not actual for
upstream kernel. It could be removed both beeper node and corresponded
timer node.
Fixes: 67ac01d03862 ("ARM: dts: aspeed: add device tree for YADRO VEGMAN BMC")

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
Signed-off-by: Andrei Kartashev <a.kartashev at yadro.com>
---
 arch/arm/boot/dts/aspeed-bmc-vegman.dtsi | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
index 1a5b25b2ea29..8ee4e6aab40e 100644
--- a/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
+++ b/arch/arm/boot/dts/aspeed-bmc-vegman.dtsi
@@ -79,11 +79,6 @@ power_ok {
 			gpios = <&gpio ASPEED_GPIO(AA, 5) GPIO_ACTIVE_LOW>;
 		};
 	};
-
-	beeper {
-		compatible = "pwm-beeper";
-		pwms = <&timer 5 1000000 0>;
-	};
 };
 
 &fmc {
@@ -165,14 +160,6 @@ &sdhci1 {
 	disable-wp;
 };
 
-&timer {
-	fttmr010,pwm-outputs = <5>;
-	pinctrl-names = "default";
-	pinctrl-0 = <&pinctrl_timer5_default>;
-	#pwm-cells = <3>;
-	status = "okay";
-};
-
 &uart1 {
 	status = "okay";
 	pinctrl-names = "default";
-- 
2.34.1



From michael.riesch at wolfvision.net  Thu Jan 27 06:16:22 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu, 27 Jan 2022 15:16:22 +0100
Subject: [PATCH v4 00/27] drm/rockchip: RK356x VOP2 support
In-Reply-To: <20220126145549.617165-1-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
Message-ID: <d0a0ddcd-43d0-fd48-7c9d-c4232b818212@wolfvision.net>

Hello Sascha,

On 1/26/22 15:55, Sascha Hauer wrote:
> This is v4 of adding RK356x VOP2 support. Due to popular demand I added
> a changelog to each patch, at least starting with changes to v3, I
> didn't care to add the older changes as well. I hopefully integrated all
> feedback I received to v3. Additionally I added some patches to the HDMI
> driver to support resolutions up to 4k at 60Hz. The patches are mostly
> taken from the downstream kernel. Some have been send to public lists,
> but were never applied upstream for reasons I do not know. The patches
> are a bit more intrusive than needed for my case, but are present in the
> downstream kernel for a long time, so I decided just to take them
> instead of stripping them down to my needs. With these patches I
> successfully used the driver with 4k at 30Hz. 4k at 60Hz doesn't work for me,
> I hope this is due to my low quality cable.

The cable might be the issue indeed, at least in my tests 4k at 60Hz worked
just fine. On a RK3568 EVB1, using

$ modetest -M rockchip -s 69:{1920x1080,3840x2160}-{30,60}

and a HP 27f 4K monitor:

Tested-by: Michael Riesch <michael.riesch at wolfvision.net>

Thanks for your work and best regards,
Michael

> 
> Sascha
> 
> Changes since v3:
> - added changelog to each patch
> - Add 4k support to hdmi driver
> - rebase on v5.17-rc1
> 
> Changes since v2:
> - Add pin names to HDMI supply pin description
> - Add hclk support to HDMI driver
> - Dual license rockchip-vop2 binding, update binding
> - Add HDMI connector to board dts files
> - drop unnecessary gamma_lut registers from vop2
> - Update dclk_vop[012] clock handling, no longer hacks needed
> - Complete regmap conversion
> 
> Changes since v1:
> - drop all unnecessary waiting for frames within atomic modeset and plane update
> - Cluster subwin support removed
> - gamma support removed
> - unnecessary irq_lock removed
> - interrupt handling simplified
> - simplified zpos handling
> - drop is_alpha_support(), use fb->format->has_alpha instead
> - use devm_regulator_get() rather than devm_regulator_get_optional() for hdmi regulators
> - Use fixed number of planes per video port
> - Drop homegrown regmap code from vop2 driver (not complete yet)
> - Add separate include file for vop2 driver to not pollute the vop include
> 
> Andy Yan (1):
>   drm: rockchip: Add VOP2 driver
> 
> Benjamin Gaignard (1):
>   dt-bindings: display: rockchip: dw-hdmi: Add compatible for rk3568
>     HDMI
> 
> Douglas Anderson (2):
>   drm/rockchip: dw_hdmi: Use auto-generated tables
>   drm/rockchip: dw_hdmi: Set cur_ctr to 0 always
> 
> Michael Riesch (1):
>   arm64: dts: rockchip: enable vop2 and hdmi tx on quartz64a
> 
> Nickey Yang (1):
>   drm/rockchip: dw_hdmi: add default 594Mhz clk for 4K at 60hz
> 
> Sascha Hauer (21):
>   drm/encoder: Add of_graph port to struct drm_encoder
>   drm/rockchip: dw_hdmi: Do not leave clock enabled in error case
>   drm/rockchip: dw_hdmi: rename vpll clock to reference clock
>   drm/rockchip: dw_hdmi: add rk3568 support
>   drm/rockchip: dw_hdmi: add regulator support
>   drm/rockchip: dw_hdmi: Add support for hclk
>   drm/rockchip: dw_hdmi: drop mode_valid hook
>   clk: rockchip: rk3568: Add more PLL rates
>   dt-bindings: display: rockchip: dw-hdmi: Make unwedge pinctrl optional
>   dt-bindings: display: rockchip: dw-hdmi: use "ref" as clock name
>   dt-bindings: display: rockchip: dw-hdmi: Add regulator support
>   dt-bindings: display: rockchip: dw-hdmi: Add additional clock
>   dt-bindings: display: rockchip: Add binding for VOP2
>   arm64: dts: rockchip: rk3399: reorder hmdi clocks
>   arm64: dts: rockchip: rk3399: rename HDMI ref clock to 'ref'
>   arm64: dts: rockchip: rk356x: Add VOP2 nodes
>   arm64: dts: rockchip: rk356x: Add HDMI nodes
>   arm64: dts: rockchip: rk3568-evb: Enable VOP2 and hdmi
>   clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop*
>   clk: rk3568: Add CLK_SET_RATE_PARENT to the HDMI reference clock
>   drm/rockchip: Make VOP driver optional
> 
>  .../display/rockchip/rockchip,dw-hdmi.yaml    |   29 +-
>  .../display/rockchip/rockchip-vop2.yaml       |  146 +
>  arch/arm64/boot/dts/rockchip/rk3399.dtsi      |    6 +-
>  .../boot/dts/rockchip/rk3566-quartz64-a.dts   |   48 +
>  arch/arm64/boot/dts/rockchip/rk3566.dtsi      |    4 +
>  .../boot/dts/rockchip/rk3568-evb1-v10.dts     |   48 +
>  arch/arm64/boot/dts/rockchip/rk3568.dtsi      |    4 +
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi      |   86 +
>  drivers/clk/rockchip/clk-rk3568.c             |   14 +-
>  drivers/gpu/drm/rockchip/Kconfig              |   14 +
>  drivers/gpu/drm/rockchip/Makefile             |    4 +-
>  drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c   |  293 +-
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |    3 +-
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.h   |    7 +-
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c    |    2 +
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h   |   15 +
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  | 2665 +++++++++++++++++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop2.h  |  480 +++
>  drivers/gpu/drm/rockchip/rockchip_vop2_reg.c  |  285 ++
>  include/drm/drm_encoder.h                     |    2 +
>  include/dt-bindings/soc/rockchip,vop2.h       |   14 +
>  21 files changed, 4039 insertions(+), 130 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
>  create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
>  create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
>  create mode 100644 drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
>  create mode 100644 include/dt-bindings/soc/rockchip,vop2.h
> 


From chunkuang.hu at kernel.org  Thu Jan 27 06:21:35 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 27 Jan 2022 22:21:35 +0800
Subject: [PATCH v2] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <4b46b8ce-7300-ef42-eb17-efd87ebdf773@collabora.com>
References: <20220104095954.10313-1-angelogioacchino.delregno@collabora.com>
 <CAMty3ZAojTyw3H8VprH9aiyTyWjeL8oqPxNNr=J33_5FrcUj9Q@mail.gmail.com>
 <4b46b8ce-7300-ef42-eb17-efd87ebdf773@collabora.com>
Message-ID: <CAAOTY_-FZ_pCpvZyNOcEMHOk1k5re51uGYY1jCxNxQuu7CQ-5A@mail.gmail.com>

Hi, Angelo:

AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
2022?1?27? ?? ??6:32???
>
> Il 12/01/22 08:09, Jagan Teki ha scritto:
> > On Tue, Jan 4, 2022 at 3:30 PM AngeloGioacchino Del Regno
> > <angelogioacchino.delregno at collabora.com> wrote:
> >>
> >> DRM bridge drivers are now attaching their DSI device at probe time,
> >> which requires us to register our DSI host in order to let the bridge
> >> to probe: this recently started producing an endless -EPROBE_DEFER
> >> loop on some machines that are using external bridges, like the
> >> parade-ps8640, found on the ACER Chromebook R13.
> >>
> >> Now that the DSI hosts/devices probe sequence is documented, we can
> >> do adjustments to the mtk_dsi driver as to both fix now and make sure
> >> to avoid this situation in the future: for this, following what is
> >> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> >> mtk_dsi_ops.attach callback and delete it in the detach callback;
> >> keeping in mind that we are registering a drm_bridge for our DSI,
> >> which is only used/attached if the DSI Host is bound, it wouldn't
> >> make sense to keep adding our bridge at probe time (as it would
> >> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> >> that one to the dsi host attach function (and remove it in detach).
> >>
> >> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> >> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> >> ---
> >
> > Eventually I've observed similar issue on other Component based DSI
> > controllers, hence
> >
> > Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
> >
>
> Hello dri-devel,
> can you please pick this patch?
>
> All MediaTek platforms are broken in v5.17 without this one.

Please add Fixes tag [1] to this patch.

[1] https://www.kernel.org/doc/html/v5.16/process/submitting-patches.html

Regards,
Chun-Kuang.

>
> Thanks,
> Angelo


From robh at kernel.org  Thu Jan 27 06:31:45 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Jan 2022 08:31:45 -0600
Subject: [RFC V1 06/11] arm64/perf: Drive BRBE from perf event states
In-Reply-To: <9e56509a-2772-a333-ccc3-ad49a2028616@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-7-git-send-email-anshuman.khandual@arm.com>
 <YfF/zBS3kL/+eC1k@robh.at.kernel.org>
 <9e56509a-2772-a333-ccc3-ad49a2028616@arm.com>
Message-ID: <CAL_JsqJXQqV3P=T8GXxDY2wReeYnLcBqge139fUUXLtcQJe=6w@mail.gmail.com>

On Thu, Jan 27, 2022 at 6:20 AM Anshuman Khandual
<anshuman.khandual at arm.com> wrote:
>
>
> On 1/26/22 10:37 PM, Rob Herring wrote:
> > On Mon, Jan 24, 2022 at 10:00:48AM +0530, Anshuman Khandual wrote:
> >> Branch stack sampling rides along the normal perf event and all the branch
> >> records get captured during the PMU interrupt. This just changes perf event
> >> handling on the arm64 platform to accommodate required BRBE operations that
> >> will enable branch stack sampling support.
> >>
> >> Cc: Peter Zijlstra <peterz at infradead.org>
> >> Cc: Ingo Molnar <mingo at redhat.com>
> >> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
> >> Cc: Mark Rutland <mark.rutland at arm.com>
> >> Cc: Will Deacon <will at kernel.org>
> >> Cc: Catalin Marinas <catalin.marinas at arm.com>
> >> Cc: linux-perf-users at vger.kernel.org
> >> Cc: linux-kernel at vger.kernel.org
> >> Cc: linux-arm-kernel at lists.infradead.org
> >> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
> >> ---
> >>  arch/arm64/kernel/perf_event.c |  6 +++++
> >>  drivers/perf/arm_pmu.c         | 40 ++++++++++++++++++++++++++++++++++
> >>  2 files changed, 46 insertions(+)
> >>
> >> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
> >> index f6a47036b0b4..11c82c8f2eec 100644
> >> --- a/arch/arm64/kernel/perf_event.c
> >> +++ b/arch/arm64/kernel/perf_event.c
> >> @@ -864,6 +864,12 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu)
> >>              if (!armpmu_event_set_period(event))
> >>                      continue;
> >>
> >> +            if (has_branch_stack(event)) {
> >> +                    cpu_pmu->brbe_read(cpuc, event);
> >
> > Is has_branch_stack() guaranteed to be false on arm32? If not, this will
> > be a NULL function ptr.
>
> armpmu_event_init() blocks a perf event from being created with branch
> stack sampling request without CONFIG_ARM_BRBE_PMU option being enabled
> first, which has dependency on CONFIG_ARM64. So has_branch_stack() is
> guaranteed to be false on arm32.

Then the stub functions in patch 3 are also not needed. The fact that
you create dummy functions makes it look like you can't have NULL
function ptrs, but you don't. This is what I mean about the structure
of the series being hard to review.

> static int armpmu_event_init(struct perf_event *event)
> {
>         ....
>         if (has_branch_stack(event)) {
>                 /*
>                  * BRBE support is absent. Select CONFIG_ARM_BRBE_PMU
>                  * in the config, before branch stack sampling events
>                  * can be requested.
>                  */
>                 if (!IS_ENABLED(CONFIG_ARM_BRBE_PMU)) {
>                         pr_warn_once("BRBE is disabled, select CONFIG_ARM_BRBE_PMU\n");
>                         return -EOPNOTSUPP;
>                 }
>
>
> config ARM_BRBE_PMU
>         tristate "Enable support for Branch Record Buffer Extension (BRBE)"
>         depends on ARM64 && ARM_PMU
>         default y
>         help
>           Enable perf support for Branch Record Buffer Extension (BRBE) which
>           records all branches taken in an execution path. This supports some
>           branch types and privilege based filtering. It captured additional
>           relevant information such as cycle count, misprediction and branch
>           type, branch privilege level etc.
>
> >
> > To add to my other comments, this patch is where I would add
> > brbe_read(), etc. to arm_pmu.
>
> Because all new arm_pmu helpers get added and get used in the perf driver
> in the same patch, although the actual helper implementation would still
> come by bit later via the driver. This also uses updates to pmu_hw_events
> struct as well, then that patch needs to be folded here as well.
>
> There is no problem as such, kind of bit subjective. I just feel inclined
> to keep the independent infrastructure changes separate making it easy to
> review while also creating a flow.

Everything about kernel development is subjective until it's a
requirement by the maintainer. I'm not here, so it's just advice.

Rob


From robh at kernel.org  Thu Jan 27 06:35:31 2022
From: robh at kernel.org (Rob Herring)
Date: Thu, 27 Jan 2022 08:35:31 -0600
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
In-Reply-To: <1jtudp1rc1.fsf@starbuckisacylon.baylibre.com>
References: <20220126231427.1638089-1-robh@kernel.org>
 <1jtudp1rc1.fsf@starbuckisacylon.baylibre.com>
Message-ID: <CAL_JsqL77E+5ftqgHPdWQzfp98Oh3d=QZRQ8Z6v91OfSeprxig@mail.gmail.com>

On Thu, Jan 27, 2022 at 3:05 AM Jerome Brunet <jbrunet at baylibre.com> wrote:
>
>
> On Wed 26 Jan 2022 at 17:14, Rob Herring <robh at kernel.org> wrote:
>
> > 'sound-dai' is a common property, but has duplicate type definitions.
> > Create a new common definition to define the type and then update all
> > the other occurrences to just define how many entries there are just
> > like other phandle+arg properties.
> >
> > The constraints on the number of entries is based on the examples and
> > could be wrong.
> >
> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> > Signed-off-by: Rob Herring <robh at kernel.org>
> > ---
> > Please ack, this depends on commit abf0fee97313 ("dt-bindings: Improve
> > phandle-array schemas") in my tree.
> > ---
> >  .../bindings/sound/amlogic,gx-sound-card.yaml |  4 ++--
> >  .../bindings/sound/google,sc7180-trogdor.yaml |  6 ++++--
> >  .../bindings/sound/imx-audio-card.yaml        |  7 +++++--
> >  .../bindings/sound/qcom,sm8250.yaml           | 10 +++++++---
> >  .../bindings/sound/samsung,aries-wm8994.yaml  |  5 +----
> >  .../bindings/sound/samsung,midas-audio.yaml   |  2 --
> >  .../bindings/sound/samsung,odroid.yaml        |  9 +++------
> >  .../devicetree/bindings/sound/sound-dai.yaml  | 20 +++++++++++++++++++
> >  8 files changed, 42 insertions(+), 21 deletions(-)
> >  create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> > index 2e35aeaa8781..8b5be4b92f35 100644
> > --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> > +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
> > @@ -57,7 +57,7 @@ patternProperties:
> >            rate
> >
> >        sound-dai:
> > -        $ref: /schemas/types.yaml#/definitions/phandle-array
> > +        maxItems: 1
> >          description: phandle of the CPU DAI
> >
> >      patternProperties:
> > @@ -71,7 +71,7 @@ patternProperties:
> >
> >          properties:
> >            sound-dai:
> > -            $ref: /schemas/types.yaml#/definitions/phandle-array
> > +            maxItems: 1
>
> No min or max here. Links may have more than one codec.
>
> Ex:
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#n158

What do you mean? Every 'sound-dai' there only has 1 phande+args. Each
codec is a child node.

Rob


From angelogioacchino.delregno at collabora.com  Thu Jan 27 06:36:23 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 15:36:23 +0100
Subject: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
Message-ID: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>

DRM bridge drivers are now attaching their DSI device at probe time,
which requires us to register our DSI host in order to let the bridge
to probe: this recently started producing an endless -EPROBE_DEFER
loop on some machines that are using external bridges, like the
parade-ps8640, found on the ACER Chromebook R13.

Now that the DSI hosts/devices probe sequence is documented, we can
do adjustments to the mtk_dsi driver as to both fix now and make sure
to avoid this situation in the future: for this, following what is
documented in drm_bridge.c, move the mtk_dsi component_add() to the
mtk_dsi_ops.attach callback and delete it in the detach callback;
keeping in mind that we are registering a drm_bridge for our DSI,
which is only used/attached if the DSI Host is bound, it wouldn't
make sense to keep adding our bridge at probe time (as it would
be useless to have it if mtk_dsi_ops.attach() fails!), so also move
that one to the dsi host attach function (and remove it in detach).

Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
 1 file changed, 84 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..bced4c7d668e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
 	mtk_dsi_poweroff(dsi);
 }
 
+static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
+{
+	int ret;
+
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		DRM_ERROR("Failed to encoder init to drm\n");
+		return ret;
+	}
+
+	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
+
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret)
+		goto err_cleanup_encoder;
+
+	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
+	if (IS_ERR(dsi->connector)) {
+		DRM_ERROR("Unable to create bridge connector\n");
+		ret = PTR_ERR(dsi->connector);
+		goto err_cleanup_encoder;
+	}
+	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
+
+	return 0;
+
+err_cleanup_encoder:
+	drm_encoder_cleanup(&dsi->encoder);
+	return ret;
+}
+
+static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	int ret;
+	struct drm_device *drm = data;
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	ret = mtk_dsi_encoder_init(drm, dsi);
+	if (ret)
+		return ret;
+
+	return device_reset_optional(dev);
+}
+
+static void mtk_dsi_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	drm_encoder_cleanup(&dsi->encoder);
+}
+
+static const struct component_ops mtk_dsi_component_ops = {
+	.bind = mtk_dsi_bind,
+	.unbind = mtk_dsi_unbind,
+};
+
 static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 			       struct mipi_dsi_device *device)
 {
 	struct mtk_dsi *dsi = host_to_dsi(host);
+	struct device *dev = host->dev;
+	int ret;
 
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
+	dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
+	if (IS_ERR(dsi->next_bridge))
+		return PTR_ERR(dsi->next_bridge);
+
+	drm_bridge_add(&dsi->bridge);
+
+	ret = component_add(host->dev, &mtk_dsi_component_ops);
+	if (ret) {
+		DRM_ERROR("failed to add dsi_host component: %d\n", ret);
+		drm_bridge_remove(&dsi->bridge);
+		return ret;
+	}
 
 	return 0;
 }
 
+static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
+			       struct mipi_dsi_device *device)
+{
+	struct mtk_dsi *dsi = host_to_dsi(host);
+
+	component_del(host->dev, &mtk_dsi_component_ops);
+	drm_bridge_remove(&dsi->bridge);
+	return 0;
+}
+
 static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
 {
 	int ret;
@@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 
 static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.attach = mtk_dsi_host_attach,
+	.detach = mtk_dsi_host_detach,
 	.transfer = mtk_dsi_host_transfer,
 };
 
-static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
-{
-	int ret;
-
-	ret = drm_simple_encoder_init(drm, &dsi->encoder,
-				      DRM_MODE_ENCODER_DSI);
-	if (ret) {
-		DRM_ERROR("Failed to encoder init to drm\n");
-		return ret;
-	}
-
-	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
-
-	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
-				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-	if (ret)
-		goto err_cleanup_encoder;
-
-	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
-	if (IS_ERR(dsi->connector)) {
-		DRM_ERROR("Unable to create bridge connector\n");
-		ret = PTR_ERR(dsi->connector);
-		goto err_cleanup_encoder;
-	}
-	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
-
-	return 0;
-
-err_cleanup_encoder:
-	drm_encoder_cleanup(&dsi->encoder);
-	return ret;
-}
-
-static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
-{
-	int ret;
-	struct drm_device *drm = data;
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	ret = mtk_dsi_encoder_init(drm, dsi);
-	if (ret)
-		return ret;
-
-	return device_reset_optional(dev);
-}
-
-static void mtk_dsi_unbind(struct device *dev, struct device *master,
-			   void *data)
-{
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	drm_encoder_cleanup(&dsi->encoder);
-}
-
-static const struct component_ops mtk_dsi_component_ops = {
-	.bind = mtk_dsi_bind,
-	.unbind = mtk_dsi_unbind,
-};
-
 static int mtk_dsi_probe(struct platform_device *pdev)
 {
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
-	struct drm_panel *panel;
 	struct resource *regs;
 	int irq_num;
 	int ret;
@@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &panel, &dsi->next_bridge);
-	if (ret)
-		goto err_unregister_host;
-
-	if (panel) {
-		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
-		if (IS_ERR(dsi->next_bridge)) {
-			ret = PTR_ERR(dsi->next_bridge);
-			goto err_unregister_host;
-		}
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.of_node = dev->of_node;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
-	drm_bridge_add(&dsi->bridge);
-
-	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to add component: %d\n", ret);
-		goto err_unregister_host;
-	}
-
 	return 0;
 
 err_unregister_host:
@@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
 	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
 
 	mtk_output_dsi_disable(dsi);
-	drm_bridge_remove(&dsi->bridge);
-	component_del(&pdev->dev, &mtk_dsi_component_ops);
 	mipi_dsi_host_unregister(&dsi->host);
 
 	return 0;
-- 
2.33.1



From piotr.oniszczuk at gmail.com  Thu Jan 27 06:43:24 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Thu, 27 Jan 2022 15:43:24 +0100
Subject: [PATCH 27/27] drm: rockchip: Add VOP2 driver
In-Reply-To: <20220127110009.GK23490@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-28-s.hauer@pengutronix.de>
 <6588D77C-D3CB-4FB0-8B00-5EDD6ABD6923@gmail.com>
 <20220127110009.GK23490@pengutronix.de>
Message-ID: <6E75EF52-3ED6-4E53-9DE3-DBEAA7BFD005@gmail.com>



> Wiadomo?? napisana przez Sascha Hauer <s.hauer at pengutronix.de> w dniu 27.01.2022, o godz. 12:00:
> 
>> 
>> -on rk3399 it gives me 4k screen where right vertical 1/3 part of screen is garbage
>> -on rk3566 my samsung 4k monitor has black screen and cycle of OSD msgs: HDMI2 connected; HDMI2 disconnected; ....
> 
> Same here on my rk3568, also with a samsung monitor. Was it 4k at 60Hz or
> 4k at 30Hz? If the former, could you give 4k at 30Hz a try? That mode works
> well here.

It was 4k at 30
Indeed - firmware of my samsung is total crap in UI aspects - so maybe in hdmi modes are as well :-p
Anyway - this crap monitor works ok with 4k at 30 on AW/RPI4/rk3399/n3450/MacBookPro

>> 
>> BTW: getting well working 4k HDMI modes on rk3399 was real story for me.
>> There is many different series of patches to address this - but all have some subtle issues for me (i.e. 4k HDMI modes works but i.e. Qt is failing with DRM atomic commits in EGLFS)
>> I developed well working [1] giving me reliable 4k on rk3399 (including working Qt DRM drawing in EGLFS mode) 
>> Maybe it will be somehow helpful to get 4k modes solution for rk3566 _and_ rk3399 (on single kernel binary)?
>> 
>> [1] https://github.com/warpme/minimyth2/blob/master/script/kernel/linux-5.16/files/0730-drm-rockchip-add-4k-videomodes-support.patch
> 
> At least there are patches in it that I have in my series as well and
> keep popping up everywhere like "drm/rockchip: dw_hdmi: Use
> auto-generated tables" and "drm/rockchip: dw_hdmi: Set cur_ctr to 0
> always"
> 

What was time-consuming for me was finding working patches combination which not breaks Qt DRM Atomic commits.
Many series floating arround various git repos/projects were offering 4k modes but breaking Qt in the same time....

btw: have you plans to look/address non-working DRM planes in VOP2?
Rendering to DRM plane gives me green screen on rk3566.
The same code (and binaries) are working ok on rk3399 (and other SoCs).
 
 

From james.morse at arm.com  Thu Jan 27 06:45:21 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 14:45:21 +0000
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
 <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
Message-ID: <680e7a1d-32e4-bf57-d519-a5df2117f94b@arm.com>

Hi Ard,

On 27/01/2022 12:39, Ard Biesheuvel wrote:
> On Thu, 27 Jan 2022 at 13:29, James Morse <james.morse at arm.com> wrote:
>>
>> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
>> occurs between a pair of AES instructions in aarch32 mode may corrupt
>> the ELR. The task will subsequently produce the wrong AES result.
>>
>> The AES instructions are part of the cryptographic extensions, which are
>> optional. User-space software will detect the support for these
>> instructions from the hwcaps. If the platform doesn't support these
>> instructions a software implementation should be used.
>>
>> Remove the hwcap bits on affected parts to indicate user-space should
>> not use the AES instructions.

> For this patch,
> 
> Acked-by: Ard Biesheuvel <ardb at kernel.org>

Thanks!

> but I will note that
> - depending on the C library used, OpenSSL may use SIGILL trapping to
> decide whether these instructions are implemented or not,

I'd argue that such software is already broken on big/little system.
If it tries on a CPU that has a feature, than migrates to one that doesn't, all bets are off.


> - the 32-bit kernel should ideally adopt the same approach,

I've had a stab at that, it will take me a little while to test it...


> Fortunately, the only A72 that is known to be widely deployed with
> 32-bit kernels and/or user space is the Raspberry Pi 4, which does not
> implement the crypto extensions.

Ah, I didn't know folk ran 32bit kernels on these.



Thanks,

James


From szabolcs.nagy at arm.com  Thu Jan 27 06:48:20 2022
From: szabolcs.nagy at arm.com (Szabolcs Nagy)
Date: Thu, 27 Jan 2022 14:48:20 +0000
Subject: [PATCH v7 0/4] arm64: Enable BTI for the executable as well as
 the interpreter
In-Reply-To: <YfKO7r5l7AUvd8r/@arm.com>
References: <YdSEkt72V1oeVx5E@sirena.org.uk>
 <101d8e84-7429-bbf1-0271-5436eca0eea2@arm.com>
 <YdbL5kIzi0xqVTVd@arm.com>
 <8550afd2-268d-a25f-88fd-0dd0b184ca23@arm.com>
 <YdcxUZ06f60UQMKM@arm.com> <Ydc+AuagOD9GSooP@sirena.org.uk>
 <YdgrjWVxRGRtnf5b@arm.com> <YeWtRk0H30q38eM8@arm.com>
 <20220118110255.GC3294453@arm.com> <YfKO7r5l7AUvd8r/@arm.com>
Message-ID: <20220127144820.GF1989194@arm.com>

The 01/27/2022 12:24, Catalin Marinas wrote:
> (Mark posted another series but I'm replying here to clarify some
> aspects)
> 
> On Tue, Jan 18, 2022 at 11:02:55AM +0000, Szabolcs Nagy wrote:
> > The 01/17/2022 17:54, Catalin Marinas wrote:
> > > On Fri, Jan 07, 2022 at 12:01:17PM +0000, Catalin Marinas wrote:
> > > > I think we can look at this from two angles:
> > > > 
> > > > 1. Ignoring MDWE, should whoever does the original mmap() also honour
> > > >    PROT_BTI? We do this for static binaries but, for consistency, should
> > > >    we extend it to dynamic executable?
> > > > 
> > > > 2. A 'simple' fix to allow MDWE together with BTI.
> > > 
> > > Thinking about it, (1) is not that different from the kernel setting
> > > PROT_EXEC on the main executable when the dynamic loader could've done
> > > it as well. There is a case for making this more consistent: whoever
> > > does the mmap() should use the full attributes.
> > 
> > Yeah that was my original idea that it should be consistent.
> > One caveat is that protection flags are normally specified
> > in the program header, but the BTI marking is in
> > PT_GNU_PROPERTY which is harder to get to, so glibc does not
> > try to get it right for the initial mapping either: it has
> > to re-mmap or mprotect. (In principle we could use read
> > syscalls to parse the ELF headers and notes before mmap,
> > but that's more complicated with additional failure modes.)
> > 
> > i.e. if (2) is fixed then mprotect can be used for library
> > mapping too which is simpler than re-mmap.
> 
> I lost track of the userspace fixes here, was glibc changed to attempt a
> re-mmap of the dynamic libraries instead of mprotect()?

yes (so under mdwe, bti is lost on the exe but not on libs)

see the commit message for the fix
https://sourceware.org/bugzilla/show_bug.cgi?id=26831

> 
> It looks like (2) is a simpler fix and (1) could still be added for
> consistency, it's complementary.

i agree.

if (2) is fixed then i would change glibc to use
mprotect and handle the failure (this will require an
update to systemd and disabling mdwe on old kernels)

if (1) is fixed then i would probably still keep
doing mprotect on the main exe so bti protection
works on old kernels.



From arnd at arndb.de  Thu Jan 27 06:52:24 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 27 Jan 2022 15:52:24 +0100
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
 <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
Message-ID: <CAK8P3a0oaP8LzxX6TSYhmSV+s+5rjHeCRzQ-pXkMQvpGvrp_0Q@mail.gmail.com>

On Thu, Jan 27, 2022 at 1:39 PM Ard Biesheuvel <ardb at kernel.org> wrote:
> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
> occurs between a pair of AES instructions in aarch32 mode may corrupt
> the ELR. The task will subsequently produce the wrong AES result.

> Fortunately, the only A72 that is known to be widely deployed with
> 32-bit kernels and/or user space is the Raspberry Pi 4, which does not
> implement the crypto extensions.

I have previously used Amazon EC2 A1 instances (using Graviton 1, Cortex-A72)
to run Debian armhf and armel user space in chroot environments. No idea how
common that is for production environments, but there is a good chance that
actual users might use e.g. 32-bit docker images for Alpine Linux on the same
machines.

There are also some early A57/A72 chips used in Android devices that may
frequently run 32-bit applications, or even be limited to 32-bit
kernels, see [1].
Not sure how likely it is for any of them to get (a backport of) this
patch though.

        Arnd

[1] https://www.androidpolice.com/2020/01/14/nvidias-shield-tv-dongle-can-only-run-32-bit-apps-but-you-probably-dont-need-to-panic/


From tobetter at gmail.com  Thu Jan 27 06:53:38 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Thu, 27 Jan 2022 23:53:38 +0900
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
References: <YfKPSvnFKOaLr74+@anyang>
 <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
Message-ID: <20220127145338.GB2417963@paju>

On Thu, Jan 27, 2022 at 02:00:11PM +0100, Neil Armstrong wrote:
> Hi,
> 
> On 27/01/2022 13:25, Dongjin Kim wrote:
> > GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> > GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
> > 'FC8731' on BPI-M5
> > 
> > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> > 
> > Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> > ---
> >  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
> >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
> >  2 files changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > index 212c6aa5a3b8..5751c48620ed 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> > @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
> >  		regulator-min-microvolt = <1800000>;
> >  		regulator-max-microvolt = <3300000>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > index bf29afac645f..d4349b355e4a 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
> >  		regulator-max-microvolt = <3300000>;
> >  		vin-supply = <&vcc_5v>;
> >  
> > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
> >  		enable-active-high;
> >  		regulator-always-on;
> >  
> > 
> Thanks for the fixes,
> can you send 2 patches fixing each files instead ?
> 
> Thanks,
> Neil

Sure.
By the way, I would drop a fix for 'meson-sm1-odroid.dtsi' since I found a
patch just now.
https://patchwork.kernel.org/project/linux-amlogic/patch/20220127130537.GA187347 at odroid-VirtualBox/

Thanks,
Dongjin.


From angelogioacchino.delregno at collabora.com  Thu Jan 27 07:02:44 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 16:02:44 +0100
Subject: [PATCH v1 06/14] media: platform: mtk-mdp3: Modify mtk-img-ipi.h
 for MT8195 SCP
In-Reply-To: <20220117055254.9777-7-roy-cw.yeh@mediatek.com>
References: <20220117055254.9777-1-roy-cw.yeh@mediatek.com>
 <20220117055254.9777-7-roy-cw.yeh@mediatek.com>
Message-ID: <f6bbe7ff-1487-0ed1-595d-2449d57098ca@collabora.com>

Il 17/01/22 06:52, roy-cw.yeh ha scritto:
> From: "Roy-CW.Yeh" <roy-cw.yeh at mediatek.com>
> 
> 1. Modify struct member to 4 byte-alignment for MT8195 SCP limitation
> 2. Add new struct for hw engine adding in MT8195
> 
> Signed-off-by: Roy-CW.Yeh <roy-cw.yeh at mediatek.com>

This will break MT8183; is there any new firmware for that SoC that will
synchronize these structures?

Alternatively, you should add a new version of these structures and select
them with a wrapper function on a per-SoC basis, or per firmware version.


From narmstrong at baylibre.com  Thu Jan 27 07:04:37 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 16:04:37 +0100
Subject: [PATCH] arm64: dts: meson-sm1: fix wrong GPIO domain for GPIOE_2
In-Reply-To: <20220127145338.GB2417963@paju>
References: <YfKPSvnFKOaLr74+@anyang>
 <dcb67b4e-6a46-86a6-b21f-99263cc9ff05@baylibre.com>
 <20220127145338.GB2417963@paju>
Message-ID: <ec1e087f-efee-fb02-9ae2-3039725538e4@baylibre.com>

Hi,

On 27/01/2022 15:53, Dongjin Kim wrote:
> On Thu, Jan 27, 2022 at 02:00:11PM +0100, Neil Armstrong wrote:
>> Hi,
>>
>> On 27/01/2022 13:25, Dongjin Kim wrote:
>>> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
>>> GPIOZ_14 connected to INTR of 'RTL8211F' on ODROID-HC and TF_PWR_EN of
>>> 'FC8731' on BPI-M5
>>>
>>> Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
>>> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
>>>
>>> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
>>> ---
>>>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>>>  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi     | 2 +-
>>>  2 files changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> index 212c6aa5a3b8..5751c48620ed 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
>>> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>>>  		regulator-min-microvolt = <1800000>;
>>>  		regulator-max-microvolt = <3300000>;
>>>  
>>> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
>>> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>>>  		enable-active-high;
>>>  		regulator-always-on;
>>>  
>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> index bf29afac645f..d4349b355e4a 100644
>>> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
>>> @@ -52,7 +52,7 @@ tf_io: gpio-regulator-tf_io {
>>>  		regulator-max-microvolt = <3300000>;
>>>  		vin-supply = <&vcc_5v>;
>>>  
>>> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
>>> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>>>  		enable-active-high;
>>>  		regulator-always-on;
>>>  
>>>
>> Thanks for the fixes,
>> can you send 2 patches fixing each files instead ?
>>
>> Thanks,
>> Neil
> 
> Sure.
> By the way, I would drop a fix for 'meson-sm1-odroid.dtsi' since I found a
> patch just now.
> https://patchwork.kernel.org/project/linux-amlogic/patch/20220127130537.GA187347 at odroid-VirtualBox/

Sure, you sent the v1 at the same time, and he just resend a new version.

Neil

> 
> Thanks,
> Dongjin.
> 



From helgaas at kernel.org  Thu Jan 27 07:16:30 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 27 Jan 2022 09:16:30 -0600
Subject: [PATCH v5 3/3] PCI: qcom: add support for IPQ60xx PCIe controller
In-Reply-To: <8735lc9r9d.fsf@tarshish>
Message-ID: <20220127151630.GA100574@bhelgaas>

On Tue, Jan 25, 2022 at 09:41:45AM +0200, Baruch Siach wrote:
> On Mon, Jan 24 2022, Bjorn Helgaas wrote:
> > On Mon, Jan 24, 2022 at 06:27:31PM +0200, Baruch Siach wrote:

> >> +static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
> >> +{
> >> +	struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
> >> +	struct device *dev = pcie->pci->dev;
> >> +	int ret;
> >> +
> >> +	ret = reset_control_assert(res->rst);
> >> +	if (ret) {
> >> +		dev_err(dev, "reset assert failed (%d)\n", ret);
> >> +		return ret;
> >> +	}
> >> +
> >> +	usleep_range(2000, 2500);
> >
> > Where do these sleep durations come from?  If they're specified
> > somewhere by PCIe, can you include a citation, e.g., a section number
> > in the spec.
> 
> As I mentioned before, I have no access to hardware documentation. I'm
> only porting working code from downstream kernel.
> 
> In a comment on v4 Bjorn Andersson mentioned "datasheet stating the
> minimum timing of the operations to be performed to get the PCIe
> controller into a known (clean) state".

Sorry if I'm repeating questions.  We can help avoid that by adding a
brief comment here like "black magic copied from working code at X" or
whatever you *do* know.  Repeated questions are wasted effort for both
the author and reviewers.

Sleeps with unsourced durations are always suspect because nobody
wants to wait longer than necessary, and if all we have is a bare
number and nobody knows how it was derived, we can't be confident
about changing it.

>   https://lore.kernel.org/all/Ydd5Wh0KeADBQ%2Fh1 at ripper/
> 
> I have no further details.


From tobetter at gmail.com  Thu Jan 27 07:16:56 2022
From: tobetter at gmail.com (Dongjin Kim)
Date: Fri, 28 Jan 2022 00:16:56 +0900
Subject: [PATCH] arm64: dts: meson-sm1-bananapi-m5: fix wrong GPIO domain for
 GPIOE_2
Message-ID: <20220127151656.GA2419733@paju>

GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
TF_PWR_EN of 'FC8731' on BPI-M5

Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")

Signed-off-by: Dongjin Kim <tobetter at gmail.com>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
index 212c6aa5a3b8..5751c48620ed 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
@@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
 		regulator-min-microvolt = <1800000>;
 		regulator-max-microvolt = <3300000>;
 
-		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From narmstrong at baylibre.com  Thu Jan 27 07:17:57 2022
From: narmstrong at baylibre.com (Neil Armstrong)
Date: Thu, 27 Jan 2022 16:17:57 +0100
Subject: [PATCH] arm64: dts: meson-sm1-bananapi-m5: fix wrong GPIO domain
 for GPIOE_2
In-Reply-To: <20220127151656.GA2419733@paju>
References: <20220127151656.GA2419733@paju>
Message-ID: <6cd58652-f24e-3919-589f-d71eb0e8070f@baylibre.com>

On 27/01/2022 16:16, Dongjin Kim wrote:
> GPIOE_2 is in AO domain and "<&gpio GPIOE_2 ...>" changes the state of
> TF_PWR_EN of 'FC8731' on BPI-M5
> 
> Fixes: 976e920183e4 ("arm64: dts: meson-sm1: add Banana PI BPI-M5 board dts")
> 
> Signed-off-by: Dongjin Kim <tobetter at gmail.com>
> ---
>  arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> index 212c6aa5a3b8..5751c48620ed 100644
> --- a/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-bananapi-m5.dts
> @@ -123,7 +123,7 @@ vddio_c: regulator-vddio_c {
>  		regulator-min-microvolt = <1800000>;
>  		regulator-max-microvolt = <3300000>;
>  
> -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
>  		enable-active-high;
>  		regulator-always-on;
>  
> 

Reviewed-by: Neil Armstrong <narmstrong at baylibre.com>

Thanks !

Neil


From chunkuang.hu at kernel.org  Thu Jan 27 07:21:27 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 27 Jan 2022 23:21:27 +0800
Subject: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>
References: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>
Message-ID: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>

Hi, Angelo:

AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
2022?1?27? ?? ??10:36???
>
> DRM bridge drivers are now attaching their DSI device at probe time,
> which requires us to register our DSI host in order to let the bridge
> to probe: this recently started producing an endless -EPROBE_DEFER
> loop on some machines that are using external bridges, like the
> parade-ps8640, found on the ACER Chromebook R13.
>
> Now that the DSI hosts/devices probe sequence is documented, we can
> do adjustments to the mtk_dsi driver as to both fix now and make sure
> to avoid this situation in the future: for this, following what is
> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> mtk_dsi_ops.attach callback and delete it in the detach callback;
> keeping in mind that we are registering a drm_bridge for our DSI,
> which is only used/attached if the DSI Host is bound, it wouldn't
> make sense to keep adding our bridge at probe time (as it would
> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> that one to the dsi host attach function (and remove it in detach).
>
> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")

The fixed tag should indicate the patch which cause the bug, but why a
patch just adding document would cause bug?
So no any patch cause bug? This patch just want to prevent a possible bug?

Regards,
Chun-Kuang.

> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>  1 file changed, 84 insertions(+), 83 deletions(-)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 5d90d2eb0019..bced4c7d668e 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>         mtk_dsi_poweroff(dsi);
>  }
>
> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> +{
> +       int ret;
> +
> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
> +                                     DRM_MODE_ENCODER_DSI);
> +       if (ret) {
> +               DRM_ERROR("Failed to encoder init to drm\n");
> +               return ret;
> +       }
> +
> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> +
> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +       if (ret)
> +               goto err_cleanup_encoder;
> +
> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> +       if (IS_ERR(dsi->connector)) {
> +               DRM_ERROR("Unable to create bridge connector\n");
> +               ret = PTR_ERR(dsi->connector);
> +               goto err_cleanup_encoder;
> +       }
> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> +
> +       return 0;
> +
> +err_cleanup_encoder:
> +       drm_encoder_cleanup(&dsi->encoder);
> +       return ret;
> +}
> +
> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> +{
> +       int ret;
> +       struct drm_device *drm = data;
> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +       ret = mtk_dsi_encoder_init(drm, dsi);
> +       if (ret)
> +               return ret;
> +
> +       return device_reset_optional(dev);
> +}
> +
> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
> +                          void *data)
> +{
> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +
> +       drm_encoder_cleanup(&dsi->encoder);
> +}
> +
> +static const struct component_ops mtk_dsi_component_ops = {
> +       .bind = mtk_dsi_bind,
> +       .unbind = mtk_dsi_unbind,
> +};
> +
>  static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>                                struct mipi_dsi_device *device)
>  {
>         struct mtk_dsi *dsi = host_to_dsi(host);
> +       struct device *dev = host->dev;
> +       int ret;
>
>         dsi->lanes = device->lanes;
>         dsi->format = device->format;
>         dsi->mode_flags = device->mode_flags;
> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
> +       if (IS_ERR(dsi->next_bridge))
> +               return PTR_ERR(dsi->next_bridge);
> +
> +       drm_bridge_add(&dsi->bridge);
> +
> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
> +       if (ret) {
> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
> +               drm_bridge_remove(&dsi->bridge);
> +               return ret;
> +       }
>
>         return 0;
>  }
>
> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
> +                              struct mipi_dsi_device *device)
> +{
> +       struct mtk_dsi *dsi = host_to_dsi(host);
> +
> +       component_del(host->dev, &mtk_dsi_component_ops);
> +       drm_bridge_remove(&dsi->bridge);
> +       return 0;
> +}
> +
>  static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>  {
>         int ret;
> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>
>  static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>         .attach = mtk_dsi_host_attach,
> +       .detach = mtk_dsi_host_detach,
>         .transfer = mtk_dsi_host_transfer,
>  };
>
> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
> -{
> -       int ret;
> -
> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
> -                                     DRM_MODE_ENCODER_DSI);
> -       if (ret) {
> -               DRM_ERROR("Failed to encoder init to drm\n");
> -               return ret;
> -       }
> -
> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
> -
> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> -       if (ret)
> -               goto err_cleanup_encoder;
> -
> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
> -       if (IS_ERR(dsi->connector)) {
> -               DRM_ERROR("Unable to create bridge connector\n");
> -               ret = PTR_ERR(dsi->connector);
> -               goto err_cleanup_encoder;
> -       }
> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
> -
> -       return 0;
> -
> -err_cleanup_encoder:
> -       drm_encoder_cleanup(&dsi->encoder);
> -       return ret;
> -}
> -
> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
> -{
> -       int ret;
> -       struct drm_device *drm = data;
> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -       ret = mtk_dsi_encoder_init(drm, dsi);
> -       if (ret)
> -               return ret;
> -
> -       return device_reset_optional(dev);
> -}
> -
> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
> -                          void *data)
> -{
> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
> -
> -       drm_encoder_cleanup(&dsi->encoder);
> -}
> -
> -static const struct component_ops mtk_dsi_component_ops = {
> -       .bind = mtk_dsi_bind,
> -       .unbind = mtk_dsi_unbind,
> -};
> -
>  static int mtk_dsi_probe(struct platform_device *pdev)
>  {
>         struct mtk_dsi *dsi;
>         struct device *dev = &pdev->dev;
> -       struct drm_panel *panel;
>         struct resource *regs;
>         int irq_num;
>         int ret;
> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>                 return ret;
>         }
>
> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -                                         &panel, &dsi->next_bridge);
> -       if (ret)
> -               goto err_unregister_host;
> -
> -       if (panel) {
> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
> -               if (IS_ERR(dsi->next_bridge)) {
> -                       ret = PTR_ERR(dsi->next_bridge);
> -                       goto err_unregister_host;
> -               }
> -       }
> -
>         dsi->driver_data = of_device_get_match_data(dev);
>
>         dsi->engine_clk = devm_clk_get(dev, "engine");
> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>         dsi->bridge.of_node = dev->of_node;
>         dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>
> -       drm_bridge_add(&dsi->bridge);
> -
> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
> -       if (ret) {
> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
> -               goto err_unregister_host;
> -       }
> -
>         return 0;
>
>  err_unregister_host:
> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>         struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>
>         mtk_output_dsi_disable(dsi);
> -       drm_bridge_remove(&dsi->bridge);
> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>         mipi_dsi_host_unregister(&dsi->host);
>
>         return 0;
> --
> 2.33.1
>


From andriy.shevchenko at linux.intel.com  Thu Jan 27 07:20:49 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Thu, 27 Jan 2022 17:20:49 +0200
Subject: [PATCH v20 2/3] Input: mt6779-keypad - Add MediaTek keypad driver
In-Reply-To: <20220127111526.3716689-3-mkorpershoek@baylibre.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
 <20220127111526.3716689-3-mkorpershoek@baylibre.com>
Message-ID: <YfK4UcuCfF7JfI7H@smile.fi.intel.com>

On Thu, Jan 27, 2022 at 12:15:25PM +0100, Mattijs Korpershoek wrote:
> From: "fengping.yu" <fengping.yu at mediatek.com>
> 
> This patch adds matrix keypad support for Mediatek SoCs.

Some comments which may be addressed now or in the follow-up patch(es).
Up to you.

...

> +static const struct regmap_config mt6779_keypad_regmap_cfg = {
> +	.reg_bits = 32,
> +	.val_bits = 32,

> +	.reg_stride = sizeof(u32),

I'm wondering if we need this when we have reg_bits = 32 already.

> +	.max_register = 36,
> +};

...

> +	regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
> +		     (debounce * 32) & MTK_KPD_DEBOUNCE_MASK);

I'm wondering if << 5 is more specific to show that the value
is based on 2^5 units.

...

> +	error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable, keypad->clk);

You have this long line...

> +	error = devm_request_threaded_irq(&pdev->dev, irq,
> +					  NULL, mt6779_keypad_irq_handler,
> +					  IRQF_ONESHOT,
> +					  MTK_KPD_NAME, keypad);

...at the same time you may reduce LOCs here...

> +	if (error) {
> +		dev_err(&pdev->dev, "Failed to request IRQ#%d:%d\n",
> +			irq, error);

...and here.

> +		return error;
> +	}

-- 
With Best Regards,
Andy Shevchenko




From catalin.marinas at arm.com  Thu Jan 27 07:25:54 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Thu, 27 Jan 2022 15:25:54 +0000
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <20220127122914.1585008-1-james.morse@arm.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
Message-ID: <YfK5grt9TiXIgh9O@arm.com>

Hi James,

On Thu, Jan 27, 2022 at 12:29:14PM +0000, James Morse wrote:
> diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
> index 9e1c1aef9ebd..b06fb054e055 100644
> --- a/arch/arm64/kernel/cpu_errata.c
> +++ b/arch/arm64/kernel/cpu_errata.c
> @@ -376,6 +376,14 @@ static struct midr_range trbe_write_out_of_range_cpus[] = {
>  };
>  #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
>  
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +static struct midr_range broken_aarch32_aes[] = {
> +	MIDR_RANGE(MIDR_CORTEX_A57, 0, 1, 0xf, 0xf),
> +	MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
> +	{},
> +};
> +#endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
> +
>  const struct arm64_cpu_capabilities arm64_errata[] = {
>  #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
>  	{
> @@ -597,6 +605,15 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
>  		.type = ARM64_CPUCAP_WEAK_LOCAL_CPU_FEATURE,
>  		CAP_MIDR_RANGE_LIST(trbe_write_out_of_range_cpus),
>  	},
> +#endif
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +	{
> +		.desc = "ARM erratum 1742098",
> +		.capability = ARM64_WORKAROUND_1742098,
> +		CAP_MIDR_RANGE_LIST(broken_aarch32_aes),
> +		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
> +		.cpu_enable = arm64_remove_aes_compat_hwcap,
> +	},
>  #endif
>  	{
>  	}
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index a46ab3b1c4d5..06605e267ab0 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -1900,6 +1900,29 @@ static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap)
>  }
>  #endif /* CONFIG_ARM64_MTE */
>  
> +#ifdef CONFIG_ARM64_ERRATUM_1742098
> +/*
> + * compat_elf_hwcap{,2} are built from the sanitised id registers after the
> + * enable calls have run.  See the order of the setup_system_capabilities()
> + * and setup_elf_hwcaps() calls in setup_cpu_features(). Removing the AES
> + * field prevents the AES hwcap from being advertised.
> + */
> +void arm64_remove_aes_compat_hwcap(const struct arm64_cpu_capabilities *cap)
> +{
> +	struct arm64_ftr_reg *aa32isar5 = get_arm64_ftr_reg(SYS_ID_ISAR5_EL1);
> +	u64 aes_mask = GENMASK_ULL(ID_ISAR5_AES_SHIFT + 3, ID_ISAR5_AES_SHIFT);
> +
> +	/*
> +	 * On affected platforms this call is made via stop_machine() on all
> +	 * online CPUs. Only clear the register from the boot CPU.
> +	 */
> +	if (smp_processor_id())
> +		return;
> +
> +	aa32isar5->sys_val &= ~aes_mask;
> +}
> +#endif /* CONFIG_ARM64_ERRATUM_1742098 */

I wonder whether this would look better if we use the
ARM64_FTR_REG_OVERRIDE approach with an id_isar5_override defined in
cpu_errata.c and populated there. I haven't checked the order in which
they would be called though.

Alternatively, we could make the ftr_id_isar5 reg global and patch it
directly in cpu_errata.c (arm64_ftr_reg_ctrel0 is another case where we
made it global). Yet another option would be to add some function in
cpufeature.[hc] to patch a feature directly and we'd call it from
cpu_errata.c. My preference would be to keep the cpu_enable function for
the workaround in cpu_errata.c.

Is this the first case where we need to change the ELF HWCAPs due to an
erratum?

-- 
Catalin


From gautham.shenoy at amd.com  Thu Jan 27 07:26:58 2022
From: gautham.shenoy at amd.com (Gautham R. Shenoy)
Date: Thu, 27 Jan 2022 20:56:58 +0530
Subject: [PATCH v2 1/2] sched: Add per_cpu cluster domain info and
 cpus_share_resources API
In-Reply-To: <20220126080947.4529-2-yangyicong@hisilicon.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-2-yangyicong@hisilicon.com>
Message-ID: <YfK5wjuvy+Y5SZDb@BLR-5CG11610CF.amd.com>

Hello Yicong, Barry,
On Wed, Jan 26, 2022 at 04:09:46PM +0800, Yicong Yang wrote:
> From: Barry Song <song.bao.hua at hisilicon.com>
> 
> Add per-cpu cluster domain info and cpus_share_resources() API.
> This is the preparation for the optimization of select_idle_cpu()
> on platforms with cluster scheduler level.
> 
> Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>

This patch looks good to me.

Reviewed-by: Gautham R. Shenoy <gautham.shenoy at amd.com>

--
Thanks and Regards
gautham.


From greg at kroah.com  Thu Jan 27 07:36:30 2022
From: greg at kroah.com (Greg KH)
Date: Thu, 27 Jan 2022 16:36:30 +0100
Subject: [4.9 PATCH] ARM: 8800/1: use choice for kernel unwinders
In-Reply-To: <20220125134148.3390940-1-anders.roxell@linaro.org>
References: <20220125134148.3390940-1-anders.roxell@linaro.org>
Message-ID: <YfK7/goKdy5qlhEc@kroah.com>

On Tue, Jan 25, 2022 at 02:41:48PM +0100, Anders Roxell wrote:
> From: Stefan Agner <stefan at agner.ch>
> 
> commit f9b58e8c7d031b0daa5c9a9ee27f5a4028ba53ac upstream.
> 
> While in theory multiple unwinders could be compiled in, it does
> not make sense in practise. Use a choice to make the unwinder
> selection mutually exclusive and mandatory.
> 
> Already before this commit it has not been possible to deselect
> FRAME_POINTER. Remove the obsolete comment.
> 
> Furthermore, to produce a meaningful backtrace with FRAME_POINTER
> enabled the kernel needs a specific function prologue:
>     mov    ip, sp
>     stmfd    sp!, {fp, ip, lr, pc}
>     sub    fp, ip, #4
> 
> To get to the required prologue gcc uses apcs and no-sched-prolog.
> This compiler options are not available on clang, and clang is not
> able to generate the required prologue. Make the FRAME_POINTER
> config symbol depending on !clang.
> 
> Suggested-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Stefan Agner <stefan at agner.ch>
> Reviewed-by: Arnd Bergmann <arnd at arndb.de>
> Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
> Signed-off-by: Anders Roxell <anders.roxell at linaro.org>
> ---
>  arch/arm/Kconfig.debug | 44 +++++++++++++++++++++++++++---------------
>  lib/Kconfig.debug      |  6 +++---
>  2 files changed, 31 insertions(+), 19 deletions(-)

Now queued up, thanks.

greg k-h


From gautham.shenoy at amd.com  Thu Jan 27 07:41:01 2022
From: gautham.shenoy at amd.com (Gautham R. Shenoy)
Date: Thu, 27 Jan 2022 21:11:01 +0530
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <20220126080947.4529-3-yangyicong@hisilicon.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
Message-ID: <YfK9DSMFabjYm/MV@BLR-5CG11610CF.amd.com>

On Wed, Jan 26, 2022 at 04:09:47PM +0800, Yicong Yang wrote:
> From: Barry Song <song.bao.hua at hisilicon.com>
> 
> For platforms having clusters like Kunpeng920, CPUs within the same
> cluster have lower latency when synchronizing and accessing shared
> resources like cache. Thus, this patch tries to find an idle cpu
> within the cluster of the target CPU before scanning the whole LLC
> to gain lower latency.
> 
> Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> patch doesn't consider SMT for this moment.
> 
> Testing has been done on Kunpeng920 by pinning tasks to one numa
> and two numa. On Kunpeng920, Each numa has 8 clusters and each
> cluster has 4 CPUs.
> 
> With this patch, We noticed enhancement on tbench within one
> numa or cross two numa.
> 
> On numa 0:
>                             5.17-rc1                patched
> Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> 
> On numa 0-1:
>                             5.17-rc1                patched
> Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> 
> This will also help to improve the MySQL. With MySQL server
> running on numa 0 and client running on numa 1, both QPS and
> latency is imporved on read-write case:
>                         5.17-rc1        patched
> QPS-16threads        143333.2633    145077.4033(+1.22%)
> QPS-24threads        195085.9367    202719.6133(+3.91%)
> QPS-32threads        241165.6867      249020.74(+3.26%)
> QPS-64threads        244586.8433    253387.7567(+3.60%)
> avg-lat-16threads           2.23           2.19(+1.19%)
> avg-lat-24threads           2.46           2.36(+3.79%)
> avg-lat-36threads           2.66           2.57(+3.26%)
> avg-lat-64threads           5.23           5.05(+3.44%)
> 
> Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> ---
>  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 42 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 5146163bfabb..2f84a933aedd 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
>  
>  #endif /* CONFIG_SCHED_SMT */
>  
> +#ifdef CONFIG_SCHED_CLUSTER
> +/*
> + * Scan the cluster domain for idle CPUs and clear cluster cpumask after scanning
> + */
> +static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
> +{
> +	struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
> +	struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster, target));
> +	int cpu, idle_cpu;
> +
> +	/* TODO: Support SMT case while a machine with both cluster and SMT born */
> +	if (!sched_smt_active() && sd) {
> +		for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> +			idle_cpu = __select_idle_cpu(cpu, p);
> +			if ((unsigned int)idle_cpu < nr_cpumask_bits)
> +				return idle_cpu;
> +		}
> +
> +		/* Don't ping-pong tasks in and out cluster frequently */
> +		if (cpus_share_resources(target, prev_cpu))
> +			return target;

We reach here when there aren't any idle CPUs within the
cluster. However there might be idle CPUs in the MC domain. Is a busy
@target preferable to a potentially idle CPU within the larger domain
?


--
Thanks and Regards
gautham.


From gregkh at linuxfoundation.org  Thu Jan 27 07:41:53 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Thu, 27 Jan 2022 16:41:53 +0100
Subject: [PATCH stable 5.4 0/7] pinctrl-bcm2835 gpio-ranges bugfix
In-Reply-To: <20220125194222.12783-1-f.fainelli@gmail.com>
References: <20220125194222.12783-1-f.fainelli@gmail.com>
Message-ID: <YfK9QfDm/p7XmgFq@kroah.com>

On Tue, Jan 25, 2022 at 11:42:15AM -0800, Florian Fainelli wrote:
> Hi all,
> 
> This patch series is intended to backport the fix from Phil "pinctrl:
> bcm2835: Change init order for gpio hogs" into the 5.4 tree since the
> blamed commit:
> 
> 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
> 
> is in 5.4. To get there, I did backport a number of changes in order for
> the commit "pinctrl: bcm2835: Change init order for gpio hogs" to apply
> cleanly with no hunks.
> 
> Those should have no functional impact since we do not have support for
> 7211 or 2711 in the upstream stable 5.4.
> 
> Both the pinctrl *and* the DTS changes must be taken in lockstep
> otherwise the GPIO pins are simply not usable unfortunately.
> 
> Thanks!
> 
> Florian Fainelli (2):
>   pinctrl: bcm2835: Match BCM7211 compatible string
>   pinctrl: bcm2835: Add support for wake-up interrupts
> 
> Phil Elwell (2):
>   pinctrl: bcm2835: Change init order for gpio hogs
>   ARM: dts: gpio-ranges property is now required
> 
> Stefan Wahren (3):
>   pinctrl: bcm2835: Drop unused define
>   pinctrl: bcm2835: Refactor platform data
>   pinctrl: bcm2835: Add support for all GPIOs on BCM2711
> 
>  arch/arm/boot/dts/bcm283x.dtsi        |   1 +
>  drivers/pinctrl/bcm/pinctrl-bcm2835.c | 209 +++++++++++++++++++++-----
>  2 files changed, 175 insertions(+), 35 deletions(-)
> 
> -- 
> 2.25.1
> 

All now queued up, thanks.

greg k-h


From angelogioacchino.delregno at collabora.com  Thu Jan 27 07:46:19 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Thu, 27 Jan 2022 16:46:19 +0100
Subject: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>
References: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>
 <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>
Message-ID: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com>

Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> Hi, Angelo:
> 
> AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
> 2022?1?27? ?? ??10:36???
>>
>> DRM bridge drivers are now attaching their DSI device at probe time,
>> which requires us to register our DSI host in order to let the bridge
>> to probe: this recently started producing an endless -EPROBE_DEFER
>> loop on some machines that are using external bridges, like the
>> parade-ps8640, found on the ACER Chromebook R13.
>>
>> Now that the DSI hosts/devices probe sequence is documented, we can
>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>> to avoid this situation in the future: for this, following what is
>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>> keeping in mind that we are registering a drm_bridge for our DSI,
>> which is only used/attached if the DSI Host is bound, it wouldn't
>> make sense to keep adding our bridge at probe time (as it would
>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>> that one to the dsi host attach function (and remove it in detach).
>>
>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> 
> The fixed tag should indicate the patch which cause the bug, but why a
> patch just adding document would cause bug?
> So no any patch cause bug? This patch just want to prevent a possible bug?
> 

I think you've missed my previous message on v2, so I will paste it here:

unfortunately I couldn't find a valid commit for a Fixes tag. This
started being an issue at some point, when the DRM was changed to
adhere to the documented probe sequence: the MediaTek DSI driver was
not the only one that got broken/affected by these changes.

If you have any advice on which commit should be tagged, I'm open for
any kind of suggestion.


I tried to check on other drivers which got fixed for the same behavior,
for example drm/msm, but none of them had a Fixes tag.
When the DRM got changed to adhere to this sequence, some drm/bridge
drivers were also changed; this has created some incompatibilities with
some drm drivers, including drm/msm and drm/mediatek.

This commit is not fixing a latent bug that was introduced in drm/mediatek
but rather one that was induced by the new, fixed, probe flow that got
recently documented - and to which drivers should adhere; failing to adhere
to that will produce an endless -EPROBE_DEFER loop, due to other drivers
(as mentioned, for example drm/bridge drivers) having been changed to use
that probe sequence.


Regards,
Angelo

> Regards,
> Chun-Kuang.
> 
>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
>> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
>>
>> ---
>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>   1 file changed, 84 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> index 5d90d2eb0019..bced4c7d668e 100644
>> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
>> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
>> @@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
>>          mtk_dsi_poweroff(dsi);
>>   }
>>
>> +static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> +{
>> +       int ret;
>> +
>> +       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> +                                     DRM_MODE_ENCODER_DSI);
>> +       if (ret) {
>> +               DRM_ERROR("Failed to encoder init to drm\n");
>> +               return ret;
>> +       }
>> +
>> +       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> +
>> +       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> +                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> +       if (ret)
>> +               goto err_cleanup_encoder;
>> +
>> +       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> +       if (IS_ERR(dsi->connector)) {
>> +               DRM_ERROR("Unable to create bridge connector\n");
>> +               ret = PTR_ERR(dsi->connector);
>> +               goto err_cleanup_encoder;
>> +       }
>> +       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> +
>> +       return 0;
>> +
>> +err_cleanup_encoder:
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +       return ret;
>> +}
>> +
>> +static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> +{
>> +       int ret;
>> +       struct drm_device *drm = data;
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       ret = mtk_dsi_encoder_init(drm, dsi);
>> +       if (ret)
>> +               return ret;
>> +
>> +       return device_reset_optional(dev);
>> +}
>> +
>> +static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> +                          void *data)
>> +{
>> +       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> +
>> +       drm_encoder_cleanup(&dsi->encoder);
>> +}
>> +
>> +static const struct component_ops mtk_dsi_component_ops = {
>> +       .bind = mtk_dsi_bind,
>> +       .unbind = mtk_dsi_unbind,
>> +};
>> +
>>   static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
>>                                 struct mipi_dsi_device *device)
>>   {
>>          struct mtk_dsi *dsi = host_to_dsi(host);
>> +       struct device *dev = host->dev;
>> +       int ret;
>>
>>          dsi->lanes = device->lanes;
>>          dsi->format = device->format;
>>          dsi->mode_flags = device->mode_flags;
>> +       dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
>> +       if (IS_ERR(dsi->next_bridge))
>> +               return PTR_ERR(dsi->next_bridge);
>> +
>> +       drm_bridge_add(&dsi->bridge);
>> +
>> +       ret = component_add(host->dev, &mtk_dsi_component_ops);
>> +       if (ret) {
>> +               DRM_ERROR("failed to add dsi_host component: %d\n", ret);
>> +               drm_bridge_remove(&dsi->bridge);
>> +               return ret;
>> +       }
>>
>>          return 0;
>>   }
>>
>> +static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
>> +                              struct mipi_dsi_device *device)
>> +{
>> +       struct mtk_dsi *dsi = host_to_dsi(host);
>> +
>> +       component_del(host->dev, &mtk_dsi_component_ops);
>> +       drm_bridge_remove(&dsi->bridge);
>> +       return 0;
>> +}
>> +
>>   static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
>>   {
>>          int ret;
>> @@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
>>
>>   static const struct mipi_dsi_host_ops mtk_dsi_ops = {
>>          .attach = mtk_dsi_host_attach,
>> +       .detach = mtk_dsi_host_detach,
>>          .transfer = mtk_dsi_host_transfer,
>>   };
>>
>> -static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
>> -{
>> -       int ret;
>> -
>> -       ret = drm_simple_encoder_init(drm, &dsi->encoder,
>> -                                     DRM_MODE_ENCODER_DSI);
>> -       if (ret) {
>> -               DRM_ERROR("Failed to encoder init to drm\n");
>> -               return ret;
>> -       }
>> -
>> -       dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
>> -
>> -       ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
>> -                               DRM_BRIDGE_ATTACH_NO_CONNECTOR);
>> -       if (ret)
>> -               goto err_cleanup_encoder;
>> -
>> -       dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
>> -       if (IS_ERR(dsi->connector)) {
>> -               DRM_ERROR("Unable to create bridge connector\n");
>> -               ret = PTR_ERR(dsi->connector);
>> -               goto err_cleanup_encoder;
>> -       }
>> -       drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
>> -
>> -       return 0;
>> -
>> -err_cleanup_encoder:
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -       return ret;
>> -}
>> -
>> -static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
>> -{
>> -       int ret;
>> -       struct drm_device *drm = data;
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       ret = mtk_dsi_encoder_init(drm, dsi);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return device_reset_optional(dev);
>> -}
>> -
>> -static void mtk_dsi_unbind(struct device *dev, struct device *master,
>> -                          void *data)
>> -{
>> -       struct mtk_dsi *dsi = dev_get_drvdata(dev);
>> -
>> -       drm_encoder_cleanup(&dsi->encoder);
>> -}
>> -
>> -static const struct component_ops mtk_dsi_component_ops = {
>> -       .bind = mtk_dsi_bind,
>> -       .unbind = mtk_dsi_unbind,
>> -};
>> -
>>   static int mtk_dsi_probe(struct platform_device *pdev)
>>   {
>>          struct mtk_dsi *dsi;
>>          struct device *dev = &pdev->dev;
>> -       struct drm_panel *panel;
>>          struct resource *regs;
>>          int irq_num;
>>          int ret;
>> @@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>                  return ret;
>>          }
>>
>> -       ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
>> -                                         &panel, &dsi->next_bridge);
>> -       if (ret)
>> -               goto err_unregister_host;
>> -
>> -       if (panel) {
>> -               dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
>> -               if (IS_ERR(dsi->next_bridge)) {
>> -                       ret = PTR_ERR(dsi->next_bridge);
>> -                       goto err_unregister_host;
>> -               }
>> -       }
>> -
>>          dsi->driver_data = of_device_get_match_data(dev);
>>
>>          dsi->engine_clk = devm_clk_get(dev, "engine");
>> @@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
>>          dsi->bridge.of_node = dev->of_node;
>>          dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
>>
>> -       drm_bridge_add(&dsi->bridge);
>> -
>> -       ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
>> -       if (ret) {
>> -               dev_err(&pdev->dev, "failed to add component: %d\n", ret);
>> -               goto err_unregister_host;
>> -       }
>> -
>>          return 0;
>>
>>   err_unregister_host:
>> @@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
>>          struct mtk_dsi *dsi = platform_get_drvdata(pdev);
>>
>>          mtk_output_dsi_disable(dsi);
>> -       drm_bridge_remove(&dsi->bridge);
>> -       component_del(&pdev->dev, &mtk_dsi_component_ops);
>>          mipi_dsi_host_unregister(&dsi->host);
>>
>>          return 0;
>> --
>> 2.33.1
>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


From chunkuang.hu at kernel.org  Thu Jan 27 07:46:59 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Thu, 27 Jan 2022 23:46:59 +0800
Subject: [PATCH v15 03/12] dt-bindings: display: mediatek: disp: split
 each block to individual yaml
In-Reply-To: <20220126071932.32615-4-jason-jh.lin@mediatek.com>
References: <20220126071932.32615-1-jason-jh.lin@mediatek.com>
 <20220126071932.32615-4-jason-jh.lin@mediatek.com>
Message-ID: <CAAOTY__K_0sp6+VdL0yi=wF9wA_uag4HKqK3ST7uySdkzfCHBA@mail.gmail.com>

Hi, Rob:

This patch looks good to me, how do you think about it?

Regards,
Chun-Kuang.

jason-jh.lin <jason-jh.lin at mediatek.com> ? 2022?1?26? ?? ??3:19???
>
> 1. Remove mediatek,dislpay.txt
> 2. Split each display function block to individual yaml file.
>
> Signed-off-by: jason-jh.lin <jason-jh.lin at mediatek.com>
> Acked-by: Chun-Kuang Hu <chunkuang.hu at kernel.org>
> ---
>  .../display/mediatek/mediatek,aal.yaml        |  76 ++++++
>  .../display/mediatek/mediatek,ccorr.yaml      |  71 ++++++
>  .../display/mediatek/mediatek,color.yaml      |  85 +++++++
>  .../display/mediatek/mediatek,disp.txt        | 219 ------------------
>  .../display/mediatek/mediatek,dither.yaml     |  75 ++++++
>  .../display/mediatek/mediatek,gamma.yaml      |  76 ++++++
>  .../display/mediatek/mediatek,merge.yaml      |  66 ++++++
>  .../display/mediatek/mediatek,mutex.yaml      |  82 +++++++
>  .../display/mediatek/mediatek,od.yaml         |  53 +++++
>  .../display/mediatek/mediatek,ovl-2l.yaml     |  88 +++++++
>  .../display/mediatek/mediatek,ovl.yaml        |  98 ++++++++
>  .../display/mediatek/mediatek,postmask.yaml   |  69 ++++++
>  .../display/mediatek/mediatek,rdma.yaml       | 115 +++++++++
>  .../display/mediatek/mediatek,split.yaml      |  58 +++++
>  .../display/mediatek/mediatek,ufoe.yaml       |  61 +++++
>  .../display/mediatek/mediatek,wdma.yaml       |  86 +++++++
>  16 files changed, 1159 insertions(+), 219 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
>  delete mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
>  create mode 100644 Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
> new file mode 100644
> index 000000000000..044331f5aacb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,aal.yaml
> @@ -0,0 +1,76 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,aal.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display adaptive ambient light processor
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display adaptive ambient light processor, namely AAL,
> +  is responsible for backlight power saving and sunlight visibility improving.
> +  AAL device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-aal
> +      - items:
> +          - enum:
> +              - mediatek,mt2712-disp-aal
> +              - mediatek,mt8183-disp-aal
> +              - mediatek,mt8192-disp-aal
> +          - enum:
> +              - mediatek,mt8173-disp-aal
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: AAL Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    aal at 14015000 {
> +        compatible = "mediatek,mt8173-disp-aal";
> +        reg = <0 0x14015000 0 0x1000>;
> +        interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_AAL>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x5000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
> new file mode 100644
> index 000000000000..ea45b40edee7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ccorr.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,ccorr.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display color correction
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display color correction, namely CCORR, reproduces correct color
> +  on panels with different color gamut.
> +  CCORR device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8183-disp-ccorr
> +      - items:
> +          - const: mediatek,mt8192-disp-ccorr
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: CCORR Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    ccorr0: ccorr at 1400f000 {
> +        compatible = "mediatek,mt8183-disp-ccorr";
> +        reg = <0 0x1400f000 0 0x1000>;
> +        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +        clocks = <&mmsys CLK_MM_DISP_CCORR0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xf000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
> new file mode 100644
> index 000000000000..13628f346718
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,color.yaml
> @@ -0,0 +1,85 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,color.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display color processor
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display color processor, namely COLOR, provides hue, luma and
> +  saturation adjustments to get better picture quality and to have one panel
> +  resemble the other in their output characteristics.
> +  COLOR device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt2701-disp-color
> +      - items:
> +          - const: mediatek,mt8167-disp-color
> +      - items:
> +          - const: mediatek,mt8173-disp-color
> +      - items:
> +          - enum:
> +              - mediatek,mt7623-disp-color
> +              - mediatek,mt2712-disp-color
> +          - enum:
> +              - mediatek,mt2701-disp-color
> +      - items:
> +          - enum:
> +              - mediatek,mt8183-disp-color
> +              - mediatek,mt8192-disp-color
> +          - enum:
> +              - mediatek,mt8173-disp-color
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: COLOR Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    color0: color at 14013000 {
> +        compatible = "mediatek,mt8173-disp-color";
> +        reg = <0 0x14013000 0 0x1000>;
> +        interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_COLOR0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x3000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt b/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
> deleted file mode 100644
> index 78044c340e20..000000000000
> --- a/Documentation/devicetree/bindings/display/mediatek/mediatek,disp.txt
> +++ /dev/null
> @@ -1,219 +0,0 @@
> -Mediatek display subsystem
> -==========================
> -
> -The Mediatek display subsystem consists of various DISP function blocks in the
> -MMSYS register space. The connections between them can be configured by output
> -and input selectors in the MMSYS_CONFIG register space. Pixel clock and start
> -of frame signal are distributed to the other function blocks by a DISP_MUTEX
> -function block.
> -
> -All DISP device tree nodes must be siblings to the central MMSYS_CONFIG node.
> -For a description of the MMSYS_CONFIG binding, see
> -Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml.
> -
> -DISP function blocks
> -====================
> -
> -A display stream starts at a source function block that reads pixel data from
> -memory and ends with a sink function block that drives pixels on a display
> -interface, or writes pixels back to memory. All DISP function blocks have
> -their own register space, interrupt, and clock gate. The blocks that can
> -access memory additionally have to list the IOMMU and local arbiter they are
> -connected to.
> -
> -For a description of the display interface sink function blocks, see
> -Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt and
> -Documentation/devicetree/bindings/display/mediatek/mediatek,dpi.yaml.
> -
> -Required properties (all function blocks):
> -- compatible: "mediatek,<chip>-disp-<function>", one of
> -       "mediatek,<chip>-disp-ovl"              - overlay (4 layers, blending, csc)
> -       "mediatek,<chip>-disp-ovl-2l"           - overlay (2 layers, blending, csc)
> -       "mediatek,<chip>-disp-rdma"             - read DMA / line buffer
> -       "mediatek,<chip>-disp-wdma"             - write DMA
> -       "mediatek,<chip>-disp-ccorr"            - color correction
> -       "mediatek,<chip>-disp-color"            - color processor
> -       "mediatek,<chip>-disp-dither"           - dither
> -       "mediatek,<chip>-disp-aal"              - adaptive ambient light controller
> -       "mediatek,<chip>-disp-gamma"            - gamma correction
> -       "mediatek,<chip>-disp-merge"            - merge streams from two RDMA sources
> -       "mediatek,<chip>-disp-postmask"         - control round corner for display frame
> -       "mediatek,<chip>-disp-split"            - split stream to two encoders
> -       "mediatek,<chip>-disp-ufoe"             - data compression engine
> -       "mediatek,<chip>-dsi"                   - DSI controller, see mediatek,dsi.txt
> -       "mediatek,<chip>-dpi"                   - DPI controller, see mediatek,dpi.txt
> -       "mediatek,<chip>-disp-mutex"            - display mutex
> -       "mediatek,<chip>-disp-od"               - overdrive
> -  the supported chips are mt2701, mt7623, mt2712, mt8167, mt8173, mt8183 and mt8192.
> -- reg: Physical base address and length of the function block register space
> -- interrupts: The interrupt signal from the function block (required, except for
> -  merge and split function blocks).
> -- clocks: device clocks
> -  See Documentation/devicetree/bindings/clock/clock-bindings.txt for details.
> -  For most function blocks this is just a single clock input. Only the DSI and
> -  DPI controller nodes have multiple clock inputs. These are documented in
> -  mediatek,dsi.txt and mediatek,dpi.txt, respectively.
> -  An exception is that the mt8183 mutex is always free running with no clocks property.
> -
> -Required properties (DMA function blocks):
> -- compatible: Should be one of
> -       "mediatek,<chip>-disp-ovl"
> -       "mediatek,<chip>-disp-rdma"
> -       "mediatek,<chip>-disp-wdma"
> -  the supported chips are mt2701, mt8167 and mt8173.
> -- larb: Should contain a phandle pointing to the local arbiter device as defined
> -  in Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
> -- iommus: Should point to the respective IOMMU block with master port as
> -  argument, see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml
> -  for details.
> -
> -Optional properties (RDMA function blocks):
> -- mediatek,rdma-fifo-size: rdma fifo size may be different even in same SOC, add this
> -  property to the corresponding rdma
> -  the value is the Max value which defined in hardware data sheet.
> -  mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
> -  mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
> -  mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
> -
> -Examples:
> -
> -mmsys: clock-controller at 14000000 {
> -       compatible = "mediatek,mt8173-mmsys", "syscon";
> -       reg = <0 0x14000000 0 0x1000>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       #clock-cells = <1>;
> -};
> -
> -ovl0: ovl at 1400c000 {
> -       compatible = "mediatek,mt8173-disp-ovl";
> -       reg = <0 0x1400c000 0 0x1000>;
> -       interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_OVL0>;
> -       iommus = <&iommu M4U_PORT_DISP_OVL0>;
> -       mediatek,larb = <&larb0>;
> -};
> -
> -ovl1: ovl at 1400d000 {
> -       compatible = "mediatek,mt8173-disp-ovl";
> -       reg = <0 0x1400d000 0 0x1000>;
> -       interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_OVL1>;
> -       iommus = <&iommu M4U_PORT_DISP_OVL1>;
> -       mediatek,larb = <&larb4>;
> -};
> -
> -rdma0: rdma at 1400e000 {
> -       compatible = "mediatek,mt8173-disp-rdma";
> -       reg = <0 0x1400e000 0 0x1000>;
> -       interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_RDMA0>;
> -       iommus = <&iommu M4U_PORT_DISP_RDMA0>;
> -       mediatek,larb = <&larb0>;
> -       mediatek,rdma-fifosize = <8192>;
> -};
> -
> -rdma1: rdma at 1400f000 {
> -       compatible = "mediatek,mt8173-disp-rdma";
> -       reg = <0 0x1400f000 0 0x1000>;
> -       interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_RDMA1>;
> -       iommus = <&iommu M4U_PORT_DISP_RDMA1>;
> -       mediatek,larb = <&larb4>;
> -};
> -
> -rdma2: rdma at 14010000 {
> -       compatible = "mediatek,mt8173-disp-rdma";
> -       reg = <0 0x14010000 0 0x1000>;
> -       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_RDMA2>;
> -       iommus = <&iommu M4U_PORT_DISP_RDMA2>;
> -       mediatek,larb = <&larb4>;
> -};
> -
> -wdma0: wdma at 14011000 {
> -       compatible = "mediatek,mt8173-disp-wdma";
> -       reg = <0 0x14011000 0 0x1000>;
> -       interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_WDMA0>;
> -       iommus = <&iommu M4U_PORT_DISP_WDMA0>;
> -       mediatek,larb = <&larb0>;
> -};
> -
> -wdma1: wdma at 14012000 {
> -       compatible = "mediatek,mt8173-disp-wdma";
> -       reg = <0 0x14012000 0 0x1000>;
> -       interrupts = <GIC_SPI 186 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_WDMA1>;
> -       iommus = <&iommu M4U_PORT_DISP_WDMA1>;
> -       mediatek,larb = <&larb4>;
> -};
> -
> -color0: color at 14013000 {
> -       compatible = "mediatek,mt8173-disp-color";
> -       reg = <0 0x14013000 0 0x1000>;
> -       interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_COLOR0>;
> -};
> -
> -color1: color at 14014000 {
> -       compatible = "mediatek,mt8173-disp-color";
> -       reg = <0 0x14014000 0 0x1000>;
> -       interrupts = <GIC_SPI 188 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_COLOR1>;
> -};
> -
> -aal at 14015000 {
> -       compatible = "mediatek,mt8173-disp-aal";
> -       reg = <0 0x14015000 0 0x1000>;
> -       interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_AAL>;
> -};
> -
> -gamma at 14016000 {
> -       compatible = "mediatek,mt8173-disp-gamma";
> -       reg = <0 0x14016000 0 0x1000>;
> -       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_GAMMA>;
> -};
> -
> -ufoe at 1401a000 {
> -       compatible = "mediatek,mt8173-disp-ufoe";
> -       reg = <0 0x1401a000 0 0x1000>;
> -       interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_UFOE>;
> -};
> -
> -dsi0: dsi at 1401b000 {
> -       /* See mediatek,dsi.txt for details */
> -};
> -
> -dpi0: dpi at 1401d000 {
> -       /* See mediatek,dpi.txt for details */
> -};
> -
> -mutex: mutex at 14020000 {
> -       compatible = "mediatek,mt8173-disp-mutex";
> -       reg = <0 0x14020000 0 0x1000>;
> -       interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_MUTEX_32K>;
> -};
> -
> -od at 14023000 {
> -       compatible = "mediatek,mt8173-disp-od";
> -       reg = <0 0x14023000 0 0x1000>;
> -       power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> -       clocks = <&mmsys CLK_MM_DISP_OD>;
> -};
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
> new file mode 100644
> index 000000000000..2c05e3019c75
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,dither.yaml
> @@ -0,0 +1,75 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,dither.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display dither processor
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display dither processor, namely DITHER, works by approximating
> +  unavailable colors with available colors and by mixing and matching available
> +  colors to mimic unavailable ones.
> +  DITHER device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8183-disp-dither
> +      - items:
> +          - enum:
> +              - mediatek,mt8192-disp-dither
> +          - enum:
> +              - mediatek,mt8183-disp-dither
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: DITHER Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    dither0: dither at 14012000 {
> +        compatible = "mediatek,mt8183-disp-dither";
> +        reg = <0 0x14012000 0 0x1000>;
> +        interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +        clocks = <&mmsys CLK_MM_DISP_DITHER0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x2000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
> new file mode 100644
> index 000000000000..89ccb8dbadd7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,gamma.yaml
> @@ -0,0 +1,76 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,gamma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display gamma correction
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display gamma correction, namely GAMMA, provides a nonlinear
> +  operation used to adjust luminance in display system.
> +  GAMMA device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-gamma
> +      - items:
> +          - const: mediatek,mt8183-disp-gamma
> +      - items:
> +          - enum:
> +              - mediatek,mt8192-disp-gamma
> +          - enum:
> +              - mediatek,mt8183-disp-gamma
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: GAMMA Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    gamma at 14016000 {
> +        compatible = "mediatek,mt8173-disp-gamma";
> +        reg = <0 0x14016000 0 0x1000>;
> +        interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_GAMMA>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x6000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
> new file mode 100644
> index 000000000000..7aa6974d509d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,merge.yaml
> @@ -0,0 +1,66 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,merge.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display merge
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display merge, namely MERGE, is used to merge two slice-per-line
> +  inputs into one side-by-side output.
> +  MERGE device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-merge
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: MERGE Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    merge at 14017000 {
> +        compatible = "mediatek,mt8173-disp-merge";
> +        reg = <0 0x14017000 0 0x1000>;
> +        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_MERGE>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
> new file mode 100644
> index 000000000000..90f11e12a55e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,mutex.yaml
> @@ -0,0 +1,82 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,mutex.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display mutex
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek mutex, namely MUTEX, is used to send the triggers signals called
> +  Start Of Frame (SOF) / End Of Frame (EOF) to each sub-modules on the display
> +  data path or MDP data path.
> +  In some SoC, such as mt2701, MUTEX could be a hardware mutex which protects
> +  the shadow register.
> +  MUTEX device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt2701-disp-mutex
> +      - items:
> +          - const: mediatek,mt2712-disp-mutex
> +      - items:
> +          - const: mediatek,mt8167-disp-mutex
> +      - items:
> +          - const: mediatek,mt8173-disp-mutex
> +      - items:
> +          - const: mediatek,mt8183-disp-mutex
> +      - items:
> +          - const: mediatek,mt8192-disp-mutex
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: MUTEX Clock
> +
> +  mediatek,gce-events:
> +    description:
> +      The event id which is mapping to the specific hardware event signal
> +      to gce. The event id is defined in the gce header
> +      include/dt-bindings/gce/<chip>-gce.h of each chips.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    mutex: mutex at 14020000 {
> +        compatible = "mediatek,mt8173-disp-mutex";
> +        reg = <0 0x14020000 0 0x1000>;
> +        interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_MUTEX_32K>;
> +        mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>,
> +                              <CMDQ_EVENT_MUTEX1_STREAM_EOF>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
> new file mode 100644
> index 000000000000..7519db315217
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,od.yaml
> @@ -0,0 +1,53 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,od.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display overdirve
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display overdrive, namely OD, increases the transition values
> +  of pixels between consecutive frames to make LCD rotate faster.
> +  OD device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt2712-disp-od
> +      - items:
> +          - const: mediatek,mt8173-disp-od
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: OD Clock
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    od at 14023000 {
> +        compatible = "mediatek,mt8173-disp-od";
> +        reg = <0 0x14023000 0 0x1000>;
> +        clocks = <&mmsys CLK_MM_DISP_OD>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
> new file mode 100644
> index 000000000000..611a2dbdefa4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl-2l.yaml
> @@ -0,0 +1,88 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl-2l.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display overlay 2 layer
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display overlay 2 layer, namely OVL-2L, provides 2 more layer
> +  for OVL.
> +  OVL-2L device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8183-disp-ovl-2l
> +      - items:
> +          - const: mediatek,mt8192-disp-ovl-2l
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: OVL-2L Clock
> +
> +  iommus:
> +    description:
> +      This property should point to the respective IOMMU block with master port as argument,
> +      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
> +
> +  mediatek,larb:
> +    description:
> +      This property should contain a phandle pointing to the local arbiter devices defined in
> +      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
> +      It must sort according to the local arbiter index, like larb0, larb1, larb2...
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    maxItems: 32
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +  - iommus
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    ovl_2l0: ovl at 14009000 {
> +        compatible = "mediatek,mt8183-disp-ovl-2l";
> +        reg = <0 0x14009000 0 0x1000>;
> +        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&spm MT8183_POWER_DOMAIN_DISP>;
> +        clocks = <&mmsys CLK_MM_DISP_OVL0_2L>;
> +        iommus = <&iommu M4U_PORT_DISP_2L_OVL0_LARB0>;
> +        mediatek,larb = <&larb0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x9000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> new file mode 100644
> index 000000000000..8e4a62cb9c81
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ovl.yaml
> @@ -0,0 +1,98 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,ovl.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display overlay
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display overlay, namely OVL, can do alpha blending from
> +  the memory.
> +  OVL device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt2701-disp-ovl
> +      - items:
> +          - const: mediatek,mt8173-disp-ovl
> +      - items:
> +          - const: mediatek,mt8183-disp-ovl
> +      - items:
> +          - const: mediatek,mt8192-disp-ovl
> +      - items:
> +          - enum:
> +              - mediatek,mt7623-disp-ovl
> +              - mediatek,mt2712-disp-ovl
> +          - enum:
> +              - mediatek,mt2701-disp-ovl
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: OVL Clock
> +
> +  iommus:
> +    description:
> +      This property should point to the respective IOMMU block with master port as argument,
> +      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
> +
> +  mediatek,larb:
> +    description:
> +      This property should contain a phandle pointing to the local arbiter devices defined in
> +      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
> +      It must sort according to the local arbiter index, like larb0, larb1, larb2...
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    maxItems: 32
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +  - iommu
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    ovl0: ovl at 1400c000 {
> +        compatible = "mediatek,mt8173-disp-ovl";
> +        reg = <0 0x1400c000 0 0x1000>;
> +        interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_OVL0>;
> +        iommus = <&iommu M4U_PORT_DISP_OVL0>;
> +        mediatek,larb = <&larb0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xc000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
> new file mode 100644
> index 000000000000..6ac1da2e8871
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,postmask.yaml
> @@ -0,0 +1,69 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,postmask.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display postmask
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display postmask, namely POSTMASK, provides round corner pattern
> +  generation.
> +  POSTMASK device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8192-disp-postmask
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: POSTMASK Clock
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    postmask0: postmask at 1400d000 {
> +        compatible = "mediatek,mt8192-disp-postmask";
> +        reg = <0 0x1400d000 0 0x1000>;
> +        interrupts = <GIC_SPI 262 IRQ_TYPE_LEVEL_HIGH 0>;
> +        power-domains = <&scpsys MT8192_POWER_DOMAIN_DISP>;
> +        clocks = <&mmsys CLK_MM_DISP_POSTMASK0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xd000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
> new file mode 100644
> index 000000000000..a3c5f4c9fbcd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,rdma.yaml
> @@ -0,0 +1,115 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,rdma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Read Direct Memory Access
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek Read Direct Memory Access(RDMA) component used to read the
> +  data into DMA. It provides real time data to the back-end panel
> +  driver, such as DSI, DPI and DP_INTF.
> +  It contains one line buffer to store the sufficient pixel data.
> +  RDMA device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt2701-disp-rdma
> +      - items:
> +          - const: mediatek,mt8173-disp-rdma
> +      - items:
> +          - const: mediatek,mt8183-disp-rdma
> +      - items:
> +          - enum:
> +              - mediatek,mt7623-disp-rdma
> +              - mediatek,mt2712-disp-rdma
> +          - enum:
> +              - mediatek,mt2701-disp-rdma
> +      - items:
> +          - enum:
> +              - mediatek,mt8192-disp-rdma
> +          - enum:
> +              - mediatek,mt8183-disp-rdma
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: RDMA Clock
> +
> +  iommus:
> +    description:
> +      This property should point to the respective IOMMU block with master port as argument,
> +      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
> +
> +  mediatek,larb:
> +    description:
> +      This property should contain a phandle pointing to the local arbiter devices defined in
> +      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
> +      It must sort according to the local arbiter index, like larb0, larb1, larb2...
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    maxItems: 32
> +
> +  mediatek,rdma-fifo-size:
> +    description:
> +      rdma fifo size may be different even in same SOC, add this property to the
> +      corresponding rdma.
> +      The value below is the Max value which defined in hardware data sheet
> +      mediatek,rdma-fifo-size of mt8173-rdma0 is 8K
> +      mediatek,rdma-fifo-size of mt8183-rdma0 is 5K
> +      mediatek,rdma-fifo-size of mt8183-rdma1 is 2K
> +    $ref: /schemas/types.yaml#/definitions/uint32
> +    enum: [8192, 5120, 2048]
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +  - iommus
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    rdma0: rdma at 1400e000 {
> +        compatible = "mediatek,mt8173-disp-rdma";
> +        reg = <0 0x1400e000 0 0x1000>;
> +        interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_RDMA0>;
> +        iommus = <&iommu M4U_PORT_DISP_RDMA0>;
> +        mediatek,larb = <&larb0>;
> +        mediatek,rdma-fifosize = <8192>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0xe000 0x1000>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
> new file mode 100644
> index 000000000000..4f08e89c1067
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,split.yaml
> @@ -0,0 +1,58 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,split.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display split
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display split, namely SPLIT, is used to split stream to two
> +  encoders.
> +  SPLIT device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-split
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: SPLIT Clock
> +
> +required:
> +  - compatible
> +  - reg
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    split0: split at 14018000 {
> +        compatible = "mediatek,mt8173-disp-split";
> +        reg = <0 0x14018000 0 0x1000>;
> +        power-domains = <&spm MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_SPLIT0>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
> new file mode 100644
> index 000000000000..6e8748529e73
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,ufoe.yaml
> @@ -0,0 +1,61 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,ufoe.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek display UFOe
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek display UFOe stands for Unified Frame Optimization engine.
> +  UFOe can cut the data rate for DSI port which may lead to reduce power
> +  consumption.
> +  UFOe device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-ufoe
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: UFOe Clock
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    ufoe at 1401a000 {
> +        compatible = "mediatek,mt8173-disp-ufoe";
> +        reg = <0 0x1401a000 0 0x1000>;
> +        interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_UFOE>;
> +    };
> diff --git a/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
> new file mode 100644
> index 000000000000..aaf5649b6413
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/mediatek/mediatek,wdma.yaml
> @@ -0,0 +1,86 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/mediatek/mediatek,wdma.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek Write Direct Memory Access
> +
> +maintainers:
> +  - Chun-Kuang Hu <chunkuang.hu at kernel.org>
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +description: |
> +  Mediatek Write Direct Memory Access(WDMA) component used to write
> +  the data into DMA.
> +  WDMA device node must be siblings to the central MMSYS_CONFIG node.
> +  For a description of the MMSYS_CONFIG binding, see
> +  Documentation/devicetree/bindings/arm/mediatek/mediatek,mmsys.yaml
> +  for details.
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - items:
> +          - const: mediatek,mt8173-disp-wdma
> +
> +  reg:
> +    maxItems: 1
> +
> +  interrupts:
> +    maxItems: 1
> +
> +  power-domains:
> +    description: A phandle and PM domain specifier as defined by bindings of
> +      the power controller specified by phandle. See
> +      Documentation/devicetree/bindings/power/power-domain.yaml for details.
> +
> +  clocks:
> +    items:
> +      - description: WDMA Clock
> +
> +  iommus:
> +    description:
> +      This property should point to the respective IOMMU block with master port as argument,
> +      see Documentation/devicetree/bindings/iommu/mediatek,iommu.yaml for details.
> +
> +  mediatek,larb:
> +    description:
> +      This property should contain a phandle pointing to the local arbiter devices defined in
> +      Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml.
> +      It must sort according to the local arbiter index, like larb0, larb1, larb2...
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    minItems: 1
> +    maxItems: 32
> +
> +  mediatek,gce-client-reg:
> +    description: The register of client driver can be configured by gce with
> +      4 arguments defined in this property, such as phandle of gce, subsys id,
> +      register offset and size. Each GCE subsys id is mapping to a client
> +      defined in the header include/dt-bindings/gce/<chip>-gce.h.
> +    $ref: /schemas/types.yaml#/definitions/phandle-array
> +    maxItems: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - power-domains
> +  - clocks
> +  - iommus
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +
> +    wdma0: wdma at 14011000 {
> +        compatible = "mediatek,mt8173-disp-wdma";
> +        reg = <0 0x14011000 0 0x1000>;
> +        interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_LOW>;
> +        power-domains = <&scpsys MT8173_POWER_DOMAIN_MM>;
> +        clocks = <&mmsys CLK_MM_DISP_WDMA0>;
> +        iommus = <&iommu M4U_PORT_DISP_WDMA0>;
> +        mediatek,larb = <&larb0>;
> +        mediatek,gce-client-reg = <&gce SUBSYS_1401XXXX 0x1000 0x1000>;
> +    };
> --
> 2.18.0
>


From mark.rutland at arm.com  Thu Jan 27 07:52:13 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Jan 2022 15:52:13 +0000
Subject: [bootwrapper PATCH v3 02/15] aarch64: correct SCTLR_EL1_KERNEL
 for AA32 kernels
In-Reply-To: <20220126150338.5af163e5@donnerap.cambridge.arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-3-mark.rutland@arm.com>
 <20220126150338.5af163e5@donnerap.cambridge.arm.com>
Message-ID: <YfK/rXWybS55syzi@FVFF77S0Q05N>

On Wed, Jan 26, 2022 at 03:03:38PM +0000, Andre Przywara wrote:
> On Tue, 25 Jan 2022 15:00:44 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> Hi,
> 
> > Bits [31:0] of the AArch64 SCTLR_EL1 register are architecturally mapped
> > to bits [31:0] of the AArch32 SCTLR register. This means that any
> > individual bit always has the same value across the two registers.
> > 
> > Across the two registers, the same bit may have distinct meanings,
> > distinct RESx behaviour, and distinct reset behaviour. For example,
> > SCTLR_EL1[28] is nTLSMD, which we wich to initialize to 0b1, whereas
> > SCTLR[28] is TRE, which we wish to initialize to 0b0.
> > 
> > To avoid setting bits which we did not intend to, and in preparation for
> > configuring more AArch64 RES1 bits, this patch decouples the
> > SCTLR_EL1_KERNEL value used for AArch32 kernels from the SCTLR_EL1_RES1
> > definitions such that is does not inherit AArch64 SCTLR_EL1 bits which
> > would be problematic in the AArch32 SCTLR. For now we open-code a copy
> > of the bits defined in arch/aarch64/include/asm/cpu.h.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > Cc: Andre Przywara <andre.przywara at arm.com>
> > ---
> >  arch/aarch64/include/asm/cpu.h | 11 +++++++++--
> >  1 file changed, 9 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> > index e3269b8..49d3f86 100644
> > --- a/arch/aarch64/include/asm/cpu.h
> > +++ b/arch/aarch64/include/asm/cpu.h
> > @@ -36,8 +36,15 @@
> >  #define SCTLR_EL1_RES1		(3 << 28 | 3 << 22 | 1 << 11)
> >  
> >  #ifdef KERNEL_32
> > -/* 32-bit kernel decompressor uses CP15 barriers */
> > -#define SCTLR_EL1_KERNEL	(SCTLR_EL1_RES1 | SCTLR_EL1_CP15BEN)
> > +/*
> > + * When booting a 32-bit kernel, EL1 uses AArch32 and registers which are
> > + * architecturally mapped must be configured with the AArch32 layout.
> > + *
> > + * We copy the AArch32 definition of SCTLR_KERNEL here.
> > + *
> > + * TODO: restructure the headers to share a single definition.
> > + */
> > +#define SCTLR_EL1_KERNEL	(3 << 22 | 1 << 11 | 1 << 5 | 3 << 4)
> 
> Is the verbatim copying of the value, including the redundancy, intended?

Yup, the intent is to have the exact same definition, overlapping bits and all.

I would like to clean that up in future, but for now I want this to clearly be
the same.

> Maybe that meant 3 << 3, as bits[4:3] are documented as "Reserved,
> RAO/SBOP" in the ARMv7 ARM?
> It's fine with me either way, since it copies the aarch32 value, just
> wanted to check:
> 
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks!

Mark.


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:49 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:49 +0100
Subject: Patch "ARM: dts: gpio-ranges property is now required" has been added
 to the 5.4-stable tree
In-Reply-To: <20220125194222.12783-8-f.fainelli@gmail.com>
Message-ID: <16432993096685@kroah.com>


This is a note to let you know that I've just added the patch titled

    ARM: dts: gpio-ranges property is now required

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm-dts-gpio-ranges-property-is-now-required.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:22 -0800
Subject: ARM: dts: gpio-ranges property is now required
To: stable at vger.kernel.org
Cc: Phil Elwell <phil at raspberrypi.com>, Stefan Wahren <stefan.wahren at i2se.com>, Florian Fainelli <f.fainelli at gmail.com>, Jan Kiszka <jan.kiszka at web.de>, Linus Walleij <linus.walleij at linaro.org>, Olof Johansson <olof at lixom.net>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-8-f.fainelli at gmail.com>

From: Phil Elwell <phil at raspberrypi.com>

commit c8013355ead68dce152cf426686f8a5f80d88b40 upstream

Since [1], added in 5.7, the absence of a gpio-ranges property has
prevented GPIOs from being restored to inputs when released.
Add those properties for BCM283x and BCM2711 devices.

[1] commit 2ab73c6d8323 ("gpio: Support GPIO controllers without
    pin-ranges")

Link: https://lore.kernel.org/r/20220104170247.956760-1-linus.walleij at linaro.org
Fixes: 2ab73c6d8323 ("gpio: Support GPIO controllers without pin-ranges")
Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
Reported-by: Florian Fainelli <f.fainelli at gmail.com>
Reported-by: Jan Kiszka <jan.kiszka at web.de>
Signed-off-by: Phil Elwell <phil at raspberrypi.com>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Link: https://lore.kernel.org/r/20211206092237.4105895-3-phil at raspberrypi.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Acked-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Olof Johansson <olof at lixom.net>
[florian: Remove bcm2711.dtsi hunk which does not exist in 5.4]
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 arch/arm/boot/dts/bcm283x.dtsi |    1 +
 1 file changed, 1 insertion(+)

--- a/arch/arm/boot/dts/bcm283x.dtsi
+++ b/arch/arm/boot/dts/bcm283x.dtsi
@@ -183,6 +183,7 @@
 
 			interrupt-controller;
 			#interrupt-cells = <2>;
+			gpio-ranges = <&gpio 0 0 54>;
 
 			/* Defines pin muxing groups according to
 			 * BCM2835-ARM-Peripherals.pdf page 102.


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:49 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:49 +0100
Subject: Patch "pinctrl: bcm2835: Add support for all GPIOs on BCM2711" has
 been added to the 5.4-stable tree
In-Reply-To: <20220125194222.12783-4-f.fainelli@gmail.com>
Message-ID: <164329930924135@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Add support for all GPIOs on BCM2711

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:18 -0800
Subject: pinctrl: bcm2835: Add support for all GPIOs on BCM2711
To: stable at vger.kernel.org
Cc: Stefan Wahren <stefan.wahren at i2se.com>, Nicolas Saenz Julienne <nsaenzjulienne at suse.de>, Linus Walleij <linus.walleij at linaro.org>, Florian Fainelli <f.fainelli at gmail.com>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, Phil Elwell <phil at raspberrypi.com>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-4-f.fainelli at gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit b1d84a3d0a26c5844a22bc09a42704b9371208bb upstream

The BCM2711 supports 58 GPIOs. So extend pinctrl and GPIOs accordingly.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1581166975-22949-4-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |   54 ++++++++++++++++++++++++++--------
 1 file changed, 42 insertions(+), 12 deletions(-)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -37,6 +37,7 @@
 
 #define MODULE_NAME "pinctrl-bcm2835"
 #define BCM2835_NUM_GPIOS 54
+#define BCM2711_NUM_GPIOS 58
 #define BCM2835_NUM_BANKS 2
 #define BCM2835_NUM_IRQS  3
 
@@ -78,7 +79,7 @@ struct bcm2835_pinctrl {
 
 	/* note: locking assumes each bank will have its own unsigned long */
 	unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
-	unsigned int irq_type[BCM2835_NUM_GPIOS];
+	unsigned int irq_type[BCM2711_NUM_GPIOS];
 
 	struct pinctrl_dev *pctl_dev;
 	struct gpio_chip gpio_chip;
@@ -145,6 +146,10 @@ static struct pinctrl_pin_desc bcm2835_g
 	BCM2835_GPIO_PIN(51),
 	BCM2835_GPIO_PIN(52),
 	BCM2835_GPIO_PIN(53),
+	BCM2835_GPIO_PIN(54),
+	BCM2835_GPIO_PIN(55),
+	BCM2835_GPIO_PIN(56),
+	BCM2835_GPIO_PIN(57),
 };
 
 /* one pin per group */
@@ -203,6 +208,10 @@ static const char * const bcm2835_gpio_g
 	"gpio51",
 	"gpio52",
 	"gpio53",
+	"gpio54",
+	"gpio55",
+	"gpio56",
+	"gpio57",
 };
 
 enum bcm2835_fsel {
@@ -353,6 +362,22 @@ static const struct gpio_chip bcm2835_gp
 	.can_sleep = false,
 };
 
+static const struct gpio_chip bcm2711_gpio_chip = {
+	.label = "pinctrl-bcm2711",
+	.owner = THIS_MODULE,
+	.request = gpiochip_generic_request,
+	.free = gpiochip_generic_free,
+	.direction_input = bcm2835_gpio_direction_input,
+	.direction_output = bcm2835_gpio_direction_output,
+	.get_direction = bcm2835_gpio_get_direction,
+	.get = bcm2835_gpio_get,
+	.set = bcm2835_gpio_set,
+	.set_config = gpiochip_generic_config,
+	.base = -1,
+	.ngpio = BCM2711_NUM_GPIOS,
+	.can_sleep = false,
+};
+
 static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc,
 					 unsigned int bank, u32 mask)
 {
@@ -399,7 +424,7 @@ static void bcm2835_gpio_irq_handler(str
 		bcm2835_gpio_irq_handle_bank(pc, 0, 0xf0000000);
 		bcm2835_gpio_irq_handle_bank(pc, 1, 0x00003fff);
 		break;
-	case 2: /* IRQ2 covers GPIOs 46-53 */
+	case 2: /* IRQ2 covers GPIOs 46-57 */
 		bcm2835_gpio_irq_handle_bank(pc, 1, 0x003fc000);
 		break;
 	}
@@ -618,7 +643,7 @@ static struct irq_chip bcm2835_gpio_irq_
 
 static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
 {
-	return ARRAY_SIZE(bcm2835_gpio_groups);
+	return BCM2835_NUM_GPIOS;
 }
 
 static const char *bcm2835_pctl_get_group_name(struct pinctrl_dev *pctldev,
@@ -776,7 +801,7 @@ static int bcm2835_pctl_dt_node_to_map(s
 		err = of_property_read_u32_index(np, "brcm,pins", i, &pin);
 		if (err)
 			goto out;
-		if (pin >= ARRAY_SIZE(bcm2835_gpio_pins)) {
+		if (pin >= pc->pctl_desc.npins) {
 			dev_err(pc->dev, "%pOF: invalid brcm,pins value %d\n",
 				np, pin);
 			err = -EINVAL;
@@ -852,7 +877,7 @@ static int bcm2835_pmx_get_function_grou
 {
 	/* every pin can do every function */
 	*groups = bcm2835_gpio_groups;
-	*num_groups = ARRAY_SIZE(bcm2835_gpio_groups);
+	*num_groups = BCM2835_NUM_GPIOS;
 
 	return 0;
 }
@@ -1055,7 +1080,7 @@ static const struct pinconf_ops bcm2711_
 static const struct pinctrl_desc bcm2835_pinctrl_desc = {
 	.name = MODULE_NAME,
 	.pins = bcm2835_gpio_pins,
-	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.npins = BCM2835_NUM_GPIOS,
 	.pctlops = &bcm2835_pctl_ops,
 	.pmxops = &bcm2835_pmx_ops,
 	.confops = &bcm2835_pinconf_ops,
@@ -1063,9 +1088,9 @@ static const struct pinctrl_desc bcm2835
 };
 
 static const struct pinctrl_desc bcm2711_pinctrl_desc = {
-	.name = MODULE_NAME,
+	.name = "pinctrl-bcm2711",
 	.pins = bcm2835_gpio_pins,
-	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.npins = BCM2711_NUM_GPIOS,
 	.pctlops = &bcm2835_pctl_ops,
 	.pmxops = &bcm2835_pmx_ops,
 	.confops = &bcm2711_pinconf_ops,
@@ -1077,6 +1102,11 @@ static const struct pinctrl_gpio_range b
 	.npins = BCM2835_NUM_GPIOS,
 };
 
+static const struct pinctrl_gpio_range bcm2711_pinctrl_gpio_range = {
+	.name = "pinctrl-bcm2711",
+	.npins = BCM2711_NUM_GPIOS,
+};
+
 struct bcm_plat_data {
 	const struct gpio_chip *gpio_chip;
 	const struct pinctrl_desc *pctl_desc;
@@ -1090,9 +1120,9 @@ static const struct bcm_plat_data bcm283
 };
 
 static const struct bcm_plat_data bcm2711_plat_data = {
-	.gpio_chip = &bcm2835_gpio_chip,
+	.gpio_chip = &bcm2711_gpio_chip,
 	.pctl_desc = &bcm2711_pinctrl_desc,
-	.gpio_range = &bcm2835_pinctrl_gpio_range,
+	.gpio_range = &bcm2711_pinctrl_gpio_range,
 };
 
 static const struct of_device_id bcm2835_pinctrl_match[] = {
@@ -1118,8 +1148,8 @@ static int bcm2835_pinctrl_probe(struct
 	int err, i;
 	const struct of_device_id *match;
 
-	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2835_NUM_GPIOS);
-	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2835_NUM_GPIOS);
+	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
+	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
 
 	pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL);
 	if (!pc)


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:49 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:49 +0100
Subject: Patch "pinctrl: bcm2835: Add support for wake-up interrupts" has been
 added to the 5.4-stable tree
In-Reply-To: <20220125194222.12783-6-f.fainelli@gmail.com>
Message-ID: <16432993096778@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Add support for wake-up interrupts

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:20 -0800
Subject: pinctrl: bcm2835: Add support for wake-up interrupts
To: stable at vger.kernel.org
Cc: Florian Fainelli <f.fainelli at gmail.com>, Linus Walleij <linus.walleij at linaro.org>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, Phil Elwell <phil at raspberrypi.com>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-6-f.fainelli at gmail.com>

From: Florian Fainelli <f.fainelli at gmail.com>

commit 920fecc1aa4591da27ef9dcb338fc5da86b404d7 upstream

Leverage the IRQCHIP_MASK_ON_SUSPEND flag in order to avoid having to
specifically treat the GPIO interrupts during suspend and resume, and
simply implement an irq_set_wake() callback that is responsible for
enabling the parent wake-up interrupt as a wake-up interrupt.

To avoid allocating unnecessary resources for other chips, the wake-up
interrupts are only initialized if we have a brcm,bcm7211-gpio
compatibility string.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20200531001101.24945-5-f.fainelli at gmail.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |   76 +++++++++++++++++++++++++++++++++-
 1 file changed, 75 insertions(+), 1 deletion(-)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -19,6 +19,7 @@
 #include <linux/irq.h>
 #include <linux/irqdesc.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
@@ -76,6 +77,7 @@
 struct bcm2835_pinctrl {
 	struct device *dev;
 	void __iomem *base;
+	int *wake_irq;
 
 	/* note: locking assumes each bank will have its own unsigned long */
 	unsigned long enabled_irq_map[BCM2835_NUM_BANKS];
@@ -432,6 +434,11 @@ static void bcm2835_gpio_irq_handler(str
 	chained_irq_exit(host_chip, desc);
 }
 
+static irqreturn_t bcm2835_gpio_wake_irq_handler(int irq, void *dev_id)
+{
+	return IRQ_HANDLED;
+}
+
 static inline void __bcm2835_gpio_irq_config(struct bcm2835_pinctrl *pc,
 	unsigned reg, unsigned offset, bool enable)
 {
@@ -631,6 +638,34 @@ static void bcm2835_gpio_irq_ack(struct
 	bcm2835_gpio_set_bit(pc, GPEDS0, gpio);
 }
 
+static int bcm2835_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
+{
+	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
+	struct bcm2835_pinctrl *pc = gpiochip_get_data(chip);
+	unsigned gpio = irqd_to_hwirq(data);
+	unsigned int irqgroup;
+	int ret = -EINVAL;
+
+	if (!pc->wake_irq)
+		return ret;
+
+	if (gpio <= 27)
+		irqgroup = 0;
+	else if (gpio >= 28 && gpio <= 45)
+		irqgroup = 1;
+	else if (gpio >= 46 && gpio <= 57)
+		irqgroup = 2;
+	else
+		return ret;
+
+	if (on)
+		ret = enable_irq_wake(pc->wake_irq[irqgroup]);
+	else
+		ret = disable_irq_wake(pc->wake_irq[irqgroup]);
+
+	return ret;
+}
+
 static struct irq_chip bcm2835_gpio_irq_chip = {
 	.name = MODULE_NAME,
 	.irq_enable = bcm2835_gpio_irq_enable,
@@ -639,6 +674,8 @@ static struct irq_chip bcm2835_gpio_irq_
 	.irq_ack = bcm2835_gpio_irq_ack,
 	.irq_mask = bcm2835_gpio_irq_disable,
 	.irq_unmask = bcm2835_gpio_irq_enable,
+	.irq_set_wake = bcm2835_gpio_irq_set_wake,
+	.flags = IRQCHIP_MASK_ON_SUSPEND,
 };
 
 static int bcm2835_pctl_get_groups_count(struct pinctrl_dev *pctldev)
@@ -1151,6 +1188,7 @@ static int bcm2835_pinctrl_probe(struct
 	struct resource iomem;
 	int err, i;
 	const struct of_device_id *match;
+	int is_7211 = 0;
 
 	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_pins) != BCM2711_NUM_GPIOS);
 	BUILD_BUG_ON(ARRAY_SIZE(bcm2835_gpio_groups) != BCM2711_NUM_GPIOS);
@@ -1177,6 +1215,7 @@ static int bcm2835_pinctrl_probe(struct
 		return -EINVAL;
 
 	pdata = match->data;
+	is_7211 = of_device_is_compatible(np, "brcm,bcm7211-gpio");
 
 	pc->gpio_chip = *pdata->gpio_chip;
 	pc->gpio_chip.parent = dev;
@@ -1211,6 +1250,15 @@ static int bcm2835_pinctrl_probe(struct
 				     GFP_KERNEL);
 	if (!girq->parents)
 		return -ENOMEM;
+
+	if (is_7211) {
+		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
+					    sizeof(*pc->wake_irq),
+					    GFP_KERNEL);
+		if (!pc->wake_irq)
+			return -ENOMEM;
+	}
+
 	/*
 	 * Use the same handler for all groups: this is necessary
 	 * since we use one gpiochip to cover all lines - the
@@ -1218,8 +1266,34 @@ static int bcm2835_pinctrl_probe(struct
 	 * bank that was firing the IRQ and look up the per-group
 	 * and bank data.
 	 */
-	for (i = 0; i < BCM2835_NUM_IRQS; i++)
+	for (i = 0; i < BCM2835_NUM_IRQS; i++) {
+		int len;
+		char *name;
+
 		girq->parents[i] = irq_of_parse_and_map(np, i);
+		if (!is_7211)
+			continue;
+
+		/* Skip over the all banks interrupts */
+		pc->wake_irq[i] = irq_of_parse_and_map(np, i +
+						       BCM2835_NUM_IRQS + 1);
+
+		len = strlen(dev_name(pc->dev)) + 16;
+		name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
+		if (!name)
+			return -ENOMEM;
+
+		snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
+
+		/* These are optional interrupts */
+		err = devm_request_irq(dev, pc->wake_irq[i],
+				       bcm2835_gpio_wake_irq_handler,
+				       IRQF_SHARED, name, pc);
+		if (err)
+			dev_warn(dev, "unable to request wake IRQ %d\n",
+				 pc->wake_irq[i]);
+	}
+
 	girq->default_type = IRQ_TYPE_NONE;
 	girq->handler = handle_level_irq;
 


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:49 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:49 +0100
Subject: Patch "pinctrl: bcm2835: Change init order for gpio hogs" has been
 added to the 5.4-stable tree
In-Reply-To: <20220125194222.12783-7-f.fainelli@gmail.com>
Message-ID: <1643299309209162@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Change init order for gpio hogs

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:21 -0800
Subject: pinctrl: bcm2835: Change init order for gpio hogs
To: stable at vger.kernel.org
Cc: Phil Elwell <phil at raspberrypi.com>, Florian Fainelli <f.fainelli at gmail.com>, Linus Walleij <linus.walleij at linaro.org>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-7-f.fainelli at gmail.com>

From: Phil Elwell <phil at raspberrypi.com>

commit 266423e60ea1b953fcc0cd97f3dad85857e434d1 upstream

...and gpio-ranges

pinctrl-bcm2835 is a combined pinctrl/gpio driver. Currently the gpio
side is registered first, but this breaks gpio hogs (which are
configured during gpiochip_add_data). Part of the hog initialisation
is a call to pinctrl_gpio_request, and since the pinctrl driver hasn't
yet been registered this results in an -EPROBE_DEFER from which it can
never recover.

Change the initialisation sequence to register the pinctrl driver
first.

This also solves a similar problem with the gpio-ranges property, which
is required in order for released pins to be returned to inputs.

Fixes: 73345a18d464b ("pinctrl: bcm2835: Pass irqchip when adding gpiochip")
Signed-off-by: Phil Elwell <phil at raspberrypi.com>
Reviewed-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20211206092237.4105895-2-phil at raspberrypi.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |   29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1241,6 +1241,18 @@ static int bcm2835_pinctrl_probe(struct
 		raw_spin_lock_init(&pc->irq_lock[i]);
 	}
 
+	pc->pctl_desc = *pdata->pctl_desc;
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
+	if (IS_ERR(pc->pctl_dev)) {
+		gpiochip_remove(&pc->gpio_chip);
+		return PTR_ERR(pc->pctl_dev);
+	}
+
+	pc->gpio_range = *pdata->gpio_range;
+	pc->gpio_range.base = pc->gpio_chip.base;
+	pc->gpio_range.gc = &pc->gpio_chip;
+	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
+
 	girq = &pc->gpio_chip.irq;
 	girq->chip = &bcm2835_gpio_irq_chip;
 	girq->parent_handler = bcm2835_gpio_irq_handler;
@@ -1248,8 +1260,10 @@ static int bcm2835_pinctrl_probe(struct
 	girq->parents = devm_kcalloc(dev, BCM2835_NUM_IRQS,
 				     sizeof(*girq->parents),
 				     GFP_KERNEL);
-	if (!girq->parents)
+	if (!girq->parents) {
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return -ENOMEM;
+	}
 
 	if (is_7211) {
 		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
@@ -1300,21 +1314,10 @@ static int bcm2835_pinctrl_probe(struct
 	err = gpiochip_add_data(&pc->gpio_chip, pc);
 	if (err) {
 		dev_err(dev, "could not add GPIO chip\n");
+		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
 		return err;
 	}
 
-	pc->pctl_desc = *pdata->pctl_desc;
-	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
-	if (IS_ERR(pc->pctl_dev)) {
-		gpiochip_remove(&pc->gpio_chip);
-		return PTR_ERR(pc->pctl_dev);
-	}
-
-	pc->gpio_range = *pdata->gpio_range;
-	pc->gpio_range.base = pc->gpio_chip.base;
-	pc->gpio_range.gc = &pc->gpio_chip;
-	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);
-
 	return 0;
 }
 


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:49 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:49 +0100
Subject: Patch "pinctrl: bcm2835: Drop unused define" has been added to the
 5.4-stable tree
In-Reply-To: <20220125194222.12783-2-f.fainelli@gmail.com>
Message-ID: <1643299309141117@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Drop unused define

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-drop-unused-define.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:16 -0800
Subject: pinctrl: bcm2835: Drop unused define
To: stable at vger.kernel.org
Cc: Stefan Wahren <stefan.wahren at i2se.com>, Nicolas Saenz Julienne <nsaenzjulienne at suse.de>, Linus Walleij <linus.walleij at linaro.org>, Florian Fainelli <f.fainelli at gmail.com>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, Phil Elwell <phil at raspberrypi.com>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-2-f.fainelli at gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit be30d5de0a5a52c6ee2cc453a51301037ab94aa upstream

There is no usage for this define, so drop it.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1580148908-4863-2-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |    3 ---
 1 file changed, 3 deletions(-)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -40,9 +40,6 @@
 #define BCM2835_NUM_BANKS 2
 #define BCM2835_NUM_IRQS  3
 
-#define BCM2835_PIN_BITMAP_SZ \
-	DIV_ROUND_UP(BCM2835_NUM_GPIOS, sizeof(unsigned long) * 8)
-
 /* GPIO register offsets */
 #define GPFSEL0		0x0	/* Function Select */
 #define GPSET0		0x1c	/* Pin Output Set */


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:50 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:50 +0100
Subject: Patch "pinctrl: bcm2835: Refactor platform data" has been added to
 the 5.4-stable tree
In-Reply-To: <20220125194222.12783-3-f.fainelli@gmail.com>
Message-ID: <1643299310190230@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Refactor platform data

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-refactor-platform-data.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:17 -0800
Subject: pinctrl: bcm2835: Refactor platform data
To: stable at vger.kernel.org
Cc: Stefan Wahren <stefan.wahren at i2se.com>, Nicolas Saenz Julienne <nsaenzjulienne at suse.de>, Linus Walleij <linus.walleij at linaro.org>, Florian Fainelli <f.fainelli at gmail.com>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, Phil Elwell <phil at raspberrypi.com>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-3-f.fainelli at gmail.com>

From: Stefan Wahren <stefan.wahren at i2se.com>

commit 90bfaf028d61a6d523c685b63c2bcc94eebb8057 upstream

This prepares the platform data to be easier to extend for more GPIOs.
Except of this there is no functional change.

Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
Link: https://lore.kernel.org/r/1581166975-22949-3-git-send-email-stefan.wahren at i2se.com
Reviewed-by: Nicolas Saenz Julienne <nsaenzjulienne at suse.de>
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |   57 ++++++++++++++++++++++++++--------
 1 file changed, 44 insertions(+), 13 deletions(-)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -82,6 +82,7 @@ struct bcm2835_pinctrl {
 
 	struct pinctrl_dev *pctl_dev;
 	struct gpio_chip gpio_chip;
+	struct pinctrl_desc pctl_desc;
 	struct pinctrl_gpio_range gpio_range;
 
 	raw_spinlock_t irq_lock[BCM2835_NUM_BANKS];
@@ -1051,7 +1052,7 @@ static const struct pinconf_ops bcm2711_
 	.pin_config_set = bcm2711_pinconf_set,
 };
 
-static struct pinctrl_desc bcm2835_pinctrl_desc = {
+static const struct pinctrl_desc bcm2835_pinctrl_desc = {
 	.name = MODULE_NAME,
 	.pins = bcm2835_gpio_pins,
 	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
@@ -1061,19 +1062,47 @@ static struct pinctrl_desc bcm2835_pinct
 	.owner = THIS_MODULE,
 };
 
-static struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
+static const struct pinctrl_desc bcm2711_pinctrl_desc = {
+	.name = MODULE_NAME,
+	.pins = bcm2835_gpio_pins,
+	.npins = ARRAY_SIZE(bcm2835_gpio_pins),
+	.pctlops = &bcm2835_pctl_ops,
+	.pmxops = &bcm2835_pmx_ops,
+	.confops = &bcm2711_pinconf_ops,
+	.owner = THIS_MODULE,
+};
+
+static const struct pinctrl_gpio_range bcm2835_pinctrl_gpio_range = {
 	.name = MODULE_NAME,
 	.npins = BCM2835_NUM_GPIOS,
 };
 
+struct bcm_plat_data {
+	const struct gpio_chip *gpio_chip;
+	const struct pinctrl_desc *pctl_desc;
+	const struct pinctrl_gpio_range *gpio_range;
+};
+
+static const struct bcm_plat_data bcm2835_plat_data = {
+	.gpio_chip = &bcm2835_gpio_chip,
+	.pctl_desc = &bcm2835_pinctrl_desc,
+	.gpio_range = &bcm2835_pinctrl_gpio_range,
+};
+
+static const struct bcm_plat_data bcm2711_plat_data = {
+	.gpio_chip = &bcm2835_gpio_chip,
+	.pctl_desc = &bcm2711_pinctrl_desc,
+	.gpio_range = &bcm2835_pinctrl_gpio_range,
+};
+
 static const struct of_device_id bcm2835_pinctrl_match[] = {
 	{
 		.compatible = "brcm,bcm2835-gpio",
-		.data = &bcm2835_pinconf_ops,
+		.data = &bcm2835_plat_data,
 	},
 	{
 		.compatible = "brcm,bcm2711-gpio",
-		.data = &bcm2711_pinconf_ops,
+		.data = &bcm2711_plat_data,
 	},
 	{}
 };
@@ -1082,6 +1111,7 @@ static int bcm2835_pinctrl_probe(struct
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
+	const struct bcm_plat_data *pdata;
 	struct bcm2835_pinctrl *pc;
 	struct gpio_irq_chip *girq;
 	struct resource iomem;
@@ -1108,7 +1138,13 @@ static int bcm2835_pinctrl_probe(struct
 	if (IS_ERR(pc->base))
 		return PTR_ERR(pc->base);
 
-	pc->gpio_chip = bcm2835_gpio_chip;
+	match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
+	if (!match)
+		return -EINVAL;
+
+	pdata = match->data;
+
+	pc->gpio_chip = *pdata->gpio_chip;
 	pc->gpio_chip.parent = dev;
 	pc->gpio_chip.of_node = np;
 
@@ -1159,19 +1195,14 @@ static int bcm2835_pinctrl_probe(struct
 		return err;
 	}
 
-	match = of_match_node(bcm2835_pinctrl_match, pdev->dev.of_node);
-	if (match) {
-		bcm2835_pinctrl_desc.confops =
-			(const struct pinconf_ops *)match->data;
-	}
-
-	pc->pctl_dev = devm_pinctrl_register(dev, &bcm2835_pinctrl_desc, pc);
+	pc->pctl_desc = *pdata->pctl_desc;
+	pc->pctl_dev = devm_pinctrl_register(dev, &pc->pctl_desc, pc);
 	if (IS_ERR(pc->pctl_dev)) {
 		gpiochip_remove(&pc->gpio_chip);
 		return PTR_ERR(pc->pctl_dev);
 	}
 
-	pc->gpio_range = bcm2835_pinctrl_gpio_range;
+	pc->gpio_range = *pdata->gpio_range;
 	pc->gpio_range.base = pc->gpio_chip.base;
 	pc->gpio_range.gc = &pc->gpio_chip;
 	pinctrl_add_gpio_range(pc->pctl_dev, &pc->gpio_range);


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From gregkh at linuxfoundation.org  Thu Jan 27 08:01:50 2022
From: gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
Date: Thu, 27 Jan 2022 17:01:50 +0100
Subject: Patch "pinctrl: bcm2835: Match BCM7211 compatible string" has been
 added to the 5.4-stable tree
In-Reply-To: <20220125194222.12783-5-f.fainelli@gmail.com>
Message-ID: <164329931012062@kroah.com>


This is a note to let you know that I've just added the patch titled

    pinctrl: bcm2835: Match BCM7211 compatible string

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     pinctrl-bcm2835-match-bcm7211-compatible-string.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From foo at baz Thu Jan 27 04:40:37 PM CET 2022
From: Florian Fainelli <f.fainelli at gmail.com>
Date: Tue, 25 Jan 2022 11:42:19 -0800
Subject: pinctrl: bcm2835: Match BCM7211 compatible string
To: stable at vger.kernel.org
Cc: Florian Fainelli <f.fainelli at gmail.com>, Linus Walleij <linus.walleij at linaro.org>, Rob Herring <robh+dt at kernel.org>, Mark Rutland <mark.rutland at arm.com>, Ray Jui <rjui at broadcom.com>, Scott Branden <sbranden at broadcom.com>, bcm-kernel-feedback-list at broadcom.com (maintainer:BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITE...), Eric Anholt <eric at anholt.net>, Stefan Wahren <wahrenst at gmx.net>, Nicolas Saenz Julienne <nsaenz at kernel.org>, Phil Elwell <phil at raspberrypi.com>, devicetree at vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS), linux-kernel at vger.kernel.org (open list), linux-gpio at vger.kernel.org (open list:PIN CONTROL SUBSYSTEM), linux-rpi-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE), linux-arm-kernel at lists.infradead.org (moderated list:BROADCOM BCM2711/BCM2835 ARM ARCHITECTURE)
Message-ID: <20220125194222.12783-5-f.fainelli at gmail.com>

From: Florian Fainelli <f.fainelli at gmail.com>

commit 562c856f96d22ef1204b0a314bc52e85617199b4 upstream

The BCM7211 SoC uses the same pinconf_ops as the ones defined for the
BCM2711 SoC, match the compatible string and use the correct set of
options.

Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Link: https://lore.kernel.org/r/20200531001101.24945-4-f.fainelli at gmail.com
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1134,6 +1134,10 @@ static const struct of_device_id bcm2835
 		.compatible = "brcm,bcm2711-gpio",
 		.data = &bcm2711_plat_data,
 	},
+	{
+		.compatible = "brcm,bcm7211-gpio",
+		.data = &bcm2711_plat_data,
+	},
 	{}
 };
 


Patches currently in stable-queue which might be from f.fainelli at gmail.com are

queue-5.4/pinctrl-bcm2835-drop-unused-define.patch
queue-5.4/arm-dts-gpio-ranges-property-is-now-required.patch
queue-5.4/pinctrl-bcm2835-add-support-for-wake-up-interrupts.patch
queue-5.4/pinctrl-bcm2835-change-init-order-for-gpio-hogs.patch
queue-5.4/pinctrl-bcm2835-refactor-platform-data.patch
queue-5.4/pinctrl-bcm2835-match-bcm7211-compatible-string.patch
queue-5.4/pinctrl-bcm2835-add-support-for-all-gpios-on-bcm2711.patch


From mark.rutland at arm.com  Thu Jan 27 08:08:50 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Jan 2022 16:08:50 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfA3D3c+lOyybNT3@sirena.org.uk>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk> <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
 <YfA3D3c+lOyybNT3@sirena.org.uk>
Message-ID: <YfLDkoihLFnixAaQ@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 05:44:47PM +0000, Mark Brown wrote:
> On Tue, Jan 25, 2022 at 04:33:39PM +0000, Mark Rutland wrote:
> > On Tue, Jan 25, 2022 at 03:59:38PM +0000, Mark Brown wrote:
> > > On Tue, Jan 25, 2022 at 03:00:43PM +0000, Mark Rutland wrote:
> 
> > > > As the same time, rename ZCR_EL3_LEN_MASK to ZCR_EL3_LEN_MAX, as it is
> > > > used as a value rather than as a bit mask.
> 
> > > Well, it's both and we do call it a mask in both the kernel and TF-A
> > > too...
> 
> > Here specifically in the boot-wrapper I'm just using it as a value, so I don't
> > see that those are relevant?
> 
> That's also a bunch of the other usage - the kernel uses it to set the
> maximum available value by virtue of setting every possible bit in the
> bitfield, though it does also use it as a mask in places.
> 
> > The idea was to be consistent with the <register>_<field>_<valuename> naming,
> > and avoiding the "why are you programming a mask as the value" questions from
> > last time around, where the unambiguous options are:
> 
> I've not seen that - I did see that there had been some discussion as to
> why the code had been including the reserved bits but hadn't seen any
> discussion of confusion between mask and max.

In:

  https://lore.kernel.org/all/20220117143104.28db5001 at donnerap.cambridge.arm.com/#t

w.r.t. the use of ZCR_EL3_LEN, Andre said:

| So when comparing this to the other uses of XXX_EL3_YYY, they typically
| describe a mask, but here we seems to abuse this as a value?
 
... which begat the rename. In this cleanup I've tried to use
<register>_<field> for masks, and <register>_<field>_<valuename> for specific
values to program in, and hence I added ZCR_EL3_LEN_MAX.

I'm going to stick with ZCR_EL3_LEN_MAX.

In that same paragraph he said:

| the existing code writes 0x1ff into that register, presumable to cover future
| vector length extensions 

... which begat the conversation of which length to use.

I later noted that TF-A currently uses 0xf, and so I aligned with that and plan
to stick with it in the absence of any published architectural guidance that we
*should* set the RAZ/WI bits. We can always add that in future when necessary
if/when the field grows, and until then it's less surprising to only be setting
the bits that are documented as needing to be set in this manner.

> > a) Use <register>_<field>_<valuename> definition, as here.
> 
> > b) Use <register>_<field>_MASK, and add comments at each usage as to why we use
> >    a mask as a value, to explain why that isn't a bug.
> 
> > c) Have both <register>_<field>_MASK and some value definition, and use some
> >    insertion helper to insert the value.
> 
> > ... and I went with (a) because it was the simplest.
> 
> > Is there a problem with this?
> 
> My concern is continuity of the enumeration algorithm between the
> various implementations we have, it's something we're not currently
> great with and this creates a separation between the kernel and the boot
> wrapper implementations.  There's no change in what's actually being
> done but it creates some additional effort to figure out why we're
> setting a maximum here and not trying to set all the bits as we do in
> the kernel.

TBH, I'd argue if we're setting those bits in the kernel it's probably a bug,
because we don't know *exactly* what effect they'll have when allocated in the
future.

Thanks,
Mark.

> TF-A is doing something else again (actually two different
> things if you include SME which uses the same algorithm for the
> streaming vector length), for SVE it uses a maximum length too but it
> uses a lower length than the maximum representable one that's used here.
> 
> It may be that the best thing to do is to make this change but also
> update the kernel to have separate but identical mask and maximum
> definitions, though TBH I'd rather not actually have that update happen
> while the SME series is pending.



From mark.rutland at arm.com  Thu Jan 27 08:11:52 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Jan 2022 16:11:52 +0000
Subject: [bootwrapper PATCH v3 04/15] Add bit-field macros
In-Reply-To: <20220126150312.56b6f536@donnerap.cambridge.arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-5-mark.rutland@arm.com>
 <20220126150312.56b6f536@donnerap.cambridge.arm.com>
Message-ID: <YfLESMj9DV7cnESq@FVFF77S0Q05N>

On Wed, Jan 26, 2022 at 03:03:12PM +0000, Andre Przywara wrote:
> On Tue, 25 Jan 2022 15:00:46 +0000
> Mark Rutland <mark.rutland at arm.com> wrote:
> 
> > Arm architectural documentation typically defines bit-fields as
> > `[msb,lsb]` and single-bit fields as `[bit]`. For clarity it would be
> > helpful if we could define fields in the same way.
> > 
> > Add helpers so that we can do so, along with helper to extract/insert
> > bit-field values.
> > 
> > There should be no functional change as a result of this patch.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> 
> I extracted the code and checked the examples, see below.

> > +/*
> > + * Define a contiguous mask of bits with `msb` as the most significant bit and
> > + * `lsb` as the least significant bit. The `msb` value must be greater than or
> > + * equal to `lsb`.
> > + *
> > + * For example:
> > + * - BITS(63, 63) is 0x8000000000000000
> > + * - BITS(63, 0)  is 0xFFFFFFFFFFFFFFFF
> > + * - BITS(0, 0)   is 0x0000000000000001
> > + * - BITS(49, 17) is 0x0001FFFFFFFE0000
> 
> This should be 0x0003fffffffe0000, in real life and with the below
> implementation. So just a comment fix.

Good spot; I'll fix that up.

> The rest of the examples checked out, so with that fixed:
> 
> Reviewed-by: Andre Przywara <andre.przywara at arm.com>

Thanks!

Mark.


From alexandru.elisei at arm.com  Thu Jan 27 08:17:53 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:53 +0000
Subject: [PATCH v4 0/6] KVM: arm64: Improve PMU support on heterogeneous
 systems
Message-ID: <20220127161759.53553-1-alexandru.elisei@arm.com>

(CC'ing Peter Maydell in case this might be of interest to qemu)

The series can be found on a branch at [1], and the kvmtool support at [2].

Detailed explanation of the issue and symptoms that the patches attempt to
correct can be found in the cover letter for v1 [3].

A summary of the problem is that on heterogeneous systems KVM will always
use the same PMU for creating the VCPU events for *all* VCPUs regardless of
the physical CPU on which the VCPU is running, leading to events suddenly
stopping and resuming in the guest as the VCPU thread gets migrated across
different CPUs.

This series proposes to fix this behaviour by allowing the user to specify
which physical PMU is used when creating the VCPU events needed for guest
PMU emulation. When the PMU is set, KVM will refuse to the VCPU on a
physical which is not part of the supported CPUs for the specified PMU. The
restriction is that all VCPUs must use the same PMU to avoid emulating an
asymmetric platform.

The default behaviour stays the same - without userspace setting the PMU,
events will stop counting if the VCPU is scheduled on the wrong CPU.

Changes since v3 [4]:

- Gathered Reviewed-by, thank you!
- Rebased on top of v5.17-rc1, on top of which I added the USB Type-C fixes to
  get my rockpro64 to boot [6]. Shouldn't affect KVM in any way.
- Patches #1 ("KVM: arm64: Do not change the PMU event filter after a
  VCPU has run") and #3 ("KVM: arm64: Keep a per-VM pointer to the default PMU")
  are new.
- Use list_is_singular() in #4 ("KVM: arm64: Keep a list of probed PMUs").
- Return -EBUSY if a VCPU has run or if a PMU event filter has been set.
- Use the PMU that the user specified to replace the default PMU at the VM
  level.

Changes since v2 [5]:

- Rebased on top of v5.16-rc5
- Check that all VCPUs have the same PMU set (or none at all).
- Use the VCPU's PMUVer value when calculating the event mask, if a PMU is
  set for that VCPU.
- Clear the unsupported CPU flag in vcpu_put().
- Move the handling of the unsupported CPU flag in kvm_vcpu_exit_request().
- Free the cpumask of supported CPUs if kvm_arch_vcpu_create() fails.

Changes since v1 [3]:

- Rebased on top of v5.16-rc4
- Implemented review comments: protect iterating through the list of PMUs
  with a mutex, documentation changes, initialize vcpu-arch.supported_cpus
  to cpu_possible_mask, changed vcpu->arch.cpu_not_supported to a VCPU
  flag, set exit reason to KVM_EXIT_FAIL_ENTRY and populate fail_entry when
  the VCPU is run on a CPU not in the PMU's supported cpumask. Many thanks
  for the review!

[1] https://gitlab.arm.com/linux-arm/linux-ae/-/tree/pmu-big-little-fix-v4
[2] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/pmu-big-little-fix-v2
[3] https://www.spinics.net/lists/arm-kernel/msg933579.html
[4] https://www.spinics.net/lists/kvm-arm/msg51079.html
[5] https://www.spinics.net/lists/kvm-arm/msg50944.html
[6] https://www.spinics.net/lists/linux-usb/msg221604.html

Alexandru Elisei (4):
  perf: Fix wrong name in comment for struct perf_cpu_context
  KVM: arm64: Keep a list of probed PMUs
  KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU attribute
  KVM: arm64: Refuse to run VCPU if the PMU doesn't match the physical
    CPU

Marc Zyngier (2):
  KVM: arm64: Do not change the PMU event filter after a VCPU has run
  KVM: arm64: Keep a per-VM pointer to the default PMU

 Documentation/virt/kvm/devices/vcpu.rst |  34 +++++-
 arch/arm64/include/asm/kvm_host.h       |  15 ++-
 arch/arm64/include/uapi/asm/kvm.h       |   4 +
 arch/arm64/kvm/arm.c                    |  21 ++++
 arch/arm64/kvm/pmu-emul.c               | 141 ++++++++++++++++++------
 include/kvm/arm_pmu.h                   |   5 +
 include/linux/perf_event.h              |   2 +-
 tools/arch/arm64/include/uapi/asm/kvm.h |   1 +
 8 files changed, 189 insertions(+), 34 deletions(-)

-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:54 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:54 +0000
Subject: [PATCH v4 1/6] KVM: arm64: Do not change the PMU event filter after a
 VCPU has run
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-2-alexandru.elisei@arm.com>

From: Marc Zyngier <maz at kernel.org>

Userspace can specify which events a guest is allowed to use with the
KVM_ARM_VCPU_PMU_V3_FILTER attribute. The list of allowed events can be
identified by a guest from reading the PMCEID{0,1}_EL0 registers.

Changing the PMU event filter after a VCPU has run can cause reads of the
registers performed before the filter is changed to return different values
than reads performed with the new event filter in place. The architecture
defines the two registers as read-only, and this behaviour contradicts
that.

Keep track when the first VCPU has run and deny changes to the PMU event
filter to prevent this from happening.

Signed-off-by: Marc Zyngier <maz at kernel.org>
[ Alexandru E: Added commit message, updated ioctl documentation ]
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
Tested with a hacked version of kvmtool [1], which sets the event filter
for VCPU 1 only after VCPU 0 has already run.

[1] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/test-pmu-filter-after-vcpu-has-run-v1

 Documentation/virt/kvm/devices/vcpu.rst |  2 +-
 arch/arm64/include/asm/kvm_host.h       |  1 +
 arch/arm64/kvm/arm.c                    |  4 +++
 arch/arm64/kvm/pmu-emul.c               | 33 +++++++++++++++----------
 4 files changed, 26 insertions(+), 14 deletions(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index 60a29972d3f1..d063aaee5bb7 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -70,7 +70,7 @@ irqchip.
 	 -ENODEV  PMUv3 not supported or GIC not initialized
 	 -ENXIO   PMUv3 not properly configured or in-kernel irqchip not
 	 	  configured as required prior to calling this attribute
-	 -EBUSY   PMUv3 already initialized
+	 -EBUSY   PMUv3 already initialized or a VCPU has already run
 	 -EINVAL  Invalid filter range
 	 =======  ======================================================
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..2869259e10c0 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -136,6 +136,7 @@ struct kvm_arch {
 
 	/* Memory Tagging Extension enabled for the guest */
 	bool mte_enabled;
+	bool ran_once;
 };
 
 struct kvm_vcpu_fault_info {
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a4a0063df456..f4e7e38a19e9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -634,6 +634,10 @@ int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)
 	if (kvm_vm_is_protected(kvm))
 		kvm_call_hyp_nvhe(__pkvm_vcpu_init_traps, vcpu);
 
+	mutex_lock(&kvm->lock);
+	kvm->arch.ran_once = true;
+	mutex_unlock(&kvm->lock);
+
 	return ret;
 }
 
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index fbcfd4ec6f92..bc771bc1a041 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -924,6 +924,8 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
 
 int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
+	struct kvm *kvm = vcpu->kvm;
+
 	if (!kvm_vcpu_has_pmu(vcpu))
 		return -ENODEV;
 
@@ -941,7 +943,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		int __user *uaddr = (int __user *)(long)attr->addr;
 		int irq;
 
-		if (!irqchip_in_kernel(vcpu->kvm))
+		if (!irqchip_in_kernel(kvm))
 			return -EINVAL;
 
 		if (get_user(irq, uaddr))
@@ -951,7 +953,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		if (!(irq_is_ppi(irq) || irq_is_spi(irq)))
 			return -EINVAL;
 
-		if (!pmu_irq_is_valid(vcpu->kvm, irq))
+		if (!pmu_irq_is_valid(kvm, irq))
 			return -EINVAL;
 
 		if (kvm_arm_pmu_irq_initialized(vcpu))
@@ -966,7 +968,7 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		struct kvm_pmu_event_filter filter;
 		int nr_events;
 
-		nr_events = kvm_pmu_event_mask(vcpu->kvm) + 1;
+		nr_events = kvm_pmu_event_mask(kvm) + 1;
 
 		uaddr = (struct kvm_pmu_event_filter __user *)(long)attr->addr;
 
@@ -978,12 +980,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 		     filter.action != KVM_PMU_EVENT_DENY))
 			return -EINVAL;
 
-		mutex_lock(&vcpu->kvm->lock);
+		mutex_lock(&kvm->lock);
+
+		if (kvm->arch.ran_once) {
+			mutex_unlock(&kvm->lock);
+			return -EBUSY;
+		}
 
-		if (!vcpu->kvm->arch.pmu_filter) {
-			vcpu->kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
-			if (!vcpu->kvm->arch.pmu_filter) {
-				mutex_unlock(&vcpu->kvm->lock);
+		if (!kvm->arch.pmu_filter) {
+			kvm->arch.pmu_filter = bitmap_alloc(nr_events, GFP_KERNEL_ACCOUNT);
+			if (!kvm->arch.pmu_filter) {
+				mutex_unlock(&kvm->lock);
 				return -ENOMEM;
 			}
 
@@ -994,17 +1001,17 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 			 * events, the default is to allow.
 			 */
 			if (filter.action == KVM_PMU_EVENT_ALLOW)
-				bitmap_zero(vcpu->kvm->arch.pmu_filter, nr_events);
+				bitmap_zero(kvm->arch.pmu_filter, nr_events);
 			else
-				bitmap_fill(vcpu->kvm->arch.pmu_filter, nr_events);
+				bitmap_fill(kvm->arch.pmu_filter, nr_events);
 		}
 
 		if (filter.action == KVM_PMU_EVENT_ALLOW)
-			bitmap_set(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+			bitmap_set(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
 		else
-			bitmap_clear(vcpu->kvm->arch.pmu_filter, filter.base_event, filter.nevents);
+			bitmap_clear(kvm->arch.pmu_filter, filter.base_event, filter.nevents);
 
-		mutex_unlock(&vcpu->kvm->lock);
+		mutex_unlock(&kvm->lock);
 
 		return 0;
 	}
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:55 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:55 +0000
Subject: [PATCH v4 2/6] perf: Fix wrong name in comment for struct
 perf_cpu_context
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-3-alexandru.elisei@arm.com>

Commit 0793a61d4df8 ("performance counters: core code") added the perf
subsystem (then called Performance Counters) to Linux, creating the struct
perf_cpu_context. The comment for the struct referred to it as a "struct
perf_counter_cpu_context".

Commit cdd6c482c9ff ("perf: Do the big rename: Performance Counters ->
Performance Events") changed the comment to refer to a "struct
perf_event_cpu_context", which was still the wrong name for the struct.

Change the comment to say "struct perf_cpu_context".

CC: Thomas Gleixner <tglx at linutronix.de>
CC: Ingo Molnar <mingo at redhat.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 include/linux/perf_event.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 117f230bcdfd..c8f4806a73db 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -875,7 +875,7 @@ struct perf_event_context {
 #define PERF_NR_CONTEXTS	4
 
 /**
- * struct perf_event_cpu_context - per cpu event context structure
+ * struct perf_cpu_context - per cpu event context structure
  */
 struct perf_cpu_context {
 	struct perf_event_context	ctx;
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:56 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:56 +0000
Subject: [PATCH v4 3/6] KVM: arm64: Keep a per-VM pointer to the default PMU
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-4-alexandru.elisei@arm.com>

From: Marc Zyngier <maz at kernel.org>

As we are about to allow selection of the PMU exposed to a guest, start by
keeping track of the default one instead of only the PMU version.

Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/include/asm/kvm_host.h |  2 +-
 arch/arm64/kvm/pmu-emul.c         | 42 +++++++++++++++++++------------
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 2869259e10c0..57141a3a3740 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -129,7 +129,7 @@ struct kvm_arch {
 	 * up to 2^10 events (ARMv8.0) or 2^16 events (ARMv8.1+).
 	 */
 	unsigned long *pmu_filter;
-	unsigned int pmuver;
+	struct arm_pmu *arm_pmu;
 
 	u8 pfr0_csv2;
 	u8 pfr0_csv3;
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index bc771bc1a041..b238b3d5515c 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -24,7 +24,11 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
 
 static u32 kvm_pmu_event_mask(struct kvm *kvm)
 {
-	switch (kvm->arch.pmuver) {
+	unsigned int pmuver;
+
+	pmuver = kvm->arch.arm_pmu->pmuver;
+
+	switch (pmuver) {
 	case ID_AA64DFR0_PMUVER_8_0:
 		return GENMASK(9, 0);
 	case ID_AA64DFR0_PMUVER_8_1:
@@ -33,7 +37,7 @@ static u32 kvm_pmu_event_mask(struct kvm *kvm)
 	case ID_AA64DFR0_PMUVER_8_7:
 		return GENMASK(15, 0);
 	default:		/* Shouldn't be here, just for sanity */
-		WARN_ONCE(1, "Unknown PMU version %d\n", kvm->arch.pmuver);
+		WARN_ONCE(1, "Unknown PMU version %d\n", pmuver);
 		return 0;
 	}
 }
@@ -600,6 +604,7 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_vcpu *vcpu, u64 select_idx)
  */
 static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
 {
+	struct arm_pmu *arm_pmu = vcpu->kvm->arch.arm_pmu;
 	struct kvm_pmu *pmu = &vcpu->arch.pmu;
 	struct kvm_pmc *pmc;
 	struct perf_event *event;
@@ -636,7 +641,7 @@ static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx)
 		return;
 
 	memset(&attr, 0, sizeof(struct perf_event_attr));
-	attr.type = PERF_TYPE_RAW;
+	attr.type = arm_pmu->pmu.type;
 	attr.size = sizeof(attr);
 	attr.pinned = 1;
 	attr.disabled = !kvm_pmu_counter_is_enabled(vcpu, pmc->idx);
@@ -750,12 +755,11 @@ void kvm_host_pmu_init(struct arm_pmu *pmu)
 		static_branch_enable(&kvm_arm_pmu_available);
 }
 
-static int kvm_pmu_probe_pmuver(void)
+static struct arm_pmu *kvm_pmu_probe_armpmu(void)
 {
 	struct perf_event_attr attr = { };
 	struct perf_event *event;
-	struct arm_pmu *pmu;
-	int pmuver = ID_AA64DFR0_PMUVER_IMP_DEF;
+	struct arm_pmu *pmu = NULL;
 
 	/*
 	 * Create a dummy event that only counts user cycles. As we'll never
@@ -780,19 +784,20 @@ static int kvm_pmu_probe_pmuver(void)
 	if (IS_ERR(event)) {
 		pr_err_once("kvm: pmu event creation failed %ld\n",
 			    PTR_ERR(event));
-		return ID_AA64DFR0_PMUVER_IMP_DEF;
+		return NULL;
 	}
 
 	if (event->pmu) {
 		pmu = to_arm_pmu(event->pmu);
-		if (pmu->pmuver)
-			pmuver = pmu->pmuver;
+		if (pmu->pmuver == 0 ||
+		    pmu->pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
+			pmu = NULL;
 	}
 
 	perf_event_disable(event);
 	perf_event_release_kernel(event);
 
-	return pmuver;
+	return pmu;
 }
 
 u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
@@ -810,7 +815,7 @@ u64 kvm_pmu_get_pmceid(struct kvm_vcpu *vcpu, bool pmceid1)
 		 * Don't advertise STALL_SLOT, as PMMIR_EL0 is handled
 		 * as RAZ
 		 */
-		if (vcpu->kvm->arch.pmuver >= ID_AA64DFR0_PMUVER_8_4)
+		if (vcpu->kvm->arch.arm_pmu->pmuver >= ID_AA64DFR0_PMUVER_8_4)
 			val &= ~BIT_ULL(ARMV8_PMUV3_PERFCTR_STALL_SLOT - 32);
 		base = 32;
 	}
@@ -932,11 +937,16 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	if (vcpu->arch.pmu.created)
 		return -EBUSY;
 
-	if (!vcpu->kvm->arch.pmuver)
-		vcpu->kvm->arch.pmuver = kvm_pmu_probe_pmuver();
-
-	if (vcpu->kvm->arch.pmuver == ID_AA64DFR0_PMUVER_IMP_DEF)
-		return -ENODEV;
+	mutex_lock(&kvm->lock);
+	if (!kvm->arch.arm_pmu) {
+		/* No PMU set, get the default one */
+		kvm->arch.arm_pmu = kvm_pmu_probe_armpmu();
+		if (!kvm->arch.arm_pmu) {
+			mutex_unlock(&kvm->lock);
+			return -ENODEV;
+		}
+	}
+	mutex_unlock(&kvm->lock);
 
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_PMU_V3_IRQ: {
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:57 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:57 +0000
Subject: [PATCH v4 4/6] KVM: arm64: Keep a list of probed PMUs
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-5-alexandru.elisei@arm.com>

The ARM PMU driver calls kvm_host_pmu_init() after probing to tell KVM that
a hardware PMU is available for guest emulation. Heterogeneous systems can
have more than one PMU present, and the callback gets called multiple
times, once for each of them. Keep track of all the PMUs available to KVM,
as they're going to be needed later.

Reviewed-by: Reiji Watanabe <reijiw at google.com>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arch/arm64/kvm/pmu-emul.c | 25 +++++++++++++++++++++++--
 include/kvm/arm_pmu.h     |  5 +++++
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index b238b3d5515c..7bab73f85b58 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -7,6 +7,7 @@
 #include <linux/cpu.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
+#include <linux/list.h>
 #include <linux/perf_event.h>
 #include <linux/perf/arm_pmu.h>
 #include <linux/uaccess.h>
@@ -16,6 +17,9 @@
 
 DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
+static LIST_HEAD(arm_pmus);
+static DEFINE_MUTEX(arm_pmus_lock);
+
 static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx);
 static void kvm_pmu_update_pmc_chained(struct kvm_vcpu *vcpu, u64 select_idx);
 static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);
@@ -750,9 +754,26 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
 
 void kvm_host_pmu_init(struct arm_pmu *pmu)
 {
-	if (pmu->pmuver != 0 && pmu->pmuver != ID_AA64DFR0_PMUVER_IMP_DEF &&
-	    !kvm_arm_support_pmu_v3() && !is_protected_kvm_enabled())
+	struct arm_pmu_entry *entry;
+
+	if (pmu->pmuver == 0 || pmu->pmuver == ID_AA64DFR0_PMUVER_IMP_DEF ||
+	    is_protected_kvm_enabled())
+		return;
+
+	mutex_lock(&arm_pmus_lock);
+
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		goto out_unlock;
+
+	entry->arm_pmu = pmu;
+	list_add_tail(&entry->entry, &arm_pmus);
+
+	if (list_is_singular(&arm_pmus))
 		static_branch_enable(&kvm_arm_pmu_available);
+
+out_unlock:
+	mutex_unlock(&arm_pmus_lock);
 }
 
 static struct arm_pmu *kvm_pmu_probe_armpmu(void)
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index f9ed4c171d7b..20193416d214 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -29,6 +29,11 @@ struct kvm_pmu {
 	struct irq_work overflow_work;
 };
 
+struct arm_pmu_entry {
+	struct list_head entry;
+	struct arm_pmu *arm_pmu;
+};
+
 DECLARE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
 
 static __always_inline bool kvm_arm_support_pmu_v3(void)
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:58 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:58 +0000
Subject: [PATCH v4 5/6] KVM: arm64: Add KVM_ARM_VCPU_PMU_V3_SET_PMU attribute
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-6-alexandru.elisei@arm.com>

When KVM creates an event and there are more than one PMUs present on the
system, perf_init_event() will go through the list of available PMUs and
will choose the first one that can create the event. The order of the PMUs
in this list depends on the probe order, which can change under various
circumstances, for example if the order of the PMU nodes change in the DTB
or if asynchronous driver probing is enabled on the kernel command line
(with the driver_async_probe=armv8-pmu option).

Another consequence of this approach is that on heteregeneous systems all
virtual machines that KVM creates will use the same PMU. This might cause
unexpected behaviour for userspace: when a VCPU is executing on the
physical CPU that uses this default PMU, PMU events in the guest work
correctly; but when the same VCPU executes on another CPU, PMU events in
the guest will suddenly stop counting.

Fortunately, perf core allows user to specify on which PMU to create an
event by using the perf_event_attr->type field, which is used by
perf_init_event() as an index in the radix tree of available PMUs.

Add the KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU
attribute to allow userspace to specify the arm_pmu that KVM will use when
creating events for that VCPU. KVM will make no attempt to run the VCPU on
the physical CPUs that share the PMU, leaving it up to userspace to manage
the VCPU threads' affinity accordingly.

To ensure that KVM doesn't expose an asymmetric system to the guest, the
PMU set for one VCPU will be used by all other VCPUs. Once a VCPU has run,
the PMU cannot be changed in order to avoid changing the list of available
events for a VCPU, or to change the semantics of existing events.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst | 28 +++++++++++++++++
 arch/arm64/include/uapi/asm/kvm.h       |  1 +
 arch/arm64/kvm/pmu-emul.c               | 40 +++++++++++++++++++++++++
 tools/arch/arm64/include/uapi/asm/kvm.h |  1 +
 4 files changed, 70 insertions(+)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index d063aaee5bb7..e8c5770590a2 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -104,6 +104,34 @@ hardware event. Filtering event 0x1E (CHAIN) has no effect either, as it
 isn't strictly speaking an event. Filtering the cycle counter is possible
 using event 0x11 (CPU_CYCLES).
 
+1.4 ATTRIBUTE: KVM_ARM_VCPU_PMU_V3_SET_PMU
+------------------------------------------
+
+:Parameters: in kvm_device_attr.addr the address to an int representing the PMU
+             identifier.
+
+:Returns:
+
+	 =======  ====================================================
+	 -EBUSY   PMUv3 already initialized, a VCPU has already run or
+                  an event filter has already been set
+	 -EFAULT  Error accessing the PMU identifier
+	 -ENXIO   PMU not found
+	 -ENODEV  PMUv3 not supported or GIC not initialized
+	 -ENOMEM  Could not allocate memory
+	 =======  ====================================================
+
+Request that the VCPU uses the specified hardware PMU when creating guest events
+for the purpose of PMU emulation. The PMU identifier can be read from the "type"
+file for the desired PMU instance under /sys/devices (or, equivalent,
+/sys/bus/even_source). This attribute is particularly useful on heterogeneous
+systems where there are at least two CPU PMUs on the system. The PMU that is set
+for one VCPU will be used by all the other VCPUs. It isn't possible to set a PMU
+if a PMU event filter is already present.
+
+Note that KVM will not make any attempts to run the VCPU on the physical CPUs
+associated with the PMU specified by this attribute. This is entirely left to
+userspace.
 
 2. GROUP: KVM_ARM_VCPU_TIMER_CTRL
 =================================
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..1d0a0a2a9711 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -362,6 +362,7 @@ struct kvm_arm_copy_mte_tags {
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
 #define   KVM_ARM_VCPU_PMU_V3_INIT	1
 #define   KVM_ARM_VCPU_PMU_V3_FILTER	2
+#define   KVM_ARM_VCPU_PMU_V3_SET_PMU	3
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 7bab73f85b58..18361f367495 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -948,6 +948,36 @@ static bool pmu_irq_is_valid(struct kvm *kvm, int irq)
 	return true;
 }
 
+static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct arm_pmu_entry *entry;
+	struct arm_pmu *arm_pmu;
+	int ret = -ENXIO;
+
+	mutex_lock(&kvm->lock);
+	mutex_lock(&arm_pmus_lock);
+
+	list_for_each_entry(entry, &arm_pmus, entry) {
+		arm_pmu = entry->arm_pmu;
+		if (arm_pmu->pmu.type == pmu_id) {
+			if (kvm->arch.ran_once ||
+			    (kvm->arch.pmu_filter && kvm->arch.arm_pmu != arm_pmu)) {
+				ret = -EBUSY;
+				break;
+			}
+
+			kvm->arch.arm_pmu = arm_pmu;
+			ret = 0;
+			break;
+		}
+	}
+
+	mutex_unlock(&arm_pmus_lock);
+	mutex_unlock(&kvm->lock);
+	return ret;
+}
+
 int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 {
 	struct kvm *kvm = vcpu->kvm;
@@ -1046,6 +1076,15 @@ int kvm_arm_pmu_v3_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 
 		return 0;
 	}
+	case KVM_ARM_VCPU_PMU_V3_SET_PMU: {
+		int __user *uaddr = (int __user *)(long)attr->addr;
+		int pmu_id;
+
+		if (get_user(pmu_id, uaddr))
+			return -EFAULT;
+
+		return kvm_arm_pmu_v3_set_pmu(vcpu, pmu_id);
+	}
 	case KVM_ARM_VCPU_PMU_V3_INIT:
 		return kvm_arm_pmu_v3_init(vcpu);
 	}
@@ -1083,6 +1122,7 @@ int kvm_arm_pmu_v3_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	case KVM_ARM_VCPU_PMU_V3_IRQ:
 	case KVM_ARM_VCPU_PMU_V3_INIT:
 	case KVM_ARM_VCPU_PMU_V3_FILTER:
+	case KVM_ARM_VCPU_PMU_V3_SET_PMU:
 		if (kvm_vcpu_has_pmu(vcpu))
 			return 0;
 	}
diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..1d0a0a2a9711 100644
--- a/tools/arch/arm64/include/uapi/asm/kvm.h
+++ b/tools/arch/arm64/include/uapi/asm/kvm.h
@@ -362,6 +362,7 @@ struct kvm_arm_copy_mte_tags {
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
 #define   KVM_ARM_VCPU_PMU_V3_INIT	1
 #define   KVM_ARM_VCPU_PMU_V3_FILTER	2
+#define   KVM_ARM_VCPU_PMU_V3_SET_PMU	3
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:17:59 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:17:59 +0000
Subject: [PATCH v4 6/6] KVM: arm64: Refuse to run VCPU if the PMU doesn't
 match the physical CPU
In-Reply-To: <20220127161759.53553-1-alexandru.elisei@arm.com>
References: <20220127161759.53553-1-alexandru.elisei@arm.com>
Message-ID: <20220127161759.53553-7-alexandru.elisei@arm.com>

Userspace can assign a PMU to a VCPU with the KVM_ARM_VCPU_PMU_V3_SET_PMU
device ioctl. If the VCPU is scheduled on a physical CPU which has a
different PMU, the perf events needed to emulate a guest PMU won't be
scheduled in and the guest performance counters will stop counting. Treat
it as an userspace error and refuse to run the VCPU in this situation.

Suggested-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Documentation/virt/kvm/devices/vcpu.rst |  6 +++++-
 arch/arm64/include/asm/kvm_host.h       | 12 ++++++++++++
 arch/arm64/include/uapi/asm/kvm.h       |  3 +++
 arch/arm64/kvm/arm.c                    | 17 +++++++++++++++++
 arch/arm64/kvm/pmu-emul.c               |  1 +
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/devices/vcpu.rst b/Documentation/virt/kvm/devices/vcpu.rst
index e8c5770590a2..260db203a1e2 100644
--- a/Documentation/virt/kvm/devices/vcpu.rst
+++ b/Documentation/virt/kvm/devices/vcpu.rst
@@ -131,7 +131,11 @@ if a PMU event filter is already present.
 
 Note that KVM will not make any attempts to run the VCPU on the physical CPUs
 associated with the PMU specified by this attribute. This is entirely left to
-userspace.
+userspace. However, attempting to run the VCPU on a physical CPU not supported
+by the PMU will fail and KVM_RUN will return with
+exit_reason = KVM_EXIT_FAIL_ENTRY and populate the fail_entry struct by setting
+hardare_entry_failure_reason field to KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED and
+the cpu field to the processor id.
 
 2. GROUP: KVM_ARM_VCPU_TIMER_CTRL
 =================================
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 57141a3a3740..0bed0e33e1ae 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -131,6 +131,8 @@ struct kvm_arch {
 	unsigned long *pmu_filter;
 	struct arm_pmu *arm_pmu;
 
+	cpumask_var_t supported_cpus;
+
 	u8 pfr0_csv2;
 	u8 pfr0_csv3;
 
@@ -436,6 +438,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
 #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
+#define KVM_ARM64_ON_UNSUPPORTED_CPU	(1 << 15) /* Physical CPU not in supported_cpus */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
@@ -454,6 +457,15 @@ struct kvm_vcpu_arch {
 #define vcpu_has_ptrauth(vcpu)		false
 #endif
 
+#define vcpu_on_unsupported_cpu(vcpu)					\
+	((vcpu)->arch.flags & KVM_ARM64_ON_UNSUPPORTED_CPU)
+
+#define vcpu_set_on_unsupported_cpu(vcpu)				\
+	((vcpu)->arch.flags |= KVM_ARM64_ON_UNSUPPORTED_CPU)
+
+#define vcpu_clear_on_unsupported_cpu(vcpu)				\
+	((vcpu)->arch.flags &= ~KVM_ARM64_ON_UNSUPPORTED_CPU)
+
 #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.regs)
 
 /*
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 1d0a0a2a9711..d49f714f48e6 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -414,6 +414,9 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_PSCI_RET_INVAL		PSCI_RET_INVALID_PARAMS
 #define KVM_PSCI_RET_DENIED		PSCI_RET_DENIED
 
+/* run->fail_entry.hardware_entry_failure_reason codes. */
+#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED	(1ULL << 0)
+
 #endif
 
 #endif /* __ARM_KVM_H__ */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index f4e7e38a19e9..7b7658a9186f 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -150,6 +150,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	if (ret)
 		goto out_free_stage2_pgd;
 
+	if (!zalloc_cpumask_var(&kvm->arch.supported_cpus, GFP_KERNEL))
+		goto out_free_stage2_pgd;
+	cpumask_copy(kvm->arch.supported_cpus, cpu_possible_mask);
+
 	kvm_vgic_early_init(kvm);
 
 	/* The maximum number of VCPUs is limited by the host's GIC model */
@@ -176,6 +180,7 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
 void kvm_arch_destroy_vm(struct kvm *kvm)
 {
 	bitmap_free(kvm->arch.pmu_filter);
+	free_cpumask_var(kvm->arch.supported_cpus);
 
 	kvm_vgic_destroy(kvm);
 
@@ -411,6 +416,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	if (vcpu_has_ptrauth(vcpu))
 		vcpu_ptrauth_disable(vcpu);
 	kvm_arch_vcpu_load_debug_state_flags(vcpu);
+
+	if (!cpumask_test_cpu(smp_processor_id(), vcpu->kvm->arch.supported_cpus))
+		vcpu_set_on_unsupported_cpu(vcpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -423,6 +431,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 	kvm_vgic_put(vcpu);
 	kvm_vcpu_pmu_restore_host(vcpu);
 
+	vcpu_clear_on_unsupported_cpu(vcpu);
 	vcpu->cpu = -1;
 }
 
@@ -796,6 +805,14 @@ static bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu, int *ret)
 		}
 	}
 
+	if (unlikely(vcpu_on_unsupported_cpu(vcpu))) {
+		run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+		run->fail_entry.hardware_entry_failure_reason = KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED;
+		run->fail_entry.cpu = smp_processor_id();
+		*ret = 0;
+		return true;
+	}
+
 	return kvm_request_pending(vcpu) ||
 			need_new_vmid_gen(&vcpu->arch.hw_mmu->vmid) ||
 			xfer_to_guest_mode_work_pending();
diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c
index 18361f367495..4526a5824dac 100644
--- a/arch/arm64/kvm/pmu-emul.c
+++ b/arch/arm64/kvm/pmu-emul.c
@@ -968,6 +968,7 @@ static int kvm_arm_pmu_v3_set_pmu(struct kvm_vcpu *vcpu, int pmu_id)
 			}
 
 			kvm->arch.arm_pmu = arm_pmu;
+			cpumask_copy(kvm->arch.supported_cpus, &arm_pmu->supported_cpus);
 			ret = 0;
 			break;
 		}
-- 
2.34.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:23 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:23 +0000
Subject: [PATCH v2 kvmtool 00/10] arm64: Improve PMU support on heterogeneous
 systems
Message-ID: <20220127162033.54290-1-alexandru.elisei@arm.com>

The series can be found at [1], and the Linux patches that this series is
based on at [2].

The series adds support for the KVM_ARM_VCPU_PMU_V3_SET_PMU PMU attribute,
which allows userspace to set a PMU for a VCPU. This PMU is used by KVM
when creating perf events to emulate the guest PMU.

Without settings this attribute, the PMU used when creating events is the
first one that successfully probed when booting, but this is unreliable as
the probe order can change (if the order of the PMUs is changed in the DTB
or if asynchronous driver probing is enabled on the host's command line),
and furthermore it requires the user to have intimate knowledge of how the
PMU was chosen in order to pin the VM on the correct physical CPUs.

With KVM_ARM_VCPU_PMU_V3_SET_PMU, the user is still expected to pin the
VCPUs on a particular set of CPUs, but now it can be any CPUs as long as
they share the same PMU. The set does not depend anymore on the driver
probe order and all that is necessary for the user to know is which CPUs
are the little core and which are the big cores, in a big.little
configuration, which I believe is more reasonable.

Patches #1-#2 are fixes and can be taken independently of this series.

Patches #3-#6 move the PMU code to aarch64, where it belongs, because the
PMU has never been supported on KVM for arm. This also paves the way for
pulling in the KVM_ARM_VCPU_PMU_V3_SET_PMU attribute, which was not defined
for KVM for arm (when KVM supported arm). This also can be merged right
now, independently of the other patches.

Patch #7 adds the cpumask_* functions which are necessary for subsequent
patches.

Patch #9 adds basic support for KVM_ARM_VCPU_PMU_V3_SET_PMU; the user is
still expected to use taskset to pin the entire VM to the correct CPUs.

Patch #10 adds --vcpu-affinity command line argument to pin VCPUs to the
correct CPUs without pinning the rest of the kvmtool threads.

Changes since v1:

* Patch #2 ("bitops.h: Include wordsize.h to provide the __WORDSIZE
  define") is new.

* Added for_each_cpu(), cpumask_and() and cpumask_subset() functions and
  all the cpumask_* functions are added in one patch.

* Bumped NR_CPUS fro arm64 to 4096 to match the Linux Kconfig option.

* Reworked the way kvmtool specific header files were included to use
  quotes to clearly differentiate them from the system level headers and to
  keep the style consistent with the current code (for example, #include
  <linux/bitops.h> is now "linux/bitops.h").

* Patch #10 ("arm64: Add --vcpu-affinity command line argument") is new.

[1] https://gitlab.arm.com/linux-arm/kvmtool-ae/-/tree/pmu-big-little-fix-v2
[2] https://gitlab.arm.com/linux-arm/linux-ae/-/tree/pmu-big-little-fix-v4

Alexandru Elisei (10):
  linux/err.h: Add missing stdbool.h include
  bitops.h: Include wordsize.h to provide the __WORDSIZE define
  arm: Move arch specific VCPU features to the arch specific function
  arm: Get rid of the ARM_VCPU_FEATURE_FLAGS() macro
  arm: Make the PMUv3 emulation code arm64 specific
  arm64: Rework set_pmu_attr()
  Add cpumask functions
  update_headers.sh: Sync headers with Linux v5.17-rc1 + SET_PMU
    attribute
  arm64: Add support for KVM_ARM_VCPU_PMU_V3_SET_PMU
  arm64: Add --vcpu-affinity command line argument

 Makefile                                      |   6 +-
 arm/aarch32/include/asm/kernel.h              |   8 +
 arm/aarch32/include/kvm/kvm-cpu-arch.h        |   4 -
 arm/aarch64/arm-cpu.c                         |   3 +-
 arm/aarch64/include/asm/kernel.h              |   8 +
 arm/aarch64/include/asm/kvm.h                 |   4 +
 .../arm-common => aarch64/include/asm}/pmu.h  |   0
 arm/aarch64/include/kvm/kvm-config-arch.h     |   5 +
 arm/aarch64/include/kvm/kvm-cpu-arch.h        |   6 -
 arm/aarch64/kvm-cpu.c                         |  21 ++
 arm/aarch64/kvm.c                             |  32 +++
 arm/aarch64/pmu.c                             | 231 ++++++++++++++++
 arm/include/arm-common/kvm-arch.h             |   7 +
 arm/include/arm-common/kvm-config-arch.h      |   1 +
 arm/kvm-cpu.c                                 |  14 +-
 arm/pmu.c                                     |  76 ------
 include/linux/bitmap.h                        |  71 +++++
 include/linux/bitops.h                        |   4 +
 include/linux/bits.h                          |   8 +
 include/linux/cpumask.h                       |  67 +++++
 include/linux/err.h                           |   2 +
 include/linux/find.h                          |  30 ++
 include/linux/kernel.h                        |   6 +
 include/linux/kvm.h                           |  16 ++
 mips/include/asm/kernel.h                     |   8 +
 powerpc/include/asm/kernel.h                  |   8 +
 util/bitmap.c                                 | 256 ++++++++++++++++++
 util/find.c                                   |  40 +++
 x86/include/asm/kernel.h                      |   8 +
 x86/include/asm/kvm.h                         |  16 +-
 30 files changed, 867 insertions(+), 99 deletions(-)
 create mode 100644 arm/aarch32/include/asm/kernel.h
 create mode 100644 arm/aarch64/include/asm/kernel.h
 rename arm/{include/arm-common => aarch64/include/asm}/pmu.h (100%)
 create mode 100644 arm/aarch64/pmu.c
 delete mode 100644 arm/pmu.c
 create mode 100644 include/linux/bitmap.h
 create mode 100644 include/linux/bits.h
 create mode 100644 include/linux/cpumask.h
 create mode 100644 include/linux/find.h
 create mode 100644 mips/include/asm/kernel.h
 create mode 100644 powerpc/include/asm/kernel.h
 create mode 100644 util/bitmap.c
 create mode 100644 util/find.c
 create mode 100644 x86/include/asm/kernel.h

-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:24 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:24 +0000
Subject: [PATCH v2 kvmtool 01/10] linux/err.h: Add missing stdbool.h include
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-2-alexandru.elisei@arm.com>

Add missing header stdbool.h to avoid errors like this one, which can
happen if the including file doesn't include stdbool.h:

include/linux/err.h:33:15: error: type defaults to ?int? in declaration of ?bool? [-Werror=implicit-int]
   33 | static inline bool __must_check IS_ERR(__force const void *ptr)
      |               ^~~~
include/linux/err.h:33:15: error: variable ?bool? declared ?inline? [-Werror]
include/linux/err.h:33:1: error: ?warn_unused_result? attribute only applies to function types [-Werror=attributes]
   33 | static inline bool __must_check IS_ERR(__force const void *ptr)
      | ^~~~~~
include/linux/err.h:33:33: error: expected ?,? or ?;? before ?IS_ERR?
   33 | static inline bool __must_check IS_ERR(__force const void *ptr)
      |                                 ^~~~~~
include/linux/err.h:38:15: error: type defaults to ?int? in declaration of ?bool? [-Werror=implicit-int]
   38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
      |               ^~~~
include/linux/err.h:38:15: error: variable ?bool? declared ?inline? [-Werror]
include/linux/err.h:38:1: error: ?warn_unused_result? attribute only applies to function types [-Werror=attributes]
   38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
      | ^~~~~~
include/linux/err.h:38:15: error: redundant redeclaration of ?bool? [-Werror=redundant-decls]
   38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
      |               ^~~~
include/linux/err.h:33:15: note: previous declaration of ?bool? was here
   33 | static inline bool __must_check IS_ERR(__force const void *ptr)
      |               ^~~~
include/linux/err.h:38:33: error: expected ?,? or ?;? before ?IS_ERR_OR_NULL?
   38 | static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
      |                                 ^~~~~~~~~~~~~~
include/linux/err.h: In function ?PTR_ERR_OR_ZERO?:
include/linux/err.h:58:6: error: implicit declaration of function ?IS_ERR? [-Werror=implicit-function-declaration]
   58 |  if (IS_ERR(ptr))
      |      ^~~~~~
include/linux/err.h:58:6: error: nested extern declaration of ?IS_ERR? [-Werror=nested-externs]

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 include/linux/err.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/err.h b/include/linux/err.h
index a729120644d5..1256c7abfefa 100644
--- a/include/linux/err.h
+++ b/include/linux/err.h
@@ -1,6 +1,8 @@
 #ifndef _LINUX_ERR_H
 #define _LINUX_ERR_H
 
+#include <stdbool.h>
+
 #include <linux/compiler.h>
 #include <linux/types.h>
 
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:25 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:25 +0000
Subject: [PATCH v2 kvmtool 02/10] bitops.h: Include wordsize.h to provide the
 __WORDSIZE define
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-3-alexandru.elisei@arm.com>

Trying to build a source file which included bitops.h, but didn't also
bring in the definition for __WORDSIZE (by including limits.h, for example)
would result in the following error:

include/linux/bitops.h:8:23: error: ?__WORDSIZE? undeclared (first use in this function)
    8 | #define BITS_PER_LONG __WORDSIZE
      |                       ^~~~~~~~~~

The symbol is defined in the bits/wordsize.h header file, include it.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 include/linux/bitops.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 56448b71ebbf..3d31f0acf48e 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -1,6 +1,8 @@
 #ifndef _KVM_LINUX_BITOPS_H_
 #define _KVM_LINUX_BITOPS_H_
 
+#include <bits/wordsize.h>
+
 #include <linux/kernel.h>
 #include <linux/compiler.h>
 #include <asm/hweight.h>
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:26 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:26 +0000
Subject: [PATCH v2 kvmtool 03/10] arm: Move arch specific VCPU features to the
 arch specific function
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-4-alexandru.elisei@arm.com>

KVM_CAP_ARM_EL1_32BIT and KVM_CAP_ARM_PMU_V3 are arm64 specific features.
They are set based on arm64 specific command line options and they target
arm64 hardware features. It makes little sense for kvmtool to set the
features in the code that is shared between arm and arm64. Move the logic
to set the feature bits to the arch specific function
kvm_cpu__select_features(), which is already used by arm64 to set other
arm64 specific features.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch64/include/kvm/kvm-cpu-arch.h |  4 +---
 arm/aarch64/kvm-cpu.c                  | 12 ++++++++++++
 arm/kvm-cpu.c                          |  8 --------
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index 8dfb82ecbc37..016cf5b2b9ea 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -6,9 +6,7 @@
 #include "arm-common/kvm-cpu-arch.h"
 
 #define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid)	{				\
-	[0] = ((!!(cpuid) << KVM_ARM_VCPU_POWER_OFF) |				\
-	       (!!(kvm)->cfg.arch.aarch32_guest << KVM_ARM_VCPU_EL1_32BIT) |	\
-	       (!!(kvm)->cfg.arch.has_pmuv3 << KVM_ARM_VCPU_PMU_V3))		\
+	[0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF),				\
 }
 
 #define ARM_MPIDR_HWID_BITMASK	0xFF00FFFFFFUL
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 9f3e8586880c..3b6224a599c8 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -130,6 +130,18 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 
 void kvm_cpu__select_features(struct kvm *kvm, struct kvm_vcpu_init *init)
 {
+	if (kvm->cfg.arch.aarch32_guest) {
+		if (!kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT))
+			die("32bit guests are not supported\n");
+		init->features[0] |= 1UL << KVM_ARM_VCPU_EL1_32BIT;
+	}
+
+	if (kvm->cfg.arch.has_pmuv3) {
+		if (!kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3))
+			die("PMUv3 is not supported");
+		init->features[0] |= 1UL << KVM_ARM_VCPU_PMU_V3;
+	}
+
 	/* Enable pointer authentication if available */
 	if (kvm__supports_extension(kvm, KVM_CAP_ARM_PTRAUTH_ADDRESS) &&
 	    kvm__supports_extension(kvm, KVM_CAP_ARM_PTRAUTH_GENERIC)) {
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 6a2408c632df..554414f81b7a 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -46,14 +46,6 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 		.features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id)
 	};
 
-	if (kvm->cfg.arch.aarch32_guest &&
-	    !kvm__supports_extension(kvm, KVM_CAP_ARM_EL1_32BIT))
-		die("32bit guests are not supported\n");
-
-	if (kvm->cfg.arch.has_pmuv3 &&
-	    !kvm__supports_extension(kvm, KVM_CAP_ARM_PMU_V3))
-		die("PMUv3 is not supported");
-
 	vcpu = calloc(1, sizeof(struct kvm_cpu));
 	if (!vcpu)
 		return NULL;
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:27 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:27 +0000
Subject: [PATCH v2 kvmtool 04/10] arm: Get rid of the ARM_VCPU_FEATURE_FLAGS()
 macro
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-5-alexandru.elisei@arm.com>

The ARM_VCPU_FEATURE_FLAGS() macro sets a feature bit in a rather
convoluted way: if cpu_id is 0, then bit KVM_ARM_VCPU_POWER_OFF is 0,
otherwise is set to 1. There's really no need for this indirection,
especially considering that the macro has been changed to return the same
value for both the arm and arm64 architectures. Replace it with a simple
conditional statement in kvm_cpu__arch_init(), which makes it clearer to
understand.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch32/include/kvm/kvm-cpu-arch.h | 4 ----
 arm/aarch64/include/kvm/kvm-cpu-arch.h | 4 ----
 arm/kvm-cpu.c                          | 6 +++++-
 3 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arm/aarch32/include/kvm/kvm-cpu-arch.h b/arm/aarch32/include/kvm/kvm-cpu-arch.h
index 780e0e2f0934..fc9aef9f6320 100644
--- a/arm/aarch32/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch32/include/kvm/kvm-cpu-arch.h
@@ -5,10 +5,6 @@
 
 #include "arm-common/kvm-cpu-arch.h"
 
-#define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid)	{			\
-	[0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF),			\
-}
-
 #define ARM_MPIDR_HWID_BITMASK	0xFFFFFF
 #define ARM_CPU_ID		0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
diff --git a/arm/aarch64/include/kvm/kvm-cpu-arch.h b/arm/aarch64/include/kvm/kvm-cpu-arch.h
index 016cf5b2b9ea..17b80493e2c0 100644
--- a/arm/aarch64/include/kvm/kvm-cpu-arch.h
+++ b/arm/aarch64/include/kvm/kvm-cpu-arch.h
@@ -5,10 +5,6 @@
 
 #include "arm-common/kvm-cpu-arch.h"
 
-#define ARM_VCPU_FEATURE_FLAGS(kvm, cpuid)	{				\
-	[0] = (!!(cpuid) << KVM_ARM_VCPU_POWER_OFF),				\
-}
-
 #define ARM_MPIDR_HWID_BITMASK	0xFF00FFFFFFUL
 #define ARM_CPU_ID		3, 0, 0, 0
 #define ARM_CPU_ID_MPIDR	5
diff --git a/arm/kvm-cpu.c b/arm/kvm-cpu.c
index 554414f81b7a..62177ea73f82 100644
--- a/arm/kvm-cpu.c
+++ b/arm/kvm-cpu.c
@@ -43,7 +43,7 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	unsigned int i;
 	struct kvm_vcpu_init preferred_init;
 	struct kvm_vcpu_init vcpu_init = {
-		.features = ARM_VCPU_FEATURE_FLAGS(kvm, cpu_id)
+		.features = {},
 	};
 
 	vcpu = calloc(1, sizeof(struct kvm_cpu));
@@ -63,6 +63,10 @@ struct kvm_cpu *kvm_cpu__arch_init(struct kvm *kvm, unsigned long cpu_id)
 	if (vcpu->kvm_run == MAP_FAILED)
 		die("unable to mmap vcpu fd");
 
+	/* VCPU 0 is the boot CPU, the others start in a poweroff state. */
+	if (cpu_id > 0)
+		vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_POWER_OFF);
+
 	/* Set KVM_ARM_VCPU_PSCI_0_2 if available */
 	if (kvm__supports_extension(kvm, KVM_CAP_ARM_PSCI_0_2)) {
 		vcpu_init.features[0] |= (1UL << KVM_ARM_VCPU_PSCI_0_2);
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:28 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:28 +0000
Subject: [PATCH v2 kvmtool 05/10] arm: Make the PMUv3 emulation code arm64
 specific
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-6-alexandru.elisei@arm.com>

KVM for aarch32 does not exist anymore, PMUv3 is a hardware feature
present only on aarch64 CPUs, the command line option to enable the
feature for a VCPU is aarch64 specific, the PMU code is called only from
an aarch64 function and it compiles to an empty stub when ARCH=arm.
There is no reason to have the PMUv3 emulation code in the common code
area for arm and arm64, so move it to the arm64 directory, where it can
be expanded in the future without fear of breaking aarch32 support.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Makefile                                              | 4 ++--
 arm/aarch64/arm-cpu.c                                 | 3 ++-
 arm/{include/arm-common => aarch64/include/asm}/pmu.h | 0
 arm/{ => aarch64}/pmu.c                               | 7 ++-----
 4 files changed, 6 insertions(+), 8 deletions(-)
 rename arm/{include/arm-common => aarch64/include/asm}/pmu.h (100%)
 rename arm/{ => aarch64}/pmu.c (93%)

diff --git a/Makefile b/Makefile
index f25114755701..2fe5fb0fba62 100644
--- a/Makefile
+++ b/Makefile
@@ -159,8 +159,7 @@ endif
 
 # ARM
 OBJS_ARM_COMMON		:= arm/fdt.o arm/gic.o arm/gicv2m.o arm/ioport.o \
-			   arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o \
-			   arm/pmu.o
+			   arm/kvm.o arm/kvm-cpu.o arm/pci.o arm/timer.o
 HDRS_ARM_COMMON		:= arm/include
 ifeq ($(ARCH), arm)
 	DEFINES		+= -DCONFIG_ARM
@@ -182,6 +181,7 @@ ifeq ($(ARCH), arm64)
 	OBJS		+= arm/aarch64/arm-cpu.o
 	OBJS		+= arm/aarch64/kvm-cpu.o
 	OBJS		+= arm/aarch64/kvm.o
+	OBJS		+= arm/aarch64/pmu.o
 	ARCH_INCLUDE	:= $(HDRS_ARM_COMMON)
 	ARCH_INCLUDE	+= -Iarm/aarch64/include
 
diff --git a/arm/aarch64/arm-cpu.c b/arm/aarch64/arm-cpu.c
index d7572b7790b1..1ec37fa60c50 100644
--- a/arm/aarch64/arm-cpu.c
+++ b/arm/aarch64/arm-cpu.c
@@ -5,7 +5,8 @@
 
 #include "arm-common/gic.h"
 #include "arm-common/timer.h"
-#include "arm-common/pmu.h"
+
+#include "asm/pmu.h"
 
 #include <linux/byteorder.h>
 #include <linux/types.h>
diff --git a/arm/include/arm-common/pmu.h b/arm/aarch64/include/asm/pmu.h
similarity index 100%
rename from arm/include/arm-common/pmu.h
rename to arm/aarch64/include/asm/pmu.h
diff --git a/arm/pmu.c b/arm/aarch64/pmu.c
similarity index 93%
rename from arm/pmu.c
rename to arm/aarch64/pmu.c
index 5b058eabb49d..6b190c5e2ae5 100644
--- a/arm/pmu.c
+++ b/arm/aarch64/pmu.c
@@ -4,9 +4,9 @@
 #include "kvm/util.h"
 
 #include "arm-common/gic.h"
-#include "arm-common/pmu.h"
 
-#ifdef CONFIG_ARM64
+#include "asm/pmu.h"
+
 static int set_pmu_attr(struct kvm *kvm, int vcpu_idx,
 			struct kvm_device_attr *attr)
 {
@@ -71,6 +71,3 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 	_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
 	_FDT(fdt_end_node(fdt));
 }
-#else
-void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm) { }
-#endif
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:29 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:29 +0000
Subject: [PATCH v2 kvmtool 06/10] arm64: Rework set_pmu_attr()
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-7-alexandru.elisei@arm.com>

By the time kvmtool generates the DTB node for the PMU, the
KVM_ARM_VCPU_PMU_V3 VCPU feature is already set by kvm_cpu__arch_init().

KVM refuses to run a VCPU if the PMU hasn't been initialized. A PMU
cannot be initialized if the interrupt ID hasn't been set by userspace.
As a consequence, kvmtool will get an error if the interrupt ID or if
the PMU has not been initialized:

KVM_RUN failed: Invalid argument

To make debugging easier, exit with an error message as soon as one the
PMU ioctls fails, instead of waiting until the VCPU is first run.

To avoid the repetition of assigning a new kvm_device_attr struct in the
main body of pmu__generate_fdt_nodes(), which hinders readability of the
function, move the struct to set_pmu_attr().

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch64/pmu.c | 48 ++++++++++++++++-------------------------------
 1 file changed, 16 insertions(+), 32 deletions(-)

diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c
index 6b190c5e2ae5..ac5b7bcd6ca9 100644
--- a/arm/aarch64/pmu.c
+++ b/arm/aarch64/pmu.c
@@ -7,30 +7,31 @@
 
 #include "asm/pmu.h"
 
-static int set_pmu_attr(struct kvm *kvm, int vcpu_idx,
-			struct kvm_device_attr *attr)
+static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
 {
-	int ret, fd;
-
-	fd = kvm->cpus[vcpu_idx]->vcpu_fd;
+	struct kvm_device_attr pmu_attr = {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.addr	= (u64)addr,
+		.attr	= attr,
+	};
+	int ret;
 
-	ret = ioctl(fd, KVM_HAS_DEVICE_ATTR, attr);
+	ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr);
 	if (!ret) {
-		ret = ioctl(fd, KVM_SET_DEVICE_ATTR, attr);
+		ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
 		if (ret)
-			perror("PMU KVM_SET_DEVICE_ATTR failed");
+			die_perror("PMU KVM_SET_DEVICE_ATTR");
 	} else {
-		pr_err("Unsupported PMU on vcpu%d\n", vcpu_idx);
+		die_perror("PMU KVM_HAS_DEVICE_ATTR");
 	}
-
-	return ret;
 }
 
 void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 {
 	const char compatible[] = "arm,armv8-pmuv3";
 	int irq = KVM_ARM_PMUv3_PPI;
-	int i, ret;
+	struct kvm_cpu *vcpu;
+	int i;
 
 	u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
 		       & GIC_FDT_IRQ_PPI_CPU_MASK;
@@ -44,26 +45,9 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 		return;
 
 	for (i = 0; i < kvm->nrcpus; i++) {
-		struct kvm_device_attr pmu_attr;
-
-		pmu_attr = (struct kvm_device_attr){
-			.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
-			.addr	= (u64)(unsigned long)&irq,
-			.attr	= KVM_ARM_VCPU_PMU_V3_IRQ,
-		};
-
-		ret = set_pmu_attr(kvm, i, &pmu_attr);
-		if (ret)
-			return;
-
-		pmu_attr = (struct kvm_device_attr){
-			.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
-			.attr	= KVM_ARM_VCPU_PMU_V3_INIT,
-		};
-
-		ret = set_pmu_attr(kvm, i, &pmu_attr);
-		if (ret)
-			return;
+		vcpu = kvm->cpus[i];
+		set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ);
+		set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
 	}
 
 	_FDT(fdt_begin_node(fdt, "pmu"));
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:30 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:30 +0000
Subject: [PATCH v2 kvmtool 07/10] Add cpumask functions
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-8-alexandru.elisei@arm.com>

Add a handful of cpumask functions, some of which will be used when
dealing with different PMUs on heterogeneous systems.

The maximum number of CPUs in a system, NR_CPUS, which dictates the size of
the cpumask, has been taken from the Kconfig file for each architecture,
from Linux version 5.16.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 Makefile                         |   2 +
 arm/aarch32/include/asm/kernel.h |   8 +
 arm/aarch64/include/asm/kernel.h |   8 +
 include/linux/bitmap.h           |  71 +++++++++
 include/linux/bitops.h           |   2 +
 include/linux/bits.h             |   8 +
 include/linux/cpumask.h          |  62 ++++++++
 include/linux/find.h             |  30 ++++
 include/linux/kernel.h           |   6 +
 mips/include/asm/kernel.h        |   8 +
 powerpc/include/asm/kernel.h     |   8 +
 util/bitmap.c                    | 256 +++++++++++++++++++++++++++++++
 util/find.c                      |  40 +++++
 x86/include/asm/kernel.h         |   8 +
 14 files changed, 517 insertions(+)
 create mode 100644 arm/aarch32/include/asm/kernel.h
 create mode 100644 arm/aarch64/include/asm/kernel.h
 create mode 100644 include/linux/bitmap.h
 create mode 100644 include/linux/bits.h
 create mode 100644 include/linux/cpumask.h
 create mode 100644 include/linux/find.h
 create mode 100644 mips/include/asm/kernel.h
 create mode 100644 powerpc/include/asm/kernel.h
 create mode 100644 util/bitmap.c
 create mode 100644 util/find.c
 create mode 100644 x86/include/asm/kernel.h

diff --git a/Makefile b/Makefile
index 2fe5fb0fba62..8bc0bba80833 100644
--- a/Makefile
+++ b/Makefile
@@ -89,6 +89,8 @@ OBJS	+= net/uip/buf.o
 OBJS	+= net/uip/csum.o
 OBJS	+= net/uip/dhcp.o
 OBJS	+= kvm-cmd.o
+OBJS	+= util/bitmap.o
+OBJS	+= util/find.o
 OBJS	+= util/init.o
 OBJS    += util/iovec.o
 OBJS	+= util/rbtree.o
diff --git a/arm/aarch32/include/asm/kernel.h b/arm/aarch32/include/asm/kernel.h
new file mode 100644
index 000000000000..61296094deb1
--- /dev/null
+++ b/arm/aarch32/include/asm/kernel.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_KERNEL_H
+#define __ASM_KERNEL_H
+
+#define NR_CPUS	32
+
+#endif /* __ASM_KERNEL_H */
diff --git a/arm/aarch64/include/asm/kernel.h b/arm/aarch64/include/asm/kernel.h
new file mode 100644
index 000000000000..a2a8d9ed4059
--- /dev/null
+++ b/arm/aarch64/include/asm/kernel.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_KERNEL_H
+#define __ASM_KERNEL_H
+
+#define NR_CPUS	4096
+
+#endif /* __ASM_KERNEL_H */
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
new file mode 100644
index 000000000000..2b36e9f42cb8
--- /dev/null
+++ b/include/linux/bitmap.h
@@ -0,0 +1,71 @@
+#ifndef KVM__BITMAP_H
+#define KVM__BITMAP_H
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "linux/bitops.h"
+
+#define DECLARE_BITMAP(name,bits) \
+	unsigned long name[BITS_TO_LONGS(bits)]
+
+#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
+#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
+
+static inline void bitmap_zero(unsigned long *dst, unsigned int nbits)
+{
+	unsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
+	memset(dst, 0, len);
+}
+
+#ifdef __LITTLE_ENDIAN
+#define BITMAP_MEM_ALIGNMENT 8
+#else
+#define BITMAP_MEM_ALIGNMENT (8 * sizeof(unsigned long))
+#endif
+#define BITMAP_MEM_MASK (BITMAP_MEM_ALIGNMENT - 1)
+
+void __bitmap_set(unsigned long *map, unsigned int start, int len);
+
+static inline void bitmap_set(unsigned long *map, unsigned int start,
+		unsigned int nbits)
+{
+	if (__builtin_constant_p(nbits) && nbits == 1)
+		set_bit(start, map);
+	else if (__builtin_constant_p(start & BITMAP_MEM_MASK) &&
+		 IS_ALIGNED(start, BITMAP_MEM_ALIGNMENT) &&
+		 __builtin_constant_p(nbits & BITMAP_MEM_MASK) &&
+		 IS_ALIGNED(nbits, BITMAP_MEM_ALIGNMENT))
+		memset((char *)map + start / 8, 0xff, nbits / 8);
+	else
+		__bitmap_set(map, start, nbits);
+}
+
+bool __bitmap_and(unsigned long *dst, const unsigned long *src1,
+		  const unsigned long *src2, unsigned int nbits);
+
+static inline bool bitmap_and(unsigned long *dst, const unsigned long *src1,
+			      const unsigned long *src2, unsigned int nbits)
+{
+	if (nbits >= 0 && nbits <= BITS_PER_LONG)
+		return (*dst = *src1 & *src2 & BITMAP_LAST_WORD_MASK(nbits)) != 0;
+
+	return __bitmap_and(dst, src1, src2, nbits);
+}
+
+int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits);
+
+bool __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2,
+		     unsigned int nbits);
+
+static inline bool bitmap_subset(const unsigned long *src1,
+				 const unsigned long *src2, unsigned int nbits)
+{
+	if (nbits >= 0 && nbits <= BITS_PER_LONG)
+		return !((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
+
+	return __bitmap_subset(src1, src2, nbits);
+}
+
+
+#endif /* KVM__BITMAP_H */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 3d31f0acf48e..ae33922f5743 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -11,6 +11,8 @@
 #define BITS_PER_BYTE           8
 #define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
 
+#define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
+
 static inline void set_bit(int nr, unsigned long *addr)
 {
 	addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
diff --git a/include/linux/bits.h b/include/linux/bits.h
new file mode 100644
index 000000000000..b6b1c2c3f96d
--- /dev/null
+++ b/include/linux/bits.h
@@ -0,0 +1,8 @@
+#ifndef KVM__BITS_H_
+#define KVM__BITS_H_
+
+#define GENMASK(h, l) \
+	((~0UL - (1UL << (l)) + 1) & \
+	 (~0UL >> (BITS_PER_LONG - 1 - (h))))
+
+#endif /* KVM__BITS_H */
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
new file mode 100644
index 000000000000..19aff92bdb5b
--- /dev/null
+++ b/include/linux/cpumask.h
@@ -0,0 +1,62 @@
+#ifndef KVM__CPUMASK_H
+#define KVM__CPUMASK_H
+
+#include <stdbool.h>
+
+#include "linux/bitmap.h"
+#include "linux/find.h"
+#include "linux/kernel.h"
+
+typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
+
+#define cpumask_bits(maskp)	((maskp)->bits)
+
+static inline void cpumask_set_cpu(int cpu, cpumask_t *dstp)
+{
+	set_bit(cpu, cpumask_bits(dstp));
+}
+
+static inline void cpumask_clear_cpu(int cpu, cpumask_t *dstp)
+{
+	clear_bit(cpu, cpumask_bits(dstp));
+}
+
+static inline bool cpumask_test_cpu(int cpu, const cpumask_t *cpumask)
+{
+	return test_bit(cpu, cpumask_bits((cpumask)));
+}
+
+static inline void cpumask_clear(cpumask_t *dstp)
+{
+	bitmap_zero(cpumask_bits(dstp), NR_CPUS);
+}
+
+static inline bool cpumask_and(cpumask_t *dstp, cpumask_t *src1p,
+			       cpumask_t *src2p)
+{
+	return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p),
+			  cpumask_bits(src2p), NR_CPUS);
+}
+
+static inline unsigned int cpumask_next(int n, const struct cpumask *srcp)
+{
+	return find_next_bit(cpumask_bits(srcp), NR_CPUS, n + 1);
+}
+
+#define for_each_cpu(cpu, maskp)			\
+	for ((cpu) = -1;				\
+	     (cpu) = cpumask_next((cpu), (maskp)),	\
+	     (cpu) < NR_CPUS;)
+
+static inline int cpulist_parse(const char *buf, cpumask_t *dstp)
+{
+	return bitmap_parselist(buf, cpumask_bits(dstp), NR_CPUS);
+}
+
+static inline bool cpumask_subset(const  cpumask_t *src1p,
+				  const  cpumask_t *src2p)
+{
+	return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p), NR_CPUS);
+}
+
+#endif /* KVM__CPUMASK_H */
diff --git a/include/linux/find.h b/include/linux/find.h
new file mode 100644
index 000000000000..29c0d67bcd30
--- /dev/null
+++ b/include/linux/find.h
@@ -0,0 +1,30 @@
+#ifndef KVM__FIND_H
+#define KVM__FIND_H
+
+#include <stddef.h>
+
+#include "linux/bitops.h"
+#include "linux/bits.h"
+
+unsigned long _find_next_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long nbits,
+		unsigned long start, unsigned long invert);
+
+static inline
+unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
+			    unsigned long offset)
+{
+	if (size >= 0 && size <= BITS_PER_LONG) {
+		unsigned long val;
+
+		if (offset >= size)
+			return size;
+
+		val = *addr & GENMASK(size - 1, offset);
+		return val ? (unsigned long)__builtin_ctzl(val) : size;
+	}
+
+	return _find_next_bit(addr, NULL, size, offset, 0);
+}
+
+#endif /* KVM__FIND_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f2bff5f12b61..6c22f1c06f6d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -2,10 +2,16 @@
 #ifndef KVM__LINUX_KERNEL_H_
 #define KVM__LINUX_KERNEL_H_
 
+#include "asm/kernel.h"
+
+#define __round_mask(x, y)	((__typeof__(x))((y)-1))
+#define round_down(x, y)	((x) & ~__round_mask(x, y))
+
 #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
 
 #define ALIGN(x,a)		__ALIGN_MASK(x,(typeof(x))(a)-1)
 #define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
+#define IS_ALIGNED(x, a)	(((x) & ((typeof(x))(a) - 1)) == 0)
 
 #ifndef offsetof
 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
diff --git a/mips/include/asm/kernel.h b/mips/include/asm/kernel.h
new file mode 100644
index 000000000000..cbceffd02acd
--- /dev/null
+++ b/mips/include/asm/kernel.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_KERNEL_H
+#define __ASM_KERNEL_H
+
+#define NR_CPUS	256
+
+#endif /* __ASM_KERNEL_H */
diff --git a/powerpc/include/asm/kernel.h b/powerpc/include/asm/kernel.h
new file mode 100644
index 000000000000..7b4fe88efd65
--- /dev/null
+++ b/powerpc/include/asm/kernel.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_KERNEL_H
+#define __ASM_KERNEL_H
+
+#define NR_CPUS	2048
+
+#endif /* __ASM_KERNEL_H */
diff --git a/util/bitmap.c b/util/bitmap.c
new file mode 100644
index 000000000000..8bae1c91499d
--- /dev/null
+++ b/util/bitmap.c
@@ -0,0 +1,256 @@
+/*
+ * Taken from Linux kernel version v5.15.
+ */
+#include <ctype.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include "linux/bitmap.h"
+#include "linux/bitops.h"
+#include "linux/err.h"
+
+/*
+ * Region 9-38:4/10 describes the following bitmap structure:
+ * 0	   9  12    18			38	     N
+ * .........****......****......****..................
+ *	    ^  ^     ^			 ^	     ^
+ *      start  off   group_len	       end	 nbits
+ */
+struct region {
+	unsigned int start;
+	unsigned int off;
+	unsigned int group_len;
+	unsigned int end;
+	unsigned int nbits;
+};
+
+void __bitmap_set(unsigned long *map, unsigned int start, int len)
+{
+	unsigned long *p = map + BIT_WORD(start);
+	const unsigned int size = start + len;
+	int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG);
+	unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start);
+
+	while (len - bits_to_set >= 0) {
+		*p |= mask_to_set;
+		len -= bits_to_set;
+		bits_to_set = BITS_PER_LONG;
+		mask_to_set = ~0UL;
+		p++;
+	}
+	if (len) {
+		mask_to_set &= BITMAP_LAST_WORD_MASK(size);
+		*p |= mask_to_set;
+	}
+}
+
+static void bitmap_set_region(const struct region *r, unsigned long *bitmap)
+{
+	unsigned int start;
+
+	for (start = r->start; start <= r->end; start += r->group_len)
+		bitmap_set(bitmap, start, min(r->end - start + 1, r->off));
+}
+
+static inline bool __end_of_region(char c)
+{
+	return isspace(c) || c == ',';
+}
+
+static inline bool end_of_str(char c)
+{
+	return c == '\0' || c == '\n';
+}
+
+static inline bool end_of_region(char c)
+{
+	return __end_of_region(c) || end_of_str(c);
+}
+
+/*
+ * The format allows commas and whitespaces at the beginning
+ * of the region.
+ */
+static const char *bitmap_find_region(const char *str)
+{
+	while (__end_of_region(*str))
+		str++;
+
+	return end_of_str(*str) ? NULL : str;
+}
+
+static int bitmap_check_region(const struct region *r)
+{
+	if (r->start > r->end || r->group_len == 0 || r->off > r->group_len)
+		return -EINVAL;
+
+	if (r->end >= r->nbits)
+		return -ERANGE;
+
+	return 0;
+}
+
+static const char *bitmap_getnum(const char *str, unsigned int *num,
+				 unsigned int lastbit)
+{
+	unsigned long long n;
+	char *endptr;
+
+	if (str[0] == 'N') {
+		*num = lastbit;
+		return str + 1;
+	}
+
+	n = strtoll(str, &endptr, 10);
+	/* No digits found. */
+	if (n == 0 && endptr == str)
+		return ERR_PTR(-EINVAL);
+	/* Check for overflows and negative numbers. */
+	if (n == ULLONG_MAX || n != (unsigned long)n || n != (unsigned int)n)
+		return ERR_PTR(-EOVERFLOW);
+
+	*num = n;
+	return endptr;
+}
+
+static const char *bitmap_parse_region(const char *str, struct region *r)
+{
+	unsigned int lastbit = r->nbits - 1;
+
+	if (!strncasecmp(str, "all", 3)) {
+		r->start = 0;
+		r->end = lastbit;
+		str += 3;
+
+		goto check_pattern;
+	}
+
+	str = bitmap_getnum(str, &r->start, lastbit);
+	if (IS_ERR(str))
+		return str;
+
+	if (end_of_region(*str))
+		goto no_end;
+
+	if (*str != '-')
+		return ERR_PTR(-EINVAL);
+
+	str = bitmap_getnum(str + 1, &r->end, lastbit);
+	if (IS_ERR(str))
+		return str;
+
+check_pattern:
+	if (end_of_region(*str))
+		goto no_pattern;
+
+	if (*str != ':')
+		return ERR_PTR(-EINVAL);
+
+	str = bitmap_getnum(str + 1, &r->off, lastbit);
+	if (IS_ERR(str))
+		return str;
+
+	if (*str != '/')
+		return ERR_PTR(-EINVAL);
+
+	return bitmap_getnum(str + 1, &r->group_len, lastbit);
+
+no_end:
+	r->end = r->start;
+no_pattern:
+	r->off = r->end + 1;
+	r->group_len = r->end + 1;
+
+	return end_of_str(*str) ? NULL : str;
+}
+
+/**
+ * bitmap_parselist - convert list format ASCII string to bitmap
+ * @buf: read user string from this buffer; must be terminated
+ *    with a \0 or \n.
+ * @maskp: write resulting mask here
+ * @nmaskbits: number of bits in mask to be written
+ *
+ * Input format is a comma-separated list of decimal numbers and
+ * ranges.  Consecutively set bits are shown as two hyphen-separated
+ * decimal numbers, the smallest and largest bit numbers set in
+ * the range.
+ * Optionally each range can be postfixed to denote that only parts of it
+ * should be set. The range will divided to groups of specific size.
+ * From each group will be used only defined amount of bits.
+ * Syntax: range:used_size/group_size
+ * Example: 0-1023:2/256 ==> 0,1,256,257,512,513,768,769
+ * The value 'N' can be used as a dynamically substituted token for the
+ * maximum allowed value; i.e (nmaskbits - 1).  Keep in mind that it is
+ * dynamic, so if system changes cause the bitmap width to change, such
+ * as more cores in a CPU list, then any ranges using N will also change.
+ *
+ * Returns: 0 on success, -errno on invalid input strings. Error values:
+ *
+ *   - ``-EINVAL``: wrong region format
+ *   - ``-EINVAL``: invalid character in string
+ *   - ``-ERANGE``: bit number specified too large for mask
+ *   - ``-EOVERFLOW``: integer overflow in the input parameters
+ */
+int bitmap_parselist(const char *buf, unsigned long *maskp, int nmaskbits)
+{
+	struct region r;
+	long ret;
+
+	r.nbits = nmaskbits;
+	bitmap_zero(maskp, r.nbits);
+
+	while (buf) {
+		buf = bitmap_find_region(buf);
+		if (buf == NULL)
+			return 0;
+
+		buf = bitmap_parse_region(buf, &r);
+		if (IS_ERR(buf))
+			return PTR_ERR(buf);
+
+		ret = bitmap_check_region(&r);
+		if (ret)
+			return ret;
+
+		bitmap_set_region(&r, maskp);
+	}
+
+	return 0;
+}
+
+bool __bitmap_and(unsigned long *dst, const unsigned long *src1,
+		  const unsigned long *src2, unsigned int nbits)
+{
+	unsigned int lim = nbits / BITS_PER_LONG;
+	unsigned long result = 0;
+	unsigned int k;
+
+	for (k = 0; k < lim; k++)
+		result |= (dst[k] = src1[k] & src2[k]);
+
+	if (nbits % BITS_PER_LONG) {
+		result |= (dst[k] = src1[k] & src2[k] &
+			   BITMAP_LAST_WORD_MASK(nbits));
+	}
+
+	return result != 0;
+}
+
+bool __bitmap_subset(const unsigned long *bitmap1, const unsigned long *bitmap2,
+		     unsigned int nbits)
+{
+	unsigned int k, lim = nbits / BITS_PER_LONG;
+
+	for (k = 0; k < lim; k++)
+		if (bitmap1[k] & ~bitmap2[k])
+			return false;
+
+	if (nbits % BITS_PER_LONG) {
+		if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(nbits))
+			return false;
+	}
+
+	return true;
+}
diff --git a/util/find.c b/util/find.c
new file mode 100644
index 000000000000..a438f2388e00
--- /dev/null
+++ b/util/find.c
@@ -0,0 +1,40 @@
+/*
+ * Taken from Linux kernel version v5.16.
+ */
+#include "linux/bitmap.h"
+#include "linux/find.h"
+#include "linux/kernel.h"
+
+unsigned long _find_next_bit(const unsigned long *addr1,
+		const unsigned long *addr2, unsigned long nbits,
+		unsigned long start, unsigned long invert)
+{
+	unsigned long tmp, mask;
+
+	if (start >= nbits)
+		return nbits;
+
+	tmp = addr1[start / BITS_PER_LONG];
+	if (addr2)
+		tmp &= addr2[start / BITS_PER_LONG];
+	tmp ^= invert;
+
+	/* Handle 1st word. */
+	mask = BITMAP_FIRST_WORD_MASK(start);
+	tmp &= mask;
+
+	start = round_down(start, BITS_PER_LONG);
+
+	while (!tmp) {
+		start += BITS_PER_LONG;
+		if (start >= nbits)
+			return nbits;
+
+		tmp = addr1[start / BITS_PER_LONG];
+		if (addr2)
+			tmp &= addr2[start / BITS_PER_LONG];
+		tmp ^= invert;
+	}
+
+	return min(start + __builtin_ctzl(tmp), nbits);
+}
diff --git a/x86/include/asm/kernel.h b/x86/include/asm/kernel.h
new file mode 100644
index 000000000000..87fad2a0300a
--- /dev/null
+++ b/x86/include/asm/kernel.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _ASM_KERNEL_H
+#define _ASM_KERNEL_H
+
+#define NR_CPUS	8196
+
+#endif /* _ASM_KERNEL_H */
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:31 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:31 +0000
Subject: [PATCH v2 kvmtool 08/10] update_headers.sh: Sync headers with Linux
 v5.17-rc1 + SET_PMU attribute
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-9-alexandru.elisei@arm.com>

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch64/include/asm/kvm.h |  4 ++++
 include/linux/kvm.h           | 16 ++++++++++++++++
 x86/include/asm/kvm.h         | 16 +++++++++++++++-
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/arm/aarch64/include/asm/kvm.h b/arm/aarch64/include/asm/kvm.h
index b3edde68bc3e..d49f714f48e6 100644
--- a/arm/aarch64/include/asm/kvm.h
+++ b/arm/aarch64/include/asm/kvm.h
@@ -362,6 +362,7 @@ struct kvm_arm_copy_mte_tags {
 #define   KVM_ARM_VCPU_PMU_V3_IRQ	0
 #define   KVM_ARM_VCPU_PMU_V3_INIT	1
 #define   KVM_ARM_VCPU_PMU_V3_FILTER	2
+#define   KVM_ARM_VCPU_PMU_V3_SET_PMU	3
 #define KVM_ARM_VCPU_TIMER_CTRL		1
 #define   KVM_ARM_VCPU_TIMER_IRQ_VTIMER		0
 #define   KVM_ARM_VCPU_TIMER_IRQ_PTIMER		1
@@ -413,6 +414,9 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_PSCI_RET_INVAL		PSCI_RET_INVALID_PARAMS
 #define KVM_PSCI_RET_DENIED		PSCI_RET_DENIED
 
+/* run->fail_entry.hardware_entry_failure_reason codes. */
+#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED	(1ULL << 0)
+
 #endif
 
 #endif /* __ARM_KVM_H__ */
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 1daa45268de2..9563d294f181 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -1131,6 +1131,8 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_EXIT_ON_EMULATION_FAILURE 204
 #define KVM_CAP_ARM_MTE 205
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
+#define KVM_CAP_VM_GPA_BITS 207
+#define KVM_CAP_XSAVE2 208
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1162,11 +1164,20 @@ struct kvm_irq_routing_hv_sint {
 	__u32 sint;
 };
 
+struct kvm_irq_routing_xen_evtchn {
+	__u32 port;
+	__u32 vcpu;
+	__u32 priority;
+};
+
+#define KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL ((__u32)(-1))
+
 /* gsi routing entry types */
 #define KVM_IRQ_ROUTING_IRQCHIP 1
 #define KVM_IRQ_ROUTING_MSI 2
 #define KVM_IRQ_ROUTING_S390_ADAPTER 3
 #define KVM_IRQ_ROUTING_HV_SINT 4
+#define KVM_IRQ_ROUTING_XEN_EVTCHN 5
 
 struct kvm_irq_routing_entry {
 	__u32 gsi;
@@ -1178,6 +1189,7 @@ struct kvm_irq_routing_entry {
 		struct kvm_irq_routing_msi msi;
 		struct kvm_irq_routing_s390_adapter adapter;
 		struct kvm_irq_routing_hv_sint hv_sint;
+		struct kvm_irq_routing_xen_evtchn xen_evtchn;
 		__u32 pad[8];
 	} u;
 };
@@ -1208,6 +1220,7 @@ struct kvm_x86_mce {
 #define KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL	(1 << 1)
 #define KVM_XEN_HVM_CONFIG_SHARED_INFO		(1 << 2)
 #define KVM_XEN_HVM_CONFIG_RUNSTATE		(1 << 3)
+#define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL	(1 << 4)
 
 struct kvm_xen_hvm_config {
 	__u32 flags;
@@ -1610,6 +1623,9 @@ struct kvm_enc_region {
 #define KVM_S390_NORMAL_RESET	_IO(KVMIO,   0xc3)
 #define KVM_S390_CLEAR_RESET	_IO(KVMIO,   0xc4)
 
+/* Available with KVM_CAP_XSAVE2 */
+#define KVM_GET_XSAVE2		  _IOR(KVMIO,  0xcf, struct kvm_xsave)
+
 struct kvm_s390_pv_sec_parm {
 	__u64 origin;
 	__u64 length;
diff --git a/x86/include/asm/kvm.h b/x86/include/asm/kvm.h
index 5a776a08f78c..2da3316bb559 100644
--- a/x86/include/asm/kvm.h
+++ b/x86/include/asm/kvm.h
@@ -373,9 +373,23 @@ struct kvm_debugregs {
 	__u64 reserved[9];
 };
 
-/* for KVM_CAP_XSAVE */
+/* for KVM_CAP_XSAVE and KVM_CAP_XSAVE2 */
 struct kvm_xsave {
+	/*
+	 * KVM_GET_XSAVE2 and KVM_SET_XSAVE write and read as many bytes
+	 * as are returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * respectively, when invoked on the vm file descriptor.
+	 *
+	 * The size value returned by KVM_CHECK_EXTENSION(KVM_CAP_XSAVE2)
+	 * will always be at least 4096. Currently, it is only greater
+	 * than 4096 if a dynamic feature has been enabled with
+	 * ``arch_prctl()``, but this may change in the future.
+	 *
+	 * The offsets of the state save areas in struct kvm_xsave follow
+	 * the contents of CPUID leaf 0xD on the host.
+	 */
 	__u32 region[1024];
+	__u32 extra[0];
 };
 
 #define KVM_MAX_XCRS	16
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:32 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:32 +0000
Subject: [PATCH v2 kvmtool 09/10] arm64: Add support for
 KVM_ARM_VCPU_PMU_V3_SET_PMU
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-10-alexandru.elisei@arm.com>

The KVM_ARM_VCPU_PMU_V3_CTRL(KVM_ARM_VCPU_PMU_V3_SET_PMU) VCPU ioctl is
used to assign a physical PMU to the events that KVM creates when emulating
the PMU for that VCPU. This is useful on heterogeneous systems, when there
is more than one hardware PMU present.

The assumption that is made in the implementation is that the user will
pin the kvmtool process on a set of CPUs that share the same PMU. This
allows kvmtool to set the same PMU for all VCPUs from the main thread,
instead of in the individual VCPU threads.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch64/pmu.c | 148 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 146 insertions(+), 2 deletions(-)

diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c
index ac5b7bcd6ca9..c0fc95ca01c4 100644
--- a/arm/aarch64/pmu.c
+++ b/arm/aarch64/pmu.c
@@ -1,3 +1,9 @@
+#include <dirent.h>
+#include <sched.h>
+
+#include "linux/cpumask.h"
+#include "linux/err.h"
+
 #include "kvm/fdt.h"
 #include "kvm/kvm.h"
 #include "kvm/kvm-cpu.h"
@@ -7,6 +13,18 @@
 
 #include "asm/pmu.h"
 
+static bool pmu_has_attr(struct kvm_cpu *vcpu, u64 attr)
+{
+	struct kvm_device_attr pmu_attr = {
+		.group	= KVM_ARM_VCPU_PMU_V3_CTRL,
+		.attr	= attr,
+	};
+	int ret;
+
+	ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr);
+	return ret == 0;
+}
+
 static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
 {
 	struct kvm_device_attr pmu_attr = {
@@ -16,8 +34,7 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
 	};
 	int ret;
 
-	ret = ioctl(vcpu->vcpu_fd, KVM_HAS_DEVICE_ATTR, &pmu_attr);
-	if (!ret) {
+	if (pmu_has_attr(vcpu, attr)) {
 		ret = ioctl(vcpu->vcpu_fd, KVM_SET_DEVICE_ATTR, &pmu_attr);
 		if (ret)
 			die_perror("PMU KVM_SET_DEVICE_ATTR");
@@ -26,11 +43,126 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
 	}
 }
 
+#define SYS_EVENT_SOURCE	"/sys/bus/event_source/devices/"
+/*
+ * int is 32 bits and INT_MAX translates in decimal to 2 * 10^9.
+ * Make room for newline and NUL.
+ */
+#define PMU_ID_MAXLEN		12
+
+/*
+ * In the case of homogeneous systems, there only one hardware PMU, and all
+ * VCPUs will use the same PMU, regardless of where the attribute gets set.
+ *
+ * For heterogeneous systems, the assumption is that the user has pinned the VM
+ * (via taskset or similar) to a set of CPUs that share the same hardware PMU.
+ * This simplifies things for kvmtool, as correctness is not affected by setting
+ * the PMU for each VCPU from the main thread, instead of setting it from each
+ * individual VCPU thread.
+ */
+static int find_pmu(void)
+{
+	char buf[PMU_ID_MAXLEN];
+	struct dirent *dirent;
+	char *cpulist, *path;
+	int pmu_id = -ENXIO;
+	unsigned long val;
+	cpumask_t cpumask;
+	ssize_t fd_sz;
+	int this_cpu;
+	int fd, ret;
+	DIR *dir;
+
+	memset(buf, 0, PMU_ID_MAXLEN);
+
+	this_cpu = sched_getcpu();
+	if (this_cpu < 0)
+		return -errno;
+
+	cpulist = calloc(1, PAGE_SIZE);
+	if (!cpulist)
+		return -ENOMEM;
+
+	path = calloc(1, PAGE_SIZE);
+	if (!path) {
+		pmu_id = -ENOMEM;
+		goto out_free_cpulist;
+	}
+	/* Make the compiler happy by copying the NULL terminating byte. */
+	strncpy(path, SYS_EVENT_SOURCE, strlen(SYS_EVENT_SOURCE) + 1);
+
+	dir = opendir(SYS_EVENT_SOURCE);
+	if (!dir) {
+		pmu_id = -errno;
+		goto out_free;
+	}
+
+	while ((dirent = readdir(dir))) {
+		if (dirent->d_type != DT_LNK)
+			continue;
+
+		strcat(path, dirent->d_name);
+		strcat(path, "/cpus");
+		fd = open(path, O_RDONLY);
+		if (fd < 0)
+			goto next_dir;
+
+		fd_sz = read_file(fd, cpulist, PAGE_SIZE);
+		if (fd_sz < 0) {
+			pmu_id = -errno;
+			goto out_free;
+		}
+		close(fd);
+
+		ret = cpulist_parse(cpulist, &cpumask);
+		if (ret) {
+			pmu_id = ret;
+			goto out_free;
+		}
+
+		if (!cpumask_test_cpu(this_cpu, &cpumask))
+			goto next_dir;
+
+		strcpy(&path[strlen(path) - 4], "type");
+		fd = open(path, O_RDONLY);
+		if (fd < 0)
+			goto next_dir;
+
+		fd_sz = read_file(fd, buf, PMU_ID_MAXLEN - 1);
+		if (fd_sz < 0) {
+			pmu_id = -errno;
+			goto out_free;
+		}
+		close(fd);
+
+		val = strtoul(buf, NULL, 10);
+		if (val > INT_MAX) {
+			pmu_id = -EOVERFLOW;
+			goto out_free;
+		}
+		pmu_id = (int)val;
+		pr_debug("Using PMU: %s (id: %d)", dirent->d_name, pmu_id);
+		break;
+
+next_dir:
+		/* Reset path. */
+		memset(&path[strlen(SYS_EVENT_SOURCE)], '\0',
+		       strlen(path) - strlen(SYS_EVENT_SOURCE));
+	}
+
+out_free:
+	free(path);
+out_free_cpulist:
+	free(cpulist);
+	return pmu_id;
+}
+
 void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 {
 	const char compatible[] = "arm,armv8-pmuv3";
 	int irq = KVM_ARM_PMUv3_PPI;
 	struct kvm_cpu *vcpu;
+	int pmu_id = -ENXIO;
 	int i;
 
 	u32 cpu_mask = (((1 << kvm->nrcpus) - 1) << GIC_FDT_IRQ_PPI_CPU_SHIFT) \
@@ -44,9 +176,21 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 	if (!kvm->cfg.arch.has_pmuv3)
 		return;
 
+	if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) {
+		pmu_id = find_pmu();
+		if (pmu_id < 0)
+			pr_debug("Failed to find a PMU (errno = %d)", -pmu_id);
+	}
+
 	for (i = 0; i < kvm->nrcpus; i++) {
 		vcpu = kvm->cpus[i];
 		set_pmu_attr(vcpu, &irq, KVM_ARM_VCPU_PMU_V3_IRQ);
+		/*
+		 * PMU IDs 0-5 are reserved; a positive value means a PMU was
+		 * found.
+		 */
+		if (pmu_id > 0)
+			set_pmu_attr(vcpu, &pmu_id, KVM_ARM_VCPU_PMU_V3_SET_PMU);
 		set_pmu_attr(vcpu, NULL, KVM_ARM_VCPU_PMU_V3_INIT);
 	}
 
-- 
2.31.1



From alexandru.elisei at arm.com  Thu Jan 27 08:20:33 2022
From: alexandru.elisei at arm.com (Alexandru Elisei)
Date: Thu, 27 Jan 2022 16:20:33 +0000
Subject: [PATCH v2 kvmtool 10/10] arm64: Add --vcpu-affinity command line
 argument
In-Reply-To: <20220127162033.54290-1-alexandru.elisei@arm.com>
References: <20220127162033.54290-1-alexandru.elisei@arm.com>
Message-ID: <20220127162033.54290-11-alexandru.elisei@arm.com>

Add a new command line argument, --vcpu-affinity, to set the CPU affinity
for the VCPUs. The affinity is expressed as a cpulist and will apply to all
VCPU threads.

This gives the user a second option for choosing the PMU on a heterogeneous
system. The PMU setup code, when --vcpu-affinity is specified, will search
for the PMU associated with the CPUs specified with this command line
argument instead of the PMU associated with the CPU on which the main
thread is executing.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 arm/aarch64/include/kvm/kvm-config-arch.h |  5 ++
 arm/aarch64/kvm-cpu.c                     |  9 +++
 arm/aarch64/kvm.c                         | 32 +++++++++++
 arm/aarch64/pmu.c                         | 70 ++++++++++++++++-------
 arm/include/arm-common/kvm-arch.h         |  7 +++
 arm/include/arm-common/kvm-config-arch.h  |  1 +
 include/linux/cpumask.h                   |  5 ++
 7 files changed, 109 insertions(+), 20 deletions(-)

diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 04be43dfa9b2..04c04a8865c9 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -1,11 +1,16 @@
 #ifndef KVM__KVM_CONFIG_ARCH_H
 #define KVM__KVM_CONFIG_ARCH_H
 
+int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset);
+
 #define ARM_OPT_ARCH_RUN(cfg)						\
 	OPT_BOOLEAN('\0', "aarch32", &(cfg)->aarch32_guest,		\
 			"Run AArch32 guest"),				\
 	OPT_BOOLEAN('\0', "pmu", &(cfg)->has_pmuv3,			\
 			"Create PMUv3 device"),				\
+	OPT_CALLBACK('\0', "vcpu-affinity", kvm, "cpulist",  		\
+			"Specify the CPU affinity that will apply to "	\
+			"all VCPUs", vcpu_affinity_parser, kvm),	\
 	OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed,			\
 			"Specify random seed for Kernel Address Space "	\
 			"Layout Randomization (KASLR)"),
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 3b6224a599c8..27ec8c1d4070 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -90,6 +90,15 @@ static void reset_vcpu_aarch64(struct kvm_cpu *vcpu)
 	struct kvm_one_reg reg;
 	u64 data;
 
+	cpu_set_t *affinity = kvm->arch.vcpu_affinity_cpuset;
+	int ret;
+
+	if (affinity) {
+		ret = sched_setaffinity(0, sizeof(cpu_set_t), affinity);
+		if (ret == -1)
+			die_perror("sched_setaffinity");
+	}
+
 	reg.addr = (u64)&data;
 
 	/* pstate = all interrupts masked */
diff --git a/arm/aarch64/kvm.c b/arm/aarch64/kvm.c
index 56a0aedc263d..764f1091ec87 100644
--- a/arm/aarch64/kvm.c
+++ b/arm/aarch64/kvm.c
@@ -3,8 +3,40 @@
 #include <asm/image.h>
 
 #include <linux/byteorder.h>
+#include <linux/cpumask.h>
+
 #include <kvm/util.h>
 
+int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset)
+{
+	struct kvm *kvm = opt->ptr;
+	const char *cpulist = arg;
+	cpumask_t *cpumask;
+	int cpu, ret;
+
+	kvm->cfg.arch.vcpu_affinity = cpulist;
+
+	cpumask = calloc(1, cpumask_size());
+	if (!cpumask)
+		die_perror("calloc");
+
+	ret = cpulist_parse(cpulist, cpumask);
+	if (ret) {
+		free(cpumask);
+		return ret;
+	}
+
+	kvm->arch.vcpu_affinity_cpuset = CPU_ALLOC(NR_CPUS);
+	if (!kvm->arch.vcpu_affinity_cpuset)
+		die_perror("CPU_ALLOC");
+	CPU_ZERO_S(CPU_ALLOC_SIZE(NR_CPUS), kvm->arch.vcpu_affinity_cpuset);
+
+	for_each_cpu(cpu, cpumask)
+		CPU_SET(cpu, kvm->arch.vcpu_affinity_cpuset);
+
+	return 0;
+}
+
 /*
  * Return the TEXT_OFFSET value that the guest kernel expects. Note
  * that pre-3.17 kernels expose this value using the native endianness
diff --git a/arm/aarch64/pmu.c b/arm/aarch64/pmu.c
index c0fc95ca01c4..3cf36d79414c 100644
--- a/arm/aarch64/pmu.c
+++ b/arm/aarch64/pmu.c
@@ -50,35 +50,20 @@ static void set_pmu_attr(struct kvm_cpu *vcpu, void *addr, u64 attr)
  */
 #define PMU_ID_MAXLEN		12
 
-/*
- * In the case of homogeneous systems, there only one hardware PMU, and all
- * VCPUs will use the same PMU, regardless of where the attribute gets set.
- *
- * For heterogeneous systems, the assumption is that the user has pinned the VM
- * (via taskset or similar) to a set of CPUs that share the same hardware PMU.
- * This simplifies things for kvmtool, as correctness is not affected by setting
- * the PMU for each VCPU from the main thread, instead of setting it from each
- * individual VCPU thread.
- */
-static int find_pmu(void)
+static int find_pmu_cpumask(struct kvm *kvm, cpumask_t *cpumask)
 {
+	cpumask_t pmu_cpumask, tmp;
 	char buf[PMU_ID_MAXLEN];
 	struct dirent *dirent;
 	char *cpulist, *path;
 	int pmu_id = -ENXIO;
 	unsigned long val;
-	cpumask_t cpumask;
 	ssize_t fd_sz;
-	int this_cpu;
 	int fd, ret;
 	DIR *dir;
 
 	memset(buf, 0, PMU_ID_MAXLEN);
 
-	this_cpu = sched_getcpu();
-	if (this_cpu < 0)
-		return -errno;
-
 	cpulist = calloc(1, PAGE_SIZE);
 	if (!cpulist)
 		return -ENOMEM;
@@ -114,15 +99,20 @@ static int find_pmu(void)
 		}
 		close(fd);
 
-		ret = cpulist_parse(cpulist, &cpumask);
+		ret = cpulist_parse(cpulist, &pmu_cpumask);
 		if (ret) {
 			pmu_id = ret;
 			goto out_free;
 		}
 
-		if (!cpumask_test_cpu(this_cpu, &cpumask))
+		if (!cpumask_and(&tmp, cpumask, &pmu_cpumask))
 			goto next_dir;
 
+		if (!cpumask_subset(cpumask, &pmu_cpumask)) {
+			die("Unable to find a PMU associated with CPUs %s",
+			    kvm->cfg.arch.vcpu_affinity);
+		}
+
 		strcpy(&path[strlen(path) - 4], "type");
 		fd = open(path, O_RDONLY);
 		if (fd < 0)
@@ -157,6 +147,46 @@ out_free_cpulist:
 	return pmu_id;
 }
 
+/*
+ * In the case of homogeneous systems, there only one hardware PMU, and all
+ * VCPUs will use the same PMU, regardless of the physical CPUs on which the
+ * VCPU threads will be executing.
+ *
+ * For heterogeneous systems, there are 2 ways for the user to ensure that the
+ * VM runs on CPUs that have the same PMU:
+ *
+ * 1. By pinning the entire VM to the desired CPUs, in which case kvmtool will
+ * choose the PMU associated with the CPU on which the main thread is executing
+ * (the thread that calls find_pmu()).
+ *
+ * 2. By setting the affinity mask for the VCPUs with the --vcpu-affinity
+ * command line argument. All CPUs in the affinity mask must have the same PMU,
+ * otherwise kvmtool will not be able to set a PMU.
+ */
+static int find_pmu(struct kvm *kvm)
+{
+	cpumask_t *cpumask;
+	int i, this_cpu;
+
+	cpumask = calloc(1, cpumask_size());
+	if (!cpumask)
+		die_perror("calloc");
+
+	if (!kvm->arch.vcpu_affinity_cpuset) {
+		this_cpu = sched_getcpu();
+		if (this_cpu < 0)
+			return -errno;
+		cpumask_set_cpu(this_cpu, cpumask);
+	} else {
+		for (i = 0; i < CPU_SETSIZE; i ++) {
+			if (CPU_ISSET(i, kvm->arch.vcpu_affinity_cpuset))
+				cpumask_set_cpu(i, cpumask);
+		}
+	}
+
+	return find_pmu_cpumask(kvm, cpumask);
+}
+
 void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 {
 	const char compatible[] = "arm,armv8-pmuv3";
@@ -177,7 +207,7 @@ void pmu__generate_fdt_nodes(void *fdt, struct kvm *kvm)
 		return;
 
 	if (pmu_has_attr(kvm->cpus[0], KVM_ARM_VCPU_PMU_V3_SET_PMU)) {
-		pmu_id = find_pmu();
+		pmu_id = find_pmu(kvm);
 		if (pmu_id < 0)
 			pr_debug("Failed to find a PMU (errno = %d)", -pmu_id);
 	}
diff --git a/arm/include/arm-common/kvm-arch.h b/arm/include/arm-common/kvm-arch.h
index c645ac001bca..b28beb0b06cf 100644
--- a/arm/include/arm-common/kvm-arch.h
+++ b/arm/include/arm-common/kvm-arch.h
@@ -2,6 +2,11 @@
 #define ARM_COMMON__KVM_ARCH_H
 
 #include <stdbool.h>
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <sched.h>
+
 #include <linux/const.h>
 #include <linux/types.h>
 
@@ -101,6 +106,8 @@ struct kvm_arch {
 	u64	initrd_guest_start;
 	u64	initrd_size;
 	u64	dtb_guest_start;
+
+	cpu_set_t *vcpu_affinity_cpuset;
 };
 
 #endif /* ARM_COMMON__KVM_ARCH_H */
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 5734c46ab9e6..d2de3b0892f2 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -12,6 +12,7 @@ struct kvm_config_arch {
 	u64		kaslr_seed;
 	enum irqchip_type irqchip;
 	u64		fw_addr;
+	const char	*vcpu_affinity;
 };
 
 int irqchip_parser(const struct option *opt, const char *arg, int unset);
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 19aff92bdb5b..f53d453c3e7d 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -11,6 +11,11 @@ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 
 #define cpumask_bits(maskp)	((maskp)->bits)
 
+static inline unsigned int cpumask_size(void)
+{
+	return BITS_TO_LONGS(NR_CPUS) * sizeof(long);
+}
+
 static inline void cpumask_set_cpu(int cpu, cpumask_t *dstp)
 {
 	set_bit(cpu, cpumask_bits(dstp));
-- 
2.31.1



From james.morse at arm.com  Thu Jan 27 08:21:24 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 16:21:24 +0000
Subject: [PATCH 0/3] arm64: insn: Generate 64 bit mask immediates correctly
Message-ID: <20220127162127.2391947-1-james.morse@arm.com>

Hello,

aarch64_insn_gen_logical_immediate() is generating the wrong code if
it is handed a 64bit immediate which has a single span of 1s (i.e. a
mask), with bit 63 set, and 0s in the remaining upper 32 bits.
Clear as mud. An example always helps: 0x800000003fffffff would be wrongly
encoded, but 0x000000003fffffff is unaffected.

It would appear eBPF is unable to hit these cases, as build_insn()'s
imm value is a s32, so when used with BPF_ALU64, the sign-extended
u64 immediate would always have all-1s or all-0s in the upper 32 bits.

KVM does not generate a va_mask with any of the top bits set as these
VA wouldn't be usable with TTBR0_EL2.

Patch 3 fixes it, and doesn't depend on the rest of the series.

As the instruction encoder is a source of headaches, the first two patches
add tests to help illustrate there is a problem, and that patch 3 fixes it.

The tests generate a header file of the expected values so it can be compared
against other sources of the same information. Objdump can be used to check
the header file is generated correctly. Embedding the code in gen_logic_imm in
test_insn.c would give less confidence that the encoder is doing the right thing.

This series is based on v5.17-rc1, and can be retrieved from:
https://git.gitlab.arm.com/linux-arm/linux-jm.git insn_encoder/fls_bug/v1

Thanks,

James Morse (3):
  arm64: selftests: Generate all the possible logical immediates as a
    header
  arm64: insn: Add tests for aarch64_insn_gen_logical_immediate()
  arm64: insn: Generate 64 bit mask immediates correctly

 arch/arm64/Kconfig.debug                   |   3 +
 arch/arm64/Makefile                        |   3 +
 arch/arm64/lib/Makefile                    |   2 +
 arch/arm64/lib/insn.c                      |   5 +-
 arch/arm64/lib/test_insn.c                 |  90 ++++++++++
 arch/arm64/tools/.gitignore                |   2 +
 arch/arm64/tools/Makefile                  |  12 +-
 arch/arm64/tools/gen_logic_imm.c           | 190 +++++++++++++++++++++
 tools/testing/selftests/arm64/Makefile     |   2 +-
 tools/testing/selftests/arm64/lib/Makefile |   6 +
 tools/testing/selftests/arm64/lib/config   |   1 +
 tools/testing/selftests/arm64/lib/insn.sh  |   5 +
 12 files changed, 318 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm64/lib/test_insn.c
 create mode 100644 arch/arm64/tools/.gitignore
 create mode 100644 arch/arm64/tools/gen_logic_imm.c
 create mode 100644 tools/testing/selftests/arm64/lib/Makefile
 create mode 100644 tools/testing/selftests/arm64/lib/config
 create mode 100755 tools/testing/selftests/arm64/lib/insn.sh

-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 08:21:25 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 16:21:25 +0000
Subject: [PATCH 1/3] arm64: selftests: Generate all the possible logical
 immediates as a header
In-Reply-To: <20220127162127.2391947-1-james.morse@arm.com>
References: <20220127162127.2391947-1-james.morse@arm.com>
Message-ID: <20220127162127.2391947-2-james.morse@arm.com>

Aarch64 has instructions to generate reasonably complicated 32 or 64
bit masks from only 13 bits of information. To test the in-kernel code
that spots the pattern to produce the instruction encoding a golden set
of values is needed.

A header file containing these is large. Instead, generate every possible
instruction encoding, and its decoded immediate, based on the arm-arm's
DecodeBitMasks() pseudocode. These are output in a format that can be used
in a header file for the test.

Having the golden values in a header file allows them to be inspected,
and checked against a trusted source. The generation program can be told
to pass each value through objdump and compared.

Unsat's jitterbug project has a python script that does this too, but
the license isn't clear from the github repository.

Link: https://lore.kernel.org/linux-arm-kernel/CAB-e3NRCJ_4+vkFPkMN67DwBBtO=sJw>
CC: Luke Nelson <luke.r.nels at gmail.com>
Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/Makefile              |   1 +
 arch/arm64/tools/.gitignore      |   2 +
 arch/arm64/tools/Makefile        |  12 +-
 arch/arm64/tools/gen_logic_imm.c | 190 +++++++++++++++++++++++++++++++
 4 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/tools/.gitignore
 create mode 100644 arch/arm64/tools/gen_logic_imm.c

diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 2f1de88651e6..0bd590605416 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -176,6 +176,7 @@ vdso_install:
 
 archprepare:
 	$(Q)$(MAKE) $(build)=arch/arm64/tools kapi
+	$(Q)$(MAKE) $(build)=arch/arm64/tools tests
 ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
   ifneq ($(CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419),y)
 	@echo "warning: ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum" >&2
diff --git a/arch/arm64/tools/.gitignore b/arch/arm64/tools/.gitignore
new file mode 100644
index 000000000000..6ee79cdac729
--- /dev/null
+++ b/arch/arm64/tools/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+gen_logic_imm
diff --git a/arch/arm64/tools/Makefile b/arch/arm64/tools/Makefile
index 932b4fe5c768..ce44b531fba7 100644
--- a/arch/arm64/tools/Makefile
+++ b/arch/arm64/tools/Makefile
@@ -4,10 +4,11 @@ gen := arch/$(ARCH)/include/generated
 kapi := $(gen)/asm
 
 kapi-hdrs-y := $(kapi)/cpucaps.h
+tests-hdrs-y := $(kapi)/test_logic_imm_generated.h
 
 targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y))
 
-PHONY += kapi
+PHONY += kapi tests
 
 kapi:   $(kapi-hdrs-y) $(gen-y)
 
@@ -20,3 +21,12 @@ quiet_cmd_gen_cpucaps = GEN     $@
 
 $(kapi)/cpucaps.h: $(src)/gen-cpucaps.awk $(src)/cpucaps FORCE
 	$(call if_changed,gen_cpucaps)
+
+tests:	$(tests-hdrs-y) $(gen-y)
+
+quiet_cmd_build_gen_logic_imm = GEN     $@
+      cmd_build_gen_logic_imm = $(obj)/gen_logic_imm > $@
+
+hostprogs := gen_logic_imm
+$(kapi)/test_logic_imm_generated.h: $(obj)/gen_logic_imm FORCE
+	$(call if_changed,build_gen_logic_imm)
diff --git a/arch/arm64/tools/gen_logic_imm.c b/arch/arm64/tools/gen_logic_imm.c
new file mode 100644
index 000000000000..42ac83a33823
--- /dev/null
+++ b/arch/arm64/tools/gen_logic_imm.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2021 ARM Limited */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+static u64 gen_mask(u32 num_bits)
+{
+	if (num_bits == 64)
+		return ~0ULL;
+
+	return (1ULL<<num_bits) - 1;
+}
+
+static u64 ror(u64 bits, u64 count, u64 esize)
+{
+	u64 ret;
+	u64 bottom_bits = bits & gen_mask(count);
+
+	if (!count)
+		return bits;
+
+	ret = bottom_bits << (esize - count) | (bits >> count);
+
+	return ret;
+}
+
+static u64 replicate(u64 bits, u32 esize)
+{
+	int i;
+	u64 ret = 0;
+
+	bits &= gen_mask(esize);
+	for (i = 0; i < 64; i += esize)
+		ret |= (u64)bits << i;
+
+	return ret;
+}
+
+static u32 fls(u32 x)
+{
+	/* If x is 0, the result is undefined */
+	if (!x)
+		return 32;
+
+	return 32 - __builtin_clz(x);
+}
+
+#define PIPE_READ	0
+#define PIPE_WRITE	1
+/*
+ * Use objdump to decode the encoded instruction, and compare the immediate.
+ * On error, returns the bad instruction, otherwise returns 0.
+ */
+static int validate(u64 val, u32 immN, u32 imms, u32 immr, char *objdump)
+{
+	pid_t child;
+	char *immediate;
+	char val_str[32];
+	u32 insn = 0x12000000;
+	char output[1024] = {0};
+	int fd, pipefd[2], bytes;
+	char filename[] = "validate_gen_logic_imm.XXXXXX";
+
+	insn |= 1 << 31;
+	insn |= (immN & 0x1)<<22;
+	insn |= (immr & 0x3f)<<16;
+	insn |= (imms & 0x3f)<<10;
+
+	fd = mkstemp(filename);
+	if (fd < 0)
+		abort();
+
+	write(fd, &insn, sizeof(insn));
+	close(fd);
+
+	if (pipe(pipefd))
+		return 0;
+
+	child = vfork();
+	if (child) {
+		close(pipefd[PIPE_WRITE]);
+		waitpid(child, NULL, 0);
+
+		bytes = read(pipefd[PIPE_READ], output, sizeof(output));
+		close(pipefd[PIPE_READ]);
+		if (!bytes || bytes == sizeof(output))
+			return insn;
+
+		immediate = strstr(output, "x0, x0, #");
+		if (!immediate)
+			return insn;
+		immediate += strlen("x0, x0, #");
+
+		/*
+		 * strtoll() has its own ideas about overflow and underflow.
+		 * Do a string comparison. immediate ends in a newline.
+		 */
+		snprintf(val_str, sizeof(val_str), "0x%lx", val);
+		if (strncmp(val_str, immediate, strlen(val_str))) {
+			fprintf(stderr, "Unexpected decode from objdump: %s\n",
+				immediate);
+			return insn;
+		}
+	} else {
+		close(pipefd[PIPE_READ]);
+		close(1);
+		dup2(pipefd[PIPE_WRITE], 1);
+		execl(objdump, objdump, "-b", "binary", "-m", "aarch64", "-D",
+		      filename, (char *) NULL);
+		abort();
+	}
+
+	unlink(filename);
+	return 0;
+}
+
+static int decode_bit_masks(u32 immN, u32 imms, u32 immr, char *objdump)
+{
+	u32 esize, len, S, R;
+	u64 levels, welem, wmask;
+
+	imms &= 0x3f;
+	immr &= 0x3f;
+
+	len = fls((immN << 6) | (~imms & 0x3f));
+	if (!len || len > 7)
+		return 0;
+
+	esize = 1 << (len - 1);
+	levels = gen_mask(len);
+	S = imms & levels;
+	if (S + 1 >= esize)
+		return 0;
+	R = immr & levels;
+	if (immr >= esize)
+		return 0;
+
+	welem = gen_mask(S + 1);
+	wmask = replicate(ror(welem, R, esize), esize);
+
+	printf("\t{0x%.16lx, %u, %2u, %2u},\n", wmask, immN, immr, imms);
+
+	if (objdump) {
+		u32 bad_insn = validate(wmask, immN, imms, immr, objdump);
+
+		if (bad_insn) {
+			fprintf(stderr,
+				"Failed to validate encoding of 0x%.16lx as 0x%x\n",
+				wmask, bad_insn);
+			exit(1);
+		}
+	}
+
+	return 1;
+}
+
+int main(int argc, char **argv)
+{
+	u32 immN, imms, immr, count = 0;
+	char *objdump = NULL;
+
+	if (argc > 2) {
+		fprintf(stderr, "Usage: %s [/path/to/objdump]\n", argv[0]);
+		exit(0);
+	} else if (argc == 2) {
+		objdump = argv[1];
+	}
+
+	for (immN = 0; immN <= 1; immN++) {
+		for (imms = 0; imms <= 0x3f; imms++) {
+			for (immr = 0; immr <= 0x3f; immr++)
+				count += decode_bit_masks(immN, imms, immr, objdump);
+		}
+	}
+
+	if (count != 5334) {
+		printf("#error Wrong number of encodings generated.\n");
+		exit(1);
+	}
+
+	return 0;
+}
-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 08:21:26 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 16:21:26 +0000
Subject: [PATCH 2/3] arm64: insn: Add tests for
 aarch64_insn_gen_logical_immediate()
In-Reply-To: <20220127162127.2391947-1-james.morse@arm.com>
References: <20220127162127.2391947-1-james.morse@arm.com>
Message-ID: <20220127162127.2391947-3-james.morse@arm.com>

Aarch64 has instructions to generate reasonably complicated 32 or 64
bit masks from only 13 bits of information.
aarch64_insn_gen_logical_immediate() has to created the immediate
encoding by spotting the patterns in the 32 or 64 bit immediate.

Despite attempts to validate or model this code, or use it as-is outside
the kernel tree, bugs still exist.

Add a self test module that tests this code in place against a golden
set of values.

Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/Kconfig.debug                   |  3 +
 arch/arm64/Makefile                        |  2 +
 arch/arm64/lib/Makefile                    |  2 +
 arch/arm64/lib/insn.c                      |  3 +
 arch/arm64/lib/test_insn.c                 | 90 ++++++++++++++++++++++
 tools/testing/selftests/arm64/Makefile     |  2 +-
 tools/testing/selftests/arm64/lib/Makefile |  6 ++
 tools/testing/selftests/arm64/lib/config   |  1 +
 tools/testing/selftests/arm64/lib/insn.sh  |  5 ++
 9 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/lib/test_insn.c
 create mode 100644 tools/testing/selftests/arm64/lib/Makefile
 create mode 100644 tools/testing/selftests/arm64/lib/config
 create mode 100755 tools/testing/selftests/arm64/lib/insn.sh

diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index 265c4461031f..10df6056db3e 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -20,4 +20,7 @@ config ARM64_RELOC_TEST
 	depends on m
 	tristate "Relocation testing module"
 
+config TEST_INSN
+	tristate "Test functions located in the aarch64 instruction encoder at runtime"
+
 source "drivers/hwtracing/coresight/Kconfig"
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index 0bd590605416..4930a2b077b8 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -176,7 +176,9 @@ vdso_install:
 
 archprepare:
 	$(Q)$(MAKE) $(build)=arch/arm64/tools kapi
+#ifdef CONFIG_TEST_INSN
 	$(Q)$(MAKE) $(build)=arch/arm64/tools tests
+#endif
 ifeq ($(CONFIG_ARM64_ERRATUM_843419),y)
   ifneq ($(CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419),y)
 	@echo "warning: ld does not support --fix-cortex-a53-843419; kernel may be susceptible to erratum" >&2
diff --git a/arch/arm64/lib/Makefile b/arch/arm64/lib/Makefile
index 29490be2546b..d180945ecc22 100644
--- a/arch/arm64/lib/Makefile
+++ b/arch/arm64/lib/Makefile
@@ -22,3 +22,5 @@ obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
 obj-$(CONFIG_ARM64_MTE) += mte.o
 
 obj-$(CONFIG_KASAN_SW_TAGS) += kasan_sw_tags.o
+
+obj-$(CONFIG_TEST_INSN) += test_insn.o
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index fccfe363e567..8888e407032f 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -193,6 +193,7 @@ u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn)
 
 	return (insn >> shift) & mask;
 }
+EXPORT_SYMBOL_GPL(aarch64_insn_decode_immediate);
 
 u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
 				  u32 insn, u64 imm)
@@ -256,6 +257,7 @@ u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
 
 	return (insn >> shift) & GENMASK(4, 0);
 }
+EXPORT_SYMBOL_GPL(aarch64_insn_decode_register);
 
 static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
 					u32 insn,
@@ -1424,6 +1426,7 @@ u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type,
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
 	return aarch64_encode_immediate(imm, variant, insn);
 }
+EXPORT_SYMBOL_GPL(aarch64_insn_gen_logical_immediate);
 
 u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
 			  enum aarch64_insn_register Rm,
diff --git a/arch/arm64/lib/test_insn.c b/arch/arm64/lib/test_insn.c
new file mode 100644
index 000000000000..41466f61c6c0
--- /dev/null
+++ b/arch/arm64/lib/test_insn.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for the aarch64 insn encoder.
+ *
+ * Copyright (C) 2021 ARM Limited.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+
+#include <asm/debug-monitors.h>
+#include <asm/insn.h>
+
+#include "../../../tools/testing/selftests/kselftest_module.h"
+
+struct bitmask_test_case {
+	/* input */
+	u64 imm;
+
+	/* expected output */
+	u64 n, immr, imms;
+};
+struct bitmask_test_case aarch64_logic_imm_test[] = {
+#include <asm/test_logic_imm_generated.h>
+};
+
+KSTM_MODULE_GLOBALS();
+
+static void __init test_logic_imm(void)
+{
+	int i;
+	u8 rd, rn;
+	u32 insn;
+
+	for (i = 0; i < ARRAY_SIZE(aarch64_logic_imm_test); i++) {
+		total_tests++;
+
+		rd = i % 30;
+		rn = (i + 1) % 30;
+
+		insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_AND,
+							  AARCH64_INSN_VARIANT_64BIT,
+							  rn, rd, aarch64_logic_imm_test[i].imm);
+
+		if (!aarch64_insn_is_and_imm(insn) ||
+		    rd != aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RD, insn) ||
+		    rn != aarch64_insn_decode_register(AARCH64_INSN_REGTYPE_RN, insn) ||
+		    aarch64_logic_imm_test[i].imms != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_S, insn) ||
+		    aarch64_logic_imm_test[i].immr != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_R, insn) ||
+		    aarch64_logic_imm_test[i].n != aarch64_insn_decode_immediate(AARCH64_INSN_IMM_N, insn)) {
+			failed_tests++;
+			pr_warn_once("[%s:%u] Failed to encode immediate 0x%llx (got insn 0x%x))\n",
+				     __FILE__, __LINE__, aarch64_logic_imm_test[i].imm, insn);
+			continue;
+		}
+	}
+}
+
+static void __init do_test_bad_logic_imm(u64 imm, enum aarch64_insn_variant var)
+{
+	u32 insn;
+
+	total_tests++;
+	insn = aarch64_insn_gen_logical_immediate(AARCH64_INSN_LOGIC_AND,
+						  var, 0, 0, imm);
+	if (insn != AARCH64_BREAK_FAULT)
+		failed_tests++;
+}
+
+static void __init test_bad_logic_imm(void)
+{
+	do_test_bad_logic_imm(0, AARCH64_INSN_VARIANT_64BIT);
+	do_test_bad_logic_imm(0x1234, AARCH64_INSN_VARIANT_64BIT);
+	do_test_bad_logic_imm(0xffffffffffffffff, AARCH64_INSN_VARIANT_64BIT);
+	do_test_bad_logic_imm((1ULL<<32), AARCH64_INSN_VARIANT_32BIT);
+}
+
+static void __init selftest(void)
+{
+	test_logic_imm();
+	test_bad_logic_imm();
+}
+
+KSTM_MODULE_LOADERS(test_insn);
+MODULE_AUTHOR("James Morse <james.morse at arm.com>");
+MODULE_LICENSE("GPL");
diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
index 1e8d9a8f59df..2c59e7d40524 100644
--- a/tools/testing/selftests/arm64/Makefile
+++ b/tools/testing/selftests/arm64/Makefile
@@ -4,7 +4,7 @@
 ARCH ?= $(shell uname -m 2>/dev/null || echo not)
 
 ifneq (,$(filter $(ARCH),aarch64 arm64))
-ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi
+ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi lib
 else
 ARM64_SUBTARGETS :=
 endif
diff --git a/tools/testing/selftests/arm64/lib/Makefile b/tools/testing/selftests/arm64/lib/Makefile
new file mode 100644
index 000000000000..5ed92a5135ce
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/Makefile
@@ -0,0 +1,6 @@
+# Copyright (C) 2022 ARM Limited
+# Makefile for arm64/lib/ function selftests
+
+TEST_PROGS := insn.sh
+
+include ../../lib.mk
diff --git a/tools/testing/selftests/arm64/lib/config b/tools/testing/selftests/arm64/lib/config
new file mode 100644
index 000000000000..cb982478782b
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/config
@@ -0,0 +1 @@
+CONFIG_TEST_INSN=m
diff --git a/tools/testing/selftests/arm64/lib/insn.sh b/tools/testing/selftests/arm64/lib/insn.sh
new file mode 100755
index 000000000000..3d893b1a0069
--- /dev/null
+++ b/tools/testing/selftests/arm64/lib/insn.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# Tests the aarch64 instruction generation infrastructure using test_insn
+# kernel module.
+$(dirname $0)/../../kselftest/module.sh "insn" test_insn
-- 
2.30.2



From james.morse at arm.com  Thu Jan 27 08:21:27 2022
From: james.morse at arm.com (James Morse)
Date: Thu, 27 Jan 2022 16:21:27 +0000
Subject: [PATCH 3/3] arm64: insn: Generate 64 bit mask immediates correctly
In-Reply-To: <20220127162127.2391947-1-james.morse@arm.com>
References: <20220127162127.2391947-1-james.morse@arm.com>
Message-ID: <20220127162127.2391947-4-james.morse@arm.com>

When the insn framework is used to encode an AND/ORR/EOR instruction,
aarch64_encode_immediate() is used to pick the immr imms values.

If the immediate is a 64bit mask, with bit 63 set, and zeros in any
of the upper 32 bits, the immr value is incorrectly calculated meaning
the wrong mask is generated.
For example, 0x8000000000000001 should have an immr of 1, but 32 is used,
meaning the resulting mask is 0x0000000300000000.

It would appear eBPF is unable to hit these cases, as build_insn()'s
imm value is a s32, so when used with BPF_ALU64, the sign-extended
u64 immediate would always have all-1s or all-0s in the upper 32 bits.

KVM does not generate a va_mask with any of the top bits set as these
VA wouldn't be usable with TTBR0_EL2.

This happens because the rotation is calculated from fls(~imm), which
takes an unsigned int, but the immediate may be 64bit.

Use fls64() so the 64bit mask doesn't get truncated to a u32.

Signed-off-by: James Morse <james.morse at arm.com>
---
 arch/arm64/lib/insn.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index 8888e407032f..90253af7e294 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -1381,7 +1381,7 @@ static u32 aarch64_encode_immediate(u64 imm,
 		 * Compute the rotation to get a continuous set of
 		 * ones, with the first bit set at position 0
 		 */
-		ror = fls(~imm);
+		ror = fls64(~imm);
 	}
 
 	/*
-- 
2.30.2



From jbrunet at baylibre.com  Thu Jan 27 08:20:49 2022
From: jbrunet at baylibre.com (Jerome Brunet)
Date: Thu, 27 Jan 2022 17:20:49 +0100
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
In-Reply-To: <CAL_JsqL77E+5ftqgHPdWQzfp98Oh3d=QZRQ8Z6v91OfSeprxig@mail.gmail.com>
References: <20220126231427.1638089-1-robh@kernel.org>
 <1jtudp1rc1.fsf@starbuckisacylon.baylibre.com>
 <CAL_JsqL77E+5ftqgHPdWQzfp98Oh3d=QZRQ8Z6v91OfSeprxig@mail.gmail.com>
Message-ID: <1jlez1172f.fsf@starbuckisacylon.baylibre.com>


On Thu 27 Jan 2022 at 08:35, Rob Herring <robh at kernel.org> wrote:

> On Thu, Jan 27, 2022 at 3:05 AM Jerome Brunet <jbrunet at baylibre.com> wrote:
>>
>>
>> On Wed 26 Jan 2022 at 17:14, Rob Herring <robh at kernel.org> wrote:
>>
>> > 'sound-dai' is a common property, but has duplicate type definitions.
>> > Create a new common definition to define the type and then update all
>> > the other occurrences to just define how many entries there are just
>> > like other phandle+arg properties.
>> >
>> > The constraints on the number of entries is based on the examples and
>> > could be wrong.
>> >
>> > Cc: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> > Signed-off-by: Rob Herring <robh at kernel.org>
>> > ---
>> > Please ack, this depends on commit abf0fee97313 ("dt-bindings: Improve
>> > phandle-array schemas") in my tree.
>> > ---
>> >  .../bindings/sound/amlogic,gx-sound-card.yaml |  4 ++--
>> >  .../bindings/sound/google,sc7180-trogdor.yaml |  6 ++++--
>> >  .../bindings/sound/imx-audio-card.yaml        |  7 +++++--
>> >  .../bindings/sound/qcom,sm8250.yaml           | 10 +++++++---
>> >  .../bindings/sound/samsung,aries-wm8994.yaml  |  5 +----
>> >  .../bindings/sound/samsung,midas-audio.yaml   |  2 --
>> >  .../bindings/sound/samsung,odroid.yaml        |  9 +++------
>> >  .../devicetree/bindings/sound/sound-dai.yaml  | 20 +++++++++++++++++++
>> >  8 files changed, 42 insertions(+), 21 deletions(-)
>> >  create mode 100644 Documentation/devicetree/bindings/sound/sound-dai.yaml
>> >
>> > diff --git a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
>> > index 2e35aeaa8781..8b5be4b92f35 100644
>> > --- a/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
>> > +++ b/Documentation/devicetree/bindings/sound/amlogic,gx-sound-card.yaml
>> > @@ -57,7 +57,7 @@ patternProperties:
>> >            rate
>> >
>> >        sound-dai:
>> > -        $ref: /schemas/types.yaml#/definitions/phandle-array
>> > +        maxItems: 1
>> >          description: phandle of the CPU DAI
>> >
>> >      patternProperties:
>> > @@ -71,7 +71,7 @@ patternProperties:
>> >
>> >          properties:
>> >            sound-dai:
>> > -            $ref: /schemas/types.yaml#/definitions/phandle-array
>> > +            maxItems: 1
>>
>> No min or max here. Links may have more than one codec.
>>
>> Ex:
>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts#n158
>
> What do you mean? Every 'sound-dai' there only has 1 phande+args. Each
> codec is a child node.

Yes it is a child - sorry I misunderstood.
I thought the MaxItems: 1 would limit the number of codecs

For the amlogic part:
Acked-by: Jerome Brunet <jbrunet at baylibre.com>

>
> Rob



From stefan.wahren at i2se.com  Thu Jan 27 08:31:50 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Thu, 27 Jan 2022 17:31:50 +0100
Subject: DTB backward/forward compatibility with "pinctrl: bcm2835: Change
 init order for gpio hogs"
In-Reply-To: <e1f1dcec-3cfb-8f7f-f3de-04c586ee30d9@gmail.com>
References: <6d6e5db3-8377-9389-6fb7-1f738a1c1b6e@gmail.com>
 <c04d26a5-16e9-44a7-8b75-a04df9f7bfb6@raspberrypi.com>
 <63cecd52-6808-d31e-3eb6-a17e692a4190@gmail.com>
 <e1f1dcec-3cfb-8f7f-f3de-04c586ee30d9@gmail.com>
Message-ID: <d26d1a31-8644-94c2-b1e4-c5d30979cdd5@i2se.com>

Hi,

Am 26.01.22 um 02:33 schrieb Florian Fainelli:
>
>
> On 1/25/2022 11:58 AM, Florian Fainelli wrote:
>>
>>
>> On 1/25/2022 11:48 AM, Phil Elwell wrote:
>>> Florian,
>>>
>>> On 25/01/2022 19:39, Florian Fainelli wrote:
>>>> Hi,
>>>>
>>>> I am a bit frustrated by this commit, we picked it up via the
>>>> stable 5.10 and 5.15 trees into our downstream tree, and in the
>>>> absence of a suitable 'gpio-ranges' property for the GPIO
>>>> controller, the SPI controller keeps getting -EPROBE_DEFER for its
>>>> chip select. If the property is present, then all is well.
>>>>
>>>> Now the problem in my case is that the boot loader is responsible
>>>> for providing the DTB to the kernel, and until recently, we did not
>>>> update it to contain a suitable 'gpio-ranges' property. Now that it
>>>> has been updated however, older kernels which *do not* have said
>>>> change in the subject are also getting -EPROBE_DEFER for the SPI
>>>> chip select.
>>>>
>>>> So this is just breaking backward/forward compatibility with the
>>>> DTB unless both are updated in lock steps which is *extremely*
>>>> inconvenient.
>>>>
>>>> This is death by a thousand cuts.
>>>>
>>>> So how do we remedy this?
>>>
>>> It's unfortunate that both the DTS and driver were incorrect, and
>>> that the fixes were inter-dependent. At Raspberry Pi we make a point
>>> of treating the DTBs as part of the kernel, updating them at the
>>> same time. Is that not possible in your situation? You don't specify
>>> which bootloader you are using (or even which platform), but U-boot
>>> can be configured to use the DTB loaded and adjusted by the firmware.
>>
>> We use a boot loader called BOLT which has an offline DTS generation
>> part an a runtime patching part. At no point in time has it been
>> necessary, desirable or even reliably possible to look at the kernel
>> version and mangle the Device Tree such that "things" work. I do not
>> even want to fathom what the code doing that would look like other
>> than a big pile of mess. This is utterly error prone and completely
>> breaks the boot loader/kernel abstraction.
>>
>> We strive to be able to update the boot loader and the kernel
>> seemingly independently from one another even though obviously there
>> are times where locksteps are necessary. What I like to do is:
>>
>> - put the changes in the DTB that are necessary for a *future* kernel
>> well in advance such that by the time that newer kernel gets used
>> these properties are already there
>>
>> - adding new properties does not break older kernels, they simply
>> ignore them
>>
>> And this allows us to define a combination that always works while
>> having a sliding window of backward/forward compatibility if we have
>> locksteps in between.
>>
>> I can make changes in the downstream kernel such that we prune DT
>> properties, but once we open that door, the list goes on and on and
>> it is just a damage control strategy anyway.
>>
>> Why cannot the pinctrl framework infer that we have a 1:1 mapping in
>> the absence of a 'gpio-ranges' property, but instead does the following:
>>
>> # cat
>> /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
>> GPIO ranges handled:
>> 0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
the driver init the gpio base with -1 which seems to lead to this huge
unsigned integer. Very confusing from my PoV.
>> #
>>
>> clearly it determined the end GPIO but it is not able to determine
>> the start GPIO?
>>
>> And now, on a 5.10 kernel which does contain both the 'gpio-ranges'
>> property and the said change to pinctrl-bcm2835.c I have this:
>>
>> # cat
>> /sys/kernel/debug/pinctrl/47e200000.gpio-pinctrl-bcm2711/gpio-ranges
>> GPIO ranges handled:
>> 0: pinctrl-bcm2711 GPIOS [4294967295 - 56] PINS [0 - 57]
>> 0: pinctrl-bcm2711 GPIOS [454 - 511] PINS [0 - 57]
>> #
>>
>> What the heck?
>
> And just to be clear, at this point I understand that the old kernel,
> new DTB/DTS is not something we can obviously fix, however new kernel
> old DTB/DTS *without* 'gpio-ranges' is something that should still
> work to ease the pain.

The whole problem started with make an optional DT property a required
one afterwards.

The only workaround i can think of is to check for the absence of
'gpio-ranges' in the pinctrl driver and mitigate. Not nice :(

>
> I will dig more into why we have this duplicated debugfs output (most
> likely we are not unwinding an error path when we get -EPROBE_DEFER)
> and also why pinctrl is not able to figure out the gpio start properly
> without 'gpio-ranges'.


From michael at walle.cc  Thu Jan 27 08:37:25 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:37:25 +0100
Subject: [PATCH v1 0/3] nvmem: add Layerscape SFP support
Message-ID: <20220127163728.3650648-1-michael@walle.cc>

Add support for the Security Fuse Processor found on Layerscape
SoCs.

Michael Walle (3):
  dt-bindings: nvmem: add fsl,layerscape-sfp binding
  nvmem: add driver for Layerscape SFP (Security Fuse Processor)
  arm64: dts: ls1028a: add efuse node

 .../bindings/nvmem/fsl,layerscape-sfp.yaml    | 38 ++++++++
 .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 11 +++
 drivers/nvmem/Kconfig                         | 12 +++
 drivers/nvmem/Makefile                        |  2 +
 drivers/nvmem/layerscape-sfp.c                | 91 +++++++++++++++++++
 5 files changed, 154 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml
 create mode 100644 drivers/nvmem/layerscape-sfp.c

-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:37:26 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:37:26 +0100
Subject: [PATCH v1 1/3] dt-bindings: nvmem: add fsl,layerscape-sfp binding
In-Reply-To: <20220127163728.3650648-1-michael@walle.cc>
References: <20220127163728.3650648-1-michael@walle.cc>
Message-ID: <20220127163728.3650648-2-michael@walle.cc>

The Security Fuse Processor provides efuses and is responsible for
reading it at SoC startup and configuring it accordingly.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 .../bindings/nvmem/fsl,layerscape-sfp.yaml    | 38 +++++++++++++++++++
 1 file changed, 38 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml b/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml
new file mode 100644
index 000000000000..80914b93638e
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/fsl,layerscape-sfp.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/fsl,layerscape-sfp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale Layerscape Security Fuse Processor
+
+maintainers:
+  - Michael Walle <michael at walle.cc>
+
+description: |
+  SFP is the security fuse processor which among other things provide a
+  unique identifier per part.
+
+allOf:
+  - $ref: "nvmem.yaml#"
+
+properties:
+  compatible:
+    enum:
+      - fsl,ls1028a-sfp
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    efuse at 1e80000 {
+        compatible = "fsl,ls1028a-sfp";
+        reg = <0x1e80000 0x8000>;
+    };
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:37:28 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:37:28 +0100
Subject: [PATCH v1 3/3] arm64: dts: ls1028a: add efuse node
In-Reply-To: <20220127163728.3650648-1-michael@walle.cc>
References: <20220127163728.3650648-1-michael@walle.cc>
Message-ID: <20220127163728.3650648-4-michael@walle.cc>

Layerscape SoCs contain a Security Fuse Processor which is basically a
efuse controller. Add the node, so userspace can read the efuses.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
index 7d44102d9c6c..4b248cee830a 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -224,6 +224,17 @@ rst: syscon at 1e60000 {
 			little-endian;
 		};
 
+		efuse at 1e80000 {
+			compatible = "fsl,ls1028a-sfp";
+			reg = <0x0 0x1e80000 0x0 0x10000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			ls1028a_uid: unique-id at 1c {
+				reg = <0x1c 0x8>;
+			};
+		};
+
 		scfg: syscon at 1fc0000 {
 			compatible = "fsl,ls1028a-scfg", "syscon";
 			reg = <0x0 0x1fc0000 0x0 0x10000>;
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:37:27 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:37:27 +0100
Subject: [PATCH v1 2/3] nvmem: add driver for Layerscape SFP (Security Fuse
 Processor)
In-Reply-To: <20220127163728.3650648-1-michael@walle.cc>
References: <20220127163728.3650648-1-michael@walle.cc>
Message-ID: <20220127163728.3650648-3-michael@walle.cc>

Add support for the Security Fuse Processor found on Layerscape SoCs.
This driver implements basic read access.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/nvmem/Kconfig          | 12 +++++
 drivers/nvmem/Makefile         |  2 +
 drivers/nvmem/layerscape-sfp.c | 91 ++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+)
 create mode 100644 drivers/nvmem/layerscape-sfp.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 94dd60b2654e..63792082e476 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -307,4 +307,16 @@ config NVMEM_BRCM_NVRAM
 	  This driver provides support for Broadcom's NVRAM that can be accessed
 	  using I/O mapping.
 
+config NVMEM_LAYERSCAPE_SFP
+	tristate "Layerscape SFP (Security Fuse Processor) support"
+	depends on ARCH_LAYERSCAPE || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This driver provides support to read the eFuses on Freescale
+	  Layerscape SoC's. For example, the vendor provides a per part
+	  unique ID there.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called layerscape-sfp.
+
 endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 4e6d877fdfaf..914358fcdb37 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -62,3 +62,5 @@ obj-$(CONFIG_NVMEM_RMEM) 	+= nvmem-rmem.o
 nvmem-rmem-y			:= rmem.o
 obj-$(CONFIG_NVMEM_BRCM_NVRAM)	+= nvmem_brcm_nvram.o
 nvmem_brcm_nvram-y		:= brcm_nvram.o
+obj-$(CONFIG_NVMEM_LAYERSCAPE_SFP)	+= nvmem-layerscape-sfp.o
+nvmem-layerscape-sfp-y		:= layerscape-sfp.o
diff --git a/drivers/nvmem/layerscape-sfp.c b/drivers/nvmem/layerscape-sfp.c
new file mode 100644
index 000000000000..4aa94e03d8d1
--- /dev/null
+++ b/drivers/nvmem/layerscape-sfp.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Layerscape SFP driver
+ *
+ * Copyright (c) 2022 Michael Walle <michael at walle.cc>
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#define LAYERSCAPE_SFP_OTP_OFFSET	0x0200
+
+struct layerscape_sfp_priv {
+	void __iomem *base;
+};
+
+struct layerscape_sfp_data {
+	int size;
+};
+
+static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
+			size_t bytes)
+{
+	struct layerscape_sfp_priv *priv = context;
+
+	memcpy_fromio(val, priv->base + LAYERSCAPE_SFP_OTP_OFFSET + offset, bytes);
+
+	return 0;
+}
+
+static struct nvmem_config layerscape_sfp_nvmem_config = {
+	.name = "fsl-sfp",
+	.reg_read = layerscape_sfp_read,
+};
+
+static int layerscape_sfp_probe(struct platform_device *pdev)
+{
+	const struct layerscape_sfp_data *data;
+	struct layerscape_sfp_priv *priv;
+	struct nvmem_device *nvmem;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	data = device_get_match_data(&pdev->dev);
+
+	layerscape_sfp_nvmem_config.size = data->size;
+	layerscape_sfp_nvmem_config.dev = &pdev->dev;
+	layerscape_sfp_nvmem_config.priv = priv;
+
+	nvmem = devm_nvmem_register(&pdev->dev, &layerscape_sfp_nvmem_config);
+
+	return PTR_ERR_OR_ZERO(nvmem);
+}
+
+static const struct layerscape_sfp_data ls1028a_data = {
+	.size = 0x88,
+};
+
+static const struct of_device_id layerscape_sfp_dt_ids[] = {
+	{ .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids);
+
+static struct platform_driver layerscape_sfp_driver = {
+	.probe	= layerscape_sfp_probe,
+	.driver = {
+		.name	= "layerscape_sfp",
+		.of_match_table = layerscape_sfp_dt_ids,
+	},
+};
+module_platform_driver(layerscape_sfp_driver);
+
+MODULE_AUTHOR("Michael Walle <michael at walle.cc>");
+MODULE_DESCRIPTION("Layerscape Security Fuse Processor driver");
+MODULE_LICENSE("GPL v2");
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:18 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:18 +0100
Subject: [PATCH v1 0/7] soc: fsl: guts: cleanups and serial_number support
Message-ID: <20220127164125.3651285-1-michael@walle.cc>

This series converts the guts driver from a platform driver to just an
core_initcall. The driver itself cannot (or rather should never) be
unloaded because others depends on detecting the current SoC revision
to apply chip errata. Other SoC drivers do it the same way. Overall I
got rid of all the global static variables.

The last patch finally adds unique id support to the guts driver. But
because the binding for the security fuse processor is still pending,
it is marked as RFC.

Michael Walle (7):
  soc: fsl: guts: machine variable might be unset
  soc: fsl: guts: remove module_exit() and fsl_guts_remove()
  soc: fsl: guts: embed fsl_guts_get_svr() in probe()
  soc: fsl: guts: allocate soc_dev_attr on the heap
  soc: fsl: guts: use of_root instead of own reference
  soc: fsl: guts: drop platform driver
  soc: fsl: guts: add serial_number support

 drivers/soc/fsl/guts.c | 215 ++++++++++++++++++++++-------------------
 1 file changed, 114 insertions(+), 101 deletions(-)

-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:19 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:19 +0100
Subject: [PATCH v1 1/7] soc: fsl: guts: machine variable might be unset
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-2-michael@walle.cc>

If both the model and the compatible properties are missing, then
machine will not be set. Initialize it with NULL.

Fixes: 34c1c21e94ac ("soc: fsl: fix section mismatch build warnings")
Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 5ed2fc1c53a0..be18d46c7b0f 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -140,7 +140,7 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	struct device_node *root, *np = pdev->dev.of_node;
 	struct device *dev = &pdev->dev;
 	const struct fsl_soc_die_attr *soc_die;
-	const char *machine;
+	const char *machine = NULL;
 	u32 svr;
 
 	/* Initialize guts */
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:20 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:20 +0100
Subject: [PATCH v1 2/7] soc: fsl: guts: remove module_exit() and
 fsl_guts_remove()
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-3-michael@walle.cc>

This driver will never be unloaded. Firstly, it is not available as a
module, but more importantly, other drivers will depend on this one to
apply possible chip errata.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index be18d46c7b0f..0bea43770d51 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -27,7 +27,6 @@ struct fsl_soc_die_attr {
 
 static struct guts *guts;
 static struct soc_device_attribute soc_dev_attr;
-static struct soc_device *soc_dev;
 
 
 /* SoC die attribute definition for QorIQ platform */
@@ -138,6 +137,7 @@ static u32 fsl_guts_get_svr(void)
 static int fsl_guts_probe(struct platform_device *pdev)
 {
 	struct device_node *root, *np = pdev->dev.of_node;
+	static struct soc_device *soc_dev;
 	struct device *dev = &pdev->dev;
 	const struct fsl_soc_die_attr *soc_die;
 	const char *machine = NULL;
@@ -197,12 +197,6 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	return 0;
 }
 
-static int fsl_guts_remove(struct platform_device *dev)
-{
-	soc_device_unregister(soc_dev);
-	return 0;
-}
-
 /*
  * Table for matching compatible strings, for device tree
  * guts node, for Freescale QorIQ SOCs.
@@ -242,7 +236,6 @@ static struct platform_driver fsl_guts_driver = {
 		.of_match_table = fsl_guts_of_match,
 	},
 	.probe = fsl_guts_probe,
-	.remove = fsl_guts_remove,
 };
 
 static int __init fsl_guts_init(void)
@@ -250,9 +243,3 @@ static int __init fsl_guts_init(void)
 	return platform_driver_register(&fsl_guts_driver);
 }
 core_initcall(fsl_guts_init);
-
-static void __exit fsl_guts_exit(void)
-{
-	platform_driver_unregister(&fsl_guts_driver);
-}
-module_exit(fsl_guts_exit);
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:21 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:21 +0100
Subject: [PATCH v1 3/7] soc: fsl: guts: embed fsl_guts_get_svr() in probe()
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-4-michael@walle.cc>

Move the reading of the SVR into the probe function as
fsl_guts_get_svr() is the only user of the static guts variable and this
lets us drop that as well as the malloc() for this variable. Also, we
can unmap the memory region after we accessed it, which will simplify
error handling later.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 41 +++++++++++------------------------------
 1 file changed, 11 insertions(+), 30 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 0bea43770d51..536377988fb4 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -14,18 +14,12 @@
 #include <linux/platform_device.h>
 #include <linux/fsl/guts.h>
 
-struct guts {
-	struct ccsr_guts __iomem *regs;
-	bool little_endian;
-};
-
 struct fsl_soc_die_attr {
 	char	*die;
 	u32	svr;
 	u32	mask;
 };
 
-static struct guts *guts;
 static struct soc_device_attribute soc_dev_attr;
 
 
@@ -119,40 +113,28 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
 	return NULL;
 }
 
-static u32 fsl_guts_get_svr(void)
-{
-	u32 svr = 0;
-
-	if (!guts || !guts->regs)
-		return svr;
-
-	if (guts->little_endian)
-		svr = ioread32(&guts->regs->svr);
-	else
-		svr = ioread32be(&guts->regs->svr);
-
-	return svr;
-}
-
 static int fsl_guts_probe(struct platform_device *pdev)
 {
 	struct device_node *root, *np = pdev->dev.of_node;
 	static struct soc_device *soc_dev;
 	struct device *dev = &pdev->dev;
 	const struct fsl_soc_die_attr *soc_die;
+	struct ccsr_guts __iomem *regs;
 	const char *machine = NULL;
+	bool little_endian;
 	u32 svr;
 
-	/* Initialize guts */
-	guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL);
-	if (!guts)
-		return -ENOMEM;
+	little_endian = of_property_read_bool(np, "little-endian");
 
-	guts->little_endian = of_property_read_bool(np, "little-endian");
+	regs = of_iomap(np, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
 
-	guts->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(guts->regs))
-		return PTR_ERR(guts->regs);
+	if (little_endian)
+		svr = ioread32(&regs->svr);
+	else
+		svr = ioread32be(&regs->svr);
+	iounmap(regs);
 
 	/* Register soc device */
 	root = of_find_node_by_path("/");
@@ -167,7 +149,6 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	}
 	of_node_put(root);
 
-	svr = fsl_guts_get_svr();
 	soc_die = fsl_soc_die_match(svr, fsl_soc_die);
 	if (soc_die) {
 		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:22 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:22 +0100
Subject: [PATCH v1 4/7] soc: fsl: guts: allocate soc_dev_attr on the heap
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-5-michael@walle.cc>

This is the last global static variable. Drop it and allocate the memory
on the heap instead.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 536377988fb4..383b35a4ed58 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -20,9 +20,6 @@ struct fsl_soc_die_attr {
 	u32	mask;
 };
 
-static struct soc_device_attribute soc_dev_attr;
-
-
 /* SoC die attribute definition for QorIQ platform */
 static const struct fsl_soc_die_attr fsl_soc_die[] = {
 	/*
@@ -116,6 +113,7 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
 static int fsl_guts_probe(struct platform_device *pdev)
 {
 	struct device_node *root, *np = pdev->dev.of_node;
+	struct soc_device_attribute *soc_dev_attr;
 	static struct soc_device *soc_dev;
 	struct device *dev = &pdev->dev;
 	const struct fsl_soc_die_attr *soc_die;
@@ -124,6 +122,10 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	bool little_endian;
 	u32 svr;
 
+	soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL);
+	if (!soc_dev_attr)
+		return -ENOMEM;
+
 	little_endian = of_property_read_bool(np, "little-endian");
 
 	regs = of_iomap(np, 0);
@@ -141,8 +143,8 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	if (of_property_read_string(root, "model", &machine))
 		of_property_read_string_index(root, "compatible", 0, &machine);
 	if (machine) {
-		soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
-		if (!soc_dev_attr.machine) {
+		soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+		if (!soc_dev_attr->machine) {
 			of_node_put(root);
 			return -ENOMEM;
 		}
@@ -151,30 +153,30 @@ static int fsl_guts_probe(struct platform_device *pdev)
 
 	soc_die = fsl_soc_die_match(svr, fsl_soc_die);
 	if (soc_die) {
-		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL,
-						     "QorIQ %s", soc_die->die);
+		soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL,
+						      "QorIQ %s", soc_die->die);
 	} else {
-		soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ");
+		soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ");
 	}
-	if (!soc_dev_attr.family)
+	if (!soc_dev_attr->family)
 		return -ENOMEM;
-	soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL,
+	soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL,
 					     "svr:0x%08x", svr);
-	if (!soc_dev_attr.soc_id)
+	if (!soc_dev_attr->soc_id)
 		return -ENOMEM;
-	soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
+	soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
 					       (svr >>  4) & 0xf, svr & 0xf);
-	if (!soc_dev_attr.revision)
+	if (!soc_dev_attr->revision)
 		return -ENOMEM;
 
-	soc_dev = soc_device_register(&soc_dev_attr);
+	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev))
 		return PTR_ERR(soc_dev);
 
-	pr_info("Machine: %s\n", soc_dev_attr.machine);
-	pr_info("SoC family: %s\n", soc_dev_attr.family);
+	pr_info("Machine: %s\n", soc_dev_attr->machine);
+	pr_info("SoC family: %s\n", soc_dev_attr->family);
 	pr_info("SoC ID: %s, Revision: %s\n",
-		soc_dev_attr.soc_id, soc_dev_attr.revision);
+		soc_dev_attr->soc_id, soc_dev_attr->revision);
 	return 0;
 }
 
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:23 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:23 +0100
Subject: [PATCH v1 5/7] soc: fsl: guts: use of_root instead of own reference
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-6-michael@walle.cc>

There is already a global of_root reference. Use that instead of getting
one on our own. We don't need to care about the reference count either
this way.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 383b35a4ed58..04c3eb6a6e17 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -112,7 +112,7 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
 
 static int fsl_guts_probe(struct platform_device *pdev)
 {
-	struct device_node *root, *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.of_node;
 	struct soc_device_attribute *soc_dev_attr;
 	static struct soc_device *soc_dev;
 	struct device *dev = &pdev->dev;
@@ -139,17 +139,13 @@ static int fsl_guts_probe(struct platform_device *pdev)
 	iounmap(regs);
 
 	/* Register soc device */
-	root = of_find_node_by_path("/");
-	if (of_property_read_string(root, "model", &machine))
-		of_property_read_string_index(root, "compatible", 0, &machine);
+	if (of_property_read_string(of_root, "model", &machine))
+		of_property_read_string_index(of_root, "compatible", 0, &machine);
 	if (machine) {
 		soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL);
-		if (!soc_dev_attr->machine) {
-			of_node_put(root);
+		if (!soc_dev_attr->machine)
 			return -ENOMEM;
-		}
 	}
-	of_node_put(root);
 
 	soc_die = fsl_soc_die_match(svr, fsl_soc_die);
 	if (soc_die) {
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:25 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:25 +0100
Subject: [RFC PATCH v1 7/7] soc: fsl: guts: add serial_number support
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-8-michael@walle.cc>

Most layerscapes provide a security fuse processor where the vendor
will store a unique id per part. Unfortunately, we cannot use the
corresponding efuse driver because this driver needs to be ready
early during the boot phase. To get the unique identifier, we just
need to access two registers. Thus we just search the device tree
for the corresponding device, map its memory to read the id and then
unmap it again.

Because it is likely that the offset within the fuses is dependent
on the SoC, we need a per SoC data. Also, the compatible string is
different among the SoCs. For now, this add support for the LS1028A
SoC.

Signed-off-by: Michael Walle <michael at walle.cc>
---
RFC because SFP binding is still pending and needs Rob's ack:
https://lore.kernel.org/linux-devicetree/20220127163728.3650648-2-michael at walle.cc/

 drivers/soc/fsl/guts.c | 48 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index be961a9193f4..2d20a344f3c9 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -20,6 +20,11 @@ struct fsl_soc_die_attr {
 	u32	mask;
 };
 
+struct fsl_soc_data {
+	const char *sfp_compat;
+	u32 uid_offset;
+};
+
 /* SoC die attribute definition for QorIQ platform */
 static const struct fsl_soc_die_attr fsl_soc_die[] = {
 	/*
@@ -110,6 +115,33 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
 	return NULL;
 }
 
+static u64 fsl_guts_get_soc_uid(const char *compat, unsigned int offset)
+{
+	struct device_node *np;
+	void __iomem *sfp_base;
+	u64 uid;
+
+	np = of_find_compatible_node(NULL, NULL, compat);
+	if (!np)
+		return 0;
+
+	sfp_base = of_iomap(np, 0);
+
+	uid = ioread32(sfp_base + offset);
+	uid <<= 32;
+	uid |= ioread32(sfp_base + offset + 4);
+
+	iounmap(sfp_base);
+	of_node_put(np);
+
+	return uid;
+}
+
+static const struct fsl_soc_data ls1028a_data = {
+	.sfp_compat = "fsl,ls1028a-sfp",
+	.uid_offset = 0x21c,
+};
+
 /*
  * Table for matching compatible strings, for device tree
  * guts node, for Freescale QorIQ SOCs.
@@ -138,7 +170,7 @@ static const struct of_device_id fsl_guts_of_match[] = {
 	{ .compatible = "fsl,ls1012a-dcfg", },
 	{ .compatible = "fsl,ls1046a-dcfg", },
 	{ .compatible = "fsl,lx2160a-dcfg", },
-	{ .compatible = "fsl,ls1028a-dcfg", },
+	{ .compatible = "fsl,ls1028a-dcfg", .data = &ls1028a_data},
 	{}
 };
 
@@ -147,16 +179,20 @@ static int __init fsl_guts_init(void)
 	struct soc_device_attribute *soc_dev_attr;
 	static struct soc_device *soc_dev;
 	const struct fsl_soc_die_attr *soc_die;
+	const struct fsl_soc_data *soc_data;
+	const struct of_device_id *match;
 	struct ccsr_guts __iomem *regs;
 	const char *machine = NULL;
 	struct device_node *np;
 	bool little_endian;
+	u64 soc_uid = 0;
 	u32 svr;
 	int ret;
 
-	np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, NULL);
+	np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, &match);
 	if (!np)
 		return 0;
+	soc_data = match->data;
 
 	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
@@ -201,6 +237,13 @@ static int __init fsl_guts_init(void)
 	if (!soc_dev_attr->revision)
 		goto err_nomem;
 
+	if (soc_data)
+		soc_uid = fsl_guts_get_soc_uid(soc_data->sfp_compat,
+					       soc_data->uid_offset);
+	if (soc_uid)
+		soc_dev_attr->serial_number = kasprintf(GFP_KERNEL, "%016llX",
+							soc_uid);
+
 	soc_dev = soc_device_register(soc_dev_attr);
 	if (IS_ERR(soc_dev)) {
 		ret = PTR_ERR(soc_dev);
@@ -221,6 +264,7 @@ static int __init fsl_guts_init(void)
 	kfree(soc_dev_attr->family);
 	kfree(soc_dev_attr->soc_id);
 	kfree(soc_dev_attr->revision);
+	kfree(soc_dev_attr->serial_number);
 
 	return ret;
 }
-- 
2.30.2



From michael at walle.cc  Thu Jan 27 08:41:24 2022
From: michael at walle.cc (Michael Walle)
Date: Thu, 27 Jan 2022 17:41:24 +0100
Subject: [PATCH v1 6/7] soc: fsl: guts: drop platform driver
In-Reply-To: <20220127164125.3651285-1-michael@walle.cc>
References: <20220127164125.3651285-1-michael@walle.cc>
Message-ID: <20220127164125.3651285-7-michael@walle.cc>

This driver cannot be unloaded and it will be needed very early in the
boot process because other driver (weakly) depend on it (eg. for chip
errata handling). Drop all the platform driver and devres stuff and
simply make it a core_initcall.

Signed-off-by: Michael Walle <michael at walle.cc>
---
 drivers/soc/fsl/guts.c | 127 +++++++++++++++++++++--------------------
 1 file changed, 65 insertions(+), 62 deletions(-)

diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
index 04c3eb6a6e17..be961a9193f4 100644
--- a/drivers/soc/fsl/guts.c
+++ b/drivers/soc/fsl/guts.c
@@ -110,19 +110,55 @@ static const struct fsl_soc_die_attr *fsl_soc_die_match(
 	return NULL;
 }
 
-static int fsl_guts_probe(struct platform_device *pdev)
+/*
+ * Table for matching compatible strings, for device tree
+ * guts node, for Freescale QorIQ SOCs.
+ */
+static const struct of_device_id fsl_guts_of_match[] = {
+	{ .compatible = "fsl,qoriq-device-config-1.0", },
+	{ .compatible = "fsl,qoriq-device-config-2.0", },
+	{ .compatible = "fsl,p1010-guts", },
+	{ .compatible = "fsl,p1020-guts", },
+	{ .compatible = "fsl,p1021-guts", },
+	{ .compatible = "fsl,p1022-guts", },
+	{ .compatible = "fsl,p1023-guts", },
+	{ .compatible = "fsl,p2020-guts", },
+	{ .compatible = "fsl,bsc9131-guts", },
+	{ .compatible = "fsl,bsc9132-guts", },
+	{ .compatible = "fsl,mpc8536-guts", },
+	{ .compatible = "fsl,mpc8544-guts", },
+	{ .compatible = "fsl,mpc8548-guts", },
+	{ .compatible = "fsl,mpc8568-guts", },
+	{ .compatible = "fsl,mpc8569-guts", },
+	{ .compatible = "fsl,mpc8572-guts", },
+	{ .compatible = "fsl,ls1021a-dcfg", },
+	{ .compatible = "fsl,ls1043a-dcfg", },
+	{ .compatible = "fsl,ls2080a-dcfg", },
+	{ .compatible = "fsl,ls1088a-dcfg", },
+	{ .compatible = "fsl,ls1012a-dcfg", },
+	{ .compatible = "fsl,ls1046a-dcfg", },
+	{ .compatible = "fsl,lx2160a-dcfg", },
+	{ .compatible = "fsl,ls1028a-dcfg", },
+	{}
+};
+
+static int __init fsl_guts_init(void)
 {
-	struct device_node *np = pdev->dev.of_node;
 	struct soc_device_attribute *soc_dev_attr;
 	static struct soc_device *soc_dev;
-	struct device *dev = &pdev->dev;
 	const struct fsl_soc_die_attr *soc_die;
 	struct ccsr_guts __iomem *regs;
 	const char *machine = NULL;
+	struct device_node *np;
 	bool little_endian;
 	u32 svr;
+	int ret;
 
-	soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL);
+	np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, NULL);
+	if (!np)
+		return 0;
+
+	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 	if (!soc_dev_attr)
 		return -ENOMEM;
 
@@ -138,87 +174,54 @@ static int fsl_guts_probe(struct platform_device *pdev)
 		svr = ioread32be(&regs->svr);
 	iounmap(regs);
 
-	/* Register soc device */
 	if (of_property_read_string(of_root, "model", &machine))
 		of_property_read_string_index(of_root, "compatible", 0, &machine);
 	if (machine) {
-		soc_dev_attr->machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+		soc_dev_attr->machine = kstrdup(machine, GFP_KERNEL);
 		if (!soc_dev_attr->machine)
 			return -ENOMEM;
 	}
 
 	soc_die = fsl_soc_die_match(svr, fsl_soc_die);
 	if (soc_die) {
-		soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL,
-						      "QorIQ %s", soc_die->die);
+		soc_dev_attr->family = kasprintf(GFP_KERNEL, "QorIQ %s",
+						 soc_die->die);
 	} else {
-		soc_dev_attr->family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ");
+		soc_dev_attr->family = kasprintf(GFP_KERNEL, "QorIQ");
 	}
 	if (!soc_dev_attr->family)
-		return -ENOMEM;
-	soc_dev_attr->soc_id = devm_kasprintf(dev, GFP_KERNEL,
-					     "svr:0x%08x", svr);
+		goto err_nomem;
+
+	soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "svr:0x%08x", svr);
 	if (!soc_dev_attr->soc_id)
-		return -ENOMEM;
-	soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d",
-					       (svr >>  4) & 0xf, svr & 0xf);
+		goto err_nomem;
+
+	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d.%d",
+					   (svr >>  4) & 0xf, svr & 0xf);
 	if (!soc_dev_attr->revision)
-		return -ENOMEM;
+		goto err_nomem;
 
 	soc_dev = soc_device_register(soc_dev_attr);
-	if (IS_ERR(soc_dev))
-		return PTR_ERR(soc_dev);
+	if (IS_ERR(soc_dev)) {
+		ret = PTR_ERR(soc_dev);
+		goto err;
+	}
 
 	pr_info("Machine: %s\n", soc_dev_attr->machine);
 	pr_info("SoC family: %s\n", soc_dev_attr->family);
 	pr_info("SoC ID: %s, Revision: %s\n",
 		soc_dev_attr->soc_id, soc_dev_attr->revision);
-	return 0;
-}
 
-/*
- * Table for matching compatible strings, for device tree
- * guts node, for Freescale QorIQ SOCs.
- */
-static const struct of_device_id fsl_guts_of_match[] = {
-	{ .compatible = "fsl,qoriq-device-config-1.0", },
-	{ .compatible = "fsl,qoriq-device-config-2.0", },
-	{ .compatible = "fsl,p1010-guts", },
-	{ .compatible = "fsl,p1020-guts", },
-	{ .compatible = "fsl,p1021-guts", },
-	{ .compatible = "fsl,p1022-guts", },
-	{ .compatible = "fsl,p1023-guts", },
-	{ .compatible = "fsl,p2020-guts", },
-	{ .compatible = "fsl,bsc9131-guts", },
-	{ .compatible = "fsl,bsc9132-guts", },
-	{ .compatible = "fsl,mpc8536-guts", },
-	{ .compatible = "fsl,mpc8544-guts", },
-	{ .compatible = "fsl,mpc8548-guts", },
-	{ .compatible = "fsl,mpc8568-guts", },
-	{ .compatible = "fsl,mpc8569-guts", },
-	{ .compatible = "fsl,mpc8572-guts", },
-	{ .compatible = "fsl,ls1021a-dcfg", },
-	{ .compatible = "fsl,ls1043a-dcfg", },
-	{ .compatible = "fsl,ls2080a-dcfg", },
-	{ .compatible = "fsl,ls1088a-dcfg", },
-	{ .compatible = "fsl,ls1012a-dcfg", },
-	{ .compatible = "fsl,ls1046a-dcfg", },
-	{ .compatible = "fsl,lx2160a-dcfg", },
-	{ .compatible = "fsl,ls1028a-dcfg", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
+	return 0;
 
-static struct platform_driver fsl_guts_driver = {
-	.driver = {
-		.name = "fsl-guts",
-		.of_match_table = fsl_guts_of_match,
-	},
-	.probe = fsl_guts_probe,
-};
+err_nomem:
+	ret = -ENOMEM;
+err:
+	kfree(soc_dev_attr->machine);
+	kfree(soc_dev_attr->family);
+	kfree(soc_dev_attr->soc_id);
+	kfree(soc_dev_attr->revision);
 
-static int __init fsl_guts_init(void)
-{
-	return platform_driver_register(&fsl_guts_driver);
+	return ret;
 }
 core_initcall(fsl_guts_init);
-- 
2.30.2



From rostedt at goodmis.org  Thu Jan 27 08:42:49 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Thu, 27 Jan 2022 11:42:49 -0500
Subject: [PATCH] ftrace: Have architectures opt-in for mcount build time
 sorting
Message-ID: <20220127114249.03b1b52b@gandalf.local.home>

From: "Steven Rostedt (Google)" <rostedt at goodmis.org>

First S390 complained that the sorting of the mcount sections at build
time caused the kernel to crash on their architecture. Now PowerPC is
complaining about it too. And also ARM64 appears to be having issues.

It may be necessary to also update the relocation table for the values
in the mcount table. Not only do we have to sort the table, but also
update the relocations that may be applied to the items in the table.

If the system is not relocatable, then it is fine to sort, but if it is,
some architectures may have issues (although x86 does not as it shifts all
addresses the same).

Add a HAVE_BUILDTIME_MCOUNT_SORT that an architecture can set to say it is
safe to do the sorting at build time.

Also update the config to compile in build time sorting in the sorttable
code in scripts/ to depend on CONFIG_BUILDTIME_MCOUNT_SORT.

Link: https://lore.kernel.org/all/944D10DA-8200-4BA9-8D0A-3BED9AA99F82 at linux.ibm.com/

Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Yinan Liu <yinan at linux.alibaba.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Kees Cook <keescook at chromium.org>
Cc: linuxppc-dev at lists.ozlabs.org
Reported-by: Sachin Sant <sachinp at linux.ibm.com>
Tested-by: Sachin Sant <sachinp at linux.ibm.com>
Fixes: 72b3942a173c ("scripts: ftrace - move the sort-processing in ftrace_init")
Signed-off-by: Steven Rostedt (Google) <rostedt at goodmis.org>
---
 arch/arm/Kconfig     | 1 +
 arch/x86/Kconfig     | 1 +
 kernel/trace/Kconfig | 8 +++++++-
 scripts/Makefile     | 2 +-
 4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c2724d986fa0..5256ebe57451 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -82,6 +82,7 @@ config ARM
 	select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
 	select HAVE_CONTEXT_TRACKING
 	select HAVE_C_RECORDMCOUNT
+	select HAVE_BUILDTIME_MCOUNT_SORT
 	select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
 	select HAVE_DMA_CONTIGUOUS if MMU
 	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7399327d1eff..46080dea5dba 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -186,6 +186,7 @@ config X86
 	select HAVE_CONTEXT_TRACKING_OFFSTACK	if HAVE_CONTEXT_TRACKING
 	select HAVE_C_RECORDMCOUNT
 	select HAVE_OBJTOOL_MCOUNT		if STACK_VALIDATION
+	select HAVE_BUILDTIME_MCOUNT_SORT
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_CONTIGUOUS
 	select HAVE_DYNAMIC_FTRACE
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 752ed89a293b..7e5b92090faa 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -70,10 +70,16 @@ config HAVE_C_RECORDMCOUNT
 	help
 	  C version of recordmcount available?
 
+config HAVE_BUILDTIME_MCOUNT_SORT
+       bool
+       help
+         An architecture selects this if it sorts the mcount_loc section
+	 at build time.
+
 config BUILDTIME_MCOUNT_SORT
        bool
        default y
-       depends on BUILDTIME_TABLE_SORT && !S390
+       depends on HAVE_BUILDTIME_MCOUNT_SORT
        help
          Sort the mcount_loc section at build time.
 
diff --git a/scripts/Makefile b/scripts/Makefile
index b082d2f93357..cedc1f0e21d8 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -32,7 +32,7 @@ HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
 HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
 endif
 
-ifdef CONFIG_DYNAMIC_FTRACE
+ifdef CONFIG_BUILDTIME_MCOUNT_SORT
 HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
 endif
 
-- 
2.33.0



From semen.protsenko at linaro.org  Thu Jan 27 08:58:30 2022
From: semen.protsenko at linaro.org (Sam Protsenko)
Date: Thu, 27 Jan 2022 18:58:30 +0200
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <cb11d2e0-dd03-9a48-74f3-0a22f49f16b5@canonical.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <cb11d2e0-dd03-9a48-74f3-0a22f49f16b5@canonical.com>
Message-ID: <CAPLW+4=Hj-vamn5EoV-SmB5JwEbuik9hF2XuhB+tU11GwXPQdg@mail.gmail.com>

On Thu, 27 Jan 2022 at 11:33, Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:
>
> On 27/12/2021 12:29, Krzysztof Kozlowski wrote:
> > Hi,
> >
> > Second pull with DTS for ARM64, on top of previous pull.
> >
> > Best regards,
> > Krzysztof
> >
> >
> > The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
> >
> >   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
> >
> > are available in the Git repository at:
> >
> >   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
> >
> > for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
> >
> >   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
> >
> > ----------------------------------------------------------------
> > Samsung DTS ARM64 changes for v5.17, part two
> >
> > Add initial Exynos850 support and WinLink E850-96 board using it.
> >
> > ----------------------------------------------------------------
> > Sam Protsenko (2):
> >       arm64: dts: exynos: Add initial Exynos850 SoC support
> >       arm64: dts: exynos: Add initial E850-96 board support
> >
>
> I'll send all this as v5.18 material, so this pull-req can be skipped.
>

Krzysztof,

As clock changes are merged in mainline now, do you want me to re-send
those two dts patches using corresponding clock constants, instead of
hard-coded numbers?

>
> Best regards,
> Krzysztof


From lkp at intel.com  Thu Jan 27 09:04:25 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 28 Jan 2022 01:04:25 +0800
Subject: [PATCH 2/3] pinctrl: uniphier: Divide pinmux group to support
 1ch and 2ch I2S
In-Reply-To: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <202201280003.icgPhtLw-lkp@intel.com>

Hi Kunihiko,

I love your patch! Yet something to improve:

[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on v5.17-rc1 next-20220127]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Kunihiko-Hayashi/pinctrl-uniphier-Add-some-more-pinmux-settings/20220127-193715
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
config: arm-randconfig-r005-20220124 (https://download.01.org/0day-ci/archive/20220128/202201280003.icgPhtLw-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f32dccb9a43b02ce4e540d6ba5dbbdb188f2dc7d)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://github.com/0day-ci/linux/commit/e0e366a006b79517336423f8a2c72661178d5e41
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Kunihiko-Hayashi/pinctrl-uniphier-Add-some-more-pinmux-settings/20220127-193715
        git checkout e0e366a006b79517336423f8a2c72661178d5e41
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/pinctrl/uniphier/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:2: error: use of undeclared identifier 'aout4_groups'
           UNIPHIER_PINMUX_FUNCTION(aout4),
           ^
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:179:13: note: expanded from macro 'UNIPHIER_PINMUX_FUNCTION'
                   .groups = func##_groups,                                \
                             ^
   <scratch space>:175:1: note: expanded from here
   aout4_groups
   ^
>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:2: error: use of undeclared identifier 'aout4_groups'
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:180:28: note: expanded from macro 'UNIPHIER_PINMUX_FUNCTION'
                   .num_groups = ARRAY_SIZE(func##_groups),                \
                                            ^
   <scratch space>:176:1: note: expanded from here
   aout4_groups
   ^
>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:2: error: use of undeclared identifier 'aout4_groups'
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:180:28: note: expanded from macro 'UNIPHIER_PINMUX_FUNCTION'
                   .num_groups = ARRAY_SIZE(func##_groups),                \
                                            ^
   <scratch space>:176:1: note: expanded from here
   aout4_groups
   ^
>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:2: error: use of undeclared identifier 'aout4_groups'
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:180:28: note: expanded from macro 'UNIPHIER_PINMUX_FUNCTION'
                   .num_groups = ARRAY_SIZE(func##_groups),                \
                                            ^
   <scratch space>:176:1: note: expanded from here
   aout4_groups
   ^
>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:1002:21: error: invalid application of 'sizeof' to an incomplete type 'const struct uniphier_pinmux_function[]'
           .functions_count = ARRAY_SIZE(uniphier_pxs2_functions),
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/kernel.h:55:32: note: expanded from macro 'ARRAY_SIZE'
   #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
                                  ^~~~~
   5 errors generated.


vim +/aout4_groups +958 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c

   949	
   950	static const struct uniphier_pinmux_function uniphier_pxs2_functions[] = {
   951		UNIPHIER_PINMUX_FUNCTION(ain1),
   952		UNIPHIER_PINMUX_FUNCTION(ain2),
   953		UNIPHIER_PINMUX_FUNCTION(ain3),
   954		UNIPHIER_PINMUX_FUNCTION(ainiec1),
   955		UNIPHIER_PINMUX_FUNCTION(aout1),
   956		UNIPHIER_PINMUX_FUNCTION(aout2),
   957		UNIPHIER_PINMUX_FUNCTION(aout3),
 > 958		UNIPHIER_PINMUX_FUNCTION(aout4),
   959		UNIPHIER_PINMUX_FUNCTION(aoutiec1),
   960		UNIPHIER_PINMUX_FUNCTION(aoutiec2),
   961		UNIPHIER_PINMUX_FUNCTION(emmc),
   962		UNIPHIER_PINMUX_FUNCTION(ether_mii),
   963		UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
   964		UNIPHIER_PINMUX_FUNCTION(ether_rmii),
   965		UNIPHIER_PINMUX_FUNCTION(i2c0),
   966		UNIPHIER_PINMUX_FUNCTION(i2c1),
   967		UNIPHIER_PINMUX_FUNCTION(i2c2),
   968		UNIPHIER_PINMUX_FUNCTION(i2c3),
   969		UNIPHIER_PINMUX_FUNCTION(i2c5),
   970		UNIPHIER_PINMUX_FUNCTION(i2c6),
   971		UNIPHIER_PINMUX_FUNCTION(nand),
   972		UNIPHIER_PINMUX_FUNCTION(sd),
   973		UNIPHIER_PINMUX_FUNCTION(spi0),
   974		UNIPHIER_PINMUX_FUNCTION(spi1),
   975		UNIPHIER_PINMUX_FUNCTION(system_bus),
   976		UNIPHIER_PINMUX_FUNCTION(uart0),
   977		UNIPHIER_PINMUX_FUNCTION(uart1),
   978		UNIPHIER_PINMUX_FUNCTION(uart2),
   979		UNIPHIER_PINMUX_FUNCTION(uart3),
   980		UNIPHIER_PINMUX_FUNCTION(usb0),
   981		UNIPHIER_PINMUX_FUNCTION(usb1),
   982		UNIPHIER_PINMUX_FUNCTION(usb2),
   983		UNIPHIER_PINMUX_FUNCTION(usb3),
   984	};
   985	
   986	static int uniphier_pxs2_get_gpio_muxval(unsigned int pin,
   987						 unsigned int gpio_offset)
   988	{
   989		if (gpio_offset >= 120 && gpio_offset <= 143)	/* XIRQx */
   990			/* 15 will do because XIRQ0-23 are aliases of PORT150-177. */
   991			return 14;
   992	
   993		return 15;
   994	}
   995	
   996	static const struct uniphier_pinctrl_socdata uniphier_pxs2_pindata = {
   997		.pins = uniphier_pxs2_pins,
   998		.npins = ARRAY_SIZE(uniphier_pxs2_pins),
   999		.groups = uniphier_pxs2_groups,
  1000		.groups_count = ARRAY_SIZE(uniphier_pxs2_groups),
  1001		.functions = uniphier_pxs2_functions,
> 1002		.functions_count = ARRAY_SIZE(uniphier_pxs2_functions),
  1003		.get_gpio_muxval = uniphier_pxs2_get_gpio_muxval,
  1004		.caps = 0,
  1005	};
  1006	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From olteanv at gmail.com  Thu Jan 27 09:05:57 2022
From: olteanv at gmail.com (Vladimir Oltean)
Date: Thu, 27 Jan 2022 19:05:57 +0200
Subject: [PATCH] arm64: dts: ls1028a-qds: define mdio slots for
 networking options
In-Reply-To: <20220126092650.19962-1-leoyang.li@nxp.com>
References: <20220126092650.19962-1-leoyang.li@nxp.com>
Message-ID: <20220127170557.v7lg3harlf2skeqi@skbuf>

On Wed, Jan 26, 2022 at 03:26:50AM -0600, Li Yang wrote:
> The ls1028a QDS board support different pluggable PHY cards.  Define the
> nodes for these slots to be updated at boot time with overlay according
> to board setup.
> 
> Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>
> ---

Tested-by: Vladimir Oltean <vladimir.oltean at nxp.com>

This fixes:
=> tftp $fdt_addr_r fsl-ls1028a-qds.dtb && tftp $fdt_ovr_addr_r fsl-ls1028a-qds-85bb.dtb
=> fdt addr $fdt_addr_r && fdt resize 0x100000 && fdt apply $fdt_ovr_addr_r
failed on fdt_overlay_apply(): FDT_ERR_NOTFOUND

>  .../boot/dts/freescale/fsl-ls1028a-qds.dts    | 24 +++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> index 177bc1405f0f..19d3952dbffe 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
> @@ -107,6 +107,30 @@ qds_phy1: ethernet-phy at 5 {
>  				reg = <5>;
>  			};
>  		};
> +
> +		mdio_slot1: mdio at 4 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <4>;
> +		};
> +
> +		mdio_slot2: mdio at 5 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <5>;
> +		};
> +
> +		mdio_slot3: mdio at 6 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <6>;
> +		};
> +
> +		mdio_slot4: mdio at 7 {
> +			#address-cells = <1>;
> +			#size-cells = <0>;
> +			reg = <7>;
> +		};
>  	};
>  };
>  
> -- 
> 2.25.1
> 


From vladimir.oltean at nxp.com  Thu Jan 27 09:21:02 2022
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Thu, 27 Jan 2022 19:21:02 +0200
Subject: [PATCH 0/3] Use sl28cpld driver for the LS1028A-QDS QIXIS FPGA
Message-ID: <20220127172105.4085950-1-vladimir.oltean@nxp.com>

Patches 1-2 are intended for Lee Jones (mfd) and patch 3 for Shawn Guo
(devicetree). Included all in the same patchset because they're small
and depend on each other.

With these changes, the mdio mux on the NXP LS1028A-QDS boards, which is
controlled through the QIXIS FPGA, works properly without the need for
any additional driver.

Vladimir Oltean (3):
  mfd: simple-mfd-i2c: add compatible string for LS1028A-QDS FPGA
  dt-bindings: mfd: add "fsl,ls1028a-qds-qixis-i2c" compatible to
    sl28cpld
  arm64: dts: ls1028a-qds: make the QIXIS CPLD use the simple-mfd-i2c.c
    driver

 .../devicetree/bindings/mfd/kontron,sl28cpld.yaml        | 4 +++-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts        | 9 +++++----
 drivers/mfd/simple-mfd-i2c.c                             | 1 +
 3 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.25.1



From vladimir.oltean at nxp.com  Thu Jan 27 09:21:03 2022
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Thu, 27 Jan 2022 19:21:03 +0200
Subject: [PATCH 1/3] mfd: simple-mfd-i2c: add compatible string for
 LS1028A-QDS FPGA
In-Reply-To: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
References: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
Message-ID: <20220127172105.4085950-2-vladimir.oltean@nxp.com>

As Michael mentions in the description of commit 3abee4579484 ("mfd: Add
simple regmap based I2C driver"), "If a device wants to use this as its
MFD core driver, it has to add an individual compatible string."

The QIXIS FPGA on the LS1028A-QDS boards has a similar purpose to the
Kontron SL28 CPLD: it deals with board power-on reset timing, muxing,
etc.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 drivers/mfd/simple-mfd-i2c.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c
index 51536691ad9d..fee709fed97a 100644
--- a/drivers/mfd/simple-mfd-i2c.c
+++ b/drivers/mfd/simple-mfd-i2c.c
@@ -63,6 +63,7 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c)
 }
 
 static const struct of_device_id simple_mfd_i2c_of_match[] = {
+	{ .compatible = "fsl,ls1028a-qds-qixis-i2c" },
 	{ .compatible = "kontron,sl28cpld" },
 	{}
 };
-- 
2.25.1



From vladimir.oltean at nxp.com  Thu Jan 27 09:21:04 2022
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Thu, 27 Jan 2022 19:21:04 +0200
Subject: [PATCH 2/3] dt-bindings: mfd: add "fsl,
 ls1028a-qds-qixis-i2c" compatible to sl28cpld
In-Reply-To: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
References: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
Message-ID: <20220127172105.4085950-3-vladimir.oltean@nxp.com>

The LS1028A-QDS QIXIS FPGA has no problem working with the
simple-mfd-i2c.c driver, so extend the list of compatible strings to
include that part.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml b/Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml
index eb3b43547cb6..8c1216eb36ee 100644
--- a/Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml
+++ b/Documentation/devicetree/bindings/mfd/kontron,sl28cpld.yaml
@@ -16,7 +16,9 @@ description: |
 
 properties:
   compatible:
-    const: kontron,sl28cpld
+    enum:
+      - fsl,ls1028a-qds-qixis-i2c
+      - kontron,sl28cpld
 
   reg:
     description:
-- 
2.25.1



From vladimir.oltean at nxp.com  Thu Jan 27 09:21:05 2022
From: vladimir.oltean at nxp.com (Vladimir Oltean)
Date: Thu, 27 Jan 2022 19:21:05 +0200
Subject: [PATCH 3/3] arm64: dts: ls1028a-qds: make the QIXIS CPLD use the
 simple-mfd-i2c.c driver
In-Reply-To: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
References: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
Message-ID: <20220127172105.4085950-4-vladimir.oltean@nxp.com>

The MDIO mux on the LS1028A-QDS never worked in mainline. The device
tree was submitted as-is, and there is a downstream driver for the QIXIS
FPGA:
https://source.codeaurora.org/external/qoriq/qoriq-components/linux/tree/drivers/soc/fsl/qixis_ctrl.c?h=lf-5.10.72-2.2.0

That driver is very similar to the already existing drivers/mfd/simple-mfd-i2c.c,
and the hardware works with the simple-mfd-i2c driver, so there isn't
any reason to upstream the other one.

This change adapts the compatible string and child node format of the
FPGA node, so that the simple-mfd-i2c driver accepts it.

Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
index 177bc1405f0f..6bd58fd9c90f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
@@ -314,17 +314,18 @@ sgtl5000: audio-codec at a {
 	};
 
 	fpga at 66 {
-		compatible = "fsl,ls1028aqds-fpga", "fsl,fpga-qixis-i2c",
-			     "simple-mfd";
+		compatible = "fsl,ls1028a-qds-qixis-i2c";
 		reg = <0x66>;
+		#address-cells = <1>;
+		#size-cells = <0>;
 
-		mux: mux-controller {
+		mux: mux-controller at 54 {
 			compatible = "reg-mux";
+			reg = <0x54>;
 			#mux-control-cells = <1>;
 			mux-reg-masks = <0x54 0xf0>; /* 0: reg 0x54, bits 7:4 */
 		};
 	};
-
 };
 
 &i2c1 {
-- 
2.25.1



From maz at kernel.org  Thu Jan 27 09:22:48 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 17:22:48 +0000
Subject: [PATCH v5 17/69] KVM: arm64: nv: Add non-VHE-EL2->EL1 translation
 helpers
In-Reply-To: <YelM4PNEjbxYkpZ3@monolith.localdoman>
References: <20211129200150.351436-1-maz@kernel.org>
 <20211129200150.351436-18-maz@kernel.org>
 <YelM4PNEjbxYkpZ3@monolith.localdoman>
Message-ID: <87tudp5c0n.wl-maz@kernel.org>

On Thu, 20 Jan 2022 11:52:00 +0000,
Alexandru Elisei <alexandru.elisei at arm.com> wrote:
> 
> Hi Marc,
> 
> On Mon, Nov 29, 2021 at 08:00:58PM +0000, Marc Zyngier wrote:
> > Some EL2 system registers immediately affect the current execution
> > of the system, so we need to use their respective EL1 counterparts.
> > For this we need to define a mapping between the two. In general,
> > this only affects non-VHE guest hypervisors, as VHE system registers
> > are compatible with the EL1 counterparts.
> > 
> > These helpers will get used in subsequent patches.
> > 
> > Co-developed-by: Andre Przywara <andre.przywara at arm.com>
> > Signed-off-by: Andre Przywara <andre.przywara at arm.com>
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> > ---
> >  arch/arm64/include/asm/kvm_nested.h | 50 +++++++++++++++++++++++++++++
> >  1 file changed, 50 insertions(+)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
> > index 1028ac65a897..67a2c0d05233 100644
> > --- a/arch/arm64/include/asm/kvm_nested.h
> > +++ b/arch/arm64/include/asm/kvm_nested.h
> > @@ -2,6 +2,7 @@
> >  #ifndef __ARM64_KVM_NESTED_H
> >  #define __ARM64_KVM_NESTED_H
> >  
> > +#include <linux/bitfield.h>
> >  #include <linux/kvm_host.h>
> >  
> >  static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
> > @@ -11,4 +12,53 @@ static inline bool nested_virt_in_use(const struct kvm_vcpu *vcpu)
> >  		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
> >  }
> >  
> > +/* Translation helpers from non-VHE EL2 to EL1 */
> > +static inline u64 tcr_el2_ips_to_tcr_el1_ps(u64 tcr_el2)
> 
> When E2H = 0, there is no IPS field in TCR_EL2, but there is a PS field.
> And for TCR_EL1, there is no PS field, but there is an IPS field. Maybe
> tcr_el2_ps_to_tcr_el1_ips() would be more precise, and would also match the
> field defines used by the function?

Yes, good point. Done.

> 
> > +{
> > +	return (u64)FIELD_GET(TCR_EL2_PS_MASK, tcr_el2) << TCR_IPS_SHIFT;
> > +}
> > +
> > +static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
> > +{
> > +	return TCR_EPD1_MASK |				/* disable TTBR1_EL1 */
> > +	       ((tcr & TCR_EL2_TBI) ? TCR_TBI0 : 0) |
> > +	       tcr_el2_ips_to_tcr_el1_ps(tcr) |
> > +	       (tcr & TCR_EL2_TG0_MASK) |
> > +	       (tcr & TCR_EL2_ORGN0_MASK) |
> > +	       (tcr & TCR_EL2_IRGN0_MASK) |
> > +	       (tcr & TCR_EL2_T0SZ_MASK);
> 
> There are a few fields in TCR_EL2 which have a corresponding field in
> TCR_EL1, when E2H = 0: HPD -> HPD0 (hierarchical permissions toggle), HA
> and HD (hardware management of dirty bit and access flag), DS (when
> FEAT_LPA2), and probably others. Why do we not also translate them? Is it
> because we hide the feature they depend on (FEAT_HPDS, FEAT_HAFBDS, etc) in
> the guest ID registers? Is it something else?

We do hide the features, and for some of them they simply cannot be
implemented. HA/HD are pretty good example of how the architecture is
broken in this respect (the PT update happens in the shadow, while the
guest can only look at its own copy).

>
> > +}
> > +
> > +static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
> > +{
> > +	u64 cpacr_el1 = 0;
> > +
> > +	if (!(cptr_el2 & CPTR_EL2_TFP))
> > +		cpacr_el1 |= CPACR_EL1_FPEN;
> > +	if (cptr_el2 & CPTR_EL2_TTA)
> > +		cpacr_el1 |= CPACR_EL1_TTA;
> > +	if (!(cptr_el2 & CPTR_EL2_TZ))
> > +		cpacr_el1 |= CPACR_EL1_ZEN;
> > +
> > +	return cpacr_el1;
> 
> Nitpick: it would make comparing against the architecture easier if the
> fields were checked in the order they were definied in the architecture. So
> first check the TTA bit, then TFP and lastly TZ.

You are easy to please! ;-) Done.

> 
> I checked the field definitions for CPTR_EL2 and the above looks correct to
> me, as TFP, TTA and TZ were the only fields which affect EL2; I also
> checked that the values in CPACR_EL1 are set correctly to mirror the
> CPTR_EL2 settings.
> 
> > +}
> > +
> > +static inline u64 translate_sctlr_el2_to_sctlr_el1(u64 sctlr)
> > +{
> > +	/* Bit 20 is RES1 in SCTLR_EL1, but RES0 in SCTLR_EL2 */
> > +	return sctlr | BIT(20);
> 
> Bits 8 and 7 in SCTLR_EL2 are RES0 when E2H,TGE != {1,1}, but they are RES1
> in SCTLR_EL1 if EL0 is not capable of using AArch32. Shouldn't we also set
> them?
> 
> Bit 5 in SCTLR_EL2 is RES1 when E2H,TGE != {1,1}, but it is RES0 in
> SCTLR_EL1 if EL0 is not capable of using AArch32. Shouldn't we clear
> it?

I actually reworked all of that as such:

static inline u64 translate_sctlr_el2_to_sctlr_el1(u64 val)
{
	/* Only preserve the minimal set of bits we support */
	val &= (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | SCTLR_ELx_SA |
		SCTLR_ELx_I | SCTLR_ELx_IESB | SCTLR_ELx_WXN | SCTLR_ELx_EE);
	val |= SCTLR_EL1_RES1;

	return val;
}

> > +}
> > +
> > +static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
> > +{
> > +	/* Force ASID to 0 (ASID 0 or RES0) */
> 
> That got me confused at first, until I realized that the first ASID refers
> to the ASID field of the register, and the second ASID to the translation
> table property. Might be more helpful if the comment was simply "Clear the
> ASID field" or something like that.

Done.

> 
> > +	return ttbr0 & ~GENMASK_ULL(63, 48);
> > +}
> > +
> > +static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
> > +{
> > +	return ((FIELD_GET(CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN, cnthctl) << 10) |
> 
> I don't understand why those two bits are left shifted by 10, the result is
> 0x3 << 10 and CNTKCTL_EL[16:10] is RES0.
> 
> > +		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));
> 
> CNTKCTL_EL1.{EVNTI,EVNTDIR,EVNTEN} refer to CNT*V*CT_EL0,
> CNTHCTL_EL2.{EVNTI,EVNTDIR,EVNTEN} refer to CNT*P*CT_EL0. I don't
> understand why they are treated as equivalent.
> 
> I get the feeling I'm misunderstanding something about this
> function.

It's a classic one. Remember that we are running VHE, and remapping a
nVHE view of CNTHCTL_EL2 into the VHE view *for the guest*, and that
these things are completely shifted around (it has the CNTKCTL_EL1
format).

For example, on nVHE, CNTHCTL_EL2.EL1PCTEN is bit 0. On nVHE, this is
bit 10. That's why we have this shift, and that you now need some
paracetamol.

You can also look at the way we deal with the same stuff in
kvm_timer_init_vhe().

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


From ceggers at arri.de  Thu Jan 27 09:23:13 2022
From: ceggers at arri.de (Christian Eggers)
Date: Thu, 27 Jan 2022 18:23:13 +0100
Subject: PROBLEM: encryption test failures since "crypto: mxs-dcp - Use
 sg_mapping_iter to copy data"
Message-ID: <2126453.Icojqenx9y@localhost.localdomain>

SoC: i.MX6ULL

After upgrading from v5.10.65-rt53 to v5.10.73-rt54 I get two additional messages on boot:

...
[    3.786333] alg: skcipher: ecb-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
[    3.789020] alg: skcipher: cbc-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
[    3.793741] mxs-dcp 2280000.crypto: mxs_dcp: initialized
..

After reverting the commit

2e6d793e1bf0 ("crypto: mxs-dcp - Use sg_mapping_iter to copy data")

the error messages above disappear again.

regards
Christian

[3.] Keywords: mxc-dcp, crypto manager self tests
[4.] Kernel information
[4.1.] Kernel version (from /proc/version):
Linux version 5.10.73-rt54+ (eggers at localhost.localdomain) (arm-poky-linux-gnueabi-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) #19 PREEMPT_RT Thu Jan 27 17:56:20 CET 2022

[4.2.] Kernel .config file:
[5.] Most recent kernel version which did not have the bug: 5.10.65-rt53
[8.] Environment
[8.1.] Software (add the output of the ver_linux script here)
n/a (embedded system, kernel cross compiled)

[8.2.] Processor information (from /proc/cpuinfo):
processor       : 0
model name      : ARMv7 Processor rev 5 (v7l)
BogoMIPS        : 16.00
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x0
CPU part        : 0xc07
CPU revision    : 5

Hardware        : Freescale i.MX6 Ultralite (Device Tree)
Revision        : 0000
Serial          : 0000000000000000





From sean.anderson at seco.com  Thu Jan 27 09:31:48 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 27 Jan 2022 12:31:48 -0500
Subject: PROBLEM: encryption test failures since "crypto: mxs-dcp - Use
 sg_mapping_iter to copy data"
In-Reply-To: <2126453.Icojqenx9y@localhost.localdomain>
References: <2126453.Icojqenx9y@localhost.localdomain>
Message-ID: <414858de-f279-c5ce-83ca-5c28d6c847b1@seco.com>

Hi Christian,

On 1/27/22 12:23 PM, Christian Eggers wrote:
> SoC: i.MX6ULL
> 
> After upgrading from v5.10.65-rt53 to v5.10.73-rt54 I get two additional messages on boot:
> 
> ...
> [ 3.786333] alg: skcipher: ecb-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> [ 3.789020] alg: skcipher: cbc-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> [ 3.793741] mxs-dcp 2280000.crypto: mxs_dcp: initialized
> ..
> 
> After reverting the commit
> 
> 2e6d793e1bf0 ("crypto: mxs-dcp - Use sg_mapping_iter to copy data")
> 
> the error messages above disappear again.

Can you try applying the patch in [1] on top of your revert?

--Sean

[1] https://lore.kernel.org/linux-arm-kernel/20210701185638.3437487-1-sean.anderson at seco.com/


From robert.hancock at calian.com  Thu Jan 27 09:50:13 2022
From: robert.hancock at calian.com (Robert Hancock)
Date: Thu, 27 Jan 2022 11:50:13 -0600
Subject: [PATCH] i2c: xiic: Make bus names unique
Message-ID: <20220127175013.3689724-1-robert.hancock@calian.com>

This driver is for an FPGA logic core, so there can be arbitrarily many
instances of the bus on a given system. Previously all of the I2C bus
names were "xiic-i2c" which caused issues with lm_sensors when trying to
map human-readable names to sensor inputs because it could not properly
distinguish the busses, for example. Append the platform device name to
the I2C bus name so it is unique between different instances.

Fixes: e1d5b6598cdc ("i2c: Add support for Xilinx XPS IIC Bus Interface")
Signed-off-by: Robert Hancock <robert.hancock at calian.com>
---
 drivers/i2c/busses/i2c-xiic.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index eb789cfb9973..ffefe3c482e9 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -734,7 +734,6 @@ static const struct i2c_adapter_quirks xiic_quirks = {
 
 static const struct i2c_adapter xiic_adapter = {
 	.owner = THIS_MODULE,
-	.name = DRIVER_NAME,
 	.class = I2C_CLASS_DEPRECATED,
 	.algo = &xiic_algorithm,
 	.quirks = &xiic_quirks,
@@ -771,6 +770,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)
 	i2c_set_adapdata(&i2c->adap, i2c);
 	i2c->adap.dev.parent = &pdev->dev;
 	i2c->adap.dev.of_node = pdev->dev.of_node;
+	snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+		 DRIVER_NAME " %s", pdev->name);
 
 	mutex_init(&i2c->lock);
 
-- 
2.31.1



From ceggers at arri.de  Thu Jan 27 10:09:15 2022
From: ceggers at arri.de (Christian Eggers)
Date: Thu, 27 Jan 2022 19:09:15 +0100
Subject: PROBLEM: encryption test failures since "crypto: mxs-dcp - Use
 sg_mapping_iter to copy data"
In-Reply-To: <414858de-f279-c5ce-83ca-5c28d6c847b1@seco.com>
References: <2126453.Icojqenx9y@localhost.localdomain>
 <414858de-f279-c5ce-83ca-5c28d6c847b1@seco.com>
Message-ID: <2382032.jE0xQCEvom@localhost.localdomain>

Hi Sean,

On Thursday, 27 January 2022, 18:31:48 CET, Sean Anderson wrote:
> Hi Christian,
> 
> On 1/27/22 12:23 PM, Christian Eggers wrote:
> > SoC: i.MX6ULL
> > 
> > After upgrading from v5.10.65-rt53 to v5.10.73-rt54 I get two additional messages on boot:
> > 
> > ...
> > [ 3.786333] alg: skcipher: ecb-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> > [ 3.789020] alg: skcipher: cbc-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> > [ 3.793741] mxs-dcp 2280000.crypto: mxs_dcp: initialized
> > ..
> > 
> > After reverting the commit
> > 
> > 2e6d793e1bf0 ("crypto: mxs-dcp - Use sg_mapping_iter to copy data")
> > 
> > the error messages above disappear again.
> 
> Can you try applying the patch in [1] on top of your revert?
with the patch from [1] on top of the reverted 2e6d793e1bf0 there are
no error messages on boot.

regards
Christian

> 
> [1] https://lore.kernel.org/linux-arm-kernel/20210701185638.3437487-1-sean.anderson at seco.com/
> 






From mathieu.poirier at linaro.org  Thu Jan 27 10:15:31 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Jan 2022 11:15:31 -0700
Subject: [PATCH v2 2/9] Coresight: Add coresight TPDM source driver
In-Reply-To: <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
References: <20211209141543.21314-1-quic_jinlmao@quicinc.com>
 <20211209141543.21314-3-quic_jinlmao@quicinc.com>
 <20211214185714.GB1549991@p14s>
 <85ad17fb-c885-831d-d841-4c6f10920355@quicinc.com>
 <CAJ9a7Vh2d79Ro72ZDsbQSVS8VrH3c+X+xo8849yGS4Z73+yq_w@mail.gmail.com>
 <20211216190223.GA78825@p14s>
 <2703bf83-3a87-e69f-2392-7e0568e91712@quicinc.com>
Message-ID: <20220127181531.GA2189869@p14s>

Hi Jinlong,

On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
> 
> Good Day.
> 
> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > [...]
> > 
> > > > > > +
> > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > +{
> > > > > > +    static int traceid = TPDM_TRACE_ID_START;
> > > > > > +
> > > > > > +    drvdata->traceid = traceid++;
> > > > > > +}
> > > > > I have been specific on how to properly do this in the last revision.  Given the
> > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > > 
> > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > process it before the holidays.
> > > > > 
> > > > > Thanks,
> > > > > Mathieu
> > > > Hi Mathieu,
> > > > 
> > > > Sorry, not addressed your previous comments here.
> > > > 
> > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > Architecture specification v3.0
> > > 
> > Correct
> > 
> > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > our internal device. About 80 ids are already used.
> > > > 
> > > > Some components have fixed trace id in HW. If we use functions below to
> > > > count the trace id, there will be conflict to other components.
> > > > 
> > > > Can we use 1-15 for etm trace ids  and 16 - 127 for other coresight
> > > > components ? And handle trace ids in its' own driver ?
> > > > 
> > > This will limit systems to 15 cores - some have more!
> > > 
> > Correct
> > 
> > > > static inline int coresight_get_system_trace_id(int id)
> > > > {
> > > >           /* Start system IDs above the highest per CPU trace ID. */
> > > >           return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > }
> > Looking at my own suggestion again this won't work since it returns the same traceID
> > when called multiple times.
> > 
> > For this patchset and _without_ taking into account internal devices that have
> > their traceID set in HW:
> > 
> > 1. Define a bitmask that is 7 bit wide.
> Should it be a 128 bit wide bitmask? (0--127)?
> > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > first available bit after cpumask_last(cpu_possible_mask) + 1.
> 
> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> Return the first zero bit position as the trace id and set the bit.

Please ignore my email from January 26th and proceed exactly as you stated
above.

I had conversations with Suzuki and Mike and providing an appropriate fix for this
issue needs more investigation. 

Aplogies for the flip-flopping, as I said earlier this is a complex problem
we've been restling with for quite some time now.

Thanks,
Mathieu

> 
> > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > clears the bit in the mask corresponding to @id.
> > 
> > For now that should work.
> > 
> > > > static inline int coresight_get_trace_id(int cpu)
> > > > {
> > > >       /*
> > > >        * A trace ID of value 0 is invalid, so let's start at some
> > > >        * random value that fits in 7 bits and go from there.  Since
> > > >        * the common convention is to have data trace IDs be I(N) + 1,
> > > >        * set instruction trace IDs as a function of the CPU number.
> > > >        */
> > > >       return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > }
> > > > 
> > > This fixed relationship between cpu and trace ID is used in the perf
> > > tooling to populate the elements in the perf.data file to correctly
> > > allow association between CPU and trace data, and thus allow correct
> > > trace decode.
> > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > perf header - theoretically we should be able to change the allocation scheme
> > without impacting the decoding process.
> > 
> > > It should be possible to create another more dynamic mapping scheme -
> > > but this must include a way to support the perf requirements too.
> > > 
> > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > For now what I have suggested above should be sufficient to provide an
> > in-between solution that doesn't hold back this patchset.
> > 
> > That being said, we need to start thinking about the best way to do this.  I
> > will put a patchset together in the new year that aims in that direction.
> > 
> > > Regards
> > > 
> > > Mike
> > > 
> > > > Thanks
> > > > 
> > > > Jinlong Mao
> > > > 
> > > > > > +
> > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > +{
> > > > > > +    struct device *dev = &adev->dev;
> > > > > > +    struct coresight_platform_data *pdata;
> > > > > > +    struct tpdm_drvdata *drvdata;
> > > > > > +    struct coresight_desc desc = { 0 };
> > > > > > +
> > > > > > +    desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > +    if (!desc.name)
> > > > > > +            return -ENOMEM;
> > > > > > +    pdata = coresight_get_platform_data(dev);
> > > > > > +    if (IS_ERR(pdata))
> > > > > > +            return PTR_ERR(pdata);
> > > > > > +    adev->dev.platform_data = pdata;
> > > > > > +
> > > > > > +    drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > +    if (!drvdata)
> > > > > > +            return -ENOMEM;
> > > > > > +    drvdata->dev = &adev->dev;
> > > > > > +    dev_set_drvdata(dev, drvdata);
> > > > > > +
> > > > > > +    drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > +    if (!drvdata->base)
> > > > > > +            return -ENOMEM;
> > > > > > +
> > > > > > +    mutex_init(&drvdata->lock);
> > > > > > +
> > > > > > +    desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > +    desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > +    desc.ops = &tpdm_cs_ops;
> > > > > > +    desc.pdata = adev->dev.platform_data;
> > > > > > +    desc.dev = &adev->dev;
> > > > > > +    drvdata->csdev = coresight_register(&desc);
> > > > > > +    if (IS_ERR(drvdata->csdev))
> > > > > > +            return PTR_ERR(drvdata->csdev);
> > > > > > +
> > > > > > +    tpdm_init_default_data(drvdata);
> > > > > > +    pm_runtime_put(&adev->dev);
> > > > > > +
> > > > > > +    return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > +{
> > > > > > +    struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > +
> > > > > > +    coresight_unregister(drvdata->csdev);
> > > > > > +}
> > > > > > +
> > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > +    {
> > > > > > +            .id = 0x000f0e00,
> > > > > > +            .mask = 0x000fff00,
> > > > > > +    },
> > > > > > +    { 0, 0},
> > > > > > +};
> > > > > > +
> > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > +    .drv = {
> > > > > > +            .name   = "coresight-tpdm",
> > > > > > +            .owner  = THIS_MODULE,
> > > > > > +            .suppress_bind_attrs = true,
> > > > > > +    },
> > > > > > +    .probe          = tpdm_probe,
> > > > > > +    .id_table       = tpdm_ids,
> > > > > > +};
> > > > > > +
> > > > > > +module_amba_driver(tpdm_driver);
> > > > > > +
> > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > new file mode 100644
> > > > > > index 000000000000..980ae90ff1c8
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > @@ -0,0 +1,31 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > +/*
> > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > + */
> > > > > > +
> > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +
> > > > > > +/* Default value of the traceid */
> > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > +
> > > > > > +/**
> > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > + * @base:       memory mapped base address for this component.
> > > > > > + * @dev:        The device entity associated to this component.
> > > > > > + * @csdev:      component vitals needed by the framework.
> > > > > > + * @lock:       lock for the enable value.
> > > > > > + * @enable:     enable status of the component.
> > > > > > + * @traceid:    value of the current ID for this component.
> > > > > > + */
> > > > > > +
> > > > > > +struct tpdm_drvdata {
> > > > > > +    void __iomem            *base;
> > > > > > +    struct device           *dev;
> > > > > > +    struct coresight_device *csdev;
> > > > > > +    struct mutex            lock;
> > > > > > +    bool                    enable;
> > > > > > +    int                     traceid;
> > > > > > +};
> > > > > > +
> > > > > > +#endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > --- a/include/linux/coresight.h
> > > > > > +++ b/include/linux/coresight.h
> > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > >       CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > +    CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > >    };
> > > > > > 
> > > > > >    enum coresight_dev_subtype_helper {
> > > > > > --
> > > > > > 2.17.1
> > > > > > 
> > > 
> > > 
> > > -- 
> > > Mike Leach
> > > Principal Engineer, ARM Ltd.
> > > Manchester Design Centre. UK


From mark.rutland at arm.com  Thu Jan 27 10:23:28 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Thu, 27 Jan 2022 18:23:28 +0000
Subject: [PATCH] ftrace: Have architectures opt-in for mcount build time
 sorting
In-Reply-To: <20220127114249.03b1b52b@gandalf.local.home>
References: <20220127114249.03b1b52b@gandalf.local.home>
Message-ID: <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N>

On Thu, Jan 27, 2022 at 11:42:49AM -0500, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt at goodmis.org>
> 
> First S390 complained that the sorting of the mcount sections at build
> time caused the kernel to crash on their architecture. Now PowerPC is
> complaining about it too. And also ARM64 appears to be having issues.
> 
> It may be necessary to also update the relocation table for the values
> in the mcount table. Not only do we have to sort the table, but also
> update the relocations that may be applied to the items in the table.
> 
> If the system is not relocatable, then it is fine to sort, but if it is,
> some architectures may have issues (although x86 does not as it shifts all
> addresses the same).
> 
> Add a HAVE_BUILDTIME_MCOUNT_SORT that an architecture can set to say it is
> safe to do the sorting at build time.
> 
> Also update the config to compile in build time sorting in the sorttable
> code in scripts/ to depend on CONFIG_BUILDTIME_MCOUNT_SORT.
> 
> Link: https://lore.kernel.org/all/944D10DA-8200-4BA9-8D0A-3BED9AA99F82 at linux.ibm.com/
> 
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Yinan Liu <yinan at linux.alibaba.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Kees Cook <keescook at chromium.org>
> Cc: linuxppc-dev at lists.ozlabs.org
> Reported-by: Sachin Sant <sachinp at linux.ibm.com>
> Tested-by: Sachin Sant <sachinp at linux.ibm.com>
> Fixes: 72b3942a173c ("scripts: ftrace - move the sort-processing in ftrace_init")
> Signed-off-by: Steven Rostedt (Google) <rostedt at goodmis.org>

Thanks for this; the rationale and patch makes sense to me. As previously, I
understand that:

* For arch/arm, the build-time sort should be safe as the 32-bit kernel isn't
  virtually relocatable, and so the sort affects the final values, and will not
  be clobbered later.

* For arch/x86, the build time sort should be safe as the mcount_loc will be
  initialazed with values consistent with the default load address, and the
  boot-time relocation will add the same offset to all values, so there's no
  need to sort the relocs.

So enabling this for arch/arm and arch/x86 makes sense to me.

Similarly, I understand that for arm64 the build-time sort isn't sound due to
not adjusting the relocations, and so it needs to be disabled there (for now at
least).

I gave this patch a spin on arm64 atop v5.17-rc1, using GCC 11.1.0 from the
kernel.org crosstool page:

  https://mirrors.edge.kernel.org/pub/tools/crosstool/

... with this applied, I'm no longer seeing a number of ftrace selftest
failures and ftrace internal bugs I previously reported at:

  https://lore.kernel.org/all/YfKGKWW5UfZ15kCW at FVFF77S0Q05N/

It looks like there's a trivial bit of whitespace damage in the patch (noted
below), but regardless:

  Reviewed-by: Mark Rutland <mark.rutland at arm.com>
  Tested-by: Mark Rutland <mark.rutlad at arm.com> [arm64]



As a heads-up, with this issue out of the way I'm hitting some unrelated issues
when running the ftrace selftests on arm64, which I'll look into. Quick summary
on those below, but I'll start new threads once I've got more detail.

* The duplicate events test seems to fail consistently:

  [15] Generic dynamic event - check if duplicate events are caught       [FAIL]

* I intermittently see a hang when running the tests. I previously hit that
  when originally trying to bisect this issue (and IIRC that bisected down to
  some RCU changes, but I need to re-run that). When the tests hang I
  magic-srsrq + L tells me:

  [  271.938438] sysrq: Show Blocked State
  [  271.939245] task:ftracetest      state:D stack:    0 pid: 5687 ppid:  5627 flags:0x00000200
  [  271.940961] Call trace:
  [  271.941472]  __switch_to+0x104/0x160
  [  271.942213]  __schedule+0x2b0/0x6e0
  [  271.942933]  schedule+0x5c/0xf0
  [  271.943586]  schedule_timeout+0x184/0x1c4
  [  271.944410]  wait_for_completion+0x8c/0x12c
  [  271.945274]  __wait_rcu_gp+0x184/0x190
  [  271.946047]  synchronize_rcu_tasks_rude+0x48/0x70
  [  271.947007]  update_ftrace_function+0xa4/0xec
  [  271.947897]  __unregister_ftrace_function+0xa4/0xf0
  [  271.948898]  unregister_ftrace_function+0x34/0x70
  [  271.949857]  wakeup_tracer_reset+0x4c/0x100
  [  271.950713]  tracing_set_tracer+0xd0/0x2b0
  [  271.951552]  tracing_set_trace_write+0xe8/0x150
  [  271.952477]  vfs_write+0xfc/0x284
  [  271.953171]  ksys_write+0x7c/0x110
  [  271.953874]  __arm64_sys_write+0x2c/0x40
  [  271.954678]  invoke_syscall+0x5c/0x130
  [  271.955442]  el0_svc_common.constprop.0+0x108/0x130
  [  271.956435]  do_el0_svc+0x74/0x90
  [  271.957124]  el0_svc+0x2c/0x90
  [  271.957757]  el0t_64_sync_handler+0xa8/0x12c
  [  271.958629]  el0t_64_sync+0x1a0/0x1a4

> ---
>  arch/arm/Kconfig     | 1 +
>  arch/x86/Kconfig     | 1 +
>  kernel/trace/Kconfig | 8 +++++++-
>  scripts/Makefile     | 2 +-
>  4 files changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index c2724d986fa0..5256ebe57451 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -82,6 +82,7 @@ config ARM
>  	select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
>  	select HAVE_CONTEXT_TRACKING
>  	select HAVE_C_RECORDMCOUNT
> +	select HAVE_BUILDTIME_MCOUNT_SORT
>  	select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
>  	select HAVE_DMA_CONTIGUOUS if MMU
>  	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 7399327d1eff..46080dea5dba 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -186,6 +186,7 @@ config X86
>  	select HAVE_CONTEXT_TRACKING_OFFSTACK	if HAVE_CONTEXT_TRACKING
>  	select HAVE_C_RECORDMCOUNT
>  	select HAVE_OBJTOOL_MCOUNT		if STACK_VALIDATION
> +	select HAVE_BUILDTIME_MCOUNT_SORT
>  	select HAVE_DEBUG_KMEMLEAK
>  	select HAVE_DMA_CONTIGUOUS
>  	select HAVE_DYNAMIC_FTRACE
> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> index 752ed89a293b..7e5b92090faa 100644
> --- a/kernel/trace/Kconfig
> +++ b/kernel/trace/Kconfig
> @@ -70,10 +70,16 @@ config HAVE_C_RECORDMCOUNT
>  	help
>  	  C version of recordmcount available?
>  
> +config HAVE_BUILDTIME_MCOUNT_SORT
> +       bool
> +       help
> +         An architecture selects this if it sorts the mcount_loc section
> +	 at build time.

Whitespace damage here? The second line has a tab, the first doesn't.

Thanks,
Mark.

> +
>  config BUILDTIME_MCOUNT_SORT
>         bool
>         default y
> -       depends on BUILDTIME_TABLE_SORT && !S390
> +       depends on HAVE_BUILDTIME_MCOUNT_SORT
>         help
>           Sort the mcount_loc section at build time.
>  
> diff --git a/scripts/Makefile b/scripts/Makefile
> index b082d2f93357..cedc1f0e21d8 100644
> --- a/scripts/Makefile
> +++ b/scripts/Makefile
> @@ -32,7 +32,7 @@ HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
>  HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
>  endif
>  
> -ifdef CONFIG_DYNAMIC_FTRACE
> +ifdef CONFIG_BUILDTIME_MCOUNT_SORT
>  HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
>  endif
>  
> -- 
> 2.33.0
> 


From valentin.schneider at arm.com  Thu Jan 27 10:23:44 2022
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 27 Jan 2022 18:23:44 +0000
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <YfJu3Z9wKOAjLuad@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de> <87czq573et.mognet@arm.com>
 <YfF9I5PcZJA5532B@linutronix.de> <87r18u2wr8.mognet@arm.com>
 <YfJu3Z9wKOAjLuad@linutronix.de>
Message-ID: <87o83x2g27.mognet@arm.com>

On 27/01/22 11:07, Sebastian Andrzej Siewior wrote:
> On 2022-01-26 18:10:51 [+0000], Valentin Schneider wrote:
>> > | 2021-08-11 21:13 +0100 Valentin Schneider    ? sched: Introduce migratable()
>> > | 2021-08-11 21:13 +0100 Valentin Schneider    ? arm64: mm: Make arch_faults_on_old_pte() check for migratability
> ?
>> Heh, had forgotten about those - I'm happy to repost with the
>> s/migratable/is_migratable/. I also need to go back to those splats I got
>> on my emag and fix the PMU/GPIO warnings...
>
> Now that I look at it gain, you might want to drop #1 and then #2 would
> switch to cant_migrate(). This might work?
>

Wasn't aware of cant_migrate(), that does look even better. Lemme give it a shot.

> Sebastian


From corbet at lwn.net  Thu Jan 27 10:33:36 2022
From: corbet at lwn.net (Jonathan Corbet)
Date: Thu, 27 Jan 2022 11:33:36 -0700
Subject: [PATCH v4 1/2] Documentation: Fill the gaps about entry/noinstr
 constraints
In-Reply-To: <20220110105044.94423-1-nsaenzju@redhat.com>
References: <20220110105044.94423-1-nsaenzju@redhat.com>
Message-ID: <877dalrptr.fsf@meer.lwn.net>

Nicolas Saenz Julienne <nsaenzju at redhat.com> writes:

> From: Thomas Gleixner <tglx at linutronix.de>
>
> The entry/exit handling for exceptions, interrupts, syscalls and KVM is
> not really documented except for some comments.
>
> Fill the gaps.
>
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de
> Co-developed-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzju at redhat.com>
> Reviewed-by: Mark Rutland <mark.rutland at arm.com>
> Reviewed-by: Paul E. McKenney <paulmck at kernel.org>
>
Both patches applied, thanks.

jon


From maz at kernel.org  Thu Jan 27 10:34:12 2022
From: maz at kernel.org (Marc Zyngier)
Date: Thu, 27 Jan 2022 18:34:12 +0000
Subject: [PATCH 3/3] arm64: insn: Generate 64 bit mask immediates correctly
In-Reply-To: <20220127162127.2391947-4-james.morse@arm.com>
References: <20220127162127.2391947-1-james.morse@arm.com>
 <20220127162127.2391947-4-james.morse@arm.com>
Message-ID: <87sft958pn.wl-maz@kernel.org>

On Thu, 27 Jan 2022 16:21:27 +0000,
James Morse <james.morse at arm.com> wrote:
> 
> When the insn framework is used to encode an AND/ORR/EOR instruction,
> aarch64_encode_immediate() is used to pick the immr imms values.
> 
> If the immediate is a 64bit mask, with bit 63 set, and zeros in any
> of the upper 32 bits, the immr value is incorrectly calculated meaning
> the wrong mask is generated.
> For example, 0x8000000000000001 should have an immr of 1, but 32 is used,
> meaning the resulting mask is 0x0000000300000000.
> 
> It would appear eBPF is unable to hit these cases, as build_insn()'s
> imm value is a s32, so when used with BPF_ALU64, the sign-extended
> u64 immediate would always have all-1s or all-0s in the upper 32 bits.
> 
> KVM does not generate a va_mask with any of the top bits set as these
> VA wouldn't be usable with TTBR0_EL2.
> 
> This happens because the rotation is calculated from fls(~imm), which
> takes an unsigned int, but the immediate may be 64bit.
> 
> Use fls64() so the 64bit mask doesn't get truncated to a u32.
> 
> Signed-off-by: James Morse <james.morse at arm.com>
> ---
>  arch/arm64/lib/insn.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
> index 8888e407032f..90253af7e294 100644
> --- a/arch/arm64/lib/insn.c
> +++ b/arch/arm64/lib/insn.c
> @@ -1381,7 +1381,7 @@ static u32 aarch64_encode_immediate(u64 imm,
>  		 * Compute the rotation to get a continuous set of
>  		 * ones, with the first bit set at position 0
>  		 */
> -		ror = fls(~imm);
> +		ror = fls64(~imm);
>  	}
>  
>  	/*

Oh crap, not again... :-( Clearly, my initial test harness wasn't as
good as I thought. Out for morbid curiosity, how was this found?

Brown-paper-bag-for: Marc Zyngier <maz at kernel.org>
Acked-by: Marc Zyngier <maz at kernel.org>

	M.

-- 
Without deviation from the norm, progress is not possible.


From svens at linux.ibm.com  Thu Jan 27 10:42:35 2022
From: svens at linux.ibm.com (Sven Schnelle)
Date: Thu, 27 Jan 2022 19:42:35 +0100
Subject: ftrace hangs waiting for rcu (was: Re: [PATCH] ftrace: Have
 architectures opt-in for mcount build time sorting)
In-Reply-To: <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> (Mark Rutland's message of "Thu, 
 27 Jan 2022 18:23:28 +0000")
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N>
Message-ID: <yt9dy231yq90.fsf_-_@linux.ibm.com>

Hi Mark,

Mark Rutland <mark.rutland at arm.com> writes:

> * I intermittently see a hang when running the tests. I previously hit that
>   when originally trying to bisect this issue (and IIRC that bisected down to
>   some RCU changes, but I need to re-run that). When the tests hang I
>   magic-srsrq + L tells me:
>
>   [  271.938438] sysrq: Show Blocked State
>   [  271.939245] task:ftracetest      state:D stack:    0 pid: 5687 ppid:  5627 flags:0x00000200
>   [  271.940961] Call trace:
>   [  271.941472]  __switch_to+0x104/0x160
>   [  271.942213]  __schedule+0x2b0/0x6e0
>   [  271.942933]  schedule+0x5c/0xf0
>   [  271.943586]  schedule_timeout+0x184/0x1c4
>   [  271.944410]  wait_for_completion+0x8c/0x12c
>   [  271.945274]  __wait_rcu_gp+0x184/0x190
>   [  271.946047]  synchronize_rcu_tasks_rude+0x48/0x70
>   [  271.947007]  update_ftrace_function+0xa4/0xec
>   [  271.947897]  __unregister_ftrace_function+0xa4/0xf0
>   [  271.948898]  unregister_ftrace_function+0x34/0x70
>   [  271.949857]  wakeup_tracer_reset+0x4c/0x100
>   [  271.950713]  tracing_set_tracer+0xd0/0x2b0
>   [  271.951552]  tracing_set_trace_write+0xe8/0x150
>   [  271.952477]  vfs_write+0xfc/0x284
>   [  271.953171]  ksys_write+0x7c/0x110
>   [  271.953874]  __arm64_sys_write+0x2c/0x40
>   [  271.954678]  invoke_syscall+0x5c/0x130
>   [  271.955442]  el0_svc_common.constprop.0+0x108/0x130
>   [  271.956435]  do_el0_svc+0x74/0x90
>   [  271.957124]  el0_svc+0x2c/0x90
>   [  271.957757]  el0t_64_sync_handler+0xa8/0x12c
>   [  271.958629]  el0t_64_sync+0x1a0/0x1a4

that's interesting. On s390 i'm seeing the same problem in CI, but with
the startup ftrace tests. So that's likely not arm64 spacific.

On s390, the last messages from ftrace are [    5.663568] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    5.667099] futex hash table entries: 65536 (order: 12, 16777216 bytes, vmalloc)
[    5.739549] Running postponed tracer tests:
[    5.740662] Testing tracer function: PASSED
[    6.194635] Testing dynamic ftrace: PASSED
[    6.471213] Testing dynamic ftrace ops #1: 
[    6.558445] (1 0 1 0 0) 
[    6.558458] (1 1 2 0 0) 
[    6.699135] (2 1 3 0 764347) 
[    6.699252] (2 2 4 0 766466) 
[    6.759857] (3 2 4 0 1159604)
[..] hangs here

The backtrace looks like this, which is very similar to the one above:

crash> bt 1
PID: 1      TASK: 80e68100          CPU: 133  COMMAND: "swapper/0"
 #0 [380004df808] __schedule at cda39f0e
 #1 [380004df880] schedule at cda3a488
 #2 [380004df8b0] schedule_timeout at cda41ef6
 #3 [380004df978] wait_for_completion at cda3bd0a
 #4 [380004df9d8] __wait_rcu_gp at ccdddd92
 #5 [380004dfa30] synchronize_rcu_tasks_generic at ccdde0aa
 #6 [380004dfad8] ftrace_shutdown at cce7b050
 #7 [380004dfb18] unregister_ftrace_function at cce7b192
 #8 [380004dfb50] trace_selftest_ops at cda1e0fa
 #9 [380004dfba0] run_tracer_selftest at cda1e4f2
#10 [380004dfc00] trace_selftest_startup_function at ce74355c
#11 [380004dfc58] run_tracer_selftest at cda1e2fc
#12 [380004dfc98] init_trace_selftests at ce742d30
#13 [380004dfcd0] do_one_initcall at cccdca16
#14 [380004dfd68] do_initcalls at ce72e776
#15 [380004dfde0] kernel_init_freeable at ce72ea60
#16 [380004dfe50] kernel_init at cda333fe
#17 [380004dfe68] __ret_from_fork at cccdf920
#18 [380004dfe98] ret_from_fork at cda444ca

I didn't had success reproducing it so far, but it is good to know that
this also happens when running the ftrace testsuite.

I have several crashdumps, so i could try to pull out some information
if someone tells me what to look for.

Thanks,
Sven


From robin.murphy at arm.com  Thu Jan 27 10:43:33 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 27 Jan 2022 18:43:33 +0000
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <CAK8P3a0oaP8LzxX6TSYhmSV+s+5rjHeCRzQ-pXkMQvpGvrp_0Q@mail.gmail.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
 <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
 <CAK8P3a0oaP8LzxX6TSYhmSV+s+5rjHeCRzQ-pXkMQvpGvrp_0Q@mail.gmail.com>
Message-ID: <3e11270f-7014-4729-13cf-d9331d4bdec7@arm.com>

On 2022-01-27 14:52, Arnd Bergmann wrote:
> On Thu, Jan 27, 2022 at 1:39 PM Ard Biesheuvel <ardb at kernel.org> wrote:
>> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
>> occurs between a pair of AES instructions in aarch32 mode may corrupt
>> the ELR. The task will subsequently produce the wrong AES result.
> 
>> Fortunately, the only A72 that is known to be widely deployed with
>> 32-bit kernels and/or user space is the Raspberry Pi 4, which does not
>> implement the crypto extensions.
> 
> I have previously used Amazon EC2 A1 instances (using Graviton 1, Cortex-A72)
> to run Debian armhf and armel user space in chroot environments. No idea how
> common that is for production environments, but there is a good chance that
> actual users might use e.g. 32-bit docker images for Alpine Linux on the same
> machines.
> 
> There are also some early A57/A72 chips used in Android devices that may
> frequently run 32-bit applications, or even be limited to 32-bit
> kernels, see [1].
> Not sure how likely it is for any of them to get (a backport of) this
> patch though.

Isn't ChromeOS still notoriously shipping AArch32 userspace? Between 
Mediatek and Rockchip, both A57 and A72 are definitely playing on that 
stage.

I'd concur that 32-bit *kernel* on v8 is a bit of a specialist sport, 
especially these days. IIRC Exynos 5433 might have been one of the more 
common Android setups for that, but 2015 is now an eternity ago in phone 
years...

Robin.

> 
>          Arnd
> 
> [1] https://www.androidpolice.com/2020/01/14/nvidias-shield-tv-dongle-can-only-run-32-bit-apps-but-you-probably-dont-need-to-panic/
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From broonie at kernel.org  Thu Jan 27 10:55:00 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 18:55:00 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfLDkoihLFnixAaQ@FVFF77S0Q05N>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk> <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
 <YfA3D3c+lOyybNT3@sirena.org.uk> <YfLDkoihLFnixAaQ@FVFF77S0Q05N>
Message-ID: <YfLqhKf4yYGVK8Do@sirena.org.uk>

On Thu, Jan 27, 2022 at 04:08:50PM +0000, Mark Rutland wrote:
> On Tue, Jan 25, 2022 at 05:44:47PM +0000, Mark Brown wrote:
> > On Tue, Jan 25, 2022 at 04:33:39PM +0000, Mark Rutland wrote:
> > > On Tue, Jan 25, 2022 at 03:59:38PM +0000, Mark Brown wrote:

> > > a) Use <register>_<field>_<valuename> definition, as here.

> > > b) Use <register>_<field>_MASK, and add comments at each usage as to why we use
> > >    a mask as a value, to explain why that isn't a bug.

> > > c) Have both <register>_<field>_MASK and some value definition, and use some
> > >    insertion helper to insert the value.

> > > ... and I went with (a) because it was the simplest.

> > > Is there a problem with this?

> > My concern is continuity of the enumeration algorithm between the
> > various implementations we have, it's something we're not currently
> > great with and this creates a separation between the kernel and the boot
> > wrapper implementations.  There's no change in what's actually being
> > done but it creates some additional effort to figure out why we're
> > setting a maximum here and not trying to set all the bits as we do in
> > the kernel.

> TBH, I'd argue if we're setting those bits in the kernel it's probably a bug,
> because we don't know *exactly* what effect they'll have when allocated in the
> future.

My comments there are related purely to the renaming of the constant,
not to the narrowing of the bitmask which is less of an issue.
Basically avoiding the question "why is that a maximum and not a mask"
and if there's limits on the valid values that are more restrictive than
the representable values.

The ideal thing for the boot wrapper would be option (c) with either a
configuration option to set the maximum to something lower than all
bits, unless someone was unduly enthusiastic and wanted to have an all
CPUs enumeration algorithm, but both are probably more trouble than it's
worth.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220127/a38b1325/attachment.sig>

From broonie at kernel.org  Thu Jan 27 11:03:23 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:03:23 +0000
Subject: [PATCH] arm64/mte: Clarify mode reported by PR_GET_TAGGED_ADDR_CTRL
Message-ID: <20220127190324.660405-1-broonie@kernel.org>

With the current wording readers might infer that PR_GET_TAGGED_ADDR_CTRL
will report the mode currently active in the thread however this is not the
actual behaviour, instead all modes currently selected by the process will
be reported with the mode used depending on the combination of the
requested modes and the default set for the current CPU. This has been the
case since 433c38f40f6a81 ("arm64: mte: change ASYNC and SYNC TCF settings
into bitfields"), before that we did not allow more than one mode to be
requested simultaneously.

Update the documentation to more clearly reflect current behaviour.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/memory-tagging-extension.rst | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
index 7b99c8f428eb..a0ab2f65b235 100644
--- a/Documentation/arm64/memory-tagging-extension.rst
+++ b/Documentation/arm64/memory-tagging-extension.rst
@@ -91,8 +91,9 @@ mode is specified, the program will run in that mode. If multiple
 modes are specified, the mode is selected as described in the "Per-CPU
 preferred tag checking modes" section below.
 
-The current tag check fault mode can be read using the
-``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call.
+The current tag check fault configuration can be read using the
+``prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)`` system call. If
+multiple modes were requested then all will be reported.
 
 Tag checking can also be disabled for a user thread by setting the
 ``PSTATE.TCO`` bit with ``MSR TCO, #1``.
-- 
2.30.2



From michael.riesch at wolfvision.net  Thu Jan 27 11:04:55 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu, 27 Jan 2022 20:04:55 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2 phy
 handles
Message-ID: <20220127190456.2195527-1-michael.riesch@wolfvision.net>

All nodes and handles related to USB have the prefix usb or usb2,
whereas the phy handles are prefixed with u2phy. Rename for
consistency reasons and to facilitate sorting.

This patch also updates the handles in the only board file that
uses them (rk3566-quartz64-a.dts).

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 18 ++++++++---------
 arch/arm64/boot/dts/rockchip/rk356x.dtsi      | 20 +++++++++----------
 2 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index f1d6bf10c650..3e65465ac7d5 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -574,32 +574,32 @@ &uart2 {
 	status = "okay";
 };
 
-&u2phy1_host {
-	phy-supply = <&vcc5v0_usb20_host>;
+&usb_host0_ehci {
 	status = "okay";
 };
 
-&u2phy1_otg {
-	phy-supply = <&vcc5v0_usb20_host>;
+&usb_host0_ohci {
 	status = "okay";
 };
 
-&u2phy1 {
+&usb_host1_ehci {
 	status = "okay";
 };
 
-&usb_host0_ehci {
+&usb_host1_ohci {
 	status = "okay";
 };
 
-&usb_host0_ohci {
+&usb2phy1 {
 	status = "okay";
 };
 
-&usb_host1_ehci {
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb20_host>;
 	status = "okay";
 };
 
-&usb_host1_ohci {
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb20_host>;
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index 8ee2fab676f4..69c30992ced2 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -214,7 +214,7 @@ usb_host0_ehci: usb at fd800000 {
 		interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
 			 <&cru PCLK_USB>;
-		phys = <&u2phy1_otg>;
+		phys = <&usb2phy1_otg>;
 		phy-names = "usb";
 		status = "disabled";
 	};
@@ -225,7 +225,7 @@ usb_host0_ohci: usb at fd840000 {
 		interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
 			 <&cru PCLK_USB>;
-		phys = <&u2phy1_otg>;
+		phys = <&usb2phy1_otg>;
 		phy-names = "usb";
 		status = "disabled";
 	};
@@ -236,7 +236,7 @@ usb_host1_ehci: usb at fd880000 {
 		interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
 			 <&cru PCLK_USB>;
-		phys = <&u2phy1_host>;
+		phys = <&usb2phy1_host>;
 		phy-names = "usb";
 		status = "disabled";
 	};
@@ -247,7 +247,7 @@ usb_host1_ohci: usb at fd8c0000 {
 		interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
 			 <&cru PCLK_USB>;
-		phys = <&u2phy1_host>;
+		phys = <&usb2phy1_host>;
 		phy-names = "usb";
 		status = "disabled";
 	};
@@ -1195,7 +1195,7 @@ pwm15: pwm at fe700030 {
 		status = "disabled";
 	};
 
-	u2phy0: usb2phy at fe8a0000 {
+	usb2phy0: usb2phy at fe8a0000 {
 		compatible = "rockchip,rk3568-usb2phy";
 		reg = <0x0 0xfe8a0000 0x0 0x10000>;
 		clocks = <&pmucru CLK_USBPHY0_REF>;
@@ -1206,18 +1206,18 @@ u2phy0: usb2phy at fe8a0000 {
 		#clock-cells = <0>;
 		status = "disabled";
 
-		u2phy0_host: host-port {
+		usb2phy0_host: host-port {
 			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		u2phy0_otg: otg-port {
+		usb2phy0_otg: otg-port {
 			#phy-cells = <0>;
 			status = "disabled";
 		};
 	};
 
-	u2phy1: usb2phy at fe8b0000 {
+	usb2phy1: usb2phy at fe8b0000 {
 		compatible = "rockchip,rk3568-usb2phy";
 		reg = <0x0 0xfe8b0000 0x0 0x10000>;
 		clocks = <&pmucru CLK_USBPHY1_REF>;
@@ -1228,12 +1228,12 @@ u2phy1: usb2phy at fe8b0000 {
 		#clock-cells = <0>;
 		status = "disabled";
 
-		u2phy1_host: host-port {
+		usb2phy1_host: host-port {
 			#phy-cells = <0>;
 			status = "disabled";
 		};
 
-		u2phy1_otg: otg-port {
+		usb2phy1_otg: otg-port {
 			#phy-cells = <0>;
 			status = "disabled";
 		};
-- 
2.30.2



From michael.riesch at wolfvision.net  Thu Jan 27 11:04:56 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Thu, 27 Jan 2022 20:04:56 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: add usb2 support to rk3568-evb1-v10
In-Reply-To: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
Message-ID: <20220127190456.2195527-2-michael.riesch@wolfvision.net>

Activate the USB2 controller and phy nodes in the device tree of the
RK3568 EVB1.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 58 +++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 184e2aa2416a..c68bade0d99b 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -53,6 +53,28 @@ vcc5v0_sys: vcc5v0-sys {
 		vin-supply = <&dc_12v>;
 	};
 
+	vcc5v0_usb: vcc5v0-usb {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc5v0_usb";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&dc_12v>;
+	};
+
+	vcc5v0_usb_host: vcc5v0-usb-host {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc5v0_usb_host_en>;
+		regulator-name = "vcc5v0_usb_host";
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_usb>;
+	};
+
 	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_lcd0_n";
@@ -345,6 +367,12 @@ pmic_int: pmic_int {
 				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
+
+	usb {
+		vcc5v0_usb_host_en: vcc5v0_usb_host_en {
+			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
 };
 
 &pmu_io_domains {
@@ -390,3 +418,33 @@ &sdmmc0 {
 &uart2 {
 	status = "okay";
 };
+
+&usb_host0_ehci {
+	status = "okay";
+};
+
+&usb_host0_ohci {
+	status = "okay";
+};
+
+&usb_host1_ehci {
+	status = "okay";
+};
+
+&usb_host1_ohci {
+	status = "okay";
+};
+
+&usb2phy1 {
+	status = "okay";
+};
+
+&usb2phy1_host {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
+
+&usb2phy1_otg {
+	phy-supply = <&vcc5v0_usb_host>;
+	status = "okay";
+};
-- 
2.30.2



From alisaidi at amazon.com  Thu Jan 27 11:13:45 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Thu, 27 Jan 2022 19:13:45 +0000
Subject: [PATCH 1/2] perf arm-spe: Add arm_spe_record to synthesized
In-Reply-To: <c4a96839-1b4b-ac4d-38aa-26c1f4c8645a@arm.com>
References: <c4a96839-1b4b-ac4d-38aa-26c1f4c8645a@arm.com>
Message-ID: <20220127191345.18173-1-alisaidi@amazon.com>


On 26/01/2022 19:07, German Gomez wrote:
[...]
>>> Have you tried this with perf-inject? I think it would need the PERF_SAMPLE_RAW bit in the sample_type,
>> Yes I've tried the following and it worked as expected with the original
>> perf.data or the perf.data.jitted after perf-inject. 
>>
>> perf record -e arm_spe_0/jitter=1/ -k 1 java ...
>> perf  inject -f --jit -i perf.data -o perf.data.jitted
>
>This is not injecting the synthesized samples. I think it is still????
>processing from the aux trace. Try adding "--itrace=i1i --strip" to the
>inject command to remove the AUXTRACE events. Judging by the raw
>samples, the data is missing:
>
> [...]

Yep, you're correct here. If I use the command above the raw samples are lost.

>>> Although I quickly looked over the perf inject code and it looks like it's expecting some type of padding:
>>>
>>> [...]
>>>
>>> I'm seeing some comments in utils/event.h related to this on the intel events.
>> Yes i noticed this too,but looking at how the raw data is added to the same
>> other places like intel-pt.c:1703 the perf_synth__raw*() functions are used to
>> strip away the 4 bytes bytes before the data is added to the sample. The other
>> places i can find the padding used is in builtin-script.c but given we have the
>> --dump-raw-trace option it's not clear to me that it's needed to wrap the
>> arm_spe_event in another struct with padding like perf_synth_intel_ptwrite?
>
>I think the intel use case makes sense because the layout of the data
>is fixed and documented. If we modify the struct arm_spe_record later it
>may not be obvious how to match it to the raw data of an older perf.data
>file. And we're generating bigger files with redundant information.

Not injecting the samples into the perf trace, but having a way to support
custom scripts parsing the data would be really useful and much faster than
trying to parse back the --dump-raw-trace output into something useful. The
other way to go would be to put a header that describes the version of the spe
struct at the head of it to address any future changes, but I'm not familiar
with a workflow that would benefit from the added complexity. 

Thanks,
Ali




From ebiggers at kernel.org  Thu Jan 27 11:20:13 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Thu, 27 Jan 2022 11:20:13 -0800
Subject: [RFC PATCH 3/7] crypto: hctr2 - Add HCTR2 support
In-Reply-To: <CAMj1kXG5vQ6SmRPPYjd4gg4O7gtjQg_NCOtEjY_EZoCPohcf2w@mail.gmail.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-4-nhuck@google.com>
 <CAMj1kXG5vQ6SmRPPYjd4gg4O7gtjQg_NCOtEjY_EZoCPohcf2w@mail.gmail.com>
Message-ID: <YfLwbSKNbf7MAoM/@sol.localdomain>

On Thu, Jan 27, 2022 at 10:29:31AM +0100, Ard Biesheuvel wrote:
> > diff --git a/crypto/hctr2.c b/crypto/hctr2.c
> > new file mode 100644
> > index 000000000000..af43f81b68f3
> > --- /dev/null
> > +++ b/crypto/hctr2.c
> > @@ -0,0 +1,475 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * HCTR2 length-preserving encryption mode
> > + *
> > + * Copyright 2021 Google LLC
> 
> Off by one?

To be pedantic, AFAIK if the first version of a file was written in 2021, then
it's correct to write 2021 even if it wasn't "published" yet.  But writing 2022
instead would also be fine if updates were made in 2022 (and I'd recommend just
doing that, to prevent people from thinking it's the wrong year :-) ).

- Eric


From valentin.schneider at arm.com  Thu Jan 27 11:24:37 2022
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 27 Jan 2022 19:24:37 +0000
Subject: [PATCH v4] arm64: mm: Make arch_faults_on_old_pte() check for
 migratability
Message-ID: <20220127192437.1192957-1-valentin.schneider@arm.com>

arch_faults_on_old_pte() relies on the calling context being
non-preemptible. CONFIG_PREEMPT_RT turns the PTE lock into a sleepable
spinlock, which doesn't disable preemption once acquired, triggering the
warning in arch_faults_on_old_pte().

It does however disable migration, ensuring the task remains on the same
CPU during the entirety of the critical section, making the read of
cpu_has_hw_af() safe and stable.

Make arch_faults_on_old_pte() check cant_migrate() instead of preemptible().

Suggested-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
Signed-off-by: Valentin Schneider <valentin.schneider at arm.com>
Link: https://lore.kernel.org/r/20210811201354.1976839-5-valentin.schneider at arm.com
---
v3 -> v4: Dropped migratable(), reuse cant_migrate() (Sebastian)
---
 arch/arm64/include/asm/pgtable.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index c4ba047a82d2..3caf6346ea95 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1001,7 +1001,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
  */
 static inline bool arch_faults_on_old_pte(void)
 {
-	WARN_ON(preemptible());
+	/* The register read below requires a stable CPU to make any sense */
+	cant_migrate();
 
 	return !cpu_has_hw_af();
 }
-- 
2.25.1



From ebiggers at kernel.org  Thu Jan 27 11:26:42 2022
From: ebiggers at kernel.org (Eric Biggers)
Date: Thu, 27 Jan 2022 11:26:42 -0800
Subject: [RFC PATCH 1/7] crypto: xctr - Add XCTR support
In-Reply-To: <CAMj1kXHCXNZEuK7hY5MfiBE2xAHbTN=ZOtm4zKzd4=dfTErgDA@mail.gmail.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-2-nhuck@google.com>
 <CAMj1kXHCXNZEuK7hY5MfiBE2xAHbTN=ZOtm4zKzd4=dfTErgDA@mail.gmail.com>
Message-ID: <YfLx8vU1jziBsihp@sol.localdomain>

On Thu, Jan 27, 2022 at 10:42:49AM +0100, Ard Biesheuvel wrote:
> > diff --git a/include/crypto/xctr.h b/include/crypto/xctr.h
> > new file mode 100644
> > index 000000000000..0d025e08ca26
> > --- /dev/null
> > +++ b/include/crypto/xctr.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > +/*
> > + * XCTR: XOR Counter mode
> > + *
> > + * Copyright 2021 Google LLC
> > + */
> > +
> > +#include <asm/unaligned.h>
> > +
> > +#ifndef _CRYPTO_XCTR_H
> > +#define _CRYPTO_XCTR_H
> > +
> > +static inline void u32_to_le_block(u8 *a, u32 x, unsigned int size)
> > +{
> > +       memset(a, 0, size);
> > +       put_unaligned(cpu_to_le32(x), (u32 *)a);
> 
> Please use put_unaligned_le32() here.
> 
> And casting 'a' to (u32 *) is invalid C, so just pass 'a' directly.
> Otherwise, the compiler might infer that 'a' is guaranteed to be
> aligned after all, and use an aligned access instead.

I agree that put_unaligned_le32() is more suitable here, but I don't think
casting 'a' to 'u32 *' is undefined; it's only dereferencing it that would be
undefined.  If such casts were undefined, then get_unaligned() and
put_unaligned() would be unusable under any circumstance.  Here's an example of
code that would be incorrect in that case:
https://lore.kernel.org/linux-crypto/20220119093109.1567314-1-ardb at kernel.org

- Eric


From valentin.schneider at arm.com  Thu Jan 27 11:27:56 2022
From: valentin.schneider at arm.com (Valentin Schneider)
Date: Thu, 27 Jan 2022 19:27:56 +0000
Subject: [PATCH v3 2/4] sched: Introduce migratable()
In-Reply-To: <YfF9I5PcZJA5532B@linutronix.de>
References: <20210811201354.1976839-1-valentin.schneider@arm.com>
 <20210811201354.1976839-3-valentin.schneider@arm.com>
 <20210817170925.2jwqvgvmqab2glwu@linutronix.de> <87czq573et.mognet@arm.com>
 <YfF9I5PcZJA5532B@linutronix.de>
Message-ID: <87v8y5nflv.mognet@arm.com>

On 26/01/22 17:56, Sebastian Andrzej Siewior wrote:
> On 2021-08-22 19:14:18 [+0100], Valentin Schneider wrote:
>> Thanks for carrying it through, I'll keep that change for the next version.
>
> Just a quick question. This series ended with 3 patches in my queue. It
> got decimated further due to Frederic series which ended up in
> v5.17-rc1. I still have
> | 2021-08-11 21:13 +0100 Valentin Schneider    ? sched: Introduce migratable()
> | 2021-08-11 21:13 +0100 Valentin Schneider    ? arm64: mm: Make arch_faults_on_old_pte() check for migratability
>
> what do we do about these two? I could repost these two if there are no
> objections?
>

While I'm at it, I see you're still carrying

  6ab5bb09040d arm64/sve: Make kernel FPU protection RT friendly

If you're OK with it, I'll repost that:
https://lore.kernel.org/lkml/20210722175157.1367122-1-valentin.schneider at arm.com/

> Sebastian


From ardb at kernel.org  Thu Jan 27 11:43:49 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Thu, 27 Jan 2022 20:43:49 +0100
Subject: [RFC PATCH 1/7] crypto: xctr - Add XCTR support
In-Reply-To: <YfLx8vU1jziBsihp@sol.localdomain>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-2-nhuck@google.com>
 <CAMj1kXHCXNZEuK7hY5MfiBE2xAHbTN=ZOtm4zKzd4=dfTErgDA@mail.gmail.com>
 <YfLx8vU1jziBsihp@sol.localdomain>
Message-ID: <CAMj1kXEGvSBoOy+TNK749+sUx8cbwSu7YHYFQKu3vA1XvXrE9Q@mail.gmail.com>

On Thu, 27 Jan 2022 at 20:26, Eric Biggers <ebiggers at kernel.org> wrote:
>
> On Thu, Jan 27, 2022 at 10:42:49AM +0100, Ard Biesheuvel wrote:
> > > diff --git a/include/crypto/xctr.h b/include/crypto/xctr.h
> > > new file mode 100644
> > > index 000000000000..0d025e08ca26
> > > --- /dev/null
> > > +++ b/include/crypto/xctr.h
> > > @@ -0,0 +1,19 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-or-later */
> > > +/*
> > > + * XCTR: XOR Counter mode
> > > + *
> > > + * Copyright 2021 Google LLC
> > > + */
> > > +
> > > +#include <asm/unaligned.h>
> > > +
> > > +#ifndef _CRYPTO_XCTR_H
> > > +#define _CRYPTO_XCTR_H
> > > +
> > > +static inline void u32_to_le_block(u8 *a, u32 x, unsigned int size)
> > > +{
> > > +       memset(a, 0, size);
> > > +       put_unaligned(cpu_to_le32(x), (u32 *)a);
> >
> > Please use put_unaligned_le32() here.
> >
> > And casting 'a' to (u32 *) is invalid C, so just pass 'a' directly.
> > Otherwise, the compiler might infer that 'a' is guaranteed to be
> > aligned after all, and use an aligned access instead.
>
> I agree that put_unaligned_le32() is more suitable here, but I don't think
> casting 'a' to 'u32 *' is undefined; it's only dereferencing it that would be
> undefined.  If such casts were undefined, then get_unaligned() and
> put_unaligned() would be unusable under any circumstance.  Here's an example of
> code that would be incorrect in that case:
> https://lore.kernel.org/linux-crypto/20220119093109.1567314-1-ardb at kernel.org
>

Good point :-)


From gerhard at engleder-embedded.com  Thu Jan 27 11:46:02 2022
From: gerhard at engleder-embedded.com (Gerhard Engleder)
Date: Thu, 27 Jan 2022 20:46:02 +0100
Subject: [PATCH] Revert "pinctrl: zynqmp: Unify pin naming"
Message-ID: <20220127194602.21987-1-gerhard@engleder-embedded.com>

From: Gerhard Engleder <gerhard at engleder-embedded.com>

This reverts commit 54784ff24971ed5bd3f1056edce998148709d0a7.

This patch changes the pin names from "MIO%d" to "MIO-%d", but all dts
in arch/arm64/boot/dts/xilinx still use the old name. As a result my
ZCU104 has no output on serial terminal and is not reachable over
network.

Signed-off-by: Gerhard Engleder <gerhard at engleder-embedded.com>
---
 drivers/pinctrl/pinctrl-zynqmp.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c
index 42da6bd399ee..e14012209992 100644
--- a/drivers/pinctrl/pinctrl-zynqmp.c
+++ b/drivers/pinctrl/pinctrl-zynqmp.c
@@ -809,7 +809,6 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
 					   unsigned int *npins)
 {
 	struct pinctrl_pin_desc *pins, *pin;
-	char **pin_names;
 	int ret;
 	int i;
 
@@ -821,14 +820,13 @@ static int zynqmp_pinctrl_prepare_pin_desc(struct device *dev,
 	if (!pins)
 		return -ENOMEM;
 
-	pin_names = devm_kasprintf_strarray(dev, ZYNQMP_PIN_PREFIX, *npins);
-	if (IS_ERR(pin_names))
-		return PTR_ERR(pin_names);
-
 	for (i = 0; i < *npins; i++) {
 		pin = &pins[i];
 		pin->number = i;
-		pin->name = pin_names[i];
+		pin->name = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
+					   ZYNQMP_PIN_PREFIX, i);
+		if (!pin->name)
+			return -ENOMEM;
 	}
 
 	*zynqmp_pins = pins;
-- 
2.20.1



From arnd at arndb.de  Thu Jan 27 11:55:27 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Thu, 27 Jan 2022 20:55:27 +0100
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <3e11270f-7014-4729-13cf-d9331d4bdec7@arm.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
 <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
 <CAK8P3a0oaP8LzxX6TSYhmSV+s+5rjHeCRzQ-pXkMQvpGvrp_0Q@mail.gmail.com>
 <3e11270f-7014-4729-13cf-d9331d4bdec7@arm.com>
Message-ID: <CAK8P3a2Vj0XCJSdKrgHmEkXjuWT2cxPnT=F8+ea2G7moiHoDyw@mail.gmail.com>

On Thu, Jan 27, 2022 at 7:43 PM Robin Murphy <robin.murphy at arm.com> wrote:
> On 2022-01-27 14:52, Arnd Bergmann wrote:
> > On Thu, Jan 27, 2022 at 1:39 PM Ard Biesheuvel <ardb at kernel.org> wrote:
> >> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
> >> occurs between a pair of AES instructions in aarch32 mode may corrupt
> >> the ELR. The task will subsequently produce the wrong AES result.
> >
> >> Fortunately, the only A72 that is known to be widely deployed with
> >> 32-bit kernels and/or user space is the Raspberry Pi 4, which does not
> >> implement the crypto extensions.
> >
> > I have previously used Amazon EC2 A1 instances (using Graviton 1, Cortex-A72)
> > to run Debian armhf and armel user space in chroot environments. No idea how
> > common that is for production environments, but there is a good chance that
> > actual users might use e.g. 32-bit docker images for Alpine Linux on the same
> > machines.
> >
> > There are also some early A57/A72 chips used in Android devices that may
> > frequently run 32-bit applications, or even be limited to 32-bit
> > kernels, see [1].
> > Not sure how likely it is for any of them to get (a backport of) this
> > patch though.
>
> Isn't ChromeOS still notoriously shipping AArch32 userspace? Between
> Mediatek and Rockchip, both A57 and A72 are definitely playing on that
> stage.

I wouldn't call it "notorious", but indeed that is an important user
that I missed. For some reason I misremembered that both mt8173 and
rk3399 are Cortex-A73 based, but they are A72 as you say.

> I'd concur that 32-bit *kernel* on v8 is a bit of a specialist sport,
> especially these days. IIRC Exynos 5433 might have been one of the more
> common Android setups for that, but 2015 is now an eternity ago in phone
> years..

Unfortunately, 32-bit kernels are still a thing on low-end Android phones,
including some very recent Cortex-A55 based products with Android Go
edition and 2GB of RAM or less, and also some highly popular (at the time)
Cortex-A53 Snapdragon 410 phones started shipping before a 64-bit kernel
port was available on Snapdragon.

A57/A72 at least disappeared from phones a long time ago because of
both cost and power consumption reasons, so it's only the low end devices
now. I'm not aware of any Android devices actually shipping with a 64-bit
kernel and 32-bit user space, maybe that was never an option in the SDK.

        Arnd


From clabbe at baylibre.com  Thu Jan 27 12:03:10 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Thu, 27 Jan 2022 20:03:10 +0000
Subject: [PATCH] dt-bindings: mtd: drop mtd/cortina,gemini-flash.txt
Message-ID: <20220127200310.4150981-1-clabbe@baylibre.com>

Drop mtd/cortina,gemini-flash.txt since it is nearly already handled by
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml.

Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
 .../bindings/mtd/cortina,gemini-flash.txt     | 24 -------------------
 .../devicetree/bindings/mtd/mtd-physmap.yaml  | 18 +++++++++++++-
 2 files changed, 17 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt

diff --git a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt b/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt
deleted file mode 100644
index efa5b2aba829..000000000000
--- a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Flash device on Cortina Systems Gemini SoC
-
-This flash is regular CFI compatible (Intel or AMD extended) flash chips with
-some special bits that can be controlled by the machine's system controller.
-
-Required properties:
-- compatible : must be "cortina,gemini-flash", "cfi-flash";
-- reg : memory address for the flash chip
-- syscon : must be a phandle to the system controller
-- bank-width : width in bytes of flash interface, should be <2>
-
-For the rest of the properties, see mtd-physmap.yaml.
-
-The device tree may optionally contain sub-nodes describing partitions of the
-address space. See partition.txt for more detail.
-
-Example:
-
-flash at 30000000 {
-	compatible = "cortina,gemini-flash", "cfi-flash";
-	reg = <0x30000000 0x01000000>;
-	syscon = <&syscon>;
-	bank-width = <2>;
-};
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
index f827984936f6..5b4440e005bc 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
@@ -44,7 +44,9 @@ properties:
               - numonyx,js28f128
               - sst,sst39vf320
               - xlnx,xps-mch-emc-2.00.a
-          - const: cfi-flash
+          - enum:
+              - cfi-flash
+              - jedec-flash
       - items:
           - enum:
               - cypress,cy7c1019dv33-10zsxi
@@ -127,6 +129,20 @@ required:
   - compatible
   - reg
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: cortina,gemini-flash
+then:
+  properties:
+    syscon:
+      $ref: /schemas/types.yaml#/definitions/phandle
+      description:
+        Phandle to the syscom controller
+  required:
+    - syscon
+
 # FIXME: A parent bus may define timing properties
 additionalProperties: true
 
-- 
2.34.1



From broonie at kernel.org  Thu Jan 27 11:57:08 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:57:08 +0000
Subject: [PATCH v1 0/4] arm64/mte: Asymmetric MTE support in userspace
Message-ID: <20220127195712.748150-1-broonie@kernel.org>

MTE3 adds a new mode which is synchronous for writes but asynchronous for
reads. Currently we make use of this within the kernel but do not make
it available for userspace, this series extends the existing userspace
ABI to allow that to happen.

There's no updates to the kselftests for MTE here, I have some work in
progress there but there's some overlap with Joey's work extending the
tests to cover some additional cases and there's some fairly extensive
assumptions that need to be unpicked about only being able to generate
one type of fault at once. I'll clean that up and post it later.

Mark Brown (4):
  arm64/mte: Document ABI for asymmetric mode
  arm64/mte: Add a little bit of documentation for
    mte_update_sctlr_user()
  arm64/mte: Add hwcap for asymmetric mode
  arm64/mte: Add userspace interface for enabling asymmetric mode

 Documentation/arm64/elf_hwcaps.rst            |  5 ++++
 .../arm64/memory-tagging-extension.rst        | 12 +++++----
 arch/arm64/include/asm/hwcap.h                |  1 +
 arch/arm64/include/asm/processor.h            |  1 +
 arch/arm64/include/uapi/asm/hwcap.h           |  1 +
 arch/arm64/kernel/cpufeature.c                |  1 +
 arch/arm64/kernel/cpuinfo.c                   |  1 +
 arch/arm64/kernel/mte.c                       | 26 ++++++++++++++++++-
 arch/arm64/kernel/process.c                   |  5 +++-
 include/uapi/linux/prctl.h                    |  4 ++-
 10 files changed, 49 insertions(+), 8 deletions(-)


base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.30.2



From broonie at kernel.org  Thu Jan 27 11:57:09 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:57:09 +0000
Subject: [PATCH v1 1/4] arm64/mte: Document ABI for asymmetric mode
In-Reply-To: <20220127195712.748150-1-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
Message-ID: <20220127195712.748150-2-broonie@kernel.org>

MTE3 adds a new mode which is synchronous for writes but asynchronous for
reads. Document the userspace ABI for this feature, we call the new mode
ASYMM and add a new prctl flag and mte_tcf_preferred value for it.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/memory-tagging-extension.rst | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
index 7b99c8f428eb..5218b838d062 100644
--- a/Documentation/arm64/memory-tagging-extension.rst
+++ b/Documentation/arm64/memory-tagging-extension.rst
@@ -76,6 +76,9 @@ configurable behaviours:
   with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
   address is unknown).
 
+- *Asymmetric* - Reads are handled as for synchronous mode while writes
+  are handled as for asynchronous mode.
+
 The user can select the above modes, per thread, using the
 ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
 contains any number of the following values in the ``PR_MTE_TCF_MASK``
@@ -85,6 +88,7 @@ bit-field:
                          (ignored if combined with other options)
 - ``PR_MTE_TCF_SYNC``  - *Synchronous* tag check fault mode
 - ``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode
+- ``PR_MTE_TCF_ASYMM`` - *Asymmetric* tag check fault mode
 
 If no modes are specified, tag check faults are ignored. If a single
 mode is specified, the program will run in that mode. If multiple
@@ -139,16 +143,14 @@ tag checking mode as the CPU's preferred tag checking mode.
 
 The preferred tag checking mode for each CPU is controlled by
 ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
-privileged user may write the value ``async`` or ``sync``.  The default
-preferred mode for each CPU is ``async``.
+privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
+default preferred mode for each CPU is ``async``.
 
 To allow a program to potentially run in the CPU's preferred tag
 checking mode, the user program may set multiple tag check fault mode
 bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
 flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
-mode is in the task's set of provided tag checking modes (this will
-always be the case at present because the kernel only supports two
-tag checking modes, but future kernels may support more modes), that
+mode is in the task's set of provided tag checking modes, that
 mode will be selected. Otherwise, one of the modes in the task's mode
 set will be selected in a currently unspecified manner.
 
-- 
2.30.2



From broonie at kernel.org  Thu Jan 27 11:57:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:57:10 +0000
Subject: [PATCH v1 2/4] arm64/mte: Add a little bit of documentation for
 mte_update_sctlr_user()
In-Reply-To: <20220127195712.748150-1-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
Message-ID: <20220127195712.748150-3-broonie@kernel.org>

The code isn't that obscure but it probably won't hurt to have a little
bit more documentation for anyone trying to find out where everything
actually takes effect.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/kernel/mte.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index f418ebc65f95..fa4001fee12a 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -186,6 +186,11 @@ void mte_check_tfsr_el1(void)
 }
 #endif
 
+/*
+ * This is where we actually resolve the system and process MTE mode
+ * configuration into an actual value in SCTLR_EL1 that affects
+ * userspace.
+ */
 static void mte_update_sctlr_user(struct task_struct *task)
 {
 	/*
@@ -199,8 +204,17 @@ static void mte_update_sctlr_user(struct task_struct *task)
 	unsigned long pref, resolved_mte_tcf;
 
 	pref = __this_cpu_read(mte_tcf_preferred);
+	/*
+	 * If there is no overlap between the system preferred and
+	 * program requested values go with what was requested.
+	 */
 	resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
 	sctlr &= ~SCTLR_EL1_TCF0_MASK;
+	/*
+	 * Pick an actual setting. The order in which we check for
+	 * set bits and map into register values determines our
+	 * default order.
+	 */
 	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
 		sctlr |= SCTLR_EL1_TCF0_ASYNC;
 	else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
-- 
2.30.2



From broonie at kernel.org  Thu Jan 27 11:57:11 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:57:11 +0000
Subject: [PATCH v1 3/4] arm64/mte: Add hwcap for asymmetric mode
In-Reply-To: <20220127195712.748150-1-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
Message-ID: <20220127195712.748150-4-broonie@kernel.org>

Allow userspace to detect support for asymmetric mode by providing a hwcap
for it, using the official feature name FEAT_MTE3.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 Documentation/arm64/elf_hwcaps.rst  | 5 +++++
 arch/arm64/include/asm/hwcap.h      | 1 +
 arch/arm64/include/uapi/asm/hwcap.h | 1 +
 arch/arm64/kernel/cpufeature.c      | 1 +
 arch/arm64/kernel/cpuinfo.c         | 1 +
 5 files changed, 9 insertions(+)

diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
index b72ff17d600a..a8f30963e550 100644
--- a/Documentation/arm64/elf_hwcaps.rst
+++ b/Documentation/arm64/elf_hwcaps.rst
@@ -259,6 +259,11 @@ HWCAP2_RPRES
 
     Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
 
+HWCAP2_MTE3
+
+    Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
+    by Documentation/arm64/memory-tagging-extension.rst.
+
 4. Unused AT_HWCAP bits
 -----------------------
 
diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
index f68fbb207473..8db5ec0089db 100644
--- a/arch/arm64/include/asm/hwcap.h
+++ b/arch/arm64/include/asm/hwcap.h
@@ -108,6 +108,7 @@
 #define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
 #define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
 #define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
+#define KERNEL_HWCAP_MTE3		__khwcap2_feature(MTE3)
 
 /*
  * This yields a mask that user programs can use to figure out what
diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
index f03731847d9d..99cb5d383048 100644
--- a/arch/arm64/include/uapi/asm/hwcap.h
+++ b/arch/arm64/include/uapi/asm/hwcap.h
@@ -78,5 +78,6 @@
 #define HWCAP2_ECV		(1 << 19)
 #define HWCAP2_AFP		(1 << 20)
 #define HWCAP2_RPRES		(1 << 21)
+#define HWCAP2_MTE3		(1 << 22)
 
 #endif /* _UAPI__ASM_HWCAP_H */
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..57de3f3e0518 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2485,6 +2485,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 #endif
 #ifdef CONFIG_ARM64_MTE
 	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
+	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE_ASYMM, CAP_HWCAP, KERNEL_HWCAP_MTE3),
 #endif /* CONFIG_ARM64_MTE */
 	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
 	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 591c18a889a5..330b92ea863a 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -97,6 +97,7 @@ static const char *const hwcap_str[] = {
 	[KERNEL_HWCAP_ECV]		= "ecv",
 	[KERNEL_HWCAP_AFP]		= "afp",
 	[KERNEL_HWCAP_RPRES]		= "rpres",
+	[KERNEL_HWCAP_MTE3]		= "mte3",
 };
 
 #ifdef CONFIG_COMPAT
-- 
2.30.2



From broonie at kernel.org  Thu Jan 27 11:57:12 2022
From: broonie at kernel.org (Mark Brown)
Date: Thu, 27 Jan 2022 19:57:12 +0000
Subject: [PATCH v1 4/4] arm64/mte: Add userspace interface for enabling
 asymmetric mode
In-Reply-To: <20220127195712.748150-1-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
Message-ID: <20220127195712.748150-5-broonie@kernel.org>

The architecture provides an asymmetric mode for MTE where tag mismatches
are checked asynchronously for reads but synchronously for loads. Allow
userspace processes to select this and make it available as a default mode
via the existing per-CPU sysfs interface.

Since there PR_MTE_TCF_ values are a bitmask (allowing the kernel to choose
between the multiple modes) and there are no free bits adjacent to the
existing PR_MTE_TCF_ bits the set of bits used to specify the mode becomes
disjoint. Programs using the new interface should be aware of this and
programs that do not use it will not see any change in behaviour.

When userspace requests two possible modes but the system default for the
CPU is the third mode (eg, default is synchronous but userspace requests
either asynchronous or asymmetric) the preference order is:

   ASYMM > ASYNC > SYNC

This situation is not currently possible since there are only two modes and
it is mandatory to have a system default so there could be no ambiguity and
there is no ABI change. The chosen order is basically arbitrary as we do not
have a clear metric for what is better here.

If userspace requests specifically asymmetric mode via the prctl() and the
system does not support it then we will return an error, this mirrors
how we handle the case where userspace enables MTE on a system that does
not support MTE at all and the behaviour that will be seen if running on
an older kernel that does not support userspace use of asymmetric mode.

Attempts to set asymmetric mode as the default mode will result in an error
if the system does not support it.

Signed-off-by: Mark Brown <broonie at kernel.org>
---
 arch/arm64/include/asm/processor.h |  1 +
 arch/arm64/kernel/mte.c            | 12 +++++++++++-
 arch/arm64/kernel/process.c        |  5 ++++-
 include/uapi/linux/prctl.h         |  4 +++-
 4 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 6f41b65f9962..73e38d9a540c 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -21,6 +21,7 @@
 
 #define MTE_CTRL_TCF_SYNC		(1UL << 16)
 #define MTE_CTRL_TCF_ASYNC		(1UL << 17)
+#define MTE_CTRL_TCF_ASYMM		(1UL << 18)
 
 #ifndef __ASSEMBLY__
 
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index fa4001fee12a..fb777d8fea32 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -215,7 +215,9 @@ static void mte_update_sctlr_user(struct task_struct *task)
 	 * set bits and map into register values determines our
 	 * default order.
 	 */
-	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
+	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYMM)
+		sctlr |= SCTLR_EL1_TCF0_ASYMM;
+	else if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
 		sctlr |= SCTLR_EL1_TCF0_ASYNC;
 	else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
 		sctlr |= SCTLR_EL1_TCF0_SYNC;
@@ -306,6 +308,8 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
 		mte_ctrl |= MTE_CTRL_TCF_ASYNC;
 	if (arg & PR_MTE_TCF_SYNC)
 		mte_ctrl |= MTE_CTRL_TCF_SYNC;
+	if (arg & PR_MTE_TCF_ASYMM)
+		mte_ctrl |= MTE_CTRL_TCF_ASYMM;
 
 	task->thread.mte_ctrl = mte_ctrl;
 	if (task == current) {
@@ -334,6 +338,8 @@ long get_mte_ctrl(struct task_struct *task)
 		ret |= PR_MTE_TCF_ASYNC;
 	if (mte_ctrl & MTE_CTRL_TCF_SYNC)
 		ret |= PR_MTE_TCF_SYNC;
+	if (mte_ctrl & MTE_CTRL_TCF_ASYMM)
+		ret |= PR_MTE_TCF_ASYMM;
 
 	return ret;
 }
@@ -481,6 +487,8 @@ static ssize_t mte_tcf_preferred_show(struct device *dev,
 		return sysfs_emit(buf, "async\n");
 	case MTE_CTRL_TCF_SYNC:
 		return sysfs_emit(buf, "sync\n");
+	case MTE_CTRL_TCF_ASYMM:
+		return sysfs_emit(buf, "asymm\n");
 	default:
 		return sysfs_emit(buf, "???\n");
 	}
@@ -496,6 +504,8 @@ static ssize_t mte_tcf_preferred_store(struct device *dev,
 		tcf = MTE_CTRL_TCF_ASYNC;
 	else if (sysfs_streq(buf, "sync"))
 		tcf = MTE_CTRL_TCF_SYNC;
+	else if (cpus_have_cap(ARM64_MTE_ASYMM) && sysfs_streq(buf, "asymm"))
+		tcf = MTE_CTRL_TCF_ASYMM;
 	else
 		return -EINVAL;
 
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..941cfa7117b9 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -635,7 +635,10 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
 		return -EINVAL;
 
 	if (system_supports_mte())
-		valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK;
+		valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
+			| PR_MTE_TAG_MASK;
+	if (cpus_have_cap(ARM64_MTE_ASYMM))
+		valid_mask |= PR_MTE_TCF_ASYMM;
 
 	if (arg & ~valid_mask)
 		return -EINVAL;
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index e998764f0262..4ae2b21e4066 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -238,7 +238,9 @@ struct prctl_mm_map {
 # define PR_MTE_TCF_NONE		0UL
 # define PR_MTE_TCF_SYNC		(1UL << 1)
 # define PR_MTE_TCF_ASYNC		(1UL << 2)
-# define PR_MTE_TCF_MASK		(PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC)
+# define PR_MTE_TCF_ASYMM		(1UL << 19)
+# define PR_MTE_TCF_MASK		(PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | \
+					 PR_MTE_TCF_ASYMM)
 /* MTE tag inclusion mask */
 # define PR_MTE_TAG_SHIFT		3
 # define PR_MTE_TAG_MASK		(0xffffUL << PR_MTE_TAG_SHIFT)
-- 
2.30.2



From sean.anderson at seco.com  Thu Jan 27 12:06:29 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 27 Jan 2022 15:06:29 -0500
Subject: [PATCH v3 0/7] usb: dwc3: Calculate REFCLKPER et. al. from reference
 clock
Message-ID: <20220127200636.1456175-1-sean.anderson@seco.com>

This is a rework of patches 3-5 of [1]. It attempts to correctly program
REFCLKPER and REFCLK_FLADJ based on the reference clock frequency. Since
we no longer need a special property duplicating this configuration,
snps,ref-clock-period-ns is deprecated.

Please test this! Patches 3/4 in this series have the effect of
programming REFCLKPER and REFCLK_FLADJ on boards which already configure
the "ref" clock. I have build tested, but not much else.

[1] https://lore.kernel.org/linux-usb/20220114044230.2677283-1-robert.hancock at calian.com/

Changes in v3:
- Define each variable on its own line
- Rebase onto linux/master
- Update comment to notes some things mentioned during review

Changes in v2:
- Add snps,ref-clock-frequency-hz property for ACPI
- Also program GFLADJ.240MHZDECR
- Document clock members
- Don't program GFLADJ if the version is < 2.50a

Sean Anderson (7):
  dt-bindings: usb: dwc3: Deprecate snps,ref-clock-period-ns
  usb: dwc3: Get clocks individually
  usb: dwc3: Calculate REFCLKPER based on reference clock
  usb: dwc3: Program GFLADJ
  usb: dwc3: Add snps,ref-clock-frequency-hz property for ACPI
  arm64: dts: zynqmp: Move USB clocks to dwc3 node
  arm64: dts: ipq6018: Use reference clock to set dwc3 period

 .../devicetree/bindings/usb/snps,dwc3.yaml    |   7 +-
 arch/arm64/boot/dts/qcom/ipq6018.dtsi         |   3 +-
 .../arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi |   4 +-
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi        |   4 +-
 drivers/usb/dwc3/core.c                       | 117 +++++++++++++++---
 drivers/usb/dwc3/core.h                       |  17 ++-
 6 files changed, 125 insertions(+), 27 deletions(-)

-- 
2.25.1



From sean.anderson at seco.com  Thu Jan 27 12:06:35 2022
From: sean.anderson at seco.com (Sean Anderson)
Date: Thu, 27 Jan 2022 15:06:35 -0500
Subject: [PATCH v3 6/7] arm64: dts: zynqmp: Move USB clocks to dwc3 node
In-Reply-To: <20220127200636.1456175-1-sean.anderson@seco.com>
References: <20220127200636.1456175-1-sean.anderson@seco.com>
Message-ID: <20220127200636.1456175-7-sean.anderson@seco.com>

These clocks are not used by the dwc3-xilinx driver except to
enable/disable them. Move them to the dwc3 node so its driver can use
them to configure the reference clock period.

Signed-off-by: Sean Anderson <sean.anderson at seco.com>
Reviewed-by: Robert Hancock <robert.hancock at calian.com>
Tested-by: Robert Hancock <robert.hancock at calian.com>
---

(no changes since v1)

 arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi | 4 ++--
 arch/arm64/boot/dts/xilinx/zynqmp.dtsi         | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
index 1e0b1bca7c94..8493dd7d5f1f 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
@@ -223,11 +223,11 @@ &uart1 {
 	clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
 };
 
-&usb0 {
+&dwc3_0 {
 	clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
-&usb1 {
+&dwc3_1 {
 	clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
 };
 
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
index 74e66443e4ce..ba68fb8529ee 100644
--- a/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
+++ b/arch/arm64/boot/dts/xilinx/zynqmp.dtsi
@@ -811,7 +811,6 @@ usb0: usb at ff9d0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9d0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_0>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB0_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB0_HIBERRESET>,
@@ -825,6 +824,7 @@ dwc3_0: usb at fe200000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 65 4>, <0 69 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x860>;
 				snps,quirk-frame-length-adjustment = <0x20>;
@@ -838,7 +838,6 @@ usb1: usb at ff9e0000 {
 			status = "disabled";
 			compatible = "xlnx,zynqmp-dwc3";
 			reg = <0x0 0xff9e0000 0x0 0x100>;
-			clock-names = "bus_clk", "ref_clk";
 			power-domains = <&zynqmp_firmware PD_USB_1>;
 			resets = <&zynqmp_reset ZYNQMP_RESET_USB1_CORERESET>,
 				 <&zynqmp_reset ZYNQMP_RESET_USB1_HIBERRESET>,
@@ -852,6 +851,7 @@ dwc3_1: usb at fe300000 {
 				interrupt-parent = <&gic>;
 				interrupt-names = "dwc_usb3", "otg";
 				interrupts = <0 70 4>, <0 74 4>;
+				clock-names = "bus_early", "ref";
 				#stream-id-cells = <1>;
 				iommus = <&smmu 0x861>;
 				snps,quirk-frame-length-adjustment = <0x20>;
-- 
2.25.1



From mathieu.poirier at linaro.org  Thu Jan 27 12:20:29 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Jan 2022 13:20:29 -0700
Subject: [GIT PULL] coresight: trbe: Workaround Cortex-A510 erratas
Message-ID: <20220127202029.2195073-1-mathieu.poirier@linaro.org>

The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

  Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

  git at gitolite.kernel.org:pub/scm/linux/kernel/git/coresight/linux.git tags/trbe-cortex-a510-errata

for you to fetch changes up to 708e8af4924ec2fdd5b81fe09192c6bac2f86935:

  arm64: errata: Add detection for TRBE trace data corruption (2022-01-27 12:01:53 -0700)

----------------------------------------------------------------
coresight: trbe: Workaround Cortex-A510 erratas

This pull request is providing arm64 definitions to support
TRBE Cortex-A510 erratas.

Signed-off-by: Mathieu Poirier <mathieu.poirier at linaro.org>

----------------------------------------------------------------
Anshuman Khandual (4):
      arm64: Add Cortex-A510 CPU part definition
      arm64: errata: Add detection for TRBE ignored system register writes
      arm64: errata: Add detection for TRBE invalid prohibited states
      arm64: errata: Add detection for TRBE trace data corruption

 Documentation/arm64/silicon-errata.rst |  6 ++++
 arch/arm64/Kconfig                     | 59 ++++++++++++++++++++++++++++++++++
 arch/arm64/include/asm/cputype.h       |  2 ++
 arch/arm64/kernel/cpu_errata.c         | 27 ++++++++++++++++
 arch/arm64/tools/cpucaps               |  3 ++
 5 files changed, 97 insertions(+)


From 21cnbao at gmail.com  Thu Jan 27 12:21:08 2022
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 28 Jan 2022 09:21:08 +1300
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <YfK9DSMFabjYm/MV@BLR-5CG11610CF.amd.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <YfK9DSMFabjYm/MV@BLR-5CG11610CF.amd.com>
Message-ID: <CAGsJ_4xL3tynB9P=rKMoX2otW4bMMU5Z-P9zSudMV3+fr2hpXw@mail.gmail.com>

On Fri, Jan 28, 2022 at 4:41 AM Gautham R. Shenoy
<gautham.shenoy at amd.com> wrote:
>
> On Wed, Jan 26, 2022 at 04:09:47PM +0800, Yicong Yang wrote:
> > From: Barry Song <song.bao.hua at hisilicon.com>
> >
> > For platforms having clusters like Kunpeng920, CPUs within the same
> > cluster have lower latency when synchronizing and accessing shared
> > resources like cache. Thus, this patch tries to find an idle cpu
> > within the cluster of the target CPU before scanning the whole LLC
> > to gain lower latency.
> >
> > Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> > patch doesn't consider SMT for this moment.
> >
> > Testing has been done on Kunpeng920 by pinning tasks to one numa
> > and two numa. On Kunpeng920, Each numa has 8 clusters and each
> > cluster has 4 CPUs.
> >
> > With this patch, We noticed enhancement on tbench within one
> > numa or cross two numa.
> >
> > On numa 0:
> >                             5.17-rc1                patched
> > Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> > Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> > Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> > Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> > Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> > Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> > Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> > Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> >
> > On numa 0-1:
> >                             5.17-rc1                patched
> > Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> > Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> > Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> > Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> > Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> > Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> > Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> > Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> > Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> > Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> >
> > This will also help to improve the MySQL. With MySQL server
> > running on numa 0 and client running on numa 1, both QPS and
> > latency is imporved on read-write case:
> >                         5.17-rc1        patched
> > QPS-16threads        143333.2633    145077.4033(+1.22%)
> > QPS-24threads        195085.9367    202719.6133(+3.91%)
> > QPS-32threads        241165.6867      249020.74(+3.26%)
> > QPS-64threads        244586.8433    253387.7567(+3.60%)
> > avg-lat-16threads           2.23           2.19(+1.19%)
> > avg-lat-24threads           2.46           2.36(+3.79%)
> > avg-lat-36threads           2.66           2.57(+3.26%)
> > avg-lat-64threads           5.23           5.05(+3.44%)
> >
> > Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> > Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> > ---
> >  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++----
> >  1 file changed, 42 insertions(+), 4 deletions(-)
> >
> > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > index 5146163bfabb..2f84a933aedd 100644
> > --- a/kernel/sched/fair.c
> > +++ b/kernel/sched/fair.c
> > @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
> >
> >  #endif /* CONFIG_SCHED_SMT */
> >
> > +#ifdef CONFIG_SCHED_CLUSTER
> > +/*
> > + * Scan the cluster domain for idle CPUs and clear cluster cpumask after scanning
> > + */
> > +static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
> > +{
> > +     struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
> > +     struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster, target));
> > +     int cpu, idle_cpu;
> > +
> > +     /* TODO: Support SMT case while a machine with both cluster and SMT born */
> > +     if (!sched_smt_active() && sd) {
> > +             for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> > +                     idle_cpu = __select_idle_cpu(cpu, p);
> > +                     if ((unsigned int)idle_cpu < nr_cpumask_bits)
> > +                             return idle_cpu;
> > +             }
> > +
> > +             /* Don't ping-pong tasks in and out cluster frequently */
> > +             if (cpus_share_resources(target, prev_cpu))
> > +                     return target;
>
> We reach here when there aren't any idle CPUs within the
> cluster. However there might be idle CPUs in the MC domain. Is a busy
> @target preferable to a potentially idle CPU within the larger domain
> ?

Hi Gautham,

My benchmark showed some performance regression while load was medium or above
if we grabbed idle cpu in and out the cluster. it turned out the
regression disappeared if
we blocked the ping-pong. so the logic here is that if we have scanned
and found an
idle cpu within the cluster before, we don't let the task jumping back
and forth frequently
as cache synchronization is higher cost. but the code still allows
scanning out of the cluster
if we haven't packed waker and wakee together yet.

it might not be a universal win in all kinds of workload. we saw
tbench, mysql benefit from
the whole change. but pgbench seems not always. so we are still on the
way to make possible
further tuning here.

>
>
> --
> Thanks and Regards
> gautham.

Thanks
Barry


From mathieu.poirier at linaro.org  Thu Jan 27 12:22:20 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Jan 2022 13:22:20 -0700
Subject: [PATCH V3 RESEND 0/7] coresight: trbe: Workaround Cortex-A510
 erratas
In-Reply-To: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <20220127202220.GA2191206@p14s>

On Tue, Jan 25, 2022 at 07:50:30PM +0530, Anshuman Khandual wrote:
> 	This series adds three different workarounds in the TRBE driver for
> Cortex-A510 specific erratas. But first, this adds Cortex-A510 specific cpu
> part number definition in the platform. This series applies on 5.17-rc1.
> 
> Relevant errata documents can be found here.
> 
> https://developer.arm.com/documentation/SDEN2397239/900
> https://developer.arm.com/documentation/SDEN2397589/900
> 
> Changes in V3:
> 
> https://lore.kernel.org/all/1641872346-3270-1-git-send-email-anshuman.khandual at arm.com/
> 
> - Moved the comment inside trbe_needs_drain_after_disable()
> - Moved the comment inside trbe_needs_ctxt_sync_after_enable()
> 
> Changes in V2:
> 
> https://lore.kernel.org/all/1641517808-5735-1-git-send-email-anshuman.khandual at arm.com/
> 
> Accommodated most review comments from the previous version.
> 
> - Split all patches into CPU errata definition, detection and TRBE workarounds
> - s/TRBE_WORKAROUND_SYSREG_WRITE_FAILURE/TRBE_NEEDS_DRAIN_AFTER_DISABLE
> - s/TRBE_WORKAROUND_CORRUPTION_WITH_ENABLE/TRBE_NEEDS_CTXT_SYNC_AFTER_ENABLE
> - s/trbe_may_fail_sysreg_write()/trbe_needs_drain_after_disable()
> - s/trbe_may_corrupt_with_enable()/trbe_needs_ctxt_sync_after_enable()
> - Updated Kconfig help message for config ARM64_ERRATUM_1902691
> - Updated error message for trbe_is_broken() detection
> - Added new trblimitr parameter to set_trbe_enabled(), improving performance
> - Added COMPILE_TEST dependency in the errata, until TRBE part is available
> 
> Changes in V1:
> 
> https://lore.kernel.org/lkml/1641359159-22726-1-git-send-email-anshuman.khandual at arm.com/
> 
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Will Deacon <will at kernel.org>
> Cc: Mathieu Poirier <mathieu.poirier at linaro.org>
> Cc: Suzuki Poulose <suzuki.poulose at arm.com>
> Cc: coresight at lists.linaro.org
> Cc: linux-doc at vger.kernel.org
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> 
> Anshuman Khandual (7):
>   arm64: Add Cortex-A510 CPU part definition
>   arm64: errata: Add detection for TRBE ignored system register writes
>   arm64: errata: Add detection for TRBE invalid prohibited states
>   arm64: errata: Add detection for TRBE trace data corruption
>   coresight: trbe: Work around the ignored system register writes
>   coresight: trbe: Work around the invalid prohibited states
>   coresight: trbe: Work around the trace data corruption
> 
>  Documentation/arm64/silicon-errata.rst       |   6 +
>  arch/arm64/Kconfig                           |  59 ++++++++++
>  arch/arm64/include/asm/cputype.h             |   2 +
>  arch/arm64/kernel/cpu_errata.c               |  27 +++++
>  arch/arm64/tools/cpucaps                     |   3 +
>  drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
>  drivers/hwtracing/coresight/coresight-trbe.h |   8 --
>  7 files changed, 183 insertions(+), 36 deletions(-)

I have applied this set and sent a pull request to Catalin for the arm64
portion.

Thanks,
Mathieu

> 
> -- 
> 2.25.1
> 


From mathieu.poirier at linaro.org  Thu Jan 27 12:26:26 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Jan 2022 13:26:26 -0700
Subject: [PATCH v2 0/6] coresight: Add config flag to enable branch
 broadcast
In-Reply-To: <20220113091056.1297982-1-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
Message-ID: <CANLsYkx4u_+hPNNdmN23g58RprqkcUfhoPeZhu578DKU0qJ_hg@mail.gmail.com>

Hi James,

I am seriously back-logged in my patch reviews and as such will not be
able to get to your work in the usual 14 days.  At this time and if
everything goes well, I should be able to start reviewing this
patchset during the week of February 7th.

Thanks,
Mathieu

On Thu, 13 Jan 2022 at 02:11, James Clark <james.clark at arm.com> wrote:
>
> This allows enabling branch broadcast for Perf hosted sessions (the option
> is currently only available for the sysfs interface). Hopefully this could
> be useful for testing the decode in perf, for example does a determinisitic
> run with branch broadcast enabled look the same as with it disabled? It
> could also be used for scenarios like OpenJ9's support for JIT code:
>
>   java -Xjit:perfTool hello.java
>
> Currently this is not working and you get the usual errors of a missing
> DSO, but branch broadcast would have to be enabled anyway before working
> through this next issue:
>
>   CS ETM Trace: Debug data not found for address 0xffff7b94b058 in /tmp/perf-29360.map
>
> Address range support in Perf for branch broadcast has also not been added
> here, but could be added later.
>
> The documentation has been refactored slightly to allow updates to be made
> that link the Perf format arguments with the existing documentation.
>
> For Suzuki's comment, I will do it as a separate change that converts all
> the other hard coded values to a more consistent sysreg.h style:
>
>   nit: While at this, please could you change the hard coded value
>   to ETM4_CFG_BIT_RETSTK ?
>
> Changes since v1:
>
>   * Added Leo's reviewed by on patch 3
>   * Fix bracket styling
>   * Add documentation
>
> Applies on top of coresight/next efa56eddf5d5c. But this docs fix is also
> required to get the links to work:
>   https://marc.info/?l=linux-doc&m=164139331923986&w=2
>
> Also available at: https://gitlab.arm.com/linux-arm/linux-jc/-/tree/james-branch-broadcast-v2
>
> James Clark (6):
>   coresight: Add config flag to enable branch broadcast
>   coresight: Fail to open with return stacks if they are unavailable
>   perf cs-etm: Update deduction of TRCCONFIGR register for branch
>     broadcast
>   Documentation: coresight: Turn numbered subsections into real
>     subsections
>   Documentation: coresight: Link config options to existing
>     documentation
>   Documentation: coresight: Expand branch broadcast documentation
>
>  .../coresight/coresight-etm4x-reference.rst   | 14 ++++-
>  Documentation/trace/coresight/coresight.rst   | 56 +++++++++++++++++--
>  .../hwtracing/coresight/coresight-etm-perf.c  |  2 +
>  .../coresight/coresight-etm4x-core.c          | 23 ++++++--
>  include/linux/coresight-pmu.h                 |  2 +
>  tools/include/linux/coresight-pmu.h           |  2 +
>  tools/perf/arch/arm/util/cs-etm.c             |  3 +
>  7 files changed, 92 insertions(+), 10 deletions(-)
>
> --
> 2.28.0
>


From mathieu.poirier at linaro.org  Thu Jan 27 12:28:23 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Thu, 27 Jan 2022 13:28:23 -0700
Subject: [RFC PATCH] ACPI / amba: Skip creating amba device when
 associated cpu is not online
In-Reply-To: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
References: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
Message-ID: <CANLsYkxdXFSVLEnJQTd87LqP5oootxyM3adbxvvpWSEvi5VcsA@mail.gmail.com>

Hi Cheng,

I am severely behind in my patch review process and as such will not
be able to start reviewing your work before the week of February 7th.

Thanks,
Mathieu

On Fri, 7 Jan 2022 at 01:47, chenxiang <chenxiang66 at hisilicon.com> wrote:
>
> From: Xiang Chen <chenxiang66 at hisilicon.com>
>
> If not up all the cpus with command line "maxcpus=x", system will be
> blocked.
> We find that some amba devices such as ETM devices, are associated with
> special cpus, and if the cpu is not up, the register of associated device
> is not allowed to access. BIOS reports all the ETM device nodes and a
> amba device is created for every ETM device, so even if one cpu is not up,
> the amba device will still be created for the associated device, and also
> the register of device (pid and cid) will be accessed when adding amba
> device which will cause the issue.
> To fix it, skip creating amba device if it is associated with a cpu which
> is not online.
>
> Signed-off-by: Xiang Chen <chenxiang66 at hisilicon.com>
> ---
>  drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
> index ab8a4e0191b1..2369198f734b 100644
> --- a/drivers/acpi/acpi_amba.c
> +++ b/drivers/acpi/acpi_amba.c
> @@ -16,6 +16,7 @@
>  #include <linux/ioport.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <acpi/processor.h>
>
>  #include "internal.h"
>
> @@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
>         clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
>  }
>
> +static int acpi_handle_to_cpuid(acpi_handle handle)
> +{
> +       int cpu = -1;
> +       struct acpi_processor *pr;
> +
> +       for_each_possible_cpu(cpu) {
> +               pr = per_cpu(processors, cpu);
> +               if (pr && pr->handle == handle)
> +                       break;
> +       }
> +
> +       return cpu;
> +}
> +
> +static int acpi_dev_get_cpu(struct acpi_device *adev)
> +{
> +       acpi_handle cpu_handle;
> +       acpi_status status;
> +       int cpu;
> +
> +       status = acpi_get_parent(adev->handle, &cpu_handle);
> +       if (ACPI_FAILURE(status))
> +               return -1;
> +       cpu = acpi_handle_to_cpuid(cpu_handle);
> +       if (cpu >= nr_cpu_ids)
> +               return -1;
> +       return cpu;
> +}
> +
>  static int amba_handler_attach(struct acpi_device *adev,
>                                 const struct acpi_device_id *id)
>  {
> @@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device *adev,
>         bool address_found = false;
>         int irq_no = 0;
>         int ret;
> +       int cpu;
>
>         /* If the ACPI node already has a physical device attached, skip it. */
>         if (adev->physical_node_count)
>                 return 0;
>
> +       /* If the cpu associated with the device is not online, skip it. */
> +       cpu = acpi_dev_get_cpu(adev);
> +       if (cpu >= 0 && !cpu_online(cpu))
> +               return 0;
> +
>         dev = amba_device_alloc(dev_name(&adev->dev), 0, 0);
>         if (!dev) {
>                 dev_err(&adev->dev, "%s(): amba_device_alloc() failed\n",
> --
> 2.33.0
>


From rostedt at goodmis.org  Thu Jan 27 12:38:32 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Thu, 27 Jan 2022 15:38:32 -0500
Subject: [PATCH v2] ftrace: Have architectures opt-in for mcount build time
 sorting
Message-ID: <20220127153821.3bc1ac6e@gandalf.local.home>

From f7d4ef4e77464e08af38789ea5d3a9cfb80a3d78 Mon Sep 17 00:00:00 2001
From: "Steven Rostedt (Google)" <rostedt at goodmis.org>
Date: Tue, 25 Jan 2022 09:19:10 -0500
Subject: [PATCH] ftrace: Have architectures opt-in for mcount build time
 sorting

First S390 complained that the sorting of the mcount sections at build
time caused the kernel to crash on their architecture. Now PowerPC is
complaining about it too. And also ARM64 appears to be having issues.

It may be necessary to also update the relocation table for the values
in the mcount table. Not only do we have to sort the table, but also
update the relocations that may be applied to the items in the table.

If the system is not relocatable, then it is fine to sort, but if it is,
some architectures may have issues (although x86 does not as it shifts all
addresses the same).

Add a HAVE_BUILDTIME_MCOUNT_SORT that an architecture can set to say it is
safe to do the sorting at build time.

Also update the config to compile in build time sorting in the sorttable
code in scripts/ to depend on CONFIG_BUILDTIME_MCOUNT_SORT.

Link: https://lore.kernel.org/all/944D10DA-8200-4BA9-8D0A-3BED9AA99F82 at linux.ibm.com/

Cc: Yinan Liu <yinan at linux.alibaba.com>
Cc: Ard Biesheuvel <ardb at kernel.org>
Cc: Kees Cook <keescook at chromium.org>
Reported-by: Sachin Sant <sachinp at linux.ibm.com>
Reviewed-by: Mark Rutland <mark.rutland at arm.com>
Tested-by: Mark Rutland <mark.rutland at arm.com> [arm64]
Tested-by: Sachin Sant <sachinp at linux.ibm.com>
Fixes: 72b3942a173c ("scripts: ftrace - move the sort-processing in ftrace_init")
Signed-off-by: Steven Rostedt (Google) <rostedt at goodmis.org>
---
Changes since v1: https://lore.kernel.org/all/20220127114249.03b1b52b at gandalf.local.home/
 - Have CONFIG_BUILDTIME_MCOUNT_SORT depend on DYNAMIC_FTRACE
   otherwise it fails to build when DYNAMIC_FTRACE is not set
   because it can not find the mcount section in the sorttable code.

 arch/arm/Kconfig     | 1 +
 arch/x86/Kconfig     | 1 +
 kernel/trace/Kconfig | 8 +++++++-
 scripts/Makefile     | 2 +-
 4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index c2724d986fa0..5256ebe57451 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -82,6 +82,7 @@ config ARM
 	select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
 	select HAVE_CONTEXT_TRACKING
 	select HAVE_C_RECORDMCOUNT
+	select HAVE_BUILDTIME_MCOUNT_SORT
 	select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
 	select HAVE_DMA_CONTIGUOUS if MMU
 	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 7399327d1eff..46080dea5dba 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -186,6 +186,7 @@ config X86
 	select HAVE_CONTEXT_TRACKING_OFFSTACK	if HAVE_CONTEXT_TRACKING
 	select HAVE_C_RECORDMCOUNT
 	select HAVE_OBJTOOL_MCOUNT		if STACK_VALIDATION
+	select HAVE_BUILDTIME_MCOUNT_SORT
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_CONTIGUOUS
 	select HAVE_DYNAMIC_FTRACE
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 752ed89a293b..a5eb5e7fd624 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -70,10 +70,16 @@ config HAVE_C_RECORDMCOUNT
 	help
 	  C version of recordmcount available?
 
+config HAVE_BUILDTIME_MCOUNT_SORT
+       bool
+       help
+         An architecture selects this if it sorts the mcount_loc section
+	 at build time.
+
 config BUILDTIME_MCOUNT_SORT
        bool
        default y
-       depends on BUILDTIME_TABLE_SORT && !S390
+       depends on HAVE_BUILDTIME_MCOUNT_SORT && DYNAMIC_FTRACE
        help
          Sort the mcount_loc section at build time.
 
diff --git a/scripts/Makefile b/scripts/Makefile
index b082d2f93357..cedc1f0e21d8 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -32,7 +32,7 @@ HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
 HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
 endif
 
-ifdef CONFIG_DYNAMIC_FTRACE
+ifdef CONFIG_BUILDTIME_MCOUNT_SORT
 HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
 endif
 
-- 
2.33.0



From lkp at intel.com  Thu Jan 27 13:00:44 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 28 Jan 2022 05:00:44 +0800
Subject: [PATCH 2/3] pinctrl: uniphier: Divide pinmux group to support
 1ch and 2ch I2S
In-Reply-To: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <202201280448.njc6LUNd-lkp@intel.com>

Hi Kunihiko,

I love your patch! Yet something to improve:

[auto build test ERROR on linusw-pinctrl/devel]
[also build test ERROR on v5.17-rc1 next-20220127]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Kunihiko-Hayashi/pinctrl-uniphier-Add-some-more-pinmux-settings/20220127-193715
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
config: openrisc-buildonly-randconfig-r003-20220124 (https://download.01.org/0day-ci/archive/20220128/202201280448.njc6LUNd-lkp at intel.com/config)
compiler: or1k-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/e0e366a006b79517336423f8a2c72661178d5e41
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Kunihiko-Hayashi/pinctrl-uniphier-Add-some-more-pinmux-settings/20220127-193715
        git checkout e0e366a006b79517336423f8a2c72661178d5e41
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=openrisc SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:12:
>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:34: error: 'aout4_groups' undeclared here (not in a function); did you mean 'aout3_groups'?
     958 |         UNIPHIER_PINMUX_FUNCTION(aout4),
         |                                  ^~~~~
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:179:27: note: in definition of macro 'UNIPHIER_PINMUX_FUNCTION'
     179 |                 .groups = func##_groups,                                \
         |                           ^~~~
   In file included from include/linux/container_of.h:5,
                    from include/linux/kernel.h:21,
                    from drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:6:
>> include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width not an integer constant
      16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
         |                                                   ^
   include/linux/compiler.h:258:33: note: in expansion of macro 'BUILD_BUG_ON_ZERO'
     258 | #define __must_be_array(a)      BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
         |                                 ^~~~~~~~~~~~~~~~~
   include/linux/kernel.h:55:59: note: in expansion of macro '__must_be_array'
      55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
         |                                                           ^~~~~~~~~~~~~~~
   drivers/pinctrl/uniphier/pinctrl-uniphier.h:180:31: note: in expansion of macro 'ARRAY_SIZE'
     180 |                 .num_groups = ARRAY_SIZE(func##_groups),                \
         |                               ^~~~~~~~~~
   drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:9: note: in expansion of macro 'UNIPHIER_PINMUX_FUNCTION'
     958 |         UNIPHIER_PINMUX_FUNCTION(aout4),
         |         ^~~~~~~~~~~~~~~~~~~~~~~~


vim +958 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c

   949	
   950	static const struct uniphier_pinmux_function uniphier_pxs2_functions[] = {
   951		UNIPHIER_PINMUX_FUNCTION(ain1),
   952		UNIPHIER_PINMUX_FUNCTION(ain2),
   953		UNIPHIER_PINMUX_FUNCTION(ain3),
   954		UNIPHIER_PINMUX_FUNCTION(ainiec1),
   955		UNIPHIER_PINMUX_FUNCTION(aout1),
   956		UNIPHIER_PINMUX_FUNCTION(aout2),
   957		UNIPHIER_PINMUX_FUNCTION(aout3),
 > 958		UNIPHIER_PINMUX_FUNCTION(aout4),
   959		UNIPHIER_PINMUX_FUNCTION(aoutiec1),
   960		UNIPHIER_PINMUX_FUNCTION(aoutiec2),
   961		UNIPHIER_PINMUX_FUNCTION(emmc),
   962		UNIPHIER_PINMUX_FUNCTION(ether_mii),
   963		UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
   964		UNIPHIER_PINMUX_FUNCTION(ether_rmii),
   965		UNIPHIER_PINMUX_FUNCTION(i2c0),
   966		UNIPHIER_PINMUX_FUNCTION(i2c1),
   967		UNIPHIER_PINMUX_FUNCTION(i2c2),
   968		UNIPHIER_PINMUX_FUNCTION(i2c3),
   969		UNIPHIER_PINMUX_FUNCTION(i2c5),
   970		UNIPHIER_PINMUX_FUNCTION(i2c6),
   971		UNIPHIER_PINMUX_FUNCTION(nand),
   972		UNIPHIER_PINMUX_FUNCTION(sd),
   973		UNIPHIER_PINMUX_FUNCTION(spi0),
   974		UNIPHIER_PINMUX_FUNCTION(spi1),
   975		UNIPHIER_PINMUX_FUNCTION(system_bus),
   976		UNIPHIER_PINMUX_FUNCTION(uart0),
   977		UNIPHIER_PINMUX_FUNCTION(uart1),
   978		UNIPHIER_PINMUX_FUNCTION(uart2),
   979		UNIPHIER_PINMUX_FUNCTION(uart3),
   980		UNIPHIER_PINMUX_FUNCTION(usb0),
   981		UNIPHIER_PINMUX_FUNCTION(usb1),
   982		UNIPHIER_PINMUX_FUNCTION(usb2),
   983		UNIPHIER_PINMUX_FUNCTION(usb3),
   984	};
   985	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From helgaas at kernel.org  Thu Jan 27 13:21:00 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 27 Jan 2022 15:21:00 -0600
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <d78b45e461b204d375830217d0d27ffdd97cedd3.camel@mediatek.com>
Message-ID: <20220127212100.GA102267@bhelgaas>

[+cc Srikanth, Pratyush, Thomas, Pali, Ryder, Jianjun]

On Wed, Jan 26, 2022 at 11:37:58AM +0800, qizhong.cheng wrote:
> On Tue, 2022-01-25 at 17:21 +0000, Marc Zyngier wrote:
> > On 2022-01-25 16:57, Bjorn Helgaas wrote:
> > > On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> > > > As an edge-triggered interrupts, its interrupt status should
> > > > be cleared before dispatch to the handler of device.
> > > 
> > > I'm not an IRQ expert, but the reasoning that "we should clear
> > > the MSI interrupt status before dispatching the handler because
> > > MSI is an edge-triggered interrupt" doesn't seem completely
> > > convincing because your code will now look like this:
> > > 
> > >   /* Clear the INTx */
> > >   writel(1 << bit, port->base + PCIE_INT_STATUS);
> > >   generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
> > >   ...
> > > 
> > >   /* Clear MSI interrupt status */
> > >   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
> > >   generic_handle_domain_irq(port->inner_domain, bit);
> > > 
> > > You clear interrupt status before dispatching the handler for
> > > *both* level-triggered INTx interrupts and edge-triggered MSI
> > > interrupts.
> > > 
> > > So it doesn't seem that simply being edge-triggered is the
> > > critical factor here.
> > 
> > This is the usual problem with these half-baked implementations.
> > The signalling to the primary interrupt controller is level, as
> > they take a multitude of input and (crucially) latch the MSI
> > edges. Effectively, this is an edge-to-level converter, with all
> > the problems that this creates.
> > 
> > By clearing the status *after* the handling, you lose edges that
> > have been received and coalesced after the read of the status
> > register. By clearing it *before*, you are acknowledging the
> > interrupts early, and allowing them to be coalesced independently
> > of the ones that have been received earlier.
> > 
> > This is however mostly an educated guess. Someone with access to
> > the TRM should verify this.
> 
> Yes, as Maz said, we save the edge-interrupt status so that it
> becomes a level-interrupt. This is similar to an edge-to-level
> converter, so we need to clear it *before*. We found this problem
> through a lot of experiments and tested this patch.

I thought there might be other host controllers with similar design,
so I looked at all the other drivers and tried to figure out whether
any others had similar problems.

The ones below look suspicious to me because they all clear some sort
of status register *after* handling an MSI.  Can you guys take a look
and make sure they are working correctly?

  keembay_pcie_msi_irq_handler
    status = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
    if (status & MSI_CTRL_INT)
      dw_handle_msi_irq
	generic_handle_domain_irq
      writel(status, pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)

  spear13xx_pcie_irq_handler
    status = readl(&app_reg->int_sts)
    if (status & MSI_CTRL_INT)
      dw_handle_msi_irq
	generic_handle_domain_irq
    writel(status, &app_reg->int_clr)

  advk_pcie_handle_int
    isr0_status = advk_readl(pcie, PCIE_ISR0_REG)
    if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
      advk_pcie_handle_msi
        advk_readl(pcie, PCIE_MSI_STATUS_REG)
	advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG)
	generic_handle_irq
	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG)

  mtk_pcie_irq_handler
    status = readl_relaxed(pcie->base + PCIE_INT_STATUS_REG)
    for_each_set_bit_from(irq_bit, &status, ...)
      mtk_pcie_msi_handler
        generic_handle_domain_irq
      writel_relaxed(BIT(irq_bit), pcie->base + PCIE_INT_STATUS_REG)

Bjorn


From f.fainelli at gmail.com  Thu Jan 27 13:50:31 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Thu, 27 Jan 2022 13:50:31 -0800
Subject: [PATCH] pinctrl: bcm2835: Fix a few error paths
Message-ID: <20220127215033.267227-1-f.fainelli@gmail.com>

After commit 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio
hogs") a few error paths would not unwind properly the registration of
gpio ranges. Correct that by assigning a single error label and goto it
whenever we encounter a fatal error.

Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>
---
 drivers/pinctrl/bcm/pinctrl-bcm2835.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
index c4ebfa852b42..47e433e09c5c 100644
--- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c
+++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c
@@ -1269,16 +1269,18 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 				     sizeof(*girq->parents),
 				     GFP_KERNEL);
 	if (!girq->parents) {
-		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out_remove;
 	}
 
 	if (is_7211) {
 		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
 					    sizeof(*pc->wake_irq),
 					    GFP_KERNEL);
-		if (!pc->wake_irq)
-			return -ENOMEM;
+		if (!pc->wake_irq) {
+			err = -ENOMEM;
+			goto out_remove;
+		}
 	}
 
 	/*
@@ -1306,8 +1308,10 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 
 		len = strlen(dev_name(pc->dev)) + 16;
 		name = devm_kzalloc(pc->dev, len, GFP_KERNEL);
-		if (!name)
-			return -ENOMEM;
+		if (!name) {
+			err = -ENOMEM;
+			goto out_remove;
+		}
 
 		snprintf(name, len, "%s:bank%d", dev_name(pc->dev), i);
 
@@ -1326,11 +1330,14 @@ static int bcm2835_pinctrl_probe(struct platform_device *pdev)
 	err = gpiochip_add_data(&pc->gpio_chip, pc);
 	if (err) {
 		dev_err(dev, "could not add GPIO chip\n");
-		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
-		return err;
+		goto out_remove;
 	}
 
 	return 0;
+
+out_remove:
+	pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
+	return err;
 }
 
 static struct platform_driver bcm2835_pinctrl_driver = {
-- 
2.25.1



From helgaas at kernel.org  Thu Jan 27 14:29:51 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Thu, 27 Jan 2022 16:29:51 -0600
Subject: [PATCH] Revert "PCI: j721e: Drop redundant struct device *"
In-Reply-To: <20220124122132.435743-1-christian.gmeiner@gmail.com>
Message-ID: <20220127222951.GA144828@bhelgaas>

On Mon, Jan 24, 2022 at 01:21:22PM +0100, Christian Gmeiner wrote:
> This reverts commit 19e863828acf6d8ac8475ba1fd93c0fe17fdc4ef.
> 
> Fixes the following oops:
>  Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010

Hi Christian,

Would you mind trying this patch?

commit 9d36a93af8fe ("PCI: j721e: Initialize pcie->cdns_pcie before using it")
Author: Bjorn Helgaas <bhelgaas at google.com>
Date:   Thu Jan 27 15:49:49 2022 -0600

    PCI: j721e: Initialize pcie->cdns_pcie before using it
    
    Christian reported a NULL pointer dereference in j721e_pcie_probe() caused
    by 19e863828acf ("PCI: j721e: Drop redundant struct device *"), which
    removed struct j721e_pcie.dev since there's another copy in struct
    cdns_pcie.dev reachable via j721e_pcie->cdns_pcie->dev.
    
    The problem is that j721e_pcie->cdns_pcie was dereferenced before being
    initialized:
    
      j721e_pcie_probe
        pcie = devm_kzalloc()             # struct j721e_pcie
        j721e_pcie_ctrl_init(pcie)
          dev = pcie->cdns_pcie->dev      <-- dereference cdns_pcie
        switch (mode) {
        case PCI_MODE_RC:
          cdns_pcie = ...                 # alloc as part of pci_host_bridge
          pcie->cdns_pcie = cdns_pcie     <-- initialize pcie->cdns_pcie
    
    Initialize pcie->cdns_pcie before it is used.
    
    Fixes: 19e863828acf ("PCI: j721e: Drop redundant struct device *")
    Reported-by: Christian Gmeiner <christian.gmeiner at gmail.com>
    Link: https://lore.kernel.org/r/20220124122132.435743-1-christian.gmeiner at gmail.com
    Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>

diff --git a/drivers/pci/controller/cadence/pci-j721e.c b/drivers/pci/controller/cadence/pci-j721e.c
index 489586a4cdc7..5d950c1d9fd0 100644
--- a/drivers/pci/controller/cadence/pci-j721e.c
+++ b/drivers/pci/controller/cadence/pci-j721e.c
@@ -372,10 +372,48 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 	mode = (u32)data->mode;
 
+	switch (mode) {
+	case PCI_MODE_RC:
+		if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST))
+			return -ENODEV;
+
+		bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
+		if (!bridge)
+			return -ENOMEM;
+
+		if (!data->byte_access_allowed)
+			bridge->ops = &cdns_ti_pcie_host_ops;
+		rc = pci_host_bridge_priv(bridge);
+		rc->quirk_retrain_flag = data->quirk_retrain_flag;
+		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
+
+		cdns_pcie = &rc->pcie;
+		break;
+	case PCI_MODE_EP:
+		if (!IS_ENABLED(CONFIG_PCIE_CADENCE_EP))
+			return -ENODEV;
+
+		ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
+		if (!ep)
+			return -ENOMEM;
+
+		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
+
+		cdns_pcie = &ep->pcie;
+		break;
+	default:
+		dev_err(dev, "INVALID device type %d\n", mode);
+		return 0;
+	}
+
+	cdns_pcie->dev = dev;
+	cdns_pcie->ops = &j721e_pcie_ops;
+
 	pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 	if (!pcie)
 		return -ENOMEM;
 
+	pcie->cdns_pcie = cdns_pcie;
 	pcie->mode = mode;
 	pcie->linkdown_irq_regfield = data->linkdown_irq_regfield;
 
@@ -426,28 +464,6 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 	switch (mode) {
 	case PCI_MODE_RC:
-		if (!IS_ENABLED(CONFIG_PCIE_CADENCE_HOST)) {
-			ret = -ENODEV;
-			goto err_get_sync;
-		}
-
-		bridge = devm_pci_alloc_host_bridge(dev, sizeof(*rc));
-		if (!bridge) {
-			ret = -ENOMEM;
-			goto err_get_sync;
-		}
-
-		if (!data->byte_access_allowed)
-			bridge->ops = &cdns_ti_pcie_host_ops;
-		rc = pci_host_bridge_priv(bridge);
-		rc->quirk_retrain_flag = data->quirk_retrain_flag;
-		rc->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
-
-		cdns_pcie = &rc->pcie;
-		cdns_pcie->dev = dev;
-		cdns_pcie->ops = &j721e_pcie_ops;
-		pcie->cdns_pcie = cdns_pcie;
-
 		gpiod = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 		if (IS_ERR(gpiod)) {
 			ret = PTR_ERR(gpiod);
@@ -497,23 +513,6 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 
 		break;
 	case PCI_MODE_EP:
-		if (!IS_ENABLED(CONFIG_PCIE_CADENCE_EP)) {
-			ret = -ENODEV;
-			goto err_get_sync;
-		}
-
-		ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
-		if (!ep) {
-			ret = -ENOMEM;
-			goto err_get_sync;
-		}
-		ep->quirk_detect_quiet_flag = data->quirk_detect_quiet_flag;
-
-		cdns_pcie = &ep->pcie;
-		cdns_pcie->dev = dev;
-		cdns_pcie->ops = &j721e_pcie_ops;
-		pcie->cdns_pcie = cdns_pcie;
-
 		ret = cdns_pcie_init_phy(dev, cdns_pcie);
 		if (ret) {
 			dev_err(dev, "Failed to init phy\n");
@@ -525,8 +524,6 @@ static int j721e_pcie_probe(struct platform_device *pdev)
 			goto err_pcie_setup;
 
 		break;
-	default:
-		dev_err(dev, "INVALID device type %d\n", mode);
 	}
 
 	return 0;


From tharvey at gateworks.com  Thu Jan 27 14:49:41 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Thu, 27 Jan 2022 14:49:41 -0800
Subject: [PATCH] arm64: dts: imx8m{m,n}_venice*: add gpio-line-names
In-Reply-To: <20220126090739.GH4686@dragon>
References: <20211215001812.9006-1-tharvey@gateworks.com>
 <20220126090739.GH4686@dragon>
Message-ID: <CAJ+vNU3Xj-b2BSc_6MQrtrh-G=5dMdMmw0S8EtujVz_7FvkQ0w@mail.gmail.com>

On Wed, Jan 26, 2022 at 1:07 AM Shawn Guo <shawnguo at kernel.org> wrote:
>
> On Tue, Dec 14, 2021 at 04:18:12PM -0800, Tim Harvey wrote:
> > Add gpio-line-names for the various GPIO's used on Gateworks Venice
> > boards. Note that these GPIO's are typically 'configured' in Boot
> > Firmware via gpio-hog therefore we only configure line names to keep the
> > boot firmware configuration from changing on kernel init.
> >
> > Signed-off-by: Tim Harvey <tharvey at gateworks.com>
>
> It doesn't apply to my imx/dt64 branch.  Could you rebase?
>

Shawn,

Sure, I'll try to submit another version within a couple of days.

Did you happen to see 'arm64: dts: imx8mm-venice*: add PCIe support'
[1]? It seems to have been archived for some reason and it may have to
be rebased after I re-post this one unless you can take that now.

Best Regards,

Tim
[1] - https://patchwork.kernel.org/project/linux-arm-kernel/patch/20211216164149.13333-1-tharvey at gateworks.com/


From briannorris at chromium.org  Thu Jan 27 15:07:11 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:11 -0800
Subject: [PATCH v2 00/15] rk3399: Clean up and enable DDR DVFS
Message-ID: <20220127230727.3369358-1-briannorris@chromium.org>

This series covers 2 primary tasks:

1) Resubmit prior work:

[RESEND PATCH v5 3/4] arm64: dts: rockchip: Enable dmc and dfi nodes on gru.
https://lore.kernel.org/lkml/20210308233858.24741-2-daniel.lezcano at linaro.org/
[RESEND PATCH v5 2/4] arm64: dts: rk3399: Add dfi and dmc nodes.
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/

This series was partially merged a while back, but the remaining 2
patches were blocked mostly on stylistic grounds (alpha/numerical
ordering).

2) Integrate many updates, bugfixes, and clarifications that were done
by Rockchip and Google engineers when first launching this platform.
Many of these were not integrated in the earlier series (e.g., the OPPs
changed before production; earlier patchsets used pre-production
numbers).

Along the way, it seemed worthwhile to convert the binding docs to a
schema. Among other reasons, it actually helped catch several errors and
omissions in translation between downstream device trees and the version
that actually landed upstream.

See the patches for further details.

Regards,
Brian

Changes in v2:
 - Fix yamllint issues
 - Adapt to various review comments (use of *-hz, hyphens, node naming)
 - Add a few new bugfixes
 - Add some new properties (ported from downstream kernels) required for
   stability
 - Convert more properties from "cycles" to "nanoseconds"

Brian Norris (13):
  dt-bindings: devfreq: rk3399_dmc: Convert to YAML
  dt-bindings: devfreq: rk3399_dmc: Deprecate unused/redundant
    properties
  dt-bindings: devfreq: rk3399_dmc: Fix Hz units
  dt-bindings: devfreq: rk3399_dmc: Specify idle params in nanoseconds
  dt-bindings: devfreq: rk3399_dmc: Add more disable-freq properties
  PM / devfreq: rk3399_dmc: Drop undocumented ondemand DT props
  PM / devfreq: rk3399_dmc: Drop excess timing properties
  PM / devfreq: rk3399_dmc: Use bitfield macro definitions for ODT_PD
  PM / devfreq: rk3399_dmc: Support new disable-freq properties
  PM / devfreq: rk3399_dmc: Support new *-ns properties
  PM / devfreq: rk3399_dmc: Disable edev on remove()
  PM / devfreq: rk3399_dmc: Use devm_pm_opp_of_add_table()
  PM / devfreq: rk3399_dmc: Avoid static (reused) profile

Lin Huang (2):
  arm64: dts: rk3399: Add dfi and dmc nodes
  arm64: dts: rockchip: Enable dmc and dfi nodes on gru

 .../bindings/devfreq/rk3399_dmc.txt           | 212 ----------
 .../bindings/devfreq/rk3399_dmc.yaml          | 370 ++++++++++++++++++
 .../dts/rockchip/rk3399-gru-chromebook.dtsi   |   7 +
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi |  12 +
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi  |  28 ++
 .../boot/dts/rockchip/rk3399-op1-opp.dtsi     |  25 ++
 arch/arm64/boot/dts/rockchip/rk3399.dtsi      |  19 +
 drivers/devfreq/rk3399_dmc.c                  | 299 +++++++-------
 8 files changed, 595 insertions(+), 377 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml

-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:13 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:13 -0800
Subject: [PATCH v2 02/15] dt-bindings: devfreq: rk3399_dmc: Deprecate
 unused/redundant properties
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>

These DRAM configuration properties are all handled in ARM Trusted
Firmware (and have been since the early days of this SoC), and there are
no in-tree users of the DMC binding yet. It's better to just defer to
firmware instead of maintaining this large list of properties.

There's also some confusion about units: many of these are specified in
MHz, but the downstream users and driver code are treating them as Hz, I
believe. Rather than straighten all that out, I just drop them.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 .../bindings/devfreq/rk3399_dmc.yaml          | 42 +++++++++----------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index 467a7b5b374b..fd62a8cd62d5 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -46,6 +46,7 @@ properties:
       finishes, a DCF interrupt is triggered.
 
   rockchip,ddr3_speed_bin:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
@@ -92,6 +93,7 @@ properties:
       if bus is idle for standby_idle * DFI clock cycles.
 
   rockchip,dram_dll_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
@@ -99,6 +101,7 @@ properties:
       Note: if DLL was bypassed, the odt will also stop working.
 
   rockchip,phy_dll_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description: |
       Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
@@ -106,6 +109,7 @@ properties:
       Note: PHY DLL and PHY ODT are independent.
 
   rockchip,auto_pd_dis_freq:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Defines the auto PD disable frequency in MHz.
@@ -119,18 +123,21 @@ properties:
       disabled.
 
   rockchip,ddr3_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the DRAM side drive
       strength in ohms. Default value is 40.
 
   rockchip,ddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the DRAM side ODT
       strength in ohms. Default value is 120.
 
   rockchip,phy_ddr3_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the phy side CA line
@@ -138,12 +145,14 @@ properties:
       Default value is 40.
 
   rockchip,phy_ddr3_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 40.
 
   rockchip,phy_ddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is DDR3, this parameter defines the PHY side ODT
@@ -158,18 +167,21 @@ properties:
       disabled.
 
   rockchip,lpddr3_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
       strength in ohms. Default value is 34.
 
   rockchip,lpddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
       strength in ohms. Default value is 240.
 
   rockchip,phy_lpddr3_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
@@ -177,12 +189,14 @@ properties:
       Default value is 40.
 
   rockchip,phy_lpddr3_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 40.
 
   rockchip,phy_lpddr3_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When dram type is LPDDR3, this parameter define the phy side odt
@@ -197,42 +211,49 @@ properties:
       disabled.
 
   rockchip,lpddr4_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
       strength in ohms. Default value is 60.
 
   rockchip,lpddr4_dq_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
       DQS/DQ line strength in ohms. Default value is 40.
 
   rockchip,lpddr4_ca_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
       CA line strength in ohms. Default value is 40.
 
   rockchip,phy_lpddr4_ca_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
       (including command address line) drive strength. Default value is 40.
 
   rockchip,phy_lpddr4_ck_cs_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side clock
       line and CS line drive strength. Default value is 80.
 
   rockchip,phy_lpddr4_dq_drv:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
       (including DQS/DQ/DM line) drive strength. Default value is 80.
 
   rockchip,phy_lpddr4_odt:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
@@ -261,33 +282,12 @@ examples:
       clock-names = "dmc_clk";
       operating-points-v2 = <&dmc_opp_table>;
       center-supply = <&ppvar_centerlogic>;
-      rockchip,ddr3_speed_bin = <21>;
       rockchip,pd_idle = <0x40>;
       rockchip,sr_idle = <0x2>;
       rockchip,sr_mc_gate_idle = <0x3>;
       rockchip,srpd_lite_idle = <0x4>;
       rockchip,standby_idle = <0x2000>;
-      rockchip,dram_dll_dis_freq = <300>;
-      rockchip,phy_dll_dis_freq = <125>;
-      rockchip,auto_pd_dis_freq = <666>;
       rockchip,ddr3_odt_dis_freq = <333>;
-      rockchip,ddr3_drv = <40>;
-      rockchip,ddr3_odt = <120>;
-      rockchip,phy_ddr3_ca_drv = <40>;
-      rockchip,phy_ddr3_dq_drv = <40>;
-      rockchip,phy_ddr3_odt = <240>;
       rockchip,lpddr3_odt_dis_freq = <333>;
-      rockchip,lpddr3_drv = <34>;
-      rockchip,lpddr3_odt = <240>;
-      rockchip,phy_lpddr3_ca_drv = <40>;
-      rockchip,phy_lpddr3_dq_drv = <40>;
-      rockchip,phy_lpddr3_odt = <240>;
       rockchip,lpddr4_odt_dis_freq = <333>;
-      rockchip,lpddr4_drv = <60>;
-      rockchip,lpddr4_dq_odt = <40>;
-      rockchip,lpddr4_ca_odt = <40>;
-      rockchip,phy_lpddr4_ca_drv = <40>;
-      rockchip,phy_lpddr4_ck_cs_drv = <80>;
-      rockchip,phy_lpddr4_dq_drv = <80>;
-      rockchip,phy_lpddr4_odt = <60>;
     };
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:12 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:12 -0800
Subject: [PATCH v2 01/15] dt-bindings: devfreq: rk3399_dmc: Convert to YAML
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.1.I875ab8f28c5155a7d2f103316191954d4b07ac13@changeid>

I want to add, deprecate, and bugfix some properties, as well as add the
first users. This is easier with a proper schema.

The transformation is mostly straightforward, plus a few notable tweaks:

 * Renamed rockchip,dram_speed_bin to rockchip,ddr3_speed_bin. The
   driver code and the example matched, but the description was
   different. I went with the implementation.

 * Drop upthreshold and downdifferential properties from the example.
   These were undocumented (so, wouldn't pass validation), but were
   representing software properties (governor tweaks). I drop them from
   the driver in subsequent patches.

 * Rename clock from pclk_ddr_mon to dmc_clk. The driver, DT example,
   and all downstream users matched -- the binding definition was the
   exception. Anyway, "dmc_clk" is a more appropriately generic name.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 * rename to 'memory-controller' in example
 * place 'required' after properties
 * drop superluous free-form references and repetitions of other
   bindings
 * fix for yamllint

 .../bindings/devfreq/rk3399_dmc.txt           | 212 -------------
 .../bindings/devfreq/rk3399_dmc.yaml          | 293 ++++++++++++++++++
 2 files changed, 293 insertions(+), 212 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
 create mode 100644 Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
deleted file mode 100644
index 58fc8a6cebc7..000000000000
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.txt
+++ /dev/null
@@ -1,212 +0,0 @@
-* Rockchip rk3399 DMC (Dynamic Memory Controller) device
-
-Required properties:
-- compatible:		 Must be "rockchip,rk3399-dmc".
-- devfreq-events:	 Node to get DDR loading, Refer to
-			 Documentation/devicetree/bindings/devfreq/event/
-			 rockchip-dfi.txt
-- clocks:		 Phandles for clock specified in "clock-names" property
-- clock-names :		 The name of clock used by the DFI, must be
-			 "pclk_ddr_mon";
-- operating-points-v2:	 Refer to Documentation/devicetree/bindings/opp/opp-v2.yaml
-			 for details.
-- center-supply:	 DMC supply node.
-- status:		 Marks the node enabled/disabled.
-- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
-			 files".
-
-Optional properties:
-- interrupts:		 The CPU interrupt number. The interrupt specifier
-			 format depends on the interrupt controller.
-			 It should be a DCF interrupt. When DDR DVFS finishes
-			 a DCF interrupt is triggered.
-- rockchip,pmu:		 Phandle to the syscon managing the "PMU general register
-			 files".
-
-Following properties relate to DDR timing:
-
-- rockchip,dram_speed_bin :	  Value reference include/dt-bindings/clock/rk3399-ddr.h,
-				  it selects the DDR3 cl-trp-trcd type. It must be
-				  set according to "Speed Bin" in DDR3 datasheet,
-				  DO NOT use a smaller "Speed Bin" than specified
-				  for the DDR3 being used.
-
-- rockchip,pd_idle :		  Configure the PD_IDLE value. Defines the
-				  power-down idle period in which memories are
-				  placed into power-down mode if bus is idle
-				  for PD_IDLE DFI clock cycles.
-
-- rockchip,sr_idle :		  Configure the SR_IDLE value. Defines the
-				  self-refresh idle period in which memories are
-				  placed into self-refresh mode if bus is idle
-				  for SR_IDLE * 1024 DFI clock cycles (DFI
-				  clocks freq is half of DRAM clock), default
-				  value is "0".
-
-- rockchip,sr_mc_gate_idle :	  Defines the memory self-refresh and controller
-				  clock gating idle period. Memories are placed
-				  into self-refresh mode and memory controller
-				  clock arg gating started if bus is idle for
-				  sr_mc_gate_idle*1024 DFI clock cycles.
-
-- rockchip,srpd_lite_idle :	  Defines the self-refresh power down idle
-				  period in which memories are placed into
-				  self-refresh power down mode if bus is idle
-				  for srpd_lite_idle * 1024 DFI clock cycles.
-				  This parameter is for LPDDR4 only.
-
-- rockchip,standby_idle :	  Defines the standby idle period in which
-				  memories are placed into self-refresh mode.
-				  The controller, pi, PHY and DRAM clock will
-				  be gated if bus is idle for standby_idle * DFI
-				  clock cycles.
-
-- rockchip,dram_dll_dis_freq :	  Defines the DDR3 DLL bypass frequency in MHz.
-				  When DDR frequency is less than DRAM_DLL_DISB_FREQ,
-				  DDR3 DLL will be bypassed. Note: if DLL was bypassed,
-				  the odt will also stop working.
-
-- rockchip,phy_dll_dis_freq :	  Defines the PHY dll bypass frequency in
-				  MHz (Mega Hz). When DDR frequency is less than
-				  DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
-				  Note: PHY DLL and PHY ODT are independent.
-
-- rockchip,ddr3_odt_dis_freq :	  When the DRAM type is DDR3, this parameter defines
-				  the ODT disable frequency in MHz (Mega Hz).
-				  when the DDR frequency is  less then ddr3_odt_dis_freq,
-				  the ODT on the DRAM side and controller side are
-				  both disabled.
-
-- rockchip,ddr3_drv :		  When the DRAM type is DDR3, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 40.
-
-- rockchip,ddr3_odt :		  When the DRAM type is DDR3, this parameter defines
-				  the DRAM side ODT strength in ohms. Default value
-				  is 120.
-
-- rockchip,phy_ddr3_ca_drv :	  When the DRAM type is DDR3, this parameter defines
-				  the phy side CA line (incluing command line,
-				  address line and clock line) driver strength.
-				  Default value is 40.
-
-- rockchip,phy_ddr3_dq_drv :	  When the DRAM type is DDR3, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 40.
-
-- rockchip,phy_ddr3_odt : 	  When the DRAM type is DDR3, this parameter defines
-				  the PHY side ODT strength. Default value is 240.
-
-- rockchip,lpddr3_odt_dis_freq : When the DRAM type is LPDDR3, this parameter defines
-				  then ODT disable frequency in MHz (Mega Hz).
-				  When DDR frequency is less then ddr3_odt_dis_freq,
-				  the ODT on the DRAM side and controller side are
-				  both disabled.
-
-- rockchip,lpddr3_drv :		  When the DRAM type is LPDDR3, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 34.
-
-- rockchip,lpddr3_odt :		  When the DRAM type is LPDDR3, this parameter defines
-				  the DRAM side ODT strength in ohms. Default value
-				  is 240.
-
-- rockchip,phy_lpddr3_ca_drv :	  When the DRAM type is LPDDR3, this parameter defines
-				  the PHY side CA line (including command line,
-				  address line and clock line) driver strength.
-				  Default value is 40.
-
-- rockchip,phy_lpddr3_dq_drv :	  When the DRAM type is LPDDR3, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 40.
-
-- rockchip,phy_lpddr3_odt : 	  When dram type is LPDDR3, this parameter define
-				  the phy side odt strength, default value is 240.
-
-- rockchip,lpddr4_odt_dis_freq : When the DRAM type is LPDDR4, this parameter
-				  defines the ODT disable frequency in
-				  MHz (Mega Hz). When the DDR frequency is less then
-				  ddr3_odt_dis_freq, the ODT on the DRAM side and
-				  controller side are both disabled.
-
-- rockchip,lpddr4_drv :		  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side driver strength in ohms. Default
-				  value is 60.
-
-- rockchip,lpddr4_dq_odt : 	  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side ODT on DQS/DQ line strength in ohms.
-				  Default value is 40.
-
-- rockchip,lpddr4_ca_odt :	  When the DRAM type is LPDDR4, this parameter defines
-				  the DRAM side ODT on CA line strength in ohms.
-				  Default value is 40.
-
-- rockchip,phy_lpddr4_ca_drv :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side CA line (including command address
-				  line) driver strength. Default value is 40.
-
-- rockchip,phy_lpddr4_ck_cs_drv : When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side clock line and CS line driver
-				  strength. Default value is 80.
-
-- rockchip,phy_lpddr4_dq_drv :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side DQ line (including DQS/DQ/DM line)
-				  driver strength. Default value is 80.
-
-- rockchip,phy_lpddr4_odt :	  When the DRAM type is LPDDR4, this parameter defines
-				  the PHY side ODT strength. Default value is 60.
-
-Example:
-	dmc_opp_table: dmc_opp_table {
-		compatible = "operating-points-v2";
-
-		opp00 {
-			opp-hz = /bits/ 64 <300000000>;
-			opp-microvolt = <900000>;
-		};
-		opp01 {
-			opp-hz = /bits/ 64 <666000000>;
-			opp-microvolt = <900000>;
-		};
-	};
-
-	dmc: dmc {
-		compatible = "rockchip,rk3399-dmc";
-		devfreq-events = <&dfi>;
-		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru SCLK_DDRC>;
-		clock-names = "dmc_clk";
-		operating-points-v2 = <&dmc_opp_table>;
-		center-supply = <&ppvar_centerlogic>;
-		upthreshold = <15>;
-		downdifferential = <10>;
-		rockchip,ddr3_speed_bin = <21>;
-		rockchip,pd_idle = <0x40>;
-		rockchip,sr_idle = <0x2>;
-		rockchip,sr_mc_gate_idle = <0x3>;
-		rockchip,srpd_lite_idle	= <0x4>;
-		rockchip,standby_idle = <0x2000>;
-		rockchip,dram_dll_dis_freq = <300>;
-		rockchip,phy_dll_dis_freq = <125>;
-		rockchip,auto_pd_dis_freq = <666>;
-		rockchip,ddr3_odt_dis_freq = <333>;
-		rockchip,ddr3_drv = <40>;
-		rockchip,ddr3_odt = <120>;
-		rockchip,phy_ddr3_ca_drv = <40>;
-		rockchip,phy_ddr3_dq_drv = <40>;
-		rockchip,phy_ddr3_odt = <240>;
-		rockchip,lpddr3_odt_dis_freq = <333>;
-		rockchip,lpddr3_drv = <34>;
-		rockchip,lpddr3_odt = <240>;
-		rockchip,phy_lpddr3_ca_drv = <40>;
-		rockchip,phy_lpddr3_dq_drv = <40>;
-		rockchip,phy_lpddr3_odt = <240>;
-		rockchip,lpddr4_odt_dis_freq = <333>;
-		rockchip,lpddr4_drv = <60>;
-		rockchip,lpddr4_dq_odt = <40>;
-		rockchip,lpddr4_ca_odt = <40>;
-		rockchip,phy_lpddr4_ca_drv = <40>;
-		rockchip,phy_lpddr4_ck_cs_drv = <80>;
-		rockchip,phy_lpddr4_dq_drv = <80>;
-		rockchip,phy_lpddr4_odt = <60>;
-	};
diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
new file mode 100644
index 000000000000..467a7b5b374b
--- /dev/null
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -0,0 +1,293 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# %YAML 1.2
+---
+$id: http://devicetree.org/schemas/devfreq/rk3399_dmc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Rockchip rk3399 DMC (Dynamic Memory Controller) device
+
+maintainers:
+  - Brian Norris <briannorris at chromium.org>
+
+properties:
+  compatible:
+    enum:
+      - rockchip,rk3399-dmc
+
+  devfreq-events:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    minItems: 1
+    description:
+      Node to get DDR loading. Refer to
+      Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt.
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: dmc_clk
+
+  operating-points-v2: true
+
+  center-supply:
+    description:
+      DMC regulator supply.
+
+  rockchip,pmu:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon managing the "PMU general register files".
+
+  interrupts:
+    maxItems: 1
+    description:
+      The CPU interrupt number. It should be a DCF interrupt. When DDR DVFS
+      finishes, a DCF interrupt is triggered.
+
+  rockchip,ddr3_speed_bin:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      For values, reference include/dt-bindings/clock/rk3399-ddr.h. Selects the
+      DDR3 cl-trp-trcd type. It must be set according to "Speed Bin" in DDR3
+      datasheet; DO NOT use a smaller "Speed Bin" than specified for the DDR3
+      being used.
+
+  rockchip,pd_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Configure the PD_IDLE value. Defines the power-down idle period in which
+      memories are placed into power-down mode if bus is idle for PD_IDLE DFI
+      clock cycles.
+
+  rockchip,sr_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Configure the SR_IDLE value. Defines the self-refresh idle period in
+      which memories are placed into self-refresh mode if bus is idle for
+      SR_IDLE * 1024 DFI clock cycles (DFI clocks freq is half of DRAM clock).
+      Default value is "0".
+
+  rockchip,sr_mc_gate_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the memory self-refresh and controller clock gating idle period.
+      Memories are placed into self-refresh mode and memory controller clock
+      arg gating started if bus is idle for sr_mc_gate_idle*1024 DFI clock
+      cycles.
+
+  rockchip,srpd_lite_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the self-refresh power down idle period in which memories are
+      placed into self-refresh power down mode if bus is idle for
+      srpd_lite_idle * 1024 DFI clock cycles. This parameter is for LPDDR4
+      only.
+
+  rockchip,standby_idle:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the standby idle period in which memories are placed into
+      self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
+      if bus is idle for standby_idle * DFI clock cycles.
+
+  rockchip,dram_dll_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Defines the DDR3 DLL bypass frequency in MHz. When DDR frequency is less
+      than DRAM_DLL_DISB_FREQ, DDR3 DLL will be bypassed.
+      Note: if DLL was bypassed, the odt will also stop working.
+
+  rockchip,phy_dll_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Defines the PHY dll bypass frequency in MHz (Mega Hz). When DDR frequency
+      is less than DRAM_DLL_DISB_FREQ, PHY DLL will be bypassed.
+      Note: PHY DLL and PHY ODT are independent.
+
+  rockchip,auto_pd_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Defines the auto PD disable frequency in MHz.
+
+  rockchip,ddr3_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the ODT disable
+      frequency in MHz (Mega Hz). When the DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,ddr3_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 40.
+
+  rockchip,ddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the DRAM side ODT
+      strength in ohms. Default value is 120.
+
+  rockchip,phy_ddr3_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the phy side CA line
+      (incluing command line, address line and clock line) drive strength.
+      Default value is 40.
+
+  rockchip,phy_ddr3_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 40.
+
+  rockchip,phy_ddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is DDR3, this parameter defines the PHY side ODT
+      strength. Default value is 240.
+
+  rockchip,lpddr3_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines then ODT disable
+      frequency in MHz (Mega Hz). When DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,lpddr3_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 34.
+
+  rockchip,lpddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the DRAM side ODT
+      strength in ohms. Default value is 240.
+
+  rockchip,phy_lpddr3_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the PHY side CA line
+      (including command line, address line and clock line) drive strength.
+      Default value is 40.
+
+  rockchip,phy_lpddr3_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR3, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 40.
+
+  rockchip,phy_lpddr3_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When dram type is LPDDR3, this parameter define the phy side odt
+      strength, default value is 240.
+
+  rockchip,lpddr4_odt_dis_freq:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the ODT disable
+      frequency in MHz (Mega Hz). When the DDR frequency is less then
+      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
+      disabled.
+
+  rockchip,lpddr4_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side drive
+      strength in ohms. Default value is 60.
+
+  rockchip,lpddr4_dq_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
+      DQS/DQ line strength in ohms. Default value is 40.
+
+  rockchip,lpddr4_ca_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the DRAM side ODT on
+      CA line strength in ohms. Default value is 40.
+
+  rockchip,phy_lpddr4_ca_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side CA line
+      (including command address line) drive strength. Default value is 40.
+
+  rockchip,phy_lpddr4_ck_cs_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side clock
+      line and CS line drive strength. Default value is 80.
+
+  rockchip,phy_lpddr4_dq_drv:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side DQ line
+      (including DQS/DQ/DM line) drive strength. Default value is 80.
+
+  rockchip,phy_lpddr4_odt:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
+      strength. Default value is 60.
+
+required:
+  - compatible
+  - devfreq-events
+  - clocks
+  - clock-names
+  - operating-points-v2
+  - center-supply
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/rk3399-cru.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    memory-controller {
+      compatible = "rockchip,rk3399-dmc";
+      devfreq-events = <&dfi>;
+      rockchip,pmu = <&pmu>;
+      interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
+      clocks = <&cru SCLK_DDRC>;
+      clock-names = "dmc_clk";
+      operating-points-v2 = <&dmc_opp_table>;
+      center-supply = <&ppvar_centerlogic>;
+      rockchip,ddr3_speed_bin = <21>;
+      rockchip,pd_idle = <0x40>;
+      rockchip,sr_idle = <0x2>;
+      rockchip,sr_mc_gate_idle = <0x3>;
+      rockchip,srpd_lite_idle = <0x4>;
+      rockchip,standby_idle = <0x2000>;
+      rockchip,dram_dll_dis_freq = <300>;
+      rockchip,phy_dll_dis_freq = <125>;
+      rockchip,auto_pd_dis_freq = <666>;
+      rockchip,ddr3_odt_dis_freq = <333>;
+      rockchip,ddr3_drv = <40>;
+      rockchip,ddr3_odt = <120>;
+      rockchip,phy_ddr3_ca_drv = <40>;
+      rockchip,phy_ddr3_dq_drv = <40>;
+      rockchip,phy_ddr3_odt = <240>;
+      rockchip,lpddr3_odt_dis_freq = <333>;
+      rockchip,lpddr3_drv = <34>;
+      rockchip,lpddr3_odt = <240>;
+      rockchip,phy_lpddr3_ca_drv = <40>;
+      rockchip,phy_lpddr3_dq_drv = <40>;
+      rockchip,phy_lpddr3_odt = <240>;
+      rockchip,lpddr4_odt_dis_freq = <333>;
+      rockchip,lpddr4_drv = <60>;
+      rockchip,lpddr4_dq_odt = <40>;
+      rockchip,lpddr4_ca_odt = <40>;
+      rockchip,phy_lpddr4_ca_drv = <40>;
+      rockchip,phy_lpddr4_ck_cs_drv = <80>;
+      rockchip,phy_lpddr4_dq_drv = <80>;
+      rockchip,phy_lpddr4_odt = <60>;
+    };
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:15 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:15 -0800
Subject: [PATCH v2 04/15] dt-bindings: devfreq: rk3399_dmc: Specify idle
 params in nanoseconds
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.4.I01c6a2b2db578136686b42d463af985cfdff2fd9@changeid>

It's inefficient to use the same number of cycles for all OPPs, since
lower frequencies make for longer idle times. Let's specify the idle
time instead, so software can pick the optimal number of cycles on its
own.

NB: these bindings aren't used anywhere yet.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - New patch

 .../bindings/devfreq/rk3399_dmc.yaml          | 50 +++++++++++++++++--
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index 8bb778df92ae..8786b7fa9b28 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -55,42 +55,52 @@ properties:
       being used.
 
   rockchip,pd_idle:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Configure the PD_IDLE value. Defines the power-down idle period in which
       memories are placed into power-down mode if bus is idle for PD_IDLE DFI
       clock cycles.
+      See also rockchip,pd-idle-ns.
 
   rockchip,sr_idle:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Configure the SR_IDLE value. Defines the self-refresh idle period in
       which memories are placed into self-refresh mode if bus is idle for
       SR_IDLE * 1024 DFI clock cycles (DFI clocks freq is half of DRAM clock).
       Default value is "0".
+      See also rockchip,sr-idle-ns.
 
   rockchip,sr_mc_gate_idle:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Defines the memory self-refresh and controller clock gating idle period.
       Memories are placed into self-refresh mode and memory controller clock
       arg gating started if bus is idle for sr_mc_gate_idle*1024 DFI clock
       cycles.
+      See also rockchip,sr-mc-gate-idle-ns.
 
   rockchip,srpd_lite_idle:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Defines the self-refresh power down idle period in which memories are
       placed into self-refresh power down mode if bus is idle for
       srpd_lite_idle * 1024 DFI clock cycles. This parameter is for LPDDR4
       only.
+      See also rockchip,srpd-lite-idle-ns.
 
   rockchip,standby_idle:
+    deprecated: true
     $ref: /schemas/types.yaml#/definitions/uint32
     description:
       Defines the standby idle period in which memories are placed into
       self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
       if bus is idle for standby_idle * DFI clock cycles.
+      See also rockchip,standby-idle-ns.
 
   rockchip,dram_dll_dis_freq:
     deprecated: true
@@ -259,6 +269,36 @@ properties:
       When the DRAM type is LPDDR4, this parameter defines the PHY side ODT
       strength. Default value is 60.
 
+  rockchip,pd-idle-ns:
+    description:
+      Configure the PD_IDLE value in nanoseconds. Defines the power-down idle
+      period in which memories are placed into power-down mode if bus is idle
+      for PD_IDLE nanoseconds.
+
+  rockchip,sr-idle-ns:
+    description:
+      Configure the SR_IDLE value in nanoseconds. Defines the self-refresh idle
+      period in which memories are placed into self-refresh mode if bus is idle
+      for SR_IDLE nanoseconds. Default value is "0".
+
+  rockchip,sr-mc-gate-idle-ns:
+    description:
+      Defines the memory self-refresh and controller clock gating idle period in nanoseconds.
+      Memories are placed into self-refresh mode and memory controller clock
+      arg gating started if bus is idle for sr_mc_gate_idle nanoseconds.
+
+  rockchip,srpd-lite-idle-ns:
+    description:
+      Defines the self-refresh power down idle period in which memories are
+      placed into self-refresh power down mode if bus is idle for
+      srpd_lite_idle nanoseonds. This parameter is for LPDDR4 only.
+
+  rockchip,standby-idle-ns:
+    description:
+      Defines the standby idle period in which memories are placed into
+      self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
+      if bus is idle for standby_idle nanoseconds.
+
 required:
   - compatible
   - devfreq-events
@@ -282,11 +322,11 @@ examples:
       clock-names = "dmc_clk";
       operating-points-v2 = <&dmc_opp_table>;
       center-supply = <&ppvar_centerlogic>;
-      rockchip,pd_idle = <0x40>;
-      rockchip,sr_idle = <0x2>;
-      rockchip,sr_mc_gate_idle = <0x3>;
-      rockchip,srpd_lite_idle = <0x4>;
-      rockchip,standby_idle = <0x2000>;
+      rockchip,pd-idle-ns = <160>;
+      rockchip,sr-idle-ns = <10240>;
+      rockchip,sr-mc-gate-idle-ns = <40960>;
+      rockchip,srpd-lite-idle-ns = <61440>;
+      rockchip,standby-idle-ns = <81920>;
       rockchip,ddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr4_odt_dis_freq = <333000000>;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:14 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:14 -0800
Subject: [PATCH v2 03/15] dt-bindings: devfreq: rk3399_dmc: Fix Hz units
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.3.I9341269171c114d0e04e41d48037fd32816e2d8c@changeid>

The driver and all downstream device trees [1] are using Hz units, but
the document claims MHz. DRAM frequency for these systems can't possibly
exceed 2^32-1 Hz, so the choice of unit doesn't really matter than much.

Rather than add unnecessary risk in getting the units wrong, let's just
go with the unofficial convention and make the docs match reality.

A sub-1MHz frequency is extremely unlikely, so include a minimum in the
schema, to help catch anybody who might have believed this was MHz.

[1] And notably, also those trying to upstream them:
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 .../bindings/devfreq/rk3399_dmc.yaml          | 24 +++++++++----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index fd62a8cd62d5..8bb778df92ae 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -116,11 +116,11 @@ properties:
 
   rockchip,ddr3_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is DDR3, this parameter defines the ODT disable
-      frequency in MHz (Mega Hz). When the DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
+      the ODT on the DRAM side and controller side are both disabled.
 
   rockchip,ddr3_drv:
     deprecated: true
@@ -160,11 +160,11 @@ properties:
 
   rockchip,lpddr3_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is LPDDR3, this parameter defines then ODT disable
-      frequency in MHz (Mega Hz). When DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When DDR frequency is less then ddr3_odt_dis_freq, the
+      ODT on the DRAM side and controller side are both disabled.
 
   rockchip,lpddr3_drv:
     deprecated: true
@@ -204,11 +204,11 @@ properties:
 
   rockchip,lpddr4_odt_dis_freq:
     $ref: /schemas/types.yaml#/definitions/uint32
+    minimum: 1000000  # In case anyone thought this was MHz.
     description:
       When the DRAM type is LPDDR4, this parameter defines the ODT disable
-      frequency in MHz (Mega Hz). When the DDR frequency is less then
-      ddr3_odt_dis_freq, the ODT on the DRAM side and controller side are both
-      disabled.
+      frequency in Hz. When the DDR frequency is less then ddr3_odt_dis_freq,
+      the ODT on the DRAM side and controller side are both disabled.
 
   rockchip,lpddr4_drv:
     deprecated: true
@@ -287,7 +287,7 @@ examples:
       rockchip,sr_mc_gate_idle = <0x3>;
       rockchip,srpd_lite_idle = <0x4>;
       rockchip,standby_idle = <0x2000>;
-      rockchip,ddr3_odt_dis_freq = <333>;
-      rockchip,lpddr3_odt_dis_freq = <333>;
-      rockchip,lpddr4_odt_dis_freq = <333>;
+      rockchip,ddr3_odt_dis_freq = <333000000>;
+      rockchip,lpddr3_odt_dis_freq = <333000000>;
+      rockchip,lpddr4_odt_dis_freq = <333000000>;
     };
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:16 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:16 -0800
Subject: [PATCH v2 05/15] dt-bindings: devfreq: rk3399_dmc: Add more
 disable-freq properties
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.5.I382d4de737198ea52deb118c9bdc4d93d76e009e@changeid>

DDR DVFS tuning has found that several power-saving features don't have
good tradeoffs at higher frequencies -- at higher frequencies, we'll see
glitches or other errors. Provide tuning controls so these can be
disabled at higher OPPs, and left active only at the lower ones.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - hyphens, not underscores
 - *-hz units, and drop the types definition

 .../bindings/devfreq/rk3399_dmc.yaml          | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
index 8786b7fa9b28..afa058c52c0b 100644
--- a/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
+++ b/Documentation/devicetree/bindings/devfreq/rk3399_dmc.yaml
@@ -299,6 +299,38 @@ properties:
       self-refresh mode. The controller, pi, PHY and DRAM clock will be gated
       if bus is idle for standby_idle nanoseconds.
 
+  rockchip,pd-idle-dis-freq-hz:
+    description:
+      Defines the power-down idle disable frequency in Hz. When the DDR
+      frequency is greater than pd-idle-dis-freq, power-down idle is disabled.
+      See also rockchip,pd-idle-ns.
+
+  rockchip,sr-idle-dis-freq-hz:
+    description:
+      Defines the self-refresh idle disable frequency in Hz. When the DDR
+      frequency is greater than sr-idle-dis-freq, self-refresh idle is
+      disabled. See also rockchip,sr-idle-ns.
+
+  rockchip,sr-mc-gate-idle-dis-freq-hz:
+    description:
+      Defines the self-refresh and memory-controller clock gating disable
+      frequency in Hz. When the DDR frequency is greater than
+      sr-mc-gate-idle-dis-freq, the clock will not be gated when idle. See also
+      rockchip,sr-mc-gate-idle-ns.
+
+  rockchip,srpd-lite-idle-dis-freq-hz:
+    description:
+      Defines the self-refresh power down idle disable frequency in Hz. When
+      the DDR frequency is greater than srpd-lite-idle-dis-freq, memory will
+      not be placed into self-refresh power down mode when idle. See also
+      rockchip,srpd-lite-idle-ns.
+
+  rockchip,standby-idle-dis-freq-hz:
+    description:
+      Defines the standby idle disable frequency in Hz. When the DDR frequency
+      is greater than standby-idle-dis-freq, standby idle is disabled. See also
+      rockchip,standby-idle-ns.
+
 required:
   - compatible
   - devfreq-events
@@ -330,4 +362,9 @@ examples:
       rockchip,ddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr3_odt_dis_freq = <333000000>;
       rockchip,lpddr4_odt_dis_freq = <333000000>;
+      rockchip,pd-idle-dis-freq-hz = <1000000000>;
+      rockchip,sr-idle-dis-freq-hz = <1000000000>;
+      rockchip,sr-mc-gate-idle-dis-freq-hz = <1000000000>;
+      rockchip,srpd-lite-idle-dis-freq-hz = <0>;
+      rockchip,standby-idle-dis-freq-hz = <928000000>;
     };
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:17 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:17 -0800
Subject: [PATCH v2 06/15] PM / devfreq: rk3399_dmc: Drop undocumented ondemand
 DT props
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.6.I4bd77eb751d5bfce8346bfed576bcacb28e4550f@changeid>

These properties are:

* undocumented
* directly representing software properties, not hardware properties
* unused (no in-tree users, yet; this IP block has so far only been used
  in downstream kernels)

Let's just stick the values that downstream users have been using
directly in the driver and call it a day.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 drivers/devfreq/rk3399_dmc.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 293857ebfd75..e982862f6ac2 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -430,10 +430,8 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 		goto err_edev;
 	}
 
-	of_property_read_u32(np, "upthreshold",
-			     &data->ondemand_data.upthreshold);
-	of_property_read_u32(np, "downdifferential",
-			     &data->ondemand_data.downdifferential);
+	data->ondemand_data.upthreshold = 25;
+	data->ondemand_data.downdifferential = 15;
 
 	data->rate = clk_get_rate(data->dmc_clk);
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:18 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:18 -0800
Subject: [PATCH v2 07/15] PM / devfreq: rk3399_dmc: Drop excess timing
 properties
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.7.Ia0f7d6168a71ba4a4fd0519972a8dfd4c681fc25@changeid>

All of these properties are initialized by ARM Trusted Firmware, and
have been since the early days of this chip. It's redundant (and
possibly wrong) to do this here now. What's more, there seems to be some
confusion about the units and some of the definitions of this timing
struct: the DT docs say MHz for many of these, but downstream users were
in Hz (and therefore, the ATF interface was Hz). Also, the in-driver
usage for some of these (e.g., for comparing to target frequency) were
in Hz too. So doubly wrong.

We can avoid thinking about who got the right units by dropping the
unnecessary code and properties. They are marked deprecated in the
binding schema.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 drivers/devfreq/rk3399_dmc.c | 144 +++++++----------------------------
 1 file changed, 29 insertions(+), 115 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index e982862f6ac2..8f447217303f 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -23,38 +23,6 @@
 #include <soc/rockchip/rk3399_grf.h>
 #include <soc/rockchip/rockchip_sip.h>
 
-struct dram_timing {
-	unsigned int ddr3_speed_bin;
-	unsigned int pd_idle;
-	unsigned int sr_idle;
-	unsigned int sr_mc_gate_idle;
-	unsigned int srpd_lite_idle;
-	unsigned int standby_idle;
-	unsigned int auto_pd_dis_freq;
-	unsigned int dram_dll_dis_freq;
-	unsigned int phy_dll_dis_freq;
-	unsigned int ddr3_odt_dis_freq;
-	unsigned int ddr3_drv;
-	unsigned int ddr3_odt;
-	unsigned int phy_ddr3_ca_drv;
-	unsigned int phy_ddr3_dq_drv;
-	unsigned int phy_ddr3_odt;
-	unsigned int lpddr3_odt_dis_freq;
-	unsigned int lpddr3_drv;
-	unsigned int lpddr3_odt;
-	unsigned int phy_lpddr3_ca_drv;
-	unsigned int phy_lpddr3_dq_drv;
-	unsigned int phy_lpddr3_odt;
-	unsigned int lpddr4_odt_dis_freq;
-	unsigned int lpddr4_drv;
-	unsigned int lpddr4_dq_odt;
-	unsigned int lpddr4_ca_odt;
-	unsigned int phy_lpddr4_ca_drv;
-	unsigned int phy_lpddr4_ck_cs_drv;
-	unsigned int phy_lpddr4_dq_drv;
-	unsigned int phy_lpddr4_odt;
-};
-
 struct rk3399_dmcfreq {
 	struct device *dev;
 	struct devfreq *devfreq;
@@ -62,13 +30,21 @@ struct rk3399_dmcfreq {
 	struct clk *dmc_clk;
 	struct devfreq_event_dev *edev;
 	struct mutex lock;
-	struct dram_timing timing;
 	struct regulator *vdd_center;
 	struct regmap *regmap_pmu;
 	unsigned long rate, target_rate;
 	unsigned long volt, target_volt;
 	unsigned int odt_dis_freq;
 	int odt_pd_arg0, odt_pd_arg1;
+
+	unsigned int pd_idle;
+	unsigned int sr_idle;
+	unsigned int sr_mc_gate_idle;
+	unsigned int srpd_lite_idle;
+	unsigned int standby_idle;
+	unsigned int ddr3_odt_dis_freq;
+	unsigned int lpddr3_odt_dis_freq;
+	unsigned int lpddr4_odt_dis_freq;
 };
 
 static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -238,69 +214,27 @@ static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,
 			 rk3399_dmcfreq_resume);
 
-static int of_get_ddr_timings(struct dram_timing *timing,
-			      struct device_node *np)
+static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
+				   struct device_node *np)
 {
 	int ret = 0;
 
-	ret = of_property_read_u32(np, "rockchip,ddr3_speed_bin",
-				   &timing->ddr3_speed_bin);
 	ret |= of_property_read_u32(np, "rockchip,pd_idle",
-				    &timing->pd_idle);
+				    &data->pd_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_idle",
-				    &timing->sr_idle);
+				    &data->sr_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle",
-				    &timing->sr_mc_gate_idle);
+				    &data->sr_mc_gate_idle);
 	ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle",
-				    &timing->srpd_lite_idle);
+				    &data->srpd_lite_idle);
 	ret |= of_property_read_u32(np, "rockchip,standby_idle",
-				    &timing->standby_idle);
-	ret |= of_property_read_u32(np, "rockchip,auto_pd_dis_freq",
-				    &timing->auto_pd_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,dram_dll_dis_freq",
-				    &timing->dram_dll_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,phy_dll_dis_freq",
-				    &timing->phy_dll_dis_freq);
+				    &data->standby_idle);
 	ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",
-				    &timing->ddr3_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,ddr3_drv",
-				    &timing->ddr3_drv);
-	ret |= of_property_read_u32(np, "rockchip,ddr3_odt",
-				    &timing->ddr3_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_ca_drv",
-				    &timing->phy_ddr3_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_dq_drv",
-				    &timing->phy_ddr3_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_ddr3_odt",
-				    &timing->phy_ddr3_odt);
+				    &data->ddr3_odt_dis_freq);
 	ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",
-				    &timing->lpddr3_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,lpddr3_drv",
-				    &timing->lpddr3_drv);
-	ret |= of_property_read_u32(np, "rockchip,lpddr3_odt",
-				    &timing->lpddr3_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_ca_drv",
-				    &timing->phy_lpddr3_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_dq_drv",
-				    &timing->phy_lpddr3_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr3_odt",
-				    &timing->phy_lpddr3_odt);
+				    &data->lpddr3_odt_dis_freq);
 	ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",
-				    &timing->lpddr4_odt_dis_freq);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_drv",
-				    &timing->lpddr4_drv);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_dq_odt",
-				    &timing->lpddr4_dq_odt);
-	ret |= of_property_read_u32(np, "rockchip,lpddr4_ca_odt",
-				    &timing->lpddr4_ca_odt);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ca_drv",
-				    &timing->phy_lpddr4_ca_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_ck_cs_drv",
-				    &timing->phy_lpddr4_ck_cs_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_dq_drv",
-				    &timing->phy_lpddr4_dq_drv);
-	ret |= of_property_read_u32(np, "rockchip,phy_lpddr4_odt",
-				    &timing->phy_lpddr4_odt);
+				    &data->lpddr4_odt_dis_freq);
 
 	return ret;
 }
@@ -311,8 +245,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct device_node *np = pdev->dev.of_node, *node;
 	struct rk3399_dmcfreq *data;
-	int ret, index, size;
-	uint32_t *timing;
+	int ret;
 	struct dev_pm_opp *opp;
 	u32 ddr_type;
 	u32 val;
@@ -343,26 +276,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	/*
-	 * Get dram timing and pass it to arm trust firmware,
-	 * the dram driver in arm trust firmware will get these
-	 * timing and to do dram initial.
-	 */
-	if (!of_get_ddr_timings(&data->timing, np)) {
-		timing = &data->timing.ddr3_speed_bin;
-		size = sizeof(struct dram_timing) / 4;
-		for (index = 0; index < size; index++) {
-			arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, *timing++, index,
-				      ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM,
-				      0, 0, 0, 0, &res);
-			if (res.a0) {
-				dev_err(dev, "Failed to set dram param: %ld\n",
-					res.a0);
-				ret = -EINVAL;
-				goto err_edev;
-			}
-		}
-	}
+	rk3399_dmcfreq_of_props(data, np);
 
 	node = of_parse_phandle(np, "rockchip,pmu", 0);
 	if (!node)
@@ -381,13 +295,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 
 	switch (ddr_type) {
 	case RK3399_PMUGRF_DDRTYPE_DDR3:
-		data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
+		data->odt_dis_freq = data->ddr3_odt_dis_freq;
 		break;
 	case RK3399_PMUGRF_DDRTYPE_LPDDR3:
-		data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
+		data->odt_dis_freq = data->lpddr3_odt_dis_freq;
 		break;
 	case RK3399_PMUGRF_DDRTYPE_LPDDR4:
-		data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
+		data->odt_dis_freq = data->lpddr4_odt_dis_freq;
 		break;
 	default:
 		ret = -EINVAL;
@@ -414,11 +328,11 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	 * arg2:
 	 *     bit[0]     : odt enable
 	 */
-	data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
-			    ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
-			    ((data->timing.standby_idle & 0xffff) << 16);
-	data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
-			    ((data->timing.srpd_lite_idle & 0xfff) << 16);
+	data->odt_pd_arg0 = (data->sr_idle & 0xff) |
+			    ((data->sr_mc_gate_idle & 0xff) << 8) |
+			    ((data->standby_idle & 0xffff) << 16);
+	data->odt_pd_arg1 = (data->pd_idle & 0xfff) |
+			    ((data->srpd_lite_idle & 0xfff) << 16);
 
 	/*
 	 * We add a devfreq driver to our parent since it has a device tree node
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:20 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:20 -0800
Subject: [PATCH v2 09/15] PM / devfreq: rk3399_dmc: Support new disable-freq
 properties
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.9.I08d654522b8a1ae92ecb8d2e2a74511f778f61e5@changeid>

Implement the newly-defined properties to allow disabling certain
power-saving-at-idle features at higher frequencies.

This is a rewritten version of work by Lin Huang <hl at rock-chips.com>.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 drivers/devfreq/rk3399_dmc.c | 51 +++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index c4efbc15cbb1..fc740c1f6747 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -55,6 +55,12 @@ struct rk3399_dmcfreq {
 	unsigned int ddr3_odt_dis_freq;
 	unsigned int lpddr3_odt_dis_freq;
 	unsigned int lpddr4_odt_dis_freq;
+
+	unsigned int pd_idle_dis_freq;
+	unsigned int sr_idle_dis_freq;
+	unsigned int sr_mc_gate_idle_dis_freq;
+	unsigned int srpd_lite_idle_dis_freq;
+	unsigned int standby_idle_dis_freq;
 };
 
 static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -81,8 +87,25 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	mutex_lock(&dmcfreq->lock);
 
 	if (dmcfreq->regmap_pmu) {
+		unsigned int odt_pd_arg0 = dmcfreq->odt_pd_arg0;
+		unsigned int odt_pd_arg1 = dmcfreq->odt_pd_arg1;
 		unsigned int odt_pd_arg2 = 0;
 
+		if (target_rate >= dmcfreq->sr_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE;
+
+		if (target_rate >= dmcfreq->sr_mc_gate_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE;
+
+		if (target_rate >= dmcfreq->standby_idle_dis_freq)
+			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_STANDBY_IDLE;
+
+		if (target_rate >= dmcfreq->pd_idle_dis_freq)
+			odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_PD_IDLE;
+
+		if (target_rate >= dmcfreq->srpd_lite_idle_dis_freq)
+			odt_pd_arg1 &= ~RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE;
+
 		if (target_rate >= dmcfreq->odt_dis_freq)
 			odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;
 
@@ -91,10 +114,9 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 		 * (power-down) timings and to enable or disable the
 		 * ODT (on-die termination) resistors.
 		 */
-		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
-			      dmcfreq->odt_pd_arg1,
-			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
-			      odt_pd_arg2, 0, 0, 0, &res);
+		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, odt_pd_arg0, odt_pd_arg1,
+			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD, odt_pd_arg2,
+			      0, 0, 0, &res);
 	}
 
 	/*
@@ -230,6 +252,16 @@ static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
 {
 	int ret = 0;
 
+	/*
+	 * These are all optional, and serve as minimum bounds. Give them large
+	 * (i.e., never "disabled") values if the DT doesn't specify one.
+	 */
+	data->pd_idle_dis_freq =
+		data->sr_idle_dis_freq =
+		data->sr_mc_gate_idle_dis_freq =
+		data->srpd_lite_idle_dis_freq =
+		data->standby_idle_dis_freq = UINT_MAX;
+
 	ret |= of_property_read_u32(np, "rockchip,pd_idle",
 				    &data->pd_idle);
 	ret |= of_property_read_u32(np, "rockchip,sr_idle",
@@ -247,6 +279,17 @@ static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
 	ret |= of_property_read_u32(np, "rockchip,lpddr4_odt_dis_freq",
 				    &data->lpddr4_odt_dis_freq);
 
+	ret |= of_property_read_u32(np, "rockchip,pd-idle-dis-freq-hz",
+				    &data->pd_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,sr-idle-dis-freq-hz",
+				    &data->sr_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-dis-freq-hz",
+				    &data->sr_mc_gate_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-dis-freq-hz",
+				    &data->srpd_lite_idle_dis_freq);
+	ret |= of_property_read_u32(np, "rockchip,standby-idle-dis-freq-hz",
+				    &data->standby_idle_dis_freq);
+
 	return ret;
 }
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:22 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:22 -0800
Subject: [PATCH v2 11/15] arm64: dts: rk3399: Add dfi and dmc nodes
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.11.Ie97993621975c5463d7928a8646f3737c9f2921d@changeid>

From: Lin Huang <hl at rock-chips.com>

These are required to support DDR DVFS on RK3399 platforms.

Signed-off-by: Lin Huang <hl at rock-chips.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Ga?l PORTAY <gael.portay at collabora.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Signed-off-by: Brian Norris <briannorris at chromium.org>
Change since Daniel's posting: reordered by unit address, per existing
style

---

Changes in v2:
 - rename dmc to memory-controller

Changes in v1:
This is based on a v5 posting from various authors:
https://lore.kernel.org/lkml/20210308233858.24741-3-daniel.lezcano at linaro.org/
Much of that series was already merged, so I start over with the
numbering.

 arch/arm64/boot/dts/rockchip/rk3399.dtsi | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index d3cdf6f42a30..4096ef6f7b72 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1295,6 +1295,25 @@ pwm3: pwm at ff420030 {
 		status = "disabled";
 	};
 
+	dfi: dfi at ff630000 {
+		reg = <0x00 0xff630000 0x00 0x4000>;
+		compatible = "rockchip,rk3399-dfi";
+		rockchip,pmu = <&pmugrf>;
+		interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
+		clocks = <&cru PCLK_DDR_MON>;
+		clock-names = "pclk_ddr_mon";
+		status = "disabled";
+	};
+
+	dmc: memory-controller {
+		compatible = "rockchip,rk3399-dmc";
+		rockchip,pmu = <&pmugrf>;
+		devfreq-events = <&dfi>;
+		clocks = <&cru SCLK_DDRC>;
+		clock-names = "dmc_clk";
+		status = "disabled";
+	};
+
 	vpu: video-codec at ff650000 {
 		compatible = "rockchip,rk3399-vpu";
 		reg = <0x0 0xff650000 0x0 0x800>;
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:23 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:23 -0800
Subject: [PATCH v2 12/15] arm64: dts: rockchip: Enable dmc and dfi nodes on gru
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.12.I3a5c7f21ecd8221b42c2dbcd618386bce7b3e9a6@changeid>

From: Lin Huang <hl at rock-chips.com>

Enable the DMC (Dynamic Memory Controller) and the DFI (DDR PHY
Interface) nodes on gru boards so we can support DDR DVFS.

Signed-off-by: Lin Huang <hl at rock-chips.com>
Signed-off-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Signed-off-by: Ga?l PORTAY <gael.portay at collabora.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Signed-off-by: Brian Norris <briannorris at chromium.org>
Updates since the old series:

 - reordered alphabetically by phandle name, per style
 - drop a ton of deprecated/unused properties
 - add required center-supply for scarlet
 - add new *_idle_dis_freq properties
 - drop the lowest (200 MHz) OPP; this was never stabilized for
   production
 - bump the voltage (0.9V -> 0.925V) for the highest OPP on Chromebook
   models; later (tablet) models were more stable, with a fixed DDR
   regulator
 - bump odt_dis_freq to 666 MHz; early versions used 333 MHz, but
   stabilization efforts landed on 666 MHz for production

---

Changes in v2:
 - Adapt to new properties

Changes in v1:
This was part of a previous series, at:
https://lore.kernel.org/r/20210308233858.24741-3-daniel.lezcano at linaro.org
I've picked up a bunch of changes and fixes, so I've restarted the patch
series numbering.

 .../dts/rockchip/rk3399-gru-chromebook.dtsi   |  7 +++++
 .../boot/dts/rockchip/rk3399-gru-scarlet.dtsi | 12 ++++++++
 arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi  | 28 +++++++++++++++++++
 .../boot/dts/rockchip/rk3399-op1-opp.dtsi     | 25 +++++++++++++++++
 4 files changed, 72 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
index 9b2c679f5eca..cc8950046d94 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-chromebook.dtsi
@@ -234,6 +234,13 @@ &cdn_dp {
 	extcon = <&usbc_extcon0>, <&usbc_extcon1>;
 };
 
+&dmc {
+	center-supply = <&ppvar_centerlogic>;
+	rockchip,pd-idle-dis-freq-hz = <800000000>;
+	rockchip,sr-idle-dis-freq-hz = <800000000>;
+	rockchip,sr-mc-gate-idle-dis-freq-hz = <800000000>;
+};
+
 &edp {
 	status = "okay";
 
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
index a9817b3d7edc..913d845eb51a 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru-scarlet.dtsi
@@ -391,6 +391,18 @@ &cru {
 		<400000000>;
 };
 
+/* The center supply is fixed to .9V on scarlet */
+&dmc {
+	center-supply = <&pp900_s0>;
+};
+
+/* We don't need .925 V for 928 MHz on scarlet */
+&dmc_opp_table {
+	opp03 {
+		opp-microvolt = <900000>;
+	};
+};
+
 &gpio0 {
 	gpio-line-names = /* GPIO0 A 0-7 */
 			  "CLK_32K_AP",
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
index 162f08bca0d4..23bfba86daab 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -373,6 +373,34 @@ &cru {
 		<200000000>;
 };
 
+&dfi {
+	status = "okay";
+};
+
+&dmc {
+	status = "okay";
+
+	rockchip,pd-idle-ns = <160>;
+	rockchip,sr-idle-ns = <10240>;
+	rockchip,sr-mc-gate-idle-ns = <40960>;
+	rockchip,srpd-lite-idle-ns = <61440>;
+	rockchip,standby-idle-ns = <81920>;
+
+	rockchip,ddr3_odt_dis_freq = <666000000>;
+	rockchip,lpddr3_odt_dis_freq = <666000000>;
+	rockchip,lpddr4_odt_dis_freq = <666000000>;
+
+	rockchip,sr-mc-gate-idle-dis-freq-hz = <1000000000>;
+	rockchip,srpd-lite-idle-dis-freq-hz = <0>;
+	rockchip,standby-idle-dis-freq-hz = <928000000>;
+};
+
+&dmc_opp_table {
+	opp03 {
+		opp-suspend;
+	};
+};
+
 &emmc_phy {
 	status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
index 2180e0f75003..6e29e74f6fc6 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-op1-opp.dtsi
@@ -110,6 +110,27 @@ opp05 {
 			opp-microvolt = <1075000>;
 		};
 	};
+
+	dmc_opp_table: dmc_opp_table {
+		compatible = "operating-points-v2";
+
+		opp00 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-microvolt = <900000>;
+		};
+		opp01 {
+			opp-hz = /bits/ 64 <666000000>;
+			opp-microvolt = <900000>;
+		};
+		opp02 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-microvolt = <900000>;
+		};
+		opp03 {
+			opp-hz = /bits/ 64 <928000000>;
+			opp-microvolt = <925000>;
+		};
+	};
 };
 
 &cpu_l0 {
@@ -136,6 +157,10 @@ &cpu_b1 {
 	operating-points-v2 = <&cluster1_opp>;
 };
 
+&dmc {
+	operating-points-v2 = <&dmc_opp_table>;
+};
+
 &gpu {
 	operating-points-v2 = <&gpu_opp_table>;
 };
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:24 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:24 -0800
Subject: [PATCH v2 13/15] PM / devfreq: rk3399_dmc: Disable edev on remove()
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.13.I1476960b2586441beaef21dca4feb3ecc067f768@changeid>

Otherwise we hit an unablanced enable-count when unbinding the DFI
device:

[ 1279.659119] ------------[ cut here ]------------
[ 1279.659179] WARNING: CPU: 2 PID: 5638 at drivers/devfreq/devfreq-event.c:360 devfreq_event_remove_edev+0x84/0x8c
...
[ 1279.659352] Hardware name: Google Kevin (DT)
[ 1279.659363] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO BTYPE=--)
[ 1279.659371] pc : devfreq_event_remove_edev+0x84/0x8c
[ 1279.659380] lr : devm_devfreq_event_release+0x1c/0x28
...
[ 1279.659571] Call trace:
[ 1279.659582]  devfreq_event_remove_edev+0x84/0x8c
[ 1279.659590]  devm_devfreq_event_release+0x1c/0x28
[ 1279.659602]  release_nodes+0x1cc/0x244
[ 1279.659611]  devres_release_all+0x44/0x60
[ 1279.659621]  device_release_driver_internal+0x11c/0x1ac
[ 1279.659629]  device_driver_detach+0x20/0x2c
[ 1279.659641]  unbind_store+0x7c/0xb0
[ 1279.659650]  drv_attr_store+0x2c/0x40
[ 1279.659663]  sysfs_kf_write+0x44/0x58
[ 1279.659672]  kernfs_fop_write_iter+0xf4/0x190
[ 1279.659684]  vfs_write+0x2b0/0x2e4
[ 1279.659693]  ksys_write+0x80/0xec
[ 1279.659701]  __arm64_sys_write+0x24/0x30
[ 1279.659714]  el0_svc_common+0xf0/0x1d8
[ 1279.659724]  do_el0_svc_compat+0x28/0x3c
[ 1279.659738]  el0_svc_compat+0x10/0x1c
[ 1279.659746]  el0_sync_compat_handler+0xa8/0xcc
[ 1279.659758]  el0_sync_compat+0x188/0x1c0
[ 1279.659768] ---[ end trace cec200e5094155b4 ]---

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - New patch

 drivers/devfreq/rk3399_dmc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index f778564cab49..fca9fcbd4249 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -452,6 +452,8 @@ static int rk3399_dmcfreq_remove(struct platform_device *pdev)
 {
 	struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
 
+	devfreq_event_disable_edev(dmcfreq->edev);
+
 	/*
 	 * Before remove the opp table we need to unregister the opp notifier.
 	 */
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:21 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:21 -0800
Subject: [PATCH v2 10/15] PM / devfreq: rk3399_dmc: Support new *-ns properties
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.10.I4e01e243ea11e9f95295b40b44a9eaa3a883a0dd@changeid>

We want to keep the idle time fixed, so compute based on the current DDR
frequency.

The old properties were deprecated and never used, so we can safely drop
them from the driver.

This is a rewritten version of work by Lin Huang <hl at rock-chips.com>.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - New patch

 drivers/devfreq/rk3399_dmc.c | 85 +++++++++++++++++++++---------------
 1 file changed, 50 insertions(+), 35 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index fc740c1f6747..f778564cab49 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -24,6 +24,8 @@
 #include <soc/rockchip/rk3399_grf.h>
 #include <soc/rockchip/rockchip_sip.h>
 
+#define NS_TO_CYCLE(NS, MHz)				(((NS) * (MHz)) / NSEC_PER_USEC)
+
 #define RK3399_SET_ODT_PD_0_SR_IDLE			GENMASK(7, 0)
 #define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE		GENMASK(15, 8)
 #define RK3399_SET_ODT_PD_0_STANDBY_IDLE		GENMASK(31, 16)
@@ -45,13 +47,12 @@ struct rk3399_dmcfreq {
 	unsigned long rate, target_rate;
 	unsigned long volt, target_volt;
 	unsigned int odt_dis_freq;
-	int odt_pd_arg0, odt_pd_arg1;
 
-	unsigned int pd_idle;
-	unsigned int sr_idle;
-	unsigned int sr_mc_gate_idle;
-	unsigned int srpd_lite_idle;
-	unsigned int standby_idle;
+	unsigned int pd_idle_ns;
+	unsigned int sr_idle_ns;
+	unsigned int sr_mc_gate_idle_ns;
+	unsigned int srpd_lite_idle_ns;
+	unsigned int standby_idle_ns;
 	unsigned int ddr3_odt_dis_freq;
 	unsigned int lpddr3_odt_dis_freq;
 	unsigned int lpddr4_odt_dis_freq;
@@ -70,9 +71,14 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	struct dev_pm_opp *opp;
 	unsigned long old_clk_rate = dmcfreq->rate;
 	unsigned long target_volt, target_rate;
+	unsigned int ddrcon_mhz;
 	struct arm_smccc_res res;
 	int err;
 
+	u32 odt_pd_arg0 = 0;
+	u32 odt_pd_arg1 = 0;
+	u32 odt_pd_arg2 = 0;
+
 	opp = devfreq_recommended_opp(dev, freq, flags);
 	if (IS_ERR(opp))
 		return PTR_ERR(opp);
@@ -86,11 +92,35 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 
 	mutex_lock(&dmcfreq->lock);
 
-	if (dmcfreq->regmap_pmu) {
-		unsigned int odt_pd_arg0 = dmcfreq->odt_pd_arg0;
-		unsigned int odt_pd_arg1 = dmcfreq->odt_pd_arg1;
-		unsigned int odt_pd_arg2 = 0;
+	/*
+	 * Some idle parameters may be based on the DDR controller clock, which
+	 * is half of the DDR frequency.
+	 * pd_idle and standby_idle are based on the controller clock cycle.
+	 * sr_idle_cycle, sr_mc_gate_idle_cycle, and srpd_lite_idle_cycle
+	 * are based on the 1024 controller clock cycle
+	 */
+	ddrcon_mhz = target_rate / USEC_PER_SEC / 2;
+
+	u32p_replace_bits(&odt_pd_arg1,
+			  NS_TO_CYCLE(dmcfreq->pd_idle_ns, ddrcon_mhz),
+			  RK3399_SET_ODT_PD_1_PD_IDLE);
+	u32p_replace_bits(&odt_pd_arg0,
+			  NS_TO_CYCLE(dmcfreq->standby_idle_ns, ddrcon_mhz),
+			  RK3399_SET_ODT_PD_0_STANDBY_IDLE);
+	u32p_replace_bits(&odt_pd_arg0,
+			  DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_idle_ns,
+						   ddrcon_mhz), 1024),
+			  RK3399_SET_ODT_PD_0_SR_IDLE);
+	u32p_replace_bits(&odt_pd_arg0,
+			  DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->sr_mc_gate_idle_ns,
+						   ddrcon_mhz), 1024),
+			  RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE);
+	u32p_replace_bits(&odt_pd_arg1,
+			  DIV_ROUND_UP(NS_TO_CYCLE(dmcfreq->srpd_lite_idle_ns,
+						   ddrcon_mhz), 1024),
+			  RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE);
 
+	if (dmcfreq->regmap_pmu) {
 		if (target_rate >= dmcfreq->sr_idle_dis_freq)
 			odt_pd_arg0 &= ~RK3399_SET_ODT_PD_0_SR_IDLE;
 
@@ -262,16 +292,16 @@ static int rk3399_dmcfreq_of_props(struct rk3399_dmcfreq *data,
 		data->srpd_lite_idle_dis_freq =
 		data->standby_idle_dis_freq = UINT_MAX;
 
-	ret |= of_property_read_u32(np, "rockchip,pd_idle",
-				    &data->pd_idle);
-	ret |= of_property_read_u32(np, "rockchip,sr_idle",
-				    &data->sr_idle);
-	ret |= of_property_read_u32(np, "rockchip,sr_mc_gate_idle",
-				    &data->sr_mc_gate_idle);
-	ret |= of_property_read_u32(np, "rockchip,srpd_lite_idle",
-				    &data->srpd_lite_idle);
-	ret |= of_property_read_u32(np, "rockchip,standby_idle",
-				    &data->standby_idle);
+	ret |= of_property_read_u32(np, "rockchip,pd-idle-ns",
+				    &data->pd_idle_ns);
+	ret |= of_property_read_u32(np, "rockchip,sr-idle-ns",
+				    &data->sr_idle_ns);
+	ret |= of_property_read_u32(np, "rockchip,sr-mc-gate-idle-ns",
+				    &data->sr_mc_gate_idle_ns);
+	ret |= of_property_read_u32(np, "rockchip,srpd-lite-idle-ns",
+				    &data->srpd_lite_idle_ns);
+	ret |= of_property_read_u32(np, "rockchip,standby-idle-ns",
+				    &data->standby_idle_ns);
 	ret |= of_property_read_u32(np, "rockchip,ddr3_odt_dis_freq",
 				    &data->ddr3_odt_dis_freq);
 	ret |= of_property_read_u32(np, "rockchip,lpddr3_odt_dis_freq",
@@ -367,21 +397,6 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 		      ROCKCHIP_SIP_CONFIG_DRAM_INIT,
 		      0, 0, 0, 0, &res);
 
-	/*
-	 * In TF-A there is a platform SIP call to set the PD (power-down)
-	 * timings and to enable or disable the ODT (on-die termination).
-	 */
-	data->odt_pd_arg0 =
-		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_IDLE, data->sr_idle) |
-		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE,
-			   data->sr_mc_gate_idle) |
-		FIELD_PREP(RK3399_SET_ODT_PD_0_STANDBY_IDLE,
-			   data->standby_idle);
-	data->odt_pd_arg1 =
-		FIELD_PREP(RK3399_SET_ODT_PD_1_PD_IDLE, data->pd_idle) |
-		FIELD_PREP(RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE,
-			   data->srpd_lite_idle);
-
 	/*
 	 * We add a devfreq driver to our parent since it has a device tree node
 	 * with operating points.
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:25 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:25 -0800
Subject: [PATCH v2 14/15] PM / devfreq: rk3399_dmc: Use
 devm_pm_opp_of_add_table()
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.14.I3df48ceacbf299549501a44433039d46e0a275ea@changeid>

This simplifies error-cleanup and remove().

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - New patch

 drivers/devfreq/rk3399_dmc.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index fca9fcbd4249..9615658d04ae 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -401,7 +401,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	 * We add a devfreq driver to our parent since it has a device tree node
 	 * with operating points.
 	 */
-	if (dev_pm_opp_of_add_table(dev)) {
+	if (devm_pm_opp_of_add_table(dev)) {
 		dev_err(dev, "Invalid operating-points in device tree.\n");
 		ret = -EINVAL;
 		goto err_edev;
@@ -415,7 +415,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	opp = devfreq_recommended_opp(dev, &data->rate, 0);
 	if (IS_ERR(opp)) {
 		ret = PTR_ERR(opp);
-		goto err_free_opp;
+		goto err_edev;
 	}
 
 	data->rate = dev_pm_opp_get_freq(opp);
@@ -430,7 +430,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 					   &data->ondemand_data);
 	if (IS_ERR(data->devfreq)) {
 		ret = PTR_ERR(data->devfreq);
-		goto err_free_opp;
+		goto err_edev;
 	}
 
 	devm_devfreq_register_opp_notifier(dev, data->devfreq);
@@ -440,8 +440,6 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 
 	return 0;
 
-err_free_opp:
-	dev_pm_opp_of_remove_table(&pdev->dev);
 err_edev:
 	devfreq_event_disable_edev(data->edev);
 
@@ -454,12 +452,6 @@ static int rk3399_dmcfreq_remove(struct platform_device *pdev)
 
 	devfreq_event_disable_edev(dmcfreq->edev);
 
-	/*
-	 * Before remove the opp table we need to unregister the opp notifier.
-	 */
-	devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
-	dev_pm_opp_of_remove_table(dmcfreq->dev);
-
 	return 0;
 }
 
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:19 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:19 -0800
Subject: [PATCH v2 08/15] PM / devfreq: rk3399_dmc: Use bitfield macro
 definitions for ODT_PD
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.8.I0f36da588afd01d0dc9ce5866240efa34bd91e21@changeid>

We're going to add new usages, and it's cleaner to work with macros
instead of comments and magic numbers.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

(no changes since v1)

 drivers/devfreq/rk3399_dmc.c | 43 ++++++++++++++++++++----------------
 1 file changed, 24 insertions(+), 19 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 8f447217303f..c4efbc15cbb1 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -5,6 +5,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/devfreq.h>
@@ -23,6 +24,15 @@
 #include <soc/rockchip/rk3399_grf.h>
 #include <soc/rockchip/rockchip_sip.h>
 
+#define RK3399_SET_ODT_PD_0_SR_IDLE			GENMASK(7, 0)
+#define RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE		GENMASK(15, 8)
+#define RK3399_SET_ODT_PD_0_STANDBY_IDLE		GENMASK(31, 16)
+
+#define RK3399_SET_ODT_PD_1_PD_IDLE			GENMASK(11, 0)
+#define RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE		GENMASK(27, 16)
+
+#define RK3399_SET_ODT_PD_2_ODT_ENABLE			BIT(0)
+
 struct rk3399_dmcfreq {
 	struct device *dev;
 	struct devfreq *devfreq;
@@ -55,7 +65,6 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	unsigned long old_clk_rate = dmcfreq->rate;
 	unsigned long target_volt, target_rate;
 	struct arm_smccc_res res;
-	bool odt_enable = false;
 	int err;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
@@ -72,8 +81,10 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 	mutex_lock(&dmcfreq->lock);
 
 	if (dmcfreq->regmap_pmu) {
+		unsigned int odt_pd_arg2 = 0;
+
 		if (target_rate >= dmcfreq->odt_dis_freq)
-			odt_enable = true;
+			odt_pd_arg2 |= RK3399_SET_ODT_PD_2_ODT_ENABLE;
 
 		/*
 		 * This makes a SMC call to the TF-A to set the DDR PD
@@ -83,7 +94,7 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
 		arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
 			      dmcfreq->odt_pd_arg1,
 			      ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
-			      odt_enable, 0, 0, 0, &res);
+			      odt_pd_arg2, 0, 0, 0, &res);
 	}
 
 	/*
@@ -316,23 +327,17 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	/*
 	 * In TF-A there is a platform SIP call to set the PD (power-down)
 	 * timings and to enable or disable the ODT (on-die termination).
-	 * This call needs three arguments as follows:
-	 *
-	 * arg0:
-	 *     bit[0-7]   : sr_idle
-	 *     bit[8-15]  : sr_mc_gate_idle
-	 *     bit[16-31] : standby idle
-	 * arg1:
-	 *     bit[0-11]  : pd_idle
-	 *     bit[16-27] : srpd_lite_idle
-	 * arg2:
-	 *     bit[0]     : odt enable
 	 */
-	data->odt_pd_arg0 = (data->sr_idle & 0xff) |
-			    ((data->sr_mc_gate_idle & 0xff) << 8) |
-			    ((data->standby_idle & 0xffff) << 16);
-	data->odt_pd_arg1 = (data->pd_idle & 0xfff) |
-			    ((data->srpd_lite_idle & 0xfff) << 16);
+	data->odt_pd_arg0 =
+		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_IDLE, data->sr_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_0_SR_MC_GATE_IDLE,
+			   data->sr_mc_gate_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_0_STANDBY_IDLE,
+			   data->standby_idle);
+	data->odt_pd_arg1 =
+		FIELD_PREP(RK3399_SET_ODT_PD_1_PD_IDLE, data->pd_idle) |
+		FIELD_PREP(RK3399_SET_ODT_PD_1_SRPD_LITE_IDLE,
+			   data->srpd_lite_idle);
 
 	/*
 	 * We add a devfreq driver to our parent since it has a device tree node
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:07:26 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:07:26 -0800
Subject: [PATCH v2 15/15] PM / devfreq: rk3399_dmc: Avoid static (reused)
 profile
In-Reply-To: <20220127230727.3369358-1-briannorris@chromium.org>
References: <20220127230727.3369358-1-briannorris@chromium.org>
Message-ID: <20220127150615.v2.15.I8d71e9555aca1fa7e532d22dd1ef27976f21799d@changeid>

This static struct can get reused if the device gets removed/reprobed,
and that causes use-after-free in its ->freq_table.

Let's just move the struct to our dynamic allocation.

Signed-off-by: Brian Norris <briannorris at chromium.org>
---

Changes in v2:
 - New patch

 drivers/devfreq/rk3399_dmc.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index 9615658d04ae..e494d1497d60 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -38,6 +38,7 @@
 struct rk3399_dmcfreq {
 	struct device *dev;
 	struct devfreq *devfreq;
+	struct devfreq_dev_profile profile;
 	struct devfreq_simple_ondemand_data ondemand_data;
 	struct clk *dmc_clk;
 	struct devfreq_event_dev *edev;
@@ -228,13 +229,6 @@ static int rk3399_dmcfreq_get_cur_freq(struct device *dev, unsigned long *freq)
 	return 0;
 }
 
-static struct devfreq_dev_profile rk3399_devfreq_dmc_profile = {
-	.polling_ms	= 200,
-	.target		= rk3399_dmcfreq_target,
-	.get_dev_status	= rk3399_dmcfreq_get_dev_status,
-	.get_cur_freq	= rk3399_dmcfreq_get_cur_freq,
-};
-
 static __maybe_unused int rk3399_dmcfreq_suspend(struct device *dev)
 {
 	struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(dev);
@@ -422,10 +416,16 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
 	data->volt = dev_pm_opp_get_voltage(opp);
 	dev_pm_opp_put(opp);
 
-	rk3399_devfreq_dmc_profile.initial_freq = data->rate;
+	data->profile = (struct devfreq_dev_profile) {
+		.polling_ms	= 200,
+		.target		= rk3399_dmcfreq_target,
+		.get_dev_status	= rk3399_dmcfreq_get_dev_status,
+		.get_cur_freq	= rk3399_dmcfreq_get_cur_freq,
+		.initial_freq	= data->rate,
+	};
 
 	data->devfreq = devm_devfreq_add_device(dev,
-					   &rk3399_devfreq_dmc_profile,
+					   &data->profile,
 					   DEVFREQ_GOV_SIMPLE_ONDEMAND,
 					   &data->ondemand_data);
 	if (IS_ERR(data->devfreq)) {
-- 
2.35.0.rc0.227.g00780c9af4-goog



From briannorris at chromium.org  Thu Jan 27 15:17:25 2022
From: briannorris at chromium.org (Brian Norris)
Date: Thu, 27 Jan 2022 15:17:25 -0800
Subject: [PATCH v2 02/15] dt-bindings: devfreq: rk3399_dmc: Deprecate
 unused/redundant properties
In-Reply-To: <20220127150615.v2.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>
References: <20220127230727.3369358-1-briannorris@chromium.org>
 <20220127150615.v2.2.I5ba582cd678d34c03d647e5500db8e33b7524d66@changeid>
Message-ID: <CA+ASDXOnO1EgStrynPe1uSB4T8=qNUPj+wY2y3vGs0fnEHdE0Q@mail.gmail.com>

On Thu, Jan 27, 2022 at 3:08 PM Brian Norris <briannorris at chromium.org> wrote:
>
> These DRAM configuration properties are all handled in ARM Trusted
> Firmware (and have been since the early days of this SoC), and there are
> no in-tree users of the DMC binding yet. It's better to just defer to
> firmware instead of maintaining this large list of properties.
>
> There's also some confusion about units: many of these are specified in
> MHz, but the downstream users and driver code are treating them as Hz, I
> believe. Rather than straighten all that out, I just drop them.
>
> Signed-off-by: Brian Norris <briannorris at chromium.org>
> ---
>
> (no changes since v1)

Apologies, I didn't include Rob's Reviewed-by tag on patch 2 and 3. If
this goes for version 3, I'll include them.

Brian


From robin.murphy at arm.com  Thu Jan 27 15:31:14 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Thu, 27 Jan 2022 23:31:14 +0000
Subject: [PATCH] arm64: errata: Remove AES hwcap for COMPAT tasks on A57
 and A72
In-Reply-To: <CAK8P3a2Vj0XCJSdKrgHmEkXjuWT2cxPnT=F8+ea2G7moiHoDyw@mail.gmail.com>
References: <20220127122914.1585008-1-james.morse@arm.com>
 <CAMj1kXG+6J10xy8C2NHEFe3_4H8YVjxbOVg1azaU26nChPT4WA@mail.gmail.com>
 <CAK8P3a0oaP8LzxX6TSYhmSV+s+5rjHeCRzQ-pXkMQvpGvrp_0Q@mail.gmail.com>
 <3e11270f-7014-4729-13cf-d9331d4bdec7@arm.com>
 <CAK8P3a2Vj0XCJSdKrgHmEkXjuWT2cxPnT=F8+ea2G7moiHoDyw@mail.gmail.com>
Message-ID: <81bb9590-4741-dc32-e590-628de4078fc4@arm.com>

On 2022-01-27 19:55, Arnd Bergmann wrote:
> On Thu, Jan 27, 2022 at 7:43 PM Robin Murphy <robin.murphy at arm.com> wrote:
>> On 2022-01-27 14:52, Arnd Bergmann wrote:
>>> On Thu, Jan 27, 2022 at 1:39 PM Ard Biesheuvel <ardb at kernel.org> wrote:
>>>> Cortex-A57 and Cortex-A72 have an erratum where an interrupt that
>>>> occurs between a pair of AES instructions in aarch32 mode may corrupt
>>>> the ELR. The task will subsequently produce the wrong AES result.
>>>
>>>> Fortunately, the only A72 that is known to be widely deployed with
>>>> 32-bit kernels and/or user space is the Raspberry Pi 4, which does not
>>>> implement the crypto extensions.
>>>
>>> I have previously used Amazon EC2 A1 instances (using Graviton 1, Cortex-A72)
>>> to run Debian armhf and armel user space in chroot environments. No idea how
>>> common that is for production environments, but there is a good chance that
>>> actual users might use e.g. 32-bit docker images for Alpine Linux on the same
>>> machines.
>>>
>>> There are also some early A57/A72 chips used in Android devices that may
>>> frequently run 32-bit applications, or even be limited to 32-bit
>>> kernels, see [1].
>>> Not sure how likely it is for any of them to get (a backport of) this
>>> patch though.
>>
>> Isn't ChromeOS still notoriously shipping AArch32 userspace? Between
>> Mediatek and Rockchip, both A57 and A72 are definitely playing on that
>> stage.
> 
> I wouldn't call it "notorious", but indeed that is an important user
> that I missed. For some reason I misremembered that both mt8173 and
> rk3399 are Cortex-A73 based, but they are A72 as you say.

Although it seems I misremembered about A57 - that must have been in a 
preproduction version of what became MT8173, or I'm imagining it completely.

>> I'd concur that 32-bit *kernel* on v8 is a bit of a specialist sport,
>> especially these days. IIRC Exynos 5433 might have been one of the more
>> common Android setups for that, but 2015 is now an eternity ago in phone
>> years..
> 
> Unfortunately, 32-bit kernels are still a thing on low-end Android phones,
> including some very recent Cortex-A55 based products with Android Go
> edition and 2GB of RAM or less, and also some highly popular (at the time)
> Cortex-A53 Snapdragon 410 phones started shipping before a 64-bit kernel
> port was available on Snapdragon.

Apologies, I really picked the wrong wording there, my head was buried 
in the context of this patch and larger cores in general - by "on v8" I 
think I was trying to imply shorthand for A57 up to A75 (after which it 
becomes moot anyway), and bare-metal rather than VMs at that. At the 
lower end and into weird embedded stuff AArch32 is indeed very much 
alive and well - obviously Cortex-A32 is v8, for starters. Luckily it 
isn't relevant to this erratum, although there is of course the 
implication for workarounds in general.

> A57/A72 at least disappeared from phones a long time ago because of
> both cost and power consumption reasons, so it's only the low end devices
> now. I'm not aware of any Android devices actually shipping with a 64-bit
> kernel and 32-bit user space, maybe that was never an option in the SDK.

FWIW I had the impression that that was pretty common for a while back 
before Google started actively pushing for 64-bit support, once new SoCs 
had 64-bit kernels from bringup but Android vendors still didn't like 
the storage/memory cost of having to carry both sets of runtime 
libraries around. But then my awareness of Android has always been more 
from the development end rather than what may have actually ended up 
going to market.

Cheers,
Robin.


From pgwipeout at gmail.com  Thu Jan 27 15:32:13 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 18:32:13 -0500
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
Message-ID: <CAMdYzYpkXdXDST+N8dEn7UvibXmytwNeJ+KZ9bn9Oq+RJuSaeQ@mail.gmail.com>

On Thu, Jan 27, 2022 at 2:05 PM Michael Riesch
<michael.riesch at wolfvision.net> wrote:
>
> All nodes and handles related to USB have the prefix usb or usb2,
> whereas the phy handles are prefixed with u2phy. Rename for
> consistency reasons and to facilitate sorting.
>
> This patch also updates the handles in the only board file that
> uses them (rk3566-quartz64-a.dts).

Good Evening,

While I'm not against this idea, my main concern still stands.
I spent a great deal of thought on this, and decided to go the route I
did to maintain consistency with previous generations.
As such, I see one of three paths here:
- Pull this patch only and depart rk356x from previous SoCs.
- Do the same for previous SoCs to maintain consistency.
- Drop this patch to maintain consistency with previous SoCs.

I ask that others weigh in here, as offline discussion has produced
mixed results already.

Thanks,
Peter

>
> Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
> ---
>  .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 18 ++++++++---------
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi      | 20 +++++++++----------
>  2 files changed, 19 insertions(+), 19 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> index f1d6bf10c650..3e65465ac7d5 100644
> --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> @@ -574,32 +574,32 @@ &uart2 {
>         status = "okay";
>  };
>
> -&u2phy1_host {
> -       phy-supply = <&vcc5v0_usb20_host>;
> +&usb_host0_ehci {
>         status = "okay";
>  };
>
> -&u2phy1_otg {
> -       phy-supply = <&vcc5v0_usb20_host>;
> +&usb_host0_ohci {
>         status = "okay";
>  };
>
> -&u2phy1 {
> +&usb_host1_ehci {
>         status = "okay";
>  };
>
> -&usb_host0_ehci {
> +&usb_host1_ohci {
>         status = "okay";
>  };
>
> -&usb_host0_ohci {
> +&usb2phy1 {
>         status = "okay";
>  };
>
> -&usb_host1_ehci {
> +&usb2phy1_host {
> +       phy-supply = <&vcc5v0_usb20_host>;
>         status = "okay";
>  };
>
> -&usb_host1_ohci {
> +&usb2phy1_otg {
> +       phy-supply = <&vcc5v0_usb20_host>;
>         status = "okay";
>  };
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index 8ee2fab676f4..69c30992ced2 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -214,7 +214,7 @@ usb_host0_ehci: usb at fd800000 {
>                 interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
>                 clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
>                          <&cru PCLK_USB>;
> -               phys = <&u2phy1_otg>;
> +               phys = <&usb2phy1_otg>;
>                 phy-names = "usb";
>                 status = "disabled";
>         };
> @@ -225,7 +225,7 @@ usb_host0_ohci: usb at fd840000 {
>                 interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
>                 clocks = <&cru HCLK_USB2HOST0>, <&cru HCLK_USB2HOST0_ARB>,
>                          <&cru PCLK_USB>;
> -               phys = <&u2phy1_otg>;
> +               phys = <&usb2phy1_otg>;
>                 phy-names = "usb";
>                 status = "disabled";
>         };
> @@ -236,7 +236,7 @@ usb_host1_ehci: usb at fd880000 {
>                 interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
>                 clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
>                          <&cru PCLK_USB>;
> -               phys = <&u2phy1_host>;
> +               phys = <&usb2phy1_host>;
>                 phy-names = "usb";
>                 status = "disabled";
>         };
> @@ -247,7 +247,7 @@ usb_host1_ohci: usb at fd8c0000 {
>                 interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
>                 clocks = <&cru HCLK_USB2HOST1>, <&cru HCLK_USB2HOST1_ARB>,
>                          <&cru PCLK_USB>;
> -               phys = <&u2phy1_host>;
> +               phys = <&usb2phy1_host>;
>                 phy-names = "usb";
>                 status = "disabled";
>         };
> @@ -1195,7 +1195,7 @@ pwm15: pwm at fe700030 {
>                 status = "disabled";
>         };
>
> -       u2phy0: usb2phy at fe8a0000 {
> +       usb2phy0: usb2phy at fe8a0000 {
>                 compatible = "rockchip,rk3568-usb2phy";
>                 reg = <0x0 0xfe8a0000 0x0 0x10000>;
>                 clocks = <&pmucru CLK_USBPHY0_REF>;
> @@ -1206,18 +1206,18 @@ u2phy0: usb2phy at fe8a0000 {
>                 #clock-cells = <0>;
>                 status = "disabled";
>
> -               u2phy0_host: host-port {
> +               usb2phy0_host: host-port {
>                         #phy-cells = <0>;
>                         status = "disabled";
>                 };
>
> -               u2phy0_otg: otg-port {
> +               usb2phy0_otg: otg-port {
>                         #phy-cells = <0>;
>                         status = "disabled";
>                 };
>         };
>
> -       u2phy1: usb2phy at fe8b0000 {
> +       usb2phy1: usb2phy at fe8b0000 {
>                 compatible = "rockchip,rk3568-usb2phy";
>                 reg = <0x0 0xfe8b0000 0x0 0x10000>;
>                 clocks = <&pmucru CLK_USBPHY1_REF>;
> @@ -1228,12 +1228,12 @@ u2phy1: usb2phy at fe8b0000 {
>                 #clock-cells = <0>;
>                 status = "disabled";
>
> -               u2phy1_host: host-port {
> +               usb2phy1_host: host-port {
>                         #phy-cells = <0>;
>                         status = "disabled";
>                 };
>
> -               u2phy1_otg: otg-port {
> +               usb2phy1_otg: otg-port {
>                         #phy-cells = <0>;
>                         status = "disabled";
>                 };
> --
> 2.30.2
>


From pgwipeout at gmail.com  Thu Jan 27 15:32:36 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 18:32:36 -0500
Subject: [PATCH 3/3] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <3859424.JUeRptVaKW@diego>
References: <20220127010023.3169415-1-pgwipeout@gmail.com>
 <07281029-0efd-0a74-0d96-92e3dcf5bbb7@gmail.com>
 <CAMdYzYrKq==Bs0aonrJBC+W2c4nQ8cUn2dn_Se4WDaRCkT6SYg@mail.gmail.com>
 <3859424.JUeRptVaKW@diego>
Message-ID: <CAMdYzYoQkR805xCyPstf2nrnzymVB3Ff4_cQAz_qsbokz8DG2w@mail.gmail.com>

On Thu, Jan 27, 2022 at 5:15 AM Heiko St?bner <heiko at sntech.de> wrote:
>
> Am Donnerstag, 27. Januar 2022, 10:55:13 CET schrieb Peter Geis:
> > On Thu, Jan 27, 2022 at 1:18 AM Johan Jonker <jbx6244 at gmail.com> wrote:
> > >
> > >
> > >
> > > On 1/27/22 02:00, Peter Geis wrote:
> > > > The sdmmc1 node on Quartz64-A supports the optional wifi module from
> > > > Pine64.
> > > > Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
> > > > the Quartz64-A.
> > > >
> > > > Signed-off-by: Peter Geis <pgwipeout at gmail.com>
> > > > ---
> > > >  .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 45 +++++++++++++++++++
> > > >  1 file changed, 45 insertions(+)
> > > >
> > > > diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > > index 33c2c18caaa9..1d73ac6557c5 100644
> > > > --- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > > +++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
> > > > @@ -91,6 +91,18 @@ simple-audio-card,codec {
> > > >               };
> > > >       };
> > > >
> > > > +     sdio_pwrseq: sdio-pwrseq {
> > >
> > > > +             status = "okay";
> > >
> > > When a node is not previously disabled, then there's no need for "okay".
> >
> > Thanks, this is here in case an end user wants to easily hack the
> > board to use this for other purposes.
>
> but please drop it here as well.
>
> A user "hacking" a devicetree should be able to also just _add_
> a status "disabled" :-) .

Understood, will do.
Thanks!

>
>


From linus.walleij at linaro.org  Thu Jan 27 16:18:55 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 28 Jan 2022 01:18:55 +0100
Subject: [PATCH] dt-bindings: mtd: drop mtd/cortina,gemini-flash.txt
In-Reply-To: <20220127200310.4150981-1-clabbe@baylibre.com>
References: <20220127200310.4150981-1-clabbe@baylibre.com>
Message-ID: <CACRpkdY7O=KjhbeBZiokchFhSo8dTM+JAeBOTq+qkKE7-63jPw@mail.gmail.com>

On Thu, Jan 27, 2022 at 9:03 PM Corentin Labbe <clabbe at baylibre.com> wrote:

> Drop mtd/cortina,gemini-flash.txt since it is nearly already handled by
> Documentation/devicetree/bindings/mtd/mtd-physmap.yaml.
>
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>

Thanks for fixing this Corentin!

> +      $ref: /schemas/types.yaml#/definitions/phandle
> +      description:
> +        Phandle to the syscom controller

syscon?

With that small fix:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Jan 27 16:26:54 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 28 Jan 2022 01:26:54 +0100
Subject: [PATCH v3 1/3] spi: dt-bindings: samsung: Add fsd spi compatible
In-Reply-To: <20220125031604.76009-2-alim.akhtar@samsung.com>
References: <CGME20220125032821epcas5p128c99ca3654fce0ec046943c90211849@epcas5p1.samsung.com>
 <20220125031604.76009-1-alim.akhtar@samsung.com>
 <20220125031604.76009-2-alim.akhtar@samsung.com>
Message-ID: <CACRpkdYYE9vbiFhNqJNv5VM_+YAtr2Jbg-Anoq38OY1w34zhgg@mail.gmail.com>

On Tue, Jan 25, 2022 at 4:28 AM Alim Akhtar <alim.akhtar at samsung.com> wrote:

> Adds spi controller dt-binding compatible information for
> Tesla Full Self-Driving (FSD) SoC.
>
> Cc: linux-fsd at tesla.com
> Signed-off-by: Adithya K V <adithya.kv at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Andi Shyti <andi at etezian.org>

The SoC is confirmed to be Tesla-specific, so:
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Thu Jan 27 16:28:55 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Fri, 28 Jan 2022 01:28:55 +0100
Subject: [PATCH v3 2/3] spi: s3c64xx: Add spi port configuration for Tesla
 FSD SoC
In-Reply-To: <20220125031604.76009-3-alim.akhtar@samsung.com>
References: <CGME20220125032825epcas5p2c5cf48a773fd26e089b31b0f6ddde83f@epcas5p2.samsung.com>
 <20220125031604.76009-1-alim.akhtar@samsung.com>
 <20220125031604.76009-3-alim.akhtar@samsung.com>
Message-ID: <CACRpkdZeXKmKtzZseJA36qQnHen1psjcXqy4tN+pJH2y9XZFzQ@mail.gmail.com>

On Tue, Jan 25, 2022 at 4:28 AM Alim Akhtar <alim.akhtar at samsung.com> wrote:

> Add compatible and port configuration for spi controller
> for Tesla Full Self-Driving SoC.
>
> Cc: linux-fsd at tesla.com
> Signed-off-by: Aswani Reddy <aswani.reddy at samsung.com>
> Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> Reviewed-by: Andi Shyti <andi at etezian.org>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Now I however remember that there was some discussion around
the compatible naming. I do not especially care which naming we end
up with but just make sure the compatible naming is the same in
this compatible as in the rest of the platform.

Yours,
Linus Walleij


From pgwipeout at gmail.com  Thu Jan 27 16:38:05 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 19:38:05 -0500
Subject: [PATCH v2 1/4] arm64: dts: rockchip: fix Quartz64-A ddr regulator
 voltage
In-Reply-To: <20220128003809.3291407-1-pgwipeout@gmail.com>
References: <20220128003809.3291407-1-pgwipeout@gmail.com>
Message-ID: <20220128003809.3291407-2-pgwipeout@gmail.com>

The Quartz64 Model A uses a voltage divider to ensure ddr voltage is
within specification from the default regulator configuration.
Adjusting this voltage is detrimental, and currently causes the ddr
voltage to be about 0.8v.

Remove the min and max voltage setpoints for the ddr regulator.

Fixes: b33a22a1e7c4 ("arm64: dts: rockchip: add basic dts for Pine64
Quartz64-A")

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 166399b7f13f..d9eb92d59099 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -285,8 +285,6 @@ regulator-state-mem {
 			vcc_ddr: DCDC_REG3 {
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <1100000>;
-				regulator-max-microvolt = <1100000>;
 				regulator-initial-mode = <0x2>;
 				regulator-name = "vcc_ddr";
 				regulator-state-mem {
-- 
2.25.1



From pgwipeout at gmail.com  Thu Jan 27 16:38:08 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 19:38:08 -0500
Subject: [PATCH v2 4/4] arm64: dts: rockchip: add Quartz64-A con40 hardware
In-Reply-To: <20220128003809.3291407-1-pgwipeout@gmail.com>
References: <20220128003809.3291407-1-pgwipeout@gmail.com>
Message-ID: <20220128003809.3291407-5-pgwipeout@gmail.com>

The Quartz64-A has a 40 pin connector that exposes various functions.
Annotate the functions exposed in the device tree.
Enable i2c3, which is pulled up to vcc_3v3 on board.

The following functions are currently exposed:
i2c3
spi1
uart2
uart0
spdif

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 23 +++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index c5a79046a9d0..d3dc60ff60dd 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -449,6 +449,14 @@ regulator-state-mem {
 	};
 };
 
+/* i2c3 is exposed on con40
+ * pin 3 - i2c3_sda_m0, pullup to vcc_3v3
+ * pin 5 - i2c3_scl_m0, pullup to vcc_3v3
+ */
+&i2c3 {
+	status = "okay";
+};
+
 &i2s1_8ch {
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2s1m0_sclktx
@@ -559,10 +567,17 @@ &sdmmc1 {
 	status = "okay";
 };
 
+/* spdif is exposed on con40 pin 18 */
 &spdif {
 	status = "okay";
 };
 
+/* spi1 is exposed on con40
+ * pin 11 - spi1_mosi_m1
+ * pin 13 - spi1_miso_m1
+ * pin 15 - spi1_clk_m1
+ * pin 17 - spi1_cs0_m1
+ */
 &spi1 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&spi1m1_cs0 &spi1m1_pins>;
@@ -576,6 +591,10 @@ &tsadc {
 	status = "okay";
 };
 
+/* uart0 is exposed on con40
+ * pin 12 - uart0_tx
+ * pin 14 - uart0_rx
+ */
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_xfer>;
@@ -602,6 +621,10 @@ bluetooth {
 	};
 };
 
+/* uart2 is exposed on con40
+ * pin 8 - uart2_tx_m0_debug
+ * pin 10 - uart2_rx_m0_debug
+ */
 &uart2 {
 	status = "okay";
 };
-- 
2.25.1



From pgwipeout at gmail.com  Thu Jan 27 16:38:06 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 19:38:06 -0500
Subject: [PATCH v2 2/4] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
In-Reply-To: <20220128003809.3291407-1-pgwipeout@gmail.com>
References: <20220128003809.3291407-1-pgwipeout@gmail.com>
Message-ID: <20220128003809.3291407-3-pgwipeout@gmail.com>

Several io power domains on the Quartz64-A operate at 1.8v.
Add the pmu_io_domains definition to enable support for this.
This permits the enablement of the following features:
sdio - wifi support
sdhci - mmc-hs200-1_8v

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---
 arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index d9eb92d59099..33c2c18caaa9 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -482,6 +482,19 @@ vcc_sd_h: vcc-sd-h {
 	};
 };
 
+&pmu_io_domains {
+	pmuio1-supply = <&vcc3v3_pmu>;
+	pmuio2-supply = <&vcc3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vccio_sd>;
+	vccio4-supply = <&vcc_1v8>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc1v8_dvp>;
+	vccio7-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
 &sdhci {
 	bus-width = <8>;
 	mmc-hs200-1_8v;
-- 
2.25.1



From pgwipeout at gmail.com  Thu Jan 27 16:38:04 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 19:38:04 -0500
Subject: [PATCH v2 0/4] Quartz64-A fixes and enablement from 5.17-rc1
Message-ID: <20220128003809.3291407-1-pgwipeout@gmail.com>


Good Evening,

This is the first of several patch series for further expanding
Quartz64-A support.

This series has the following patches:
Fix the ddr regulator voltage.
Add pmu_io_domains to permit sdio and high speed emmc support.
Add sdmmc1 node for wifi support.
Annotate con40 functions and enable i2c3.

Please review and apply.

Very Respectfully,
Peter Geis

Changelog:
v2:
- drop status = "okay" from sdio_pwrseq
- drop disable-wp from sdmmc1
- move reset-gpios to be alphabetical in sdio_pwrseq
- add con40 annotation patch

Peter Geis (4):
  arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
  arm64: dts: rockchip: add Quartz64-A pmu_io_domains
  arm64: dts: rockchip: add Quartz64-A sdmmc1 node
  arm64: dts: rockchip: add Quartz64-A con40 hardware

 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 81 ++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

-- 
2.25.1



From pgwipeout at gmail.com  Thu Jan 27 16:38:07 2022
From: pgwipeout at gmail.com (Peter Geis)
Date: Thu, 27 Jan 2022 19:38:07 -0500
Subject: [PATCH v2 3/4] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
In-Reply-To: <20220128003809.3291407-1-pgwipeout@gmail.com>
References: <20220128003809.3291407-1-pgwipeout@gmail.com>
Message-ID: <20220128003809.3291407-4-pgwipeout@gmail.com>

The sdmmc1 node on Quartz64-A supports the optional wifi module from
Pine64.
Add the sdmmc1 node and requisite sdio_pwrseq to enable wifi support on
the Quartz64-A.

Signed-off-by: Peter Geis <pgwipeout at gmail.com>
---

Changelog:
v2:
- drop status = "okay" from sdio_pwrseq
- drop disable-wp from sdmmc1
- move reset-gpios to be alphabetical in sdio_pwrseq

---
 .../boot/dts/rockchip/rk3566-quartz64-a.dts   | 43 +++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
index 33c2c18caaa9..c5a79046a9d0 100644
--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
@@ -91,6 +91,17 @@ simple-audio-card,codec {
 		};
 	};
 
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk817 1>;
+		clock-names = "ext_clock";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_enable_h>;
+		post-power-on-delay-ms = <100>;
+		power-off-delay-us = <5000000>;
+		reset-gpios = <&gpio2 RK_PC2 GPIO_ACTIVE_LOW>;
+	};
+
 	vcc12v_dcin: vcc12v_dcin {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc12v_dcin";
@@ -147,6 +158,17 @@ vcc_sys: vcc_sys {
 		regulator-max-microvolt = <4400000>;
 		vin-supply = <&vbus>;
 	};
+
+	/* sourced from vcc_sys, sdio module operates internally at 3.3v */
+	vcc_wl: vcc_wl {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_wl";
+		regulator-always-on;
+		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
 };
 
 &cpu0 {
@@ -475,6 +497,12 @@ pmic_int_l: pmic-int-l {
 		};
 	};
 
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <2 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	vcc_sd {
 		vcc_sd_h: vcc-sd-h {
 			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -516,6 +544,21 @@ &sdmmc0 {
 	status = "okay";
 };
 
+&sdmmc1 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&sdmmc1_bus4 &sdmmc1_cmd &sdmmc1_clk>;
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_wl>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
 &spdif {
 	status = "okay";
 };
-- 
2.25.1



From tharvey at gateworks.com  Thu Jan 27 17:06:03 2022
From: tharvey at gateworks.com (Tim Harvey)
Date: Thu, 27 Jan 2022 17:06:03 -0800
Subject: [PATCH v2] arm64: dts: imx8m{m,n}_venice*: add gpio-line-names
Message-ID: <20220128010603.17620-1-tharvey@gateworks.com>

Add gpio-line-names for the various GPIO's used on Gateworks Venice
boards. Note that these GPIO's are typically 'configured' in Boot
Firmware via gpio-hog therefore we only configure line names to keep the
boot firmware configuration from changing on kernel init.

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
v2: rebase on imx/dt64
---
 .../dts/freescale/imx8mm-venice-gw71xx.dtsi   | 14 +++++++
 .../dts/freescale/imx8mm-venice-gw72xx.dtsi   | 16 ++++++++
 .../dts/freescale/imx8mm-venice-gw73xx.dtsi   | 16 ++++++++
 .../dts/freescale/imx8mm-venice-gw7901.dts    | 23 +++++++++++
 .../dts/freescale/imx8mm-venice-gw7902.dts    | 39 ++++++++++++++++++-
 .../dts/freescale/imx8mn-venice-gw7902.dts    | 39 ++++++++++++++++++-
 6 files changed, 145 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
index 506335efc391..73addc0b8e57 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -68,6 +68,20 @@
 	status = "okay";
 };
 
+&gpio1 {
+	gpio-line-names = "", "", "", "", "", "", "pci_usb_sel", "dio0",
+		"", "dio1", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "", "", "", "dio2", "dio3", "", "", "pci_wdis#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &i2c2 {
 	clock-frequency = <400000>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
index 72a3a3aa8fcd..1e7badb2a82e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi
@@ -88,6 +88,22 @@
 	status = "okay";
 };
 
+&gpio1 {
+	gpio-line-names = "rs485_term", "mipi_gpio4", "", "",
+		"", "", "pci_usb_sel", "dio0",
+		"", "dio1", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "rs485_en", "mipi_gpio3", "rs485_hd", "mipi_gpio2",
+		"mipi_gpio1", "", "", "pci_wdis#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &i2c2 {
 	clock-frequency = <400000>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
index 7b00b6b5bb38..426483ec1f88 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx.dtsi
@@ -108,6 +108,22 @@
 	status = "okay";
 };
 
+&gpio1 {
+	gpio-line-names = "rs485_term", "mipi_gpio4", "", "",
+		"", "", "pci_usb_sel", "dio0",
+		"", "dio1", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "rs485_en", "mipi_gpio3", "rs485_hd", "mipi_gpio2",
+		"mipi_gpio1", "", "", "pci_wdis#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &i2c2 {
 	clock-frequency = <400000>;
 	pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
index ca754dff918d..7e7231046215 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts
@@ -293,6 +293,29 @@
 	};
 };
 
+&gpio1 {
+	gpio-line-names = "uart1_rs422#", "", "", "uart1_rs485#",
+		"", "uart1_rs232#", "dig1_in", "dig1_out",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "", "", "", "",
+		"", "", "uart3_rs232#", "uart3_rs422#",
+		"uart3_rs485#", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "uart4_rs485#", "", "sim1det#", "sim2det#", "";
+};
+
+&gpio5 {
+	gpio-line-names = "", "", "", "dig2_out", "dig2_in", "sim2sel", "", "",
+		"", "", "uart4_rs232#", "", "", "uart4_rs422#", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &gpu_2d {
 	status = "disabled";
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
index 1b2aaf299b24..edf0c7aaaef0 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7902.dts
@@ -260,6 +260,43 @@
 	};
 };
 
+&gpio1 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"", "", "", "", "", "m2_reset", "", "m2_wdis#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"uart2_en#", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio3 {
+	gpio-line-names = "", "m2_gdis#", "", "", "", "", "", "m2_off#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"", "", "", "amp_gpio3", "amp_gpio2", "", "amp_gpio1", "",
+		"", "", "", "", "amp_gpio4", "app_gpio1", "", "uart1_rs485",
+		"", "uart1_term", "uart1_half", "app_gpio2",
+		"mipi_gpio1", "", "", "";
+};
+
+&gpio5 {
+	gpio-line-names = "", "", "", "mipi_gpio4",
+		"mipi_gpio3", "mipi_gpio2", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &i2c1 {
 	clock-frequency = <100000>;
 	pinctrl-names = "default";
@@ -691,7 +728,7 @@
 	pinctrl_hog: hoggrp {
 		fsl,pins = <
 			MX8MM_IOMUXC_NAND_CE0_B_GPIO3_IO1	0x40000159 /* M2_GDIS# */
-			MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13	0x40000041 /* M2_RST# */
+			MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13	0x40000041 /* M2_RESET */
 			MX8MM_IOMUXC_NAND_DATA01_GPIO3_IO7	0x40000119 /* M2_OFF# */
 			MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15	0x40000159 /* M2_WDIS# */
 			MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14	0x40000041 /* AMP GPIO1 */
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
index 2d58005d20e4..3c0e63d2e82d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts
@@ -255,6 +255,43 @@
 	};
 };
 
+&gpio1 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"", "", "", "", "", "m2_reset", "", "m2_wdis#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio2 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"uart2_en#", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio3 {
+	gpio-line-names = "", "m2_gdis#", "", "", "", "", "", "m2_off#",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
+&gpio4 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "app_gpio1", "", "uart1_rs485",
+		"", "uart1_term", "uart1_half", "app_gpio2",
+		"mipi_gpio1", "", "", "";
+};
+
+&gpio5 {
+	gpio-line-names = "", "", "", "mipi_gpio4",
+		"mipi_gpio3", "mipi_gpio2", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "",
+		"", "", "", "", "", "", "", "";
+};
+
 &gpu {
 	status = "disabled";
 };
@@ -645,7 +682,7 @@
 	pinctrl_hog: hoggrp {
 		fsl,pins = <
 			MX8MN_IOMUXC_NAND_CE0_B_GPIO3_IO1	0x40000159 /* M2_GDIS# */
-			MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13	0x40000041 /* M2_RST# */
+			MX8MN_IOMUXC_GPIO1_IO13_GPIO1_IO13	0x40000041 /* M2_RESET */
 			MX8MN_IOMUXC_NAND_DATA01_GPIO3_IO7	0x40000119 /* M2_OFF# */
 			MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15	0x40000159 /* M2_WDIS# */
 			MX8MN_IOMUXC_SAI2_RXFS_GPIO4_IO21	0x40000041 /* APP GPIO1 */
-- 
2.17.1



From allen-kh.cheng at mediatek.com  Thu Jan 27 17:09:53 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 09:09:53 +0800
Subject: [PATCH v2 7/7] arm64: dts: Add Mediatek SoC MT8186 dts and
 evaluation board and Makefile
In-Reply-To: <CAJMQK-j0F_yrWNnS418O7e1AdS7VH76XdQMx2boLoe2LVV0nYA@mail.gmail.com>
References: <20220105022726.2458-1-allen-kh.cheng@mediatek.com>
 <20220105022726.2458-8-allen-kh.cheng@mediatek.com>
 <CAJMQK-j0F_yrWNnS418O7e1AdS7VH76XdQMx2boLoe2LVV0nYA@mail.gmail.com>
Message-ID: <f534568034a263fc518374653dffdb52f49344b8.camel@mediatek.com>

On Thu, 2022-01-27 at 14:17 +0800, Hsin-Yi Wang wrote:
> On Wed, Jan 5, 2022 at 10:27 AM allen-kh.cheng
> <allen-kh.cheng at mediatek.com> wrote:
> > 
> > From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> > 
> > Add basic chip support for Mediatek MT8186
> > 
> > Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> > ---
> >  arch/arm64/boot/dts/mediatek/Makefile       |   1 +
> >  arch/arm64/boot/dts/mediatek/mt8186-evb.dts |  24 ++
> >  arch/arm64/boot/dts/mediatek/mt8186.dtsi    | 352
> > ++++++++++++++++++++
> >  3 files changed, 377 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi
> > 
> > diff --git a/arch/arm64/boot/dts/mediatek/Makefile
> > b/arch/arm64/boot/dts/mediatek/Makefile
> > index 4f68ebed2e31..2271c3452c64 100644
> > --- a/arch/arm64/boot/dts/mediatek/Makefile
> > +++ b/arch/arm64/boot/dts/mediatek/Makefile
> > @@ -31,5 +31,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-
> > kodama-sku32.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
> > +dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
> >  dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> > b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> > new file mode 100644
> > index 000000000000..eb23d1f19f87
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> > @@ -0,0 +1,24 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + */
> > +/dts-v1/;
> > +#include "mt8186.dtsi"
> > +
> > +/ {
> > +       model = "MediaTek MT8186 evaluation board";
> > +       compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
> > +
> > +       aliases {
> > +               serial0 = &uart0;
> > +       };
> > +
> > +       chosen {
> > +               stdout-path = "serial0:921600n8";
> > +       };
> > +
> > +       memory {
> > +               device_type = "memory";
> > +               reg = <0 0x40000000 0 0x80000000>;
> > +       };
> > +};
> > diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> > b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> > new file mode 100644
> > index 000000000000..fce84c341291
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
> > @@ -0,0 +1,352 @@
> > +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> > +/*
> > + * Copyright (C) 2022 MediaTek Inc.
> > + */
> > +/dts-v1/;
> > +
> > +#include <dt-bindings/interrupt-controller/arm-gic.h>
> > +#include <dt-bindings/interrupt-controller/irq.h>
> > +#include <dt-bindings/phy/phy.h>
> > +
> > +/ {
> > +       compatible = "mediatek,mt8186";
> > +       interrupt-parent = <&gic>;
> > +       #address-cells = <2>;
> > +       #size-cells = <2>;
> > +
> > +       cpus {
> > +               #address-cells = <1>;
> > +               #size-cells = <0>;
> > +
> > +               cpu0: cpu at 000 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0000>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu1: cpu at 001 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0100>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu2: cpu at 002 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0200>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu3: cpu at 003 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0300>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu4: cpu at 100 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0400>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu5: cpu at 101 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a55", "arm,armv8";
> > +                       reg = <0x0500>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2000000000>;
> > +                       cpu-idle-states = <&cpuoff_l &clusteroff_l
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_0>;
> > +               };
> > +
> > +               cpu6: cpu at 102 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a75", "arm,armv8";
> > +                       reg = <0x0600>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2050000000>;
> > +                       cpu-idle-states = <&cpuoff_b &clusteroff_b
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_1>;
> > +               };
> > +
> > +               cpu7: cpu at 103 {
> > +                       device_type = "cpu";
> > +                       compatible = "arm,cortex-a75", "arm,armv8";
> > +                       reg = <0x0700>;
> > +                       enable-method = "psci";
> > +                       clock-frequency = <2050000000>;
> > +                       cpu-idle-states = <&cpuoff_b &clusteroff_b
> > &mcusysoff>;
> > +                       next-level-cache = <&l2_1>;
> > +               };
> > +
> > +               cpu-map {
> > +                       cluster0 {
> > +                               core0 {
> > +                                       cpu = <&cpu0>;
> > +                               };
> > +
> > +                               core1 {
> > +                                       cpu = <&cpu1>;
> > +                               };
> > +
> > +                               core2 {
> > +                                       cpu = <&cpu2>;
> > +                               };
> > +
> > +                               core3 {
> > +                                       cpu = <&cpu3>;
> > +                               };
> > +
> > +                               core4 {
> > +                                       cpu = <&cpu4>;
> > +                               };
> > +
> > +                               core5 {
> > +                                       cpu = <&cpu5>;
> > +                               };
> > +
> > +                       };
> > +                       cluster1 {
> > +                               core0 {
> > +                                       cpu = <&cpu6>;
> > +                               };
> > +
> > +                               core1 {
> > +                                       cpu = <&cpu7>;
> > +                               };
> > +                       };
> > +               };
> > +
> > +               idle-states {
> > +                       entry-method = "psci";
> > +
> > +                       cpuoff_l: cpu-off-l {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x00010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <50>;
> > +                               exit-latency-us = <100>;
> > +                               min-residency-us = <1600>;
> > +                       };
> > +
> > +                       cpuoff_b: cpu-off-b {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x00010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <50>;
> > +                               exit-latency-us = <100>;
> > +                               min-residency-us = <1400>;
> > +                       };
> > +
> > +                       clusteroff_l: cluster-off-l {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x01010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <100>;
> > +                               exit-latency-us = <250>;
> > +                               min-residency-us = <2100>;
> > +                       };
> > +
> > +                       clusteroff_b: cluster-off-b {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x01010001>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <100>;
> > +                               exit-latency-us = <250>;
> > +                               min-residency-us = <1900>;
> > +                       };
> > +
> > +                       mcusysoff: mcusys-off {
> > +                               compatible = "arm,idle-state";
> > +                               arm,psci-suspend-param =
> > <0x01010002>;
> > +                               local-timer-stop;
> > +                               entry-latency-us = <300>;
> > +                               exit-latency-us = <1200>;
> > +                               min-residency-us = <2600>;
> > +                       };
> > +               };
> > +
> > +               l2_0: l2-cache0 {
> > +                       compatible = "cache";
> > +                       next-level-cache = <&l3_0>;
> > +               };
> > +
> > +               l2_1: l2-cache1 {
> > +                       compatible = "cache";
> > +                       next-level-cache = <&l3_0>;
> > +               };
> > +
> > +               l3_0: l3-cache {
> > +                       compatible = "cache";
> > +               };
> > +       };
> > +
> > +       clk26m: oscillator-26m {
> > +               compatible = "fixed-clock";
> > +               #clock-cells = <0>;
> > +               clock-frequency = <26000000>;
> > +       };
> > +
> > +       clk32k: oscillator-32k {
> > +               compatible = "fixed-clock";
> > +               #clock-cells = <0>;
> > +               clock-frequency = <32000>;
> > +       };
> > +
> > +       psci {
> > +               compatible      = "arm,psci-1.0";
> > +               method          = "smc";
> > +       };
> > +
> 
> please move below nodes into soc {}

Hi Hsin-Yi,

Thanks you for your feedback.

I will add soc {} in next version.

> 
> 
> > +       gic: interrupt-controller {
> > +               compatible = "arm,gic-v3";
> > +               #interrupt-cells = <3>;
> > +               #address-cells = <2>;
> > +               #size-cells = <2>;
> > +               #redistributor-regions = <1>;
> > +               interrupt-parent = <&gic>;
> > +               interrupt-controller;
> > +               reg = <0 0x0c000000 0 0x40000>, // distributor
> > +                     <0 0x0c040000 0 0x200000>; // redistributor
> > +               interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
> > +       };
> > +
> > +       watchdog: watchdog at 10007000 {
> > +               compatible = "mediatek,mt8186-wdt",
> > +                               "mediatek,mt6589-wdt";
> > +               reg = <0 0x10007000 0 0x1000>;
> > +       };
> > +
> > +       sys_timer at 10017000 {
> > +               compatible = "mediatek,mt8186_timer",
> > +                            "mediatek,mt6765-timer";
> > +               reg = <0 0x10017000 0 0x1000>;
> > +               interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>;
> > +       };
> > +
> > +       timer: timer {
> > +               compatible = "arm,armv8-timer";
> > +               interrupt-parent = <&gic>;
> > +               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
> > +                               <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
> > +                               <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
> > +                               <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
> > +               clock-frequency = <13000000>;
> > +       };
> > +
> > +       uart0: serial at 11002000 {
> > +               compatible = "mediatek,mt8186-uart",
> > +                            "mediatek,mt6577-uart";
> > +               reg = <0 0x11002000 0 0x1000>;
> > +               interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>, <&clk26m>;
> > +               clock-names = "baud", "bus";
> > +       };
> > +
> > +       uart1: serial at 11003000 {
> > +               compatible = "mediatek,mt8186-uart",
> > +                            "mediatek,mt6577-uart";
> > +               reg = <0 0x11003000 0 0x1000>;
> > +               interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>, <&clk26m>;
> > +               clock-names = "baud", "bus";
> > +               status = "disabled";
> > +       };
> > +
> > +       uart2: serial at 11018000 {
> > +               compatible = "mediatek,mt8186-uart",
> > +                            "mediatek,mt6577-uart";
> > +               reg = <0 0x11018000 0 0x1000>;
> > +               interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>, <&clk26m>;
> > +               clock-names = "baud", "bus";
> > +               status = "disabled";
> > +       };
> > +
> > +       mmc0: mmc at 11230000 {
> > +               compatible = "mediatek,mt8186-mmc",
> > "mediatek,mt8183-mmc";
> > +               reg = <0 0x11230000 0 0x1000>,
> > +                     <0 0x11cd0000 0 0x1000>;
> > +               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>,
> > +                        <&clk26m>,
> > +                        <&clk26m>,
> > +                        <&clk26m>;
> > +               clock-names = "source", "hclk", "source_cg",
> > +                             "ahb_clk";
> > +               status = "disabled";
> > +       };
> > +
> > +       mmc1: mmc at 11240000 {
> > +               compatible = "mediatek,mt8186-mmc",
> > "mediatek,mt8183-mmc";
> > +               reg = <0 0x11240000 0 0x1000>,
> > +                     <0 0x11c90000 0 0x1000>;
> > +               interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
> > +               clocks = <&clk26m>,
> > +                        <&clk26m>,
> > +                        <&clk26m>;
> > +               clock-names = "source", "hclk", "source_cg";
> > +               status = "disabled";
> > +       };
> > +
> > +       u3phy1: usb-phy1 at 11c80000 {
> > +               compatible = "mediatek,mt8186-tphy",
> > "mediatek,generic-tphy-v2";
> > +               #address-cells = <2>;
> > +               #size-cells = <2>;
> > +               ranges;
> > +               status = "okay";
> > +
> > +               u2port1: usb2-phy1 at 11c80000 {
> > +                       reg = <0 0x11c80000 0 0x700>;
> > +                       clocks = <&clk26m>;
> > +                       clock-names = "ref";
> > +                       #phy-cells = <1>;
> > +                       status = "okay";
> > +               };
> > +
> > +               u3port1: usb3-phy1 at 11c80900 {
> > +                       reg = <0 0x11c80900 0 0x700>;
> > +                       clocks = <&clk26m>;
> > +                       clock-names = "ref";
> > +                       #phy-cells = <1>;
> > +                       status = "okay";
> > +               };
> > +       };
> > +
> > +       u3phy0: usb-phy at 11ca0000 {
> > +               compatible = "mediatek,mt8186-tphy",
> > "mediatek,generic-tphy-v2";
> > +               #address-cells = <2>;
> > +               #size-cells = <2>;
> > +               ranges;
> > +               status = "okay";
> > +
> > +               u2port0: usb2-phy at 11ca0000 {
> > +                       reg = <0 0x11ca0000 0 0x700>;
> > +                       clocks = <&clk26m>;
> > +                       clock-names = "ref";
> > +                       #phy-cells = <1>;
> > +                       mediatek,discth = <0x8>;
> > +                       status = "okay";
> > +               };
> > +       };
> > +};
> > --
> > 2.18.0
> > 



From john.fastabend at gmail.com  Thu Jan 27 18:43:53 2022
From: john.fastabend at gmail.com (John Fastabend)
Date: Thu, 27 Jan 2022 18:43:53 -0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <8b67fa3d-f83c-85a5-5159-70b0f913833a@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
 <61f23655411bc_57f032084@john.notmuch>
 <8b67fa3d-f83c-85a5-5159-70b0f913833a@huawei.com>
Message-ID: <61f35869ba5a_738dc20823@john.notmuch>

Hou Tao wrote:
> Hi,
> 
> On 1/27/2022 2:06 PM, John Fastabend wrote:
> > Hou Tao wrote:
> >> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
> >> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
> >> it only add support for x86-64, so support these atomic operations
> >> for arm64 as well.
> >>
> >> +static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
> >> +{
> >> +	const u8 code = insn->code;
> >> +	const u8 dst = bpf2a64[insn->dst_reg];
> >> +	const u8 src = bpf2a64[insn->src_reg];
> >> +	const u8 tmp = bpf2a64[TMP_REG_1];
> >> +	const u8 tmp2 = bpf2a64[TMP_REG_2];
> >> +	const bool isdw = BPF_SIZE(code) == BPF_DW;
> >> +	const s16 off = insn->off;
> >> +	u8 reg;
> >> +
> >> +	if (!off) {
> >> +		reg = dst;
> >> +	} else {
> >> +		emit_a64_mov_i(1, tmp, off, ctx);
> >> +		emit(A64_ADD(1, tmp, tmp, dst), ctx);
> >> +		reg = tmp;
> >> +	}
> >> +
> >> +	switch (insn->imm) {
> > Diff'ing X86 implementation which has a BPF_SUB case how is it avoided
> > here?
> I think it is just left over from patchset [1], because according to the LLVM
> commit [2]
> __sync_fetch_and_sub(&addr, value) is implemented by __sync_fetch_and_add(&addr,
> -value).
> I will post a patch to remove it.

OK in that case LGTM with the caveat not an ARM expert.

Acked-by: John Fastabend <john.fastabend at gmail.com>

[...]

> >> +	default:
> >> +		pr_err_once("unknown atomic op code %02x\n", insn->imm);
> >> +		return -EINVAL;
> > Was about to suggest maybe EFAULT to align with x86, but on second
> > thought seems arm jit uses EINVAL more universally so best to be
> > self consistent. Just an observation.
> OK. So I will still return -EINVAL for invalid atomic operation.

Sounds good to me.

> >
> >> +	}
> >> +
> >> +	return 0;
> >> +}
> >> +
> > .
> 




From lkp at intel.com  Thu Jan 27 18:47:07 2022
From: lkp at intel.com (kernel test robot)
Date: Fri, 28 Jan 2022 10:47:07 +0800
Subject: [PATCH 1/3] arm64: selftests: Generate all the possible logical
 immediates as a header
In-Reply-To: <20220127162127.2391947-2-james.morse@arm.com>
References: <20220127162127.2391947-2-james.morse@arm.com>
Message-ID: <202201281052.Nzl9wJM4-lkp@intel.com>

Hi James,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on arm/for-next xilinx-xlnx/master soc/for-next kvmarm/next v5.17-rc1 next-20220127]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/James-Morse/arm64-insn-Generate-64-bit-mask-immediates-correctly/20220128-002213
base:   https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: arm64-randconfig-p001-20220128 (https://download.01.org/0day-ci/archive/20220128/202201281052.Nzl9wJM4-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/1ead98d2c8c4c28ea27964dbf7b5b89a83b8e7ec
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review James-Morse/arm64-insn-Generate-64-bit-mask-immediates-correctly/20220128-002213
        git checkout 1ead98d2c8c4c28ea27964dbf7b5b89a83b8e7ec
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 prepare

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   arch/arm64/tools/gen_logic_imm.c: In function 'validate':
>> arch/arm64/tools/gen_logic_imm.c:81:2: warning: ignoring return value of 'write' declared with attribute 'warn_unused_result' [-Wunused-result]
      81 |  write(fd, &insn, sizeof(insn));
         |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
   arch/arm64/tools/gen_logic_imm.c: In function 'validate':
>> arch/arm64/tools/gen_logic_imm.c:81:2: warning: ignoring return value of 'write' declared with attribute 'warn_unused_result' [-Wunused-result]
      81 |  write(fd, &insn, sizeof(insn));
         |  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/kernel/vdso/vgettimeofday.c:9:5: warning: no previous prototype for '__kernel_clock_gettime' [-Wmissing-prototypes]
       9 | int __kernel_clock_gettime(clockid_t clock,
         |     ^~~~~~~~~~~~~~~~~~~~~~
   arch/arm64/kernel/vdso/vgettimeofday.c:15:5: warning: no previous prototype for '__kernel_gettimeofday' [-Wmissing-prototypes]
      15 | int __kernel_gettimeofday(struct __kernel_old_timeval *tv,
         |     ^~~~~~~~~~~~~~~~~~~~~
   arch/arm64/kernel/vdso/vgettimeofday.c:21:5: warning: no previous prototype for '__kernel_clock_getres' [-Wmissing-prototypes]
      21 | int __kernel_clock_getres(clockid_t clock_id,
         |     ^~~~~~~~~~~~~~~~~~~~~


vim +81 arch/arm64/tools/gen_logic_imm.c

    55	
    56	#define PIPE_READ	0
    57	#define PIPE_WRITE	1
    58	/*
    59	 * Use objdump to decode the encoded instruction, and compare the immediate.
    60	 * On error, returns the bad instruction, otherwise returns 0.
    61	 */
    62	static int validate(u64 val, u32 immN, u32 imms, u32 immr, char *objdump)
    63	{
    64		pid_t child;
    65		char *immediate;
    66		char val_str[32];
    67		u32 insn = 0x12000000;
    68		char output[1024] = {0};
    69		int fd, pipefd[2], bytes;
    70		char filename[] = "validate_gen_logic_imm.XXXXXX";
    71	
    72		insn |= 1 << 31;
    73		insn |= (immN & 0x1)<<22;
    74		insn |= (immr & 0x3f)<<16;
    75		insn |= (imms & 0x3f)<<10;
    76	
    77		fd = mkstemp(filename);
    78		if (fd < 0)
    79			abort();
    80	
  > 81		write(fd, &insn, sizeof(insn));
    82		close(fd);
    83	
    84		if (pipe(pipefd))
    85			return 0;
    86	
    87		child = vfork();
    88		if (child) {
    89			close(pipefd[PIPE_WRITE]);
    90			waitpid(child, NULL, 0);
    91	
    92			bytes = read(pipefd[PIPE_READ], output, sizeof(output));
    93			close(pipefd[PIPE_READ]);
    94			if (!bytes || bytes == sizeof(output))
    95				return insn;
    96	
    97			immediate = strstr(output, "x0, x0, #");
    98			if (!immediate)
    99				return insn;
   100			immediate += strlen("x0, x0, #");
   101	
   102			/*
   103			 * strtoll() has its own ideas about overflow and underflow.
   104			 * Do a string comparison. immediate ends in a newline.
   105			 */
   106			snprintf(val_str, sizeof(val_str), "0x%lx", val);
   107			if (strncmp(val_str, immediate, strlen(val_str))) {
   108				fprintf(stderr, "Unexpected decode from objdump: %s\n",
   109					immediate);
   110				return insn;
   111			}
   112		} else {
   113			close(pipefd[PIPE_READ]);
   114			close(1);
   115			dup2(pipefd[PIPE_WRITE], 1);
   116			execl(objdump, objdump, "-b", "binary", "-m", "aarch64", "-D",
   117			      filename, (char *) NULL);
   118			abort();
   119		}
   120	
   121		unlink(filename);
   122		return 0;
   123	}
   124	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From herbert at gondor.apana.org.au  Thu Jan 27 18:58:53 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 28 Jan 2022 13:58:53 +1100
Subject: PROBLEM: encryption test failures since "crypto: mxs-dcp - Use
 sg_mapping_iter to copy data"
In-Reply-To: <414858de-f279-c5ce-83ca-5c28d6c847b1@seco.com>
References: <2126453.Icojqenx9y@localhost.localdomain>
 <414858de-f279-c5ce-83ca-5c28d6c847b1@seco.com>
Message-ID: <YfNb7WMXWv1flCvM@gondor.apana.org.au>

On Thu, Jan 27, 2022 at 12:31:48PM -0500, Sean Anderson wrote:
> Hi Christian,
> 
> On 1/27/22 12:23 PM, Christian Eggers wrote:
> > SoC: i.MX6ULL
> > 
> > After upgrading from v5.10.65-rt53 to v5.10.73-rt54 I get two additional messages on boot:
> > 
> > ...
> > [ 3.786333] alg: skcipher: ecb-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> > [ 3.789020] alg: skcipher: cbc-aes-dcp encryption test failed (wrong result) on test vector 0, cfg="two even aligned splits"
> > [ 3.793741] mxs-dcp 2280000.crypto: mxs_dcp: initialized
> > ..
> > 
> > After reverting the commit
> > 
> > 2e6d793e1bf0 ("crypto: mxs-dcp - Use sg_mapping_iter to copy data")
> > 
> > the error messages above disappear again.
> 
> Can you try applying the patch in [1] on top of your revert?

Please resubmit your patch with a proper Subject, otherwise it'll
be automatically discarded by patchwork.

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From yunfei.dong at mediatek.com  Thu Jan 27 19:23:30 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:23:30 +0800
Subject: [PATCH] media: uapi: Init VP9 stateless decode params
Message-ID: <20220128032330.24045-1-yunfei.dong@mediatek.com>

Init some of VP9 frame decode params to default value.

Fixes: b88dbe38dca8 ("media: uapi: Add VP9 stateless decoder controls")
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c
index 54abe5245dcc..b25c77b8a445 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -112,6 +112,7 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
 	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
 	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
+	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
 	struct v4l2_ctrl_fwht_params *p_fwht_params;
 	void *p = ptr.p + idx * ctrl->elem_size;
 
@@ -152,6 +153,13 @@ static void std_init_compound(const struct v4l2_ctrl *ctrl, u32 idx,
 		p_vp8_frame = p;
 		p_vp8_frame->num_dct_parts = 1;
 		break;
+	case V4L2_CTRL_TYPE_VP9_FRAME:
+		p_vp9_frame = p;
+		p_vp9_frame->profile = 0;
+		p_vp9_frame->bit_depth = 8;
+		p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
+			V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
+		break;
 	case V4L2_CTRL_TYPE_FWHT_PARAMS:
 		p_fwht_params = p;
 		p_fwht_params->version = V4L2_FWHT_VERSION;
-- 
2.25.1



From ck.hu at mediatek.com  Thu Jan 27 19:26:09 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 28 Jan 2022 11:26:09 +0800
Subject: [RFC PATCH 2/2] drm/mediatek: add mtk8195 hdmi display driver
In-Reply-To: <20211108000847.14320-3-granquet@baylibre.com>
References: <20211108000847.14320-1-granquet@baylibre.com>
 <20211108000847.14320-3-granquet@baylibre.com>
Message-ID: <55d7459dd403b55594e707680b014a8a4c84e344.camel@mediatek.com>

Hi, Guillaume:

On Mon, 2021-11-08 at 01:08 +0100, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Change-Id: I6399dec26cfe56a338c2ca96989cb7cbd14e292b
> ---
>  drivers/gpu/drm/mediatek/Kconfig              |    9 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  219 +-
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |   24 +-
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c    | 1835
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h    |   26 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c    |  530 +++++
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h    |   20 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h   |  329 +++
>  9 files changed, 2932 insertions(+), 62 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h
> 
> 

[snip]

>  
> diff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> index f60b5b8bf99e..a58946d3848b 100644
> --- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.h
> @@ -25,12 +25,17 @@
>  
>  #include <sound/hdmi-codec.h>
>  
> +//TODO: see what can be done here... :-/
> +#include "mtk_mt8195_hdmi_ddc.h"
> +#include "mtk_mt8195_hdmi.h"
>  #include "mtk_cec.h"
>  #include "mtk_hdmi.h"
>  
>  struct mtk_hdmi_conf {
>  	bool tz_disabled;
>  	bool cea_modes_only;
> +	bool is_mt8195;
> +	bool low_power;
>  	unsigned long max_mode_clock;
>  };
>  
> @@ -127,6 +132,17 @@ enum hdmi_aud_channel_swap_type {
>  	HDMI_AUD_SWAP_LR_STATUS,
>  };
>  
> +enum mtk_hdmi_clk_id_mt8195 {
> +	MTK_MT8195_HDMI_CLK_UNIVPLL_D6D4,
> +	MTK_MT8195_HDMI_CLK_MSDCPLL_D2,
> +	MTK_MT8195_HDMI_CLK_HDMI_APB_SEL,
> +	MTK_MT8195_HDMI_UNIVPLL_D4D8,
> +	MTK_MT8195_HDIM_HDCP_SEL,
> +	MTK_MT8195_HDMI_HDCP_24M_SEL,
> +	MTK_MT8195_HDMI_VPP_SPLIT_HDMI,
> +	MTK_MT8195_HDMI_CLK_COUNT,
> +};
> +
>  enum mtk_hdmi_clk_id_mt8183 {
>  	MTK_MT8183_HDMI_CLK_HDMI_PIXEL,
>  	MTK_MT8183_HDMI_CLK_HDMI_PLL,
> @@ -136,6 +152,7 @@ enum mtk_hdmi_clk_id_mt8183 {
>  };
>  
>  extern const char *const
> mtk_hdmi_clk_names_mt8183[MTK_MT8183_HDMI_CLK_COUNT];
> +extern const char *const
> mtk_hdmi_clk_names_mt8195[MTK_MT8195_HDMI_CLK_COUNT];
>  
>  enum hdmi_hpd_state {
>  	HDMI_PLUG_OUT = 0,
> @@ -160,7 +177,8 @@ struct mtk_hdmi {
>  	const struct mtk_hdmi_conf *conf;
>  	struct phy *phy;
>  	struct i2c_adapter *ddc_adpt;
> -	struct clk *clk[MTK_MT8183_HDMI_CLK_COUNT];
> +	//TODO: array size is max(MTK_MT8183_HDMI_CLK_COUNT,
> MTK_MT8195_HDMI_CLK_COUNT)... dynamically allocate instead?
> +	struct clk *clk[MTK_MT8195_HDMI_CLK_COUNT];
>  	struct drm_display_mode mode;
>  	bool dvi_mode;
>  	struct regmap *sys_regmap;
> @@ -228,9 +246,13 @@ int mtk_drm_hdmi_probe(struct platform_device
> *pdev);
>  int mtk_drm_hdmi_remove(struct platform_device *pdev);
>  
>  //TODO: do better than this? function pointers?
> +extern const struct drm_bridge_funcs mtk_mt8195_hdmi_bridge_funcs;
>  extern const struct drm_bridge_funcs mtk_mt8183_hdmi_bridge_funcs;
>  void mtk_hdmi_output_init_mt8183(struct mtk_hdmi *hdmi);
> +void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi);
> +void mtk_hdmi_clk_disable_mt8195(struct mtk_hdmi *hdmi);
>  void mtk_hdmi_clk_disable_mt8183(struct mtk_hdmi *hdmi);
> +void set_hdmi_codec_pdata_mt8195(struct hdmi_codec_pdata
> *codec_data);
>  void set_hdmi_codec_pdata_mt8183(struct hdmi_codec_pdata
> *codec_data);
>  
>  #endif //_MTK_HDMI_COMMON_H
> diff --git a/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
> b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
> new file mode 100644
> index 000000000000..3fa928b79ed2
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
> @@ -0,0 +1,1835 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 MediaTek Inc.
> + * Copyright (c) 2021 BayLibre, SAS
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/clk.h>
> +#include <linux/clk-provider.h>
> +#include <linux/delay.h>
> +#include <linux/debugfs.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of_platform.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_gpio.h>
> +#include <linux/of_graph.h>
> +#include <linux/pm_wakeup.h>
> +#include <linux/timer.h>
> +
> +#include <drm/drm_displayid.h>
> +#include <drm/drm_edid.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_probe_helper.h>
> +#include <drm/drm_scdc_helper.h>
> +
> +#include "mtk_drm_crtc.h"
> +#include "mtk_mt8195_hdmi.h"
> +#include "mtk_hdmi_common.h"
> +#include "mtk_mt8195_hdmi_ddc.h"
> +#include "mtk_mt8195_hdmi_regs.h"
> +
> +#define RGB444_8bit BIT(0)
> +#define RGB444_10bit BIT(1)
> +#define RGB444_12bit BIT(2)
> +#define RGB444_16bit BIT(3)
> +
> +#define YCBCR444_8bit BIT(4)
> +#define YCBCR444_10bit BIT(5)
> +#define YCBCR444_12bit BIT(6)
> +#define YCBCR444_16bit BIT(7)
> +
> +#define YCBCR422_8bit_NO_SUPPORT BIT(8)
> +#define YCBCR422_10bit_NO_SUPPORT BIT(9)
> +#define YCBCR422_12bit BIT(10)
> +#define YCBCR422_16bit_NO_SUPPORT BIT(11)
> +
> +#define YCBCR420_8bit BIT(12)
> +#define YCBCR420_10bit BIT(13)
> +#define YCBCR420_12bit BIT(14)
> +#define YCBCR420_16bit BIT(15)
> +
> +#define BYTES_TO_UINT32(msb, b1, b2,
> lsb)                                      \
> +	(((msb & 0xff) << 24) + ((b1 & 0xff) << 16) + ((b2 & 0xff) <<
> 8) +     \
> +	 ((lsb & 0xff)))
> +
> +static inline struct mtk_hdmi *hdmi_ctx_from_conn(struct
> drm_connector *c)
> +{
> +	return container_of(c, struct mtk_hdmi, conn);
> +}
> +
> +static inline void mtk_hdmi_clr_all_int_status(struct mtk_hdmi
> *hdmi)
> +{
> +	/*clear all tx irq*/
> +	mtk_hdmi_write(hdmi, TOP_INT_CLR00, 0xffffffff);
> +	mtk_hdmi_write(hdmi, TOP_INT_CLR00, 0x00000000);
> +	mtk_hdmi_write(hdmi, TOP_INT_CLR01, 0xffffffff);
> +	mtk_hdmi_write(hdmi, TOP_INT_CLR01, 0x00000000);
> +}
> +
> +static inline void mtk_hdmi_disable_all_int(struct mtk_hdmi *hdmi)
> +{
> +	/*disable all tx irq*/
> +	mtk_hdmi_write(hdmi, TOP_INT_MASK00, 0x00000000);
> +	mtk_hdmi_write(hdmi, TOP_INT_MASK01, 0x00000000);
> +}
> +
> +static inline void mtk_hdmi_en_hdcp_reauth_int(struct mtk_hdmi
> *hdmi,
> +					       bool enable)
> +{
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, TOP_INT_MASK00,
> +			      HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK,
> +			      HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_INT_MASK00,
> +			      HDCP2X_RX_REAUTH_REQ_DDCM_INT_MASK,
> +			      HDCP2X_RX_REAUTH_REQ_DDCM_INT_UNMASK);
> +}
> +
> +static inline void mtk_hdmi_enable_hpd_pord_irq(struct mtk_hdmi
> *hdmi,
> +						bool enable)
> +{
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, TOP_INT_MASK00, 0x0000000f,
> 0x0000000f);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_INT_MASK00, 0x00000000,
> 0x0000000f);
> +}
> +
> +static inline void mtk_hdmi_clr_htplg_pord_irq(struct mtk_hdmi
> *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, TOP_INT_CLR00, 0x0000000f, 0x0000000f);
> +	mtk_hdmi_mask(hdmi, TOP_INT_CLR00, 0x00000000, 0x0000000f);
> +}
> +
> +static inline void mtk_hdmi_set_sw_hpd(struct mtk_hdmi *hdmi, bool
> high)
> +{
> +	if (high)
> +		mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x1 <<
> HDMITX_SW_HPD_SHIFT,
> +			      HDMITX_SW_HPD);
> +	else
> +		mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0 <<
> HDMITX_SW_HPD_SHIFT,
> +			      HDMITX_SW_HPD);
> +}
> +
> +static inline void mtk_hdmi_force_hdcp_hpd(struct mtk_hdmi *hdmi)
> +{
> +	/* force HDCP HPD to 1*/
> +	mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, HDCP2X_HPD_OVR,
> HDCP2X_HPD_OVR);
> +	mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, HDCP2X_HPD_SW,
> HDCP2X_HPD_SW);
> +}
> +
> +static void mtk_hdmi_disable_hdcp_encrypt(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, HDCP2X_CTRL_0, 0x0 <<
> HDCP2X_ENCRYPT_EN_SHIFT,
> +		      HDCP2X_ENCRYPT_EN);
> +	mtk_hdmi_mask(hdmi, HDCP1X_CTRL, 0x0 << HDCP1X_ENC_EN_SHIFT,
> +		      HDCP1X_ENC_EN);
> +}
> +
> +static void mtk_hdmi_yuv420_downsample(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	if (enable) {
> +		mtk_hdmi_mask(hdmi, HDMITX_CONFIG,
> +			      HDMI_YUV420_MODE | HDMITX_SW_HPD,
> +			      HDMI_YUV420_MODE | HDMITX_SW_HPD);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG,
> +			      C444_C422_CONFIG_ENABLE,
> C444_C422_CONFIG_ENABLE);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG,
> +			      C422_C420_CONFIG_ENABLE,
> C422_C420_CONFIG_ENABLE);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0,
> +			      C422_C420_CONFIG_BYPASS);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG,
> +			      C422_C420_CONFIG_OUT_CB_OR_CR,
> +			      C422_C420_CONFIG_OUT_CB_OR_CR);
> +		mtk_hdmi_mask(hdmi, VID_OUT_FORMAT,
> +			      OUTPUT_FORMAT_DEMUX_420_ENABLE,
> +			      OUTPUT_FORMAT_DEMUX_420_ENABLE);
> +	} else {
> +		mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0 | HDMITX_SW_HPD,
> +			      HDMI_YUV420_MODE | HDMITX_SW_HPD);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0,
> +			      C444_C422_CONFIG_ENABLE);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0,
> +			      C422_C420_CONFIG_ENABLE);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG,
> +			      C422_C420_CONFIG_BYPASS,
> C422_C420_CONFIG_BYPASS);
> +		mtk_hdmi_mask(hdmi, VID_DOWNSAMPLE_CONFIG, 0,
> +			      C422_C420_CONFIG_OUT_CB_OR_CR);
> +		mtk_hdmi_mask(hdmi, VID_OUT_FORMAT, 0,
> +			      OUTPUT_FORMAT_DEMUX_420_ENABLE);
> +	}
> +}
> +
> +static bool mtk_hdmi_tmds_over_340M(struct mtk_hdmi *hdmi)
> +{
> +	unsigned long pixel_clk, tmds_clk;
> +
> +	pixel_clk = hdmi->mode.clock * 1000;
> +
> +	/* TMDS clk frequency */
> +	if (hdmi->color_depth == HDMI_8_BIT)
> +		tmds_clk = pixel_clk;
> +	else if (hdmi->color_depth == HDMI_10_BIT)
> +		tmds_clk = pixel_clk * 5 / 4;
> +	else if (hdmi->color_depth == HDMI_12_BIT)
> +		tmds_clk = pixel_clk * 3 / 2;
> +	else if (hdmi->color_depth == HDMI_16_BIT)
> +		tmds_clk = pixel_clk * 2;
> +	else
> +		return -EINVAL;
> +
> +	if (tmds_clk >= 340000000 && hdmi->csp !=
> HDMI_COLORSPACE_YUV420)
> +		return true;
> +
> +	return false;
> +}
> +
> +static inline void mtk_hdmi_enable_scrambling(struct mtk_hdmi *hdmi,
> +					      bool enable)
> +{
> +	usleep_range(100, 150);
> +
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, TOP_CFG00, SCR_ON | HDMI2_ON,
> +			      SCR_ON | HDMI2_ON);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_CFG00, SCR_OFF | HDMI2_OFF,
> +			      SCR_ON | HDMI2_ON);
> +}
> +
> +static void mtk_hdmi_hw_vid_black(struct mtk_hdmi *hdmi, bool black)
> +{
> +	if (black)
> +		mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, REG_VMUTE_EN,
> REG_VMUTE_EN);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_VMUTE_CFG1, 0, REG_VMUTE_EN);
> +}
> +
> +static void mtk_hdmi_hw_aud_mute(struct mtk_hdmi *hdmi)
> +{
> +	if (mtk_hdmi_read(hdmi, AIP_CTRL) & DSD_EN)
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL,
> +			      DSD_MUTE_DATA | AUD_MUTE_FIFO_EN,
> +			      DSD_MUTE_DATA | AUD_MUTE_FIFO_EN);
> +	else
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_FIFO_EN,
> +			      AUD_MUTE_FIFO_EN);
> +}
> +
> +static void mtk_hdmi_hw_aud_unmute(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_MUTE_DIS,
> AUD_MUTE_FIFO_EN);
> +}
> +
> +static void mtk_hdmi_hw_reset(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x0 << HDMITX_SW_RSTB_SHIFT,
> +		      HDMITX_SW_RSTB);
> +	usleep_range(1, 5);
> +	mtk_hdmi_mask(hdmi, HDMITX_CONFIG, 0x1 << HDMITX_SW_RSTB_SHIFT,
> +		      HDMITX_SW_RSTB);
> +}
> +
> +static void mtk_hdmi_enable_hdmi_mode(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, TOP_CFG00, HDMI_MODE_HDMI,
> HDMI_MODE_HDMI);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_CFG00, HDMI_MODE_DVI,
> HDMI_MODE_HDMI);
> +}
> +
> +static bool mtk_hdmi_sink_is_hdmi_device(struct mtk_hdmi *hdmi)
> +{
> +	if (hdmi->dvi_mode)
> +		return false;
> +	else
> +		return true;
> +}
> +
> +static void mtk_hdmi_set_deep_color(struct mtk_hdmi *hdmi, bool
> is_hdmi_sink)
> +{
> +	unsigned int deep_color = 0;
> +
> +	/* ycbcr422 12bit no deep color */
> +	if (hdmi->csp == HDMI_COLORSPACE_YUV422) {
> +		deep_color = DEEPCOLOR_MODE_8BIT;
> +	} else {
> +		switch (hdmi->color_depth) {
> +		case HDMI_8_BIT:
> +			deep_color = DEEPCOLOR_MODE_8BIT;
> +			break;
> +		case HDMI_10_BIT:
> +			deep_color = DEEPCOLOR_MODE_10BIT;
> +			break;
> +		case HDMI_12_BIT:
> +			deep_color = DEEPCOLOR_MODE_12BIT;
> +			break;
> +		case HDMI_16_BIT:
> +			deep_color = DEEPCOLOR_MODE_16BIT;
> +			break;
> +		default:
> +			WARN(1, "Unssupported color depth %d\n",
> +			     hdmi->color_depth);
> +		}
> +	}
> +
> +	mtk_hdmi_mask(hdmi, TOP_CFG00, deep_color,
> DEEPCOLOR_MODE_MASKBIT);
> +
> +	/* GCP */
> +	mtk_hdmi_mask(hdmi, TOP_CFG00, 0, DEEPCOLOR_PAT_EN);
> +	if (is_hdmi_sink && deep_color != DEEPCOLOR_MODE_8BIT)
> +		mtk_hdmi_mask(hdmi, TOP_MISC_CTLR, DEEP_COLOR_ADD,
> +			      DEEP_COLOR_ADD);
> +	else
> +		mtk_hdmi_mask(hdmi, TOP_MISC_CTLR, 0, DEEP_COLOR_ADD);
> +}
> +
> +static void mtk_hdmi_hw_audio_infoframe(struct mtk_hdmi *hdmi, u8
> *buffer,
> +					u8 len)
> +{
> +	enum hdmi_infoframe_type frame_type;
> +	u8 frame_ver;
> +	u8 frame_len;
> +	u8 checksum;
> +
> +	frame_type = buffer[0];
> +	frame_ver = buffer[1];
> +	frame_len = buffer[2];
> +	checksum = buffer[3];
> +
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, AUD_DIS_WR | AUD_DIS,
> +		      AUD_EN_WR | AUD_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AUD_RPT_DIS, AUD_RPT_EN);
> +
> +	mtk_hdmi_write(hdmi, TOP_AIF_HEADER,
> +		       BYTES_TO_UINT32(0, frame_len, frame_ver,
> frame_type));
> +	mtk_hdmi_write(hdmi, TOP_AIF_PKT00,
> +		       BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4],
> +				       buffer[3]));
> +	mtk_hdmi_write(hdmi, TOP_AIF_PKT01,
> +		       BYTES_TO_UINT32(0, 0, buffer[8], buffer[7]));
> +	mtk_hdmi_write(hdmi, TOP_AIF_PKT02, 0);
> +	mtk_hdmi_write(hdmi, TOP_AIF_PKT03, 0);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AUD_RPT_EN, AUD_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, AUD_EN_WR | AUD_EN,
> +		      AUD_EN_WR | AUD_EN);
> +}
> +
> +static void mtk_hdmi_hw_avi_infoframe(struct mtk_hdmi *hdmi, u8
> *buffer, u8 len)
> +{
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, AVI_DIS_WR | AVI_DIS,
> +		      AVI_EN_WR | AVI_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AVI_RPT_DIS, AVI_RPT_EN);
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_HEADER,
> +		       BYTES_TO_UINT32(0, buffer[2], buffer[1],
> buffer[0]));
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT00,
> +		       BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4],
> +				       buffer[3]));
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT01,
> +		       BYTES_TO_UINT32(0, buffer[9], buffer[8],
> buffer[7]));
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT02,
> +		       BYTES_TO_UINT32(buffer[13], buffer[12],
> buffer[11],
> +				       buffer[10]));
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT03,
> +		       BYTES_TO_UINT32(0, buffer[16], buffer[15],
> buffer[14]));
> +
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT04, 0);
> +	mtk_hdmi_write(hdmi, TOP_AVI_PKT05, 0);
> +
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, AVI_RPT_EN, AVI_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, AVI_EN_WR | AVI_EN,
> +		      AVI_EN_WR | AVI_EN);
> +}
> +
> +static void mtk_hdmi_hw_spd_infoframe(struct mtk_hdmi *hdmi, u8
> *buffer, u8 len)
> +{
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, SPD_DIS_WR | SPD_DIS,
> +		      SPD_EN_WR | SPD_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, SPD_RPT_DIS, SPD_RPT_EN);
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_HEADER,
> +		       BYTES_TO_UINT32(0, buffer[2], buffer[1],
> buffer[0]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT00,
> +		       BYTES_TO_UINT32(buffer[6], buffer[5], buffer[4],
> +				       buffer[3]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT01,
> +		       BYTES_TO_UINT32(0, buffer[9], buffer[8],
> buffer[7]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT02,
> +		       BYTES_TO_UINT32(buffer[13], buffer[12],
> buffer[11],
> +				       buffer[10]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT03,
> +		       BYTES_TO_UINT32(0, buffer[16], buffer[15],
> buffer[14]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT04,
> +		       BYTES_TO_UINT32(buffer[20], buffer[19],
> buffer[18],
> +				       buffer[17]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT05,
> +		       BYTES_TO_UINT32(0, buffer[23], buffer[22],
> buffer[21]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT06,
> +		       BYTES_TO_UINT32(buffer[27], buffer[26],
> buffer[25],
> +				       buffer[24]));
> +
> +	mtk_hdmi_write(hdmi, TOP_SPDIF_PKT07,
> +		       BYTES_TO_UINT32(0, buffer[30], buffer[29],
> buffer[28]));
> +
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, SPD_RPT_EN, SPD_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, SPD_EN_WR | SPD_EN,
> +		      SPD_EN_WR | SPD_EN);
> +}
> +
> +static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi)
> +{
> +	struct hdmi_codec_params *params = &hdmi-
> >aud_param.codec_params;
> +	struct hdmi_audio_infoframe frame;
> +	u8 buffer[14];
> +	ssize_t err;
> +
> +	memcpy(&frame, &params->cea, sizeof(struct
> hdmi_audio_infoframe));
> +
> +	err = hdmi_audio_infoframe_pack(&frame, buffer,
> sizeof(buffer));
> +	if (err < 0)
> +		return err;
> +
> +	mtk_hdmi_hw_audio_infoframe(hdmi, buffer, sizeof(buffer));
> +	return 0;
> +}
> +
> +static void mtk_hdmi_hw_send_aud_packet(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0, AUD_PACKET_DROP);
> +	else
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, AUD_PACKET_DROP,
> +			      AUD_PACKET_DROP);
> +}
> +
> +static inline void mtk_hdmi_hw_send_av_mute(struct mtk_hdmi *hdmi)
> +{
> +	/*GCP packet */
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, 0, CP_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, 0, CP_EN | CP_EN_WR);
> +
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, CP_SET_MUTE_EN, CP_SET_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, CP_RPT_EN, CP_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, CP_EN | CP_EN_WR, CP_EN |
> CP_EN_WR);
> +}
> +
> +static inline void mtk_hdmi_hw_send_av_unmute(struct mtk_hdmi *hdmi)
> +{
> +	/*GCP packet */
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_CLR_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, 0, CP_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, 0, CP_EN | CP_EN_WR);
> +
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, CP_CLR_MUTE_EN, CP_CLR_MUTE_EN);
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, 0, CP_SET_MUTE_DIS);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_RPT, CP_RPT_EN, CP_RPT_EN);
> +	mtk_hdmi_mask(hdmi, TOP_INFO_EN, CP_EN | CP_EN_WR, CP_EN |
> CP_EN_WR);
> +}
> +
> +static void mtk_hdmi_hw_ncts_enable(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	unsigned int data;
> +
> +	data = mtk_hdmi_read(hdmi, AIP_CTRL);
> +
> +	if (enable)
> +		data |= CTS_SW_SEL;
> +	else
> +		data &= ~CTS_SW_SEL;
> +
> +	mtk_hdmi_write(hdmi, AIP_CTRL, data);
> +}
> +
> +static void mtk_hdmi_hw_aud_set_channel_status(struct mtk_hdmi
> *hdmi,
> +					       u8 *channel_status)
> +{
> +	/* actually, only the first 5 or 7 bytes of Channel Status
> +	 * contain useful information
> +	 */
> +	mtk_hdmi_write(hdmi, AIP_I2S_CHST0,
> +		       BYTES_TO_UINT32(channel_status[3],
> channel_status[2],
> +				       channel_status[1],
> channel_status[0]));
> +	mtk_hdmi_write(hdmi, AIP_I2S_CHST1,
> +		       BYTES_TO_UINT32(0, channel_status[6],
> channel_status[5],
> +				       channel_status[4]));
> +}
> +
> +struct hdmi_acr_n {
> +	unsigned int clock;
> +	unsigned int n[3];
> +};
> +
> +/* Recommended N values from HDMI specification, tables 7-1 to 7-3
> */
> +static const struct hdmi_acr_n hdmi_rec_n_table[] = {
> +	/* Clock, N: 32kHz 44.1kHz 48kHz */
> +	{ 25175, { 4576, 7007, 6864 } },
> +	{ 74176, { 11648, 17836, 11648 } },
> +	{ 148352, { 11648, 8918, 5824 } },
> +	{ 296703, { 5824, 4459, 5824 } },
> +	{ 297000, { 3072, 4704, 5120 } },
> +	{ 0, { 4096, 6272, 6144 } }, /* all other TMDS clocks */
> +};
> +
> +/**
> + * hdmi_recommended_n() - Return N value recommended by HDMI
> specification
> + * @freq: audio sample rate in Hz
> + * @clock: rounded TMDS clock in kHz
> + */
> +static int hdmi_recommended_n(unsigned int freq, unsigned int clock)
> +{
> +	const struct hdmi_acr_n *recommended;
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(hdmi_rec_n_table) - 1; i++) {
> +		if (clock == hdmi_rec_n_table[i].clock)
> +			break;
> +	}
> +
> +	if (i == ARRAY_SIZE(hdmi_rec_n_table))
> +		return -EINVAL;
> +
> +	recommended = hdmi_rec_n_table + i;
> +
> +	switch (freq) {
> +	case 32000:
> +		return recommended->n[0];
> +	case 44100:
> +		return recommended->n[1];
> +	case 48000:
> +		return recommended->n[2];
> +	case 88200:
> +		return recommended->n[1] * 2;
> +	case 96000:
> +		return recommended->n[2] * 2;
> +	case 176400:
> +		return recommended->n[1] * 4;
> +	case 192000:
> +		return recommended->n[2] * 4;
> +	default:
> +		return (128 * freq) / 1000;
> +	}
> +}
> +
> +static unsigned int hdmi_mode_clock_to_hz(unsigned int clock)
> +{
> +	switch (clock) {
> +	case 25175:
> +		return 25174825; /* 25.2/1.001 MHz */
> +	case 74176:
> +		return 74175824; /* 74.25/1.001 MHz */
> +	case 148352:
> +		return 148351648; /* 148.5/1.001 MHz */
> +	case 296703:
> +		return 296703297; /* 297/1.001 MHz */
> +	default:
> +		return clock * 1000;
> +	}
> +}
> +
> +static unsigned int hdmi_expected_cts(unsigned int
> audio_sample_rate,
> +				      unsigned int tmds_clock, unsigned
> int n)
> +{
> +	return
> DIV_ROUND_CLOSEST_ULL((u64)hdmi_mode_clock_to_hz(tmds_clock) * n,
> +				     128 * audio_sample_rate);
> +}
> +
> +static void mtk_hdmi_hw_aud_set_ncts(struct mtk_hdmi *hdmi,
> +				     unsigned int sample_rate,
> +				     unsigned int clock)
> +{
> +	unsigned int ncts;
> +	int n;
> +
> +	n = hdmi_recommended_n(sample_rate, clock);
> +
> +	if (n == -EINVAL) {
> +		DRM_ERROR("Invalid sample rate: %u\n", sample_rate);
> +		return;
> +	}
> +
> +	ncts = hdmi_expected_cts(sample_rate, clock, n);
> +	mtk_hdmi_write(hdmi, AIP_N_VAL, n);
> +	mtk_hdmi_write(hdmi, AIP_CTS_SVAL, ncts);
> +}
> +
> +static void mtk_hdmi_aud_enable_packet(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	mtk_hdmi_hw_send_aud_packet(hdmi, enable);
> +}
> +
> +static void mtk_hdmi_aud_on_off_hw_ncts(struct mtk_hdmi *hdmi, bool
> on)
> +{
> +	mtk_hdmi_hw_ncts_enable(hdmi, on);
> +}
> +
> +static void mtk_hdmi_audio_dsd_config(struct mtk_hdmi *hdmi,
> +				      unsigned char chnum, bool
> dsd_bypass)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_CTRL, DSD_EN, SPDIF_EN | DSD_EN |
> HBRA_ON);
> +	mtk_hdmi_mask(hdmi, AIP_TXCTRL, DSD_MUTE_DATA, DSD_MUTE_DATA);
> +	if (dsd_bypass)
> +		mtk_hdmi_write(hdmi, TOP_AUD_MAP, 0x75316420);
> +	else
> +		mtk_hdmi_write(hdmi, TOP_AUD_MAP, 0x04230150);
> +
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0, I2S2DSD_EN);
> +}
> +
> +static inline void mtk_hdmi_hw_i2s_fifo_map(struct mtk_hdmi *hdmi,
> +					    unsigned int fifo_mapping)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, fifo_mapping,
> +		      FIFO3_MAP | FIFO2_MAP | FIFO1_MAP | FIFO0_MAP);
> +}
> +
> +static inline void mtk_hdmi_hw_i2s_ch_number(struct mtk_hdmi *hdmi,
> +					     unsigned int chnum)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_CTRL, chnum << I2S_EN_SHIFT, I2S_EN);
> +}
> +
> +static void mtk_hdmi_hw_i2s_ch_mapping(struct mtk_hdmi *hdmi,
> +				       unsigned char chnum,
> +				       unsigned char mapping)
> +{
> +	unsigned int bdata;
> +
> +	switch (chnum) {
> +	case 2:
> +		bdata = 0x1;
> +		break;
> +	case 3:
> +		bdata = 0x3;
> +		break;
> +	case 6:
> +		if (mapping == 0x0E) {
> +			bdata = 0xf;
> +			break;
> +		}
> +		fallthrough;
> +	case 5:
> +		bdata = 0x7;
> +		break;
> +	case 7:
> +	case 8:
> +		bdata = 0xf;
> +		break;
> +	default:
> +		bdata = 0x1;
> +	}
> +
> +	mtk_hdmi_hw_i2s_fifo_map(hdmi, (MAP_SD3 << 6) | (MAP_SD2 << 4)
> |
> +					       (MAP_SD1 << 2) |
> (MAP_SD0 << 0));
> +	mtk_hdmi_hw_i2s_ch_number(hdmi, bdata);
> +
> +	if (chnum == 2)
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, LAYOUT0, LAYOUT1);
> +	else
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, LAYOUT1, LAYOUT1);
> +}
> +
> +static void mtk_hdmi_i2s_data_fmt(struct mtk_hdmi *hdmi, unsigned
> char fmt)
> +{
> +	unsigned int u4Data;
> +
> +	u4Data = mtk_hdmi_read(hdmi, AIP_I2S_CTRL);
> +	u4Data &= ~(WS_HIGH | I2S_1ST_BIT_NOSHIFT | JUSTIFY_RIGHT);
> +
> +	switch (fmt) {
> +	case HDMI_I2S_MODE_RJT_24BIT:
> +	case HDMI_I2S_MODE_RJT_16BIT:
> +		u4Data |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT |
> JUSTIFY_RIGHT);
> +		u4Data |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT |
> JUSTIFY_RIGHT);
> +		break;
> +
> +	case HDMI_I2S_MODE_LJT_24BIT:
> +	case HDMI_I2S_MODE_LJT_16BIT:
> +		u4Data |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT);
> +		u4Data |= (WS_HIGH | I2S_1ST_BIT_NOSHIFT);
> +		break;
> +
> +	case HDMI_I2S_MODE_I2S_24BIT:
> +	case HDMI_I2S_MODE_I2S_16BIT:
> +	default:
> +		break;
> +	}
> +	mtk_hdmi_write(hdmi, AIP_I2S_CTRL, u4Data);
> +}
> +
> +static inline void mtk_hdmi_i2s_sck_edge(struct mtk_hdmi *hdmi,
> +					 unsigned int edge)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, edge, SCK_EDGE_RISE);
> +}
> +
> +static inline void mtk_hdmi_i2s_cbit_order(struct mtk_hdmi *hdmi,
> +					   unsigned int cbit)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, cbit, CBIT_ORDER_SAME);
> +}
> +
> +static inline void mtk_hdmi_i2s_vbit(struct mtk_hdmi *hdmi, unsigned
> int vbit)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, vbit, VBIT_COM);
> +}
> +
> +static inline void mtk_hdmi_i2s_data_direction(struct mtk_hdmi
> *hdmi,
> +					       unsigned int data_dir)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_I2S_CTRL, data_dir, DATA_DIR_LSB);
> +}
> +
> +static inline void mtk_hdmi_hw_audio_type(struct mtk_hdmi *hdmi,
> +					  unsigned int spdif_i2s)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_CTRL, spdif_i2s << SPDIF_EN_SHIFT,
> SPDIF_EN);
> +}
> +
> +static unsigned char mtk_hdmi_get_i2s_ch_mapping(struct mtk_hdmi
> *hdmi,
> +						 unsigned char
> channel_type)
> +{
> +	unsigned char FC, LFE, RR, RL, RRC, RLC, RC;
> +	unsigned char ch_number = 0;
> +	unsigned char channelmap = 0x00;
> +
> +	switch (channel_type) {
> +	case HDMI_AUD_CHAN_TYPE_1_0:
> +	case HDMI_AUD_CHAN_TYPE_2_0:
> +		LFE = 0;
> +		ch_number = 2;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_1_1:
> +	case HDMI_AUD_CHAN_TYPE_2_1:
> +		LFE = 1;
> +		ch_number = 3;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_3_0:
> +		FC = 1;
> +		LFE = 0;
> +		ch_number = 3;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_3_0_LRS:
> +		RR = 1;
> +		RL = 1;
> +		LFE = 0;
> +		ch_number = 4;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_3_1_LRS:
> +		FC = 0;
> +		LFE = 1;
> +		RR = 1;
> +		RL = 1;
> +		ch_number = 5;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_4_0_CLRS:
> +		FC = 1;
> +		LFE = 0;
> +		RR = 1;
> +		RL = 1;
> +		ch_number = 5;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_4_1_CLRS:
> +		FC = 1;
> +		LFE = 1;
> +		RR = 1;
> +		RL = 1;
> +		ch_number = 6;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_3_1:
> +		FC = 1;
> +		LFE = 1;
> +		ch_number = 4;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_4_0:
> +		RR = 1;
> +		RL = 1;
> +		LFE = 0;
> +		ch_number = 4;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_4_1:
> +		RR = 1;
> +		RL = 1;
> +		LFE = 1;
> +		ch_number = 5;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_5_0:
> +		FC = 1;
> +		LFE = 0;
> +		RR = 1;
> +		RL = 1;
> +		ch_number = 5;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_5_1:
> +		FC = 1;
> +		LFE = 1;
> +		RR = 1;
> +		RL = 1;
> +		ch_number = 6;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_6_0:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CS:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CH:
> +	case HDMI_AUD_CHAN_TYPE_6_0_OH:
> +	case HDMI_AUD_CHAN_TYPE_6_0_CHR:
> +		FC = 1;
> +		LFE = 0;
> +		RR = 1;
> +		RL = 1;
> +		RC = 1;
> +		ch_number = 6;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_6_1:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CS:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CH:
> +	case HDMI_AUD_CHAN_TYPE_6_1_OH:
> +	case HDMI_AUD_CHAN_TYPE_6_1_CHR:
> +		FC = 1;
> +		LFE = 1;
> +		RR = 1;
> +		RL = 1;
> +		RC = 1;
> +		ch_number = 7;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_7_0:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LH_RH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LC_RC:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LW_RW:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSD_RSD:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LHS_RHS:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_CH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CS_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CH_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_0_CH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_OH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_0_LSS_RSS_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_8_0_LH_RH_CS:
> +		FC = 1;
> +		LFE = 0;
> +		RR = 1;
> +		RL = 1;
> +		RRC = 1;
> +		RLC = 1;
> +		ch_number = 7;
> +		break;
> +
> +	case HDMI_AUD_CHAN_TYPE_7_1:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LH_RH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSR_RSR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LC_RC:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LW_RW:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSD_RSD:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LHS_RHS:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_CH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CS_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CH_OH:
> +	case HDMI_AUD_CHAN_TYPE_7_1_CH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_OH_CHR:
> +	case HDMI_AUD_CHAN_TYPE_7_1_LSS_RSS_LSR_RSR:
> +		FC = 1;
> +		LFE = 1;
> +		RR = 1;
> +		RL = 1;
> +		RRC = 1;
> +		RLC = 1;
> +		ch_number = 8;
> +		break;
> +
> +	default:
> +		ch_number = 2;
> +		break;
> +	}
> +
> +	switch (ch_number) {
> +	case 8:
> +		break;
> +
> +	case 7:
> +		break;
> +
> +	case 6:
> +		if (FC == 1 && RR == 1 && RL == 1 && RC == 1 && LFE ==
> 0) {
> +			/* 6.0 */
> +			channelmap = 0x0E;
> +		} else if (FC == 1 && RR == 1 && RL == 1 && RC == 0 &&
> +			   LFE == 1) {
> +			/* 5.1 */
> +			channelmap = 0x0B;
> +		}
> +		break;
> +
> +	case 5:
> +		break;
> +
> +	case 4:
> +		if (RR == 1 && RL == 1 && LFE == 0)
> +			channelmap = 0x08;
> +		else if (FC == 1 && LFE == 1)
> +			channelmap = 0x03;
> +		break;
> +
> +	case 3:
> +		if (FC == 1)
> +			channelmap = 0x02;
> +		else if (LFE == 1)
> +			channelmap = 0x01;
> +		break;
> +
> +	case 2:
> +		channelmap = 0x00;
> +		break;
> +
> +	default:
> +		break;
> +	}
> +
> +	return channelmap;
> +}
> +
> +static inline void mtk_hdmi_hw_i2s_ch_swap(struct mtk_hdmi *hdmi,
> +					   unsigned char swapbit)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, swapbit << 20, 0x0F << 20);
> +}
> +
> +static void mtk_hdmi_hbr_config(struct mtk_hdmi *hdmi, bool
> dsd_bypass)
> +{
> +	if (dsd_bypass) {
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, HBRA_ON,
> +			      SPDIF_EN | DSD_EN | HBRA_ON);
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, I2S_EN, I2S_EN);
> +	} else {
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, SPDIF_EN,
> +			      SPDIF_EN | DSD_EN | HBRA_ON);
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, SPDIF_INTERNAL_MODULE,
> +			      SPDIF_INTERNAL_MODULE);
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, HBR_FROM_SPDIF,
> HBR_FROM_SPDIF);
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, CTS_CAL_N4, CTS_CAL_N4);
> +	}
> +}
> +
> +static inline void mtk_hdmi_hw_spdif_config(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, WR_1UI_UNLOCK,
> WR_1UI_LOCK);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, FS_UNOVERRIDE,
> FS_OVERRIDE_WRITE);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, WR_2UI_UNLOCK,
> WR_2UI_LOCK);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x4 << MAX_1UI_WRITE_SHIFT,
> +		      MAX_1UI_WRITE);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x9 << MAX_2UI_WRITE_SHIFT,
> +		      MAX_2UI_WRITE);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0x4 <<
> AUD_ERR_THRESH_SHIFT,
> +		      AUD_ERR_THRESH);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, I2S2DSD_EN, I2S2DSD_EN);
> +}
> +
> +static void mtk_hdmi_aud_set_input(struct mtk_hdmi *hdmi)
> +{
> +	unsigned char ChMapping;
> +
> +	mtk_hdmi_write(hdmi, TOP_AUD_MAP,
> +		       C_SD7 + C_SD6 + C_SD5 + C_SD4 + C_SD3 + C_SD2 +
> C_SD1 +
> +			       C_SD0);
> +	mtk_hdmi_mask(hdmi, AIP_SPDIF_CTRL, 0, 0x0F << 20);
> +	mtk_hdmi_mask(hdmi, AIP_CTRL, 0,
> +		      SPDIF_EN | DSD_EN | HBRA_ON | CTS_CAL_N4 |
> +			      HBR_FROM_SPDIF | SPDIF_INTERNAL_MODULE);
> +	mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0, DSD_MUTE_DATA | LAYOUT1);
> +
> +	if (hdmi->aud_param.aud_input_type == HDMI_AUD_INPUT_I2S) {
> +		if (hdmi->aud_param.aud_codec ==
> HDMI_AUDIO_CODING_TYPE_DSD) {
> +			mtk_hdmi_audio_dsd_config(
> +				hdmi, hdmi-
> >aud_param.codec_params.channels,
> +				0);
> +			mtk_hdmi_hw_i2s_ch_mapping(
> +				hdmi, hdmi-
> >aud_param.codec_params.channels,
> +				1);
> +		} else {
> +			mtk_hdmi_i2s_data_fmt(hdmi,
> +					      hdmi-
> >aud_param.aud_i2s_fmt);
> +			mtk_hdmi_i2s_sck_edge(hdmi, SCK_EDGE_RISE);
> +			mtk_hdmi_i2s_cbit_order(hdmi, CBIT_ORDER_SAME);
> +			mtk_hdmi_i2s_vbit(hdmi, VBIT_PCM);
> +			mtk_hdmi_i2s_data_direction(hdmi,
> DATA_DIR_MSB);
> +			mtk_hdmi_hw_audio_type(hdmi,
> HDMI_AUD_INPUT_I2S);
> +			ChMapping = mtk_hdmi_get_i2s_ch_mapping(
> +				hdmi, hdmi-
> >aud_param.aud_input_chan_type);
> +			mtk_hdmi_hw_i2s_ch_mapping(
> +				hdmi, hdmi-
> >aud_param.codec_params.channels,
> +				ChMapping);
> +			mtk_hdmi_hw_i2s_ch_swap(hdmi, LFE_CC_SWAP);
> +		}
> +	} else {
> +		if (hdmi->aud_param.aud_input_type ==
> HDMI_AUD_INPUT_SPDIF &&
> +		    (hdmi->aud_param.aud_codec ==
> +		      HDMI_AUDIO_CODING_TYPE_DTS_HD ||
> +		     hdmi->aud_param.aud_codec ==
> +		      HDMI_AUDIO_CODING_TYPE_MLP) &&
> +		    hdmi->aud_param.codec_params.sample_rate == 768000)
> {
> +			mtk_hdmi_hbr_config(hdmi, false);
> +		} else {
> +			mtk_hdmi_hw_spdif_config(hdmi);
> +			mtk_hdmi_hw_i2s_ch_mapping(hdmi, 2, 0);
> +		}
> +	}
> +}
> +
> +static void mtk_hdmi_aud_set_sw_ncts(struct mtk_hdmi *hdmi,
> +				     struct drm_display_mode
> *display_mode)
> +{
> +	unsigned int sample_rate = hdmi-
> >aud_param.codec_params.sample_rate;
> +
> +	mtk_hdmi_aud_on_off_hw_ncts(hdmi, false);
> +
> +	mtk_hdmi_hw_aud_set_ncts(hdmi, sample_rate, display_mode-
> >clock);
> +}
> +
> +static inline void mtk_hdmi_hw_audio_input_enable(struct mtk_hdmi
> *hdmi,
> +						  unsigned int enable)
> +{
> +	if (enable)
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, AUD_IN_EN, AUD_IN_EN);
> +	else
> +		mtk_hdmi_mask(hdmi, AIP_CTRL, 0x0 << AUD_IN_EN_SHIFT,
> +			      AUD_IN_EN);
> +}
> +
> +static void mtk_hdmi_aip_ctrl_init(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_mask(hdmi, AIP_CTRL,
> +		      AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | CTS_REQ_EN,
> +		      AUD_SEL_OWRT | NO_MCLK_CTSGEN_SEL | MCLK_EN |
> CTS_REQ_EN);
> +	mtk_hdmi_mask(hdmi, AIP_TPI_CTRL, TPI_AUDIO_LOOKUP_DIS,
> +		      TPI_AUDIO_LOOKUP_EN);
> +}
> +
> +static void mtk_hdmi_audio_reset(struct mtk_hdmi *hdmi, bool rst)
> +{
> +	if (rst)
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL,
> +			      RST4AUDIO | RST4AUDIO_FIFO |
> RST4AUDIO_ACR,
> +			      RST4AUDIO | RST4AUDIO_FIFO |
> RST4AUDIO_ACR);
> +	else
> +		mtk_hdmi_mask(hdmi, AIP_TXCTRL, 0,
> +			      RST4AUDIO | RST4AUDIO_FIFO |
> RST4AUDIO_ACR);
> +}
> +
> +static void mtk_hdmi_aud_output_config(struct mtk_hdmi *hdmi,
> +				       struct drm_display_mode
> *display_mode)
> +{
> +	mtk_hdmi_hw_aud_mute(hdmi);
> +	mtk_hdmi_aud_enable_packet(hdmi, false);
> +	mtk_hdmi_audio_reset(hdmi, true);
> +	mtk_hdmi_aip_ctrl_init(hdmi);
> +
> +	mtk_hdmi_aud_set_input(hdmi);
> +
> +	mtk_hdmi_hw_aud_set_channel_status(
> +		hdmi, hdmi->aud_param.codec_params.iec.status);
> +
> +	mtk_hdmi_setup_audio_infoframe(hdmi);
> +
> +	mtk_hdmi_hw_audio_input_enable(hdmi, true);
> +
> +	mtk_hdmi_audio_reset(hdmi, false);
> +
> +	mtk_hdmi_aud_set_sw_ncts(hdmi, display_mode);
> +
> +	usleep_range(25, 50);
> +	mtk_hdmi_aud_on_off_hw_ncts(hdmi, true);
> +
> +	mtk_hdmi_aud_enable_packet(hdmi, true);
> +	mtk_hdmi_hw_aud_unmute(hdmi);
> +}
> +
> +void mtk_hdmi_output_init_mt8195(struct mtk_hdmi *hdmi)
> +{
> +	struct hdmi_audio_param *aud_param = &hdmi->aud_param;
> +
> +	aud_param->aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
> +	aud_param->aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
> +	aud_param->aud_input_type = HDMI_AUD_INPUT_I2S;
> +	aud_param->aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
> +	aud_param->aud_mclk = HDMI_AUD_MCLK_128FS;
> +	aud_param->aud_input_chan_type = HDMI_AUD_CHAN_TYPE_2_0;
> +
> +	hdmi->hpd = HDMI_PLUG_OUT;
> +	hdmi->set_csp_depth = RGB444_8bit;
> +	hdmi->csp = HDMI_COLORSPACE_RGB;
> +	hdmi->color_depth = HDMI_8_BIT;
> +	hdmi->colorimtery = HDMI_COLORIMETRY_NONE;
> +	hdmi->extended_colorimetry =
> HDMI_EXTENDED_COLORIMETRY_RESERVED;
> +	hdmi->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
> +	hdmi->ycc_quantization_range =
> HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> +}
> +
> +static void mtk_hdmi_reset_colorspace_setting(struct mtk_hdmi *hdmi)
> +{
> +	hdmi->set_csp_depth = RGB444_8bit;
> +	hdmi->csp = HDMI_COLORSPACE_RGB;
> +	hdmi->color_depth = HDMI_8_BIT;
> +	hdmi->colorimtery = HDMI_COLORIMETRY_NONE;
> +	hdmi->extended_colorimetry =
> HDMI_EXTENDED_COLORIMETRY_RESERVED;
> +	hdmi->quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
> +	hdmi->ycc_quantization_range =
> HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> +}
> +
> +static void mtk_hdmi_audio_enable(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_aud_enable_packet(hdmi, true);
> +	hdmi->audio_enable = true;
> +}
> +
> +static void mtk_hdmi_audio_disable(struct mtk_hdmi *hdmi)
> +{
> +	mtk_hdmi_aud_enable_packet(hdmi, false);
> +	hdmi->audio_enable = false;
> +}
> +
> +static void mtk_hdmi_audio_set_param(struct mtk_hdmi *hdmi,
> +				     struct hdmi_audio_param *param)
> +{
> +	if (!hdmi->audio_enable)
> +		return;
> +
> +	memcpy(&hdmi->aud_param, param, sizeof(*param));
> +	mtk_hdmi_aud_output_config(hdmi, &hdmi->mode);
> +}
> +
> +static void mtk_hdmi_change_video_resolution(struct mtk_hdmi *hdmi)
> +{
> +	bool is_over_340M = false;
> +	bool is_hdmi_sink = false;
> +
> +	mtk_hdmi_hw_reset(hdmi);
> +	mtk_hdmi_set_sw_hpd(hdmi, true);
> +	usleep_range(2, 5);
> +
> +	mtk_hdmi_write(hdmi, HDCP_TOP_CTRL, 0x0);
> +	mtk_hdmi_en_hdcp_reauth_int(hdmi, true);
> +	mtk_hdmi_enable_hpd_pord_irq(hdmi, true);
> +	mtk_hdmi_force_hdcp_hpd(hdmi);
> +
> +	is_hdmi_sink = mtk_hdmi_sink_is_hdmi_device(hdmi);
> +	mtk_hdmi_set_deep_color(hdmi, is_hdmi_sink);
> +	mtk_hdmi_enable_hdmi_mode(hdmi, is_hdmi_sink);
> +
> +	usleep_range(5, 10);
> +	mtk_hdmi_hw_vid_black(hdmi, true);
> +	mtk_hdmi_hw_aud_mute(hdmi);
> +	mtk_hdmi_hw_send_av_unmute(hdmi);
> +
> +	mtk_hdmi_mask(hdmi, TOP_CFG01, NULL_PKT_VSYNC_HIGH_EN,
> +		      NULL_PKT_VSYNC_HIGH_EN | NULL_PKT_EN);
> +
> +	is_over_340M = mtk_hdmi_tmds_over_340M(hdmi);
> +	mtk_hdmi_enable_scrambling(hdmi, is_over_340M);
> +
> +	if (hdmi->csp == HDMI_COLORSPACE_YUV420)
> +		mtk_hdmi_yuv420_downsample(hdmi, true);
> +	else
> +		mtk_hdmi_yuv420_downsample(hdmi, false);
> +}
> +
> +static void mtk_hdmi_output_set_display_mode(struct mtk_hdmi *hdmi,
> +					     struct drm_display_mode
> *mode)
> +{

Try to implement this function like the one in mt8173 hdmi driver. That
means the callee function and the callee function of callee function.
So I would compare the difference of mt8173 and mt8195.

> +	mtk_hdmi_change_video_resolution(hdmi);
> +	mtk_hdmi_aud_output_config(hdmi, mode);
> +}
> +
> +static void mtk_hdmi_clk_enable(struct mtk_hdmi *hdmi)
> +{
> +	int i;
> +
> +	clk_set_parent(hdmi->clk[MTK_MT8195_HDIM_HDCP_SEL],
> +		       hdmi->clk[MTK_MT8195_HDMI_UNIVPLL_D4D8]);
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names_mt8195); i++) {
> +		if (i == MTK_MT8195_HDMI_UNIVPLL_D4D8 ||
> +		    i == MTK_MT8195_HDMI_CLK_UNIVPLL_D6D4 ||
> +		    i == MTK_MT8195_HDMI_CLK_MSDCPLL_D2 ||
> +		    i == MTK_MT8195_HDMI_CLK_HDMI_APB_SEL)
> +			continue;
> +		else
> +			clk_prepare_enable(hdmi->clk[i]);
> +	}
> +}
> +
> +void mtk_hdmi_clk_disable_mt8195(struct mtk_hdmi *hdmi)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(mtk_hdmi_clk_names_mt8195); i++) {
> +		if (i == MTK_MT8195_HDMI_UNIVPLL_D4D8 ||
> +		    i == MTK_MT8195_HDMI_CLK_UNIVPLL_D6D4 ||
> +		    i == MTK_MT8195_HDMI_CLK_MSDCPLL_D2 ||
> +		    i == MTK_MT8195_HDMI_CLK_HDMI_APB_SEL)
> +			continue;
> +		else
> +			clk_disable_unprepare(hdmi->clk[i]);
> +	}
> +}
> +
> +static void mtk_hdmi_hpd_event(enum hdmi_hpd_state hpd, struct
> device *dev)
> +{
> +	struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
> +
> +	if (hdmi && hdmi->bridge.encoder && hdmi->bridge.encoder->dev)
> +		drm_helper_hpd_irq_event(hdmi->bridge.encoder->dev);
> +}
> +
> +static enum hdmi_hpd_state mtk_hdmi_hpd_pord_status(struct mtk_hdmi
> *hdmi)
> +{
> +	unsigned int hpd_status;
> +
> +	hpd_status = mtk_hdmi_read(hdmi, HPD_DDC_STATUS);
> +	if ((hpd_status & (HPD_PIN_STA | PORD_PIN_STA)) ==
> +	    (HPD_PIN_STA | PORD_PIN_STA))
> +		return HDMI_PLUG_IN_AND_SINK_POWER_ON;
> +	else if ((hpd_status & (HPD_PIN_STA | PORD_PIN_STA)) ==
> PORD_PIN_STA)
> +		return HDMI_PLUG_IN_ONLY;
> +	else
> +		return HDMI_PLUG_OUT;
> +}
> +
> +static irqreturn_t mtk_hdmi_isr(int irq, void *arg)
> +{
> +	struct mtk_hdmi *hdmi = arg;
> +	unsigned int int_status;
> +	int ret = IRQ_HANDLED;
> +
> +	int_status = mtk_hdmi_read(hdmi, TOP_INT_STA00);
> +
> +	/* handle hpd interrupt */
> +	if (int_status & (PORD_F_INT_STA | PORD_R_INT_STA |
> HTPLG_F_INT_STA |
> +			  HTPLG_R_INT_STA)) {
> +		mtk_hdmi_enable_hpd_pord_irq(hdmi, false);
> +		mtk_hdmi_clr_htplg_pord_irq(hdmi);
> +		ret = IRQ_WAKE_THREAD;
> +	}
> +
> +	/*clear all tx irq*/
> +	mtk_hdmi_clr_all_int_status(hdmi);
> +
> +	return ret;
> +}
> +
> +static irqreturn_t mtk_hdmi_hpd_work_handle(int irq, void *arg)
> +{
> +	struct mtk_hdmi *hdmi = arg;
> +	enum hdmi_hpd_state hpd;
> +
> +	hpd = mtk_hdmi_hpd_pord_status(hdmi);
> +	if (hpd != hdmi->hpd) {
> +		hdmi->hpd = hpd;
> +		mtk_hdmi_hpd_event(hpd, hdmi->dev);
> +	}
> +
> +	mtk_hdmi_enable_hpd_pord_irq(hdmi, true);
> +	return IRQ_HANDLED;
> +}
> +
> +static enum drm_connector_status hdmi_conn_detect(struct
> drm_connector *conn,
> +						  bool force)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +
> +	if (hdmi->hpd != HDMI_PLUG_IN_AND_SINK_POWER_ON &&
> +	    hdmi->hpd != HDMI_PLUG_IN_ONLY) {
> +		hdmi->support_csp_depth = RGB444_8bit;
> +		hdmi->set_csp_depth = RGB444_8bit;
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_8_BIT;
> +		hdmi->colorimtery = HDMI_COLORIMETRY_NONE;
> +		hdmi->extended_colorimetry =
> HDMI_EXTENDED_COLORIMETRY_RESERVED;
> +		hdmi->quantization_range =
> HDMI_QUANTIZATION_RANGE_DEFAULT;
> +		hdmi->ycc_quantization_range =
> +			HDMI_YCC_QUANTIZATION_RANGE_LIMITED;
> +	}
> +
> +	return (hdmi->hpd != HDMI_PLUG_OUT) ?
> connector_status_connected :
> +						    connector_status_di
> sconnected;
> +}
> +
> +static void hdmi_conn_destroy(struct drm_connector *conn)
> +{
> +	drm_connector_cleanup(conn);
> +}
> +
> +static int hdmi_conn_atomic_set_property(struct drm_connector *conn,
> +					 struct drm_connector_state
> *state,
> +					 struct drm_property *property,
> +					 uint64_t val)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +	int ret = 0;
> +
> +	spin_lock(&hdmi->property_lock);
> +
> +	if (property == hdmi->csp_depth_prop) {
> +		if (val & hdmi->support_csp_depth)
> +			hdmi->set_csp_depth = val;
> +		else
> +			ret = -EINVAL;
> +	} else {
> +		ret = -EINVAL;
> +	}
> +
> +	spin_unlock(&hdmi->property_lock);
> +	return ret;
> +}
> +
> +static int
> +hdmi_conn_atomic_get_property(struct drm_connector *conn,
> +			      const struct drm_connector_state *state,
> +			      struct drm_property *property, uint64_t
> *val)
> +{
> +	int ret = -EINVAL;
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +
> +	spin_lock(&hdmi->property_lock);
> +
> +	if (property == hdmi->csp_depth_prop) {
> +		*val = hdmi->support_csp_depth;
> +		ret = 0;
> +	}
> +
> +	spin_unlock(&hdmi->property_lock);
> +	return ret;
> +}
> +
> +static int mtk_hdmi_enable_disable(struct mtk_hdmi *hdmi, bool
> enable)
> +{
> +	int ret;
> +
> +	if (enable && !hdmi->hdmi_enabled) {
> +		if (!hdmi->power_clk_enabled) {
> +			/* power domain on */
> +			ret = pm_runtime_get_sync(hdmi->dev);
> +
> +			/* clk on */
> +			mtk_hdmi_clk_enable(hdmi);
> +			hdmi->power_clk_enabled = true;
> +		}
> +
> +		if (!hdmi->irq_registered) {
> +			/* disable all tx interrupts */
> +			mtk_hdmi_disable_all_int(hdmi);
> +			/* request irq */
> +			hdmi->hdmi_irq =
> +				irq_of_parse_and_map(hdmi->dev-
> >of_node, 0);
> +			ret = request_threaded_irq(hdmi->hdmi_irq,
> mtk_hdmi_isr,
> +						   mtk_hdmi_hpd_work_ha
> ndle,
> +						   IRQF_TRIGGER_HIGH,
> "hdmiirq",
> +						   hdmi);
> +			hdmi->irq_registered = true;
> +			/* enable hpd interrupt */
> +			mtk_hdmi_set_sw_hpd(hdmi, true);
> +			mtk_hdmi_enable_hpd_pord_irq(hdmi, true);
> +		}
> +
> +	} else if (!enable && hdmi->hdmi_enabled) {
> +		if (hdmi->irq_registered) {
> +			/* free irq */
> +			free_irq(hdmi->hdmi_irq, NULL);
> +			hdmi->irq_registered = false;
> +		}
> +
> +		if (hdmi->power_clk_enabled) {
> +			/* clk disable */
> +			mtk_hdmi_clk_disable_mt8195(hdmi);
> +			/* power domain off */
> +			ret = pm_runtime_put_sync(hdmi->dev);
> +			hdmi->power_clk_enabled = false;
> +		}
> +	}
> +
> +	hdmi->hdmi_enabled = enable;
> +
> +	return 0;
> +}
> +
> +static const struct drm_prop_enum_list csp_depth_props[] = {
> +	{ __builtin_ffs(RGB444_8bit), "RGB444_8bit" },
> +	{ __builtin_ffs(RGB444_10bit), "RGB444_10bit" },
> +	{ __builtin_ffs(RGB444_12bit), "RGB444_10bit" },
> +	{ __builtin_ffs(RGB444_16bit), "RGB444_16bit" },
> +	{ __builtin_ffs(YCBCR444_8bit), "YCBCR444_8bit" },
> +	{ __builtin_ffs(YCBCR444_10bit), "YCBCR444_10bit" },
> +	{ __builtin_ffs(YCBCR444_12bit), "YCBCR444_12bit" },
> +	{ __builtin_ffs(YCBCR444_16bit), "YCBCR444_16bit" },
> +	{ __builtin_ffs(YCBCR422_8bit_NO_SUPPORT),
> "YCBCR422_8bit_NO_SUPPORT" },
> +	{ __builtin_ffs(YCBCR422_10bit_NO_SUPPORT),
> +	  "YCBCR422_10bit_NO_SUPPORT" },
> +	{ __builtin_ffs(YCBCR422_12bit), "YCBCR422_12bit" },
> +	{ __builtin_ffs(YCBCR422_16bit_NO_SUPPORT),
> +	  "YCBCR422_16bit_NO_SUPPORT" },
> +	{ __builtin_ffs(YCBCR420_8bit), "YCBCR420_8bit" },
> +	{ __builtin_ffs(YCBCR420_10bit), "YCBCR420_10bit" },
> +	{ __builtin_ffs(YCBCR420_12bit), "YCBCR420_12bit" },
> +	{ __builtin_ffs(YCBCR420_16bit), "YCBCR420_16bit" },
> +};
> +
> +static void mtk_hdmi_connetor_init_property(struct drm_device
> *drm_dev,
> +					    struct drm_connector *conn)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +	struct drm_property *prop;
> +	/* ycbcr422 cannot support 8,10,16bit */
> +	unsigned int supported_csp_depth_mask =
> +		RGB444_8bit | RGB444_10bit | RGB444_12bit |
> RGB444_16bit |
> +		YCBCR444_8bit | YCBCR444_10bit | YCBCR444_12bit |
> +		YCBCR444_16bit | YCBCR422_12bit | YCBCR420_8bit |
> +		YCBCR420_10bit | YCBCR420_12bit | YCBCR420_16bit;
> +
> +	spin_lock_init(&hdmi->property_lock);
> +
> +	/* create colorspace_depth bitmask property */
> +	prop = drm_property_create_bitmask(
> +		conn->dev, 0, "hdmi_colorspace_depth", csp_depth_props,
> +		ARRAY_SIZE(csp_depth_props), supported_csp_depth_mask);
> +
> +	if (!prop)
> +		return;
> +
> +	hdmi->csp_depth_prop = prop;
> +	drm_object_attach_property(&conn->base, prop, 0);
> +
> +	/* create mtk_hdmi_blob property, include EDID parser info,
> +	 * such as max_tmds_clock_rate, max_tmds_character_rate,
> support dolby vision
> +	 */
> +	prop = drm_property_create(conn->dev,
> +				   DRM_MODE_PROP_BLOB |
> DRM_MODE_PROP_IMMUTABLE,
> +				   "HDMI_INFO", 0);
> +	if (!prop)
> +		return;
> +
> +	drm_object_attach_property(&conn->base, prop, 0);
> +}
> +
> +static void mtk_hdmi_convert_colorspace_depth(struct mtk_hdmi *hdmi)
> +{
> +	switch (hdmi->set_csp_depth) {
> +	case RGB444_8bit:
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_8_BIT;
> +		break;
> +	case RGB444_10bit:
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_10_BIT;
> +		break;
> +	case RGB444_12bit:
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_12_BIT;
> +		break;
> +	case RGB444_16bit:
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_16_BIT;
> +		break;
> +	case YCBCR444_8bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV444;
> +		hdmi->color_depth = HDMI_8_BIT;
> +		break;
> +	case YCBCR444_10bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV444;
> +		hdmi->color_depth = HDMI_10_BIT;
> +		break;
> +	case YCBCR444_12bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV444;
> +		hdmi->color_depth = HDMI_12_BIT;
> +		break;
> +	case YCBCR444_16bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV444;
> +		hdmi->color_depth = HDMI_16_BIT;
> +		break;
> +	case YCBCR422_12bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV422;
> +		hdmi->color_depth = HDMI_12_BIT;
> +		break;
> +	case YCBCR420_8bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV420;
> +		hdmi->color_depth = HDMI_8_BIT;
> +		break;
> +	case YCBCR420_10bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV420;
> +		hdmi->color_depth = HDMI_10_BIT;
> +		break;
> +	case YCBCR420_12bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV420;
> +		hdmi->color_depth = HDMI_12_BIT;
> +		break;
> +	case YCBCR420_16bit:
> +		hdmi->csp = HDMI_COLORSPACE_YUV420;
> +		hdmi->color_depth = HDMI_16_BIT;
> +		break;
> +	default:
> +
> +		hdmi->csp = HDMI_COLORSPACE_RGB;
> +		hdmi->color_depth = HDMI_8_BIT;
> +	}
> +}
> +
> +static int mtk_hdmi_conn_get_modes(struct drm_connector *conn)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +	struct edid *edid;
> +	int ret;
> +
> +	if (!hdmi->ddc_adpt)
> +		return -ENODEV;
> +
> +	edid = drm_get_edid(conn, hdmi->ddc_adpt);
> +	if (!edid)
> +		return -ENODEV;
> +
> +	hdmi->dvi_mode = !drm_detect_hdmi_monitor(edid);
> +
> +	drm_connector_update_edid_property(conn, edid);
> +
> +	ret = drm_add_edid_modes(conn, edid);
> +
> +	kfree(edid);
> +
> +	return ret;
> +}
> +
> +static int mtk_hdmi_conn_mode_valid(struct drm_connector *conn,
> +				    struct drm_display_mode *mode)
> +{
> +	if (mode->clock < 27000)
> +		return MODE_CLOCK_LOW;
> +	if (mode->clock > 594000)
> +		return MODE_CLOCK_HIGH;
> +
> +	return drm_mode_validate_size(mode, 0x1fff, 0x1fff);
> +}
> +
> +static struct drm_encoder *mtk_hdmi_conn_best_enc(struct
> drm_connector *conn)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
> +
> +	return hdmi->bridge.encoder;
> +}
> +
> +static const struct drm_connector_funcs mtk_hdmi_connector_funcs = {
> +	.detect = hdmi_conn_detect,
> +	.fill_modes = drm_helper_probe_single_connector_modes,
> +	.destroy = hdmi_conn_destroy,
> +	.reset = drm_atomic_helper_connector_reset,
> +	.atomic_duplicate_state =
> drm_atomic_helper_connector_duplicate_state,
> +	.atomic_destroy_state =
> drm_atomic_helper_connector_destroy_state,
> +	.atomic_set_property = hdmi_conn_atomic_set_property,
> +	.atomic_get_property = hdmi_conn_atomic_get_property,
> +};
> +
> +static const struct drm_connector_helper_funcs
> mtk_hdmi_connector_helper_funcs = {
> +	.get_modes = mtk_hdmi_conn_get_modes,
> +	.mode_valid = mtk_hdmi_conn_mode_valid,
> +	.best_encoder = mtk_hdmi_conn_best_enc,
> +};
> +
> +/*
> + * Bridge callbacks
> + */
> +
> +static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
> +				  enum drm_bridge_attach_flags flags)
> +{

This implementation like the old style in v4.8 [1], but I think you
should implement this as the new style [2].


[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/mediatek/mtk_hdmi.c?h=v4.8-rc1#n1297

[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/mediatek/mtk_hdmi.c?h=v5.17-rc1#n1283

> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	int ret;
> +
> +	ret = drm_connector_init(bridge->encoder->dev, &hdmi->conn,
> +				 &mtk_hdmi_connector_funcs,
> +				 DRM_MODE_CONNECTOR_HDMIA);
> +	if (ret)
> +		return ret;
> +
> +	drm_connector_helper_add(&hdmi->conn,
> &mtk_hdmi_connector_helper_funcs);
> +
> +	hdmi->conn.polled = DRM_CONNECTOR_POLL_HPD;
> +	hdmi->conn.interlace_allowed = false;
> +	hdmi->conn.doublescan_allowed = false;
> +	hdmi->conn.ycbcr_420_allowed = true;
> +
> +	ret = drm_connector_attach_encoder(&hdmi->conn, bridge-
> >encoder);
> +	if (ret)
> +		return ret;
> +
> +	mtk_hdmi_connetor_init_property(bridge->dev, &hdmi->conn);
> +
> +	pm_runtime_enable(hdmi->dev);
> +	mtk_hdmi_enable_disable(hdmi, true);
> +
> +	return 0;
> +}
> +
> +static void mtk_hdmi_bridge_disable(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	if (!hdmi->enabled)
> +		return;
> +
> +	mtk_hdmi_hw_send_av_mute(hdmi);
> +	usleep_range(50000, 50050);
> +	mtk_hdmi_hw_vid_black(hdmi, true);
> +	mtk_hdmi_hw_aud_mute(hdmi);
> +	mtk_hdmi_disable_hdcp_encrypt(hdmi);
> +	usleep_range(50000, 50050);
> +
> +	hdmi->enabled = false;
> +}
> +
> +static void mtk_hdmi_handle_plugged_change(struct mtk_hdmi *hdmi,
> bool plugged)
> +{
> +	if (hdmi->plugged_cb && hdmi->codec_dev)
> +		hdmi->plugged_cb(hdmi->codec_dev, plugged);
> +}
> +
> +static void mtk_hdmi_bridge_post_disable(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	if (!hdmi->powered)
> +		return;
> +
> +	phy_power_off(hdmi->phy);
> +
> +	hdmi->powered = false;
> +
> +	mtk_hdmi_reset_colorspace_setting(hdmi);
> +
> +	/* signal the disconnect event to audio codec */
> +	mtk_hdmi_handle_plugged_change(hdmi, false);
> +}
> +
> +static void mtk_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +	u8 buffer_spd[HDMI_INFOFRAME_HEADER_SIZE +
> HDMI_SPD_INFOFRAME_SIZE];
> +	u8 buffer_avi[HDMI_INFOFRAME_HEADER_SIZE +
> HDMI_AVI_INFOFRAME_SIZE];
> +	union phy_configure_opts opts = {
> +		.dp = { .link_rate = hdmi->mode.clock * 1000 }
> +	};
> +
> +	mtk_hdmi_convert_colorspace_depth(hdmi);
> +	mtk_hdmi_output_set_display_mode(hdmi, &hdmi->mode);
> +	phy_configure(hdmi->phy, &opts);

In mt8173 hdmi driver, it does not call phy_configure(), please add
comment for why do this.

> +	phy_power_on(hdmi->phy);
> +	mtk_hdmi_send_infoframe(hdmi, buffer_spd, sizeof(buffer_spd),
> buffer_avi, sizeof(buffer_avi), &hdmi->mode);

In mt8173 hdmi driver, send infoframe in
mtk_hdmi_bridge_atomic_enable(), try to move to that function. If can
not move, add comment for why can not move.

> +	mtk_hdmi_hw_spd_infoframe(hdmi, buffer_spd,
> sizeof(buffer_avi));
> +	mtk_hdmi_hw_avi_infoframe(hdmi, buffer_avi,
> sizeof(buffer_spd));
> +
> +	hdmi->powered = true;
> +}
> +
> +static void mtk_hdmi_bridge_enable(struct drm_bridge *bridge)
> +{
> +	struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
> +
> +	phy_power_on(hdmi->phy);
> +	mtk_hdmi_hw_vid_black(hdmi, false);
> +	mtk_hdmi_hw_aud_unmute(hdmi);
> +
> +	/* signal the connect event to audio codec */
> +	mtk_hdmi_handle_plugged_change(hdmi, true);

clk_prepare_enable() here.

> +
> +	hdmi->enabled = true;
> +}
> +
> +const struct drm_bridge_funcs mtk_mt8195_hdmi_bridge_funcs = {
> +	.attach = mtk_hdmi_bridge_attach,
> +	.mode_fixup = mtk_hdmi_bridge_mode_fixup,
> +	.disable = mtk_hdmi_bridge_disable,

atomic_disable

> +	.post_disable = mtk_hdmi_bridge_post_disable,

atomic_post_disable

> +	.mode_set = mtk_hdmi_bridge_mode_set,
> +	.pre_enable = mtk_hdmi_bridge_pre_enable,

atomic_pre_enable

> +	.enable = mtk_hdmi_bridge_enable,

atomic_enable

Regards,
CK

> +	.get_edid = mtk_hdmi_bridge_get_edid,
> +};
> +
> +static void mtk_hdmi_set_plugged_cb(struct mtk_hdmi *hdmi,
> +				    hdmi_codec_plugged_cb fn,
> +				    struct device *codec_dev)
> +{
> +	bool plugged;
> +
> +	hdmi->plugged_cb = fn;
> +	hdmi->codec_dev = codec_dev;
> +	plugged = (hdmi->hpd == HDMI_PLUG_IN_AND_SINK_POWER_ON) ? true
> : false;
> +	mtk_hdmi_handle_plugged_change(hdmi, plugged);
> +}
> +
> +/*
> + * HDMI audio codec callbacks
> + */
> 



From anshuman.khandual at arm.com  Thu Jan 27 19:27:06 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 08:57:06 +0530
Subject: [RFC V1 05/11] arm64/perf: Detect support for BRBE
In-Reply-To: <YfGCgwlk6wHS/OYe@robh.at.kernel.org>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-6-git-send-email-anshuman.khandual@arm.com>
 <YfGCgwlk6wHS/OYe@robh.at.kernel.org>
Message-ID: <71181375-c36e-d3a6-d244-a2bbfd4004fc@arm.com>



On 1/26/22 10:48 PM, Rob Herring wrote:
> On Mon, Jan 24, 2022 at 10:00:47AM +0530, Anshuman Khandual wrote:
>> CPU specific BRBE entries, cycle count, format support gets detected during
>> PMU init. This information gets saved in per-cpu struct pmu_hw_events which
>> later helps in operating BRBE during a perf event context.
> 
> Another NOP commit. The subject says 'arm64' and that we detect BRBE 
> support. This patch neither touches arm64 code nor detects anything.

Right, this is a NOP at this point but it will have functionality when the
driver gets added later on. I will correct the arm64 part and also update
the message saying - it just adds the infrastructure for BRBE detection not
the actual function.

> 
>>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  drivers/perf/arm_pmu_platform.c | 34 +++++++++++++++++++++++++++++++++
>>  1 file changed, 34 insertions(+)
>>
>> diff --git a/drivers/perf/arm_pmu_platform.c b/drivers/perf/arm_pmu_platform.c
>> index 513de1f54e2d..800e4a6e8bc3 100644
>> --- a/drivers/perf/arm_pmu_platform.c
>> +++ b/drivers/perf/arm_pmu_platform.c
>> @@ -172,6 +172,36 @@ static int armpmu_request_irqs(struct arm_pmu *armpmu)
>>  	return err;
>>  }
>>  
>> +static void arm_brbe_probe_cpu(void *info)
>> +{
>> +	struct pmu_hw_events *hw_events;
>> +	struct arm_pmu *armpmu = info;
>> +
>> +	/*
>> +	 * Return from here, if BRBE driver has not been
>> +	 * implemented for this PMU. This helps prevent
>> +	 * kernel crash later when brbe_probe() will be
>> +	 * called on the PMU.
>> +	 */
>> +	if (!armpmu->brbe_probe)
>> +		return;
>> +
>> +	hw_events = per_cpu_ptr(armpmu->hw_events, smp_processor_id());
>> +	armpmu->brbe_probe(hw_events);
>> +}
>> +
>> +static int armpmu_request_brbe(struct arm_pmu *armpmu)
>> +{
>> +	int cpu, err = 0;
>> +
>> +	for_each_cpu(cpu, &armpmu->supported_cpus) {
>> +		err = smp_call_function_single(cpu, arm_brbe_probe_cpu, armpmu, 1);
>> +		if (err)
>> +			return err;
>> +	}
>> +	return err;
>> +}
>> +
>>  static void armpmu_free_irqs(struct arm_pmu *armpmu)
>>  {
>>  	int cpu;
>> @@ -229,6 +259,10 @@ int arm_pmu_device_probe(struct platform_device *pdev,
>>  	if (ret)
>>  		goto out_free_irqs;
>>  
>> +	ret = armpmu_request_brbe(pmu);
>> +	if (ret)
>> +		goto out_free_irqs;
>> +
>>  	ret = armpmu_register(pmu);
>>  	if (ret) {
>>  		dev_err(dev, "failed to register PMU devices!\n");
>> -- 
>> 2.25.1
>>
>>


From yunfei.dong at mediatek.com  Thu Jan 27 19:28:28 2022
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Fri, 28 Jan 2022 11:28:28 +0800
Subject: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
In-Reply-To: <CAGXv+5ELuvvG6dwXH5DdHtjOm4j4AAVTk2UxGOitF5v5Vx265A@mail.gmail.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
 <20220127025544.10854-8-yunfei.dong@mediatek.com>
 <CAGXv+5ELuvvG6dwXH5DdHtjOm4j4AAVTk2UxGOitF5v5Vx265A@mail.gmail.com>
Message-ID: <c7e8cccc04aeb5520e5b3f090c89d1356b763acd.camel@mediatek.com>

Hi Chen-Yu,

Thanks for your suggestion.
Send this patch again.
On Thu, 2022-01-27 at 17:23 +0800, Chen-Yu Tsai wrote:
> Hi,
> 
> On Thu, Jan 27, 2022 at 10:56 AM Yunfei Dong <
> yunfei.dong at mediatek.com> wrote:
> > 
> > Init some of VP9 frame decode params to default value.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> 
> Maybe add
> 
> Fixes: b88dbe38dca8 ("media: uapi: Add VP9 stateless decoder
> controls")
> 
Best Regards,
Yunfei Dong
> > ---
> >  drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
> >  1 file changed, 8 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > index 54abe5245dcc..b25c77b8a445 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > @@ -112,6 +112,7 @@ static void std_init_compound(const struct
> > v4l2_ctrl *ctrl, u32 idx,
> >         struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
> >         struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
> >         struct v4l2_ctrl_vp8_frame *p_vp8_frame;
> > +       struct v4l2_ctrl_vp9_frame *p_vp9_frame;
> >         struct v4l2_ctrl_fwht_params *p_fwht_params;
> >         void *p = ptr.p + idx * ctrl->elem_size;
> > 
> > @@ -152,6 +153,13 @@ static void std_init_compound(const struct
> > v4l2_ctrl *ctrl, u32 idx,
> >                 p_vp8_frame = p;
> >                 p_vp8_frame->num_dct_parts = 1;
> >                 break;
> > +       case V4L2_CTRL_TYPE_VP9_FRAME:
> > +               p_vp9_frame = p;
> > +               p_vp9_frame->profile = 0;
> > +               p_vp9_frame->bit_depth = 8;
> > +               p_vp9_frame->flags |=
> > V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING |
> > +                       V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
> > +               break;
> >         case V4L2_CTRL_TYPE_FWHT_PARAMS:
> >                 p_fwht_params = p;
> >                 p_fwht_params->version = V4L2_FWHT_VERSION;
> > --
> > 2.25.1
> > 

From anshuman.khandual at arm.com  Thu Jan 27 19:38:20 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 09:08:20 +0530
Subject: [RFC V1 03/11] arm64/perf: Update struct arm_pmu for BRBE
In-Reply-To: <YfF+APV2vew5AloE@robh.at.kernel.org>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-4-git-send-email-anshuman.khandual@arm.com>
 <YfF+APV2vew5AloE@robh.at.kernel.org>
Message-ID: <c3804290-bdb1-d1eb-3526-9b0ce4c8e8b1@arm.com>



On 1/26/22 10:29 PM, Rob Herring wrote:
> On Mon, Jan 24, 2022 at 10:00:45AM +0530, Anshuman Khandual wrote:
>> This updates struct arm_pmu to include all required helpers that will drive
> 
>>From submitting-patches.rst:
> 
> Describe your changes in imperative mood, e.g. "make xyzzy do frotz"
> instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy
> to do frotz", as if you are giving orders to the codebase to change
> its behaviour.

s/This updates struct arm_pmu to/Update struct arm_pmu to/ should address
this problem I guess. Although the difference here seems very subtle :)

> 
>> BRBE functionality for a given PMU implementation. These are the following.
> 
> Don't describe what the change is, one can read the diff for that. 

Sure, though was trying just to enumerate a potential driver's functional
responsibilities.

> Answer why it is needed.

Sure.

> 
> One thing to answer in the commit msg is why we need the hooks here.  
> Have we concluded that adding BRBE hooks to struct arm_pmu for what is 
> an armv8 specific feature is the right approach? I don't recall 
> reaching that conclusion.

Although it might be possible to have this implementation embedded in
the existing armv8 PMU implementation, I still believe that the BRBE
functionalities abstracted out at the arm_pmu level with a separate
config option is cleaner, easier to follow and to maintain as well.

Besides some helpers i.e brbe_supported(), brbe_probe() and brbe_reset()
might not fit seamlessly, when tried to be embedded via existing arm_pmu
helpers in the armv8 implementation.

Nonetheless if arm_pmu based additional BRBE helpers is absolutely a no
go for folks here in general, will explore arm64 based implementation.

> 
>>
>> - brbe_filter	: Convert perf event filters into BRBE HW filters
>> - brbe_probe	: Probe BRBE HW and capture its attributes
>> - brbe_enable	: Enable BRBE HW with a given config
>> - brbe_disable	: Disable BRBE HW
>> - brbe_read	: Read BRBE buffer for captured branch records
>> - brbe_reset	: Reset BRBE buffer
>> - brbe_supported: Whether BRBE is supported or not
> 
> The function names seem pretty self-explanatory, but the text is needed, 
> shouldn't it be in the struct declaration.

Sure, sounds good. Will move there.

> 
> I'm not really a fan of patches adding dead code. That's not any less to 
> review. Restructuring with 'no functional change' OTOH is helpful in 
> reviewing.

Restructuring without functional change clarifies the purpose better.
Besides this is more relevant in this context where the functions will
be provided by a separate (and also detached) driver implementation.

>> A BRBE driver implementation needs to provide these functionalities.
>>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Peter Zijlstra <peterz at infradead.org>
>> Cc: Ingo Molnar <mingo at redhat.com>
>> Cc: Catalin Marinas <catalin.marinas at arm.com>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-perf-users at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  arch/arm64/kernel/perf_event.c | 36 ++++++++++++++++++++++++++++++++++
>>  include/linux/perf/arm_pmu.h   |  7 +++++++
>>  2 files changed, 43 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
>> index cab678ed6618..f6a47036b0b4 100644
>> --- a/arch/arm64/kernel/perf_event.c
>> +++ b/arch/arm64/kernel/perf_event.c
>> @@ -1015,6 +1015,35 @@ static int armv8pmu_filter_match(struct perf_event *event)
>>  	return evtype != ARMV8_PMUV3_PERFCTR_CHAIN;
>>  }
>>  
>> +static void armv8pmu_brbe_filter(struct pmu_hw_events *hw_event, struct perf_event *event)
>> +{
>> +}
>> +
>> +static void armv8pmu_brbe_enable(struct pmu_hw_events *hw_event)
>> +{
>> +}
>> +
>> +static void armv8pmu_brbe_disable(struct pmu_hw_events *hw_event)
>> +{
>> +}
>> +
>> +static void armv8pmu_brbe_read(struct pmu_hw_events *hw_event, struct perf_event *event)
>> +{
>> +}
>> +
>> +static void armv8pmu_brbe_probe(struct pmu_hw_events *hw_event)
>> +{
>> +}
>> +
>> +static void armv8pmu_brbe_reset(struct pmu_hw_events *hw_event)
>> +{
>> +}
>> +
>> +static bool armv8pmu_brbe_supported(struct perf_event *event)
>> +{
>> +	return false;
>> +}
>> +
>>  static void armv8pmu_reset(void *info)
>>  {
>>  	struct arm_pmu *cpu_pmu = (struct arm_pmu *)info;
>> @@ -1247,6 +1276,13 @@ static int armv8_pmu_init(struct arm_pmu *cpu_pmu, char *name,
>>  
>>  	cpu_pmu->pmu.event_idx		= armv8pmu_user_event_idx;
>>  
>> +	cpu_pmu->brbe_filter		= armv8pmu_brbe_filter;
>> +	cpu_pmu->brbe_enable		= armv8pmu_brbe_enable;
>> +	cpu_pmu->brbe_disable		= armv8pmu_brbe_disable;
>> +	cpu_pmu->brbe_read		= armv8pmu_brbe_read;
>> +	cpu_pmu->brbe_probe		= armv8pmu_brbe_probe;
>> +	cpu_pmu->brbe_reset		= armv8pmu_brbe_reset;
>> +	cpu_pmu->brbe_supported		= armv8pmu_brbe_supported;
>>  	cpu_pmu->name			= name;
>>  	cpu_pmu->map_event		= map_event;
>>  	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = events ?
>> diff --git a/include/linux/perf/arm_pmu.h b/include/linux/perf/arm_pmu.h
>> index 2512e2f9cd4e..c0dd0d6c5883 100644
>> --- a/include/linux/perf/arm_pmu.h
>> +++ b/include/linux/perf/arm_pmu.h
>> @@ -98,6 +98,13 @@ struct arm_pmu {
>>  	void		(*reset)(void *);
>>  	int		(*map_event)(struct perf_event *event);
>>  	int		(*filter_match)(struct perf_event *event);
>> +	void		(*brbe_filter)(struct pmu_hw_events *hw_events, struct perf_event *event);
>> +	void		(*brbe_probe)(struct pmu_hw_events *hw_events);
>> +	void		(*brbe_enable)(struct pmu_hw_events *hw_events);
>> +	void		(*brbe_disable)(struct pmu_hw_events *hw_events);
>> +	void		(*brbe_read)(struct pmu_hw_events *hw_events, struct perf_event *event);
>> +	void		(*brbe_reset)(struct pmu_hw_events *hw_events);
>> +	bool		(*brbe_supported)(struct perf_event *event);
>>  	int		num_events;
>>  	bool		secure_access; /* 32-bit ARM only */
>>  #define ARMV8_PMUV3_MAX_COMMON_EVENTS		0x40
>> -- 
>> 2.25.1
>>
>>


From yunfei.dong at mediatek.com  Thu Jan 27 19:29:48 2022
From: yunfei.dong at mediatek.com (yunfei.dong at mediatek.com)
Date: Fri, 28 Jan 2022 11:29:48 +0800
Subject: [PATCH v1, 7/8] media: uapi: Init VP9 stateless decode params
In-Reply-To: <07468ddd-22a8-c2a5-21fd-8468e0e77d74@collabora.com>
References: <20220127025544.10854-1-yunfei.dong@mediatek.com>
 <20220127025544.10854-8-yunfei.dong@mediatek.com>
 <07468ddd-22a8-c2a5-21fd-8468e0e77d74@collabora.com>
Message-ID: <f1a722ca06545c8fcb23707356b889e7c963ea7a.camel@mediatek.com>

Hi AngeloGioacchino,

Thanks for your suggestion,

Separate this patch with mt8195 support, and sent it again.
On Thu, 2022-01-27 at 11:35 +0100, AngeloGioacchino Del Regno wrote:
> Il 27/01/22 03:55, Yunfei Dong ha scritto:
> > Init some of VP9 frame decode params to default value.
> > 
> > Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> 
> Hello Yunfei,
> 
> This patch is not strictly related to MediaTek SoCs, since it's
> modfying v4l2-core.
> Can you please send this patch separately?
> 
> Thanks,
> Angelo
> 
Best Regards,
Yunfei Dong
> > ---
> >   drivers/media/v4l2-core/v4l2-ctrls-core.c | 8 ++++++++
> >   1 file changed, 8 insertions(+)
> > 
> > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > index 54abe5245dcc..b25c77b8a445 100644
> > --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
> > @@ -112,6 +112,7 @@ static void std_init_compound(const struct
> > v4l2_ctrl *ctrl, u32 idx,
> >   	struct v4l2_ctrl_mpeg2_picture *p_mpeg2_picture;
> >   	struct v4l2_ctrl_mpeg2_quantisation *p_mpeg2_quant;
> >   	struct v4l2_ctrl_vp8_frame *p_vp8_frame;
> > +	struct v4l2_ctrl_vp9_frame *p_vp9_frame;
> >   	struct v4l2_ctrl_fwht_params *p_fwht_params;
> >   	void *p = ptr.p + idx * ctrl->elem_size;
> >   
> > @@ -152,6 +153,13 @@ static void std_init_compound(const struct
> > v4l2_ctrl *ctrl, u32 idx,
> >   		p_vp8_frame = p;
> >   		p_vp8_frame->num_dct_parts = 1;
> >   		break;
> > +	case V4L2_CTRL_TYPE_VP9_FRAME:
> > +		p_vp9_frame = p;
> > +		p_vp9_frame->profile = 0;
> > +		p_vp9_frame->bit_depth = 8;
> > +		p_vp9_frame->flags |= V4L2_VP9_FRAME_FLAG_X_SUBSAMPLING
> > |
> > +			V4L2_VP9_FRAME_FLAG_Y_SUBSAMPLING;
> > +		break;
> >   	case V4L2_CTRL_TYPE_FWHT_PARAMS:
> >   		p_fwht_params = p;
> >   		p_fwht_params->version = V4L2_FWHT_VERSION;
> > 
> 
> 

From kuba at kernel.org  Thu Jan 27 19:43:38 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Thu, 27 Jan 2022 19:43:38 -0800
Subject: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate
 tx/rx handling with two NAPIs
In-Reply-To: <20220127015857.9868-10-biao.huang@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
 <20220127015857.9868-10-biao.huang@mediatek.com>
Message-ID: <20220127194338.01722b3c@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Thu, 27 Jan 2022 09:58:57 +0800 Biao Huang wrote:
> Current driver may lost tx interrupts under bidirectional test with iperf3,
> which leads to some unexpected issues.
> 
> This patch let rx/tx interrupt enable/disable separately, and rx/tx are
> handled in different NAPIs.

> +/* mtk_star_handle_irq - Interrupt Handler.
> + * @irq: interrupt number.
> + * @data: pointer to a network interface device structure.

if you mean this to me a kdoc comment it needs to start with /**

> + * Description : this is the driver interrupt service routine.
> + * it mainly handles:
> + *  1. tx complete interrupt for frame transmission.
> + *  2. rx complete interrupt for frame reception.
> + *  3. MAC Management Counter interrupt to avoid counter overflow.
>   */
>  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
>  {
> -	struct mtk_star_priv *priv;
> -	struct net_device *ndev;
> +	struct net_device *ndev = data;
> +	struct mtk_star_priv *priv = netdev_priv(ndev);
> +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> +	unsigned long flags = 0;
> +
> +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> +		if (napi_schedule_prep(&priv->rx_napi)) {
> +			spin_lock_irqsave(&priv->lock, flags);
> +			/* mask Rx Complete interrupt */
> +			mtk_star_disable_dma_irq(priv, true, false);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +			__napi_schedule_irqoff(&priv->rx_napi);
> +		}
> +	}
>  
> -	ndev = data;
> -	priv = netdev_priv(ndev);
> +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> +		if (napi_schedule_prep(&priv->tx_napi)) {
> +			spin_lock_irqsave(&priv->lock, flags);
> +			/* mask Tx Complete interrupt */
> +			mtk_star_disable_dma_irq(priv, false, true);
> +			spin_unlock_irqrestore(&priv->lock, flags);
> +			__napi_schedule_irqoff(&priv->tx_napi);
> +		}
> +	}

Seems a little wasteful to retake the same lock twice if two IRQ
sources fire at the same time.

> @@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
>  	struct mtk_star_ring *ring = &priv->tx_ring;
>  	struct device *dev = mtk_star_get_dev(priv);
>  	struct mtk_star_ring_desc_data desc_data;
> +	int nfrags = skb_shinfo(skb)->nr_frags;
> +
> +	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
> +		if (!netif_queue_stopped(ndev)) {
> +			netif_stop_queue(ndev);
> +			/* This is a hard error, log it. */
> +			netdev_err(priv->ndev, "%s: Tx Ring full when queue awake\n",
> +				   __func__);

This needs to be rate limited. Also no point printing the function
name, unless the same message appears in multiple places.

> +		}
> +		return NETDEV_TX_BUSY;
> +	}
>  
>  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
>  	if (dma_mapping_error(dev, desc_data.dma_addr))
> @@ -1050,18 +1103,10 @@ static int mtk_star_netdev_start_xmit(struct sk_buff *skb,
>  
>  	desc_data.skb = skb;
>  	desc_data.len = skb->len;
> -
> -	spin_lock_bh(&priv->lock);
> 
>  	mtk_star_ring_push_head_tx(ring, &desc_data);
>  
>  	netdev_sent_queue(ndev, skb->len);
>  
> -	if (mtk_star_ring_full(ring))
> -		netif_stop_queue(ndev);

Are you stopping the queue in advance somewhere else now? Did you only
test this with BQL enabled? Only place that stops the ring also prints
a loud warning now AFAICS..

> -static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
> +static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
>  {
> -	struct mtk_star_ring *ring = &priv->tx_ring;
> -	struct net_device *ndev = priv->ndev;
> -	int ret, pkts_compl, bytes_compl;
> +	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
> +	struct mtk_star_priv *priv;
> +	struct mtk_star_ring *ring;
> +	struct net_device *ndev;
> +	unsigned long flags = 0;
> +	unsigned int entry;
>  	bool wake = false;
>  
> -	spin_lock(&priv->lock);
> +	priv = container_of(napi, struct mtk_star_priv, tx_napi);
> +	ndev = priv->ndev;
>  
> -	for (pkts_compl = 0, bytes_compl = 0;;
> +	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));

Do you really need to lock out the Tx while cleaning?

Drivers usually manage to implement concurrent Tx and cleanup with just
a couple of memory barriers.

> +	ring = &priv->tx_ring;
> +	entry = ring->tail;
> +	for (pkts_compl = 0, bytes_compl = 0;
> +	     (entry != ring->head) && (count < budget);

budget is not really relevant for Tx, you can clean the whole ring.
netpoll will pass a budget of 0 to clean up rings.

>  	     pkts_compl++, bytes_compl += ret, wake = true) {
> -		if (!mtk_star_ring_descs_available(ring))
> -			break;
>  
>  		ret = mtk_star_tx_complete_one(priv);
>  		if (ret < 0)
>  			break;
> +		count++;
> +		entry = ring->tail;
>  	}
>  

> @@ -1196,7 +1258,7 @@ static const struct ethtool_ops mtk_star_ethtool_ops = {
>  	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
>  };
>  
> -static int mtk_star_receive_packet(struct mtk_star_priv *priv)
> +static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
>  {
>  	struct mtk_star_ring *ring = &priv->rx_ring;
>  	struct device *dev = mtk_star_get_dev(priv);
> @@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct mtk_star_priv *priv)
>  	struct net_device *ndev = priv->ndev;
>  	struct sk_buff *curr_skb, *new_skb;
>  	dma_addr_t new_dma_addr;
> -	int ret;
> +	int ret, count = 0;
>  
> -	spin_lock(&priv->lock);
> -	ret = mtk_star_ring_pop_tail(ring, &desc_data);
> -	spin_unlock(&priv->lock);
> -	if (ret)
> -		return -1;
> +	while (count < budget) {
> +		ret = mtk_star_ring_pop_tail(ring, &desc_data);
> +		if (ret)
> +			return -1;

> -static int mtk_star_process_rx(struct mtk_star_priv *priv, int budget)
> -{
> -	int received, ret;
> +		count++;
>  
> -	for (received = 0, ret = 0; received < budget && ret == 0; received++)
> -		ret = mtk_star_receive_packet(priv);
> +		desc_data.len = skb_tailroom(new_skb);
> +		desc_data.skb = new_skb;
> +		mtk_star_ring_push_head_rx(ring, &desc_data);
> +	}
>  
>  	mtk_star_dma_resume_rx(priv);

Again you can get a call with a budget of 0, not sure if it's okay to
resume DMA in that case..

> -	return received;
> +	return count;
>  }



From shawnguo at kernel.org  Thu Jan 27 19:54:48 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 11:54:48 +0800
Subject: [PATCH] arm64: dts: imx8m{m,n}_venice*: add gpio-line-names
In-Reply-To: <CAJ+vNU3Xj-b2BSc_6MQrtrh-G=5dMdMmw0S8EtujVz_7FvkQ0w@mail.gmail.com>
References: <20211215001812.9006-1-tharvey@gateworks.com>
 <20220126090739.GH4686@dragon>
 <CAJ+vNU3Xj-b2BSc_6MQrtrh-G=5dMdMmw0S8EtujVz_7FvkQ0w@mail.gmail.com>
Message-ID: <20220128035447.GZ4686@dragon>

On Thu, Jan 27, 2022 at 02:49:41PM -0800, Tim Harvey wrote:
> On Wed, Jan 26, 2022 at 1:07 AM Shawn Guo <shawnguo at kernel.org> wrote:
> >
> > On Tue, Dec 14, 2021 at 04:18:12PM -0800, Tim Harvey wrote:
> > > Add gpio-line-names for the various GPIO's used on Gateworks Venice
> > > boards. Note that these GPIO's are typically 'configured' in Boot
> > > Firmware via gpio-hog therefore we only configure line names to keep the
> > > boot firmware configuration from changing on kernel init.
> > >
> > > Signed-off-by: Tim Harvey <tharvey at gateworks.com>
> >
> > It doesn't apply to my imx/dt64 branch.  Could you rebase?
> >
> 
> Shawn,
> 
> Sure, I'll try to submit another version within a couple of days.
> 
> Did you happen to see 'arm64: dts: imx8mm-venice*: add PCIe support'
> [1]? It seems to have been archived for some reason and it may have to
> be rebased after I re-post this one unless you can take that now.

I forgot to reply, but I had already pick that up.

Shawn


From yunfei.dong at mediatek.com  Thu Jan 27 19:54:39 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:39 +0800
Subject: [PATCH v2,
 6/7] media: mtk-vcodec: prevent kernel crash when scp ipi timeout
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-7-yunfei.dong@mediatek.com>

From: Tinghan Shen <tinghan.shen at mediatek.com>

When SCP timeout during playing video, kernel crashes with following
message. It's caused by accessing NULL pointer in vpu_dec_ipi_handler.
This patch doesn't solve the root cause of NULL pointer, but merely
prevent kernel crashed when encounter the NULL pointer.

After applied this patch, kernel keeps alive, only the video player turns
to green screen.

[67242.065474] pc : vpu_dec_ipi_handler+0xa0/0xb20 [mtk_vcodec_dec]
[67242.065485] [MTK_V4L2] level=0 fops_vcodec_open(),334:
18000000.vcodec_dec decoder [135]
[67242.065523] lr : scp_ipi_handler+0x11c/0x244 [mtk_scp]
[67242.065540] sp : ffffffbb4207fb10
[67242.065557] x29: ffffffbb4207fb30 x28: ffffffd00a1d5000
[67242.065592] x27: 1ffffffa0143aa24 x26: 0000000000000000
[67242.065625] x25: dfffffd000000000 x24: ffffffd0168bfdb0
[67242.065659] x23: 1ffffff76840ff74 x22: ffffffbb41fa8a88
[67242.065692] x21: ffffffbb4207fb9c x20: ffffffbb4207fba0
[67242.065725] x19: ffffffbb4207fb98 x18: 0000000000000000
[67242.065758] x17: 0000000000000000 x16: ffffffd042022094
[67242.065791] x15: 1ffffff77ed4b71a x14: 1ffffff77ed4b719
[67242.065824] x13: 0000000000000000 x12: 0000000000000000
[67242.065857] x11: 0000000000000000 x10: dfffffd000000001
[67242.065890] x9 : 0000000000000000 x8 : 0000000000000002
[67242.065923] x7 : 0000000000000000 x6 : 000000000000003f
[67242.065956] x5 : 0000000000000040 x4 : ffffffffffffffe0
[67242.065989] x3 : ffffffd043b841b8 x2 : 0000000000000000
[67242.066021] x1 : 0000000000000010 x0 : 0000000000000010
[67242.066055] Call trace:
[67242.066092]  vpu_dec_ipi_handler+0xa0/0xb20 [mtk_vcodec_dec
12220d230d83a7426fc38c56b3e7bc6066955bae]
[67242.066119]  scp_ipi_handler+0x11c/0x244 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066145]  mt8192_scp_irq_handler+0x70/0x128 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066172]  scp_irq_handler+0xa0/0x114 [mtk_scp
8fb69c2ef141dd3192518b952b65aba35627b8bf]
[67242.066200]  irq_thread_fn+0x84/0xf8
[67242.066220]  irq_thread+0x170/0x1ec
[67242.066242]  kthread+0x2f8/0x3b8
[67242.066264]  ret_from_fork+0x10/0x30
[67242.066292] Code: 38f96908 35003628 91004340 d343fc08 (38f96908)

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Macpaul Lin <macpaul.lin at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/vdec_vpu_if.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
index 35f4d5583084..1041dd663e76 100644
--- a/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec_vpu_if.c
@@ -91,6 +91,11 @@ static void vpu_dec_ipi_handler(void *data, unsigned int len, void *priv)
 	struct vdec_vpu_inst *vpu = (struct vdec_vpu_inst *)
 					(unsigned long)msg->ap_inst_addr;
 
+	if (!vpu) {
+		mtk_v4l2_err("ap_inst_addr is NULL");
+		return;
+	}
+
 	mtk_vcodec_debug(vpu, "+ id=%X", msg->msg_id);
 
 	vpu->failure = msg->status;
-- 
2.25.1



From shawnguo at kernel.org  Thu Jan 27 20:03:48 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 12:03:48 +0800
Subject: [PATCH 1/2] ARM: dts: imx28: Use correct compatible string for RTC
In-Reply-To: <20211220134311.683553-1-thierry.reding@gmail.com>
References: <20211220134311.683553-1-thierry.reding@gmail.com>
Message-ID: <20220128040347.GB4686@dragon>

On Mon, Dec 20, 2021 at 02:43:10PM +0100, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
> 
> The "mxim" vendor prefix does not exit, though it looks like it might
> have been a typo'ed "maxim". Still, no compatible string exists that
> matches "maxim,ds1339". The closest is the "dallas,ds1339" and since
> this node is named "rtc" that's probably the one that was intended.
> 
> Signed-off-by: Thierry Reding <treding at nvidia.com>

Applied both, thanks!


From yunfei.dong at mediatek.com  Thu Jan 27 19:54:33 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:33 +0800
Subject: [PATCH v2, 0/7] support mt8195 decoder
Message-ID: <20220128035440.24533-1-yunfei.dong@mediatek.com>

Firstly, add mt8195 soc lat hardware and compatible, then add documents.
For vp8 only support MM21 mode, H264/vp9 support MT21C, need to separate
them. Lastly, enable H264 inner racing mode to reduce hardware latency.

Patch 1~4 add mt8195 soc lat hardware and compatible, then add documents.
Patch 5 using different format for different codecs.
Patch 6 prevent kernel crash when scp reboot.
Patch 7 enable H264 inner racing mode to reduce hardware latency.
---
This patch depends on "support mt8186 decoder"[1]

[1]  https://patchwork.kernel.org/project/linux-mediatek/cover/20220122075606.19373-1-yunfei.dong at mediatek.com
---
changed with v1:
- separate "Init VP9 stateless decode params" patch and remove it to another one.
- add reviewed-by in patch v3/v4/v6
---
Tinghan Shen (1):
  media: mtk-vcodec: prevent kernel crash when scp ipi timeout

Yunfei Dong (6):
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for lat soc
  media: mtk-vcodec: Add to support lat soc hardware
  dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for mt8195
  media: mtk-vcodec: Adds compatible for mt8195
  media: mtk-vcodec: Different codec using different capture format
  media: mtk-vcodec: Add to support H264 inner racing mode

 .../media/mediatek,vcodec-subdev-decoder.yaml | 50 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 41 +++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  8 +++
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c   | 12 +++--
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h   |  2 +
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 50 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 11 ++++
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 23 +++++++--
 .../media/platform/mtk-vcodec/vdec_vpu_if.c   |  5 ++
 9 files changed, 194 insertions(+), 8 deletions(-)

-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:37 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:37 +0800
Subject: [PATCH v2, 4/7] media: mtk-vcodec: Adds compatible for mt8195
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-5-yunfei.dong@mediatek.com>

Adds compatible for mt8195 platform.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Macpaul Lin <macpaul.lin at mediatek.com>
---
 drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 2d21d0010c9c..938bf14e4e8c 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -468,6 +468,10 @@ static const struct of_device_id mtk_vcodec_match[] = {
 		.compatible = "mediatek,mt8186-vcodec-dec",
 		.data = &mtk_vdec_single_core_pdata,
 	},
+	{
+		.compatible = "mediatek,mt8195-vcodec-dec",
+		.data = &mtk_lat_sig_core_pdata,
+	},
 	{},
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:35 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:35 +0800
Subject: [PATCH v2, 2/7] media: mtk-vcodec: Add to support lat soc hardware
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-3-yunfei.dong@mediatek.com>

Add lat soc compatible and to support lat soc power/clk helper.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.c      | 12 +++++++++---
 .../platform/mtk-vcodec/mtk_vcodec_dec_hw.h      |  2 ++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c      | 16 ++++++++++++++++
 .../media/platform/mtk-vcodec/mtk_vcodec_drv.h   |  1 +
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
index 7b5da3e4cac2..7374d5a5c156 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.c
@@ -28,6 +28,10 @@ static const struct of_device_id mtk_vdec_hw_match[] = {
 		.compatible = "mediatek,mtk-vcodec-core",
 		.data = (void *)MTK_VDEC_CORE,
 	},
+	{
+		.compatible = "mediatek,mtk-vcodec-lat-soc",
+		.data = (void *)MTK_VDEC_LAT_SOC,
+	},
 	{},
 };
 MODULE_DEVICE_TABLE(of, mtk_vdec_hw_match);
@@ -166,9 +170,11 @@ static int mtk_vdec_hw_probe(struct platform_device *pdev)
 	subdev_dev->reg_base[VDEC_HW_SYS] = main_dev->reg_base[VDEC_HW_SYS];
 	set_bit(subdev_dev->hw_idx, main_dev->subdev_bitmap);
 
-	ret = mtk_vdec_hw_init_irq(subdev_dev);
-	if (ret)
-		goto err;
+	if (IS_SUPPORT_VDEC_HW_IRQ(hw_idx)) {
+		ret = mtk_vdec_hw_init_irq(subdev_dev);
+		if (ret)
+			goto err;
+	}
 
 	subdev_dev->reg_base[VDEC_HW_MISC] =
 		devm_platform_ioremap_resource(pdev, 0);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
index a63e4b1b81c3..b8938c6c3e72 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_hw.h
@@ -17,6 +17,8 @@
 #define VDEC_IRQ_CLR 0x10
 #define VDEC_IRQ_CFG_REG 0xa4
 
+#define IS_SUPPORT_VDEC_HW_IRQ(hw_idx) (hw_idx != MTK_VDEC_LAT_SOC)
+
 /**
  * enum mtk_vdec_hw_reg_idx - subdev hardware register base index
  * @VDEC_HW_SYS : vdec soc register index
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 1581a1277473..76e1442fc6f9 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -203,6 +203,14 @@ static void mtk_vcodec_dec_child_dev_on(struct mtk_vcodec_dev *vdec_dev,
 		mtk_vcodec_dec_pw_on(pm);
 		mtk_vcodec_dec_clock_on(pm);
 	}
+
+	if (hw_idx == MTK_VDEC_LAT0) {
+		pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC);
+		if (pm) {
+			mtk_vcodec_dec_pw_on(pm);
+			mtk_vcodec_dec_clock_on(pm);
+		}
+	}
 }
 
 static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
@@ -215,6 +223,14 @@ static void mtk_vcodec_dec_child_dev_off(struct mtk_vcodec_dev *vdec_dev,
 		mtk_vcodec_dec_clock_off(pm);
 		mtk_vcodec_dec_pw_off(pm);
 	}
+
+	if (hw_idx == MTK_VDEC_LAT0) {
+		pm = mtk_vcodec_dec_get_pm(vdec_dev, MTK_VDEC_LAT_SOC);
+		if (pm) {
+			mtk_vcodec_dec_clock_off(pm);
+			mtk_vcodec_dec_pw_off(pm);
+		}
+	}
 }
 
 void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index cd2939b47790..363b999dd709 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -104,6 +104,7 @@ enum mtk_vdec_hw_id {
 	MTK_VDEC_CORE,
 	MTK_VDEC_LAT0,
 	MTK_VDEC_LAT1,
+	MTK_VDEC_LAT_SOC,
 	MTK_VDEC_HW_MAX,
 };
 
-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:34 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:34 +0800
Subject: [PATCH v2,
 1/7] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for lat
 soc
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-2-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for compatible "mediatek,mtk-vcodec-lat-soc".

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../media/mediatek,vcodec-subdev-decoder.yaml | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index 6415c9f29130..a3c892338ac0 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -189,6 +189,55 @@ patternProperties:
 
     additionalProperties: false
 
+  '^vcodec-lat-soc@[0-9a-f]+$':
+    type: object
+
+    properties:
+      compatible:
+        const: mediatek,mtk-vcodec-lat-soc
+
+      reg:
+        maxItems: 1
+
+      iommus:
+        minItems: 1
+        maxItems: 32
+        description: |
+          List of the hardware port in respective IOMMU block for current Socs.
+          Refer to bindings/iommu/mediatek,iommu.yaml.
+
+      clocks:
+        maxItems: 5
+
+      clock-names:
+        items:
+          - const: sel
+          - const: soc-vdec
+          - const: soc-lat
+          - const: vdec
+          - const: top
+
+      assigned-clocks:
+        maxItems: 1
+
+      assigned-clock-parents:
+        maxItems: 1
+
+      power-domains:
+        maxItems: 1
+
+    required:
+      - compatible
+      - reg
+      - iommus
+      - clocks
+      - clock-names
+      - assigned-clocks
+      - assigned-clock-parents
+      - power-domains
+
+    additionalProperties: false
+
 required:
   - compatible
   - reg
-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:38 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:38 +0800
Subject: [PATCH v2,
 5/7] media: mtk-vcodec: Different codec using different capture format
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-6-yunfei.dong@mediatek.com>

Vp8 need to use MM21, but vp9 and h264 need to use HyFbc mode
for mt8195. Vp8/vp9/h264 use the same MM21 format for mt8192.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec.c      | 41 +++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
index 6ad17e69e32d..f2ced0147534 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c
@@ -35,6 +35,44 @@ mtk_vdec_find_format(struct v4l2_format *f,
 	return NULL;
 }
 
+static bool mtk_vdec_get_cap_fmt(struct mtk_vcodec_ctx *ctx, int format_index)
+{
+	const struct mtk_vcodec_dec_pdata *dec_pdata = ctx->dev->vdec_pdata;
+	const struct mtk_video_fmt *fmt;
+	struct mtk_q_data *q_data;
+	int num_frame_count = 0, i;
+	bool ret = true;
+
+	for (i = 0; i < *dec_pdata->num_formats; i++) {
+		if (dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
+			continue;
+
+		num_frame_count++;
+	}
+
+	if (num_frame_count == 1)
+		return true;
+
+	fmt = &dec_pdata->vdec_formats[format_index];
+	q_data = &ctx->q_data[MTK_Q_DATA_SRC];
+	switch (q_data->fmt->fourcc) {
+	case V4L2_PIX_FMT_VP8_FRAME:
+		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+			ret = true;
+		break;
+	case V4L2_PIX_FMT_H264_SLICE:
+	case V4L2_PIX_FMT_VP9_FRAME:
+		if (fmt->fourcc == V4L2_PIX_FMT_MM21)
+			ret = false;
+		break;
+	default:
+		ret = true;
+		break;
+	};
+
+	return ret;
+}
+
 static struct mtk_q_data *mtk_vdec_get_q_data(struct mtk_vcodec_ctx *ctx,
 					      enum v4l2_buf_type type)
 {
@@ -578,6 +616,9 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, void *priv,
 		    dec_pdata->vdec_formats[i].type != MTK_FMT_FRAME)
 			continue;
 
+		if (!output_queue && !mtk_vdec_get_cap_fmt(ctx, i))
+			continue;
+
 		if (j == f->index)
 			break;
 		++j;
-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:40 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:40 +0800
Subject: [PATCH v2,
 7/7] media: mtk-vcodec: Add to support H264 inner racing mode
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-8-yunfei.dong@mediatek.com>

In order to reduce decoder latency, enable H264 inner racing mode.

Send lat trans buffer information to core when trigger lat to work,
need not to wait until lat decode done.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
---
 .../platform/mtk-vcodec/mtk_vcodec_dec_drv.c  |  4 +++
 .../platform/mtk-vcodec/mtk_vcodec_dec_pm.c   | 34 +++++++++++++++++++
 .../platform/mtk-vcodec/mtk_vcodec_drv.h      | 10 ++++++
 .../mtk-vcodec/vdec/vdec_h264_req_multi_if.c  | 23 ++++++++++---
 4 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
index 938bf14e4e8c..099dc28b7445 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_drv.c
@@ -390,6 +390,10 @@ static int mtk_vcodec_probe(struct platform_device *pdev)
 		}
 	}
 
+	atomic_set(&dev->dec_active_cnt, 0);
+	memset(dev->vdec_racing_info, 0 , sizeof(dev->vdec_racing_info));
+	mutex_init(&dev->dec_racing_info_mutex);
+
 	if (dev->vdec_pdata->uses_stateless_api) {
 		dev->mdev_dec.dev = &pdev->dev;
 		strscpy(dev->mdev_dec.model, MTK_VCODEC_DEC_NAME,
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
index 76e1442fc6f9..065d14a3d11f 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_pm.c
@@ -173,6 +173,34 @@ static void mtk_vcodec_dec_disable_irq(struct mtk_vcodec_dev *vdec_dev, int hw_i
 	}
 }
 
+static void mtk_vcodec_load_racing_info(struct mtk_vcodec_ctx *ctx)
+{
+	void __iomem *vdec_racing_addr;
+	int j;
+
+	mutex_lock(&ctx->dev->dec_racing_info_mutex);
+	if (atomic_inc_return(&ctx->dev->dec_active_cnt) == 1) {
+		vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100;
+		for (j = 0; j < 132; j++)
+			writel(ctx->dev->vdec_racing_info[j], vdec_racing_addr + j * 4);
+	}
+	mutex_unlock(&ctx->dev->dec_racing_info_mutex);
+}
+
+static void mtk_vcodec_record_racing_info(struct mtk_vcodec_ctx *ctx)
+{
+	void __iomem *vdec_racing_addr;
+	int j;
+
+	mutex_lock(&ctx->dev->dec_racing_info_mutex);
+	if (atomic_dec_and_test(&ctx->dev->dec_active_cnt)) {
+		vdec_racing_addr = ctx->dev->reg_base[VDEC_MISC] + 0x100;
+		for (j = 0; j < 132; j++)
+			ctx->dev->vdec_racing_info[j] = readl(vdec_racing_addr + j * 4);
+	}
+	mutex_unlock(&ctx->dev->dec_racing_info_mutex);
+}
+
 static struct mtk_vcodec_pm *mtk_vcodec_dec_get_pm(struct mtk_vcodec_dev *vdec_dev,
 						   int hw_idx)
 {
@@ -243,11 +271,17 @@ void mtk_vcodec_dec_enable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
 	mtk_vcodec_dec_child_dev_on(ctx->dev, hw_idx);
 
 	mtk_vcodec_dec_enable_irq(ctx->dev, hw_idx);
+
+	if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
+		mtk_vcodec_load_racing_info(ctx);
 }
 EXPORT_SYMBOL_GPL(mtk_vcodec_dec_enable_hardware);
 
 void mtk_vcodec_dec_disable_hardware(struct mtk_vcodec_ctx *ctx, int hw_idx)
 {
+	if (IS_VDEC_INNER_RACING(ctx->dev->dec_capability))
+		mtk_vcodec_record_racing_info(ctx);
+
 	mtk_vcodec_dec_disable_irq(ctx->dev, hw_idx);
 
 	mtk_vcodec_dec_child_dev_off(ctx->dev, hw_idx);
diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
index 363b999dd709..4d6ace869b5a 100644
--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
+++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
@@ -28,6 +28,7 @@
 #define MTK_V4L2_BENCHMARK	0
 #define WAIT_INTR_TIMEOUT_MS	1000
 #define IS_VDEC_LAT_ARCH(hw_arch) ((hw_arch) >= MTK_VDEC_LAT_SINGLE_CORE)
+#define IS_VDEC_INNER_RACING(capability) (capability & MTK_VCODEC_INNER_RACING)
 
 /*
  * enum mtk_hw_reg_idx - MTK hw register base index
@@ -360,6 +361,7 @@ enum mtk_vdec_format_types {
 	MTK_VDEC_FORMAT_H264_SLICE = 0x100,
 	MTK_VDEC_FORMAT_VP8_FRAME = 0x200,
 	MTK_VDEC_FORMAT_VP9_FRAME = 0x400,
+	MTK_VCODEC_INNER_RACING = 0x20000,
 };
 
 /**
@@ -480,6 +482,10 @@ struct mtk_vcodec_enc_pdata {
  * @subdev_dev: subdev hardware device
  * @subdev_prob_done: check whether all used hw device is prob done
  * @subdev_bitmap: used to record hardware is ready or not
+ *
+ * @dec_active_cnt: used to mark whether need to record register value
+ * @vdec_racing_info: record register value
+ * @dec_racing_info_mutex: mutex lock used for inner racing mode
  */
 struct mtk_vcodec_dev {
 	struct v4l2_device v4l2_dev;
@@ -525,6 +531,10 @@ struct mtk_vcodec_dev {
 	void *subdev_dev[MTK_VDEC_HW_MAX];
 	int (*subdev_prob_done)(struct mtk_vcodec_dev *vdec_dev);
 	DECLARE_BITMAP(subdev_bitmap, MTK_VDEC_HW_MAX);
+
+	atomic_t dec_active_cnt;
+	u32 vdec_racing_info[132];
+	struct mutex dec_racing_info_mutex;
 };
 
 static inline struct mtk_vcodec_ctx *fh_to_ctx(struct v4l2_fh *fh)
diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
index 5541edbafed2..988d1d12d5c8 100644
--- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
+++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_multi_if.c
@@ -617,6 +617,17 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 		goto err_free_fb_out;
 	}
 
+	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
+		inst->vsi->wdma_end_addr_offset;
+	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
+	share_info->nal_info = inst->vsi->dec.nal_info;
+
+	if (IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
+		memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		       sizeof(share_info->h264_slice_params));
+		vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	}
+
 	/* wait decoder done interrupt */
 	timeout = mtk_vcodec_wait_for_done_ctx(inst->ctx, MTK_INST_IRQ_RECEIVED,
 					       WAIT_INTR_TIMEOUT_MS, MTK_VDEC_LAT0);
@@ -630,14 +641,16 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
 
 	share_info->trans_end = inst->ctx->msg_queue.wdma_addr.dma_addr +
 		inst->vsi->wdma_end_addr_offset;
-	share_info->trans_start = inst->ctx->msg_queue.wdma_wptr_addr;
-	share_info->nal_info = inst->vsi->dec.nal_info;
 	vdec_msg_queue_update_ube_wptr(&lat_buf->ctx->msg_queue,
 				       share_info->trans_end);
 
-	memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
-	       sizeof(share_info->h264_slice_params));
-	vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	if (!IS_VDEC_INNER_RACING(inst->ctx->dev->dec_capability)) {
+		memcpy(&share_info->h264_slice_params, &inst->vsi->h264_slice_params,
+		       sizeof(share_info->h264_slice_params));
+		vdec_msg_queue_qbuf(&inst->ctx->dev->msg_queue_core_ctx, lat_buf);
+	}
+	mtk_vcodec_debug(inst, "lat crc: 0x%x 0x%x 0x%x", inst->vsi->dec.crc[0],
+			 inst->vsi->dec.crc[1], inst->vsi->dec.crc[2]);
 	inst->slice_dec_num++;
 
 err_free_fb_out:
-- 
2.25.1



From yunfei.dong at mediatek.com  Thu Jan 27 19:54:36 2022
From: yunfei.dong at mediatek.com (Yunfei Dong)
Date: Fri, 28 Jan 2022 11:54:36 +0800
Subject: [PATCH v2,
 3/7] dt-bindings: media: mtk-vcodec: Adds decoder dt-bindings for
 mt8195
In-Reply-To: <20220128035440.24533-1-yunfei.dong@mediatek.com>
References: <20220128035440.24533-1-yunfei.dong@mediatek.com>
Message-ID: <20220128035440.24533-4-yunfei.dong@mediatek.com>

Adds decoder dt-bindings for mt8195.

Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
Reviewed-by: Macpaul Lin <macpaul.lin at mediatek.com>
---
 .../bindings/media/mediatek,vcodec-subdev-decoder.yaml           | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
index a3c892338ac0..a2f2db29daed 100644
--- a/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
+++ b/Documentation/devicetree/bindings/media/mediatek,vcodec-subdev-decoder.yaml
@@ -50,6 +50,7 @@ properties:
     enum:
       - mediatek,mt8192-vcodec-dec
       - mediatek,mt8186-vcodec-dec
+      - mediatek,mt8195-vcodec-dec
 
   reg:
     maxItems: 1
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan 27 20:14:22 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 09:44:22 +0530
Subject: [RFC V1 10/11] perf: Expand perf_branch_entry.type
In-Reply-To: <2d7297b3-9a22-626b-9840-a4eaab4b94e8@arm.com>
References: <1642998653-21377-1-git-send-email-anshuman.khandual@arm.com>
 <1642998653-21377-11-git-send-email-anshuman.khandual@arm.com>
 <2d7297b3-9a22-626b-9840-a4eaab4b94e8@arm.com>
Message-ID: <17dc4a62-14d6-c0f2-b428-c1525411b1e0@arm.com>



On 1/25/22 10:28 PM, James Clark wrote:
> 
> On 24/01/2022 04:30, Anshuman Khandual wrote:
>> Current perf_branch_entry.type is a 4 bits field just enough to accommodate
>> 16 generic branch types. This is insufficient to accommodate platforms like
>> arm64 which has much more branch types. Lets just expands this field into a
>> 6 bits one, which can now hold 64 generic branch types. This also adds more
>> generic branch types and updates the BRBE driver as required.
>>
>> Cc: Peter Zijlstra <peterz at infradead.org>
>> Cc: Ingo Molnar <mingo at redhat.com>
>> Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
>> Cc: Mark Rutland <mark.rutland at arm.com>
>> Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
>> Cc: Jiri Olsa <jolsa at redhat.com>
>> Cc: Namhyung Kim <namhyung at kernel.org>
>> Cc: Will Deacon <will at kernel.org>
>> Cc: linux-arm-kernel at lists.infradead.org
>> Cc: linux-perf-users at vger.kernel.org
>> Cc: linux-kernel at vger.kernel.org
>> Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
>> ---
>>  drivers/perf/arm_pmu_brbe.c           |  7 ++++++-
>>  include/uapi/linux/perf_event.h       | 10 ++++++++--
>>  tools/include/uapi/linux/perf_event.h | 10 ++++++++--
>>  tools/perf/util/branch.c              |  8 +++++++-
>>  4 files changed, 29 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/perf/arm_pmu_brbe.c b/drivers/perf/arm_pmu_brbe.c
>> index 8d27ad868359..7cd1208c6c58 100644
>> --- a/drivers/perf/arm_pmu_brbe.c
>> +++ b/drivers/perf/arm_pmu_brbe.c
>> @@ -253,12 +253,17 @@ static int brbe_fetch_perf_type(u64 brbinf)
>>  	case BRBINF_TYPE_DEBUG_EXIT:
>>  		return PERF_BR_DEBUG_EXIT;
>>  	case BRBINF_TYPE_SERROR:
>> +		return PERF_BR_SERROR;
>>  	case BRBINF_TYPE_INST_DEBUG:
>> +		return PERF_BR_DEBUG_INST;
>>  	case BRBINF_TYPE_DATA_DEBUG:
>> +		return PERF_BR_DEBUG_DATA;
>>  	case BRBINF_TYPE_ALGN_FAULT:
>> +		return PERF_BR_FAULT_ALGN;
>>  	case BRBINF_TYPE_INST_FAULT:
>> +		return PERF_BR_FAULT_INST;
>>  	case BRBINF_TYPE_DATA_FAULT:
>> -		return PERF_BR_UNKNOWN;
>> +		return PERF_BR_FAULT_DATA;
>>  	default:
>>  		pr_warn("unknown branch type captured\n");
>>  		return PERF_BR_UNKNOWN;
>> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
>> index b91d0f575d0c..361fdc6b87a0 100644
>> --- a/include/uapi/linux/perf_event.h
>> +++ b/include/uapi/linux/perf_event.h
>> @@ -256,6 +256,12 @@ enum {
>>  	PERF_BR_FIQ		= 13,	/* fiq */
>>  	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
>>  	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
>> +	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
>> +	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
>> +	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
>> +	PERF_BR_FAULT_DATA	= 19,	/* data fault */
>> +	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
>> +	PERF_BR_SERROR		= 21,	/* system error */
>>  	PERF_BR_MAX,
>>  };
>>  
>> @@ -1370,8 +1376,8 @@ struct perf_branch_entry {
>>  		in_tx:1,    /* in transaction */
>>  		abort:1,    /* transaction abort */
>>  		cycles:16,  /* cycle count to last branch */
>> -		type:4,     /* branch type */
>> -		reserved:40;
>> +		type:6,     /* branch type */
>> +		reserved:38;
>>  };
>>  
>>  union perf_sample_weight {
>> diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
>> index 1882054e8684..9a82b8aaed93 100644
>> --- a/tools/include/uapi/linux/perf_event.h
>> +++ b/tools/include/uapi/linux/perf_event.h
>> @@ -256,6 +256,12 @@ enum {
>>  	PERF_BR_FIQ		= 13,	/* fiq */
>>  	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
>>  	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
>> +	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
>> +	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
>> +	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
>> +	PERF_BR_FAULT_DATA	= 19,	/* data fault */
>> +	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
>> +	PERF_BR_SERROR		= 21,	/* system error */
>>  	PERF_BR_MAX,
>>  };
>>  
>> @@ -1370,8 +1376,8 @@ struct perf_branch_entry {
>>  		in_tx:1,    /* in transaction */
>>  		abort:1,    /* transaction abort */
>>  		cycles:16,  /* cycle count to last branch */
>> -		type:4,     /* branch type */
>> -		reserved:40;
>> +		type:6,     /* branch type */
>> +		reserved:38;
>>  };
> There's another copy of this struct in branch.h that is used to access the same data in
> perf which also needs updating:
> 
> 	struct branch_flags {
> 		union {
> 			u64 value;
> 			struct {
> 				u64 mispred:1;
> 				u64 predicted:1;
> 				u64 in_tx:1;
> 				u64 abort:1;
> 				u64 cycles:16;
> 				u64 type:4;
> 				u64 reserved:40;
> 			};
> 		};
> 	};

Sure, thanks for the catch. Will fix it.

> 
> It's never assigned directly but there is some casting stuff going on in
> evsel__parse_sample() and it eventually ends up being used to access branch
> records. Same applies to the privilege data change.
> 

Okay, will do the necessary changes in the privilege data patch.


From nikhil.gupta at nxp.com  Thu Jan 27 20:23:21 2022
From: nikhil.gupta at nxp.com (nikhil.gupta at nxp.com)
Date: Fri, 28 Jan 2022 09:53:21 +0530
Subject: [PATCH] of/fdt: move elfcorehdr reservation early for crash dump
 kernel
Message-ID: <20220128042321.15228-1-nikhil.gupta@nxp.com>

From: Nikhil Gupta <nikhil.gupta at nxp.com>

elfcorehdr_addr is fixed address passed to Second kernel which may be conflicted
with potential reserved memory in Second kernel,so fdt_reserve_elfcorehdr() ahead
of fdt_init_reserved_mem() can relieve this situation.

Signed-off-by: Nikhil Gupta <nikhil.gupta at nxp.com>
---
elfcorehdr addr is calculated in kexec tool based on reserved crashkernel memory space. (Last page is used in top down order)
So It may potentially conflict the reserved memory in 2nd kernel.
Below is log:
load_crashdump_segments: page_offset:   ffffc00000000000
???..
load_crashdump_segments: elfcorehdr 0xf3fff000-0xf3fff3ff
read_1st_dtb: found /sys/firmware/fdt
get_cells_size: #address-cells:2 #size-cells:2
cells_size_fitted: f3fff000-f3fff3ff
cells_size_fitted: d4000000-f3ffffff

Overlaps seen on LS1043A SoC:

[    0.000000] memblock_reserve: [0x00000000d4010000-0x00000000d677ffff] arm64_memblock_init+0x258/0x2c8
[    0.000000] memblock_phys_alloc_range: 4194304 bytes align=0x400000 from=0x0000000000000000 max_addr=0x0001000000000000 early_init_dt_alloc_reserved_memory_arch+0x9c/0x16c
[    0.000000] memblock_reserve: [0x00000000f3c00000-0x00000000f3ffffff] memblock_alloc_range_nid+0xdc/0x150
[    0.000000] memblock_phys_alloc_range: 33554432 bytes align=0x2000000 from=0x0000000000000000 max_addr=0x0001000000000000 early_init_dt_alloc_reserved_memory_arch+0x9c/0x16c
[    0.000000] memblock_reserve: [0x00000000f0000000-0x00000000f1ffffff] memblock_alloc_range_nid+0xdc/0x150
[    0.000000] memblock_phys_alloc_range: 16777216 bytes align=0x1000000 from=0x0000000000000000 max_addr=0x0001000000000000 early_init_dt_alloc_reserved_memory_arch+0x9c/0x16c
[    0.000000] memblock_reserve: [0x00000000f2000000-0x00000000f2ffffff] memblock_alloc_range_nid+0xdc/0x150
[    0.000000] OF: reserved mem: initialized node bman-fbpr, compatible id fsl,bman-fbpr
[    0.000000] OF: fdt: elfcorehdr is overlapped

panic in elfcorehdr_read.
[    0.443984] Unable to handle kernel paging request at virtual address ffff000037fff000
[    0.451942] Mem abort info:
[    0.454740]   ESR = 0x96000006
[    0.457806]   EC = 0x25: DABT (current EL), IL = 32 bits
[    0.463142]   SET = 0, FnV = 0
[    0.466202]   EA = 0, S1PTW = 0
[    0.469353] Data abort info:
[    0.472243]   ISV = 0, ISS = 0x00000006
[    0.476094]   CM = 0, WnR = 0
[    0.479072] swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000d9373000
[    0.485806] [ffff000037fff000] pgd=00000000f7bf7003, pud=00000000f7bf6003, pmd=0000000000000000
[    0.494553] Internal error: Oops: 96000006 [#1] PREEMPT SMP
[    0.500146] Modules linked in:
[    0.503211] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.5.0-rc3-00062-gbf8d1cd #5
[    0.510725] Hardware name: LS1043A RDB Board (DT)
[    0.515446] pstate: 80000005 (Nzcv daif -PAN -UAO)
[    0.520260] pc : __memcpy+0x78/0x180
[    0.523847] lr : elfcorehdr_read+0x28/0x38
[    0.611262] Call trace:
[    0.613713]  __memcpy+0x78/0x180
[    0.616950]  vmcore_init+0x70/0x534
 drivers/of/fdt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index ad85ff6474ff..ec315b060cd5 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -648,8 +648,8 @@ void __init early_init_fdt_scan_reserved_mem(void)
 	}
 
 	fdt_scan_reserved_mem();
-	fdt_init_reserved_mem();
 	fdt_reserve_elfcorehdr();
+	fdt_init_reserved_mem();
 }
 
 /**
-- 
2.17.1



From hayashi.kunihiko at socionext.com  Thu Jan 27 20:24:19 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 28 Jan 2022 13:24:19 +0900
Subject: [PATCH 2/3] pinctrl: uniphier: Divide pinmux group to support 1ch
 and 2ch I2S
In-Reply-To: <202201280448.njc6LUNd-lkp@intel.com>
References: <1643283344-24911-3-git-send-email-hayashi.kunihiko@socionext.com>
 <202201280448.njc6LUNd-lkp@intel.com>
Message-ID: <66679643-05a3-a404-adac-a18f008d7e65@socionext.com>

On 2022/01/28 6:00, kernel test robot wrote:
> Hi Kunihiko,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on linusw-pinctrl/devel]
> [also build test ERROR on v5.17-rc1 next-20220127]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:
> https://github.com/0day-ci/linux/commits/Kunihiko-Hayashi/pinctrl-uniphier
> -Add-some-more-pinmux-settings/20220127-193715
> base:
> https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git
> devel
> config: openrisc-buildonly-randconfig-r003-20220124
> (https://download.01.org/0day-ci/archive/20220128/202201280448.njc6LUNd-lk
> p at intel.com/config)
> compiler: or1k-linux-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>          wget
> https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross
> -O ~/bin/make.cross
>          chmod +x ~/bin/make.cross
>          #
> https://github.com/0day-ci/linux/commit/e0e366a006b79517336423f8a2c7266117
> 8d5e41
>          git remote add linux-review https://github.com/0day-ci/linux
>          git fetch --no-tags linux-review
> Kunihiko-Hayashi/pinctrl-uniphier-Add-some-more-pinmux-settings/20220127-1
> 93715
>          git checkout e0e366a006b79517336423f8a2c72661178d5e41
>          # save the config file to linux build tree
>          mkdir build_dir
>          COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross
> O=build_dir ARCH=openrisc SHELL=/bin/bash
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All errors (new ones prefixed by >>):
> 
>     In file included from drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:
> 12:
>>> drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:34: error:
> 'aout4_groups' undeclared here (not in a function); did you mean
> 'aout3_groups'?
>       958 |         UNIPHIER_PINMUX_FUNCTION(aout4),
>           |                                  ^~~~~
>     drivers/pinctrl/uniphier/pinctrl-uniphier.h:179:27: note: in definition
> of macro 'UNIPHIER_PINMUX_FUNCTION'
>       179 |                 .groups = func##_groups,
> \
>           |                           ^~~~
>     In file included from include/linux/container_of.h:5,
>                      from include/linux/kernel.h:21,
>                      from drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:
> 6:
>>> include/linux/build_bug.h:16:51: error: bit-field '<anonymous>' width
> not an integer constant
>        16 | #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct {
> int:(-!!(e)); })))
>           |                                                   ^
>     include/linux/compiler.h:258:33: note: in expansion of macro
> 'BUILD_BUG_ON_ZERO'
>       258 | #define __must_be_array(a)
> BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
>           |                                 ^~~~~~~~~~~~~~~~~
>     include/linux/kernel.h:55:59: note: in expansion of macro
> '__must_be_array'
>        55 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) +
> __must_be_array(arr))
>           |
> ^~~~~~~~~~~~~~~
>     drivers/pinctrl/uniphier/pinctrl-uniphier.h:180:31: note: in expansion
> of macro 'ARRAY_SIZE'
>       180 |                 .num_groups = ARRAY_SIZE(func##_groups),
> \
>           |                               ^~~~~~~~~~
>     drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c:958:9: note: in
> expansion of macro 'UNIPHIER_PINMUX_FUNCTION'
>       958 |         UNIPHIER_PINMUX_FUNCTION(aout4),
>           |         ^~~~~~~~~~~~~~~~~~~~~~~~
> 
> 
> vim +958 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
> 
>     949	
>     950	static const struct uniphier_pinmux_function
> uniphier_pxs2_functions[] = {
>     951		UNIPHIER_PINMUX_FUNCTION(ain1),
>     952		UNIPHIER_PINMUX_FUNCTION(ain2),
>     953		UNIPHIER_PINMUX_FUNCTION(ain3),
>     954		UNIPHIER_PINMUX_FUNCTION(ainiec1),
>     955		UNIPHIER_PINMUX_FUNCTION(aout1),
>     956		UNIPHIER_PINMUX_FUNCTION(aout2),
>     957		UNIPHIER_PINMUX_FUNCTION(aout3),
>   > 958		UNIPHIER_PINMUX_FUNCTION(aout4),

The aout4 function doesn't exist now. I'll remove them in next.

Thank you,

>     959		UNIPHIER_PINMUX_FUNCTION(aoutiec1),
>     960		UNIPHIER_PINMUX_FUNCTION(aoutiec2),
>     961		UNIPHIER_PINMUX_FUNCTION(emmc),
>     962		UNIPHIER_PINMUX_FUNCTION(ether_mii),
>     963		UNIPHIER_PINMUX_FUNCTION(ether_rgmii),
>     964		UNIPHIER_PINMUX_FUNCTION(ether_rmii),
>     965		UNIPHIER_PINMUX_FUNCTION(i2c0),
>     966		UNIPHIER_PINMUX_FUNCTION(i2c1),
>     967		UNIPHIER_PINMUX_FUNCTION(i2c2),
>     968		UNIPHIER_PINMUX_FUNCTION(i2c3),
>     969		UNIPHIER_PINMUX_FUNCTION(i2c5),
>     970		UNIPHIER_PINMUX_FUNCTION(i2c6),
>     971		UNIPHIER_PINMUX_FUNCTION(nand),
>     972		UNIPHIER_PINMUX_FUNCTION(sd),
>     973		UNIPHIER_PINMUX_FUNCTION(spi0),
>     974		UNIPHIER_PINMUX_FUNCTION(spi1),
>     975		UNIPHIER_PINMUX_FUNCTION(system_bus),
>     976		UNIPHIER_PINMUX_FUNCTION(uart0),
>     977		UNIPHIER_PINMUX_FUNCTION(uart1),
>     978		UNIPHIER_PINMUX_FUNCTION(uart2),
>     979		UNIPHIER_PINMUX_FUNCTION(uart3),
>     980		UNIPHIER_PINMUX_FUNCTION(usb0),
>     981		UNIPHIER_PINMUX_FUNCTION(usb1),
>     982		UNIPHIER_PINMUX_FUNCTION(usb2),
>     983		UNIPHIER_PINMUX_FUNCTION(usb3),
>     984	};
>     985	
> 
> ---
> 0-DAY CI Kernel Test Service, Intel Corporation
> https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org
> 

-- 
---
Best Regards
Kunihiko Hayashi


From herbert at gondor.apana.org.au  Thu Jan 27 20:42:38 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 28 Jan 2022 15:42:38 +1100
Subject: [PATCH v4 6/6] crypto: tcrypt - add asynchronous speed test for
 SM3
In-Reply-To: <20220107120700.730-7-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
 <20220107120700.730-7-tianjia.zhang@linux.alibaba.com>
Message-ID: <YfN0PsCAXYo0Hx9T@gondor.apana.org.au>

On Fri, Jan 07, 2022 at 08:07:00PM +0800, Tianjia Zhang wrote:
> tcrypt supports testing of SM3 hash algorithms that use AVX
> instruction acceleration.
> 
> In order to add the sm3 asynchronous test to the appropriate
> position, shift the testcase sequence number of the multi buffer
> backward and start from 450.
> 
> Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
> ---
>  crypto/tcrypt.c | 14 +++++++++-----
>  1 file changed, 9 insertions(+), 5 deletions(-)

This is not an issue with your patch but we should delete all
the mb hash tests as the mb hash algorithm tself was removed
in 2018.

Thanks,
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From ck.hu at mediatek.com  Thu Jan 27 21:03:55 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 28 Jan 2022 13:03:55 +0800
Subject: [v1, 3/3] drm/mediatek: Move the getting bridge node function
 to mtk_dsi_bind
In-Reply-To: <1643283773-7081-4-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
 <1643283773-7081-4-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <092258211c47eca805c4dea6c4bf4ecc4c246cea.camel@mediatek.com>

Hi, Xinlei:

On Thu, 2022-01-27 at 19:42 +0800, xinlei.lee at mediatek.com wrote:
> From: xinlei lee <xinlei.lee at mediatek.com>
> 
> The order of probe function for bridge drivers and dsi drivers is
> uncertain.
> To avoid the dsi probe cannot be executed, we place getting bridge
> node function in
> mtk_dsi_bind.

It seems this patch want to fix the same problem as [1]. Does [1] fix
your problem? If so, let's ignore this patch.

[1] 
https://patchwork.kernel.org/project/linux-mediatek/patch/20220127143623.123025-1-angelogioacchino.delregno at collabora.com/

Regards,
CK

> 
> Signed-off-by:Xinlei Lee <xinlei.lee at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 29 +++++++++++++++-------------
> -
>  1 file changed, 15 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index 62af60d..a390f26 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -991,6 +991,21 @@ static int mtk_dsi_bind(struct device *dev,
> struct device *master, void *data)
>  	int ret;
>  	struct drm_device *drm = data;
>  	struct mtk_dsi *dsi = dev_get_drvdata(dev);
> +	struct drm_panel *panel;
> +
> +	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> +					  &panel, &dsi->next_bridge);
> +	if (ret)
> +		return ret;
> +
> +	if (panel) {
> +		dsi->next_bridge = devm_drm_panel_bridge_add(dev,
> panel);
> +		if (IS_ERR(dsi->next_bridge)) {
> +			ret = PTR_ERR(dsi->next_bridge);
> +			dev_err(dev, "failed to add bridge: %d\n",
> ret);
> +			return ret;
> +		}
> +	}
>  
>  	ret = mtk_dsi_encoder_init(drm, dsi);
>  	if (ret)
> @@ -1016,7 +1031,6 @@ static int mtk_dsi_probe(struct platform_device
> *pdev)
>  {
>  	struct mtk_dsi *dsi;
>  	struct device *dev = &pdev->dev;
> -	struct drm_panel *panel;
>  	struct resource *regs;
>  	int irq_num;
>  	int ret;
> @@ -1033,19 +1047,6 @@ static int mtk_dsi_probe(struct
> platform_device *pdev)
>  		return ret;
>  	}
>  
> -	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
> -					  &panel, &dsi->next_bridge);
> -	if (ret)
> -		goto err_unregister_host;
> -
> -	if (panel) {
> -		dsi->next_bridge = devm_drm_panel_bridge_add(dev,
> panel);
> -		if (IS_ERR(dsi->next_bridge)) {
> -			ret = PTR_ERR(dsi->next_bridge);
> -			goto err_unregister_host;
> -		}
> -	}
> -
>  	dsi->driver_data = of_device_get_match_data(dev);
>  
>  	dsi->engine_clk = devm_clk_get(dev, "engine");



From ck.hu at mediatek.com  Thu Jan 27 21:08:03 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 28 Jan 2022 13:08:03 +0800
Subject: [v1, 1/3] dt-bindings: display: mediatek: dsi: add
 documentation for MT8186 SoC
In-Reply-To: <1643283773-7081-2-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
 <1643283773-7081-2-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <846d50400a14129c5ff7f7acb2b23f9f4658d11f.camel@mediatek.com>

Hi, Xinlei:

On Thu, 2022-01-27 at 19:42 +0800, xinlei.lee at mediatek.com wrote:
> From: xinlei lee <xinlei.lee at mediatek.com>
> 
> Add binding documentation for the MT8186 SoC.

DPI has a yaml format document, so I would like DSI also has a yaml
format document.
Please send a patch to transfer DSI document to yaml, and then apply
this patch to yaml document.

Regards,
CK

> 
> Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
> ---
>  Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> index 36b0145..c82b8b2 100644
> ---
> a/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> +++
> b/Documentation/devicetree/bindings/display/mediatek/mediatek,dsi.txt
> @@ -7,7 +7,7 @@ channel output.
>  
>  Required properties:
>  - compatible: "mediatek,<chip>-dsi"
> -- the supported chips are mt2701, mt7623, mt8167, mt8173 and mt8183.
> +- the supported chips are mt2701, mt7623, mt8167, mt8173, mt8183 and
> mt8186.
>  - reg: Physical base address and length of the controller's
> registers
>  - interrupts: The interrupt signal from the function block.
>  - clocks: device clocks



From ck.hu at mediatek.com  Thu Jan 27 21:10:00 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 28 Jan 2022 13:10:00 +0800
Subject: [v1,2/3] drm/mediatek: Add mt8186 dsi compatible to mtk_dsi.c
In-Reply-To: <1643283773-7081-3-git-send-email-xinlei.lee@mediatek.com>
References: <1643283773-7081-1-git-send-email-xinlei.lee@mediatek.com>
 <1643283773-7081-3-git-send-email-xinlei.lee@mediatek.com>
Message-ID: <2a5d1498b29f4cf74160e1881e530f34cd69e263.camel@mediatek.com>

Hi, Xinlei:

On Thu, 2022-01-27 at 19:42 +0800, xinlei.lee at mediatek.com wrote:
> From: xinlei lee <xinlei.lee at mediatek.com>
> 
> Add the compatible of mt8186-dsi because we use different cmdq
> addresses in mt8186.

Reviewed-by: CK Hu <ck.hu at mediatek.com>

> 
> Signed-off-by: Xinlei Lee <xinlei.lee at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index e91b3ff..62af60d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -1151,6 +1151,12 @@ static const struct mtk_dsi_driver_data
> mt8183_dsi_driver_data = {
>  	.has_size_ctl = true,
>  };
>  
> +static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
> +	.reg_cmdq_off = 0xd00,
> +	.has_shadow_ctl = true,
> +	.has_size_ctl = true,
> +};
> +
>  static const struct of_device_id mtk_dsi_of_match[] = {
>  	{ .compatible = "mediatek,mt2701-dsi",
>  	  .data = &mt2701_dsi_driver_data },
> @@ -1158,6 +1164,8 @@ static const struct of_device_id
> mtk_dsi_of_match[] = {
>  	  .data = &mt8173_dsi_driver_data },
>  	{ .compatible = "mediatek,mt8183-dsi",
>  	  .data = &mt8183_dsi_driver_data },
> +	{ .compatible = "mediatek,mt8186-dsi",
> +	  .data = &mt8186_dsi_driver_data },
>  	{ },
>  };
>  MODULE_DEVICE_TABLE(of, mtk_dsi_of_match);



From reijiw at google.com  Thu Jan 27 21:40:15 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 27 Jan 2022 21:40:15 -0800
Subject: [RFC PATCH v4 22/26] KVM: arm64: Trap disabled features of
 ID_AA64DFR0_EL1
In-Reply-To: <CA+EHjTyimL8nuE0gH8B3V-MzoA9rz+n3KazqFxMtdJKgjefAag@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-23-reijiw@google.com>
 <CA+EHjTyimL8nuE0gH8B3V-MzoA9rz+n3KazqFxMtdJKgjefAag@mail.gmail.com>
Message-ID: <CAAeT=Fw5LC559c=NxSp8xk1WO0CkD-DoJd-sACf78Uf6Yu1nMA@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 9:20 AM Fuad Tabba <tabba at google.com> wrote:
>
> .Hi Reiji,
>
> On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Add feature_config_ctrl for PMUv3, PMS and TraceFilt, which are
> > indicated in ID_AA64DFR0_EL1, to program configuration registers
> > to trap guest's using those features when they are not exposed to
> > the guest.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 47 +++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 47 insertions(+)
> >
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 72e745c5a9c2..229671ec3abd 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -349,6 +349,22 @@ static void feature_mte_trap_activate(struct kvm_vcpu *vcpu)
> >         feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TID5, HCR_DCT | HCR_ATA);
> >  }
> >
> > +static void feature_pmuv3_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPM, 0);
>
> I think that for full coverage it might be good to include setting
> MDCR_EL2_TPMCR, and clearing MDCR_EL2_HPME | MDCR_EL2_MTPME |
> MDCR_EL2_HPMN_MASK, even if redundant at this point.

I included what is needed only, and I would prefer not to let KVM
do things that are not needed to trap guest's using the feature.
Please let me know if you have a specific reason why you think it
would be better to include them.

>
> > +}
> > +
> > +static void feature_pms_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TPMS,
> > +                             MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT);
> > +}
> > +
> > +static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
> > +}
> > +
> >  /* For ID_AA64PFR0_EL1 */
> >  static struct feature_config_ctrl ftr_ctrl_ras = {
> >         .ftr_reg = SYS_ID_AA64PFR0_EL1,
> > @@ -375,6 +391,31 @@ static struct feature_config_ctrl ftr_ctrl_mte = {
> >         .trap_activate = feature_mte_trap_activate,
> >  };
> >
> > +/* For ID_AA64DFR0_EL1 */
> > +static struct feature_config_ctrl ftr_ctrl_pmuv3 = {
> > +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> > +       .ftr_shift = ID_AA64DFR0_PMUVER_SHIFT,
> > +       .ftr_min = ID_AA64DFR0_PMUVER_8_0,
> > +       .ftr_signed = FTR_UNSIGNED,
> > +       .trap_activate = feature_pmuv3_trap_activate,
> > +};
> > +
> > +static struct feature_config_ctrl ftr_ctrl_pms = {
> > +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> > +       .ftr_shift = ID_AA64DFR0_PMSVER_SHIFT,
> > +       .ftr_min = ID_AA64DFR0_PMSVER_8_2,
> > +       .ftr_signed = FTR_UNSIGNED,
> > +       .trap_activate = feature_pms_trap_activate,
> > +};
> > +
> > +static struct feature_config_ctrl ftr_ctrl_tracefilt = {
> > +       .ftr_reg = SYS_ID_AA64DFR0_EL1,
> > +       .ftr_shift = ID_AA64DFR0_TRACE_FILT_SHIFT,
> > +       .ftr_min = 1,
> > +       .ftr_signed = FTR_UNSIGNED,
> > +       .trap_activate = feature_tracefilt_trap_activate,
> > +};
>
> I think you might be missing trace, ID_AA64DFR0_TRACEVER -> CPTR_EL2_TTA.

Thank you for catching this. I will add the trace.

Thanks,
Reiji


From reijiw at google.com  Thu Jan 27 21:43:21 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 27 Jan 2022 21:43:21 -0800
Subject: [RFC PATCH v4 23/26] KVM: arm64: Trap disabled features of
 ID_AA64MMFR1_EL1
In-Reply-To: <CA+EHjTxYqPvyUz96hoJWe43raST1X7oKhdR7PeZDuwuuD9QcYQ@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-24-reijiw@google.com>
 <CA+EHjTxYqPvyUz96hoJWe43raST1X7oKhdR7PeZDuwuuD9QcYQ@mail.gmail.com>
Message-ID: <CAAeT=FxKgH_a7vthT3ai_TiCu9UCj+PNJ6SarHDF+R5tcR--Dg@mail.gmail.com>

Hi Fuad,

On Mon, Jan 24, 2022 at 9:38 AM Fuad Tabba <tabba at google.com> wrote:
>
> Hi Reiji,
>
> The series might be missing an entry for ID_AA64MMFR0_EL1, Debug
> Communications Channel registers, ID_AA64MMFR0_FGT -> MDCR_EL2_TDCC.

I will add them in v5 series.
Thank you so much for all the review comments!

Thanks,
Reiji


>
> Cheers,
> /fuad
>
>
> On Thu, Jan 6, 2022 at 4:29 AM Reiji Watanabe <reijiw at google.com> wrote:
> >
> > Add feature_config_ctrl for LORegions, which is indicated in
> > ID_AA64MMFR1_EL1, to program configuration register to trap
> > guest's using the feature when it is not exposed to the guest.
> >
> > Change trap_loregion() to use vcpu_feature_is_available()
> > to simplify checking of the feature's availability.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/kvm/sys_regs.c | 26 ++++++++++++++++++++++++--
> >  1 file changed, 24 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index 229671ec3abd..f8a5ee927ecf 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -365,6 +365,11 @@ static void feature_tracefilt_trap_activate(struct kvm_vcpu *vcpu)
> >         feature_trap_activate(vcpu, VCPU_MDCR_EL2, MDCR_EL2_TTRF, 0);
> >  }
> >
> > +static void feature_lor_trap_activate(struct kvm_vcpu *vcpu)
> > +{
> > +       feature_trap_activate(vcpu, VCPU_HCR_EL2, HCR_TLOR, 0);
> > +}
> > +
> >  /* For ID_AA64PFR0_EL1 */
> >  static struct feature_config_ctrl ftr_ctrl_ras = {
> >         .ftr_reg = SYS_ID_AA64PFR0_EL1,
> > @@ -416,6 +421,15 @@ static struct feature_config_ctrl ftr_ctrl_tracefilt = {
> >         .trap_activate = feature_tracefilt_trap_activate,
> >  };
> >
> > +/* For ID_AA64MMFR1_EL1 */
> > +static struct feature_config_ctrl ftr_ctrl_lor = {
> > +       .ftr_reg = SYS_ID_AA64MMFR1_EL1,
> > +       .ftr_shift = ID_AA64MMFR1_LOR_SHIFT,
> > +       .ftr_min = 1,
> > +       .ftr_signed = FTR_UNSIGNED,
> > +       .trap_activate = feature_lor_trap_activate,
> > +};
> > +
> >  struct id_reg_info {
> >         u32     sys_reg;        /* Register ID */
> >         u64     sys_val;        /* Sanitized system value */
> > @@ -947,6 +961,14 @@ static struct id_reg_info id_aa64dfr0_el1_info = {
> >         },
> >  };
> >
> > +static struct id_reg_info id_aa64mmfr1_el1_info = {
> > +       .sys_reg = SYS_ID_AA64MMFR1_EL1,
> > +       .trap_features = &(const struct feature_config_ctrl *[]) {
> > +               &ftr_ctrl_lor,
> > +               NULL,
> > +       },
> > +};
> > +
> >  static struct id_reg_info id_dfr0_el1_info = {
> >         .sys_reg = SYS_ID_DFR0_EL1,
> >         .init = init_id_dfr0_el1_info,
> > @@ -976,6 +998,7 @@ static struct id_reg_info *id_reg_info_table[KVM_ARM_ID_REG_MAX_NUM] = {
> >         [IDREG_IDX(SYS_ID_AA64ISAR0_EL1)] = &id_aa64isar0_el1_info,
> >         [IDREG_IDX(SYS_ID_AA64ISAR1_EL1)] = &id_aa64isar1_el1_info,
> >         [IDREG_IDX(SYS_ID_AA64MMFR0_EL1)] = &id_aa64mmfr0_el1_info,
> > +       [IDREG_IDX(SYS_ID_AA64MMFR1_EL1)] = &id_aa64mmfr1_el1_info,
> >  };
> >
> >  static int validate_id_reg(struct kvm_vcpu *vcpu, u32 id, u64 val)
> > @@ -1050,10 +1073,9 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
> >                           struct sys_reg_params *p,
> >                           const struct sys_reg_desc *r)
> >  {
> > -       u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
> >         u32 sr = reg_to_encoding(r);
> >
> > -       if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> > +       if (!vcpu_feature_is_available(vcpu, &ftr_ctrl_lor)) {
> >                 kvm_inject_undefined(vcpu);
> >                 return false;
> >         }
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >
> > _______________________________________________
> > kvmarm mailing list
> > kvmarm at lists.cs.columbia.edu
> > https://lists.cs.columbia.edu/mailman/listinfo/kvmarm


From anshuman.khandual at arm.com  Thu Jan 27 21:44:11 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 11:14:11 +0530
Subject: [PATCH 0/2] perf: Expand captured branch types
Message-ID: <1643348653-24367-1-git-send-email-anshuman.khandual@arm.com>

Branch Record Buffer Extension (BRBE) implementation on arm64 captures more
branch type classification which cannot be accommodated in the current perf
branch record format via perf_branch_entry.type element. To overcome this
limitation, perf_branch_entry.type needs to be expanded along with generic
branch classification.

This series achieves this expansion. But before that it adds more generic
branch classification types which can be accommodated without any changes,
while also updating the x86 implementation as required.

This series applies on v5.17-rc1

Please find BRBE captured branch type classification reference here.

https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/
BRBINF-n--EL1--Branch-Record-Buffer-Information-Register--n-?lang=en

Proposed perf branch stack enablement on arm64 platform can be found here.

https://lore.kernel.org/all/1642998653-21377-1-git-send-email-anshuman.khandual at arm.com/

These patches are split from the above series (PATCH 9/11, PATCH 10/11) as
these perf changes are pre-requisite for BRBE enablement. Although there is
another proposal (PATCH 11/11), extending struct perf_branch_entry further
to capture branch record privilege level information (priv, 2 bits), it is
not included here. But please do let me know if that proposal should also
be discussed in this series. Thank you.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org

Anshuman Khandual (2):
  perf: Add more generic branch types
  perf: Expand perf_branch_entry.type

 arch/x86/events/intel/lbr.c           |  4 ++--
 include/uapi/linux/perf_event.h       | 15 +++++++++++++--
 tools/include/uapi/linux/perf_event.h | 15 +++++++++++++--
 tools/perf/util/branch.c              | 13 ++++++++++++-
 tools/perf/util/branch.h              |  4 ++--
 5 files changed, 42 insertions(+), 9 deletions(-)

-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan 27 21:44:12 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 11:14:12 +0530
Subject: [PATCH 1/2] perf: Add more generic branch types
In-Reply-To: <1643348653-24367-1-git-send-email-anshuman.khandual@arm.com>
References: <1643348653-24367-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643348653-24367-2-git-send-email-anshuman.khandual@arm.com>

This expands generic branch type classification by adding some more entries
, that can still be represented with the existing 4 bit 'type' field. While
here this also updates the x86 implementation with these new branch types.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 arch/x86/events/intel/lbr.c           | 4 ++--
 include/uapi/linux/perf_event.h       | 5 +++++
 tools/include/uapi/linux/perf_event.h | 5 +++++
 tools/perf/util/branch.c              | 7 ++++++-
 4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/arch/x86/events/intel/lbr.c b/arch/x86/events/intel/lbr.c
index 8043213b75a5..9f86fac8c6a5 100644
--- a/arch/x86/events/intel/lbr.c
+++ b/arch/x86/events/intel/lbr.c
@@ -1336,10 +1336,10 @@ static int branch_map[X86_BR_TYPE_MAP_MAX] = {
 	PERF_BR_SYSCALL,	/* X86_BR_SYSCALL */
 	PERF_BR_SYSRET,		/* X86_BR_SYSRET */
 	PERF_BR_UNKNOWN,	/* X86_BR_INT */
-	PERF_BR_UNKNOWN,	/* X86_BR_IRET */
+	PERF_BR_EXPT_RET,	/* X86_BR_IRET */
 	PERF_BR_COND,		/* X86_BR_JCC */
 	PERF_BR_UNCOND,		/* X86_BR_JMP */
-	PERF_BR_UNKNOWN,	/* X86_BR_IRQ */
+	PERF_BR_IRQ,		/* X86_BR_IRQ */
 	PERF_BR_IND_CALL,	/* X86_BR_IND_CALL */
 	PERF_BR_UNKNOWN,	/* X86_BR_ABORT */
 	PERF_BR_UNKNOWN,	/* X86_BR_IN_TX */
diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042ab1db..b91d0f575d0c 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -251,6 +251,11 @@ enum {
 	PERF_BR_SYSRET		= 8,	/* syscall return */
 	PERF_BR_COND_CALL	= 9,	/* conditional function call */
 	PERF_BR_COND_RET	= 10,	/* conditional function return */
+	PERF_BR_EXPT_RET	= 11,	/* exception return */
+	PERF_BR_IRQ		= 12,	/* irq */
+	PERF_BR_FIQ		= 13,	/* fiq */
+	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
+	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
 	PERF_BR_MAX,
 };
 
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 4cd39aaccbe7..1882054e8684 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -251,6 +251,11 @@ enum {
 	PERF_BR_SYSRET		= 8,	/* syscall return */
 	PERF_BR_COND_CALL	= 9,	/* conditional function call */
 	PERF_BR_COND_RET	= 10,	/* conditional function return */
+	PERF_BR_EXPT_RET	= 11,	/* exception return */
+	PERF_BR_IRQ		= 12,	/* irq */
+	PERF_BR_FIQ		= 13,	/* fiq */
+	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
+	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
 	PERF_BR_MAX,
 };
 
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index 2285b1eb3128..74e5e67b1779 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -49,7 +49,12 @@ const char *branch_type_name(int type)
 		"SYSCALL",
 		"SYSRET",
 		"COND_CALL",
-		"COND_RET"
+		"COND_RET",
+		"EXPT_RET",
+		"IRQ",
+		"FIQ",
+		"DEBUG_HALT",
+		"DEBUG_EXIT"
 	};
 
 	if (type >= 0 && type < PERF_BR_MAX)
-- 
2.25.1



From anshuman.khandual at arm.com  Thu Jan 27 21:44:13 2022
From: anshuman.khandual at arm.com (Anshuman Khandual)
Date: Fri, 28 Jan 2022 11:14:13 +0530
Subject: [PATCH 2/2] perf: Expand perf_branch_entry.type
In-Reply-To: <1643348653-24367-1-git-send-email-anshuman.khandual@arm.com>
References: <1643348653-24367-1-git-send-email-anshuman.khandual@arm.com>
Message-ID: <1643348653-24367-3-git-send-email-anshuman.khandual@arm.com>

Current perf_branch_entry.type is a 4 bits field just enough to accommodate
16 generic branch types. This is insufficient to accommodate platforms like
arm64 which has much more branch types. Lets just expands this field into a
6 bits one, which can now hold 64 generic branch types. This also adds more
generic branch types.

Cc: Peter Zijlstra <peterz at infradead.org>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Arnaldo Carvalho de Melo <acme at kernel.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Alexander Shishkin <alexander.shishkin at linux.intel.com>
Cc: Jiri Olsa <jolsa at redhat.com>
Cc: Namhyung Kim <namhyung at kernel.org>
Cc: Will Deacon <will at kernel.org>
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-perf-users at vger.kernel.org
Cc: linux-kernel at vger.kernel.org
Signed-off-by: Anshuman Khandual <anshuman.khandual at arm.com>
---
 include/uapi/linux/perf_event.h       | 10 ++++++++--
 tools/include/uapi/linux/perf_event.h | 10 ++++++++--
 tools/perf/util/branch.c              |  8 +++++++-
 tools/perf/util/branch.h              |  4 ++--
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index b91d0f575d0c..361fdc6b87a0 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -256,6 +256,12 @@ enum {
 	PERF_BR_FIQ		= 13,	/* fiq */
 	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
 	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
+	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
+	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
+	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
+	PERF_BR_FAULT_DATA	= 19,	/* data fault */
+	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
+	PERF_BR_SERROR		= 21,	/* system error */
 	PERF_BR_MAX,
 };
 
@@ -1370,8 +1376,8 @@ struct perf_branch_entry {
 		in_tx:1,    /* in transaction */
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
-		type:4,     /* branch type */
-		reserved:40;
+		type:6,     /* branch type */
+		reserved:38;
 };
 
 union perf_sample_weight {
diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h
index 1882054e8684..9a82b8aaed93 100644
--- a/tools/include/uapi/linux/perf_event.h
+++ b/tools/include/uapi/linux/perf_event.h
@@ -256,6 +256,12 @@ enum {
 	PERF_BR_FIQ		= 13,	/* fiq */
 	PERF_BR_DEBUG_HALT	= 14,	/* debug halt */
 	PERF_BR_DEBUG_EXIT	= 15,	/* debug exit */
+	PERF_BR_DEBUG_INST	= 16,	/* instruciton debug */
+	PERF_BR_DEBUG_DATA	= 17,	/* data debug */
+	PERF_BR_FAULT_ALGN	= 18,	/* alignment fault */
+	PERF_BR_FAULT_DATA	= 19,	/* data fault */
+	PERF_BR_FAULT_INST	= 20,	/* instruction fault */
+	PERF_BR_SERROR		= 21,	/* system error */
 	PERF_BR_MAX,
 };
 
@@ -1370,8 +1376,8 @@ struct perf_branch_entry {
 		in_tx:1,    /* in transaction */
 		abort:1,    /* transaction abort */
 		cycles:16,  /* cycle count to last branch */
-		type:4,     /* branch type */
-		reserved:40;
+		type:6,     /* branch type */
+		reserved:38;
 };
 
 union perf_sample_weight {
diff --git a/tools/perf/util/branch.c b/tools/perf/util/branch.c
index 74e5e67b1779..1e216ea2e2a8 100644
--- a/tools/perf/util/branch.c
+++ b/tools/perf/util/branch.c
@@ -54,7 +54,13 @@ const char *branch_type_name(int type)
 		"IRQ",
 		"FIQ",
 		"DEBUG_HALT",
-		"DEBUG_EXIT"
+		"DEBUG_EXIT",
+		"DEBUG_INST",
+		"DEBUG_DATA",
+		"FAULT_ALGN",
+		"FAULT_DATA",
+		"FAULT_INST",
+		"SERROR"
 	};
 
 	if (type >= 0 && type < PERF_BR_MAX)
diff --git a/tools/perf/util/branch.h b/tools/perf/util/branch.h
index 17b2ccc61094..875d99abdc36 100644
--- a/tools/perf/util/branch.h
+++ b/tools/perf/util/branch.h
@@ -23,8 +23,8 @@ struct branch_flags {
 			u64 in_tx:1;
 			u64 abort:1;
 			u64 cycles:16;
-			u64 type:4;
-			u64 reserved:40;
+			u64 type:6;
+			u64 reserved:38;
 		};
 	};
 };
-- 
2.25.1



From shawnguo at kernel.org  Thu Jan 27 21:59:33 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 13:59:33 +0800
Subject: [PATCH] ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from
 hog group
In-Reply-To: <20211227161402.2523009-1-festevam@gmail.com>
References: <20211227161402.2523009-1-festevam@gmail.com>
Message-ID: <20220128055933.GC4686@dragon>

On Mon, Dec 27, 2021 at 01:14:02PM -0300, Fabio Estevam wrote:
> Currently, SD card fails to mount due to the following pinctrl error:
> 
> [   11.170000] imx23-pinctrl 80018000.pinctrl: pin SSP1_DETECT already requested by 80018000.pinctrl; cannot claim for 80010000.spi
> [   11.180000] imx23-pinctrl 80018000.pinctrl: pin-65 (80010000.spi) status -22
> [   11.190000] imx23-pinctrl 80018000.pinctrl: could not request pin 65 (SSP1_DETECT) from group mmc0-pins-fixup.0  on device 80018000.pinctrl
> [   11.200000] mxs-mmc 80010000.spi: Error applying setting, reverse things back
> 
> Fix it by removing the MX23_PAD_SSP1_DETECT pin from the hog group as it
> is already been used by the mmc0-pins-fixup pinctrl group.
> 
> With this change the rootfs can be mounted and the imx23-evk board can
> boot successfully.
> 
> Cc: <stable at vger.kernel.org>
> Fixes: bc3875f1a61e ("ARM: dts: mxs: modify mx23/mx28 dts files to use pinctrl headers")
> Signed-off-by: Fabio Estevam <festevam at gmail.com>

Applied, thanks!


From reijiw at google.com  Thu Jan 27 22:01:52 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 27 Jan 2022 22:01:52 -0800
Subject: [RFC PATCH v4 01/26] KVM: arm64: Introduce a validation function
 for an ID register
In-Reply-To: <YfDOaMrj3/M8g+7z@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-2-reijiw@google.com>
 <YfDOaMrj3/M8g+7z@google.com>
Message-ID: <CAAeT=FwSg=uj9XvRnOWBp+V5n9yvs3WQub+oCtbGcOWFY2LFkw@mail.gmail.com>

Hi Ricardo,

On Tue, Jan 25, 2022 at 8:30 PM Ricardo Koller <ricarkol at google.com> wrote:
>
> Hey Reiji,
>
> On Wed, Jan 05, 2022 at 08:26:43PM -0800, Reiji Watanabe wrote:
> > Introduce arm64_check_features(), which does a basic validity checking
> > of an ID register value against the register's limit value, which is
> > generally the host's sanitized value.
> >
> > This function will be used by the following patches to check if an ID
> > register value that userspace tries to set for a guest can be supported
> > on the host.
> >
> > The validation is done using arm64_ftr_bits_kvm, which is created from
> > arm64_ftr_regs, with some entries overwritten by entries from
> > arm64_ftr_bits_kvm_override.
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/include/asm/cpufeature.h |   1 +
> >  arch/arm64/kernel/cpufeature.c      | 228 ++++++++++++++++++++++++++++
> >  2 files changed, 229 insertions(+)
> >
> > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> > index ef6be92b1921..eda7ddbed8cf 100644
> > --- a/arch/arm64/include/asm/cpufeature.h
> > +++ b/arch/arm64/include/asm/cpufeature.h
> > @@ -631,6 +631,7 @@ void check_local_cpu_capabilities(void);
> >
> >  u64 read_sanitised_ftr_reg(u32 id);
> >  u64 __read_sysreg_by_encoding(u32 sys_id);
> > +int arm64_check_features(u32 sys_reg, u64 val, u64 limit);
> >
> >  static inline bool cpu_supports_mixed_endian_el0(void)
> >  {
> > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> > index 6f3e677d88f1..48dff8b101d9 100644
> > --- a/arch/arm64/kernel/cpufeature.c
> > +++ b/arch/arm64/kernel/cpufeature.c
> > @@ -3140,3 +3140,231 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr,
> >               return sprintf(buf, "Vulnerable\n");
> >       }
> >  }
> > +
> > +#ifdef CONFIG_KVM
> > +/*
> > + * arm64_ftr_bits_kvm[] is used for KVM to check if features that are
> > + * indicated in an ID register value for the guest are available on the host.
> > + * arm64_ftr_bits_kvm[] is created based on arm64_ftr_regs[].  But, for
> > + * registers for which arm64_ftr_bits_kvm_override[] has a corresponding
> > + * entry, replace arm64_ftr_bits entries in arm64_ftr_bits_kvm[] with the
> > + * ones in arm64_ftr_bits_kvm_override[].
> > + */
> > +static struct __ftr_reg_bits_entry *arm64_ftr_bits_kvm;
> > +static size_t arm64_ftr_bits_kvm_nentries;
>
> I don't think this is really needed, as arm64_ftr_bits_kvm_override has
> to have the same size as arm64_ftr_bits_kvm. You could use
> ARRAY_SIZE(arm64_ftr_regs) like in get_arm64_ftr_reg_nowarn().

Thanks for the review!
Yes, you are right. I will remove arm64_ftr_bits_kvm_nentries,
and use ARRAY_SIZE(arm64_ftr_regs) instead.

> > +static DEFINE_MUTEX(arm64_ftr_bits_kvm_lock);
> > +
> > +/*
> > + * Number of arm64_ftr_bits entries for each register.
> > + * (Number of 4 bits fields in 64 bit register + 1 entry for ARM64_FTR_END)
> > + */
> > +#define      MAX_FTR_BITS_LEN        17
> > +
> > +/* Use FTR_LOWER_SAFE for AA64DFR0_EL1.PMUVER and AA64DFR0_EL1.DEBUGVER. */
> > +static struct arm64_ftr_bits ftr_id_aa64dfr0_kvm[MAX_FTR_BITS_LEN] = {
> > +     S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
> > +     ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
> > +     ARM64_FTR_END,
> > +};
> > +
> > +#define      ARM64_FTR_REG_BITS(id, table)   {       \
> > +     .sys_id = id,                           \
> > +     .ftr_bits = &((table)[0]),              \
> > +}
> > +
> > +struct __ftr_reg_bits_entry {
> > +     u32     sys_id;
> > +     struct arm64_ftr_bits   *ftr_bits;
> > +};
> > +
> > +/*
> > + * All entries in arm64_ftr_bits_kvm_override[] are used to override
> > + * the corresponding entries in arm64_ftr_bits_kvm[].
> > + */
> > +static struct __ftr_reg_bits_entry arm64_ftr_bits_kvm_override[] = {
> > +     ARM64_FTR_REG_BITS(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0_kvm),
> > +};
> > +
> > +/*
> > + * Override entries in @orig_ftrp with the ones in @new_ftrp when their shift
> > + * fields match.  The last entry of @orig_ftrp and @new_ftrp must be
> > + * ARM64_FTR_END (.width == 0).
> > + */
> > +static void arm64_ftr_reg_bits_overrite(struct arm64_ftr_bits *orig_ftrp,
> > +                                     struct arm64_ftr_bits *new_ftrp)
> > +{
> > +     struct arm64_ftr_bits *o_ftrp, *n_ftrp;
> > +
> > +     for (n_ftrp = new_ftrp; n_ftrp->width; n_ftrp++) {
> > +             for (o_ftrp = orig_ftrp; o_ftrp->width; o_ftrp++) {
> > +                     if (o_ftrp->shift == n_ftrp->shift) {
> > +                             *o_ftrp = *n_ftrp;
> > +                             break;
> > +                     }
> > +             }
> > +     }
> > +}
> > +
> > +/*
> > + * Copy arm64_ftr_bits entries from @src_ftrp to @dst_ftrp.  The last entries
> > + * of @dst_ftrp and @src_ftrp must be ARM64_FTR_END (.width == 0).
> > + */
> > +static void copy_arm64_ftr_bits(struct arm64_ftr_bits *dst_ftrp,
> > +                             const struct arm64_ftr_bits *src_ftrp)
> > +{
> > +     int i = 0;
> > +
> > +     for (; src_ftrp[i].width; i++) {
> > +             if (WARN_ON_ONCE(i >= (MAX_FTR_BITS_LEN - 1)))
> > +                     break;
> > +
> > +             dst_ftrp[i] = src_ftrp[i];
> > +     }
> > +
> > +     dst_ftrp[i].width = 0;
> > +}
> > +
> > +/*
> > + * Initialize arm64_ftr_bits_kvm.  Copy arm64_ftr_bits for each ID register
> > + * from arm64_ftr_regs to arm64_ftr_bits_kvm, and then override entries in
> > + * arm64_ftr_bits_kvm with ones in arm64_ftr_bits_kvm_override.
> > + */
> > +static int init_arm64_ftr_bits_kvm(void)
> > +{
> > +     struct arm64_ftr_bits ftr_temp[MAX_FTR_BITS_LEN];
> > +     static struct __ftr_reg_bits_entry *reg_bits_array, *bits, *o_bits;
> > +     int i, j, nent, ret;
> > +
> > +     mutex_lock(&arm64_ftr_bits_kvm_lock);
>
> This is initialized lazily, whenever KVM calls arm64_check_features(). I
> guess that's why it needs the lock (and possibly a barrier as you
> mentoin in your reply). Would it be possible to simplify things by
> initializing arm64_ftr_bits_kvm somewhere at boot time (in
> init_cpu_features maybe?)?

I agree that it could simplify the code.
I will look into initializing that earlier.


>
> > +     if (arm64_ftr_bits_kvm) {
> > +             /* Already initialized */
> > +             ret = 0;
> > +             goto unlock_exit;
> > +     }
> > +
> > +     nent = ARRAY_SIZE(arm64_ftr_regs);
> > +     reg_bits_array = kcalloc(nent, sizeof(struct __ftr_reg_bits_entry),
> > +                              GFP_KERNEL);
> > +     if (!reg_bits_array) {
> > +             ret = ENOMEM;
> > +             goto unlock_exit;
> > +     }
> > +
> > +     /* Copy entries from arm64_ftr_regs to reg_bits_array */
> > +     for (i = 0; i < nent; i++) {
> > +             bits = &reg_bits_array[i];
> > +             bits->sys_id = arm64_ftr_regs[i].sys_id;
> > +             bits->ftr_bits = (struct arm64_ftr_bits *)arm64_ftr_regs[i].reg->ftr_bits;
> > +     };
> > +
> > +     /*
> > +      * Override the entries in reg_bits_array with the ones in
> > +      * arm64_ftr_bits_kvm_override.
> > +      */
> > +     for (i = 0; i < ARRAY_SIZE(arm64_ftr_bits_kvm_override); i++) {
> > +             o_bits = &arm64_ftr_bits_kvm_override[i];
> > +             for (j = 0; j < nent; j++) {
> > +                     bits = &reg_bits_array[j];
> > +                     if (bits->sys_id != o_bits->sys_id)
> > +                             continue;
> > +
> > +                     memset(ftr_temp, 0, sizeof(ftr_temp));
> > +
> > +                     /*
> > +                      * Temporary save all entries in o_bits->ftr_bits
> > +                      * to ftr_temp.
> > +                      */
> > +                     copy_arm64_ftr_bits(ftr_temp, o_bits->ftr_bits);
> > +
> > +                     /*
> > +                      * Copy entries from bits->ftr_bits to o_bits->ftr_bits.
> > +                      */
> > +                     copy_arm64_ftr_bits(o_bits->ftr_bits, bits->ftr_bits);
> > +
> > +                     /*
> > +                      * Override entries in o_bits->ftr_bits with the
> > +                      * saved ones, and update bits->ftr_bits with
> > +                      * o_bits->ftr_bits.
> > +                      */
> > +                     arm64_ftr_reg_bits_overrite(o_bits->ftr_bits, ftr_temp);
> > +                     bits->ftr_bits = o_bits->ftr_bits;
> > +                     break;
> > +             }
> > +     }
> > +
> > +     arm64_ftr_bits_kvm_nentries = nent;
> > +     arm64_ftr_bits_kvm = reg_bits_array;
> > +     ret = 0;
> > +
> > +unlock_exit:
> > +     mutex_unlock(&arm64_ftr_bits_kvm_lock);
> > +     return ret;
> > +}
> > +
> > +static int search_cmp_ftr_reg_bits(const void *id, const void *regp)
> > +{
> > +     return ((int)(unsigned long)id -
> > +             (int)((const struct __ftr_reg_bits_entry *)regp)->sys_id);
> > +}
> > +
> > +static const struct arm64_ftr_bits *get_arm64_ftr_bits_kvm(u32 sys_id)
> > +{
> > +     const struct __ftr_reg_bits_entry *ret;
> > +     int err;
> > +
> > +     if (!arm64_ftr_bits_kvm) {
> > +             /* arm64_ftr_bits_kvm is not initialized yet. */
> > +             err = init_arm64_ftr_bits_kvm();
> > +             if (err)
> > +                     return NULL;
> > +     }
> > +
> > +     ret = bsearch((const void *)(unsigned long)sys_id,
> > +                   arm64_ftr_bits_kvm,
> > +                   arm64_ftr_bits_kvm_nentries,
> > +                   sizeof(arm64_ftr_bits_kvm[0]),
> > +                   search_cmp_ftr_reg_bits);
> > +     if (ret)
> > +             return ret->ftr_bits;
> > +
> > +     return NULL;
> > +}
> > +
> > +/*
> > + * Check if features (or levels of features) that are indicated in the ID
> > + * register value @val are also indicated in @limit.
> > + * This function is for KVM to check if features that are indicated in @val,
> > + * which will be used as the ID register value for its guest, are supported
> > + * on the host.
> > + * For AA64MMFR0_EL1.TGranX_2 fields, which don't follow the standard ID
> > + * scheme, the function checks if values of the fields in @val are the same
> > + * as the ones in @limit.
> > + */
> > +int arm64_check_features(u32 sys_reg, u64 val, u64 limit)
> > +{
> > +     const struct arm64_ftr_bits *ftrp = get_arm64_ftr_bits_kvm(sys_reg);
>
> Given that this is to be used only by KVM (and it's inside CONFIG_KVM),
> it might be better to have "kvm" somewhere in its name.

Yes, that might be better. I will change the name.

Thanks,
Reiji


From liuqi115 at huawei.com  Thu Jan 27 22:17:55 2022
From: liuqi115 at huawei.com (Qi Liu)
Date: Fri, 28 Jan 2022 14:17:55 +0800
Subject: [PATCH v4] drivers/coresight: Add Ultrasoc System Memory Buffer driver
Message-ID: <20220128061755.31909-1-liuqi115@huawei.com>

This patch adds driver for Ultrasoc SMB(System Memory Buffer)
device. SMB provides a way to buffer messages from ETM, and
store these CPU instructions in system memory.

SMB is developed by Ultrasoc technology, which is acquired by
Siemens, and we still use "Ultrasoc" to name driver.

Signed-off-by: Qi Liu <liuqi115 at huawei.com>
Tested-by: JunHao He <hejunhao2 at hisilicon.com>
---
Change since v3:
- Modify the file header according to community specifications.
- Address the comments from Mathieu.
- Link:https://lore.kernel.org/linux-arm-kernel/20211118110016.40398-1-liuqi115 at huawei.com/
Change since v2:
- Move ultrasoc driver to drivers/hwtracing/coresight.
- Link:https://lists.linaro.org/pipermail/coresight/2021-November/007310.html

Change since v1:
- Drop the document of Ultrasoc according to Mathieu's comment.
- Add comments to explain some private hardware settings.
- Address the comments from Mathieu.
- Link: https://lists.linaro.org/pipermail/coresight/2021-August/006842.html

Change since RFC:
- Move ultrasoc driver to drivers/hwtracing/coresight/ultrasoc.
- Remove ultrasoc-axi-com.c, as AXI-COM doesn't need to be configured in
  basic tracing function.
- Remove ultrasoc.c as SMB does not need to register with the ultrasoc core.
- Address the comments from Mathieu and Suzuki.
- Link: https://lists.linaro.org/pipermail/coresight/2021-June/006535.html

 drivers/hwtracing/coresight/Kconfig        |  10 +
 drivers/hwtracing/coresight/Makefile       |   1 +
 drivers/hwtracing/coresight/ultrasoc-smb.c | 602 +++++++++++++++++++++
 drivers/hwtracing/coresight/ultrasoc-smb.h | 100 ++++
 4 files changed, 713 insertions(+)
 create mode 100644 drivers/hwtracing/coresight/ultrasoc-smb.c
 create mode 100644 drivers/hwtracing/coresight/ultrasoc-smb.h

diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 514a9b8086e3..32b87df9994a 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -201,4 +201,14 @@ config CORESIGHT_TRBE
 
 	  To compile this driver as a module, choose M here: the module will be
 	  called coresight-trbe.
+config ULTRASOC_SMB
+	tristate "Ultrasoc system memory buffer drivers"
+	depends on ARM64 && CORESIGHT_LINKS_AND_SINKS
+	help
+	  This driver provides support for the Ultrasoc system memory buffer (SMB).
+	  SMB is responsible for receiving the trace data from Coresight ETM devices
+	  and storing them to a system buffer.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ultrasoc-smb.
 endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index b6c4a48140ec..344dba8d6ff8 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -27,3 +27,4 @@ obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
 obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
 coresight-cti-y := coresight-cti-core.o	coresight-cti-platform.o \
 		   coresight-cti-sysfs.o
+obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.c b/drivers/hwtracing/coresight/ultrasoc-smb.c
new file mode 100644
index 000000000000..a18d061aab61
--- /dev/null
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.c
@@ -0,0 +1,602 @@
+// SPDX-License-Identifier: MIT/GPL
+/*
+ * Siemens System Memory Buffer driver.
+ * Copyright(c) 2022, HiSilicon Limited.
+ */
+
+#include <linux/acpi.h>
+#include <linux/circ_buf.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+
+#include "ultrasoc-smb.h"
+
+DEFINE_CORESIGHT_DEVLIST(sink_devs, "smb");
+
+static bool smb_buffer_is_empty(struct smb_drv_data *drvdata)
+{
+	u32 buf_status = readl(drvdata->base + SMB_LB_INT_STS);
+
+	return buf_status & BIT(0) ? false : true;
+}
+
+static bool smb_buffer_cmp_pointer(struct smb_drv_data *drvdata)
+{
+	u32 wr_offset, rd_offset;
+
+	wr_offset = readl(drvdata->base + SMB_LB_WR_ADDR);
+	rd_offset = readl(drvdata->base + SMB_LB_RD_ADDR);
+	return wr_offset == rd_offset;
+}
+
+static void smb_reset_buffer_status(struct smb_drv_data *drvdata)
+{
+	writel(0xf, drvdata->base + SMB_LB_INT_STS);
+}
+
+/* Purge data remaining in hardware path to SMB. */
+static void smb_purge_data(struct smb_drv_data *drvdata)
+{
+	writel(0x1, drvdata->base + SMB_LB_PURGE);
+}
+
+static void smb_update_data_size(struct smb_drv_data *drvdata)
+{
+	struct smb_data_buffer *sdb = &drvdata->sdb;
+	u32 write_offset;
+
+	smb_purge_data(drvdata);
+	if (smb_buffer_cmp_pointer(drvdata)) {
+		if (smb_buffer_is_empty(drvdata))
+			sdb->data_size = 0;
+		else
+			sdb->data_size = sdb->buf_size;
+		return;
+	}
+
+	write_offset = readl(drvdata->base + SMB_LB_WR_ADDR) - sdb->start_addr;
+	sdb->data_size = CIRC_CNT(write_offset, sdb->rd_offset, sdb->buf_size);
+}
+
+static int smb_open(struct inode *inode, struct file *file)
+{
+	struct smb_drv_data *drvdata = container_of(file->private_data,
+						    struct smb_drv_data, miscdev);
+
+	if (local_cmpxchg(&drvdata->reading, 0, 1))
+		return -EBUSY;
+
+	return 0;
+}
+
+static ssize_t smb_read(struct file *file, char __user *data, size_t len, loff_t *ppos)
+{
+	struct smb_drv_data *drvdata = container_of(file->private_data,
+						    struct smb_drv_data, miscdev);
+	struct smb_data_buffer *sdb = &drvdata->sdb;
+	struct device *dev = &drvdata->csdev->dev;
+	unsigned long flags;
+	int to_copy = 0;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	if (!sdb->data_size) {
+		smb_update_data_size(drvdata);
+		if (!sdb->data_size)
+			goto out;
+	}
+
+	if (atomic_read(drvdata->csdev->refcnt)) {
+		to_copy = -EBUSY;
+		goto out;
+	}
+
+	to_copy = min(sdb->data_size, len);
+
+	/* Copy parts of trace data when the read pointer will wrap around SMB buffer. */
+	if (sdb->rd_offset + to_copy > sdb->buf_size)
+		to_copy = sdb->buf_size - sdb->rd_offset;
+
+	if (copy_to_user(data, (void *)sdb->buf_base + sdb->rd_offset, to_copy)) {
+		dev_dbg(dev, "Failed to copy data to user\n");
+		to_copy = -EFAULT;
+		goto out;
+	}
+
+	*ppos += to_copy;
+	sdb->data_size -= to_copy;
+	sdb->rd_offset += to_copy;
+	sdb->rd_offset %= sdb->buf_size;
+	writel(sdb->start_addr + sdb->rd_offset, drvdata->base + SMB_LB_RD_ADDR);
+	dev_dbg(dev, "%d bytes copied\n", to_copy);
+out:
+	if (!sdb->data_size)
+		smb_reset_buffer_status(drvdata);
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	return to_copy;
+}
+
+static int smb_release(struct inode *inode, struct file *file)
+{
+	struct smb_drv_data *drvdata = container_of(file->private_data,
+						    struct smb_drv_data, miscdev);
+	local_set(&drvdata->reading, 0);
+	return 0;
+}
+
+static const struct file_operations smb_fops = {
+	.owner		= THIS_MODULE,
+	.open		= smb_open,
+	.read		= smb_read,
+	.release	= smb_release,
+	.llseek		= no_llseek,
+};
+
+smb_reg(read_pos, SMB_LB_RD_ADDR);
+smb_reg(write_pos, SMB_LB_WR_ADDR);
+smb_reg(buf_status, SMB_LB_INT_STS);
+
+static ssize_t buf_size_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct smb_drv_data *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "0x%lx\n", drvdata->sdb.buf_size);
+}
+static DEVICE_ATTR_RO(buf_size);
+
+static struct attribute *smb_sink_attrs[] = {
+	&dev_attr_read_pos.attr,
+	&dev_attr_write_pos.attr,
+	&dev_attr_buf_status.attr,
+	&dev_attr_buf_size.attr,
+	NULL,
+};
+
+static const struct attribute_group smb_sink_group = {
+	.attrs = smb_sink_attrs,
+	.name = "status",
+};
+
+static const struct attribute_group *smb_sink_groups[] = {
+	&smb_sink_group,
+	NULL,
+};
+
+static int smb_set_perf_buffer(struct perf_output_handle *handle)
+{
+	struct cs_buffers *buf = etm_perf_sink_config(handle);
+	u32 head;
+
+	if (!buf)
+		return -EINVAL;
+
+	/* Wrap head around to the amount of space we have */
+	head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1);
+
+	/* Find the page to write to and offset within that page */
+	buf->cur = head / PAGE_SIZE;
+	buf->offset = head % PAGE_SIZE;
+
+	local_set(&buf->data_size, 0);
+
+	return 0;
+}
+
+static void smb_enable_hw(struct smb_drv_data *drvdata)
+{
+	writel(0x1, drvdata->base + SMB_GLOBAL_EN);
+}
+
+static void smb_disable_hw(struct smb_drv_data *drvdata)
+{
+	writel(0x0, drvdata->base + SMB_GLOBAL_EN);
+}
+
+static int smb_enable_sysfs(struct smb_drv_data *drvdata)
+{
+	if (drvdata->mode == CS_MODE_PERF)
+		return -EBUSY;
+
+	if (drvdata->mode == CS_MODE_SYSFS)
+		return 0;
+
+	smb_enable_hw(drvdata);
+	drvdata->mode = CS_MODE_SYSFS;
+	return 0;
+}
+
+static int smb_enable_perf(struct smb_drv_data *drvdata, void *data)
+{
+	struct device *dev = &drvdata->csdev->dev;
+	struct perf_output_handle *handle = data;
+	pid_t pid;
+
+	if (drvdata->mode == CS_MODE_SYSFS) {
+		dev_err(dev, "Device is already in used by sysfs\n");
+		return -EBUSY;
+	}
+
+	/* Get a handle on the pid of the target process*/
+	pid = task_pid_nr(handle->event->owner);
+	if (drvdata->pid != -1 && drvdata->pid != pid) {
+		dev_err(dev, "Device is already in used by other session\n");
+		return -EBUSY;
+	}
+	/* The sink is already enabled by this session. */
+	if (drvdata->pid == pid)
+		return 0;
+
+	if (smb_set_perf_buffer(handle))
+		return -EINVAL;
+
+	smb_enable_hw(drvdata);
+	drvdata->pid = pid;
+	drvdata->mode = CS_MODE_PERF;
+
+	return 0;
+}
+
+static int smb_enable(struct coresight_device *csdev, u32 mode, void *data)
+{
+	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+	int ret = -EINVAL;
+
+	/* Do nothing if trace data is reading by other interface now. */
+	if (local_read(&drvdata->reading))
+		return -EBUSY;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	if (mode == CS_MODE_SYSFS)
+		ret = smb_enable_sysfs(drvdata);
+
+	if (mode == CS_MODE_PERF)
+		ret = smb_enable_perf(drvdata, data);
+
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	if (ret)
+		return ret;
+
+	atomic_inc(csdev->refcnt);
+	dev_dbg(&csdev->dev, "Ultrasoc SMB enabled\n");
+
+	return 0;
+}
+
+static int smb_disable(struct coresight_device *csdev)
+{
+	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
+	unsigned long flags;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	if (atomic_dec_return(csdev->refcnt)) {
+		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		return -EBUSY;
+	}
+
+	WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
+	smb_disable_hw(drvdata);
+
+	/*
+	 * Data remaining in hardware path will be sent to SMB after purge, so needs to
+	 * synchronize the read pointer to write pointer in perf mode.
+	 */
+	smb_purge_data(drvdata);
+	if (drvdata->mode == CS_MODE_PERF)
+		writel(readl(drvdata->base + SMB_LB_WR_ADDR), drvdata->base + SMB_LB_RD_ADDR);
+
+	/* Dissociate from the target process. */
+	drvdata->pid = -1;
+	drvdata->mode = CS_MODE_DISABLED;
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	dev_dbg(&csdev->dev, "Ultrasoc SMB disabled\n");
+	return 0;
+}
+
+static void *smb_alloc_buffer(struct coresight_device *csdev,
+			      struct perf_event *event, void **pages,
+			      int nr_pages, bool overwrite)
+{
+	struct cs_buffers *buf;
+	int node;
+
+	node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu);
+	buf = kzalloc_node(sizeof(*buf), GFP_KERNEL, node);
+	if (!buf)
+		return NULL;
+
+	buf->snapshot = overwrite;
+	buf->nr_pages = nr_pages;
+	buf->data_pages = pages;
+
+	return buf;
+}
+
+static void smb_free_buffer(void *config)
+{
+	struct cs_buffers *buf = config;
+
+	kfree(buf);
+}
+
+static void smb_sync_perf_buffer(struct smb_drv_data *drvdata,
+				 struct cs_buffers *buf, unsigned long data_size)
+{
+	struct smb_data_buffer *sdb = &drvdata->sdb;
+	char **dst_pages = (char **)buf->data_pages;
+	unsigned long buf_offset = buf->offset;
+	unsigned int cur = buf->cur;
+	unsigned long to_copy;
+
+	while (data_size) {
+		/* Copy parts of trace data when the read pointer will wrap around SMB buffer. */
+		if (sdb->rd_offset + PAGE_SIZE - buf_offset > sdb->buf_size)
+			to_copy = sdb->buf_size - sdb->rd_offset;
+		else
+			to_copy = min(data_size, PAGE_SIZE - buf_offset);
+
+		memcpy_fromio(dst_pages[cur] + buf_offset, sdb->buf_base + sdb->rd_offset, to_copy);
+
+		buf_offset += to_copy;
+		if (buf_offset >= PAGE_SIZE) {
+			buf_offset = 0;
+			cur++;
+			cur %= buf->nr_pages;
+		}
+		data_size -= to_copy;
+		/* ensure memcpy finished before update the read pointer */
+		sdb->rd_offset += to_copy;
+		sdb->rd_offset %= sdb->buf_size;
+	}
+
+	sdb->data_size = 0;
+	writel(sdb->start_addr + sdb->rd_offset, drvdata->base + SMB_LB_RD_ADDR);
+	smb_reset_buffer_status(drvdata);
+}
+
+static unsigned long smb_update_buffer(struct coresight_device *csdev,
+				       struct perf_output_handle *handle,
+				       void *sink_config)
+{
+	struct smb_drv_data *drvdata = dev_get_drvdata(csdev->dev.parent);
+	struct smb_data_buffer *sdb = &drvdata->sdb;
+	struct cs_buffers *buf = sink_config;
+	unsigned long data_size = 0;
+	unsigned long flags;
+	bool lost = false;
+
+	if (!buf)
+		return 0;
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	/* Don't do anything if another tracer is using this sink. */
+	if (atomic_read(csdev->refcnt) != 1)
+		goto out;
+
+	smb_update_data_size(drvdata);
+	data_size = sdb->data_size;
+	if (data_size > handle->size) {
+		sdb->rd_offset += data_size - handle->size;
+		sdb->rd_offset %= sdb->buf_size;
+		data_size = handle->size;
+		lost = true;
+	}
+
+	smb_sync_perf_buffer(drvdata, buf, data_size);
+	if (!buf->snapshot && lost)
+		perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
+
+out:
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	return data_size;
+}
+
+static const struct coresight_ops_sink smb_cs_ops = {
+	.enable		= smb_enable,
+	.disable	= smb_disable,
+	.alloc_buffer	= smb_alloc_buffer,
+	.free_buffer	= smb_free_buffer,
+	.update_buffer	= smb_update_buffer,
+};
+
+static const struct coresight_ops cs_ops = {
+	.sink_ops	= &smb_cs_ops,
+};
+
+static int smb_init_data_buffer(struct platform_device *pdev, struct smb_data_buffer *sdb)
+{
+	struct resource *res;
+	void __iomem *base;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (IS_ERR(res)) {
+		dev_err(&pdev->dev, "SMB device failed to get resource\n");
+		return -EINVAL;
+	}
+
+	sdb->start_addr = res->start & SMB_BASE_LOW_MASK;
+	sdb->buf_size = resource_size(res);
+	if (sdb->buf_size == 0)
+		return -EINVAL;
+
+	base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	sdb->buf_base = base;
+
+	return 0;
+}
+
+static void smb_init_hw(struct smb_drv_data *drvdata)
+{
+	u32 value;
+
+	/* First disable smb and clear the status of SMB buffer */
+	smb_reset_buffer_status(drvdata);
+	smb_disable_hw(drvdata);
+	smb_purge_data(drvdata);
+
+	/* Using smb in single-end mode, and set other configures default */
+	value = SMB_BUF_CFG_STREAMING | SMB_BUF_SINGLE_END | SMB_BUF_EN;
+	writel(value, drvdata->base + SMB_LB_CFG_LO);
+	value = SMB_MSG_FILTER(0x0, 0xff);
+	writel(value, drvdata->base + SMB_LB_CFG_HI);
+
+	writel(SMB_GLOBAL_CFG, drvdata->base + SMB_CFG_REG);
+	writel(SMB_GLB_INT_CFG, drvdata->base + SMB_GLOBAL_INT);
+	writel(SMB_BUF_INT_CFG, drvdata->base + SMB_LB_INT_CTRL);
+}
+
+static int smb_register_sink(struct platform_device *pdev, struct smb_drv_data *drvdata)
+{
+	struct coresight_platform_data *pdata = NULL;
+	struct coresight_desc desc = { 0 };
+	int ret;
+
+	pdata = coresight_get_platform_data(&pdev->dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+
+	desc.type = CORESIGHT_DEV_TYPE_SINK;
+	desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
+	desc.ops = &cs_ops;
+	desc.pdata = pdata;
+	desc.dev = &pdev->dev;
+	desc.groups = smb_sink_groups;
+	desc.name = coresight_alloc_device_name(&sink_devs, &pdev->dev);
+	if (!desc.name) {
+		dev_err(&pdev->dev, "Failed to alloc coresight device name");
+		return -ENOMEM;
+	}
+
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev))
+		return PTR_ERR(drvdata->csdev);
+
+	drvdata->miscdev.name = desc.name;
+	drvdata->miscdev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->miscdev.fops = &smb_fops;
+	ret = misc_register(&drvdata->miscdev);
+	if (ret) {
+		coresight_unregister(drvdata->csdev);
+		dev_err(&pdev->dev, "Failed to register misc: %d\n", ret);
+	}
+
+	return ret;
+}
+
+static void smb_unregister_sink(struct smb_drv_data *drvdata)
+{
+	misc_deregister(&drvdata->miscdev);
+	coresight_unregister(drvdata->csdev);
+}
+
+/*
+ * Send ultrasoc messge to control hardwares on the tracing path,
+ * using DSM calls to avoid exposing ultrasoc message format.
+ */
+static int smb_config_inport(struct device *dev, bool enable)
+{
+	u32 flag = enable ? 1 : 0;
+	union acpi_object *obj;
+	guid_t guid;
+
+	if (guid_parse("82ae1283-7f6a-4cbe-aa06-53e8fb24db18", &guid)) {
+		dev_err(dev, "Get GUID failed\n");
+		return -EINVAL;
+	}
+
+	obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &guid, 0, flag, NULL);
+	if (!obj)
+		dev_err(dev, "ACPI handle failed\n");
+	else
+		ACPI_FREE(obj);
+
+	return 0;
+}
+
+static int smb_probe(struct platform_device *pdev)
+{
+	struct smb_drv_data *drvdata;
+	int ret;
+
+	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(drvdata->base)) {
+		dev_err(&pdev->dev, "Failed to ioremap resource\n");
+		return PTR_ERR(drvdata->base);
+	}
+
+	ret = smb_init_data_buffer(pdev, &drvdata->sdb);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to init buffer: %d\n", ret);
+		return ret;
+	}
+
+	smb_init_hw(drvdata);
+	spin_lock_init(&drvdata->spinlock);
+	drvdata->pid = -1;
+
+	ret = smb_register_sink(pdev, drvdata);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register smb sink\n");
+		return ret;
+	}
+
+	ret = smb_config_inport(&pdev->dev, true);
+	if (ret) {
+		smb_unregister_sink(drvdata);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, drvdata);
+	return 0;
+}
+
+static int smb_remove(struct platform_device *pdev)
+{
+	struct smb_drv_data *drvdata = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = smb_config_inport(&pdev->dev, false);
+	if (ret)
+		return ret;
+
+	smb_unregister_sink(drvdata);
+	return 0;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id ultrasoc_smb_acpi_match[] = {
+	{"HISI03A1", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(acpi, ultrasoc_smb_acpi_match);
+#endif
+
+static struct platform_driver smb_driver = {
+	.driver = {
+		.name = "ultrasoc-smb",
+		.acpi_match_table = ACPI_PTR(ultrasoc_smb_acpi_match),
+		.suppress_bind_attrs = true,
+	},
+	.probe = smb_probe,
+	.remove = smb_remove,
+};
+module_platform_driver(smb_driver);
+
+MODULE_DESCRIPTION("Ultrasoc smb driver");
+MODULE_LICENSE("Dual MIT/GPL");
+MODULE_AUTHOR("Jonathan Zhou <jonathan.zhouwen at huawei.com>");
+MODULE_AUTHOR("Qi Liu <liuqi115 at huawei.com>");
diff --git a/drivers/hwtracing/coresight/ultrasoc-smb.h b/drivers/hwtracing/coresight/ultrasoc-smb.h
new file mode 100644
index 000000000000..a7c76140ee46
--- /dev/null
+++ b/drivers/hwtracing/coresight/ultrasoc-smb.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Siemens System Memory Buffer driver.
+ * Copyright(c) 2022, HiSilicon Limited.
+ */
+
+#ifndef _ULTRASOC_SMB_H
+#define _ULTRASOC_SMB_H
+
+#include <linux/coresight.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+
+#include "coresight-etm-perf.h"
+#include "coresight-priv.h"
+
+/* Offset of SMB logical buffer registers */
+#define SMB_CFG_REG			0X0
+#define SMB_GLOBAL_EN			0X4
+#define SMB_GLOBAL_INT			0X8
+#define SMB_LB_CFG_LO			0X40
+#define SMB_LB_CFG_HI			0X44
+#define SMB_LB_INT_CTRL			0X48
+#define SMB_LB_INT_STS			0X4C
+#define SMB_LB_LIMIT			0X58
+#define SMB_LB_RD_ADDR			0X5C
+#define SMB_LB_WR_ADDR			0X60
+#define SMB_LB_PURGE			0X64
+
+/* Set SMB_CFG_REG register */
+#define SMB_IDLE_PRD(period)		((((period) - 216) & 0xf) << 12)
+#define SMB_MEM_WR(credit, rate)	(((credit) << 16) | ((rate) << 18))
+#define SMB_MEM_RD(credit, rate)	(((credit) << 22) | ((rate) << 24))
+#define SMB_BURST_LEN(len)		(((len) - 1) << 4)
+#define SMB_GLOBAL_CFG			(SMB_IDLE_PRD(231) | SMB_MEM_WR(0x3, 0x0) |   \
+					 SMB_MEM_RD(0x3, 0x6) | SMB_BURST_LEN(16))
+
+/* Set SMB_GLOBAL_INT register */
+#define SMB_INT_EN			BIT(0)
+#define SMB_INT_TYPE_PULSE		BIT(1)
+#define SMB_INT_POLARITY_HIGH		BIT(2)
+#define SMB_GLB_INT_CFG			(SMB_INT_EN | SMB_INT_TYPE_PULSE | SMB_INT_POLARITY_HIGH)
+
+/* Set SMB_LB_CFG_LO register */
+#define SMB_BUF_EN			BIT(0)
+#define SMB_BUF_SINGLE_END		BIT(1)
+#define SMB_BUF_INIT			BIT(8)
+#define SMB_BUF_CONTINUOUS		BIT(11)
+#define SMB_FLOW_MASK			GENMASK(19, 16)
+#define SMB_BUF_CFG_STREAMING		(SMB_BUF_INIT | SMB_BUF_CONTINUOUS | SMB_FLOW_MASK)
+#define SMB_BASE_LOW_MASK		GENMASK(31, 0)
+
+/* Set SMB_LB_CFG_HI register */
+#define SMB_MSG_FILTER(lower, upper)	(((lower) & 0xff) | (((upper) & 0xff) << 8))
+#define SMB_BUF_INT_EN			BIT(0)
+#define SMB_BUF_NOTE_MASK		GENMASK(11, 8)
+#define SMB_BUF_INT_CFG			(SMB_BUF_INT_EN | SMB_BUF_NOTE_MASK)
+
+/**
+ * struct smb_data_buffer - Details of the buffer used by SMB
+ * @buf_base	: Memory mapped base address of SMB.
+ * @start_addr	: SMB buffer start Physical address.
+ * @buf_size	: Size of the buffer.
+ * @data_size	: Size of Trace data copy to userspace.
+ * @rd_offset	: Offset of the read pointer in the buffer.
+ */
+struct smb_data_buffer {
+	void __iomem *buf_base;
+	u32 start_addr;
+	unsigned long buf_size;
+	unsigned long data_size;
+	unsigned long rd_offset;
+};
+
+/**
+ * struct smb_drv_data - specifics associated to an SMB component
+ * @base	: Memory mapped base address for SMB component.
+ * @csdev	: Component vitals needed by the framework.
+ * @sdb		: Data buffer for SMB.
+ * @miscdev	: Specifics to handle "/dev/smb" entry.
+ * @spinlock	: Only one at a time pls.
+ * @reading	: Synchronise user space access to SMB buffer.
+ * @pid		: Process ID of the process being monitored by the session
+ *		that is using this component.
+ * @mode	: how this SMB is being used, perf mode or sysfs mode.
+ */
+struct smb_drv_data {
+	void __iomem *base;
+	struct coresight_device	*csdev;
+	struct smb_data_buffer sdb;
+	struct miscdevice miscdev;
+	spinlock_t spinlock;
+	local_t reading;
+	pid_t pid;
+	u32 mode;
+};
+
+#define smb_reg(name, offset)  coresight_simple_reg32(struct smb_drv_data, name, offset)
+
+#endif
-- 
2.24.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:43 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:43 +0800
Subject: [PATCH v3 0/7] Add basic node support for Mediatek MT8186 SoC
Message-ID: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

MT8186 is a SoC based on 64bit ARMv8 architecture.
It contains 6 CA55 and 2 CA78 cores.
MT8186 share many HW IP with MT65xx series.

This patchset was tested on MT8186 evaluation board to shell.

Based on linux-next

changes since v2:$
 - add soc {} in mt8186.dtsi

changes since v1:
 - add dt-bindings: arm: Add compatible for Mediatek MT8186


Allen-KH Cheng (7):
  dt-bindings: timer: Add compatible for Mediatek MT8186
  dt-bindings: serial: Add compatible for Mediatek MT8186
  dt-bindings: watchdog: Add compatible for Mediatek MT8186
  dt-bindings: mmc: Add compatible for Mediatek MT8186
  dt-bindings: phy: Add compatible for Mediatek MT8186
  dt-bindings: arm: Add compatible for Mediatek MT8186
  arm64: dts: Add Mediatek SoC MT8186 dts and evaluation board and
    Makefile

 .../devicetree/bindings/arm/mediatek.yaml     |   4 +
 .../devicetree/bindings/mmc/mtk-sd.yaml       |   3 +
 .../bindings/phy/mediatek,tphy.yaml           |   1 +
 .../devicetree/bindings/serial/mtk-uart.txt   |   1 +
 .../bindings/timer/mediatek,mtk-timer.txt     |   1 +
 .../devicetree/bindings/watchdog/mtk-wdt.txt  |   1 +
 arch/arm64/boot/dts/mediatek/Makefile         |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts   |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi      | 360 ++++++++++++++++++
 9 files changed, 396 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:48 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:48 +0800
Subject: [PATCH v3 5/7] dt-bindings: phy: Add compatible for Mediatek MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-6-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of T-Phy for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/phy/mediatek,tphy.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
index 05ee274b4b71..d279ba222316 100644
--- a/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
+++ b/Documentation/devicetree/bindings/phy/mediatek,tphy.yaml
@@ -80,6 +80,7 @@ properties:
               - mediatek,mt2712-tphy
               - mediatek,mt7629-tphy
               - mediatek,mt8183-tphy
+              - mediatek,mt8186-tphy
           - const: mediatek,generic-tphy-v2
       - items:
           - enum:
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:50 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:50 +0800
Subject: [PATCH v3 7/7] arm64: dts: Add Mediatek SoC MT8186 dts and evaluation
 board and Makefile
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-8-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Add basic chip support for Mediatek MT8186

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |   1 +
 arch/arm64/boot/dts/mediatek/mt8186-evb.dts |  24 ++
 arch/arm64/boot/dts/mediatek/mt8186.dtsi    | 360 ++++++++++++++++++++
 3 files changed, 385 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8c1e18032f9f..d32fdcf9afc6 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -37,5 +37,6 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-kodama-sku32.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8186-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-evb.dts b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
new file mode 100644
index 000000000000..eb23d1f19f87
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186-evb.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ */
+/dts-v1/;
+#include "mt8186.dtsi"
+
+/ {
+	model = "MediaTek MT8186 evaluation board";
+	compatible = "mediatek,mt8186-evb", "mediatek,mt8186";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8186.dtsi b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
new file mode 100644
index 000000000000..d6b81b4d68ca
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2022 MediaTek Inc.
+ * Author: Allen-KH Cheng <allenn-kh.cheng at mediatek.com>
+ */
+/dts-v1/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+
+/ {
+	compatible = "mediatek,mt8186";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0000>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu1: cpu at 001 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0100>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu2: cpu at 002 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0200>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu3: cpu at 003 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0300>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu4: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0400>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu5: cpu at 101 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55", "arm,armv8";
+			reg = <0x0500>;
+			enable-method = "psci";
+			clock-frequency = <2000000000>;
+			cpu-idle-states = <&cpuoff_l &clusteroff_l &mcusysoff>;
+			next-level-cache = <&l2_0>;
+		};
+
+		cpu6: cpu at 102 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0600>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu7: cpu at 103 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a75", "arm,armv8";
+			reg = <0x0700>;
+			enable-method = "psci";
+			clock-frequency = <2050000000>;
+			cpu-idle-states = <&cpuoff_b &clusteroff_b &mcusysoff>;
+			next-level-cache = <&l2_1>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+
+				core4 {
+					cpu = <&cpu4>;
+				};
+
+				core5 {
+					cpu = <&cpu5>;
+				};
+
+			};
+			cluster1 {
+				core0 {
+					cpu = <&cpu6>;
+				};
+
+				core1 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpuoff_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1600>;
+			};
+
+			cpuoff_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <100>;
+				min-residency-us = <1400>;
+			};
+
+			clusteroff_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <2100>;
+			};
+
+			clusteroff_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010001>;
+				local-timer-stop;
+				entry-latency-us = <100>;
+				exit-latency-us = <250>;
+				min-residency-us = <1900>;
+			};
+
+			mcusysoff: mcusys-off {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <300>;
+				exit-latency-us = <1200>;
+				min-residency-us = <2600>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32000>;
+	};
+
+	psci {
+		compatible      = "arm,psci-1.0";
+		method          = "smc";
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+		clock-frequency = <13000000>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <3>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			#redistributor-regions = <1>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>, // distributor
+			      <0 0x0c040000 0 0x200000>; // redistributor
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		watchdog: watchdog at 10007000 {
+			compatible = "mediatek,mt8186-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x10007000 0 0x1000>;
+		};
+
+		sys_timer at 10017000 {
+			compatible = "mediatek,mt8186-timer",
+				     "mediatek,mt6765-timer";
+			reg = <0 0x10017000 0 0x1000>;
+			interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>;
+		};
+
+		uart0: serial at 11002000 {
+			compatible = "mediatek,mt8186-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11002000 0 0x1000>;
+			interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "baud", "bus";
+		};
+
+		uart1: serial at 11003000 {
+			compatible = "mediatek,mt8186-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11003000 0 0x1000>;
+			interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart2: serial at 11018000 {
+			compatible = "mediatek,mt8186-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11018000 0 0x1000>;
+			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt8186-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11230000 0 0x1000>,
+			      <0 0x11cd0000 0 0x1000>;
+			interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>, <&clk26m>, <&clk26m>,
+				 <&clk26m>;
+			clock-names = "source", "hclk", "source_cg",
+				      "ahb_clk";
+			status = "disabled";
+		};
+
+		mmc1: mmc at 11240000 {
+			compatible = "mediatek,mt8186-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11240000 0 0x1000>,
+			      <0 0x11c90000 0 0x1000>;
+			interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&clk26m>, <&clk26m>, <&clk26m>;
+			clock-names = "source", "hclk", "source_cg";
+			status = "disabled";
+		};
+
+		u3phy1: usb-phy1 at 11c80000 {
+			compatible = "mediatek,mt8186-tphy",
+				     "mediatek,generic-tphy-v2";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "okay";
+
+			u2port1: usb2-phy1 at 11c80000 {
+				reg = <0 0x11c80000 0 0x700>;
+				clocks = <&clk26m>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+				status = "okay";
+			};
+
+			u3port1: usb3-phy1 at 11c80900 {
+				reg = <0 0x11c80900 0 0x700>;
+				clocks = <&clk26m>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+				status = "okay";
+			};
+		};
+
+		u3phy0: usb-phy at 11ca0000 {
+			compatible = "mediatek,mt8186-tphy",
+				     "mediatek,generic-tphy-v2";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			status = "okay";
+
+			u2port0: usb2-phy at 11ca0000 {
+				reg = <0 0x11ca0000 0 0x700>;
+				clocks = <&clk26m>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+				mediatek,discth = <0x8>;
+				status = "okay";
+			};
+		};
+	};
+};
-- 
2.18.0



From herbert at gondor.apana.org.au  Thu Jan 27 22:22:21 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 28 Jan 2022 17:22:21 +1100
Subject: [PATCH v4 0/6] Introduce x86 assembly accelerated implementation
 for SM3 algorithm
In-Reply-To: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
Message-ID: <YfOLnacTQffp3tO9@gondor.apana.org.au>

On Fri, Jan 07, 2022 at 08:06:54PM +0800, Tianjia Zhang wrote:
> This series of patches creates an stand-alone library for SM3 hash
> algorithm in the lib/crypto directory, and makes the implementations
> that originally depended on sm3-generic depend on the stand-alone SM3
> library, which also includes sm3-generic itself.
> 
> On this basis, the AVX assembly acceleration implementation of SM3
> algorithm is introduced, the main algorithm implementation based on
> SM3 AES/BMI2 accelerated work by libgcrypt at:
> https://gnupg.org/software/libgcrypt/index.html
> 
> >From the performance benchmark data, the performance improvement of
> SM3 algorithm after AVX optimization can reach up to 38%.
> 
> ---
> v4 changes:
>  - Rebase on latest cryptodev-2.6/master
>  - Fix the compilation error of arm64/sm3
> 
> v3 changes:
>  - update git commit message for patch 01
> 
> v2 changes:
>  - x86/sm3: Change K macros to signed decimal and use LEA and 32-bit offset
> 
> Tianjia Zhang (6):
>   crypto: sm3 - create SM3 stand-alone library
>   crypto: arm64/sm3-ce - make dependent on sm3 library
>   crypto: sm2 - make dependent on sm3 library
>   crypto: sm3 - make dependent on sm3 library
>   crypto: x86/sm3 - add AVX assembly implementation
>   crypto: tcrypt - add asynchronous speed test for SM3
> 
>  arch/arm64/crypto/Kconfig        |   2 +-
>  arch/arm64/crypto/sm3-ce-glue.c  |  28 +-
>  arch/x86/crypto/Makefile         |   3 +
>  arch/x86/crypto/sm3-avx-asm_64.S | 517 +++++++++++++++++++++++++++++++
>  arch/x86/crypto/sm3_avx_glue.c   | 134 ++++++++
>  crypto/Kconfig                   |  16 +-
>  crypto/sm2.c                     |  38 +--
>  crypto/sm3_generic.c             | 142 +--------
>  crypto/tcrypt.c                  |  14 +-
>  include/crypto/sm3.h             |  34 +-
>  lib/crypto/Kconfig               |   3 +
>  lib/crypto/Makefile              |   3 +
>  lib/crypto/sm3.c                 | 246 +++++++++++++++
>  13 files changed, 1013 insertions(+), 167 deletions(-)
>  create mode 100644 arch/x86/crypto/sm3-avx-asm_64.S
>  create mode 100644 arch/x86/crypto/sm3_avx_glue.c
>  create mode 100644 lib/crypto/sm3.c

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From reijiw at google.com  Thu Jan 27 22:24:25 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Thu, 27 Jan 2022 22:24:25 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <YfDaiUbSkpi9/5YY@google.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
 <YfDaiUbSkpi9/5YY@google.com>
Message-ID: <CAAeT=FzNSvzz-Ok0Ka95=kkdDGsAMmzf9xiRfD5gYCdvmEfifg@mail.gmail.com>

Hi Ricardo,

On Tue, Jan 25, 2022 at 9:22 PM Ricardo Koller <ricarkol at google.com> wrote:
>
> On Wed, Jan 05, 2022 at 08:26:44PM -0800, Reiji Watanabe wrote:
> > Introduce id_regs[] in kvm_arch as a storage of guest's ID registers,
> > and save ID registers' sanitized value in the array at KVM_CREATE_VM.
> > Use the saved ones when ID registers are read by the guest or
> > userspace (via KVM_GET_ONE_REG).
> >
> > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > ---
> >  arch/arm64/include/asm/kvm_host.h | 16 ++++++++
> >  arch/arm64/kvm/arm.c              |  1 +
> >  arch/arm64/kvm/sys_regs.c         | 62 ++++++++++++++++++++++---------
> >  3 files changed, 62 insertions(+), 17 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 2a5f7f38006f..c789a0137f58 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -102,6 +102,17 @@ struct kvm_s2_mmu {
> >  struct kvm_arch_memory_slot {
> >  };
> >
> > +/*
> > + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> > + * where 0<=crm<8, 0<=op2<8.
>
> Is this observation based on this table?
>
> Table D12-2 System instruction encodings for non-Debug System register accesses
> in that case, it seems that the ID registers list might grow after
> crm=7, and as CRm has 4 bits, why not 16*8=128?

This is basically for registers that are already reserved as RAZ in the
table (sys_reg_descs[] has entries for the reserved ones as well).
Registers with crm > 7 are not reserved yet, and that will be expanded
later as needed later.


>
> > + */
> > +#define KVM_ARM_ID_REG_MAX_NUM       64
> > +#define IDREG_IDX(id)                ((sys_reg_CRm(id) << 3) | sys_reg_Op2(id))
> > +#define is_id_reg(id)        \
> > +     (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&        \
> > +      sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&        \
> > +      sys_reg_CRm(id) < 8)
> > +
> >  struct kvm_arch {
> >       struct kvm_s2_mmu mmu;
> >
> > @@ -137,6 +148,9 @@ struct kvm_arch {
> >
> >       /* Memory Tagging Extension enabled for the guest */
> >       bool mte_enabled;
> > +
> > +     /* ID registers for the guest. */
> > +     u64 id_regs[KVM_ARM_ID_REG_MAX_NUM];
> >  };
> >
> >  struct kvm_vcpu_fault_info {
> > @@ -734,6 +748,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
> >  long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
> >                               struct kvm_arm_copy_mte_tags *copy_tags);
> >
> > +void set_default_id_regs(struct kvm *kvm);
> > +
> >  /* Guest/host FPSIMD coordination helpers */
> >  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> >  void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index e4727dc771bf..5f497a0af254 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> >       kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
> >
> >       set_default_spectre(kvm);
> > +     set_default_id_regs(kvm);
> >
> >       return ret;
> >  out_free_stage2_pgd:
> > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > index e3ec1a44f94d..80dc62f98ef0 100644
> > --- a/arch/arm64/kvm/sys_regs.c
> > +++ b/arch/arm64/kvm/sys_regs.c
> > @@ -33,6 +33,8 @@
> >
> >  #include "trace.h"
> >
> > +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
> > +
> >  /*
> >   * All of this file is extremely similar to the ARM coproc.c, but the
> >   * types are different. My gut feeling is that it should be pretty
> > @@ -273,7 +275,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
> >                         struct sys_reg_params *p,
> >                         const struct sys_reg_desc *r)
> >  {
> > -     u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> > +     u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
> >       u32 sr = reg_to_encoding(r);
> >
> >       if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> > @@ -1059,17 +1061,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
> >       return true;
> >  }
> >
> > -/* Read a sanitised cpufeature ID register by sys_reg_desc */
> > -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> > -             struct sys_reg_desc const *r, bool raz)
> > +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> >  {
> > -     u32 id = reg_to_encoding(r);
> > -     u64 val;
> > -
> > -     if (raz)
> > -             return 0;
> > -
> > -     val = read_sanitised_ftr_reg(id);
> > +     u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
> >
> >       switch (id) {
> >       case SYS_ID_AA64PFR0_EL1:
> > @@ -1119,6 +1113,14 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> >       return val;
> >  }
> >
> > +static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> > +                    struct sys_reg_desc const *r, bool raz)
> > +{
> > +     u32 id = reg_to_encoding(r);
> > +
> > +     return raz ? 0 : __read_id_reg(vcpu, id);
> > +}
> > +
> >  static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
> >                                 const struct sys_reg_desc *r)
> >  {
> > @@ -1223,9 +1225,8 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> >  /*
> >   * cpufeature ID register user accessors
> >   *
> > - * For now, these registers are immutable for userspace, so no values
> > - * are stored, and for set_id_reg() we don't allow the effective value
> > - * to be changed.
> > + * For now, these registers are immutable for userspace, so for set_id_reg()
> > + * we don't allow the effective value to be changed.
> >   */
> >  static int __get_id_reg(const struct kvm_vcpu *vcpu,
> >                       const struct sys_reg_desc *rd, void __user *uaddr,
> > @@ -1237,7 +1238,7 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
> >       return reg_to_user(uaddr, &val, id);
> >  }
> >
> > -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> > +static int __set_id_reg(struct kvm_vcpu *vcpu,
> >                       const struct sys_reg_desc *rd, void __user *uaddr,
> >                       bool raz)
> >  {
> > @@ -1837,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
> >       if (p->is_write) {
> >               return ignore_write(vcpu, p);
> >       } else {
> > -             u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
> > -             u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> > +             u64 dfr = __read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> > +             u64 pfr = __read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
> >               u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
> >
> >               p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
> > @@ -2850,3 +2851,30 @@ void kvm_sys_reg_table_init(void)
> >       /* Clear all higher bits. */
> >       cache_levels &= (1 << (i*3))-1;
> >  }
> > +
> > +/*
> > + * Set the guest's ID registers that are defined in sys_reg_descs[]
> > + * with ID_SANITISED() to the host's sanitized value.
> > + */
> > +void set_default_id_regs(struct kvm *kvm)
> > +{
> > +     int i;
> > +     u32 id;
> > +     const struct sys_reg_desc *rd;
> > +     u64 val;
> > +
> > +     for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> > +             rd = &sys_reg_descs[i];
> > +             if (rd->access != access_id_reg)
> > +                     /* Not ID register, or hidden/reserved ID register */
> > +                     continue;
> > +
> > +             id = reg_to_encoding(rd);
> > +             if (WARN_ON_ONCE(!is_id_reg(id)))
> > +                     /* Shouldn't happen */
> > +                     continue;
> > +
> > +             val = read_sanitised_ftr_reg(id);
>
> I'm a bit confused. Shouldn't the default+sanitized values already use
> arm64_ftr_bits_kvm (instead of arm64_ftr_regs)?

I'm not sure if I understand your question.
arm64_ftr_bits_kvm is used for feature support checkings when
userspace tries to modify a value of ID registers.
With this patch, KVM just saves the sanitized values in the kvm's
buffer, but userspace is still not allowed to modify values of ID
registers yet.
I hope it answers your question.

Thanks,
Reiji

>
> > +             kvm->arch.id_regs[IDREG_IDX(id)] = val;
> > +     }
> > +}
> > --
> > 2.34.1.448.ga2b2bfdf31-goog
> >


From herbert at gondor.apana.org.au  Thu Jan 27 22:24:55 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 28 Jan 2022 17:24:55 +1100
Subject: [PATCH] crypto: sun8i-ss: really disable hash on A80
In-Reply-To: <20220115100714.3016838-1-clabbe@baylibre.com>
References: <20220115100714.3016838-1-clabbe@baylibre.com>
Message-ID: <YfOMNy1kiI4gvePu@gondor.apana.org.au>

On Sat, Jan 15, 2022 at 10:07:14AM +0000, Corentin Labbe wrote:
> When adding hashes support to sun8i-ss, I have added them only on A83T.
> But I forgot that 0 is a valid algorithm ID, so hashes are enabled on A80 but
> with an incorrect ID.
> Anyway, even with correct IDs, hashes do not work on A80 and I cannot
> find why.
> So let's disable all of them on A80.
> 
> Fixes: d9b45418a917 ("crypto: sun8i-ss - support hash algorithms")
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
> ---
>  drivers/crypto/allwinner/sun8i-ss/sun8i-ss-core.c | 2 ++
>  1 file changed, 2 insertions(+)

Patch applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From herbert at gondor.apana.org.au  Thu Jan 27 22:25:02 2022
From: herbert at gondor.apana.org.au (Herbert Xu)
Date: Fri, 28 Jan 2022 17:25:02 +1100
Subject: [PATCH v3 0/4] arm64: accelerate crc32_be
In-Reply-To: <20220118102351.3356105-1-kevin@bracey.fi>
References: <20220118102351.3356105-1-kevin@bracey.fi>
Message-ID: <YfOMPhAczX7KBu8v@gondor.apana.org.au>

On Tue, Jan 18, 2022 at 12:23:47PM +0200, Kevin Bracey wrote:
> Originally sent only to the arm-linux list - now including linux-crypto.
> Ard suggested that Herbert take the series.
> 
> This series completes the arm64 crc32 helper acceleration by adding crc32_be.
> 
> There are plenty of users, for example OF.
> 
> To compensate for the extra supporting cruft in lib/crc32.c, a couple of minor
> tidies.
> 
> changes since v2:
> - no code change, but sent to Herbert+crypto with Catalin's ack for arm64
> 
> changes since v1:
> - assembler style fixes from Ard's review
> 
> Kevin Bracey (4):
>   lib/crc32.c: remove unneeded casts
>   lib/crc32.c: Make crc32_be weak for arch override
>   lib/crc32test.c: correct printed bytes count
>   arm64: accelerate crc32_be
> 
>  arch/arm64/lib/crc32.S | 87 +++++++++++++++++++++++++++++++++++-------
>  lib/crc32.c            | 14 +++----
>  lib/crc32test.c        |  2 +-
>  3 files changed, 80 insertions(+), 23 deletions(-)

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert at gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt


From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:49 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:49 +0800
Subject: [PATCH v3 6/7] dt-bindings: arm: Add compatible for Mediatek MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-7-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation for the Mediatek MT8186
reference board.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/arm/mediatek.yaml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml
index 0ffe1acf1344..05472d9308a1 100644
--- a/Documentation/devicetree/bindings/arm/mediatek.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -127,6 +127,10 @@ properties:
           - enum:
               - mediatek,mt8183-evb
           - const: mediatek,mt8183
+      - items:
+          - enum:
+              - mediatek,mt8186-evb
+          - const: mediatek,mt8186
       - items:
           - enum:
               - mediatek,mt8195-evb
-- 
2.18.0



From chunfeng.yun at mediatek.com  Thu Jan 27 22:29:01 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 28 Jan 2022 14:29:01 +0800
Subject: [PATCH v2 3/4] arm64: dts: mediatek: mt8195: add efuse node and cells
In-Reply-To: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
References: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
Message-ID: <20220128062902.26273-3-chunfeng.yun@mediatek.com>

Add efuse node and cells used by t-phy to fix the bit shift issue

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: use hw auto load for u2phy which has no this issue

Note:

 depend on the reviewing patch:

[v9,3/3] arm64: dts: Add mediatek SoC mt8195 and evaluation board
https://patchwork.kernel.org/patch/12711296
---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 55 ++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index a363e82f6988..240a21708806 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -695,6 +695,53 @@
 			status = "disabled";
 		};
 
+		efuse: efuse at 11c10000 {
+			compatible = "mediatek,mt8195-efuse", "mediatek,efuse";
+			reg = <0 0x11c10000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			u3_tx_imp_p0: usb3-tx-imp at 184 {
+				reg = <0x184 0x1>;
+				bits = <0 5>;
+			};
+			u3_rx_imp_p0: usb3-rx-imp at 184 {
+				reg = <0x184 0x2>;
+				bits = <5 5>;
+			};
+			u3_intr_p0: usb3-intr at 185 {
+				reg = <0x185 0x1>;
+				bits = <2 6>;
+			};
+			comb_tx_imp_p1: usb3-tx-imp at 186 {
+				reg = <0x186 0x1>;
+				bits = <0 5>;
+			};
+			comb_rx_imp_p1: usb3-rx-imp at 186 {
+				reg = <0x186 0x2>;
+				bits = <5 5>;
+			};
+			comb_intr_p1: usb3-intr at 187 {
+				reg = <0x187 0x1>;
+				bits = <2 6>;
+			};
+			u2_intr_p0: usb2-intr-p0 at 188 {
+				reg = <0x188 0x1>;
+				bits = <0 5>;
+			};
+			u2_intr_p1: usb2-intr-p1 at 188 {
+				reg = <0x188 0x2>;
+				bits = <5 5>;
+			};
+			u2_intr_p2: usb2-intr-p2 at 189 {
+				reg = <0x189 0x1>;
+				bits = <2 5>;
+			};
+			u2_intr_p3: usb2-intr-p3 at 189 {
+				reg = <0x189 0x2>;
+				bits = <7 5>;
+			};
+		};
+
 		u3phy2: t-phy at 11c40000 {
 			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
 			#address-cells = <1>;
@@ -877,6 +924,10 @@
 				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
 					 <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>;
 				clock-names = "ref", "da_ref";
+				nvmem-cells = <&comb_intr_p1>,
+					      <&comb_rx_imp_p1>,
+					      <&comb_tx_imp_p1>;
+				nvmem-cell-names = "intr", "rx_imp", "tx_imp";
 				#phy-cells = <1>;
 			};
 		};
@@ -901,6 +952,10 @@
 				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
 					 <&topckgen CLK_TOP_SSUSB_PHY_REF>;
 				clock-names = "ref", "da_ref";
+				nvmem-cells = <&u3_intr_p0>,
+					      <&u3_rx_imp_p0>,
+					      <&u3_tx_imp_p0>;
+				nvmem-cell-names = "intr", "rx_imp", "tx_imp";
 				#phy-cells = <1>;
 			};
 		};
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:45 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:45 +0800
Subject: [PATCH v3 2/7] dt-bindings: serial: Add compatible for Mediatek MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of uart for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/serial/mtk-uart.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/serial/mtk-uart.txt b/Documentation/devicetree/bindings/serial/mtk-uart.txt
index b3a0bfef0d54..113b5d6a2245 100644
--- a/Documentation/devicetree/bindings/serial/mtk-uart.txt
+++ b/Documentation/devicetree/bindings/serial/mtk-uart.txt
@@ -20,6 +20,7 @@ Required properties:
   * "mediatek,mt8135-uart" for MT8135 compatible UARTS
   * "mediatek,mt8173-uart" for MT8173 compatible UARTS
   * "mediatek,mt8183-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
+  * "mediatek,mt8186-uart", "mediatek,mt6577-uart" for MT8183 compatible UARTS
   * "mediatek,mt8192-uart", "mediatek,mt6577-uart" for MT8192 compatible UARTS
   * "mediatek,mt8195-uart", "mediatek,mt6577-uart" for MT8195 compatible UARTS
   * "mediatek,mt8516-uart" for MT8516 compatible UARTS
-- 
2.18.0



From chunfeng.yun at mediatek.com  Thu Jan 27 22:29:00 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 28 Jan 2022 14:29:00 +0800
Subject: [PATCH v2 2/4] usb: xhci-mtk: add support ip-sleep wakeup for mt8195
In-Reply-To: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
References: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
Message-ID: <20220128062902.26273-2-chunfeng.yun@mediatek.com>

Add support ip-sleep wakeup for mt8195, it's a specific revision for
each USB controller, and not following IPM rule.

Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg at gmail.com>
Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: add reviewed-by Matthias & AngeloGioacchino
---
 drivers/usb/host/xhci-mtk.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
index 91738af0ab14..96a0ff0bb11e 100644
--- a/drivers/usb/host/xhci-mtk.c
+++ b/drivers/usb/host/xhci-mtk.c
@@ -95,6 +95,19 @@
 #define WC0_SSUSB0_CDEN		BIT(6)
 #define WC0_IS_SPM_EN		BIT(1)
 
+/* mt8195 */
+#define PERI_WK_CTRL0_8195	0x04
+#define WC0_IS_P_95		BIT(30)	/* polarity */
+#define WC0_IS_C_95(x)		((u32)(((x) & 0x7) << 27))
+#define WC0_IS_EN_P3_95		BIT(26)
+#define WC0_IS_EN_P2_95		BIT(25)
+#define WC0_IS_EN_P1_95		BIT(24)
+
+#define PERI_WK_CTRL1_8195	0x20
+#define WC1_IS_C_95(x)		((u32)(((x) & 0xf) << 28))
+#define WC1_IS_P_95		BIT(12)
+#define WC1_IS_EN_P0_95		BIT(6)
+
 /* mt2712 etc */
 #define PERI_SSUSB_SPM_CTRL	0x0
 #define SSC_IP_SLEEP_EN	BIT(4)
@@ -105,6 +118,10 @@ enum ssusb_uwk_vers {
 	SSUSB_UWK_V2,
 	SSUSB_UWK_V1_1 = 101,	/* specific revision 1.01 */
 	SSUSB_UWK_V1_2,		/* specific revision 1.2 */
+	SSUSB_UWK_V1_3,		/* mt8195 IP0 */
+	SSUSB_UWK_V1_4,		/* mt8195 IP1 */
+	SSUSB_UWK_V1_5,		/* mt8195 IP2 */
+	SSUSB_UWK_V1_6,		/* mt8195 IP3 */
 };
 
 /*
@@ -308,6 +325,26 @@ static void usb_wakeup_ip_sleep_set(struct xhci_hcd_mtk *mtk, bool enable)
 		msk = WC0_SSUSB0_CDEN | WC0_IS_SPM_EN;
 		val = enable ? msk : 0;
 		break;
+	case SSUSB_UWK_V1_3:
+		reg = mtk->uwk_reg_base + PERI_WK_CTRL1_8195;
+		msk = WC1_IS_EN_P0_95 | WC1_IS_C_95(0xf) | WC1_IS_P_95;
+		val = enable ? (WC1_IS_EN_P0_95 | WC1_IS_C_95(0x1)) : 0;
+		break;
+	case SSUSB_UWK_V1_4:
+		reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195;
+		msk = WC0_IS_EN_P1_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95;
+		val = enable ? (WC0_IS_EN_P1_95 | WC0_IS_C_95(0x1)) : 0;
+		break;
+	case SSUSB_UWK_V1_5:
+		reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195;
+		msk = WC0_IS_EN_P2_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95;
+		val = enable ? (WC0_IS_EN_P2_95 | WC0_IS_C_95(0x1)) : 0;
+		break;
+	case SSUSB_UWK_V1_6:
+		reg = mtk->uwk_reg_base + PERI_WK_CTRL0_8195;
+		msk = WC0_IS_EN_P3_95 | WC0_IS_C_95(0x7) | WC0_IS_P_95;
+		val = enable ? (WC0_IS_EN_P3_95 | WC0_IS_C_95(0x1)) : 0;
+		break;
 	case SSUSB_UWK_V2:
 		reg = mtk->uwk_reg_base + PERI_SSUSB_SPM_CTRL;
 		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN;
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:46 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:46 +0800
Subject: [PATCH v3 3/7] dt-bindings: watchdog: Add compatible for Mediatek
 MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-4-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of watchdog for Mediatek
MT8186 SoC Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/watchdog/mtk-wdt.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
index 0114871f887a..74db01e3658b 100644
--- a/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
@@ -15,6 +15,7 @@ Required properties:
 	"mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
 	"mediatek,mt7986-wdt", "mediatek,mt6589-wdt": for MT7986
 	"mediatek,mt8183-wdt": for MT8183
+	"mediatek,mt8186-wdt", "mediatek,mt6589-wdt": for MT8186
 	"mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
 	"mediatek,mt8192-wdt": for MT8192
 	"mediatek,mt8195-wdt", "mediatek,mt6589-wdt": for MT8195
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:47 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:47 +0800
Subject: [PATCH v3 4/7] dt-bindings: mmc: Add compatible for Mediatek MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-5-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of mmc for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
index faf89b0c918f..297ada03e3de 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml
@@ -29,6 +29,9 @@ properties:
       - items:
           - const: mediatek,mt7623-mmc
           - const: mediatek,mt2701-mmc
+      - items:
+          - const: mediatek,mt8186-mmc
+          - const: mediatek,mt8183-mmc
       - items:
           - const: mediatek,mt8192-mmc
           - const: mediatek,mt8183-mmc
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Thu Jan 27 22:20:44 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 14:20:44 +0800
Subject: [PATCH v3 1/7] dt-bindings: timer: Add compatible for Mediatek MT8186
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128062050.23978-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This commit adds dt-binding documentation of timer for Mediatek MT8186 SoC
Platform.

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
index e5c57d6e0186..e0d20d6adf81 100644
--- a/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
+++ b/Documentation/devicetree/bindings/timer/mediatek,mtk-timer.txt
@@ -22,6 +22,7 @@ Required properties:
 
 	For those SoCs that use SYST
 	* "mediatek,mt8183-timer" for MT8183 compatible timers (SYST)
+	* "mediatek,mt8186-timer" for MT8186 compatible timers (SYST)
 	* "mediatek,mt8192-timer" for MT8192 compatible timers (SYST)
 	* "mediatek,mt8195-timer" for MT8195 compatible timers (SYST)
 	* "mediatek,mt7629-timer" for MT7629 compatible timers (SYST)
-- 
2.18.0



From chunfeng.yun at mediatek.com  Thu Jan 27 22:28:59 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 28 Jan 2022 14:28:59 +0800
Subject: [PATCH v2 1/4] dt-bindings: usb: mtk-xhci: add support ip-sleep for
 mt8195
Message-ID: <20220128062902.26273-1-chunfeng.yun@mediatek.com>

There are 4 USB controllers on MT8195, each controller's wakeup control is
different, add some specific versions for them.

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
v2:
  1. fix typo 'specific' suggested by Rob
  2. add acked-by AngeloGioacchino
---
 .../devicetree/bindings/usb/mediatek,mtk-xhci.yaml          | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
index 11f7bacd4e2b..41efb51638d1 100644
--- a/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
+++ b/Documentation/devicetree/bindings/usb/mediatek,mtk-xhci.yaml
@@ -146,7 +146,11 @@ properties:
             2 - used by mt2712 etc, revision 2 following IPM rule;
             101 - used by mt8183, specific 1.01;
             102 - used by mt8192, specific 1.02;
-          enum: [1, 2, 101, 102]
+            103 - used by mt8195, IP0, specific 1.03;
+            104 - used by mt8195, IP1, specific 1.04;
+            105 - used by mt8195, IP2, specific 1.05;
+            106 - used by mt8195, IP3, specific 1.06;
+          enum: [1, 2, 101, 102, 103, 104, 105, 106]
 
   mediatek,u3p-dis-msk:
     $ref: /schemas/types.yaml#/definitions/uint32
-- 
2.18.0



From tianjia.zhang at linux.alibaba.com  Thu Jan 27 22:36:17 2022
From: tianjia.zhang at linux.alibaba.com (Tianjia Zhang)
Date: Fri, 28 Jan 2022 14:36:17 +0800
Subject: [PATCH v4 6/6] crypto: tcrypt - add asynchronous speed test for
 SM3
In-Reply-To: <YfN0PsCAXYo0Hx9T@gondor.apana.org.au>
References: <20220107120700.730-1-tianjia.zhang@linux.alibaba.com>
 <20220107120700.730-7-tianjia.zhang@linux.alibaba.com>
 <YfN0PsCAXYo0Hx9T@gondor.apana.org.au>
Message-ID: <948c7ddc-1a2d-aa38-1841-576ab85e63a4@linux.alibaba.com>

Hi Herbert,

On 1/28/22 12:42 PM, Herbert Xu wrote:
> On Fri, Jan 07, 2022 at 08:07:00PM +0800, Tianjia Zhang wrote:
>> tcrypt supports testing of SM3 hash algorithms that use AVX
>> instruction acceleration.
>>
>> In order to add the sm3 asynchronous test to the appropriate
>> position, shift the testcase sequence number of the multi buffer
>> backward and start from 450.
>>
>> Signed-off-by: Tianjia Zhang <tianjia.zhang at linux.alibaba.com>
>> ---
>>   crypto/tcrypt.c | 14 +++++++++-----
>>   1 file changed, 9 insertions(+), 5 deletions(-)
> 
> This is not an issue with your patch but we should delete all
> the mb hash tests as the mb hash algorithm tself was removed
> in 2018.
> 
> Thanks,

Thanks for the reminder, I will add an extra patch to remove the mb hash 
tests.

Happy New Year.


Tianjia


From ck.hu at mediatek.com  Thu Jan 27 22:38:20 2022
From: ck.hu at mediatek.com (CK Hu)
Date: Fri, 28 Jan 2022 14:38:20 +0800
Subject: [RFC PATCH 2/2] drm/mediatek: add mtk8195 hdmi display driver
In-Reply-To: <20211108000847.14320-3-granquet@baylibre.com>
References: <20211108000847.14320-1-granquet@baylibre.com>
 <20211108000847.14320-3-granquet@baylibre.com>
Message-ID: <10f4a1a11759f2b2a2d322f9d4f17c3159f9769a.camel@mediatek.com>

Hi, Guillaume:

On Mon, 2021-11-08 at 01:08 +0100, Guillaume Ranquet wrote:
> Signed-off-by: Guillaume Ranquet <granquet at baylibre.com>
> Change-Id: I6399dec26cfe56a338c2ca96989cb7cbd14e292b
> ---
>  drivers/gpu/drm/mediatek/Kconfig              |    9 +
>  drivers/gpu/drm/mediatek/Makefile             |    2 +
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.c    |  219 +-
>  drivers/gpu/drm/mediatek/mtk_hdmi_common.h    |   24 +-
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c    | 1835
> +++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h    |   26 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c    |  530 +++++
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h    |   20 +
>  .../gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h   |  329 +++
>  9 files changed, 2932 insertions(+), 62 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h
> 
> diff --git a/drivers/gpu/drm/mediatek/Kconfig
> b/drivers/gpu/drm/mediatek/Kconfig
> index 0df75bceb74e..76cc402cbd75 100644
> --- a/drivers/gpu/drm/mediatek/Kconfig
> +++ b/drivers/gpu/drm/mediatek/Kconfig
> @@ -31,3 +31,12 @@ config DRM_MEDIATEK_HDMI
>  	help
>  	  DRM/KMS HDMI driver for Mediatek SoCs

[snip]

> +
> +static int mtk_hdmi_ddc_xfer(struct i2c_adapter *adapter, struct
> i2c_msg *msgs,
> +			     int num)
> +{
> +	struct mtk_hdmi_ddc *ddc = adapter->algo_data;
> +	struct device *dev = adapter->dev.parent;
> +	int ret;
> +	int i;
> +
> +	if (!ddc)
> +		return -EINVAL;
> +
> +	for (i = 0; i < num; i++) {
> +		struct i2c_msg *msg = &msgs[i];
> +
> +		if (msg->flags & I2C_M_RD)
> +			ret = fg_ddc_data_read(ddc, msg->addr, msg-
> >buf[0],
> +					    (msg->len), &msg->buf[0]);
> +		else
> +			ret = fg_ddc_data_write(ddc, msg->addr, msg-
> >buf[0],
> +					     (msg->len - 1), &msg-
> >buf[1]);

Why do you use msg->buf[1]? In mt8173 hdmi ddc driver,
mtk_hdmi_ddc_write_msg() just use msg->buf[0]. If using msg->buf[1] is
advance function, separate this advance function to another patch.

Regards,
CK

> +
> +		if (ret <= 0)
> +			goto xfer_end;
> +	}
> +
> +	return i;
> +
> +xfer_end:
> +	dev_err(dev, "ddc failed! : %d\n", ret);
> +	return ret;
> +}
> +



From chunfeng.yun at mediatek.com  Thu Jan 27 22:29:02 2022
From: chunfeng.yun at mediatek.com (Chunfeng Yun)
Date: Fri, 28 Jan 2022 14:29:02 +0800
Subject: [PATCH v2 4/4] arm64: dts: mediatek: mt8195: enable usb remote wakeup
In-Reply-To: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
References: <20220128062902.26273-1-chunfeng.yun@mediatek.com>
Message-ID: <20220128062902.26273-4-chunfeng.yun@mediatek.com>

Enable USB remote wakeup of all four xHCI controllers

Signed-off-by: Chunfeng Yun <chunfeng.yun at mediatek.com>
---
v2: based on new mt8195 base dts, no need add usb nodes

Note:

 depend on the reviewing patch:

[v9,3/3] arm64: dts: Add mediatek SoC mt8195 and evaluation board
https://patchwork.kernel.org/patch/12711296

---
 arch/arm64/boot/dts/mediatek/mt8195.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
index 240a21708806..444e5448c9b1 100644
--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -573,6 +573,8 @@
 				 <&apmixedsys CLK_APMIXED_USB1PLL>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
 			clock-names = "sys_ck", "ref_ck", "mcu_ck", "xhci_ck";
+			mediatek,syscon-wakeup = <&pericfg 0x400 103>;
+			wakeup-source;
 			status = "disabled";
 		};
 
@@ -636,6 +638,8 @@
 				 <&apmixedsys CLK_APMIXED_USB1PLL>,
 				 <&pericfg_ao CLK_PERI_AO_SSUSB_1P_XHCI>;
 			clock-names = "sys_ck", "ref_ck", "mcu_ck","xhci_ck";
+			mediatek,syscon-wakeup = <&pericfg 0x400 104>;
+			wakeup-source;
 			status = "disabled";
 		};
 
@@ -655,6 +659,8 @@
 				 <&topckgen CLK_TOP_SSUSB_P2_REF>,
 				 <&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
 			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			mediatek,syscon-wakeup = <&pericfg 0x400 105>;
+			wakeup-source;
 			status = "disabled";
 		};
 
@@ -674,6 +680,8 @@
 				 <&topckgen CLK_TOP_SSUSB_P3_REF>,
 				 <&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
 			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			mediatek,syscon-wakeup = <&pericfg 0x400 106>;
+			wakeup-source;
 			/* This controller is connected with a BT device.
 			 * Disable usb2 lpm to prevent konwn issues.
 			 */
-- 
2.18.0



From dan.carpenter at oracle.com  Thu Jan 27 23:03:31 2022
From: dan.carpenter at oracle.com (Dan Carpenter)
Date: Fri, 28 Jan 2022 10:03:31 +0300
Subject: [PATCH] vchiq-mmal: Remove redundant 'flush_workqueue()' calls
In-Reply-To: <fdbe3eaf-c737-0714-6b54-8a7cdbe38a0c@i2se.com>
References: <20220127014432.1185206-1-chi.minghao@zte.com.cn>
 <fdbe3eaf-c737-0714-6b54-8a7cdbe38a0c@i2se.com>
Message-ID: <20220128070330.GD1951@kadam>

On Thu, Jan 27, 2022 at 01:35:09PM +0100, Stefan Wahren wrote:
> Hi,
> 
> Am 27.01.22 um 02:44 schrieb cgel.zte at gmail.com:
> > From: "Minghao Chi (CGEL ZTE)" <chi.minghao at zte.com.cn>
> >
> > 'destroy_workqueue()' already drains the queue before destroying it,
> > so there is no need to flush it explicitly.
> >
> > Remove the redundant 'flush_workqueue()' calls.
> are you sure that drain_workqueue() is the same as flush_workqueue()?

drain_workqueue() calls flush_workqueue() repeatedly.

regards,
dan carpenter



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:25 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:25 +0530
Subject: [PATCH 1/9] soc: qcom: llcc: Add support for 16 ways of allocation
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <b63745f844547f4d7e1ffd99fc93997170c44585.1643353154.git.quic_saipraka@quicinc.com>

From: Huang Yiwei <hyiwei at codeaurora.org>

Add support for 16 ways of allocation for LLCC HW version 2.1.0
and later.

Signed-off-by: Huang Yiwei <hyiwei at codeaurora.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index ec52f29c8867..b3a34f117a7c 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -29,8 +29,8 @@
 #define ATTR1_FIXED_SIZE_SHIFT        0x03
 #define ATTR1_PRIORITY_SHIFT          0x04
 #define ATTR1_MAX_CAP_SHIFT           0x10
-#define ATTR0_RES_WAYS_MASK           GENMASK(11, 0)
-#define ATTR0_BONUS_WAYS_MASK         GENMASK(27, 16)
+#define ATTR0_RES_WAYS_MASK           GENMASK(15, 0)
+#define ATTR0_BONUS_WAYS_MASK         GENMASK(31, 16)
 #define ATTR0_BONUS_WAYS_SHIFT        0x10
 #define LLCC_STATUS_READ_DELAY        100
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:24 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:24 +0530
Subject: [PATCH 0/9] soc: qcom: llcc: Add LLCC support for SM8450 SoC
Message-ID: <cover.1643353154.git.quic_saipraka@quicinc.com>

This patch series adds support for LLCC on SM8450 SoC. It mainly
consists of LLCC driver changes to incorporate newer LLCC HW found
on SM8450 SoC and the corresponding DT bits to enable LLCC.
Based on qcom/for-next branch.

Huang Yiwei (1):
  soc: qcom: llcc: Add support for 16 ways of allocation

Sai Prakash Ranjan (8):
  soc: qcom: llcc: Update the logic for version info extraction
  soc: qcom: llcc: Add write-cache cacheable support
  soc: qcom: llcc: Add missing llcc configuration data
  soc: qcom: llcc: Update register offsets for newer LLCC HW
  soc: qcom: llcc: Add configuration data for SM8450 SoC
  dt-bindings: arm: msm: Add LLCC compatible for SM8350
  dt-bindings: arm: msm: Add LLCC compatible for SM8450
  arm64: dts: qcom: sm8450: Add LLCC/system-cache-controller node

 .../bindings/arm/msm/qcom,llcc.yaml           |   2 +
 arch/arm64/boot/dts/qcom/sm8450.dtsi          |   7 ++
 drivers/soc/qcom/llcc-qcom.c                  | 102 +++++++++++++++---
 include/linux/soc/qcom/llcc-qcom.h            |   9 +-
 4 files changed, 104 insertions(+), 16 deletions(-)


base-commit: 073a39a2a63abd46339a50eb07bd23958d99efbe
prerequisite-patch-id: 33fc8487573f4dd2ef21bfdfcf57d1437f456df3
prerequisite-patch-id: 026a0e76224498cec9ad15cbbc452f8f4fcdbca9
prerequisite-patch-id: 626323d13e5cc60434e225544b71314fd84adf90
prerequisite-patch-id: a1d79b7d366eb3a749621998580d8607a852a432
prerequisite-patch-id: 51d51021554581d9ccf510a8c9087748b9a77019
prerequisite-patch-id: ecbbd03ca61082e78754d52d1b3e99848185b4d1
prerequisite-patch-id: 6120d52065436b3d5fcc4aa509af2046bea1e344
prerequisite-patch-id: 388f5c230d39b7181a0f563b6fc5b3e35d4d7f75
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:26 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:26 +0530
Subject: [PATCH 2/9] soc: qcom: llcc: Update the logic for version info
 extraction
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <e311b16376329b9e9483fed8ae910a31d0f7bcba.1643353154.git.quic_saipraka@quicinc.com>

LLCC HW version info is made up of major, branch, minor and echo
version bits each of which are 8bits. Several features in newer
LLCC HW are based on the full version rather than just major or
minor versions such as write-subcache enable which is applicable
for versions greater than v2.0.0.0 and upcoming write-subcache
cacheable for SM8450 SoC which is only present in versions v2.1.0.0
and later, so it makes it easier and cleaner to just directly
compare with the full version than adding additional major/branch/
minor/echo version checks. So remove the earlier major version check
and add full version check for those features.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c       | 9 ++++-----
 include/linux/soc/qcom/llcc-qcom.h | 4 ++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index b3a34f117a7c..a06764f16023 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -37,7 +37,6 @@
 #define CACHE_LINE_SIZE_SHIFT         6
 
 #define LLCC_COMMON_HW_INFO           0x00030000
-#define LLCC_MAJOR_VERSION_MASK       GENMASK(31, 24)
 
 #define LLCC_COMMON_STATUS0           0x0003000c
 #define LLCC_LB_CNT_MASK              GENMASK(31, 28)
@@ -55,6 +54,8 @@
 
 #define BANK_OFFSET_STRIDE	      0x80000
 
+#define LLCC_VERSION_2_0_0_0          0x02000000
+
 /**
  * struct llcc_slice_config - Data associated with the llcc slice
  * @usecase_id: Unique id for the client's use case
@@ -504,7 +505,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
 			return ret;
 	}
 
-	if (drv_data->major_version == 2) {
+	if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
 		u32 wren;
 
 		wren = config->write_scid_en << config->slice_id;
@@ -598,13 +599,11 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	/* Extract major version of the IP */
+	/* Extract version of the IP */
 	ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
 	if (ret)
 		goto err;
 
-	drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version);
-
 	ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
 						&num_banks);
 	if (ret)
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 9e8fd92c96b7..beecf00b707d 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -83,7 +83,7 @@ struct llcc_edac_reg_data {
  * @bitmap: Bit map to track the active slice ids
  * @offsets: Pointer to the bank offsets array
  * @ecc_irq: interrupt for llcc cache error detection and reporting
- * @major_version: Indicates the LLCC major version
+ * @version: Indicates the LLCC version
  */
 struct llcc_drv_data {
 	struct regmap *regmap;
@@ -96,7 +96,7 @@ struct llcc_drv_data {
 	unsigned long *bitmap;
 	u32 *offsets;
 	int ecc_irq;
-	u32 major_version;
+	u32 version;
 };
 
 #if IS_ENABLED(CONFIG_QCOM_LLCC)
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:27 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:27 +0530
Subject: [PATCH 3/9] soc: qcom: llcc: Add write-cache cacheable support
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <e533680b3976330115fc5bd49f4c99440eda6a69.1643353154.git.quic_saipraka@quicinc.com>

Newer SoCs with LLCC IP version 2.1.0 and later support write
sub-cache cacheable feature. Use a separate llcc_slice_config member
"write_scid_cacheable_en" to identify this feature and program
LLCC_TRP_SCID_WRSC_CACHEABLE_EN register to enable it.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index a06764f16023..79fce5a2ff06 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -51,10 +51,12 @@
 #define LLCC_TRP_SCID_DIS_CAP_ALLOC   0x21f00
 #define LLCC_TRP_PCB_ACT              0x21f04
 #define LLCC_TRP_WRSC_EN              0x21f20
+#define LLCC_TRP_WRSC_CACHEABLE_EN    0x21f2c
 
 #define BANK_OFFSET_STRIDE	      0x80000
 
 #define LLCC_VERSION_2_0_0_0          0x02000000
+#define LLCC_VERSION_2_1_0_0          0x02010000
 
 /**
  * struct llcc_slice_config - Data associated with the llcc slice
@@ -80,6 +82,8 @@
  *               collapse.
  * @activate_on_init: Activate the slice immediately after it is programmed
  * @write_scid_en: Bit enables write cache support for a given scid.
+ * @write_scid_cacheable_en: Enables write cache cacheable support for a
+ *			     given scid (not supported on v2 or older hardware).
  */
 struct llcc_slice_config {
 	u32 usecase_id;
@@ -95,6 +99,7 @@ struct llcc_slice_config {
 	bool retain_on_pc;
 	bool activate_on_init;
 	bool write_scid_en;
+	bool write_scid_cacheable_en;
 };
 
 struct qcom_llcc_config {
@@ -515,6 +520,16 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
 			return ret;
 	}
 
+	if (drv_data->version >= LLCC_VERSION_2_1_0_0) {
+		u32 wr_cache_en;
+
+		wr_cache_en = config->write_scid_cacheable_en << config->slice_id;
+		ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN,
+					 BIT(config->slice_id), wr_cache_en);
+		if (ret)
+			return ret;
+	}
+
 	if (config->activate_on_init) {
 		desc.slice_id = config->slice_id;
 		ret = llcc_slice_activate(&desc);
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:28 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:28 +0530
Subject: [PATCH 4/9] soc: qcom: llcc: Add missing llcc configuration data
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <547065fed7889b3aa02b8ff5437ceaa40fb7d8c5.1643353154.git.quic_saipraka@quicinc.com>

Add missing llcc configuration data for few chipsets which
were not added during initial post.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 79fce5a2ff06..d14d20d824b2 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -244,21 +244,25 @@ static const struct qcom_llcc_config sdm845_cfg = {
 static const struct qcom_llcc_config sm6350_cfg = {
 	.sct_data	= sm6350_data,
 	.size		= ARRAY_SIZE(sm6350_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8150_cfg = {
 	.sct_data       = sm8150_data,
 	.size           = ARRAY_SIZE(sm8150_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8250_cfg = {
 	.sct_data       = sm8250_data,
 	.size           = ARRAY_SIZE(sm8250_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8350_cfg = {
 	.sct_data       = sm8350_data,
 	.size           = ARRAY_SIZE(sm8350_data),
+	.need_llcc_cfg	= true,
 };
 
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:29 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:29 +0530
Subject: [PATCH 5/9] soc: qcom: llcc: Update register offsets for newer LLCC HW
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <af3dc1ff65dac8e261af1816d4a3fda37858719f.1643353154.git.quic_saipraka@quicinc.com>

Newer LLCC HW have different register offsets for several registers,
currently of which LLCC hardware info and status are used to identify
the LLCC version information and other data. So use separate table to
keep track of these register offsets which vary by different LLCC HW
versions and eases any future addition in variations of register offsets
for newer hardware.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index d14d20d824b2..2306536fbc76 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -36,9 +36,6 @@
 
 #define CACHE_LINE_SIZE_SHIFT         6
 
-#define LLCC_COMMON_HW_INFO           0x00030000
-
-#define LLCC_COMMON_STATUS0           0x0003000c
 #define LLCC_LB_CNT_MASK              GENMASK(31, 28)
 #define LLCC_LB_CNT_SHIFT             28
 
@@ -106,6 +103,12 @@ struct qcom_llcc_config {
 	const struct llcc_slice_config *sct_data;
 	int size;
 	bool need_llcc_cfg;
+	const u32 *reg_offset;
+};
+
+enum llcc_reg_offset {
+	LLCC_COMMON_HW_INFO,
+	LLCC_COMMON_STATUS0,
 };
 
 static const struct llcc_slice_config sc7180_data[] =  {
@@ -223,46 +226,63 @@ static const struct llcc_slice_config sm8350_data[] =  {
 	{ LLCC_CPUHWT,   5, 512,   1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
 };
 
+static const u32 llcc_v1_2_reg_offset[] = {
+	[LLCC_COMMON_HW_INFO]	= 0x00030000,
+	[LLCC_COMMON_STATUS0]	= 0x0003000c,
+};
+
+static const u32 llcc_v21_reg_offset[] = {
+	[LLCC_COMMON_HW_INFO]	= 0x00034000,
+	[LLCC_COMMON_STATUS0]	= 0x0003400c,
+};
+
 static const struct qcom_llcc_config sc7180_cfg = {
 	.sct_data	= sc7180_data,
 	.size		= ARRAY_SIZE(sc7180_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sc7280_cfg = {
 	.sct_data	= sc7280_data,
 	.size		= ARRAY_SIZE(sc7280_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sdm845_cfg = {
 	.sct_data	= sdm845_data,
 	.size		= ARRAY_SIZE(sdm845_data),
 	.need_llcc_cfg	= false,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm6350_cfg = {
 	.sct_data	= sm6350_data,
 	.size		= ARRAY_SIZE(sm6350_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8150_cfg = {
 	.sct_data       = sm8150_data,
 	.size           = ARRAY_SIZE(sm8150_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8250_cfg = {
 	.sct_data       = sm8250_data,
 	.size           = ARRAY_SIZE(sm8250_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8350_cfg = {
 	.sct_data       = sm8350_data,
 	.size           = ARRAY_SIZE(sm8350_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
@@ -618,13 +638,16 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	cfg = of_device_get_match_data(&pdev->dev);
+
 	/* Extract version of the IP */
-	ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
+	ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
+			  &version);
 	if (ret)
 		goto err;
 
-	ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
-						&num_banks);
+	ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0],
+			  &num_banks);
 	if (ret)
 		goto err;
 
@@ -632,7 +655,6 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 	num_banks >>= LLCC_LB_CNT_SHIFT;
 	drv_data->num_banks = num_banks;
 
-	cfg = of_device_get_match_data(&pdev->dev);
 	llcc_cfg = cfg->sct_data;
 	sz = cfg->size;
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:30 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:30 +0530
Subject: [PATCH 6/9] soc: qcom: llcc: Add configuration data for SM8450 SoC
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <7ff138539f561c9cda7a07128ac5f530ec122028.1643353154.git.quic_saipraka@quicinc.com>

Add LLCC configuration data for SM8450 SoC.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c       | 34 ++++++++++++++++++++++++++++++
 include/linux/soc/qcom/llcc-qcom.h |  5 +++++
 2 files changed, 39 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 2306536fbc76..ea88f171686b 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -226,6 +226,32 @@ static const struct llcc_slice_config sm8350_data[] =  {
 	{ LLCC_CPUHWT,   5, 512,   1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
 };
 
+static const struct llcc_slice_config sm8450_data[] =  {
+	{LLCC_CPUSS,     1, 3072, 1, 0, 0xFFFF, 0x0,   0, 0, 0, 1, 1, 0, 0 },
+	{LLCC_VIDSC0,    2,  512, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AUDIO,     6, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+	{LLCC_MDMHPGRW,  7, 1024, 3, 0, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MODHW,     9, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CMPT,     10, 4096, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_GPUHTW,   11,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_GPU,      12, 2048, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 1, 0 },
+	{LLCC_MMUHWT,   13,  768, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_DISP,     16, 4096, 2, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MDMPNG,   21, 1024, 1, 1, 0xF000, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AUDHW,    22, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+	{LLCC_CVP,      28,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MODPE,    29,   64, 1, 1, 0xF000, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_APTCM,    30, 1024, 3, 1, 0x0,    0xF0,  1, 0, 0, 1, 0, 0, 0 },
+	{LLCC_WRCACHE,  31,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_CVPFW,    17,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CPUSS1,    3, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CAMEXP0,   4,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CPUMTE,   23,  256, 1, 1, 0x0FFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_CPUHWT,    5,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 1, 0, 0 },
+	{LLCC_CAMEXP1,  27,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AENPU,     8, 2048, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+};
+
 static const u32 llcc_v1_2_reg_offset[] = {
 	[LLCC_COMMON_HW_INFO]	= 0x00030000,
 	[LLCC_COMMON_STATUS0]	= 0x0003000c,
@@ -285,6 +311,13 @@ static const struct qcom_llcc_config sm8350_cfg = {
 	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
+static const struct qcom_llcc_config sm8450_cfg = {
+	.sct_data       = sm8450_data,
+	.size           = ARRAY_SIZE(sm8450_data),
+	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v21_reg_offset,
+};
+
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
 
 /**
@@ -712,6 +745,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
 	{ .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
 	{ .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
 	{ .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
+	{ .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
 	{ }
 };
 
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index beecf00b707d..0bc21ee58fac 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -35,7 +35,12 @@
 #define LLCC_WRCACHE     31
 #define LLCC_CVPFW       32
 #define LLCC_CPUSS1      33
+#define LLCC_CAMEXP0     34
+#define LLCC_CPUMTE      35
 #define LLCC_CPUHWT      36
+#define LLCC_MDMCLAD2    37
+#define LLCC_CAMEXP1     38
+#define LLCC_AENPU       45
 
 /**
  * struct llcc_slice_desc - Cache slice descriptor
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:31 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:31 +0530
Subject: [PATCH 7/9] dt-bindings: arm: msm: Add LLCC compatible for SM8350
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <716c4aa5535111daa929f8e5b302fbf51b4667bd.1643353154.git.quic_saipraka@quicinc.com>

Add LLCC compatible for SM8350 SoC.

Cc: Rob Herring <robh at kernel.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index 03882aac8d2d..c1eded3a3257 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -27,6 +27,7 @@ properties:
       - qcom,sm6350-llcc
       - qcom,sm8150-llcc
       - qcom,sm8250-llcc
+      - qcom,sm8350-llcc
 
   reg:
     items:
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:32 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:32 +0530
Subject: [PATCH 8/9] dt-bindings: arm: msm: Add LLCC compatible for SM8450
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <091438d27d802d6f8bb96353bf7ea6cc52fa4e8a.1643353154.git.quic_saipraka@quicinc.com>

Add LLCC compatible for SM8450 SoC.

Cc: Rob Herring <robh at kernel.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index c1eded3a3257..30fcbe2ad8a3 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -28,6 +28,7 @@ properties:
       - qcom,sm8150-llcc
       - qcom,sm8250-llcc
       - qcom,sm8350-llcc
+      - qcom,sm8450-llcc
 
   reg:
     items:
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:09:33 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:39:33 +0530
Subject: [PATCH 9/9] arm64: dts: qcom: sm8450: Add
 LLCC/system-cache-controller node
In-Reply-To: <cover.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <d99178f475900c9d8fa1e2081e5b3427a644f9a9.1643353154.git.quic_saipraka@quicinc.com>

Add a DT node for Last level cache (aka. system cache) controller
which provides control over the last level cache present on SM8450
SoC.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8450.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 10c25ad2d0c7..5a3d050b94f7 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -1102,6 +1102,13 @@ usb_1_dwc3: usb at a600000 {
 				phy-names = "usb2-phy", "usb3-phy";
 			};
 		};
+
+		system-cache-controller at 19200000 {
+			compatible = "qcom,sm8450-llcc";
+			reg = <0 0x19200000 0 0x580000>, <0 0x19a00000 0 0x80000>;
+			reg-names = "llcc_base", "llcc_broadcast_base";
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 
 	timer {
-- 
2.33.1



From srikar at linux.vnet.ibm.com  Thu Jan 27 23:13:37 2022
From: srikar at linux.vnet.ibm.com (Srikar Dronamraju)
Date: Fri, 28 Jan 2022 12:43:37 +0530
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <CAGsJ_4xL3tynB9P=rKMoX2otW4bMMU5Z-P9zSudMV3+fr2hpXw@mail.gmail.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <YfK9DSMFabjYm/MV@BLR-5CG11610CF.amd.com>
 <CAGsJ_4xL3tynB9P=rKMoX2otW4bMMU5Z-P9zSudMV3+fr2hpXw@mail.gmail.com>
Message-ID: <20220128071337.GC618915@linux.vnet.ibm.com>

* Barry Song <21cnbao at gmail.com> [2022-01-28 09:21:08]:

> On Fri, Jan 28, 2022 at 4:41 AM Gautham R. Shenoy
> <gautham.shenoy at amd.com> wrote:
> >
> > On Wed, Jan 26, 2022 at 04:09:47PM +0800, Yicong Yang wrote:
> > > From: Barry Song <song.bao.hua at hisilicon.com>
> > >
> > > For platforms having clusters like Kunpeng920, CPUs within the same
> > > cluster have lower latency when synchronizing and accessing shared
> > > resources like cache. Thus, this patch tries to find an idle cpu
> > > within the cluster of the target CPU before scanning the whole LLC
> > > to gain lower latency.
> > >
> > > Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> > > patch doesn't consider SMT for this moment.
> > >
> > > Testing has been done on Kunpeng920 by pinning tasks to one numa
> > > and two numa. On Kunpeng920, Each numa has 8 clusters and each
> > > cluster has 4 CPUs.
> > >
> > > With this patch, We noticed enhancement on tbench within one
> > > numa or cross two numa.
> > >
> > > On numa 0:
> > >                             5.17-rc1                patched
> > > Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> > > Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> > > Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> > > Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> > > Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> > > Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> > > Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> > > Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> > >
> > > On numa 0-1:
> > >                             5.17-rc1                patched
> > > Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> > > Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> > > Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> > > Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> > > Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> > > Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> > > Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> > > Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> > > Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> > > Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> > >
> > > This will also help to improve the MySQL. With MySQL server
> > > running on numa 0 and client running on numa 1, both QPS and
> > > latency is imporved on read-write case:
> > >                         5.17-rc1        patched
> > > QPS-16threads        143333.2633    145077.4033(+1.22%)
> > > QPS-24threads        195085.9367    202719.6133(+3.91%)
> > > QPS-32threads        241165.6867      249020.74(+3.26%)
> > > QPS-64threads        244586.8433    253387.7567(+3.60%)
> > > avg-lat-16threads           2.23           2.19(+1.19%)
> > > avg-lat-24threads           2.46           2.36(+3.79%)
> > > avg-lat-36threads           2.66           2.57(+3.26%)
> > > avg-lat-64threads           5.23           5.05(+3.44%)
> > >
> > > Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> > > Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> > > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> > > ---
> > >  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++----
> > >  1 file changed, 42 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > > index 5146163bfabb..2f84a933aedd 100644
> > > --- a/kernel/sched/fair.c
> > > +++ b/kernel/sched/fair.c
> > > @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
> > >
> > >  #endif /* CONFIG_SCHED_SMT */
> > >
> > > +#ifdef CONFIG_SCHED_CLUSTER
> > > +/*
> > > + * Scan the cluster domain for idle CPUs and clear cluster cpumask after scanning
> > > + */
> > > +static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
> > > +{
> > > +     struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
> > > +     struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster, target));
> > > +     int cpu, idle_cpu;
> > > +
> > > +     /* TODO: Support SMT case while a machine with both cluster and SMT born */
> > > +     if (!sched_smt_active() && sd) {
> > > +             for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> > > +                     idle_cpu = __select_idle_cpu(cpu, p);
> > > +                     if ((unsigned int)idle_cpu < nr_cpumask_bits)
> > > +                             return idle_cpu;
> > > +             }
> > > +
> > > +             /* Don't ping-pong tasks in and out cluster frequently */
> > > +             if (cpus_share_resources(target, prev_cpu))
> > > +                     return target;
> >
> > We reach here when there aren't any idle CPUs within the
> > cluster. However there might be idle CPUs in the MC domain. Is a busy
> > @target preferable to a potentially idle CPU within the larger domain
> > ?
> 
> Hi Gautham,
> 

Hi Barry,


> My benchmark showed some performance regression while load was medium or above
> if we grabbed idle cpu in and out the cluster. it turned out the
> regression disappeared if
> we blocked the ping-pong. so the logic here is that if we have scanned
> and found an
> idle cpu within the cluster before, we don't let the task jumping back
> and forth frequently
> as cache synchronization is higher cost. but the code still allows
> scanning out of the cluster
> if we haven't packed waker and wakee together yet.
> 

Like what Gautham said, should we choose the same cluster if we find that
there are no idle-cpus in the LLC? This way we avoid ping-pong if there are
no idle-cpus but we still pick an idle-cpu to a busy cpu?

> it might not be a universal win in all kinds of workload. we saw
> tbench, mysql benefit from
> the whole change. but pgbench seems not always. so we are still on the
> way to make possible
> further tuning here.
> 

> >
> >
> > --
> > Thanks and Regards
> > gautham.
> 
> Thanks
> Barry

-- 
Thanks and Regards
Srikar Dronamraju


From biao.huang at mediatek.com  Thu Jan 27 23:05:27 2022
From: biao.huang at mediatek.com (Biao Huang)
Date: Fri, 28 Jan 2022 15:05:27 +0800
Subject: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate
 tx/rx handling with two NAPIs
In-Reply-To: <20220127194338.01722b3c@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
 <20220127015857.9868-10-biao.huang@mediatek.com>
 <20220127194338.01722b3c@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
Message-ID: <2bdb6c9b5ec90b6c606b7db8c13f8acb34910b36.camel@mediatek.com>

Dear Jakub,
	Thanks for your comments!

On Thu, 2022-01-27 at 19:43 -0800, Jakub Kicinski wrote:
> On Thu, 27 Jan 2022 09:58:57 +0800 Biao Huang wrote:
> > Current driver may lost tx interrupts under bidirectional test with
> > iperf3,
> > which leads to some unexpected issues.
> > 
> > This patch let rx/tx interrupt enable/disable separately, and rx/tx
> > are
> > handled in different NAPIs.
> > +/* mtk_star_handle_irq - Interrupt Handler.
> > + * @irq: interrupt number.
> > + * @data: pointer to a network interface device structure.
> 
> if you mean this to me a kdoc comment it needs to start with /**
Yes, will fix in next send.
> 
> > + * Description : this is the driver interrupt service routine.
> > + * it mainly handles:
> > + *  1. tx complete interrupt for frame transmission.
> > + *  2. rx complete interrupt for frame reception.
> > + *  3. MAC Management Counter interrupt to avoid counter overflow.
> >   */
> >  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
> >  {
> > -	struct mtk_star_priv *priv;
> > -	struct net_device *ndev;
> > +	struct net_device *ndev = data;
> > +	struct mtk_star_priv *priv = netdev_priv(ndev);
> > +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> > +	unsigned long flags = 0;
> > +
> > +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> > +		if (napi_schedule_prep(&priv->rx_napi)) {
> > +			spin_lock_irqsave(&priv->lock, flags);
> > +			/* mask Rx Complete interrupt */
> > +			mtk_star_disable_dma_irq(priv, true, false);
> > +			spin_unlock_irqrestore(&priv->lock, flags);
> > +			__napi_schedule_irqoff(&priv->rx_napi);
> > +		}
> > +	}
> >  
> > -	ndev = data;
> > -	priv = netdev_priv(ndev);
> > +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> > +		if (napi_schedule_prep(&priv->tx_napi)) {
> > +			spin_lock_irqsave(&priv->lock, flags);
> > +			/* mask Tx Complete interrupt */
> > +			mtk_star_disable_dma_irq(priv, false, true);
> > +			spin_unlock_irqrestore(&priv->lock, flags);
> > +			__napi_schedule_irqoff(&priv->tx_napi);
> > +		}
> > +	}
> 
> Seems a little wasteful to retake the same lock twice if two IRQ
> sources fire at the same time.
The TX/RX irq control bits are in the same register,
but they are triggered independently.
So it seems necessary to protect the register
access with a spin lock.
> 
> > @@ -1043,6 +1085,17 @@ static int mtk_star_netdev_start_xmit(struct
> > sk_buff *skb,
> >  	struct mtk_star_ring *ring = &priv->tx_ring;
> >  	struct device *dev = mtk_star_get_dev(priv);
> >  	struct mtk_star_ring_desc_data desc_data;
> > +	int nfrags = skb_shinfo(skb)->nr_frags;
> > +
> > +	if (unlikely(mtk_star_tx_ring_avail(ring) < nfrags + 1)) {
> > +		if (!netif_queue_stopped(ndev)) {
> > +			netif_stop_queue(ndev);
> > +			/* This is a hard error, log it. */
> > +			netdev_err(priv->ndev, "%s: Tx Ring full when
> > queue awake\n",
> > +				   __func__);
> 
> This needs to be rate limited. Also no point printing the function
> name, unless the same message appears in multiple places.
OK, will fix in next send.
> 
> > +		}
> > +		return NETDEV_TX_BUSY;
> > +	}
> >  
> >  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
> >  	if (dma_mapping_error(dev, desc_data.dma_addr))
> > @@ -1050,18 +1103,10 @@ static int
> > mtk_star_netdev_start_xmit(struct sk_buff *skb,
> >  
> >  	desc_data.skb = skb;
> >  	desc_data.len = skb->len;
> > -
> > -	spin_lock_bh(&priv->lock);
> > 
> >  	mtk_star_ring_push_head_tx(ring, &desc_data);
> >  
> >  	netdev_sent_queue(ndev, skb->len);
> >  
> > -	if (mtk_star_ring_full(ring))
> > -		netif_stop_queue(ndev);
> 
> Are you stopping the queue in advance somewhere else now? Did you
> only
> test this with BQL enabled? Only place that stops the ring also
> prints
> a loud warning now AFAICS..
No.

We modify the ring full condition, and will not invoke netif_stop_queue
if queue is already stopped.
Test pass no matter whether BQL is enabled or disabled.

It's much safer to judge queue is full or not at the beginning of
start_xmit() to avoid invalid setting.
> 
> > -static void mtk_star_tx_complete_all(struct mtk_star_priv *priv)
> > +static int mtk_star_tx_poll(struct napi_struct *napi, int budget)
> >  {
> > -	struct mtk_star_ring *ring = &priv->tx_ring;
> > -	struct net_device *ndev = priv->ndev;
> > -	int ret, pkts_compl, bytes_compl;
> > +	int ret, pkts_compl = 0, bytes_compl = 0, count = 0;
> > +	struct mtk_star_priv *priv;
> > +	struct mtk_star_ring *ring;
> > +	struct net_device *ndev;
> > +	unsigned long flags = 0;
> > +	unsigned int entry;
> >  	bool wake = false;
> >  
> > -	spin_lock(&priv->lock);
> > +	priv = container_of(napi, struct mtk_star_priv, tx_napi);
> > +	ndev = priv->ndev;
> >  
> > -	for (pkts_compl = 0, bytes_compl = 0;;
> > +	__netif_tx_lock_bh(netdev_get_tx_queue(priv->ndev, 0));
> 
> Do you really need to lock out the Tx while cleaning?
> 
> Drivers usually manage to implement concurrent Tx and cleanup with
> just
> a couple of memory barriers.
We'll simplify the lock handling in next send,
the lock should protect tx descriptor ring, which is accessed by xmit()
and tx_complete().
> 
> > +	ring = &priv->tx_ring;
> > +	entry = ring->tail;
> > +	for (pkts_compl = 0, bytes_compl = 0;
> > +	     (entry != ring->head) && (count < budget);
> 
> budget is not really relevant for Tx, you can clean the whole ring.
> netpoll will pass a budget of 0 to clean up rings.
OK, will fix in next send.
> 
> >  	     pkts_compl++, bytes_compl += ret, wake = true) {
> > -		if (!mtk_star_ring_descs_available(ring))
> > -			break;
> >  
> >  		ret = mtk_star_tx_complete_one(priv);
> >  		if (ret < 0)
> >  			break;
> > +		count++;
> > +		entry = ring->tail;
> >  	}
> >  
> > @@ -1196,7 +1258,7 @@ static const struct ethtool_ops
> > mtk_star_ethtool_ops = {
> >  	.set_link_ksettings	= phy_ethtool_set_link_ksettings,
> >  };
> >  
> > -static int mtk_star_receive_packet(struct mtk_star_priv *priv)
> > +static int mtk_star_rx(struct mtk_star_priv *priv, int budget)
> >  {
> >  	struct mtk_star_ring *ring = &priv->rx_ring;
> >  	struct device *dev = mtk_star_get_dev(priv);
> > @@ -1204,107 +1266,86 @@ static int mtk_star_receive_packet(struct
> > mtk_star_priv *priv)
> >  	struct net_device *ndev = priv->ndev;
> >  	struct sk_buff *curr_skb, *new_skb;
> >  	dma_addr_t new_dma_addr;
> > -	int ret;
> > +	int ret, count = 0;
> >  
> > -	spin_lock(&priv->lock);
> > -	ret = mtk_star_ring_pop_tail(ring, &desc_data);
> > -	spin_unlock(&priv->lock);
> > -	if (ret)
> > -		return -1;
> > +	while (count < budget) {
> > +		ret = mtk_star_ring_pop_tail(ring, &desc_data);
> > +		if (ret)
> > +			return -1;
> > -static int mtk_star_process_rx(struct mtk_star_priv *priv, int
> > budget)
> > -{
> > -	int received, ret;
> > +		count++;
> >  
> > -	for (received = 0, ret = 0; received < budget && ret == 0;
> > received++)
> > -		ret = mtk_star_receive_packet(priv);
> > +		desc_data.len = skb_tailroom(new_skb);
> > +		desc_data.skb = new_skb;
> > +		mtk_star_ring_push_head_rx(ring, &desc_data);
> > +	}
> >  
> >  	mtk_star_dma_resume_rx(priv);
> 
> Again you can get a call with a budget of 0, not sure if it's okay to
> resume DMA in that case..
OK, we'll take it into consideration in next send.
> 
> > -	return received;
> > +	return count;
> >  }
> 
> 
Regards!
Biao

From kavyasree.kotagiri at microchip.com  Thu Jan 27 23:17:55 2022
From: kavyasree.kotagiri at microchip.com (Kavyasree Kotagiri)
Date: Fri, 28 Jan 2022 12:47:55 +0530
Subject: [PATCH v2] crypto: atmel: add support for AES and SHA IPs available
 on lan966x SoC
Message-ID: <20220128071755.25277-1-kavyasree.kotagiri@microchip.com>

This patch adds support for hardware version of AES and SHA IPs
available on lan966x SoC.

Signed-off-by: Kavyasree Kotagiri <kavyasree.kotagiri at microchip.com>
---
v1 -> v2:
- Removed fallthrough line, as it is not required.

 drivers/crypto/atmel-aes.c | 1 +
 drivers/crypto/atmel-sha.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
index fe0558403191..f72c6b3e4ad8 100644
--- a/drivers/crypto/atmel-aes.c
+++ b/drivers/crypto/atmel-aes.c
@@ -2509,6 +2509,7 @@ static void atmel_aes_get_cap(struct atmel_aes_dev *dd)
 
 	/* keep only major version number */
 	switch (dd->hw_version & 0xff0) {
+	case 0x700:
 	case 0x500:
 		dd->caps.has_dualbuff = 1;
 		dd->caps.has_cfb64 = 1;
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
index 1b13f601fd95..d1628112dacc 100644
--- a/drivers/crypto/atmel-sha.c
+++ b/drivers/crypto/atmel-sha.c
@@ -2508,6 +2508,7 @@ static void atmel_sha_get_cap(struct atmel_sha_dev *dd)
 
 	/* keep only major version number */
 	switch (dd->hw_version & 0xff0) {
+	case 0x700:
 	case 0x510:
 		dd->caps.has_dma = 1;
 		dd->caps.has_dualbuff = 1;
-- 
2.17.1



From guoren at kernel.org  Thu Jan 27 23:20:11 2022
From: guoren at kernel.org (Guo Ren)
Date: Fri, 28 Jan 2022 15:20:11 +0800
Subject: [PATCH V3 03/17] asm-generic: compat: Cleanup duplicate
 definitions
In-Reply-To: <CAK8P3a1UmnjHk8B6hSULiKv3FKoY5BW9=4=ESerQzc+4=LR5Zw@mail.gmail.com>
References: <20220120073911.99857-4-guoren@kernel.org>
 <CAK8P3a1UmnjHk8B6hSULiKv3FKoY5BW9=4=ESerQzc+4=LR5Zw@mail.gmail.com>
Message-ID: <CAJF2gTRoVaD0yrh7_Lxwvn9KdYdUeiNH4YhiaY6+G=nt04r9Yw@mail.gmail.com>

On Thu, Jan 20, 2022 at 9:02 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
>   On Thu, Jan 20, 2022 at 8:38 AM <guoren at kernel.org> wrote:
> >
> > From: Guo Ren <guoren at linux.alibaba.com>
> >
> > There are 7 64bit architectures that support Linux COMPAT mode to
> > run 32bit applications. A lot of definitions are duplicate:
> >  - COMPAT_USER_HZ
> >  - COMPAT_RLIM_INFINITY
> >  - COMPAT_OFF_T_MAX
> >  - __compat_uid_t, __compat_uid_t
> >  - compat_dev_t
> >  - compat_ipc_pid_t
> >  - struct compat_flock
> >  - struct compat_flock64
> >  - struct compat_statfs
> >  - struct compat_ipc64_perm, compat_semid64_ds,
> >           compat_msqid64_ds, compat_shmid64_ds
> >
> > Cleanup duplicate definitions and merge them into asm-generic.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Cc: Arnd Bergmann <arnd at arndb.de>
>
> > ---
> >  arch/arm64/include/asm/compat.h   | 108 +++-----------------------
> >  arch/mips/include/asm/compat.h    |  24 ++----
> >  arch/parisc/include/asm/compat.h  |  47 ++----------
> >  arch/powerpc/include/asm/compat.h |  47 ++----------
> >  arch/s390/include/asm/compat.h    | 109 +++-----------------------
> >  arch/sparc/include/asm/compat.h   |  39 ++++------
> >  arch/x86/include/asm/compat.h     | 114 +++-------------------------
> >  include/asm-generic/compat.h      | 122 ++++++++++++++++++++++++++++++
> >  8 files changed, 191 insertions(+), 419 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
> > index eaa6ca062d89..f54f295efae3 100644
> > --- a/arch/arm64/include/asm/compat.h
> > +++ b/arch/arm64/include/asm/compat.h
> > @@ -5,9 +5,18 @@
> >  #ifndef __ASM_COMPAT_H
> >  #define __ASM_COMPAT_H
> >
> > +#define COMPAT_RLIM_INFINITY           0xffffffff
> ...
> > +#ifndef COMPAT_RLIM_INFINITY
> > +#define COMPAT_RLIM_INFINITY   0x7fffffff
> > +#endif
>
> While this is a correct conversion, I think the default should
> be 0xffffffff, to match the asm-generic RLIM_INFINITY
> definition, with only mips and sparc getting the exception
Okay

>
> > -struct compat_flock {
> > -       short           l_type;
> > -       short           l_whence;
> > -       compat_off_t    l_start;
> > -       compat_off_t    l_len;
> > -       compat_pid_t    l_pid;
> > -};
> ...
> > +#ifndef compat_flock
> > +struct compat_flock {
> > +       compat_short_t  l_type;
> > +       compat_short_t  l_whence;
> > +       compat_off_t    l_start;
> > +       compat_off_t    l_len;
> > +       compat_pid_t    l_pid;
> > +} __attribute__((packed));
> > +#endif
>
> You are adding __attribute__((packed)) here, which I think has
> no effect on the layout on the structure on any of the architectures
> but it does change the alignment requirements needlessly.
>
> Better leave it without the attribute.
Okay

>
> > -struct compat_flock64 {
> > -       short           l_type;
> > -       short           l_whence;
> > -       compat_loff_t   l_start;
> > -       compat_loff_t   l_len;
> > -       compat_pid_t    l_pid;
> > -};
> ...
> > +#ifndef compat_flock64
> > +struct compat_flock64 {
> > +       compat_short_t  l_type;
> > +       compat_short_t  l_whence;
> > +       compat_loff_t   l_start;
> > +       compat_loff_t   l_len;
> > +       compat_pid_t    l_pid;
> > +} __attribute__((packed));
> > +#endif
>
> This one is different: on all architectures other than x86,
> the added packed attribute changes the size of the
> structure by removing the four padding bytes at the
> end. x86 originally added the attribute here to work around
> the weirdness of the x86-32 ABI that aligns 64-bit values
> on a 4-byte boundary.
>
> The easiest workaround would be to have x86 keep its
> custom definition. A slightly nicer version would drop the
> attribute on x86 as well but instead change the compat_loff_t
> definition to use compat_s64 instead of s64, giving it the
> correct alignment.
Okay, I would leave x86 origin first.

>
> > -struct compat_statfs {
> > -       int             f_type;
> > -       int             f_bsize;
> > -       int             f_blocks;
> > -       int             f_bfree;
> > -       int             f_bavail;
> > -       int             f_files;
> > -       int             f_ffree;
> > -       compat_fsid_t   f_fsid;
> > -       int             f_namelen;      /* SunOS ignores this field. */
> > -       int             f_frsize;
> > -       int             f_flags;
> > -       int             f_spare[4];
> > -};
> ...
> > +#ifndef compat_statfs
> > +struct compat_statfs {
> > +       compat_uint_t   f_type;
> > +       compat_uint_t   f_bsize;
> > +       compat_uint_t   f_blocks;
> > +       compat_uint_t   f_bfree;
> > +       compat_uint_t   f_bavail;
> > +       compat_uint_t   f_files;
> > +       compat_uint_t   f_ffree;
> > +       __kernel_fsid_t f_fsid;
> > +       compat_uint_t   f_namelen;
> > +       compat_uint_t   f_frsize;
> > +       compat_uint_t   f_flags;
> > +       compat_uint_t   f_spare[4];
> > +} __attribute__((packed));
> > +#endif
>
> None of the architectures use the packed attribute at the moment,
> so please don't add one here.
>
> Changing compat_fsid_t to __kernel_fsid_t is harmless, but seems
> unnecessary.
Okay. I would add another
typedef __kernel_fsid_t compat_fsid_t;
in the file.

>
> Changing the signed int to an unsigned int (regardless of notation)
> may be a change in behavior. s390 is the only architecture
> using unsigned members here at the moment, as of b8668fd0a7e1
> ("s390/uapi: change struct statfs[64] member types to unsigned
> values").
> The description of that patch sounds like this was changed to fix
> a bug, but I don't see what the actual problem would be in the
> put_compat_statfs().
>
> For the moment I'd suggest leaving this with the signed version,
> with s390 being another exception next to mips. We can follow-up
> with merging s390 into the common definition using either the
> signed or unsigned types, but I think that needs to be a separate
> patch with a detailed explanation.
Okay, I would leave s390 origin first.

>
>  +#ifndef compat_ipc64_perm
> > +struct compat_ipc64_perm {
> > +       compat_key_t key;
> > +       __compat_uid32_t uid;
> > +       __compat_gid32_t gid;
> > +       __compat_uid32_t cuid;
> > +       __compat_gid32_t cgid;
> > +       compat_mode_t   mode;
> > +       unsigned char   __pad1[4 - sizeof(compat_mode_t)];
> > +       compat_ushort_t seq;
> > +       compat_ushort_t __pad2;
> > +       compat_ulong_t  unused1;
> > +       compat_ulong_t  unused2;
> > +} __attribute__((packed));
> > +
> > +struct compat_semid64_ds {
> > +       struct compat_ipc64_perm sem_perm;
> > +       compat_ulong_t sem_otime;
> > +       compat_ulong_t sem_otime_high;
> > +       compat_ulong_t sem_ctime;
> > +       compat_ulong_t sem_ctime_high;
> > +       compat_ulong_t sem_nsems;
> > +       compat_ulong_t __unused3;
> > +       compat_ulong_t __unused4;
> > +} __attribute__((packed));
> > +
> > +struct compat_msqid64_ds {
> > +       struct compat_ipc64_perm msg_perm;
> > +       compat_ulong_t msg_stime;
> > +       compat_ulong_t msg_stime_high;
> > +       compat_ulong_t msg_rtime;
> > +       compat_ulong_t msg_rtime_high;
> > +       compat_ulong_t msg_ctime;
> > +       compat_ulong_t msg_ctime_high;
> > +       compat_ulong_t msg_cbytes;
> > +       compat_ulong_t msg_qnum;
> > +       compat_ulong_t msg_qbytes;
> > +       compat_pid_t   msg_lspid;
> > +       compat_pid_t   msg_lrpid;
> > +       compat_ulong_t __unused4;
> > +       compat_ulong_t __unused5;
> > +} __attribute__((packed));
> > +
> > +struct compat_shmid64_ds {
> > +       struct compat_ipc64_perm shm_perm;
> > +       compat_size_t  shm_segsz;
> > +       compat_ulong_t shm_atime;
> > +       compat_ulong_t shm_atime_high;
> > +       compat_ulong_t shm_dtime;
> > +       compat_ulong_t shm_dtime_high;
> > +       compat_ulong_t shm_ctime;
> > +       compat_ulong_t shm_ctime_high;
> > +       compat_pid_t   shm_cpid;
> > +       compat_pid_t   shm_lpid;
> > +       compat_ulong_t shm_nattch;
> > +       compat_ulong_t __unused4;
> > +       compat_ulong_t __unused5;
> > +} __attribute__((packed));
> > +#endif
>
> I checked these in detail, looking at the seven architectures, and your
> conversion looks exactly right (I had initially missed the part about
> compat_mode_t that you got right).
>
> As with compat_flock, the packed attribute has no impact on the layout
> here, but please drop it anyway for consistency.
>
>         Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From shawnguo at kernel.org  Thu Jan 27 23:23:34 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 15:23:34 +0800
Subject: [PATCH] ARM: dts: imx6qdl-dhcom-pdk2: Include missing headers
In-Reply-To: <20211231001214.439733-1-marex@denx.de>
References: <20211231001214.439733-1-marex@denx.de>
Message-ID: <20220128072333.GD4686@dragon>

On Fri, Dec 31, 2021 at 01:12:14AM +0100, Marek Vasut wrote:
> Include missing headers, since this DT source uses symbolic names defined
> in those headers. If an external DT includes this dtsi without including
> the headers as well, the DT becomes unbuildable.
> 
> Three headers are included:
> dt-bindings/gpio/gpio.h -- because this DT contains GPIO_ACTIVE_HIGH
> dt-bindings/input/input.h -- because this DT contains KEY_A
> dt-bindings/pwm/pwm.h -- because this DT contains PWM_POLARITY_INVERTED
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Christoph Niedermaier <cniedermaier at dh-electronics.com>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>
> Cc: kernel at dh-electronics.com

Applied, thanks!


From shawnguo at kernel.org  Thu Jan 27 23:25:14 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 15:25:14 +0800
Subject: [PATCH] ARM: dts: imx6sx-udoo-neo: Add HDMI support
In-Reply-To: <20211231014120.140034-1-festevam@gmail.com>
References: <20211231014120.140034-1-festevam@gmail.com>
Message-ID: <20220128072513.GE4686@dragon>

On Thu, Dec 30, 2021 at 10:41:20PM -0300, Fabio Estevam wrote:
> imx6sx-udoo-neo has a TDA19988 HDMI transmitter connected to the
> parallel eLCDIF interface.
> 
> Add support for it.
> 
> Signed-off-by: Fabio Estevam <festevam at gmail.com>

Applied, thanks!


From shawnguo at kernel.org  Thu Jan 27 23:29:19 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 15:29:19 +0800
Subject: [PATCH v2] arm64: dts: imx8qm: Add SCU RTC node
In-Reply-To: <20220103224900.1439756-1-abel.vesa@nxp.com>
References: <20220103224900.1439756-1-abel.vesa@nxp.com>
Message-ID: <20220128072918.GF4686@dragon>

On Tue, Jan 04, 2022 at 12:49:00AM +0200, Abel Vesa wrote:
> Add SCU RTC node to support SC RTC driver.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>

Applied, thanks!


From quic_saipraka at quicinc.com  Thu Jan 27 23:29:29 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 12:59:29 +0530
Subject: [PATCH 2/9] soc: qcom: llcc: Update the logic for version info
 extraction
In-Reply-To: <e311b16376329b9e9483fed8ae910a31d0f7bcba.1643353154.git.quic_saipraka@quicinc.com>
References: <cover.1643353154.git.quic_saipraka@quicinc.com>
 <e311b16376329b9e9483fed8ae910a31d0f7bcba.1643353154.git.quic_saipraka@quicinc.com>
Message-ID: <8f0d544f-ea79-9fab-9579-7bdfed6dcf1b@quicinc.com>

On 1/28/2022 12:39 PM, Sai Prakash Ranjan wrote:
> LLCC HW version info is made up of major, branch, minor and echo
> version bits each of which are 8bits. Several features in newer
> LLCC HW are based on the full version rather than just major or
> minor versions such as write-subcache enable which is applicable
> for versions greater than v2.0.0.0 and upcoming write-subcache
> cacheable for SM8450 SoC which is only present in versions v2.1.0.0
> and later, so it makes it easier and cleaner to just directly
> compare with the full version than adding additional major/branch/
> minor/echo version checks. So remove the earlier major version check
> and add full version check for those features.
>
> Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
> ---
>   drivers/soc/qcom/llcc-qcom.c       | 9 ++++-----
>   include/linux/soc/qcom/llcc-qcom.h | 4 ++--
>   2 files changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
> index b3a34f117a7c..a06764f16023 100644
> --- a/drivers/soc/qcom/llcc-qcom.c
> +++ b/drivers/soc/qcom/llcc-qcom.c
> @@ -37,7 +37,6 @@
>   #define CACHE_LINE_SIZE_SHIFT         6
>   
>   #define LLCC_COMMON_HW_INFO           0x00030000
> -#define LLCC_MAJOR_VERSION_MASK       GENMASK(31, 24)
>   
>   #define LLCC_COMMON_STATUS0           0x0003000c
>   #define LLCC_LB_CNT_MASK              GENMASK(31, 28)
> @@ -55,6 +54,8 @@
>   
>   #define BANK_OFFSET_STRIDE	      0x80000
>   
> +#define LLCC_VERSION_2_0_0_0          0x02000000
> +
>   /**
>    * struct llcc_slice_config - Data associated with the llcc slice
>    * @usecase_id: Unique id for the client's use case
> @@ -504,7 +505,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
>   			return ret;
>   	}
>   
> -	if (drv_data->major_version == 2) {
> +	if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
>   		u32 wren;
>   
>   		wren = config->write_scid_en << config->slice_id;
> @@ -598,13 +599,11 @@ static int qcom_llcc_probe(struct platform_device *pdev)
>   		goto err;
>   	}
>   
> -	/* Extract major version of the IP */
> +	/* Extract version of the IP */
>   	ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
>   	if (ret)
>   		goto err;
>   
> -	drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version);
> -

Sorry, I missed assigning version info to drv_data here in this version. 
I am sending a v2 with the fix.

Thanks,
Sai

>   	ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
>   						&num_banks);
>   	if (ret)
> diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
> index 9e8fd92c96b7..beecf00b707d 100644
> --- a/include/linux/soc/qcom/llcc-qcom.h
> +++ b/include/linux/soc/qcom/llcc-qcom.h
> @@ -83,7 +83,7 @@ struct llcc_edac_reg_data {
>    * @bitmap: Bit map to track the active slice ids
>    * @offsets: Pointer to the bank offsets array
>    * @ecc_irq: interrupt for llcc cache error detection and reporting
> - * @major_version: Indicates the LLCC major version
> + * @version: Indicates the LLCC version
>    */
>   struct llcc_drv_data {
>   	struct regmap *regmap;
> @@ -96,7 +96,7 @@ struct llcc_drv_data {
>   	unsigned long *bitmap;
>   	u32 *offsets;
>   	int ecc_irq;
> -	u32 major_version;
> +	u32 version;
>   };
>   
>   #if IS_ENABLED(CONFIG_QCOM_LLCC)




From 21cnbao at gmail.com  Thu Jan 27 10:40:15 2022
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 28 Jan 2022 07:40:15 +1300
Subject: [PATCH v2 2/2] sched/fair: Scan cluster before scanning LLC in
 wake-up path
In-Reply-To: <20220128071337.GC618915@linux.vnet.ibm.com>
References: <20220126080947.4529-1-yangyicong@hisilicon.com>
 <20220126080947.4529-3-yangyicong@hisilicon.com>
 <YfK9DSMFabjYm/MV@BLR-5CG11610CF.amd.com>
 <CAGsJ_4xL3tynB9P=rKMoX2otW4bMMU5Z-P9zSudMV3+fr2hpXw@mail.gmail.com>
 <20220128071337.GC618915@linux.vnet.ibm.com>
Message-ID: <CAGsJ_4yoUONACY-j+9XxSNC0VgmdyRdHC=z87dWvZvVSASzXRQ@mail.gmail.com>

On Fri, Jan 28, 2022 at 8:13 PM Srikar Dronamraju
<srikar at linux.vnet.ibm.com> wrote:
>
> * Barry Song <21cnbao at gmail.com> [2022-01-28 09:21:08]:
>
> > On Fri, Jan 28, 2022 at 4:41 AM Gautham R. Shenoy
> > <gautham.shenoy at amd.com> wrote:
> > >
> > > On Wed, Jan 26, 2022 at 04:09:47PM +0800, Yicong Yang wrote:
> > > > From: Barry Song <song.bao.hua at hisilicon.com>
> > > >
> > > > For platforms having clusters like Kunpeng920, CPUs within the same
> > > > cluster have lower latency when synchronizing and accessing shared
> > > > resources like cache. Thus, this patch tries to find an idle cpu
> > > > within the cluster of the target CPU before scanning the whole LLC
> > > > to gain lower latency.
> > > >
> > > > Note neither Kunpeng920 nor x86 Jacobsville supports SMT, so this
> > > > patch doesn't consider SMT for this moment.
> > > >
> > > > Testing has been done on Kunpeng920 by pinning tasks to one numa
> > > > and two numa. On Kunpeng920, Each numa has 8 clusters and each
> > > > cluster has 4 CPUs.
> > > >
> > > > With this patch, We noticed enhancement on tbench within one
> > > > numa or cross two numa.
> > > >
> > > > On numa 0:
> > > >                             5.17-rc1                patched
> > > > Hmean     1        324.73 (   0.00%)      378.01 *  16.41%*
> > > > Hmean     2        645.36 (   0.00%)      754.63 *  16.93%*
> > > > Hmean     4       1302.09 (   0.00%)     1507.54 *  15.78%*
> > > > Hmean     8       2612.03 (   0.00%)     2982.57 *  14.19%*
> > > > Hmean     16      5307.12 (   0.00%)     5886.66 *  10.92%*
> > > > Hmean     32      9354.22 (   0.00%)     9908.13 *   5.92%*
> > > > Hmean     64      7240.35 (   0.00%)     7278.78 *   0.53%*
> > > > Hmean     128     6186.40 (   0.00%)     6187.85 (   0.02%)
> > > >
> > > > On numa 0-1:
> > > >                             5.17-rc1                patched
> > > > Hmean     1        320.01 (   0.00%)      378.44 *  18.26%*
> > > > Hmean     2        643.85 (   0.00%)      752.52 *  16.88%*
> > > > Hmean     4       1287.36 (   0.00%)     1505.62 *  16.95%*
> > > > Hmean     8       2564.60 (   0.00%)     2955.29 *  15.23%*
> > > > Hmean     16      5195.69 (   0.00%)     5814.74 *  11.91%*
> > > > Hmean     32      9769.16 (   0.00%)    10872.63 *  11.30%*
> > > > Hmean     64     15952.50 (   0.00%)    17281.98 *   8.33%*
> > > > Hmean     128    13113.77 (   0.00%)    13895.20 *   5.96%*
> > > > Hmean     256    10997.59 (   0.00%)    11244.69 *   2.25%*
> > > > Hmean     512    14623.60 (   0.00%)    15526.25 *   6.17%*
> > > >
> > > > This will also help to improve the MySQL. With MySQL server
> > > > running on numa 0 and client running on numa 1, both QPS and
> > > > latency is imporved on read-write case:
> > > >                         5.17-rc1        patched
> > > > QPS-16threads        143333.2633    145077.4033(+1.22%)
> > > > QPS-24threads        195085.9367    202719.6133(+3.91%)
> > > > QPS-32threads        241165.6867      249020.74(+3.26%)
> > > > QPS-64threads        244586.8433    253387.7567(+3.60%)
> > > > avg-lat-16threads           2.23           2.19(+1.19%)
> > > > avg-lat-24threads           2.46           2.36(+3.79%)
> > > > avg-lat-36threads           2.66           2.57(+3.26%)
> > > > avg-lat-64threads           5.23           5.05(+3.44%)
> > > >
> > > > Tested-by: Yicong Yang <yangyicong at hisilicon.com>
> > > > Signed-off-by: Barry Song <song.bao.hua at hisilicon.com>
> > > > Signed-off-by: Yicong Yang <yangyicong at hisilicon.com>
> > > > ---
> > > >  kernel/sched/fair.c | 46 +++++++++++++++++++++++++++++++++++++++++----
> > > >  1 file changed, 42 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> > > > index 5146163bfabb..2f84a933aedd 100644
> > > > --- a/kernel/sched/fair.c
> > > > +++ b/kernel/sched/fair.c
> > > > @@ -6262,12 +6262,46 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
> > > >
> > > >  #endif /* CONFIG_SCHED_SMT */
> > > >
> > > > +#ifdef CONFIG_SCHED_CLUSTER
> > > > +/*
> > > > + * Scan the cluster domain for idle CPUs and clear cluster cpumask after scanning
> > > > + */
> > > > +static inline int scan_cluster(struct task_struct *p, int prev_cpu, int target)
> > > > +{
> > > > +     struct cpumask *cpus = this_cpu_cpumask_var_ptr(select_idle_mask);
> > > > +     struct sched_domain *sd = rcu_dereference(per_cpu(sd_cluster, target));
> > > > +     int cpu, idle_cpu;
> > > > +
> > > > +     /* TODO: Support SMT case while a machine with both cluster and SMT born */
> > > > +     if (!sched_smt_active() && sd) {
> > > > +             for_each_cpu_and(cpu, cpus, sched_domain_span(sd)) {
> > > > +                     idle_cpu = __select_idle_cpu(cpu, p);
> > > > +                     if ((unsigned int)idle_cpu < nr_cpumask_bits)
> > > > +                             return idle_cpu;
> > > > +             }
> > > > +
> > > > +             /* Don't ping-pong tasks in and out cluster frequently */
> > > > +             if (cpus_share_resources(target, prev_cpu))
> > > > +                     return target;
> > >
> > > We reach here when there aren't any idle CPUs within the
> > > cluster. However there might be idle CPUs in the MC domain. Is a busy
> > > @target preferable to a potentially idle CPU within the larger domain
> > > ?
> >
> > Hi Gautham,
> >
>
> Hi Barry,
>
>
> > My benchmark showed some performance regression while load was medium or above
> > if we grabbed idle cpu in and out the cluster. it turned out the
> > regression disappeared if
> > we blocked the ping-pong. so the logic here is that if we have scanned
> > and found an
> > idle cpu within the cluster before, we don't let the task jumping back
> > and forth frequently
> > as cache synchronization is higher cost. but the code still allows
> > scanning out of the cluster
> > if we haven't packed waker and wakee together yet.
> >
>
> Like what Gautham said, should we choose the same cluster if we find that
> there are no idle-cpus in the LLC? This way we avoid ping-pong if there are
> no idle-cpus but we still pick an idle-cpu to a busy cpu?

Hi Srikar,
I am sorry I didn't get your question. Currently the code works as below:
if task A wakes up task B, and task A is in LLC0 and task B is in LLC1.
we will scan the cluster of A before scanning the whole LLC0, in this case,
cluster of A is the closest sibling, so it is the better choice than other CPUs
which are in LLC0 but not in the cluster of A. But we do scan all cpus of LLC0
afterwards if we fail to find an idle CPU in the cluster.

After a while, if the cluster of A gets an idle CPU and pulls B into the
cluster, we prefer not pushing B out of the cluster of A again though
there might be an idle CPU outside. as benchmark shows getting an
idle CPU out of the cluster of A doesn't bring performance improvement
but performance decreases as B might be getting in and getting out
the cluster of A very frequently, then cache coherence ping-pong.

Note we are only returning target while if
(cpus_share_resources(target, prev_cpu))
is true. So we are not losing chance to pull B to the LLC of A while LLC0 has
an idle one.

>
> > it might not be a universal win in all kinds of workload. we saw
> > tbench, mysql benefit from
> > the whole change. but pgbench seems not always. so we are still on the
> > way to make possible
> > further tuning here.
> >
>
> > >
> > >
> > > --
> > > Thanks and Regards
> > > gautham.
> >
> > Thanks
> > Barry
>
> --
> Thanks and Regards
> Srikar Dronamraju

Thanks
Barry


From krzysztof.kozlowski at canonical.com  Thu Jan 27 23:46:27 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Fri, 28 Jan 2022 08:46:27 +0100
Subject: [GIT PULL] arm64: dts: samsung: Second pull for v5.17
In-Reply-To: <CAPLW+4=Hj-vamn5EoV-SmB5JwEbuik9hF2XuhB+tU11GwXPQdg@mail.gmail.com>
References: <20211227112959.7325-1-krzysztof.kozlowski@canonical.com>
 <cb11d2e0-dd03-9a48-74f3-0a22f49f16b5@canonical.com>
 <CAPLW+4=Hj-vamn5EoV-SmB5JwEbuik9hF2XuhB+tU11GwXPQdg@mail.gmail.com>
Message-ID: <51ce758d-b96d-c9b1-b439-e97cc59d1052@canonical.com>

On 27/01/2022 17:58, Sam Protsenko wrote:
> On Thu, 27 Jan 2022 at 11:33, Krzysztof Kozlowski
> <krzysztof.kozlowski at canonical.com> wrote:
>>
>> On 27/12/2021 12:29, Krzysztof Kozlowski wrote:
>>> Hi,
>>>
>>> Second pull with DTS for ARM64, on top of previous pull.
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>>
>>> The following changes since commit 51b1a5729469cef57a3c97aa014aa6e1d2b8d864:
>>>
>>>   dt-bindings: pinctrl: samsung: Add pin drive definitions for Exynos850 (2021-12-20 10:35:32 +0100)
>>>
>>> are available in the Git repository at:
>>>
>>>   https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt64-5.17-2
>>>
>>> for you to fetch changes up to a1828d772e0738c30a383a7d335aded2f2baf908:
>>>
>>>   arm64: dts: exynos: Add initial E850-96 board support (2021-12-22 12:31:13 +0100)
>>>
>>> ----------------------------------------------------------------
>>> Samsung DTS ARM64 changes for v5.17, part two
>>>
>>> Add initial Exynos850 support and WinLink E850-96 board using it.
>>>
>>> ----------------------------------------------------------------
>>> Sam Protsenko (2):
>>>       arm64: dts: exynos: Add initial Exynos850 SoC support
>>>       arm64: dts: exynos: Add initial E850-96 board support
>>>
>>
>> I'll send all this as v5.18 material, so this pull-req can be skipped.
>>
> 
> Krzysztof,
> 
> As clock changes are merged in mainline now, do you want me to re-send
> those two dts patches using corresponding clock constants, instead of
> hard-coded numbers?

Yes, please.

Best regards,
Krzysztof


From quic_saipraka at quicinc.com  Thu Jan 27 23:47:07 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:07 +0530
Subject: [PATCHv2 0/9] soc: qcom: llcc: Add LLCC support for SM8450 SoC
Message-ID: <cover.1643355594.git.quic_saipraka@quicinc.com>

This patch series adds support for LLCC on SM8450 SoC. It mainly
consists of LLCC driver changes to incorporate newer LLCC HW found
on SM8450 SoC and the corresponding DT bits to enable LLCC.
Based on qcom/for-next branch.

Changes in v2:
 * Fix version assignment to drv_data.

Huang Yiwei (1):
  soc: qcom: llcc: Add support for 16 ways of allocation

Sai Prakash Ranjan (8):
  soc: qcom: llcc: Update the logic for version info extraction
  soc: qcom: llcc: Add write-cache cacheable support
  soc: qcom: llcc: Add missing llcc configuration data
  soc: qcom: llcc: Update register offsets for newer LLCC HW
  soc: qcom: llcc: Add configuration data for SM8450 SoC
  dt-bindings: arm: msm: Add LLCC compatible for SM8350
  dt-bindings: arm: msm: Add LLCC compatible for SM8450
  arm64: dts: qcom: sm8450: Add LLCC/system-cache-controller node

 .../bindings/arm/msm/qcom,llcc.yaml           |   2 +
 arch/arm64/boot/dts/qcom/sm8450.dtsi          |   7 ++
 drivers/soc/qcom/llcc-qcom.c                  | 102 +++++++++++++++---
 include/linux/soc/qcom/llcc-qcom.h            |   9 +-
 4 files changed, 105 insertions(+), 15 deletions(-)

-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:08 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:08 +0530
Subject: [PATCHv2 1/9] soc: qcom: llcc: Add support for 16 ways of allocation
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <a7a5f64259c2c02628f03fb59b91e9fa78da2dfb.1643355594.git.quic_saipraka@quicinc.com>

From: Huang Yiwei <hyiwei at codeaurora.org>

Add support for 16 ways of allocation for LLCC HW version 2.1.0
and later.

Signed-off-by: Huang Yiwei <hyiwei at codeaurora.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index ec52f29c8867..b3a34f117a7c 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -29,8 +29,8 @@
 #define ATTR1_FIXED_SIZE_SHIFT        0x03
 #define ATTR1_PRIORITY_SHIFT          0x04
 #define ATTR1_MAX_CAP_SHIFT           0x10
-#define ATTR0_RES_WAYS_MASK           GENMASK(11, 0)
-#define ATTR0_BONUS_WAYS_MASK         GENMASK(27, 16)
+#define ATTR0_RES_WAYS_MASK           GENMASK(15, 0)
+#define ATTR0_BONUS_WAYS_MASK         GENMASK(31, 16)
 #define ATTR0_BONUS_WAYS_SHIFT        0x10
 #define LLCC_STATUS_READ_DELAY        100
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:09 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:09 +0530
Subject: [PATCHv2 2/9] soc: qcom: llcc: Update the logic for version info
 extraction
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <a82d7c32348c51fcc2b63e220d91b318bf706c83.1643355594.git.quic_saipraka@quicinc.com>

LLCC HW version info is made up of major, branch, minor and echo
version bits each of which are 8bits. Several features in newer
LLCC HW are based on the full version rather than just major or
minor versions such as write-subcache enable which is applicable
for versions v2.0.0.0 and later, also upcoming write-subcache
cacheable for SM8450 SoC which is only present in versions v2.1.0.0
and later, so it makes it easier and cleaner to just directly
compare with the full version than adding additional major/branch/
minor/echo version checks. So remove the earlier major version check
and add full version check for those features.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c       | 9 +++++----
 include/linux/soc/qcom/llcc-qcom.h | 4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index b3a34f117a7c..8d4953800fa9 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -37,7 +37,6 @@
 #define CACHE_LINE_SIZE_SHIFT         6
 
 #define LLCC_COMMON_HW_INFO           0x00030000
-#define LLCC_MAJOR_VERSION_MASK       GENMASK(31, 24)
 
 #define LLCC_COMMON_STATUS0           0x0003000c
 #define LLCC_LB_CNT_MASK              GENMASK(31, 28)
@@ -55,6 +54,8 @@
 
 #define BANK_OFFSET_STRIDE	      0x80000
 
+#define LLCC_VERSION_2_0_0_0          0x02000000
+
 /**
  * struct llcc_slice_config - Data associated with the llcc slice
  * @usecase_id: Unique id for the client's use case
@@ -504,7 +505,7 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
 			return ret;
 	}
 
-	if (drv_data->major_version == 2) {
+	if (drv_data->version >= LLCC_VERSION_2_0_0_0) {
 		u32 wren;
 
 		wren = config->write_scid_en << config->slice_id;
@@ -598,12 +599,12 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
-	/* Extract major version of the IP */
+	/* Extract version of the IP */
 	ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
 	if (ret)
 		goto err;
 
-	drv_data->major_version = FIELD_GET(LLCC_MAJOR_VERSION_MASK, version);
+	drv_data->version = version;
 
 	ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
 						&num_banks);
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index 9e8fd92c96b7..beecf00b707d 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -83,7 +83,7 @@ struct llcc_edac_reg_data {
  * @bitmap: Bit map to track the active slice ids
  * @offsets: Pointer to the bank offsets array
  * @ecc_irq: interrupt for llcc cache error detection and reporting
- * @major_version: Indicates the LLCC major version
+ * @version: Indicates the LLCC version
  */
 struct llcc_drv_data {
 	struct regmap *regmap;
@@ -96,7 +96,7 @@ struct llcc_drv_data {
 	unsigned long *bitmap;
 	u32 *offsets;
 	int ecc_irq;
-	u32 major_version;
+	u32 version;
 };
 
 #if IS_ENABLED(CONFIG_QCOM_LLCC)
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:10 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:10 +0530
Subject: [PATCHv2 3/9] soc: qcom: llcc: Add write-cache cacheable support
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <83372c8178f579d055ec58212ce5af5d55abadd4.1643355594.git.quic_saipraka@quicinc.com>

Newer SoCs with LLCC IP version 2.1.0.0 and later support write
sub-cache cacheable feature. Use a separate llcc_slice_config member
"write_scid_cacheable_en" to identify this feature and program
LLCC_TRP_SCID_WRSC_CACHEABLE_EN register to enable it.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index 8d4953800fa9..e845d3919ef3 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -51,10 +51,12 @@
 #define LLCC_TRP_SCID_DIS_CAP_ALLOC   0x21f00
 #define LLCC_TRP_PCB_ACT              0x21f04
 #define LLCC_TRP_WRSC_EN              0x21f20
+#define LLCC_TRP_WRSC_CACHEABLE_EN    0x21f2c
 
 #define BANK_OFFSET_STRIDE	      0x80000
 
 #define LLCC_VERSION_2_0_0_0          0x02000000
+#define LLCC_VERSION_2_1_0_0          0x02010000
 
 /**
  * struct llcc_slice_config - Data associated with the llcc slice
@@ -80,6 +82,8 @@
  *               collapse.
  * @activate_on_init: Activate the slice immediately after it is programmed
  * @write_scid_en: Bit enables write cache support for a given scid.
+ * @write_scid_cacheable_en: Enables write cache cacheable support for a
+ *			     given scid (not supported on v2 or older hardware).
  */
 struct llcc_slice_config {
 	u32 usecase_id;
@@ -95,6 +99,7 @@ struct llcc_slice_config {
 	bool retain_on_pc;
 	bool activate_on_init;
 	bool write_scid_en;
+	bool write_scid_cacheable_en;
 };
 
 struct qcom_llcc_config {
@@ -515,6 +520,16 @@ static int _qcom_llcc_cfg_program(const struct llcc_slice_config *config,
 			return ret;
 	}
 
+	if (drv_data->version >= LLCC_VERSION_2_1_0_0) {
+		u32 wr_cache_en;
+
+		wr_cache_en = config->write_scid_cacheable_en << config->slice_id;
+		ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_WRSC_CACHEABLE_EN,
+					 BIT(config->slice_id), wr_cache_en);
+		if (ret)
+			return ret;
+	}
+
 	if (config->activate_on_init) {
 		desc.slice_id = config->slice_id;
 		ret = llcc_slice_activate(&desc);
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:11 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:11 +0530
Subject: [PATCHv2 4/9] soc: qcom: llcc: Add missing llcc configuration data
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <143d11bacaca086406fdd10fc32f91eccd943527.1643355594.git.quic_saipraka@quicinc.com>

Add missing llcc configuration data for few chipsets which
were not added during initial post.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index e845d3919ef3..a791213a99e0 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -244,21 +244,25 @@ static const struct qcom_llcc_config sdm845_cfg = {
 static const struct qcom_llcc_config sm6350_cfg = {
 	.sct_data	= sm6350_data,
 	.size		= ARRAY_SIZE(sm6350_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8150_cfg = {
 	.sct_data       = sm8150_data,
 	.size           = ARRAY_SIZE(sm8150_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8250_cfg = {
 	.sct_data       = sm8250_data,
 	.size           = ARRAY_SIZE(sm8250_data),
+	.need_llcc_cfg	= true,
 };
 
 static const struct qcom_llcc_config sm8350_cfg = {
 	.sct_data       = sm8350_data,
 	.size           = ARRAY_SIZE(sm8350_data),
+	.need_llcc_cfg	= true,
 };
 
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:12 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:12 +0530
Subject: [PATCHv2 5/9] soc: qcom: llcc: Update register offsets for newer LLCC
 HW
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <c655d16d945aef2d7fc8e7c212f3e1c58a84eb95.1643355594.git.quic_saipraka@quicinc.com>

Newer LLCC HW have different register offsets for several registers,
currently of which LLCC hardware info and status are used to identify
the LLCC version information and other data. So use separate table to
keep track of these register offsets which vary by different LLCC HW
versions and eases any future addition in variations of register offsets
for newer hardware.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index a791213a99e0..ea93740cc671 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -36,9 +36,6 @@
 
 #define CACHE_LINE_SIZE_SHIFT         6
 
-#define LLCC_COMMON_HW_INFO           0x00030000
-
-#define LLCC_COMMON_STATUS0           0x0003000c
 #define LLCC_LB_CNT_MASK              GENMASK(31, 28)
 #define LLCC_LB_CNT_SHIFT             28
 
@@ -106,6 +103,12 @@ struct qcom_llcc_config {
 	const struct llcc_slice_config *sct_data;
 	int size;
 	bool need_llcc_cfg;
+	const u32 *reg_offset;
+};
+
+enum llcc_reg_offset {
+	LLCC_COMMON_HW_INFO,
+	LLCC_COMMON_STATUS0,
 };
 
 static const struct llcc_slice_config sc7180_data[] =  {
@@ -223,46 +226,63 @@ static const struct llcc_slice_config sm8350_data[] =  {
 	{ LLCC_CPUHWT,   5, 512,   1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
 };
 
+static const u32 llcc_v1_2_reg_offset[] = {
+	[LLCC_COMMON_HW_INFO]	= 0x00030000,
+	[LLCC_COMMON_STATUS0]	= 0x0003000c,
+};
+
+static const u32 llcc_v21_reg_offset[] = {
+	[LLCC_COMMON_HW_INFO]	= 0x00034000,
+	[LLCC_COMMON_STATUS0]	= 0x0003400c,
+};
+
 static const struct qcom_llcc_config sc7180_cfg = {
 	.sct_data	= sc7180_data,
 	.size		= ARRAY_SIZE(sc7180_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sc7280_cfg = {
 	.sct_data	= sc7280_data,
 	.size		= ARRAY_SIZE(sc7280_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sdm845_cfg = {
 	.sct_data	= sdm845_data,
 	.size		= ARRAY_SIZE(sdm845_data),
 	.need_llcc_cfg	= false,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm6350_cfg = {
 	.sct_data	= sm6350_data,
 	.size		= ARRAY_SIZE(sm6350_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8150_cfg = {
 	.sct_data       = sm8150_data,
 	.size           = ARRAY_SIZE(sm8150_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8250_cfg = {
 	.sct_data       = sm8250_data,
 	.size           = ARRAY_SIZE(sm8250_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static const struct qcom_llcc_config sm8350_cfg = {
 	.sct_data       = sm8350_data,
 	.size           = ARRAY_SIZE(sm8350_data),
 	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
@@ -618,15 +638,18 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 		goto err;
 	}
 
+	cfg = of_device_get_match_data(&pdev->dev);
+
 	/* Extract version of the IP */
-	ret = regmap_read(drv_data->bcast_regmap, LLCC_COMMON_HW_INFO, &version);
+	ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO],
+			  &version);
 	if (ret)
 		goto err;
 
 	drv_data->version = version;
 
-	ret = regmap_read(drv_data->regmap, LLCC_COMMON_STATUS0,
-						&num_banks);
+	ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0],
+			  &num_banks);
 	if (ret)
 		goto err;
 
@@ -634,7 +657,6 @@ static int qcom_llcc_probe(struct platform_device *pdev)
 	num_banks >>= LLCC_LB_CNT_SHIFT;
 	drv_data->num_banks = num_banks;
 
-	cfg = of_device_get_match_data(&pdev->dev);
 	llcc_cfg = cfg->sct_data;
 	sz = cfg->size;
 
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:13 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:13 +0530
Subject: [PATCHv2 6/9] soc: qcom: llcc: Add configuration data for SM8450 SoC
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <fec944cb8f2a4a70785903c6bfec629c6f31b6a4.1643355594.git.quic_saipraka@quicinc.com>

Add LLCC configuration data for SM8450 SoC.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 drivers/soc/qcom/llcc-qcom.c       | 34 ++++++++++++++++++++++++++++++
 include/linux/soc/qcom/llcc-qcom.h |  5 +++++
 2 files changed, 39 insertions(+)

diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c
index ea93740cc671..53816e66d877 100644
--- a/drivers/soc/qcom/llcc-qcom.c
+++ b/drivers/soc/qcom/llcc-qcom.c
@@ -226,6 +226,32 @@ static const struct llcc_slice_config sm8350_data[] =  {
 	{ LLCC_CPUHWT,   5, 512,   1, 1, 0xfff, 0x0, 0, 0, 0, 0, 0, 1 },
 };
 
+static const struct llcc_slice_config sm8450_data[] =  {
+	{LLCC_CPUSS,     1, 3072, 1, 0, 0xFFFF, 0x0,   0, 0, 0, 1, 1, 0, 0 },
+	{LLCC_VIDSC0,    2,  512, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AUDIO,     6, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+	{LLCC_MDMHPGRW,  7, 1024, 3, 0, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MODHW,     9, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CMPT,     10, 4096, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_GPUHTW,   11,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_GPU,      12, 2048, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 1, 0 },
+	{LLCC_MMUHWT,   13,  768, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_DISP,     16, 4096, 2, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MDMPNG,   21, 1024, 1, 1, 0xF000, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AUDHW,    22, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+	{LLCC_CVP,      28,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_MODPE,    29,   64, 1, 1, 0xF000, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_APTCM,    30, 1024, 3, 1, 0x0,    0xF0,  1, 0, 0, 1, 0, 0, 0 },
+	{LLCC_WRCACHE,  31,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_CVPFW,    17,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CPUSS1,    3, 1024, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CAMEXP0,   4,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_CPUMTE,   23,  256, 1, 1, 0x0FFF, 0x0,   0, 0, 0, 0, 1, 0, 0 },
+	{LLCC_CPUHWT,    5,  512, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 1, 0, 0 },
+	{LLCC_CAMEXP1,  27,  256, 3, 1, 0xFFFF, 0x0,   0, 0, 0, 1, 0, 0, 0 },
+	{LLCC_AENPU,     8, 2048, 1, 1, 0xFFFF, 0x0,   0, 0, 0, 0, 0, 0, 0 },
+};
+
 static const u32 llcc_v1_2_reg_offset[] = {
 	[LLCC_COMMON_HW_INFO]	= 0x00030000,
 	[LLCC_COMMON_STATUS0]	= 0x0003000c,
@@ -285,6 +311,13 @@ static const struct qcom_llcc_config sm8350_cfg = {
 	.reg_offset	= llcc_v1_2_reg_offset,
 };
 
+static const struct qcom_llcc_config sm8450_cfg = {
+	.sct_data       = sm8450_data,
+	.size           = ARRAY_SIZE(sm8450_data),
+	.need_llcc_cfg	= true,
+	.reg_offset	= llcc_v21_reg_offset,
+};
+
 static struct llcc_drv_data *drv_data = (void *) -EPROBE_DEFER;
 
 /**
@@ -714,6 +747,7 @@ static const struct of_device_id qcom_llcc_of_match[] = {
 	{ .compatible = "qcom,sm8150-llcc", .data = &sm8150_cfg },
 	{ .compatible = "qcom,sm8250-llcc", .data = &sm8250_cfg },
 	{ .compatible = "qcom,sm8350-llcc", .data = &sm8350_cfg },
+	{ .compatible = "qcom,sm8450-llcc", .data = &sm8450_cfg },
 	{ }
 };
 
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h
index beecf00b707d..0bc21ee58fac 100644
--- a/include/linux/soc/qcom/llcc-qcom.h
+++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -35,7 +35,12 @@
 #define LLCC_WRCACHE     31
 #define LLCC_CVPFW       32
 #define LLCC_CPUSS1      33
+#define LLCC_CAMEXP0     34
+#define LLCC_CPUMTE      35
 #define LLCC_CPUHWT      36
+#define LLCC_MDMCLAD2    37
+#define LLCC_CAMEXP1     38
+#define LLCC_AENPU       45
 
 /**
  * struct llcc_slice_desc - Cache slice descriptor
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:14 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:14 +0530
Subject: [PATCHv2 7/9] dt-bindings: arm: msm: Add LLCC compatible for SM8350
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <e3d200eb06949f7e216b7f82f5811b7addb7fdc8.1643355594.git.quic_saipraka@quicinc.com>

Add LLCC compatible for SM8350 SoC.

Cc: Rob Herring <robh at kernel.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index 03882aac8d2d..c1eded3a3257 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -27,6 +27,7 @@ properties:
       - qcom,sm6350-llcc
       - qcom,sm8150-llcc
       - qcom,sm8250-llcc
+      - qcom,sm8350-llcc
 
   reg:
     items:
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:15 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:15 +0530
Subject: [PATCHv2 8/9] dt-bindings: arm: msm: Add LLCC compatible for SM8450
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <f5235371f07ac0ce367c6ea84ed49937fb751a07.1643355594.git.quic_saipraka@quicinc.com>

Add LLCC compatible for SM8450 SoC.

Cc: Rob Herring <robh at kernel.org>
Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
index c1eded3a3257..30fcbe2ad8a3 100644
--- a/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
+++ b/Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
@@ -28,6 +28,7 @@ properties:
       - qcom,sm8150-llcc
       - qcom,sm8250-llcc
       - qcom,sm8350-llcc
+      - qcom,sm8450-llcc
 
   reg:
     items:
-- 
2.33.1



From quic_saipraka at quicinc.com  Thu Jan 27 23:47:16 2022
From: quic_saipraka at quicinc.com (Sai Prakash Ranjan)
Date: Fri, 28 Jan 2022 13:17:16 +0530
Subject: [PATCHv2 9/9] arm64: dts: qcom: sm8450: Add
 LLCC/system-cache-controller node
In-Reply-To: <cover.1643355594.git.quic_saipraka@quicinc.com>
References: <cover.1643355594.git.quic_saipraka@quicinc.com>
Message-ID: <7995d003b77d5e066658af5b2cfa22ccb40b6cf7.1643355594.git.quic_saipraka@quicinc.com>

Add a DT node for Last level cache (aka. system cache) controller
which provides control over the last level cache present on SM8450
SoC.

Signed-off-by: Sai Prakash Ranjan <quic_saipraka at quicinc.com>
---
 arch/arm64/boot/dts/qcom/sm8450.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi
index 10c25ad2d0c7..5a3d050b94f7 100644
--- a/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -1102,6 +1102,13 @@ usb_1_dwc3: usb at a600000 {
 				phy-names = "usb2-phy", "usb3-phy";
 			};
 		};
+
+		system-cache-controller at 19200000 {
+			compatible = "qcom,sm8450-llcc";
+			reg = <0 0x19200000 0 0x580000>, <0 0x19a00000 0 0x80000>;
+			reg-names = "llcc_base", "llcc_broadcast_base";
+			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+		};
 	};
 
 	timer {
-- 
2.33.1



From jianjun.wang at mediatek.com  Thu Jan 27 23:58:25 2022
From: jianjun.wang at mediatek.com (Jianjun Wang)
Date: Fri, 28 Jan 2022 15:58:25 +0800
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220127212100.GA102267@bhelgaas>
References: <20220127212100.GA102267@bhelgaas>
Message-ID: <06cfb0231f084936ede1b252101861c1787de25f.camel@mediatek.com>

Hi Bjorn,

On Thu, 2022-01-27 at 15:21 -0600, Bjorn Helgaas wrote:
> [+cc Srikanth, Pratyush, Thomas, Pali, Ryder, Jianjun]
> 
> On Wed, Jan 26, 2022 at 11:37:58AM +0800, qizhong.cheng wrote:
> > On Tue, 2022-01-25 at 17:21 +0000, Marc Zyngier wrote:
> > > On 2022-01-25 16:57, Bjorn Helgaas wrote:
> > > > On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> > > > > As an edge-triggered interrupts, its interrupt status should
> > > > > be cleared before dispatch to the handler of device.
> > > > 
> > > > I'm not an IRQ expert, but the reasoning that "we should clear
> > > > the MSI interrupt status before dispatching the handler because
> > > > MSI is an edge-triggered interrupt" doesn't seem completely
> > > > convincing because your code will now look like this:
> > > > 
> > > >   /* Clear the INTx */
> > > >   writel(1 << bit, port->base + PCIE_INT_STATUS);
> > > >   generic_handle_domain_irq(port->irq_domain, bit -
> > > > INTX_SHIFT);
> > > >   ...
> > > > 
> > > >   /* Clear MSI interrupt status */
> > > >   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
> > > >   generic_handle_domain_irq(port->inner_domain, bit);
> > > > 
> > > > You clear interrupt status before dispatching the handler for
> > > > *both* level-triggered INTx interrupts and edge-triggered MSI
> > > > interrupts.
> > > > 
> > > > So it doesn't seem that simply being edge-triggered is the
> > > > critical factor here.
> > > 
> > > This is the usual problem with these half-baked implementations.
> > > The signalling to the primary interrupt controller is level, as
> > > they take a multitude of input and (crucially) latch the MSI
> > > edges. Effectively, this is an edge-to-level converter, with all
> > > the problems that this creates.
> > > 
> > > By clearing the status *after* the handling, you lose edges that
> > > have been received and coalesced after the read of the status
> > > register. By clearing it *before*, you are acknowledging the
> > > interrupts early, and allowing them to be coalesced independently
> > > of the ones that have been received earlier.
> > > 
> > > This is however mostly an educated guess. Someone with access to
> > > the TRM should verify this.
> > 
> > Yes, as Maz said, we save the edge-interrupt status so that it
> > becomes a level-interrupt. This is similar to an edge-to-level
> > converter, so we need to clear it *before*. We found this problem
> > through a lot of experiments and tested this patch.
> 
> I thought there might be other host controllers with similar design,
> so I looked at all the other drivers and tried to figure out whether
> any others had similar problems.
> 
> The ones below look suspicious to me because they all clear some sort
> of status register *after* handling an MSI.  Can you guys take a look
> and make sure they are working correctly?
> 
>   keembay_pcie_msi_irq_handler
>     status = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
>     if (status & MSI_CTRL_INT)
>       dw_handle_msi_irq
> 	generic_handle_domain_irq
>       writel(status, pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
> 
>   spear13xx_pcie_irq_handler
>     status = readl(&app_reg->int_sts)
>     if (status & MSI_CTRL_INT)
>       dw_handle_msi_irq
> 	generic_handle_domain_irq
>     writel(status, &app_reg->int_clr)
> 
>   advk_pcie_handle_int
>     isr0_status = advk_readl(pcie, PCIE_ISR0_REG)
>     if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
>       advk_pcie_handle_msi
>         advk_readl(pcie, PCIE_MSI_STATUS_REG)
> 	advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG)
> 	generic_handle_irq
> 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG)
> 
>   mtk_pcie_irq_handler
>     status = readl_relaxed(pcie->base + PCIE_INT_STATUS_REG)
>     for_each_set_bit_from(irq_bit, &status, ...)
>       mtk_pcie_msi_handler
>         generic_handle_domain_irq
>       writel_relaxed(BIT(irq_bit), pcie->base + PCIE_INT_STATUS_REG)

Thanks for mention that. In the hardware corresponding to pcie-
mediatek-gen3.c, the interrupt status in PCIE_INT_STATUS_REG cannot be
cleared if the MSI status remaining in the register of msi_set, so we
have to clear it after handling the MSI.

I guess the root cause of this patch is the interrupt status can be
cleared even the MSI status still remaining, hence that if there are
some MSIs received while clearing the interrupt status, these MSIs
cannot be serviced.

We will discuss and test internally and update the results later,
thanks for your review.

Thanks.

> 
> Bjorn

From yong.wu at mediatek.com  Fri Jan 28 00:11:01 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 28 Jan 2022 16:11:01 +0800
Subject: [RFC PATCH] component: Add common helpers for compare/release
 functions
Message-ID: <20220128081101.27837-1-yong.wu@mediatek.com>

The component requires the compare/release functions, there are so many
copy in current kernel. Just define three common helpers for them.
No functional change.

Signed-off-by: Yong Wu <yong.wu at mediatek.com>
---
Base on v5.17-rc1
---
 .../gpu/drm/arm/display/komeda/komeda_drv.c    |  5 -----
 drivers/gpu/drm/arm/hdlcd_drv.c                |  7 +------
 drivers/gpu/drm/armada/armada_drv.c            |  5 -----
 drivers/gpu/drm/drm_of.c                       |  8 +-------
 drivers/gpu/drm/etnaviv/etnaviv_drv.c          |  7 -------
 drivers/gpu/drm/exynos/exynos_drm_drv.c        |  5 -----
 .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c    |  5 -----
 drivers/gpu/drm/imx/imx-drm-core.c             |  4 ++--
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c      |  5 -----
 drivers/gpu/drm/mcde/mcde_drv.c                |  7 +------
 drivers/gpu/drm/mediatek/mtk_drm_drv.c         |  5 -----
 drivers/gpu/drm/meson/meson_drv.c              |  8 --------
 drivers/gpu/drm/msm/msm_drv.c                  |  9 ---------
 drivers/gpu/drm/omapdrm/dss/dss.c              |  8 +-------
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c    |  5 -----
 drivers/gpu/drm/sti/sti_drv.c                  |  5 -----
 drivers/gpu/drm/sun4i/sun4i_drv.c              |  9 ---------
 drivers/gpu/drm/vc4/vc4_drv.c                  |  5 -----
 drivers/iommu/mtk_iommu.h                      | 10 ----------
 drivers/power/supply/ab8500_charger.c          |  8 +-------
 drivers/video/fbdev/omap2/omapfb/dss/dss.c     |  8 +-------
 include/linux/component.h                      | 18 ++++++++++++++++++
 sound/soc/codecs/wcd938x.c                     | 16 ++--------------
 23 files changed, 28 insertions(+), 144 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index e7933930a657..fe5b97107417 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -92,11 +92,6 @@ static const struct component_master_ops komeda_master_ops = {
 	.unbind	= komeda_unbind,
 };
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static void komeda_add_slave(struct device *master,
 			     struct component_match **match,
 			     struct device_node *np,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 479c2422a2e0..36d84c439df8 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -372,11 +372,6 @@ static const struct component_master_ops hdlcd_master_ops = {
 	.unbind		= hdlcd_drm_unbind,
 };
 
-static int compare_dev(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static int hdlcd_probe(struct platform_device *pdev)
 {
 	struct device_node *port;
@@ -387,7 +382,7 @@ static int hdlcd_probe(struct platform_device *pdev)
 	if (!port)
 		return -ENODEV;
 
-	drm_of_component_match_add(&pdev->dev, &match, compare_dev, port);
+	drm_of_component_match_add(&pdev->dev, &match, compare_of, port);
 	of_node_put(port);
 
 	return component_master_add_with_match(&pdev->dev, &hdlcd_master_ops,
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 8e3e98f13db4..9edc4912c1a0 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -177,11 +177,6 @@ static void armada_drm_unbind(struct device *dev)
 	drm_mm_takedown(&priv->linear);
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static int compare_dev_name(struct device *dev, void *data)
 {
 	const char *name = data;
diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
index 59d368ea006b..f958f48f8ba4 100644
--- a/drivers/gpu/drm/drm_of.c
+++ b/drivers/gpu/drm/drm_of.c
@@ -18,11 +18,6 @@
  * properties.
  */
 
-static void drm_release_of(struct device *dev, void *data)
-{
-	of_node_put(data);
-}
-
 /**
  * drm_of_crtc_port_mask - find the mask of a registered CRTC by port OF node
  * @dev: DRM device
@@ -94,8 +89,7 @@ void drm_of_component_match_add(struct device *master,
 				struct device_node *node)
 {
 	of_node_get(node);
-	component_match_add_release(master, matchptr, drm_release_of,
-				    compare, node);
+	component_match_add_release(master, matchptr, release_of, compare, node);
 }
 EXPORT_SYMBOL_GPL(drm_of_component_match_add);
 
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 0b756ecb1bc2..15351e26ab00 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -574,13 +574,6 @@ static const struct component_master_ops etnaviv_master_ops = {
 	.unbind = etnaviv_unbind,
 };
 
-static int compare_of(struct device *dev, void *data)
-{
-	struct device_node *np = data;
-
-	return dev->of_node == np;
-}
-
 static int compare_str(struct device *dev, void *data)
 {
 	return !strcmp(dev_name(dev), data);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 9743b6b17447..97f6bc69bee3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -212,11 +212,6 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
 	}
 };
 
-static int compare_dev(struct device *dev, void *data)
-{
-	return dev == (struct device *)data;
-}
-
 static struct component_match *exynos_drm_match_add(struct device *dev)
 {
 	struct component_match *match = NULL;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index 98ae9a48f3fe..8cc6e13e46af 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -203,11 +203,6 @@ static int kirin_drm_kms_init(struct drm_device *dev,
 	return ret;
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static int kirin_drm_kms_cleanup(struct drm_device *dev)
 {
 	drm_kms_helper_poll_fini(dev);
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index cb685fe2039b..11b5c0fae045 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -176,7 +176,7 @@ static const struct drm_driver imx_drm_driver = {
 	.patchlevel		= 0,
 };
 
-static int compare_of(struct device *dev, void *data)
+static int imx_compare_of(struct device *dev, void *data)
 {
 	struct device_node *np = data;
 
@@ -286,7 +286,7 @@ static const struct component_master_ops imx_drm_ops = {
 
 static int imx_drm_platform_probe(struct platform_device *pdev)
 {
-	int ret = drm_of_component_probe(&pdev->dev, compare_of, &imx_drm_ops);
+	int ret = drm_of_component_probe(&pdev->dev, imx_compare_of, &imx_drm_ops);
 
 	if (!ret)
 		ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index b4943a56be09..194abab14ffe 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -1322,11 +1322,6 @@ static int ingenic_drm_bind_with_components(struct device *dev)
 	return ingenic_drm_bind(dev, true);
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static void ingenic_drm_unbind(struct device *dev)
 {
 	struct ingenic_drm *priv = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
index 5b5afc6aaf8e..015690b6d308 100644
--- a/drivers/gpu/drm/mcde/mcde_drv.c
+++ b/drivers/gpu/drm/mcde/mcde_drv.c
@@ -265,11 +265,6 @@ static struct platform_driver *const mcde_component_drivers[] = {
 	&mcde_dsi_driver,
 };
 
-static int mcde_compare_dev(struct device *dev, void *data)
-{
-	return dev == data;
-}
-
 static int mcde_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -399,7 +394,7 @@ static int mcde_probe(struct platform_device *pdev)
 
 		while ((d = platform_find_device_by_driver(p, drv))) {
 			put_device(p);
-			component_match_add(dev, &match, mcde_compare_dev, d);
+			component_match_add(dev, &match, compare_dev, d);
 			p = d;
 		}
 		put_device(p);
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 56ff8c57ef8f..72586983ec1d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -369,11 +369,6 @@ static const struct drm_driver mtk_drm_driver = {
 	.minor = DRIVER_MINOR,
 };
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static int mtk_drm_bind(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 80f1d439841a..b68631d16eb3 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -423,14 +423,6 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev)
 	return drm_mode_config_helper_resume(priv->drm);
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-	DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
-			 dev->of_node, data);
-
-	return dev->of_node == data;
-}
-
 static void meson_drv_shutdown(struct platform_device *pdev)
 {
 	struct meson_drm *priv = dev_get_drvdata(&pdev->dev);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ad35a5d94053..6250327b1eda 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1173,15 +1173,6 @@ static const struct dev_pm_ops msm_pm_ops = {
  * Componentized driver support:
  */
 
-/*
- * NOTE: duplication of the same code as exynos or imx (or probably any other).
- * so probably some room for some helpers
- */
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 /*
  * Identify what components need to be added by parsing what remote-endpoints
  * our MDP output ports are connected to. In the case of LVDS on MDP4, there
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
index 69b3e15b9356..5216000c7657 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1344,12 +1344,6 @@ static const struct component_master_ops dss_component_ops = {
 	.unbind = dss_unbind,
 };
 
-static int dss_component_compare(struct device *dev, void *data)
-{
-	struct device *child = data;
-	return dev == child;
-}
-
 struct dss_component_match_data {
 	struct device *dev;
 	struct component_match **match;
@@ -1379,7 +1373,7 @@ static int dss_add_child_component(struct device *dev, void *data)
 		return device_for_each_child(dev, cmatch,
 					     dss_add_child_component);
 
-	component_match_add(cmatch->dev, match, dss_component_compare, dev);
+	component_match_add(cmatch->dev, match, compare_dev, dev);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index bec207de4544..276e41168bd0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -290,11 +290,6 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
 	return false;
 }
 
-static int compare_dev(struct device *dev, void *data)
-{
-	return dev == (struct device *)data;
-}
-
 static void rockchip_drm_match_remove(struct device *dev)
 {
 	struct device_link *link;
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index c7efb43b83ee..3c3294c2100d 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -144,11 +144,6 @@ static const struct drm_driver sti_driver = {
 	.minor = DRIVER_MINOR,
 };
 
-static int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
 static int sti_init(struct drm_device *ddev)
 {
 	struct sti_private *private;
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index b630614b3d72..de26c1448486 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -201,15 +201,6 @@ static bool sun4i_drv_node_is_tcon_top(struct device_node *node)
 		!!of_match_node(sun8i_tcon_top_of_table, node);
 }
 
-static int compare_of(struct device *dev, void *data)
-{
-	DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
-			 dev->of_node,
-			 data);
-
-	return dev->of_node == data;
-}
-
 /*
  * The encoder drivers use drm_of_find_possible_crtcs to get upstream
  * crtcs from the device tree using of_graph. For the results to be
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 16abc3a3d601..43474107a4f2 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -187,11 +187,6 @@ static struct drm_driver vc4_drm_driver = {
 	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
-static int compare_dev(struct device *dev, void *data)
-{
-	return dev == data;
-}
-
 static void vc4_match_add_drivers(struct device *dev,
 				  struct component_match **match,
 				  struct platform_driver *const *drivers,
diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
index f81fa8862ed0..b742432220c5 100644
--- a/drivers/iommu/mtk_iommu.h
+++ b/drivers/iommu/mtk_iommu.h
@@ -84,16 +84,6 @@ struct mtk_iommu_data {
 	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
 };
 
-static inline int compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
-static inline void release_of(struct device *dev, void *data)
-{
-	of_node_put(data);
-}
-
 static inline int mtk_iommu_bind(struct device *dev)
 {
 	struct mtk_iommu_data *data = dev_get_drvdata(dev);
diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
index ce074c018dcb..248dfd8aec19 100644
--- a/drivers/power/supply/ab8500_charger.c
+++ b/drivers/power/supply/ab8500_charger.c
@@ -3414,11 +3414,6 @@ static struct platform_driver *const ab8500_charger_component_drivers[] = {
 	&ab8500_chargalg_driver,
 };
 
-static int ab8500_charger_compare_dev(struct device *dev, void *data)
-{
-	return dev == data;
-}
-
 static int ab8500_charger_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -3657,8 +3652,7 @@ static int ab8500_charger_probe(struct platform_device *pdev)
 
 		while ((d = platform_find_device_by_driver(p, drv))) {
 			put_device(p);
-			component_match_add(dev, &match,
-					    ab8500_charger_compare_dev, d);
+			component_match_add(dev, &match, compare_dev, d);
 			p = d;
 		}
 		put_device(p);
diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
index a6b1c1598040..328aa5d86f1a 100644
--- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c
+++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
@@ -1193,12 +1193,6 @@ static const struct component_master_ops dss_component_ops = {
 	.unbind = dss_unbind,
 };
 
-static int dss_component_compare(struct device *dev, void *data)
-{
-	struct device *child = data;
-	return dev == child;
-}
-
 static int dss_add_child_component(struct device *dev, void *data)
 {
 	struct component_match **match = data;
@@ -1212,7 +1206,7 @@ static int dss_add_child_component(struct device *dev, void *data)
 	if (strstr(dev_name(dev), "rfbi"))
 		return 0;
 
-	component_match_add(dev->parent, match, dss_component_compare, dev);
+	component_match_add(dev->parent, match, compare_dev, dev);
 
 	return 0;
 }
diff --git a/include/linux/component.h b/include/linux/component.h
index 16de18f473d7..5a7468ea827c 100644
--- a/include/linux/component.h
+++ b/include/linux/component.h
@@ -2,6 +2,8 @@
 #ifndef COMPONENT_H
 #define COMPONENT_H
 
+#include <linux/device.h>
+#include <linux/of.h>
 #include <linux/stddef.h>
 
 
@@ -82,6 +84,22 @@ struct component_master_ops {
 	void (*unbind)(struct device *master);
 };
 
+/* A set common helpers for compare/release functions */
+static inline int compare_of(struct device *dev, void *data)
+{
+	return dev->of_node == data;
+}
+
+static inline void release_of(struct device *dev, void *data)
+{
+	of_node_put(data);
+}
+
+static inline int compare_dev(struct device *dev, void *data)
+{
+	return dev == data;
+}
+
 void component_master_del(struct device *,
 	const struct component_master_ops *);
 
diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
index eff200a07d9f..992132cbfb9f 100644
--- a/sound/soc/codecs/wcd938x.c
+++ b/sound/soc/codecs/wcd938x.c
@@ -4417,16 +4417,6 @@ static const struct component_master_ops wcd938x_comp_ops = {
 	.unbind = wcd938x_unbind,
 };
 
-static int wcd938x_compare_of(struct device *dev, void *data)
-{
-	return dev->of_node == data;
-}
-
-static void wcd938x_release_of(struct device *dev, void *data)
-{
-	of_node_put(data);
-}
-
 static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
 					struct device *dev,
 					struct component_match **matchptr)
@@ -4442,8 +4432,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
 	}
 
 	of_node_get(wcd938x->rxnode);
-	component_match_add_release(dev, matchptr, wcd938x_release_of,
-				    wcd938x_compare_of,	wcd938x->rxnode);
+	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->rxnode);
 
 	wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
 	if (!wcd938x->txnode) {
@@ -4451,8 +4440,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
 		return -ENODEV;
 	}
 	of_node_get(wcd938x->txnode);
-	component_match_add_release(dev, matchptr, wcd938x_release_of,
-				    wcd938x_compare_of,	wcd938x->txnode);
+	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->txnode);
 	return 0;
 }
 
-- 
2.18.0



From francesco.dolcini at toradex.com  Fri Jan 28 00:29:20 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Fri, 28 Jan 2022 09:29:20 +0100
Subject: [RFC PATCH] PCI: imx6: Handle the abort from user-space
Message-ID: <20220128082920.591115-1-francesco.dolcini@toradex.com>

From: Jason Liu <jason.hui.liu at nxp.com>

The driver install one hook to handle the external abort, but issue
is that if the abort introduced from user space code, the following
code unsigned long instr = *(unsigned long *)pc; which will created
another data-abort(page domain fault) if CONFIG_CPU_SW_DOMAIN_PAN.

The patch does not intent to use copy_from_user and then do the hack
due to the security consideration. In fact, we can just return and
report the external abort to user-space.

Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
Reviewed-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
---
We have this patch from NXP downstream kernel [1] in our kernel branch [2]
since a long time, to me it would make sense to upstream it. Any concern?

[1] https://source.codeaurora.org/external/imxsupport/linux-imx/commit/?id=62dfb2fb953463dd1b6710567c9e174672a98f24
[2] https://git.toradex.com/cgit/linux-toradex.git/commit/?id=2b42547cf659f979be2defdff6a99f921b33d0f1
---
 drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6974bd5aa116..6b178a29e253 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -27,6 +27,7 @@
 #include <linux/resource.h>
 #include <linux/signal.h>
 #include <linux/types.h>
+#include <linux/uaccess.h>
 #include <linux/interrupt.h>
 #include <linux/reset.h>
 #include <linux/phy/phy.h>
@@ -297,8 +298,15 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
 		unsigned int fsr, struct pt_regs *regs)
 {
 	unsigned long pc = instruction_pointer(regs);
-	unsigned long instr = *(unsigned long *)pc;
-	int reg = (instr >> 12) & 15;
+	unsigned long instr;
+	int reg;
+
+	/* if the abort from user-space, just return and report it */
+	if (user_mode(regs))
+		return 1;
+
+	instr = *(unsigned long *)pc;
+	reg = (instr >> 12) & 15;
 
 	/*
 	 * If the instruction being executed was a read,
-- 
2.25.1



From houtao1 at huawei.com  Wed Jan 26 23:15:32 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:15:32 +0800
Subject: [PATCH bpf-next v2 2/2] selftests/bpf: check whether s32 is
 sufficient for kfunc offset
In-Reply-To: <20220127071532.384888-1-houtao1@huawei.com>
References: <20220127071532.384888-1-houtao1@huawei.com>
Message-ID: <20220127071532.384888-3-houtao1@huawei.com>

In add_kfunc_call(), bpf_kfunc_desc->imm with type s32 is used to
represent the offset of called kfunc from __bpf_call_base, so
add a test to ensure that the offset will not be overflowed.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 .../selftests/bpf/prog_tests/ksyms_module.c   | 72 +++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
index d490ad80eccb..ce0cd3446931 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
@@ -6,6 +6,76 @@
 #include "test_ksyms_module.lskel.h"
 #include "test_ksyms_module.skel.h"
 
+/* Most logic comes from bpf_object__read_kallsyms_file() */
+static int test_find_func_in_kallsyms(const char *func, unsigned long *addr)
+{
+	/* Same as KSYM_NAME_LEN */
+	char sym_name[128];
+	char sym_type;
+	unsigned long sym_addr;
+	int ret, err;
+	FILE *f;
+
+	f = fopen("/proc/kallsyms", "r");
+	if (!f)
+		return -errno;
+
+	err = -ENOENT;
+	while (true) {
+		ret = fscanf(f, "%lx %c %127s%*[^\n]\n",
+			     &sym_addr, &sym_type, sym_name);
+		if (ret == EOF && feof(f))
+			break;
+
+		if (ret != 3) {
+			err = -EINVAL;
+			break;
+		}
+
+		if ((sym_type == 't' || sym_type == 'T') &&
+		    !strcmp(sym_name, func)) {
+			*addr = sym_addr;
+			err = 0;
+			break;
+		}
+	}
+
+	fclose(f);
+	return err;
+}
+
+/*
+ * Check whether or not s32 in bpf_kfunc_desc is sufficient
+ * to represent the offset between bpf_testmod_test_mod_kfunc
+ * and __bpf_call_base.
+ */
+void test_ksyms_module_valid_offset(void)
+{
+	unsigned long kfunc_addr;
+	unsigned long base_addr;
+	int used_offset;
+	long actual_offset;
+	int err;
+
+	if (!env.has_testmod) {
+		test__skip();
+		return;
+	}
+
+	err = test_find_func_in_kallsyms("bpf_testmod_test_mod_kfunc",
+					 &kfunc_addr);
+	if (!ASSERT_OK(err, "find kfunc addr"))
+		return;
+
+	err = test_find_func_in_kallsyms("__bpf_call_base", &base_addr);
+	if (!ASSERT_OK(err, "find base addr"))
+		return;
+
+	used_offset = kfunc_addr - base_addr;
+	actual_offset = kfunc_addr - base_addr;
+	ASSERT_EQ((long)used_offset, actual_offset, "kfunc offset overflowed");
+}
+
 void test_ksyms_module_lskel(void)
 {
 	struct test_ksyms_module_lskel *skel;
@@ -55,6 +125,8 @@ void test_ksyms_module_libbpf(void)
 
 void test_ksyms_module(void)
 {
+	if (test__start_subtest("valid_offset"))
+		test_ksyms_module_valid_offset();
 	if (test__start_subtest("lskel"))
 		test_ksyms_module_lskel();
 	if (test__start_subtest("libbpf"))
-- 
2.27.0



From houtao1 at huawei.com  Wed Jan 26 23:15:30 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:15:30 +0800
Subject: [PATCH bpf-next v2 0/2] bpf, arm64: enable kfunc call
Message-ID: <20220127071532.384888-1-houtao1@huawei.com>

Hi,

The simple patchset tries to enable kfunc call for arm64. Patch #1 just
overrides bpf_jit_supports_kfunc_call() to enable kfunc call and patch #2
add a test to ensure s32 is sufficient for kfunc offset.

Change Log:
v2: 
  * add a test to check whether imm will be overflowed for kfunc call

v1: https://lore.kernel.org/bpf/20220119144942.305568-1-houtao1 at huawei.com

Hou Tao (2):
  bpf, arm64: enable kfunc call
  selftests/bpf: check whether s32 is sufficient for kfunc offset

 arch/arm64/net/bpf_jit_comp.c                 |  5 ++
 .../selftests/bpf/prog_tests/ksyms_module.c   | 72 +++++++++++++++++++
 2 files changed, 77 insertions(+)

-- 
2.27.0



From houtao1 at huawei.com  Wed Jan 26 23:15:31 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:15:31 +0800
Subject: [PATCH bpf-next v2 1/2] bpf, arm64: enable kfunc call
In-Reply-To: <20220127071532.384888-1-houtao1@huawei.com>
References: <20220127071532.384888-1-houtao1@huawei.com>
Message-ID: <20220127071532.384888-2-houtao1@huawei.com>

Since commit b2eed9b58811 ("arm64/kernel: kaslr: reduce module
randomization range to 2 GB"), for arm64 whether KASLR is enabled
or not, the module is placed within 2GB of the kernel region, so
s32 in bpf_kfunc_desc is sufficient to represente the offset of
module function relative to __bpf_call_base. The only thing needed
is to override bpf_jit_supports_kfunc_call().

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 6d92f363028c..e60c464004c2 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1284,6 +1284,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	return prog;
 }
 
+bool bpf_jit_supports_kfunc_call(void)
+{
+	return true;
+}
+
 u64 bpf_jit_alloc_exec_limit(void)
 {
 	return VMALLOC_END - VMALLOC_START;
-- 
2.27.0



From lee.jones at linaro.org  Fri Jan 28 00:44:47 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Fri, 28 Jan 2022 08:44:47 +0000
Subject: [PATCH 1/3] mfd: simple-mfd-i2c: add compatible string for
 LS1028A-QDS FPGA
In-Reply-To: <20220127172105.4085950-2-vladimir.oltean@nxp.com>
References: <20220127172105.4085950-1-vladimir.oltean@nxp.com>
 <20220127172105.4085950-2-vladimir.oltean@nxp.com>
Message-ID: <YfOs/wkylwMgsepj@google.com>

On Thu, 27 Jan 2022, Vladimir Oltean wrote:

> As Michael mentions in the description of commit 3abee4579484 ("mfd: Add
> simple regmap based I2C driver"), "If a device wants to use this as its
> MFD core driver, it has to add an individual compatible string."
> 
> The QIXIS FPGA on the LS1028A-QDS boards has a similar purpose to the
> Kontron SL28 CPLD: it deals with board power-on reset timing, muxing,
> etc.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean at nxp.com>
> ---
>  drivers/mfd/simple-mfd-i2c.c | 1 +
>  1 file changed, 1 insertion(+)

For my own reference (apply this as-is to your sign-off block):

  Acked-for-MFD-by: Lee Jones <lee.jones at linaro.org>

-- 
Lee Jones [???]
Principal Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From iivanov at suse.de  Fri Jan 28 00:47:17 2022
From: iivanov at suse.de (Ivan T . Ivanov)
Date: Fri, 28 Jan 2022 10:47:17 +0200
Subject: [PATCH] i2c: bcm2835: Set clock-stretch timeout to 35ms
In-Reply-To: <20220117102504.90585-1-iivanov@suse.de>
References: <20220117102504.90585-1-iivanov@suse.de>
Message-ID: <20220128084717.rbvbciprfqen4rvb@suse>

On 01-17 11:25, Ivan T. Ivanov wrote:
> Date: Mon, 17 Jan 2022 11:25:04 +0100
> From: "Ivan T. Ivanov" <iivanov at suse.de>
> To: Florian Fainelli <f.fainelli at gmail.com>, Ray Jui <rjui at broadcom.com>,
>  Scott Branden <sbranden at broadcom.com>, Nicolas Saenz Julienne
>  <nsaenz at kernel.org>
> Cc: linux-i2c at vger.kernel.org, linux-arm-kernel at lists.infradead.org, Phil
>  Elwell <phil at raspberrypi.org>, "Ivan T . Ivanov" <iivanov at suse.de>
> Subject: [PATCH] i2c: bcm2835: Set clock-stretch timeout to 35ms
> Message-Id: <20220117102504.90585-1-iivanov at suse.de>
Tags: all arm i2c linux me ring rpi sent

Hi,

> 
> From: Phil Elwell <phil at raspberrypi.org>
> 
> The BCM2835 I2C blocks have a register to set the clock-stretch
> timeout - how long the device is allowed to hold SCL low - in bus
> cycles. The current driver doesn't write to the register, therefore
> the default value of 64 cycles is being used for all devices.
> 
> Set the timeout to the value recommended for SMBus - 35ms.
> 
> See: https://github.com/raspberrypi/linux/issues/3064

It will be nice if we have this fix upstream.

Regards,
Ivan

> 
> Signed-off-by: Phil Elwell <phil at raspberrypi.org>
> [iivanov at suse.de fix small coding style issue]
> Signed-off-by: Ivan T. Ivanov <iivanov at suse.de>
> ---
>  drivers/i2c/busses/i2c-bcm2835.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c
> index 37443edbf754..9cce0e15da32 100644
> --- a/drivers/i2c/busses/i2c-bcm2835.c
> +++ b/drivers/i2c/busses/i2c-bcm2835.c
> @@ -106,6 +106,7 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
>  {
>  	struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw);
>  	u32 redl, fedl;
> +	u32 clk_tout;
>  	u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate);
>  
>  	if (divider == -EINVAL)
> @@ -129,6 +130,17 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
>  	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL,
>  			   (fedl << BCM2835_I2C_FEDL_SHIFT) |
>  			   (redl << BCM2835_I2C_REDL_SHIFT));
> +
> +	/*
> +	 * Set the clock stretch timeout to the SMBUs-recommended 35ms.
> +	 */
> +	if (rate > 0xffff * 1000 / 35)
> +		clk_tout = 0xffff;
> +	else
> +		clk_tout = 35 * rate / 1000;
> +
> +	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout);
> +
>  	return 0;
>  }
>  
> -- 
> 2.26.2
> 


From 21cnbao at gmail.com  Fri Jan 28 00:54:09 2022
From: 21cnbao at gmail.com (Barry Song)
Date: Fri, 28 Jan 2022 21:54:09 +1300
Subject: [PATCH v6 0/9] Multigenerational LRU Framework
In-Reply-To: <Ye+dPmO17JN2bNLL@google.com>
References: <20220104202227.2903605-1-yuzhao@google.com>
 <CAGsJ_4zULJ5vPwn73Z5Bap3eRkAX+Yv24c-n41+zC7fN8xG60g@mail.gmail.com>
 <Ye+dPmO17JN2bNLL@google.com>
Message-ID: <CAGsJ_4w5GM5r916XEz+gj=33A+b98kyJONLNpEnBMmX5XnPRmg@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:48 PM Yu Zhao <yuzhao at google.com> wrote:
>
> On Sun, Jan 23, 2022 at 06:43:06PM +1300, Barry Song wrote:
> > On Wed, Jan 5, 2022 at 7:17 PM Yu Zhao <yuzhao at google.com> wrote:
>
> <snipped>
>
> > > Large-scale deployments
> > > -----------------------
> > > We've rolled out MGLRU to tens of millions of Chrome OS users and
> > > about a million Android users. Google's fleetwide profiling [13] shows
> > > an overall 40% decrease in kswapd CPU usage, in addition to
> >
> > Hi Yu,
> >
> > Was the overall 40% decrease of kswap CPU usgae seen on x86 or arm64?
> > And I am curious how much we are taking advantage of NONLEAF_PMD_YOUNG.
> > Does it help a lot in decreasing the cpu usage?
>
> Hi Barry,
>
> The fleet-wide profiling data I shared was from x86. For arm64, I only
> have data from synthetic benchmarks at the moment, and it also shows
> similar improvements.
>
> For Chrome OS (individual users), walk_pte_range(), the function that
> would benefit from ARCH_HAS_NONLEAF_PMD_YOUNG, only uses a small
> portion (<4%) of kswapd CPU time. So ARCH_HAS_NONLEAF_PMD_YOUNG isn't
> that helpful.

Hi Yu,
Thanks!

In the current kernel, depending on reverse mapping, while memory is
under pressure,
the cpu usage of kswapd can be very very high especially while a lot of pages
have large mapcount, thus a huge reverse mapping cost.

Regarding  <4%, I guess the figure came from machines with NONLEAF_PMD_YOUNG?
In this case, we can skip many PTE scans while PMD has no accessed bit
set. But for
a machine without NONLEAF, will the figure of cpu usage be much larger?

>
> > If so, this might be
> > a good proof that arm64 also needs this hardware feature?
> > In short, I am curious how much the improvement in this patchset depends
> > on the hardware ability of NONLEAF_PMD_YOUNG.
>
> For data centers, I do think ARCH_HAS_NONLEAF_PMD_YOUNG has some value.
> In addition to cold/hot memory scanning, there are other use cases like
> dirty tracking, which can benefit from the accessed bit on non-leaf
> entries. I know some proprietary software uses this capability on x86
> for different purposes than this patchset does. And AFAIK, x86 is the
> only arch that supports this capability, e.g., risc-v and ppc can only
> set the accessed bit in PTEs.

Yep. NONLEAF is a nice feature.

btw, page table should have a separate DIRTY bit, right? wouldn't dirty page
tracking depend on the DIRTY bit rather than the accessed bit? so x86 also has
NONLEAF dirty bit? Or they are scanning accessed bit of PMD before
scanning DIRTY bits of PTEs?

>
> In fact, I've discussed this with one of the arm maintainers Will. So
> please check with him too if you are interested in moving forward with
> the idea. I might be able to provide with additional data if you need
> it to make a decision.

I am interested in running it and have some data without NONLEAF
especially while free memory is very limited and the system has memory
thrashing.

>
> Thanks.

Thanks
Barry


From shawnguo at kernel.org  Fri Jan 28 00:56:34 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 16:56:34 +0800
Subject: [PATCH] firmware: imx: add get resource owner api
In-Reply-To: <20220111032147.342012-1-peng.fan@oss.nxp.com>
References: <20220111032147.342012-1-peng.fan@oss.nxp.com>
Message-ID: <20220128085633.GG4686@dragon>

On Tue, Jan 11, 2022 at 11:21:47AM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add resource owner management API, this API could be used to check
> whether M4 is under control of Linux.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
> ---
>  drivers/firmware/imx/rm.c           | 45 +++++++++++++++++++++++++++++
>  include/linux/firmware/imx/svc/rm.h |  5 ++++
>  2 files changed, 50 insertions(+)
> 
> diff --git a/drivers/firmware/imx/rm.c b/drivers/firmware/imx/rm.c
> index a12db6ff323b..3c3605f98123 100644
> --- a/drivers/firmware/imx/rm.c
> +++ b/drivers/firmware/imx/rm.c
> @@ -43,3 +43,48 @@ bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
>  	return hdr->func;
>  }
>  EXPORT_SYMBOL(imx_sc_rm_is_resource_owned);
> +
> +/*
> + * This function get @resource partition number
> + *
> + * @param[in]     ipc         IPC handle
> + * @param[in]     resource    resource the control is associated with
> + * @param[out]    pt          pointer to return the partition number
> + *
> + * @return Returns 0 for success and < 0 for errors.
> + */

Shouldn't the documentation be put right above the function?

Shawn

> +struct imx_sc_msg_rm_get_resource_owner {
> +	struct imx_sc_rpc_msg hdr;
> +	union {
> +		struct {
> +			u16 resource;
> +		} req;
> +		struct {
> +			u8 val;
> +		} resp;
> +	} data;
> +} __packed __aligned(4);
> +
> +int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
> +{
> +	struct imx_sc_msg_rm_get_resource_owner msg;
> +	struct imx_sc_rpc_msg *hdr = &msg.hdr;
> +	int ret;
> +
> +	hdr->ver = IMX_SC_RPC_VERSION;
> +	hdr->svc = IMX_SC_RPC_SVC_RM;
> +	hdr->func = IMX_SC_RM_FUNC_GET_RESOURCE_OWNER;
> +	hdr->size = 2;
> +
> +	msg.data.req.resource = resource;
> +
> +	ret = imx_scu_call_rpc(ipc, &msg, true);
> +	if (ret)
> +		return ret;
> +
> +	if (pt)
> +		*pt = msg.data.resp.val;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(imx_sc_rm_get_resource_owner);
> diff --git a/include/linux/firmware/imx/svc/rm.h b/include/linux/firmware/imx/svc/rm.h
> index 456b6a59d29b..ff481b23ea36 100644
> --- a/include/linux/firmware/imx/svc/rm.h
> +++ b/include/linux/firmware/imx/svc/rm.h
> @@ -59,11 +59,16 @@ enum imx_sc_rm_func {
>  
>  #if IS_ENABLED(CONFIG_IMX_SCU)
>  bool imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource);
> +int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt);
>  #else
>  static inline bool
>  imx_sc_rm_is_resource_owned(struct imx_sc_ipc *ipc, u16 resource)
>  {
>  	return true;
>  }
> +static inline int imx_sc_rm_get_resource_owner(struct imx_sc_ipc *ipc, u16 resource, u8 *pt)
> +{
> +	return -ENOTSUPP;
> +}
>  #endif
>  #endif
> -- 
> 2.25.1
> 


From maz at kernel.org  Fri Jan 28 00:57:16 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 08:57:16 +0000
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220127212100.GA102267@bhelgaas>
References: <d78b45e461b204d375830217d0d27ffdd97cedd3.camel@mediatek.com>
 <20220127212100.GA102267@bhelgaas>
Message-ID: <87r18s5jbn.wl-maz@kernel.org>

On Thu, 27 Jan 2022 21:21:00 +0000,
Bjorn Helgaas <helgaas at kernel.org> wrote:
> 
> [+cc Srikanth, Pratyush, Thomas, Pali, Ryder, Jianjun]
> 
> On Wed, Jan 26, 2022 at 11:37:58AM +0800, qizhong.cheng wrote:
> > On Tue, 2022-01-25 at 17:21 +0000, Marc Zyngier wrote:
> > > On 2022-01-25 16:57, Bjorn Helgaas wrote:
> > > > On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> > > > > As an edge-triggered interrupts, its interrupt status should
> > > > > be cleared before dispatch to the handler of device.
> > > > 
> > > > I'm not an IRQ expert, but the reasoning that "we should clear
> > > > the MSI interrupt status before dispatching the handler because
> > > > MSI is an edge-triggered interrupt" doesn't seem completely
> > > > convincing because your code will now look like this:
> > > > 
> > > >   /* Clear the INTx */
> > > >   writel(1 << bit, port->base + PCIE_INT_STATUS);
> > > >   generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
> > > >   ...
> > > > 
> > > >   /* Clear MSI interrupt status */
> > > >   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
> > > >   generic_handle_domain_irq(port->inner_domain, bit);
> > > > 
> > > > You clear interrupt status before dispatching the handler for
> > > > *both* level-triggered INTx interrupts and edge-triggered MSI
> > > > interrupts.
> > > > 
> > > > So it doesn't seem that simply being edge-triggered is the
> > > > critical factor here.
> > > 
> > > This is the usual problem with these half-baked implementations.
> > > The signalling to the primary interrupt controller is level, as
> > > they take a multitude of input and (crucially) latch the MSI
> > > edges. Effectively, this is an edge-to-level converter, with all
> > > the problems that this creates.
> > > 
> > > By clearing the status *after* the handling, you lose edges that
> > > have been received and coalesced after the read of the status
> > > register. By clearing it *before*, you are acknowledging the
> > > interrupts early, and allowing them to be coalesced independently
> > > of the ones that have been received earlier.
> > > 
> > > This is however mostly an educated guess. Someone with access to
> > > the TRM should verify this.
> > 
> > Yes, as Maz said, we save the edge-interrupt status so that it
> > becomes a level-interrupt. This is similar to an edge-to-level
> > converter, so we need to clear it *before*. We found this problem
> > through a lot of experiments and tested this patch.
> 
> I thought there might be other host controllers with similar design,
> so I looked at all the other drivers and tried to figure out whether
> any others had similar problems.
> 
> The ones below look suspicious to me because they all clear some sort
> of status register *after* handling an MSI.  Can you guys take a look
> and make sure they are working correctly?
> 
>   keembay_pcie_msi_irq_handler
>     status = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
>     if (status & MSI_CTRL_INT)
>       dw_handle_msi_irq
> 	generic_handle_domain_irq
>       writel(status, pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
> 
>   spear13xx_pcie_irq_handler
>     status = readl(&app_reg->int_sts)
>     if (status & MSI_CTRL_INT)
>       dw_handle_msi_irq
> 	generic_handle_domain_irq
>     writel(status, &app_reg->int_clr)

I think these two are fine.

The top level interrupt is only a level signal that the is something
to process. The only thing that is unclear is what the effect of
writing to that status register if MSIs are pending at that point. A
sane implementation would just ignore the write.

The actual processing is done in dw_handle_msi_irq(), reading the
PCIE_MSI_INTR0_STATUS register. This same register is then used to Ack
the interrupt, one bit at a time, as interrupts are handled (see
dw_pci_bottom_ack). Ack taking place before the handling, it makes it
safe for edge delivery.

> 
>   advk_pcie_handle_int
>     isr0_status = advk_readl(pcie, PCIE_ISR0_REG)
>     if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
>       advk_pcie_handle_msi
>         advk_readl(pcie, PCIE_MSI_STATUS_REG)
> 	advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG)
> 	generic_handle_irq
> 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG)

Same thing, I guess. It is just that the Ack has been open-coded.

>
>   mtk_pcie_irq_handler
>     status = readl_relaxed(pcie->base + PCIE_INT_STATUS_REG)
>     for_each_set_bit_from(irq_bit, &status, ...)
>       mtk_pcie_msi_handler
>         generic_handle_domain_irq
>       writel_relaxed(BIT(irq_bit), pcie->base + PCIE_INT_STATUS_REG)

Similar thing. The PCIE_MSI_SET_STATUS register is read first, and
then written back in the ack callback.

	M.

-- 
Without deviation from the norm, progress is not possible.


From shawnguo at kernel.org  Fri Jan 28 00:59:32 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 16:59:32 +0800
Subject: [PATCH] arm64: dts: imx8: add mu5/6 node
In-Reply-To: <20220111062013.1027517-1-peng.fan@oss.nxp.com>
References: <20220111062013.1027517-1-peng.fan@oss.nxp.com>
Message-ID: <20220128085932.GH4686@dragon>

On Tue, Jan 11, 2022 at 02:20:13PM +0800, Peng Fan (OSS) wrote:
> From: Peng Fan <peng.fan at nxp.com>
> 
> Add mu5/6 for i.MX8QXP/QM, these two mu will be used for
> communicating with general purpose Cortex-M4 cores.
> 
> Signed-off-by: Peng Fan <peng.fan at nxp.com>

Applied, thanks!


From l.stach at pengutronix.de  Fri Jan 28 01:07:58 2022
From: l.stach at pengutronix.de (Lucas Stach)
Date: Fri, 28 Jan 2022 10:07:58 +0100
Subject: [RFC PATCH] PCI: imx6: Handle the abort from user-space
In-Reply-To: <20220128082920.591115-1-francesco.dolcini@toradex.com>
References: <20220128082920.591115-1-francesco.dolcini@toradex.com>
Message-ID: <dd30b476f0378a4ae4639ffff635e55093bd070c.camel@pengutronix.de>

Am Freitag, dem 28.01.2022 um 09:29 +0100 schrieb Francesco Dolcini:
> From: Jason Liu <jason.hui.liu at nxp.com>
> 
> The driver install one hook to handle the external abort, but issue
> is that if the abort introduced from user space code, the following
> code unsigned long instr = *(unsigned long *)pc; which will created
> another data-abort(page domain fault) if CONFIG_CPU_SW_DOMAIN_PAN.
> 
> The patch does not intent to use copy_from_user and then do the hack
> due to the security consideration. In fact, we can just return and
> report the external abort to user-space.
> 
I'm not sure how userspace would be able to trigger this abort. Maybe
invalid access to a device cfg space via sysfs?

However the patch seems to do the right thing in that case.

Acked-by: Lucas Stach <l.stach at pengutronix.de>
 
> Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
> Reviewed-by: Richard Zhu <hongxing.zhu at nxp.com>
> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
> ---
> We have this patch from NXP downstream kernel [1] in our kernel branch [2]
> since a long time, to me it would make sense to upstream it. Any concern?
> 
> [1] https://source.codeaurora.org/external/imxsupport/linux-imx/commit/?id=62dfb2fb953463dd1b6710567c9e174672a98f24
> [2] https://git.toradex.com/cgit/linux-toradex.git/commit/?id=2b42547cf659f979be2defdff6a99f921b33d0f1
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index 6974bd5aa116..6b178a29e253 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -27,6 +27,7 @@
>  #include <linux/resource.h>
>  #include <linux/signal.h>
>  #include <linux/types.h>
> +#include <linux/uaccess.h>
>  #include <linux/interrupt.h>
>  #include <linux/reset.h>
>  #include <linux/phy/phy.h>
> @@ -297,8 +298,15 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
>  		unsigned int fsr, struct pt_regs *regs)
>  {
>  	unsigned long pc = instruction_pointer(regs);
> -	unsigned long instr = *(unsigned long *)pc;
> -	int reg = (instr >> 12) & 15;
> +	unsigned long instr;
> +	int reg;
> +
> +	/* if the abort from user-space, just return and report it */
> +	if (user_mode(regs))
> +		return 1;
> +
> +	instr = *(unsigned long *)pc;
> +	reg = (instr >> 12) & 15;
>  
>  	/*
>  	 * If the instruction being executed was a read,




From angelogioacchino.delregno at collabora.com  Fri Jan 28 01:13:32 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 28 Jan 2022 10:13:32 +0100
Subject: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com>
References: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>
 <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>
 <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com>
Message-ID: <ddb05e08-f81a-11f9-8091-9af0c57e687d@collabora.com>

Il 27/01/22 16:46, AngeloGioacchino Del Regno ha scritto:
> Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
>> Hi, Angelo:
>>
>> AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
>> 2022?1?27? ?? ??10:36???
>>>
>>> DRM bridge drivers are now attaching their DSI device at probe time,
>>> which requires us to register our DSI host in order to let the bridge
>>> to probe: this recently started producing an endless -EPROBE_DEFER
>>> loop on some machines that are using external bridges, like the
>>> parade-ps8640, found on the ACER Chromebook R13.
>>>
>>> Now that the DSI hosts/devices probe sequence is documented, we can
>>> do adjustments to the mtk_dsi driver as to both fix now and make sure
>>> to avoid this situation in the future: for this, following what is
>>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
>>> mtk_dsi_ops.attach callback and delete it in the detach callback;
>>> keeping in mind that we are registering a drm_bridge for our DSI,
>>> which is only used/attached if the DSI Host is bound, it wouldn't
>>> make sense to keep adding our bridge at probe time (as it would
>>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
>>> that one to the dsi host attach function (and remove it in detach).
>>>
>>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
>>
>> The fixed tag should indicate the patch which cause the bug, but why a
>> patch just adding document would cause bug?
>> So no any patch cause bug? This patch just want to prevent a possible bug?
>>
> 
> I think you've missed my previous message on v2, so I will paste it here:
> 
> unfortunately I couldn't find a valid commit for a Fixes tag. This
> started being an issue at some point, when the DRM was changed to
> adhere to the documented probe sequence: the MediaTek DSI driver was
> not the only one that got broken/affected by these changes.
> 
> If you have any advice on which commit should be tagged, I'm open for
> any kind of suggestion.
> 
> 
> I tried to check on other drivers which got fixed for the same behavior,
> for example drm/msm, but none of them had a Fixes tag.
> When the DRM got changed to adhere to this sequence, some drm/bridge
> drivers were also changed; this has created some incompatibilities with
> some drm drivers, including drm/msm and drm/mediatek.
> 
> This commit is not fixing a latent bug that was introduced in drm/mediatek
> but rather one that was induced by the new, fixed, probe flow that got
> recently documented - and to which drivers should adhere; failing to adhere
> to that will produce an endless -EPROBE_DEFER loop, due to other drivers
> (as mentioned, for example drm/bridge drivers) having been changed to use
> that probe sequence.
> 
> 
> Regards,
> Angelo
> 

I've been thinking about another solution to this issue.

Would it be fine if I send a v4 that removes the Fixes tag, but adds the following?

Cc: stable at kernel.org # v5.15+

>> Regards,
>> Chun-Kuang.
>>
>>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
>>> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
>>> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
>>>
>>> ---
>>> ? drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
>>> ? 1 file changed, 84 insertions(+), 83 deletions(-)
>>>


-- 
AngeloGioacchino Del Regno
Software Engineer

Collabora Ltd.
Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
Registered in England & Wales, no. 5513718


From houtao1 at huawei.com  Fri Jan 28 01:18:35 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Fri, 28 Jan 2022 17:18:35 +0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <61f35869ba5a_738dc20823@john.notmuch>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
 <61f23655411bc_57f032084@john.notmuch>
 <8b67fa3d-f83c-85a5-5159-70b0f913833a@huawei.com>
 <61f35869ba5a_738dc20823@john.notmuch>
Message-ID: <cf4f75c9-dccb-913f-4527-d358cf653f93@huawei.com>

Hi,

On 1/28/2022 10:43 AM, John Fastabend wrote:
> Hou Tao wrote:
>> Hi,
>>
>> On 1/27/2022 2:06 PM, John Fastabend wrote:
>>> Hou Tao wrote:
>>>> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
>>>> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
>>>> it only add support for x86-64, so support these atomic operations
>>>> for arm64 as well.
snip
>>>> +
>>>> +	switch (insn->imm) {
>>> Diff'ing X86 implementation which has a BPF_SUB case how is it avoided
>>> here?
>> I think it is just left over from patchset [1], because according to the LLVM
>> commit [2]
>> __sync_fetch_and_sub(&addr, value) is implemented by __sync_fetch_and_add(&addr,
>> -value).
>> I will post a patch to remove it.
> OK in that case LGTM with the caveat not an ARM expert.
>
> Acked-by: John Fastabend <john.fastabend at gmail.com>
Thanks for your Acked-by.

Regards,
Tao


From houtao1 at huawei.com  Wed Jan 26 23:53:21 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:53:21 +0800
Subject: [PATCH bpf-next v2 1/2] selftests/bpf: use raw_tp program for atomic
 test
In-Reply-To: <20220127075322.675323-1-houtao1@huawei.com>
References: <20220127075322.675323-1-houtao1@huawei.com>
Message-ID: <20220127075322.675323-2-houtao1@huawei.com>

Now atomic tests will attach fentry program and run it through
bpf_prog_test_run(), but attaching fentry program depends on bpf
trampoline which is only available under x86-64. Considering many
archs have atomic support, using raw_tp program instead.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
Acked-by: Andrii Nakryiko <andrii at kernel.org>
---
 .../selftests/bpf/prog_tests/atomics.c        | 121 ++++++------------
 tools/testing/selftests/bpf/progs/atomics.c   |  28 ++--
 2 files changed, 50 insertions(+), 99 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/atomics.c b/tools/testing/selftests/bpf/prog_tests/atomics.c
index 86b7d5d84eec..8e05a703a62b 100644
--- a/tools/testing/selftests/bpf/prog_tests/atomics.c
+++ b/tools/testing/selftests/bpf/prog_tests/atomics.c
@@ -8,18 +8,14 @@ static void test_add(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__add__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(add)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.add.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run add",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run add") ||
+	    !ASSERT_OK(retval, "test_run add ret"))
+		return;
 
 	ASSERT_EQ(skel->data->add64_value, 3, "add64_value");
 	ASSERT_EQ(skel->bss->add64_result, 1, "add64_result");
@@ -31,28 +27,20 @@ static void test_add(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->add_stack_result, 1, "add_stack_result");
 
 	ASSERT_EQ(skel->data->add_noreturn_value, 3, "add_noreturn_value");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_sub(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__sub__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(sub)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.sub.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run sub",
-		  "err %d errno %d retval %d duration %d\n",
-		  err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run sub") ||
+	    !ASSERT_OK(retval, "test_run sub ret"))
+		return;
 
 	ASSERT_EQ(skel->data->sub64_value, -1, "sub64_value");
 	ASSERT_EQ(skel->bss->sub64_result, 1, "sub64_result");
@@ -64,27 +52,20 @@ static void test_sub(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->sub_stack_result, 1, "sub_stack_result");
 
 	ASSERT_EQ(skel->data->sub_noreturn_value, -1, "sub_noreturn_value");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_and(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__and__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(and)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.and.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run and",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run and") ||
+	    !ASSERT_OK(retval, "test_run and ret"))
+		return;
 
 	ASSERT_EQ(skel->data->and64_value, 0x010ull << 32, "and64_value");
 	ASSERT_EQ(skel->bss->and64_result, 0x110ull << 32, "and64_result");
@@ -93,27 +74,20 @@ static void test_and(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->and32_result, 0x110, "and32_result");
 
 	ASSERT_EQ(skel->data->and_noreturn_value, 0x010ull << 32, "and_noreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_or(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__or__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(or)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.or.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run or",
-		  "err %d errno %d retval %d duration %d\n",
-		  err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run or") ||
+	    !ASSERT_OK(retval, "test_run or ret"))
+		return;
 
 	ASSERT_EQ(skel->data->or64_value, 0x111ull << 32, "or64_value");
 	ASSERT_EQ(skel->bss->or64_result, 0x110ull << 32, "or64_result");
@@ -122,26 +96,20 @@ static void test_or(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->or32_result, 0x110, "or32_result");
 
 	ASSERT_EQ(skel->data->or_noreturn_value, 0x111ull << 32, "or_noreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_xor(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__xor__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(xor)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.xor.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run xor",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run xor") ||
+	    !ASSERT_OK(retval, "test_run xor ret"))
+		return;
 
 	ASSERT_EQ(skel->data->xor64_value, 0x101ull << 32, "xor64_value");
 	ASSERT_EQ(skel->bss->xor64_result, 0x110ull << 32, "xor64_result");
@@ -150,26 +118,20 @@ static void test_xor(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->bss->xor32_result, 0x110, "xor32_result");
 
 	ASSERT_EQ(skel->data->xor_noreturn_value, 0x101ull << 32, "xor_nxoreturn_value");
-cleanup:
-	close(link_fd);
 }
 
 static void test_cmpxchg(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__cmpxchg__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(cmpxchg)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.cmpxchg.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run cmpxchg",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run cmpxchg") ||
+	    !ASSERT_OK(retval, "test_run cmpxchg ret"))
+		return;
 
 	ASSERT_EQ(skel->data->cmpxchg64_value, 2, "cmpxchg64_value");
 	ASSERT_EQ(skel->bss->cmpxchg64_result_fail, 1, "cmpxchg_result_fail");
@@ -178,45 +140,34 @@ static void test_cmpxchg(struct atomics_lskel *skel)
 	ASSERT_EQ(skel->data->cmpxchg32_value, 2, "lcmpxchg32_value");
 	ASSERT_EQ(skel->bss->cmpxchg32_result_fail, 1, "cmpxchg_result_fail");
 	ASSERT_EQ(skel->bss->cmpxchg32_result_succeed, 1, "cmpxchg_result_succeed");
-
-cleanup:
-	close(link_fd);
 }
 
 static void test_xchg(struct atomics_lskel *skel)
 {
 	int err, prog_fd;
 	__u32 duration = 0, retval;
-	int link_fd;
-
-	link_fd = atomics_lskel__xchg__attach(skel);
-	if (!ASSERT_GT(link_fd, 0, "attach(xchg)"))
-		return;
 
+	/* No need to attach it, just run it directly */
 	prog_fd = skel->progs.xchg.prog_fd;
-	err = bpf_prog_test_run(prog_fd, 1, NULL, 0,
+	err = bpf_prog_test_run(prog_fd, 0, NULL, 0,
 				NULL, NULL, &retval, &duration);
-	if (CHECK(err || retval, "test_run xchg",
-		  "err %d errno %d retval %d duration %d\n", err, errno, retval, duration))
-		goto cleanup;
+	if (!ASSERT_OK(err, "test_run xchg") ||
+	    !ASSERT_OK(retval, "test_run xchg ret"))
+		return;
 
 	ASSERT_EQ(skel->data->xchg64_value, 2, "xchg64_value");
 	ASSERT_EQ(skel->bss->xchg64_result, 1, "xchg64_result");
 
 	ASSERT_EQ(skel->data->xchg32_value, 2, "xchg32_value");
 	ASSERT_EQ(skel->bss->xchg32_result, 1, "xchg32_result");
-
-cleanup:
-	close(link_fd);
 }
 
 void test_atomics(void)
 {
 	struct atomics_lskel *skel;
-	__u32 duration = 0;
 
 	skel = atomics_lskel__open_and_load();
-	if (CHECK(!skel, "skel_load", "atomics skeleton failed\n"))
+	if (!ASSERT_OK_PTR(skel, "atomics skeleton load"))
 		return;
 
 	if (skel->data->skip_tests) {
diff --git a/tools/testing/selftests/bpf/progs/atomics.c b/tools/testing/selftests/bpf/progs/atomics.c
index 16e57313204a..f89c7f0cc53b 100644
--- a/tools/testing/selftests/bpf/progs/atomics.c
+++ b/tools/testing/selftests/bpf/progs/atomics.c
@@ -20,8 +20,8 @@ __u64 add_stack_value_copy = 0;
 __u64 add_stack_result = 0;
 __u64 add_noreturn_value = 1;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(add, int a)
+SEC("raw_tp/sys_enter")
+int add(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -46,8 +46,8 @@ __s64 sub_stack_value_copy = 0;
 __s64 sub_stack_result = 0;
 __s64 sub_noreturn_value = 1;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(sub, int a)
+SEC("raw_tp/sys_enter")
+int sub(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -70,8 +70,8 @@ __u32 and32_value = 0x110;
 __u32 and32_result = 0;
 __u64 and_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(and, int a)
+SEC("raw_tp/sys_enter")
+int and(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -91,8 +91,8 @@ __u32 or32_value = 0x110;
 __u32 or32_result = 0;
 __u64 or_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(or, int a)
+SEC("raw_tp/sys_enter")
+int or(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -111,8 +111,8 @@ __u32 xor32_value = 0x110;
 __u32 xor32_result = 0;
 __u64 xor_noreturn_value = (0x110ull << 32);
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(xor, int a)
+SEC("raw_tp/sys_enter")
+int xor(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -132,8 +132,8 @@ __u32 cmpxchg32_value = 1;
 __u32 cmpxchg32_result_fail = 0;
 __u32 cmpxchg32_result_succeed = 0;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(cmpxchg, int a)
+SEC("raw_tp/sys_enter")
+int cmpxchg(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
@@ -153,8 +153,8 @@ __u64 xchg64_result = 0;
 __u32 xchg32_value = 1;
 __u32 xchg32_result = 0;
 
-SEC("fentry/bpf_fentry_test1")
-int BPF_PROG(xchg, int a)
+SEC("raw_tp/sys_enter")
+int xchg(const void *ctx)
 {
 	if (pid != (bpf_get_current_pid_tgid() >> 32))
 		return 0;
-- 
2.27.0



From houtao1 at huawei.com  Wed Jan 26 23:53:20 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:53:20 +0800
Subject: [PATCH bpf-next v2 0/2] arm64, bpf: support more atomic ops
Message-ID: <20220127075322.675323-1-houtao1@huawei.com>

Hi,

Atomics support in bpf has already been done by "Atomics for eBPF"
patch series [1], but it only adds support for x86, and this patchset
adds support for arm64.

Patch #1 changes the type of test program from fentry/ to raw_tp/ for
atomics test, because bpf trampoline is not available for arm64 now.
After the change, atomics test will be available for arm64 and other
archs.

Patch #2 implements atomic[64]_fetch_add, atomic[64]_[fetch_]{and,or,xor}
and atomic[64]_{xchg|cmpxchg} for arm64. For no-LSE-ATOMICS case and
cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case, both ./test_verifier and
"./test_progs -t atomic" are exercised and passed correspondingly.

Comments are always welcome.

Regards,
Tao

[1]: https://lore.kernel.org/bpf/20210114181751.768687-2-jackmanb at google.com/

Change Log:
v2:
  * patch #1: use two seperated ASSERT_OK() instead of ASSERT_TRUE()
  * add Acked-by tag for both patches

v1: https://lore.kernel.org/bpf/20220121135632.136976-1-houtao1 at huawei.com/


Hou Tao (2):
  selftests/bpf: use raw_tp program for atomic test
  arm64, bpf: support more atomic operations

 arch/arm64/include/asm/insn.h                 |  45 +++-
 arch/arm64/lib/insn.c                         | 155 +++++++++++--
 arch/arm64/net/bpf_jit.h                      |  43 +++-
 arch/arm64/net/bpf_jit_comp.c                 | 216 ++++++++++++++----
 .../selftests/bpf/prog_tests/atomics.c        | 121 +++-------
 tools/testing/selftests/bpf/progs/atomics.c   |  28 +--
 6 files changed, 444 insertions(+), 164 deletions(-)

-- 
2.27.0



From houtao1 at huawei.com  Wed Jan 26 23:53:22 2022
From: houtao1 at huawei.com (Hou Tao)
Date: Thu, 27 Jan 2022 15:53:22 +0800
Subject: [PATCH bpf-next v2 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <20220127075322.675323-1-houtao1@huawei.com>
References: <20220127075322.675323-1-houtao1@huawei.com>
Message-ID: <20220127075322.675323-3-houtao1@huawei.com>

Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
it only add support for x86-64, so support these atomic operations
for arm64 as well.

Basically the implementation procedure is almost mechanical translation
of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
under arch/arm64/include/asm. An extra temporary register is needed
for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
adding TMP_REG_4 just use BPF_REG_AX instead.

For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
both ./test_verifier and "./test_progs -t atomic" are exercised and
passed correspondingly.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
Acked-by: John Fastabend <john.fastabend at gmail.com>
---
 arch/arm64/include/asm/insn.h |  45 +++++--
 arch/arm64/lib/insn.c         | 155 +++++++++++++++++++++---
 arch/arm64/net/bpf_jit.h      |  43 ++++++-
 arch/arm64/net/bpf_jit_comp.c | 216 +++++++++++++++++++++++++++-------
 4 files changed, 394 insertions(+), 65 deletions(-)

diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
index 6b776c8667b2..1416d636f1af 100644
--- a/arch/arm64/include/asm/insn.h
+++ b/arch/arm64/include/asm/insn.h
@@ -280,6 +280,23 @@ enum aarch64_insn_adr_type {
 	AARCH64_INSN_ADR_TYPE_ADR,
 };
 
+enum aarch64_insn_mem_atomic_op {
+	AARCH64_INSN_MEM_ATOMIC_ADD,
+	AARCH64_INSN_MEM_ATOMIC_BIC,
+	AARCH64_INSN_MEM_ATOMIC_EOR,
+	AARCH64_INSN_MEM_ATOMIC_ORR,
+	AARCH64_INSN_MEM_ATOMIC_SWP,
+};
+
+enum aarch64_insn_mem_order_type {
+	AARCH64_INSN_MEM_ORDER_NONE,
+	AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL,
+};
+
+enum aarch64_insn_mb_type {
+	AARCH64_INSN_MB_ISH,
+};
+
 #define	__AARCH64_INSN_FUNCS(abbr, mask, val)				\
 static __always_inline bool aarch64_insn_is_##abbr(u32 code)		\
 {									\
@@ -303,6 +320,11 @@ __AARCH64_INSN_FUNCS(store_post,	0x3FE00C00, 0x38000400)
 __AARCH64_INSN_FUNCS(load_post,	0x3FE00C00, 0x38400400)
 __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
 __AARCH64_INSN_FUNCS(ldadd,	0x3F20FC00, 0x38200000)
+__AARCH64_INSN_FUNCS(ldclr,	0x3F20FC00, 0x38201000)
+__AARCH64_INSN_FUNCS(ldeor,	0x3F20FC00, 0x38202000)
+__AARCH64_INSN_FUNCS(ldset,	0x3F20FC00, 0x38203000)
+__AARCH64_INSN_FUNCS(swp,	0x3F20FC00, 0x38208000)
+__AARCH64_INSN_FUNCS(cas,	0x3FA07C00, 0x08A07C00)
 __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
 __AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
 __AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
@@ -474,13 +496,21 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 				   enum aarch64_insn_register state,
 				   enum aarch64_insn_size_type size,
 				   enum aarch64_insn_ldst_type type);
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-			   enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size);
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size);
+u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
+				      enum aarch64_insn_register base,
+				      enum aarch64_insn_register state,
+				      enum aarch64_insn_size_type size);
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+				  enum aarch64_insn_register address,
+				  enum aarch64_insn_register value,
+				  enum aarch64_insn_size_type size,
+				  enum aarch64_insn_mem_atomic_op op,
+				  enum aarch64_insn_mem_order_type order);
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+			 enum aarch64_insn_register address,
+			 enum aarch64_insn_register value,
+			 enum aarch64_insn_size_type size,
+			 enum aarch64_insn_mem_order_type order);
 u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
 				 enum aarch64_insn_register src,
 				 int imm, enum aarch64_insn_variant variant,
@@ -541,6 +571,7 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
 			      enum aarch64_insn_prfm_type type,
 			      enum aarch64_insn_prfm_target target,
 			      enum aarch64_insn_prfm_policy policy);
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
 s32 aarch64_get_branch_offset(u32 insn);
 u32 aarch64_set_branch_offset(u32 insn, s32 offset);
 
diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
index fccfe363e567..2a7dde58c44b 100644
--- a/arch/arm64/lib/insn.c
+++ b/arch/arm64/lib/insn.c
@@ -328,6 +328,29 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
 	return insn;
 }
 
+static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
+					  u32 insn)
+{
+	u32 order;
+
+	switch (type) {
+	case AARCH64_INSN_MEM_ORDER_NONE:
+		order = 0;
+		break;
+	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
+		order = 3;
+		break;
+	default:
+		pr_err("%s: unknown mem order %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn &= ~GENMASK(23, 22);
+	insn |= order << 22;
+
+	return insn;
+}
+
 static inline long branch_imm_common(unsigned long pc, unsigned long addr,
 				     long range)
 {
@@ -603,12 +626,49 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 					    state);
 }
 
-u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
-			   enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size)
+u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
+				      enum aarch64_insn_register base,
+				      enum aarch64_insn_register state,
+				      enum aarch64_insn_size_type size)
+{
+	u32 insn = aarch64_insn_gen_load_store_ex(reg, base, state, size,
+						  AARCH64_INSN_LDST_STORE_EX);
+
+	if (insn == AARCH64_BREAK_FAULT)
+		return insn;
+
+	return insn | BIT(15);
+}
+
+u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
+				  enum aarch64_insn_register address,
+				  enum aarch64_insn_register value,
+				  enum aarch64_insn_size_type size,
+				  enum aarch64_insn_mem_atomic_op op,
+				  enum aarch64_insn_mem_order_type order)
 {
-	u32 insn = aarch64_insn_get_ldadd_value();
+	u32 insn;
+
+	switch (op) {
+	case AARCH64_INSN_MEM_ATOMIC_ADD:
+		insn = aarch64_insn_get_ldadd_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_BIC:
+		insn = aarch64_insn_get_ldclr_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_EOR:
+		insn = aarch64_insn_get_ldeor_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_ORR:
+		insn = aarch64_insn_get_ldset_value();
+		break;
+	case AARCH64_INSN_MEM_ATOMIC_SWP:
+		insn = aarch64_insn_get_swp_value();
+		break;
+	default:
+		pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
+		return AARCH64_BREAK_FAULT;
+	}
 
 	switch (size) {
 	case AARCH64_INSN_SIZE_32:
@@ -621,6 +681,8 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
 
 	insn = aarch64_insn_encode_ldst_size(size, insn);
 
+	insn = aarch64_insn_encode_ldst_order(order, insn);
+
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
 					    result);
 
@@ -631,16 +693,60 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
 					    value);
 }
 
-u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
-			   enum aarch64_insn_register value,
-			   enum aarch64_insn_size_type size)
+static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
+					 u32 insn)
 {
-	/*
-	 * STADD is simply encoded as an alias for LDADD with XZR as
-	 * the destination register.
-	 */
-	return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address,
-				      value, size);
+	u32 order;
+
+	switch (type) {
+	case AARCH64_INSN_MEM_ORDER_NONE:
+		order = 0;
+		break;
+	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
+		order = BIT(15) | BIT(22);
+		break;
+	default:
+		pr_err("%s: unknown mem order %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn &= ~(BIT(15) | BIT(22));
+	insn |= order;
+
+	return insn;
+}
+
+u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
+			 enum aarch64_insn_register address,
+			 enum aarch64_insn_register value,
+			 enum aarch64_insn_size_type size,
+			 enum aarch64_insn_mem_order_type order)
+{
+	u32 insn;
+
+	switch (size) {
+	case AARCH64_INSN_SIZE_32:
+	case AARCH64_INSN_SIZE_64:
+		break;
+	default:
+		pr_err("%s: unimplemented size encoding %d\n", __func__, size);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn = aarch64_insn_get_cas_value();
+
+	insn = aarch64_insn_encode_ldst_size(size, insn);
+
+	insn = aarch64_insn_encode_cas_order(order, insn);
+
+	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
+					    result);
+
+	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
+					    address);
+
+	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
+					    value);
 }
 
 static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
@@ -1456,3 +1562,24 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
 	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
 	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
 }
+
+u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
+{
+	u32 opt;
+	u32 insn;
+
+	switch (type) {
+	case AARCH64_INSN_MB_ISH:
+		opt = 0xb;
+		break;
+	default:
+		pr_err("%s: unknown dmb type %d\n", __func__, type);
+		return AARCH64_BREAK_FAULT;
+	}
+
+	insn = aarch64_insn_get_dmb_value();
+	insn &= ~GENMASK(11, 8);
+	insn |= (opt << 8);
+
+	return insn;
+}
diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
index cc0cf0f5c7c3..308f96587861 100644
--- a/arch/arm64/net/bpf_jit.h
+++ b/arch/arm64/net/bpf_jit.h
@@ -88,10 +88,41 @@
 /* [Rn] = Rt; (atomic) Rs = [state] */
 #define A64_STXR(sf, Rt, Rn, Rs) \
 	A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
+/* smp_mb(); [Rn] = Rt; (atomic) Rs = [state] */
+#define A64_STLXR(sf, Rt, Rn, Rs) \
+	aarch64_insn_gen_store_release_ex(Rt, Rn, Rs, A64_SIZE(sf))
 
-/* LSE atomics */
-#define A64_STADD(sf, Rn, Rs) \
-	aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf))
+/*
+ * LSE atomics
+ *
+ * ST{ADD,CLR,SET,EOR} is simply encoded as an alias for
+ * LDD{ADD,CLR,SET,EOR} with XZR as the destination register.
+ */
+#define A64_ST_OP(sf, Rn, Rs, op) \
+	aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
+		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+		AARCH64_INSN_MEM_ORDER_NONE)
+/* [Rn] <op>= Rs */
+#define A64_STADD(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ADD)
+#define A64_STCLR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, BIC)
+#define A64_STEOR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, EOR)
+#define A64_STSET(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ORR)
+
+#define A64_LD_OP_AL(sf, Rt, Rn, Rs, op) \
+	aarch64_insn_gen_atomic_ld_op(Rt, Rn, Rs, \
+		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
+		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
+/* Rt = [Rn]; [Rn] <op>= Rs */
+#define A64_LDADDAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ADD)
+#define A64_LDCLRAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, BIC)
+#define A64_LDEORAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, EOR)
+#define A64_LDSETAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ORR)
+/* Rt = [Rn]; [Rn] = Rs */
+#define A64_SWPAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SWP)
+/* Rs = CAS(Rn, Rs, Rt) */
+#define A64_CASAL(sf, Rt, Rn, Rs) \
+	aarch64_insn_gen_cas(Rt, Rn, Rs, A64_SIZE(sf), \
+		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
 
 /* Add/subtract (immediate) */
 #define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
@@ -196,6 +227,9 @@
 #define A64_ANDS(sf, Rd, Rn, Rm) A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND_SETFLAGS)
 /* Rn & Rm; set condition flags */
 #define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm)
+/* Rd = ~Rm (alias of ORN with A64_ZR as Rn) */
+#define A64_MVN(sf, Rd, Rm)  \
+	A64_LOGIC_SREG(sf, Rd, A64_ZR, Rm, ORN)
 
 /* Logical (immediate) */
 #define A64_LOGIC_IMM(sf, Rd, Rn, imm, type) ({ \
@@ -219,4 +253,7 @@
 #define A64_BTI_J  A64_HINT(AARCH64_INSN_HINT_BTIJ)
 #define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC)
 
+/* DMB */
+#define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
+
 #endif /* _BPF_JIT_H */
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 3c2f91b8b00b..e60c464004c2 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -29,6 +29,17 @@
 #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
 #define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
 
+#define check_imm(bits, imm) do {				\
+	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
+	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
+		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
+			i, imm, imm);				\
+		return -EINVAL;					\
+	}							\
+} while (0)
+#define check_imm19(imm) check_imm(19, imm)
+#define check_imm26(imm) check_imm(26, imm)
+
 /* Map BPF registers to A64 registers */
 static const int bpf2a64[] = {
 	/* return value from in-kernel function, and exit value from eBPF */
@@ -332,6 +343,163 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
 #undef jmp_offset
 }
 
+static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const u8 code = insn->code;
+	const u8 dst = bpf2a64[insn->dst_reg];
+	const u8 src = bpf2a64[insn->src_reg];
+	const u8 tmp = bpf2a64[TMP_REG_1];
+	const u8 tmp2 = bpf2a64[TMP_REG_2];
+	const bool isdw = BPF_SIZE(code) == BPF_DW;
+	const s16 off = insn->off;
+	u8 reg;
+
+	if (!off) {
+		reg = dst;
+	} else {
+		emit_a64_mov_i(1, tmp, off, ctx);
+		emit(A64_ADD(1, tmp, tmp, dst), ctx);
+		reg = tmp;
+	}
+
+	switch (insn->imm) {
+	/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+	case BPF_ADD:
+		emit(A64_STADD(isdw, reg, src), ctx);
+		break;
+	case BPF_AND:
+		emit(A64_MVN(isdw, tmp2, src), ctx);
+		emit(A64_STCLR(isdw, reg, tmp2), ctx);
+		break;
+	case BPF_OR:
+		emit(A64_STSET(isdw, reg, src), ctx);
+		break;
+	case BPF_XOR:
+		emit(A64_STEOR(isdw, reg, src), ctx);
+		break;
+	/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
+	case BPF_ADD | BPF_FETCH:
+		emit(A64_LDADDAL(isdw, src, reg, src), ctx);
+		break;
+	case BPF_AND | BPF_FETCH:
+		emit(A64_MVN(isdw, tmp2, src), ctx);
+		emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
+		break;
+	case BPF_OR | BPF_FETCH:
+		emit(A64_LDSETAL(isdw, src, reg, src), ctx);
+		break;
+	case BPF_XOR | BPF_FETCH:
+		emit(A64_LDEORAL(isdw, src, reg, src), ctx);
+		break;
+	/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+	case BPF_XCHG:
+		emit(A64_SWPAL(isdw, src, reg, src), ctx);
+		break;
+	/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+	case BPF_CMPXCHG:
+		emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
+		break;
+	default:
+		pr_err_once("unknown atomic op code %02x\n", insn->imm);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int emit_ll_sc_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const u8 code = insn->code;
+	const u8 dst = bpf2a64[insn->dst_reg];
+	const u8 src = bpf2a64[insn->src_reg];
+	const u8 tmp = bpf2a64[TMP_REG_1];
+	const u8 tmp2 = bpf2a64[TMP_REG_2];
+	const u8 tmp3 = bpf2a64[TMP_REG_3];
+	const int i = insn - ctx->prog->insnsi;
+	const s32 imm = insn->imm;
+	const s16 off = insn->off;
+	const bool isdw = BPF_SIZE(code) == BPF_DW;
+	u8 reg;
+	s32 jmp_offset;
+
+	if (!off) {
+		reg = dst;
+	} else {
+		emit_a64_mov_i(1, tmp, off, ctx);
+		emit(A64_ADD(1, tmp, tmp, dst), ctx);
+		reg = tmp;
+	}
+
+	if (imm == BPF_ADD || imm == BPF_AND ||
+	    imm == BPF_OR || imm == BPF_XOR) {
+		/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
+		emit(A64_LDXR(isdw, tmp2, reg), ctx);
+		if (imm == BPF_ADD)
+			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
+		else if (imm == BPF_AND)
+			emit(A64_AND(isdw, tmp2, tmp2, src), ctx);
+		else if (imm == BPF_OR)
+			emit(A64_ORR(isdw, tmp2, tmp2, src), ctx);
+		else
+			emit(A64_EOR(isdw, tmp2, tmp2, src), ctx);
+		emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -3;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+	} else if (imm == (BPF_ADD | BPF_FETCH) ||
+		   imm == (BPF_AND | BPF_FETCH) ||
+		   imm == (BPF_OR | BPF_FETCH) ||
+		   imm == (BPF_XOR | BPF_FETCH)) {
+		/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
+		const u8 ax = bpf2a64[BPF_REG_AX];
+
+		emit(A64_MOV(isdw, ax, src), ctx);
+		emit(A64_LDXR(isdw, src, reg), ctx);
+		if (imm == (BPF_ADD | BPF_FETCH))
+			emit(A64_ADD(isdw, tmp2, src, ax), ctx);
+		else if (imm == (BPF_AND | BPF_FETCH))
+			emit(A64_AND(isdw, tmp2, src, ax), ctx);
+		else if (imm == (BPF_OR | BPF_FETCH))
+			emit(A64_ORR(isdw, tmp2, src, ax), ctx);
+		else
+			emit(A64_EOR(isdw, tmp2, src, ax), ctx);
+		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -3;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else if (imm == BPF_XCHG) {
+		/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
+		emit(A64_MOV(isdw, tmp2, src), ctx);
+		emit(A64_LDXR(isdw, src, reg), ctx);
+		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
+		jmp_offset = -2;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else if (imm == BPF_CMPXCHG) {
+		/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
+		const u8 r0 = bpf2a64[BPF_REG_0];
+
+		emit(A64_MOV(isdw, tmp2, r0), ctx);
+		emit(A64_LDXR(isdw, r0, reg), ctx);
+		emit(A64_EOR(isdw, tmp3, r0, tmp2), ctx);
+		jmp_offset = 4;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(isdw, tmp3, jmp_offset), ctx);
+		emit(A64_STLXR(isdw, src, reg, tmp3), ctx);
+		jmp_offset = -4;
+		check_imm19(jmp_offset);
+		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
+		emit(A64_DMB_ISH, ctx);
+	} else {
+		pr_err_once("unknown atomic op code %02x\n", imm);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static void build_epilogue(struct jit_ctx *ctx)
 {
 	const u8 r0 = bpf2a64[BPF_REG_0];
@@ -437,29 +605,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
 	const u8 src = bpf2a64[insn->src_reg];
 	const u8 tmp = bpf2a64[TMP_REG_1];
 	const u8 tmp2 = bpf2a64[TMP_REG_2];
-	const u8 tmp3 = bpf2a64[TMP_REG_3];
 	const s16 off = insn->off;
 	const s32 imm = insn->imm;
 	const int i = insn - ctx->prog->insnsi;
 	const bool is64 = BPF_CLASS(code) == BPF_ALU64 ||
 			  BPF_CLASS(code) == BPF_JMP;
-	const bool isdw = BPF_SIZE(code) == BPF_DW;
-	u8 jmp_cond, reg;
+	u8 jmp_cond;
 	s32 jmp_offset;
 	u32 a64_insn;
 	int ret;
 
-#define check_imm(bits, imm) do {				\
-	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
-	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
-		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
-			i, imm, imm);				\
-		return -EINVAL;					\
-	}							\
-} while (0)
-#define check_imm19(imm) check_imm(19, imm)
-#define check_imm26(imm) check_imm(26, imm)
-
 	switch (code) {
 	/* dst = src */
 	case BPF_ALU | BPF_MOV | BPF_X:
@@ -894,33 +1049,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
 
 	case BPF_STX | BPF_ATOMIC | BPF_W:
 	case BPF_STX | BPF_ATOMIC | BPF_DW:
-		if (insn->imm != BPF_ADD) {
-			pr_err_once("unknown atomic op code %02x\n", insn->imm);
-			return -EINVAL;
-		}
-
-		/* STX XADD: lock *(u32 *)(dst + off) += src
-		 * and
-		 * STX XADD: lock *(u64 *)(dst + off) += src
-		 */
-
-		if (!off) {
-			reg = dst;
-		} else {
-			emit_a64_mov_i(1, tmp, off, ctx);
-			emit(A64_ADD(1, tmp, tmp, dst), ctx);
-			reg = tmp;
-		}
-		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) {
-			emit(A64_STADD(isdw, reg, src), ctx);
-		} else {
-			emit(A64_LDXR(isdw, tmp2, reg), ctx);
-			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
-			emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
-			jmp_offset = -3;
-			check_imm19(jmp_offset);
-			emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
-		}
+		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
+			ret = emit_lse_atomic(insn, ctx);
+		else
+			ret = emit_ll_sc_atomic(insn, ctx);
+		if (ret)
+			return ret;
 		break;
 
 	default:
-- 
2.27.0



From victor.liu at nxp.com  Fri Jan 28 01:19:44 2022
From: victor.liu at nxp.com (Liu Ying)
Date: Fri, 28 Jan 2022 17:19:44 +0800
Subject: [PATCH] drm/imx: dw_hdmi-imx: Fix bailout in error cases of probe
Message-ID: <20220128091944.3831256-1-victor.liu@nxp.com>

In dw_hdmi_imx_probe(), if error happens after dw_hdmi_probe() returns
successfully, dw_hdmi_remove() should be called where necessary as
bailout.

Fixes: c805ec7eb210 ("drm/imx: dw_hdmi-imx: move initialization into probe")
Cc: Philipp Zabel <p.zabel at pengutronix.de>
Cc: David Airlie <airlied at linux.ie>
Cc: Daniel Vetter <daniel at ffwll.ch>
Cc: Shawn Guo <shawnguo at kernel.org>
Cc: Sascha Hauer <s.hauer at pengutronix.de>
Cc: Pengutronix Kernel Team <kernel at pengutronix.de>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: NXP Linux Team <linux-imx at nxp.com>
Signed-off-by: Liu Ying <victor.liu at nxp.com>
---
 drivers/gpu/drm/imx/dw_hdmi-imx.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 87428fb23d9f..a2277a0d6d06 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -222,6 +222,7 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	const struct of_device_id *match = of_match_node(dw_hdmi_imx_dt_ids, np);
 	struct imx_hdmi *hdmi;
+	int ret;
 
 	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
 	if (!hdmi)
@@ -243,10 +244,15 @@ static int dw_hdmi_imx_probe(struct platform_device *pdev)
 	hdmi->bridge = of_drm_find_bridge(np);
 	if (!hdmi->bridge) {
 		dev_err(hdmi->dev, "Unable to find bridge\n");
+		dw_hdmi_remove(hdmi->hdmi);
 		return -ENODEV;
 	}
 
-	return component_add(&pdev->dev, &dw_hdmi_imx_ops);
+	ret = component_add(&pdev->dev, &dw_hdmi_imx_ops);
+	if (ret)
+		dw_hdmi_remove(hdmi->hdmi);
+
+	return ret;
 }
 
 static int dw_hdmi_imx_remove(struct platform_device *pdev)
-- 
2.25.1



From hongxing.zhu at nxp.com  Fri Jan 28 01:25:11 2022
From: hongxing.zhu at nxp.com (Hongxing Zhu)
Date: Fri, 28 Jan 2022 09:25:11 +0000
Subject: [RFC PATCH] PCI: imx6: Handle the abort from user-space
In-Reply-To: <20220128082920.591115-1-francesco.dolcini@toradex.com>
References: <20220128082920.591115-1-francesco.dolcini@toradex.com>
Message-ID: <AS8PR04MB8676E90C0A394C82BB0A890B8C229@AS8PR04MB8676.eurprd04.prod.outlook.com>

> -----Original Message-----
> From: Francesco Dolcini <francesco.dolcini at toradex.com>
> Sent: 2022??1??28?? 16:29
> To: Hongxing Zhu <hongxing.zhu at nxp.com>; Lucas Stach
> <l.stach at pengutronix.de>; Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>; Rob
> Herring <robh at kernel.org>; Krzysztof Wilczy??ski <kw at linux.com>; Sascha
> Hauer <s.hauer at pengutronix.de>; Pengutronix Kernel Team
> <kernel at pengutronix.de>; Fabio Estevam <festevam at gmail.com>;
> dl-linux-imx <linux-imx at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>
> Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; Bjorn Helgaas <bhelgaas at google.com>; Shawn
> Guo <shawnguo at kernel.org>; Francesco Dolcini
> <francesco.dolcini at toradex.com>
> Subject: [RFC PATCH] PCI: imx6: Handle the abort from user-space
> 
> From: Jason Liu <jason.hui.liu at nxp.com>
> 
> The driver install one hook to handle the external abort, but issue is that if the
> abort introduced from user space code, the following code unsigned long instr
> = *(unsigned long *)pc; which will created another data-abort(page domain
> fault) if CONFIG_CPU_SW_DOMAIN_PAN.
> 
> The patch does not intent to use copy_from_user and then do the hack due to
> the security consideration. In fact, we can just return and report the external
> abort to user-space.
> 
> Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
> Reviewed-by: Richard Zhu <hongxing.zhu at nxp.com>
> Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
> ---
> We have this patch from NXP downstream kernel [1] in our kernel branch [2]
> since a long time, to me it would make sense to upstream it. Any concern?
> 
> [1]
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.
> codeaurora.org%2Fexternal%2Fimxsupport%2Flinux-imx%2Fcommit%2F%3Fid
> %3D62dfb2fb953463dd1b6710567c9e174672a98f24&amp;data=04%7C01%7
> Chongxing.zhu%40nxp.com%7Ccbe193ab4c3e4ad11bcb08d9e2384a1f%7C68
> 6ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637789553659549198%7
> CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBT
> iI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Mwhx8DFF7EDJdpqTsHT
> %2BBAGzhQadDOqcgJnVjeoi1yk%3D&amp;reserved=0
> [2]
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.tora
> dex.com%2Fcgit%2Flinux-toradex.git%2Fcommit%2F%3Fid%3D2b42547cf659f
> 979be2defdff6a99f921b33d0f1&amp;data=04%7C01%7Chongxing.zhu%40nx
> p.com%7Ccbe193ab4c3e4ad11bcb08d9e2384a1f%7C686ea1d3bc2b4c6fa92c
> d99c5c301635%7C0%7C0%7C637789553659549198%7CUnknown%7CTWFp
> bGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI
> 6Mn0%3D%7C3000&amp;sdata=QEW1frh8WacCzniWo4ng1cy3Z1UZ9uMRFw
> GBKuIh7zE%3D&amp;reserved=0
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> b/drivers/pci/controller/dwc/pci-imx6.c
> index 6974bd5aa116..6b178a29e253 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -27,6 +27,7 @@
>  #include <linux/resource.h>
>  #include <linux/signal.h>
>  #include <linux/types.h>
> +#include <linux/uaccess.h>

[Richard Zhu] Thanks for your kindly help.
This header include is not required actually, please remove it.
Best Regards
Richard

>  #include <linux/interrupt.h>
>  #include <linux/reset.h>
>  #include <linux/phy/phy.h>
> @@ -297,8 +298,15 @@ static int imx6q_pcie_abort_handler(unsigned long
> addr,
>  		unsigned int fsr, struct pt_regs *regs)  {
>  	unsigned long pc = instruction_pointer(regs);
> -	unsigned long instr = *(unsigned long *)pc;
> -	int reg = (instr >> 12) & 15;
> +	unsigned long instr;
> +	int reg;
> +
> +	/* if the abort from user-space, just return and report it */
> +	if (user_mode(regs))
> +		return 1;
> +
> +	instr = *(unsigned long *)pc;
> +	reg = (instr >> 12) & 15;
> 
>  	/*
>  	 * If the instruction being executed was a read,
> --
> 2.25.1


From yong.wu at mediatek.com  Fri Jan 28 01:39:06 2022
From: yong.wu at mediatek.com (Yong Wu)
Date: Fri, 28 Jan 2022 17:39:06 +0800
Subject: [PATCH 2/2] iommu/mediatek: Add mt8186 iommu support
In-Reply-To: <b52a1df8-58f4-baa2-cfb6-9c56244caa0f@collabora.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
 <20220125093244.18230-3-yong.wu@mediatek.com>
 <b52a1df8-58f4-baa2-cfb6-9c56244caa0f@collabora.com>
Message-ID: <01cc69cdf7773962140c01fe37b12ab2c9491c25.camel@mediatek.com>

On Thu, 2022-01-27 at 12:28 +0100, AngeloGioacchino Del Regno wrote:
> Il 25/01/22 10:32, Yong Wu ha scritto:
> > Add mt8186 iommu supports.
> > 
> > Signed-off-by: Anan Sun <anan.sun at mediatek.com>
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > ---
> >   drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
> >   1 file changed, 17 insertions(+)

[snip]

> >   static const struct mtk_iommu_plat_data mt8192_data = {
> >   	.m4u_plat       = M4U_MT8192,
> >   	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS |
> > OUT_ORDER_WR_EN |
> > @@ -1470,6 +1486,7 @@ static const struct of_device_id
> > mtk_iommu_of_ids[] = {
> >   	{ .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data},
> >   	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
> >   	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
> > +	{ .compatible = "mediatek,mt8186-iommu-mm", .data =
> > &mt8186_data_mm},
> 
> Hello!
> 
> Is there any particular reason why this compatible is not
> "mediatek,mt8186-m4u"?

There is no special reason. In the previous SoC, We only support MM
IOMMU, it was called by "m4u". In the lastest SoC, We have the other
types IOMMU, like for INFRA masters and APU, thus they are called "mm
iommu", "infra iommu" and "apu iommu". Of course, "m4u" means "mm
iommu".

> 
> Thanks,
> Angelo
> 
> >   	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
> >   	{ .compatible = "mediatek,mt8195-iommu-infra", .data =
> > &mt8195_data_infra},
> >   	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data =
> > &mt8195_data_vdo},
> 
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek

From shawnguo at kernel.org  Fri Jan 28 01:47:44 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 17:47:44 +0800
Subject: [PATCH v8 1/7] ARM: imx: Add initial support for i.MXRT10xx family
In-Reply-To: <20220111215415.2075257-2-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-2-Mr.Bossman075@gmail.com>
Message-ID: <20220128094743.GI4686@dragon>

On Tue, Jan 11, 2022 at 04:54:09PM -0500, Jesse Taube wrote:
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> The i.MXRT10xx family of processors features NXP's implementation of the
> Arm Cortex-M7 core and in some case the Arm Cortex-M4 core too.
> 
> This patch aims to add an initial support for imxrt.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: removed SOC_IMXRT's 'depends on ARCH_MULTI_V7' and 'select
> ARM_GIC if ARCH_MULTI_V7']

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 01:49:18 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 17:49:18 +0800
Subject: [PATCH v8 2/7] ARM: dts: imxrt1050-pinfunc: Add pinctrl binding
 header
In-Reply-To: <20220111215415.2075257-3-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-3-Mr.Bossman075@gmail.com>
Message-ID: <20220128094910.GJ4686@dragon>

On Tue, Jan 11, 2022 at 04:54:10PM -0500, Jesse Taube wrote:
> From: Jesse Taube <mr.bossman075 at gmail.com>
> 
> Add binding header for i.MXRT1050 pinctrl device tree.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: move pinfunc from dt-bindings to dts folder]

Applied, thanks!


From frank-w at public-files.de  Fri Jan 28 01:51:20 2022
From: frank-w at public-files.de (Frank Wunderlich)
Date: Fri, 28 Jan 2022 10:51:20 +0100
Subject: BUG: [PATCH v2] isoc: mediatek: Check for error clk pointer
In-Reply-To: <20211222015157.1025853-1-jiasheng@iscas.ac.cn>
References: <20211222015157.1025853-1-jiasheng@iscas.ac.cn>
Message-ID: <trinity-2a727d96-0335-4d03-8f30-e22a0e10112d-1643363480085@3c-app-gmx-bap33>

Hi,

this commit is merged in 5.17-rc1 and breaks scpsys on mt7622/bananapi R64

mtk-scpsys: probe of 10006000.power-controller failed with error -2

at least ethernet is affected (i guess usb,sata,btif,... too, but not checked), as gmacs do not get probed as depency of it

after reverting this commit it is working again.

have not yet digged deeper into it why it is failing, but maybe author has an idea

regards Frank

> Gesendet: Mittwoch, 22. Dezember 2021 um 02:51 Uhr
> Von: "Jiasheng Jiang" <jiasheng at iscas.ac.cn>
> An: matthias.bgg at gmail.com, lgirdwood at gmail.com, broonie at kernel.org
> Cc: linux-arm-kernel at lists.infradead.org, linux-mediatek at lists.infradead.org, linux-kernel at vger.kernel.org, "Jiasheng Jiang" <jiasheng at iscas.ac.cn>
> Betreff: [PATCH v2] isoc: mediatek: Check for error clk pointer
>
> On Wed, Dec 22, 2021 at 01:57:15AM +0800, Mark Brown wrote:
> >> +	for (i = CLK_NONE + 1; i < CLK_MAX; i++) {
> >>  		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
> >> +		if (IS_ERR(clk[i]))
> >> +			return PTR_ERR(clk[i]);
> >
> > This now pays attention to the error code here which is good but...
> >
> >> -	init_clks(pdev, clk);
> >> +	ret = init_clks(pdev, clk);
> >> +	if (ret)
> >> +		return ERR_PTR(-ENOMEM);
> >
> > ...then discards it here with a random most likely inappropriate error
> > code.
>
> Yes, you are right and now the return code depending on the
> init_clks().
>
> Fixes: 6078c651947a ("soc: mediatek: Refine scpsys to support multiple platform")
> Signed-off-by: Jiasheng Jiang <jiasheng at iscas.ac.cn>
> ---
> Changelog:
>
> v1 -> v2
>
> *Change 1. Change the return code.
> ---
>  drivers/soc/mediatek/mtk-scpsys.c | 15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
> index ca75b14931ec..670cc82d17dc 100644
> --- a/drivers/soc/mediatek/mtk-scpsys.c
> +++ b/drivers/soc/mediatek/mtk-scpsys.c
> @@ -411,12 +411,17 @@ static int scpsys_power_off(struct generic_pm_domain *genpd)
>  	return ret;
>  }
>
> -static void init_clks(struct platform_device *pdev, struct clk **clk)
> +static int init_clks(struct platform_device *pdev, struct clk **clk)
>  {
>  	int i;
>
> -	for (i = CLK_NONE + 1; i < CLK_MAX; i++)
> +	for (i = CLK_NONE + 1; i < CLK_MAX; i++) {
>  		clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
> +		if (IS_ERR(clk[i]))
> +			return PTR_ERR(clk[i]);
> +	}
> +
> +	return 0;
>  }
>
>  static struct scp *init_scp(struct platform_device *pdev,
> @@ -426,7 +431,7 @@ static struct scp *init_scp(struct platform_device *pdev,
>  {
>  	struct genpd_onecell_data *pd_data;
>  	struct resource *res;
> -	int i, j;
> +	int i, j, ret;
>  	struct scp *scp;
>  	struct clk *clk[CLK_MAX];
>
> @@ -481,7 +486,9 @@ static struct scp *init_scp(struct platform_device *pdev,
>
>  	pd_data->num_domains = num;
>
> -	init_clks(pdev, clk);
> +	ret = init_clks(pdev, clk);
> +	if (ret)
> +		return ERR_PTR(ret);
>
>  	for (i = 0; i < num; i++) {
>  		struct scp_domain *scpd = &scp->domains[i];
> --
> 2.25.1
>
>
> _______________________________________________
> Linux-mediatek mailing list
> Linux-mediatek at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-mediatek
>


From mkorpershoek at baylibre.com  Fri Jan 28 02:03:08 2022
From: mkorpershoek at baylibre.com (Mattijs Korpershoek)
Date: Fri, 28 Jan 2022 11:03:08 +0100
Subject: [PATCH v20 2/3] Input: mt6779-keypad - Add MediaTek keypad driver
In-Reply-To: <YfK4UcuCfF7JfI7H@smile.fi.intel.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
 <20220127111526.3716689-3-mkorpershoek@baylibre.com>
 <YfK4UcuCfF7JfI7H@smile.fi.intel.com>
Message-ID: <87v8y4p483.fsf@baylibre.com>

On Thu, Jan 27, 2022 at 17:20, Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:

> On Thu, Jan 27, 2022 at 12:15:25PM +0100, Mattijs Korpershoek wrote:
>> From: "fengping.yu" <fengping.yu at mediatek.com>
>> 
>> This patch adds matrix keypad support for Mediatek SoCs.
>
> Some comments which may be addressed now or in the follow-up patch(es).
> Up to you.
Hi Andy,
Thank you for your review and your suggestions.

>
> ...
>
>> +static const struct regmap_config mt6779_keypad_regmap_cfg = {
>> +	.reg_bits = 32,
>> +	.val_bits = 32,
>
>> +	.reg_stride = sizeof(u32),
>
> I'm wondering if we need this when we have reg_bits = 32 already.

Per my understanding, .reg_stride is mainly used to check for invalid register
addresses in regmap_{read,write}():

    if (!IS_ALIGNED(reg, map->reg_stride))
            return -EINVAL;

If .reg_stride is not set, regmap core will default it to 1.
It's not computed from reg_bits.

So I think we still need it.
>
>> +	.max_register = 36,
>> +};
>
> ...
>
>> +	regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
>> +		     (debounce * 32) & MTK_KPD_DEBOUNCE_MASK);
>
> I'm wondering if << 5 is more specific to show that the value
> is based on 2^5 units.

The datasheet I've seen states: "De-bounce time = KP_DEBOUNCE / 32ms"
But rewriting it as 1 << 5 seems reasonable as well:
regmap_write(keypad->regmap, MTK_KPD_DEBOUNCE,
            (debounce * (1 << 5)) & MTK_KPD_DEBOUNCE_MASK);

I don't have any preference on this one.
If I have to send a v21, I will rewrite it using (1 << 5)

>
> ...
>
>> +	error = devm_add_action_or_reset(&pdev->dev, mt6779_keypad_clk_disable, keypad->clk);
>
> You have this long line...
>
>> +	error = devm_request_threaded_irq(&pdev->dev, irq,
>> +					  NULL, mt6779_keypad_irq_handler,
>> +					  IRQF_ONESHOT,
>> +					  MTK_KPD_NAME, keypad);
>
> ...at the same time you may reduce LOCs here...
Ack. will join lines to reduce LOCs if I have to send v21.
>
>> +	if (error) {
>> +		dev_err(&pdev->dev, "Failed to request IRQ#%d:%d\n",
>> +			irq, error);
>
> ...and here.
Ack. will join lines to reduce LOCs if I have to send v21.

>
>> +		return error;
>> +	}
>
> -- 
> With Best Regards,
> Andy Shevchenko


From mark.rutland at arm.com  Fri Jan 28 02:03:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 10:03:57 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfLqhKf4yYGVK8Do@sirena.org.uk>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk> <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
 <YfA3D3c+lOyybNT3@sirena.org.uk> <YfLDkoihLFnixAaQ@FVFF77S0Q05N>
 <YfLqhKf4yYGVK8Do@sirena.org.uk>
Message-ID: <YfO/d5a0zc7cBgw5@FVFF77S0Q05N>

On Thu, Jan 27, 2022 at 06:55:00PM +0000, Mark Brown wrote:
> On Thu, Jan 27, 2022 at 04:08:50PM +0000, Mark Rutland wrote:
> > On Tue, Jan 25, 2022 at 05:44:47PM +0000, Mark Brown wrote:
> > > On Tue, Jan 25, 2022 at 04:33:39PM +0000, Mark Rutland wrote:
> > > > On Tue, Jan 25, 2022 at 03:59:38PM +0000, Mark Brown wrote:
> 
> > > > a) Use <register>_<field>_<valuename> definition, as here.
> 
> > > > b) Use <register>_<field>_MASK, and add comments at each usage as to why we use
> > > >    a mask as a value, to explain why that isn't a bug.
> 
> > > > c) Have both <register>_<field>_MASK and some value definition, and use some
> > > >    insertion helper to insert the value.
> 
> > > > ... and I went with (a) because it was the simplest.
> 
> > > > Is there a problem with this?
> 
> > > My concern is continuity of the enumeration algorithm between the
> > > various implementations we have, it's something we're not currently
> > > great with and this creates a separation between the kernel and the boot
> > > wrapper implementations.  There's no change in what's actually being
> > > done but it creates some additional effort to figure out why we're
> > > setting a maximum here and not trying to set all the bits as we do in
> > > the kernel.
> 
> > TBH, I'd argue if we're setting those bits in the kernel it's probably a bug,
> > because we don't know *exactly* what effect they'll have when allocated in the
> > future.
> 
> My comments there are related purely to the renaming of the constant,
> not to the narrowing of the bitmask which is less of an issue.

Ok.

> Basically avoiding the question "why is that a maximum and not a mask"
> and if there's limits on the valid values that are more restrictive than
> the representable values.
>
> The ideal thing for the boot wrapper would be option (c) with either a
> configuration option to set the maximum to something lower than all
> bits, unless someone was unduly enthusiastic and wanted to have an all
> CPUs enumeration algorithm, but both are probably more trouble than it's
> worth.

FWIW, if it's useful for testing to be able to configure the ZCR_EL3.LEN to
some smaller value, I'd be happy to move to (c) and get that plumbed into the
build system.

For now, I plan to take the series with this as-is, since having
ZCR_EL3_LEN_MAX is consistent with other field values we only insert, e.g.
MDCR_EL3_NSPB_NS_NOTRAP.

I'm happy to rejig that in future.

Thanks,
Mark


From daniel at iogearbox.net  Fri Jan 28 02:06:05 2022
From: daniel at iogearbox.net (Daniel Borkmann)
Date: Fri, 28 Jan 2022 11:06:05 +0100
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <20220121135632.136976-3-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
Message-ID: <2dca37b0-6eed-38d5-3491-1febf80bd50d@iogearbox.net>

On 1/21/22 2:56 PM, Hou Tao wrote:
> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
> it only add support for x86-64, so support these atomic operations
> for arm64 as well.
> 
> Basically the implementation procedure is almost mechanical translation
> of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
> under arch/arm64/include/asm. An extra temporary register is needed
> for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
> adding TMP_REG_4 just use BPF_REG_AX instead.
> 
> For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
> both ./test_verifier and "./test_progs -t atomic" are exercised and
> passed correspondingly.

Please also make sure that lib/test_bpf.ko passes given it has the most
extensive tests around atomics.

Thanks,
Daniel


From carsten.haitzler at foss.arm.com  Fri Jan 28 02:07:20 2022
From: carsten.haitzler at foss.arm.com (carsten.haitzler at foss.arm.com)
Date: Fri, 28 Jan 2022 10:07:20 +0000
Subject: [PATCH] arm64: defconfig: Enable modules for arm displays
Message-ID: <20220128100720.87803-1-carsten.haitzler@foss.arm.com>

From: Carsten Haitzler <carsten.haitzler at arm.com>

Key devices that support displays on SoCs like the Komeda DRM driver, the
older HDLCD were not enabled by default and should be so displays can work
out of the box on defconfig. Also Candence I2C support should be enabled so
the PHY and thus displays can work too.

Signed-off-by: Carsten Haitzler <carsten.haitzler at arm.com>
---
 arch/arm64/configs/defconfig | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..87edd79dac99 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -469,6 +469,7 @@ CONFIG_I2C_TEGRA=y
 CONFIG_I2C_UNIPHIER_F=y
 CONFIG_I2C_RCAR=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
+CONFIG_I2C_CADENCE=m
 CONFIG_SPI=y
 CONFIG_SPI_ARMADA_3700=y
 CONFIG_SPI_BCM2835=m
@@ -678,7 +679,9 @@ CONFIG_VIDEO_OV5645=m
 CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
+CONFIG_DRM_HDLCD=m
 CONFIG_DRM_MALI_DISPLAY=m
+CONFIG_DRM_KOMEDA=m
 CONFIG_DRM_NOUVEAU=m
 CONFIG_DRM_EXYNOS=m
 CONFIG_DRM_EXYNOS5433_DECON=y
-- 
2.25.1



From maz at kernel.org  Fri Jan 28 02:12:45 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 10:12:45 +0000
Subject: [GIT PULL] KVM/arm64 fixes for 5.17, take #1
Message-ID: <20220128101245.506715-1-maz@kernel.org>

Paolo,

Here's a small set of fixes for 5.17. Nothing stands out, just the
usual set of bug fixes. There will be another series next week, but
these patches need a bit of soak time.

Please pull,

	M.

The following changes since commit 1c53a1ae36120997a82f936d044c71075852e521:

  Merge branch kvm-arm64/misc-5.17 into kvmarm-master/next (2022-01-04 17:16:15 +0000)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-5.17-1

for you to fetch changes up to 278583055a237270fac70518275ba877bf9e4013:

  KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions on !VHE (2022-01-24 09:39:03 +0000)

----------------------------------------------------------------
KVM/arm64 fixes for 5.17, take #1

- Correctly update the shadow register on exception injection when
  running in nVHE mode

- Correctly use the mm_ops indirection when performing cache invalidation
  from the page-table walker

- Restrict the vgic-v3 workaround for SEIS to the two known broken
  implementations

----------------------------------------------------------------
Marc Zyngier (3):
      KVM: arm64: pkvm: Use the mm_ops indirection for cache maintenance
      KVM: arm64: vgic-v3: Restrict SEIS workaround to known broken systems
      KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions on !VHE

 arch/arm64/kvm/hyp/exception.c  |  5 ++++-
 arch/arm64/kvm/hyp/pgtable.c    | 18 ++++++------------
 arch/arm64/kvm/hyp/vgic-v3-sr.c |  3 +++
 arch/arm64/kvm/vgic/vgic-v3.c   | 17 +++++++++++++++--
 4 files changed, 28 insertions(+), 15 deletions(-)


From hverkuil at xs4all.nl  Fri Jan 28 02:13:09 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 28 Jan 2022 11:13:09 +0100
Subject: [PATCH] media: s5p-mfc: set V4L2_BUF_FLAG_LAST flag on final
 buffer
In-Reply-To: <20200502194052.485-1-andriy.gelman@gmail.com>
References: <20200502194052.485-1-andriy.gelman@gmail.com>
Message-ID: <040ba85c-6cdd-8053-30ed-194548d23a18@xs4all.nl>

Hi all,

I'm going through a bunch of (very) old patches in my patchwork TODO list
that for one reason or another I never processed. This patch is one of
them.

I don't feel comfortable merging this, given the follow-ups that were posted.

If someone wants to get this in anyway, then please make a new patch. I'm
marking it as 'Changes Requested' in patchwork.

Regards,

	Hans

On 02/05/2020 21:40, Andriy Gelman wrote:
> From: Andriy Gelman <andriy.gelman at gmail.com>
> 
> As per V4L2 api, the final buffer should set V4L2_BUF_FLAG_LAST flag.
> 
> Signed-off-by: Andriy Gelman <andriy.gelman at gmail.com>
> ---
>  drivers/media/platform/s5p-mfc/s5p_mfc.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> index 5c2a23b953a4..b3d9b3a523fe 100644
> --- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
> +++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
> @@ -614,6 +614,7 @@ static void s5p_mfc_handle_stream_complete(struct s5p_mfc_ctx *ctx)
>  		list_del(&mb_entry->list);
>  		ctx->dst_queue_cnt--;
>  		vb2_set_plane_payload(&mb_entry->b->vb2_buf, 0, 0);
> +		mb_entry->b->flags |= V4L2_BUF_FLAG_LAST;
>  		vb2_buffer_done(&mb_entry->b->vb2_buf, VB2_BUF_STATE_DONE);
>  	}
>  



From gregkh at linuxfoundation.org  Fri Jan 28 02:16:20 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 28 Jan 2022 11:16:20 +0100
Subject: [PATCH] clk: imx: Fix a NULL pointer dereference in
 imx_register_uart_clocks()
In-Reply-To: <20220124165206.55059-1-zhou1615@umn.edu>
References: <20220124165206.55059-1-zhou1615@umn.edu>
Message-ID: <YfPCdPuoB3RYgzL8@kroah.com>

On Tue, Jan 25, 2022 at 12:52:06AM +0800, Zhou Qingyang wrote:
> In imx_register_uart_clocks(), the global variable imx_uart_clocks is
> assigned by kcalloc() and there is a dereference of in the next for loop,
> which could introduce a NULL pointer dereference on failure of kcalloc().
> 
> Fix this by adding a NULL check of imx_uart_clocks.
> 
> This bug was found by a static analyzer.
> 
> Builds with 'make allyesconfig' show no new warnings,
> and our static analyzer no longer warns about this code.
> 
> Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
> Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> ---
> The analysis employs differential checking to identify inconsistent 
> security operations (e.g., checks or kfrees) between two code paths 
> and confirms that the inconsistent operations are not recovered in the
> current function or the callers, so they constitute bugs. 
> 
> Note that, as a bug found by static analysis, it can be a false
> positive or hard to trigger. Multiple researchers have cross-reviewed
> the bug.
> 
>  drivers/clk/imx/clk.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
> index 7cc669934253..99249ab361d2 100644
> --- a/drivers/clk/imx/clk.c
> +++ b/drivers/clk/imx/clk.c
> @@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
>  		int i;
>  
>  		imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
> +		if (!imx_uart_clocks)
> +			return;
>  
>  		if (!of_stdout)
>  			return;
> -- 
> 2.25.1
> 

As stated before, umn.edu is still not allowed to contribute to the
Linux kernel.  Please work with your administration to resolve this
issue.



From mark.rutland at arm.com  Fri Jan 28 02:16:49 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 10:16:49 +0000
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <20220121135632.136976-3-houtao1@huawei.com>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com>
Message-ID: <YfPCkUW4XIHGTZ6z@FVFF77S0Q05N>

On Fri, Jan 21, 2022 at 09:56:32PM +0800, Hou Tao wrote:
> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
> it only add support for x86-64, so support these atomic operations
> for arm64 as well.

What ordering semantics are the BPF atomics supposed to have?

e.g. are those meant to be sequentially consistent, entirely relaxed, or
somewhere imbetween?

> Basically the implementation procedure is almost mechanical translation
> of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
> under arch/arm64/include/asm. An extra temporary register is needed
> for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
> adding TMP_REG_4 just use BPF_REG_AX instead.
> 
> For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
> both ./test_verifier and "./test_progs -t atomic" are exercised and
> passed correspondingly.
> 
> Signed-off-by: Hou Tao <houtao1 at huawei.com>
> ---
>  arch/arm64/include/asm/insn.h |  45 +++++--
>  arch/arm64/lib/insn.c         | 155 +++++++++++++++++++++---

Could we please split the arm64 insn bits into a preparatory patch?

That way it's easier for folk familiar with the A64 ISA to review that in
isolation from the BPF bis which they might know nothign about.

>  arch/arm64/net/bpf_jit.h      |  43 ++++++-
>  arch/arm64/net/bpf_jit_comp.c | 216 +++++++++++++++++++++++++++-------
>  4 files changed, 394 insertions(+), 65 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h
> index 6b776c8667b2..1416d636f1af 100644
> --- a/arch/arm64/include/asm/insn.h
> +++ b/arch/arm64/include/asm/insn.h
> @@ -280,6 +280,23 @@ enum aarch64_insn_adr_type {
>  	AARCH64_INSN_ADR_TYPE_ADR,
>  };
>  
> +enum aarch64_insn_mem_atomic_op {
> +	AARCH64_INSN_MEM_ATOMIC_ADD,
> +	AARCH64_INSN_MEM_ATOMIC_BIC,
> +	AARCH64_INSN_MEM_ATOMIC_EOR,
> +	AARCH64_INSN_MEM_ATOMIC_ORR,
> +	AARCH64_INSN_MEM_ATOMIC_SWP,
> +};

Is "BIC" the "CLR" instructions, and "ORR" the "SET" instructions?

I think it'd be best to use the "SET" and "CLR" naming here for consistency
with the actual instruction names.

> +
> +enum aarch64_insn_mem_order_type {
> +	AARCH64_INSN_MEM_ORDER_NONE,
> +	AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL,
> +};

I think this is an over-simplification. There are instructions with all
combinations of acquire+release, e.g.

     |       REL        |
     | N      |  Y      |
-----+--------+---------|
A  N | LDCLR  | LCDLRL  |
C  --+--------+---------|
Q  Y | LDCLRA | LDCLRAL |
------------------------'

... so I reckon we need:

enum aarch64_insn_mem_order_type {
	AARCH64_INSN_MEM_ORDER_NONE,
	AARCH64_INSN_MEM_ORDER_ACQ,
	AARCH64_INSN_MEM_ORDER_REL,
	AARCH64_INSN_MEM_ORDER_ACQREL
};

> +
> +enum aarch64_insn_mb_type {
> +	AARCH64_INSN_MB_ISH,
> +};

Similarly, I think we want to be able to encode the other cases here.

Thanks,
Mark.

> +
>  #define	__AARCH64_INSN_FUNCS(abbr, mask, val)				\
>  static __always_inline bool aarch64_insn_is_##abbr(u32 code)		\
>  {									\
> @@ -303,6 +320,11 @@ __AARCH64_INSN_FUNCS(store_post,	0x3FE00C00, 0x38000400)
>  __AARCH64_INSN_FUNCS(load_post,	0x3FE00C00, 0x38400400)
>  __AARCH64_INSN_FUNCS(str_reg,	0x3FE0EC00, 0x38206800)
>  __AARCH64_INSN_FUNCS(ldadd,	0x3F20FC00, 0x38200000)
> +__AARCH64_INSN_FUNCS(ldclr,	0x3F20FC00, 0x38201000)
> +__AARCH64_INSN_FUNCS(ldeor,	0x3F20FC00, 0x38202000)
> +__AARCH64_INSN_FUNCS(ldset,	0x3F20FC00, 0x38203000)
> +__AARCH64_INSN_FUNCS(swp,	0x3F20FC00, 0x38208000)
> +__AARCH64_INSN_FUNCS(cas,	0x3FA07C00, 0x08A07C00)
>  __AARCH64_INSN_FUNCS(ldr_reg,	0x3FE0EC00, 0x38606800)
>  __AARCH64_INSN_FUNCS(ldr_lit,	0xBF000000, 0x18000000)
>  __AARCH64_INSN_FUNCS(ldrsw_lit,	0xFF000000, 0x98000000)
> @@ -474,13 +496,21 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
>  				   enum aarch64_insn_register state,
>  				   enum aarch64_insn_size_type size,
>  				   enum aarch64_insn_ldst_type type);
> -u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
> -			   enum aarch64_insn_register address,
> -			   enum aarch64_insn_register value,
> -			   enum aarch64_insn_size_type size);
> -u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
> -			   enum aarch64_insn_register value,
> -			   enum aarch64_insn_size_type size);
> +u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
> +				      enum aarch64_insn_register base,
> +				      enum aarch64_insn_register state,
> +				      enum aarch64_insn_size_type size);
> +u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
> +				  enum aarch64_insn_register address,
> +				  enum aarch64_insn_register value,
> +				  enum aarch64_insn_size_type size,
> +				  enum aarch64_insn_mem_atomic_op op,
> +				  enum aarch64_insn_mem_order_type order);
> +u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
> +			 enum aarch64_insn_register address,
> +			 enum aarch64_insn_register value,
> +			 enum aarch64_insn_size_type size,
> +			 enum aarch64_insn_mem_order_type order);
>  u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
>  				 enum aarch64_insn_register src,
>  				 int imm, enum aarch64_insn_variant variant,
> @@ -541,6 +571,7 @@ u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
>  			      enum aarch64_insn_prfm_type type,
>  			      enum aarch64_insn_prfm_target target,
>  			      enum aarch64_insn_prfm_policy policy);
> +u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type);
>  s32 aarch64_get_branch_offset(u32 insn);
>  u32 aarch64_set_branch_offset(u32 insn, s32 offset);
>  
> diff --git a/arch/arm64/lib/insn.c b/arch/arm64/lib/insn.c
> index fccfe363e567..2a7dde58c44b 100644
> --- a/arch/arm64/lib/insn.c
> +++ b/arch/arm64/lib/insn.c
> @@ -328,6 +328,29 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
>  	return insn;
>  }
>  
> +static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
> +					  u32 insn)
> +{
> +	u32 order;
> +
> +	switch (type) {
> +	case AARCH64_INSN_MEM_ORDER_NONE:
> +		order = 0;
> +		break;
> +	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
> +		order = 3;
> +		break;
> +	default:
> +		pr_err("%s: unknown mem order %d\n", __func__, type);
> +		return AARCH64_BREAK_FAULT;
> +	}
> +
> +	insn &= ~GENMASK(23, 22);
> +	insn |= order << 22;
> +
> +	return insn;
> +}
> +
>  static inline long branch_imm_common(unsigned long pc, unsigned long addr,
>  				     long range)
>  {
> @@ -603,12 +626,49 @@ u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
>  					    state);
>  }
>  
> -u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
> -			   enum aarch64_insn_register address,
> -			   enum aarch64_insn_register value,
> -			   enum aarch64_insn_size_type size)
> +u32 aarch64_insn_gen_store_release_ex(enum aarch64_insn_register reg,
> +				      enum aarch64_insn_register base,
> +				      enum aarch64_insn_register state,
> +				      enum aarch64_insn_size_type size)
> +{
> +	u32 insn = aarch64_insn_gen_load_store_ex(reg, base, state, size,
> +						  AARCH64_INSN_LDST_STORE_EX);
> +
> +	if (insn == AARCH64_BREAK_FAULT)
> +		return insn;
> +
> +	return insn | BIT(15);
> +}
> +
> +u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
> +				  enum aarch64_insn_register address,
> +				  enum aarch64_insn_register value,
> +				  enum aarch64_insn_size_type size,
> +				  enum aarch64_insn_mem_atomic_op op,
> +				  enum aarch64_insn_mem_order_type order)
>  {
> -	u32 insn = aarch64_insn_get_ldadd_value();
> +	u32 insn;
> +
> +	switch (op) {
> +	case AARCH64_INSN_MEM_ATOMIC_ADD:
> +		insn = aarch64_insn_get_ldadd_value();
> +		break;
> +	case AARCH64_INSN_MEM_ATOMIC_BIC:
> +		insn = aarch64_insn_get_ldclr_value();
> +		break;
> +	case AARCH64_INSN_MEM_ATOMIC_EOR:
> +		insn = aarch64_insn_get_ldeor_value();
> +		break;
> +	case AARCH64_INSN_MEM_ATOMIC_ORR:
> +		insn = aarch64_insn_get_ldset_value();
> +		break;
> +	case AARCH64_INSN_MEM_ATOMIC_SWP:
> +		insn = aarch64_insn_get_swp_value();
> +		break;
> +	default:
> +		pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
> +		return AARCH64_BREAK_FAULT;
> +	}
>  
>  	switch (size) {
>  	case AARCH64_INSN_SIZE_32:
> @@ -621,6 +681,8 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
>  
>  	insn = aarch64_insn_encode_ldst_size(size, insn);
>  
> +	insn = aarch64_insn_encode_ldst_order(order, insn);
> +
>  	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
>  					    result);
>  
> @@ -631,16 +693,60 @@ u32 aarch64_insn_gen_ldadd(enum aarch64_insn_register result,
>  					    value);
>  }
>  
> -u32 aarch64_insn_gen_stadd(enum aarch64_insn_register address,
> -			   enum aarch64_insn_register value,
> -			   enum aarch64_insn_size_type size)
> +static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
> +					 u32 insn)
>  {
> -	/*
> -	 * STADD is simply encoded as an alias for LDADD with XZR as
> -	 * the destination register.
> -	 */
> -	return aarch64_insn_gen_ldadd(AARCH64_INSN_REG_ZR, address,
> -				      value, size);
> +	u32 order;
> +
> +	switch (type) {
> +	case AARCH64_INSN_MEM_ORDER_NONE:
> +		order = 0;
> +		break;
> +	case AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL:
> +		order = BIT(15) | BIT(22);
> +		break;
> +	default:
> +		pr_err("%s: unknown mem order %d\n", __func__, type);
> +		return AARCH64_BREAK_FAULT;
> +	}
> +
> +	insn &= ~(BIT(15) | BIT(22));
> +	insn |= order;
> +
> +	return insn;
> +}
> +
> +u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
> +			 enum aarch64_insn_register address,
> +			 enum aarch64_insn_register value,
> +			 enum aarch64_insn_size_type size,
> +			 enum aarch64_insn_mem_order_type order)
> +{
> +	u32 insn;
> +
> +	switch (size) {
> +	case AARCH64_INSN_SIZE_32:
> +	case AARCH64_INSN_SIZE_64:
> +		break;
> +	default:
> +		pr_err("%s: unimplemented size encoding %d\n", __func__, size);
> +		return AARCH64_BREAK_FAULT;
> +	}
> +
> +	insn = aarch64_insn_get_cas_value();
> +
> +	insn = aarch64_insn_encode_ldst_size(size, insn);
> +
> +	insn = aarch64_insn_encode_cas_order(order, insn);
> +
> +	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
> +					    result);
> +
> +	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
> +					    address);
> +
> +	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
> +					    value);
>  }
>  
>  static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
> @@ -1456,3 +1562,24 @@ u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
>  	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
>  	return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
>  }
> +
> +u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
> +{
> +	u32 opt;
> +	u32 insn;
> +
> +	switch (type) {
> +	case AARCH64_INSN_MB_ISH:
> +		opt = 0xb;
> +		break;
> +	default:
> +		pr_err("%s: unknown dmb type %d\n", __func__, type);
> +		return AARCH64_BREAK_FAULT;
> +	}
> +
> +	insn = aarch64_insn_get_dmb_value();
> +	insn &= ~GENMASK(11, 8);
> +	insn |= (opt << 8);
> +
> +	return insn;
> +}
> diff --git a/arch/arm64/net/bpf_jit.h b/arch/arm64/net/bpf_jit.h
> index cc0cf0f5c7c3..308f96587861 100644
> --- a/arch/arm64/net/bpf_jit.h
> +++ b/arch/arm64/net/bpf_jit.h
> @@ -88,10 +88,41 @@
>  /* [Rn] = Rt; (atomic) Rs = [state] */
>  #define A64_STXR(sf, Rt, Rn, Rs) \
>  	A64_LSX(sf, Rt, Rn, Rs, STORE_EX)
> +/* smp_mb(); [Rn] = Rt; (atomic) Rs = [state] */
> +#define A64_STLXR(sf, Rt, Rn, Rs) \
> +	aarch64_insn_gen_store_release_ex(Rt, Rn, Rs, A64_SIZE(sf))
>  
> -/* LSE atomics */
> -#define A64_STADD(sf, Rn, Rs) \
> -	aarch64_insn_gen_stadd(Rn, Rs, A64_SIZE(sf))
> +/*
> + * LSE atomics
> + *
> + * ST{ADD,CLR,SET,EOR} is simply encoded as an alias for
> + * LDD{ADD,CLR,SET,EOR} with XZR as the destination register.
> + */
> +#define A64_ST_OP(sf, Rn, Rs, op) \
> +	aarch64_insn_gen_atomic_ld_op(A64_ZR, Rn, Rs, \
> +		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
> +		AARCH64_INSN_MEM_ORDER_NONE)
> +/* [Rn] <op>= Rs */
> +#define A64_STADD(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ADD)
> +#define A64_STCLR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, BIC)
> +#define A64_STEOR(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, EOR)
> +#define A64_STSET(sf, Rn, Rs) A64_ST_OP(sf, Rn, Rs, ORR)
> +
> +#define A64_LD_OP_AL(sf, Rt, Rn, Rs, op) \
> +	aarch64_insn_gen_atomic_ld_op(Rt, Rn, Rs, \
> +		A64_SIZE(sf), AARCH64_INSN_MEM_ATOMIC_##op, \
> +		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
> +/* Rt = [Rn]; [Rn] <op>= Rs */
> +#define A64_LDADDAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ADD)
> +#define A64_LDCLRAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, BIC)
> +#define A64_LDEORAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, EOR)
> +#define A64_LDSETAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, ORR)
> +/* Rt = [Rn]; [Rn] = Rs */
> +#define A64_SWPAL(sf, Rt, Rn, Rs) A64_LD_OP_AL(sf, Rt, Rn, Rs, SWP)
> +/* Rs = CAS(Rn, Rs, Rt) */
> +#define A64_CASAL(sf, Rt, Rn, Rs) \
> +	aarch64_insn_gen_cas(Rt, Rn, Rs, A64_SIZE(sf), \
> +		AARCH64_INSN_MEM_ORDER_LOAD_ACQ_STORE_REL)
>  
>  /* Add/subtract (immediate) */
>  #define A64_ADDSUB_IMM(sf, Rd, Rn, imm12, type) \
> @@ -196,6 +227,9 @@
>  #define A64_ANDS(sf, Rd, Rn, Rm) A64_LOGIC_SREG(sf, Rd, Rn, Rm, AND_SETFLAGS)
>  /* Rn & Rm; set condition flags */
>  #define A64_TST(sf, Rn, Rm) A64_ANDS(sf, A64_ZR, Rn, Rm)
> +/* Rd = ~Rm (alias of ORN with A64_ZR as Rn) */
> +#define A64_MVN(sf, Rd, Rm)  \
> +	A64_LOGIC_SREG(sf, Rd, A64_ZR, Rm, ORN)
>  
>  /* Logical (immediate) */
>  #define A64_LOGIC_IMM(sf, Rd, Rn, imm, type) ({ \
> @@ -219,4 +253,7 @@
>  #define A64_BTI_J  A64_HINT(AARCH64_INSN_HINT_BTIJ)
>  #define A64_BTI_JC A64_HINT(AARCH64_INSN_HINT_BTIJC)
>  
> +/* DMB */
> +#define A64_DMB_ISH aarch64_insn_gen_dmb(AARCH64_INSN_MB_ISH)
> +
>  #endif /* _BPF_JIT_H */
> diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
> index 74f9a9b6a053..79e2c2c4c733 100644
> --- a/arch/arm64/net/bpf_jit_comp.c
> +++ b/arch/arm64/net/bpf_jit_comp.c
> @@ -27,6 +27,17 @@
>  #define TCALL_CNT (MAX_BPF_JIT_REG + 2)
>  #define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
>  
> +#define check_imm(bits, imm) do {				\
> +	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
> +	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
> +		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
> +			i, imm, imm);				\
> +		return -EINVAL;					\
> +	}							\
> +} while (0)
> +#define check_imm19(imm) check_imm(19, imm)
> +#define check_imm26(imm) check_imm(26, imm)
> +
>  /* Map BPF registers to A64 registers */
>  static const int bpf2a64[] = {
>  	/* return value from in-kernel function, and exit value from eBPF */
> @@ -329,6 +340,163 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx)
>  #undef jmp_offset
>  }
>  
> +static int emit_lse_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
> +{
> +	const u8 code = insn->code;
> +	const u8 dst = bpf2a64[insn->dst_reg];
> +	const u8 src = bpf2a64[insn->src_reg];
> +	const u8 tmp = bpf2a64[TMP_REG_1];
> +	const u8 tmp2 = bpf2a64[TMP_REG_2];
> +	const bool isdw = BPF_SIZE(code) == BPF_DW;
> +	const s16 off = insn->off;
> +	u8 reg;
> +
> +	if (!off) {
> +		reg = dst;
> +	} else {
> +		emit_a64_mov_i(1, tmp, off, ctx);
> +		emit(A64_ADD(1, tmp, tmp, dst), ctx);
> +		reg = tmp;
> +	}
> +
> +	switch (insn->imm) {
> +	/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
> +	case BPF_ADD:
> +		emit(A64_STADD(isdw, reg, src), ctx);
> +		break;
> +	case BPF_AND:
> +		emit(A64_MVN(isdw, tmp2, src), ctx);
> +		emit(A64_STCLR(isdw, reg, tmp2), ctx);
> +		break;
> +	case BPF_OR:
> +		emit(A64_STSET(isdw, reg, src), ctx);
> +		break;
> +	case BPF_XOR:
> +		emit(A64_STEOR(isdw, reg, src), ctx);
> +		break;
> +	/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
> +	case BPF_ADD | BPF_FETCH:
> +		emit(A64_LDADDAL(isdw, src, reg, src), ctx);
> +		break;
> +	case BPF_AND | BPF_FETCH:
> +		emit(A64_MVN(isdw, tmp2, src), ctx);
> +		emit(A64_LDCLRAL(isdw, src, reg, tmp2), ctx);
> +		break;
> +	case BPF_OR | BPF_FETCH:
> +		emit(A64_LDSETAL(isdw, src, reg, src), ctx);
> +		break;
> +	case BPF_XOR | BPF_FETCH:
> +		emit(A64_LDEORAL(isdw, src, reg, src), ctx);
> +		break;
> +	/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
> +	case BPF_XCHG:
> +		emit(A64_SWPAL(isdw, src, reg, src), ctx);
> +		break;
> +	/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
> +	case BPF_CMPXCHG:
> +		emit(A64_CASAL(isdw, src, reg, bpf2a64[BPF_REG_0]), ctx);
> +		break;
> +	default:
> +		pr_err_once("unknown atomic op code %02x\n", insn->imm);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int emit_ll_sc_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
> +{
> +	const u8 code = insn->code;
> +	const u8 dst = bpf2a64[insn->dst_reg];
> +	const u8 src = bpf2a64[insn->src_reg];
> +	const u8 tmp = bpf2a64[TMP_REG_1];
> +	const u8 tmp2 = bpf2a64[TMP_REG_2];
> +	const u8 tmp3 = bpf2a64[TMP_REG_3];
> +	const int i = insn - ctx->prog->insnsi;
> +	const s32 imm = insn->imm;
> +	const s16 off = insn->off;
> +	const bool isdw = BPF_SIZE(code) == BPF_DW;
> +	u8 reg;
> +	s32 jmp_offset;
> +
> +	if (!off) {
> +		reg = dst;
> +	} else {
> +		emit_a64_mov_i(1, tmp, off, ctx);
> +		emit(A64_ADD(1, tmp, tmp, dst), ctx);
> +		reg = tmp;
> +	}
> +
> +	if (imm == BPF_ADD || imm == BPF_AND ||
> +	    imm == BPF_OR || imm == BPF_XOR) {
> +		/* lock *(u32/u64 *)(dst_reg + off) <op>= src_reg */
> +		emit(A64_LDXR(isdw, tmp2, reg), ctx);
> +		if (imm == BPF_ADD)
> +			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
> +		else if (imm == BPF_AND)
> +			emit(A64_AND(isdw, tmp2, tmp2, src), ctx);
> +		else if (imm == BPF_OR)
> +			emit(A64_ORR(isdw, tmp2, tmp2, src), ctx);
> +		else
> +			emit(A64_EOR(isdw, tmp2, tmp2, src), ctx);
> +		emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
> +		jmp_offset = -3;
> +		check_imm19(jmp_offset);
> +		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
> +	} else if (imm == (BPF_ADD | BPF_FETCH) ||
> +		   imm == (BPF_AND | BPF_FETCH) ||
> +		   imm == (BPF_OR | BPF_FETCH) ||
> +		   imm == (BPF_XOR | BPF_FETCH)) {
> +		/* src_reg = atomic_fetch_add(dst_reg + off, src_reg) */
> +		const u8 ax = bpf2a64[BPF_REG_AX];
> +
> +		emit(A64_MOV(isdw, ax, src), ctx);
> +		emit(A64_LDXR(isdw, src, reg), ctx);
> +		if (imm == (BPF_ADD | BPF_FETCH))
> +			emit(A64_ADD(isdw, tmp2, src, ax), ctx);
> +		else if (imm == (BPF_AND | BPF_FETCH))
> +			emit(A64_AND(isdw, tmp2, src, ax), ctx);
> +		else if (imm == (BPF_OR | BPF_FETCH))
> +			emit(A64_ORR(isdw, tmp2, src, ax), ctx);
> +		else
> +			emit(A64_EOR(isdw, tmp2, src, ax), ctx);
> +		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
> +		jmp_offset = -3;
> +		check_imm19(jmp_offset);
> +		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
> +		emit(A64_DMB_ISH, ctx);
> +	} else if (imm == BPF_XCHG) {
> +		/* src_reg = atomic_xchg(dst_reg + off, src_reg); */
> +		emit(A64_MOV(isdw, tmp2, src), ctx);
> +		emit(A64_LDXR(isdw, src, reg), ctx);
> +		emit(A64_STLXR(isdw, tmp2, reg, tmp3), ctx);
> +		jmp_offset = -2;
> +		check_imm19(jmp_offset);
> +		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
> +		emit(A64_DMB_ISH, ctx);
> +	} else if (imm == BPF_CMPXCHG) {
> +		/* r0 = atomic_cmpxchg(dst_reg + off, r0, src_reg); */
> +		const u8 r0 = bpf2a64[BPF_REG_0];
> +
> +		emit(A64_MOV(isdw, tmp2, r0), ctx);
> +		emit(A64_LDXR(isdw, r0, reg), ctx);
> +		emit(A64_EOR(isdw, tmp3, r0, tmp2), ctx);
> +		jmp_offset = 4;
> +		check_imm19(jmp_offset);
> +		emit(A64_CBNZ(isdw, tmp3, jmp_offset), ctx);
> +		emit(A64_STLXR(isdw, src, reg, tmp3), ctx);
> +		jmp_offset = -4;
> +		check_imm19(jmp_offset);
> +		emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
> +		emit(A64_DMB_ISH, ctx);
> +	} else {
> +		pr_err_once("unknown atomic op code %02x\n", imm);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
>  static void build_epilogue(struct jit_ctx *ctx)
>  {
>  	const u8 r0 = bpf2a64[BPF_REG_0];
> @@ -434,29 +602,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
>  	const u8 src = bpf2a64[insn->src_reg];
>  	const u8 tmp = bpf2a64[TMP_REG_1];
>  	const u8 tmp2 = bpf2a64[TMP_REG_2];
> -	const u8 tmp3 = bpf2a64[TMP_REG_3];
>  	const s16 off = insn->off;
>  	const s32 imm = insn->imm;
>  	const int i = insn - ctx->prog->insnsi;
>  	const bool is64 = BPF_CLASS(code) == BPF_ALU64 ||
>  			  BPF_CLASS(code) == BPF_JMP;
> -	const bool isdw = BPF_SIZE(code) == BPF_DW;
> -	u8 jmp_cond, reg;
> +	u8 jmp_cond;
>  	s32 jmp_offset;
>  	u32 a64_insn;
>  	int ret;
>  
> -#define check_imm(bits, imm) do {				\
> -	if ((((imm) > 0) && ((imm) >> (bits))) ||		\
> -	    (((imm) < 0) && (~(imm) >> (bits)))) {		\
> -		pr_info("[%2d] imm=%d(0x%x) out of range\n",	\
> -			i, imm, imm);				\
> -		return -EINVAL;					\
> -	}							\
> -} while (0)
> -#define check_imm19(imm) check_imm(19, imm)
> -#define check_imm26(imm) check_imm(26, imm)
> -
>  	switch (code) {
>  	/* dst = src */
>  	case BPF_ALU | BPF_MOV | BPF_X:
> @@ -891,33 +1046,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx,
>  
>  	case BPF_STX | BPF_ATOMIC | BPF_W:
>  	case BPF_STX | BPF_ATOMIC | BPF_DW:
> -		if (insn->imm != BPF_ADD) {
> -			pr_err_once("unknown atomic op code %02x\n", insn->imm);
> -			return -EINVAL;
> -		}
> -
> -		/* STX XADD: lock *(u32 *)(dst + off) += src
> -		 * and
> -		 * STX XADD: lock *(u64 *)(dst + off) += src
> -		 */
> -
> -		if (!off) {
> -			reg = dst;
> -		} else {
> -			emit_a64_mov_i(1, tmp, off, ctx);
> -			emit(A64_ADD(1, tmp, tmp, dst), ctx);
> -			reg = tmp;
> -		}
> -		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS)) {
> -			emit(A64_STADD(isdw, reg, src), ctx);
> -		} else {
> -			emit(A64_LDXR(isdw, tmp2, reg), ctx);
> -			emit(A64_ADD(isdw, tmp2, tmp2, src), ctx);
> -			emit(A64_STXR(isdw, tmp2, reg, tmp3), ctx);
> -			jmp_offset = -3;
> -			check_imm19(jmp_offset);
> -			emit(A64_CBNZ(0, tmp3, jmp_offset), ctx);
> -		}
> +		if (cpus_have_cap(ARM64_HAS_LSE_ATOMICS))
> +			ret = emit_lse_atomic(insn, ctx);
> +		else
> +			ret = emit_ll_sc_atomic(insn, ctx);
> +		if (ret)
> +			return ret;
>  		break;
>  
>  	default:
> -- 
> 2.27.0
> 
> 


From gregkh at linuxfoundation.org  Fri Jan 28 02:17:02 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 28 Jan 2022 11:17:02 +0100
Subject: [PATCH] media: mtk-vcodec: Fix a NULL pointer dereference in
 mtk_vcodec_fw_scp_init()
In-Reply-To: <20220124170731.59240-1-zhou1615@umn.edu>
References: <20220124170731.59240-1-zhou1615@umn.edu>
Message-ID: <YfPCnsZ1Vce3fJ1u@kroah.com>

On Tue, Jan 25, 2022 at 01:07:31AM +0800, Zhou Qingyang wrote:
> In mtk_vcodec_fw_scp_init(), devm_kzalloc() is assigned to fw and there is
> a dereference of it right after that, which could lead to NULL pointer
> dereference on failure of devm_kzalloc().
> 
> Fix this bug by adding a NULL check of fw.
> 
> This bug was found by a static analyzer.
> 
> Builds with 'make allyesconfig' show no new warnings,
> and our static analyzer no longer warns about this code.
> 
> Fixes: 46233e91fa24 ("media: mtk-vcodec: move firmware implementations into their own files")
> Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> ---
> The analysis employs differential checking to identify inconsistent 
> security operations (e.g., checks or kfrees) between two code paths 
> and confirms that the inconsistent operations are not recovered in the
> current function or the callers, so they constitute bugs. 
> 
> Note that, as a bug found by static analysis, it can be a false
> positive or hard to trigger. Multiple researchers have cross-reviewed
> the bug.
> 
>  drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
> index d8e66b645bd8..aa36bee51d01 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_scp.c
> @@ -65,6 +65,9 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_scp_init(struct mtk_vcodec_dev *dev)
>  	}
>  
>  	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
> +	if (!fw)
> +		return ERR_PTR(-ENOMEM);
> +
>  	fw->type = SCP;
>  	fw->ops = &mtk_vcodec_rproc_msg;
>  	fw->scp = scp;
> -- 
> 2.25.1
> 

As stated before, umn.edu is still not allowed to contribute to the
Linux kernel.  Please work with your administration to resolve this
issue.



From gregkh at linuxfoundation.org  Fri Jan 28 02:17:18 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 28 Jan 2022 11:17:18 +0100
Subject: [PATCH] media: mtk-vcodec: media: mtk-vcodec: Fix a NULL pointer
 dereference in mtk_vcodec_fw_vpu_init()
In-Reply-To: <20220124171503.61098-1-zhou1615@umn.edu>
References: <20220124171503.61098-1-zhou1615@umn.edu>
Message-ID: <YfPCrjuXhRYEKOFC@kroah.com>

On Tue, Jan 25, 2022 at 01:15:03AM +0800, Zhou Qingyang wrote:
> In mtk_vcodec_fw_vpu_init(), devm_kzalloc() is assigned to fw and there is
> a dereference of it right after that, which could lead to NULL pointer
> dereference on failure of devm_kzalloc().
> 
> Fix this bug by adding a NULL check of fw.
> 
> This bug was found by a static analyzer.
> 
> Builds with 'make allyesconfig' show no new warnings,
> and our static analyzer no longer warns about this code.
> 
> Fixes: 46233e91fa24 ("media: mtk-vcodec: move firmware implementations into their own files")
> Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> ---
> The analysis employs differential checking to identify inconsistent 
> security operations (e.g., checks or kfrees) between two code paths 
> and confirms that the inconsistent operations are not recovered in the
> current function or the callers, so they constitute bugs. 
> 
> Note that, as a bug found by static analysis, it can be a false
> positive or hard to trigger. Multiple researchers have cross-reviewed
> the bug.
> 
>  drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
> index cd27f637dbe7..33ae88a9f9da 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_fw_vpu.c
> @@ -102,6 +102,9 @@ struct mtk_vcodec_fw *mtk_vcodec_fw_vpu_init(struct mtk_vcodec_dev *dev,
>  	vpu_wdt_reg_handler(fw_pdev, mtk_vcodec_vpu_reset_handler, dev, rst_id);
>  
>  	fw = devm_kzalloc(&dev->plat_dev->dev, sizeof(*fw), GFP_KERNEL);
> +	if (!fw)
> +		return ERR_PTR(-ENOMEM);
> +
>  	fw->type = VPU;
>  	fw->ops = &mtk_vcodec_vpu_msg;
>  	fw->pdev = fw_pdev;
> -- 
> 2.25.1
> 

As stated before, umn.edu is still not allowed to contribute to the
Linux kernel.  Please work with your administration to resolve this
issue.



From alexander.stein at ew.tq-group.com  Fri Jan 28 02:18:04 2022
From: alexander.stein at ew.tq-group.com (Alexander Stein)
Date: Fri, 28 Jan 2022 11:18:04 +0100
Subject: (EXT) RE: [RFC PATCH] PCI: imx6: Handle the abort from user-space
In-Reply-To: <AS8PR04MB8676E90C0A394C82BB0A890B8C229@AS8PR04MB8676.eurprd04.prod.outlook.com>
References: <20220128082920.591115-1-francesco.dolcini@toradex.com>
 <AS8PR04MB8676E90C0A394C82BB0A890B8C229@AS8PR04MB8676.eurprd04.prod.outlook.com>
Message-ID: <4621593.CQOukoFCf9@steina-w>

Am Freitag, 28. Januar 2022, 10:25:11 CET schrieb Hongxing Zhu:
> > -----Original Message-----
> > From: Francesco Dolcini <francesco.dolcini at toradex.com>
> > Sent: 2022?1?28? 16:29
> > To: Hongxing Zhu <hongxing.zhu at nxp.com>; Lucas Stach
> > <l.stach at pengutronix.de>; Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>;
> > Rob
 Herring <robh at kernel.org>; Krzysztof Wilczy?ski <kw at linux.com>;
> > Sascha Hauer <s.hauer at pengutronix.de>; Pengutronix Kernel Team
> > <kernel at pengutronix.de>; Fabio Estevam <festevam at gmail.com>;
> > dl-linux-imx <linux-imx at nxp.com>; Jason Liu <jason.hui.liu at nxp.com>
> > Cc: linux-pci at vger.kernel.org; linux-arm-kernel at lists.infradead.org;
> > linux-kernel at vger.kernel.org; Bjorn Helgaas <bhelgaas at google.com>; Shawn
> > Guo <shawnguo at kernel.org>; Francesco Dolcini
> > <francesco.dolcini at toradex.com>
> > Subject: [RFC PATCH] PCI: imx6: Handle the abort from user-space
> > 
> > From: Jason Liu <jason.hui.liu at nxp.com>
> > 
> > The driver install one hook to handle the external abort, but issue is
> > that if the
 abort introduced from user space code, the following code
> > unsigned long instr = *(unsigned long *)pc; which will created another
> > data-abort(page domain fault) if CONFIG_CPU_SW_DOMAIN_PAN.
> > 
> > The patch does not intent to use copy_from_user and then do the hack due
> > to
 the security consideration. In fact, we can just return and report
> > the external abort to user-space.
> > 
> > Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
> > Reviewed-by: Richard Zhu <hongxing.zhu at nxp.com>
> > Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
> > ---
> > We have this patch from NXP downstream kernel [1] in our kernel branch
> > [2]
> > since a long time, to me it would make sense to upstream it. Any concern?
> > 
> > [1]
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.
> > codeaurora.org%2Fexternal%2Fimxsupport%2Flinux-imx%2Fcommit%2F%3Fid
> > %3D62dfb2fb953463dd1b6710567c9e174672a98f24&amp;data=04%7C01%7
> > Chongxing.zhu%40nxp.com%7Ccbe193ab4c3e4ad11bcb08d9e2384a1f%7C68
> > 6ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637789553659549198%7
> > CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBT
> > iI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=Mwhx8DFF7EDJdpqTsHT
> > %2BBAGzhQadDOqcgJnVjeoi1yk%3D&amp;reserved=0
> > [2]
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit.tora
> > 
> > dex.com%2Fcgit%2Flinux-toradex.git%2Fcommit%2F%3Fid%3D2b42547cf659f
> > 979be2defdff6a99f921b33d0f1&amp;data=04%7C01%7Chongxing.zhu%40nx
> > p.com%7Ccbe193ab4c3e4ad11bcb08d9e2384a1f%7C686ea1d3bc2b4c6fa92c
> > d99c5c301635%7C0%7C0%7C637789553659549198%7CUnknown%7CTWFp
> > bGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI
> > 6Mn0%3D%7C3000&amp;sdata=QEW1frh8WacCzniWo4ng1cy3Z1UZ9uMRFw
> > GBKuIh7zE%3D&amp;reserved=0
> > ---
> > 
> >  drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> > 
> > 
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index 6974bd5aa116..6b178a29e253 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -27,6 +27,7 @@
> > 
> >  #include <linux/resource.h>
> >  #include <linux/signal.h>
> >  #include <linux/types.h>
> > 
> > +#include <linux/uaccess.h>
> 
> 
> [Richard Zhu] Thanks for your kindly help.
> This header include is not required actually, please remove it.

It should be <linux/ptrace.h> instead, for using user_mode().
Best regards,
Alexander


> >  #include <linux/interrupt.h>
> >  #include <linux/reset.h>
> >  #include <linux/phy/phy.h>
> > 
> > @@ -297,8 +298,15 @@ static int imx6q_pcie_abort_handler(unsigned long
> > addr,
> > 
> >  		unsigned int fsr, struct pt_regs *regs)  {
> >  	
> >  	unsigned long pc = instruction_pointer(regs);
> > 
> > -	unsigned long instr = *(unsigned long *)pc;
> > -	int reg = (instr >> 12) & 15;
> > +	unsigned long instr;
> > +	int reg;
> > +
> > +	/* if the abort from user-space, just return and report it */
> > +	if (user_mode(regs))
> > +		return 1;
> > +
> > +	instr = *(unsigned long *)pc;
> > +	reg = (instr >> 12) & 15;
> > 
> > 
> >  	/*
> >  	
> >  	 * If the instruction being executed was a read,
> > 
> > --
> > 2.25.1
> 
> 






From heiko at sntech.de  Fri Jan 28 02:19:22 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 28 Jan 2022 11:19:22 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <20220125171809.1273269-6-daniel.lezcano@linaro.org>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
Message-ID: <48865702.Mx8J7aE1p6@diego>

Am Dienstag, 25. Januar 2022, 18:18:09 CET schrieb Daniel Lezcano:
> The DTPM framework does support now the hierarchy description.
> 
> The platform specific code can call the hierarchy creation function
> with an array of struct dtpm_node pointing to their parent.
> 
> This patch provides a description of the big / Little CPUs and the
> GPU and tie them together under a virtual 'package' name. Only rk3399 is
> described now.
> 
> The description could be extended in the future with the memory
> controller with devfreq.
> 
> The description is always a module and it describes the soft
> dependencies. The userspace has to load the softdeps module in the
> right order.
> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
> ---
>  drivers/soc/rockchip/Kconfig  |  8 +++++
>  drivers/soc/rockchip/Makefile |  1 +
>  drivers/soc/rockchip/dtpm.c   | 59 +++++++++++++++++++++++++++++++++++
>  3 files changed, 68 insertions(+)
>  create mode 100644 drivers/soc/rockchip/dtpm.c
> 
> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
> index 25eb2c1e31bb..6dc017f02431 100644
> --- a/drivers/soc/rockchip/Kconfig
> +++ b/drivers/soc/rockchip/Kconfig
> @@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS
>  
>            If unsure, say N.
>  
> +config ROCKCHIP_DTPM
> +	tristate "Rockchip DTPM hierarchy"
> +	depends on DTPM && DRM_PANFROST && m
> +	help
> +	 Describe the hierarchy for the Dynamic Thermal Power
> +	 Management tree on this platform. That will create all the
> +	 power capping capable devices.
> +
>  endif
> diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
> index 875032f7344e..05f31a4e743c 100644
> --- a/drivers/soc/rockchip/Makefile
> +++ b/drivers/soc/rockchip/Makefile
> @@ -5,3 +5,4 @@
>  obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
>  obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
>  obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
> +obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
> diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
> new file mode 100644
> index 000000000000..0b73a9cba954
> --- /dev/null
> +++ b/drivers/soc/rockchip/dtpm.c
> @@ -0,0 +1,59 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright 2021 Linaro Limited
> + *
> + * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
> + *
> + * DTPM hierarchy description
> + */
> +#include <linux/dtpm.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/platform_device.h>
> +
> +static struct dtpm_node __initdata rk3399_hierarchy[] = {

The driver is tristate so buildable as module but uses __initdata.
As it depends on panfrost (which also can be a module) you
probably want a "__initdata_or_module" here .


> +	[0]{ .name = "rk3399",
> +	     .type = DTPM_NODE_VIRTUAL },
> +	[1]{ .name = "package",
> +	     .type = DTPM_NODE_VIRTUAL,
> +	     .parent = &rk3399_hierarchy[0] },
> +	[2]{ .name = "/cpus/cpu at 0",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[3]{ .name = "/cpus/cpu at 1",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[4]{ .name = "/cpus/cpu at 2",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[5]{ .name = "/cpus/cpu at 3",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[6]{ .name = "/cpus/cpu at 100",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[7]{ .name = "/cpus/cpu at 101",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[8]{ .name = "/gpu at ff9a0000",
> +	     .type = DTPM_NODE_DT,
> +	     .parent = &rk3399_hierarchy[1] },
> +	[9]{ },

hmm, do we want a "/* sentinel */" inside the empty last entry?
I think that is pretty common to denote the "this one is the last entry"
of a dynamic list ;-)

> +};
> +
> +static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
> +        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
> +        {},
> +};
> +
> +static int __init rockchip_dtpm_init(void)
> +{
> +	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
> +}
> +module_init(rockchip_dtpm_init);

Just for my understanding what happens on driver unload?


Thanks
Heiko

> +
> +MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
> +MODULE_DESCRIPTION("Rockchip DTPM driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:dtpm");
> +MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano at kernel.org");
> 






From Jonathan.Cameron at Huawei.com  Fri Jan 28 02:32:09 2022
From: Jonathan.Cameron at Huawei.com (Jonathan Cameron)
Date: Fri, 28 Jan 2022 10:32:09 +0000
Subject: [PATCH v3 0/7] Add basic node support for Mediatek MT8186 SoC
In-Reply-To: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128103209.00002704@Huawei.com>

On Fri, 28 Jan 2022 14:20:43 +0800
allen-kh.cheng <allen-kh.cheng at mediatek.com> wrote:

> From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> 
> MT8186 is a SoC based on 64bit ARMv8 architecture.
> It contains 6 CA55 and 2 CA78 cores.
> MT8186 share many HW IP with MT65xx series.
> 
> This patchset was tested on MT8186 evaluation board to shell.

Please prune your cc list for any future versions.
We all get enough emails as it is :)

I'm not seeing anything relevant to linux-iio in here for example.

Thanks,

Jonathan

> 
> Based on linux-next
> 
> changes since v2:$
>  - add soc {} in mt8186.dtsi
> 
> changes since v1:
>  - add dt-bindings: arm: Add compatible for Mediatek MT8186
> 
> 
> Allen-KH Cheng (7):
>   dt-bindings: timer: Add compatible for Mediatek MT8186
>   dt-bindings: serial: Add compatible for Mediatek MT8186
>   dt-bindings: watchdog: Add compatible for Mediatek MT8186
>   dt-bindings: mmc: Add compatible for Mediatek MT8186
>   dt-bindings: phy: Add compatible for Mediatek MT8186
>   dt-bindings: arm: Add compatible for Mediatek MT8186
>   arm64: dts: Add Mediatek SoC MT8186 dts and evaluation board and
>     Makefile
> 
>  .../devicetree/bindings/arm/mediatek.yaml     |   4 +
>  .../devicetree/bindings/mmc/mtk-sd.yaml       |   3 +
>  .../bindings/phy/mediatek,tphy.yaml           |   1 +
>  .../devicetree/bindings/serial/mtk-uart.txt   |   1 +
>  .../bindings/timer/mediatek,mtk-timer.txt     |   1 +
>  .../devicetree/bindings/watchdog/mtk-wdt.txt  |   1 +
>  arch/arm64/boot/dts/mediatek/Makefile         |   1 +
>  arch/arm64/boot/dts/mediatek/mt8186-evb.dts   |  24 ++
>  arch/arm64/boot/dts/mediatek/mt8186.dtsi      | 360 ++++++++++++++++++
>  9 files changed, 396 insertions(+)
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
>  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi
> 



From wsa at kernel.org  Fri Jan 28 02:37:31 2022
From: wsa at kernel.org (Wolfram Sang)
Date: Fri, 28 Jan 2022 11:37:31 +0100
Subject: [PATCH] i2c: bcm2835: Set clock-stretch timeout to 35ms
In-Reply-To: <20220117102504.90585-1-iivanov@suse.de>
References: <20220117102504.90585-1-iivanov@suse.de>
Message-ID: <YfPHawUXJRPDHPmM@shikoro>

Hi Ivan,

> The BCM2835 I2C blocks have a register to set the clock-stretch
> timeout - how long the device is allowed to hold SCL low - in bus
> cycles. The current driver doesn't write to the register, therefore
> the default value of 64 cycles is being used for all devices.
> 
> Set the timeout to the value recommended for SMBus - 35ms.

By default, busses are I2C and not SMBus, so it looks like we should
finally apply this patch which disables CLKT:

http://patchwork.ozlabs.org/project/linux-i2c/patch/1519422151-6218-1-git-send-email-stefan.wahren at i2se.com/

If you really want the SMBus timeout applied, you can check for a
"smbus" property in DT and then set CLKT accordingly in a seperate
patch.

Kind regards,

   Wolfram

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/229710c6/attachment.sig>

From catalin.marinas at arm.com  Fri Jan 28 02:51:42 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 10:51:42 +0000
Subject: [PATCH V3 RESEND 0/7] coresight: trbe: Workaround Cortex-A510
 erratas
In-Reply-To: <20220127202220.GA2191206@p14s>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
 <20220127202220.GA2191206@p14s>
Message-ID: <YfPKvsw+fOsJvSm7@arm.com>

Hi Mathieu,

On Thu, Jan 27, 2022 at 01:22:20PM -0700, Mathieu Poirier wrote:
> On Tue, Jan 25, 2022 at 07:50:30PM +0530, Anshuman Khandual wrote:
> > Anshuman Khandual (7):
> >   arm64: Add Cortex-A510 CPU part definition
> >   arm64: errata: Add detection for TRBE ignored system register writes
> >   arm64: errata: Add detection for TRBE invalid prohibited states
> >   arm64: errata: Add detection for TRBE trace data corruption
> >   coresight: trbe: Work around the ignored system register writes
> >   coresight: trbe: Work around the invalid prohibited states
> >   coresight: trbe: Work around the trace data corruption
> > 
> >  Documentation/arm64/silicon-errata.rst       |   6 +
> >  arch/arm64/Kconfig                           |  59 ++++++++++
> >  arch/arm64/include/asm/cputype.h             |   2 +
> >  arch/arm64/kernel/cpu_errata.c               |  27 +++++
> >  arch/arm64/tools/cpucaps                     |   3 +
> >  drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
> >  drivers/hwtracing/coresight/coresight-trbe.h |   8 --
> >  7 files changed, 183 insertions(+), 36 deletions(-)
> 
> I have applied this set and sent a pull request to Catalin for the arm64
> portion.

Well, I'm happy for the whole series to go in via Greg's tree or however
the coresight patches go in (that's why I acked them). The last three
patches depend on the first four, so you might as well send them all
together. I'd split the series only if there's a conflict with the arm64
tree (I haven't checked).

-- 
Catalin


From hverkuil at xs4all.nl  Fri Jan 28 02:57:00 2022
From: hverkuil at xs4all.nl (Hans Verkuil)
Date: Fri, 28 Jan 2022 11:57:00 +0100
Subject: [PATCHv3 4/4] media: imx: Use dedicated format handler for i.MX7/8
In-Reply-To: <20211019120047.827915-4-dorota.czaplejewicz@puri.sm>
References: <20211019120047.827915-1-dorota.czaplejewicz@puri.sm>
 <20211019120047.827915-4-dorota.czaplejewicz@puri.sm>
Message-ID: <3f5a10aa-fda8-ea3d-9ca2-eba77c720338@xs4all.nl>

Hi Dorota,

Since I marked "media: Add 16-bit Bayer formats" as 'Changes Requested', and since
this patch appears to depend on that patch based on a comment in the first patch,
I decided to mark this series as 'Changes Requested' (except for patch 1 which has
already been accepted).

Please post a v4 if you want this in, and add the "media: Add 16-bit Bayer formats"
patch as well to that v4 series.

Thanks!

	Hans

On 19/10/2021 14:14, Dorota Czaplejewicz wrote:
> This splits out a format handler which takes into account
> the capabilities of the i.MX7/8 video device,
> as opposed to the default handler compatible with both i.MX5/6 and i.MX7/8.
> 
> Signed-off-by: Dorota Czaplejewicz <dorota.czaplejewicz at puri.sm>
> ---
>  drivers/staging/media/imx/imx-media-utils.c | 56 +++++++++++++++++++--
>  1 file changed, 52 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/staging/media/imx/imx-media-utils.c b/drivers/staging/media/imx/imx-media-utils.c
> index 8b5c6bcfd4fa..1ff7ec4c877a 100644
> --- a/drivers/staging/media/imx/imx-media-utils.c
> +++ b/drivers/staging/media/imx/imx-media-utils.c
> @@ -516,10 +516,9 @@ void imx_media_try_colorimetry(struct v4l2_mbus_framefmt *tryfmt,
>  }
>  EXPORT_SYMBOL_GPL(imx_media_try_colorimetry);
>  
> -int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
> -				  const struct v4l2_mbus_framefmt *mbus,
> -				  const struct imx_media_pixfmt *cc,
> -				  enum imx_media_device_type type)
> +static int imx56_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
> +					   const struct v4l2_mbus_framefmt *mbus,
> +					   const struct imx_media_pixfmt *cc)
>  {
>  	u32 width;
>  	u32 stride;
> @@ -568,6 +567,55 @@ int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
>  
>  	return 0;
>  }
> +
> +static int imx78_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
> +					   const struct v4l2_mbus_framefmt *mbus,
> +					   const struct imx_media_pixfmt *cc)
> +{
> +	int ret;
> +
> +	if (!cc)
> +		cc = imx_media_find_mbus_format(mbus->code, PIXFMT_SEL_ANY);
> +
> +	/*
> +	 * The hardware can handle line lengths divisible by 4 pixels
> +	 * as long as the whole buffer size ends up divisible by 8 bytes.
> +	 * If not, use the value of 8 pixels recommended in the datasheet.
> +	 */
> +	ret = v4l2_fill_pixfmt(pix, cc->fourcc,
> +			       round_up(mbus->width, 4), mbus->height);
> +	if (ret)
> +		return ret;
> +
> +	/* Only 8bits-per-pixel formats may need to get aligned to 8 pixels,
> +	 * because both 10-bit and 16-bit pixels occupy 2 bytes.
> +	 * In those, 4-pixel aligmnent is equal to 8-byte alignment.
> +	 */
> +	if (pix->sizeimage % 8 != 0)
> +		ret = v4l2_fill_pixfmt(pix, cc->fourcc,
> +				       round_up(mbus->width, 8), mbus->height);
> +
> +	pix->colorspace = mbus->colorspace;
> +	pix->xfer_func = mbus->xfer_func;
> +	pix->ycbcr_enc = mbus->ycbcr_enc;
> +	pix->quantization = mbus->quantization;
> +	pix->field = mbus->field;
> +
> +	return ret;
> +}
> +
> +int imx_media_mbus_fmt_to_pix_fmt(struct v4l2_pix_format *pix,
> +				  const struct v4l2_mbus_framefmt *mbus,
> +				  const struct imx_media_pixfmt *cc,
> +				  enum imx_media_device_type type) {
> +	switch (type) {
> +	case DEVICE_TYPE_IMX56:
> +		return imx56_media_mbus_fmt_to_pix_fmt(pix, mbus, cc);
> +	case DEVICE_TYPE_IMX78:
> +		return imx78_media_mbus_fmt_to_pix_fmt(pix, mbus, cc);
> +	}
> +	return -EINVAL;
> +}
>  EXPORT_SYMBOL_GPL(imx_media_mbus_fmt_to_pix_fmt);
>  
>  void imx_media_free_dma_buf(struct device *dev,



From u.kleine-koenig at pengutronix.de  Fri Jan 28 02:58:48 2022
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 28 Jan 2022 11:58:48 +0100
Subject: [PATCH 1/2] dt-bindings: display: imx: Add fsl,imx21-lcdc docs
In-Reply-To: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
Message-ID: <20220128105849.368438-2-u.kleine-koenig@pengutronix.de>

From: Marian Cichy <m.cichy at pengutronix.de>

This files documents the device tree for the new imx21-lcdc DRM driver.

Signed-off-by: Marian Cichy <m.cichy at pengutronix.de>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 .../bindings/display/imx/fsl,imx21-lcdc.yaml  | 79 +++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml

diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
new file mode 100644
index 000000000000..edf71cfac81c
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/imx/fsl,imx21-lcdc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX21 LCD Controller
+
+maintainers:
+  - Philipp Zabel <p.zabel at pengutronix.de>
+
+properties:
+  compatible:
+    oneOf:
+      - const: fsl,imx21-lcdc
+      - items:
+          - enum:
+              - fsl,imx25-lcdc
+              - fsl,imx27-lcdc
+          - const: fsl,imx21-lcdc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 3
+
+  clock-names:
+    items:
+      - const: ipg
+      - const: per
+      - const: ahb
+
+  resets:
+    maxItems: 1
+
+  port:
+    type: object
+    description:
+      "Video port for DPI RGB output."
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - port
+
+additionalProperties: false
+
+examples:
+  - |
+    lcdc: lcdc at 53fbc000 {
+        compatible = "fsl,imx25-lcdc", "fsl,imx21-lcdc";
+        reg = <0x53fbc000 0x4000>;
+        interrupts = <39>;
+        clocks = <&clks 103>, <&clks 66>, <&clks 49>;
+        clock-names = "ipg", "ahb", "per";
+
+        port {
+             parallel_out: endpoint {
+                 remote-endpoint = <&panel_in>;
+             };
+        };
+
+    };
+
+    panel: panel {
+        compatible = "edt,etm0700g0dh6";
+        power-supply = <&lcd_supply>;
+        backlight = <&bl>;
+
+        port {
+                panel_in: endpoint {
+                        remote-endpoint = <&parallel_out>;
+                };
+        };
+    };
-- 
2.34.1



From u.kleine-koenig at pengutronix.de  Fri Jan 28 02:58:49 2022
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 28 Jan 2022 11:58:49 +0100
Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21
In-Reply-To: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
Message-ID: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>

From: Marian Cichy <m.cichy at pengutronix.de>

Add support for the LCD Controller found on i.MX21, i.MX25 and i.MX27

Note there is already a fb driver for this hardware in the tree that is
supposed to be superseded by this one.

Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
---
 drivers/gpu/drm/imx/Kconfig                 |   9 +
 drivers/gpu/drm/imx/Makefile                |   2 +
 drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c | 631 ++++++++++++++++++++
 3 files changed, 642 insertions(+)
 create mode 100644 drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c

diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index bb9738c7c825..62b24ea1bbe0 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -42,3 +42,12 @@ config DRM_IMX_HDMI
 	  Choose this if you want to use HDMI on i.MX6.
 
 source "drivers/gpu/drm/imx/dcss/Kconfig"
+
+config DRM_IMX21_LCDC
+	tristate "Freescale i.MX LCDC displays"
+	depends on DRM && (ARCH_MXC || ARCH_MULTIPLATFORM || COMPILE_TEST)
+	select DRM_GEM_CMA_HELPER
+	select DRM_KMS_HELPER
+	help
+	  This driver is for the Liquid Crystal Display Controller (LCDC) found
+	  on Freescale i.MX21, i.MX25 and i.MX27.
diff --git a/drivers/gpu/drm/imx/Makefile b/drivers/gpu/drm/imx/Makefile
index b644deffe948..25685230f4f7 100644
--- a/drivers/gpu/drm/imx/Makefile
+++ b/drivers/gpu/drm/imx/Makefile
@@ -10,3 +10,5 @@ obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o
 
 obj-$(CONFIG_DRM_IMX_HDMI) += dw_hdmi-imx.o
 obj-$(CONFIG_DRM_IMX_DCSS) += dcss/
+
+obj-$(CONFIG_DRM_IMX21_LCDC) += imx21-lcdc/
diff --git a/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c b/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c
new file mode 100644
index 000000000000..37e75f728293
--- /dev/null
+++ b/drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c
@@ -0,0 +1,631 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: 2020 Marian Cichy <kernel at pengutronix.de>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_vblank.h>
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+/* LCDC Screen Start Address Register */
+#define IMX21LCDC_LSSAR		0x0000
+
+/* LCDC Size Register */
+#define IMX21LCDC_LSR		0x0004
+#define   IMX21LCDC_LSR_XMAX		GENMASK(25, 20) /* Screen width (in pixels) divided by 16. */
+#define   IMX21LCDC_LSR_YMAX		GENMASK(9, 0)
+
+/* LCDC Virtual Page Width Register */
+#define IMX21LCDC_LVPWR		0x0008
+
+/* LCDC Cursor Position Register */
+#define IMX21LCDC_LCPR		0x000c
+#define   IMX21LCDC_LCPR_CC		GENMASK(31, 30) /* Cursor Control */
+
+/* LCDC Cursor Width Height and Blink Register*/
+#define IMX21LCDC_LCWHB		0x0010
+
+/* LCDC Color Cursor Mapping Register */
+#define IMX21LCDC_LCCMR		0x0014
+
+/* LCDC Panel Configuration Register */
+#define IMX21LCDC_LPCR		0x0018
+#define   IMX21LCDC_LPCR_PCD		GENMASK(5, 0)
+#define   IMX21LCDC_LPCR_SHARP		BIT(6)
+#define   IMX21LCDC_LPCR_SCLKSEL	BIT(7)
+#define   IMX21LCDC_LPCR_ACD		GENMASK(14, 8)
+#define   IMX21LCDC_LPCR_ACDSEL		BIT(15)
+#define   IMX21LCDC_LPCR_REV_VS		BIT(16)
+#define   IMX21LCDC_LPCR_SWAP_SEL	BIT(17)
+#define   IMX21LCDC_LPCR_END_SEL	BIT(18)
+#define   IMX21LCDC_LPCR_SCLKIDLE	BIT(19)
+#define   IMX21LCDC_LPCR_OEPOL		BIT(20)
+#define   IMX21LCDC_LPCR_CLKPOL		BIT(21)
+#define   IMX21LCDC_LPCR_LPPOL		BIT(22)
+#define   IMX21LCDC_LPCR_FLMPOL		BIT(23)
+#define   IMX21LCDC_LPCR_PIXPOL		BIT(24)
+#define   IMX21LCDC_LPCR_BPIX		GENMASK(27, 25)
+#define   IMX21LCDC_LPCR_PBSIZ		GENMASK(29, 28)
+#define   IMX21LCDC_LPCR_COLOR		BIT(30)
+#define   IMX21LCDC_LPCR_TFT		BIT(31)
+
+/* LCDC Horizontal Configuration Register */
+#define IMX21LCDC_LHCR		0x001c
+#define   IMX21LCDC_LHCR_H_WIDTH	GENMASK(31, 26)
+#define   IMX21LCDC_LHCR_H_BPORCH	GENMASK(7, 0)
+#define   IMX21LCDC_LHCR_H_FPORCH	GENMASK(15, 8)
+
+/* LCDC Vertical Configuration Register */
+#define IMX21LCDC_LVCR		0x0020
+#define   IMX21LCDC_LVCR_V_WIDTH	GENMASK(31, 26)
+#define   IMX21LCDC_LVCR_V_BPORCH	GENMASK(7, 0)
+#define   IMX21LCDC_LVCR_V_FPORCH	GENMASK(15, 8)
+
+/* LCDC Panning Offset Register */
+#define IMX21LCDC_LPOR		0x0024
+
+/* LCDC Sharp Configuration Register */
+#define IMX21LCDC_LSCR		0x0028
+
+/* LCDC PWM Contrast Control Register */
+#define IMX21LCDC_LPCCR		0x002c
+
+/* LCDC DMA Control Register */
+#define IMX21LCDC_LDCR		0x0030
+
+/* LCDC Refresh Mode Control Register */
+#define IMX21LCDC_LRMCR		0x0034
+
+/* LCDC Interrupt Configuration Register */
+#define IMX21LCDC_LICR		0x0038
+
+/* LCDC Interrupt Enable Register */
+#define IMX21LCDC_LIER		0x003c
+#define   IMX21LCDC_LIER_EOF		BIT(1)
+
+/* LCDC Interrupt Status Register */
+#define IMX21LCDC_LISR		0x0040
+#define   IMX21LCDC_LISR_EOF		BIT(1)
+
+/* LCDC Graphic Window Start Address Register */
+#define IMX21LCDC_LGWSAR	0x0050
+
+/* LCDC Graph Window Size Register */
+#define IMX21LCDC_LGWSR		0x0054
+
+/* LCDC Graphic Window Virtual Page Width Register */
+#define IMX21LCDC_LGWVPWR	0x0058
+
+/* LCDC Graphic Window Panning Offset Register */
+#define IMX21LCDC_LGWPOR	0x005c
+
+/* LCDC Graphic Window Position Register */
+#define IMX21LCDC_LGWPR		0x0060
+
+/* LCDC Graphic Window Control Register */
+#define IMX21LCDC_LGWCR		0x0064
+
+/* LCDC Graphic Window DMA Control Register */
+#define IMX21LCDC_LGWDCR	0x0068
+
+/* LCDC AUS Mode Control Register */
+#define IMX21LCDC_LAUSCR	0x0080
+
+/* LCDC AUS Mode Cursor Control Register */
+#define IMX21LCDC_LAUSCCR	0x0084
+
+/* Background Lookup Table */
+#define IMX21LCDC_BGLUT		0x0800
+
+/* Graphic Window Lookup Table */
+#define IMX21LCDC_GWLUT		0x0c00
+
+#define BPP_RGB565 0x05
+
+#define LCDC_MIN_XRES 64
+#define LCDC_MIN_YRES 64
+
+#define LCDC_MAX_XRES 1024
+#define LCDC_MAX_YRES 1024
+
+struct imx_lcdc {
+	struct drm_device drm;
+	struct drm_simple_display_pipe pipe;
+	const struct drm_display_mode *mode;
+	struct drm_connector connector;
+	struct drm_panel *panel;
+	struct drm_bridge *bridge;
+	void __iomem *base;
+
+	struct clk *clk_ipg;
+	struct clk *clk_ahb;
+	struct clk *clk_per;
+};
+
+static const u32 imx_lcdc_formats[] = {
+	DRM_FORMAT_RGB565,
+};
+
+static inline struct imx_lcdc *drm_to_lcdc(struct drm_device *drm)
+{
+	return container_of(drm, struct imx_lcdc, drm);
+}
+
+static unsigned int imx_lcdc_get_format(unsigned int drm_format)
+{
+	unsigned int bpp;
+
+	switch (drm_format) {
+	default:
+		DRM_WARN("Format not supported - fallback to RGB565\n");
+		fallthrough;
+	case DRM_FORMAT_RGB565:
+		bpp = BPP_RGB565;
+		break;
+	}
+
+	return bpp;
+}
+
+static int imx_lcdc_connector_get_modes(struct drm_connector *connector)
+{
+	struct imx_lcdc *lcdc = drm_to_lcdc(connector->dev);
+
+	if (lcdc->panel)
+		return drm_panel_get_modes(lcdc->panel, connector);
+
+	return 0;
+}
+
+static const struct drm_connector_helper_funcs imx_lcdc_connector_hfuncs = {
+	.get_modes = imx_lcdc_connector_get_modes,
+};
+
+static const struct drm_connector_funcs imx_lcdc_connector_funcs = {
+	.reset = drm_atomic_helper_connector_reset,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static void imx_lcdc_update_hw_registers(struct drm_simple_display_pipe *pipe,
+					 struct drm_plane_state *old_state,
+					 bool mode_set)
+{
+	struct drm_crtc *crtc = &pipe->crtc;
+	struct drm_plane_state *new_state = pipe->plane.state;
+	struct drm_framebuffer *fb = new_state->fb;
+	struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev);
+	unsigned int bpp = imx_lcdc_get_format(fb->format->format);
+	unsigned int lvcr; /* LVCR-Register value */
+	unsigned int lhcr; /* LHCR-Register value */
+	unsigned int framesize;
+	dma_addr_t addr = drm_fb_cma_get_gem_addr(fb, new_state, 0);
+
+	/* The LSSAR register specifies the LCD screen start address (SSA). */
+	writel(addr, lcdc->base + IMX21LCDC_LSSAR);
+
+	if (!mode_set)
+		return;
+
+	/* Disable PER clock to make register write possible */
+	if (old_state && old_state->crtc && old_state->crtc->enabled)
+		clk_disable_unprepare(lcdc->clk_per);
+
+	/* Framesize */
+	framesize = FIELD_PREP(IMX21LCDC_LSR_XMAX, crtc->mode.hdisplay / 16);
+	framesize |= FIELD_PREP(IMX21LCDC_LSR_YMAX, crtc->mode.vdisplay);
+	writel(framesize, lcdc->base + IMX21LCDC_LSR);
+
+	/* HSYNC */
+	lhcr = FIELD_PREP(IMX21LCDC_LHCR_H_FPORCH, crtc->mode.hsync_start - crtc->mode.hdisplay - 1);
+	lhcr |= FIELD_PREP(IMX21LCDC_LHCR_H_WIDTH, crtc->mode.hsync_end - crtc->mode.hsync_start - 1);
+	lhcr |= FIELD_PREP(IMX21LCDC_LHCR_H_BPORCH, crtc->mode.htotal - crtc->mode.hsync_end - 3);
+	writel(lhcr, lcdc->base + IMX21LCDC_LHCR);
+
+	/* VSYNC */
+	lvcr = FIELD_PREP(IMX21LCDC_LVCR_V_FPORCH, crtc->mode.vsync_start - crtc->mode.vdisplay);
+	lvcr |= FIELD_PREP(IMX21LCDC_LVCR_V_WIDTH, crtc->mode.vsync_end - crtc->mode.vsync_start);
+	lvcr |= FIELD_PREP(IMX21LCDC_LVCR_V_BPORCH, crtc->mode.vtotal - crtc->mode.vsync_end);
+	writel(lvcr, lcdc->base + IMX21LCDC_LVCR);
+
+	writel(readl(lcdc->base + IMX21LCDC_LPCR) | FIELD_PREP(IMX21LCDC_LPCR_BPIX, bpp),
+	       lcdc->base + IMX21LCDC_LPCR);
+
+	/* Virtual Page Width */
+	writel(new_state->fb->pitches[0] / 4, lcdc->base + IMX21LCDC_LVPWR);
+
+	/* Enable PER clock */
+	if (new_state->crtc->enabled)
+		clk_prepare_enable(lcdc->clk_per);
+}
+
+static void imx_lcdc_pipe_enable(struct drm_simple_display_pipe *pipe,
+				 struct drm_crtc_state *crtc_state,
+				 struct drm_plane_state *plane_state)
+{
+	int ret;
+	int clk_div;
+	int bpp;
+	struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev);
+	struct drm_display_mode *mode = &pipe->crtc.mode;
+	struct drm_display_info *disp_info = &pipe->connector->display_info;
+	const int hsync_pol = (mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : 1;
+	const int vsync_pol = (mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : 1;
+	const int data_enable_pol =
+		(disp_info->bus_flags & DRM_BUS_FLAG_DE_HIGH) ? 0 : 1;
+	const int clk_pol =
+		(disp_info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) ? 0 : 1;
+
+	drm_panel_prepare(lcdc->panel);
+
+	clk_div = DIV_ROUND_CLOSEST_ULL(clk_get_rate(lcdc->clk_per),
+					mode->clock * 1000);
+	bpp = imx_lcdc_get_format(plane_state->fb->format->format);
+
+	writel(FIELD_PREP(IMX21LCDC_LPCR_PCD, clk_div - 1) |
+	       FIELD_PREP(IMX21LCDC_LPCR_LPPOL, hsync_pol) |
+	       FIELD_PREP(IMX21LCDC_LPCR_FLMPOL, vsync_pol) |
+	       FIELD_PREP(IMX21LCDC_LPCR_OEPOL, data_enable_pol) |
+	       FIELD_PREP(IMX21LCDC_LPCR_TFT, 1) |
+	       FIELD_PREP(IMX21LCDC_LPCR_COLOR, 1) |
+	       FIELD_PREP(IMX21LCDC_LPCR_PBSIZ, 3) |
+	       FIELD_PREP(IMX21LCDC_LPCR_BPIX, bpp) |
+	       FIELD_PREP(IMX21LCDC_LPCR_SCLKSEL, 1) |
+	       FIELD_PREP(IMX21LCDC_LPCR_PIXPOL, 0) |
+	       FIELD_PREP(IMX21LCDC_LPCR_CLKPOL, clk_pol),
+	       lcdc->base + IMX21LCDC_LPCR);
+
+	/* 0px panning offset */
+	writel(0x0, lcdc->base + IMX21LCDC_LPOR);
+
+	/* disable hardware cursor */
+	writel(readl(lcdc->base + IMX21LCDC_LCPR) & ~IMX21LCDC_LCPR_CC,
+	       lcdc->base + IMX21LCDC_LCPR);
+
+	ret = clk_prepare_enable(lcdc->clk_ipg);
+	if (ret) {
+		dev_err(pipe->crtc.dev->dev, "Cannot enable ipg clock: %pe\n", ERR_PTR(ret));
+		return;
+	}
+	ret = clk_prepare_enable(lcdc->clk_ahb);
+	if (ret) {
+		dev_err(pipe->crtc.dev->dev, "Cannot enable ahb clock: %pe\n", ERR_PTR(ret));
+		clk_disable_unprepare(lcdc->clk_ipg);
+		return;
+	}
+
+	imx_lcdc_update_hw_registers(pipe, NULL, true);
+	drm_panel_enable(lcdc->panel);
+
+	/* Enable VBLANK Interrupt */
+	writel(IMX21LCDC_LIER_EOF, lcdc->base + IMX21LCDC_LIER);
+}
+
+static void imx_lcdc_pipe_disable(struct drm_simple_display_pipe *pipe)
+{
+	struct imx_lcdc *lcdc = drm_to_lcdc(pipe->crtc.dev);
+	struct drm_panel *panel = lcdc->panel;
+	struct drm_crtc *crtc = &lcdc->pipe.crtc;
+	struct drm_pending_vblank_event *event;
+
+	drm_panel_disable(panel);
+
+	clk_disable_unprepare(lcdc->clk_ahb);
+	clk_disable_unprepare(lcdc->clk_ipg);
+
+	if (pipe->crtc.enabled)
+		clk_disable_unprepare(lcdc->clk_per);
+
+	drm_panel_unprepare(panel);
+
+	spin_lock_irq(&lcdc->drm.event_lock);
+	event = crtc->state->event;
+	if (event) {
+		crtc->state->event = NULL;
+		drm_crtc_send_vblank_event(crtc, event);
+	}
+	spin_unlock_irq(&lcdc->drm.event_lock);
+
+	/* Disable VBLANK Interrupt */
+	writel(0, lcdc->base + IMX21LCDC_LIER);
+}
+
+static int imx_lcdc_pipe_check(struct drm_simple_display_pipe *pipe,
+			       struct drm_plane_state *plane_state,
+			       struct drm_crtc_state *crtc_state)
+{
+	const struct drm_display_mode *mode = &crtc_state->mode;
+
+	if ((mode->hdisplay < LCDC_MIN_XRES || mode->hdisplay > LCDC_MAX_XRES) ||
+	    (mode->vdisplay < LCDC_MIN_YRES || mode->vdisplay > LCDC_MAX_YRES) ||
+	    (mode->hdisplay % 16)) {
+		DRM_ERROR("unsupported display mode (%u x %u)\n",
+			  mode->hdisplay, mode->vdisplay);
+		return -EINVAL;
+	}
+
+	if (!FIELD_FIT(IMX21LCDC_LHCR_H_FPORCH, mode->hsync_start - mode->hdisplay - 1) ||
+	    !FIELD_FIT(IMX21LCDC_LHCR_H_WIDTH, mode->hsync_end - mode->hsync_start - 1) ||
+	    !FIELD_FIT(IMX21LCDC_LHCR_H_BPORCH, mode->htotal - mode->hsync_end - 3)) {
+		DRM_ERROR("invalid HSYNC setting (htotal = %hu, hsync_start = %hu, hsync_end = %hu, hdisplay = %hu)\n",
+			  mode->htotal, mode->hsync_start, mode->hsync_end, mode->hdisplay);
+		return -EINVAL;
+	}
+	if (!FIELD_FIT(IMX21LCDC_LVCR_V_FPORCH, mode->vsync_start - mode->vdisplay) ||
+	    !FIELD_FIT(IMX21LCDC_LVCR_V_WIDTH, mode->vsync_end - mode->vsync_start) ||
+	    !FIELD_FIT(IMX21LCDC_LVCR_V_BPORCH, mode->vtotal - mode->vsync_end)) {
+		DRM_ERROR("invalid VSYNC setting (vtotal = %hu, vsync_start = %hu, vsync_end = %hu, vdisplay = %hu)\n",
+			  mode->vtotal, mode->vsync_start, mode->vsync_end, mode->vdisplay);
+		return -EINVAL;
+
+	}
+
+	if (plane_state->fb->pitches[0] % 4) {
+		DRM_ERROR("invalid pitches setting (%hu)\n", plane_state->fb->pitches[0]);
+		return -EINVAL;
+	}
+
+	crtc_state->mode_changed =
+		crtc_state->mode.hdisplay != pipe->crtc.state->mode.hdisplay ||
+		crtc_state->mode.vdisplay != pipe->crtc.state->mode.vdisplay ||
+		plane_state->fb->pitches[0] != pipe->plane.state->fb->pitches[0];
+
+	return 0;
+}
+
+static void imx_lcdc_pipe_update(struct drm_simple_display_pipe *pipe,
+				 struct drm_plane_state *old_state)
+{
+	struct drm_crtc *crtc = &pipe->crtc;
+	struct drm_pending_vblank_event *event = crtc->state->event;
+	struct drm_plane_state *new_state = pipe->plane.state;
+	struct drm_framebuffer *fb = new_state->fb;
+	struct drm_framebuffer *old_fb = old_state->fb;
+	struct drm_crtc *old_crtc = old_state->crtc;
+	bool mode_changed = false;
+
+	if (old_fb && old_fb->format != fb->format)
+		mode_changed = true;
+	else if (old_crtc != crtc)
+		mode_changed = true;
+	else if (crtc->state->mode_changed)
+		mode_changed = true;
+
+	imx_lcdc_update_hw_registers(pipe, old_state, mode_changed);
+
+	if (event) {
+		crtc->state->event = NULL;
+
+		spin_lock_irq(&crtc->dev->event_lock);
+
+		if (crtc->state->active && drm_crtc_vblank_get(crtc) == 0)
+			drm_crtc_arm_vblank_event(crtc, event);
+		else
+			drm_crtc_send_vblank_event(crtc, event);
+
+		spin_unlock_irq(&crtc->dev->event_lock);
+	}
+}
+
+static const struct drm_simple_display_pipe_funcs imx_lcdc_pipe_funcs = {
+	.enable = imx_lcdc_pipe_enable,
+	.disable = imx_lcdc_pipe_disable,
+	.check = imx_lcdc_pipe_check,
+	.update = imx_lcdc_pipe_update,
+	.prepare_fb = drm_gem_simple_display_pipe_prepare_fb,
+};
+
+static const struct drm_mode_config_funcs imx_lcdc_mode_config_funcs = {
+	.fb_create = drm_gem_fb_create_with_dirty,
+	.atomic_check = drm_atomic_helper_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static const struct drm_mode_config_helper_funcs imx_lcdc_mode_config_helpers = {
+	.atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
+};
+
+DEFINE_DRM_GEM_CMA_FOPS(imx_lcdc_drm_fops);
+
+static struct drm_driver imx_lcdc_drm_driver = {
+	.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
+	.fops = &imx_lcdc_drm_fops,
+	DRM_GEM_CMA_DRIVER_OPS_VMAP,
+	.name = "imx-lcdc",
+	.desc = "i.MX LCDC driver",
+	.date = "20200716",
+};
+
+static const struct of_device_id imx_lcdc_of_dev_id[] = {
+	{ .compatible = "fsl,imx21-lcdc", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx_lcdc_of_dev_id);
+
+static irqreturn_t irq_handler(int irq, void *arg)
+{
+	struct imx_lcdc *lcdc = (struct imx_lcdc *)arg;
+	struct drm_crtc *crtc = &lcdc->pipe.crtc;
+	unsigned int status;
+
+	status = readl(lcdc->base + IMX21LCDC_LISR);
+
+	if (status & IMX21LCDC_LISR_EOF) {
+		drm_crtc_handle_vblank(crtc);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int imx_lcdc_probe(struct platform_device *pdev)
+{
+	struct imx_lcdc *lcdc;
+	struct drm_device *drm;
+	int irq;
+	int ret;
+	struct device *dev = &pdev->dev;
+
+	lcdc = devm_drm_dev_alloc(&pdev->dev, &imx_lcdc_drm_driver,
+				  struct imx_lcdc, drm);
+	if (!lcdc)
+		return -ENOMEM;
+
+	drm = &lcdc->drm;
+
+	lcdc->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(lcdc->base))
+		return PTR_ERR(lcdc->base);
+
+	/* Panel */
+	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &lcdc->panel, &lcdc->bridge);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to find panel or bridge\n");
+
+	/* Get Clocks */
+	lcdc->clk_ipg = devm_clk_get(dev, "ipg");
+	if (IS_ERR(lcdc->clk_ipg))
+		return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ipg clk\n");
+
+	lcdc->clk_ahb = devm_clk_get(dev, "ahb");
+	if (IS_ERR(lcdc->clk_ahb))
+		return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ahb clk\n");
+
+	lcdc->clk_per = devm_clk_get(dev, "per");
+	if (IS_ERR(lcdc->clk_per))
+		return dev_err_probe(dev, PTR_ERR(lcdc->clk_ipg), "Failed to get ahb clk\n");
+
+	ret = dma_set_mask_and_coherent(drm->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return dev_err_probe(drm->dev, ret, "Failed to set DMA Mask.\n");
+
+	/* Modeset init */
+	ret = drmm_mode_config_init(drm);
+	if (ret)
+		return dev_err_probe(drm->dev, ret, "Failed to initialized mode setting.\n");
+
+	/* CRTC, Plane, Encoder */
+	ret = drm_simple_display_pipe_init(drm, &lcdc->pipe, &imx_lcdc_pipe_funcs, imx_lcdc_formats,
+					   ARRAY_SIZE(imx_lcdc_formats), NULL, &lcdc->connector);
+	if (ret < 0)
+		return dev_err_probe(drm->dev, ret, "Cannot setup simple display pipe\n");
+
+	ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
+	if (ret < 0)
+		return dev_err_probe(drm->dev, ret, "Failed to initialize vblank\n");
+
+	if (lcdc->bridge) {
+		ret = drm_simple_display_pipe_attach_bridge(&lcdc->pipe,
+							    lcdc->bridge);
+		if (ret)
+			return dev_err_probe(drm->dev, ret, "Cannot connect bridge\n");
+	}
+
+	/* Connector */
+	drm_connector_helper_add(&lcdc->connector, &imx_lcdc_connector_hfuncs);
+	drm_connector_init(drm, &lcdc->connector, &imx_lcdc_connector_funcs,
+			   DRM_MODE_CONNECTOR_DPI);
+
+	/*
+	 * The LCDC controller does not have an enable bit. The
+	 * controller starts directly when the clocks are enabled.
+	 * If the clocks are enabled when the controller is not yet
+	 * programmed with proper register values (enabled at the
+	 * bootloader, for example) then it just goes into some undefined
+	 * state.
+	 * To avoid this issue, let's enable and disable LCDC IPG,
+	 * PER and AHB clock so that we force some kind of 'reset'
+	 * to the LCDC block.
+	 */
+
+	ret = clk_prepare_enable(lcdc->clk_ipg);
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot enable ipg clock\n");
+	clk_disable_unprepare(lcdc->clk_ipg);
+
+	ret = clk_prepare_enable(lcdc->clk_per);
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot enable per clock\n");
+	clk_disable_unprepare(lcdc->clk_per);
+
+	ret = clk_prepare_enable(lcdc->clk_ahb);
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot enable ahb clock\n");
+	clk_disable_unprepare(lcdc->clk_ahb);
+
+	drm->mode_config.min_width = LCDC_MIN_XRES;
+	drm->mode_config.max_width = LCDC_MAX_XRES;
+	drm->mode_config.min_height = LCDC_MIN_YRES;
+	drm->mode_config.max_height = LCDC_MAX_YRES;
+	drm->mode_config.preferred_depth = 16;
+	drm->mode_config.funcs = &imx_lcdc_mode_config_funcs;
+	drm->mode_config.helper_private = &imx_lcdc_mode_config_helpers;
+
+	drm_mode_config_reset(drm);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = irq;
+		return ret;
+	}
+
+	ret = devm_request_irq(dev, irq, irq_handler, 0, "imx-lcdc", lcdc);
+	if (ret < 0)
+		return dev_err_probe(drm->dev, ret, "Failed to install IRQ handler\n");
+
+	platform_set_drvdata(pdev, drm);
+
+	ret = drm_dev_register(&lcdc->drm, 0);
+	if (ret)
+		return dev_err_probe(dev, ret, "Cannot register device\n");
+
+	drm_fbdev_generic_setup(drm, 0);
+
+	return 0;
+}
+
+static int imx_lcdc_remove(struct platform_device *pdev)
+{
+	struct imx_lcdc *lcdc = drm_to_lcdc(platform_get_drvdata(pdev));
+
+	drm_dev_unregister(&lcdc->drm);
+	drm_atomic_helper_shutdown(&lcdc->drm);
+
+	return 0;
+}
+
+static void imx_lcdc_shutdown(struct platform_device *pdev)
+{
+	drm_atomic_helper_shutdown(platform_get_drvdata(pdev));
+}
+
+static struct platform_driver imx_lcdc_driver = {
+	.driver = {
+		.name = "imx-lcdc",
+		.of_match_table = imx_lcdc_of_dev_id,
+	},
+	.probe = imx_lcdc_probe,
+	.remove = imx_lcdc_remove,
+	.shutdown = imx_lcdc_shutdown,
+};
+module_platform_driver(imx_lcdc_driver);
+
+MODULE_AUTHOR("Marian Cichy <kernel at pengutronix.de>");
+MODULE_DESCRIPTION("Freescale i.MX LCDC driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1



From u.kleine-koenig at pengutronix.de  Fri Jan 28 02:58:47 2022
From: u.kleine-koenig at pengutronix.de (=?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?=)
Date: Fri, 28 Jan 2022 11:58:47 +0100
Subject: [PATCH 0/2] drm/imx/lcdc: drm driver for imx21/25/27
Message-ID: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>

Hello,

this patchset was created mostly by Marian Cichy, who in the meantime
left Pengutronix. I still kept his name and email address as author, but
note that the email address doesn't reach Marian any more.

There is already a maintainer entry for imx DRM drivers that matches
good enough.

This was tested on an i.MX25 based customer machine.

Best regards
Uwe

Marian Cichy (2):
  dt-bindings: display: imx: Add fsl,imx21-lcdc docs
  drm/imx/lcdc: Implement DRM driver for imx21

 .../bindings/display/imx/fsl,imx21-lcdc.yaml  |  79 +++
 drivers/gpu/drm/imx/Kconfig                   |   9 +
 drivers/gpu/drm/imx/Makefile                  |   2 +
 drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c   | 631 ++++++++++++++++++
 4 files changed, 721 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
 create mode 100644 drivers/gpu/drm/imx/imx21-lcdc/imx21-lcdc.c

-- 
2.34.1



From suzuki.poulose at arm.com  Fri Jan 28 03:00:59 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 11:00:59 +0000
Subject: [RFC PATCH] ACPI / amba: Skip creating amba device when
 associated cpu is not online
In-Reply-To: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
References: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
Message-ID: <2f3c5e6b-7000-8fa2-21f7-3b0c3fb66ae3@arm.com>

Hi Xiang

On 07/01/2022 08:41, chenxiang wrote:
> From: Xiang Chen <chenxiang66 at hisilicon.com>
> 
> If not up all the cpus with command line "maxcpus=x", system will be
> blocked.
> We find that some amba devices such as ETM devices, are associated with
> special cpus, and if the cpu is not up, the register of associated device
> is not allowed to access. BIOS reports all the ETM device nodes and a
> amba device is created for every ETM device, so even if one cpu is not up,
> the amba device will still be created for the associated device, and also
> the register of device (pid and cid) will be accessed when adding amba
> device which will cause the issue.
> To fix it, skip creating amba device if it is associated with a cpu which
> is not online.

I understand the issue. We do not have an issue at least on DT based 
platforms with a similar environment (Juno). The key is the power 
management for the components.

There are two separate issues at play here :

1) Power management with ACPI. I believe there is a solution in progress
to address this.

2) The ETM is in the same power domain as that of the CPU and normal 
device power management may not work without the CPU being online.

3) Additionally we have other issue of supporting system instructions
with ACPI, which do not appear on the AMBA bus.

Considering all of these, the ideal solution is to :

1) Implement power management for ACPI, which is anyway in progress
   (at least for SCMI based systems)
2) Move the ETM driver away from the AMBA framework. That would make
    the CPU online problem and the (3) above easier to solve.
    Anshuman is going to look into this.

In the meantime, we could have this temporary fix in and solve it
forever by moving away from the AMBA.

> 
> Signed-off-by: Xiang Chen <chenxiang66 at hisilicon.com>
> ---
>   drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
>   1 file changed, 36 insertions(+)
> 
> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
> index ab8a4e0191b1..2369198f734b 100644
> --- a/drivers/acpi/acpi_amba.c
> +++ b/drivers/acpi/acpi_amba.c
> @@ -16,6 +16,7 @@
>   #include <linux/ioport.h>
>   #include <linux/kernel.h>
>   #include <linux/module.h>
> +#include <acpi/processor.h>
>   
>   #include "internal.h"
>   
> @@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
>   	clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
>   }
>   
> +static int acpi_handle_to_cpuid(acpi_handle handle)
> +{
> +	int cpu = -1;
> +	struct acpi_processor *pr;
> +
> +	for_each_possible_cpu(cpu) {
> +		pr = per_cpu(processors, cpu);
> +		if (pr && pr->handle == handle)
> +			break;
> +	}
> +
> +	return cpu;
> +}
> +

Please could we reuse the function in coresight-platform.c ?
i.e, move it to a generic location and share it, rather than
duplicating it ?


> +static int acpi_dev_get_cpu(struct acpi_device *adev)
> +{
> +	acpi_handle cpu_handle;
> +	acpi_status status;
> +	int cpu;
> +
> +	status = acpi_get_parent(adev->handle, &cpu_handle);
> +	if (ACPI_FAILURE(status))
> +		return -1;
> +	cpu = acpi_handle_to_cpuid(cpu_handle);
> +	if (cpu >= nr_cpu_ids)
> +		return -1;
> +	return cpu;
> +}
> +
>   static int amba_handler_attach(struct acpi_device *adev,
>   				const struct acpi_device_id *id)
>   {
> @@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device *adev,
>   	bool address_found = false;
>   	int irq_no = 0;
>   	int ret;
> +	int cpu;
>   
>   	/* If the ACPI node already has a physical device attached, skip it. */
>   	if (adev->physical_node_count)
>   		return 0;
>   
> +	/* If the cpu associated with the device is not online, skip it. */
> +	cpu = acpi_dev_get_cpu(adev);
> +	if (cpu >= 0 && !cpu_online(cpu))
> +		return 0;
> +

Except for the comment above, the patch looks good to me.

Suzuki


From allen-kh.cheng at mediatek.com  Fri Jan 28 03:05:46 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:05:46 +0800
Subject: [PATCH v3 0/7] Add basic node support for Mediatek MT8186 SoC
In-Reply-To: <20220128103209.00002704@Huawei.com>
References: <20220128062050.23978-1-allen-kh.cheng@mediatek.com>
 <20220128103209.00002704@Huawei.com>
Message-ID: <88655c2bd0e2db25861803550f0a6b393177ec67.camel@mediatek.com>

On Fri, 2022-01-28 at 10:32 +0000, Jonathan Cameron wrote:
> On Fri, 28 Jan 2022 14:20:43 +0800
> allen-kh.cheng <allen-kh.cheng at mediatek.com> wrote:
> 
> > From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
> > 
> > MT8186 is a SoC based on 64bit ARMv8 architecture.
> > It contains 6 CA55 and 2 CA78 cores.
> > MT8186 share many HW IP with MT65xx series.
> > 
> > This patchset was tested on MT8186 evaluation board to shell.
> 
> Please prune your cc list for any future versions.
> We all get enough emails as it is :)
> 
> I'm not seeing anything relevant to linux-iio in here for example.
> 
> Thanks,
> 
> Jonathan
> 

Hi Jonathan,

Sorry for any inconvenience caused to you.

I will remove linux-iio in next version.

Thanks.

> > 
> > Based on linux-next
> > 
> > changes since v2:$
> >  - add soc {} in mt8186.dtsi
> > 
> > changes since v1:
> >  - add dt-bindings: arm: Add compatible for Mediatek MT8186
> > 
> > 
> > Allen-KH Cheng (7):
> >   dt-bindings: timer: Add compatible for Mediatek MT8186
> >   dt-bindings: serial: Add compatible for Mediatek MT8186
> >   dt-bindings: watchdog: Add compatible for Mediatek MT8186
> >   dt-bindings: mmc: Add compatible for Mediatek MT8186
> >   dt-bindings: phy: Add compatible for Mediatek MT8186
> >   dt-bindings: arm: Add compatible for Mediatek MT8186
> >   arm64: dts: Add Mediatek SoC MT8186 dts and evaluation board and
> >     Makefile
> > 
> >  .../devicetree/bindings/arm/mediatek.yaml     |   4 +
> >  .../devicetree/bindings/mmc/mtk-sd.yaml       |   3 +
> >  .../bindings/phy/mediatek,tphy.yaml           |   1 +
> >  .../devicetree/bindings/serial/mtk-uart.txt   |   1 +
> >  .../bindings/timer/mediatek,mtk-timer.txt     |   1 +
> >  .../devicetree/bindings/watchdog/mtk-wdt.txt  |   1 +
> >  arch/arm64/boot/dts/mediatek/Makefile         |   1 +
> >  arch/arm64/boot/dts/mediatek/mt8186-evb.dts   |  24 ++
> >  arch/arm64/boot/dts/mediatek/mt8186.dtsi      | 360
> > ++++++++++++++++++
> >  9 files changed, 396 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186-evb.dts
> >  create mode 100644 arch/arm64/boot/dts/mediatek/mt8186.dtsi
> > 
> 
> 



From allen-kh.cheng at mediatek.com  Fri Jan 28 03:08:27 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:08:27 +0800
Subject: [PATCH v17 0/2] mtk: add ADSP mailbox controller for MT8195
Message-ID: <20220128110829.17202-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Mediatek ADSP IPC is used to send notification or short message 
between processors with dsp. It will place the message to the
share buffer and will access the ADSP mailbox registers to kick
dsp. Two mailboxes used to send notification or short message 
between processors with dsp.

This patchset was tested and confirmed on MT8195 cherry board.

Based on linux-next

changes since v16:
- fix WARNING: modpost: missing MODULE_LICENSE() in drivers/mailbox
  /mtk-adsp-mailbox.o. Add MODULE_LICENSE in the last line.
- Due to WARNING: Missing or malformed SPDX-License-Identifier tag
  in line 1 in checkpatch, we don't remove SPDX-License in line 1.

changes since v15:
- add paragraphs to describe the config symbols fully

changes since v14:
- add inline for get_mtk_adsp_mbox_priv

changes since v13:
- rebase on v5.16-rc8
- add back ptr check from of_device_get_match_data

changes since v12:
- remove of_device_get_match_data ptr check:
  of_device_get_match_data(dev) will never going to return NULL.
  driver probe with compatible mediatek,mt8195-adsp-mbox.

changes since v11:
- remove useless MODULE_LICENSE

changes since v10:
- split up v9 into two separate submissions

changes since v9:
- rename adsp_mbox_chan_ops to mtk_adsp_mbox_chan_ops

changes since v8:
- remove struct adsp_mbox_ch_info
- add get_mtk_adsp_mbox_priv
- use mtk_adsp_mbox_priv va_mboxreg address in adsp mbox driver
- add struct mtk_adsp_mbox_cfg for DSP mbox register offset
- remove adsp mbox register offset hard code define
- remove mtk-adsp-ipc.h reference in adsp mbox driver

changes since v7:
- add mtk prefix for adsp ipc functions
- rename adsp_mbox_ch_info to mtk_adsp_mbox_ch_info
- remove incorrect reviewers in commit message

changes since v6:
- dt-bindings: change example dtsi node.
- rename config MTK_ADSP_IPC_MBOX to MTK_ADSP_MBOX
- remove unused variable
- add reviewers

changes since v5:
- remove some redundant code

changes since v4:
- use switch ... case in adsp_ipc_recv
- add error handling path for chan_name pointer
- refine some code to be concise

changes since v3:
- reorder MTK_ADSP_IPC_MBOX config
- remove some redundant code
- remove lock in mtk-adsp-mailbox

changes since v2:
- separate adsp_mailbox into two instances

changes since v1:
- fix dt_binding_check error

Allen-KH Cheng (2):
  dt-bindings: mailbox: add mtk adsp-mbox document
  mailbox: mediatek: add support for adsp mailbox controller

 .../bindings/mailbox/mtk,adsp-mbox.yaml       |  52 ++++++
 drivers/mailbox/Kconfig                       |   9 +
 drivers/mailbox/Makefile                      |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c            | 176 ++++++++++++++++++
 4 files changed, 239 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 28 03:08:29 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:08:29 +0800
Subject: [PATCH v17 2/2] mailbox: mediatek: add support for adsp mailbox
 controller
In-Reply-To: <20220128110829.17202-1-allen-kh.cheng@mediatek.com>
References: <20220128110829.17202-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128110829.17202-3-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch is to for MediaTek ADSP IPC mailbox controller driver
It is used to send short messages between processors with adsp

Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/mailbox/Kconfig            |   9 ++
 drivers/mailbox/Makefile           |   2 +
 drivers/mailbox/mtk-adsp-mailbox.c | 176 +++++++++++++++++++++++++++++
 3 files changed, 187 insertions(+)
 create mode 100644 drivers/mailbox/mtk-adsp-mailbox.c

diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index d9cd3606040e..05d6fae800e3 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -238,6 +238,15 @@ config STM32_IPCC
 	  with hardware for Inter-Processor Communication Controller (IPCC)
 	  between processors. Say Y here if you want to have this support.
 
+config MTK_ADSP_MBOX
+	tristate "MediaTek ADSP Mailbox Controller"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	help
+          Say yes here to add support for "MediaTek ADSP Mailbox Controller.
+          This mailbox driver is used to send notification or short message
+          between processors with ADSP. It will place the message to share
+	  buffer and will access the ipc control.
+
 config MTK_CMDQ_MBOX
 	tristate "MediaTek CMDQ Mailbox Support"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 338cc05e5431..fc9376117111 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -49,6 +49,8 @@ obj-$(CONFIG_TEGRA_HSP_MBOX)	+= tegra-hsp.o
 
 obj-$(CONFIG_STM32_IPCC) 	+= stm32-ipcc.o
 
+obj-$(CONFIG_MTK_ADSP_MBOX)	+= mtk-adsp-mailbox.o
+
 obj-$(CONFIG_MTK_CMDQ_MBOX)	+= mtk-cmdq-mailbox.o
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
diff --git a/drivers/mailbox/mtk-adsp-mailbox.c b/drivers/mailbox/mtk-adsp-mailbox.c
new file mode 100644
index 000000000000..5e7378090c7b
--- /dev/null
+++ b/drivers/mailbox/mtk-adsp-mailbox.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/slab.h>
+
+struct mtk_adsp_mbox_priv {
+	struct device *dev;
+	struct mbox_controller mbox;
+	void __iomem *va_mboxreg;
+	const struct mtk_adsp_mbox_cfg *cfg;
+};
+
+struct mtk_adsp_mbox_cfg {
+	u32 set_in;
+	u32 set_out;
+	u32 clr_in;
+	u32 clr_out;
+};
+
+static inline struct mtk_adsp_mbox_priv *get_mtk_adsp_mbox_priv(struct mbox_controller *mbox)
+{
+	return container_of(mbox, struct mtk_adsp_mbox_priv, mbox);
+}
+
+static irqreturn_t mtk_adsp_mbox_irq(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 op = readl(priv->va_mboxreg + priv->cfg->set_out);
+
+	writel(op, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t mtk_adsp_mbox_isr(int irq, void *data)
+{
+	struct mbox_chan *chan = data;
+
+	mbox_chan_received_data(chan, NULL);
+
+	return IRQ_HANDLED;
+}
+
+static struct mbox_chan *mtk_adsp_mbox_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *sp)
+{
+	return mbox->chans;
+}
+
+static int mtk_adsp_mbox_startup(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+
+	return 0;
+}
+
+static void mtk_adsp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	/* Clear ADSP mbox command */
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_in);
+	writel(0xFFFFFFFF, priv->va_mboxreg + priv->cfg->clr_out);
+}
+
+static int mtk_adsp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+	u32 *msg = data;
+
+	writel(*msg, priv->va_mboxreg + priv->cfg->set_in);
+
+	return 0;
+}
+
+static bool mtk_adsp_mbox_last_tx_done(struct mbox_chan *chan)
+{
+	struct mtk_adsp_mbox_priv *priv = get_mtk_adsp_mbox_priv(chan->mbox);
+
+	return readl(priv->va_mboxreg + priv->cfg->set_in) == 0;
+}
+
+static const struct mbox_chan_ops mtk_adsp_mbox_chan_ops = {
+	.send_data	= mtk_adsp_mbox_send_data,
+	.startup	= mtk_adsp_mbox_startup,
+	.shutdown	= mtk_adsp_mbox_shutdown,
+	.last_tx_done	= mtk_adsp_mbox_last_tx_done,
+};
+
+static int mtk_adsp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_mbox_priv *priv;
+	const struct mtk_adsp_mbox_cfg *cfg;
+	struct mbox_controller *mbox;
+	int ret, irq;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	mbox = &priv->mbox;
+	mbox->dev = dev;
+	mbox->ops = &mtk_adsp_mbox_chan_ops;
+	mbox->txdone_irq = false;
+	mbox->txdone_poll = true;
+	mbox->of_xlate = mtk_adsp_mbox_xlate;
+	mbox->num_chans = 1;
+	mbox->chans = devm_kzalloc(dev, sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	priv->va_mboxreg = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(priv->va_mboxreg))
+		return PTR_ERR(priv->va_mboxreg);
+
+	cfg = of_device_get_match_data(dev);
+	if (!cfg)
+		return -EINVAL;
+	priv->cfg = cfg;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_threaded_irq(dev, irq, mtk_adsp_mbox_irq,
+					mtk_adsp_mbox_isr, IRQF_TRIGGER_NONE,
+					dev_name(dev), mbox->chans);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, priv);
+
+	return devm_mbox_controller_register(dev, &priv->mbox);
+}
+
+static const struct mtk_adsp_mbox_cfg mt8195_adsp_mbox_cfg = {
+	.set_in		= 0x00,
+	.set_out	= 0x1c,
+	.clr_in		= 0x04,
+	.clr_out	= 0x20,
+};
+
+static const struct of_device_id mtk_adsp_mbox_of_match[] = {
+	{ .compatible = "mediatek,mt8195-adsp-mbox", .data = &mt8195_adsp_mbox_cfg },
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_adsp_mbox_of_match);
+
+static struct platform_driver mtk_adsp_mbox_driver = {
+	.probe		= mtk_adsp_mbox_probe,
+	.driver = {
+		.name	= "mtk_adsp_mbox",
+		.of_match_table = mtk_adsp_mbox_of_match,
+	},
+};
+module_platform_driver(mtk_adsp_mbox_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP Mailbox Controller");
+MODULE_LICENSE("GPL v2");
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 28 03:08:28 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:08:28 +0800
Subject: [PATCH v17 1/2] dt-bindings: mailbox: add mtk adsp-mbox document
In-Reply-To: <20220128110829.17202-1-allen-kh.cheng@mediatek.com>
References: <20220128110829.17202-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128110829.17202-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch adds document for mediatek adsp mbox

Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 .../bindings/mailbox/mtk,adsp-mbox.yaml       | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
new file mode 100644
index 000000000000..25756837797f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/mtk,adsp-mbox.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/mtk,adsp-mbox.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek ADSP mailbox
+
+maintainers:
+  - Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
+
+description: |
+  The MTK ADSP mailbox Inter-Processor Communication (IPC) enables the SoC
+  to ommunicate with ADSP by passing messages through two mailbox channels.
+  The MTK ADSP mailbox IPC also provides the ability for one processor to
+  signal the other processor using interrupts.
+
+properties:
+  compatible:
+    items:
+      - const: mediatek,mt8195-adsp-mbox
+
+  "#mbox-cells":
+    const: 0
+
+  reg:
+    description:
+      Physical address base for dsp mbox registers.
+
+  interrupts:
+    description:
+      adsp mbox interrupt
+
+required:
+  - compatible
+  - "#mbox-cells"
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    adsp_mailbox0:mailbox at 10816000 {
+        compatible = "mediatek,mt8195-adsp-mbox";
+        #mbox-cells = <0>;
+        reg = <0x10816000 0x1000>;
+        interrupts = <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH 0>;
+    };
-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 28 03:18:31 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:18:31 +0800
Subject: [PATCH v6 0/1] firmware: mtk: add adsp ipc protocol for sof
Message-ID: <20220128111832.22989-1-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

This patch provides mtk adsp ipc support for sof.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

This was tested and confirmed on MT8195 cherry board with sof.

Based on linux-next

changes since v5:
- fix WARNING: modpost: missing MODULE_LICENSE() in drivers/mailbox
  /mtk-adsp-mailbox.o. Add MODULE_LICENSE in the last line.
- Due to WARNING: Missing or malformed SPDX-License-Identifier tag
  in line 1 in checkpatch, we don't remove SPDX-License in line 1.

changes since v4:
- add error message for wrong mbox chan

changes since v3:
- rebase on v5.16-rc8
- update reviewers

changes since v2:
- add out tag for two memory free phases

changes since v1:
- add comments for mtk_adsp_ipc_send and mtk_adsp_ipc_recv
- remove useless MODULE_LICENSE
- change label name to out_free

Allen-KH Cheng (1):
  firmware: mediatek: add adsp ipc protocol interface

 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 161 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 239 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

-- 
2.18.0



From allen-kh.cheng at mediatek.com  Fri Jan 28 03:18:32 2022
From: allen-kh.cheng at mediatek.com (allen-kh.cheng)
Date: Fri, 28 Jan 2022 19:18:32 +0800
Subject: [PATCH v6 1/1] firmware: mediatek: add adsp ipc protocol interface
In-Reply-To: <20220128111832.22989-1-allen-kh.cheng@mediatek.com>
References: <20220128111832.22989-1-allen-kh.cheng@mediatek.com>
Message-ID: <20220128111832.22989-2-allen-kh.cheng@mediatek.com>

From: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>

Some of mediatek processors contain
the Tensilica HiFix DSP for audio processing.

The communication between Host CPU and DSP firmware is
taking place using a shared memory area for message passing.

ADSP IPC protocol offers (send/recv) interfaces using
mediatek-mailbox APIs.

We use two mbox channels to implement a request-reply protocol.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
Reviewed-by: Curtis Malainey <cujomalainey at chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi at google.com>
Reviewed-by: YC Hung <yc.hung at mediatek.com>
Signed-off-by: Allen-KH Cheng <Allen-KH.Cheng at mediatek.com>
---
 drivers/firmware/Kconfig                      |   1 +
 drivers/firmware/Makefile                     |   1 +
 drivers/firmware/mediatek/Kconfig             |   9 +
 drivers/firmware/mediatek/Makefile            |   2 +
 drivers/firmware/mediatek/mtk-adsp-ipc.c      | 161 ++++++++++++++++++
 .../linux/firmware/mediatek/mtk-adsp-ipc.h    |  65 +++++++
 6 files changed, 239 insertions(+)
 create mode 100644 drivers/firmware/mediatek/Kconfig
 create mode 100644 drivers/firmware/mediatek/Makefile
 create mode 100644 drivers/firmware/mediatek/mtk-adsp-ipc.c
 create mode 100644 include/linux/firmware/mediatek/mtk-adsp-ipc.h

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 75cb91055c17..f3578c60cff0 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -299,6 +299,7 @@ source "drivers/firmware/cirrus/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 source "drivers/firmware/imx/Kconfig"
+source "drivers/firmware/mediatek/Kconfig"
 source "drivers/firmware/meson/Kconfig"
 source "drivers/firmware/psci/Kconfig"
 source "drivers/firmware/smccc/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 4e58cb474a68..88fbdc110100 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
 obj-y				+= imx/
+obj-y				+= mediatek/
 obj-y				+= psci/
 obj-y				+= smccc/
 obj-y				+= tegra/
diff --git a/drivers/firmware/mediatek/Kconfig b/drivers/firmware/mediatek/Kconfig
new file mode 100644
index 000000000000..6d1e580b967b
--- /dev/null
+++ b/drivers/firmware/mediatek/Kconfig
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-only
+config MTK_ADSP_IPC
+	tristate "MTK ADSP IPC Protocol driver"
+	depends on MTK_ADSP_MBOX
+	help
+	  Say yes here to add support for the MediaTek ADSP IPC
+	  between host AP (Linux) and the firmware running on ADSP.
+	  ADSP exists on some mtk processors.
+	  Client might use shared memory to exchange information with ADSP side.
diff --git a/drivers/firmware/mediatek/Makefile b/drivers/firmware/mediatek/Makefile
new file mode 100644
index 000000000000..4e840b65650d
--- /dev/null
+++ b/drivers/firmware/mediatek/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_MTK_ADSP_IPC)		+= mtk-adsp-ipc.o
diff --git a/drivers/firmware/mediatek/mtk-adsp-ipc.c b/drivers/firmware/mediatek/mtk-adsp-ipc.c
new file mode 100644
index 000000000000..9c535d2688d9
--- /dev/null
+++ b/drivers/firmware/mediatek/mtk-adsp-ipc.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ * Author: Allen-KH Cheng <allen-kh.cheng at mediatek.com>
+ */
+
+#include <linux/firmware/mediatek/mtk-adsp-ipc.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * mtk_adsp_ipc_send - send ipc cmd to MTK ADSP
+ *
+ * @ipc: ADSP IPC handle
+ * @idx: index of the mailbox channel
+ * @msg: IPC cmd (reply or request)
+ *
+ * Returns zero for success from mbox_send_message
+ * negative value for error
+ */
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t msg)
+{
+	struct mtk_adsp_chan *adsp_chan;
+	int ret;
+
+	if (idx >= MTK_ADSP_MBOX_NUM)
+		return -EINVAL;
+
+	adsp_chan = &ipc->chans[idx];
+	ret = mbox_send_message(adsp_chan->ch, &msg);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * mbox_send_message returns non-negative value on success,
+	 * return zero for success
+	 */
+	return 0;
+}
+EXPORT_SYMBOL(mtk_adsp_ipc_send);
+
+/*
+ * mtk_adsp_ipc_recv - recv callback used by MTK ADSP mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of ADSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void mtk_adsp_ipc_recv(struct mbox_client *c, void *msg)
+{
+	struct mtk_adsp_chan *chan = container_of(c, struct mtk_adsp_chan, cl);
+	struct device *dev = c->dev;
+
+	switch (chan->idx) {
+	case MTK_ADSP_MBOX_REPLY:
+		chan->ipc->ops->handle_reply(chan->ipc);
+		break;
+	case MTK_ADSP_MBOX_REQUEST:
+		chan->ipc->ops->handle_request(chan->ipc);
+		break;
+	default:
+		dev_err(dev, "wrong mbox chan %d\n", chan->idx);
+		break;
+	}
+}
+
+static int mtk_adsp_ipc_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_adsp_ipc *adsp_ipc;
+	struct mtk_adsp_chan *adsp_chan;
+	struct mbox_client *cl;
+	char *chan_name;
+	int ret;
+	int i, j;
+
+	device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+	adsp_ipc = devm_kzalloc(dev, sizeof(*adsp_ipc), GFP_KERNEL);
+	if (!adsp_ipc)
+		return -ENOMEM;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		chan_name = kasprintf(GFP_KERNEL, "mbox%d", i);
+		if (!chan_name) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		adsp_chan = &adsp_ipc->chans[i];
+		cl = &adsp_chan->cl;
+		cl->dev = dev->parent;
+		cl->tx_block = false;
+		cl->knows_txdone = false;
+		cl->tx_prepare = NULL;
+		cl->rx_callback = mtk_adsp_ipc_recv;
+
+		adsp_chan->ipc = adsp_ipc;
+		adsp_chan->idx = i;
+		adsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+		if (IS_ERR(adsp_chan->ch)) {
+			ret = PTR_ERR(adsp_chan->ch);
+			if (ret != -EPROBE_DEFER)
+				dev_err(dev, "Failed to request mbox chan %d ret %d\n",
+					i, ret);
+			goto out_free;
+		}
+
+		dev_dbg(dev, "request mbox chan %s\n", chan_name);
+		kfree(chan_name);
+	}
+
+	adsp_ipc->dev = dev;
+	dev_set_drvdata(dev, adsp_ipc);
+	dev_dbg(dev, "MTK ADSP IPC initialized\n");
+
+	return 0;
+
+out_free:
+	kfree(chan_name);
+out:
+	for (j = 0; j < i; j++) {
+		adsp_chan = &adsp_ipc->chans[j];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return ret;
+}
+
+static int mtk_adsp_ipc_remove(struct platform_device *pdev)
+{
+	struct mtk_adsp_ipc *adsp_ipc = dev_get_drvdata(&pdev->dev);
+	struct mtk_adsp_chan *adsp_chan;
+	int i;
+
+	for (i = 0; i < MTK_ADSP_MBOX_NUM; i++) {
+		adsp_chan = &adsp_ipc->chans[i];
+		mbox_free_channel(adsp_chan->ch);
+	}
+
+	return 0;
+}
+
+static struct platform_driver mtk_adsp_ipc_driver = {
+	.driver = {
+		.name = "mtk-adsp-ipc",
+	},
+	.probe = mtk_adsp_ipc_probe,
+	.remove = mtk_adsp_ipc_remove,
+};
+builtin_platform_driver(mtk_adsp_ipc_driver);
+
+MODULE_AUTHOR("Allen-KH Cheng <allen-kh.cheng at mediatek.com>");
+MODULE_DESCRIPTION("MTK ADSP IPC Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/firmware/mediatek/mtk-adsp-ipc.h b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
new file mode 100644
index 000000000000..28fd313340b8
--- /dev/null
+++ b/include/linux/firmware/mediatek/mtk-adsp-ipc.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ */
+
+#ifndef MTK_ADSP_IPC_H
+#define MTK_ADSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_controller.h>
+#include <linux/mailbox_client.h>
+
+#define MTK_ADSP_IPC_REQ 0
+#define MTK_ADSP_IPC_RSP 1
+#define MTK_ADSP_IPC_OP_REQ 0x1
+#define MTK_ADSP_IPC_OP_RSP 0x2
+
+enum {
+	MTK_ADSP_MBOX_REPLY,
+	MTK_ADSP_MBOX_REQUEST,
+	MTK_ADSP_MBOX_NUM,
+};
+
+struct mtk_adsp_ipc;
+
+struct mtk_adsp_ipc_ops {
+	void (*handle_reply)(struct mtk_adsp_ipc *ipc);
+	void (*handle_request)(struct mtk_adsp_ipc *ipc);
+};
+
+struct mtk_adsp_chan {
+	struct mtk_adsp_ipc *ipc;
+	struct mbox_client cl;
+	struct mbox_chan *ch;
+	char *name;
+	int idx;
+};
+
+struct mtk_adsp_ipc {
+	struct mtk_adsp_chan chans[MTK_ADSP_MBOX_NUM];
+	struct device *dev;
+	struct mtk_adsp_ipc_ops *ops;
+	void *private_data;
+};
+
+static inline void mtk_adsp_ipc_set_data(struct mtk_adsp_ipc *ipc, void *data)
+{
+	if (!ipc)
+		return;
+
+	ipc->private_data = data;
+}
+
+static inline void *mtk_adsp_ipc_get_data(struct mtk_adsp_ipc *ipc)
+{
+	if (!ipc)
+		return NULL;
+
+	return ipc->private_data;
+}
+
+int mtk_adsp_ipc_send(struct mtk_adsp_ipc *ipc, unsigned int idx, uint32_t op);
+
+#endif /* MTK_ADSP_IPC_H */
-- 
2.18.0



From suzuki.poulose at arm.com  Fri Jan 28 03:19:28 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 11:19:28 +0000
Subject: [PATCH v2 1/6] coresight: Add config flag to enable branch
 broadcast
In-Reply-To: <20220113091056.1297982-2-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-2-james.clark@arm.com>
Message-ID: <b3545a88-4743-db95-4676-b0b193cbea78@arm.com>

On 13/01/2022 09:10, James Clark wrote:
> When enabled, all taken branch addresses are output, even if the branch
> was because of a direct branch instruction. This enables reconstruction
> of the program flow without having access to the memory image of the
> code being executed.
> 
> Use bit 8 for the config option which would be the correct bit for
> programming ETMv3. Although branch broadcast can't be enabled on ETMv3
> because it's not in the define ETM3X_SUPPORTED_OPTIONS, using the
> correct bit might help prevent future collisions or allow it to be
> enabled if needed.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-etm-perf.c   |  2 ++
>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 10 ++++++++++
>   include/linux/coresight-pmu.h                      |  2 ++
>   3 files changed, 14 insertions(+)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
> index c039b6ae206f..43bbd5dc3d3b 100644
> --- a/drivers/hwtracing/coresight/coresight-etm-perf.c
> +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
> @@ -52,6 +52,7 @@ static DEFINE_PER_CPU(struct coresight_device *, csdev_src);
>    * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config';
>    * now take them as general formats and apply on all ETMs.
>    */
> +PMU_FORMAT_ATTR(branch_broadcast, "config:"__stringify(ETM_OPT_BRANCH_BROADCAST));
>   PMU_FORMAT_ATTR(cycacc,		"config:" __stringify(ETM_OPT_CYCACC));
>   /* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */
>   PMU_FORMAT_ATTR(contextid1,	"config:" __stringify(ETM_OPT_CTXTID));
> @@ -97,6 +98,7 @@ static struct attribute *etm_config_formats_attr[] = {
>   	&format_attr_sinkid.attr,
>   	&format_attr_preset.attr,
>   	&format_attr_configid.attr,
> +	&format_attr_branch_broadcast.attr,

Does it make sense to hide the option if the bb is not supported ? I 
guess it will be tricky as we don't track the common feature set. So,
that said...

>   	NULL,
>   };
>   
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index bf18128cf5de..04669ecc0efa 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -692,6 +692,16 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   		ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset);
>   	}
>   
> +	/* branch broadcast - enable if selected and supported */
> +	if (attr->config & BIT(ETM_OPT_BRANCH_BROADCAST)) {
> +		if (!drvdata->trcbb) {
> +			ret = -EINVAL;

Should we fail here ? We could simply ignore this and generate the trace 
normally. This would work on a big.LITTLE system with one set missing 
the branch broadcast, while the others support.

Mike,

Does this affect the trace decoding ? As such the OpenCSD should be able
to decode the packets as they appear in the stream. Correct ?

Suzuki


> +			goto out;
> +		} else {
> +			config->cfg |= BIT(ETM4_CFG_BIT_BB);
> +		}
> +	}
> +
>   out:
>   	return ret;
>   }
> diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h
> index 4ac5c081af93..6c2fd6cc5a98 100644
> --- a/include/linux/coresight-pmu.h
> +++ b/include/linux/coresight-pmu.h
> @@ -18,6 +18,7 @@
>    * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
>    * directly use below macros as config bits.
>    */
> +#define ETM_OPT_BRANCH_BROADCAST 8
>   #define ETM_OPT_CYCACC		12
>   #define ETM_OPT_CTXTID		14
>   #define ETM_OPT_CTXTID2		15
> @@ -25,6 +26,7 @@
>   #define ETM_OPT_RETSTK		29
>   
>   /* ETMv4 CONFIGR programming bits for the ETM OPTs */
> +#define ETM4_CFG_BIT_BB         3
>   #define ETM4_CFG_BIT_CYCACC	4
>   #define ETM4_CFG_BIT_CTXTID	6
>   #define ETM4_CFG_BIT_VMID	7



From catalin.marinas at arm.com  Fri Jan 28 03:22:39 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 11:22:39 +0000
Subject: [PATCH V3 RESEND 0/7] coresight: trbe: Workaround Cortex-A510
 erratas
In-Reply-To: <YfPKvsw+fOsJvSm7@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
 <20220127202220.GA2191206@p14s> <YfPKvsw+fOsJvSm7@arm.com>
Message-ID: <YfPR/93To8n7S9Sa@arm.com>

On Fri, Jan 28, 2022 at 10:51:42AM +0000, Catalin Marinas wrote:
> On Thu, Jan 27, 2022 at 01:22:20PM -0700, Mathieu Poirier wrote:
> > On Tue, Jan 25, 2022 at 07:50:30PM +0530, Anshuman Khandual wrote:
> > > Anshuman Khandual (7):
> > >   arm64: Add Cortex-A510 CPU part definition
> > >   arm64: errata: Add detection for TRBE ignored system register writes
> > >   arm64: errata: Add detection for TRBE invalid prohibited states
> > >   arm64: errata: Add detection for TRBE trace data corruption
> > >   coresight: trbe: Work around the ignored system register writes
> > >   coresight: trbe: Work around the invalid prohibited states
> > >   coresight: trbe: Work around the trace data corruption
> > > 
> > >  Documentation/arm64/silicon-errata.rst       |   6 +
> > >  arch/arm64/Kconfig                           |  59 ++++++++++
> > >  arch/arm64/include/asm/cputype.h             |   2 +
> > >  arch/arm64/kernel/cpu_errata.c               |  27 +++++
> > >  arch/arm64/tools/cpucaps                     |   3 +
> > >  drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
> > >  drivers/hwtracing/coresight/coresight-trbe.h |   8 --
> > >  7 files changed, 183 insertions(+), 36 deletions(-)
> > 
> > I have applied this set and sent a pull request to Catalin for the arm64
> > portion.
> 
> Well, I'm happy for the whole series to go in via Greg's tree or however
> the coresight patches go in (that's why I acked them). The last three
> patches depend on the first four, so you might as well send them all
> together. I'd split the series only if there's a conflict with the arm64
> tree (I haven't checked).

I now checked and there's a minor conflict. I can send the arm64 part
from your pull request to Linus tonight and you can send the others via
the usual coresight path.

Thanks.

-- 
Catalin


From suzuki.poulose at arm.com  Fri Jan 28 03:24:14 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 11:24:14 +0000
Subject: [PATCH v2 2/6] coresight: Fail to open with return stacks if they
 are unavailable
In-Reply-To: <20220113091056.1297982-3-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-3-james.clark@arm.com>
Message-ID: <50e5ff63-ae00-f04b-fc5b-f294742cb13a@arm.com>

Hi James

On 13/01/2022 09:10, James Clark wrote:
> Maintain consistency with the other options by failing to open when they
> aren't supported. For example ETM_OPT_TS, ETM_OPT_CTXTID2 and the newly
> added ETM_OPT_BRANCH_BROADCAST all return with -EINVAL if they are
> requested but not supported by hardware.

Looking at this again (with similar comment to the Branch Broadcast),
won't it disable using retstack on all CPUs, even when some of them
support it ?

i.e., CPU0 - supports retstack, CPU1 - doesn't

A perf run with retstack will fail, as CPU1 doesn't support it (even
though we advertise it, unconditionally).

So, if we ignore the failure, this would still allow CPU0 to use
the feature and as long as the OpenCSD is able to decode the trace
we should ignore the failure ?

I think we may also need to tune the etm4x_enable_hw() to skip
updating the TRCCONFIGR with features not supported by the ETM

Suzuki


> 
> The consequence of not doing this is that the user may not be
> aware that they are not enabling the feature as it is silently disabled.
> 
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>   drivers/hwtracing/coresight/coresight-etm4x-core.c | 13 +++++++++----
>   1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 04669ecc0efa..a93c1a5fe045 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -674,10 +674,15 @@ static int etm4_parse_event_config(struct coresight_device *csdev,
>   	}
>   
>   	/* return stack - enable if selected and supported */
> -	if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack)
> -		/* bit[12], Return stack enable bit */
> -		config->cfg |= BIT(12);
> -
> +	if (attr->config & BIT(ETM_OPT_RETSTK)) {
> +		if (!drvdata->retstack) {
> +			ret = -EINVAL;
> +			goto out;
> +		} else {
> +			/* bit[12], Return stack enable bit */
> +			config->cfg |= BIT(12);
> +		}
> +	}
>   	/*
>   	 * Set any selected configuration and preset.
>   	 *



From suzuki.poulose at arm.com  Fri Jan 28 03:25:24 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 11:25:24 +0000
Subject: [PATCH v2 3/6] perf cs-etm: Update deduction of TRCCONFIGR
 register for branch broadcast
In-Reply-To: <20220113091056.1297982-4-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-4-james.clark@arm.com>
Message-ID: <25b85560-dd95-2569-d1bc-872902d6343f@arm.com>

On 13/01/2022 09:10, James Clark wrote:
> Now that a config flag for branch broadcast has been added, take it into
> account when trying to deduce what the driver would have programmed the
> TRCCONFIGR register to.
> 
> Reviewed-by: Leo Yan <leo.yan at linaro.org>
> Signed-off-by: James Clark <james.clark at arm.com>
> ---
>   tools/include/linux/coresight-pmu.h | 2 ++
>   tools/perf/arch/arm/util/cs-etm.c   | 3 +++
>   2 files changed, 5 insertions(+)
> 
> diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h
> index 4ac5c081af93..6c2fd6cc5a98 100644
> --- a/tools/include/linux/coresight-pmu.h
> +++ b/tools/include/linux/coresight-pmu.h
> @@ -18,6 +18,7 @@
>    * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and
>    * directly use below macros as config bits.
>    */
> +#define ETM_OPT_BRANCH_BROADCAST 8
>   #define ETM_OPT_CYCACC		12
>   #define ETM_OPT_CTXTID		14
>   #define ETM_OPT_CTXTID2		15
> @@ -25,6 +26,7 @@
>   #define ETM_OPT_RETSTK		29
>   
>   /* ETMv4 CONFIGR programming bits for the ETM OPTs */
> +#define ETM4_CFG_BIT_BB         3
>   #define ETM4_CFG_BIT_CYCACC	4
>   #define ETM4_CFG_BIT_CTXTID	6
>   #define ETM4_CFG_BIT_VMID	7
> diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c
> index 293a23bf8be3..c7ef4e9b4a3a 100644
> --- a/tools/perf/arch/arm/util/cs-etm.c
> +++ b/tools/perf/arch/arm/util/cs-etm.c
> @@ -527,6 +527,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
>   	if (config_opts & BIT(ETM_OPT_CTXTID2))
>   		config |= BIT(ETM4_CFG_BIT_VMID) |
>   			  BIT(ETM4_CFG_BIT_VMID_OPT);
> +	if (config_opts & BIT(ETM_OPT_BRANCH_BROADCAST))
> +		config |= BIT(ETM4_CFG_BIT_BB);
> +
>   	return config;

Reviewed-by: Suzuki K Poulose <suzuki.poulose at arm.com>

>   }
>   



From suzuki.poulose at arm.com  Fri Jan 28 03:26:25 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 11:26:25 +0000
Subject: [PATCH v2 4/6] Documentation: coresight: Turn numbered
 subsections into real subsections
In-Reply-To: <20220113091056.1297982-5-james.clark@arm.com>
References: <20220113091056.1297982-1-james.clark@arm.com>
 <20220113091056.1297982-5-james.clark@arm.com>
Message-ID: <e84cf689-10a5-c63f-b574-9da682da034e@arm.com>

On 13/01/2022 09:10, James Clark wrote:
> This is to allow them to be referenced in a later commit. There was
> also a mistake where sysFS was introduced as section 2, but numbered
> as section 1. And vice versa for 'Using perf framework'. This can't
> happen with unnumbered sections.
> 
> Signed-off-by: James Clark <james.clark at arm.com>

Looks good to me



From liang.yang at amlogic.com  Fri Jan 28 03:32:35 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:35 +0800
Subject: [PATCH v2 0/2] refine the NFC clock framework
Message-ID: <20220128113237.39996-1-liang.yang@amlogic.com>

Background firstly, 
EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
bit6~7 is the mux for fix pll and xtal.
Previously a common MMC sub clock framework is implemented and shared by EMMC and
NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
exclusive. see the link:
[https://lore.kernel.org/all/1jy23226sa.fsf at starbuckisacylon.baylibre.com/]
Now we plan to abandon common mmc sub clock framework and recovery the series.

Changes since v1 [2]
 - use clk_parent_data instead of parent_names
 - define a reg resource instead of sd_emmc_c_clkc 
 
[1]
https://lore.kernel.org/r/20220106033130.37623-1-liang.yang at amlogic.com
https://lore.kernel.org/r/20220106032504.23310-1-liang.yang at amlogic.com
Liang Yang (2):
  mtd: rawnand: meson: discard the common MMC sub clock framework
  dt-bindings: nand: meson: refine Amlogic NAND controller driver

 .../bindings/mtd/amlogic,meson-nand.txt       |  60 -------
 .../bindings/mtd/amlogic,meson-nand.yaml      |  70 ++++++++
 drivers/mtd/nand/raw/meson_nand.c             | 161 ++++++++++--------
 3 files changed, 159 insertions(+), 132 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml

-- 
2.34.1



From liang.yang at amlogic.com  Fri Jan 28 03:32:36 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:36 +0800
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub clock
 framework
In-Reply-To: <20220128113237.39996-1-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
Message-ID: <20220128113237.39996-2-liang.yang@amlogic.com>

EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
bit6~7 is the mux for fix pll and xtal.
Previously a common MMC sub clock framework is implemented and shared by EMMC and
NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
exclusive.

Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
 1 file changed, 89 insertions(+), 72 deletions(-)

diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
index ac3be92872d0..f6a3d5c2ea1c 100644
--- a/drivers/mtd/nand/raw/meson_nand.c
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -2,7 +2,7 @@
 /*
  * Amlogic Meson Nand Flash Controller Driver
  *
- * Copyright (c) 2018 Amlogic, inc.
+ * Copyright (c) 2018-2021 Amlogic, inc.
  * Author: Liang Yang <liang.yang at amlogic.com>
  */
 
@@ -10,6 +10,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/mtd/rawnand.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mfd/syscon.h>
@@ -19,6 +20,7 @@
 #include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_address.h>
 #include <linux/sched/task_stack.h>
 
 #define NFC_REG_CMD		0x00
@@ -104,6 +106,9 @@
 
 #define PER_INFO_BYTE		8
 
+#define CLK_DIV_SHIFT		0
+#define CLK_DIV_WIDTH		6
+
 struct meson_nfc_nand_chip {
 	struct list_head node;
 	struct nand_chip nand;
@@ -151,15 +156,17 @@ struct meson_nfc {
 	struct nand_controller controller;
 	struct clk *core_clk;
 	struct clk *device_clk;
-	struct clk *phase_tx;
-	struct clk *phase_rx;
+	struct clk *nand_clk;
+	struct clk_divider nand_divider;
 
 	unsigned long clk_rate;
 	u32 bus_timing;
 
 	struct device *dev;
-	void __iomem *reg_base;
-	struct regmap *reg_clk;
+	struct {
+		void __iomem *reg_base;
+		void __iomem *sd_emmc_clock;
+	} res;
 	struct completion completion;
 	struct list_head chips;
 	const struct meson_nfc_data *data;
@@ -244,8 +251,8 @@ static void meson_nfc_select_chip(struct nand_chip *nand, int chip)
 	}
 	if (nfc->bus_timing != meson_chip->bus_timing) {
 		value = (NFC_CLK_CYCLE - 1) | (meson_chip->bus_timing << 5);
-		writel(value, nfc->reg_base + NFC_REG_CFG);
-		writel((1 << 31), nfc->reg_base + NFC_REG_CMD);
+		writel(value, nfc->res.reg_base + NFC_REG_CFG);
+		writel((1 << 31), nfc->res.reg_base + NFC_REG_CMD);
 		nfc->bus_timing =  meson_chip->bus_timing;
 	}
 }
@@ -253,13 +260,13 @@ static void meson_nfc_select_chip(struct nand_chip *nand, int chip)
 static void meson_nfc_cmd_idle(struct meson_nfc *nfc, u32 time)
 {
 	writel(nfc->param.chip_select | NFC_CMD_IDLE | (time & 0x3ff),
-	       nfc->reg_base + NFC_REG_CMD);
+	       nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_cmd_seed(struct meson_nfc *nfc, u32 seed)
 {
 	writel(NFC_CMD_SEED | (0xc2 + (seed & 0x7fff)),
-	       nfc->reg_base + NFC_REG_CMD);
+	       nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
@@ -276,7 +283,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
 	if (raw) {
 		len = mtd->writesize + mtd->oobsize;
 		cmd = (len & GENMASK(5, 0)) | scrambler | DMA_DIR(dir);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 		return;
 	}
 
@@ -285,7 +292,7 @@ static void meson_nfc_cmd_access(struct nand_chip *nand, int raw, bool dir,
 	cmd = CMDRWGEN(DMA_DIR(dir), scrambler, bch,
 		       NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);
 
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 }
 
 static void meson_nfc_drain_cmd(struct meson_nfc *nfc)
@@ -312,7 +319,7 @@ static int meson_nfc_wait_cmd_finish(struct meson_nfc *nfc,
 	int ret;
 
 	/* wait cmd fifo is empty */
-	ret = readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size,
+	ret = readl_relaxed_poll_timeout(nfc->res.reg_base + NFC_REG_CMD, cmd_size,
 					 !NFC_CMD_GET_SIZE(cmd_size),
 					 10, timeout_ms * 1000);
 	if (ret)
@@ -396,16 +403,16 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms)
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, CMD_FIFO_EMPTY_TIMEOUT);
 
-	cfg = readl(nfc->reg_base + NFC_REG_CFG);
+	cfg = readl(nfc->res.reg_base + NFC_REG_CFG);
 	cfg |= NFC_RB_IRQ_EN;
-	writel(cfg, nfc->reg_base + NFC_REG_CFG);
+	writel(cfg, nfc->res.reg_base + NFC_REG_CFG);
 
 	reinit_completion(&nfc->completion);
 
 	/* use the max erase time as the maximum clock for waiting R/B */
 	cmd = NFC_CMD_RB | NFC_CMD_RB_INT
 		| nfc->param.chip_select | nfc->timing.tbers_max;
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	ret = wait_for_completion_timeout(&nfc->completion,
 					  msecs_to_jiffies(timeout_ms));
@@ -485,10 +492,10 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
 		return ret;
 	}
 	cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr);
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr);
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	if (infobuf) {
 		nfc->iaddr = dma_map_single(nfc->dev, infobuf, infolen, dir);
@@ -500,10 +507,10 @@ static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
 			return ret;
 		}
 		cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 		cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr);
-		writel(cmd, nfc->reg_base + NFC_REG_CMD);
+		writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 	}
 
 	return ret;
@@ -537,7 +544,7 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len)
 		goto out;
 
 	cmd = NFC_CMD_N2M | (len & GENMASK(5, 0));
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, 1000);
@@ -561,7 +568,7 @@ static int meson_nfc_write_buf(struct nand_chip *nand, u8 *buf, int len)
 		return ret;
 
 	cmd = NFC_CMD_M2N | (len & GENMASK(5, 0));
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 
 	meson_nfc_drain_cmd(nfc);
 	meson_nfc_wait_cmd_finish(nfc, 1000);
@@ -610,11 +617,11 @@ static int meson_nfc_rw_cmd_prepare_and_execute(struct nand_chip *nand,
 
 	for (i = 0; i < cmd_num; i++)
 		writel_relaxed(nfc->cmdfifo.cmd[i],
-			       nfc->reg_base + NFC_REG_CMD);
+			       nfc->res.reg_base + NFC_REG_CMD);
 
 	if (in) {
 		nfc->cmdfifo.rw.cmd1 = cs | NFC_CMD_CLE | NAND_CMD_READSTART;
-		writel(nfc->cmdfifo.rw.cmd1, nfc->reg_base + NFC_REG_CMD);
+		writel(nfc->cmdfifo.rw.cmd1, nfc->res.reg_base + NFC_REG_CMD);
 		meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tR_max));
 	} else {
 		meson_nfc_cmd_idle(nfc, nfc->timing.tadl);
@@ -660,7 +667,7 @@ static int meson_nfc_write_page_sub(struct nand_chip *nand,
 	}
 
 	cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
-	writel(cmd, nfc->reg_base + NFC_REG_CMD);
+	writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 	meson_nfc_queue_rb(nfc, PSEC_TO_MSEC(sdr->tPROG_max));
 
 	meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE);
@@ -912,7 +919,7 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
 		case NAND_OP_CMD_INSTR:
 			cmd = nfc->param.chip_select | NFC_CMD_CLE;
 			cmd |= instr->ctx.cmd.opcode & 0xff;
-			writel(cmd, nfc->reg_base + NFC_REG_CMD);
+			writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 			meson_nfc_cmd_idle(nfc, delay_idle);
 			break;
 
@@ -920,7 +927,7 @@ static int meson_nfc_exec_op(struct nand_chip *nand,
 			for (i = 0; i < instr->ctx.addr.naddrs; i++) {
 				cmd = nfc->param.chip_select | NFC_CMD_ALE;
 				cmd |= instr->ctx.addr.addrs[i] & 0xff;
-				writel(cmd, nfc->reg_base + NFC_REG_CMD);
+				writel(cmd, nfc->res.reg_base + NFC_REG_CMD);
 			}
 			meson_nfc_cmd_idle(nfc, delay_idle);
 			break;
@@ -988,6 +995,8 @@ static const struct mtd_ooblayout_ops meson_ooblayout_ops = {
 static int meson_nfc_clk_init(struct meson_nfc *nfc)
 {
 	int ret;
+	struct clk_init_data init = {0};
+	struct clk_parent_data nfc_divider_parent_data[1];
 
 	/* request core clock */
 	nfc->core_clk = devm_clk_get(nfc->dev, "core");
@@ -1002,21 +1011,26 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		return PTR_ERR(nfc->device_clk);
 	}
 
-	nfc->phase_tx = devm_clk_get(nfc->dev, "tx");
-	if (IS_ERR(nfc->phase_tx)) {
-		dev_err(nfc->dev, "failed to get TX clk\n");
-		return PTR_ERR(nfc->phase_tx);
-	}
-
-	nfc->phase_rx = devm_clk_get(nfc->dev, "rx");
-	if (IS_ERR(nfc->phase_rx)) {
-		dev_err(nfc->dev, "failed to get RX clk\n");
-		return PTR_ERR(nfc->phase_rx);
-	}
+	init.name = devm_kstrdup(nfc->dev, "nfc#div", GFP_KERNEL);
+	init.ops = &clk_divider_ops;
+	nfc_divider_parent_data[0].fw_name = __clk_get_name(nfc->device_clk);
+	init.parent_data = nfc_divider_parent_data;
+	init.num_parents = 1;
+	nfc->nand_divider.reg = nfc->res.sd_emmc_clock;
+	nfc->nand_divider.shift = CLK_DIV_SHIFT;
+	nfc->nand_divider.width = CLK_DIV_WIDTH;
+	nfc->nand_divider.hw.init = &init;
+	nfc->nand_divider.flags = CLK_DIVIDER_ONE_BASED |
+				  CLK_DIVIDER_ROUND_CLOSEST |
+				  CLK_DIVIDER_ALLOW_ZERO;
+
+	nfc->nand_clk = devm_clk_register(nfc->dev, &nfc->nand_divider.hw);
+	if (IS_ERR(nfc->nand_clk))
+		return PTR_ERR(nfc->nand_clk);
 
 	/* init SD_EMMC_CLOCK to sane defaults w/min clock rate */
-	regmap_update_bits(nfc->reg_clk,
-			   0, CLK_SELECT_NAND, CLK_SELECT_NAND);
+	writel(CLK_SELECT_NAND | readl(nfc->res.sd_emmc_clock),
+	       nfc->res.sd_emmc_clock);
 
 	ret = clk_prepare_enable(nfc->core_clk);
 	if (ret) {
@@ -1030,29 +1044,21 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 		goto err_device_clk;
 	}
 
-	ret = clk_prepare_enable(nfc->phase_tx);
-	if (ret) {
-		dev_err(nfc->dev, "failed to enable TX clock\n");
-		goto err_phase_tx;
-	}
-
-	ret = clk_prepare_enable(nfc->phase_rx);
+	ret = clk_prepare_enable(nfc->nand_clk);
 	if (ret) {
-		dev_err(nfc->dev, "failed to enable RX clock\n");
-		goto err_phase_rx;
+		dev_err(nfc->dev, "pre enable NFC divider fail\n");
+		goto err_nand_clk;
 	}
 
 	ret = clk_set_rate(nfc->device_clk, 24000000);
 	if (ret)
-		goto err_disable_rx;
+		goto err_disable_clk;
 
 	return 0;
 
-err_disable_rx:
-	clk_disable_unprepare(nfc->phase_rx);
-err_phase_rx:
-	clk_disable_unprepare(nfc->phase_tx);
-err_phase_tx:
+err_disable_clk:
+	clk_disable_unprepare(nfc->nand_clk);
+err_nand_clk:
 	clk_disable_unprepare(nfc->device_clk);
 err_device_clk:
 	clk_disable_unprepare(nfc->core_clk);
@@ -1061,8 +1067,7 @@ static int meson_nfc_clk_init(struct meson_nfc *nfc)
 
 static void meson_nfc_disable_clk(struct meson_nfc *nfc)
 {
-	clk_disable_unprepare(nfc->phase_rx);
-	clk_disable_unprepare(nfc->phase_tx);
+	clk_disable_unprepare(nfc->nand_clk);
 	clk_disable_unprepare(nfc->device_clk);
 	clk_disable_unprepare(nfc->core_clk);
 }
@@ -1339,12 +1344,12 @@ static irqreturn_t meson_nfc_irq(int irq, void *id)
 	struct meson_nfc *nfc = id;
 	u32 cfg;
 
-	cfg = readl(nfc->reg_base + NFC_REG_CFG);
+	cfg = readl(nfc->res.reg_base + NFC_REG_CFG);
 	if (!(cfg & NFC_RB_IRQ_EN))
 		return IRQ_NONE;
 
 	cfg &= ~(NFC_RB_IRQ_EN);
-	writel(cfg, nfc->reg_base + NFC_REG_CFG);
+	writel(cfg, nfc->res.reg_base + NFC_REG_CFG);
 
 	complete(&nfc->completion);
 	return IRQ_HANDLED;
@@ -1370,11 +1375,31 @@ static const struct of_device_id meson_nfc_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, meson_nfc_id_table);
 
+static int meson_nfc_reg_resource(struct device *dev, struct meson_nfc *nfc)
+{
+	struct resource res;
+	void __iomem *base[2];
+	struct device_node *node = dev->of_node;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (of_address_to_resource(node, i, &res))
+			return -ENOENT;
+
+		base[i] = devm_ioremap_resource(dev, &res);
+		if (IS_ERR(base))
+			return PTR_ERR(base);
+	}
+	nfc->res.reg_base = base[0];
+	nfc->res.sd_emmc_clock = base[1];
+
+	return 0;
+}
+
 static int meson_nfc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct meson_nfc *nfc;
-	struct resource *res;
 	int ret, irq;
 
 	nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL);
@@ -1388,20 +1413,12 @@ static int meson_nfc_probe(struct platform_device *pdev)
 	nand_controller_init(&nfc->controller);
 	INIT_LIST_HEAD(&nfc->chips);
 	init_completion(&nfc->completion);
-
 	nfc->dev = dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	nfc->reg_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(nfc->reg_base))
-		return PTR_ERR(nfc->reg_base);
-
-	nfc->reg_clk =
-		syscon_regmap_lookup_by_phandle(dev->of_node,
-						"amlogic,mmc-syscon");
-	if (IS_ERR(nfc->reg_clk)) {
-		dev_err(dev, "Failed to lookup clock base\n");
-		return PTR_ERR(nfc->reg_clk);
+	ret = meson_nfc_reg_resource(dev, nfc);
+	if (ret) {
+		dev_err(dev, "Failed to get reg resource\n");
+		return ret;
 	}
 
 	irq = platform_get_irq(pdev, 0);
@@ -1414,7 +1431,7 @@ static int meson_nfc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	writel(0, nfc->reg_base + NFC_REG_CFG);
+	writel(0, nfc->res.reg_base + NFC_REG_CFG);
 	ret = devm_request_irq(dev, irq, meson_nfc_irq, 0, dev_name(dev), nfc);
 	if (ret) {
 		dev_err(dev, "failed to request NFC IRQ\n");
-- 
2.34.1



From liang.yang at amlogic.com  Fri Jan 28 03:32:37 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 19:32:37 +0800
Subject: [PATCH v2 2/2] dt-bindings: nand: meson: refine Amlogic NAND
 controller driver
In-Reply-To: <20220128113237.39996-1-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
Message-ID: <20220128113237.39996-3-liang.yang@amlogic.com>

convert txt to yaml and refine the meson NFC clock document.

Signed-off-by: Liang Yang <liang.yang at amlogic.com>
---
 .../bindings/mtd/amlogic,meson-nand.txt       | 60 ----------------
 .../bindings/mtd/amlogic,meson-nand.yaml      | 70 +++++++++++++++++++
 2 files changed, 70 insertions(+), 60 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
 create mode 100644 Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml

diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
deleted file mode 100644
index 5794ab1147c1..000000000000
--- a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
-
-This file documents the properties in addition to those available in
-the MTD NAND bindings.
-
-Required properties:
-- compatible : contains one of:
-  - "amlogic,meson-gxl-nfc"
-  - "amlogic,meson-axg-nfc"
-- clocks     :
-	A list of phandle + clock-specifier pairs for the clocks listed
-	in clock-names.
-
-- clock-names: Should contain the following:
-	"core" - NFC module gate clock
-	"device" - device clock from eMMC sub clock controller
-	"rx" - rx clock phase
-	"tx" - tx clock phase
-
-- amlogic,mmc-syscon	: Required for NAND clocks, it's shared with SD/eMMC
-				controller port C
-
-Optional children nodes:
-Children nodes represent the available nand chips.
-
-Other properties:
-see Documentation/devicetree/bindings/mtd/nand-controller.yaml for generic bindings.
-
-Example demonstrate on AXG SoC:
-
-	sd_emmc_c_clkc: mmc at 7000 {
-		compatible = "amlogic,meson-axg-mmc-clkc", "syscon";
-		reg = <0x0 0x7000 0x0 0x800>;
-	};
-
-	nand-controller at 7800 {
-		compatible = "amlogic,meson-axg-nfc";
-		reg = <0x0 0x7800 0x0 0x100>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-		interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
-
-		clocks = <&clkc CLKID_SD_EMMC_C>,
-			<&sd_emmc_c_clkc CLKID_MMC_DIV>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_RX>,
-			<&sd_emmc_c_clkc CLKID_MMC_PHASE_TX>;
-		clock-names = "core", "device", "rx", "tx";
-		amlogic,mmc-syscon = <&sd_emmc_c_clkc>;
-
-		pinctrl-names = "default";
-		pinctrl-0 = <&nand_pins>;
-
-		nand at 0 {
-			reg = <0>;
-			#address-cells = <1>;
-			#size-cells = <1>;
-
-			nand-on-flash-bbt;
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
new file mode 100644
index 000000000000..671f0a8fdc7c
--- /dev/null
+++ b/Documentation/devicetree/bindings/mtd/amlogic,meson-nand.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,mmc-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic NAND Flash Controller (NFC) for GXBB/GXL/AXG family SoCs
+
+maintainers:
+  - liang.yang at amlogic.com
+
+properties:
+  compatible:
+    enum:
+      - "amlogic,meson-gxl-nfc"
+      - "amlogic,meson-axg-nfc"
+
+  reg:
+    maxItems: 2
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: "core", "device"
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    nand-controller at 7800 {
+	compatible = "amlogic,meson-axg-nfc";
+	reg = <0x0 0x7800 0x0 0x100>,
+	      <0x0 0x7000 0x0 0x1>;
+	#address-cells = <1>;
+	#size-cells = <0>;
+	interrupts = <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>;
+
+	clocks = <&clkc CLKID_SD_EMMC_C>,
+		<&clkc CLKID_FCLK_DIV2>;
+	clock-names = "core", "device";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&nand_pins>;
+
+	nand at 0 {
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		nand-on-flash-bbt;
+	};
+     };
+
+...
\ No newline at end of file
-- 
2.34.1



From miquel.raynal at bootlin.com  Fri Jan 28 03:40:36 2022
From: miquel.raynal at bootlin.com (Miquel Raynal)
Date: Fri, 28 Jan 2022 12:40:36 +0100
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub
 clock framework
In-Reply-To: <20220128113237.39996-2-liang.yang@amlogic.com>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
 <20220128113237.39996-2-liang.yang@amlogic.com>
Message-ID: <20220128124036.25fe0539@xps13>

Hi Liang,

liang.yang at amlogic.com wrote on Fri, 28 Jan 2022 19:32:36 +0800:

> EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is

have

> defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
> bit6~7 is the mux for fix pll and xtal.

> Previously a common MMC sub clock framework is implemented and shared by EMMC and

I believe you meant that this hasa already been contributed? I would
then rephrase with:

A common MMC and NAND sub-clock has been implemented and can be used by
the eMMC and NAND controller (which are mutually exclusive anyway).

Let's use this new clock.

> NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
> exclusive.
> 
> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997

No change Ids.

> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
> ---
>  drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
>  1 file changed, 89 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
> index ac3be92872d0..f6a3d5c2ea1c 100644
> --- a/drivers/mtd/nand/raw/meson_nand.c
> +++ b/drivers/mtd/nand/raw/meson_nand.c
> @@ -2,7 +2,7 @@
>  /*
>   * Amlogic Meson Nand Flash Controller Driver
>   *
> - * Copyright (c) 2018 Amlogic, inc.
> + * Copyright (c) 2018-2021 Amlogic, inc.

Please don't.

>   * Author: Liang Yang <liang.yang at amlogic.com>
>   */
>  
> @@ -10,6 +10,7 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/interrupt.h>
>  #include <linux/clk.h>
> +#include <linux/clk-provider.h>
>  #include <linux/mtd/rawnand.h>
>  #include <linux/mtd/mtd.h>
>  #include <linux/mfd/syscon.h>
> @@ -19,6 +20,7 @@
>  #include <linux/iopoll.h>
>  #include <linux/of.h>
>  #include <linux/of_device.h>
> +#include <linux/of_address.h>
>  #include <linux/sched/task_stack.h>
>  
>  #define NFC_REG_CMD		0x00
> @@ -104,6 +106,9 @@
>  
>  #define PER_INFO_BYTE		8
>  
> +#define CLK_DIV_SHIFT		0
> +#define CLK_DIV_WIDTH		6
> +
>  struct meson_nfc_nand_chip {
>  	struct list_head node;
>  	struct nand_chip nand;
> @@ -151,15 +156,17 @@ struct meson_nfc {
>  	struct nand_controller controller;
>  	struct clk *core_clk;
>  	struct clk *device_clk;
> -	struct clk *phase_tx;
> -	struct clk *phase_rx;
> +	struct clk *nand_clk;
> +	struct clk_divider nand_divider;
>  
>  	unsigned long clk_rate;
>  	u32 bus_timing;
>  
>  	struct device *dev;
> -	void __iomem *reg_base;
> -	struct regmap *reg_clk;
> +	struct {
> +		void __iomem *reg_base;
> +		void __iomem *sd_emmc_clock;
> +	} res;

Please split your commit: first the mechanical changes, then the use of
the new area or something like that.

Otherwise there are too many lines changed, I can't spot where it is
interesting.

Thanks,
Miqu?l


From stefan.wahren at i2se.com  Fri Jan 28 03:51:10 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Fri, 28 Jan 2022 12:51:10 +0100
Subject: [PATCH] vchiq-mmal: Remove redundant 'flush_workqueue()' calls
In-Reply-To: <20220128070330.GD1951@kadam>
References: <20220127014432.1185206-1-chi.minghao@zte.com.cn>
 <fdbe3eaf-c737-0714-6b54-8a7cdbe38a0c@i2se.com> <20220128070330.GD1951@kadam>
Message-ID: <fa3e33a5-0940-c9e3-07c4-adef1f03e212@i2se.com>

Am 28.01.22 um 08:03 schrieb Dan Carpenter:
> On Thu, Jan 27, 2022 at 01:35:09PM +0100, Stefan Wahren wrote:
>> Hi,
>>
>> Am 27.01.22 um 02:44 schrieb cgel.zte at gmail.com:
>>> From: "Minghao Chi (CGEL ZTE)" <chi.minghao at zte.com.cn>
>>>
>>> 'destroy_workqueue()' already drains the queue before destroying it,
>>> so there is no need to flush it explicitly.
>>>
>>> Remove the redundant 'flush_workqueue()' calls.
>> are you sure that drain_workqueue() is the same as flush_workqueue()?
> drain_workqueue() calls flush_workqueue() repeatedly.

sorry, i overlooked this

I'm fine with the patch

>
> regards,
> dan carpenter
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From shawnguo at kernel.org  Fri Jan 28 03:58:44 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 19:58:44 +0800
Subject: [PATCH v8 6/7] ARM: dts: imx: Add i.MXRT1050-EVK support
In-Reply-To: <20220111215415.2075257-7-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-7-Mr.Bossman075@gmail.com>
Message-ID: <20220128115844.GK4686@dragon>

On Tue, Jan 11, 2022 at 04:54:14PM -0500, Jesse Taube wrote:
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> The NXP i.MXRT1050 Evaluation Kit (EVK) provides a platform for rapid
> evaluation of the i.MXRT, which features NXP's implementation of the Arm
> Cortex-M7 core.
> 
> The EVK provides 32 MB SDRAM, 64 MB Quad SPI flash, Micro SD card socket,
> USB 2.0 OTG.
> 
> This patch aims to support the preliminary booting up features
> as follows:
> GPIO
> LPUART
> SD/MMC
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> [Jesse: Add clock-parents, edma, usdhc, anatop, remove old pinctl]
> ---
> V1->V2:
> * dtsi: Add clock parent definitions
> * dtsi: Change hex values to lowercase
> * dtsi: Move anatop definition from driver
> * dts: Remove unused pin controll (semc)
> * dts: Use moved pin controll header
> * Move aliases from dtsi to dts
> * Change commit description
> * Change licence to "GPL-2.0+ OR MIT"
> V2->V3:
> * Remove bootargs, comments, unused container
> * Remove unnecessary new lines
> * Rename imxrt to imxrt1050 for seiral and mmc
> * GPT uses own clock
> * fix memory at 0
> * Change GPT compatible handles
> V3->V4:
> * Remove "fsl,imx-osc"
> * Add space on serial compatible
> * Change "iomuxc@" to "pinctrl@"
> * Change "ccm@" to "clock-controller@"
> * Change "fsl,imxrt-gpio" to "fsl,imxrt1050-gpio"
> V4->V5:
> * Nothing done
> V5->V6:
> * Nothing done
> V6->V7:
> * Add fixed clock for GPT
> * Fix lpuart compatible
> * Add usdhc compatible
> V7->V8:
> * Nothing done
> ---
>  arch/arm/boot/dts/Makefile          |   2 +
>  arch/arm/boot/dts/imxrt1050-evk.dts |  72 +++++++++++++
>  arch/arm/boot/dts/imxrt1050.dtsi    | 160 ++++++++++++++++++++++++++++
>  3 files changed, 234 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imxrt1050-evk.dts
>  create mode 100644 arch/arm/boot/dts/imxrt1050.dtsi
> 
> diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
> index 0de64f237cd8..07acd6189cae 100644
> --- a/arch/arm/boot/dts/Makefile
> +++ b/arch/arm/boot/dts/Makefile
> @@ -723,6 +723,8 @@ dtb-$(CONFIG_SOC_IMX7D) += \
>  dtb-$(CONFIG_SOC_IMX7ULP) += \
>  	imx7ulp-com.dtb \
>  	imx7ulp-evk.dtb
> +dtb-$(CONFIG_SOC_IMXRT) += \
> +	imxrt1050-evk.dtb
>  dtb-$(CONFIG_SOC_LS1021A) += \
>  	ls1021a-moxa-uc-8410a.dtb \
>  	ls1021a-qds.dtb \
> diff --git a/arch/arm/boot/dts/imxrt1050-evk.dts b/arch/arm/boot/dts/imxrt1050-evk.dts
> new file mode 100644
> index 000000000000..6a9c10decf52
> --- /dev/null
> +++ b/arch/arm/boot/dts/imxrt1050-evk.dts
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) 2019
> + * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
> + */
> +
> +/dts-v1/;
> +#include "imxrt1050.dtsi"
> +#include "imxrt1050-pinfunc.h"
> +
> +/ {
> +	model = "NXP IMXRT1050-evk board";
> +	compatible = "fsl,imxrt1050-evk", "fsl,imxrt1050";
> +
> +	chosen {
> +		stdout-path = &lpuart1;
> +	};
> +
> +	aliases {
> +		gpio0 = &gpio1;
> +		gpio1 = &gpio2;
> +		gpio2 = &gpio3;
> +		gpio3 = &gpio4;
> +		gpio4 = &gpio5;
> +		mmc0 = &usdhc1;
> +		serial0 = &lpuart1;
> +	};
> +
> +	memory at 80000000 {
> +		device_type = "memory";
> +		reg = <0x80000000 0x2000000>;
> +	};
> +};
> +
> +&lpuart1 {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_lpuart1>;
> +	status = "okay";
> +};
> +
> +&iomuxc {
> +	pinctrl-names = "default";
> +	pinctrl_lpuart1: lpuart1grp {
> +		fsl,pins = <
> +			MXRT1050_IOMUXC_GPIO_AD_B0_12_LPUART1_TXD	0xf1
> +			MXRT1050_IOMUXC_GPIO_AD_B0_13_LPUART1_RXD	0xf1
> +		>;
> +	};
> +
> +	pinctrl_usdhc0: usdhc0grp {
> +		fsl,pins = <
> +			MXRT1050_IOMUXC_GPIO_B1_12_USDHC1_CD_B		0x1B000
> +			MXRT1050_IOMUXC_GPIO_B1_14_USDHC1_VSELECT	0xB069
> +			MXRT1050_IOMUXC_GPIO_SD_B0_00_USDHC1_CMD	0x17061
> +			MXRT1050_IOMUXC_GPIO_SD_B0_01_USDHC1_CLK	0x17061
> +			MXRT1050_IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3	0x17061
> +			MXRT1050_IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2	0x17061
> +			MXRT1050_IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1	0x17061
> +			MXRT1050_IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0	0x17061
> +		>;
> +	};
> +};
> +
> +&usdhc1 {
> +	pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep";
> +	pinctrl-0 = <&pinctrl_usdhc0>;
> +	pinctrl-1 = <&pinctrl_usdhc0>;
> +	pinctrl-2 = <&pinctrl_usdhc0>;
> +	pinctrl-3 = <&pinctrl_usdhc0>;
> +	cd-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
> +	status = "okay";
> +};
> diff --git a/arch/arm/boot/dts/imxrt1050.dtsi b/arch/arm/boot/dts/imxrt1050.dtsi
> new file mode 100644
> index 000000000000..77b911b06041
> --- /dev/null
> +++ b/arch/arm/boot/dts/imxrt1050.dtsi
> @@ -0,0 +1,160 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Copyright (C) 2019
> + * Author(s): Giulio Benetti <giulio.benetti at benettiengineering.com>
> + */
> +
> +#include "armv7-m.dtsi"
> +#include <dt-bindings/interrupt-controller/arm-gic.h>
> +#include <dt-bindings/clock/imxrt1050-clock.h>

As this introduces a cross tree dependency (between clk and imx), we may
need to wait for clock change land first.

Shawn

> +#include <dt-bindings/gpio/gpio.h>
> +
> +/ {
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +
> +	clocks {
> +		osc: osc {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <24000000>;
> +		};
> +
> +		osc3M: osc3M {
> +			compatible = "fixed-clock";
> +			#clock-cells = <0>;
> +			clock-frequency = <3000000>;
> +		};
> +	};
> +
> +	soc {
> +		lpuart1: serial at 40184000 {
> +			compatible = "fsl,imxrt1050-lpuart", "fsl,imx7ulp-lpuart";
> +			reg = <0x40184000 0x4000>;
> +			interrupts = <20>;
> +			clocks = <&clks IMXRT1050_CLK_LPUART1>;
> +			clock-names = "ipg";
> +			status = "disabled";
> +		};
> +
> +		iomuxc: pinctrl at 401f8000 {
> +			compatible = "fsl,imxrt1050-iomuxc";
> +			reg = <0x401f8000 0x4000>;
> +			fsl,mux_mask = <0x7>;
> +		};
> +
> +		anatop: anatop at 400d8000 {
> +			compatible = "fsl,imxrt-anatop";
> +			reg = <0x400d8000 0x4000>;
> +		};
> +
> +		clks: clock-controller at 400fc000 {
> +			compatible = "fsl,imxrt1050-ccm";
> +			reg = <0x400fc000 0x4000>;
> +			interrupts = <95>, <96>;
> +			clocks = <&osc>;
> +			clock-names = "osc";
> +			#clock-cells = <1>;
> +			assigned-clocks = <&clks IMXRT1050_CLK_PLL1_BYPASS>,
> +				<&clks IMXRT1050_CLK_PLL1_BYPASS>,
> +				<&clks IMXRT1050_CLK_PLL2_BYPASS>,
> +				<&clks IMXRT1050_CLK_PLL3_BYPASS>,
> +				<&clks IMXRT1050_CLK_PLL3_PFD1_664_62M>,
> +				<&clks IMXRT1050_CLK_PLL2_PFD2_396M>;
> +			assigned-clock-parents = <&clks IMXRT1050_CLK_PLL1_REF_SEL>,
> +				<&clks IMXRT1050_CLK_PLL1_ARM>,
> +				<&clks IMXRT1050_CLK_PLL2_SYS>,
> +				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
> +				<&clks IMXRT1050_CLK_PLL3_USB_OTG>,
> +				<&clks IMXRT1050_CLK_PLL2_SYS>;
> +		};
> +
> +		edma1: dma-controller at 400e8000 {
> +			#dma-cells = <2>;
> +			compatible = "fsl,imx7ulp-edma";
> +			reg = <0x400e8000 0x4000>,
> +				<0x400ec000 0x4000>;
> +			dma-channels = <32>;
> +			interrupts = <0>, <1>, <2>, <3>, <4>, <5>, <6>, <7>, <8>,
> +				<9>, <10>, <11>, <12>, <13>, <14>, <15>, <16>;
> +			clock-names = "dma", "dmamux0";
> +			clocks = <&clks IMXRT1050_CLK_DMA>,
> +				 <&clks IMXRT1050_CLK_DMA_MUX>;
> +		};
> +
> +		usdhc1: mmc at 402c0000 {
> +			compatible ="fsl,imxrt1050-usdhc", "fsl,imx6sl-usdhc";
> +			reg = <0x402c0000 0x4000>;
> +			interrupts = <110>;
> +			clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
> +				<&clks IMXRT1050_CLK_OSC>,
> +				<&clks IMXRT1050_CLK_USDHC1>;
> +			clock-names = "ipg", "ahb", "per";
> +			bus-width = <4>;
> +			fsl,wp-controller;
> +			no-1-8-v;
> +			max-frequency = <4000000>;
> +			fsl,tuning-start-tap = <20>;
> +			fsl,tuning-step= <2>;
> +			status = "disabled";
> +		};
> +
> +		gpio1: gpio at 401b8000 {
> +			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
> +			reg = <0x401b8000 0x4000>;
> +			interrupts = <80>, <81>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio2: gpio at 401bc000 {
> +			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
> +			reg = <0x401bc000 0x4000>;
> +			interrupts = <82>, <83>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio3: gpio at 401c0000 {
> +			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
> +			reg = <0x401c0000 0x4000>;
> +			interrupts = <84>, <85>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio4: gpio at 401c4000 {
> +			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
> +			reg = <0x401c4000 0x4000>;
> +			interrupts = <86>, <87>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpio5: gpio at 400c0000 {
> +			compatible = "fsl,imxrt1050-gpio", "fsl,imx35-gpio";
> +			reg = <0x400c0000 0x4000>;
> +			interrupts = <88>, <89>;
> +			gpio-controller;
> +			#gpio-cells = <2>;
> +			interrupt-controller;
> +			#interrupt-cells = <2>;
> +		};
> +
> +		gpt: timer at 401ec000 {
> +			compatible = "fsl,imxrt1050-gpt", "fsl,imx6dl-gpt", "fsl,imx6sl-gpt";
> +			reg = <0x401ec000 0x4000>;
> +			interrupts = <100>;
> +			clocks = <&osc3M>;
> +			clock-names = "per";
> +		};
> +	};
> +};
> -- 
> 2.34.1
> 


From shawnguo at kernel.org  Fri Jan 28 03:59:39 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Fri, 28 Jan 2022 19:59:39 +0800
Subject: [PATCH v8 7/7] ARM: imxrt_defconfig: Add i.MXRT family defconfig
In-Reply-To: <20220111215415.2075257-8-Mr.Bossman075@gmail.com>
References: <20220111212606.2072669-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-1-Mr.Bossman075@gmail.com>
 <20220111215415.2075257-8-Mr.Bossman075@gmail.com>
Message-ID: <20220128115938.GL4686@dragon>

On Tue, Jan 11, 2022 at 04:54:15PM -0500, Jesse Taube wrote:
> From: Giulio Benetti <giulio.benetti at benettiengineering.com>
> 
> Add generic i.MXRT family defconfig.
> 
> Signed-off-by: Giulio Benetti <giulio.benetti at benettiengineering.com>
> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>

Applied, thanks!


From catalin.marinas at arm.com  Fri Jan 28 04:06:15 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 12:06:15 +0000
Subject: [arm64] kernel boot slowdown in v5.10.19 -> v5.10.42 update
In-Reply-To: <9a34ee9b-0ede-30a6-0898-d32fe81d5b0c@linux.microsoft.com>
References: <9a34ee9b-0ede-30a6-0898-d32fe81d5b0c@linux.microsoft.com>
Message-ID: <YfPcNy3JcnwuJNMx@arm.com>

On Mon, Jan 24, 2022 at 03:03:48PM -0800, Vijay Balakrishna wrote:
> We noticed 150ms kernel boot slowdown back in June, 2021, when moving from
> v5.10.19 to v5.10.42.  This on a 8GB SoC.  Only recently we investigated
> this issue and found the regression is introduced by a change in map_mem()
> (paging_init() -> map_mem() -> __map_memblock(), in particular "map all the
> memory banks" for loop) by patch
> 
> 2687275a5843d1089687f08fc64eb3f3b026a169
> arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required
> 
> above is a follow up to
> 
> 0a30c53573b07d5561457e41fb0ab046cd857da5
> arm64: mm: Move reserve_crashkernel() into mem_init())
> 
> which deferred crashkernel reservation into mem_init().
> 
> The ~150ms slowdown disappears on booting without "crashkernel=.." on kernel
> command-line.

Is CONFIG_RODATA_FULL_DEFAULT_ENABLED set in your config file? It may
cause the same slowdown. I suspect it's because we end up mapping the
RAM at the page granularity so more loops and slightly higher TLB
pressure. Not sure we can do much about.

-- 
Catalin


From yongqiang.niu at mediatek.com  Fri Jan 28 04:07:15 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Fri, 28 Jan 2022 20:07:15 +0800
Subject: [PATCH v1, 1/4] soc: mediatek: mmsys: Add mt8186 mmsys routing table
In-Reply-To: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
Message-ID: <20220128120718.30545-2-yongqiang.niu@mediatek.com>

mt8186 routing registers is different with other Soc

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/soc/mediatek/mt8186-mmsys.h | 113 ++++++++++++++++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c    |  11 +++
 2 files changed, 124 insertions(+)
 create mode 100644 drivers/soc/mediatek/mt8186-mmsys.h

diff --git a/drivers/soc/mediatek/mt8186-mmsys.h b/drivers/soc/mediatek/mt8186-mmsys.h
new file mode 100644
index 000000000000..7de329f2d729
--- /dev/null
+++ b/drivers/soc/mediatek/mt8186-mmsys.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SOC_MEDIATEK_MT8186_MMSYS_H
+#define __SOC_MEDIATEK_MT8186_MMSYS_H
+
+#define MT8186_MMSYS_OVL_CON			0xF04
+#define MT8186_MMSYS_OVL0_CON_MASK			0x3
+#define MT8186_MMSYS_OVL0_2L_CON_MASK			0xC
+#define MT8186_OVL0_GO_BLEND				BIT(0)
+#define MT8186_OVL0_GO_BG				BIT(1)
+#define MT8186_OVL0_2L_GO_BLEND				BIT(2)
+#define MT8186_OVL0_2L_GO_BG				BIT(3)
+#define MT8186_DISP_RDMA0_SOUT_SEL		0xF0C
+#define MT8186_RDMA0_SOUT_SEL_MASK			0xF
+#define MT8186_RDMA0_SOUT_TO_DSI0			(0)
+#define MT8186_RDMA0_SOUT_TO_COLOR0			(1)
+#define MT8186_RDMA0_SOUT_TO_DPI0			(2)
+#define MT8186_DISP_OVL0_2L_MOUT_EN		0xF14
+#define MT8186_OVL0_2L_MOUT_EN_MASK			0xF
+#define MT8186_OVL0_2L_MOUT_TO_RDMA0			BIT(0)
+#define MT8186_OVL0_2L_MOUT_TO_RDMA1			BIT(3)
+#define MT8186_DISP_OVL0_MOUT_EN		0xF18
+#define MT8186_OVL0_MOUT_EN_MASK			0xF
+#define MT8186_OVL0_MOUT_TO_RDMA0			BIT(0)
+#define MT8186_OVL0_MOUT_TO_RDMA1			BIT(3)
+#define MT8186_DISP_DITHER0_MOUT_EN		0xF20
+#define MT8186_DITHER0_MOUT_EN_MASK			0xF
+#define MT8186_DITHER0_MOUT_TO_DSI0			BIT(0)
+#define MT8186_DITHER0_MOUT_TO_RDMA1			BIT(2)
+#define MT8186_DITHER0_MOUT_TO_DPI0			BIT(3)
+#define MT8186_DISP_RDMA0_SEL_IN		0xF28
+#define MT8186_RDMA0_SEL_IN_MASK			0xF
+#define MT8186_RDMA0_FROM_OVL0				0
+#define MT8186_RDMA0_FROM_OVL0_2L			2
+#define MT8186_DISP_DSI0_SEL_IN			0xF30
+#define MT8186_DSI0_SEL_IN_MASK				0xF
+#define MT8186_DSI0_FROM_RDMA0				0
+#define MT8186_DSI0_FROM_DITHER0			1
+#define MT8186_DSI0_FROM_RDMA1				2
+#define MT8186_DISP_RDMA1_MOUT_EN		0xF3C
+#define MT8186_RDMA1_MOUT_EN_MASK			0xF
+#define MT8186_RDMA1_MOUT_TO_DPI0_SEL			BIT(0)
+#define MT8186_RDMA1_MOUT_TO_DSI0_SEL			BIT(2)
+#define MT8186_DISP_RDMA1_SEL_IN		0xF40
+#define MT8186_RDMA1_SEL_IN_MASK			0xF
+#define MT8186_RDMA1_FROM_OVL0				0
+#define MT8186_RDMA1_FROM_OVL0_2L			2
+#define MT8186_RDMA1_FROM_DITHER0			3
+#define MT8186_DISP_DPI0_SEL_IN			0xF44
+#define MT8186_DPI0_SEL_IN_MASK				0xF
+#define MT8186_DPI0_FROM_RDMA1				0
+#define MT8186_DPI0_FROM_DITHER0			1
+#define MT8186_DPI0_FROM_RDMA0				2
+
+static const struct mtk_mmsys_routes mmsys_mt8186_routing_table[] = {
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8186_DISP_OVL0_MOUT_EN, MT8186_OVL0_MOUT_EN_MASK,
+		MT8186_OVL0_MOUT_TO_RDMA0
+	},
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8186_DISP_RDMA0_SEL_IN, MT8186_RDMA0_SEL_IN_MASK,
+		MT8186_RDMA0_FROM_OVL0
+	},
+	{
+		DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
+		MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_CON_MASK,
+		MT8186_OVL0_GO_BLEND
+	},
+	{
+		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
+		MT8186_DISP_RDMA0_SOUT_SEL, MT8186_RDMA0_SOUT_SEL_MASK,
+		MT8186_RDMA0_SOUT_TO_COLOR0
+	},
+	{
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8186_DISP_DITHER0_MOUT_EN, MT8186_DITHER0_MOUT_EN_MASK,
+		MT8186_DITHER0_MOUT_TO_DSI0,
+	},
+	{
+		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
+		MT8186_DISP_DSI0_SEL_IN, MT8186_DSI0_SEL_IN_MASK,
+		MT8186_DSI0_FROM_DITHER0
+	},
+	{
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
+		MT8186_DISP_OVL0_2L_MOUT_EN, MT8186_OVL0_2L_MOUT_EN_MASK,
+		MT8186_OVL0_2L_MOUT_TO_RDMA1
+	},
+	{
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
+		MT8186_DISP_RDMA1_SEL_IN, MT8186_RDMA1_SEL_IN_MASK,
+		MT8186_RDMA1_FROM_OVL0_2L
+	},
+	{
+		DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
+		MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_2L_CON_MASK,
+		MT8186_OVL0_2L_GO_BLEND
+	},
+	{
+		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+		MT8186_DISP_RDMA1_MOUT_EN, MT8186_RDMA1_MOUT_EN_MASK,
+		MT8186_RDMA1_MOUT_TO_DPI0_SEL
+	},
+	{
+		DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
+		MT8186_DISP_DPI0_SEL_IN, MT8186_DPI0_SEL_IN_MASK,
+		MT8186_DPI0_FROM_RDMA1
+	},
+};
+
+#endif /* __SOC_MEDIATEK_MT8186_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
index 1e448f1ffefb..0da25069ffb3 100644
--- a/drivers/soc/mediatek/mtk-mmsys.c
+++ b/drivers/soc/mediatek/mtk-mmsys.c
@@ -15,6 +15,7 @@
 #include "mtk-mmsys.h"
 #include "mt8167-mmsys.h"
 #include "mt8183-mmsys.h"
+#include "mt8186-mmsys.h"
 #include "mt8192-mmsys.h"
 #include "mt8365-mmsys.h"
 
@@ -56,6 +57,12 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
 };
 
+static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
+	.clk_driver = "clk-mt8186-mm",
+	.routes = mmsys_mt8186_routing_table,
+	.num_routes = ARRAY_SIZE(mmsys_mt8186_routing_table),
+};
+
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.clk_driver = "clk-mt8192-mm",
 	.routes = mmsys_mt8192_routing_table,
@@ -242,6 +249,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
 		.compatible = "mediatek,mt8183-mmsys",
 		.data = &mt8183_mmsys_driver_data,
 	},
+	{
+		.compatible = "mediatek,mt8186-mmsys",
+		.data = &mt8186_mmsys_driver_data,
+	},
 	{
 		.compatible = "mediatek,mt8192-mmsys",
 		.data = &mt8192_mmsys_driver_data,
-- 
2.25.1



From yongqiang.niu at mediatek.com  Fri Jan 28 04:07:17 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Fri, 28 Jan 2022 20:07:17 +0800
Subject: [PATCH v1, 3/4] drm/mediatek: split postmask component
In-Reply-To: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
Message-ID: <20220128120718.30545-4-yongqiang.niu@mediatek.com>

add postmask private data for differnt soc support

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/gpu/drm/mediatek/Makefile            |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h      |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_postmask.c | 155 +++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c  |  30 +---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c       |   2 +
 drivers/gpu/drm/mediatek/mtk_drm_drv.h       |   1 +
 6 files changed, 170 insertions(+), 27 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_postmask.c

diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
index 29098d7c8307..f26fe646ee2a 100644
--- a/drivers/gpu/drm/mediatek/Makefile
+++ b/drivers/gpu/drm/mediatek/Makefile
@@ -5,6 +5,7 @@ mediatek-drm-y := mtk_disp_aal.o \
 		  mtk_disp_color.o \
 		  mtk_disp_gamma.o \
 		  mtk_disp_ovl.o \
+		  mtk_disp_postmask.o \
 		  mtk_disp_rdma.o \
 		  mtk_drm_crtc.o \
 		  mtk_drm_ddp_comp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
index 86c3068894b1..f4c21195c3ea 100644
--- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
@@ -81,6 +81,14 @@ void mtk_ovl_enable_vblank(struct device *dev,
 			   void *vblank_cb_data);
 void mtk_ovl_disable_vblank(struct device *dev);
 
+int mtk_postmask_clk_enable(struct device *dev);
+void mtk_postmask_clk_disable(struct device *dev);
+void mtk_postmask_config(struct device *dev, unsigned int w,
+				unsigned int h, unsigned int vrefresh,
+				unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
+void mtk_postmask_start(struct device *dev);
+void mtk_postmask_stop(struct device *dev);
+
 void mtk_rdma_bypass_shadow(struct device *dev);
 int mtk_rdma_clk_enable(struct device *dev);
 void mtk_rdma_clk_disable(struct device *dev);
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_postmask.c b/drivers/gpu/drm/mediatek/mtk_disp_postmask.c
new file mode 100644
index 000000000000..fc04b445c2ed
--- /dev/null
+++ b/drivers/gpu/drm/mediatek/mtk_disp_postmask.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-cmdq.h>
+
+#include "mtk_disp_drv.h"
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+
+#define DISP_POSTMASK_EN			0x0000
+#define POSTMASK_EN					BIT(0)
+#define DISP_POSTMASK_CFG			0x0020
+#define POSTMASK_RELAY_MODE				BIT(0)
+#define DISP_POSTMASK_SIZE			0x0030
+
+struct mtk_disp_postmask_data {
+	u32 reserved;
+};
+
+/*
+ * struct mtk_disp_postmask - DISP_POSTMASK driver structure
+ */
+struct mtk_disp_postmask {
+	struct clk *clk;
+	void __iomem *regs;
+	struct cmdq_client_reg cmdq_reg;
+	const struct mtk_disp_postmask_data *data;
+};
+
+int mtk_postmask_clk_enable(struct device *dev)
+{
+	struct mtk_disp_postmask *postmask = dev_get_drvdata(dev);
+
+	return clk_prepare_enable(postmask->clk);
+}
+
+void mtk_postmask_clk_disable(struct device *dev)
+{
+	struct mtk_disp_postmask *postmask = dev_get_drvdata(dev);
+
+	clk_disable_unprepare(postmask->clk);
+}
+
+void mtk_postmask_config(struct device *dev, unsigned int w,
+				unsigned int h, unsigned int vrefresh,
+				unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
+{
+	struct mtk_disp_postmask *postmask = dev_get_drvdata(dev);
+
+	mtk_ddp_write(cmdq_pkt, w << 16 | h, &postmask->cmdq_reg, postmask->regs,
+		      DISP_POSTMASK_SIZE);
+	mtk_ddp_write(cmdq_pkt, POSTMASK_RELAY_MODE, &postmask->cmdq_reg,
+		      postmask->regs, DISP_POSTMASK_CFG);
+}
+
+void mtk_postmask_start(struct device *dev)
+{
+	struct mtk_disp_postmask *postmask = dev_get_drvdata(dev);
+
+	writel(POSTMASK_EN, postmask->regs + DISP_POSTMASK_EN);
+}
+
+void mtk_postmask_stop(struct device *dev)
+{
+	struct mtk_disp_postmask *postmask = dev_get_drvdata(dev);
+
+	writel_relaxed(0x0, postmask->regs + DISP_POSTMASK_EN);
+}
+
+static int mtk_disp_postmask_bind(struct device *dev, struct device *master,
+				  void *data)
+{
+	return 0;
+}
+
+static void mtk_disp_postmask_unbind(struct device *dev, struct device *master,
+				     void *data)
+{
+}
+
+static const struct component_ops mtk_disp_postmask_component_ops = {
+	.bind	= mtk_disp_postmask_bind,
+	.unbind = mtk_disp_postmask_unbind,
+};
+
+static int mtk_disp_postmask_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_disp_postmask *priv;
+	struct resource *res;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(dev, "failed to get postmask clk\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	priv->regs = devm_ioremap_resource(dev, res);
+	if (IS_ERR(priv->regs)) {
+		dev_err(dev, "failed to ioremap postmask\n");
+		return PTR_ERR(priv->regs);
+	}
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
+	if (ret)
+		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
+#endif
+
+	priv->data = of_device_get_match_data(dev);
+	platform_set_drvdata(pdev, priv);
+
+	ret = component_add(dev, &mtk_disp_postmask_component_ops);
+	if (ret)
+		dev_err(dev, "Failed to add component: %d\n", ret);
+
+	return ret;
+}
+
+static int mtk_disp_postmask_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &mtk_disp_postmask_component_ops);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_disp_postmask_driver_dt_match[] = {
+	{ .compatible = "mediatek,mt8192-disp-postmask"},
+	{},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_postmask_driver_dt_match);
+
+struct platform_driver mtk_disp_postmask_driver = {
+	.probe		= mtk_disp_postmask_probe,
+	.remove		= mtk_disp_postmask_remove,
+	.driver		= {
+		.name	= "mediatek-disp-postmask",
+		.owner	= THIS_MODULE,
+		.of_match_table = mtk_disp_postmask_driver_dt_match,
+	},
+};
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
index b4b682bc1991..e02fc8dcad91 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -199,31 +199,6 @@ static void mtk_od_start(struct device *dev)
 	writel(1, priv->regs + DISP_REG_OD_EN);
 }
 
-static void mtk_postmask_config(struct device *dev, unsigned int w,
-				unsigned int h, unsigned int vrefresh,
-				unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs,
-		      DISP_REG_POSTMASK_SIZE);
-	mtk_ddp_write(cmdq_pkt, POSTMASK_RELAY_MODE, &priv->cmdq_reg,
-		      priv->regs, DISP_REG_POSTMASK_CFG);
-}
-
-static void mtk_postmask_start(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	writel(POSTMASK_EN, priv->regs + DISP_REG_POSTMASK_EN);
-}
-
-static void mtk_postmask_stop(struct device *dev)
-{
-	struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
-
-	writel_relaxed(0x0, priv->regs + DISP_REG_POSTMASK_EN);
-}
 
 static void mtk_ufoe_start(struct device *dev)
 {
@@ -308,8 +283,8 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
 };
 
 static const struct mtk_ddp_comp_funcs ddp_postmask = {
-	.clk_enable = mtk_ddp_clk_enable,
-	.clk_disable = mtk_ddp_clk_disable,
+	.clk_enable = mtk_postmask_clk_enable,
+	.clk_disable = mtk_postmask_clk_disable,
 	.config = mtk_postmask_config,
 	.start = mtk_postmask_start,
 	.stop = mtk_postmask_stop,
@@ -510,6 +485,7 @@ int mtk_ddp_comp_init(struct device_node *node, struct mtk_ddp_comp *comp,
 	    type == MTK_DISP_GAMMA ||
 	    type == MTK_DISP_OVL ||
 	    type == MTK_DISP_OVL_2L ||
+	    type == MTK_DISP_POSTMASK ||
 	    type == MTK_DISP_PWM ||
 	    type == MTK_DISP_RDMA ||
 	    type == MTK_DPI ||
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 56ff8c57ef8f..6efb423ccc92 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -609,6 +609,7 @@ static int mtk_drm_probe(struct platform_device *pdev)
 		    comp_type == MTK_DISP_GAMMA ||
 		    comp_type == MTK_DISP_OVL ||
 		    comp_type == MTK_DISP_OVL_2L ||
+		    comp_type == MTK_DISP_POSTMASK ||
 		    comp_type == MTK_DISP_RDMA ||
 		    comp_type == MTK_DPI ||
 		    comp_type == MTK_DSI) {
@@ -709,6 +710,7 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 	&mtk_disp_color_driver,
 	&mtk_disp_gamma_driver,
 	&mtk_disp_ovl_driver,
+	&mtk_disp_postmask_driver,
 	&mtk_disp_rdma_driver,
 	&mtk_dpi_driver,
 	&mtk_drm_platform_driver,
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.h b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
index 3e7d1e6fbe01..c1e676aebe57 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -51,6 +51,7 @@ extern struct platform_driver mtk_disp_ccorr_driver;
 extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_gamma_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
+extern struct platform_driver mtk_disp_postmask_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
 extern struct platform_driver mtk_dsi_driver;
-- 
2.25.1



From geert+renesas at glider.be  Fri Jan 28 04:10:44 2022
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 28 Jan 2022 13:10:44 +0100
Subject: [PATCH] ARM: shmobile: defconfig: Disable unneeded 8250 serial options
Message-ID: <caefa806d66b83085c4ceab09819b469088664a1.1643371790.git.geert+renesas@glider.be>

The only Renesas platform with 16550 serial ports is Emma Mobile EV2,
which does not need any of the following options:
  - CONFIG_SERIAL_8250_DEPRECATED_OPTIONS,
  - CONFIG_SERIAL_8250_16550A_VARIANTS,
  - CONFIG_SERIAL_8250_PCI,
  - CONFIG_SERIAL_8250_PERICOM (new in v5.17-rc1).

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v5.18.

 arch/arm/configs/shmobile_defconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 2c2702ec6d025a22..db8df8a3a7b12d13 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -69,9 +69,13 @@ CONFIG_INPUT_DA9063_ONKEY=y
 CONFIG_INPUT_ADXL34X=y
 # CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
 CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_PCI is not set
 CONFIG_SERIAL_8250_DW=y
 CONFIG_SERIAL_8250_EM=y
+# CONFIG_SERIAL_8250_PERICOM is not set
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_DEMUX_PINCTRL=y
-- 
2.25.1



From yongqiang.niu at mediatek.com  Fri Jan 28 04:07:16 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Fri, 28 Jan 2022 20:07:16 +0800
Subject: [PATCH v1, 2/4] soc: mediatek: add mtk mutex support for MT8186
In-Reply-To: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
Message-ID: <20220128120718.30545-3-yongqiang.niu@mediatek.com>

Add mtk mutex support for MT8186 SoC.

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/soc/mediatek/mtk-mutex.c | 45 ++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
index 2ca55bb5a8be..ebd95fd0f36e 100644
--- a/drivers/soc/mediatek/mtk-mutex.c
+++ b/drivers/soc/mediatek/mtk-mutex.c
@@ -26,6 +26,23 @@
 
 #define INT_MUTEX				BIT(1)
 
+#define MT8186_MUTEX_MOD_DISP_OVL0		0
+#define MT8186_MUTEX_MOD_DISP_OVL0_2L 		1
+#define MT8186_MUTEX_MOD_DISP_RDMA0		2
+#define MT8186_MUTEX_MOD_DISP_COLOR0		4
+#define MT8186_MUTEX_MOD_DISP_CCORR0		5
+#define MT8186_MUTEX_MOD_DISP_AAL0		7
+#define MT8186_MUTEX_MOD_DISP_GAMMA0		8
+#define MT8186_MUTEX_MOD_DISP_POSTMASK0		9
+#define MT8186_MUTEX_MOD_DISP_DITHER0		10
+#define MT8186_MUTEX_MOD_DISP_RDMA1		17
+
+#define MT8186_MUTEX_SOF_SINGLE_MODE 0
+#define MT8186_MUTEX_SOF_DSI0 1
+#define MT8186_MUTEX_SOF_DPI0 2
+#define MT8186_MUTEX_EOF_DSI0 (MT8186_MUTEX_SOF_DSI0 << 6)
+#define MT8186_MUTEX_EOF_DPI0 (MT8186_MUTEX_SOF_DPI0 << 6)
+
 #define MT8167_MUTEX_MOD_DISP_PWM		1
 #define MT8167_MUTEX_MOD_DISP_OVL0		6
 #define MT8167_MUTEX_MOD_DISP_OVL1		7
@@ -226,6 +243,19 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
 };
 
+static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
+	[DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
+	[DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
+	[DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
+	[DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0,
+	[DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
+	[DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
+	[DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
+	[DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
+	[DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
+	[DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
+};
+
 static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
 	[DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
 	[DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
@@ -264,6 +294,12 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
 	[MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
 };
 
+static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
+	[MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
+	[MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
+	[MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
+};
+
 static const struct mtk_mutex_data mt2701_mutex_driver_data = {
 	.mutex_mod = mt2701_mutex_mod,
 	.mutex_sof = mt2712_mutex_sof,
@@ -301,6 +337,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
 	.no_clk = true,
 };
 
+static const struct mtk_mutex_data mt8186_mutex_driver_data = {
+	.mutex_mod = mt8186_mutex_mod,
+	.mutex_sof = mt8186_mutex_sof,
+	.mutex_mod_reg = MT8183_MUTEX0_MOD0,
+	.mutex_sof_reg = MT8183_MUTEX0_SOF0,
+};
+
 static const struct mtk_mutex_data mt8192_mutex_driver_data = {
 	.mutex_mod = mt8192_mutex_mod,
 	.mutex_sof = mt8183_mutex_sof,
@@ -540,6 +583,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
 	  .data = &mt8173_mutex_driver_data},
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = &mt8183_mutex_driver_data},
+	{ .compatible = "mediatek,mt8186-disp-mutex",
+	.data = &mt8186_mutex_driver_data},
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = &mt8192_mutex_driver_data},
 	{},
-- 
2.25.1



From yongqiang.niu at mediatek.com  Fri Jan 28 04:07:14 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Fri, 28 Jan 2022 20:07:14 +0800
Subject: [PATCH v1, 0/4] add display support for mediatek SOC MT8186
Message-ID: <20220128120718.30545-1-yongqiang.niu@mediatek.com>


Yongqiang Niu (4):
  soc: mediatek: mmsys: Add mt8186 mmsys routing table
  soc: mediatek: add mtk mutex support for MT8186
  drm/mediatek: split postmask component
  drm/mediatek: add mt8186 display support

 drivers/gpu/drm/mediatek/Makefile            |   1 +
 drivers/gpu/drm/mediatek/mtk_disp_drv.h      |   8 +
 drivers/gpu/drm/mediatek/mtk_disp_postmask.c | 155 +++++++++++++++++++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c  |  30 +---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c       |  41 +++++
 drivers/gpu/drm/mediatek/mtk_drm_drv.h       |   1 +
 drivers/soc/mediatek/mt8186-mmsys.h          | 113 ++++++++++++++
 drivers/soc/mediatek/mtk-mmsys.c             |  11 ++
 drivers/soc/mediatek/mtk-mutex.c             |  45 ++++++
 9 files changed, 378 insertions(+), 27 deletions(-)
 create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_postmask.c
 create mode 100644 drivers/soc/mediatek/mt8186-mmsys.h

-- 
2.25.1



From yongqiang.niu at mediatek.com  Fri Jan 28 04:07:18 2022
From: yongqiang.niu at mediatek.com (Yongqiang Niu)
Date: Fri, 28 Jan 2022 20:07:18 +0800
Subject: [PATCH v1, 4/4] drm/mediatek: add mt8186 display support
In-Reply-To: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
Message-ID: <20220128120718.30545-5-yongqiang.niu@mediatek.com>

Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
---
 drivers/gpu/drm/mediatek/mtk_drm_drv.c | 39 ++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 6efb423ccc92..754b1be25d0d 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -158,6 +158,24 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
 	DDP_COMPONENT_DPI0,
 };
 
+static const enum mtk_ddp_comp_id mt8186_mtk_ddp_main[] = {
+	DDP_COMPONENT_OVL0,
+	DDP_COMPONENT_RDMA0,
+	DDP_COMPONENT_COLOR0,
+	DDP_COMPONENT_CCORR,
+	DDP_COMPONENT_AAL0,
+	DDP_COMPONENT_GAMMA,
+	DDP_COMPONENT_POSTMASK0,
+	DDP_COMPONENT_DITHER,
+	DDP_COMPONENT_DSI0,
+};
+
+static const enum mtk_ddp_comp_id mt8186_mtk_ddp_ext[] = {
+	DDP_COMPONENT_OVL_2L0,
+	DDP_COMPONENT_RDMA1,
+	DDP_COMPONENT_DPI0,
+};
+
 static const enum mtk_ddp_comp_id mt8192_mtk_ddp_main[] = {
 	DDP_COMPONENT_OVL0,
 	DDP_COMPONENT_OVL_2L0,
@@ -221,6 +239,13 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
 	.ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
 };
 
+static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
+	.main_path = mt8186_mtk_ddp_main,
+	.main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
+	.ext_path = mt8186_mtk_ddp_ext,
+	.ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
+};
+
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
 	.main_path = mt8192_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
@@ -463,6 +488,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8183-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
+	{ .compatible = "mediatek,mt8186-disp-mutex",
+	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8192-disp-mutex",
 	  .data = (void *)MTK_DISP_MUTEX },
 	{ .compatible = "mediatek,mt8173-disp-od",
@@ -475,14 +502,20 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8186-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8192-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
+	{ .compatible = "mediatek,mt8186-disp-ovl-2l",
+	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-postmask",
 	  .data = (void *)MTK_DISP_POSTMASK },
+	{ .compatible = "mediatek,mt8186-disp-postmask",
+	  .data = (void *)MTK_DISP_POSTMASK},
 	{ .compatible = "mediatek,mt2701-disp-pwm",
 	  .data = (void *)MTK_DISP_BLS },
 	{ .compatible = "mediatek,mt8167-disp-pwm",
@@ -511,12 +544,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
 	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt8183-dpi",
 	  .data = (void *)MTK_DPI },
+	{ .compatible = "mediatek,mt8186-dpi",
+	  .data = (void *)MTK_DPI },
 	{ .compatible = "mediatek,mt2701-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8173-dsi",
 	  .data = (void *)MTK_DSI },
 	{ .compatible = "mediatek,mt8183-dsi",
 	  .data = (void *)MTK_DSI },
+	{ .compatible = "mediatek,mt8186-dsi",
+	  .data = (void *)MTK_DSI },
 	{ }
 };
 
@@ -533,6 +570,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
 	  .data = &mt8173_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8183-mmsys",
 	  .data = &mt8183_mmsys_driver_data},
+	{ .compatible = "mediatek,mt8186-mmsys",
+	  .data = &mt8186_mmsys_driver_data},
 	{ .compatible = "mediatek,mt8192-mmsys",
 	  .data = &mt8192_mmsys_driver_data},
 	{ }
-- 
2.25.1



From liang.yang at amlogic.com  Fri Jan 28 04:16:26 2022
From: liang.yang at amlogic.com (Liang Yang)
Date: Fri, 28 Jan 2022 20:16:26 +0800
Subject: [PATCH v2 1/2] mtd: rawnand: meson: discard the common MMC sub
 clock framework
In-Reply-To: <20220128124036.25fe0539@xps13>
References: <20220128113237.39996-1-liang.yang@amlogic.com>
 <20220128113237.39996-2-liang.yang@amlogic.com>
 <20220128124036.25fe0539@xps13>
Message-ID: <e87b40f0-140e-0521-b861-7481cfc1507d@amlogic.com>

Hi Miquel,

Thanks for the review and quick response.

On 2022/1/28 19:40, Miquel Raynal wrote:
> [ EXTERNAL EMAIL ]
> 
> Hi Liang,
> 
> liang.yang at amlogic.com wrote on Fri, 28 Jan 2022 19:32:36 +0800:
> 
>> EMMC and NAND has the same clock control register named 'SD_EMMC_CLOCK' which is
> 
> have
ok
> 
>> defined in EMMC port internally. bit0~5 of 'SD_EMMC_CLOCK' is the divider and
>> bit6~7 is the mux for fix pll and xtal.
> 
>> Previously a common MMC sub clock framework is implemented and shared by EMMC and
> 
> I believe you meant that this hasa already been contributed? I would
> then rephrase with:
> 
> A common MMC and NAND sub-clock has been implemented and can be used by
> the eMMC and NAND controller (which are mutually exclusive anyway).
> 
> Let's use this new clock.
ok. thanks
> 
>> NAND, but that is coupling the EMMC and NAND, although EMMC and NAND is mutually
>> exclusive.
>>
>> Change-Id: Ibeb4c7ff886f5886aac4d6c664d7bbd1b1bcb997
> 
> No change Ids.
ok. i will delete next version.
> 
>> Signed-off-by: Liang Yang <liang.yang at amlogic.com>
>> ---
>>   drivers/mtd/nand/raw/meson_nand.c | 161 +++++++++++++++++-------------
>>   1 file changed, 89 insertions(+), 72 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
>> index ac3be92872d0..f6a3d5c2ea1c 100644
>> --- a/drivers/mtd/nand/raw/meson_nand.c
>> +++ b/drivers/mtd/nand/raw/meson_nand.c
>> @@ -2,7 +2,7 @@
>>   /*
>>    * Amlogic Meson Nand Flash Controller Driver
>>    *
>> - * Copyright (c) 2018 Amlogic, inc.
>> + * Copyright (c) 2018-2021 Amlogic, inc.
> 
> Please don't.
> 
>>    * Author: Liang Yang <liang.yang at amlogic.com>
>>    */
>>   
>> @@ -10,6 +10,7 @@
>>   #include <linux/dma-mapping.h>
>>   #include <linux/interrupt.h>
>>   #include <linux/clk.h>
>> +#include <linux/clk-provider.h>
>>   #include <linux/mtd/rawnand.h>
>>   #include <linux/mtd/mtd.h>
>>   #include <linux/mfd/syscon.h>
>> @@ -19,6 +20,7 @@
>>   #include <linux/iopoll.h>
>>   #include <linux/of.h>
>>   #include <linux/of_device.h>
>> +#include <linux/of_address.h>
>>   #include <linux/sched/task_stack.h>
>>   
>>   #define NFC_REG_CMD		0x00
>> @@ -104,6 +106,9 @@
>>   
>>   #define PER_INFO_BYTE		8
>>   
>> +#define CLK_DIV_SHIFT		0
>> +#define CLK_DIV_WIDTH		6
>> +
>>   struct meson_nfc_nand_chip {
>>   	struct list_head node;
>>   	struct nand_chip nand;
>> @@ -151,15 +156,17 @@ struct meson_nfc {
>>   	struct nand_controller controller;
>>   	struct clk *core_clk;
>>   	struct clk *device_clk;
>> -	struct clk *phase_tx;
>> -	struct clk *phase_rx;
>> +	struct clk *nand_clk;
>> +	struct clk_divider nand_divider;
>>   
>>   	unsigned long clk_rate;
>>   	u32 bus_timing;
>>   
>>   	struct device *dev;
>> -	void __iomem *reg_base;
>> -	struct regmap *reg_clk;
>> +	struct {
>> +		void __iomem *reg_base;
>> +		void __iomem *sd_emmc_clock;
>> +	} res;
> 
> Please split your commit: first the mechanical changes, then the use of
> the new area or something like that.
> 
> Otherwise there are too many lines changed, I can't spot where it is
> interesting.

ok. i will split it next version. thanks.

> 
> Thanks,
> Miqu?l
> 
> .


From maz at kernel.org  Fri Jan 28 04:18:09 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:09 +0000
Subject: [PATCH v6 01/64] arm64: Add ARM64_HAS_NESTED_VIRT cpufeature
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-2-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Add a new ARM64_HAS_NESTED_VIRT feature to indicate that the
CPU has the ARMv8.3 nested virtualization capability, together
with the 'kvm-arm.mode=nested' command line option.

This will be used to support nested virtualization in KVM.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: moved the command-line option to kvm-arm.mode]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 .../admin-guide/kernel-parameters.txt         |  7 +++++-
 arch/arm64/include/asm/kvm_host.h             |  5 ++++
 arch/arm64/kernel/cpufeature.c                | 24 +++++++++++++++++++
 arch/arm64/kvm/arm.c                          |  5 ++++
 arch/arm64/tools/cpucaps                      |  1 +
 5 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index f5a27f067db9..466d8fdbaee2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2391,9 +2391,14 @@
 				   state is kept private from the host.
 				   Not valid if the kernel is running in EL2.
 
+			nested: VHE-based mode with support for nested
+				virtualization. Requires at least ARMv8.3
+				hardware.
+
 			Defaults to VHE/nVHE based on hardware support. Setting
 			mode to "protected" will disable kexec and hibernation
-			for the host.
+			for the host. "nested" is experimental and should be
+			used with extreme caution.
 
 	kvm-arm.vgic_v3_group0_trap=
 			[KVM,ARM] Trap guest accesses to GICv3 group-0
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 5bc01e62c08a..115e0e2caf9a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -57,9 +57,14 @@
 enum kvm_mode {
 	KVM_MODE_DEFAULT,
 	KVM_MODE_PROTECTED,
+	KVM_MODE_NV,
 	KVM_MODE_NONE,
 };
+#ifdef CONFIG_KVM
 enum kvm_mode kvm_get_mode(void);
+#else
+static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
+#endif
 
 DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a46ab3b1c4d5..2fa39ce108d0 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -1772,6 +1772,20 @@ static void cpu_copy_el2regs(const struct arm64_cpu_capabilities *__unused)
 		write_sysreg(read_sysreg(tpidr_el1), tpidr_el2);
 }
 
+static bool has_nested_virt_support(const struct arm64_cpu_capabilities *cap,
+				    int scope)
+{
+	if (kvm_get_mode() != KVM_MODE_NV)
+		return false;
+
+	if (!has_cpuid_feature(cap, scope)) {
+		pr_warn("unavailable: %s\n", cap->desc);
+		return false;
+	}
+
+	return true;
+}
+
 static void cpu_has_fwb(const struct arm64_cpu_capabilities *__unused)
 {
 	u64 val = read_sysreg_s(SYS_CLIDR_EL1);
@@ -2005,6 +2019,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = runs_at_el2,
 		.cpu_enable = cpu_copy_el2regs,
 	},
+	{
+		.desc = "Nested Virtualization Support",
+		.capability = ARM64_HAS_NESTED_VIRT,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_nested_virt_support,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR2_NV_SHIFT,
+		.min_field_value = 1,
+	},
 	{
 		.capability = ARM64_HAS_32BIT_EL0_DO_NOT_USE,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index a4a0063df456..06ca11e90482 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -2209,6 +2209,11 @@ static int __init early_kvm_mode_cfg(char *arg)
 		return 0;
 	}
 
+	if (strcmp(arg, "nested") == 0 && !WARN_ON(!is_kernel_in_hyp_mode())) {
+		kvm_mode = KVM_MODE_NV;
+		return 0;
+	}
+
 	if (strcmp(arg, "none") == 0) {
 		kvm_mode = KVM_MODE_NONE;
 		return 0;
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index 870c39537dd0..a49864b56a07 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -26,6 +26,7 @@ HAS_GENERIC_AUTH_IMP_DEF
 HAS_IRQ_PRIO_MASKING
 HAS_LDAPR
 HAS_LSE_ATOMICS
+HAS_NESTED_VIRT
 HAS_NO_FPSIMD
 HAS_NO_HW_PREFETCH
 HAS_PAN
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:11 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:11 +0000
Subject: [PATCH v6 03/64] KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU
 nested virt is set
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-4-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
feature is enabled on the VCPU.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: rework register reset not to use empty data structures]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/reset.c | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index ecc40c8cd6f6..d19a9aad2d85 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -27,6 +27,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/virt.h>
 
 /* Maximum phys_shift supported for any VM on this host */
@@ -38,6 +39,9 @@ static u32 kvm_ipa_limit;
 #define VCPU_RESET_PSTATE_EL1	(PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \
 				 PSR_F_BIT | PSR_D_BIT)
 
+#define VCPU_RESET_PSTATE_EL2	(PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \
+				 PSR_F_BIT | PSR_D_BIT)
+
 #define VCPU_RESET_PSTATE_SVC	(PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \
 				 PSR_AA32_I_BIT | PSR_AA32_F_BIT)
 
@@ -188,12 +192,19 @@ static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
 	unsigned long i;
 
 	is32bit = vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT);
-	if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
-		return false;
+	if (is32bit) {
+		/* The HW must obviously support AArch32 at EL1 */
+		if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1))
+			return false;
 
-	/* MTE is incompatible with AArch32 */
-	if (kvm_has_mte(vcpu->kvm) && is32bit)
-		return false;
+		/* MTE is incompatible with AArch32 */
+		if (kvm_has_mte(vcpu->kvm))
+			return false;
+
+		/* NV is incompatible with AArch32 */
+		if (vcpu_has_nv(vcpu))
+			return false;
+	}
 
 	/* Check that the vcpus are either all 32bit or all 64bit */
 	kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
@@ -265,10 +276,18 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
 		goto out;
 	}
 
+	if (vcpu_has_nv(vcpu) &&
+	    vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	switch (vcpu->arch.target) {
 	default:
 		if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
 			pstate = VCPU_RESET_PSTATE_SVC;
+		} else if (vcpu_has_nv(vcpu)) {
+			pstate = VCPU_RESET_PSTATE_EL2;
 		} else {
 			pstate = VCPU_RESET_PSTATE_EL1;
 		}
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:12 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:12 +0000
Subject: [PATCH v6 04/64] KVM: arm64: nv: Allow userspace to set PSR_MODE_EL2x
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-5-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at linaro.org>

We were not allowing userspace to set a more privileged mode for the VCPU
than EL1, but we should allow this when nested virtualization is enabled
for the VCPU.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/guest.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
index e116c7767730..db6209622be9 100644
--- a/arch/arm64/kvm/guest.c
+++ b/arch/arm64/kvm/guest.c
@@ -24,6 +24,7 @@
 #include <asm/fpsimd.h>
 #include <asm/kvm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
 #include <asm/sigcontext.h>
 
 #include "trace.h"
@@ -259,6 +260,11 @@ static int set_core_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
 			if (vcpu_el1_is_32bit(vcpu))
 				return -EINVAL;
 			break;
+		case PSR_MODE_EL2h:
+		case PSR_MODE_EL2t:
+			if (vcpu_el1_is_32bit(vcpu) || !vcpu_has_nv(vcpu))
+				return -EINVAL;
+			break;
 		default:
 			err = -EINVAL;
 			goto out;
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:13 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:13 +0000
Subject: [PATCH v6 05/64] KVM: arm64: nv: Add EL2 system registers to vcpu
 context
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-6-maz@kernel.org>

Add the minimal set of EL2 system registers to the vcpu context.
Nothing uses them just yet.

Reviewed-by: Andre Przywara <andre.przywara at arm.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 33 ++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 115e0e2caf9a..15f690c27baf 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -220,12 +220,43 @@ enum vcpu_sysreg {
 	TFSR_EL1,	/* Tag Fault Status Register (EL1) */
 	TFSRE0_EL1,	/* Tag Fault Status Register (EL0) */
 
-	/* 32bit specific registers. Keep them at the end of the range */
+	/* 32bit specific registers. */
 	DACR32_EL2,	/* Domain Access Control Register */
 	IFSR32_EL2,	/* Instruction Fault Status Register */
 	FPEXC32_EL2,	/* Floating-Point Exception Control Register */
 	DBGVCR32_EL2,	/* Debug Vector Catch Register */
 
+	/* EL2 registers */
+	VPIDR_EL2,	/* Virtualization Processor ID Register */
+	VMPIDR_EL2,	/* Virtualization Multiprocessor ID Register */
+	SCTLR_EL2,	/* System Control Register (EL2) */
+	ACTLR_EL2,	/* Auxiliary Control Register (EL2) */
+	HCR_EL2,	/* Hypervisor Configuration Register */
+	MDCR_EL2,	/* Monitor Debug Configuration Register (EL2) */
+	CPTR_EL2,	/* Architectural Feature Trap Register (EL2) */
+	HSTR_EL2,	/* Hypervisor System Trap Register */
+	HACR_EL2,	/* Hypervisor Auxiliary Control Register */
+	TTBR0_EL2,	/* Translation Table Base Register 0 (EL2) */
+	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
+	TCR_EL2,	/* Translation Control Register (EL2) */
+	VTTBR_EL2,	/* Virtualization Translation Table Base Register */
+	VTCR_EL2,	/* Virtualization Translation Control Register */
+	SPSR_EL2,	/* EL2 saved program status register */
+	ELR_EL2,	/* EL2 exception link register */
+	AFSR0_EL2,	/* Auxiliary Fault Status Register 0 (EL2) */
+	AFSR1_EL2,	/* Auxiliary Fault Status Register 1 (EL2) */
+	ESR_EL2,	/* Exception Syndrome Register (EL2) */
+	FAR_EL2,	/* Hypervisor IPA Fault Address Register */
+	HPFAR_EL2,	/* Hypervisor IPA Fault Address Register */
+	MAIR_EL2,	/* Memory Attribute Indirection Register (EL2) */
+	AMAIR_EL2,	/* Auxiliary Memory Attribute Indirection Register (EL2) */
+	VBAR_EL2,	/* Vector Base Address Register (EL2) */
+	RVBAR_EL2,	/* Reset Vector Base Address Register */
+	CONTEXTIDR_EL2,	/* Context ID Register (EL2) */
+	TPIDR_EL2,	/* EL2 Software Thread ID Register */
+	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
+	SP_EL2,		/* EL2 Stack Pointer */
+
 	NR_SYS_REGS	/* Nothing after this line! */
 };
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:14 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:14 +0000
Subject: [PATCH v6 06/64] KVM: arm64: nv: Add nested virt VCPU primitives for
 vEL2 VCPU state
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-7-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

When running a nested hypervisor we commonly have to figure out if
the VCPU mode is running in the context of a guest hypervisor or guest
guest, or just a normal guest.

Add convenient primitives for this.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h | 53 ++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index d62405ce3e6d..ea9a130c4b6a 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -178,6 +178,59 @@ static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
 		vcpu_gp_regs(vcpu)->regs[reg_num] = val;
 }
 
+static inline bool vcpu_is_el2_ctxt(const struct kvm_cpu_context *ctxt)
+{
+	switch (ctxt->regs.pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) {
+	case PSR_MODE_EL2h:
+	case PSR_MODE_EL2t:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static inline bool vcpu_is_el2(const struct kvm_vcpu *vcpu)
+{
+	return vcpu_is_el2_ctxt(&vcpu->arch.ctxt);
+}
+
+static inline bool __vcpu_el2_e2h_is_set(const struct kvm_cpu_context *ctxt)
+{
+	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_E2H;
+}
+
+static inline bool vcpu_el2_e2h_is_set(const struct kvm_vcpu *vcpu)
+{
+	return __vcpu_el2_e2h_is_set(&vcpu->arch.ctxt);
+}
+
+static inline bool __vcpu_el2_tge_is_set(const struct kvm_cpu_context *ctxt)
+{
+	return ctxt_sys_reg(ctxt, HCR_EL2) & HCR_TGE;
+}
+
+static inline bool vcpu_el2_tge_is_set(const struct kvm_vcpu *vcpu)
+{
+	return __vcpu_el2_tge_is_set(&vcpu->arch.ctxt);
+}
+
+static inline bool __is_hyp_ctxt(const struct kvm_cpu_context *ctxt)
+{
+	/*
+	 * We are in a hypervisor context if the vcpu mode is EL2 or
+	 * E2H and TGE bits are set. The latter means we are in the user space
+	 * of the VHE kernel. ARMv8.1 ARM describes this as 'InHost'
+	 */
+	return vcpu_is_el2_ctxt(ctxt) ||
+		(__vcpu_el2_e2h_is_set(ctxt) && __vcpu_el2_tge_is_set(ctxt)) ||
+		WARN_ON(__vcpu_el2_tge_is_set(ctxt));
+}
+
+static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
+{
+	return __is_hyp_ctxt(&vcpu->arch.ctxt);
+}
+
 /*
  * The layout of SPSR for an AArch32 state is different when observed from an
  * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:10 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:10 +0000
Subject: [PATCH v6 02/64] KVM: arm64: nv: Introduce nested virtualization VCPU
 feature
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-3-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Introduce the feature bit and a primitive that checks if the feature is
set behind a static key check based on the cpus_have_const_cap check.

Checking vcpu_has_nv() on systems without nested virt enabled
should have negligible overhead.

We don't yet allow userspace to actually set this feature.

Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 14 ++++++++++++++
 arch/arm64/include/uapi/asm/kvm.h   |  1 +
 2 files changed, 15 insertions(+)
 create mode 100644 arch/arm64/include/asm/kvm_nested.h

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
new file mode 100644
index 000000000000..fd601ea68d13
--- /dev/null
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ARM64_KVM_NESTED_H
+#define __ARM64_KVM_NESTED_H
+
+#include <linux/kvm_host.h>
+
+static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
+{
+	return (!__is_defined(__KVM_NVHE_HYPERVISOR__) &&
+		cpus_have_final_cap(ARM64_HAS_NESTED_VIRT) &&
+		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
+}
+
+#endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index b3edde68bc3e..395a4c039bcc 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -106,6 +106,7 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_SVE		4 /* enable SVE for this CPU */
 #define KVM_ARM_VCPU_PTRAUTH_ADDRESS	5 /* VCPU uses address authentication */
 #define KVM_ARM_VCPU_PTRAUTH_GENERIC	6 /* VCPU uses generic authentication */
+#define KVM_ARM_VCPU_HAS_EL2		7 /* Support nested virtualization */
 
 struct kvm_vcpu_init {
 	__u32 target;
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:08 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:08 +0000
Subject: [PATCH v6 00/64] KVM: arm64: ARMv8.3/8.4 Nested Virtualization support
Message-ID: <20220128121912.509006-1-maz@kernel.org>

Here the first drop of the KVM/arm64 NV support code for 2022. Nothing
to worry about, it certainly isn't going to be the last!

A number of changes since [1]:

- The exposure of the EL2 sysregs to userspace is now gated by NV
  being enabled, as you'd expect. Which means we shouldn't break live
  migration anymore (yay!).

- We now correctly detect and handle an Illegal Exception Return from
  vEL2. Don't try this at home, kids!

- Non-nested exception injection when executing at EL0 has been fixed.

- We forbid NV+SVE for now. This is a change in ABI, and I hope to
  remove this requirement at some point. I've pushed out a kvmtool
  change that enforces this [2], and QEMU will need similar surgery
  for now.

- nested_virt_in_use() is now renamed to vcpu_has_nv() (resp
  vcpu_has_nv2() for the v8.4 support).

- A bunch of small nits being tidied up, thanks to our eagle eyed
  reviewers.

Many thanks to Alexandru, Chase, Ganapatrao and Russell for spending a
lot of time reviewing this and actively spotting issues. There is a
pending issue that Ganapatrao mentioned when running L0 with 4kB and
L1 with 64kB, resulting in no forward progress. I haven't investigated
this yet, but I strongly suspect that something is amiss in the S2 PTW
at the point where we combine the L2 IPA with the L1 IPA.

As usual, blame me for any bug, and nobody else. It has been tested on
my usual zoo, and nothing caught fire. Which means nothing, of course.
Obviously, it isn't feature complete, and it is quite easy to write a
guest that will not behave as intended. The current goal is to make
sure that non-NV KVM is unaffected by the NV stuff.

It is massively painful to run on the FVP, but if you have a Neoverse
V1 or N2 system (or anything else with ARMv8.4-NV) that is collecting
dust, I have the right stuff to keep it busy.

	M.

[1] https://lore.kernel.org/r/20211129200150.351436-1-maz at kernel.org
[2] https://git.kernel.org/pub/scm/linux/kernel/git/maz/kvmtool.git/log/?h=arm64/nv-5.16

Andre Przywara (1):
  KVM: arm64: nv: vgic: Allow userland to set VGIC maintenance IRQ

Christoffer Dall (15):
  KVM: arm64: nv: Introduce nested virtualization VCPU feature
  KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU nested virt is set
  KVM: arm64: nv: Allow userspace to set PSR_MODE_EL2x
  KVM: arm64: nv: Add nested virt VCPU primitives for vEL2 VCPU state
  KVM: arm64: nv: Reset VMPIDR_EL2 and VPIDR_EL2 to sane values
  KVM: arm64: nv: Handle trapped ERET from virtual EL2
  KVM: arm64: nv: Emulate PSTATE.M for a guest hypervisor
  KVM: arm64: nv: Trap EL1 VM register accesses in virtual EL2
  KVM: arm64: nv: Only toggle cache for virtual EL2 when SCTLR_EL2
    changes
  KVM: arm64: nv: Implement nested Stage-2 page table walk logic
  KVM: arm64: nv: Unmap/flush shadow stage 2 page tables
  KVM: arm64: nv: arch_timer: Support hyp timer emulation
  KVM: arm64: nv: vgic: Emulate the HW bit in software
  KVM: arm64: nv: Add nested GICv3 tracepoints
  KVM: arm64: nv: Sync nested timer state with ARMv8.4

Jintack Lim (18):
  arm64: Add ARM64_HAS_NESTED_VIRT cpufeature
  KVM: arm64: nv: Handle HCR_EL2.NV system register traps
  KVM: arm64: nv: Support virtual EL2 exceptions
  KVM: arm64: nv: Inject HVC exceptions to the virtual EL2
  KVM: arm64: nv: Trap SPSR_EL1, ELR_EL1 and VBAR_EL1 from virtual EL2
  KVM: arm64: nv: Trap CPACR_EL1 access in virtual EL2
  KVM: arm64: nv: Handle PSCI call via smc from the guest
  KVM: arm64: nv: Respect virtual HCR_EL2.TWX setting
  KVM: arm64: nv: Respect virtual CPTR_EL2.{TFP,FPEN} settings
  KVM: arm64: nv: Respect the virtual HCR_EL2.NV bit setting
  KVM: arm64: nv: Respect virtual HCR_EL2.TVM and TRVM settings
  KVM: arm64: nv: Respect the virtual HCR_EL2.NV1 bit setting
  KVM: arm64: nv: Emulate EL12 register accesses from the virtual EL2
  KVM: arm64: nv: Configure HCR_EL2 for nested virtualization
  KVM: arm64: nv: Set a handler for the system instruction traps
  KVM: arm64: nv: Trap and emulate AT instructions from virtual EL2
  KVM: arm64: nv: Trap and emulate TLBI instructions from virtual EL2
  KVM: arm64: nv: Nested GICv3 Support

Marc Zyngier (30):
  KVM: arm64: nv: Add EL2 system registers to vcpu context
  KVM: arm64: nv: Add non-VHE-EL2->EL1 translation helpers
  KVM: arm64: nv: Handle virtual EL2 registers in
    vcpu_read/write_sys_reg()
  KVM: arm64: nv: Handle SPSR_EL2 specially
  KVM: arm64: nv: Handle HCR_EL2.E2H specially
  KVM: arm64: nv: Save/Restore vEL2 sysregs
  KVM: arm64: nv: Allow a sysreg to be hidden from userspace only
  KVM: arm64: nv: Forward debug traps to the nested guest
  KVM: arm64: nv: Filter out unsupported features from ID regs
  KVM: arm64: nv: Hide RAS from nested guests
  KVM: arm64: nv: Support multiple nested Stage-2 mmu structures
  KVM: arm64: nv: Handle shadow stage 2 page faults
  KVM: arm64: nv: Restrict S2 RD/WR permissions to match the guest's
  KVM: arm64: nv: Fold guest's HCR_EL2 configuration into the host's
  KVM: arm64: nv: Add handling of EL2-specific timer registers
  KVM: arm64: nv: Load timer before the GIC
  KVM: arm64: nv: Don't load the GICv4 context on entering a nested
    guest
  KVM: arm64: nv: Implement maintenance interrupt forwarding
  KVM: arm64: nv: Allow userspace to request KVM_ARM_VCPU_NESTED_VIRT
  KVM: arm64: nv: Add handling of ARMv8.4-TTL TLB invalidation
  KVM: arm64: nv: Invalidate TLBs based on shadow S2 TTL-like
    information
  KVM: arm64: nv: Tag shadow S2 entries with nested level
  KVM: arm64: nv: Add include containing the VNCR_EL2 offsets
  KVM: arm64: nv: Map VNCR-capable registers to a separate page
  KVM: arm64: nv: Move nested vgic state into the sysreg file
  KVM: arm64: Add ARMv8.4 Enhanced Nested Virt cpufeature
  KVM: arm64: nv: Allocate VNCR page when required
  KVM: arm64: nv: Enable ARMv8.4-NV support
  KVM: arm64: nv: Fast-track 'InHost' exception returns
  KVM: arm64: nv: Fast-track EL1 TLBIs for VHE guests

 .../admin-guide/kernel-parameters.txt         |    7 +-
 .../virt/kvm/devices/arm-vgic-v3.rst          |   12 +-
 arch/arm64/include/asm/esr.h                  |    5 +
 arch/arm64/include/asm/kvm_arm.h              |   27 +-
 arch/arm64/include/asm/kvm_asm.h              |    4 +
 arch/arm64/include/asm/kvm_emulate.h          |  143 +-
 arch/arm64/include/asm/kvm_host.h             |  185 ++-
 arch/arm64/include/asm/kvm_hyp.h              |    2 +
 arch/arm64/include/asm/kvm_mmu.h              |   18 +-
 arch/arm64/include/asm/kvm_nested.h           |  156 ++
 arch/arm64/include/asm/sysreg.h               |  101 +-
 arch/arm64/include/asm/vncr_mapping.h         |   74 +
 arch/arm64/include/uapi/asm/kvm.h             |    2 +
 arch/arm64/kernel/cpufeature.c                |   34 +
 arch/arm64/kvm/Makefile                       |    4 +-
 arch/arm64/kvm/arch_timer.c                   |  202 ++-
 arch/arm64/kvm/arm.c                          |   42 +-
 arch/arm64/kvm/at.c                           |  219 +++
 arch/arm64/kvm/emulate-nested.c               |  211 +++
 arch/arm64/kvm/guest.c                        |    6 +
 arch/arm64/kvm/handle_exit.c                  |   81 +-
 arch/arm64/kvm/hyp/exception.c                |   49 +-
 arch/arm64/kvm/hyp/include/hyp/switch.h       |   12 +-
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h    |   24 +-
 arch/arm64/kvm/hyp/nvhe/switch.c              |    2 +-
 arch/arm64/kvm/hyp/nvhe/sysreg-sr.c           |    2 +-
 arch/arm64/kvm/hyp/vgic-v3-sr.c               |    2 +-
 arch/arm64/kvm/hyp/vhe/switch.c               |  181 ++-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c            |  125 +-
 arch/arm64/kvm/hyp/vhe/tlb.c                  |   83 ++
 arch/arm64/kvm/inject_fault.c                 |   68 +-
 arch/arm64/kvm/mmu.c                          |  206 ++-
 arch/arm64/kvm/nested.c                       |  915 ++++++++++++
 arch/arm64/kvm/reset.c                        |   30 +-
 arch/arm64/kvm/sys_regs.c                     | 1252 ++++++++++++++++-
 arch/arm64/kvm/sys_regs.h                     |   14 +-
 arch/arm64/kvm/trace_arm.h                    |   65 +-
 arch/arm64/kvm/vgic/vgic-init.c               |   30 +
 arch/arm64/kvm/vgic/vgic-kvm-device.c         |   22 +
 arch/arm64/kvm/vgic/vgic-nested-trace.h       |  137 ++
 arch/arm64/kvm/vgic/vgic-v3-nested.c          |  242 ++++
 arch/arm64/kvm/vgic/vgic-v3.c                 |   39 +-
 arch/arm64/kvm/vgic/vgic.c                    |   44 +
 arch/arm64/kvm/vgic/vgic.h                    |   10 +
 arch/arm64/tools/cpucaps                      |    2 +
 include/kvm/arm_arch_timer.h                  |    9 +-
 include/kvm/arm_vgic.h                        |   16 +
 include/uapi/linux/kvm.h                      |    1 +
 tools/arch/arm/include/uapi/asm/kvm.h         |    1 +
 49 files changed, 4947 insertions(+), 171 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_nested.h
 create mode 100644 arch/arm64/include/asm/vncr_mapping.h
 create mode 100644 arch/arm64/kvm/at.c
 create mode 100644 arch/arm64/kvm/emulate-nested.c
 create mode 100644 arch/arm64/kvm/nested.c
 create mode 100644 arch/arm64/kvm/vgic/vgic-nested-trace.h
 create mode 100644 arch/arm64/kvm/vgic/vgic-v3-nested.c

-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:16 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:16 +0000
Subject: [PATCH v6 08/64] KVM: arm64: nv: Reset VMPIDR_EL2 and VPIDR_EL2 to
 sane values
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-9-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

The VMPIDR_EL2 and VPIDR_EL2 are architecturally UNKNOWN at reset, but
let's be nice to a guest hypervisor behaving foolishly and reset these
to something reasonable anyway.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 06ca98458815..25386cb622c5 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -591,7 +591,7 @@ static void reset_actlr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 	vcpu_write_sys_reg(vcpu, actlr, ACTLR_EL1);
 }
 
-static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+static u64 compute_reset_mpidr(struct kvm_vcpu *vcpu)
 {
 	u64 mpidr;
 
@@ -605,7 +605,24 @@ static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
 	mpidr = (vcpu->vcpu_id & 0x0f) << MPIDR_LEVEL_SHIFT(0);
 	mpidr |= ((vcpu->vcpu_id >> 4) & 0xff) << MPIDR_LEVEL_SHIFT(1);
 	mpidr |= ((vcpu->vcpu_id >> 12) & 0xff) << MPIDR_LEVEL_SHIFT(2);
-	vcpu_write_sys_reg(vcpu, (1ULL << 31) | mpidr, MPIDR_EL1);
+	mpidr |= (1ULL << 31);
+
+	return mpidr;
+}
+
+static void reset_mpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	vcpu_write_sys_reg(vcpu, compute_reset_mpidr(vcpu), MPIDR_EL1);
+}
+
+static void reset_vmpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	vcpu_write_sys_reg(vcpu, compute_reset_mpidr(vcpu), VMPIDR_EL2);
+}
+
+static void reset_vpidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
+{
+	vcpu_write_sys_reg(vcpu, read_cpuid_id(), VPIDR_EL2);
 }
 
 static unsigned int pmu_visibility(const struct kvm_vcpu *vcpu,
@@ -1873,8 +1890,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
 	  .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
 
-	EL2_REG(VPIDR_EL2, access_rw, reset_val, 0),
-	EL2_REG(VMPIDR_EL2, access_rw, reset_val, 0),
+	EL2_REG(VPIDR_EL2, access_rw, reset_vpidr, 0),
+	EL2_REG(VMPIDR_EL2, access_rw, reset_vmpidr, 0),
 	EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
 	EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
 	EL2_REG(HCR_EL2, access_rw, reset_val, 0),
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:15 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:15 +0000
Subject: [PATCH v6 07/64] KVM: arm64: nv: Handle HCR_EL2.NV system register
 traps
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-8-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

ARM v8.3 introduces a new bit in the HCR_EL2, which is the NV bit. When
this bit is set, accessing EL2 registers in EL1 traps to EL2. In
addition, executing the following instructions in EL1 will trap to EL2:
tlbi, at, eret, and msr/mrs instructions to access SP_EL1. Most of the
instructions that trap to EL2 with the NV bit were undef at EL1 prior to
ARM v8.3. The only instruction that was not undef is eret.

This patch sets up a handler for EL2 registers and SP_EL1 register
accesses at EL1. The host hypervisor keeps those register values in
memory, and will emulate their behavior.

This patch doesn't set the NV bit yet. It will be set in a later patch
once nested virtualization support is completed.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: EL2_REG() macros]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h | 41 +++++++++++++-
 arch/arm64/kvm/sys_regs.c       | 99 +++++++++++++++++++++++++++++++--
 2 files changed, 134 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 898bee0004ae..61c990e5591a 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -532,10 +532,26 @@
 
 #define SYS_PMCCFILTR_EL0		sys_reg(3, 3, 14, 15, 7)
 
+#define SYS_VPIDR_EL2			sys_reg(3, 4, 0, 0, 0)
+#define SYS_VMPIDR_EL2			sys_reg(3, 4, 0, 0, 5)
+
 #define SYS_SCTLR_EL2			sys_reg(3, 4, 1, 0, 0)
+#define SYS_ACTLR_EL2			sys_reg(3, 4, 1, 0, 1)
+#define SYS_HCR_EL2			sys_reg(3, 4, 1, 1, 0)
+#define SYS_MDCR_EL2			sys_reg(3, 4, 1, 1, 1)
+#define SYS_CPTR_EL2			sys_reg(3, 4, 1, 1, 2)
+#define SYS_HSTR_EL2			sys_reg(3, 4, 1, 1, 3)
 #define SYS_HFGRTR_EL2			sys_reg(3, 4, 1, 1, 4)
 #define SYS_HFGWTR_EL2			sys_reg(3, 4, 1, 1, 5)
 #define SYS_HFGITR_EL2			sys_reg(3, 4, 1, 1, 6)
+#define SYS_HACR_EL2			sys_reg(3, 4, 1, 1, 7)
+
+#define SYS_TTBR0_EL2			sys_reg(3, 4, 2, 0, 0)
+#define SYS_TTBR1_EL2			sys_reg(3, 4, 2, 0, 1)
+#define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
+#define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
+#define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
+
 #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
 #define SYS_DACR32_EL2			sys_reg(3, 4, 3, 0, 0)
@@ -544,14 +560,26 @@
 #define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
 #define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
 #define SYS_ELR_EL2			sys_reg(3, 4, 4, 0, 1)
+#define SYS_SP_EL1			sys_reg(3, 4, 4, 1, 0)
 #define SYS_IFSR32_EL2			sys_reg(3, 4, 5, 0, 1)
+#define SYS_AFSR0_EL2			sys_reg(3, 4, 5, 1, 0)
+#define SYS_AFSR1_EL2			sys_reg(3, 4, 5, 1, 1)
 #define SYS_ESR_EL2			sys_reg(3, 4, 5, 2, 0)
 #define SYS_VSESR_EL2			sys_reg(3, 4, 5, 2, 3)
 #define SYS_FPEXC32_EL2			sys_reg(3, 4, 5, 3, 0)
 #define SYS_TFSR_EL2			sys_reg(3, 4, 5, 6, 0)
 #define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
 
-#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1,  1)
+#define SYS_FAR_EL2			sys_reg(3, 4, 6, 0, 0)
+#define SYS_HPFAR_EL2			sys_reg(3, 4, 6, 0, 4)
+
+#define SYS_MAIR_EL2			sys_reg(3, 4, 10, 2, 0)
+#define SYS_AMAIR_EL2			sys_reg(3, 4, 10, 3, 0)
+
+#define SYS_VBAR_EL2			sys_reg(3, 4, 12, 0, 0)
+#define SYS_RVBAR_EL2			sys_reg(3, 4, 12, 0, 1)
+#define SYS_RMR_EL2			sys_reg(3, 4, 12, 0, 2)
+#define SYS_VDISR_EL2			sys_reg(3, 4, 12, 1, 1)
 #define __SYS__AP0Rx_EL2(x)		sys_reg(3, 4, 12, 8, x)
 #define SYS_ICH_AP0R0_EL2		__SYS__AP0Rx_EL2(0)
 #define SYS_ICH_AP0R1_EL2		__SYS__AP0Rx_EL2(1)
@@ -593,15 +621,24 @@
 #define SYS_ICH_LR14_EL2		__SYS__LR8_EL2(6)
 #define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)
 
+#define SYS_CONTEXTIDR_EL2		sys_reg(3, 4, 13, 0, 1)
+#define SYS_TPIDR_EL2			sys_reg(3, 4, 13, 0, 2)
+
+#define SYS_CNTVOFF_EL2			sys_reg(3, 4, 14, 0, 3)
+#define SYS_CNTHCTL_EL2			sys_reg(3, 4, 14, 1, 0)
+
 /* VHE encodings for architectural EL0/1 system registers */
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
 #define SYS_CPACR_EL12			sys_reg(3, 5, 1, 0, 2)
 #define SYS_ZCR_EL12			sys_reg(3, 5, 1, 2, 0)
+
 #define SYS_TTBR0_EL12			sys_reg(3, 5, 2, 0, 0)
 #define SYS_TTBR1_EL12			sys_reg(3, 5, 2, 0, 1)
 #define SYS_TCR_EL12			sys_reg(3, 5, 2, 0, 2)
+
 #define SYS_SPSR_EL12			sys_reg(3, 5, 4, 0, 0)
 #define SYS_ELR_EL12			sys_reg(3, 5, 4, 0, 1)
+
 #define SYS_AFSR0_EL12			sys_reg(3, 5, 5, 1, 0)
 #define SYS_AFSR1_EL12			sys_reg(3, 5, 5, 1, 1)
 #define SYS_ESR_EL12			sys_reg(3, 5, 5, 2, 0)
@@ -619,6 +656,8 @@
 #define SYS_CNTV_CTL_EL02		sys_reg(3, 5, 14, 3, 1)
 #define SYS_CNTV_CVAL_EL02		sys_reg(3, 5, 14, 3, 2)
 
+#define SYS_SP_EL2			sys_reg(3, 6,  4, 1, 0)
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4dc2fba316ff..06ca98458815 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -24,6 +24,7 @@
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/perf_event.h>
 #include <asm/sysreg.h>
 
@@ -105,6 +106,18 @@ static u32 get_ccsidr(u32 csselr)
 	return ccsidr;
 }
 
+static bool access_rw(struct kvm_vcpu *vcpu,
+		      struct sys_reg_params *p,
+		      const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
+	else
+		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
+
+	return true;
+}
+
 /*
  * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
  */
@@ -263,6 +276,14 @@ static bool trap_raz_wi(struct kvm_vcpu *vcpu,
 		return read_zero(vcpu, p);
 }
 
+static bool trap_undef(struct kvm_vcpu *vcpu,
+		       struct sys_reg_params *p,
+		       const struct sys_reg_desc *r)
+{
+	kvm_inject_undefined(vcpu);
+	return false;
+}
+
 /*
  * ARMv8.1 mandates at least a trivial LORegion implementation, where all the
  * RW registers are RES0 (which we can implement as RAZ/WI). On an ARMv8.0
@@ -342,12 +363,9 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
 			    struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
 {
-	if (p->is_write) {
-		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
+	access_rw(vcpu, p, r);
+	if (p->is_write)
 		vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY;
-	} else {
-		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
-	}
 
 	trace_trap_reg(__func__, r->reg, p->is_write, p->regval);
 
@@ -1378,6 +1396,24 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
 	.visibility = mte_visibility,		\
 }
 
+static unsigned int el2_visibility(const struct kvm_vcpu *vcpu,
+				   const struct sys_reg_desc *rd)
+{
+	if (vcpu_has_nv(vcpu))
+		return 0;
+
+	return REG_HIDDEN;
+}
+
+#define EL2_REG(name, acc, rst, v) {		\
+	SYS_DESC(SYS_##name),			\
+	.access = acc,				\
+	.reset = rst,				\
+	.reg = name,				\
+	.visibility = el2_visibility,		\
+	.val = v,				\
+}
+
 /* sys_reg_desc initialiser for known cpufeature ID registers */
 #define ID_SANITISED(name) {			\
 	SYS_DESC(SYS_##name),			\
@@ -1411,6 +1447,18 @@ static unsigned int mte_visibility(const struct kvm_vcpu *vcpu,
 	.set_user = set_raz_id_reg,		\
 }
 
+static bool access_sp_el1(struct kvm_vcpu *vcpu,
+			  struct sys_reg_params *p,
+			  const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		__vcpu_sys_reg(vcpu, SP_EL1) = p->regval;
+	else
+		p->regval = __vcpu_sys_reg(vcpu, SP_EL1);
+
+	return true;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -1825,9 +1873,50 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ PMU_SYS_REG(SYS_PMCCFILTR_EL0), .access = access_pmu_evtyper,
 	  .reset = reset_val, .reg = PMCCFILTR_EL0, .val = 0 },
 
+	EL2_REG(VPIDR_EL2, access_rw, reset_val, 0),
+	EL2_REG(VMPIDR_EL2, access_rw, reset_val, 0),
+	EL2_REG(SCTLR_EL2, access_rw, reset_val, SCTLR_EL2_RES1),
+	EL2_REG(ACTLR_EL2, access_rw, reset_val, 0),
+	EL2_REG(HCR_EL2, access_rw, reset_val, 0),
+	EL2_REG(MDCR_EL2, access_rw, reset_val, 0),
+	EL2_REG(CPTR_EL2, access_rw, reset_val, CPTR_EL2_DEFAULT ),
+	EL2_REG(HSTR_EL2, access_rw, reset_val, 0),
+	EL2_REG(HACR_EL2, access_rw, reset_val, 0),
+
+	EL2_REG(TTBR0_EL2, access_rw, reset_val, 0),
+	EL2_REG(TTBR1_EL2, access_rw, reset_val, 0),
+	EL2_REG(TCR_EL2, access_rw, reset_val, TCR_EL2_RES1),
+	EL2_REG(VTTBR_EL2, access_rw, reset_val, 0),
+	EL2_REG(VTCR_EL2, access_rw, reset_val, 0),
+
 	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
+	EL2_REG(SPSR_EL2, access_rw, reset_val, 0),
+	EL2_REG(ELR_EL2, access_rw, reset_val, 0),
+	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
+
 	{ SYS_DESC(SYS_IFSR32_EL2), NULL, reset_unknown, IFSR32_EL2 },
+	EL2_REG(AFSR0_EL2, access_rw, reset_val, 0),
+	EL2_REG(AFSR1_EL2, access_rw, reset_val, 0),
+	EL2_REG(ESR_EL2, access_rw, reset_val, 0),
 	{ SYS_DESC(SYS_FPEXC32_EL2), NULL, reset_val, FPEXC32_EL2, 0x700 },
+
+	EL2_REG(FAR_EL2, access_rw, reset_val, 0),
+	EL2_REG(HPFAR_EL2, access_rw, reset_val, 0),
+
+	EL2_REG(MAIR_EL2, access_rw, reset_val, 0),
+	EL2_REG(AMAIR_EL2, access_rw, reset_val, 0),
+
+	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
+	EL2_REG(RVBAR_EL2, access_rw, reset_val, 0),
+	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
+
+	EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
+	EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
+
+	EL2_REG(CNTVOFF_EL2, access_rw, reset_val, 0),
+	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
+
+	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:17 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:17 +0000
Subject: [PATCH v6 09/64] KVM: arm64: nv: Support virtual EL2 exceptions
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-10-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Support injecting exceptions and performing exception returns to and
from virtual EL2.  This must be done entirely in software except when
taking an exception from vEL0 to vEL2 when the virtual HCR_EL2.{E2H,TGE}
== {1,1}  (a VHE guest hypervisor).

Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: switch to common exception injection framework, illegal exeption
 return handling]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h     |  17 +++
 arch/arm64/include/asm/kvm_emulate.h |  10 ++
 arch/arm64/include/asm/kvm_host.h    |   1 +
 arch/arm64/kvm/Makefile              |   2 +-
 arch/arm64/kvm/emulate-nested.c      | 197 +++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/exception.c       |  49 +++++--
 arch/arm64/kvm/inject_fault.c        |  68 +++++++--
 arch/arm64/kvm/trace_arm.h           |  59 ++++++++
 8 files changed, 382 insertions(+), 21 deletions(-)
 create mode 100644 arch/arm64/kvm/emulate-nested.c

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 01d47c5886dc..e6e3aae87a09 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -359,4 +359,21 @@
 #define CPACR_EL1_TTA		(1 << 28)
 #define CPACR_EL1_DEFAULT	(CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN)
 
+#define kvm_mode_names				\
+	{ PSR_MODE_EL0t,	"EL0t" },	\
+	{ PSR_MODE_EL1t,	"EL1t" },	\
+	{ PSR_MODE_EL1h,	"EL1h" },	\
+	{ PSR_MODE_EL2t,	"EL2t" },	\
+	{ PSR_MODE_EL2h,	"EL2h" },	\
+	{ PSR_MODE_EL3t,	"EL3t" },	\
+	{ PSR_MODE_EL3h,	"EL3h" },	\
+	{ PSR_AA32_MODE_USR,	"32-bit USR" },	\
+	{ PSR_AA32_MODE_FIQ,	"32-bit FIQ" },	\
+	{ PSR_AA32_MODE_IRQ,	"32-bit IRQ" },	\
+	{ PSR_AA32_MODE_SVC,	"32-bit SVC" },	\
+	{ PSR_AA32_MODE_ABT,	"32-bit ABT" },	\
+	{ PSR_AA32_MODE_HYP,	"32-bit HYP" },	\
+	{ PSR_AA32_MODE_UND,	"32-bit UND" },	\
+	{ PSR_AA32_MODE_SYS,	"32-bit SYS" }
+
 #endif /* __ARM64_KVM_ARM_H__ */
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index ea9a130c4b6a..cb9f123d26f3 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -33,6 +33,12 @@ enum exception_type {
 	except_type_serror	= 0x180,
 };
 
+#define kvm_exception_type_names		\
+	{ except_type_sync,	"SYNC"   },	\
+	{ except_type_irq,	"IRQ"    },	\
+	{ except_type_fiq,	"FIQ"    },	\
+	{ except_type_serror,	"SERROR" }
+
 bool kvm_condition_valid32(const struct kvm_vcpu *vcpu);
 void kvm_skip_instr32(struct kvm_vcpu *vcpu);
 
@@ -43,6 +49,10 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr);
 
 void kvm_vcpu_wfi(struct kvm_vcpu *vcpu);
 
+void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu);
+int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2);
+int kvm_inject_nested_irq(struct kvm_vcpu *vcpu);
+
 static __always_inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
 {
 	return !(vcpu->arch.hcr_el2 & HCR_RW);
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 15f690c27baf..8fffe2888403 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -467,6 +467,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_EXCEPT_AA64_ELx_SERR	(3 << 9)
 #define KVM_ARM64_EXCEPT_AA64_EL1	(0 << 11)
 #define KVM_ARM64_EXCEPT_AA64_EL2	(1 << 11)
+#define KVM_ARM64_EXCEPT_AA64_EL_MASK	(1 << 11)
 
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index 91861fd8b897..b67c4ebd72b1 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,7 +14,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
 	 guest.o debug.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o pkvm.o \
-	 arch_timer.o trng.o\
+	 arch_timer.o trng.o emulate-nested.o \
 	 vgic/vgic.o vgic/vgic-init.o \
 	 vgic/vgic-irqfd.o vgic/vgic-v2.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
new file mode 100644
index 000000000000..f52cd4458947
--- /dev/null
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2016 - Linaro and Columbia University
+ * Author: Jintack Lim <jintack.lim at linaro.org>
+ */
+
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
+
+#include "hyp/include/hyp/adjust_pc.h"
+
+#include "trace.h"
+
+static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
+{
+	u64 mode = spsr & PSR_MODE_MASK;
+
+	/*
+	 * Possible causes for an Illegal Exception Return from EL2:
+	 * - trying to return to EL3
+	 * - trying to return to a 32bit EL
+	 * - trying to return to EL1 with HCR_EL2.TGE set
+	 */
+	if (mode == PSR_MODE_EL3t || mode == PSR_MODE_EL3h ||
+	    spsr & PSR_MODE32_BIT ||
+	    (vcpu_el2_tge_is_set(vcpu) && (mode == PSR_MODE_EL1t ||
+					   mode == PSR_MODE_EL1h))) {
+		/*
+		 * The guest is playing with our nerves. Preserve EL, SP,
+		 * masks, flags from the existing PSTATE, and set IL.
+		 * The HW will then generate an Illegal State Exception
+		 * immediately after ERET.
+		 */
+		spsr = *vcpu_cpsr(vcpu);
+
+		spsr &= (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT |
+			 PSR_N_BIT | PSR_Z_BIT | PSR_C_BIT | PSR_V_BIT |
+			 PSR_MODE_MASK | PSR_MODE32_BIT);
+		spsr |= PSR_IL_BIT;
+	}
+
+	return spsr;
+}
+
+void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
+{
+	u64 spsr, elr, mode;
+	bool direct_eret;
+
+	/*
+	 * Going through the whole put/load motions is a waste of time
+	 * if this is a VHE guest hypervisor returning to its own
+	 * userspace, or the hypervisor performing a local exception
+	 * return. No need to save/restore registers, no need to
+	 * switch S2 MMU. Just do the canonical ERET.
+	 */
+	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
+	spsr = kvm_check_illegal_exception_return(vcpu, spsr);
+
+	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+	direct_eret  = (mode == PSR_MODE_EL0t &&
+			vcpu_el2_e2h_is_set(vcpu) &&
+			vcpu_el2_tge_is_set(vcpu));
+	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
+
+	if (direct_eret) {
+		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
+		*vcpu_cpsr(vcpu) = spsr;
+		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
+		return;
+	}
+
+	preempt_disable();
+	kvm_arch_vcpu_put(vcpu);
+
+	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
+
+	trace_kvm_nested_eret(vcpu, elr, spsr);
+
+	/*
+	 * Note that the current exception level is always the virtual EL2,
+	 * since we set HCR_EL2.NV bit only when entering the virtual EL2.
+	 */
+	*vcpu_pc(vcpu) = elr;
+	*vcpu_cpsr(vcpu) = spsr;
+
+	kvm_arch_vcpu_load(vcpu, smp_processor_id());
+	preempt_enable();
+}
+
+static void kvm_inject_el2_exception(struct kvm_vcpu *vcpu, u64 esr_el2,
+				     enum exception_type type)
+{
+	trace_kvm_inject_nested_exception(vcpu, esr_el2, type);
+
+	switch (type) {
+	case except_type_sync:
+		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_SYNC;
+		break;
+	case except_type_irq:
+		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_ELx_IRQ;
+		break;
+	default:
+		WARN_ONCE(1, "Unsupported EL2 exception injection %d\n", type);
+	}
+
+	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL2		|
+			     KVM_ARM64_PENDING_EXCEPTION);
+
+	vcpu_write_sys_reg(vcpu, esr_el2, ESR_EL2);
+}
+
+/*
+ * Emulate taking an exception to EL2.
+ * See ARM ARM J8.1.2 AArch64.TakeException()
+ */
+static int kvm_inject_nested(struct kvm_vcpu *vcpu, u64 esr_el2,
+			     enum exception_type type)
+{
+	u64 pstate, mode;
+	bool direct_inject;
+
+	if (!vcpu_has_nv(vcpu)) {
+		kvm_err("Unexpected call to %s for the non-nesting configuration\n",
+				__func__);
+		return -EINVAL;
+	}
+
+	/*
+	 * As for ERET, we can avoid doing too much on the injection path by
+	 * checking that we either took the exception from a VHE host
+	 * userspace or from vEL2. In these cases, there is no change in
+	 * translation regime (or anything else), so let's do as little as
+	 * possible.
+	 */
+	pstate = *vcpu_cpsr(vcpu);
+	mode = pstate & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+	direct_inject  = (mode == PSR_MODE_EL0t &&
+			  vcpu_el2_e2h_is_set(vcpu) &&
+			  vcpu_el2_tge_is_set(vcpu));
+	direct_inject |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
+
+	if (direct_inject) {
+		kvm_inject_el2_exception(vcpu, esr_el2, type);
+		return 1;
+	}
+
+	preempt_disable();
+	kvm_arch_vcpu_put(vcpu);
+
+	kvm_inject_el2_exception(vcpu, esr_el2, type);
+
+	/*
+	 * A hard requirement is that a switch between EL1 and EL2
+	 * contexts has to happen between a put/load, so that we can
+	 * pick the correct timer and interrupt configuration, among
+	 * other things.
+	 *
+	 * Make sure the exception actually took place before we load
+	 * the new context.
+	 */
+	__kvm_adjust_pc(vcpu);
+
+	kvm_arch_vcpu_load(vcpu, smp_processor_id());
+	preempt_enable();
+
+	return 1;
+}
+
+int kvm_inject_nested_sync(struct kvm_vcpu *vcpu, u64 esr_el2)
+{
+	return kvm_inject_nested(vcpu, esr_el2, except_type_sync);
+}
+
+int kvm_inject_nested_irq(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * Do not inject an irq if the:
+	 *  - Current exception level is EL2, and
+	 *  - virtual HCR_EL2.TGE == 0
+	 *  - virtual HCR_EL2.IMO == 0
+	 *
+	 * See Table D1-17 "Physical interrupt target and masking when EL3 is
+	 * not implemented and EL2 is implemented" in ARM DDI 0487C.a.
+	 */
+
+	if (vcpu_is_el2(vcpu) && !vcpu_el2_tge_is_set(vcpu) &&
+	    !(__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_IMO))
+		return 1;
+
+	/* esr_el2 value doesn't matter for exits due to irqs. */
+	return kvm_inject_nested(vcpu, 0, except_type_irq);
+}
diff --git a/arch/arm64/kvm/hyp/exception.c b/arch/arm64/kvm/hyp/exception.c
index 0418399e0a20..93f9c6f97376 100644
--- a/arch/arm64/kvm/hyp/exception.c
+++ b/arch/arm64/kvm/hyp/exception.c
@@ -13,6 +13,7 @@
 #include <hyp/adjust_pc.h>
 #include <linux/kvm_host.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
 
 #if !defined (__KVM_NVHE_HYPERVISOR__) && !defined (__KVM_VHE_HYPERVISOR__)
 #error Hypervisor code only!
@@ -22,7 +23,9 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 {
 	u64 val;
 
-	if (__vcpu_read_sys_reg_from_cpu(reg, &val))
+	if (unlikely(vcpu_has_nv(vcpu)))
+		return vcpu_read_sys_reg(vcpu, reg);
+	else if (__vcpu_read_sys_reg_from_cpu(reg, &val))
 		return val;
 
 	return __vcpu_sys_reg(vcpu, reg);
@@ -30,14 +33,24 @@ static inline u64 __vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 
 static inline void __vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 {
-	if (__vcpu_write_sys_reg_to_cpu(val, reg))
-		return;
-
-	 __vcpu_sys_reg(vcpu, reg) = val;
+	if (unlikely(vcpu_has_nv(vcpu)))
+		vcpu_write_sys_reg(vcpu, val, reg);
+	else if (!__vcpu_write_sys_reg_to_cpu(val, reg))
+		__vcpu_sys_reg(vcpu, reg) = val;
 }
 
-static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, u64 val)
+static void __vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long target_mode,
+			      u64 val)
 {
+	if (unlikely(vcpu_has_nv(vcpu))) {
+		if (target_mode == PSR_MODE_EL1h)
+			vcpu_write_sys_reg(vcpu, val, SPSR_EL1);
+		else
+			vcpu_write_sys_reg(vcpu, val, SPSR_EL2);
+
+		return;
+	}
+
 	write_sysreg_el1(val, SYS_SPSR);
 }
 
@@ -97,6 +110,11 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
 		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL1);
 		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL1);
 		break;
+	case PSR_MODE_EL2h:
+		vbar = __vcpu_read_sys_reg(vcpu, VBAR_EL2);
+		sctlr = __vcpu_read_sys_reg(vcpu, SCTLR_EL2);
+		__vcpu_write_sys_reg(vcpu, *vcpu_pc(vcpu), ELR_EL2);
+		break;
 	default:
 		/* Don't do that */
 		BUG();
@@ -149,7 +167,7 @@ static void enter_exception64(struct kvm_vcpu *vcpu, unsigned long target_mode,
 	new |= target_mode;
 
 	*vcpu_cpsr(vcpu) = new;
-	__vcpu_write_spsr(vcpu, old);
+	__vcpu_write_spsr(vcpu, target_mode, old);
 }
 
 /*
@@ -320,11 +338,22 @@ static void kvm_inject_exception(struct kvm_vcpu *vcpu)
 		      KVM_ARM64_EXCEPT_AA64_EL1):
 			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync);
 			break;
+
+		case (KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+		      KVM_ARM64_EXCEPT_AA64_EL2):
+			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_sync);
+			break;
+
+		case (KVM_ARM64_EXCEPT_AA64_ELx_IRQ |
+		      KVM_ARM64_EXCEPT_AA64_EL2):
+			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_irq);
+			break;
+
 		default:
 			/*
-			 * Only EL1_SYNC makes sense so far, EL2_{SYNC,IRQ}
-			 * will be implemented at some point. Everything
-			 * else gets silently ignored.
+			 * Only EL1_SYNC and EL2_{SYNC,IRQ} makes
+			 * sense so far. Everything else gets silently
+			 * ignored.
 			 */
 			break;
 		}
diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
index b47df73e98d7..81ceee6998cc 100644
--- a/arch/arm64/kvm/inject_fault.c
+++ b/arch/arm64/kvm/inject_fault.c
@@ -12,19 +12,58 @@
 
 #include <linux/kvm_host.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
 #include <asm/esr.h>
 
+static void pend_sync_exception(struct kvm_vcpu *vcpu)
+{
+	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
+			     KVM_ARM64_PENDING_EXCEPTION);
+
+	/* If not nesting, EL1 is the only possible exception target */
+	if (likely(!vcpu_has_nv(vcpu))) {
+		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
+		return;
+	}
+
+	/*
+	 * With NV, we need to pick between EL1 and EL2. Note that we
+	 * never deal with a nesting exception here, hence never
+	 * changing context, and the exception itself can be delayed
+	 * until the next entry.
+	 */
+	switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
+	case PSR_MODE_EL2h:
+	case PSR_MODE_EL2t:
+		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
+		break;
+	case PSR_MODE_EL1h:
+	case PSR_MODE_EL1t:
+		vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
+		break;
+	case PSR_MODE_EL0t:
+		if (vcpu_el2_tge_is_set(vcpu))
+			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL2;
+		else
+			vcpu->arch.flags |= KVM_ARM64_EXCEPT_AA64_EL1;
+		break;
+	default:
+		BUG();
+	}
+}
+
+static bool match_target_el(struct kvm_vcpu *vcpu, unsigned long target)
+{
+	return (vcpu->arch.flags & KVM_ARM64_EXCEPT_AA64_EL_MASK) == target;
+}
+
 static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr)
 {
 	unsigned long cpsr = *vcpu_cpsr(vcpu);
 	bool is_aarch32 = vcpu_mode_is_32bit(vcpu);
 	u32 esr = 0;
 
-	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1		|
-			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
-			     KVM_ARM64_PENDING_EXCEPTION);
-
-	vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
+	pend_sync_exception(vcpu);
 
 	/*
 	 * Build an {i,d}abort, depending on the level and the
@@ -45,16 +84,22 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
 	if (!is_iabt)
 		esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
 
-	vcpu_write_sys_reg(vcpu, esr | ESR_ELx_FSC_EXTABT, ESR_EL1);
+	esr |= ESR_ELx_FSC_EXTABT;
+
+	if (match_target_el(vcpu, KVM_ARM64_EXCEPT_AA64_EL1)) {
+		vcpu_write_sys_reg(vcpu, addr, FAR_EL1);
+		vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
+	} else {
+		vcpu_write_sys_reg(vcpu, addr, FAR_EL2);
+		vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
+	}
 }
 
 static void inject_undef64(struct kvm_vcpu *vcpu)
 {
 	u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
 
-	vcpu->arch.flags |= (KVM_ARM64_EXCEPT_AA64_EL1		|
-			     KVM_ARM64_EXCEPT_AA64_ELx_SYNC	|
-			     KVM_ARM64_PENDING_EXCEPTION);
+	pend_sync_exception(vcpu);
 
 	/*
 	 * Build an unknown exception, depending on the instruction
@@ -63,7 +108,10 @@ static void inject_undef64(struct kvm_vcpu *vcpu)
 	if (kvm_vcpu_trap_il_is32bit(vcpu))
 		esr |= ESR_ELx_IL;
 
-	vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
+	if (match_target_el(vcpu, KVM_ARM64_EXCEPT_AA64_EL1))
+		vcpu_write_sys_reg(vcpu, esr, ESR_EL1);
+	else
+		vcpu_write_sys_reg(vcpu, esr, ESR_EL2);
 }
 
 #define DFSR_FSC_EXTABT_LPAE	0x10
diff --git a/arch/arm64/kvm/trace_arm.h b/arch/arm64/kvm/trace_arm.h
index 33e4e7dd2719..f3e46a976125 100644
--- a/arch/arm64/kvm/trace_arm.h
+++ b/arch/arm64/kvm/trace_arm.h
@@ -2,6 +2,7 @@
 #if !defined(_TRACE_ARM_ARM64_KVM_H) || defined(TRACE_HEADER_MULTI_READ)
 #define _TRACE_ARM_ARM64_KVM_H
 
+#include <asm/kvm_emulate.h>
 #include <kvm/arm_arch_timer.h>
 #include <linux/tracepoint.h>
 
@@ -301,6 +302,64 @@ TRACE_EVENT(kvm_timer_emulate,
 		  __entry->timer_idx, __entry->should_fire)
 );
 
+TRACE_EVENT(kvm_nested_eret,
+	TP_PROTO(struct kvm_vcpu *vcpu, unsigned long elr_el2,
+		 unsigned long spsr_el2),
+	TP_ARGS(vcpu, elr_el2, spsr_el2),
+
+	TP_STRUCT__entry(
+		__field(struct kvm_vcpu *,	vcpu)
+		__field(unsigned long,		elr_el2)
+		__field(unsigned long,		spsr_el2)
+		__field(unsigned long,		target_mode)
+		__field(unsigned long,		hcr_el2)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu = vcpu;
+		__entry->elr_el2 = elr_el2;
+		__entry->spsr_el2 = spsr_el2;
+		__entry->target_mode = spsr_el2 & (PSR_MODE_MASK | PSR_MODE32_BIT);
+		__entry->hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+	),
+
+	TP_printk("elr_el2: 0x%lx spsr_el2: 0x%08lx (M: %s) hcr_el2: %lx",
+		  __entry->elr_el2, __entry->spsr_el2,
+		  __print_symbolic(__entry->target_mode, kvm_mode_names),
+		  __entry->hcr_el2)
+);
+
+TRACE_EVENT(kvm_inject_nested_exception,
+	TP_PROTO(struct kvm_vcpu *vcpu, u64 esr_el2, int type),
+	TP_ARGS(vcpu, esr_el2, type),
+
+	TP_STRUCT__entry(
+		__field(struct kvm_vcpu *,		vcpu)
+		__field(unsigned long,			esr_el2)
+		__field(int,				type)
+		__field(unsigned long,			spsr_el2)
+		__field(unsigned long,			pc)
+		__field(unsigned long,			source_mode)
+		__field(unsigned long,			hcr_el2)
+	),
+
+	TP_fast_assign(
+		__entry->vcpu = vcpu;
+		__entry->esr_el2 = esr_el2;
+		__entry->type = type;
+		__entry->spsr_el2 = *vcpu_cpsr(vcpu);
+		__entry->pc = *vcpu_pc(vcpu);
+		__entry->source_mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
+		__entry->hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+	),
+
+	TP_printk("%s: esr_el2 0x%lx elr_el2: 0x%lx spsr_el2: 0x%08lx (M: %s) hcr_el2: %lx",
+		  __print_symbolic(__entry->type, kvm_exception_type_names),
+		  __entry->esr_el2, __entry->pc, __entry->spsr_el2,
+		  __print_symbolic(__entry->source_mode, kvm_mode_names),
+		  __entry->hcr_el2)
+);
+
 #endif /* _TRACE_ARM_ARM64_KVM_H */
 
 #undef TRACE_INCLUDE_PATH
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:34 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:34 +0000
Subject: [PATCH v6 26/64] KVM: arm64: nv: Respect the virtual HCR_EL2.NV1 bit
 setting
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-27-maz@kernel.org>

From: Jintack Lim <jintack at cs.columbia.edu>

Forward ELR_EL1, SPSR_EL1 and VBAR_EL1 traps to the virtual EL2 if the
virtual HCR_EL2.NV bit is set.

This is for recursive nested virtualization.

Signed-off-by: Jintack Lim <jintack at cs.columbia.edu>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h    |  1 +
 arch/arm64/include/asm/kvm_nested.h |  1 +
 arch/arm64/kvm/emulate-nested.c     |  5 +++++
 arch/arm64/kvm/sys_regs.c           | 22 +++++++++++++++++++++-
 4 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 8043827e7dc0..748c2b068d4e 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -20,6 +20,7 @@
 #define HCR_AMVOFFEN	(UL(1) << 51)
 #define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
+#define HCR_NV1		(UL(1) << 43)
 #define HCR_NV		(UL(1) << 42)
 #define HCR_API		(UL(1) << 41)
 #define HCR_APK		(UL(1) << 40)
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 37ff6458296d..82fc8b6c990b 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -68,5 +68,6 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
 extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
+extern bool forward_nv1_traps(struct kvm_vcpu *vcpu);
 
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 7dd98d6e96e0..0109dfd664dd 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -33,6 +33,11 @@ bool forward_nv_traps(struct kvm_vcpu *vcpu)
 	return forward_traps(vcpu, HCR_NV);
 }
 
+bool forward_nv1_traps(struct kvm_vcpu *vcpu)
+{
+	return forward_traps(vcpu, HCR_NV1);
+}
+
 static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
 {
 	u64 mode = spsr & PSR_MODE_MASK;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index edaf287c7ec9..31d739d59f67 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -288,6 +288,16 @@ static bool access_rw(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_vbar_el1(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (forward_nv1_traps(vcpu))
+		return false;
+
+	return access_rw(vcpu, p, r);
+}
+
 /*
  * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
  */
@@ -1669,6 +1679,7 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+
 static bool access_elr(struct kvm_vcpu *vcpu,
 		       struct sys_reg_params *p,
 		       const struct sys_reg_desc *r)
@@ -1676,6 +1687,9 @@ static bool access_elr(struct kvm_vcpu *vcpu,
 	if (el12_reg(p) && forward_nv_traps(vcpu))
 		return false;
 
+	if (!el12_reg(p) && forward_nv1_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		vcpu_write_sys_reg(vcpu, p->regval, ELR_EL1);
 	else
@@ -1691,6 +1705,9 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
 	if (el12_reg(p) && forward_nv_traps(vcpu))
 		return false;
 
+	if (!el12_reg(p) && forward_nv1_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		__vcpu_sys_reg(vcpu, SPSR_EL1) = p->regval;
 	else
@@ -1706,6 +1723,9 @@ static bool access_spsr_el2(struct kvm_vcpu *vcpu,
 	if (el12_reg(p) && forward_nv_traps(vcpu))
 		return false;
 
+	if (!el12_reg(p) && forward_nv1_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		vcpu_write_sys_reg(vcpu, p->regval, SPSR_EL2);
 	else
@@ -1914,7 +1934,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_LORC_EL1), trap_loregion },
 	{ SYS_DESC(SYS_LORID_EL1), trap_loregion },
 
-	{ SYS_DESC(SYS_VBAR_EL1), access_rw, reset_val, VBAR_EL1, 0 },
+	{ SYS_DESC(SYS_VBAR_EL1), access_vbar_el1, reset_val, VBAR_EL1, 0 },
 	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
 
 	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:21 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:21 +0000
Subject: [PATCH v6 13/64] KVM: arm64: nv: Handle virtual EL2 registers in
 vcpu_read/write_sys_reg()
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-14-maz@kernel.org>

KVM internally uses accessor functions when reading or writing the
guest's system registers. This takes care of accessing either the stored
copy or using the "live" EL1 system registers when the host uses VHE.

With the introduction of virtual EL2 we add a bunch of EL2 system
registers, which now must also be taken care of:
- If the guest is running in vEL2, and we access an EL1 sysreg, we must
  revert to the stored version of that, and not use the CPU's copy.
- If the guest is running in vEL1, and we access an EL2 sysreg, we must
  also use the stored version, since the CPU carries the EL1 copy.
- Some EL2 system registers are supposed to affect the current execution
  of the system, so we need to put them into their respective EL1
  counterparts. For this we need to define a mapping between the two.
  This is done using the newly introduced struct el2_sysreg_map.
- Some EL2 system registers have a different format than their EL1
  counterpart, so we need to translate them before writing them to the
  CPU. This is done using an (optional) translate function in the map.
- There are the three special registers SP_EL2, SPSR_EL2 and ELR_EL2,
  which need some separate handling (SPSR_EL2 is being handled in a
  separate patch).

All of these cases are now wrapped into the existing accessor functions,
so KVM users wouldn't need to care whether they access EL2 or EL1
registers and also which state the guest is in.

This handles what was formerly known as the "shadow state" dynamically,
without requiring a separate copy for each vCPU EL.

Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>
Co-developed-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 142 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 138 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 25386cb622c5..0927e6c345b4 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -65,23 +65,157 @@ static bool write_to_read_only(struct kvm_vcpu *vcpu,
 	return false;
 }
 
+#define PURE_EL2_SYSREG(el2)						\
+	case el2: {							\
+		*el1r = el2;						\
+		return true;						\
+	}
+
+#define MAPPED_EL2_SYSREG(el2, el1, fn)					\
+	case el2: {							\
+		*xlate = fn;						\
+		*el1r = el1;						\
+		return true;						\
+	}
+
+static bool get_el2_to_el1_mapping(unsigned int reg,
+				   unsigned int *el1r, u64 (**xlate)(u64))
+{
+	switch (reg) {
+		PURE_EL2_SYSREG(  VPIDR_EL2	);
+		PURE_EL2_SYSREG(  VMPIDR_EL2	);
+		PURE_EL2_SYSREG(  ACTLR_EL2	);
+		PURE_EL2_SYSREG(  HCR_EL2	);
+		PURE_EL2_SYSREG(  MDCR_EL2	);
+		PURE_EL2_SYSREG(  HSTR_EL2	);
+		PURE_EL2_SYSREG(  HACR_EL2	);
+		PURE_EL2_SYSREG(  VTTBR_EL2	);
+		PURE_EL2_SYSREG(  VTCR_EL2	);
+		PURE_EL2_SYSREG(  RVBAR_EL2	);
+		PURE_EL2_SYSREG(  TPIDR_EL2	);
+		PURE_EL2_SYSREG(  HPFAR_EL2	);
+		PURE_EL2_SYSREG(  ELR_EL2	);
+		PURE_EL2_SYSREG(  SPSR_EL2	);
+		MAPPED_EL2_SYSREG(SCTLR_EL2,   SCTLR_EL1,
+				  translate_sctlr_el2_to_sctlr_el1	     );
+		MAPPED_EL2_SYSREG(CPTR_EL2,    CPACR_EL1,
+				  translate_cptr_el2_to_cpacr_el1	     );
+		MAPPED_EL2_SYSREG(TTBR0_EL2,   TTBR0_EL1,
+				  translate_ttbr0_el2_to_ttbr0_el1	     );
+		MAPPED_EL2_SYSREG(TTBR1_EL2,   TTBR1_EL1,   NULL	     );
+		MAPPED_EL2_SYSREG(TCR_EL2,     TCR_EL1,
+				  translate_tcr_el2_to_tcr_el1		     );
+		MAPPED_EL2_SYSREG(VBAR_EL2,    VBAR_EL1,    NULL	     );
+		MAPPED_EL2_SYSREG(AFSR0_EL2,   AFSR0_EL1,   NULL	     );
+		MAPPED_EL2_SYSREG(AFSR1_EL2,   AFSR1_EL1,   NULL	     );
+		MAPPED_EL2_SYSREG(ESR_EL2,     ESR_EL1,     NULL	     );
+		MAPPED_EL2_SYSREG(FAR_EL2,     FAR_EL1,     NULL	     );
+		MAPPED_EL2_SYSREG(MAIR_EL2,    MAIR_EL1,    NULL	     );
+		MAPPED_EL2_SYSREG(AMAIR_EL2,   AMAIR_EL1,   NULL	     );
+		MAPPED_EL2_SYSREG(CNTHCTL_EL2, CNTKCTL_EL1,
+				  translate_cnthctl_el2_to_cntkctl_el1	     );
+	default:
+		return false;
+	}
+}
+
 u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 {
 	u64 val = 0x8badf00d8badf00d;
+	u64 (*xlate)(u64) = NULL;
+	unsigned int el1r;
+
+	if (!vcpu->arch.sysregs_loaded_on_cpu)
+		goto memory_read;
+
+	if (unlikely(get_el2_to_el1_mapping(reg, &el1r, &xlate))) {
+		if (!is_hyp_ctxt(vcpu))
+			goto memory_read;
+
+		/*
+		 * ELR_EL2 is special cased for now.
+		 */
+		switch (reg) {
+		case ELR_EL2:
+			return read_sysreg_el1(SYS_ELR);
+		}
+
+		/*
+		 * If this register does not have an EL1 counterpart,
+		 * then read the stored EL2 version.
+		 */
+		if (reg == el1r)
+			goto memory_read;
+
+		/*
+		 * If we have a non-VHE guest and that the sysreg
+		 * requires translation to be used at EL1, use the
+		 * in-memory copy instead.
+		 */
+		if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
+			goto memory_read;
+
+		/* Get the current version of the EL1 counterpart. */
+		WARN_ON(!__vcpu_read_sys_reg_from_cpu(el1r, &val));
+		return val;
+	}
+
+	/* EL1 register can't be on the CPU if the guest is in vEL2. */
+	if (unlikely(is_hyp_ctxt(vcpu)))
+		goto memory_read;
 
-	if (vcpu->arch.sysregs_loaded_on_cpu &&
-	    __vcpu_read_sys_reg_from_cpu(reg, &val))
+	if (__vcpu_read_sys_reg_from_cpu(reg, &val))
 		return val;
 
+memory_read:
 	return __vcpu_sys_reg(vcpu, reg);
 }
 
 void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 {
-	if (vcpu->arch.sysregs_loaded_on_cpu &&
-	    __vcpu_write_sys_reg_to_cpu(val, reg))
+	u64 (*xlate)(u64) = NULL;
+	unsigned int el1r;
+
+	if (!vcpu->arch.sysregs_loaded_on_cpu)
+		goto memory_write;
+
+	if (unlikely(get_el2_to_el1_mapping(reg, &el1r, &xlate))) {
+		if (!is_hyp_ctxt(vcpu))
+			goto memory_write;
+
+		/*
+		 * Always store a copy of the write to memory to avoid having
+		 * to reverse-translate virtual EL2 system registers for a
+		 * non-VHE guest hypervisor.
+		 */
+		__vcpu_sys_reg(vcpu, reg) = val;
+
+		switch (reg) {
+		case ELR_EL2:
+			write_sysreg_el1(val, SYS_ELR);
+			return;
+		}
+
+		/* No EL1 counterpart? We're done here.? */
+		if (reg == el1r)
+			return;
+
+		if (!vcpu_el2_e2h_is_set(vcpu) && xlate)
+			val = xlate(val);
+
+		/* Redirect this to the EL1 version of the register. */
+		WARN_ON(!__vcpu_write_sys_reg_to_cpu(val, el1r));
+		return;
+	}
+
+	/* EL1 register can't be on the CPU if the guest is in vEL2. */
+	if (unlikely(is_hyp_ctxt(vcpu)))
+		goto memory_write;
+
+	if (__vcpu_write_sys_reg_to_cpu(val, reg))
 		return;
 
+memory_write:
 	 __vcpu_sys_reg(vcpu, reg) = val;
 }
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:27 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:27 +0000
Subject: [PATCH v6 19/64] KVM: arm64: nv: Trap SPSR_EL1,
 ELR_EL1 and VBAR_EL1 from virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-20-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

For the same reason we trap virtual memory register accesses at virtual
EL2, we need to trap SPSR_EL1, ELR_EL1 and VBAR_EL1 accesses. ARM v8.3
introduces the HCR_EL2.NV1 bit to be able to trap on those register
accesses in EL1. Do not set this bit until the whole nesting support is
completed.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 9d3520f1d17a..4f2bcc1e0c25 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1650,6 +1650,30 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_elr(struct kvm_vcpu *vcpu,
+		       struct sys_reg_params *p,
+		       const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		vcpu_write_sys_reg(vcpu, p->regval, ELR_EL1);
+	else
+		p->regval = vcpu_read_sys_reg(vcpu, ELR_EL1);
+
+	return true;
+}
+
+static bool access_spsr(struct kvm_vcpu *vcpu,
+			struct sys_reg_params *p,
+			const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		__vcpu_sys_reg(vcpu, SPSR_EL1) = p->regval;
+	else
+		p->regval = __vcpu_sys_reg(vcpu, SPSR_EL1);
+
+	return true;
+}
+
 static bool access_spsr_el2(struct kvm_vcpu *vcpu,
 			    struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
@@ -1812,6 +1836,9 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	PTRAUTH_KEY(APDB),
 	PTRAUTH_KEY(APGA),
 
+	{ SYS_DESC(SYS_SPSR_EL1), access_spsr},
+	{ SYS_DESC(SYS_ELR_EL1), access_elr},
+
 	{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
 	{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
 	{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
@@ -1859,7 +1886,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_LORC_EL1), trap_loregion },
 	{ SYS_DESC(SYS_LORID_EL1), trap_loregion },
 
-	{ SYS_DESC(SYS_VBAR_EL1), NULL, reset_val, VBAR_EL1, 0 },
+	{ SYS_DESC(SYS_VBAR_EL1), access_rw, reset_val, VBAR_EL1, 0 },
 	{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
 
 	{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:32 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:32 +0000
Subject: [PATCH v6 24/64] KVM: arm64: nv: Respect the virtual HCR_EL2.NV bit
 setting
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-25-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Forward traps due to HCR_EL2.NV bit to the virtual EL2 if they are not
coming from the virtual EL2 and the virtual HCR_EL2.NV bit is set.

In addition to EL2 register accesses, setting NV bit will also make EL12
register accesses trap to EL2. To emulate this for the virtual EL2,
forword traps due to EL12 register accessses to the virtual EL2 if the
virtual HCR_EL2.NV bit is set.

This is for recursive nested virtualization.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[Moved code to emulate-nested.c]
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h    |  1 +
 arch/arm64/include/asm/kvm_nested.h |  2 ++
 arch/arm64/kvm/emulate-nested.c     | 27 +++++++++++++++++++++++++++
 arch/arm64/kvm/handle_exit.c        |  7 +++++++
 arch/arm64/kvm/sys_regs.c           | 21 +++++++++++++++++++++
 5 files changed, 58 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 5acb153a82c8..8043827e7dc0 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -20,6 +20,7 @@
 #define HCR_AMVOFFEN	(UL(1) << 51)
 #define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
+#define HCR_NV		(UL(1) << 42)
 #define HCR_API		(UL(1) << 41)
 #define HCR_APK		(UL(1) << 40)
 #define HCR_TEA		(UL(1) << 37)
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 79d382fa02ea..37ff6458296d 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -66,5 +66,7 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
 }
 
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
+extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
+extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
 
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index f52cd4458947..7dd98d6e96e0 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -13,6 +13,26 @@
 
 #include "trace.h"
 
+bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
+{
+	bool control_bit_set;
+
+	if (!vcpu_has_nv(vcpu))
+		return false;
+
+	control_bit_set = __vcpu_sys_reg(vcpu, HCR_EL2) & control_bit;
+	if (!vcpu_is_el2(vcpu) && control_bit_set) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return true;
+	}
+	return false;
+}
+
+bool forward_nv_traps(struct kvm_vcpu *vcpu)
+{
+	return forward_traps(vcpu, HCR_NV);
+}
+
 static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
 {
 	u64 mode = spsr & PSR_MODE_MASK;
@@ -49,6 +69,13 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	u64 spsr, elr, mode;
 	bool direct_eret;
 
+	/*
+	 * Forward this trap to the virtual EL2 if the virtual
+	 * HCR_EL2.NV bit is set and this is coming from !EL2.
+	 */
+	if (forward_nv_traps(vcpu))
+		return;
+
 	/*
 	 * Going through the whole put/load motions is a waste of time
 	 * if this is a VHE guest hypervisor returning to its own
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index a5c698f188d6..867de65eb766 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -64,6 +64,13 @@ static int handle_smc(struct kvm_vcpu *vcpu)
 {
 	int ret;
 
+	/*
+	 * Forward this trapped smc instruction to the virtual EL2 if
+	 * the guest has asked for it.
+	 */
+	if (forward_traps(vcpu, HCR_TSC))
+		return 1;
+
 	/*
 	 * "If an SMC instruction executed at Non-secure EL1 is
 	 * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7f074a7f6eb3..ccd063d6cb69 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -267,10 +267,19 @@ static u32 get_ccsidr(u32 csselr)
 	return ccsidr;
 }
 
+static bool el12_reg(struct sys_reg_params *p)
+{
+	/* All *_EL12 registers have Op1=5. */
+	return (p->Op1 == 5);
+}
+
 static bool access_rw(struct kvm_vcpu *vcpu,
 		      struct sys_reg_params *p,
 		      const struct sys_reg_desc *r)
 {
+	if (el12_reg(p) && forward_nv_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		vcpu_write_sys_reg(vcpu, p->regval, r->reg);
 	else
@@ -339,6 +348,9 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 	bool was_enabled = vcpu_has_cache_enabled(vcpu);
 	u64 val, mask, shift;
 
+	if (el12_reg(p) && forward_nv_traps(vcpu))
+		return false;
+
 	/* We don't expect TRVM on the host */
 	BUG_ON(!vcpu_is_el2(vcpu) && !p->is_write);
 
@@ -1654,6 +1666,9 @@ static bool access_elr(struct kvm_vcpu *vcpu,
 		       struct sys_reg_params *p,
 		       const struct sys_reg_desc *r)
 {
+	if (el12_reg(p) && forward_nv_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		vcpu_write_sys_reg(vcpu, p->regval, ELR_EL1);
 	else
@@ -1666,6 +1681,9 @@ static bool access_spsr(struct kvm_vcpu *vcpu,
 			struct sys_reg_params *p,
 			const struct sys_reg_desc *r)
 {
+	if (el12_reg(p) && forward_nv_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		__vcpu_sys_reg(vcpu, SPSR_EL1) = p->regval;
 	else
@@ -1678,6 +1696,9 @@ static bool access_spsr_el2(struct kvm_vcpu *vcpu,
 			    struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
 {
+	if (el12_reg(p) && forward_nv_traps(vcpu))
+		return false;
+
 	if (p->is_write)
 		vcpu_write_sys_reg(vcpu, p->regval, SPSR_EL2);
 	else
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:29 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:29 +0000
Subject: [PATCH v6 21/64] KVM: arm64: nv: Handle PSCI call via smc from the
 guest
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-22-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

VMs used to execute hvc #0 for the psci call if EL3 is not implemented.
However, when we come to provide the virtual EL2 mode to the VM, the
host OS inside the VM calls kvm_call_hyp() which is also hvc #0. So,
it's hard to differentiate between them from the host hypervisor's point
of view.

So, let the VM execute smc instruction for the psci call. On ARMv8.3,
even if EL3 is not implemented, a smc instruction executed at non-secure
EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than being treated as
UNDEFINED. So, the host hypervisor can handle this psci call without any
confusion.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/handle_exit.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 2bbeed8c9786..0cedef6e0d80 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -62,6 +62,8 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
 
 static int handle_smc(struct kvm_vcpu *vcpu)
 {
+	int ret;
+
 	/*
 	 * "If an SMC instruction executed at Non-secure EL1 is
 	 * trapped to EL2 because HCR_EL2.TSC is 1, the exception is a
@@ -69,10 +71,28 @@ static int handle_smc(struct kvm_vcpu *vcpu)
 	 *
 	 * We need to advance the PC after the trap, as it would
 	 * otherwise return to the same address...
+	 *
+	 * If imm is non-zero, it's not defined, so just skip it.
+	 */
+	if (kvm_vcpu_hvc_get_imm(vcpu)) {
+		vcpu_set_reg(vcpu, 0, ~0UL);
+		kvm_incr_pc(vcpu);
+		return 1;
+	}
+
+	/*
+	 * If imm is zero, it's a psci call.
+	 * Note that on ARMv8.3, even if EL3 is not implemented, SMC executed
+	 * at Non-secure EL1 is trapped to EL2 if HCR_EL2.TSC==1, rather than
+	 * being treated as UNDEFINED.
 	 */
-	vcpu_set_reg(vcpu, 0, ~0UL);
+	ret = kvm_hvc_call_handler(vcpu);
+	if (ret < 0)
+		vcpu_set_reg(vcpu, 0, ~0UL);
+
 	kvm_incr_pc(vcpu);
-	return 1;
+
+	return ret;
 }
 
 /*
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:23 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:23 +0000
Subject: [PATCH v6 15/64] KVM: arm64: nv: Handle HCR_EL2.E2H specially
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-16-maz@kernel.org>

HCR_EL2.E2H is nasty, as a flip of this bit completely changes the way
we deal with a lot of the state. So when the guest flips this bit
(sysregs are live), do the put/load dance so that we have a consistent
state.

Yes, this is slow. Don't do it.

Suggested-by: Alexandru Elisei <alexandru.elisei at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ace4a54caef9..102bc4906723 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -183,9 +183,24 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 		goto memory_write;
 
 	if (unlikely(get_el2_to_el1_mapping(reg, &el1r, &xlate))) {
+		bool need_put_load;
+
 		if (!is_hyp_ctxt(vcpu))
 			goto memory_write;
 
+		/*
+		 * HCR_EL2.E2H is nasty: it changes the way we interpret a
+		 * lot of the EL2 state, so treat is as a full state
+		 * transition.
+		 */
+		need_put_load = ((reg == HCR_EL2) &&
+				 vcpu_el2_e2h_is_set(vcpu) != !!(val & HCR_E2H));
+
+		if (need_put_load) {
+			preempt_disable();
+			kvm_arch_vcpu_put(vcpu);
+		}
+
 		/*
 		 * Always store a copy of the write to memory to avoid having
 		 * to reverse-translate virtual EL2 system registers for a
@@ -193,6 +208,11 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 		 */
 		__vcpu_sys_reg(vcpu, reg) = val;
 
+		if (need_put_load) {
+			kvm_arch_vcpu_load(vcpu, smp_processor_id());
+			preempt_enable();
+		}
+
 		switch (reg) {
 		case ELR_EL2:
 			write_sysreg_el1(val, SYS_ELR);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:31 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:31 +0000
Subject: [PATCH v6 23/64] KVM: arm64: nv: Respect virtual CPTR_EL2.{TFP,
 FPEN} settings
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-24-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Forward traps due to FP/ASIMD register accesses to the virtual EL2
if virtual CPTR_EL2.TFP is set (with HCR_EL2.E2H == 0) or
CPTR_EL2.FPEN is configure to do so (with HCR_EL2.E2h == 1).

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: account for HCR_EL2.E2H when testing for TFP/FPEN, with
 all the hard work actually being done by Chase Conklin]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h    | 26 +++++++++++++++++++++++++
 arch/arm64/kvm/handle_exit.c            | 16 +++++++++++----
 arch/arm64/kvm/hyp/include/hyp/switch.h |  8 ++++++--
 3 files changed, 44 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 54e8eee413eb..ff8980a39ee8 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -11,12 +11,14 @@
 #ifndef __ARM64_KVM_EMULATE_H__
 #define __ARM64_KVM_EMULATE_H__
 
+#include <linux/bitfield.h>
 #include <linux/kvm_host.h>
 
 #include <asm/debug-monitors.h>
 #include <asm/esr.h>
 #include <asm/kvm_arm.h>
 #include <asm/kvm_hyp.h>
+#include <asm/kvm_nested.h>
 #include <asm/ptrace.h>
 #include <asm/cputype.h>
 #include <asm/virt.h>
@@ -324,6 +326,30 @@ static inline bool vcpu_mode_priv(const struct kvm_vcpu *vcpu)
 	return mode != PSR_MODE_EL0t;
 }
 
+static inline bool guest_hyp_fpsimd_traps_enabled(const struct kvm_vcpu *vcpu)
+{
+	u64 val;
+
+	if (!vcpu_has_nv(vcpu))
+		return false;
+
+	val = vcpu_read_sys_reg(vcpu, CPTR_EL2);
+
+	if (!vcpu_el2_e2h_is_set(vcpu))
+		return (val & CPTR_EL2_TFP);
+
+	switch (FIELD_GET(CPACR_EL1_FPEN, val)) {
+	case 0b00:
+	case 0b10:
+		return true;
+	case 0b01:
+		return vcpu_el2_tge_is_set(vcpu) && !vcpu_is_el2(vcpu);
+	case 0b11:
+	default:		/* GCC is dumb */
+		return false;
+	}
+}
+
 static __always_inline u32 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu)
 {
 	return vcpu->arch.fault.esr_el2;
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index a1b1bbf3d598..a5c698f188d6 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -96,11 +96,19 @@ static int handle_smc(struct kvm_vcpu *vcpu)
 }
 
 /*
- * Guest access to FP/ASIMD registers are routed to this handler only
- * when the system doesn't support FP/ASIMD.
+ * This handles the cases where the system does not support FP/ASIMD or when
+ * we are running nested virtualization and the guest hypervisor is trapping
+ * FP/ASIMD accesses by its guest guest.
+ *
+ * All other handling of guest vs. host FP/ASIMD register state is handled in
+ * fixup_guest_exit().
  */
-static int handle_no_fpsimd(struct kvm_vcpu *vcpu)
+static int kvm_handle_fpasimd(struct kvm_vcpu *vcpu)
 {
+	if (guest_hyp_fpsimd_traps_enabled(vcpu))
+		return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+	/* This is the case when the system doesn't support FP/ASIMD. */
 	kvm_inject_undefined(vcpu);
 	return 1;
 }
@@ -231,7 +239,7 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BKPT32]	= kvm_handle_guest_debug,
 	[ESR_ELx_EC_BRK64]	= kvm_handle_guest_debug,
-	[ESR_ELx_EC_FP_ASIMD]	= handle_no_fpsimd,
+	[ESR_ELx_EC_FP_ASIMD]	= kvm_handle_fpasimd,
 	[ESR_ELx_EC_PAC]	= kvm_handle_ptrauth,
 };
 
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 49c3b9eb09d7..42c47731f64e 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -166,8 +166,12 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
 	sve_guest = vcpu_has_sve(vcpu);
 	esr_ec = kvm_vcpu_trap_get_class(vcpu);
 
-	/* Don't handle SVE traps for non-SVE vcpus here: */
-	if (!sve_guest && esr_ec != ESR_ELx_EC_FP_ASIMD)
+	/*
+	 * Don't handle SVE traps for non-SVE vcpus here. This
+	 * includes NV guests for the time being.
+	 */
+	if (!sve_guest && (esr_ec != ESR_ELx_EC_FP_ASIMD ||
+			   guest_hyp_fpsimd_traps_enabled(vcpu)))
 		return false;
 
 	/* Valid trap.  Switch the context: */
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:35 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:35 +0000
Subject: [PATCH v6 27/64] KVM: arm64: nv: Allow a sysreg to be hidden from
 userspace only
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-28-maz@kernel.org>

So far, we never needed to distinguish between registers hidden
from userspace and being hidden from a guest (they are always
either visible to both, or hidden from both).

With NV, we have the ugly case of the EL{0,1}2 registers, which
are only a view on the EL{0,1} registers. It makes absolutely no
sense to expose them to userspace, since it already has the
canonical view.

Add a new visibility flag (REG_HIDDEN_USER) and a new helper that
checks for it and REG_HIDDEN when checking whether to expose
a sysreg to userspace. Subsequent patches will make use of it.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c |  6 +++---
 arch/arm64/kvm/sys_regs.h | 12 +++++++++++-
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 31d739d59f67..0c9bbe5eee5e 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -3031,7 +3031,7 @@ int kvm_arm_sys_reg_get_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 		return get_invariant_sys_reg(reg->id, uaddr);
 
 	/* Check for regs disabled by runtime config */
-	if (sysreg_hidden(vcpu, r))
+	if (sysreg_hidden_user(vcpu, r))
 		return -ENOENT;
 
 	if (r->get_user)
@@ -3056,7 +3056,7 @@ int kvm_arm_sys_reg_set_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg
 		return set_invariant_sys_reg(reg->id, uaddr);
 
 	/* Check for regs disabled by runtime config */
-	if (sysreg_hidden(vcpu, r))
+	if (sysreg_hidden_user(vcpu, r))
 		return -ENOENT;
 
 	if (r->set_user)
@@ -3127,7 +3127,7 @@ static int walk_one_sys_reg(const struct kvm_vcpu *vcpu,
 	if (!(rd->reg || rd->get_user))
 		return 0;
 
-	if (sysreg_hidden(vcpu, rd))
+	if (sysreg_hidden_user(vcpu, rd))
 		return 0;
 
 	if (!copy_reg_to_user(rd, uind))
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index cc0cc95a0280..850629f083a3 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -78,7 +78,8 @@ struct sys_reg_desc {
 };
 
 #define REG_HIDDEN		(1 << 0) /* hidden from userspace and guest */
-#define REG_RAZ			(1 << 1) /* RAZ from userspace and guest */
+#define REG_HIDDEN_USER		(1 << 1) /* hidden from userspace only */
+#define REG_RAZ			(1 << 2) /* RAZ from userspace and guest */
 
 static __printf(2, 3)
 inline void print_sys_reg_msg(const struct sys_reg_params *p,
@@ -138,6 +139,15 @@ static inline bool sysreg_hidden(const struct kvm_vcpu *vcpu,
 	return r->visibility(vcpu, r) & REG_HIDDEN;
 }
 
+static inline bool sysreg_hidden_user(const struct kvm_vcpu *vcpu,
+				      const struct sys_reg_desc *r)
+{
+	if (likely(!r->visibility))
+		return false;
+
+	return r->visibility(vcpu, r) & (REG_HIDDEN | REG_HIDDEN_USER);
+}
+
 static inline bool sysreg_visible_as_raz(const struct kvm_vcpu *vcpu,
 					 const struct sys_reg_desc *r)
 {
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:36 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:36 +0000
Subject: [PATCH v6 28/64] KVM: arm64: nv: Emulate EL12 register accesses from
 the virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-29-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

With HCR_EL2.NV bit set, accesses to EL12 registers in the virtual EL2
trap to EL2. Handle those traps just like we do for EL1 registers.

One exception is CNTKCTL_EL12. We don't trap on CNTKCTL_EL1 for non-VHE
virtual EL2 because we don't have to. However, accessing CNTKCTL_EL12
will trap since it's one of the EL12 registers controlled by HCR_EL2.NV
bit.  Therefore, add a handler for it and don't treat it as a
non-trap-registers when preparing a shadow context.

These registers, being only a view on their EL1 counterpart, are
permanently hidden from userspace.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: EL12_REG(), register visibility]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 0c9bbe5eee5e..697bf0bca550 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1634,6 +1634,26 @@ static unsigned int el2_visibility(const struct kvm_vcpu *vcpu,
 	.val = v,				\
 }
 
+/*
+ * EL{0,1}2 registers are the EL2 view on an EL0 or EL1 register when
+ * HCR_EL2.E2H==1, and only in the sysreg table for convenience of
+ * handling traps. Given that, they are always hidden from userspace.
+ */
+static unsigned int elx2_visibility(const struct kvm_vcpu *vcpu,
+				    const struct sys_reg_desc *rd)
+{
+	return REG_HIDDEN_USER;
+}
+
+#define EL12_REG(name, acc, rst, v) {		\
+	SYS_DESC(SYS_##name##_EL12),		\
+	.access = acc,				\
+	.reset = rst,				\
+	.reg = name##_EL1,			\
+	.val = v,				\
+	.visibility = elx2_visibility,		\
+}
+
 /* sys_reg_desc initialiser for known cpufeature ID registers */
 #define ID_SANITISED(name) {			\
 	SYS_DESC(SYS_##name),			\
@@ -2194,6 +2214,23 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(CNTVOFF_EL2, access_rw, reset_val, 0),
 	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
 
+	EL12_REG(SCTLR, access_vm_reg, reset_val, 0x00C50078),
+	EL12_REG(CPACR, access_rw, reset_val, 0),
+	EL12_REG(TTBR0, access_vm_reg, reset_unknown, 0),
+	EL12_REG(TTBR1, access_vm_reg, reset_unknown, 0),
+	EL12_REG(TCR, access_vm_reg, reset_val, 0),
+	{ SYS_DESC(SYS_SPSR_EL12), access_spsr},
+	{ SYS_DESC(SYS_ELR_EL12), access_elr},
+	EL12_REG(AFSR0, access_vm_reg, reset_unknown, 0),
+	EL12_REG(AFSR1, access_vm_reg, reset_unknown, 0),
+	EL12_REG(ESR, access_vm_reg, reset_unknown, 0),
+	EL12_REG(FAR, access_vm_reg, reset_unknown, 0),
+	EL12_REG(MAIR, access_vm_reg, reset_unknown, 0),
+	EL12_REG(AMAIR, access_vm_reg, reset_amair_el1, 0),
+	EL12_REG(VBAR, access_rw, reset_val, 0),
+	EL12_REG(CONTEXTIDR, access_vm_reg, reset_val, 0),
+	EL12_REG(CNTKCTL, access_rw, reset_val, 0),
+
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:22 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:22 +0000
Subject: [PATCH v6 14/64] KVM: arm64: nv: Handle SPSR_EL2 specially
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-15-maz@kernel.org>

SPSR_EL2 needs special attention when running nested on ARMv8.3:

If taking an exception while running at vEL2 (actually EL1), the
HW will update the SPSR_EL1 register with the EL1 mode. We need
to track this in order to make sure that accesses to the virtual
view of SPSR_EL2 is correct.

To do so, we place an illegal value in SPSR_EL1.M, and patch it
accordingly if required when accessing it.

Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h | 37 ++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c            | 23 +++++++++++++++--
 2 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index cb9f123d26f3..54e8eee413eb 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -241,6 +241,43 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
 	return __is_hyp_ctxt(&vcpu->arch.ctxt);
 }
 
+static inline u64 __fixup_spsr_el2_write(struct kvm_cpu_context *ctxt, u64 val)
+{
+	if (!__vcpu_el2_e2h_is_set(ctxt)) {
+		/*
+		 * Clear the .M field when writing SPSR to the CPU, so that we
+		 * can detect when the CPU clobbered our SPSR copy during a
+		 * local exception.
+		 */
+		val &= ~0xc;
+	}
+
+	return val;
+}
+
+static inline u64 __fixup_spsr_el2_read(const struct kvm_cpu_context *ctxt, u64 val)
+{
+	if (__vcpu_el2_e2h_is_set(ctxt))
+		return val;
+
+	/*
+	 * SPSR.M == 0 means the CPU has not touched the SPSR, so the
+	 * register has still the value we saved on the last write.
+	 */
+	if ((val & 0xc) == 0)
+		return ctxt_sys_reg(ctxt, SPSR_EL2);
+
+	/*
+	 * Otherwise there was a "local" exception on the CPU,
+	 * which from the guest's point of view was being taken from
+	 * EL2 to EL2, although it actually happened to be from
+	 * EL1 to EL1.
+	 * So we need to fix the .M field in SPSR, to make it look
+	 * like EL2, which is what the guest would expect.
+	 */
+	return (val & ~0x0c) | CurrentEL_EL2;
+}
+
 /*
  * The layout of SPSR for an AArch32 state is different when observed from an
  * AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 0927e6c345b4..ace4a54caef9 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -133,11 +133,14 @@ u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg)
 			goto memory_read;
 
 		/*
-		 * ELR_EL2 is special cased for now.
+		 * ELR_EL2 and SPSR_EL2 are special cased for now.
 		 */
 		switch (reg) {
 		case ELR_EL2:
 			return read_sysreg_el1(SYS_ELR);
+		case SPSR_EL2:
+			val = read_sysreg_el1(SYS_SPSR);
+			return __fixup_spsr_el2_read(&vcpu->arch.ctxt, val);
 		}
 
 		/*
@@ -194,6 +197,10 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
 		case ELR_EL2:
 			write_sysreg_el1(val, SYS_ELR);
 			return;
+		case SPSR_EL2:
+			val = __fixup_spsr_el2_write(&vcpu->arch.ctxt, val);
+			write_sysreg_el1(val, SYS_SPSR);
+			return;
 		}
 
 		/* No EL1 counterpart? We're done here.? */
@@ -1610,6 +1617,18 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_spsr_el2(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		vcpu_write_sys_reg(vcpu, p->regval, SPSR_EL2);
+	else
+		p->regval = vcpu_read_sys_reg(vcpu, SPSR_EL2);
+
+	return true;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2041,7 +2060,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(VTCR_EL2, access_rw, reset_val, 0),
 
 	{ SYS_DESC(SYS_DACR32_EL2), NULL, reset_unknown, DACR32_EL2 },
-	EL2_REG(SPSR_EL2, access_rw, reset_val, 0),
+	EL2_REG(SPSR_EL2, access_spsr_el2, reset_val, 0),
 	EL2_REG(ELR_EL2, access_rw, reset_val, 0),
 	{ SYS_DESC(SYS_SP_EL1), access_sp_el1},
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:26 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:26 +0000
Subject: [PATCH v6 18/64] KVM: arm64: nv: Trap EL1 VM register accesses in
 virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-19-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at linaro.org>

When running in virtual EL2 mode, we actually run the hardware in EL1
and therefore have to use the EL1 registers to ensure correct operation.

By setting the HCR.TVM and HCR.TVRM we ensure that the virtual EL2 mode
doesn't shoot itself in the foot when setting up what it believes to be
a different mode's system register state (for example when preparing to
switch to a VM).

We can leverage the existing sysregs infrastructure to support trapped
accesses to these registers.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/switch.h |  4 +---
 arch/arm64/kvm/hyp/nvhe/switch.c        |  2 +-
 arch/arm64/kvm/hyp/vhe/switch.c         |  7 ++++++-
 arch/arm64/kvm/sys_regs.c               | 19 ++++++++++++++++---
 4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 58e14f8ead23..49c3b9eb09d7 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -110,10 +110,8 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 		write_sysreg(0, pmuserenr_el0);
 }
 
-static inline void ___activate_traps(struct kvm_vcpu *vcpu)
+static inline void ___activate_traps(struct kvm_vcpu *vcpu, u64 hcr)
 {
-	u64 hcr = vcpu->arch.hcr_el2;
-
 	if (cpus_have_final_cap(ARM64_WORKAROUND_CAVIUM_TX2_219_TVM))
 		hcr |= HCR_TVM;
 
diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c
index 6410d21d8695..61a5627fd456 100644
--- a/arch/arm64/kvm/hyp/nvhe/switch.c
+++ b/arch/arm64/kvm/hyp/nvhe/switch.c
@@ -38,7 +38,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 {
 	u64 val;
 
-	___activate_traps(vcpu);
+	___activate_traps(vcpu, vcpu->arch.hcr_el2);
 	__activate_traps_common(vcpu);
 
 	val = vcpu->arch.cptr_el2;
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 82ddaebe66de..6ed9e4893a02 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -32,9 +32,14 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
 
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
+	u64 hcr = vcpu->arch.hcr_el2;
 	u64 val;
 
-	___activate_traps(vcpu);
+	/* Trap VM sysreg accesses if an EL2 guest is not using VHE. */
+	if (vcpu_is_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
+		hcr |= HCR_TVM | HCR_TRVM;
+
+	___activate_traps(vcpu, hcr);
 
 	val = read_sysreg(cpacr_el1);
 	val |= CPACR_EL1_TTA;
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 102bc4906723..9d3520f1d17a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -322,8 +322,15 @@ static void get_access_mask(const struct sys_reg_desc *r, u64 *mask, u64 *shift)
 
 /*
  * Generic accessor for VM registers. Only called as long as HCR_TVM
- * is set. If the guest enables the MMU, we stop trapping the VM
- * sys_regs and leave it in complete control of the caches.
+ * is set.
+ *
+ * This is set in two cases: either (1) we're running at vEL2, or (2)
+ * we're running at EL1 and the guest has its MMU off.
+ *
+ * (1) TVM/TRVM is set, as we need to virtualise some of the VM
+ * registers for the guest hypervisor
+ * (2) Once the guest enables the MMU, we stop trapping the VM sys_regs
+ * and leave it in complete control of the caches.
  */
 static bool access_vm_reg(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
@@ -332,7 +339,13 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 	bool was_enabled = vcpu_has_cache_enabled(vcpu);
 	u64 val, mask, shift;
 
-	BUG_ON(!p->is_write);
+	/* We don't expect TRVM on the host */
+	BUG_ON(!vcpu_is_el2(vcpu) && !p->is_write);
+
+	if (!p->is_write) {
+		p->regval = vcpu_read_sys_reg(vcpu, r->reg);
+		return true;
+	}
 
 	get_access_mask(r, &mask, &shift);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:30 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:30 +0000
Subject: [PATCH v6 22/64] KVM: arm64: nv: Respect virtual HCR_EL2.TWX setting
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-23-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Forward exceptions due to WFI or WFE instructions to the virtual EL2 if
they are not coming from the virtual EL2 and virtual HCR_EL2.TWX is set.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  2 ++
 arch/arm64/kvm/Makefile             |  2 +-
 arch/arm64/kvm/handle_exit.c        | 11 ++++++++++-
 arch/arm64/kvm/nested.c             | 28 ++++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/kvm/nested.c

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 5a85be6d8eb3..79d382fa02ea 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -65,4 +65,6 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
 		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));
 }
 
+int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index b67c4ebd72b1..dbaf42ff65f1 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,7 +14,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
 	 guest.o debug.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o pkvm.o \
-	 arch_timer.o trng.o emulate-nested.o \
+	 arch_timer.o trng.o emulate-nested.o nested.o \
 	 vgic/vgic.o vgic/vgic-init.o \
 	 vgic/vgic-irqfd.o vgic/vgic-v2.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 0cedef6e0d80..a1b1bbf3d598 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -119,7 +119,16 @@ static int handle_no_fpsimd(struct kvm_vcpu *vcpu)
  */
 static int kvm_handle_wfx(struct kvm_vcpu *vcpu)
 {
-	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_WFx_ISS_WFE) {
+	bool is_wfe = !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_WFx_ISS_WFE);
+
+	if (vcpu_has_nv(vcpu)) {
+		int ret = handle_wfx_nested(vcpu, is_wfe);
+
+		if (ret != -EINVAL)
+			return ret;
+	}
+
+	if (is_wfe) {
 		trace_kvm_wfx_arm64(*vcpu_pc(vcpu), true);
 		vcpu->stat.wfe_exit_stat++;
 		kvm_vcpu_on_spin(vcpu, vcpu_mode_priv(vcpu));
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
new file mode 100644
index 000000000000..5e1104f8e765
--- /dev/null
+++ b/arch/arm64/kvm/nested.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 - Columbia University and Linaro Ltd.
+ * Author: Jintack Lim <jintack.lim at linaro.org>
+ */
+
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+
+#include <asm/kvm_emulate.h>
+
+/*
+ * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
+ * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
+ * handle this.
+ */
+int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
+{
+	u64 hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+
+	if (vcpu_is_el2(vcpu))
+		return -EINVAL;
+
+	if ((is_wfe && (hcr_el2 & HCR_TWE)) || (!is_wfe && (hcr_el2 & HCR_TWI)))
+		return kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+	return -EINVAL;
+}
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:18 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:18 +0000
Subject: [PATCH v6 10/64] KVM: arm64: nv: Inject HVC exceptions to the virtual
 EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-11-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

As we expect all PSCI calls from the L1 hypervisor to be performed
using SMC when nested virtualization is enabled, it is clear that
all HVC instruction from the VM (including from the virtual EL2)
are supposed to handled in the virtual EL2.

Forward these to EL2 as required.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: add handling of HCR_EL2.HCD]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/handle_exit.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index fd2dd26caf91..6bfb5c31cad1 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -16,6 +16,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/debug-monitors.h>
 #include <asm/traps.h>
 
@@ -40,6 +41,16 @@ static int handle_hvc(struct kvm_vcpu *vcpu)
 			    kvm_vcpu_hvc_get_imm(vcpu));
 	vcpu->stat.hvc_exit_stat++;
 
+	/* Forward hvc instructions to the virtual EL2 if the guest has EL2. */
+	if (vcpu_has_nv(vcpu)) {
+		if (vcpu_read_sys_reg(vcpu, HCR_EL2) & HCR_HCD)
+			kvm_inject_undefined(vcpu);
+		else
+			kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+
+		return 1;
+	}
+
 	ret = kvm_hvc_call_handler(vcpu);
 	if (ret < 0) {
 		vcpu_set_reg(vcpu, 0, ~0UL);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:19 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:19 +0000
Subject: [PATCH v6 11/64] KVM: arm64: nv: Handle trapped ERET from virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-12-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

When a guest hypervisor running virtual EL2 in EL1 executes an ERET
instruction, we will have set HCR_EL2.NV which traps ERET to EL2, so
that we can emulate the exception return in software.

Reviewed-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
Reviewed-by: Alexandru Elisei <alexandru.elisei at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/esr.h     |  4 ++++
 arch/arm64/include/asm/kvm_arm.h |  2 +-
 arch/arm64/kvm/handle_exit.c     | 10 ++++++++++
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index d52a0b269ee8..3574c224889f 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -257,6 +257,10 @@
 		(((e) & ESR_ELx_SYS64_ISS_OP2_MASK) >>		\
 		 ESR_ELx_SYS64_ISS_OP2_SHIFT))
 
+/* ISS field definitions for ERET/ERETAA/ERETAB trapping */
+#define ESR_ELx_ERET_ISS_ERET		0x2
+#define ESR_ELx_ERET_ISS_ERETA		0x1
+
 /*
  * ISS field definitions for floating-point exception traps
  * (FP_EXC_32/FP_EXC_64).
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index e6e3aae87a09..5acb153a82c8 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -353,7 +353,7 @@
 	ECN(SP_ALIGN), ECN(FP_EXC32), ECN(FP_EXC64), ECN(SERROR), \
 	ECN(BREAKPT_LOW), ECN(BREAKPT_CUR), ECN(SOFTSTP_LOW), \
 	ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \
-	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64)
+	ECN(BKPT32), ECN(VECTOR32), ECN(BRK64), ECN(ERET)
 
 #define CPACR_EL1_FPEN		(3 << 20)
 #define CPACR_EL1_TTA		(1 << 28)
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 6bfb5c31cad1..2bbeed8c9786 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -171,6 +171,15 @@ static int kvm_handle_ptrauth(struct kvm_vcpu *vcpu)
 	return 1;
 }
 
+static int kvm_handle_eret(struct kvm_vcpu *vcpu)
+{
+	if (kvm_vcpu_get_esr(vcpu) & ESR_ELx_ERET_ISS_ERET)
+		return kvm_handle_ptrauth(vcpu);
+
+	kvm_emulate_nested_eret(vcpu);
+	return 1;
+}
+
 static exit_handle_fn arm_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]	= kvm_handle_unknown_ec,
 	[ESR_ELx_EC_WFx]	= kvm_handle_wfx,
@@ -185,6 +194,7 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_SMC64]	= handle_smc,
 	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
 	[ESR_ELx_EC_SVE]	= handle_sve,
+	[ESR_ELx_EC_ERET]	= kvm_handle_eret,
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_DABT_LOW]	= kvm_handle_guest_abort,
 	[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:28 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:28 +0000
Subject: [PATCH v6 20/64] KVM: arm64: nv: Trap CPACR_EL1 access in virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-21-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

For the same reason we trap virtual memory register accesses in virtual
EL2, we trap CPACR_EL1 access too; We allow the virtual EL2 mode to
access EL1 system register state instead of the virtual EL2 one.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 3 +++
 arch/arm64/kvm/sys_regs.c       | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 6ed9e4893a02..1e6a00e7bfb3 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -64,6 +64,9 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		__activate_traps_fpsimd32(vcpu);
 	}
 
+	if (vcpu_is_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
+		val |= CPTR_EL2_TCPAC;
+	
 	write_sysreg(val, cpacr_el1);
 
 	write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 4f2bcc1e0c25..7f074a7f6eb3 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1819,7 +1819,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 
 	{ SYS_DESC(SYS_SCTLR_EL1), access_vm_reg, reset_val, SCTLR_EL1, 0x00C50078 },
 	{ SYS_DESC(SYS_ACTLR_EL1), access_actlr, reset_actlr, ACTLR_EL1 },
-	{ SYS_DESC(SYS_CPACR_EL1), NULL, reset_val, CPACR_EL1, 0 },
+	{ SYS_DESC(SYS_CPACR_EL1), access_rw, reset_val, CPACR_EL1, 0 },
 
 	MTE_REG(RGSR_EL1),
 	MTE_REG(GCR_EL1),
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:24 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:24 +0000
Subject: [PATCH v6 16/64] KVM: arm64: nv: Save/Restore vEL2 sysregs
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-17-maz@kernel.org>

Whenever we need to restore the guest's system registers to the CPU, we
now need to take care of the EL2 system registers as well. Most of them
are accessed via traps only, but some have an immediate effect and also
a guest running in VHE mode would expect them to be accessible via their
EL1 encoding, which we do not trap.

For vEL2 we write the virtual EL2 registers with an identical format directly
into their EL1 counterpart, and translate the few registers that have a
different format for the same effect on the execution when running a
non-VHE guest guest hypervisor.

Based on an initial patch from Andre Przywara, rewritten many times
since.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h |   5 +-
 arch/arm64/kvm/hyp/nvhe/sysreg-sr.c        |   2 +-
 arch/arm64/kvm/hyp/vhe/sysreg-sr.c         | 125 ++++++++++++++++++++-
 3 files changed, 127 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 7ecca8b07851..283f780f5f56 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -92,9 +92,10 @@ static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt)
 	write_sysreg(ctxt_sys_reg(ctxt, TPIDRRO_EL0),	tpidrro_el0);
 }
 
-static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
+static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
+					      u64 mpidr)
 {
-	write_sysreg(ctxt_sys_reg(ctxt, MPIDR_EL1),	vmpidr_el2);
+	write_sysreg(mpidr,				vmpidr_el2);
 	write_sysreg(ctxt_sys_reg(ctxt, CSSELR_EL1),	csselr_el1);
 
 	if (has_vhe() ||
diff --git a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
index 29305022bc04..dba101565de3 100644
--- a/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/nvhe/sysreg-sr.c
@@ -28,7 +28,7 @@ void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt)
 
 void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt)
 {
-	__sysreg_restore_el1_state(ctxt);
+	__sysreg_restore_el1_state(ctxt, ctxt_sys_reg(ctxt, MPIDR_EL1));
 	__sysreg_restore_common_state(ctxt);
 	__sysreg_restore_user_state(ctxt);
 	__sysreg_restore_el2_return_state(ctxt);
diff --git a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
index 007a12dd4351..3e26a78d00c5 100644
--- a/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
+++ b/arch/arm64/kvm/hyp/vhe/sysreg-sr.c
@@ -13,6 +13,96 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
+#include <asm/kvm_nested.h>
+
+static void __sysreg_save_vel2_state(struct kvm_cpu_context *ctxt)
+{
+	/* These registers are common with EL1 */
+	ctxt_sys_reg(ctxt, CSSELR_EL1)	= read_sysreg(csselr_el1);
+	ctxt_sys_reg(ctxt, PAR_EL1)	= read_sysreg(par_el1);
+	ctxt_sys_reg(ctxt, TPIDR_EL1)	= read_sysreg(tpidr_el1);
+
+	ctxt_sys_reg(ctxt, ESR_EL2)	= read_sysreg_el1(SYS_ESR);
+	ctxt_sys_reg(ctxt, AFSR0_EL2)	= read_sysreg_el1(SYS_AFSR0);
+	ctxt_sys_reg(ctxt, AFSR1_EL2)	= read_sysreg_el1(SYS_AFSR1);
+	ctxt_sys_reg(ctxt, FAR_EL2)	= read_sysreg_el1(SYS_FAR);
+	ctxt_sys_reg(ctxt, MAIR_EL2)	= read_sysreg_el1(SYS_MAIR);
+	ctxt_sys_reg(ctxt, VBAR_EL2)	= read_sysreg_el1(SYS_VBAR);
+	ctxt_sys_reg(ctxt, CONTEXTIDR_EL2) = read_sysreg_el1(SYS_CONTEXTIDR);
+	ctxt_sys_reg(ctxt, AMAIR_EL2)	= read_sysreg_el1(SYS_AMAIR);
+
+	/*
+	 * In VHE mode those registers are compatible between EL1 and EL2,
+	 * and the guest uses the _EL1 versions on the CPU naturally.
+	 * So we save them into their _EL2 versions here.
+	 * For nVHE mode we trap accesses to those registers, so our
+	 * _EL2 copy in sys_regs[] is always up-to-date and we don't need
+	 * to save anything here.
+	 */
+	if (__vcpu_el2_e2h_is_set(ctxt)) {
+		ctxt_sys_reg(ctxt, SCTLR_EL2)	= read_sysreg_el1(SYS_SCTLR);
+		ctxt_sys_reg(ctxt, CPTR_EL2)	= read_sysreg_el1(SYS_CPACR);
+		ctxt_sys_reg(ctxt, TTBR0_EL2)	= read_sysreg_el1(SYS_TTBR0);
+		ctxt_sys_reg(ctxt, TTBR1_EL2)	= read_sysreg_el1(SYS_TTBR1);
+		ctxt_sys_reg(ctxt, TCR_EL2)	= read_sysreg_el1(SYS_TCR);
+		ctxt_sys_reg(ctxt, CNTHCTL_EL2)	= read_sysreg_el1(SYS_CNTKCTL);
+	}
+
+	ctxt_sys_reg(ctxt, SP_EL2)	= read_sysreg(sp_el1);
+	ctxt_sys_reg(ctxt, ELR_EL2)	= read_sysreg_el1(SYS_ELR);
+	ctxt_sys_reg(ctxt, SPSR_EL2)	= __fixup_spsr_el2_read(ctxt, read_sysreg_el1(SYS_SPSR));
+}
+
+static void __sysreg_restore_vel2_state(struct kvm_cpu_context *ctxt)
+{
+	u64 val;
+
+	/* These registers are common with EL1 */
+	write_sysreg(ctxt_sys_reg(ctxt, CSSELR_EL1),	csselr_el1);
+	write_sysreg(ctxt_sys_reg(ctxt, PAR_EL1),	par_el1);
+	write_sysreg(ctxt_sys_reg(ctxt, TPIDR_EL1),	tpidr_el1);
+
+	write_sysreg(read_cpuid_id(),			vpidr_el2);
+	write_sysreg(ctxt_sys_reg(ctxt, MPIDR_EL1),	vmpidr_el2);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, MAIR_EL2),	SYS_MAIR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, VBAR_EL2),	SYS_VBAR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, CONTEXTIDR_EL2),SYS_CONTEXTIDR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AMAIR_EL2),	SYS_AMAIR);
+
+	if (__vcpu_el2_e2h_is_set(ctxt)) {
+		/*
+		 * In VHE mode those registers are compatible between
+		 * EL1 and EL2.
+		 */
+		write_sysreg_el1(ctxt_sys_reg(ctxt, SCTLR_EL2),	SYS_SCTLR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, CPTR_EL2),	SYS_CPACR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL2),	SYS_TTBR0);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL2),	SYS_TTBR1);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TCR_EL2),	SYS_TCR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, CNTHCTL_EL2), SYS_CNTKCTL);
+	} else {
+		val = translate_sctlr_el2_to_sctlr_el1(ctxt_sys_reg(ctxt, SCTLR_EL2));
+		write_sysreg_el1(val, SYS_SCTLR);
+		val = translate_cptr_el2_to_cpacr_el1(ctxt_sys_reg(ctxt, CPTR_EL2));
+		write_sysreg_el1(val, SYS_CPACR);
+		val = translate_ttbr0_el2_to_ttbr0_el1(ctxt_sys_reg(ctxt, TTBR0_EL2));
+		write_sysreg_el1(val, SYS_TTBR0);
+		val = translate_tcr_el2_to_tcr_el1(ctxt_sys_reg(ctxt, TCR_EL2));
+		write_sysreg_el1(val, SYS_TCR);
+		val = translate_cnthctl_el2_to_cntkctl_el1(ctxt_sys_reg(ctxt, CNTHCTL_EL2));
+		write_sysreg_el1(val, SYS_CNTKCTL);
+	}
+
+	write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL2),	SYS_ESR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL2),	SYS_AFSR0);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR1_EL2),	SYS_AFSR1);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, FAR_EL2),	SYS_FAR);
+	write_sysreg(ctxt_sys_reg(ctxt, SP_EL2),	sp_el1);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, ELR_EL2),	SYS_ELR);
+
+	val = __fixup_spsr_el2_write(ctxt, ctxt_sys_reg(ctxt, SPSR_EL2));
+	write_sysreg_el1(val,	SYS_SPSR);
+}
 
 /*
  * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and
@@ -65,6 +155,7 @@ void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
 	struct kvm_cpu_context *host_ctxt;
+	u64 mpidr;
 
 	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	__sysreg_save_user_state(host_ctxt);
@@ -77,7 +168,29 @@ void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
 	 */
 	__sysreg32_restore_state(vcpu);
 	__sysreg_restore_user_state(guest_ctxt);
-	__sysreg_restore_el1_state(guest_ctxt);
+
+	if (unlikely(__is_hyp_ctxt(guest_ctxt))) {
+		__sysreg_restore_vel2_state(guest_ctxt);
+	} else {
+		if (vcpu_has_nv(vcpu)) {
+			/*
+			 * Only set VPIDR_EL2 for nested VMs, as this is the
+			 * only time it changes. We'll restore the MIDR_EL1
+			 * view on put.
+			 */
+			write_sysreg(ctxt_sys_reg(guest_ctxt, VPIDR_EL2), vpidr_el2);
+
+			/*
+			 * As we're restoring a nested guest, set the value
+			 * provided by the guest hypervisor.
+			 */
+			mpidr = ctxt_sys_reg(guest_ctxt, VMPIDR_EL2);
+		} else {
+			mpidr = ctxt_sys_reg(guest_ctxt, MPIDR_EL1);
+		}
+
+		__sysreg_restore_el1_state(guest_ctxt, mpidr);
+	}
 
 	vcpu->arch.sysregs_loaded_on_cpu = true;
 
@@ -103,12 +216,20 @@ void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu)
 	host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
 	deactivate_traps_vhe_put(vcpu);
 
-	__sysreg_save_el1_state(guest_ctxt);
+	if (unlikely(__is_hyp_ctxt(guest_ctxt)))
+		__sysreg_save_vel2_state(guest_ctxt);
+	else
+		__sysreg_save_el1_state(guest_ctxt);
+
 	__sysreg_save_user_state(guest_ctxt);
 	__sysreg32_save_state(vcpu);
 
 	/* Restore host user state */
 	__sysreg_restore_user_state(host_ctxt);
 
+	/* If leaving a nesting guest, restore MPIDR_EL1 default view */
+	if (vcpu_has_nv(vcpu))
+		write_sysreg(read_cpuid_id(),	vpidr_el2);
+
 	vcpu->arch.sysregs_loaded_on_cpu = false;
 }
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:25 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:25 +0000
Subject: [PATCH v6 17/64] KVM: arm64: nv: Emulate PSTATE.M for a guest
 hypervisor
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-18-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

We can no longer blindly copy the VCPU's PSTATE into SPSR_EL2 and return
to the guest and vice versa when taking an exception to the hypervisor,
because we emulate virtual EL2 in EL1 and therefore have to translate
the mode field from EL2 to EL1 and vice versa.

This requires keeping track of the state we enter the guest, for which
we transiently use a dedicated flag.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h          |  1 +
 arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h | 19 ++++++++++++++++-
 arch/arm64/kvm/hyp/vhe/switch.c            | 24 ++++++++++++++++++++++
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 8fffe2888403..fa253f08e0fd 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -472,6 +472,7 @@ struct kvm_vcpu_arch {
 #define KVM_ARM64_DEBUG_STATE_SAVE_SPE	(1 << 12) /* Save SPE context if active  */
 #define KVM_ARM64_DEBUG_STATE_SAVE_TRBE	(1 << 13) /* Save TRBE context if active  */
 #define KVM_ARM64_FP_FOREIGN_FPSTATE	(1 << 14)
+#define KVM_ARM64_IN_HYP_CONTEXT	(1 << 15) /* Guest running in HYP context */
 
 #define KVM_GUESTDBG_VALID_MASK (KVM_GUESTDBG_ENABLE | \
 				 KVM_GUESTDBG_USE_SW_BP | \
diff --git a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
index 283f780f5f56..e3689c6ce4cc 100644
--- a/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
+++ b/arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
@@ -157,9 +157,26 @@ static inline void __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt,
 	write_sysreg_el1(ctxt_sys_reg(ctxt, SPSR_EL1),	SYS_SPSR);
 }
 
+/* Read the VCPU state's PSTATE, but translate (v)EL2 to EL1. */
+static inline u64 to_hw_pstate(const struct kvm_cpu_context *ctxt)
+{
+	u64 mode = ctxt->regs.pstate & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+	switch (mode) {
+	case PSR_MODE_EL2t:
+		mode = PSR_MODE_EL1t;
+		break;
+	case PSR_MODE_EL2h:
+		mode = PSR_MODE_EL1h;
+		break;
+	}
+
+	return (ctxt->regs.pstate & ~(PSR_MODE_MASK | PSR_MODE32_BIT)) | mode;
+}
+
 static inline void __sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
 {
-	u64 pstate = ctxt->regs.pstate;
+	u64 pstate = to_hw_pstate(ctxt);
 	u64 mode = pstate & PSR_AA32_MODE_MASK;
 
 	/*
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 11d053fdd604..82ddaebe66de 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -113,6 +113,25 @@ static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
 
 static void early_exit_filter(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
+	/*
+	 * If we were in HYP context on entry, adjust the PSTATE view
+	 * so that the usual helpers work correctly.
+	 */
+	if (unlikely(vcpu->arch.flags & KVM_ARM64_IN_HYP_CONTEXT)) {
+		u64 mode = *vcpu_cpsr(vcpu) & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+		switch (mode) {
+		case PSR_MODE_EL1t:
+			mode = PSR_MODE_EL2t;
+			break;
+		case PSR_MODE_EL1h:
+			mode = PSR_MODE_EL2h;
+			break;
+		}
+
+		*vcpu_cpsr(vcpu) &= ~(PSR_MODE_MASK | PSR_MODE32_BIT);
+		*vcpu_cpsr(vcpu) |= mode;
+	}
 }
 
 /* Switch to the guest for VHE systems running in EL2 */
@@ -147,6 +166,11 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 	sysreg_restore_guest_state_vhe(guest_ctxt);
 	__debug_switch_to_guest(vcpu);
 
+	if (is_hyp_ctxt(vcpu))
+		vcpu->arch.flags |= KVM_ARM64_IN_HYP_CONTEXT;
+	else
+		vcpu->arch.flags &= ~KVM_ARM64_IN_HYP_CONTEXT;
+
 	do {
 		/* Jump in the fire! */
 		exit_code = __guest_enter(vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:33 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:33 +0000
Subject: [PATCH v6 25/64] KVM: arm64: nv: Respect virtual HCR_EL2.TVM and TRVM
 settings
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-26-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

Forward the EL1 virtual memory register traps to the virtual EL2 if they
are not coming from the virtual EL2 and the virtual HCR_EL2.TVM or TRVM
bit is set.

This is for recursive nested virtualization.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ccd063d6cb69..edaf287c7ec9 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -351,6 +351,13 @@ static bool access_vm_reg(struct kvm_vcpu *vcpu,
 	if (el12_reg(p) && forward_nv_traps(vcpu))
 		return false;
 
+	if (!el12_reg(p)) {
+		u64 bit = p->is_write ? HCR_TVM : HCR_TRVM;
+
+		if (forward_traps(vcpu, bit))
+			return false;
+	}
+
 	/* We don't expect TRVM on the host */
 	BUG_ON(!vcpu_is_el2(vcpu) && !p->is_write);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:37 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:37 +0000
Subject: [PATCH v6 29/64] KVM: arm64: nv: Forward debug traps to the nested
 guest
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-30-maz@kernel.org>

On handling a debug trap, check whether we need to forward it to the
guest before handling it.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 2 ++
 arch/arm64/kvm/emulate-nested.c     | 9 +++++++--
 arch/arm64/kvm/sys_regs.c           | 3 +++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 82fc8b6c990b..047ca700163b 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -66,6 +66,8 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
 }
 
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
+extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
+			    u64 control_bit);
 extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
 extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
 extern bool forward_nv1_traps(struct kvm_vcpu *vcpu);
diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 0109dfd664dd..1f6cf8fe9fe3 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -13,14 +13,14 @@
 
 #include "trace.h"
 
-bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
+bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg, u64 control_bit)
 {
 	bool control_bit_set;
 
 	if (!vcpu_has_nv(vcpu))
 		return false;
 
-	control_bit_set = __vcpu_sys_reg(vcpu, HCR_EL2) & control_bit;
+	control_bit_set = __vcpu_sys_reg(vcpu, reg) & control_bit;
 	if (!vcpu_is_el2(vcpu) && control_bit_set) {
 		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
 		return true;
@@ -28,6 +28,11 @@ bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
 	return false;
 }
 
+bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit)
+{
+	return __forward_traps(vcpu, HCR_EL2, control_bit);
+}
+
 bool forward_nv_traps(struct kvm_vcpu *vcpu)
 {
 	return forward_traps(vcpu, HCR_NV);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 697bf0bca550..3e1f37c507a8 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -566,6 +566,9 @@ static bool trap_debug_regs(struct kvm_vcpu *vcpu,
 			    struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
 {
+	if (__forward_traps(vcpu, MDCR_EL2, MDCR_EL2_TDA | MDCR_EL2_TDE))
+		return false;
+
 	access_rw(vcpu, p, r);
 	if (p->is_write)
 		vcpu->arch.flags |= KVM_ARM64_DEBUG_DIRTY;
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:20 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:20 +0000
Subject: [PATCH v6 12/64] KVM: arm64: nv: Add non-VHE-EL2->EL1 translation
 helpers
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-13-maz@kernel.org>

Some EL2 system registers immediately affect the current execution
of the system, so we need to use their respective EL1 counterparts.
For this we need to define a mapping between the two. In general,
this only affects non-VHE guest hypervisors, as VHE system registers
are compatible with the EL1 counterparts.

These helpers will get used in subsequent patches.

Co-developed-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Andre Przywara <andre.przywara at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 54 +++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index fd601ea68d13..5a85be6d8eb3 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -2,6 +2,7 @@
 #ifndef __ARM64_KVM_NESTED_H
 #define __ARM64_KVM_NESTED_H
 
+#include <linux/bitfield.h>
 #include <linux/kvm_host.h>
 
 static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
@@ -11,4 +12,57 @@ static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
 		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
 }
 
+/* Translation helpers from non-VHE EL2 to EL1 */
+static inline u64 tcr_el2_ps_to_tcr_el1_ips(u64 tcr_el2)
+{
+	return (u64)FIELD_GET(TCR_EL2_PS_MASK, tcr_el2) << TCR_IPS_SHIFT;
+}
+
+static inline u64 translate_tcr_el2_to_tcr_el1(u64 tcr)
+{
+	return TCR_EPD1_MASK |				/* disable TTBR1_EL1 */
+	       ((tcr & TCR_EL2_TBI) ? TCR_TBI0 : 0) |
+	       tcr_el2_ps_to_tcr_el1_ips(tcr) |
+	       (tcr & TCR_EL2_TG0_MASK) |
+	       (tcr & TCR_EL2_ORGN0_MASK) |
+	       (tcr & TCR_EL2_IRGN0_MASK) |
+	       (tcr & TCR_EL2_T0SZ_MASK);
+}
+
+static inline u64 translate_cptr_el2_to_cpacr_el1(u64 cptr_el2)
+{
+	u64 cpacr_el1 = 0;
+
+	if (cptr_el2 & CPTR_EL2_TTA)
+		cpacr_el1 |= CPACR_EL1_TTA;
+	if (!(cptr_el2 & CPTR_EL2_TFP))
+		cpacr_el1 |= CPACR_EL1_FPEN;
+	if (!(cptr_el2 & CPTR_EL2_TZ))
+		cpacr_el1 |= CPACR_EL1_ZEN;
+
+	return cpacr_el1;
+}
+
+static inline u64 translate_sctlr_el2_to_sctlr_el1(u64 val)
+{
+	/* Only preserve the minimal set of bits we support */
+	val &= (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | SCTLR_ELx_SA |
+		SCTLR_ELx_I | SCTLR_ELx_IESB | SCTLR_ELx_WXN | SCTLR_ELx_EE);
+	val |= SCTLR_EL1_RES1;
+
+	return val;
+}
+
+static inline u64 translate_ttbr0_el2_to_ttbr0_el1(u64 ttbr0)
+{
+	/* Clear the ASID field */
+	return ttbr0 & ~GENMASK_ULL(63, 48);
+}
+
+static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
+{
+	return ((FIELD_GET(CNTHCTL_EL1PCTEN | CNTHCTL_EL1PCEN, cnthctl) << 10) |
+		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));
+}
+
 #endif /* __ARM64_KVM_NESTED_H */
-- 
2.30.2



From dongas86 at gmail.com  Fri Jan 28 04:20:03 2022
From: dongas86 at gmail.com (Dong Aisheng)
Date: Fri, 28 Jan 2022 20:20:03 +0800
Subject: [PATCH v2 2/2] mm: cma: try next MAX_ORDER_NR_PAGES during retry
In-Reply-To: <517e1ea1-f826-228b-16a0-da1dc76017cc@redhat.com>
References: <20220112131552.3329380-1-aisheng.dong@nxp.com>
 <20220112131552.3329380-3-aisheng.dong@nxp.com>
 <517e1ea1-f826-228b-16a0-da1dc76017cc@redhat.com>
Message-ID: <CAA+hA=SFCERXZWmxiraq6N044Np+YTO+JgQFyX65AQmCfyrPQw@mail.gmail.com>

On Wed, Jan 26, 2022 at 12:33 AM David Hildenbrand <david at redhat.com> wrote:
>
> On 12.01.22 14:15, Dong Aisheng wrote:
> > On an ARMv7 platform with 32M pageblock(MAX_ORDER 14), we observed a
>
> Did you actually intend to talk about pageblocks here (and below)?
>
> I assume you have to be clearer here that you talk about the maximum
> allocation granularity, which is usually bigger than actual pageblock size.
>

I'm talking about the ARM32 case where pageblock_order is equal to MAX_ORDER -1.
/* If huge pages are not used, group by MAX_ORDER_NR_PAGES */
#define pageblock_order         (MAX_ORDER-1)
In order to be clearer, maybe I can add this info into the commit message too.

> > huge number of repeat retries of CMA allocation (1k+) during booting
> > when allocating one page for each of 3 mmc instance probe.
> >
> > This is caused by CMA now supports cocurrent allocation since commit
> > a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock").
> > The pageblock or (MAX_ORDER -1) from which we are trying to allocate
> > memory may have already been acquired and isolated by others.
> > Current cma_alloc() will then retry the next area by the step of
> > bitmap_no + mask + 1 which are very likely within the same isolated range
> > and fail again. So when the pageblock or MAX_ORDER is big (e.g. 8192),
> > keep retrying in a small step become meaningless because it will be known
> > to fail at a huge number of times due to the pageblock has been isolated
> > by others, especially when allocating only one or two pages.
> >
> > Instread of looping in the same pageblock and wasting CPU mips a lot,
> > especially for big pageblock system (e.g. 16M or 32M),
> > we try the next MAX_ORDER_NR_PAGES directly.
> >
> > Doing this way can greatly mitigate the situtation.
> >
> > Below is the original error log during booting:
> > [    2.004804] cma: cma_alloc(cma (ptrval), count 1, align 0)
> > [    2.010318] cma: cma_alloc(cma (ptrval), count 1, align 0)
> > [    2.010776] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > [    2.010785] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > [    2.010793] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > [    2.010800] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > [    2.010807] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > [    2.010814] cma: cma_alloc(): memory range at (ptrval) is busy, retrying
> > .... (+1K retries)
> >
> > After fix, the 1200+ reties can be reduced to 0.
> > Another test running 8 VPU decoder in parallel shows that 1500+ retries
> > dropped to ~145.
> >
> > IOW this patch can improve the CMA allocation speed a lot when there're
> > enough CMA memory by reducing retries significantly.
> >
> > Cc: Andrew Morton <akpm at linux-foundation.org>
> > Cc: Marek Szyprowski <m.szyprowski at samsung.com>
> > Cc: Lecopzer Chen <lecopzer.chen at mediatek.com>
> > Cc: David Hildenbrand <david at redhat.com>
> > Cc: Vlastimil Babka <vbabka at suse.cz>
> > CC: stable at vger.kernel.org # 5.11+
> > Fixes: a4efc174b382 ("mm/cma.c: remove redundant cma_mutex lock")
> > Signed-off-by: Dong Aisheng <aisheng.dong at nxp.com>
> > ---
> > v1->v2:
> >  * change to align with MAX_ORDER_NR_PAGES instead of pageblock_nr_pages
> > ---
> >  mm/cma.c | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/mm/cma.c b/mm/cma.c
> > index 1c13a729d274..1251f65e2364 100644
> > --- a/mm/cma.c
> > +++ b/mm/cma.c
> > @@ -500,7 +500,9 @@ struct page *cma_alloc(struct cma *cma, unsigned long count,
> >               trace_cma_alloc_busy_retry(cma->name, pfn, pfn_to_page(pfn),
> >                                          count, align);
> >               /* try again with a bit different memory target */
> > -             start = bitmap_no + mask + 1;
> > +             start = ALIGN(bitmap_no + mask + 1,
> > +                           MAX_ORDER_NR_PAGES >> cma->order_per_bit);
>
> Mind giving the reader a hint in the code why we went for
> MAX_ORDER_NR_PAGES?
>

Yes, good suggestion.
I could add one more line of code comments as follows:
"As alloc_contig_range() will isolate all pageblocks within the range
which are aligned
with max_t(MAX_ORDER_NR_PAGES, pageblock_nr_pages),
here we align with MAX_ORDER_NR_PAGES  which is usually bigger
than actual pageblock size"
Does this look ok to you?

> What would happen if the CMA granularity is bigger than
> MAX_ORDER_NR_PAGES? I'd assume no harm done, as we'd try aligning to 0.
>

I think yes.

Regards
Aisheng

> --
> Thanks,
>
> David / dhildenb
>


From geert+renesas at glider.be  Fri Jan 28 04:34:55 2022
From: geert+renesas at glider.be (Geert Uytterhoeven)
Date: Fri, 28 Jan 2022 13:34:55 +0100
Subject: [PATCH] arm64: defconfig: Enable additional support for Renesas
 platforms
Message-ID: <c9800d67f91a90d418a3ce44c59109ae0a87b2d8.1643373223.git.geert+renesas@glider.be>

Increase build and test coverage by enabling support for more hardware
present on Renesas SoCs and boards:
  - Renesas RSPI, RZ/G2L thermal, RZ/G2L WDT watchdog, and OSTM timer,
    as used on the RZ/G2L SMARC EVK board,
  - R-Car Image Signal Processor (ISP) and Display Unit embedded MIPI
    DSI encoder on R-Car V3U, as used on the Falcon board.

All of the above are modular, except for thermal, watchdog, and timer.

Signed-off-by: Geert Uytterhoeven <geert+renesas at glider.be>
---
To be queued in renesas-devel for v5.18.

 arch/arm64/configs/defconfig | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 92635ca9f635bb60..46ccecad89c52e4b 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -487,6 +487,7 @@ CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_ROCKCHIP=y
 CONFIG_SPI_RPCIF=m
+CONFIG_SPI_RSPI=m
 CONFIG_SPI_QCOM_QSPI=m
 CONFIG_SPI_QUP=y
 CONFIG_SPI_QCOM_GENI=m
@@ -576,6 +577,7 @@ CONFIG_IMX8MM_THERMAL=m
 CONFIG_ROCKCHIP_THERMAL=m
 CONFIG_RCAR_THERMAL=y
 CONFIG_RCAR_GEN3_THERMAL=y
+CONFIG_RZG2L_THERMAL=y
 CONFIG_ARMADA_THERMAL=y
 CONFIG_BCM2711_THERMAL=m
 CONFIG_BCM2835_THERMAL=m
@@ -601,6 +603,7 @@ CONFIG_QCOM_WDT=m
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
 CONFIG_RENESAS_WDT=y
+CONFIG_RENESAS_RZG2LWDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
 CONFIG_MFD_ALTERA_SYSMGR=y
@@ -662,6 +665,7 @@ CONFIG_V4L_PLATFORM_DRIVERS=y
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
+CONFIG_VIDEO_RCAR_ISP=m
 CONFIG_V4L_MEM2MEM_DRIVERS=y
 CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m
 CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
@@ -696,6 +700,7 @@ CONFIG_ROCKCHIP_INNO_HDMI=y
 CONFIG_ROCKCHIP_LVDS=y
 CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_RCAR_DW_HDMI=m
+CONFIG_DRM_RCAR_MIPI_DSI=m
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_SUN6I_DSI=m
 CONFIG_DRM_SUN8I_DW_HDMI=m
@@ -1022,6 +1027,7 @@ CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_RENESAS_OSTM=y
 CONFIG_ARM_MHU=y
 CONFIG_IMX_MBOX=y
 CONFIG_PLATFORM_MHU=y
-- 
2.25.1



From mchehab at kernel.org  Fri Jan 28 04:40:55 2022
From: mchehab at kernel.org (Mauro Carvalho Chehab)
Date: Fri, 28 Jan 2022 13:40:55 +0100
Subject: [PATCH v10 02/13] iommu/mediatek-v1: Free the existed fwspec if
 the master dev already has
In-Reply-To: <20220117070510.17642-3-yong.wu@mediatek.com>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
 <20220117070510.17642-3-yong.wu@mediatek.com>
Message-ID: <20220128134055.720bb43c@coco.lan>

Hi Matthias/Yong,

Are you ok if this patch gets merged via the media tree together with the
remaining series, or do you prefer to apply it via SoC tree instead?

Regards,
Mauro


Em Mon, 17 Jan 2022 15:04:59 +0800
Yong Wu <yong.wu at mediatek.com> escreveu:

> When the iommu master device enters of_iommu_xlate, the ops may be
> NULL(iommu dev is defered), then it will initialize the fwspec here:
> 
> [<c0c9c5bc>] (dev_iommu_fwspec_set) from [<c06bda80>]
> (iommu_fwspec_init+0xbc/0xd4)
> [<c06bd9c4>] (iommu_fwspec_init) from [<c06c0db4>]
> (of_iommu_xlate+0x7c/0x12c)
> [<c06c0d38>] (of_iommu_xlate) from [<c06c10e8>]
> (of_iommu_configure+0x144/0x1e8)
> 
> BUT the mtk_iommu_v1.c only supports arm32, the probing flow still is a bit
> weird. We always expect create the fwspec internally. otherwise it will
> enter here and return fail.
> 
> static int mtk_iommu_create_mapping(struct device *dev,
> 				    struct of_phandle_args *args)
> {
>         ...
> 	if (!fwspec) {
> 	        ....
> 	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {
>                 >>>>>>>>>>Enter here. return fail.<<<<<<<<<<<<  
> 		return -EINVAL;
> 	}
> 	...
> }
> 
> Thus, Free the existed fwspec if the master device already has fwspec.
> 
> This issue is reported at:
> https://lore.kernel.org/linux-mediatek/trinity-7d9ebdc9-4849-4d93-bfb5-429dcb4ee449-1626253158870 at 3c-app-gmx-bs01/
> 
> Reported-by: Frank Wunderlich <frank-w at public-files.de>
> Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> Acked-by: Joerg Roedel <jroedel at suse.de>
> Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> ---
>  drivers/iommu/mtk_iommu_v1.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> index be22fcf988ce..1467ba1e4417 100644
> --- a/drivers/iommu/mtk_iommu_v1.c
> +++ b/drivers/iommu/mtk_iommu_v1.c
> @@ -425,6 +425,15 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
>  	struct mtk_iommu_data *data;
>  	int err, idx = 0;
>  
> +	/*
> +	 * In the deferred case, free the existed fwspec.
> +	 * Always initialize the fwspec internally.
> +	 */
> +	if (fwspec) {
> +		iommu_fwspec_free(dev);
> +		fwspec = dev_iommu_fwspec_get(dev);
> +	}
> +
>  	while (!of_parse_phandle_with_args(dev->of_node, "iommus",
>  					   "#iommu-cells",
>  					   idx, &iommu_spec)) {



Thanks,
Mauro


From broonie at kernel.org  Fri Jan 28 04:41:10 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 12:41:10 +0000
Subject: [bootwrapper PATCH v3 01/15] aarch64: correct ZCR_EL3.LEN
 initialization
In-Reply-To: <YfO/d5a0zc7cBgw5@FVFF77S0Q05N>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
 <20220125150057.3936090-2-mark.rutland@arm.com>
 <YfAeal8MmLsUIJpo@sirena.org.uk> <YfAmYxs9mFK5GNuy@FVFF77S0Q05N>
 <YfA3D3c+lOyybNT3@sirena.org.uk> <YfLDkoihLFnixAaQ@FVFF77S0Q05N>
 <YfLqhKf4yYGVK8Do@sirena.org.uk> <YfO/d5a0zc7cBgw5@FVFF77S0Q05N>
Message-ID: <YfPkZgcEhJyZDgSB@sirena.org.uk>

On Fri, Jan 28, 2022 at 10:03:57AM +0000, Mark Rutland wrote:
> On Thu, Jan 27, 2022 at 06:55:00PM +0000, Mark Brown wrote:

> > The ideal thing for the boot wrapper would be option (c) with either a
> > configuration option to set the maximum to something lower than all
> > bits, unless someone was unduly enthusiastic and wanted to have an all
> > CPUs enumeration algorithm, but both are probably more trouble than it's
> > worth.

> FWIW, if it's useful for testing to be able to configure the ZCR_EL3.LEN to
> some smaller value, I'd be happy to move to (c) and get that plumbed into the
> build system.

For Linux it'd mainly be useful in the case where the boot wrapper got
used on systems which have asymmetric maximum vector lengths.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/27a363b2/attachment.sig>

From mchehab at kernel.org  Fri Jan 28 04:45:40 2022
From: mchehab at kernel.org (Mauro Carvalho Chehab)
Date: Fri, 28 Jan 2022 13:45:40 +0100
Subject: [PATCH v10 02/13] iommu/mediatek-v1: Free the existed fwspec if
 the master dev already has
In-Reply-To: <20220128134055.720bb43c@coco.lan>
References: <20220117070510.17642-1-yong.wu@mediatek.com>
 <20220117070510.17642-3-yong.wu@mediatek.com>
 <20220128134055.720bb43c@coco.lan>
Message-ID: <20220128134540.00c6c380@coco.lan>

Em Fri, 28 Jan 2022 13:40:55 +0100
Mauro Carvalho Chehab <mchehab at kernel.org> escreveu:

> Hi Matthias/Yong,
> 
> Are you ok if this patch gets merged via the media tree together with the
> remaining series, or do you prefer to apply it via SoC tree instead?

Same questions for other patches touching files outside drivers/media
on this pull request:

	https://patchwork.kernel.org/project/linux-mediatek/patch/7af52d61-47c7-581d-62ed-76a7f8315b16 at xs4all.nl/

Like those:
	0004-0013-iommu-mediatek-v1-Free-the-existed-fwspec-if-the-mas.patch
	0005-0013-iommu-mediatek-Return-ENODEV-if-the-device-is-NULL.patch
	0006-0013-iommu-mediatek-Add-probe_defer-for-smi-larb.patch
	0007-0013-iommu-mediatek-Add-device_link-between-the-consumer-.patch

Regards,
Mauro

> 
> Regards,
> Mauro
> 
> 
> Em Mon, 17 Jan 2022 15:04:59 +0800
> Yong Wu <yong.wu at mediatek.com> escreveu:
> 
> > When the iommu master device enters of_iommu_xlate, the ops may be
> > NULL(iommu dev is defered), then it will initialize the fwspec here:
> > 
> > [<c0c9c5bc>] (dev_iommu_fwspec_set) from [<c06bda80>]
> > (iommu_fwspec_init+0xbc/0xd4)
> > [<c06bd9c4>] (iommu_fwspec_init) from [<c06c0db4>]
> > (of_iommu_xlate+0x7c/0x12c)
> > [<c06c0d38>] (of_iommu_xlate) from [<c06c10e8>]
> > (of_iommu_configure+0x144/0x1e8)
> > 
> > BUT the mtk_iommu_v1.c only supports arm32, the probing flow still is a bit
> > weird. We always expect create the fwspec internally. otherwise it will
> > enter here and return fail.
> > 
> > static int mtk_iommu_create_mapping(struct device *dev,
> > 				    struct of_phandle_args *args)
> > {
> >         ...
> > 	if (!fwspec) {
> > 	        ....
> > 	} else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) {  
> >                 >>>>>>>>>>Enter here. return fail.<<<<<<<<<<<<    
> > 		return -EINVAL;
> > 	}
> > 	...
> > }
> > 
> > Thus, Free the existed fwspec if the master device already has fwspec.
> > 
> > This issue is reported at:
> > https://lore.kernel.org/linux-mediatek/trinity-7d9ebdc9-4849-4d93-bfb5-429dcb4ee449-1626253158870 at 3c-app-gmx-bs01/
> > 
> > Reported-by: Frank Wunderlich <frank-w at public-files.de>
> > Tested-by: Frank Wunderlich <frank-w at public-files.de> # BPI-R2/MT7623
> > Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> > Acked-by: Joerg Roedel <jroedel at suse.de>
> > Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> > ---
> >  drivers/iommu/mtk_iommu_v1.c | 9 +++++++++
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c
> > index be22fcf988ce..1467ba1e4417 100644
> > --- a/drivers/iommu/mtk_iommu_v1.c
> > +++ b/drivers/iommu/mtk_iommu_v1.c
> > @@ -425,6 +425,15 @@ static struct iommu_device *mtk_iommu_probe_device(struct device *dev)
> >  	struct mtk_iommu_data *data;
> >  	int err, idx = 0;
> >  
> > +	/*
> > +	 * In the deferred case, free the existed fwspec.
> > +	 * Always initialize the fwspec internally.
> > +	 */
> > +	if (fwspec) {
> > +		iommu_fwspec_free(dev);
> > +		fwspec = dev_iommu_fwspec_get(dev);
> > +	}
> > +
> >  	while (!of_parse_phandle_with_args(dev->of_node, "iommus",
> >  					   "#iommu-cells",
> >  					   idx, &iommu_spec)) {  
> 
> 
> 
> Thanks,
> Mauro



Thanks,
Mauro


From pbonzini at redhat.com  Fri Jan 28 04:48:10 2022
From: pbonzini at redhat.com (Paolo Bonzini)
Date: Fri, 28 Jan 2022 13:48:10 +0100
Subject: [GIT PULL] KVM/arm64 fixes for 5.17, take #1
In-Reply-To: <20220128101245.506715-1-maz@kernel.org>
References: <20220128101245.506715-1-maz@kernel.org>
Message-ID: <8a78eca4-79b2-e183-f01a-6f56124bfdeb@redhat.com>

On 1/28/22 11:12, Marc Zyngier wrote:
> The following changes since commit 1c53a1ae36120997a82f936d044c71075852e521:
> 
>    Merge branch kvm-arm64/misc-5.17 into kvmarm-master/next (2022-01-04 17:16:15 +0000)
> 
> are available in the Git repository at:
> 
>    git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm.git tags/kvmarm-fixes-5.17-1
> 
> for you to fetch changes up to 278583055a237270fac70518275ba877bf9e4013:
> 
>    KVM: arm64: Use shadow SPSR_EL1 when injecting exceptions on !VHE (2022-01-24 09:39:03 +0000)

Pulled, thanks.

Paolo



From maz at kernel.org  Fri Jan 28 04:18:46 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:46 +0000
Subject: [PATCH v6 38/64] KVM: arm64: nv: Unmap/flush shadow stage 2 page
 tables
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-39-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at linaro.org>

Unmap/flush shadow stage 2 page tables for the nested VMs as well as the
stage 2 page table for the guest hypervisor.

Note: A bunch of the code in mmu.c relating to MMU notifiers is
currently dealt with in an extremely abrupt way, for example by clearing
out an entire shadow stage-2 table. This will be handled in a more
efficient way using the reverse mapping feature in a later version of
the patch series.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_mmu.h    |  3 +++
 arch/arm64/include/asm/kvm_nested.h |  3 +++
 arch/arm64/kvm/mmu.c                | 31 +++++++++++++++++++----
 arch/arm64/kvm/nested.c             | 39 +++++++++++++++++++++++++++++
 4 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 0750d022bbf8..afad4a27a6f2 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -160,6 +160,8 @@ int create_hyp_io_mappings(phys_addr_t phys_addr, size_t size,
 			   void __iomem **haddr);
 int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
 			     void **haddr);
+void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu,
+			    phys_addr_t addr, phys_addr_t end);
 void free_hyp_pgds(void);
 
 void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size);
@@ -168,6 +170,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu);
 void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
 int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 			  phys_addr_t pa, unsigned long size, bool writable);
+void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end);
 
 int kvm_handle_guest_abort(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index f4b846d09d86..8915bead0633 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -118,6 +118,9 @@ extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
 extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
 				    struct kvm_s2_trans *trans);
 extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2);
+extern void kvm_nested_s2_wp(struct kvm *kvm);
+extern void kvm_nested_s2_clear(struct kvm *kvm);
+extern void kvm_nested_s2_flush(struct kvm *kvm);
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 			    u64 control_bit);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 7c56e1522d3c..b9b11be65009 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -190,13 +190,20 @@ void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
 	__unmap_stage2_range(mmu, start, size, true);
 }
 
+void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu,
+			    phys_addr_t addr, phys_addr_t end)
+{
+	stage2_apply_range_resched(kvm_s2_mmu_to_kvm(mmu), addr, end, kvm_pgtable_stage2_flush);
+}
+
 static void stage2_flush_memslot(struct kvm *kvm,
 				 struct kvm_memory_slot *memslot)
 {
 	phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT;
 	phys_addr_t end = addr + PAGE_SIZE * memslot->npages;
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
 
-	stage2_apply_range_resched(kvm, addr, end, kvm_pgtable_stage2_flush);
+	kvm_stage2_flush_range(mmu, addr, end);
 }
 
 /**
@@ -219,6 +226,8 @@ static void stage2_flush_vm(struct kvm *kvm)
 	kvm_for_each_memslot(memslot, bkt, slots)
 		stage2_flush_memslot(kvm, memslot);
 
+	kvm_nested_s2_flush(kvm);
+
 	spin_unlock(&kvm->mmu_lock);
 	srcu_read_unlock(&kvm->srcu, idx);
 }
@@ -742,6 +751,8 @@ void stage2_unmap_vm(struct kvm *kvm)
 	kvm_for_each_memslot(memslot, bkt, slots)
 		stage2_unmap_memslot(kvm, memslot);
 
+	kvm_nested_s2_clear(kvm);
+
 	spin_unlock(&kvm->mmu_lock);
 	mmap_read_unlock(current->mm);
 	srcu_read_unlock(&kvm->srcu, idx);
@@ -814,12 +825,12 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
 }
 
 /**
- * stage2_wp_range() - write protect stage2 memory region range
+ * kvm_stage2_wp_range() - write protect stage2 memory region range
  * @mmu:        The KVM stage-2 MMU pointer
  * @addr:	Start address of range
  * @end:	End address of range
  */
-static void stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
+void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
 	stage2_apply_range_resched(kvm, addr, end, kvm_pgtable_stage2_wrprotect);
@@ -851,7 +862,8 @@ static void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
 	end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
 
 	spin_lock(&kvm->mmu_lock);
-	stage2_wp_range(&kvm->arch.mmu, start, end);
+	kvm_stage2_wp_range(&kvm->arch.mmu, start, end);
+	kvm_nested_s2_wp(kvm);
 	spin_unlock(&kvm->mmu_lock);
 	kvm_flush_remote_tlbs(kvm);
 }
@@ -875,7 +887,7 @@ static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
 	phys_addr_t start = (base_gfn +  __ffs(mask)) << PAGE_SHIFT;
 	phys_addr_t end = (base_gfn + __fls(mask) + 1) << PAGE_SHIFT;
 
-	stage2_wp_range(&kvm->arch.mmu, start, end);
+	kvm_stage2_wp_range(&kvm->arch.mmu, start, end);
 }
 
 /*
@@ -890,6 +902,7 @@ void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
 		gfn_t gfn_offset, unsigned long mask)
 {
 	kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
+	kvm_nested_s2_wp(kvm);
 }
 
 static void kvm_send_hwpoison_signal(unsigned long address, short lsb)
@@ -1529,6 +1542,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
 			     (range->end - range->start) << PAGE_SHIFT,
 			     range->may_block);
 
+	kvm_nested_s2_clear(kvm);
 	return false;
 }
 
@@ -1560,6 +1574,7 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 			       PAGE_SIZE, __pfn_to_phys(pfn),
 			       KVM_PGTABLE_PROT_R, NULL);
 
+	kvm_nested_s2_clear(kvm);
 	return false;
 }
 
@@ -1578,6 +1593,11 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
 					range->start << PAGE_SHIFT);
 	pte = __pte(kpte);
 	return pte_valid(pte) && pte_young(pte);
+
+	/*
+	 * TODO: Handle nested_mmu structures here using the reverse mapping in
+	 * a later version of patch series.
+	 */
 }
 
 bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range)
@@ -1789,6 +1809,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 
 	spin_lock(&kvm->mmu_lock);
 	kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, size);
+	kvm_nested_s2_clear(kvm);
 	spin_unlock(&kvm->mmu_lock);
 }
 
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index a74ffb1d2064..b39af4d87787 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -505,6 +505,45 @@ int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2)
 	return kvm_inject_nested_sync(vcpu, esr_el2);
 }
 
+/* expects kvm->mmu_lock to be held */
+void kvm_nested_s2_wp(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+		if (kvm_s2_mmu_valid(mmu))
+			kvm_stage2_wp_range(mmu, 0, kvm_phys_size(kvm));
+	}
+}
+
+/* expects kvm->mmu_lock to be held */
+void kvm_nested_s2_clear(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+		if (kvm_s2_mmu_valid(mmu))
+			kvm_unmap_stage2_range(mmu, 0, kvm_phys_size(kvm));
+	}
+}
+
+/* expects kvm->mmu_lock to be held */
+void kvm_nested_s2_flush(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+		if (kvm_s2_mmu_valid(mmu))
+			kvm_stage2_flush_range(mmu, 0, kvm_phys_size(kvm));
+	}
+}
+
 /*
  * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
  * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:05 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:05 +0000
Subject: [PATCH v6 57/64] KVM: arm64: nv: Map VNCR-capable registers to a
 separate page
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-58-maz@kernel.org>

With ARMv8.4-NV, registers that can be directly accessed in memory
by the guest have to live at architected offsets in a special page.

Let's annotate the sysreg enum to reflect the offset at which they
are in this page, whith a little twist:

If running on HW that doesn't have the ARMv8.4-NV feature, or even
a VM that doesn't use NV, we store all the system registers in the
usual sys_regs array. The only difference with the pre-8.4
situation is that VNCR-capable registers are at a "similar" offset
as in the VNCR page (we can compute the actual offset at compile
time), and that the sys_regs array is both bigger and sparse.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 99 ++++++++++++++++++++-----------
 1 file changed, 64 insertions(+), 35 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0ea8cf0eeca7..3f6ddccae310 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -26,6 +26,7 @@
 #include <asm/fpsimd.h>
 #include <asm/kvm.h>
 #include <asm/kvm_asm.h>
+#include <asm/vncr_mapping.h>
 
 #define __KVM_HAVE_ARCH_INTC_INITIALIZED
 
@@ -180,31 +181,32 @@ struct kvm_vcpu_fault_info {
 	u64 disr_el1;		/* Deferred [SError] Status Register */
 };
 
+/*
+ * VNCR() just places the VNCR_capable registers in the enum after
+ * __VNCR_START__, and the value (after correction) to be an 8-byte offset
+ * from the VNCR base. As we don't require the enum to be otherwise ordered,
+ * we need the terrible hack below to ensure that we correctly size the
+ * sys_regs array, no matter what.
+ *
+ * The __MAX__ macro has been lifted from Sean Eron Anderson's wonderful
+ * treasure trove of bit hacks:
+ * https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
+ */
+#define __MAX__(x,y)	((x) ^ (((x) ^ (y)) & -((x) < (y))))
+#define VNCR(r)						\
+	__before_##r,					\
+	r = __VNCR_START__ + ((VNCR_ ## r) / 8),	\
+	__after_##r = __MAX__(__before_##r - 1, r)
+
 enum vcpu_sysreg {
 	__INVALID_SYSREG__,   /* 0 is reserved as an invalid value */
 	MPIDR_EL1,	/* MultiProcessor Affinity Register */
 	CSSELR_EL1,	/* Cache Size Selection Register */
-	SCTLR_EL1,	/* System Control Register */
-	ACTLR_EL1,	/* Auxiliary Control Register */
-	CPACR_EL1,	/* Coprocessor Access Control */
-	ZCR_EL1,	/* SVE Control */
-	TTBR0_EL1,	/* Translation Table Base Register 0 */
-	TTBR1_EL1,	/* Translation Table Base Register 1 */
-	TCR_EL1,	/* Translation Control Register */
-	ESR_EL1,	/* Exception Syndrome Register */
-	AFSR0_EL1,	/* Auxiliary Fault Status Register 0 */
-	AFSR1_EL1,	/* Auxiliary Fault Status Register 1 */
-	FAR_EL1,	/* Fault Address Register */
-	MAIR_EL1,	/* Memory Attribute Indirection Register */
-	VBAR_EL1,	/* Vector Base Address Register */
-	CONTEXTIDR_EL1,	/* Context ID Register */
 	TPIDR_EL0,	/* Thread ID, User R/W */
 	TPIDRRO_EL0,	/* Thread ID, User R/O */
 	TPIDR_EL1,	/* Thread ID, Privileged */
-	AMAIR_EL1,	/* Aux Memory Attribute Indirection Register */
 	CNTKCTL_EL1,	/* Timer Control Register (EL1) */
 	PAR_EL1,	/* Physical Address Register */
-	MDSCR_EL1,	/* Monitor Debug System Control Register */
 	MDCCINT_EL1,	/* Monitor Debug Comms Channel Interrupt Enable Reg */
 	DISR_EL1,	/* Deferred Interrupt Status Register */
 
@@ -234,20 +236,9 @@ enum vcpu_sysreg {
 	APGAKEYLO_EL1,
 	APGAKEYHI_EL1,
 
-	ELR_EL1,
-	SP_EL1,
-	SPSR_EL1,
-
-	CNTVOFF_EL2,
-	CNTV_CVAL_EL0,
-	CNTV_CTL_EL0,
-	CNTP_CVAL_EL0,
-	CNTP_CTL_EL0,
-
 	/* Memory Tagging Extension registers */
 	RGSR_EL1,	/* Random Allocation Tag Seed Register */
 	GCR_EL1,	/* Tag Control Register */
-	TFSR_EL1,	/* Tag Fault Status Register (EL1) */
 	TFSRE0_EL1,	/* Tag Fault Status Register (EL0) */
 
 	/* 32bit specific registers. */
@@ -257,20 +248,14 @@ enum vcpu_sysreg {
 	DBGVCR32_EL2,	/* Debug Vector Catch Register */
 
 	/* EL2 registers */
-	VPIDR_EL2,	/* Virtualization Processor ID Register */
-	VMPIDR_EL2,	/* Virtualization Multiprocessor ID Register */
 	SCTLR_EL2,	/* System Control Register (EL2) */
 	ACTLR_EL2,	/* Auxiliary Control Register (EL2) */
-	HCR_EL2,	/* Hypervisor Configuration Register */
 	MDCR_EL2,	/* Monitor Debug Configuration Register (EL2) */
 	CPTR_EL2,	/* Architectural Feature Trap Register (EL2) */
-	HSTR_EL2,	/* Hypervisor System Trap Register */
 	HACR_EL2,	/* Hypervisor Auxiliary Control Register */
 	TTBR0_EL2,	/* Translation Table Base Register 0 (EL2) */
 	TTBR1_EL2,	/* Translation Table Base Register 1 (EL2) */
 	TCR_EL2,	/* Translation Control Register (EL2) */
-	VTTBR_EL2,	/* Virtualization Translation Table Base Register */
-	VTCR_EL2,	/* Virtualization Translation Control Register */
 	SPSR_EL2,	/* EL2 saved program status register */
 	ELR_EL2,	/* EL2 exception link register */
 	AFSR0_EL2,	/* Auxiliary Fault Status Register 0 (EL2) */
@@ -283,7 +268,6 @@ enum vcpu_sysreg {
 	VBAR_EL2,	/* Vector Base Address Register (EL2) */
 	RVBAR_EL2,	/* Reset Vector Base Address Register */
 	CONTEXTIDR_EL2,	/* Context ID Register (EL2) */
-	TPIDR_EL2,	/* EL2 Software Thread ID Register */
 	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 	SP_EL2,		/* EL2 Stack Pointer */
 	CNTHP_CTL_EL2,
@@ -291,6 +275,42 @@ enum vcpu_sysreg {
 	CNTHV_CTL_EL2,
 	CNTHV_CVAL_EL2,
 
+	__VNCR_START__,	/* Any VNCR-capable reg goes after this point */
+
+	VNCR(SCTLR_EL1),/* System Control Register */
+	VNCR(ACTLR_EL1),/* Auxiliary Control Register */
+	VNCR(CPACR_EL1),/* Coprocessor Access Control */
+	VNCR(ZCR_EL1),	/* SVE Control */
+	VNCR(TTBR0_EL1),/* Translation Table Base Register 0 */
+	VNCR(TTBR1_EL1),/* Translation Table Base Register 1 */
+	VNCR(TCR_EL1),	/* Translation Control Register */
+	VNCR(ESR_EL1),	/* Exception Syndrome Register */
+	VNCR(AFSR0_EL1),/* Auxiliary Fault Status Register 0 */
+	VNCR(AFSR1_EL1),/* Auxiliary Fault Status Register 1 */
+	VNCR(FAR_EL1),	/* Fault Address Register */
+	VNCR(MAIR_EL1),	/* Memory Attribute Indirection Register */
+	VNCR(VBAR_EL1),	/* Vector Base Address Register */
+	VNCR(CONTEXTIDR_EL1),	/* Context ID Register */
+	VNCR(AMAIR_EL1),/* Aux Memory Attribute Indirection Register */
+	VNCR(MDSCR_EL1),/* Monitor Debug System Control Register */
+	VNCR(ELR_EL1),
+	VNCR(SP_EL1),
+	VNCR(SPSR_EL1),
+	VNCR(TFSR_EL1),	/* Tag Fault Status Register (EL1) */
+	VNCR(VPIDR_EL2),/* Virtualization Processor ID Register */
+	VNCR(VMPIDR_EL2),/* Virtualization Multiprocessor ID Register */
+	VNCR(HCR_EL2),	/* Hypervisor Configuration Register */
+	VNCR(HSTR_EL2),	/* Hypervisor System Trap Register */
+	VNCR(VTTBR_EL2),/* Virtualization Translation Table Base Register */
+	VNCR(VTCR_EL2),	/* Virtualization Translation Control Register */
+	VNCR(TPIDR_EL2),/* EL2 Software Thread ID Register */
+
+	VNCR(CNTVOFF_EL2),
+	VNCR(CNTV_CVAL_EL0),
+	VNCR(CNTV_CTL_EL0),
+	VNCR(CNTP_CVAL_EL0),
+	VNCR(CNTP_CTL_EL0),
+
 	NR_SYS_REGS	/* Nothing after this line! */
 };
 
@@ -307,6 +327,9 @@ struct kvm_cpu_context {
 	u64 sys_regs[NR_SYS_REGS];
 
 	struct kvm_vcpu *__hyp_running_vcpu;
+
+	/* This pointer has to be 4kB aligned. */
+	u64 *vncr_array;
 };
 
 struct kvm_pmu_events {
@@ -534,7 +557,13 @@ struct kvm_vcpu_arch {
  * for system registers that are never context switched, but only
  * emulated.
  */
-#define __ctxt_sys_reg(c,r)	(&(c)->sys_regs[(r)])
+static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
+{
+	if (unlikely(r >= __VNCR_START__ && ctxt->vncr_array))
+		return &ctxt->vncr_array[r - __VNCR_START__];
+
+	return (u64 *)&ctxt->sys_regs[r];
+}
 
 #define ctxt_sys_reg(c,r)	(*__ctxt_sys_reg(c,r))
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:56 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:56 +0000
Subject: [PATCH v6 48/64] KVM: arm64: nv: vgic: Emulate the HW bit in software
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-49-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Should the guest hypervisor use the HW bit in the LRs, we need to
emulate the deactivation from the L2 guest into the L1 distributor
emulation, which is handled by L0.

It's all good fun.

Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_hyp.h     |  2 ++
 arch/arm64/kvm/hyp/vgic-v3-sr.c      |  2 +-
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 32 ++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic.c           |  6 ++++--
 include/kvm/arm_vgic.h               |  1 +
 5 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 462882f356c7..9dc157a59642 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -57,6 +57,8 @@ DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
 
 int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
 
+u64 __gic_v3_get_lr(unsigned int lr);
+
 void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
 void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
 void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 20db2f281cf2..0601d73de11b 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -18,7 +18,7 @@
 #define vtr_to_nr_pre_bits(v)		((((u32)(v) >> 26) & 7) + 1)
 #define vtr_to_nr_apr_regs(v)		(1 << (vtr_to_nr_pre_bits(v) - 5))
 
-static u64 __gic_v3_get_lr(unsigned int lr)
+u64 __gic_v3_get_lr(unsigned int lr)
 {
 	switch (lr & 0xf) {
 	case 0:
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index ab8ddf490b31..e88c75e79010 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -140,6 +140,38 @@ static void vgic_v3_fixup_shadow_lr_state(struct kvm_vcpu *vcpu)
 	}
 }
 
+void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
+	struct vgic_irq *irq;
+	int i;
+
+	for (i = 0; i < s_cpu_if->used_lrs; i++) {
+		u64 lr = cpu_if->vgic_lr[i];
+		int l1_irq;
+
+		if (!(lr & ICH_LR_HW) || !(lr & ICH_LR_STATE))
+			continue;
+
+		/*
+		 * If we had a HW lr programmed by the guest hypervisor, we
+		 * need to emulate the HW effect between the guest hypervisor
+		 * and the nested guest.
+		 */
+		l1_irq = (lr & ICH_LR_PHYS_ID_MASK) >> ICH_LR_PHYS_ID_SHIFT;
+		irq = vgic_get_irq(vcpu->kvm, vcpu, l1_irq);
+		if (!irq)
+			continue; /* oh well, the guest hyp is broken */
+
+		lr = __gic_v3_get_lr(i);
+		if (!(lr & ICH_LR_STATE))
+			irq->active = false;
+
+		vgic_put_irq(vcpu->kvm, irq);
+	}
+}
+
 void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index f467ea454c66..92df86726c86 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -876,9 +876,11 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
 	int used_lrs;
 
-	/* If nesting, this is a load/put affair, not flush/sync. */
-	if (vgic_state_is_nested(vcpu))
+	/* If nesting, emulate the HW effect from L0 to L1 */
+	if (vgic_state_is_nested(vcpu)) {
+		vgic_v3_sync_nested(vcpu);
 		return;
+	}
 
 	/* An empty ap_list_head implies used_lrs == 0 */
 	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 2e27259b451f..beeb99dc3cc1 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -393,6 +393,7 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu);
 void kvm_vgic_put(struct kvm_vcpu *vcpu);
 void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu);
 
+void vgic_v3_sync_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:06 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:06 +0000
Subject: [PATCH v6 58/64] KVM: arm64: nv: Move nested vgic state into the
 sysreg file
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-59-maz@kernel.org>

The vgic nested state needs to be accessible from the VNCR page, and
thus needs to be part of the normal sysreg file. Let's move it there.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h    |  9 +++
 arch/arm64/kvm/sys_regs.c            | 53 +++++++++++------
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 88 ++++++++++++++--------------
 arch/arm64/kvm/vgic/vgic-v3.c        | 17 ++++--
 arch/arm64/kvm/vgic/vgic.h           | 10 ++++
 include/kvm/arm_vgic.h               |  7 ---
 6 files changed, 110 insertions(+), 74 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 3f6ddccae310..15bbe8ccdefa 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -311,6 +311,15 @@ enum vcpu_sysreg {
 	VNCR(CNTP_CVAL_EL0),
 	VNCR(CNTP_CTL_EL0),
 
+	VNCR(ICH_LR0_EL2),
+	ICH_LR15_EL2 = ICH_LR0_EL2 + 15,
+	VNCR(ICH_AP0R0_EL2),
+	ICH_AP0R3_EL2 = ICH_AP0R0_EL2 + 3,
+	VNCR(ICH_AP1R0_EL2),
+	ICH_AP1R3_EL2 = ICH_AP1R0_EL2 + 3,
+	VNCR(ICH_HCR_EL2),
+	VNCR(ICH_VMCR_EL2),
+
 	NR_SYS_REGS	/* Nothing after this line! */
 };
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 32b8f4c1074a..351bcb429f25 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1865,17 +1865,17 @@ static bool access_gic_apr(struct kvm_vcpu *vcpu,
 			   struct sys_reg_params *p,
 			   const struct sys_reg_desc *r)
 {
-	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
-	u32 index, *base;
+	u64 *base;
+	u8 index;
 
 	index = r->Op2;
 	if (r->CRm == 8)
-		base = cpu_if->vgic_ap0r;
+		base = __ctxt_sys_reg(&vcpu->arch.ctxt, ICH_AP0R0_EL2);
 	else
-		base = cpu_if->vgic_ap1r;
+		base = __ctxt_sys_reg(&vcpu->arch.ctxt, ICH_AP1R0_EL2);
 
 	if (p->is_write)
-		base[index] = p->regval;
+		base[index] = lower_32_bits(p->regval);
 	else
 		p->regval = base[index];
 
@@ -1886,12 +1886,10 @@ static bool access_gic_hcr(struct kvm_vcpu *vcpu,
 			   struct sys_reg_params *p,
 			   const struct sys_reg_desc *r)
 {
-	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
-
 	if (p->is_write)
-		cpu_if->vgic_hcr = p->regval;
+		__vcpu_sys_reg(vcpu, ICH_HCR_EL2) = lower_32_bits(p->regval);
 	else
-		p->regval = cpu_if->vgic_hcr;
+		p->regval = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
 
 	return true;
 }
@@ -1948,12 +1946,19 @@ static bool access_gic_vmcr(struct kvm_vcpu *vcpu,
 			    struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
 {
-	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
-
 	if (p->is_write)
-		cpu_if->vgic_vmcr = p->regval;
+		__vcpu_sys_reg(vcpu, ICH_VMCR_EL2) = (p->regval	&
+						      (ICH_VMCR_ENG0_MASK	|
+						       ICH_VMCR_ENG1_MASK	|
+						       ICH_VMCR_PMR_MASK	|
+						       ICH_VMCR_BPR0_MASK	|
+						       ICH_VMCR_BPR1_MASK	|
+						       ICH_VMCR_EOIM_MASK	|
+						       ICH_VMCR_CBPR_MASK	|
+						       ICH_VMCR_FIQ_EN_MASK	|
+						       ICH_VMCR_ACK_CTL_MASK));
 	else
-		p->regval = cpu_if->vgic_vmcr;
+		p->regval = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2);
 
 	return true;
 }
@@ -1962,17 +1967,29 @@ static bool access_gic_lr(struct kvm_vcpu *vcpu,
 			  struct sys_reg_params *p,
 			  const struct sys_reg_desc *r)
 {
-	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
 	u32 index;
+	u64 *base;
 
+	base = __ctxt_sys_reg(&vcpu->arch.ctxt, ICH_LR0_EL2);
 	index = p->Op2;
 	if (p->CRm == 13)
 		index += 8;
 
-	if (p->is_write)
-		cpu_if->vgic_lr[index] = p->regval;
-	else
-		p->regval = cpu_if->vgic_lr[index];
+	if (p->is_write) {
+		u64 mask = (ICH_LR_VIRTUAL_ID_MASK	|
+			    ICH_LR_GROUP		|
+			    ICH_LR_HW			|
+			    ICH_LR_STATE);
+
+		if (p->regval & ICH_LR_HW)
+			mask |= ICH_LR_PHYS_ID_MASK;
+		else
+			mask |= ICH_LR_EOI;
+
+		base[index] = p->regval & mask;
+	} else {
+		p->regval = base[index];
+	}
 
 	return true;
 }
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index 02b0b335f72a..5ffffddb5776 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -18,11 +18,6 @@
 #define CREATE_TRACE_POINTS
 #include "vgic-nested-trace.h"
 
-static inline struct vgic_v3_cpu_if *vcpu_nested_if(struct kvm_vcpu *vcpu)
-{
-	return &vcpu->arch.vgic_cpu.nested_vgic_v3;
-}
-
 static inline struct vgic_v3_cpu_if *vcpu_shadow_if(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.vgic_cpu.shadow_vgic_v3;
@@ -35,12 +30,11 @@ static inline bool lr_triggers_eoi(u64 lr)
 
 u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	u16 reg = 0;
 	int i;
 
 	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
-		if (lr_triggers_eoi(cpu_if->vgic_lr[i]))
+		if (lr_triggers_eoi(__vcpu_sys_reg(vcpu, ICH_LRN(i))))
 			reg |= BIT(i);
 	}
 
@@ -49,12 +43,11 @@ u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu)
 
 u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	u16 reg = 0;
 	int i;
 
 	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
-		if (!(cpu_if->vgic_lr[i] & ICH_LR_STATE))
+		if (!(__vcpu_sys_reg(vcpu, ICH_LRN(i)) & ICH_LR_STATE))
 			reg |= BIT(i);
 	}
 
@@ -63,14 +56,13 @@ u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu)
 
 u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	int nr_lr = kvm_vgic_global_state.nr_lr;
 	u64 reg = 0;
 
 	if (vgic_v3_get_eisr(vcpu))
 		reg |= ICH_MISR_EOI;
 
-	if (cpu_if->vgic_hcr & ICH_HCR_UIE) {
+	if (__vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_UIE) {
 		int used_lrs;
 
 		used_lrs = nr_lr - hweight16(vgic_v3_get_elrsr(vcpu));
@@ -89,13 +81,12 @@ u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
  */
 static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
 	struct vgic_irq *irq;
 	int i, used_lrs = 0;
 
 	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
-		u64 lr = cpu_if->vgic_lr[i];
+		u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i));
 		int l1_irq;
 
 		if (!(lr & ICH_LR_HW))
@@ -125,36 +116,20 @@ static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu)
 	}
 
 	trace_vgic_create_shadow_lrs(vcpu, kvm_vgic_global_state.nr_lr,
-				     s_cpu_if->vgic_lr, cpu_if->vgic_lr);
+				     s_cpu_if->vgic_lr,
+				     __ctxt_sys_reg(&vcpu->arch.ctxt, ICH_LR0_EL2));
 
 	s_cpu_if->used_lrs = used_lrs;
 }
 
-/*
- * Change the shadow HWIRQ field back to the virtual value before copying over
- * the entire shadow struct to the nested state.
- */
-static void vgic_v3_fixup_shadow_lr_state(struct kvm_vcpu *vcpu)
-{
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
-	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
-	int lr;
-
-	for (lr = 0; lr < kvm_vgic_global_state.nr_lr; lr++) {
-		s_cpu_if->vgic_lr[lr] &= ~ICH_LR_PHYS_ID_MASK;
-		s_cpu_if->vgic_lr[lr] |= cpu_if->vgic_lr[lr] & ICH_LR_PHYS_ID_MASK;
-	}
-}
-
 void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
 	struct vgic_irq *irq;
 	int i;
 
 	for (i = 0; i < s_cpu_if->used_lrs; i++) {
-		u64 lr = cpu_if->vgic_lr[i];
+		u64 lr = __vcpu_sys_reg(vcpu, ICH_LRN(i));
 		int l1_irq;
 
 		if (!(lr & ICH_LR_HW) || !(lr & ICH_LR_STATE))
@@ -180,14 +155,27 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 	}
 }
 
+void vgic_v3_create_shadow_state(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.shadow_vgic_v3;
+	int i;
+
+	cpu_if->vgic_hcr = __vcpu_sys_reg(vcpu, ICH_HCR_EL2);
+	cpu_if->vgic_vmcr = __vcpu_sys_reg(vcpu, ICH_VMCR_EL2);
+
+	for (i = 0; i < 4; i++) {
+		cpu_if->vgic_ap0r[i] = __vcpu_sys_reg(vcpu, ICH_AP0RN(i));
+		cpu_if->vgic_ap1r[i] = __vcpu_sys_reg(vcpu, ICH_AP1RN(i));
+	}
+
+	vgic_v3_create_shadow_lr(vcpu);
+}
+
 void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
 {
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
 	struct vgic_irq *irq;
 	unsigned long flags;
 
-	vgic_cpu->shadow_vgic_v3 = vgic_cpu->nested_vgic_v3;
-	vgic_v3_create_shadow_lr(vcpu);
 	__vgic_v3_restore_state(vcpu_shadow_if(vcpu));
 
 	irq = vgic_get_irq(vcpu->kvm, vcpu, vcpu->kvm->arch.vgic.maint_irq);
@@ -201,26 +189,40 @@ void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
 
 void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 {
-	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
+	int i;
 
-	__vgic_v3_save_state(vcpu_shadow_if(vcpu));
+	__vgic_v3_save_state(s_cpu_if);
 
-	trace_vgic_put_nested(vcpu, kvm_vgic_global_state.nr_lr,
-			      vcpu_shadow_if(vcpu)->vgic_lr);
+	trace_vgic_put_nested(vcpu, kvm_vgic_global_state.nr_lr, s_cpu_if->vgic_lr);
 
 	/*
 	 * Translate the shadow state HW fields back to the virtual ones
 	 * before copying the shadow struct back to the nested one.
 	 */
-	vgic_v3_fixup_shadow_lr_state(vcpu);
-	vgic_cpu->nested_vgic_v3 = vgic_cpu->shadow_vgic_v3;
+	__vcpu_sys_reg(vcpu, ICH_HCR_EL2) = s_cpu_if->vgic_hcr;
+	__vcpu_sys_reg(vcpu, ICH_VMCR_EL2) = s_cpu_if->vgic_vmcr;
+
+	for (i = 0; i < 4; i++) {
+		__vcpu_sys_reg(vcpu, ICH_AP0RN(i)) = s_cpu_if->vgic_ap0r[i];
+		__vcpu_sys_reg(vcpu, ICH_AP1RN(i)) = s_cpu_if->vgic_ap1r[i];
+	}
+
+	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		u64 val = __vcpu_sys_reg(vcpu, ICH_LRN(i));
+
+		val &= ~ICH_LR_STATE;
+		val |= s_cpu_if->vgic_lr[i] & ICH_LR_STATE;
+
+		__vcpu_sys_reg(vcpu, ICH_LRN(i)) = val;
+	}
+
 	irq_set_irqchip_state(kvm_vgic_global_state.maint_irq,
 			      IRQCHIP_STATE_ACTIVE, false);
 }
 
 void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
 {
-	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
 	bool state;
 
 	/*
@@ -232,7 +234,7 @@ void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
 	if (!vgic_state_is_nested(vcpu))
 		return;
 
-	state  = cpu_if->vgic_hcr & ICH_HCR_EN;
+	state  = __vcpu_sys_reg(vcpu, ICH_HCR_EL2) & ICH_HCR_EN;
 	state &= vgic_v3_get_misr(vcpu);
 
 	kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 39e5c68087ea..f8ed60563587 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -280,10 +280,11 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
 				     ICC_SRE_EL1_SRE);
 		/*
 		 * If nesting is allowed, force GICv3 onto the nested
-		 * guests as well.
+		 * guests as well by setting the shadow state to the
+		 * same value.
 		 */
 		if (vcpu_has_nv(vcpu))
-			vcpu->arch.vgic_cpu.nested_vgic_v3.vgic_sre = vgic_v3->vgic_sre;
+			vcpu->arch.vgic_cpu.shadow_vgic_v3.vgic_sre = vgic_v3->vgic_sre;
 		vcpu->arch.vgic_cpu.pendbaser = INITIAL_PENDBASER_VALUE;
 	} else {
 		vgic_v3->vgic_sre = 0;
@@ -715,11 +716,15 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
 	/*
-	 * vgic_v3_load_nested only affects the LRs in the shadow
-	 * state, so it is fine to pass the nested state around.
+	 * If the vgic is in nested state, populate the shadow state
+	 * from the guest's nested state. As vgic_v3_load_nested()
+	 * will only load LRs, let's deal with the rest of the state
+	 * here as if it was a non-nested state. Cunning.
 	 */
-	if (vgic_state_is_nested(vcpu))
-		cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+	if (vgic_state_is_nested(vcpu)) {
+		vgic_v3_create_shadow_state(vcpu);
+		cpu_if = &vcpu->arch.vgic_cpu.shadow_vgic_v3;
+	}
 
 	/*
 	 * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 3fd6c86a7ef3..ffdfe7bd9aea 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -323,4 +323,14 @@ void vgic_v4_teardown(struct kvm *kvm);
 void vgic_v4_configure_vsgis(struct kvm *kvm);
 void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
 
+void vgic_v3_sync_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_create_shadow_state(struct kvm_vcpu *vcpu);
+void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
+
+#define ICH_LRN(n)	(ICH_LR0_EL2 + (n))
+#define ICH_AP0RN(n)	(ICH_AP0R0_EL2 + (n))
+#define ICH_AP1RN(n)	(ICH_AP1R0_EL2 + (n))
+
 #endif
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index b44db6b013f5..43fef20f1671 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -330,9 +330,6 @@ struct vgic_cpu {
 
 	struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
 
-	/* CPU vif control registers for the virtual GICH interface */
-	struct vgic_v3_cpu_if	nested_vgic_v3;
-
 	/*
 	 * The shadow vif control register loaded to the hardware when
 	 * running a nested L2 guest with the virtual IMO/FMO bit set.
@@ -396,10 +393,6 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu);
 void kvm_vgic_put(struct kvm_vcpu *vcpu);
 void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu);
 
-void vgic_v3_sync_nested(struct kvm_vcpu *vcpu);
-void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
-void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
-void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
 u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu);
 u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu);
 u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:59 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:59 +0000
Subject: [PATCH v6 51/64] KVM: arm64: nv: Add nested GICv3 tracepoints
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-52-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Adding tracepoints to be able to peek into the shadow LRs used when
running a guest guest.

Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-nested-trace.h | 137 ++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3-nested.c    |  13 ++-
 2 files changed, 149 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/kvm/vgic/vgic-nested-trace.h

diff --git a/arch/arm64/kvm/vgic/vgic-nested-trace.h b/arch/arm64/kvm/vgic/vgic-nested-trace.h
new file mode 100644
index 000000000000..f1a074c791a6
--- /dev/null
+++ b/arch/arm64/kvm/vgic/vgic-nested-trace.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(_TRACE_VGIC_NESTED_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_VGIC_NESTED_H
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kvm
+
+#define SLR_ENTRY_VALS(x)							\
+	" ",									\
+	!!(__entry->lrs[x] & ICH_LR_HW),		   			\
+	!!(__entry->lrs[x] & ICH_LR_PENDING_BIT),	   			\
+	!!(__entry->lrs[x] & ICH_LR_ACTIVE_BIT),	   			\
+	__entry->lrs[x] & ICH_LR_VIRTUAL_ID_MASK,				\
+	(__entry->lrs[x] & ICH_LR_PHYS_ID_MASK) >> ICH_LR_PHYS_ID_SHIFT,	\
+	(__entry->orig_lrs[x] & ICH_LR_PHYS_ID_MASK) >> ICH_LR_PHYS_ID_SHIFT
+
+TRACE_EVENT(vgic_create_shadow_lrs,
+	TP_PROTO(struct kvm_vcpu *vcpu, int nr_lr, u64 *lrs, u64 *orig_lrs),
+	TP_ARGS(vcpu, nr_lr, lrs, orig_lrs),
+
+	TP_STRUCT__entry(
+		__field(	int,	nr_lr			)
+		__array(	u64,	lrs,		16	)
+		__array(	u64,	orig_lrs,	16	)
+	),
+
+	TP_fast_assign(
+		__entry->nr_lr		= nr_lr;
+		memcpy(__entry->lrs, lrs, 16 * sizeof(u64));
+		memcpy(__entry->orig_lrs, orig_lrs, 16 * sizeof(u64));
+	),
+
+	TP_printk("nr_lr: %d\n"
+		  "%50sLR[ 0]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 1]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 2]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 3]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 4]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 5]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 6]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 7]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 8]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[ 9]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[10]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[11]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[12]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[13]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[14]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)\n"
+		  "%50sLR[15]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu (%5llu)",
+		  __entry->nr_lr,
+		  SLR_ENTRY_VALS(0), SLR_ENTRY_VALS(1), SLR_ENTRY_VALS(2),
+		  SLR_ENTRY_VALS(3), SLR_ENTRY_VALS(4), SLR_ENTRY_VALS(5),
+		  SLR_ENTRY_VALS(6), SLR_ENTRY_VALS(7), SLR_ENTRY_VALS(8),
+		  SLR_ENTRY_VALS(9), SLR_ENTRY_VALS(10), SLR_ENTRY_VALS(11),
+		  SLR_ENTRY_VALS(12), SLR_ENTRY_VALS(13), SLR_ENTRY_VALS(14),
+		  SLR_ENTRY_VALS(15))
+);
+
+#define LR_ENTRY_VALS(x)							\
+	" ",									\
+	!!(__entry->lrs[x] & ICH_LR_HW),		   			\
+	!!(__entry->lrs[x] & ICH_LR_PENDING_BIT),	   			\
+	!!(__entry->lrs[x] & ICH_LR_ACTIVE_BIT),	   			\
+	__entry->lrs[x] & ICH_LR_VIRTUAL_ID_MASK,				\
+	(__entry->lrs[x] & ICH_LR_PHYS_ID_MASK) >> ICH_LR_PHYS_ID_SHIFT
+
+TRACE_EVENT(vgic_put_nested,
+	TP_PROTO(struct kvm_vcpu *vcpu, int nr_lr, u64 *lrs),
+	TP_ARGS(vcpu, nr_lr, lrs),
+
+	TP_STRUCT__entry(
+		__field(	int,	nr_lr			)
+		__array(	u64,	lrs,		16	)
+	),
+
+	TP_fast_assign(
+		__entry->nr_lr		= nr_lr;
+		memcpy(__entry->lrs, lrs, 16 * sizeof(u64));
+	),
+
+	TP_printk("nr_lr: %d\n"
+		  "%50sLR[ 0]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 1]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 2]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 3]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 4]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 5]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 6]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 7]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 8]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[ 9]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[10]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[11]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[12]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[13]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[14]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu\n"
+		  "%50sLR[15]: HW: %d P: %d: A: %d vINTID: %5llu pINTID: %5llu",
+		  __entry->nr_lr,
+		  LR_ENTRY_VALS(0), LR_ENTRY_VALS(1), LR_ENTRY_VALS(2),
+		  LR_ENTRY_VALS(3), LR_ENTRY_VALS(4), LR_ENTRY_VALS(5),
+		  LR_ENTRY_VALS(6), LR_ENTRY_VALS(7), LR_ENTRY_VALS(8),
+		  LR_ENTRY_VALS(9), LR_ENTRY_VALS(10), LR_ENTRY_VALS(11),
+		  LR_ENTRY_VALS(12), LR_ENTRY_VALS(13), LR_ENTRY_VALS(14),
+		  LR_ENTRY_VALS(15))
+);
+
+TRACE_EVENT(vgic_nested_hw_emulate,
+	TP_PROTO(int lr, u64 lr_val, u32 l1_intid),
+	TP_ARGS(lr, lr_val, l1_intid),
+
+	TP_STRUCT__entry(
+		__field(	int,	lr		)
+		__field(	u64,	lr_val		)
+		__field(	u32,	l1_intid	)
+	),
+
+	TP_fast_assign(
+		__entry->lr		= lr;
+		__entry->lr_val		= lr_val;
+		__entry->l1_intid	= l1_intid;
+	),
+
+	TP_printk("lr: %d LR %llx L1 INTID: %u\n",
+		  __entry->lr, __entry->lr_val, __entry->l1_intid)
+);
+
+#endif /* _TRACE_VGIC_NESTED_H */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH vgic/
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE vgic-nested-trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index 4a35c2be7984..02b0b335f72a 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -15,6 +15,9 @@
 
 #include "vgic.h"
 
+#define CREATE_TRACE_POINTS
+#include "vgic-nested-trace.h"
+
 static inline struct vgic_v3_cpu_if *vcpu_nested_if(struct kvm_vcpu *vcpu)
 {
 	return &vcpu->arch.vgic_cpu.nested_vgic_v3;
@@ -121,6 +124,9 @@ static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu)
 		used_lrs = i + 1;
 	}
 
+	trace_vgic_create_shadow_lrs(vcpu, kvm_vgic_global_state.nr_lr,
+				     s_cpu_if->vgic_lr, cpu_if->vgic_lr);
+
 	s_cpu_if->used_lrs = used_lrs;
 }
 
@@ -165,8 +171,10 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 			continue; /* oh well, the guest hyp is broken */
 
 		lr = __gic_v3_get_lr(i);
-		if (!(lr & ICH_LR_STATE))
+		if (!(lr & ICH_LR_STATE)) {
+			trace_vgic_nested_hw_emulate(i, lr, l1_irq);
 			irq->active = false;
+		}
 
 		vgic_put_irq(vcpu->kvm, irq);
 	}
@@ -197,6 +205,9 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 
 	__vgic_v3_save_state(vcpu_shadow_if(vcpu));
 
+	trace_vgic_put_nested(vcpu, kvm_vgic_global_state.nr_lr,
+			      vcpu_shadow_if(vcpu)->vgic_lr);
+
 	/*
 	 * Translate the shadow state HW fields back to the virtual ones
 	 * before copying the shadow struct back to the nested one.
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:53 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:53 +0000
Subject: [PATCH v6 45/64] KVM: arm64: nv: Load timer before the GIC
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-46-maz@kernel.org>

In order for vgic_v3_load_nested to be able to observe which timer
interrupts have the HW bit set for the current context, the timers
must have been loaded in the new mode and the right timer mapped
to their corresponding HW IRQs.

At the moment, we load the GIC first, meaning that timer interrupts
injected to an L2 guest will never have the HW bit set (we see the
old configuration).

Swapping the two loads solves this particular problem.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 14f85f1e15b2..6597cb8f64f9 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -400,8 +400,8 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 
 	vcpu->cpu = cpu;
 
-	kvm_vgic_load(vcpu);
 	kvm_timer_vcpu_load(vcpu);
+	kvm_vgic_load(vcpu);
 	if (has_vhe())
 		kvm_vcpu_load_sysregs_vhe(vcpu);
 	kvm_arch_vcpu_load_fp(vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:09 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:09 +0000
Subject: [PATCH v6 61/64] KVM: arm64: nv: Allocate VNCR page when required
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-62-maz@kernel.org>

If running a NV guest on an ARMv8.4-NV capable system, let's
allocate an additional page that will be used by the hypervisor
to fulfill system register accesses.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  3 ++-
 arch/arm64/kvm/nested.c           | 10 ++++++++++
 arch/arm64/kvm/reset.c            |  1 +
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 15bbe8ccdefa..5d69992106aa 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -568,7 +568,8 @@ struct kvm_vcpu_arch {
  */
 static inline u64 *__ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
 {
-	if (unlikely(r >= __VNCR_START__ && ctxt->vncr_array))
+	if (unlikely(cpus_have_final_cap(ARM64_HAS_ENHANCED_NESTED_VIRT) &&
+		     r >= __VNCR_START__ && ctxt->vncr_array))
 		return &ctxt->vncr_array[r - __VNCR_START__];
 
 	return (u64 *)&ctxt->sys_regs[r];
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 8e99690cdde1..bbdd4633e665 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -35,6 +35,14 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
 	if (!cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
 		return -EINVAL;
 
+	if (cpus_have_final_cap(ARM64_HAS_ENHANCED_NESTED_VIRT)) {
+		if (!vcpu->arch.ctxt.vncr_array)
+			vcpu->arch.ctxt.vncr_array = (u64 *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+
+		if (!vcpu->arch.ctxt.vncr_array)
+			return -ENOMEM;
+	}
+
 	mutex_lock(&kvm->lock);
 
 	/*
@@ -64,6 +72,8 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
 		    kvm_init_stage2_mmu(kvm, &tmp[num_mmus - 2])) {
 			kvm_free_stage2_pgd(&tmp[num_mmus - 1]);
 			kvm_free_stage2_pgd(&tmp[num_mmus - 2]);
+			free_page((unsigned long)vcpu->arch.ctxt.vncr_array);
+			vcpu->arch.ctxt.vncr_array = NULL;
 		} else {
 			kvm->arch.nested_mmus_size = num_mmus;
 			ret = 0;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index d19a9aad2d85..f59c00fb53cc 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -161,6 +161,7 @@ void kvm_arm_vcpu_destroy(struct kvm_vcpu *vcpu)
 	if (sve_state)
 		kvm_unshare_hyp(sve_state, sve_state + vcpu_sve_state_size(vcpu));
 	kfree(sve_state);
+	free_page((unsigned long)vcpu->arch.ctxt.vncr_array);
 }
 
 static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:10 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:10 +0000
Subject: [PATCH v6 62/64] KVM: arm64: nv: Enable ARMv8.4-NV support
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-63-maz@kernel.org>

As all the VNCR-capable system registers are nicely separated
from the rest of the crowd, let's set HCR_EL2.NV2 on and let
the ball rolling.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h     |  1 +
 arch/arm64/include/asm/kvm_emulate.h | 23 +++++++++++++----------
 arch/arm64/include/asm/sysreg.h      |  1 +
 arch/arm64/kvm/hyp/vhe/switch.c      | 14 +++++++++++++-
 4 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index aa3bdce1b166..19998cf067ce 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -20,6 +20,7 @@
 #define HCR_AMVOFFEN	(UL(1) << 51)
 #define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
+#define HCR_NV2		(UL(1) << 45)
 #define HCR_AT		(UL(1) << 44)
 #define HCR_NV1		(UL(1) << 43)
 #define HCR_NV		(UL(1) << 42)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index 2128d623a8b3..7c09d36fd593 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -245,21 +245,24 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
 
 static inline u64 __fixup_spsr_el2_write(struct kvm_cpu_context *ctxt, u64 val)
 {
-	if (!__vcpu_el2_e2h_is_set(ctxt)) {
-		/*
-		 * Clear the .M field when writing SPSR to the CPU, so that we
-		 * can detect when the CPU clobbered our SPSR copy during a
-		 * local exception.
-		 */
-		val &= ~0xc;
-	}
+	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
+
+	if (vcpu_has_nv2(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
+		return val;
 
-	return val;
+	/*
+	 * Clear the .M field when writing SPSR to the CPU, so that we
+	 * can detect when the CPU clobbered our SPSR copy during a
+	 * local exception.
+	 */
+	return val &= ~0xc;
 }
 
 static inline u64 __fixup_spsr_el2_read(const struct kvm_cpu_context *ctxt, u64 val)
 {
-	if (__vcpu_el2_e2h_is_set(ctxt))
+	struct kvm_vcpu *vcpu = container_of(ctxt, struct kvm_vcpu, arch.ctxt);
+
+	if (vcpu_has_nv2(vcpu) || __vcpu_el2_e2h_is_set(ctxt))
 		return val;
 
 	/*
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ff6d3af8ed34..0a21be5263d9 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -551,6 +551,7 @@
 #define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
 #define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
 #define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)
+#define SYS_VNCR_EL2			sys_reg(3, 4, 2, 2, 0)
 
 #define SYS_ZCR_EL2			sys_reg(3, 4, 1, 2, 0)
 #define SYS_TRFCR_EL2			sys_reg(3, 4, 1, 2, 1)
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 5e8eafac27c6..65120c9027d6 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -44,7 +44,13 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 			 * the EL1 virtual memory control register accesses
 			 * as well as the AT S1 operations.
 			 */
-			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_TTLB | HCR_NV1;
+			if (vcpu_has_nv2(vcpu)) {
+				hcr &= ~HCR_TVM;
+			} else {
+				hcr |= HCR_TVM | HCR_TRVM | HCR_TTLB;
+			}
+
+			hcr |= HCR_AT | HCR_NV1;
 		} else {
 			/*
 			 * For a guest hypervisor on v8.1 (VHE), allow to
@@ -78,6 +84,12 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 			if (!vcpu_el2_tge_is_set(vcpu))
 				hcr |= HCR_AT | HCR_TTLB;
 		}
+
+		if (vcpu_has_nv2(vcpu)) {
+			hcr |= HCR_AT | HCR_TTLB | HCR_NV2;
+			write_sysreg_s(vcpu->arch.ctxt.vncr_array,
+				       SYS_VNCR_EL2);
+		}
 	} else if (vcpu_has_nv(vcpu)) {
 		u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:08 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:08 +0000
Subject: [PATCH v6 60/64] KVM: arm64: nv: Sync nested timer state with ARMv8.4
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-61-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Emulating the ARMv8.4-NV timers is a bit odd, as the timers can
be reconfigured behind our back without the hypervisor even
noticing. In the VHE case, that's an actual regression in the
architecture...

Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/arch_timer.c  | 37 ++++++++++++++++++++++++++++++++++++
 arch/arm64/kvm/arm.c         |  3 +++
 include/kvm/arm_arch_timer.h |  1 +
 3 files changed, 41 insertions(+)

diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 5e4f93605d36..2371796b1ab5 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -785,6 +785,43 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
 	set_cntvoff(0);
 }
 
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
+{
+	if (!is_hyp_ctxt(vcpu))
+		return;
+
+	/*
+	 * Guest hypervisors using ARMv8.4 enhanced nested virt support have
+	 * their EL1 timer register accesses redirected to the VNCR page.
+	 */
+	if (!vcpu_el2_e2h_is_set(vcpu)) {
+		/*
+		 * For a non-VHE guest hypervisor, we update the hardware
+		 * timer registers with the latest value written by the guest
+		 * to the VNCR page and let the hardware take care of the
+		 * rest.
+		 */
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CTL_EL0),  SYS_CNTV_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0), SYS_CNTV_CVAL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CTL_EL0),  SYS_CNTP_CTL);
+		write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0), SYS_CNTP_CVAL);
+	} else {
+		/*
+		 * For a VHE guest hypervisor, the emulated state (which
+		 * is stored in the VNCR page) could have been updated behind
+		 * our back, and we must reset the emulation of the timers.
+		 */
+
+		struct timer_map map;
+		get_timer_map(vcpu, &map);
+
+		soft_timer_cancel(&map.emul_vtimer->hrtimer);
+		soft_timer_cancel(&map.emul_ptimer->hrtimer);
+		timer_emulate(map.emul_vtimer);
+		timer_emulate(map.emul_ptimer);
+	}
+}
+
 /*
  * With a userspace irqchip we have to check if the guest de-asserted the
  * timer and if so, unmask the timer irq signal on the host interrupt
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index ac7d89c1e987..4c47a66eac8c 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -936,6 +936,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (static_branch_unlikely(&userspace_irqchip_in_use))
 			kvm_timer_sync_user(vcpu);
 
+		if (vcpu_has_nv2(vcpu))
+			kvm_timer_sync_nested(vcpu);
+
 		kvm_arch_vcpu_ctxsync_fp(vcpu);
 
 		/*
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 0a76dac8cb6a..89b08e5b456e 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -68,6 +68,7 @@ int kvm_timer_hyp_init(bool);
 int kvm_timer_enable(struct kvm_vcpu *vcpu);
 int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
 void kvm_timer_update_run(struct kvm_vcpu *vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:48 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:48 +0000
Subject: [PATCH v6 40/64] KVM: arm64: nv: Trap and emulate AT instructions
 from virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-41-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

When supporting nested virtualization a guest hypervisor executing AT
instructions must be trapped and emulated by the host hypervisor,
because untrapped AT instructions operating on S1E1 will use the wrong
translation regieme (the one used to emulate virtual EL2 in EL1 instead
of virtual EL1) and AT instructions operating on S12 will not work from
EL1.

This patch does several things.

1. List and define all AT system instructions to emulate and document
the emulation design.

2. Implement AT instruction handling logic in EL2. This will be used to
emulate AT instructions executed in the virtual EL2.

AT instruction emulation works by loading the proper processor
context, which depends on the trapped instruction and the virtual
HCR_EL2, to the EL1 virtual memory control registers and executing AT
instructions. Note that ctxt->hw_sys_regs is expected to have the
proper processor context before calling the handling
function(__kvm_at_insn) implemented in this patch.

4. Emulate AT S1E[01] instructions by issuing the same instructions in
EL2. We set the physical EL1 registers, NV and NV1 bits as described in
the AT instruction emulation overview.

5. Emulate AT A12E[01] instructions in two steps: First, do the stage-1
translation by reusing the existing AT emulation functions.  Second, do
the stage-2 translation by walking the guest hypervisor's stage-2 page
table in software. Record the translation result to PAR_EL1.

6. Emulate AT S1E2 instructions by issuing the corresponding S1E1
instructions in EL2. We set the physical EL1 registers and the HCR_EL2
register as described in the AT instruction emulation overview.

7. Forward system instruction traps to the virtual EL2 if the corresponding
virtual AT bit is set in the virtual HCR_EL2.

  [ Much logic above has been reworked by Marc Zyngier ]

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
---
 arch/arm64/include/asm/kvm_arm.h |   2 +
 arch/arm64/include/asm/kvm_asm.h |   2 +
 arch/arm64/include/asm/sysreg.h  |  17 +++
 arch/arm64/kvm/Makefile          |   2 +-
 arch/arm64/kvm/at.c              | 219 +++++++++++++++++++++++++++++
 arch/arm64/kvm/hyp/vhe/switch.c  |  13 +-
 arch/arm64/kvm/sys_regs.c        | 229 ++++++++++++++++++++++++++++++-
 7 files changed, 478 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm64/kvm/at.c

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 3675879b53c6..aa3bdce1b166 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -20,6 +20,7 @@
 #define HCR_AMVOFFEN	(UL(1) << 51)
 #define HCR_FIEN	(UL(1) << 47)
 #define HCR_FWB		(UL(1) << 46)
+#define HCR_AT		(UL(1) << 44)
 #define HCR_NV1		(UL(1) << 43)
 #define HCR_NV		(UL(1) << 42)
 #define HCR_API		(UL(1) << 41)
@@ -118,6 +119,7 @@
 #define VTCR_EL2_TG0_16K	TCR_TG0_16K
 #define VTCR_EL2_TG0_64K	TCR_TG0_64K
 #define VTCR_EL2_SH0_MASK	TCR_SH0_MASK
+#define VTCR_EL2_SH0_SHIFT	TCR_SH0_SHIFT
 #define VTCR_EL2_SH0_INNER	TCR_SH0_INNER
 #define VTCR_EL2_ORGN0_MASK	TCR_ORGN0_MASK
 #define VTCR_EL2_ORGN0_WBWA	TCR_ORGN0_WBWA
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index d5b0386ef765..e22861ece3c3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -208,6 +208,8 @@ extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
 extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
 
 extern void __kvm_timer_set_cntvoff(u64 cntvoff);
+extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
+extern void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
 
 extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 61c990e5591a..ea17d1eabfc5 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -658,6 +658,23 @@
 
 #define SYS_SP_EL2			sys_reg(3, 6,  4, 1, 0)
 
+/* AT instructions */
+#define AT_Op0 1
+#define AT_CRn 7
+
+#define OP_AT_S1E1R	sys_insn(AT_Op0, 0, AT_CRn, 8, 0)
+#define OP_AT_S1E1W	sys_insn(AT_Op0, 0, AT_CRn, 8, 1)
+#define OP_AT_S1E0R	sys_insn(AT_Op0, 0, AT_CRn, 8, 2)
+#define OP_AT_S1E0W	sys_insn(AT_Op0, 0, AT_CRn, 8, 3)
+#define OP_AT_S1E1RP	sys_insn(AT_Op0, 0, AT_CRn, 9, 0)
+#define OP_AT_S1E1WP	sys_insn(AT_Op0, 0, AT_CRn, 9, 1)
+#define OP_AT_S1E2R	sys_insn(AT_Op0, 4, AT_CRn, 8, 0)
+#define OP_AT_S1E2W	sys_insn(AT_Op0, 4, AT_CRn, 8, 1)
+#define OP_AT_S12E1R	sys_insn(AT_Op0, 4, AT_CRn, 8, 4)
+#define OP_AT_S12E1W	sys_insn(AT_Op0, 4, AT_CRn, 8, 5)
+#define OP_AT_S12E0R	sys_insn(AT_Op0, 4, AT_CRn, 8, 6)
+#define OP_AT_S12E0W	sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index dbaf42ff65f1..b800dcbd157f 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -14,7 +14,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 inject_fault.o va_layout.o handle_exit.o \
 	 guest.o debug.o reset.o sys_regs.o \
 	 vgic-sys-reg-v3.o fpsimd.o pmu.o pkvm.o \
-	 arch_timer.o trng.o emulate-nested.o nested.o \
+	 arch_timer.o trng.o emulate-nested.o nested.o at.o \
 	 vgic/vgic.o vgic/vgic-init.o \
 	 vgic/vgic-irqfd.o vgic/vgic-v2.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c
new file mode 100644
index 000000000000..574c664e984b
--- /dev/null
+++ b/arch/arm64/kvm/at.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 - Linaro Ltd
+ * Author: Jintack Lim <jintack.lim at linaro.org>
+ */
+
+#include <asm/kvm_hyp.h>
+#include <asm/kvm_mmu.h>
+
+struct mmu_config {
+	u64	ttbr0;
+	u64	ttbr1;
+	u64	tcr;
+	u64	sctlr;
+	u64	vttbr;
+	u64	vtcr;
+	u64	hcr;
+};
+
+static void __mmu_config_save(struct mmu_config *config)
+{
+	config->ttbr0	= read_sysreg_el1(SYS_TTBR0);
+	config->ttbr1	= read_sysreg_el1(SYS_TTBR1);
+	config->tcr	= read_sysreg_el1(SYS_TCR);
+	config->sctlr	= read_sysreg_el1(SYS_SCTLR);
+	config->vttbr	= read_sysreg(vttbr_el2);
+	config->vtcr	= read_sysreg(vtcr_el2);
+	config->hcr	= read_sysreg(hcr_el2);
+}
+
+static void __mmu_config_restore(struct mmu_config *config)
+{
+	write_sysreg_el1(config->ttbr0,	SYS_TTBR0);
+	write_sysreg_el1(config->ttbr1,	SYS_TTBR1);
+	write_sysreg_el1(config->tcr,	SYS_TCR);
+	write_sysreg_el1(config->sctlr,	SYS_SCTLR);
+	write_sysreg(config->vttbr,	vttbr_el2);
+	write_sysreg(config->vtcr,	vtcr_el2);
+	write_sysreg(config->hcr,	hcr_el2);
+
+	isb();
+}
+
+void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
+{
+	struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+	struct mmu_config config;
+	struct kvm_s2_mmu *mmu;
+
+	spin_lock(&vcpu->kvm->mmu_lock);
+
+	/*
+	 * If HCR_EL2.{E2H,TGE} == {1,1}, the MMU context is already
+	 * the right one (as we trapped from vEL2).
+	 */
+	if (vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu))
+		goto skip_mmu_switch;
+
+	/*
+	 * FIXME: Obtaining the S2 MMU for a guest guest is horribly
+	 * racy, and we may not find it (evicted by another vcpu, for
+	 * example).
+	 */
+	mmu = lookup_s2_mmu(vcpu->kvm,
+			    vcpu_read_sys_reg(vcpu, VTTBR_EL2),
+			    vcpu_read_sys_reg(vcpu, HCR_EL2));
+
+	if (WARN_ON(!mmu))
+		goto out;
+
+	/* We've trapped, so everything is live on the CPU. */
+	__mmu_config_save(&config);
+
+	write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL1),	SYS_TTBR0);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL1),	SYS_TTBR1);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, TCR_EL1),	SYS_TCR);
+	write_sysreg_el1(ctxt_sys_reg(ctxt, SCTLR_EL1),	SYS_SCTLR);
+	write_sysreg(kvm_get_vttbr(mmu),		vttbr_el2);
+	/*
+	 * REVISIT: do we need anything from the guest's VTCR_EL2? If
+	 * looks like keeping the hosts configuration is the right
+	 * thing to do at this stage (and we could avoid save/restore
+	 * it. Keep the host's version for now.
+	 */
+	write_sysreg((config.hcr & ~HCR_TGE) | HCR_VM,	hcr_el2);
+
+	isb();
+
+skip_mmu_switch:
+
+	switch (op) {
+	case OP_AT_S1E1R:
+	case OP_AT_S1E1RP:
+		asm volatile("at s1e1r, %0" : : "r" (vaddr));
+		break;
+	case OP_AT_S1E1W:
+	case OP_AT_S1E1WP:
+		asm volatile("at s1e1w, %0" : : "r" (vaddr));
+		break;
+	case OP_AT_S1E0R:
+		asm volatile("at s1e0r, %0" : : "r" (vaddr));
+		break;
+	case OP_AT_S1E0W:
+		asm volatile("at s1e0w, %0" : : "r" (vaddr));
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		break;
+	}
+
+	isb();
+
+	ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg(par_el1);
+
+	/*
+	 * Failed? let's leave the building now.
+	 *
+	 * FIXME: how about a failed translation because the shadow S2
+	 * wasn't populated? We may need to perform a SW PTW,
+	 * populating our shadow S2 and retry the instruction.
+	 */
+	if (ctxt_sys_reg(ctxt, PAR_EL1) & 1)
+		goto nopan;
+
+	/* No PAN? No problem. */
+	if (!(*vcpu_cpsr(vcpu) & PSR_PAN_BIT))
+		goto nopan;
+
+	/*
+	 * For PAN-involved AT operations, perform the same
+	 * translation, using EL0 this time.
+	 */
+	switch (op) {
+	case OP_AT_S1E1RP:
+		asm volatile("at s1e0r, %0" : : "r" (vaddr));
+		break;
+	case OP_AT_S1E1WP:
+		asm volatile("at s1e0w, %0" : : "r" (vaddr));
+		break;
+	default:
+		goto nopan;
+	}
+
+	/*
+	 * If the EL0 translation has succeeded, we need to pretend
+	 * the AT operation has failed, as the PAN setting forbids
+	 * such a translation.
+	 *
+	 * FIXME: we hardcode a Level-3 permission fault. We really
+	 * should return the real fault level.
+	 */
+	if (!(read_sysreg(par_el1) & 1))
+		ctxt_sys_reg(ctxt, PAR_EL1) = 0x1f;
+
+nopan:
+	if (!(vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)))
+		__mmu_config_restore(&config);
+
+out:
+	spin_unlock(&vcpu->kvm->mmu_lock);
+}
+
+void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr)
+{
+	struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+	struct mmu_config config;
+	struct kvm_s2_mmu *mmu;
+	u64 val;
+
+	spin_lock(&vcpu->kvm->mmu_lock);
+
+	mmu = &vcpu->kvm->arch.mmu;
+
+	/* We've trapped, so everything is live on the CPU. */
+	__mmu_config_save(&config);
+
+	if (vcpu_el2_e2h_is_set(vcpu)) {
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL2),	SYS_TTBR0);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR1_EL2),	SYS_TTBR1);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TCR_EL2),	SYS_TCR);
+		write_sysreg_el1(ctxt_sys_reg(ctxt, SCTLR_EL2),	SYS_SCTLR);
+
+		val = config.hcr;
+	} else {
+		write_sysreg_el1(ctxt_sys_reg(ctxt, TTBR0_EL2),	SYS_TTBR0);
+		val = translate_tcr_el2_to_tcr_el1(ctxt_sys_reg(ctxt, TCR_EL2));
+		write_sysreg_el1(val, SYS_TCR);
+		val = translate_sctlr_el2_to_sctlr_el1(ctxt_sys_reg(ctxt, SCTLR_EL2));
+		write_sysreg_el1(val, SYS_SCTLR);
+
+		val = config.hcr | HCR_NV | HCR_NV1;
+	}
+
+	write_sysreg(kvm_get_vttbr(mmu),		vttbr_el2);
+	/* FIXME: write S2 MMU VTCR_EL2? */
+	write_sysreg((val & ~HCR_TGE) | HCR_VM,		hcr_el2);
+
+	isb();
+
+	switch (op) {
+	case OP_AT_S1E2R:
+		asm volatile("at s1e1r, %0" : : "r" (vaddr));
+		break;
+	case OP_AT_S1E2W:
+		asm volatile("at s1e1w, %0" : : "r" (vaddr));
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		break;
+	}
+
+	isb();
+
+	/* FIXME: handle failed translation due to shadow S2 */
+	ctxt_sys_reg(ctxt, PAR_EL1) = read_sysreg(par_el1);
+
+	__mmu_config_restore(&config);
+	spin_unlock(&vcpu->kvm->mmu_lock);
+}
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 28845f907cfc..b7790d3c4122 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -41,9 +41,10 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 		if (!vcpu_el2_e2h_is_set(vcpu)) {
 			/*
 			 * For a guest hypervisor on v8.0, trap and emulate
-			 * the EL1 virtual memory control register accesses.
+			 * the EL1 virtual memory control register accesses
+			 * as well as the AT S1 operations.
 			 */
-			hcr |= HCR_TVM | HCR_TRVM | HCR_NV1;
+			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_NV1;
 		} else {
 			/*
 			 * For a guest hypervisor on v8.1 (VHE), allow to
@@ -68,6 +69,14 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 			hcr &= ~HCR_TVM;
 
 			hcr |= vhcr_el2 & (HCR_TVM | HCR_TRVM);
+
+			/*
+			 * If we're using the EL1 translation regime
+			 * (TGE clear), then ensure that AT S1 ops are
+			 * trapped too.
+			 */
+			if (!vcpu_el2_tge_is_set(vcpu))
+				hcr |= HCR_AT;
 		}
 	}
 
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f669618f966b..7be57e1b7019 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1704,7 +1704,6 @@ static bool access_sp_el1(struct kvm_vcpu *vcpu,
 	return true;
 }
 
-
 static bool access_elr(struct kvm_vcpu *vcpu,
 		       struct sys_reg_params *p,
 		       const struct sys_reg_desc *r)
@@ -2236,12 +2235,236 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
-#define SYS_INSN_TO_DESC(insn, access_fn, forward_fn)	\
-	{ SYS_DESC((insn)), (access_fn), NULL, 0, 0, NULL, NULL, (forward_fn) }
+static bool handle_s1e01(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			 const struct sys_reg_desc *r)
+{
+	int sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+
+	if (vcpu_has_nv(vcpu) && forward_traps(vcpu, HCR_AT))
+		return false;
+
+	__kvm_at_s1e01(vcpu, sys_encoding, p->regval);
+
+	return true;
+}
+
+static bool handle_s1e2(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			const struct sys_reg_desc *r)
+{
+	int sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	__kvm_at_s1e2(vcpu, sys_encoding, p->regval);
+
+	return true;
+}
+
+static u64 setup_par_aborted(u32 esr)
+{
+	u64 par = 0;
+
+	/* S [9]: fault in the stage 2 translation */
+	par |= (1 << 9);
+	/* FST [6:1]: Fault status code  */
+	par |= (esr << 1);
+	/* F [0]: translation is aborted */
+	par |= 1;
+
+	return par;
+}
+
+static u64 setup_par_completed(struct kvm_vcpu *vcpu, struct kvm_s2_trans *out)
+{
+	u64 par, vtcr_sh0;
+
+	/* F [0]: Translation is completed successfully */
+	par = 0;
+	/* ATTR [63:56] */
+	par |= out->upper_attr;
+	/* PA [47:12] */
+	par |= out->output & GENMASK_ULL(11, 0);
+	/* RES1 [11] */
+	par |= (1UL << 11);
+	/* SH [8:7]: Shareability attribute */
+	vtcr_sh0 = vcpu_read_sys_reg(vcpu, VTCR_EL2) & VTCR_EL2_SH0_MASK;
+	par |= (vtcr_sh0 >> VTCR_EL2_SH0_SHIFT) << 7;
+
+	return par;
+}
+
+static bool handle_s12(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+		       const struct sys_reg_desc *r, bool write)
+{
+	u64 par, va;
+	u32 esr, op;
+	phys_addr_t ipa;
+	struct kvm_s2_trans out;
+	int ret;
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	/* Do the stage-1 translation */
+	va = p->regval;
+	op = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+	switch (op) {
+	case OP_AT_S12E1R:
+		op = OP_AT_S1E1R;
+		break;
+	case OP_AT_S12E1W:
+		op = OP_AT_S1E1W;
+		break;
+	case OP_AT_S12E0R:
+		op = OP_AT_S1E0R;
+		break;
+	case OP_AT_S12E0W:
+		op = OP_AT_S1E0W;
+		break;
+	default:
+		WARN_ON_ONCE(1);
+		return true;
+	}
+
+	__kvm_at_s1e01(vcpu, op, va);
+	par = vcpu_read_sys_reg(vcpu, PAR_EL1);
+	if (par & 1) {
+		/* The stage-1 translation aborted */
+		return true;
+	}
+
+	/* Do the stage-2 translation */
+	ipa = (par & GENMASK_ULL(47, 12)) | (va & GENMASK_ULL(11, 0));
+	out.esr = 0;
+	ret = kvm_walk_nested_s2(vcpu, ipa, &out);
+	if (ret < 0)
+		return false;
+
+	/* Check if the stage-2 PTW is aborted */
+	if (out.esr) {
+		esr = out.esr;
+		goto s2_trans_abort;
+	}
+
+	/* Check the access permission */
+	if ((!write && !out.readable) || (write && !out.writable)) {
+		esr = ESR_ELx_FSC_PERM;
+		esr |= out.level & 0x3;
+		goto s2_trans_abort;
+	}
+
+	vcpu_write_sys_reg(vcpu, setup_par_completed(vcpu, &out), PAR_EL1);
+	return true;
+
+s2_trans_abort:
+	vcpu_write_sys_reg(vcpu, setup_par_aborted(esr), PAR_EL1);
+	return true;
+}
+
+static bool handle_s12r(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			const struct sys_reg_desc *r)
+{
+	return handle_s12(vcpu, p, r, false);
+}
+
+static bool handle_s12w(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			const struct sys_reg_desc *r)
+{
+	return handle_s12(vcpu, p, r, true);
+}
+
+/*
+ * AT instruction emulation
+ *
+ * We emulate AT instructions executed in the virtual EL2.
+ * Basic strategy for the stage-1 translation emulation is to load proper
+ * context, which depends on the trapped instruction and the virtual HCR_EL2,
+ * to the EL1 virtual memory control registers and execute S1E[01] instructions
+ * in EL2. See below for more detail.
+ *
+ * For the stage-2 translation, which is necessary for S12E[01] emulation,
+ * we walk the guest hypervisor's stage-2 page table in software.
+ *
+ * The stage-1 translation emulations can be divided into two groups depending
+ * on the translation regime.
+ *
+ * 1. EL2 AT instructions: S1E2x
+ * +-----------------------------------------------------------------------+
+ * |                             |         Setting for the emulation       |
+ * | Virtual HCR_EL2.E2H on trap |-----------------------------------------+
+ * |                             | Phys EL1 regs | Phys NV, NV1 | Phys TGE |
+ * |-----------------------------------------------------------------------|
+ * |             0               |     vEL2      |    (1, 1)    |    0     |
+ * |             1               |     vEL2      |    (0, 0)    |    0     |
+ * +-----------------------------------------------------------------------+
+ *
+ * We emulate the EL2 AT instructions by loading virtual EL2 context
+ * to the EL1 virtual memory control registers and executing corresponding
+ * EL1 AT instructions.
+ *
+ * We set physical NV and NV1 bits to use EL2 page table format for non-VHE
+ * guest hypervisor (i.e. HCR_EL2.E2H == 0). As a VHE guest hypervisor uses the
+ * EL1 page table format, we don't set those bits.
+ *
+ * We should clear physical TGE bit not to use the EL2 translation regime when
+ * the host uses the VHE feature.
+ *
+ *
+ * 2. EL0/EL1 AT instructions: S1E[01]x, S12E1x
+ * +----------------------------------------------------------------------+
+ * |   Virtual HCR_EL2 on trap  |        Setting for the emulation        |
+ * |----------------------------------------------------------------------+
+ * | (vE2H, vTGE) | (vNV, vNV1) | Phys EL1 regs | Phys NV, NV1 | Phys TGE |
+ * |----------------------------------------------------------------------|
+ * |    (0, 0)*   |   (0, 0)    |      vEL1     |    (0, 0)    |    0     |
+ * |    (0, 0)    |   (1, 1)    |      vEL1     |    (1, 1)    |    0     |
+ * |    (1, 1)    |   (0, 0)    |      vEL2     |    (0, 0)    |    0     |
+ * |    (1, 1)    |   (1, 1)    |      vEL2     |    (1, 1)    |    0     |
+ * +----------------------------------------------------------------------+
+ *
+ * *For (0, 0) in the 'Virtual HCR_EL2 on trap' column, it actually means
+ *  (1, 1). Keep them (0, 0) just for the readability.
+ *
+ * We set physical EL1 virtual memory control registers depending on
+ * (vE2H, vTGE) pair. When the pair is (0, 0) where AT instructions are
+ * supposed to use EL0/EL1 translation regime, we load the EL1 registers with
+ * the virtual EL1 registers (i.e. EL1 registers from the guest hypervisor's
+ * point of view). When the pair is (1, 1), however, AT instructions are defined
+ * to apply EL2 translation regime. To emulate this behavior, we load the EL1
+ * registers with the virtual EL2 context. (i.e the shadow registers)
+ *
+ * We respect the virtual NV and NV1 bit for the emulation. When those bits are
+ * set, it means that a guest hypervisor would like to use EL2 page table format
+ * for the EL1 translation regime. We emulate this by setting the physical
+ * NV and NV1 bits.
+ */
+
+#define SYS_INSN(insn, access_fn)					\
+	{								\
+		SYS_DESC(OP_##insn),					\
+		.access = (access_fn),					\
+	}
+
 static struct sys_reg_desc sys_insn_descs[] = {
 	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
+
+	SYS_INSN(AT_S1E1R, handle_s1e01),
+	SYS_INSN(AT_S1E1W, handle_s1e01),
+	SYS_INSN(AT_S1E0R, handle_s1e01),
+	SYS_INSN(AT_S1E0W, handle_s1e01),
+	SYS_INSN(AT_S1E1RP, handle_s1e01),
+	SYS_INSN(AT_S1E1WP, handle_s1e01),
+
 	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
 	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
+
+	SYS_INSN(AT_S1E2R, handle_s1e2),
+	SYS_INSN(AT_S1E2W, handle_s1e2),
+	SYS_INSN(AT_S12E1R, handle_s12r),
+	SYS_INSN(AT_S12E1W, handle_s12w),
+	SYS_INSN(AT_S12E0R, handle_s12r),
+	SYS_INSN(AT_S12E0W, handle_s12w),
 };
 
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:01 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:01 +0000
Subject: [PATCH v6 53/64] KVM: arm64: nv: Add handling of ARMv8.4-TTL TLB
 invalidation
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-54-maz@kernel.org>

Support guest-provided information information to find out about
the range of required invalidation.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  1 +
 arch/arm64/kvm/nested.c             | 57 +++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c           | 78 ++++++++++++++++++-----------
 3 files changed, 108 insertions(+), 28 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 3eef5f60c76d..8bfbeca2f4cd 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -128,6 +128,7 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
 extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
 extern bool forward_nv1_traps(struct kvm_vcpu *vcpu);
+unsigned int ttl_to_size(u8 ttl);
 
 struct sys_reg_params;
 struct sys_reg_desc;
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 39c9b1033f02..7e4ff98c4e95 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -351,6 +351,63 @@ int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
 	return ret;
 }
 
+
+unsigned int ttl_to_size(u8 ttl)
+{
+	int level = ttl & 3;
+	int gran = (ttl >> 2) & 3;
+	unsigned int max_size = 0;
+
+	switch (gran) {
+	case TLBI_TTL_TG_4K:
+		switch (level) {
+		case 0:
+			break;
+		case 1:
+			max_size = SZ_1G;
+			break;
+		case 2:
+			max_size = SZ_2M;
+			break;
+		case 3:
+			max_size = SZ_4K;
+			break;
+		}
+		break;
+	case TLBI_TTL_TG_16K:
+		switch (level) {
+		case 0:
+		case 1:
+			break;
+		case 2:
+			max_size = SZ_32M;
+			break;
+		case 3:
+			max_size = SZ_16K;
+			break;
+		}
+		break;
+	case TLBI_TTL_TG_64K:
+		switch (level) {
+		case 0:
+		case 1:
+			/* No 52bit IPA support */
+			break;
+		case 2:
+			max_size = SZ_512M;
+			break;
+		case 3:
+			max_size = SZ_64K;
+			break;
+		}
+		break;
+	default:			/* No size information */
+		break;
+	}
+
+	return max_size;
+}
+
 /* Must be called with kvm->lock held */
 struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
 {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index a18d845bcff7..ebe6fad76b4b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2731,14 +2731,54 @@ static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	return true;
 }
 
+static unsigned long compute_tlb_inval_range(struct kvm_vcpu *vcpu,
+					     struct kvm_s2_mmu *mmu,
+					     u64 val)
+{
+	unsigned long max_size;
+	u8 ttl = 0;
+
+	if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL)) {
+		ttl = FIELD_GET(GENMASK_ULL(47, 44), val);
+	}
+
+	max_size = ttl_to_size(ttl);
+
+	if (!max_size) {
+		u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+
+		/* Compute the maximum extent of the invalidation */
+		switch ((vtcr & VTCR_EL2_TG0_MASK)) {
+		case VTCR_EL2_TG0_4K:
+			max_size = SZ_1G;
+			break;
+		case VTCR_EL2_TG0_16K:
+			max_size = SZ_32M;
+			break;
+		case VTCR_EL2_TG0_64K:
+			/*
+			 * No, we do not support 52bit IPA in nested yet. Once
+			 * we do, this should be 4TB.
+			 */
+			/* FIXME: remove the 52bit PA support from the IDregs */
+			max_size = SZ_512M;
+			break;
+		default:
+			BUG();
+		}
+	}
+
+	WARN_ON(!max_size);
+	return max_size;
+}
+
 static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			     const struct sys_reg_desc *r)
 {
 	u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
-	u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
 	struct kvm_s2_mmu *mmu;
 	u64 base_addr;
-	int max_size;
+	unsigned long max_size;
 
 	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
 		return false;
@@ -2748,45 +2788,27 @@ static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	 *
 	 * - NS bit: we're non-secure only.
 	 *
-	 * - TTL field: We already have the granule size from the
-	 *   VTCR_EL2.TG0 field, and the level is only relevant to the
-	 *   guest's S2PT.
-	 *
 	 * - IPA[51:48]: We don't support 52bit IPA just yet...
 	 *
 	 * And of course, adjust the IPA to be on an actual address.
 	 */
 	base_addr = (p->regval & GENMASK_ULL(35, 0)) << 12;
 
-	/* Compute the maximum extent of the invalidation */
-	switch ((vtcr & VTCR_EL2_TG0_MASK)) {
-	case VTCR_EL2_TG0_4K:
-		max_size = SZ_1G;
-		break;
-	case VTCR_EL2_TG0_16K:
-		max_size = SZ_32M;
-		break;
-	case VTCR_EL2_TG0_64K:
-		/*
-		 * No, we do not support 52bit IPA in nested yet. Once
-		 * we do, this should be 4TB.
-		 */
-		/* FIXME: remove the 52bit PA support from the IDregs */
-		max_size = SZ_512M;
-		break;
-	default:
-		BUG();
-	}
-
 	spin_lock(&vcpu->kvm->mmu_lock);
 
 	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, HCR_VM);
-	if (mmu)
+	if (mmu) {
+		max_size = compute_tlb_inval_range(vcpu, mmu, p->regval);
+		base_addr &= ~(max_size - 1);
 		kvm_unmap_stage2_range(mmu, base_addr, max_size);
+	}
 
 	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, 0);
-	if (mmu)
+	if (mmu) {
+		max_size = compute_tlb_inval_range(vcpu, mmu, p->regval);
+		base_addr &= ~(max_size - 1);
 		kvm_unmap_stage2_range(mmu, base_addr, max_size);
+	}
 
 	spin_unlock(&vcpu->kvm->mmu_lock);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:12 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:12 +0000
Subject: [PATCH v6 64/64] KVM: arm64: nv: Fast-track EL1 TLBIs for VHE guests
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-65-maz@kernel.org>

Due to the way ARMv8.4-NV suppresses traps when accessing EL2
system registers, we can't track when the guest changes its
HCR_EL2.TGE setting. This means we always trap EL1 TLBIs,
even if they don't affect any guest.

This obviously has a huge impact on performance, as we handle
TLBI traps as a normal exit, and a normal VHE host issues
thousands of TLBIs when booting (and quite a few when running
userspace).

A cheap way to reduce the overhead is to handle the limited
case of {E2H,TGE}=={1,1} as a guest fixup, as we already have
the right mmu configuration in place. Just execute the decoded
instruction right away and return to the guest.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 43 ++++++++++++++++++++++++++++++++-
 arch/arm64/kvm/hyp/vhe/tlb.c    |  6 +++--
 arch/arm64/kvm/sys_regs.c       | 25 ++++++-------------
 3 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index f469bf51b4be..686b37579d3b 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -161,6 +161,47 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
 	__deactivate_traps_common(vcpu);
 }
 
+static bool kvm_hyp_handle_tlbi_el1(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	u32 instr;
+	u64 val;
+
+	/*
+	 * Ideally, we would never trap on EL1 TLB invalidations when the
+	 * guest's HCR_EL2.{E2H,TGE} == {1,1}. But "thanks" to ARMv8.4, we
+	 * don't trap writes to HCR_EL2, meaning that we can't track
+	 * changes to the virtual TGE bit. So we leave HCR_EL2.TTLB set on
+	 * the host. Oopsie...
+	 *
+	 * In order to speed-up EL1 TLBIs from the vEL2 guest when TGE is
+	 * set, try and handle these invalidation as quickly as possible,
+	 * without fully exiting (unless this needs forwarding).
+	 */
+	if (!vcpu_has_nv2(vcpu) ||
+	    !vcpu_is_el2(vcpu) ||
+	    (__vcpu_sys_reg(vcpu, HCR_EL2) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE))
+		return false;
+
+	instr = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
+	if (sys_reg_Op0(instr) != TLBI_Op0 ||
+	    sys_reg_Op1(instr) != TLBI_Op1_EL1)
+		return false;
+
+	val = vcpu_get_reg(vcpu, kvm_vcpu_sys_get_rt(vcpu));
+	__kvm_tlb_el1_instr(NULL, val, instr);
+	__kvm_skip_instr(vcpu);
+
+	return true;
+}
+
+static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	if (kvm_hyp_handle_tlbi_el1(vcpu, exit_code))
+		return true;
+
+	return kvm_hyp_handle_sysreg(vcpu, exit_code);
+}
+
 static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 {
 	struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
@@ -209,7 +250,7 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
 static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
-	[ESR_ELx_EC_SYS64]		= kvm_hyp_handle_sysreg,
+	[ESR_ELx_EC_SYS64]		= kvm_hyp_handle_sysreg_vhe,
 	[ESR_ELx_EC_SVE]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_FP_ASIMD]		= kvm_hyp_handle_fpsimd,
 	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index c4389db4cc22..beb162468c0b 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -201,7 +201,8 @@ void __kvm_tlb_el1_instr(struct kvm_s2_mmu *mmu, u64 val, u64 sys_encoding)
 	dsb(ishst);
 
 	/* Switch to requested VMID */
-	__tlb_switch_to_guest(mmu, &cxt);
+	if (mmu)
+		__tlb_switch_to_guest(mmu, &cxt);
 
 	/*
 	 * Execute the same instruction as the guest hypervisor did,
@@ -240,5 +241,6 @@ void __kvm_tlb_el1_instr(struct kvm_s2_mmu *mmu, u64 val, u64 sys_encoding)
 	dsb(ish);
 	isb();
 
-	__tlb_switch_to_host(&cxt);
+	if (mmu)
+		__tlb_switch_to_host(&cxt);
 }
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 351bcb429f25..5023ae566f7f 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2839,6 +2839,8 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 			    const struct sys_reg_desc *r)
 {
 	u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+	u64 virtual_vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+	struct kvm_s2_mmu *mmu;
 
 	if (vcpu_has_nv(vcpu) && forward_traps(vcpu, HCR_TTLB))
 		return false;
@@ -2860,24 +2862,13 @@ static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 
 	mutex_lock(&vcpu->kvm->lock);
 
-	if ((__vcpu_sys_reg(vcpu, HCR_EL2) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
-		u64 virtual_vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
-		struct kvm_s2_mmu *mmu;
-
-		mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, HCR_VM);
-		if (mmu)
-			__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
+	mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, HCR_VM);
+	if (mmu)
+		__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
 
-		mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, 0);
-		if (mmu)
-			__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
-	} else {
-		/*
-		 * ARMv8.4-NV allows the guest to change TGE behind
-		 * our back, so we always trap EL1 TLBIs from vEL2...
-		 */
-		__kvm_tlb_el1_instr(&vcpu->kvm->arch.mmu, p->regval, sys_encoding);
-	}
+	mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, 0);
+	if (mmu)
+		__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
 
 	mutex_unlock(&vcpu->kvm->lock);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:58 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:58 +0000
Subject: [PATCH v6 50/64] KVM: arm64: nv: Implement maintenance interrupt
 forwarding
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-51-maz@kernel.org>

When we take a maintenance interrupt, we need to decide whether
it is generated on an action from the guest, or if it is something
that needs to be forwarded to the guest hypervisor.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-init.c      | 30 ++++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 25 +++++++++++++++++++----
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c
index fc00304fe7d8..6485b7935155 100644
--- a/arch/arm64/kvm/vgic/vgic-init.c
+++ b/arch/arm64/kvm/vgic/vgic-init.c
@@ -6,10 +6,12 @@
 #include <linux/uaccess.h>
 #include <linux/interrupt.h>
 #include <linux/cpu.h>
+#include <linux/irq.h>
 #include <linux/kvm_host.h>
 #include <kvm/arm_vgic.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include "vgic.h"
 
 /*
@@ -222,6 +224,16 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu)
 	if (!irqchip_in_kernel(vcpu->kvm))
 		return 0;
 
+	if (vcpu_has_nv(vcpu)) {
+		/* FIXME: remove this hack */
+		if (vcpu->kvm->arch.vgic.maint_irq == 0)
+			vcpu->kvm->arch.vgic.maint_irq = kvm_vgic_global_state.maint_irq;
+		ret = kvm_vgic_set_owner(vcpu, vcpu->kvm->arch.vgic.maint_irq,
+					 vcpu);
+		if (ret)
+			return ret;
+	}
+
 	/*
 	 * If we are creating a VCPU with a GICv3 we must also register the
 	 * KVM io device for the redistributor that belongs to this VCPU.
@@ -475,12 +487,23 @@ static int vgic_init_cpu_dying(unsigned int cpu)
 
 static irqreturn_t vgic_maintenance_handler(int irq, void *data)
 {
+	struct kvm_vcpu *vcpu = *(struct kvm_vcpu **)data;
+
 	/*
 	 * We cannot rely on the vgic maintenance interrupt to be
 	 * delivered synchronously. This means we can only use it to
 	 * exit the VM, and we perform the handling of EOIed
 	 * interrupts on the exit path (see vgic_fold_lr_state).
 	 */
+
+	/* If not nested, deactivate */
+	if (!vcpu || !vgic_state_is_nested(vcpu)) {
+		irq_set_irqchip_state(irq, IRQCHIP_STATE_ACTIVE, false);
+		return IRQ_HANDLED;
+	}
+
+	/* Assume nested from now */
+	vgic_v3_handle_nested_maint_irq(vcpu);
 	return IRQ_HANDLED;
 }
 
@@ -579,6 +602,13 @@ int kvm_vgic_hyp_init(void)
 		return ret;
 	}
 
+	ret = irq_set_vcpu_affinity(kvm_vgic_global_state.maint_irq,
+				    kvm_get_running_vcpus());
+	if (ret) {
+		kvm_err("Error setting vcpu affinity\n");
+		goto out_free_irq;
+	}
+
 	ret = cpuhp_setup_state(CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
 				"kvm/arm/vgic:starting",
 				vgic_init_cpu_starting, vgic_init_cpu_dying);
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
index e88c75e79010..4a35c2be7984 100644
--- a/arch/arm64/kvm/vgic/vgic-v3-nested.c
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -175,10 +175,20 @@ void vgic_v3_sync_nested(struct kvm_vcpu *vcpu)
 void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
 {
 	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+	struct vgic_irq *irq;
+	unsigned long flags;
 
 	vgic_cpu->shadow_vgic_v3 = vgic_cpu->nested_vgic_v3;
 	vgic_v3_create_shadow_lr(vcpu);
 	__vgic_v3_restore_state(vcpu_shadow_if(vcpu));
+
+	irq = vgic_get_irq(vcpu->kvm, vcpu, vcpu->kvm->arch.vgic.maint_irq);
+	raw_spin_lock_irqsave(&irq->irq_lock, flags);
+	if (irq->line_level || irq->active)
+		irq_set_irqchip_state(kvm_vgic_global_state.maint_irq,
+				      IRQCHIP_STATE_ACTIVE, true);
+	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
+	vgic_put_irq(vcpu->kvm, irq);
 }
 
 void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
@@ -193,11 +203,14 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
 	 */
 	vgic_v3_fixup_shadow_lr_state(vcpu);
 	vgic_cpu->nested_vgic_v3 = vgic_cpu->shadow_vgic_v3;
+	irq_set_irqchip_state(kvm_vgic_global_state.maint_irq,
+			      IRQCHIP_STATE_ACTIVE, false);
 }
 
 void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	bool state;
 
 	/*
 	 * If we exit a nested VM with a pending maintenance interrupt from the
@@ -205,8 +218,12 @@ void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
 	 * can re-sync the appropriate LRs and sample level triggered interrupts
 	 * again.
 	 */
-	if (vgic_state_is_nested(vcpu) &&
-	    (cpu_if->vgic_hcr & ICH_HCR_EN) &&
-	    vgic_v3_get_misr(vcpu))
-		kvm_inject_nested_irq(vcpu);
+	if (!vgic_state_is_nested(vcpu))
+		return;
+
+	state  = cpu_if->vgic_hcr & ICH_HCR_EN;
+	state &= vgic_v3_get_misr(vcpu);
+
+	kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id,
+			    vcpu->kvm->arch.vgic.maint_irq, state, vcpu);
 }
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:02 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:02 +0000
Subject: [PATCH v6 54/64] KVM: arm64: nv: Invalidate TLBs based on shadow S2
 TTL-like information
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-55-maz@kernel.org>

In order to be able to make S2 TLB invalidations more performant on NV,
let's use a scheme derived from the ARMv8.4 TTL extension.

If bits [56:55] in the descriptor are non-zero, they indicate a level
which can be used as an invalidation range.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  4 ++
 arch/arm64/kvm/nested.c             | 98 +++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c           | 13 ++--
 3 files changed, 110 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 8bfbeca2f4cd..847b652bd376 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -128,6 +128,8 @@ extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
 extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
 extern bool forward_nv1_traps(struct kvm_vcpu *vcpu);
+u8 get_guest_mapping_ttl(struct kvm_vcpu *vcpu, struct kvm_s2_mmu *mmu,
+			 u64 addr);
 unsigned int ttl_to_size(u8 ttl);
 
 struct sys_reg_params;
@@ -136,4 +138,6 @@ struct sys_reg_desc;
 void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
 			  const struct sys_reg_desc *r);
 
+#define KVM_NV_GUEST_MAP_SZ	(KVM_PGTABLE_PROT_SW1 | KVM_PGTABLE_PROT_SW0)
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 7e4ff98c4e95..8e99690cdde1 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -4,6 +4,7 @@
  * Author: Jintack Lim <jintack.lim at linaro.org>
  */
 
+#include <linux/bitfield.h>
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
@@ -351,6 +352,29 @@ int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
 	return ret;
 }
 
+static int read_host_s2_desc(phys_addr_t pa, u64 *desc, void *data)
+{
+	u64 *va = phys_to_virt(pa);
+
+	*desc = *va;
+
+	return 0;
+}
+
+static int kvm_walk_shadow_s2(struct kvm_s2_mmu *mmu, phys_addr_t gipa,
+			      struct kvm_s2_trans *result)
+{
+	struct s2_walk_info wi = { };
+
+	wi.read_desc = read_host_s2_desc;
+	wi.baddr = mmu->pgd_phys;
+
+	vtcr_to_walk_info(mmu->arch->vtcr, &wi);
+
+	wi.be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN);
+
+	return walk_nested_s2_pgd(gipa, &wi, result);
+}
 
 unsigned int ttl_to_size(u8 ttl)
 {
@@ -408,6 +432,80 @@ unsigned int ttl_to_size(u8 ttl)
 	return max_size;
 }
 
+/*
+ * Compute the equivalent of the TTL field by parsing the shadow PT.
+ * The granule size is extracted from VTCR_EL2.TG0 while the level is
+ * retrieved from first entry carrying the level as a tag.
+ */
+u8 get_guest_mapping_ttl(struct kvm_vcpu *vcpu, struct kvm_s2_mmu *mmu,
+			 u64 addr)
+{
+	u64 tmp, sz = 0, vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+	struct kvm_s2_trans out;
+	u8 ttl, level;
+
+	switch (vtcr & VTCR_EL2_TG0_MASK) {
+	case VTCR_EL2_TG0_4K:
+		ttl = (1 << 2);
+		break;
+	case VTCR_EL2_TG0_16K:
+		ttl = (2 << 2);
+		break;
+	case VTCR_EL2_TG0_64K:
+		ttl = (3 << 2);
+		break;
+	default:
+		BUG();
+	}
+
+	tmp = addr;
+
+again:
+	/* Iteratively compute the block sizes for a particular granule size */
+	switch (vtcr & VTCR_EL2_TG0_MASK) {
+	case VTCR_EL2_TG0_4K:
+		if	(sz < SZ_4K)	sz = SZ_4K;
+		else if (sz < SZ_2M)	sz = SZ_2M;
+		else if (sz < SZ_1G)	sz = SZ_1G;
+		else			sz = 0;
+		break;
+	case VTCR_EL2_TG0_16K:
+		if	(sz < SZ_16K)	sz = SZ_16K;
+		else if (sz < SZ_32M)	sz = SZ_32M;
+		else			sz = 0;
+		break;
+	case VTCR_EL2_TG0_64K:
+		if	(sz < SZ_64K)	sz = SZ_64K;
+		else if (sz < SZ_512M)	sz = SZ_512M;
+		else			sz = 0;
+		break;
+	default:
+		BUG();
+	}
+
+	if (sz == 0)
+		return 0;
+
+	tmp &= ~(sz - 1);
+	out = (struct kvm_s2_trans) { };
+	kvm_walk_shadow_s2(mmu, tmp, &out);
+	level = FIELD_GET(KVM_NV_GUEST_MAP_SZ, out.upper_attr);
+	if (!level)
+		goto again;
+
+	ttl |= level;
+
+	/*
+	 * We now have found some level information in the shadow S2. Check
+	 * that the resulting range is actually including the original IPA.
+	 */
+	sz = ttl_to_size(ttl);
+	if (addr < (tmp + sz))
+		return ttl;
+
+	return 0;
+}
+
 /* Must be called with kvm->lock held */
 struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
 {
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ebe6fad76b4b..32b8f4c1074a 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2736,10 +2736,13 @@ static unsigned long compute_tlb_inval_range(struct kvm_vcpu *vcpu,
 					     u64 val)
 {
 	unsigned long max_size;
-	u8 ttl = 0;
+	u8 ttl;
 
-	if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL)) {
-		ttl = FIELD_GET(GENMASK_ULL(47, 44), val);
+	ttl = FIELD_GET(GENMASK_ULL(47, 44), val);
+
+	if (!(cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) && ttl)) {
+		u64 addr = (val & GENMASK_ULL(35, 0)) << 12;
+		ttl = get_guest_mapping_ttl(vcpu, mmu, addr);
 	}
 
 	max_size = ttl_to_size(ttl);
@@ -2783,6 +2786,8 @@ static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
 		return false;
 
+	spin_lock(&vcpu->kvm->mmu_lock);
+
 	/*
 	 * We drop a number of things from the supplied value:
 	 *
@@ -2794,8 +2799,6 @@ static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	 */
 	base_addr = (p->regval & GENMASK_ULL(35, 0)) << 12;
 
-	spin_lock(&vcpu->kvm->mmu_lock);
-
 	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, HCR_VM);
 	if (mmu) {
 		max_size = compute_tlb_inval_range(vcpu, mmu, p->regval);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:39 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:39 +0000
Subject: [PATCH v6 31/64] KVM: arm64: nv: Only toggle cache for virtual EL2
 when SCTLR_EL2 changes
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-32-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at linaro.org>

So far we were flushing almost the entire universe whenever a VM would
load/unload the SCTLR_EL1 and the two versions of that register had
different MMU enabled settings.  This turned out to be so slow that it
prevented forward progress for a nested VM, because a scheduler timer
tick interrupt would always be pending when we reached the nested VM.

To avoid this problem, we consider the SCTLR_EL2 when evaluating if
caches are on or off when entering virtual EL2 (because this is the
value that we end up shadowing onto the hardware EL1 register).

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_mmu.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 81839e9a8a24..1b314b2a69bc 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -115,6 +115,7 @@ alternative_cb_end
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
+#include <asm/kvm_emulate.h>
 
 void kvm_update_va_mask(struct alt_instr *alt,
 			__le32 *origptr, __le32 *updptr, int nr_inst);
@@ -187,7 +188,10 @@ struct kvm;
 
 static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
 {
-	return (vcpu_read_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
+	if (vcpu_is_el2(vcpu))
+		return (__vcpu_sys_reg(vcpu, SCTLR_EL2) & 0b101) == 0b101;
+	else
+		return (vcpu_read_sys_reg(vcpu, SCTLR_EL1) & 0b101) == 0b101;
 }
 
 static inline void __clean_dcache_guest_page(void *va, size_t size)
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:03 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:03 +0000
Subject: [PATCH v6 55/64] KVM: arm64: nv: Tag shadow S2 entries with nested
 level
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-56-maz@kernel.org>

Populate bits [56:55] of the leaf entry with the level provided
by the guest's S2 translation.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  7 +++++++
 arch/arm64/kvm/mmu.c                | 11 +++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 847b652bd376..3b5838a2f29e 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -5,6 +5,8 @@
 #include <linux/bitfield.h>
 #include <linux/kvm_host.h>
 
+#include <asm/kvm_pgtable.h>
+
 static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
 {
 	return (!__is_defined(__KVM_NVHE_HYPERVISOR__) &&
@@ -140,4 +142,9 @@ void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
 
 #define KVM_NV_GUEST_MAP_SZ	(KVM_PGTABLE_PROT_SW1 | KVM_PGTABLE_PROT_SW0)
 
+static inline u64 kvm_encode_nested_level(struct kvm_s2_trans *trans)
+{
+	return FIELD_PREP(KVM_NV_GUEST_MAP_SZ, trans->level);
+}
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 4b38f2f3c997..6caa48da1b2e 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1281,11 +1281,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * Potentially reduce shadow S2 permissions to match the guest's own
 	 * S2. For exec faults, we'd only reach this point if the guest
 	 * actually allowed it (see kvm_s2_handle_perm_fault).
+	 *
+	 * Also encode the level of the nested translation in the SW bits of
+	 * the PTE/PMD/PUD. This will be retrived on TLB invalidation from
+	 * the guest.
 	 */
 	if (kvm_is_shadow_s2_fault(vcpu)) {
 		writable &= kvm_s2_trans_writable(nested);
 		if (!kvm_s2_trans_readable(nested))
 			prot &= ~KVM_PGTABLE_PROT_R;
+
+		prot |= kvm_encode_nested_level(nested);
 	}
 
 	spin_lock(&kvm->mmu_lock);
@@ -1336,6 +1342,11 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * kvm_pgtable_stage2_map() should be called to change block size.
 	 */
 	if (fault_status == FSC_PERM && vma_pagesize == fault_granule) {
+		/*
+		 * Drop the SW bits in favour of those stored in the
+		 * PTE, which will be preserved.
+		 */
+		prot &= ~KVM_NV_GUEST_MAP_SZ;
 		ret = kvm_pgtable_stage2_relax_perms(pgt, fault_ipa, prot);
 	} else {
 		ret = kvm_pgtable_stage2_map(pgt, fault_ipa, vma_pagesize,
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:47 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:47 +0000
Subject: [PATCH v6 39/64] KVM: arm64: nv: Set a handler for the system
 instruction traps
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-40-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

When HCR.NV bit is set, execution of the EL2 translation regime address
aranslation instructions and TLB maintenance instructions are trapped to
EL2. In addition, execution of the EL1 translation regime address
aranslation instructions and TLB maintenance instructions that are only
accessible from EL2 and above are trapped to EL2. In these cases,
ESR_EL2.EC will be set to 0x18.

Rework the system instruction emulation framework to handle potentially
all system instruction traps other than MSR/MRS instructions. Those
system instructions would be AT and TLBI instructions controlled by
HCR_EL2.NV, AT, and TTLB bits.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: squashed two patches together, redispatched various bits around]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |  4 +--
 arch/arm64/kvm/handle_exit.c      |  2 +-
 arch/arm64/kvm/sys_regs.c         | 48 +++++++++++++++++++++++++------
 3 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index a15183d0e1bf..0b887364f994 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -407,7 +407,7 @@ struct kvm_vcpu_arch {
 	/*
 	 * Guest registers we preserve during guest debugging.
 	 *
-	 * These shadow registers are updated by the kvm_handle_sys_reg
+	 * These shadow registers are updated by the kvm_handle_sys
 	 * trap handler if the guest accesses or updates them while we
 	 * are using guest debug.
 	 */
@@ -724,7 +724,7 @@ int kvm_handle_cp14_32(struct kvm_vcpu *vcpu);
 int kvm_handle_cp14_64(struct kvm_vcpu *vcpu);
 int kvm_handle_cp15_32(struct kvm_vcpu *vcpu);
 int kvm_handle_cp15_64(struct kvm_vcpu *vcpu);
-int kvm_handle_sys_reg(struct kvm_vcpu *vcpu);
+int kvm_handle_sys(struct kvm_vcpu *vcpu);
 
 void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
 
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 867de65eb766..d135fc7e6883 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -236,7 +236,7 @@ static exit_handle_fn arm_exit_handlers[] = {
 	[ESR_ELx_EC_SMC32]	= handle_smc,
 	[ESR_ELx_EC_HVC64]	= handle_hvc,
 	[ESR_ELx_EC_SMC64]	= handle_smc,
-	[ESR_ELx_EC_SYS64]	= kvm_handle_sys_reg,
+	[ESR_ELx_EC_SYS64]	= kvm_handle_sys,
 	[ESR_ELx_EC_SVE]	= handle_sve,
 	[ESR_ELx_EC_ERET]	= kvm_handle_eret,
 	[ESR_ELx_EC_IABT_LOW]	= kvm_handle_guest_abort,
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 5e8876177ce6..f669618f966b 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1771,10 +1771,6 @@ static bool access_spsr_el2(struct kvm_vcpu *vcpu,
  * more demanding guest...
  */
 static const struct sys_reg_desc sys_reg_descs[] = {
-	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
-	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
-
 	DBG_BCR_BVR_WCR_WVR_EL1(0),
 	DBG_BCR_BVR_WCR_WVR_EL1(1),
 	{ SYS_DESC(SYS_MDCCINT_EL1), trap_debug_regs, reset_val, MDCCINT_EL1, 0 },
@@ -2240,6 +2236,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
+#define SYS_INSN_TO_DESC(insn, access_fn, forward_fn)	\
+	{ SYS_DESC((insn)), (access_fn), NULL, 0, 0, NULL, NULL, (forward_fn) }
+static struct sys_reg_desc sys_insn_descs[] = {
+	{ SYS_DESC(SYS_DC_ISW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
+	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
+};
+
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
 			struct sys_reg_params *p,
 			const struct sys_reg_desc *r)
@@ -2786,6 +2790,24 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu,
 	return 1;
 }
 
+static int emulate_sys_instr(struct kvm_vcpu *vcpu, struct sys_reg_params *p)
+{
+	const struct sys_reg_desc *r;
+
+	/* Search from the system instruction table. */
+	r = find_reg(p, sys_insn_descs, ARRAY_SIZE(sys_insn_descs));
+
+	if (likely(r)) {
+		perform_access(vcpu, p, r);
+	} else {
+		kvm_err("Unsupported guest sys instruction at: %lx\n",
+			*vcpu_pc(vcpu));
+		print_sys_reg_instr(p);
+		kvm_inject_undefined(vcpu);
+	}
+	return 1;
+}
+
 /**
  * kvm_reset_sys_regs - sets system registers to reset value
  * @vcpu: The VCPU pointer
@@ -2803,10 +2825,11 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu)
 }
 
 /**
- * kvm_handle_sys_reg -- handles a mrs/msr trap on a guest sys_reg access
+ * kvm_handle_sys-- handles a system instruction or mrs/msr instruction trap
+		    on a guest execution
  * @vcpu: The VCPU pointer
  */
-int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
+int kvm_handle_sys(struct kvm_vcpu *vcpu)
 {
 	struct sys_reg_params params;
 	unsigned long esr = kvm_vcpu_get_esr(vcpu);
@@ -2818,10 +2841,16 @@ int kvm_handle_sys_reg(struct kvm_vcpu *vcpu)
 	params = esr_sys64_to_params(esr);
 	params.regval = vcpu_get_reg(vcpu, Rt);
 
-	ret = emulate_sys_reg(vcpu, &params);
+	if (params.Op0 == 1) {
+		/* System instructions */
+		ret = emulate_sys_instr(vcpu, &params);
+	} else {
+		/* MRS/MSR instructions */
+		ret = emulate_sys_reg(vcpu, &params);
+		if (!params.is_write)
+			vcpu_set_reg(vcpu, Rt, params.regval);
+	}
 
-	if (!params.is_write)
-		vcpu_set_reg(vcpu, Rt, params.regval);
 	return ret;
 }
 
@@ -3237,6 +3266,7 @@ void kvm_sys_reg_table_init(void)
 	BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs), true));
 	BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs), true));
 	BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs), false));
+	BUG_ON(check_sysreg_table(sys_insn_descs, ARRAY_SIZE(sys_insn_descs), false));
 
 	/* We abuse the reset function to overwrite the table itself. */
 	for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++)
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:55 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:55 +0000
Subject: [PATCH v6 47/64] KVM: arm64: nv: Don't load the GICv4 context on
 entering a nested guest
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-48-maz@kernel.org>

When entering a nested guest (vgic_state_is_nested() == true),
special care must be taken *not* to make the vPE resident, as
these are interrupts targetting the L1 guest, and not any
nested guest.

By not making the vPE resident, we guarantee that the delivery
of an vLPI will result in a doorbell, forcing an exit from the
nested guest and a switch to the L1 guest to handle the interrupt.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/vgic/vgic-v3.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index 6bfca28ecced..39e5c68087ea 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -736,8 +736,8 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 
 	if (vgic_state_is_nested(vcpu))
 		vgic_v3_load_nested(vcpu);
-
-	WARN_ON(vgic_v4_load(vcpu));
+	else
+		WARN_ON(vgic_v4_load(vcpu));
 }
 
 void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu)
@@ -755,6 +755,12 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	/*
+	 * vgic_v4_put will do nothing if we were not resident. This
+	 * covers both the cases where we've blocked (we already have
+	 * done a vgic_v4_put) and when running a nested guest (the
+	 * vPE was never resident in order to generate a doorbell).
+	 */
 	WARN_ON(vgic_v4_put(vcpu, false));
 
 	vgic_v3_vmcr_sync(vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:45 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:45 +0000
Subject: [PATCH v6 37/64] KVM: arm64: nv: Restrict S2 RD/WR permissions to
 match the guest's
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-38-maz@kernel.org>

When mapping a page in a shadow stage-2, special care must be
taken not to be more permissive than the guest is (writable or
readable page when the guest hasn't set that permission).

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h | 15 +++++++++++++++
 arch/arm64/kvm/mmu.c                | 14 +++++++++++++-
 arch/arm64/kvm/nested.c             |  2 +-
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 4fad4d3848ce..f4b846d09d86 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -97,6 +97,21 @@ static inline u32 kvm_s2_trans_esr(struct kvm_s2_trans *trans)
 	return trans->esr;
 }
 
+static inline bool kvm_s2_trans_readable(struct kvm_s2_trans *trans)
+{
+	return trans->readable;
+}
+
+static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans)
+{
+	return trans->writable;
+}
+
+static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans)
+{
+	return !(trans->upper_attr & BIT(54));
+}
+
 extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
 			      struct kvm_s2_trans *result);
 
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 36f7ecb4f81b..7c56e1522d3c 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1247,6 +1247,17 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	if (exec_fault && device)
 		return -ENOEXEC;
 
+	/*
+	 * Potentially reduce shadow S2 permissions to match the guest's own
+	 * S2. For exec faults, we'd only reach this point if the guest
+	 * actually allowed it (see kvm_s2_handle_perm_fault).
+	 */
+	if (kvm_is_shadow_s2_fault(vcpu)) {
+		writable &= kvm_s2_trans_writable(nested);
+		if (!kvm_s2_trans_readable(nested))
+			prot &= ~KVM_PGTABLE_PROT_R;
+	}
+
 	spin_lock(&kvm->mmu_lock);
 	pgt = vcpu->arch.hw_mmu->pgt;
 	if (mmu_notifier_retry(kvm, mmu_seq))
@@ -1285,7 +1296,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 
 	if (device)
 		prot |= KVM_PGTABLE_PROT_DEVICE;
-	else if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC))
+	else if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC) &&
+		 kvm_s2_trans_executable(nested))
 		prot |= KVM_PGTABLE_PROT_X;
 
 	/*
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 0a9708f776fc..a74ffb1d2064 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -481,7 +481,7 @@ int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, struct kvm_s2_trans *trans)
 		return 0;
 
 	if (kvm_vcpu_trap_is_iabt(vcpu)) {
-		forward_fault = (trans->upper_attr & BIT(54));
+		forward_fault = !kvm_s2_trans_executable(trans);
 	} else {
 		bool write_fault = kvm_is_write_fault(vcpu);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:52 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:52 +0000
Subject: [PATCH v6 44/64] KVM: arm64: nv: Add handling of EL2-specific timer
 registers
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-45-maz@kernel.org>

Add the required handling for EL2 and EL02 registers, as
well as EL1 registers used in the E2H context.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/sysreg.h |  6 +++
 arch/arm64/kvm/sys_regs.c       | 87 +++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 41c3603a3f29..ff6d3af8ed34 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -626,6 +626,12 @@
 
 #define SYS_CNTVOFF_EL2			sys_reg(3, 4, 14, 0, 3)
 #define SYS_CNTHCTL_EL2			sys_reg(3, 4, 14, 1, 0)
+#define SYS_CNTHP_TVAL_EL2		sys_reg(3, 4, 14, 2, 0)
+#define SYS_CNTHP_CTL_EL2		sys_reg(3, 4, 14, 2, 1)
+#define SYS_CNTHP_CVAL_EL2		sys_reg(3, 4, 14, 2, 2)
+#define SYS_CNTHV_TVAL_EL2		sys_reg(3, 4, 14, 3, 0)
+#define SYS_CNTHV_CTL_EL2		sys_reg(3, 4, 14, 3, 1)
+#define SYS_CNTHV_CVAL_EL2		sys_reg(3, 4, 14, 3, 2)
 
 /* VHE encodings for architectural EL0/1 system registers */
 #define SYS_SCTLR_EL12			sys_reg(3, 5, 1, 0, 0)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index bbc58930a5eb..f2452e76156c 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1274,20 +1274,92 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 
 	switch (reg) {
 	case SYS_CNTP_TVAL_EL0:
+		if (vcpu_is_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_TVAL:
+	case SYS_CNTP_TVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_TVAL;
 		break;
+
+	case SYS_CNTV_TVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHP_TVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
+	case SYS_CNTHV_TVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_TVAL;
+		break;
+
 	case SYS_CNTP_CTL_EL0:
+		if (vcpu_is_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_AARCH32_CNTP_CTL:
+	case SYS_CNTP_CTL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CTL;
 		break;
+
+	case SYS_CNTV_CTL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHP_CTL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
+	case SYS_CNTHV_CTL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CTL;
+		break;
+
 	case SYS_CNTP_CVAL_EL0:
+		if (vcpu_is_el2(vcpu) && vcpu_el2_e2h_is_set(vcpu))
+			tmr = TIMER_HPTIMER;
+		else
+			tmr = TIMER_PTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_AARCH32_CNTP_CVAL:
+	case SYS_CNTP_CVAL_EL02:
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CVAL;
 		break;
+
+	case SYS_CNTV_CVAL_EL02:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHP_CVAL_EL2:
+		tmr = TIMER_HPTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
+	case SYS_CNTHV_CVAL_EL2:
+		tmr = TIMER_HVTIMER;
+		treg = TIMER_REG_CVAL;
+		break;
+
 	case SYS_CNTVOFF_EL2:
 		tmr = TIMER_VTIMER;
 		treg = TIMER_REG_VOFF;
@@ -2220,6 +2292,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_CNTVOFF_EL2), access_arch_timer },
 	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
 
+	{ SYS_DESC(SYS_CNTHP_TVAL_EL2), access_arch_timer },
+	{ SYS_DESC(SYS_CNTHP_CTL_EL2), access_arch_timer },
+	{ SYS_DESC(SYS_CNTHP_CVAL_EL2), access_arch_timer },
+	{ SYS_DESC(SYS_CNTHV_TVAL_EL2), access_arch_timer },
+	{ SYS_DESC(SYS_CNTHV_CTL_EL2), access_arch_timer },
+	{ SYS_DESC(SYS_CNTHV_CVAL_EL2), access_arch_timer },
+
 	EL12_REG(SCTLR, access_vm_reg, reset_val, 0x00C50078),
 	EL12_REG(CPACR, access_rw, reset_val, 0),
 	EL12_REG(TTBR0, access_vm_reg, reset_unknown, 0),
@@ -2237,6 +2316,14 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL12_REG(CONTEXTIDR, access_vm_reg, reset_val, 0),
 	EL12_REG(CNTKCTL, access_rw, reset_val, 0),
 
+	{ SYS_DESC(SYS_CNTP_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTP_CVAL_EL02), access_arch_timer },
+
+	{ SYS_DESC(SYS_CNTV_TVAL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CTL_EL02), access_arch_timer },
+	{ SYS_DESC(SYS_CNTV_CVAL_EL02), access_arch_timer },
+
 	EL2_REG(SP_EL2, NULL, reset_unknown, 0),
 };
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:44 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:44 +0000
Subject: [PATCH v6 36/64] KVM: arm64: nv: Handle shadow stage 2 page faults
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-37-maz@kernel.org>

If we are faulting on a shadow stage 2 translation, we first walk the
guest hypervisor's stage 2 page table to see if it has a mapping. If
not, we inject a stage 2 page fault to the virtual EL2. Otherwise, we
create a mapping in the shadow stage 2 page table.

Note that we have to deal with two IPAs when we got a shadow stage 2
page fault. One is the address we faulted on, and is in the L2 guest
phys space. The other is from the guest stage-2 page table walk, and is
in the L1 guest phys space.  To differentiate them, we rename variables
so that fault_ipa is used for the former and ipa is used for the latter.

Co-developed-by: Christoffer Dall <christoffer.dall at linaro.org>
Co-developed-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: rewrote this multiple times...]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h |   6 ++
 arch/arm64/include/asm/kvm_nested.h  |  18 +++++
 arch/arm64/kvm/mmu.c                 | 102 +++++++++++++++++++++++----
 arch/arm64/kvm/nested.c              |  48 +++++++++++++
 4 files changed, 159 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index ff8980a39ee8..dc6eeb0cc8a9 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -602,4 +602,10 @@ static inline bool vcpu_has_feature(struct kvm_vcpu *vcpu, int feature)
 	return test_bit(feature, vcpu->arch.features);
 }
 
+static inline bool kvm_is_shadow_s2_fault(struct kvm_vcpu *vcpu)
+{
+	return (vcpu->arch.hw_mmu != &vcpu->kvm->arch.mmu &&
+		vcpu->arch.hw_mmu->nested_stage2_enabled);
+}
+
 #endif /* __ARM64_KVM_EMULATE_H__ */
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 48cf288ea238..4fad4d3848ce 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -82,9 +82,27 @@ struct kvm_s2_trans {
 	u64 upper_attr;
 };
 
+static inline phys_addr_t kvm_s2_trans_output(struct kvm_s2_trans *trans)
+{
+	return trans->output;
+}
+
+static inline unsigned long kvm_s2_trans_size(struct kvm_s2_trans *trans)
+{
+	return trans->block_size;
+}
+
+static inline u32 kvm_s2_trans_esr(struct kvm_s2_trans *trans)
+{
+	return trans->esr;
+}
+
 extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
 			      struct kvm_s2_trans *result);
 
+extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu,
+				    struct kvm_s2_trans *trans);
+extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2);
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 			    u64 control_bit);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 55525fd5743d..36f7ecb4f81b 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -969,7 +969,7 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
 static unsigned long
 transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
 			    unsigned long hva, kvm_pfn_t *pfnp,
-			    phys_addr_t *ipap)
+			    phys_addr_t *ipap, phys_addr_t *fault_ipap)
 {
 	kvm_pfn_t pfn = *pfnp;
 
@@ -998,6 +998,7 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
 		 * to PG_head and switch the pfn from a tail page to the head
 		 * page accordingly.
 		 */
+		*fault_ipap &= PMD_MASK;
 		*ipap &= PMD_MASK;
 		kvm_release_pfn_clean(pfn);
 		pfn &= ~(PTRS_PER_PMD - 1);
@@ -1080,15 +1081,17 @@ static int sanitise_mte_tags(struct kvm *kvm, kvm_pfn_t pfn,
 }
 
 static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
-			  struct kvm_memory_slot *memslot, unsigned long hva,
-			  unsigned long fault_status)
+			  struct kvm_s2_trans *nested,
+			  struct kvm_memory_slot *memslot,
+			  unsigned long hva, unsigned long fault_status)
 {
 	int ret = 0;
-	bool write_fault, writable, force_pte = false;
+	bool write_fault, writable;
 	bool exec_fault;
 	bool device = false;
 	bool shared;
 	unsigned long mmu_seq;
+	phys_addr_t ipa = fault_ipa;
 	struct kvm *kvm = vcpu->kvm;
 	struct kvm_mmu_memory_cache *memcache = &vcpu->arch.mmu_page_cache;
 	struct vm_area_struct *vma;
@@ -1100,6 +1103,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	unsigned long vma_pagesize, fault_granule;
 	enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
 	struct kvm_pgtable *pgt;
+	unsigned long max_map_size = PUD_SIZE;
 
 	fault_granule = 1UL << ARM64_HW_PGTABLE_LEVEL_SHIFT(fault_level);
 	write_fault = kvm_is_write_fault(vcpu);
@@ -1128,7 +1132,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * memslots.
 	 */
 	if (logging_active) {
-		force_pte = true;
+		max_map_size = vma_pagesize = PAGE_SIZE;
 		vma_shift = PAGE_SHIFT;
 	} else {
 		vma_shift = get_vma_page_shift(vma, hva);
@@ -1152,7 +1156,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 		fallthrough;
 	case CONT_PTE_SHIFT:
 		vma_shift = PAGE_SHIFT;
-		force_pte = true;
+		max_map_size = PAGE_SIZE;
 		fallthrough;
 	case PAGE_SHIFT:
 		break;
@@ -1161,10 +1165,25 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	}
 
 	vma_pagesize = 1UL << vma_shift;
+
+	if (kvm_is_shadow_s2_fault(vcpu)) {
+		ipa = kvm_s2_trans_output(nested);
+
+		/*
+		 * If we're about to create a shadow stage 2 entry, then we
+		 * can only create a block mapping if the guest stage 2 page
+		 * table uses at least as big a mapping.
+		 */
+		max_map_size = min(kvm_s2_trans_size(nested), max_map_size);
+	}
+
+	vma_pagesize = min(vma_pagesize, max_map_size);
+
 	if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
 		fault_ipa &= ~(vma_pagesize - 1);
 
-	gfn = fault_ipa >> PAGE_SHIFT;
+	gfn = ipa >> PAGE_SHIFT;
+
 	mmap_read_unlock(current->mm);
 
 	/*
@@ -1237,12 +1256,14 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
 	 * If we are not forced to use page mapping, check if we are
 	 * backed by a THP and thus use block mapping if possible.
 	 */
-	if (vma_pagesize == PAGE_SIZE && !(force_pte || device)) {
+	if (vma_pagesize == PAGE_SIZE &&
+	    !(max_map_size == PAGE_SIZE || device)) {
 		if (fault_status == FSC_PERM && fault_granule > PAGE_SIZE)
 			vma_pagesize = fault_granule;
 		else
 			vma_pagesize = transparent_hugepage_adjust(kvm, memslot,
 								   hva, &pfn,
+								   &ipa,
 								   &fault_ipa);
 	}
 
@@ -1326,8 +1347,10 @@ static void handle_access_fault(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
 int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 {
 	unsigned long fault_status;
-	phys_addr_t fault_ipa;
+	phys_addr_t fault_ipa; /* The address we faulted on */
+	phys_addr_t ipa; /* Always the IPA in the L1 guest phys space */
 	struct kvm_memory_slot *memslot;
+	struct kvm_s2_trans nested_trans;
 	unsigned long hva;
 	bool is_iabt, write_fault, writable;
 	gfn_t gfn;
@@ -1335,7 +1358,7 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 
 	fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
 
-	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
+	ipa = fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
 	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
 
 	/* Synchronous External Abort? */
@@ -1356,6 +1379,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 	/* Check the stage-2 fault is trans. fault or write fault */
 	if (fault_status != FSC_FAULT && fault_status != FSC_PERM &&
 	    fault_status != FSC_ACCESS) {
+		/*
+		 * We must never see an address size fault on shadow stage 2
+		 * page table walk, because we would have injected an addr
+		 * size fault when we walked the nested s2 page and not
+		 * create the shadow entry.
+		 */
 		kvm_err("Unsupported FSC: EC=%#x xFSC=%#lx ESR_EL2=%#lx\n",
 			kvm_vcpu_trap_get_class(vcpu),
 			(unsigned long)kvm_vcpu_trap_get_fault(vcpu),
@@ -1365,7 +1394,49 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 
 	idx = srcu_read_lock(&vcpu->kvm->srcu);
 
-	gfn = fault_ipa >> PAGE_SHIFT;
+	/*
+	 * We may have faulted on a shadow stage 2 page table if we are
+	 * running a nested guest.  In this case, we have to resolve the L2
+	 * IPA to the L1 IPA first, before knowing what kind of memory should
+	 * back the L1 IPA.
+	 *
+	 * If the shadow stage 2 page table walk faults, then we simply inject
+	 * this to the guest and carry on.
+	 */
+	if (kvm_is_shadow_s2_fault(vcpu)) {
+		u32 esr;
+
+		ret = kvm_walk_nested_s2(vcpu, fault_ipa, &nested_trans);
+		esr = kvm_s2_trans_esr(&nested_trans);
+		if (esr)
+			kvm_inject_s2_fault(vcpu, esr);
+		if (ret)
+			goto out_unlock;
+
+		ret = kvm_s2_handle_perm_fault(vcpu, &nested_trans);
+		esr = kvm_s2_trans_esr(&nested_trans);
+		if (esr)
+			kvm_inject_s2_fault(vcpu, esr);
+		if (ret)
+			goto out_unlock;
+
+		ipa = kvm_s2_trans_output(&nested_trans);
+	} else {
+		nested_trans = (struct kvm_s2_trans) {
+			/*
+			 * Default to RWX so that we don't filter
+			 * anything while evaluating the permissions.
+			 */
+			.writable	= true,
+			.readable	= true,
+			.upper_attr	= 0,
+			.output		= ipa,
+			.level		= kvm_vcpu_trap_get_fault_level(vcpu),
+			.esr		= kvm_vcpu_get_esr(vcpu),
+		};
+	}
+
+	gfn = ipa >> PAGE_SHIFT;
 	memslot = gfn_to_memslot(vcpu->kvm, gfn);
 	hva = gfn_to_hva_memslot_prot(memslot, gfn, &writable);
 	write_fault = kvm_is_write_fault(vcpu);
@@ -1409,13 +1480,13 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		 * faulting VA. This is always 12 bits, irrespective
 		 * of the page size.
 		 */
-		fault_ipa |= kvm_vcpu_get_hfar(vcpu) & ((1 << 12) - 1);
-		ret = io_mem_abort(vcpu, fault_ipa);
+		ipa |= kvm_vcpu_get_hfar(vcpu) & ((1 << 12) - 1);
+		ret = io_mem_abort(vcpu, ipa);
 		goto out_unlock;
 	}
 
 	/* Userspace should not be able to register out-of-bounds IPAs */
-	VM_BUG_ON(fault_ipa >= kvm_phys_size(vcpu->kvm));
+	VM_BUG_ON(ipa >= kvm_phys_size(vcpu->kvm));
 
 	if (fault_status == FSC_ACCESS) {
 		handle_access_fault(vcpu, fault_ipa);
@@ -1423,7 +1494,8 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)
 		goto out_unlock;
 	}
 
-	ret = user_mem_abort(vcpu, fault_ipa, memslot, hva, fault_status);
+	ret = user_mem_abort(vcpu, fault_ipa, &nested_trans,
+			     memslot, hva, fault_status);
 	if (ret == 0)
 		ret = 1;
 out:
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index c2a99b672368..0a9708f776fc 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -108,6 +108,15 @@ static u32 compute_fsc(int level, u32 fsc)
 	return fsc | (level & 0x3);
 }
 
+static int esr_s2_fault(struct kvm_vcpu *vcpu, int level, u32 fsc)
+{
+	u32 esr;
+
+	esr = kvm_vcpu_get_esr(vcpu) & ~ESR_ELx_FSC;
+	esr |= compute_fsc(level, fsc);
+	return esr;
+}
+
 static int check_base_s2_limits(struct s2_walk_info *wi,
 				int level, int input_size, int stride)
 {
@@ -457,6 +466,45 @@ void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
 	}
 }
 
+/*
+ * Returns non-zero if permission fault is handled by injecting it to the next
+ * level hypervisor.
+ */
+int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, struct kvm_s2_trans *trans)
+{
+	unsigned long fault_status = kvm_vcpu_trap_get_fault_type(vcpu);
+	bool forward_fault = false;
+
+	trans->esr = 0;
+
+	if (fault_status != FSC_PERM)
+		return 0;
+
+	if (kvm_vcpu_trap_is_iabt(vcpu)) {
+		forward_fault = (trans->upper_attr & BIT(54));
+	} else {
+		bool write_fault = kvm_is_write_fault(vcpu);
+
+		forward_fault = ((write_fault && !trans->writable) ||
+				 (!write_fault && !trans->readable));
+	}
+
+	if (forward_fault) {
+		trans->esr = esr_s2_fault(vcpu, trans->level, ESR_ELx_FSC_PERM);
+		return 1;
+	}
+
+	return 0;
+}
+
+int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2)
+{
+	vcpu_write_sys_reg(vcpu, vcpu->arch.fault.far_el2, FAR_EL2);
+	vcpu_write_sys_reg(vcpu, vcpu->arch.fault.hpfar_el2, HPFAR_EL2);
+
+	return kvm_inject_nested_sync(vcpu, esr_el2);
+}
+
 /*
  * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
  * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:40 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:40 +0000
Subject: [PATCH v6 32/64] KVM: arm64: nv: Filter out unsupported features from
 ID regs
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-33-maz@kernel.org>

As there is a number of features that we either can't support,
or don't want to support right away with NV, let's add some
basic filtering so that we don't advertize silly things to the
EL2 guest.

Whilst we are at it, advertize ARMv8.4-TTL as well as ARMv8.5-GTG.

Reviewed-by: Ganapatrao Kulkarni <gankulkarni at os.amperecomputing.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |   6 ++
 arch/arm64/kvm/nested.c             | 157 ++++++++++++++++++++++++++++
 arch/arm64/kvm/sys_regs.c           |   4 +-
 arch/arm64/kvm/sys_regs.h           |   2 +
 4 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 047ca700163b..7d398510fd9d 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -72,4 +72,10 @@ extern bool forward_traps(struct kvm_vcpu *vcpu, u64 control_bit);
 extern bool forward_nv_traps(struct kvm_vcpu *vcpu);
 extern bool forward_nv1_traps(struct kvm_vcpu *vcpu);
 
+struct sys_reg_params;
+struct sys_reg_desc;
+
+void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
+			  const struct sys_reg_desc *r);
+
 #endif /* __ARM64_KVM_NESTED_H */
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 5e1104f8e765..254152cd791e 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -8,6 +8,10 @@
 #include <linux/kvm_host.h>
 
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
+#include <asm/sysreg.h>
+
+#include "sys_regs.h"
 
 /*
  * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
@@ -26,3 +30,156 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
 
 	return -EINVAL;
 }
+
+/*
+ * Our emulated CPU doesn't support all the possible features. For the
+ * sake of simplicity (and probably mental sanity), wipe out a number
+ * of feature bits we don't intend to support for the time being.
+ * This list should get updated as new features get added to the NV
+ * support, and new extension to the architecture.
+ */
+void access_nested_id_reg(struct kvm_vcpu *v, struct sys_reg_params *p,
+			  const struct sys_reg_desc *r)
+{
+	u32 id = sys_reg((u32)r->Op0, (u32)r->Op1,
+			 (u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
+	u64 val, tmp;
+
+	if (!vcpu_has_nv(v))
+		return;
+
+	val = p->regval;
+
+	switch (id) {
+	case SYS_ID_AA64ISAR0_EL1:
+		/* Support everything but O.S. and Range TLBIs */
+		val &= ~(FEATURE(ID_AA64ISAR0_TLB)	|
+			 GENMASK_ULL(27, 24)		|
+			 GENMASK_ULL(3, 0));
+		break;
+
+	case SYS_ID_AA64ISAR1_EL1:
+		/* Support everything but PtrAuth and Spec Invalidation */
+		val &= ~(GENMASK_ULL(63, 56)		|
+			 FEATURE(ID_AA64ISAR1_SPECRES)	|
+			 FEATURE(ID_AA64ISAR1_GPI)	|
+			 FEATURE(ID_AA64ISAR1_GPA)	|
+			 FEATURE(ID_AA64ISAR1_API)	|
+			 FEATURE(ID_AA64ISAR1_APA));
+		break;
+
+	case SYS_ID_AA64PFR0_EL1:
+		/* No AMU, MPAM, S-EL2, RAS or SVE */
+		val &= ~(GENMASK_ULL(55, 52)		|
+			 FEATURE(ID_AA64PFR0_AMU)	|
+			 FEATURE(ID_AA64PFR0_MPAM)	|
+			 FEATURE(ID_AA64PFR0_SEL2)	|
+			 FEATURE(ID_AA64PFR0_RAS)	|
+			 FEATURE(ID_AA64PFR0_SVE)	|
+			 FEATURE(ID_AA64PFR0_EL3)	|
+			 FEATURE(ID_AA64PFR0_EL2));
+		/* 64bit EL2/EL3 only */
+		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL2), 0b0001);
+		val |= FIELD_PREP(FEATURE(ID_AA64PFR0_EL3), 0b0001);
+		break;
+
+	case SYS_ID_AA64PFR1_EL1:
+		/* Only support SSBS */
+		val &= FEATURE(ID_AA64PFR1_SSBS);
+		break;
+
+	case SYS_ID_AA64MMFR0_EL1:
+		/* Hide ECV, FGT, ExS, Secure Memory */
+		val &= ~(GENMASK_ULL(63, 43)			|
+			 FEATURE(ID_AA64MMFR0_TGRAN4_2)		|
+			 FEATURE(ID_AA64MMFR0_TGRAN16_2)	|
+			 FEATURE(ID_AA64MMFR0_TGRAN64_2)	|
+			 FEATURE(ID_AA64MMFR0_SNSMEM));
+
+		/* Disallow unsupported S2 page sizes */
+		switch (PAGE_SIZE) {
+		case SZ_64K:
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0001);
+			fallthrough;
+		case SZ_16K:
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0001);
+			fallthrough;
+		case SZ_4K:
+			/* Support everything */
+			break;
+		}
+		/*
+		 * Since we can't support a guest S2 page size smaller than
+		 * the host's own page size (due to KVM only populating its
+		 * own S2 using the kernel's page size), advertise the
+		 * limitation using FEAT_GTG.
+		 */
+		switch (PAGE_SIZE) {
+		case SZ_4K:
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN4_2), 0b0010);
+			fallthrough;
+		case SZ_16K:
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN16_2), 0b0010);
+			fallthrough;
+		case SZ_64K:
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_TGRAN64_2), 0b0010);
+			break;
+		}
+		/* Cap PARange to 40bits */
+		tmp = FIELD_GET(FEATURE(ID_AA64MMFR0_PARANGE), val);
+		if (tmp > 0b0010) {
+			val &= ~FEATURE(ID_AA64MMFR0_PARANGE);
+			val |= FIELD_PREP(FEATURE(ID_AA64MMFR0_PARANGE), 0b0010);
+		}
+		break;
+
+	case SYS_ID_AA64MMFR1_EL1:
+		val &= (FEATURE(ID_AA64MMFR1_PAN)	|
+			FEATURE(ID_AA64MMFR1_LOR)	|
+			FEATURE(ID_AA64MMFR1_HPD)	|
+			FEATURE(ID_AA64MMFR1_VHE)	|
+			FEATURE(ID_AA64MMFR1_VMIDBITS));
+		break;
+
+	case SYS_ID_AA64MMFR2_EL1:
+		val &= ~(FEATURE(ID_AA64MMFR2_EVT)	|
+			 FEATURE(ID_AA64MMFR2_BBM)	|
+			 FEATURE(ID_AA64MMFR2_TTL)	|
+			 GENMASK_ULL(47, 44)		|
+			 FEATURE(ID_AA64MMFR2_ST)	|
+			 FEATURE(ID_AA64MMFR2_CCIDX)	|
+			 FEATURE(ID_AA64MMFR2_LVA));
+
+		/* Force TTL support */
+		val |= FIELD_PREP(FEATURE(ID_AA64MMFR2_TTL), 0b0001);
+		break;
+
+	case SYS_ID_AA64DFR0_EL1:
+		/* Only limited support for PMU, Debug, BPs and WPs */
+		val &= (FEATURE(ID_AA64DFR0_PMSVER)	|
+			FEATURE(ID_AA64DFR0_WRPS)	|
+			FEATURE(ID_AA64DFR0_BRPS)	|
+			FEATURE(ID_AA64DFR0_DEBUGVER));
+
+		/* Cap PMU to ARMv8.1 */
+		tmp = FIELD_GET(FEATURE(ID_AA64DFR0_PMUVER), val);
+		if (tmp > 0b0100) {
+			val &= ~FEATURE(ID_AA64DFR0_PMUVER);
+			val |= FIELD_PREP(FEATURE(ID_AA64DFR0_PMUVER), 0b0100);
+		}
+		/* Cap Debug to ARMv8.1 */
+		tmp = FIELD_GET(FEATURE(ID_AA64DFR0_DEBUGVER), val);
+		if (tmp > 0b0111) {
+			val &= ~FEATURE(ID_AA64DFR0_DEBUGVER);
+			val |= FIELD_PREP(FEATURE(ID_AA64DFR0_DEBUGVER), 0b0111);
+		}
+		break;
+
+	default:
+		/* Unknown register, just wipe it clean */
+		val = 0;
+		break;
+	}
+
+	p->regval = val;
+}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 3e1f37c507a8..ebcdf2714b73 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1394,8 +1394,10 @@ static bool access_id_reg(struct kvm_vcpu *vcpu,
 			  const struct sys_reg_desc *r)
 {
 	bool raz = sysreg_visible_as_raz(vcpu, r);
+	bool ret = __access_id_reg(vcpu, p, r, raz);
 
-	return __access_id_reg(vcpu, p, r, raz);
+	access_nested_id_reg(vcpu, p, r);
+	return ret;
 }
 
 static bool access_raz_id_reg(struct kvm_vcpu *vcpu,
diff --git a/arch/arm64/kvm/sys_regs.h b/arch/arm64/kvm/sys_regs.h
index 850629f083a3..b82683224250 100644
--- a/arch/arm64/kvm/sys_regs.h
+++ b/arch/arm64/kvm/sys_regs.h
@@ -211,4 +211,6 @@ const struct sys_reg_desc *find_reg_by_id(u64 id,
 	CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)),	\
 	Op2(sys_reg_Op2(reg))
 
+#define FEATURE(x)	(GENMASK_ULL(x##_SHIFT + 3, x##_SHIFT))
+
 #endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:04 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:04 +0000
Subject: [PATCH v6 56/64] KVM: arm64: nv: Add include containing the VNCR_EL2
 offsets
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-57-maz@kernel.org>

VNCR_EL2 points to a page containing a number of system registers
accessed by a guest hypervisor when ARMv8.4-NV is enabled.

Let's document the offsets in that page, as we are going to use
this layout.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/vncr_mapping.h | 74 +++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 arch/arm64/include/asm/vncr_mapping.h

diff --git a/arch/arm64/include/asm/vncr_mapping.h b/arch/arm64/include/asm/vncr_mapping.h
new file mode 100644
index 000000000000..c0a2acd5045c
--- /dev/null
+++ b/arch/arm64/include/asm/vncr_mapping.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * System register offsets in the VNCR page
+ * All offsets are *byte* displacements!
+ */
+
+#ifndef __ARM64_VNCR_MAPPING_H__
+#define __ARM64_VNCR_MAPPING_H__
+
+#define VNCR_VTTBR_EL2          0x020
+#define VNCR_VTCR_EL2           0x040
+#define VNCR_VMPIDR_EL2         0x050
+#define VNCR_CNTVOFF_EL2        0x060
+#define VNCR_HCR_EL2            0x078
+#define VNCR_HSTR_EL2           0x080
+#define VNCR_VPIDR_EL2          0x088
+#define VNCR_TPIDR_EL2          0x090
+#define VNCR_VNCR_EL2           0x0B0
+#define VNCR_CPACR_EL1          0x100
+#define VNCR_CONTEXTIDR_EL1     0x108
+#define VNCR_SCTLR_EL1          0x110
+#define VNCR_ACTLR_EL1          0x118
+#define VNCR_TCR_EL1            0x120
+#define VNCR_AFSR0_EL1          0x128
+#define VNCR_AFSR1_EL1          0x130
+#define VNCR_ESR_EL1            0x138
+#define VNCR_MAIR_EL1           0x140
+#define VNCR_AMAIR_EL1          0x148
+#define VNCR_MDSCR_EL1          0x158
+#define VNCR_SPSR_EL1           0x160
+#define VNCR_CNTV_CVAL_EL0      0x168
+#define VNCR_CNTV_CTL_EL0       0x170
+#define VNCR_CNTP_CVAL_EL0      0x178
+#define VNCR_CNTP_CTL_EL0       0x180
+#define VNCR_SCXTNUM_EL1        0x188
+#define VNCR_TFSR_EL1		0x190
+#define VNCR_ZCR_EL1            0x1E0
+#define VNCR_TTBR0_EL1          0x200
+#define VNCR_TTBR1_EL1          0x210
+#define VNCR_FAR_EL1            0x220
+#define VNCR_ELR_EL1            0x230
+#define VNCR_SP_EL1             0x240
+#define VNCR_VBAR_EL1           0x250
+#define VNCR_ICH_LR0_EL2        0x400
+//      VNCR_ICH_LRN_EL2(n)     VNCR_ICH_LR0_EL2+8*((n) & 7)
+#define VNCR_ICH_AP0R0_EL2      0x480
+//      VNCR_ICH_AP0RN_EL2(n)   VNCR_ICH_AP0R0_EL2+8*((n) & 3)
+#define VNCR_ICH_AP1R0_EL2      0x4A0
+//      VNCR_ICH_AP1RN_EL2(n)   VNCR_ICH_AP1R0_EL2+8*((n) & 3)
+#define VNCR_ICH_HCR_EL2        0x4C0
+#define VNCR_ICH_VMCR_EL2       0x4C8
+#define VNCR_VDISR_EL2          0x500
+#define VNCR_PMBLIMITR_EL1      0x800
+#define VNCR_PMBPTR_EL1         0x810
+#define VNCR_PMBSR_EL1          0x820
+#define VNCR_PMSCR_EL1          0x828
+#define VNCR_PMSEVFR_EL1        0x830
+#define VNCR_PMSICR_EL1         0x838
+#define VNCR_PMSIRR_EL1         0x840
+#define VNCR_PMSLATFR_EL1       0x848
+#define VNCR_TRFCR_EL1          0x880
+#define VNCR_MPAM1_EL1          0x900
+#define VNCR_MPAMHCR_EL2        0x930
+#define VNCR_MPAMVPMV_EL2       0x938
+#define VNCR_MPAMVPM0_EL2       0x940
+#define VNCR_MPAMVPM1_EL2       0x948
+#define VNCR_MPAMVPM2_EL2       0x950
+#define VNCR_MPAMVPM3_EL2       0x958
+#define VNCR_MPAMVPM4_EL2       0x960
+#define VNCR_MPAMVPM5_EL2       0x968
+#define VNCR_MPAMVPM6_EL2       0x970
+#define VNCR_MPAMVPM7_EL2       0x978
+
+#endif /* __ARM64_VNCR_MAPPING_H__ */
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:11 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:11 +0000
Subject: [PATCH v6 63/64] KVM: arm64: nv: Fast-track 'InHost' exception returns
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-64-maz@kernel.org>

A significant part of the ARMv8.3-NV extension is to trap ERET
instructions so that the hypervisor gets a chance to switch
from a vEL2 L1 guest to an EL1 L2 guest.

But this also has the unfortunate consequence of trapping ERET
in unsuspecting circumstances, such as staying at vEL2 (interrupt
handling while being in the guest hypervisor), or returning to host
userspace in the case of a VHE guest.

Although we already make some effort to handle these ERET quicker
by not doing the put/load dance, it is still way too far down the
line for it to be efficient enough.

For these cases, it would ideal to ERET directly, no question asked.
Of course, we can't do that. But the next best thing is to do it as
early as possible, in fixup_guest_exit(), much as we would handle
FPSIMD exceptions.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 29 +++------------------
 arch/arm64/kvm/hyp/vhe/switch.c | 46 +++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 26 deletions(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 1f6cf8fe9fe3..3f3b1296b4ac 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -76,8 +76,7 @@ static u64 kvm_check_illegal_exception_return(struct kvm_vcpu *vcpu, u64 spsr)
 
 void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 {
-	u64 spsr, elr, mode;
-	bool direct_eret;
+	u64 spsr, elr;
 
 	/*
 	 * Forward this trap to the virtual EL2 if the virtual
@@ -86,33 +85,11 @@ void kvm_emulate_nested_eret(struct kvm_vcpu *vcpu)
 	if (forward_nv_traps(vcpu))
 		return;
 
-	/*
-	 * Going through the whole put/load motions is a waste of time
-	 * if this is a VHE guest hypervisor returning to its own
-	 * userspace, or the hypervisor performing a local exception
-	 * return. No need to save/restore registers, no need to
-	 * switch S2 MMU. Just do the canonical ERET.
-	 */
-	spsr = vcpu_read_sys_reg(vcpu, SPSR_EL2);
-	spsr = kvm_check_illegal_exception_return(vcpu, spsr);
-
-	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
-
-	direct_eret  = (mode == PSR_MODE_EL0t &&
-			vcpu_el2_e2h_is_set(vcpu) &&
-			vcpu_el2_tge_is_set(vcpu));
-	direct_eret |= (mode == PSR_MODE_EL2h || mode == PSR_MODE_EL2t);
-
-	if (direct_eret) {
-		*vcpu_pc(vcpu) = vcpu_read_sys_reg(vcpu, ELR_EL2);
-		*vcpu_cpsr(vcpu) = spsr;
-		trace_kvm_nested_eret(vcpu, *vcpu_pc(vcpu), spsr);
-		return;
-	}
-
 	preempt_disable();
 	kvm_arch_vcpu_put(vcpu);
 
+	spsr = __vcpu_sys_reg(vcpu, SPSR_EL2);
+	spsr = kvm_check_illegal_exception_return(vcpu, spsr);
 	elr = __vcpu_sys_reg(vcpu, ELR_EL2);
 
 	trace_kvm_nested_eret(vcpu, elr, spsr);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 65120c9027d6..f469bf51b4be 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -161,6 +161,51 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
 	__deactivate_traps_common(vcpu);
 }
 
+static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
+{
+	struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+	u64 spsr, mode;
+
+	/*
+	 * Going through the whole put/load motions is a waste of time
+	 * if this is a VHE guest hypervisor returning to its own
+	 * userspace, or the hypervisor performing a local exception
+	 * return. No need to save/restore registers, no need to
+	 * switch S2 MMU. Just do the canonical ERET.
+	 *
+	 * Unless the trap has to be forwarded further down the line,
+	 * of course...
+	 */
+	if (__vcpu_sys_reg(vcpu, HCR_EL2) & HCR_NV)
+		return false;
+
+	spsr = read_sysreg_el1(SYS_SPSR);
+	spsr = __fixup_spsr_el2_read(ctxt, spsr);
+	mode = spsr & (PSR_MODE_MASK | PSR_MODE32_BIT);
+
+	switch (mode) {
+	case PSR_MODE_EL0t:
+		if (!(vcpu_el2_e2h_is_set(vcpu) && vcpu_el2_tge_is_set(vcpu)))
+			return false;
+		break;
+	case PSR_MODE_EL2t:
+		mode = PSR_MODE_EL1t;
+		break;
+	case PSR_MODE_EL2h:
+		mode = PSR_MODE_EL1h;
+		break;
+	default:
+		return false;
+	}
+
+	spsr = (spsr & ~(PSR_MODE_MASK | PSR_MODE32_BIT)) | mode;
+
+	write_sysreg_el2(spsr, SYS_SPSR);
+	write_sysreg_el2(read_sysreg_el1(SYS_ELR), SYS_ELR);
+
+	return true;
+}
+
 static const exit_handler_fn hyp_exit_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= NULL,
 	[ESR_ELx_EC_CP15_32]		= kvm_hyp_handle_cp15_32,
@@ -170,6 +215,7 @@ static const exit_handler_fn hyp_exit_handlers[] = {
 	[ESR_ELx_EC_IABT_LOW]		= kvm_hyp_handle_iabt_low,
 	[ESR_ELx_EC_DABT_LOW]		= kvm_hyp_handle_dabt_low,
 	[ESR_ELx_EC_PAC]		= kvm_hyp_handle_ptrauth,
+	[ESR_ELx_EC_ERET]		= kvm_hyp_handle_eret,
 };
 
 static const exit_handler_fn *kvm_get_exit_handler_array(struct kvm_vcpu *vcpu)
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:50 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:50 +0000
Subject: [PATCH v6 42/64] KVM: arm64: nv: Fold guest's HCR_EL2 configuration
 into the host's
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-43-maz@kernel.org>

When entering a L2 guest (nested virt enabled, but not in hypervisor
context), we need to honor the traps the L1 guest has asked enabled.

For now, just OR the guest's HCR_EL2 into the host's. We may have to do
some filtering in the future though.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/hyp/vhe/switch.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 0e164cc8e913..5e8eafac27c6 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -78,6 +78,11 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 			if (!vcpu_el2_tge_is_set(vcpu))
 				hcr |= HCR_AT | HCR_TTLB;
 		}
+	} else if (vcpu_has_nv(vcpu)) {
+		u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+
+		vhcr_el2 &= ~HCR_GUEST_NV_FILTER_FLAGS;
+		hcr |= vhcr_el2;
 	}
 
 	___activate_traps(vcpu, hcr);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:42 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:42 +0000
Subject: [PATCH v6 34/64] KVM: arm64: nv: Support multiple nested Stage-2 mmu
 structures
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-35-maz@kernel.org>

Add Stage-2 mmu data structures for virtual EL2 and for nested guests.
We don't yet populate shadow Stage-2 page tables, but we now have a
framework for getting to a shadow Stage-2 pgd.

We allocate twice the number of vcpus as Stage-2 mmu structures because
that's sufficient for each vcpu running two translation regimes without
having to flush the Stage-2 page tables.

Co-developed-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h   |  29 +++++
 arch/arm64/include/asm/kvm_mmu.h    |   9 ++
 arch/arm64/include/asm/kvm_nested.h |   7 +
 arch/arm64/kvm/arm.c                |  16 ++-
 arch/arm64/kvm/mmu.c                |  29 +++--
 arch/arm64/kvm/nested.c             | 195 ++++++++++++++++++++++++++++
 6 files changed, 275 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index fa253f08e0fd..a15183d0e1bf 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -101,14 +101,43 @@ struct kvm_s2_mmu {
 	int __percpu *last_vcpu_ran;
 
 	struct kvm_arch *arch;
+
+	/*
+	 * For a shadow stage-2 MMU, the virtual vttbr programmed by the guest
+	 * hypervisor.  Unused for kvm_arch->mmu. Set to 1 when the structure
+	 * contains no valid information.
+	 */
+	u64	vttbr;
+
+	/* true when this represents a nested context where virtual HCR_EL2.VM == 1 */
+	bool	nested_stage2_enabled;
+
+	/*
+	 *  0: Nobody is currently using this, check vttbr for validity
+	 * >0: Somebody is actively using this.
+	 */
+	atomic_t refcnt;
 };
 
+static inline bool kvm_s2_mmu_valid(struct kvm_s2_mmu *mmu)
+{
+	return !(mmu->vttbr & 1);
+}
+
 struct kvm_arch_memory_slot {
 };
 
 struct kvm_arch {
 	struct kvm_s2_mmu mmu;
 
+	/*
+	 * Stage 2 paging stage for VMs with nested virtual using a virtual
+	 * VMID.
+	 */
+	struct kvm_s2_mmu *nested_mmus;
+	size_t nested_mmus_size;
+	int nested_mmus_next;
+
 	/* VTCR_EL2 value for this VM */
 	u64    vtcr;
 
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index 1b314b2a69bc..0750d022bbf8 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -116,6 +116,7 @@ alternative_cb_end
 #include <asm/cacheflush.h>
 #include <asm/mmu_context.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_nested.h>
 
 void kvm_update_va_mask(struct alt_instr *alt,
 			__le32 *origptr, __le32 *updptr, int nr_inst);
@@ -161,6 +162,7 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
 			     void **haddr);
 void free_hyp_pgds(void);
 
+void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size);
 void stage2_unmap_vm(struct kvm *kvm);
 int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu);
 void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
@@ -296,5 +298,12 @@ static inline struct kvm *kvm_s2_mmu_to_kvm(struct kvm_s2_mmu *mmu)
 {
 	return container_of(mmu->arch, struct kvm, arch);
 }
+
+static inline u64 get_vmid(u64 vttbr)
+{
+	return (vttbr & VTTBR_VMID_MASK(kvm_get_vmid_bits())) >>
+		VTTBR_VMID_SHIFT;
+}
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ARM64_KVM_MMU_H__ */
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 7d398510fd9d..8bb7159f2b6b 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -65,6 +65,13 @@ static inline u64 translate_cnthctl_el2_to_cntkctl_el1(u64 cnthctl)
 		(cnthctl & (CNTHCTL_EVNTI | CNTHCTL_EVNTDIR | CNTHCTL_EVNTEN)));
 }
 
+extern void kvm_init_nested(struct kvm *kvm);
+extern int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu);
+extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
+extern struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr);
+extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
+extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
+
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 			    u64 control_bit);
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 06ca11e90482..14f85f1e15b2 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -37,6 +37,7 @@
 #include <asm/kvm_arm.h>
 #include <asm/kvm_asm.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/kvm_emulate.h>
 #include <asm/sections.h>
 
@@ -146,6 +147,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
 	if (ret)
 		return ret;
 
+	kvm_init_nested(kvm);
+
 	ret = kvm_share_hyp(kvm, kvm + 1);
 	if (ret)
 		goto out_free_stage2_pgd;
@@ -375,6 +378,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 	struct kvm_s2_mmu *mmu;
 	int *last_ran;
 
+	if (vcpu_has_nv(vcpu))
+		kvm_vcpu_load_hw_mmu(vcpu);
+
 	mmu = vcpu->arch.hw_mmu;
 	last_ran = this_cpu_ptr(mmu->last_vcpu_ran);
 
@@ -423,6 +429,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 	kvm_vgic_put(vcpu);
 	kvm_vcpu_pmu_restore_host(vcpu);
 
+	if (vcpu_has_nv(vcpu))
+		kvm_vcpu_put_hw_mmu(vcpu);
+
 	vcpu->cpu = -1;
 }
 
@@ -1122,8 +1131,13 @@ static int kvm_vcpu_set_target(struct kvm_vcpu *vcpu,
 
 	vcpu->arch.target = phys_target;
 
+	/* Prepare for nested if required */
+	ret = kvm_vcpu_init_nested(vcpu);
+
 	/* Now we know what it is, we can reset it. */
-	ret = kvm_reset_vcpu(vcpu);
+	if (!ret)
+		ret = kvm_reset_vcpu(vcpu);
+
 	if (ret) {
 		vcpu->arch.target = -1;
 		bitmap_zero(vcpu->arch.features, KVM_VCPU_MAX_FEATURES);
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index bc2aba953299..55525fd5743d 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -162,7 +162,7 @@ static void invalidate_icache_guest_page(void *va, size_t size)
  * does.
  */
 /**
- * unmap_stage2_range -- Clear stage2 page table entries to unmap a range
+ * __unmap_stage2_range -- Clear stage2 page table entries to unmap a range
  * @mmu:   The KVM stage-2 MMU pointer
  * @start: The intermediate physical base address of the range to unmap
  * @size:  The size of the area to unmap
@@ -185,7 +185,7 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64
 				   may_block));
 }
 
-static void unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
+void kvm_unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size)
 {
 	__unmap_stage2_range(mmu, start, size, true);
 }
@@ -628,7 +628,20 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
 	int cpu, err;
 	struct kvm_pgtable *pgt;
 
+	/*
+	 * If we already have our page tables in place, and that the
+	 * MMU context is the canonical one, we have a bug somewhere,
+	 * as this is only supposed to ever happen once per VM.
+	 *
+	 * Otherwise, we're building nested page tables, and that's
+	 * probably because userspace called KVM_ARM_VCPU_INIT more
+	 * than once on the same vcpu. Since that's actually legal,
+	 * don't kick a fuss and leave gracefully.
+	 */
 	if (mmu->pgt != NULL) {
+		if (&kvm->arch.mmu != mmu)
+			return 0;
+
 		kvm_err("kvm_arch already initialized?\n");
 		return -EINVAL;
 	}
@@ -654,6 +667,9 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
 	mmu->pgt = pgt;
 	mmu->pgd_phys = __pa(pgt->pgd);
 	WRITE_ONCE(mmu->vmid.vmid_gen, 0);
+
+	kvm_init_nested_s2_mmu(mmu);
+
 	return 0;
 
 out_destroy_pgtable:
@@ -699,7 +715,7 @@ static void stage2_unmap_memslot(struct kvm *kvm,
 
 		if (!(vma->vm_flags & VM_PFNMAP)) {
 			gpa_t gpa = addr + (vm_start - memslot->userspace_addr);
-			unmap_stage2_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
+			kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, vm_end - vm_start);
 		}
 		hva = vm_end;
 	} while (hva < reg_end);
@@ -1681,11 +1697,6 @@ void kvm_arch_memslots_updated(struct kvm *kvm, u64 gen)
 {
 }
 
-void kvm_arch_flush_shadow_all(struct kvm *kvm)
-{
-	kvm_free_stage2_pgd(&kvm->arch.mmu);
-}
-
 void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 				   struct kvm_memory_slot *slot)
 {
@@ -1693,7 +1704,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
 	phys_addr_t size = slot->npages << PAGE_SHIFT;
 
 	spin_lock(&kvm->mmu_lock);
-	unmap_stage2_range(&kvm->arch.mmu, gpa, size);
+	kvm_unmap_stage2_range(&kvm->arch.mmu, gpa, size);
 	spin_unlock(&kvm->mmu_lock);
 }
 
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 254152cd791e..bfa2b9229173 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -7,12 +7,189 @@
 #include <linux/kvm.h>
 #include <linux/kvm_host.h>
 
+#include <asm/kvm_arm.h>
 #include <asm/kvm_emulate.h>
+#include <asm/kvm_mmu.h>
 #include <asm/kvm_nested.h>
 #include <asm/sysreg.h>
 
 #include "sys_regs.h"
 
+void kvm_init_nested(struct kvm *kvm)
+{
+	kvm->arch.nested_mmus = NULL;
+	kvm->arch.nested_mmus_size = 0;
+}
+
+int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	struct kvm_s2_mmu *tmp;
+	int num_mmus;
+	int ret = -ENOMEM;
+
+	if (!test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features))
+		return 0;
+
+	if (!cpus_have_final_cap(ARM64_HAS_NESTED_VIRT))
+		return -EINVAL;
+
+	mutex_lock(&kvm->lock);
+
+	/*
+	 * Let's treat memory allocation failures as benign: If we fail to
+	 * allocate anything, return an error and keep the allocated array
+	 * alive. Userspace may try to recover by intializing the vcpu
+	 * again, and there is no reason to affect the whole VM for this.
+	 */
+	num_mmus = atomic_read(&kvm->online_vcpus) * 2;
+	tmp = krealloc(kvm->arch.nested_mmus,
+		       num_mmus * sizeof(*kvm->arch.nested_mmus),
+		       GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+	if (tmp) {
+		/*
+		 * If we went through a realocation, adjust the MMU
+		 * back-pointers in the previously initialised
+		 * pg_table structures.
+		 */
+		if (kvm->arch.nested_mmus != tmp) {
+			int i;
+
+			for (i = 0; i < num_mmus - 2; i++)
+				tmp[i].pgt->mmu = &tmp[i];
+		}
+
+		if (kvm_init_stage2_mmu(kvm, &tmp[num_mmus - 1]) ||
+		    kvm_init_stage2_mmu(kvm, &tmp[num_mmus - 2])) {
+			kvm_free_stage2_pgd(&tmp[num_mmus - 1]);
+			kvm_free_stage2_pgd(&tmp[num_mmus - 2]);
+		} else {
+			kvm->arch.nested_mmus_size = num_mmus;
+			ret = 0;
+		}
+
+		kvm->arch.nested_mmus = tmp;
+	}
+
+	mutex_unlock(&kvm->lock);
+	return ret;
+}
+
+/* Must be called with kvm->lock held */
+struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
+{
+	bool nested_stage2_enabled = hcr & HCR_VM;
+	int i;
+
+	/* Don't consider the CnP bit for the vttbr match */
+	vttbr = vttbr & ~VTTBR_CNP_BIT;
+
+	/*
+	 * Two possibilities when looking up a S2 MMU context:
+	 *
+	 * - either S2 is enabled in the guest, and we need a context that
+         *   is S2-enabled and matches the full VTTBR (VMID+BADDR), which
+         *   makes it safe from a TLB conflict perspective (a broken guest
+         *   won't be able to generate them),
+	 *
+	 * - or S2 is disabled, and we need a context that is S2-disabled
+         *   and matches the VMID only, as all TLBs are tagged by VMID even
+         *   if S2 translation is disabled.
+	 */
+	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+		if (!kvm_s2_mmu_valid(mmu))
+			continue;
+
+		if (nested_stage2_enabled &&
+		    mmu->nested_stage2_enabled &&
+		    vttbr == mmu->vttbr)
+			return mmu;
+
+		if (!nested_stage2_enabled &&
+		    !mmu->nested_stage2_enabled &&
+		    get_vmid(vttbr) == get_vmid(mmu->vttbr))
+			return mmu;
+	}
+	return NULL;
+}
+
+static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu)
+{
+	struct kvm *kvm = vcpu->kvm;
+	u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+	u64 hcr= vcpu_read_sys_reg(vcpu, HCR_EL2);
+	struct kvm_s2_mmu *s2_mmu;
+	int i;
+
+	s2_mmu = lookup_s2_mmu(kvm, vttbr, hcr);
+	if (s2_mmu)
+		goto out;
+
+	/*
+	 * Make sure we don't always search from the same point, or we
+	 * will always reuse a potentially active context, leaving
+	 * free contexts unused.
+	 */
+	for (i = kvm->arch.nested_mmus_next;
+	     i < (kvm->arch.nested_mmus_size + kvm->arch.nested_mmus_next);
+	     i++) {
+		s2_mmu = &kvm->arch.nested_mmus[i % kvm->arch.nested_mmus_size];
+
+		if (atomic_read(&s2_mmu->refcnt) == 0)
+			break;
+	}
+	BUG_ON(atomic_read(&s2_mmu->refcnt)); /* We have struct MMUs to spare */
+
+	/* Set the scene for the next search */
+	kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size;
+
+	if (kvm_s2_mmu_valid(s2_mmu)) {
+		/* Clear the old state */
+		kvm_unmap_stage2_range(s2_mmu, 0, kvm_phys_size(kvm));
+		if (s2_mmu->vmid.vmid_gen)
+			kvm_call_hyp(__kvm_tlb_flush_vmid, s2_mmu);
+	}
+
+	/*
+	 * The virtual VMID (modulo CnP) will be used as a key when matching
+	 * an existing kvm_s2_mmu.
+	 */
+	s2_mmu->vttbr = vttbr & ~VTTBR_CNP_BIT;
+	s2_mmu->nested_stage2_enabled = hcr & HCR_VM;
+
+out:
+	atomic_inc(&s2_mmu->refcnt);
+	return s2_mmu;
+}
+
+void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu)
+{
+	mmu->vttbr = 1;
+	mmu->nested_stage2_enabled = false;
+	atomic_set(&mmu->refcnt, 0);
+}
+
+void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu)
+{
+	if (is_hyp_ctxt(vcpu)) {
+		vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
+	} else {
+		spin_lock(&vcpu->kvm->mmu_lock);
+		vcpu->arch.hw_mmu = get_s2_mmu_nested(vcpu);
+		spin_unlock(&vcpu->kvm->mmu_lock);
+	}
+}
+
+void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu)
+{
+	if (vcpu->arch.hw_mmu != &vcpu->kvm->arch.mmu) {
+		atomic_dec(&vcpu->arch.hw_mmu->refcnt);
+		vcpu->arch.hw_mmu = NULL;
+	}
+}
+
 /*
  * Inject wfx to the virtual EL2 if this is not from the virtual EL2 and
  * the virtual HCR_EL2.TWX is set. Otherwise, let the host hypervisor
@@ -31,6 +208,24 @@ int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe)
 	return -EINVAL;
 }
 
+void kvm_arch_flush_shadow_all(struct kvm *kvm)
+{
+	int i;
+
+	for (i = 0; i < kvm->arch.nested_mmus_size; i++) {
+		struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i];
+
+		WARN_ON(atomic_read(&mmu->refcnt));
+
+		if (!atomic_read(&mmu->refcnt))
+			kvm_free_stage2_pgd(mmu);
+	}
+	kfree(kvm->arch.nested_mmus);
+	kvm->arch.nested_mmus = NULL;
+	kvm->arch.nested_mmus_size = 0;
+	kvm_free_stage2_pgd(&kvm->arch.mmu);
+}
+
 /*
  * Our emulated CPU doesn't support all the possible features. For the
  * sake of simplicity (and probably mental sanity), wipe out a number
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:49 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:49 +0000
Subject: [PATCH v6 41/64] KVM: arm64: nv: Trap and emulate TLBI instructions
 from virtual EL2
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-42-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

When supporting nested virtualization a guest hypervisor executing TLBI
instructions must be trapped and emulated by the host hypervisor,
because the guest hypervisor can only affect physical TLB entries
relating to its own execution environment (virtual EL2 in EL1) but not
to the nested guests as required by the semantics of the instructions
and TLBI instructions might also result in updates (invalidations) to
shadow page tables.

This patch does several things.

1. List and define all TLBI system instructions to emulate.

2. Emulate TLBI ALLE2(IS) instruction executed in the virtual EL2. Since
we emulate the virtual EL2 in the EL1, we invalidate EL1&0 regime stage
1 TLB entries with setting vttbr_el2 having the VMID of the virtual EL2.

3. Emulate TLBI VAE2* instruction executed in the virtual EL2. Based on the
same principle as TLBI ALLE2 instruction, we can simply emulate those
instructions by executing corresponding VAE1* instructions with the
virtual EL2's VMID assigned by the host hypervisor.

Note that we are able to emulate TLBI ALLE2IS precisely by only
invalidating stage 1 TLB entries via TLBI VMALL1IS instruction, but to
make it simeple, we reuse the existing function, __kvm_tlb_flush_vmid(),
which invalidates both of stage 1 and 2 TLB entries.

4. TLBI ALLE1(IS) instruction invalidates all EL1&0 regime stage 1 and 2
TLB entries (on all PEs in the same Inner Shareable domain). To emulate
these instructions, we first need to clear all the mappings in the
shadow page tables since executing those instructions implies the change
of mappings in the stage 2 page tables maintained by the guest
hypervisor.  We then need to invalidate all EL1&0 regime stage 1 and 2
TLB entries of all VMIDs, which are assigned by the host hypervisor, for
this VM.

5. Based on the same principle as TLBI ALLE1(IS) emulation, we clear the
mappings in the shadow stage-2 page tables and invalidate TLB entries.
But this time we do it only for the current VMID from the guest
hypervisor's perspective, not for all VMIDs.

6. Based on the same principle as TLBI ALLE1(IS) and TLBI VMALLS12E1(IS)
emulation, we clear the mappings in the shadow stage-2 page tables and
invalidate TLB entries. We do it only for one mapping for the current
VMID from the guest hypervisor's view.

7. Forward system instruction traps to the virtual EL2 if a
corresponding bit in the virtual HCR_EL2 is set.

8. Even though a guest hypervisor can execute TLBI instructions that are
accesible at EL1 without trap, it's wrong; All those TLBI instructions
work based on current VMID, and when running a guest hypervisor current
VMID is the one for itself, not the one from the virtual vttbr_el2. So
letting a guest hypervisor execute those TLBI instructions results in
invalidating its own TLB entries and leaving invalid TLB entries
unhandled.

Therefore we trap and emulate those TLBI instructions. The emulation is
simple; we find a shadow VMID mapped to the virtual vttbr_el2, set it in
the physical vttbr_el2, then execute the same instruction in EL2.

We don't set HCR_EL2.TTLB bit yet.

  [ Changes performed by Marc Zynger:

    The TLBI handling code more or less directly execute the same
    instruction that has been trapped (with an EL2->EL1 conversion
    in the case of an EL2 TLBI), but that's unfortunately not enough:

    - TLBIs must be upgraded to the Inner Shareable domain to account
      for vcpu migration, just like we already have with HCR_EL2.FB.

    - The DSB instruction that synchronises these must thus be on
      the Inner Shareable domain as well.

    - Prior to executing the TLBI, we need another DSB ISHST to make
      sure that the update to the page tables is now visible.

      Ordering of system instructions fixed

    - The current TLB invalidation code is pretty buggy, as it assume a
      page mapping. On the contrary, it is likely that TLB invalidation
      will cover more than a single page, and the size should be decided
      by the guests configuration (and not the host's).

      Since we don't cache the guest mapping sizes in the shadow PT yet,
      let's assume the worse case (a block mapping) and invalidate that.

      Take this opportunity to fix the decoding of the parameter (it
      isn't a straight IPA).

    - In general, we always emulate local TBL invalidations as being
      as upgraded to the Inner Shareable domain so that we can easily
      deal with vcpu migration. This is consistent with the fact that
      we set HCR_EL2.FB when running non-nested VMs.

      So let's emulate TLBI ALLE2 as ALLE2IS.
  ]

  [ Changes performed by Christoffer Dall:

    Sometimes when we are invalidating the TLB for a certain S2 MMU
    context, this context can also have EL2 context associated with it
    and we have to invalidate this too.
  ]

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_asm.h |   2 +
 arch/arm64/include/asm/sysreg.h  |  36 +++++
 arch/arm64/kvm/hyp/vhe/switch.c  |   8 +-
 arch/arm64/kvm/hyp/vhe/tlb.c     |  81 +++++++++++
 arch/arm64/kvm/mmu.c             |  19 ++-
 arch/arm64/kvm/sys_regs.c        | 227 +++++++++++++++++++++++++++++++
 6 files changed, 368 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index e22861ece3c3..64ddbecab241 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -206,6 +206,8 @@ extern void __kvm_flush_cpu_context(struct kvm_s2_mmu *mmu);
 extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
 				     int level);
 extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
+extern void __kvm_tlb_vae2is(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);
+extern void __kvm_tlb_el1_instr(struct kvm_s2_mmu *mmu, u64 val, u64 sys_encoding);
 
 extern void __kvm_timer_set_cntvoff(u64 cntvoff);
 extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index ea17d1eabfc5..41c3603a3f29 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -675,6 +675,42 @@
 #define OP_AT_S12E0R	sys_insn(AT_Op0, 4, AT_CRn, 8, 6)
 #define OP_AT_S12E0W	sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
 
+/* TLBI instructions */
+#define TLBI_Op0	1
+#define TLBI_Op1_EL1	0	/* Accessible from EL1 or higher */
+#define TLBI_Op1_EL2	4	/* Accessible from EL2 or higher */
+#define TLBI_CRn	8
+#define tlbi_insn_el1(CRm, Op2)	sys_insn(TLBI_Op0, TLBI_Op1_EL1, TLBI_CRn, (CRm), (Op2))
+#define tlbi_insn_el2(CRm, Op2)	sys_insn(TLBI_Op0, TLBI_Op1_EL2, TLBI_CRn, (CRm), (Op2))
+
+#define OP_TLBI_VMALLE1IS	tlbi_insn_el1(3, 0)
+#define OP_TLBI_VAE1IS		tlbi_insn_el1(3, 1)
+#define OP_TLBI_ASIDE1IS	tlbi_insn_el1(3, 2)
+#define OP_TLBI_VAAE1IS		tlbi_insn_el1(3, 3)
+#define OP_TLBI_VALE1IS		tlbi_insn_el1(3, 5)
+#define OP_TLBI_VAALE1IS	tlbi_insn_el1(3, 7)
+#define OP_TLBI_VMALLE1		tlbi_insn_el1(7, 0)
+#define OP_TLBI_VAE1		tlbi_insn_el1(7, 1)
+#define OP_TLBI_ASIDE1		tlbi_insn_el1(7, 2)
+#define OP_TLBI_VAAE1		tlbi_insn_el1(7, 3)
+#define OP_TLBI_VALE1		tlbi_insn_el1(7, 5)
+#define OP_TLBI_VAALE1		tlbi_insn_el1(7, 7)
+
+#define OP_TLBI_IPAS2E1IS	tlbi_insn_el2(0, 1)
+#define OP_TLBI_IPAS2LE1IS	tlbi_insn_el2(0, 5)
+#define OP_TLBI_ALLE2IS		tlbi_insn_el2(3, 0)
+#define OP_TLBI_VAE2IS		tlbi_insn_el2(3, 1)
+#define OP_TLBI_ALLE1IS		tlbi_insn_el2(3, 4)
+#define OP_TLBI_VALE2IS		tlbi_insn_el2(3, 5)
+#define OP_TLBI_VMALLS12E1IS	tlbi_insn_el2(3, 6)
+#define OP_TLBI_IPAS2E1		tlbi_insn_el2(4, 1)
+#define OP_TLBI_IPAS2LE1	tlbi_insn_el2(4, 5)
+#define OP_TLBI_ALLE2		tlbi_insn_el2(7, 0)
+#define OP_TLBI_VAE2		tlbi_insn_el2(7, 1)
+#define OP_TLBI_ALLE1		tlbi_insn_el2(7, 4)
+#define OP_TLBI_VALE2		tlbi_insn_el2(7, 5)
+#define OP_TLBI_VMALLS12E1	tlbi_insn_el2(7, 6)
+
 /* Common SCTLR_ELx flags. */
 #define SCTLR_ELx_DSSBS	(BIT(44))
 #define SCTLR_ELx_ATA	(BIT(43))
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index b7790d3c4122..0e164cc8e913 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -44,7 +44,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 			 * the EL1 virtual memory control register accesses
 			 * as well as the AT S1 operations.
 			 */
-			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_NV1;
+			hcr |= HCR_TVM | HCR_TRVM | HCR_AT | HCR_TTLB | HCR_NV1;
 		} else {
 			/*
 			 * For a guest hypervisor on v8.1 (VHE), allow to
@@ -72,11 +72,11 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 
 			/*
 			 * If we're using the EL1 translation regime
-			 * (TGE clear), then ensure that AT S1 ops are
-			 * trapped too.
+			 * (TGE clear), then ensure that AT S1 and
+			 * TLBI E1 ops are trapped too.
 			 */
 			if (!vcpu_el2_tge_is_set(vcpu))
-				hcr |= HCR_AT;
+				hcr |= HCR_AT | HCR_TTLB;
 		}
 	}
 
diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c
index 24cef9b87f9e..c4389db4cc22 100644
--- a/arch/arm64/kvm/hyp/vhe/tlb.c
+++ b/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -161,3 +161,84 @@ void __kvm_flush_vm_context(void)
 
 	dsb(ish);
 }
+
+void __kvm_tlb_vae2is(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding)
+{
+	struct tlb_inv_context cxt;
+
+	dsb(ishst);
+
+	/* Switch to requested VMID */
+	__tlb_switch_to_guest(mmu, &cxt);
+
+	/*
+	 * Execute the EL1 version of TLBI VAE2* instruction, forcing
+	 * an upgrade to the Inner Shareable domain in order to
+	 * perform the invalidation on all CPUs.
+	 */
+	switch (sys_encoding) {
+	case OP_TLBI_VAE2:
+	case OP_TLBI_VAE2IS:
+		__tlbi(vae1is, va);
+		break;
+	case OP_TLBI_VALE2:
+	case OP_TLBI_VALE2IS:
+		__tlbi(vale1is, va);
+		break;
+	default:
+		break;
+	}
+	dsb(ish);
+	isb();
+
+	__tlb_switch_to_host(&cxt);
+}
+
+void __kvm_tlb_el1_instr(struct kvm_s2_mmu *mmu, u64 val, u64 sys_encoding)
+{
+	struct tlb_inv_context cxt;
+
+	dsb(ishst);
+
+	/* Switch to requested VMID */
+	__tlb_switch_to_guest(mmu, &cxt);
+
+	/*
+	 * Execute the same instruction as the guest hypervisor did,
+	 * expanding the scope of local TLB invalidations to the Inner
+	 * Shareable domain so that it takes place on all CPUs. This
+	 * is equivalent to having HCR_EL2.FB set.
+	 */
+	switch (sys_encoding) {
+	case OP_TLBI_VMALLE1:
+	case OP_TLBI_VMALLE1IS:
+		__tlbi(vmalle1is);
+		break;
+	case OP_TLBI_VAE1:
+	case OP_TLBI_VAE1IS:
+		__tlbi(vae1is, val);
+		break;
+	case OP_TLBI_ASIDE1:
+	case OP_TLBI_ASIDE1IS:
+		__tlbi(aside1is, val);
+		break;
+	case OP_TLBI_VAAE1:
+	case OP_TLBI_VAAE1IS:
+		__tlbi(vaae1is, val);
+		break;
+	case OP_TLBI_VALE1:
+	case OP_TLBI_VALE1IS:
+		__tlbi(vale1is, val);
+		break;
+	case OP_TLBI_VAALE1:
+	case OP_TLBI_VAALE1IS:
+		__tlbi(vaale1is, val);
+		break;
+	default:
+		break;
+	}
+	dsb(ish);
+	isb();
+
+	__tlb_switch_to_host(&cxt);
+}
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index b9b11be65009..4b38f2f3c997 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -80,8 +80,25 @@ static bool memslot_is_logging(struct kvm_memory_slot *memslot)
  */
 void kvm_flush_remote_tlbs(struct kvm *kvm)
 {
+	struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
+
 	++kvm->stat.generic.remote_tlb_flush_requests;
-	kvm_call_hyp(__kvm_tlb_flush_vmid, &kvm->arch.mmu);
+
+	if (mmu == &kvm->arch.mmu) {
+		/*
+		 * For a normal (i.e. non-nested) guest, flush entries for the
+		 * given VMID *
+		 */
+		kvm_call_hyp(__kvm_tlb_flush_vmid, mmu);
+	} else {
+		/*
+		 * When supporting nested virtualization, we can have multiple
+		 * VMIDs in play for each VCPU in the VM, so it's really not
+		 * worth it to try to quiesce the system and flush all the
+		 * VMIDs that may be in use, instead just nuke the whole thing.
+		 */
+		kvm_call_hyp(__kvm_flush_vm_context);
+	}
 }
 
 static bool kvm_is_device_pfn(unsigned long pfn)
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index 7be57e1b7019..d7441b8ba406 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2374,6 +2374,205 @@ static bool handle_s12w(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
 	return handle_s12(vcpu, p, r, true);
 }
 
+static bool handle_alle2is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	/*
+	 * To emulate invalidating all EL2 regime stage 1 TLB entries for all
+	 * PEs, executing TLBI VMALLE1IS is enough. But reuse the existing
+	 * interface for the simplicity; invalidating stage 2 entries doesn't
+	 * affect the correctness.
+	 */
+	__kvm_tlb_flush_vmid(&vcpu->kvm->arch.mmu);
+	return true;
+}
+
+static bool handle_vae2is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			  const struct sys_reg_desc *r)
+{
+	int sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	/*
+	 * Based on the same principle as TLBI ALLE2 instruction
+	 * emulation, we emulate TLBI VAE2* instructions by executing
+	 * corresponding TLBI VAE1* instructions with the virtual
+	 * EL2's VMID assigned by the host hypervisor.
+	 */
+	__kvm_tlb_vae2is(&vcpu->kvm->arch.mmu, p->regval, sys_encoding);
+	return true;
+}
+
+static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	struct kvm_s2_mmu *mmu = &vcpu->kvm->arch.mmu;
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	spin_lock(&vcpu->kvm->mmu_lock);
+
+	/*
+	 * Clear all mappings in the shadow page tables and invalidate the stage
+	 * 1 and 2 TLB entries via kvm_tlb_flush_vmid_ipa().
+	 */
+	kvm_nested_s2_clear(vcpu->kvm);
+
+	if (mmu->vmid.vmid_gen) {
+		/*
+		 * Invalidate the stage 1 and 2 TLB entries for the host OS
+		 * in a VM only if there is one.
+		 */
+		__kvm_tlb_flush_vmid(mmu);
+	}
+
+	spin_unlock(&vcpu->kvm->mmu_lock);
+
+	return true;
+}
+
+static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+				const struct sys_reg_desc *r)
+{
+	struct kvm_s2_mmu *mmu;
+	u64 vttbr;
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+	spin_lock(&vcpu->kvm->mmu_lock);
+
+	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, HCR_VM);
+	if (mmu)
+		kvm_unmap_stage2_range(mmu, 0, kvm_phys_size(vcpu->kvm));
+
+	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, 0);
+	if (mmu)
+		kvm_unmap_stage2_range(mmu, 0, kvm_phys_size(vcpu->kvm));
+
+	spin_unlock(&vcpu->kvm->mmu_lock);
+
+	return true;
+}
+
+static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			     const struct sys_reg_desc *r)
+{
+	u64 vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+	u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+	struct kvm_s2_mmu *mmu;
+	u64 base_addr;
+	int max_size;
+
+	if (vcpu_has_nv(vcpu) && forward_nv_traps(vcpu))
+		return false;
+
+	/*
+	 * We drop a number of things from the supplied value:
+	 *
+	 * - NS bit: we're non-secure only.
+	 *
+	 * - TTL field: We already have the granule size from the
+	 *   VTCR_EL2.TG0 field, and the level is only relevant to the
+	 *   guest's S2PT.
+	 *
+	 * - IPA[51:48]: We don't support 52bit IPA just yet...
+	 *
+	 * And of course, adjust the IPA to be on an actual address.
+	 */
+	base_addr = (p->regval & GENMASK_ULL(35, 0)) << 12;
+
+	/* Compute the maximum extent of the invalidation */
+	switch ((vtcr & VTCR_EL2_TG0_MASK)) {
+	case VTCR_EL2_TG0_4K:
+		max_size = SZ_1G;
+		break;
+	case VTCR_EL2_TG0_16K:
+		max_size = SZ_32M;
+		break;
+	case VTCR_EL2_TG0_64K:
+		/*
+		 * No, we do not support 52bit IPA in nested yet. Once
+		 * we do, this should be 4TB.
+		 */
+		/* FIXME: remove the 52bit PA support from the IDregs */
+		max_size = SZ_512M;
+		break;
+	default:
+		BUG();
+	}
+
+	spin_lock(&vcpu->kvm->mmu_lock);
+
+	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, HCR_VM);
+	if (mmu)
+		kvm_unmap_stage2_range(mmu, base_addr, max_size);
+
+	mmu = lookup_s2_mmu(vcpu->kvm, vttbr, 0);
+	if (mmu)
+		kvm_unmap_stage2_range(mmu, base_addr, max_size);
+
+	spin_unlock(&vcpu->kvm->mmu_lock);
+
+	return true;
+}
+
+static bool handle_tlbi_el1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	u32 sys_encoding = sys_insn(p->Op0, p->Op1, p->CRn, p->CRm, p->Op2);
+
+	if (vcpu_has_nv(vcpu) && forward_traps(vcpu, HCR_TTLB))
+		return false;
+
+	/*
+	 * If we're here, this is because we've trapped on a EL1 TLBI
+	 * instruction that affects the EL1 translation regime while
+	 * we're running in a context that doesn't allow us to let the
+	 * HW do its thing (aka vEL2):
+	 *
+	 * - HCR_EL2.E2H == 0 : a non-VHE guest
+	 * - HCR_EL2.{E2H,TGE} == { 1, 0 } : a VHE guest in guest mode
+	 *
+	 * We don't expect these helpers to ever be called when running
+	 * in a vEL1 context.
+	 */
+
+	WARN_ON(!vcpu_is_el2(vcpu));
+
+	mutex_lock(&vcpu->kvm->lock);
+
+	if ((__vcpu_sys_reg(vcpu, HCR_EL2) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
+		u64 virtual_vttbr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+		struct kvm_s2_mmu *mmu;
+
+		mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, HCR_VM);
+		if (mmu)
+			__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
+
+		mmu = lookup_s2_mmu(vcpu->kvm, virtual_vttbr, 0);
+		if (mmu)
+			__kvm_tlb_el1_instr(mmu, p->regval, sys_encoding);
+	} else {
+		/*
+		 * ARMv8.4-NV allows the guest to change TGE behind
+		 * our back, so we always trap EL1 TLBIs from vEL2...
+		 */
+		__kvm_tlb_el1_instr(&vcpu->kvm->arch.mmu, p->regval, sys_encoding);
+	}
+
+	mutex_unlock(&vcpu->kvm->lock);
+
+	return true;
+}
+
 /*
  * AT instruction emulation
  *
@@ -2459,12 +2658,40 @@ static struct sys_reg_desc sys_insn_descs[] = {
 	{ SYS_DESC(SYS_DC_CSW), access_dcsw },
 	{ SYS_DESC(SYS_DC_CISW), access_dcsw },
 
+	SYS_INSN(TLBI_VMALLE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_ASIDE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAAE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_VALE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAALE1IS, handle_tlbi_el1),
+	SYS_INSN(TLBI_VMALLE1, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAE1, handle_tlbi_el1),
+	SYS_INSN(TLBI_ASIDE1, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAAE1, handle_tlbi_el1),
+	SYS_INSN(TLBI_VALE1, handle_tlbi_el1),
+	SYS_INSN(TLBI_VAALE1, handle_tlbi_el1),
+
 	SYS_INSN(AT_S1E2R, handle_s1e2),
 	SYS_INSN(AT_S1E2W, handle_s1e2),
 	SYS_INSN(AT_S12E1R, handle_s12r),
 	SYS_INSN(AT_S12E1W, handle_s12w),
 	SYS_INSN(AT_S12E0R, handle_s12r),
 	SYS_INSN(AT_S12E0W, handle_s12w),
+
+	SYS_INSN(TLBI_IPAS2E1IS, handle_ipas2e1is),
+	SYS_INSN(TLBI_IPAS2LE1IS, handle_ipas2e1is),
+	SYS_INSN(TLBI_ALLE2IS, handle_alle2is),
+	SYS_INSN(TLBI_VAE2IS, handle_vae2is),
+	SYS_INSN(TLBI_ALLE1IS, handle_alle1is),
+	SYS_INSN(TLBI_VALE2IS, handle_vae2is),
+	SYS_INSN(TLBI_VMALLS12E1IS, handle_vmalls12e1is),
+	SYS_INSN(TLBI_IPAS2E1, handle_ipas2e1is),
+	SYS_INSN(TLBI_IPAS2LE1, handle_ipas2e1is),
+	SYS_INSN(TLBI_ALLE2, handle_alle2is),
+	SYS_INSN(TLBI_VAE2, handle_vae2is),
+	SYS_INSN(TLBI_ALLE1, handle_alle1is),
+	SYS_INSN(TLBI_VALE2, handle_vae2is),
+	SYS_INSN(TLBI_VMALLS12E1, handle_vmalls12e1is),
 };
 
 static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:43 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:43 +0000
Subject: [PATCH v6 35/64] KVM: arm64: nv: Implement nested Stage-2 page table
 walk logic
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-36-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at linaro.org>

Based on the pseudo-code in the ARM ARM, implement a stage 2 software
page table walker.

Signed-off-by: Christoffer Dall <christoffer.dall at linaro.org>
Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
[maz: heavily reworked for future ARMv8.4-TTL support]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/esr.h        |   1 +
 arch/arm64/include/asm/kvm_arm.h    |   2 +
 arch/arm64/include/asm/kvm_nested.h |  13 ++
 arch/arm64/kvm/nested.c             | 267 ++++++++++++++++++++++++++++
 4 files changed, 283 insertions(+)

diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 3574c224889f..b4f6f86a3631 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -130,6 +130,7 @@
 #define ESR_ELx_CM 		(UL(1) << ESR_ELx_CM_SHIFT)
 
 /* ISS field definitions for exceptions taken in to Hyp */
+#define ESR_ELx_FSC_ADDRSZ	(0x00)
 #define ESR_ELx_CV		(UL(1) << 24)
 #define ESR_ELx_COND_SHIFT	(20)
 #define ESR_ELx_COND_MASK	(UL(0xF) << ESR_ELx_COND_SHIFT)
diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index d913c3fb5665..3675879b53c6 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -272,6 +272,8 @@
 #define VTTBR_VMID_SHIFT  (UL(48))
 #define VTTBR_VMID_MASK(size) (_AT(u64, (1 << size) - 1) << VTTBR_VMID_SHIFT)
 
+#define SCTLR_EE	(UL(1) << 25)
+
 /* Hyp System Trap Register */
 #define HSTR_EL2_T(x)	(1 << x)
 
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 8bb7159f2b6b..48cf288ea238 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -72,6 +72,19 @@ extern struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr);
 extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
 extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
 
+struct kvm_s2_trans {
+	phys_addr_t output;
+	unsigned long block_size;
+	bool writable;
+	bool readable;
+	int level;
+	u32 esr;
+	u64 upper_attr;
+};
+
+extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+			      struct kvm_s2_trans *result);
+
 int handle_wfx_nested(struct kvm_vcpu *vcpu, bool is_wfe);
 extern bool __forward_traps(struct kvm_vcpu *vcpu, unsigned int reg,
 			    u64 control_bit);
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index bfa2b9229173..c2a99b672368 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -75,6 +75,273 @@ int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
 	return ret;
 }
 
+struct s2_walk_info {
+	int	     (*read_desc)(phys_addr_t pa, u64 *desc, void *data);
+	void	     *data;
+	u64	     baddr;
+	unsigned int max_pa_bits;
+	unsigned int pgshift;
+	unsigned int pgsize;
+	unsigned int ps;
+	unsigned int sl;
+	unsigned int t0sz;
+	bool	     be;
+	bool	     el1_aarch32;
+};
+
+static unsigned int ps_to_output_size(unsigned int ps)
+{
+	switch (ps) {
+	case 0: return 32;
+	case 1: return 36;
+	case 2: return 40;
+	case 3: return 42;
+	case 4: return 44;
+	case 5:
+	default:
+		return 48;
+	}
+}
+
+static u32 compute_fsc(int level, u32 fsc)
+{
+	return fsc | (level & 0x3);
+}
+
+static int check_base_s2_limits(struct s2_walk_info *wi,
+				int level, int input_size, int stride)
+{
+	int start_size;
+
+	/* Check translation limits */
+	switch (wi->pgsize) {
+	case SZ_64K:
+		if (level == 0 || (level == 1 && wi->max_pa_bits <= 42))
+			return -EFAULT;
+		break;
+	case SZ_16K:
+		if (level == 0 || (level == 1 && wi->max_pa_bits <= 40))
+			return -EFAULT;
+		break;
+	case SZ_4K:
+		if (level < 0 || (level == 0 && wi->max_pa_bits <= 42))
+			return -EFAULT;
+		break;
+	}
+
+	/* Check input size limits */
+	if (input_size > wi->max_pa_bits &&
+	    (!wi->el1_aarch32 || input_size > 40))
+		return -EFAULT;
+
+	/* Check number of entries in starting level table */
+	start_size = input_size - ((3 - level) * stride + wi->pgshift);
+	if (start_size < 1 || start_size > stride + 4)
+		return -EFAULT;
+
+	return 0;
+}
+
+/* Check if output is within boundaries */
+static int check_output_size(struct s2_walk_info *wi, phys_addr_t output)
+{
+	unsigned int output_size = ps_to_output_size(wi->ps);
+
+	if (output_size > wi->max_pa_bits)
+		output_size = wi->max_pa_bits;
+
+	if (output_size != 48 && (output & GENMASK_ULL(47, output_size)))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * This is essentially a C-version of the pseudo code from the ARM ARM
+ * AArch64.TranslationTableWalk  function.  I strongly recommend looking at
+ * that pseudocode in trying to understand this.
+ *
+ * Must be called with the kvm->srcu read lock held
+ */
+static int walk_nested_s2_pgd(phys_addr_t ipa,
+			      struct s2_walk_info *wi, struct kvm_s2_trans *out)
+{
+	int first_block_level, level, stride, input_size, base_lower_bound;
+	phys_addr_t base_addr;
+	unsigned int addr_top, addr_bottom;
+	u64 desc;  /* page table entry */
+	int ret;
+	phys_addr_t paddr;
+
+	switch (wi->pgsize) {
+	case SZ_64K:
+	case SZ_16K:
+		level = 3 - wi->sl;
+		first_block_level = 2;
+		break;
+	case SZ_4K:
+		level = 2 - wi->sl;
+		first_block_level = 1;
+		break;
+	default:
+		/* GCC is braindead */
+		unreachable();
+	}
+
+	stride = wi->pgshift - 3;
+	input_size = 64 - wi->t0sz;
+	if (input_size > 48 || input_size < 25)
+		return -EFAULT;
+
+	ret = check_base_s2_limits(wi, level, input_size, stride);
+	if (WARN_ON(ret))
+		return ret;
+
+	base_lower_bound = 3 + input_size - ((3 - level) * stride +
+			   wi->pgshift);
+	base_addr = wi->baddr & GENMASK_ULL(47, base_lower_bound);
+
+	if (check_output_size(wi, base_addr)) {
+		out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+		return 1;
+	}
+
+	addr_top = input_size - 1;
+
+	while (1) {
+		phys_addr_t index;
+
+		addr_bottom = (3 - level) * stride + wi->pgshift;
+		index = (ipa & GENMASK_ULL(addr_top, addr_bottom))
+			>> (addr_bottom - 3);
+
+		paddr = base_addr | index;
+		ret = wi->read_desc(paddr, &desc, wi->data);
+		if (ret < 0)
+			return ret;
+
+		/*
+		 * Handle reversedescriptors if endianness differs between the
+		 * host and the guest hypervisor.
+		 */
+		if (wi->be)
+			desc = be64_to_cpu(desc);
+		else
+			desc = le64_to_cpu(desc);
+
+		/* Check for valid descriptor at this point */
+		if (!(desc & 1) || ((desc & 3) == 1 && level == 3)) {
+			out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
+			out->upper_attr = desc;
+			return 1;
+		}
+
+		/* We're at the final level or block translation level */
+		if ((desc & 3) == 1 || level == 3)
+			break;
+
+		if (check_output_size(wi, desc)) {
+			out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+			out->upper_attr = desc;
+			return 1;
+		}
+
+		base_addr = desc & GENMASK_ULL(47, wi->pgshift);
+
+		level += 1;
+		addr_top = addr_bottom - 1;
+	}
+
+	if (level < first_block_level) {
+		out->esr = compute_fsc(level, ESR_ELx_FSC_FAULT);
+		out->upper_attr = desc;
+		return 1;
+	}
+
+	/*
+	 * We don't use the contiguous bit in the stage-2 ptes, so skip check
+	 * for misprogramming of the contiguous bit.
+	 */
+
+	if (check_output_size(wi, desc)) {
+		out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ);
+		out->upper_attr = desc;
+		return 1;
+	}
+
+	if (!(desc & BIT(10))) {
+		out->esr = compute_fsc(level, ESR_ELx_FSC_ACCESS);
+		out->upper_attr = desc;
+		return 1;
+	}
+
+	/* Calculate and return the result */
+	paddr = (desc & GENMASK_ULL(47, addr_bottom)) |
+		(ipa & GENMASK_ULL(addr_bottom - 1, 0));
+	out->output = paddr;
+	out->block_size = 1UL << ((3 - level) * stride + wi->pgshift);
+	out->readable = desc & (0b01 << 6);
+	out->writable = desc & (0b10 << 6);
+	out->level = level;
+	out->upper_attr = desc & GENMASK_ULL(63, 52);
+	return 0;
+}
+
+static int read_guest_s2_desc(phys_addr_t pa, u64 *desc, void *data)
+{
+	struct kvm_vcpu *vcpu = data;
+
+	return kvm_read_guest(vcpu->kvm, pa, desc, sizeof(*desc));
+}
+
+static void vtcr_to_walk_info(u64 vtcr, struct s2_walk_info *wi)
+{
+	wi->t0sz = vtcr & TCR_EL2_T0SZ_MASK;
+
+	switch (vtcr & VTCR_EL2_TG0_MASK) {
+	case VTCR_EL2_TG0_4K:
+		wi->pgshift = 12;	 break;
+	case VTCR_EL2_TG0_16K:
+		wi->pgshift = 14;	 break;
+	case VTCR_EL2_TG0_64K:
+	default:
+		wi->pgshift = 16;	 break;
+	}
+
+	wi->pgsize = 1UL << wi->pgshift;
+	wi->ps = (vtcr & VTCR_EL2_PS_MASK) >> VTCR_EL2_PS_SHIFT;
+	wi->sl = (vtcr & VTCR_EL2_SL0_MASK) >> VTCR_EL2_SL0_SHIFT;
+	wi->max_pa_bits = VTCR_EL2_IPA(vtcr);
+}
+
+int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
+		       struct kvm_s2_trans *result)
+{
+	u64 vtcr = vcpu_read_sys_reg(vcpu, VTCR_EL2);
+	struct s2_walk_info wi;
+	int ret;
+
+	result->esr = 0;
+
+	if (!vcpu_has_nv(vcpu))
+		return 0;
+
+	wi.read_desc = read_guest_s2_desc;
+	wi.data = vcpu;
+	wi.baddr = vcpu_read_sys_reg(vcpu, VTTBR_EL2);
+
+	vtcr_to_walk_info(vtcr, &wi);
+
+	wi.be = vcpu_read_sys_reg(vcpu, SCTLR_EL2) & SCTLR_EE;
+	wi.el1_aarch32 = vcpu_mode_is_32bit(vcpu);
+
+	ret = walk_nested_s2_pgd(gipa, &wi, result);
+	if (ret)
+		result->esr |= (kvm_vcpu_get_esr(vcpu) & ~ESR_ELx_FSC);
+
+	return ret;
+}
+
 /* Must be called with kvm->lock held */
 struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr)
 {
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:38 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:38 +0000
Subject: [PATCH v6 30/64] KVM: arm64: nv: Configure HCR_EL2 for nested
 virtualization
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-31-maz@kernel.org>

From: Jintack Lim <jintack.lim at linaro.org>

We enable nested virtualization by setting the HCR NV and NV1 bit.

When the virtual E2H bit is set, we can support EL2 register accesses
via EL1 registers from the virtual EL2 by doing trap-and-emulate. A
better alternative, however, is to allow the virtual EL2 to access EL2
register states without trap. This can be easily achieved by not traping
EL1 registers since those registers already have EL2 register states.

Signed-off-by: Jintack Lim <jintack.lim at linaro.org>
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_arm.h |  1 +
 arch/arm64/kvm/hyp/vhe/switch.c  | 38 +++++++++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h
index 748c2b068d4e..d913c3fb5665 100644
--- a/arch/arm64/include/asm/kvm_arm.h
+++ b/arch/arm64/include/asm/kvm_arm.h
@@ -87,6 +87,7 @@
 			 HCR_BSU_IS | HCR_FB | HCR_TACR | \
 			 HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW | HCR_TLOR | \
 			 HCR_FMO | HCR_IMO | HCR_PTW )
+#define HCR_GUEST_NV_FILTER_FLAGS (HCR_ATA | HCR_API | HCR_APK)
 #define HCR_VIRT_EXCP_MASK (HCR_VSE | HCR_VI | HCR_VF)
 #define HCR_HOST_NVHE_FLAGS (HCR_RW | HCR_API | HCR_APK | HCR_ATA)
 #define HCR_HOST_NVHE_PROTECTED_FLAGS (HCR_HOST_NVHE_FLAGS | HCR_TSC)
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 1e6a00e7bfb3..28845f907cfc 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -35,9 +35,41 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
 	u64 hcr = vcpu->arch.hcr_el2;
 	u64 val;
 
-	/* Trap VM sysreg accesses if an EL2 guest is not using VHE. */
-	if (vcpu_is_el2(vcpu) && !vcpu_el2_e2h_is_set(vcpu))
-		hcr |= HCR_TVM | HCR_TRVM;
+	if (is_hyp_ctxt(vcpu)) {
+		hcr |= HCR_NV;
+
+		if (!vcpu_el2_e2h_is_set(vcpu)) {
+			/*
+			 * For a guest hypervisor on v8.0, trap and emulate
+			 * the EL1 virtual memory control register accesses.
+			 */
+			hcr |= HCR_TVM | HCR_TRVM | HCR_NV1;
+		} else {
+			/*
+			 * For a guest hypervisor on v8.1 (VHE), allow to
+			 * access the EL1 virtual memory control registers
+			 * natively. These accesses are to access EL2 register
+			 * states.
+			 * Note that we still need to respect the virtual
+			 * HCR_EL2 state.
+			 */
+			u64 vhcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);
+
+			vhcr_el2 &= ~HCR_GUEST_NV_FILTER_FLAGS;
+
+			/*
+			 * We already set TVM to handle set/way cache maint
+			 * ops traps, this somewhat collides with the nested
+			 * virt trapping for nVHE. So turn this off for now
+			 * here, in the hope that VHE guests won't ever do this.
+			 * TODO: find out whether it's worth to support both
+			 * cases at the same time.
+			 */
+			hcr &= ~HCR_TVM;
+
+			hcr |= vhcr_el2 & (HCR_TVM | HCR_TRVM);
+		}
+	}
 
 	___activate_traps(vcpu, hcr);
 
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:57 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:57 +0000
Subject: [PATCH v6 49/64] KVM: arm64: nv: vgic: Allow userland to set VGIC
 maintenance IRQ
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-50-maz@kernel.org>

From: Andre Przywara <andre.przywara at arm.com>

The VGIC maintenance IRQ signals various conditions about the LRs, when
the GIC's virtualization extension is used.
So far we didn't need it, but nested virtualization needs to know about
this interrupt, so add a userland interface to setup the IRQ number.
The architecture mandates that it must be a PPI, on top of that this code
only exports a per-device option, so the PPI is the same on all VCPUs.

Signed-off-by: Andre Przywara <andre.przywara at arm.com>
[added some bits of documentation]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 .../virt/kvm/devices/arm-vgic-v3.rst          | 12 +++++++++-
 arch/arm64/include/uapi/asm/kvm.h             |  1 +
 arch/arm64/kvm/vgic/vgic-kvm-device.c         | 22 +++++++++++++++++++
 include/kvm/arm_vgic.h                        |  3 +++
 tools/arch/arm/include/uapi/asm/kvm.h         |  1 +
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/Documentation/virt/kvm/devices/arm-vgic-v3.rst b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
index 51e5e5762571..1901e651cc00 100644
--- a/Documentation/virt/kvm/devices/arm-vgic-v3.rst
+++ b/Documentation/virt/kvm/devices/arm-vgic-v3.rst
@@ -284,8 +284,18 @@ Groups:
       |    Aff3    |    Aff2    |    Aff1    |    Aff0    |
 
   Errors:
-
     =======  =============================================
     -EINVAL  vINTID is not multiple of 32 or info field is
 	     not VGIC_LEVEL_INFO_LINE_LEVEL
     =======  =============================================
+
+  KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
+   Attributes:
+
+    The attr field of kvm_device_attr encodes the following values:
+
+      bits:     | 31   ....    5 | 4  ....  0 |
+      values:   |      RES0      |   vINTID   |
+
+    The vINTID specifies which interrupt is generated when the vGIC
+    must generate a maintenance interrupt. This must be a PPI.
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 395a4c039bcc..b2811b90fa13 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -346,6 +346,7 @@ struct kvm_arm_copy_mte_tags {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO  7
 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8
+#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ  9
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT	10
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
 			(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vgic-kvm-device.c
index c6d52a1fd9c8..c653259f5a4f 100644
--- a/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -251,6 +251,12 @@ static int vgic_get_common_attr(struct kvm_device *dev,
 			     VGIC_NR_PRIVATE_IRQS, uaddr);
 		break;
 	}
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
+		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
+
+		r = put_user(dev->kvm->arch.vgic.maint_irq, uaddr);
+		break;
+	}
 	}
 
 	return r;
@@ -637,6 +643,21 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
 		reg = tmp32;
 		return vgic_v3_attr_regs_access(dev, attr, &reg, true);
 	}
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
+		u32 __user *uaddr = (u32 __user *)(long)attr->addr;
+		u32 val;
+
+		if (get_user(val, uaddr))
+			return -EFAULT;
+
+		/* Must be a PPI. */
+		if ((val >= VGIC_NR_PRIVATE_IRQS) || (val < VGIC_NR_SGIS))
+			return -EINVAL;
+
+		dev->kvm->arch.vgic.maint_irq = val;
+
+		return 0;
+	}
 	case KVM_DEV_ARM_VGIC_GRP_CTRL: {
 		int ret;
 
@@ -722,6 +743,7 @@ static int vgic_v3_has_attr(struct kvm_device *dev,
 	case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
 		return vgic_v3_has_attr_regs(dev, attr);
 	case KVM_DEV_ARM_VGIC_GRP_NR_IRQS:
+	case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
 		return 0;
 	case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO: {
 		if (((attr->attr & KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK) >>
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index beeb99dc3cc1..b44db6b013f5 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -240,6 +240,9 @@ struct vgic_dist {
 
 	int			nr_spis;
 
+	/* The GIC maintenance IRQ for nested hypervisors. */
+	u32			maint_irq;
+
 	/* base addresses in guest physical address space: */
 	gpa_t			vgic_dist_base;		/* distributor */
 	union {
diff --git a/tools/arch/arm/include/uapi/asm/kvm.h b/tools/arch/arm/include/uapi/asm/kvm.h
index 03cd7c19a683..d5dd96902817 100644
--- a/tools/arch/arm/include/uapi/asm/kvm.h
+++ b/tools/arch/arm/include/uapi/asm/kvm.h
@@ -246,6 +246,7 @@ struct kvm_vcpu_events {
 #define KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS 6
 #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO  7
 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS	8
+#define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ	9
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT	10
 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \
 			(0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT)
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:41 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:41 +0000
Subject: [PATCH v6 33/64] KVM: arm64: nv: Hide RAS from nested guests
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-34-maz@kernel.org>

We don't want to expose complicated features to guests until we have
a good grasp on the basic CPU emulation. So let's pretend that RAS,
doesn't exist in a nested guest. We already hide the feature bits,
let's now make sure VDISR_EL1 will UNDEF.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/kvm/sys_regs.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index ebcdf2714b73..5e8876177ce6 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -2212,6 +2212,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(VBAR_EL2, access_rw, reset_val, 0),
 	EL2_REG(RVBAR_EL2, access_rw, reset_val, 0),
 	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
+	{ SYS_DESC(SYS_VDISR_EL2), trap_undef },
 
 	EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
 	EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:07 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:07 +0000
Subject: [PATCH v6 59/64] KVM: arm64: Add ARMv8.4 Enhanced Nested Virt
 cpufeature
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-60-maz@kernel.org>

Add the detection code for the ARMv8.4-NV feature.

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_nested.h |  6 ++++++
 arch/arm64/kernel/cpufeature.c      | 10 ++++++++++
 arch/arm64/tools/cpucaps            |  1 +
 3 files changed, 17 insertions(+)

diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 3b5838a2f29e..57b14474a062 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -14,6 +14,12 @@ static inline bool vcpu_has_nv(const struct kvm_vcpu *vcpu)
 		test_bit(KVM_ARM_VCPU_HAS_EL2, vcpu->arch.features));
 }
 
+static inline bool vcpu_has_nv2(const struct kvm_vcpu *vcpu)
+{
+	return cpus_have_final_cap(ARM64_HAS_ENHANCED_NESTED_VIRT) &&
+		vcpu_has_nv(vcpu);
+}
+
 /* Translation helpers from non-VHE EL2 to EL1 */
 static inline u64 tcr_el2_ps_to_tcr_el1_ips(u64 tcr_el2)
 {
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 2fa39ce108d0..6e0577d3bf63 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2029,6 +2029,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.field_pos = ID_AA64MMFR2_NV_SHIFT,
 		.min_field_value = 1,
 	},
+	{
+		.desc = "Enhanced Nested Virtualization Support",
+		.capability = ARM64_HAS_ENHANCED_NESTED_VIRT,
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.matches = has_nested_virt_support,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR2_NV_SHIFT,
+		.min_field_value = 2,
+	},
 	{
 		.capability = ARM64_HAS_32BIT_EL0_DO_NOT_USE,
 		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index a49864b56a07..3f6f567d2811 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -19,6 +19,7 @@ HAS_DCPODP
 HAS_DCPOP
 HAS_E0PD
 HAS_ECV
+HAS_ENHANCED_NESTED_VIRT
 HAS_EPAN
 HAS_GENERIC_AUTH
 HAS_GENERIC_AUTH_ARCH
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:54 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:54 +0000
Subject: [PATCH v6 46/64] KVM: arm64: nv: Nested GICv3 Support
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-47-maz@kernel.org>

From: Jintack Lim <jintack at cs.columbia.edu>

When entering a nested VM, we set up the hypervisor control interface
based on what the guest hypervisor has set. Especially, we investigate
each list register written by the guest hypervisor whether HW bit is
set.  If so, we translate hw irq number from the guest's point of view
to the real hardware irq number if there is a mapping.

Signed-off-by: Jintack Lim <jintack at cs.columbia.edu>
[Redesigned execution flow around vcpu load/put]
Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[Rewritten to support GICv3 instead of GICv2]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_emulate.h |   8 +-
 arch/arm64/include/asm/kvm_host.h    |  11 +-
 arch/arm64/include/asm/kvm_nested.h  |   1 +
 arch/arm64/kvm/Makefile              |   2 +-
 arch/arm64/kvm/arm.c                 |  13 +-
 arch/arm64/kvm/nested.c              |  16 +++
 arch/arm64/kvm/sys_regs.c            | 179 +++++++++++++++++++++++++-
 arch/arm64/kvm/vgic/vgic-v3-nested.c | 180 +++++++++++++++++++++++++++
 arch/arm64/kvm/vgic/vgic-v3.c        |  26 ++++
 arch/arm64/kvm/vgic/vgic.c           |  27 ++++
 include/kvm/arm_vgic.h               |  18 +++
 11 files changed, 471 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/kvm/vgic/vgic-v3-nested.c

diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
index dc6eeb0cc8a9..2128d623a8b3 100644
--- a/arch/arm64/include/asm/kvm_emulate.h
+++ b/arch/arm64/include/asm/kvm_emulate.h
@@ -505,7 +505,13 @@ static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
 
 static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
 {
-	return vcpu_read_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
+	/*
+	 * Use the in-memory view for MPIDR_EL1. It can't be changed by the
+	 * guest, and is also accessed from the context of *another* vcpu,
+	 * so anything using some other state (such as the NV state that is
+	 * used by vcpu_read_sys_reg) will eventually go wrong.
+	 */
+	return __vcpu_sys_reg(vcpu, MPIDR_EL1) & MPIDR_HWID_BITMASK;
 }
 
 static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 03833eca3307..6bfdb21c0d8a 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -41,11 +41,12 @@
 
 #define KVM_REQ_SLEEP \
 	KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
-#define KVM_REQ_IRQ_PENDING	KVM_ARCH_REQ(1)
-#define KVM_REQ_VCPU_RESET	KVM_ARCH_REQ(2)
-#define KVM_REQ_RECORD_STEAL	KVM_ARCH_REQ(3)
-#define KVM_REQ_RELOAD_GICv4	KVM_ARCH_REQ(4)
-#define KVM_REQ_RELOAD_PMU	KVM_ARCH_REQ(5)
+#define KVM_REQ_IRQ_PENDING		KVM_ARCH_REQ(1)
+#define KVM_REQ_VCPU_RESET		KVM_ARCH_REQ(2)
+#define KVM_REQ_RECORD_STEAL		KVM_ARCH_REQ(3)
+#define KVM_REQ_RELOAD_GICv4		KVM_ARCH_REQ(4)
+#define KVM_REQ_RELOAD_PMU		KVM_ARCH_REQ(5)
+#define KVM_REQ_GUEST_HYP_IRQ_PENDING	KVM_ARCH_REQ(6)
 
 #define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
 				     KVM_DIRTY_LOG_INITIALLY_SET)
diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h
index 8915bead0633..3eef5f60c76d 100644
--- a/arch/arm64/include/asm/kvm_nested.h
+++ b/arch/arm64/include/asm/kvm_nested.h
@@ -71,6 +71,7 @@ extern void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu);
 extern struct kvm_s2_mmu *lookup_s2_mmu(struct kvm *kvm, u64 vttbr, u64 hcr);
 extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu);
 extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu);
+extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu);
 
 struct kvm_s2_trans {
 	phys_addr_t output;
diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile
index b800dcbd157f..a982fe1b4fc4 100644
--- a/arch/arm64/kvm/Makefile
+++ b/arch/arm64/kvm/Makefile
@@ -20,7 +20,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
 	 vgic/vgic-v3.o vgic/vgic-v4.o \
 	 vgic/vgic-mmio.o vgic/vgic-mmio-v2.o \
 	 vgic/vgic-mmio-v3.o vgic/vgic-kvm-device.o \
-	 vgic/vgic-its.o vgic/vgic-debug.o
+	 vgic/vgic-its.o vgic/vgic-debug.o vgic/vgic-v3-nested.o
 
 kvm-$(CONFIG_HW_PERF_EVENTS)  += pmu-emul.o
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 6597cb8f64f9..91fb7bc09b8e 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -755,6 +755,8 @@ static void check_vcpu_requests(struct kvm_vcpu *vcpu)
 		if (kvm_check_request(KVM_REQ_RELOAD_PMU, vcpu))
 			kvm_pmu_handle_pmcr(vcpu,
 					    __vcpu_sys_reg(vcpu, PMCR_EL0));
+
+		check_nested_vcpu_requests(vcpu);
 	}
 }
 
@@ -846,9 +848,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 		if (!ret)
 			ret = 1;
 
-		update_vmid(&vcpu->arch.hw_mmu->vmid);
-
+		/*
+		 * A nested exeption triggered by a vcpu request (such
+		 * as an interrupt injected in a guest hypervisor) can
+		 * change the currently used VMID (by switching to a
+		 * different translation regime. It is thus necesary
+		 * to update the VMID *after* all requests have been
+		 * processed.
+		 */
 		check_vcpu_requests(vcpu);
+		update_vmid(&vcpu->arch.hw_mmu->vmid);
 
 		/*
 		 * Preparing the interrupts to be injected also
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index b39af4d87787..39c9b1033f02 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -580,6 +580,22 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm)
 	kvm_free_stage2_pgd(&kvm->arch.mmu);
 }
 
+bool vgic_state_is_nested(struct kvm_vcpu *vcpu)
+{
+	bool imo = __vcpu_sys_reg(vcpu, HCR_EL2) & HCR_IMO;
+	bool fmo = __vcpu_sys_reg(vcpu, HCR_EL2) & HCR_FMO;
+
+	WARN_ONCE(imo != fmo, "Separate virtual IRQ/FIQ settings not supported\n");
+
+	return vcpu_has_nv(vcpu) && imo && fmo && !is_hyp_ctxt(vcpu);
+}
+
+void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
+{
+	if (kvm_check_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu))
+		kvm_inject_nested_irq(vcpu);
+}
+
 /*
  * Our emulated CPU doesn't support all the possible features. For the
  * sake of simplicity (and probably mental sanity), wipe out a number
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index f2452e76156c..a18d845bcff7 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -16,6 +16,8 @@
 #include <linux/printk.h>
 #include <linux/uaccess.h>
 
+#include <linux/irqchip/arm-gic-v3.h>
+
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/debug-monitors.h>
@@ -407,6 +409,19 @@ static bool access_actlr(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+/*
+ * The architecture says that non-secure write accesses to this register from
+ * EL1 are trapped to EL2, if either:
+ *  - HCR_EL2.FMO==1, or
+ *  - HCR_EL2.IMO==1
+ */
+static bool sgi_traps_to_vel2(struct kvm_vcpu *vcpu)
+{
+	return (vcpu_has_nv(vcpu) &&
+		!vcpu_is_el2(vcpu) &&
+		!!(vcpu_read_sys_reg(vcpu, HCR_EL2) & (HCR_IMO | HCR_FMO)));
+}
+
 /*
  * Trap handler for the GICv3 SGI generation system register.
  * Forward the request to the VGIC emulation.
@@ -422,6 +437,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
 	if (!p->is_write)
 		return read_from_write_only(vcpu, p, r);
 
+	if (sgi_traps_to_vel2(vcpu)) {
+		kvm_inject_nested_sync(vcpu, kvm_vcpu_get_esr(vcpu));
+		return false;
+	}
+
 	/*
 	 * In a system where GICD_CTLR.DS=1, a ICC_SGI0R_EL1 access generates
 	 * Group0 SGIs only, while ICC_SGI1R_EL1 can generate either group,
@@ -465,7 +485,13 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
 	if (p->is_write)
 		return ignore_write(vcpu, p);
 
-	p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+	if (p->Op1 == 4) {	/* ICC_SRE_EL2 */
+		p->regval = (ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE |
+			     ICC_SRE_EL1_DIB | ICC_SRE_EL1_DFB);
+	} else {		/* ICC_SRE_EL1 */
+		p->regval = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+	}
+
 	return true;
 }
 
@@ -1835,6 +1861,122 @@ static bool access_spsr_el2(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_gic_apr(struct kvm_vcpu *vcpu,
+			   struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+	u32 index, *base;
+
+	index = r->Op2;
+	if (r->CRm == 8)
+		base = cpu_if->vgic_ap0r;
+	else
+		base = cpu_if->vgic_ap1r;
+
+	if (p->is_write)
+		base[index] = p->regval;
+	else
+		p->regval = base[index];
+
+	return true;
+}
+
+static bool access_gic_hcr(struct kvm_vcpu *vcpu,
+			   struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+
+	if (p->is_write)
+		cpu_if->vgic_hcr = p->regval;
+	else
+		p->regval = cpu_if->vgic_hcr;
+
+	return true;
+}
+
+static bool access_gic_vtr(struct kvm_vcpu *vcpu,
+			   struct sys_reg_params *p,
+			   const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = kvm_vgic_global_state.ich_vtr_el2;
+
+	return true;
+}
+
+static bool access_gic_misr(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_misr(vcpu);
+
+	return true;
+}
+
+static bool access_gic_eisr(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_eisr(vcpu);
+
+	return true;
+}
+
+static bool access_gic_elrsr(struct kvm_vcpu *vcpu,
+			     struct sys_reg_params *p,
+			     const struct sys_reg_desc *r)
+{
+	if (p->is_write)
+		return write_to_read_only(vcpu, p, r);
+
+	p->regval = vgic_v3_get_elrsr(vcpu);
+
+	return true;
+}
+
+static bool access_gic_vmcr(struct kvm_vcpu *vcpu,
+			    struct sys_reg_params *p,
+			    const struct sys_reg_desc *r)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+
+	if (p->is_write)
+		cpu_if->vgic_vmcr = p->regval;
+	else
+		p->regval = cpu_if->vgic_vmcr;
+
+	return true;
+}
+
+static bool access_gic_lr(struct kvm_vcpu *vcpu,
+			  struct sys_reg_params *p,
+			  const struct sys_reg_desc *r)
+{
+	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+	u32 index;
+
+	index = p->Op2;
+	if (p->CRm == 13)
+		index += 8;
+
+	if (p->is_write)
+		cpu_if->vgic_lr[index] = p->regval;
+	else
+		p->regval = cpu_if->vgic_lr[index];
+
+	return true;
+}
+
 /*
  * Architected system registers.
  * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
@@ -2286,6 +2428,41 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	{ SYS_DESC(SYS_RMR_EL2), trap_undef },
 	{ SYS_DESC(SYS_VDISR_EL2), trap_undef },
 
+	{ SYS_DESC(SYS_ICH_AP0R0_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP0R1_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP0R2_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP0R3_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP1R0_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP1R1_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP1R2_EL2), access_gic_apr },
+	{ SYS_DESC(SYS_ICH_AP1R3_EL2), access_gic_apr },
+
+	{ SYS_DESC(SYS_ICC_SRE_EL2), access_gic_sre },
+
+	{ SYS_DESC(SYS_ICH_HCR_EL2), access_gic_hcr },
+	{ SYS_DESC(SYS_ICH_VTR_EL2), access_gic_vtr },
+	{ SYS_DESC(SYS_ICH_MISR_EL2), access_gic_misr },
+	{ SYS_DESC(SYS_ICH_EISR_EL2), access_gic_eisr },
+	{ SYS_DESC(SYS_ICH_ELRSR_EL2), access_gic_elrsr },
+	{ SYS_DESC(SYS_ICH_VMCR_EL2), access_gic_vmcr },
+
+	{ SYS_DESC(SYS_ICH_LR0_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR1_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR2_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR3_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR4_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR5_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR6_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR7_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR8_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR9_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR10_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR11_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR12_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR13_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR14_EL2), access_gic_lr },
+	{ SYS_DESC(SYS_ICH_LR15_EL2), access_gic_lr },
+
 	EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
 	EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
 
diff --git a/arch/arm64/kvm/vgic/vgic-v3-nested.c b/arch/arm64/kvm/vgic/vgic-v3-nested.c
new file mode 100644
index 000000000000..ab8ddf490b31
--- /dev/null
+++ b/arch/arm64/kvm/vgic/vgic-v3-nested.c
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/cpu.h>
+#include <linux/kvm.h>
+#include <linux/kvm_host.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <linux/irqchip/arm-gic-v3.h>
+
+#include <asm/kvm_emulate.h>
+#include <asm/kvm_arm.h>
+#include <kvm/arm_vgic.h>
+
+#include "vgic.h"
+
+static inline struct vgic_v3_cpu_if *vcpu_nested_if(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.vgic_cpu.nested_vgic_v3;
+}
+
+static inline struct vgic_v3_cpu_if *vcpu_shadow_if(struct kvm_vcpu *vcpu)
+{
+	return &vcpu->arch.vgic_cpu.shadow_vgic_v3;
+}
+
+static inline bool lr_triggers_eoi(u64 lr)
+{
+	return !(lr & (ICH_LR_STATE | ICH_LR_HW)) && (lr & ICH_LR_EOI);
+}
+
+u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	u16 reg = 0;
+	int i;
+
+	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		if (lr_triggers_eoi(cpu_if->vgic_lr[i]))
+			reg |= BIT(i);
+	}
+
+	return reg;
+}
+
+u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	u16 reg = 0;
+	int i;
+
+	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		if (!(cpu_if->vgic_lr[i] & ICH_LR_STATE))
+			reg |= BIT(i);
+	}
+
+	return reg;
+}
+
+u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	int nr_lr = kvm_vgic_global_state.nr_lr;
+	u64 reg = 0;
+
+	if (vgic_v3_get_eisr(vcpu))
+		reg |= ICH_MISR_EOI;
+
+	if (cpu_if->vgic_hcr & ICH_HCR_UIE) {
+		int used_lrs;
+
+		used_lrs = nr_lr - hweight16(vgic_v3_get_elrsr(vcpu));
+		if (used_lrs <= 1)
+			reg |= ICH_MISR_U;
+	}
+
+	/* TODO: Support remaining bits in this register */
+	return reg;
+}
+
+/*
+ * For LRs which have HW bit set such as timer interrupts, we modify them to
+ * have the host hardware interrupt number instead of the virtual one programmed
+ * by the guest hypervisor.
+ */
+static void vgic_v3_create_shadow_lr(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
+	struct vgic_irq *irq;
+	int i, used_lrs = 0;
+
+	for (i = 0; i < kvm_vgic_global_state.nr_lr; i++) {
+		u64 lr = cpu_if->vgic_lr[i];
+		int l1_irq;
+
+		if (!(lr & ICH_LR_HW))
+			goto next;
+
+		/* We have the HW bit set */
+		l1_irq = (lr & ICH_LR_PHYS_ID_MASK) >> ICH_LR_PHYS_ID_SHIFT;
+		irq = vgic_get_irq(vcpu->kvm, vcpu, l1_irq);
+
+		if (!irq || !irq->hw) {
+			/* There was no real mapping, so nuke the HW bit */
+			lr &= ~ICH_LR_HW;
+			if (irq)
+				vgic_put_irq(vcpu->kvm, irq);
+			goto next;
+		}
+
+		/* Translate the virtual mapping to the real one */
+		lr &= ~ICH_LR_EOI; /* Why? */
+		lr &= ~ICH_LR_PHYS_ID_MASK;
+		lr |= (u64)irq->hwintid << ICH_LR_PHYS_ID_SHIFT;
+		vgic_put_irq(vcpu->kvm, irq);
+
+next:
+		s_cpu_if->vgic_lr[i] = lr;
+		used_lrs = i + 1;
+	}
+
+	s_cpu_if->used_lrs = used_lrs;
+}
+
+/*
+ * Change the shadow HWIRQ field back to the virtual value before copying over
+ * the entire shadow struct to the nested state.
+ */
+static void vgic_v3_fixup_shadow_lr_state(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+	struct vgic_v3_cpu_if *s_cpu_if = vcpu_shadow_if(vcpu);
+	int lr;
+
+	for (lr = 0; lr < kvm_vgic_global_state.nr_lr; lr++) {
+		s_cpu_if->vgic_lr[lr] &= ~ICH_LR_PHYS_ID_MASK;
+		s_cpu_if->vgic_lr[lr] |= cpu_if->vgic_lr[lr] & ICH_LR_PHYS_ID_MASK;
+	}
+}
+
+void vgic_v3_load_nested(struct kvm_vcpu *vcpu)
+{
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+
+	vgic_cpu->shadow_vgic_v3 = vgic_cpu->nested_vgic_v3;
+	vgic_v3_create_shadow_lr(vcpu);
+	__vgic_v3_restore_state(vcpu_shadow_if(vcpu));
+}
+
+void vgic_v3_put_nested(struct kvm_vcpu *vcpu)
+{
+	struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+
+	__vgic_v3_save_state(vcpu_shadow_if(vcpu));
+
+	/*
+	 * Translate the shadow state HW fields back to the virtual ones
+	 * before copying the shadow struct back to the nested one.
+	 */
+	vgic_v3_fixup_shadow_lr_state(vcpu);
+	vgic_cpu->nested_vgic_v3 = vgic_cpu->shadow_vgic_v3;
+}
+
+void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu)
+{
+	struct vgic_v3_cpu_if *cpu_if = vcpu_nested_if(vcpu);
+
+	/*
+	 * If we exit a nested VM with a pending maintenance interrupt from the
+	 * GIC, then we need to forward this to the guest hypervisor so that it
+	 * can re-sync the appropriate LRs and sample level triggered interrupts
+	 * again.
+	 */
+	if (vgic_state_is_nested(vcpu) &&
+	    (cpu_if->vgic_hcr & ICH_HCR_EN) &&
+	    vgic_v3_get_misr(vcpu))
+		kvm_inject_nested_irq(vcpu);
+}
diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index a33d4366b326..6bfca28ecced 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -8,6 +8,7 @@
 #include <kvm/arm_vgic.h>
 #include <asm/kvm_hyp.h>
 #include <asm/kvm_mmu.h>
+#include <asm/kvm_nested.h>
 #include <asm/kvm_asm.h>
 
 #include "vgic.h"
@@ -277,6 +278,12 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu)
 		vgic_v3->vgic_sre = (ICC_SRE_EL1_DIB |
 				     ICC_SRE_EL1_DFB |
 				     ICC_SRE_EL1_SRE);
+		/*
+		 * If nesting is allowed, force GICv3 onto the nested
+		 * guests as well.
+		 */
+		if (vcpu_has_nv(vcpu))
+			vcpu->arch.vgic_cpu.nested_vgic_v3.vgic_sre = vgic_v3->vgic_sre;
 		vcpu->arch.vgic_cpu.pendbaser = INITIAL_PENDBASER_VALUE;
 	} else {
 		vgic_v3->vgic_sre = 0;
@@ -707,6 +714,13 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	/*
+	 * vgic_v3_load_nested only affects the LRs in the shadow
+	 * state, so it is fine to pass the nested state around.
+	 */
+	if (vgic_state_is_nested(vcpu))
+		cpu_if = &vcpu->arch.vgic_cpu.nested_vgic_v3;
+
 	/*
 	 * If dealing with a GICv2 emulation on GICv3, VMCR_EL2.VFIQen
 	 * is dependent on ICC_SRE_EL1.SRE, and we have to perform the
@@ -720,6 +734,9 @@ void vgic_v3_load(struct kvm_vcpu *vcpu)
 	if (has_vhe())
 		__vgic_v3_activate_traps(cpu_if);
 
+	if (vgic_state_is_nested(vcpu))
+		vgic_v3_load_nested(vcpu);
+
 	WARN_ON(vgic_v4_load(vcpu));
 }
 
@@ -727,6 +744,9 @@ void vgic_v3_vmcr_sync(struct kvm_vcpu *vcpu)
 {
 	struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
 
+	if (vgic_state_is_nested(vcpu))
+		cpu_if = &vcpu->arch.vgic_cpu.shadow_vgic_v3;
+
 	if (likely(cpu_if->vgic_sre))
 		cpu_if->vgic_vmcr = kvm_call_hyp_ret(__vgic_v3_read_vmcr);
 }
@@ -739,8 +759,14 @@ void vgic_v3_put(struct kvm_vcpu *vcpu)
 
 	vgic_v3_vmcr_sync(vcpu);
 
+	if (vgic_state_is_nested(vcpu))
+		cpu_if = &vcpu->arch.vgic_cpu.shadow_vgic_v3;
+
 	kvm_call_hyp(__vgic_v3_save_aprs, cpu_if);
 
 	if (has_vhe())
 		__vgic_v3_deactivate_traps(cpu_if);
+
+	if (vgic_state_is_nested(vcpu))
+		vgic_v3_put_nested(vcpu);
 }
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index e7fe0447af08..f467ea454c66 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -876,6 +876,10 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
 {
 	int used_lrs;
 
+	/* If nesting, this is a load/put affair, not flush/sync. */
+	if (vgic_state_is_nested(vcpu))
+		return;
+
 	/* An empty ap_list_head implies used_lrs == 0 */
 	if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head))
 		return;
@@ -920,6 +924,29 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
 	    !vgic_supports_direct_msis(vcpu->kvm))
 		return;
 
+	/*
+	 * If in a nested state, we must return early. Two possibilities:
+	 *
+	 * - If we have any pending IRQ for the guest and the guest
+	 *   expects IRQs to be handled in its virtual EL2 mode (the
+	 *   virtual IMO bit is set) and it is not already running in
+	 *   virtual EL2 mode, then we have to emulate an IRQ
+	 *   exception to virtual EL2.
+	 *
+	 *   We do that by placing a request to ourselves which will
+	 *   abort the entry procedure and inject the exception at the
+	 *   beginning of the run loop.
+	 *
+	 * - Otherwise, do exactly *NOTHING*. The guest state is
+	 *   already loaded, and we can carry on with running it.
+	 */
+	if (vgic_state_is_nested(vcpu)) {
+		if (kvm_vgic_vcpu_pending_irq(vcpu))
+			kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);
+
+		return;
+	}
+
 	DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
 
 	if (!list_empty(&vcpu->arch.vgic_cpu.ap_list_head)) {
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 17b651890d22..2e27259b451f 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -327,6 +327,15 @@ struct vgic_cpu {
 
 	struct vgic_irq private_irqs[VGIC_NR_PRIVATE_IRQS];
 
+	/* CPU vif control registers for the virtual GICH interface */
+	struct vgic_v3_cpu_if	nested_vgic_v3;
+
+	/*
+	 * The shadow vif control register loaded to the hardware when
+	 * running a nested L2 guest with the virtual IMO/FMO bit set.
+	 */
+	struct vgic_v3_cpu_if	shadow_vgic_v3;
+
 	raw_spinlock_t ap_list_lock;	/* Protects the ap_list */
 
 	/*
@@ -384,6 +393,13 @@ void kvm_vgic_load(struct kvm_vcpu *vcpu);
 void kvm_vgic_put(struct kvm_vcpu *vcpu);
 void kvm_vgic_vmcr_sync(struct kvm_vcpu *vcpu);
 
+void vgic_v3_load_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
+void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
+u16 vgic_v3_get_eisr(struct kvm_vcpu *vcpu);
+u16 vgic_v3_get_elrsr(struct kvm_vcpu *vcpu);
+u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu);
+
 #define irqchip_in_kernel(k)	(!!((k)->arch.vgic.in_kernel))
 #define vgic_initialized(k)	((k)->arch.vgic.initialized)
 #define vgic_ready(k)		((k)->arch.vgic.ready)
@@ -428,4 +444,6 @@ int vgic_v4_load(struct kvm_vcpu *vcpu);
 void vgic_v4_commit(struct kvm_vcpu *vcpu);
 int vgic_v4_put(struct kvm_vcpu *vcpu, bool need_db);
 
+bool vgic_state_is_nested(struct kvm_vcpu *vcpu);
+
 #endif /* __KVM_ARM_VGIC_H */
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:18:51 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:18:51 +0000
Subject: [PATCH v6 43/64] KVM: arm64: nv: arch_timer: Support hyp timer
 emulation
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-44-maz@kernel.org>

From: Christoffer Dall <christoffer.dall at arm.com>

Emulating EL2 also means emulating the EL2 timers. To do so, we expand
our timer framework to deal with at most 4 timers. At any given time,
two timers are using the HW timers, and the two others are purely
emulated.

The role of deciding which is which at any given time is left to a
mapping function which is called every time we need to make such a
decision.

Signed-off-by: Christoffer Dall <christoffer.dall at arm.com>
[maz: added CNTVOFF support, general reworking for v4.8]
Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h |   4 +
 arch/arm64/kvm/arch_timer.c       | 165 ++++++++++++++++++++++++++++--
 arch/arm64/kvm/sys_regs.c         |   7 +-
 arch/arm64/kvm/trace_arm.h        |   6 +-
 arch/arm64/kvm/vgic/vgic.c        |  15 +++
 include/kvm/arm_arch_timer.h      |   8 +-
 include/kvm/arm_vgic.h            |   1 +
 7 files changed, 194 insertions(+), 12 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0b887364f994..03833eca3307 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -285,6 +285,10 @@ enum vcpu_sysreg {
 	TPIDR_EL2,	/* EL2 Software Thread ID Register */
 	CNTHCTL_EL2,	/* Counter-timer Hypervisor Control register */
 	SP_EL2,		/* EL2 Stack Pointer */
+	CNTHP_CTL_EL2,
+	CNTHP_CVAL_EL2,
+	CNTHV_CTL_EL2,
+	CNTHV_CVAL_EL2,
 
 	NR_SYS_REGS	/* Nothing after this line! */
 };
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 6e542e2eae32..5e4f93605d36 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -16,6 +16,7 @@
 #include <asm/arch_timer.h>
 #include <asm/kvm_emulate.h>
 #include <asm/kvm_hyp.h>
+#include <asm/kvm_nested.h>
 
 #include <kvm/arm_vgic.h>
 #include <kvm/arm_arch_timer.h>
@@ -40,6 +41,16 @@ static const struct kvm_irq_level default_vtimer_irq = {
 	.level	= 1,
 };
 
+static const struct kvm_irq_level default_hptimer_irq = {
+	.irq	= 26,
+	.level	= 1,
+};
+
+static const struct kvm_irq_level default_hvtimer_irq = {
+	.irq	= 28,
+	.level	= 1,
+};
+
 static bool kvm_timer_irq_can_fire(struct arch_timer_context *timer_ctx);
 static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level,
 				 struct arch_timer_context *timer_ctx);
@@ -51,6 +62,11 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 			      struct arch_timer_context *timer,
 			      enum kvm_arch_timer_regs treg);
+static bool kvm_arch_timer_get_input_level(int vintid);
+
+static struct irq_ops arch_timer_irq_ops = {
+	.get_input_level = kvm_arch_timer_get_input_level,
+};
 
 u32 timer_get_ctl(struct arch_timer_context *ctxt)
 {
@@ -61,6 +77,10 @@ u32 timer_get_ctl(struct arch_timer_context *ctxt)
 		return __vcpu_sys_reg(vcpu, CNTV_CTL_EL0);
 	case TIMER_PTIMER:
 		return __vcpu_sys_reg(vcpu, CNTP_CTL_EL0);
+	case TIMER_HVTIMER:
+		return __vcpu_sys_reg(vcpu, CNTHV_CTL_EL2);
+	case TIMER_HPTIMER:
+		return __vcpu_sys_reg(vcpu, CNTHP_CTL_EL2);
 	default:
 		WARN_ON(1);
 		return 0;
@@ -76,6 +96,10 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
 		return __vcpu_sys_reg(vcpu, CNTV_CVAL_EL0);
 	case TIMER_PTIMER:
 		return __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
+	case TIMER_HVTIMER:
+		return __vcpu_sys_reg(vcpu, CNTHV_CVAL_EL2);
+	case TIMER_HPTIMER:
+		return __vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2);
 	default:
 		WARN_ON(1);
 		return 0;
@@ -105,6 +129,12 @@ static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
 	case TIMER_PTIMER:
 		__vcpu_sys_reg(vcpu, CNTP_CTL_EL0) = ctl;
 		break;
+	case TIMER_HVTIMER:
+		__vcpu_sys_reg(vcpu, CNTHV_CTL_EL2) = ctl;
+		break;
+	case TIMER_HPTIMER:
+		__vcpu_sys_reg(vcpu, CNTHP_CTL_EL2) = ctl;
+		break;
 	default:
 		WARN_ON(1);
 	}
@@ -121,6 +151,12 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
 	case TIMER_PTIMER:
 		__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0) = cval;
 		break;
+	case TIMER_HVTIMER:
+		__vcpu_sys_reg(vcpu, CNTHV_CVAL_EL2) = cval;
+		break;
+	case TIMER_HPTIMER:
+		__vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2) = cval;
+		break;
 	default:
 		WARN_ON(1);
 	}
@@ -146,13 +182,27 @@ u64 kvm_phys_timer_read(void)
 
 static void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map)
 {
-	if (has_vhe()) {
+	if (vcpu_has_nv(vcpu)) {
+		if (is_hyp_ctxt(vcpu)) {
+			map->direct_vtimer = vcpu_hvtimer(vcpu);
+			map->direct_ptimer = vcpu_hptimer(vcpu);
+			map->emul_vtimer = vcpu_vtimer(vcpu);
+			map->emul_ptimer = vcpu_ptimer(vcpu);
+		} else {
+			map->direct_vtimer = vcpu_vtimer(vcpu);
+			map->direct_ptimer = vcpu_ptimer(vcpu);
+			map->emul_vtimer = vcpu_hvtimer(vcpu);
+			map->emul_ptimer = vcpu_hptimer(vcpu);
+		}
+	} else if (has_vhe()) {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
 		map->direct_ptimer = vcpu_ptimer(vcpu);
+		map->emul_vtimer = NULL;
 		map->emul_ptimer = NULL;
 	} else {
 		map->direct_vtimer = vcpu_vtimer(vcpu);
 		map->direct_ptimer = NULL;
+		map->emul_vtimer = NULL;
 		map->emul_ptimer = vcpu_ptimer(vcpu);
 	}
 
@@ -325,9 +375,11 @@ static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx)
 
 		switch (index) {
 		case TIMER_VTIMER:
+		case TIMER_HVTIMER:
 			cnt_ctl = read_sysreg_el0(SYS_CNTV_CTL);
 			break;
 		case TIMER_PTIMER:
+		case TIMER_HPTIMER:
 			cnt_ctl = read_sysreg_el0(SYS_CNTP_CTL);
 			break;
 		case NR_KVM_TIMERS:
@@ -358,6 +410,7 @@ bool kvm_timer_is_pending(struct kvm_vcpu *vcpu)
 
 	return kvm_timer_should_fire(map.direct_vtimer) ||
 	       kvm_timer_should_fire(map.direct_ptimer) ||
+	       kvm_timer_should_fire(map.emul_vtimer) ||
 	       kvm_timer_should_fire(map.emul_ptimer);
 }
 
@@ -438,6 +491,7 @@ static void timer_save_state(struct arch_timer_context *ctx)
 
 	switch (index) {
 	case TIMER_VTIMER:
+	case TIMER_HVTIMER:
 		timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTV_CTL));
 		timer_set_cval(ctx, read_sysreg_el0(SYS_CNTV_CVAL));
 
@@ -447,6 +501,7 @@ static void timer_save_state(struct arch_timer_context *ctx)
 
 		break;
 	case TIMER_PTIMER:
+	case TIMER_HPTIMER:
 		timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTP_CTL));
 		timer_set_cval(ctx, read_sysreg_el0(SYS_CNTP_CVAL));
 
@@ -484,6 +539,7 @@ static void kvm_timer_blocking(struct kvm_vcpu *vcpu)
 	 */
 	if (!kvm_timer_irq_can_fire(map.direct_vtimer) &&
 	    !kvm_timer_irq_can_fire(map.direct_ptimer) &&
+	    !kvm_timer_irq_can_fire(map.emul_vtimer) &&
 	    !kvm_timer_irq_can_fire(map.emul_ptimer))
 		return;
 
@@ -517,11 +573,13 @@ static void timer_restore_state(struct arch_timer_context *ctx)
 
 	switch (index) {
 	case TIMER_VTIMER:
+	case TIMER_HVTIMER:
 		write_sysreg_el0(timer_get_cval(ctx), SYS_CNTV_CVAL);
 		isb();
 		write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTV_CTL);
 		break;
 	case TIMER_PTIMER:
+	case TIMER_HPTIMER:
 		write_sysreg_el0(timer_get_cval(ctx), SYS_CNTP_CVAL);
 		isb();
 		write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTP_CTL);
@@ -598,6 +656,42 @@ static void kvm_timer_vcpu_load_nogic(struct kvm_vcpu *vcpu)
 		enable_percpu_irq(host_vtimer_irq, host_vtimer_irq_flags);
 }
 
+static void kvm_timer_vcpu_load_nested_switch(struct kvm_vcpu *vcpu,
+					      struct timer_map *map)
+{
+	int hw, ret;
+
+	if (!irqchip_in_kernel(vcpu->kvm))
+		return;
+
+	/*
+	 * We only ever unmap the vtimer irq on a VHE system that runs nested
+	 * virtualization, in which case we have both a valid emul_vtimer,
+	 * emul_ptimer, direct_vtimer, and direct_ptimer.
+	 *
+	 * Since this is called from kvm_timer_vcpu_load(), a change between
+	 * vEL2 and vEL1/0 will have just happened, and the timer_map will
+	 * represent this, and therefore we switch the emul/direct mappings
+	 * below.
+	 */
+	hw = kvm_vgic_get_map(vcpu, map->direct_vtimer->irq.irq);
+	if (hw < 0) {
+		kvm_vgic_unmap_phys_irq(vcpu, map->emul_vtimer->irq.irq);
+		kvm_vgic_unmap_phys_irq(vcpu, map->emul_ptimer->irq.irq);
+
+		ret = kvm_vgic_map_phys_irq(vcpu,
+					    map->direct_vtimer->host_timer_irq,
+					    map->direct_vtimer->irq.irq,
+					    &arch_timer_irq_ops);
+		WARN_ON_ONCE(ret);
+		ret = kvm_vgic_map_phys_irq(vcpu,
+					    map->direct_ptimer->host_timer_irq,
+					    map->direct_ptimer->irq.irq,
+					    &arch_timer_irq_ops);
+		WARN_ON_ONCE(ret);
+	}
+}
+
 void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 {
 	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
@@ -609,6 +703,9 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 	get_timer_map(vcpu, &map);
 
 	if (static_branch_likely(&has_gic_active_state)) {
+		if (vcpu_has_nv(vcpu))
+			kvm_timer_vcpu_load_nested_switch(vcpu, &map);
+
 		kvm_timer_vcpu_load_gic(map.direct_vtimer);
 		if (map.direct_ptimer)
 			kvm_timer_vcpu_load_gic(map.direct_ptimer);
@@ -624,6 +721,8 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
 	if (map.direct_ptimer)
 		timer_restore_state(map.direct_ptimer);
 
+	if (map.emul_vtimer)
+		timer_emulate(map.emul_vtimer);
 	if (map.emul_ptimer)
 		timer_emulate(map.emul_ptimer);
 }
@@ -668,6 +767,8 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu)
 	 * In any case, we re-schedule the hrtimer for the physical timer when
 	 * coming back to the VCPU thread in kvm_timer_vcpu_load().
 	 */
+	if (map.emul_vtimer)
+		soft_timer_cancel(&map.emul_vtimer->hrtimer);
 	if (map.emul_ptimer)
 		soft_timer_cancel(&map.emul_ptimer->hrtimer);
 
@@ -728,10 +829,14 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 	 */
 	timer_set_ctl(vcpu_vtimer(vcpu), 0);
 	timer_set_ctl(vcpu_ptimer(vcpu), 0);
+	timer_set_ctl(vcpu_hvtimer(vcpu), 0);
+	timer_set_ctl(vcpu_hptimer(vcpu), 0);
 
 	if (timer->enabled) {
 		kvm_timer_update_irq(vcpu, false, vcpu_vtimer(vcpu));
 		kvm_timer_update_irq(vcpu, false, vcpu_ptimer(vcpu));
+		kvm_timer_update_irq(vcpu, false, vcpu_hvtimer(vcpu));
+		kvm_timer_update_irq(vcpu, false, vcpu_hptimer(vcpu));
 
 		if (irqchip_in_kernel(vcpu->kvm)) {
 			kvm_vgic_reset_mapped_irq(vcpu, map.direct_vtimer->irq.irq);
@@ -740,6 +845,8 @@ int kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu)
 		}
 	}
 
+	if (map.emul_vtimer)
+		soft_timer_cancel(&map.emul_vtimer->hrtimer);
 	if (map.emul_ptimer)
 		soft_timer_cancel(&map.emul_ptimer->hrtimer);
 
@@ -770,30 +877,47 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
 	struct arch_timer_cpu *timer = vcpu_timer(vcpu);
 	struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
 	struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
+	struct arch_timer_context *hvtimer = vcpu_hvtimer(vcpu);
+	struct arch_timer_context *hptimer = vcpu_hptimer(vcpu);
 
 	vtimer->vcpu = vcpu;
 	ptimer->vcpu = vcpu;
+	hvtimer->vcpu = vcpu;
+	hptimer->vcpu = vcpu;
 
 	/* Synchronize cntvoff across all vtimers of a VM. */
 	update_vtimer_cntvoff(vcpu, kvm_phys_timer_read());
 	timer_set_offset(ptimer, 0);
+	timer_set_offset(hvtimer, 0);
+	timer_set_offset(hptimer, 0);
 
 	hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
 	timer->bg_timer.function = kvm_bg_timer_expire;
 
 	hrtimer_init(&vtimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
 	hrtimer_init(&ptimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
+	hrtimer_init(&hvtimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
+	hrtimer_init(&hptimer->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
+
 	vtimer->hrtimer.function = kvm_hrtimer_expire;
 	ptimer->hrtimer.function = kvm_hrtimer_expire;
+	hvtimer->hrtimer.function = kvm_hrtimer_expire;
+	hptimer->hrtimer.function = kvm_hrtimer_expire;
 
 	vtimer->irq.irq = default_vtimer_irq.irq;
 	ptimer->irq.irq = default_ptimer_irq.irq;
+	hvtimer->irq.irq = default_hvtimer_irq.irq;
+	hptimer->irq.irq = default_hptimer_irq.irq;
 
 	vtimer->host_timer_irq = host_vtimer_irq;
 	ptimer->host_timer_irq = host_ptimer_irq;
+	hvtimer->host_timer_irq = host_vtimer_irq;
+	hptimer->host_timer_irq = host_ptimer_irq;
 
 	vtimer->host_timer_irq_flags = host_vtimer_irq_flags;
 	ptimer->host_timer_irq_flags = host_ptimer_irq_flags;
+	hvtimer->host_timer_irq_flags = host_vtimer_irq_flags;
+	hptimer->host_timer_irq_flags = host_ptimer_irq_flags;
 }
 
 static void kvm_timer_init_interrupt(void *info)
@@ -900,6 +1024,10 @@ static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
 		val = kvm_phys_timer_read() - timer_get_offset(timer);
 		break;
 
+	case TIMER_REG_VOFF:
+		val = timer_get_offset(timer);
+		break;
+
 	default:
 		BUG();
 	}
@@ -942,6 +1070,10 @@ static void kvm_arm_timer_write(struct kvm_vcpu *vcpu,
 		timer_set_cval(timer, val);
 		break;
 
+	case TIMER_REG_VOFF:
+		timer_set_offset(timer, val);
+		break;
+
 	default:
 		BUG();
 	}
@@ -1040,10 +1172,6 @@ static const struct irq_domain_ops timer_domain_ops = {
 	.free	= timer_irq_domain_free,
 };
 
-static struct irq_ops arch_timer_irq_ops = {
-	.get_input_level = kvm_arch_timer_get_input_level,
-};
-
 static void kvm_irq_fixup_flags(unsigned int virq, u32 *flags)
 {
 	*flags = irq_get_trigger_type(virq);
@@ -1188,7 +1316,7 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu)
 
 static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)
 {
-	int vtimer_irq, ptimer_irq, ret;
+	int vtimer_irq, ptimer_irq, hvtimer_irq, hptimer_irq, ret;
 	unsigned long i;
 
 	vtimer_irq = vcpu_vtimer(vcpu)->irq.irq;
@@ -1201,16 +1329,28 @@ static bool timer_irqs_are_valid(struct kvm_vcpu *vcpu)
 	if (ret)
 		return false;
 
+	hvtimer_irq = vcpu_hvtimer(vcpu)->irq.irq;
+	ret = kvm_vgic_set_owner(vcpu, hvtimer_irq, vcpu_hvtimer(vcpu));
+	if (ret)
+		return false;
+
+	hptimer_irq = vcpu_hptimer(vcpu)->irq.irq;
+	ret = kvm_vgic_set_owner(vcpu, hptimer_irq, vcpu_hptimer(vcpu));
+	if (ret)
+		return false;
+
 	kvm_for_each_vcpu(i, vcpu, vcpu->kvm) {
 		if (vcpu_vtimer(vcpu)->irq.irq != vtimer_irq ||
-		    vcpu_ptimer(vcpu)->irq.irq != ptimer_irq)
+		    vcpu_ptimer(vcpu)->irq.irq != ptimer_irq ||
+		    vcpu_hvtimer(vcpu)->irq.irq != hvtimer_irq ||
+		    vcpu_hptimer(vcpu)->irq.irq != hptimer_irq)
 			return false;
 	}
 
 	return true;
 }
 
-bool kvm_arch_timer_get_input_level(int vintid)
+static bool kvm_arch_timer_get_input_level(int vintid)
 {
 	struct kvm_vcpu *vcpu = kvm_get_running_vcpu();
 	struct arch_timer_context *timer;
@@ -1219,6 +1359,10 @@ bool kvm_arch_timer_get_input_level(int vintid)
 		timer = vcpu_vtimer(vcpu);
 	else if (vintid == vcpu_ptimer(vcpu)->irq.irq)
 		timer = vcpu_ptimer(vcpu);
+	else if (vintid == vcpu_hvtimer(vcpu)->irq.irq)
+		timer = vcpu_hvtimer(vcpu);
+	else if (vintid == vcpu_hptimer(vcpu)->irq.irq)
+		timer = vcpu_hptimer(vcpu);
 	else
 		BUG();
 
@@ -1301,6 +1445,7 @@ static void set_timer_irqs(struct kvm *kvm, int vtimer_irq, int ptimer_irq)
 	kvm_for_each_vcpu(i, vcpu, kvm) {
 		vcpu_vtimer(vcpu)->irq.irq = vtimer_irq;
 		vcpu_ptimer(vcpu)->irq.irq = ptimer_irq;
+		/* TODO: Add support for hv/hp timers */
 	}
 }
 
@@ -1311,6 +1456,8 @@ int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
 	int irq;
 
+	/* TODO: Add support for hv/hp timers */
+
 	if (!irqchip_in_kernel(vcpu->kvm))
 		return -EINVAL;
 
@@ -1343,6 +1490,8 @@ int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
 	struct arch_timer_context *timer;
 	int irq;
 
+	/* TODO: Add support for hv/hp timers */
+
 	switch (attr->attr) {
 	case KVM_ARM_VCPU_TIMER_IRQ_VTIMER:
 		timer = vcpu_vtimer(vcpu);
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index d7441b8ba406..bbc58930a5eb 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -1288,6 +1288,11 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
 		tmr = TIMER_PTIMER;
 		treg = TIMER_REG_CVAL;
 		break;
+	case SYS_CNTVOFF_EL2:
+		tmr = TIMER_VTIMER;
+		treg = TIMER_REG_VOFF;
+		break;
+
 	default:
 		BUG();
 	}
@@ -2212,7 +2217,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
 	EL2_REG(CONTEXTIDR_EL2, access_rw, reset_val, 0),
 	EL2_REG(TPIDR_EL2, access_rw, reset_val, 0),
 
-	EL2_REG(CNTVOFF_EL2, access_rw, reset_val, 0),
+	{ SYS_DESC(SYS_CNTVOFF_EL2), access_arch_timer },
 	EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0),
 
 	EL12_REG(SCTLR, access_vm_reg, reset_val, 0x00C50078),
diff --git a/arch/arm64/kvm/trace_arm.h b/arch/arm64/kvm/trace_arm.h
index f3e46a976125..6ce5c025218d 100644
--- a/arch/arm64/kvm/trace_arm.h
+++ b/arch/arm64/kvm/trace_arm.h
@@ -206,6 +206,7 @@ TRACE_EVENT(kvm_get_timer_map,
 		__field(	unsigned long,		vcpu_id	)
 		__field(	int,			direct_vtimer	)
 		__field(	int,			direct_ptimer	)
+		__field(	int,			emul_vtimer	)
 		__field(	int,			emul_ptimer	)
 	),
 
@@ -214,14 +215,17 @@ TRACE_EVENT(kvm_get_timer_map,
 		__entry->direct_vtimer		= arch_timer_ctx_index(map->direct_vtimer);
 		__entry->direct_ptimer =
 			(map->direct_ptimer) ? arch_timer_ctx_index(map->direct_ptimer) : -1;
+		__entry->emul_vtimer =
+			(map->emul_vtimer) ? arch_timer_ctx_index(map->emul_vtimer) : -1;
 		__entry->emul_ptimer =
 			(map->emul_ptimer) ? arch_timer_ctx_index(map->emul_ptimer) : -1;
 	),
 
-	TP_printk("VCPU: %ld, dv: %d, dp: %d, ep: %d",
+	TP_printk("VCPU: %ld, dv: %d, dp: %d, ev: %d, ep: %d",
 		  __entry->vcpu_id,
 		  __entry->direct_vtimer,
 		  __entry->direct_ptimer,
+		  __entry->emul_vtimer,
 		  __entry->emul_ptimer)
 );
 
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 9b98876a8a93..e7fe0447af08 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -573,6 +573,21 @@ int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid)
 	return 0;
 }
 
+int kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid)
+{
+	struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, vintid);
+	unsigned long flags;
+	int ret = -1;
+
+	raw_spin_lock_irqsave(&irq->irq_lock, flags);
+	if (irq->hw)
+		ret = irq->hwintid;
+	raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
+
+	vgic_put_irq(vcpu->kvm, irq);
+	return ret;
+}
+
 /**
  * kvm_vgic_set_owner - Set the owner of an interrupt for a VM
  *
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 51c19381108c..0a76dac8cb6a 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -13,6 +13,8 @@
 enum kvm_arch_timers {
 	TIMER_PTIMER,
 	TIMER_VTIMER,
+	TIMER_HVTIMER,
+	TIMER_HPTIMER,
 	NR_KVM_TIMERS
 };
 
@@ -21,6 +23,7 @@ enum kvm_arch_timer_regs {
 	TIMER_REG_CVAL,
 	TIMER_REG_TVAL,
 	TIMER_REG_CTL,
+	TIMER_REG_VOFF,
 };
 
 struct arch_timer_context {
@@ -47,6 +50,7 @@ struct arch_timer_context {
 struct timer_map {
 	struct arch_timer_context *direct_vtimer;
 	struct arch_timer_context *direct_ptimer;
+	struct arch_timer_context *emul_vtimer;
 	struct arch_timer_context *emul_ptimer;
 };
 
@@ -85,12 +89,12 @@ void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
 
 void kvm_timer_init_vhe(void);
 
-bool kvm_arch_timer_get_input_level(int vintid);
-
 #define vcpu_timer(v)	(&(v)->arch.timer_cpu)
 #define vcpu_get_timer(v,t)	(&vcpu_timer(v)->timers[(t)])
 #define vcpu_vtimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_VTIMER])
 #define vcpu_ptimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_PTIMER])
+#define vcpu_hvtimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_HVTIMER])
+#define vcpu_hptimer(v)	(&(v)->arch.timer_cpu.timers[TIMER_HPTIMER])
 
 #define arch_timer_ctx_index(ctx)	((ctx) - vcpu_timer((ctx)->vcpu)->timers)
 
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index bb30a6803d9f..17b651890d22 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -375,6 +375,7 @@ int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int intid,
 int kvm_vgic_map_phys_irq(struct kvm_vcpu *vcpu, unsigned int host_irq,
 			  u32 vintid, struct irq_ops *ops);
 int kvm_vgic_unmap_phys_irq(struct kvm_vcpu *vcpu, unsigned int vintid);
+int kvm_vgic_get_map(struct kvm_vcpu *vcpu, unsigned int vintid);
 bool kvm_vgic_map_is_active(struct kvm_vcpu *vcpu, unsigned int vintid);
 
 int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu);
-- 
2.30.2



From maz at kernel.org  Fri Jan 28 04:19:00 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 12:19:00 +0000
Subject: [PATCH v6 52/64] KVM: arm64: nv: Allow userspace to request
 KVM_ARM_VCPU_NESTED_VIRT
In-Reply-To: <20220128121912.509006-1-maz@kernel.org>
References: <20220128121912.509006-1-maz@kernel.org>
Message-ID: <20220128121912.509006-53-maz@kernel.org>

Since we're (almost) feature complete, let's allow userspace to
request KVM_ARM_VCPU_NESTED_VIRT by bumping the KVM_VCPU_MAX_FEATURES
up. We also now advertise the feature to userspace with a new capability.

It's going to be great...

Signed-off-by: Marc Zyngier <maz at kernel.org>
---
 arch/arm64/include/asm/kvm_host.h | 2 +-
 arch/arm64/kvm/arm.c              | 3 +++
 include/uapi/linux/kvm.h          | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 6bfdb21c0d8a..0ea8cf0eeca7 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -37,7 +37,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 7
+#define KVM_VCPU_MAX_FEATURES 8
 
 #define KVM_REQ_SLEEP \
 	KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 91fb7bc09b8e..ac7d89c1e987 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -258,6 +258,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_EL1_32BIT:
 		r = cpus_have_const_cap(ARM64_HAS_32BIT_EL1);
 		break;
+	case KVM_CAP_ARM_EL2:
+		r = cpus_have_const_cap(ARM64_HAS_NESTED_VIRT);
+		break;
 	case KVM_CAP_GUEST_DEBUG_HW_BPS:
 		r = get_num_brps();
 		break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 9563d294f181..6950497e5032 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1133,6 +1133,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_VM_MOVE_ENC_CONTEXT_FROM 206
 #define KVM_CAP_VM_GPA_BITS 207
 #define KVM_CAP_XSAVE2 208
+#define KVM_CAP_ARM_EL2 209
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
2.30.2



From robin.murphy at arm.com  Fri Jan 28 05:04:07 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 28 Jan 2022 13:04:07 +0000
Subject: [RFC PATCH] component: Add common helpers for compare/release
 functions
In-Reply-To: <20220128081101.27837-1-yong.wu@mediatek.com>
References: <20220128081101.27837-1-yong.wu@mediatek.com>
Message-ID: <29deffd6-aac4-f085-bcd5-f5a2d02784a8@arm.com>

On 2022-01-28 08:11, Yong Wu wrote:
[...]
> diff --git a/include/linux/component.h b/include/linux/component.h
> index 16de18f473d7..5a7468ea827c 100644
> --- a/include/linux/component.h
> +++ b/include/linux/component.h
> @@ -2,6 +2,8 @@
>   #ifndef COMPONENT_H
>   #define COMPONENT_H
>   
> +#include <linux/device.h>
> +#include <linux/of.h>
>   #include <linux/stddef.h>
>   
>   
> @@ -82,6 +84,22 @@ struct component_master_ops {
>   	void (*unbind)(struct device *master);
>   };
>   
> +/* A set common helpers for compare/release functions */
> +static inline int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}

Note that this is effectively just device_match_of_node(), although I 
guess there is an argument that having a nice consistent set of 
component_match API helpers might be worth more than a tiny code saving 
by borrowing one from a different API.

Either way, however, I don't think there's any good argument for 
instantiating separate copies of these functions in every driver that 
uses them. If they're used as callbacks then they can't actually be 
inlined anyway, so they may as well be exported from component.c as 
normal so that the code really is shared (plus then there's nice 
symmetry with the aforementioned device_match API helpers too).

Thanks,
Robin.

> +static inline void release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +
> +static inline int compare_dev(struct device *dev, void *data)
> +{
> +	return dev == data;
> +}
> +
>   void component_master_del(struct device *,
>   	const struct component_master_ops *);
>   
> diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
> index eff200a07d9f..992132cbfb9f 100644
> --- a/sound/soc/codecs/wcd938x.c
> +++ b/sound/soc/codecs/wcd938x.c
> @@ -4417,16 +4417,6 @@ static const struct component_master_ops wcd938x_comp_ops = {
>   	.unbind = wcd938x_unbind,
>   };
>   
> -static int wcd938x_compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
> -static void wcd938x_release_of(struct device *dev, void *data)
> -{
> -	of_node_put(data);
> -}
> -
>   static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>   					struct device *dev,
>   					struct component_match **matchptr)
> @@ -4442,8 +4432,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>   	}
>   
>   	of_node_get(wcd938x->rxnode);
> -	component_match_add_release(dev, matchptr, wcd938x_release_of,
> -				    wcd938x_compare_of,	wcd938x->rxnode);
> +	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->rxnode);
>   
>   	wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
>   	if (!wcd938x->txnode) {
> @@ -4451,8 +4440,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>   		return -ENODEV;
>   	}
>   	of_node_get(wcd938x->txnode);
> -	component_match_add_release(dev, matchptr, wcd938x_release_of,
> -				    wcd938x_compare_of,	wcd938x->txnode);
> +	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->txnode);
>   	return 0;
>   }
>   


From robh+dt at kernel.org  Fri Jan 28 05:04:10 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 28 Jan 2022 07:04:10 -0600
Subject: [PATCH 1/2] dt-bindings: display: imx: Add fsl,imx21-lcdc docs
In-Reply-To: <20220128105849.368438-2-u.kleine-koenig@pengutronix.de>
References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
 <20220128105849.368438-2-u.kleine-koenig@pengutronix.de>
Message-ID: <CAL_JsqJjTf2zY-n69Ozh+S1gSi5Eoa5T44Qnq9RPNgJWDLmzKQ@mail.gmail.com>

On Fri, Jan 28, 2022 at 4:59 AM Uwe Kleine-K?nig
<u.kleine-koenig at pengutronix.de> wrote:
>
> From: Marian Cichy <m.cichy at pengutronix.de>
>
> This files documents the device tree for the new imx21-lcdc DRM driver.

No, bindings document h/w and the h/w has not changed. We already have
a binding for the LCDC.

>
> Signed-off-by: Marian Cichy <m.cichy at pengutronix.de>
> Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig at pengutronix.de>
> ---
>  .../bindings/display/imx/fsl,imx21-lcdc.yaml  | 79 +++++++++++++++++++
>  1 file changed, 79 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
>
> diff --git a/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml b/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
> new file mode 100644
> index 000000000000..edf71cfac81c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/imx/fsl,imx21-lcdc.yaml
> @@ -0,0 +1,79 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/display/imx/fsl,imx21-lcdc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: i.MX21 LCD Controller
> +
> +maintainers:
> +  - Philipp Zabel <p.zabel at pengutronix.de>
> +
> +properties:
> +  compatible:
> +    oneOf:
> +      - const: fsl,imx21-lcdc
> +      - items:
> +          - enum:
> +              - fsl,imx25-lcdc
> +              - fsl,imx27-lcdc
> +          - const: fsl,imx21-lcdc
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 3
> +
> +  clock-names:
> +    items:
> +      - const: ipg
> +      - const: per
> +      - const: ahb
> +
> +  resets:
> +    maxItems: 1
> +
> +  port:
> +    type: object
> +    description:
> +      "Video port for DPI RGB output."
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts
> +  - clocks
> +  - clock-names
> +  - port
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    lcdc: lcdc at 53fbc000 {
> +        compatible = "fsl,imx25-lcdc", "fsl,imx21-lcdc";
> +        reg = <0x53fbc000 0x4000>;
> +        interrupts = <39>;
> +        clocks = <&clks 103>, <&clks 66>, <&clks 49>;
> +        clock-names = "ipg", "ahb", "per";
> +
> +        port {
> +             parallel_out: endpoint {
> +                 remote-endpoint = <&panel_in>;
> +             };
> +        };
> +
> +    };
> +
> +    panel: panel {
> +        compatible = "edt,etm0700g0dh6";
> +        power-supply = <&lcd_supply>;
> +        backlight = <&bl>;
> +
> +        port {
> +                panel_in: endpoint {
> +                        remote-endpoint = <&parallel_out>;
> +                };
> +        };
> +    };
> --
> 2.34.1
>


From broonie at kernel.org  Fri Jan 28 05:06:19 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 13:06:19 +0000
Subject: [PATCH] ASoC: dt-bindings: Centralize the 'sound-dai' definition
In-Reply-To: <20220126231427.1638089-1-robh@kernel.org>
References: <20220126231427.1638089-1-robh@kernel.org>
Message-ID: <YfPqS8v7ZtT6HDyS@sirena.org.uk>

On Wed, Jan 26, 2022 at 05:14:27PM -0600, Rob Herring wrote:
> 'sound-dai' is a common property, but has duplicate type definitions.
> Create a new common definition to define the type and then update all
> the other occurrences to just define how many entries there are just
> like other phandle+arg properties.

Acked-by: Mark Brown <broonie at kernel.org>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/85a95f44/attachment.sig>

From helgaas at kernel.org  Fri Jan 28 05:12:50 2022
From: helgaas at kernel.org (Bjorn Helgaas)
Date: Fri, 28 Jan 2022 07:12:50 -0600
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <87r18s5jbn.wl-maz@kernel.org>
Message-ID: <20220128131250.GA200007@bhelgaas>

On Fri, Jan 28, 2022 at 08:57:16AM +0000, Marc Zyngier wrote:
> On Thu, 27 Jan 2022 21:21:00 +0000,
> Bjorn Helgaas <helgaas at kernel.org> wrote:
> > On Wed, Jan 26, 2022 at 11:37:58AM +0800, qizhong.cheng wrote:
> > > On Tue, 2022-01-25 at 17:21 +0000, Marc Zyngier wrote:
> > > > On 2022-01-25 16:57, Bjorn Helgaas wrote:
> > > > > On Sun, Jan 23, 2022 at 11:33:06AM +0800, qizhong cheng wrote:
> > > > > > As an edge-triggered interrupts, its interrupt status should
> > > > > > be cleared before dispatch to the handler of device.
> > > > > 
> > > > > I'm not an IRQ expert, but the reasoning that "we should clear
> > > > > the MSI interrupt status before dispatching the handler because
> > > > > MSI is an edge-triggered interrupt" doesn't seem completely
> > > > > convincing because your code will now look like this:
> > > > > 
> > > > >   /* Clear the INTx */
> > > > >   writel(1 << bit, port->base + PCIE_INT_STATUS);
> > > > >   generic_handle_domain_irq(port->irq_domain, bit - INTX_SHIFT);
> > > > >   ...
> > > > > 
> > > > >   /* Clear MSI interrupt status */
> > > > >   writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
> > > > >   generic_handle_domain_irq(port->inner_domain, bit);
> > > > > 
> > > > > You clear interrupt status before dispatching the handler for
> > > > > *both* level-triggered INTx interrupts and edge-triggered MSI
> > > > > interrupts.
> > > > > 
> > > > > So it doesn't seem that simply being edge-triggered is the
> > > > > critical factor here.
> > > > 
> > > > This is the usual problem with these half-baked implementations.
> > > > The signalling to the primary interrupt controller is level, as
> > > > they take a multitude of input and (crucially) latch the MSI
> > > > edges. Effectively, this is an edge-to-level converter, with all
> > > > the problems that this creates.
> > > > 
> > > > By clearing the status *after* the handling, you lose edges that
> > > > have been received and coalesced after the read of the status
> > > > register. By clearing it *before*, you are acknowledging the
> > > > interrupts early, and allowing them to be coalesced independently
> > > > of the ones that have been received earlier.
> > > > 
> > > > This is however mostly an educated guess. Someone with access to
> > > > the TRM should verify this.
> > > 
> > > Yes, as Maz said, we save the edge-interrupt status so that it
> > > becomes a level-interrupt. This is similar to an edge-to-level
> > > converter, so we need to clear it *before*. We found this problem
> > > through a lot of experiments and tested this patch.
> > 
> > I thought there might be other host controllers with similar design,
> > so I looked at all the other drivers and tried to figure out whether
> > any others had similar problems.
> > 
> > The ones below look suspicious to me because they all clear some sort
> > of status register *after* handling an MSI.  Can you guys take a look
> > and make sure they are working correctly?
> > 
> >   keembay_pcie_msi_irq_handler
> >     status = readl(pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
> >     if (status & MSI_CTRL_INT)
> >       dw_handle_msi_irq
> > 	generic_handle_domain_irq
> >       writel(status, pcie->apb_base + PCIE_REGS_INTERRUPT_STATUS)
> > 
> >   spear13xx_pcie_irq_handler
> >     status = readl(&app_reg->int_sts)
> >     if (status & MSI_CTRL_INT)
> >       dw_handle_msi_irq
> > 	generic_handle_domain_irq
> >     writel(status, &app_reg->int_clr)
> 
> I think these two are fine.
> 
> The top level interrupt is only a level signal that the is something
> to process. The only thing that is unclear is what the effect of
> writing to that status register if MSIs are pending at that point. A
> sane implementation would just ignore the write.
> 
> The actual processing is done in dw_handle_msi_irq(), reading the
> PCIE_MSI_INTR0_STATUS register. This same register is then used to Ack
> the interrupt, one bit at a time, as interrupts are handled (see
> dw_pci_bottom_ack). Ack taking place before the handling, it makes it
> safe for edge delivery.
> 
> >   advk_pcie_handle_int
> >     isr0_status = advk_readl(pcie, PCIE_ISR0_REG)
> >     if (isr0_status & PCIE_ISR0_MSI_INT_PENDING)
> >       advk_pcie_handle_msi
> >         advk_readl(pcie, PCIE_MSI_STATUS_REG)
> > 	advk_writel(pcie, BIT(msi_idx), PCIE_MSI_STATUS_REG)
> > 	generic_handle_irq
> > 	advk_writel(pcie, PCIE_ISR0_MSI_INT_PENDING, PCIE_ISR0_REG)
> 
> Same thing, I guess. It is just that the Ack has been open-coded.
> 
> >   mtk_pcie_irq_handler
> >     status = readl_relaxed(pcie->base + PCIE_INT_STATUS_REG)
> >     for_each_set_bit_from(irq_bit, &status, ...)
> >       mtk_pcie_msi_handler
> >         generic_handle_domain_irq
> >       writel_relaxed(BIT(irq_bit), pcie->base + PCIE_INT_STATUS_REG)
> 
> Similar thing. The PCIE_MSI_SET_STATUS register is read first, and
> then written back in the ack callback.

Thanks a lot for taking a look at these, Marc!  Is there anything we
can do to make all these drivers/pci/controller/* drivers more
consistent and easier to review?  I found it very difficult to look
across all of them and find similar design patterns.

Bjorn


From andriy.shevchenko at linux.intel.com  Fri Jan 28 05:23:19 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 15:23:19 +0200
Subject: [PATCH v20 2/3] Input: mt6779-keypad - Add MediaTek keypad driver
In-Reply-To: <87v8y4p483.fsf@baylibre.com>
References: <20220127111526.3716689-1-mkorpershoek@baylibre.com>
 <20220127111526.3716689-3-mkorpershoek@baylibre.com>
 <YfK4UcuCfF7JfI7H@smile.fi.intel.com> <87v8y4p483.fsf@baylibre.com>
Message-ID: <YfPuR/Q5//hSQYKG@smile.fi.intel.com>

On Fri, Jan 28, 2022 at 11:03:08AM +0100, Mattijs Korpershoek wrote:
> On Thu, Jan 27, 2022 at 17:20, Andy Shevchenko <andriy.shevchenko at linux.intel.com> wrote:
> > On Thu, Jan 27, 2022 at 12:15:25PM +0100, Mattijs Korpershoek wrote:

...

> > Up to you.

> Thank you for your review and your suggestions.

Yes, as I said it you need a new version and consider them good.
Thanks!

-- 
With Best Regards,
Andy Shevchenko




From hayashi.kunihiko at socionext.com  Fri Jan 28 05:35:01 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 28 Jan 2022 22:35:01 +0900
Subject: [PATCH v2 1/3] pinctrl: uniphier: Add missing audio pinmux settings
 for PXs2 SoC
In-Reply-To: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643376903-18623-2-git-send-email-hayashi.kunihiko@socionext.com>

Add missing audio I/O pinmux settings for PXs2 SoC.
This adds ain1 4ch pins, ain3 and aout1.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index e52e65a24048..6ef892543cb9 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -719,12 +719,16 @@ static const struct pinctrl_pin_desc uniphier_pxs2_pins[] = {
 			     234, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {161, 162, 173, 174};
-static const int ain1_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain1_pins[] = {161, 162, 173, 174, 127, 128, 129};
+static const int ain1_muxvals[] = {8, 8, 8, 8, 3, 3, 3};
 static const unsigned ain2_pins[] = {98, 99, 100, 101, 102, 103, 104};
 static const int ain2_muxvals[] = {8, 8, 8, 8, 8, 8, 8};
+static const unsigned ain3_pins[] = {132, 133, 134, 131};
+static const int ain3_muxvals[] = {5, 5, 5, 5};
 static const unsigned ainiec1_pins[] = {91};
 static const int ainiec1_muxvals[] = {11};
+static const unsigned aout1_pins[] = {87, 88, 89, 90, 92, 93, 94};
+static const int aout1_muxvals[] = {11, 11, 11, 11, 11, 11, 11};
 static const unsigned aout2_pins[] = {175, 176, 177, 178, 183, 184, 185};
 static const int aout2_muxvals[] = {8, 8, 8, 8, 9, 9, 9};
 static const unsigned aout3_pins[] = {105, 106, 107, 108};
@@ -839,7 +843,9 @@ static const unsigned int gpio_range1_pins[] = {
 static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
+	UNIPHIER_PINCTRL_GROUP(aout1),
 	UNIPHIER_PINCTRL_GROUP(aout2),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -880,7 +886,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 
 static const char * const ain1_groups[] = {"ain1"};
 static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain3_groups[] = {"ain3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
+static const char * const aout1_groups[] = {"aout1"};
 static const char * const aout2_groups[] = {"aout2"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
-- 
2.7.4



From hayashi.kunihiko at socionext.com  Fri Jan 28 05:35:00 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 28 Jan 2022 22:35:00 +0900
Subject: [PATCH v2 0/3] pinctrl: uniphier: Add some more pinmux settings
Message-ID: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>

This series includes changes to audio I/O pinmux settings and addition
to USB device pinmux settings.

- Divide audio I/O pinmux groups so that 1/2/4ch can be specified.
  The audio I/O function is available for LD11, LD20, PXs2 and PXs3 SoCs.
  In addition, add the missing pinmux settings for PXs2.

- Add USB device pinmux settings. The USB device function is available
  for PXs2 and PXs3 SoCs.

---
Changes since v1:
- Remove the line of the nonexistent function

Kunihiko Hayashi (3):
  pinctrl: uniphier: Add missing audio pinmux settings for PXs2 SoC
  pinctrl: uniphier: Divide pinmux group to support 1ch and 2ch I2S
  pinctrl: uniphier: Add USB device pinmux settings

 drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c | 26 +++++++---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c | 64 ++++++++++++++++++------
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 62 +++++++++++++++++++----
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 62 +++++++++++++++++------
 4 files changed, 171 insertions(+), 43 deletions(-)

-- 
2.7.4



From hayashi.kunihiko at socionext.com  Fri Jan 28 05:35:03 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 28 Jan 2022 22:35:03 +0900
Subject: [PATCH v2 3/3] pinctrl: uniphier: Add USB device pinmux settings
In-Reply-To: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643376903-18623-4-git-send-email-hayashi.kunihiko@socionext.com>

Add USB device pinmux settings for PXs2 and PXs3 SoCs. Only pins for
ports 0 and 1 support USB device mode.

Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 10 ++++++++--
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 10 ++++++++--
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index 7da8616f8d47..2a9dbf969f0b 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -817,8 +817,12 @@ static const unsigned uart3b_pins[] = {181, 182};
 static const int uart3b_muxvals[] = {10, 10};
 static const unsigned usb0_pins[] = {56, 57};
 static const int usb0_muxvals[] = {8, 8};
+static const unsigned usb0_device_pins[] = {213};
+static const int usb0_device_muxvals[] = {9};
 static const unsigned usb1_pins[] = {58, 59};
 static const int usb1_muxvals[] = {8, 8};
+static const unsigned usb1_device_pins[] = {214};
+static const int usb1_device_muxvals[] = {9};
 static const unsigned usb2_pins[] = {60, 61};
 static const int usb2_muxvals[] = {8, 8};
 static const unsigned usb3_pins[] = {62, 63};
@@ -901,7 +905,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(uart3),
 	UNIPHIER_PINCTRL_GROUP(uart3b),
 	UNIPHIER_PINCTRL_GROUP(usb0),
+	UNIPHIER_PINCTRL_GROUP(usb0_device),
 	UNIPHIER_PINCTRL_GROUP(usb1),
+	UNIPHIER_PINCTRL_GROUP(usb1_device),
 	UNIPHIER_PINCTRL_GROUP(usb2),
 	UNIPHIER_PINCTRL_GROUP(usb3),
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range0),
@@ -942,8 +948,8 @@ static const char * const uart0_groups[] = {"uart0", "uart0b",
 static const char * const uart1_groups[] = {"uart1"};
 static const char * const uart2_groups[] = {"uart2"};
 static const char * const uart3_groups[] = {"uart3", "uart3b"};
-static const char * const usb0_groups[] = {"usb0"};
-static const char * const usb1_groups[] = {"usb1"};
+static const char * const usb0_groups[] = {"usb0", "usb0_device"};
+static const char * const usb1_groups[] = {"usb1", "usb1_device"};
 static const char * const usb2_groups[] = {"usb2"};
 static const char * const usb3_groups[] = {"usb3"};
 
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
index eb3c9b55f6e3..ab3bd2d9c6c7 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
@@ -855,8 +855,12 @@ static const unsigned int uart3_pins[] = {98, 99};
 static const int uart3_muxvals[] = {0, 0};
 static const unsigned int usb0_pins[] = {84, 85};
 static const int usb0_muxvals[] = {0, 0};
+static const unsigned int usb0_device_pins[] = {110};
+static const int usb0_device_muxvals[] = {2};
 static const unsigned int usb1_pins[] = {86, 87};
 static const int usb1_muxvals[] = {0, 0};
+static const unsigned int usb1_device_pins[] = {111};
+static const int usb1_device_muxvals[] = {2};
 static const unsigned int usb2_pins[] = {88, 89};
 static const int usb2_muxvals[] = {0, 0};
 static const unsigned int usb3_pins[] = {90, 91};
@@ -942,7 +946,9 @@ static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(uart2),
 	UNIPHIER_PINCTRL_GROUP(uart3),
 	UNIPHIER_PINCTRL_GROUP(usb0),
+	UNIPHIER_PINCTRL_GROUP(usb0_device),
 	UNIPHIER_PINCTRL_GROUP(usb1),
+	UNIPHIER_PINCTRL_GROUP(usb1_device),
 	UNIPHIER_PINCTRL_GROUP(usb2),
 	UNIPHIER_PINCTRL_GROUP(usb3),
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range0),
@@ -982,8 +988,8 @@ static const char * const uart0_groups[] = {"uart0", "uart0_ctsrts",
 static const char * const uart1_groups[] = {"uart1"};
 static const char * const uart2_groups[] = {"uart2"};
 static const char * const uart3_groups[] = {"uart3"};
-static const char * const usb0_groups[] = {"usb0"};
-static const char * const usb1_groups[] = {"usb1"};
+static const char * const usb0_groups[] = {"usb0", "usb0_device"};
+static const char * const usb1_groups[] = {"usb1", "usb1_device"};
 static const char * const usb2_groups[] = {"usb2"};
 static const char * const usb3_groups[] = {"usb3"};
 
-- 
2.7.4



From hayashi.kunihiko at socionext.com  Fri Jan 28 05:35:02 2022
From: hayashi.kunihiko at socionext.com (Kunihiko Hayashi)
Date: Fri, 28 Jan 2022 22:35:02 +0900
Subject: [PATCH v2 2/3] pinctrl: uniphier: Divide pinmux group to support 1ch
 and 2ch I2S
In-Reply-To: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
References: <1643376903-18623-1-git-send-email-hayashi.kunihiko@socionext.com>
Message-ID: <1643376903-18623-3-git-send-email-hayashi.kunihiko@socionext.com>

Current pinmux group for audio in/out assumes 4ch I2S case but the
UniPhier AIO hardware also supports 1ch and 2ch I2S. So divide current
ain1 group into ain1, ain1_dat2 and ain1_dat4 groups. Divide other
ain and aout in the same way.

Signed-off-by: Ryuta NAKANISHI <nakanishi.ryuta at socionext.com>
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko at socionext.com>
---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c | 26 +++++++---
 drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c | 64 ++++++++++++++++++------
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 54 +++++++++++++++-----
 drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c | 52 ++++++++++++++-----
 4 files changed, 152 insertions(+), 44 deletions(-)

diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
index a4fa8e3af607..65ed20bc1fa2 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c
@@ -461,10 +461,18 @@ static const struct pinctrl_pin_desc uniphier_ld11_pins[] = {
 			     166, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {151, 152, 153, 154, 155, 156, 157};
-static const int ain1_muxvals[] = {4, 4, 4, 4, 4, 4, 4};
-static const unsigned aout1_pins[] = {137, 138, 139, 140, 141, 142};
-static const int aout1_muxvals[] = {0, 0, 0, 0, 0, 0};
+static const unsigned ain1_pins[] = {151, 152, 153, 154};
+static const int ain1_muxvals[] = {4, 4, 4, 4};
+static const unsigned ain1_dat2_pins[] = {155};
+static const int ain1_dat2_muxvals[] = {4};
+static const unsigned ain1_dat4_pins[] = {156, 157};
+static const int ain1_dat4_muxvals[] = {4, 4};
+static const unsigned aout1_pins[] = {137, 138, 139, 140};
+static const int aout1_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout1_dat2_pins[] = {141};
+static const int aout1_dat2_muxvals[] = {0};
+static const unsigned aout1_dat4_pins[] = {142, 143};
+static const int aout1_dat4_muxvals[] = {0, 3};
 static const unsigned ainiec1_pins[] = {150};
 static const int ainiec1_muxvals[] = {4};
 static const unsigned ainiec1b_pins[] = {141};
@@ -582,7 +590,11 @@ static const unsigned int gpio_range5_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(ainiec1b),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -626,8 +638,10 @@ static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range5),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const aout1_groups[] = {"aout1"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
 static const char * const ainiec1_groups[] = {"ainiec1", "ainiec1b"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
 static const char * const aoutiec2_groups[] = {"aoutiec2"};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
index 850736998206..a68b21fbd0c7 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c
@@ -542,18 +542,38 @@ static const struct pinctrl_pin_desc uniphier_ld20_pins[] = {
 			     175, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {150, 151, 152, 153, 154, 155, 156};
-static const int ain1_muxvals[] = {4, 4, 4, 4, 4, 4, 4};
-static const unsigned ain2_pins[] = {116, 117, 118, 119, 120, 121, 122};
-static const int ain2_muxvals[] = {26, 26, 26, 26, 26, 26, 26};
+static const unsigned ain1_pins[] = {150, 151, 152, 153};
+static const int ain1_muxvals[] = {4, 4, 4, 4};
+static const unsigned ain1_dat2_pins[] = {154};
+static const int ain1_dat2_muxvals[] = {4};
+static const unsigned ain1_dat4_pins[] = {155, 156};
+static const int ain1_dat4_muxvals[] = {4, 4};
+static const unsigned ain2_pins[] = {116, 117, 118, 119};
+static const int ain2_muxvals[] = {26, 26, 26, 26};
+static const unsigned ain2_dat2_pins[] = {120};
+static const int ain2_dat2_muxvals[] = {26};
+static const unsigned ain2_dat4_pins[] = {121, 122};
+static const int ain2_dat4_muxvals[] = {26, 26};
 static const unsigned ain3_pins[] = {116, 117, 118, 119};
 static const int ain3_muxvals[] = {27, 27, 27, 27};
-static const unsigned aout1_pins[] = {137, 138, 139, 140, 141, 142};
-static const int aout1_muxvals[] = {0, 0, 0, 0, 0, 0};
-static const unsigned aout1b_pins[] = {150, 151, 152, 153, 154, 155, 156};
-static const int aout1b_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout2_pins[] = {165, 157, 162, 158, 159, 160, 161};
-static const int aout2_muxvals[] = {2, 2, 2, 1, 1, 1, 1};
+static const unsigned aout1_pins[] = {137, 138, 139, 140};
+static const int aout1_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout1_dat2_pins[] = {141};
+static const int aout1_dat2_muxvals[] = {0};
+static const unsigned aout1_dat4_pins[] = {142, 156};
+static const int aout1_dat4_muxvals[] = {0, 1};
+static const unsigned aout1b_pins[] = {150, 151, 152, 153};
+static const int aout1b_muxvals[] = {1, 1, 1, 1};
+static const unsigned aout1b_dat2_pins[] = {154};
+static const int aout1b_dat2_muxvals[] = {1};
+static const unsigned aout1b_dat4_pins[] = {155, 156};
+static const int aout1b_dat4_muxvals[] = {1, 1};
+static const unsigned aout2_pins[] = {165, 157, 162, 158};
+static const int aout2_muxvals[] = {2, 2, 2, 1};
+static const unsigned aout2_dat2_pins[] = {159};
+static const int aout2_dat2_muxvals[] = {1};
+static const unsigned aout2_dat4_pins[] = {160, 161};
+static const int aout2_dat4_muxvals[] = {1, 1};
 static const unsigned aout3_pins[] = {166, 167, 168, 163};
 static const int aout3_muxvals[] = {2, 2, 2, 1};
 static const unsigned aout4_pins[] = {169, 170, 171, 164};
@@ -682,11 +702,21 @@ static const unsigned int gpio_range2_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1b),
+	UNIPHIER_PINCTRL_GROUP(aout1b_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1b_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aout4),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -734,11 +764,17 @@ static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range2),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain2_dat4"};
 static const char * const ain3_groups[] = {"ain3"};
-static const char * const aout1_groups[] = {"aout1", "aout1b"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4",
+					    "aout1b", "aout1b_dat2",
+					    "aout1b_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aout4_groups[] = {"aout4"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
index 6ef892543cb9..7da8616f8d47 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c
@@ -719,18 +719,34 @@ static const struct pinctrl_pin_desc uniphier_pxs2_pins[] = {
 			     234, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {161, 162, 173, 174, 127, 128, 129};
-static const int ain1_muxvals[] = {8, 8, 8, 8, 3, 3, 3};
-static const unsigned ain2_pins[] = {98, 99, 100, 101, 102, 103, 104};
-static const int ain2_muxvals[] = {8, 8, 8, 8, 8, 8, 8};
+static const unsigned ain1_pins[] = {161, 162, 173, 174};
+static const int ain1_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain1_dat2_pins[] = {127};
+static const int ain1_dat2_muxvals[] = {3};
+static const unsigned ain1_dat4_pins[] = {128, 129};
+static const int ain1_dat4_muxvals[] = {3, 3};
+static const unsigned ain2_pins[] = {98, 99, 100, 101};
+static const int ain2_muxvals[] = {8, 8, 8, 8};
+static const unsigned ain2_dat2_pins[] = {102};
+static const int ain2_dat2_muxvals[] = {8};
+static const unsigned ain2_dat4_pins[] = {103, 104};
+static const int ain2_dat4_muxvals[] = {8, 8};
 static const unsigned ain3_pins[] = {132, 133, 134, 131};
 static const int ain3_muxvals[] = {5, 5, 5, 5};
 static const unsigned ainiec1_pins[] = {91};
 static const int ainiec1_muxvals[] = {11};
-static const unsigned aout1_pins[] = {87, 88, 89, 90, 92, 93, 94};
-static const int aout1_muxvals[] = {11, 11, 11, 11, 11, 11, 11};
-static const unsigned aout2_pins[] = {175, 176, 177, 178, 183, 184, 185};
-static const int aout2_muxvals[] = {8, 8, 8, 8, 9, 9, 9};
+static const unsigned aout1_pins[] = {87, 88, 89, 90};
+static const int aout1_muxvals[] = {11, 11, 11, 11};
+static const unsigned aout1_dat2_pins[] = {92};
+static const int aout1_dat2_muxvals[] = {11};
+static const unsigned aout1_dat4_pins[] = {93, 94};
+static const int aout1_dat4_muxvals[] = {11, 11};
+static const unsigned aout2_pins[] = {177, 178, 175, 176};
+static const int aout2_muxvals[] = {8, 8, 8, 8};
+static const unsigned aout2_dat2_pins[] = {183};
+static const int aout2_dat2_muxvals[] = {9};
+static const unsigned aout2_dat4_pins[] = {184, 185};
+static const int aout2_dat4_muxvals[] = {9, 9};
 static const unsigned aout3_pins[] = {105, 106, 107, 108};
 static const int aout3_muxvals[] = {8, 8, 8, 8};
 static const unsigned aoutiec1_pins[] = {95};
@@ -842,11 +858,19 @@ static const unsigned int gpio_range1_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
 	UNIPHIER_PINCTRL_GROUP(aoutiec2),
@@ -884,12 +908,16 @@ static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range1),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain2_dat4"};
 static const char * const ain3_groups[] = {"ain3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
-static const char * const aout1_groups[] = {"aout1"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
 static const char * const aoutiec2_groups[] = {"aoutiec2"};
@@ -922,7 +950,9 @@ static const char * const usb3_groups[] = {"usb3"};
 static const struct uniphier_pinmux_function uniphier_pxs2_functions[] = {
 	UNIPHIER_PINMUX_FUNCTION(ain1),
 	UNIPHIER_PINMUX_FUNCTION(ain2),
+	UNIPHIER_PINMUX_FUNCTION(ain3),
 	UNIPHIER_PINMUX_FUNCTION(ainiec1),
+	UNIPHIER_PINMUX_FUNCTION(aout1),
 	UNIPHIER_PINMUX_FUNCTION(aout2),
 	UNIPHIER_PINMUX_FUNCTION(aout3),
 	UNIPHIER_PINMUX_FUNCTION(aoutiec1),
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
index 4810db6c0ee8..eb3c9b55f6e3 100644
--- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
+++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs3.c
@@ -767,14 +767,30 @@ static const struct pinctrl_pin_desc uniphier_pxs3_pins[] = {
 			     250, UNIPHIER_PIN_PULL_DOWN),
 };
 
-static const unsigned ain1_pins[] = {186, 187, 188, 189, 237, 238, 239};
-static const int ain1_muxvals[] = {0, 0, 0, 0, 1, 1, 1};
-static const unsigned ain2_pins[] = {243, 244, 245, 246, 247, 248, 249};
-static const int ain2_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout1_pins[] = {226, 227, 228, 229, 230, 231, 232};
-static const int aout1_muxvals[] = {1, 1, 1, 1, 1, 1, 1};
-static const unsigned aout2_pins[] = {192, 193, 194, 195, 196, 197, 198};
-static const int aout2_muxvals[] = {0, 0, 0, 0, 0, 0, 0};
+static const unsigned ain1_pins[] = {186, 187, 188, 189};
+static const int ain1_muxvals[] = {0, 0, 0, 0};
+static const unsigned ain1_dat2_pins[] = {237};
+static const int ain1_dat2_muxvals[] = {1};
+static const unsigned ain1_dat4_pins[] = {238, 239};
+static const int ain1_dat4_muxvals[] = {1, 1};
+static const unsigned ain2_pins[] = {243, 244, 245, 246};
+static const int ain2_muxvals[] = {1, 1, 1, 1};
+static const unsigned ain2_dat2_pins[] = {247};
+static const int ain2_dat2_muxvals[] = {1};
+static const unsigned ain2_dat4_pins[] = {248, 249};
+static const int ain2_dat4_muxvals[] = {1, 1};
+static const unsigned aout1_pins[] = {226, 227, 228, 229};
+static const int aout1_muxvals[] = {1, 1, 1, 1};
+static const unsigned aout1_dat2_pins[] = {230};
+static const int aout1_dat2_muxvals[] = {1};
+static const unsigned aout1_dat4_pins[] = {231, 232};
+static const int aout1_dat4_muxvals[] = {1, 1};
+static const unsigned aout2_pins[] = {192, 193, 194, 195};
+static const int aout2_muxvals[] = {0, 0, 0, 0};
+static const unsigned aout2_dat2_pins[] = {196};
+static const int aout2_dat2_muxvals[] = {0};
+static const unsigned aout2_dat4_pins[] = {197, 198};
+static const int aout2_dat4_muxvals[] = {0, 0};
 static const unsigned aout3_pins[] = {199, 200, 201, 202};
 static const int aout3_muxvals[] = {0, 0, 0, 0};
 static const unsigned ainiec1_pins[] = {240};
@@ -888,9 +904,17 @@ static const unsigned int gpio_range2_pins[] = {
 
 static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP(ain1),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain1_dat4),
 	UNIPHIER_PINCTRL_GROUP(ain2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat2),
+	UNIPHIER_PINCTRL_GROUP(ain2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout1),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout1_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat2),
+	UNIPHIER_PINCTRL_GROUP(aout2_dat4),
 	UNIPHIER_PINCTRL_GROUP(aout3),
 	UNIPHIER_PINCTRL_GROUP(ainiec1),
 	UNIPHIER_PINCTRL_GROUP(aoutiec1),
@@ -926,10 +950,14 @@ static const struct uniphier_pinctrl_group uniphier_pxs3_groups[] = {
 	UNIPHIER_PINCTRL_GROUP_GPIO(gpio_range2),
 };
 
-static const char * const ain1_groups[] = {"ain1"};
-static const char * const ain2_groups[] = {"ain2"};
-static const char * const aout1_groups[] = {"aout1"};
-static const char * const aout2_groups[] = {"aout2"};
+static const char * const ain1_groups[] = {"ain1", "ain1_dat2",
+					   "ain1_dat4"};
+static const char * const ain2_groups[] = {"ain2", "ain2_dat2",
+					   "ain1_dat4"};
+static const char * const aout1_groups[] = {"aout1", "aout1_dat2",
+					    "aout1_dat4"};
+static const char * const aout2_groups[] = {"aout2", "aout2_dat2",
+					    "aout2_dat4"};
 static const char * const aout3_groups[] = {"aout3"};
 static const char * const ainiec1_groups[] = {"ainiec1"};
 static const char * const aoutiec1_groups[] = {"aoutiec1"};
-- 
2.7.4



From usama.anjum at collabora.com  Fri Jan 28 05:36:49 2022
From: usama.anjum at collabora.com (Muhammad Usama Anjum)
Date: Fri, 28 Jan 2022 18:36:49 +0500
Subject: [PATCH] media: imx: imx8mq-mipi_csi2: Remove unneeded code
Message-ID: <20220128133649.1393201-1-usama.anjum@collabora.com>

ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
return error. Remove the return variable. Simplify other functions which
are using this function.

Fixes: f0c2ba1ed4ad ("media: imx: imx8mq-mipi_csi2: fix system resume")
Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
---
 drivers/staging/media/imx/imx8mq-mipi-csi2.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
index 3b9fa75efac6b..c992b845e63d1 100644
--- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
@@ -693,11 +693,10 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state)
  * Suspend/resume
  */
 
-static int imx8mq_mipi_csi_pm_suspend(struct device *dev)
+static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
-	int ret = 0;
 
 	mutex_lock(&state->lock);
 
@@ -708,8 +707,6 @@ static int imx8mq_mipi_csi_pm_suspend(struct device *dev)
 	}
 
 	mutex_unlock(&state->lock);
-
-	return ret ? -EAGAIN : 0;
 }
 
 static int imx8mq_mipi_csi_pm_resume(struct device *dev)
@@ -742,15 +739,12 @@ static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
-	int ret;
 
-	ret = imx8mq_mipi_csi_pm_suspend(dev);
-	if (ret)
-		return ret;
+	imx8mq_mipi_csi_pm_suspend(dev);
 
 	state->state |= ST_SUSPENDED;
 
-	return ret;
+	return 0;
 }
 
 static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev)
@@ -770,9 +764,7 @@ static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev)
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
 	int ret;
 
-	ret = imx8mq_mipi_csi_pm_suspend(dev);
-	if (ret)
-		return ret;
+	imx8mq_mipi_csi_pm_suspend(dev);
 
 	ret = icc_set_bw(state->icc_path, 0, 0);
 	if (ret)
-- 
2.30.2



From aford173 at gmail.com  Fri Jan 28 05:47:06 2022
From: aford173 at gmail.com (Adam Ford)
Date: Fri, 28 Jan 2022 07:47:06 -0600
Subject: [PATCH] clk: imx: Fix a NULL pointer dereference in
 imx_register_uart_clocks()
In-Reply-To: <YfPCdPuoB3RYgzL8@kroah.com>
References: <20220124165206.55059-1-zhou1615@umn.edu>
 <YfPCdPuoB3RYgzL8@kroah.com>
Message-ID: <CAHCN7x+bvC70Y18j8tvSVZNjwipYu3xTvFo=AjKvYnmaucBiGg@mail.gmail.com>

On Fri, Jan 28, 2022 at 4:16 AM Greg KH <gregkh at linuxfoundation.org> wrote:
>
> On Tue, Jan 25, 2022 at 12:52:06AM +0800, Zhou Qingyang wrote:
> > In imx_register_uart_clocks(), the global variable imx_uart_clocks is
> > assigned by kcalloc() and there is a dereference of in the next for loop,
> > which could introduce a NULL pointer dereference on failure of kcalloc().
> >
> > Fix this by adding a NULL check of imx_uart_clocks.
> >
> > This bug was found by a static analyzer.
> >
> > Builds with 'make allyesconfig' show no new warnings,
> > and our static analyzer no longer warns about this code.
> >
> > Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
> > Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> > ---
> > The analysis employs differential checking to identify inconsistent
> > security operations (e.g., checks or kfrees) between two code paths
> > and confirms that the inconsistent operations are not recovered in the
> > current function or the callers, so they constitute bugs.
> >
> > Note that, as a bug found by static analysis, it can be a false
> > positive or hard to trigger. Multiple researchers have cross-reviewed
> > the bug.
> >
> >  drivers/clk/imx/clk.c | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
> > index 7cc669934253..99249ab361d2 100644
> > --- a/drivers/clk/imx/clk.c
> > +++ b/drivers/clk/imx/clk.c
> > @@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
> >               int i;
> >
> >               imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
> > +             if (!imx_uart_clocks)
> > +                     return;
> >
> >               if (!of_stdout)
> >                       return;
> > --
> > 2.25.1
> >
>
> As stated before, umn.edu is still not allowed to contribute to the
> Linux kernel.  Please work with your administration to resolve this
> issue.

Greg,

In the interest of safety, I believe this patch is reasonable.  I
wrote the original patch that is being fixed by this.  Would it be
acceptable if I submitted the same patch with "suggested-by"
associated with Zhou @ umn.edu?  I want to give credit where credit is
due while still maintaining the rule that patches are not actually
being accepted by umn.edu.

adam


From krzysztof.adamski at nokia.com  Fri Jan 28 05:50:26 2022
From: krzysztof.adamski at nokia.com (Krzysztof Adamski)
Date: Fri, 28 Jan 2022 14:50:26 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
Message-ID: <YfP0osb45uJldtM9@localhost.localdomain>

On EFI enabled arm64 systems, efi_reboot was called before
do_kernel_restart, completely omitting the reset_handlers functionality.
By registering efi_reboot as part of the chain with slightly elevated
priority, we make it run before the default handler but still allow
plugging in other handlers.
Thanks to that, things like gpio_restart, restart handlers in
watchdog_core, mmc or mtds are working on those platforms.

The priority 130 is one higher than PSCI, to overrule that but still
allow to easily register higher prio handlers, if needed.

Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>
---

Changes in v2:
  - Register the handler in EFI code, instead of arm64 setup.c
  - Remove the contdition from the handler - it should be run in all
    cases when it is registered
  - Bump the priority to 130 to make it completly obious this should be
    run before PSCI (which has priority of 129)

 arch/arm64/kernel/process.c        |  7 -------
 drivers/firmware/efi/arm-runtime.c | 21 +++++++++++++++++++++
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 5369e649fa79..b86ef77bb0c8 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -130,13 +130,6 @@ void machine_restart(char *cmd)
 	local_irq_disable();
 	smp_send_stop();
 
-	/*
-	 * UpdateCapsule() depends on the system being reset via
-	 * ResetSystem().
-	 */
-	if (efi_enabled(EFI_RUNTIME_SERVICES))
-		efi_reboot(reboot_mode, NULL);
-
 	/* Now call the architecture specific reboot code. */
 	do_kernel_restart(cmd);
 
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index 3359ae2adf24..b9a2cdbe80b4 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -80,6 +80,24 @@ static bool __init efi_virtmap_init(void)
 	return true;
 }
 
+static int efi_restart(struct notifier_block *nb, unsigned long action,
+		       void *data)
+{
+	/*
+	 * UpdateCapsule() depends on the system being reset via
+	 * ResetSystem().
+	 */
+	efi_reboot(reboot_mode, NULL);
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block efi_restart_nb = {
+	.notifier_call = efi_restart,
+	/* We want this to take priority over PSCI which has priority of 129. */
+	.priority = 130,
+};
+
 /*
  * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
  * non-early mapping of the UEFI system table and virtual mappings for all
@@ -148,6 +166,9 @@ static int __init arm_enable_runtime_services(void)
 	efi_native_runtime_setup();
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 
+	if (IS_ENABLED(CONFIG_ARM64))
+		register_restart_handler(&efi_restart_nb);
+
 	return 0;
 }
 early_initcall(arm_enable_runtime_services);
-- 
2.34.1



From mkl at pengutronix.de  Fri Jan 28 05:52:17 2022
From: mkl at pengutronix.de (Marc Kleine-Budde)
Date: Fri, 28 Jan 2022 14:52:17 +0100
Subject: [PATCH] media: imx: imx8mq-mipi_csi2: Remove unneeded code
In-Reply-To: <20220128133649.1393201-1-usama.anjum@collabora.com>
References: <20220128133649.1393201-1-usama.anjum@collabora.com>
Message-ID: <20220128135217.ncvjlffzpxxmqbjo@pengutronix.de>

On 28.01.2022 18:36:49, Muhammad Usama Anjum wrote:
> ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
> return error. Remove the return variable. Simplify other functions which
> are using this function.
> 
> Fixes: f0c2ba1ed4ad ("media: imx: imx8mq-mipi_csi2: fix system resume")
> Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
> ---
>  drivers/staging/media/imx/imx8mq-mipi-csi2.c | 16 ++++------------
>  1 file changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
> index 3b9fa75efac6b..c992b845e63d1 100644
> --- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c
> +++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
[...]
>  static int imx8mq_mipi_csi_pm_resume(struct device *dev)
> @@ -742,15 +739,12 @@ static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
>  {
>  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
>  	struct csi_state *state = mipi_sd_to_csi2_state(sd);
> -	int ret;
>  
> -	ret = imx8mq_mipi_csi_pm_suspend(dev);
> -	if (ret)
> -		return ret;
> +	imx8mq_mipi_csi_pm_suspend(dev);
>  
>  	state->state |= ST_SUSPENDED;


what about this flag?

Marc
>  
> -	return ret;
> +	return 0;
>  }


-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/edbf5613/attachment-0001.sig>

From ardb at kernel.org  Fri Jan 28 06:10:27 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Fri, 28 Jan 2022 15:10:27 +0100
Subject: [RFC PATCH 5/7] crypto: arm64/aes-xctr: Add accelerated
 implementation of XCTR
In-Reply-To: <20220125014422.80552-6-nhuck@google.com>
References: <20220125014422.80552-1-nhuck@google.com>
 <20220125014422.80552-6-nhuck@google.com>
Message-ID: <CAMj1kXFW1fBXtELj+gpQ0mqVA=+vce7LCMRtxW+uT5AzyYTmwA@mail.gmail.com>

On Tue, 25 Jan 2022 at 02:47, Nathan Huckleberry <nhuck at google.com> wrote:
>
> Add hardware accelerated version of XCTR for ARM64 CPUs with ARMv8
> Crypto Extension support.  This XCTR implementation is based on the CTR
> implementation in aes-modes.S.
>
> More information on XCTR can be found in
> the HCTR2 paper: Length-preserving encryption with HCTR2:
> https://eprint.iacr.org/2021/1441.pdf
>
> Signed-off-by: Nathan Huckleberry <nhuck at google.com>
> ---
>  arch/arm64/crypto/Kconfig     |   4 +-
>  arch/arm64/crypto/aes-glue.c  |  70 ++++++++++++++++++-
>  arch/arm64/crypto/aes-modes.S | 128 ++++++++++++++++++++++++++++++++++
>  3 files changed, 198 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
> index addfa413650b..cab469e279ec 100644
> --- a/arch/arm64/crypto/Kconfig
> +++ b/arch/arm64/crypto/Kconfig
> @@ -84,13 +84,13 @@ config CRYPTO_AES_ARM64_CE_CCM
>         select CRYPTO_LIB_AES
>
>  config CRYPTO_AES_ARM64_CE_BLK
> -       tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
> +       tristate "AES in ECB/CBC/CTR/XTS/XCTR modes using ARMv8 Crypto Extensions"
>         depends on KERNEL_MODE_NEON
>         select CRYPTO_SKCIPHER
>         select CRYPTO_AES_ARM64_CE
>
>  config CRYPTO_AES_ARM64_NEON_BLK
> -       tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
> +       tristate "AES in ECB/CBC/CTR/XTS/XCTR modes using NEON instructions"
>         depends on KERNEL_MODE_NEON
>         select CRYPTO_SKCIPHER
>         select CRYPTO_LIB_AES
> diff --git a/arch/arm64/crypto/aes-glue.c b/arch/arm64/crypto/aes-glue.c
> index 30b7cc6a7079..377f8d8369fb 100644
> --- a/arch/arm64/crypto/aes-glue.c
> +++ b/arch/arm64/crypto/aes-glue.c
> @@ -35,10 +35,11 @@
>  #define aes_essiv_cbc_encrypt  ce_aes_essiv_cbc_encrypt
>  #define aes_essiv_cbc_decrypt  ce_aes_essiv_cbc_decrypt
>  #define aes_ctr_encrypt                ce_aes_ctr_encrypt
> +#define aes_xctr_encrypt       ce_aes_xctr_encrypt
>  #define aes_xts_encrypt                ce_aes_xts_encrypt
>  #define aes_xts_decrypt                ce_aes_xts_decrypt
>  #define aes_mac_update         ce_aes_mac_update
> -MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
> +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 Crypto Extensions");
>  #else
>  #define MODE                   "neon"
>  #define PRIO                   200
> @@ -52,16 +53,18 @@ MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 Crypto Extensions");
>  #define aes_essiv_cbc_encrypt  neon_aes_essiv_cbc_encrypt
>  #define aes_essiv_cbc_decrypt  neon_aes_essiv_cbc_decrypt
>  #define aes_ctr_encrypt                neon_aes_ctr_encrypt
> +#define aes_xctr_encrypt       neon_aes_xctr_encrypt
>  #define aes_xts_encrypt                neon_aes_xts_encrypt
>  #define aes_xts_decrypt                neon_aes_xts_decrypt
>  #define aes_mac_update         neon_aes_mac_update
> -MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS using ARMv8 NEON");
> +MODULE_DESCRIPTION("AES-ECB/CBC/CTR/XTS/XCTR using ARMv8 NEON");
>  #endif
>  #if defined(USE_V8_CRYPTO_EXTENSIONS) || !IS_ENABLED(CONFIG_CRYPTO_AES_ARM64_BS)
>  MODULE_ALIAS_CRYPTO("ecb(aes)");
>  MODULE_ALIAS_CRYPTO("cbc(aes)");
>  MODULE_ALIAS_CRYPTO("ctr(aes)");
>  MODULE_ALIAS_CRYPTO("xts(aes)");
> +MODULE_ALIAS_CRYPTO("xctr(aes)");
>  #endif
>  MODULE_ALIAS_CRYPTO("cts(cbc(aes))");
>  MODULE_ALIAS_CRYPTO("essiv(cbc(aes),sha256)");
> @@ -91,6 +94,10 @@ asmlinkage void aes_cbc_cts_decrypt(u8 out[], u8 const in[], u32 const rk[],
>  asmlinkage void aes_ctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
>                                 int rounds, int bytes, u8 ctr[], u8 finalbuf[]);
>
> +asmlinkage void aes_xctr_encrypt(u8 out[], u8 const in[], u32 const rk[],
> +                                int rounds, int bytes, u8 ctr[], u8 finalbuf[],
> +                                int byte_ctr);
> +
>  asmlinkage void aes_xts_encrypt(u8 out[], u8 const in[], u32 const rk1[],
>                                 int rounds, int bytes, u32 const rk2[], u8 iv[],
>                                 int first);
> @@ -444,6 +451,49 @@ static int __maybe_unused essiv_cbc_decrypt(struct skcipher_request *req)
>         return err ?: cbc_decrypt_walk(req, &walk);
>  }
>
> +static int __maybe_unused xctr_encrypt(struct skcipher_request *req)
> +{
> +       struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> +       struct crypto_aes_ctx *ctx = crypto_skcipher_ctx(tfm);
> +       int err, rounds = 6 + ctx->key_length / 4;
> +       struct skcipher_walk walk;
> +       unsigned int byte_ctr = 0;
> +
> +       err = skcipher_walk_virt(&walk, req, false);
> +
> +       while (walk.nbytes > 0) {
> +               const u8 *src = walk.src.virt.addr;
> +               unsigned int nbytes = walk.nbytes;
> +               u8 *dst = walk.dst.virt.addr;
> +               u8 buf[AES_BLOCK_SIZE];
> +               unsigned int tail;
> +
> +               if (unlikely(nbytes < AES_BLOCK_SIZE))
> +                       src = memcpy(buf, src, nbytes);
> +               else if (nbytes < walk.total)
> +                       nbytes &= ~(AES_BLOCK_SIZE - 1);
> +
> +               kernel_neon_begin();
> +               aes_xctr_encrypt(dst, src, ctx->key_enc, rounds, nbytes,
> +                                                walk.iv, buf, byte_ctr);
> +               kernel_neon_end();
> +
> +               tail = nbytes % (STRIDE * AES_BLOCK_SIZE);
> +               if (tail > 0 && tail < AES_BLOCK_SIZE)
> +                       /*
> +                        * The final partial block could not be returned using
> +                        * an overlapping store, so it was passed via buf[]
> +                        * instead.
> +                        */
> +                       memcpy(dst + nbytes - tail, buf, tail);

I have a patch [0] that elides this memcpy() for the CTR routine if
the input is more than a block. It's independent of this one, of
course, but for symmetry, it would make sense to do the same.

[0] https://lore.kernel.org/r/20220127095211.3481959-1-ardb at kernel.org


>
> +               byte_ctr += nbytes;
> +
> +               err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
> +       }
> +
> +       return err;
> +}
> +
>  static int __maybe_unused ctr_encrypt(struct skcipher_request *req)
>  {
>         struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
> @@ -676,6 +726,22 @@ static struct skcipher_alg aes_algs[] = { {
>         .setkey         = skcipher_aes_setkey,
>         .encrypt        = ctr_encrypt,
>         .decrypt        = ctr_encrypt,
> +}, {
> +       .base = {
> +               .cra_name               = "xctr(aes)",
> +               .cra_driver_name        = "xctr-aes-" MODE,
> +               .cra_priority           = PRIO,
> +               .cra_blocksize          = 1,
> +               .cra_ctxsize            = sizeof(struct crypto_aes_ctx),
> +               .cra_module             = THIS_MODULE,
> +       },
> +       .min_keysize    = AES_MIN_KEY_SIZE,
> +       .max_keysize    = AES_MAX_KEY_SIZE,
> +       .ivsize         = AES_BLOCK_SIZE,
> +       .chunksize      = AES_BLOCK_SIZE,
> +       .setkey         = skcipher_aes_setkey,
> +       .encrypt        = xctr_encrypt,
> +       .decrypt        = xctr_encrypt,
>  }, {
>         .base = {
>                 .cra_name               = "xts(aes)",
> diff --git a/arch/arm64/crypto/aes-modes.S b/arch/arm64/crypto/aes-modes.S
> index ff01f0167ba2..7128907f8190 100644
> --- a/arch/arm64/crypto/aes-modes.S
> +++ b/arch/arm64/crypto/aes-modes.S
> @@ -471,6 +471,134 @@ ST5(      mov             v3.16b, v4.16b                  )
>         b               .Lctrout
>  AES_FUNC_END(aes_ctr_encrypt)
>
> +    /*
> +        * aes_xctr_encrypt(u8 out[], u8 const in[], u8 const rk[], int rounds,
> +        *                 int bytes, u8 const ctr[], u8 finalbuf[], int byte_ctr)
> +        */
> +
> +AES_FUNC_START(aes_xctr_encrypt)
> +       stp             x29, x30, [sp, #-16]!
> +       mov             x29, sp
> +
> +       enc_prepare     w3, x2, x12
> +       ld1             {vctr.16b}, [x5]
> +
> +       umov            x12, vctr.d[0]          /* keep ctr in reg */
> +       lsr             x7, x7, #4
> +       add             x11, x7, #1
> +
> +.LxctrloopNx:
> +       add             w7, w4, #15
> +       sub             w4, w4, #MAX_STRIDE << 4
> +       lsr             w7, w7, #4
> +       mov             w8, #MAX_STRIDE
> +       cmp             w7, w8
> +       csel            w7, w7, w8, lt
> +       add             x11, x11, x7
> +
> +       mov             v0.16b, vctr.16b
> +       mov             v1.16b, vctr.16b
> +       mov             v2.16b, vctr.16b
> +       mov             v3.16b, vctr.16b
> +ST5(   mov             v4.16b, vctr.16b                )
> +
> +       sub             x7, x11, #MAX_STRIDE
> +       eor             x7, x12, x7
> +       ins             v0.d[0], x7
> +       sub             x7, x11, #MAX_STRIDE - 1
> +       sub             x8, x11, #MAX_STRIDE - 2
> +       eor             x7, x7, x12
> +       sub             x9, x11, #MAX_STRIDE - 3
> +       mov             v1.d[0], x7
> +       eor             x8, x8, x12
> +       eor             x9, x9, x12
> +ST5(   sub             x10, x11, #MAX_STRIDE - 4)
> +       mov             v2.d[0], x8
> +       eor             x10, x10, x12
> +       mov             v3.d[0], x9
> +ST5(   mov             v4.d[0], x10                    )
> +       tbnz            w4, #31, .Lxctrtail
> +       ld1             {v5.16b-v7.16b}, [x1], #48
> +ST4(   bl              aes_encrypt_block4x             )
> +ST5(   bl              aes_encrypt_block5x             )
> +       eor             v0.16b, v5.16b, v0.16b
> +ST4(   ld1             {v5.16b}, [x1], #16             )
> +       eor             v1.16b, v6.16b, v1.16b
> +ST5(   ld1             {v5.16b-v6.16b}, [x1], #32      )
> +       eor             v2.16b, v7.16b, v2.16b
> +       eor             v3.16b, v5.16b, v3.16b
> +ST5(   eor             v4.16b, v6.16b, v4.16b          )
> +       st1             {v0.16b-v3.16b}, [x0], #64
> +ST5(   st1             {v4.16b}, [x0], #16             )
> +       cbz             w4, .Lxctrout
> +       b               .LxctrloopNx
> +
> +.Lxctrout:
> +       ldp             x29, x30, [sp], #16
> +       ret
> +
> +.Lxctrtail:
> +       /* XOR up to MAX_STRIDE * 16 - 1 bytes of in/output with v0 ... v3/v4 */
> +       mov             x17, #16
> +       ands            x13, x4, #0xf
> +       csel            x13, x13, x17, ne
> +
> +ST5(   cmp             w4, #64 - (MAX_STRIDE << 4))
> +ST5(   csel            x14, x17, xzr, gt               )
> +       cmp             w4, #48 - (MAX_STRIDE << 4)
> +       csel            x15, x17, xzr, gt
> +       cmp             w4, #32 - (MAX_STRIDE << 4)
> +       csel            x16, x17, xzr, gt
> +       cmp             w4, #16 - (MAX_STRIDE << 4)
> +       ble             .Lxctrtail1x
> +
> +ST5(   mov             v4.d[0], x10                    )
> +
> +       adr_l           x12, .Lcts_permute_table
> +       add             x12, x12, x13
> +
> +ST5(   ld1             {v5.16b}, [x1], x14             )
> +       ld1             {v6.16b}, [x1], x15
> +       ld1             {v7.16b}, [x1], x16
> +
> +ST4(   bl              aes_encrypt_block4x             )
> +ST5(   bl              aes_encrypt_block5x             )
> +
> +       ld1             {v8.16b}, [x1], x13
> +       ld1             {v9.16b}, [x1]
> +       ld1             {v10.16b}, [x12]
> +
> +ST4(   eor             v6.16b, v6.16b, v0.16b          )
> +ST4(   eor             v7.16b, v7.16b, v1.16b          )
> +ST4(   tbl             v3.16b, {v3.16b}, v10.16b       )
> +ST4(   eor             v8.16b, v8.16b, v2.16b          )
> +ST4(   eor             v9.16b, v9.16b, v3.16b          )
> +
> +ST5(   eor             v5.16b, v5.16b, v0.16b          )
> +ST5(   eor             v6.16b, v6.16b, v1.16b          )
> +ST5(   tbl             v4.16b, {v4.16b}, v10.16b       )
> +ST5(   eor             v7.16b, v7.16b, v2.16b          )
> +ST5(   eor             v8.16b, v8.16b, v3.16b          )
> +ST5(   eor             v9.16b, v9.16b, v4.16b          )
> +
> +ST5(   st1             {v5.16b}, [x0], x14             )
> +       st1             {v6.16b}, [x0], x15
> +       st1             {v7.16b}, [x0], x16
> +       add             x13, x13, x0
> +       st1             {v9.16b}, [x13]         // overlapping stores
> +       st1             {v8.16b}, [x0]
> +       b               .Lxctrout
> +
> +.Lxctrtail1x:
> +       csel            x0, x0, x6, eq          // use finalbuf if less than a full block
> +       ld1             {v5.16b}, [x1]
> +ST5(   mov             v3.16b, v4.16b                  )
> +       encrypt_block   v3, w3, x2, x8, w7
> +       eor             v5.16b, v5.16b, v3.16b
> +       st1             {v5.16b}, [x0]
> +       b               .Lxctrout
> +AES_FUNC_END(aes_xctr_encrypt)
> +
>
>         /*
>          * aes_xts_encrypt(u8 out[], u8 const in[], u8 const rk1[], int rounds,
> --
> 2.35.0.rc0.227.g00780c9af4-goog
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From andy.shevchenko at gmail.com  Fri Jan 28 06:19:12 2022
From: andy.shevchenko at gmail.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 16:19:12 +0200
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
In-Reply-To: <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>
References: <20220125161245.418882-1-horatiu.vultur@microchip.com>
 <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>
Message-ID: <CAHp75Vc71mnKST5aFGEivoU8ZhmmRf-ArNYVMb5Cf52jE8jetQ@mail.gmail.com>

On Wed, Jan 26, 2022 at 3:19 AM Colin Foster
<colin.foster at in-advantage.com> wrote:
> On Tue, Jan 25, 2022 at 05:12:45PM +0100, Horatiu Vultur wrote:

> The only difference is I
> had copied reg_stride into sgpio_priv instead of making regmap_config
> file-scope.

I'm wondering if we may access config via a pointer to regmap.

-- 
With Best Regards,
Andy Shevchenko


From angelogioacchino.delregno at collabora.com  Fri Jan 28 06:20:56 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Fri, 28 Jan 2022 15:20:56 +0100
Subject: [PATCH] soc: mediatek: mt8192-mmsys: Fix dither to dsi0 path's input
 sel
Message-ID: <20220128142056.359900-1-angelogioacchino.delregno@collabora.com>

In commit d687e056a18f ("soc: mediatek: mmsys: Add mt8192 mmsys routing table"),
the mmsys routing table for mt8192 was introduced but the input selector
for DITHER->DSI0 has no value assigned to it.

This means that we are clearing bit 0 instead of setting it, blocking
communication between these two blocks; due to that, any display that
is connected to DSI0 will not work, as no data will go through.
The effect of that issue is that, during bootup, the DRM will block for
some time, while atomically waiting for a vblank that never happens;
later, the situation doesn't get better, leaving the display in a
non-functional state.

To fix this issue, fix the route entry in the table by assigning the
dither input selector to MT8192_DISP_DSI0_SEL_IN.

Fixes: d687e056a18f ("soc: mediatek: mmsys: Add mt8192 mmsys routing table")
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mt8192-mmsys.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/soc/mediatek/mt8192-mmsys.h b/drivers/soc/mediatek/mt8192-mmsys.h
index 6f0a57044a7b..6aae0b12b6ff 100644
--- a/drivers/soc/mediatek/mt8192-mmsys.h
+++ b/drivers/soc/mediatek/mt8192-mmsys.h
@@ -53,7 +53,8 @@ static const struct mtk_mmsys_routes mmsys_mt8192_routing_table[] = {
 		MT8192_AAL0_SEL_IN_CCORR0
 	}, {
 		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
-		MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0
+		MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0,
+		MT8192_DSI0_SEL_IN_DITHER0
 	}, {
 		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
 		MT8192_DISP_RDMA0_SOUT_SEL, MT8192_RDMA0_SOUT_COLOR0,
-- 
2.33.1



From alexander.sverdlin at nokia.com  Fri Jan 28 06:21:30 2022
From: alexander.sverdlin at nokia.com (Alexander Sverdlin)
Date: Fri, 28 Jan 2022 15:21:30 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfP0osb45uJldtM9@localhost.localdomain>
References: <YfP0osb45uJldtM9@localhost.localdomain>
Message-ID: <f0575d3c-15a0-8a33-9fbd-8ebe1be33034@nokia.com>

Hi!

On 28/01/2022 14:50, Krzysztof Adamski wrote:
> On EFI enabled arm64 systems, efi_reboot was called before
> do_kernel_restart, completely omitting the reset_handlers functionality.
> By registering efi_reboot as part of the chain with slightly elevated
> priority, we make it run before the default handler but still allow
> plugging in other handlers.
> Thanks to that, things like gpio_restart, restart handlers in
> watchdog_core, mmc or mtds are working on those platforms.
> 
> The priority 130 is one higher than PSCI, to overrule that but still
> allow to easily register higher prio handlers, if needed.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>

Reviewed-by: Alexander Sverdlin <alexander.sverdlin at nokia.com>

> ---
> 
> Changes in v2:
>   - Register the handler in EFI code, instead of arm64 setup.c
>   - Remove the contdition from the handler - it should be run in all
>     cases when it is registered
>   - Bump the priority to 130 to make it completly obious this should be
>     run before PSCI (which has priority of 129)
> 
>  arch/arm64/kernel/process.c        |  7 -------
>  drivers/firmware/efi/arm-runtime.c | 21 +++++++++++++++++++++
>  2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..b86ef77bb0c8 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>  	local_irq_disable();
>  	smp_send_stop();
>  
> -	/*
> -	 * UpdateCapsule() depends on the system being reset via
> -	 * ResetSystem().
> -	 */
> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
> -		efi_reboot(reboot_mode, NULL);
> -
>  	/* Now call the architecture specific reboot code. */
>  	do_kernel_restart(cmd);
>  
> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
> index 3359ae2adf24..b9a2cdbe80b4 100644
> --- a/drivers/firmware/efi/arm-runtime.c
> +++ b/drivers/firmware/efi/arm-runtime.c
> @@ -80,6 +80,24 @@ static bool __init efi_virtmap_init(void)
>  	return true;
>  }
>  
> +static int efi_restart(struct notifier_block *nb, unsigned long action,
> +		       void *data)
> +{
> +	/*
> +	 * UpdateCapsule() depends on the system being reset via
> +	 * ResetSystem().
> +	 */
> +	efi_reboot(reboot_mode, NULL);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block efi_restart_nb = {
> +	.notifier_call = efi_restart,
> +	/* We want this to take priority over PSCI which has priority of 129. */
> +	.priority = 130,
> +};
> +
>  /*
>   * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
>   * non-early mapping of the UEFI system table and virtual mappings for all
> @@ -148,6 +166,9 @@ static int __init arm_enable_runtime_services(void)
>  	efi_native_runtime_setup();
>  	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
>  
> +	if (IS_ENABLED(CONFIG_ARM64))
> +		register_restart_handler(&efi_restart_nb);
> +
>  	return 0;
>  }
>  early_initcall(arm_enable_runtime_services);

-- 
Best regards,
Alexander Sverdlin.


From jszhang at kernel.org  Fri Jan 28 06:15:50 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Fri, 28 Jan 2022 22:15:50 +0800
Subject: [PATCH] net: stmmac: properly handle with runtime pm in
 stmmac_dvr_remove()
Message-ID: <20220128141550.2350-1-jszhang@kernel.org>

There are two issues with runtime pm handling in stmmac_dvr_remove():

1. the mac is runtime suspended before stopping dma and rx/tx. We
need to ensure the device is properly resumed back.

2. the stmmaceth clk enable/disable isn't balanced in both exit and
error handling code path. Take the exit code path for example, when we
unbind the driver or rmmod the driver module, the mac is runtime
suspended as said above, so the stmmaceth clk is disabled, but
	stmmac_dvr_remove()
	  stmmac_remove_config_dt()
	    clk_disable_unprepare()
CCF will complain this time. The error handling code path suffers
from the similar situtaion.

Here are kernel warnings in error handling code path on Allwinner D1
platform:

[    1.604695] ------------[ cut here ]------------
[    1.609328] bus-emac already disabled
[    1.613015] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:952 clk_core_disable+0xcc/0xec
[    1.621039] CPU: 0 PID: 38 Comm: kworker/u2:1 Not tainted 5.14.0-rc4#1
[    1.627653] Hardware name: Allwinner D1 NeZha (DT)
[    1.632443] Workqueue: events_unbound deferred_probe_work_func
[    1.638286] epc : clk_core_disable+0xcc/0xec
[    1.642561]  ra : clk_core_disable+0xcc/0xec
[    1.646835] epc : ffffffff8023c2ec ra : ffffffff8023c2ec sp : ffffffd00411bb10
[    1.654054]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : ffffffff80ed6a6f
[    1.661272]  t1 : ffffffff80ed6a60 t2 : 0000000000000000 s0 : ffffffe001509e00
[    1.668489]  s1 : 0000000000000001 a0 : 0000000000000019 a1 : ffffffff80e80bd8
[    1.675707]  a2 : 00000000ffffefff a3 : 00000000000000f4 a4 : 0000000000000002
[    1.682924]  a5 : 0000000000000001 a6 : 0000000000000030 a7 : 00000000028f5c29
[    1.690141]  s2 : 0000000000000800 s3 : ffffffe001375000 s4 : ffffffe01fdf7a80
[    1.697358]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
[    1.704577]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
[    1.711794]  s11: ffffffe001b80760 t3 : 0000000000000062 t4 : ffffffffffffffff
[    1.719012]  t5 : ffffffff80e0f6d8 t6 : ffffffd00411b8f0
[    1.724321] status: 8000000201800100 badaddr: 0000000000000000 cause: 0000000000000003
[    1.732233] [<ffffffff8023c2ec>] clk_core_disable+0xcc/0xec
[    1.737810] [<ffffffff80240430>] clk_disable+0x38/0x78
[    1.742956] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    1.748451] [<ffffffff8031a500>] stmmac_remove_config_dt+0x1c/0x4c
[    1.754646] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
[    1.760484] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    1.765975] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
[    1.771382] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
[    1.777305] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
[    1.783402] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
[    1.789324] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
[    1.795508] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
[    1.802125] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
[    1.807701] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
[    1.813277] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
[    1.818852] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
[    1.825122] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
[    1.830872] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
[    1.836362] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    1.841335] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    1.846304] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
[    1.852054] [<ffffffff80026564>] kthread+0x124/0x160
[    1.857021] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
[    1.862770] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
[    1.868956] ---[ end trace 8d5c6046255f84a0 ]---
[    1.873675] ------------[ cut here ]------------
[    1.878366] bus-emac already unprepared
[    1.882378] WARNING: CPU: 0 PID: 38 at drivers/clk/clk.c:810 clk_core_unprepare+0xe4/0x168
[    1.890673] CPU: 0 PID: 38 Comm: kworker/u2:1 Tainted: G        W	5.14.0-rc4 #1
[    1.898674] Hardware name: Allwinner D1 NeZha (DT)
[    1.903464] Workqueue: events_unbound deferred_probe_work_func
[    1.909305] epc : clk_core_unprepare+0xe4/0x168
[    1.913840]  ra : clk_core_unprepare+0xe4/0x168
[    1.918375] epc : ffffffff8023d6cc ra : ffffffff8023d6cc sp : ffffffd00411bb10
[    1.925593]  gp : ffffffff80ec9988 tp : ffffffe00143a800 t0 : 0000000000000002
[    1.932811]  t1 : ffffffe01f743be0 t2 : 0000000000000040 s0 : ffffffe001509e00
[    1.940029]  s1 : 0000000000000001 a0 : 000000000000001b a1 : ffffffe00143a800
[    1.947246]  a2 : 0000000000000000 a3 : 00000000000000f4 a4 : 0000000000000001
[    1.954463]  a5 : 0000000000000000 a6 : 0000000005fce2a5 a7 : 0000000000000001
[    1.961680]  s2 : 0000000000000800 s3 : ffffffff80afeb90 s4 : ffffffe01fdf7a80
[    1.968898]  s5 : ffffffe001375010 s6 : ffffffff8001fc10 s7 : ffffffffffffffff
[    1.976115]  s8 : 0000000000000001 s9 : ffffffff80ecb248 s10: ffffffe001b80000
[    1.983333]  s11: ffffffe001b80760 t3 : ffffffff80b39120 t4 : 0000000000000001
[    1.990550]  t5 : 0000000000000000 t6 : ffffffe001600002
[    1.995859] status: 8000000201800120 badaddr: 0000000000000000 cause: 0000000000000003
[    2.003771] [<ffffffff8023d6cc>] clk_core_unprepare+0xe4/0x168
[    2.009609] [<ffffffff802403a0>] clk_unprepare+0x24/0x3c
[    2.014929] [<ffffffff8031a508>] stmmac_remove_config_dt+0x24/0x4c
[    2.021125] [<ffffffff8031c8ec>] sun8i_dwmac_probe+0x378/0x82c
[    2.026965] [<ffffffff8001fc0c>] worker_thread+0x1a8/0x4d8
[    2.032463] [<ffffffff8029a6c8>] platform_probe+0x64/0xf0
[    2.037871] [<ffffffff8029833c>] really_probe.part.0+0x8c/0x30c
[    2.043795] [<ffffffff8029865c>] __driver_probe_device+0xa0/0x148
[    2.049892] [<ffffffff8029873c>] driver_probe_device+0x38/0x138
[    2.055815] [<ffffffff802989cc>] __device_attach_driver+0xd0/0x170
[    2.061999] [<ffffffff802988f8>] __driver_attach_async_helper+0xbc/0xc0
[    2.068616] [<ffffffff802965ac>] bus_for_each_drv+0x68/0xb4
[    2.074193] [<ffffffff80298d1c>] __device_attach+0xd8/0x184
[    2.079769] [<ffffffff802967b0>] bus_probe_device+0x98/0xbc
[    2.085345] [<ffffffff80297904>] deferred_probe_work_func+0x90/0xd4
[    2.091616] [<ffffffff8001f8b8>] process_one_work+0x1e4/0x390
[    2.097367] [<ffffffff8001fd80>] worker_thread+0x31c/0x4d8
[    2.102858] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    2.107830] [<ffffffff80026bf4>] kthreadd+0x94/0x188
[    2.112800] [<ffffffff8001fa60>] process_one_work+0x38c/0x390
[    2.118551] [<ffffffff80026564>] kthread+0x124/0x160
[    2.123520] [<ffffffff8002643c>] set_kthread_struct+0x5c/0x60
[    2.129268] [<ffffffff80001f08>] ret_from_syscall_rejected+0x8/0xc
[    2.135455] ---[ end trace 8d5c6046255f84a1 ]---

Fixes: 5ec55823438e ("net: stmmac: add clocks management for gmac driver")
Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 639a753266e6..bde76ea2deec 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -7252,6 +7252,10 @@ int stmmac_dvr_remove(struct device *dev)
 
 	netdev_info(priv->dev, "%s: removing driver", __func__);
 
+	pm_runtime_get_sync(dev);
+	pm_runtime_disable(dev);
+	pm_runtime_put_noidle(dev);
+
 	stmmac_stop_all_dma(priv);
 	stmmac_mac_set(priv, priv->ioaddr, false);
 	netif_carrier_off(ndev);
@@ -7270,8 +7274,6 @@ int stmmac_dvr_remove(struct device *dev)
 	if (priv->plat->stmmac_rst)
 		reset_control_assert(priv->plat->stmmac_rst);
 	reset_control_assert(priv->plat->stmmac_ahb_rst);
-	pm_runtime_put(dev);
-	pm_runtime_disable(dev);
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI)
 		stmmac_mdio_unregister(ndev);
-- 
2.34.1



From patchwork-bot+netdevbpf at kernel.org  Fri Jan 28 06:30:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 28 Jan 2022 14:30:10 +0000
Subject: [PATCH 0/1] net: stmmac: dwmac-visconti: Avoid updating hardware
 register for unexpected speed requst
In-Reply-To: <20220127121714.22915-1-yuji2.ishikawa@toshiba.co.jp>
References: <20220127121714.22915-1-yuji2.ishikawa@toshiba.co.jp>
Message-ID: <164338021033.15816.13738860195654864475.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Thu, 27 Jan 2022 21:17:13 +0900 you wrote:
> Function visconti_eth_fix_mac_speed() should not change a register when an unexpected speed value is passed.
> 
> Yuji Ishikawa (1):
>   net: stmmac: dwmac-visconti: No change to ETHER_CLOCK_SEL for
>     unexpected speed request.
> 
>  drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)

Here is the summary with links:
  - [1/1] net: stmmac: dwmac-visconti: No change to ETHER_CLOCK_SEL for unexpected speed request.
    https://git.kernel.org/netdev/net/c/928d6fe996f6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Fri Jan 28 06:30:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 28 Jan 2022 14:30:10 +0000
Subject: [PATCH net-next] net: sparx5: use .mac_select_pcs() interface
In-Reply-To: <E1nD2QW-005UHW-QK@rmk-PC.armlinux.org.uk>
References: <E1nD2QW-005UHW-QK@rmk-PC.armlinux.org.uk>
Message-ID: <164338021067.15816.10336079646445394338.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (master)
by David S. Miller <davem at davemloft.net>:

On Thu, 27 Jan 2022 10:54:52 +0000 you wrote:
> Convert sparx5 to use the mac_select_interface rather than using
> phylink_set_pcs(). The intention here is to unify the approach for
> PCS and eventually remove phylink_set_pcs().
> 
> Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
> ---
>  drivers/net/ethernet/microchip/sparx5/sparx5_main.c    |  1 -
>  drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 10 ++++++++++
>  2 files changed, 10 insertions(+), 1 deletion(-)

Here is the summary with links:
  - [net-next] net: sparx5: use .mac_select_pcs() interface
    https://git.kernel.org/netdev/net-next/c/9c8c44022b0d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From andriy.shevchenko at linux.intel.com  Fri Jan 28 06:35:58 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 16:35:58 +0200
Subject: [PATCH] pinctrl: bcm2835: Fix a few error paths
In-Reply-To: <20220127215033.267227-1-f.fainelli@gmail.com>
References: <20220127215033.267227-1-f.fainelli@gmail.com>
Message-ID: <YfP/TuEERCrgst+k@smile.fi.intel.com>

On Thu, Jan 27, 2022 at 01:50:31PM -0800, Florian Fainelli wrote:
> After commit 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio
> hogs") a few error paths would not unwind properly the registration of
> gpio ranges. Correct that by assigning a single error label and goto it
> whenever we encounter a fatal error.

>  1 file changed, 15 insertions(+), 8 deletions(-)

While this seems legit per se, my eyes caught this:


>  	if (!girq->parents) {
> -		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
> -		return -ENOMEM;
> +		err = -ENOMEM;
> +		goto out_remove;

Non-devm....

>  	}
>  
>  	if (is_7211) {
>  		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
>  					    sizeof(*pc->wake_irq),
>  					    GFP_KERNEL);

...followed by devm.

It means more ordering bugs in the ->remove() and error path are lurking
around. Can you double check and be sure that we do not have a case where
non-devm registration code followed by devm?

If that is the case it has to be fixed as well.

> -		if (!pc->wake_irq)
> -			return -ENOMEM;
> +		if (!pc->wake_irq) {
> +			err = -ENOMEM;
> +			goto out_remove;
> +		}
>  	}


-- 
With Best Regards,
Andy Shevchenko




From daniel at iogearbox.net  Fri Jan 28 06:42:40 2022
From: daniel at iogearbox.net (Daniel Borkmann)
Date: Fri, 28 Jan 2022 15:42:40 +0100
Subject: [PATCH bpf-next v2 2/2] selftests/bpf: check whether s32 is
 sufficient for kfunc offset
In-Reply-To: <20220127071532.384888-3-houtao1@huawei.com>
References: <20220127071532.384888-1-houtao1@huawei.com>
 <20220127071532.384888-3-houtao1@huawei.com>
Message-ID: <ba562bf9-c328-1258-940f-b4d9a3169776@iogearbox.net>

On 1/27/22 8:15 AM, Hou Tao wrote:
> In add_kfunc_call(), bpf_kfunc_desc->imm with type s32 is used to
> represent the offset of called kfunc from __bpf_call_base, so
> add a test to ensure that the offset will not be overflowed.
> 
> Signed-off-by: Hou Tao <houtao1 at huawei.com>

Thanks for looking into this!

> ---
>   .../selftests/bpf/prog_tests/ksyms_module.c   | 72 +++++++++++++++++++
>   1 file changed, 72 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
> index d490ad80eccb..ce0cd3446931 100644
> --- a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
> +++ b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
> @@ -6,6 +6,76 @@
>   #include "test_ksyms_module.lskel.h"
>   #include "test_ksyms_module.skel.h"
>   
> +/* Most logic comes from bpf_object__read_kallsyms_file() */
> +static int test_find_func_in_kallsyms(const char *func, unsigned long *addr)
> +{
> +	/* Same as KSYM_NAME_LEN */
> +	char sym_name[128];
> +	char sym_type;
> +	unsigned long sym_addr;
> +	int ret, err;
> +	FILE *f;
> +
> +	f = fopen("/proc/kallsyms", "r");
> +	if (!f)
> +		return -errno;
> +
> +	err = -ENOENT;
> +	while (true) {
> +		ret = fscanf(f, "%lx %c %127s%*[^\n]\n",
> +			     &sym_addr, &sym_type, sym_name);
> +		if (ret == EOF && feof(f))
> +			break;
> +
> +		if (ret != 3) {
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		if ((sym_type == 't' || sym_type == 'T') &&
> +		    !strcmp(sym_name, func)) {
> +			*addr = sym_addr;
> +			err = 0;
> +			break;
> +		}
> +	}
> +
> +	fclose(f);
> +	return err;
> +}

Could we just reuse kallsyms_find() from trace_helpers.c which is also used
in couple of other prog_tests already?

> +
> +/*
> + * Check whether or not s32 in bpf_kfunc_desc is sufficient
> + * to represent the offset between bpf_testmod_test_mod_kfunc
> + * and __bpf_call_base.
> + */
> +void test_ksyms_module_valid_offset(void)
> +{
> +	unsigned long kfunc_addr;
> +	unsigned long base_addr;
> +	int used_offset;
> +	long actual_offset;
> +	int err;
> +
> +	if (!env.has_testmod) {
> +		test__skip();
> +		return;
> +	}
> +
> +	err = test_find_func_in_kallsyms("bpf_testmod_test_mod_kfunc",
> +					 &kfunc_addr);
> +	if (!ASSERT_OK(err, "find kfunc addr"))
> +		return;
> +
> +	err = test_find_func_in_kallsyms("__bpf_call_base", &base_addr);
> +	if (!ASSERT_OK(err, "find base addr"))
> +		return;
> +
> +	used_offset = kfunc_addr - base_addr;
> +	actual_offset = kfunc_addr - base_addr;
> +	ASSERT_EQ((long)used_offset, actual_offset, "kfunc offset overflowed");

Is the above also executed in case bpf_jit_supports_kfunc_call() falls back to
the default __weak callback, returning false? If yes, then the ASSERT_EQ() may
fail on archs like s390, ppc, etc where the offset may not be enough.

> +}
> +
>   void test_ksyms_module_lskel(void)
>   {
>   	struct test_ksyms_module_lskel *skel;
> @@ -55,6 +125,8 @@ void test_ksyms_module_libbpf(void)
>   
>   void test_ksyms_module(void)
>   {
> +	if (test__start_subtest("valid_offset"))
> +		test_ksyms_module_valid_offset();
>   	if (test__start_subtest("lskel"))
>   		test_ksyms_module_lskel();
>   	if (test__start_subtest("libbpf"))
> 



From andriy.shevchenko at linux.intel.com  Fri Jan 28 06:45:14 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 16:45:14 +0200
Subject: [PATCH] Revert "pinctrl: zynqmp: Unify pin naming"
In-Reply-To: <20220127194602.21987-1-gerhard@engleder-embedded.com>
References: <20220127194602.21987-1-gerhard@engleder-embedded.com>
Message-ID: <YfQBemA3bCz0FdYS@smile.fi.intel.com>

On Thu, Jan 27, 2022 at 08:46:02PM +0100, Gerhard Engleder wrote:
> From: Gerhard Engleder <gerhard at engleder-embedded.com>

Thanks for your report, my comments below.

> This reverts commit 54784ff24971ed5bd3f1056edce998148709d0a7.
> 
> This patch changes the pin names from "MIO%d" to "MIO-%d", but all dts
> in arch/arm64/boot/dts/xilinx still use the old name. As a result my
> ZCU104 has no output on serial terminal and is not reachable over
> network.

And question here again, is the pin names ABI or not?
If it's an ABI, then it should be clarified in the documentation.
Otherwise, I'm wondering how this even may break anything.

-- 
With Best Regards,
Andy Shevchenko




From andriy.shevchenko at linux.intel.com  Fri Jan 28 06:49:38 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 16:49:38 +0200
Subject: [PATCH] Revert "pinctrl: zynqmp: Unify pin naming"
In-Reply-To: <YfQBemA3bCz0FdYS@smile.fi.intel.com>
References: <20220127194602.21987-1-gerhard@engleder-embedded.com>
 <YfQBemA3bCz0FdYS@smile.fi.intel.com>
Message-ID: <YfQCgnmyMOvB0V/k@smile.fi.intel.com>

On Fri, Jan 28, 2022 at 04:45:14PM +0200, Andy Shevchenko wrote:
> On Thu, Jan 27, 2022 at 08:46:02PM +0100, Gerhard Engleder wrote:
> > From: Gerhard Engleder <gerhard at engleder-embedded.com>
> 
> Thanks for your report, my comments below.
> 
> > This reverts commit 54784ff24971ed5bd3f1056edce998148709d0a7.
> > 
> > This patch changes the pin names from "MIO%d" to "MIO-%d", but all dts
> > in arch/arm64/boot/dts/xilinx still use the old name. As a result my
> > ZCU104 has no output on serial terminal and is not reachable over
> > network.
> 
> And question here again, is the pin names ABI or not?
> If it's an ABI, then it should be clarified in the documentation.
> Otherwise, I'm wondering how this even may break anything.

Meanwhile I apply this to my tree and send as fix PR to Linus.

-- 
With Best Regards,
Andy Shevchenko




From usama.anjum at collabora.com  Fri Jan 28 06:51:13 2022
From: usama.anjum at collabora.com (Muhammad Usama Anjum)
Date: Fri, 28 Jan 2022 19:51:13 +0500
Subject: [PATCH] media: imx: imx8mq-mipi_csi2: Remove unneeded code
In-Reply-To: <20220128135217.ncvjlffzpxxmqbjo@pengutronix.de>
References: <20220128133649.1393201-1-usama.anjum@collabora.com>
 <20220128135217.ncvjlffzpxxmqbjo@pengutronix.de>
Message-ID: <61220daf-ff1e-0c5d-b89e-9325625417ae@collabora.com>

On 1/28/22 6:52 PM, Marc Kleine-Budde wrote:
> On 28.01.2022 18:36:49, Muhammad Usama Anjum wrote:
>> ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
>> return error. Remove the return variable. Simplify other functions which
>> are using this function.
>>
>> Fixes: f0c2ba1ed4ad ("media: imx: imx8mq-mipi_csi2: fix system resume")
>> Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
>> ---
>>  drivers/staging/media/imx/imx8mq-mipi-csi2.c | 16 ++++------------
>>  1 file changed, 4 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
>> index 3b9fa75efac6b..c992b845e63d1 100644
>> --- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c
>> +++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
> [...]
>>  static int imx8mq_mipi_csi_pm_resume(struct device *dev)
>> @@ -742,15 +739,12 @@ static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
>>  {
>>  	struct v4l2_subdev *sd = dev_get_drvdata(dev);
>>  	struct csi_state *state = mipi_sd_to_csi2_state(sd);
>> -	int ret;
>>  
>> -	ret = imx8mq_mipi_csi_pm_suspend(dev);
>> -	if (ret)
>> -		return ret;
>> +	imx8mq_mipi_csi_pm_suspend(dev);
>>  
>>  	state->state |= ST_SUSPENDED;
> 
> 
> what about this flag?
Now that no error is possible inside this function. The state is being
updated each time. This seems correct logically.

Thanks,
Usama


From jszhang at kernel.org  Fri Jan 28 06:52:13 2022
From: jszhang at kernel.org (Jisheng Zhang)
Date: Fri, 28 Jan 2022 22:52:13 +0800
Subject: [PATCH net-next] net: stmmac: dwmac-sun8i: make clk really gated
 during rpm suspended
Message-ID: <20220128145213.2454-1-jszhang@kernel.org>

Currently, the dwmac-sun8i's stmmaceth clk isn't disabled even if the
the device has been runtime suspended. The reason is the driver gets
the "stmmaceth" clk as tx_clk and enabling it during probe. But
there's no other usage of tx_clk except preparing and enabling, so
we can remove tx_clk and its usage then rely on the common routine
stmmac_probe_config_dt() to prepare and enable the stmmaceth clk
during driver initialization, and benefit from the runtime pm feature
after probed.

Signed-off-by: Jisheng Zhang <jszhang at kernel.org>
---
 .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 30 +++++++------------
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index 09644ab0d87a..f86cc83003f2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -16,6 +16,7 @@
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regmap.h>
 #include <linux/stmmac.h>
@@ -57,7 +58,6 @@ struct emac_variant {
 };
 
 /* struct sunxi_priv_data - hold all sunxi private data
- * @tx_clk:	reference to MAC TX clock
  * @ephy_clk:	reference to the optional EPHY clock for the internal PHY
  * @regulator:	reference to the optional regulator
  * @rst_ephy:	reference to the optional EPHY reset for the internal PHY
@@ -68,7 +68,6 @@ struct emac_variant {
  * @mux_handle:	Internal pointer used by mdio-mux lib
  */
 struct sunxi_priv_data {
-	struct clk *tx_clk;
 	struct clk *ephy_clk;
 	struct regulator *regulator;
 	struct reset_control *rst_ephy;
@@ -579,22 +578,14 @@ static int sun8i_dwmac_init(struct platform_device *pdev, void *priv)
 		}
 	}
 
-	ret = clk_prepare_enable(gmac->tx_clk);
-	if (ret) {
-		dev_err(&pdev->dev, "Could not enable AHB clock\n");
-		goto err_disable_regulator;
-	}
-
 	if (gmac->use_internal_phy) {
 		ret = sun8i_dwmac_power_internal_phy(netdev_priv(ndev));
 		if (ret)
-			goto err_disable_clk;
+			goto err_disable_regulator;
 	}
 
 	return 0;
 
-err_disable_clk:
-	clk_disable_unprepare(gmac->tx_clk);
 err_disable_regulator:
 	if (gmac->regulator)
 		regulator_disable(gmac->regulator);
@@ -1043,8 +1034,6 @@ static void sun8i_dwmac_exit(struct platform_device *pdev, void *priv)
 	if (gmac->variant->soc_has_internal_phy)
 		sun8i_dwmac_unpower_internal_phy(gmac);
 
-	clk_disable_unprepare(gmac->tx_clk);
-
 	if (gmac->regulator)
 		regulator_disable(gmac->regulator);
 }
@@ -1167,12 +1156,6 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	gmac->tx_clk = devm_clk_get(dev, "stmmaceth");
-	if (IS_ERR(gmac->tx_clk)) {
-		dev_err(dev, "Could not get TX clock\n");
-		return PTR_ERR(gmac->tx_clk);
-	}
-
 	/* Optional regulator for PHY */
 	gmac->regulator = devm_regulator_get_optional(dev, "phy");
 	if (IS_ERR(gmac->regulator)) {
@@ -1254,6 +1237,12 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 	ndev = dev_get_drvdata(&pdev->dev);
 	priv = netdev_priv(ndev);
 
+	/* the MAC is runtime suspended after stmmac_dvr_probe(), so we
+	 * need to ensure the MAC resume back before other operations such
+	 * as reset.
+	 */
+	pm_runtime_get_sync(&pdev->dev);
+
 	/* The mux must be registered after parent MDIO
 	 * so after stmmac_dvr_probe()
 	 */
@@ -1272,12 +1261,15 @@ static int sun8i_dwmac_probe(struct platform_device *pdev)
 			goto dwmac_remove;
 	}
 
+	pm_runtime_put(&pdev->dev);
+
 	return 0;
 
 dwmac_mux:
 	reset_control_put(gmac->rst_ephy);
 	clk_put(gmac->ephy_clk);
 dwmac_remove:
+	pm_runtime_put_noidle(&pdev->dev);
 	stmmac_dvr_remove(&pdev->dev);
 dwmac_exit:
 	sun8i_dwmac_exit(pdev, gmac);
-- 
2.34.1



From maz at kernel.org  Fri Jan 28 07:09:49 2022
From: maz at kernel.org (Marc Zyngier)
Date: Fri, 28 Jan 2022 15:09:49 +0000
Subject: [PATCH] PCI: mediatek: Change MSI interrupt processing sequence
In-Reply-To: <20220128131250.GA200007@bhelgaas>
References: <87r18s5jbn.wl-maz@kernel.org> <20220128131250.GA200007@bhelgaas>
Message-ID: <87o83v6gn6.wl-maz@kernel.org>

On Fri, 28 Jan 2022 13:12:50 +0000,
Bjorn Helgaas <helgaas at kernel.org> wrote:
> 
> On Fri, Jan 28, 2022 at 08:57:16AM +0000, Marc Zyngier wrote:
> > On Thu, 27 Jan 2022 21:21:00 +0000,
> > Bjorn Helgaas <helgaas at kernel.org> wrote:
>
> Thanks a lot for taking a look at these, Marc!  Is there anything we
> can do to make all these drivers/pci/controller/* drivers more
> consistent and easier to review?  I found it very difficult to look
> across all of them and find similar design patterns.

It looks to me that a number of them are just wrapping the same
underlying IP block, most likely the DW controller (this looks to be
the case for at least the first two).

They probably all use different register and bit offsets, but it
should be possible to write a library abstracting all these details
and have a common handling for most of them. This would certainly go a
long way in making things more solid.

	M.

-- 
Without deviation from the norm, progress is not possible.


From daniel.lezcano at linaro.org  Fri Jan 28 07:13:11 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 28 Jan 2022 16:13:11 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <48865702.Mx8J7aE1p6@diego>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
 <48865702.Mx8J7aE1p6@diego>
Message-ID: <55780cda-f963-9168-f439-5a51da3b4907@linaro.org>


Hi Heiko,

thanks for your comments

On 28/01/2022 11:19, Heiko St?bner wrote:
> Am Dienstag, 25. Januar 2022, 18:18:09 CET schrieb Daniel Lezcano:
>> The DTPM framework does support now the hierarchy description.
>>
>> The platform specific code can call the hierarchy creation function
>> with an array of struct dtpm_node pointing to their parent.
>>
>> This patch provides a description of the big / Little CPUs and the
>> GPU and tie them together under a virtual 'package' name. Only rk3399 is
>> described now.
>>
>> The description could be extended in the future with the memory
>> controller with devfreq.
>>
>> The description is always a module and it describes the soft
>> dependencies. The userspace has to load the softdeps module in the
>> right order.
>>
>> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>

[ ... ]

>> +static struct dtpm_node __initdata rk3399_hierarchy[] = {
> 
> The driver is tristate so buildable as module but uses __initdata.
> As it depends on panfrost (which also can be a module) you
> probably want a "__initdata_or_module" here .

Well, actually the dependency is wrong.

It should be:

	depends on DTPM && m

It will be compiled always as a module.

Referring to the Documentation/kernel-hacking/hacking.rst

"After boot, the kernel frees up a special section; functions marked with
``__init`` and data structures marked with ``__initdata`` are dropped
after boot is complete: similarly modules discard this memory after
initialization."

So after the module is loaded and the hierarchy is created, nothing will 
stay in memory (except the future module exit function)


>> +	[0]{ .name = "rk3399",
>> +	     .type = DTPM_NODE_VIRTUAL },
>> +	[1]{ .name = "package",
>> +	     .type = DTPM_NODE_VIRTUAL,
>> +	     .parent = &rk3399_hierarchy[0] },
>> +	[2]{ .name = "/cpus/cpu at 0",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[3]{ .name = "/cpus/cpu at 1",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[4]{ .name = "/cpus/cpu at 2",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[5]{ .name = "/cpus/cpu at 3",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[6]{ .name = "/cpus/cpu at 100",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[7]{ .name = "/cpus/cpu at 101",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[8]{ .name = "/gpu at ff9a0000",
>> +	     .type = DTPM_NODE_DT,
>> +	     .parent = &rk3399_hierarchy[1] },
>> +	[9]{ },
> 
> hmm, do we want a "/* sentinel */" inside the empty last entry?
> I think that is pretty common to denote the "this one is the last entry"
> of a dynamic list ;-)

Sure

>> +};
>> +
>> +static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
>> +        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
>> +        {},
>> +};
>> +
>> +static int __init rockchip_dtpm_init(void)
>> +{
>> +	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
>> +}
>> +module_init(rockchip_dtpm_init);
> 
> Just for my understanding what happens on driver unload?

ATM it is not possible to unload it.

A second series with the hierarchy destruction will follow once this 
series is merged. The module unloading will be added here.


-- 
<http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


From linux at roeck-us.net  Fri Jan 28 07:14:19 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Fri, 28 Jan 2022 07:14:19 -0800
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfP0osb45uJldtM9@localhost.localdomain>
References: <YfP0osb45uJldtM9@localhost.localdomain>
Message-ID: <58da38d1-6a1f-ccdf-fc65-b53bf79851e1@roeck-us.net>

On 1/28/22 05:50, Krzysztof Adamski wrote:
> On EFI enabled arm64 systems, efi_reboot was called before
> do_kernel_restart, completely omitting the reset_handlers functionality.
> By registering efi_reboot as part of the chain with slightly elevated
> priority, we make it run before the default handler but still allow
> plugging in other handlers.
> Thanks to that, things like gpio_restart, restart handlers in
> watchdog_core, mmc or mtds are working on those platforms.
> 
> The priority 130 is one higher than PSCI, to overrule that but still
> allow to easily register higher prio handlers, if needed.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
> 
> Changes in v2:
>    - Register the handler in EFI code, instead of arm64 setup.c
>    - Remove the contdition from the handler - it should be run in all
>      cases when it is registered
>    - Bump the priority to 130 to make it completly obious this should be
>      run before PSCI (which has priority of 129)
> 
>   arch/arm64/kernel/process.c        |  7 -------
>   drivers/firmware/efi/arm-runtime.c | 21 +++++++++++++++++++++
>   2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..b86ef77bb0c8 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>   	local_irq_disable();
>   	smp_send_stop();
>   
> -	/*
> -	 * UpdateCapsule() depends on the system being reset via
> -	 * ResetSystem().
> -	 */
> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
> -		efi_reboot(reboot_mode, NULL);
> -
>   	/* Now call the architecture specific reboot code. */
>   	do_kernel_restart(cmd);
>   
> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
> index 3359ae2adf24..b9a2cdbe80b4 100644
> --- a/drivers/firmware/efi/arm-runtime.c
> +++ b/drivers/firmware/efi/arm-runtime.c
> @@ -80,6 +80,24 @@ static bool __init efi_virtmap_init(void)
>   	return true;
>   }
>   
> +static int efi_restart(struct notifier_block *nb, unsigned long action,
> +		       void *data)
> +{
> +	/*
> +	 * UpdateCapsule() depends on the system being reset via
> +	 * ResetSystem().
> +	 */
> +	efi_reboot(reboot_mode, NULL);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block efi_restart_nb = {
> +	.notifier_call = efi_restart,
> +	/* We want this to take priority over PSCI which has priority of 129. */
> +	.priority = 130,
> +};
> +
>   /*
>    * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
>    * non-early mapping of the UEFI system table and virtual mappings for all
> @@ -148,6 +166,9 @@ static int __init arm_enable_runtime_services(void)
>   	efi_native_runtime_setup();
>   	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
>   
> +	if (IS_ENABLED(CONFIG_ARM64))
> +		register_restart_handler(&efi_restart_nb);
> +
>   	return 0;
>   }
>   early_initcall(arm_enable_runtime_services);



From david at redhat.com  Fri Jan 28 07:15:40 2022
From: david at redhat.com (David Hildenbrand)
Date: Fri, 28 Jan 2022 16:15:40 +0100
Subject: [PATCH RFC v1] drivers/base/node: consolidate node device subsystem
 initialization in node_dev_init()
Message-ID: <20220128151540.164759-1-david@redhat.com>

... and call node_dev_init() after memory_dev_init() from driver_init(),
so before any of the existing arch/subsys calls. All online nodes should
be known at that point.

This is in line with memory_dev_init(), which initializes the memory
device subsystem and creates all memory block devices.

Similar to memory_dev_init(), panic() if anything goes wrong, we don't
want to continue with such basic initialization errors.

The important part is that node_dev_init() gets called after
memory_dev_init() and after cpu_dev_init(), but before any of the
relevant archs call register_cpu() to register the new cpu device under
the node device. The latter should be the case for the current users
of topology_init().

Cc: Andrew Morton <akpm at linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
Cc: Michal Hocko <mhocko at suse.com>
Cc: Oscar Salvador <osalvador at suse.de>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will at kernel.org>
Cc: Thomas Bogendoerfer <tsbogend at alpha.franken.de>
Cc: Michael Ellerman <mpe at ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: Paul Walmsley <paul.walmsley at sifive.com>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
Cc: Albert Ou <aou at eecs.berkeley.edu>
Cc: Heiko Carstens <hca at linux.ibm.com>
Cc: Vasily Gorbik <gor at linux.ibm.com>
Cc: Yoshinori Sato <ysato at users.sourceforge.jp>
Cc: Rich Felker <dalias at libc.org>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: Ingo Molnar <mingo at redhat.com>
Cc: Borislav Petkov <bp at alien8.de>
Cc: Dave Hansen <dave.hansen at linux.intel.com>
Cc: "Rafael J. Wysocki" <rafael at kernel.org>
Cc: x86 at kernel.org
Cc: linux-arm-kernel at lists.infradead.org
Cc: linux-kernel at vger.kernel.org
Cc: linux-ia64 at vger.kernel.org
Cc: linux-mips at vger.kernel.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: linux-riscv at lists.infradead.org
Cc: linux-s390 at vger.kernel.org
Cc: linux-sh at vger.kernel.org
Cc: sparclinux at vger.kernel.org
Cc: linux-mm at kvack.org
Signed-off-by: David Hildenbrand <david at redhat.com>

---

RFC because I tested only on x86-64 and s390x, I think I cross-compiled all
applicable architectures except riscv and sparc.

This is somewhat a preparation for detecting if a memory block
(/sys/devices/system/memory/memory*) is managed by a single zone, and
storing the zone for the memory block -- to get rid of
test_pages_in_a_zone(). For that, we want to know all nodes that are
applicable for a single memory block (mem->nid), which is determined when
registering the node.

While this change might not be strictly required for that change, this
way it's easier to see when the nodes are gettin created and
consequently when the node ids for a memory block are determined.

---
 arch/arm64/kernel/setup.c   |  3 ---
 arch/ia64/kernel/topology.c | 10 ----------
 arch/mips/kernel/topology.c |  5 -----
 arch/powerpc/kernel/sysfs.c | 17 -----------------
 arch/riscv/kernel/setup.c   |  3 ---
 arch/s390/kernel/numa.c     |  7 -------
 arch/sh/kernel/topology.c   |  5 -----
 arch/sparc/kernel/sysfs.c   | 12 ------------
 arch/x86/kernel/topology.c  |  5 -----
 drivers/base/init.c         |  1 +
 drivers/base/node.c         | 30 +++++++++++++++++-------------
 include/linux/node.h        |  4 ++++
 12 files changed, 22 insertions(+), 80 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index f70573928f1b..3505789cf4bd 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -406,9 +406,6 @@ static int __init topology_init(void)
 {
 	int i;
 
-	for_each_online_node(i)
-		register_one_node(i);
-
 	for_each_possible_cpu(i) {
 		struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
 		cpu->hotpluggable = cpu_can_disable(i);
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index e4992917a24b..94a848b06f15 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -70,16 +70,6 @@ static int __init topology_init(void)
 {
 	int i, err = 0;
 
-#ifdef CONFIG_NUMA
-	/*
-	 * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes?
-	 */
-	for_each_online_node(i) {
-		if ((err = register_one_node(i)))
-			goto out;
-	}
-#endif
-
 	sysfs_cpus = kcalloc(NR_CPUS, sizeof(struct ia64_cpu), GFP_KERNEL);
 	if (!sysfs_cpus)
 		panic("kzalloc in topology_init failed - NR_CPUS too big?");
diff --git a/arch/mips/kernel/topology.c b/arch/mips/kernel/topology.c
index 08ad6371fbe0..9429d85a4703 100644
--- a/arch/mips/kernel/topology.c
+++ b/arch/mips/kernel/topology.c
@@ -12,11 +12,6 @@ static int __init topology_init(void)
 {
 	int i, ret;
 
-#ifdef CONFIG_NUMA
-	for_each_online_node(i)
-		register_one_node(i);
-#endif /* CONFIG_NUMA */
-
 	for_each_present_cpu(i) {
 		struct cpu *c = &per_cpu(cpu_devices, i);
 
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index d45a415d5374..2069bbb90a9a 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -1110,14 +1110,6 @@ EXPORT_SYMBOL_GPL(cpu_remove_dev_attr_group);
 /* NUMA stuff */
 
 #ifdef CONFIG_NUMA
-static void __init register_nodes(void)
-{
-	int i;
-
-	for (i = 0; i < MAX_NUMNODES; i++)
-		register_one_node(i);
-}
-
 int sysfs_add_device_to_node(struct device *dev, int nid)
 {
 	struct node *node = node_devices[nid];
@@ -1132,13 +1124,6 @@ void sysfs_remove_device_from_node(struct device *dev, int nid)
 	sysfs_remove_link(&node->dev.kobj, kobject_name(&dev->kobj));
 }
 EXPORT_SYMBOL_GPL(sysfs_remove_device_from_node);
-
-#else
-static void __init register_nodes(void)
-{
-	return;
-}
-
 #endif
 
 /* Only valid if CPU is present. */
@@ -1155,8 +1140,6 @@ static int __init topology_init(void)
 {
 	int cpu, r;
 
-	register_nodes();
-
 	for_each_possible_cpu(cpu) {
 		struct cpu *c = &per_cpu(cpu_devices, cpu);
 
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index b42bfdc67482..834eb652a7b9 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -301,9 +301,6 @@ static int __init topology_init(void)
 {
 	int i, ret;
 
-	for_each_online_node(i)
-		register_one_node(i);
-
 	for_each_possible_cpu(i) {
 		struct cpu *cpu = &per_cpu(cpu_devices, i);
 
diff --git a/arch/s390/kernel/numa.c b/arch/s390/kernel/numa.c
index 51c5a9f6e525..23ab9f02f278 100644
--- a/arch/s390/kernel/numa.c
+++ b/arch/s390/kernel/numa.c
@@ -33,10 +33,3 @@ void __init numa_setup(void)
 	NODE_DATA(0)->node_spanned_pages = memblock_end_of_DRAM() >> PAGE_SHIFT;
 	NODE_DATA(0)->node_id = 0;
 }
-
-static int __init numa_init_late(void)
-{
-	register_one_node(0);
-	return 0;
-}
-arch_initcall(numa_init_late);
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 76af6db9daa2..2d2a7509b565 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -46,11 +46,6 @@ static int __init topology_init(void)
 {
 	int i, ret;
 
-#ifdef CONFIG_NUMA
-	for_each_online_node(i)
-		register_one_node(i);
-#endif
-
 	for_each_present_cpu(i) {
 		struct cpu *c = &per_cpu(cpu_devices, i);
 
diff --git a/arch/sparc/kernel/sysfs.c b/arch/sparc/kernel/sysfs.c
index 6d60d416f0dd..f19487e4cc71 100644
--- a/arch/sparc/kernel/sysfs.c
+++ b/arch/sparc/kernel/sysfs.c
@@ -244,22 +244,10 @@ static void __init check_mmu_stats(void)
 		mmu_stats_supported = 1;
 }
 
-static void register_nodes(void)
-{
-#ifdef CONFIG_NUMA
-	int i;
-
-	for (i = 0; i < MAX_NUMNODES; i++)
-		register_one_node(i);
-#endif
-}
-
 static int __init topology_init(void)
 {
 	int cpu, ret;
 
-	register_nodes();
-
 	check_mmu_stats();
 
 	for_each_possible_cpu(cpu) {
diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
index bd83748e2bde..8617d1ed9d31 100644
--- a/arch/x86/kernel/topology.c
+++ b/arch/x86/kernel/topology.c
@@ -154,11 +154,6 @@ static int __init topology_init(void)
 {
 	int i;
 
-#ifdef CONFIG_NUMA
-	for_each_online_node(i)
-		register_one_node(i);
-#endif
-
 	for_each_present_cpu(i)
 		arch_register_cpu(i);
 
diff --git a/drivers/base/init.c b/drivers/base/init.c
index a9f57c22fb9e..d8d0fe687111 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -35,5 +35,6 @@ void __init driver_init(void)
 	auxiliary_bus_init();
 	cpu_dev_init();
 	memory_dev_init();
+	node_dev_init();
 	container_dev_init();
 }
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 87acc47e8951..a133981a12fc 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -1065,26 +1065,30 @@ static const struct attribute_group *cpu_root_attr_groups[] = {
 };
 
 #define NODE_CALLBACK_PRI	2	/* lower than SLAB */
-static int __init register_node_type(void)
+void __init node_dev_init(void)
 {
-	int ret;
+	static struct notifier_block node_memory_callback_nb = {
+		.notifier_call = node_memory_callback,
+		.priority = NODE_CALLBACK_PRI,
+	};
+	int ret, i;
 
  	BUILD_BUG_ON(ARRAY_SIZE(node_state_attr) != NR_NODE_STATES);
  	BUILD_BUG_ON(ARRAY_SIZE(node_state_attrs)-1 != NR_NODE_STATES);
 
 	ret = subsys_system_register(&node_subsys, cpu_root_attr_groups);
-	if (!ret) {
-		static struct notifier_block node_memory_callback_nb = {
-			.notifier_call = node_memory_callback,
-			.priority = NODE_CALLBACK_PRI,
-		};
-		register_hotmemory_notifier(&node_memory_callback_nb);
-	}
+	if (ret)
+		panic("%s() failed to register subsystem: %d\n", __func__, ret);
+
+	register_hotmemory_notifier(&node_memory_callback_nb);
 
 	/*
-	 * Note:  we're not going to unregister the node class if we fail
-	 * to register the node state class attribute files.
+	 * Create all node devices, which will properly link the node
+	 * to applicable memory block devices and already created cpu devices.
 	 */
-	return ret;
+	for_each_online_node(i) {
+		ret = register_one_node(i);
+		if (ret)
+			panic("%s() failed to add node: %d\n", __func__, ret);
+	}
 }
-postcore_initcall(register_node_type);
diff --git a/include/linux/node.h b/include/linux/node.h
index bb21fd631b16..f3be6ccfebed 100644
--- a/include/linux/node.h
+++ b/include/linux/node.h
@@ -112,6 +112,7 @@ static inline void link_mem_sections(int nid, unsigned long start_pfn,
 
 extern void unregister_node(struct node *node);
 #ifdef CONFIG_NUMA
+extern void node_dev_init(void);
 /* Core of the node registration - only memory hotplug should use this */
 extern int __register_one_node(int nid);
 
@@ -149,6 +150,9 @@ extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
 					 node_registration_func_t unregister);
 #endif
 #else
+static inline void node_dev_init(void)
+{
+}
 static inline int __register_one_node(int nid)
 {
 	return 0;

base-commit: e783362eb54cd99b2cac8b3a9aeac942e6f6ac07
-- 
2.34.1



From patchwork-bot+netdevbpf at kernel.org  Fri Jan 28 07:20:11 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 28 Jan 2022 15:20:11 +0000
Subject: [PATCH net-next] net: stmmac: dwmac-sun8i: make clk really gated
 during rpm suspended
In-Reply-To: <20220128145213.2454-1-jszhang@kernel.org>
References: <20220128145213.2454-1-jszhang@kernel.org>
Message-ID: <164338321113.8810.8058423675917516702.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net-next.git (master)
by David S. Miller <davem at davemloft.net>:

On Fri, 28 Jan 2022 22:52:13 +0800 you wrote:
> Currently, the dwmac-sun8i's stmmaceth clk isn't disabled even if the
> the device has been runtime suspended. The reason is the driver gets
> the "stmmaceth" clk as tx_clk and enabling it during probe. But
> there's no other usage of tx_clk except preparing and enabling, so
> we can remove tx_clk and its usage then rely on the common routine
> stmmac_probe_config_dt() to prepare and enable the stmmaceth clk
> during driver initialization, and benefit from the runtime pm feature
> after probed.
> 
> [...]

Here is the summary with links:
  - [net-next] net: stmmac: dwmac-sun8i: make clk really gated during rpm suspended
    https://git.kernel.org/netdev/net-next/c/b76bbb34dc80

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From patchwork-bot+netdevbpf at kernel.org  Fri Jan 28 07:20:10 2022
From: patchwork-bot+netdevbpf at kernel.org (patchwork-bot+netdevbpf at kernel.org)
Date: Fri, 28 Jan 2022 15:20:10 +0000
Subject: [PATCH] net: stmmac: properly handle with runtime pm in
 stmmac_dvr_remove()
In-Reply-To: <20220128141550.2350-1-jszhang@kernel.org>
References: <20220128141550.2350-1-jszhang@kernel.org>
Message-ID: <164338321073.8810.2377370074085228481.git-patchwork-notify@kernel.org>

Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem at davemloft.net>:

On Fri, 28 Jan 2022 22:15:50 +0800 you wrote:
> There are two issues with runtime pm handling in stmmac_dvr_remove():
> 
> 1. the mac is runtime suspended before stopping dma and rx/tx. We
> need to ensure the device is properly resumed back.
> 
> 2. the stmmaceth clk enable/disable isn't balanced in both exit and
> error handling code path. Take the exit code path for example, when we
> unbind the driver or rmmod the driver module, the mac is runtime
> suspended as said above, so the stmmaceth clk is disabled, but
> 	stmmac_dvr_remove()
> 	  stmmac_remove_config_dt()
> 	    clk_disable_unprepare()
> CCF will complain this time. The error handling code path suffers
> from the similar situtaion.
> 
> [...]

Here is the summary with links:
  - net: stmmac: properly handle with runtime pm in stmmac_dvr_remove()
    https://git.kernel.org/netdev/net/c/6449520391df

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




From naresh.kamboju at linaro.org  Fri Jan 28 07:21:53 2022
From: naresh.kamboju at linaro.org (Naresh Kamboju)
Date: Fri, 28 Jan 2022 20:51:53 +0530
Subject: [next] arch/arm/kernel/setup.c:1028:63: error: 'SECTION_SIZE'
 undeclared
Message-ID: <CA+G9fYvxxc4o5UjRfHVgmcaTN1ijxXX8e=OTP4t7PbRENmVBsQ@mail.gmail.com>

Following build errors noticed on Linux next 20220128 arm with tinyconfig.

make --silent --keep-going --jobs=8 \
   ARCH=arm \
   CROSS_COMPILE=arm-linux-gnueabihf- \
   'CC=sccache arm-linux-gnueabihf-gcc' \
   'HOSTCC=sccache gcc'

arch/arm/kernel/setup.c: In function 'reserve_crashkernel':
arch/arm/kernel/setup.c:1028:63: error: 'SECTION_SIZE' undeclared
(first use in this function); did you mean 'SECTIONS_SHIFT'?
 1028 |                 start = memblock_phys_alloc_range(crash_size,
SECTION_SIZE,
      |
^~~~~~~~~~~~
      |
SECTIONS_SHIFT
arch/arm/kernel/setup.c:1028:63: note: each undeclared identifier is
reported only once for each function it appears in
make[3]: *** [scripts/Makefile.build:289: arch/arm/kernel/setup.o] Error 1


Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>

meta data:
-----------
    git describe: next-20220128
    git_repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
    git_sha: b605fdc54c2b28c30ef06d9db99282d8a32ae4be
    target_arch: arm
    kconfig: tinyconfig
    toolchain: gcc-11

Build log:
-------------
https://builds.tuxbuild.com/24JPvTrXx7HvkQtxoIXqZtZoZkA/

Steps to reproduce:
--------------------
# To install tuxmake on your system globally:
# sudo pip3 install -U tuxmake
#
# See https://docs.tuxmake.org/ for complete documentation.
# Original tuxmake command with fragments listed below.

tuxmake --runtime podman --target-arch arm --toolchain gcc-11
--kconfig tinyconfig

--
Linaro LKFT
https://lkft.linaro.org


From robin.murphy at arm.com  Fri Jan 28 07:28:23 2022
From: robin.murphy at arm.com (Robin Murphy)
Date: Fri, 28 Jan 2022 15:28:23 +0000
Subject: [RFC PATCH] ACPI / amba: Skip creating amba device when
 associated cpu is not online
In-Reply-To: <2f3c5e6b-7000-8fa2-21f7-3b0c3fb66ae3@arm.com>
References: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
 <2f3c5e6b-7000-8fa2-21f7-3b0c3fb66ae3@arm.com>
Message-ID: <136be111-c75e-48b2-caef-cbf4900b6ce1@arm.com>

On 2022-01-28 11:00, Suzuki K Poulose wrote:
> Hi Xiang
> 
> On 07/01/2022 08:41, chenxiang wrote:
>> From: Xiang Chen <chenxiang66 at hisilicon.com>
>>
>> If not up all the cpus with command line "maxcpus=x", system will be
>> blocked.
>> We find that some amba devices such as ETM devices, are associated with
>> special cpus, and if the cpu is not up, the register of associated device
>> is not allowed to access. BIOS reports all the ETM device nodes and a
>> amba device is created for every ETM device, so even if one cpu is not 
>> up,
>> the amba device will still be created for the associated device, and also
>> the register of device (pid and cid) will be accessed when adding amba
>> device which will cause the issue.
>> To fix it, skip creating amba device if it is associated with a cpu which
>> is not online.
> 
> I understand the issue. We do not have an issue at least on DT based 
> platforms with a similar environment (Juno). The key is the power 
> management for the components.
> 
> There are two separate issues at play here :
> 
> 1) Power management with ACPI. I believe there is a solution in progress
> to address this.
> 
> 2) The ETM is in the same power domain as that of the CPU and normal 
> device power management may not work without the CPU being online.
> 
> 3) Additionally we have other issue of supporting system instructions
> with ACPI, which do not appear on the AMBA bus.
> 
> Considering all of these, the ideal solution is to :
> 
> 1) Implement power management for ACPI, which is anyway in progress
>  ? (at least for SCMI based systems)
> 2) Move the ETM driver away from the AMBA framework. That would make
>  ?? the CPU online problem and the (3) above easier to solve.
>  ?? Anshuman is going to look into this.
> 
> In the meantime, we could have this temporary fix in and solve it
> forever by moving away from the AMBA.

Out of curiosity, what happens when you boot with "maxcpus=" and then 
manually bring up the extra cpus from userspace later? Is there a chance 
that tracing will explode if some online CPUs have ETM initialised but 
others don't?

Robin.

>>
>> Signed-off-by: Xiang Chen <chenxiang66 at hisilicon.com>
>> ---
>> ? drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
>> ? 1 file changed, 36 insertions(+)
>>
>> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
>> index ab8a4e0191b1..2369198f734b 100644
>> --- a/drivers/acpi/acpi_amba.c
>> +++ b/drivers/acpi/acpi_amba.c
>> @@ -16,6 +16,7 @@
>> ? #include <linux/ioport.h>
>> ? #include <linux/kernel.h>
>> ? #include <linux/module.h>
>> +#include <acpi/processor.h>
>> ? #include "internal.h"
>> @@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
>> ????? clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
>> ? }
>> +static int acpi_handle_to_cpuid(acpi_handle handle)
>> +{
>> +??? int cpu = -1;
>> +??? struct acpi_processor *pr;
>> +
>> +??? for_each_possible_cpu(cpu) {
>> +??????? pr = per_cpu(processors, cpu);
>> +??????? if (pr && pr->handle == handle)
>> +??????????? break;
>> +??? }
>> +
>> +??? return cpu;
>> +}
>> +
> 
> Please could we reuse the function in coresight-platform.c ?
> i.e, move it to a generic location and share it, rather than
> duplicating it ?
> 
> 
>> +static int acpi_dev_get_cpu(struct acpi_device *adev)
>> +{
>> +??? acpi_handle cpu_handle;
>> +??? acpi_status status;
>> +??? int cpu;
>> +
>> +??? status = acpi_get_parent(adev->handle, &cpu_handle);
>> +??? if (ACPI_FAILURE(status))
>> +??????? return -1;
>> +??? cpu = acpi_handle_to_cpuid(cpu_handle);
>> +??? if (cpu >= nr_cpu_ids)
>> +??????? return -1;
>> +??? return cpu;
>> +}
>> +
>> ? static int amba_handler_attach(struct acpi_device *adev,
>> ????????????????? const struct acpi_device_id *id)
>> ? {
>> @@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device 
>> *adev,
>> ????? bool address_found = false;
>> ????? int irq_no = 0;
>> ????? int ret;
>> +??? int cpu;
>> ????? /* If the ACPI node already has a physical device attached, skip 
>> it. */
>> ????? if (adev->physical_node_count)
>> ????????? return 0;
>> +??? /* If the cpu associated with the device is not online, skip it. */
>> +??? cpu = acpi_dev_get_cpu(adev);
>> +??? if (cpu >= 0 && !cpu_online(cpu))
>> +??????? return 0;
>> +
> 
> Except for the comment above, the patch looks good to me.
> 
> Suzuki
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


From mathieu.poirier at linaro.org  Fri Jan 28 07:29:32 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Jan 2022 08:29:32 -0700
Subject: [PATCH V3 RESEND 0/7] coresight: trbe: Workaround Cortex-A510
 erratas
In-Reply-To: <YfPKvsw+fOsJvSm7@arm.com>
References: <1643120437-14352-1-git-send-email-anshuman.khandual@arm.com>
 <20220127202220.GA2191206@p14s> <YfPKvsw+fOsJvSm7@arm.com>
Message-ID: <CANLsYkwOdYsFwmp+tBazJetivFdJU=y8NEp=sz8mFH3s__pzkg@mail.gmail.com>

On Fri, 28 Jan 2022 at 03:51, Catalin Marinas <catalin.marinas at arm.com> wrote:
>
> Hi Mathieu,
>
> On Thu, Jan 27, 2022 at 01:22:20PM -0700, Mathieu Poirier wrote:
> > On Tue, Jan 25, 2022 at 07:50:30PM +0530, Anshuman Khandual wrote:
> > > Anshuman Khandual (7):
> > >   arm64: Add Cortex-A510 CPU part definition
> > >   arm64: errata: Add detection for TRBE ignored system register writes
> > >   arm64: errata: Add detection for TRBE invalid prohibited states
> > >   arm64: errata: Add detection for TRBE trace data corruption
> > >   coresight: trbe: Work around the ignored system register writes
> > >   coresight: trbe: Work around the invalid prohibited states
> > >   coresight: trbe: Work around the trace data corruption
> > >
> > >  Documentation/arm64/silicon-errata.rst       |   6 +
> > >  arch/arm64/Kconfig                           |  59 ++++++++++
> > >  arch/arm64/include/asm/cputype.h             |   2 +
> > >  arch/arm64/kernel/cpu_errata.c               |  27 +++++
> > >  arch/arm64/tools/cpucaps                     |   3 +
> > >  drivers/hwtracing/coresight/coresight-trbe.c | 114 ++++++++++++++-----
> > >  drivers/hwtracing/coresight/coresight-trbe.h |   8 --
> > >  7 files changed, 183 insertions(+), 36 deletions(-)
> >
> > I have applied this set and sent a pull request to Catalin for the arm64
> > portion.
>
> Well, I'm happy for the whole series to go in via Greg's tree or however
> the coresight patches go in (that's why I acked them). The last three
> patches depend on the first four, so you might as well send them all
> together. I'd split the series only if there's a conflict with the arm64
> tree (I haven't checked).
>

Very well - thanks for the follow up.

> --
> Catalin


From robh+dt at kernel.org  Fri Jan 28 07:32:59 2022
From: robh+dt at kernel.org (Rob Herring)
Date: Fri, 28 Jan 2022 09:32:59 -0600
Subject: [PATCH] of/fdt: move elfcorehdr reservation early for crash dump
 kernel
In-Reply-To: <20220128042321.15228-1-nikhil.gupta@nxp.com>
References: <20220128042321.15228-1-nikhil.gupta@nxp.com>
Message-ID: <CAL_JsqKWmnQde+4tnZ3d90pWguezLVqto4DRe3WRjf9PCQ=L4w@mail.gmail.com>

On Thu, Jan 27, 2022 at 10:23 PM <nikhil.gupta at nxp.com> wrote:
>
> From: Nikhil Gupta <nikhil.gupta at nxp.com>
>
> elfcorehdr_addr is fixed address passed to Second kernel which may be conflicted
> with potential reserved memory in Second kernel,so fdt_reserve_elfcorehdr() ahead
> of fdt_init_reserved_mem() can relieve this situation.

How does changing the order help exactly? If you have an overlap, that
seems bad no matter what. What if the overlapping reserved area is
used by another core or firmware?

Rob


From camel.guo at axis.com  Fri Jan 28 07:36:42 2022
From: camel.guo at axis.com (Camel Guo)
Date: Fri, 28 Jan 2022 16:36:42 +0100
Subject: [PATCH] net: stmmac: dump gmac4 DMA registers correctly
Message-ID: <20220128153642.3129922-1-camel.guo@axis.com>

From: Camel Guo <camelg at axis.com>

Unlike gmac100, gmac1000, gmac4 has 27 DMA registers and they are
located at DMA_CHAN_BASE_ADDR (0x1100). In order for ethtool to dump
gmac4 DMA registers correctly, this commit checks if a net_device has
gmac4 and uses different logic to dump its DMA registers.

This fixes the following KASAN warning, which can normally be triggered
by a command similar like "ethtool -d eth0":

BUG: KASAN: vmalloc-out-of-bounds in dwmac4_dump_dma_regs+0x6d4/0xb30
Write of size 4 at addr ffffffc010177100 by task ethtool/1839
 kasan_report+0x200/0x21c
 __asan_report_store4_noabort+0x34/0x60
 dwmac4_dump_dma_regs+0x6d4/0xb30
 stmmac_ethtool_gregs+0x110/0x204
 ethtool_get_regs+0x200/0x4b0
 dev_ethtool+0x1dac/0x3800
 dev_ioctl+0x7c0/0xb50
 sock_ioctl+0x298/0x6c4
 ...

Signed-off-by: Camel Guo <camelg at axis.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac_dma.h   |  1 +
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 1914ad698cab..acd70b9a3173 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -150,6 +150,7 @@
 
 #define NUM_DWMAC100_DMA_REGS	9
 #define NUM_DWMAC1000_DMA_REGS	23
+#define NUM_DWMAC4_DMA_REGS	27
 
 void dwmac_enable_dma_transmission(void __iomem *ioaddr);
 void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 164dff5ec32e..abfb3cd5958d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -21,10 +21,18 @@
 #include "dwxgmac2.h"
 
 #define REG_SPACE_SIZE	0x1060
+#define GMAC4_REG_SPACE_SIZE	0x116C
 #define MAC100_ETHTOOL_NAME	"st_mac100"
 #define GMAC_ETHTOOL_NAME	"st_gmac"
 #define XGMAC_ETHTOOL_NAME	"st_xgmac"
 
+/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
+ *
+ * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
+ * same time due to the conflicting macro names.
+ */
+#define GMAC4_DMA_CHAN_BASE_ADDR  0x00001100
+
 #define ETHTOOL_DMA_OFFSET	55
 
 struct stmmac_stats {
@@ -434,6 +442,8 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
 
 	if (priv->plat->has_xgmac)
 		return XGMAC_REGSIZE * 4;
+	else if (priv->plat->has_gmac4)
+		return GMAC4_REG_SPACE_SIZE;
 	return REG_SPACE_SIZE;
 }
 
@@ -446,8 +456,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
 	stmmac_dump_mac_regs(priv, priv->hw, reg_space);
 	stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
 
-	if (!priv->plat->has_xgmac) {
-		/* Copy DMA registers to where ethtool expects them */
+	/* Copy DMA registers to where ethtool expects them */
+	if (priv->plat->has_gmac4) {
+		/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
+		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
+		       &reg_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
+		       NUM_DWMAC4_DMA_REGS * 4);
+	} else if (!priv->plat->has_xgmac) {
 		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
 		       &reg_space[DMA_BUS_MODE / 4],
 		       NUM_DWMAC1000_DMA_REGS * 4);
-- 
2.30.2



From mark.rutland at arm.com  Fri Jan 28 07:42:48 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 15:42:48 +0000
Subject: ftrace hangs waiting for rcu (was: Re: [PATCH] ftrace: Have
 architectures opt-in for mcount build time sorting)
In-Reply-To: <yt9dy231yq90.fsf_-_@linux.ibm.com>
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
Message-ID: <YfQCohKWJg9H+uID@FVFF77S0Q05N>

Hi Sven,

On Thu, Jan 27, 2022 at 07:42:35PM +0100, Sven Schnelle wrote:
> Mark Rutland <mark.rutland at arm.com> writes:
> 
> > * I intermittently see a hang when running the tests. I previously hit that
> >   when originally trying to bisect this issue (and IIRC that bisected down to
> >   some RCU changes, but I need to re-run that). When the tests hang I
> >   magic-srsrq + L tells me:
> >
> >   [  271.938438] sysrq: Show Blocked State
> >   [  271.939245] task:ftracetest      state:D stack:    0 pid: 5687 ppid:  5627 flags:0x00000200
> >   [  271.940961] Call trace:
> >   [  271.941472]  __switch_to+0x104/0x160
> >   [  271.942213]  __schedule+0x2b0/0x6e0
> >   [  271.942933]  schedule+0x5c/0xf0
> >   [  271.943586]  schedule_timeout+0x184/0x1c4
> >   [  271.944410]  wait_for_completion+0x8c/0x12c
> >   [  271.945274]  __wait_rcu_gp+0x184/0x190
> >   [  271.946047]  synchronize_rcu_tasks_rude+0x48/0x70
> >   [  271.947007]  update_ftrace_function+0xa4/0xec
> >   [  271.947897]  __unregister_ftrace_function+0xa4/0xf0
> >   [  271.948898]  unregister_ftrace_function+0x34/0x70
> >   [  271.949857]  wakeup_tracer_reset+0x4c/0x100
> >   [  271.950713]  tracing_set_tracer+0xd0/0x2b0
> >   [  271.951552]  tracing_set_trace_write+0xe8/0x150
> >   [  271.952477]  vfs_write+0xfc/0x284
> >   [  271.953171]  ksys_write+0x7c/0x110
> >   [  271.953874]  __arm64_sys_write+0x2c/0x40
> >   [  271.954678]  invoke_syscall+0x5c/0x130
> >   [  271.955442]  el0_svc_common.constprop.0+0x108/0x130
> >   [  271.956435]  do_el0_svc+0x74/0x90
> >   [  271.957124]  el0_svc+0x2c/0x90
> >   [  271.957757]  el0t_64_sync_handler+0xa8/0x12c
> >   [  271.958629]  el0t_64_sync+0x1a0/0x1a4

On arm64 I bisected this down to:

  7a30871b6a27de1a ("rcu-tasks: Introduce ->percpu_enqueue_shift for dynamic queue selection")

Which was going wrong because ilog2() rounds down, and so the shift was wrong
for any nr_cpus that was not a power-of-two. Paul had already fixed that in
rcu-next, and just sent a pull request to Linus:

  https://lore.kernel.org/lkml/20220128143251.GA2398275 at paulmck-ThinkPad-P17-Gen-1/

With that applied, I no longer see these hangs.

Does your s390 test machine have a non-power-of-two nr_cpus, and does that fix
the issue for you?

On arm64 the startup tests didn't seem to trigger the hang, but I was able to
trigger the hang fairly reliably with the ftrace selftests, e.g.

  $ for N in $(seq 1 10); do ./ftracetest test.d/00basic/basic2.tc; done

... which prior to the fix, would hang between runs 2 to 5.

Thanks,
Mark.

> that's interesting. On s390 i'm seeing the same problem in CI, but with
> the startup ftrace tests. So that's likely not arm64 spacific.
> 
> On s390, the last messages from ftrace are [    5.663568] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
> [    5.667099] futex hash table entries: 65536 (order: 12, 16777216 bytes, vmalloc)
> [    5.739549] Running postponed tracer tests:
> [    5.740662] Testing tracer function: PASSED
> [    6.194635] Testing dynamic ftrace: PASSED
> [    6.471213] Testing dynamic ftrace ops #1: 
> [    6.558445] (1 0 1 0 0) 
> [    6.558458] (1 1 2 0 0) 
> [    6.699135] (2 1 3 0 764347) 
> [    6.699252] (2 2 4 0 766466) 
> [    6.759857] (3 2 4 0 1159604)
> [..] hangs here
> 
> The backtrace looks like this, which is very similar to the one above:
> 
> crash> bt 1
> PID: 1      TASK: 80e68100          CPU: 133  COMMAND: "swapper/0"
>  #0 [380004df808] __schedule at cda39f0e
>  #1 [380004df880] schedule at cda3a488
>  #2 [380004df8b0] schedule_timeout at cda41ef6
>  #3 [380004df978] wait_for_completion at cda3bd0a
>  #4 [380004df9d8] __wait_rcu_gp at ccdddd92
>  #5 [380004dfa30] synchronize_rcu_tasks_generic at ccdde0aa
>  #6 [380004dfad8] ftrace_shutdown at cce7b050
>  #7 [380004dfb18] unregister_ftrace_function at cce7b192
>  #8 [380004dfb50] trace_selftest_ops at cda1e0fa
>  #9 [380004dfba0] run_tracer_selftest at cda1e4f2
> #10 [380004dfc00] trace_selftest_startup_function at ce74355c
> #11 [380004dfc58] run_tracer_selftest at cda1e2fc
> #12 [380004dfc98] init_trace_selftests at ce742d30
> #13 [380004dfcd0] do_one_initcall at cccdca16
> #14 [380004dfd68] do_initcalls at ce72e776
> #15 [380004dfde0] kernel_init_freeable at ce72ea60
> #16 [380004dfe50] kernel_init at cda333fe
> #17 [380004dfe68] __ret_from_fork at cccdf920
> #18 [380004dfe98] ret_from_fork at cda444ca
> 
> I didn't had success reproducing it so far, but it is good to know that
> this also happens when running the ftrace testsuite.
> 
> I have several crashdumps, so i could try to pull out some information
> if someone tells me what to look for.
> 
> Thanks,
> Sven


From kuba at kernel.org  Fri Jan 28 07:44:54 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 28 Jan 2022 07:44:54 -0800
Subject: [PATCH net-next v2 9/9] net: ethernet: mtk-star-emac: separate
 tx/rx handling with two NAPIs
In-Reply-To: <2bdb6c9b5ec90b6c606b7db8c13f8acb34910b36.camel@mediatek.com>
References: <20220127015857.9868-1-biao.huang@mediatek.com>
 <20220127015857.9868-10-biao.huang@mediatek.com>
 <20220127194338.01722b3c@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
 <2bdb6c9b5ec90b6c606b7db8c13f8acb34910b36.camel@mediatek.com>
Message-ID: <20220128074454.46d0ca29@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Fri, 28 Jan 2022 15:05:27 +0800 Biao Huang wrote:
> > > + * Description : this is the driver interrupt service routine.
> > > + * it mainly handles:
> > > + *  1. tx complete interrupt for frame transmission.
> > > + *  2. rx complete interrupt for frame reception.
> > > + *  3. MAC Management Counter interrupt to avoid counter overflow.
> > >   */
> > >  static irqreturn_t mtk_star_handle_irq(int irq, void *data)
> > >  {
> > > -	struct mtk_star_priv *priv;
> > > -	struct net_device *ndev;
> > > +	struct net_device *ndev = data;
> > > +	struct mtk_star_priv *priv = netdev_priv(ndev);
> > > +	unsigned int intr_status = mtk_star_intr_ack_all(priv);
> > > +	unsigned long flags = 0;
> > > +
> > > +	if (intr_status & MTK_STAR_BIT_INT_STS_FNRC) {
> > > +		if (napi_schedule_prep(&priv->rx_napi)) {
> > > +			spin_lock_irqsave(&priv->lock, flags);
> > > +			/* mask Rx Complete interrupt */
> > > +			mtk_star_disable_dma_irq(priv, true, false);
> > > +			spin_unlock_irqrestore(&priv->lock, flags);
> > > +			__napi_schedule_irqoff(&priv->rx_napi);
> > > +		}
> > > +	}
> > >  
> > > -	ndev = data;
> > > -	priv = netdev_priv(ndev);
> > > +	if (intr_status & MTK_STAR_BIT_INT_STS_TNTC) {
> > > +		if (napi_schedule_prep(&priv->tx_napi)) {
> > > +			spin_lock_irqsave(&priv->lock, flags);
> > > +			/* mask Tx Complete interrupt */
> > > +			mtk_star_disable_dma_irq(priv, false, true);
> > > +			spin_unlock_irqrestore(&priv->lock, flags);
> > > +			__napi_schedule_irqoff(&priv->tx_napi);
> > > +		}
> > > +	}  
> > 
> > Seems a little wasteful to retake the same lock twice if two IRQ
> > sources fire at the same time.  
> The TX/RX irq control bits are in the same register,
> but they are triggered independently.
> So it seems necessary to protect the register
> access with a spin lock.

This is what I meant:

rx = (status & RX) && napi_schedule_prep(rx_napi);
tx = (status & TX) && napi_schedule_prep(tx_napi);

if (rx || tx) {
	spin_lock()
	disable_irq(priv, rx, tx);	
	spin_unlock();
	if (rx)
		__napi_schedule_irqoff(rx_napi)
	if (tx)
		__napi_schedule_irqoff(tx_napi)
}

> > >  	desc_data.dma_addr = mtk_star_dma_map_tx(priv, skb);
> > >  	if (dma_mapping_error(dev, desc_data.dma_addr))
> > > @@ -1050,18 +1103,10 @@ static int
> > > mtk_star_netdev_start_xmit(struct sk_buff *skb,
> > >  
> > >  	desc_data.skb = skb;
> > >  	desc_data.len = skb->len;
> > > -
> > > -	spin_lock_bh(&priv->lock);
> > > 
> > >  	mtk_star_ring_push_head_tx(ring, &desc_data);
> > >  
> > >  	netdev_sent_queue(ndev, skb->len);
> > >  
> > > -	if (mtk_star_ring_full(ring))
> > > -		netif_stop_queue(ndev);  
> > 
> > Are you stopping the queue in advance somewhere else now? Did you
> > only
> > test this with BQL enabled? Only place that stops the ring also
> > prints
> > a loud warning now AFAICS..  
> No.
> 
> We modify the ring full condition, and will not invoke netif_stop_queue
> if queue is already stopped.

I don't understand what you're saying.

> Test pass no matter whether BQL is enabled or disabled.
> 
> It's much safer to judge queue is full or not at the beginning of
> start_xmit() to avoid invalid setting.

Drivers are expected to stop their queues at the end of xmit routine if
the ring can't accommodate another frame. It's more efficient to stop
the queues early than have to put skbs already dequeued from the qdisc
layer back into the qdiscs.


From heiko at sntech.de  Fri Jan 28 07:48:27 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Fri, 28 Jan 2022 16:48:27 +0100
Subject: [PATCH v7 5/5] rockchip/soc/drivers: Add DTPM description for
 rk3399
In-Reply-To: <20220125171809.1273269-6-daniel.lezcano@linaro.org>
References: <20220125171809.1273269-1-daniel.lezcano@linaro.org>
 <20220125171809.1273269-6-daniel.lezcano@linaro.org>
Message-ID: <3660693.PMFMTDrQKU@diego>

Am Dienstag, 25. Januar 2022, 18:18:09 CET schrieb Daniel Lezcano:
> The DTPM framework does support now the hierarchy description.
> 
> The platform specific code can call the hierarchy creation function
> with an array of struct dtpm_node pointing to their parent.
> 
> This patch provides a description of the big / Little CPUs and the
> GPU and tie them together under a virtual 'package' name. Only rk3399 is
> described now.
> 
> The description could be extended in the future with the memory
> controller with devfreq.
> 
> The description is always a module and it describes the soft
> dependencies. The userspace has to load the softdeps module in the
> right order.
> 
> Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>

Reviewed-by; Heiko Stuebner <heiko at sntech.de>




From mark.rutland at arm.com  Fri Jan 28 07:50:35 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 15:50:35 +0000
Subject: [bootwrapper PATCH v3 00/15] Cleanups and improvements
In-Reply-To: <20220125150057.3936090-1-mark.rutland@arm.com>
References: <20220125150057.3936090-1-mark.rutland@arm.com>
Message-ID: <YfQQy8L6tYFkgUIL@FVFF77S0Q05N>

On Tue, Jan 25, 2022 at 03:00:42PM +0000, Mark Rutland wrote:

> If there are no objections I'll apply this by the end of this week. 

I've pushed this out to master branch now (with the comment fix Andre
suggested). As before, the repo is:

>   https://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git/
>   git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git

Thanks,
Mark.


From gregkh at linuxfoundation.org  Fri Jan 28 07:50:54 2022
From: gregkh at linuxfoundation.org (Greg KH)
Date: Fri, 28 Jan 2022 16:50:54 +0100
Subject: [PATCH] clk: imx: Fix a NULL pointer dereference in
 imx_register_uart_clocks()
In-Reply-To: <CAHCN7x+bvC70Y18j8tvSVZNjwipYu3xTvFo=AjKvYnmaucBiGg@mail.gmail.com>
References: <20220124165206.55059-1-zhou1615@umn.edu>
 <YfPCdPuoB3RYgzL8@kroah.com>
 <CAHCN7x+bvC70Y18j8tvSVZNjwipYu3xTvFo=AjKvYnmaucBiGg@mail.gmail.com>
Message-ID: <YfQQ3iQhSxCiUQ2U@kroah.com>

On Fri, Jan 28, 2022 at 07:47:06AM -0600, Adam Ford wrote:
> On Fri, Jan 28, 2022 at 4:16 AM Greg KH <gregkh at linuxfoundation.org> wrote:
> >
> > On Tue, Jan 25, 2022 at 12:52:06AM +0800, Zhou Qingyang wrote:
> > > In imx_register_uart_clocks(), the global variable imx_uart_clocks is
> > > assigned by kcalloc() and there is a dereference of in the next for loop,
> > > which could introduce a NULL pointer dereference on failure of kcalloc().
> > >
> > > Fix this by adding a NULL check of imx_uart_clocks.
> > >
> > > This bug was found by a static analyzer.
> > >
> > > Builds with 'make allyesconfig' show no new warnings,
> > > and our static analyzer no longer warns about this code.
> > >
> > > Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
> > > Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> > > ---
> > > The analysis employs differential checking to identify inconsistent
> > > security operations (e.g., checks or kfrees) between two code paths
> > > and confirms that the inconsistent operations are not recovered in the
> > > current function or the callers, so they constitute bugs.
> > >
> > > Note that, as a bug found by static analysis, it can be a false
> > > positive or hard to trigger. Multiple researchers have cross-reviewed
> > > the bug.
> > >
> > >  drivers/clk/imx/clk.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
> > > index 7cc669934253..99249ab361d2 100644
> > > --- a/drivers/clk/imx/clk.c
> > > +++ b/drivers/clk/imx/clk.c
> > > @@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
> > >               int i;
> > >
> > >               imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
> > > +             if (!imx_uart_clocks)
> > > +                     return;
> > >
> > >               if (!of_stdout)
> > >                       return;
> > > --
> > > 2.25.1
> > >
> >
> > As stated before, umn.edu is still not allowed to contribute to the
> > Linux kernel.  Please work with your administration to resolve this
> > issue.
> 
> Greg,
> 
> In the interest of safety, I believe this patch is reasonable.

How can kcalloc really fail here?  Seriously, this is an impossible
thing to happen in real-world situations, you have to have special
fault-injection tooling to ever hit this in a system that is not just
frozen due to other problems.

> I
> wrote the original patch that is being fixed by this.  Would it be
> acceptable if I submitted the same patch with "suggested-by"
> associated with Zhou @ umn.edu?  I want to give credit where credit is
> due while still maintaining the rule that patches are not actually
> being accepted by umn.edu.

If you think this really is needed, then yes, feel free to rewrite it.

But rewrite it to be correct.  As it is, this is not correct.  If an
error happens because we are out of memory, actually handle that and do
not just return as if everything worked properly like this patch is
doing here.

The "suggestion" here is incorrect, which is the big problem here.
Whatever tool this group is using is wrong, and as a few people have
hinted to me offline, maybe they are just still messing around with us
and seeing how we behave.  Personally, I'm starting to get mad.

thanks,

greg k-h


From chunkuang.hu at kernel.org  Fri Jan 28 07:57:30 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Fri, 28 Jan 2022 23:57:30 +0800
Subject: [PATCH v3] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
In-Reply-To: <ddb05e08-f81a-11f9-8091-9af0c57e687d@collabora.com>
References: <20220127143623.123025-1-angelogioacchino.delregno@collabora.com>
 <CAAOTY__yO6Cq8qt8RSh9AX68mJEv+wWvuhY0_p-PTJ=eJD_7aA@mail.gmail.com>
 <b8911eab-1419-60ad-ef07-25a5de365a52@collabora.com>
 <ddb05e08-f81a-11f9-8091-9af0c57e687d@collabora.com>
Message-ID: <CAAOTY_8ZPmUEizdVEOWb26FV+3qpndk=t1N2vYyFCd4K2RM0Nw@mail.gmail.com>

AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
2022?1?28? ?? ??5:13???
>
> Il 27/01/22 16:46, AngeloGioacchino Del Regno ha scritto:
> > Il 27/01/22 16:21, Chun-Kuang Hu ha scritto:
> >> Hi, Angelo:
> >>
> >> AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com> ?
> >> 2022?1?27? ?? ??10:36???
> >>>
> >>> DRM bridge drivers are now attaching their DSI device at probe time,
> >>> which requires us to register our DSI host in order to let the bridge
> >>> to probe: this recently started producing an endless -EPROBE_DEFER
> >>> loop on some machines that are using external bridges, like the
> >>> parade-ps8640, found on the ACER Chromebook R13.
> >>>
> >>> Now that the DSI hosts/devices probe sequence is documented, we can
> >>> do adjustments to the mtk_dsi driver as to both fix now and make sure
> >>> to avoid this situation in the future: for this, following what is
> >>> documented in drm_bridge.c, move the mtk_dsi component_add() to the
> >>> mtk_dsi_ops.attach callback and delete it in the detach callback;
> >>> keeping in mind that we are registering a drm_bridge for our DSI,
> >>> which is only used/attached if the DSI Host is bound, it wouldn't
> >>> make sense to keep adding our bridge at probe time (as it would
> >>> be useless to have it if mtk_dsi_ops.attach() fails!), so also move
> >>> that one to the dsi host attach function (and remove it in detach).
> >>>
> >>> Fixes: 209264a85707 ("drm/bridge: Document the probe issue with MIPI-DSI bridges")
> >>
> >> The fixed tag should indicate the patch which cause the bug, but why a
> >> patch just adding document would cause bug?
> >> So no any patch cause bug? This patch just want to prevent a possible bug?
> >>
> >
> > I think you've missed my previous message on v2, so I will paste it here:
> >
> > unfortunately I couldn't find a valid commit for a Fixes tag. This
> > started being an issue at some point, when the DRM was changed to
> > adhere to the documented probe sequence: the MediaTek DSI driver was
> > not the only one that got broken/affected by these changes.
> >
> > If you have any advice on which commit should be tagged, I'm open for
> > any kind of suggestion.
> >
> >
> > I tried to check on other drivers which got fixed for the same behavior,
> > for example drm/msm, but none of them had a Fixes tag.
> > When the DRM got changed to adhere to this sequence, some drm/bridge
> > drivers were also changed; this has created some incompatibilities with
> > some drm drivers, including drm/msm and drm/mediatek.
> >
> > This commit is not fixing a latent bug that was introduced in drm/mediatek
> > but rather one that was induced by the new, fixed, probe flow that got
> > recently documented - and to which drivers should adhere; failing to adhere
> > to that will produce an endless -EPROBE_DEFER loop, due to other drivers
> > (as mentioned, for example drm/bridge drivers) having been changed to use
> > that probe sequence.
> >
> >
> > Regards,
> > Angelo
> >
>
> I've been thinking about another solution to this issue.
>
> Would it be fine if I send a v4 that removes the Fixes tag, but adds the following?
>
> Cc: stable at kernel.org # v5.15+

It's ok to me. According to the documented format [1], I think this should be

Cc: <stable at vger.kernel.org> # 5.15.x

[1] https://www.kernel.org/doc/html/v5.16/process/stable-kernel-rules.html

Regards,
Chun-Kuang.

>
> >> Regards,
> >> Chun-Kuang.
> >>
> >>> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> >>> Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
> >>> Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>
> >>>
> >>> ---
> >>>   drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
> >>>   1 file changed, 84 insertions(+), 83 deletions(-)
> >>>
>
>
> --
> AngeloGioacchino Del Regno
> Software Engineer
>
> Collabora Ltd.
> Platinum Building, St John's Innovation Park, Cambridge CB4 0DS, UK
> Registered in England & Wales, no. 5513718


From broonie at kernel.org  Fri Jan 28 07:59:03 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 15:59:03 +0000
Subject: [PATCH] spi: uniphier: fix reference count leak in
 uniphier_spi_probe()
In-Reply-To: <20220125101214.35677-1-xiongx18@fudan.edu.cn>
References: <20220125101214.35677-1-xiongx18@fudan.edu.cn>
Message-ID: <164338554302.1711475.9019138910301906036.b4-ty@kernel.org>

On Tue, 25 Jan 2022 18:12:15 +0800, Xin Xiong wrote:
> The issue happens in several error paths in uniphier_spi_probe().
> When either dma_get_slave_caps() or devm_spi_register_master() returns
> an error code, the function forgets to decrease the refcount of both
> `dma_rx` and `dma_tx` objects, which may lead to refcount leaks.
> 
> Fix it by decrementing the reference count of specific objects in
> those error paths.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-linus

Thanks!

[1/1] spi: uniphier: fix reference count leak in uniphier_spi_probe()
      commit: 37c2c83ca4f1ef4b6908181ac98e18360af89b42

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From marcel at ziswiler.com  Fri Jan 28 08:00:49 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:49 +0100
Subject: [PATCH v3 01/12] arm64: dts: imx8mm: fix strange hex notation
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-2-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Fix strange hex notation with mixed lower-case and upper-case letters.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

---

(no changes since v2)

Changes in v2:
- Add Laurent's reviewed-by tag.

 arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
index a003e6af3353..c68a5e456025 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
+++ b/arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
@@ -279,7 +279,7 @@
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_DATA4                                0x150 0x3B8 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI1_TX_SYNC                                 0x150 0x3B8 0x4CC 0x2 0x1
 #define MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK                                 0x150 0x3B8 0x4E8 0x3 0x0
-#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53c 0x4 0x0
+#define MX8MM_IOMUXC_SAI5_RXD2_PDM_DATA2                                    0x150 0x3B8 0x53C 0x4 0x0
 #define MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23                                   0x150 0x3B8 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI5_RX_DATA3                                0x154 0x3BC 0x4E0 0x0 0x0
 #define MX8MM_IOMUXC_SAI5_RXD3_SAI1_TX_DATA5                                0x154 0x3BC 0x000 0x1 0x0
@@ -486,7 +486,7 @@
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                0x1D8 0x440 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
-#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4Fc 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4FC 0x4 0x2
 #define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                 0x1D8 0x440 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
@@ -494,7 +494,7 @@
 #define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
 #define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX                                  0x1DC 0x444 0x000 0x4 0x0
-#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4Fc 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4FC 0x4 0x3
 #define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:50 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:50 +0100
Subject: [PATCH v3 02/12] arm64: defconfig: enable taskstats configuration
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-3-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_TASKSTATS which is required for CONFIG_TASK_XACCT (and
subsequently CONFIG_TASK_IO_ACCOUNTING). Previously, taskstats got
pulled in by KVM but that got changed in commit 63b3f96e1a98
("kvm: Select SCHED_INFO instead of TASK_DELAY_ACCT").

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Add Krzysztof's reviewed-by tag.

Changes in v2:
- New patch following full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 30516dc0b70e..b057b08c0fc2 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -7,6 +7,7 @@ CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
 CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_IKCONFIG=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:51 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:51 +0100
Subject: [PATCH v3 03/12] arm64: defconfig: enable pcieaer configuration
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-4-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable CONFIG_PCIEAER which is required for CONFIG_ACPI_APEI_PCIEAER.
Commit 8c8ff55b4da7 ("PCI/AER: Don't select CONFIG_PCIEAER by default")
changed it to no longer being enabled by default.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Add Krzysztof's reviewed-by tag.

Changes in v2:
- New patch following full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index b057b08c0fc2..c37dace3e89d 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -211,6 +211,7 @@ CONFIG_NFC_NCI=m
 CONFIG_NFC_S3FWRN5_I2C=m
 CONFIG_PCI=y
 CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
 CONFIG_PCI_IOV=y
 CONFIG_PCI_PASID=y
 CONFIG_HOTPLUG_PCI=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:53 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:53 +0100
Subject: [PATCH v3 05/12] arm64: defconfig: rebuild default configuration
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-6-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Run "make defconfig; make savedefconfig" to rebuild defconfig.

This dropped the following configuration options which are nowaday's
already enabled (resp. disabled) by default:

CONFIG_MEMCG_SWAP=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
# CONFIG_BT_HS is not set
CONFIG_FSL_MC_BUS=y
CONFIG_QCOM_SCM=y
CONFIG_MFD_CROS_EC_DEV=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_DRM_DISPLAY_CONNECTOR=m
CONFIG_SND_SOC_FSL_SAI=m
CONFIG_USB_CONN_GPIO=m
CONFIG_USB_XHCI_PCI=m
CONFIG_SDM_GCC_845=y
CONFIG_SM_DISPCC_8250=y
CONFIG_SM_GCC_8150=y
CONFIG_SM_GCC_8250=y
CONFIG_COMMON_CLK_ZYNQMP=y

CONFIG_POWER_AVS was renamed to POWER_AVS_OMAP in commit bca815d62054
("PM: AVS: smartreflex Move driver to soc specific drivers"). As there
are no 64-bit Arm OMAPs it getting dropped seems fair.

Note that the following user-selectable configuration options have been
preserved:

CONFIG_SECCOMP=y
CONFIG_SLIMBUS=m
CONFIG_INTERCONNECT=y
CONFIG_CONFIGFS_FS=y

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v3:
- Not dropping CONFIG_SECCOMP=y, CONFIG_SLIMBUS=m, CONFIG_INTERCONNECT=y
  and CONFIG_CONFIGFS_FS=y as requested by Krzysztof.

Changes in v2:
- Done full defconfig analysis as requested by Krzysztof.

 arch/arm64/configs/defconfig | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 25a4eff126d4..530ad076b5cb 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -15,7 +15,6 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_NUMA_BALANCING=y
 CONFIG_MEMCG=y
-CONFIG_MEMCG_SWAP=y
 CONFIG_BLK_CGROUP=y
 CONFIG_CGROUP_PIDS=y
 CONFIG_CGROUP_HUGETLB=y
@@ -85,7 +84,6 @@ CONFIG_CPU_FREQ_GOV_POWERSAVE=m
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
 CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
-CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m
@@ -181,7 +179,6 @@ CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
-# CONFIG_BT_HS is not set
 # CONFIG_BT_LE is not set
 CONFIG_BT_LEDS=y
 # CONFIG_BT_DEBUGFS is not set
@@ -237,13 +234,11 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_HISILICON_LPC=y
 CONFIG_TEGRA_ACONNECT=m
-CONFIG_FSL_MC_BUS=y
 CONFIG_ARM_SCMI_PROTOCOL=y
 CONFIG_ARM_SCPI_PROTOCOL=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
 CONFIG_INTEL_STRATIX10_SERVICE=y
 CONFIG_INTEL_STRATIX10_RSU=m
-CONFIG_QCOM_SCM=y
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
 CONFIG_IMX_SCU_PD=y
@@ -545,7 +540,6 @@ CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
-CONFIG_POWER_AVS=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_QCOM_PON=m
 CONFIG_POWER_RESET_XGENE=y
@@ -606,7 +600,6 @@ CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_I2C=y
 CONFIG_MFD_AXP20X_RSB=y
-CONFIG_MFD_CROS_EC_DEV=y
 CONFIG_MFD_EXYNOS_LPASS=m
 CONFIG_MFD_HI6421_PMIC=y
 CONFIG_MFD_HI655X_PMIC=y
@@ -653,8 +646,6 @@ CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 CONFIG_MEDIA_SDR_SUPPORT=y
 CONFIG_MEDIA_PLATFORM_SUPPORT=y
-CONFIG_MEDIA_CONTROLLER=y
-CONFIG_VIDEO_V4L2_SUBDEV_API=y
 # CONFIG_DVB_NET is not set
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
@@ -710,7 +701,6 @@ CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
-CONFIG_DRM_DISPLAY_CONNECTOR=m
 CONFIG_DRM_LONTIUM_LT8912B=m
 CONFIG_DRM_LONTIUM_LT9611=m
 CONFIG_DRM_LONTIUM_LT9611UXC=m
@@ -751,7 +741,6 @@ CONFIG_SND_HDA_CODEC_HDMI=m
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
 CONFIG_SND_SOC_FSL_ASRC=m
-CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_FSL_MICFIL=m
 CONFIG_SND_SOC_FSL_EASRC=m
 CONFIG_SND_IMX_SOC=m
@@ -812,11 +801,9 @@ CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_HID_MULTITOUCH=m
 CONFIG_I2C_HID_ACPI=m
 CONFIG_I2C_HID_OF=m
-CONFIG_USB_CONN_GPIO=m
 CONFIG_USB=y
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PCI=m
 CONFIG_USB_XHCI_PCI_RENESAS=m
 CONFIG_USB_XHCI_TEGRA=y
 CONFIG_USB_EHCI_HCD=y
@@ -1004,20 +991,15 @@ CONFIG_QCS_GCC_404=y
 CONFIG_SC_GCC_7180=y
 CONFIG_SC_GCC_7280=y
 CONFIG_SDM_CAMCC_845=m
-CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_VIDEOCC_845=y
 CONFIG_SDM_DISPCC_845=y
-CONFIG_SM_DISPCC_8250=y
-CONFIG_SM_GCC_8150=y
-CONFIG_SM_GCC_8250=y
 CONFIG_SM_GCC_8350=y
 CONFIG_SM_GPUCC_8150=y
 CONFIG_SM_GPUCC_8250=y
 CONFIG_QCOM_HFPLL=y
 CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
-CONFIG_COMMON_CLK_ZYNQMP=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_ARM_MHU=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:52 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:52 +0100
Subject: [PATCH v3 04/12] arm64: defconfig: re-order default configuration
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-5-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Use "make defconfig", "make savedefconfig" and friends to just assess
re-ordering of configuration items in defconfig.

This re-ordered the following configuration options:

CONFIG_BPF_JIT=y
CONFIG_SECCOMP=y
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_INTEL_STRATIX10_SERVICE=y
CONFIG_INTEL_STRATIX10_RSU=m
CONFIG_QCOM_SCM=y
CONFIG_EFI_CAPSULE_LOADER=y
CONFIG_IMX_SCU=y
CONFIG_IMX_SCU_PD=y
CONFIG_CAN_FLEXCAN=m
CONFIG_PCIE_LAYERSCAPE_GEN4=y
CONFIG_FSL_MC_BUS=y
CONFIG_MTK_DEVAPC=m
CONFIG_SPI_CADENCE_QUADSPI=y
CONFIG_MDIO_BUS_MUX_MMIOREG=y
CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
CONFIG_MESON_GXL_PHY=m
CONFIG_PINCTRL_SINGLE=y
CONFIG_QCOM_CPR=y
CONFIG_ROCKCHIP_IODOMAIN=y
CONFIG_SENSORS_ARM_SCMI=y
CONFIG_QORIQ_THERMAL=m
CONFIG_SUN8I_THERMAL=y
CONFIG_TEGRA_BPMP_THERMAL=m
CONFIG_ARM_SMC_WATCHDOG=y
CONFIG_MFD_CROS_EC_DEV=y
CONFIG_MEDIA_PLATFORM_SUPPORT=y
CONFIG_VIDEO_QCOM_CAMSS=m
CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
CONFIG_DRM_NWL_MIPI_DSI=m
CONFIG_DRM_LONTIUM_LT9611UXC=m
CONFIG_SND_SOC_FSL_SAI=m
CONFIG_SND_SOC_IMX_AUDMIX=m
CONFIG_TYPEC_HD3SS3220=m
CONFIG_COMMON_CLK_SCMI=y
CONFIG_COMMON_CLK_ZYNQMP=y
CONFIG_IPQ_GCC_8074=y
CONFIG_SM_DISPCC_8250=y
CONFIG_QCOM_WCNSS_CTRL=m
CONFIG_ARCH_R8A774A1=y
CONFIG_ARCH_R8A774B1=y
CONFIG_ARCH_R8A774C0=y
CONFIG_ARCH_R8A774E1=y
CONFIG_ARCH_R8A77995=y
CONFIG_ARCH_R8A77990=y
CONFIG_ARCH_R8A77965=y
CONFIG_ARCH_R8A77970=y
CONFIG_ARCH_R8A779F0=y
CONFIG_HISI_PMU=y
CONFIG_QCOM_QFPROM=y
CONFIG_MUX_MMIO=y

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v3:
- New separate patch only for re-ordering as suggested by Krzysztof.

 arch/arm64/configs/defconfig | 106 +++++++++++++++++------------------
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index c37dace3e89d..25a4eff126d4 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_JIT=y
 CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
 CONFIG_BSD_PROCESS_ACCT=y
@@ -67,7 +68,6 @@ CONFIG_ARM64_VA_BITS_48=y
 CONFIG_SCHED_MC=y
 CONFIG_SCHED_SMT=y
 CONFIG_NUMA=y
-CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_KEXEC_FILE=y
 CONFIG_CRASH_DUMP=y
@@ -98,15 +98,6 @@ CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
 CONFIG_ARM_SCMI_CPUFREQ=y
 CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_QORIQ_CPUFREQ=y
-CONFIG_ARM_SCMI_PROTOCOL=y
-CONFIG_ARM_SCPI_PROTOCOL=y
-CONFIG_RASPBERRYPI_FIRMWARE=y
-CONFIG_INTEL_STRATIX10_SERVICE=y
-CONFIG_INTEL_STRATIX10_RSU=m
-CONFIG_QCOM_SCM=y
-CONFIG_EFI_CAPSULE_LOADER=y
-CONFIG_IMX_SCU=y
-CONFIG_IMX_SCU_PD=y
 CONFIG_ACPI=y
 CONFIG_ACPI_APEI=y
 CONFIG_ACPI_APEI_GHES=y
@@ -128,6 +119,7 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 CONFIG_CRYPTO_CHACHA20_NEON=m
 CONFIG_CRYPTO_AES_ARM64_BS=m
 CONFIG_JUMP_LABEL=y
+CONFIG_SECCOMP=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
@@ -183,11 +175,10 @@ CONFIG_NET_ACT_GATE=m
 CONFIG_QRTR=m
 CONFIG_QRTR_SMD=m
 CONFIG_QRTR_TUN=m
-CONFIG_BPF_JIT=y
 CONFIG_CAN=m
+CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
-CONFIG_CAN_FLEXCAN=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
 # CONFIG_BT_HS is not set
@@ -230,7 +221,6 @@ CONFIG_PCIE_ROCKCHIP_HOST=m
 CONFIG_PCIE_BRCMSTB=m
 CONFIG_PCI_IMX6=y
 CONFIG_PCI_LAYERSCAPE=y
-CONFIG_PCIE_LAYERSCAPE_GEN4=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
 CONFIG_PCIE_ARMADA_8K=y
@@ -238,6 +228,7 @@ CONFIG_PCIE_KIRIN=y
 CONFIG_PCIE_HISI_STB=y
 CONFIG_PCIE_TEGRA194_HOST=m
 CONFIG_PCIE_VISCONTI_HOST=y
+CONFIG_PCIE_LAYERSCAPE_GEN4=y
 CONFIG_PCI_ENDPOINT=y
 CONFIG_PCI_ENDPOINT_CONFIGFS=y
 CONFIG_PCI_EPF_TEST=m
@@ -245,8 +236,17 @@ CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_FW_LOADER_USER_HELPER=y
 CONFIG_HISILICON_LPC=y
-CONFIG_FSL_MC_BUS=y
 CONFIG_TEGRA_ACONNECT=m
+CONFIG_FSL_MC_BUS=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_RASPBERRYPI_FIRMWARE=y
+CONFIG_INTEL_STRATIX10_SERVICE=y
+CONFIG_INTEL_STRATIX10_RSU=m
+CONFIG_QCOM_SCM=y
+CONFIG_EFI_CAPSULE_LOADER=y
+CONFIG_IMX_SCU=y
+CONFIG_IMX_SCU_PD=y
 CONFIG_GNSS=m
 CONFIG_GNSS_MTK_SERIAL=m
 CONFIG_MTD=y
@@ -266,8 +266,6 @@ CONFIG_MTD_NAND_MARVELL=y
 CONFIG_MTD_NAND_FSL_IFC=y
 CONFIG_MTD_NAND_QCOM=y
 CONFIG_MTD_SPI_NOR=y
-CONFIG_MTK_DEVAPC=m
-CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_VIRTIO_BLK=y
@@ -353,13 +351,11 @@ CONFIG_SNI_NETSEC=y
 CONFIG_STMMAC_ETH=m
 CONFIG_TI_K3_AM65_CPSW_NUSS=y
 CONFIG_QCOM_IPA=m
-CONFIG_MDIO_BUS_MUX_MMIOREG=y
-CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MESON_GXL_PHY=m
 CONFIG_AQUANTIA_PHY=y
 CONFIG_BCM54140_PHY=m
 CONFIG_MARVELL_PHY=m
 CONFIG_MARVELL_10G_PHY=m
-CONFIG_MESON_GXL_PHY=m
 CONFIG_MICREL_PHY=y
 CONFIG_MICROSEMI_PHY=y
 CONFIG_AT803X_PHY=y
@@ -367,6 +363,8 @@ CONFIG_REALTEK_PHY=y
 CONFIG_ROCKCHIP_PHY=y
 CONFIG_DP83867_PHY=y
 CONFIG_VITESSE_PHY=y
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
+CONFIG_MDIO_BUS_MUX_MMIOREG=y
 CONFIG_USB_PEGASUS=m
 CONFIG_USB_RTL8150=m
 CONFIG_USB_RTL8152=m
@@ -475,6 +473,7 @@ CONFIG_SPI=y
 CONFIG_SPI_ARMADA_3700=y
 CONFIG_SPI_BCM2835=m
 CONFIG_SPI_BCM2835AUX=m
+CONFIG_SPI_CADENCE_QUADSPI=y
 CONFIG_SPI_DESIGNWARE=m
 CONFIG_SPI_DW_DMA=y
 CONFIG_SPI_DW_MMIO=m
@@ -497,8 +496,8 @@ CONFIG_SPI_SH_MSIOF=m
 CONFIG_SPI_SUN6I=y
 CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
-CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_OWL=y
 CONFIG_PINCTRL_S700=y
 CONFIG_PINCTRL_S900=y
@@ -547,8 +546,6 @@ CONFIG_GPIO_BD9571MWV=m
 CONFIG_GPIO_MAX77620=y
 CONFIG_GPIO_SL28CPLD=m
 CONFIG_POWER_AVS=y
-CONFIG_QCOM_CPR=y
-CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_QCOM_PON=m
 CONFIG_POWER_RESET_XGENE=y
@@ -556,10 +553,10 @@ CONFIG_POWER_RESET_SYSCON=y
 CONFIG_SYSCON_REBOOT_MODE=y
 CONFIG_BATTERY_SBS=m
 CONFIG_BATTERY_BQ27XXX=y
-CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_BATTERY_MAX17042=m
 CONFIG_CHARGER_BQ25890=m
 CONFIG_CHARGER_BQ25980=m
+CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
 CONFIG_SENSORS_LM90=m
@@ -571,10 +568,10 @@ CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
-CONFIG_QORIQ_THERMAL=m
-CONFIG_SUN8I_THERMAL=y
 CONFIG_IMX_SC_THERMAL=m
 CONFIG_IMX8MM_THERMAL=m
+CONFIG_QORIQ_THERMAL=m
+CONFIG_SUN8I_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=m
 CONFIG_RCAR_THERMAL=y
 CONFIG_RCAR_GEN3_THERMAL=y
@@ -583,8 +580,8 @@ CONFIG_BCM2711_THERMAL=m
 CONFIG_BCM2835_THERMAL=m
 CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
-CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_TEGRA_SOCTHERM=m
+CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_QCOM_TSENS=y
 CONFIG_QCOM_SPMI_TEMP_ALARM=m
 CONFIG_QCOM_LMH=m
@@ -593,7 +590,6 @@ CONFIG_WATCHDOG=y
 CONFIG_SL28CPLD_WATCHDOG=m
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_ARM_SBSA_WATCHDOG=y
-CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
 CONFIG_DW_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=m
@@ -602,6 +598,7 @@ CONFIG_IMX_SC_WDT=m
 CONFIG_QCOM_WDT=m
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
+CONFIG_ARM_SMC_WATCHDOG=y
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
@@ -609,6 +606,7 @@ CONFIG_MFD_ALTERA_SYSMGR=y
 CONFIG_MFD_BD9571MWV=y
 CONFIG_MFD_AXP20X_I2C=y
 CONFIG_MFD_AXP20X_RSB=y
+CONFIG_MFD_CROS_EC_DEV=y
 CONFIG_MFD_EXYNOS_LPASS=m
 CONFIG_MFD_HI6421_PMIC=y
 CONFIG_MFD_HI655X_PMIC=y
@@ -654,13 +652,14 @@ CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
 CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
 CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
 CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
-CONFIG_MEDIA_PLATFORM_SUPPORT=y
 # CONFIG_DVB_NET is not set
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_VIDEO_RCAR_CSI2=m
 CONFIG_VIDEO_RCAR_VIN=m
 CONFIG_VIDEO_SUN6I_CSI=m
@@ -677,7 +676,6 @@ CONFIG_VIDEO_RCAR_DRIF=m
 CONFIG_VIDEO_IMX219=m
 CONFIG_VIDEO_OV5640=m
 CONFIG_VIDEO_OV5645=m
-CONFIG_VIDEO_QCOM_CAMSS=m
 CONFIG_DRM=m
 CONFIG_DRM_I2C_NXP_TDA998X=m
 CONFIG_DRM_MALI_DISPLAY=m
@@ -704,24 +702,24 @@ CONFIG_DRM_SUN8I_DW_HDMI=m
 CONFIG_DRM_SUN8I_MIXER=m
 CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
+CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_LVDS=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_PANEL_EDP=m
-CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
 CONFIG_DRM_DISPLAY_CONNECTOR=m
 CONFIG_DRM_LONTIUM_LT8912B=m
-CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_LONTIUM_LT9611=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_NWL_MIPI_DSI=m
 CONFIG_DRM_PARADE_PS8640=m
 CONFIG_DRM_SII902X=m
 CONFIG_DRM_SIMPLE_BRIDGE=m
 CONFIG_DRM_THINE_THC63LVD1024=m
 CONFIG_DRM_TI_SN65DSI86=m
-CONFIG_DRM_LONTIUM_LT9611UXC=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@@ -752,15 +750,15 @@ CONFIG_SND_HDA_TEGRA=m
 CONFIG_SND_HDA_CODEC_HDMI=m
 CONFIG_SND_SOC=y
 CONFIG_SND_BCM2835_SOC_I2S=m
-CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_FSL_ASRC=m
+CONFIG_SND_SOC_FSL_SAI=m
 CONFIG_SND_SOC_FSL_MICFIL=m
 CONFIG_SND_SOC_FSL_EASRC=m
 CONFIG_SND_IMX_SOC=m
 CONFIG_SND_SOC_IMX_SGTL5000=m
 CONFIG_SND_SOC_IMX_SPDIF=m
-CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_SOC_FSL_ASOC_CARD=m
+CONFIG_SND_SOC_IMX_AUDMIX=m
 CONFIG_SND_MESON_AXG_SOUND_CARD=m
 CONFIG_SND_MESON_GX_SOUND_CARD=m
 CONFIG_SND_SOC_QCOM=m
@@ -865,8 +863,8 @@ CONFIG_TYPEC=m
 CONFIG_TYPEC_TCPM=m
 CONFIG_TYPEC_TCPCI=m
 CONFIG_TYPEC_FUSB302=m
-CONFIG_TYPEC_HD3SS3220=m
 CONFIG_TYPEC_TPS6598X=m
+CONFIG_TYPEC_HD3SS3220=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
 CONFIG_MMC_ARMMMCI=y
@@ -964,7 +962,6 @@ CONFIG_VIRTIO_BALLOON=y
 CONFIG_VIRTIO_MMIO=y
 CONFIG_XEN_GNTDEV=y
 CONFIG_XEN_GRANT_DEV_ALLOC=y
-CONFIG_MFD_CROS_EC_DEV=y
 CONFIG_STAGING=y
 CONFIG_STAGING_MEDIA=y
 CONFIG_VIDEO_HANTRO=m
@@ -974,15 +971,14 @@ CONFIG_CROS_EC=y
 CONFIG_CROS_EC_I2C=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_CHARDEV=m
-CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_RK808=y
+CONFIG_COMMON_CLK_SCMI=y
 CONFIG_COMMON_CLK_SCPI=y
 CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_FSL_SAI=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_COMMON_CLK_PWM=y
 CONFIG_COMMON_CLK_VC5=y
-CONFIG_COMMON_CLK_ZYNQMP=y
 CONFIG_COMMON_CLK_BD718XX=m
 CONFIG_CLK_RASPBERRYPI=m
 CONFIG_CLK_IMX8MM=y
@@ -998,8 +994,8 @@ CONFIG_QCOM_CLK_APCS_MSM8916=y
 CONFIG_QCOM_CLK_APCC_MSM8996=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
-CONFIG_IPQ_GCC_8074=y
 CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
 CONFIG_MSM_GCC_8916=y
 CONFIG_MSM_GCC_8994=y
 CONFIG_MSM_MMCC_8996=y
@@ -1012,15 +1008,16 @@ CONFIG_SDM_GCC_845=y
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_VIDEOCC_845=y
 CONFIG_SDM_DISPCC_845=y
+CONFIG_SM_DISPCC_8250=y
 CONFIG_SM_GCC_8150=y
 CONFIG_SM_GCC_8250=y
 CONFIG_SM_GCC_8350=y
 CONFIG_SM_GPUCC_8150=y
 CONFIG_SM_GPUCC_8250=y
-CONFIG_SM_DISPCC_8250=y
 CONFIG_QCOM_HFPLL=y
 CONFIG_CLK_GFM_LPASS_SM8250=m
 CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y
+CONFIG_COMMON_CLK_ZYNQMP=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_ARM_MHU=y
@@ -1051,9 +1048,11 @@ CONFIG_RASPBERRYPI_POWER=y
 CONFIG_FSL_DPAA=y
 CONFIG_FSL_MC_DPIO=y
 CONFIG_FSL_RCPM=y
+CONFIG_MTK_DEVAPC=m
 CONFIG_MTK_PMIC_WRAP=y
 CONFIG_QCOM_AOSS_QMP=y
 CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_RMTFS_MEM=m
 CONFIG_QCOM_RPMH=y
@@ -1064,25 +1063,26 @@ CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
 CONFIG_QCOM_SMSM=y
 CONFIG_QCOM_SOCINFO=m
-CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
 CONFIG_QCOM_APR=m
-CONFIG_ARCH_R8A774A1=y
-CONFIG_ARCH_R8A774B1=y
-CONFIG_ARCH_R8A774C0=y
-CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77990=y
 CONFIG_ARCH_R8A77950=y
 CONFIG_ARCH_R8A77951=y
+CONFIG_ARCH_R8A77965=y
 CONFIG_ARCH_R8A77960=y
 CONFIG_ARCH_R8A77961=y
-CONFIG_ARCH_R8A77965=y
-CONFIG_ARCH_R8A77970=y
+CONFIG_ARCH_R8A779F0=y
 CONFIG_ARCH_R8A77980=y
-CONFIG_ARCH_R8A77990=y
-CONFIG_ARCH_R8A77995=y
+CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A779A0=y
-CONFIG_ARCH_R8A779F0=y
+CONFIG_ARCH_R8A774C0=y
+CONFIG_ARCH_R8A774E1=y
+CONFIG_ARCH_R8A774A1=y
+CONFIG_ARCH_R8A774B1=y
 CONFIG_ARCH_R9A07G044=y
+CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
@@ -1161,13 +1161,13 @@ CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
 CONFIG_ARM_SMMU_V3_PMU=m
 CONFIG_FSL_IMX8_DDR_PMU=m
-CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
+CONFIG_HISI_PMU=y
 CONFIG_NVMEM_IMX_OCOTP=y
 CONFIG_NVMEM_IMX_OCOTP_SCU=y
-CONFIG_QCOM_QFPROM=y
 CONFIG_MTK_EFUSE=y
+CONFIG_QCOM_QFPROM=y
 CONFIG_ROCKCHIP_EFUSE=y
 CONFIG_NVMEM_SUNXI_SID=y
 CONFIG_UNIPHIER_EFUSE=y
@@ -1181,10 +1181,10 @@ CONFIG_FPGA_REGION=m
 CONFIG_OF_FPGA_REGION=m
 CONFIG_TEE=y
 CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=y
 CONFIG_SLIMBUS=m
 CONFIG_SLIM_QCOM_CTRL=m
 CONFIG_SLIM_QCOM_NGD_CTRL=m
-CONFIG_MUX_MMIO=y
 CONFIG_INTERCONNECT=y
 CONFIG_INTERCONNECT_IMX=m
 CONFIG_INTERCONNECT_IMX8MM=m
-- 
2.33.1



From mark.rutland at arm.com  Fri Jan 28 08:01:41 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 16:01:41 +0000
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfP0osb45uJldtM9@localhost.localdomain>
References: <YfP0osb45uJldtM9@localhost.localdomain>
Message-ID: <YfQTZTUNaeGi+8tG@FVFF77S0Q05N>

On Fri, Jan 28, 2022 at 02:50:26PM +0100, Krzysztof Adamski wrote:
> On EFI enabled arm64 systems, efi_reboot was called before
> do_kernel_restart, completely omitting the reset_handlers functionality.

As I pointed out before, per the EFI spec we *need* to do this before any other
restart mechanism so that anything which EFI ties to the restart actually
occurs as expected -- e.g. UpdateCapsule(), as the comment says.
AFAICT, either:

* The other restart handlers have lower priority, in which case they'll be
  called after this anyway, and in such cases this patch is not necessary.

* At least one other restart handler has higher priority, and the EFI restart
  isn't actually used, and so any functionaltiy tied to the EFI restart will
  not work on that machine.

> By registering efi_reboot as part of the chain with slightly elevated
> priority, we make it run before the default handler but still allow
> plugging in other handlers.
> Thanks to that, things like gpio_restart, restart handlers in
> watchdog_core, mmc or mtds are working on those platforms.

On which platforms is it necessary that these are used in preference to the EFI
restart? Can you please give a specific example?

If there's a specific platform that needs this, then we should call that out
and explain why the EFI restart isn't actually required on that (or if it is,
and functionality is broken, why that's acceptable).

Otherwise this patch is making this logic more complicated *and* making it
possible to have problems which we avoid by construction today, without any
actual benefit.

Thanks,
Mark.

> The priority 130 is one higher than PSCI, to overrule that but still
> allow to easily register higher prio handlers, if needed.
> 
> Signed-off-by: Krzysztof Adamski <krzysztof.adamski at nokia.com>
> ---
> 
> Changes in v2:
>   - Register the handler in EFI code, instead of arm64 setup.c
>   - Remove the contdition from the handler - it should be run in all
>     cases when it is registered
>   - Bump the priority to 130 to make it completly obious this should be
>     run before PSCI (which has priority of 129)
> 
>  arch/arm64/kernel/process.c        |  7 -------
>  drivers/firmware/efi/arm-runtime.c | 21 +++++++++++++++++++++
>  2 files changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..b86ef77bb0c8 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -130,13 +130,6 @@ void machine_restart(char *cmd)
>  	local_irq_disable();
>  	smp_send_stop();
>  
> -	/*
> -	 * UpdateCapsule() depends on the system being reset via
> -	 * ResetSystem().
> -	 */
> -	if (efi_enabled(EFI_RUNTIME_SERVICES))
> -		efi_reboot(reboot_mode, NULL);
> -
>  	/* Now call the architecture specific reboot code. */
>  	do_kernel_restart(cmd);
>  
> diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
> index 3359ae2adf24..b9a2cdbe80b4 100644
> --- a/drivers/firmware/efi/arm-runtime.c
> +++ b/drivers/firmware/efi/arm-runtime.c
> @@ -80,6 +80,24 @@ static bool __init efi_virtmap_init(void)
>  	return true;
>  }
>  
> +static int efi_restart(struct notifier_block *nb, unsigned long action,
> +		       void *data)
> +{
> +	/*
> +	 * UpdateCapsule() depends on the system being reset via
> +	 * ResetSystem().
> +	 */
> +	efi_reboot(reboot_mode, NULL);
> +
> +	return NOTIFY_DONE;
> +}
> +
> +static struct notifier_block efi_restart_nb = {
> +	.notifier_call = efi_restart,
> +	/* We want this to take priority over PSCI which has priority of 129. */
> +	.priority = 130,
> +};
> +
>  /*
>   * Enable the UEFI Runtime Services if all prerequisites are in place, i.e.,
>   * non-early mapping of the UEFI system table and virtual mappings for all
> @@ -148,6 +166,9 @@ static int __init arm_enable_runtime_services(void)
>  	efi_native_runtime_setup();
>  	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
>  
> +	if (IS_ENABLED(CONFIG_ARM64))
> +		register_restart_handler(&efi_restart_nb);
> +
>  	return 0;
>  }
>  early_initcall(arm_enable_runtime_services);
> -- 
> 2.34.1
> 


From marcel at ziswiler.com  Fri Jan 28 08:00:55 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:55 +0100
Subject: [PATCH v3 07/12] arm64: defconfig: enable imx8m pcie phy driver
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-8-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This enables the i.MX 8M PCIe PHY driver (CONFIG_PHY_FSL_IMX8M_PCIE)
required for PCIe functionality.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

Changes in v3:
- New patch enabling imx8m pcie phy driver in arm64 defconfig.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 444fec9ec73a..0fed8477e72e 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -1121,6 +1121,7 @@ CONFIG_RESET_TI_SCI=y
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_SUN4I_USB=y
 CONFIG_PHY_MIXEL_MIPI_DPHY=m
+CONFIG_PHY_FSL_IMX8M_PCIE=y
 CONFIG_PHY_HI6220_USB=y
 CONFIG_PHY_HISTB_COMBPHY=y
 CONFIG_PHY_HISI_INNO_USB2=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:57 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:57 +0100
Subject: [PATCH v3 09/12] arm64: defconfig: build r8169 as a module
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-10-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Build Realtek Gigabit Ethernet driver as a module.

Network cards based on chipsets this driver supports are ubiquitous both
in regular PCIe as well as mini-PCIe and nowadays even various M.2
formats. It is therefore a suitable card to be used for any kind of PCIe
and/or Gigabit Ethernet testing. As it is not designed in, just enabling
it as a module seems most suitable.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Add Krzysztof's reviewed-by tag.

Changes in v2:
- Explain why enabling it may be a good idea as requested by Krzysztof.

 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 27afe24a025a..76334cb698af 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -339,6 +339,7 @@ CONFIG_MLX5_CORE=m
 CONFIG_MLX5_CORE_EN=y
 CONFIG_QCOM_EMAC=m
 CONFIG_RMNET=m
+CONFIG_R8169=m
 CONFIG_SH_ETH=y
 CONFIG_RAVB=y
 CONFIG_SMC91X=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:56 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:56 +0100
Subject: [PATCH v3 08/12] arm64: defconfig: build imx-sdma as a module
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-9-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids firmware load error and sysfs fallback reported as follows:

[    0.199448] imx-sdma 302c0000.dma-controller: Direct firmware load
 for imx/sdma/sdma-imx7d.bin failed with error -2
[    0.199487] imx-sdma 302c0000.dma-controller: Falling back to sysfs
 fallback for: imx/sdma/sdma-imx7d.bin

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>

---

(no changes since v2)

Changes in v2:
- A similar change got accepted for imx_v6_v7_defconfig. Further
discussion may be found in [1].
[1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/

 arch/arm64/configs/defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0fed8477e72e..27afe24a025a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -928,7 +928,7 @@ CONFIG_DMADEVICES=y
 CONFIG_DMA_BCM2835=y
 CONFIG_DMA_SUN6I=m
 CONFIG_FSL_EDMA=y
-CONFIG_IMX_SDMA=y
+CONFIG_IMX_SDMA=m
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:58 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:58 +0100
Subject: [PATCH v3 10/12] arm64: defconfig: enable verdin-imx8mm relevant
 drivers as modules
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-11-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Enable various drivers which support peripherals as found on the
Verdin iMX8M Mini et al. computer/system on modules:

- CONFIG_CAN_MCP251XFD
At least one Microchip MCP2518FDT SPI CAN controller which this driver
also supports may be found on the Verdin iMX8M Mini computer/system on
module.

- CONFIG_BT_HCIUART_MRVL, CONFIG_BT_MRVL, CONFIG_BT_MRVL_SDIO and
  CONFIG_MWIFIEX_SDIO
The AzureWave AW-CM276NF which these Bluetooth and Wi-Fi drivers also
support may be found on the Verdin iMX8M Mini (as well as the Apalis
iMX8, Colibri iMX8X and Verdin iMX8M Plus for that matter) computer/
system on module.

- CONFIG_SENSORS_LM75
The TI TMP75C temperature sensor which this driver also supports may be
found on the Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for
that matter) computer/system on module.

- CONFIG_SND_SOC_NAU8822
The Nuvoton Technology Corporation (NTC) NAU88C22YG which this driver
also supports may be found on the Verdin Development Board a carrier
board for the Verdin family of computer/system on module which the
Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
may be mated in.

- CONFIG_TI_ADS1015
The TLA2024 ADC which this driver also supports may be found on the
Verdin iMX8M Mini (as well as the Verdin iMX8M Plus for that matter)
computer/system on module.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Add Krzysztof's reviewed-by tag.

Changes in v2:
- Explain why enabling these may make sense and squash them relevant
  changes as requested by Krzysztof.

 arch/arm64/configs/defconfig | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 76334cb698af..8d2733f8a7d9 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -179,6 +179,7 @@ CONFIG_CAN=m
 CONFIG_CAN_FLEXCAN=m
 CONFIG_CAN_RCAR=m
 CONFIG_CAN_RCAR_CANFD=m
+CONFIG_CAN_MCP251XFD=m
 CONFIG_BT=m
 CONFIG_BT_HIDP=m
 # CONFIG_BT_LE is not set
@@ -189,6 +190,9 @@ CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_LL=y
 CONFIG_BT_HCIUART_BCM=y
 CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_HCIUART_MRVL=y
+CONFIG_BT_MRVL=m
+CONFIG_BT_MRVL_SDIO=m
 CONFIG_BT_QCOMSMD=m
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
@@ -380,6 +384,7 @@ CONFIG_ATH10K_SNOC=m
 CONFIG_WCN36XX=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
 CONFIG_MWIFIEX_PCIE=m
 CONFIG_WL18XX=m
 CONFIG_WLCORE_SDIO=m
@@ -556,6 +561,7 @@ CONFIG_CHARGER_BQ25980=m
 CONFIG_SENSORS_ARM_SCMI=y
 CONFIG_SENSORS_ARM_SCPI=y
 CONFIG_SENSORS_JC42=m
+CONFIG_SENSORS_LM75=m
 CONFIG_SENSORS_LM90=m
 CONFIG_SENSORS_PWM_FAN=m
 CONFIG_SENSORS_RASPBERRYPI_HWMON=m
@@ -797,6 +803,7 @@ CONFIG_SND_SOC_WM8960=m
 CONFIG_SND_SOC_WM8962=m
 CONFIG_SND_SOC_WM8978=m
 CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_NAU8822=m
 CONFIG_SND_SOC_LPASS_WSA_MACRO=m
 CONFIG_SND_SOC_LPASS_VA_MACRO=m
 CONFIG_SND_SIMPLE_CARD=m
@@ -1088,6 +1095,7 @@ CONFIG_QCOM_SPMI_VADC=m
 CONFIG_QCOM_SPMI_ADC5=m
 CONFIG_ROCKCHIP_SARADC=m
 CONFIG_RZG2L_ADC=m
+CONFIG_TI_ADS1015=m
 CONFIG_IIO_CROS_EC_SENSORS_CORE=m
 CONFIG_IIO_CROS_EC_SENSORS=m
 CONFIG_IIO_ST_LSM6DSX=m
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:54 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:54 +0100
Subject: [PATCH v3 06/12] arm64: defconfig: enable bpf/cgroup firewalling
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-7-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This avoids the following systemd warning:

[    2.618538] systemd[1]: system-getty.slice: unit configures an IP
 firewall, but the local system does not support BPF/cgroup firewalling.
[    2.630916] systemd[1]: (This warning is only shown for the first
 unit using IP firewalling.)

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Song Liu <songliubraving at fb.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Add Krzysztof's reviewed-by tag.

Changes in v2:
- Add Song's acked-by tag.

 arch/arm64/configs/defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 530ad076b5cb..444fec9ec73a 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -3,6 +3,7 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
 CONFIG_BPF_JIT=y
 CONFIG_PREEMPT=y
 CONFIG_IRQ_TIME_ACCOUNTING=y
@@ -22,6 +23,7 @@ CONFIG_CPUSETS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
 CONFIG_USER_NS=y
 CONFIG_SCHED_AUTOGROUP=y
 CONFIG_BLK_DEV_INITRD=y
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:48 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:48 +0100
Subject: [PATCH v3 00/12] arm64: prepare and add verdin imx8m mini support
Message-ID: <20220128160100.1228537-1-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>


Fix strange hex notation and gpio-hog example, rebuild default
configuration, enable various relevant configuration options mainly to
be built as modules, add toradex,verdin-imx8mm et al. to dt-bindings and
finally, add initial support for Verdin iMX8M Mini.

Changes in v3:
- Rebase on top of shawnguo's for-next.
- Drop [PATCH v2 02/11] ("dt-bindings: gpio: fix gpio-hog example") as
  it already got applied by Bart.
- Add Krzysztof's reviewed-by tag.
- New separate patch only for re-ordering as suggested by Krzysztof.
- Not dropping CONFIG_SECCOMP=y, CONFIG_SLIMBUS=m, CONFIG_INTERCONNECT=y
  and CONFIG_CONFIGFS_FS=y as requested by Krzysztof.
- New patch enabling imx8m pcie phy driver in arm64 defconfig.
- Remove the 'pm-ignore-notify' property analogous to commit aafac22d6b23
  ("arm64: dts: imx8mm/n: Remove the 'pm-ignore-notify' property").
- Now with PCIe support finally having landed in -next enable it as well.
- Add Krzysztof's acked-by tag.

Changes in v2:
- Add Laurent's reviewed-by tag.
- New patch following full defconfig analysis as requested by Krzysztof.
- New patch following full defconfig analysis as requested by Krzysztof.
- Done full defconfig analysis as requested by Krzysztof.
- Add Song's acked-by tag.
- A similar change got accepted for imx_v6_v7_defconfig. Further
  discussion may be found in [1].
[1] https://lore.kernel.org/lkml/20210920144938.314588-6-marcel at ziswiler.com/
- Explain why enabling it may be a good idea as requested by Krzysztof.
- Explain why enabling these may make sense and squash them relevant
  changes as requested by Krzysztof.
- Add Rob's acked-by tag.
- Fix Colibri vs. Verdin copy/paste mistake. Thanks to Francesco Dolcini
  <francesco.dolcini at toradex.com> for pointing that out to me.
- Remove bootargs which will be filled in by the bootloader as requested
  by Krzysztof.
- Remove the previously #ifdefed-out spi-nor as requested by Krzysztof.
- Fix capitalisation in cover-letter.

Marcel Ziswiler (12):
  arm64: dts: imx8mm: fix strange hex notation
  arm64: defconfig: enable taskstats configuration
  arm64: defconfig: enable pcieaer configuration
  arm64: defconfig: re-order default configuration
  arm64: defconfig: rebuild default configuration
  arm64: defconfig: enable bpf/cgroup firewalling
  arm64: defconfig: enable imx8m pcie phy driver
  arm64: defconfig: build imx-sdma as a module
  arm64: defconfig: build r8169 as a module
  arm64: defconfig: enable verdin-imx8mm relevant drivers as modules
  dt-bindings: arm: fsl: add toradex,verdin-imx8mm et al.
  arm64: dts: freescale: add initial support for verdin imx8m mini

 .../devicetree/bindings/arm/fsl.yaml          |   21 +
 arch/arm64/boot/dts/freescale/Makefile        |    4 +
 .../arm64/boot/dts/freescale/imx8mm-pinfunc.h |    6 +-
 .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  150 ++
 .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
 .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
 .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
 .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
 .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
 .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1291 +++++++++++++++++
 arch/arm64/configs/defconfig                  |  126 +-
 13 files changed, 1839 insertions(+), 68 deletions(-)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi

-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:01:00 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:01:00 +0100
Subject: [PATCH v3 12/12] arm64: dts: freescale: add initial support for
 verdin imx8m mini
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-13-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

This patch adds the device tree to support Toradex Verdin iMX8M Mini a
computer on module which can be used on different carrier boards.

The module consists of an NXP i.MX 8M Mini family SoC (either i.MX 8M
Mini Quad or 8M Mini DualLite), a PCA9450A PMIC, a Gigabit Ethernet PHY,
1 or 2 GB of LPDDR4 RAM, an eMMC, a TLA2024 ADC, an I2C EEPROM, an
RX8130 RTC, an optional SPI CAN controller plus an optional Bluetooth/
Wi-Fi module.

Anything that is not self-contained on the module is disabled by
default.

The device tree for the Dahlia includes the module's device tree and
enables the supported peripherals of the carrier board.

The device tree for the Verdin Development Board includes the module's
device tree as well as the Dahlia one as it is a superset and supports
almost all peripherals available.

So far there is no display functionality supported at all but basic
console UART, PCIe, USB host, eMMC and Ethernet and PCIe functionality
work fine.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>

---

Changes in v3:
- Rebase on top of shawnguo's for-next.
- Drop [PATCH v2 02/11] ("dt-bindings: gpio: fix gpio-hog example") as
  it already got applied by Bart.
- Remove the 'pm-ignore-notify' property analogous to commit aafac22d6b23
  ("arm64: dts: imx8mm/n: Remove the 'pm-ignore-notify' property").
- Now with PCIe support finally having landed in -next enable it as well.
- Add Krzysztof's acked-by tag.

Changes in v2:
- Remove bootargs which will be filled in by the bootloader as requested
  by Krzysztof.
- Remove the previously #ifdefed-out spi-nor as requested by Krzysztof.
- Fix capitalisation in cover-letter.

 arch/arm64/boot/dts/freescale/Makefile        |    4 +
 .../dts/freescale/imx8mm-verdin-dahlia.dtsi   |  150 ++
 .../boot/dts/freescale/imx8mm-verdin-dev.dtsi |   67 +
 .../imx8mm-verdin-nonwifi-dahlia.dts          |   18 +
 .../freescale/imx8mm-verdin-nonwifi-dev.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-nonwifi.dtsi  |   75 +
 .../freescale/imx8mm-verdin-wifi-dahlia.dts   |   18 +
 .../dts/freescale/imx8mm-verdin-wifi-dev.dts  |   18 +
 .../dts/freescale/imx8mm-verdin-wifi.dtsi     |   95 ++
 .../boot/dts/freescale/imx8mm-verdin.dtsi     | 1291 +++++++++++++++++
 10 files changed, 1754 insertions(+)
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
 create mode 100644 arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 6d8f0a532587..04380f2e44a2 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -63,6 +63,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw72xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw73xx-0x.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7901.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw7902.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-nonwifi-dev.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dahlia.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mm-verdin-wifi-dev.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-beacon-kit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mn-bsh-smm-s2pro.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
new file mode 100644
index 000000000000..455127966e67
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-wm8904";
+		simple-audio-card,routing =
+			"Headphone Jack", "HPOUTL",
+			"Headphone Jack", "HPOUTR",
+			"IN2L", "Line In Jack",
+			"IN2R", "Line In Jack",
+			"Headphone Jack", "MICBIAS",
+			"IN1L", "Headphone Jack";
+		simple-audio-card,widgets =
+			"Microphone", "Headphone Jack",
+			"Headphone", "Headphone Jack",
+			"Line", "Line In Jack";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&wm8904_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	status = "okay";
+};
+
+/* EEPROM on display adapter boards */
+&eeprom_display_adapter {
+	status = "okay";
+};
+
+/* EEPROM on Verdin Development board */
+&eeprom_carrier_board {
+	status = "okay";
+};
+
+&fec1 {
+	status = "okay";
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	status = "okay";
+};
+
+/* Current measurement into module VCC */
+&hwmon {
+	status = "okay";
+};
+
+&hwmon_temp {
+	vs-supply = <&reg_1p8v>;
+	status = "okay";
+};
+
+&i2c3 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	status = "okay";
+
+	/* Audio Codec */
+	wm8904_1a: codec at 1a {
+		compatible = "wlf,wm8904";
+		AVDD-supply = <&reg_3p3v>;
+		clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+		clock-names = "mclk";
+		CPVDD-supply = <&reg_3p3v>;
+		DBVDD-supply = <&reg_3p3v>;
+		DCVDD-supply = <&reg_3p3v>;
+		MICVDD-supply = <&reg_3p3v>;
+		reg = <0x1a>;
+		#sound-dai-cells = <0>;
+	};
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+	status = "okay";
+};
+
+&pcie_phy {
+	status = "okay";
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	status = "okay";
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	status = "okay";
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	status = "okay";
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	status = "okay";
+};
+
+/* Verdin UART_3 */
+&uart1 {
+	status = "okay";
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	status = "okay";
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	status = "okay";
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	status = "okay";
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
new file mode 100644
index 000000000000..f35d22dc546b
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	sound_card: sound-card {
+		compatible = "simple-audio-card";
+		simple-audio-card,bitclock-master = <&dailink_master>;
+		simple-audio-card,format = "i2s";
+		simple-audio-card,frame-master = <&dailink_master>;
+		simple-audio-card,name = "imx8mm-nau8822";
+		simple-audio-card,routing =
+			"Headphones", "LHP",
+			"Headphones", "RHP",
+			"Speaker", "LSPK",
+			"Speaker", "RSPK",
+			"Line Out", "AUXOUT1",
+			"Line Out", "AUXOUT2",
+			"LAUX", "Line In",
+			"RAUX", "Line In",
+			"LMICP", "Mic In",
+			"RMICP", "Mic In";
+		simple-audio-card,widgets =
+			"Headphones", "Headphones",
+			"Line Out", "Line Out",
+			"Speaker", "Speaker",
+			"Microphone", "Mic In",
+			"Line", "Line In";
+
+		dailink_master: simple-audio-card,codec {
+			clocks = <&clk IMX8MM_CLK_SAI2_ROOT>;
+			sound-dai = <&nau8822_1a>;
+		};
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai2>;
+		};
+	};
+};
+
+&gpio_expander_21 {
+	status = "okay";
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	/* Audio Codec */
+	nau8822_1a: codec at 1a {
+		compatible = "nuvoton,nau8822";
+		reg = <0x1a>;
+	};
+};
+
+/* Verdin UART_1, connector X50 through RS485 transceiver */
+&uart2 {
+	linux,rs485-enabled-at-boot-time;
+	rs485-rts-active-low;
+	rs485-rx-during-tx;
+};
+
+/* Limit frequency on dev board due to long traces and bad signal integrity */
+&usdhc2 {
+	max-frequency = <100000000>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
new file mode 100644
index 000000000000..d64ff378a152
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dahlia",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
new file mode 100644
index 000000000000..6ae71ecac8de
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-nonwifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-nonwifi-dev",
+		     "toradex,verdin-imx8mm-nonwifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
new file mode 100644
index 000000000000..9aff9dde1a02
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-nonwifi.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "SODIMM_162",
+			  "SODIMM_164",
+			  "SODIMM_166",
+			  "SODIMM_168",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "SODIMM_156",
+			  "SODIMM_160",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "SODIMM_148",
+			  "SODIMM_152",
+			  "SODIMM_154",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "SODIMM_150",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
+
+&usdhc3 {
+	bus-width = <4>;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
new file mode 100644
index 000000000000..d424c475cba1
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dahlia.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dahlia.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Dahlia Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dahlia",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
new file mode 100644
index 000000000000..ef952021832e
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi-dev.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/dts-v1/;
+
+#include "imx8mm-verdin.dtsi"
+#include "imx8mm-verdin-wifi.dtsi"
+#include "imx8mm-verdin-dev.dtsi"
+
+/ {
+	model = "Toradex Verdin iMX8M Mini WB on Verdin Development Board";
+	compatible = "toradex,verdin-imx8mm-wifi-dev",
+		     "toradex,verdin-imx8mm-wifi",
+		     "toradex,verdin-imx8mm",
+		     "fsl,imx8mm";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
new file mode 100644
index 000000000000..c400770c1df5
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-wifi.dtsi
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+/ {
+	reg_wifi_en: regulator-wifi-en {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio3 25 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_wifi_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "PDn_AW-CM276NF";
+		startup-delay-us = <2000>;
+	};
+};
+
+/* On-module Wi-Fi */
+&usdhc3 {
+	bus-width = <4>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc3>, <&pinctrl_wifi_ctrl>;
+	pinctrl-1 = <&pinctrl_usdhc3_100mhz>, <&pinctrl_wifi_ctrl>;
+	pinctrl-2 = <&pinctrl_usdhc3_200mhz>, <&pinctrl_wifi_ctrl>;
+	vmmc-supply = <&reg_wifi_en>;
+	wifi-host;
+	status = "okay";
+};
+
+&gpio3 {
+	gpio-line-names = "SODIMM_52",
+			  "SODIMM_54",
+			  "SODIMM_64",
+			  "SODIMM_21",
+			  "SODIMM_206",
+			  "SODIMM_76",
+			  "SODIMM_56",
+			  "SODIMM_58",
+			  "SODIMM_60",
+			  "SODIMM_62",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_66",
+			  "SODIMM_17",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_244",
+			  "SODIMM_250",
+			  "SODIMM_48",
+			  "SODIMM_44",
+			  "SODIMM_42",
+			  "SODIMM_46";
+};
+
+&gpio4 {
+	gpio-line-names = "SODIMM_102",
+			  "SODIMM_90",
+			  "SODIMM_92",
+			  "SODIMM_94",
+			  "SODIMM_96",
+			  "SODIMM_100",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_174",
+			  "SODIMM_120",
+			  "SODIMM_104",
+			  "SODIMM_106",
+			  "SODIMM_108",
+			  "SODIMM_112",
+			  "SODIMM_114",
+			  "SODIMM_116",
+			  "",
+			  "SODIMM_118",
+			  "",
+			  "SODIMM_88",
+			  "SODIMM_149",
+			  "SODIMM_147",
+			  "SODIMM_36",
+			  "SODIMM_32",
+			  "SODIMM_30",
+			  "SODIMM_34",
+			  "SODIMM_38",
+			  "SODIMM_252",
+			  "SODIMM_133",
+			  "SODIMM_135",
+			  "SODIMM_129";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
new file mode 100644
index 000000000000..00df2a0f1014
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -0,0 +1,1291 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * Copyright 2022 Toradex
+ */
+
+#include "dt-bindings/phy/phy-imx8-pcie.h"
+#include "dt-bindings/pwm/pwm.h"
+#include "imx8mm.dtsi"
+
+/ {
+	chosen {
+		stdout-path = &uart1;
+	};
+
+	aliases {
+		rtc0 = &rtc_i2c;
+		rtc1 = &snvs_rtc;
+	};
+
+	backlight: backlight {
+		compatible = "pwm-backlight";
+		brightness-levels = <0 45 63 88 119 158 203 255>;
+		default-brightness-level = <4>;
+		/* Verdin I2S_2_D_OUT (DSI_1_BKL_EN/DSI_1_BKL_EN_LVDS, SODIMM 46) */
+		enable-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_i2s_2_d_out_dsi_1_bkl_en>;
+		power-supply = <&reg_3p3v>;
+		/* Verdin PWM_3_DSI/PWM_3_DSI_LVDS (SODIMM 19) */
+		pwms = <&pwm1 0 6666667 PWM_POLARITY_INVERTED>;
+		status = "disabled";
+	};
+
+	/* Fixed clock dedicated to SPI CAN controller */
+	clk20m: oscillator {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <20000000>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		wakeup {
+			debounce-interval = <10>;
+			/* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
+			gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
+			label = "Wake-Up";
+			linux,code = <KEY_WAKEUP>;
+			wakeup-source;
+		};
+	};
+
+	/* Carrier Board Supplies */
+	reg_1p8v: regulator-1p8v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <1800000>;
+		regulator-name = "+V1.8_SW";
+	};
+
+	reg_3p3v: regulator-3p3v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SW";
+	};
+
+	reg_5p0v: regulator-5p0v {
+		compatible = "regulator-fixed";
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "+V5_SW";
+	};
+
+	/* Non PMIC On-module Supplies */
+	reg_ethphy: regulator-ethphy {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio2 20 GPIO_ACTIVE_HIGH>; /* PMIC_EN_ETH */
+		off-on-delay = <500000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_eth>;
+		regulator-boot-on;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_ETH";
+		startup-delay-us = <200000>;
+	};
+
+	reg_usb_otg1_vbus: regulator-usb-otg1 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_1_EN (SODIMM 155) */
+		gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb1_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg1_vbus";
+	};
+
+	reg_usb_otg2_vbus: regulator-usb-otg2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin USB_2_EN (SODIMM 185) */
+		gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_reg_usb2_en>;
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		regulator-name = "usb_otg2_vbus";
+	};
+
+	reg_usdhc2_vmmc: regulator-usdhc2 {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		/* Verdin SD_1_PWR_EN (SODIMM 76) */
+		gpio = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+		off-on-delay = <100000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usdhc2_pwr_en>;
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		regulator-name = "+V3.3_SD";
+		startup-delay-us = <2000>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/* Use the kernel configuration settings instead */
+		/delete-node/ linux,cma;
+
+		rpmsg_reserved: rpmsg at b8000000 {
+			no-map;
+			reg = <0 0xb8000000 0 0x400000>;
+		};
+	};
+};
+
+&A53_0 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_1 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_2 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&A53_3 {
+	cpu-supply = <&reg_vdd_arm>;
+};
+
+&ddrc {
+	operating-points-v2 = <&ddrc_opp_table>;
+
+	ddrc_opp_table: opp-table {
+		compatible = "operating-points-v2";
+
+		opp-25M {
+			opp-hz = /bits/ 64 <25000000>;
+		};
+
+		opp-100M {
+			opp-hz = /bits/ 64 <100000000>;
+		};
+
+		opp-750M {
+			opp-hz = /bits/ 64 <750000000>;
+		};
+	};
+};
+
+/* Verdin SPI_1 */
+&ecspi2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi2>;
+};
+
+/* Verdin CAN_1 and CAN_2 (On-module) */
+&ecspi3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>,
+		   <&gpio1 5 GPIO_ACTIVE_LOW>;
+	spi-num-chipselects = <2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi3>;
+	status = "okay";
+
+	can1: can at 0 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 6 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can1_int>;
+		reg = <0>;
+		spi-max-frequency = <8500000>;
+	};
+
+	can2: can at 1 {
+		compatible = "microchip,mcp251xfd";
+		clocks = <&clk20m>;
+		interrupts-extended = <&gpio1 7 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_can2_int>;
+		reg = <1>;
+		spi-max-frequency = <8500000>;
+		/* Not assembled on regular SKUs */
+		status = "disabled";
+	};
+};
+
+/* Verdin ETH_1 (On-module PHY) */
+&fec1 {
+	fsl,magic-packet;
+	phy-handle = <&ethphy0>;
+	phy-mode = "rgmii-id";
+	phy-supply = <&reg_ethphy>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&pinctrl_fec1>;
+	pinctrl-1 = <&pinctrl_fec1_sleep>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		ethphy0: ethernet-phy at 7 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			interrupt-parent = <&gpio1>;
+			interrupts = <10 IRQ_TYPE_LEVEL_LOW>;
+			micrel,led-mode = <0>;
+			reg = <7>;
+		};
+	};
+};
+
+/* Verdin QSPI_1 */
+&flexspi {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexspi0>;
+};
+
+&gpio1 {
+	gpio-line-names = "SODIMM_216",
+			  "SODIMM_19",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_220",
+			  "SODIMM_222",
+			  "",
+			  "SODIMM_218",
+			  "SODIMM_155",
+			  "SODIMM_157",
+			  "SODIMM_185",
+			  "SODIMM_187";
+};
+
+&gpio2 {
+	gpio-line-names = "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_84",
+			  "SODIMM_78",
+			  "SODIMM_74",
+			  "SODIMM_80",
+			  "SODIMM_82",
+			  "SODIMM_70",
+			  "SODIMM_72";
+};
+
+&gpio5 {
+	gpio-line-names = "SODIMM_131",
+			  "",
+			  "SODIMM_91",
+			  "SODIMM_16",
+			  "SODIMM_15",
+			  "SODIMM_208",
+			  "SODIMM_137",
+			  "SODIMM_139",
+			  "SODIMM_141",
+			  "SODIMM_143",
+			  "SODIMM_196",
+			  "SODIMM_200",
+			  "SODIMM_198",
+			  "SODIMM_202",
+			  "",
+			  "",
+			  "SODIMM_55",
+			  "SODIMM_53",
+			  "SODIMM_95",
+			  "SODIMM_93",
+			  "SODIMM_14",
+			  "SODIMM_12",
+			  "",
+			  "",
+			  "",
+			  "",
+			  "SODIMM_210",
+			  "SODIMM_212",
+			  "SODIMM_151",
+			  "SODIMM_153";
+
+	ctrl_sleep_moci-hog {
+		gpio-hog;
+		/* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
+		gpios = <1 GPIO_ACTIVE_HIGH>;
+		line-name = "CTRL_SLEEP_MOCI#";
+		output-high;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_ctrl_sleep_moci>;
+	};
+};
+
+/* On-module I2C */
+&i2c1 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c1>;
+	pinctrl-1 = <&pinctrl_i2c1_gpio>;
+	scl-gpios = <&gpio5 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+
+	pca9450: pmic at 25 {
+		compatible = "nxp,pca9450a";
+		interrupt-parent = <&gpio1>;
+		/* PMIC PCA9450 PMIC_nINT GPIO1_IO3 */
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pmic>;
+		reg = <0x25>;
+		sd-vsel-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			reg_vdd_soc: BUCK1 {
+				nxp,dvs-run-voltage = <850000>;
+				nxp,dvs-standby-voltage = <800000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <850000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+VDD_SOC";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_arm: BUCK2 {
+				nxp,dvs-run-voltage = <950000>;
+				nxp,dvs-standby-voltage = <850000>;
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_ARM";
+				regulator-ramp-delay = <3125>;
+			};
+
+			reg_vdd_dram: BUCK3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <950000>;
+				regulator-min-microvolt = <850000>;
+				regulator-name = "+VDD_GPU_VPU_DDR";
+			};
+
+			reg_vdd_3v3: BUCK4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <3300000>;
+				regulator-name = "+V3.3";
+			};
+
+			reg_vdd_1v8: BUCK5 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "PWR_1V8_MOCI";
+			};
+
+			reg_nvcc_dram: BUCK6 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1100000>;
+				regulator-min-microvolt = <1100000>;
+				regulator-name = "+VDD_DDR";
+			};
+
+			reg_nvcc_snvs: LDO1 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8_SNVS";
+			};
+
+			reg_vdd_snvs: LDO2 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <800000>;
+				regulator-name = "+V0.8_SNVS";
+			};
+
+			reg_vdda: LDO3 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <1800000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V1.8A";
+			};
+
+			reg_vdd_phy: LDO4 {
+				regulator-always-on;
+				regulator-boot-on;
+				regulator-max-microvolt = <900000>;
+				regulator-min-microvolt = <900000>;
+				regulator-name = "+V0.9_MIPI";
+			};
+
+			reg_nvcc_sd: LDO5 {
+				regulator-max-microvolt = <3300000>;
+				regulator-min-microvolt = <1800000>;
+				regulator-name = "+V3.3_1.8_SD";
+			};
+		};
+	};
+
+	rtc_i2c: rtc at 32 {
+		compatible = "epson,rx8130";
+		reg = <0x32>;
+	};
+
+	adc at 49 {
+		compatible = "ti,ads1015";
+		reg = <0x49>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* Verdin I2C_1 (ADC_4 - ADC_3) */
+		channel at 0 {
+			reg = <0>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_4 - ADC_1) */
+		channel at 1 {
+			reg = <1>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_3 - ADC_1) */
+		channel at 2 {
+			reg = <2>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 (ADC_2 - ADC_1) */
+		channel at 3 {
+			reg = <3>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_4 */
+		channel at 4 {
+			reg = <4>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_3 */
+		channel at 5 {
+			reg = <5>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_2 */
+		channel at 6 {
+			reg = <6>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+
+		/* Verdin I2C_1 ADC_1 */
+		channel at 7 {
+			reg = <7>;
+			ti,datarate = <4>;
+			ti,gain = <2>;
+		};
+	};
+
+	eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+	};
+};
+
+/* Verdin I2C_2_DSI */
+&i2c2 {
+	clock-frequency = <10000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	scl-gpios = <&gpio5 16 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "disabled";
+};
+
+/* Verdin I2C_3_HDMI N/A */
+
+/* Verdin I2C_4_CSI */
+&i2c3 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	scl-gpios = <&gpio5 18 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 19 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+};
+
+/* Verdin I2C_1 */
+&i2c4 {
+	clock-frequency = <400000>;
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	pinctrl-1 = <&pinctrl_i2c4_gpio>;
+	scl-gpios = <&gpio5 20 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&gpio5 21 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
+	gpio_expander_21: gpio-expander at 21 {
+		compatible = "nxp,pcal6416";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x21>;
+		status = "disabled";
+		vcc-supply = <&reg_3p3v>;
+	};
+
+	lvds_ti_sn65dsi83: bridge at 2c {
+		compatible = "ti,sn65dsi83";
+		/* Verdin GPIO_9_DSI (SN65DSI84 IRQ, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		enable-gpios = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>;
+		reg = <0x2c>;
+		status = "disabled";
+	};
+
+	/* Current measurement into module VCC */
+	hwmon: hwmon at 40 {
+		compatible = "ti,ina219";
+		reg = <0x40>;
+		shunt-resistor = <10000>;
+		status = "disabled";
+	};
+
+	hdmi_lontium_lt8912: hdmi at 48 {
+		compatible = "lontium,lt8912b";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_10_dsi>, <&pinctrl_pwm_3_dsi_hpd_gpio>;
+		reg = <0x48>;
+		/* Verdin GPIO_9_DSI (LT8912 INT, SODIMM 17, unused) */
+		/* Verdin GPIO_10_DSI (SODIMM 21) */
+		reset-gpios = <&gpio3 3 GPIO_ACTIVE_LOW>;
+		status = "disabled";
+	};
+
+	atmel_mxt_ts: touch at 4a {
+		compatible = "atmel,maxtouch";
+		/* Verdin GPIO_9_DSI */
+		/* (TOUCH_INT#, SODIMM 17, also routed to SN65dsi83 IRQ albeit currently unused) */
+		interrupt-parent = <&gpio3>;
+		interrupts = <15 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_9_dsi>, <&pinctrl_i2s_2_bclk_touch_reset>;
+		reg = <0x4a>;
+		/* Verdin I2S_2_BCLK (TOUCH_RESET#, SODIMM 42) */
+		reset-gpios = <&gpio3 23 GPIO_ACTIVE_HIGH>;
+		status = "disabled";
+	};
+
+	/* Temperature sensor on carrier board */
+	hwmon_temp: sensor at 4f {
+		compatible = "ti,tmp75c";
+		reg = <0x4f>;
+		status = "disabled";
+	};
+
+	/* EEPROM on display adapter (MIPI DSI Display Adapter) */
+	eeprom_display_adapter: eeprom at 50 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x50>;
+		status = "disabled";
+	};
+
+	/* EEPROM on carrier board */
+	eeprom_carrier_board: eeprom at 57 {
+		compatible = "st,24c02";
+		pagesize = <16>;
+		reg = <0x57>;
+		status = "disabled";
+	};
+};
+
+/* Verdin PCIE_1 */
+&pcie0 {
+	assigned-clocks = <&clk IMX8MM_CLK_PCIE1_AUX>,
+			  <&clk IMX8MM_CLK_PCIE1_CTRL>;
+	assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_50M>,
+				 <&clk IMX8MM_SYS_PLL2_250M>;
+	assigned-clock-rates = <10000000>, <250000000>;
+	clocks = <&clk IMX8MM_CLK_PCIE1_ROOT>, <&clk IMX8MM_CLK_PCIE1_AUX>,
+		 <&clk IMX8MM_CLK_PCIE1_PHY>;
+	clock-names = "pcie", "pcie_aux", "pcie_bus";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pcie0>;
+	/* PCIE_1_RESET# (SODIMM 244) */
+	reset-gpio = <&gpio3 19 GPIO_ACTIVE_LOW>;
+};
+
+&pcie_phy {
+	clocks = <&clk IMX8MM_CLK_PCIE1_PHY>;
+	fsl,clkreq-unsupported;
+	fsl,refclk-pad-mode = <IMX8_PCIE_REFCLK_PAD_OUTPUT>;
+	fsl,tx-deemph-gen1 = <0x2d>;
+	fsl,tx-deemph-gen2 = <0xf>;
+};
+
+/* Verdin PWM_3_DSI */
+&pwm1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_1>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_1 */
+&pwm2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_2>;
+	#pwm-cells = <3>;
+};
+
+/* Verdin PWM_2 */
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm_3>;
+	#pwm-cells = <3>;
+};
+
+/* VERDIN I2S_1 */
+&sai2 {
+	#sound-dai-cells = <0>;
+	assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <24576000>;
+	assigned-clocks = <&clk IMX8MM_CLK_SAI2>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_sai2>;
+};
+
+&snvs_pwrkey {
+	status = "okay";
+};
+
+/* Verdin UART_3, used as the Linux console */
+&uart1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart1>;
+};
+
+/* Verdin UART_1 */
+&uart2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart2>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_2 */
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	uart-has-rtscts;
+};
+
+/* Verdin UART_4 */
+/*
+ * Resource allocated to M4 by default, must not be accessed from Cortex-A35 or you get an OOPS
+ */
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+};
+
+&usbmisc1 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+&usbmisc2 {
+	vbus-wakeup-supply = <&reg_vdd_3v3>;
+};
+
+/* Verdin USB_1 */
+&usbotg1 {
+	adp-disable;
+	dr_mode = "otg";
+	hnp-disable;
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	srp-disable;
+	vbus-supply = <&reg_usb_otg1_vbus>;
+};
+
+/* Verdin USB_2 */
+&usbotg2 {
+	dr_mode = "host";
+	over-current-active-low;
+	picophy,dc-vol-level-adjust = <7>;
+	picophy,pre-emp-curr-control = <3>;
+	vbus-supply = <&reg_usb_otg2_vbus>;
+};
+
+&usbphynop1 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+&usbphynop2 {
+	vcc-supply = <&reg_vdd_3v3>;
+};
+
+/* On-module eMMC */
+&usdhc1 {
+	bus-width = <8>;
+	keep-power-in-suspend;
+	non-removable;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	status = "okay";
+};
+
+/* Verdin SD_1 */
+&usdhc2 {
+	bus-width = <4>;
+	cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+	disable-wp;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_cd>;
+	pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_cd>;
+	pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_cd>;
+	vmmc-supply = <&reg_usdhc2_vmmc>;
+};
+
+&wdog1 {
+	fsl,ext-reset-output;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_wdog>;
+	status = "okay";
+};
+
+&iomuxc {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>,
+		    <&pinctrl_gpio3>, <&pinctrl_gpio4>,
+		    <&pinctrl_gpio7>, <&pinctrl_gpio8>,
+		    <&pinctrl_gpio_hog1>, <&pinctrl_gpio_hog2>, <&pinctrl_gpio_hog3>,
+		    <&pinctrl_pmic_tpm_ena>;
+
+	pinctrl_can1_int: can1intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6		0x1c4>;	/* CAN_1_SPI_INT#_1.8V */
+	};
+
+	pinctrl_can2_int: can2intgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7		0x1c4>;	/* CAN_2_SPI_INT#_1.8V */
+	};
+
+	pinctrl_ctrl_sleep_moci: ctrlsleepmocigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1		0x1c4>;	/* SODIMM 256 */
+	};
+
+	pinctrl_ecspi2: ecspi2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK		0x4>,	/* SODIMM 196 */
+			<MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI		0x4>,	/* SODIMM 200 */
+			<MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO		0x1c4>,	/* SODIMM 198 */
+			<MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13		0x1c4>;	/* SODIMM 202 */
+	};
+
+	pinctrl_ecspi3: ecspi3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK		0x4>,	/* CAN_SPI_SCK_1.8V */
+			<MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI		0x4>,	/* CAN_SPI_MOSI_1.8V */
+			<MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO		0x1c4>,	/* CAN_SPI_MISO_1.8V */
+			<MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25		0x1c4>,	/* CAN_1_SPI_CS_1.8V# */
+			<MX8MM_IOMUXC_GPIO1_IO05_GPIO1_IO5		0x1c4>;	/* CAN_2_SPI_CS#_1.8V */
+	};
+
+	pinctrl_fec1: fec1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_ENET1_RGMII_TD3		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_ENET1_RGMII_TD2		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_ENET1_RGMII_TD1		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_ENET1_RGMII_TD0		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL	0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x1c4>;
+	};
+
+	pinctrl_fec1_sleep: fec1-sleepgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ENET_MDC_ENET1_MDC		0x3>,
+			<MX8MM_IOMUXC_ENET_MDIO_ENET1_MDIO		0x3>,
+			<MX8MM_IOMUXC_ENET_TD3_GPIO1_IO18		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD2_GPIO1_IO19		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD1_GPIO1_IO20		0x1f>,
+			<MX8MM_IOMUXC_ENET_TD0_GPIO1_IO21		0x1f>,
+			<MX8MM_IOMUXC_ENET_RD3_ENET1_RGMII_RD3		0x91>,
+			<MX8MM_IOMUXC_ENET_RD2_ENET1_RGMII_RD2		0x91>,
+			<MX8MM_IOMUXC_ENET_RD1_ENET1_RGMII_RD1		0x91>,
+			<MX8MM_IOMUXC_ENET_RD0_ENET1_RGMII_RD0		0x91>,
+			<MX8MM_IOMUXC_ENET_TXC_GPIO1_IO23		0x1f>,
+			<MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC		0x91>,
+			<MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL	0x91>,
+			<MX8MM_IOMUXC_ENET_TX_CTL_GPIO1_IO22		0x1f>,
+			<MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x184>;
+	};
+
+	pinctrl_flexspi0: flexspi0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_ALE_QSPI_A_SCLK		0x1c2>,	/* SODIMM 52 */
+			<MX8MM_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B		0x82>,	/* SODIMM 54 */
+			<MX8MM_IOMUXC_NAND_CE1_B_QSPI_A_SS1_B		0x82>,	/* SODIMM 64 */
+			<MX8MM_IOMUXC_NAND_DQS_QSPI_A_DQS		0x82>,	/* SODIMM 66 */
+			<MX8MM_IOMUXC_NAND_DATA00_QSPI_A_DATA0		0x82>,	/* SODIMM 56 */
+			<MX8MM_IOMUXC_NAND_DATA01_QSPI_A_DATA1		0x82>,	/* SODIMM 58 */
+			<MX8MM_IOMUXC_NAND_DATA02_QSPI_A_DATA2		0x82>,	/* SODIMM 60 */
+			<MX8MM_IOMUXC_NAND_DATA03_QSPI_A_DATA3		0x82>;	/* SODIMM 62 */
+	};
+
+	pinctrl_gpio1: gpio1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE3_B_GPIO3_IO4		0x184>;	/* SODIMM 206 */
+	};
+
+	pinctrl_gpio2: gpio2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5		0x1c4>;	/* SODIMM 208 */
+	};
+
+	pinctrl_gpio3: gpio3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_RXD_GPIO5_IO26		0x184>;	/* SODIMM 210 */
+	};
+
+	pinctrl_gpio4: gpio4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART3_TXD_GPIO5_IO27		0x184>;	/* SODIMM 212 */
+	};
+
+	pinctrl_gpio5: gpio5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO00_GPIO1_IO0		0x184>;	/* SODIMM 216 */
+	};
+
+	pinctrl_gpio6: gpio6grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11		0x184>;	/* SODIMM 218 */
+	};
+
+	pinctrl_gpio7: gpio7grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x184>;	/* SODIMM 220 */
+	};
+
+	pinctrl_gpio8: gpio8grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x184>;	/* SODIMM 222 */
+	};
+
+	/* Verdin GPIO_9_DSI (pulled-up as active-low) */
+	pinctrl_gpio_9_dsi: gpio9dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15		0x1c4>;	/* SODIMM 17 */
+	};
+
+	/* Verdin GPIO_10_DSI */
+	pinctrl_gpio_10_dsi: gpio10dsigrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CE2_B_GPIO3_IO3		0x1c4>;	/* SODIMM 21 */
+	};
+
+	pinctrl_gpio_hog1: gpiohog1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_MCLK_GPIO4_IO20		0x1c4>,	/* SODIMM 88 */
+			<MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1		0x1c4>,	/* SODIMM 90 */
+			<MX8MM_IOMUXC_SAI1_RXD0_GPIO4_IO2		0x1c4>,	/* SODIMM 92 */
+			<MX8MM_IOMUXC_SAI1_RXD1_GPIO4_IO3		0x1c4>,	/* SODIMM 94 */
+			<MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4		0x1c4>,	/* SODIMM 96 */
+			<MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5		0x1c4>,	/* SODIMM 100 */
+			<MX8MM_IOMUXC_SAI1_RXFS_GPIO4_IO0		0x1c4>,	/* SODIMM 102 */
+			<MX8MM_IOMUXC_SAI1_TXC_GPIO4_IO11		0x1c4>,	/* SODIMM 104 */
+			<MX8MM_IOMUXC_SAI1_TXD0_GPIO4_IO12		0x1c4>,	/* SODIMM 106 */
+			<MX8MM_IOMUXC_SAI1_TXD1_GPIO4_IO13		0x1c4>,	/* SODIMM 108 */
+			<MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14		0x1c4>,	/* SODIMM 112 */
+			<MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15		0x1c4>,	/* SODIMM 114 */
+			<MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16		0x1c4>,	/* SODIMM 116 */
+			<MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18		0x1c4>,	/* SODIMM 118 */
+			<MX8MM_IOMUXC_SAI1_TXFS_GPIO4_IO10		0x1c4>;	/* SODIMM 120 */
+	};
+
+	pinctrl_gpio_hog2: gpiohog2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2		0x1c4>;	/* SODIMM 91 */
+	};
+
+	pinctrl_gpio_hog3: gpiohog3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO13_GPIO1_IO13		0x1c4>,	/* SODIMM 157 */
+			<MX8MM_IOMUXC_GPIO1_IO15_GPIO1_IO15		0x1c4>;	/* SODIMM 187 */
+	};
+
+	pinctrl_gpio_keys: gpiokeysgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28		0x1c4>;	/* SODIMM 252 */
+	};
+
+	/* On-module I2C */
+	pinctrl_i2c1: i2c1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	pinctrl_i2c1_gpio: i2c1gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C1_SCL_GPIO5_IO14		0x400001c6>,	/* PMIC_I2C_SCL */
+			<MX8MM_IOMUXC_I2C1_SDA_GPIO5_IO15		0x400001c6>;	/* PMIC_I2C_SDA */
+	};
+
+	/* Verdin I2C_4_CSI */
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL			0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA			0x400001c6>;	/* SODIMM 53 */
+	};
+
+	pinctrl_i2c2_gpio: i2c2gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C2_SCL_GPIO5_IO16		0x400001c6>,	/* SODIMM 55 */
+			<MX8MM_IOMUXC_I2C2_SDA_GPIO5_IO17		0x400001c6>;	/* SODIMM 53 */
+	};
+
+	/* Verdin I2C_2_DSI */
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL			0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA			0x400001c6>;	/* SODIMM 93 */
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C3_SCL_GPIO5_IO18		0x400001c6>,	/* SODIMM 95 */
+			<MX8MM_IOMUXC_I2C3_SDA_GPIO5_IO19		0x400001c6>;	/* SODIMM 93 */
+	};
+
+	/* Verdin I2C_1 */
+	pinctrl_i2c4: i2c4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c6>;	/* SODIMM 12 */
+	};
+
+	pinctrl_i2c4_gpio: i2c4gpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_I2C4_SCL_GPIO5_IO20		0x400001c6>,	/* SODIMM 14 */
+			<MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21		0x400001c6>;	/* SODIMM 12 */
+	};
+
+	/* Verdin I2S_2_BCLK (TOUCH_RESET#) */
+	pinctrl_i2s_2_bclk_touch_reset: i2s2bclktouchresetgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23		0x184>;	/* SODIMM 42 */
+	};
+
+	/* Verdin I2S_2_D_OUT shared with SAI5 */
+	pinctrl_i2s_2_d_out_dsi_1_bkl_en: i2s2doutdsi1bklengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24		0x184>;	/* SODIMM 46 */
+	};
+
+	pinctrl_pcie0: pcie0grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19		0x6>,	/* SODIMM 244 */
+			/* PMIC_EN_PCIe_CLK, unused */
+			<MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19		0x6>;
+	};
+
+	pinctrl_pmic: pmicirqgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x41>;	/* PMIC_INT# */
+	};
+
+	/* Verdin PWM_3_DSI shared with GPIO1_IO1 */
+	pinctrl_pwm_1: pwm1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_PWM1_OUT		0x6>;	/* SODIMM 19 */
+	};
+
+	pinctrl_pwm_2: pwm2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT			0x6>;	/* SODIMM 15 */
+	};
+
+	pinctrl_pwm_3: pwm3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT			0x6>;	/* SODIMM 16 */
+	};
+
+	/* Verdin PWM_3_DSI (pulled-down as active-high) shared with PWM1_OUT */
+	pinctrl_pwm_3_dsi_hpd_gpio: pwm3dsihpdgpiogrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO01_GPIO1_IO1		0x184>;	/* SODIMM 19 */
+	};
+
+	pinctrl_reg_eth: regethgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_WP_GPIO2_IO20			0x184>;	/* PMIC_EN_ETH */
+	};
+
+	pinctrl_reg_usb1_en: regusb1engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12		0x184>;	/* SODIMM 155 */
+	};
+
+	pinctrl_reg_usb2_en: regusb2engrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO14_GPIO1_IO14		0x184>;	/* SODIMM 185 */
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC		0xd6>,	/* SODIMM 32 */
+			<MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK		0xd6>,	/* SODIMM 30 */
+			<MX8MM_IOMUXC_SAI2_MCLK_SAI2_MCLK		0xd6>,	/* SODIMM 38 */
+			<MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0		0xd6>,	/* SODIMM 36 */
+			<MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0		0xd6>;	/* SODIMM 34 */
+	};
+
+	pinctrl_sai5: sai5grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_RXD0_SAI5_RX_DATA0		0xd6>,	/* SODIMM 48 */
+			<MX8MM_IOMUXC_SAI5_RXD1_SAI5_TX_SYNC		0xd6>,	/* SODIMM 44 */
+			<MX8MM_IOMUXC_SAI5_RXD2_SAI5_TX_BCLK		0xd6>,	/* SODIMM 42 */
+			<MX8MM_IOMUXC_SAI5_RXD3_SAI5_TX_DATA0		0xd6>;	/* SODIMM 46 */
+	};
+
+	/* control signal for optional ATTPM20P or SE050 */
+	pinctrl_pmic_tpm_ena: pmictpmenagrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19		0x1c4>;	/* PMIC_TPM_ENA */
+	};
+
+	pinctrl_tsp: tspgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6		0x140>,	/* SODIMM 148 */
+			<MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7		0x140>,	/* SODIMM 152 */
+			<MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8		0x140>,	/* SODIMM 154 */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x140>,	/* SODIMM 179 */
+			<MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17		0x140>;	/* SODIMM 150 */
+	};
+
+	pinctrl_uart1: uart1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x1c4>,	/* SODIMM 149 */
+			<MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x1c4>;	/* SODIMM 147 */
+	};
+
+	pinctrl_uart2: uart2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x1c4>,	/* SODIMM 129 */
+			<MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x1c4>,	/* SODIMM 131 */
+			<MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x1c4>,	/* SODIMM 133 */
+			<MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x1c4>;	/* SODIMM 135 */
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_ECSPI1_SCLK_UART3_DCE_RX		0x1c4>,	/* SODIMM 137 */
+			<MX8MM_IOMUXC_ECSPI1_MOSI_UART3_DCE_TX		0x1c4>,	/* SODIMM 139 */
+			<MX8MM_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B	0x1c4>,	/* SODIMM 141 */
+			<MX8MM_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B	0x1c4>;	/* SODIMM 143 */
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_UART4_RXD_UART4_DCE_RX		0x1c4>,	/* SODIMM 151 */
+			<MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX		0x1c4>;	/* SODIMM 153 */
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x190>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d0>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d0>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x190>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x194>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d4>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d4>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x194>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK		0x196>,
+			<MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA4_USDHC1_DATA4		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA5_USDHC1_DATA5		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA6_USDHC1_DATA6		0x1d6>,
+			<MX8MM_IOMUXC_SD1_DATA7_USDHC1_DATA7		0x1d6>,
+			<MX8MM_IOMUXC_SD1_RESET_B_USDHC1_RESET_B	0x1d1>,
+			<MX8MM_IOMUXC_SD1_STROBE_USDHC1_STROBE		0x196>;
+	};
+
+	pinctrl_usdhc2_cd: usdhc2cdgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x1c4>;	/* SODIMM 84 */
+	};
+
+	pinctrl_usdhc2_pwr_en: usdhc2pwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_CLE_GPIO3_IO5		0x184>;	/* SODIMM 76 */
+	};
+
+	pinctrl_usdhc2: usdhc2grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x190>,	/* SODIMM 78 */
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d0>,	/* SODIMM 74 */
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0>,	/* SODIMM 80 */
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0>,	/* SODIMM 82 */
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0>,	/* SODIMM 70 */
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0>,	/* SODIMM 72 */
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x194>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK		0x196>,
+			<MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6>,
+			<MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0>;
+	};
+
+	/* On-module Wi-Fi/BT or type specific SDHC interface */
+	/* (e.g. on X52 extension slot of Verdin Development Board) */
+	pinctrl_usdhc3: usdhc3grp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x190>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d0>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d0>;
+	};
+
+	pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x194>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d4>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d4>;
+	};
+
+	pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_WE_B_USDHC3_CLK		0x196>,
+			<MX8MM_IOMUXC_NAND_WP_B_USDHC3_CMD		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA04_USDHC3_DATA0		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA05_USDHC3_DATA1		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA06_USDHC3_DATA2		0x1d6>,
+			<MX8MM_IOMUXC_NAND_DATA07_USDHC3_DATA3		0x1d6>;
+	};
+
+	pinctrl_wdog: wdoggrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B		0xc6>;	/* PMIC_WDI */
+	};
+
+	pinctrl_wifi_ctrl: wifictrlgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16		0x1c4>,	/* WIFI_WKUP_BT */
+			<MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9		0x1c4>,	/* WIFI_W_WKUP_HOST */
+			<MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20		0x1c4>;	/* WIFI_WKUP_WLAN */
+	};
+
+	pinctrl_wifi_i2s: bti2sgrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI1_RXD4_SAI6_TX_BCLK		0xd6>,	/* WIFI_TX_BCLK */
+			<MX8MM_IOMUXC_SAI1_RXD5_SAI6_TX_DATA0		0xd6>,	/* WIFI_TX_DATA0 */
+			<MX8MM_IOMUXC_SAI1_RXD6_SAI6_TX_SYNC		0xd6>,	/* WIFI_TX_SYNC */
+			<MX8MM_IOMUXC_SAI1_TXD5_SAI6_RX_DATA0		0xd6>;	/* WIFI_RX_DATA0 */
+	};
+
+	pinctrl_wifi_pwr_en: wifipwrengrp {
+		fsl,pins =
+			<MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25		0x184>;	/* PMIC_EN_WIFI */
+	};
+};
-- 
2.33.1



From marcel at ziswiler.com  Fri Jan 28 08:00:59 2022
From: marcel at ziswiler.com (Marcel Ziswiler)
Date: Fri, 28 Jan 2022 17:00:59 +0100
Subject: [PATCH v3 11/12] dt-bindings: arm: fsl: add toradex,
 verdin-imx8mm et al.
In-Reply-To: <20220128160100.1228537-1-marcel@ziswiler.com>
References: <20220128160100.1228537-1-marcel@ziswiler.com>
Message-ID: <20220128160100.1228537-12-marcel@ziswiler.com>

From: Marcel Ziswiler <marcel.ziswiler at toradex.com>

Add toradex,verdin-imx8mm for our new Verdin iMX8M Mini modules, its
nonwifi and wifi variants and the carrier boards (both Dahlia and the
Verdin Development Board) they may be mated in.

Signed-off-by: Marcel Ziswiler <marcel.ziswiler at toradex.com>
Acked-by: Rob Herring <robh at kernel.org>

---

(no changes since v2)

Changes in v2:
- Add Rob's acked-by tag.
- Fix Colibri vs. Verdin copy/paste mistake. Thanks to Francesco Dolcini
  <francesco.dolcini at toradex.com> for pointing that out to me.

 .../devicetree/bindings/arm/fsl.yaml          | 21 +++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 5075fd8c1b42..4ddeb9b20195 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -770,6 +770,9 @@ properties:
               - gw,imx8mm-gw7901          # i.MX8MM Gateworks Board
               - gw,imx8mm-gw7902          # i.MX8MM Gateworks Board
               - kontron,imx8mm-n801x-som  # i.MX8MM Kontron SL (N801X) SOM
+              - toradex,verdin-imx8mm     # Verdin iMX8M Mini Modules
+              - toradex,verdin-imx8mm-nonwifi  # Verdin iMX8M Mini Modules without Wi-Fi / BT
+              - toradex,verdin-imx8mm-wifi  # Verdin iMX8M Mini Wi-Fi / BT Modules
               - variscite,var-som-mx8mm   # i.MX8MM Variscite VAR-SOM-MX8MM module
               - prt,prt8mm                # i.MX8MM Protonic PRT8MM Board
           - const: fsl,imx8mm
@@ -788,6 +791,24 @@ properties:
           - const: kontron,imx8mm-n801x-som
           - const: fsl,imx8mm
 
+      - description: Toradex Boards with Verdin iMX8M Mini Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-nonwifi-dahlia # Verdin iMX8M Mini Module on Dahlia
+              - toradex,verdin-imx8mm-nonwifi-dev    # Verdin iMX8M Mini Module on Verdin Development Board
+          - const: toradex,verdin-imx8mm-nonwifi     # Verdin iMX8M Mini Module without Wi-Fi / BT
+          - const: toradex,verdin-imx8mm             # Verdin iMX8M Mini Module
+          - const: fsl,imx8mm
+
+      - description: Toradex Boards with Verdin iMX8M Mini Wi-Fi / BT Modules
+        items:
+          - enum:
+              - toradex,verdin-imx8mm-wifi-dahlia # Verdin iMX8M Mini Wi-Fi / BT Module on Dahlia
+              - toradex,verdin-imx8mm-wifi-dev    # Verdin iMX8M Mini Wi-Fi / BT M. on Verdin Development B.
+          - const: toradex,verdin-imx8mm-wifi     # Verdin iMX8M Mini Wi-Fi / BT Module
+          - const: toradex,verdin-imx8mm          # Verdin iMX8M Mini Module
+          - const: fsl,imx8mm
+
       - description: Variscite VAR-SOM-MX8MM based boards
         items:
           - const: variscite,var-som-mx8mm-symphony
-- 
2.33.1



From vladimir.murzin at arm.com  Fri Jan 28 08:02:14 2022
From: vladimir.murzin at arm.com (Vladimir Murzin)
Date: Fri, 28 Jan 2022 16:02:14 +0000
Subject: [bootwrapper PATCH] aarch64: Recognize PAuth QARMA3
Message-ID: <20220128160214.92297-1-vladimir.murzin@arm.com>

QARMA3 is relaxed version of the QARMA5 algorithm which expected to
reduce the latency of calculation while still delivering a suitable
level of security.

Support for QARMA3 can be discovered via ID_AA64ISAR2_EL1 [1]

APA3, bits [15:12] Indicates whether the QARMA3 algorithm is
                   implemented in the PE for address authentication in
		   AArch64 state.

GPA3, bits [11:8]  Indicates whether the QARMA3 algorithm is
                   implemented in the PE for generic code
                   authentication in AArch64 state.

[1] https://developer.arm.com/documentation/ddi0601/2021-12/AArch64-Registers/ID-AA64ISAR2-EL1--AArch64-Instruction-Set-Attribute-Register-2?lang=en

Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
---
 arch/aarch64/include/asm/cpu.h |  5 +++++
 arch/aarch64/init.c            | 14 +++++++++-----
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index 1be2d54..ce80b6e 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -63,6 +63,9 @@
 #define ID_AA64ISAR1_EL1_GPA		BITS(27, 24)
 #define ID_AA64ISAR1_EL1_GPI		BITS(31, 28)
 
+#define ID_AA64ISAR2_EL1_GPA3		BITS(11, 8)
+#define ID_AA64ISAR2_EL1_APA3		BITS(15, 12)
+
 #define ID_AA64MMFR0_EL1_FGT		BITS(59, 56)
 #define ID_AA64MMFR0_EL1_ECV		BITS(63, 60)
 
@@ -104,6 +107,8 @@
 #define ZCR_EL3			s3_6_c1_c2_0
 #define ZCR_EL3_LEN_MAX		0xf
 
+#define ID_AA64ISAR2_EL1	s3_0_c0_c6_2
+
 #define SCTLR_EL1_CP15BEN	(1 << 5)
 
 #ifdef KERNEL_32
diff --git a/arch/aarch64/init.c b/arch/aarch64/init.c
index 6677f2b..aa58567 100644
--- a/arch/aarch64/init.c
+++ b/arch/aarch64/init.c
@@ -30,12 +30,16 @@ static inline bool kernel_is_32bit(void)
 
 static inline bool cpu_has_pauth(void)
 {
-	const unsigned long id_pauth = ID_AA64ISAR1_EL1_APA |
-				       ID_AA64ISAR1_EL1_API |
-				       ID_AA64ISAR1_EL1_GPA |
-				       ID_AA64ISAR1_EL1_GPI;
+	const unsigned long isar1_pauth = ID_AA64ISAR1_EL1_APA |
+					  ID_AA64ISAR1_EL1_API |
+					  ID_AA64ISAR1_EL1_GPA |
+					  ID_AA64ISAR1_EL1_GPI;
 
-	return mrs(ID_AA64ISAR1_EL1) & id_pauth;
+	const unsigned long isar2_pauth = ID_AA64ISAR2_EL1_APA3 |
+					  ID_AA64ISAR2_EL1_GPA3;
+
+	return (mrs(ID_AA64ISAR1_EL1) & isar1_pauth) ||
+	       (mrs(ID_AA64ISAR2_EL1) & isar2_pauth);
 }
 
 void cpu_init_el3(void)
-- 
2.7.4



From steven.price at arm.com  Fri Jan 28 08:08:50 2022
From: steven.price at arm.com (Steven Price)
Date: Fri, 28 Jan 2022 16:08:50 +0000
Subject: [RFC PATCH 03/12] arm64: mm: use a fixmap slot for user page
 table modifications
In-Reply-To: <20220126173011.3476262-4-ardb@kernel.org>
References: <20220126173011.3476262-1-ardb@kernel.org>
 <20220126173011.3476262-4-ardb@kernel.org>
Message-ID: <65e1ae7d-44ae-a19f-e193-583590cfa0c3@arm.com>

Hi Ard,

Interesting series - I attempted[1] something similar a few years ago,
but only dealing with the page tables in the linear map.

At first glace the series looks like it should work, but this patch
caught my eye because there's only a single fixmap slot for page table
modifications. The upshot of which is you need the patch_pte_lock
serialising multiple CPUs' access to the page tables. Which looks like
it would hurt badly as the number of CPUs grows.

Do you have any benchmarks of the performance? I've lost any I did at
the time I previously looked at this idea but obviously thought it was
important at the time.

Thanks,

Steve

[1]
https://lore.kernel.org/lkml/20200417152619.41680-1-steven.price at arm.com/

On 26/01/2022 17:30, Ard Biesheuvel wrote:
> To prepare for user and kernel page tables being remapped read-only in
> the linear region, define a new fixmap slot and use it to apply all page
> table descriptor updates that target page tables other than swapper.
> 
> Fortunately for us, the fixmap descriptors themselves are always
> manipulated via their kernel mapping in .bss, so there is no special
> exception required to avoid circular logic here.
> 
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm64/Kconfig               |  11 +++
>  arch/arm64/include/asm/fixmap.h  |   1 +
>  arch/arm64/include/asm/pgalloc.h |  28 +++++-
>  arch/arm64/include/asm/pgtable.h |  79 +++++++++++++---
>  arch/arm64/mm/Makefile           |   2 +
>  arch/arm64/mm/fault.c            |   8 +-
>  arch/arm64/mm/ro_page_tables.c   | 100 ++++++++++++++++++++
>  7 files changed, 209 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 6978140edfa4..a3e98286b074 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -1311,6 +1311,17 @@ config RODATA_FULL_DEFAULT_ENABLED
>  	  This requires the linear region to be mapped down to pages,
>  	  which may adversely affect performance in some cases.
>  
> +config ARM64_RO_PAGE_TABLES
> +	bool "Remap page tables read-only in the kernel VA space"
> +	select RODATA_FULL_DEFAULT_ENABLED
> +	help
> +	  Remap linear mappings of page table pages read-only as long as they
> +	  are being used as such, and use a fixmap API to manipulate all page
> +	  table descriptors, instead of manipulating them directly via their
> +	  writable mappings in the direct map. This is intended as a debug
> +	  and/or hardening feature, as it removes the ability for stray writes
> +	  to be exploited to bypass permission restrictions.
> +
>  config ARM64_SW_TTBR0_PAN
>  	bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
>  	help
> diff --git a/arch/arm64/include/asm/fixmap.h b/arch/arm64/include/asm/fixmap.h
> index 4335800201c9..71dfbe0452bb 100644
> --- a/arch/arm64/include/asm/fixmap.h
> +++ b/arch/arm64/include/asm/fixmap.h
> @@ -50,6 +50,7 @@ enum fixed_addresses {
>  
>  	FIX_EARLYCON_MEM_BASE,
>  	FIX_TEXT_POKE0,
> +	FIX_TEXT_POKE_PTE,
>  
>  #ifdef CONFIG_ACPI_APEI_GHES
>  	/* Used for GHES mapping from assorted contexts */
> diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
> index 237224484d0f..d54ac9f8d6c7 100644
> --- a/arch/arm64/include/asm/pgalloc.h
> +++ b/arch/arm64/include/asm/pgalloc.h
> @@ -30,7 +30,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
>  	pudval_t pudval = PUD_TYPE_TABLE;
>  
>  	pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
> -	__pud_populate(pudp, __pa(pmdp), pudval);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(mm, (pte_t *)pudp,
> +			    __pte(__phys_to_pud_val(__pa(pmdp) | pudval)));
> +	else
> +		__pud_populate(pudp, __pa(pmdp), pudval);
>  }
>  #else
>  static inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
> @@ -51,7 +55,11 @@ static inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
>  	p4dval_t p4dval = P4D_TYPE_TABLE;
>  
>  	p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
> -	__p4d_populate(p4dp, __pa(pudp), p4dval);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(mm, (pte_t *)p4dp,
> +			    __pte(__phys_to_p4d_val(__pa(pudp) | p4dval)));
> +	else
> +		__p4d_populate(p4dp, __pa(pudp), p4dval);
>  }
>  #else
>  static inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
> @@ -76,15 +84,27 @@ static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
>  static inline void
>  pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
>  {
> +	pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_UXN;
> +
>  	VM_BUG_ON(mm && mm != &init_mm);
> -	__pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(mm, (pte_t *)pmdp,
> +			    __pte(__phys_to_pmd_val(__pa(ptep) | pmdval)));
> +	else
> +		__pmd_populate(pmdp, __pa(ptep), pmdval);
>  }
>  
>  static inline void
>  pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
>  {
> +	pmdval_t pmdval = PMD_TYPE_TABLE | PMD_TABLE_PXN;
> +
>  	VM_BUG_ON(mm == &init_mm);
> -	__pmd_populate(pmdp, page_to_phys(ptep), PMD_TYPE_TABLE | PMD_TABLE_PXN);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(mm, (pte_t *)pmdp,
> +			    __pte(__phys_to_pmd_val(page_to_phys(ptep) | pmdval)));
> +	else
> +		__pmd_populate(pmdp, page_to_phys(ptep), pmdval);
>  }
>  
>  #endif
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index 8d3806c68687..a8daea6b4ac9 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -30,6 +30,7 @@
>  
>  #include <asm/cmpxchg.h>
>  #include <asm/fixmap.h>
> +#include <linux/jump_label.h>
>  #include <linux/mmdebug.h>
>  #include <linux/mm_types.h>
>  #include <linux/sched.h>
> @@ -37,6 +38,17 @@
>  int set_pgtable_ro(void *addr);
>  int set_pgtable_rw(void *addr);
>  
> +DECLARE_STATIC_KEY_FALSE(ro_page_tables);
> +
> +static inline bool page_tables_are_ro(void)
> +{
> +	return IS_ENABLED(CONFIG_ARM64_RO_PAGE_TABLES) &&
> +	       static_branch_unlikely(&ro_page_tables);
> +}
> +
> +pte_t xchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t pte);
> +pte_t cmpxchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t old, pte_t new);
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
>  
> @@ -89,7 +101,7 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys)
>  	__pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
>  
>  #define pte_none(pte)		(!pte_val(pte))
> -#define pte_clear(mm,addr,ptep)	set_pte(ptep, __pte(0))
> +#define pte_clear(mm,addr,ptep)	set_pte_at(mm, addr, ptep, __pte(0))
>  #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
>  
>  /*
> @@ -257,7 +269,10 @@ static inline pte_t pte_mkdevmap(pte_t pte)
>  
>  static inline void set_pte(pte_t *ptep, pte_t pte)
>  {
> -	WRITE_ONCE(*ptep, pte);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(&init_mm, ptep, pte);
> +	else
> +		WRITE_ONCE(*ptep, pte);
>  
>  	/*
>  	 * Only if the new pte is valid and kernel, otherwise TLB maintenance
> @@ -343,7 +358,10 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
>  
>  	__check_racy_pte_update(mm, ptep, pte);
>  
> -	set_pte(ptep, pte);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(mm, ptep, pte);
> +	else
> +		set_pte(ptep, pte);
>  }
>  
>  /*
> @@ -579,7 +597,10 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
>  	}
>  #endif /* __PAGETABLE_PMD_FOLDED */
>  
> -	WRITE_ONCE(*pmdp, pmd);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(&init_mm, (pte_t *)pmdp, pmd_pte(pmd));
> +	else
> +		WRITE_ONCE(*pmdp, pmd);
>  
>  	if (pmd_valid(pmd)) {
>  		dsb(ishst);
> @@ -589,7 +610,10 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
>  
>  static inline void pmd_clear(pmd_t *pmdp)
>  {
> -	set_pmd(pmdp, __pmd(0));
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(NULL, (pte_t *)pmdp, __pte(0));
> +	else
> +		set_pmd(pmdp, __pmd(0));
>  }
>  
>  static inline phys_addr_t pmd_page_paddr(pmd_t pmd)
> @@ -640,7 +664,10 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
>  	}
>  #endif /* __PAGETABLE_PUD_FOLDED */
>  
> -	WRITE_ONCE(*pudp, pud);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(&init_mm, (pte_t *)pudp, pud_pte(pud));
> +	else
> +		WRITE_ONCE(*pudp, pud);
>  
>  	if (pud_valid(pud)) {
>  		dsb(ishst);
> @@ -650,7 +677,10 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
>  
>  static inline void pud_clear(pud_t *pudp)
>  {
> -	set_pud(pudp, __pud(0));
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(NULL, (pte_t *)pudp, __pte(0));
> +	else
> +		set_pud(pudp, __pud(0));
>  }
>  
>  static inline phys_addr_t pud_page_paddr(pud_t pud)
> @@ -704,14 +734,20 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
>  		return;
>  	}
>  
> -	WRITE_ONCE(*p4dp, p4d);
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(&init_mm, (pte_t *)p4dp, p4d_pte(p4d));
> +	else
> +		WRITE_ONCE(*p4dp, p4d);
>  	dsb(ishst);
>  	isb();
>  }
>  
>  static inline void p4d_clear(p4d_t *p4dp)
>  {
> -	set_p4d(p4dp, __p4d(0));
> +	if (page_tables_are_ro())
> +		xchg_ro_pte(NULL, (pte_t *)p4dp, __pte(0));
> +	else
> +		set_p4d(p4dp, __p4d(0));
>  }
>  
>  static inline phys_addr_t p4d_page_paddr(p4d_t p4d)
> @@ -806,7 +842,7 @@ static inline int pgd_devmap(pgd_t pgd)
>   * Atomic pte/pmd modifications.
>   */
>  #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> -static inline int __ptep_test_and_clear_young(pte_t *ptep)
> +static inline int __ptep_test_and_clear_young(struct mm_struct *mm, pte_t *ptep)
>  {
>  	pte_t old_pte, pte;
>  
> @@ -814,8 +850,13 @@ static inline int __ptep_test_and_clear_young(pte_t *ptep)
>  	do {
>  		old_pte = pte;
>  		pte = pte_mkold(pte);
> -		pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
> -					       pte_val(old_pte), pte_val(pte));
> +
> +		if (page_tables_are_ro())
> +			pte = cmpxchg_ro_pte(mm, ptep, old_pte, pte);
> +		else
> +			pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
> +						       pte_val(old_pte),
> +						       pte_val(pte));
>  	} while (pte_val(pte) != pte_val(old_pte));
>  
>  	return pte_young(pte);
> @@ -825,7 +866,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
>  					    unsigned long address,
>  					    pte_t *ptep)
>  {
> -	return __ptep_test_and_clear_young(ptep);
> +	return __ptep_test_and_clear_young(vma->vm_mm, ptep);
>  }
>  
>  #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> @@ -863,6 +904,8 @@ static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
>  static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
>  				       unsigned long address, pte_t *ptep)
>  {
> +	if (page_tables_are_ro())
> +		return xchg_ro_pte(mm, ptep, __pte(0));
>  	return __pte(xchg_relaxed(&pte_val(*ptep), 0));
>  }
>  
> @@ -888,8 +931,12 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
>  	do {
>  		old_pte = pte;
>  		pte = pte_wrprotect(pte);
> -		pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
> -					       pte_val(old_pte), pte_val(pte));
> +		if (page_tables_are_ro())
> +			pte = cmpxchg_ro_pte(mm, ptep, old_pte, pte);
> +		else
> +			pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
> +						       pte_val(old_pte),
> +						       pte_val(pte));
>  	} while (pte_val(pte) != pte_val(old_pte));
>  }
>  
> @@ -905,6 +952,8 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm,
>  static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
>  		unsigned long address, pmd_t *pmdp, pmd_t pmd)
>  {
> +	if (page_tables_are_ro())
> +		return pte_pmd(xchg_ro_pte(vma->vm_mm, (pte_t *)pmdp, pmd_pte(pmd)));
>  	return __pmd(xchg_relaxed(&pmd_val(*pmdp), pmd_val(pmd)));
>  }
>  #endif
> diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile
> index ff1e800ba7a1..7750cafd969a 100644
> --- a/arch/arm64/mm/Makefile
> +++ b/arch/arm64/mm/Makefile
> @@ -14,3 +14,5 @@ KASAN_SANITIZE_physaddr.o	+= n
>  
>  obj-$(CONFIG_KASAN)		+= kasan_init.o
>  KASAN_SANITIZE_kasan_init.o	:= n
> +
> +obj-$(CONFIG_ARM64_RO_PAGE_TABLES) += ro_page_tables.o
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 77341b160aca..5a5055c3e1c2 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -220,7 +220,13 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
>  		pteval ^= PTE_RDONLY;
>  		pteval |= pte_val(entry);
>  		pteval ^= PTE_RDONLY;
> -		pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval, pteval);
> +		if (page_tables_are_ro())
> +			pteval = pte_val(cmpxchg_ro_pte(vma->vm_mm, ptep,
> +							__pte(old_pteval),
> +							__pte(pteval)));
> +		else
> +			pteval = cmpxchg_relaxed(&pte_val(*ptep), old_pteval,
> +						 pteval);
>  	} while (pteval != old_pteval);
>  
>  	/* Invalidate a stale read-only entry */
> diff --git a/arch/arm64/mm/ro_page_tables.c b/arch/arm64/mm/ro_page_tables.c
> new file mode 100644
> index 000000000000..f497adfd774d
> --- /dev/null
> +++ b/arch/arm64/mm/ro_page_tables.c
> @@ -0,0 +1,100 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2021 - Google Inc
> + * Author: Ard Biesheuvel <ardb at google.com>
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/memory.h>
> +#include <linux/mm.h>
> +#include <linux/sizes.h>
> +
> +#include <asm/fixmap.h>
> +#include <asm/kernel-pgtable.h>
> +#include <asm/mmu_context.h>
> +#include <asm/pgalloc.h>
> +#include <asm/tlbflush.h>
> +#include <asm/sections.h>
> +
> +static DEFINE_RAW_SPINLOCK(patch_pte_lock);
> +
> +DEFINE_STATIC_KEY_FALSE(ro_page_tables);
> +
> +static bool __initdata ro_page_tables_enabled = true;
> +
> +static int __init parse_ro_page_tables(char *arg)
> +{
> +	return strtobool(arg, &ro_page_tables_enabled);
> +}
> +early_param("ro_page_tables", parse_ro_page_tables);
> +
> +static bool in_kernel_text_or_rodata(phys_addr_t pa)
> +{
> +	/*
> +	 * This is a minimal check to ensure that the r/o page table patching
> +	 * API is not being abused to make changes to the kernel text. This
> +	 * should ideally cover module and BPF text/rodata as well, but that
> +	 * is less straight-forward and hence more costly.
> +	 */
> +	return pa >= __pa_symbol(_stext) && pa < __pa_symbol(__init_begin);
> +}
> +
> +pte_t xchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t pte)
> +{
> +	unsigned long flags;
> +	u64 pte_pa;
> +	pte_t ret;
> +	pte_t *p;
> +
> +	/* can we use __pa() on ptep? */
> +	if (!virt_addr_valid(ptep)) {
> +		/* only linear aliases are remapped r/o anyway */
> +		pte_val(ret) = xchg_relaxed(&pte_val(*ptep), pte_val(pte));
> +		return ret;
> +	}
> +
> +	pte_pa = __pa(ptep);
> +	BUG_ON(in_kernel_text_or_rodata(pte_pa));
> +
> +	raw_spin_lock_irqsave(&patch_pte_lock, flags);
> +	p = (pte_t *)set_fixmap_offset(FIX_TEXT_POKE_PTE, pte_pa);
> +	pte_val(ret) = xchg_relaxed(&pte_val(*p), pte_val(pte));
> +	clear_fixmap(FIX_TEXT_POKE_PTE);
> +	raw_spin_unlock_irqrestore(&patch_pte_lock, flags);
> +	return ret;
> +}
> +
> +pte_t cmpxchg_ro_pte(struct mm_struct *mm, pte_t *ptep, pte_t old, pte_t new)
> +{
> +	unsigned long flags;
> +	u64 pte_pa;
> +	pte_t ret;
> +	pte_t *p;
> +
> +	BUG_ON(!virt_addr_valid(ptep));
> +
> +	pte_pa = __pa(ptep);
> +	BUG_ON(in_kernel_text_or_rodata(pte_pa));
> +
> +	raw_spin_lock_irqsave(&patch_pte_lock, flags);
> +	p = (pte_t *)set_fixmap_offset(FIX_TEXT_POKE_PTE, pte_pa);
> +	pte_val(ret) = cmpxchg_relaxed(&pte_val(*p), pte_val(old), pte_val(new));
> +	clear_fixmap(FIX_TEXT_POKE_PTE);
> +	raw_spin_unlock_irqrestore(&patch_pte_lock, flags);
> +	return ret;
> +}
> +
> +static int __init ro_page_tables_init(void)
> +{
> +	if (ro_page_tables_enabled) {
> +		if (!rodata_full) {
> +			pr_err("Failed to enable R/O page table protection, rodata=full is not enabled\n");
> +		} else {
> +			pr_err("Enabling R/O page table protection\n");
> +			static_branch_enable(&ro_page_tables);
> +		}
> +	}
> +	return 0;
> +}
> +early_initcall(ro_page_tables_init);



From svens at linux.ibm.com  Fri Jan 28 08:08:48 2022
From: svens at linux.ibm.com (Sven Schnelle)
Date: Fri, 28 Jan 2022 17:08:48 +0100
Subject: ftrace hangs waiting for rcu
In-Reply-To: <YfQCohKWJg9H+uID@FVFF77S0Q05N> (Mark Rutland's message of "Fri, 
 28 Jan 2022 15:42:48 +0000")
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
 <YfQCohKWJg9H+uID@FVFF77S0Q05N>
Message-ID: <yt9dee4rn8q7.fsf@linux.ibm.com>

Hi Mark,

Mark Rutland <mark.rutland at arm.com> writes:

> On arm64 I bisected this down to:
>
>   7a30871b6a27de1a ("rcu-tasks: Introduce ->percpu_enqueue_shift for dynamic queue selection")
>
> Which was going wrong because ilog2() rounds down, and so the shift was wrong
> for any nr_cpus that was not a power-of-two. Paul had already fixed that in
> rcu-next, and just sent a pull request to Linus:
>
>   https://lore.kernel.org/lkml/20220128143251.GA2398275 at paulmck-ThinkPad-P17-Gen-1/
>
> With that applied, I no longer see these hangs.
>
> Does your s390 test machine have a non-power-of-two nr_cpus, and does that fix
> the issue for you?

We noticed the PR from Paul and are currently testing the fix. So far
it's looking good. The configuration where we have seen the hang is a
bit unusual:

- 16 physical CPUs on the kvm host
- 248 logical CPUs inside kvm
- debug kernel both on the host and kvm guest

So things are likely a bit slow in the kvm guest. Interesting is that
the number of CPUs is even. But maybe RCU sees an odd number of CPUs
and gets confused before all cpus are brought up. Have to read code/test
to see whether that could be possible.

Thanks for investigating!
Sven


From f.fainelli at gmail.com  Fri Jan 28 08:12:02 2022
From: f.fainelli at gmail.com (Florian Fainelli)
Date: Fri, 28 Jan 2022 08:12:02 -0800
Subject: [PATCH] pinctrl: bcm2835: Fix a few error paths
In-Reply-To: <YfP/TuEERCrgst+k@smile.fi.intel.com>
References: <20220127215033.267227-1-f.fainelli@gmail.com>
 <YfP/TuEERCrgst+k@smile.fi.intel.com>
Message-ID: <f28cba7f-6799-9f08-71b2-249a2a506913@gmail.com>



On 1/28/2022 6:35 AM, Andy Shevchenko wrote:
> On Thu, Jan 27, 2022 at 01:50:31PM -0800, Florian Fainelli wrote:
>> After commit 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio
>> hogs") a few error paths would not unwind properly the registration of
>> gpio ranges. Correct that by assigning a single error label and goto it
>> whenever we encounter a fatal error.
> 
>>   1 file changed, 15 insertions(+), 8 deletions(-)
> 
> While this seems legit per se, my eyes caught this:
> 
> 
>>   	if (!girq->parents) {
>> -		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
>> -		return -ENOMEM;
>> +		err = -ENOMEM;
>> +		goto out_remove;
> 
> Non-devm....
> 
>>   	}
>>   
>>   	if (is_7211) {
>>   		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
>>   					    sizeof(*pc->wake_irq),
>>   					    GFP_KERNEL);
> 
> ...followed by devm.
> 
> It means more ordering bugs in the ->remove() and error path are lurking
> around. Can you double check and be sure that we do not have a case where
> non-devm registration code followed by devm?

It seems to me like we are fine with the patch as is, because:

- girq->parents is allocated with devm
- pc->wake_irq is allocated with devm
- name is allocated with devm

and those are the only variables being allocated for which we also 
process an error handling path.
-- 
Florian


From mark.rutland at arm.com  Fri Jan 28 08:11:57 2022
From: mark.rutland at arm.com (Mark Rutland)
Date: Fri, 28 Jan 2022 16:11:57 +0000
Subject: ftrace hangs waiting for rcu
In-Reply-To: <yt9dee4rn8q7.fsf@linux.ibm.com>
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
 <YfQCohKWJg9H+uID@FVFF77S0Q05N> <yt9dee4rn8q7.fsf@linux.ibm.com>
Message-ID: <YfQVzba5thVs+qap@FVFF77S0Q05N>

On Fri, Jan 28, 2022 at 05:08:48PM +0100, Sven Schnelle wrote:
> Hi Mark,
> 
> Mark Rutland <mark.rutland at arm.com> writes:
> 
> > On arm64 I bisected this down to:
> >
> >   7a30871b6a27de1a ("rcu-tasks: Introduce ->percpu_enqueue_shift for dynamic queue selection")
> >
> > Which was going wrong because ilog2() rounds down, and so the shift was wrong
> > for any nr_cpus that was not a power-of-two. Paul had already fixed that in
> > rcu-next, and just sent a pull request to Linus:
> >
> >   https://lore.kernel.org/lkml/20220128143251.GA2398275 at paulmck-ThinkPad-P17-Gen-1/
> >
> > With that applied, I no longer see these hangs.
> >
> > Does your s390 test machine have a non-power-of-two nr_cpus, and does that fix
> > the issue for you?
> 
> We noticed the PR from Paul and are currently testing the fix. So far
> it's looking good. The configuration where we have seen the hang is a
> bit unusual:
> 
> - 16 physical CPUs on the kvm host
> - 248 logical CPUs inside kvm

Aha! 248 is notably *NOT* a power of two, and in this case the shift would be
wrong (ilog2() would give 7, when we need a shift of 8).

So I suspect you're hitting the same issue as I was.

Thanks,
Mark.

> - debug kernel both on the host and kvm guest
> 
> So things are likely a bit slow in the kvm guest. Interesting is that
> the number of CPUs is even. But maybe RCU sees an odd number of CPUs
> and gets confused before all cpus are brought up. Have to read code/test
> to see whether that could be possible.
> 
> Thanks for investigating!
> Sven


From yhs at fb.com  Fri Jan 28 08:15:09 2022
From: yhs at fb.com (Yonghong Song)
Date: Fri, 28 Jan 2022 08:15:09 -0800
Subject: [PATCH bpf-next 2/2] arm64, bpf: support more atomic operations
In-Reply-To: <YfPCkUW4XIHGTZ6z@FVFF77S0Q05N>
References: <20220121135632.136976-1-houtao1@huawei.com>
 <20220121135632.136976-3-houtao1@huawei.com> <YfPCkUW4XIHGTZ6z@FVFF77S0Q05N>
Message-ID: <03a72767-37bb-2d6f-0553-5a55571e09bd@fb.com>



On 1/28/22 2:16 AM, Mark Rutland wrote:
> On Fri, Jan 21, 2022 at 09:56:32PM +0800, Hou Tao wrote:
>> Atomics for eBPF patch series adds support for atomic[64]_fetch_add,
>> atomic[64]_[fetch_]{and,or,xor} and atomic[64]_{xchg|cmpxchg}, but
>> it only add support for x86-64, so support these atomic operations
>> for arm64 as well.
> 
> What ordering semantics are the BPF atomics supposed to have?
> 
> e.g. are those meant to be sequentially consistent, entirely relaxed, or
> somewhere imbetween?

The ordering semantics follows linux kernel memory model. Please
see interpreter implementation at kernel/bpf/core.c. The kernel
atomic_*() functions are used to implement these functions.

> 
>> Basically the implementation procedure is almost mechanical translation
>> of code snippets in atomic_ll_sc.h & atomic_lse.h & cmpxchg.h located
>> under arch/arm64/include/asm. An extra temporary register is needed
>> for (BPF_ADD | BPF_FETCH) to save the value of src register, instead of
>> adding TMP_REG_4 just use BPF_REG_AX instead.
>>
>> For cpus_have_cap(ARM64_HAS_LSE_ATOMICS) case and no-LSE-ATOMICS case,
>> both ./test_verifier and "./test_progs -t atomic" are exercised and
>> passed correspondingly.
>>
>> Signed-off-by: Hou Tao <houtao1 at huawei.com>
>> ---
>>   arch/arm64/include/asm/insn.h |  45 +++++--
>>   arch/arm64/lib/insn.c         | 155 +++++++++++++++++++++---
> 
[...]


From paulmck at kernel.org  Fri Jan 28 08:15:47 2022
From: paulmck at kernel.org (Paul E. McKenney)
Date: Fri, 28 Jan 2022 08:15:47 -0800
Subject: ftrace hangs waiting for rcu
In-Reply-To: <YfQVzba5thVs+qap@FVFF77S0Q05N>
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
 <YfQCohKWJg9H+uID@FVFF77S0Q05N> <yt9dee4rn8q7.fsf@linux.ibm.com>
 <YfQVzba5thVs+qap@FVFF77S0Q05N>
Message-ID: <20220128161547.GL4285@paulmck-ThinkPad-P17-Gen-1>

On Fri, Jan 28, 2022 at 04:11:57PM +0000, Mark Rutland wrote:
> On Fri, Jan 28, 2022 at 05:08:48PM +0100, Sven Schnelle wrote:
> > Hi Mark,
> > 
> > Mark Rutland <mark.rutland at arm.com> writes:
> > 
> > > On arm64 I bisected this down to:
> > >
> > >   7a30871b6a27de1a ("rcu-tasks: Introduce ->percpu_enqueue_shift for dynamic queue selection")
> > >
> > > Which was going wrong because ilog2() rounds down, and so the shift was wrong
> > > for any nr_cpus that was not a power-of-two. Paul had already fixed that in
> > > rcu-next, and just sent a pull request to Linus:
> > >
> > >   https://lore.kernel.org/lkml/20220128143251.GA2398275 at paulmck-ThinkPad-P17-Gen-1/
> > >
> > > With that applied, I no longer see these hangs.
> > >
> > > Does your s390 test machine have a non-power-of-two nr_cpus, and does that fix
> > > the issue for you?
> > 
> > We noticed the PR from Paul and are currently testing the fix. So far
> > it's looking good. The configuration where we have seen the hang is a
> > bit unusual:
> > 
> > - 16 physical CPUs on the kvm host
> > - 248 logical CPUs inside kvm
> 
> Aha! 248 is notably *NOT* a power of two, and in this case the shift would be
> wrong (ilog2() would give 7, when we need a shift of 8).
> 
> So I suspect you're hitting the same issue as I was.

And apparently no one runs -next on systems having a non-power-of-two
number of CPUs.  ;-)

							Thanx, Paul

> Thanks,
> Mark.
> 
> > - debug kernel both on the host and kvm guest
> > 
> > So things are likely a bit slow in the kvm guest. Interesting is that
> > the number of CPUs is even. But maybe RCU sees an odd number of CPUs
> > and gets confused before all cpus are brought up. Have to read code/test
> > to see whether that could be possible.
> > 
> > Thanks for investigating!
> > Sven


From chunkuang.hu at kernel.org  Fri Jan 28 08:16:28 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 29 Jan 2022 00:16:28 +0800
Subject: [PATCH v1,
 1/4] soc: mediatek: mmsys: Add mt8186 mmsys routing table
In-Reply-To: <20220128120718.30545-2-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
 <20220128120718.30545-2-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_-V2A5SqQ5XGh54QfLYAtue1_Uita=J0osdFC1hLnRP2g@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2022?1?28? ?? ??8:07???
>
> mt8186 routing registers is different with other Soc
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/soc/mediatek/mt8186-mmsys.h | 113 ++++++++++++++++++++++++++++
>  drivers/soc/mediatek/mtk-mmsys.c    |  11 +++
>  2 files changed, 124 insertions(+)
>  create mode 100644 drivers/soc/mediatek/mt8186-mmsys.h
>
> diff --git a/drivers/soc/mediatek/mt8186-mmsys.h b/drivers/soc/mediatek/mt8186-mmsys.h
> new file mode 100644
> index 000000000000..7de329f2d729
> --- /dev/null
> +++ b/drivers/soc/mediatek/mt8186-mmsys.h
> @@ -0,0 +1,113 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +
> +#ifndef __SOC_MEDIATEK_MT8186_MMSYS_H
> +#define __SOC_MEDIATEK_MT8186_MMSYS_H
> +
> +#define MT8186_MMSYS_OVL_CON                   0xF04
> +#define MT8186_MMSYS_OVL0_CON_MASK                     0x3
> +#define MT8186_MMSYS_OVL0_2L_CON_MASK                  0xC
> +#define MT8186_OVL0_GO_BLEND                           BIT(0)
> +#define MT8186_OVL0_GO_BG                              BIT(1)
> +#define MT8186_OVL0_2L_GO_BLEND                                BIT(2)
> +#define MT8186_OVL0_2L_GO_BG                           BIT(3)
> +#define MT8186_DISP_RDMA0_SOUT_SEL             0xF0C
> +#define MT8186_RDMA0_SOUT_SEL_MASK                     0xF
> +#define MT8186_RDMA0_SOUT_TO_DSI0                      (0)
> +#define MT8186_RDMA0_SOUT_TO_COLOR0                    (1)
> +#define MT8186_RDMA0_SOUT_TO_DPI0                      (2)
> +#define MT8186_DISP_OVL0_2L_MOUT_EN            0xF14
> +#define MT8186_OVL0_2L_MOUT_EN_MASK                    0xF
> +#define MT8186_OVL0_2L_MOUT_TO_RDMA0                   BIT(0)
> +#define MT8186_OVL0_2L_MOUT_TO_RDMA1                   BIT(3)
> +#define MT8186_DISP_OVL0_MOUT_EN               0xF18
> +#define MT8186_OVL0_MOUT_EN_MASK                       0xF
> +#define MT8186_OVL0_MOUT_TO_RDMA0                      BIT(0)
> +#define MT8186_OVL0_MOUT_TO_RDMA1                      BIT(3)
> +#define MT8186_DISP_DITHER0_MOUT_EN            0xF20
> +#define MT8186_DITHER0_MOUT_EN_MASK                    0xF
> +#define MT8186_DITHER0_MOUT_TO_DSI0                    BIT(0)
> +#define MT8186_DITHER0_MOUT_TO_RDMA1                   BIT(2)
> +#define MT8186_DITHER0_MOUT_TO_DPI0                    BIT(3)
> +#define MT8186_DISP_RDMA0_SEL_IN               0xF28
> +#define MT8186_RDMA0_SEL_IN_MASK                       0xF
> +#define MT8186_RDMA0_FROM_OVL0                         0
> +#define MT8186_RDMA0_FROM_OVL0_2L                      2
> +#define MT8186_DISP_DSI0_SEL_IN                        0xF30
> +#define MT8186_DSI0_SEL_IN_MASK                                0xF
> +#define MT8186_DSI0_FROM_RDMA0                         0
> +#define MT8186_DSI0_FROM_DITHER0                       1
> +#define MT8186_DSI0_FROM_RDMA1                         2
> +#define MT8186_DISP_RDMA1_MOUT_EN              0xF3C
> +#define MT8186_RDMA1_MOUT_EN_MASK                      0xF
> +#define MT8186_RDMA1_MOUT_TO_DPI0_SEL                  BIT(0)
> +#define MT8186_RDMA1_MOUT_TO_DSI0_SEL                  BIT(2)
> +#define MT8186_DISP_RDMA1_SEL_IN               0xF40
> +#define MT8186_RDMA1_SEL_IN_MASK                       0xF
> +#define MT8186_RDMA1_FROM_OVL0                         0
> +#define MT8186_RDMA1_FROM_OVL0_2L                      2
> +#define MT8186_RDMA1_FROM_DITHER0                      3
> +#define MT8186_DISP_DPI0_SEL_IN                        0xF44
> +#define MT8186_DPI0_SEL_IN_MASK                                0xF
> +#define MT8186_DPI0_FROM_RDMA1                         0
> +#define MT8186_DPI0_FROM_DITHER0                       1
> +#define MT8186_DPI0_FROM_RDMA0                         2
> +
> +static const struct mtk_mmsys_routes mmsys_mt8186_routing_table[] = {
> +       {
> +               DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +               MT8186_DISP_OVL0_MOUT_EN, MT8186_OVL0_MOUT_EN_MASK,
> +               MT8186_OVL0_MOUT_TO_RDMA0
> +       },
> +       {
> +               DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +               MT8186_DISP_RDMA0_SEL_IN, MT8186_RDMA0_SEL_IN_MASK,
> +               MT8186_RDMA0_FROM_OVL0
> +       },
> +       {
> +               DDP_COMPONENT_OVL0, DDP_COMPONENT_RDMA0,
> +               MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_CON_MASK,
> +               MT8186_OVL0_GO_BLEND
> +       },
> +       {
> +               DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
> +               MT8186_DISP_RDMA0_SOUT_SEL, MT8186_RDMA0_SOUT_SEL_MASK,
> +               MT8186_RDMA0_SOUT_TO_COLOR0
> +       },
> +       {
> +               DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +               MT8186_DISP_DITHER0_MOUT_EN, MT8186_DITHER0_MOUT_EN_MASK,
> +               MT8186_DITHER0_MOUT_TO_DSI0,
> +       },
> +       {
> +               DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> +               MT8186_DISP_DSI0_SEL_IN, MT8186_DSI0_SEL_IN_MASK,
> +               MT8186_DSI0_FROM_DITHER0
> +       },
> +       {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
> +               MT8186_DISP_OVL0_2L_MOUT_EN, MT8186_OVL0_2L_MOUT_EN_MASK,
> +               MT8186_OVL0_2L_MOUT_TO_RDMA1
> +       },
> +       {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
> +               MT8186_DISP_RDMA1_SEL_IN, MT8186_RDMA1_SEL_IN_MASK,
> +               MT8186_RDMA1_FROM_OVL0_2L
> +       },
> +       {
> +               DDP_COMPONENT_OVL_2L0, DDP_COMPONENT_RDMA1,
> +               MT8186_MMSYS_OVL_CON, MT8186_MMSYS_OVL0_2L_CON_MASK,
> +               MT8186_OVL0_2L_GO_BLEND
> +       },
> +       {
> +               DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
> +               MT8186_DISP_RDMA1_MOUT_EN, MT8186_RDMA1_MOUT_EN_MASK,
> +               MT8186_RDMA1_MOUT_TO_DPI0_SEL
> +       },
> +       {
> +               DDP_COMPONENT_RDMA1, DDP_COMPONENT_DPI0,
> +               MT8186_DISP_DPI0_SEL_IN, MT8186_DPI0_SEL_IN_MASK,
> +               MT8186_DPI0_FROM_RDMA1
> +       },
> +};
> +
> +#endif /* __SOC_MEDIATEK_MT8186_MMSYS_H */
> diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c
> index 1e448f1ffefb..0da25069ffb3 100644
> --- a/drivers/soc/mediatek/mtk-mmsys.c
> +++ b/drivers/soc/mediatek/mtk-mmsys.c
> @@ -15,6 +15,7 @@
>  #include "mtk-mmsys.h"
>  #include "mt8167-mmsys.h"
>  #include "mt8183-mmsys.h"
> +#include "mt8186-mmsys.h"
>  #include "mt8192-mmsys.h"
>  #include "mt8365-mmsys.h"
>
> @@ -56,6 +57,12 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>         .num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
>  };
>
> +static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
> +       .clk_driver = "clk-mt8186-mm",
> +       .routes = mmsys_mt8186_routing_table,
> +       .num_routes = ARRAY_SIZE(mmsys_mt8186_routing_table),
> +};
> +
>  static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
>         .clk_driver = "clk-mt8192-mm",
>         .routes = mmsys_mt8192_routing_table,
> @@ -242,6 +249,10 @@ static const struct of_device_id of_match_mtk_mmsys[] = {
>                 .compatible = "mediatek,mt8183-mmsys",
>                 .data = &mt8183_mmsys_driver_data,
>         },
> +       {
> +               .compatible = "mediatek,mt8186-mmsys",

Add "mediatek,mt8186-mmsys" to binding document.

Regards,
Chun-Kuang.

> +               .data = &mt8186_mmsys_driver_data,
> +       },
>         {
>                 .compatible = "mediatek,mt8192-mmsys",
>                 .data = &mt8192_mmsys_driver_data,
> --
> 2.25.1
>


From chunkuang.hu at kernel.org  Fri Jan 28 08:17:14 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 29 Jan 2022 00:17:14 +0800
Subject: [PATCH v1, 2/4] soc: mediatek: add mtk mutex support for MT8186
In-Reply-To: <20220128120718.30545-3-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
 <20220128120718.30545-3-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_-qXrE+5ej2YUFCqrMmuNvRzcQtnyJPoSUD5O9N5fgs1A@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2022?1?28? ?? ??8:07???
>
> Add mtk mutex support for MT8186 SoC.
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/soc/mediatek/mtk-mutex.c | 45 ++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>
> diff --git a/drivers/soc/mediatek/mtk-mutex.c b/drivers/soc/mediatek/mtk-mutex.c
> index 2ca55bb5a8be..ebd95fd0f36e 100644
> --- a/drivers/soc/mediatek/mtk-mutex.c
> +++ b/drivers/soc/mediatek/mtk-mutex.c
> @@ -26,6 +26,23 @@
>
>  #define INT_MUTEX                              BIT(1)
>
> +#define MT8186_MUTEX_MOD_DISP_OVL0             0
> +#define MT8186_MUTEX_MOD_DISP_OVL0_2L          1
> +#define MT8186_MUTEX_MOD_DISP_RDMA0            2
> +#define MT8186_MUTEX_MOD_DISP_COLOR0           4
> +#define MT8186_MUTEX_MOD_DISP_CCORR0           5
> +#define MT8186_MUTEX_MOD_DISP_AAL0             7
> +#define MT8186_MUTEX_MOD_DISP_GAMMA0           8
> +#define MT8186_MUTEX_MOD_DISP_POSTMASK0                9
> +#define MT8186_MUTEX_MOD_DISP_DITHER0          10
> +#define MT8186_MUTEX_MOD_DISP_RDMA1            17
> +
> +#define MT8186_MUTEX_SOF_SINGLE_MODE 0
> +#define MT8186_MUTEX_SOF_DSI0 1
> +#define MT8186_MUTEX_SOF_DPI0 2
> +#define MT8186_MUTEX_EOF_DSI0 (MT8186_MUTEX_SOF_DSI0 << 6)
> +#define MT8186_MUTEX_EOF_DPI0 (MT8186_MUTEX_SOF_DPI0 << 6)
> +
>  #define MT8167_MUTEX_MOD_DISP_PWM              1
>  #define MT8167_MUTEX_MOD_DISP_OVL0             6
>  #define MT8167_MUTEX_MOD_DISP_OVL1             7
> @@ -226,6 +243,19 @@ static const unsigned int mt8183_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_WDMA0] = MT8183_MUTEX_MOD_DISP_WDMA0,
>  };
>
> +static const unsigned int mt8186_mutex_mod[DDP_COMPONENT_ID_MAX] = {
> +       [DDP_COMPONENT_AAL0] = MT8186_MUTEX_MOD_DISP_AAL0,
> +       [DDP_COMPONENT_CCORR] = MT8186_MUTEX_MOD_DISP_CCORR0,
> +       [DDP_COMPONENT_COLOR0] = MT8186_MUTEX_MOD_DISP_COLOR0,
> +       [DDP_COMPONENT_DITHER] = MT8186_MUTEX_MOD_DISP_DITHER0,
> +       [DDP_COMPONENT_GAMMA] = MT8186_MUTEX_MOD_DISP_GAMMA0,
> +       [DDP_COMPONENT_OVL0] = MT8186_MUTEX_MOD_DISP_OVL0,
> +       [DDP_COMPONENT_OVL_2L0] = MT8186_MUTEX_MOD_DISP_OVL0_2L,
> +       [DDP_COMPONENT_POSTMASK0] = MT8186_MUTEX_MOD_DISP_POSTMASK0,
> +       [DDP_COMPONENT_RDMA0] = MT8186_MUTEX_MOD_DISP_RDMA0,
> +       [DDP_COMPONENT_RDMA1] = MT8186_MUTEX_MOD_DISP_RDMA1,
> +};
> +
>  static const unsigned int mt8192_mutex_mod[DDP_COMPONENT_ID_MAX] = {
>         [DDP_COMPONENT_AAL0] = MT8192_MUTEX_MOD_DISP_AAL0,
>         [DDP_COMPONENT_CCORR] = MT8192_MUTEX_MOD_DISP_CCORR0,
> @@ -264,6 +294,12 @@ static const unsigned int mt8183_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
>         [MUTEX_SOF_DPI0] = MT8183_MUTEX_SOF_DPI0 | MT8183_MUTEX_EOF_DPI0,
>  };
>
> +static const unsigned int mt8186_mutex_sof[MUTEX_SOF_DSI3 + 1] = {
> +       [MUTEX_SOF_SINGLE_MODE] = MUTEX_SOF_SINGLE_MODE,
> +       [MUTEX_SOF_DSI0] = MT8186_MUTEX_SOF_DSI0 | MT8186_MUTEX_EOF_DSI0,
> +       [MUTEX_SOF_DPI0] = MT8186_MUTEX_SOF_DPI0 | MT8186_MUTEX_EOF_DPI0,
> +};
> +
>  static const struct mtk_mutex_data mt2701_mutex_driver_data = {
>         .mutex_mod = mt2701_mutex_mod,
>         .mutex_sof = mt2712_mutex_sof,
> @@ -301,6 +337,13 @@ static const struct mtk_mutex_data mt8183_mutex_driver_data = {
>         .no_clk = true,
>  };
>
> +static const struct mtk_mutex_data mt8186_mutex_driver_data = {
> +       .mutex_mod = mt8186_mutex_mod,
> +       .mutex_sof = mt8186_mutex_sof,
> +       .mutex_mod_reg = MT8183_MUTEX0_MOD0,
> +       .mutex_sof_reg = MT8183_MUTEX0_SOF0,
> +};
> +
>  static const struct mtk_mutex_data mt8192_mutex_driver_data = {
>         .mutex_mod = mt8192_mutex_mod,
>         .mutex_sof = mt8183_mutex_sof,
> @@ -540,6 +583,8 @@ static const struct of_device_id mutex_driver_dt_match[] = {
>           .data = &mt8173_mutex_driver_data},
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = &mt8183_mutex_driver_data},
> +       { .compatible = "mediatek,mt8186-disp-mutex",

Add "mediatek,mt8186-disp-mutex" to binding document.

Regards,
Chun-Kuang.

> +       .data = &mt8186_mutex_driver_data},
>         { .compatible = "mediatek,mt8192-disp-mutex",
>           .data = &mt8192_mutex_driver_data},
>         {},
> --
> 2.25.1
>


From svens at linux.ibm.com  Fri Jan 28 08:17:32 2022
From: svens at linux.ibm.com (Sven Schnelle)
Date: Fri, 28 Jan 2022 17:17:32 +0100
Subject: ftrace hangs waiting for rcu
In-Reply-To: <YfQVzba5thVs+qap@FVFF77S0Q05N> (Mark Rutland's message of "Fri, 
 28 Jan 2022 16:11:57 +0000")
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
 <YfQCohKWJg9H+uID@FVFF77S0Q05N> <yt9dee4rn8q7.fsf@linux.ibm.com>
 <YfQVzba5thVs+qap@FVFF77S0Q05N>
Message-ID: <yt9da6ffn8bn.fsf@linux.ibm.com>

Hi Mark,

Mark Rutland <mark.rutland at arm.com> writes:

> On Fri, Jan 28, 2022 at 05:08:48PM +0100, Sven Schnelle wrote:
>> We noticed the PR from Paul and are currently testing the fix. So far
>> it's looking good. The configuration where we have seen the hang is a
>> bit unusual:
>> 
>> - 16 physical CPUs on the kvm host
>> - 248 logical CPUs inside kvm
>
> Aha! 248 is notably *NOT* a power of two, and in this case the shift would be
> wrong (ilog2() would give 7, when we need a shift of 8).
>
> So I suspect you're hitting the same issue as I was.

Argh, indeed! I somehow changed 'power of two' to 'odd number' in my
head. I guess it's time for the weekend. :-)

Thanks!


From chunkuang.hu at kernel.org  Fri Jan 28 08:19:01 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 29 Jan 2022 00:19:01 +0800
Subject: [PATCH v1, 4/4] drm/mediatek: add mt8186 display support
In-Reply-To: <20220128120718.30545-5-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
 <20220128120718.30545-5-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_8uF1TY9TsP3wUW6gw9M21F9Op9wRc9GDX7edbSa8sQeQ@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2022?1?28? ?? ??8:07???
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c | 39 ++++++++++++++++++++++++++
>  1 file changed, 39 insertions(+)
>
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 6efb423ccc92..754b1be25d0d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -158,6 +158,24 @@ static const enum mtk_ddp_comp_id mt8183_mtk_ddp_ext[] = {
>         DDP_COMPONENT_DPI0,
>  };
>
> +static const enum mtk_ddp_comp_id mt8186_mtk_ddp_main[] = {
> +       DDP_COMPONENT_OVL0,
> +       DDP_COMPONENT_RDMA0,
> +       DDP_COMPONENT_COLOR0,
> +       DDP_COMPONENT_CCORR,
> +       DDP_COMPONENT_AAL0,
> +       DDP_COMPONENT_GAMMA,
> +       DDP_COMPONENT_POSTMASK0,
> +       DDP_COMPONENT_DITHER,
> +       DDP_COMPONENT_DSI0,
> +};
> +
> +static const enum mtk_ddp_comp_id mt8186_mtk_ddp_ext[] = {
> +       DDP_COMPONENT_OVL_2L0,
> +       DDP_COMPONENT_RDMA1,
> +       DDP_COMPONENT_DPI0,
> +};
> +
>  static const enum mtk_ddp_comp_id mt8192_mtk_ddp_main[] = {
>         DDP_COMPONENT_OVL0,
>         DDP_COMPONENT_OVL_2L0,
> @@ -221,6 +239,13 @@ static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
>         .ext_len = ARRAY_SIZE(mt8183_mtk_ddp_ext),
>  };
>
> +static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
> +       .main_path = mt8186_mtk_ddp_main,
> +       .main_len = ARRAY_SIZE(mt8186_mtk_ddp_main),
> +       .ext_path = mt8186_mtk_ddp_ext,
> +       .ext_len = ARRAY_SIZE(mt8186_mtk_ddp_ext),
> +};
> +
>  static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
>         .main_path = mt8192_mtk_ddp_main,
>         .main_len = ARRAY_SIZE(mt8192_mtk_ddp_main),
> @@ -463,6 +488,8 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8183-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
> +       { .compatible = "mediatek,mt8186-disp-mutex",
> +         .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8192-disp-mutex",
>           .data = (void *)MTK_DISP_MUTEX },
>         { .compatible = "mediatek,mt8173-disp-od",
> @@ -475,14 +502,20 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DISP_OVL },
>         { .compatible = "mediatek,mt8183-disp-ovl",
>           .data = (void *)MTK_DISP_OVL },
> +       { .compatible = "mediatek,mt8186-disp-ovl",

Add "mediatek,mt8186-disp-ovl" to binding document.

> +         .data = (void *)MTK_DISP_OVL },
>         { .compatible = "mediatek,mt8192-disp-ovl",
>           .data = (void *)MTK_DISP_OVL },
>         { .compatible = "mediatek,mt8183-disp-ovl-2l",
>           .data = (void *)MTK_DISP_OVL_2L },
> +       { .compatible = "mediatek,mt8186-disp-ovl-2l",

Ditto.

> +         .data = (void *)MTK_DISP_OVL_2L },
>         { .compatible = "mediatek,mt8192-disp-ovl-2l",
>           .data = (void *)MTK_DISP_OVL_2L },
>         { .compatible = "mediatek,mt8192-disp-postmask",
>           .data = (void *)MTK_DISP_POSTMASK },
> +       { .compatible = "mediatek,mt8186-disp-postmask",

Ditto.

> +         .data = (void *)MTK_DISP_POSTMASK},
>         { .compatible = "mediatek,mt2701-disp-pwm",
>           .data = (void *)MTK_DISP_BLS },
>         { .compatible = "mediatek,mt8167-disp-pwm",
> @@ -511,12 +544,16 @@ static const struct of_device_id mtk_ddp_comp_dt_ids[] = {
>           .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt8183-dpi",
>           .data = (void *)MTK_DPI },
> +       { .compatible = "mediatek,mt8186-dpi",

Ditto.

> +         .data = (void *)MTK_DPI },
>         { .compatible = "mediatek,mt2701-dsi",
>           .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt8173-dsi",
>           .data = (void *)MTK_DSI },
>         { .compatible = "mediatek,mt8183-dsi",
>           .data = (void *)MTK_DSI },
> +       { .compatible = "mediatek,mt8186-dsi",

Ditto.

Regards,
Chun-Kuang.

> +         .data = (void *)MTK_DSI },
>         { }
>  };
>
> @@ -533,6 +570,8 @@ static const struct of_device_id mtk_drm_of_ids[] = {
>           .data = &mt8173_mmsys_driver_data},
>         { .compatible = "mediatek,mt8183-mmsys",
>           .data = &mt8183_mmsys_driver_data},
> +       { .compatible = "mediatek,mt8186-mmsys",
> +         .data = &mt8186_mmsys_driver_data},
>         { .compatible = "mediatek,mt8192-mmsys",
>           .data = &mt8192_mmsys_driver_data},
>         { }
> --
> 2.25.1
>


From suzuki.poulose at arm.com  Fri Jan 28 08:19:48 2022
From: suzuki.poulose at arm.com (Suzuki K Poulose)
Date: Fri, 28 Jan 2022 16:19:48 +0000
Subject: [RFC PATCH] ACPI / amba: Skip creating amba device when
 associated cpu is not online
In-Reply-To: <136be111-c75e-48b2-caef-cbf4900b6ce1@arm.com>
References: <1641544906-7069-1-git-send-email-chenxiang66@hisilicon.com>
 <2f3c5e6b-7000-8fa2-21f7-3b0c3fb66ae3@arm.com>
 <136be111-c75e-48b2-caef-cbf4900b6ce1@arm.com>
Message-ID: <61b51d19-aad4-dd98-a1a1-8227d43fa28b@arm.com>

On 28/01/2022 15:28, Robin Murphy wrote:
> On 2022-01-28 11:00, Suzuki K Poulose wrote:
>> Hi Xiang
>>
>> On 07/01/2022 08:41, chenxiang wrote:
>>> From: Xiang Chen <chenxiang66 at hisilicon.com>
>>>
>>> If not up all the cpus with command line "maxcpus=x", system will be
>>> blocked.
>>> We find that some amba devices such as ETM devices, are associated with
>>> special cpus, and if the cpu is not up, the register of associated 
>>> device
>>> is not allowed to access. BIOS reports all the ETM device nodes and a
>>> amba device is created for every ETM device, so even if one cpu is 
>>> not up,
>>> the amba device will still be created for the associated device, and 
>>> also
>>> the register of device (pid and cid) will be accessed when adding amba
>>> device which will cause the issue.
>>> To fix it, skip creating amba device if it is associated with a cpu 
>>> which
>>> is not online.
>>
>> I understand the issue. We do not have an issue at least on DT based 
>> platforms with a similar environment (Juno). The key is the power 
>> management for the components.
>>
>> There are two separate issues at play here :
>>
>> 1) Power management with ACPI. I believe there is a solution in progress
>> to address this.
>>
>> 2) The ETM is in the same power domain as that of the CPU and normal 
>> device power management may not work without the CPU being online.
>>
>> 3) Additionally we have other issue of supporting system instructions
>> with ACPI, which do not appear on the AMBA bus.
>>
>> Considering all of these, the ideal solution is to :
>>
>> 1) Implement power management for ACPI, which is anyway in progress
>> ?? (at least for SCMI based systems)
>> 2) Move the ETM driver away from the AMBA framework. That would make
>> ??? the CPU online problem and the (3) above easier to solve.
>> ??? Anshuman is going to look into this.
>>
>> In the meantime, we could have this temporary fix in and solve it
>> forever by moving away from the AMBA.
> 
> Out of curiosity, what happens when you boot with "maxcpus=" and then 
> manually bring up the extra cpus from userspace later? Is there a chance 
> that tracing will explode if some online CPUs have ETM initialised but 
> others don't?

No. At the moment, we don't bring the ETMs online for hotplugged CPUs.
i.e., ETM is not registered for the CPU. So any attempt to trace on that
CPU will fail.

Probe deferral doesn't go beyond the userspace init. But we plan to add 
hotplug support, by defering the ETM probe.

At present, the ETMs are bound to the AMBA frame work and I am not sure
if there is a way to explicitly trigger a probe from the AMBA layer on
CPU hotplug. The other option is to always create the AMBA device and
defer the "etm" probe to a cpu hotplug notifier in the ETM driver.
This is something we plan to add.

Suzuki

> 
> Robin.
> 
>>>
>>> Signed-off-by: Xiang Chen <chenxiang66 at hisilicon.com>
>>> ---
>>> ? drivers/acpi/acpi_amba.c | 36 ++++++++++++++++++++++++++++++++++++
>>> ? 1 file changed, 36 insertions(+)
>>>
>>> diff --git a/drivers/acpi/acpi_amba.c b/drivers/acpi/acpi_amba.c
>>> index ab8a4e0191b1..2369198f734b 100644
>>> --- a/drivers/acpi/acpi_amba.c
>>> +++ b/drivers/acpi/acpi_amba.c
>>> @@ -16,6 +16,7 @@
>>> ? #include <linux/ioport.h>
>>> ? #include <linux/kernel.h>
>>> ? #include <linux/module.h>
>>> +#include <acpi/processor.h>
>>> ? #include "internal.h"
>>> @@ -45,6 +46,35 @@ static void amba_register_dummy_clk(void)
>>> ????? clk_register_clkdev(amba_dummy_clk, "apb_pclk", NULL);
>>> ? }
>>> +static int acpi_handle_to_cpuid(acpi_handle handle)
>>> +{
>>> +??? int cpu = -1;
>>> +??? struct acpi_processor *pr;
>>> +
>>> +??? for_each_possible_cpu(cpu) {
>>> +??????? pr = per_cpu(processors, cpu);
>>> +??????? if (pr && pr->handle == handle)
>>> +??????????? break;
>>> +??? }
>>> +
>>> +??? return cpu;
>>> +}
>>> +
>>
>> Please could we reuse the function in coresight-platform.c ?
>> i.e, move it to a generic location and share it, rather than
>> duplicating it ?
>>
>>
>>> +static int acpi_dev_get_cpu(struct acpi_device *adev)
>>> +{
>>> +??? acpi_handle cpu_handle;
>>> +??? acpi_status status;
>>> +??? int cpu;
>>> +
>>> +??? status = acpi_get_parent(adev->handle, &cpu_handle);
>>> +??? if (ACPI_FAILURE(status))
>>> +??????? return -1;
>>> +??? cpu = acpi_handle_to_cpuid(cpu_handle);
>>> +??? if (cpu >= nr_cpu_ids)
>>> +??????? return -1;
>>> +??? return cpu;
>>> +}
>>> +
>>> ? static int amba_handler_attach(struct acpi_device *adev,
>>> ????????????????? const struct acpi_device_id *id)
>>> ? {
>>> @@ -54,11 +84,17 @@ static int amba_handler_attach(struct acpi_device 
>>> *adev,
>>> ????? bool address_found = false;
>>> ????? int irq_no = 0;
>>> ????? int ret;
>>> +??? int cpu;
>>> ????? /* If the ACPI node already has a physical device attached, 
>>> skip it. */
>>> ????? if (adev->physical_node_count)
>>> ????????? return 0;
>>> +??? /* If the cpu associated with the device is not online, skip it. */
>>> +??? cpu = acpi_dev_get_cpu(adev);
>>> +??? if (cpu >= 0 && !cpu_online(cpu))
>>> +??????? return 0;
>>> +
>>
>> Except for the comment above, the patch looks good to me.
>>
>> Suzuki
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



From festevam at gmail.com  Fri Jan 28 08:23:43 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Fri, 28 Jan 2022 13:23:43 -0300
Subject: [PATCH] media: imx: imx8mq-mipi_csi2: Remove unneeded code
In-Reply-To: <20220128133649.1393201-1-usama.anjum@collabora.com>
References: <20220128133649.1393201-1-usama.anjum@collabora.com>
Message-ID: <CAOMZO5DaNpZbO2JS7KUOHJLAZNqpnY_ub8H_UF2sSHuQp-Ki0g@mail.gmail.com>

Hi Muhammad,

On Fri, Jan 28, 2022 at 10:38 AM Muhammad Usama Anjum
<usama.anjum at collabora.com> wrote:
>
> ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
> return error. Remove the return variable. Simplify other functions which
> are using this function.
>
> Fixes: f0c2ba1ed4ad ("media: imx: imx8mq-mipi_csi2: fix system resume")

The patch looks good.

I would suggest removing the Fixes tag though as this is more of a
clean-up rather than a bug fix.


From andriy.shevchenko at linux.intel.com  Fri Jan 28 08:26:55 2022
From: andriy.shevchenko at linux.intel.com (Andy Shevchenko)
Date: Fri, 28 Jan 2022 18:26:55 +0200
Subject: [PATCH] pinctrl: bcm2835: Fix a few error paths
In-Reply-To: <f28cba7f-6799-9f08-71b2-249a2a506913@gmail.com>
References: <20220127215033.267227-1-f.fainelli@gmail.com>
 <YfP/TuEERCrgst+k@smile.fi.intel.com>
 <f28cba7f-6799-9f08-71b2-249a2a506913@gmail.com>
Message-ID: <YfQZT3NokrgF5OQA@smile.fi.intel.com>

On Fri, Jan 28, 2022 at 08:12:02AM -0800, Florian Fainelli wrote:
> On 1/28/2022 6:35 AM, Andy Shevchenko wrote:
> > On Thu, Jan 27, 2022 at 01:50:31PM -0800, Florian Fainelli wrote:
> > > After commit 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio
> > > hogs") a few error paths would not unwind properly the registration of
> > > gpio ranges. Correct that by assigning a single error label and goto it
> > > whenever we encounter a fatal error.
> > 
> > >   1 file changed, 15 insertions(+), 8 deletions(-)
> > 
> > While this seems legit per se, my eyes caught this:
> > 
> > 
> > >   	if (!girq->parents) {
> > > -		pinctrl_remove_gpio_range(pc->pctl_dev, &pc->gpio_range);
> > > -		return -ENOMEM;
> > > +		err = -ENOMEM;
> > > +		goto out_remove;
> > 
> > Non-devm....
> > 
> > >   	}
> > >   	if (is_7211) {
> > >   		pc->wake_irq = devm_kcalloc(dev, BCM2835_NUM_IRQS,
> > >   					    sizeof(*pc->wake_irq),
> > >   					    GFP_KERNEL);
> > 
> > ...followed by devm.
> > 
> > It means more ordering bugs in the ->remove() and error path are lurking
> > around. Can you double check and be sure that we do not have a case where
> > non-devm registration code followed by devm?
> 
> It seems to me like we are fine with the patch as is, because:
> 
> - girq->parents is allocated with devm
> - pc->wake_irq is allocated with devm
> - name is allocated with devm
> 
> and those are the only variables being allocated for which we also process
> an error handling path.

Okay, thanks.

My worries that it might be the case when the GPIO ranges have been removed by
explicit call in ->remove() followed by some interrupt or so and oops or
misbehaviour because of that.

-- 
With Best Regards,
Andy Shevchenko




From chunkuang.hu at kernel.org  Fri Jan 28 08:34:18 2022
From: chunkuang.hu at kernel.org (Chun-Kuang Hu)
Date: Sat, 29 Jan 2022 00:34:18 +0800
Subject: [PATCH v1, 3/4] drm/mediatek: split postmask component
In-Reply-To: <20220128120718.30545-4-yongqiang.niu@mediatek.com>
References: <20220128120718.30545-1-yongqiang.niu@mediatek.com>
 <20220128120718.30545-4-yongqiang.niu@mediatek.com>
Message-ID: <CAAOTY_-c8CoPpT=4E9iR0fDiWfg9my=B7Oz1r4Vro80uHaGszg@mail.gmail.com>

Hi, Yongqiang:

Yongqiang Niu <yongqiang.niu at mediatek.com> ? 2022?1?28? ?? ??8:07???
>
> add postmask private data for differnt soc support
>
> Signed-off-by: Yongqiang Niu <yongqiang.niu at mediatek.com>
> ---
>  drivers/gpu/drm/mediatek/Makefile            |   1 +
>  drivers/gpu/drm/mediatek/mtk_disp_drv.h      |   8 +
>  drivers/gpu/drm/mediatek/mtk_disp_postmask.c | 155 +++++++++++++++++++
>  drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c  |  30 +---
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c       |   2 +
>  drivers/gpu/drm/mediatek/mtk_drm_drv.h       |   1 +
>  6 files changed, 170 insertions(+), 27 deletions(-)
>  create mode 100644 drivers/gpu/drm/mediatek/mtk_disp_postmask.c
>
> diff --git a/drivers/gpu/drm/mediatek/Makefile b/drivers/gpu/drm/mediatek/Makefile
> index 29098d7c8307..f26fe646ee2a 100644
> --- a/drivers/gpu/drm/mediatek/Makefile
> +++ b/drivers/gpu/drm/mediatek/Makefile
> @@ -5,6 +5,7 @@ mediatek-drm-y := mtk_disp_aal.o \
>                   mtk_disp_color.o \
>                   mtk_disp_gamma.o \
>                   mtk_disp_ovl.o \
> +                 mtk_disp_postmask.o \
>                   mtk_disp_rdma.o \
>                   mtk_drm_crtc.o \
>                   mtk_drm_ddp_comp.o \
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_drv.h b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> index 86c3068894b1..f4c21195c3ea 100644
> --- a/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_drv.h
> @@ -81,6 +81,14 @@ void mtk_ovl_enable_vblank(struct device *dev,
>                            void *vblank_cb_data);
>  void mtk_ovl_disable_vblank(struct device *dev);
>
> +int mtk_postmask_clk_enable(struct device *dev);
> +void mtk_postmask_clk_disable(struct device *dev);
> +void mtk_postmask_config(struct device *dev, unsigned int w,
> +                               unsigned int h, unsigned int vrefresh,
> +                               unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
> +void mtk_postmask_start(struct device *dev);
> +void mtk_postmask_stop(struct device *dev);
> +
>  void mtk_rdma_bypass_shadow(struct device *dev);
>  int mtk_rdma_clk_enable(struct device *dev);
>  void mtk_rdma_clk_disable(struct device *dev);
> diff --git a/drivers/gpu/drm/mediatek/mtk_disp_postmask.c b/drivers/gpu/drm/mediatek/mtk_disp_postmask.c
> new file mode 100644
> index 000000000000..fc04b445c2ed
> --- /dev/null
> +++ b/drivers/gpu/drm/mediatek/mtk_disp_postmask.c
> @@ -0,0 +1,155 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2021 MediaTek Inc.

2022

> + */
> +
> +#include <linux/clk.h>
> +#include <linux/component.h>
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +#include <linux/soc/mediatek/mtk-cmdq.h>
> +
> +#include "mtk_disp_drv.h"
> +#include "mtk_drm_crtc.h"
> +#include "mtk_drm_ddp_comp.h"
> +
> +#define DISP_POSTMASK_EN                       0x0000
> +#define POSTMASK_EN                                    BIT(0)
> +#define DISP_POSTMASK_CFG                      0x0020
> +#define POSTMASK_RELAY_MODE                            BIT(0)
> +#define DISP_POSTMASK_SIZE                     0x0030

I think you should 'move' these definition not 'copy' them, so
remember to remove them in mtk_drm_ddp_comp.c

Regards,
Chun-Kuang.

> +
> +struct mtk_disp_postmask_data {
> +       u32 reserved;
> +};
> +
> +/*
> + * struct mtk_disp_postmask - DISP_POSTMASK driver structure
> + */
> +struct mtk_disp_postmask {
> +       struct clk *clk;
> +       void __iomem *regs;
> +       struct cmdq_client_reg cmdq_reg;
> +       const struct mtk_disp_postmask_data *data;
> +};
> +


From usama.anjum at collabora.com  Fri Jan 28 08:35:27 2022
From: usama.anjum at collabora.com (Muhammad Usama Anjum)
Date: Fri, 28 Jan 2022 21:35:27 +0500
Subject: [PATCH] clk: visconti: Remove dead code
Message-ID: <20220128163527.1587325-1-usama.anjum@collabora.com>

rs_id is of unsigned type, u8. The condition rs_id >= 0 will always be
true. Remove the if-else condition and the dead code.

Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
---
 drivers/clk/visconti/clkc.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/visconti/clkc.c b/drivers/clk/visconti/clkc.c
index 56a8a4ffebca8..5ccf771d05985 100644
--- a/drivers/clk/visconti/clkc.c
+++ b/drivers/clk/visconti/clkc.c
@@ -147,13 +147,9 @@ int visconti_clk_register_gates(struct visconti_clk_provider *ctx,
 		if (!dev_name)
 			return -ENOMEM;
 
-		if (clks[i].rs_id >= 0) {
-			rson_offset = reset[clks[i].rs_id].rson_offset;
-			rsoff_offset = reset[clks[i].rs_id].rsoff_offset;
-			rs_idx = reset[clks[i].rs_id].rs_idx;
-		} else {
-			rson_offset = rsoff_offset = rs_idx = -1;
-		}
+		rson_offset = reset[clks[i].rs_id].rson_offset;
+		rsoff_offset = reset[clks[i].rs_id].rsoff_offset;
+		rs_idx = reset[clks[i].rs_id].rs_idx;
 
 		div_clk = devm_clk_hw_register_fixed_factor(dev,
 							    dev_name,
-- 
2.30.2



From daniel.lezcano at linaro.org  Fri Jan 28 08:35:37 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Fri, 28 Jan 2022 17:35:37 +0100
Subject: [PATCH v8 5/5] rockchip/soc/drivers: Add DTPM description for rk3399
In-Reply-To: <20220128163537.212248-1-daniel.lezcano@linaro.org>
References: <20220128163537.212248-1-daniel.lezcano@linaro.org>
Message-ID: <20220128163537.212248-6-daniel.lezcano@linaro.org>

The DTPM framework does support now the hierarchy description.

The platform specific code can call the hierarchy creation function
with an array of struct dtpm_node pointing to their parent.

This patch provides a description of the big / Little CPUs and the
GPU and tie them together under a virtual 'package' name. Only rk3399 is
described now.

The description could be extended in the future with the memory
controller with devfreq.

The description is always a module and it describes the soft
dependencies. The userspace has to load the softdeps module in the
right order.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
Reviewed-by; Heiko Stuebner <heiko at sntech.de>
---
Changelog:
   V8:
   - Add '/* sentinel */' in the last array entry
   - Remove Panfrost dependency in the dtpm rockchip module's Kconfig

   V7:
   - No changes

   V6:
   - Made rk3399 always as a module and added module softdeps

   V5:
   - Module creation
---
drivers/soc/rockchip/Kconfig  |  8 +++++
 drivers/soc/rockchip/Makefile |  1 +
 drivers/soc/rockchip/dtpm.c   | 59 +++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+)
 create mode 100644 drivers/soc/rockchip/dtpm.c

diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig
index 25eb2c1e31bb..156ac0e0c8fe 100644
--- a/drivers/soc/rockchip/Kconfig
+++ b/drivers/soc/rockchip/Kconfig
@@ -34,4 +34,12 @@ config ROCKCHIP_PM_DOMAINS
 
           If unsure, say N.
 
+config ROCKCHIP_DTPM
+	tristate "Rockchip DTPM hierarchy"
+	depends on DTPM && m
+	help
+	 Describe the hierarchy for the Dynamic Thermal Power
+	 Management tree on this platform. That will create all the
+	 power capping capable devices.
+
 endif
diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile
index 875032f7344e..05f31a4e743c 100644
--- a/drivers/soc/rockchip/Makefile
+++ b/drivers/soc/rockchip/Makefile
@@ -5,3 +5,4 @@
 obj-$(CONFIG_ROCKCHIP_GRF) += grf.o
 obj-$(CONFIG_ROCKCHIP_IODOMAIN) += io-domain.o
 obj-$(CONFIG_ROCKCHIP_PM_DOMAINS) += pm_domains.o
+obj-$(CONFIG_ROCKCHIP_DTPM) += dtpm.o
diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
new file mode 100644
index 000000000000..ebebb748488b
--- /dev/null
+++ b/drivers/soc/rockchip/dtpm.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2021 Linaro Limited
+ *
+ * Author: Daniel Lezcano <daniel.lezcano at linaro.org>
+ *
+ * DTPM hierarchy description
+ */
+#include <linux/dtpm.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+static struct dtpm_node __initdata rk3399_hierarchy[] = {
+	[0]{ .name = "rk3399",
+	     .type = DTPM_NODE_VIRTUAL },
+	[1]{ .name = "package",
+	     .type = DTPM_NODE_VIRTUAL,
+	     .parent = &rk3399_hierarchy[0] },
+	[2]{ .name = "/cpus/cpu at 0",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[3]{ .name = "/cpus/cpu at 1",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[4]{ .name = "/cpus/cpu at 2",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[5]{ .name = "/cpus/cpu at 3",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[6]{ .name = "/cpus/cpu at 100",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[7]{ .name = "/cpus/cpu at 101",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[8]{ .name = "/gpu at ff9a0000",
+	     .type = DTPM_NODE_DT,
+	     .parent = &rk3399_hierarchy[1] },
+	[9]{ /* sentinel */ }
+};
+
+static struct of_device_id __initdata rockchip_dtpm_match_table[] = {
+        { .compatible = "rockchip,rk3399", .data = rk3399_hierarchy },
+        {},
+};
+
+static int __init rockchip_dtpm_init(void)
+{
+	return dtpm_create_hierarchy(rockchip_dtpm_match_table);
+}
+module_init(rockchip_dtpm_init);
+
+MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
+MODULE_DESCRIPTION("Rockchip DTPM driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dtpm");
+MODULE_AUTHOR("Daniel Lezcano <daniel.lezcano at kernel.org");
-- 
2.25.1



From catalin.marinas at arm.com  Fri Jan 28 08:36:32 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 16:36:32 +0000
Subject: [PATCH v1 0/2] kselftest/arm64: Small fixes for sve-ptrace test
In-Reply-To: <20220124175527.3260234-1-broonie@kernel.org>
References: <20220124175527.3260234-1-broonie@kernel.org>
Message-ID: <164338778361.1487778.11798631924947396189.b4-ty@arm.com>

On Mon, 24 Jan 2022 17:55:25 +0000, Mark Brown wrote:
> A couple of fairly minor fixes for the sve-ptrace test, one output thing
> and one for an issue which would generate spurious false positives.
> 
> Mark Brown (2):
>   kselftest/arm64: Skip VL_INHERIT tests for unsupported vector types
>   kselftest/arm64: Correct logging of FPSIMD register read via ptrace
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[1/2] kselftest/arm64: Skip VL_INHERIT tests for unsupported vector types
      https://git.kernel.org/arm64/c/50806fd91428
[2/2] kselftest/arm64: Correct logging of FPSIMD register read via ptrace
      https://git.kernel.org/arm64/c/9ae279ecabe3

-- 
Catalin



From catalin.marinas at arm.com  Fri Jan 28 08:37:19 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 16:37:19 +0000
Subject: (subset) [PATCH 0/2] arm64: cpufeature: List early Cortex-A510
 parts as having broken dbm
In-Reply-To: <20220125154040.549272-1-james.morse@arm.com>
References: <20220125154040.549272-1-james.morse@arm.com>
Message-ID: <164338778362.1487778.4508446962917163984.b4-ty@arm.com>

On Tue, 25 Jan 2022 15:40:38 +0000, James Morse wrote:
> Early Cortex-A510 parts have broken dbm. Add them to the list of CPUs with
> broken dbm.
> 
> The SDEN is available here:
> https://developer.arm.com/documentation/SDEN2397239/900
> 
> 
> [...]

Applied to arm64 (for-next/fixes), thanks!

[2/2] arm64: cpufeature: List early Cortex-A510 parts as having broken dbm
      https://git.kernel.org/arm64/c/297ae1eb23b0

Patch 1 got into for-next/fixes via Mathieu's pull request.

-- 
Catalin



From linmq006 at gmail.com  Fri Jan 28 08:37:27 2022
From: linmq006 at gmail.com (Miaoqian Lin)
Date: Fri, 28 Jan 2022 16:37:27 +0000
Subject: [PATCH] dmaengine: owl-dma: Add missing IRQ check in owl_dma_probe
Message-ID: <20220128163728.21255-1-linmq006@gmail.com>

This func misses checking for platform_get_irq()'s call and may passes the
negative error codes to request_threaded_irq(), which takes unsigned IRQ #,
causing it to fail with -EINVAL, overriding an original error code.
Stop calling request_threaded_irq() with invalid IRQ #s.

Fixes: 47e20577c24d ("dmaengine: Add Actions Semi Owl family S900 DMA driver")
Signed-off-by: Miaoqian Lin <linmq006 at gmail.com>
---
 drivers/dma/owl-dma.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c
index 1f0bbaed4643..09cdaecee635 100644
--- a/drivers/dma/owl-dma.c
+++ b/drivers/dma/owl-dma.c
@@ -1160,6 +1160,11 @@ static int owl_dma_probe(struct platform_device *pdev)
 	 * simplification.
 	 */
 	od->irq = platform_get_irq(pdev, 0);
+	if (od->irq < 0) {
+		dev_err(&pdev->dev, "unable to get IRQ\n");
+		return od->irq;
+	}
+
 	ret = devm_request_irq(&pdev->dev, od->irq, owl_dma_interrupt, 0,
 			       dev_name(&pdev->dev), od);
 	if (ret) {
-- 
2.17.1



From catalin.marinas at arm.com  Fri Jan 28 08:43:21 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 16:43:21 +0000
Subject: [PATCH v1 1/4] arm64/mte: Document ABI for asymmetric mode
In-Reply-To: <20220127195712.748150-2-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-2-broonie@kernel.org>
Message-ID: <YfQdKTH8DEF+L5HI@arm.com>

On Thu, Jan 27, 2022 at 07:57:09PM +0000, Mark Brown wrote:
> MTE3 adds a new mode which is synchronous for writes but asynchronous for
> reads.

It's the other way around: synchronous for reads, async for writes. You
got it correctly in the doc.

> Document the userspace ABI for this feature, we call the new mode
> ASYMM and add a new prctl flag and mte_tcf_preferred value for it.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>
> ---
>  Documentation/arm64/memory-tagging-extension.rst | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
> index 7b99c8f428eb..5218b838d062 100644
> --- a/Documentation/arm64/memory-tagging-extension.rst
> +++ b/Documentation/arm64/memory-tagging-extension.rst
> @@ -76,6 +76,9 @@ configurable behaviours:
>    with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
>    address is unknown).
>  
> +- *Asymmetric* - Reads are handled as for synchronous mode while writes
> +  are handled as for asynchronous mode.

That's correct.

> +
>  The user can select the above modes, per thread, using the
>  ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
>  contains any number of the following values in the ``PR_MTE_TCF_MASK``
> @@ -85,6 +88,7 @@ bit-field:
>                           (ignored if combined with other options)
>  - ``PR_MTE_TCF_SYNC``  - *Synchronous* tag check fault mode
>  - ``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode
> +- ``PR_MTE_TCF_ASYMM`` - *Asymmetric* tag check fault mode
>  
>  If no modes are specified, tag check faults are ignored. If a single
>  mode is specified, the program will run in that mode. If multiple
> @@ -139,16 +143,14 @@ tag checking mode as the CPU's preferred tag checking mode.
>  
>  The preferred tag checking mode for each CPU is controlled by
>  ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
> -privileged user may write the value ``async`` or ``sync``.  The default
> -preferred mode for each CPU is ``async``.
> +privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
> +default preferred mode for each CPU is ``async``.

That's fine by me. It can be configured at boot for each CPU.

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan 28 08:45:40 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 16:45:40 +0000
Subject: [PATCH v1 2/4] arm64/mte: Add a little bit of documentation for
 mte_update_sctlr_user()
In-Reply-To: <20220127195712.748150-3-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-3-broonie@kernel.org>
Message-ID: <YfQdtOseBVIvD87r@arm.com>

On Thu, Jan 27, 2022 at 07:57:10PM +0000, Mark Brown wrote:
> The code isn't that obscure but it probably won't hurt to have a little
> bit more documentation for anyone trying to find out where everything
> actually takes effect.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan 28 08:51:18 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 16:51:18 +0000
Subject: [PATCH v1 3/4] arm64/mte: Add hwcap for asymmetric mode
In-Reply-To: <20220127195712.748150-4-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-4-broonie@kernel.org>
Message-ID: <YfQfBt6wsqa03J/f@arm.com>

On Thu, Jan 27, 2022 at 07:57:11PM +0000, Mark Brown wrote:
> diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
> index b72ff17d600a..a8f30963e550 100644
> --- a/Documentation/arm64/elf_hwcaps.rst
> +++ b/Documentation/arm64/elf_hwcaps.rst
> @@ -259,6 +259,11 @@ HWCAP2_RPRES
>  
>      Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
>  
> +HWCAP2_MTE3
> +
> +    Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
> +    by Documentation/arm64/memory-tagging-extension.rst.

In hindsight, we should have called the other HWCAP2_MTE2 but since we
decided not to expose MTE == 0b0001 to user, we removed the '2'. Anyway,
I'm fine with HWCAP2_MTE3.

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From vincenzo.frascino at arm.com  Fri Jan 28 08:55:32 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 28 Jan 2022 16:55:32 +0000
Subject: [PATCH v1 1/4] arm64/mte: Document ABI for asymmetric mode
In-Reply-To: <20220127195712.748150-2-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-2-broonie@kernel.org>
Message-ID: <abddfc90-54fd-9bd0-e826-0c7111f77f2e@arm.com>

Hi Mark,

On 1/27/22 7:57 PM, Mark Brown wrote:
> MTE3 adds a new mode which is synchronous for writes but asynchronous for
> reads.

MTE3 (Asymmetric Mode) is synchronous for reads and asynchronous for writes.

> Document the userspace ABI for this feature, we call the new mode
> ASYMM and add a new prctl flag and mte_tcf_preferred value for it.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

A part that:

Reviewed-by: Vincenzo Frascino <Vincenzo.Frascino at arm.com>

> ---
>  Documentation/arm64/memory-tagging-extension.rst | 12 +++++++-----
>  1 file changed, 7 insertions(+), 5 deletions(-)
> 
> diff --git a/Documentation/arm64/memory-tagging-extension.rst b/Documentation/arm64/memory-tagging-extension.rst
> index 7b99c8f428eb..5218b838d062 100644
> --- a/Documentation/arm64/memory-tagging-extension.rst
> +++ b/Documentation/arm64/memory-tagging-extension.rst
> @@ -76,6 +76,9 @@ configurable behaviours:
>    with ``.si_code = SEGV_MTEAERR`` and ``.si_addr = 0`` (the faulting
>    address is unknown).
>  
> +- *Asymmetric* - Reads are handled as for synchronous mode while writes
> +  are handled as for asynchronous mode.
> +
>  The user can select the above modes, per thread, using the
>  ``prctl(PR_SET_TAGGED_ADDR_CTRL, flags, 0, 0, 0)`` system call where ``flags``
>  contains any number of the following values in the ``PR_MTE_TCF_MASK``
> @@ -85,6 +88,7 @@ bit-field:
>                           (ignored if combined with other options)
>  - ``PR_MTE_TCF_SYNC``  - *Synchronous* tag check fault mode
>  - ``PR_MTE_TCF_ASYNC`` - *Asynchronous* tag check fault mode
> +- ``PR_MTE_TCF_ASYMM`` - *Asymmetric* tag check fault mode
>  
>  If no modes are specified, tag check faults are ignored. If a single
>  mode is specified, the program will run in that mode. If multiple
> @@ -139,16 +143,14 @@ tag checking mode as the CPU's preferred tag checking mode.
>  
>  The preferred tag checking mode for each CPU is controlled by
>  ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
> -privileged user may write the value ``async`` or ``sync``.  The default
> -preferred mode for each CPU is ``async``.
> +privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
> +default preferred mode for each CPU is ``async``.
>  
>  To allow a program to potentially run in the CPU's preferred tag
>  checking mode, the user program may set multiple tag check fault mode
>  bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL,
>  flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking
> -mode is in the task's set of provided tag checking modes (this will
> -always be the case at present because the kernel only supports two
> -tag checking modes, but future kernels may support more modes), that
> +mode is in the task's set of provided tag checking modes, that
>  mode will be selected. Otherwise, one of the modes in the task's mode
>  set will be selected in a currently unspecified manner.
>  
> 

-- 
Regards,
Vincenzo


From vincenzo.frascino at arm.com  Fri Jan 28 08:57:12 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 28 Jan 2022 16:57:12 +0000
Subject: [PATCH v1 2/4] arm64/mte: Add a little bit of documentation for
 mte_update_sctlr_user()
In-Reply-To: <20220127195712.748150-3-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-3-broonie@kernel.org>
Message-ID: <f1a6d996-149b-71fb-0901-90deb838a47a@arm.com>



On 1/27/22 7:57 PM, Mark Brown wrote:
> The code isn't that obscure but it probably won't hurt to have a little
> bit more documentation for anyone trying to find out where everything
> actually takes effect.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Reviewed-by: Vincenzo Frascino <Vincenzo.Frascino at arm.com>

> ---
>  arch/arm64/kernel/mte.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index f418ebc65f95..fa4001fee12a 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -186,6 +186,11 @@ void mte_check_tfsr_el1(void)
>  }
>  #endif
>  
> +/*
> + * This is where we actually resolve the system and process MTE mode
> + * configuration into an actual value in SCTLR_EL1 that affects
> + * userspace.
> + */
>  static void mte_update_sctlr_user(struct task_struct *task)
>  {
>  	/*
> @@ -199,8 +204,17 @@ static void mte_update_sctlr_user(struct task_struct *task)
>  	unsigned long pref, resolved_mte_tcf;
>  
>  	pref = __this_cpu_read(mte_tcf_preferred);
> +	/*
> +	 * If there is no overlap between the system preferred and
> +	 * program requested values go with what was requested.
> +	 */
>  	resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl;
>  	sctlr &= ~SCTLR_EL1_TCF0_MASK;
> +	/*
> +	 * Pick an actual setting. The order in which we check for
> +	 * set bits and map into register values determines our
> +	 * default order.
> +	 */
>  	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
>  		sctlr |= SCTLR_EL1_TCF0_ASYNC;
>  	else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
> 

-- 
Regards,
Vincenzo


From nfraprado at collabora.com  Fri Jan 28 08:58:09 2022
From: nfraprado at collabora.com (=?utf-8?B?TsOtY29sYXMgRi4gUi4gQS4=?= Prado)
Date: Fri, 28 Jan 2022 11:58:09 -0500
Subject: [PATCH] soc: mediatek: mt8192-mmsys: Fix dither to dsi0 path's
 input sel
In-Reply-To: <20220128142056.359900-1-angelogioacchino.delregno@collabora.com>
References: <20220128142056.359900-1-angelogioacchino.delregno@collabora.com>
Message-ID: <20220128165809.ir2x5ghynw22xki7@notapiano>

On Fri, Jan 28, 2022 at 03:20:56PM +0100, AngeloGioacchino Del Regno wrote:
> In commit d687e056a18f ("soc: mediatek: mmsys: Add mt8192 mmsys routing table"),
> the mmsys routing table for mt8192 was introduced but the input selector
> for DITHER->DSI0 has no value assigned to it.
> 
> This means that we are clearing bit 0 instead of setting it, blocking
> communication between these two blocks; due to that, any display that
> is connected to DSI0 will not work, as no data will go through.
> The effect of that issue is that, during bootup, the DRM will block for
> some time, while atomically waiting for a vblank that never happens;
> later, the situation doesn't get better, leaving the display in a
> non-functional state.
> 
> To fix this issue, fix the route entry in the table by assigning the
> dither input selector to MT8192_DISP_DSI0_SEL_IN.
> 
> Fixes: d687e056a18f ("soc: mediatek: mmsys: Add mt8192 mmsys routing table")
> Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>

Reviewed-by: N?colas F. R. A. Prado <nfraprado at collabora.com>

> ---
>  drivers/soc/mediatek/mt8192-mmsys.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/mediatek/mt8192-mmsys.h b/drivers/soc/mediatek/mt8192-mmsys.h
> index 6f0a57044a7b..6aae0b12b6ff 100644
> --- a/drivers/soc/mediatek/mt8192-mmsys.h
> +++ b/drivers/soc/mediatek/mt8192-mmsys.h
> @@ -53,7 +53,8 @@ static const struct mtk_mmsys_routes mmsys_mt8192_routing_table[] = {
>  		MT8192_AAL0_SEL_IN_CCORR0
>  	}, {
>  		DDP_COMPONENT_DITHER, DDP_COMPONENT_DSI0,
> -		MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0
> +		MT8192_DISP_DSI0_SEL_IN, MT8192_DSI0_SEL_IN_DITHER0,
> +		MT8192_DSI0_SEL_IN_DITHER0
>  	}, {
>  		DDP_COMPONENT_RDMA0, DDP_COMPONENT_COLOR0,
>  		MT8192_DISP_RDMA0_SOUT_SEL, MT8192_RDMA0_SOUT_COLOR0,
> -- 
> 2.33.1
> 
> 
> -- 
> To unsubscribe, send mail to kernel-unsubscribe at lists.collabora.co.uk.


From vincenzo.frascino at arm.com  Fri Jan 28 09:00:59 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 28 Jan 2022 17:00:59 +0000
Subject: [PATCH v1 3/4] arm64/mte: Add hwcap for asymmetric mode
In-Reply-To: <20220127195712.748150-4-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-4-broonie@kernel.org>
Message-ID: <a55a1e97-b8e9-16b4-c7a4-608b8be7052e@arm.com>



On 1/27/22 7:57 PM, Mark Brown wrote:
> Allow userspace to detect support for asymmetric mode by providing a hwcap
> for it, using the official feature name FEAT_MTE3.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Reviewed-by: Vincenzo Frascino <Vincenzo.Frascino at arm.com>

> ---
>  Documentation/arm64/elf_hwcaps.rst  | 5 +++++
>  arch/arm64/include/asm/hwcap.h      | 1 +
>  arch/arm64/include/uapi/asm/hwcap.h | 1 +
>  arch/arm64/kernel/cpufeature.c      | 1 +
>  arch/arm64/kernel/cpuinfo.c         | 1 +
>  5 files changed, 9 insertions(+)
> 
> diff --git a/Documentation/arm64/elf_hwcaps.rst b/Documentation/arm64/elf_hwcaps.rst
> index b72ff17d600a..a8f30963e550 100644
> --- a/Documentation/arm64/elf_hwcaps.rst
> +++ b/Documentation/arm64/elf_hwcaps.rst
> @@ -259,6 +259,11 @@ HWCAP2_RPRES
>  
>      Functionality implied by ID_AA64ISAR2_EL1.RPRES == 0b0001.
>  
> +HWCAP2_MTE3
> +
> +    Functionality implied by ID_AA64PFR1_EL1.MTE == 0b0011, as described
> +    by Documentation/arm64/memory-tagging-extension.rst.
> +
>  4. Unused AT_HWCAP bits
>  -----------------------
>  
> diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h
> index f68fbb207473..8db5ec0089db 100644
> --- a/arch/arm64/include/asm/hwcap.h
> +++ b/arch/arm64/include/asm/hwcap.h
> @@ -108,6 +108,7 @@
>  #define KERNEL_HWCAP_ECV		__khwcap2_feature(ECV)
>  #define KERNEL_HWCAP_AFP		__khwcap2_feature(AFP)
>  #define KERNEL_HWCAP_RPRES		__khwcap2_feature(RPRES)
> +#define KERNEL_HWCAP_MTE3		__khwcap2_feature(MTE3)
>  
>  /*
>   * This yields a mask that user programs can use to figure out what
> diff --git a/arch/arm64/include/uapi/asm/hwcap.h b/arch/arm64/include/uapi/asm/hwcap.h
> index f03731847d9d..99cb5d383048 100644
> --- a/arch/arm64/include/uapi/asm/hwcap.h
> +++ b/arch/arm64/include/uapi/asm/hwcap.h
> @@ -78,5 +78,6 @@
>  #define HWCAP2_ECV		(1 << 19)
>  #define HWCAP2_AFP		(1 << 20)
>  #define HWCAP2_RPRES		(1 << 21)
> +#define HWCAP2_MTE3		(1 << 22)
>  
>  #endif /* _UAPI__ASM_HWCAP_H */
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index a46ab3b1c4d5..57de3f3e0518 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -2485,6 +2485,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
>  #endif
>  #ifdef CONFIG_ARM64_MTE
>  	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE, CAP_HWCAP, KERNEL_HWCAP_MTE),
> +	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_MTE_ASYMM, CAP_HWCAP, KERNEL_HWCAP_MTE3),
>  #endif /* CONFIG_ARM64_MTE */
>  	HWCAP_CAP(SYS_ID_AA64MMFR0_EL1, ID_AA64MMFR0_ECV_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_ECV),
>  	HWCAP_CAP(SYS_ID_AA64MMFR1_EL1, ID_AA64MMFR1_AFP_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, KERNEL_HWCAP_AFP),
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 591c18a889a5..330b92ea863a 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -97,6 +97,7 @@ static const char *const hwcap_str[] = {
>  	[KERNEL_HWCAP_ECV]		= "ecv",
>  	[KERNEL_HWCAP_AFP]		= "afp",
>  	[KERNEL_HWCAP_RPRES]		= "rpres",
> +	[KERNEL_HWCAP_MTE3]		= "mte3",
>  };
>  
>  #ifdef CONFIG_COMPAT
> 

-- 
Regards,
Vincenzo


From usama.anjum at collabora.com  Fri Jan 28 09:01:03 2022
From: usama.anjum at collabora.com (Muhammad Usama Anjum)
Date: Fri, 28 Jan 2022 22:01:03 +0500
Subject: [PATCH] media: imx: imx8mq-mipi_csi2: Remove unneeded code
In-Reply-To: <CAOMZO5DaNpZbO2JS7KUOHJLAZNqpnY_ub8H_UF2sSHuQp-Ki0g@mail.gmail.com>
References: <20220128133649.1393201-1-usama.anjum@collabora.com>
 <CAOMZO5DaNpZbO2JS7KUOHJLAZNqpnY_ub8H_UF2sSHuQp-Ki0g@mail.gmail.com>
Message-ID: <ab0b6146-d8ab-b9f5-4dea-99849a0f5ee4@collabora.com>


On 1/28/22 9:23 PM, Fabio Estevam wrote:
> Hi Muhammad,
> 
> On Fri, Jan 28, 2022 at 10:38 AM Muhammad Usama Anjum
> <usama.anjum at collabora.com> wrote:
>>
>> ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
>> return error. Remove the return variable. Simplify other functions which
>> are using this function.
>>
>> Fixes: f0c2ba1ed4ad ("media: imx: imx8mq-mipi_csi2: fix system resume")
> 
> The patch looks good.
> 
> I would suggest removing the Fixes tag though as this is more of a
> clean-up rather than a bug fix.
I'll send a V2.

Thanks,
Usama


From usama.anjum at collabora.com  Fri Jan 28 09:07:22 2022
From: usama.anjum at collabora.com (Muhammad Usama Anjum)
Date: Fri, 28 Jan 2022 22:07:22 +0500
Subject: [PATCH V2] media: imx: imx8mq-mipi_csi2: Remove unneeded code
Message-ID: <20220128170722.1624767-1-usama.anjum@collabora.com>

ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
return error. Remove the return variable. Simplify other functions which
are using this function.

Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
---
Changes in V2:
Removed fixes tag
---
 drivers/staging/media/imx/imx8mq-mipi-csi2.c | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/media/imx/imx8mq-mipi-csi2.c b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
index 3b9fa75efac6b..c992b845e63d1 100644
--- a/drivers/staging/media/imx/imx8mq-mipi-csi2.c
+++ b/drivers/staging/media/imx/imx8mq-mipi-csi2.c
@@ -693,11 +693,10 @@ static int imx8mq_mipi_csi_async_register(struct csi_state *state)
  * Suspend/resume
  */
 
-static int imx8mq_mipi_csi_pm_suspend(struct device *dev)
+static void imx8mq_mipi_csi_pm_suspend(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
-	int ret = 0;
 
 	mutex_lock(&state->lock);
 
@@ -708,8 +707,6 @@ static int imx8mq_mipi_csi_pm_suspend(struct device *dev)
 	}
 
 	mutex_unlock(&state->lock);
-
-	return ret ? -EAGAIN : 0;
 }
 
 static int imx8mq_mipi_csi_pm_resume(struct device *dev)
@@ -742,15 +739,12 @@ static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
 {
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
-	int ret;
 
-	ret = imx8mq_mipi_csi_pm_suspend(dev);
-	if (ret)
-		return ret;
+	imx8mq_mipi_csi_pm_suspend(dev);
 
 	state->state |= ST_SUSPENDED;
 
-	return ret;
+	return 0;
 }
 
 static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev)
@@ -770,9 +764,7 @@ static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev)
 	struct csi_state *state = mipi_sd_to_csi2_state(sd);
 	int ret;
 
-	ret = imx8mq_mipi_csi_pm_suspend(dev);
-	if (ret)
-		return ret;
+	imx8mq_mipi_csi_pm_suspend(dev);
 
 	ret = icc_set_bw(state->icc_path, 0, 0);
 	if (ret)
-- 
2.30.2



From vincenzo.frascino at arm.com  Fri Jan 28 09:12:20 2022
From: vincenzo.frascino at arm.com (Vincenzo Frascino)
Date: Fri, 28 Jan 2022 17:12:20 +0000
Subject: [PATCH v1 4/4] arm64/mte: Add userspace interface for enabling
 asymmetric mode
In-Reply-To: <20220127195712.748150-5-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-5-broonie@kernel.org>
Message-ID: <a665c786-530d-aada-0f82-f297cda35353@arm.com>



On 1/27/22 7:57 PM, Mark Brown wrote:
> The architecture provides an asymmetric mode for MTE where tag mismatches
> are checked asynchronously for reads but synchronously for loads. 

MTE3 checks synchronously the reads and asynchronously the writes.

Nit: Please use load/store or read/write.


> Allow userspace processes to select this and make it available as a default mode
> via the existing per-CPU sysfs interface.
> 
> Since there PR_MTE_TCF_ values are a bitmask (allowing the kernel to choose
> between the multiple modes) and there are no free bits adjacent to the
> existing PR_MTE_TCF_ bits the set of bits used to specify the mode becomes
> disjoint. Programs using the new interface should be aware of this and
> programs that do not use it will not see any change in behaviour.
> > When userspace requests two possible modes but the system default for the
> CPU is the third mode (eg, default is synchronous but userspace requests
> either asynchronous or asymmetric) the preference order is:
> 
>    ASYMM > ASYNC > SYNC
> 
> This situation is not currently possible since there are only two modes and
> it is mandatory to have a system default so there could be no ambiguity and
> there is no ABI change. The chosen order is basically arbitrary as we do not
> have a clear metric for what is better here.
> 
> If userspace requests specifically asymmetric mode via the prctl() and the
> system does not support it then we will return an error, this mirrors
> how we handle the case where userspace enables MTE on a system that does
> not support MTE at all and the behaviour that will be seen if running on
> an older kernel that does not support userspace use of asymmetric mode.
> 
> Attempts to set asymmetric mode as the default mode will result in an error
> if the system does not support it.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Otherwise:

Reviewed-by: Vincenzo Frascino <Vincenzo.Frascino at arm.com>

> ---
>  arch/arm64/include/asm/processor.h |  1 +
>  arch/arm64/kernel/mte.c            | 12 +++++++++++-
>  arch/arm64/kernel/process.c        |  5 ++++-
>  include/uapi/linux/prctl.h         |  4 +++-
>  4 files changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index 6f41b65f9962..73e38d9a540c 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -21,6 +21,7 @@
>  
>  #define MTE_CTRL_TCF_SYNC		(1UL << 16)
>  #define MTE_CTRL_TCF_ASYNC		(1UL << 17)
> +#define MTE_CTRL_TCF_ASYMM		(1UL << 18)
>  
>  #ifndef __ASSEMBLY__
>  
> diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
> index fa4001fee12a..fb777d8fea32 100644
> --- a/arch/arm64/kernel/mte.c
> +++ b/arch/arm64/kernel/mte.c
> @@ -215,7 +215,9 @@ static void mte_update_sctlr_user(struct task_struct *task)
>  	 * set bits and map into register values determines our
>  	 * default order.
>  	 */
> -	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
> +	if (resolved_mte_tcf & MTE_CTRL_TCF_ASYMM)
> +		sctlr |= SCTLR_EL1_TCF0_ASYMM;
> +	else if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC)
>  		sctlr |= SCTLR_EL1_TCF0_ASYNC;
>  	else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC)
>  		sctlr |= SCTLR_EL1_TCF0_SYNC;
> @@ -306,6 +308,8 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
>  		mte_ctrl |= MTE_CTRL_TCF_ASYNC;
>  	if (arg & PR_MTE_TCF_SYNC)
>  		mte_ctrl |= MTE_CTRL_TCF_SYNC;
> +	if (arg & PR_MTE_TCF_ASYMM)
> +		mte_ctrl |= MTE_CTRL_TCF_ASYMM;
>  
>  	task->thread.mte_ctrl = mte_ctrl;
>  	if (task == current) {
> @@ -334,6 +338,8 @@ long get_mte_ctrl(struct task_struct *task)
>  		ret |= PR_MTE_TCF_ASYNC;
>  	if (mte_ctrl & MTE_CTRL_TCF_SYNC)
>  		ret |= PR_MTE_TCF_SYNC;
> +	if (mte_ctrl & MTE_CTRL_TCF_ASYMM)
> +		ret |= PR_MTE_TCF_ASYMM;
>  
>  	return ret;
>  }
> @@ -481,6 +487,8 @@ static ssize_t mte_tcf_preferred_show(struct device *dev,
>  		return sysfs_emit(buf, "async\n");
>  	case MTE_CTRL_TCF_SYNC:
>  		return sysfs_emit(buf, "sync\n");
> +	case MTE_CTRL_TCF_ASYMM:
> +		return sysfs_emit(buf, "asymm\n");
>  	default:
>  		return sysfs_emit(buf, "???\n");
>  	}
> @@ -496,6 +504,8 @@ static ssize_t mte_tcf_preferred_store(struct device *dev,
>  		tcf = MTE_CTRL_TCF_ASYNC;
>  	else if (sysfs_streq(buf, "sync"))
>  		tcf = MTE_CTRL_TCF_SYNC;
> +	else if (cpus_have_cap(ARM64_MTE_ASYMM) && sysfs_streq(buf, "asymm"))
> +		tcf = MTE_CTRL_TCF_ASYMM;
>  	else
>  		return -EINVAL;
>  
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 5369e649fa79..941cfa7117b9 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -635,7 +635,10 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)
>  		return -EINVAL;
>  
>  	if (system_supports_mte())
> -		valid_mask |= PR_MTE_TCF_MASK | PR_MTE_TAG_MASK;
> +		valid_mask |= PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC \
> +			| PR_MTE_TAG_MASK;
> +	if (cpus_have_cap(ARM64_MTE_ASYMM))
> +		valid_mask |= PR_MTE_TCF_ASYMM;
>  
>  	if (arg & ~valid_mask)
>  		return -EINVAL;
> diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
> index e998764f0262..4ae2b21e4066 100644
> --- a/include/uapi/linux/prctl.h
> +++ b/include/uapi/linux/prctl.h
> @@ -238,7 +238,9 @@ struct prctl_mm_map {
>  # define PR_MTE_TCF_NONE		0UL
>  # define PR_MTE_TCF_SYNC		(1UL << 1)
>  # define PR_MTE_TCF_ASYNC		(1UL << 2)
> -# define PR_MTE_TCF_MASK		(PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC)
> +# define PR_MTE_TCF_ASYMM		(1UL << 19)
> +# define PR_MTE_TCF_MASK		(PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | \
> +					 PR_MTE_TCF_ASYMM)
>  /* MTE tag inclusion mask */
>  # define PR_MTE_TAG_SHIFT		3
>  # define PR_MTE_TAG_MASK		(0xffffUL << PR_MTE_TAG_SHIFT)
> 

-- 
Regards,
Vincenzo


From catalin.marinas at arm.com  Fri Jan 28 09:15:14 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 17:15:14 +0000
Subject: [PATCH v1 4/4] arm64/mte: Add userspace interface for enabling
 asymmetric mode
In-Reply-To: <20220127195712.748150-5-broonie@kernel.org>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-5-broonie@kernel.org>
Message-ID: <YfQkotjUykKW93tb@arm.com>

On Thu, Jan 27, 2022 at 07:57:12PM +0000, Mark Brown wrote:
> The architecture provides an asymmetric mode for MTE where tag mismatches
> are checked asynchronously for reads but synchronously for loads. Allow
> userspace processes to select this and make it available as a default mode
> via the existing per-CPU sysfs interface.
> 
> Since there PR_MTE_TCF_ values are a bitmask (allowing the kernel to choose
> between the multiple modes) and there are no free bits adjacent to the
> existing PR_MTE_TCF_ bits the set of bits used to specify the mode becomes
> disjoint. Programs using the new interface should be aware of this and
> programs that do not use it will not see any change in behaviour.
> 
> When userspace requests two possible modes but the system default for the
> CPU is the third mode (eg, default is synchronous but userspace requests
> either asynchronous or asymmetric) the preference order is:
> 
>    ASYMM > ASYNC > SYNC
> 
> This situation is not currently possible since there are only two modes and
> it is mandatory to have a system default so there could be no ambiguity and
> there is no ABI change. The chosen order is basically arbitrary as we do not
> have a clear metric for what is better here.
> 
> If userspace requests specifically asymmetric mode via the prctl() and the
> system does not support it then we will return an error, this mirrors
> how we handle the case where userspace enables MTE on a system that does
> not support MTE at all and the behaviour that will be seen if running on
> an older kernel that does not support userspace use of asymmetric mode.
> 
> Attempts to set asymmetric mode as the default mode will result in an error
> if the system does not support it.
> 
> Signed-off-by: Mark Brown <broonie at kernel.org>

Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>


From catalin.marinas at arm.com  Fri Jan 28 09:16:58 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 17:16:58 +0000
Subject: [GIT PULL] coresight: trbe: Workaround Cortex-A510 erratas
In-Reply-To: <20220127202029.2195073-1-mathieu.poirier@linaro.org>
References: <20220127202029.2195073-1-mathieu.poirier@linaro.org>
Message-ID: <YfQlCncQRuRXWXMR@arm.com>

On Thu, Jan 27, 2022 at 01:20:29PM -0700, Mathieu Poirier wrote:
> The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:
> 
>   Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)
> 
> are available in the Git repository at:
> 
>   git at gitolite.kernel.org:pub/scm/linux/kernel/git/coresight/linux.git tags/trbe-cortex-a510-errata
> 
> for you to fetch changes up to 708e8af4924ec2fdd5b81fe09192c6bac2f86935:
> 
>   arm64: errata: Add detection for TRBE trace data corruption (2022-01-27 12:01:53 -0700)

Pulled into the arm64 for-next/fixes branch. Thanks.

-- 
Catalin


From linux at roeck-us.net  Fri Jan 28 09:20:03 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Fri, 28 Jan 2022 09:20:03 -0800
Subject: [BUG] pinctrl: reg-fixed-voltage usb0-vbus: error -EINVAL: can't
 get GPIO
In-Reply-To: <2f82dbe8-50d6-d905-9065-d3869948aa06@xs4all.nl>
References: <Yea3rBmY+MO4AhhV@Red>
 <2f82dbe8-50d6-d905-9065-d3869948aa06@xs4all.nl>
Message-ID: <20220128172003.GA2666058@roeck-us.net>

On Tue, Jan 18, 2022 at 03:13:20PM +0100, Hans Verkuil wrote:
> On 1/18/22 13:50, Corentin Labbe wrote:
> > Hello
> > 
> > As reported on old googlegroup sunxi mainling list, on linux-next-20220118, USB storage fail to bring up on orangepiPC.
> > We can see some error logs in dmesg:
> > reg-fixed-voltage usb0-vbus: error -EINVAL: can't get GPIO
> > reg-fixed-voltage: probe of usb0-vbus failed with error -22
> > 
> > This is bisected to: 8df89a7cbc63c7598c00611ad17b67e8d5b4fad3 pinctrl-sunxi: don't call pinctrl_gpio_direction()
> > 
> > Reverting this commit lead to a working USB storage being setuped.
> 
> Hmm, I'll bet it's EPROBE_DEFER related.
> 

No. For me the problem is only seen if I try to boot from the second usb
interface with the orangepi-pc qemu emulation, but not when I try to boot
from the first usb interface. That alone makes it unlikely to be an
EPROBE_DEFER related problem.

Some debugging with your code in the tree:

[    7.076227] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=10, input=0
[    7.076567] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pinctrl_gpio_direction_output: offset=10, value=1, ret=-22
[    7.076992] leds-gpio: probe of leds failed with error -22
[    7.081645] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=2, input=0
[    7.081887] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pinctrl_gpio_direction_output: offset=2, value=0, ret=-22
[    7.082424] reg-fixed-voltage usb0-vbus: error -EINVAL: can't get GPIO
[    7.082793] reg-fixed-voltage: probe of usb0-vbus failed with error -22
[    7.129355] sun8i-h3-pinctrl 1c20800.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=166, input=1
[    7.129844] sun8i-h3-pinctrl 1c20800.pinctrl: ######### sunxi_pinctrl_gpio_direction_input: offset=166, ret=0
[    7.130788] sunxi-mmc 1c0f000.mmc: Got CD GPIO
[    7.169391] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=3, input=1
[    7.169663] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ######### sunxi_pinctrl_gpio_direction_input: offset=3, ret=-22
[    7.170054] gpio-keys r_gpio_keys: failed to get gpio: -22
[    7.170262] gpio-keys: probe of r_gpio_keys failed with error -22

And after reverting it:

[    6.138097] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=362, input=0
[    6.138375] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pinctrl_gpio_direction_output: offset=10, value=1, ret=0
[    6.140762] sun8i-h3-pinctrl 1c20800.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=15, input=0
[    6.140918] sun8i-h3-pinctrl 1c20800.pinctrl: ########### sunxi_pinctrl_gpio_direction_output: offset=15, value=0, ret=0
[    6.142808] sun8i-h3-pinctrl 1c20800.pinctrl: supply vcc-pf not found, using dummy regulator
[    6.148879] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=354, input=0
[    6.149086] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pinctrl_gpio_direction_output: offset=2, value=0, ret=0
[    6.154485] sun8i-h3-pinctrl 1c20800.pinctrl: supply vcc-pg not found, using dummy regulator
[    6.155657] sun8i-h3-pinctrl 1c20800.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=204, input=1
[    6.155853] sun8i-h3-pinctrl 1c20800.pinctrl: ######### sunxi_pinctrl_gpio_direction_input: offset=204, ret=0
[    6.174411] ehci-platform 1c1b000.usb: EHCI Host Controller
[    6.174737] ehci-platform 1c1b000.usb: new USB bus registered, assigned bus number 3
[    6.188776] sun8i-h3-pinctrl 1c20800.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=166, input=1
[    6.189149] sun8i-h3-pinctrl 1c20800.pinctrl: ######### sunxi_pinctrl_gpio_direction_input: offset=166, ret=0
[    6.189720] sunxi-mmc 1c0f000.mmc: Got CD GPIO
...
[    6.674660] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ########### sunxi_pmx_gpio_set_direction: offset=355, input=1
[    6.674796] sun8i-h3-r-pinctrl 1f02c00.pinctrl: ######### sunxi_pinctrl_gpio_direction_input: offset=3, ret=0

In other words, there is some offset translation missing with your patch,
causing -EINVAL returns.

Guenter


From german.gomez at arm.com  Fri Jan 28 09:20:23 2022
From: german.gomez at arm.com (German Gomez)
Date: Fri, 28 Jan 2022 17:20:23 +0000
Subject: [PATCH 2/2] perf arm-spe: Parse more SPE fields and store source
In-Reply-To: <20220125192016.20538-3-alisaidi@amazon.com>
References: <20220125192016.20538-1-alisaidi@amazon.com>
 <20220125192016.20538-3-alisaidi@amazon.com>
Message-ID: <b1b3697d-4a0a-d041-5cbd-e08fec9e658c@arm.com>

Hi Ali,

On 25/01/2022 19:20, Ali Saidi wrote:
> Decode more SPE events and op types to allow for processing by perf
> scripts. For example looking for branches which may indicate candidates
> for conversion to a CSEL, store exclusives that are candidates for
> conversion to LSE atomics and record the source information for memory
> ops.
>
> Signed-off-by: Ali Saidi <alisaidi at amazon.com>
> ---
>  .../util/arm-spe-decoder/arm-spe-decoder.c     | 18 ++++++++++++++++++
>  .../util/arm-spe-decoder/arm-spe-decoder.h     |  8 ++++++++
>  2 files changed, 26 insertions(+)
>
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
> index 5e390a1a79ab..177bac0f7128 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
> @@ -191,6 +191,20 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
>  					decoder->record.op = ARM_SPE_ST;
>  				else
>  					decoder->record.op = ARM_SPE_LD;
> +				if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
> +					if (payload & SPE_OP_PKT_AT)
> +						decoder->record.op |= ARM_SPE_LDST_ATOMIC;

In "utils/arm-spe.c" we check "if (record->op == ARM_SPE_LD)" so this
ORing could break some of the generated samples.

> +					if (payload & SPE_OP_PKT_EXCL)
> +						decoder->record.op |= ARM_SPE_LDST_EXCL;
> +					if (payload & SPE_OP_PKT_AR)
> +						decoder->record.op |= ARM_SPE_LDST_ACQREL;
> +				}
> +			} else if (idx == SPE_OP_PKT_HDR_CLASS_BR_ERET) {
> +				decoder->record.op = ARM_SPE_BR;
> +				if (payload & SPE_OP_PKT_COND)
> +					decoder->record.op |= ARM_SPE_BR_COND;
> +				if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload))
> +					decoder->record.op |= ARM_SPE_BR_IND;
>  			}
>  			break;
>  		case ARM_SPE_EVENTS:
> @@ -218,8 +232,12 @@ static int arm_spe_read_record(struct arm_spe_decoder *decoder)
>  			if (payload & BIT(EV_MISPRED))
>  				decoder->record.type |= ARM_SPE_BRANCH_MISS;
>  
> +			if (payload & BIT(EV_NOT_TAKEN))
> +				decoder->record.type |= ARM_SPE_BR_NOT_TAKEN;
> +
>  			break;
>  		case ARM_SPE_DATA_SOURCE:
> +			decoder->record.source = payload;
>  			break;
>  		case ARM_SPE_BAD:
>  			break;
> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> index 69b31084d6be..113e427afe99 100644
> --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
> @@ -22,11 +22,18 @@ enum arm_spe_sample_type {
>  	ARM_SPE_TLB_MISS	= 1 << 5,
>  	ARM_SPE_BRANCH_MISS	= 1 << 6,
>  	ARM_SPE_REMOTE_ACCESS	= 1 << 7,
> +	ARM_SPE_BR_NOT_TAKEN	= 1 << 8,

Can you rename it to ARM_SPE_BRANCH_NOT_TAKEN for consistency?

>  };
>  
>  enum arm_spe_op_type {
>  	ARM_SPE_LD		= 1 << 0,
>  	ARM_SPE_ST		= 1 << 1,
> +	ARM_SPE_LDST_EXCL	= 1 << 2,
> +	ARM_SPE_LDST_ATOMIC	= 1 << 3,
> +	ARM_SPE_LDST_ACQREL	= 1 << 4,
> +	ARM_SPE_BR		= 1 << 5,
> +	ARM_SPE_BR_COND		= 1 << 6,
> +	ARM_SPE_BR_IND		= 1 << 7,

I'm not sure if we should keep everything in one enum/bitmask. I'm also
looking at adding more of the data from the packets to the record, and
considering refactoring the record structure. I'll share here when I
have something.

Thanks,
German

>  };
>  
>  struct arm_spe_record {
> @@ -40,6 +47,7 @@ struct arm_spe_record {
>  	u64 virt_addr;
>  	u64 phys_addr;
>  	u64 context_id;
> +	u16 source;
>  };
>  
>  struct arm_spe_insn;


From broonie at kernel.org  Fri Jan 28 09:23:16 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 17:23:16 +0000
Subject: [PATCH v1 1/4] arm64/mte: Document ABI for asymmetric mode
In-Reply-To: <YfQdKTH8DEF+L5HI@arm.com>
References: <20220127195712.748150-1-broonie@kernel.org>
 <20220127195712.748150-2-broonie@kernel.org>
 <YfQdKTH8DEF+L5HI@arm.com>
Message-ID: <YfQmhMHQ9EOqN94H@sirena.org.uk>

On Fri, Jan 28, 2022 at 04:43:21PM +0000, Catalin Marinas wrote:
> On Thu, Jan 27, 2022 at 07:57:09PM +0000, Mark Brown wrote:

> > MTE3 adds a new mode which is synchronous for writes but asynchronous for
> > reads.

> It's the other way around: synchronous for reads, async for writes. You
> got it correctly in the doc.

Doh.  See, I know that the way to get fast review is to make some
obvious error which someone can point out :P

> >  The preferred tag checking mode for each CPU is controlled by
> >  ``/sys/devices/system/cpu/cpu<N>/mte_tcf_preferred``, to which a
> > -privileged user may write the value ``async`` or ``sync``.  The default
> > -preferred mode for each CPU is ``async``.
> > +privileged user may write the value ``async``, ``sync`` or ``asymm``.  The
> > +default preferred mode for each CPU is ``async``.
> 
> That's fine by me. It can be configured at boot for each CPU.
> 
> Reviewed-by: Catalin Marinas <catalin.marinas at arm.com>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/673071d0/attachment-0001.sig>

From paulmck at kernel.org  Fri Jan 28 09:47:23 2022
From: paulmck at kernel.org (Paul E. McKenney)
Date: Fri, 28 Jan 2022 09:47:23 -0800
Subject: ftrace hangs waiting for rcu
In-Reply-To: <20220128161547.GL4285@paulmck-ThinkPad-P17-Gen-1>
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfLjIOlGfFmbh1Zv@FVFF77S0Q05N> <yt9dy231yq90.fsf_-_@linux.ibm.com>
 <YfQCohKWJg9H+uID@FVFF77S0Q05N> <yt9dee4rn8q7.fsf@linux.ibm.com>
 <YfQVzba5thVs+qap@FVFF77S0Q05N>
 <20220128161547.GL4285@paulmck-ThinkPad-P17-Gen-1>
Message-ID: <20220128174723.GA2410054@paulmck-ThinkPad-P17-Gen-1>

On Fri, Jan 28, 2022 at 08:15:47AM -0800, Paul E. McKenney wrote:
> On Fri, Jan 28, 2022 at 04:11:57PM +0000, Mark Rutland wrote:
> > On Fri, Jan 28, 2022 at 05:08:48PM +0100, Sven Schnelle wrote:
> > > Hi Mark,
> > > 
> > > Mark Rutland <mark.rutland at arm.com> writes:
> > > 
> > > > On arm64 I bisected this down to:
> > > >
> > > >   7a30871b6a27de1a ("rcu-tasks: Introduce ->percpu_enqueue_shift for dynamic queue selection")
> > > >
> > > > Which was going wrong because ilog2() rounds down, and so the shift was wrong
> > > > for any nr_cpus that was not a power-of-two. Paul had already fixed that in
> > > > rcu-next, and just sent a pull request to Linus:
> > > >
> > > >   https://lore.kernel.org/lkml/20220128143251.GA2398275 at paulmck-ThinkPad-P17-Gen-1/
> > > >
> > > > With that applied, I no longer see these hangs.
> > > >
> > > > Does your s390 test machine have a non-power-of-two nr_cpus, and does that fix
> > > > the issue for you?
> > > 
> > > We noticed the PR from Paul and are currently testing the fix. So far
> > > it's looking good. The configuration where we have seen the hang is a
> > > bit unusual:
> > > 
> > > - 16 physical CPUs on the kvm host
> > > - 248 logical CPUs inside kvm
> > 
> > Aha! 248 is notably *NOT* a power of two, and in this case the shift would be
> > wrong (ilog2() would give 7, when we need a shift of 8).
> > 
> > So I suspect you're hitting the same issue as I was.
> 
> And apparently no one runs -next on systems having a non-power-of-two
> number of CPUs.  ;-)

And the fix is now in mainline.

							Thanx, Paul

> > Thanks,
> > Mark.
> > 
> > > - debug kernel both on the host and kvm guest
> > > 
> > > So things are likely a bit slow in the kvm guest. Interesting is that
> > > the number of CPUs is even. But maybe RCU sees an odd number of CPUs
> > > and gets confused before all cpus are brought up. Have to read code/test
> > > to see whether that could be possible.
> > > 
> > > Thanks for investigating!
> > > Sven


From u.kleine-koenig at pengutronix.de  Fri Jan 28 09:58:29 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Fri, 28 Jan 2022 18:58:29 +0100
Subject: [PATCH 1/2] dt-bindings: display: imx: Add fsl,imx21-lcdc docs
In-Reply-To: <CAL_JsqJjTf2zY-n69Ozh+S1gSi5Eoa5T44Qnq9RPNgJWDLmzKQ@mail.gmail.com>
References: <20220128105849.368438-1-u.kleine-koenig@pengutronix.de>
 <20220128105849.368438-2-u.kleine-koenig@pengutronix.de>
 <CAL_JsqJjTf2zY-n69Ozh+S1gSi5Eoa5T44Qnq9RPNgJWDLmzKQ@mail.gmail.com>
Message-ID: <20220128175829.vjm66rs7eu7pk2my@pengutronix.de>

Hello Rob,

On Fri, Jan 28, 2022 at 07:04:10AM -0600, Rob Herring wrote:
> On Fri, Jan 28, 2022 at 4:59 AM Uwe Kleine-K?nig
> <u.kleine-koenig at pengutronix.de> wrote:
> >
> > From: Marian Cichy <m.cichy at pengutronix.de>
> >
> > This files documents the device tree for the new imx21-lcdc DRM driver.
> 
> No, bindings document h/w and the h/w has not changed. We already have
> a binding for the LCDC.

Just to be sure we're talking about the same thing: You're refering to
Documentation/devicetree/bindings/display/imx/fsl,imx-fb.txt, right?

I'm unsure what to do now. Should the two different bindings just be
described in the same file? Should I stick to fsl,imx21-fb even for the
new binding? (The hardware unit is named LCDC, so the name chosen here
is the better one.) Please advise.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/7263ad5a/attachment.sig>

From john.garry at huawei.com  Fri Jan 28 10:00:57 2022
From: john.garry at huawei.com (John Garry)
Date: Fri, 28 Jan 2022 18:00:57 +0000
Subject: [RFC PATCH 1/1] perf arm64: Implement --topdown with metrics
In-Reply-To: <6ba550d1-61bc-e229-2a64-331cfa59c388@arm.com>
References: <4c375d34-bf20-496d-22fc-aed8597126e2@huawei.com>
 <20211214184240.24215-1-andrew.kilroy@arm.com>
 <20211214184240.24215-2-andrew.kilroy@arm.com>
 <48437bee-9c39-38ba-e990-ba9a6a5378b4@huawei.com>
 <6ba550d1-61bc-e229-2a64-331cfa59c388@arm.com>
Message-ID: <2bd5593e-615f-2ad1-ce03-cb452c7cd370@huawei.com>

On 05/01/2022 16:58, Andrew Kilroy wrote:
>>
> 

Sorry for very slow response..

> The --topdown kernel event colouring is dictated by a large if-else 
> statement in stat-shadow.c:perf_stat__print_shadow_stats.
> 
> There are branches depending on what is returned by 
> perf_stat_evsel__is() for example
> 
>  ????} else if (perf_stat_evsel__is(evsel, TOPDOWN_FETCH_BUBBLES)) {
>  ??????? double fe_bound = td_fe_bound(cpu, st, &rsd);
> 
>  ??????? if (fe_bound > 0.2)
>  ??????????? color = PERF_COLOR_RED;
>  ??????? print_metric(config, ctxp, color, "%8.1f%%", "frontend bound",
>  ??????????????? fe_bound * 100.);
>  ????} else if (perf_stat_evsel__is(evsel, TOPDOWN_SLOTS_RETIRED)) {
> 
> 
> 
> Because the patches are enabling metrics (equivalent of the -M 
> 'somemetricname' option), the perf_stat__print_shadow_stats function 
> always makes calls to generic_metric(), where colours are never picked.
> 
> Seeing thresholds like:
> 
>  ? retiring > 0.7
>  ? fe_bound > 0.2
>  ? be_bound > 0.2
>  ? bad_spec > 0.1
> 
> 
> I'm not sure about adding the colouring really.? Are these thresholds 
> x86 specific?

There is info on topdown for vtune here:

https://www.intel.com/content/www/us/en/develop/documentation/vtune-cookbook/top/methodologies/top-down-microarchitecture-analysis-method.html

The threshold info described there seems somewhat consistent with perf 
tool topdown thresholds and that is based on general guidelines for 
certain compute categories.

Andi did mention "specification" here:
https://lore.kernel.org/lkml/CABPqkBRftsHEAEwgCn3i3=mfk9fjh5r4MycdjHKRka5voTj9JA at mail.gmail.com/

But I don't know it, apart from a paper:
file:///home/john/Downloads/TopDown-Yasin-ISPASS14.pdf

Thanks,
John


From vijayb at linux.microsoft.com  Fri Jan 28 10:03:09 2022
From: vijayb at linux.microsoft.com (Vijay Balakrishna)
Date: Fri, 28 Jan 2022 10:03:09 -0800
Subject: [arm64] kernel boot slowdown in v5.10.19 -> v5.10.42 update
In-Reply-To: <YfPcNy3JcnwuJNMx@arm.com>
References: <9a34ee9b-0ede-30a6-0898-d32fe81d5b0c@linux.microsoft.com>
 <YfPcNy3JcnwuJNMx@arm.com>
Message-ID: <7e43a7e9-f299-1d6d-8b61-425793abcc3e@linux.microsoft.com>



On 1/28/2022 4:06 AM, Catalin Marinas wrote:
> On Mon, Jan 24, 2022 at 03:03:48PM -0800, Vijay Balakrishna wrote:
>> We noticed 150ms kernel boot slowdown back in June, 2021, when moving from
>> v5.10.19 to v5.10.42.  This on a 8GB SoC.  Only recently we investigated
>> this issue and found the regression is introduced by a change in map_mem()
>> (paging_init() -> map_mem() -> __map_memblock(), in particular "map all the
>> memory banks" for loop) by patch
>>
>> 2687275a5843d1089687f08fc64eb3f3b026a169
>> arm64: Force NO_BLOCK_MAPPINGS if crashkernel reservation is required
>>
>> above is a follow up to
>>
>> 0a30c53573b07d5561457e41fb0ab046cd857da5
>> arm64: mm: Move reserve_crashkernel() into mem_init())
>>
>> which deferred crashkernel reservation into mem_init().
>>
>> The ~150ms slowdown disappears on booting without "crashkernel=.." on kernel
>> command-line.
> 
> Is CONFIG_RODATA_FULL_DEFAULT_ENABLED set in your config file? It may
> cause the same slowdown. I suspect it's because we end up mapping the
> RAM at the page granularity so more loops and slightly higher TLB
> pressure. Not sure we can do much about >

Catalin,

Thanks for your reply.

CONFIG_RODATA_FULL_DEFAULT_ENABLED is not set in our config for boot 
time performance reasons.


From mathieu.poirier at linaro.org  Fri Jan 28 10:08:52 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Jan 2022 11:08:52 -0700
Subject: [PATCH v2 1/6] coresight: configfs: Add in functionality for
 load via configfs
In-Reply-To: <20211130220100.25888-2-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-2-mike.leach@linaro.org>
Message-ID: <20220128180852.GA2240873@p14s>

Good morning Mike,

Please find below (and in upcoming emails) the rest or my comments for this set.

On Tue, Nov 30, 2021 at 10:00:55PM +0000, Mike Leach wrote:
> Add in functionality to allow load via configfs.
> 
> define a binary file format and provide a reader for that format
> that will create and populate configuration and feature structures
> use by the driver infrastructure.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  drivers/hwtracing/coresight/Makefile          |   2 +-
>  .../coresight/coresight-config-file.c         | 432 ++++++++++++++++++
>  .../coresight/coresight-config-file.h         | 118 +++++
>  .../hwtracing/coresight/coresight-config.h    |  17 +
>  .../hwtracing/coresight/coresight-syscfg.h    |   1 +
>  5 files changed, 569 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-config-file.h
> 
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index b6c4a48140ec..5de2bb79f4ac 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -6,7 +6,7 @@ obj-$(CONFIG_CORESIGHT) += coresight.o
>  coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
>  		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
>  		coresight-cfg-preload.o coresight-cfg-afdo.o \
> -		coresight-syscfg-configfs.o
> +		coresight-syscfg-configfs.o coresight-config-file.o
>  obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
>  coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
>  		      coresight-tmc-etr.o
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c
> new file mode 100644
> index 000000000000..3fd001938324
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config-file.c
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#include "coresight-config.h"
> +#include "coresight-config-file.h"
> +#include "coresight-syscfg.h"
> +
> +#define cscfg_extract_u64(val64) {	\
> +	val64 = *(u64 *)(buffer + used); \
> +	used += sizeof(u64); \
> +	}
> +
> +#define cscfg_extract_u32(val32) { \
> +	val32 = *(u32 *)(buffer + used); \
> +	used += sizeof(u32); \
> +	}
> +
> +#define cscfg_extract_u16(val16) { \
> +	val16 = *(u16 *)(buffer + used); \
> +	used += sizeof(u16); \
> +	}
> +
> +#define cscfg_extract_u8(val8) {	\
> +	val8 = *(buffer + used); \
> +	used++; \
> +	}
> +
> +static int cscfg_file_read_hdr(const u8 *buffer, const int buflen, int *buf_used,
> +			       struct cscfg_file_header *hdr)
> +{
> +	/* file header always at the start of the buffer */
> +	int used = 0;
> +
> +	if (buflen < sizeof(struct cscfg_file_header))
> +		return -EINVAL;
> +
> +	cscfg_extract_u32(hdr->magic_version);
> +	if (hdr->magic_version != CSCFG_FILE_MAGIC_VERSION)
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(hdr->length);
> +	if (hdr->length > buflen)
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(hdr->nr_features);
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_hdr(const u8 *buffer, const int buflen, int *buf_used,
> +				    struct cscfg_file_elem_header *elem_hdr)
> +{
> +	int used = *buf_used;
> +
> +	if ((buflen - used) < (sizeof(u16) + sizeof(u8)))
> +		return -EINVAL;
> +
> +	/* read length and check enough buffer remains for this element */
> +	elem_hdr->elem_length = *(u16 *)(buffer + used);
> +	if ((buflen - used) < elem_hdr->elem_length)
> +		return -EINVAL;
> +	/* don't use extract fn as we update used _after_ the comparison */
> +	used += sizeof(u16);
> +
> +	/* read type and validate */
> +	cscfg_extract_u8(elem_hdr->elem_type);
> +	if ((elem_hdr->elem_type < CSCFG_FILE_ELEM_TYPE_FEAT) ||
> +	    (elem_hdr->elem_type > CSCFG_FILE_ELEM_TYPE_CFG))
> +		return -EINVAL;
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf_used,
> +				    struct cscfg_file_elem_str *elem_str)
> +{
> +	int used = *buf_used;
> +
> +	if ((buflen - used) < sizeof(u16))
> +		return -EINVAL;
> +
> +	cscfg_extract_u16(elem_str->str_len);
> +
> +	if ((buflen - used) < elem_str->str_len)
> +		return -EINVAL;
> +
> +	/* check for 0 termination */
> +	if (buffer[elem_str->str_len - 1] != 0)
> +		return -EINVAL;
> +
> +	elem_str->str = devm_kstrdup(cscfg_device(), (char *)buffer, GFP_KERNEL);
> +	used += elem_str->str_len;
> +
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays,
> +					int nr_features)
> +{
> +	/* arrays are 0 terminated - max of 1 config & nr_features features */
> +	desc_arrays->config_descs = devm_kcalloc(cscfg_device(), 2,
> +						 sizeof(struct cscfg_config_desc *),
> +						 GFP_KERNEL);
> +	if (!desc_arrays->config_descs)
> +		return -ENOMEM;
> +	desc_arrays->feat_descs = devm_kcalloc(cscfg_device(), nr_features + 1,
> +					       sizeof(struct cscfg_feature_desc *),
> +					       GFP_KERNEL);
> +	if (!desc_arrays->feat_descs)
> +		return -ENOMEM;
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *buf_used,
> +				       struct cscfg_fs_load_descs *desc_arrays)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	struct cscfg_config_desc *config_desc;
> +	int used = *buf_used, nr_preset_vals, nr_preset_bytes, i;
> +	int err = 0;
> +	u64 *presets;
> +
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG)
> +		return 0;
> +
> +	/* we have a config - allocate the descriptor */
> +	config_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_config_desc),
> +				   GFP_KERNEL);
> +	if (!config_desc)
> +		return -ENOMEM;
> +
> +	/* read the name string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	config_desc->name = elem_str.str;
> +
> +	/* read the description string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	config_desc->description = elem_str.str;
> +
> +	/* read in some values */
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +	cscfg_extract_u16(config_desc->nr_presets);
> +	cscfg_extract_u32(config_desc->nr_total_params);
> +	cscfg_extract_u16(config_desc->nr_feat_refs);
> +
> +	/* read the array of 64bit presets if present */
> +	nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets;
> +	if (nr_preset_vals) {
> +		presets = devm_kcalloc(cscfg_device(), nr_preset_vals,
> +				       sizeof(u64), GFP_KERNEL);
> +		if (!presets)
> +			return -ENOMEM;
> +
> +		nr_preset_bytes = sizeof(u64) * nr_preset_vals;
> +		if ((buflen - used) < nr_preset_bytes)
> +			return -EINVAL;
> +
> +		memcpy(presets, (buffer + used), nr_preset_bytes);
> +		config_desc->presets = presets;
> +		used += nr_preset_bytes;
> +	}
> +
> +	/* read the array of feature names referenced by the config */
> +	if (config_desc->nr_feat_refs) {
> +		config_desc->feat_ref_names = devm_kcalloc(cscfg_device(),
> +							   config_desc->nr_feat_refs,
> +							   sizeof(char *),
> +							   GFP_KERNEL);
> +		if (!config_desc->feat_ref_names)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < config_desc->nr_feat_refs; i++) {
> +			err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +			if (err)
> +				return err;
> +			config_desc->feat_ref_names[i] = elem_str.str;
> +		}
> +	}
> +
> +	desc_arrays->config_descs[0] = config_desc;
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +/* just read the config name - if there is a config at this position */
> +static int cscfg_file_read_elem_config_name(const u8 *buffer, const int buflen, int *buf_used,
> +					    struct cscfg_file_elem_str *elem_str)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	int used = *buf_used;
> +	int err;
> +
> +	elem_str->str_len = 0;
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_CFG)
> +		return 0;
> +
> +	/* read the name string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str);
> +	if (err)
> +		return err;
> +	*buf_used = used;
> +
> +	return 0;
> +}
> +
> +static int cscfg_file_read_elem_param(const u8 *buffer, const int buflen, int *buf_used,
> +				      struct cscfg_parameter_desc *param_desc)
> +{
> +	struct cscfg_file_elem_str elem_str;
> +	int err = 0, used = *buf_used;
> +
> +	/* parameter name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	param_desc->name = elem_str.str;
> +
> +	/* parameter value */
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +	cscfg_extract_u64(param_desc->value);
> +
> +	*buf_used = used;
> +	return err;
> +}
> +
> +static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int *buf_used,
> +					struct cscfg_fs_load_descs *desc_arrays,
> +					const int feat_idx)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	struct cscfg_feature_desc *feat_desc;
> +	struct cscfg_regval_desc *p_reg_desc;
> +	int used = *buf_used, err, i, nr_regs_bytes;
> +	u32 val32;
> +
> +	/* allocate the feature descriptor object */
> +	feat_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_feature_desc),
> +				 GFP_KERNEL);
> +	if (!feat_desc)
> +		return -ENOMEM;
> +
> +	/* read and check the element header */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT)
> +		return -EINVAL;
> +
> +	/* read the feature name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	feat_desc->name = elem_str.str;
> +
> +	/* read the description string */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +	feat_desc->description = elem_str.str;
> +
> +	/*
> +	 * read in some values
> +	 * [u32 value: match_flags]
> +	 * [u16 value: nr_regs]	    - number of registers.
> +	 * [u16 value: nr_params]   - number of parameters.
> +	 */
> +	cscfg_extract_u32(feat_desc->match_flags);
> +	cscfg_extract_u16(feat_desc->nr_regs);
> +	cscfg_extract_u16(feat_desc->nr_params);
> +
> +	/* register descriptors  - 32 bit + 64 bit value */
> +	if (feat_desc->nr_regs) {
> +		nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs);
> +		if ((buflen - used) < nr_regs_bytes)
> +			return -EINVAL;
> +		feat_desc->regs_desc = devm_kcalloc(cscfg_device(),
> +						    feat_desc->nr_regs,
> +						    sizeof(struct cscfg_regval_desc),
> +						    GFP_KERNEL);
> +		if (!feat_desc->regs_desc)
> +			return -ENOMEM;
> +
> +		for (i = 0; i < feat_desc->nr_regs; i++) {
> +			cscfg_extract_u32(val32);
> +			p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
> +			CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_reg_desc);
> +			cscfg_extract_u64(feat_desc->regs_desc[i].val64);
> +		}
> +	}
> +
> +	/* parameter descriptors - string + 64 bit value */
> +	if (feat_desc->nr_params) {
> +		feat_desc->params_desc = devm_kcalloc(cscfg_device(),
> +						      feat_desc->nr_params,
> +						      sizeof(struct cscfg_parameter_desc),
> +						      GFP_KERNEL);
> +		if (!feat_desc->params_desc)
> +			return -ENOMEM;
> +		for (i = 0; i < feat_desc->nr_params; i++) {
> +			err = cscfg_file_read_elem_param(buffer, buflen, &used,
> +							 &feat_desc->params_desc[i]);
> +			if (err)
> +				return err;
> +		}
> +	}
> +
> +	desc_arrays->feat_descs[feat_idx] = feat_desc;
> +	*buf_used = used;
> +	return 0;
> +}
> +
> +/* just read the feature name - if there is a feature at this position */
> +static int cscfg_file_read_elem_feat_name(const u8 *buffer, const int buflen, int *buf_used,
> +					  struct cscfg_file_elem_str *elem_str)
> +{
> +	struct cscfg_file_elem_header elem_hdr;
> +	int used = *buf_used;
> +	int err;
> +
> +	elem_str->str_len = 0;
> +	/*
> +	 * read the header - if not config, then don't update buf_used
> +	 * pointer on return
> +	 */
> +	err = cscfg_file_read_elem_hdr(buffer, buflen, &used, &elem_hdr);
> +	if (err)
> +		return err;
> +	if (elem_hdr.elem_type != CSCFG_FILE_ELEM_TYPE_FEAT)
> +		return -EINVAL;
> +
> +	/* read the feature name */
> +	err = cscfg_file_read_elem_str(buffer, buflen, &used, elem_str);
> +	if (err)
> +		return err;
> +	*buf_used = used;
> +
> +	return 0;
> +}
> +
> +/*
> + * Read a buffer and create the configuration and feature
> + * descriptors to load into the cscfg system
> + */
> +int cscfg_file_read_buffer(const u8 *buffer, const int buflen,
> +			   struct cscfg_fs_load_descs *desc_arrays)
> +{
> +	struct cscfg_file_header hdr;
> +	int used = 0, err, i;
> +
> +	/* read in the file header */
> +	err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr);
> +	if (err)
> +		return err;
> +
> +	/* allocate the memory for the descriptor pointer arrays */
> +	err = cscfg_file_alloc_desc_arrays(desc_arrays, hdr.nr_features);
> +	if (err)
> +		return err;
> +
> +	/* read elements */
> +
> +	/* first element could be a config so check */
> +	err = cscfg_file_read_elem_config(buffer, buflen, &used, desc_arrays);
> +	if (err)
> +		return err;
> +
> +	/* now read and populate all the feature descriptors */
> +	for (i = 0; i < hdr.nr_features; i++) {
> +		err = cscfg_file_read_elem_feature(buffer, buflen, &used, desc_arrays, i);
> +		if (err)
> +			return err;
> +	}
> +	return used;
> +}
> +
> +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen,
> +				      const char **name)
> +{
> +	struct cscfg_file_header hdr;
> +	struct cscfg_file_elem_str elem_str;
> +	int used = 0, err = 0;
> +
> +	*name = NULL;
> +
> +	/* read in the file header */
> +	err = cscfg_file_read_hdr(buffer, buflen, &used, &hdr);
> +	if (err)
> +		return err;
> +
> +	err = cscfg_file_read_elem_config_name(buffer, buflen, &used, &elem_str);
> +	if (err)
> +		return err;
> +
> +	/* no config string - get first feature name */
> +	if (!elem_str.str_len) {
> +		err = cscfg_file_read_elem_feat_name(buffer, buflen, &used, &elem_str);
> +		if (err)
> +			return err;
> +	}
> +	if (elem_str.str_len)
> +		*name = elem_str.str;
> +	return err;
> +}

I haven't found a problem or a bug in the above.

> diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h
> new file mode 100644
> index 000000000000..6c8c5af0a614
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-config-file.h
> @@ -0,0 +1,118 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H
> +#define _CORESIGHT_CORESIGHT_CONFIG_FILE_H
> +
> +/*
> + * Structures to represent configuration descriptors in a memory buffer
> + * to serialise to and from files
> + *
> + * File structure - for loading a configuration + features
> + * from configfs.
> + *
> + * [cscfg_file_header]	- mandatory
> + * [CONFIG_ELEM]	- optional - only one permitted,
> + * [FEATURE_ELEM] * [cscfg_file_header.nr_features]
> + *			- optional - file valid with config only.
> + *
> + * Invalid file if no config or features.
> + *
> + *
> + * File structure for [CONFIG_ELEM]:
> + *
> + * [cscfg_file_elem_header] - header length value to end of feature strings.
> + * [cscfg_file_elem_str]    - name of the configuration
> + * [cscfg_file_elem_str]    - description of configuration
> + * [u16 value - nr_presets]
> + * [u32 value - nr_total_params]
> + * [u16 value - nr_feat_refs]
> + * [u64 values] * (nr_presets * nr_total_params)
> + * [cscfg_file_elem_str] * nr_feat_refs
> + *
> + * Only one configuration per file.
> + *
> + * File structure for a [FEATURE_ELEM]
> + *
> + * [cscfg_file_elem_header] - header length is total bytes to end of param structures.
> + * [cscfg_file_elem_str]    - feature name.
> + * [cscfg_file_elem_str]    - feature description.
> + * [u32 value: match_flags]
> + * [u16 value: nr_regs]	    - number of registers.
> + * [u16 value: nr_params]   - number of parameters.
> + * [cscfg_regval_desc struct] * nr_regs
> + * [PARAM_ELEM] * nr_params
> + *
> + * File structure for [PARAM_ELEM]
> + *
> + * [cscfg_file_elem_str]    - parameter name.
> + * [u64 value: param_value] - initial value.
> + */
> +

The above is really really dry, even for someone that is acquainted with the CS
subsystem and the complex configuration feature.  I doubt someone looking to
start with the subsystem will be able to understand what is going on.  

> +/* major element types - configurations and features */
> +
> +#define CSCFG_FILE_ELEM_TYPE_FEAT	0x1
> +#define CSCFG_FILE_ELEM_TYPE_CFG	0x2
> +
> +#define CSCFG_FILE_MAGIC_VERSION	0xC5CF0001

I like that magic number.

> +
> +#define CSCFG_FILE_U32_TO_REG_DESC_INFO(val32, p_desc) \
> +	{ \
> +	p_desc->type = (val32 >> 24) & 0xFF; \
> +	p_desc->offset = (val32 >> 12) & 0xFFF; \
> +	p_desc->hw_info = val32 & 0xFFF; \
> +	}
> +
> +#define CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_desc) \
> +	{ \
> +	val32 = p_desc->hw_info & 0xFFF; \
> +	val32 |= ((p_desc->offset & 0xFFF) << 12); \
> +	val32 |= ((p_desc->type & 0xFF) << 24); \
> +	}
> +
> +/* binary attributes in configfs need a max size - declare a value for this. */
> +#define CSCFG_FILE_MAXSIZE	16384
> +
> +/* limit string sizes */
> +#define CSCFG_FILE_STR_MAXSIZE	1024
> +
> +

Extra newline.

> +/**
> + * file header.
> + *
> + * @magic_version: magic number / version for file/buffer format.
> + * @length       : total length of all data in the buffer.
> + * @nr_features  : total number of features in the buffer.
> + */
> +struct cscfg_file_header {
> +	u32 magic_version;
> +	u16 length;
> +	u16 nr_features;
> +};
> +
> +/**
> + * element header
> + *
> + * @elem_length: total length of this element
> + * @elem_type  : type of this element - one of CSCFG_FILE_ELEM_TYPE.. defines.
> + */
> +struct cscfg_file_elem_header {
> +	u16 elem_length;
> +	u8 elem_type;
> +};
> +
> +/**
> + * string file element.
> + *
> + * @str_len: length of string buffer including 0 terminator
> + * @str    : string buffer - 0 terminated.
> + */
> +struct cscfg_file_elem_str {
> +	u16 str_len;
> +	char *str;
> +};
> +
> +#endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index 9bd44b940add..770986316bc2 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -150,6 +150,23 @@ struct cscfg_config_desc {
>  	struct config_group *fs_group;
>  };
>  
> +/**
> + * Dynamically loaded descriptor arrays loaded via configfs.
> + *
> + * For builtin or module loaded configurations / features these are
> + * statically defined at compile time. For configfs we create the arrays
> + * dynamically so need a structure to handle this.
> + *
> + * @owner_info:		associated owner info struct to add to load order list.
> + * @config_descs:	array of config descriptor pointers.
> + * @feat_descs:		array of feature descriptor pointers.
> + */
> +struct cscfg_fs_load_descs {
> +	void *owner_info;
> +	struct cscfg_config_desc **config_descs;
> +	struct cscfg_feature_desc **feat_descs;
> +};
> +
>  /**
>   * config register instance - part of a loaded feature.
>   *                            maps register values to csdev driver structures
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
> index 9106ffab4833..6a6e33585be9 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.h
> @@ -66,6 +66,7 @@ struct cscfg_registered_csdev {
>  enum cscfg_load_owner_type {
>  	CSCFG_OWNER_PRELOAD,
>  	CSCFG_OWNER_MODULE,
> +	CSCFG_OWNER_CONFIGFS,

Other than the above comments this patch works.

>  };
>  
>  /**
> -- 
> 2.17.1
> 


From mathieu.poirier at linaro.org  Fri Jan 28 10:17:23 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Jan 2022 11:17:23 -0700
Subject: [PATCH v2 2/6] coresight: configfs: Add in binary attributes to
 load files
In-Reply-To: <20211130220100.25888-3-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-3-mike.leach@linaro.org>
Message-ID: <20220128181723.GB2240873@p14s>

On Tue, Nov 30, 2021 at 10:00:56PM +0000, Mike Leach wrote:
> Add in functionality and binary attribute to load configurations
> as binary data.
> 
> Reads the incoming attribute, which must be formatted correctly
> as defined in the file reader code - and will create a configuration
> and/or features and load them into the system.
> 
> These will then appear in configfs ready for use.
> 
> Unload functionality is also provided.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  .../coresight/coresight-config-file.h         |   7 +
>  .../coresight/coresight-syscfg-configfs.c     | 148 +++++++++++++++++-
>  .../coresight/coresight-syscfg-configfs.h     |   8 +
>  .../hwtracing/coresight/coresight-syscfg.c    |  36 +++++
>  .../hwtracing/coresight/coresight-syscfg.h    |   1 +
>  5 files changed, 193 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h
> index 6c8c5af0a614..03899f7d94c9 100644
> --- a/drivers/hwtracing/coresight/coresight-config-file.h
> +++ b/drivers/hwtracing/coresight/coresight-config-file.h
> @@ -115,4 +115,11 @@ struct cscfg_file_elem_str {
>  	char *str;
>  };
>  
> +/* kernel configfs needs to read the incoming file buffers to load. */
> +int cscfg_file_read_buffer(const u8 *buffer, const int buflen,
> +			   struct cscfg_fs_load_descs *desc_arrays);
> +/* to unload we just need the first name - config or first feature */
> +int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen,
> +				      const char **name);
> +
>  #endif /* _CORESIGHT_CORESIGHT_CONFIG_FILE_H */
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> index 433ede94dd63..50abdb5aa6b6 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.c
> @@ -7,6 +7,7 @@
>  #include <linux/configfs.h>
>  
>  #include "coresight-config.h"
> +#include "coresight-config-file.h"
>  #include "coresight-syscfg-configfs.h"
>  
>  /* create a default ci_type. */
> @@ -380,14 +381,147 @@ static struct config_group *cscfg_create_feature_group(struct cscfg_feature_desc
>  	return &feat_view->group;
>  }
>  
> +/* Attributes in configfs that allow load and unload of configuration binary files */
> +
> +/* load "buffer" as a configuration binary file */
> +static ssize_t cscfg_cfg_load_write(struct config_item *item, const void *buffer, size_t size)
> +{
> +	struct cscfg_fs_configs_grp *configs_grp;
> +	struct cscfg_fs_load_descs *load_descs = 0;
> +	struct cscfg_load_owner_info *owner_info = 0;
> +	int err = 0;
> +	const char *name;
> +
> +	configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> +	if (size > CSCFG_FILE_MAXSIZE) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Load error: Input file too large.\n");
> +		return -EINVAL;
> +	}
> +
> +	load_descs = kzalloc(sizeof(struct cscfg_fs_load_descs), GFP_KERNEL);
> +	owner_info = kzalloc(sizeof(struct cscfg_load_owner_info), GFP_KERNEL);
> +	if (!load_descs || !owner_info) {
> +		err = -ENOMEM;
> +		goto exit_memfree;
> +	}
> +
> +	load_descs->owner_info = owner_info;
> +	owner_info->owner_handle = load_descs;
> +	owner_info->type = CSCFG_OWNER_CONFIGFS;
> +
> +	err = cscfg_file_read_buffer(buffer, size, load_descs);
> +	if (err) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Load error: Failed to read input file.\n");
> +		goto exit_memfree;
> +	}
> +
> +	err = cscfg_load_config_sets(load_descs->config_descs, load_descs->feat_descs, owner_info);
> +	if (err) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Load error: Failed to load configuaration file.\n");
> +		goto exit_memfree;
> +	}
> +
> +	/* name of config if there is one, otherwise first feature */
> +	if (load_descs->config_descs[0])
> +		name = load_descs->config_descs[0]->name;
> +	else
> +		name = load_descs->feat_descs[0]->name;
> +	scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +		  "OK: configuration file loaded (%s).\n", name);
> +
> +	return size;
> +
> +exit_memfree:
> +	kfree(load_descs);
> +	kfree(owner_info);
> +	return err;
> +}
> +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, load, NULL, CSCFG_FILE_MAXSIZE);
> +
> +/* read "buffer" and unload configuration */
> +static ssize_t cscfg_cfg_unload_write(struct config_item *item, const void *buffer, size_t size)
> +{
> +	struct cscfg_fs_configs_grp *configs_grp;
> +	struct cscfg_fs_load_descs *load_descs;
> +	const char *name;
> +	int err;
> +
> +	configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> +	if (size > CSCFG_FILE_MAXSIZE) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Unload error: Input file too large\n");
> +		return -EINVAL;
> +	}
> +
> +	err = cscfg_file_read_buffer_first_name(buffer, size, &name);
> +	if (err) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Unload error: Failed to read input file\n");
> +		return err;
> +	}
> +
> +	load_descs = cscfg_find_fs_owned_cfg_by_name(name);
> +	if (!load_descs) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Unload error: Failed to find configuration %s from input file\n",
> +			  name);
> +		return err;
> +	}
> +	err = cscfg_unload_config_sets(load_descs->owner_info);
> +	if (err) {
> +		scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +			  "Unload error: Cannot unload configuration %s\n",
> +			  name);
> +		return err;
> +	}
> +
> +	scnprintf(configs_grp->status, CSCFG_FS_STATUS_STRLEN,
> +		  "OK: configuration file unloaded (%s).\n", name);
> +
> +	kfree((struct cscfg_load_owner_info *)load_descs->owner_info);
> +	kfree(load_descs);
> +	return size;
> +}
> +CONFIGFS_BIN_ATTR_WO(cscfg_cfg_, unload, NULL, CSCFG_FILE_MAXSIZE);
> +
> +/* show the status of the last load / unload operation */
> +static ssize_t cscfg_cfg_last_load_status_show(struct config_item *item, char *page)
> +{
> +	struct cscfg_fs_configs_grp *configs_grp;
> +
> +	configs_grp = container_of(to_config_group(item), struct cscfg_fs_configs_grp, group);
> +
> +	return scnprintf(page, PAGE_SIZE, "%s\n", configs_grp->status);

I am still very ambivalent about this status thing...  Especially since it only
reports on the last item that was loaded/unloaded.

> +}
> +CONFIGFS_ATTR_RO(cscfg_cfg_, last_load_status);
> +
> +static struct configfs_attribute *cscfg_config_configs_attrs[] = {
> +	&cscfg_cfg_attr_last_load_status,
> +	NULL,
> +};
> +
> +static struct configfs_bin_attribute *cscfg_config_configfs_bin_attrs[] = {
> +	&cscfg_cfg_attr_load,
> +	&cscfg_cfg_attr_unload,
> +	NULL,
> +};
> +
>  static struct config_item_type cscfg_configs_type = {
>  	.ct_owner = THIS_MODULE,
> +	.ct_bin_attrs = cscfg_config_configfs_bin_attrs,
> +	.ct_attrs = cscfg_config_configs_attrs,
>  };
>  
> -static struct config_group cscfg_configs_grp = {
> -	.cg_item = {
> -		.ci_namebuf = "configurations",
> -		.ci_type = &cscfg_configs_type,
> +/* group for configurations dir, with load, unload and status attribs */
> +static struct cscfg_fs_configs_grp cscfg_configs_grp = {
> +	.group = {
> +		.cg_item = {
> +			.ci_namebuf = "configurations",
> +			.ci_type = &cscfg_configs_type,
> +		},
>  	},
>  };
>  
> @@ -400,7 +534,7 @@ int cscfg_configfs_add_config(struct cscfg_config_desc *config_desc)
>  	new_group = cscfg_create_config_group(config_desc);
>  	if (IS_ERR(new_group))
>  		return PTR_ERR(new_group);
> -	err =  configfs_register_group(&cscfg_configs_grp, new_group);
> +	err =  configfs_register_group(&cscfg_configs_grp.group, new_group);
>  	if (!err)
>  		config_desc->fs_group = new_group;
>  	return err;
> @@ -468,8 +602,8 @@ int cscfg_configfs_init(struct cscfg_manager *cscfg_mgr)
>  	mutex_init(&subsys->su_mutex);
>  
>  	/* Add default groups to subsystem */
> -	config_group_init(&cscfg_configs_grp);
> -	configfs_add_default_group(&cscfg_configs_grp, &subsys->su_group);
> +	config_group_init(&cscfg_configs_grp.group);
> +	configfs_add_default_group(&cscfg_configs_grp.group, &subsys->su_group);
>  
>  	config_group_init(&cscfg_features_grp);
>  	configfs_add_default_group(&cscfg_features_grp, &subsys->su_group);
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> index 373d84d43268..8d6900e8c1ea 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg-configfs.h
> @@ -11,6 +11,14 @@
>  
>  #define CSCFG_FS_SUBSYS_NAME "cs-syscfg"
>  
> +#define CSCFG_FS_STATUS_STRLEN 256
> +
> +/* container for configs group */
> +struct cscfg_fs_configs_grp {
> +	struct config_group group;
> +	char status[CSCFG_FS_STATUS_STRLEN];
> +};
> +
>  /* container for configuration view */
>  struct cscfg_fs_config {
>  	struct cscfg_config_desc *config_desc;
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c
> index 098fc34c4829..b5804cc2af9c 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.c
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.c
> @@ -587,6 +587,42 @@ int cscfg_unload_config_sets(struct cscfg_load_owner_info *owner_info)
>  }
>  EXPORT_SYMBOL_GPL(cscfg_unload_config_sets);
>  
> +/* find a configuration owned by configfs by name of config / first feature */
> +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name)
> +{
> +	struct cscfg_load_owner_info *owner_info;
> +	struct cscfg_fs_load_descs *fs_load_cfg = NULL;
> +	struct cscfg_config_desc *config_desc;
> +	struct cscfg_feature_desc *feat_desc;
> +
> +	mutex_lock(&cscfg_mutex);
> +
> +	/* search the load_owner list for CONFIGFS loaded types */
> +	list_for_each_entry(owner_info, &cscfg_mgr->load_order_list, item) {
> +		/* if this is a config fs owned item, then try to match */
> +		if (owner_info->type == CSCFG_OWNER_CONFIGFS) {
> +			fs_load_cfg = owner_info->owner_handle;
> +			/* first try to match the name against the config if it exists */
> +			if (fs_load_cfg->config_descs[0]) {
> +				config_desc = fs_load_cfg->config_descs[0];
> +				if (!strcmp(config_desc->name, name))
> +					goto exit_unlock;
> +			/* no config - match against first feature name */
> +			} else {
> +				feat_desc = fs_load_cfg->feat_descs[0];
> +				if (!strcmp(feat_desc->name, name))
> +					goto exit_unlock;
> +			}
> +			/* no match - move on */
> +			fs_load_cfg = NULL;
> +		}
> +	}
> +
> +exit_unlock:
> +	mutex_unlock(&cscfg_mutex);
> +	return fs_load_cfg;
> +}
> +
>  /* Handle coresight device registration and add configs and features to devices */
>  
>  /* iterate through config lists and load matching configs to device */
> diff --git a/drivers/hwtracing/coresight/coresight-syscfg.h b/drivers/hwtracing/coresight/coresight-syscfg.h
> index 6a6e33585be9..6bc29abe0650 100644
> --- a/drivers/hwtracing/coresight/coresight-syscfg.h
> +++ b/drivers/hwtracing/coresight/coresight-syscfg.h
> @@ -95,6 +95,7 @@ int cscfg_update_feat_param_val(struct cscfg_feature_desc *feat_desc,
>  				int param_idx, u64 value);
>  int cscfg_config_sysfs_activate(struct cscfg_config_desc *cfg_desc, bool activate);
>  void cscfg_config_sysfs_set_preset(int preset);
> +struct cscfg_fs_load_descs *cscfg_find_fs_owned_cfg_by_name(const char *name);
>  
>  /* syscfg manager external API */
>  int cscfg_load_config_sets(struct cscfg_config_desc **cfg_descs,
> -- 
> 2.17.1
> 


From mathieu.poirier at linaro.org  Fri Jan 28 10:33:44 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Jan 2022 11:33:44 -0700
Subject: [PATCH v2 3/6] coresight: configfs: Modify config files to allow
 userspace use
In-Reply-To: <20211130220100.25888-4-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-4-mike.leach@linaro.org>
Message-ID: <20220128183344.GC2240873@p14s>

On Tue, Nov 30, 2021 at 10:00:57PM +0000, Mike Leach wrote:
> Update coresight-config.h and the coresight-config-file.c & .h
> to allow use in userspace programs.
> 
> Use __KERNEL__ defines to filter out driver only structures and
> elements so that user space programs can use the descriptor structures.
> 
> Abstract memory allocation in coresight-config-file.c to allow read
> file functions to be run in userspace and kernel drivers.
> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  .../coresight/coresight-config-file.c         | 96 +++++++++++++------
>  .../coresight/coresight-config-file.h         | 33 +++++++
>  .../hwtracing/coresight/coresight-config.h    | 21 ++++
>  3 files changed, 122 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.c b/drivers/hwtracing/coresight/coresight-config-file.c
> index 3fd001938324..77a64b54280d 100644
> --- a/drivers/hwtracing/coresight/coresight-config-file.c
> +++ b/drivers/hwtracing/coresight/coresight-config-file.c
> @@ -4,10 +4,58 @@
>   * Author: Mike Leach <mike.leach at linaro.org>
>   */
>  
> -#include "coresight-config.h"
>  #include "coresight-config-file.h"
> +
> +/*
> + * To allow reuse of this source in tools, define memory allocation fns according
> + * to build environment.
> + */
> +
> +#ifdef __KERNEL__
>  #include "coresight-syscfg.h"
>  
> +static void *cscfg_calloc(size_t num, size_t size)
> +{
> +	return devm_kcalloc(cscfg_device(), num, size, GFP_KERNEL);
> +}
> +
> +static char *cscfg_strdup(const char *str)
> +{
> +	return devm_kstrdup(cscfg_device(), str, GFP_KERNEL);
> +}
> +
> +static void *cscfg_zalloc(size_t size)
> +{
> +	return devm_kzalloc(cscfg_device(), size, GFP_KERNEL);
> +}
> +
> +#else
> +
> +#include <stddef.h>
> +#include <string.h>
> +#include <stdlib.h>
> +
> +static void *cscfg_calloc(size_t num, size_t size)
> +{
> +	return calloc(num, size);
> +}
> +
> +static char *cscfg_strdup(const char *str)
> +{
> +	return strdup(str);
> +}
> +
> +static void *cscfg_zalloc(size_t size)
> +{
> +	void *ptr = malloc(size);
> +
> +	if (ptr)
> +		memset(ptr, 0, size);
> +	return ptr;
> +}
> +
> +#endif
> +
>  #define cscfg_extract_u64(val64) {	\
>  	val64 = *(u64 *)(buffer + used); \
>  	used += sizeof(u64); \
> @@ -80,6 +128,7 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf
>  				    struct cscfg_file_elem_str *elem_str)
>  {
>  	int used = *buf_used;
> +	const u8 *str;
>  
>  	if ((buflen - used) < sizeof(u16))
>  		return -EINVAL;
> @@ -89,11 +138,13 @@ static int cscfg_file_read_elem_str(const u8 *buffer, const int buflen, int *buf
>  	if ((buflen - used) < elem_str->str_len)
>  		return -EINVAL;
>  
> +	str = buffer + used;
> +
>  	/* check for 0 termination */
> -	if (buffer[elem_str->str_len - 1] != 0)
> +	if (str[elem_str->str_len - 1] != 0)
>  		return -EINVAL;
>  
> -	elem_str->str = devm_kstrdup(cscfg_device(), (char *)buffer, GFP_KERNEL);
> +	elem_str->str = cscfg_strdup((char *)str);
>  	used += elem_str->str_len;
>  
>  	*buf_used = used;
> @@ -104,14 +155,12 @@ static int cscfg_file_alloc_desc_arrays(struct cscfg_fs_load_descs *desc_arrays,
>  					int nr_features)
>  {
>  	/* arrays are 0 terminated - max of 1 config & nr_features features */
> -	desc_arrays->config_descs = devm_kcalloc(cscfg_device(), 2,
> -						 sizeof(struct cscfg_config_desc *),
> -						 GFP_KERNEL);
> +	desc_arrays->config_descs = cscfg_calloc(2, sizeof(struct cscfg_config_desc *));
>  	if (!desc_arrays->config_descs)
>  		return -ENOMEM;
> -	desc_arrays->feat_descs = devm_kcalloc(cscfg_device(), nr_features + 1,
> -					       sizeof(struct cscfg_feature_desc *),
> -					       GFP_KERNEL);
> +
> +	desc_arrays->feat_descs = cscfg_calloc(nr_features + 1,
> +					       sizeof(struct cscfg_feature_desc *));
>  	if (!desc_arrays->feat_descs)
>  		return -ENOMEM;
>  	return 0;
> @@ -138,8 +187,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
>  		return 0;
>  
>  	/* we have a config - allocate the descriptor */
> -	config_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_config_desc),
> -				   GFP_KERNEL);
> +	config_desc = cscfg_zalloc(sizeof(struct cscfg_config_desc));
>  	if (!config_desc)
>  		return -ENOMEM;
>  
> @@ -165,8 +213,7 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
>  	/* read the array of 64bit presets if present */
>  	nr_preset_vals = config_desc->nr_total_params * config_desc->nr_presets;
>  	if (nr_preset_vals) {
> -		presets = devm_kcalloc(cscfg_device(), nr_preset_vals,
> -				       sizeof(u64), GFP_KERNEL);
> +		presets = cscfg_calloc(nr_preset_vals, sizeof(u64));
>  		if (!presets)
>  			return -ENOMEM;
>  
> @@ -181,10 +228,8 @@ static int cscfg_file_read_elem_config(const u8 *buffer, const int buflen, int *
>  
>  	/* read the array of feature names referenced by the config */
>  	if (config_desc->nr_feat_refs) {
> -		config_desc->feat_ref_names = devm_kcalloc(cscfg_device(),
> -							   config_desc->nr_feat_refs,
> -							   sizeof(char *),
> -							   GFP_KERNEL);
> +		config_desc->feat_ref_names = cscfg_calloc(config_desc->nr_feat_refs,
> +							   sizeof(char *));
>  		if (!config_desc->feat_ref_names)
>  			return -ENOMEM;
>  
> @@ -262,8 +307,7 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
>  	u32 val32;
>  
>  	/* allocate the feature descriptor object */
> -	feat_desc = devm_kzalloc(cscfg_device(), sizeof(struct cscfg_feature_desc),
> -				 GFP_KERNEL);
> +	feat_desc = cscfg_zalloc(sizeof(struct cscfg_feature_desc));
>  	if (!feat_desc)
>  		return -ENOMEM;
>  
> @@ -302,10 +346,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
>  		nr_regs_bytes = ((sizeof(u32) + sizeof(u64)) * feat_desc->nr_regs);
>  		if ((buflen - used) < nr_regs_bytes)
>  			return -EINVAL;
> -		feat_desc->regs_desc = devm_kcalloc(cscfg_device(),
> -						    feat_desc->nr_regs,
> -						    sizeof(struct cscfg_regval_desc),
> -						    GFP_KERNEL);
> +		feat_desc->regs_desc = cscfg_calloc(feat_desc->nr_regs,
> +						    sizeof(struct cscfg_regval_desc));
>  		if (!feat_desc->regs_desc)
>  			return -ENOMEM;
>  
> @@ -319,10 +361,8 @@ static int cscfg_file_read_elem_feature(const u8 *buffer, const int buflen, int
>  
>  	/* parameter descriptors - string + 64 bit value */
>  	if (feat_desc->nr_params) {
> -		feat_desc->params_desc = devm_kcalloc(cscfg_device(),
> -						      feat_desc->nr_params,
> -						      sizeof(struct cscfg_parameter_desc),
> -						      GFP_KERNEL);
> +		feat_desc->params_desc = cscfg_calloc(feat_desc->nr_params,
> +						      sizeof(struct cscfg_parameter_desc));
>  		if (!feat_desc->params_desc)
>  			return -ENOMEM;
>  		for (i = 0; i < feat_desc->nr_params; i++) {
> @@ -399,7 +439,7 @@ int cscfg_file_read_buffer(const u8 *buffer, const int buflen,
>  		if (err)
>  			return err;
>  	}
> -	return used;
> +	return 0;
>  }
>  
>  int cscfg_file_read_buffer_first_name(const u8 *buffer, const int buflen,
> diff --git a/drivers/hwtracing/coresight/coresight-config-file.h b/drivers/hwtracing/coresight/coresight-config-file.h
> index 03899f7d94c9..04c365e5109b 100644
> --- a/drivers/hwtracing/coresight/coresight-config-file.h
> +++ b/drivers/hwtracing/coresight/coresight-config-file.h
> @@ -7,6 +7,39 @@
>  #ifndef _CORESIGHT_CORESIGHT_CONFIG_FILE_H
>  #define _CORESIGHT_CORESIGHT_CONFIG_FILE_H
>  
> +#include <linux/types.h>
> +
> +#ifndef __KERNEL__
> +/*
> + * allow the user space programs to include the coresight config headers
> + * to use the _desc structures, and reuse the read code
> + */
> +#ifndef u8
> +typedef __u8 u8;
> +typedef __u16 u16;
> +typedef __u32 u32;
> +typedef __u64 u64;
> +#endif
> +
> +/* ARRAY SIZE is useful too */
> +#ifndef ARRAY_SIZE
> +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
> +#endif
> +
> +/* define EINVAL for user space */
> +#ifndef EINVAL
> +#define EINVAL 22
> +#endif
> +
> +#ifndef ENOMEM
> +#define ENOMEM 12
> +#endif
> +
> +#endif
> +
> +#include "coresight-config.h"
> +
> +
>  /*
>   * Structures to represent configuration descriptors in a memory buffer
>   * to serialise to and from files
> diff --git a/drivers/hwtracing/coresight/coresight-config.h b/drivers/hwtracing/coresight/coresight-config.h
> index 770986316bc2..2136393df710 100644
> --- a/drivers/hwtracing/coresight/coresight-config.h
> +++ b/drivers/hwtracing/coresight/coresight-config.h
> @@ -7,7 +7,14 @@
>  #ifndef _CORESIGHT_CORESIGHT_CONFIG_H
>  #define _CORESIGHT_CORESIGHT_CONFIG_H
>  
> +/*
> + * Filter out kernel only portions of the file to allow user space programs
> + * to use the descriptor definitions.
> + */
> +#ifdef __KERNEL__
>  #include <linux/coresight.h>
> +#endif
> +
>  #include <linux/types.h>
>  
>  /* CoreSight Configuration Management - component and system wide configuration */
> @@ -103,14 +110,18 @@ struct cscfg_regval_desc {
>  struct cscfg_feature_desc {
>  	const char *name;
>  	const char *description;
> +#ifdef __KERNEL__
>  	struct list_head item;
> +#endif
>  	u32 match_flags;
>  	int nr_params;
>  	struct cscfg_parameter_desc *params_desc;
>  	int nr_regs;
>  	struct cscfg_regval_desc *regs_desc;
> +#ifdef __KERNEL__
>  	void *load_owner;
>  	struct config_group *fs_group;
> +#endif
>  };

That will quickly become a maintenance nightmare.  I suggest the following:

struct cscfg_feature_desc {
  	struct list_head item;
  	void *load_owner;
  	struct config_group *fs_group;
        struct cscfg_feature_udesc *udesc;
};

struct cscfg_feature_udesc {
        u32 version;
 	const char *name;
  	const char *description;
  	u32 match_flags;
  	int nr_params;
  	struct cscfg_parameter_desc *params_desc;
  	int nr_regs;
  	struct cscfg_regval_desc *regs_desc;
};

Structure cscfg_feature_udesc should likely be under include/uapi/linux/coresight-config.h

>  
>  /**
> @@ -138,16 +149,20 @@ struct cscfg_feature_desc {
>  struct cscfg_config_desc {
>  	const char *name;
>  	const char *description;
> +#ifdef __KERNEL__
>  	struct list_head item;
> +#endif
>  	int nr_feat_refs;
>  	const char **feat_ref_names;
>  	int nr_presets;
>  	int nr_total_params;
>  	const u64 *presets; /* nr_presets * nr_total_params */
> +#ifdef __KERNEL__
>  	struct dev_ext_attribute *event_ea;
>  	atomic_t active_cnt;
>  	void *load_owner;
>  	struct config_group *fs_group;
> +#endif
>  };
>  
>  /**
> @@ -162,11 +177,16 @@ struct cscfg_config_desc {
>   * @feat_descs:		array of feature descriptor pointers.
>   */
>  struct cscfg_fs_load_descs {
> +#ifdef __KERNEL__
>  	void *owner_info;
> +#endif
>  	struct cscfg_config_desc **config_descs;
>  	struct cscfg_feature_desc **feat_descs;
>  };

Same comment as above.

>  
> +/* remainder of header is used by the kernel drivers only */
> +#ifdef __KERNEL__
> +
>  /**
>   * config register instance - part of a loaded feature.
>   *                            maps register values to csdev driver structures
> @@ -274,4 +294,5 @@ void cscfg_csdev_disable_config(struct cscfg_config_csdev *config_csdev);
>  /* reset a feature to default values */
>  void cscfg_reset_feat(struct cscfg_feature_csdev *feat_csdev);
>  
> +#endif /* __KERNEL__ */
>  #endif /* _CORESIGHT_CORESIGHT_CONFIG_H */
> -- 
> 2.17.1
> 


From mathieu.poirier at linaro.org  Fri Jan 28 10:43:33 2022
From: mathieu.poirier at linaro.org (Mathieu Poirier)
Date: Fri, 28 Jan 2022 11:43:33 -0700
Subject: [PATCH v2 4/6] coresight: samples: Add an example config writer
 for configfs load
In-Reply-To: <20211130220100.25888-5-mike.leach@linaro.org>
References: <20211130220100.25888-1-mike.leach@linaro.org>
 <20211130220100.25888-5-mike.leach@linaro.org>
Message-ID: <20220128184333.GD2240873@p14s>

On Tue, Nov 30, 2021 at 10:00:58PM +0000, Mike Leach wrote:
> Add an example file generator to test loading configurations via a
> binary attribute in configfs.
> 
> Provides a file buffer writer function that can be re-used in other
> userspace programs.
> 
> Buffer write format matches that expected by the corresponding reader
> in the configfs driver code.

The user space program to read and write configurations should go under
tools/coresight rather than sample/coresight.  Have a look at tools/perf and tools/bpf.
There is a lot of examples in there that deals with code shared between kernel
and user space.  There is even a nifty scripts that checks for diverging files
between kernel and tools when compiling the perf tools.

You should also find how to properly deal with error codes and standard
types in a generic way rather than redefining them as in the previous patch.

I think this patchset is holding together but needs some refactoring to conform
to what others have done when dealing with shared kernel/user space code.

I am done reviewing this set.

Thanks,
Mathieu

> 
> Signed-off-by: Mike Leach <mike.leach at linaro.org>
> ---
>  samples/coresight/Makefile                |   7 +
>  samples/coresight/coresight-cfg-bufw.c    | 302 ++++++++++++++++++++++
>  samples/coresight/coresight-cfg-bufw.h    |  24 ++
>  samples/coresight/coresight-cfg-filegen.c |  89 +++++++
>  4 files changed, 422 insertions(+)
>  create mode 100644 samples/coresight/coresight-cfg-bufw.c
>  create mode 100644 samples/coresight/coresight-cfg-bufw.h
>  create mode 100644 samples/coresight/coresight-cfg-filegen.c
> 
> diff --git a/samples/coresight/Makefile b/samples/coresight/Makefile
> index b3fce4af2347..07bfd99d7a68 100644
> --- a/samples/coresight/Makefile
> +++ b/samples/coresight/Makefile
> @@ -1,4 +1,11 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  
> +# coresight config - loadable module configuration.
>  obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight-cfg-sample.o
>  ccflags-y += -I$(srctree)/drivers/hwtracing/coresight
> +
> +# coresight config - configfs loadable binary config generator
> +userprogs-always-y += coresight-cfg-filegen
> +
> +coresight-cfg-filegen-objs := coresight-cfg-filegen.o coresight-cfg-bufw.o
> +userccflags += -I$(srctree)/drivers/hwtracing/coresight
> diff --git a/samples/coresight/coresight-cfg-bufw.c b/samples/coresight/coresight-cfg-bufw.c
> new file mode 100644
> index 000000000000..8c32a8509eef
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-bufw.c
> @@ -0,0 +1,302 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#include <string.h>
> +
> +#include "coresight-cfg-bufw.h"
> +
> +/*
> + * Set of macros to make writing the buffer code easier.
> + *.
> + * Uses naming convention as 'buffer' for the buffer pointer and
> + * 'used' as the current bytes used by the encosing function.
> + */
> +#define cscfg_write_u64(val64) {	\
> +	*(u64 *)(buffer + used) = val64; \
> +	used += sizeof(u64); \
> +	}
> +
> +#define cscfg_write_u32(val32) { \
> +	*(u32 *)(buffer + used) = val32;	\
> +	used += sizeof(u32); \
> +	}
> +
> +#define cscfg_write_u16(val16) { \
> +	*(u16 *)(buffer + used) = val16;	\
> +	used += sizeof(u16); \
> +	}
> +
> +#define cscfg_write_u8(val8) { \
> +	*(buffer + used) = val8;	\
> +	used++;	\
> +	}
> +
> +#define CHECK_WRET(rval) { \
> +	if (rval < 0) \
> +		return rval;	   \
> +	used += rval;		   \
> +	}
> +
> +/* write the header at the start of the buffer */
> +static int cscfg_file_write_fhdr(u8 *buffer, const int buflen,
> +				 const struct cscfg_file_header *fhdr)
> +{
> +	int used = 0;
> +
> +	cscfg_write_u32(fhdr->magic_version);
> +	cscfg_write_u16(fhdr->length);
> +	cscfg_write_u16(fhdr->nr_features);
> +	return used;
> +}
> +
> +static int cscfg_file_write_string(u8 *buffer, const int buflen, const char *string)
> +{
> +	int len, used = 0;
> +
> +	len = strlen(string);
> +	if (len > CSCFG_FILE_STR_MAXSIZE)
> +		return -EINVAL;
> +
> +	if (buflen < (len + 1 + sizeof(u16)))
> +		return -EINVAL;
> +
> +	cscfg_write_u16((u16)(len + 1));
> +	strcpy((char *)(buffer + used), string);
> +	used += (len + 1);
> +
> +	return used;
> +}
> +
> +static int cscfg_file_write_elem_hdr(u8 *buffer, const int buflen,
> +				     struct cscfg_file_elem_header *ehdr)
> +{
> +	int used = 0;
> +
> +	if (buflen < (sizeof(u16) + sizeof(u8)))
> +		return -EINVAL;
> +
> +	cscfg_write_u16(ehdr->elem_length);
> +	cscfg_write_u8(ehdr->elem_type);
> +
> +	return used;
> +}
> +
> +
> +static int cscfg_file_write_config(u8 *buffer, const int buflen,
> +				   struct cscfg_config_desc *config_desc)
> +{
> +	int used = 0, bytes_w, space_req, preset_bytes, i;
> +	struct cscfg_file_elem_header ehdr;
> +
> +	ehdr.elem_length = 0;
> +	ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_CFG;
> +
> +	/* write element header at current buffer location */
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the configuration name */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  config_desc->name);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the description string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  config_desc->description);
> +	CHECK_WRET(bytes_w);
> +
> +	/*
> +	 * calculate the space needed for variables + presets
> +	 * [u16 value - nr_presets]
> +	 * [u32 value - nr_total_params]
> +	 * [u16 value - nr_feat_refs]
> +	 * [u64 values] * (nr_presets * nr_total_params)
> +	 */
> +	preset_bytes = sizeof(u64) * config_desc->nr_presets * config_desc->nr_total_params;
> +	space_req = (sizeof(u16) * 2) + sizeof(u32) + preset_bytes;
> +
> +	if ((buflen - used) < space_req)
> +		return -EINVAL;
> +
> +	cscfg_write_u16((u16)config_desc->nr_presets);
> +	cscfg_write_u32((u32)config_desc->nr_total_params);
> +	cscfg_write_u16((u16)config_desc->nr_feat_refs);
> +	if (preset_bytes) {
> +		memcpy(buffer + used, (u8 *)config_desc->presets, preset_bytes);
> +		used += preset_bytes;
> +	}
> +
> +	/* now write the feature ref names */
> +	for (i = 0; i < config_desc->nr_feat_refs; i++) {
> +		bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +						  config_desc->feat_ref_names[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* rewrite the element header with the correct length */
> +	ehdr.elem_length = used;
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +
> +	return used;
> +}
> +
> +/*
> + * write a parameter structure into the buffer in following format:
> + * [cscfg_file_elem_str]    - parameter name.
> + * [u64 value: param_value] - initial value.
> + */
> +static int cscfg_file_write_param(u8 *buffer, const int buflen,
> +				  struct cscfg_parameter_desc *param_desc)
> +{
> +	int used = 0, bytes_w;
> +
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  param_desc->name);
> +	CHECK_WRET(bytes_w);
> +
> +	if ((buflen - used) < sizeof(u64))
> +		return -EINVAL;
> +
> +	cscfg_write_u64(param_desc->value);
> +	return used;
> +}
> +/*
> + * Write a feature element from cscfg_feature_desc in following format:
> + *
> + * [cscfg_file_elem_header] - header length is total bytes to end of param structures.
> + * [cscfg_file_elem_str]    - feature name.
> + * [cscfg_file_elem_str]    - feature description.
> + * [u32 value: match_flags]
> + * [u16 value: nr_regs]	    - number of registers.
> + * [u16 value: nr_params]   - number of parameters.
> + * [cscfg_regval_desc struct] * nr_regs
> + * [PARAM_ELEM] * nr_params
> + *
> + *
> + */
> +static int cscfg_file_write_feat(u8 *buffer, const int buflen,
> +				 struct cscfg_feature_desc *feat_desc)
> +{
> +	struct cscfg_file_elem_header ehdr;
> +	struct cscfg_regval_desc *p_reg_desc;
> +	int used = 0, bytes_w, i, space_req;
> +	u32 val32;
> +
> +	ehdr.elem_length = 0;
> +	ehdr.elem_type = CSCFG_FILE_ELEM_TYPE_FEAT;
> +
> +	/* write element header at current buffer location */
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write out the name string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  feat_desc->name);
> +	CHECK_WRET(bytes_w)
> +
> +	/* write out the description string */
> +	bytes_w = cscfg_file_write_string(buffer + used, buflen - used,
> +					  feat_desc->description);
> +	CHECK_WRET(bytes_w);
> +
> +	/* check for space for variables and register structures */
> +	space_req = (sizeof(u16) * 2) + sizeof(u32) +
> +		(sizeof(struct cscfg_regval_desc) * feat_desc->nr_regs);
> +	if ((buflen - used) < space_req)
> +		return -EINVAL;
> +
> +	/* write the variables */
> +	cscfg_write_u32((u32)feat_desc->match_flags);
> +	cscfg_write_u16((u16)feat_desc->nr_regs);
> +	cscfg_write_u16((u16)feat_desc->nr_params);
> +
> +	/*write the registers */
> +	for (i = 0; i < feat_desc->nr_regs; i++) {
> +		p_reg_desc = (struct cscfg_regval_desc *)&feat_desc->regs_desc[i];
> +		CSCFG_FILE_REG_DESC_INFO_TO_U32(val32, p_reg_desc);
> +		cscfg_write_u32(val32);
> +		cscfg_write_u64(feat_desc->regs_desc[i].val64);
> +	}
> +
> +	/* write any parameters */
> +	for (i = 0; i < feat_desc->nr_params; i++) {
> +		bytes_w = cscfg_file_write_param(buffer + used, buflen - used,
> +						 &feat_desc->params_desc[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/*
> +	 * rewrite the element header at the start of the buffer block
> +	 * with the correct length
> +	 */
> +	ehdr.elem_length = used;
> +	bytes_w = cscfg_file_write_elem_hdr(buffer, buflen, &ehdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +
> +	return used;
> +}
> +
> +/*
> + * write a buffer from the configuration and feature
> + * descriptors to write into a file for configfs.
> + *
> + * Will only write one config, and/or a number of features,
> + * per the file standard.
> + */
> +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> +			    struct cscfg_config_desc *config_desc,
> +			    struct cscfg_feature_desc **feat_descs)
> +{
> +	struct cscfg_file_header fhdr;
> +	int used = 0,  bytes_w, i;
> +
> +	/* init the file header */
> +	fhdr.magic_version = CSCFG_FILE_MAGIC_VERSION;
> +	fhdr.length = 0;
> +	fhdr.nr_features = 0;
> +
> +	/* count the features */
> +	if (feat_descs) {
> +		while (feat_descs[fhdr.nr_features])
> +			fhdr.nr_features++;
> +	}
> +
> +	/* need a buffer and at least one config or feature */
> +	if ((!config_desc && !fhdr.nr_features) ||
> +	    !buffer || (buflen > CSCFG_FILE_MAXSIZE))
> +		return -EINVAL;
> +
> +	/* write a header at the start to get the length of the header */
> +	bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> +	CHECK_WRET(bytes_w);
> +
> +	/* write a single config */
> +	if (config_desc) {
> +		bytes_w = cscfg_file_write_config(buffer + used, buflen - used,
> +						  config_desc);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* write any features */
> +	for (i = 0; i < fhdr.nr_features; i++) {
> +		bytes_w = cscfg_file_write_feat(buffer + used, buflen - used,
> +						feat_descs[i]);
> +		CHECK_WRET(bytes_w);
> +	}
> +
> +	/* finally re-write the header at the buffer start with the correct length */
> +	fhdr.length = (u16)used;
> +	bytes_w = cscfg_file_write_fhdr(buffer, buflen, &fhdr);
> +	/* no CHECK_WRET as used must not be updated */
> +	if (bytes_w < 0)
> +		return bytes_w;
> +	return used;
> +}
> diff --git a/samples/coresight/coresight-cfg-bufw.h b/samples/coresight/coresight-cfg-bufw.h
> new file mode 100644
> index 000000000000..00b16c583cad
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-bufw.h
> @@ -0,0 +1,24 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#ifndef _CORESIGHT_CFG_BUFW_H
> +#define _CORESIGHT_CFG_BUFW_H
> +
> +#include "coresight-config-file.h"
> +
> +/*
> + * Function to take coresight configurations and features and
> + * write them into a supplied memory buffer for serialisation
> + * into a file.
> + *
> + * Resulting file can then be loaded into the coresight
> + * infrastructure via configfs.
> + */
> +int cscfg_file_write_buffer(u8 *buffer, const int buflen,
> +			    struct cscfg_config_desc *config_desc,
> +			    struct cscfg_feature_desc **feat_descs);
> +
> +#endif /* _CORESIGHT_CFG_BUFW_H */
> diff --git a/samples/coresight/coresight-cfg-filegen.c b/samples/coresight/coresight-cfg-filegen.c
> new file mode 100644
> index 000000000000..c8be18ee97b6
> --- /dev/null
> +++ b/samples/coresight/coresight-cfg-filegen.c
> @@ -0,0 +1,89 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2020 Linaro Limited, All rights reserved.
> + * Author: Mike Leach <mike.leach at linaro.org>
> + */
> +
> +#include <linux/types.h>
> +#include <linux/unistd.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +
> +#include "coresight-cfg-bufw.h"
> +
> +/*
> + * generate example binary coresight configuration files for loading
> + * into the coresight subsystem via configfs
> + */
> +
> +/* create a similar configuration example as the coresight-cfg-sample.c file. */
> +
> +/* we will provide 4 sets of preset parameter values */
> +#define AFDO2_NR_PRESETS	4
> +/* the total number of parameters in used features - strobing has 2 */
> +#define AFDO2_NR_PARAM_SUM	2
> +
> +static const char *afdo2_ref_names[] = {
> +	"strobing",
> +};
> +
> +/*
> + * set of presets leaves strobing window constant while varying period to allow
> + * experimentation with mark / space ratios for various workloads
> + */
> +static u64 afdo2_presets[AFDO2_NR_PRESETS][AFDO2_NR_PARAM_SUM] = {
> +	{ 2000, 100 },
> +	{ 2000, 1000 },
> +	{ 2000, 5000 },
> +	{ 2000, 10000 },
> +};
> +
> +struct cscfg_config_desc afdo3 = {
> +	.name = "autofdo3",
> +	.description = "Setup ETMs with strobing for autofdo\n"
> +	"Supplied presets allow experimentation with mark-space ratio for various loads\n",
> +	.nr_feat_refs = ARRAY_SIZE(afdo2_ref_names),
> +	.feat_ref_names = afdo2_ref_names,
> +	.nr_presets = AFDO2_NR_PRESETS,
> +	.nr_total_params = AFDO2_NR_PARAM_SUM,
> +	.presets = &afdo2_presets[0][0],
> +};
> +
> +static struct cscfg_feature_desc *sample_feats[] = {
> +	NULL
> +};
> +
> +static struct cscfg_config_desc *sample_cfgs[] = {
> +	&afdo3,
> +	NULL
> +};
> +
> +
> +#define CSCFG_BIN_FILENAME "example1.cscfg"
> +
> +int main(int argc, char **argv)
> +{
> +	u8 buffer[CSCFG_FILE_MAXSIZE];
> +	int used;
> +	FILE *fp;
> +
> +	printf("Coresight Configuration file Generator\n\n");
> +
> +	used = cscfg_file_write_buffer(buffer, CSCFG_FILE_MAXSIZE,
> +				       sample_cfgs[0], sample_feats);
> +
> +	if (used < 0) {
> +		printf("Error %d writing configuration %s into buffer\n",
> +		       used, sample_cfgs[0]->name);
> +		return used;
> +	}
> +
> +	fp = fopen(CSCFG_BIN_FILENAME, "wb");
> +	if (fp == NULL) {
> +		printf("Error opening file %s\n", CSCFG_BIN_FILENAME);
> +		return -1;
> +	}
> +	fwrite(buffer, used, sizeof(u8), fp);
> +	fclose(fp);
> +	return 0;
> +}
> -- 
> 2.17.1
> 


From catalin.marinas at arm.com  Fri Jan 28 11:14:29 2022
From: catalin.marinas at arm.com (Catalin Marinas)
Date: Fri, 28 Jan 2022 19:14:29 +0000
Subject: [GIT PULL] arm64 fixes for 5.17-rc2
Message-ID: <YfRAlb4M0Su+iyow@arm.com>

Hi Linus,

Please pull the arm64 fixes below. Thanks.

The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

  Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

for you to fetch changes up to 297ae1eb23b04c5a46111ab53c8d0f69af43f402:

  arm64: cpufeature: List early Cortex-A510 parts as having broken dbm (2022-01-28 16:15:46 +0000)

----------------------------------------------------------------
arm64 fixes:

- Errata workarounds for Cortex-A510: broken hardware dirty bit
  management, detection code for the TRBE (tracing) bugs with the actual
  fixes going in via the CoreSight tree.

- Cortex-X2 errata handling for TRBE (inheriting the workarounds from
  Cortex-A710).

- Fix ex_handler_load_unaligned_zeropad() to use the correct struct
  members.

- A couple of kselftest fixes for FPSIMD.

- Silence the vdso "no previous prototype" warning.

- Mark start_backtrace() notrace and NOKPROBE_SYMBOL.

----------------------------------------------------------------
Anshuman Khandual (6):
      arm64: Add Cortex-X2 CPU part definition
      arm64: errata: Update ARM64_ERRATUM_[2119858|2224489] with Cortex-X2 ranges
      arm64: Add Cortex-A510 CPU part definition
      arm64: errata: Add detection for TRBE ignored system register writes
      arm64: errata: Add detection for TRBE invalid prohibited states
      arm64: errata: Add detection for TRBE trace data corruption

Catalin Marinas (1):
      Merge tag 'trbe-cortex-a510-errata' of gitolite.kernel.org:pub/scm/linux/kernel/git/coresight/linux into for-next/fixes

Evgenii Stepanov (1):
      arm64: extable: fix load_unaligned_zeropad() reg indices

James Morse (1):
      arm64: cpufeature: List early Cortex-A510 parts as having broken dbm

Mark Brown (2):
      kselftest/arm64: Skip VL_INHERIT tests for unsupported vector types
      kselftest/arm64: Correct logging of FPSIMD register read via ptrace

Masami Hiramatsu (1):
      arm64: Mark start_backtrace() notrace and NOKPROBE_SYMBOL

Vincenzo Frascino (1):
      arm64: vdso: Fix "no previous prototype" warning

 Documentation/arm64/silicon-errata.rst        | 12 ++++
 arch/arm64/Kconfig                            | 81 +++++++++++++++++++++++++--
 arch/arm64/include/asm/cputype.h              |  4 ++
 arch/arm64/kernel/cpu_errata.c                | 29 ++++++++++
 arch/arm64/kernel/cpufeature.c                |  3 +
 arch/arm64/kernel/stacktrace.c                |  5 +-
 arch/arm64/kernel/vdso/Makefile               |  5 +-
 arch/arm64/mm/extable.c                       |  4 +-
 arch/arm64/tools/cpucaps                      |  3 +
 tools/testing/selftests/arm64/fp/sve-ptrace.c | 11 +++-
 10 files changed, 144 insertions(+), 13 deletions(-)

-- 
Catalin


From ricarkol at google.com  Fri Jan 28 11:27:21 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Fri, 28 Jan 2022 11:27:21 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <CAAeT=FzNSvzz-Ok0Ka95=kkdDGsAMmzf9xiRfD5gYCdvmEfifg@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
 <YfDaiUbSkpi9/5YY@google.com>
 <CAAeT=FzNSvzz-Ok0Ka95=kkdDGsAMmzf9xiRfD5gYCdvmEfifg@mail.gmail.com>
Message-ID: <CAOHnOrwBoQncTPngxqWgD_mEDWT6AwcmB_QC=j-eUPY2fwHa2Q@mail.gmail.com>

On Thu, Jan 27, 2022 at 10:24 PM Reiji Watanabe <reijiw at google.com> wrote:
>
> Hi Ricardo,
>
> On Tue, Jan 25, 2022 at 9:22 PM Ricardo Koller <ricarkol at google.com> wrote:
> >
> > On Wed, Jan 05, 2022 at 08:26:44PM -0800, Reiji Watanabe wrote:
> > > Introduce id_regs[] in kvm_arch as a storage of guest's ID registers,
> > > and save ID registers' sanitized value in the array at KVM_CREATE_VM.
> > > Use the saved ones when ID registers are read by the guest or
> > > userspace (via KVM_GET_ONE_REG).
> > >
> > > Signed-off-by: Reiji Watanabe <reijiw at google.com>
> > > ---
> > >  arch/arm64/include/asm/kvm_host.h | 16 ++++++++
> > >  arch/arm64/kvm/arm.c              |  1 +
> > >  arch/arm64/kvm/sys_regs.c         | 62 ++++++++++++++++++++++---------
> > >  3 files changed, 62 insertions(+), 17 deletions(-)
> > >
> > > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > > index 2a5f7f38006f..c789a0137f58 100644
> > > --- a/arch/arm64/include/asm/kvm_host.h
> > > +++ b/arch/arm64/include/asm/kvm_host.h
> > > @@ -102,6 +102,17 @@ struct kvm_s2_mmu {
> > >  struct kvm_arch_memory_slot {
> > >  };
> > >
> > > +/*
> > > + * (Op0, Op1, CRn, CRm, Op2) of ID registers is (3, 0, 0, crm, op2),
> > > + * where 0<=crm<8, 0<=op2<8.
> >
> > Is this observation based on this table?
> >
> > Table D12-2 System instruction encodings for non-Debug System register accesses
> > in that case, it seems that the ID registers list might grow after
> > crm=7, and as CRm has 4 bits, why not 16*8=128?
>
> This is basically for registers that are already reserved as RAZ in the
> table (sys_reg_descs[] has entries for the reserved ones as well).
> Registers with crm > 7 are not reserved yet, and that will be expanded
> later as needed later.
>
>
> >
> > > + */
> > > +#define KVM_ARM_ID_REG_MAX_NUM       64
> > > +#define IDREG_IDX(id)                ((sys_reg_CRm(id) << 3) | sys_reg_Op2(id))
> > > +#define is_id_reg(id)        \
> > > +     (sys_reg_Op0(id) == 3 && sys_reg_Op1(id) == 0 &&        \
> > > +      sys_reg_CRn(id) == 0 && sys_reg_CRm(id) >= 0 &&        \
> > > +      sys_reg_CRm(id) < 8)
> > > +
> > >  struct kvm_arch {
> > >       struct kvm_s2_mmu mmu;
> > >
> > > @@ -137,6 +148,9 @@ struct kvm_arch {
> > >
> > >       /* Memory Tagging Extension enabled for the guest */
> > >       bool mte_enabled;
> > > +
> > > +     /* ID registers for the guest. */
> > > +     u64 id_regs[KVM_ARM_ID_REG_MAX_NUM];
> > >  };
> > >
> > >  struct kvm_vcpu_fault_info {
> > > @@ -734,6 +748,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
> > >  long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
> > >                               struct kvm_arm_copy_mte_tags *copy_tags);
> > >
> > > +void set_default_id_regs(struct kvm *kvm);
> > > +
> > >  /* Guest/host FPSIMD coordination helpers */
> > >  int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> > >  void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu);
> > > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > > index e4727dc771bf..5f497a0af254 100644
> > > --- a/arch/arm64/kvm/arm.c
> > > +++ b/arch/arm64/kvm/arm.c
> > > @@ -156,6 +156,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
> > >       kvm->arch.max_vcpus = kvm_arm_default_max_vcpus();
> > >
> > >       set_default_spectre(kvm);
> > > +     set_default_id_regs(kvm);
> > >
> > >       return ret;
> > >  out_free_stage2_pgd:
> > > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
> > > index e3ec1a44f94d..80dc62f98ef0 100644
> > > --- a/arch/arm64/kvm/sys_regs.c
> > > +++ b/arch/arm64/kvm/sys_regs.c
> > > @@ -33,6 +33,8 @@
> > >
> > >  #include "trace.h"
> > >
> > > +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id);
> > > +
> > >  /*
> > >   * All of this file is extremely similar to the ARM coproc.c, but the
> > >   * types are different. My gut feeling is that it should be pretty
> > > @@ -273,7 +275,7 @@ static bool trap_loregion(struct kvm_vcpu *vcpu,
> > >                         struct sys_reg_params *p,
> > >                         const struct sys_reg_desc *r)
> > >  {
> > > -     u64 val = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1);
> > > +     u64 val = __read_id_reg(vcpu, SYS_ID_AA64MMFR1_EL1);
> > >       u32 sr = reg_to_encoding(r);
> > >
> > >       if (!(val & (0xfUL << ID_AA64MMFR1_LOR_SHIFT))) {
> > > @@ -1059,17 +1061,9 @@ static bool access_arch_timer(struct kvm_vcpu *vcpu,
> > >       return true;
> > >  }
> > >
> > > -/* Read a sanitised cpufeature ID register by sys_reg_desc */
> > > -static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> > > -             struct sys_reg_desc const *r, bool raz)
> > > +static u64 __read_id_reg(const struct kvm_vcpu *vcpu, u32 id)
> > >  {
> > > -     u32 id = reg_to_encoding(r);
> > > -     u64 val;
> > > -
> > > -     if (raz)
> > > -             return 0;
> > > -
> > > -     val = read_sanitised_ftr_reg(id);
> > > +     u64 val = vcpu->kvm->arch.id_regs[IDREG_IDX(id)];
> > >
> > >       switch (id) {
> > >       case SYS_ID_AA64PFR0_EL1:
> > > @@ -1119,6 +1113,14 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> > >       return val;
> > >  }
> > >
> > > +static u64 read_id_reg(const struct kvm_vcpu *vcpu,
> > > +                    struct sys_reg_desc const *r, bool raz)
> > > +{
> > > +     u32 id = reg_to_encoding(r);
> > > +
> > > +     return raz ? 0 : __read_id_reg(vcpu, id);
> > > +}
> > > +
> > >  static unsigned int id_visibility(const struct kvm_vcpu *vcpu,
> > >                                 const struct sys_reg_desc *r)
> > >  {
> > > @@ -1223,9 +1225,8 @@ static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
> > >  /*
> > >   * cpufeature ID register user accessors
> > >   *
> > > - * For now, these registers are immutable for userspace, so no values
> > > - * are stored, and for set_id_reg() we don't allow the effective value
> > > - * to be changed.
> > > + * For now, these registers are immutable for userspace, so for set_id_reg()
> > > + * we don't allow the effective value to be changed.
> > >   */
> > >  static int __get_id_reg(const struct kvm_vcpu *vcpu,
> > >                       const struct sys_reg_desc *rd, void __user *uaddr,
> > > @@ -1237,7 +1238,7 @@ static int __get_id_reg(const struct kvm_vcpu *vcpu,
> > >       return reg_to_user(uaddr, &val, id);
> > >  }
> > >
> > > -static int __set_id_reg(const struct kvm_vcpu *vcpu,
> > > +static int __set_id_reg(struct kvm_vcpu *vcpu,
> > >                       const struct sys_reg_desc *rd, void __user *uaddr,
> > >                       bool raz)
> > >  {
> > > @@ -1837,8 +1838,8 @@ static bool trap_dbgdidr(struct kvm_vcpu *vcpu,
> > >       if (p->is_write) {
> > >               return ignore_write(vcpu, p);
> > >       } else {
> > > -             u64 dfr = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
> > > -             u64 pfr = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
> > > +             u64 dfr = __read_id_reg(vcpu, SYS_ID_AA64DFR0_EL1);
> > > +             u64 pfr = __read_id_reg(vcpu, SYS_ID_AA64PFR0_EL1);
> > >               u32 el3 = !!cpuid_feature_extract_unsigned_field(pfr, ID_AA64PFR0_EL3_SHIFT);
> > >
> > >               p->regval = ((((dfr >> ID_AA64DFR0_WRPS_SHIFT) & 0xf) << 28) |
> > > @@ -2850,3 +2851,30 @@ void kvm_sys_reg_table_init(void)
> > >       /* Clear all higher bits. */
> > >       cache_levels &= (1 << (i*3))-1;
> > >  }
> > > +
> > > +/*
> > > + * Set the guest's ID registers that are defined in sys_reg_descs[]
> > > + * with ID_SANITISED() to the host's sanitized value.
> > > + */
> > > +void set_default_id_regs(struct kvm *kvm)
> > > +{
> > > +     int i;
> > > +     u32 id;
> > > +     const struct sys_reg_desc *rd;
> > > +     u64 val;
> > > +
> > > +     for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> > > +             rd = &sys_reg_descs[i];
> > > +             if (rd->access != access_id_reg)
> > > +                     /* Not ID register, or hidden/reserved ID register */
> > > +                     continue;
> > > +
> > > +             id = reg_to_encoding(rd);
> > > +             if (WARN_ON_ONCE(!is_id_reg(id)))
> > > +                     /* Shouldn't happen */
> > > +                     continue;
> > > +
> > > +             val = read_sanitised_ftr_reg(id);
> >
> > I'm a bit confused. Shouldn't the default+sanitized values already use
> > arm64_ftr_bits_kvm (instead of arm64_ftr_regs)?
>
> I'm not sure if I understand your question.
> arm64_ftr_bits_kvm is used for feature support checkings when
> userspace tries to modify a value of ID registers.
> With this patch, KVM just saves the sanitized values in the kvm's
> buffer, but userspace is still not allowed to modify values of ID
> registers yet.
> I hope it answers your question.

Based on the previous commit I was assuming that some registers, like
id_aa64dfr0,
would default to the overwritten values as the sanitized values. More
specifically: if
userspace doesn't modify any ID reg, shouldn't the defaults have the
KVM overwritten
values (arm64_ftr_bits_kvm)?

>
> Thanks,
> Reiji
>
> >
> > > +             kvm->arch.id_regs[IDREG_IDX(id)] = val;
> > > +     }
> > > +}
> > > --
> > > 2.34.1.448.ga2b2bfdf31-goog
> > >


From wsa+renesas at sang-engineering.com  Fri Jan 28 11:29:06 2022
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Fri, 28 Jan 2022 20:29:06 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfP0osb45uJldtM9@localhost.localdomain>
References: <YfP0osb45uJldtM9@localhost.localdomain>
Message-ID: <YfREAiRMjQ9ci4LC@shikoro>


> +	/* We want this to take priority over PSCI which has priority of 129. */
> +	.priority = 130,

Is it an idea to add a #define for the PSCI priority somewhere and use
here the define + 1? Hardcoded priorities look a bit fragile to me.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/93804a69/attachment.sig>

From theleks at ko-hh.de  Fri Jan 28 11:31:50 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Fri, 28 Jan 2022 20:31:50 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: fix boot loop after reboot
Message-ID: <20220128193150.GA1304381@odroid-VirtualBox>

Since the correct gpio pin is used for enabling tf-io regulator the
system did not boot correctly after calling reboot.

[   36.862443] reboot: Restarting system
bl31 reboot reason: 0xd
bl31 reboot reason: 0x0
system cmd  1.
SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:B;RCY:0;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:0;READ:0;0.0;CHK:0;
bl2_stage_init 0x01
bl2_stage_init 0x81
hw id:?SM1:BL:511f6b:81ca2f;FEAT:A0F83180:20282000;POC:B;RCY:0;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:1;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:2;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:3;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:4;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;LOOP:5;SPINOR:0;CHK:1F;EMMC:800;NAND:81;SD?:0;SD:400;USB:8;

Setting the gpio to open drain solves the issue.

Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
---
 arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
index ed7cd5f53046..ddb1b345397f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
@@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
 		regulator-max-microvolt = <3300000>;
 		vin-supply = <&vcc_5v>;
 
-		enable-gpio = <&gpio_ao GPIOE_2 GPIO_ACTIVE_HIGH>;
+		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
 		enable-active-high;
 		regulator-always-on;
 
-- 
2.25.1



From broonie at kernel.org  Fri Jan 28 11:32:03 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 19:32:03 +0000
Subject: [RESEND PATCH 1/2] dt-bindings: firmware: arm,scmi: define
 support for name based regulators
In-Reply-To: <fcd130891cc1d52cb09b8bfc866ab7ef1ce3b2a1.1643069954.git.quic_collinsd@quicinc.com>
References: <cover.1643069954.git.quic_collinsd@quicinc.com>
 <fcd130891cc1d52cb09b8bfc866ab7ef1ce3b2a1.1643069954.git.quic_collinsd@quicinc.com>
Message-ID: <YfREsxeSSX2pbALf@sirena.org.uk>

On Mon, Jan 24, 2022 at 04:27:35PM -0800, David Collins wrote:

> Name based SCMI regulator specification helps ensure that an SCMI
> agent doesn't need to be aware of the numbering scheme used for

What is a "SCMI agent" in this context?  This is changing how the DT
bindings are specified, at some point things are going to need to be
hard coded.

> +              regulator-name: true
> +
> +            anyOf:
> +              - required:
> +                  - reg
> +              - required:
> +                  - regulator-name

This is abusing the existing regulator-name property which is there to
allow a human readable descriptive string to be attached to a regulator.
It should have no effect other than being included in diagnostic output.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/9947805f/attachment.sig>

From alisaidi at amazon.com  Fri Jan 28 13:02:45 2022
From: alisaidi at amazon.com (Ali Saidi)
Date: Fri, 28 Jan 2022 21:02:45 +0000
Subject: [PATCH 2/2] perf arm-spe: Parse more SPE fields and store source
In-Reply-To: <b1b3697d-4a0a-d041-5cbd-e08fec9e658c@arm.com>
References: <b1b3697d-4a0a-d041-5cbd-e08fec9e658c@arm.com>
Message-ID: <20220128210245.4628-1-alisaidi@amazon.com>

Hi German,

On 28/01/2022 19:20, German Gomez wrote:
>Hi Ali,
>
>On 25/01/2022 19:20, Ali Saidi wrote:
>> Decode more SPE events and op types to allow for processing by perf
>> scripts. For example looking for branches which may indicate candidates
>> for conversion to a CSEL, store exclusives that are candidates for
>> conversion to LSE atomics and record the source information for memory
>> ops.
>> [snip]
>> +				if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
>> +					if (payload & SPE_OP_PKT_AT)
>> +						decoder->record.op |= ARM_SPE_LDST_ATOMIC;
>
>In "utils/arm-spe.c" we check "if (record->op == ARM_SPE_LD)" so this
>ORing could break some of the generated samples.

Yep, you're correct. Interestingly I can only find one use of record->op using
equivalence instead of a logical and so perhaps it's best to fix this one use.

...
>> diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
>> index 69b31084d6be..113e427afe99 100644
>> --- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
>> +++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
>> @@ -22,11 +22,18 @@ enum arm_spe_sample_type {
>>  	ARM_SPE_TLB_MISS	= 1 << 5,
>>  	ARM_SPE_BRANCH_MISS	= 1 << 6,
>>  	ARM_SPE_REMOTE_ACCESS	= 1 << 7,
>> +	ARM_SPE_BR_NOT_TAKEN	= 1 << 8,
>
>Can you rename it to ARM_SPE_BRANCH_NOT_TAKEN for consistency?

No problem

>
>>  };
>>  
>>  enum arm_spe_op_type {
>>  	ARM_SPE_LD		= 1 << 0,
>>  	ARM_SPE_ST		= 1 << 1,
>> +	ARM_SPE_LDST_EXCL	= 1 << 2,
>> +	ARM_SPE_LDST_ATOMIC	= 1 << 3,
>> +	ARM_SPE_LDST_ACQREL	= 1 << 4,
>> +	ARM_SPE_BR		= 1 << 5,
>> +	ARM_SPE_BR_COND		= 1 << 6,
>> +	ARM_SPE_BR_IND		= 1 << 7,
>
>I'm not sure if we should keep everything in one enum/bitmask. I'm also
>looking at adding more of the data from the packets to the record, and
>considering refactoring the record structure. I'll share here when I
>have something.

One straight forward way to do this would be to make it a u16 field that was 
SPE operation-type header and operation-type payload with some accessors instead
of trying to re-encode the operation type into a new format.

Thanks,
Ali



From lkp at intel.com  Fri Jan 28 13:03:18 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 29 Jan 2022 05:03:18 +0800
Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21
In-Reply-To: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>
References: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>
Message-ID: <202201290246.pin2pNs4-lkp@intel.com>

Hi "Uwe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on shawnguo/for-next]
[also build test ERROR on robh/for-next pza/reset/next v5.17-rc1 next-20220128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
config: riscv-allyesconfig (https://download.01.org/0day-ci/archive/20220129/202201290246.pin2pNs4-lkp at intel.com/config)
compiler: riscv64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/cba99931972f752a7b3105a3697b0cda88fe54d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
        git checkout cba99931972f752a7b3105a3697b0cda88fe54d4
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=riscv SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> scripts/Makefile.build:44: drivers/gpu/drm/imx/imx21-lcdc/Makefile: No such file or directory
>> make[6]: *** No rule to make target 'drivers/gpu/drm/imx/imx21-lcdc/Makefile'.
   make[6]: Failed to remake makefile 'drivers/gpu/drm/imx/imx21-lcdc/Makefile'.


vim +44 scripts/Makefile.build

20a468b51325b3 Sam Ravnborg   2006-01-22  40  
2a691470345a00 Sam Ravnborg   2005-07-25  41  # The filename Kbuild has precedence over Makefile
db8c1a7b2ca25f Sam Ravnborg   2005-07-27  42  kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
0c53c8e6eb456c Sam Ravnborg   2007-10-14  43  kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
0c53c8e6eb456c Sam Ravnborg   2007-10-14 @44  include $(kbuild-file)
^1da177e4c3f41 Linus Torvalds 2005-04-16  45  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From joe.lawrence at redhat.com  Fri Jan 28 13:11:39 2022
From: joe.lawrence at redhat.com (Joe Lawrence)
Date: Fri, 28 Jan 2022 16:11:39 -0500
Subject: [PATCH] ftrace: Have architectures opt-in for mcount build time
 sorting
In-Reply-To: <20220127114249.03b1b52b@gandalf.local.home>
References: <20220127114249.03b1b52b@gandalf.local.home>
Message-ID: <YfRcC/ggq90jw7Uc@redhat.com>

On Thu, Jan 27, 2022 at 11:42:49AM -0500, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt at goodmis.org>
>
> First S390 complained that the sorting of the mcount sections at build
> time caused the kernel to crash on their architecture. Now PowerPC is
> complaining about it too. And also ARM64 appears to be having issues.
>
> It may be necessary to also update the relocation table for the values
> in the mcount table. Not only do we have to sort the table, but also
> update the relocations that may be applied to the items in the table.
>
> If the system is not relocatable, then it is fine to sort, but if it is,
> some architectures may have issues (although x86 does not as it shifts all
> addresses the same).
>
> Add a HAVE_BUILDTIME_MCOUNT_SORT that an architecture can set to say it is
> safe to do the sorting at build time.
>
> Also update the config to compile in build time sorting in the sorttable
> code in scripts/ to depend on CONFIG_BUILDTIME_MCOUNT_SORT.
>
> Link: https://lore.kernel.org/all/944D10DA-8200-4BA9-8D0A-3BED9AA99F82 at linux.ibm.com/
>
> Cc: Mark Rutland <mark.rutland at arm.com>
> Cc: Yinan Liu <yinan at linux.alibaba.com>
> Cc: Ard Biesheuvel <ardb at kernel.org>
> Cc: Kees Cook <keescook at chromium.org>
> Cc: linuxppc-dev at lists.ozlabs.org
> Reported-by: Sachin Sant <sachinp at linux.ibm.com>
> Tested-by: Sachin Sant <sachinp at linux.ibm.com>
> Fixes: 72b3942a173c ("scripts: ftrace - move the sort-processing in ftrace_init")
> Signed-off-by: Steven Rostedt (Google) <rostedt at goodmis.org>
> ---
>  arch/arm/Kconfig     | 1 +
>  arch/x86/Kconfig     | 1 +
>  kernel/trace/Kconfig | 8 +++++++-
>  scripts/Makefile     | 2 +-
>  4 files changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index c2724d986fa0..5256ebe57451 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -82,6 +82,7 @@ config ARM
>  	select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
>  	select HAVE_CONTEXT_TRACKING
>  	select HAVE_C_RECORDMCOUNT
> +	select HAVE_BUILDTIME_MCOUNT_SORT
>  	select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
>  	select HAVE_DMA_CONTIGUOUS if MMU
>  	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 7399327d1eff..46080dea5dba 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -186,6 +186,7 @@ config X86
>  	select HAVE_CONTEXT_TRACKING_OFFSTACK	if HAVE_CONTEXT_TRACKING
>  	select HAVE_C_RECORDMCOUNT
>  	select HAVE_OBJTOOL_MCOUNT		if STACK_VALIDATION
> +	select HAVE_BUILDTIME_MCOUNT_SORT
>  	select HAVE_DEBUG_KMEMLEAK
>  	select HAVE_DMA_CONTIGUOUS
>  	select HAVE_DYNAMIC_FTRACE
> diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
> index 752ed89a293b..7e5b92090faa 100644
> --- a/kernel/trace/Kconfig
> +++ b/kernel/trace/Kconfig
> @@ -70,10 +70,16 @@ config HAVE_C_RECORDMCOUNT
>  	help
>  	  C version of recordmcount available?
>
> +config HAVE_BUILDTIME_MCOUNT_SORT
> +       bool
> +       help
> +         An architecture selects this if it sorts the mcount_loc section
> +	 at build time.
> +
>  config BUILDTIME_MCOUNT_SORT
>         bool
>         default y
> -       depends on BUILDTIME_TABLE_SORT && !S390
> +       depends on HAVE_BUILDTIME_MCOUNT_SORT
>         help
>           Sort the mcount_loc section at build time.
>
> diff --git a/scripts/Makefile b/scripts/Makefile
> index b082d2f93357..cedc1f0e21d8 100644
> --- a/scripts/Makefile
> +++ b/scripts/Makefile
> @@ -32,7 +32,7 @@ HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include
>  HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED
>  endif
>
> -ifdef CONFIG_DYNAMIC_FTRACE
> +ifdef CONFIG_BUILDTIME_MCOUNT_SORT
>  HOSTCFLAGS_sorttable.o += -DMCOUNT_SORT_ENABLED
>  endif
>
> --
> 2.33.0
>

Hi Steve,

I just finished bisecting what is probably the same problem... when
running the livepatch selftests for 5.17-rc1, x86_64 passes, but I kept
getting errors like this on ppc64le:

  kernel: livepatch: enabling patch 'test_klp_livepatch'
  kernel: livepatch: failed to find location for function 'cmdline_proc_show'
  kernel: livepatch: failed to patch object 'vmlinux'
  kernel: livepatch: failed to enable patch 'test_klp_livepatch'
  kernel: livepatch: 'test_klp_livepatch': unpatching complete

which means klp_get_ftrace_location() / ftrace_location_range() hit a
problem with that function.

The bisect finally landed on:

  72b3942a173c387b27860ba1069636726e208777 is the first bad commit
  commit 72b3942a173c387b27860ba1069636726e208777
  Author: Yinan Liu <yinan at linux.alibaba.com>
  Date:   Sun Dec 12 19:33:58 2021 +0800

      scripts: ftrace - move the sort-processing in ftrace_init

and I can confirm that your updates today in "[for-linus][PATCH 00/10]
tracing: Fixes for 5.17-rc1" fix or avoid the issue.  I just wanted to
add my report in case this adds any future complications for mcount
build time sorting.  Let me know if any additional tests would be
helpful.

Regards,

-- Joe



From abel.vesa at nxp.com  Fri Jan 28 13:21:47 2022
From: abel.vesa at nxp.com (Abel Vesa)
Date: Fri, 28 Jan 2022 23:21:47 +0200
Subject: [PATCH] clk: imx: Fix a NULL pointer dereference in
 imx_register_uart_clocks()
In-Reply-To: <YfQQ3iQhSxCiUQ2U@kroah.com>
References: <20220124165206.55059-1-zhou1615@umn.edu>
 <YfPCdPuoB3RYgzL8@kroah.com>
 <CAHCN7x+bvC70Y18j8tvSVZNjwipYu3xTvFo=AjKvYnmaucBiGg@mail.gmail.com>
 <YfQQ3iQhSxCiUQ2U@kroah.com>
Message-ID: <YfReawz+QGsgkYgR@abelvesa>

On 22-01-28 16:50:54, Greg KH wrote:
> On Fri, Jan 28, 2022 at 07:47:06AM -0600, Adam Ford wrote:
> > On Fri, Jan 28, 2022 at 4:16 AM Greg KH <gregkh at linuxfoundation.org> wrote:
> > >
> > > On Tue, Jan 25, 2022 at 12:52:06AM +0800, Zhou Qingyang wrote:
> > > > In imx_register_uart_clocks(), the global variable imx_uart_clocks is
> > > > assigned by kcalloc() and there is a dereference of in the next for loop,
> > > > which could introduce a NULL pointer dereference on failure of kcalloc().
> > > >
> > > > Fix this by adding a NULL check of imx_uart_clocks.
> > > >
> > > > This bug was found by a static analyzer.
> > > >
> > > > Builds with 'make allyesconfig' show no new warnings,
> > > > and our static analyzer no longer warns about this code.
> > > >
> > > > Fixes: 379c9a24cc23 ("clk: imx: Fix reparenting of UARTs not associated with stdout")
> > > > Signed-off-by: Zhou Qingyang <zhou1615 at umn.edu>
> > > > ---
> > > > The analysis employs differential checking to identify inconsistent
> > > > security operations (e.g., checks or kfrees) between two code paths
> > > > and confirms that the inconsistent operations are not recovered in the
> > > > current function or the callers, so they constitute bugs.
> > > >
> > > > Note that, as a bug found by static analysis, it can be a false
> > > > positive or hard to trigger. Multiple researchers have cross-reviewed
> > > > the bug.
> > > >
> > > >  drivers/clk/imx/clk.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > >
> > > > diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
> > > > index 7cc669934253..99249ab361d2 100644
> > > > --- a/drivers/clk/imx/clk.c
> > > > +++ b/drivers/clk/imx/clk.c
> > > > @@ -173,6 +173,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
> > > >               int i;
> > > >
> > > >               imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
> > > > +             if (!imx_uart_clocks)
> > > > +                     return;
> > > >
> > > >               if (!of_stdout)
> > > >                       return;
> > > > --
> > > > 2.25.1
> > > >
> > >
> > > As stated before, umn.edu is still not allowed to contribute to the
> > > Linux kernel.  Please work with your administration to resolve this
> > > issue.

I'll ignore any patch from umn.edu until further notice.

> > 
> > Greg,
> > 
> > In the interest of safety, I believe this patch is reasonable.
> 
> How can kcalloc really fail here?  Seriously, this is an impossible
> thing to happen in real-world situations, you have to have special
> fault-injection tooling to ever hit this in a system that is not just
> frozen due to other problems.

Totally agree.

> 
> > I
> > wrote the original patch that is being fixed by this.  Would it be
> > acceptable if I submitted the same patch with "suggested-by"
> > associated with Zhou @ umn.edu?  I want to give credit where credit is
> > due while still maintaining the rule that patches are not actually
> > being accepted by umn.edu.
> 
> If you think this really is needed, then yes, feel free to rewrite it.
> 
> But rewrite it to be correct.  As it is, this is not correct.  If an
> error happens because we are out of memory, actually handle that and do
> not just return as if everything worked properly like this patch is
> doing here.
> 
> The "suggestion" here is incorrect, which is the big problem here.
> Whatever tool this group is using is wrong, and as a few people have
> hinted to me offline, maybe they are just still messing around with us
> and seeing how we behave.  Personally, I'm starting to get mad.

Lets consider this matter closed. The fix is quite pointless, TBH.

> 
> thanks,
> 
> greg k-h


From colin.foster at in-advantage.com  Fri Jan 28 13:32:34 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Fri, 28 Jan 2022 13:32:34 -0800
Subject: [PATCH] pinctrl: microchip-sgpio: Fix support for regmap
In-Reply-To: <CAHp75Vc71mnKST5aFGEivoU8ZhmmRf-ArNYVMb5Cf52jE8jetQ@mail.gmail.com>
References: <20220125161245.418882-1-horatiu.vultur@microchip.com>
 <20220125164659.GA31440@COLIN-DESKTOP1.localdomain>
 <CAHp75Vc71mnKST5aFGEivoU8ZhmmRf-ArNYVMb5Cf52jE8jetQ@mail.gmail.com>
Message-ID: <20220128213234.GA1638668@euler>

On Fri, Jan 28, 2022 at 04:19:12PM +0200, Andy Shevchenko wrote:
> On Wed, Jan 26, 2022 at 3:19 AM Colin Foster
> <colin.foster at in-advantage.com> wrote:
> > On Tue, Jan 25, 2022 at 05:12:45PM +0100, Horatiu Vultur wrote:
> 
> > The only difference is I
> > had copied reg_stride into sgpio_priv instead of making regmap_config
> > file-scope.
> 
> I'm wondering if we may access config via a pointer to regmap.

Ooh... regmap_get_reg_stride() exists. I didn't see that before. That
seems like it is the answer.

I don't know the etiquette here. Ask Horatiu to re-submit, or me send
along a v2, or something else.

> 
> -- 
> With Best Regards,
> Andy Shevchenko


From rostedt at goodmis.org  Fri Jan 28 13:39:48 2022
From: rostedt at goodmis.org (Steven Rostedt)
Date: Fri, 28 Jan 2022 16:39:48 -0500
Subject: [PATCH] ftrace: Have architectures opt-in for mcount build time
 sorting
In-Reply-To: <YfRcC/ggq90jw7Uc@redhat.com>
References: <20220127114249.03b1b52b@gandalf.local.home>
 <YfRcC/ggq90jw7Uc@redhat.com>
Message-ID: <20220128163948.721c8b12@gandalf.local.home>

On Fri, 28 Jan 2022 16:11:39 -0500
Joe Lawrence <joe.lawrence at redhat.com> wrote:

> The bisect finally landed on:
> 
>   72b3942a173c387b27860ba1069636726e208777 is the first bad commit
>   commit 72b3942a173c387b27860ba1069636726e208777
>   Author: Yinan Liu <yinan at linux.alibaba.com>
>   Date:   Sun Dec 12 19:33:58 2021 +0800
> 
>       scripts: ftrace - move the sort-processing in ftrace_init
> 
> and I can confirm that your updates today in "[for-linus][PATCH 00/10]
> tracing: Fixes for 5.17-rc1" fix or avoid the issue.  I just wanted to
> add my report in case this adds any future complications for mcount
> build time sorting.  Let me know if any additional tests would be
> helpful.

Thanks for letting me know. That patch set has already landed in Linus's
tree.


-- Steve


From nicolas at ndufresne.ca  Fri Jan 28 13:49:21 2022
From: nicolas at ndufresne.ca (Nicolas Dufresne)
Date: Fri, 28 Jan 2022 16:49:21 -0500
Subject: [PATCH v6, 06/15] media: mtk-vcodec: Refactor get and put
 capture buffer flow
In-Reply-To: <20220122035316.18179-7-yunfei.dong@mediatek.com>
References: <20220122035316.18179-1-yunfei.dong@mediatek.com>
 <20220122035316.18179-7-yunfei.dong@mediatek.com>
Message-ID: <b07ac9bebb1d2ecef8ddb1426f16f4ff3218a131.camel@ndufresne.ca>

Hi Yunfei,

thanks for you work, see comments below...

Le samedi 22 janvier 2022 ? 11:53 +0800, Yunfei Dong a ?crit?:
> For lat and core decode in parallel, need to get capture buffer
> when core start to decode and put capture buffer to display
> list when core decode done.
> 
> Signed-off-by: Yunfei Dong <yunfei.dong at mediatek.com>
> ---
>  .../mtk-vcodec/mtk_vcodec_dec_stateless.c     | 121 ++++++++++++------
>  .../platform/mtk-vcodec/mtk_vcodec_drv.h      |   5 +-
>  .../mtk-vcodec/vdec/vdec_h264_req_if.c        |  16 ++-
>  3 files changed, 102 insertions(+), 40 deletions(-)
> 
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> index 23a154c4e321..6d481410bf89 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec_stateless.c
> @@ -108,37 +108,87 @@ static const struct mtk_codec_framesizes mtk_vdec_framesizes[] = {
>  
>  #define NUM_SUPPORTED_FRAMESIZE ARRAY_SIZE(mtk_vdec_framesizes)
>  
> -static void mtk_vdec_stateless_set_dst_payload(struct mtk_vcodec_ctx *ctx,
> -					       struct vdec_fb *fb)
> +static void mtk_vdec_stateless_out_to_done(struct mtk_vcodec_ctx *ctx,
> +					   struct mtk_vcodec_mem *bs, int error)
>  {
> -	struct mtk_video_dec_buf *vdec_frame_buf =
> -		container_of(fb, struct mtk_video_dec_buf, frame_buffer);
> -	struct vb2_v4l2_buffer *vb = &vdec_frame_buf->m2m_buf.vb;
> -	unsigned int cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
> +	struct mtk_video_dec_buf *out_buf;
> +	struct vb2_v4l2_buffer *vb;
>  
> -	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
> -	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
> -		unsigned int cap_c_size =
> -			ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
> +	if (!bs) {
> +		mtk_v4l2_err("Free bitstream buffer fail.");
> +		return;
> +	}
> +	out_buf = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
> +	vb = &out_buf->m2m_buf.vb;
>  
> -		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
> +	mtk_v4l2_debug(2, "Free bitsteam buffer id = %d to done_list",
> +		       vb->vb2_buf.index);
> +
> +	v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
> +	if (error) {
> +		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
> +		if (error == -EIO)
> +			out_buf->error = true;
> +	} else {
> +		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
>  	}
>  }
>  
> -static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx,
> -					   struct vb2_v4l2_buffer *vb2_v4l2)
> +static void mtk_vdec_stateless_cap_to_disp(struct mtk_vcodec_ctx *ctx,
> +					   struct vdec_fb *fb, int error)
>  {
> -	struct mtk_video_dec_buf *framebuf =
> -		container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
> -	struct vdec_fb *pfb = &framebuf->frame_buffer;
> -	struct vb2_buffer *dst_buf = &vb2_v4l2->vb2_buf;
> +	struct mtk_video_dec_buf *vdec_frame_buf;
> +	struct vb2_v4l2_buffer *vb;
> +	unsigned int cap_y_size, cap_c_size;
> +
> +	if (!fb) {
> +		mtk_v4l2_err("Free frame buffer fail.");
> +		return;
> +	}
> +	vdec_frame_buf = container_of(fb, struct mtk_video_dec_buf,
> +				      frame_buffer);
> +	vb = &vdec_frame_buf->m2m_buf.vb;
> +
> +	cap_y_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
> +	cap_c_size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
> +
> +	v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
>  
> -	pfb->base_y.va = NULL;
> +	vb2_set_plane_payload(&vb->vb2_buf, 0, cap_y_size);
> +	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2)
> +		vb2_set_plane_payload(&vb->vb2_buf, 1, cap_c_size);
> +
> +	mtk_v4l2_debug(2, "Free frame buffer id = %d to done_list",
> +		       vb->vb2_buf.index);
> +	if (error)
> +		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);
> +	else
> +		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_DONE);
> +}
> +
> +static struct vdec_fb *vdec_get_cap_buffer(struct mtk_vcodec_ctx *ctx)
> +{
> +	struct mtk_video_dec_buf *framebuf;
> +	struct vb2_v4l2_buffer *vb2_v4l2;
> +	struct vb2_buffer *dst_buf;
> +	struct vdec_fb *pfb;
> +
> +	vb2_v4l2 = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
> +	if (!vb2_v4l2) {
> +		mtk_v4l2_debug(1, "[%d] dst_buf empty!!", ctx->id);
> +		return NULL;
> +	}
> +
> +	dst_buf = &vb2_v4l2->vb2_buf;
> +	framebuf = container_of(vb2_v4l2, struct mtk_video_dec_buf, m2m_buf.vb);
> +
> +	pfb = &framebuf->frame_buffer;
> +	pfb->base_y.va = vb2_plane_vaddr(dst_buf, 0);
>  	pfb->base_y.dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
>  	pfb->base_y.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[0];
>  
>  	if (ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 2) {
> -		pfb->base_c.va = NULL;
> +		pfb->base_c.va = vb2_plane_vaddr(dst_buf, 1);
>  		pfb->base_c.dma_addr =
>  			vb2_dma_contig_plane_dma_addr(dst_buf, 1);
>  		pfb->base_c.size = ctx->q_data[MTK_Q_DATA_DST].sizeimage[1];
> @@ -162,12 +212,11 @@ static void mtk_vdec_worker(struct work_struct *work)
>  	struct mtk_vcodec_ctx *ctx =
>  		container_of(work, struct mtk_vcodec_ctx, decode_work);
>  	struct mtk_vcodec_dev *dev = ctx->dev;
> -	struct vb2_v4l2_buffer *vb2_v4l2_src, *vb2_v4l2_dst;
> +	struct vb2_v4l2_buffer *vb2_v4l2_src;
>  	struct vb2_buffer *vb2_src;
>  	struct mtk_vcodec_mem *bs_src;
>  	struct mtk_video_dec_buf *dec_buf_src;
>  	struct media_request *src_buf_req;
> -	struct vdec_fb *dst_buf;
>  	bool res_chg = false;
>  	int ret;
>  
> @@ -178,13 +227,6 @@ static void mtk_vdec_worker(struct work_struct *work)
>  		return;
>  	}
>  
> -	vb2_v4l2_dst = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
> -	if (!vb2_v4l2_dst) {
> -		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
> -		mtk_v4l2_debug(1, "[%d] no available destination buffer", ctx->id);
> -		return;
> -	}
> -
>  	vb2_src = &vb2_v4l2_src->vb2_buf;
>  	dec_buf_src = container_of(vb2_v4l2_src, struct mtk_video_dec_buf,
>  				   m2m_buf.vb);
> @@ -193,9 +235,15 @@ static void mtk_vdec_worker(struct work_struct *work)
>  	mtk_v4l2_debug(3, "[%d] (%d) id=%d, vb=%p", ctx->id,
>  		       vb2_src->vb2_queue->type, vb2_src->index, vb2_src);
>  
> -	bs_src->va = NULL;
> +	bs_src->va = vb2_plane_vaddr(vb2_src, 0);
>  	bs_src->dma_addr = vb2_dma_contig_plane_dma_addr(vb2_src, 0);
>  	bs_src->size = (size_t)vb2_src->planes[0].bytesused;
> +	if (!bs_src->va) {
> +		v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
> +		mtk_v4l2_err("[%d] id=%d source buffer is NULL", ctx->id,
> +			     vb2_src->index);
> +		return;
> +	}
>  
>  	mtk_v4l2_debug(3, "[%d] Bitstream VA=%p DMA=%pad Size=%zx vb=%p",
>  		       ctx->id, bs_src->va, &bs_src->dma_addr, bs_src->size, vb2_src);
> @@ -206,9 +254,7 @@ static void mtk_vdec_worker(struct work_struct *work)
>  	else
>  		mtk_v4l2_err("vb2 buffer media request is NULL");
>  
> -	dst_buf = vdec_get_cap_buffer(ctx, vb2_v4l2_dst);
> -	v4l2_m2m_buf_copy_metadata(vb2_v4l2_src, vb2_v4l2_dst, true);

Please keep using this helper, it is specially crafted to ease maintenance.

> -	ret = vdec_if_decode(ctx, bs_src, dst_buf, &res_chg);
> +	ret = vdec_if_decode(ctx, bs_src, NULL, &res_chg);
>  	if (ret) {
>  		mtk_v4l2_err(" <===[%d], src_buf[%d] sz=0x%zx pts=%llu vdec_if_decode() ret=%d res_chg=%d===>",
>  			     ctx->id, vb2_src->index, bs_src->size,
> @@ -220,12 +266,9 @@ static void mtk_vdec_worker(struct work_struct *work)
>  		}
>  	}
>  
> -	mtk_vdec_stateless_set_dst_payload(ctx, dst_buf);
> -
> -	v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx,
> -					 ret ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
> -
> +	mtk_vdec_stateless_out_to_done(ctx, bs_src, ret);

v4l2_m2m_buf_done_and_job_finish() was specially crafted to prevent developer
from implementing the signalling of the request at the wrong moment. This patch
broke this strict ordering. The relevant comment in the helper function:


	/*
	 * If the request API is being used, returning the OUTPUT
	 * (src) buffer will wake-up any process waiting on the
	 * request file descriptor.
	 *
	 * Therefore, return the CAPTURE (dst) buffer first,
	 * to avoid signalling the request file descriptor
	 * before the CAPTURE buffer is done.
	 */

In short, as request signalling is bound to the src buffer, with this change you
signal the request too early, which may lead userland to think it can DQ the
capture buffer. I see exactly that happening when running with GStreamer, which
strictly rely on the request polling. Please keep using
v4l2_m2m_buf_done_and_job_finish(), and move it into
mtk_vdec_stateless_cap_to_disp(). 


>  	v4l2_ctrl_request_complete(src_buf_req, &ctx->ctrl_hdl);
> +	v4l2_m2m_job_finish(dev->m2m_dev_dec, ctx->m2m_ctx);
>  }
>  
>  static void vb2ops_vdec_stateless_buf_queue(struct vb2_buffer *vb)
> @@ -358,6 +401,8 @@ const struct mtk_vcodec_dec_pdata mtk_vdec_8183_pdata = {
>  	.uses_stateless_api = true,
>  	.worker = mtk_vdec_worker,
>  	.flush_decoder = mtk_vdec_flush_decoder,
> +	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
> +	.get_cap_buffer = vdec_get_cap_buffer,
>  	.is_subdev_supported = false,
>  	.hw_arch = MTK_VDEC_PURE_SINGLE_CORE,
>  };
> @@ -376,6 +421,8 @@ const struct mtk_vcodec_dec_pdata mtk_lat_sig_core_pdata = {
>  	.uses_stateless_api = true,
>  	.worker = mtk_vdec_worker,
>  	.flush_decoder = mtk_vdec_flush_decoder,
> +	.cap_to_disp = mtk_vdec_stateless_cap_to_disp,
> +	.get_cap_buffer = vdec_get_cap_buffer,
>  	.is_subdev_supported = true,
>  	.hw_arch = MTK_VDEC_LAT_SINGLE_CORE,
>  };
> diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> index 2d1d878692ca..e0b7d2fda632 100644
> --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h
> @@ -353,7 +353,8 @@ enum mtk_vdec_hw_arch {
>   * @ctrls_setup: init vcodec dec ctrls
>   * @worker: worker to start a decode job
>   * @flush_decoder: function that flushes the decoder
> - *
> + * @get_cap_buffer: get capture buffer from capture queue
> + * @cap_to_disp: put capture buffer to disp list
>   * @vdec_vb2_ops: struct vb2_ops
>   *
>   * @vdec_formats: supported video decoder formats
> @@ -375,6 +376,8 @@ struct mtk_vcodec_dec_pdata {
>  	int (*ctrls_setup)(struct mtk_vcodec_ctx *ctx);
>  	void (*worker)(struct work_struct *work);
>  	int (*flush_decoder)(struct mtk_vcodec_ctx *ctx);
> +	struct vdec_fb *(*get_cap_buffer)(struct mtk_vcodec_ctx *ctx);
> +	void (*cap_to_disp)(struct mtk_vcodec_ctx *ctx, struct vdec_fb *fb, int error);
>  
>  	struct vb2_ops *vdec_vb2_ops;
>  
> diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> index 43542de11e9c..36f3dc1fbe3b 100644
> --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_req_if.c
> @@ -670,32 +670,42 @@ static void vdec_h264_slice_deinit(void *h_vdec)
>  }
>  
>  static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
> -				  struct vdec_fb *fb, bool *res_chg)
> +				  struct vdec_fb *unused, bool *res_chg)
>  {
>  	struct vdec_h264_slice_inst *inst = h_vdec;
>  	const struct v4l2_ctrl_h264_decode_params *dec_params =
>  		get_ctrl_ptr(inst->ctx, V4L2_CID_STATELESS_H264_DECODE_PARAMS);
>  	struct vdec_vpu_inst *vpu = &inst->vpu;
> +	struct mtk_video_dec_buf *src_buf_info;
> +	struct mtk_video_dec_buf *dst_buf_info;
> +	struct vdec_fb *fb;
>  	u32 data[2];
>  	u64 y_fb_dma;
>  	u64 c_fb_dma;
>  	int err;
>  
> +	inst->num_nalu++;
>  	/* bs NULL means flush decoder */
>  	if (!bs)
>  		return vpu_dec_reset(vpu);
>  
> +	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
> +	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
> +	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
> +
>  	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
>  	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
>  
>  	mtk_vcodec_debug(inst, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
> -			 ++inst->num_nalu, y_fb_dma, c_fb_dma, fb);
> +			 inst->num_nalu, y_fb_dma, c_fb_dma, fb);
>  
>  	inst->vsi_ctx.dec.bs_dma = (uint64_t)bs->dma_addr;
>  	inst->vsi_ctx.dec.y_fb_dma = y_fb_dma;
>  	inst->vsi_ctx.dec.c_fb_dma = c_fb_dma;
>  	inst->vsi_ctx.dec.vdec_fb_va = (u64)(uintptr_t)fb;
>  
> +	v4l2_m2m_buf_copy_metadata(&src_buf_info->m2m_buf.vb,
> +				   &dst_buf_info->m2m_buf.vb, true);
>  	get_vdec_decode_parameters(inst);
>  	data[0] = bs->size;
>  	/*
> @@ -734,6 +744,8 @@ static int vdec_h264_slice_decode(void *h_vdec, struct mtk_vcodec_mem *bs,
>  
>  	memcpy(&inst->vsi_ctx, inst->vpu.vsi, sizeof(inst->vsi_ctx));
>  	mtk_vcodec_debug(inst, "\n - NALU[%d]", inst->num_nalu);
> +
> +	inst->ctx->dev->vdec_pdata->cap_to_disp(inst->ctx, fb, 0);
>  	return 0;
>  
>  err_free_fb_out:



From wsa at the-dreams.de  Fri Jan 28 13:46:39 2022
From: wsa at the-dreams.de (Wolfram Sang)
Date: Fri, 28 Jan 2022 22:46:39 +0100
Subject: [v2 1/2] dt-bindings: i2c: update bindings for MT8186 SoC
In-Reply-To: <20220125110413.18988-2-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
 <20220125110413.18988-2-kewei.xu@mediatek.com>
Message-ID: <YfRkP7Wf7lzarVrf@shikoro>

On Tue, Jan 25, 2022 at 07:04:12PM +0800, Kewei Xu wrote:
> Add a DT binding documentation for the MT8186 soc.
> 
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>

Applied to for-next, thanks! But you forgot to add the ack from Rob
which he gave when you sent v1.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/b95987e3/attachment.sig>

From wsa at the-dreams.de  Fri Jan 28 13:46:03 2022
From: wsa at the-dreams.de (Wolfram Sang)
Date: Fri, 28 Jan 2022 22:46:03 +0100
Subject: [v2 0/2] add i2c support for mt8186
In-Reply-To: <20220125110413.18988-1-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
Message-ID: <YfRkG7KdAMD7FiuY@shikoro>

On Tue, Jan 25, 2022 at 07:04:11PM +0800, Kewei Xu wrote:
> V1:
> Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
> MT8186 doesn't need handshake signal with apdma.

A description of what has changed in v2 would have been helpful. Please
add it next time.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/71fbc22f/attachment.sig>

From wsa at the-dreams.de  Fri Jan 28 13:46:49 2022
From: wsa at the-dreams.de (Wolfram Sang)
Date: Fri, 28 Jan 2022 22:46:49 +0100
Subject: [v2 2/2] i2c: mediatek: Add i2c compatible for Mediatek MT8186
In-Reply-To: <20220125110413.18988-3-kewei.xu@mediatek.com>
References: <20220125110413.18988-1-kewei.xu@mediatek.com>
 <20220125110413.18988-3-kewei.xu@mediatek.com>
Message-ID: <YfRkSWXZjMipeY9t@shikoro>

On Tue, Jan 25, 2022 at 07:04:13PM +0800, Kewei Xu wrote:
> Add i2c compatible for MT8186. Compare to MT8192 i2c controller,
> MT8186 doesn't need handshake signal witch apdma.
> 
> Signed-off-by: Kewei Xu <kewei.xu at mediatek.com>

Applied to for-next, thanks!

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220128/081650e1/attachment.sig>

From krzysztof.adamski at nokia.com  Fri Jan 28 14:05:32 2022
From: krzysztof.adamski at nokia.com (Krzysztof Adamski)
Date: Fri, 28 Jan 2022 23:05:32 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfQTZTUNaeGi+8tG@FVFF77S0Q05N>
References: <YfP0osb45uJldtM9@localhost.localdomain>
 <YfQTZTUNaeGi+8tG@FVFF77S0Q05N>
Message-ID: <YfRorCpk0seVGI+5@localhost.localdomain>

Hi Mark,

Thank you for your feedback. I don't know UEFI specification that much,
it is quite complicated so maybe I am misunderstnading something. Let's
clarify.

Dnia Fri, Jan 28, 2022 at 04:01:41PM +0000, Mark Rutland napisa?(a):
>On Fri, Jan 28, 2022 at 02:50:26PM +0100, Krzysztof Adamski wrote:
>> On EFI enabled arm64 systems, efi_reboot was called before
>> do_kernel_restart, completely omitting the reset_handlers functionality.
>
>As I pointed out before, per the EFI spec we *need* to do this before any other
>restart mechanism so that anything which EFI ties to the restart actually
>occurs as expected -- e.g. UpdateCapsule(), as the comment says.
>AFAICT, either:
>
>* The other restart handlers have lower priority, in which case they'll be
>  called after this anyway, and in such cases this patch is not necessary.

But efi_reboot calls ResetSystem(), which according to the spec:
"Resets all processors and devices and reboots the system."

So nothing should be able to run *after* this call. Thus, none of the
reset handlers will ever run on a system where efi_reboot() is used
(with current, unmodified kernel code) so this case is invalid.

>
>* At least one other restart handler has higher priority, and the EFI restart
>  isn't actually used, and so any functionaltiy tied to the EFI restart will
>  not work on that machine.

If we use the restart handlers only to reset the system, this is indeed
true. But technically, restart handlers support the scenario where the
handler does some action that does not do reset of the whole system and
passes the control further down the chain, eventually reaching a handler
that will reset the whole system.
This can be done on non-uefi systems without problems but it doesn't
work on UEFI bases arm64 systems and this is a problem for us.

In other words, I would like to be able to run a restart handler on EFI
based ARM64 systems, just like I can on other systems, just for its
"side effects", not to do the actual reboot. Current code disables this
possibility on an ARM64 EFI system.

>
>> By registering efi_reboot as part of the chain with slightly elevated
>> priority, we make it run before the default handler but still allow
>> plugging in other handlers.
>> Thanks to that, things like gpio_restart, restart handlers in
>> watchdog_core, mmc or mtds are working on those platforms.
>
>On which platforms is it necessary that these are used in preference to the EFI
>restart? Can you please give a specific example?

>If there's a specific platform that needs this, then we should call that out
>and explain why the EFI restart isn't actually required on that (or if it is,
>and functionality is broken, why that's acceptable).

Again, I'm not saying EFI restart is not required. I would just like to
have the flexibility I have on other architectures, and run some code
just before restart. My understanding is that pwrseq_emmc.c driver does
exactly that, for example, but there are also other possibilities:
  - using gpio-restart to notify external components about reset of the
    CPU
  - starting an external watchdog that makes sure we are not stuck in the
    reset procedure, etc.

>Otherwise this patch is making this logic more complicated *and* making it
>possible to have problems which we avoid by construction today, without any
>actual benefit.

The benefit for me is this added flexibility and unification between
architectures. On other systems, like ARM32 or non-EFI ARM64 I can
insert a custom reset handler to do some actions just before restart and
on EFI based ARM64, I can't.

You could argue that restart handlers were not created for that but they
suit this purpose ideally and it wouldn't make much sense (in my
opinion) to add yet another notifier chain that would run before reset
notifiers, for code that is not supposed to reset the whole system and
this is exacly what I would have to do if efi_reboot() is forced to be
called before all handlers.

Best regards,
Krzysztof Adamski


From daniel at ffwll.ch  Fri Jan 28 14:24:24 2022
From: daniel at ffwll.ch (Daniel Vetter)
Date: Fri, 28 Jan 2022 23:24:24 +0100
Subject: [RFC PATCH] component: Add common helpers for compare/release
 functions
In-Reply-To: <20220128081101.27837-1-yong.wu@mediatek.com>
References: <20220128081101.27837-1-yong.wu@mediatek.com>
Message-ID: <YfRtGF3v+BwH5RkG@phenom.ffwll.local>

On Fri, Jan 28, 2022 at 04:11:01PM +0800, Yong Wu wrote:
> The component requires the compare/release functions, there are so many
> copy in current kernel. Just define three common helpers for them.
> No functional change.
> 
> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
> ---
> Base on v5.17-rc1
> ---
>  .../gpu/drm/arm/display/komeda/komeda_drv.c    |  5 -----
>  drivers/gpu/drm/arm/hdlcd_drv.c                |  7 +------
>  drivers/gpu/drm/armada/armada_drv.c            |  5 -----
>  drivers/gpu/drm/drm_of.c                       |  8 +-------
>  drivers/gpu/drm/etnaviv/etnaviv_drv.c          |  7 -------
>  drivers/gpu/drm/exynos/exynos_drm_drv.c        |  5 -----
>  .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c    |  5 -----
>  drivers/gpu/drm/imx/imx-drm-core.c             |  4 ++--
>  drivers/gpu/drm/ingenic/ingenic-drm-drv.c      |  5 -----
>  drivers/gpu/drm/mcde/mcde_drv.c                |  7 +------
>  drivers/gpu/drm/mediatek/mtk_drm_drv.c         |  5 -----
>  drivers/gpu/drm/meson/meson_drv.c              |  8 --------
>  drivers/gpu/drm/msm/msm_drv.c                  |  9 ---------
>  drivers/gpu/drm/omapdrm/dss/dss.c              |  8 +-------
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c    |  5 -----
>  drivers/gpu/drm/sti/sti_drv.c                  |  5 -----
>  drivers/gpu/drm/sun4i/sun4i_drv.c              |  9 ---------
>  drivers/gpu/drm/vc4/vc4_drv.c                  |  5 -----
>  drivers/iommu/mtk_iommu.h                      | 10 ----------
>  drivers/power/supply/ab8500_charger.c          |  8 +-------
>  drivers/video/fbdev/omap2/omapfb/dss/dss.c     |  8 +-------
>  include/linux/component.h                      | 18 ++++++++++++++++++
>  sound/soc/codecs/wcd938x.c                     | 16 ++--------------

Seems like a neat idea. Please add kerneldoc for the new functions you're
adding (bonus point for an example in there) and make sure it all renders
correctly in

$ make htmldoc

Also please split up the patch series per-driver and add the maintainers
to each patches' Cc: list. With that I think this should be ready for
merging.

Cheers, Daniel

>  23 files changed, 28 insertions(+), 144 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> index e7933930a657..fe5b97107417 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> @@ -92,11 +92,6 @@ static const struct component_master_ops komeda_master_ops = {
>  	.unbind	= komeda_unbind,
>  };
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static void komeda_add_slave(struct device *master,
>  			     struct component_match **match,
>  			     struct device_node *np,
> diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
> index 479c2422a2e0..36d84c439df8 100644
> --- a/drivers/gpu/drm/arm/hdlcd_drv.c
> +++ b/drivers/gpu/drm/arm/hdlcd_drv.c
> @@ -372,11 +372,6 @@ static const struct component_master_ops hdlcd_master_ops = {
>  	.unbind		= hdlcd_drm_unbind,
>  };
>  
> -static int compare_dev(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static int hdlcd_probe(struct platform_device *pdev)
>  {
>  	struct device_node *port;
> @@ -387,7 +382,7 @@ static int hdlcd_probe(struct platform_device *pdev)
>  	if (!port)
>  		return -ENODEV;
>  
> -	drm_of_component_match_add(&pdev->dev, &match, compare_dev, port);
> +	drm_of_component_match_add(&pdev->dev, &match, compare_of, port);
>  	of_node_put(port);
>  
>  	return component_master_add_with_match(&pdev->dev, &hdlcd_master_ops,
> diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
> index 8e3e98f13db4..9edc4912c1a0 100644
> --- a/drivers/gpu/drm/armada/armada_drv.c
> +++ b/drivers/gpu/drm/armada/armada_drv.c
> @@ -177,11 +177,6 @@ static void armada_drm_unbind(struct device *dev)
>  	drm_mm_takedown(&priv->linear);
>  }
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static int compare_dev_name(struct device *dev, void *data)
>  {
>  	const char *name = data;
> diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c
> index 59d368ea006b..f958f48f8ba4 100644
> --- a/drivers/gpu/drm/drm_of.c
> +++ b/drivers/gpu/drm/drm_of.c
> @@ -18,11 +18,6 @@
>   * properties.
>   */
>  
> -static void drm_release_of(struct device *dev, void *data)
> -{
> -	of_node_put(data);
> -}
> -
>  /**
>   * drm_of_crtc_port_mask - find the mask of a registered CRTC by port OF node
>   * @dev: DRM device
> @@ -94,8 +89,7 @@ void drm_of_component_match_add(struct device *master,
>  				struct device_node *node)
>  {
>  	of_node_get(node);
> -	component_match_add_release(master, matchptr, drm_release_of,
> -				    compare, node);
> +	component_match_add_release(master, matchptr, release_of, compare, node);
>  }
>  EXPORT_SYMBOL_GPL(drm_of_component_match_add);
>  
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> index 0b756ecb1bc2..15351e26ab00 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
> @@ -574,13 +574,6 @@ static const struct component_master_ops etnaviv_master_ops = {
>  	.unbind = etnaviv_unbind,
>  };
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	struct device_node *np = data;
> -
> -	return dev->of_node == np;
> -}
> -
>  static int compare_str(struct device *dev, void *data)
>  {
>  	return !strcmp(dev_name(dev), data);
> diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> index 9743b6b17447..97f6bc69bee3 100644
> --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
> +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
> @@ -212,11 +212,6 @@ static struct exynos_drm_driver_info exynos_drm_drivers[] = {
>  	}
>  };
>  
> -static int compare_dev(struct device *dev, void *data)
> -{
> -	return dev == (struct device *)data;
> -}
> -
>  static struct component_match *exynos_drm_match_add(struct device *dev)
>  {
>  	struct component_match *match = NULL;
> diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> index 98ae9a48f3fe..8cc6e13e46af 100644
> --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
> @@ -203,11 +203,6 @@ static int kirin_drm_kms_init(struct drm_device *dev,
>  	return ret;
>  }
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static int kirin_drm_kms_cleanup(struct drm_device *dev)
>  {
>  	drm_kms_helper_poll_fini(dev);
> diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
> index cb685fe2039b..11b5c0fae045 100644
> --- a/drivers/gpu/drm/imx/imx-drm-core.c
> +++ b/drivers/gpu/drm/imx/imx-drm-core.c
> @@ -176,7 +176,7 @@ static const struct drm_driver imx_drm_driver = {
>  	.patchlevel		= 0,
>  };
>  
> -static int compare_of(struct device *dev, void *data)
> +static int imx_compare_of(struct device *dev, void *data)
>  {
>  	struct device_node *np = data;
>  
> @@ -286,7 +286,7 @@ static const struct component_master_ops imx_drm_ops = {
>  
>  static int imx_drm_platform_probe(struct platform_device *pdev)
>  {
> -	int ret = drm_of_component_probe(&pdev->dev, compare_of, &imx_drm_ops);
> +	int ret = drm_of_component_probe(&pdev->dev, imx_compare_of, &imx_drm_ops);
>  
>  	if (!ret)
>  		ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
> diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> index b4943a56be09..194abab14ffe 100644
> --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
> @@ -1322,11 +1322,6 @@ static int ingenic_drm_bind_with_components(struct device *dev)
>  	return ingenic_drm_bind(dev, true);
>  }
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static void ingenic_drm_unbind(struct device *dev)
>  {
>  	struct ingenic_drm *priv = dev_get_drvdata(dev);
> diff --git a/drivers/gpu/drm/mcde/mcde_drv.c b/drivers/gpu/drm/mcde/mcde_drv.c
> index 5b5afc6aaf8e..015690b6d308 100644
> --- a/drivers/gpu/drm/mcde/mcde_drv.c
> +++ b/drivers/gpu/drm/mcde/mcde_drv.c
> @@ -265,11 +265,6 @@ static struct platform_driver *const mcde_component_drivers[] = {
>  	&mcde_dsi_driver,
>  };
>  
> -static int mcde_compare_dev(struct device *dev, void *data)
> -{
> -	return dev == data;
> -}
> -
>  static int mcde_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -399,7 +394,7 @@ static int mcde_probe(struct platform_device *pdev)
>  
>  		while ((d = platform_find_device_by_driver(p, drv))) {
>  			put_device(p);
> -			component_match_add(dev, &match, mcde_compare_dev, d);
> +			component_match_add(dev, &match, compare_dev, d);
>  			p = d;
>  		}
>  		put_device(p);
> diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> index 56ff8c57ef8f..72586983ec1d 100644
> --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
> @@ -369,11 +369,6 @@ static const struct drm_driver mtk_drm_driver = {
>  	.minor = DRIVER_MINOR,
>  };
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static int mtk_drm_bind(struct device *dev)
>  {
>  	struct mtk_drm_private *private = dev_get_drvdata(dev);
> diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
> index 80f1d439841a..b68631d16eb3 100644
> --- a/drivers/gpu/drm/meson/meson_drv.c
> +++ b/drivers/gpu/drm/meson/meson_drv.c
> @@ -423,14 +423,6 @@ static int __maybe_unused meson_drv_pm_resume(struct device *dev)
>  	return drm_mode_config_helper_resume(priv->drm);
>  }
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
> -			 dev->of_node, data);
> -
> -	return dev->of_node == data;
> -}
> -
>  static void meson_drv_shutdown(struct platform_device *pdev)
>  {
>  	struct meson_drm *priv = dev_get_drvdata(&pdev->dev);
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index ad35a5d94053..6250327b1eda 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -1173,15 +1173,6 @@ static const struct dev_pm_ops msm_pm_ops = {
>   * Componentized driver support:
>   */
>  
> -/*
> - * NOTE: duplication of the same code as exynos or imx (or probably any other).
> - * so probably some room for some helpers
> - */
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  /*
>   * Identify what components need to be added by parsing what remote-endpoints
>   * our MDP output ports are connected to. In the case of LVDS on MDP4, there
> diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c
> index 69b3e15b9356..5216000c7657 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dss.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dss.c
> @@ -1344,12 +1344,6 @@ static const struct component_master_ops dss_component_ops = {
>  	.unbind = dss_unbind,
>  };
>  
> -static int dss_component_compare(struct device *dev, void *data)
> -{
> -	struct device *child = data;
> -	return dev == child;
> -}
> -
>  struct dss_component_match_data {
>  	struct device *dev;
>  	struct component_match **match;
> @@ -1379,7 +1373,7 @@ static int dss_add_child_component(struct device *dev, void *data)
>  		return device_for_each_child(dev, cmatch,
>  					     dss_add_child_component);
>  
> -	component_match_add(cmatch->dev, match, dss_component_compare, dev);
> +	component_match_add(cmatch->dev, match, compare_dev, dev);
>  
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> index bec207de4544..276e41168bd0 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> @@ -290,11 +290,6 @@ int rockchip_drm_endpoint_is_subdriver(struct device_node *ep)
>  	return false;
>  }
>  
> -static int compare_dev(struct device *dev, void *data)
> -{
> -	return dev == (struct device *)data;
> -}
> -
>  static void rockchip_drm_match_remove(struct device *dev)
>  {
>  	struct device_link *link;
> diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
> index c7efb43b83ee..3c3294c2100d 100644
> --- a/drivers/gpu/drm/sti/sti_drv.c
> +++ b/drivers/gpu/drm/sti/sti_drv.c
> @@ -144,11 +144,6 @@ static const struct drm_driver sti_driver = {
>  	.minor = DRIVER_MINOR,
>  };
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
>  static int sti_init(struct drm_device *ddev)
>  {
>  	struct sti_private *private;
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index b630614b3d72..de26c1448486 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -201,15 +201,6 @@ static bool sun4i_drv_node_is_tcon_top(struct device_node *node)
>  		!!of_match_node(sun8i_tcon_top_of_table, node);
>  }
>  
> -static int compare_of(struct device *dev, void *data)
> -{
> -	DRM_DEBUG_DRIVER("Comparing of node %pOF with %pOF\n",
> -			 dev->of_node,
> -			 data);
> -
> -	return dev->of_node == data;
> -}
> -
>  /*
>   * The encoder drivers use drm_of_find_possible_crtcs to get upstream
>   * crtcs from the device tree using of_graph. For the results to be
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 16abc3a3d601..43474107a4f2 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -187,11 +187,6 @@ static struct drm_driver vc4_drm_driver = {
>  	.patchlevel = DRIVER_PATCHLEVEL,
>  };
>  
> -static int compare_dev(struct device *dev, void *data)
> -{
> -	return dev == data;
> -}
> -
>  static void vc4_match_add_drivers(struct device *dev,
>  				  struct component_match **match,
>  				  struct platform_driver *const *drivers,
> diff --git a/drivers/iommu/mtk_iommu.h b/drivers/iommu/mtk_iommu.h
> index f81fa8862ed0..b742432220c5 100644
> --- a/drivers/iommu/mtk_iommu.h
> +++ b/drivers/iommu/mtk_iommu.h
> @@ -84,16 +84,6 @@ struct mtk_iommu_data {
>  	struct mtk_smi_larb_iommu	larb_imu[MTK_LARB_NR_MAX];
>  };
>  
> -static inline int compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
> -static inline void release_of(struct device *dev, void *data)
> -{
> -	of_node_put(data);
> -}
> -
>  static inline int mtk_iommu_bind(struct device *dev)
>  {
>  	struct mtk_iommu_data *data = dev_get_drvdata(dev);
> diff --git a/drivers/power/supply/ab8500_charger.c b/drivers/power/supply/ab8500_charger.c
> index ce074c018dcb..248dfd8aec19 100644
> --- a/drivers/power/supply/ab8500_charger.c
> +++ b/drivers/power/supply/ab8500_charger.c
> @@ -3414,11 +3414,6 @@ static struct platform_driver *const ab8500_charger_component_drivers[] = {
>  	&ab8500_chargalg_driver,
>  };
>  
> -static int ab8500_charger_compare_dev(struct device *dev, void *data)
> -{
> -	return dev == data;
> -}
> -
>  static int ab8500_charger_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -3657,8 +3652,7 @@ static int ab8500_charger_probe(struct platform_device *pdev)
>  
>  		while ((d = platform_find_device_by_driver(p, drv))) {
>  			put_device(p);
> -			component_match_add(dev, &match,
> -					    ab8500_charger_compare_dev, d);
> +			component_match_add(dev, &match, compare_dev, d);
>  			p = d;
>  		}
>  		put_device(p);
> diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss.c b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
> index a6b1c1598040..328aa5d86f1a 100644
> --- a/drivers/video/fbdev/omap2/omapfb/dss/dss.c
> +++ b/drivers/video/fbdev/omap2/omapfb/dss/dss.c
> @@ -1193,12 +1193,6 @@ static const struct component_master_ops dss_component_ops = {
>  	.unbind = dss_unbind,
>  };
>  
> -static int dss_component_compare(struct device *dev, void *data)
> -{
> -	struct device *child = data;
> -	return dev == child;
> -}
> -
>  static int dss_add_child_component(struct device *dev, void *data)
>  {
>  	struct component_match **match = data;
> @@ -1212,7 +1206,7 @@ static int dss_add_child_component(struct device *dev, void *data)
>  	if (strstr(dev_name(dev), "rfbi"))
>  		return 0;
>  
> -	component_match_add(dev->parent, match, dss_component_compare, dev);
> +	component_match_add(dev->parent, match, compare_dev, dev);
>  
>  	return 0;
>  }
> diff --git a/include/linux/component.h b/include/linux/component.h
> index 16de18f473d7..5a7468ea827c 100644
> --- a/include/linux/component.h
> +++ b/include/linux/component.h
> @@ -2,6 +2,8 @@
>  #ifndef COMPONENT_H
>  #define COMPONENT_H
>  
> +#include <linux/device.h>
> +#include <linux/of.h>
>  #include <linux/stddef.h>
>  
>  
> @@ -82,6 +84,22 @@ struct component_master_ops {
>  	void (*unbind)(struct device *master);
>  };
>  
> +/* A set common helpers for compare/release functions */
> +static inline int compare_of(struct device *dev, void *data)
> +{
> +	return dev->of_node == data;
> +}
> +
> +static inline void release_of(struct device *dev, void *data)
> +{
> +	of_node_put(data);
> +}
> +
> +static inline int compare_dev(struct device *dev, void *data)
> +{
> +	return dev == data;
> +}
> +
>  void component_master_del(struct device *,
>  	const struct component_master_ops *);
>  
> diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c
> index eff200a07d9f..992132cbfb9f 100644
> --- a/sound/soc/codecs/wcd938x.c
> +++ b/sound/soc/codecs/wcd938x.c
> @@ -4417,16 +4417,6 @@ static const struct component_master_ops wcd938x_comp_ops = {
>  	.unbind = wcd938x_unbind,
>  };
>  
> -static int wcd938x_compare_of(struct device *dev, void *data)
> -{
> -	return dev->of_node == data;
> -}
> -
> -static void wcd938x_release_of(struct device *dev, void *data)
> -{
> -	of_node_put(data);
> -}
> -
>  static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>  					struct device *dev,
>  					struct component_match **matchptr)
> @@ -4442,8 +4432,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>  	}
>  
>  	of_node_get(wcd938x->rxnode);
> -	component_match_add_release(dev, matchptr, wcd938x_release_of,
> -				    wcd938x_compare_of,	wcd938x->rxnode);
> +	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->rxnode);
>  
>  	wcd938x->txnode = of_parse_phandle(np, "qcom,tx-device", 0);
>  	if (!wcd938x->txnode) {
> @@ -4451,8 +4440,7 @@ static int wcd938x_add_slave_components(struct wcd938x_priv *wcd938x,
>  		return -ENODEV;
>  	}
>  	of_node_get(wcd938x->txnode);
> -	component_match_add_release(dev, matchptr, wcd938x_release_of,
> -				    wcd938x_compare_of,	wcd938x->txnode);
> +	component_match_add_release(dev, matchptr, release_of, compare_of, wcd938x->txnode);
>  	return 0;
>  }
>  
> -- 
> 2.18.0
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch


From lkp at intel.com  Fri Jan 28 14:25:53 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 29 Jan 2022 06:25:53 +0800
Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21
In-Reply-To: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>
References: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>
Message-ID: <202201290646.48sNgWm1-lkp@intel.com>

Hi "Uwe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on shawnguo/for-next]
[also build test ERROR on robh/for-next pza/reset/next v5.17-rc1 next-20220128]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
config: arc-randconfig-r012-20220128 (https://download.01.org/0day-ci/archive/20220129/202201290646.48sNgWm1-lkp at intel.com/config)
compiler: arc-elf-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/cba99931972f752a7b3105a3697b0cda88fe54d4
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
        git checkout cba99931972f752a7b3105a3697b0cda88fe54d4
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc distclean

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> scripts/Makefile.clean:15: drivers/gpu/drm/imx/imx21-lcdc/Makefile: No such file or directory
>> make[6]: *** No rule to make target 'drivers/gpu/drm/imx/imx21-lcdc/Makefile'.
   make[6]: Failed to remake makefile 'drivers/gpu/drm/imx/imx21-lcdc/Makefile'.
   make[5]: *** [scripts/Makefile.clean:68: drivers/gpu/drm/imx/imx21-lcdc] Error 2
   make[5]: Target '__clean' not remade because of errors.
   make[4]: *** [scripts/Makefile.clean:68: drivers/gpu/drm/imx] Error 2
   make[4]: Target '__clean' not remade because of errors.
   make[3]: *** [scripts/Makefile.clean:68: drivers/gpu/drm] Error 2
   make[3]: Target '__clean' not remade because of errors.
   make[2]: *** [scripts/Makefile.clean:68: drivers/gpu] Error 2
   make[2]: Target '__clean' not remade because of errors.
   make[1]: *** [Makefile:1838: _clean_drivers] Error 2
   make[1]: Target 'distclean' not remade because of errors.
   make: *** [Makefile:219: __sub-make] Error 2
   make: Target 'distclean' not remade because of errors.


vim +15 scripts/Makefile.clean

2315c6e4227815 Sam Ravnborg   2005-07-25  12  
2a691470345a00 Sam Ravnborg   2005-07-25  13  # The filename Kbuild has precedence over Makefile
db8c1a7b2ca25f Sam Ravnborg   2005-07-27  14  kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
db8c1a7b2ca25f Sam Ravnborg   2005-07-27 @15  include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
^1da177e4c3f41 Linus Torvalds 2005-04-16  16  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From kuba at kernel.org  Fri Jan 28 14:29:55 2022
From: kuba at kernel.org (Jakub Kicinski)
Date: Fri, 28 Jan 2022 14:29:55 -0800
Subject: [PATCH] net: stmmac: dump gmac4 DMA registers correctly
In-Reply-To: <20220128153642.3129922-1-camel.guo@axis.com>
References: <20220128153642.3129922-1-camel.guo@axis.com>
Message-ID: <20220128142955.047bd9d4@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>

On Fri, 28 Jan 2022 16:36:42 +0100 Camel Guo wrote:
> From: Camel Guo <camelg at axis.com>
> 
> Unlike gmac100, gmac1000, gmac4 has 27 DMA registers and they are
> located at DMA_CHAN_BASE_ADDR (0x1100). In order for ethtool to dump
> gmac4 DMA registers correctly, this commit checks if a net_device has
> gmac4 and uses different logic to dump its DMA registers.
> 
> This fixes the following KASAN warning, which can normally be triggered
> by a command similar like "ethtool -d eth0":
> 
> BUG: KASAN: vmalloc-out-of-bounds in dwmac4_dump_dma_regs+0x6d4/0xb30
> Write of size 4 at addr ffffffc010177100 by task ethtool/1839
>  kasan_report+0x200/0x21c
>  __asan_report_store4_noabort+0x34/0x60
>  dwmac4_dump_dma_regs+0x6d4/0xb30
>  stmmac_ethtool_gregs+0x110/0x204
>  ethtool_get_regs+0x200/0x4b0
>  dev_ethtool+0x1dac/0x3800
>  dev_ioctl+0x7c0/0xb50
>  sock_ioctl+0x298/0x6c4
>  ...
> 
> Signed-off-by: Camel Guo <camelg at axis.com>

Can we get a Fixes tag for this? If it was always broken the Fixes tag
should point to the commit which added gmac4 support.


From krzysztof.adamski at nokia.com  Fri Jan 28 14:32:19 2022
From: krzysztof.adamski at nokia.com (Krzysztof Adamski)
Date: Fri, 28 Jan 2022 23:32:19 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfREAiRMjQ9ci4LC@shikoro>
References: <YfP0osb45uJldtM9@localhost.localdomain> <YfREAiRMjQ9ci4LC@shikoro>
Message-ID: <YfRu86YoiFpVsqyn@localhost.localdomain>

Dnia Fri, Jan 28, 2022 at 08:29:06PM +0100, Wolfram Sang napisa?(a):
>
>> +	/* We want this to take priority over PSCI which has priority of 129. */
>> +	.priority = 130,
>
>Is it an idea to add a #define for the PSCI priority somewhere and use
>here the define + 1? Hardcoded priorities look a bit fragile to me.
>

You are right. Our priority policy for restart handlers isn't really
good and it is hard to choose right priority just about every time a
handler is added.

That being said, after reading Mark's argumentation, I now thing that
just being before PSCI is not enough. I think that a much higher
priority should be used as it is not normal situation that you would
like to run something before efi_reboot().

I would really still like to move the efi_reboot() to the
restart_handler even if you consider running some code before
efi_reboot() crazy. Since 255 is max priorty but using it basically
does not make sense (as this would let to the exact same situation we
have now).

I would use something like 250, or even 254, just to indicate that we
know that most certainly nothing should be run before efi_reboot(), but
still allow those silly people like me, to do what they want in their
system, without the need to run the custom kernel. I think we could even
add a proper comment, so it woudld become something like:

/**
  * If you are running UEFI based system, you most certainly should let
  * efi_reboot() do a reset for you. If you think you know better, we
  * leave you a window of opportunity here by not using maximal priorty
  * here.
  */
  .priority = 250,

What is the downside of doing that? That we will run through atomic
notfier chain instead of calling efi_reboot directly? Sure this is
slightly more complicated but it works on all our platforms and is
battle proven and we don't worry about that there. And the upside is
that we give people possibility to use their beloved mechanism if they
really like to. Because flexibility is a good thing.

What do you think?

Krzysztof


From quic_collinsd at quicinc.com  Fri Jan 28 15:09:30 2022
From: quic_collinsd at quicinc.com (David Collins)
Date: Fri, 28 Jan 2022 15:09:30 -0800
Subject: [RESEND PATCH 1/2] dt-bindings: firmware: arm,scmi: define
 support for name based regulators
In-Reply-To: <YfREsxeSSX2pbALf@sirena.org.uk>
References: <cover.1643069954.git.quic_collinsd@quicinc.com>
 <fcd130891cc1d52cb09b8bfc866ab7ef1ce3b2a1.1643069954.git.quic_collinsd@quicinc.com>
 <YfREsxeSSX2pbALf@sirena.org.uk>
Message-ID: <8355035c-6d90-adfd-c4e1-7bb37a2d8055@quicinc.com>

On 1/28/22 11:32 AM, Mark Brown wrote:
> On Mon, Jan 24, 2022 at 04:27:35PM -0800, David Collins wrote:
> 
>> Name based SCMI regulator specification helps ensure that an SCMI
>> agent doesn't need to be aware of the numbering scheme used for
> 
> What is a "SCMI agent" in this context?  This is changing how the DT
> bindings are specified, at some point things are going to need to be
> hard coded.

An SCMI agent is the entity that issues SCMI commands (i.e. the
consumer).  An SCMI platform is the entity that receives the SCMI
commands and performs the necessary operations (i.e. the provider).
This is the terminology used in the ARM SCMI spec [1].

A typical system layout could have an agent that is the application
processor (running Linux) and a platform that is an embedded controller.

The system layout that this patch is targeted for consists of an SCMI
platform implemented in software in the primary Linux OS on the
application processor and an SCMI agent in a guest VM (also running
Linux).  This provides paravirtualized regulator control to the guest VM
where full virtualization is not supported.

During the course of development of these software images, it may be
necessary to add or reorder the set of SCMI voltage domains (regulators)
implemented on the platform side.  If the voltage domains are only
identified and matched based on the ID number, then it is easy for the
platform and agent to get out of sync.

Using the voltage domain name instead of ID number for identification
and matching provides robust assurance of correct regulator usage in the
face of domains being added, removed, or reordered on the platform side.


>> +              regulator-name: true
>> +
>> +            anyOf:
>> +              - required:
>> +                  - reg
>> +              - required:
>> +                  - regulator-name
> 
> This is abusing the existing regulator-name property which is there to
> allow a human readable descriptive string to be attached to a regulator.
> It should have no effect other than being included in diagnostic output.

Would you be ok with a new DT property being added in place of
"regulator-name" in this patch which serves the same matching purpose
(perhaps "arm,scmi-domain-name")?

Thanks,
David

[1]: https://developer.arm.com/documentation/den0056/latest


From j.neuschaefer at gmx.net  Fri Jan 28 15:09:19 2022
From: j.neuschaefer at gmx.net (=?UTF-8?q?Jonathan=20Neusch=C3=A4fer?=)
Date: Sat, 29 Jan 2022 00:09:19 +0100
Subject: [PATCH 1/4] clk: actions: Terminate clk_div_table with sentinel
 element
In-Reply-To: <20220128230922.2047140-1-j.neuschaefer@gmx.net>
References: <20220128230922.2047140-1-j.neuschaefer@gmx.net>
Message-ID: <20220128230922.2047140-2-j.neuschaefer@gmx.net>

In order that the end of a clk_div_table can be detected, it must be
terminated with a sentinel element (.div = 0).

Signed-off-by: Jonathan Neusch?fer <j.neuschaefer at gmx.net>
---

I'm not so sure about usb3_mac_div_table. Maybe the { 0, 8 } element was
meant to be { 0, 0 }?
---
 drivers/clk/actions/owl-s700.c | 1 +
 drivers/clk/actions/owl-s900.c | 4 ++--
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/actions/owl-s700.c b/drivers/clk/actions/owl-s700.c
index a2f34d13fb543..617174644f728 100644
--- a/drivers/clk/actions/owl-s700.c
+++ b/drivers/clk/actions/owl-s700.c
@@ -162,6 +162,7 @@ static struct clk_div_table hdmia_div_table[] = {

 static struct clk_div_table rmii_div_table[] = {
 	{0, 4},   {1, 10},
+	{0, 0},
 };

 /* divider clocks */
diff --git a/drivers/clk/actions/owl-s900.c b/drivers/clk/actions/owl-s900.c
index 790890978424a..f6f49100a865b 100644
--- a/drivers/clk/actions/owl-s900.c
+++ b/drivers/clk/actions/owl-s900.c
@@ -139,8 +139,8 @@ static struct clk_div_table rmii_ref_div_table[] = {
 };

 static struct clk_div_table usb3_mac_div_table[] = {
-	{ 1, 2 }, { 2, 3 }, { 3, 4 },
-	{ 0, 8 },
+	{ 1, 2 }, { 2, 3 }, { 3, 4 }, { 0, 8 },
+	{ 0, 0 },
 };

 static struct clk_div_table i2s_div_table[] = {
--
2.34.1



From j.neuschaefer at gmx.net  Fri Jan 28 15:09:22 2022
From: j.neuschaefer at gmx.net (=?UTF-8?q?Jonathan=20Neusch=C3=A4fer?=)
Date: Sat, 29 Jan 2022 00:09:22 +0100
Subject: [PATCH 4/4] clk: clps711x: Terminate clk_div_table with sentinel
 element
In-Reply-To: <20220128230922.2047140-1-j.neuschaefer@gmx.net>
References: <20220128230922.2047140-1-j.neuschaefer@gmx.net>
Message-ID: <20220128230922.2047140-5-j.neuschaefer@gmx.net>

In order that the end of a clk_div_table can be detected, it must be
terminated with a sentinel element (.div = 0).

Signed-off-by: Jonathan Neusch?fer <j.neuschaefer at gmx.net>
---
 drivers/clk/clk-clps711x.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c
index a2c6486ef1708..d96d96c8752c7 100644
--- a/drivers/clk/clk-clps711x.c
+++ b/drivers/clk/clk-clps711x.c
@@ -28,11 +28,13 @@ static const struct clk_div_table spi_div_table[] = {
 	{ .val = 1, .div = 8, },
 	{ .val = 2, .div = 2, },
 	{ .val = 3, .div = 1, },
+	{}
 };

 static const struct clk_div_table timer_div_table[] = {
 	{ .val = 0, .div = 256, },
 	{ .val = 1, .div = 1, },
+	{}
 };

 struct clps711x_clk {
--
2.34.1



From broonie at kernel.org  Fri Jan 28 15:46:57 2022
From: broonie at kernel.org (Mark Brown)
Date: Fri, 28 Jan 2022 23:46:57 +0000
Subject: (subset) [PATCH v2 0/3] (Re)enable DP/HDMI audio for RK3399 Gru
In-Reply-To: <20220114230209.4091727-1-briannorris@chromium.org>
References: <20220114230209.4091727-1-briannorris@chromium.org>
Message-ID: <164341361780.694709.13259283241590347085.b4-ty@kernel.org>

On Fri, 14 Jan 2022 15:02:06 -0800, Brian Norris wrote:
> This series fixes DP/HDMI audio for RK3399 Gru systems.
> 
> First, there was a regression with the switch to SPDIF. Patch 1 can be
> taken separately as a regression fix if desired. But it's not quite so
> useful (at least on Chrome OS systems) without the second part.
> 
> Second, jack detection was never upstreamed, because the hdmi-codec
> dependencies were still being worked out when this platform was first
> supported.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[2/3] drm/rockchip: cdn-dp: Support HDMI codec plug-change callback
      commit: 9da1467b49ad6c02840e8f331c5da69f6a5bdb2e
[3/3] ASoC: rk3399_gru_sound: Wire up DP jack detection
      commit: 6a8bc4b68ca0c6ef73518b692c00b7e1e010d056

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


From linus.walleij at linaro.org  Fri Jan 28 17:21:33 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sat, 29 Jan 2022 02:21:33 +0100
Subject: [PATCH 1/2] ARM: dts: gemini: ns2502: permit to use gigabit
In-Reply-To: <20220115100444.3014823-1-clabbe@baylibre.com>
References: <20220115100444.3014823-1-clabbe@baylibre.com>
Message-ID: <CACRpkdY2jo2f+O4TjRfHenLQcFEyE=Tm1SnmxrS-_H9P9mqqyA@mail.gmail.com>

On Sat, Jan 15, 2022 at 11:04 AM Corentin Labbe <clabbe at baylibre.com> wrote:

> I believed that gigabit was not working due to some unknown missing GPIO.
> In fact, gigabit worked when REALTEK_PHY was compiled out.
> So the problem was due to PHY delay and we need to use rgmii-id.
>
> Signed-off-by: Corentin Labbe <clabbe at baylibre.com>

Thanks Corentin!

Patches applied.

Do you think I need a similar fix "rgmii"->"rgmii-id" on other
Gemini devicetrees that claim gigabit performance?

Yours,
Linus Walleij


From linus.walleij at linaro.org  Fri Jan 28 17:53:30 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sat, 29 Jan 2022 02:53:30 +0100
Subject: [PATCH 3/3] ARM: dts: qcom: basic HP TouchPad support
In-Reply-To: <YfDKTGQDh3tDMECz@builder.lan>
References: <cover.1643075547.git.benwolsieffer@gmail.com>
 <9f19df2a0017b71547445ac34df221e827c45bd0.1643075547.git.benwolsieffer@gmail.com>
 <YfDKTGQDh3tDMECz@builder.lan>
Message-ID: <CACRpkday7mRWPfirjY+VcS-tB8CwqWQCyunkTUh0om9DXF4F3g@mail.gmail.com>

On Wed, Jan 26, 2022 at 5:13 AM Bjorn Andersson
<bjorn.andersson at linaro.org> wrote:

> @Linus, please take a look at the regulator question below.

OK!

> >  arch/arm/boot/dts/qcom-apq8060-tenderloin.dts | 549 ++----------------

Nice to see some use of all the work put into the APQ8060 support!

FYI: if you want graphics, this work may need to get finished:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-integrator.git/log/?h=apq8060-dragonboard-graphics
(mainly the MMCC)

> >               pinctrl at 800000 {
> > -                     /* eMMMC pins, all 8 data lines connected */
>
> It would be nice if you could throw a separate patch on the list that
> fixes this spelling mistake in the original as well.

Yes pls.

> >                               l21 {
> > -                                     // 1.1 V according to schematic
> >                                       regulator-min-microvolt = <1200000>;
> >                                       regulator-max-microvolt = <1200000>;
> >                                       bias-pull-down;
> > -                                     regulator-always-on;
> > +                                     /*
> > +                                      * RPM driver can't handle always-on regulators that are
> > +                                      * supplied by regulators initialized after them.
> > +                                      */
>
> That looks like an oversight that should be corrected, perhaps it needs
> similar attention that was given to the smd-rpm driver recently?

Indeed

> But this makes me wonder, how can this work on the other board? Linus?

I suppose these don't supply anything vital?

I know I have seen some regulators switch off and on but I
may have been confused.


> >                               s0 {
> > -                                     // regulator-min-microvolt = <500000>;
> > +                                     // regulator-min-microvolt = <800000>;
> >                                       // regulator-max-microvolt = <1325000>;
>
> This looks like the full range the regulator could do, do you see a
> reason for documenting that here? Unless there's a good reason I think
> you should leave the commented min/max out.

Yours,
Linus Walleij


From mr.bossman075 at gmail.com  Fri Jan 28 18:05:28 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Fri, 28 Jan 2022 21:05:28 -0500
Subject: [PATCH] ARM: dts: suniv: Add MMC and clock macros.
In-Reply-To: <20220127005304.06215ae8@slackpad.fritz.box>
References: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
 <20220126235726.03abdab4@slackpad.fritz.box>
 <d69233d8-4e3d-56db-d4d3-1b39fe84ee30@gmail.com>
 <20220127005304.06215ae8@slackpad.fritz.box>
Message-ID: <d19e70d8-02e1-b986-c0cf-f081fd82b52a@gmail.com>



On 1/26/22 19:53, Andre Przywara wrote:
> On Wed, 26 Jan 2022 19:12:05 -0500
> Jesse Taube <mr.bossman075 at gmail.com> wrote:
> 
>> On 1/26/22 18:57, Andre Przywara wrote:
>>> On Mon, 24 Jan 2022 20:13:52 -0500
>>> Jesse Taube <mr.bossman075 at gmail.com> wrote:
>>>
>>> Hi Jesse,
>>>
>>> I understand that get_maintainers.pl suggested this CC: list,  but you
>>> should add sunxi people and linux-arm kernel ML. Doing that now.
>> Uh yeah that makes sense in hind sight.
>>>> Include clock and reset macros and replace magic numbers.
>>>> Add MMC node.
>>>
>>> This patch itself does not do much, does it? You would at least need to
>>> enable that in the board dts.
>> True it doesn't do much just so that its in both u-boot and linux.
>>> And this should be multiple patches:
>>> 1) replace numbers with macros (part of this patch)
>>> 2) Add the MMC compatible string combo to the the bindings doc
Uh there is no f1c100s driver yet its just a placeholder it should be 
compatible with the a20 though.
>>> 3) Add the *two* MMC nodes and at least the pinctrl node for MMC0 to the
>>> SoC .dtsi (partly in this patch)
>>> 4) Enable the MMC and the card detect pin in the Nano board .dts
Uh after like an hour of trying to find the schematic I found it here 
nano.lichee.pro but the card detect pin isn't connected ;-(.
>>>
>>> I checked that the macros names match the numbers they replace, so
>>> you can add my R-b: on that patch 1 (if you follow my suggestion).
>>> The MMC node also seems to look sane.
>> That seems okay.
>>>>
>>>> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>
>>>
>>> It is not evident why Mesih's S-o-b: is in here? The patch seems to be
>>> authored and sent by you? Either you make him the author if that is his
>>> patch originally, or you put him just as Cc: or in Suggested-by:, maybe.
>> I did write the patch after I wrote it I was looking at his github and
>> he had almost the same patch.
> 
> Yeah, not really surprising, there are only so many ways to write a DT.
> I guess he never sent it, and since you wrote it, it's yours, so just
> add him in Cc:, since he was involved in the F1C100s upstreaming.
> 
> Cheers,
> Andre
> 
>>> Cheers,
>>> Andre
>>>    
>>>> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
>>>> ---
>>>>    arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 +++++++++++++++++++++++-----
>>>>    1 file changed, 34 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
>>>> index 6100d3b75f61..32872bb29917 100644
>>>> --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
>>>> +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
>>>> @@ -4,6 +4,9 @@
>>>>     * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
>>>>     */
>>>>    
>>>> +#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
>>>> +#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
>>>> +
>>>>    / {
>>>>    	#address-cells = <1>;
>>>>    	#size-cells = <1>;
>>>> @@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
>>>>    			compatible = "allwinner,suniv-f1c100s-pinctrl";
>>>>    			reg = <0x01c20800 0x400>;
>>>>    			interrupts = <38>, <39>, <40>;
>>>> -			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
>>>> +			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
>>>>    			clock-names = "apb", "hosc", "losc";
>>>>    			gpio-controller;
>>>>    			interrupt-controller;
>>>> @@ -93,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
>>>>    				pins = "PE0", "PE1";
>>>>    				function = "uart0";
>>>>    			};
>>>> +
>>>> +			mmc0_pins: mmc0-pins {
>>>> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
>>>> +				function = "mmc0";
>>>> +			};
>>>>    		};
>>>>    
>>>>    		timer at 1c20c00 {
>>>> @@ -108,14 +116,33 @@ wdt: watchdog at 1c20ca0 {
>>>>    			reg = <0x01c20ca0 0x20>;
>>>>    		};
>>>>    
>>>> +		mmc0: mmc at 1c0f000 {
>>>> +			compatible = "allwinner,suniv-f1c100s-mmc",
>>>> +				     "allwinner,sun7i-a20-mmc";
>>>> +			reg = <0x01c0f000 0x1000>;
>>>> +			clocks = <&ccu CLK_BUS_MMC0>,
>>>> +				 <&ccu CLK_MMC0>,
>>>> +				 <&ccu CLK_MMC0_OUTPUT>,
>>>> +				 <&ccu CLK_MMC0_SAMPLE>;
>>>> +			clock-names = "ahb", "mmc", "output", "sample";
>>>> +			resets = <&ccu RST_BUS_MMC0>;
>>>> +			reset-names = "ahb";
>>>> +			interrupts = <23>;
>>>> +			pinctrl-names = "default";
>>>> +			pinctrl-0 = <&mmc0_pins>;
>>>> +			status = "disabled";
>>>> +			#address-cells = <1>;
>>>> +			#size-cells = <0>;
>>>> +		};
>>>> +
>>>>    		uart0: serial at 1c25000 {
>>>>    			compatible = "snps,dw-apb-uart";
>>>>    			reg = <0x01c25000 0x400>;
>>>>    			interrupts = <1>;
>>>>    			reg-shift = <2>;
>>>>    			reg-io-width = <4>;
>>>> -			clocks = <&ccu 38>;
>>>> -			resets = <&ccu 24>;
>>>> +			clocks = <&ccu CLK_BUS_UART0>;
>>>> +			resets = <&ccu RST_BUS_UART0>;
>>>>    			status = "disabled";
>>>>    		};
>>>>    
>>>> @@ -125,8 +152,8 @@ uart1: serial at 1c25400 {
>>>>    			interrupts = <2>;
>>>>    			reg-shift = <2>;
>>>>    			reg-io-width = <4>;
>>>> -			clocks = <&ccu 39>;
>>>> -			resets = <&ccu 25>;
>>>> +			clocks = <&ccu CLK_BUS_UART1>;
>>>> +			resets = <&ccu RST_BUS_UART1>;
>>>>    			status = "disabled";
>>>>    		};
>>>>    
>>>> @@ -136,8 +163,8 @@ uart2: serial at 1c25800 {
>>>>    			interrupts = <3>;
>>>>    			reg-shift = <2>;
>>>>    			reg-io-width = <4>;
>>>> -			clocks = <&ccu 40>;
>>>> -			resets = <&ccu 26>;
>>>> +			clocks = <&ccu CLK_BUS_UART2>;
>>>> +			resets = <&ccu RST_BUS_UART2>;
>>>>    			status = "disabled";
>>>>    		};
>>>>    	};
>>>    
> 


From andre.przywara at arm.com  Fri Jan 28 18:31:55 2022
From: andre.przywara at arm.com (Andre Przywara)
Date: Sat, 29 Jan 2022 02:31:55 +0000
Subject: [PATCH] ARM: dts: suniv: Add MMC and clock macros.
In-Reply-To: <d19e70d8-02e1-b986-c0cf-f081fd82b52a@gmail.com>
References: <20220125011352.2691365-1-Mr.Bossman075@gmail.com>
 <20220126235726.03abdab4@slackpad.fritz.box>
 <d69233d8-4e3d-56db-d4d3-1b39fe84ee30@gmail.com>
 <20220127005304.06215ae8@slackpad.fritz.box>
 <d19e70d8-02e1-b986-c0cf-f081fd82b52a@gmail.com>
Message-ID: <20220129023155.401b2fa3@slackpad.fritz.box>

On Fri, 28 Jan 2022 21:05:28 -0500
Jesse Taube <mr.bossman075 at gmail.com> wrote:

> On 1/26/22 19:53, Andre Przywara wrote:
> > On Wed, 26 Jan 2022 19:12:05 -0500
> > Jesse Taube <mr.bossman075 at gmail.com> wrote:
> >   
> >> On 1/26/22 18:57, Andre Przywara wrote:  
> >>> On Mon, 24 Jan 2022 20:13:52 -0500
> >>> Jesse Taube <mr.bossman075 at gmail.com> wrote:
> >>>
> >>> Hi Jesse,
> >>>
> >>> I understand that get_maintainers.pl suggested this CC: list,  but you
> >>> should add sunxi people and linux-arm kernel ML. Doing that now.  
> >> Uh yeah that makes sense in hind sight.  
> >>>> Include clock and reset macros and replace magic numbers.
> >>>> Add MMC node.  
> >>>
> >>> This patch itself does not do much, does it? You would at least need to
> >>> enable that in the board dts.  
> >> True it doesn't do much just so that its in both u-boot and linux.  
> >>> And this should be multiple patches:
> >>> 1) replace numbers with macros (part of this patch)
> >>> 2) Add the MMC compatible string combo to the the bindings doc  
> Uh there is no f1c100s driver yet its just a placeholder it should be 
> compatible with the a20 though.

That is expected, ideally we won't need any addition to the driver
file, as indeed chances are it's really compatible to the A20.
But in any case we need to document the compatible string, and how it
is used: paired with the actual defining A20 fallback string. This
needs to go to
Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml.
If you look around in that file and its git history, you should get the
idea what you need to do.

> >>> 3) Add the *two* MMC nodes and at least the pinctrl node for MMC0 to the
> >>> SoC .dtsi (partly in this patch)
> >>> 4) Enable the MMC and the card detect pin in the Nano board .dts  
> Uh after like an hour of trying to find the schematic I found it here 
> nano.lichee.pro but the card detect pin isn't connected ;-(.

That's fine, it wouldn't be the first one. We have the "broken-cd;"
property for this.

Cheers,
Andre


> >>>
> >>> I checked that the macros names match the numbers they replace, so
> >>> you can add my R-b: on that patch 1 (if you follow my suggestion).
> >>> The MMC node also seems to look sane.  
> >> That seems okay.  
> >>>>
> >>>> Signed-off-by: Mesih Kilinc <mesihkilinc at gmail.com>  
> >>>
> >>> It is not evident why Mesih's S-o-b: is in here? The patch seems to be
> >>> authored and sent by you? Either you make him the author if that is his
> >>> patch originally, or you put him just as Cc: or in Suggested-by:, maybe.  
> >> I did write the patch after I wrote it I was looking at his github and
> >> he had almost the same patch.  
> > 
> > Yeah, not really surprising, there are only so many ways to write a DT.
> > I guess he never sent it, and since you wrote it, it's yours, so just
> > add him in Cc:, since he was involved in the F1C100s upstreaming.
> > 
> > Cheers,
> > Andre
> >   
> >>> Cheers,
> >>> Andre
> >>>      
> >>>> Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
> >>>> ---
> >>>>    arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 +++++++++++++++++++++++-----
> >>>>    1 file changed, 34 insertions(+), 7 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >>>> index 6100d3b75f61..32872bb29917 100644
> >>>> --- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >>>> +++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
> >>>> @@ -4,6 +4,9 @@
> >>>>     * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
> >>>>     */
> >>>>    
> >>>> +#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
> >>>> +#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
> >>>> +
> >>>>    / {
> >>>>    	#address-cells = <1>;
> >>>>    	#size-cells = <1>;
> >>>> @@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
> >>>>    			compatible = "allwinner,suniv-f1c100s-pinctrl";
> >>>>    			reg = <0x01c20800 0x400>;
> >>>>    			interrupts = <38>, <39>, <40>;
> >>>> -			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
> >>>> +			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
> >>>>    			clock-names = "apb", "hosc", "losc";
> >>>>    			gpio-controller;
> >>>>    			interrupt-controller;
> >>>> @@ -93,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
> >>>>    				pins = "PE0", "PE1";
> >>>>    				function = "uart0";
> >>>>    			};
> >>>> +
> >>>> +			mmc0_pins: mmc0-pins {
> >>>> +				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
> >>>> +				function = "mmc0";
> >>>> +			};
> >>>>    		};
> >>>>    
> >>>>    		timer at 1c20c00 {
> >>>> @@ -108,14 +116,33 @@ wdt: watchdog at 1c20ca0 {
> >>>>    			reg = <0x01c20ca0 0x20>;
> >>>>    		};
> >>>>    
> >>>> +		mmc0: mmc at 1c0f000 {
> >>>> +			compatible = "allwinner,suniv-f1c100s-mmc",
> >>>> +				     "allwinner,sun7i-a20-mmc";
> >>>> +			reg = <0x01c0f000 0x1000>;
> >>>> +			clocks = <&ccu CLK_BUS_MMC0>,
> >>>> +				 <&ccu CLK_MMC0>,
> >>>> +				 <&ccu CLK_MMC0_OUTPUT>,
> >>>> +				 <&ccu CLK_MMC0_SAMPLE>;
> >>>> +			clock-names = "ahb", "mmc", "output", "sample";
> >>>> +			resets = <&ccu RST_BUS_MMC0>;
> >>>> +			reset-names = "ahb";
> >>>> +			interrupts = <23>;
> >>>> +			pinctrl-names = "default";
> >>>> +			pinctrl-0 = <&mmc0_pins>;
> >>>> +			status = "disabled";
> >>>> +			#address-cells = <1>;
> >>>> +			#size-cells = <0>;
> >>>> +		};
> >>>> +
> >>>>    		uart0: serial at 1c25000 {
> >>>>    			compatible = "snps,dw-apb-uart";
> >>>>    			reg = <0x01c25000 0x400>;
> >>>>    			interrupts = <1>;
> >>>>    			reg-shift = <2>;
> >>>>    			reg-io-width = <4>;
> >>>> -			clocks = <&ccu 38>;
> >>>> -			resets = <&ccu 24>;
> >>>> +			clocks = <&ccu CLK_BUS_UART0>;
> >>>> +			resets = <&ccu RST_BUS_UART0>;
> >>>>    			status = "disabled";
> >>>>    		};
> >>>>    
> >>>> @@ -125,8 +152,8 @@ uart1: serial at 1c25400 {
> >>>>    			interrupts = <2>;
> >>>>    			reg-shift = <2>;
> >>>>    			reg-io-width = <4>;
> >>>> -			clocks = <&ccu 39>;
> >>>> -			resets = <&ccu 25>;
> >>>> +			clocks = <&ccu CLK_BUS_UART1>;
> >>>> +			resets = <&ccu RST_BUS_UART1>;
> >>>>    			status = "disabled";
> >>>>    		};
> >>>>    
> >>>> @@ -136,8 +163,8 @@ uart2: serial at 1c25800 {
> >>>>    			interrupts = <3>;
> >>>>    			reg-shift = <2>;
> >>>>    			reg-io-width = <4>;
> >>>> -			clocks = <&ccu 40>;
> >>>> -			resets = <&ccu 26>;
> >>>> +			clocks = <&ccu CLK_BUS_UART2>;
> >>>> +			resets = <&ccu RST_BUS_UART2>;
> >>>>    			status = "disabled";
> >>>>    		};
> >>>>    	};  
> >>>      
> >   
> 



From sfr at canb.auug.org.au  Fri Jan 28 19:07:10 2022
From: sfr at canb.auug.org.au (Stephen Rothwell)
Date: Sat, 29 Jan 2022 14:07:10 +1100
Subject: [next] arch/arm/kernel/setup.c:1028:63: error: 'SECTION_SIZE'
 undeclared
In-Reply-To: <CA+G9fYvxxc4o5UjRfHVgmcaTN1ijxXX8e=OTP4t7PbRENmVBsQ@mail.gmail.com>
References: <CA+G9fYvxxc4o5UjRfHVgmcaTN1ijxXX8e=OTP4t7PbRENmVBsQ@mail.gmail.com>
Message-ID: <20220129140710.1ef9f9a5@canb.auug.org.au>

Hi all,

On Fri, 28 Jan 2022 20:51:53 +0530 Naresh Kamboju <naresh.kamboju at linaro.org> wrote:
>
> Following build errors noticed on Linux next 20220128 arm with tinyconfig.
> 
> make --silent --keep-going --jobs=8 \
>    ARCH=arm \
>    CROSS_COMPILE=arm-linux-gnueabihf- \
>    'CC=sccache arm-linux-gnueabihf-gcc' \
>    'HOSTCC=sccache gcc'
> 
> arch/arm/kernel/setup.c: In function 'reserve_crashkernel':
> arch/arm/kernel/setup.c:1028:63: error: 'SECTION_SIZE' undeclared
> (first use in this function); did you mean 'SECTIONS_SHIFT'?
>  1028 |                 start = memblock_phys_alloc_range(crash_size,
> SECTION_SIZE,
>       |
> ^~~~~~~~~~~~
>       |
> SECTIONS_SHIFT
> arch/arm/kernel/setup.c:1028:63: note: each undeclared identifier is
> reported only once for each function it appears in
> make[3]: *** [scripts/Makefile.build:289: arch/arm/kernel/setup.o] Error 1
> 
> 
> Reported-by: Linux Kernel Functional Testing <lkft at linaro.org>
> 
> meta data:
> -----------
>     git describe: next-20220128
>     git_repo: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
>     git_sha: b605fdc54c2b28c30ef06d9db99282d8a32ae4be
>     target_arch: arm
>     kconfig: tinyconfig
>     toolchain: gcc-11
> 
> Build log:
> -------------
> https://builds.tuxbuild.com/24JPvTrXx7HvkQtxoIXqZtZoZkA/
> 
> Steps to reproduce:
> --------------------
> # To install tuxmake on your system globally:
> # sudo pip3 install -U tuxmake
> #
> # See https://docs.tuxmake.org/ for complete documentation.
> # Original tuxmake command with fragments listed below.
> 
> tuxmake --runtime podman --target-arch arm --toolchain gcc-11
> --kconfig tinyconfig
> 
> --
> Linaro LKFT
> https://lkft.linaro.org

Caused by commit

  35f56ebeffca ("arm: use IS_ENABLED(CONFIG_KEXEC_CORE) instead of #ifdef")

from Andrew's patch series.

I assume CONFIG_MMU is not set in tinyconfig for arm (so neither of
asm/pgtable-[23]level.h are included by asm/pgtable.h)?  CONFIG_KEXEC
depends on CONFIG_MMU.
-- 
Cheers,
Stephen Rothwell
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220129/015d68d8/attachment.sig>

From shawnguo at kernel.org  Fri Jan 28 21:34:49 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 13:34:49 +0800
Subject: [PATCH] arm64: dts: ls1028a: sl28: re-enable ftm_alarm0
In-Reply-To: <20220115210432.449968-1-michael@walle.cc>
References: <20220115210432.449968-1-michael@walle.cc>
Message-ID: <20220129053448.GN4686@dragon>

On Sat, Jan 15, 2022 at 10:04:32PM +0100, Michael Walle wrote:
> Commit dd3d936a1b17 ("arm64: dts: ls1028a: add ftm_alarm1 node to be
> used as wakeup source") disables ftm_alarm0 in the SoC dtsi but doesn't
> enable it on the board which is still using it. Re-enable it on the sl28
> board.
> 
> Fixes: dd3d936a1b17 ("arm64: dts: ls1028a: add ftm_alarm1 node to be used as wakeup source")
> Reported-by: Guillaume Tucker <guillaume.tucker at collabora.com>
> Reported-by: "kernelci.org bot" <bot at kernelci.org>
> Signed-off-by: Michael Walle <michael at walle.cc>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 21:42:10 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 13:42:10 +0800
Subject: [PATCH 2/2] Revert "arm64: dts: ls1028a: add flextimer based pwm
 nodes"
In-Reply-To: <20220115210907.451189-2-michael@walle.cc>
References: <20220115210907.451189-1-michael@walle.cc>
 <20220115210907.451189-2-michael@walle.cc>
Message-ID: <20220129054209.GO4686@dragon>

On Sat, Jan 15, 2022 at 10:09:07PM +0100, Michael Walle wrote:
> The changes to the device tree look very wrong. There are now two
> devices with the same base address: pwm0 and ftm_alarm0. Both are using
> the Flex Timer Module. It seems like this should either be one driver or
> and MFD driver. Either way, there should only be one node in the device
> tree. Revert the offending changes to avoid getting a broken device tree
> in circulation.

Why not just fix the conflicting nodes?

Shawn

> 
> This reverts commit 71799672ea24d2935322d655d2407c1ccd7db9ff.
> 
> Fixes: 71799672ea24 ("arm64: dts: ls1028a: add flextimer based pwm nodes")
> Signed-off-by: Michael Walle <michael at walle.cc>
> ---
> 
> Btw, the nodes are also not sorted by the address. Otherwise it should have
> been spotted easily.
> 
>  .../arm64/boot/dts/freescale/fsl-ls1028a.dtsi | 95 -------------------
>  1 file changed, 95 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> index 1ef26cbc79cb..d3cc8cbaf768 100644
> --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
> @@ -66,13 +66,6 @@ CPU_PW20: cpu-pw20 {
>  		};
>  	};
>  
> -	rtc_clk: rtc-clk {
> -		compatible = "fixed-clock";
> -		#clock-cells = <0>;
> -		clock-frequency = <32768>;
> -		clock-output-names = "rtc_clk";
> -	};
> -
>  	sysclk: sysclk {
>  		compatible = "fixed-clock";
>  		#clock-cells = <0>;
> @@ -1245,94 +1238,6 @@ ierb at 1f0800000 {
>  			reg = <0x01 0xf0800000 0x0 0x10000>;
>  		};
>  
> -		pwm0: pwm at 2800000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2800000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm1: pwm at 2810000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2810000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm2: pwm at 2820000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2820000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm3: pwm at 2830000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2830000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm4: pwm at 2840000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2840000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm5: pwm at 2850000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2850000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm6: pwm at 2860000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2860000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
> -		pwm7: pwm at 2870000 {
> -			compatible = "fsl,vf610-ftm-pwm";
> -			#pwm-cells = <3>;
> -			reg = <0x0 0x2870000 0x0 0x10000>;
> -			clock-names = "ftm_sys", "ftm_ext",
> -				      "ftm_fix", "ftm_cnt_clk_en";
> -			clocks = <&clockgen 4 1>, <&clockgen 4 1>,
> -				 <&rtc_clk>, <&clockgen 4 1>;
> -			status = "disabled";
> -		};
> -
>  		rcpm: power-controller at 1e34040 {
>  			compatible = "fsl,ls1028a-rcpm", "fsl,qoriq-rcpm-2.1+";
>  			reg = <0x0 0x1e34040 0x0 0x1c>;
> -- 
> 2.30.2
> 


From shawnguo at kernel.org  Fri Jan 28 21:46:30 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 13:46:30 +0800
Subject: [RFC PATCH v3 1/4] ARM: dts: imx28: reparent gpmi clock to
 ref_gpmi
In-Reply-To: <20220117161755.1863579-2-dario.binacchi@amarulasolutions.com>
References: <20220117161755.1863579-1-dario.binacchi@amarulasolutions.com>
 <20220117161755.1863579-2-dario.binacchi@amarulasolutions.com>
Message-ID: <20220129054629.GP4686@dragon>

On Mon, Jan 17, 2022 at 05:17:52PM +0100, Dario Binacchi wrote:
> Since ref_gpmi is sourced from pll0 (480MHz), It allows the GPMI
> controller to manage High-Speed ??NAND Timing (edo mode 3,4 and 5).
> 
> Co-developed-by: Michael Trimarchi <michael at amarulasolutions.com>
> Signed-off-by: Michael Trimarchi <michael at amarulasolutions.com>
> Signed-off-by: Dario Binacchi <dario.binacchi at amarulasolutions.com>

Applied, thanks!


From reijiw at google.com  Fri Jan 28 21:52:21 2022
From: reijiw at google.com (Reiji Watanabe)
Date: Fri, 28 Jan 2022 21:52:21 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <CAOHnOrwBoQncTPngxqWgD_mEDWT6AwcmB_QC=j-eUPY2fwHa2Q@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
 <YfDaiUbSkpi9/5YY@google.com>
 <CAAeT=FzNSvzz-Ok0Ka95=kkdDGsAMmzf9xiRfD5gYCdvmEfifg@mail.gmail.com>
 <CAOHnOrwBoQncTPngxqWgD_mEDWT6AwcmB_QC=j-eUPY2fwHa2Q@mail.gmail.com>
Message-ID: <CAAeT=FyqPX_XQ+LDuRBZhApeiWD4s81bTMe=qiKDOZkBWm5ARg@mail.gmail.com>

Hi Ricardo,

> > > > +
> > > > +/*
> > > > + * Set the guest's ID registers that are defined in sys_reg_descs[]
> > > > + * with ID_SANITISED() to the host's sanitized value.
> > > > + */
> > > > +void set_default_id_regs(struct kvm *kvm)
> > > > +{
> > > > +     int i;
> > > > +     u32 id;
> > > > +     const struct sys_reg_desc *rd;
> > > > +     u64 val;
> > > > +
> > > > +     for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> > > > +             rd = &sys_reg_descs[i];
> > > > +             if (rd->access != access_id_reg)
> > > > +                     /* Not ID register, or hidden/reserved ID register */
> > > > +                     continue;
> > > > +
> > > > +             id = reg_to_encoding(rd);
> > > > +             if (WARN_ON_ONCE(!is_id_reg(id)))
> > > > +                     /* Shouldn't happen */
> > > > +                     continue;
> > > > +
> > > > +             val = read_sanitised_ftr_reg(id);
> > >
> > > I'm a bit confused. Shouldn't the default+sanitized values already use
> > > arm64_ftr_bits_kvm (instead of arm64_ftr_regs)?
> >
> > I'm not sure if I understand your question.
> > arm64_ftr_bits_kvm is used for feature support checkings when
> > userspace tries to modify a value of ID registers.
> > With this patch, KVM just saves the sanitized values in the kvm's
> > buffer, but userspace is still not allowed to modify values of ID
> > registers yet.
> > I hope it answers your question.
>
> Based on the previous commit I was assuming that some registers, like
> id_aa64dfr0,
> would default to the overwritten values as the sanitized values. More
> specifically: if
> userspace doesn't modify any ID reg, shouldn't the defaults have the
> KVM overwritten
> values (arm64_ftr_bits_kvm)?

arm64_ftr_bits_kvm doesn't have arm64_ftr_reg but arm64_ftr_bits,
and arm64_ftr_bits_kvm doesn't have the sanitized values.

Thanks,
Reiji


From shawnguo at kernel.org  Fri Jan 28 22:08:19 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:08:19 +0800
Subject: [PATCH] arm64: dts: imx8mp-evk: add PCA6416 interrupt controller
 mode
In-Reply-To: <20220117230639.1257549-1-hugo@hugovil.com>
References: <20220117230639.1257549-1-hugo@hugovil.com>
Message-ID: <20220129060818.GQ4686@dragon>

On Mon, Jan 17, 2022 at 06:06:39PM -0500, Hugo Villeneuve wrote:
> From: Hugo Villeneuve <hvilleneuve at dimonoff.com>
> 
> Add interrupt controller mode for the pca6416 on i.MX8MP EVK board's.
> 
> Signed-off-by: Hugo Villeneuve <hvilleneuve at dimonoff.com>

It doesn't apply to my branch.  Could you rebase?

Shawn

> ---
>  arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> index 66437b659f3a..00e1e1342162 100755
> --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
> @@ -526,6 +526,12 @@ pca6416: gpio at 20 {
>  		reg = <0x20>;
>  		gpio-controller;
>  		#gpio-cells = <2>;
> +		interrupt-controller;
> +		#interrupt-cells = <2>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_pca6416_int>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
>  	};
>  
>  	codec: wm8960 at 1a {
> @@ -1209,6 +1215,12 @@ pinctrl_csi_mclk: csi_mclk_grp {
>  			MX8MP_IOMUXC_GPIO1_IO15__CCM_CLKO2	0x59
>  		>;
>  	};
> +
> +	pinctrl_pca6416_int: pca6416_int_grp {
> +		fsl,pins = <
> +			MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12	0x146 /* Input pull-up. */
> +		>;
> +	};
>  };
>  
>  &vpu_g1 {
> -- 
> 2.30.2
> 


From shawnguo at kernel.org  Fri Jan 28 22:15:26 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:15:26 +0800
Subject: [PATCH 2/2] arm64: dts: imx8qxp-ss-adma: Drop fsl, imx7ulp-lpuart
 comaptible
In-Reply-To: <20220118135918.2126010-2-abel.vesa@nxp.com>
References: <20220118135918.2126010-1-abel.vesa@nxp.com>
 <20220118135918.2126010-2-abel.vesa@nxp.com>
Message-ID: <20220129061525.GR4686@dragon>

On Tue, Jan 18, 2022 at 03:59:18PM +0200, Abel Vesa wrote:
> The driver differs from clocks point of view, so the i.MX8QXP
> is not backwards compatible with i.MX7ULP.
> 
> Signed-off-by: Abel Vesa <abel.vesa at nxp.com>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 22:17:04 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:17:04 +0800
Subject: [PATCH] arm64: dts: imx8mp: disable usb3_phy1
In-Reply-To: <20220119132348.2093807-1-l.stach@pengutronix.de>
References: <20220119132348.2093807-1-l.stach@pengutronix.de>
Message-ID: <20220129061704.GS4686@dragon>

On Wed, Jan 19, 2022 at 02:23:48PM +0100, Lucas Stach wrote:
> Like usb3_phy0 the default state of the usb3_phy1 should be disabled, so
> it is only enabled on boards exposing this USB port.
> 
> Signed-off-by: Lucas Stach <l.stach at pengutronix.de>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 22:23:40 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:23:40 +0800
Subject: [PATCH] ARM: dts: imx7ulp: Fix 'assigned-clocks-parents' typo
In-Reply-To: <20220120172355.1629650-1-robh@kernel.org>
References: <20220120172355.1629650-1-robh@kernel.org>
Message-ID: <20220129062339.GT4686@dragon>

On Thu, Jan 20, 2022 at 11:23:55AM -0600, Rob Herring wrote:
> The correct property name is 'assigned-clock-parents', not
> 'assigned-clocks-parents'. Though if the platform works with the typo, one
> has to wonder if the property is even needed.
> 
> Signed-off-by: Rob Herring <robh at kernel.org>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 22:30:00 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:30:00 +0800
Subject: [PATCH v1 0/2] arm64: dts: imx8mq: fix mipi_csi port numbering
In-Reply-To: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
References: <20220121093326.2388251-1-martin.kepplinger@puri.sm>
Message-ID: <20220129062959.GU4686@dragon>

On Fri, Jan 21, 2022 at 10:33:24AM +0100, Martin Kepplinger wrote:
> hi Shawn and all interested,
> 
> This is a fix for an embarrassing bug that slipped into commit
> bcadd5f66c2a ("arm64: dts: imx8mq: add mipi csi phy and csi bridge descriptions")
> and commit fed7603597fa ("arm64: dts: imx8mq-librem5: describe the selfie cam").
> 
> When preparing the imx8mq.dtsi description I only tested with port at 1
> being connected to the csi bridge, but what I sent said port at 0.
> 
> I have this on my list for a while and want to sort this out now. I'm
> sorry for the inconvenience. Until now imx8mq-librem5 is the only user
> (maybe because of this :).
> 
> thank you,
> 
>                               martin
> 
> 
> Martin Kepplinger (2):
>   arm64: dts: imx8mq: fix mipi_csi bidirectional port numbers
>   arm64: dts: imx8mq-librem5: fix mipi_csi1 port number to sensor

Applied both, thanks!


From wsa+renesas at sang-engineering.com  Fri Jan 28 22:38:56 2022
From: wsa+renesas at sang-engineering.com (Wolfram Sang)
Date: Sat, 29 Jan 2022 07:38:56 +0100
Subject: [PATCH v2] arm64: move efi_reboot to restart handler
In-Reply-To: <YfRu86YoiFpVsqyn@localhost.localdomain>
References: <YfP0osb45uJldtM9@localhost.localdomain> <YfREAiRMjQ9ci4LC@shikoro>
 <YfRu86YoiFpVsqyn@localhost.localdomain>
Message-ID: <YfThAF9U1DJx0Hja@shikoro>

Hi Krzysztof,
> I would use something like 250, or even 254, just to indicate that we
> know that most certainly nothing should be run before efi_reboot(), but
> still allow those silly people like me, to do what they want in their
> system, without the need to run the custom kernel. I think we could even
> add a proper comment, so it woudld become something like:
> 
> /**
>  * If you are running UEFI based system, you most certainly should let
>  * efi_reboot() do a reset for you. If you think you know better, we
>  * leave you a window of opportunity here by not using maximal priorty
>  * here.
>  */
>  .priority = 250,

For your patchset, this seems good enough for me because it is decoupled
from PSCI now. I still think a set of defines should be collected in
linux/reboot.h so they can be used in reboot handlers. This is a
different patch series, though.

> What is the downside of doing that? That we will run through atomic
> notfier chain instead of calling efi_reboot directly? Sure this is
> slightly more complicated but it works on all our platforms and is
> battle proven and we don't worry about that there. And the upside is
> that we give people possibility to use their beloved mechanism if they
> really like to. Because flexibility is a good thing.

I agree with the upside having more value than the downside.

Happy hacking,

   Wolfram

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220129/d6ce6206/attachment.sig>

From shawnguo at kernel.org  Fri Jan 28 22:40:13 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:40:13 +0800
Subject: [PATCH 1/1] arm64: dts: imx8mq: fix lcdif port node
In-Reply-To: <20220125091646.2845111-1-alexander.stein@ew.tq-group.com>
References: <20220125091646.2845111-1-alexander.stein@ew.tq-group.com>
Message-ID: <20220129064012.GV4686@dragon>

On Tue, Jan 25, 2022 at 10:16:46AM +0100, Alexander Stein wrote:
> The port node does not have a unit-address, remove it.
> This fixes the warnings:
> lcd-controller at 30320000: 'port' is a required property
> lcd-controller at 30320000: 'port at 0' does not match any of the regexes:
> 'pinctrl-[0-9]+'
> 
> Fixes: commit d0081bd02a03 ("arm64: dts: imx8mq: Add NWL MIPI DSI controller")
> Signed-off-by: Alexander Stein <alexander.stein at ew.tq-group.com>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 22:42:13 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:42:13 +0800
Subject: [PATCH] arm64: dts: imx8mm: Add missing
 MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B
In-Reply-To: <20220125025409.130667-1-marex@denx.de>
References: <20220125025409.130667-1-marex@denx.de>
Message-ID: <20220129064213.GW4686@dragon>

On Tue, Jan 25, 2022 at 03:54:09AM +0100, Marek Vasut wrote:
> The i.MX8M Mini Application Processor Reference Manual, Rev. 3, 11/2020
> documents AF MX8MM_IOMUXC_NAND_READY_B_SD3_RESET_B , add it into the
> pinmux tables.
> 
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Fabio Estevam <festevam at gmail.com>
> Cc: NXP Linux Team <linux-imx at nxp.com>
> Cc: Peng Fan <peng.fan at nxp.com>
> Cc: Shawn Guo <shawnguo at kernel.org>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 22:59:22 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 14:59:22 +0800
Subject: [PATCH v2] arm64: dts: imx8m{m,n}_venice*: add gpio-line-names
In-Reply-To: <20220128010603.17620-1-tharvey@gateworks.com>
References: <20220128010603.17620-1-tharvey@gateworks.com>
Message-ID: <20220129065922.GX4686@dragon>

On Thu, Jan 27, 2022 at 05:06:03PM -0800, Tim Harvey wrote:
> Add gpio-line-names for the various GPIO's used on Gateworks Venice
> boards. Note that these GPIO's are typically 'configured' in Boot
> Firmware via gpio-hog therefore we only configure line names to keep the
> boot firmware configuration from changing on kernel init.
> 
> Signed-off-by: Tim Harvey <tharvey at gateworks.com>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 23:01:01 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 15:01:01 +0800
Subject: [PATCH] arm64: dts: ls1028a-qds: define mdio slots for
 networking options
In-Reply-To: <20220126092650.19962-1-leoyang.li@nxp.com>
References: <20220126092650.19962-1-leoyang.li@nxp.com>
Message-ID: <20220129070100.GY4686@dragon>

On Wed, Jan 26, 2022 at 03:26:50AM -0600, Li Yang wrote:
> The ls1028a QDS board support different pluggable PHY cards.  Define the
> nodes for these slots to be updated at boot time with overlay according
> to board setup.
> 
> Signed-off-by: Alex Marginean <alexandru.marginean at nxp.com>
> Signed-off-by: Li Yang <leoyang.li at nxp.com>

Applied, thanks!


From shawnguo at kernel.org  Fri Jan 28 23:09:10 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 15:09:10 +0800
Subject: [PATCH 0/2] Improve fsl-ls1028a-qds device tree overlay build
Message-ID: <20220129070912.9836-1-shawnguo@kernel.org>

It makes a couple of improvments on fsl-ls1028a-qds device tree overlay
build.  Compile tested only.

Shawn Guo (2):
  arm64: dts: fsl-ls1028a-qds: Drop overlay syntax hard coding
  arm64: dts: freescale: Use overlay target for simplicity

 arch/arm64/boot/dts/freescale/Makefile        |  29 ++--
 .../dts/freescale/fsl-ls1028a-qds-13bb.dts    | 146 ++++++++----------
 .../dts/freescale/fsl-ls1028a-qds-65bb.dts    | 138 +++++++----------
 .../dts/freescale/fsl-ls1028a-qds-7777.dts    |  99 ++++++------
 .../dts/freescale/fsl-ls1028a-qds-85bb.dts    | 134 +++++++---------
 .../dts/freescale/fsl-ls1028a-qds-899b.dts    |  86 +++++------
 .../dts/freescale/fsl-ls1028a-qds-9999.dts    |  97 ++++++------
 7 files changed, 313 insertions(+), 416 deletions(-)

-- 
2.17.1



From shawnguo at kernel.org  Fri Jan 28 23:09:12 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 15:09:12 +0800
Subject: [PATCH 2/2] arm64: dts: freescale: Use overlay target for simplicity
In-Reply-To: <20220129070912.9836-1-shawnguo@kernel.org>
References: <20220129070912.9836-1-shawnguo@kernel.org>
Message-ID: <20220129070912.9836-3-shawnguo@kernel.org>

With commit 15d16d6dadf6 ("kbuild: Add generic rule to apply
fdtoverlay"), overlay target can be used to simplify the build of DTB
overlays.  It also performs a cross check to ensure base DT and overlay
actually match.

Signed-off-by: Shawn Guo <shawnguo at kernel.org>
---
 arch/arm64/boot/dts/freescale/Makefile | 29 +++++++++++++-------------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 6d8f0a532587..c521ac2b00ca 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -1,14 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
-# required for overlay support
-DTC_FLAGS_fsl-ls1028a-qds := -@
-DTC_FLAGS_fsl-ls1028a-qds-13bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-65bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-7777 := -@
-DTC_FLAGS_fsl-ls1028a-qds-85bb := -@
-DTC_FLAGS_fsl-ls1028a-qds-899b := -@
-DTC_FLAGS_fsl-ls1028a-qds-9999 := -@
-
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frwy.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-oxalis.dtb
@@ -21,12 +12,6 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var2.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var3-ads2.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-kontron-sl28-var4.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
-dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
@@ -49,6 +34,20 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2162a-qds.dtb
 
+fsl-ls1028a-qds-13bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-13bb.dtbo
+fsl-ls1028a-qds-65bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-65bb.dtbo
+fsl-ls1028a-qds-7777-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-7777.dtbo
+fsl-ls1028a-qds-85bb-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-85bb.dtbo
+fsl-ls1028a-qds-899b-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-899b.dtbo
+fsl-ls1028a-qds-9999-dtbs := fsl-ls1028a-qds.dtb fsl-ls1028a-qds-9999.dtbo
+
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-13bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-65bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-7777.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-85bb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-899b.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds-9999.dtb
+
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-ddr4-evk.dtb
-- 
2.17.1



From shawnguo at kernel.org  Fri Jan 28 23:09:11 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 15:09:11 +0800
Subject: [PATCH 1/2] arm64: dts: fsl-ls1028a-qds: Drop overlay syntax hard
 coding
In-Reply-To: <20220129070912.9836-1-shawnguo@kernel.org>
References: <20220129070912.9836-1-shawnguo@kernel.org>
Message-ID: <20220129070912.9836-2-shawnguo@kernel.org>

As suggested by commit 9ae8578b517a ("of: Documentation: change overlay
example to use current syntax"), there is no need to have overlay syntax
be hard coded in the device tree source file any more.

Signed-off-by: Shawn Guo <shawnguo at kernel.org>
---
 .../dts/freescale/fsl-ls1028a-qds-13bb.dts    | 146 ++++++++----------
 .../dts/freescale/fsl-ls1028a-qds-65bb.dts    | 138 +++++++----------
 .../dts/freescale/fsl-ls1028a-qds-7777.dts    |  99 ++++++------
 .../dts/freescale/fsl-ls1028a-qds-85bb.dts    | 134 +++++++---------
 .../dts/freescale/fsl-ls1028a-qds-899b.dts    |  86 +++++------
 .../dts/freescale/fsl-ls1028a-qds-9999.dts    |  97 ++++++------
 6 files changed, 299 insertions(+), 401 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
index f748a2c12a70..f826392c23fa 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-13bb.dts
@@ -12,102 +12,80 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
-
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			slot1_sgmii: ethernet-phy at 2 {
-				/* AQR112 */
-				reg = <0x2>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-		};
-	};
-
-	fragment at 1 {
-		target = <&enetc_port0>;
-
-		__overlay__ {
-			phy-handle = <&slot1_sgmii>;
-			phy-mode = "usxgmii";
-			managed = "in-band-status";
-			status = "okay";
-		};
+&mdio_slot1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	slot1_sgmii: ethernet-phy at 2 {
+		/* AQR112 */
+		reg = <0x2>;
+		compatible = "ethernet-phy-ieee802.3-c45";
 	};
+};
 
-	fragment at 2 {
-		target = <&mdio_slot2>;
-
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			/* 4 ports on AQR412 */
-			slot2_qxgmii0: ethernet-phy at 0 {
-				reg = <0x0>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-
-			slot2_qxgmii1: ethernet-phy at 1 {
-				reg = <0x1>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
+&enetc_port0 {
+	phy-handle = <&slot1_sgmii>;
+	phy-mode = "usxgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
 
-			slot2_qxgmii2: ethernet-phy at 2 {
-				reg = <0x2>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
+&mdio_slot2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-			slot2_qxgmii3: ethernet-phy at 3 {
-				reg = <0x3>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-		};
+	/* 4 ports on AQR412 */
+	slot2_qxgmii0: ethernet-phy at 0 {
+		reg = <0x0>;
+		compatible = "ethernet-phy-ieee802.3-c45";
 	};
 
-	fragment at 3 {
-		target = <&mscc_felix_ports>;
+	slot2_qxgmii1: ethernet-phy at 1 {
+		reg = <0x1>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
 
-		__overlay__ {
-			port at 0 {
-				status = "okay";
-				phy-handle = <&slot2_qxgmii0>;
-				phy-mode = "usxgmii";
-				managed = "in-band-status";
-			};
+	slot2_qxgmii2: ethernet-phy at 2 {
+		reg = <0x2>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
 
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot2_qxgmii1>;
-				phy-mode = "usxgmii";
-				managed = "in-band-status";
-			};
+	slot2_qxgmii3: ethernet-phy at 3 {
+		reg = <0x3>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
+};
 
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot2_qxgmii2>;
-				phy-mode = "usxgmii";
-				managed = "in-band-status";
-			};
+&mscc_felix_ports {
+	port at 0 {
+		status = "okay";
+		phy-handle = <&slot2_qxgmii0>;
+		phy-mode = "usxgmii";
+		managed = "in-band-status";
+	};
 
-			port at 3 {
-				status = "okay";
-				phy-handle = <&slot2_qxgmii3>;
-				phy-mode = "usxgmii";
-				managed = "in-band-status";
-			};
-		};
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot2_qxgmii1>;
+		phy-mode = "usxgmii";
+		managed = "in-band-status";
 	};
 
-	fragment at 4 {
-		target = <&mscc_felix>;
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot2_qxgmii2>;
+		phy-mode = "usxgmii";
+		managed = "in-band-status";
+	};
 
-		__overlay__ {
-			status = "okay";
-		};
+	port at 3 {
+		status = "okay";
+		phy-handle = <&slot2_qxgmii3>;
+		phy-mode = "usxgmii";
+		managed = "in-band-status";
 	};
 };
+
+&mscc_felix {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
index 8ffb707a1576..bd88438c2ecd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-65bb.dts
@@ -11,98 +11,78 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
-
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			slot1_sgmii: ethernet-phy at 2 {
-				/* AQR112 */
-				reg = <0x2>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-		};
-	};
+&mdio_slot1 {
 
-	fragment at 1 {
-		target = <&enetc_port0>;
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-		__overlay__ {
-			phy-handle = <&slot1_sgmii>;
-			phy-mode = "2500base-x";
-			managed = "in-band-status";
-			status = "okay";
-		};
+	slot1_sgmii: ethernet-phy at 2 {
+		/* AQR112 */
+		reg = <0x2>;
+		compatible = "ethernet-phy-ieee802.3-c45";
 	};
+};
 
-	fragment at 2 {
-		target = <&mdio_slot2>;
+&enetc_port0 {
+	phy-handle = <&slot1_sgmii>;
+	phy-mode = "2500base-x";
+	managed = "in-band-status";
+	status = "okay";
+};
 
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
+&mdio_slot2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-			/* 4 ports on VSC8514 */
-			slot2_qsgmii0: ethernet-phy at 8 {
-				reg = <0x8>;
-			};
+	/* 4 ports on VSC8514 */
+	slot2_qsgmii0: ethernet-phy at 8 {
+		reg = <0x8>;
+	};
 
-			slot2_qsgmii1: ethernet-phy at 9 {
-				reg = <0x9>;
-			};
+	slot2_qsgmii1: ethernet-phy at 9 {
+		reg = <0x9>;
+	};
 
-			slot2_qsgmii2: ethernet-phy at a {
-				reg = <0xa>;
-			};
+	slot2_qsgmii2: ethernet-phy at a {
+		reg = <0xa>;
+	};
 
-			slot2_qsgmii3: ethernet-phy at b {
-				reg = <0xb>;
-			};
-		};
+	slot2_qsgmii3: ethernet-phy at b {
+		reg = <0xb>;
 	};
+};
 
-	fragment at 3 {
-		target = <&mscc_felix_ports>;
-
-		__overlay__ {
-			port at 0 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii0>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
-
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii1>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
-
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii2>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
-
-			port at 3 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii3>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
-		};
+&mscc_felix_ports {
+	port at 0 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii0>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
 	};
 
-	fragment at 4 {
-		target = <&mscc_felix>;
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii1>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
+	};
+
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii2>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
+	};
 
-		__overlay__ {
-			status = "okay";
-		};
+	port at 3 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii3>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
 	};
 };
+
+&mscc_felix {
+
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
index eb6a1e674f10..1dff68d7484b 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-7777.dts
@@ -12,71 +12,58 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
+&mdio_slot1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			/* 4 ports on AQR412 */
-			slot1_sxgmii0: ethernet-phy at 0 {
-				reg = <0x0>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-
-			slot1_sxgmii1: ethernet-phy at 1 {
-				reg = <0x1>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-
-			slot1_sxgmii2: ethernet-phy at 2 {
-				reg = <0x2>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
+	/* 4 ports on AQR412 */
+	slot1_sxgmii0: ethernet-phy at 0 {
+		reg = <0x0>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
 
-			slot1_sxgmii3: ethernet-phy at 3 {
-				reg = <0x3>;
-				compatible = "ethernet-phy-ieee802.3-c45";
-			};
-		};
+	slot1_sxgmii1: ethernet-phy at 1 {
+		reg = <0x1>;
+		compatible = "ethernet-phy-ieee802.3-c45";
 	};
 
-	fragment at 1 {
-		target = <&mscc_felix_ports>;
+	slot1_sxgmii2: ethernet-phy at 2 {
+		reg = <0x2>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
 
-		__overlay__ {
-			port at 0 {
-				status = "okay";
-				phy-handle = <&slot1_sxgmii0>;
-				phy-mode = "2500base-x";
-			};
+	slot1_sxgmii3: ethernet-phy at 3 {
+		reg = <0x3>;
+		compatible = "ethernet-phy-ieee802.3-c45";
+	};
+};
 
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot1_sxgmii1>;
-				phy-mode = "2500base-x";
-			};
+&mscc_felix_ports {
+	port at 0 {
+		status = "okay";
+		phy-handle = <&slot1_sxgmii0>;
+		phy-mode = "2500base-x";
+	};
 
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot1_sxgmii2>;
-				phy-mode = "2500base-x";
-			};
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot1_sxgmii1>;
+		phy-mode = "2500base-x";
+	};
 
-			port at 3 {
-				status = "okay";
-				phy-handle = <&slot1_sxgmii3>;
-				phy-mode = "2500base-x";
-			};
-		};
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot1_sxgmii2>;
+		phy-mode = "2500base-x";
 	};
 
-	fragment at 2 {
-		target = <&mscc_felix>;
-		__overlay__ {
-			status = "okay";
-		};
+	port at 3 {
+		status = "okay";
+		phy-handle = <&slot1_sxgmii3>;
+		phy-mode = "2500base-x";
 	};
 };
+
+&mscc_felix {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
index 8e90c3088ba1..19424d349713 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-85bb.dts
@@ -11,97 +11,75 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
+&mdio_slot1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			slot1_sgmii: ethernet-phy at 1c {
-				/* 1st port on VSC8234 */
-				reg = <0x1c>;
-			};
-		};
+	slot1_sgmii: ethernet-phy at 1c {
+		/* 1st port on VSC8234 */
+		reg = <0x1c>;
 	};
+};
 
-	fragment at 1 {
-		target = <&enetc_port0>;
-
-		__overlay__ {
-			phy-handle = <&slot1_sgmii>;
-			phy-mode = "sgmii";
-			managed = "in-band-status";
-			status = "okay";
-		};
-	};
-
-	fragment at 2 {
-		target = <&mdio_slot2>;
-
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
-
-			/* 4 ports on VSC8514 */
-			slot2_qsgmii0: ethernet-phy at 8 {
-				reg = <0x8>;
-			};
-
-			slot2_qsgmii1: ethernet-phy at 9 {
-				reg = <0x9>;
-			};
+&enetc_port0 {
+	phy-handle = <&slot1_sgmii>;
+	phy-mode = "sgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
 
-			slot2_qsgmii2: ethernet-phy at a {
-				reg = <0xa>;
-			};
+&mdio_slot2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-			slot2_qsgmii3: ethernet-phy at b {
-				reg = <0xb>;
-			};
-		};
+	/* 4 ports on VSC8514 */
+	slot2_qsgmii0: ethernet-phy at 8 {
+		reg = <0x8>;
 	};
 
-	fragment at 3 {
-		target = <&mscc_felix_ports>;
+	slot2_qsgmii1: ethernet-phy at 9 {
+		reg = <0x9>;
+	};
 
-		__overlay__ {
-			port at 0 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii0>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
+	slot2_qsgmii2: ethernet-phy at a {
+		reg = <0xa>;
+	};
 
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii1>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
+	slot2_qsgmii3: ethernet-phy at b {
+		reg = <0xb>;
+	};
+};
 
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii2>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
+&mscc_felix_ports {
+	port at 0 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii0>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
+	};
 
-			port at 3 {
-				status = "okay";
-				phy-handle = <&slot2_qsgmii3>;
-				phy-mode = "qsgmii";
-				managed = "in-band-status";
-			};
-		};
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii1>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
 	};
 
-	fragment at 4 {
-		target = <&mscc_felix>;
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii2>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
+	};
 
-		__overlay__ {
-			status = "okay";
-		};
+	port at 3 {
+		status = "okay";
+		phy-handle = <&slot2_qsgmii3>;
+		phy-mode = "qsgmii";
+		managed = "in-band-status";
 	};
 };
+
+&mscc_felix {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
index 5d0a094e6c44..fb85847f778f 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-899b.dts
@@ -11,65 +11,51 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
+&mdio_slot1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-			/* VSC8234 */
-			slot1_sgmii0: ethernet-phy at 1c {
-				reg = <0x1c>;
-			};
-
-			slot1_sgmii1: ethernet-phy at 1d {
-				reg = <0x1d>;
-			};
+	/* VSC8234 */
+	slot1_sgmii0: ethernet-phy at 1c {
+		reg = <0x1c>;
+	};
 
-			slot1_sgmii2: ethernet-phy at 1e {
-				reg = <0x1e>;
-			};
+	slot1_sgmii1: ethernet-phy at 1d {
+		reg = <0x1d>;
+	};
 
-			slot1_sgmii3: ethernet-phy at 1f {
-				reg = <0x1f>;
-			};
-		};
+	slot1_sgmii2: ethernet-phy at 1e {
+		reg = <0x1e>;
 	};
 
-	fragment at 1 {
-		target = <&enetc_port0>;
-		__overlay__ {
-			phy-handle = <&slot1_sgmii0>;
-			phy-mode = "sgmii";
-			managed = "in-band-status";
-			status = "okay";
-		};
+	slot1_sgmii3: ethernet-phy at 1f {
+		reg = <0x1f>;
 	};
+};
 
-	fragment at 2 {
-		target = <&mscc_felix_ports>;
-		__overlay__ {
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii1>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
+&enetc_port0 {
+	phy-handle = <&slot1_sgmii0>;
+	phy-mode = "sgmii";
+	managed = "in-band-status";
+	status = "okay";
+};
 
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii2>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
-		};
+&mscc_felix_ports {
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii1>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
 	};
 
-	fragment at 3 {
-		target = <&mscc_felix>;
-		__overlay__ {
-			status = "okay";
-		};
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii2>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
 	};
 };
+
+&mscc_felix {
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
index 1ef743c48e84..63e46fad22bd 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds-9999.dts
@@ -11,69 +11,58 @@
 /dts-v1/;
 /plugin/;
 
-/ {
-	fragment at 0 {
-		target = <&mdio_slot1>;
-		__overlay__ {
-			#address-cells = <1>;
-			#size-cells = <0>;
+&mdio_slot1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
 
-			/* VSC8234 */
-			slot1_sgmii0: ethernet-phy at 1c {
-				reg = <0x1c>;
-			};
-
-			slot1_sgmii1: ethernet-phy at 1d {
-				reg = <0x1d>;
-			};
+	/* VSC8234 */
+	slot1_sgmii0: ethernet-phy at 1c {
+		reg = <0x1c>;
+	};
 
-			slot1_sgmii2: ethernet-phy at 1e {
-				reg = <0x1e>;
-			};
+	slot1_sgmii1: ethernet-phy at 1d {
+		reg = <0x1d>;
+	};
 
-			slot1_sgmii3: ethernet-phy at 1f {
-				reg = <0x1f>;
-			};
-		};
+	slot1_sgmii2: ethernet-phy at 1e {
+		reg = <0x1e>;
 	};
 
-	fragment at 1 {
-		target = <&mscc_felix_ports>;
-		__overlay__ {
-			port at 0 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii0>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
+	slot1_sgmii3: ethernet-phy at 1f {
+		reg = <0x1f>;
+	};
+};
 
-			port at 1 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii1>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
+&mscc_felix_ports {
+	port at 0 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii0>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
+	};
 
-			port at 2 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii2>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
+	port at 1 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii1>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
+	};
 
-			port at 3 {
-				status = "okay";
-				phy-handle = <&slot1_sgmii3>;
-				phy-mode = "sgmii";
-				managed = "in-band-status";
-			};
-		};
+	port at 2 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii2>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
 	};
 
-	fragment at 2 {
-		target = <&mscc_felix>;
-		__overlay__ {
-			status = "okay";
-		};
+	port at 3 {
+		status = "okay";
+		phy-handle = <&slot1_sgmii3>;
+		phy-mode = "sgmii";
+		managed = "in-band-status";
 	};
 };
+
+&mscc_felix {
+	status = "okay";
+};
-- 
2.17.1



From shawnguo at kernel.org  Fri Jan 28 23:31:50 2022
From: shawnguo at kernel.org (Shawn Guo)
Date: Sat, 29 Jan 2022 15:31:50 +0800
Subject: [GIT PULL] i.MX fixes for 5.17
Message-ID: <20220129073150.GZ4686@dragon>

The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

  Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git tags/imx-fixes-5.17

for you to fetch changes up to 91f6d5f181f6629dd74ab71759fe92d3f4eff966:

  arm64: dts: imx8mq: fix lcdif port node (2022-01-29 14:39:05 +0800)

----------------------------------------------------------------
i.MX fixes for 5.17:

- Fix sound card model for MBa8Mx board.
- Drop i.MX8MQ LCDIF port node unit-address to fix DTC warning.
- Add missing SD card detect line for imx6qdl-udoo board.
- Remove MX23_PAD_SSP1_DETECT from imx23-evk hog group. It fixes the
  broken SD ard support on the board.
- A couple of fixes from Martin Kepplinger to fix the MIPI_CSI port
  number on i.MX8MQ.
- Re-enable ftm_alarm0 device on ls1028a-kontron-sl28 board which was
  disabled accidentally.
- Fix 'assigned-clocks-parents' typo in i.MX7ULP watchdog device node.
- Disable GPU device on imx8mn-venice-gw7902 board, as it uses
  MIMX8MN5CVTI SoC which does not integrate a GPU.

----------------------------------------------------------------
Alexander Stein (2):
      arm64: dts: freescale: Fix sound card model for MBa8Mx
      arm64: dts: imx8mq: fix lcdif port node

Fabio Estevam (2):
      ARM: dts: imx6qdl-udoo: Properly describe the SD card detect
      ARM: dts: imx23-evk: Remove MX23_PAD_SSP1_DETECT from hog group

Martin Kepplinger (2):
      arm64: dts: imx8mq: fix mipi_csi bidirectional port numbers
      arm64: dts: imx8mq-librem5: fix mipi_csi1 port number to sensor

Michael Walle (1):
      arm64: dts: ls1028a: sl28: re-enable ftm_alarm0

Rob Herring (1):
      ARM: dts: imx7ulp: Fix 'assigned-clocks-parents' typo

Tim Harvey (1):
      arm64: dts: imx8mn-venice-gw7902: disable gpu

 arch/arm/boot/dts/imx23-evk.dts                            |  1 -
 arch/arm/boot/dts/imx6qdl-udoo.dtsi                        |  5 ++++-
 arch/arm/boot/dts/imx7ulp.dtsi                             |  2 +-
 arch/arm64/boot/dts/freescale/fsl-ls1028a-kontron-sl28.dts |  4 ++++
 arch/arm64/boot/dts/freescale/imx8mn-venice-gw7902.dts     | 12 ++++++++++++
 arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi          |  4 ++--
 arch/arm64/boot/dts/freescale/imx8mq.dtsi                  | 10 +++++-----
 arch/arm64/boot/dts/freescale/mba8mx.dtsi                  |  2 +-
 8 files changed, 29 insertions(+), 11 deletions(-)


From piotr.oniszczuk at gmail.com  Sat Jan 29 01:23:18 2022
From: piotr.oniszczuk at gmail.com (Piotr Oniszczuk)
Date: Sat, 29 Jan 2022 10:23:18 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <CAMdYzYpkXdXDST+N8dEn7UvibXmytwNeJ+KZ9bn9Oq+RJuSaeQ@mail.gmail.com>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
 <CAMdYzYpkXdXDST+N8dEn7UvibXmytwNeJ+KZ9bn9Oq+RJuSaeQ@mail.gmail.com>
Message-ID: <FBB7C392-C5E0-4E34-AC17-5323414623F5@gmail.com>



> 
> Good Evening,
> 
> While I'm not against this idea, my main concern still stands.
> I spent a great deal of thought on this, and decided to go the route I
> did to maintain consistency with previous generations.
> As such, I see one of three paths here:
> - Pull this patch only and depart rk356x from previous SoCs.
> - Do the same for previous SoCs to maintain consistency.
> - Drop this patch to maintain consistency with previous SoCs.
> 
> I ask that others weigh in here, as offline discussion has produced
> mixed results already.

just pure user perspective

(who spent last weeks considerable time to develop DT for rk3566 tvbox. 99% of my work was by reading/learning from other boards existing DT's. Any inconsistencies in DTs makes work for such ppl like me much more harder):

For option 1 - i don't see value
For option 2 - what is reward for extra work needs to be done on all other SoCs?

so option 3 seems to be natural choice...

in other words:

for me:
option 1 brings practically zero value + increased inconsistency.
option 2: extra work - but consistency is like in option 3 (so where is value?)

so option 3 offers the same consistency - but without extra work...
 
just my 0.02$

 

From michael.riesch at wolfvision.net  Sat Jan 29 01:59:32 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Sat, 29 Jan 2022 10:59:32 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <FBB7C392-C5E0-4E34-AC17-5323414623F5@gmail.com>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
 <CAMdYzYpkXdXDST+N8dEn7UvibXmytwNeJ+KZ9bn9Oq+RJuSaeQ@mail.gmail.com>
 <FBB7C392-C5E0-4E34-AC17-5323414623F5@gmail.com>
Message-ID: <64f539b5-30b2-c0b7-17bf-c448b507713e@wolfvision.net>

Hello Peter and Piotr,

On 1/29/22 10:23, Piotr Oniszczuk wrote:
> 
> 
>>
>> Good Evening,
>>
>> While I'm not against this idea, my main concern still stands.
>> I spent a great deal of thought on this, and decided to go the route I
>> did to maintain consistency with previous generations.
>> As such, I see one of three paths here:
>> - Pull this patch only and depart rk356x from previous SoCs.
>> - Do the same for previous SoCs to maintain consistency.
>> - Drop this patch to maintain consistency with previous SoCs.
>>
>> I ask that others weigh in here, as offline discussion has produced
>> mixed results already.
> 
> just pure user perspective
> 
> (who spent last weeks considerable time to develop DT for rk3566 tvbox. 99% of my work was by reading/learning from other boards existing DT's. Any inconsistencies in DTs makes work for such ppl like me much more harder):
> 
> For option 1 - i don't see value
> For option 2 - what is reward for extra work needs to be done on all other SoCs?
> 
> so option 3 seems to be natural choice...
> 
> in other words:
> 
> for me:
> option 1 brings practically zero value + increased inconsistency.
> option 2: extra work - but consistency is like in option 3 (so where is value?)
> 
> so option 3 offers the same consistency - but without extra work...
>  
> just my 0.02$

Of course this change is purely cosmetic and it is reasonable to ask for
the practical value. It is just that technically the quartz64 dts is not
sorted alphabetically at the moment. The u2phy* nodes should be but
before the uart* nodes to follow the convention. On the other hand, it
may be nice to have the usb2 phys and controllers grouped in the dts.
The proposed renaming would allow all the mentioned nodes sorted
alphabetically and grouped logically.

Therefore I had option 1 in mind. I don't see any dependencies between
the different SoCs and think we can make a fresh start here.

Option 2 is not really feasible, we would almost definitely break
something existent.

Option 3 is feasible, of course. However, I would sort the nodes
alphabetically (u2phy*, then uart*, then usb*). Works for me as well,
although it is not that nice IMHO.

Since many boards with the RK3566 and RK3568 will pop up in near future
we should do the change right now (if we want to do it), as of course
all the board files need to be changed. Therefore I wanted to bring this
matter up now. Let's agree on something and move on.

Best regards,
Michael


From michael at walle.cc  Sat Jan 29 02:12:22 2022
From: michael at walle.cc (Michael Walle)
Date: Sat, 29 Jan 2022 11:12:22 +0100
Subject: [PATCH 2/2] Revert "arm64: dts: ls1028a: add flextimer based pwm
 nodes"
In-Reply-To: <20220129054209.GO4686@dragon>
References: <20220115210907.451189-1-michael@walle.cc>
 <20220115210907.451189-2-michael@walle.cc> <20220129054209.GO4686@dragon>
Message-ID: <3d1328729d93daa2e6a50a4d03ec5ef0@walle.cc>

Am 2022-01-29 06:42, schrieb Shawn Guo:
> On Sat, Jan 15, 2022 at 10:09:07PM +0100, Michael Walle wrote:
>> The changes to the device tree look very wrong. There are now two
>> devices with the same base address: pwm0 and ftm_alarm0. Both are 
>> using
>> the Flex Timer Module. It seems like this should either be one driver 
>> or
>> and MFD driver. Either way, there should only be one node in the 
>> device
>> tree. Revert the offending changes to avoid getting a broken device 
>> tree
>> in circulation.
> 
> Why not just fix the conflicting nodes?

And how would you fix it? There are two conflicting drivers. Like
I said, maybe it should be an MFD driver, see for example
Documentation/devicetree/bindings/mfd/atmel-flexcom.txt, which also
have a common block which you can switch between different modes. But
that would mean a lot of work which I don't think will happen until
the next merge window, let alone that this is not a bugfix.

Therefore, the only sensible thing is to revert the latest changes,
so that you don't have a broken device tree released with 5.17 and
work on a proper support for the next release.

And TBH, I'd expect that NXP will fix this.

-michael


From u.kleine-koenig at pengutronix.de  Sat Jan 29 02:19:41 2022
From: u.kleine-koenig at pengutronix.de (Uwe =?utf-8?Q?Kleine-K=C3=B6nig?=)
Date: Sat, 29 Jan 2022 11:19:41 +0100
Subject: [PATCH 2/2] drm/imx/lcdc: Implement DRM driver for imx21
In-Reply-To: <202201290646.48sNgWm1-lkp@intel.com>
References: <20220128105849.368438-3-u.kleine-koenig@pengutronix.de>
 <202201290646.48sNgWm1-lkp@intel.com>
Message-ID: <20220129101941.aqzgnt2q2e7bl34v@pengutronix.de>

On Sat, Jan 29, 2022 at 06:25:53AM +0800, kernel test robot wrote:
> Hi "Uwe,
> 
> Thank you for the patch! Yet something to improve:
> 
> [auto build test ERROR on shawnguo/for-next]
> [also build test ERROR on robh/for-next pza/reset/next v5.17-rc1 next-20220128]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:    https://github.com/0day-ci/linux/commits/Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git for-next
> config: arc-randconfig-r012-20220128 (https://download.01.org/0day-ci/archive/20220129/202201290646.48sNgWm1-lkp at intel.com/config)
> compiler: arc-elf-gcc (GCC) 11.2.0
> reproduce (this is a W=1 build):
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # https://github.com/0day-ci/linux/commit/cba99931972f752a7b3105a3697b0cda88fe54d4
>         git remote add linux-review https://github.com/0day-ci/linux
>         git fetch --no-tags linux-review Uwe-Kleine-K-nig/drm-imx-lcdc-drm-driver-for-imx21-25-27/20220128-190002
>         git checkout cba99931972f752a7b3105a3697b0cda88fe54d4
>         # save the config file to linux build tree
>         mkdir build_dir
>         COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arc distclean
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot <lkp at intel.com>
> 
> All errors (new ones prefixed by >>):
> 
> >> scripts/Makefile.clean:15: drivers/gpu/drm/imx/imx21-lcdc/Makefile: No such file or directory
> >> make[6]: *** No rule to make target 'drivers/gpu/drm/imx/imx21-lcdc/Makefile'.

Argh, yes, I forgot to commit that one. I'll add it in the next round,
but wait a bit for more feedback (mainly by Rob). The Makefile just
contains:

	obj-$(CONFIG_DRM_IMX21_LCDC) += imx21-lcdc.o

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220129/2ae3cb18/attachment.sig>

From krzysztof.kozlowski at canonical.com  Sat Jan 29 03:29:22 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 12:29:22 +0100
Subject: (subset) [PATCH v3 3/3] arm64: dts: fsd: Add SPI device nodes
In-Reply-To: <20220125031604.76009-4-alim.akhtar@samsung.com>
References: <20220125031604.76009-1-alim.akhtar@samsung.com>
 <CGME20220125032828epcas5p22fbacf42ebfb1b78c1f74f48d37aa381@epcas5p2.samsung.com>
 <20220125031604.76009-4-alim.akhtar@samsung.com>
Message-ID: <164345575829.11115.173136141798893555.b4-ty@canonical.com>

On Tue, 25 Jan 2022 08:46:04 +0530, Alim Akhtar wrote:
> From: Aswani Reddy <aswani.reddy at samsung.com>
> 
> Adds device tree node for SPI IPs
> 
> 

Applied, thanks!

[3/3] arm64: dts: fsd: Add SPI device nodes
      commit: bd1e3696a052b9b2bd3c1c72ef4bf800a3a1e286

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Sat Jan 29 03:53:52 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 12:53:52 +0100
Subject: [GIT PULL] ARM: dts/drivers: samsung pinctrl for v5.18
Message-ID: <20220129115352.13274-1-krzysztof.kozlowski@canonical.com>

Hi Arnd and Olof,

There is quite a lot of changes in Samsung these days, so I am sending this one
very early. It's also a controversial one because it combines pinctrl
driver+dts into one. I mentioned it before in [1].

The pinctrl driver changes have to go before DTS. The DTS has to go with
dtschema, so the dtschema checks won't complain with warnings.

The pinctrl driver changes are coming from my Samsung pinctrl repository and I
will send them later also to Linus Walleij.

Linus,
I will send the pinctrl driver bits in separate pull to you.

[1] https://lore.kernel.org/all/CAOesGMg2eH1B94h+etPBDW3B1LMeHBytz0v2e0GfVRDv8gU0YA at mail.gmail.com/

Best regards,
Krzysztof


The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

  Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-dt-pinctrl-5.18

for you to fetch changes up to 41bd4354a1513afa4a9dd9940d8cd790fbd00e68:

  arm64: dts: exynos: use dedicated wake-up pinctrl compatible in ExynosAutov9 (2022-01-23 17:54:59 +0100)

----------------------------------------------------------------
Samsung pinctrl DTS and driver changes for v5.18

Conversion of Samsung pinctrl bindings to dtschema followed up with
alignment of DTS files to the dtschema.

The entire work consists of three parts but everything should be merged
at once to avoid dtschema check errors:
1. Samsung pinctrl driver change necessary to accept new DTS (driver
   depends on node names and this has to be adjusted because of dtschema).
2. Conversion to dtschema which brings requirement of different naming
   of the GPIO nodes.
3. DTS commits depending on driver (1) above, which convert all GPIO pin
   bank names to new naming, required by dtschema.
   This also includes few cleanups around DTS which are here to avoid
   any merge conflicts.

The Samsung pinctrl driver changes are backwards compatible.  However
the DTS changes (renaming nodes) could cause problems in out-of-tree or
other project implementations of the driver.

----------------------------------------------------------------
Krzysztof Kozlowski (28):
      pinctrl: samsung: drop pin banks references on error paths
      pinctrl: samsung: accept GPIO bank nodes with a suffix
      dt-bindings: pinctrl: samsung: convert to dtschema
      dt-bindings: pinctrl: samsung: describe Exynos850 and ExynosAutov9 wake-ups
      pinctrl: samsung: add support for Exynos850 and ExynosAutov9 wake-ups
      Merge tag 'samsung-pinctrl-5.18' of https://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/samsung into for-v5.18/dt-pinctrl
      ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
      ARM: dts: exynos: drop unused pinctrl defines in Exynos3250
      ARM: dts: exynos: simplify PMIC DVS pin configuration in Odroid XU
      ARM: dts: exynos: override pins by label in Peach Pit
      ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pit
      ARM: dts: exynos: override pins by label in Peach Pi
      ARM: dts: exynos: simplify PMIC DVS pin configuration in Peach Pi
      ARM: dts: s3c64xx: drop unneeded pinctrl wake-up interrupt mapping
      ARM: dts: exynos: align pinctrl with dtschema in Exynos3250
      ARM: dts: exynos: align pinctrl with dtschema in Exynos4210
      ARM: dts: exynos: align pinctrl with dtschema in Exynos4412
      ARM: dts: exynos: align pinctrl with dtschema in Exynos5250
      ARM: dts: exynos: align pinctrl with dtschema in Exynos5260
      ARM: dts: exynos: align pinctrl with dtschema in Exynos5410
      ARM: dts: exynos: align pinctrl with dtschema in Exynos542x/5800
      arm64: dts: exynos: align pinctrl with dtschema in Exynos5433
      arm64: dts: exynos: align pinctrl with dtschema in Exynos7
      arm64: dts: exynos: align pinctrl with dtschema in ExynosAutov9
      ARM: dts: s3c24xx: align pinctrl with dtschema
      ARM: dts: s3c64xx: align pinctrl with dtschema
      ARM: dts: s5pv210: align pinctrl with dtschema
      arm64: dts: exynos: use dedicated wake-up pinctrl compatible in ExynosAutov9

Sam Protsenko (1):
      pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and CMGP gpios

 .../pinctrl/samsung,pinctrl-gpio-bank.yaml         |  52 +++
 .../bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml |  81 +++++
 .../pinctrl/samsung,pinctrl-wakeup-interrupt.yaml  | 106 ++++++
 .../bindings/pinctrl/samsung,pinctrl.yaml          | 392 +++++++++++++++++++++
 .../bindings/pinctrl/samsung-pinctrl.txt           | 383 --------------------
 MAINTAINERS                                        |   2 +-
 arch/arm/boot/dts/exynos3250-artik5.dtsi           |  10 +-
 arch/arm/boot/dts/exynos3250-pinctrl.dtsi          | 165 ++++-----
 arch/arm/boot/dts/exynos4210-i9100.dts             |  30 +-
 arch/arm/boot/dts/exynos4210-origen.dts            |   2 +-
 arch/arm/boot/dts/exynos4210-pinctrl.dtsi          | 226 ++++++------
 arch/arm/boot/dts/exynos4210-smdkv310.dts          |   4 +-
 arch/arm/boot/dts/exynos4210-trats.dts             |   6 +-
 arch/arm/boot/dts/exynos4210-universal_c210.dts    |  12 +-
 arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi        |   4 +-
 arch/arm/boot/dts/exynos4412-itop-elite.dts        |   2 +-
 arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi    |   2 +-
 arch/arm/boot/dts/exynos4412-midas.dtsi            |  30 +-
 arch/arm/boot/dts/exynos4412-odroid-common.dtsi    |   8 +-
 arch/arm/boot/dts/exynos4412-odroidx.dts           |   2 +-
 arch/arm/boot/dts/exynos4412-origen.dts            |   4 +-
 arch/arm/boot/dts/exynos4412-p4note.dtsi           |  44 +--
 arch/arm/boot/dts/exynos4412-pinctrl.dtsi          | 252 ++++++-------
 arch/arm/boot/dts/exynos4412-smdk4412.dts          |   4 +-
 arch/arm/boot/dts/exynos5250-arndale.dts           |   2 +-
 arch/arm/boot/dts/exynos5250-pinctrl.dtsi          | 222 ++++++------
 arch/arm/boot/dts/exynos5250-smdk5250.dts          |   2 +-
 arch/arm/boot/dts/exynos5250-snow-common.dtsi      |  22 +-
 arch/arm/boot/dts/exynos5250-snow-rev5.dts         |   2 +-
 arch/arm/boot/dts/exynos5250-snow.dts              |   2 +-
 arch/arm/boot/dts/exynos5250-spring.dts            |  20 +-
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi          | 148 ++++----
 arch/arm/boot/dts/exynos5260-xyref5260.dts         |   2 +-
 arch/arm/boot/dts/exynos5410-odroidxu.dts          |  22 +-
 arch/arm/boot/dts/exynos5410-pinctrl.dtsi          | 170 ++++-----
 arch/arm/boot/dts/exynos5410-smdk5410.dts          |   4 +-
 arch/arm/boot/dts/exynos5420-arndale-octa.dts      |   2 +-
 arch/arm/boot/dts/exynos5420-peach-pit.dts         |  89 +++--
 arch/arm/boot/dts/exynos5420-pinctrl.dtsi          | 194 +++++-----
 arch/arm/boot/dts/exynos5420-smdk5420.dts          |   6 +-
 arch/arm/boot/dts/exynos5422-odroid-core.dtsi      |   2 +-
 arch/arm/boot/dts/exynos5422-odroidxu3-common.dtsi |   6 +-
 arch/arm/boot/dts/exynos5800-peach-pi.dts          |  89 +++--
 arch/arm/boot/dts/s3c2416-pinctrl.dtsi             |  60 ++--
 arch/arm/boot/dts/s3c6410-mini6410.dts             |   4 +-
 arch/arm/boot/dts/s3c64xx-pinctrl.dtsi             | 210 +++++------
 arch/arm/boot/dts/s3c64xx.dtsi                     |  16 +-
 arch/arm/boot/dts/s5pv210-aquila.dts               |   2 +-
 arch/arm/boot/dts/s5pv210-aries.dtsi               |  40 +--
 arch/arm/boot/dts/s5pv210-fascinate4g.dts          |  12 +-
 arch/arm/boot/dts/s5pv210-galaxys.dts              |  16 +-
 arch/arm/boot/dts/s5pv210-pinctrl.dtsi             | 226 ++++++------
 arch/arm64/boot/dts/exynos/exynos5433-pinctrl.dtsi | 211 +++++------
 .../boot/dts/exynos/exynos5433-tm2-common.dtsi     | 259 +++++++-------
 arch/arm64/boot/dts/exynos/exynos7-espresso.dts    |   6 +-
 arch/arm64/boot/dts/exynos/exynos7-pinctrl.dtsi    | 176 ++++-----
 .../boot/dts/exynos/exynosautov9-pinctrl.dtsi      |  50 +--
 arch/arm64/boot/dts/exynos/exynosautov9.dtsi       |   2 +-
 drivers/pinctrl/samsung/pinctrl-exynos-arm64.c     |   2 -
 drivers/pinctrl/samsung/pinctrl-exynos.c           |   4 +
 drivers/pinctrl/samsung/pinctrl-samsung.c          |  87 ++++-
 61 files changed, 2234 insertions(+), 1978 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-gpio-bank.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-pins-cfg.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
 create mode 100644 Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
 delete mode 100644 Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt


From krzysztof.kozlowski at canonical.com  Sat Jan 29 03:54:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 12:54:42 +0100
Subject: [GIT PULL] Samsung fixes for v5.17
Message-ID: <20220129115442.13474-1-krzysztof.kozlowski@canonical.com>

The following changes since commit e783362eb54cd99b2cac8b3a9aeac942e6f6ac07:

  Linux 5.17-rc1 (2022-01-23 10:12:53 +0200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux.git tags/samsung-fixes-5.17

for you to fetch changes up to 442b0c08db7e35980bed6af091877f4dda72ffca:

  soc: samsung: Fix typo in CONFIG_EXYNOS_USI description (2022-01-23 18:05:41 +0100)

----------------------------------------------------------------
Samsung fixes for v5.17

1. Typo in CONFIG_EXYNOS_USI description.
2. Add Alim Akhtar as a reviewer for Samsung Exynos platform.

----------------------------------------------------------------
Alim Akhtar (1):
      MAINTAINERS: add reviewer entry for Samsung/Exynos platform

Sam Protsenko (1):
      soc: samsung: Fix typo in CONFIG_EXYNOS_USI description

 MAINTAINERS                 | 3 +++
 drivers/soc/samsung/Kconfig | 2 +-
 2 files changed, 4 insertions(+), 1 deletion(-)


From guoren at kernel.org  Sat Jan 29 04:17:11 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:11 +0800
Subject: [PATCH V4 00/17] riscv: compat: Add COMPAT mode support for rv64
Message-ID: <20220129121728.1079364-1-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Currently, most 64-bit architectures (x86, parisc, powerpc, arm64,
s390, mips, sparc) have supported COMPAT mode. But they all have
history issues and can't use standard linux unistd.h. RISC-V would
be first standard __SYSCALL_COMPAT user of include/uapi/asm-generic
/unistd.h.

The patchset are based on v5.17-rc1, you can compare rv64-compat32
v.s. rv32-whole in qemu with following step:

 - Prepare rv32 rootfs & fw_jump.bin by buildroot.org
   $ git clone git://git.busybox.net/buildroot
   $ cd buildroot
   $ make qemu_riscv32_virt_defconfig O=qemu_riscv32_virt_defconfig
   $ make -C qemu_riscv32_virt_defconfig
   $ make qemu_riscv64_virt_defconfig O=qemu_riscv64_virt_defconfig
   $ make -C qemu_riscv64_virt_defconfig
   (Got fw_jump.bin & rootfs.ext2 in qemu_riscvXX_virt_defconfig/images)

 - Prepare Linux rv32 & rv64 Image
   $ git clone git at github.com:c-sky/csky-linux.git -b riscv_compat_v4 linux
   $ cd linux
   $ echo "CONFIG_STRICT_KERNEL_RWX=n" >> arch/riscv/configs/defconfig
   $ echo "CONFIG_STRICT_MODULE_RWX=n" >> arch/riscv/configs/defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ rv32_defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ Image
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ defconfig
   $ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ Image

 - Prepare Qemu: (made by LIU Zhiwei <zhiwei_liu at c-sky.com>)
   $ git clone git at github.com:alistair23/qemu.git -b riscv-to-apply.for-upstream linux
   $ cd qemu
   $ ./configure --target-list="riscv64-softmmu riscv32-softmmu"
   $ make

 - Run rv64 with rv32 rootfs in compat mode:
   $ ./build/qemu-system-riscv64 -cpu rv64,x-h=true -M virt -m 64m -nographic -bios qemu_riscv64_virt_defconfig/images/fw_jump.bin -kernel build-rv64/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv64-unknown-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.37) #96 SMP Tue Dec 28 21:01:55 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   DMA32    [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000]   Normal   empty
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 17 pages/cpu s30696 r8192 d30744 u69632
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15655
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0xffffffcefee00000 - 0xffffffceff000000   (2048 kB)
[    0.000000]       pci io : 0xffffffceff000000 - 0xffffffcf00000000   (  16 MB)
[    0.000000]      vmemmap : 0xffffffcf00000000 - 0xffffffcfffffffff   (4095 MB)
[    0.000000]      vmalloc : 0xffffffd000000000 - 0xffffffdfffffffff   (65535 MB)
[    0.000000]       lowmem : 0xffffffe000000000 - 0xffffffe003e00000   (  62 MB)
[    0.000000]       kernel : 0xffffffff80000000 - 0xffffffffffffffff   (2047 MB)
[    0.000000] Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 64 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv64imafdcsuh
mmu             : sv48

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
# ca[   78.386630] random: fast init done
# cat /proc/meminfo
MemTotal:          53076 kB
MemFree:           40264 kB
MemAvailable:      40244 kB
Buffers:             236 kB
Cached:             1560 kB
SwapCached:            0 kB
Active:             1700 kB
Inactive:            516 kB
Active(anon):         40 kB
Inactive(anon):      424 kB
Active(file):       1660 kB
Inactive(file):       92 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:           444 kB
Mapped:             1188 kB
Shmem:                44 kB
KReclaimable:        952 kB
Slab:               5744 kB
SReclaimable:        952 kB
SUnreclaim:         4792 kB
KernelStack:         624 kB
PageTables:          156 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26536 kB
Committed_AS:       1748 kB
VmallocTotal:   67108863 kB
VmallocUsed:         652 kB
VmallocChunk:          0 kB
Percpu:               80 kB
#

 - Run rv32 with rv32 rootfs:
   $ ./build/qemu-system-riscv32 -cpu rv32,x-h=true -M virt -m 64m -nographic -bios qemu_riscv32_virt_defconfig/images/fw_jump.bin -kernel build-rv32/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0

QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[    0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren at guoren-Z87-HD3) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11-201-g7600ca7960-dirty) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #7 SMP Tue Dec 28 21:02:21 CST 2021
[    0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80400000
[    0.000000] Machine model: riscv-virtio,qemu
[    0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[    0.000000] printk: bootconsole [sbi0] enabled
[    0.000000] efi: UEFI not found.
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000080400000-0x0000000083ffffff]
[    0.000000] SBI specification v0.2 detected
[    0.000000] SBI implementation ID=0x1 Version=0x9
[    0.000000] SBI TIME extension detected
[    0.000000] SBI IPI extension detected
[    0.000000] SBI RFENCE extension detected
[    0.000000] SBI v0.2 HSM extension detected
[    0.000000] riscv: ISA extensions acdfhimsu
[    0.000000] riscv: ELF capabilities acdfim
[    0.000000] percpu: Embedded 12 pages/cpu s16600 r8192 d24360 u49152
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 15240
[    0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[    0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[    0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[    0.000000] Virtual kernel memory layout:
[    0.000000]       fixmap : 0x9dc00000 - 0x9e000000   (4096 kB)
[    0.000000]       pci io : 0x9e000000 - 0x9f000000   (  16 MB)
[    0.000000]      vmemmap : 0x9f000000 - 0x9fffffff   (  15 MB)
[    0.000000]      vmalloc : 0xa0000000 - 0xbfffffff   ( 511 MB)
[    0.000000]       lowmem : 0xc0000000 - 0xc3c00000   (  60 MB)
[    0.000000] Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss, 9516K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] rcu: Hierarchical RCU implementation.
[    0.000000] rcu:     RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[    0.000000] rcu:     RCU debug extended QS entry/exit.
[    0.000000]  Tracing variant of Tasks RCU enabled.
[    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[    0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[    0.000000] riscv-intc: 32 local interrupts mapped
[    0.000000] plic: plic at c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv32imafdcsuh
mmu             : sv32

# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
[   79.320589] random: fast init done
# cat /proc/meminfo
MemTotal:          52176 kB
MemFree:           41012 kB
MemAvailable:      42176 kB
Buffers:             644 kB
Cached:             2724 kB
SwapCached:            0 kB
Active:             3128 kB
Inactive:            752 kB
Active(anon):         40 kB
Inactive(anon):      516 kB
Active(file):       3088 kB
Inactive(file):      236 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 4 kB
Writeback:             0 kB
AnonPages:           556 kB
Mapped:             2172 kB
Shmem:                44 kB
KReclaimable:        656 kB
Slab:               3684 kB
SReclaimable:        656 kB
SUnreclaim:         3028 kB
KernelStack:         312 kB
PageTables:           88 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:       26088 kB
Committed_AS:       2088 kB
VmallocTotal:     524287 kB
VmallocUsed:          12 kB
VmallocChunk:          0 kB
Percpu:               60 kB
#

 Some conclusions:
 - kernel statics:
   64: Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved)
   32: Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss,  9516K reserved)
   rv32 better than rv64:                  1%               22%           17%          13%        19%         11%
   The code size is very similar, but data size rv32 would be better.

 - rv32 kernel runtime KernelStack, Slab... are smaller,
   rv64: MemTotal: 53076 kB,        MemFree: 40264 kB
   rv32: MemTotal: 52176 + 2048 kB, MemFree: 41012  + 2048 kB
   rv32 better than rv64:       2%                         6%

   (Because opensbi problem, we could add another 2MB for rv32.)
   Overall, rv64-compat is 6% worse than rv32-full at memory footprint.
   If the user space memory usage increases, the gap will be further
   reduced.

 - Qemu, kernel, rv32 = rv64 defconfig, rootfs, opensbi
   are the same in this comparison.

Changes in v4:
 - Rebase on linux-5.17-rc1
 - Optimize compat_sys_call_table implementation with Arnd's advice
 - Add reviewed-by for Arnd. Thx :)
 - Remove FIXME comment in elf.h
 - Optimize Cleanup duplicate definitions in compat.h with Arnd's advice

Changes in v3:
 - Rebase on newest master (pre linux-5.17-rc1)
 - Using newest qemu version v7 for test
 - Remove fcntl common modification
 - Fixup SET_PERSONALITY in elf.h by Arnd
 - Fixup KVM Kconfig
 - Update Acked-by & Reviewed-by

Changes in v2:
 - Add __ARCH_WANT_COMPAT_STAT suggested
 - Cleanup fcntl compatduplicate definitions
 - Cleanup compat.h
 - Move rv32_defconfig into Makefile
 - Fixup rv64 rootfs boot failed, remove hw_compat_mode_detect
 - Move SYSVIPC_COMPAT into init/Kconfig
 - Simplify compat_elf_check

Guo Ren (17):
  kconfig: Add SYSVIPC_COMPAT for all architectures
  fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
  asm-generic: compat: Cleanup duplicate definitions
  syscalls: compat: Fix the missing part for __SYSCALL_COMPAT
  riscv: Fixup difference with defconfig
  riscv: compat: Add basic compat date type implementation
  riscv: compat: Re-implement TASK_SIZE for COMPAT_32BIT
  riscv: compat: syscall: Add compat_sys_call_table implementation
  riscv: compat: syscall: Add entry.S implementation
  riscv: compat: Add elf.h implementation
  riscv: compat: vdso: Add rv32 VDSO base code implementation
  riscv: compat: vdso: Add setup additional pages implementation
  riscv: compat: signal: Add rt_frame implementation
  riscv: compat: ptrace: Add compat_arch_ptrace implement
  riscv: compat: Add UXL_32 support in start_thread
  riscv: compat: Add COMPAT Kbuild skeletal support
  KVM: compat: riscv: Prevent KVM_COMPAT from being selected


Guo Ren (17):
  kconfig: Add SYSVIPC_COMPAT for all architectures
  fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
  asm-generic: compat: Cleanup duplicate definitions
  syscalls: compat: Fix the missing part for __SYSCALL_COMPAT
  riscv: Fixup difference with defconfig
  riscv: compat: Add basic compat date type implementation
  riscv: compat: Re-implement TASK_SIZE for COMPAT_32BIT
  riscv: compat: syscall: Add compat_sys_call_table implementation
  riscv: compat: syscall: Add entry.S implementation
  riscv: compat: process: Add UXL_32 support in start_thread
  riscv: compat: Add elf.h implementation
  riscv: compat: vdso: Add rv32 VDSO base code implementation
  riscv: compat: vdso: Add setup additional pages implementation
  riscv: compat: signal: Add rt_frame implementation
  riscv: compat: ptrace: Add compat_arch_ptrace implement
  riscv: compat: Add COMPAT Kbuild skeletal support
  KVM: compat: riscv: Prevent KVM_COMPAT from being selected

 arch/arm64/Kconfig                            |   4 -
 arch/arm64/include/asm/compat.h               | 106 +-------
 arch/arm64/include/asm/unistd.h               |   1 +
 arch/mips/Kconfig                             |   5 -
 arch/mips/include/asm/compat.h                |  27 +-
 arch/mips/include/asm/unistd.h                |   2 +
 arch/parisc/Kconfig                           |   4 -
 arch/parisc/include/asm/compat.h              |  45 +---
 arch/parisc/include/asm/unistd.h              |   1 +
 arch/powerpc/Kconfig                          |   5 -
 arch/powerpc/include/asm/compat.h             |  46 +---
 arch/powerpc/include/asm/unistd.h             |   1 +
 arch/riscv/Kconfig                            |  19 ++
 arch/riscv/Makefile                           |   9 +
 arch/riscv/configs/rv32_defconfig             | 135 ----------
 arch/riscv/include/asm/compat.h               | 135 ++++++++++
 arch/riscv/include/asm/csr.h                  |   7 +
 arch/riscv/include/asm/elf.h                  |  53 +++-
 arch/riscv/include/asm/mmu.h                  |   1 +
 arch/riscv/include/asm/pgtable.h              |  13 +-
 arch/riscv/include/asm/syscall.h              |   1 +
 arch/riscv/include/asm/thread_info.h          |   1 +
 arch/riscv/include/asm/unistd.h               |  11 +
 arch/riscv/include/asm/vdso.h                 |   9 +
 arch/riscv/include/uapi/asm/unistd.h          |   2 +-
 arch/riscv/kernel/Makefile                    |   3 +
 arch/riscv/kernel/compat_signal.c             | 243 ++++++++++++++++++
 arch/riscv/kernel/compat_syscall_table.c      |  19 ++
 arch/riscv/kernel/compat_vdso/.gitignore      |   2 +
 arch/riscv/kernel/compat_vdso/Makefile        |  68 +++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |   8 +
 .../kernel/compat_vdso/compat_vdso.lds.S      |   3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |   3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |   5 +
 arch/riscv/kernel/compat_vdso/getcpu.S        |   3 +
 arch/riscv/kernel/compat_vdso/note.S          |   3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |   3 +
 arch/riscv/kernel/entry.S                     |  18 +-
 arch/riscv/kernel/process.c                   |   5 +
 arch/riscv/kernel/ptrace.c                    |  87 ++++++-
 arch/riscv/kernel/signal.c                    |  13 +-
 arch/riscv/kernel/sys_riscv.c                 |   6 +-
 arch/riscv/kernel/vdso.c                      | 104 +++++---
 arch/riscv/kernel/vdso/vdso.S                 |   6 +-
 arch/s390/Kconfig                             |   3 -
 arch/s390/include/asm/compat.h                |  95 +------
 arch/s390/include/asm/unistd.h                |   1 +
 arch/sparc/Kconfig                            |   5 -
 arch/sparc/include/asm/compat.h               |  42 ++-
 arch/sparc/include/asm/unistd.h               |   1 +
 arch/x86/Kconfig                              |   4 -
 arch/x86/include/asm/compat.h                 |  89 +------
 arch/x86/include/asm/unistd.h                 |   1 +
 fs/open.c                                     |  24 ++
 fs/read_write.c                               |  16 ++
 fs/stat.c                                     |   2 +-
 fs/sync.c                                     |   9 +
 include/asm-generic/compat.h                  | 133 ++++++++++
 include/linux/compat.h                        |  37 +++
 include/uapi/asm-generic/unistd.h             |   4 +-
 init/Kconfig                                  |   4 +
 mm/fadvise.c                                  |  11 +
 mm/readahead.c                                |   7 +
 tools/include/uapi/asm-generic/unistd.h       |   4 +-
 virt/kvm/Kconfig                              |   2 +-
 65 files changed, 1141 insertions(+), 598 deletions(-)
 delete mode 100644 arch/riscv/configs/rv32_defconfig
 create mode 100644 arch/riscv/include/asm/compat.h
 create mode 100644 arch/riscv/kernel/compat_signal.c
 create mode 100644 arch/riscv/kernel/compat_syscall_table.c
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:12 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:12 +0800
Subject: [PATCH V4 01/17] kconfig: Add SYSVIPC_COMPAT for all architectures
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-2-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

The existing per-arch definitions are pretty much historic cruft.
Move SYSVIPC_COMPAT into init/Kconfig.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Acked-by: Arnd Bergmann <arnd at arndb.de>
Cc: Christoph Hellwig <hch at infradead.org>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/arm64/Kconfig   | 4 ----
 arch/mips/Kconfig    | 5 -----
 arch/parisc/Kconfig  | 4 ----
 arch/powerpc/Kconfig | 5 -----
 arch/s390/Kconfig    | 3 ---
 arch/sparc/Kconfig   | 5 -----
 arch/x86/Kconfig     | 4 ----
 init/Kconfig         | 4 ++++
 8 files changed, 4 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 6978140edfa4..ad1beb70dc36 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2022,10 +2022,6 @@ config DMI
 
 endmenu
 
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on COMPAT && SYSVIPC
-
 menu "Power management options"
 
 source "kernel/power/Kconfig"
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 058446f01487..91a17ad380c9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -3170,16 +3170,12 @@ config MIPS32_COMPAT
 config COMPAT
 	bool
 
-config SYSVIPC_COMPAT
-	bool
-
 config MIPS32_O32
 	bool "Kernel support for o32 binaries"
 	depends on 64BIT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT
 	select MIPS32_COMPAT
-	select SYSVIPC_COMPAT if SYSVIPC
 	help
 	  Select this option if you want to run o32 binaries.  These are pure
 	  32-bit binaries as used by the 32-bit Linux/MIPS port.  Most of
@@ -3193,7 +3189,6 @@ config MIPS32_N32
 	select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
 	select COMPAT
 	select MIPS32_COMPAT
-	select SYSVIPC_COMPAT if SYSVIPC
 	help
 	  Select this option if you want to run n32 binaries.  These are
 	  64-bit binaries using 32-bit quantities for addressing and certain
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 43c1c880def6..bc56759d44a2 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -345,10 +345,6 @@ config COMPAT
 	def_bool y
 	depends on 64BIT
 
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on COMPAT && SYSVIPC
-
 config AUDIT_ARCH
 	def_bool y
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b779603978e1..5a32b7f21af2 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -291,11 +291,6 @@ config COMPAT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
 
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
 config SCHED_OMIT_FRAME_POINTER
 	bool
 	default y
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 9750f92380f5..e41265c938ec 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -459,9 +459,6 @@ config COMPAT
 	  (and some other stuff like libraries and such) is needed for
 	  executing 31 bit applications.  It is safe to say "Y".
 
-config SYSVIPC_COMPAT
-	def_bool y if COMPAT && SYSVIPC
-
 config SMP
 	def_bool y
 
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 1cab1b284f1a..15d5725bd623 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -488,9 +488,4 @@ config COMPAT
 	select ARCH_WANT_OLD_COMPAT_IPC
 	select COMPAT_OLD_SIGACTION
 
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
 source "drivers/sbus/char/Kconfig"
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ebe8fc76949a..9609f191719d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2859,10 +2859,6 @@ config COMPAT
 if COMPAT
 config COMPAT_FOR_U64_ALIGNMENT
 	def_bool y
-
-config SYSVIPC_COMPAT
-	def_bool y
-	depends on SYSVIPC
 endif
 
 endmenu
diff --git a/init/Kconfig b/init/Kconfig
index e9119bf54b1f..589ccec56571 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -386,6 +386,10 @@ config SYSVIPC_SYSCTL
 	depends on SYSCTL
 	default y
 
+config SYSVIPC_COMPAT
+	def_bool y
+	depends on COMPAT && SYSVIPC
+
 config POSIX_MQUEUE
 	bool "POSIX Message Queues"
 	depends on NET
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:13 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:13 +0800
Subject: [PATCH V4 02/17] fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-3-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

RISC-V doesn't neeed compat_stat, so using __ARCH_WANT_COMPAT_STAT
to exclude unnecessary SYSCALL functions.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/arm64/include/asm/unistd.h   | 1 +
 arch/mips/include/asm/unistd.h    | 2 ++
 arch/parisc/include/asm/unistd.h  | 1 +
 arch/powerpc/include/asm/unistd.h | 1 +
 arch/s390/include/asm/unistd.h    | 1 +
 arch/sparc/include/asm/unistd.h   | 1 +
 arch/x86/include/asm/unistd.h     | 1 +
 fs/stat.c                         | 2 +-
 8 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 4e65da3445c7..037feba03a51 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h
@@ -3,6 +3,7 @@
  * Copyright (C) 2012 ARM Ltd.
  */
 #ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_STAT
 #define __ARCH_WANT_COMPAT_STAT64
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_PAUSE
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index c2196b1b6604..25a5253db7f4 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -50,6 +50,8 @@
 # ifdef CONFIG_32BIT
 #  define __ARCH_WANT_STAT64
 #  define __ARCH_WANT_SYS_TIME32
+# else
+#  define __ARCH_WANT_COMPAT_STAT
 # endif
 # ifdef CONFIG_MIPS32_O32
 #  define __ARCH_WANT_SYS_TIME32
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..14e0668184cb 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -168,6 +168,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_CLONE3
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
+#define __ARCH_WANT_COMPAT_STAT
 
 #ifdef CONFIG_64BIT
 #define __ARCH_WANT_SYS_TIME
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 5eb462af6766..b1129b4ef57d 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -44,6 +44,7 @@
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_SYS_NEWFSTATAT
+#define __ARCH_WANT_COMPAT_STAT
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
 #endif
 #define __ARCH_WANT_SYS_FORK
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 9e9f75ef046a..4260bc5ce7f8 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -28,6 +28,7 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 # ifdef CONFIG_COMPAT
+#   define __ARCH_WANT_COMPAT_STAT
 #   define __ARCH_WANT_SYS_TIME32
 #   define __ARCH_WANT_SYS_UTIME32
 # endif
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 1e66278ba4a5..d6bc76706a7a 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -46,6 +46,7 @@
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
 #define __ARCH_WANT_COMPAT_SYS_SENDFILE
+#define __ARCH_WANT_COMPAT_STAT
 #endif
 
 #ifdef __32bit_syscall_numbers__
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 80e9d5206a71..761173ccc33c 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -22,6 +22,7 @@
 #  include <asm/unistd_32_ia32.h>
 #  define __ARCH_WANT_SYS_TIME
 #  define __ARCH_WANT_SYS_UTIME
+#  define __ARCH_WANT_COMPAT_STAT
 #  define __ARCH_WANT_COMPAT_SYS_PREADV64
 #  define __ARCH_WANT_COMPAT_SYS_PWRITEV64
 #  define __ARCH_WANT_COMPAT_SYS_PREADV64V2
diff --git a/fs/stat.c b/fs/stat.c
index 28d2020ba1f4..ffdeb9065d53 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -639,7 +639,7 @@ SYSCALL_DEFINE5(statx,
 	return do_statx(dfd, filename, flags, mask, buffer);
 }
 
-#ifdef CONFIG_COMPAT
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)
 static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
 {
 	struct compat_stat tmp;
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:14 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:14 +0800
Subject: [PATCH V4 03/17] asm-generic: compat: Cleanup duplicate definitions
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-4-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

There are 7 64bit architectures that support Linux COMPAT mode to
run 32bit applications. A lot of definitions are duplicate:
 - COMPAT_USER_HZ
 - COMPAT_RLIM_INFINITY
 - COMPAT_OFF_T_MAX
 - __compat_uid_t, __compat_uid_t
 - compat_dev_t
 - compat_ipc_pid_t
 - struct compat_flock
 - struct compat_flock64
 - struct compat_statfs
 - struct compat_ipc64_perm, compat_semid64_ds,
	  compat_msqid64_ds, compat_shmid64_ds

Cleanup duplicate definitions and merge them into asm-generic.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/arm64/include/asm/compat.h   | 106 ++-----------------------
 arch/mips/include/asm/compat.h    |  27 ++-----
 arch/parisc/include/asm/compat.h  |  45 ++---------
 arch/powerpc/include/asm/compat.h |  46 ++---------
 arch/s390/include/asm/compat.h    |  95 +++-------------------
 arch/sparc/include/asm/compat.h   |  42 ++++------
 arch/x86/include/asm/compat.h     |  89 +++------------------
 include/asm-generic/compat.h      | 126 ++++++++++++++++++++++++++++++
 8 files changed, 193 insertions(+), 383 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eaa6ca062d89..5b911f3625e8 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -8,6 +8,13 @@
 #define compat_mode_t compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
 #include <asm-generic/compat.h>
 
 #ifdef CONFIG_COMPAT
@@ -19,21 +26,15 @@ typedef u16		compat_mode_t;
 #include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 
-#define COMPAT_USER_HZ		100
 #ifdef __AARCH64EB__
 #define COMPAT_UTS_MACHINE	"armv8b\0\0"
 #else
 #define COMPAT_UTS_MACHINE	"armv8l\0\0"
 #endif
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
 typedef u16		__compat_uid16_t;
 typedef u16		__compat_gid16_t;
-typedef u32		compat_dev_t;
 typedef s32		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
 #ifdef __AARCH64EB__
@@ -65,106 +66,13 @@ struct compat_stat {
 	compat_ulong_t	__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 #define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
 #define COMPAT_MINSIGSTKSZ	2048
 
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	unsigned short mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	compat_ulong_t unused1;
-	compat_ulong_t unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused3;
-	compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
 static inline int is_compat_task(void)
 {
 	return test_thread_flag(TIF_32BIT);
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index bbb3bc5a42fd..ceab66ba052b 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -9,28 +9,29 @@
 #include <asm/page.h>
 #include <asm/ptrace.h>
 
+#define __compat_uid_t	__compat_uid_t
 typedef s32		__compat_uid_t;
 typedef s32		__compat_gid_t;
+
 typedef __compat_uid_t	__compat_uid32_t;
 typedef __compat_gid_t	__compat_gid32_t;
 #define __compat_uid32_t __compat_uid32_t
-#define __compat_gid32_t __compat_gid32_t
+
+#define compat_flock		compat_flock
+#define compat_statfs		compat_statfs
+#define compat_ipc64_perm	compat_ipc64_perm
 
 #define _COMPAT_NSIG		128		/* Don't ask !$@#% ...	*/
 #define _COMPAT_NSIG_BPW	32
 typedef u32		compat_sigset_word;
 
+#define COMPAT_RLIM_INFINITY	0x7fffffffUL
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"mips\0\0\0"
 
-typedef u32		compat_dev_t;
 typedef u32		compat_nlink_t;
-typedef s32		compat_ipc_pid_t;
-typedef struct {
-	s32	val[2];
-} compat_fsid_t;
 
 struct compat_stat {
 	compat_dev_t	st_dev;
@@ -69,14 +70,6 @@ struct compat_flock {
 #define F_SETLK64	34
 #define F_SETLKW64	35
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
@@ -92,10 +85,6 @@ struct compat_statfs {
 	int		f_spare[5];
 };
 
-#define COMPAT_RLIM_INFINITY	0x7fffffffUL
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid32_t uid;
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c04f5a637c39..339d1b833fa7 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -11,16 +11,16 @@
 #define compat_mode_t compat_mode_t
 typedef u16	compat_mode_t;
 
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16	compat_ipc_pid_t;
+
+#define compat_ipc64_perm compat_ipc64_perm
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ 		100
 #define COMPAT_UTS_MACHINE	"parisc\0\0"
 
-typedef u32	__compat_uid_t;
-typedef u32	__compat_gid_t;
-typedef u32	compat_dev_t;
 typedef u16	compat_nlink_t;
-typedef u16	compat_ipc_pid_t;
 
 struct compat_stat {
 	compat_dev_t		st_dev;	/* dev_t is 32 bits on parisc */
@@ -53,37 +53,6 @@ struct compat_stat {
 	u32			st_spare4[3];
 };
 
-struct compat_flock {
-	short			l_type;
-	short			l_whence;
-	compat_off_t		l_start;
-	compat_off_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_flock64 {
-	short			l_type;
-	short			l_whence;
-	compat_loff_t		l_start;
-	compat_loff_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_statfs {
-	s32		f_type;
-	s32		f_bsize;
-	s32		f_blocks;
-	s32		f_bfree;
-	s32		f_bavail;
-	s32		f_files;
-	s32		f_ffree;
-	__kernel_fsid_t	f_fsid;
-	s32		f_namelen;
-	s32		f_frsize;
-	s32		f_flags;
-	s32		f_spare[4];
-};
-
 struct compat_sigcontext {
 	compat_int_t sc_flags;
 	compat_int_t sc_gr[32]; /* PSW in sc_gr[0] */
@@ -93,10 +62,6 @@ struct compat_sigcontext {
 	compat_int_t sc_sar; /* cr11 */
 };
 
-#define COMPAT_RLIM_INFINITY 0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid_t uid;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 7afc96fb6524..a71d235bc5d7 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -8,21 +8,20 @@
 #include <linux/types.h>
 #include <linux/sched.h>
 
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		compat_ipc_pid_t;
+
+#define compat_ipc64_perm compat_ipc64_perm
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #ifdef __BIG_ENDIAN__
 #define COMPAT_UTS_MACHINE	"ppc\0\0"
 #else
 #define COMPAT_UTS_MACHINE	"ppcle\0\0"
 #endif
 
-typedef u32		__compat_uid_t;
-typedef u32		__compat_gid_t;
-typedef u32		compat_dev_t;
 typedef s16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
 	compat_dev_t	st_dev;
@@ -44,45 +43,10 @@ struct compat_stat {
 	u32		__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 /*
  * ipc64_perm is actually 32/64bit clean but since the compat layer refers to
  * it we may as well define it.
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index cdc7ae72529d..028a79c2de00 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -12,6 +12,18 @@
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
+#define compat_statfs	compat_statfs
+
 #include <asm-generic/compat.h>
 
 #define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
@@ -53,15 +65,9 @@ typedef u16		compat_mode_t;
 			 PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
 			 PSW32_ASC_PRIMARY)
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"s390\0\0\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef u16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 typedef struct {
 	u32 mask;
@@ -102,26 +108,10 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64       12
 #define F_SETLK64       13
 #define F_SETLKW64      14    
 
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	u32		f_type;
 	u32		f_bsize;
@@ -152,10 +142,6 @@ struct compat_statfs64 {
 	u32		f_spare[4];
 };
 
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 /*
  * A pointer passed in from user mode. This should not
  * be used for syscall parameters, just declare them
@@ -178,61 +164,4 @@ static inline int is_compat_task(void)
 
 #endif
 
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	compat_mode_t mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	unsigned int __unused1;
-	unsigned int __unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-};
 #endif /* _ASM_S390X_COMPAT_H */
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index bd949fcf9d63..63a32f1b13c4 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -9,17 +9,28 @@
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
+#define compat_flock	compat_flock
+#define compat_flock64	compat_flock64
+
+#define compat_ipc64_perm compat_ipc64_perm
+
+#define COMPAT_RLIM_INFINITY 0x7fffffff
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"sparc\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef s16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
 	compat_dev_t	st_dev;
@@ -97,25 +108,6 @@ struct compat_flock64 {
 	short		__unused;
 };
 
-struct compat_statfs {
-	int		f_type;
-	int		f_bsize;
-	int		f_blocks;
-	int		f_bfree;
-	int		f_bavail;
-	int		f_files;
-	int		f_ffree;
-	compat_fsid_t	f_fsid;
-	int		f_namelen;	/* SunOS ignores this field. */
-	int		f_frsize;
-	int		f_flags;
-	int		f_spare[4];
-};
-
-#define COMPAT_RLIM_INFINITY 0x7fffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
 struct compat_ipc64_perm {
 	compat_key_t key;
 	__compat_uid32_t uid;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7516e4199b3c..d3523cf1b673 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -15,17 +15,24 @@
 #define compat_mode_t	compat_mode_t
 typedef u16		compat_mode_t;
 
+#define __compat_uid_t	__compat_uid_t
+typedef u16		__compat_uid_t;
+typedef u16		__compat_gid_t;
+
+#define compat_dev_t	compat_dev_t
+typedef u16		compat_dev_t;
+
+#define compat_ipc_pid_t compat_ipc_pid_t
+typedef u16		 compat_ipc_pid_t;
+
+#define compat_flock64	compat_flock64
+#define compat_statfs	compat_statfs
+
 #include <asm-generic/compat.h>
 
-#define COMPAT_USER_HZ		100
 #define COMPAT_UTS_MACHINE	"i686\0\0"
 
-typedef u16		__compat_uid_t;
-typedef u16		__compat_gid_t;
-typedef u16		compat_dev_t;
 typedef u16		compat_nlink_t;
-typedef u16		compat_ipc_pid_t;
-typedef __kernel_fsid_t	compat_fsid_t;
 
 struct compat_stat {
 	compat_dev_t	st_dev;
@@ -50,14 +57,6 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
@@ -89,68 +88,6 @@ struct compat_statfs {
 	int		f_spare[4];
 };
 
-#define COMPAT_RLIM_INFINITY		0xffffffff
-
-#define COMPAT_OFF_T_MAX	0x7fffffff
-
-struct compat_ipc64_perm {
-	compat_key_t key;
-	__compat_uid32_t uid;
-	__compat_gid32_t gid;
-	__compat_uid32_t cuid;
-	__compat_gid32_t cgid;
-	unsigned short mode;
-	unsigned short __pad1;
-	unsigned short seq;
-	unsigned short __pad2;
-	compat_ulong_t unused1;
-	compat_ulong_t unused2;
-};
-
-struct compat_semid64_ds {
-	struct compat_ipc64_perm sem_perm;
-	compat_ulong_t sem_otime;
-	compat_ulong_t sem_otime_high;
-	compat_ulong_t sem_ctime;
-	compat_ulong_t sem_ctime_high;
-	compat_ulong_t sem_nsems;
-	compat_ulong_t __unused3;
-	compat_ulong_t __unused4;
-};
-
-struct compat_msqid64_ds {
-	struct compat_ipc64_perm msg_perm;
-	compat_ulong_t msg_stime;
-	compat_ulong_t msg_stime_high;
-	compat_ulong_t msg_rtime;
-	compat_ulong_t msg_rtime_high;
-	compat_ulong_t msg_ctime;
-	compat_ulong_t msg_ctime_high;
-	compat_ulong_t msg_cbytes;
-	compat_ulong_t msg_qnum;
-	compat_ulong_t msg_qbytes;
-	compat_pid_t   msg_lspid;
-	compat_pid_t   msg_lrpid;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
-struct compat_shmid64_ds {
-	struct compat_ipc64_perm shm_perm;
-	compat_size_t  shm_segsz;
-	compat_ulong_t shm_atime;
-	compat_ulong_t shm_atime_high;
-	compat_ulong_t shm_dtime;
-	compat_ulong_t shm_dtime_high;
-	compat_ulong_t shm_ctime;
-	compat_ulong_t shm_ctime_high;
-	compat_pid_t   shm_cpid;
-	compat_pid_t   shm_lpid;
-	compat_ulong_t shm_nattch;
-	compat_ulong_t __unused4;
-	compat_ulong_t __unused5;
-};
-
 #ifdef CONFIG_X86_X32_ABI
 #define COMPAT_USE_64BIT_TIME \
 	(!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
diff --git a/include/asm-generic/compat.h b/include/asm-generic/compat.h
index d46c0201cc34..32269059058a 100644
--- a/include/asm-generic/compat.h
+++ b/include/asm-generic/compat.h
@@ -2,6 +2,18 @@
 #ifndef __ASM_GENERIC_COMPAT_H
 #define __ASM_GENERIC_COMPAT_H
 
+#ifndef COMPAT_USER_HZ
+#define COMPAT_USER_HZ		100
+#endif
+
+#ifndef COMPAT_RLIM_INFINITY
+#define COMPAT_RLIM_INFINITY	0xffffffff
+#endif
+
+#ifndef COMPAT_OFF_T_MAX
+#define COMPAT_OFF_T_MAX	0x7fffffff
+#endif
+
 /* These types are common across all compat ABIs */
 typedef u32 compat_size_t;
 typedef s32 compat_ssize_t;
@@ -24,6 +36,11 @@ typedef u32 compat_caddr_t;
 typedef u32 compat_aio_context_t;
 typedef u32 compat_old_sigset_t;
 
+#ifndef __compat_uid_t
+typedef u32 __compat_uid_t;
+typedef u32 __compat_gid_t;
+#endif
+
 #ifndef __compat_uid32_t
 typedef u32 __compat_uid32_t;
 typedef u32 __compat_gid32_t;
@@ -47,4 +64,113 @@ typedef u32 compat_sigset_word;
 #define _COMPAT_NSIG_BPW 32
 #endif
 
+#ifndef compat_dev_t
+typedef u32 compat_dev_t;
+#endif
+
+#ifndef compat_ipc_pid_t
+typedef s32 compat_ipc_pid_t;
+#endif
+
+#ifndef compat_fsid_t
+typedef __kernel_fsid_t	compat_fsid_t;
+#endif
+
+#ifndef compat_flock
+struct compat_flock {
+	compat_short_t	l_type;
+	compat_short_t	l_whence;
+	compat_off_t	l_start;
+	compat_off_t	l_len;
+	compat_pid_t	l_pid;
+};
+#endif
+
+#ifndef compat_flock64
+struct compat_flock64 {
+	compat_short_t	l_type;
+	compat_short_t	l_whence;
+	compat_loff_t	l_start;
+	compat_loff_t	l_len;
+	compat_pid_t	l_pid;
+};
+#endif
+
+#ifndef compat_statfs
+struct compat_statfs {
+	compat_int_t	f_type;
+	compat_int_t	f_bsize;
+	compat_int_t	f_blocks;
+	compat_int_t	f_bfree;
+	compat_int_t	f_bavail;
+	compat_int_t	f_files;
+	compat_int_t	f_ffree;
+	compat_fsid_t	f_fsid;
+	compat_int_t	f_namelen;
+	compat_int_t	f_frsize;
+	compat_int_t	f_flags;
+	compat_int_t	f_spare[4];
+};
+#endif
+
+#ifndef compat_ipc64_perm
+struct compat_ipc64_perm {
+	compat_key_t key;
+	__compat_uid32_t uid;
+	__compat_gid32_t gid;
+	__compat_uid32_t cuid;
+	__compat_gid32_t cgid;
+	compat_mode_t	mode;
+	unsigned char	__pad1[4 - sizeof(compat_mode_t)];
+	compat_ushort_t	seq;
+	compat_ushort_t	__pad2;
+	compat_ulong_t	unused1;
+	compat_ulong_t	unused2;
+};
+
+struct compat_semid64_ds {
+	struct compat_ipc64_perm sem_perm;
+	compat_ulong_t sem_otime;
+	compat_ulong_t sem_otime_high;
+	compat_ulong_t sem_ctime;
+	compat_ulong_t sem_ctime_high;
+	compat_ulong_t sem_nsems;
+	compat_ulong_t __unused3;
+	compat_ulong_t __unused4;
+};
+
+struct compat_msqid64_ds {
+	struct compat_ipc64_perm msg_perm;
+	compat_ulong_t msg_stime;
+	compat_ulong_t msg_stime_high;
+	compat_ulong_t msg_rtime;
+	compat_ulong_t msg_rtime_high;
+	compat_ulong_t msg_ctime;
+	compat_ulong_t msg_ctime_high;
+	compat_ulong_t msg_cbytes;
+	compat_ulong_t msg_qnum;
+	compat_ulong_t msg_qbytes;
+	compat_pid_t   msg_lspid;
+	compat_pid_t   msg_lrpid;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+	struct compat_ipc64_perm shm_perm;
+	compat_size_t  shm_segsz;
+	compat_ulong_t shm_atime;
+	compat_ulong_t shm_atime_high;
+	compat_ulong_t shm_dtime;
+	compat_ulong_t shm_dtime_high;
+	compat_ulong_t shm_ctime;
+	compat_ulong_t shm_ctime_high;
+	compat_pid_t   shm_cpid;
+	compat_pid_t   shm_lpid;
+	compat_ulong_t shm_nattch;
+	compat_ulong_t __unused4;
+	compat_ulong_t __unused5;
+};
+#endif
+
 #endif
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:15 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:15 +0800
Subject: [PATCH V4 04/17] syscalls: compat: Fix the missing part for
 __SYSCALL_COMPAT
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-5-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Make "uapi asm unistd.h" could be used for architectures' COMPAT
mode. The __SYSCALL_COMPAT is first used in riscv.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
---
 include/uapi/asm-generic/unistd.h       | 4 ++--
 tools/include/uapi/asm-generic/unistd.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 1c48b0ae3ba3..45fa180cc56a 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h
@@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
 
 /* kernel/ptrace.c */
 #define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
+__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
 
 /* kernel/sched/core.c */
 #define __NR_sched_setparam 118
@@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
 #define __NR_kexec_file_load 294
 __SYSCALL(__NR_kexec_file_load,     sys_kexec_file_load)
 /* 295 through 402 are unassigned to sync up with generic numbers, don't use */
-#if __BITS_PER_LONG == 32
+#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
 #define __NR_clock_gettime64 403
 __SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
 #define __NR_clock_settime64 404
diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index 1c48b0ae3ba3..45fa180cc56a 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h
@@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
 
 /* kernel/ptrace.c */
 #define __NR_ptrace 117
-__SYSCALL(__NR_ptrace, sys_ptrace)
+__SC_COMP(__NR_ptrace, sys_ptrace, compat_sys_ptrace)
 
 /* kernel/sched/core.c */
 #define __NR_sched_setparam 118
@@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
 #define __NR_kexec_file_load 294
 __SYSCALL(__NR_kexec_file_load,     sys_kexec_file_load)
 /* 295 through 402 are unassigned to sync up with generic numbers, don't use */
-#if __BITS_PER_LONG == 32
+#if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
 #define __NR_clock_gettime64 403
 __SYSCALL(__NR_clock_gettime64, sys_clock_gettime)
 #define __NR_clock_settime64 404
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:16 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:16 +0800
Subject: [PATCH V4 05/17] riscv: Fixup difference with defconfig
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-6-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Let's follow the origin patch's spirit:

The only difference between rv32_defconfig and defconfig is that
rv32_defconfig has  CONFIG_ARCH_RV32I=y.

This is helpful to compare rv64-compat-rv32 v.s. rv32-linux.

Fixes: 1b937e8faa87ccfb ("RISC-V: Add separate defconfig for 32bit systems")
Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Anup Patel <anup.patel at wdc.com>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/Makefile               |   4 +
 arch/riscv/configs/rv32_defconfig | 135 ------------------------------
 2 files changed, 4 insertions(+), 135 deletions(-)
 delete mode 100644 arch/riscv/configs/rv32_defconfig

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8a107ed18b0d..a02e588c4947 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -148,3 +148,7 @@ PHONY += rv64_randconfig
 rv64_randconfig:
 	$(Q)$(MAKE) KCONFIG_ALLCONFIG=$(srctree)/arch/riscv/configs/64-bit.config \
 		-f $(srctree)/Makefile randconfig
+
+PHONY += rv32_defconfig
+rv32_defconfig:
+	$(Q)$(MAKE) -f $(srctree)/Makefile defconfig 32-bit.config
diff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig
deleted file mode 100644
index 8b56a7f1eb06..000000000000
--- a/arch/riscv/configs/rv32_defconfig
+++ /dev/null
@@ -1,135 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_NO_HZ_IDLE=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_BPF_SYSCALL=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_CFS_BANDWIDTH=y
-CONFIG_CGROUP_BPF=y
-CONFIG_NAMESPACES=y
-CONFIG_USER_NS=y
-CONFIG_CHECKPOINT_RESTORE=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-# CONFIG_SYSFS_SYSCALL is not set
-CONFIG_SOC_SIFIVE=y
-CONFIG_SOC_VIRT=y
-CONFIG_ARCH_RV32I=y
-CONFIG_SMP=y
-CONFIG_HOTPLUG_CPU=y
-CONFIG_VIRTUALIZATION=y
-CONFIG_KVM=m
-CONFIG_JUMP_LABEL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NETLINK_DIAG=y
-CONFIG_NET_9P=y
-CONFIG_NET_9P_VIRTIO=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCI_HOST_GENERIC=y
-CONFIG_PCIE_XILINX=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_VIRTIO_BLK=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_SCSI_VIRTIO=y
-CONFIG_ATA=y
-CONFIG_SATA_AHCI=y
-CONFIG_SATA_AHCI_PLATFORM=y
-CONFIG_NETDEVICES=y
-CONFIG_VIRTIO_NET=y
-CONFIG_MACB=y
-CONFIG_E1000E=y
-CONFIG_R8169=y
-CONFIG_MICROSEMI_PHY=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_OF_PLATFORM=y
-CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
-CONFIG_HVC_RISCV_SBI=y
-CONFIG_VIRTIO_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_HW_RANDOM_VIRTIO=y
-CONFIG_SPI=y
-CONFIG_SPI_SIFIVE=y
-# CONFIG_PTP_1588_CLOCK is not set
-CONFIG_DRM=y
-CONFIG_DRM_RADEON=y
-CONFIG_DRM_VIRTIO_GPU=y
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_USB=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_PLATFORM=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_HCD_PLATFORM=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PLATFORM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_UAS=y
-CONFIG_MMC=y
-CONFIG_MMC_SPI=y
-CONFIG_RTC_CLASS=y
-CONFIG_VIRTIO_PCI=y
-CONFIG_VIRTIO_BALLOON=y
-CONFIG_VIRTIO_INPUT=y
-CONFIG_VIRTIO_MMIO=y
-CONFIG_RPMSG_CHAR=y
-CONFIG_RPMSG_VIRTIO=y
-CONFIG_EXT4_FS=y
-CONFIG_EXT4_FS_POSIX_ACL=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_NFS_V4_2=y
-CONFIG_ROOT_NFS=y
-CONFIG_9P_FS=y
-CONFIG_CRYPTO_USER_API_HASH=y
-CONFIG_CRYPTO_DEV_VIRTIO=y
-CONFIG_PRINTK_TIME=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_PAGEALLOC=y
-CONFIG_SCHED_STACK_END_CHECK=y
-CONFIG_DEBUG_VM=y
-CONFIG_DEBUG_VM_PGFLAGS=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_PER_CPU_MAPS=y
-CONFIG_SOFTLOCKUP_DETECTOR=y
-CONFIG_WQ_WATCHDOG=y
-CONFIG_DEBUG_TIMEKEEPING=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_RWSEMS=y
-CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_PLIST=y
-CONFIG_DEBUG_SG=y
-# CONFIG_RCU_TRACE is not set
-CONFIG_RCU_EQS_DEBUG=y
-# CONFIG_FTRACE is not set
-# CONFIG_RUNTIME_TESTING_MENU is not set
-CONFIG_MEMTEST=y
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:17 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:17 +0800
Subject: [PATCH V4 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-7-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement asm/compat.h for struct compat_xxx, RLIM_INFINITY,
OFF_T_MAX, is_compat_task, compat_user_regset, regset convert.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/compat.h      | 135 +++++++++++++++++++++++++++
 arch/riscv/include/asm/thread_info.h |   1 +
 2 files changed, 136 insertions(+)
 create mode 100644 arch/riscv/include/asm/compat.h

diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
new file mode 100644
index 000000000000..3d3e89629e3b
--- /dev/null
+++ b/arch/riscv/include/asm/compat.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __ASM_COMPAT_H
+#define __ASM_COMPAT_H
+
+#define COMPAT_UTS_MACHINE	"riscv\0\0"
+
+#define COMPAT_RLIM_INFINITY	0x7fffffff
+
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/sched/task_stack.h>
+#include <asm-generic/compat.h>
+
+#define F_GETLK64	12
+#define F_SETLK64	13
+#define F_SETLKW64	14
+
+static inline int is_compat_task(void)
+{
+	return test_thread_flag(TIF_32BIT);
+}
+
+struct compat_user_regs_struct {
+	compat_ulong_t pc;
+	compat_ulong_t ra;
+	compat_ulong_t sp;
+	compat_ulong_t gp;
+	compat_ulong_t tp;
+	compat_ulong_t t0;
+	compat_ulong_t t1;
+	compat_ulong_t t2;
+	compat_ulong_t s0;
+	compat_ulong_t s1;
+	compat_ulong_t a0;
+	compat_ulong_t a1;
+	compat_ulong_t a2;
+	compat_ulong_t a3;
+	compat_ulong_t a4;
+	compat_ulong_t a5;
+	compat_ulong_t a6;
+	compat_ulong_t a7;
+	compat_ulong_t s2;
+	compat_ulong_t s3;
+	compat_ulong_t s4;
+	compat_ulong_t s5;
+	compat_ulong_t s6;
+	compat_ulong_t s7;
+	compat_ulong_t s8;
+	compat_ulong_t s9;
+	compat_ulong_t s10;
+	compat_ulong_t s11;
+	compat_ulong_t t3;
+	compat_ulong_t t4;
+	compat_ulong_t t5;
+	compat_ulong_t t6;
+};
+
+static inline void regs_to_cregs(struct compat_user_regs_struct *cregs,
+				 struct pt_regs *regs)
+{
+	cregs->pc	= (compat_ulong_t) regs->epc;
+	cregs->ra	= (compat_ulong_t) regs->ra;
+	cregs->sp	= (compat_ulong_t) regs->sp;
+	cregs->gp	= (compat_ulong_t) regs->gp;
+	cregs->tp	= (compat_ulong_t) regs->tp;
+	cregs->t0	= (compat_ulong_t) regs->t0;
+	cregs->t1	= (compat_ulong_t) regs->t1;
+	cregs->t2	= (compat_ulong_t) regs->t2;
+	cregs->s0	= (compat_ulong_t) regs->s0;
+	cregs->s1	= (compat_ulong_t) regs->s1;
+	cregs->a0	= (compat_ulong_t) regs->a0;
+	cregs->a1	= (compat_ulong_t) regs->a1;
+	cregs->a2	= (compat_ulong_t) regs->a2;
+	cregs->a3	= (compat_ulong_t) regs->a3;
+	cregs->a4	= (compat_ulong_t) regs->a4;
+	cregs->a5	= (compat_ulong_t) regs->a5;
+	cregs->a6	= (compat_ulong_t) regs->a6;
+	cregs->a7	= (compat_ulong_t) regs->a7;
+	cregs->s2	= (compat_ulong_t) regs->s2;
+	cregs->s3	= (compat_ulong_t) regs->s3;
+	cregs->s4	= (compat_ulong_t) regs->s4;
+	cregs->s5	= (compat_ulong_t) regs->s5;
+	cregs->s6	= (compat_ulong_t) regs->s6;
+	cregs->s7	= (compat_ulong_t) regs->s7;
+	cregs->s8	= (compat_ulong_t) regs->s8;
+	cregs->s9	= (compat_ulong_t) regs->s9;
+	cregs->s10	= (compat_ulong_t) regs->s10;
+	cregs->s11	= (compat_ulong_t) regs->s11;
+	cregs->t3	= (compat_ulong_t) regs->t3;
+	cregs->t4	= (compat_ulong_t) regs->t4;
+	cregs->t5	= (compat_ulong_t) regs->t5;
+	cregs->t6	= (compat_ulong_t) regs->t6;
+};
+
+static inline void cregs_to_regs(struct compat_user_regs_struct *cregs,
+				 struct pt_regs *regs)
+{
+	regs->epc	= (unsigned long) cregs->pc;
+	regs->ra	= (unsigned long) cregs->ra;
+	regs->sp	= (unsigned long) cregs->sp;
+	regs->gp	= (unsigned long) cregs->gp;
+	regs->tp	= (unsigned long) cregs->tp;
+	regs->t0	= (unsigned long) cregs->t0;
+	regs->t1	= (unsigned long) cregs->t1;
+	regs->t2	= (unsigned long) cregs->t2;
+	regs->s0	= (unsigned long) cregs->s0;
+	regs->s1	= (unsigned long) cregs->s1;
+	regs->a0	= (unsigned long) cregs->a0;
+	regs->a1	= (unsigned long) cregs->a1;
+	regs->a2	= (unsigned long) cregs->a2;
+	regs->a3	= (unsigned long) cregs->a3;
+	regs->a4	= (unsigned long) cregs->a4;
+	regs->a5	= (unsigned long) cregs->a5;
+	regs->a6	= (unsigned long) cregs->a6;
+	regs->a7	= (unsigned long) cregs->a7;
+	regs->s2	= (unsigned long) cregs->s2;
+	regs->s3	= (unsigned long) cregs->s3;
+	regs->s4	= (unsigned long) cregs->s4;
+	regs->s5	= (unsigned long) cregs->s5;
+	regs->s6	= (unsigned long) cregs->s6;
+	regs->s7	= (unsigned long) cregs->s7;
+	regs->s8	= (unsigned long) cregs->s8;
+	regs->s9	= (unsigned long) cregs->s9;
+	regs->s10	= (unsigned long) cregs->s10;
+	regs->s11	= (unsigned long) cregs->s11;
+	regs->t3	= (unsigned long) cregs->t3;
+	regs->t4	= (unsigned long) cregs->t4;
+	regs->t5	= (unsigned long) cregs->t5;
+	regs->t6	= (unsigned long) cregs->t6;
+};
+
+#endif /* __ASM_COMPAT_H */
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 60da0dcacf14..9392e35c689d 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -91,6 +91,7 @@ struct thread_info {
 #define TIF_SECCOMP		8	/* syscall secure computing */
 #define TIF_NOTIFY_SIGNAL	9	/* signal notifications exist */
 #define TIF_UPROBE		10	/* uprobe breakpoint or singlestep */
+#define TIF_32BIT		11	/* 32bit process */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:18 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:18 +0800
Subject: [PATCH V4 07/17] riscv: compat: Re-implement TASK_SIZE for
 COMPAT_32BIT
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-8-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Make TASK_SIZE from const to dynamic detect TIF_32BIT flag
function. Refer to arm64 to implement DEFAULT_MAP_WINDOW_64 for
efi-stub.

Limit 32-bit compatible process in 0-2GB virtual address range
(which is enough for real scenarios), because it could avoid
address sign extend problem when 32-bit enter 64-bit and ease
software design.

The standard 32-bit TASK_SIZE is 0x9dc00000:FIXADDR_START, and
compared to a compatible 32-bit, it increases 476MB for the
application's virtual address.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/pgtable.h | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7e949f25c933..f0d125ea3ceb 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -704,8 +704,17 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
  * 63?48 all equal to bit 47, or else a page-fault exception will occur."
  */
 #ifdef CONFIG_64BIT
-#define TASK_SIZE      (PGDIR_SIZE * PTRS_PER_PGD / 2)
-#define TASK_SIZE_MIN  (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
+#define TASK_SIZE_64	(PGDIR_SIZE * PTRS_PER_PGD / 2)
+#define TASK_SIZE_MIN	(PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
+
+#ifdef CONFIG_COMPAT
+#define TASK_SIZE_32	(_AC(0x80000000, UL) - PAGE_SIZE)
+#define TASK_SIZE	(test_thread_flag(TIF_32BIT) ? \
+			 TASK_SIZE_32 : TASK_SIZE_64)
+#else
+#define TASK_SIZE	TASK_SIZE_64
+#endif
+
 #else
 #define TASK_SIZE	FIXADDR_START
 #define TASK_SIZE_MIN	TASK_SIZE
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:19 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:19 +0800
Subject: [PATCH V4 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-9-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement compat sys_call_table and some system call functions:
truncate64, ftruncate64, fallocate, pread64, pwrite64,
sync_file_range, readahead, fadvise64_64 which need argument
translation.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/syscall.h         |  1 +
 arch/riscv/include/asm/unistd.h          | 11 +++++++
 arch/riscv/include/uapi/asm/unistd.h     |  2 +-
 arch/riscv/kernel/Makefile               |  1 +
 arch/riscv/kernel/compat_syscall_table.c | 19 ++++++++++++
 arch/riscv/kernel/sys_riscv.c            |  6 ++--
 fs/open.c                                | 24 +++++++++++++++
 fs/read_write.c                          | 16 ++++++++++
 fs/sync.c                                |  9 ++++++
 include/asm-generic/compat.h             |  7 +++++
 include/linux/compat.h                   | 37 ++++++++++++++++++++++++
 mm/fadvise.c                             | 11 +++++++
 mm/readahead.c                           |  7 +++++
 13 files changed, 148 insertions(+), 3 deletions(-)
 create mode 100644 arch/riscv/kernel/compat_syscall_table.c

diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 7ac6a0e275f2..384a63b86420 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -16,6 +16,7 @@
 
 /* The array of function pointers for syscalls. */
 extern void * const sys_call_table[];
+extern void * const compat_sys_call_table[];
 
 /*
  * Only the low 32 bits of orig_r0 are meaningful, so we return int.
diff --git a/arch/riscv/include/asm/unistd.h b/arch/riscv/include/asm/unistd.h
index 6c316093a1e5..5ddac412b578 100644
--- a/arch/riscv/include/asm/unistd.h
+++ b/arch/riscv/include/asm/unistd.h
@@ -11,6 +11,17 @@
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_MEMFD_SECRET
 
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_COMPAT_TRUNCATE64
+#define __ARCH_WANT_COMPAT_FTRUNCATE64
+#define __ARCH_WANT_COMPAT_FALLOCATE
+#define __ARCH_WANT_COMPAT_PREAD64
+#define __ARCH_WANT_COMPAT_PWRITE64
+#define __ARCH_WANT_COMPAT_SYNC_FILE_RANGE
+#define __ARCH_WANT_COMPAT_READAHEAD
+#define __ARCH_WANT_COMPAT_FADVISE64_64
+#endif
+
 #include <uapi/asm/unistd.h>
 
 #define NR_syscalls (__NR_syscalls)
diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
index 8062996c2dfd..c9e50eed14aa 100644
--- a/arch/riscv/include/uapi/asm/unistd.h
+++ b/arch/riscv/include/uapi/asm/unistd.h
@@ -15,7 +15,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#ifdef __LP64__
+#if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
 #define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SET_GET_RLIMIT
 #endif /* __LP64__ */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 612556faa527..954dc7043ad2 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -66,3 +66,4 @@ obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
+obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
diff --git a/arch/riscv/kernel/compat_syscall_table.c b/arch/riscv/kernel/compat_syscall_table.c
new file mode 100644
index 000000000000..651f2b009c28
--- /dev/null
+++ b/arch/riscv/kernel/compat_syscall_table.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#define __SYSCALL_COMPAT
+
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <asm-generic/mman-common.h>
+#include <asm-generic/syscalls.h>
+#include <asm/syscall.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call)      [nr] = (call),
+
+asmlinkage long compat_sys_rt_sigreturn(void);
+
+void * const compat_sys_call_table[__NR_syscalls] = {
+	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 12f8a7fce78b..9c0194f176fc 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c
@@ -33,7 +33,9 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
 {
 	return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 0);
 }
-#else
+#endif
+
+#if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
 SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags,
 	unsigned long, fd, off_t, offset)
@@ -44,7 +46,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
 	 */
 	return riscv_sys_mmap(addr, len, prot, flags, fd, offset, 12);
 }
-#endif /* !CONFIG_64BIT */
+#endif
 
 /*
  * Allows the instruction cache to be flushed from userspace.  Despite RISC-V
diff --git a/fs/open.c b/fs/open.c
index 9ff2f621b760..b25613f7c0a7 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -224,6 +224,21 @@ SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
 }
 #endif /* BITS_PER_LONG == 32 */
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_TRUNCATE64)
+COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
+		       compat_arg_u64_dual(length))
+{
+	return ksys_truncate(pathname, compat_arg_u64_glue(length));
+}
+#endif
+
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FTRUNCATE64)
+COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
+		       compat_arg_u64_dual(length))
+{
+	return ksys_ftruncate(fd, compat_arg_u64_glue(length));
+}
+#endif
 
 int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 {
@@ -339,6 +354,15 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
 	return ksys_fallocate(fd, mode, offset, len);
 }
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FALLOCATE)
+COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset),
+		       compat_arg_u64_dual(len))
+{
+	return ksys_fallocate(fd, mode, compat_arg_u64_glue(offset),
+			      compat_arg_u64_glue(len));
+}
+#endif
+
 /*
  * access() needs to use the real uid/gid, not the effective uid/gid.
  * We do this by temporarily clearing all FS-related capabilities and
diff --git a/fs/read_write.c b/fs/read_write.c
index 0074afa7ecb3..548657c462e8 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -681,6 +681,14 @@ SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
 	return ksys_pread64(fd, buf, count, pos);
 }
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PREAD64)
+COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
+		       size_t, count, compat_arg_u64_dual(pos))
+{
+	return ksys_pread64(fd, buf, count, compat_arg_u64_glue(pos));
+}
+#endif
+
 ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
 		      size_t count, loff_t pos)
 {
@@ -707,6 +715,14 @@ SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
 	return ksys_pwrite64(fd, buf, count, pos);
 }
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PWRITE64)
+COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, buf,
+		       size_t, count, compat_arg_u64_dual(pos))
+{
+	return ksys_pwrite64(fd, buf, count, compat_arg_u64_glue(pos));
+}
+#endif
+
 static ssize_t do_iter_readv_writev(struct file *filp, struct iov_iter *iter,
 		loff_t *ppos, int type, rwf_t flags)
 {
diff --git a/fs/sync.c b/fs/sync.c
index 3ce8e2137f31..75edb7a664e5 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -367,6 +367,15 @@ SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
 	return ksys_sync_file_range(fd, offset, nbytes, flags);
 }
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_SYNC_FILE_RANGE)
+COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset),
+		       compat_arg_u64_dual(nbytes), unsigned int, flags)
+{
+	return ksys_sync_file_range(fd, compat_arg_u64_glue(offset),
+				    compat_arg_u64_glue(nbytes), flags);
+}
+#endif
+
 /* It would be nice if people remember that not all the world's an i386
    when they introduce new system calls */
 SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
diff --git a/include/asm-generic/compat.h b/include/asm-generic/compat.h
index 32269059058a..cdf1124a4883 100644
--- a/include/asm-generic/compat.h
+++ b/include/asm-generic/compat.h
@@ -14,6 +14,13 @@
 #define COMPAT_OFF_T_MAX	0x7fffffff
 #endif
 
+#ifndef compat_arg_u64
+#define compat_arg_u64(name)		u32  name##_lo, u32  name##_hi
+#define compat_arg_u64_dual(name)	u32, name##_lo, u32, name##_hi
+#define compat_arg_u64_glue(name)	(((u64)name##_hi << 32) | \
+					 ((u64)name##_lo & 0xffffffffUL))
+#endif
+
 /* These types are common across all compat ABIs */
 typedef u32 compat_size_t;
 typedef s32 compat_ssize_t;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1c758b0e0359..841d882c41e2 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -895,6 +895,43 @@ asmlinkage long compat_sys_sigaction(int sig,
 /* obsolete: net/socket.c */
 asmlinkage long compat_sys_socketcall(int call, u32 __user *args);
 
+#ifdef __ARCH_WANT_COMPAT_TRUNCATE64
+asmlinkage long compat_sys_truncate64(const char __user *pathname, compat_arg_u64(len));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_FTRUNCATE64
+asmlinkage long compat_sys_ftruncate64(unsigned int fd, compat_arg_u64(len));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_FALLOCATE
+asmlinkage long compat_sys_fallocate(int fd, int mode, compat_arg_u64(offset),
+				     compat_arg_u64(len));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_PREAD64
+asmlinkage long compat_sys_pread64(unsigned int fd, char __user * buf, size_t count,
+				   compat_arg_u64(pos));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_PWRITE64
+asmlinkage long compat_sys_pwrite64(unsigned int fd, const char __user * buf, size_t count,
+				    compat_arg_u64(pos));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_SYNC_FILE_RANGE
+asmlinkage long compat_sys_sync_file_range(int fd, compat_arg_u64(pos),
+					   compat_arg_u64(nbytes), unsigned int flags);
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_FADVISE64_64
+asmlinkage long compat_sys_fadvise64_64(int fd, int advice, compat_arg_u64(pos),
+					compat_arg_u64(len));
+#endif
+
+#ifdef __ARCH_WANT_COMPAT_READAHEAD
+asmlinkage long compat_sys_readahead(int fd, compat_arg_u64(offset), size_t count);
+#endif
+
 #endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */
 
 /**
diff --git a/mm/fadvise.c b/mm/fadvise.c
index d6baa4f451c5..8950f7c05d20 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -215,5 +215,16 @@ SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
 	return ksys_fadvise64_64(fd, offset, len, advice);
 }
 
+#endif
+
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FADVISE64_64)
+
+COMPAT_SYSCALL_DEFINE6(fadvise64_64, int, fd, int, advice, compat_arg_u64_dual(offset),
+		       compat_arg_u64_dual(len))
+{
+	return ksys_fadvise64_64(fd, compat_arg_u64_glue(offset),
+				 compat_arg_u64_glue(len), advice);
+}
+
 #endif
 #endif
diff --git a/mm/readahead.c b/mm/readahead.c
index cf0dcf89eb69..9adf57044299 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -640,6 +640,13 @@ SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)
 	return ksys_readahead(fd, offset, count);
 }
 
+#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_READAHEAD)
+COMPAT_SYSCALL_DEFINE4(readahead, int, fd, compat_arg_u64_dual(offset), size_t, count)
+{
+	return ksys_readahead(fd, compat_arg_u64_glue(offset), count);
+}
+#endif
+
 /**
  * readahead_expand - Expand a readahead request
  * @ractl: The request to be expanded
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:20 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:20 +0800
Subject: [PATCH V4 09/17] riscv: compat: syscall: Add entry.S implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-10-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement the entry of compat_sys_call_table[] in asm. Ref to
riscv-privileged spec 4.1.1 Supervisor Status Register (sstatus):

 BIT[32:33] = UXL[1:0]:
 - 1:32
 - 2:64
 - 3:128

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/csr.h |  7 +++++++
 arch/riscv/kernel/entry.S    | 18 ++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index ae711692eec9..eed96fa62d66 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -36,6 +36,13 @@
 #define SR_SD		_AC(0x8000000000000000, UL) /* FS/XS dirty */
 #endif
 
+#ifdef CONFIG_COMPAT
+#define SR_UXL		_AC(0x300000000, UL) /* XLEN mask for U-mode */
+#define SR_UXL_32	_AC(0x100000000, UL) /* XLEN = 32 for U-mode */
+#define SR_UXL_64	_AC(0x200000000, UL) /* XLEN = 64 for U-mode */
+#define SR_UXL_SHIFT	32
+#endif
+
 /* SATP flags */
 #ifndef CONFIG_64BIT
 #define SATP_PPN	_AC(0x003FFFFF, UL)
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index ed29e9c8f660..1951743f09b3 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -207,13 +207,27 @@ check_syscall_nr:
 	 * Syscall number held in a7.
 	 * If syscall number is above allowed value, redirect to ni_syscall.
 	 */
-	bgeu a7, t0, 1f
+	bgeu a7, t0, 3f
+#ifdef CONFIG_COMPAT
+	REG_L s0, PT_STATUS(sp)
+	srli s0, s0, SR_UXL_SHIFT
+	andi s0, s0, (SR_UXL >> SR_UXL_SHIFT)
+	li t0, (SR_UXL_32 >> SR_UXL_SHIFT)
+	sub t0, s0, t0
+	bnez t0, 1f
+
+	/* Call compat_syscall */
+	la s0, compat_sys_call_table
+	j 2f
+1:
+#endif
 	/* Call syscall */
 	la s0, sys_call_table
+2:
 	slli t0, a7, RISCV_LGPTR
 	add s0, s0, t0
 	REG_L s0, 0(s0)
-1:
+3:
 	jalr s0
 
 ret_from_syscall:
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:21 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:21 +0800
Subject: [PATCH V4 10/17] riscv: compat: process: Add UXL_32 support in
 start_thread
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-11-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

If the current task is in COMPAT mode, set SR_UXL_32 in status for
returning userspace. We need CONFIG _COMPAT to prevent compiling
errors with rv32 defconfig.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/kernel/process.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 03ac3aa611f5..1a666ad299b4 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
 	}
 	regs->epc = pc;
 	regs->sp = sp;
+
+#ifdef CONFIG_COMPAT
+	if (is_compat_task())
+		regs->status |= SR_UXL_32;
+#endif
 }
 
 void flush_thread(void)
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:22 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:22 +0800
Subject: [PATCH V4 11/17] riscv: compat: Add elf.h implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-12-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement necessary type and macro for compat elf. See the code
comment for detail.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/riscv/include/asm/elf.h | 48 +++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index f53c40026c7a..c1fc31629d40 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -8,6 +8,8 @@
 #ifndef _ASM_RISCV_ELF_H
 #define _ASM_RISCV_ELF_H
 
+#include <uapi/linux/elf.h>
+#include <linux/compat.h>
 #include <uapi/asm/elf.h>
 #include <asm/auxvec.h>
 #include <asm/byteorder.h>
@@ -18,11 +20,13 @@
  */
 #define ELF_ARCH	EM_RISCV
 
+#ifndef ELF_CLASS
 #ifdef CONFIG_64BIT
 #define ELF_CLASS	ELFCLASS64
 #else
 #define ELF_CLASS	ELFCLASS32
 #endif
+#endif
 
 #define ELF_DATA	ELFDATA2LSB
 
@@ -31,6 +35,15 @@
  */
 #define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
 
+#ifdef CONFIG_COMPAT
+/*
+ * Use the same code with elf_check_arch, because elf32_hdr &
+ * elf64_hdr e_machine's offset are different. The checker is
+ * a little bit simple compare to other architectures.
+ */
+#define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
+#endif
+
 #define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	(PAGE_SIZE)
 
@@ -43,8 +56,14 @@
 #define ELF_ET_DYN_BASE		((TASK_SIZE / 3) * 2)
 
 #ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
+#define STACK_RND_MASK		(test_thread_flag(TIF_32BIT) ? \
+				 0x7ff >> (PAGE_SHIFT - 12) : \
+				 0x3ffff >> (PAGE_SHIFT - 12))
+#else
 #define STACK_RND_MASK		(0x3ffff >> (PAGE_SHIFT - 12))
 #endif
+#endif
 /*
  * This yields a mask that user programs can use to figure out what
  * instruction set this CPU supports.  This could be done in user space,
@@ -60,11 +79,19 @@ extern unsigned long elf_hwcap;
  */
 #define ELF_PLATFORM	(NULL)
 
+#define COMPAT_ELF_PLATFORM	(NULL)
+
 #ifdef CONFIG_MMU
 #define ARCH_DLINFO						\
 do {								\
+	/*							\
+	 * Note that we add ulong after elf_addr_t because	\
+	 * casting current->mm->context.vdso triggers a cast	\
+	 * warning of cast from pointer to integer for		\
+	 * COMPAT ELFCLASS32.					\
+	 */							\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
-		(elf_addr_t)current->mm->context.vdso);		\
+		(elf_addr_t)(ulong)current->mm->context.vdso);	\
 	NEW_AUX_ENT(AT_L1I_CACHESIZE,				\
 		get_cache_size(1, CACHE_TYPE_INST));		\
 	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,			\
@@ -90,4 +117,23 @@ do {							\
 		*(struct user_regs_struct *)regs;	\
 } while (0);
 
+#ifdef CONFIG_COMPAT
+
+#define SET_PERSONALITY(ex)					\
+do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
+		set_thread_flag(TIF_32BIT);			\
+	else							\
+		clear_thread_flag(TIF_32BIT);			\
+	if (personality(current->personality) != PER_LINUX32)	\
+		set_personality(PER_LINUX |			\
+			(current->personality & (~PER_MASK)));	\
+} while (0)
+
+#define COMPAT_ELF_ET_DYN_BASE		((TASK_SIZE_32 / 3) * 2)
+
+/* rv32 registers */
+typedef compat_ulong_t			compat_elf_greg_t;
+typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
+
+#endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:23 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:23 +0800
Subject: [PATCH V4 12/17] riscv: compat: vdso: Add rv32 VDSO base code
 implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-13-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

There is no vgettimeofday supported in rv32 that makes simple to
generate rv32 vdso code which only needs riscv64 compiler. Other
architectures need change compiler or -m (machine parameter) to
support vdso32 compiling. If rv32 support vgettimeofday (which
cause C compile) in future, we would add CROSS_COMPILE to support
that makes more requirement on compiler enviornment.

linux-rv64/arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:
file format elf64-littleriscv

Disassembly of section .text:

0000000000000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

000000000000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

0000000000000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

linux-rv32/arch/riscv/kernel/vdso/vdso.so.dbg:
file format elf32-littleriscv

Disassembly of section .text:

00000800 <__vdso_rt_sigreturn>:
 800:   08b00893                li      a7,139
 804:   00000073                ecall
 808:   0000                    unimp
        ...

0000080c <__vdso_getcpu>:
 80c:   0a800893                li      a7,168
 810:   00000073                ecall
 814:   8082                    ret
        ...

00000818 <__vdso_flush_icache>:
 818:   10300893                li      a7,259
 81c:   00000073                ecall
 820:   8082                    ret

Finally, reuse all *.S from vdso in compat_vdso that makes
implementation clear and readable.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/Makefile                           |  5 ++
 arch/riscv/include/asm/vdso.h                 |  9 +++
 arch/riscv/kernel/Makefile                    |  1 +
 arch/riscv/kernel/compat_vdso/.gitignore      |  2 +
 arch/riscv/kernel/compat_vdso/Makefile        | 68 +++++++++++++++++++
 arch/riscv/kernel/compat_vdso/compat_vdso.S   |  8 +++
 .../kernel/compat_vdso/compat_vdso.lds.S      |  3 +
 arch/riscv/kernel/compat_vdso/flush_icache.S  |  3 +
 .../compat_vdso/gen_compat_vdso_offsets.sh    |  5 ++
 arch/riscv/kernel/compat_vdso/getcpu.S        |  3 +
 arch/riscv/kernel/compat_vdso/note.S          |  3 +
 arch/riscv/kernel/compat_vdso/rt_sigreturn.S  |  3 +
 arch/riscv/kernel/vdso/vdso.S                 |  6 +-
 13 files changed, 118 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
 create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
 create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
 create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
 create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
 create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
 create mode 100644 arch/riscv/kernel/compat_vdso/note.S
 create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S

diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index a02e588c4947..f73d50552e09 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -106,12 +106,17 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 PHONY += vdso_install
 vdso_install:
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso $@)
 
 ifeq ($(KBUILD_EXTMOD),)
 ifeq ($(CONFIG_MMU),y)
 prepare: vdso_prepare
 vdso_prepare: prepare0
 	$(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
+	$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
+
 endif
 endif
 
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index bc6f75f3a199..af981426fe0f 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -21,6 +21,15 @@
 
 #define VDSO_SYMBOL(base, name)							\
 	(void __user *)((unsigned long)(base) + __vdso_##name##_offset)
+
+#ifdef CONFIG_COMPAT
+#include <generated/compat_vdso-offsets.h>
+
+#define COMPAT_VDSO_SYMBOL(base, name)						\
+	(void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
+
+#endif /* CONFIG_COMPAT */
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* CONFIG_MMU */
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 954dc7043ad2..88e79f481c21 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -67,3 +67,4 @@ obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
 obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
+obj-$(CONFIG_COMPAT)		+= compat_vdso/
diff --git a/arch/riscv/kernel/compat_vdso/.gitignore b/arch/riscv/kernel/compat_vdso/.gitignore
new file mode 100644
index 000000000000..19d83d846c1e
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/.gitignore
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+compat_vdso.lds
diff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
new file mode 100644
index 000000000000..7bbbbf94307f
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+# the inclusion of generic Makefile.
+ARCH_REL_TYPE_ABS := R_RISCV_32|R_RISCV_64|R_RISCV_JUMP_SLOT
+include $(srctree)/lib/vdso/Makefile
+# Symbols present in the compat_vdso
+compat_vdso-syms  = rt_sigreturn
+compat_vdso-syms += getcpu
+compat_vdso-syms += flush_icache
+
+# Files to link into the compat_vdso
+obj-compat_vdso = $(patsubst %, %.o, $(compat_vdso-syms)) note.o
+
+ccflags-y := -fno-stack-protector
+
+# Build rules
+targets := $(obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
+obj-compat_vdso := $(addprefix $(obj)/, $(obj-compat_vdso))
+
+obj-y += compat_vdso.o
+CPPFLAGS_compat_vdso.lds += -P -C -U$(ARCH)
+
+# Disable profiling and instrumentation for VDSO code
+GCOV_PROFILE := n
+KCOV_INSTRUMENT := n
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
+
+# Force dependency
+$(obj)/compat_vdso.o: $(obj)/compat_vdso.so
+
+# link rule for the .so file, .lds has to be first
+$(obj)/compat_vdso.so.dbg: $(obj)/compat_vdso.lds $(obj-compat_vdso) FORCE
+	$(call if_changed,compat_vdsold)
+LDFLAGS_compat_vdso.so.dbg = -shared -S -soname=linux-compat_vdso.so.1 \
+	--build-id=sha1 --hash-style=both --eh-frame-hdr
+
+# strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+# Generate VDSO offsets using helper script
+gen-compat_vdsosym := $(srctree)/$(src)/gen_compat_vdso_offsets.sh
+quiet_cmd_compat_vdsosym = VDSOSYM $@
+	cmd_compat_vdsosym = $(NM) $< | $(gen-compat_vdsosym) | LC_ALL=C sort > $@
+
+include/generated/compat_vdso-offsets.h: $(obj)/compat_vdso.so.dbg FORCE
+	$(call if_changed,compat_vdsosym)
+
+# actual build commands
+# The DSO images are built using a special linker script
+# Make sure only to export the intended __compat_vdso_xxx symbol offsets.
+quiet_cmd_compat_vdsold = VDSOLD  $@
+      cmd_compat_vdsold = $(LD) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
+                   $(OBJCOPY) $(patsubst %, -G __compat_vdso_%, $(compat_vdso-syms)) $@.tmp $@ && \
+                   rm $@.tmp
+
+# install commands for the unstripped file
+quiet_cmd_compat_vdso_install = INSTALL $@
+      cmd_compat_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/compat_vdso/$@
+
+compat_vdso.so: $(obj)/compat_vdso.so.dbg
+	@mkdir -p $(MODLIB)/compat_vdso
+	$(call cmd,compat_vdso_install)
+
+compat_vdso_install: compat_vdso.so
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.S b/arch/riscv/kernel/compat_vdso/compat_vdso.S
new file mode 100644
index 000000000000..fea4a8b0c45d
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define	vdso_start	compat_vdso_start
+#define	vdso_end	compat_vdso_end
+
+#define	__VDSO_PATH	"arch/riscv/kernel/compat_vdso/compat_vdso.so"
+
+#include <../vdso/vdso.S>
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
new file mode 100644
index 000000000000..02a9ec5dc7f6
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/vdso.lds.S>
diff --git a/arch/riscv/kernel/compat_vdso/flush_icache.S b/arch/riscv/kernel/compat_vdso/flush_icache.S
new file mode 100644
index 000000000000..88e21a84a974
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/flush_icache.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/flush_icache.S>
diff --git a/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
new file mode 100755
index 000000000000..8ac070c783b3
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+LC_ALL=C
+sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define compat\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/compat_vdso/getcpu.S b/arch/riscv/kernel/compat_vdso/getcpu.S
new file mode 100644
index 000000000000..946449a15a94
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/getcpu.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/getcpu.S>
diff --git a/arch/riscv/kernel/compat_vdso/note.S b/arch/riscv/kernel/compat_vdso/note.S
new file mode 100644
index 000000000000..67c50898b8e5
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/note.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/note.S>
diff --git a/arch/riscv/kernel/compat_vdso/rt_sigreturn.S b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
new file mode 100644
index 000000000000..f4c98f18c053
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
@@ -0,0 +1,3 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <../vdso/rt_sigreturn.S>
diff --git a/arch/riscv/kernel/vdso/vdso.S b/arch/riscv/kernel/vdso/vdso.S
index df222245be05..83f1c899e8d8 100644
--- a/arch/riscv/kernel/vdso/vdso.S
+++ b/arch/riscv/kernel/vdso/vdso.S
@@ -7,12 +7,16 @@
 #include <linux/linkage.h>
 #include <asm/page.h>
 
+#ifndef __VDSO_PATH
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
+#endif
+
 	__PAGE_ALIGNED_DATA
 
 	.globl vdso_start, vdso_end
 	.balign PAGE_SIZE
 vdso_start:
-	.incbin "arch/riscv/kernel/vdso/vdso.so"
+	.incbin __VDSO_PATH
 	.balign PAGE_SIZE
 vdso_end:
 
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:24 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:24 +0800
Subject: [PATCH V4 13/17] riscv: compat: vdso: Add setup additional pages
 implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-14-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Reconstruct __setup_additional_pages() by appending vdso info
pointer argument to meet compat_vdso_info requirement. And change
vm_special_mapping *dm, *cm initialization into static.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/include/asm/elf.h |   5 ++
 arch/riscv/include/asm/mmu.h |   1 +
 arch/riscv/kernel/vdso.c     | 104 +++++++++++++++++++++++++----------
 3 files changed, 81 insertions(+), 29 deletions(-)

diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index c1fc31629d40..6f374e6bc786 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -135,5 +135,10 @@ do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
 typedef compat_ulong_t			compat_elf_greg_t;
 typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
 
+extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+					      int uses_interp);
+#define compat_arch_setup_additional_pages \
+				compat_arch_setup_additional_pages
+
 #endif /* CONFIG_COMPAT */
 #endif /* _ASM_RISCV_ELF_H */
diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 0099dc116168..cedcf8ea3c76 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h
@@ -16,6 +16,7 @@ typedef struct {
 	atomic_long_t id;
 #endif
 	void *vdso;
+	void *vdso_info;
 #ifdef CONFIG_SMP
 	/* A local icache flush is needed before user execution can resume. */
 	cpumask_t icache_stale_mask;
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index a9436a65161a..deca69524799 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -23,6 +23,9 @@ struct vdso_data {
 #endif
 
 extern char vdso_start[], vdso_end[];
+#ifdef CONFIG_COMPAT
+extern char compat_vdso_start[], compat_vdso_end[];
+#endif
 
 enum vvar_pages {
 	VVAR_DATA_PAGE_OFFSET,
@@ -30,6 +33,11 @@ enum vvar_pages {
 	VVAR_NR_PAGES,
 };
 
+enum rv_vdso_map {
+	RV_VDSO_MAP_VVAR,
+	RV_VDSO_MAP_VDSO,
+};
+
 #define VVAR_SIZE  (VVAR_NR_PAGES << PAGE_SHIFT)
 
 /*
@@ -52,12 +60,6 @@ struct __vdso_info {
 	struct vm_special_mapping *cm;
 };
 
-static struct __vdso_info vdso_info __ro_after_init = {
-	.name = "vdso",
-	.vdso_code_start = vdso_start,
-	.vdso_code_end = vdso_end,
-};
-
 static int vdso_mremap(const struct vm_special_mapping *sm,
 		       struct vm_area_struct *new_vma)
 {
@@ -66,35 +68,35 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
 	return 0;
 }
 
-static int __init __vdso_init(void)
+static int __init __vdso_init(struct __vdso_info *vdso_info)
 {
 	unsigned int i;
 	struct page **vdso_pagelist;
 	unsigned long pfn;
 
-	if (memcmp(vdso_info.vdso_code_start, "\177ELF", 4)) {
+	if (memcmp(vdso_info->vdso_code_start, "\177ELF", 4)) {
 		pr_err("vDSO is not a valid ELF object!\n");
 		return -EINVAL;
 	}
 
-	vdso_info.vdso_pages = (
-		vdso_info.vdso_code_end -
-		vdso_info.vdso_code_start) >>
+	vdso_info->vdso_pages = (
+		vdso_info->vdso_code_end -
+		vdso_info->vdso_code_start) >>
 		PAGE_SHIFT;
 
-	vdso_pagelist = kcalloc(vdso_info.vdso_pages,
+	vdso_pagelist = kcalloc(vdso_info->vdso_pages,
 				sizeof(struct page *),
 				GFP_KERNEL);
 	if (vdso_pagelist == NULL)
 		return -ENOMEM;
 
 	/* Grab the vDSO code pages. */
-	pfn = sym_to_pfn(vdso_info.vdso_code_start);
+	pfn = sym_to_pfn(vdso_info->vdso_code_start);
 
-	for (i = 0; i < vdso_info.vdso_pages; i++)
+	for (i = 0; i < vdso_info->vdso_pages; i++)
 		vdso_pagelist[i] = pfn_to_page(pfn + i);
 
-	vdso_info.cm->pages = vdso_pagelist;
+	vdso_info->cm->pages = vdso_pagelist;
 
 	return 0;
 }
@@ -116,13 +118,14 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
 {
 	struct mm_struct *mm = task->mm;
 	struct vm_area_struct *vma;
+	struct __vdso_info *vdso_info = mm->context.vdso_info;
 
 	mmap_read_lock(mm);
 
 	for (vma = mm->mmap; vma; vma = vma->vm_next) {
 		unsigned long size = vma->vm_end - vma->vm_start;
 
-		if (vma_is_special_mapping(vma, vdso_info.dm))
+		if (vma_is_special_mapping(vma, vdso_info->dm))
 			zap_page_range(vma, vma->vm_start, size);
 	}
 
@@ -187,11 +190,6 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
 	return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
-enum rv_vdso_map {
-	RV_VDSO_MAP_VVAR,
-	RV_VDSO_MAP_VDSO,
-};
-
 static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
 	[RV_VDSO_MAP_VVAR] = {
 		.name   = "[vvar]",
@@ -203,25 +201,53 @@ static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
 	},
 };
 
+static struct __vdso_info vdso_info __ro_after_init = {
+	.name = "vdso",
+	.vdso_code_start = vdso_start,
+	.vdso_code_end = vdso_end,
+	.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+	.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+};
+
+#ifdef CONFIG_COMPAT
+static struct __vdso_info compat_vdso_info __ro_after_init = {
+	.name = "compat_vdso",
+	.vdso_code_start = compat_vdso_start,
+	.vdso_code_end = compat_vdso_end,
+	.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+	.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+};
+#endif
+
 static int __init vdso_init(void)
 {
-	vdso_info.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR];
-	vdso_info.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO];
+	int ret;
+
+	ret = __vdso_init(&vdso_info);
+	if (ret)
+		goto out;
 
-	return __vdso_init();
+#ifdef CONFIG_COMPAT
+	ret = __vdso_init(&compat_vdso_info);
+	if (ret)
+		goto out;
+#endif
+out:
+	return ret;
 }
 arch_initcall(vdso_init);
 
 static int __setup_additional_pages(struct mm_struct *mm,
 				    struct linux_binprm *bprm,
-				    int uses_interp)
+				    int uses_interp,
+				    struct __vdso_info *vdso_info)
 {
 	unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
 	void *ret;
 
 	BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
 
-	vdso_text_len = vdso_info.vdso_pages << PAGE_SHIFT;
+	vdso_text_len = vdso_info->vdso_pages << PAGE_SHIFT;
 	/* Be sure to map the data page */
 	vdso_mapping_len = vdso_text_len + VVAR_SIZE;
 
@@ -232,16 +258,18 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	}
 
 	ret = _install_special_mapping(mm, vdso_base, VVAR_SIZE,
-		(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info.dm);
+		(VM_READ | VM_MAYREAD | VM_PFNMAP), vdso_info->dm);
 	if (IS_ERR(ret))
 		goto up_fail;
 
 	vdso_base += VVAR_SIZE;
 	mm->context.vdso = (void *)vdso_base;
+	mm->context.vdso_info = (void *)vdso_info;
+
 	ret =
 	   _install_special_mapping(mm, vdso_base, vdso_text_len,
 		(VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC),
-		vdso_info.cm);
+		vdso_info->cm);
 
 	if (IS_ERR(ret))
 		goto up_fail;
@@ -253,6 +281,24 @@ static int __setup_additional_pages(struct mm_struct *mm,
 	return PTR_ERR(ret);
 }
 
+#ifdef CONFIG_COMPAT
+int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
+				       int uses_interp)
+{
+	struct mm_struct *mm = current->mm;
+	int ret;
+
+	if (mmap_write_lock_killable(mm))
+		return -EINTR;
+
+	ret = __setup_additional_pages(mm, bprm, uses_interp,
+							&compat_vdso_info);
+	mmap_write_unlock(mm);
+
+	return ret;
+}
+#endif
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	struct mm_struct *mm = current->mm;
@@ -261,7 +307,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 	if (mmap_write_lock_killable(mm))
 		return -EINTR;
 
-	ret = __setup_additional_pages(mm, bprm, uses_interp);
+	ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso_info);
 	mmap_write_unlock(mm);
 
 	return ret;
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:25 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:25 +0800
Subject: [PATCH V4 14/17] riscv: compat: signal: Add rt_frame implementation
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-15-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Implement compat_setup_rt_frame for sigcontext save & restore. The
main process is the same with signal, but the rv32 pt_regs' size
is different from rv64's, so we needs convert them.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/kernel/Makefile        |   1 +
 arch/riscv/kernel/compat_signal.c | 243 ++++++++++++++++++++++++++++++
 arch/riscv/kernel/signal.c        |  13 +-
 3 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 arch/riscv/kernel/compat_signal.c

diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 88e79f481c21..a46f9807c59e 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -67,4 +67,5 @@ obj-$(CONFIG_JUMP_LABEL)	+= jump_label.o
 
 obj-$(CONFIG_EFI)		+= efi.o
 obj-$(CONFIG_COMPAT)		+= compat_syscall_table.o
+obj-$(CONFIG_COMPAT)		+= compat_signal.o
 obj-$(CONFIG_COMPAT)		+= compat_vdso/
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
new file mode 100644
index 000000000000..7041742ded08
--- /dev/null
+++ b/arch/riscv/kernel/compat_signal.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/compat.h>
+#include <linux/signal.h>
+#include <linux/uaccess.h>
+#include <linux/syscalls.h>
+#include <linux/tracehook.h>
+#include <linux/linkage.h>
+
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+#include <asm/switch_to.h>
+#include <asm/csr.h>
+
+#define COMPAT_DEBUG_SIG 0
+
+struct compat_sigcontext {
+	struct compat_user_regs_struct sc_regs;
+	union __riscv_fp_state sc_fpregs;
+};
+
+struct compat_ucontext {
+	compat_ulong_t		uc_flags;
+	struct compat_ucontext	*uc_link;
+	compat_stack_t		uc_stack;
+	sigset_t		uc_sigmask;
+	/* There's some padding here to allow sigset_t to be expanded in the
+	 * future.  Though this is unlikely, other architectures put uc_sigmask
+	 * at the end of this structure and explicitly state it can be
+	 * expanded, so we didn't want to box ourselves in here. */
+	__u8		  __unused[1024 / 8 - sizeof(sigset_t)];
+	/* We can't put uc_sigmask at the end of this structure because we need
+	 * to be able to expand sigcontext in the future.  For example, the
+	 * vector ISA extension will almost certainly add ISA state.  We want
+	 * to ensure all user-visible ISA state can be saved and restored via a
+	 * ucontext, so we're putting this at the end in order to allow for
+	 * infinite extensibility.  Since we know this will be extended and we
+	 * assume sigset_t won't be extended an extreme amount, we're
+	 * prioritizing this. */
+	struct compat_sigcontext uc_mcontext;
+};
+
+struct compat_rt_sigframe {
+	struct compat_siginfo info;
+	struct compat_ucontext uc;
+};
+
+#ifdef CONFIG_FPU
+static long compat_restore_fp_state(struct pt_regs *regs,
+	union __riscv_fp_state __user *sc_fpregs)
+{
+	long err;
+	struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
+	size_t i;
+
+	err = __copy_from_user(&current->thread.fstate, state, sizeof(*state));
+	if (unlikely(err))
+		return err;
+
+	fstate_restore(current, regs);
+
+	/* We support no other extension state at this time. */
+	for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
+		u32 value;
+
+		err = __get_user(value, &sc_fpregs->q.reserved[i]);
+		if (unlikely(err))
+			break;
+		if (value != 0)
+			return -EINVAL;
+	}
+
+	return err;
+}
+
+static long compat_save_fp_state(struct pt_regs *regs,
+			  union __riscv_fp_state __user *sc_fpregs)
+{
+	long err;
+	struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
+	size_t i;
+
+	fstate_save(current, regs);
+	err = __copy_to_user(state, &current->thread.fstate, sizeof(*state));
+	if (unlikely(err))
+		return err;
+
+	/* We support no other extension state at this time. */
+	for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
+		err = __put_user(0, &sc_fpregs->q.reserved[i]);
+		if (unlikely(err))
+			break;
+	}
+
+	return err;
+}
+#else
+#define compat_save_fp_state(task, regs) (0)
+#define compat_restore_fp_state(task, regs) (0)
+#endif
+
+static long compat_restore_sigcontext(struct pt_regs *regs,
+	struct compat_sigcontext __user *sc)
+{
+	long err;
+	struct compat_user_regs_struct cregs;
+
+	/* sc_regs is structured the same as the start of pt_regs */
+	err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));
+
+	cregs_to_regs(&cregs, regs);
+
+	/* Restore the floating-point state. */
+	if (has_fpu())
+		err |= compat_restore_fp_state(regs, &sc->sc_fpregs);
+	return err;
+}
+
+COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
+{
+	struct pt_regs *regs = current_pt_regs();
+	struct compat_rt_sigframe __user *frame;
+	struct task_struct *task;
+	sigset_t set;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current->restart_block.fn = do_no_restart_syscall;
+
+	frame = (struct compat_rt_sigframe __user *)regs->sp;
+
+	if (!access_ok(frame, sizeof(*frame)))
+		goto badframe;
+
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	set_current_blocked(&set);
+
+	if (compat_restore_sigcontext(regs, &frame->uc.uc_mcontext))
+		goto badframe;
+
+	if (compat_restore_altstack(&frame->uc.uc_stack))
+		goto badframe;
+
+	return regs->a0;
+
+badframe:
+	task = current;
+	if (show_unhandled_signals) {
+		pr_info_ratelimited(
+			"%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
+			task->comm, task_pid_nr(task), __func__,
+			frame, (void *)regs->epc, (void *)regs->sp);
+	}
+	force_sig(SIGSEGV);
+	return 0;
+}
+
+static long compat_setup_sigcontext(struct compat_rt_sigframe __user *frame,
+	struct pt_regs *regs)
+{
+	struct compat_sigcontext __user *sc = &frame->uc.uc_mcontext;
+	struct compat_user_regs_struct cregs;
+	long err;
+
+	regs_to_cregs(&cregs, regs);
+
+	/* sc_regs is structured the same as the start of pt_regs */
+	err = __copy_to_user(&sc->sc_regs, &cregs, sizeof(sc->sc_regs));
+	/* Save the floating-point state. */
+	if (has_fpu())
+		err |= compat_save_fp_state(regs, &sc->sc_fpregs);
+	return err;
+}
+
+static inline void __user *compat_get_sigframe(struct ksignal *ksig,
+	struct pt_regs *regs, size_t framesize)
+{
+	unsigned long sp;
+	/* Default to using normal stack */
+	sp = regs->sp;
+
+	/*
+	 * If we are on the alternate signal stack and would overflow it, don't.
+	 * Return an always-bogus address instead so we will die with SIGSEGV.
+	 */
+	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
+		return (void __user __force *)(-1UL);
+
+	/* This is the X/Open sanctioned signal stack switching. */
+	sp = sigsp(sp, ksig) - framesize;
+
+	/* Align the stack frame. */
+	sp &= ~0xfUL;
+
+	return (void __user *)sp;
+}
+
+int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+	struct pt_regs *regs)
+{
+	struct compat_rt_sigframe __user *frame;
+	long err = 0;
+
+	frame = compat_get_sigframe(ksig, regs, sizeof(*frame));
+	if (!access_ok(frame, sizeof(*frame)))
+		return -EFAULT;
+
+	err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
+
+	/* Create the ucontext. */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(NULL, &frame->uc.uc_link);
+	err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
+	err |= compat_setup_sigcontext(frame, regs);
+	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+	if (err)
+		return -EFAULT;
+
+	regs->ra = (unsigned long)COMPAT_VDSO_SYMBOL(
+			current->mm->context.vdso, rt_sigreturn);
+
+	/*
+	 * Set up registers for signal handler.
+	 * Registers that we don't modify keep the value they had from
+	 * user-space at the time we took the signal.
+	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
+	 * since some things rely on this (e.g. glibc's debug/segfault.c).
+	 */
+	regs->epc = (unsigned long)ksig->ka.sa.sa_handler;
+	regs->sp = (unsigned long)frame;
+	regs->a0 = ksig->sig;                     /* a0: signal number */
+	regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */
+	regs->a2 = (unsigned long)(&frame->uc);   /* a2: ucontext pointer */
+
+#if COMPAT_DEBUG_SIG
+	pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n",
+		current->comm, task_pid_nr(current), ksig->sig,
+		(void *)regs->epc, (void *)regs->ra, frame);
+#endif
+
+	return 0;
+}
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index c2d5ecbe5526..27d8f39228c4 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -6,6 +6,7 @@
  * Copyright (C) 2012 Regents of the University of California
  */
 
+#include <linux/compat.h>
 #include <linux/signal.h>
 #include <linux/uaccess.h>
 #include <linux/syscalls.h>
@@ -229,6 +230,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+extern int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
+				 struct pt_regs *regs);
+#endif
+
 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 {
 	sigset_t *oldset = sigmask_to_save();
@@ -258,8 +264,13 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 		}
 	}
 
+#ifdef CONFIG_COMPAT
 	/* Set up the stack frame */
-	ret = setup_rt_frame(ksig, oldset, regs);
+	if (is_compat_task())
+		ret = compat_setup_rt_frame(ksig, oldset, regs);
+	else
+#endif
+		ret = setup_rt_frame(ksig, oldset, regs);
 
 	signal_setup_done(ret, ksig, 0);
 }
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:26 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:26 +0800
Subject: [PATCH V4 15/17] riscv: compat: ptrace: Add compat_arch_ptrace
 implement
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-16-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Now, you can use native gdb on riscv64 for rv32 app debugging.

$ uname -a
Linux buildroot 5.16.0-rc4-00036-gbef6b82fdf23-dirty #53 SMP Mon Dec 20 23:06:53 CST 2021 riscv64 GNU/Linux
$ cat /proc/cpuinfo
processor       : 0
hart            : 0
isa             : rv64imafdcsuh
mmu             : sv48

$ file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ file /usr/bin/gdb
/usr/bin/gdb: ELF 32-bit LSB shared object, UCB RISC-V, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ /usr/bin/gdb /bin/busybox
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
Reading symbols from /bin/busybox...
(No debugging symbols found in /bin/busybox)
(gdb) b main
Breakpoint 1 at 0x8ddc
(gdb) r
Starting program: /bin/busybox
Failed to read a valid object file image from memory.

Breakpoint 1, 0x555a8ddc in main ()
(gdb) i r
ra             0x77df0b74       0x77df0b74
sp             0x7fdd3d10       0x7fdd3d10
gp             0x5567e800       0x5567e800 <bb_common_bufsiz1+160>
tp             0x77f64280       0x77f64280
t0             0x0      0
t1             0x555a6fac       1431990188
t2             0x77dd8db4       2011008436
fp             0x7fdd3e34       0x7fdd3e34
s1             0x7fdd3e34       2145205812
a0             0xffffffff       -1
a1             0x2000   8192
a2             0x7fdd3e3c       2145205820
a3             0x0      0
a4             0x7fdd3d30       2145205552
a5             0x555a8dc0       1431997888
a6             0x77f2c170       2012397936
a7             0x6a7c7a2f       1786542639
s2             0x0      0
s3             0x0      0
s4             0x555a8dc0       1431997888
s5             0x77f8a3a8       2012783528
s6             0x7fdd3e3c       2145205820
s7             0x5567cecc       1432866508
--Type <RET> for more, q to quit, c to continue without paging--
s8             0x1      1
s9             0x0      0
s10            0x55634448       1432568904
s11            0x0      0
t3             0x77df0bb8       2011106232
t4             0x42fc   17148
t5             0x0      0
t6             0x40     64
pc             0x555a8ddc       0x555a8ddc <main+28>
(gdb) si
0x555a78f0 in mallopt at plt ()
(gdb) c
Continuing.
BusyBox v1.34.1 (2021-12-19 22:39:48 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.

Usage: busybox [function [arguments]...]
   or: busybox --list[-full]
...
[Inferior 1 (process 107) exited normally]
(gdb) q

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/kernel/ptrace.c | 87 +++++++++++++++++++++++++++++++++++---
 1 file changed, 82 insertions(+), 5 deletions(-)

diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index a89243730153..bb387593a121 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -12,6 +12,7 @@
 #include <asm/thread_info.h>
 #include <asm/switch_to.h>
 #include <linux/audit.h>
+#include <linux/compat.h>
 #include <linux/ptrace.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
@@ -111,11 +112,6 @@ static const struct user_regset_view riscv_user_native_view = {
 	.n = ARRAY_SIZE(riscv_user_regset),
 };
 
-const struct user_regset_view *task_user_regset_view(struct task_struct *task)
-{
-	return &riscv_user_native_view;
-}
-
 struct pt_regs_offset {
 	const char *name;
 	int offset;
@@ -273,3 +269,84 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
 		trace_sys_exit(regs, regs_return_value(regs));
 #endif
 }
+
+#ifdef CONFIG_COMPAT
+static int compat_riscv_gpr_get(struct task_struct *target,
+				const struct user_regset *regset,
+				struct membuf to)
+{
+	struct compat_user_regs_struct cregs;
+
+	regs_to_cregs(&cregs, task_pt_regs(target));
+
+	return membuf_write(&to, &cregs,
+			    sizeof(struct compat_user_regs_struct));
+}
+
+static int compat_riscv_gpr_set(struct task_struct *target,
+				const struct user_regset *regset,
+				unsigned int pos, unsigned int count,
+				const void *kbuf, const void __user *ubuf)
+{
+	int ret;
+	struct compat_user_regs_struct cregs;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
+
+	cregs_to_regs(&cregs, task_pt_regs(target));
+
+	return ret;
+}
+
+static const struct user_regset compat_riscv_user_regset[] = {
+	[REGSET_X] = {
+		.core_note_type = NT_PRSTATUS,
+		.n = ELF_NGREG,
+		.size = sizeof(compat_elf_greg_t),
+		.align = sizeof(compat_elf_greg_t),
+		.regset_get = compat_riscv_gpr_get,
+		.set = compat_riscv_gpr_set,
+	},
+#ifdef CONFIG_FPU
+	[REGSET_F] = {
+		.core_note_type = NT_PRFPREG,
+		.n = ELF_NFPREG,
+		.size = sizeof(elf_fpreg_t),
+		.align = sizeof(elf_fpreg_t),
+		.regset_get = riscv_fpr_get,
+		.set = riscv_fpr_set,
+	},
+#endif
+};
+
+static const struct user_regset_view compat_riscv_user_native_view = {
+	.name = "riscv",
+	.e_machine = EM_RISCV,
+	.regsets = compat_riscv_user_regset,
+	.n = ARRAY_SIZE(compat_riscv_user_regset),
+};
+
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+			compat_ulong_t caddr, compat_ulong_t cdata)
+{
+	long ret = -EIO;
+
+	switch (request) {
+	default:
+		ret = compat_ptrace_request(child, request, caddr, cdata);
+		break;
+	}
+
+	return ret;
+}
+#endif /* CONFIG_COMPAT */
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+#ifdef CONFIG_COMPAT
+	if (test_tsk_thread_flag(task, TIF_32BIT))
+		return &compat_riscv_user_native_view;
+	else
+#endif
+		return &riscv_user_native_view;
+}
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:27 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:27 +0800
Subject: [PATCH V4 16/17] riscv: compat: Add COMPAT Kbuild skeletal support
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-17-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Adds initial skeletal COMPAT Kbuild (Runing 32bit U-mode on 64bit
S-mode) support.
 - Setup kconfig & dummy functions for compiling.
 - Implement compat_start_thread by the way.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Cc: Palmer Dabbelt <palmer at dabbelt.com>
---
 arch/riscv/Kconfig | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5adcbd9b5e88..6f11df8c189f 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -73,6 +73,7 @@ config RISCV
 	select HAVE_ARCH_KGDB if !XIP_KERNEL
 	select HAVE_ARCH_KGDB_QXFER_PKT
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
+	select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
 	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT && MMU
@@ -123,12 +124,18 @@ config ARCH_MMAP_RND_BITS_MIN
 	default 18 if 64BIT
 	default 8
 
+config ARCH_MMAP_RND_COMPAT_BITS_MIN
+	default 8
+
 # max bits determined by the following formula:
 #  VA_BITS - PAGE_SHIFT - 3
 config ARCH_MMAP_RND_BITS_MAX
 	default 24 if 64BIT # SV39 based
 	default 17
 
+config ARCH_MMAP_RND_COMPAT_BITS_MAX
+	default 17
+
 # set if we run in machine mode, cleared if we run in supervisor mode
 config RISCV_M_MODE
 	bool
@@ -406,6 +413,18 @@ config CRASH_DUMP
 
 	  For more details see Documentation/admin-guide/kdump/kdump.rst
 
+config COMPAT
+	bool "Kernel support for 32-bit U-mode"
+	default 64BIT
+	depends on 64BIT && MMU
+	help
+	  This option enables support for a 32-bit U-mode running under a 64-bit
+	  kernel at S-mode. riscv32-specific components such as system calls,
+	  the user helper functions (vdso), signal rt_frame functions and the
+	  ptrace interface are handled appropriately by the kernel.
+
+	  If you want to execute 32-bit userspace applications, say Y.
+
 endmenu
 
 menu "Boot options"
-- 
2.25.1



From guoren at kernel.org  Sat Jan 29 04:17:28 2022
From: guoren at kernel.org (guoren at kernel.org)
Date: Sat, 29 Jan 2022 20:17:28 +0800
Subject: [PATCH V4 17/17] KVM: compat: riscv: Prevent KVM_COMPAT from being
 selected
In-Reply-To: <20220129121728.1079364-1-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
Message-ID: <20220129121728.1079364-18-guoren@kernel.org>

From: Guo Ren <guoren at linux.alibaba.com>

Current riscv doesn't support the 32bit KVM API. Let's make it
clear by not selecting KVM_COMPAT.

Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
Signed-off-by: Guo Ren <guoren at kernel.org>
Cc: Arnd Bergmann <arnd at arndb.de>
---
 virt/kvm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig
index f4834c20e4a6..a8c5c9f06b3c 100644
--- a/virt/kvm/Kconfig
+++ b/virt/kvm/Kconfig
@@ -53,7 +53,7 @@ config KVM_GENERIC_DIRTYLOG_READ_PROTECT
 
 config KVM_COMPAT
        def_bool y
-       depends on KVM && COMPAT && !(S390 || ARM64)
+       depends on KVM && COMPAT && !(S390 || ARM64 || RISCV)
 
 config HAVE_KVM_IRQ_BYPASS
        bool
-- 
2.25.1



From lkp at intel.com  Sat Jan 29 04:27:29 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 29 Jan 2022 20:27:29 +0800
Subject: [linusw-nomadik:ixp4xx-cleanup-v5.17-rc1 21/22]
 drivers/irqchip/irq-ixp4xx.c:210:38: warning: unused variable
 'ixp4xx_irq_chunks'
Message-ID: <202201292056.2xCamI4I-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-cleanup-v5.17-rc1
head:   c9bbd09b3066286f881709c58d82c55724840bbb
commit: b4a844677bb1d7ace4c7a4a8adb1da9e279d8424 [21/22] irq/gpio: ixp4xx: Drop boardfile probe path
config: arm-buildonly-randconfig-r001-20220127 (https://download.01.org/0day-ci/archive/20220129/202201292056.2xCamI4I-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 33b45ee44b1f32ffdbc995e6fec806271b4b3ba4)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/commit/?id=b4a844677bb1d7ace4c7a4a8adb1da9e279d8424
        git remote add linusw-nomadik https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
        git fetch --no-tags linusw-nomadik ixp4xx-cleanup-v5.17-rc1
        git checkout b4a844677bb1d7ace4c7a4a8adb1da9e279d8424
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash drivers/irqchip/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/irqchip/irq-ixp4xx.c:108:39: warning: no previous prototype for function 'ixp4xx_handle_irq' [-Wmissing-prototypes]
   asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
                                         ^
   drivers/irqchip/irq-ixp4xx.c:108:12: note: declare 'static' if the function is not intended to be used outside of this translation unit
   asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
              ^
              static 
   drivers/irqchip/irq-ixp4xx.c:287:12: warning: no previous prototype for function 'ixp4xx_of_init_irq' [-Wmissing-prototypes]
   int __init ixp4xx_of_init_irq(struct device_node *np,
              ^
   drivers/irqchip/irq-ixp4xx.c:287:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   int __init ixp4xx_of_init_irq(struct device_node *np,
   ^
   static 
>> drivers/irqchip/irq-ixp4xx.c:210:38: warning: unused variable 'ixp4xx_irq_chunks' [-Wunused-const-variable]
   static const struct ixp4xx_irq_chunk ixp4xx_irq_chunks[] = {
                                        ^
   3 warnings generated.


vim +/ixp4xx_irq_chunks +210 drivers/irqchip/irq-ixp4xx.c

5b978c10665973 Linus Walleij 2019-01-25  209  
5b978c10665973 Linus Walleij 2019-01-25 @210  static const struct ixp4xx_irq_chunk ixp4xx_irq_chunks[] = {
5b978c10665973 Linus Walleij 2019-01-25  211  	{
5b978c10665973 Linus Walleij 2019-01-25  212  		.irq = 16,
5b978c10665973 Linus Walleij 2019-01-25  213  		.hwirq = 0,
5b978c10665973 Linus Walleij 2019-01-25  214  		.nr_irqs = 6,
5b978c10665973 Linus Walleij 2019-01-25  215  	},
5b978c10665973 Linus Walleij 2019-01-25  216  	{
5b978c10665973 Linus Walleij 2019-01-25  217  		.irq = 24,
5b978c10665973 Linus Walleij 2019-01-25  218  		.hwirq = 8,
5b978c10665973 Linus Walleij 2019-01-25  219  		.nr_irqs = 11,
5b978c10665973 Linus Walleij 2019-01-25  220  	},
5b978c10665973 Linus Walleij 2019-01-25  221  	{
5b978c10665973 Linus Walleij 2019-01-25  222  		.irq = 46,
5b978c10665973 Linus Walleij 2019-01-25  223  		.hwirq = 30,
5b978c10665973 Linus Walleij 2019-01-25  224  		.nr_irqs = 2,
5b978c10665973 Linus Walleij 2019-01-25  225  	},
5b978c10665973 Linus Walleij 2019-01-25  226  	/* Only on the 436 variants */
5b978c10665973 Linus Walleij 2019-01-25  227  	{
5b978c10665973 Linus Walleij 2019-01-25  228  		.irq = 48,
5b978c10665973 Linus Walleij 2019-01-25  229  		.hwirq = 32,
5b978c10665973 Linus Walleij 2019-01-25  230  		.nr_irqs = 10,
5b978c10665973 Linus Walleij 2019-01-25  231  	},
5b978c10665973 Linus Walleij 2019-01-25  232  };
5b978c10665973 Linus Walleij 2019-01-25  233  
5b978c10665973 Linus Walleij 2019-01-25  234  /**
5b978c10665973 Linus Walleij 2019-01-25  235   * ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller
5b978c10665973 Linus Walleij 2019-01-25  236   * @ixi: State container
5b978c10665973 Linus Walleij 2019-01-25  237   * @irqbase: Virtual memory base for the interrupt controller
5b978c10665973 Linus Walleij 2019-01-25  238   * @fwnode: Corresponding fwnode abstraction for this controller
5b978c10665973 Linus Walleij 2019-01-25  239   * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
5b978c10665973 Linus Walleij 2019-01-25  240   */
4ea10150ea00ec Arnd Bergmann 2019-06-17  241  static int __init ixp4xx_irq_setup(struct ixp4xx_irq *ixi,
5b978c10665973 Linus Walleij 2019-01-25  242  				   void __iomem *irqbase,
5b978c10665973 Linus Walleij 2019-01-25  243  				   struct fwnode_handle *fwnode,
5b978c10665973 Linus Walleij 2019-01-25  244  				   bool is_356)
5b978c10665973 Linus Walleij 2019-01-25  245  {
5b978c10665973 Linus Walleij 2019-01-25  246  	int nr_irqs;
5b978c10665973 Linus Walleij 2019-01-25  247  
5b978c10665973 Linus Walleij 2019-01-25  248  	ixi->irqbase = irqbase;
5b978c10665973 Linus Walleij 2019-01-25  249  	ixi->is_356 = is_356;
5b978c10665973 Linus Walleij 2019-01-25  250  
5b978c10665973 Linus Walleij 2019-01-25  251  	/* Route all sources to IRQ instead of FIQ */
5b978c10665973 Linus Walleij 2019-01-25  252  	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR);
5b978c10665973 Linus Walleij 2019-01-25  253  
5b978c10665973 Linus Walleij 2019-01-25  254  	/* Disable all interrupts */
5b978c10665973 Linus Walleij 2019-01-25  255  	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR);
5b978c10665973 Linus Walleij 2019-01-25  256  
5b978c10665973 Linus Walleij 2019-01-25  257  	if (is_356) {
5b978c10665973 Linus Walleij 2019-01-25  258  		/* Route upper 32 sources to IRQ instead of FIQ */
5b978c10665973 Linus Walleij 2019-01-25  259  		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR2);
5b978c10665973 Linus Walleij 2019-01-25  260  
5b978c10665973 Linus Walleij 2019-01-25  261  		/* Disable upper 32 interrupts */
5b978c10665973 Linus Walleij 2019-01-25  262  		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR2);
5b978c10665973 Linus Walleij 2019-01-25  263  
5b978c10665973 Linus Walleij 2019-01-25  264  		nr_irqs = 64;
5b978c10665973 Linus Walleij 2019-01-25  265  	} else {
5b978c10665973 Linus Walleij 2019-01-25  266  		nr_irqs = 32;
5b978c10665973 Linus Walleij 2019-01-25  267  	}
5b978c10665973 Linus Walleij 2019-01-25  268  
5b978c10665973 Linus Walleij 2019-01-25  269  	ixi->irqchip.name = "IXP4xx";
5b978c10665973 Linus Walleij 2019-01-25  270  	ixi->irqchip.irq_mask = ixp4xx_irq_mask;
5b978c10665973 Linus Walleij 2019-01-25  271  	ixi->irqchip.irq_unmask	= ixp4xx_irq_unmask;
5b978c10665973 Linus Walleij 2019-01-25  272  	ixi->irqchip.irq_set_type = ixp4xx_set_irq_type;
5b978c10665973 Linus Walleij 2019-01-25  273  
5b978c10665973 Linus Walleij 2019-01-25  274  	ixi->domain = irq_domain_create_linear(fwnode, nr_irqs,
5b978c10665973 Linus Walleij 2019-01-25  275  					       &ixp4xx_irqdomain_ops,
5b978c10665973 Linus Walleij 2019-01-25  276  					       ixi);
5b978c10665973 Linus Walleij 2019-01-25  277  	if (!ixi->domain) {
5b978c10665973 Linus Walleij 2019-01-25  278  		pr_crit("IXP4XX: can not add primary irqdomain\n");
5b978c10665973 Linus Walleij 2019-01-25  279  		return -ENODEV;
5b978c10665973 Linus Walleij 2019-01-25  280  	}
5b978c10665973 Linus Walleij 2019-01-25  281  
5b978c10665973 Linus Walleij 2019-01-25  282  	set_handle_irq(ixp4xx_handle_irq);
5b978c10665973 Linus Walleij 2019-01-25  283  
5b978c10665973 Linus Walleij 2019-01-25  284  	return 0;
5b978c10665973 Linus Walleij 2019-01-25  285  }
5b978c10665973 Linus Walleij 2019-01-25  286  
f1497f3d06ad30 Linus Walleij 2019-01-27 @287  int __init ixp4xx_of_init_irq(struct device_node *np,

:::::: The code at line 210 was first introduced by commit
:::::: 5b978c10665973d8ee7050b03ef6e97013066b03 irqchip: Add driver for IXP4xx

:::::: TO: Linus Walleij <linus.walleij at linaro.org>
:::::: CC: Linus Walleij <linus.walleij at linaro.org>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From pr-tracker-bot at kernel.org  Sat Jan 29 04:51:48 2022
From: pr-tracker-bot at kernel.org (pr-tracker-bot at kernel.org)
Date: Sat, 29 Jan 2022 12:51:48 +0000
Subject: [GIT PULL] arm64 fixes for 5.17-rc2
In-Reply-To: <YfRAlb4M0Su+iyow@arm.com>
References: <YfRAlb4M0Su+iyow@arm.com>
Message-ID: <164346070840.2828.7233492612070791271.pr-tracker-bot@kernel.org>

The pull request you sent on Fri, 28 Jan 2022 19:14:29 +0000:

> git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux tags/arm64-fixes

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/216e2aede2b575016bd579e0c23661bbdbbaada7

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html


From lkp at intel.com  Sat Jan 29 06:51:33 2022
From: lkp at intel.com (kernel test robot)
Date: Sat, 29 Jan 2022 22:51:33 +0800
Subject: [linusw-nomadik:ixp4xx-cleanup-v5.17-rc1] BUILD SUCCESS WITH
 WARNING c9bbd09b3066286f881709c58d82c55724840bbb
Message-ID: <61f55475.3xBxU6pd/EoCP6E1%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-cleanup-v5.17-rc1
branch HEAD: c9bbd09b3066286f881709c58d82c55724840bbb  clocksource/drivers/ixp4xx: Drop boardfile probe path

Warning reports:

https://lore.kernel.org/linux-arm-kernel/202201292056.2xCamI4I-lkp at intel.com

Warning in current branch:

drivers/irqchip/irq-ixp4xx.c:210:38: warning: unused variable 'ixp4xx_irq_chunks' [-Wunused-const-variable]

Warning ids grouped by kconfigs:

clang_recent_errors
`-- arm-buildonly-randconfig-r001-20220127
    `-- drivers-irqchip-irq-ixp4xx.c:warning:unused-variable-ixp4xx_irq_chunks

elapsed time: 726m

configs tested: 153
configs skipped: 3

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                 randconfig-c001-20220124
sh                             sh03_defconfig
ia64                        generic_defconfig
sh                        edosk7760_defconfig
sh                             espt_defconfig
um                                  defconfig
arm                         axm55xx_defconfig
powerpc                      pcm030_defconfig
xtensa                           alldefconfig
arm                          pxa3xx_defconfig
m68k                                defconfig
arm                       aspeed_g5_defconfig
arm                         vf610m4_defconfig
arm                           tegra_defconfig
h8300                               defconfig
arm                         cm_x300_defconfig
sh                           se7751_defconfig
sparc                               defconfig
powerpc                      ppc6xx_defconfig
arc                           tb10x_defconfig
mips                           xway_defconfig
mips                 decstation_r4k_defconfig
m68k                          multi_defconfig
powerpc                      ep88xc_defconfig
powerpc                     ep8248e_defconfig
m68k                        stmark2_defconfig
powerpc                 mpc834x_itx_defconfig
arm                        shmobile_defconfig
mips                     decstation_defconfig
arm                         lubbock_defconfig
arm                          iop32x_defconfig
openrisc                         alldefconfig
arc                 nsimosci_hs_smp_defconfig
powerpc                     sequoia_defconfig
m68k                           sun3_defconfig
powerpc                 mpc834x_mds_defconfig
powerpc                     rainier_defconfig
arm                          badge4_defconfig
sh                           se7705_defconfig
xtensa                    smp_lx200_defconfig
arm                        mini2440_defconfig
sh                           se7343_defconfig
sh                          polaris_defconfig
sh                           se7712_defconfig
xtensa                  audio_kc705_defconfig
mips                        vocore2_defconfig
powerpc                     asp8347_defconfig
mips                           ip32_defconfig
arm                  randconfig-c002-20220127
arm                  randconfig-c002-20220124
arm                  randconfig-c002-20220129
ia64                                defconfig
ia64                             allyesconfig
ia64                             allmodconfig
m68k                             allmodconfig
m68k                             allyesconfig
nios2                               defconfig
arc                              allyesconfig
nds32                             allnoconfig
csky                                defconfig
alpha                               defconfig
nds32                               defconfig
nios2                            allyesconfig
alpha                            allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
sh                               allmodconfig
parisc                              defconfig
s390                             allyesconfig
s390                             allmodconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
i386                                defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                          allyesconfig
powerpc                          allmodconfig
powerpc                           allnoconfig
x86_64               randconfig-a002-20220124
x86_64               randconfig-a003-20220124
x86_64               randconfig-a001-20220124
x86_64               randconfig-a004-20220124
x86_64               randconfig-a005-20220124
x86_64               randconfig-a006-20220124
i386                 randconfig-a002-20220124
i386                 randconfig-a005-20220124
i386                 randconfig-a003-20220124
i386                 randconfig-a004-20220124
i386                 randconfig-a001-20220124
i386                 randconfig-a006-20220124
i386                          randconfig-a003
i386                          randconfig-a001
i386                          randconfig-a005
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
um                             i386_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                    rhel-8.3-kselftests
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
x86_64                        randconfig-c007
riscv                randconfig-c006-20220129
arm                  randconfig-c002-20220129
powerpc              randconfig-c003-20220129
mips                 randconfig-c004-20220129
i386                          randconfig-c001
s390                 randconfig-c005-20220129
arm                        vexpress_defconfig
arm                         orion5x_defconfig
powerpc                      ppc44x_defconfig
i386                          randconfig-a002
i386                          randconfig-a006
i386                          randconfig-a004
x86_64               randconfig-a011-20220124
x86_64               randconfig-a013-20220124
x86_64               randconfig-a015-20220124
x86_64               randconfig-a016-20220124
x86_64               randconfig-a014-20220124
x86_64               randconfig-a012-20220124
i386                 randconfig-a011-20220124
i386                 randconfig-a016-20220124
i386                 randconfig-a013-20220124
i386                 randconfig-a014-20220124
i386                 randconfig-a015-20220124
i386                 randconfig-a012-20220124
riscv                randconfig-r042-20220124
hexagon              randconfig-r045-20220124
hexagon              randconfig-r045-20220127
hexagon              randconfig-r041-20220124
hexagon              randconfig-r041-20220127
riscv                randconfig-r042-20220126
hexagon              randconfig-r045-20220126
hexagon              randconfig-r041-20220126
s390                 randconfig-r044-20220124
hexagon              randconfig-r045-20220125
hexagon              randconfig-r041-20220125

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From heiko at sntech.de  Sat Jan 29 07:28:09 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 29 Jan 2022 16:28:09 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <64f539b5-30b2-c0b7-17bf-c448b507713e@wolfvision.net>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
 <FBB7C392-C5E0-4E34-AC17-5323414623F5@gmail.com>
 <64f539b5-30b2-c0b7-17bf-c448b507713e@wolfvision.net>
Message-ID: <3736463.EBuT6JFcjP@diego>

Am Samstag, 29. Januar 2022, 10:59:32 CET schrieb Michael Riesch:
> Hello Peter and Piotr,
> 
> On 1/29/22 10:23, Piotr Oniszczuk wrote:
> > 
> > 
> >>
> >> Good Evening,
> >>
> >> While I'm not against this idea, my main concern still stands.
> >> I spent a great deal of thought on this, and decided to go the route I
> >> did to maintain consistency with previous generations.
> >> As such, I see one of three paths here:
> >> - Pull this patch only and depart rk356x from previous SoCs.
> >> - Do the same for previous SoCs to maintain consistency.
> >> - Drop this patch to maintain consistency with previous SoCs.
> >>
> >> I ask that others weigh in here, as offline discussion has produced
> >> mixed results already.
> > 
> > just pure user perspective
> > 
> > (who spent last weeks considerable time to develop DT for rk3566 tvbox. 99% of my work was by reading/learning from other boards existing DT's. Any inconsistencies in DTs makes work for such ppl like me much more harder):
> > 
> > For option 1 - i don't see value
> > For option 2 - what is reward for extra work needs to be done on all other SoCs?
> > 
> > so option 3 seems to be natural choice...
> > 
> > in other words:
> > 
> > for me:
> > option 1 brings practically zero value + increased inconsistency.
> > option 2: extra work - but consistency is like in option 3 (so where is value?)
> > 
> > so option 3 offers the same consistency - but without extra work...
> >  
> > just my 0.02$
> 
> Of course this change is purely cosmetic and it is reasonable to ask for
> the practical value. It is just that technically the quartz64 dts is not
> sorted alphabetically at the moment. The u2phy* nodes should be but
> before the uart* nodes to follow the convention. On the other hand, it
> may be nice to have the usb2 phys and controllers grouped in the dts.
> The proposed renaming would allow all the mentioned nodes sorted
> alphabetically and grouped logically.
> 
> Therefore I had option 1 in mind. I don't see any dependencies between
> the different SoCs and think we can make a fresh start here.

correct :-) .

I do see each SoC individually and while I try to have people follow some
styling guidelines everywhere (ordering of properties, ordering of nodes)
I don't really want people to fear what some other SoC has done before.

But even these rules evolve sometimes, when something seems to work
better than before.

We have nowadays 9 years of Rockchip SoC history in the kernel.
Thanks to general dt-binding conventions most nodes have specific
names anyway (mmc at ... etc), but for example trying to rename stuff
in older SoCs that has worked for years now is for one error-prone
as Michael pointed out, but also introduces unnecessary churn,
when these old SoCs (thinking of rk3188, rk3288 and friends but also things
like the rk3368) are essentially "finished" and most likely won't see that
much additional support for stuff added.


Heiko


> Option 2 is not really feasible, we would almost definitely break
> something existent.
> 
> Option 3 is feasible, of course. However, I would sort the nodes
> alphabetically (u2phy*, then uart*, then usb*). Works for me as well,
> although it is not that nice IMHO.
> 
> Since many boards with the RK3566 and RK3568 will pop up in near future
> we should do the change right now (if we want to do it), as of course
> all the board files need to be changed. Therefore I wanted to bring this
> matter up now. Let's agree on something and move on.
> 
> Best regards,
> Michael
> 






From baltazar.radics at gmail.com  Sat Jan 29 07:42:14 2022
From: baltazar.radics at gmail.com (=?UTF-8?q?Baltaz=C3=A1r=20Radics?=)
Date: Sat, 29 Jan 2022 16:42:14 +0100
Subject: [PATCH] Add ethernet0 alias in Nanopi NEO's device tree
Message-ID: <20220129154214.45629-1-baltazar.radics@gmail.com>

This is required for U-Boot to generate a MAC address for it
automatically.
(Without this, the MAC address will be random on each boot.)

Signed-off-by: Baltaz?r Radics <baltazar.radics at gmail.com>
---
 arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
index 9f33f6fae5..df71fab3cf 100644
--- a/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
+++ b/arch/arm/boot/dts/sun8i-h3-nanopi-neo.dts
@@ -45,6 +45,10 @@
 / {
 	model = "FriendlyARM NanoPi NEO";
 	compatible = "friendlyarm,nanopi-neo", "allwinner,sun8i-h3";
+
+	aliases {
+		ethernet0 = &emac;
+	};
 };
 
 &ehci0 {
-- 
2.35.1



From jernej.skrabec at gmail.com  Sat Jan 29 08:10:45 2022
From: jernej.skrabec at gmail.com (Jernej =?utf-8?B?xaBrcmFiZWM=?=)
Date: Sat, 29 Jan 2022 17:10:45 +0100
Subject: [PATCH] Add ethernet0 alias in Nanopi NEO's device tree
In-Reply-To: <20220129154214.45629-1-baltazar.radics@gmail.com>
References: <20220129154214.45629-1-baltazar.radics@gmail.com>
Message-ID: <5534722.DvuYhMxLoT@kista>

Hi!

Dne sobota, 29. januar 2022 ob 16:42:14 CET je Baltaz?r Radics napisal(a):
> This is required for U-Boot to generate a MAC address for it
> automatically.
> (Without this, the MAC address will be random on each boot.)
> 
> Signed-off-by: Baltaz?r Radics <baltazar.radics at gmail.com>

Acked-by: Jernej Skrabec <jernej.skrabec at gmail.com>

Thanks!

Best regards,
Jernej




From ardb at kernel.org  Sat Jan 29 08:19:42 2022
From: ardb at kernel.org (Ard Biesheuvel)
Date: Sat, 29 Jan 2022 17:19:42 +0100
Subject: [PATCH 1/3] memblock: define functions to set the usable memory
 range
In-Reply-To: <20220124210538.GA15943@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
References: <20220110210809.3528-1-fllinden@amazon.com>
 <20220110210809.3528-2-fllinden@amazon.com>
 <Yd1cnquQFZoNE7FP@kernel.org>
 <20220124210538.GA15943@dev-dsk-fllinden-2c-d7720709.us-west-2.amazon.com>
Message-ID: <CAMj1kXHSGGUhmAdOFzpHJrMjfts-AgdpVJ6LJRkmm9_xLL0guw@mail.gmail.com>

On Mon, 24 Jan 2022 at 22:05, Frank van der Linden <fllinden at amazon.com> wrote:
>
> Meanwhile, it seems that this issue was already addressed in:
>
> https://lore.kernel.org/all/20211215021348.8766-1-kernelfans at gmail.com/
>
> ..which has now been pulled in, and sent to stable@ for 5.15. I
> somehow missed that message, and sent my change in a few weeks
> later.
>
> The fix to just reserve the ranges does seem a bit cleaner overall,
> but this will do fine.
>

Works for me.


From michael.riesch at wolfvision.net  Sat Jan 29 08:24:39 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Sat, 29 Jan 2022 17:24:39 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: fix vcc3v3_lcd{0,
 1}_n regulators in rk3568-evb1-10
Message-ID: <20220129162440.5415-1-michael.riesch@wolfvision.net>

The voltages VCC3V3_LCD{0,1} can be enabled with the pins GPIO0_C7 and
GPIO0_C5, respectively. This patch modifies the device tree in order to
reflect this.

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 25 +++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 184e2aa2416a..197aaf7ee348 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -56,7 +56,13 @@ vcc5v0_sys: vcc5v0-sys {
 	vcc3v3_lcd0_n: vcc3v3-lcd0-n {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_lcd0_n";
-		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd0_n_en>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -66,7 +72,13 @@ regulator-state-mem {
 	vcc3v3_lcd1_n: vcc3v3-lcd1-n {
 		compatible = "regulator-fixed";
 		regulator-name = "vcc3v3_lcd1_n";
-		regulator-boot-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		gpio = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&vcc3v3_sys>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&vcc3v3_lcd1_n_en>;
 
 		regulator-state-mem {
 			regulator-off-in-suspend;
@@ -339,6 +351,15 @@ rgmii_phy1: ethernet-phy at 0 {
 };
 
 &pinctrl {
+	display {
+		vcc3v3_lcd0_n_en: vcc3v3_lcd0_n_en {
+			rockchip,pins = <0 RK_PC7 0 &pcfg_pull_none>;
+		};
+		vcc3v3_lcd1_n_en: vcc3v3_lcd1_n_en {
+			rockchip,pins = <0 RK_PC5 0 &pcfg_pull_none>;
+		};
+	};
+
 	pmic {
 		pmic_int: pmic_int {
 			rockchip,pins =
-- 
2.30.2



From michael.riesch at wolfvision.net  Sat Jan 29 08:24:40 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Sat, 29 Jan 2022 17:24:40 +0100
Subject: [PATCH 2/2] arm64: dts: rockchip: add the touchscreen controller to
 rk3568-evb1-v10
In-Reply-To: <20220129162440.5415-1-michael.riesch@wolfvision.net>
References: <20220129162440.5415-1-michael.riesch@wolfvision.net>
Message-ID: <20220129162440.5415-2-michael.riesch@wolfvision.net>

The Rockchip RK3568 EVB1 comes with a mounted touch display featuring
a Goodix GT1158 touch controller (according to the product ID register).

Signed-off-by: Michael Riesch <michael.riesch at wolfvision.net>
---
 .../boot/dts/rockchip/rk3568-evb1-v10.dts     | 26 +++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
index 197aaf7ee348..d8c20a23e856 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -330,6 +330,23 @@ regulator-state-mem {
 	};
 };
 
+&i2c1 {
+	status = "okay";
+
+	touchscreen0: goodix at 14 {
+		compatible = "goodix,gt1151";
+		reg = <0x14>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB5 IRQ_TYPE_EDGE_FALLING>;
+		AVDD28-supply = <&vcc3v3_lcd0_n>;
+		irq-gpios = <&gpio0 RK_PB5 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&touch_int &touch_rst>;
+		reset-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
+		VDDIO-supply = <&vcc3v3_lcd0_n>;
+	};
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy at 0 {
 		compatible = "ethernet-phy-ieee802.3-c22";
@@ -366,6 +383,15 @@ pmic_int: pmic_int {
 				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
+
+	touchscreen {
+		touch_int: touch_int {
+			rockchip,pins = <0 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+		touch_rst: touch_rst {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
 };
 
 &pmu_io_domains {
-- 
2.30.2



From rdunlap at infradead.org  Sat Jan 29 09:03:23 2022
From: rdunlap at infradead.org (Randy Dunlap)
Date: Sat, 29 Jan 2022 09:03:23 -0800
Subject: [PATCH 4/8] arm64: Add Kconfig/Makefile to build hardware
 prefetch control driver
In-Reply-To: <20220125071414.811344-5-tarumizu.kohei@fujitsu.com>
References: <20220125071414.811344-1-tarumizu.kohei@fujitsu.com>
 <20220125071414.811344-5-tarumizu.kohei@fujitsu.com>
Message-ID: <964539a8-334d-37d4-99e7-d2dd76887fa1@infradead.org>

Hi--

On 1/24/22 23:14, Kohei Tarumizu wrote:
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 6978140edfa4..c2256dbb0243 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig

>  	def_bool y
>  	depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_SYSREG
>  
> +config ARM64_HWPF_CONTROL
> +	tristate "ARM64 Hardware Prefetch Control support"
> +	depends on HWPF_CONTROL
> +	default m

Don't enable random drivers unless they are required for booting etc.
So can you justify having this driver enabled by default?

I see that the X86 driver is not enabled by default.

> +	help
> +	  This adds Hardware Prefetch Control driver support for ARM64.

thanks.
-- 
~Randy


From heiko at sntech.de  Sat Jan 29 09:48:13 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sat, 29 Jan 2022 18:48:13 +0100
Subject: [PATCH 24/27] clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop*
In-Reply-To: <20220126145549.617165-25-s.hauer@pengutronix.de>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-25-s.hauer@pengutronix.de>
Message-ID: <5329207.qDA9hNt6id@diego>

Am Mittwoch, 26. Januar 2022, 15:55:46 CET schrieb Sascha Hauer:
> The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or
> cpll. gpll and cpll also drive many other clocks, so changing the
> dclk_vop[012] clocks could change these other clocks as well. Drop
> CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can
> only adjust the pixel clocks with the divider between the PLL and the
> dclk_vop[012] which means the user may have to adjust the PLL clock to a
> suitable rate using the assigned-clock-rate device tree property.
> 
> Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> ---
>  drivers/clk/rockchip/clk-rk3568.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
> index 9d889fc46811..7687c62d1fa8 100644
> --- a/drivers/clk/rockchip/clk-rk3568.c
> +++ b/drivers/clk/rockchip/clk-rk3568.c
> @@ -1044,13 +1044,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
>  			RK3568_CLKGATE_CON(20), 8, GFLAGS),
>  	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
>  			RK3568_CLKGATE_CON(20), 9, GFLAGS),
> -	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,

hmm, I'm wondering about the use of having CLK_SET_RATE_NO_REPARENT here
(and even adding it below).

Using SET_RATE_PARENT in the following patch for the hdmi-pll, should give
us at least a suitable rate for the hdmi output, so the vop using that
should already find a nice rate to use.

The normal system-PLLs don't normally don't change their rate at runtime,
so I think we should liberate the dclks to select a PLL that best matches
their target rate - so drop the CLK_SET_RATE_NO_REPARENT as well.

That way the DCLKs can change to another PLL source if that provides
a rate nearer to their target.

Heiko

>  			RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
>  			RK3568_CLKGATE_CON(20), 10, GFLAGS),
> -	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> +	COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
>  			RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
>  			RK3568_CLKGATE_CON(20), 11, GFLAGS),
> -	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
> +	COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
>  			RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
>  			RK3568_CLKGATE_CON(20), 12, GFLAGS),
>  	GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0,
> 






From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:53:32 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:53:32 +0100
Subject: [PATCH 5/5] dt-bindings: serial: samsung_uart: Document Exynos5433
 compatible
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129175332.298666-5-krzysztof.kozlowski@canonical.com>

Document the Exynos5433 UART compatible, supported since commit
31ec77aca72e ("serial: samsung: Add the support for Exynos5433 SoC").

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 Documentation/devicetree/bindings/serial/samsung_uart.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
index 2940afb874b3..6aceba4a5f79 100644
--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
@@ -26,6 +26,7 @@ properties:
           - samsung,s3c6400-uart
           - samsung,s5pv210-uart
           - samsung,exynos4210-uart
+          - samsung,exynos5433-uart
           - samsung,exynos850-uart
 
   reg:
@@ -111,6 +112,7 @@ allOf:
             enum:
               - apple,s5l-uart
               - samsung,exynos4210-uart
+              - samsung,exynos5433-uart
     then:
       properties:
         clocks:
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:53:28 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:53:28 +0100
Subject: [PATCH 1/5] arm64: dts: exynos: align pl330 node name with dtschema
Message-ID: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>

Fixes dtbs_check warnings like:

  pdma at 15610000: $nodename:0: 'pdma at 15610000' does not match '^dma-controller(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 6 +++---
 arch/arm64/boot/dts/exynos/exynos7.dtsi    | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index bfe4ed8a23d6..b4cde77e02d3 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1858,7 +1858,7 @@ mshc_2: mshc at 15560000 {
 			status = "disabled";
 		};
 
-		pdma0: pdma at 15610000 {
+		pdma0: dma-controller at 15610000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x15610000 0x1000>;
 			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
@@ -1869,7 +1869,7 @@ pdma0: pdma at 15610000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 15600000 {
+		pdma1: dma-controller at 15600000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x15600000 0x1000>;
 			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
@@ -1891,7 +1891,7 @@ audio-subsystem at 11400000 {
 			#size-cells = <1>;
 			ranges;
 
-			adma: adma at 11420000 {
+			adma: dma-controller at 11420000 {
 				compatible = "arm,pl330", "arm,primecell";
 				reg = <0x11420000 0x1000>;
 				interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 960823b8247a..3364b09c3158 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -142,7 +142,7 @@ gic: interrupt-controller at 11001000 {
 				<0x11006000 0x2000>;
 		};
 
-		pdma0: pdma at 10e10000 {
+		pdma0: dma-controller at 10e10000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x10E10000 0x1000>;
 			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
@@ -153,7 +153,7 @@ pdma0: pdma at 10e10000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 10eb0000 {
+		pdma1: dma-controller at 10eb0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x10EB0000 0x1000>;
 			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:53:30 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:53:30 +0100
Subject: [PATCH 3/5] mfd: exynos-lpass: Drop unneeded syscon.h include
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129175332.298666-3-krzysztof.kozlowski@canonical.com>

syscon regmap is not used since commit addebf1588ab ("mfd: exynos-lpass:
Remove pad retention control").

Fixes: addebf1588ab ("mfd: exynos-lpass: Remove pad retention control")
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 drivers/mfd/exynos-lpass.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c
index 99bd0e73c19c..166cd21088cd 100644
--- a/drivers/mfd/exynos-lpass.c
+++ b/drivers/mfd/exynos-lpass.c
@@ -15,7 +15,6 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/module.h>
-#include <linux/mfd/syscon.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:53:29 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:53:29 +0100
Subject: [PATCH 2/5] arm64: dts: exynos: drop unneeded syscon phandle in
 Exynos5433 LPASS
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129175332.298666-2-krzysztof.kozlowski@canonical.com>

Exynos5433 LPASS audio node does not use syscon phandle since commit
addebf1588ab ("mfd: exynos-lpass: Remove pad retention control").  It
was also dropped from bindings.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos5433.dtsi | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
index b4cde77e02d3..661567d2dd7a 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -1885,7 +1885,6 @@ audio-subsystem at 11400000 {
 			reg = <0x11400000 0x100>, <0x11500000 0x08>;
 			clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
 			clock-names = "sfr0_ctrl";
-			samsung,pmu-syscon = <&pmu_system_controller>;
 			power-domains = <&pd_aud>;
 			#address-cells = <1>;
 			#size-cells = <1>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:53:31 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:53:31 +0100
Subject: [PATCH 4/5] dt-bindings: mfd: samsung,
 exynos5433-lpass: Convert to dtschema
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129175332.298666-4-krzysztof.kozlowski@canonical.com>

Convert the Exynos5433 LPASS bindings to DT schema format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/mfd/samsung,exynos5433-lpass.txt |  72 -----------
 .../mfd/samsung,exynos5433-lpass.yaml         | 119 ++++++++++++++++++
 2 files changed, 119 insertions(+), 72 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
 create mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml

diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
deleted file mode 100644
index 30ea27c3936d..000000000000
--- a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
-
-Required properties:
-
- - compatible		: "samsung,exynos5433-lpass"
- - reg			: should contain the LPASS top SFR region location
-			  and size
- - clock-names		: should contain following required clocks: "sfr0_ctrl"
- - clocks		: should contain clock specifiers of all clocks, which
-			  input names have been specified in clock-names
-			  property, in same order.
- - #address-cells	: should be 1
- - #size-cells		: should be 1
- - ranges		: must be present
-
-Each IP block of the Low Power Audio Subsystem should be specified as
-an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes:
-UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices.
-
-Bindings of the sub-nodes are described in:
-  ../serial/samsung_uart.yaml
-  ../sound/samsung-i2s.txt
-  ../dma/arm-pl330.txt
-
-
-Example:
-
-audio-subsystem {
-	compatible = "samsung,exynos5433-lpass";
-	reg = <0x11400000 0x100>, <0x11500000 0x08>;
-	clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
-	clock-names = "sfr0_ctrl";
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges;
-
-	adma: adma at 11420000 {
-		compatible = "arm,pl330", "arm,primecell";
-		reg = <0x11420000 0x1000>;
-		interrupts = <0 73 0>;
-		clocks = <&cmu_aud CLK_ACLK_DMAC>;
-		clock-names = "apb_pclk";
-		#dma-cells = <1>;
-		#dma-channels = <8>;
-		#dma-requests = <32>;
-	};
-
-	i2s0: i2s0 at 11440000 {
-		compatible = "samsung,exynos7-i2s";
-		reg = <0x11440000 0x100>;
-		dmas = <&adma 0 &adma 2>;
-		dma-names = "tx", "rx";
-		interrupts = <0 70 0>;
-		clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
-			 <&cmu_aud CLK_SCLK_AUD_I2S>,
-			 <&cmu_aud CLK_SCLK_I2S_BCLK>;
-		clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
-		pinctrl-names = "default";
-		pinctrl-0 = <&i2s0_bus>;
-	};
-
-	serial_3: serial at 11460000 {
-		compatible = "samsung,exynos5433-uart";
-		reg = <0x11460000 0x100>;
-		interrupts = <0 67 0>;
-		clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
-			 <&cmu_aud CLK_SCLK_AUD_UART>;
-		clock-names = "uart", "clk_uart_baud0";
-		pinctrl-names = "default";
-		pinctrl-0 = <&uart_aud_bus>;
-	};
- };
diff --git a/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
new file mode 100644
index 000000000000..96ef6113c8bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/samsung,exynos5433-lpass.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC Low Power Audio Subsystem (LPASS)
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+properties:
+  compatible:
+    const: samsung,exynos5433-lpass
+
+  '#address-cells':
+    const: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: sfr0_ctrl
+
+  power-domains:
+    maxItems: 1
+
+  ranges: true
+
+  reg:
+    minItems: 2
+    maxItems: 2
+
+  '#size-cells':
+    const: 1
+
+patternProperties:
+  "^dma-controller@[0-9a-f]+$":
+    $ref: /schemas/dma/arm,pl330.yaml
+
+  "^i2s@[0-9a-f]+$":
+    $ref: /schemas/sound/samsung-i2s.yaml
+
+  "^serial@[0-9a-f]+$":
+    $ref: /schemas/serial/samsung_uart.yaml
+
+required:
+  - compatible
+  - '#address-cells'
+  - clocks
+  - clock-names
+  - ranges
+  - reg
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5433.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    audio-subsystem at 11400000 {
+        compatible = "samsung,exynos5433-lpass";
+        reg = <0x11400000 0x100>, <0x11500000 0x08>;
+        clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
+        clock-names = "sfr0_ctrl";
+        power-domains = <&pd_aud>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        dma-controller at 11420000 {
+            compatible = "arm,pl330", "arm,primecell";
+            reg = <0x11420000 0x1000>;
+            interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cmu_aud CLK_ACLK_DMAC>;
+            clock-names = "apb_pclk";
+            #dma-cells = <1>;
+            #dma-channels = <8>;
+            #dma-requests = <32>;
+            power-domains = <&pd_aud>;
+        };
+
+        i2s at 11440000 {
+            compatible = "samsung,exynos7-i2s";
+            reg = <0x11440000 0x100>;
+            dmas = <&adma 0>, <&adma 2>;
+            dma-names = "tx", "rx";
+            interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+            clocks = <&cmu_aud CLK_PCLK_AUD_I2S>,
+                     <&cmu_aud CLK_SCLK_AUD_I2S>,
+                     <&cmu_aud CLK_SCLK_I2S_BCLK>;
+            clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
+            #clock-cells = <1>;
+            pinctrl-names = "default";
+            pinctrl-0 = <&i2s0_bus>;
+            power-domains = <&pd_aud>;
+            #sound-dai-cells = <1>;
+            status = "disabled";
+        };
+
+        serial at 11460000 {
+            compatible = "samsung,exynos5433-uart";
+            reg = <0x11460000 0x100>;
+            interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&cmu_aud CLK_PCLK_AUD_UART>,
+                     <&cmu_aud CLK_SCLK_AUD_UART>;
+            clock-names = "uart", "clk_uart_baud0";
+            pinctrl-names = "default";
+            pinctrl-0 = <&uart_aud_bus>;
+            power-domains = <&pd_aud>;
+            status = "disabled";
+        };
+    };
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:54:29 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:54:29 +0100
Subject: [PATCH] arm64: dts: rockchip: align pl330 node name with dtschema
Message-ID: <20220129175429.298836-1-krzysztof.kozlowski@canonical.com>

Fixes dtbs_check warnings like:

  dmac at ff240000: $nodename:0: 'dmac at ff240000' does not match '^dma-controller(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/rockchip/px30.dtsi   | 2 +-
 arch/arm64/boot/dts/rockchip/rk3328.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/rockchip/px30.dtsi b/arch/arm64/boot/dts/rockchip/px30.dtsi
index f972704dfe7a..56dfbb2e2fa6 100644
--- a/arch/arm64/boot/dts/rockchip/px30.dtsi
+++ b/arch/arm64/boot/dts/rockchip/px30.dtsi
@@ -711,7 +711,7 @@ rktimer: timer at ff210000 {
 		clock-names = "pclk", "timer";
 	};
 
-	dmac: dmac at ff240000 {
+	dmac: dma-controller at ff240000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xff240000 0x0 0x4000>;
 		interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
index 39db0b85b4da..b822533dc7f1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -489,7 +489,7 @@ pwm3: pwm at ff1b0030 {
 		status = "disabled";
 	};
 
-	dmac: dmac at ff1f0000 {
+	dmac: dma-controller at ff1f0000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xff1f0000 0x0 0x4000>;
 		interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:55:13 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:55:13 +0100
Subject: [PATCH 1/2] arm64: dts: lg: add dma-cells to pl330 node
Message-ID: <20220129175514.298942-1-krzysztof.kozlowski@canonical.com>

dma-cells property is required for dma-controller.  Fixes dtbs_check
warnings like:

  dma at c1128000: '#dma-cells' is a required property

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/lg/lg1312.dtsi | 1 +
 arch/arm64/boot/dts/lg/lg1313.dtsi | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi
index 081fe7a9f605..ef57df716f14 100644
--- a/arch/arm64/boot/dts/lg/lg1312.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1312.dtsi
@@ -188,6 +188,7 @@ dmac0: dma at c1128000 {
 			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clk_bus>;
 			clock-names = "apb_pclk";
+			#dma-cells = <1>;
 		};
 		gpio0: gpio at fd400000 {
 			#gpio-cells = <2>;
diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi
index 604bb6975337..4e6b65939b72 100644
--- a/arch/arm64/boot/dts/lg/lg1313.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1313.dtsi
@@ -188,6 +188,7 @@ dmac0: dma at c1128000 {
 			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&clk_bus>;
 			clock-names = "apb_pclk";
+			#dma-cells = <1>;
 		};
 		gpio0: gpio at fd400000 {
 			#gpio-cells = <2>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:55:14 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:55:14 +0100
Subject: [PATCH 2/2] arm64: dts: lg: align pl330 node name with dtschema
In-Reply-To: <20220129175514.298942-1-krzysztof.kozlowski@canonical.com>
References: <20220129175514.298942-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129175514.298942-2-krzysztof.kozlowski@canonical.com>

Fixes dtbs_check warnings like:

  dma at c1128000: $nodename:0: 'dma at c1128000' does not match '^dma-controller(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/lg/lg1312.dtsi | 2 +-
 arch/arm64/boot/dts/lg/lg1313.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/lg/lg1312.dtsi b/arch/arm64/boot/dts/lg/lg1312.dtsi
index ef57df716f14..bec97480a960 100644
--- a/arch/arm64/boot/dts/lg/lg1312.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1312.dtsi
@@ -182,7 +182,7 @@ spi1: spi at fe900000 {
 			clocks = <&clk_bus>;
 			clock-names = "apb_pclk";
 		};
-		dmac0: dma at c1128000 {
+		dmac0: dma-controller at c1128000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x0 0xc1128000 0x1000>;
 			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/lg/lg1313.dtsi b/arch/arm64/boot/dts/lg/lg1313.dtsi
index 4e6b65939b72..ada3d4dc6305 100644
--- a/arch/arm64/boot/dts/lg/lg1313.dtsi
+++ b/arch/arm64/boot/dts/lg/lg1313.dtsi
@@ -182,7 +182,7 @@ spi1: spi at fe900000 {
 			clocks = <&clk_bus>;
 			clock-names = "apb_pclk";
 		};
-		dmac0: dma at c1128000 {
+		dmac0: dma-controller at c1128000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x0 0xc1128000 0x1000>;
 			interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:55:57 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:55:57 +0100
Subject: [PATCH] arm64: dts: broadcom: align pl330 node name with dtschema
Message-ID: <20220129175557.299166-1-krzysztof.kozlowski@canonical.com>

Fixes dtbs_check warnings like:

  dma at 310000: $nodename:0: 'dma at 310000' does not match '^dma-controller(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi    | 2 +-
 arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
index 2cfeaf3b0a87..6da38ac317f2 100644
--- a/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
+++ b/arch/arm64/boot/dts/broadcom/northstar2/ns2.dtsi
@@ -276,7 +276,7 @@ crypto3: crypto at 61330000 {
 			mboxes = <&pdc3 0>;
 		};
 
-		dma0: dma at 61360000 {
+		dma0: dma-controller at 61360000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x61360000 0x1000>;
 			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
index 7b04dfe67bef..4135246b6e72 100644
--- a/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
+++ b/arch/arm64/boot/dts/broadcom/stingray/stingray.dtsi
@@ -543,7 +543,7 @@ hwrng: hwrng at 220000 {
 			reg = <0x00220000 0x28>;
 		};
 
-		dma0: dma at 310000 {
+		dma0: dma-controller at 310000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x00310000 0x1000>;
 			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>,
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 09:56:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 18:56:21 +0100
Subject: [PATCH] arm64: dts: juno: align pl330 node name with dtschema
Message-ID: <20220129175621.299254-1-krzysztof.kozlowski@canonical.com>

Fixes dtbs_check warning:

  dma at 7ff00000: $nodename:0: 'dma at 7ff00000' does not match '^dma-controller(@.*)?$'

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/arm/juno-base.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
index 6288e104a089..af499049cb00 100644
--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
+++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
@@ -672,7 +672,7 @@ smmu_usb: iommu at 7fb30000 {
 		dma-coherent;
 	};
 
-	dma at 7ff00000 {
+	dma-controller at 7ff00000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0x7ff00000 0 0x1000>;
 		#dma-cells = <1>;
-- 
2.32.0



From heiko at sntech.de  Sat Jan 29 09:57:38 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 29 Jan 2022 18:57:38 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: fix vcc3v3_lcd{0,
 1}_n regulators in rk3568-evb1-10
In-Reply-To: <20220129162440.5415-1-michael.riesch@wolfvision.net>
References: <20220129162440.5415-1-michael.riesch@wolfvision.net>
Message-ID: <164347899463.1472860.17650444631712126787.b4-ty@sntech.de>

On Sat, 29 Jan 2022 17:24:39 +0100, Michael Riesch wrote:
> The voltages VCC3V3_LCD{0,1} can be enabled with the pins GPIO0_C7 and
> GPIO0_C5, respectively. This patch modifies the device tree in order to
> reflect this.

Applied, thanks!

[1/2] arm64: dts: rockchip: fix vcc3v3_lcd{0,1}_n regulators in rk3568-evb1-10
      commit: 9ade1ab4d85f5fc31a5d6cf5147702ed5c1b5b10
[2/2] arm64: dts: rockchip: add the touchscreen controller to rk3568-evb1-v10
      commit: 922237a6c211d9fe46b5dfb56307872cdced386d

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sat Jan 29 09:57:39 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 29 Jan 2022 18:57:39 +0100
Subject: [PATCH v2 0/4] Quartz64-A fixes and enablement from 5.17-rc1
In-Reply-To: <20220128003809.3291407-1-pgwipeout@gmail.com>
References: <20220128003809.3291407-1-pgwipeout@gmail.com>
Message-ID: <164347899463.1472860.246056649344007753.b4-ty@sntech.de>

On Thu, 27 Jan 2022 19:38:04 -0500, Peter Geis wrote:
> Good Evening,
> 
> This is the first of several patch series for further expanding
> Quartz64-A support.
> 
> This series has the following patches:
> Fix the ddr regulator voltage.
> Add pmu_io_domains to permit sdio and high speed emmc support.
> Add sdmmc1 node for wifi support.
> Annotate con40 functions and enable i2c3.
> 
> [...]

Applied, thanks!

[1/4] arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
      commit: 8c318aaa20000bcfb9dc115c2a8e08c2e77ad439
[2/4] arm64: dts: rockchip: add Quartz64-A pmu_io_domains
      commit: 827dfba89ae150cd0fd88bc13117540cb4882943
[3/4] arm64: dts: rockchip: add Quartz64-A sdmmc1 node
      commit: 2ed1e35457a1917a9c567c186a5adc7ce6341b6e

With a minimal reordering (sdio-* comes before spdif alphabetically)

[4/4] arm64: dts: rockchip: add Quartz64-A con40 hardware
      commit: 2943660fe301aa650cdf60226a2a350d09145823

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sat Jan 29 09:57:40 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 29 Jan 2022 18:57:40 +0100
Subject: [PATCH] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal
 integrity
In-Reply-To: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
References: <20220119134948.1444965-1-quentin.schulz@theobroma-systems.com>
Message-ID: <164347899463.1472860.17160610322270835288.b4-ty@sntech.de>

On Wed, 19 Jan 2022 14:49:48 +0100, quentin.schulz at theobroma-systems.com wrote:
> There are signal integrity issues running the eMMC at 200MHz on Puma
> RK3399-Q7.
> 
> Similar to the work-around found for RK3399 Gru boards, lowering the
> frequency to 100MHz made the eMMC much more stable, so let's lower the
> frequency to 100MHz.
> 
> [...]

Applied, thanks!

[1/1] arm64: dts: rockchip: fix rk3399-puma eMMC HS400 signal integrity
      commit: 7623e16af6bac131305292eb99cea988adbf0484

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From heiko at sntech.de  Sat Jan 29 10:01:17 2022
From: heiko at sntech.de (Heiko Stuebner)
Date: Sat, 29 Jan 2022 19:01:17 +0100
Subject: [PATCH] arm64: dts: rockchip: align pl330 node name with dtschema
In-Reply-To: <20220129175429.298836-1-krzysztof.kozlowski@canonical.com>
References: <20220129175429.298836-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164347927007.1475317.12886729868087154113.b4-ty@sntech.de>

On Sat, 29 Jan 2022 18:54:29 +0100, Krzysztof Kozlowski wrote:
> Fixes dtbs_check warnings like:
> 
>   dmac at ff240000: $nodename:0: 'dmac at ff240000' does not match '^dma-controller(@.*)?$'

Applied, thanks!

[1/1] arm64: dts: rockchip: align pl330 node name with dtschema
      commit: 3d7eaaa2fda44a5d11efdb1069664dba6ee49ee0

Best regards,
-- 
Heiko Stuebner <heiko at sntech.de>


From festevam at gmail.com  Sat Jan 29 10:54:26 2022
From: festevam at gmail.com (Fabio Estevam)
Date: Sat, 29 Jan 2022 15:54:26 -0300
Subject: [PATCH V2] media: imx: imx8mq-mipi_csi2: Remove unneeded code
In-Reply-To: <20220128170722.1624767-1-usama.anjum@collabora.com>
References: <20220128170722.1624767-1-usama.anjum@collabora.com>
Message-ID: <CAOMZO5CSE8bwASsk8_Z3J_i1rSKoiENx96_bLaYxQnvghgWtyw@mail.gmail.com>

On Fri, Jan 28, 2022 at 2:07 PM Muhammad Usama Anjum
<usama.anjum at collabora.com> wrote:
>
> ret is constant in imx8mq_mipi_csi_pm_suspend(). This function cannot
> return error. Remove the return variable. Simplify other functions which
> are using this function.
>
> Signed-off-by: Muhammad Usama Anjum <usama.anjum at collabora.com>
> ---
> Changes in V2:
> Removed fixes tag

Reviewed-by: Fabio Estevam <festevam at gmail.com>


From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:40 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:40 +0100
Subject: [PATCH 2/8] dt-bindings: phy: samsung: drop old Eynos5440 PCIe phy
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-2-krzysztof.kozlowski@canonical.com>

The Exynos5440 PCIe phy support was removed in commit 496db029142f
("phy: samsung: phy-exynos-pcie: rework driver to support Exynos5433
PCIe PHY") (with its own bindings), so drop the old bindings.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/phy/samsung-phy.txt     | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 8f51aee91101..390065f49b62 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -191,20 +191,3 @@ Example:
 		usbdrdphy0 = &usb3_phy0;
 		usbdrdphy1 = &usb3_phy1;
 	};
-
-Samsung Exynos SoC series PCIe PHY controller
---------------------------------------------------
-Required properties:
-- compatible : Should be set to "samsung,exynos5440-pcie-phy"
-- #phy-cells : Must be zero
-- reg : a register used by phy driver.
-	- First is for phy register, second is for block register.
-- reg-names : Must be set to "phy" and "block".
-
-Example:
-	pcie_phy0: pcie-phy at 270000 {
-		#phy-cells = <0>;
-		compatible = "samsung,exynos5440-pcie-phy";
-		reg = <0x270000 0x1000>, <0x271000 0x40>;
-		reg-names = "phy", "block";
-	};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:42 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:42 +0100
Subject: [PATCH 4/8] dt-bindings: phy: samsung,
 dp-video-phy: convert to dtschema
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-4-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC DisplayPort PHY bindings to DT schema format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/phy/samsung,dp-video-phy.yaml    | 41 +++++++++++++++++++
 .../devicetree/bindings/phy/samsung-phy.txt   | 11 -----
 2 files changed, 41 insertions(+), 11 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,dp-video-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/samsung,dp-video-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,dp-video-phy.yaml
new file mode 100644
index 000000000000..838c6d480ce6
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,dp-video-phy.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,dp-video-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC DisplayPort PHY
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5250-dp-video-phy
+      - samsung,exynos5420-dp-video-phy
+
+  "#phy-cells":
+    const: 0
+
+  samsung,pmu-syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface.
+
+required:
+  - compatible
+  - "#phy-cells"
+  - samsung,pmu-syscon
+
+additionalProperties: false
+
+examples:
+  - |
+    phy {
+        compatible = "samsung,exynos5420-dp-video-phy";
+        samsung,pmu-syscon = <&pmu_system_controller>;
+        #phy-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 6ab16734eb65..839ffe2a2d05 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -1,14 +1,3 @@
-Samsung Exynos SoC series Display Port PHY
--------------------------------------------------
-
-Required properties:
-- compatible : should be one of the following supported values:
-	 - "samsung,exynos5250-dp-video-phy"
-	 - "samsung,exynos5420-dp-video-phy"
-- samsung,pmu-syscon: phandle for PMU system controller interface, used to
-		      control pmu registers for power isolation.
-- #phy-cells : from the generic PHY bindings, must be 0;
-
 Samsung S5P/Exynos SoC series USB PHY
 -------------------------------------------------
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:41 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:41 +0100
Subject: [PATCH 3/8] dt-bindings: phy: samsung,
 mipi-video-phy: convert to dtschema
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-3-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC MIPI CSIS/DSIM DPHY bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/phy/samsung,mipi-video-phy.yaml  | 113 ++++++++++++++++++
 .../devicetree/bindings/phy/samsung-phy.txt   |  29 -----
 2 files changed, 113 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml
new file mode 100644
index 000000000000..54aa056b224d
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml
@@ -0,0 +1,113 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,mipi-video-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5P/Exynos SoC MIPI CSIS/DSIM DPHY
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+description: |
+  For samsung,s5pv210-mipi-video-phy compatible PHYs the second cell in the
+  PHY specifier identifies the PHY and its meaning is as follows::
+    0 - MIPI CSIS 0,
+    1 - MIPI DSIM 0,
+    2 - MIPI CSIS 1,
+    3 - MIPI DSIM 1.
+
+  samsung,exynos5420-mipi-video-phy and samsung,exynos5433-mipi-video-phy
+  support additional fifth PHY::
+    4 - MIPI CSIS 2.
+
+properties:
+  compatible:
+    enum:
+      - samsung,s5pv210-mipi-video-phy
+      - samsung,exynos5420-mipi-video-phy
+      - samsung,exynos5433-mipi-video-phy
+
+  "#phy-cells":
+    const: 1
+
+  syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface, valid only for
+      samsung,s5pv210-mipi-video-phy and samsung,exynos5420-mipi-video-phy.
+
+  samsung,pmu-syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface, valid for
+      samsung,exynos5433-mipi-video-phy.
+
+  samsung,disp-sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to DISP system controller interface, valid for
+      samsung,exynos5433-mipi-video-phy.
+
+  samsung,cam0-sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to CAM0 system controller interface, valid for
+      samsung,exynos5433-mipi-video-phy.
+
+  samsung,cam1-sysreg:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to CAM1 system controller interface, valid for
+      samsung,exynos5433-mipi-video-phy.
+
+required:
+  - compatible
+  - "#phy-cells"
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,s5pv210-mipi-video-phy
+              - samsung,exynos5420-mipi-video-phy
+    then:
+      properties:
+        samsung,pmu-syscon: false
+        samsung,disp-sysreg: false
+        samsung,cam0-sysreg: false
+        samsung,cam1-sysreg: false
+      required:
+        - syscon
+    else:
+      properties:
+        syscon: false
+      required:
+        - samsung,pmu-syscon
+        - samsung,disp-sysreg
+        - samsung,cam0-sysreg
+        - samsung,cam1-sysreg
+
+additionalProperties: false
+
+examples:
+  - |
+    phy {
+        compatible = "samsung,exynos5433-mipi-video-phy";
+        #phy-cells = <1>;
+        samsung,pmu-syscon = <&pmu_system_controller>;
+        samsung,cam0-sysreg = <&syscon_cam0>;
+        samsung,cam1-sysreg = <&syscon_cam1>;
+        samsung,disp-sysreg = <&syscon_disp>;
+    };
+
+  - |
+    phy {
+        compatible = "samsung,s5pv210-mipi-video-phy";
+        syscon = <&pmu_system_controller>;
+        #phy-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 390065f49b62..6ab16734eb65 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -1,32 +1,3 @@
-Samsung S5P/Exynos SoC series MIPI CSIS/DSIM DPHY
--------------------------------------------------
-
-Required properties:
-- compatible : should be one of the listed compatibles:
-	- "samsung,s5pv210-mipi-video-phy"
-	- "samsung,exynos5420-mipi-video-phy"
-	- "samsung,exynos5433-mipi-video-phy"
-- #phy-cells : from the generic phy bindings, must be 1;
-
-In case of s5pv210 and exynos5420 compatible PHYs:
-- syscon - phandle to the PMU system controller
-
-In case of exynos5433 compatible PHY:
- - samsung,pmu-syscon - phandle to the PMU system controller
- - samsung,disp-sysreg - phandle to the DISP system registers controller
- - samsung,cam0-sysreg - phandle to the CAM0 system registers controller
- - samsung,cam1-sysreg - phandle to the CAM1 system registers controller
-
-For "samsung,s5pv210-mipi-video-phy" compatible PHYs the second cell in
-the PHY specifier identifies the PHY and its meaning is as follows:
-  0 - MIPI CSIS 0,
-  1 - MIPI DSIM 0,
-  2 - MIPI CSIS 1,
-  3 - MIPI DSIM 1.
-"samsung,exynos5420-mipi-video-phy" and "samsung,exynos5433-mipi-video-phy"
-supports additional fifth PHY:
-  4 - MIPI CSIS 2.
-
 Samsung Exynos SoC series Display Port PHY
 -------------------------------------------------
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:39 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:39 +0100
Subject: [PATCH 1/8] arm64: dts: exynos: adjust USB DRD clocks with dtschema
 in Exynos7
Message-ID: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>

Use the same order of USB 3.0 DRD controller clocks as in Exynos5433.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 arch/arm64/boot/dts/exynos/exynos7.dtsi | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/boot/dts/exynos/exynos7.dtsi b/arch/arm64/boot/dts/exynos/exynos7.dtsi
index 3364b09c3158..e38bb02a2152 100644
--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
@@ -684,11 +684,10 @@ usbdrd_phy: phy at 15500000 {
 			reg = <0x15500000 0x100>;
 			clocks = <&clock_fsys0 ACLK_USBDRD300>,
 			       <&clock_fsys0 OSCCLK_PHY_CLKOUT_USB30_PHY>,
-			       <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER>,
 			       <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PHYCLK_USER>,
+			       <&clock_fsys0 PHYCLK_USBDRD300_UDRD30_PIPE_PCLK_USER>,
 			       <&clock_fsys0 SCLK_USBDRD300_REFCLK>;
-			clock-names = "phy", "ref", "phy_pipe",
-				"phy_utmi", "itp";
+			clock-names = "phy", "ref", "phy_utmi", "phy_pipe", "itp";
 			samsung,pmu-syscon = <&pmu_system_controller>;
 			#phy-cells = <1>;
 		};
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:44 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:44 +0100
Subject: [PATCH 6/8] dt-bindings: phy: samsung,
 exynos5250-sata-phy: convert to dtschema
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-6-krzysztof.kozlowski@canonical.com>

Convert the Samsung Exynos5250 SoC SATA PHY bindings to DT schema
format.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../phy/samsung,exynos5250-sata-phy.yaml      | 64 +++++++++++++++++++
 .../devicetree/bindings/phy/samsung-phy.txt   | 26 --------
 2 files changed, 64 insertions(+), 26 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,exynos5250-sata-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/samsung,exynos5250-sata-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,exynos5250-sata-phy.yaml
new file mode 100644
index 000000000000..62b39bb46585
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,exynos5250-sata-phy.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,exynos5250-sata-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos5250 SoC SATA PHY
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+properties:
+  compatible:
+    const: samsung,exynos5250-sata-phy
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: sata_phyctrl
+
+  "#phy-cells":
+    const: 0
+
+  reg:
+    maxItems: 1
+
+  samsung,syscon-phandle:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface.
+
+  samsung,exynos-sataphy-i2c-phandle:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to I2C SATA interface.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - reg
+  - samsung,syscon-phandle
+  - samsung,exynos-sataphy-i2c-phandle
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5250.h>
+
+    phy at 12170000 {
+        compatible = "samsung,exynos5250-sata-phy";
+        reg = <0x12170000 0x1ff>;
+        clocks = <&clock CLK_SATA_PHYCTRL>;
+        clock-names = "sata_phyctrl";
+        #phy-cells = <0>;
+        samsung,syscon-phandle = <&pmu_system_controller>;
+        samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index d26ac7401258..1ee78016dc72 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -1,29 +1,3 @@
-Samsung SATA PHY Controller
----------------------------
-
-SATA PHY nodes are defined to describe on-chip SATA Physical layer controllers.
-Each SATA PHY controller should have its own node.
-
-Required properties:
-- compatible        : compatible list, contains "samsung,exynos5250-sata-phy"
-- reg : offset and length of the SATA PHY register set;
-- #phy-cells : must be zero
-- clocks : must be exactly one entry
-- clock-names : must be "sata_phyctrl"
-- samsung,exynos-sataphy-i2c-phandle : a phandle to the I2C device, no arguments
-- samsung,syscon-phandle : a phandle to the PMU system controller, no arguments
-
-Example:
-	sata_phy: sata-phy at 12170000 {
-		compatible = "samsung,exynos5250-sata-phy";
-		reg = <0x12170000 0x1ff>;
-		clocks = <&clock 287>;
-		clock-names = "sata_phyctrl";
-		#phy-cells = <0>;
-		samsung,exynos-sataphy-i2c-phandle = <&sata_phy_i2c>;
-		samsung,syscon-phandle = <&pmu_syscon>;
-	};
-
 Device-Tree bindings for sataphy i2c client driver
 --------------------------------------------------
 
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:43 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:43 +0100
Subject: [PATCH 5/8] dt-bindings: phy: samsung,usb2-phy: convert to dtschema
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-5-krzysztof.kozlowski@canonical.com>

Convert the Samsung SoC USB 2.0 PHY bindings to DT schema format.

Except the conversion, add also vbus-supply property which was already
used by the driver and DTS.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/phy/samsung,usb2-phy.yaml        | 102 ++++++++++++++++++
 .../devicetree/bindings/phy/samsung-phy.txt   |  60 -----------
 MAINTAINERS                                   |   2 +-
 3 files changed, 103 insertions(+), 61 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
new file mode 100644
index 000000000000..056e270a4e88
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,usb2-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung S5P/Exynos SoC USB 2.0 PHY
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+description: |
+  The first phandle argument in the PHY specifier identifies the PHY, its
+  meaning is compatible dependent. For the currently supported SoCs (Exynos4210
+  and Exynos4212) it is as follows::
+    0 - USB device ("device"),
+    1 - USB host ("host"),
+    2 - HSIC0 ("hsic0"),
+    3 - HSIC1 ("hsic1"),
+  Exynos3250 has only USB device phy available as phy 0.
+
+  Exynos4210 and Exynos4212 use mode switching and require that mode switch
+  register is supplied.
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos3250-usb2-phy
+      - samsung,exynos4210-usb2-phy
+      - samsung,exynos4x12-usb2-phy
+      - samsung,exynos5250-usb2-phy
+      - samsung,exynos5420-usb2-phy
+      - samsung,s5pv210-usb2-phy
+
+  clocks:
+    items:
+      - description: PHY module gate clock.
+      - description: Reference rate clock of PHY module.
+
+  clock-names:
+    items:
+      - const: phy
+      - const: ref
+
+  "#phy-cells":
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  samsung,pmureg-phandle:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface.
+
+  samsung,sysreg-phandle:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to system registers interface.
+
+  vbus-supply:
+    description:
+      VBUS power source.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - reg
+  - samsung,pmureg-phandle
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos4x12-usb2-phy
+              - samsung,exynos5250-usb2-phy
+              - samsung,exynos5420-usb2-phy
+    then:
+      required:
+        - samsung,sysreg-phandle
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+
+    phy at 12130000 {
+        compatible = "samsung,exynos5420-usb2-phy";
+        reg = <0x12130000 0x100>;
+        #phy-cells = <1>;
+        clocks = <&clock CLK_USBH20>, <&clock CLK_SCLK_USBPHY300>;
+        clock-names = "phy", "ref";
+        samsung,sysreg-phandle = <&sysreg_system_controller>;
+        samsung,pmureg-phandle = <&pmu_system_controller>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 839ffe2a2d05..d26ac7401258 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -1,63 +1,3 @@
-Samsung S5P/Exynos SoC series USB PHY
--------------------------------------------------
-
-Required properties:
-- compatible : should be one of the listed compatibles:
-	- "samsung,exynos3250-usb2-phy"
-	- "samsung,exynos4210-usb2-phy"
-	- "samsung,exynos4x12-usb2-phy"
-	- "samsung,exynos5250-usb2-phy"
-	- "samsung,exynos5420-usb2-phy"
-	- "samsung,s5pv210-usb2-phy"
-- reg : a list of registers used by phy driver
-	- first and obligatory is the location of phy modules registers
-- samsung,sysreg-phandle - handle to syscon used to control the system registers
-- samsung,pmureg-phandle - handle to syscon used to control PMU registers
-- #phy-cells : from the generic phy bindings, must be 1;
-- clocks and clock-names:
-	- the "phy" clock is required by the phy module, used as a gate
-	- the "ref" clock is used to get the rate of the clock provided to the
-	  PHY module
-
-Optional properties:
-- vbus-supply: power-supply phandle for vbus power source
-
-The first phandle argument in the PHY specifier identifies the PHY, its
-meaning is compatible dependent. For the currently supported SoCs (Exynos 4210
-and Exynos 4212) it is as follows:
-  0 - USB device ("device"),
-  1 - USB host ("host"),
-  2 - HSIC0 ("hsic0"),
-  3 - HSIC1 ("hsic1"),
-Exynos3250 has only USB device phy available as phy 0.
-
-Exynos 4210 and Exynos 4212 use mode switching and require that mode switch
-register is supplied.
-
-Example:
-
-For Exynos 4412 (compatible with Exynos 4212):
-
-usbphy: phy at 125b0000 {
-	compatible = "samsung,exynos4x12-usb2-phy";
-	reg = <0x125b0000 0x100>;
-	clocks = <&clock 305>, <&clock 2>;
-	clock-names = "phy", "ref";
-	#phy-cells = <1>;
-	samsung,sysreg-phandle = <&sys_reg>;
-	samsung,pmureg-phandle = <&pmu_reg>;
-};
-
-Then the PHY can be used in other nodes such as:
-
-phy-consumer at 12340000 {
-	phys = <&usbphy 2>;
-	phy-names = "phy";
-};
-
-Refer to DT bindings documentation of particular PHY consumer devices for more
-information about required PHYs and the way of specification.
-
 Samsung SATA PHY Controller
 ---------------------------
 
diff --git a/MAINTAINERS b/MAINTAINERS
index ddcee331dc09..46f6ced8370a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17168,7 +17168,7 @@ SAMSUNG USB2 PHY DRIVER
 M:	Sylwester Nawrocki <s.nawrocki at samsung.com>
 L:	linux-kernel at vger.kernel.org
 S:	Supported
-F:	Documentation/devicetree/bindings/phy/samsung-phy.txt
+F:	Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
 F:	Documentation/driver-api/phy/samsung-usb2.rst
 F:	drivers/phy/samsung/phy-exynos4210-usb2.c
 F:	drivers/phy/samsung/phy-exynos4x12-usb2.c
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:45 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:45 +0100
Subject: [PATCH 7/8] dt-bindings: phy: samsung: move SATA phy I2C to trivial
 devices
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-7-krzysztof.kozlowski@canonical.com>

The I2C interface for Samsung Exynos SoC SATA phy is a very simple and
limited, so move it to trivial devices.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../devicetree/bindings/phy/samsung-phy.txt        | 14 --------------
 .../devicetree/bindings/trivial-devices.yaml       |  2 ++
 2 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
index 1ee78016dc72..b0abeb4ac0a2 100644
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt
@@ -1,17 +1,3 @@
-Device-Tree bindings for sataphy i2c client driver
---------------------------------------------------
-
-Required properties:
-compatible: Should be "samsung,exynos-sataphy-i2c"
-- reg: I2C address of the sataphy i2c device.
-
-Example:
-
-	sata_phy_i2c:sata-phy at 38 {
-		compatible = "samsung,exynos-sataphy-i2c";
-		reg = <0x38>;
-	};
-
 Samsung Exynos5 SoC series USB DRD PHY controller
 --------------------------------------------------
 
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml
index 091792ba993e..d53a4b2f81aa 100644
--- a/Documentation/devicetree/bindings/trivial-devices.yaml
+++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -283,6 +283,8 @@ properties:
           - renesas,isl29501
             # S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power)
           - samsung,24ad0xd1
+            # Samsung Exynos SoC SATA PHY I2C device
+          - samsung,exynos-sataphy-i2c
             # Sensirion low power multi-pixel gas sensor with I2C interface
           - sensirion,sgpc3
             # Sensirion multi-pixel gas sensor with I2C interface
-- 
2.32.0



From krzysztof.kozlowski at canonical.com  Sat Jan 29 11:36:46 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Sat, 29 Jan 2022 20:36:46 +0100
Subject: [PATCH 8/8] dt-bindings: phy: samsung,
 usb3-drd-phy: convert to dtschema
In-Reply-To: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
References: <20220129193646.372481-1-krzysztof.kozlowski@canonical.com>
Message-ID: <20220129193646.372481-8-krzysztof.kozlowski@canonical.com>

Convert the Samsung Exynos USB 3.0 DRD PHY bindings to DT schema format.

Except the conversion, add also vbus-supply and vbus-boost-supply
properties which were already used by the driver and DTS.

Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
---
 .../bindings/phy/samsung,usb3-drd-phy.yaml    | 126 ++++++++++++++++++
 .../devicetree/bindings/phy/samsung-phy.txt   |  53 --------
 2 files changed, 126 insertions(+), 53 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
 delete mode 100644 Documentation/devicetree/bindings/phy/samsung-phy.txt

diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
new file mode 100644
index 000000000000..f83f0f8135b9
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/samsung,usb3-drd-phy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Samsung Exynos SoC USB 3.0 DRD PHY USB 2.0 PHY
+
+maintainers:
+  - Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
+  - Marek Szyprowski <m.szyprowski at samsung.com>
+  - Sylwester Nawrocki <s.nawrocki at samsung.com>
+
+description: |
+  For samsung,exynos5250-usbdrd-phy and samsung,exynos5420-usbdrd-phy
+  compatible PHYs, the second cell in the PHY specifier identifies the
+  PHY id, which is interpreted as follows::
+    0 - UTMI+ type phy,
+    1 - PIPE3 type phy.
+
+  For SoCs like Exynos5420 having multiple USB 3.0 DRD PHY controllers,
+  'usbdrd_phy' nodes should have numbered alias in the aliases node, in the
+  form of usbdrdphyN, N = 0, 1... (depending on number of controllers).
+
+properties:
+  compatible:
+    enum:
+      - samsung,exynos5250-usbdrd-phy
+      - samsung,exynos5420-usbdrd-phy
+      - samsung,exynos5433-usbdrd-phy
+      - samsung,exynos7-usbdrd-phy
+
+  clocks:
+    minItems: 2
+    maxItems: 5
+
+  clock-names:
+    minItems: 2
+    maxItems: 5
+    description: |
+      At least two clocks::
+        - Main PHY clock (same as USB DRD controller i.e. DWC3 IP clock), used
+          for register access.
+        - PHY reference clock (usually crystal clock), used for PHY operations,
+          associated by phy name. It is used to determine bit values for clock
+          settings register.  For Exynos5420 this is given as 'sclk_usbphy30'
+          in the CMU.
+
+  "#phy-cells":
+    const: 1
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      Any connector to the data bus of this controller should be modelled using
+      the OF graph bindings specified.
+
+  reg:
+    maxItems: 1
+
+  samsung,pmu-syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to PMU system controller interface.
+
+  vbus-supply:
+    description:
+      VBUS power source.
+
+  vbus-boost-supply:
+    description:
+      VBUS Boost 5V power source.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - "#phy-cells"
+  - reg
+  - samsung,pmu-syscon
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - samsung,exynos5433-usbdrd-phy
+              - samsung,exynos7-usbdrd-phy
+    then:
+      properties:
+        clocks:
+          minItems: 5
+          maxItems: 5
+        clock-names:
+          items:
+            - const: phy
+            - const: ref
+            - const: phy_utmi
+            - const: phy_pipe
+            - const: itp
+    else:
+      properties:
+        clocks:
+          minItems: 2
+          maxItems: 2
+        clock-names:
+          items:
+            - const: phy
+            - const: ref
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/exynos5420.h>
+
+    phy at 12100000 {
+        compatible = "samsung,exynos5420-usbdrd-phy";
+        reg = <0x12100000 0x100>;
+        #phy-cells = <1>;
+        clocks = <&clock CLK_USBD300>, <&clock CLK_SCLK_USBPHY300>;
+        clock-names = "phy", "ref";
+        samsung,pmu-syscon = <&pmu_system_controller>;
+        vbus-supply = <&usb300_vbus_reg>;
+    };
diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt
deleted file mode 100644
index b0abeb4ac0a2..000000000000
--- a/Documentation/devicetree/bindings/phy/samsung-phy.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-Samsung Exynos5 SoC series USB DRD PHY controller
---------------------------------------------------
-
-Required properties:
-- compatible : Should be set to one of the following supported values:
-	- "samsung,exynos5250-usbdrd-phy" - for exynos5250 SoC,
-	- "samsung,exynos5420-usbdrd-phy" - for exynos5420 SoC.
-	- "samsung,exynos5433-usbdrd-phy" - for exynos5433 SoC.
-	- "samsung,exynos7-usbdrd-phy" - for exynos7 SoC.
-- reg : Register offset and length of USB DRD PHY register set;
-- clocks: Clock IDs array as required by the controller
-- clock-names: names of clocks correseponding to IDs in the clock property;
-	       Required clocks:
-	- phy: main PHY clock (same as USB DRD controller i.e. DWC3 IP clock),
-	       used for register access.
-	- ref: PHY's reference clock (usually crystal clock), used for
-	       PHY operations, associated by phy name. It is used to
-	       determine bit values for clock settings register.
-	       For Exynos5420 this is given as 'sclk_usbphy30' in CMU.
-	- optional clocks: Exynos5433 & Exynos7 SoC has now following additional
-			   gate clocks available:
-			   - phy_pipe: for PIPE3 phy
-			   - phy_utmi: for UTMI+ phy
-			   - itp: for ITP generation
-- samsung,pmu-syscon: phandle for PMU system controller interface, used to
-		      control pmu registers for power isolation.
-- #phy-cells : from the generic PHY bindings, must be 1;
-
-For "samsung,exynos5250-usbdrd-phy" and "samsung,exynos5420-usbdrd-phy"
-compatible PHYs, the second cell in the PHY specifier identifies the
-PHY id, which is interpreted as follows:
-  0 - UTMI+ type phy,
-  1 - PIPE3 type phy,
-
-Example:
-	usbdrd_phy: usbphy at 12100000 {
-		compatible = "samsung,exynos5250-usbdrd-phy";
-		reg = <0x12100000 0x100>;
-		clocks = <&clock 286>, <&clock 1>;
-		clock-names = "phy", "ref";
-		samsung,pmu-syscon = <&pmu_system_controller>;
-		#phy-cells = <1>;
-	};
-
-- aliases: For SoCs like Exynos5420 having multiple USB 3.0 DRD PHY controllers,
-	   'usbdrd_phy' nodes should have numbered alias in the aliases node,
-	   in the form of usbdrdphyN, N = 0, 1... (depending on number of
-	   controllers).
-Example:
-	aliases {
-		usbdrdphy0 = &usb3_phy0;
-		usbdrdphy1 = &usb3_phy1;
-	};
-- 
2.32.0



From hugo at hugovil.com  Sat Jan 29 12:26:17 2022
From: hugo at hugovil.com (Hugo Villeneuve)
Date: Sat, 29 Jan 2022 15:26:17 -0500
Subject: [PATCH v2] arm64: dts: imx8mp-evk: add PCA6416 interrupt controller
 mode
In-Reply-To: <20220129060818.GQ4686@dragon>
References: <20220129060818.GQ4686@dragon>
Message-ID: <20220129202617.2332885-1-hugo@hugovil.com>

From: Hugo Villeneuve <hvilleneuve at dimonoff.com>

Add interrupt controller mode for the pca6416 on i.MX8MP EVK board's.

Signed-off-by: Hugo Villeneuve <hvilleneuve at dimonoff.com>
---

Rebased on tree: git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
         branch: for-next

 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
index 2eb943210678..9055ce32aecc 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -294,6 +294,12 @@ pca6416: gpio at 20 {
 		reg = <0x20>;
 		gpio-controller;
 		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_pca6416_int>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
 	};
 };
 
@@ -448,6 +454,12 @@ MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x000001c0
 		>;
 	};
 
+	pinctrl_pca6416_int: pca6416_int_grp {
+		fsl,pins = <
+			MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12	0x146 /* Input pull-up. */
+		>;
+	};
+
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
 			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
-- 
2.30.2



From dfustini at baylibre.com  Sat Jan 29 13:05:31 2022
From: dfustini at baylibre.com (Drew Fustini)
Date: Sat, 29 Jan 2022 13:05:31 -0800
Subject: [PATCH 2/2] clocksource/drivers/timer-ti-dm: Handle dra7 timer
 wrap errata i940
In-Reply-To: <20210323074326.28302-3-tony@atomide.com>
References: <20210323074326.28302-1-tony@atomide.com>
 <20210323074326.28302-3-tony@atomide.com>
Message-ID: <YfWsG0p6to3IJuvE@x1>

On Tue, Mar 23, 2021 at 09:43:26AM +0200, Tony Lindgren wrote:
> There is a timer wrap issue on dra7 for the ARM architected timer.
> In a typical clock configuration the timer fails to wrap after 388 days.
> 
> To work around the issue, we need to use timer-ti-dm percpu timers instead.
> 
> Let's configure dmtimer3 and 4 as percpu timers by default, and warn about
> the issue if the dtb is not configured properly.

Hi Tony,

This causes a conflict for IPU2 which is using timer 3 and 4.

>From arch/arm/boot/dts/dra7-ipu-dsp-common.dtsi:

  &ipu2 {
          mboxes = <&mailbox6 &mbox_ipu2_ipc3x>;
          ti,timers = <&timer3>;
          ti,watchdog-timers = <&timer4>, <&timer9>;
  };

I noticed an error ("could not get timer platform device") when booting
mainline on a BeagleBoard X15 (AM578):

  omap-rproc 55020000.ipu: assigned reserved memory node ipu2-memory at 95800000
  remoteproc remoteproc1: 55020000.ipu is available
  remoteproc remoteproc1: powering up 55020000.ipu
  remoteproc remoteproc1: Booting fw image dra7-ipu2-fw.xem4, size 3747220
  omap-rproc 55020000.ipu: could not get timer platform device
  omap-rproc 55020000.ipu: omap_rproc_enable_timers failed: -19
  remoteproc remoteproc1: can't start rproc 55020000.ipu: -19

I switched this errata fix to use timer 15 and 16 instead which resolves
the error.  Do you think that is an acceptable solution?

If so, I will post the patch to the list.

Thanks,
Drew


From arnd at arndb.de  Sat Jan 29 13:40:02 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 29 Jan 2022 22:40:02 +0100
Subject: [PATCH V4 03/17] asm-generic: compat: Cleanup duplicate
 definitions
In-Reply-To: <20220129121728.1079364-4-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-4-guoren@kernel.org>
Message-ID: <CAK8P3a0jK4quTT6txPakQuuAjyoMXRq1eM35pCFLo0PQNq+p2Q@mail.gmail.com>

On Sat, Jan 29, 2022 at 1:17 PM <guoren at kernel.org> wrote:
>
> From: Guo Ren <guoren at linux.alibaba.com>
>
> There are 7 64bit architectures that support Linux COMPAT mode to
> run 32bit applications. A lot of definitions are duplicate:
>  - COMPAT_USER_HZ
>  - COMPAT_RLIM_INFINITY
>  - COMPAT_OFF_T_MAX
>  - __compat_uid_t, __compat_uid_t
>  - compat_dev_t
>  - compat_ipc_pid_t
>  - struct compat_flock
>  - struct compat_flock64
>  - struct compat_statfs
>  - struct compat_ipc64_perm, compat_semid64_ds,
>           compat_msqid64_ds, compat_shmid64_ds
>
> Cleanup duplicate definitions and merge them into asm-generic.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>
> Cc: Palmer Dabbelt <palmer at dabbelt.com>

Reviewed-by: Arnd Bergmann <arnd at arndb.de>


From arnd at arndb.de  Sat Jan 29 13:56:25 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 29 Jan 2022 22:56:25 +0100
Subject: [PATCH V4 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <20220129121728.1079364-7-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-7-guoren@kernel.org>
Message-ID: <CAK8P3a3_kVB78-26sxdsEjb3MMcco6U55tc7siCBFZbJjyH6Sw@mail.gmail.com>

On Sat, Jan 29, 2022 at 1:17 PM <guoren at kernel.org> wrote:
> +
> +#define COMPAT_RLIM_INFINITY   0x7fffffff
>
> +#define F_GETLK64      12
> +#define F_SETLK64      13
> +#define F_SETLKW64     14

These now come from the generic definitions I think. The flock definitions
are just the normal ones, and AFAICT the RLIM_INIFINITY definition here
is actually wrong and should be the default 0xffffffffu to match the
native (~0UL) definition.

            Arnd


From martin.juecker at gmail.com  Sat Jan 29 14:01:53 2022
From: martin.juecker at gmail.com (Martin =?iso-8859-1?Q?J=FCcker?=)
Date: Sat, 29 Jan 2022 23:01:53 +0100
Subject: [PATCH] drm/exynos: fimd: add BGR support for exynos4/5
Message-ID: <20220129220153.GA33165@adroid>

In the downstream kernels for exynos4 and exynos5 devices, there is an
undocumented register that controls the order of the RGB output. It can
be set to either normal order or reversed, which enables BGR support for
those SoCs.

This patch enables the BGR support for all the SoCs that were found to
have at least one device with this logic in the corresponding downstream
kernels.

Signed-off-by: Martin J?cker <martin.juecker at gmail.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 42 ++++++++++++++++++++++--
 include/video/samsung_fimd.h             |  4 +++
 2 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index c735e53939d8..cb632360c968 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -109,6 +109,7 @@ struct fimd_driver_data {
 	unsigned int has_dp_clk:1;
 	unsigned int has_hw_trigger:1;
 	unsigned int has_trigger_per_te:1;
+	unsigned int has_bgr_support:1;
 };
 
 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -138,6 +139,7 @@ static struct fimd_driver_data exynos4_fimd_driver_data = {
 	.lcdblk_bypass_shift = 1,
 	.has_shadowcon = 1,
 	.has_vtsel = 1,
+	.has_bgr_support = 1,
 };
 
 static struct fimd_driver_data exynos5_fimd_driver_data = {
@@ -149,6 +151,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = {
 	.has_vidoutcon = 1,
 	.has_vtsel = 1,
 	.has_dp_clk = 1,
+	.has_bgr_support = 1,
 };
 
 static struct fimd_driver_data exynos5420_fimd_driver_data = {
@@ -162,6 +165,7 @@ static struct fimd_driver_data exynos5420_fimd_driver_data = {
 	.has_vtsel = 1,
 	.has_mic_bypass = 1,
 	.has_dp_clk = 1,
+	.has_bgr_support = 1,
 };
 
 struct fimd_context {
@@ -226,6 +230,18 @@ static const uint32_t fimd_formats[] = {
 	DRM_FORMAT_ARGB8888,
 };
 
+static const uint32_t fimd_extended_formats[] = {
+	DRM_FORMAT_C8,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+};
+
 static const unsigned int capabilities[WINDOWS_NR] = {
 	0,
 	EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
@@ -673,21 +689,25 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
 		val |= WINCONx_BYTSWP;
 		break;
 	case DRM_FORMAT_XRGB1555:
+	case DRM_FORMAT_XBGR1555:
 		val |= WINCON0_BPPMODE_16BPP_1555;
 		val |= WINCONx_HAWSWP;
 		val |= WINCONx_BURSTLEN_16WORD;
 		break;
 	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_BGR565:
 		val |= WINCON0_BPPMODE_16BPP_565;
 		val |= WINCONx_HAWSWP;
 		val |= WINCONx_BURSTLEN_16WORD;
 		break;
 	case DRM_FORMAT_XRGB8888:
+	case DRM_FORMAT_XBGR8888:
 		val |= WINCON0_BPPMODE_24BPP_888;
 		val |= WINCONx_WSWP;
 		val |= WINCONx_BURSTLEN_16WORD;
 		break;
 	case DRM_FORMAT_ARGB8888:
+	case DRM_FORMAT_ABGR8888:
 	default:
 		val |= WINCON1_BPPMODE_25BPP_A1888;
 		val |= WINCONx_WSWP;
@@ -695,6 +715,18 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
 		break;
 	}
 
+	switch (pixel_format) {
+	case DRM_FORMAT_XBGR1555:
+	case DRM_FORMAT_XBGR8888:
+	case DRM_FORMAT_ABGR8888:
+	case DRM_FORMAT_BGR565:
+		writel(WIN_RGB_ORDER_REVERSE, ctx->regs + WIN_RGB_ORDER(win));
+		break;
+	default:
+		writel(WIN_RGB_ORDER_FORWARD, ctx->regs + WIN_RGB_ORDER(win));
+		break;
+	}
+
 	/*
 	 * Setting dma-burst to 16Word causes permanent tearing for very small
 	 * buffers, e.g. cursor buffer. Burst Mode switching which based on
@@ -1074,8 +1106,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
 	ctx->drm_dev = drm_dev;
 
 	for (i = 0; i < WINDOWS_NR; i++) {
-		ctx->configs[i].pixel_formats = fimd_formats;
-		ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
+		if (ctx->driver_data->has_bgr_support) {
+			ctx->configs[i].pixel_formats = fimd_extended_formats;
+			ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_extended_formats);
+		} else {
+			ctx->configs[i].pixel_formats = fimd_formats;
+			ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
+		}
+
 		ctx->configs[i].zpos = i;
 		ctx->configs[i].type = fimd_win_types[i];
 		ctx->configs[i].capabilities = capabilities[i];
diff --git a/include/video/samsung_fimd.h b/include/video/samsung_fimd.h
index c4a93ce1de48..e6966d187591 100644
--- a/include/video/samsung_fimd.h
+++ b/include/video/samsung_fimd.h
@@ -476,6 +476,10 @@
  * 1111		-none-	 -none-   -none-   -none-    -none-
 */
 
+#define WIN_RGB_ORDER(_win)			(0x2020 + ((_win) * 4))
+#define WIN_RGB_ORDER_FORWARD			(0 << 11)
+#define WIN_RGB_ORDER_REVERSE			(1 << 11)
+
 /* FIMD Version 8 register offset definitions */
 #define FIMD_V8_VIDTCON0	0x20010
 #define FIMD_V8_VIDTCON1	0x20014
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:13 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:13 -0800
Subject: [RFC v6 net-next 1/9] pinctrl: ocelot: allow pinctrl-ocelot to be
 loaded as a module
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-2-colin.foster@in-advantage.com>

Work is being done to allow external control of Ocelot chips. When pinctrl
drivers are used internally, it wouldn't make much sense to allow them to
be loaded as modules. In the case where the Ocelot chip is controlled
externally, this scenario becomes practical.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/pinctrl/Kconfig          | 2 +-
 drivers/pinctrl/pinctrl-ocelot.c | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 6fc56d6598e2..1b367f423ceb 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -311,7 +311,7 @@ config PINCTRL_MICROCHIP_SGPIO
 	  LED controller.
 
 config PINCTRL_OCELOT
-	bool "Pinctrl driver for the Microsemi Ocelot and Jaguar2 SoCs"
+	tristate "Pinctrl driver for the Microsemi Ocelot and Jaguar2 SoCs"
 	depends on OF
 	depends on HAS_IOMEM
 	select GPIOLIB
diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index fc969208d904..b6ad3ffb4596 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -1778,6 +1778,7 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = {
 	{ .compatible = "microchip,lan966x-pinctrl", .data = &lan966x_desc },
 	{},
 };
+MODULE_DEVICE_TABLE(of, ocelot_pinctrl_of_match);
 
 static struct regmap *ocelot_pinctrl_create_pincfg(struct platform_device *pdev)
 {
@@ -1866,3 +1867,6 @@ static struct platform_driver ocelot_pinctrl_driver = {
 	.probe = ocelot_pinctrl_probe,
 };
 builtin_platform_driver(ocelot_pinctrl_driver);
+
+MODULE_DESCRIPTION("Ocelot Chip Pinctrl Driver");
+MODULE_LICENSE("Dual MIT/GPL");
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:14 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:14 -0800
Subject: [RFC v6 net-next 2/9] pinctrl: microchip-sgpio: allow sgpio driver to
 be used as a module
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-3-colin.foster@in-advantage.com>

As the commit message suggests, this simply adds the ability to select
SGPIO pinctrl as a module. This becomes more practical when the SGPIO
hardware exists on an external chip, controlled indirectly by I2C or SPI.
This commit enables that level of control.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/pinctrl/Kconfig                   | 2 +-
 drivers/pinctrl/pinctrl-microchip-sgpio.c | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1b367f423ceb..7ff00c560775 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -292,7 +292,7 @@ config PINCTRL_MCP23S08
 	  corresponding interrupt-controller.
 
 config PINCTRL_MICROCHIP_SGPIO
-	bool "Pinctrl driver for Microsemi/Microchip Serial GPIO"
+	tristate "Pinctrl driver for Microsemi/Microchip Serial GPIO"
 	depends on OF
 	depends on HAS_IOMEM
 	select GPIOLIB
diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
index 8e081c90bdb2..8db3caf15cf2 100644
--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
+++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
@@ -912,6 +912,7 @@ static const struct of_device_id microchip_sgpio_gpio_of_match[] = {
 		/* sentinel */
 	}
 };
+MODULE_DEVICE_TABLE(of, microchip_sgpio_gpio_of_match);
 
 static struct platform_driver microchip_sgpio_pinctrl_driver = {
 	.driver = {
@@ -922,3 +923,6 @@ static struct platform_driver microchip_sgpio_pinctrl_driver = {
 	.probe = microchip_sgpio_probe,
 };
 builtin_platform_driver(microchip_sgpio_pinctrl_driver);
+
+MODULE_DESCRIPTION("Microchip SGPIO Pinctrl Driver");
+MODULE_LICENSE("GPL v2");
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:15 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:15 -0800
Subject: [RFC v6 net-next 3/9] net: mdio: mscc-miim: add local dev variable to
 cleanup probe function
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-4-colin.foster@in-advantage.com>

Create a local device *dev in order to not dereference the platform_device
several times throughout the probe function.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/net/mdio/mdio-mscc-miim.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
index 7d2abaf2b2c9..6b14f3cf3891 100644
--- a/drivers/net/mdio/mdio-mscc-miim.c
+++ b/drivers/net/mdio/mdio-mscc-miim.c
@@ -220,6 +220,7 @@ EXPORT_SYMBOL(mscc_miim_setup);
 static int mscc_miim_probe(struct platform_device *pdev)
 {
 	struct regmap *mii_regmap, *phy_regmap = NULL;
+	struct device *dev = &pdev->dev;
 	void __iomem *regs, *phy_regs;
 	struct mscc_miim_dev *miim;
 	struct resource *res;
@@ -228,38 +229,37 @@ static int mscc_miim_probe(struct platform_device *pdev)
 
 	regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
 	if (IS_ERR(regs)) {
-		dev_err(&pdev->dev, "Unable to map MIIM registers\n");
+		dev_err(dev, "Unable to map MIIM registers\n");
 		return PTR_ERR(regs);
 	}
 
-	mii_regmap = devm_regmap_init_mmio(&pdev->dev, regs,
-					   &mscc_miim_regmap_config);
+	mii_regmap = devm_regmap_init_mmio(dev, regs, &mscc_miim_regmap_config);
 
 	if (IS_ERR(mii_regmap)) {
-		dev_err(&pdev->dev, "Unable to create MIIM regmap\n");
+		dev_err(dev, "Unable to create MIIM regmap\n");
 		return PTR_ERR(mii_regmap);
 	}
 
 	/* This resource is optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (res) {
-		phy_regs = devm_ioremap_resource(&pdev->dev, res);
+		phy_regs = devm_ioremap_resource(dev, res);
 		if (IS_ERR(phy_regs)) {
-			dev_err(&pdev->dev, "Unable to map internal phy registers\n");
+			dev_err(dev, "Unable to map internal phy registers\n");
 			return PTR_ERR(phy_regs);
 		}
 
-		phy_regmap = devm_regmap_init_mmio(&pdev->dev, phy_regs,
+		phy_regmap = devm_regmap_init_mmio(dev, phy_regs,
 						   &mscc_miim_regmap_config);
 		if (IS_ERR(phy_regmap)) {
-			dev_err(&pdev->dev, "Unable to create phy register regmap\n");
+			dev_err(dev, "Unable to create phy register regmap\n");
 			return PTR_ERR(phy_regmap);
 		}
 	}
 
-	ret = mscc_miim_setup(&pdev->dev, &bus, "mscc_miim", mii_regmap, 0);
+	ret = mscc_miim_setup(dev, &bus, "mscc_miim", mii_regmap, 0);
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Unable to setup the MDIO bus\n");
+		dev_err(dev, "Unable to setup the MDIO bus\n");
 		return ret;
 	}
 
@@ -267,9 +267,9 @@ static int mscc_miim_probe(struct platform_device *pdev)
 	miim->phy_regs = phy_regmap;
 	miim->phy_reset_offset = 0;
 
-	ret = of_mdiobus_register(bus, pdev->dev.of_node);
+	ret = of_mdiobus_register(bus, dev->of_node);
 	if (ret < 0) {
-		dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret);
+		dev_err(dev, "Cannot register MDIO bus (%d)\n", ret);
 		return ret;
 	}
 
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:12 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:12 -0800
Subject: [RFC v6 net-next 0/9] add support for VSC7512 control over SPI
Message-ID: <20220129220221.2823127-1-colin.foster@in-advantage.com>

The patch set in general is to add support for the VSC7512, and
eventually the VSC7511, VSC7513 and VSC7514 devices controlled over
SPI. The driver is believed to be fully functional for the internal
phy ports (0-3)  on the VSC7512. It is not yet functional for SGMII,
QSGMII, and SerDes ports.

I have mentioned previously:
The hardware setup I'm using for development is a beaglebone black, with
jumpers from SPI0 to the microchip VSC7512 dev board. The microchip dev
board has been modified to not boot from flash, but wait for SPI. An
ethernet cable is connected from the beaglebone ethernet to port 0 of
the dev board.

The relevant sections of the device tree I'm using for the VSC7512 is
below. Notably the SGPIO LEDs follow link status and speed from network
triggers.

In order to make this work, I have modified the cpsw driver, and now the
cpsw_new driver, to allow for frames over 1500 bytes. Otherwise the
tagging protocol will not work between the beaglebone and the VSC7512. I
plan to eventually try to get those changes in mainline, but I don't
want to get distracted from my initial goal. I also had to change
bonecommon.dtsi to avoid using VLAN 0.


Lastly, there are things that I have not changed. v6 still uses
device_is_mfd to reason about whether it should use
devm_ioremap_resource or ocelot_get_regmap_from_resource. If necessary,
a different compatible string could be used. That would create some code
duplication, but if device_is_mfd is not desired I completely
understand.

I also still use ocelot_get_regmap_from_resource, and it has been
squashed into the main MFD addition commit. My initial thoughts of it
being able to be done through dev / MFD were probably over-complicating
things.


/ {
	model = "TI AM335x BeagleBone Black";
	compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx";

	// 125 MHz clock on dev board
	ocelot_clock: ocelot-clock {
		compatible = "fixed-clock";
		#clock-cells = <0>;
		clock-frequency = <125000000>;
	};

	vscleds {
		compatible = "gpio-leds";
		vscled at 0 {
			label = "port0led";
			gpios = <&sgpio_out1 0 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:00:link";
		};
		vscled at 1 {
			label = "port0led1";
			gpios = <&sgpio_out1 0 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:00:1Gbps";
		};
		vscled at 10 {
			label = "port1led";
			gpios = <&sgpio_out1 1 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:01:link";
		};
		vscled at 11 {
			label = "port1led1";
			gpios = <&sgpio_out1 1 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:01:1Gbps";
		};
		vscled at 20 {
			label = "port2led";
			gpios = <&sgpio_out1 2 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:02:link";
		};
		vscled at 21 {
			label = "port2led1";
			gpios = <&sgpio_out1 2 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:02:1Gbps";
		};
		vscled at 30 {
			label = "port3led";
			gpios = <&sgpio_out1 3 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:03:link";
		};
		vscled at 31 {
			label = "port3led1";
			gpios = <&sgpio_out1 3 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-ext-switch-mii:03:1Gbps";
		};
		vscled at 40 {
			label = "port4led";
			gpios = <&sgpio_out1 4 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:04:link";
		};
		vscled at 41 {
			label = "port4led1";
			gpios = <&sgpio_out1 4 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:04:1Gbps";
		};
		vscled at 50 {
			label = "port5led";
			gpios = <&sgpio_out1 5 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:05:link";
		};
		vscled at 51 {
			label = "port5led1";
			gpios = <&sgpio_out1 5 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:05:1Gbps";
		};
		vscled at 60 {
			label = "port6led";
			gpios = <&sgpio_out1 6 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:06:link";
		};
		vscled at 61 {
			label = "port6led1";
			gpios = <&sgpio_out1 6 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:06:1Gbps";
		};
		vscled at 70 {
			label = "port7led";
			gpios = <&sgpio_out1 7 0 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:07:link";
		};
		vscled at 71 {
			label = "port7led1";
			gpios = <&sgpio_out1 7 1 GPIO_ACTIVE_LOW>;
			default-state = "off";
			linux,default-trigger = "ocelot-miim1-mii:07:1Gbps";
		};
	};
};


&spi0 {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	ocelot-chip at 0 {
		compatible = "mscc,vsc7512_mfd_spi";
		spi-max-frequency = <2500000>;
		reg = <0>;

		ethernet-switch at 0 {
			compatible = "mscc,vsc7512-ext-switch";
			ports {
				#address-cells = <1>;
				#size-cells = <0>;

				port at 0 {
					reg = <0>;
					label = "cpu";
					status = "okay";
					ethernet = <&mac_sw>;
					phy-handle = <&sw_phy0>;
					phy-mode = "internal";
				};

				port at 1 {
					reg = <1>;
					label = "swp1";
					status = "okay";
					phy-handle = <&sw_phy1>;
					phy-mode = "internal";
				};

				port at 2 {
					reg = <2>;
					label = "swp2";
					status = "okay";
					phy-handle = <&sw_phy2>;
					phy-mode = "internal";
				};

				port at 3 {
					reg = <3>;
					label = "swp3";
					status = "okay";
					phy-handle = <&sw_phy3>;
					phy-mode = "internal";
				};

				port at 4 {
					reg = <4>;
					label = "swp4";
					status = "okay";
					phy-handle = <&sw_phy4>;
					phy-mode = "qsgmii";
					phys = <&serdes 4 SERDES6G(0)>;
				};

				port at 5 {
					reg = <5>;
					label = "swp5";
					status = "okay";
					phy-handle = <&sw_phy5>;
					phy-mode = "qsgmii";
					phys = <&serdes 5 SERDES6G(0)>;
				};

				port at 6 {
					reg = <6>;
					label = "swp6";
					status = "okay";
					phy-handle = <&sw_phy6>;
					phy-mode = "qsgmii";
					phys = <&serdes 6 SERDES6G(0)>;
				};

				port at 7 {
					reg = <7>;
					label = "swp7";
					status = "okay";
					phy-handle = <&sw_phy7>;
					phy-mode = "qsgmii";
					phys = <&serdes 7 SERDES6G(0)>;
				};
			};


			mdio {
				#address-cells = <1>;
				#size-cells = <0>;

				sw_phy0: ethernet-phy at 0 {
					reg = <0x0>;
				};

				sw_phy1: ethernet-phy at 1 {
					reg = <0x1>;
				};

				sw_phy2: ethernet-phy at 2 {
					reg = <0x2>;
				};

				sw_phy3: ethernet-phy at 3 {
					reg = <0x3>;
				};
			};
		};

		mdio1: mdio1 {
			compatible = "mscc,ocelot-miim";
			pinctrl-names = "default";
			pinctrl-0 = <&miim1>;
			#address-cells = <1>;
			#size-cells = <0>;

			sw_phy4: ethernet-phy at 4 {
				reg = <0x4>;
			};

			sw_phy5: ethernet-phy at 5 {
				reg = <0x5>;
			};

			sw_phy6: ethernet-phy at 6 {
				reg = <0x6>;
			};

			sw_phy7: ethernet-phy at 7 {
				reg = <0x7>;
			};
		};

		gpio: pinctrl at 0 {
			compatible = "mscc,ocelot-pinctrl";
			gpio-controller;
			#gpio_cells = <2>;
			gpio-ranges = <&gpio 0 0 22>;

			led_shift_reg_pins: led-shift-reg-pins {
				pins = "GPIO_0", "GPIO_1", "GPIO_2", "GPIO_3";
				function = "sg0";
			};

			miim1: miim1 {
				pins = "GPIO_14", "GPIO_15";
				function = "miim";
			};
		};

		sgpio: sgpio {
			compatible = "mscc,ocelot-sgpio";
			#address-cells = <1>;
			#size-cells = <0>;
			bus-frequency=<12500000>;
			clocks = <&ocelot_clock>;
			microchip,sgpio-port-ranges = <0 15>;
			pinctrl-names = "default";
			pinctrl-0 = <&led_shift_reg_pins>;

			sgpio_in0: sgpio at 0 {
				compatible = "microchip,sparx5-sgpio-bank";
				reg = <0>;
				gpio-controller;
				#gpio-cells = <3>;
				ngpios = <64>;
			};

			sgpio_out1: sgpio at 1 {
				compatible = "microchip,sparx5-sgpio-bank";
				reg = <1>;
				gpio-controller;
				#gpio-cells = <3>;
				ngpios = <64>;
			};
		};
	};
};


RFC history:
v1 (accidentally named vN)
	* Initial architecture. Not functional
	* General concepts laid out

v2
	* Near functional. No CPU port communication, but control over all
	external ports
	* Cleaned up regmap implementation from v1

v3
	* Functional
	* Shared MDIO transactions routed through mdio-mscc-miim
	* CPU / NPI port enabled by way of vsc7512_enable_npi_port /
	felix->info->enable_npi_port
	* NPI port tagging functional - Requires a CPU port driver that supports
	frames of 1520 bytes. Verified with a patch to the cpsw driver

v4
    * Functional
    * Device tree fixes
    * Add hooks for pinctrl-ocelot - some functionality by way of sysfs
    * Add hooks for pinctrl-microsemi-sgpio - not yet fully functional
    * Remove lynx_pcs interface for a generic phylink_pcs. The goal here
    is to have an ocelot_pcs that will work for each configuration of
    every port.

v5
    * Restructured to MFD
    * Several commits were split out, submitted, and accepted
    * pinctrl-ocelot believed to be fully functional (requires commits
    from the linux-pinctrl tree)
    * External MDIO bus believed to be fully functional

v6
    * Applied several suggestions from the last RFC from Lee Jones. I
      hope I didn't miss anything.
    * Clean up MFD core - SPI interaction. They no longer use callbacks.
    * regmaps get registered to the child device, and don't attempt to
      get shared. It seems if a regmap is to be shared, that should be
      solved with syscon, not dev or mfd.


Colin Foster (9):
  pinctrl: ocelot: allow pinctrl-ocelot to be loaded as a module
  pinctrl: microchip-sgpio: allow sgpio driver to be used as a module
  net: mdio: mscc-miim: add local dev variable to cleanup probe function
  net: mdio: mscc-miim: add ability to externally register phy reset
    control
  mfd: add interface to check whether a device is mfd
  mfd: ocelot: add support for external mfd control over SPI for the
    VSC7512
  net: mscc: ocelot: expose ocelot wm functions
  net: dsa: felix: add configurable device quirks
  net: dsa: ocelot: add external ocelot switch control

 drivers/mfd/Kconfig                        |  19 +
 drivers/mfd/Makefile                       |   3 +
 drivers/mfd/mfd-core.c                     |   6 +
 drivers/mfd/ocelot-core.c                  | 169 +++++
 drivers/mfd/ocelot-spi.c                   | 325 ++++++++++
 drivers/mfd/ocelot.h                       |  36 ++
 drivers/net/dsa/ocelot/Kconfig             |  14 +
 drivers/net/dsa/ocelot/Makefile            |   5 +
 drivers/net/dsa/ocelot/felix.c             |   7 +-
 drivers/net/dsa/ocelot/felix.h             |   1 +
 drivers/net/dsa/ocelot/felix_vsc9959.c     |   1 +
 drivers/net/dsa/ocelot/ocelot_ext.c        | 681 +++++++++++++++++++++
 drivers/net/dsa/ocelot/seville_vsc9953.c   |   4 +-
 drivers/net/ethernet/mscc/ocelot_devlink.c |  31 +
 drivers/net/ethernet/mscc/ocelot_vsc7514.c |  28 -
 drivers/net/mdio/mdio-mscc-miim.c          |  49 +-
 drivers/pinctrl/Kconfig                    |   4 +-
 drivers/pinctrl/pinctrl-microchip-sgpio.c  |  26 +-
 drivers/pinctrl/pinctrl-ocelot.c           |  33 +-
 include/linux/mdio/mdio-mscc-miim.h        |   3 +-
 include/linux/mfd/core.h                   |  10 +
 include/soc/mscc/ocelot.h                  |  18 +
 22 files changed, 1409 insertions(+), 64 deletions(-)
 create mode 100644 drivers/mfd/ocelot-core.c
 create mode 100644 drivers/mfd/ocelot-spi.c
 create mode 100644 drivers/mfd/ocelot.h
 create mode 100644 drivers/net/dsa/ocelot/ocelot_ext.c

-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:16 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:16 -0800
Subject: [RFC v6 net-next 4/9] net: mdio: mscc-miim: add ability to externally
 register phy reset control
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-5-colin.foster@in-advantage.com>

The ocelot-ext driver requires the phys to be externally controlled by an
optional parameter. This commit exposes that variable so it can be
utilized.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/net/dsa/ocelot/seville_vsc9953.c |  3 ++-
 drivers/net/mdio/mdio-mscc-miim.c        | 10 ++++++----
 include/linux/mdio/mdio-mscc-miim.h      |  3 ++-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index 8c1c9da61602..c6264e9f4c37 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -1021,7 +1021,8 @@ static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
 
 	rc = mscc_miim_setup(dev, &bus, "VSC9953 internal MDIO bus",
 			     ocelot->targets[GCB],
-			     ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK]);
+			     ocelot->map[GCB][GCB_MIIM_MII_STATUS & REG_MASK],
+			     NULL, 0);
 
 	if (rc) {
 		dev_err(dev, "failed to setup MDIO bus\n");
diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
index 6b14f3cf3891..07baf8390744 100644
--- a/drivers/net/mdio/mdio-mscc-miim.c
+++ b/drivers/net/mdio/mdio-mscc-miim.c
@@ -188,7 +188,8 @@ static const struct regmap_config mscc_miim_regmap_config = {
 };
 
 int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
-		    struct regmap *mii_regmap, int status_offset)
+		    struct regmap *mii_regmap, int status_offset,
+		    struct regmap *phy_regmap, int phy_offset)
 {
 	struct mscc_miim_dev *miim;
 	struct mii_bus *bus;
@@ -210,6 +211,8 @@ int mscc_miim_setup(struct device *dev, struct mii_bus **pbus, const char *name,
 
 	miim->regs = mii_regmap;
 	miim->mii_status_offset = status_offset;
+	miim->phy_regs = phy_regmap;
+	miim->phy_reset_offset = phy_offset;
 
 	*pbus = bus;
 
@@ -257,15 +260,14 @@ static int mscc_miim_probe(struct platform_device *pdev)
 		}
 	}
 
-	ret = mscc_miim_setup(dev, &bus, "mscc_miim", mii_regmap, 0);
+	ret = mscc_miim_setup(&pdev->dev, &bus, "mscc_miim", mii_regmap, 0,
+			      phy_regmap, 0);
 	if (ret < 0) {
 		dev_err(dev, "Unable to setup the MDIO bus\n");
 		return ret;
 	}
 
 	miim = bus->priv;
-	miim->phy_regs = phy_regmap;
-	miim->phy_reset_offset = 0;
 
 	ret = of_mdiobus_register(bus, dev->of_node);
 	if (ret < 0) {
diff --git a/include/linux/mdio/mdio-mscc-miim.h b/include/linux/mdio/mdio-mscc-miim.h
index 5b4ed2c3cbb9..5a95e43f73f9 100644
--- a/include/linux/mdio/mdio-mscc-miim.h
+++ b/include/linux/mdio/mdio-mscc-miim.h
@@ -14,6 +14,7 @@
 
 int mscc_miim_setup(struct device *device, struct mii_bus **bus,
 		    const char *name, struct regmap *mii_regmap,
-		    int status_offset);
+		    int status_offset, struct regmap *phy_regmap,
+		    int phy_offset);
 
 #endif
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:17 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:17 -0800
Subject: [RFC v6 net-next 5/9] mfd: add interface to check whether a device is
 mfd
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-6-colin.foster@in-advantage.com>

Some drivers will need to create regmaps differently based on whether they
are a child of an MFD or a standalone device. An example of this would be
if a regmap were directly memory-mapped or an external bus. In the
memory-mapped case a call to devm_regmap_init_mmio would return the correct
regmap. In the case of an MFD, the regmap would need to be requested from
the parent device.

This addition allows the driver to correctly reason about these scenarios.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/mfd/mfd-core.c   |  6 ++++++
 include/linux/mfd/core.h | 10 ++++++++++
 2 files changed, 16 insertions(+)

diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 684a011a6396..2ba6a692499b 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -33,6 +33,12 @@ static struct device_type mfd_dev_type = {
 	.name	= "mfd_device",
 };
 
+int device_is_mfd(struct platform_device *pdev)
+{
+	return (!strcmp(pdev->dev.type->name, mfd_dev_type.name));
+}
+EXPORT_SYMBOL(device_is_mfd);
+
 int mfd_cell_enable(struct platform_device *pdev)
 {
 	const struct mfd_cell *cell = mfd_get_cell(pdev);
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 0bc7cba798a3..c0719436b652 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -10,6 +10,7 @@
 #ifndef MFD_CORE_H
 #define MFD_CORE_H
 
+#include <generated/autoconf.h>
 #include <linux/platform_device.h>
 
 #define MFD_RES_SIZE(arr) (sizeof(arr) / sizeof(struct resource))
@@ -123,6 +124,15 @@ struct mfd_cell {
 	int			num_parent_supplies;
 };
 
+#ifdef CONFIG_MFD_CORE
+int device_is_mfd(struct platform_device *pdev);
+#else
+static inline int device_is_mfd(struct platform_device *pdev)
+{
+	return 0;
+}
+#endif
+
 /*
  * Convenience functions for clients using shared cells.  Refcounting
  * happens automatically, with the cell's enable/disable callbacks
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:18 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:18 -0800
Subject: [RFC v6 net-next 6/9] mfd: ocelot: add support for external mfd
 control over SPI for the VSC7512
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-7-colin.foster@in-advantage.com>

Create a single SPI MFD ocelot device that manages the SPI bus on the
external chip and can handle requests for regmaps. This should allow any
ocelot driver (pinctrl, miim, etc.) to be used externally, provided they
utilize regmaps.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/mfd/Kconfig                       |  19 ++
 drivers/mfd/Makefile                      |   3 +
 drivers/mfd/ocelot-core.c                 | 165 +++++++++++
 drivers/mfd/ocelot-spi.c                  | 325 ++++++++++++++++++++++
 drivers/mfd/ocelot.h                      |  36 +++
 drivers/net/mdio/mdio-mscc-miim.c         |  21 +-
 drivers/pinctrl/pinctrl-microchip-sgpio.c |  22 +-
 drivers/pinctrl/pinctrl-ocelot.c          |  29 +-
 include/soc/mscc/ocelot.h                 |  11 +
 9 files changed, 614 insertions(+), 17 deletions(-)
 create mode 100644 drivers/mfd/ocelot-core.c
 create mode 100644 drivers/mfd/ocelot-spi.c
 create mode 100644 drivers/mfd/ocelot.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ba0b3eb131f1..57bbf2d11324 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -948,6 +948,25 @@ config MFD_MENF21BMC
 	  This driver can also be built as a module. If so the module
 	  will be called menf21bmc.
 
+config MFD_OCELOT
+	tristate "Microsemi Ocelot External Control Support"
+	select MFD_CORE
+	help
+	  Say yes here to add support for Ocelot chips (VSC7511, VSC7512,
+	  VSC7513, VSC7514) controlled externally.
+
+	  All four of these chips can be controlled internally (MMIO) or
+	  externally via SPI, I2C, PCIe. This enables control of these chips
+	  over one or more of these buses.
+
+config MFD_OCELOT_SPI
+	tristate "Microsemi Ocelot SPI interface"
+	depends on MFD_OCELOT
+	depends on SPI_MASTER
+	select REGMAP_SPI
+	help
+	  Say yes here to add control to the MFD_OCELOT chips via SPI.
+
 config EZX_PCAP
 	bool "Motorola EZXPCAP Support"
 	depends on SPI_MASTER
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index df1ecc4a4c95..12513843067a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -120,6 +120,9 @@ obj-$(CONFIG_MFD_MC13XXX_I2C)	+= mc13xxx-i2c.o
 
 obj-$(CONFIG_MFD_CORE)		+= mfd-core.o
 
+obj-$(CONFIG_MFD_OCELOT)	+= ocelot-core.o
+obj-$(CONFIG_MFD_OCELOT_SPI)	+= ocelot-spi.o
+
 obj-$(CONFIG_EZX_PCAP)		+= ezx-pcap.o
 obj-$(CONFIG_MFD_CPCAP)		+= motorola-cpcap.o
 
diff --git a/drivers/mfd/ocelot-core.c b/drivers/mfd/ocelot-core.c
new file mode 100644
index 000000000000..590489481b8c
--- /dev/null
+++ b/drivers/mfd/ocelot-core.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * MFD core driver for the Ocelot chip family.
+ *
+ * The VSC7511, 7512, 7513, and 7514 can be controlled internally via an
+ * on-chip MIPS processor, or externally via SPI, I2C, PCIe. This core driver is
+ * intended to be the bus-agnostic glue between, for example, the SPI bus and
+ * the MFD children.
+ *
+ * Copyright 2021 Innovative Advantage Inc.
+ *
+ * Author: Colin Foster <colin.foster at in-advantage.com>
+ */
+
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+#include <asm/byteorder.h>
+
+#include "ocelot.h"
+
+#define GCB_SOFT_RST (0x0008)
+
+#define SOFT_CHIP_RST (0x1)
+
+static const struct resource vsc7512_gcb_resource = {
+	.start	= 0x71070000,
+	.end	= 0x7107022b,
+	.name	= "devcpu_gcb",
+};
+
+static int ocelot_reset(struct ocelot_core *core)
+{
+	int ret;
+
+	/*
+	 * Reset the entire chip here to put it into a completely known state.
+	 * Other drivers may want to reset their own subsystems. The register
+	 * self-clears, so one write is all that is needed
+	 */
+	ret = regmap_write(core->gcb_regmap, GCB_SOFT_RST, SOFT_CHIP_RST);
+	if (ret)
+		return ret;
+
+	msleep(100);
+
+	/*
+	 * A chip reset will clear the SPI configuration, so it needs to be done
+	 * again before we can access any more registers
+	 */
+	ret = ocelot_spi_initialize(core);
+
+	return ret;
+}
+
+static struct regmap *ocelot_devm_regmap_init(struct ocelot_core *core,
+					      struct device *dev,
+					      const struct resource *res)
+{
+	struct regmap *regmap;
+
+	regmap = dev_get_regmap(dev, res->name);
+	if (!regmap)
+		regmap = ocelot_spi_devm_get_regmap(core, dev, res);
+
+	return regmap;
+}
+
+struct regmap *ocelot_get_regmap_from_resource(struct device *dev,
+					       const struct resource *res)
+{
+	struct ocelot_core *core = dev_get_drvdata(dev);
+
+	return ocelot_devm_regmap_init(core, dev, res);
+}
+EXPORT_SYMBOL(ocelot_get_regmap_from_resource);
+
+static const struct resource vsc7512_miim1_resources[] = {
+	{
+		.start = 0x710700c0,
+		.end = 0x710700e3,
+		.name = "gcb_miim1",
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const struct resource vsc7512_pinctrl_resources[] = {
+	{
+		.start = 0x71070034,
+		.end = 0x7107009f,
+		.name = "gcb_gpio",
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const struct resource vsc7512_sgpio_resources[] = {
+	{
+		.start = 0x710700f8,
+		.end = 0x710701f7,
+		.name = "gcb_sio",
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static const struct mfd_cell vsc7512_devs[] = {
+	{
+		.name = "pinctrl-ocelot",
+		.of_compatible = "mscc,ocelot-pinctrl",
+		.num_resources = ARRAY_SIZE(vsc7512_pinctrl_resources),
+		.resources = vsc7512_pinctrl_resources,
+	},
+	{
+		.name = "pinctrl-sgpio",
+		.of_compatible = "mscc,ocelot-sgpio",
+		.num_resources = ARRAY_SIZE(vsc7512_sgpio_resources),
+		.resources = vsc7512_sgpio_resources,
+	},
+	{
+		.name = "ocelot-miim1",
+		.of_compatible = "mscc,ocelot-miim",
+		.num_resources = ARRAY_SIZE(vsc7512_miim1_resources),
+		.resources = vsc7512_miim1_resources,
+	},
+};
+
+int ocelot_core_init(struct ocelot_core *core)
+{
+	struct device *dev = core->dev;
+	int ret;
+
+	dev_set_drvdata(dev, core);
+
+	core->gcb_regmap = ocelot_devm_regmap_init(core, dev,
+						   &vsc7512_gcb_resource);
+	if (!core->gcb_regmap)
+		return -ENOMEM;
+
+	/* Prepare the chip */
+	ret = ocelot_reset(core);
+	if (ret) {
+		dev_err(dev, "ocelot mfd reset failed with code %d\n", ret);
+		return ret;
+	}
+
+	ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, vsc7512_devs,
+				   ARRAY_SIZE(vsc7512_devs), NULL, 0, NULL);
+	if (ret) {
+		dev_err(dev, "error adding mfd devices\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(ocelot_core_init);
+
+int ocelot_remove(struct ocelot_core *core)
+{
+	return 0;
+}
+EXPORT_SYMBOL(ocelot_remove);
+
+MODULE_DESCRIPTION("Ocelot Chip MFD driver");
+MODULE_AUTHOR("Colin Foster <colin.foster at in-advantage.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ocelot-spi.c b/drivers/mfd/ocelot-spi.c
new file mode 100644
index 000000000000..1e268a4dfa17
--- /dev/null
+++ b/drivers/mfd/ocelot-spi.c
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * SPI core driver for the Ocelot chip family.
+ *
+ * This driver will handle everything necessary to allow for communication over
+ * SPI to the VSC7511, VSC7512, VSC7513 and VSC7514 chips. The main functions
+ * are to prepare the chip's SPI interface for a specific bus speed, and a host
+ * processor's endianness. This will create and distribute regmaps for any MFD
+ * children.
+ *
+ * Copyright 2021 Innovative Advantage Inc.
+ *
+ * Author: Colin Foster <colin.foster at in-advantage.com>
+ */
+
+#include <linux/iopoll.h>
+#include <linux/kconfig.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+#include <asm/byteorder.h>
+
+#include "ocelot.h"
+
+struct ocelot_spi {
+	int spi_padding_bytes;
+	struct spi_device *spi;
+	struct ocelot_core core;
+	struct regmap *cpuorg_regmap;
+};
+
+#define DEV_CPUORG_IF_CTRL	(0x0000)
+#define DEV_CPUORG_IF_CFGSTAT	(0x0004)
+
+static const struct resource vsc7512_dev_cpuorg_resource = {
+	.start	= 0x71000000,
+	.end	= 0x710002ff,
+	.name	= "devcpu_org",
+};
+
+#define VSC7512_BYTE_ORDER_LE 0x00000000
+#define VSC7512_BYTE_ORDER_BE 0x81818181
+#define VSC7512_BIT_ORDER_MSB 0x00000000
+#define VSC7512_BIT_ORDER_LSB 0x42424242
+
+static struct ocelot_spi *core_to_ocelot_spi(struct ocelot_core *core)
+{
+	return container_of(core, struct ocelot_spi, core);
+}
+
+static int ocelot_spi_init_bus(struct ocelot_spi *ocelot_spi)
+{
+	struct spi_device *spi;
+	struct device *dev;
+	u32 val, check;
+	int err;
+
+	spi = ocelot_spi->spi;
+	dev = &spi->dev;
+
+#ifdef __LITTLE_ENDIAN
+	val = VSC7512_BYTE_ORDER_LE;
+#else
+	val = VSC7512_BYTE_ORDER_BE;
+#endif
+
+	err = regmap_write(ocelot_spi->cpuorg_regmap, DEV_CPUORG_IF_CTRL, val);
+	if (err)
+		return err;
+
+	val = ocelot_spi->spi_padding_bytes;
+	err = regmap_write(ocelot_spi->cpuorg_regmap, DEV_CPUORG_IF_CFGSTAT,
+			   val);
+	if (err)
+		return err;
+
+	check = val | 0x02000000;
+
+	err = regmap_read(ocelot_spi->cpuorg_regmap, DEV_CPUORG_IF_CFGSTAT,
+			  &val);
+	if (err)
+		return err;
+
+	if (check != val)
+		return -ENODEV;
+
+	return 0;
+}
+
+int ocelot_spi_initialize(struct ocelot_core *core)
+{
+	struct ocelot_spi *ocelot_spi = core_to_ocelot_spi(core);
+
+	return ocelot_spi_init_bus(ocelot_spi);
+}
+EXPORT_SYMBOL(ocelot_spi_initialize);
+
+static unsigned int ocelot_spi_translate_address(unsigned int reg)
+{
+	return cpu_to_be32((reg & 0xffffff) >> 2);
+}
+
+struct ocelot_spi_regmap_context {
+	u32 base;
+	struct ocelot_spi *ocelot_spi;
+};
+
+static int ocelot_spi_reg_read(void *context, unsigned int reg,
+			       unsigned int *val)
+{
+	struct ocelot_spi_regmap_context *regmap_context = context;
+	struct ocelot_spi *ocelot_spi = regmap_context->ocelot_spi;
+	struct spi_transfer tx, padding, rx;
+	struct spi_message msg;
+	struct spi_device *spi;
+	unsigned int addr;
+	u8 *tx_buf;
+
+	WARN_ON(!val);
+
+	spi = ocelot_spi->spi;
+
+	addr = ocelot_spi_translate_address(reg + regmap_context->base);
+	tx_buf = (u8 *)&addr;
+
+	spi_message_init(&msg);
+
+	memset(&tx, 0, sizeof(struct spi_transfer));
+
+	/* Ignore the first byte for the 24-bit address */
+	tx.tx_buf = &tx_buf[1];
+	tx.len = 3;
+
+	spi_message_add_tail(&tx, &msg);
+
+	if (ocelot_spi->spi_padding_bytes > 0) {
+		u8 dummy_buf[16] = {0};
+
+		memset(&padding, 0, sizeof(struct spi_transfer));
+
+		/* Just toggle the clock for padding bytes */
+		padding.len = ocelot_spi->spi_padding_bytes;
+		padding.tx_buf = dummy_buf;
+		padding.dummy_data = 1;
+
+		spi_message_add_tail(&padding, &msg);
+	}
+
+	memset(&rx, 0, sizeof(struct spi_transfer));
+	rx.rx_buf = val;
+	rx.len = 4;
+
+	spi_message_add_tail(&rx, &msg);
+
+	return spi_sync(spi, &msg);
+}
+
+static int ocelot_spi_reg_write(void *context, unsigned int reg,
+				unsigned int val)
+{
+	struct ocelot_spi_regmap_context *regmap_context = context;
+	struct ocelot_spi *ocelot_spi = regmap_context->ocelot_spi;
+	struct spi_transfer tx[2] = {0};
+	struct spi_message msg;
+	struct spi_device *spi;
+	unsigned int addr;
+	u8 *tx_buf;
+
+	spi = ocelot_spi->spi;
+
+	addr = ocelot_spi_translate_address(reg + regmap_context->base);
+	tx_buf = (u8 *)&addr;
+
+	spi_message_init(&msg);
+
+	/* Ignore the first byte for the 24-bit address and set the write bit */
+	tx_buf[1] |= BIT(7);
+	tx[0].tx_buf = &tx_buf[1];
+	tx[0].len = 3;
+
+	spi_message_add_tail(&tx[0], &msg);
+
+	memset(&tx[1], 0, sizeof(struct spi_transfer));
+	tx[1].tx_buf = &val;
+	tx[1].len = 4;
+
+	spi_message_add_tail(&tx[1], &msg);
+
+	return spi_sync(spi, &msg);
+}
+
+static const struct regmap_config ocelot_spi_regmap_config = {
+	.reg_bits = 24,
+	.reg_stride = 4,
+	.val_bits = 32,
+
+	.reg_read = ocelot_spi_reg_read,
+	.reg_write = ocelot_spi_reg_write,
+
+	.max_register = 0xffffffff,
+	.use_single_write = true,
+	.use_single_read = true,
+	.can_multi_write = false,
+
+	.reg_format_endian = REGMAP_ENDIAN_BIG,
+	.val_format_endian = REGMAP_ENDIAN_NATIVE,
+};
+
+struct regmap *
+ocelot_spi_devm_get_regmap(struct ocelot_core *core, struct device *dev,
+			   const struct resource *res)
+{
+	struct ocelot_spi *ocelot_spi = core_to_ocelot_spi(core);
+	struct ocelot_spi_regmap_context *context;
+	struct regmap_config regmap_config;
+	struct regmap *regmap;
+
+	context = devm_kzalloc(dev, sizeof(*context), GFP_KERNEL);
+	if (IS_ERR(context))
+		return ERR_CAST(context);
+
+	context->base = res->start;
+	context->ocelot_spi = ocelot_spi;
+
+	memcpy(&regmap_config, &ocelot_spi_regmap_config,
+	       sizeof(ocelot_spi_regmap_config));
+
+	regmap_config.name = res->name;
+	regmap_config.max_register = res->end - res->start;
+
+	regmap = devm_regmap_init(dev, NULL, context, &regmap_config);
+	if (IS_ERR(regmap))
+		return ERR_CAST(regmap);
+
+	return regmap;
+}
+
+static int ocelot_spi_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct ocelot_spi *ocelot_spi;
+	int err;
+
+	ocelot_spi = devm_kzalloc(dev, sizeof(*ocelot_spi), GFP_KERNEL);
+
+	if (!ocelot_spi)
+		return -ENOMEM;
+
+	if (spi->max_speed_hz <= 500000) {
+		ocelot_spi->spi_padding_bytes = 0;
+	} else {
+		/*
+		 * Calculation taken from the manual for IF_CFGSTAT:IF_CFG.
+		 * Register access time is 1us, so we need to configure and send
+		 * out enough padding bytes between the read request and data
+		 * transmission that lasts at least 1 microsecond.
+		 */
+		ocelot_spi->spi_padding_bytes = 1 +
+			(spi->max_speed_hz / 1000000 + 2) / 8;
+	}
+
+	ocelot_spi->spi = spi;
+
+	spi->bits_per_word = 8;
+
+	err = spi_setup(spi);
+	if (err < 0) {
+		dev_err(&spi->dev, "Error %d initializing SPI\n", err);
+		return err;
+	}
+
+	ocelot_spi->cpuorg_regmap =
+		ocelot_spi_devm_get_regmap(&ocelot_spi->core, dev,
+					   &vsc7512_dev_cpuorg_resource);
+	if (!ocelot_spi->cpuorg_regmap)
+		return -ENOMEM;
+
+	ocelot_spi->core.dev = dev;
+
+	/*
+	 * The chip must be set up for SPI before it gets initialized and reset.
+	 * This must be done before calling init, and after a chip reset is
+	 * performed.
+	 */
+	err = ocelot_spi_init_bus(ocelot_spi);
+	if (err) {
+		dev_err(dev, "Error %d initializing Ocelot SPI bus\n", err);
+		return err;
+	}
+
+	err = ocelot_core_init(&ocelot_spi->core);
+	if (err < 0) {
+		dev_err(dev, "Error %d initializing Ocelot MFD\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
+static int ocelot_spi_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+const struct of_device_id ocelot_spi_of_match[] = {
+	{ .compatible = "mscc,vsc7512_mfd_spi" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ocelot_spi_of_match);
+
+static struct spi_driver ocelot_spi_driver = {
+	.driver = {
+		.name = "ocelot_mfd_spi",
+		.of_match_table = of_match_ptr(ocelot_spi_of_match),
+	},
+	.probe = ocelot_spi_probe,
+	.remove = ocelot_spi_remove,
+};
+module_spi_driver(ocelot_spi_driver);
+
+MODULE_DESCRIPTION("Ocelot Chip MFD SPI driver");
+MODULE_AUTHOR("Colin Foster <colin.foster at in-advantage.com>");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/drivers/mfd/ocelot.h b/drivers/mfd/ocelot.h
new file mode 100644
index 000000000000..8bb2b57002be
--- /dev/null
+++ b/drivers/mfd/ocelot.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/*
+ * Copyright 2021 Innovative Advantage Inc.
+ */
+
+#include <linux/kconfig.h>
+#include <linux/regmap.h>
+
+struct ocelot_core {
+	struct device *dev;
+	struct regmap *gcb_regmap;
+};
+
+void ocelot_get_resource_name(char *name, const struct resource *res,
+			      int size);
+int ocelot_core_init(struct ocelot_core *core);
+int ocelot_remove(struct ocelot_core *core);
+
+#if IS_ENABLED(CONFIG_MFD_OCELOT_SPI)
+struct regmap *ocelot_spi_devm_get_regmap(struct ocelot_core *core,
+					  struct device *dev,
+					  const struct resource *res);
+int ocelot_spi_initialize(struct ocelot_core *core);
+#else
+static inline struct regmap *ocelot_spi_devm_get_regmap(
+		struct ocelot_core *core, struct device *dev,
+		const struct resource *res)
+{
+	return NULL;
+}
+
+static inline int ocelot_spi_initialize(struct ocelot_core *core)
+{
+	return -EOPNOTSUPP;
+}
+#endif
diff --git a/drivers/net/mdio/mdio-mscc-miim.c b/drivers/net/mdio/mdio-mscc-miim.c
index 07baf8390744..8e54bde06fd5 100644
--- a/drivers/net/mdio/mdio-mscc-miim.c
+++ b/drivers/net/mdio/mdio-mscc-miim.c
@@ -11,11 +11,13 @@
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mdio/mdio-mscc-miim.h>
+#include <linux/mfd/core.h>
 #include <linux/module.h>
 #include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <soc/mscc/ocelot.h>
 
 #define MSCC_MIIM_REG_STATUS		0x0
 #define		MSCC_MIIM_STATUS_STAT_PENDING	BIT(2)
@@ -230,13 +232,20 @@ static int mscc_miim_probe(struct platform_device *pdev)
 	struct mii_bus *bus;
 	int ret;
 
-	regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
-	if (IS_ERR(regs)) {
-		dev_err(dev, "Unable to map MIIM registers\n");
-		return PTR_ERR(regs);
-	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!device_is_mfd(pdev)) {
+		regs = devm_ioremap_resource(dev, res);
+		if (IS_ERR(regs)) {
+			dev_err(dev, "Unable to map MIIM registers\n");
+			return PTR_ERR(regs);
+		}
 
-	mii_regmap = devm_regmap_init_mmio(dev, regs, &mscc_miim_regmap_config);
+		mii_regmap = devm_regmap_init_mmio(dev, regs,
+						   &mscc_miim_regmap_config);
+	} else {
+		mii_regmap = ocelot_get_regmap_from_resource(dev->parent, res);
+	}
 
 	if (IS_ERR(mii_regmap)) {
 		dev_err(dev, "Unable to create MIIM regmap\n");
diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
index 8db3caf15cf2..53df095b33e0 100644
--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
+++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/gpio/driver.h>
 #include <linux/io.h>
+#include <linux/mfd/core.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/pinctrl/pinmux.h>
@@ -19,6 +20,7 @@
 #include <linux/property.h>
 #include <linux/regmap.h>
 #include <linux/reset.h>
+#include <soc/mscc/ocelot.h>
 
 #include "core.h"
 #include "pinconf.h"
@@ -137,7 +139,9 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
 
 static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
 {
-	return priv->properties->regoff[rno] + off;
+	int stride = regmap_get_reg_stride(priv->regs);
+
+	return (priv->properties->regoff[rno] + off) * stride;
 }
 
 static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
@@ -818,6 +822,7 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
 	struct fwnode_handle *fwnode;
 	struct reset_control *reset;
 	struct sgpio_priv *priv;
+	struct resource *res;
 	struct clk *clk;
 	u32 __iomem *regs;
 	u32 val;
@@ -850,11 +855,18 @@ static int microchip_sgpio_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
-	regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(regs))
-		return PTR_ERR(regs);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!device_is_mfd(pdev)) {
+		regs = devm_ioremap_resource(dev, res);
+		if (IS_ERR(regs))
+			return PTR_ERR(regs);
+
+		priv->regs = devm_regmap_init_mmio(dev, regs, &regmap_config);
+	} else {
+		priv->regs = ocelot_get_regmap_from_resource(dev->parent, res);
+	}
 
-	priv->regs = devm_regmap_init_mmio(dev, regs, &regmap_config);
 	if (IS_ERR(priv->regs))
 		return PTR_ERR(priv->regs);
 
diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c
index b6ad3ffb4596..d5485c6a0e20 100644
--- a/drivers/pinctrl/pinctrl-ocelot.c
+++ b/drivers/pinctrl/pinctrl-ocelot.c
@@ -10,6 +10,7 @@
 #include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/mfd/core.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
@@ -20,6 +21,7 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/slab.h>
+#include <soc/mscc/ocelot.h>
 
 #include "core.h"
 #include "pinconf.h"
@@ -1123,6 +1125,9 @@ static int lan966x_pinmux_set_mux(struct pinctrl_dev *pctldev,
 	return 0;
 }
 
+#if defined(REG)
+#undef REG
+#endif
 #define REG(r, info, p) ((r) * (info)->stride + (4 * ((p) / 32)))
 
 static int ocelot_gpio_set_direction(struct pinctrl_dev *pctldev,
@@ -1805,6 +1810,7 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct ocelot_pinctrl *info;
 	struct regmap *pincfg;
+	struct resource *res;
 	void __iomem *base;
 	int ret;
 	struct regmap_config regmap_config = {
@@ -1819,16 +1825,27 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev)
 
 	info->desc = (struct pinctrl_desc *)device_get_match_data(dev);
 
-	base = devm_ioremap_resource(dev,
-			platform_get_resource(pdev, IORESOURCE_MEM, 0));
-	if (IS_ERR(base))
-		return PTR_ERR(base);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (IS_ERR(res)) {
+		dev_err(dev, "Failed to get resource\n");
+		return PTR_ERR(res);
+	}
 
 	info->stride = 1 + (info->desc->npins - 1) / 32;
 
-	regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
+	if (!device_is_mfd(pdev)) {
+		base = devm_ioremap_resource(dev, res);
+		if (IS_ERR(base))
+			return PTR_ERR(base);
+
+		regmap_config.max_register =
+			OCELOT_GPIO_SD_MAP * info->stride + 15 * 4;
+
+		info->map = devm_regmap_init_mmio(dev, base, &regmap_config);
+	} else {
+		info->map = ocelot_get_regmap_from_resource(dev->parent, res);
+	}
 
-	info->map = devm_regmap_init_mmio(dev, base, &regmap_config);
 	if (IS_ERR(info->map)) {
 		dev_err(dev, "Failed to create regmap\n");
 		return PTR_ERR(info->map);
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 5c3a3597f1d2..70fae9c8b649 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -969,4 +969,15 @@ ocelot_mrp_del_ring_role(struct ocelot *ocelot, int port,
 }
 #endif
 
+#if IS_ENABLED(CONFIG_MFD_OCELOT)
+struct regmap *ocelot_get_regmap_from_resource(struct device *dev,
+					       const struct resource *res);
+#else
+static inline struct regmap *
+ocelot_get_regmap_from_resource(struct device *dev, const struct resource *res)
+{
+	return NULL;
+}
+#endif
+
 #endif
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:19 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:19 -0800
Subject: [RFC v6 net-next 7/9] net: mscc: ocelot: expose ocelot wm functions
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-8-colin.foster@in-advantage.com>

Expose ocelot_wm functions so they can be shared with other drivers.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean at nxp.com>
---
 drivers/net/ethernet/mscc/ocelot_devlink.c | 31 ++++++++++++++++++++++
 drivers/net/ethernet/mscc/ocelot_vsc7514.c | 28 -------------------
 include/soc/mscc/ocelot.h                  |  5 ++++
 3 files changed, 36 insertions(+), 28 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot_devlink.c b/drivers/net/ethernet/mscc/ocelot_devlink.c
index b8737efd2a85..d9ea75a14f2f 100644
--- a/drivers/net/ethernet/mscc/ocelot_devlink.c
+++ b/drivers/net/ethernet/mscc/ocelot_devlink.c
@@ -487,6 +487,37 @@ static void ocelot_watermark_init(struct ocelot *ocelot)
 	ocelot_setup_sharing_watermarks(ocelot);
 }
 
+/* Watermark encode
+ * Bit 8:   Unit; 0:1, 1:16
+ * Bit 7-0: Value to be multiplied with unit
+ */
+u16 ocelot_wm_enc(u16 value)
+{
+	WARN_ON(value >= 16 * BIT(8));
+
+	if (value >= BIT(8))
+		return BIT(8) | (value / 16);
+
+	return value;
+}
+EXPORT_SYMBOL(ocelot_wm_enc);
+
+u16 ocelot_wm_dec(u16 wm)
+{
+	if (wm & BIT(8))
+		return (wm & GENMASK(7, 0)) * 16;
+
+	return wm;
+}
+EXPORT_SYMBOL(ocelot_wm_dec);
+
+void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
+{
+	*inuse = (val & GENMASK(23, 12)) >> 12;
+	*maxuse = val & GENMASK(11, 0);
+}
+EXPORT_SYMBOL(ocelot_wm_stat);
+
 /* Pool size and type are fixed up at runtime. Keeping this structure to
  * look up the cell size multipliers.
  */
diff --git a/drivers/net/ethernet/mscc/ocelot_vsc7514.c b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
index 4f4a495a60ad..5e526545ef67 100644
--- a/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ b/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -307,34 +307,6 @@ static int ocelot_reset(struct ocelot *ocelot)
 	return 0;
 }
 
-/* Watermark encode
- * Bit 8:   Unit; 0:1, 1:16
- * Bit 7-0: Value to be multiplied with unit
- */
-static u16 ocelot_wm_enc(u16 value)
-{
-	WARN_ON(value >= 16 * BIT(8));
-
-	if (value >= BIT(8))
-		return BIT(8) | (value / 16);
-
-	return value;
-}
-
-static u16 ocelot_wm_dec(u16 wm)
-{
-	if (wm & BIT(8))
-		return (wm & GENMASK(7, 0)) * 16;
-
-	return wm;
-}
-
-static void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse)
-{
-	*inuse = (val & GENMASK(23, 12)) >> 12;
-	*maxuse = val & GENMASK(11, 0);
-}
-
 static const struct ocelot_ops ocelot_ops = {
 	.reset			= ocelot_reset,
 	.wm_enc			= ocelot_wm_enc,
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 70fae9c8b649..8b8ebede5a01 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -812,6 +812,11 @@ void ocelot_deinit(struct ocelot *ocelot);
 void ocelot_init_port(struct ocelot *ocelot, int port);
 void ocelot_deinit_port(struct ocelot *ocelot, int port);
 
+/* Watermark interface */
+u16 ocelot_wm_enc(u16 value);
+u16 ocelot_wm_dec(u16 wm);
+void ocelot_wm_stat(u32 val, u32 *inuse, u32 *maxuse);
+
 /* DSA callbacks */
 void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data);
 void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data);
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:20 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:20 -0800
Subject: [RFC v6 net-next 8/9] net: dsa: felix: add configurable device quirks
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-9-colin.foster@in-advantage.com>

The define FELIX_MAC_QUIRKS was used directly in the felix.c shared driver.
Other devices (VSC7512 for example) don't require the same quirks, so they
need to be configured on a per-device basis.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/net/dsa/ocelot/felix.c           | 7 +++++--
 drivers/net/dsa/ocelot/felix.h           | 1 +
 drivers/net/dsa/ocelot/felix_vsc9959.c   | 1 +
 drivers/net/dsa/ocelot/seville_vsc9953.c | 1 +
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 9957772201d5..4c086bcf111b 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -850,9 +850,12 @@ static void felix_phylink_mac_link_down(struct dsa_switch *ds, int port,
 					phy_interface_t interface)
 {
 	struct ocelot *ocelot = ds->priv;
+	struct felix *felix;
+
+	felix = ocelot_to_felix(ocelot);
 
 	ocelot_phylink_mac_link_down(ocelot, port, link_an_mode, interface,
-				     FELIX_MAC_QUIRKS);
+				     felix->info->quirks);
 }
 
 static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
@@ -867,7 +870,7 @@ static void felix_phylink_mac_link_up(struct dsa_switch *ds, int port,
 
 	ocelot_phylink_mac_link_up(ocelot, port, phydev, link_an_mode,
 				   interface, speed, duplex, tx_pause, rx_pause,
-				   FELIX_MAC_QUIRKS);
+				   felix->info->quirks);
 
 	if (felix->info->port_sched_speed_set)
 		felix->info->port_sched_speed_set(ocelot, port, speed);
diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h
index 9395ac119d33..f35894b06ce5 100644
--- a/drivers/net/dsa/ocelot/felix.h
+++ b/drivers/net/dsa/ocelot/felix.h
@@ -26,6 +26,7 @@ struct felix_info {
 	u16				vcap_pol_base2;
 	u16				vcap_pol_max2;
 	const struct ptp_clock_info	*ptp_caps;
+	u32				quirks;
 
 	/* Some Ocelot switches are integrated into the SoC without the
 	 * extraction IRQ line connected to the ARM GIC. By enabling this
diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c
index bf8d38239e7e..7e88480cc103 100644
--- a/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ b/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -2231,6 +2231,7 @@ static const struct felix_info felix_info_vsc9959 = {
 	.num_mact_rows		= 2048,
 	.num_ports		= 6,
 	.num_tx_queues		= OCELOT_NUM_TC,
+	.quirks			= FELIX_MAC_QUIRKS,
 	.quirk_no_xtr_irq	= true,
 	.ptp_caps		= &vsc9959_ptp_caps,
 	.mdio_bus_alloc		= vsc9959_mdio_bus_alloc,
diff --git a/drivers/net/dsa/ocelot/seville_vsc9953.c b/drivers/net/dsa/ocelot/seville_vsc9953.c
index c6264e9f4c37..aa31f741634e 100644
--- a/drivers/net/dsa/ocelot/seville_vsc9953.c
+++ b/drivers/net/dsa/ocelot/seville_vsc9953.c
@@ -1100,6 +1100,7 @@ static const struct felix_info seville_info_vsc9953 = {
 	.vcap_pol_max		= VSC9953_VCAP_POLICER_MAX,
 	.vcap_pol_base2		= VSC9953_VCAP_POLICER_BASE2,
 	.vcap_pol_max2		= VSC9953_VCAP_POLICER_MAX2,
+	.quirks			= FELIX_MAC_QUIRKS,
 	.num_mact_rows		= 2048,
 	.num_ports		= 10,
 	.num_tx_queues		= OCELOT_NUM_TC,
-- 
2.25.1



From colin.foster at in-advantage.com  Sat Jan 29 14:02:21 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sat, 29 Jan 2022 14:02:21 -0800
Subject: [RFC v6 net-next 9/9] net: dsa: ocelot: add external ocelot switch
 control
In-Reply-To: <20220129220221.2823127-1-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
Message-ID: <20220129220221.2823127-10-colin.foster@in-advantage.com>

Add control of an external VSC7512 chip by way of the ocelot-mfd interface.

Currently the four copper phy ports are fully functional. Communication to
external phys is also functional, but the SGMII / QSGMII interfaces are
currently non-functional.

Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
---
 drivers/mfd/ocelot-core.c           |   4 +
 drivers/net/dsa/ocelot/Kconfig      |  14 +
 drivers/net/dsa/ocelot/Makefile     |   5 +
 drivers/net/dsa/ocelot/ocelot_ext.c | 681 ++++++++++++++++++++++++++++
 include/soc/mscc/ocelot.h           |   2 +
 5 files changed, 706 insertions(+)
 create mode 100644 drivers/net/dsa/ocelot/ocelot_ext.c

diff --git a/drivers/mfd/ocelot-core.c b/drivers/mfd/ocelot-core.c
index 590489481b8c..17a77d618e92 100644
--- a/drivers/mfd/ocelot-core.c
+++ b/drivers/mfd/ocelot-core.c
@@ -122,6 +122,10 @@ static const struct mfd_cell vsc7512_devs[] = {
 		.num_resources = ARRAY_SIZE(vsc7512_miim1_resources),
 		.resources = vsc7512_miim1_resources,
 	},
+	{
+		.name = "ocelot-ext-switch",
+		.of_compatible = "mscc,vsc7512-ext-switch",
+	},
 };
 
 int ocelot_core_init(struct ocelot_core *core)
diff --git a/drivers/net/dsa/ocelot/Kconfig b/drivers/net/dsa/ocelot/Kconfig
index 220b0b027b55..f40b2c7171ad 100644
--- a/drivers/net/dsa/ocelot/Kconfig
+++ b/drivers/net/dsa/ocelot/Kconfig
@@ -1,4 +1,18 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config NET_DSA_MSCC_OCELOT_EXT
+	tristate "Ocelot External Ethernet switch support"
+	depends on NET_DSA && SPI
+	depends on NET_VENDOR_MICROSEMI
+	select MDIO_MSCC_MIIM
+	select MFD_OCELOT_CORE
+	select MSCC_OCELOT_SWITCH_LIB
+	select NET_DSA_TAG_OCELOT_8021Q
+	select NET_DSA_TAG_OCELOT
+	help
+	  This driver supports the VSC7511, VSC7512, VSC7513 and VSC7514 chips
+	  when controlled through SPI. It can be used with the Microsemi dev
+	  boards and an external CPU or custom hardware.
+
 config NET_DSA_MSCC_FELIX
 	tristate "Ocelot / Felix Ethernet switch support"
 	depends on NET_DSA && PCI
diff --git a/drivers/net/dsa/ocelot/Makefile b/drivers/net/dsa/ocelot/Makefile
index f6dd131e7491..d7f3f5a4461c 100644
--- a/drivers/net/dsa/ocelot/Makefile
+++ b/drivers/net/dsa/ocelot/Makefile
@@ -1,11 +1,16 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_NET_DSA_MSCC_FELIX) += mscc_felix.o
+obj-$(CONFIG_NET_DSA_MSCC_OCELOT_EXT) += mscc_ocelot_ext.o
 obj-$(CONFIG_NET_DSA_MSCC_SEVILLE) += mscc_seville.o
 
 mscc_felix-objs := \
 	felix.o \
 	felix_vsc9959.o
 
+mscc_ocelot_ext-objs := \
+	felix.o \
+	ocelot_ext.o
+
 mscc_seville-objs := \
 	felix.o \
 	seville_vsc9953.o
diff --git a/drivers/net/dsa/ocelot/ocelot_ext.c b/drivers/net/dsa/ocelot/ocelot_ext.c
new file mode 100644
index 000000000000..6fdff016673e
--- /dev/null
+++ b/drivers/net/dsa/ocelot/ocelot_ext.c
@@ -0,0 +1,681 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2021 Innovative Advantage Inc.
+ */
+
+#include <asm/byteorder.h>
+#include <linux/iopoll.h>
+#include <linux/kconfig.h>
+#include <linux/mdio/mdio-mscc-miim.h>
+#include <linux/of_mdio.h>
+#include <linux/phylink.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <soc/mscc/ocelot_ana.h>
+#include <soc/mscc/ocelot_dev.h>
+#include <soc/mscc/ocelot_qsys.h>
+#include <soc/mscc/ocelot_vcap.h>
+#include <soc/mscc/ocelot_ptp.h>
+#include <soc/mscc/ocelot_sys.h>
+#include <soc/mscc/ocelot.h>
+#include <soc/mscc/vsc7514_regs.h>
+#include "felix.h"
+
+#define VSC7512_NUM_PORTS		11
+
+#define OCELOT_SPI_PORT_MODE_INTERNAL	(1 << 0)
+#define OCELOT_SPI_PORT_MODE_SGMII	(1 << 1)
+#define OCELOT_SPI_PORT_MODE_QSGMII	(1 << 2)
+
+const u32 vsc7512_port_modes[VSC7512_NUM_PORTS] = {
+	OCELOT_SPI_PORT_MODE_INTERNAL,
+	OCELOT_SPI_PORT_MODE_INTERNAL,
+	OCELOT_SPI_PORT_MODE_INTERNAL,
+	OCELOT_SPI_PORT_MODE_INTERNAL,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+	OCELOT_SPI_PORT_MODE_SGMII,
+	OCELOT_SPI_PORT_MODE_SGMII | OCELOT_SPI_PORT_MODE_QSGMII,
+};
+
+struct ocelot_ext_data {
+	struct felix felix;
+	const u32 *port_modes;
+};
+
+static const u32 vsc7512_gcb_regmap[] = {
+	REG(GCB_SOFT_RST,			0x0008),
+	REG(GCB_MIIM_MII_STATUS,		0x009c),
+	REG(GCB_PHY_PHY_CFG,			0x00f0),
+	REG(GCB_PHY_PHY_STAT,			0x00f4),
+};
+
+static const u32 *vsc7512_regmap[TARGET_MAX] = {
+	[ANA] = vsc7514_ana_regmap,
+	[QS] = vsc7514_qs_regmap,
+	[QSYS] = vsc7514_qsys_regmap,
+	[REW] = vsc7514_rew_regmap,
+	[SYS] = vsc7514_sys_regmap,
+	[S0] = vsc7514_vcap_regmap,
+	[S1] = vsc7514_vcap_regmap,
+	[S2] = vsc7514_vcap_regmap,
+	[PTP] = vsc7514_ptp_regmap,
+	[GCB] = vsc7512_gcb_regmap,
+	[DEV_GMII] = vsc7514_dev_gmii_regmap,
+};
+
+#define VSC7512_BYTE_ORDER_LE 0x00000000
+#define VSC7512_BYTE_ORDER_BE 0x81818181
+#define VSC7512_BIT_ORDER_MSB 0x00000000
+#define VSC7512_BIT_ORDER_LSB 0x42424242
+
+static struct ocelot_ext_data *felix_to_ocelot_ext(struct felix *felix)
+{
+	return container_of(felix, struct ocelot_ext_data, felix);
+}
+
+static struct ocelot_ext_data *ocelot_to_ocelot_ext(struct ocelot *ocelot)
+{
+	struct felix *felix = ocelot_to_felix(ocelot);
+
+	return felix_to_ocelot_ext(felix);
+}
+
+static void ocelot_ext_reset_phys(struct ocelot *ocelot)
+{
+	ocelot_write(ocelot, 0, GCB_PHY_PHY_CFG);
+	ocelot_write(ocelot, 0x1ff, GCB_PHY_PHY_CFG);
+	mdelay(500);
+}
+
+static int ocelot_ext_reset(struct ocelot *ocelot)
+{
+	struct felix *felix = ocelot_to_felix(ocelot);
+	struct device *dev = ocelot->dev;
+	struct device_node *mdio_node;
+	int retries = 100;
+	int err, val;
+
+	ocelot_ext_reset_phys(ocelot);
+
+	mdio_node = of_get_child_by_name(dev->of_node, "mdio");
+	if (!mdio_node)
+		dev_info(ocelot->dev,
+			 "mdio children not found in device tree\n");
+
+	err = of_mdiobus_register(felix->imdio, mdio_node);
+	if (err) {
+		dev_err(ocelot->dev, "error registering MDIO bus\n");
+		return err;
+	}
+
+	felix->ds->slave_mii_bus = felix->imdio;
+
+	/* We might need to reset the switch core here, if that is possible */
+	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_INIT], 1);
+	if (err)
+		return err;
+
+	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_MEM_ENA], 1);
+	if (err)
+		return err;
+
+	do {
+		msleep(1);
+		regmap_field_read(ocelot->regfields[SYS_RESET_CFG_MEM_INIT],
+				  &val);
+	} while (val && --retries);
+
+	if (!retries)
+		return -ETIMEDOUT;
+
+	err = regmap_field_write(ocelot->regfields[SYS_RESET_CFG_CORE_ENA], 1);
+
+	return err;
+}
+
+static u32 ocelot_offset_from_reg_base(struct ocelot *ocelot, u32 target,
+				       u32 reg)
+{
+	return ocelot->map[target][reg & REG_MASK];
+}
+
+static const struct ocelot_ops vsc7512_ops = {
+	.reset		= ocelot_ext_reset,
+	.wm_enc		= ocelot_wm_enc,
+	.wm_dec		= ocelot_wm_dec,
+	.wm_stat	= ocelot_wm_stat,
+	.port_to_netdev	= felix_port_to_netdev,
+	.netdev_to_port	= felix_netdev_to_port,
+};
+
+static const struct resource vsc7512_target_io_res[TARGET_MAX] = {
+	[ANA] = {
+		.start	= 0x71880000,
+		.end	= 0x7188ffff,
+		.name	= "ana",
+	},
+	[QS] = {
+		.start	= 0x71080000,
+		.end	= 0x710800ff,
+		.name	= "qs",
+	},
+	[QSYS] = {
+		.start	= 0x71800000,
+		.end	= 0x719fffff,
+		.name	= "qsys",
+	},
+	[REW] = {
+		.start	= 0x71030000,
+		.end	= 0x7103ffff,
+		.name	= "rew",
+	},
+	[SYS] = {
+		.start	= 0x71010000,
+		.end	= 0x7101ffff,
+		.name	= "sys",
+	},
+	[S0] = {
+		.start	= 0x71040000,
+		.end	= 0x710403ff,
+		.name	= "s0",
+	},
+	[S1] = {
+		.start	= 0x71050000,
+		.end	= 0x710503ff,
+		.name	= "s1",
+	},
+	[S2] = {
+		.start	= 0x71060000,
+		.end	= 0x710603ff,
+		.name	= "s2",
+	},
+	[GCB] =	{
+		.start	= 0x71070000,
+		.end	= 0x7107022b,
+		.name	= "devcpu_gcb",
+	},
+};
+
+static const struct resource vsc7512_port_io_res[] = {
+	{
+		.start	= 0x711e0000,
+		.end	= 0x711effff,
+		.name	= "port0",
+	},
+	{
+		.start	= 0x711f0000,
+		.end	= 0x711fffff,
+		.name	= "port1",
+	},
+	{
+		.start	= 0x71200000,
+		.end	= 0x7120ffff,
+		.name	= "port2",
+	},
+	{
+		.start	= 0x71210000,
+		.end	= 0x7121ffff,
+		.name	= "port3",
+	},
+	{
+		.start	= 0x71220000,
+		.end	= 0x7122ffff,
+		.name	= "port4",
+	},
+	{
+		.start	= 0x71230000,
+		.end	= 0x7123ffff,
+		.name	= "port5",
+	},
+	{
+		.start	= 0x71240000,
+		.end	= 0x7124ffff,
+		.name	= "port6",
+	},
+	{
+		.start	= 0x71250000,
+		.end	= 0x7125ffff,
+		.name	= "port7",
+	},
+	{
+		.start	= 0x71260000,
+		.end	= 0x7126ffff,
+		.name	= "port8",
+	},
+	{
+		.start	= 0x71270000,
+		.end	= 0x7127ffff,
+		.name	= "port9",
+	},
+	{
+		.start	= 0x71280000,
+		.end	= 0x7128ffff,
+		.name	= "port10",
+	},
+};
+
+static const struct reg_field vsc7512_regfields[REGFIELD_MAX] = {
+	[ANA_ADVLEARN_VLAN_CHK] = REG_FIELD(ANA_ADVLEARN, 11, 11),
+	[ANA_ADVLEARN_LEARN_MIRROR] = REG_FIELD(ANA_ADVLEARN, 0, 10),
+	[ANA_ANEVENTS_MSTI_DROP] = REG_FIELD(ANA_ANEVENTS, 27, 27),
+	[ANA_ANEVENTS_ACLKILL] = REG_FIELD(ANA_ANEVENTS, 26, 26),
+	[ANA_ANEVENTS_ACLUSED] = REG_FIELD(ANA_ANEVENTS, 25, 25),
+	[ANA_ANEVENTS_AUTOAGE] = REG_FIELD(ANA_ANEVENTS, 24, 24),
+	[ANA_ANEVENTS_VS2TTL1] = REG_FIELD(ANA_ANEVENTS, 23, 23),
+	[ANA_ANEVENTS_STORM_DROP] = REG_FIELD(ANA_ANEVENTS, 22, 22),
+	[ANA_ANEVENTS_LEARN_DROP] = REG_FIELD(ANA_ANEVENTS, 21, 21),
+	[ANA_ANEVENTS_AGED_ENTRY] = REG_FIELD(ANA_ANEVENTS, 20, 20),
+	[ANA_ANEVENTS_CPU_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 19, 19),
+	[ANA_ANEVENTS_AUTO_LEARN_FAILED] = REG_FIELD(ANA_ANEVENTS, 18, 18),
+	[ANA_ANEVENTS_LEARN_REMOVE] = REG_FIELD(ANA_ANEVENTS, 17, 17),
+	[ANA_ANEVENTS_AUTO_LEARNED] = REG_FIELD(ANA_ANEVENTS, 16, 16),
+	[ANA_ANEVENTS_AUTO_MOVED] = REG_FIELD(ANA_ANEVENTS, 15, 15),
+	[ANA_ANEVENTS_DROPPED] = REG_FIELD(ANA_ANEVENTS, 14, 14),
+	[ANA_ANEVENTS_CLASSIFIED_DROP] = REG_FIELD(ANA_ANEVENTS, 13, 13),
+	[ANA_ANEVENTS_CLASSIFIED_COPY] = REG_FIELD(ANA_ANEVENTS, 12, 12),
+	[ANA_ANEVENTS_VLAN_DISCARD] = REG_FIELD(ANA_ANEVENTS, 11, 11),
+	[ANA_ANEVENTS_FWD_DISCARD] = REG_FIELD(ANA_ANEVENTS, 10, 10),
+	[ANA_ANEVENTS_MULTICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 9, 9),
+	[ANA_ANEVENTS_UNICAST_FLOOD] = REG_FIELD(ANA_ANEVENTS, 8, 8),
+	[ANA_ANEVENTS_DEST_KNOWN] = REG_FIELD(ANA_ANEVENTS, 7, 7),
+	[ANA_ANEVENTS_BUCKET3_MATCH] = REG_FIELD(ANA_ANEVENTS, 6, 6),
+	[ANA_ANEVENTS_BUCKET2_MATCH] = REG_FIELD(ANA_ANEVENTS, 5, 5),
+	[ANA_ANEVENTS_BUCKET1_MATCH] = REG_FIELD(ANA_ANEVENTS, 4, 4),
+	[ANA_ANEVENTS_BUCKET0_MATCH] = REG_FIELD(ANA_ANEVENTS, 3, 3),
+	[ANA_ANEVENTS_CPU_OPERATION] = REG_FIELD(ANA_ANEVENTS, 2, 2),
+	[ANA_ANEVENTS_DMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 1, 1),
+	[ANA_ANEVENTS_SMAC_LOOKUP] = REG_FIELD(ANA_ANEVENTS, 0, 0),
+	[ANA_TABLES_MACACCESS_B_DOM] = REG_FIELD(ANA_TABLES_MACACCESS, 18, 18),
+	[ANA_TABLES_MACTINDX_BUCKET] = REG_FIELD(ANA_TABLES_MACTINDX, 10, 11),
+	[ANA_TABLES_MACTINDX_M_INDEX] = REG_FIELD(ANA_TABLES_MACTINDX, 0, 9),
+	[GCB_SOFT_RST_SWC_RST] = REG_FIELD(GCB_SOFT_RST, 1, 1),
+	[QSYS_TIMED_FRAME_ENTRY_TFRM_VLD] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 20, 20),
+	[QSYS_TIMED_FRAME_ENTRY_TFRM_FP] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 8, 19),
+	[QSYS_TIMED_FRAME_ENTRY_TFRM_PORTNO] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 4, 7),
+	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_SEL] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 1, 3),
+	[QSYS_TIMED_FRAME_ENTRY_TFRM_TM_T] = REG_FIELD(QSYS_TIMED_FRAME_ENTRY, 0, 0),
+	[SYS_RESET_CFG_CORE_ENA] = REG_FIELD(SYS_RESET_CFG, 2, 2),
+	[SYS_RESET_CFG_MEM_ENA] = REG_FIELD(SYS_RESET_CFG, 1, 1),
+	[SYS_RESET_CFG_MEM_INIT] = REG_FIELD(SYS_RESET_CFG, 0, 0),
+	/* Replicated per number of ports (12), register size 4 per port */
+	[QSYS_SWITCH_PORT_MODE_PORT_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 14, 14, 12, 4),
+	[QSYS_SWITCH_PORT_MODE_SCH_NEXT_CFG] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 11, 13, 12, 4),
+	[QSYS_SWITCH_PORT_MODE_YEL_RSRVD] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 10, 10, 12, 4),
+	[QSYS_SWITCH_PORT_MODE_INGRESS_DROP_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 9, 9, 12, 4),
+	[QSYS_SWITCH_PORT_MODE_TX_PFC_ENA] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 1, 8, 12, 4),
+	[QSYS_SWITCH_PORT_MODE_TX_PFC_MODE] = REG_FIELD_ID(QSYS_SWITCH_PORT_MODE, 0, 0, 12, 4),
+	[SYS_PORT_MODE_DATA_WO_TS] = REG_FIELD_ID(SYS_PORT_MODE, 5, 6, 12, 4),
+	[SYS_PORT_MODE_INCL_INJ_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 3, 4, 12, 4),
+	[SYS_PORT_MODE_INCL_XTR_HDR] = REG_FIELD_ID(SYS_PORT_MODE, 1, 2, 12, 4),
+	[SYS_PORT_MODE_INCL_HDR_ERR] = REG_FIELD_ID(SYS_PORT_MODE, 0, 0, 12, 4),
+	[SYS_PAUSE_CFG_PAUSE_START] = REG_FIELD_ID(SYS_PAUSE_CFG, 10, 18, 12, 4),
+	[SYS_PAUSE_CFG_PAUSE_STOP] = REG_FIELD_ID(SYS_PAUSE_CFG, 1, 9, 12, 4),
+	[SYS_PAUSE_CFG_PAUSE_ENA] = REG_FIELD_ID(SYS_PAUSE_CFG, 0, 1, 12, 4),
+};
+
+static const struct ocelot_stat_layout vsc7512_stats_layout[] = {
+	{ .offset = 0x00,	.name = "rx_octets", },
+	{ .offset = 0x01,	.name = "rx_unicast", },
+	{ .offset = 0x02,	.name = "rx_multicast", },
+	{ .offset = 0x03,	.name = "rx_broadcast", },
+	{ .offset = 0x04,	.name = "rx_shorts", },
+	{ .offset = 0x05,	.name = "rx_fragments", },
+	{ .offset = 0x06,	.name = "rx_jabbers", },
+	{ .offset = 0x07,	.name = "rx_crc_align_errs", },
+	{ .offset = 0x08,	.name = "rx_sym_errs", },
+	{ .offset = 0x09,	.name = "rx_frames_below_65_octets", },
+	{ .offset = 0x0A,	.name = "rx_frames_65_to_127_octets", },
+	{ .offset = 0x0B,	.name = "rx_frames_128_to_255_octets", },
+	{ .offset = 0x0C,	.name = "rx_frames_256_to_511_octets", },
+	{ .offset = 0x0D,	.name = "rx_frames_512_to_1023_octets", },
+	{ .offset = 0x0E,	.name = "rx_frames_1024_to_1526_octets", },
+	{ .offset = 0x0F,	.name = "rx_frames_over_1526_octets", },
+	{ .offset = 0x10,	.name = "rx_pause", },
+	{ .offset = 0x11,	.name = "rx_control", },
+	{ .offset = 0x12,	.name = "rx_longs", },
+	{ .offset = 0x13,	.name = "rx_classified_drops", },
+	{ .offset = 0x14,	.name = "rx_red_prio_0", },
+	{ .offset = 0x15,	.name = "rx_red_prio_1", },
+	{ .offset = 0x16,	.name = "rx_red_prio_2", },
+	{ .offset = 0x17,	.name = "rx_red_prio_3", },
+	{ .offset = 0x18,	.name = "rx_red_prio_4", },
+	{ .offset = 0x19,	.name = "rx_red_prio_5", },
+	{ .offset = 0x1A,	.name = "rx_red_prio_6", },
+	{ .offset = 0x1B,	.name = "rx_red_prio_7", },
+	{ .offset = 0x1C,	.name = "rx_yellow_prio_0", },
+	{ .offset = 0x1D,	.name = "rx_yellow_prio_1", },
+	{ .offset = 0x1E,	.name = "rx_yellow_prio_2", },
+	{ .offset = 0x1F,	.name = "rx_yellow_prio_3", },
+	{ .offset = 0x20,	.name = "rx_yellow_prio_4", },
+	{ .offset = 0x21,	.name = "rx_yellow_prio_5", },
+	{ .offset = 0x22,	.name = "rx_yellow_prio_6", },
+	{ .offset = 0x23,	.name = "rx_yellow_prio_7", },
+	{ .offset = 0x24,	.name = "rx_green_prio_0", },
+	{ .offset = 0x25,	.name = "rx_green_prio_1", },
+	{ .offset = 0x26,	.name = "rx_green_prio_2", },
+	{ .offset = 0x27,	.name = "rx_green_prio_3", },
+	{ .offset = 0x28,	.name = "rx_green_prio_4", },
+	{ .offset = 0x29,	.name = "rx_green_prio_5", },
+	{ .offset = 0x2A,	.name = "rx_green_prio_6", },
+	{ .offset = 0x2B,	.name = "rx_green_prio_7", },
+	{ .offset = 0x40,	.name = "tx_octets", },
+	{ .offset = 0x41,	.name = "tx_unicast", },
+	{ .offset = 0x42,	.name = "tx_multicast", },
+	{ .offset = 0x43,	.name = "tx_broadcast", },
+	{ .offset = 0x44,	.name = "tx_collision", },
+	{ .offset = 0x45,	.name = "tx_drops", },
+	{ .offset = 0x46,	.name = "tx_pause", },
+	{ .offset = 0x47,	.name = "tx_frames_below_65_octets", },
+	{ .offset = 0x48,	.name = "tx_frames_65_to_127_octets", },
+	{ .offset = 0x49,	.name = "tx_frames_128_255_octets", },
+	{ .offset = 0x4A,	.name = "tx_frames_256_511_octets", },
+	{ .offset = 0x4B,	.name = "tx_frames_512_1023_octets", },
+	{ .offset = 0x4C,	.name = "tx_frames_1024_1526_octets", },
+	{ .offset = 0x4D,	.name = "tx_frames_over_1526_octets", },
+	{ .offset = 0x4E,	.name = "tx_yellow_prio_0", },
+	{ .offset = 0x4F,	.name = "tx_yellow_prio_1", },
+	{ .offset = 0x50,	.name = "tx_yellow_prio_2", },
+	{ .offset = 0x51,	.name = "tx_yellow_prio_3", },
+	{ .offset = 0x52,	.name = "tx_yellow_prio_4", },
+	{ .offset = 0x53,	.name = "tx_yellow_prio_5", },
+	{ .offset = 0x54,	.name = "tx_yellow_prio_6", },
+	{ .offset = 0x55,	.name = "tx_yellow_prio_7", },
+	{ .offset = 0x56,	.name = "tx_green_prio_0", },
+	{ .offset = 0x57,	.name = "tx_green_prio_1", },
+	{ .offset = 0x58,	.name = "tx_green_prio_2", },
+	{ .offset = 0x59,	.name = "tx_green_prio_3", },
+	{ .offset = 0x5A,	.name = "tx_green_prio_4", },
+	{ .offset = 0x5B,	.name = "tx_green_prio_5", },
+	{ .offset = 0x5C,	.name = "tx_green_prio_6", },
+	{ .offset = 0x5D,	.name = "tx_green_prio_7", },
+	{ .offset = 0x5E,	.name = "tx_aged", },
+	{ .offset = 0x80,	.name = "drop_local", },
+	{ .offset = 0x81,	.name = "drop_tail", },
+	{ .offset = 0x82,	.name = "drop_yellow_prio_0", },
+	{ .offset = 0x83,	.name = "drop_yellow_prio_1", },
+	{ .offset = 0x84,	.name = "drop_yellow_prio_2", },
+	{ .offset = 0x85,	.name = "drop_yellow_prio_3", },
+	{ .offset = 0x86,	.name = "drop_yellow_prio_4", },
+	{ .offset = 0x87,	.name = "drop_yellow_prio_5", },
+	{ .offset = 0x88,	.name = "drop_yellow_prio_6", },
+	{ .offset = 0x89,	.name = "drop_yellow_prio_7", },
+	{ .offset = 0x8A,	.name = "drop_green_prio_0", },
+	{ .offset = 0x8B,	.name = "drop_green_prio_1", },
+	{ .offset = 0x8C,	.name = "drop_green_prio_2", },
+	{ .offset = 0x8D,	.name = "drop_green_prio_3", },
+	{ .offset = 0x8E,	.name = "drop_green_prio_4", },
+	{ .offset = 0x8F,	.name = "drop_green_prio_5", },
+	{ .offset = 0x90,	.name = "drop_green_prio_6", },
+	{ .offset = 0x91,	.name = "drop_green_prio_7", },
+};
+
+static void vsc7512_phylink_validate(struct ocelot *ocelot, int port,
+				     unsigned long *supported,
+				     struct phylink_link_state *state)
+{
+	struct ocelot_port *ocelot_port = ocelot->ports[port];
+
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+
+	if (state->interface != PHY_INTERFACE_MODE_NA &&
+	    state->interface != ocelot_port->phy_mode) {
+		bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+		return;
+	}
+
+	phylink_set_port_modes(mask);
+
+	phylink_set(mask, Pause);
+	phylink_set(mask, Autoneg);
+	phylink_set(mask, Asym_Pause);
+	phylink_set(mask, 10baseT_Half);
+	phylink_set(mask, 10baseT_Full);
+	phylink_set(mask, 100baseT_Half);
+	phylink_set(mask, 100baseT_Full);
+	phylink_set(mask, 1000baseT_Half);
+	phylink_set(mask, 1000baseT_Full);
+
+	bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
+	bitmap_and(state->advertising, state->advertising, mask,
+		   __ETHTOOL_LINK_MODE_MASK_NBITS);
+}
+
+static int vsc7512_prevalidate_phy_mode(struct ocelot *ocelot, int port,
+					phy_interface_t phy_mode)
+{
+	struct ocelot_ext_data *ocelot_ext = ocelot_to_ocelot_ext(ocelot);
+
+	switch (phy_mode) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+		if (ocelot_ext->port_modes[port] &
+				OCELOT_SPI_PORT_MODE_INTERNAL)
+			return 0;
+		return -EOPNOTSUPP;
+	case PHY_INTERFACE_MODE_SGMII:
+		if (ocelot_ext->port_modes[port] & OCELOT_SPI_PORT_MODE_SGMII)
+			return 0;
+		return -EOPNOTSUPP;
+	case PHY_INTERFACE_MODE_QSGMII:
+		if (ocelot_ext->port_modes[port] & OCELOT_SPI_PORT_MODE_QSGMII)
+			return 0;
+		return -EOPNOTSUPP;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static int vsc7512_port_setup_tc(struct dsa_switch *ds, int port,
+				 enum tc_setup_type type, void *type_data)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct vcap_props vsc7512_vcap_props[] = {
+	[VCAP_ES0] = {
+		.action_type_width = 0,
+		.action_table = {
+			[ES0_ACTION_TYPE_NORMAL] = {
+				.width = 73,
+				.count = 1,
+			},
+		},
+		.target = S0,
+		.keys = vsc7514_vcap_es0_keys,
+		.actions = vsc7514_vcap_es0_actions,
+	},
+	[VCAP_IS1] = {
+		.action_type_width = 0,
+		.action_table = {
+			[IS1_ACTION_TYPE_NORMAL] = {
+				.width = 78,
+				.count = 4,
+			},
+		},
+		.target = S1,
+		.keys = vsc7514_vcap_is1_keys,
+		.actions = vsc7514_vcap_is1_actions,
+	},
+	[VCAP_IS2] = {
+		.action_type_width = 1,
+		.action_table = {
+			[IS2_ACTION_TYPE_NORMAL] = {
+				.width = 49,
+				.count = 2,
+			},
+			[IS2_ACTION_TYPE_SMAC_SIP] = {
+				.width = 6,
+				.count = 4,
+			},
+		},
+		.target = S2,
+		.keys = vsc7514_vcap_is2_keys,
+		.actions = vsc7514_vcap_is2_actions,
+	},
+};
+
+static struct regmap *vsc7512_regmap_init(struct ocelot *ocelot,
+					  struct resource *res)
+{
+	struct device *dev = ocelot->dev;
+	struct regmap *regmap;
+
+	regmap = ocelot_get_regmap_from_resource(dev->parent, res);
+	if (IS_ERR(regmap))
+		return ERR_CAST(regmap);
+
+	return regmap;
+}
+
+static int vsc7512_mdio_bus_alloc(struct ocelot *ocelot)
+{
+	struct felix *felix = ocelot_to_felix(ocelot);
+	struct device *dev = ocelot->dev;
+	u32 mii_offset, phy_offset;
+	struct mii_bus *bus;
+	int err;
+
+	mii_offset = ocelot_offset_from_reg_base(ocelot, GCB,
+						 GCB_MIIM_MII_STATUS);
+
+	phy_offset = ocelot_offset_from_reg_base(ocelot, GCB, GCB_PHY_PHY_CFG);
+
+	err = mscc_miim_setup(dev, &bus, "ocelot_ext MDIO bus",
+			       ocelot->targets[GCB], mii_offset,
+			       ocelot->targets[GCB], phy_offset);
+	if (err) {
+		dev_err(dev, "failed to setup MDIO bus\n");
+		return err;
+	}
+
+	felix->imdio = bus;
+
+	return err;
+}
+
+
+static void vsc7512_mdio_bus_free(struct ocelot *ocelot)
+{
+	struct felix *felix = ocelot_to_felix(ocelot);
+
+	if (felix->imdio)
+		mdiobus_unregister(felix->imdio);
+}
+
+static const struct felix_info ocelot_ext_info = {
+	.target_io_res			= vsc7512_target_io_res,
+	.port_io_res			= vsc7512_port_io_res,
+	.regfields			= vsc7512_regfields,
+	.map				= vsc7512_regmap,
+	.ops				= &vsc7512_ops,
+	.stats_layout			= vsc7512_stats_layout,
+	.num_stats			= ARRAY_SIZE(vsc7512_stats_layout),
+	.vcap				= vsc7512_vcap_props,
+	.num_mact_rows			= 1024,
+	.num_ports			= VSC7512_NUM_PORTS,
+	.num_tx_queues			= OCELOT_NUM_TC,
+	.mdio_bus_alloc			= vsc7512_mdio_bus_alloc,
+	.mdio_bus_free			= vsc7512_mdio_bus_free,
+	.phylink_validate		= vsc7512_phylink_validate,
+	.prevalidate_phy_mode		= vsc7512_prevalidate_phy_mode,
+	.port_setup_tc			= vsc7512_port_setup_tc,
+	.init_regmap			= vsc7512_regmap_init,
+};
+
+static int ocelot_ext_probe(struct platform_device *pdev)
+{
+	struct ocelot_ext_data *ocelot_ext;
+	struct dsa_switch *ds;
+	struct ocelot *ocelot;
+	struct felix *felix;
+	struct device *dev;
+	int err;
+
+	dev = &pdev->dev;
+
+	ocelot_ext = devm_kzalloc(dev, sizeof(struct ocelot_ext_data),
+				  GFP_KERNEL);
+
+	if (!ocelot_ext)
+		return -ENOMEM;
+
+	dev_set_drvdata(dev, ocelot_ext);
+
+	ocelot_ext->port_modes = vsc7512_port_modes;
+	felix = &ocelot_ext->felix;
+
+	ocelot = &felix->ocelot;
+	ocelot->dev = dev;
+
+	ocelot->num_flooding_pgids = 1;
+
+	felix->info = &ocelot_ext_info;
+
+	ds = kzalloc(sizeof(*ds), GFP_KERNEL);
+	if (!ds) {
+		err = -ENOMEM;
+		dev_err(dev, "Failed to allocate DSA switch\n");
+		return err;
+	}
+
+	ds->dev = dev;
+	ds->num_ports = felix->info->num_ports;
+	ds->num_tx_queues = felix->info->num_tx_queues;
+
+	ds->ops = &felix_switch_ops;
+	ds->priv = ocelot;
+	felix->ds = ds;
+	felix->tag_proto = DSA_TAG_PROTO_OCELOT;
+
+	err = dsa_register_switch(ds);
+
+	if (err) {
+		dev_err(dev, "Failed to register DSA switch: %d\n", err);
+		goto err_register_ds;
+	}
+
+	return 0;
+
+err_register_ds:
+	kfree(ds);
+	return err;
+}
+
+static int ocelot_ext_remove(struct platform_device *pdev)
+{
+	struct ocelot_ext_data *ocelot_ext;
+	struct felix *felix;
+
+	ocelot_ext = dev_get_drvdata(&pdev->dev);
+	felix = &ocelot_ext->felix;
+
+	dsa_unregister_switch(felix->ds);
+
+	kfree(felix->ds);
+
+	devm_kfree(&pdev->dev, ocelot_ext);
+
+	return 0;
+}
+
+const struct of_device_id ocelot_ext_switch_of_match[] = {
+	{ .compatible = "mscc,vsc7512-ext-switch" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, ocelot_ext_switch_of_match);
+
+static struct platform_driver ocelot_ext_switch_driver = {
+	.driver = {
+		.name = "ocelot-ext-switch",
+		.of_match_table = of_match_ptr(ocelot_ext_switch_of_match),
+	},
+	.probe = ocelot_ext_probe,
+	.remove = ocelot_ext_remove,
+};
+module_platform_driver(ocelot_ext_switch_driver);
+
+MODULE_DESCRIPTION("External Ocelot Switch driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 8b8ebede5a01..62cd61d4142e 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -399,6 +399,8 @@ enum ocelot_reg {
 	GCB_MIIM_MII_STATUS,
 	GCB_MIIM_MII_CMD,
 	GCB_MIIM_MII_DATA,
+	GCB_PHY_PHY_CFG,
+	GCB_PHY_PHY_STAT,
 	DEV_CLOCK_CFG = DEV_GMII << TARGET_OFFSET,
 	DEV_PORT_MISC,
 	DEV_EVENTS,
-- 
2.25.1



From martin.juecker at gmail.com  Sat Jan 29 14:14:52 2022
From: martin.juecker at gmail.com (Martin =?iso-8859-1?Q?J=FCcker?=)
Date: Sat, 29 Jan 2022 23:14:52 +0100
Subject: [PATCH] ARM: dts: add 533 MHz step to p4note GPU opp table
Message-ID: <20220129221452.GA36524@adroid>

The p4note devices support 533 MHz GPU speed, so let's make use of it.

Signed-off-by: Martin J?cker <martin.juecker at gmail.com>
---
 arch/arm/boot/dts/exynos4412-p4note.dtsi | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4412-p4note.dtsi b/arch/arm/boot/dts/exynos4412-p4note.dtsi
index 4ae6eb3091c4..d277b2337ae0 100644
--- a/arch/arm/boot/dts/exynos4412-p4note.dtsi
+++ b/arch/arm/boot/dts/exynos4412-p4note.dtsi
@@ -355,6 +355,13 @@ &gpu {
 	status = "okay";
 };
 
+&gpu_opp_table {
+	opp-533000000 {
+		opp-hz = /bits/ 64 <533000000>;
+		opp-microvolt = <1075000>;
+	};
+};
+
 &hsotg {
 	vusb_a-supply = <&ldo12_reg>;
 	dr_mode = "peripheral";
-- 
2.25.1



From macro at orcam.me.uk  Sat Jan 29 14:34:03 2022
From: macro at orcam.me.uk (Maciej W. Rozycki)
Date: Sat, 29 Jan 2022 22:34:03 +0000 (GMT)
Subject: [PATCH 19/19] PCI: Set bridge map_irq and swizzle_irq to default
 functions
In-Reply-To: <20220111214608.GA169999@bhelgaas>
References: <20220111214608.GA169999@bhelgaas>
Message-ID: <alpine.DEB.2.21.2201220459090.58572@angie.orcam.me.uk>

On Tue, 11 Jan 2022, Bjorn Helgaas wrote:

> This patch removed all the ->swizzle_irq users in drivers/pci/, which
> is great -- IIUC swizzling is specified by the PCI-to-PCI Bridge Spec,
> r1.2, sec 9.1, and should not be device-specific.  I assume the few
> remaining arch/ users (arm and alpha) are either bugs or workarounds
> for broken devices.

 I skimmed over the Alpha stuff and it seems to mostly care about setting 
the slot value returned differently and defers to `pci_common_swizzle' for 
actual pin determination.  This could be moderately easy to sort out.

 One exception is `takara_swizzle' which looks incomplete to me; as this 
is a PICMG device[1] someone would have to fill in the missing details as 
AFAICT the PICMG connector is supposed to provide all the INT# A-D lines 
and then routing is done on the backplane using binding defined by PICMG.

 According to DEC documentation there's an alternative interrupt routing 
mode available too, using a external interrupt controller FPGA placed on 
the backplane[2], where no swizzling is done and instead each of the four 
INT# lines across all the PCI slots, up to 16, provided by a backplane is 
individually routed to 64 inputs of the interrupt controller.

 There is a paper by DEC available online[3] that could help filling in 
the missing details for either mode, especially someone who has access to 
such a system and could verify it in reality.

References:

[1] "DIGITAL 21164 PICMG SBC, User Information for the EBM21 and EBM23",
    V1.0, Digital Equipment Corporation, June 1997, Part Number: 
    EK-A0937-UG. A01

[2] "DIGITAL Modular Computing Components, OEM Information for DMCC 
    Backplanes", Version 4.1, Compaq Computer Corporation, January 1999, 
    Order Number: EK-A0929-TM. C01

[3] Ross L. Armstrong, "PCI Interrupt Controller for Industry Standard 
    PCI-ISA Bus Architecture using PCI-to-PCI Bridge Technology", Digital 
    Equipment Corporation (Scotland) Ltd., 1996

 FWIW,

  Maciej


From arnd at arndb.de  Sat Jan 29 14:12:53 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Sat, 29 Jan 2022 23:12:53 +0100
Subject: [PATCH V4 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <20220129121728.1079364-9-guoren@kernel.org>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-9-guoren@kernel.org>
Message-ID: <CAK8P3a3JGP6fLVOyLgdNw2YpRSmArbEX8orUhRrN=GHmcdk=1g@mail.gmail.com>

> Implement compat sys_call_table and some system call functions:
> truncate64, ftruncate64, fallocate, pread64, pwrite64,
> sync_file_range, readahead, fadvise64_64 which need argument
> translation.
>
> Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> Signed-off-by: Guo Ren <guoren at kernel.org>
> Cc: Arnd Bergmann <arnd at arndb.de>

This all looks really good, but I would change one detail:

> +#ifndef compat_arg_u64
> +#define compat_arg_u64(name)           u32  name##_lo, u32  name##_hi
> +#define compat_arg_u64_dual(name)      u32, name##_lo, u32, name##_hi
> +#define compat_arg_u64_glue(name)      (((u64)name##_hi << 32) | \
> +                                        ((u64)name##_lo & 0xffffffffUL))
> +#endif

I would make these endian-specific, and reverse them on big-endian
architectures. That way it
should be possible to share them across all compat architectures
without needing the override
option.

        Arnd


From jassisinghbrar at gmail.com  Sat Jan 29 16:17:33 2022
From: jassisinghbrar at gmail.com (Jassi Brar)
Date: Sat, 29 Jan 2022 18:17:33 -0600
Subject: [PATCH 0/7] mailbox: imx: misc fix and SECO MU support
In-Reply-To: <DU0PR04MB941793A918C5E08C9A48BCAC88209@DU0PR04MB9417.eurprd04.prod.outlook.com>
References: <20220104062547.2103016-1-peng.fan@oss.nxp.com>
 <DU0PR04MB941793A918C5E08C9A48BCAC88209@DU0PR04MB9417.eurprd04.prod.outlook.com>
Message-ID: <CABb+yY2tFtwFvWGh5OtHYwfvkjv3z51CD3cyemq=4Vd-YnY6aQ@mail.gmail.com>

On Wed, Jan 26, 2022 at 2:28 AM Peng Fan <peng.fan at nxp.com> wrote:
>
> > Subject: [PATCH 0/7] mailbox: imx: misc fix and SECO MU support
>
> Ping..
>
This adds new features, so it will go in the next release.
Meanwhile you may want to fix the issue in 3/7 reported by lkp test bot.

thanks.




> Thanks,
> Peng.
>
> >
> > From: Peng Fan <peng.fan at nxp.com>
> >
> > This patchset includes a few fixes for low power and i.MX8 SECO MU support
> >
> > Franck LENORMAND (1):
> >   mailbox: imx: add i.MX8 SECO MU support
> >
> > Peng Fan (2):
> >   dt-bindings: mailbox: imx-mu: add i.MX8 SECO MU support
> >   mailbox: imx: introduce rxdb callback
> >
> > Ranjani Vaidyanathan (2):
> >   mailbox: imx: Add support for identifying SCU wakeup source from sysfs
> >   mailbox: imx: enlarge timeout while reading/writing messages to SCFW
> >
> > Robin Gong (2):
> >   mailbox: imx: fix wakeup failure from freeze mode
> >   mailbox: imx: fix crash in resume on i.mx8ulp
> >
> >  .../devicetree/bindings/mailbox/fsl,mu.yaml   |   1 +
> >  drivers/mailbox/imx-mailbox.c                 | 249
> > +++++++++++++++++-
> >  2 files changed, 243 insertions(+), 7 deletions(-)
> >
> > --
> > 2.25.1
>


From theleks at ko-hh.de  Sat Jan 29 16:21:08 2022
From: theleks at ko-hh.de (Lutz Koschorreck)
Date: Sun, 30 Jan 2022 01:21:08 +0100
Subject: [PATCH] arm64: dts: meson-sm1-odroid: use correct enable-gpio
 pin for tf-io regulator
In-Reply-To: <20220127123814.GA152653@odroid-VirtualBox>
References: <20220126234325.GA7363@odroid-VirtualBox>
 <651adde5-4887-4701-5183-6a35a443574c@baylibre.com>
 <20220127123814.GA152653@odroid-VirtualBox>
Message-ID: <20220130002108.GA408329@odroid-VirtualBox>

On Thu, Jan 27, 2022 at 01:38:14PM +0100, Lutz Koschorreck wrote:
> On Thu, Jan 27, 2022 at 11:15:12AM +0100, Neil Armstrong wrote:
> > Hi,
> > 
> > On 27/01/2022 00:43, Lutz Koschorreck wrote:
> > > The interrupt pin of the external ethernet phy is used, instead of the
> > > enable-gpio pin of the tf-io regulator. The GPIOE_2 pin is located in
> > > the gpio_ao bank.
> > > Using open drain prevents reboot issues.
> > > 
> > > This causes phy interrupt problems at system startup.
> > > [   76.645190] irq 36: nobody cared (try booting with the "irqpoll" option)
> > > [   76.649617] CPU: 0 PID: 1416 Comm: irq/36-0.0:00 Not tainted 5.16.0 #2
> > > [   76.649629] Hardware name: Hardkernel ODROID-HC4 (DT)
> > > [   76.649635] Call trace:
> > > [   76.649638]  dump_backtrace+0x0/0x1c8
> > > [   76.649658]  show_stack+0x14/0x60
> > > [   76.649667]  dump_stack_lvl+0x64/0x7c
> > > [   76.649676]  dump_stack+0x14/0x2c
> > > [   76.649683]  __report_bad_irq+0x38/0xe8
> > > [   76.649695]  note_interrupt+0x220/0x3a0
> > > [   76.649704]  handle_irq_event_percpu+0x58/0x88
> > > [   76.649713]  handle_irq_event+0x44/0xd8
> > > [   76.649721]  handle_fasteoi_irq+0xa8/0x130
> > > [   76.649730]  generic_handle_domain_irq+0x38/0x58
> > > [   76.649738]  gic_handle_irq+0x9c/0xb8
> > > [   76.649747]  call_on_irq_stack+0x28/0x38
> > > [   76.649755]  do_interrupt_handler+0x7c/0x80
> > > [   76.649763]  el1_interrupt+0x34/0x80
> > > [   76.649772]  el1h_64_irq_handler+0x14/0x20
> > > [   76.649781]  el1h_64_irq+0x74/0x78
> > > [   76.649788]  irq_finalize_oneshot.part.56+0x68/0xf8
> > > [   76.649796]  irq_thread_fn+0x5c/0x98
> > > [   76.649804]  irq_thread+0x13c/0x260
> > > [   76.649812]  kthread+0x144/0x178
> > > [   76.649822]  ret_from_fork+0x10/0x20
> > > [   76.649830] handlers:
> > > [   76.653170] [<0000000025a6cd31>] irq_default_primary_handler threaded [<0000000093580eb7>] phy_interrupt
> > > [   76.661256] Disabling IRQ #36
> > > 
> > > Fixes: 1f80a5cf74a6 ("arm64: dts: meson-sm1-odroid: add missing enable gpio and supply for tf_io regulator")
> > > 
> > > Signed-off-by: Lutz Koschorreck <theleks at ko-hh.de>
> > > ---
> > >  arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > index 0bd1e98a0eef..ddb1b345397f 100644
> > > --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid.dtsi
> > > @@ -48,7 +48,7 @@ tf_io: gpio-regulator-tf_io {
> > >  		regulator-max-microvolt = <3300000>;
> > >  		vin-supply = <&vcc_5v>;
> > >  
> > > -		enable-gpio = <&gpio GPIOE_2 GPIO_ACTIVE_HIGH>;
> > > +		enable-gpio = <&gpio_ao GPIOE_2 GPIO_OPEN_DRAIN>;
> > 
> > Wow, indeed it's not the right GPIO chip... my bad.
> > 
> > >  		enable-active-high;
> > >  		regulator-always-on;
> > >  
> > 
> > Concerning the GPIO_OPEN_DRAIN, it's right since the line has a pull-up, does it really fix reboot issues ?
> There is a 10k pull up on the pin of C4 and HC4. Therefore it is fine to
> set to GPIO_OPEN_DRAIN. If this pin is left ACTIVE_HIGH and I call
> reboot, the bootloader is does not came up, it is an boot loop. Tobetter
> fixed that with a reset device driver, but I think using GPIO_OPEN_DRAIN
> is the right solution.
Sorry, this comment is not entirely correct. The GPIO_OPEN_DRAIN is
needed to fix a boot loop at bl2 level. Also it look like that the reset
driver fixes the boot loop at BL3X boot level and is needed for proper
operation.
> > 
> > Anyway, can you split the changes ? First for gpio_ao, second for GPIO_OPEN_DRAIN ?
> Yes of cause. I will generate a new patch set.
> > 
> > Neil
> > 
> > 
> > _______________________________________________
> > linux-amlogic mailing list
> > linux-amlogic at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-amlogic
> 
> _______________________________________________
> linux-amlogic mailing list
> linux-amlogic at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-amlogic


From robh at kernel.org  Sat Jan 29 16:22:17 2022
From: robh at kernel.org (Rob Herring)
Date: Sat, 29 Jan 2022 18:22:17 -0600
Subject: [PATCH 4/5] dt-bindings: mfd: samsung,
 exynos5433-lpass: Convert to dtschema
In-Reply-To: <20220129175332.298666-4-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <20220129175332.298666-4-krzysztof.kozlowski@canonical.com>
Message-ID: <1643502137.259074.416953.nullmailer@robh.at.kernel.org>

On Sat, 29 Jan 2022 18:53:31 +0100, Krzysztof Kozlowski wrote:
> Convert the Exynos5433 LPASS bindings to DT schema format.
> 
> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
> ---
>  .../bindings/mfd/samsung,exynos5433-lpass.txt |  72 -----------
>  .../mfd/samsung,exynos5433-lpass.yaml         | 119 ++++++++++++++++++
>  2 files changed, 119 insertions(+), 72 deletions(-)
>  delete mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
>  create mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.example.dt.yaml: audio-subsystem at 11400000: serial at 11460000:compatible:0: 'samsung,exynos5433-uart' is not one of ['apple,s5l-uart', 'samsung,s3c2410-uart', 'samsung,s3c2412-uart', 'samsung,s3c2440-uart', 'samsung,s3c6400-uart', 'samsung,s5pv210-uart', 'samsung,exynos4210-uart', 'samsung,exynos850-uart']
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.example.dt.yaml:0:0: /example-0/audio-subsystem at 11400000/serial at 11460000: failed to match any schema with compatible: ['samsung,exynos5433-uart']

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/patch/1586234

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.



From linus.walleij at linaro.org  Sat Jan 29 16:30:57 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 01:30:57 +0100
Subject: [RFC v6 net-next 1/9] pinctrl: ocelot: allow pinctrl-ocelot to be
 loaded as a module
In-Reply-To: <20220129220221.2823127-2-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
 <20220129220221.2823127-2-colin.foster@in-advantage.com>
Message-ID: <CACRpkdbFOB-uoVKiG0qTcHDa45bNjwdkP=AzAB7kU2Car37QYg@mail.gmail.com>

On Sat, Jan 29, 2022 at 11:02 PM Colin Foster
<colin.foster at in-advantage.com> wrote:

> Work is being done to allow external control of Ocelot chips. When pinctrl
> drivers are used internally, it wouldn't make much sense to allow them to
> be loaded as modules. In the case where the Ocelot chip is controlled
> externally, this scenario becomes practical.
>
> Signed-off-by: Colin Foster <colin.foster at in-advantage.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

This is fine to merge through the netdev tree, if you prefer I merge patches
1 & 2 to the pinctrl tree just tell me.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 29 16:31:29 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 01:31:29 +0100
Subject: [RFC v6 net-next 2/9] pinctrl: microchip-sgpio: allow sgpio
 driver to be used as a module
In-Reply-To: <20220129220221.2823127-3-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
 <20220129220221.2823127-3-colin.foster@in-advantage.com>
Message-ID: <CACRpkdbXD0cA07zPQtVH1_hdc-aLq5ktm1DpUW=dB-i+B5dacw@mail.gmail.com>

On Sat, Jan 29, 2022 at 11:02 PM Colin Foster
<colin.foster at in-advantage.com> wrote:

> As the commit message suggests, this simply adds the ability to select
> SGPIO pinctrl as a module. This becomes more practical when the SGPIO
> hardware exists on an external chip, controlled indirectly by I2C or SPI.
> This commit enables that level of control.
>
> Signed-off-by: Colin Foster <colin.foster at in-advantage.com>

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 29 16:38:10 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 01:38:10 +0100
Subject: [PATCH v9 2/3] dt-bindings: pinctrl: mt8195: Add
 mediatek,drive-strength-adv property
In-Reply-To: <102ea6303dd16fdf9ec931d0a1845a93afe92545.camel@mediatek.com>
References: <20220112114724.1953-1-tinghan.shen@mediatek.com>
 <20220112114724.1953-3-tinghan.shen@mediatek.com>
 <18f7a647-6153-6d38-dff1-727b9592b01e@gmail.com>
 <102ea6303dd16fdf9ec931d0a1845a93afe92545.camel@mediatek.com>
Message-ID: <CACRpkdZ194_7+mHauDPwMHG3TeGnp2ENdcSDjZnWny1X4YTT7w@mail.gmail.com>

On Tue, Jan 25, 2022 at 7:21 AM Tinghan Shen <tinghan.shen at mediatek.com> wrote:

> I want to send next version to update the CC list of this series, but I'm not sure
> whether this will break the conversation between you and Linus.
>
> Is it ok to send next version? or waiting the response?

Send a new version, I'll apply the v10 version!

Yours,
Linus Walleij


From chun-jie.chen at mediatek.com  Sat Jan 29 17:20:59 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:20:59 +0800
Subject: [v7 0/5] Mediatek MT8195 power domain support
Message-ID: <20220130012104.5292-1-chun-jie.chen@mediatek.com>

This patch series adds power domain support for MT8195
and is based on 5.17-rc1.

change since v6:
- rebase to 5.17-rc1

change since v5:
- rebase to 5.16-rc1
- add domain capacity in mfg power domain

change since v4:
- rebase to 5.15-rc1 (fix conflict at patch 4 in this series)
- change license

change since v3:
- remove redundant bus protection steps
- remove unused power domain

change since v2:
- move modification of wakeup capacity to single patch

reason for resend v2:
- miss patch version in series

changes since v1:
- fix signed-off name
- describe more detail in patch 3
- move modification of removing redundant macro to single patch

Chun-Jie Chen (5):
  dt-bindings: power: Add MT8195 power domains
  soc: mediatek: pm-domains: Add wakeup capacity support in power domain
  soc: mediatek: pm-domains: Remove unused macro
  soc: mediatek: pm-domains: Move power status offset to power domain
    data
  soc: mediatek: pm-domains: Add support for mt8195

 .../power/mediatek,power-controller.yaml      |   2 +
 drivers/soc/mediatek/mt8167-pm-domains.h      |  16 +-
 drivers/soc/mediatek/mt8173-pm-domains.h      |  22 +-
 drivers/soc/mediatek/mt8183-pm-domains.h      |  32 +-
 drivers/soc/mediatek/mt8192-pm-domains.h      |  44 +-
 drivers/soc/mediatek/mt8195-pm-domains.h      | 613 ++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c         |  12 +-
 drivers/soc/mediatek/mtk-pm-domains.h         |   8 +-
 include/dt-bindings/power/mt8195-power.h      |  46 ++
 include/linux/soc/mediatek/infracfg.h         |  82 +++
 10 files changed, 862 insertions(+), 15 deletions(-)
 create mode 100644 drivers/soc/mediatek/mt8195-pm-domains.h
 create mode 100644 include/dt-bindings/power/mt8195-power.h

-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan 29 17:21:00 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:21:00 +0800
Subject: [v7 1/5] dt-bindings: power: Add MT8195 power domains
In-Reply-To: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
References: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
Message-ID: <20220130012104.5292-2-chun-jie.chen@mediatek.com>

Add power domains dt-bindings for MT8195.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../power/mediatek,power-controller.yaml      |  2 +
 include/dt-bindings/power/mt8195-power.h      | 46 +++++++++++++++++++
 2 files changed, 48 insertions(+)
 create mode 100644 include/dt-bindings/power/mt8195-power.h

diff --git a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
index f234a756c193..d6ebd77d28a7 100644
--- a/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
+++ b/Documentation/devicetree/bindings/power/mediatek,power-controller.yaml
@@ -27,6 +27,7 @@ properties:
       - mediatek,mt8173-power-controller
       - mediatek,mt8183-power-controller
       - mediatek,mt8192-power-controller
+      - mediatek,mt8195-power-controller
 
   '#power-domain-cells':
     const: 1
@@ -64,6 +65,7 @@ patternProperties:
               "include/dt-bindings/power/mt8173-power.h" - for MT8173 type power domain.
               "include/dt-bindings/power/mt8183-power.h" - for MT8183 type power domain.
               "include/dt-bindings/power/mt8192-power.h" - for MT8192 type power domain.
+              "include/dt-bindings/power/mt8195-power.h" - for MT8195 type power domain.
         maxItems: 1
 
       clocks:
diff --git a/include/dt-bindings/power/mt8195-power.h b/include/dt-bindings/power/mt8195-power.h
new file mode 100644
index 000000000000..b20ca4b3e3a8
--- /dev/null
+++ b/include/dt-bindings/power/mt8195-power.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT8195_POWER_H
+#define _DT_BINDINGS_POWER_MT8195_POWER_H
+
+#define MT8195_POWER_DOMAIN_PCIE_MAC_P0		0
+#define MT8195_POWER_DOMAIN_PCIE_MAC_P1		1
+#define MT8195_POWER_DOMAIN_PCIE_PHY		2
+#define MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY	3
+#define MT8195_POWER_DOMAIN_CSI_RX_TOP		4
+#define MT8195_POWER_DOMAIN_ETHER		5
+#define MT8195_POWER_DOMAIN_ADSP		6
+#define MT8195_POWER_DOMAIN_AUDIO		7
+#define MT8195_POWER_DOMAIN_MFG0		8
+#define MT8195_POWER_DOMAIN_MFG1		9
+#define MT8195_POWER_DOMAIN_MFG2		10
+#define MT8195_POWER_DOMAIN_MFG3		11
+#define MT8195_POWER_DOMAIN_MFG4		12
+#define MT8195_POWER_DOMAIN_MFG5		13
+#define MT8195_POWER_DOMAIN_MFG6		14
+#define MT8195_POWER_DOMAIN_VPPSYS0		15
+#define MT8195_POWER_DOMAIN_VDOSYS0		16
+#define MT8195_POWER_DOMAIN_VPPSYS1		17
+#define MT8195_POWER_DOMAIN_VDOSYS1		18
+#define MT8195_POWER_DOMAIN_DP_TX		19
+#define MT8195_POWER_DOMAIN_EPD_TX		20
+#define MT8195_POWER_DOMAIN_HDMI_TX		21
+#define MT8195_POWER_DOMAIN_WPESYS		22
+#define MT8195_POWER_DOMAIN_VDEC0		23
+#define MT8195_POWER_DOMAIN_VDEC1		24
+#define MT8195_POWER_DOMAIN_VDEC2		25
+#define MT8195_POWER_DOMAIN_VENC		26
+#define MT8195_POWER_DOMAIN_VENC_CORE1		27
+#define MT8195_POWER_DOMAIN_IMG			28
+#define MT8195_POWER_DOMAIN_DIP			29
+#define MT8195_POWER_DOMAIN_IPE			30
+#define MT8195_POWER_DOMAIN_CAM			31
+#define MT8195_POWER_DOMAIN_CAM_RAWA		32
+#define MT8195_POWER_DOMAIN_CAM_RAWB		33
+#define MT8195_POWER_DOMAIN_CAM_MRAW		34
+
+#endif /* _DT_BINDINGS_POWER_MT8195_POWER_H */
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan 29 17:21:01 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:21:01 +0800
Subject: [v7 2/5] soc: mediatek: pm-domains: Add wakeup capacity support in
 power domain
In-Reply-To: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
References: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
Message-ID: <20220130012104.5292-3-chun-jie.chen@mediatek.com>

Due to some power domain needs to keep on for wakeup in system suspend,
so add GENPD_FLAG_ACTIVE_WAKEUP support in Mediatek power domain driver.

Fixes: 59b644b01cf4 ("soc: mediatek: Add MediaTek SCPSYS power domains")
Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mtk-pm-domains.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index b762bc40f56b..afd2fd74802d 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -443,6 +443,9 @@ generic_pm_domain *scpsys_add_one_domain(struct scpsys *scpsys, struct device_no
 	pd->genpd.power_off = scpsys_power_off;
 	pd->genpd.power_on = scpsys_power_on;
 
+	if (MTK_SCPD_CAPS(pd, MTK_SCPD_ACTIVE_WAKEUP))
+		pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
 	if (MTK_SCPD_CAPS(pd, MTK_SCPD_KEEP_DEFAULT_OFF))
 		pm_genpd_init(&pd->genpd, NULL, true);
 	else
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan 29 17:21:02 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:21:02 +0800
Subject: [v7 3/5] soc: mediatek: pm-domains: Remove unused macro
In-Reply-To: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
References: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
Message-ID: <20220130012104.5292-4-chun-jie.chen@mediatek.com>

Due to clk resource data will be allocated dynamically by
searching parent count of clk in power domain node, so remove
the unused marco MAX_SUBSYS_CLKS for static allocation.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mtk-pm-domains.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index c5ac649ae51b..089a31679806 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -72,8 +72,6 @@ struct scpsys_bus_prot_data {
 	bool ignore_clr_ack;
 };
 
-#define MAX_SUBSYS_CLKS 10
-
 /**
  * struct scpsys_domain_data - scp domain data for power on/off flow
  * @name: The name of the power domain.
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan 29 17:21:03 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:21:03 +0800
Subject: [v7 4/5] soc: mediatek: pm-domains: Move power status offset to power
 domain data
In-Reply-To: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
References: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
Message-ID: <20220130012104.5292-5-chun-jie.chen@mediatek.com>

MT8195 has more than 32 power domains so it needs
two set of pwr_sta and pwr_sta2nd registers,
so move the register offset from soc data into power domain data.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Enric Balletbo i Serra <enric.balletbo at collabora.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mt8167-pm-domains.h | 16 +++++++--
 drivers/soc/mediatek/mt8173-pm-domains.h | 22 ++++++++++--
 drivers/soc/mediatek/mt8183-pm-domains.h | 32 +++++++++++++++--
 drivers/soc/mediatek/mt8192-pm-domains.h | 44 ++++++++++++++++++++++--
 drivers/soc/mediatek/mtk-pm-domains.c    |  4 +--
 drivers/soc/mediatek/mtk-pm-domains.h    |  4 +--
 6 files changed, 110 insertions(+), 12 deletions(-)

diff --git a/drivers/soc/mediatek/mt8167-pm-domains.h b/drivers/soc/mediatek/mt8167-pm-domains.h
index 15559ddf26e4..4d6c32759606 100644
--- a/drivers/soc/mediatek/mt8167-pm-domains.h
+++ b/drivers/soc/mediatek/mt8167-pm-domains.h
@@ -18,6 +18,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mm",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = SPM_DIS_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -30,6 +32,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "vdec",
 		.sta_mask = PWR_STATUS_VDEC,
 		.ctl_offs = SPM_VDE_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -38,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = SPM_ISP_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -46,6 +52,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg_async",
 		.sta_mask = MT8167_PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -57,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg_2d",
 		.sta_mask = MT8167_PWR_STATUS_MFG_2D,
 		.ctl_offs = SPM_MFG_2D_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -64,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = SPM_MFG_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -71,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = SPM_CONN_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = 0,
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -85,8 +99,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8167[] = {
 static const struct scpsys_soc_data mt8167_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8167,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8167),
-	.pwr_sta_offs = SPM_PWR_STATUS,
-	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 };
 
 #endif /* __SOC_MEDIATEK_MT8167_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8173-pm-domains.h b/drivers/soc/mediatek/mt8173-pm-domains.h
index 714fa92575df..1a5dc63b7357 100644
--- a/drivers/soc/mediatek/mt8173-pm-domains.h
+++ b/drivers/soc/mediatek/mt8173-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "vdec",
 		.sta_mask = PWR_STATUS_VDEC,
 		.ctl_offs = SPM_VDE_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "venc",
 		.sta_mask = PWR_STATUS_VENC,
 		.ctl_offs = SPM_VEN_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -29,6 +33,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = SPM_ISP_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 	},
@@ -36,6 +42,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mm",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = SPM_DIS_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -47,6 +55,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "venc_lt",
 		.sta_mask = PWR_STATUS_VENC_LT,
 		.ctl_offs = SPM_VEN2_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -54,6 +64,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "audio",
 		.sta_mask = PWR_STATUS_AUDIO,
 		.ctl_offs = SPM_AUDIO_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -61,6 +73,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "usb",
 		.sta_mask = PWR_STATUS_USB,
 		.ctl_offs = SPM_USB_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.caps = MTK_SCPD_ACTIVE_WAKEUP,
@@ -69,6 +83,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg_async",
 		.sta_mask = PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = SPM_MFG_ASYNC_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = 0,
 		.caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -77,6 +93,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg_2d",
 		.sta_mask = PWR_STATUS_MFG_2D,
 		.ctl_offs = SPM_MFG_2D_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 	},
@@ -84,6 +102,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = SPM_MFG_PWR_CON,
+		.pwr_sta_offs = SPM_PWR_STATUS,
+		.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 		.sram_pdn_bits = GENMASK(13, 8),
 		.sram_pdn_ack_bits = GENMASK(21, 16),
 		.bp_infracfg = {
@@ -98,8 +118,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8173[] = {
 static const struct scpsys_soc_data mt8173_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8173,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8173),
-	.pwr_sta_offs = SPM_PWR_STATUS,
-	.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND,
 };
 
 #endif /* __SOC_MEDIATEK_MT8173_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8183-pm-domains.h b/drivers/soc/mediatek/mt8183-pm-domains.h
index 98a9940d05fb..71b8757e552d 100644
--- a/drivers/soc/mediatek/mt8183-pm-domains.h
+++ b/drivers/soc/mediatek/mt8183-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "audio",
 		.sta_mask = PWR_STATUS_AUDIO,
 		.ctl_offs = 0x0314,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 	},
@@ -22,6 +24,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = 0x032c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -33,6 +37,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_async",
 		.sta_mask = PWR_STATUS_MFG_ASYNC,
 		.ctl_offs = 0x0334,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 	},
@@ -40,6 +46,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg",
 		.sta_mask = PWR_STATUS_MFG,
 		.ctl_offs = 0x0338,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.caps = MTK_SCPD_DOMAIN_SUPPLY,
@@ -48,6 +56,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_core0",
 		.sta_mask = BIT(7),
 		.ctl_offs = 0x034c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -55,6 +65,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_core1",
 		.sta_mask = BIT(20),
 		.ctl_offs = 0x0310,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -62,6 +74,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "mfg_2d",
 		.sta_mask = PWR_STATUS_MFG_2D,
 		.ctl_offs = 0x0348,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -75,6 +89,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "disp",
 		.sta_mask = PWR_STATUS_DISP,
 		.ctl_offs = 0x030c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -94,6 +110,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "cam",
 		.sta_mask = BIT(25),
 		.ctl_offs = 0x0344,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(9, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "isp",
 		.sta_mask = PWR_STATUS_ISP,
 		.ctl_offs = 0x0308,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(9, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -140,6 +160,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vdec",
 		.sta_mask = BIT(31),
 		.ctl_offs = 0x0300,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_smi = {
@@ -153,6 +175,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "venc",
 		.sta_mask = PWR_STATUS_VENC,
 		.ctl_offs = 0x0304,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(15, 12),
 		.bp_smi = {
@@ -166,6 +190,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_top",
 		.sta_mask = BIT(26),
 		.ctl_offs = 0x0324,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -193,6 +219,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_core0",
 		.sta_mask = BIT(27),
 		.ctl_offs = 0x33c,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -211,6 +239,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 		.name = "vpu_core1",
 		.sta_mask = BIT(28),
 		.ctl_offs = 0x0340,
+		.pwr_sta_offs = 0x0180,
+		.pwr_sta2nd_offs = 0x0184,
 		.sram_pdn_bits = GENMASK(11, 8),
 		.sram_pdn_ack_bits = GENMASK(13, 12),
 		.bp_infracfg = {
@@ -230,8 +260,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8183[] = {
 static const struct scpsys_soc_data mt8183_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8183,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8183),
-	.pwr_sta_offs = 0x0180,
-	.pwr_sta2nd_offs = 0x0184
 };
 
 #endif /* __SOC_MEDIATEK_MT8183_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mt8192-pm-domains.h b/drivers/soc/mediatek/mt8192-pm-domains.h
index 543dda70de01..558c4ee4784a 100644
--- a/drivers/soc/mediatek/mt8192-pm-domains.h
+++ b/drivers/soc/mediatek/mt8192-pm-domains.h
@@ -15,6 +15,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "audio",
 		.sta_mask = BIT(21),
 		.ctl_offs = 0x0354,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -28,6 +30,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "conn",
 		.sta_mask = PWR_STATUS_CONN,
 		.ctl_offs = 0x0304,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = 0,
 		.sram_pdn_ack_bits = 0,
 		.bp_infracfg = {
@@ -50,6 +54,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg0",
 		.sta_mask = BIT(2),
 		.ctl_offs = 0x0308,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -57,6 +63,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg1",
 		.sta_mask = BIT(3),
 		.ctl_offs = 0x030c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -82,6 +90,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg2",
 		.sta_mask = BIT(4),
 		.ctl_offs = 0x0310,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -89,6 +99,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg3",
 		.sta_mask = BIT(5),
 		.ctl_offs = 0x0314,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -96,6 +108,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg4",
 		.sta_mask = BIT(6),
 		.ctl_offs = 0x0318,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -103,6 +117,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg5",
 		.sta_mask = BIT(7),
 		.ctl_offs = 0x031c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -110,6 +126,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mfg6",
 		.sta_mask = BIT(8),
 		.ctl_offs = 0x0320,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -117,6 +135,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "disp",
 		.sta_mask = BIT(20),
 		.ctl_offs = 0x0350,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -146,6 +166,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "ipe",
 		.sta_mask = BIT(14),
 		.ctl_offs = 0x0338,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -163,6 +185,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "isp",
 		.sta_mask = BIT(12),
 		.ctl_offs = 0x0330,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -180,6 +204,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "isp2",
 		.sta_mask = BIT(13),
 		.ctl_offs = 0x0334,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -197,6 +223,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "mdp",
 		.sta_mask = BIT(19),
 		.ctl_offs = 0x034c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -214,6 +242,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "venc",
 		.sta_mask = BIT(17),
 		.ctl_offs = 0x0344,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -231,6 +261,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "vdec",
 		.sta_mask = BIT(15),
 		.ctl_offs = 0x033c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -248,6 +280,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "vdec2",
 		.sta_mask = BIT(16),
 		.ctl_offs = 0x0340,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -255,6 +289,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam",
 		.sta_mask = BIT(23),
 		.ctl_offs = 0x035c,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 		.bp_infracfg = {
@@ -284,6 +320,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawa",
 		.sta_mask = BIT(24),
 		.ctl_offs = 0x0360,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -291,6 +329,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawb",
 		.sta_mask = BIT(25),
 		.ctl_offs = 0x0364,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -298,6 +338,8 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 		.name = "cam_rawc",
 		.sta_mask = BIT(26),
 		.ctl_offs = 0x0368,
+		.pwr_sta_offs = 0x016c,
+		.pwr_sta2nd_offs = 0x0170,
 		.sram_pdn_bits = GENMASK(8, 8),
 		.sram_pdn_ack_bits = GENMASK(12, 12),
 	},
@@ -306,8 +348,6 @@ static const struct scpsys_domain_data scpsys_domain_data_mt8192[] = {
 static const struct scpsys_soc_data mt8192_scpsys_data = {
 	.domains_data = scpsys_domain_data_mt8192,
 	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8192),
-	.pwr_sta_offs = 0x016c,
-	.pwr_sta2nd_offs = 0x0170,
 };
 
 #endif /* __SOC_MEDIATEK_MT8192_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index afd2fd74802d..ad06b6f90435 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -60,10 +60,10 @@ static bool scpsys_domain_is_on(struct scpsys_domain *pd)
 	struct scpsys *scpsys = pd->scpsys;
 	u32 status, status2;
 
-	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta_offs, &status);
+	regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status);
 	status &= pd->data->sta_mask;
 
-	regmap_read(scpsys->base, scpsys->soc_data->pwr_sta2nd_offs, &status2);
+	regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2);
 	status2 &= pd->data->sta_mask;
 
 	/* A domain is on when both status bits are set. */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index 089a31679806..c233ed828f86 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -92,13 +92,13 @@ struct scpsys_domain_data {
 	u8 caps;
 	const struct scpsys_bus_prot_data bp_infracfg[SPM_MAX_BUS_PROT_DATA];
 	const struct scpsys_bus_prot_data bp_smi[SPM_MAX_BUS_PROT_DATA];
+	int pwr_sta_offs;
+	int pwr_sta2nd_offs;
 };
 
 struct scpsys_soc_data {
 	const struct scpsys_domain_data *domains_data;
 	int num_domains;
-	int pwr_sta_offs;
-	int pwr_sta2nd_offs;
 };
 
 #endif /* __SOC_MEDIATEK_MTK_PM_DOMAINS_H */
-- 
2.18.0



From chun-jie.chen at mediatek.com  Sat Jan 29 17:21:04 2022
From: chun-jie.chen at mediatek.com (Chun-Jie Chen)
Date: Sun, 30 Jan 2022 09:21:04 +0800
Subject: [v7 5/5] soc: mediatek: pm-domains: Add support for mt8195
In-Reply-To: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
References: <20220130012104.5292-1-chun-jie.chen@mediatek.com>
Message-ID: <20220130012104.5292-6-chun-jie.chen@mediatek.com>

Add domain control data including bus protection data size
change due to more protection steps in mt8195.

Signed-off-by: Chun-Jie Chen <chun-jie.chen at mediatek.com>
Reviewed-by: Chen-Yu Tsai <wenst at chromium.org>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 drivers/soc/mediatek/mt8195-pm-domains.h | 613 +++++++++++++++++++++++
 drivers/soc/mediatek/mtk-pm-domains.c    |   5 +
 drivers/soc/mediatek/mtk-pm-domains.h    |   2 +-
 include/linux/soc/mediatek/infracfg.h    |  82 +++
 4 files changed, 701 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/mediatek/mt8195-pm-domains.h

diff --git a/drivers/soc/mediatek/mt8195-pm-domains.h b/drivers/soc/mediatek/mt8195-pm-domains.h
new file mode 100644
index 000000000000..938f4d51f5ae
--- /dev/null
+++ b/drivers/soc/mediatek/mt8195-pm-domains.h
@@ -0,0 +1,613 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Chun-Jie Chen <chun-jie.chen at mediatek.com>
+ */
+
+#ifndef __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
+#define __SOC_MEDIATEK_MT8195_PM_DOMAINS_H
+
+#include "mtk-pm-domains.h"
+#include <dt-bindings/power/mt8195-power.h>
+
+/*
+ * MT8195 power domain support
+ */
+
+static const struct scpsys_domain_data scpsys_domain_data_mt8195[] = {
+	[MT8195_POWER_DOMAIN_PCIE_MAC_P0] = {
+		.name = "pcie_mac_p0",
+		.sta_mask = BIT(11),
+		.ctl_offs = 0x328,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_PCIE_MAC_P1] = {
+		.name = "pcie_mac_p1",
+		.sta_mask = BIT(12),
+		.ctl_offs = 0x32C,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_PCIE_PHY] = {
+		.name = "pcie_phy",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x330,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_SSUSB_PCIE_PHY] = {
+		.name = "ssusb_pcie_phy",
+		.sta_mask = BIT(14),
+		.ctl_offs = 0x334,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_CSI_RX_TOP] = {
+		.name = "csi_rx_top",
+		.sta_mask = BIT(18),
+		.ctl_offs = 0x3C4,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_ETHER] = {
+		.name = "ether",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x344,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_ADSP] = {
+		.name = "adsp",
+		.sta_mask = BIT(10),
+		.ctl_offs = 0x360,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_ADSP,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+		},
+		.caps = MTK_SCPD_SRAM_ISO | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_AUDIO] = {
+		.name = "audio",
+		.sta_mask = BIT(8),
+		.ctl_offs = 0x358,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_AUDIO,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_MFG0] = {
+		.name = "mfg0",
+		.sta_mask = BIT(1),
+		.ctl_offs = 0x300,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_DOMAIN_SUPPLY,
+	},
+	[MT8195_POWER_DOMAIN_MFG1] = {
+		.name = "mfg1",
+		.sta_mask = BIT(2),
+		.ctl_offs = 0x304,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_1_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MFG1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG2] = {
+		.name = "mfg2",
+		.sta_mask = BIT(3),
+		.ctl_offs = 0x308,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG3] = {
+		.name = "mfg3",
+		.sta_mask = BIT(4),
+		.ctl_offs = 0x30C,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG4] = {
+		.name = "mfg4",
+		.sta_mask = BIT(5),
+		.ctl_offs = 0x310,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG5] = {
+		.name = "mfg5",
+		.sta_mask = BIT(6),
+		.ctl_offs = 0x314,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_MFG6] = {
+		.name = "mfg6",
+		.sta_mask = BIT(7),
+		.ctl_offs = 0x318,
+		.pwr_sta_offs = 0x174,
+		.pwr_sta2nd_offs = 0x178,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VPPSYS0] = {
+		.name = "vppsys0",
+		.sta_mask = BIT(11),
+		.ctl_offs = 0x364,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDOSYS0] = {
+		.name = "vdosys0",
+		.sta_mask = BIT(13),
+		.ctl_offs = 0x36C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SET,
+				    MT8195_TOP_AXI_PROT_EN_CLR,
+				    MT8195_TOP_AXI_PROT_EN_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR,
+				    MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VPPSYS1] = {
+		.name = "vppsys1",
+		.sta_mask = BIT(12),
+		.ctl_offs = 0x368,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDOSYS1] = {
+		.name = "vdosys1",
+		.sta_mask = BIT(14),
+		.ctl_offs = 0x370,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_DP_TX] = {
+		.name = "dp_tx",
+		.sta_mask = BIT(16),
+		.ctl_offs = 0x378,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_EPD_TX] = {
+		.name = "epd_tx",
+		.sta_mask = BIT(17),
+		.ctl_offs = 0x37C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_HDMI_TX] = {
+		.name = "hdmi_tx",
+		.sta_mask = BIT(18),
+		.ctl_offs = 0x380,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF | MTK_SCPD_ACTIVE_WAKEUP,
+	},
+	[MT8195_POWER_DOMAIN_WPESYS] = {
+		.name = "wpesys",
+		.sta_mask = BIT(15),
+		.ctl_offs = 0x374,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_WPESYS,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+	},
+	[MT8195_POWER_DOMAIN_VDEC0] = {
+		.name = "vdec0",
+		.sta_mask = BIT(20),
+		.ctl_offs = 0x388,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VDEC1] = {
+		.name = "vdec1",
+		.sta_mask = BIT(21),
+		.ctl_offs = 0x38C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VDEC2] = {
+		.name = "vdec2",
+		.sta_mask = BIT(22),
+		.ctl_offs = 0x390,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VENC] = {
+		.name = "venc",
+		.sta_mask = BIT(23),
+		.ctl_offs = 0x394,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_VENC_CORE1] = {
+		.name = "venc_core1",
+		.sta_mask = BIT(24),
+		.ctl_offs = 0x398,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_IMG] = {
+		.name = "img",
+		.sta_mask = BIT(29),
+		.ctl_offs = 0x3AC,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_DIP] = {
+		.name = "dip",
+		.sta_mask = BIT(30),
+		.ctl_offs = 0x3B0,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_IPE] = {
+		.name = "ipe",
+		.sta_mask = BIT(31),
+		.ctl_offs = 0x3B4,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_IPE,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_IPE,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM] = {
+		.name = "cam",
+		.sta_mask = BIT(25),
+		.ctl_offs = 0x39C,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.bp_infracfg = {
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_2_CAM,
+				    MT8195_TOP_AXI_PROT_EN_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_2_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_1_CAM,
+				    MT8195_TOP_AXI_PROT_EN_1_SET,
+				    MT8195_TOP_AXI_PROT_EN_1_CLR,
+				    MT8195_TOP_AXI_PROT_EN_1_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND,
+				    MT8195_TOP_AXI_PROT_EN_MM_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_STA1),
+			BUS_PROT_WR(MT8195_TOP_AXI_PROT_EN_MM_2_CAM,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_SET,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_CLR,
+				    MT8195_TOP_AXI_PROT_EN_MM_2_STA1),
+		},
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_RAWA] = {
+		.name = "cam_rawa",
+		.sta_mask = BIT(26),
+		.ctl_offs = 0x3A0,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_RAWB] = {
+		.name = "cam_rawb",
+		.sta_mask = BIT(27),
+		.ctl_offs = 0x3A4,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+	[MT8195_POWER_DOMAIN_CAM_MRAW] = {
+		.name = "cam_mraw",
+		.sta_mask = BIT(28),
+		.ctl_offs = 0x3A8,
+		.pwr_sta_offs = 0x16c,
+		.pwr_sta2nd_offs = 0x170,
+		.sram_pdn_bits = GENMASK(8, 8),
+		.sram_pdn_ack_bits = GENMASK(12, 12),
+		.caps = MTK_SCPD_KEEP_DEFAULT_OFF,
+	},
+};
+
+static const struct scpsys_soc_data mt8195_scpsys_data = {
+	.domains_data = scpsys_domain_data_mt8195,
+	.num_domains = ARRAY_SIZE(scpsys_domain_data_mt8195),
+};
+
+#endif /* __SOC_MEDIATEK_MT8195_PM_DOMAINS_H */
diff --git a/drivers/soc/mediatek/mtk-pm-domains.c b/drivers/soc/mediatek/mtk-pm-domains.c
index ad06b6f90435..61973a306e97 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.c
+++ b/drivers/soc/mediatek/mtk-pm-domains.c
@@ -20,6 +20,7 @@
 #include "mt8173-pm-domains.h"
 #include "mt8183-pm-domains.h"
 #include "mt8192-pm-domains.h"
+#include "mt8195-pm-domains.h"
 
 #define MTK_POLL_DELAY_US		10
 #define MTK_POLL_TIMEOUT		USEC_PER_SEC
@@ -569,6 +570,10 @@ static const struct of_device_id scpsys_of_match[] = {
 		.compatible = "mediatek,mt8192-power-controller",
 		.data = &mt8192_scpsys_data,
 	},
+	{
+		.compatible = "mediatek,mt8195-power-controller",
+		.data = &mt8195_scpsys_data,
+	},
 	{ }
 };
 
diff --git a/drivers/soc/mediatek/mtk-pm-domains.h b/drivers/soc/mediatek/mtk-pm-domains.h
index c233ed828f86..daa24e890dd4 100644
--- a/drivers/soc/mediatek/mtk-pm-domains.h
+++ b/drivers/soc/mediatek/mtk-pm-domains.h
@@ -37,7 +37,7 @@
 #define PWR_STATUS_AUDIO		BIT(24)
 #define PWR_STATUS_USB			BIT(25)
 
-#define SPM_MAX_BUS_PROT_DATA		5
+#define SPM_MAX_BUS_PROT_DATA		6
 
 #define _BUS_PROT(_mask, _set, _clr, _sta, _update, _ignore) {	\
 		.bus_prot_mask = (_mask),			\
diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h
index 4615a228da51..d858e0bab7a2 100644
--- a/include/linux/soc/mediatek/infracfg.h
+++ b/include/linux/soc/mediatek/infracfg.h
@@ -2,6 +2,88 @@
 #ifndef __SOC_MEDIATEK_INFRACFG_H
 #define __SOC_MEDIATEK_INFRACFG_H
 
+#define MT8195_TOP_AXI_PROT_EN_STA1                     0x228
+#define MT8195_TOP_AXI_PROT_EN_1_STA1                   0x258
+#define MT8195_TOP_AXI_PROT_EN_SET			0x2a0
+#define MT8195_TOP_AXI_PROT_EN_CLR                      0x2a4
+#define MT8195_TOP_AXI_PROT_EN_1_SET                    0x2a8
+#define MT8195_TOP_AXI_PROT_EN_1_CLR                    0x2ac
+#define MT8195_TOP_AXI_PROT_EN_MM_SET                   0x2d4
+#define MT8195_TOP_AXI_PROT_EN_MM_CLR                   0x2d8
+#define MT8195_TOP_AXI_PROT_EN_MM_STA1                  0x2ec
+#define MT8195_TOP_AXI_PROT_EN_2_SET                    0x714
+#define MT8195_TOP_AXI_PROT_EN_2_CLR                    0x718
+#define MT8195_TOP_AXI_PROT_EN_2_STA1                   0x724
+#define MT8195_TOP_AXI_PROT_EN_VDNR_SET                 0xb84
+#define MT8195_TOP_AXI_PROT_EN_VDNR_CLR                 0xb88
+#define MT8195_TOP_AXI_PROT_EN_VDNR_STA1                0xb90
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_SET               0xba4
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_CLR               0xba8
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_STA1              0xbb0
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_SET               0xbb8
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_CLR               0xbbc
+#define MT8195_TOP_AXI_PROT_EN_VDNR_2_STA1              0xbc4
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_SET       0xbcc
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_CLR       0xbd0
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_STA1      0xbd8
+#define MT8195_TOP_AXI_PROT_EN_MM_2_SET                 0xdcc
+#define MT8195_TOP_AXI_PROT_EN_MM_2_CLR                 0xdd0
+#define MT8195_TOP_AXI_PROT_EN_MM_2_STA1                0xdd8
+
+#define MT8195_TOP_AXI_PROT_EN_VDOSYS0			BIT(6)
+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0			BIT(10)
+#define MT8195_TOP_AXI_PROT_EN_MFG1			BIT(11)
+#define MT8195_TOP_AXI_PROT_EN_MFG1_2ND			GENMASK(22, 21)
+#define MT8195_TOP_AXI_PROT_EN_VPPSYS0_2ND		BIT(23)
+#define MT8195_TOP_AXI_PROT_EN_1_MFG1			GENMASK(20, 19)
+#define MT8195_TOP_AXI_PROT_EN_1_CAM			BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_2_CAM			BIT(0)
+#define MT8195_TOP_AXI_PROT_EN_2_MFG1_2ND		GENMASK(6, 5)
+#define MT8195_TOP_AXI_PROT_EN_2_MFG1			BIT(7)
+#define MT8195_TOP_AXI_PROT_EN_2_AUDIO			(BIT(9) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_2_ADSP			(BIT(12) | GENMASK(16, 14))
+#define MT8195_TOP_AXI_PROT_EN_MM_CAM			(BIT(0) | BIT(2) | BIT(4))
+#define MT8195_TOP_AXI_PROT_EN_MM_IPE			BIT(1)
+#define MT8195_TOP_AXI_PROT_EN_MM_IMG			BIT(3)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS0		GENMASK(21, 17)
+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1		GENMASK(8, 5)
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC			(BIT(9) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_CORE1		(BIT(10) | BIT(12))
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0			BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1			BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1_2ND		BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_MM_VPPSYS1_2ND		BIT(23)
+#define MT8195_TOP_AXI_PROT_EN_MM_CAM_2ND		BIT(24)
+#define MT8195_TOP_AXI_PROT_EN_MM_IMG_2ND		BIT(25)
+#define MT8195_TOP_AXI_PROT_EN_MM_VENC_2ND		BIT(26)
+#define MT8195_TOP_AXI_PROT_EN_MM_WPESYS		BIT(27)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC0_2ND		BIT(28)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDEC1_2ND		BIT(29)
+#define MT8195_TOP_AXI_PROT_EN_MM_VDOSYS1		GENMASK(31, 30)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0_2ND		(GENMASK(1, 0) | BIT(4) | BIT(11))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC		BIT(2)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VENC_CORE1		(BIT(3) | BIT(15))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_CAM			(BIT(5) | BIT(17))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS1		(GENMASK(7, 6) | BIT(18))
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VPPSYS0		GENMASK(9, 8)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDOSYS1		BIT(10)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2_2ND		BIT(12)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0_2ND		BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS_2ND		BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_IPE			BIT(16)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC2		BIT(21)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_VDEC0		BIT(22)
+#define MT8195_TOP_AXI_PROT_EN_MM_2_WPESYS		GENMASK(24, 23)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_EPD_TX		BIT(1)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_DP_TX		BIT(2)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P0		(BIT(11) | BIT(28))
+#define MT8195_TOP_AXI_PROT_EN_VDNR_PCIE_MAC_P1		(BIT(12) | BIT(29))
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P0	BIT(13)
+#define MT8195_TOP_AXI_PROT_EN_VDNR_1_PCIE_MAC_P1	BIT(14)
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_MFG1	(BIT(17) | BIT(19))
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VPPSYS0	BIT(20)
+#define MT8195_TOP_AXI_PROT_EN_SUB_INFRA_VDNR_VDOSYS0	BIT(21)
+
 #define MT8192_TOP_AXI_PROT_EN_STA1			0x228
 #define MT8192_TOP_AXI_PROT_EN_1_STA1			0x258
 #define MT8192_TOP_AXI_PROT_EN_SET			0x2a0
-- 
2.18.0



From linus.walleij at linaro.org  Sat Jan 29 17:34:16 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:34:16 +0100
Subject: [PATCH] pinctrl: bcm2835: Fix a few error paths
In-Reply-To: <20220127215033.267227-1-f.fainelli@gmail.com>
References: <20220127215033.267227-1-f.fainelli@gmail.com>
Message-ID: <CACRpkdaEnXTDpAVPGkVVNHtYoQtG6fNNZ8xnSJdCzyDHVO4SkQ@mail.gmail.com>

On Thu, Jan 27, 2022 at 10:50 PM Florian Fainelli <f.fainelli at gmail.com> wrote:

> After commit 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio
> hogs") a few error paths would not unwind properly the registration of
> gpio ranges. Correct that by assigning a single error label and goto it
> whenever we encounter a fatal error.
>
> Fixes: 266423e60ea1 ("pinctrl: bcm2835: Change init order for gpio hogs")
> Signed-off-by: Florian Fainelli <f.fainelli at gmail.com>

Patch applied.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 29 17:36:10 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:36:10 +0100
Subject: [GIT PULL] ARM: dts/drivers: samsung pinctrl for v5.18
In-Reply-To: <20220129115352.13274-1-krzysztof.kozlowski@canonical.com>
References: <20220129115352.13274-1-krzysztof.kozlowski@canonical.com>
Message-ID: <CACRpkdYt1qM2gBefaWbWyh-a09c++wgR+12QrHZMneRK1mA9Xg@mail.gmail.com>

On Sat, Jan 29, 2022 at 12:54 PM Krzysztof Kozlowski
<krzysztof.kozlowski at canonical.com> wrote:

> Linus,
> I will send the pinctrl driver bits in separate pull to you.

OK I'll wait for it.

Yours,
Linus Walleij


From linux at roeck-us.net  Sat Jan 29 17:42:26 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Sat, 29 Jan 2022 17:42:26 -0800
Subject: [PATCH v3] watchdog: imx2_wdg: Alow ping on suspend
In-Reply-To: <20220127104739.312592-1-alistair@alistair23.me>
References: <20220127104739.312592-1-alistair@alistair23.me>
Message-ID: <20220130014226.GA1805103@roeck-us.net>

On Thu, Jan 27, 2022 at 08:47:39PM +1000, Alistair Francis wrote:
> The i.MX watchdog cannot be disabled by software once it has been
> enabled. This means that it can't be stopped before suspend.
> 
> For systems that enter low power mode this is fine, as the watchdog will
> be automatically stopped by hardware in low power mode. Not all i.MX
> platforms support low power mode in the mainline kernel. For example the
> i.MX7D does not enter low power mode and so will be rebooted 2 minutes
> after entering sleep states.
> 
> This patch introduces a device tree property "fsl,ping-during-suspend"
> that can be used to enable ping on suspend support for these systems.
> 
> Signed-off-by: Alistair Francis <alistair at alistair23.me>

Reviewed-by: Guenter Roeck <linux at roeck-us.net>

> ---
> v3:
>  - Fixup typos in commit message
> v2:
>  - Remove custom property
> 
>  drivers/watchdog/imx2_wdt.c | 27 ++++++++++++++++++++-------
>  1 file changed, 20 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
> index 51bfb796898b..d0c5d47ddede 100644
> --- a/drivers/watchdog/imx2_wdt.c
> +++ b/drivers/watchdog/imx2_wdt.c
> @@ -66,6 +66,7 @@ struct imx2_wdt_device {
>  	struct watchdog_device wdog;
>  	bool ext_reset;
>  	bool clk_is_on;
> +	bool no_ping;
>  };
>  
>  static bool nowayout = WATCHDOG_NOWAYOUT;
> @@ -312,12 +313,18 @@ static int __init imx2_wdt_probe(struct platform_device *pdev)
>  
>  	wdev->ext_reset = of_property_read_bool(dev->of_node,
>  						"fsl,ext-reset-output");
> +	/*
> +	 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
> +	 * during suspend.
> +	 */
> +	wdev->no_ping = !of_device_is_compatible(dev->of_node, "fsl,imx7d-wdt");
>  	platform_set_drvdata(pdev, wdog);
>  	watchdog_set_drvdata(wdog, wdev);
>  	watchdog_set_nowayout(wdog, nowayout);
>  	watchdog_set_restart_priority(wdog, 128);
>  	watchdog_init_timeout(wdog, timeout, dev);
> -	watchdog_stop_ping_on_suspend(wdog);
> +	if (wdev->no_ping)
> +		watchdog_stop_ping_on_suspend(wdog);
>  
>  	if (imx2_wdt_is_running(wdev)) {
>  		imx2_wdt_set_timeout(wdog, wdog->timeout);
> @@ -366,9 +373,11 @@ static int __maybe_unused imx2_wdt_suspend(struct device *dev)
>  		imx2_wdt_ping(wdog);
>  	}
>  
> -	clk_disable_unprepare(wdev->clk);
> +	if (wdev->no_ping) {
> +		clk_disable_unprepare(wdev->clk);
>  
> -	wdev->clk_is_on = false;
> +		wdev->clk_is_on = false;
> +	}
>  
>  	return 0;
>  }
> @@ -380,11 +389,14 @@ static int __maybe_unused imx2_wdt_resume(struct device *dev)
>  	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
>  	int ret;
>  
> -	ret = clk_prepare_enable(wdev->clk);
> -	if (ret)
> -		return ret;
> +	if (wdev->no_ping) {
> +		ret = clk_prepare_enable(wdev->clk);
>  
> -	wdev->clk_is_on = true;
> +		if (ret)
> +			return ret;
> +
> +		wdev->clk_is_on = true;
> +	}
>  
>  	if (watchdog_active(wdog) && !imx2_wdt_is_running(wdev)) {
>  		/*
> @@ -407,6 +419,7 @@ static SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops, imx2_wdt_suspend,
>  
>  static const struct of_device_id imx2_wdt_dt_ids[] = {
>  	{ .compatible = "fsl,imx21-wdt", },
> +	{ .compatible = "fsl,imx7d-wdt", },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, imx2_wdt_dt_ids);


From linus.walleij at linaro.org  Sat Jan 29 17:42:57 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:42:57 +0100
Subject: [PATCH v2 0/2] pinctrl: mediatek: Support pinctrl driver on mt8186
In-Reply-To: <20220121060120.10683-1-guodong.liu@mediatek.com>
References: <20220121060120.10683-1-guodong.liu@mediatek.com>
Message-ID: <CACRpkdaL_cUj2rbQUSzVj+ViEuNWiQbsakChNkaj6FK+fE76FA@mail.gmail.com>

On Fri, Jan 21, 2022 at 7:01 AM Guodong Liu <guodong.liu at mediatek.com> wrote:

> changes since v1:
> - add default pinctrl config to consistent with other MTK pinctrl drivers
>
> Patch 1 add pinctrl file and binding document.
>
> Patch 2 add pinctrl chip driver on mt8186.
>
> Guodong Liu (2):
>   dt-bindings: pinctrl: mt8186: add pinctrl file and binding document
>   pinctrl: add pinctrl driver on mt8186

Looks good to me, just wanna loop this by Chen-Yu Tsai for a check that
it looks good to him too.

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 29 17:53:17 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:53:17 +0100
Subject: [PATCH v4 0/3] pinctrl: meson-s4: add pinctrl driver
In-Reply-To: <20220113031044.2665-1-qianggui.song@amlogic.com>
References: <20220113031044.2665-1-qianggui.song@amlogic.com>
Message-ID: <CACRpkda-jP8m-os6tjXQj3zOykzDq5cfTp9ir+T-H16N4ZAWcg@mail.gmail.com>

On Thu, Jan 13, 2022 at 4:10 AM Qianggui Song <qianggui.song at amlogic.com> wrote:

> This patchset adds Pin controller driver support for Meson-S4 SoC
> which shares the same register layout with previous Meson-A1
>
> Changes since v3 at [2]:
> - collect Martin's Acked-by and Reviewed-by
> - remove useless empty line

Patches applied for v5.18!

Yours,
Linus Walleij


From linus.walleij at linaro.org  Sat Jan 29 17:56:45 2022
From: linus.walleij at linaro.org (Linus Walleij)
Date: Sun, 30 Jan 2022 02:56:45 +0100
Subject: [PATCH v6 0/2] This is a patch series for pinctrl driver of
 Sunplus SP7021 SoC.
In-Reply-To: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
References: <1642344734-27229-1-git-send-email-wellslutw@gmail.com>
Message-ID: <CACRpkdZsrsFK69hUOBtOBz+OSEfTVaukxQ4woXwwjCAB3EgJ+A@mail.gmail.com>

On Sun, Jan 16, 2022 at 3:52 PM Wells Lu <wellslutw at gmail.com> wrote:

> Sunplus SP7021 is an ARM Cortex A7 (4 cores) based SoC. It integrates
> many peripherals (ex: UART, I2C, SPI, SDIO, eMMC, USB, SD card and
> etc.) into a single chip. It is designed for industrial control
> applications.

No further comments for some two weeks so patches applied!
Any remaining issues can be fixed in-tree.

Thanks for you efforts to fix this up!

Yours,
Linus Walleij


From tinghan.shen at mediatek.com  Sat Jan 29 18:32:08 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Sun, 30 Jan 2022 10:32:08 +0800
Subject: [PATCH v10 2/3] dt-bindings: pinctrl: mt8195: Add mediatek,
 drive-strength-adv property
In-Reply-To: <20220130023209.16275-1-tinghan.shen@mediatek.com>
References: <20220130023209.16275-1-tinghan.shen@mediatek.com>
Message-ID: <20220130023209.16275-3-tinghan.shen@mediatek.com>

Extend driving support for I2C pins on SoC mt8195.
This property is already documented in mediatek,mt8183-pinctrl.yaml.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: Rob Herring <robh at kernel.org>
---
 .../bindings/pinctrl/pinctrl-mt8195.yaml      | 35 +++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
index 328ea59c5466..4db4899af6b1 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt8195.yaml
@@ -98,6 +98,32 @@ patternProperties:
           drive-strength:
             enum: [2, 4, 6, 8, 10, 12, 14, 16]
 
+          mediatek,drive-strength-adv:
+            description: |
+              Describe the specific driving setup property.
+              For I2C pins, the existing generic driving setup can only support
+              2/4/6/8/10/12/14/16mA driving. But in specific driving setup, they
+              can support 0.125/0.25/0.5/1mA adjustment. If we enable specific
+              driving setup, the existing generic setup will be disabled.
+              The specific driving setup is controlled by E1E0EN.
+              When E1=0/E0=0, the strength is 0.125mA.
+              When E1=0/E0=1, the strength is 0.25mA.
+              When E1=1/E0=0, the strength is 0.5mA.
+              When E1=1/E0=1, the strength is 1mA.
+              EN is used to enable or disable the specific driving setup.
+              Valid arguments are described as below:
+              0: (E1, E0, EN) = (0, 0, 0)
+              1: (E1, E0, EN) = (0, 0, 1)
+              2: (E1, E0, EN) = (0, 1, 0)
+              3: (E1, E0, EN) = (0, 1, 1)
+              4: (E1, E0, EN) = (1, 0, 0)
+              5: (E1, E0, EN) = (1, 0, 1)
+              6: (E1, E0, EN) = (1, 1, 0)
+              7: (E1, E0, EN) = (1, 1, 1)
+              So the valid arguments are from 0 to 7.
+            $ref: /schemas/types.yaml#/definitions/uint32
+            enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
           bias-pull-down:
             description: |
               For pull down type is normal, it don't need add RSEL & R1R0 define
@@ -268,4 +294,13 @@ examples:
           bias-pull-down;
         };
       };
+
+      i2c0-pins {
+        pins {
+          pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+                   <PINMUX_GPIO9__FUNC_SCL0>;
+          bias-disable;
+          mediatek,drive-strength-adv = <7>;
+        };
+      };
     };
-- 
2.18.0



From tinghan.shen at mediatek.com  Sat Jan 29 18:32:09 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Sun, 30 Jan 2022 10:32:09 +0800
Subject: [PATCH v10 3/3] arm64: dts: Add mediatek SoC mt8195 and evaluation
 board
In-Reply-To: <20220130023209.16275-1-tinghan.shen@mediatek.com>
References: <20220130023209.16275-1-tinghan.shen@mediatek.com>
Message-ID: <20220130023209.16275-4-tinghan.shen@mediatek.com>

Add basic chip support for mediatek mt8195.

Signed-off-by: Seiya Wang <seiya.wang at mediatek.com>
Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 arch/arm64/boot/dts/mediatek/Makefile       |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi    | 1049 +++++++++++++++++++
 3 files changed, 1211 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

diff --git a/arch/arm64/boot/dts/mediatek/Makefile b/arch/arm64/boot/dts/mediatek/Makefile
index 8c1e18032f9f..5da29e7223e4 100644
--- a/arch/arm64/boot/dts/mediatek/Makefile
+++ b/arch/arm64/boot/dts/mediatek/Makefile
@@ -38,4 +38,5 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku0.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-kukui-krane-sku176.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8183-pumpkin.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8192-evb.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += mt8195-evb.dtb
 dtb-$(CONFIG_ARCH_MEDIATEK) += mt8516-pumpkin.dtb
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-evb.dts b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
new file mode 100644
index 000000000000..51633d91d984
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195-evb.dts
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+/dts-v1/;
+#include "mt8195.dtsi"
+
+/ {
+	model = "MediaTek MT8195 evaluation board";
+	compatible = "mediatek,mt8195-evb", "mediatek,mt8195";
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:921600n8";
+	};
+
+	memory at 40000000 {
+		device_type = "memory";
+		reg = <0 0x40000000 0 0x80000000>;
+	};
+};
+
+&auxadc {
+	status = "okay";
+};
+
+&i2c0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c0_pin>;
+	clock-frequency = <100000>;
+	status = "okay";
+};
+
+&i2c1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c1_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c4_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&i2c6_pin>;
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&nor_flash {
+	status = "okay";
+	pinctrl-names = "default";
+	pinctrl-0 = <&nor_pins_default>;
+
+	flash at 0 {
+		compatible = "jedec,spi-nor";
+		reg = <0>;
+		spi-max-frequency = <50000000>;
+	};
+};
+
+&pio {
+	i2c0_pin: i2c0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO8__FUNC_SDA0>,
+				 <PINMUX_GPIO9__FUNC_SCL0>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c1_pin: i2c1-pins {
+		pins {
+			pinmux = <PINMUX_GPIO10__FUNC_SDA1>,
+				 <PINMUX_GPIO11__FUNC_SCL1>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <0>;
+			drive-strength = <6>;
+		};
+	};
+
+	i2c4_pin: i2c4-pins {
+		pins {
+			pinmux = <PINMUX_GPIO16__FUNC_SDA4>,
+				 <PINMUX_GPIO17__FUNC_SCL4>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+			mediatek,drive-strength-adv = <7>;
+		};
+	};
+
+	i2c6_pin: i2c6-pins {
+		pins {
+			pinmux = <PINMUX_GPIO25__FUNC_SDA6>,
+				 <PINMUX_GPIO26__FUNC_SCL6>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	i2c7_pin: i2c7-pins {
+		pins {
+			pinmux = <PINMUX_GPIO27__FUNC_SCL7>,
+				 <PINMUX_GPIO28__FUNC_SDA7>;
+			bias-pull-up = <MTK_PUPD_SET_R1R0_01>;
+		};
+	};
+
+	nor_pins_default: nor-pins {
+		pins0 {
+			pinmux = <PINMUX_GPIO142__FUNC_SPINOR_IO0>,
+				 <PINMUX_GPIO141__FUNC_SPINOR_CK>,
+				 <PINMUX_GPIO143__FUNC_SPINOR_IO1>;
+			bias-pull-down;
+		};
+
+		pins1 {
+			pinmux = <PINMUX_GPIO140__FUNC_SPINOR_CS>,
+				 <PINMUX_GPIO130__FUNC_SPINOR_IO2>,
+				 <PINMUX_GPIO131__FUNC_SPINOR_IO3>;
+			bias-pull-up;
+		};
+	};
+
+	uart0_pin: uart0-pins {
+		pins {
+			pinmux = <PINMUX_GPIO98__FUNC_UTXD0>,
+				 <PINMUX_GPIO99__FUNC_URXD0>;
+		};
+	};
+};
+
+&u2port0 {
+	status = "okay";
+};
+
+&u2port1 {
+	status = "okay";
+};
+
+&u3phy0 {
+	status="okay";
+};
+
+&u3phy1 {
+	status="okay";
+};
+
+&uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_pin>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
new file mode 100644
index 000000000000..a363e82f6988
--- /dev/null
+++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Seiya Wang <seiya.wang at mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/clock/mt8195-clk.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/pinctrl/mt8195-pinfunc.h>
+#include <dt-bindings/reset/ti-syscon.h>
+
+/ {
+	compatible = "mediatek,mt8195";
+	interrupt-parent = <&gic>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x000>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu1: cpu at 100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x100>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu2: cpu at 200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x200>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu3: cpu at 300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x300>;
+			enable-method = "psci";
+			clock-frequency = <1701000000>;
+			capacity-dmips-mhz = <578>;
+			cpu-idle-states = <&cpu_off_l &cluster_off_l>;
+			next-level-cache = <&l2_0>;
+			#cooling-cells = <2>;
+		};
+
+		cpu4: cpu at 400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x400>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu5: cpu at 500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x500>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu6: cpu at 600 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x600>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu7: cpu at 700 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78";
+			reg = <0x700>;
+			enable-method = "psci";
+			clock-frequency = <2171000000>;
+			capacity-dmips-mhz = <1024>;
+			cpu-idle-states = <&cpu_off_b &cluster_off_b>;
+			next-level-cache = <&l2_1>;
+			#cooling-cells = <2>;
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			cpu_off_l: cpu-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <95>;
+				min-residency-us = <580>;
+			};
+
+			cpu_off_b: cpu-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x00010001>;
+				local-timer-stop;
+				entry-latency-us = <45>;
+				exit-latency-us = <140>;
+				min-residency-us = <740>;
+			};
+
+			cluster_off_l: cluster-off-l {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <55>;
+				exit-latency-us = <155>;
+				min-residency-us = <840>;
+			};
+
+			cluster_off_b: cluster-off-b {
+				compatible = "arm,idle-state";
+				arm,psci-suspend-param = <0x01010002>;
+				local-timer-stop;
+				entry-latency-us = <50>;
+				exit-latency-us = <200>;
+				min-residency-us = <1000>;
+			};
+		};
+
+		l2_0: l2-cache0 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l2_1: l2-cache1 {
+			compatible = "cache";
+			next-level-cache = <&l3_0>;
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+		};
+	};
+
+	dsu-pmu {
+		compatible = "arm,dsu-pmu";
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH 0>;
+		cpus = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>,
+		       <&cpu4>, <&cpu5>, <&cpu6>, <&cpu7>;
+	};
+
+	clk26m: oscillator-26m {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <26000000>;
+		clock-output-names = "clk26m";
+	};
+
+	clk32k: oscillator-32k {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <32768>;
+		clock-output-names = "clk32k";
+	};
+
+	pmu-a55 {
+		compatible = "arm,cortex-a55-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>;
+	};
+
+	pmu-a78 {
+		compatible = "arm,cortex-a78-pmu";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster1>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+	};
+
+	timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH 0>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH 0>;
+	};
+
+	soc {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		compatible = "simple-bus";
+		ranges;
+
+		gic: interrupt-controller at c000000 {
+			compatible = "arm,gic-v3";
+			#interrupt-cells = <4>;
+			#redistributor-regions = <1>;
+			interrupt-parent = <&gic>;
+			interrupt-controller;
+			reg = <0 0x0c000000 0 0x40000>,
+			      <0 0x0c040000 0 0x200000>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>;
+
+			ppi-partitions {
+				ppi_cluster0: interrupt-partition-0 {
+					affinity = <&cpu0 &cpu1 &cpu2 &cpu3>;
+				};
+
+				ppi_cluster1: interrupt-partition-1 {
+					affinity = <&cpu4 &cpu5 &cpu6 &cpu7>;
+				};
+			};
+		};
+
+		topckgen: syscon at 10000000 {
+			compatible = "mediatek,mt8195-topckgen", "syscon";
+			reg = <0 0x10000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		infracfg_ao: syscon at 10001000 {
+			compatible = "mediatek,mt8195-infracfg_ao", "syscon", "simple-mfd";
+			reg = <0 0x10001000 0 0x1000>;
+			#clock-cells = <1>;
+
+			infracfg_rst: reset-controller {
+				compatible = "ti,syscon-reset";
+				#reset-cells = <1>;
+				ti,reset-bits = <
+					0x140 18 0x144 18 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* pcie */
+					0x120 0  0x124 0  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x730 10 0x734 10 0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* thermal */
+					0x150 5  0x154 5  0 0 (ASSERT_SET | DEASSERT_SET | STATUS_NONE) /* svs gpu */
+				>;
+			};
+		};
+
+		pericfg: syscon at 10003000 {
+			compatible = "mediatek,mt8195-pericfg", "syscon";
+			reg = <0 0x10003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		pio: pinctrl at 10005000 {
+			compatible = "mediatek,mt8195-pinctrl";
+			reg = <0 0x10005000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>,
+			      <0 0x11d30000 0 0x1000>,
+			      <0 0x11d40000 0 0x1000>,
+			      <0 0x11e20000 0 0x1000>,
+			      <0 0x11eb0000 0 0x1000>,
+			      <0 0x11f40000 0 0x1000>,
+			      <0 0x1000b000 0 0x1000>;
+			reg-names = "iocfg0", "iocfg_bm", "iocfg_bl",
+				    "iocfg_br", "iocfg_lm", "iocfg_rb",
+				    "iocfg_tl", "eint";
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&pio 0 0 144>;
+			interrupt-controller;
+			interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH 0>;
+			#interrupt-cells = <2>;
+		};
+
+		watchdog: watchdog at 10007000 {
+			compatible = "mediatek,mt8195-wdt",
+				     "mediatek,mt6589-wdt";
+			reg = <0 0x10007000 0 0x100>;
+		};
+
+		apmixedsys: syscon at 1000c000 {
+			compatible = "mediatek,mt8195-apmixedsys", "syscon";
+			reg = <0 0x1000c000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		systimer: timer at 10017000 {
+			compatible = "mediatek,mt8195-timer",
+				     "mediatek,mt6765-timer";
+			reg = <0 0x10017000 0 0x1000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_CLK26M_D2>;
+		};
+
+		pwrap: pwrap at 10024000 {
+			compatible = "mediatek,mt8195-pwrap", "syscon";
+			reg = <0 0x10024000 0 0x1000>;
+			reg-names = "pwrap";
+			interrupts = <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_PMIC_AP>,
+				 <&infracfg_ao CLK_INFRA_AO_PMIC_TMR>;
+			clock-names = "spi", "wrap";
+			assigned-clocks = <&topckgen CLK_TOP_PWRAP_ULPOSC>;
+			assigned-clock-parents = <&topckgen CLK_TOP_ULPOSC1_D10>;
+		};
+
+		scp_adsp: clock-controller at 10720000 {
+			compatible = "mediatek,mt8195-scp_adsp";
+			reg = <0 0x10720000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		uart0: serial at 11001100 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001100 0 0x100>;
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART0>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart1: serial at 11001200 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001200 0 0x100>;
+			interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART1>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart2: serial at 11001300 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001300 0 0x100>;
+			interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART2>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart3: serial at 11001400 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001400 0 0x100>;
+			interrupts = <GIC_SPI 723 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART3>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart4: serial at 11001500 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001500 0 0x100>;
+			interrupts = <GIC_SPI 724 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART4>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		uart5: serial at 11001600 {
+			compatible = "mediatek,mt8195-uart",
+				     "mediatek,mt6577-uart";
+			reg = <0 0x11001600 0 0x100>;
+			interrupts = <GIC_SPI 725 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&clk26m>, <&infracfg_ao CLK_INFRA_AO_UART5>;
+			clock-names = "baud", "bus";
+			status = "disabled";
+		};
+
+		auxadc: auxadc at 11002000 {
+			compatible = "mediatek,mt8195-auxadc",
+				     "mediatek,mt8173-auxadc";
+			reg = <0 0x11002000 0 0x1000>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_AUXADC>;
+			clock-names = "main";
+			#io-channel-cells = <1>;
+			status = "disabled";
+		};
+
+		pericfg_ao: syscon at 11003000 {
+			compatible = "mediatek,mt8195-pericfg_ao", "syscon";
+			reg = <0 0x11003000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		spi0: spi at 1100a000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x1100a000 0 0x1000>;
+			interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI0>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi1: spi at 11010000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11010000 0 0x1000>;
+			interrupts = <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI1>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi2: spi at 11012000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11012000 0 0x1000>;
+			interrupts = <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI2>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi3: spi at 11013000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11013000 0 0x1000>;
+			interrupts = <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI3>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi4: spi at 11018000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11018000 0 0x1000>;
+			interrupts = <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI4>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spi5: spi at 11019000 {
+			compatible = "mediatek,mt8195-spi",
+				     "mediatek,mt6765-spi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0 0x11019000 0 0x1000>;
+			interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_UNIVPLL_D6_D2>,
+				 <&topckgen CLK_TOP_SPI>,
+				 <&infracfg_ao CLK_INFRA_AO_SPI5>;
+			clock-names = "parent-clk", "sel-clk", "spi-clk";
+			status = "disabled";
+		};
+
+		spis0: spi at 1101d000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101d000 0 0x1000>;
+			interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS0>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		spis1: spi at 1101e000 {
+			compatible = "mediatek,mt8195-spi-slave";
+			reg = <0 0x1101e000 0 0x1000>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SPIS1>;
+			clock-names = "spi";
+			assigned-clocks = <&topckgen CLK_TOP_SPIS>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D6>;
+			status = "disabled";
+		};
+
+		xhci0: usb at 11200000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11200000 0 0x1000>,
+			      <0 0x11203e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port0 PHY_TYPE_USB2>,
+			       <&u3port0 PHY_TYPE_USB3>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB>,
+				 <&topckgen CLK_TOP_SSUSB_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		mmc0: mmc at 11230000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11230000 0 0x10000>,
+			      <0 0x11f50000 0 0x1000>;
+			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC50_0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC0_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			status = "disabled";
+		};
+
+		mmc1: mmc at 11240000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11240000 0 0x1000>,
+			      <0 0x11c70000 0 0x1000>;
+			interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1>,
+				 <&infracfg_ao CLK_INFRA_AO_MSDC1_SRC>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_1>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		mmc2: mmc at 11250000 {
+			compatible = "mediatek,mt8195-mmc",
+				     "mediatek,mt8183-mmc";
+			reg = <0 0x11250000 0 0x1000>,
+			      <0 0x11e60000 0 0x1000>;
+			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_MSDC30_2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG1_MSDC2>,
+				 <&infracfg_ao CLK_INFRA_AO_CG3_MSDC2>;
+			clock-names = "source", "hclk", "source_cg";
+			assigned-clocks = <&topckgen CLK_TOP_MSDC30_2>;
+			assigned-clock-parents = <&topckgen CLK_TOP_MSDCPLL_D2>;
+			status = "disabled";
+		};
+
+		xhci1: usb at 11290000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x11290000 0 0x1000>,
+			      <0 0x11293e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port1 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_1P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_1P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_1P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P1_REF>,
+				 <&apmixedsys CLK_APMIXED_USB1PLL>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_1P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck","xhci_ck";
+			status = "disabled";
+		};
+
+		xhci2: usb at 112a0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112a0000 0 0x1000>,
+			      <0 0x112a3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port2 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_2P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_2P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_2P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P2_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_2P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			status = "disabled";
+		};
+
+		xhci3: usb at 112b0000 {
+			compatible = "mediatek,mt8195-xhci",
+				     "mediatek,mtk-xhci";
+			reg = <0 0x112b0000 0 0x1000>,
+			      <0 0x112b3e00 0 0x0100>;
+			reg-names = "mac", "ippc";
+			interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH 0>;
+			phys = <&u2port3 PHY_TYPE_USB2>;
+			assigned-clocks = <&topckgen CLK_TOP_USB_TOP_3P>,
+					  <&topckgen CLK_TOP_SSUSB_XHCI_3P>;
+			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D5_D4>,
+						 <&topckgen CLK_TOP_UNIVPLL_D5_D4>;
+			clocks = <&pericfg_ao CLK_PERI_AO_SSUSB_3P_BUS>,
+				 <&topckgen CLK_TOP_SSUSB_P3_REF>,
+				 <&pericfg_ao CLK_PERI_AO_SSUSB_3P_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "xhci_ck";
+			/* This controller is connected with a BT device.
+			 * Disable usb2 lpm to prevent known issues.
+			 */
+			usb2-lpm-disable;
+			status = "disabled";
+		};
+
+		nor_flash: spi at 1132c000 {
+			compatible = "mediatek,mt8195-nor",
+				     "mediatek,mt8173-nor";
+			reg = <0 0x1132c000 0 0x1000>;
+			interrupts = <GIC_SPI 825 IRQ_TYPE_LEVEL_HIGH 0>;
+			clocks = <&topckgen CLK_TOP_SPINOR>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_FLASH>,
+				 <&pericfg_ao CLK_PERI_AO_FLASHIF_BUS>;
+			clock-names = "spi", "sf", "axi";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		u3phy2: t-phy at 11c40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c40000 0x700>;
+			status = "disabled";
+
+			u2port2: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P2_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy3: t-phy at 11c50000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11c50000 0x700>;
+			status = "disabled";
+
+			u2port3: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P3_REF>;
+				clock-names = "ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		i2c5: i2c at 11d00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d00000 0 0x1000>,
+			      <0 0x10220580 0 0x80>;
+			interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C5>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c6: i2c at 11d01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d01000 0 0x1000>,
+			      <0 0x10220600 0 0x80>;
+			interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C6>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c7: i2c at 11d02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11d02000 0 0x1000>,
+			      <0 0x10220680 0 0x80>;
+			interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_s CLK_IMP_IIC_WRAP_S_I2C7>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_s: clock-controller at 11d03000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_s";
+			reg = <0 0x11d03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		i2c0: i2c at 11e00000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e00000 0 0x1000>,
+			      <0 0x10220080 0 0x80>;
+			interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C0>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "okay";
+		};
+
+		i2c1: i2c at 11e01000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e01000 0 0x1000>,
+			      <0 0x10220200 0 0x80>;
+			interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C1>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c2: i2c at 11e02000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e02000 0 0x1000>,
+			      <0 0x10220380 0 0x80>;
+			interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C2>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c3: i2c at 11e03000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e03000 0 0x1000>,
+			      <0 0x10220480 0 0x80>;
+			interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C3>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		i2c4: i2c at 11e04000 {
+			compatible = "mediatek,mt8195-i2c",
+				     "mediatek,mt8192-i2c";
+			reg = <0 0x11e04000 0 0x1000>,
+			      <0 0x10220500 0 0x80>;
+			interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH 0>;
+			clock-div = <1>;
+			clocks = <&imp_iic_wrap_w CLK_IMP_IIC_WRAP_W_I2C4>,
+				 <&infracfg_ao CLK_INFRA_AO_APDMA_B>;
+			clock-names = "main", "dma";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
+		imp_iic_wrap_w: clock-controller at 11e05000 {
+			compatible = "mediatek,mt8195-imp_iic_wrap_w";
+			reg = <0 0x11e05000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		u3phy1: t-phy at 11e30000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e30000 0xe00>;
+			status = "disabled";
+
+			u2port1: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port1: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_P1_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		u3phy0: t-phy at 11e40000 {
+			compatible = "mediatek,mt8195-tphy", "mediatek,generic-tphy-v3";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0 0x11e40000 0xe00>;
+			status = "disabled";
+
+			u2port0: usb-phy at 0 {
+				reg = <0x0 0x700>;
+				clocks = <&topckgen CLK_TOP_SSUSB_PHY_REF>,
+					 <&clk26m>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+
+			u3port0: usb-phy at 700 {
+				reg = <0x700 0x700>;
+				clocks = <&apmixedsys CLK_APMIXED_PLL_SSUSB26M>,
+					 <&topckgen CLK_TOP_SSUSB_PHY_REF>;
+				clock-names = "ref", "da_ref";
+				#phy-cells = <1>;
+			};
+		};
+
+		ufsphy: ufs-phy at 11fa0000 {
+			compatible = "mediatek,mt8195-ufsphy", "mediatek,mt8183-ufsphy";
+			reg = <0 0x11fa0000 0 0xc000>;
+			clocks = <&clk26m>, <&clk26m>;
+			clock-names = "unipro", "mp";
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		mfgcfg: clock-controller at 13fbf000 {
+			compatible = "mediatek,mt8195-mfgcfg";
+			reg = <0 0x13fbf000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys: clock-controller at 14e00000 {
+			compatible = "mediatek,mt8195-wpesys";
+			reg = <0 0x14e00000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp0: clock-controller at 14e02000 {
+			compatible = "mediatek,mt8195-wpesys_vpp0";
+			reg = <0 0x14e02000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		wpesys_vpp1: clock-controller at 14e03000 {
+			compatible = "mediatek,mt8195-wpesys_vpp1";
+			reg = <0 0x14e03000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys: clock-controller at 15000000 {
+			compatible = "mediatek,mt8195-imgsys";
+			reg = <0 0x15000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_top: clock-controller at 15110000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_top";
+			reg = <0 0x15110000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_dip_nr: clock-controller at 15130000 {
+			compatible = "mediatek,mt8195-imgsys1_dip_nr";
+			reg = <0 0x15130000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		imgsys1_wpe: clock-controller at 15220000 {
+			compatible = "mediatek,mt8195-imgsys1_wpe";
+			reg = <0 0x15220000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ipesys: clock-controller at 15330000 {
+			compatible = "mediatek,mt8195-ipesys";
+			reg = <0 0x15330000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys: clock-controller at 16000000 {
+			compatible = "mediatek,mt8195-camsys";
+			reg = <0 0x16000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawa: clock-controller at 1604f000 {
+			compatible = "mediatek,mt8195-camsys_rawa";
+			reg = <0 0x1604f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuva: clock-controller at 1606f000 {
+			compatible = "mediatek,mt8195-camsys_yuva";
+			reg = <0 0x1606f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_rawb: clock-controller at 1608f000 {
+			compatible = "mediatek,mt8195-camsys_rawb";
+			reg = <0 0x1608f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_yuvb: clock-controller at 160af000 {
+			compatible = "mediatek,mt8195-camsys_yuvb";
+			reg = <0 0x160af000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		camsys_mraw: clock-controller at 16140000 {
+			compatible = "mediatek,mt8195-camsys_mraw";
+			reg = <0 0x16140000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		ccusys: clock-controller at 17200000 {
+			compatible = "mediatek,mt8195-ccusys";
+			reg = <0 0x17200000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_soc: clock-controller at 1800f000 {
+			compatible = "mediatek,mt8195-vdecsys_soc";
+			reg = <0 0x1800f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys: clock-controller at 1802f000 {
+			compatible = "mediatek,mt8195-vdecsys";
+			reg = <0 0x1802f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vdecsys_core1: clock-controller at 1803f000 {
+			compatible = "mediatek,mt8195-vdecsys_core1";
+			reg = <0 0x1803f000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		apusys_pll: clock-controller at 190f3000 {
+			compatible = "mediatek,mt8195-apusys_pll";
+			reg = <0 0x190f3000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys: clock-controller at 1a000000 {
+			compatible = "mediatek,mt8195-vencsys";
+			reg = <0 0x1a000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+
+		vencsys_core1: clock-controller at 1b000000 {
+			compatible = "mediatek,mt8195-vencsys_core1";
+			reg = <0 0x1b000000 0 0x1000>;
+			#clock-cells = <1>;
+		};
+	};
+};
-- 
2.18.0



From tinghan.shen at mediatek.com  Sat Jan 29 18:32:07 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Sun, 30 Jan 2022 10:32:07 +0800
Subject: [PATCH v10 1/3] dt-bindings: arm: mediatek: Add mt8195 pericfg
 compatible
In-Reply-To: <20220130023209.16275-1-tinghan.shen@mediatek.com>
References: <20220130023209.16275-1-tinghan.shen@mediatek.com>
Message-ID: <20220130023209.16275-2-tinghan.shen@mediatek.com>

Add mt8195 pericfg compatible to binding document.

Signed-off-by: Tinghan Shen <tinghan.shen at mediatek.com>
Acked-by: Rob Herring <robh at kernel.org>
Acked-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
---
 .../devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml       | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
index 8723dfe34bab..611f666f359d 100644
--- a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
+++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
@@ -26,6 +26,7 @@ properties:
               - mediatek,mt8135-pericfg
               - mediatek,mt8173-pericfg
               - mediatek,mt8183-pericfg
+              - mediatek,mt8195-pericfg
               - mediatek,mt8516-pericfg
           - const: syscon
       - items:
-- 
2.18.0



From tinghan.shen at mediatek.com  Sat Jan 29 18:32:06 2022
From: tinghan.shen at mediatek.com (Tinghan Shen)
Date: Sun, 30 Jan 2022 10:32:06 +0800
Subject: [PATCH v10 0/3] Add basic SoC support for mediatek mt8195
Message-ID: <20220130023209.16275-1-tinghan.shen@mediatek.com>

This series adds basic SoC support for Mediatek's SoC MT8195.

---
Changes in v10:
  - clean CC list
Changes in v9:
  - remove duplicated cpus dt-bindings patch in v8
Changes in v8:
  - v7 mediatek,spi-mtk-nor.yaml patch is applied in branch for-5.17 at 
    kernel/git/broonie/spi.git
  - v7 pinctrl-mt8195.yaml patch is applied in branch for-next at 
    kernel/git/linusw/linux-pinctrl.git
  - add cortex-a78 compatible to cpus dt-bindings
  - add mediatek,drive-strength-adv property to pinctrl dt-bindings
  - fix evb dts
    - remove i2c nodes with disabled status from dts
    - fix pin properties not match pinctrl dt-bindings
    - remove unnecessary u3port*
  - fix dtsi
    - fix node format
    - reorder oscillator* nodes 
    - fix node name of cpu idle nodes
    - remove clock-frequency property in the timer node
    - reorder clock and clock names in usb nodes
Changes in v7:
  - refine title of spi-nor dt-bindings patch
  - refine commit message of pinctrl dt-bindings patch
  - update pinctrl-mt8195.yaml
    - change property pattern from 'pins' to '^pins'
    - update examples with new property in descriptions
    - add new example
  - drop '_' from node names of pinctrl subnodes in mt8195-evb.dts
Changes in v6:
  - rebase on 5.16-rc1
  - add new clock name to spi-nor dt-bindings
  - add "pins" property in pinctrl dt-bindings
  - fix fails of dtbs_checks
    - remove "arm,armv8" not matched in yaml from cpu compatile
    - fix node name of xhci
    - remvoe xhci upstreaming wakeup properties
    - remove xhci unused properties address-cells and size-cells
    - fix node name of ufs-phy 
    - fix node name of spi-nor
    - fix node name and sub-nodes of pinctrl
    - fix mmc compatible
Changes in v5:
  - enable basic nodes in mt8195-evb.dts
  - remove dedicated clock nodes
  - add mmc2 node
  - fix interrupt number of pinctrl node
  - update clock nodes to apply internal fixes
  - add dt-bindings for perficfg node

v4 thread:
https://lore.kernel.org/all/20210922093303.23720-2-seiya.wang at mediatek.com/
v3 thread:
https://lore.kernel.org/all/20210601075350.31515-2-seiya.wang at mediatek.com/
v2 thread:
https://lore.kernel.org/all/20210319023427.16711-10-seiya.wang at mediatek.com/
v1 thread:
https://lore.kernel.org/all/20210316111443.3332-11-seiya.wang at mediatek.com/
---

Tinghan Shen (3):
  dt-bindings: arm: mediatek: Add mt8195 pericfg compatible
  dt-bindings: pinctrl: mt8195: Add mediatek,drive-strength-adv property
  arm64: dts: Add mediatek SoC mt8195 and evaluation board

 .../arm/mediatek/mediatek,pericfg.yaml        |    1 +
 .../bindings/pinctrl/pinctrl-mt8195.yaml      |   35 +
 arch/arm64/boot/dts/mediatek/Makefile         |    1 +
 arch/arm64/boot/dts/mediatek/mt8195-evb.dts   |  161 +++
 arch/arm64/boot/dts/mediatek/mt8195.dtsi      | 1049 +++++++++++++++++
 5 files changed, 1247 insertions(+)
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195-evb.dts
 create mode 100644 arch/arm64/boot/dts/mediatek/mt8195.dtsi

-- 
2.18.0



From samuel at sholland.org  Sat Jan 29 21:38:01 2022
From: samuel at sholland.org (Samuel Holland)
Date: Sat, 29 Jan 2022 23:38:01 -0600
Subject: [PATCH 1/3] dt-bindings: arm: rockchip: Add Pine64 PineNote board
Message-ID: <20220130053803.43660-1-samuel@sholland.org>

The PineNote is a tablet from Pine64 based on the RK3566 SoC. There are
two existing variants of the board. v1.1 was contained in some early
samples, and v1.2 was sold as the "PineNote Developer Edition".

Signed-off-by: Samuel Holland <samuel at sholland.org>
---

 Documentation/devicetree/bindings/arm/rockchip.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml
index 4aed16176434..77fedeae8d2e 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.yaml
+++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -481,6 +481,14 @@ properties:
           - const: pine64,pinebook-pro
           - const: rockchip,rk3399
 
+      - description: Pine64 PineNote
+        items:
+          - enum:
+              - pine64,pinenote-v1.1
+              - pine64,pinenote-v1.2
+          - const: pine64,pinenote
+          - const: rockchip,rk3566
+
       - description: Pine64 Rock64
         items:
           - const: pine64,rock64
-- 
2.33.1



From samuel at sholland.org  Sat Jan 29 21:38:03 2022
From: samuel at sholland.org (Samuel Holland)
Date: Sat, 29 Jan 2022 23:38:03 -0600
Subject: [PATCH 3/3] arm64: dts: rockchip: Add Pine64 PineNote board
In-Reply-To: <20220130053803.43660-1-samuel@sholland.org>
References: <20220130053803.43660-1-samuel@sholland.org>
Message-ID: <20220130053803.43660-3-samuel@sholland.org>

The PineNote is a tablet from Pine64 based on the RK3566 SoC, featuring
4G/128G of storage, a 10.3" electrophoretic display (EPD) with two-color
frontlight, both EMR and capacitive digitizers, dual-band wireless,
quad-channel digital microphones, and stereo speakers.

There are two existing variants of the board. v1.1 was contained in some
early samples, and v1.2 was sold as the "PineNote Developer Edition".

Signed-off-by: Samuel Holland <samuel at sholland.org>
---

 arch/arm64/boot/dts/rockchip/Makefile         |   2 +
 .../dts/rockchip/rk3566-pinenote-v1.1.dts     |  18 +
 .../dts/rockchip/rk3566-pinenote-v1.2.dts     |  18 +
 .../boot/dts/rockchip/rk3566-pinenote.dtsi    | 638 ++++++++++++++++++
 4 files changed, 676 insertions(+)
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts
 create mode 100644 arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi

diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile
index 479906f3ad7b..2e67f2558b6a 100644
--- a/arch/arm64/boot/dts/rockchip/Makefile
+++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -56,5 +56,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.1.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-pinenote-v1.2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3566-quartz64-a.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-evb1-v10.dtb
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts
new file mode 100644
index 000000000000..1901a456e91b
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.1.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinenote.dtsi"
+
+/ {
+	model = "Pine64 PineNote v1.1";
+	compatible = "pine64,pinenote-v1.1", "pine64,pinenote", "rockchip,rk3566";
+};
+
+&spk_amp {
+	VCC-supply = <&dcdc_boost>;
+};
+
+&pmu_io_domains {
+	vccio7-supply = <&vcc_1v8>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts
new file mode 100644
index 000000000000..d7f5372fc40f
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote-v1.2.dts
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include "rk3566-pinenote.dtsi"
+
+/ {
+	model = "Pine64 PineNote v1.2";
+	compatible = "pine64,pinenote-v1.2", "pine64,pinenote", "rockchip,rk3566";
+};
+
+&spk_amp {
+	VCC-supply = <&vcc_bat>;
+};
+
+&pmu_io_domains {
+	vccio7-supply = <&vcc_3v3>;
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
new file mode 100644
index 000000000000..0d8f4db3901d
--- /dev/null
+++ b/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -0,0 +1,638 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#include "rk3566.dtsi"
+
+/ {
+	aliases {
+		mmc0 = &sdhci;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+
+	adc-keys-0 {
+		compatible = "adc-keys";
+		io-channels = <&saradc 0>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <1750000>;
+
+		button-recovery {
+			label = "Recovery";
+			linux,code = <KEY_VENDOR>;
+			press-threshold-microvolt = <0>;
+		};
+	};
+
+	spk_amp: audio-amplifier {
+		compatible = "simple-audio-amplifier";
+		enable-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&spk_amp_enable_h>;
+		pinctrl-names = "default";
+		sound-name-prefix = "Speaker Amp";
+	};
+
+	dmic_codec: dmic-codec {
+		compatible = "dmic-codec";
+		num-channels = <6>;
+		#sound-dai-cells = <0>;
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-0 = <&hall_int_l>;
+		pinctrl-names = "default";
+
+		switch-cover {
+			label = "Cover";
+			gpios = <&gpio0 RK_PC7 GPIO_ACTIVE_LOW>;
+			linux,input-type = <EV_SW>;
+			linux,code = <SW_MACHINE_COVER>;
+			linux,can-disable;
+			wakeup-event-action = <EV_ACT_DEASSERTED>;
+			wakeup-source;
+		};
+	};
+
+	gpio-leds {
+		compatible = "gpio-leds";
+		pinctrl-0 = <&led_gpio>;
+		pinctrl-names = "default";
+
+		led-0 {
+			color = <LED_COLOR_ID_WHITE>;
+			function = LED_FUNCTION_CHARGING;
+			gpios = <&gpio3 RK_PC5 GPIO_ACTIVE_HIGH>;
+		};
+	};
+
+	sdio_pwrseq: sdio-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		clocks = <&rk817 1>;
+		clock-names = "ext_clock";
+		pinctrl-0 = <&wifi_enable_h>;
+		pinctrl-names = "default";
+		reset-gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_LOW>;
+	};
+
+	sound {
+		compatible = "simple-audio-card";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		simple-audio-card,name = "PineNote";
+		simple-audio-card,aux-devs = <&spk_amp>;
+		simple-audio-card,widgets = "Headphone", "Headphones",
+					    "Speaker", "Internal Speakers";
+		simple-audio-card,routing = "Headphones", "HPOL",
+					    "Headphones", "HPOR",
+					    "Internal Speakers", "Speaker Amp OUTL",
+					    "Internal Speakers", "Speaker Amp OUTR",
+					    "Speaker Amp INL", "HPOL",
+					    "Speaker Amp INR", "HPOR";
+		simple-audio-card,pin-switches = "Internal Speakers";
+
+		simple-audio-card,dai-link at 0 {
+			format = "i2s";
+			mclk-fs = <256>;
+			frame-master = <&link0_cpu>;
+			bitclock-master = <&link0_cpu>;
+
+			link0_cpu: cpu {
+				sound-dai = <&i2s1_8ch>;
+			};
+
+			link0_codec: codec {
+				sound-dai = <&rk817>;
+			};
+		};
+
+		simple-audio-card,dai-link at 1 {
+			format = "pdm";
+			frame-master = <&link1_cpu>;
+			bitclock-master = <&link1_cpu>;
+
+			link1_cpu: cpu {
+				sound-dai = <&pdm>;
+			};
+
+			link1_codec: codec {
+				sound-dai = <&dmic_codec>;
+			};
+		};
+	};
+
+	vbat_4g: vbat-4g {
+		compatible = "regulator-fixed";
+		regulator-name = "vbat_4g";
+		regulator-min-microvolt = <3800000>;
+		regulator-max-microvolt = <3800000>;
+		/* powered by vcc_bat, enabled by vbat_4g_en */
+		vin-supply = <&vbat_4g_en>;
+	};
+
+	vcc_1v8: vcc-1v8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_1v8";
+		regulator-always-on;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		/* powered by vcc_sys, enabled by vcc_1v8_en */
+		vin-supply = <&vcc_1v8_en>;
+	};
+
+	vcc_bat: vcc-bat {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_bat";
+		regulator-always-on;
+		regulator-min-microvolt = <3800000>;
+		regulator-max-microvolt = <3800000>;
+	};
+
+	vcc_hall_3v3: vcc-hall-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_hall_3v3";
+		regulator-always-on;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_sys>;
+	};
+
+	vcc_sys: vcc-sys {
+		compatible = "regulator-fixed";
+		regulator-name = "vcc_sys";
+		regulator-always-on;
+		regulator-min-microvolt = <3800000>;
+		regulator-max-microvolt = <3800000>;
+		vin-supply = <&vcc_bat>;
+	};
+
+	vcc_wl: vcc-wl {
+		compatible = "regulator-fixed";
+		enable-active-high;
+		gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&vcc_wl_gpio>;
+		pinctrl-names = "default";
+		regulator-name = "vcc_wl";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		vin-supply = <&vcc_bat>;
+	};
+
+	vdda_0v9: vdda-0v9 {
+		compatible = "regulator-fixed";
+		regulator-name = "vdda_0v9";
+		regulator-always-on;
+		regulator-min-microvolt = <900000>;
+		regulator-max-microvolt = <900000>;
+		/* powered by vcc_sys, enabled by vcc_1v8_en */
+		vin-supply = <&vcc_1v8_en>;
+	};
+};
+
+&cpu0 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu1 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu2 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&cpu3 {
+	cpu-supply = <&vdd_cpu>;
+};
+
+&i2c0 {
+	status = "okay";
+
+	vdd_cpu: regulator at 1c {
+		compatible = "tcs,tcs4525";
+		reg = <0x1c>;
+		fcs,suspend-voltage-selector = <0>;
+		regulator-name = "vdd_cpu";
+		regulator-min-microvolt = <712500>;
+		regulator-max-microvolt = <1390000>;
+		regulator-ramp-delay = <2300>;
+		regulator-always-on;
+		vin-supply = <&vcc_sys>;
+
+		regulator-state-mem {
+			regulator-on-in-suspend;
+		};
+	};
+
+	rk817: pmic at 20 {
+		compatible = "rockchip,rk817";
+		reg = <0x20>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA3 IRQ_TYPE_LEVEL_LOW>;
+		assigned-clocks = <&cru I2S1_MCLKOUT_TX>;
+		assigned-clock-parents = <&cru CLK_I2S1_8CH_TX>;
+		clocks = <&cru I2S1_MCLKOUT_TX>;
+		clock-names = "mclk";
+		#clock-cells = <1>;
+		pinctrl-0 = <&i2s1m0_mclk>, <&pmic_int_l>, <&pmic_sleep>;
+		pinctrl-names = "default";
+		rockchip,system-power-controller;
+		#sound-dai-cells = <0>;
+		wakeup-source;
+
+		vcc1-supply = <&vcc_sys>;
+		vcc2-supply = <&vcc_sys>;
+		vcc3-supply = <&vcc_sys>;
+		vcc4-supply = <&vcc_sys>;
+		vcc5-supply = <&vcc_sys>;
+		vcc6-supply = <&vcc_sys>;
+		vcc7-supply = <&vcc_sys>;
+		vcc8-supply = <&vcc_sys>;
+		vcc9-supply = <&dcdc_boost>;
+
+		regulators {
+			vdd_logic: DCDC_REG1 {
+				regulator-name = "vdd_logic";
+				regulator-always-on;
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+					regulator-suspend-microvolt = <900000>;
+				};
+			};
+
+			vdd_gpu_npu: DCDC_REG2 {
+				regulator-name = "vdd_gpu_npu";
+				regulator-min-microvolt = <500000>;
+				regulator-max-microvolt = <1350000>;
+				regulator-init-microvolt = <900000>;
+				regulator-ramp-delay = <6001>;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_ddr: DCDC_REG3 {
+				regulator-name = "vcc_ddr";
+				regulator-always-on;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_3v3: DCDC_REG4 {
+				regulator-name = "vcc_3v3";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+				regulator-initial-mode = <0x2>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcca_1v8_pmu: LDO_REG1 {
+				regulator-name = "vcca_1v8_pmu";
+				regulator-always-on;
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			/* unused */
+			vdda_0v9_ldo: LDO_REG2 {
+				regulator-name = "vdda_0v9_ldo";
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vdda_0v9_pmu: LDO_REG3 {
+				regulator-name = "vdda_0v9_pmu";
+				regulator-always-on;
+				regulator-min-microvolt = <900000>;
+				regulator-max-microvolt = <900000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vccio_acodec: LDO_REG4 {
+				regulator-name = "vccio_acodec";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			/* unused */
+			vccio_sd: LDO_REG5 {
+				regulator-name = "vccio_sd";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vcc_3v3_pmu: LDO_REG6 {
+				regulator-name = "vcc_3v3_pmu";
+				regulator-always-on;
+				regulator-min-microvolt = <3300000>;
+				regulator-max-microvolt = <3300000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			vcc_1v8_en: LDO_REG7 {
+				regulator-name = "vcc_1v8_en";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			vbat_4g_en: LDO_REG8 {
+				regulator-name = "vbat_4g_en";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			sleep_sta_ctl: LDO_REG9 {
+				regulator-name = "sleep_sta_ctl";
+				regulator-min-microvolt = <1800000>;
+				regulator-max-microvolt = <1800000>;
+
+				regulator-state-mem {
+					regulator-on-in-suspend;
+				};
+			};
+
+			dcdc_boost: BOOST {
+				regulator-name = "boost";
+				regulator-min-microvolt = <5000000>;
+				regulator-max-microvolt = <5000000>;
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+
+			otg_switch: OTG_SWITCH {
+				regulator-name = "otg_switch";
+
+				regulator-state-mem {
+					regulator-off-in-suspend;
+				};
+			};
+		};
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	digitizer at 9 {
+		compatible = "wacom,w9013", "hid-over-i2c";
+		reg = <0x09>;
+		hid-descr-addr = <0x1>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PB6 IRQ_TYPE_LEVEL_LOW>;
+		pinctrl-0 = <&pen_fwe>, <&pen_irq_l>, <&pen_rst_l>;
+		pinctrl-names = "default";
+		vdd-supply = <&vcc_3v3_pmu>;
+	};
+};
+
+&i2c3 {
+	pinctrl-0 = <&i2c3m1_xfer>;
+	status = "okay";
+
+	led-controller at 36 {
+		compatible = "ti,lm3630a";
+		reg = <0x36>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		enable-gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&backlight_hwen_h>;
+		pinctrl-names = "default";
+
+		led at 0 {
+			reg = <0>;
+			label = "backlight_cool";
+			default-brightness = <0>;
+		};
+
+		led at 1 {
+			reg = <1>;
+			label = "backlight_warm";
+			default-brightness = <0>;
+		};
+	};
+};
+
+&i2s1_8ch {
+	pinctrl-0 = <&i2s1m0_lrcktx>, <&i2s1m0_sclktx>, <&i2s1m0_sdi0>, <&i2s1m0_sdo0>;
+	rockchip,trcm-sync-tx-only;
+	status = "okay";
+};
+
+&pdm {
+	pinctrl-0 = <&pdmm0_clk1>, <&pdmm0_sdi1>, <&pdmm0_sdi2>;
+	/* microphones are on channels 1 and 2 */
+	rockchip,path-map = <1>, <2>, <0>, <3>;
+	status = "okay";
+};
+
+&pinctrl {
+	audio-amplifier {
+		spk_amp_enable_h: spk-amp-enable-h {
+			rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	backlight {
+		backlight_hwen_h: backlight-hwen-h {
+			rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	bt {
+		bt_enable_h: bt-enable-h {
+			rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_host_wake_l: bt-host-wake-l {
+			rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+
+		bt_wake_h: bt-wake-h {
+			rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	led {
+		led_gpio: led-gpio {
+			rockchip,pins = <3 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	hall {
+		hall_int_l: hall-int-l {
+			rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pen {
+		pen_fwe: pen-fwe {
+			rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		pen_irq_l: pen-irq-l {
+			rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pen_rst_l: pen-rst-l {
+			rockchip,pins = <0 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	pmic {
+		pmic_int_l: pmic-int-l {
+			rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		pmic_sleep: pmic-sleep {
+			rockchip,pins = <0 RK_PA2 1 &pcfg_pull_none>;
+		};
+	};
+
+	sdio-pwrseq {
+		wifi_enable_h: wifi-enable-h {
+			rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	vcc-wl {
+		vcc_wl_gpio: vcc-wl-gpio {
+			rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	wifi {
+		wifi_host_wake_l: wifi-host-wake-l {
+			rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+};
+
+&pmu_io_domains {
+	pmuio1-supply = <&vcc_3v3_pmu>;
+	pmuio2-supply = <&vcc_3v3_pmu>;
+	vccio1-supply = <&vccio_acodec>;
+	vccio2-supply = <&vcc_1v8>;
+	vccio3-supply = <&vcc_3v3>;
+	vccio4-supply = <&vcca_1v8_pmu>;
+	vccio5-supply = <&vcc_3v3>;
+	vccio6-supply = <&vcc_3v3>;
+	status = "okay";
+};
+
+&saradc {
+	vref-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdhci {
+	bus-width = <8>;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, <&emmc_datastrobe>, <&emmc_rstnout>;
+	pinctrl-names = "default";
+	vmmc-supply = <&vcc_3v3>;
+	vqmmc-supply = <&vcc_1v8>;
+	status = "okay";
+};
+
+&sdmmc1 {
+	bus-width = <4>;
+	cap-sd-highspeed;
+	cap-sdio-irq;
+	disable-wp;
+	keep-power-in-suspend;
+	mmc-pwrseq = <&sdio_pwrseq>;
+	non-removable;
+	pinctrl-0 = <&sdmmc1_bus4>, <&sdmmc1_clk>, <&sdmmc1_cmd>;
+	pinctrl-names = "default";
+	sd-uhs-sdr104;
+	vmmc-supply = <&vcc_wl>;
+	vqmmc-supply = <&vcca_1v8_pmu>;
+	status = "okay";
+};
+
+&tsadc {
+	/* tshut mode 0:CRU 1:GPIO */
+	rockchip,hw-tshut-mode = <1>;
+	/* tshut polarity 0:LOW 1:HIGH */
+	rockchip,hw-tshut-polarity = <0>;
+	status = "okay";
+};
+
+&uart1 {
+	pinctrl-0 = <&uart1m0_ctsn>, <&uart1m0_rtsn>, <&uart1m0_xfer>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm43438-bt";
+		clocks = <&rk817 1>;
+		clock-names = "lpo";
+		device-wake-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+		host-wake-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
+		pinctrl-0 = <&bt_enable_h>, <&bt_host_wake_l>, <&bt_wake_h>;
+		pinctrl-names = "default";
+		vbat-supply = <&vcc_wl>;
+		vddio-supply = <&vcca_1v8_pmu>;
+	};
+};
+
+&uart2 {
+	status = "okay";
+};
-- 
2.33.1



From samuel at sholland.org  Sat Jan 29 21:38:02 2022
From: samuel at sholland.org (Samuel Holland)
Date: Sat, 29 Jan 2022 23:38:02 -0600
Subject: [PATCH 2/3] arm64: dts: rockchip: rk356x: Add pdm node
In-Reply-To: <20220130053803.43660-1-samuel@sholland.org>
References: <20220130053803.43660-1-samuel@sholland.org>
Message-ID: <20220130053803.43660-2-samuel@sholland.org>

rk356x contains a PDM microphone controller which is compatible with the
existing rockchip,pdm binding. Add its node.

Signed-off-by: Samuel Holland <samuel at sholland.org>
---

 arch/arm64/boot/dts/rockchip/rk356x.dtsi | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
index a68033a23975..f2f3cdeab0aa 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -651,6 +651,27 @@ &i2s1m0_sdo0   &i2s1m0_sdo1
 		status = "disabled";
 	};
 
+	pdm: pdm at fe440000 {
+		compatible = "rockchip,rk3568-pdm";
+		reg = <0x0 0xfe440000 0x0 0x1000>;
+		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
+		clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>;
+		clock-names = "pdm_clk", "pdm_hclk";
+		dmas = <&dmac1 9>;
+		dma-names = "rx";
+		resets = <&cru SRST_M_PDM>;
+		reset-names = "pdm-m";
+		pinctrl-0 = <&pdmm0_clk
+			     &pdmm0_clk1
+			     &pdmm0_sdi0
+			     &pdmm0_sdi1
+			     &pdmm0_sdi2
+			     &pdmm0_sdi3>;
+		pinctrl-names = "default";
+		#sound-dai-cells = <0>;
+		status = "disabled";
+	};
+
 	dmac0: dmac at fe530000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x0 0xfe530000 0x0 0x4000>;
-- 
2.33.1



From guoren at kernel.org  Sat Jan 29 21:47:16 2022
From: guoren at kernel.org (Guo Ren)
Date: Sun, 30 Jan 2022 13:47:16 +0800
Subject: [PATCH V4 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <CAK8P3a3_kVB78-26sxdsEjb3MMcco6U55tc7siCBFZbJjyH6Sw@mail.gmail.com>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-7-guoren@kernel.org>
 <CAK8P3a3_kVB78-26sxdsEjb3MMcco6U55tc7siCBFZbJjyH6Sw@mail.gmail.com>
Message-ID: <CAJF2gTThb8_-T0iOFVZoJrvZqeFvjfWB+AdFyOwtGhN9aG-MQQ@mail.gmail.com>

On Sun, Jan 30, 2022 at 5:56 AM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Sat, Jan 29, 2022 at 1:17 PM <guoren at kernel.org> wrote:
> > +
> > +#define COMPAT_RLIM_INFINITY   0x7fffffff
> >
> > +#define F_GETLK64      12
> > +#define F_SETLK64      13
> > +#define F_SETLKW64     14
>
> These now come from the generic definitions I think. The flock definitions
> are just the normal ones,
Yes, it could be removed after Christoph Hellwig's patch merged.

> and AFAICT the RLIM_INIFINITY definition here
> is actually wrong and should be the default 0xffffffffu to match the
> native (~0UL) definition.
Yes, native rv32 used ~0UL, although its task_size is only 2.4GB.

I would remove #define COMPAT_RLIM_INFINITY   0x7fffffff

>
>             Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From guoren at kernel.org  Sat Jan 29 21:54:20 2022
From: guoren at kernel.org (Guo Ren)
Date: Sun, 30 Jan 2022 13:54:20 +0800
Subject: [PATCH V4 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAK8P3a3JGP6fLVOyLgdNw2YpRSmArbEX8orUhRrN=GHmcdk=1g@mail.gmail.com>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-9-guoren@kernel.org>
 <CAK8P3a3JGP6fLVOyLgdNw2YpRSmArbEX8orUhRrN=GHmcdk=1g@mail.gmail.com>
Message-ID: <CAJF2gTQQnrUFNQ85vvoMkpxnCWuMw8iXtPZOJwWGaEA9f+rTwA@mail.gmail.com>

On Sun, Jan 30, 2022 at 6:41 AM Arnd Bergmann <arnd at arndb.de> wrote:
>
> > Implement compat sys_call_table and some system call functions:
> > truncate64, ftruncate64, fallocate, pread64, pwrite64,
> > sync_file_range, readahead, fadvise64_64 which need argument
> > translation.
> >
> > Signed-off-by: Guo Ren <guoren at linux.alibaba.com>
> > Signed-off-by: Guo Ren <guoren at kernel.org>
> > Cc: Arnd Bergmann <arnd at arndb.de>
>
> This all looks really good, but I would change one detail:
>
> > +#ifndef compat_arg_u64
> > +#define compat_arg_u64(name)           u32  name##_lo, u32  name##_hi
> > +#define compat_arg_u64_dual(name)      u32, name##_lo, u32, name##_hi
> > +#define compat_arg_u64_glue(name)      (((u64)name##_hi << 32) | \
> > +                                        ((u64)name##_lo & 0xffffffffUL))
> > +#endif
>
> I would make these endian-specific, and reverse them on big-endian
> architectures. That way it
> should be possible to share them across all compat architectures
> without needing the override
> option.
I hope it could be another patch. Because it's not clear to
_LITTLE_ENDIAN definition in archs.

eg: Names could be __ORDER_LITTLE_ENDIAN__ CPU_LITTLE_ENDIAN
SYS_SUPPORTS_LITTLE_ENDIAN __LITTLE_ENDIAN

riscv is little-endian, but no any LITTLE_ENDIAN definition.

So let's keep them in the patch, first, Thx

>
>         Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From alim.akhtar at samsung.com  Sat Jan 29 23:17:17 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 12:47:17 +0530
Subject: [PATCH 1/5] arm64: dts: exynos: align pl330 node name with
 dtschema
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <CGME20220129175341epcas5p480a45065d3d6faee0e405a1efda46a1f@epcas5p4.samsung.com>
 <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <00d601d815a9$6b509890$41f1c9b0$@samsung.com>

Hi Krzysztof

>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Saturday, January 29, 2022 11:23 PM
>To: Lee Jones <lee.jones at linaro.org>; Rob Herring <robh+dt at kernel.org>;
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Alim Akhtar
><alim.akhtar at samsung.com>; Greg Kroah-Hartman
><gregkh at linuxfoundation.org>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; Marek Szyprowski
><m.szyprowski at samsung.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-serial at vger.kernel.org
>Subject: [PATCH 1/5] arm64: dts: exynos: align pl330 node name with
>dtschema
>
>Fixes dtbs_check warnings like:
>
>  pdma at 15610000: $nodename:0: 'pdma at 15610000' does not match '^dma-
>controller(@.*)?$'
>
>Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>---

Reviewed-by: Alim Akhtar <alim.akhtar at smasung.com>


> arch/arm64/boot/dts/exynos/exynos5433.dtsi | 6 +++---
> arch/arm64/boot/dts/exynos/exynos7.dtsi    | 4 ++--
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
>diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>index bfe4ed8a23d6..b4cde77e02d3 100644
>--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>@@ -1858,7 +1858,7 @@ mshc_2: mshc at 15560000 {
> 			status = "disabled";
> 		};
>
>-		pdma0: pdma at 15610000 {
>+		pdma0: dma-controller at 15610000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x15610000 0x1000>;
> 			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
>@@ -1869,7 +1869,7 @@ pdma0: pdma at 15610000 {
> 			#dma-requests = <32>;
> 		};
>
>-		pdma1: pdma at 15600000 {
>+		pdma1: dma-controller at 15600000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x15600000 0x1000>;
> 			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
>@@ -1891,7 +1891,7 @@ audio-subsystem at 11400000 {
> 			#size-cells = <1>;
> 			ranges;
>
>-			adma: adma at 11420000 {
>+			adma: dma-controller at 11420000 {
> 				compatible = "arm,pl330", "arm,primecell";
> 				reg = <0x11420000 0x1000>;
> 				interrupts = <GIC_SPI 73
>IRQ_TYPE_LEVEL_HIGH>; diff --git
>a/arch/arm64/boot/dts/exynos/exynos7.dtsi
>b/arch/arm64/boot/dts/exynos/exynos7.dtsi
>index 960823b8247a..3364b09c3158 100644
>--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
>+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
>@@ -142,7 +142,7 @@ gic: interrupt-controller at 11001000 {
> 				<0x11006000 0x2000>;
> 		};
>
>-		pdma0: pdma at 10e10000 {
>+		pdma0: dma-controller at 10e10000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x10E10000 0x1000>;
> 			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
>@@ -153,7 +153,7 @@ pdma0: pdma at 10e10000 {
> 			#dma-requests = <32>;
> 		};
>
>-		pdma1: pdma at 10eb0000 {
>+		pdma1: dma-controller at 10eb0000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x10EB0000 0x1000>;
> 			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
>--
>2.32.0




From alim.akhtar at samsung.com  Sat Jan 29 23:20:25 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 12:50:25 +0530
Subject: [PATCH 1/5] arm64: dts: exynos: align pl330 node name with
 dtschema
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <CGME20220129175341epcas5p480a45065d3d6faee0e405a1efda46a1f@epcas5p4.samsung.com>
 <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <00d801d815a9$db41f9a0$91c5ece0$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Saturday, January 29, 2022 11:23 PM
>To: Lee Jones <lee.jones at linaro.org>; Rob Herring <robh+dt at kernel.org>;
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Alim Akhtar
><alim.akhtar at samsung.com>; Greg Kroah-Hartman
><gregkh at linuxfoundation.org>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; Marek Szyprowski
><m.szyprowski at samsung.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-serial at vger.kernel.org
>Subject: [PATCH 1/5] arm64: dts: exynos: align pl330 node name with
>dtschema
>
>Fixes dtbs_check warnings like:
>
>  pdma at 15610000: $nodename:0: 'pdma at 15610000' does not match '^dma-
>controller(@.*)?$'
>
>Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>---
Thanks

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>


> arch/arm64/boot/dts/exynos/exynos5433.dtsi | 6 +++---
> arch/arm64/boot/dts/exynos/exynos7.dtsi    | 4 ++--
> 2 files changed, 5 insertions(+), 5 deletions(-)
>
>diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>index bfe4ed8a23d6..b4cde77e02d3 100644
>--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>@@ -1858,7 +1858,7 @@ mshc_2: mshc at 15560000 {
> 			status = "disabled";
> 		};
>
>-		pdma0: pdma at 15610000 {
>+		pdma0: dma-controller at 15610000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x15610000 0x1000>;
> 			interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
>@@ -1869,7 +1869,7 @@ pdma0: pdma at 15610000 {
> 			#dma-requests = <32>;
> 		};
>
>-		pdma1: pdma at 15600000 {
>+		pdma1: dma-controller at 15600000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x15600000 0x1000>;
> 			interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>;
>@@ -1891,7 +1891,7 @@ audio-subsystem at 11400000 {
> 			#size-cells = <1>;
> 			ranges;
>
>-			adma: adma at 11420000 {
>+			adma: dma-controller at 11420000 {
> 				compatible = "arm,pl330", "arm,primecell";
> 				reg = <0x11420000 0x1000>;
> 				interrupts = <GIC_SPI 73
>IRQ_TYPE_LEVEL_HIGH>; diff --git
>a/arch/arm64/boot/dts/exynos/exynos7.dtsi
>b/arch/arm64/boot/dts/exynos/exynos7.dtsi
>index 960823b8247a..3364b09c3158 100644
>--- a/arch/arm64/boot/dts/exynos/exynos7.dtsi
>+++ b/arch/arm64/boot/dts/exynos/exynos7.dtsi
>@@ -142,7 +142,7 @@ gic: interrupt-controller at 11001000 {
> 				<0x11006000 0x2000>;
> 		};
>
>-		pdma0: pdma at 10e10000 {
>+		pdma0: dma-controller at 10e10000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x10E10000 0x1000>;
> 			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
>@@ -153,7 +153,7 @@ pdma0: pdma at 10e10000 {
> 			#dma-requests = <32>;
> 		};
>
>-		pdma1: pdma at 10eb0000 {
>+		pdma1: dma-controller at 10eb0000 {
> 			compatible = "arm,pl330", "arm,primecell";
> 			reg = <0x10EB0000 0x1000>;
> 			interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
>--
>2.32.0




From alim.akhtar at samsung.com  Sat Jan 29 23:34:49 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:04:49 +0530
Subject: [PATCH 2/5] arm64: dts: exynos: drop unneeded syscon phandle in
 Exynos5433 LPASS
In-Reply-To: <20220129175332.298666-2-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <CGME20220129175341epcas5p3a110f6f10b38206e008e2c377a6640d9@epcas5p3.samsung.com>
 <20220129175332.298666-2-krzysztof.kozlowski@canonical.com>
Message-ID: <00d901d815ab$de78a8b0$9b69fa10$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Saturday, January 29, 2022 11:23 PM
>To: Lee Jones <lee.jones at linaro.org>; Rob Herring <robh+dt at kernel.org>;
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Alim Akhtar
><alim.akhtar at samsung.com>; Greg Kroah-Hartman
><gregkh at linuxfoundation.org>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; Marek Szyprowski
><m.szyprowski at samsung.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-serial at vger.kernel.org
>Subject: [PATCH 2/5] arm64: dts: exynos: drop unneeded syscon phandle in
>Exynos5433 LPASS
>
>Exynos5433 LPASS audio node does not use syscon phandle since commit
>addebf1588ab ("mfd: exynos-lpass: Remove pad retention control").  It was
>also dropped from bindings.
>
>Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>---

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>

> arch/arm64/boot/dts/exynos/exynos5433.dtsi | 1 -
> 1 file changed, 1 deletion(-)
>
>diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>index b4cde77e02d3..661567d2dd7a 100644
>--- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>+++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
>@@ -1885,7 +1885,6 @@ audio-subsystem at 11400000 {
> 			reg = <0x11400000 0x100>, <0x11500000 0x08>;
> 			clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>;
> 			clock-names = "sfr0_ctrl";
>-			samsung,pmu-syscon = <&pmu_system_controller>;
> 			power-domains = <&pd_aud>;
> 			#address-cells = <1>;
> 			#size-cells = <1>;
>--
>2.32.0




From alim.akhtar at samsung.com  Sat Jan 29 23:36:54 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:06:54 +0530
Subject: [PATCH 3/5] mfd: exynos-lpass: Drop unneeded syscon.h include
In-Reply-To: <20220129175332.298666-3-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <CGME20220129175342epcas5p19f205a37734553a9f5ddf0d5c4b186f4@epcas5p1.samsung.com>
 <20220129175332.298666-3-krzysztof.kozlowski@canonical.com>
Message-ID: <00da01d815ac$28e89900$7ab9cb00$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Saturday, January 29, 2022 11:24 PM
>To: Lee Jones <lee.jones at linaro.org>; Rob Herring <robh+dt at kernel.org>;
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Alim Akhtar
><alim.akhtar at samsung.com>; Greg Kroah-Hartman
><gregkh at linuxfoundation.org>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; Marek Szyprowski
><m.szyprowski at samsung.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-serial at vger.kernel.org
>Subject: [PATCH 3/5] mfd: exynos-lpass: Drop unneeded syscon.h include
>
>syscon regmap is not used since commit addebf1588ab ("mfd: exynos-lpass:
>Remove pad retention control").
>
>Fixes: addebf1588ab ("mfd: exynos-lpass: Remove pad retention control")
>Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>---

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>


> drivers/mfd/exynos-lpass.c | 1 -
> 1 file changed, 1 deletion(-)
>
>diff --git a/drivers/mfd/exynos-lpass.c b/drivers/mfd/exynos-lpass.c index
>99bd0e73c19c..166cd21088cd 100644
>--- a/drivers/mfd/exynos-lpass.c
>+++ b/drivers/mfd/exynos-lpass.c
>@@ -15,7 +15,6 @@
> #include <linux/delay.h>
> #include <linux/io.h>
> #include <linux/module.h>
>-#include <linux/mfd/syscon.h>
> #include <linux/of.h>
> #include <linux/of_platform.h>
> #include <linux/platform_device.h>
>--
>2.32.0




From alim.akhtar at samsung.com  Sat Jan 29 23:39:03 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:09:03 +0530
Subject: [PATCH 5/5] dt-bindings: serial: samsung_uart: Document
 Exynos5433 compatible
In-Reply-To: <20220129175332.298666-5-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <CGME20220129175345epcas5p37b7f9b667292af3d085580696fe86c10@epcas5p3.samsung.com>
 <20220129175332.298666-5-krzysztof.kozlowski@canonical.com>
Message-ID: <00db01d815ac$77248570$656d9050$@samsung.com>



>-----Original Message-----
>From: Krzysztof Kozlowski [mailto:krzysztof.kozlowski at canonical.com]
>Sent: Saturday, January 29, 2022 11:24 PM
>To: Lee Jones <lee.jones at linaro.org>; Rob Herring <robh+dt at kernel.org>;
>Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>; Alim Akhtar
><alim.akhtar at samsung.com>; Greg Kroah-Hartman
><gregkh at linuxfoundation.org>; Sylwester Nawrocki
><s.nawrocki at samsung.com>; Marek Szyprowski
><m.szyprowski at samsung.com>; devicetree at vger.kernel.org; linux-arm-
>kernel at lists.infradead.org; linux-samsung-soc at vger.kernel.org; linux-
>kernel at vger.kernel.org; linux-serial at vger.kernel.org
>Subject: [PATCH 5/5] dt-bindings: serial: samsung_uart: Document
>Exynos5433 compatible
>
>Document the Exynos5433 UART compatible, supported since commit
>31ec77aca72e ("serial: samsung: Add the support for Exynos5433 SoC").
>
>Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>---
Thanks

Reviewed-by: Alim Akhtar <alim.akhtar at samsung.com>


> Documentation/devicetree/bindings/serial/samsung_uart.yaml | 2 ++
> 1 file changed, 2 insertions(+)
>
>diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
>b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
>index 2940afb874b3..6aceba4a5f79 100644
>--- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml
>+++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml
>@@ -26,6 +26,7 @@ properties:
>           - samsung,s3c6400-uart
>           - samsung,s5pv210-uart
>           - samsung,exynos4210-uart
>+          - samsung,exynos5433-uart
>           - samsung,exynos850-uart
>
>   reg:
>@@ -111,6 +112,7 @@ allOf:
>             enum:
>               - apple,s5l-uart
>               - samsung,exynos4210-uart
>+              - samsung,exynos5433-uart
>     then:
>       properties:
>         clocks:
>--
>2.32.0




From alim.akhtar at samsung.com  Sat Jan 29 23:55:18 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:25:18 +0530
Subject: [PATCH 1/3] ARM: dts: exynos: update dma nodename for exynos3250
References: <CGME20220130080810epcas5p425f29e7a017b4b1690509e60651d4245@epcas5p4.samsung.com>
Message-ID: <20220130075520.49193-1-alim.akhtar@samsung.com>

Currently dma node name does not matches the pl330
dt schema and make dtbs_check report below warning

'pdma at 12680000' does not match '^dma-controller(@.*)?$'

Update the dma node name to match pl330 dt schema

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos3250.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/exynos3250.dtsi b/arch/arm/boot/dts/exynos3250.dtsi
index a10b789d8acf..ae644315855d 100644
--- a/arch/arm/boot/dts/exynos3250.dtsi
+++ b/arch/arm/boot/dts/exynos3250.dtsi
@@ -421,7 +421,7 @@ exynos_usbphy: exynos-usbphy at 125b0000 {
 			status = "disabled";
 		};
 
-		pdma0: pdma at 12680000 {
+		pdma0: dma-controller at 12680000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x12680000 0x1000>;
 			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
@@ -432,7 +432,7 @@ pdma0: pdma at 12680000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 12690000 {
+		pdma1: dma-controller at 12690000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x12690000 0x1000>;
 			interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From alim.akhtar at samsung.com  Sat Jan 29 23:55:19 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:25:19 +0530
Subject: [PATCH 2/3] ARM: dts: exynos: update dma nodename for exynos4
In-Reply-To: <20220130075520.49193-1-alim.akhtar@samsung.com>
References: <20220130075520.49193-1-alim.akhtar@samsung.com>
 <CGME20220130080815epcas5p33462c816b7ca206bf1ce498cb04f7686@epcas5p3.samsung.com>
Message-ID: <20220130075520.49193-2-alim.akhtar@samsung.com>

Currently dma node name does not matches the pl330
dt schema and make dtbs_check report below warning

'mdma at 12850000' does not match '^dma-controller(@.*)?$'

Update the dma node name to match pl330 dt schema

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos4.dtsi                  | 6 +++---
 arch/arm/boot/dts/exynos4210-universal_c210.dts | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index eab77a66ae8f..e81b3ee4e0f7 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -669,7 +669,7 @@ pwm: pwm at 139d0000 {
 			status = "disabled";
 		};
 
-		pdma0: pdma at 12680000 {
+		pdma0: dma-controller at 12680000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x12680000 0x1000>;
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -680,7 +680,7 @@ pdma0: pdma at 12680000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 12690000 {
+		pdma1: dma-controller at 12690000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x12690000 0x1000>;
 			interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
@@ -691,7 +691,7 @@ pdma1: pdma at 12690000 {
 			#dma-requests = <32>;
 		};
 
-		mdma1: mdma at 12850000 {
+		mdma1: dma-controller at 12850000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x12850000 0x1000>;
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 170d54a0bb5c..138d606d58a5 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -659,7 +659,7 @@ &serial_3 {
 };
 
 &soc {
-	mdma0: mdma at 12840000 {
+	mdma0: dma-controller at 12840000 {
 		compatible = "arm,pl330", "arm,primecell";
 		reg = <0x12840000 0x1000>;
 		interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From alim.akhtar at samsung.com  Sat Jan 29 23:55:20 2022
From: alim.akhtar at samsung.com (Alim Akhtar)
Date: Sun, 30 Jan 2022 13:25:20 +0530
Subject: [PATCH 3/3] ARM: dts: exynos: update dma nodename for exynos5
In-Reply-To: <20220130075520.49193-1-alim.akhtar@samsung.com>
References: <20220130075520.49193-1-alim.akhtar@samsung.com>
 <CGME20220130080818epcas5p15adb431d08cb37060310fec00bb77cd2@epcas5p1.samsung.com>
Message-ID: <20220130075520.49193-3-alim.akhtar@samsung.com>

Currently dma node name does not matches the pl330
dt schema and make dtbs_check report below warning

'pdma at 121a0000' does not match '^dma-controller(@.*)?$'
'mdma at 10800000' does not match '^dma-controller(@.*)?$'

Update the dma node name to match pl330 dt schema

Signed-off-by: Alim Akhtar <alim.akhtar at samsung.com>
---
 arch/arm/boot/dts/exynos5250.dtsi |  8 ++++----
 arch/arm/boot/dts/exynos5410.dtsi |  4 ++--
 arch/arm/boot/dts/exynos5420.dtsi | 10 +++++-----
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index c6080bb75a62..5baaa7eb71a4 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -692,7 +692,7 @@ usb2_phy_gen: phy at 12130000 {
 			samsung,pmureg-phandle = <&pmu_system_controller>;
 		};
 
-		pdma0: pdma at 121a0000 {
+		pdma0: dma-controller at 121a0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121A0000 0x1000>;
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -703,7 +703,7 @@ pdma0: pdma at 121a0000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 121b0000 {
+		pdma1: dma-controller at 121b0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121B0000 0x1000>;
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -714,7 +714,7 @@ pdma1: pdma at 121b0000 {
 			#dma-requests = <32>;
 		};
 
-		mdma0: mdma at 10800000 {
+		mdma0: dma-controller at 10800000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x10800000 0x1000>;
 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
@@ -725,7 +725,7 @@ mdma0: mdma at 10800000 {
 			#dma-requests = <1>;
 		};
 
-		mdma1: mdma at 11c10000 {
+		mdma1: dma-controller at 11c10000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x11C10000 0x1000>;
 			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos5410.dtsi b/arch/arm/boot/dts/exynos5410.dtsi
index 584ce62361b1..4d797a9abba4 100644
--- a/arch/arm/boot/dts/exynos5410.dtsi
+++ b/arch/arm/boot/dts/exynos5410.dtsi
@@ -189,7 +189,7 @@ pinctrl_3: pinctrl at 3860000 {
 			interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		pdma0: pdma at 121a0000 {
+		pdma0: dma-controller at 121a0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121a0000 0x1000>;
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -200,7 +200,7 @@ pdma0: pdma at 121a0000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 121b0000 {
+		pdma1: dma-controller at 121b0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121b0000 0x1000>;
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index e23e8ffb093f..29e33cda14c4 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -430,7 +430,7 @@ pinctrl_4: pinctrl at 3860000 {
 			power-domains = <&mau_pd>;
 		};
 
-		adma: adma at 3880000 {
+		adma: dma-controller at 3880000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x03880000 0x1000>;
 			interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
@@ -442,7 +442,7 @@ adma: adma at 3880000 {
 			power-domains = <&mau_pd>;
 		};
 
-		pdma0: pdma at 121a0000 {
+		pdma0: dma-controller at 121a0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121A0000 0x1000>;
 			interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
@@ -453,7 +453,7 @@ pdma0: pdma at 121a0000 {
 			#dma-requests = <32>;
 		};
 
-		pdma1: pdma at 121b0000 {
+		pdma1: dma-controller at 121b0000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x121B0000 0x1000>;
 			interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
@@ -464,7 +464,7 @@ pdma1: pdma at 121b0000 {
 			#dma-requests = <32>;
 		};
 
-		mdma0: mdma at 10800000 {
+		mdma0: dma-controller at 10800000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x10800000 0x1000>;
 			interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
@@ -475,7 +475,7 @@ mdma0: mdma at 10800000 {
 			#dma-requests = <1>;
 		};
 
-		mdma1: mdma at 11c10000 {
+		mdma1: dma-controller at 11c10000 {
 			compatible = "arm,pl330", "arm,primecell";
 			reg = <0x11C10000 0x1000>;
 			interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-- 
2.25.1



From hotforest at gmail.com  Sun Jan 30 01:29:14 2022
From: hotforest at gmail.com (Hou Tao)
Date: Sun, 30 Jan 2022 17:29:14 +0800
Subject: [PATCH bpf-next v3 0/3] bpf, arm64: enable kfunc call
Message-ID: <20220130092917.14544-1-hotforest@gmail.com>

Hi,

The simple patchset tries to enable kfunc call for arm64. Patch #1 just
overrides bpf_jit_supports_kfunc_call() to enable kfunc call, patch #2
unexports the subtests in ksyms_module.c to fix the confusion in test
output and patch #3 add a test in ksyms_module.c to ensure s32 is
sufficient for kfunc offset.

Change Log:
v3:
  * patch #2: newly-addded to unexport unnecessary subtests
  * patch #3: use kallsyms_find() instead of reimplementing it.
  * patch #3: ensure kfunc call is supported before checking
              whether s32 will be overflowed or not.

v2: https://lore.kernel.org/bpf/20220127071532.384888-1-houtao1 at huawei.com/
  * add a test to check whether imm will be overflowed for kfunc call

v1: https://lore.kernel.org/bpf/20220119144942.305568-1-houtao1 at huawei.com

Hou Tao (3):
  bpf, arm64: enable kfunc call
  selftests/bpf: do not export subtest as standalone test
  selftests/bpf: check whether s32 is sufficient for kfunc offset

 arch/arm64/net/bpf_jit_comp.c                 |  5 ++
 .../selftests/bpf/prog_tests/ksyms_module.c   | 46 ++++++++++++++++++-
 .../bpf/prog_tests/xdp_adjust_frags.c         |  6 ---
 .../bpf/prog_tests/xdp_adjust_tail.c          |  4 +-
 .../bpf/prog_tests/xdp_cpumap_attach.c        |  4 +-
 .../bpf/prog_tests/xdp_devmap_attach.c        |  2 +-
 6 files changed, 54 insertions(+), 13 deletions(-)

-- 
2.20.1



From hotforest at gmail.com  Sun Jan 30 01:29:15 2022
From: hotforest at gmail.com (Hou Tao)
Date: Sun, 30 Jan 2022 17:29:15 +0800
Subject: [PATCH bpf-next v3 1/3] bpf, arm64: enable kfunc call
In-Reply-To: <20220130092917.14544-1-hotforest@gmail.com>
References: <20220130092917.14544-1-hotforest@gmail.com>
Message-ID: <20220130092917.14544-2-hotforest@gmail.com>

From: Hou Tao <houtao1 at huawei.com>

Since commit b2eed9b58811 ("arm64/kernel: kaslr: reduce module
randomization range to 2 GB"), for arm64 whether KASLR is enabled
or not, the module is placed within 2GB of the kernel region, so
s32 in bpf_kfunc_desc is sufficient to represente the offset of
module function relative to __bpf_call_base. The only thing needed
is to override bpf_jit_supports_kfunc_call().

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 arch/arm64/net/bpf_jit_comp.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index e96d4d87291f..74f9a9b6a053 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -1143,6 +1143,11 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	return prog;
 }
 
+bool bpf_jit_supports_kfunc_call(void)
+{
+	return true;
+}
+
 u64 bpf_jit_alloc_exec_limit(void)
 {
 	return VMALLOC_END - VMALLOC_START;
-- 
2.20.1



From hotforest at gmail.com  Sun Jan 30 01:29:16 2022
From: hotforest at gmail.com (Hou Tao)
Date: Sun, 30 Jan 2022 17:29:16 +0800
Subject: [PATCH bpf-next v3 2/3] selftests/bpf: do not export subtest as
 standalone test
In-Reply-To: <20220130092917.14544-1-hotforest@gmail.com>
References: <20220130092917.14544-1-hotforest@gmail.com>
Message-ID: <20220130092917.14544-3-hotforest@gmail.com>

Two subtests in ksyms_module.c are not qualified as static, so these
subtests are exported as standalone tests in tests.h and lead to
confusion for the output of "./test_progs -t ksyms_module".

By using the following command:

  grep "^void \(serial_\)\?test_[a-zA-Z0-9_]\+(\(void\)\?)" \
      tools/testing/selftests/bpf/prog_tests/*.c | \
	awk -F : '{print $1}' | sort | uniq -c | awk '$1 != 1'

Find out that other tests also have the similar problem, so fix
these tests by marking subtests in these tests as static. For
xdp_adjust_frags.c, there is just one subtest, so just export
the subtest directly.

Signed-off-by: Hou Tao <hotforest at gmail.com>
---
 tools/testing/selftests/bpf/prog_tests/ksyms_module.c      | 4 ++--
 tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c  | 6 ------
 tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c   | 4 ++--
 tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c | 4 ++--
 tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c | 2 +-
 5 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
index d490ad80eccb..997aa90dea64 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
@@ -6,7 +6,7 @@
 #include "test_ksyms_module.lskel.h"
 #include "test_ksyms_module.skel.h"
 
-void test_ksyms_module_lskel(void)
+static void test_ksyms_module_lskel(void)
 {
 	struct test_ksyms_module_lskel *skel;
 	int retval;
@@ -30,7 +30,7 @@ void test_ksyms_module_lskel(void)
 	test_ksyms_module_lskel__destroy(skel);
 }
 
-void test_ksyms_module_libbpf(void)
+static void test_ksyms_module_libbpf(void)
 {
 	struct test_ksyms_module *skel;
 	int retval, err;
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c
index 31c188666e81..6ca3582bb056 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_frags.c
@@ -96,9 +96,3 @@ void test_xdp_update_frags(void)
 out:
 	bpf_object__close(obj);
 }
-
-void test_xdp_adjust_frags(void)
-{
-	if (test__start_subtest("xdp_adjust_frags"))
-		test_xdp_update_frags();
-}
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
index ccc9e63254a8..a254c54c3ada 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c
@@ -118,7 +118,7 @@ static void test_xdp_adjust_tail_grow2(void)
 	bpf_object__close(obj);
 }
 
-void test_xdp_adjust_frags_tail_shrink(void)
+static void test_xdp_adjust_frags_tail_shrink(void)
 {
 	const char *file = "./test_xdp_adjust_tail_shrink.o";
 	__u32 duration, retval, size, exp_size;
@@ -180,7 +180,7 @@ void test_xdp_adjust_frags_tail_shrink(void)
 	bpf_object__close(obj);
 }
 
-void test_xdp_adjust_frags_tail_grow(void)
+static void test_xdp_adjust_frags_tail_grow(void)
 {
 	const char *file = "./test_xdp_adjust_tail_grow.o";
 	__u32 duration, retval, size, exp_size;
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c b/tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c
index 13aabb3b6cf2..15e48098c8b8 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_cpumap_attach.c
@@ -8,7 +8,7 @@
 
 #define IFINDEX_LO	1
 
-void test_xdp_with_cpumap_helpers(void)
+static void test_xdp_with_cpumap_helpers(void)
 {
 	struct test_xdp_with_cpumap_helpers *skel;
 	struct bpf_prog_info info = {};
@@ -68,7 +68,7 @@ void test_xdp_with_cpumap_helpers(void)
 	test_xdp_with_cpumap_helpers__destroy(skel);
 }
 
-void test_xdp_with_cpumap_frags_helpers(void)
+static void test_xdp_with_cpumap_frags_helpers(void)
 {
 	struct test_xdp_with_cpumap_frags_helpers *skel;
 	struct bpf_prog_info info = {};
diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c b/tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
index 2a784ccd3136..08d074ec471d 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_devmap_attach.c
@@ -81,7 +81,7 @@ static void test_neg_xdp_devmap_helpers(void)
 	}
 }
 
-void test_xdp_with_devmap_frags_helpers(void)
+static void test_xdp_with_devmap_frags_helpers(void)
 {
 	struct test_xdp_with_devmap_frags_helpers *skel;
 	struct bpf_prog_info info = {};
-- 
2.20.1



From hotforest at gmail.com  Sun Jan 30 01:29:17 2022
From: hotforest at gmail.com (Hou Tao)
Date: Sun, 30 Jan 2022 17:29:17 +0800
Subject: [PATCH bpf-next v3 3/3] selftests/bpf: check whether s32 is
 sufficient for kfunc offset
In-Reply-To: <20220130092917.14544-1-hotforest@gmail.com>
References: <20220130092917.14544-1-hotforest@gmail.com>
Message-ID: <20220130092917.14544-4-hotforest@gmail.com>

From: Hou Tao <houtao1 at huawei.com>

In add_kfunc_call(), bpf_kfunc_desc->imm with type s32 is used to
represent the offset of called kfunc from __bpf_call_base, so
add a test to ensure that the offset will not be overflowed.

Signed-off-by: Hou Tao <houtao1 at huawei.com>
---
 .../selftests/bpf/prog_tests/ksyms_module.c   | 42 +++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
index 997aa90dea64..955a9ede4756 100644
--- a/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
+++ b/tools/testing/selftests/bpf/prog_tests/ksyms_module.c
@@ -3,9 +3,49 @@
 
 #include <test_progs.h>
 #include <network_helpers.h>
+#include <trace_helpers.h>
 #include "test_ksyms_module.lskel.h"
 #include "test_ksyms_module.skel.h"
 
+/*
+ * Check whether or not s32 in bpf_kfunc_desc is sufficient
+ * to represent the offset between bpf_testmod_test_mod_kfunc
+ * and __bpf_call_base.
+ */
+static void test_ksyms_module_valid_offset(void)
+{
+	struct test_ksyms_module *skel;
+	unsigned long long kfunc_addr;
+	unsigned long long base_addr;
+	long long actual_offset;
+	int used_offset;
+	int err;
+
+	if (!env.has_testmod) {
+		test__skip();
+		return;
+	}
+
+	/* Ensure kfunc call is supported */
+	skel = test_ksyms_module__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "test_ksyms_module__open"))
+		return;
+
+	err = kallsyms_find("bpf_testmod_test_mod_kfunc", &kfunc_addr);
+	if (!ASSERT_OK(err, "find kfunc addr"))
+		goto cleanup;
+
+	err = kallsyms_find("__bpf_call_base", &base_addr);
+	if (!ASSERT_OK(err, "find base addr"))
+		goto cleanup;
+
+	used_offset = kfunc_addr - base_addr;
+	actual_offset = kfunc_addr - base_addr;
+	ASSERT_EQ((long long)used_offset, actual_offset, "kfunc offset overflowed");
+cleanup:
+	test_ksyms_module__destroy(skel);
+}
+
 static void test_ksyms_module_lskel(void)
 {
 	struct test_ksyms_module_lskel *skel;
@@ -55,6 +95,8 @@ static void test_ksyms_module_libbpf(void)
 
 void test_ksyms_module(void)
 {
+	if (test__start_subtest("valid_offset"))
+		test_ksyms_module_valid_offset();
 	if (test__start_subtest("lskel"))
 		test_ksyms_module_lskel();
 	if (test__start_subtest("libbpf"))
-- 
2.20.1



From lkp at intel.com  Sun Jan 30 01:46:34 2022
From: lkp at intel.com (kernel test robot)
Date: Sun, 30 Jan 2022 17:46:34 +0800
Subject: [linusw-nomadik:ixp4xx-cleanup-v5.17-rc1] BUILD SUCCESS
 f631d4816f6cd4a83d522c69b18091c93cf4f064
Message-ID: <61f65e7a.QsFQsccmF7PWiH98%lkp@intel.com>

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git ixp4xx-cleanup-v5.17-rc1
branch HEAD: f631d4816f6cd4a83d522c69b18091c93cf4f064  clocksource/drivers/ixp4xx: Drop boardfile probe path

elapsed time: 720m

configs tested: 129
configs skipped: 3

The following configs have been built successfully.
More configs may be tested in the coming days.

gcc tested configs:
arm                                 defconfig
arm64                            allyesconfig
arm64                               defconfig
arm                              allyesconfig
arm                              allmodconfig
i386                          randconfig-c001
m68k                             allmodconfig
powerpc                          allmodconfig
m68k                             allyesconfig
powerpc                          allyesconfig
s390                             allmodconfig
s390                             allyesconfig
sh                  sh7785lcr_32bit_defconfig
arm                           sunxi_defconfig
powerpc                 mpc8540_ads_defconfig
m68k                          amiga_defconfig
arm                           u8500_defconfig
sparc64                             defconfig
powerpc                        cell_defconfig
sh                                  defconfig
sh                          r7785rp_defconfig
powerpc                      bamboo_defconfig
mips                        jmr3927_defconfig
arm                             rpc_defconfig
arm                             ezx_defconfig
powerpc                  iss476-smp_defconfig
arm                         s3c6400_defconfig
powerpc                      arches_defconfig
mips                       capcella_defconfig
arm                         lubbock_defconfig
arc                    vdk_hs38_smp_defconfig
m68k                         amcore_defconfig
nds32                               defconfig
nds32                             allnoconfig
arm                        spear6xx_defconfig
m68k                                defconfig
powerpc                     tqm8541_defconfig
xtensa                           alldefconfig
powerpc                    adder875_defconfig
powerpc                       eiger_defconfig
mips                 decstation_r4k_defconfig
powerpc                      pcm030_defconfig
sh                               allmodconfig
mips                         tb0226_defconfig
sh                        edosk7705_defconfig
powerpc                 mpc837x_rdb_defconfig
sh                          rsk7264_defconfig
sh                             espt_defconfig
sh                           se7712_defconfig
i386                                defconfig
arm                  randconfig-c002-20220130
ia64                             allmodconfig
ia64                             allyesconfig
ia64                                defconfig
alpha                               defconfig
alpha                            allyesconfig
csky                                defconfig
nios2                            allyesconfig
nios2                               defconfig
arc                              allyesconfig
xtensa                           allyesconfig
h8300                            allyesconfig
arc                                 defconfig
parisc                              defconfig
parisc                           allyesconfig
s390                                defconfig
i386                             allyesconfig
sparc                            allyesconfig
sparc                               defconfig
i386                   debian-10.3-kselftests
i386                              debian-10.3
mips                             allyesconfig
mips                             allmodconfig
powerpc                           allnoconfig
x86_64                        randconfig-a004
x86_64                        randconfig-a002
x86_64                        randconfig-a006
i386                          randconfig-a003
i386                          randconfig-a001
i386                          randconfig-a005
i386                          randconfig-a012
i386                          randconfig-a014
i386                          randconfig-a016
riscv                randconfig-r042-20220130
arc                  randconfig-r043-20220130
s390                 randconfig-r044-20220130
riscv                    nommu_k210_defconfig
riscv                            allyesconfig
riscv                    nommu_virt_defconfig
riscv                             allnoconfig
riscv                               defconfig
riscv                          rv32_defconfig
riscv                            allmodconfig
x86_64                    rhel-8.3-kselftests
um                             i386_defconfig
um                           x86_64_defconfig
x86_64                           allyesconfig
x86_64                              defconfig
x86_64                               rhel-8.3
x86_64                          rhel-8.3-func
x86_64                                  kexec

clang tested configs:
riscv                randconfig-c006-20220130
x86_64                        randconfig-c007
arm                  randconfig-c002-20220130
powerpc              randconfig-c003-20220130
mips                 randconfig-c004-20220130
i386                          randconfig-c001
s390                 randconfig-c005-20220130
mips                         tb0287_defconfig
mips                           ip28_defconfig
powerpc                 mpc836x_mds_defconfig
arm                        vexpress_defconfig
mips                  cavium_octeon_defconfig
hexagon                             defconfig
arm                  colibri_pxa300_defconfig
arm                       imx_v4_v5_defconfig
arm                           omap1_defconfig
x86_64                        randconfig-a005
x86_64                        randconfig-a003
x86_64                        randconfig-a001
i386                          randconfig-a002
i386                          randconfig-a004
i386                          randconfig-a006
x86_64                        randconfig-a012
x86_64                        randconfig-a014
x86_64                        randconfig-a016
i386                          randconfig-a011
i386                          randconfig-a013
i386                          randconfig-a015
hexagon              randconfig-r045-20220130
hexagon              randconfig-r041-20220130

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From michael.riesch at wolfvision.net  Sun Jan 30 01:49:54 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Sun, 30 Jan 2022 10:49:54 +0100
Subject: [PATCH 2/3] arm64: dts: rockchip: rk356x: Add pdm node
In-Reply-To: <20220130053803.43660-2-samuel@sholland.org>
References: <20220130053803.43660-1-samuel@sholland.org>
 <20220130053803.43660-2-samuel@sholland.org>
Message-ID: <0fe601eb-2993-79a5-bb45-6eafc7f9d0ba@wolfvision.net>

Hello Samuel,

On 1/30/22 06:38, Samuel Holland wrote:
> rk356x contains a PDM microphone controller which is compatible with the
> existing rockchip,pdm binding. Add its node.
> 
> Signed-off-by: Samuel Holland <samuel at sholland.org>
> ---
> 
>  arch/arm64/boot/dts/rockchip/rk356x.dtsi | 21 +++++++++++++++++++++
>  1 file changed, 21 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x.dtsi b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> index a68033a23975..f2f3cdeab0aa 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi
> @@ -651,6 +651,27 @@ &i2s1m0_sdo0   &i2s1m0_sdo1
>  		status = "disabled";
>  	};
>  
> +	pdm: pdm at fe440000 {
> +		compatible = "rockchip,rk3568-pdm";
> +		reg = <0x0 0xfe440000 0x0 0x1000>;
> +		interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
> +		clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>;
> +		clock-names = "pdm_clk", "pdm_hclk";
> +		dmas = <&dmac1 9>;
> +		dma-names = "rx";
> +		resets = <&cru SRST_M_PDM>;
> +		reset-names = "pdm-m";
> +		pinctrl-0 = <&pdmm0_clk
> +			     &pdmm0_clk1
> +			     &pdmm0_sdi0
> +			     &pdmm0_sdi1
> +			     &pdmm0_sdi2
> +			     &pdmm0_sdi3>;
> +		pinctrl-names = "default";

I think the pinctrl properties should go before the reset properties.

Apart from that this patch looks good to me.

Best regards,
Michael

> +		#sound-dai-cells = <0>;
> +		status = "disabled";
> +	};
> +
>  	dmac0: dmac at fe530000 {
>  		compatible = "arm,pl330", "arm,primecell";
>  		reg = <0x0 0xfe530000 0x0 0x4000>;


From michael.riesch at wolfvision.net  Sun Jan 30 01:56:08 2022
From: michael.riesch at wolfvision.net (Michael Riesch)
Date: Sun, 30 Jan 2022 10:56:08 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <3736463.EBuT6JFcjP@diego>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
 <FBB7C392-C5E0-4E34-AC17-5323414623F5@gmail.com>
 <64f539b5-30b2-c0b7-17bf-c448b507713e@wolfvision.net>
 <3736463.EBuT6JFcjP@diego>
Message-ID: <d203569c-bae1-c35a-204a-53617170d3b3@wolfvision.net>

Hello Heiko,

On 1/29/22 16:28, Heiko St?bner wrote:
> Am Samstag, 29. Januar 2022, 10:59:32 CET schrieb Michael Riesch:
>> Hello Peter and Piotr,
>>
>> On 1/29/22 10:23, Piotr Oniszczuk wrote:
>>>
>>>
>>>>
>>>> Good Evening,
>>>>
>>>> While I'm not against this idea, my main concern still stands.
>>>> I spent a great deal of thought on this, and decided to go the route I
>>>> did to maintain consistency with previous generations.
>>>> As such, I see one of three paths here:
>>>> - Pull this patch only and depart rk356x from previous SoCs.
>>>> - Do the same for previous SoCs to maintain consistency.
>>>> - Drop this patch to maintain consistency with previous SoCs.
>>>>
>>>> I ask that others weigh in here, as offline discussion has produced
>>>> mixed results already.
>>>
>>> just pure user perspective
>>>
>>> (who spent last weeks considerable time to develop DT for rk3566 tvbox. 99% of my work was by reading/learning from other boards existing DT's. Any inconsistencies in DTs makes work for such ppl like me much more harder):
>>>
>>> For option 1 - i don't see value
>>> For option 2 - what is reward for extra work needs to be done on all other SoCs?
>>>
>>> so option 3 seems to be natural choice...
>>>
>>> in other words:
>>>
>>> for me:
>>> option 1 brings practically zero value + increased inconsistency.
>>> option 2: extra work - but consistency is like in option 3 (so where is value?)
>>>
>>> so option 3 offers the same consistency - but without extra work...
>>>  
>>> just my 0.02$
>>
>> Of course this change is purely cosmetic and it is reasonable to ask for
>> the practical value. It is just that technically the quartz64 dts is not
>> sorted alphabetically at the moment. The u2phy* nodes should be but
>> before the uart* nodes to follow the convention. On the other hand, it
>> may be nice to have the usb2 phys and controllers grouped in the dts.
>> The proposed renaming would allow all the mentioned nodes sorted
>> alphabetically and grouped logically.
>>
>> Therefore I had option 1 in mind. I don't see any dependencies between
>> the different SoCs and think we can make a fresh start here.
> 
> correct :-) .
> 
> I do see each SoC individually and while I try to have people follow some
> styling guidelines everywhere (ordering of properties, ordering of nodes)
> I don't really want people to fear what some other SoC has done before.
> 
> But even these rules evolve sometimes, when something seems to work
> better than before.
> 
> We have nowadays 9 years of Rockchip SoC history in the kernel.
> Thanks to general dt-binding conventions most nodes have specific
> names anyway (mmc at ... etc), but for example trying to rename stuff
> in older SoCs that has worked for years now is for one error-prone
> as Michael pointed out, but also introduces unnecessary churn,
> when these old SoCs (thinking of rk3188, rk3288 and friends but also things
> like the rk3368) are essentially "finished" and most likely won't see that
> much additional support for stuff added.

So... may I take it that you are going to apply the patches in this series?

Or should I switch to option 3 and re-submit?

Thanks and best regards,
Michael

> 
> 
> Heiko
> 
> 
>> Option 2 is not really feasible, we would almost definitely break
>> something existent.
>>
>> Option 3 is feasible, of course. However, I would sort the nodes
>> alphabetically (u2phy*, then uart*, then usb*). Works for me as well,
>> although it is not that nice IMHO.
>>
>> Since many boards with the RK3566 and RK3568 will pop up in near future
>> we should do the change right now (if we want to do it), as of course
>> all the board files need to be changed. Therefore I wanted to bring this
>> matter up now. Let's agree on something and move on.
>>
>> Best regards,
>> Michael
>>
> 
> 
> 
> 


From heiko at sntech.de  Sun Jan 30 03:02:16 2022
From: heiko at sntech.de (Heiko =?ISO-8859-1?Q?St=FCbner?=)
Date: Sun, 30 Jan 2022 12:02:16 +0100
Subject: [PATCH 1/2] arm64: dts: rockchip: rename and sort the rk356x usb2
 phy handles
In-Reply-To: <d203569c-bae1-c35a-204a-53617170d3b3@wolfvision.net>
References: <20220127190456.2195527-1-michael.riesch@wolfvision.net>
 <3736463.EBuT6JFcjP@diego>
 <d203569c-bae1-c35a-204a-53617170d3b3@wolfvision.net>
Message-ID: <14752572.ChuAC8jng2@diego>

Am Sonntag, 30. Januar 2022, 10:56:08 CET schrieb Michael Riesch:
> Hello Heiko,
> 
> On 1/29/22 16:28, Heiko St?bner wrote:
> > Am Samstag, 29. Januar 2022, 10:59:32 CET schrieb Michael Riesch:
> >> Hello Peter and Piotr,
> >>
> >> On 1/29/22 10:23, Piotr Oniszczuk wrote:
> >>>
> >>>
> >>>>
> >>>> Good Evening,
> >>>>
> >>>> While I'm not against this idea, my main concern still stands.
> >>>> I spent a great deal of thought on this, and decided to go the route I
> >>>> did to maintain consistency with previous generations.
> >>>> As such, I see one of three paths here:
> >>>> - Pull this patch only and depart rk356x from previous SoCs.
> >>>> - Do the same for previous SoCs to maintain consistency.
> >>>> - Drop this patch to maintain consistency with previous SoCs.
> >>>>
> >>>> I ask that others weigh in here, as offline discussion has produced
> >>>> mixed results already.
> >>>
> >>> just pure user perspective
> >>>
> >>> (who spent last weeks considerable time to develop DT for rk3566 tvbox. 99% of my work was by reading/learning from other boards existing DT's. Any inconsistencies in DTs makes work for such ppl like me much more harder):
> >>>
> >>> For option 1 - i don't see value
> >>> For option 2 - what is reward for extra work needs to be done on all other SoCs?
> >>>
> >>> so option 3 seems to be natural choice...
> >>>
> >>> in other words:
> >>>
> >>> for me:
> >>> option 1 brings practically zero value + increased inconsistency.
> >>> option 2: extra work - but consistency is like in option 3 (so where is value?)
> >>>
> >>> so option 3 offers the same consistency - but without extra work...
> >>>  
> >>> just my 0.02$
> >>
> >> Of course this change is purely cosmetic and it is reasonable to ask for
> >> the practical value. It is just that technically the quartz64 dts is not
> >> sorted alphabetically at the moment. The u2phy* nodes should be but
> >> before the uart* nodes to follow the convention. On the other hand, it
> >> may be nice to have the usb2 phys and controllers grouped in the dts.
> >> The proposed renaming would allow all the mentioned nodes sorted
> >> alphabetically and grouped logically.
> >>
> >> Therefore I had option 1 in mind. I don't see any dependencies between
> >> the different SoCs and think we can make a fresh start here.
> > 
> > correct :-) .
> > 
> > I do see each SoC individually and while I try to have people follow some
> > styling guidelines everywhere (ordering of properties, ordering of nodes)
> > I don't really want people to fear what some other SoC has done before.
> > 
> > But even these rules evolve sometimes, when something seems to work
> > better than before.
> > 
> > We have nowadays 9 years of Rockchip SoC history in the kernel.
> > Thanks to general dt-binding conventions most nodes have specific
> > names anyway (mmc at ... etc), but for example trying to rename stuff
> > in older SoCs that has worked for years now is for one error-prone
> > as Michael pointed out, but also introduces unnecessary churn,
> > when these old SoCs (thinking of rk3188, rk3288 and friends but also things
> > like the rk3368) are essentially "finished" and most likely won't see that
> > much additional support for stuff added.
> 
> So... may I take it that you are going to apply the patches in this series?

that was the intention behind that "wall of text" :-D

Heiko


> Or should I switch to option 3 and re-submit?
> 
> Thanks and best regards,
> Michael
> 
> > 
> > 
> > Heiko
> > 
> > 
> >> Option 2 is not really feasible, we would almost definitely break
> >> something existent.
> >>
> >> Option 3 is feasible, of course. However, I would sort the nodes
> >> alphabetically (u2phy*, then uart*, then usb*). Works for me as well,
> >> although it is not that nice IMHO.
> >>
> >> Since many boards with the RK3566 and RK3568 will pop up in near future
> >> we should do the change right now (if we want to do it), as of course
> >> all the board files need to be changed. Therefore I wanted to bring this
> >> matter up now. Let's agree on something and move on.
> >>
> >> Best regards,
> >> Michael
> >>
> > 
> > 
> > 
> > 
> 






From arnd at arndb.de  Sun Jan 30 03:32:29 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Sun, 30 Jan 2022 12:32:29 +0100
Subject: [PATCH V4 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAJF2gTQQnrUFNQ85vvoMkpxnCWuMw8iXtPZOJwWGaEA9f+rTwA@mail.gmail.com>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-9-guoren@kernel.org>
 <CAK8P3a3JGP6fLVOyLgdNw2YpRSmArbEX8orUhRrN=GHmcdk=1g@mail.gmail.com>
 <CAJF2gTQQnrUFNQ85vvoMkpxnCWuMw8iXtPZOJwWGaEA9f+rTwA@mail.gmail.com>
Message-ID: <CAK8P3a12CygLFT7qoQ9K=sowvTgNpeRej6Zh6Pv2PL_e2zMhMQ@mail.gmail.com>

On Sun, Jan 30, 2022 at 6:54 AM Guo Ren <guoren at kernel.org> wrote:
> On Sun, Jan 30, 2022 at 6:41 AM Arnd Bergmann <arnd at arndb.de> wrote:
> >
> > I would make these endian-specific, and reverse them on big-endian
> > architectures. That way it
> > should be possible to share them across all compat architectures
> > without needing the override
> > option.
> I hope it could be another patch. Because it's not clear to
> _LITTLE_ENDIAN definition in archs.
>
> eg: Names could be __ORDER_LITTLE_ENDIAN__ CPU_LITTLE_ENDIAN
> SYS_SUPPORTS_LITTLE_ENDIAN __LITTLE_ENDIAN
>
> riscv is little-endian, but no any LITTLE_ENDIAN definition.
>
> So let's keep them in the patch, first, Thx

The correct way to do it is to check for CONFIG_CPU_BIG_ENDIAN,
which works on all architectures. Since nothing else selects the
__ARCH_WANT_COMPAT_* symbols, there is also no risk for
regressions, so just use this and leave the #ifndef compat_arg_u64
check in place.

      Arnd


From stefan.wahren at i2se.com  Sun Jan 30 03:35:29 2022
From: stefan.wahren at i2se.com (Stefan Wahren)
Date: Sun, 30 Jan 2022 12:35:29 +0100
Subject: [PATCH RFC 1/4] brcmfmac: use separate firmware for 43430
 revision 4
In-Reply-To: <dff5f86f-d6a5-f197-3c90-3b77d06991ce@broadcom.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
 <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>
 <8ed4450d-85d9-c69b-761a-7695b3f1bbb3@i2se.com>
 <dff5f86f-d6a5-f197-3c90-3b77d06991ce@broadcom.com>
Message-ID: <aa3c8cfc-39bf-22e4-cb98-c19c14e7d8bc@i2se.com>

Hi Arend,

Am 24.01.22 um 10:43 schrieb Arend van Spriel:
> On 1/22/2022 1:35 PM, Stefan Wahren wrote:
>> Am 01.01.22 um 21:26 schrieb Stefan Wahren:
>>> A separate firmware is needed, for Broadcom 43430 revision 4. This
>>> chip can be found on e.g. certain revisions of Raspberry Pi Zero 2 W.
>>> Original firmware file from IC vendor is named
>>> 'brcmfmac43436-sdio.bin',
>>> but brcmfmac and also btbcm drivers report chip id 43430, so requested
>>> firmware file name is 'brcmfmac43430c0-sdio.bin' in line with other
>>> 43430 revisions.
>>>
>>> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
>>> ---
>>>
>>> Hi,
>>> i'm not sure about all these mappings. All i can say is that the wifi
>>> interface of the RPi Zero 2 cames up with this patch.
>> gentle ping (yes, i'm aware of the merge window)
>
> Sorry, Stefan
>
> Should have seen this earlier, but here it is....
>
>>>
>>> ? drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
>>> ? 1 file changed, 3 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>> index 8effeb7..c79bd47 100644
>>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>> @@ -618,6 +618,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
>>> ? /* Note the names are not postfixed with a1 for backward
>>> compatibility */
>>> ? BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
>>> ? BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
>>> +BRCMF_FW_CLM_DEF(43430C0, "brcmfmac43430c0-sdio");
>>> ? BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
>>> ? BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
>>> ? BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
>>> @@ -649,7 +650,8 @@ static const struct brcmf_firmware_mapping
>>> brcmf_sdio_fwnames[] = {
>>> ????? BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
>>> ????? BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
>>> ????? BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
>>> -??? BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
>>> +??? BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43430C0),
>
> According to the revision mask your firmware seems to be for numerical
> revision 2 of this chip...
>
>>> +??? BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFF8, 43430B0),
>
> and for the b0 the chip revision is 3 (or higher). So the alphanumeric
> revision of your chip would be 'a2' instead of 'c0'.

i changed this to a2 for the next version of this series. But before i
send them out, please doublecheck the kernel log 5.17-rc1 of my RPi Zero
2 W. I confuses me that the bluetooth part tells about BCM43430B0:

[??? 9.653199] Bluetooth: hci0: BCM: chip id 115
[??? 9.653749] Bluetooth: hci0: BCM: features 0x0e
[??? 9.655466] Bluetooth: hci0: BCM43430B0
[??? 9.655502] Bluetooth: hci0: BCM43430B0 (002.001.012) build 0000
[??? 9.659512] vc4-drm soc:gpu: bound 3f400000.hvs (ops
vc4_drm_unregister [vc4])
[??? 9.667047] Bluetooth: hci0: BCM43430B0 'brcm/BCM43430B0.hcd' Patch
[??? 9.668052] brcmfmac: brcmf_fw_alloc_request: using
brcm/brcmfmac43430a2-sdio for chip BCM43430/2
[??? 9.668567] brcmfmac mmc1:0001:1: Direct firmware load for
brcm/brcmfmac43430a2-sdio.raspberrypi,model-zero-2-w.bin failed with
error -2
[??? 9.673724] vc4-drm soc:gpu: bound 3f400000.hvs (ops
vc4_drm_unregister [vc4])
[??? 9.697996] brcmfmac mmc1:0001:1: Direct firmware load for
brcm/brcmfmac43430a2-sdio.raspberrypi,model-zero-2-w.txt failed with
error -2
[??? 9.816030] brcmfmac: brcmf_fw_alloc_request: using
brcm/brcmfmac43430a2-sdio for chip BCM43430/2
[??? 9.840128] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/2
wl0: Oct? 9 2020 14:44:32 version 9.88.4.65 (test) (f149b32 at shgit)?
(r679549) FWID 01-f40f3270
[??? 9.919182] random: crng init done
[??? 9.919200] random: 7 urandom warning(s) missed due to ratelimiting
[?? 10.105524] vc4-drm soc:gpu: bound 3f400000.hvs (ops
vc4_drm_unregister [vc4])
[?? 10.118011] vc4-drm soc:gpu: bound 3f902000.hdmi (ops
vc4_drm_unregister [vc4])
[?? 10.118190] vc4-drm soc:gpu: bound 3f806000.vec (ops
vc4_drm_unregister [vc4])
[?? 10.118364] vc4-drm soc:gpu: bound 3f004000.txp (ops
vc4_drm_unregister [vc4])
[?? 10.118503] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops
vc4_drm_unregister [vc4])
[?? 10.118625] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops
vc4_drm_unregister [vc4])
[?? 10.118747] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops
vc4_drm_unregister [vc4])
[?? 10.118847] vc4-drm soc:gpu: bound 3fc00000.v3d (ops
vc4_drm_unregister [vc4])
[?? 10.119331] checking generic (1e330000 8ca000) vs hw (0 ffffffff)
[?? 10.119339] fb0: switching to vc4 from simple
[?? 10.122443] Console: switching to colour dummy device 80x30
[?? 10.125147] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
[?? 10.203822] Console: switching to colour frame buffer device 240x75
[?? 10.241067] vc4-drm soc:gpu: [drm] fb0: vc4drmfb frame buffer device
[?? 10.414793] Bluetooth: hci0: BCM4343B0 37.4MHz wlbga_iLNA_iTR
[Baseline: 0092]
[?? 10.414822] Bluetooth: hci0: BCM43430B0 (002.001.012) build 0092

Thanks




From arnd at arndb.de  Sun Jan 30 03:36:22 2022
From: arnd at arndb.de (Arnd Bergmann)
Date: Sun, 30 Jan 2022 12:36:22 +0100
Subject: [PATCH V4 06/17] riscv: compat: Add basic compat date type
 implementation
In-Reply-To: <CAJF2gTThb8_-T0iOFVZoJrvZqeFvjfWB+AdFyOwtGhN9aG-MQQ@mail.gmail.com>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-7-guoren@kernel.org>
 <CAK8P3a3_kVB78-26sxdsEjb3MMcco6U55tc7siCBFZbJjyH6Sw@mail.gmail.com>
 <CAJF2gTThb8_-T0iOFVZoJrvZqeFvjfWB+AdFyOwtGhN9aG-MQQ@mail.gmail.com>
Message-ID: <CAK8P3a3A9AMyv7ABRpUgrTo3sg+SogoDSG5cudR87iK+PifU4g@mail.gmail.com>

On Sun, Jan 30, 2022 at 6:47 AM Guo Ren <guoren at kernel.org> wrote:
>
> On Sun, Jan 30, 2022 at 5:56 AM Arnd Bergmann <arnd at arndb.de> wrote:
> >
> > On Sat, Jan 29, 2022 at 1:17 PM <guoren at kernel.org> wrote:
> > > +
> > > +#define COMPAT_RLIM_INFINITY   0x7fffffff
> > >
> > > +#define F_GETLK64      12
> > > +#define F_SETLK64      13
> > > +#define F_SETLKW64     14
> >
> > These now come from the generic definitions I think. The flock definitions
> > are just the normal ones,
> Yes, it could be removed after Christoph Hellwig's patch merged.

Rgiht, I keep forgetting that this is a separate series, so this is fine.

> > and AFAICT the RLIM_INIFINITY definition here
> > is actually wrong and should be the default 0xffffffffu to match the
> > native (~0UL) definition.
> Yes, native rv32 used ~0UL, although its task_size is only 2.4GB.

The rlimit range has very little to do with the virtual memory address
limits, it is used for a number of other things that are typically more
limited in practice.

> I would remove #define COMPAT_RLIM_INFINITY   0x7fffffff

Ok.

       Arnd


From jic23 at kernel.org  Sun Jan 30 04:29:34 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 12:29:34 +0000
Subject: [PATCH 2/4] iio: adc: xilinx-ams: Fixed missing PS channels
In-Reply-To: <20220125080634.GD25856@pengutronix.de>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-3-robert.hancock@calian.com>
 <c615acdc4f0a818e070705e1f3f5d82660fb4c8a.camel@calian.com>
 <20220125080634.GD25856@pengutronix.de>
Message-ID: <20220130122934.705dcd87@jic23-huawei>

On Tue, 25 Jan 2022 09:06:34 +0100
Michael Tretter <m.tretter at pengutronix.de> wrote:

> On Thu, 20 Jan 2022 01:09:39 +0000, Robert Hancock wrote:
> > On Wed, 2022-01-19 at 19:02 -0600, Robert Hancock wrote:  
> > > The code forgot to increment num_channels for the PS channel inputs,
> > > resulting in them not being enabled as they should.
> > > 
> > > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > > ---
> > >  drivers/iio/adc/xilinx-ams.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > > 
> > > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > > index 8343c5f74121..b93864362dac 100644
> > > --- a/drivers/iio/adc/xilinx-ams.c
> > > +++ b/drivers/iio/adc/xilinx-ams.c
> > > @@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
> > >  
> > >  		/* add PS channels to iio device channels */
> > >  		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
> > > +		num_channels = ARRAY_SIZE(ams_ps_channels);
> > >  	} else if (fwnode_property_match_string(fwnode, "compatible",
> > >  						"xlnx,zynqmp-ams-pl") == 0) {
> > >  		ams->pl_base = fwnode_iomap(fwnode, 0);  
> > 
> > Looks like this is the same change just submitted by Michael Tretter ("iio:
> > adc: xilinx-ams: Fix num_channels for PS channels").  
> 
> Thanks for pointing me here.
> 
> Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

I picked up Michael's patch and will drop this one...
(based on random email reading order. I'd argue his was first in time, but
then someone would point out next time I pick a patch up that is later than
another one :)

Thanks,

> 
> Michael



From jic23 at kernel.org  Sun Jan 30 04:30:25 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 12:30:25 +0000
Subject: [PATCH] iio: adc: xilinx-ams: Fix num_channels for PS channels
In-Reply-To: <20220119114513.2035609-1-m.tretter@pengutronix.de>
References: <20220119114513.2035609-1-m.tretter@pengutronix.de>
Message-ID: <20220130123025.5ff021d9@jic23-huawei>

On Wed, 19 Jan 2022 12:45:13 +0100
Michael Tretter <m.tretter at pengutronix.de> wrote:

> The IIO channels of the PS are not provided in the sysfs even if the
> ams_ps is enabled in the device tree. The reason is that the channels of
> the PS are not added to the overall number of IIO channels.
> 
> The line somehow got lost between v11 and v12 of the patch series.
> 
> Add the number of ams_ps_channels to the number of channels to correctly
> register all channels.
> 
> Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
Applied to the fixes togreg branch of iio.git.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/xilinx-ams.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index 8343c5f74121..ede968efb77f 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
>  
>  		/* add PS channels to iio device channels */
>  		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
> +		num_channels += ARRAY_SIZE(ams_ps_channels);
>  	} else if (fwnode_property_match_string(fwnode, "compatible",
>  						"xlnx,zynqmp-ams-pl") == 0) {
>  		ams->pl_base = fwnode_iomap(fwnode, 0);



From jic23 at kernel.org  Sun Jan 30 04:31:57 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 12:31:57 +0000
Subject: [PATCH 3/4] iio: adc: xilinx-ams: Fixed wrong sequencer
 register settings
In-Reply-To: <20220126091250.GC2550@pengutronix.de>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-4-robert.hancock@calian.com>
 <20220125082108.GE25856@pengutronix.de>
 <4c5fb3899a8aafa34106a668bcb2807b6f073036.camel@calian.com>
 <20220126091250.GC2550@pengutronix.de>
Message-ID: <20220130123157.0d98f968@jic23-huawei>

On Wed, 26 Jan 2022 10:12:50 +0100
Michael Tretter <m.tretter at pengutronix.de> wrote:

> On Tue, 25 Jan 2022 16:15:05 +0000, Robert Hancock wrote:
> > On Tue, 2022-01-25 at 09:21 +0100, Michael Tretter wrote:  
> > > On Wed, 19 Jan 2022 19:02:45 -0600, Robert Hancock wrote:  
> > > > Register settings used for the sequencer configuration register
> > > > were incorrect, causing some inputs to not be read properly.
> > > > 
> > > > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> > > > Signed-off-by: Robert Hancock <robert.hancock at calian.com>
> > > > ---
> > > >  drivers/iio/adc/xilinx-ams.c | 4 ++--
> > > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > > > 
> > > > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > > > index b93864362dac..199027c93cdc 100644
> > > > --- a/drivers/iio/adc/xilinx-ams.c
> > > > +++ b/drivers/iio/adc/xilinx-ams.c
> > > > @@ -91,8 +91,8 @@
> > > >  
> > > >  #define AMS_CONF1_SEQ_MASK		GENMASK(15, 12)
> > > >  #define AMS_CONF1_SEQ_DEFAULT		FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > > 0)
> > > > -#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 1)
> > > > -#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > > 2)
> > > > +#define AMS_CONF1_SEQ_CONTINUOUS	FIELD_PREP(AMS_CONF1_SEQ_MASK, 2)
> > > > +#define AMS_CONF1_SEQ_SINGLE_CHANNEL	FIELD_PREP(AMS_CONF1_SEQ_MASK,
> > > > 3)  
> > > 
> > > The TRM states that Continuous Loop Mode is 2, but Single Pass Sequence Mode
> > > is 1, not 3. Is there a reason, why you need to set both bits?  
> > 
> > Single pass sequence mode (1) just runs the same sequence only once. To read
> > these values it needs to switch to single channel mode (3).
> > 
> > The register bits are defined in Table 3-8 of 
> > https://www.xilinx.com/support/documentation/user_guides/ug580-ultrascale-sysmon.pdf
> >  .  
> 
> Thanks for the clarification.
> 
> Reviewed-by: Michael Tretter <m.tretter at pengutronix.de>

Applied to the fixes-togreg branch of iio.git

Thanks,

Jonathan


From jic23 at kernel.org  Sun Jan 30 04:34:59 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 12:34:59 +0000
Subject: [PATCH 4/4] iio: adc: xilinx-ams: Fix single channel switching
 sequence
In-Reply-To: <20220120010246.3794962-5-robert.hancock@calian.com>
References: <20220120010246.3794962-1-robert.hancock@calian.com>
 <20220120010246.3794962-5-robert.hancock@calian.com>
Message-ID: <20220130123459.5d44c1ec@jic23-huawei>

On Wed, 19 Jan 2022 19:02:46 -0600
Robert Hancock <robert.hancock at calian.com> wrote:

> Some of the AMS channels need to be read by switching into single-channel
> mode from the normal polling sequence. There was a logic issue in this
> switching code that could cause the first read of these channels to read
> back as zero.
> 
> It appears that the sequencer should be set back to default mode before
> changing the channel selection, and the channel should be set before
> switching the sequencer back into single-channel mode.
> 
> Also, write 1 to the EOC bit in the status register to clear it before
> waiting for it to become set, so that we actually wait for a new
> conversion to complete, and don't proceed based on a previous conversion
> completing.
> 
> Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")
> Signed-off-by: Robert Hancock <robert.hancock at calian.com>

Looking for an Ack from Anand or someone else familiar with this device.

Thanks,

Jonathan


> ---
>  drivers/iio/adc/xilinx-ams.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> index 199027c93cdc..7bf097fa10cb 100644
> --- a/drivers/iio/adc/xilinx-ams.c
> +++ b/drivers/iio/adc/xilinx-ams.c
> @@ -530,14 +530,18 @@ static int ams_enable_single_channel(struct ams *ams, unsigned int offset)
>  		return -EINVAL;
>  	}
>  
> -	/* set single channel, sequencer off mode */
> +	/* put sysmon in a soft reset to change the sequence */
>  	ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK,
> -			  AMS_CONF1_SEQ_SINGLE_CHANNEL);
> +			  AMS_CONF1_SEQ_DEFAULT);
>  
>  	/* write the channel number */
>  	ams_ps_update_reg(ams, AMS_REG_CONFIG0, AMS_CONF0_CHANNEL_NUM_MASK,
>  			  channel_num);
>  
> +	/* set single channel, sequencer off mode */
> +	ams_ps_update_reg(ams, AMS_REG_CONFIG1, AMS_CONF1_SEQ_MASK,
> +			  AMS_CONF1_SEQ_SINGLE_CHANNEL);
> +
>  	return 0;
>  }
>  
> @@ -551,6 +555,8 @@ static int ams_read_vcc_reg(struct ams *ams, unsigned int offset, u32 *data)
>  	if (ret)
>  		return ret;
>  
> +	/* clear end-of-conversion flag, wait for next conversion to complete */
> +	writel(expect, ams->base + AMS_ISR_1);
>  	ret = readl_poll_timeout(ams->base + AMS_ISR_1, reg, (reg & expect),
>  				 AMS_INIT_POLL_TIME_US, AMS_INIT_TIMEOUT_US);
>  	if (ret)



From jic23 at kernel.org  Sun Jan 30 04:44:45 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 12:44:45 +0000
Subject: [PATCH] iio: adc: xilinx-ams: Fix num_channels for PS channels
In-Reply-To: <20220130123025.5ff021d9@jic23-huawei>
References: <20220119114513.2035609-1-m.tretter@pengutronix.de>
 <20220130123025.5ff021d9@jic23-huawei>
Message-ID: <20220130124445.22a34873@jic23-huawei>

On Sun, 30 Jan 2022 12:30:25 +0000
Jonathan Cameron <jic23 at kernel.org> wrote:

> On Wed, 19 Jan 2022 12:45:13 +0100
> Michael Tretter <m.tretter at pengutronix.de> wrote:
> 
> > The IIO channels of the PS are not provided in the sysfs even if the
> > ams_ps is enabled in the device tree. The reason is that the channels of
> > the PS are not added to the overall number of IIO channels.
> > 
> > The line somehow got lost between v11 and v12 of the patch series.
> > 
> > Add the number of ams_ps_channels to the number of channels to correctly
> > register all channels.
> > 
> > Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
> > Fixes: d5c70627a794 ("iio: adc: Add Xilinx AMS driver")  
> Applied to the fixes togreg branch of iio.git.
> 
Actually change of plan . I'll just pick up the v2 fixes set from
Robert as otherwise I'll loose track of where we are with these.

Thanks,

Jonathan

> Thanks,
> 
> Jonathan
> 
> > ---
> >  drivers/iio/adc/xilinx-ams.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/iio/adc/xilinx-ams.c b/drivers/iio/adc/xilinx-ams.c
> > index 8343c5f74121..ede968efb77f 100644
> > --- a/drivers/iio/adc/xilinx-ams.c
> > +++ b/drivers/iio/adc/xilinx-ams.c
> > @@ -1224,6 +1224,7 @@ static int ams_init_module(struct iio_dev *indio_dev,
> >  
> >  		/* add PS channels to iio device channels */
> >  		memcpy(channels, ams_ps_channels, sizeof(ams_ps_channels));
> > +		num_channels += ARRAY_SIZE(ams_ps_channels);
> >  	} else if (fwnode_property_match_string(fwnode, "compatible",
> >  						"xlnx,zynqmp-ams-pl") == 0) {
> >  		ams->pl_base = fwnode_iomap(fwnode, 0);  
> 



From arend.vanspriel at broadcom.com  Sun Jan 30 04:56:57 2022
From: arend.vanspriel at broadcom.com (Arend Van Spriel)
Date: Sun, 30 Jan 2022 13:56:57 +0100
Subject: [PATCH RFC 1/4] brcmfmac: use separate firmware for 43430
 revision 4
In-Reply-To: <aa3c8cfc-39bf-22e4-cb98-c19c14e7d8bc@i2se.com>
References: <1641068812-5851-1-git-send-email-stefan.wahren@i2se.com>
 <1641068812-5851-2-git-send-email-stefan.wahren@i2se.com>
 <8ed4450d-85d9-c69b-761a-7695b3f1bbb3@i2se.com>
 <dff5f86f-d6a5-f197-3c90-3b77d06991ce@broadcom.com>
 <aa3c8cfc-39bf-22e4-cb98-c19c14e7d8bc@i2se.com>
Message-ID: <17eab0f59a8.279b.9b12b7fc0a3841636cfb5e919b41b954@broadcom.com>

I am also a bit confused. The subject mentions revision 4, but your log 
shows 43430/2. Took some digging but found that numerical rev 2 matches 
'b0' and rev 3 matches 'b1'. The BT part is unknown territory for me so can 
not clarify things there.

Regards,
Arend

On January 30, 2022 12:35:35 PM Stefan Wahren <stefan.wahren at i2se.com> wrote:

> Hi Arend,
>
> Am 24.01.22 um 10:43 schrieb Arend van Spriel:
>> On 1/22/2022 1:35 PM, Stefan Wahren wrote:
>>> Am 01.01.22 um 21:26 schrieb Stefan Wahren:
>>>> A separate firmware is needed, for Broadcom 43430 revision 4. This
>>>> chip can be found on e.g. certain revisions of Raspberry Pi Zero 2 W.
>>>> Original firmware file from IC vendor is named
>>>> 'brcmfmac43436-sdio.bin',
>>>> but brcmfmac and also btbcm drivers report chip id 43430, so requested
>>>> firmware file name is 'brcmfmac43430c0-sdio.bin' in line with other
>>>> 43430 revisions.
>>>>
>>>> Signed-off-by: Stefan Wahren <stefan.wahren at i2se.com>
>>>> ---
>>>>
>>>> Hi,
>>>> i'm not sure about all these mappings. All i can say is that the wifi
>>>> interface of the RPi Zero 2 cames up with this patch.
>>> gentle ping (yes, i'm aware of the merge window)
>>
>> Sorry, Stefan
>>
>> Should have seen this earlier, but here it is....
>>
>>>>
>>>>  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++-
>>>>  1 file changed, 3 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>>> b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>>> index 8effeb7..c79bd47 100644
>>>> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>>> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
>>>> @@ -618,6 +618,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-sdio");
>>>>  /* Note the names are not postfixed with a1 for backward
>>>> compatibility */
>>>>  BRCMF_FW_CLM_DEF(43430A1, "brcmfmac43430-sdio");
>>>>  BRCMF_FW_DEF(43430B0, "brcmfmac43430b0-sdio");
>>>> +BRCMF_FW_CLM_DEF(43430C0, "brcmfmac43430c0-sdio");
>>>>  BRCMF_FW_CLM_DEF(43455, "brcmfmac43455-sdio");
>>>>  BRCMF_FW_DEF(43456, "brcmfmac43456-sdio");
>>>>  BRCMF_FW_CLM_DEF(4354, "brcmfmac4354-sdio");
>>>> @@ -649,7 +650,8 @@ static const struct brcmf_firmware_mapping
>>>> brcmf_sdio_fwnames[] = {
>>>>      BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
>>>>      BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0),
>>>>      BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000002, 43430A1),
>>>> -    BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFC, 43430B0),
>>>> +    BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000004, 43430C0),
>>
>> According to the revision mask your firmware seems to be for numerical
>> revision 2 of this chip...
>>
>>>> +    BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFF8, 43430B0),
>>
>> and for the b0 the chip revision is 3 (or higher). So the alphanumeric
>> revision of your chip would be 'a2' instead of 'c0'.
>
> i changed this to a2 for the next version of this series. But before i
> send them out, please doublecheck the kernel log 5.17-rc1 of my RPi Zero
> 2 W. I confuses me that the bluetooth part tells about BCM43430B0:
>
> [    9.653199] Bluetooth: hci0: BCM: chip id 115
> [    9.653749] Bluetooth: hci0: BCM: features 0x0e
> [    9.655466] Bluetooth: hci0: BCM43430B0
> [    9.655502] Bluetooth: hci0: BCM43430B0 (002.001.012) build 0000
> [    9.659512] vc4-drm soc:gpu: bound 3f400000.hvs (ops
> vc4_drm_unregister [vc4])
> [    9.667047] Bluetooth: hci0: BCM43430B0 'brcm/BCM43430B0.hcd' Patch
> [    9.668052] brcmfmac: brcmf_fw_alloc_request: using
> brcm/brcmfmac43430a2-sdio for chip BCM43430/2
> [    9.668567] brcmfmac mmc1:0001:1: Direct firmware load for
> brcm/brcmfmac43430a2-sdio.raspberrypi,model-zero-2-w.bin failed with
> error -2
> [    9.673724] vc4-drm soc:gpu: bound 3f400000.hvs (ops
> vc4_drm_unregister [vc4])
> [    9.697996] brcmfmac mmc1:0001:1: Direct firmware load for
> brcm/brcmfmac43430a2-sdio.raspberrypi,model-zero-2-w.txt failed with
> error -2
> [    9.816030] brcmfmac: brcmf_fw_alloc_request: using
> brcm/brcmfmac43430a2-sdio for chip BCM43430/2
> [    9.840128] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM43430/2
> wl0: Oct  9 2020 14:44:32 version 9.88.4.65 (test) (f149b32 at shgit)
> (r679549) FWID 01-f40f3270
> [    9.919182] random: crng init done
> [    9.919200] random: 7 urandom warning(s) missed due to ratelimiting
> [   10.105524] vc4-drm soc:gpu: bound 3f400000.hvs (ops
> vc4_drm_unregister [vc4])
> [   10.118011] vc4-drm soc:gpu: bound 3f902000.hdmi (ops
> vc4_drm_unregister [vc4])
> [   10.118190] vc4-drm soc:gpu: bound 3f806000.vec (ops
> vc4_drm_unregister [vc4])
> [   10.118364] vc4-drm soc:gpu: bound 3f004000.txp (ops
> vc4_drm_unregister [vc4])
> [   10.118503] vc4-drm soc:gpu: bound 3f206000.pixelvalve (ops
> vc4_drm_unregister [vc4])
> [   10.118625] vc4-drm soc:gpu: bound 3f207000.pixelvalve (ops
> vc4_drm_unregister [vc4])
> [   10.118747] vc4-drm soc:gpu: bound 3f807000.pixelvalve (ops
> vc4_drm_unregister [vc4])
> [   10.118847] vc4-drm soc:gpu: bound 3fc00000.v3d (ops
> vc4_drm_unregister [vc4])
> [   10.119331] checking generic (1e330000 8ca000) vs hw (0 ffffffff)
> [   10.119339] fb0: switching to vc4 from simple
> [   10.122443] Console: switching to colour dummy device 80x30
> [   10.125147] [drm] Initialized vc4 0.0.0 20140616 for soc:gpu on minor 0
> [   10.203822] Console: switching to colour frame buffer device 240x75
> [   10.241067] vc4-drm soc:gpu: [drm] fb0: vc4drmfb frame buffer device
> [   10.414793] Bluetooth: hci0: BCM4343B0 37.4MHz wlbga_iLNA_iTR
> [Baseline: 0092]
> [   10.414822] Bluetooth: hci0: BCM43430B0 (002.001.012) build 0092
>
> Thanks



-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4219 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20220130/2349d45a/attachment.p7s>

From nicolas.ferre at microchip.com  Sun Jan 30 06:39:35 2022
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Sun, 30 Jan 2022 15:39:35 +0100
Subject: [PATCH 1/2] MAINTAINERS: replace a Microchip AT91 maintainer
Message-ID: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

As Ludovic is more focusing on other aspects of the Microchip
Linux-based development, replace him with Claudiu.
Entry is added to the CREDITS file.

Thanks Ludovic for these great contributions in the kernel space!

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
 CREDITS     | 6 ++++++
 MAINTAINERS | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/CREDITS b/CREDITS
index b97256d5bc24..7e85a53b6a88 100644
--- a/CREDITS
+++ b/CREDITS
@@ -895,6 +895,12 @@ S: 3000 FORE Drive
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Ludovic Desroches
+E: ludovic.desroches at microchip.com
+D: Maintainer for ARM/Microchip (AT91) SoC support
+D: Author of ADC, pinctrl, XDMA and SDHCI drivers for this platform
+S: France
+
 N: Martin Devera
 E: devik at cdi.cz
 W: http://luxik.cdi.cz/~devik/qos/
diff --git a/MAINTAINERS b/MAINTAINERS
index ea3e6c914384..674d13708324 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2250,7 +2250,7 @@ F:	drivers/phy/mediatek/
 ARM/Microchip (AT91) SoC support
 M:	Nicolas Ferre <nicolas.ferre at microchip.com>
 M:	Alexandre Belloni <alexandre.belloni at bootlin.com>
-M:	Ludovic Desroches <ludovic.desroches at microchip.com>
+M:	Claudiu Beznea <claudiu.beznea at microchip.com>
 L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
 S:	Supported
 W:	http://www.linux4sam.org
-- 
2.32.0



From nicolas.ferre at microchip.com  Sun Jan 30 06:39:36 2022
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Sun, 30 Jan 2022 15:39:36 +0100
Subject: [PATCH 2/2] dt-bindings: ARM: at91: update maintainers entry
In-Reply-To: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
References: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
Message-ID: <5bf9873eeee3cd49c52a8952a7cd4cb60b61d50a.1643553501.git.nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Align the binding documentation with the newly updated MAINTAINERS
entry.

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
 Documentation/devicetree/bindings/arm/atmel-at91.yaml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
index c612e1f48dba..ff91df04f9f4 100644
--- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
+++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
@@ -8,7 +8,8 @@ title: Atmel AT91 device tree bindings.
 
 maintainers:
   - Alexandre Belloni <alexandre.belloni at bootlin.com>
-  - Ludovic Desroches <ludovic.desroches at microchip.com>
+  - Claudiu Beznea <claudiu.beznea at microchip.com>
+  - Nicolas Ferre <nicolas.ferre at microchip.com>
 
 description: |
   Boards with a SoC of the Atmel AT91 or SMART family shall have the following
-- 
2.32.0



From nicolas.ferre at microchip.com  Sun Jan 30 06:47:08 2022
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Sun, 30 Jan 2022 15:47:08 +0100
Subject: [PATCH] dt-bindings: rng: atmel,at91-trng: update maintainers entry
Message-ID: <d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Update according to new MAINTAINERS entry.

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Hi,

Patch for new MAINTAINERS entry is here:
https://lore.kernel.org/linux-arm-kernel/23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre at microchip.com/

Regards,
  Nicolas

 Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
index c1527637eb74..3ce45456d867 100644
--- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
+++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
@@ -9,7 +9,7 @@ title: Atmel AT91 True Random Number Generator
 maintainers:
   - Nicolas Ferre <nicolas.ferre at microchip.com>
   - Alexandre Belloni <alexandre.belloni at bootlin.com>
-  - Ludovic Desroches <ludovic.desroches at microchip.com>
+  - Claudiu Beznea <claudiu.beznea at microchip.com>
 
 properties:
   compatible:
-- 
2.32.0



From nicolas.ferre at microchip.com  Sun Jan 30 06:50:08 2022
From: nicolas.ferre at microchip.com (nicolas.ferre at microchip.com)
Date: Sun, 30 Jan 2022 15:50:08 +0100
Subject: [PATCH 1/1] dt-bindings: iio: adc: at91-sama5d2: update maintainers
 entry
Message-ID: <6acdb66592baf395a77a431c0cb9a37b0f178097.1643554065.git.nicolas.ferre@microchip.com>

From: Nicolas Ferre <nicolas.ferre at microchip.com>

Update the maintainers entry to match the changes made back in
mid-2020 with 853fa48717c2 ("MAINTAINERS: adc: at91-sama5d2_adc:
remove myself as co-maintainer").

Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
---
Hi,

Patch for new MAINTAINERS entry is here:
https://lore.kernel.org/linux-arm-kernel/23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre at microchip.com/

Regards,
  Nicolas

 Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
index efed361215b4..9a2292e7defc 100644
--- a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
@@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: AT91 SAMA5D2 Analog to Digital Converter (ADC)
 
 maintainers:
-  - Ludovic Desroches <ludovic.desroches at atmel.com>
   - Eugen Hristev <eugen.hristev at microchip.com>
 
 properties:
-- 
2.32.0



From nbd at nbd.name  Sun Jan 30 06:51:04 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:04 +0100
Subject: [PATCH v9 01/13] dt-bindings: Add vendor prefix for Airoha
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-2-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Add vendor prefix "airoha" for Airoha, a subsidiary of MediaTek

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Bert Vermeulen <bert at biot.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index eb8ab0d82198..d2f9fd7654bc 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -59,6 +59,8 @@ patternProperties:
     description: Aeroflex Gaisler AB
   "^aesop,.*":
     description: AESOP Embedded Forum
+  "^airoha,.*":
+    description: Airoha
   "^al,.*":
     description: Annapurna Labs
   "^alcatel,.*":
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:05 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:05 +0100
Subject: [PATCH v9 02/13] dt-bindings: arm: airoha: Add binding for EN7523 SoC
 and EVB
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-3-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Add devicetree binding for Airoha EN7523 SoC and evaluation board.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Bert Vermeulen <bert at biot.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 .../devicetree/bindings/arm/airoha.yaml       | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/airoha.yaml

diff --git a/Documentation/devicetree/bindings/arm/airoha.yaml b/Documentation/devicetree/bindings/arm/airoha.yaml
new file mode 100644
index 000000000000..fc19b1a6f37b
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/airoha.yaml
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/airoha.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha SoC based Platforms Device Tree Bindings
+
+maintainers:
+  - Felix Fietkau <nbd at nbd.name>
+  - John Crispin <john at phrozen.org>
+
+description:
+  Boards with an Airoha SoC shall have the following properties.
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - airoha,en7523-evb
+          - const: airoha,en7523
+
+additionalProperties: true
+
+...
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:10 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:10 +0100
Subject: [PATCH v9 07/13] ARM: dts: add clock support for Airoha EN7523
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-8-nbd@nbd.name>

This driver only registers fixed rate clocks, since the clocks are fully
initialized by the boot loader and should not be changed later, according
to Airoha.

Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 arch/arm/boot/dts/en7523.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/en7523.dtsi b/arch/arm/boot/dts/en7523.dtsi
index f1d4c03aad89..1e5280be02ba 100644
--- a/arch/arm/boot/dts/en7523.dtsi
+++ b/arch/arm/boot/dts/en7523.dtsi
@@ -2,6 +2,7 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/en7523-clk.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -82,6 +83,13 @@ L2_0: l2-cache0 {
 		};
 	};
 
+	scu: system-controller at 1fa20000 {
+		compatible = "airoha,en7523-scu";
+		reg = <0x1fa20000 0x400>,
+		      <0x1fb00000 0x1000>;
+		#clock-cells = <1>;
+	};
+
 	gic: interrupt-controller at 9000000 {
 		compatible = "arm,gic-v3";
 		interrupt-controller;
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:03 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:03 +0100
Subject: [PATCH v9 00/13] Add support for Airoha EN7523 SoC
Message-ID: <20220130145116.88406-1-nbd@nbd.name>

This patchset adds support for the Airoha EN7523 SoC, intended primarily
for xPON/xDSL routers.

Felix Fietkau (4):
  clk: en7523: Add clock driver for Airoha EN7523 SoC
  ARM: dts: add clock support for Airoha EN7523
  PCI: mediatek: Allow building for ARCH_AIROHA
  ARM: dts: Add PCIe support for Airoha EN7523

John Crispin (9):
  dt-bindings: Add vendor prefix for Airoha
  dt-bindings: arm: airoha: Add binding for EN7523 SoC and EVB
  ARM: Add basic support for Airoha EN7523 SoC
  ARM: multi_v7_defconfig: Add support for Airoha EN7523 SoC
  dt-bindings: Add en7523-scu device tree binding documentation
  dt-bindings: PCI: Add support for Airoha EN7532
  dt-bindings: arm: airoha: Add binding for Airoha GPIO controller
  gpio: Add support for Airoha EN7523 GPIO controller
  ARM: dts: add GPIO support for Airoha EN7523

 .../devicetree/bindings/arm/airoha.yaml       |  28 ++
 .../bindings/clock/airoha,en7523-scu.yaml     |  58 +++
 .../bindings/gpio/airoha,en7523-gpio.yaml     |  67 ++++
 .../devicetree/bindings/pci/mediatek-pcie.txt |   1 +
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 arch/arm/Kconfig                              |  12 +
 arch/arm/Makefile                             |   1 +
 arch/arm/boot/dts/Makefile                    |   2 +
 arch/arm/boot/dts/en7523-evb.dts              |  43 +++
 arch/arm/boot/dts/en7523.dtsi                 | 205 ++++++++++
 arch/arm/configs/multi_v7_defconfig           |   1 +
 arch/arm/mach-airoha/Makefile                 |   2 +
 arch/arm/mach-airoha/airoha.c                 |  16 +
 drivers/clk/Kconfig                           |   9 +
 drivers/clk/Makefile                          |   1 +
 drivers/clk/clk-en7523.c                      | 350 ++++++++++++++++++
 drivers/gpio/Kconfig                          |  10 +
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-en7523.c                    | 137 +++++++
 drivers/pci/controller/Kconfig                |   2 +-
 include/dt-bindings/clock/en7523-clk.h        |  17 +
 21 files changed, 964 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/arm/airoha.yaml
 create mode 100644 Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
 create mode 100644 Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml
 create mode 100644 arch/arm/boot/dts/en7523-evb.dts
 create mode 100644 arch/arm/boot/dts/en7523.dtsi
 create mode 100644 arch/arm/mach-airoha/Makefile
 create mode 100644 arch/arm/mach-airoha/airoha.c
 create mode 100644 drivers/clk/clk-en7523.c
 create mode 100644 drivers/gpio/gpio-en7523.c
 create mode 100644 include/dt-bindings/clock/en7523-clk.h

-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:08 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:08 +0100
Subject: [PATCH v9 05/13] dt-bindings: Add en7523-scu device tree binding
 documentation
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-6-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Adds device tree binding documentation for clocks in the EN7523 SOC.

Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 .../bindings/clock/airoha,en7523-scu.yaml     | 58 +++++++++++++++++++
 include/dt-bindings/clock/en7523-clk.h        | 17 ++++++
 2 files changed, 75 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
 create mode 100644 include/dt-bindings/clock/en7523-clk.h

diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
new file mode 100644
index 000000000000..d60e74654809
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/airoha,en7523-scu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: EN7523 Clock Device Tree Bindings
+
+maintainers:
+  - Felix Fietkau <nbd at nbd.name>
+  - John Crispin <nbd at nbd.name>
+
+description: |
+  This node defines the System Control Unit of the EN7523 SoC,
+  a collection of registers configuring many different aspects of the SoC.
+
+  The clock driver uses it to read and configure settings of the
+  PLL controller, which provides clocks for the CPU, the bus and
+  other SoC internal peripherals.
+
+  Each clock is assigned an identifier and client nodes use this identifier
+  to specify which clock they consume.
+
+  All these identifiers can be found in:
+  [1]: <include/dt-bindings/clock/en7523-clk.h>.
+
+  The clocks are provided inside a system controller node.
+
+properties:
+  compatible:
+    items:
+      - const: airoha,en7523-scu
+
+  reg:
+    maxItems: 2
+
+  "#clock-cells":
+    description:
+      The first cell indicates the clock number, see [1] for available
+      clocks.
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/en7523-clk.h>
+    scu: system-controller at 1fa20000 {
+      compatible = "airoha,en7523-scu";
+      reg = <0x1fa20000 0x400>,
+            <0x1fb00000 0x1000>;
+      #clock-cells = <1>;
+    };
diff --git a/include/dt-bindings/clock/en7523-clk.h b/include/dt-bindings/clock/en7523-clk.h
new file mode 100644
index 000000000000..717d23a5e5ae
--- /dev/null
+++ b/include/dt-bindings/clock/en7523-clk.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+
+#ifndef _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_
+#define _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_
+
+#define EN7523_CLK_GSW		0
+#define EN7523_CLK_EMI		1
+#define EN7523_CLK_BUS		2
+#define EN7523_CLK_SLIC		3
+#define EN7523_CLK_SPI		4
+#define EN7523_CLK_NPU		5
+#define EN7523_CLK_CRYPTO	6
+#define EN7523_CLK_PCIE		7
+
+#define EN7523_NUM_CLOCKS	8
+
+#endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:09 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:09 +0100
Subject: [PATCH v9 06/13] clk: en7523: Add clock driver for Airoha EN7523 SoC
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-7-nbd@nbd.name>

This driver only registers fixed rate clocks, since the clocks are fully
initialized by the boot loader and should not be changed later, according
to Airoha.

Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 drivers/clk/Kconfig      |   9 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-en7523.c | 350 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 360 insertions(+)
 create mode 100644 drivers/clk/clk-en7523.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index c91931c94888..4614d6452fb7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -192,6 +192,15 @@ config COMMON_CLK_CS2000_CP
 	help
 	  If you say yes here you get support for the CS2000 clock multiplier.
 
+config COMMON_CLK_EN7523
+	bool "Clock driver for Airoha EN7523 SoC system clocks"
+	depends on OF
+	depends on ARCH_AIROHA || COMPILE_TEST
+	default ARCH_AIROHA
+	help
+	  This driver provides the fixed clocks and gates present on Airoha
+	  ARM silicon.
+
 config COMMON_CLK_FSL_FLEXSPI
 	tristate "Clock driver for FlexSPI on Layerscape SoCs"
 	depends on ARCH_LAYERSCAPE || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index a9bb2478fbdd..da1e2ac2dfc1 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925)	+= clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
 obj-$(CONFIG_COMMON_CLK_CS2000_CP)	+= clk-cs2000-cp.o
 obj-$(CONFIG_ARCH_SPARX5)		+= clk-sparx5.o
+obj-$(CONFIG_COMMON_CLK_EN7523)		+= clk-en7523.o
 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO)	+= clk-fixed-mmio.o
 obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI)	+= clk-fsl-flexspi.o
 obj-$(CONFIG_COMMON_CLK_FSL_SAI)	+= clk-fsl-sai.o
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
new file mode 100644
index 000000000000..137e13520ad9
--- /dev/null
+++ b/drivers/clk/clk-en7523.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/delay.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/clock/en7523-clk.h>
+
+#define REG_PCI_CONTROL			0x88
+#define   REG_PCI_CONTROL_PERSTOUT	BIT(29)
+#define   REG_PCI_CONTROL_PERSTOUT1	BIT(26)
+#define   REG_PCI_CONTROL_REFCLK_EN1	BIT(22)
+#define REG_GSW_CLK_DIV_SEL		0x1b4
+#define REG_EMI_CLK_DIV_SEL		0x1b8
+#define REG_BUS_CLK_DIV_SEL		0x1bc
+#define REG_SPI_CLK_DIV_SEL		0x1c4
+#define REG_SPI_CLK_FREQ_SEL		0x1c8
+#define REG_NPU_CLK_DIV_SEL		0x1fc
+#define REG_CRYPTO_CLKSRC		0x200
+#define REG_RESET_CONTROL		0x834
+#define   REG_RESET_CONTROL_PCIEHB	BIT(29)
+#define   REG_RESET_CONTROL_PCIE1	BIT(27)
+#define   REG_RESET_CONTROL_PCIE2	BIT(26)
+
+struct en_clk_desc {
+	int id;
+	const char *name;
+	u32 base_reg;
+	u32 base_bits;
+	u32 base_shift;
+	union {
+		const u32 *base_values;
+		u32 base_value;
+	};
+	int n_base_values;
+
+	u32 div_reg;
+	u32 div_bits;
+	u32 div_shift;
+	u32 div_val0;
+	u32 div_step;
+};
+
+struct en_clk_gate {
+	void __iomem *base;
+	struct clk_hw hw;
+};
+
+static const u32 gsw_base[] = { 400000000, 500000000 };
+static const u32 emi_base[] = { 333000000, 400000000 };
+static const u32 bus_base[] = { 500000000, 540000000 };
+static const u32 slic_base[] = { 100000000, 3125000 };
+static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
+
+static const struct en_clk_desc en7523_base_clks[] = {
+	{
+		.id = EN7523_CLK_GSW,
+		.name = "gsw",
+
+		.base_reg = REG_GSW_CLK_DIV_SEL,
+		.base_bits = 1,
+		.base_shift = 8,
+		.base_values = gsw_base,
+		.n_base_values = ARRAY_SIZE(gsw_base),
+
+		.div_bits = 3,
+		.div_shift = 0,
+		.div_step = 1,
+	}, {
+		.id = EN7523_CLK_EMI,
+		.name = "emi",
+
+		.base_reg = REG_EMI_CLK_DIV_SEL,
+		.base_bits = 1,
+		.base_shift = 8,
+		.base_values = emi_base,
+		.n_base_values = ARRAY_SIZE(emi_base),
+
+		.div_bits = 3,
+		.div_shift = 0,
+		.div_step = 1,
+	}, {
+		.id = EN7523_CLK_BUS,
+		.name = "bus",
+
+		.base_reg = REG_BUS_CLK_DIV_SEL,
+		.base_bits = 1,
+		.base_shift = 8,
+		.base_values = bus_base,
+		.n_base_values = ARRAY_SIZE(bus_base),
+
+		.div_bits = 3,
+		.div_shift = 0,
+		.div_step = 1,
+	}, {
+		.id = EN7523_CLK_SLIC,
+		.name = "slic",
+
+		.base_reg = REG_SPI_CLK_FREQ_SEL,
+		.base_bits = 1,
+		.base_shift = 0,
+		.base_values = slic_base,
+		.n_base_values = ARRAY_SIZE(slic_base),
+
+		.div_reg = REG_SPI_CLK_DIV_SEL,
+		.div_bits = 5,
+		.div_shift = 24,
+		.div_val0 = 20,
+		.div_step = 2,
+	}, {
+		.id = EN7523_CLK_SPI,
+		.name = "spi",
+
+		.base_reg = REG_SPI_CLK_DIV_SEL,
+
+		.base_value = 400000000,
+
+		.div_bits = 5,
+		.div_shift = 8,
+		.div_val0 = 40,
+		.div_step = 2,
+	}, {
+		.id = EN7523_CLK_NPU,
+		.name = "npu",
+
+		.base_reg = REG_NPU_CLK_DIV_SEL,
+		.base_bits = 2,
+		.base_shift = 8,
+		.base_values = npu_base,
+		.n_base_values = ARRAY_SIZE(npu_base),
+
+		.div_bits = 3,
+		.div_shift = 0,
+		.div_step = 1,
+	}, {
+		.id = EN7523_CLK_CRYPTO,
+		.name = "crypto",
+
+		.base_reg = REG_CRYPTO_CLKSRC,
+		.base_bits = 1,
+		.base_shift = 8,
+		.base_values = emi_base,
+		.n_base_values = ARRAY_SIZE(emi_base),
+	}
+};
+
+static const struct of_device_id of_match_clk_en7523[] = {
+	{ .compatible = "airoha,en7523-scu", },
+	{ /* sentinel */ }
+};
+
+static u32 en7523_get_base_rate(void __iomem *base, int i)
+{
+	const struct en_clk_desc *desc = &en7523_base_clks[i];
+	u32 val;
+
+	if (!desc->base_bits)
+		return desc->base_value;
+
+	val = readl(base + desc->base_reg);
+	val >>= desc->base_shift;
+	val &= (1 << desc->base_bits) - 1;
+
+	if (val >= desc->n_base_values)
+		return 0;
+
+	return desc->base_values[val];
+}
+
+static u32 en7523_get_div(void __iomem *base, int i)
+{
+	const struct en_clk_desc *desc = &en7523_base_clks[i];
+	u32 reg, val;
+
+	if (!desc->div_bits)
+		return 1;
+
+	reg = desc->div_reg ? desc->div_reg : desc->base_reg;
+	val = readl(base + reg);
+	val >>= desc->div_shift;
+	val &= (1 << desc->div_bits) - 1;
+
+	if (!val && desc->div_val0)
+		return desc->div_val0;
+
+	return (val + 1) * desc->div_step;
+}
+
+static int en7523_pci_is_enabled(struct clk_hw *hw)
+{
+	struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+
+	return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
+}
+
+static int en7523_pci_prepare(struct clk_hw *hw)
+{
+	struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+	void __iomem *np_base = cg->base;
+	u32 val, mask;
+
+	/* Need to pull device low before reset */
+	val = readl(np_base + REG_PCI_CONTROL);
+	val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
+	writel(val, np_base + REG_PCI_CONTROL);
+	usleep_range(1000, 2000);
+
+	/* Enable PCIe port 1 */
+	val |= REG_PCI_CONTROL_REFCLK_EN1;
+	writel(val, np_base + REG_PCI_CONTROL);
+	usleep_range(1000, 2000);
+
+	/* Reset to default */
+	val = readl(np_base + REG_RESET_CONTROL);
+	mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
+	       REG_RESET_CONTROL_PCIEHB;
+	writel(val & ~mask, np_base + REG_RESET_CONTROL);
+	usleep_range(1000, 2000);
+	writel(val | mask, np_base + REG_RESET_CONTROL);
+	msleep(100);
+	writel(val & ~mask, np_base + REG_RESET_CONTROL);
+	usleep_range(5000, 10000);
+
+	/* Release device */
+	mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
+	val = readl(np_base + REG_PCI_CONTROL);
+	writel(val & ~mask, np_base + REG_PCI_CONTROL);
+	usleep_range(1000, 2000);
+	writel(val | mask, np_base + REG_PCI_CONTROL);
+	msleep(250);
+
+	return 0;
+}
+
+static void en7523_pci_unprepare(struct clk_hw *hw)
+{
+	struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
+	void __iomem *np_base = cg->base;
+	u32 val;
+
+	val = readl(np_base + REG_PCI_CONTROL);
+	val &= ~REG_PCI_CONTROL_REFCLK_EN1;
+	writel(val, np_base + REG_PCI_CONTROL);
+}
+
+static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
+					       void __iomem *np_base)
+{
+	static const struct clk_ops pcie_gate_ops = {
+		.is_enabled = en7523_pci_is_enabled,
+		.prepare = en7523_pci_prepare,
+		.unprepare = en7523_pci_unprepare,
+	};
+	struct clk_init_data init = {
+		.name = "pcie",
+		.ops = &pcie_gate_ops,
+	};
+	struct en_clk_gate *cg;
+
+	cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
+	if (!cg)
+		return NULL;
+
+	cg->base = np_base;
+	cg->hw.init = &init;
+	en7523_pci_unprepare(&cg->hw);
+
+	if (clk_hw_register(NULL, &cg->hw))
+		return NULL;
+
+	return &cg->hw;
+}
+
+static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
+				   void __iomem *base, void __iomem *np_base)
+{
+	struct clk_hw *hw;
+	u32 rate;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
+		const struct en_clk_desc *desc = &en7523_base_clks[i];
+
+		rate = en7523_get_base_rate(base, i);
+		rate /= en7523_get_div(base, i);
+
+		hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
+		if (IS_ERR(hw)) {
+			pr_err("Failed to register clk %s: %ld\n",
+			       desc->name, PTR_ERR(hw));
+			continue;
+		}
+
+		clk_data->hws[desc->id] = hw;
+	}
+
+	hw = en7523_register_pcie_clk(dev, np_base);
+	clk_data->hws[EN7523_CLK_PCIE] = hw;
+
+	clk_data->num = EN7523_NUM_CLOCKS;
+}
+
+static int en7523_clk_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct clk_hw_onecell_data *clk_data;
+	void __iomem *base, *np_base;
+	int r;
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	np_base = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(base))
+		return PTR_ERR(np_base);
+
+	clk_data = devm_kzalloc(&pdev->dev,
+				struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
+				GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
+
+	r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
+	if (r)
+		dev_err(&pdev->dev,
+			"could not register clock provider: %s: %d\n",
+			pdev->name, r);
+
+	return r;
+}
+
+static struct platform_driver clk_en7523_drv = {
+	.probe = en7523_clk_probe,
+	.driver = {
+		.name = "clk-en7523",
+		.of_match_table = of_match_clk_en7523,
+	},
+};
+
+static int __init clk_en7523_init(void)
+{
+	return platform_driver_register(&clk_en7523_drv);
+}
+
+arch_initcall(clk_en7523_init);
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:07 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:07 +0100
Subject: [PATCH v9 04/13] ARM: multi_v7_defconfig: Add support for Airoha
 EN7523 SoC
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-5-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

This enables basic bootup support for the Airoha EN7523 SoC.

Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 arch/arm/configs/multi_v7_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index 1c2c3e9f0e05..3b413635f5bd 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -34,6 +34,7 @@ CONFIG_MACH_BERLIN_BG2=y
 CONFIG_MACH_BERLIN_BG2CD=y
 CONFIG_MACH_BERLIN_BG2Q=y
 CONFIG_ARCH_DIGICOLOR=y
+CONFIG_ARCH_AIROHA=y
 CONFIG_ARCH_EXYNOS=y
 CONFIG_ARCH_HIGHBANK=y
 CONFIG_ARCH_HISI=y
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:06 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:06 +0100
Subject: [PATCH v9 03/13] ARM: Add basic support for Airoha EN7523 SoC
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-4-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

EN7523 is an armv8 based silicon used inside broadband access type devices
such as xPON and xDSL. It shares various silicon blocks with MediaTek
silicon such as the MT7622.

Add basic support for Airoha EN7523, enough for booting to console.

The UART is basically 8250-compatible, except for the clock selection.
A clock-frequency value is synthesized to get this to run at 115200 bps.

Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Bert Vermeulen <bert at biot.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 arch/arm/Kconfig                 |  12 ++++
 arch/arm/Makefile                |   1 +
 arch/arm/boot/dts/Makefile       |   2 +
 arch/arm/boot/dts/en7523-evb.dts |  27 +++++++
 arch/arm/boot/dts/en7523.dtsi    | 117 +++++++++++++++++++++++++++++++
 arch/arm/mach-airoha/Makefile    |   2 +
 arch/arm/mach-airoha/airoha.c    |  16 +++++
 7 files changed, 177 insertions(+)
 create mode 100644 arch/arm/boot/dts/en7523-evb.dts
 create mode 100644 arch/arm/boot/dts/en7523.dtsi
 create mode 100644 arch/arm/mach-airoha/Makefile
 create mode 100644 arch/arm/mach-airoha/airoha.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 796fc8017f5d..57ef390d3146 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -572,6 +572,18 @@ config ARCH_VIRT
 	select HAVE_ARM_ARCH_TIMER
 	select ARCH_SUPPORTS_BIG_ENDIAN
 
+config ARCH_AIROHA
+	bool "Airoha SoC Support"
+	depends on ARCH_MULTI_V7
+	select ARM_AMBA
+	select ARM_GIC
+	select ARM_GIC_V3
+	select ARM_PSCI
+	select HAVE_ARM_ARCH_TIMER
+	select COMMON_CLK
+	help
+	  Support for Airoha EN7523 SoCs
+
 #
 # This is sorted alphabetically by mach-* pathname.  However, plat-*
 # Kconfigs may be included either alphabetically (according to the
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 77172d555c7e..34baf885573a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -160,6 +160,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 # Machine directory name.  This list is sorted alphanumerically
 # by CONFIG_* macro name.
 machine-$(CONFIG_ARCH_ACTIONS)		+= actions
+machine-$(CONFIG_ARCH_AIROHA)		+= airoha
 machine-$(CONFIG_ARCH_ALPINE)		+= alpine
 machine-$(CONFIG_ARCH_ARTPEC)		+= artpec
 machine-$(CONFIG_ARCH_ASPEED)           += aspeed
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e41eca79c950..5c2dd47b58b0 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -187,6 +187,8 @@ dtb-$(CONFIG_ARCH_DAVINCI) += \
 	da850-lego-ev3.dtb
 dtb-$(CONFIG_ARCH_DIGICOLOR) += \
 	cx92755_equinox.dtb
+dtb-$(CONFIG_ARCH_AIROHA) += \
+	en7523-evb.dtb
 dtb-$(CONFIG_ARCH_EXYNOS3) += \
 	exynos3250-artik5-eval.dtb \
 	exynos3250-monk.dtb \
diff --git a/arch/arm/boot/dts/en7523-evb.dts b/arch/arm/boot/dts/en7523-evb.dts
new file mode 100644
index 000000000000..69754ef9a628
--- /dev/null
+++ b/arch/arm/boot/dts/en7523-evb.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+/dts-v1/;
+
+/* Bootloader installs ATF here */
+/memreserve/ 0x80000000 0x200000;
+
+#include "en7523.dtsi"
+
+/ {
+	model = "Airoha EN7523 Evaluation Board";
+	compatible = "airoha,en7523-evb", "airoha,en7523";
+
+	aliases {
+		serial0 = &uart1;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 earlycon";
+		stdout-path = "serial0:115200n8";
+		linux,usable-memory-range = <0x80200000 0x1fe00000>;
+	};
+
+	memory at 80000000 {
+		device_type = "memory";
+		reg = <0x80000000 0x20000000>;
+	};
+};
diff --git a/arch/arm/boot/dts/en7523.dtsi b/arch/arm/boot/dts/en7523.dtsi
new file mode 100644
index 000000000000..f1d4c03aad89
--- /dev/null
+++ b/arch/arm/boot/dts/en7523.dtsi
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+	interrupt-parent = <&gic>;
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	reserved-memory {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		npu_binary at 84000000 {
+			no-map;
+			reg = <0x84000000 0xA00000>;
+		};
+
+		npu_flag at 84B0000 {
+			no-map;
+			reg = <0x84B00000 0x100000>;
+		};
+
+		npu_pkt at 85000000 {
+			no-map;
+			reg = <0x85000000 0x1A00000>;
+		};
+
+		npu_phyaddr at 86B00000 {
+			no-map;
+			reg = <0x86B00000 0x100000>;
+		};
+
+		npu_rxdesc at 86D00000 {
+			no-map;
+			reg = <0x86D00000 0x100000>;
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-0.2";
+		method = "smc";
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+				core1 {
+					cpu = <&cpu1>;
+				};
+			};
+		};
+
+		cpu0: cpu at 0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x0>;
+			enable-method = "psci";
+			clock-frequency = <80000000>;
+			next-level-cache = <&L2_0>;
+		};
+
+		cpu1: cpu at 1 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a53";
+			reg = <0x1>;
+			enable-method = "psci";
+			clock-frequency = <80000000>;
+			next-level-cache = <&L2_0>;
+		};
+
+		L2_0: l2-cache0 {
+			compatible = "cache";
+		};
+	};
+
+	gic: interrupt-controller at 9000000 {
+		compatible = "arm,gic-v3";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x09000000 0x20000>,
+		      <0x09080000 0x80000>,
+		      <0x09400000 0x2000>,
+		      <0x09500000 0x2000>,
+		      <0x09600000 0x20000>;
+		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	uart1: serial at 1fbf0000 {
+		compatible = "ns16550";
+		reg = <0x1fbf0000 0x30>;
+		reg-io-width = <4>;
+		reg-shift = <2>;
+		interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+		clock-frequency = <1843200>;
+		status = "okay";
+	};
+};
diff --git a/arch/arm/mach-airoha/Makefile b/arch/arm/mach-airoha/Makefile
new file mode 100644
index 000000000000..a5857d0d02eb
--- /dev/null
+++ b/arch/arm/mach-airoha/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y			+= airoha.o
diff --git a/arch/arm/mach-airoha/airoha.c b/arch/arm/mach-airoha/airoha.c
new file mode 100644
index 000000000000..ea23b5abb478
--- /dev/null
+++ b/arch/arm/mach-airoha/airoha.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device Tree support for Airoha SoCs
+ *
+ * Copyright (c) 2022 Felix Fietkau <nbd at nbd.name>
+ */
+#include <asm/mach/arch.h>
+
+static const char * const airoha_board_dt_compat[] = {
+	"airoha,en7523",
+	NULL,
+};
+
+DT_MACHINE_START(MEDIATEK_DT, "Airoha Cortex-A53 (Device Tree)")
+	.dt_compat	= airoha_board_dt_compat,
+MACHINE_END
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:11 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:11 +0100
Subject: [PATCH v9 08/13] dt-bindings: PCI: Add support for Airoha EN7532
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-9-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

EN7532 is an ARM based platform SoC integrating the same PCIe IP as
MT7622, add a binding for it.

Acked-by: Rob Herring <robh at kernel.org>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 Documentation/devicetree/bindings/pci/mediatek-pcie.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
index 57ae73462272..684227522267 100644
--- a/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/mediatek-pcie.txt
@@ -7,6 +7,7 @@ Required properties:
 	"mediatek,mt7622-pcie"
 	"mediatek,mt7623-pcie"
 	"mediatek,mt7629-pcie"
+	"airoha,en7523-pcie"
 - device_type: Must be "pci"
 - reg: Base addresses and lengths of the root ports.
 - reg-names: Names of the above areas to use during resource lookup.
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:12 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:12 +0100
Subject: [PATCH v9 09/13] PCI: mediatek: Allow building for ARCH_AIROHA
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-10-nbd@nbd.name>

Allow selecting the pcie-mediatek driver if ARCH_AIROHA is set, because the
Airoha EN7523 SoC uses the same controller as MT7622.
The driver itself is not modified. The PCIe controller DT node should use
mediatek,mt7622-pcie after airoha,en7523-pcie.

Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi at arm.com>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 drivers/pci/controller/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 7fc5135ffbbf..08b0e50dcc12 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -233,7 +233,7 @@ config PCIE_ROCKCHIP_EP
 
 config PCIE_MEDIATEK
 	tristate "MediaTek PCIe controller"
-	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
 	depends on OF
 	depends on PCI_MSI_IRQ_DOMAIN
 	help
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:16 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:16 +0100
Subject: [PATCH v9 13/13] ARM: dts: add GPIO support for Airoha EN7523
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-14-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Airoha's GPIO controller on their ARM EN7523 SoCs consists of two banks of 32
GPIOs

Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 arch/arm/boot/dts/en7523-evb.dts |  8 ++++++++
 arch/arm/boot/dts/en7523.dtsi    | 20 ++++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/arch/arm/boot/dts/en7523-evb.dts b/arch/arm/boot/dts/en7523-evb.dts
index 0a79f5f6c311..cd9cded5b564 100644
--- a/arch/arm/boot/dts/en7523-evb.dts
+++ b/arch/arm/boot/dts/en7523-evb.dts
@@ -33,3 +33,11 @@ &pcie0 {
 &pcie1 {
 	status = "okay";
 };
+
+&gpio0 {
+	status = "okay";
+};
+
+&gpio1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/en7523.dtsi b/arch/arm/boot/dts/en7523.dtsi
index b897fb6cffd2..8932e2ab96b6 100644
--- a/arch/arm/boot/dts/en7523.dtsi
+++ b/arch/arm/boot/dts/en7523.dtsi
@@ -3,6 +3,7 @@
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/en7523-clk.h>
+#include <dt-bindings/gpio/gpio.h>
 
 / {
 	interrupt-parent = <&gic>;
@@ -123,6 +124,25 @@ uart1: serial at 1fbf0000 {
 		status = "okay";
 	};
 
+	gpio0: gpio at 1fbf0200 {
+		compatible = "airoha,en7523-gpio";
+		reg = <0x1fbf0204 0x4>,
+		      <0x1fbf0200 0x4>,
+		      <0x1fbf0220 0x4>,
+		      <0x1fbf0214 0x4>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpio1: gpio at 1fbf0270 {
+		compatible = "airoha,en7523-gpio";
+		reg = <0x1fbf0270 0x4>,
+		      <0x1fbf0260 0x4>,
+		      <0x1fbf0264 0x4>,
+		      <0x1fbf0278 0x4>;
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
 
 	pcie0: pcie at 1fa91000 {
 		compatible = "airoha,en7523-pcie", "mediatek,mt7622-pcie";
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:14 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:14 +0100
Subject: [PATCH v9 11/13] dt-bindings: arm: airoha: Add binding for Airoha
 GPIO controller
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-12-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Airoha's GPIO controller on their ARM EN7523 SoCs consists of two banks of 32
GPIOs

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Rob Herring <robh at kernel.org>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 .../bindings/gpio/airoha,en7523-gpio.yaml     | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml

diff --git a/Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml b/Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml
new file mode 100644
index 000000000000..66c00ec85731
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/airoha,en7523-gpio.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/airoha,en7523-gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Airoha EN7523 GPIO controller
+
+maintainers:
+  - John Crispin <john at phrozen.org>
+
+description: |
+  Airoha's GPIO controller on their ARM EN7523 SoCs consists of two banks of 32
+  GPIOs.
+
+properties:
+  $nodename:
+    pattern: "^gpio@[0-9a-f]+$"
+
+  compatible:
+    items:
+      - const: airoha,en7523-gpio
+
+  reg:
+    description: |
+      The first tuple points to the input register.
+      The second and third tuple point to the direction registers
+      The fourth tuple points to the output register
+    maxItems: 4
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+required:
+  - compatible
+  - reg
+  - "#gpio-cells"
+  - gpio-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    gpio0: gpio at 1fbf0200 {
+        compatible = "airoha,en7523-gpio";
+        reg = <0x1fbf0204 0x4>,
+              <0x1fbf0200 0x4>,
+              <0x1fbf0220 0x4>,
+              <0x1fbf0214 0x4>;
+        gpio-controller;
+        #gpio-cells = <2>;
+    };
+
+    gpio1: gpio at 1fbf0270 {
+        compatible = "airoha,en7523-gpio";
+        reg = <0x1fbf0270 0x4>,
+              <0x1fbf0260 0x4>,
+              <0x1fbf0264 0x4>,
+              <0x1fbf0278 0x4>;
+        gpio-controller;
+        #gpio-cells = <2>;
+    };
+
+
+...
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:13 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:13 +0100
Subject: [PATCH v9 10/13] ARM: dts: Add PCIe support for Airoha EN7523
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-11-nbd@nbd.name>

This uses the MediaTek MT7622 PCIe driver, since the PCIe IP block is nearly
identical to the one in MT7622

Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 arch/arm/boot/dts/en7523-evb.dts |  8 +++++
 arch/arm/boot/dts/en7523.dtsi    | 60 ++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/arch/arm/boot/dts/en7523-evb.dts b/arch/arm/boot/dts/en7523-evb.dts
index 69754ef9a628..0a79f5f6c311 100644
--- a/arch/arm/boot/dts/en7523-evb.dts
+++ b/arch/arm/boot/dts/en7523-evb.dts
@@ -25,3 +25,11 @@ memory at 80000000 {
 		reg = <0x80000000 0x20000000>;
 	};
 };
+
+&pcie0 {
+	status = "okay";
+};
+
+&pcie1 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/en7523.dtsi b/arch/arm/boot/dts/en7523.dtsi
index 1e5280be02ba..b897fb6cffd2 100644
--- a/arch/arm/boot/dts/en7523.dtsi
+++ b/arch/arm/boot/dts/en7523.dtsi
@@ -122,4 +122,64 @@ uart1: serial at 1fbf0000 {
 		clock-frequency = <1843200>;
 		status = "okay";
 	};
+
+
+	pcie0: pcie at 1fa91000 {
+		compatible = "airoha,en7523-pcie", "mediatek,mt7622-pcie";
+		device_type = "pci";
+		reg = <0x1fa91000 0x1000>;
+		reg-names = "port0";
+		linux,pci-domain = <0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&scu EN7523_CLK_PCIE>;
+		clock-names = "sys_ck0";
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x20000000  0x20000000  0 0x8000000>;
+		status = "disabled";
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc0 0>,
+				<0 0 0 2 &pcie_intc0 1>,
+				<0 0 0 3 &pcie_intc0 2>,
+				<0 0 0 4 &pcie_intc0 3>;
+		pcie_intc0: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
+
+	pcie1: pcie at 1fa92000 {
+		compatible = "airoha,en7523-pcie", "mediatek,mt7622-pcie";
+		device_type = "pci";
+		reg = <0x1fa92000 0x1000>;
+		reg-names = "port1";
+		linux,pci-domain = <1>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pcie_irq";
+		clocks = <&scu EN7523_CLK_PCIE>;
+		clock-names = "sys_ck1";
+		bus-range = <0x00 0xff>;
+		ranges = <0x82000000 0 0x28000000  0x28000000  0 0x8000000>;
+		status = "disabled";
+
+		#interrupt-cells = <1>;
+		interrupt-map-mask = <0 0 0 7>;
+		interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+				<0 0 0 2 &pcie_intc1 1>,
+				<0 0 0 3 &pcie_intc1 2>,
+				<0 0 0 4 &pcie_intc1 3>;
+		pcie_intc1: interrupt-controller {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+		};
+	};
+
 };
-- 
2.32.0 (Apple Git-132)



From nbd at nbd.name  Sun Jan 30 06:51:15 2022
From: nbd at nbd.name (Felix Fietkau)
Date: Sun, 30 Jan 2022 15:51:15 +0100
Subject: [PATCH v9 12/13] gpio: Add support for Airoha EN7523 GPIO controller
In-Reply-To: <20220130145116.88406-1-nbd@nbd.name>
References: <20220130145116.88406-1-nbd@nbd.name>
Message-ID: <20220130145116.88406-13-nbd@nbd.name>

From: John Crispin <john at phrozen.org>

Airoha's GPIO controller on their ARM EN7523 SoCs consists of two banks of 32
GPIOs. Each instance in DT is for a single bank.

Acked-by: Bartosz Golaszewski <brgl at bgdev.pl>
Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Andy Shevchenko <andy.shevchenko at gmail.com>
Signed-off-by: John Crispin <john at phrozen.org>
Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 drivers/gpio/Kconfig       |  10 +++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-en7523.c | 137 +++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+)
 create mode 100644 drivers/gpio/gpio-en7523.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 60d9374c72c0..0e9aacbcb4bd 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -247,6 +247,16 @@ config GPIO_EM
 	help
 	  Say yes here to support GPIO on Renesas Emma Mobile SoCs.
 
+config GPIO_EN7523
+	tristate "Airoha GPIO support"
+	depends on ARCH_AIROHA
+	default ARCH_AIROHA
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	help
+	  Say Y or M here to support the GPIO controller block on the
+	  Airoha EN7523 SoC. It supports two banks of 32 GPIOs.
+
 config GPIO_EP93XX
 	def_bool y
 	depends on ARCH_EP93XX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 71ee9fc2ff83..d2269ee0948e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_GPIO_DLN2)			+= gpio-dln2.o
 obj-$(CONFIG_GPIO_DWAPB)		+= gpio-dwapb.o
 obj-$(CONFIG_GPIO_EIC_SPRD)		+= gpio-eic-sprd.o
 obj-$(CONFIG_GPIO_EM)			+= gpio-em.o
+obj-$(CONFIG_GPIO_EN7523)		+= gpio-en7523.o
 obj-$(CONFIG_GPIO_EP93XX)		+= gpio-ep93xx.o
 obj-$(CONFIG_GPIO_EXAR)			+= gpio-exar.o
 obj-$(CONFIG_GPIO_F7188X)		+= gpio-f7188x.o
diff --git a/drivers/gpio/gpio-en7523.c b/drivers/gpio/gpio-en7523.c
new file mode 100644
index 000000000000..f836a8db4c1d
--- /dev/null
+++ b/drivers/gpio/gpio-en7523.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/bits.h>
+#include <linux/gpio/driver.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+
+#define AIROHA_GPIO_MAX		32
+
+/**
+ * airoha_gpio_ctrl - Airoha GPIO driver data
+ * @gc: Associated gpio_chip instance.
+ * @data: The data register.
+ * @dir0: The direction register for the lower 16 pins.
+ * @dir1: The direction register for the higher 16 pins.
+ * @output: The output enable register.
+ */
+struct airoha_gpio_ctrl {
+	struct gpio_chip gc;
+	void __iomem *data;
+	void __iomem *dir[2];
+	void __iomem *output;
+};
+
+static struct airoha_gpio_ctrl *gc_to_ctrl(struct gpio_chip *gc)
+{
+	return container_of(gc, struct airoha_gpio_ctrl, gc);
+}
+
+static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio,
+			  int val, int out)
+{
+	struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
+	u32 dir = ioread32(ctrl->dir[gpio / 16]);
+	u32 output = ioread32(ctrl->output);
+	u32 mask = BIT((gpio % 16) * 2);
+
+	if (out) {
+		dir |= mask;
+		output |= BIT(gpio);
+	} else {
+		dir &= ~mask;
+		output &= ~BIT(gpio);
+	}
+
+	iowrite32(dir, ctrl->dir[gpio / 16]);
+
+	if (out)
+		gc->set(gc, gpio, val);
+
+	iowrite32(output, ctrl->output);
+
+	return 0;
+}
+
+static int airoha_dir_out(struct gpio_chip *gc, unsigned int gpio,
+			  int val)
+{
+	return airoha_dir_set(gc, gpio, val, 1);
+}
+
+static int airoha_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	return airoha_dir_set(gc, gpio, 0, 0);
+}
+
+static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc);
+	u32 dir = ioread32(ctrl->dir[gpio / 16]);
+	u32 mask = BIT((gpio % 16) * 2);
+
+	return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
+}
+
+static int airoha_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct airoha_gpio_ctrl *ctrl;
+	int err;
+
+	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl)
+		return -ENOMEM;
+
+	ctrl->data = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(ctrl->data))
+		return PTR_ERR(ctrl->data);
+
+	ctrl->dir[0] = devm_platform_ioremap_resource(pdev, 1);
+	if (IS_ERR(ctrl->dir[0]))
+		return PTR_ERR(ctrl->dir[0]);
+
+	ctrl->dir[1] = devm_platform_ioremap_resource(pdev, 2);
+	if (IS_ERR(ctrl->dir[1]))
+		return PTR_ERR(ctrl->dir[1]);
+
+	ctrl->output = devm_platform_ioremap_resource(pdev, 3);
+	if (IS_ERR(ctrl->output))
+		return PTR_ERR(ctrl->output);
+
+	err = bgpio_init(&ctrl->gc, dev, 4, ctrl->data, NULL,
+			 NULL, NULL, NULL, 0);
+	if (err)
+		return dev_err_probe(dev, err, "unable to init generic GPIO");
+
+	ctrl->gc.ngpio = AIROHA_GPIO_MAX;
+	ctrl->gc.owner = THIS_MODULE;
+	ctrl->gc.direction_output = airoha_dir_out;
+	ctrl->gc.direction_input = airoha_dir_in;
+	ctrl->gc.get_direction = airoha_get_dir;
+
+	return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl);
+}
+
+static const struct of_device_id airoha_gpio_of_match[] = {
+	{ .compatible = "airoha,en7523-gpio" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, airoha_gpio_of_match);
+
+static struct platform_driver airoha_gpio_driver = {
+	.driver = {
+		.name = "airoha-gpio",
+		.of_match_table	= airoha_gpio_of_match,
+	},
+	.probe = airoha_gpio_probe,
+};
+module_platform_driver(airoha_gpio_driver);
+
+MODULE_DESCRIPTION("Airoha GPIO support");
+MODULE_AUTHOR("John Crispin <john at phrozen.org>");
+MODULE_LICENSE("GPL v2");
-- 
2.32.0 (Apple Git-132)



From guoren at kernel.org  Sun Jan 30 06:57:09 2022
From: guoren at kernel.org (Guo Ren)
Date: Sun, 30 Jan 2022 22:57:09 +0800
Subject: [PATCH V4 08/17] riscv: compat: syscall: Add compat_sys_call_table
 implementation
In-Reply-To: <CAK8P3a12CygLFT7qoQ9K=sowvTgNpeRej6Zh6Pv2PL_e2zMhMQ@mail.gmail.com>
References: <20220129121728.1079364-1-guoren@kernel.org>
 <20220129121728.1079364-9-guoren@kernel.org>
 <CAK8P3a3JGP6fLVOyLgdNw2YpRSmArbEX8orUhRrN=GHmcdk=1g@mail.gmail.com>
 <CAJF2gTQQnrUFNQ85vvoMkpxnCWuMw8iXtPZOJwWGaEA9f+rTwA@mail.gmail.com>
 <CAK8P3a12CygLFT7qoQ9K=sowvTgNpeRej6Zh6Pv2PL_e2zMhMQ@mail.gmail.com>
Message-ID: <CAJF2gTSULHYYvAjfDvHiD-rJFsOy0-x58AKcD2upzpxaVf5sZQ@mail.gmail.com>

On Sun, Jan 30, 2022 at 7:32 PM Arnd Bergmann <arnd at arndb.de> wrote:
>
> On Sun, Jan 30, 2022 at 6:54 AM Guo Ren <guoren at kernel.org> wrote:
> > On Sun, Jan 30, 2022 at 6:41 AM Arnd Bergmann <arnd at arndb.de> wrote:
> > >
> > > I would make these endian-specific, and reverse them on big-endian
> > > architectures. That way it
> > > should be possible to share them across all compat architectures
> > > without needing the override
> > > option.
> > I hope it could be another patch. Because it's not clear to
> > _LITTLE_ENDIAN definition in archs.
> >
> > eg: Names could be __ORDER_LITTLE_ENDIAN__ CPU_LITTLE_ENDIAN
> > SYS_SUPPORTS_LITTLE_ENDIAN __LITTLE_ENDIAN
> >
> > riscv is little-endian, but no any LITTLE_ENDIAN definition.
> >
> > So let's keep them in the patch, first, Thx
>
> The correct way to do it is to check for CONFIG_CPU_BIG_ENDIAN,
> which works on all architectures. Since nothing else selects the
> __ARCH_WANT_COMPAT_* symbols, there is also no risk for
> regressions, so just use this and leave the #ifndef compat_arg_u64
> check in place.
Okay, got it.

>
>       Arnd



-- 
Best Regards
 Guo Ren

ML: https://lore.kernel.org/linux-csky/


From jic23 at kernel.org  Sun Jan 30 07:08:17 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 15:08:17 +0000
Subject: [PATCH] dt-bindings: iio: adc: atmel,sama5d2-adc: make
 atmel,trigger-edge-type non-mandatory
In-Reply-To: <YcIYOh6TmtVElt05@robh.at.kernel.org>
References: <20211217095401.583821-1-eugen.hristev@microchip.com>
 <YcIYOh6TmtVElt05@robh.at.kernel.org>
Message-ID: <20220130150803.1112cba7@jic23-huawei>

On Tue, 21 Dec 2021 14:08:58 -0400
Rob Herring <robh at kernel.org> wrote:

> On Fri, 17 Dec 2021 11:54:01 +0200, Eugen Hristev wrote:
> > The atmel,trigger-edge-type was never imposed by the driver.
> > Make things right and remove this property from the mandatory list.
> > This will not break existing nodes because according to the binding they
> > should have this property.
> > However, the driver does not impose it and it works without it, the property
> > selects the trigger type, and without it, the driver will have no trigger
> > available, which is the case on some boards which do not have access
> > to the trigger pin.
> > This will avoid generating this warning for example:
> > 
> > */arch/arm/boot/dts/at91-sama7g5ek.dt.yaml: adc at e1000000: 'atmel,trigger-edge-type' is a required property
> >   
> 
> Acked-by: Rob Herring <robh at kernel.org>

oops. I lost this one until doing a cleanup of patchwork.

Anyhow, now applied to the togreg branch of iio.git and pushed out as testing
for all the normal reasons.

Sorry for the delay!

Jonathan


From jic23 at kernel.org  Sun Jan 30 07:13:53 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 15:13:53 +0000
Subject: [PATCH] mailmap: Update email address for Cai Huoqing
In-Reply-To: <20211216164051.10225276@jic23-huawei>
References: <20211206025034.2729-1-caihuoqing@baidu.com>
 <20211216164051.10225276@jic23-huawei>
Message-ID: <20220130151353.1ddcd70e@jic23-huawei>

On Thu, 16 Dec 2021 16:41:00 +0000
Jonathan Cameron <jic23 at jic23.retrosnub.co.uk> wrote:

> On Mon, 6 Dec 2021 10:50:34 +0800
> Cai Huoqing <caihuoqing at baidu.com> wrote:
> 
> > The caihuoqing at baidu.com would be deprecated and use cai.huoqing at linux.dev
> > as the main email address.
> > 
> > Signed-off-by: Cai Huoqing <caihuoqing at baidu.com>  
> 
> Which maintainer wants to pick this one up?  I can take it via iio if that
> is fine with others.

Long enough for someone else to shout.

Applied to the togreg branch of iio.git and pushed out as testing so
0-day can poke some other stuff I've just applied.

Thanks,

Jonathan

> 
> Thanks,
> 
> Jonathan
> 
> 
> > ---
> >  .mailmap | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/.mailmap b/.mailmap
> > index a83599921b1a..f82b0378df7c 100644
> > --- a/.mailmap
> > +++ b/.mailmap
> > @@ -68,6 +68,7 @@ Boris Brezillon <bbrezillon at kernel.org> <boris.brezillon at bootlin.com>
> >  Boris Brezillon <bbrezillon at kernel.org> <boris.brezillon at free-electrons.com>
> >  Brian Avery <b.avery at hp.com>
> >  Brian King <brking at us.ibm.com>
> > +Cai Huoqing <cai.huoqing at linux.dev> <caihuoqing at baidu.com>
> >  Changbin Du <changbin.du at intel.com> <changbin.du at gmail.com>
> >  Changbin Du <changbin.du at intel.com> <changbin.du at intel.com>
> >  Chao Yu <chao at kernel.org> <chao2.yu at samsung.com>  
> 



From jic23 at kernel.org  Sun Jan 30 07:25:41 2022
From: jic23 at kernel.org (Jonathan Cameron)
Date: Sun, 30 Jan 2022 15:25:41 +0000
Subject: [PATCH 1/1] dt-bindings: iio: adc: at91-sama5d2: update
 maintainers entry
In-Reply-To: <6acdb66592baf395a77a431c0cb9a37b0f178097.1643554065.git.nicolas.ferre@microchip.com>
References: <6acdb66592baf395a77a431c0cb9a37b0f178097.1643554065.git.nicolas.ferre@microchip.com>
Message-ID: <20220130152541.5772d4ad@jic23-huawei>

On Sun, 30 Jan 2022 15:50:08 +0100
<nicolas.ferre at microchip.com> wrote:

> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Update the maintainers entry to match the changes made back in
> mid-2020 with 853fa48717c2 ("MAINTAINERS: adc: at91-sama5d2_adc:
> remove myself as co-maintainer").
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>
Applied to the togreg branch of iio.git and pushed out as testing
for 0-day to poke at other things I applied today.

Thanks,

Jonathan

> ---
> Hi,
> 
> Patch for new MAINTAINERS entry is here:
> https://lore.kernel.org/linux-arm-kernel/23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre at microchip.com/
> 
> Regards,
>   Nicolas
> 
>  Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
> index efed361215b4..9a2292e7defc 100644
> --- a/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/atmel,sama5d2-adc.yaml
> @@ -7,7 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
>  title: AT91 SAMA5D2 Analog to Digital Converter (ADC)
>  
>  maintainers:
> -  - Ludovic Desroches <ludovic.desroches at atmel.com>
>    - Eugen Hristev <eugen.hristev at microchip.com>
>  
>  properties:



From alexander.sverdlin at gmail.com  Sun Jan 30 07:25:02 2022
From: alexander.sverdlin at gmail.com (Alexander Sverdlin)
Date: Sun, 30 Jan 2022 16:25:02 +0100
Subject: [PATCH v2] ep93xx: clock: Fix UAF in ep93xx_clk_register_gate()
Message-ID: <20220130152502.236531-1-alexander.sverdlin@gmail.com>

arch/arm/mach-ep93xx/clock.c:154:2: warning: Use of memory after it is freed [clang-analyzer-unix.Malloc]
arch/arm/mach-ep93xx/clock.c:151:2: note: Taking true branch
if (IS_ERR(clk))
^
arch/arm/mach-ep93xx/clock.c:152:3: note: Memory is released
kfree(psc);
^~~~~~~~~~
arch/arm/mach-ep93xx/clock.c:154:2: note: Use of memory after it is freed
return &psc->hw;
^ ~~~~~~~~

Link: https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org/thread/B5YCO2NJEXINCYE26Y255LCVMO55BGWW/
Reported-by: kernel test robot <lkp at intel.com>
Fixes: 9645ccc7bd7a ("ep93xx: clock: convert in-place to COMMON_CLK")
Cc: stable at vger.kernel.org
Signed-off-by: Alexander Sverdlin <alexander.sverdlin at gmail.com>
---
Changelog:
v2:
- Thanks to Nick for the hint to use ERR_CAST()

 arch/arm/mach-ep93xx/clock.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index cc75087134d3..4aee14f18123 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -148,8 +148,10 @@ static struct clk_hw *ep93xx_clk_register_gate(const char *name,
 	psc->lock = &clk_lock;
 
 	clk = clk_register(NULL, &psc->hw);
-	if (IS_ERR(clk))
+	if (IS_ERR(clk)) {
 		kfree(psc);
+		return ERR_CAST(clk);
+	}
 
 	return &psc->hw;
 }
-- 
2.34.1



From linux at roeck-us.net  Sun Jan 30 09:12:10 2022
From: linux at roeck-us.net (Guenter Roeck)
Date: Sun, 30 Jan 2022 09:12:10 -0800
Subject: [patch V3 28/35] PCI/MSI: Simplify pci_irq_get_affinity()
In-Reply-To: <20211210221814.900929381@linutronix.de>
References: <20211210221642.869015045@linutronix.de>
 <20211210221814.900929381@linutronix.de>
Message-ID: <20220130171210.GA3545402@roeck-us.net>

On Fri, Dec 10, 2021 at 11:19:26PM +0100, Thomas Gleixner wrote:
> From: Thomas Gleixner <tglx at linutronix.de>
> 
> Replace open coded MSI descriptor chasing and use the proper accessor
> functions instead.
> 
> Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
> Reviewed-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
> Reviewed-by: Jason Gunthorpe <jgg at nvidia.com>

This patch results in the following runtime warning when booting x86
(32 bit) nosmp images from NVME in qemu.

[   14.825482] nvme nvme0: 1/0/0 default/read/poll queues
ILLOPC: ca7c6d10: 0f 0b
[   14.826188] ------------[ cut here ]------------
[   14.826307] WARNING: CPU: 0 PID: 7 at drivers/pci/msi/msi.c:1114 pci_irq_get_affinity+0x80/0x90
[   14.826455] Modules linked in:
[   14.826640] CPU: 0 PID: 7 Comm: kworker/u2:0 Not tainted 5.17.0-rc1-00419-g1d2d8baaf053 #1
[   14.826797] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014
[   14.827132] Workqueue: nvme-reset-wq nvme_reset_work
[   14.827336] EIP: pci_irq_get_affinity+0x80/0x90
[   14.827452] Code: e8 d5 30 af ff 85 c0 75 bd 90 0f 0b 31 c0 5b 5e 5d c3 8d b4 26 00 00 00 00 90 5b b8 24 32 7e cb 5e 5d c3 8d b4 26 00 00 00 00 <0f> 0b eb e0 8d b4 26 00 00 00 00 8d 74 26 00 90 55 89 e5 57 56 53
[   14.827717] EAX: 00000000 EBX: c18ba000 ECX: 00000000 EDX: c297c210
[   14.827816] ESI: 00000001 EDI: c18ba000 EBP: c1247e24 ESP: c1247e1c
[   14.827924] DS: 007b ES: 007b FS: 0000 GS: 0000 SS: 0068 EFLAGS: 00000246
[   14.828110] CR0: 80050033 CR2: ffda9000 CR3: 0b8ad000 CR4: 000006d0
[   14.828268] Call Trace:
[   14.828554]  blk_mq_pci_map_queues+0x26/0x70
[   14.828710]  nvme_pci_map_queues+0x75/0xc0
[   14.828808]  blk_mq_update_queue_map+0x86/0xa0
[   14.828891]  blk_mq_alloc_tag_set+0xf3/0x390
[   14.828965]  ? nvme_wait_freeze+0x3d/0x50
[   14.829137]  nvme_reset_work+0xd02/0x1120
[   14.829269]  ? lock_acquire+0xc3/0x290
[   14.829435]  process_one_work+0x1ed/0x490
[   14.829569]  worker_thread+0x15e/0x3c0
[   14.829665]  kthread+0xd3/0x100
[   14.829729]  ? process_one_work+0x490/0x490
[   14.829799]  ? kthread_complete_and_exit+0x20/0x20
[   14.829890]  ret_from_fork+0x1c/0x28

Bisect results below.

#regzbot introduced: f48235900182d6

Guenter

---
# bad: [e783362eb54cd99b2cac8b3a9aeac942e6f6ac07] Linux 5.17-rc1
# good: [df0cc57e057f18e44dac8e6c18aba47ab53202f9] Linux 5.16
git bisect start 'v5.17-rc1' 'v5.16'
# good: [fef8dfaea9d6c444b6c2174b3a2b0fca4d226c5e] Merge tag 'regulator-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator
git bisect good fef8dfaea9d6c444b6c2174b3a2b0fca4d226c5e
# bad: [3ceff4ea07410763d5d4cccd60349bf7691e7e61] Merge tag 'sound-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
git bisect bad 3ceff4ea07410763d5d4cccd60349bf7691e7e61
# good: [57ea81971b7296b42fc77424af44c5915d3d4ae2] Merge tag 'usb-5.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
git bisect good 57ea81971b7296b42fc77424af44c5915d3d4ae2
# bad: [feb7a43de5ef625ad74097d8fd3481d5dbc06a59] Merge tag 'irq-msi-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
git bisect bad feb7a43de5ef625ad74097d8fd3481d5dbc06a59
# good: [ce990f1de0bc6ff3de43d385e0985efa980fba24] Merge tag 'for-linus-5.17-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
git bisect good ce990f1de0bc6ff3de43d385e0985efa980fba24
# good: [4afd2a9355a9deb16ea42b896820dacf49843a8f] Merge branches 'clk-ingenic' and 'clk-mediatek' into clk-next
git bisect good 4afd2a9355a9deb16ea42b896820dacf49843a8f
# good: [455e73a07f6e288b0061dfcf4fcf54fa9fe06458] Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux
git bisect good 455e73a07f6e288b0061dfcf4fcf54fa9fe06458
# bad: [f2948df5f87a722591499da60ab91c611422f755] x86/pci/xen: Use msi_for_each_desc()
git bisect bad f2948df5f87a722591499da60ab91c611422f755
# good: [93296cd1325d1d9afede60202d8833011c9001f2] PCI/MSI: Allocate MSI device data on first use
git bisect good 93296cd1325d1d9afede60202d8833011c9001f2
# good: [82ff8e6b78fc4587a4255301f0a283506daf11b6] PCI/MSI: Use msi_get_virq() in pci_get_vector()
git bisect good 82ff8e6b78fc4587a4255301f0a283506daf11b6
# bad: [125282cd4f33ecd53a24ae4807409da0e5e90fd4] genirq/msi: Move descriptor list to struct msi_device_data
git bisect bad 125282cd4f33ecd53a24ae4807409da0e5e90fd4
# bad: [065afdc9c521f05c53f226dabe5dda2d30294d65] iommu/arm-smmu-v3: Use msi_get_virq()
git bisect bad 065afdc9c521f05c53f226dabe5dda2d30294d65
# bad: [f6632bb2c1454b857adcd131320379ec16fd8666] dmaengine: mv_xor_v2: Get rid of msi_desc abuse
git bisect bad f6632bb2c1454b857adcd131320379ec16fd8666
# bad: [f48235900182d64537c6e8f8dc0932b57a1a0638] PCI/MSI: Simplify pci_irq_get_affinity()
git bisect bad f48235900182d64537c6e8f8dc0932b57a1a0638
# first bad commit: [f48235900182d64537c6e8f8dc0932b57a1a0638] PCI/MSI: Simplify pci_irq_get_affinity()


From daniel.lezcano at linaro.org  Sun Jan 30 13:02:09 2022
From: daniel.lezcano at linaro.org (Daniel Lezcano)
Date: Sun, 30 Jan 2022 22:02:09 +0100
Subject: [PATCH v1 7/7] dtpm/soc/rk3399: Add the ability to unload the module
In-Reply-To: <20220130210210.549877-1-daniel.lezcano@linaro.org>
References: <20220130210210.549877-1-daniel.lezcano@linaro.org>
Message-ID: <20220130210210.549877-7-daniel.lezcano@linaro.org>

The dtpm hierarchy can now be removed with the
dtpm_destroy_hierarchy() function. Add the module_exit() callback so
the module can be unloaded by removing the previously created
hierarchy.

Signed-off-by: Daniel Lezcano <daniel.lezcano at linaro.org>
---
 drivers/soc/rockchip/dtpm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/soc/rockchip/dtpm.c b/drivers/soc/rockchip/dtpm.c
index ebebb748488b..5a23784b5221 100644
--- a/drivers/soc/rockchip/dtpm.c
+++ b/drivers/soc/rockchip/dtpm.c
@@ -52,6 +52,12 @@ static int __init rockchip_dtpm_init(void)
 }
 module_init(rockchip_dtpm_init);
 
+static void __exit rockchip_dtpm_exit(void)
+{
+	return dtpm_destroy_hierarchy();
+}
+module_exit(rockchip_dtpm_exit);
+
 MODULE_SOFTDEP("pre: panfrost cpufreq-dt");
 MODULE_DESCRIPTION("Rockchip DTPM driver");
 MODULE_LICENSE("GPL");
-- 
2.25.1



From colin.foster at in-advantage.com  Sun Jan 30 13:30:22 2022
From: colin.foster at in-advantage.com (Colin Foster)
Date: Sun, 30 Jan 2022 13:30:22 -0800
Subject: [RFC v6 net-next 1/9] pinctrl: ocelot: allow pinctrl-ocelot to
 be loaded as a module
In-Reply-To: <CACRpkdbFOB-uoVKiG0qTcHDa45bNjwdkP=AzAB7kU2Car37QYg@mail.gmail.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
 <20220129220221.2823127-2-colin.foster@in-advantage.com>
 <CACRpkdbFOB-uoVKiG0qTcHDa45bNjwdkP=AzAB7kU2Car37QYg@mail.gmail.com>
Message-ID: <20220130213022.GA2914669@euler>

On Sun, Jan 30, 2022 at 01:30:57AM +0100, Linus Walleij wrote:
> On Sat, Jan 29, 2022 at 11:02 PM Colin Foster
> <colin.foster at in-advantage.com> wrote:
> 
> > Work is being done to allow external control of Ocelot chips. When pinctrl
> > drivers are used internally, it wouldn't make much sense to allow them to
> > be loaded as modules. In the case where the Ocelot chip is controlled
> > externally, this scenario becomes practical.
> >
> > Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
> 
> Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
> 
> This is fine to merge through the netdev tree, if you prefer I merge patches
> 1 & 2 to the pinctrl tree just tell me.

I'd thought about splitting these out, but they really don't make much
sense to be anywhere until the MFD is added in. The big one I needed in
pinctrl was the regmap conversions that are in 5.17-rc1, so I'm hopeful
I won't need to bounce back and forth much moving forward.

Thanks for reviewing!

> 
> Yours,
> Linus Walleij


From mr.bossman075 at gmail.com  Sun Jan 30 14:03:22 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 30 Jan 2022 17:03:22 -0500
Subject: [PATCH v2 1/4] ARM: dtsi: suniv: F1c100s add clock and reset macros
Message-ID: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>

Include clock and reset macros and replace magic numbers.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
 arch/arm/boot/dts/suniv-f1c100s.dtsi | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
index 6100d3b75f61..953228cc8d52 100644
--- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
+++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
@@ -4,6 +4,9 @@
  * Copyright 2018 Mesih Kilinc <mesihkilinc at gmail.com>
  */
 
+#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
+#include <dt-bindings/reset/suniv-ccu-f1c100s.h>
+
 / {
 	#address-cells = <1>;
 	#size-cells = <1>;
@@ -82,7 +85,7 @@ pio: pinctrl at 1c20800 {
 			compatible = "allwinner,suniv-f1c100s-pinctrl";
 			reg = <0x01c20800 0x400>;
 			interrupts = <38>, <39>, <40>;
-			clocks = <&ccu 37>, <&osc24M>, <&osc32k>;
+			clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>;
 			clock-names = "apb", "hosc", "losc";
 			gpio-controller;
 			interrupt-controller;
@@ -114,8 +117,8 @@ uart0: serial at 1c25000 {
 			interrupts = <1>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&ccu 38>;
-			resets = <&ccu 24>;
+			clocks = <&ccu CLK_BUS_UART0>;
+			resets = <&ccu RST_BUS_UART0>;
 			status = "disabled";
 		};
 
@@ -125,8 +128,8 @@ uart1: serial at 1c25400 {
 			interrupts = <2>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&ccu 39>;
-			resets = <&ccu 25>;
+			clocks = <&ccu CLK_BUS_UART1>;
+			resets = <&ccu RST_BUS_UART1>;
 			status = "disabled";
 		};
 
@@ -136,8 +139,8 @@ uart2: serial at 1c25800 {
 			interrupts = <3>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
-			clocks = <&ccu 40>;
-			resets = <&ccu 26>;
+			clocks = <&ccu CLK_BUS_UART2>;
+			resets = <&ccu RST_BUS_UART2>;
 			status = "disabled";
 		};
 	};
-- 
2.34.1



From mr.bossman075 at gmail.com  Sun Jan 30 14:03:23 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 30 Jan 2022 17:03:23 -0500
Subject: [PATCH v2 2/4] dt-bindings: mmc: sunxi: Add Allwinner F1c100s
 compatibles
In-Reply-To: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
References: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
Message-ID: <20220130220325.1983918-2-Mr.Bossman075@gmail.com>

Add binding for F1c100s's mmc controller.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1 -> V2:
* New commit
---
 .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml       | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
index 4f62ad6ce50c..76137132500d 100644
--- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
+++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -55,6 +55,9 @@ properties:
       - items:
           - const: allwinner,sun50i-h616-mmc
           - const: allwinner,sun50i-a100-mmc
+      - items:
+          - const: allwinner,suniv-f1c100s-mmc
+          - const: allwinner,sun7i-a20-mmc
 
   reg:
     maxItems: 1
-- 
2.34.1



From mr.bossman075 at gmail.com  Sun Jan 30 14:03:24 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 30 Jan 2022 17:03:24 -0500
Subject: [PATCH v2 3/4] ARM: dtsi: suniv: Add mmc to f1c100s dtsi.
In-Reply-To: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
References: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
Message-ID: <20220130220325.1983918-3-Mr.Bossman075@gmail.com>

Add mmc0 and 1 for f1c100s dtsi.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1 -> V2:
* Split patch
---
 arch/arm/boot/dts/suniv-f1c100s.dtsi | 41 ++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/arch/arm/boot/dts/suniv-f1c100s.dtsi b/arch/arm/boot/dts/suniv-f1c100s.dtsi
index 953228cc8d52..60fa56c278a8 100644
--- a/arch/arm/boot/dts/suniv-f1c100s.dtsi
+++ b/arch/arm/boot/dts/suniv-f1c100s.dtsi
@@ -96,6 +96,11 @@ uart0_pe_pins: uart0-pe-pins {
 				pins = "PE0", "PE1";
 				function = "uart0";
 			};
+
+			mmc0_pins: mmc0-pins {
+				pins = "PF0", "PF1", "PF2", "PF3", "PF4", "PF5";
+				function = "mmc0";
+			};
 		};
 
 		timer at 1c20c00 {
@@ -111,6 +116,42 @@ wdt: watchdog at 1c20ca0 {
 			reg = <0x01c20ca0 0x20>;
 		};
 
+		mmc0: mmc at 1c0f000 {
+			compatible = "allwinner,suniv-f1c100s-mmc",
+				     "allwinner,sun7i-a20-mmc";
+			reg = <0x01c0f000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC0>,
+				 <&ccu CLK_MMC0>,
+				 <&ccu CLK_MMC0_OUTPUT>,
+				 <&ccu CLK_MMC0_SAMPLE>;
+			clock-names = "ahb", "mmc", "output", "sample";
+			resets = <&ccu RST_BUS_MMC0>;
+			reset-names = "ahb";
+			interrupts = <23>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mmc0_pins>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
+		mmc1: mmc at 1c10000 {
+			compatible = "allwinner,suniv-f1c100s-mmc",
+				     "allwinner,sun7i-a20-mmc";
+			reg = <0x01c10000 0x1000>;
+			clocks = <&ccu CLK_BUS_MMC1>,
+				 <&ccu CLK_MMC1>,
+				 <&ccu CLK_MMC1_OUTPUT>,
+				 <&ccu CLK_MMC1_SAMPLE>;
+			clock-names = "ahb", "mmc", "output", "sample";
+			resets = <&ccu RST_BUS_MMC1>;
+			reset-names = "ahb";
+			interrupts = <24>;
+			status = "disabled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+		};
+
 		uart0: serial at 1c25000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0x01c25000 0x400>;
-- 
2.34.1



From mr.bossman075 at gmail.com  Sun Jan 30 14:03:25 2022
From: mr.bossman075 at gmail.com (Jesse Taube)
Date: Sun, 30 Jan 2022 17:03:25 -0500
Subject: [PATCH v2 4/4] ARM: dts: suniv: Enable mmc for f1c100s.
In-Reply-To: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
References: <20220130220325.1983918-1-Mr.Bossman075@gmail.com>
Message-ID: <20220130220325.1983918-4-Mr.Bossman075@gmail.com>

Enable mmc0 in f1c100s-licheepi-nano device tree.

Signed-off-by: Jesse Taube <Mr.Bossman075 at gmail.com>
---
V1 -> V2:
* New patch
---
 arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
index a1154e6c7cb5..c856a6a20dc8 100644
--- a/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
+++ b/arch/arm/boot/dts/suniv-f1c100s-licheepi-nano.dts
@@ -24,3 +24,9 @@ &uart0 {
 	pinctrl-0 = <&uart0_pe_pins>;
 	status = "okay";
 };
+
+&mmc0 {
+	bus-width = <4>;
+	broken-cd;
+	status = "okay";
+};
-- 
2.34.1



From colin.i.king at gmail.com  Sun Jan 30 15:05:15 2022
From: colin.i.king at gmail.com (Colin Ian King)
Date: Sun, 30 Jan 2022 23:05:15 +0000
Subject: [PATCH] crypto: sl3516: remove redundant initializations of pointers
 in_sg and out_sg
Message-ID: <20220130230515.8338-1-colin.i.king@gmail.com>

Pointers in_sg and out_sg are being initialized with values that are
never read, they are being re-assigned the same values later on. The
initializations are redundant, remove them in preference to the later
assignments that are closer to when the pointers are being used.

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/crypto/gemini/sl3516-ce-cipher.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/gemini/sl3516-ce-cipher.c b/drivers/crypto/gemini/sl3516-ce-cipher.c
index c1c2b1d86663..53e3fefb81de 100644
--- a/drivers/crypto/gemini/sl3516-ce-cipher.c
+++ b/drivers/crypto/gemini/sl3516-ce-cipher.c
@@ -23,8 +23,8 @@ static bool sl3516_ce_need_fallback(struct skcipher_request *areq)
 	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
 	struct sl3516_ce_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
 	struct sl3516_ce_dev *ce = op->ce;
-	struct scatterlist *in_sg = areq->src;
-	struct scatterlist *out_sg = areq->dst;
+	struct scatterlist *in_sg;
+	struct scatterlist *out_sg;
 	struct scatterlist *sg;
 
 	if (areq->cryptlen == 0 || areq->cryptlen % 16) {
-- 
2.34.1



From colin.i.king at gmail.com  Sun Jan 30 15:11:11 2022
From: colin.i.king at gmail.com (Colin Ian King)
Date: Sun, 30 Jan 2022 23:11:11 +0000
Subject: [PATCH] media: mtk-jpeg: remove redundant initialization of variable
 plane_fmt
Message-ID: <20220130231111.8563-1-colin.i.king@gmail.com>

The variable plane_fmt is being initialized with a value that is never
read, it is being re-assigned a new value on each iteration of a for
loop. The initialization is redundant and can be removed.

Signed-off-by: Colin Ian King <colin.i.king at gmail.com>
---
 drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
index f332beb06d51..b334bbb2e682 100644
--- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.c
@@ -681,7 +681,7 @@ static int mtk_jpeg_buf_prepare(struct vb2_buffer *vb)
 {
 	struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
 	struct mtk_jpeg_q_data *q_data = NULL;
-	struct v4l2_plane_pix_format plane_fmt = {};
+	struct v4l2_plane_pix_format plane_fmt;
 	int i;
 
 	q_data = mtk_jpeg_get_q_data(ctx, vb->vb2_queue->type);
-- 
2.34.1



From martin.juecker at gmail.com  Sun Jan 30 15:21:22 2022
From: martin.juecker at gmail.com (Martin =?iso-8859-1?Q?J=FCcker?=)
Date: Mon, 31 Jan 2022 00:21:22 +0100
Subject: [PATCH] pinctrl: samsung: improve wake irq info on console
Message-ID: <20220130232122.GA119248@adroid>

Improve the wake irq message by also printing the bank name and hwirq
number that matches this irq number.

Signed-off-by: Martin J?cker <martin.juecker at gmail.com>
---
 drivers/pinctrl/samsung/pinctrl-exynos.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index 0489c899b401..30293fc23354 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -344,7 +344,8 @@ static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
 	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 	unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
 
-	pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
+	pr_info("wake %s for irq %u (%s-%lu)\n", on ? "enabled" : "disabled",
+		irqd->irq, bank->name, irqd->hwirq);
 
 	if (!on)
 		*our_chip->eint_wake_mask_value |= bit;
-- 
2.25.1



From ricarkol at google.com  Sun Jan 30 19:40:26 2022
From: ricarkol at google.com (Ricardo Koller)
Date: Sun, 30 Jan 2022 19:40:26 -0800
Subject: [RFC PATCH v4 02/26] KVM: arm64: Save ID registers' sanitized
 value per guest
In-Reply-To: <CAAeT=FyqPX_XQ+LDuRBZhApeiWD4s81bTMe=qiKDOZkBWm5ARg@mail.gmail.com>
References: <20220106042708.2869332-1-reijiw@google.com>
 <20220106042708.2869332-3-reijiw@google.com>
 <YfDaiUbSkpi9/5YY@google.com>
 <CAAeT=FzNSvzz-Ok0Ka95=kkdDGsAMmzf9xiRfD5gYCdvmEfifg@mail.gmail.com>
 <CAOHnOrwBoQncTPngxqWgD_mEDWT6AwcmB_QC=j-eUPY2fwHa2Q@mail.gmail.com>
 <CAAeT=FyqPX_XQ+LDuRBZhApeiWD4s81bTMe=qiKDOZkBWm5ARg@mail.gmail.com>
Message-ID: <YfdaKpBqFkULxgX/@google.com>

On Fri, Jan 28, 2022 at 09:52:21PM -0800, Reiji Watanabe wrote:
> Hi Ricardo,
> 
> > > > > +
> > > > > +/*
> > > > > + * Set the guest's ID registers that are defined in sys_reg_descs[]
> > > > > + * with ID_SANITISED() to the host's sanitized value.
> > > > > + */
> > > > > +void set_default_id_regs(struct kvm *kvm)
> > > > > +{
> > > > > +     int i;
> > > > > +     u32 id;
> > > > > +     const struct sys_reg_desc *rd;
> > > > > +     u64 val;
> > > > > +
> > > > > +     for (i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) {
> > > > > +             rd = &sys_reg_descs[i];
> > > > > +             if (rd->access != access_id_reg)
> > > > > +                     /* Not ID register, or hidden/reserved ID register */
> > > > > +                     continue;
> > > > > +
> > > > > +             id = reg_to_encoding(rd);
> > > > > +             if (WARN_ON_ONCE(!is_id_reg(id)))
> > > > > +                     /* Shouldn't happen */
> > > > > +                     continue;
> > > > > +
> > > > > +             val = read_sanitised_ftr_reg(id);
> > > >
> > > > I'm a bit confused. Shouldn't the default+sanitized values already use
> > > > arm64_ftr_bits_kvm (instead of arm64_ftr_regs)?
> > >
> > > I'm not sure if I understand your question.
> > > arm64_ftr_bits_kvm is used for feature support checkings when
> > > userspace tries to modify a value of ID registers.
> > > With this patch, KVM just saves the sanitized values in the kvm's
> > > buffer, but userspace is still not allowed to modify values of ID
> > > registers yet.
> > > I hope it answers your question.
> >
> > Based on the previous commit I was assuming that some registers, like
> > id_aa64dfr0,
> > would default to the overwritten values as the sanitized values. More
> > specifically: if
> > userspace doesn't modify any ID reg, shouldn't the defaults have the
> > KVM overwritten
> > values (arm64_ftr_bits_kvm)?
> 
> arm64_ftr_bits_kvm doesn't have arm64_ftr_reg but arm64_ftr_bits,
> and arm64_ftr_bits_kvm doesn't have the sanitized values.
> 
> Thanks,

Hey Reiji,

Sorry, I wasn't very clear. This is what I meant.

If I set DEBUGVER to 0x5 (w/ FTR_EXACT) using this patch on top of the
series:

 static struct arm64_ftr_bits ftr_id_aa64dfr0_kvm[MAX_FTR_BITS_LEN] = {
        S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMUVER_SHIFT, 4, 0),
-       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x6),
+       ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_DEBUGVER_SHIFT, 4, 0x5),

it means that userspace would not be able to set DEBUGVER to anything
but 0x5. But I'm not sure what it should mean for the default KVM value
of DEBUGVER, specifically the value calculated in set_default_id_regs().
As it is, KVM is still setting the guest-visible value to 0x6, and my
"desire" to only allow booting VMs with DEBUGVER=0x5 is being ignored: I
booted a VM and the DEBUGVER value from inside is still 0x6. I was
expecting it to not boot, or to show a warning.

I think this has some implications for migrations. It would not be
possible to migrate the example VM on the patched kernel from above: you
can boot a VM with DEBUGVER=0x5 but you can't migrate it.

Thanks,
Ricardo


From lkp at intel.com  Sun Jan 30 20:35:59 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 12:35:59 +0800
Subject: [arm-platforms:irq/irq_chip_ro 4/9]
 drivers/irqchip/irq-ts4800.c:55:9: error: implicit declaration of function
 'seq_printf'; did you mean 'bstr_printf'?
Message-ID: <202201311240.tTRiqGNX-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 75f43f84cf6ef6e3a967aa84352173e37a83111d [4/9] irqchip/ts4800: Switch to dynamic chip name output
config: alpha-allmodconfig (https://download.01.org/0day-ci/archive/20220131/202201311240.tTRiqGNX-lkp at intel.com/config)
compiler: alpha-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=75f43f84cf6ef6e3a967aa84352173e37a83111d
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 75f43f84cf6ef6e3a967aa84352173e37a83111d
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=alpha SHELL=/bin/bash drivers/irqchip/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-ts4800.c: In function 'ts4800_irq_print_chip':
>> drivers/irqchip/irq-ts4800.c:55:9: error: implicit declaration of function 'seq_printf'; did you mean 'bstr_printf'? [-Werror=implicit-function-declaration]
      55 |         seq_printf(p, "%s", dev_name(&data->pdev->dev));
         |         ^~~~~~~~~~
         |         bstr_printf
   cc1: some warnings being treated as errors


vim +55 drivers/irqchip/irq-ts4800.c

    50	
    51	static void ts4800_irq_print_chip(struct irq_data *d, struct seq_file *p)
    52	{
    53		struct ts4800_irq_data *data = irq_data_get_irq_chip_data(d);
    54	
  > 55		seq_printf(p, "%s", dev_name(&data->pdev->dev));
    56	}
    57	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan 30 20:46:15 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 12:46:15 +0800
Subject: [arm-platforms:irq/irq_chip_ro 5/9]
 drivers/irqchip/irq-versatile-fpga.c:150:39: warning: passing argument 2 of
 'irq_set_chip_and_handler' discards 'const' qualifier from pointer target
 type
Message-ID: <202201311206.w5a8z0pV-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 2c12b32e6767380c697a9dd8bf032c643228485c [5/9] irqchip/versatile-fpga: Switch to dynamic chip name output
config: arm-integrator_defconfig (https://download.01.org/0day-ci/archive/20220131/202201311206.w5a8z0pV-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=2c12b32e6767380c697a9dd8bf032c643228485c
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 2c12b32e6767380c697a9dd8bf032c643228485c
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash drivers/irqchip/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All warnings (new ones prefixed by >>):

   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irq_print_chip':
   drivers/irqchip/irq-versatile-fpga.c:72:9: error: implicit declaration of function 'seq_printf'; did you mean 'scnprintf'? [-Werror=implicit-function-declaration]
      72 |         seq_printf(p, "%s", f->np->name);
         |         ^~~~~~~~~~
         |         scnprintf
   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irqdomain_map':
>> drivers/irqchip/irq-versatile-fpga.c:150:39: warning: passing argument 2 of 'irq_set_chip_and_handler' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
     150 |         irq_set_chip_and_handler(irq, &fpga_chip,
         |                                       ^~~~~~~~~~
   In file included from drivers/irqchip/irq-versatile-fpga.c:6:
   include/linux/irq.h:718:80: note: expected 'struct irq_chip *' but argument is of type 'const struct irq_chip *'
     718 | static inline void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *chip,
         |                                                               ~~~~~~~~~~~~~~~~~^~~~
   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irq_init':
   drivers/irqchip/irq-versatile-fpga.c:187:30: error: 'irq_start' undeclared (first use in this function); did you mean 'irq_stat'?
     187 |                         if (!irq_start)
         |                              ^~~~~~~~~
         |                              irq_stat
   drivers/irqchip/irq-versatile-fpga.c:187:30: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors


vim +150 drivers/irqchip/irq-versatile-fpga.c

   140	
   141	static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
   142			irq_hw_number_t hwirq)
   143	{
   144		struct fpga_irq_data *f = d->host_data;
   145	
   146		/* Skip invalid IRQs, only register handlers for the real ones */
   147		if (!(f->valid & BIT(hwirq)))
   148			return -EPERM;
   149		irq_set_chip_data(irq, f);
 > 150		irq_set_chip_and_handler(irq, &fpga_chip,
   151					handle_level_irq);
   152		irq_set_probe(irq);
   153		return 0;
   154	}
   155	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan 30 21:38:03 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 13:38:03 +0800
Subject: [arm-platforms:irq/irq_chip_ro 1/9] drivers/irqchip/irq-gic.c:405:3:
 error: implicit declaration of function 'seq_printf'
Message-ID: <202201311355.HUXeoGa5-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 6a55685f591b540217d642fc5e0799634ee29a91 [1/9] irqchip/gic: Switch to dynamic chip name output
config: arm64-randconfig-r024-20220131 (https://download.01.org/0day-ci/archive/20220131/202201311355.HUXeoGa5-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project f1c18acb07aa40f42b87b70462a6d1ab77a4825c)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=6a55685f591b540217d642fc5e0799634ee29a91
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 6a55685f591b540217d642fc5e0799634ee29a91
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/irqchip/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-gic.c:405:3: error: implicit declaration of function 'seq_printf' [-Werror,-Wimplicit-function-declaration]
                   seq_printf(p, "%s", gic->chip.parent_device->of_node->name);
                   ^
   1 error generated.


vim +/seq_printf +405 drivers/irqchip/irq-gic.c

   399	
   400	static void gic_irq_print_chip(struct irq_data *d, struct seq_file *p)
   401	{
   402		struct gic_chip_data *gic = irq_data_get_irq_chip_data(d);
   403	
   404		if (gic->chip.parent_device)
 > 405			seq_printf(p, "%s", gic->chip.parent_device->of_node->name);
   406		else if (static_branch_likely(&supports_deactivate_key) &&
   407			 gic == &gic_data[0])
   408			seq_printf(p, "GICv2");
   409		else
   410			seq_printf(p, "GIC-%d", (int)(gic - &gic_data[0]));
   411	}
   412	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan 30 21:38:00 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 13:38:00 +0800
Subject: [arm-platforms:irq/irq_chip_ro 4/9]
 drivers/irqchip/irq-ts4800.c:55:2: error: implicit declaration of function
 'seq_printf'
Message-ID: <202201311353.3t1CnmBZ-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 75f43f84cf6ef6e3a967aa84352173e37a83111d [4/9] irqchip/ts4800: Switch to dynamic chip name output
config: riscv-buildonly-randconfig-r005-20220131 (https://download.01.org/0day-ci/archive/20220131/202201311353.3t1CnmBZ-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2cdbaca3943a4d6259119f185656328bd3805b68)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install riscv cross compiling tool for clang build
        # apt-get install binutils-riscv64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=75f43f84cf6ef6e3a967aa84352173e37a83111d
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 75f43f84cf6ef6e3a967aa84352173e37a83111d
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash drivers/irqchip/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-ts4800.c:55:2: error: implicit declaration of function 'seq_printf' [-Werror,-Wimplicit-function-declaration]
           seq_printf(p, "%s", dev_name(&data->pdev->dev));
           ^
   1 error generated.


vim +/seq_printf +55 drivers/irqchip/irq-ts4800.c

    50	
    51	static void ts4800_irq_print_chip(struct irq_data *d, struct seq_file *p)
    52	{
    53		struct ts4800_irq_data *data = irq_data_get_irq_chip_data(d);
    54	
  > 55		seq_printf(p, "%s", dev_name(&data->pdev->dev));
    56	}
    57	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From lkp at intel.com  Sun Jan 30 22:09:11 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 14:09:11 +0800
Subject: [arm-platforms:irq/irq_chip_ro 5/9]
 drivers/irqchip/irq-versatile-fpga.c:72:9: error: implicit declaration of
 function 'seq_printf'; did you mean 'scnprintf'?
Message-ID: <202201311454.gbUcvZPq-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 2c12b32e6767380c697a9dd8bf032c643228485c [5/9] irqchip/versatile-fpga: Switch to dynamic chip name output
config: arm-integrator_defconfig (https://download.01.org/0day-ci/archive/20220131/202201311454.gbUcvZPq-lkp at intel.com/config)
compiler: arm-linux-gnueabi-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=2c12b32e6767380c697a9dd8bf032c643228485c
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 2c12b32e6767380c697a9dd8bf032c643228485c
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irq_print_chip':
>> drivers/irqchip/irq-versatile-fpga.c:72:9: error: implicit declaration of function 'seq_printf'; did you mean 'scnprintf'? [-Werror=implicit-function-declaration]
      72 |         seq_printf(p, "%s", f->np->name);
         |         ^~~~~~~~~~
         |         scnprintf
   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irqdomain_map':
   drivers/irqchip/irq-versatile-fpga.c:150:39: warning: passing argument 2 of 'irq_set_chip_and_handler' discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
     150 |         irq_set_chip_and_handler(irq, &fpga_chip,
         |                                       ^~~~~~~~~~
   In file included from drivers/irqchip/irq-versatile-fpga.c:6:
   include/linux/irq.h:718:80: note: expected 'struct irq_chip *' but argument is of type 'const struct irq_chip *'
     718 | static inline void irq_set_chip_and_handler(unsigned int irq, struct irq_chip *chip,
         |                                                               ~~~~~~~~~~~~~~~~~^~~~
   drivers/irqchip/irq-versatile-fpga.c: In function 'fpga_irq_init':
>> drivers/irqchip/irq-versatile-fpga.c:187:30: error: 'irq_start' undeclared (first use in this function); did you mean 'irq_stat'?
     187 |                         if (!irq_start)
         |                              ^~~~~~~~~
         |                              irq_stat
   drivers/irqchip/irq-versatile-fpga.c:187:30: note: each undeclared identifier is reported only once for each function it appears in
   cc1: some warnings being treated as errors


vim +72 drivers/irqchip/irq-versatile-fpga.c

    67	
    68	static void fpga_irq_print_chip(struct irq_data *d, struct seq_file *p)
    69	{
    70		struct fpga_irq_data *f = irq_data_get_irq_chip_data(d);
    71	
  > 72		seq_printf(p, "%s", f->np->name);
    73	}
    74	
    75	static const struct irq_chip fpga_chip = {
    76		.irq_ack	= fpga_irq_mask,
    77		.irq_mask	= fpga_irq_mask,
    78		.irq_unmask	= fpga_irq_unmask,
    79		.irq_print_chip	= fpga_irq_print_chip,
    80	};
    81	
    82	static void fpga_irq_handle(struct irq_desc *desc)
    83	{
    84		struct irq_chip *chip = irq_desc_get_chip(desc);
    85		struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
    86		u32 status;
    87	
    88		chained_irq_enter(chip, desc);
    89	
    90		status = readl(f->base + IRQ_STATUS);
    91		if (status == 0) {
    92			do_bad_IRQ(desc);
    93			goto out;
    94		}
    95	
    96		do {
    97			unsigned int irq = ffs(status) - 1;
    98	
    99			status &= ~(1 << irq);
   100			generic_handle_domain_irq(f->domain, irq);
   101		} while (status);
   102	
   103	out:
   104		chained_irq_exit(chip, desc);
   105	}
   106	
   107	/*
   108	 * Handle each interrupt in a single FPGA IRQ controller.  Returns non-zero
   109	 * if we've handled at least one interrupt.  This does a single read of the
   110	 * status register and handles all interrupts in order from LSB first.
   111	 */
   112	static int handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
   113	{
   114		int handled = 0;
   115		int irq;
   116		u32 status;
   117	
   118		while ((status  = readl(f->base + IRQ_STATUS))) {
   119			irq = ffs(status) - 1;
   120			generic_handle_domain_irq(f->domain, irq);
   121			handled = 1;
   122		}
   123	
   124		return handled;
   125	}
   126	
   127	/*
   128	 * Keep iterating over all registered FPGA IRQ controllers until there are
   129	 * no pending interrupts.
   130	 */
   131	static asmlinkage void __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
   132	{
   133		int i, handled;
   134	
   135		do {
   136			for (i = 0, handled = 0; i < fpga_irq_id; ++i)
   137				handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
   138		} while (handled);
   139	}
   140	
   141	static int fpga_irqdomain_map(struct irq_domain *d, unsigned int irq,
   142			irq_hw_number_t hwirq)
   143	{
   144		struct fpga_irq_data *f = d->host_data;
   145	
   146		/* Skip invalid IRQs, only register handlers for the real ones */
   147		if (!(f->valid & BIT(hwirq)))
   148			return -EPERM;
   149		irq_set_chip_data(irq, f);
   150		irq_set_chip_and_handler(irq, &fpga_chip,
   151					handle_level_irq);
   152		irq_set_probe(irq);
   153		return 0;
   154	}
   155	
   156	static const struct irq_domain_ops fpga_irqdomain_ops = {
   157		.map = fpga_irqdomain_map,
   158		.xlate = irq_domain_xlate_onetwocell,
   159	};
   160	
   161	static void __init fpga_irq_init(void __iomem *base, int parent_irq,
   162					 u32 valid, struct device_node *node)
   163	{
   164		struct fpga_irq_data *f;
   165		int i;
   166	
   167		if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {
   168			pr_err("%s: too few FPGA IRQ controllers, increase CONFIG_VERSATILE_FPGA_IRQ_NR\n", __func__);
   169			return;
   170		}
   171		f = &fpga_irq_devices[fpga_irq_id];
   172		f->base = base;
   173		f->np = node;
   174		f->valid = valid;
   175	
   176		if (parent_irq != -1) {
   177			irq_set_chained_handler_and_data(parent_irq, fpga_irq_handle,
   178							 f);
   179		}
   180	
   181		f->domain = irq_domain_add_linear(node, fls(valid),
   182						  &fpga_irqdomain_ops, f);
   183	
   184		/* This will allocate all valid descriptors in the linear case */
   185		for (i = 0; i < fls(valid); i++)
   186			if (valid & BIT(i)) {
 > 187				if (!irq_start)
   188					irq_create_mapping(f->domain, i);
   189				f->used_irqs++;
   190			}
   191	
   192		pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs",
   193			fpga_irq_id, node->name, base, f->used_irqs);
   194		if (parent_irq != -1)
   195			pr_cont(", parent IRQ: %d\n", parent_irq);
   196		else
   197			pr_cont("\n");
   198	
   199		fpga_irq_id++;
   200	}
   201	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From osalvador at suse.de  Sun Jan 30 22:23:02 2022
From: osalvador at suse.de (Oscar Salvador)
Date: Mon, 31 Jan 2022 07:23:02 +0100
Subject: [PATCH RFC v1] drivers/base/node: consolidate node device
 subsystem initialization in node_dev_init()
In-Reply-To: <20220128151540.164759-1-david@redhat.com>
References: <20220128151540.164759-1-david@redhat.com>
Message-ID: <YfeARpenqPii1WQH@localhost.localdomain>

On Fri, Jan 28, 2022 at 04:15:40PM +0100, David Hildenbrand wrote:
> ... and call node_dev_init() after memory_dev_init() from driver_init(),
> so before any of the existing arch/subsys calls. All online nodes should
> be known at that point.
> 
> This is in line with memory_dev_init(), which initializes the memory
> device subsystem and creates all memory block devices.
> 
> Similar to memory_dev_init(), panic() if anything goes wrong, we don't
> want to continue with such basic initialization errors.
> 
> The important part is that node_dev_init() gets called after
> memory_dev_init() and after cpu_dev_init(), but before any of the
> relevant archs call register_cpu() to register the new cpu device under
> the node device. The latter should be the case for the current users
> of topology_init().

So, before this change we had something like this:

do_basic_setup
 driver_init
  memory_dev_init
 do_init_calls
  ...
   topology_init
    register_nodes/register_one_node

And after the patch all happens in driver_init()

driver_init
 memory_dev_init
 node_dev_init

I guess this is fine as we do not have any ordering problems (aka: none
of the functions we used to call before expect the nodes not to be
there for some weird reason).

So, no functional change, right?

This certainly looks like an improvment. 

-- 
Oscar Salvador
SUSE Labs


From lkp at intel.com  Sun Jan 30 22:29:38 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 14:29:38 +0800
Subject: [arm-platforms:irq/irq_chip_ro 1/9]
 drivers/irqchip/irq-gic.c:405:17: error: implicit declaration of function
 'seq_printf'; did you mean 'bstr_printf'?
Message-ID: <202201311432.fUCsdn2s-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: 6a55685f591b540217d642fc5e0799634ee29a91 [1/9] irqchip/gic: Switch to dynamic chip name output
config: arm64-buildonly-randconfig-r002-20220131 (https://download.01.org/0day-ci/archive/20220131/202201311432.fUCsdn2s-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=6a55685f591b540217d642fc5e0799634ee29a91
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout 6a55685f591b540217d642fc5e0799634ee29a91
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-gic.c: In function 'gic_irq_print_chip':
>> drivers/irqchip/irq-gic.c:405:17: error: implicit declaration of function 'seq_printf'; did you mean 'bstr_printf'? [-Werror=implicit-function-declaration]
     405 |                 seq_printf(p, "%s", gic->chip.parent_device->of_node->name);
         |                 ^~~~~~~~~~
         |                 bstr_printf
   cc1: some warnings being treated as errors


vim +405 drivers/irqchip/irq-gic.c

   399	
   400	static void gic_irq_print_chip(struct irq_data *d, struct seq_file *p)
   401	{
   402		struct gic_chip_data *gic = irq_data_get_irq_chip_data(d);
   403	
   404		if (gic->chip.parent_device)
 > 405			seq_printf(p, "%s", gic->chip.parent_device->of_node->name);
   406		else if (static_branch_likely(&supports_deactivate_key) &&
   407			 gic == &gic_data[0])
   408			seq_printf(p, "GICv2");
   409		else
   410			seq_printf(p, "GIC-%d", (int)(gic - &gic_data[0]));
   411	}
   412	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From hch at lst.de  Sun Jan 30 22:49:28 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:28 +0100
Subject: consolidate the compat fcntl definitions v2
Message-ID: <20220131064933.3780271-1-hch@lst.de>

Hi all,

currenty the compat fcnt definitions are duplicate for all compat
architectures, and the native fcntl64 definitions aren't even usable
from userspace due to a bogus CONFIG_64BIT ifdef.  This series tries
to sort out all that.

Changes since v1:
 - only make the F*64 defines uapi visible for 32-bit architectures

Diffstat:
 arch/arm64/include/asm/compat.h        |   20 --------------------
 arch/mips/include/asm/compat.h         |   23 ++---------------------
 arch/mips/include/uapi/asm/fcntl.h     |   30 +++++-------------------------
 arch/parisc/include/asm/compat.h       |   16 ----------------
 arch/powerpc/include/asm/compat.h      |   20 --------------------
 arch/s390/include/asm/compat.h         |   20 --------------------
 arch/sparc/include/asm/compat.h        |   22 +---------------------
 arch/x86/include/asm/compat.h          |   24 +++---------------------
 include/linux/compat.h                 |   31 +++++++++++++++++++++++++++++++
 include/uapi/asm-generic/fcntl.h       |   23 +++++++++--------------
 tools/include/uapi/asm-generic/fcntl.h |   21 +++++++--------------
 11 files changed, 58 insertions(+), 192 deletions(-)


From hch at lst.de  Sun Jan 30 22:49:29 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:29 +0100
Subject: [PATCH 1/5] uapi: remove the unused HAVE_ARCH_STRUCT_FLOCK64 define
In-Reply-To: <20220131064933.3780271-1-hch@lst.de>
References: <20220131064933.3780271-1-hch@lst.de>
Message-ID: <20220131064933.3780271-2-hch@lst.de>

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 include/uapi/asm-generic/fcntl.h       | 2 --
 tools/include/uapi/asm-generic/fcntl.h | 2 --
 2 files changed, 4 deletions(-)

diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index ecd0f5bdfc1d6..caa482e3b01af 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -207,7 +207,6 @@ struct flock {
 };
 #endif
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK64
 #ifndef __ARCH_FLOCK64_PAD
 #define __ARCH_FLOCK64_PAD
 #endif
@@ -220,6 +219,5 @@ struct flock64 {
 	__kernel_pid_t  l_pid;
 	__ARCH_FLOCK64_PAD
 };
-#endif
 
 #endif /* _ASM_GENERIC_FCNTL_H */
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index ac190958c9814..4a49d33ca4d55 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -202,7 +202,6 @@ struct flock {
 };
 #endif
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK64
 #ifndef __ARCH_FLOCK64_PAD
 #define __ARCH_FLOCK64_PAD
 #endif
@@ -215,6 +214,5 @@ struct flock64 {
 	__kernel_pid_t  l_pid;
 	__ARCH_FLOCK64_PAD
 };
-#endif
 
 #endif /* _ASM_GENERIC_FCNTL_H */
-- 
2.30.2



From hch at lst.de  Sun Jan 30 22:49:30 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:30 +0100
Subject: [PATCH 2/5] uapi: simplify __ARCH_FLOCK{,64}_PAD a little
In-Reply-To: <20220131064933.3780271-1-hch@lst.de>
References: <20220131064933.3780271-1-hch@lst.de>
Message-ID: <20220131064933.3780271-3-hch@lst.de>

Don't bother to define the symbols empty, just don't use them.  That
makes the intent a little more clear.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 include/uapi/asm-generic/fcntl.h       | 12 ++++--------
 tools/include/uapi/asm-generic/fcntl.h | 12 ++++--------
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index caa482e3b01af..c53897ca5d402 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -193,22 +193,16 @@ struct f_owner_ex {
 #define F_LINUX_SPECIFIC_BASE	1024
 
 #ifndef HAVE_ARCH_STRUCT_FLOCK
-#ifndef __ARCH_FLOCK_PAD
-#define __ARCH_FLOCK_PAD
-#endif
-
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
 	__kernel_pid_t	l_pid;
+#ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
-};
 #endif
-
-#ifndef __ARCH_FLOCK64_PAD
-#define __ARCH_FLOCK64_PAD
+};
 #endif
 
 struct flock64 {
@@ -217,7 +211,9 @@ struct flock64 {
 	__kernel_loff_t l_start;
 	__kernel_loff_t l_len;
 	__kernel_pid_t  l_pid;
+#ifdef __ARCH_FLOCK64_PAD
 	__ARCH_FLOCK64_PAD
+#endif
 };
 
 #endif /* _ASM_GENERIC_FCNTL_H */
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index 4a49d33ca4d55..82054502b9748 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -188,22 +188,16 @@ struct f_owner_ex {
 #define F_LINUX_SPECIFIC_BASE	1024
 
 #ifndef HAVE_ARCH_STRUCT_FLOCK
-#ifndef __ARCH_FLOCK_PAD
-#define __ARCH_FLOCK_PAD
-#endif
-
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
 	__kernel_pid_t	l_pid;
+#ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
-};
 #endif
-
-#ifndef __ARCH_FLOCK64_PAD
-#define __ARCH_FLOCK64_PAD
+};
 #endif
 
 struct flock64 {
@@ -212,7 +206,9 @@ struct flock64 {
 	__kernel_loff_t l_start;
 	__kernel_loff_t l_len;
 	__kernel_pid_t  l_pid;
+#ifdef __ARCH_FLOCK64_PAD
 	__ARCH_FLOCK64_PAD
+#endif
 };
 
 #endif /* _ASM_GENERIC_FCNTL_H */
-- 
2.30.2



From hch at lst.de  Sun Jan 30 22:49:31 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:31 +0100
Subject: [PATCH 3/5] uapi: merge the 32-bit mips struct flock into the generic
 one
In-Reply-To: <20220131064933.3780271-1-hch@lst.de>
References: <20220131064933.3780271-1-hch@lst.de>
Message-ID: <20220131064933.3780271-4-hch@lst.de>

Add a new __ARCH_FLOCK_EXTRA_SYSID macro following the style of
__ARCH_FLOCK_PAD to avoid having a separate definition just for one
architecture.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/mips/include/uapi/asm/fcntl.h     | 26 +++-----------------------
 include/uapi/asm-generic/fcntl.h       |  5 +++--
 tools/include/uapi/asm-generic/fcntl.h |  5 +++--
 3 files changed, 9 insertions(+), 27 deletions(-)

diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 42e13dead5431..9e44ac810db94 100644
--- a/arch/mips/include/uapi/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
@@ -50,30 +50,10 @@
 #define F_SETLKW64	35
 #endif
 
-/*
- * The flavours of struct flock.  "struct flock" is the ABI compliant
- * variant.  Finally struct flock64 is the LFS variant of struct flock.	 As
- * a historic accident and inconsistence with the ABI definition it doesn't
- * contain all the same fields as struct flock.
- */
-
 #if _MIPS_SIM != _MIPS_SIM_ABI64
-
-#include <linux/types.h>
-
-struct flock {
-	short	l_type;
-	short	l_whence;
-	__kernel_off_t	l_start;
-	__kernel_off_t	l_len;
-	long	l_sysid;
-	__kernel_pid_t l_pid;
-	long	pad[4];
-};
-
-#define HAVE_ARCH_STRUCT_FLOCK
-
-#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
+#define __ARCH_FLOCK_EXTRA_SYSID	long l_sysid;
+#define __ARCH_FLOCK_PAD		long pad[4];
+#endif
 
 #include <asm-generic/fcntl.h>
 
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index c53897ca5d402..98f4ff165b776 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -192,18 +192,19 @@ struct f_owner_ex {
 
 #define F_LINUX_SPECIFIC_BASE	1024
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
+#ifdef __ARCH_FLOCK_EXTRA_SYSID
+	__ARCH_FLOCK_EXTRA_SYSID
+#endif
 	__kernel_pid_t	l_pid;
 #ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
 #endif
 };
-#endif
 
 struct flock64 {
 	short  l_type;
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index 82054502b9748..bf961a71802e0 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -187,18 +187,19 @@ struct f_owner_ex {
 
 #define F_LINUX_SPECIFIC_BASE	1024
 
-#ifndef HAVE_ARCH_STRUCT_FLOCK
 struct flock {
 	short	l_type;
 	short	l_whence;
 	__kernel_off_t	l_start;
 	__kernel_off_t	l_len;
+#ifdef __ARCH_FLOCK_EXTRA_SYSID
+	__ARCH_FLOCK_EXTRA_SYSID
+#endif
 	__kernel_pid_t	l_pid;
 #ifdef __ARCH_FLOCK_PAD
 	__ARCH_FLOCK_PAD
 #endif
 };
-#endif
 
 struct flock64 {
 	short  l_type;
-- 
2.30.2



From hch at lst.de  Sun Jan 30 22:49:32 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:32 +0100
Subject: [PATCH 4/5] uapi: always define F_GETLK64/F_SETLK64/F_SETLKW64 in
 fcntl.h
In-Reply-To: <20220131064933.3780271-1-hch@lst.de>
References: <20220131064933.3780271-1-hch@lst.de>
Message-ID: <20220131064933.3780271-5-hch@lst.de>

The F_GETLK64/F_SETLK64/F_SETLKW64 fcntl opcodes are only implemented
for the 32-bit syscall APIs, but are also needed for compat handling
on 64-bit kernels.

Consolidate them in unistd.h instead of definining the internal compat
definitions in compat.h, which is rather errror prone (e.g. parisc
gets the values wrong currently).

Note that before this change they were never visible to userspace due
to the fact that CONFIG_64BIT is only set for kernel builds.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/arm64/include/asm/compat.h        | 4 ----
 arch/mips/include/asm/compat.h         | 4 ----
 arch/mips/include/uapi/asm/fcntl.h     | 4 ++--
 arch/powerpc/include/asm/compat.h      | 4 ----
 arch/s390/include/asm/compat.h         | 4 ----
 arch/sparc/include/asm/compat.h        | 4 ----
 arch/x86/include/asm/compat.h          | 4 ----
 include/uapi/asm-generic/fcntl.h       | 4 ++--
 tools/include/uapi/asm-generic/fcntl.h | 2 --
 9 files changed, 4 insertions(+), 30 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eaa6ca062d89b..2763287654081 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -73,10 +73,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index bbb3bc5a42fd8..6a350c1f70d7e 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -65,10 +65,6 @@ struct compat_flock {
 	s32		pad[4];
 };
 
-#define F_GETLK64	33
-#define F_SETLK64	34
-#define F_SETLKW64	35
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/mips/include/uapi/asm/fcntl.h b/arch/mips/include/uapi/asm/fcntl.h
index 9e44ac810db94..0369a38e3d4f2 100644
--- a/arch/mips/include/uapi/asm/fcntl.h
+++ b/arch/mips/include/uapi/asm/fcntl.h
@@ -44,11 +44,11 @@
 #define F_SETOWN	24	/*  for sockets. */
 #define F_GETOWN	23	/*  for sockets. */
 
-#ifndef __mips64
+#if __BITS_PER_LONG == 32 || defined(__KERNEL__)
 #define F_GETLK64	33	/*  using 'struct flock64' */
 #define F_SETLK64	34
 #define F_SETLKW64	35
-#endif
+#endif /* __BITS_PER_LONG == 32 || defined(__KERNEL__) */
 
 #if _MIPS_SIM != _MIPS_SIM_ABI64
 #define __ARCH_FLOCK_EXTRA_SYSID	long l_sysid;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 7afc96fb6524b..83d8f70779cbc 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -52,10 +52,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index cdc7ae72529d8..0f14b3188b1bb 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -110,10 +110,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64       12
-#define F_SETLK64       13
-#define F_SETLKW64      14    
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index bd949fcf9d63b..108078751bb5a 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -84,10 +84,6 @@ struct compat_flock {
 	short		__unused;
 };
 
-#define F_GETLK64	12
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 struct compat_flock64 {
 	short		l_type;
 	short		l_whence;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7516e4199b3c6..8d19a212f4f26 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -58,10 +58,6 @@ struct compat_flock {
 	compat_pid_t	l_pid;
 };
 
-#define F_GETLK64	12	/*  using 'struct flock64' */
-#define F_SETLK64	13
-#define F_SETLKW64	14
-
 /*
  * IA32 uses 4 byte alignment for 64 bit quantities,
  * so we need to pack this structure.
diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index 98f4ff165b776..8c05d3d89ff18 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h
@@ -116,13 +116,13 @@
 #define F_GETSIG	11	/* for sockets. */
 #endif
 
-#ifndef CONFIG_64BIT
+#if __BITS_PER_LONG == 32 || defined(__KERNEL__)
 #ifndef F_GETLK64
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 #endif
-#endif
+#endif /* __BITS_PER_LONG == 32 || defined(__KERNEL__) */
 
 #ifndef F_SETOWN_EX
 #define F_SETOWN_EX	15
diff --git a/tools/include/uapi/asm-generic/fcntl.h b/tools/include/uapi/asm-generic/fcntl.h
index bf961a71802e0..6e16722026f39 100644
--- a/tools/include/uapi/asm-generic/fcntl.h
+++ b/tools/include/uapi/asm-generic/fcntl.h
@@ -115,13 +115,11 @@
 #define F_GETSIG	11	/* for sockets. */
 #endif
 
-#ifndef CONFIG_64BIT
 #ifndef F_GETLK64
 #define F_GETLK64	12	/*  using 'struct flock64' */
 #define F_SETLK64	13
 #define F_SETLKW64	14
 #endif
-#endif
 
 #ifndef F_SETOWN_EX
 #define F_SETOWN_EX	15
-- 
2.30.2



From hch at lst.de  Sun Jan 30 22:49:33 2022
From: hch at lst.de (Christoph Hellwig)
Date: Mon, 31 Jan 2022 07:49:33 +0100
Subject: [PATCH 5/5] compat: consolidate the compat_flock{,64} definition
In-Reply-To: <20220131064933.3780271-1-hch@lst.de>
References: <20220131064933.3780271-1-hch@lst.de>
Message-ID: <20220131064933.3780271-6-hch@lst.de>

Provide a single common definition for the compat_flock and
compat_flock64 structures using the same tricks as for the native
variants.  Another extra define is added for the packing required on
x86.

Signed-off-by: Christoph Hellwig <hch at lst.de>
---
 arch/arm64/include/asm/compat.h   | 16 ----------------
 arch/mips/include/asm/compat.h    | 19 ++-----------------
 arch/parisc/include/asm/compat.h  | 16 ----------------
 arch/powerpc/include/asm/compat.h | 16 ----------------
 arch/s390/include/asm/compat.h    | 16 ----------------
 arch/sparc/include/asm/compat.h   | 18 +-----------------
 arch/x86/include/asm/compat.h     | 20 +++-----------------
 include/linux/compat.h            | 31 +++++++++++++++++++++++++++++++
 8 files changed, 37 insertions(+), 115 deletions(-)

diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 2763287654081..e0faec1984a1c 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h
@@ -65,22 +65,6 @@ struct compat_stat {
 	compat_ulong_t	__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index 6a350c1f70d7e..6d6e5a451f4d9 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h
@@ -55,23 +55,8 @@ struct compat_stat {
 	s32		st_pad4[14];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	s32		l_sysid;
-	compat_pid_t	l_pid;
-	s32		pad[4];
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
+#define __ARCH_COMPAT_FLOCK_EXTRA_SYSID		s32 l_sysid;
+#define __ARCH_COMPAT_FLOCK_PAD			s32 pad[4];
 
 struct compat_statfs {
 	int		f_type;
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c04f5a637c390..a1e4534d80509 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -53,22 +53,6 @@ struct compat_stat {
 	u32			st_spare4[3];
 };
 
-struct compat_flock {
-	short			l_type;
-	short			l_whence;
-	compat_off_t		l_start;
-	compat_off_t		l_len;
-	compat_pid_t		l_pid;
-};
-
-struct compat_flock64 {
-	short			l_type;
-	short			l_whence;
-	compat_loff_t		l_start;
-	compat_loff_t		l_len;
-	compat_pid_t		l_pid;
-};
-
 struct compat_statfs {
 	s32		f_type;
 	s32		f_bsize;
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 83d8f70779cbc..5ef3c7c83c343 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -44,22 +44,6 @@ struct compat_stat {
 	u32		__unused4[2];
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	int		f_type;
 	int		f_bsize;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 0f14b3188b1bb..07f04d37068b6 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -102,22 +102,6 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 struct compat_statfs {
 	u32		f_type;
 	u32		f_bsize;
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index 108078751bb5a..d78fb44942e0f 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h
@@ -75,23 +75,7 @@ struct compat_stat64 {
 	unsigned int	__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-	short		__unused;
-};
-
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-	short		__unused;
-};
+#define __ARCH_COMPAT_FLOCK_PAD		short __unused;
 
 struct compat_statfs {
 	int		f_type;
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 8d19a212f4f26..de794d8958663 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -50,25 +50,11 @@ struct compat_stat {
 	u32		__unused5;
 };
 
-struct compat_flock {
-	short		l_type;
-	short		l_whence;
-	compat_off_t	l_start;
-	compat_off_t	l_len;
-	compat_pid_t	l_pid;
-};
-
 /*
- * IA32 uses 4 byte alignment for 64 bit quantities,
- * so we need to pack this structure.
+ * IA32 uses 4 byte alignment for 64 bit quantities, so we need to pack the
+ * compat flock64 structure.
  */
-struct compat_flock64 {
-	short		l_type;
-	short		l_whence;
-	compat_loff_t	l_start;
-	compat_loff_t	l_len;
-	compat_pid_t	l_pid;
-} __attribute__((packed));
+#define __ARCH_NEED_COMPAT_FLOCK64_PACKED
 
 struct compat_statfs {
 	int		f_type;
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 1c758b0e03598..a0481fe6c5d51 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -258,6 +258,37 @@ struct compat_rlimit {
 	compat_ulong_t	rlim_max;
 };
 
+#ifdef __ARCH_NEED_COMPAT_FLOCK64_PACKED
+#define __ARCH_COMPAT_FLOCK64_PACK	__attribute__((packed))
+#else
+#define __ARCH_COMPAT_FLOCK64_PACK
+#endif
+
+struct compat_flock {
+	short			l_type;
+	short			l_whence;
+	compat_off_t		l_start;
+	compat_off_t		l_len;
+#ifdef __ARCH_COMPAT_FLOCK_EXTRA_SYSID
+	__ARCH_COMPAT_FLOCK_EXTRA_SYSID
+#endif
+	compat_pid_t		l_pid;
+#ifdef __ARCH_COMPAT_FLOCK_PAD
+	__ARCH_COMPAT_FLOCK_PAD
+#endif
+};
+
+struct compat_flock64 {
+	short		l_type;
+	short		l_whence;
+	compat_loff_t	l_start;
+	compat_loff_t	l_len;
+	compat_pid_t	l_pid;
+#ifdef __ARCH_COMPAT_FLOCK64_PAD
+	__ARCH_COMPAT_FLOCK64_PAD
+#endif
+} __ARCH_COMPAT_FLOCK64_PACK;
+
 struct compat_rusage {
 	struct old_timeval32 ru_utime;
 	struct old_timeval32 ru_stime;
-- 
2.30.2



From hch at infradead.org  Sun Jan 30 22:54:24 2022
From: hch at infradead.org (Christoph Hellwig)
Date: Sun, 30 Jan 2022 22:54:24 -0800
Subject: [PATCH 11/13] ARM: ixp4xx: Drop custom DMA coherency and bouncing
In-Reply-To: <CAK8P3a3eqGSZ68smMRdYKOEyghX+tnpfsVqHGYhtFcWTYqf+Pg@mail.gmail.com>
References: <20220127003656.330161-1-linus.walleij@linaro.org>
 <20220127003656.330161-12-linus.walleij@linaro.org>
 <CAK8P3a3eqGSZ68smMRdYKOEyghX+tnpfsVqHGYhtFcWTYqf+Pg@mail.gmail.com>
Message-ID: <YfeHoIHPADwKX0ET@infradead.org>

On Thu, Jan 27, 2022 at 11:00:54AM +0100, Arnd Bergmann wrote:
> Maybe we could change the sa1111-ohci driver to use usb_hcd_setup_local_mem(),
> which implements a similar method locally, and then kill off dmabounce for good.
> 
> usb_hcd_setup_local_mem() is used on some pxa machines (csb726 with ohci-sm501
> and eseries/tosa with ohci-tmio), though they use it to DMA into a
> small SRAM (8KB
> for tmio, 256KB for sm501) rather than a limited section of DRAM.

That would be awesome.


From Ludovic.Desroches at microchip.com  Sun Jan 30 22:59:02 2022
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Mon, 31 Jan 2022 06:59:02 +0000
Subject: [PATCH] dt-bindings: rng: atmel,at91-trng: update maintainers
 entry
In-Reply-To: <d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com>
References: <d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com>
Message-ID: <aee5a70d-fcc1-f7a8-75f4-b82905f7883e@microchip.com>

On 1/30/2022 3:47 PM, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Update according to new MAINTAINERS entry.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Ludovic Desroches <ludovic.desroches at microchip.com>

> ---
> Hi,
> 
> Patch for new MAINTAINERS entry is here:
> https://lore.kernel.org/linux-arm-kernel/23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre at microchip.com/
> 
> Regards,
>    Nicolas
> 
>   Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> index c1527637eb74..3ce45456d867 100644
> --- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> +++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> @@ -9,7 +9,7 @@ title: Atmel AT91 True Random Number Generator
>   maintainers:
>     - Nicolas Ferre <nicolas.ferre at microchip.com>
>     - Alexandre Belloni <alexandre.belloni at bootlin.com>
> -  - Ludovic Desroches <ludovic.desroches at microchip.com>
> +  - Claudiu Beznea <claudiu.beznea at microchip.com>
>   
>   properties:
>     compatible:


From phind.uet at gmail.com  Sun Jan 30 23:10:06 2022
From: phind.uet at gmail.com (Nguyen Dinh Phi)
Date: Mon, 31 Jan 2022 15:10:06 +0800
Subject: [PATCH] staging: vc04_services: make a couple of functions static
Message-ID: <20220131071006.1764343-1-phind.uet@gmail.com>

Functions vchiq_platform_init and vchiq_platform_get_arm_state are used
locally in vchiq_arm.c file, so make them static.

Cleans up sparse warnings:
warning: symbol 'vchiq_platform_init' was not declared. Should it be
static?
warning: warning: symbol 'vchiq_platform_get_arm_state' was not declared.
Should it be static?

Signed-off-by: Nguyen Dinh Phi <phind.uet at gmail.com>
---
 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 54ab6208ddae..b1054550ed27 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -466,7 +466,7 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
 	cleanup_pagelistinfo(pagelistinfo);
 }
 
-int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
+static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state)
 {
 	struct device *dev = &pdev->dev;
 	struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
@@ -593,7 +593,7 @@ vchiq_platform_init_state(struct vchiq_state *state)
 	return 0;
 }
 
-struct vchiq_arm_state*
+static struct vchiq_arm_state*
 vchiq_platform_get_arm_state(struct vchiq_state *state)
 {
 	struct vchiq_2835_state *platform_state;
-- 
2.25.1



From Ludovic.Desroches at microchip.com  Sun Jan 30 23:10:54 2022
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Mon, 31 Jan 2022 07:10:54 +0000
Subject: [PATCH 1/2] MAINTAINERS: replace a Microchip AT91 maintainer
In-Reply-To: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
References: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
Message-ID: <810150de-5099-6110-c5b2-167bf206fc6e@microchip.com>

On 1/30/2022 3:39 PM, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> As Ludovic is more focusing on other aspects of the Microchip
> Linux-based development, replace him with Claudiu.
> Entry is added to the CREDITS file.
> 
> Thanks Ludovic for these great contributions in the kernel space!
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Ludovic Desroches <ludovic.desroches at microchip.com>

> ---
>   CREDITS     | 6 ++++++
>   MAINTAINERS | 2 +-
>   2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/CREDITS b/CREDITS
> index b97256d5bc24..7e85a53b6a88 100644
> --- a/CREDITS
> +++ b/CREDITS
> @@ -895,6 +895,12 @@ S: 3000 FORE Drive
>   S: Warrendale, Pennsylvania 15086
>   S: USA
>   
> +N: Ludovic Desroches
> +E: ludovic.desroches at microchip.com
> +D: Maintainer for ARM/Microchip (AT91) SoC support
> +D: Author of ADC, pinctrl, XDMA and SDHCI drivers for this platform
> +S: France
> +
>   N: Martin Devera
>   E: devik at cdi.cz
>   W: http://luxik.cdi.cz/~devik/qos/
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ea3e6c914384..674d13708324 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2250,7 +2250,7 @@ F:	drivers/phy/mediatek/
>   ARM/Microchip (AT91) SoC support
>   M:	Nicolas Ferre <nicolas.ferre at microchip.com>
>   M:	Alexandre Belloni <alexandre.belloni at bootlin.com>
> -M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> +M:	Claudiu Beznea <claudiu.beznea at microchip.com>
>   L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>   S:	Supported
>   W:	http://www.linux4sam.org


From lkp at intel.com  Sun Jan 30 23:10:43 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 15:10:43 +0800
Subject: [arm-platforms:irq/irq_chip_ro 3/9]
 drivers/irqchip/irq-mvebu-pic.c:74:2: error: implicit declaration of
 function 'seq_printf'
Message-ID: <202201311558.nL1CN3DT-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: a57739a1ce5301e34704447de96205450c3bf87d [3/9] irqchip/mvebu-pic: Switch to dynamic chip name output
config: arm64-randconfig-r015-20220131 (https://download.01.org/0day-ci/archive/20220131/202201311558.nL1CN3DT-lkp at intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 2cdbaca3943a4d6259119f185656328bd3805b68)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm64 cross compiling tool for clang build
        # apt-get install binutils-aarch64-linux-gnu
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=a57739a1ce5301e34704447de96205450c3bf87d
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout a57739a1ce5301e34704447de96205450c3bf87d
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

>> drivers/irqchip/irq-mvebu-pic.c:74:2: error: implicit declaration of function 'seq_printf' [-Werror,-Wimplicit-function-declaration]
           seq_printf(p, "%s", dev_name(&pic->pdev->dev));
           ^
   1 error generated.


vim +/seq_printf +74 drivers/irqchip/irq-mvebu-pic.c

    69	
    70	static void mvebu_pic_print_chip(struct irq_data *d, struct seq_file *p)
    71	{
    72		struct mvebu_pic *pic = irq_data_get_irq_chip_data(d);
    73	
  > 74		seq_printf(p, "%s", dev_name(&pic->pdev->dev));
    75	}
    76	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From Ludovic.Desroches at microchip.com  Sun Jan 30 23:11:14 2022
From: Ludovic.Desroches at microchip.com (Ludovic.Desroches at microchip.com)
Date: Mon, 31 Jan 2022 07:11:14 +0000
Subject: [PATCH 2/2] dt-bindings: ARM: at91: update maintainers entry
In-Reply-To: <5bf9873eeee3cd49c52a8952a7cd4cb60b61d50a.1643553501.git.nicolas.ferre@microchip.com>
References: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
 <5bf9873eeee3cd49c52a8952a7cd4cb60b61d50a.1643553501.git.nicolas.ferre@microchip.com>
Message-ID: <eb3f4e8d-cde1-4d1d-ff65-35e046afd13c@microchip.com>

On 1/30/2022 3:39 PM, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Align the binding documentation with the newly updated MAINTAINERS
> entry.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Ludovic Desroches <ludovic.desroches at microchip.com>

> ---
>   Documentation/devicetree/bindings/arm/atmel-at91.yaml | 3 ++-
>   1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> index c612e1f48dba..ff91df04f9f4 100644
> --- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> +++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> @@ -8,7 +8,8 @@ title: Atmel AT91 device tree bindings.
>   
>   maintainers:
>     - Alexandre Belloni <alexandre.belloni at bootlin.com>
> -  - Ludovic Desroches <ludovic.desroches at microchip.com>
> +  - Claudiu Beznea <claudiu.beznea at microchip.com>
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
>   
>   description: |
>     Boards with a SoC of the Atmel AT91 or SMART family shall have the following


From Claudiu.Beznea at microchip.com  Sun Jan 30 23:47:02 2022
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 31 Jan 2022 07:47:02 +0000
Subject: [PATCH 1/2] MAINTAINERS: replace a Microchip AT91 maintainer
In-Reply-To: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
References: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
Message-ID: <9aa5be01-d0e0-3267-a347-7cd456830677@microchip.com>

On 30.01.2022 16:39, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> As Ludovic is more focusing on other aspects of the Microchip
> Linux-based development, replace him with Claudiu.
> Entry is added to the CREDITS file.
> 
> Thanks Ludovic for these great contributions in the kernel space!
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Claudiu Beznea <claudiu.beznea at microchip.com>


> ---
>  CREDITS     | 6 ++++++
>  MAINTAINERS | 2 +-
>  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/CREDITS b/CREDITS
> index b97256d5bc24..7e85a53b6a88 100644
> --- a/CREDITS
> +++ b/CREDITS
> @@ -895,6 +895,12 @@ S: 3000 FORE Drive
>  S: Warrendale, Pennsylvania 15086
>  S: USA
>  
> +N: Ludovic Desroches
> +E: ludovic.desroches at microchip.com
> +D: Maintainer for ARM/Microchip (AT91) SoC support
> +D: Author of ADC, pinctrl, XDMA and SDHCI drivers for this platform
> +S: France
> +
>  N: Martin Devera
>  E: devik at cdi.cz
>  W: http://luxik.cdi.cz/~devik/qos/
> diff --git a/MAINTAINERS b/MAINTAINERS
> index ea3e6c914384..674d13708324 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2250,7 +2250,7 @@ F:	drivers/phy/mediatek/
>  ARM/Microchip (AT91) SoC support
>  M:	Nicolas Ferre <nicolas.ferre at microchip.com>
>  M:	Alexandre Belloni <alexandre.belloni at bootlin.com>
> -M:	Ludovic Desroches <ludovic.desroches at microchip.com>
> +M:	Claudiu Beznea <claudiu.beznea at microchip.com>
>  L:	linux-arm-kernel at lists.infradead.org (moderated for non-subscribers)
>  S:	Supported
>  W:	http://www.linux4sam.org


From Claudiu.Beznea at microchip.com  Sun Jan 30 23:47:51 2022
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 31 Jan 2022 07:47:51 +0000
Subject: [PATCH 2/2] dt-bindings: ARM: at91: update maintainers entry
In-Reply-To: <5bf9873eeee3cd49c52a8952a7cd4cb60b61d50a.1643553501.git.nicolas.ferre@microchip.com>
References: <23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre@microchip.com>
 <5bf9873eeee3cd49c52a8952a7cd4cb60b61d50a.1643553501.git.nicolas.ferre@microchip.com>
Message-ID: <03bbe737-ce57-a7ef-211c-b29e15afdffd@microchip.com>

On 30.01.2022 16:39, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Align the binding documentation with the newly updated MAINTAINERS
> entry.
> > Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Claudiu Beznea <claudiu.beznea at microchip.com>


> ---
>  Documentation/devicetree/bindings/arm/atmel-at91.yaml | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.yaml b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> index c612e1f48dba..ff91df04f9f4 100644
> --- a/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> +++ b/Documentation/devicetree/bindings/arm/atmel-at91.yaml
> @@ -8,7 +8,8 @@ title: Atmel AT91 device tree bindings.
>  
>  maintainers:
>    - Alexandre Belloni <alexandre.belloni at bootlin.com>
> -  - Ludovic Desroches <ludovic.desroches at microchip.com>
> +  - Claudiu Beznea <claudiu.beznea at microchip.com>
> +  - Nicolas Ferre <nicolas.ferre at microchip.com>
>  
>  description: |
>    Boards with a SoC of the Atmel AT91 or SMART family shall have the following


From Claudiu.Beznea at microchip.com  Sun Jan 30 23:48:35 2022
From: Claudiu.Beznea at microchip.com (Claudiu.Beznea at microchip.com)
Date: Mon, 31 Jan 2022 07:48:35 +0000
Subject: [PATCH] dt-bindings: rng: atmel,at91-trng: update maintainers
 entry
In-Reply-To: <d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com>
References: <d84760e0b81c338e01f7856e1ce3c5b600b08f23.1643553619.git.nicolas.ferre@microchip.com>
Message-ID: <7fe32b04-1dec-b23a-c8dd-3e7e392796d9@microchip.com>

On 30.01.2022 16:47, nicolas.ferre at microchip.com wrote:
> From: Nicolas Ferre <nicolas.ferre at microchip.com>
> 
> Update according to new MAINTAINERS entry.
> 
> Signed-off-by: Nicolas Ferre <nicolas.ferre at microchip.com>

Acked-by: Claudiu Beznea <claudiu.beznea at microchip.com>


> ---
> Hi,
> 
> Patch for new MAINTAINERS entry is here:
> https://lore.kernel.org/linux-arm-kernel/23819d8baa635815d0893955197561fe4f044d5e.1643553501.git.nicolas.ferre at microchip.com/
> 
> Regards,
>   Nicolas
> 
>  Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> index c1527637eb74..3ce45456d867 100644
> --- a/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> +++ b/Documentation/devicetree/bindings/rng/atmel,at91-trng.yaml
> @@ -9,7 +9,7 @@ title: Atmel AT91 True Random Number Generator
>  maintainers:
>    - Nicolas Ferre <nicolas.ferre at microchip.com>
>    - Alexandre Belloni <alexandre.belloni at bootlin.com>
> -  - Ludovic Desroches <ludovic.desroches at microchip.com>
> +  - Claudiu Beznea <claudiu.beznea at microchip.com>
>  
>  properties:
>    compatible:


From david at redhat.com  Sun Jan 30 23:48:54 2022
From: david at redhat.com (David Hildenbrand)
Date: Mon, 31 Jan 2022 08:48:54 +0100
Subject: [PATCH RFC v1] drivers/base/node: consolidate node device
 subsystem initialization in node_dev_init()
In-Reply-To: <YfeARpenqPii1WQH@localhost.localdomain>
References: <20220128151540.164759-1-david@redhat.com>
 <YfeARpenqPii1WQH@localhost.localdomain>
Message-ID: <3be2e20c-f0b9-c080-adf4-b0e17c046eb0@redhat.com>

On 31.01.22 07:23, Oscar Salvador wrote:
> On Fri, Jan 28, 2022 at 04:15:40PM +0100, David Hildenbrand wrote:
>> ... and call node_dev_init() after memory_dev_init() from driver_init(),
>> so before any of the existing arch/subsys calls. All online nodes should
>> be known at that point.
>>
>> This is in line with memory_dev_init(), which initializes the memory
>> device subsystem and creates all memory block devices.
>>
>> Similar to memory_dev_init(), panic() if anything goes wrong, we don't
>> want to continue with such basic initialization errors.
>>
>> The important part is that node_dev_init() gets called after
>> memory_dev_init() and after cpu_dev_init(), but before any of the
>> relevant archs call register_cpu() to register the new cpu device under
>> the node device. The latter should be the case for the current users
>> of topology_init().
> 

Hi Oscar,

> So, before this change we had something like this:
> 
> do_basic_setup
>  driver_init
>   memory_dev_init
>  do_init_calls
>   ...
>    topology_init
>     register_nodes/register_one_node
> 
> And after the patch all happens in driver_init()
> 
> driver_init
>  memory_dev_init
>  node_dev_init
> 
> I guess this is fine as we do not have any ordering problems (aka: none
> of the functions we used to call before expect the nodes not to be
> there for some weird reason).
> 
> So, no functional change, right?
> 

Right, and the idea is that the online state of nodes (+ node/zone
ranges) already has to be known at that point in time, because
otherwise, we'd be in bigger trouble.

Thanks!


-- 
Thanks,

David / dhildenb



From francesco.dolcini at toradex.com  Sun Jan 30 23:52:35 2022
From: francesco.dolcini at toradex.com (Francesco Dolcini)
Date: Mon, 31 Jan 2022 08:52:35 +0100
Subject: [PATCH v1] PCI: imx6: Handle the abort from user-space
Message-ID: <20220131075235.787432-1-francesco.dolcini@toradex.com>

From: Jason Liu <jason.hui.liu at nxp.com>

The driver install one hook to handle the external abort, but issue
is that if the abort introduced from user space code, the following
code unsigned long instr = *(unsigned long *)pc; which will created
another data-abort(page domain fault) if CONFIG_CPU_SW_DOMAIN_PAN.

The patch does not intent to use copy_from_user and then do the hack
due to the security consideration. In fact, we can just return and
report the external abort to user-space.

Link: https://lore.kernel.org/all/20220128082920.591115-1-francesco.dolcini at toradex.com
Signed-off-by: Jason Liu <jason.hui.liu at nxp.com>
Reviewed-by: Richard Zhu <hongxing.zhu at nxp.com>
Signed-off-by: Francesco Dolcini <francesco.dolcini at toradex.com>
Acked-by: Lucas Stach <l.stach at pengutronix.de>
---
rfc -> v1:
 * added Acked-by Lucas Stach
 * include correct header for user_mode()
---
 drivers/pci/controller/dwc/pci-imx6.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 6974bd5aa116..c47a05332a94 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -22,6 +22,7 @@
 #include <linux/of_address.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
+#include <linux/ptrace.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/resource.h>
@@ -297,8 +298,15 @@ static int imx6q_pcie_abort_handler(unsigned long addr,
 		unsigned int fsr, struct pt_regs *regs)
 {
 	unsigned long pc = instruction_pointer(regs);
-	unsigned long instr = *(unsigned long *)pc;
-	int reg = (instr >> 12) & 15;
+	unsigned long instr;
+	int reg;
+
+	/* if the abort from user-space, just return and report it */
+	if (user_mode(regs))
+		return 1;
+
+	instr = *(unsigned long *)pc;
+	reg = (instr >> 12) & 15;
 
 	/*
 	 * If the instruction being executed was a read,
-- 
2.25.1



From lkp at intel.com  Mon Jan 31 00:01:43 2022
From: lkp at intel.com (kernel test robot)
Date: Mon, 31 Jan 2022 16:01:43 +0800
Subject: [arm-platforms:irq/irq_chip_ro 3/9]
 drivers/irqchip/irq-mvebu-pic.c:74:9: error: implicit declaration of
 function 'seq_printf'; did you mean 'bstr_printf'?
Message-ID: <202201311519.CLOwt1F2-lkp@intel.com>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git irq/irq_chip_ro
head:   f63a5ded3ea0cd2c587db00f89d219789fbee683
commit: a57739a1ce5301e34704447de96205450c3bf87d [3/9] irqchip/mvebu-pic: Switch to dynamic chip name output
config: arm64-buildonly-randconfig-r002-20220131 (https://download.01.org/0day-ci/archive/20220131/202201311519.CLOwt1F2-lkp at intel.com/config)
compiler: aarch64-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?id=a57739a1ce5301e34704447de96205450c3bf87d
        git remote add arm-platforms https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git
        git fetch --no-tags arm-platforms irq/irq_chip_ro
        git checkout a57739a1ce5301e34704447de96205450c3bf87d
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp at intel.com>

All errors (new ones prefixed by >>):

   drivers/irqchip/irq-mvebu-pic.c: In function 'mvebu_pic_print_chip':
>> drivers/irqchip/irq-mvebu-pic.c:74:9: error: implicit declaration of function 'seq_printf'; did you mean 'bstr_printf'? [-Werror=implicit-function-declaration]
      74 |         seq_printf(p, "%s", dev_name(&pic->pdev->dev));
         |         ^~~~~~~~~~
         |         bstr_printf
   cc1: some warnings being treated as errors


vim +74 drivers/irqchip/irq-mvebu-pic.c

    69	
    70	static void mvebu_pic_print_chip(struct irq_data *d, struct seq_file *p)
    71	{
    72		struct mvebu_pic *pic = irq_data_get_irq_chip_data(d);
    73	
  > 74		seq_printf(p, "%s", dev_name(&pic->pdev->dev));
    75	}
    76	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all at lists.01.org


From clabbe at baylibre.com  Mon Jan 31 00:05:14 2022
From: clabbe at baylibre.com (LABBE Corentin)
Date: Mon, 31 Jan 2022 09:05:14 +0100
Subject: [PATCH] dt-bindings: mtd: drop mtd/cortina,gemini-flash.txt
In-Reply-To: <CACRpkdY7O=KjhbeBZiokchFhSo8dTM+JAeBOTq+qkKE7-63jPw@mail.gmail.com>
References: <20220127200310.4150981-1-clabbe@baylibre.com>
 <CACRpkdY7O=KjhbeBZiokchFhSo8dTM+JAeBOTq+qkKE7-63jPw@mail.gmail.com>
Message-ID: <YfeYOsFLBeu+tLLE@Red>

Le Fri, Jan 28, 2022 at 01:18:55AM +0100, Linus Walleij a ?crit :
> On Thu, Jan 27, 2022 at 9:03 PM Corentin Labbe <clabbe at baylibre.com> wrote:
> 
> > Drop mtd/cortina,gemini-flash.txt since it is nearly already handled by
> > Documentation/devicetree/bindings/mtd/mtd-physmap.yaml.
> >
> > Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
> 
> Thanks for fixing this Corentin!
> 
> > +      $ref: /schemas/types.yaml#/definitions/phandle
> > +      description:
> > +        Phandle to the syscom controller
> 
> syscon?
> 

Hello

I will fix it in v2.

Thanks.


From andrej.picej at norik.com  Mon Jan 31 00:05:25 2022
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 31 Jan 2022 09:05:25 +0100
Subject: [PATCH RESEND 3/4] ARM: dts: imx6ul: phycore: Change USB LDO voltage
 for usb compliance
In-Reply-To: <20220131080526.1171072-1-andrej.picej@norik.com>
References: <20220131080526.1171072-1-andrej.picej@norik.com>
Message-ID: <20220131080526.1171072-4-andrej.picej@norik.com>

From: Yunus Bas <y.bas at phytec.de>

According to the NXP usb compliance reference, the USB data lines for
Full/Low speed are connected to the ARM USB LDO, which is set to
minimum-voltage = 2.6V and maximum-voltage = 3.4 V. When the regulator
is deactivated, the data lines are defaulty driven with 2.6V, which is
not USB Full-Speed compliant. To be compliant, we need to activate the
USB LDO regulator and set it to the value of 3V, which is the specified
value in the USB specification.

Signed-off-by: Yunus Bas <y.bas at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
 arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi
index 3cddc68917a0..2e03be3d43ec 100644
--- a/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi
+++ b/arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi
@@ -83,6 +83,11 @@ eeprom at 52 {
 	};
 };
 
+&reg_3p0 {
+	regulator-min-microvolt = <3000000>;
+	regulator-always-on;
+};
+
 &snvs_poweroff {
 	status = "okay";
 };
-- 
2.25.1



From andrej.picej at norik.com  Mon Jan 31 00:05:23 2022
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 31 Jan 2022 09:05:23 +0100
Subject: [PATCH RESEND 1/4] dt-bindings: arm: fsl: add PHYTEC phyGATE Tauri
 i.MX6 ULL
In-Reply-To: <20220131080526.1171072-1-andrej.picej@norik.com>
References: <20220131080526.1171072-1-andrej.picej@norik.com>
Message-ID: <20220131080526.1171072-2-andrej.picej@norik.com>

Add devicetree bindings for phyGATE Tauri board with phyCORE-i.MX6 ULL.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 97f6eebad76a..aca681477e1e 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -640,6 +640,15 @@ properties:
           - const: phytec,imx6ull-pcl063  # PHYTEC phyCORE-i.MX 6ULL
           - const: fsl,imx6ull
 
+      - description: i.MX6ULL PHYTEC phyGATE-Tauri
+        items:
+          - enum:
+              - phytec,imx6ull-phygate-tauri-emmc
+              - phytec,imx6ull-phygate-tauri-nand
+          - const: phytec,imx6ull-phygate-tauri # PHYTEC phyGATE-Tauri with i.MX6 ULL
+          - const: phytec,imx6ull-pcl063        # PHYTEC phyCORE-i.MX 6ULL
+          - const: fsl,imx6ull
+
       - description: i.MX6ULL Boards with Toradex Colibri iMX6ULL Modules
         items:
           - enum:
-- 
2.25.1



From andrej.picej at norik.com  Mon Jan 31 00:05:22 2022
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 31 Jan 2022 09:05:22 +0100
Subject: [PATCH RESEND 0/4] PHYTEC i.MX 6UL/ULL devicetree patches
Message-ID: <20220131080526.1171072-1-andrej.picej@norik.com>

Hi all,

this patch series contains PHYTEC i.MX 6UL/ULL devicetree patches not
yet upstreamed.

First and second patch add devicetree for relatively new phyGATE
Tauri-S, which is based on i.MX 6ULL.

Third patch changes USB LDO voltage for i.MX 6UL/ULL phyCORE devices so
they match USB Full-speed compliance.

The fourth patch moves from using 2 pwm-cell to default 3 cell pwm
property.

Best regards,
Andrej


Alexander Bauer (1):
  ARM: dts: imx6ull: Add support for PHYTEC phyGATE-Tauri-S with i.MX
    6ULL

Andrej Picej (2):
  dt-bindings: arm: fsl: add PHYTEC phyGATE Tauri i.MX6 ULL
  ARM: dts: imx6ul: peb-av-02: move to 3 cell pwm

Yunus Bas (1):
  ARM: dts: imx6ul: phycore: Change USB LDO voltage for usb compliance

 .../devicetree/bindings/arm/fsl.yaml          |   9 +
 arch/arm/boot/dts/Makefile                    |   2 +
 .../boot/dts/imx6ul-phytec-phycore-som.dtsi   |   5 +
 .../dts/imx6ul-phytec-segin-peb-av-02.dtsi    |   3 +-
 .../boot/dts/imx6ull-phytec-tauri-emmc.dts    |  20 +
 .../boot/dts/imx6ull-phytec-tauri-nand.dts    |  20 +
 arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi   | 605 ++++++++++++++++++
 7 files changed, 662 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri-emmc.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri-nand.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi

-- 
2.25.1



From andrej.picej at norik.com  Mon Jan 31 00:05:26 2022
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 31 Jan 2022 09:05:26 +0100
Subject: [PATCH RESEND 4/4] ARM: dts: imx6ul: peb-av-02: move to 3 cell pwm
In-Reply-To: <20220131080526.1171072-1-andrej.picej@norik.com>
References: <20220131080526.1171072-1-andrej.picej@norik.com>
Message-ID: <20220131080526.1171072-5-andrej.picej@norik.com>

Instead of changing default pwm-cells property, use the default
"#pwm-cells = <3>" and add the third option.

Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
 arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi b/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi
index 7cda6944501d..6ce534a896ef 100644
--- a/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi
+++ b/arch/arm/boot/dts/imx6ul-phytec-segin-peb-av-02.dtsi
@@ -11,7 +11,7 @@ backlight_lcd: backlight-lcd {
 		brightness-levels = <0 4 8 16 32 64 128 255>;
 		default-brightness-level = <5>;
 		power-supply = <&reg_backlight_en>;
-		pwms = <&pwm3 0 5000000>;
+		pwms = <&pwm3 0 5000000 0>;
 		status = "disabled";
 	};
 
@@ -91,7 +91,6 @@ lcdif_parallel_out: endpoint {
 };
 
 &pwm3 {
-	#pwm-cells = <2>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pwm3>;
 	status = "disabled";
-- 
2.25.1



From andrej.picej at norik.com  Mon Jan 31 00:05:24 2022
From: andrej.picej at norik.com (Andrej Picej)
Date: Mon, 31 Jan 2022 09:05:24 +0100
Subject: [PATCH RESEND 2/4] ARM: dts: imx6ull: Add support for PHYTEC
 phyGATE-Tauri-S with i.MX 6ULL
In-Reply-To: <20220131080526.1171072-1-andrej.picej@norik.com>
References: <20220131080526.1171072-1-andrej.picej@norik.com>
Message-ID: <20220131080526.1171072-3-andrej.picej@norik.com>

From: Alexander Bauer <a.bauer at phytec.de>

Add support for the PHYTEC phyGATE-Tauri-S with i.MX 6ULL with eMMC or
NAND.

Supported features:
        * eMMC/NAND
        * i2c RTC
        * i2c TEMP
        * PMIC
        * PWM
        * debug UART
        * CAN
        * SD card
        * 2x 1Gbit Ethernet
        * RS232/RS485
        * USB 2.0 Host
        * TPM
        * SPI-NOR

Signed-off-by: Alexander Bauer <a.bauer at phytec.de>
Signed-off-by: Jens Lang <j.lang at phytec.de>
Signed-off-by: Andrej Picej <andrej.picej at norik.com>
---
 arch/arm/boot/dts/Makefile                    |   2 +
 .../boot/dts/imx6ull-phytec-tauri-emmc.dts    |  20 +
 .../boot/dts/imx6ull-phytec-tauri-nand.dts    |  20 +
 arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi   | 605 ++++++++++++++++++
 4 files changed, 647 insertions(+)
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri-emmc.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri-nand.dts
 create mode 100644 arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 235ad559acb2..f50270b9965a 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -704,6 +704,8 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
 	imx6ull-phytec-segin-ff-rdk-nand.dtb \
 	imx6ull-phytec-segin-ff-rdk-emmc.dtb \
 	imx6ull-phytec-segin-lc-rdk-nand.dtb \
+	imx6ull-phytec-tauri-nand.dtb \
+	imx6ull-phytec-tauri-emmc.dtb \
 	imx6ulz-14x14-evk.dtb \
 	imx6ulz-bsh-smm-m2.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
diff --git a/arch/arm/boot/dts/imx6ull-phytec-tauri-emmc.dts b/arch/arm/boot/dts/imx6ull-phytec-tauri-emmc.dts
new file mode 100644
index 000000000000..14adb87da911
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-phytec-tauri-emmc.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 PHYTEC Messtechnik GmbH
+ * Author: Alexander Bauer <a.bauer at phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull-phytec-tauri.dtsi"
+
+/ {
+	model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
+	compatible = "phytec,imx6ull-phygate-tauri",
+		     "phytec,imx6ull-phygate-tauri-emmc",
+		     "phytec,imx6ull-pcl063", "fsl,imx6ull";
+};
+
+/* EMMC-Version */
+&usdhc2 {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-tauri-nand.dts b/arch/arm/boot/dts/imx6ull-phytec-tauri-nand.dts
new file mode 100644
index 000000000000..ae396ac63443
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-phytec-tauri-nand.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 PHYTEC Messtechnik GmbH
+ * Author: Alexander Bauer <a.bauer at phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull-phytec-tauri.dtsi"
+
+/ {
+	model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
+	compatible = "phytec,imx6ull-phygate-tauri",
+		     "phytec,imx6ull-phygate-tauri-nand",
+		     "phytec,imx6ull-pcl063", "fsl,imx6ull";
+};
+
+/* NAND-Version */
+&gpmi {
+	status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi b/arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi
new file mode 100644
index 000000000000..62a70d80c009
--- /dev/null
+++ b/arch/arm/boot/dts/imx6ull-phytec-tauri.dtsi
@@ -0,0 +1,605 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2021 PHYTEC Messtechnik GmbH
+ * Author: Alexander Bauer <a.bauer at phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-phytec-phycore-som.dtsi"
+
+/ {
+
+	model = "PHYTEC phyGate-Tauri i.MX6 UltraLite";
+	compatible = "phytec,imx6ull-phygate-tauri",
+		     "phytec,imx6ull-pcl063", "fsl,imx6ull";
+
+	aliases {
+		rtc0 = &i2c_rtc;
+		rtc1 = &snvs_rtc;
+	};
+
+	gpio_keys: gpio-keys {
+		compatible = "gpio-key";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		key {
+			label = "KEY-A";
+			gpios = <&gpio1 18 GPIO_ACTIVE_LOW>;
+			linux,code = <30>;
+			wakeup-source;
+		};
+	};
+
+	reg_adc1_vref_3v3: regulator-vref-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "vref-3v3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
+	reg_s25fl064_hold: regulator-s25fl064-hold {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_s25fl064_hold>;
+		compatible = "regulator-fixed";
+		regulator-name = "s25fl064_hold";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio3 17 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	reg_usb_hub_vbus: regulator-hub-otg1-vbus {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbhubpwr>;
+		compatible = "regulator-fixed";
+		regulator-name = "usb_hub_vbus";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio5 5 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_usbotg1pwr>;
+		compatible = "regulator-fixed";
+		regulator-name = "usb_otg1_vbus";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		gpio = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	user_leds: user-leds {
+		compatible = "gpio-leds";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_user_leds>,
+			    <&pinctrl_user_leds_snvs>;
+
+		user-led1 {
+			label = "yellow";
+			gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "off";
+		};
+
+		user-led2 {
+			label = "red";
+			gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
+			linux,default-trigger = "off";
+		};
+	};
+};
+
+&can1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan1>;
+	status = "okay";
+};
+
+&can2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_flexcan2>;
+	status = "okay";
+};
+
+&ecspi1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	fsl,spi-num-chipselects = <3>;
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi1>,
+		    <&pinctrl_ecspi1_cs>;
+	cs-gpios = <&gpio3 26 GPIO_ACTIVE_LOW>,
+		   <&gpio3 10 GPIO_ACTIVE_LOW>,
+		   <&gpio3 11 GPIO_ACTIVE_LOW>;
+	status = "okay";
+
+	spi_dev0: spi at 0 {
+		compatible = "linux,spidev";
+		spi-max-frequency = <57600000>;
+		reg = <0>;
+	};
+
+	tpm_tis: tpm at 1 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_tpm>;
+		compatible = "tcg,tpm_tis-spi";
+		reg = <1>;
+		spi-max-frequency = <20000000>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+		status = "okay";
+	};
+
+/* S25FL064P */
+	s25fl064: flash at 2 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = " jedec,spi-nor";
+		reg = <2>;
+		spi-max-frequency = <40000000>;
+		m25p,fast-read;
+		status = "disabled";
+	};
+};
+
+&ecspi3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_ecspi3>;
+	cs-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+	dmas = <&sdma 7 8 0>,
+	       <&sdma 8 8 0>;
+	dma-names = "rx", "tx";
+	status = "okay";
+
+	spi_dev1: spi at 0 {
+		compatible = "linux,spidev";
+		spi-max-frequency = <57600000>;
+		reg = <0>;
+	};
+};
+
+&ethphy1 {
+	status = "okay";
+};
+
+&fec1 {
+	status = "okay";
+};
+
+&fec2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_enet2>;
+	phy-mode = "rmii";
+	phy-handle = <&ethphy2>;
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+
+	i2c_rtc: rtc at 68 {
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_rtc_int>;
+		compatible = "microcrystal,rv4162";
+		reg = <0x68>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	tmp102: tmp at 49 {
+		compatible = "ti,tmp102";
+		reg = <0x49>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_tempsense>;
+		interrupt-parent = <&gpio5>;
+		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+		#thermal-sensor-cells = <1>;
+	};
+};
+
+&i2c2 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c2>;
+	pinctrl-1 = <&pinctrl_i2c2_gpio>;
+	sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	scl-gpios = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+};
+
+&i2c3 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c3>;
+	pinctrl-1 = <&pinctrl_i2c3_gpio>;
+	sda-gpios = <&gpio3 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	scl-gpios = <&gpio3 6 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+};
+
+&i2c4 {
+	pinctrl-names = "default", "gpio";
+	pinctrl-0 = <&pinctrl_i2c4>;
+	pinctrl-1 = <&pinctrl_i2c4_gpio>;
+	sda-gpios = <&gpio3 7 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	scl-gpios = <&gpio3 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+};
+
+&mdio {
+	ethphy2: ethernet-phy at 2 {
+		reg = <2>;
+		micrel,led-mode = <1>;
+		clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+		clock-names = "rmii-ref";
+		status = "okay";
+	};
+};
+
+&pwm3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm3>;
+	status = "okay";
+};
+
+&pwm6 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm6>;
+	status = "okay";
+};
+
+&pwm7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm7>;
+	status = "okay";
+};
+
+&pwm8 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_pwm8>;
+	status = "okay";
+};
+
+&uart3 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart3>;
+	status = "okay";
+};
+
+/* UART4 * RS485  */
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart4>;
+	rts-gpios = <&gpio3 2 GPIO_ACTIVE_HIGH>;
+	rs485-rts-active-high;
+	linux,rs485-enabled-at-boot-time;
+	status = "okay";
+};
+
+/* UART5 * RS232  */
+&uart5 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart5>;
+	uart-has-rtscts;
+	status = "okay";
+};
+
+&uart7 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_uart7>;
+	status = "okay";
+};
+
+/* USB */
+&usbotg1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usb_otg1>;
+	vbus-supply = <&reg_usb_otg1_vbus>;
+	dr_mode = "host";
+	disable-over-current;
+	status = "okay";
+};
+
+&usbotg2 {
+	vbus-supply = <&reg_usb_hub_vbus>;
+	disable-over-current;
+	dr_mode = "host";
+	status = "okay";
+};
+
+&usdhc1 {
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	pinctrl-0 = <&pinctrl_usdhc1>;
+	pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+	pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+	cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+	no-1-8-v;
+	keep-power-in-suspend;
+	wakeup-source;
+	status = "okay";
+};
+
+&usdhc2 {
+	status = "disabled";
+};
+
+&iomuxc_snvs {
+
+	pinctrl_rtc_int: rtcintgrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01	0x17059
+		>;
+	};
+
+	pinctrl_stmpe: stmpegrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03	0x17059
+		>;
+	};
+
+	pinctrl_tempsense: tempsensegrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00	0x17059
+		>;
+	};
+
+	pinctrl_tpm: tpmgrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02	0x17059
+		>;
+	};
+
+	pinctrl_usbhubpwr: usbhubpwrgrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05	0x17059
+		>;
+	};
+
+	pinctrl_user_leds_snvs: user_ledsgrp {
+		fsl,pins = <
+			MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09	0x79
+		>;
+	};
+};
+
+&iomuxc {
+
+	pinctrl_gpio: gpio_gpiogrp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA05__GPIO4_IO26	0x17059  /* nUART_MUX_RS232 */
+			MX6UL_PAD_CSI_DATA04__GPIO4_IO25	0x17059  /* nUART_MUX_DUAL_RX_TX */
+		>;
+	};
+
+	pinctrl_gpio_keys: gpio_keysgrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_CTS_B__GPIO1_IO18	0x79
+		>;
+	};
+
+	pinctrl_ecspi3: ecspi3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK	0x100b1
+			MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO	0x100b1
+			MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI	0x100b1
+			MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20	0x10b0
+		>;
+	};
+
+	pinctrl_ecspi1: ecspi1grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK	0x100b1
+			MX6UL_PAD_LCD_DATA23__ECSPI1_MISO	0x100b1
+			MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI	0x100b1
+		>;
+	};
+
+	pinctrl_ecspi1_cs: ecspi1csgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA21__GPIO3_IO26	0x10b0
+			MX6UL_PAD_LCD_DATA05__GPIO3_IO10	0x10b0
+			MX6UL_PAD_LCD_DATA06__GPIO3_IO11	0x10b0
+		>;
+	};
+
+
+	pinctrl_enet2: enet2grp {
+		fsl,pins = <
+			MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN	0x1b0b0
+			MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00	0x1b0b0
+			MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01	0x1b0b0
+			MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN	0x1b010
+			MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00	0x1b010
+			MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01	0x1b010
+			MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2	0x4001b010
+		>;
+	};
+
+	pinctrl_flexcan1: flexcan1grp {
+		fsl,pins = <
+			MX6UL_PAD_UART3_CTS_B__FLEXCAN1_TX	0x0b0b0
+			MX6UL_PAD_UART3_RTS_B__FLEXCAN1_RX	0x0b0b0
+		>;
+	};
+
+	pinctrl_flexcan2: flexcan2grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA10__FLEXCAN2_TX	0x0b0b0
+			MX6UL_PAD_LCD_DATA11__FLEXCAN2_RX	0x0b0b0
+		>;
+	};
+
+	princtrl_flexcan2_en: flexcan2engrp {
+		fsl,pins = <
+			MX6UL_PAD_UART1_CTS_B__GPIO1_IO18	0x17059
+		>;
+	};
+
+	pinctrl_i2c2: i2c2grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO00__I2C2_SCL	0xb0
+			MX6UL_PAD_GPIO1_IO01__I2C2_SDA	0xb0
+		>;
+	};
+
+	pinctrl_i2c2_gpio: i2c2gpiogrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO00__GPIO1_IO00	0xb0
+			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01	0xb0
+		>;
+	};
+
+	pinctrl_i2c3: i2c3grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA01__I2C3_SCL	0xb0
+			MX6UL_PAD_LCD_DATA00__I2C3_SDA	0xb0
+		>;
+	};
+
+	pinctrl_i2c3_gpio: i2c3gpiogrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA01__GPIO3_IO06	0xb0
+			MX6UL_PAD_LCD_DATA00__GPIO3_IO05	0xb0
+		>;
+	};
+
+	pinctrl_i2c4: i2c4grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA03__I2C4_SCL	0xb0
+			MX6UL_PAD_LCD_DATA02__I2C4_SDA	0xb0
+		>;
+	};
+
+	pinctrl_i2c4_gpio: i2c4gpiogrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA03__GPIO3_IO08	0xb0
+			MX6UL_PAD_LCD_DATA02__GPIO3_IO07	0xb0
+		>;
+	};
+
+	pinctrl_pwm3: pwm3grp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO04__PWM3_OUT	0x0b0b0
+		>;
+	};
+
+	pinctrl_pwm6: pwm6grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TDI__PWM6_OUT	0x0b0b0
+		>;
+	};
+
+	pinctrl_pwm7: pwm7grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TCK__PWM7_OUT	0x0b0b0
+		>;
+	};
+
+	pinctrl_pwm8: pwm8grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TRST_B__PWM8_OUT	0x0b0b0
+		>;
+	};
+
+	pinctrl_s25fl064_hold: s25fl064_holdgrp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA12__GPIO3_IO17	0x100b1
+		>;
+	};
+
+	pinctrl_sai2: sai2grp {
+		fsl,pins = <
+			MX6UL_PAD_JTAG_TDI__SAI2_TX_BCLK	0x17088
+			MX6UL_PAD_JTAG_TDO__SAI2_TX_SYNC	0x17088
+			MX6UL_PAD_JTAG_TRST_B__SAI2_TX_DATA	0x11088
+			MX6UL_PAD_JTAG_TCK__SAI2_RX_DATA	0x11088
+			MX6UL_PAD_JTAG_TMS__SAI2_MCLK		0x17088
+		>;
+	};
+
+	pinctrl_uart3: uart3grp {
+		fsl,pins = <
+			MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart4: uart4grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_CLK__UART4_DCE_TX		0x1b0b1
+			MX6UL_PAD_LCD_ENABLE__UART4_DCE_RX	0x1b0b1
+			MX6UL_PAD_LCD_HSYNC__GPIO3_IO02	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart5: uart5grp {
+		fsl,pins = <
+			MX6UL_PAD_UART5_TX_DATA__UART5_DCE_TX	0x1b0b1
+			MX6UL_PAD_UART5_RX_DATA__UART5_DCE_RX	0x1b0b1
+		>;
+	};
+
+	pinctrl_uart7: uart7grp {
+		fsl,pins = <
+			MX6UL_PAD_LCD_DATA16__UART7_DCE_TX	0x1b0b1
+			MX6UL_PAD_LCD_DATA17__UART7_DCE_RX	0x1b0b1
+		>;
+	};
+
+	pinctrl_usb_otg1: usbotg1grp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA06__GPIO4_IO27	0x80
+		>;
+	};
+
+	pinctrl_usbotg1pwr: usbotg1pwrgrp {
+		fsl,pins = <
+			MX6UL_PAD_CSI_DATA07__GPIO4_IO28	0x17059
+		>;
+	};
+
+	pinctrl_usdhc1: usdhc1grp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x17059
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x10059
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x17059
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x17059
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x17059
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x17059
+			MX6UL_PAD_UART1_RTS_B__GPIO1_IO19	0x17059
+		>;
+	};
+
+	pinctrl_usdhc1_100mhz: usdhc1100mhzgrp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x170b9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x100b9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170b9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170b9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170b9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170b9
+		>;
+	};
+
+	pinctrl_usdhc1_200mhz: usdhc1200mhzgrp {
+		fsl,pins = <
+			MX6UL_PAD_SD1_CMD__USDHC1_CMD		0x170f9
+			MX6UL_PAD_SD1_CLK__USDHC1_CLK		0x100f9
+			MX6UL_PAD_SD1_DATA0__USDHC1_DATA0	0x170f9
+			MX6UL_PAD_SD1_DATA1__USDHC1_DATA1	0x170f9
+			MX6UL_PAD_SD1_DATA2__USDHC1_DATA2	0x170f9
+			MX6UL_PAD_SD1_DATA3__USDHC1_DATA3	0x170f9
+		>;
+	};
+
+	pinctrl_user_leds: user_ledsgrp {
+		fsl,pins = <
+			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03	0x79
+		>;
+	};
+};
-- 
2.25.1



From clabbe at baylibre.com  Mon Jan 31 00:08:58 2022
From: clabbe at baylibre.com (Corentin Labbe)
Date: Mon, 31 Jan 2022 08:08:58 +0000
Subject: [PATCH v2] dt-bindings: mtd: drop mtd/cortina,gemini-flash.txt
Message-ID: <20220131080858.1777518-1-clabbe@baylibre.com>

Drop mtd/cortina,gemini-flash.txt since it is nearly already handled by
Documentation/devicetree/bindings/mtd/mtd-physmap.yaml.

Reviewed-by: Linus Walleij <linus.walleij at linaro.org>
Signed-off-by: Corentin Labbe <clabbe at baylibre.com>
---
Change since v1:
- fixed typo on syscon

 .../bindings/mtd/cortina,gemini-flash.txt     | 24 -------------------
 .../devicetree/bindings/mtd/mtd-physmap.yaml  | 18 +++++++++++++-
 2 files changed, 17 insertions(+), 25 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt

diff --git a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt b/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt
deleted file mode 100644
index efa5b2aba829..000000000000
--- a/Documentation/devicetree/bindings/mtd/cortina,gemini-flash.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Flash device on Cortina Systems Gemini SoC
-
-This flash is regular CFI compatible (Intel or AMD extended) flash chips with
-some special bits that can be controlled by the machine's system controller.
-
-Required properties:
-- compatible : must be "cortina,gemini-flash", "cfi-flash";
-- reg : memory address for the flash chip
-- syscon : must be a phandle to the system controller
-- bank-width : width in bytes of flash interface, should be <2>
-
-For the rest of the properties, see mtd-physmap.yaml.
-
-The device tree may optionally contain sub-nodes describing partitions of the
-address space. See partition.txt for more detail.
-
-Example:
-
-flash at 30000000 {
-	compatible = "cortina,gemini-flash", "cfi-flash";
-	reg = <0x30000000 0x01000000>;
-	syscon = <&syscon>;
-	bank-width = <2>;
-};
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
index f827984936f6..82eb4e0f453b 100644
--- a/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
+++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.yaml
@@ -44,7 +44,9 @@ properties:
               - numonyx,js28f128
               - sst,sst39vf320
               - xlnx,xps-mch-emc-2.00.a
-          - const: cfi-flash
+          - enum:
+              - cfi-flash
+              - jedec-flash
       - items:
           - enum:
               - cypress,cy7c1019dv33-10zsxi
@@ -127,6 +129,20 @@ required:
   - compatible
   - reg
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: cortina,gemini-flash
+then:
+  properties:
+    syscon:
+      $ref: /schemas/types.yaml#/definitions/phandle
+      description:
+        Phandle to the syscon controller
+  required:
+    - syscon
+
 # FIXME: A parent bus may define timing properties
 additionalProperties: true
 
-- 
2.34.1



From s.hauer at pengutronix.de  Mon Jan 31 00:10:42 2022
From: s.hauer at pengutronix.de (Sascha Hauer)
Date: Mon, 31 Jan 2022 09:10:42 +0100
Subject: [PATCH 24/27] clk: rk3568: drop CLK_SET_RATE_PARENT from dclk_vop*
In-Reply-To: <5329207.qDA9hNt6id@diego>
References: <20220126145549.617165-1-s.hauer@pengutronix.de>
 <20220126145549.617165-25-s.hauer@pengutronix.de>
 <5329207.qDA9hNt6id@diego>
Message-ID: <20220131081042.GW23490@pengutronix.de>

On Sat, Jan 29, 2022 at 06:48:13PM +0100, Heiko St?bner wrote:
> Am Mittwoch, 26. Januar 2022, 15:55:46 CET schrieb Sascha Hauer:
> > The pixel clocks dclk_vop[012] can be clocked from hpll, vpll, gpll or
> > cpll. gpll and cpll also drive many other clocks, so changing the
> > dclk_vop[012] clocks could change these other clocks as well. Drop
> > CLK_SET_RATE_PARENT to fix that. With this change the VOP2 driver can
> > only adjust the pixel clocks with the divider between the PLL and the
> > dclk_vop[012] which means the user may have to adjust the PLL clock to a
> > suitable rate using the assigned-clock-rate device tree property.
> > 
> > Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
> > ---
> >  drivers/clk/rockchip/clk-rk3568.c | 6 +++---
> >  1 file changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/clk/rockchip/clk-rk3568.c b/drivers/clk/rockchip/clk-rk3568.c
> > index 9d889fc46811..7687c62d1fa8 100644
> > --- a/drivers/clk/rockchip/clk-rk3568.c
> > +++ b/drivers/clk/rockchip/clk-rk3568.c
> > @@ -1044,13 +1044,13 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
> >  			RK3568_CLKGATE_CON(20), 8, GFLAGS),
> >  	GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0,
> >  			RK3568_CLKGATE_CON(20), 9, GFLAGS),
> > -	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
> > +	COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, CLK_SET_RATE_NO_REPARENT,
> 
> hmm, I'm wondering about the use of having CLK_SET_RATE_NO_REPARENT here
> (and even adding it below).
> 
> Using SET_RATE_PARENT in the following patch for the hdmi-pll, should give
> us at least a suitable rate for the hdmi output, so the vop using that
> should already find a nice rate to use.
> 
> The normal system-PLLs don't normally don't change their rate at runtime,
> so I think we should liberate the dclks to select a PLL that best matches
> their target rate - so drop the CLK_SET_RATE_NO_REPARENT as well.
> 
> That way the DCLKs can change to another PLL source if that provides
> a rate nearer to their target.

The HDMI reference clock has the CLK_SET_RATE_PARENT flag set and we
need that to program the HPLL clock to suitable rates for the HDMI
output. Now any other display choosing HPLL as parent, because that
provides the best rate in that point of time, hangs on a PLL which
changes its rate whenever the resolution is changed on the HDMI output.

Changing parents on rate changes only works when all possible parents of
all the children involved have a constant rate. IMO allowing reparenting
on rate changes is a poorly chosen default because it's very unsafe. We
should rather have a CLK_SET_RATE_ALLOW_REPARENT flag.

Sascha

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


From Jianyong.Wu at arm.com  Mon Jan 31 00:10:44 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Mon, 31 Jan 2022 08:10:44 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com>
References: <20211216082812.165387-1-jianyong.wu@arm.com>
 <YdXdjcJ7jbnkFsqp@arm.com>
 <AM9PR08MB7276E0DE6B4224C22B20A89CF44C9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdcRLohx777jzWah@arm.com>
 <AM9PR08MB7276B412F02CA0431E30E06CF44D9@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <YdgZJ/mBG+BCxmEv@arm.com>
 <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
 <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
 <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com>
Message-ID: <AM9PR08MB72760F336E9D198FB4A1E6D5F4259@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi David,

> -----Original Message-----
> From: David Hildenbrand <david at redhat.com>
> Sent: Thursday, January 27, 2022 8:23 PM
> To: Jianyong Wu <Jianyong.Wu at arm.com>; Ard Biesheuvel
> <ardb at kernel.org>; Catalin Marinas <Catalin.Marinas at arm.com>
> Cc: Justin He <Justin.He at arm.com>; will at kernel.org; Anshuman Khandual
> <Anshuman.Khandual at arm.com>; akpm at linux-foundation.org;
> quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org; linux-arm-
> kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> >
> > Yes, system_state can roughly separate these callers of
> __create_pgd_mapping. When system_state > SYSTEM_BOOTING we can
> add the lock.
> > Thus, I have the following change:
> >
> > static DEFINE_SPINLOCK(swapper_pgdir_lock);
> > +static DEFINE_MUTEX(fixmap_lock);
> >
> >  void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)  { @@ -329,6 +330,8 @@
> > static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long
> end,
> >         }
> >         BUG_ON(p4d_bad(p4d));
> >
> > +       if (system_state > SYSTEM_BOOTING)
> 
> As there is nothing smaller than SYSTEM_BOOTING, you can use
> 	if (system_state != SYSTEM_BOOTING)
> 
> ...
OK,

> 
> >
> > It seems work and somehow simper. But I don't know if it is reasonable
> > to do this. So, any idea? @Ard Biesheuvel  @Catalin Marinas
> 
> It's worth looking at kernel/notifier.c, e.g.,
> blocking_notifier_chain_register()
> 
> if (unlikely(system_state == SYSTEM_BOOTING))
> 	return notifier_chain_register(&nh->head, n);
> 
> down_write(&nh->rwsem);
> ret = notifier_chain_register(&nh->head, n); up_write(&nh->rwsem);
> 
> 
> 
> If we decide to go down that path, we should make sure to add a comment
> like
> 
> /*
>  * No need for locking during early boot. And it doesn't work as
>  * expected with KASLR enabled where we might clear BSS twice.
>  */
> 

Thanks David, it's very helpful.

Thanks
Jianyong

> --
> Thanks,
> 
> David / dhildenb


From Jianyong.Wu at arm.com  Mon Jan 31 00:13:05 2022
From: Jianyong.Wu at arm.com (Jianyong Wu)
Date: Mon, 31 Jan 2022 08:13:05 +0000
Subject: [PATCH v3] arm64/mm: avoid fixmap race condition when create pud
 mapping
In-Reply-To: <YfKRVJlWrgluqD9e@arm.com>
References: <DB7PR08MB3737631DEE8D6625D3A9E393F7209@DB7PR08MB3737.eurprd08.prod.outlook.com>
 <CAMj1kXF7DJ5UeMn=9gw_Hs3Fa525OFEPsriO=ZprT3rN83=qtQ@mail.gmail.com>
 <AM9PR08MB72763D5DA0C5F22D2126ABF4F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <CAMj1kXGjAxd2xb0u1PLSLGAe8jJdhJm3wR+y=7qB4C1J6Ebgcw@mail.gmail.com>
 <3e6513f9-77ca-79e5-d185-7e9a11ec7689@redhat.com>
 <AM9PR08MB72764111B775352448D75CD9F4209@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <65fdd873-1f93-56e3-c7a5-98d621c5dbd8@redhat.com>
 <7eb4bc77-c1db-99c4-4c77-ae9ddd159abb@redhat.com>
 <AM9PR08MB7276062BC7B474174FFFA11BF4219@AM9PR08MB7276.eurprd08.prod.outlook.com>
 <ca62449b-7ab0-0e18-ee5a-b46b3f527385@redhat.com> <YfKRVJlWrgluqD9e@arm.com>
Message-ID: <AM9PR08MB72760D717ACE24811C4EA221F4259@AM9PR08MB7276.eurprd08.prod.outlook.com>

Hi Catalin,

> -----Original Message-----
> From: Catalin Marinas <catalin.marinas at arm.com>
> Sent: Thursday, January 27, 2022 8:34 PM
> To: David Hildenbrand <david at redhat.com>
> Cc: Jianyong Wu <Jianyong.Wu at arm.com>; Ard Biesheuvel
> <ardb at kernel.org>; Justin He <Justin.He at arm.com>; will at kernel.org;
> Anshuman Khandual <Anshuman.Khandual at arm.com>; akpm at linux-
> foundation.org; quic_qiancai at quicinc.com; linux-kernel at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; gshan at redhat.com; nd <nd at arm.com>
> Subject: Re: [PATCH v3] arm64/mm: avoid fixmap race condition when create
> pud mapping
> 
> On Thu, Jan 27, 2022 at 01:22:47PM +0100, David Hildenbrand wrote:
> > > Yes, system_state can roughly separate these callers of
> __create_pgd_mapping. When system_state > SYSTEM_BOOTING we can
> add the lock.
> > > Thus, I have the following change:
> > >
> > > static DEFINE_SPINLOCK(swapper_pgdir_lock);
> > > +static DEFINE_MUTEX(fixmap_lock);
> > >
> > >  void set_swapper_pgd(pgd_t *pgdp, pgd_t pgd)  { @@ -329,6 +330,8
> @@
> > > static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long
> end,
> > >         }
> > >         BUG_ON(p4d_bad(p4d));
> > >
> > > +       if (system_state > SYSTEM_BOOTING)
> >
> > As there is nothing smaller than SYSTEM_BOOTING, you can use
> > 	if (system_state != SYSTEM_BOOTING)
> >
> > ...
> >
> > >
> > > It seems work and somehow simper. But I don't know if it is
> > > reasonable to do this. So, any idea? @Ard Biesheuvel  @Catalin
> > > Marinas
> >
> > It's worth looking at kernel/notifier.c, e.g.,
> > blocking_notifier_chain_register()
> >
> > if (unlikely(system_state == SYSTEM_BOOTING))
> > 	return notifier_chain_register(&nh->head, n);
> >
> > down_write(&nh->rwsem);
> > ret = notifier_chain_register(&nh->head, n); up_write(&nh->rwsem);
> >
> > If we decide to go down that path, we should make sure to add a
> > comment like
> >
> > /*
> >  * No need for locking during early boot. And it doesn't work as
> >  * expected with KASLR enabled where we might clear BSS twice.
> >  */
> 
> A similar approach sounds fine to me.
> 

OK, I'll send the next version based on David's comments.

Thanks
Jianyong

> --
> Catalin


From camel.guo at axis.com  Mon Jan 31 00:37:56 2022
From: camel.guo at axis.com (Camel Guo)
Date: Mon, 31 Jan 2022 09:37:56 +0100
Subject: [PATCH] net: stmmac: dump gmac4 DMA registers correctly
Message-ID: <20220131083756.3346506-1-camel.guo@axis.com>

From: Camel Guo <camelg at axis.com>

Unlike gmac100, gmac1000, gmac4 has 27 DMA registers and they are
located at DMA_CHAN_BASE_ADDR (0x1100). In order for ethtool to dump
gmac4 DMA registers correctly, this commit checks if a net_device has
gmac4 and uses different logic to dump its DMA registers.

This fixes the following KASAN warning, which can normally be triggered
by a command similar like "ethtool -d eth0":

BUG: KASAN: vmalloc-out-of-bounds in dwmac4_dump_dma_regs+0x6d4/0xb30
Write of size 4 at addr ffffffc010177100 by task ethtool/1839
 kasan_report+0x200/0x21c
 __asan_report_store4_noabort+0x34/0x60
 dwmac4_dump_dma_regs+0x6d4/0xb30
 stmmac_ethtool_gregs+0x110/0x204
 ethtool_get_regs+0x200/0x4b0
 dev_ethtool+0x1dac/0x3800
 dev_ioctl+0x7c0/0xb50
 sock_ioctl+0x298/0x6c4
 ...

Fixes: fbf68229ffe7 ("net: stmmac: unify registers dumps methods")
Signed-off-by: Camel Guo <camelg at axis.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac_dma.h   |  1 +
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 1914ad698cab..acd70b9a3173 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -150,6 +150,7 @@
 
 #define NUM_DWMAC100_DMA_REGS	9
 #define NUM_DWMAC1000_DMA_REGS	23
+#define NUM_DWMAC4_DMA_REGS	27
 
 void dwmac_enable_dma_transmission(void __iomem *ioaddr);
 void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 164dff5ec32e..abfb3cd5958d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -21,10 +21,18 @@
 #include "dwxgmac2.h"
 
 #define REG_SPACE_SIZE	0x1060
+#define GMAC4_REG_SPACE_SIZE	0x116C
 #define MAC100_ETHTOOL_NAME	"st_mac100"
 #define GMAC_ETHTOOL_NAME	"st_gmac"
 #define XGMAC_ETHTOOL_NAME	"st_xgmac"
 
+/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
+ *
+ * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
+ * same time due to the conflicting macro names.
+ */
+#define GMAC4_DMA_CHAN_BASE_ADDR  0x00001100
+
 #define ETHTOOL_DMA_OFFSET	55
 
 struct stmmac_stats {
@@ -434,6 +442,8 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
 
 	if (priv->plat->has_xgmac)
 		return XGMAC_REGSIZE * 4;
+	else if (priv->plat->has_gmac4)
+		return GMAC4_REG_SPACE_SIZE;
 	return REG_SPACE_SIZE;
 }
 
@@ -446,8 +456,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
 	stmmac_dump_mac_regs(priv, priv->hw, reg_space);
 	stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
 
-	if (!priv->plat->has_xgmac) {
-		/* Copy DMA registers to where ethtool expects them */
+	/* Copy DMA registers to where ethtool expects them */
+	if (priv->plat->has_gmac4) {
+		/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
+		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
+		       &reg_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
+		       NUM_DWMAC4_DMA_REGS * 4);
+	} else if (!priv->plat->has_xgmac) {
 		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
 		       &reg_space[DMA_BUS_MODE / 4],
 		       NUM_DWMAC1000_DMA_REGS * 4);
-- 
2.30.2



From camel.guo at axis.com  Mon Jan 31 00:38:40 2022
From: camel.guo at axis.com (Camel Guo)
Date: Mon, 31 Jan 2022 09:38:40 +0100
Subject: [PATCH v2] net: stmmac: dump gmac4 DMA registers correctly
Message-ID: <20220131083841.3346801-1-camel.guo@axis.com>

From: Camel Guo <camelg at axis.com>

Unlike gmac100, gmac1000, gmac4 has 27 DMA registers and they are
located at DMA_CHAN_BASE_ADDR (0x1100). In order for ethtool to dump
gmac4 DMA registers correctly, this commit checks if a net_device has
gmac4 and uses different logic to dump its DMA registers.

This fixes the following KASAN warning, which can normally be triggered
by a command similar like "ethtool -d eth0":

BUG: KASAN: vmalloc-out-of-bounds in dwmac4_dump_dma_regs+0x6d4/0xb30
Write of size 4 at addr ffffffc010177100 by task ethtool/1839
 kasan_report+0x200/0x21c
 __asan_report_store4_noabort+0x34/0x60
 dwmac4_dump_dma_regs+0x6d4/0xb30
 stmmac_ethtool_gregs+0x110/0x204
 ethtool_get_regs+0x200/0x4b0
 dev_ethtool+0x1dac/0x3800
 dev_ioctl+0x7c0/0xb50
 sock_ioctl+0x298/0x6c4
 ...

Fixes: fbf68229ffe7 ("net: stmmac: unify registers dumps methods")
Signed-off-by: Camel Guo <camelg at axis.com>
---

Notes:
    v2: add Fixes footnote

 .../net/ethernet/stmicro/stmmac/dwmac_dma.h   |  1 +
 .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
index 1914ad698cab..acd70b9a3173 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_dma.h
@@ -150,6 +150,7 @@
 
 #define NUM_DWMAC100_DMA_REGS	9
 #define NUM_DWMAC1000_DMA_REGS	23
+#define NUM_DWMAC4_DMA_REGS	27
 
 void dwmac_enable_dma_transmission(void __iomem *ioaddr);
 void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 164dff5ec32e..abfb3cd5958d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -21,10 +21,18 @@
 #include "dwxgmac2.h"
 
 #define REG_SPACE_SIZE	0x1060
+#define GMAC4_REG_SPACE_SIZE	0x116C
 #define MAC100_ETHTOOL_NAME	"st_mac100"
 #define GMAC_ETHTOOL_NAME	"st_gmac"
 #define XGMAC_ETHTOOL_NAME	"st_xgmac"
 
+/* Same as DMA_CHAN_BASE_ADDR defined in dwmac4_dma.h
+ *
+ * It is here because dwmac_dma.h and dwmac4_dam.h can not be included at the
+ * same time due to the conflicting macro names.
+ */
+#define GMAC4_DMA_CHAN_BASE_ADDR  0x00001100
+
 #define ETHTOOL_DMA_OFFSET	55
 
 struct stmmac_stats {
@@ -434,6 +442,8 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev)
 
 	if (priv->plat->has_xgmac)
 		return XGMAC_REGSIZE * 4;
+	else if (priv->plat->has_gmac4)
+		return GMAC4_REG_SPACE_SIZE;
 	return REG_SPACE_SIZE;
 }
 
@@ -446,8 +456,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
 	stmmac_dump_mac_regs(priv, priv->hw, reg_space);
 	stmmac_dump_dma_regs(priv, priv->ioaddr, reg_space);
 
-	if (!priv->plat->has_xgmac) {
-		/* Copy DMA registers to where ethtool expects them */
+	/* Copy DMA registers to where ethtool expects them */
+	if (priv->plat->has_gmac4) {
+		/* GMAC4 dumps its DMA registers at its DMA_CHAN_BASE_ADDR */
+		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
+		       &reg_space[GMAC4_DMA_CHAN_BASE_ADDR / 4],
+		       NUM_DWMAC4_DMA_REGS * 4);
+	} else if (!priv->plat->has_xgmac) {
 		memcpy(&reg_space[ETHTOOL_DMA_OFFSET],
 		       &reg_space[DMA_BUS_MODE / 4],
 		       NUM_DWMAC1000_DMA_REGS * 4);
-- 
2.30.2



From lee.jones at linaro.org  Mon Jan 31 00:47:33 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 31 Jan 2022 08:47:33 +0000
Subject: [RFC v6 net-next 5/9] mfd: add interface to check whether a
 device is mfd
In-Reply-To: <20220129220221.2823127-6-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
 <20220129220221.2823127-6-colin.foster@in-advantage.com>
Message-ID: <YfeiJVmAbLa497Ht@google.com>

On Sat, 29 Jan 2022, Colin Foster wrote:

> Some drivers will need to create regmaps differently based on whether they
> are a child of an MFD or a standalone device. An example of this would be
> if a regmap were directly memory-mapped or an external bus. In the
> memory-mapped case a call to devm_regmap_init_mmio would return the correct
> regmap. In the case of an MFD, the regmap would need to be requested from
> the parent device.
> 
> This addition allows the driver to correctly reason about these scenarios.
> 
> Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
> ---
>  drivers/mfd/mfd-core.c   |  6 ++++++
>  include/linux/mfd/core.h | 10 ++++++++++
>  2 files changed, 16 insertions(+)
> 
> diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
> index 684a011a6396..2ba6a692499b 100644
> --- a/drivers/mfd/mfd-core.c
> +++ b/drivers/mfd/mfd-core.c
> @@ -33,6 +33,12 @@ static struct device_type mfd_dev_type = {
>  	.name	= "mfd_device",
>  };
>  
> +int device_is_mfd(struct platform_device *pdev)
> +{
> +	return (!strcmp(pdev->dev.type->name, mfd_dev_type.name));
> +}
> +EXPORT_SYMBOL(device_is_mfd);

As I said before, I really don't want MFDness leaking out into other
parts of the kernel.  Please find another way to differentiate between
devices registered via the MFD API and by other means.

I'm happy to help here.

How else could these devices be enumerated? 

>  int mfd_cell_enable(struct platform_device *pdev)
>  {
>  	const struct mfd_cell *cell = mfd_get_cell(pdev);
> diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
> index 0bc7cba798a3..c0719436b652 100644
> --- a/include/linux/mfd/core.h
> +++ b/include/linux/mfd/core.h
> @@ -10,6 +10,7 @@
>  #ifndef MFD_CORE_H
>  #define MFD_CORE_H
>  
> +#include <generated/autoconf.h>
>  #include <linux/platform_device.h>
>  
>  #define MFD_RES_SIZE(arr) (sizeof(arr) / sizeof(struct resource))
> @@ -123,6 +124,15 @@ struct mfd_cell {
>  	int			num_parent_supplies;
>  };
>  
> +#ifdef CONFIG_MFD_CORE
> +int device_is_mfd(struct platform_device *pdev);
> +#else
> +static inline int device_is_mfd(struct platform_device *pdev)
> +{
> +	return 0;
> +}
> +#endif
> +
>  /*
>   * Convenience functions for clients using shared cells.  Refcounting
>   * happens automatically, with the cell's enable/disable callbacks

-- 
Lee Jones [???]
Principal Technical Lead - Developer Services
Linaro.org ? Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog


From krzysztof.kozlowski at canonical.com  Mon Jan 31 00:49:07 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 31 Jan 2022 09:49:07 +0100
Subject: [PATCH 4/5] dt-bindings: mfd: samsung,exynos5433-lpass: Convert
 to dtschema
In-Reply-To: <1643502137.259074.416953.nullmailer@robh.at.kernel.org>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <20220129175332.298666-4-krzysztof.kozlowski@canonical.com>
 <1643502137.259074.416953.nullmailer@robh.at.kernel.org>
Message-ID: <0e5263dc-d4ba-45e9-a38f-9db127d67334@canonical.com>

On 30/01/2022 01:22, Rob Herring wrote:
> On Sat, 29 Jan 2022 18:53:31 +0100, Krzysztof Kozlowski wrote:
>> Convert the Exynos5433 LPASS bindings to DT schema format.
>>
>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>
>> ---
>>  .../bindings/mfd/samsung,exynos5433-lpass.txt |  72 -----------
>>  .../mfd/samsung,exynos5433-lpass.yaml         | 119 ++++++++++++++++++
>>  2 files changed, 119 insertions(+), 72 deletions(-)
>>  delete mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.txt
>>  create mode 100644 Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
>>
> 
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
> 
> yamllint warnings/errors:
> 
> dtschema/dtc warnings/errors:
> /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.example.dt.yaml: audio-subsystem at 11400000: serial at 11460000:compatible:0: 'samsung,exynos5433-uart' is not one of ['apple,s5l-uart', 'samsung,s3c2410-uart', 'samsung,s3c2412-uart', 'samsung,s3c2440-uart', 'samsung,s3c6400-uart', 'samsung,s5pv210-uart', 'samsung,exynos4210-uart', 'samsung,exynos850-uart']
> 	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.yaml
> Documentation/devicetree/bindings/mfd/samsung,exynos5433-lpass.example.dt.yaml:0:0: /example-0/audio-subsystem at 11400000/serial at 11460000: failed to match any schema with compatible: ['samsung,exynos5433-uart']
> 

This is false positive or rather my patch-ordering issue. I fixed it up
in patch 5/5 of this series.


Best regards,
Krzysztof


From horatiu.vultur at microchip.com  Mon Jan 31 00:52:01 2022
From: horatiu.vultur at microchip.com (Horatiu Vultur)
Date: Mon, 31 Jan 2022 09:52:01 +0100
Subject: [PATCH v2] pinctrl: microchip-sgpio: Fix support for regmap
Message-ID: <20220131085201.307031-1-horatiu.vultur@microchip.com>

Initially the driver accessed the registers using u32 __iomem but then
in the blamed commit it changed it to use regmap. The problem is that now
the offset of the registers is not calculated anymore at word offset but
at byte offset. Therefore make sure to multiply the offset with word size.

Acked-by: Steen Hegelund <Steen.Hegelund at microchip.com>
Reviewed-by: Colin Foster <colin.foster at in-advantage.com>
Fixes: 2afbbab45c261a ("pinctrl: microchip-sgpio: update to support regmap")
Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>

---
v1->v2:
- use regmap_get_reg_stride() instead of regmap_config.reg_stride
---
 drivers/pinctrl/pinctrl-microchip-sgpio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c
index 8e081c90bdb2..639f1130e989 100644
--- a/drivers/pinctrl/pinctrl-microchip-sgpio.c
+++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c
@@ -137,7 +137,8 @@ static inline int sgpio_addr_to_pin(struct sgpio_priv *priv, int port, int bit)
 
 static inline u32 sgpio_get_addr(struct sgpio_priv *priv, u32 rno, u32 off)
 {
-	return priv->properties->regoff[rno] + off;
+	return (priv->properties->regoff[rno] + off) *
+		regmap_get_reg_stride(priv->regs);
 }
 
 static u32 sgpio_readl(struct sgpio_priv *priv, u32 rno, u32 off)
-- 
2.33.0



From krzysztof.kozlowski at canonical.com  Mon Jan 31 00:54:00 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 31 Jan 2022 09:54:00 +0100
Subject: [PATCH] ARM: dts: add 533 MHz step to p4note GPU opp table
In-Reply-To: <20220129221452.GA36524@adroid>
References: <20220129221452.GA36524@adroid>
Message-ID: <131c9bd9-b035-8a75-ca27-f9c2b3993566@canonical.com>

On 29/01/2022 23:14, Martin J?cker wrote:
> The p4note devices support 533 MHz GPU speed, so let's make use of it.
> 

If there is going to be resend, please add prefix "exynos:" in subject.
Just like other commits (git log --oneline arch/arm/boot/dts/exynos*).

> Signed-off-by: Martin J?cker <martin.juecker at gmail.com>
> ---
>  arch/arm/boot/dts/exynos4412-p4note.dtsi | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/exynos4412-p4note.dtsi b/arch/arm/boot/dts/exynos4412-p4note.dtsi
> index 4ae6eb3091c4..d277b2337ae0 100644
> --- a/arch/arm/boot/dts/exynos4412-p4note.dtsi
> +++ b/arch/arm/boot/dts/exynos4412-p4note.dtsi
> @@ -355,6 +355,13 @@ &gpu {
>  	status = "okay";
>  };
>  
> +&gpu_opp_table {
> +	opp-533000000 {
> +		opp-hz = /bits/ 64 <533000000>;
> +		opp-microvolt = <1075000>;
> +	};
> +};

This looks like Exynos4412 Prime. Please check also CPU frequencies and
if they match, just include exynos4412-prime.dtsi (like Odroid U3).

> +
>  &hsotg {
>  	vusb_a-supply = <&ldo12_reg>;
>  	dr_mode = "peripheral";


Best regards,
Krzysztof


From angelogioacchino.delregno at collabora.com  Mon Jan 31 00:55:20 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 31 Jan 2022 09:55:20 +0100
Subject: [PATCH v4] drm/mediatek: mtk_dsi: Avoid EPROBE_DEFER loop with
 external bridge
Message-ID: <20220131085520.287105-1-angelogioacchino.delregno@collabora.com>

DRM bridge drivers are now attaching their DSI device at probe time,
which requires us to register our DSI host in order to let the bridge
to probe: this recently started producing an endless -EPROBE_DEFER
loop on some machines that are using external bridges, like the
parade-ps8640, found on the ACER Chromebook R13.

Now that the DSI hosts/devices probe sequence is documented, we can
do adjustments to the mtk_dsi driver as to both fix now and make sure
to avoid this situation in the future: for this, following what is
documented in drm_bridge.c, move the mtk_dsi component_add() to the
mtk_dsi_ops.attach callback and delete it in the detach callback;
keeping in mind that we are registering a drm_bridge for our DSI,
which is only used/attached if the DSI Host is bound, it wouldn't
make sense to keep adding our bridge at probe time (as it would
be useless to have it if mtk_dsi_ops.attach() fails!), so also move
that one to the dsi host attach function (and remove it in detach).

Cc: <stable at vger.kernel.org> # 5.15.x
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
Reviewed-by: Andrzej Hajda <andrzej.hajda at intel.com>
Reviewed-by: Jagan Teki <jagan at amarulasolutions.com>

---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 167 +++++++++++++++--------------
 1 file changed, 84 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 5d90d2eb0019..bced4c7d668e 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -786,18 +786,101 @@ void mtk_dsi_ddp_stop(struct device *dev)
 	mtk_dsi_poweroff(dsi);
 }
 
+static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
+{
+	int ret;
+
+	ret = drm_simple_encoder_init(drm, &dsi->encoder,
+				      DRM_MODE_ENCODER_DSI);
+	if (ret) {
+		DRM_ERROR("Failed to encoder init to drm\n");
+		return ret;
+	}
+
+	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
+
+	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
+				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret)
+		goto err_cleanup_encoder;
+
+	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
+	if (IS_ERR(dsi->connector)) {
+		DRM_ERROR("Unable to create bridge connector\n");
+		ret = PTR_ERR(dsi->connector);
+		goto err_cleanup_encoder;
+	}
+	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
+
+	return 0;
+
+err_cleanup_encoder:
+	drm_encoder_cleanup(&dsi->encoder);
+	return ret;
+}
+
+static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	int ret;
+	struct drm_device *drm = data;
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	ret = mtk_dsi_encoder_init(drm, dsi);
+	if (ret)
+		return ret;
+
+	return device_reset_optional(dev);
+}
+
+static void mtk_dsi_unbind(struct device *dev, struct device *master,
+			   void *data)
+{
+	struct mtk_dsi *dsi = dev_get_drvdata(dev);
+
+	drm_encoder_cleanup(&dsi->encoder);
+}
+
+static const struct component_ops mtk_dsi_component_ops = {
+	.bind = mtk_dsi_bind,
+	.unbind = mtk_dsi_unbind,
+};
+
 static int mtk_dsi_host_attach(struct mipi_dsi_host *host,
 			       struct mipi_dsi_device *device)
 {
 	struct mtk_dsi *dsi = host_to_dsi(host);
+	struct device *dev = host->dev;
+	int ret;
 
 	dsi->lanes = device->lanes;
 	dsi->format = device->format;
 	dsi->mode_flags = device->mode_flags;
+	dsi->next_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 0, 0);
+	if (IS_ERR(dsi->next_bridge))
+		return PTR_ERR(dsi->next_bridge);
+
+	drm_bridge_add(&dsi->bridge);
+
+	ret = component_add(host->dev, &mtk_dsi_component_ops);
+	if (ret) {
+		DRM_ERROR("failed to add dsi_host component: %d\n", ret);
+		drm_bridge_remove(&dsi->bridge);
+		return ret;
+	}
 
 	return 0;
 }
 
+static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
+			       struct mipi_dsi_device *device)
+{
+	struct mtk_dsi *dsi = host_to_dsi(host);
+
+	component_del(host->dev, &mtk_dsi_component_ops);
+	drm_bridge_remove(&dsi->bridge);
+	return 0;
+}
+
 static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
 {
 	int ret;
@@ -938,73 +1021,14 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host *host,
 
 static const struct mipi_dsi_host_ops mtk_dsi_ops = {
 	.attach = mtk_dsi_host_attach,
+	.detach = mtk_dsi_host_detach,
 	.transfer = mtk_dsi_host_transfer,
 };
 
-static int mtk_dsi_encoder_init(struct drm_device *drm, struct mtk_dsi *dsi)
-{
-	int ret;
-
-	ret = drm_simple_encoder_init(drm, &dsi->encoder,
-				      DRM_MODE_ENCODER_DSI);
-	if (ret) {
-		DRM_ERROR("Failed to encoder init to drm\n");
-		return ret;
-	}
-
-	dsi->encoder.possible_crtcs = mtk_drm_find_possible_crtc_by_comp(drm, dsi->host.dev);
-
-	ret = drm_bridge_attach(&dsi->encoder, &dsi->bridge, NULL,
-				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
-	if (ret)
-		goto err_cleanup_encoder;
-
-	dsi->connector = drm_bridge_connector_init(drm, &dsi->encoder);
-	if (IS_ERR(dsi->connector)) {
-		DRM_ERROR("Unable to create bridge connector\n");
-		ret = PTR_ERR(dsi->connector);
-		goto err_cleanup_encoder;
-	}
-	drm_connector_attach_encoder(dsi->connector, &dsi->encoder);
-
-	return 0;
-
-err_cleanup_encoder:
-	drm_encoder_cleanup(&dsi->encoder);
-	return ret;
-}
-
-static int mtk_dsi_bind(struct device *dev, struct device *master, void *data)
-{
-	int ret;
-	struct drm_device *drm = data;
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	ret = mtk_dsi_encoder_init(drm, dsi);
-	if (ret)
-		return ret;
-
-	return device_reset_optional(dev);
-}
-
-static void mtk_dsi_unbind(struct device *dev, struct device *master,
-			   void *data)
-{
-	struct mtk_dsi *dsi = dev_get_drvdata(dev);
-
-	drm_encoder_cleanup(&dsi->encoder);
-}
-
-static const struct component_ops mtk_dsi_component_ops = {
-	.bind = mtk_dsi_bind,
-	.unbind = mtk_dsi_unbind,
-};
-
 static int mtk_dsi_probe(struct platform_device *pdev)
 {
 	struct mtk_dsi *dsi;
 	struct device *dev = &pdev->dev;
-	struct drm_panel *panel;
 	struct resource *regs;
 	int irq_num;
 	int ret;
@@ -1021,19 +1045,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0,
-					  &panel, &dsi->next_bridge);
-	if (ret)
-		goto err_unregister_host;
-
-	if (panel) {
-		dsi->next_bridge = devm_drm_panel_bridge_add(dev, panel);
-		if (IS_ERR(dsi->next_bridge)) {
-			ret = PTR_ERR(dsi->next_bridge);
-			goto err_unregister_host;
-		}
-	}
-
 	dsi->driver_data = of_device_get_match_data(dev);
 
 	dsi->engine_clk = devm_clk_get(dev, "engine");
@@ -1098,14 +1109,6 @@ static int mtk_dsi_probe(struct platform_device *pdev)
 	dsi->bridge.of_node = dev->of_node;
 	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 
-	drm_bridge_add(&dsi->bridge);
-
-	ret = component_add(&pdev->dev, &mtk_dsi_component_ops);
-	if (ret) {
-		dev_err(&pdev->dev, "failed to add component: %d\n", ret);
-		goto err_unregister_host;
-	}
-
 	return 0;
 
 err_unregister_host:
@@ -1118,8 +1121,6 @@ static int mtk_dsi_remove(struct platform_device *pdev)
 	struct mtk_dsi *dsi = platform_get_drvdata(pdev);
 
 	mtk_output_dsi_disable(dsi);
-	drm_bridge_remove(&dsi->bridge);
-	component_del(&pdev->dev, &mtk_dsi_component_ops);
 	mipi_dsi_host_unregister(&dsi->host);
 
 	return 0;
-- 
2.33.1



From krzysztof.kozlowski at canonical.com  Mon Jan 31 00:59:21 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 31 Jan 2022 09:59:21 +0100
Subject: [PATCH 1/3] ARM: dts: exynos: update dma nodename for exynos3250
In-Reply-To: <20220130075520.49193-1-alim.akhtar@samsung.com>
References: <CGME20220130080810epcas5p425f29e7a017b4b1690509e60651d4245@epcas5p4.samsung.com>
 <20220130075520.49193-1-alim.akhtar@samsung.com>
Message-ID: <164361952065.14120.582076973615108824.b4-ty@canonical.com>

On Sun, 30 Jan 2022 13:25:18 +0530, Alim Akhtar wrote:
> Currently dma node name does not matches the pl330
> dt schema and make dtbs_check report below warning
> 
> 'pdma at 12680000' does not match '^dma-controller(@.*)?$'
> 
> Update the dma node name to match pl330 dt schema
> 
> [...]

Squashed into one commit, that's a tiny change in each file.

Applied, thanks!

[1/3] ARM: dts: exynos: update dma nodename for exynos3250
      commit: a5a881a33f8d6d5427a4150ee1a24a8790ada270
[2/3] ARM: dts: exynos: update dma nodename for exynos4
      commit: 0e1434e19717309c2c3a0770bd4ef5c3a937fe03
[3/3] ARM: dts: exynos: update dma nodename for exynos5
      commit: 51d6d2cb2523c3d979e94efc065a7c88a9c8dd61

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Mon Jan 31 01:02:53 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 31 Jan 2022 10:02:53 +0100
Subject: (subset) [PATCH 1/5] arm64: dts: exynos: align pl330 node name
 with dtschema
In-Reply-To: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
Message-ID: <164361966593.14585.5079368192105542217.b4-ty@canonical.com>

On Sat, 29 Jan 2022 18:53:28 +0100, Krzysztof Kozlowski wrote:
> Fixes dtbs_check warnings like:
> 
>   pdma at 15610000: $nodename:0: 'pdma at 15610000' does not match '^dma-controller(@.*)?$'
> 
> 

Applied, thanks!

[1/5] arm64: dts: exynos: align pl330 node name with dtschema
      commit: 706d8df83c8ec9cbe948ff8c8bd082b7819f4196

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From krzysztof.kozlowski at canonical.com  Mon Jan 31 01:02:54 2022
From: krzysztof.kozlowski at canonical.com (Krzysztof Kozlowski)
Date: Mon, 31 Jan 2022 10:02:54 +0100
Subject: (subset) [PATCH 2/5] arm64: dts: exynos: drop unneeded syscon
 phandle in Exynos5433 LPASS
In-Reply-To: <20220129175332.298666-2-krzysztof.kozlowski@canonical.com>
References: <20220129175332.298666-1-krzysztof.kozlowski@canonical.com>
 <20220129175332.298666-2-krzysztof.kozlowski@canonical.com>
Message-ID: <164361966594.14585.5432470637577397205.b4-ty@canonical.com>

On Sat, 29 Jan 2022 18:53:29 +0100, Krzysztof Kozlowski wrote:
> Exynos5433 LPASS audio node does not use syscon phandle since commit
> addebf1588ab ("mfd: exynos-lpass: Remove pad retention control").  It
> was also dropped from bindings.
> 
> 

Applied, thanks!

[2/5] arm64: dts: exynos: drop unneeded syscon phandle in Exynos5433 LPASS
      commit: f1afd24c3f532defa77c2d6e069b82dc7d6a9129

Best regards,
-- 
Krzysztof Kozlowski <krzysztof.kozlowski at canonical.com>


From maxime at cerno.tech  Mon Jan 31 01:21:26 2022
From: maxime at cerno.tech (Maxime Ripard)
Date: Mon, 31 Jan 2022 10:21:26 +0100
Subject: (subset) [PATCH] Add ethernet0 alias in Nanopi NEO's device tree
In-Reply-To: <20220129154214.45629-1-baltazar.radics@gmail.com>
References: <20220129154214.45629-1-baltazar.radics@gmail.com>
Message-ID: <164362087329.15921.5807470907175600465.b4-ty@cerno.tech>

On Sat, 29 Jan 2022 16:42:14 +0100, Baltaz?r Radics wrote:
> This is required for U-Boot to generate a MAC address for it
> automatically.
> (Without this, the MAC address will be random on each boot.)
> 
> 

Applied to sunxi/linux.git (sunxi/for-next).

Thanks!
Maxime


From angelogioacchino.delregno at collabora.com  Mon Jan 31 01:25:13 2022
From: angelogioacchino.delregno at collabora.com (AngeloGioacchino Del Regno)
Date: Mon, 31 Jan 2022 10:25:13 +0100
Subject: [PATCH 2/2] iommu/mediatek: Add mt8186 iommu support
In-Reply-To: <01cc69cdf7773962140c01fe37b12ab2c9491c25.camel@mediatek.com>
References: <20220125093244.18230-1-yong.wu@mediatek.com>
 <20220125093244.18230-3-yong.wu@mediatek.com>
 <b52a1df8-58f4-baa2-cfb6-9c56244caa0f@collabora.com>
 <01cc69cdf7773962140c01fe37b12ab2c9491c25.camel@mediatek.com>
Message-ID: <0e430d1e-ee25-1b3d-4a2c-8641db255adb@collabora.com>

Il 28/01/22 10:39, Yong Wu ha scritto:
> On Thu, 2022-01-27 at 12:28 +0100, AngeloGioacchino Del Regno wrote:
>> Il 25/01/22 10:32, Yong Wu ha scritto:
>>> Add mt8186 iommu supports.
>>>
>>> Signed-off-by: Anan Sun <anan.sun at mediatek.com>
>>> Signed-off-by: Yong Wu <yong.wu at mediatek.com>
>>> ---
>>>    drivers/iommu/mtk_iommu.c | 17 +++++++++++++++++
>>>    1 file changed, 17 insertions(+)
> 
> [snip]
> 
>>>    static const struct mtk_iommu_plat_data mt8192_data = {
>>>    	.m4u_plat       = M4U_MT8192,
>>>    	.flags          = HAS_BCLK | HAS_SUB_COMM_2BITS |
>>> OUT_ORDER_WR_EN |
>>> @@ -1470,6 +1486,7 @@ static const struct of_device_id
>>> mtk_iommu_of_ids[] = {
>>>    	{ .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data},
>>>    	{ .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
>>>    	{ .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
>>> +	{ .compatible = "mediatek,mt8186-iommu-mm", .data =
>>> &mt8186_data_mm},
>>
>> Hello!
>>
>> Is there any particular reason why this compatible is not
>> "mediatek,mt8186-m4u"?
> 
> There is no special reason. In the previous SoC, We only support MM
> IOMMU, it was called by "m4u". In the lastest SoC, We have the other
> types IOMMU, like for INFRA masters and APU, thus they are called "mm
> iommu", "infra iommu" and "apu iommu". Of course, "m4u" means "mm
> iommu".
> 

I suggest, at this point, to change it to "mediatek,mt8186-m4u" for naming
consistency with the other bindings and to avoid any kind of confusion.

Thank you!

>>
>> Thanks,
>> Angelo
>>
>>>    	{ .compatible = "mediatek,mt8192-m4u", .data = &mt8192_data},
>>>    	{ .compatible = "mediatek,mt8195-iommu-infra", .data =
>>> &mt8195_data_infra},
>>>    	{ .compatible = "mediatek,mt8195-iommu-vdo",   .data =
>>> &mt8195_data_vdo},
>>
>> _______________________________________________
>> Linux-mediatek mailing list
>> Linux-mediatek at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-mediatek
> 



From lee.jones at linaro.org  Mon Jan 31 01:29:34 2022
From: lee.jones at linaro.org (Lee Jones)
Date: Mon, 31 Jan 2022 09:29:34 +0000
Subject: [RFC v6 net-next 6/9] mfd: ocelot: add support for external mfd
 control over SPI for the VSC7512
In-Reply-To: <20220129220221.2823127-7-colin.foster@in-advantage.com>
References: <20220129220221.2823127-1-colin.foster@in-advantage.com>
 <20220129220221.2823127-7-colin.foster@in-advantage.com>
Message-ID: <Yfer/qJmwRdShv4y@google.com>

On Sat, 29 Jan 2022, Colin Foster wrote:

> Create a single SPI MFD ocelot device that manages the SPI bus on the
> external chip and can handle requests for regmaps. This should allow any
> ocelot driver (pinctrl, miim, etc.) to be used externally, provided they
> utilize regmaps.
> 
> Signed-off-by: Colin Foster <colin.foster at in-advantage.com>
> ---
>  drivers/mfd/Kconfig                       |  19 ++
>  drivers/mfd/Makefile                      |   3 +
>  drivers/mfd/ocelot-core.c                 | 165 +++++++++++
>  drivers/mfd/ocelot-spi.c                  | 325 ++++++++++++++++++++++
>  drivers/mfd/ocelot.h                      |  36 +++

>  drivers/net/mdio/mdio-mscc-miim.c         |  21 +-
>  drivers/pinctrl/pinctrl-microchip-sgpio.c |  22 +-
>  drivers/pinctrl/pinctrl-ocelot.c          |  29 +-
>  include/soc/mscc/ocelot.h                 |  11 +

Please avoid mixing subsystems in patches if at all avoidable.

If there are not build time dependencies/breakages, I'd suggest
firstly applying support for this into MFD *then* utilising that
support in subsequent patches.

>  9 files changed, 614 insertions(+), 17 deletions(-)
>  create mode 100644 drivers/mfd/ocelot-core.c
>  create mode 100644 drivers/mfd/ocelot-spi.c
>  create mode 100644 drivers/mfd/ocelot.h
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index ba0b3eb131f1..57bbf2d11324 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -948,6 +948,25 @@ config MFD_MENF21BMC
>  	  This driver can also be built as a module. If so the module
>  	  will be called menf21bmc.
>  
> +config MFD_OCELOT
> +	tristate "Microsemi Ocelot External Control Support"

Please explain exactly what an ECS is in the help below.

> +	select MFD_CORE
> +	help
> +	  Say yes here to add support for Ocelot chips (VSC7511, VSC7512,
> +	  VSC7513, VSC7514) controlled externally.
> +
> +	  All four of these chips can be controlled internally (MMIO) or
> +	  externally via SPI, I2C, PCIe. This enables control of these chips
> +	  over one or more of these buses.
> +
> +config MFD_OCELOT_SPI
> +	tristate "Microsemi Ocelot SPI interface"
> +	depends on MFD_OCELOT
> +	depends on SPI_MASTER
> +	select REGMAP_SPI
> +	help
> +	  Say yes here to add control to the MFD_OCELOT chips via SPI.
> +
>  config EZX_PCAP
>  	bool "Motorola EZXPCAP Support"
>  	depends on SPI_MASTER
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index df1ecc4a4c95..12513843067a 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -120,6 +120,9 @@ obj-$(CONFIG_MFD_MC13XXX_I2C)	+= mc13xxx-i2c.o
>  
>  obj-$(CONFIG_MFD_CORE)		+= mfd-core.o
>  
> +obj-$(CONFIG_MFD_OCELOT)	+= ocelot-core.o
> +obj-$(CONFIG_MFD_OCELOT_SPI)	+= ocelot-spi.o
> +

These do not look lined-up with the remainder of the file.

>  obj-$(CONFIG_EZX_PCAP)		+= ezx-pcap.o
>  obj-$(CONFIG_MFD_CPCAP)		+= motorola-cpcap.o
>  
> diff --git a/drivers/mfd/ocelot-core.c b/drivers/mfd/ocelot-core.c
> new file mode 100644
> index 000000000000..590489481b8c
> --- /dev/null
> +++ b/drivers/mfd/ocelot-core.c
> @@ -0,0 +1,165 @@
> +// SPDX-License-Identifier: (GPL-2.0 OR MIT)
> +/*
> + * MFD core driver for the Ocelot chip family.
> + *
> + * The VSC7511, 7512, 7513, and 7514 can be controlled internally via an
> + * on-chip MIPS processor, or externally via SPI, I2C, PCIe. This core driver is
> + * intended to be the bus-agnostic glue between, for example, the SPI bus and
> + * the MFD children.
> + *
> + * Copyright 2021 Innovative Advantage Inc.
> + *
> + * Author: Colin Foster <colin.foster at in-advantage.com>
> + */
> +
> +#include <linux/mfd/core.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +
> +#include <asm/byteorder.h>
> +
> +#include "ocelot.h"
> +
> +#define GCB_SOFT_RST (0x0008)

Why the brackets?

> +#define SOFT_CHIP_RST (0x1)

As above.

> +static const struct resource vsc7512_gcb_resource = {
> +	.start	= 0x71070000,
> +	.end	= 0x7107022b,

Please define these somewhere.

> +	.name	= "devcpu_gcb",
> +};

There is a macro you can use for these.

Grep for "DEFINE_RES_"

> +static int ocelot_reset(struct ocelot_core *core)
> +{
> +	int ret;
> +
> +	/*
> +	 * Reset the entire chip here to put it into a completely known state.
> +	 * Other drivers may want to reset their own subsystems. The register
> +	 * self-clears, so one write is all that is needed
> +	 */
> +	ret = regmap_write(core->gcb_regmap, GCB_SOFT_RST, SOFT_CHIP_RST);
> +	if (ret)
> +		return ret;
> +
> +	msleep(100);
> +
> +	/*
> +	 * A chip reset will clear the SPI configuration, so it needs to be done
> +	 * again befor